Initial commit

The binaries in this patch were generated by running the script
under clang-install/
diff --git a/bin/bugpoint b/bin/bugpoint
new file mode 100755
index 0000000..0fc4a3e
--- /dev/null
+++ b/bin/bugpoint
Binary files differ
diff --git a/bin/clang b/bin/clang
new file mode 120000
index 0000000..2eb013b
--- /dev/null
+++ b/bin/clang
@@ -0,0 +1 @@
+clang-3.5
\ No newline at end of file
diff --git a/bin/clang++ b/bin/clang++
new file mode 120000
index 0000000..060d289
--- /dev/null
+++ b/bin/clang++
@@ -0,0 +1 @@
+clang
\ No newline at end of file
diff --git a/bin/clang-3.5 b/bin/clang-3.5
new file mode 100755
index 0000000..f2ecbb1
--- /dev/null
+++ b/bin/clang-3.5
Binary files differ
diff --git a/bin/clang-apply-replacements b/bin/clang-apply-replacements
new file mode 100755
index 0000000..6959c90
--- /dev/null
+++ b/bin/clang-apply-replacements
Binary files differ
diff --git a/bin/clang-check b/bin/clang-check
new file mode 100755
index 0000000..6f42e49
--- /dev/null
+++ b/bin/clang-check
Binary files differ
diff --git a/bin/clang-cl b/bin/clang-cl
new file mode 120000
index 0000000..060d289
--- /dev/null
+++ b/bin/clang-cl
@@ -0,0 +1 @@
+clang
\ No newline at end of file
diff --git a/bin/clang-format b/bin/clang-format
new file mode 100755
index 0000000..7a7d105
--- /dev/null
+++ b/bin/clang-format
Binary files differ
diff --git a/bin/clang-modernize b/bin/clang-modernize
new file mode 100755
index 0000000..1bccbe1
--- /dev/null
+++ b/bin/clang-modernize
Binary files differ
diff --git a/bin/clang-tidy b/bin/clang-tidy
new file mode 100755
index 0000000..288a9aa
--- /dev/null
+++ b/bin/clang-tidy
Binary files differ
diff --git a/bin/git-clang-format b/bin/git-clang-format
new file mode 100755
index 0000000..c40b74d
--- /dev/null
+++ b/bin/git-clang-format
@@ -0,0 +1,484 @@
+#!/usr/bin/python
+#
+#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""                                                                             
+clang-format git integration                                                     
+============================                                                     
+                                                                                 
+This file provides a clang-format integration for git. Put it somewhere in your  
+path and ensure that it is executable. Then, "git clang-format" will invoke      
+clang-format on the changes in current files or a specific commit.               
+                                                                                 
+For further details, run:                                                        
+git clang-format -h                                                              
+                                                                                 
+Requires Python 2.7                                                              
+"""               
+
+import argparse
+import collections
+import contextlib
+import errno
+import os
+import re
+import subprocess
+import sys
+
+usage = 'git clang-format [OPTIONS] [<commit>] [--] [<file>...]'
+
+desc = '''
+Run clang-format on all lines that differ between the working directory
+and <commit>, which defaults to HEAD.  Changes are only applied to the working
+directory.
+
+The following git-config settings set the default of the corresponding option:
+  clangFormat.binary
+  clangFormat.commit
+  clangFormat.extension
+  clangFormat.style
+'''
+
+# Name of the temporary index file in which save the output of clang-format.
+# This file is created within the .git directory.
+temp_index_basename = 'clang-format-index'
+
+
+Range = collections.namedtuple('Range', 'start, count')
+
+
+def main():
+  config = load_git_config()
+
+  # In order to keep '--' yet allow options after positionals, we need to
+  # check for '--' ourselves.  (Setting nargs='*' throws away the '--', while
+  # nargs=argparse.REMAINDER disallows options after positionals.)
+  argv = sys.argv[1:]
+  try:
+    idx = argv.index('--')
+  except ValueError:
+    dash_dash = []
+  else:
+    dash_dash = argv[idx:]
+    argv = argv[:idx]
+
+  default_extensions = ','.join([
+      # From clang/lib/Frontend/FrontendOptions.cpp, all lower case
+      'c', 'h',  # C
+      'm',  # ObjC
+      'mm',  # ObjC++
+      'cc', 'cp', 'cpp', 'c++', 'cxx', 'hpp',  # C++
+      # Other languages that clang-format supports
+      'proto', 'protodevel',  # Protocol Buffers
+      'js',  # JavaScript
+      ])
+
+  p = argparse.ArgumentParser(
+    usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
+    description=desc)
+  p.add_argument('--binary',
+                 default=config.get('clangformat.binary', 'clang-format'),
+                 help='path to clang-format'),
+  p.add_argument('--commit',
+                 default=config.get('clangformat.commit', 'HEAD'),
+                 help='default commit to use if none is specified'),
+  p.add_argument('--diff', action='store_true',
+                 help='print a diff instead of applying the changes')
+  p.add_argument('--extensions',
+                 default=config.get('clangformat.extensions',
+                                    default_extensions),
+                 help=('comma-separated list of file extensions to format, '
+                       'excluding the period and case-insensitive')),
+  p.add_argument('-f', '--force', action='store_true',
+                 help='allow changes to unstaged files')
+  p.add_argument('-p', '--patch', action='store_true',
+                 help='select hunks interactively')
+  p.add_argument('-q', '--quiet', action='count', default=0,
+                 help='print less information')
+  p.add_argument('--style',
+                 default=config.get('clangformat.style', None),
+                 help='passed to clang-format'),
+  p.add_argument('-v', '--verbose', action='count', default=0,
+                 help='print extra information')
+  # We gather all the remaining positional arguments into 'args' since we need
+  # to use some heuristics to determine whether or not <commit> was present.
+  # However, to print pretty messages, we make use of metavar and help.
+  p.add_argument('args', nargs='*', metavar='<commit>',
+                 help='revision from which to compute the diff')
+  p.add_argument('ignored', nargs='*', metavar='<file>...',
+                 help='if specified, only consider differences in these files')
+  opts = p.parse_args(argv)
+
+  opts.verbose -= opts.quiet
+  del opts.quiet
+
+  commit, files = interpret_args(opts.args, dash_dash, opts.commit)
+  changed_lines = compute_diff_and_extract_lines(commit, files)
+  if opts.verbose >= 1:
+    ignored_files = set(changed_lines)
+  filter_by_extension(changed_lines, opts.extensions.lower().split(','))
+  if opts.verbose >= 1:
+    ignored_files.difference_update(changed_lines)
+    if ignored_files:
+      print 'Ignoring changes in the following files (wrong extension):'
+      for filename in ignored_files:
+        print '   ', filename
+    if changed_lines:
+      print 'Running clang-format on the following files:'
+      for filename in changed_lines:
+        print '   ', filename
+  if not changed_lines:
+    print 'no modified files to format'
+    return
+  # The computed diff outputs absolute paths, so we must cd before accessing
+  # those files.
+  cd_to_toplevel()
+  old_tree = create_tree_from_workdir(changed_lines)
+  new_tree = run_clang_format_and_save_to_tree(changed_lines,
+                                               binary=opts.binary,
+                                               style=opts.style)
+  if opts.verbose >= 1:
+    print 'old tree:', old_tree
+    print 'new tree:', new_tree
+  if old_tree == new_tree:
+    if opts.verbose >= 0:
+      print 'clang-format did not modify any files'
+  elif opts.diff:
+    print_diff(old_tree, new_tree)
+  else:
+    changed_files = apply_changes(old_tree, new_tree, force=opts.force,
+                                  patch_mode=opts.patch)
+    if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
+      print 'changed files:'
+      for filename in changed_files:
+        print '   ', filename
+
+
+def load_git_config(non_string_options=None):
+  """Return the git configuration as a dictionary.
+
+  All options are assumed to be strings unless in `non_string_options`, in which
+  is a dictionary mapping option name (in lower case) to either "--bool" or
+  "--int"."""
+  if non_string_options is None:
+    non_string_options = {}
+  out = {}
+  for entry in run('git', 'config', '--list', '--null').split('\0'):
+    if entry:
+      name, value = entry.split('\n', 1)
+      if name in non_string_options:
+        value = run('git', 'config', non_string_options[name], name)
+      out[name] = value
+  return out
+
+
+def interpret_args(args, dash_dash, default_commit):
+  """Interpret `args` as "[commit] [--] [files...]" and return (commit, files).
+
+  It is assumed that "--" and everything that follows has been removed from
+  args and placed in `dash_dash`.
+
+  If "--" is present (i.e., `dash_dash` is non-empty), the argument to its
+  left (if present) is taken as commit.  Otherwise, the first argument is
+  checked if it is a commit or a file.  If commit is not given,
+  `default_commit` is used."""
+  if dash_dash:
+    if len(args) == 0:
+      commit = default_commit
+    elif len(args) > 1:
+      die('at most one commit allowed; %d given' % len(args))
+    else:
+      commit = args[0]
+    object_type = get_object_type(commit)
+    if object_type not in ('commit', 'tag'):
+      if object_type is None:
+        die("'%s' is not a commit" % commit)
+      else:
+        die("'%s' is a %s, but a commit was expected" % (commit, object_type))
+    files = dash_dash[1:]
+  elif args:
+    if disambiguate_revision(args[0]):
+      commit = args[0]
+      files = args[1:]
+    else:
+      commit = default_commit
+      files = args
+  else:
+    commit = default_commit
+    files = []
+  return commit, files
+
+
+def disambiguate_revision(value):
+  """Returns True if `value` is a revision, False if it is a file, or dies."""
+  # If `value` is ambiguous (neither a commit nor a file), the following
+  # command will die with an appropriate error message.
+  run('git', 'rev-parse', value, verbose=False)
+  object_type = get_object_type(value)
+  if object_type is None:
+    return False
+  if object_type in ('commit', 'tag'):
+    return True
+  die('`%s` is a %s, but a commit or filename was expected' %
+      (value, object_type))
+
+
+def get_object_type(value):
+  """Returns a string description of an object's type, or None if it is not
+  a valid git object."""
+  cmd = ['git', 'cat-file', '-t', value]
+  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  stdout, stderr = p.communicate()
+  if p.returncode != 0:
+    return None
+  return stdout.strip()
+
+
+def compute_diff_and_extract_lines(commit, files):
+  """Calls compute_diff() followed by extract_lines()."""
+  diff_process = compute_diff(commit, files)
+  changed_lines = extract_lines(diff_process.stdout)
+  diff_process.stdout.close()
+  diff_process.wait()
+  if diff_process.returncode != 0:
+    # Assume error was already printed to stderr.
+    sys.exit(2)
+  return changed_lines
+
+
+def compute_diff(commit, files):
+  """Return a subprocess object producing the diff from `commit`.
+
+  The return value's `stdin` file object will produce a patch with the
+  differences between the working directory and `commit`, filtered on `files`
+  (if non-empty).  Zero context lines are used in the patch."""
+  cmd = ['git', 'diff-index', '-p', '-U0', commit, '--']
+  cmd.extend(files)
+  p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+  p.stdin.close()
+  return p
+
+
+def extract_lines(patch_file):
+  """Extract the changed lines in `patch_file`.
+
+  The return value is a dictionary mapping filename to a list of (start_line,
+  line_count) pairs.
+
+  The input must have been produced with ``-U0``, meaning unidiff format with
+  zero lines of context.  The return value is a dict mapping filename to a
+  list of line `Range`s."""
+  matches = {}
+  for line in patch_file:
+    match = re.search(r'^\+\+\+\ [^/]+/(.*)', line)
+    if match:
+      filename = match.group(1).rstrip('\r\n')
+    match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
+    if match:
+      start_line = int(match.group(1))
+      line_count = 1
+      if match.group(3):
+        line_count = int(match.group(3))
+      if line_count > 0:
+        matches.setdefault(filename, []).append(Range(start_line, line_count))
+  return matches
+
+
+def filter_by_extension(dictionary, allowed_extensions):
+  """Delete every key in `dictionary` that doesn't have an allowed extension.
+
+  `allowed_extensions` must be a collection of lowercase file extensions,
+  excluding the period."""
+  allowed_extensions = frozenset(allowed_extensions)
+  for filename in dictionary.keys():
+    base_ext = filename.rsplit('.', 1)
+    if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
+      del dictionary[filename]
+
+
+def cd_to_toplevel():
+  """Change to the top level of the git repository."""
+  toplevel = run('git', 'rev-parse', '--show-toplevel')
+  os.chdir(toplevel)
+
+
+def create_tree_from_workdir(filenames):
+  """Create a new git tree with the given files from the working directory.
+
+  Returns the object ID (SHA-1) of the created tree."""
+  return create_tree(filenames, '--stdin')
+
+
+def run_clang_format_and_save_to_tree(changed_lines, binary='clang-format',
+                                      style=None):
+  """Run clang-format on each file and save the result to a git tree.
+
+  Returns the object ID (SHA-1) of the created tree."""
+  def index_info_generator():
+    for filename, line_ranges in changed_lines.iteritems():
+      mode = oct(os.stat(filename).st_mode)
+      blob_id = clang_format_to_blob(filename, line_ranges, binary=binary,
+                                     style=style)
+      yield '%s %s\t%s' % (mode, blob_id, filename)
+  return create_tree(index_info_generator(), '--index-info')
+
+
+def create_tree(input_lines, mode):
+  """Create a tree object from the given input.
+
+  If mode is '--stdin', it must be a list of filenames.  If mode is
+  '--index-info' is must be a list of values suitable for "git update-index
+  --index-info", such as "<mode> <SP> <sha1> <TAB> <filename>".  Any other mode
+  is invalid."""
+  assert mode in ('--stdin', '--index-info')
+  cmd = ['git', 'update-index', '--add', '-z', mode]
+  with temporary_index_file():
+    p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
+    for line in input_lines:
+      p.stdin.write('%s\0' % line)
+    p.stdin.close()
+    if p.wait() != 0:
+      die('`%s` failed' % ' '.join(cmd))
+    tree_id = run('git', 'write-tree')
+    return tree_id
+
+
+def clang_format_to_blob(filename, line_ranges, binary='clang-format',
+                         style=None):
+  """Run clang-format on the given file and save the result to a git blob.
+
+  Returns the object ID (SHA-1) of the created blob."""
+  clang_format_cmd = [binary, filename]
+  if style:
+    clang_format_cmd.extend(['-style='+style])
+  clang_format_cmd.extend([
+      '-lines=%s:%s' % (start_line, start_line+line_count-1)
+      for start_line, line_count in line_ranges])
+  try:
+    clang_format = subprocess.Popen(clang_format_cmd, stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE)
+  except OSError as e:
+    if e.errno == errno.ENOENT:
+      die('cannot find executable "%s"' % binary)
+    else:
+      raise
+  clang_format.stdin.close()
+  hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
+  hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout,
+                                 stdout=subprocess.PIPE)
+  clang_format.stdout.close()
+  stdout = hash_object.communicate()[0]
+  if hash_object.returncode != 0:
+    die('`%s` failed' % ' '.join(hash_object_cmd))
+  if clang_format.wait() != 0:
+    die('`%s` failed' % ' '.join(clang_format_cmd))
+  return stdout.rstrip('\r\n')
+
+
+@contextlib.contextmanager
+def temporary_index_file(tree=None):
+  """Context manager for setting GIT_INDEX_FILE to a temporary file and deleting
+  the file afterward."""
+  index_path = create_temporary_index(tree)
+  old_index_path = os.environ.get('GIT_INDEX_FILE')
+  os.environ['GIT_INDEX_FILE'] = index_path
+  try:
+    yield
+  finally:
+    if old_index_path is None:
+      del os.environ['GIT_INDEX_FILE']
+    else:
+      os.environ['GIT_INDEX_FILE'] = old_index_path
+    os.remove(index_path)
+
+
+def create_temporary_index(tree=None):
+  """Create a temporary index file and return the created file's path.
+
+  If `tree` is not None, use that as the tree to read in.  Otherwise, an
+  empty index is created."""
+  gitdir = run('git', 'rev-parse', '--git-dir')
+  path = os.path.join(gitdir, temp_index_basename)
+  if tree is None:
+    tree = '--empty'
+  run('git', 'read-tree', '--index-output='+path, tree)
+  return path
+
+
+def print_diff(old_tree, new_tree):
+  """Print the diff between the two trees to stdout."""
+  # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output
+  # is expected to be viewed by the user, and only the former does nice things
+  # like color and pagination.
+  subprocess.check_call(['git', 'diff', old_tree, new_tree, '--'])
+
+
+def apply_changes(old_tree, new_tree, force=False, patch_mode=False):
+  """Apply the changes in `new_tree` to the working directory.
+
+  Bails if there are local changes in those files and not `force`.  If
+  `patch_mode`, runs `git checkout --patch` to select hunks interactively."""
+  changed_files = run('git', 'diff-tree', '-r', '-z', '--name-only', old_tree,
+                      new_tree).rstrip('\0').split('\0')
+  if not force:
+    unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
+    if unstaged_files:
+      print >>sys.stderr, ('The following files would be modified but '
+                           'have unstaged changes:')
+      print >>sys.stderr, unstaged_files
+      print >>sys.stderr, 'Please commit, stage, or stash them first.'
+      sys.exit(2)
+  if patch_mode:
+    # In patch mode, we could just as well create an index from the new tree
+    # and checkout from that, but then the user will be presented with a
+    # message saying "Discard ... from worktree".  Instead, we use the old
+    # tree as the index and checkout from new_tree, which gives the slightly
+    # better message, "Apply ... to index and worktree".  This is not quite
+    # right, since it won't be applied to the user's index, but oh well.
+    with temporary_index_file(old_tree):
+      subprocess.check_call(['git', 'checkout', '--patch', new_tree])
+    index_tree = old_tree
+  else:
+    with temporary_index_file(new_tree):
+      run('git', 'checkout-index', '-a', '-f')
+  return changed_files
+
+
+def run(*args, **kwargs):
+  stdin = kwargs.pop('stdin', '')
+  verbose = kwargs.pop('verbose', True)
+  strip = kwargs.pop('strip', True)
+  for name in kwargs:
+    raise TypeError("run() got an unexpected keyword argument '%s'" % name)
+  p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                       stdin=subprocess.PIPE)
+  stdout, stderr = p.communicate(input=stdin)
+  if p.returncode == 0:
+    if stderr:
+      if verbose:
+        print >>sys.stderr, '`%s` printed to stderr:' % ' '.join(args)
+      print >>sys.stderr, stderr.rstrip()
+    if strip:
+      stdout = stdout.rstrip('\r\n')
+    return stdout
+  if verbose:
+    print >>sys.stderr, '`%s` returned %s' % (' '.join(args), p.returncode)
+  if stderr:
+    print >>sys.stderr, stderr.rstrip()
+  sys.exit(2)
+
+
+def die(message):
+  print >>sys.stderr, 'error:', message
+  sys.exit(2)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/bin/llc b/bin/llc
new file mode 100755
index 0000000..5d4fa00
--- /dev/null
+++ b/bin/llc
Binary files differ
diff --git a/bin/lli b/bin/lli
new file mode 100755
index 0000000..a89e956
--- /dev/null
+++ b/bin/lli
Binary files differ
diff --git a/bin/llvm-ar b/bin/llvm-ar
new file mode 100755
index 0000000..ae4106c
--- /dev/null
+++ b/bin/llvm-ar
Binary files differ
diff --git a/bin/llvm-as b/bin/llvm-as
new file mode 100755
index 0000000..a96d81a
--- /dev/null
+++ b/bin/llvm-as
Binary files differ
diff --git a/bin/llvm-bcanalyzer b/bin/llvm-bcanalyzer
new file mode 100755
index 0000000..a70cb23
--- /dev/null
+++ b/bin/llvm-bcanalyzer
Binary files differ
diff --git a/bin/llvm-c-test b/bin/llvm-c-test
new file mode 100755
index 0000000..4b005dd
--- /dev/null
+++ b/bin/llvm-c-test
Binary files differ
diff --git a/bin/llvm-config b/bin/llvm-config
new file mode 100755
index 0000000..643cf61
--- /dev/null
+++ b/bin/llvm-config
Binary files differ
diff --git a/bin/llvm-cov b/bin/llvm-cov
new file mode 100755
index 0000000..ddfa552
--- /dev/null
+++ b/bin/llvm-cov
Binary files differ
diff --git a/bin/llvm-diff b/bin/llvm-diff
new file mode 100755
index 0000000..2552255
--- /dev/null
+++ b/bin/llvm-diff
Binary files differ
diff --git a/bin/llvm-dis b/bin/llvm-dis
new file mode 100755
index 0000000..30879cb
--- /dev/null
+++ b/bin/llvm-dis
Binary files differ
diff --git a/bin/llvm-dwarfdump b/bin/llvm-dwarfdump
new file mode 100755
index 0000000..adbbb93
--- /dev/null
+++ b/bin/llvm-dwarfdump
Binary files differ
diff --git a/bin/llvm-extract b/bin/llvm-extract
new file mode 100755
index 0000000..3a066ec
--- /dev/null
+++ b/bin/llvm-extract
Binary files differ
diff --git a/bin/llvm-link b/bin/llvm-link
new file mode 100755
index 0000000..5035ce6
--- /dev/null
+++ b/bin/llvm-link
Binary files differ
diff --git a/bin/llvm-lto b/bin/llvm-lto
new file mode 100755
index 0000000..04b412c
--- /dev/null
+++ b/bin/llvm-lto
Binary files differ
diff --git a/bin/llvm-mc b/bin/llvm-mc
new file mode 100755
index 0000000..52b2970
--- /dev/null
+++ b/bin/llvm-mc
Binary files differ
diff --git a/bin/llvm-mcmarkup b/bin/llvm-mcmarkup
new file mode 100755
index 0000000..43fd3d8
--- /dev/null
+++ b/bin/llvm-mcmarkup
Binary files differ
diff --git a/bin/llvm-nm b/bin/llvm-nm
new file mode 100755
index 0000000..0a32d69
--- /dev/null
+++ b/bin/llvm-nm
Binary files differ
diff --git a/bin/llvm-objdump b/bin/llvm-objdump
new file mode 100755
index 0000000..cffbd4f
--- /dev/null
+++ b/bin/llvm-objdump
Binary files differ
diff --git a/bin/llvm-profdata b/bin/llvm-profdata
new file mode 100755
index 0000000..7aad3be
--- /dev/null
+++ b/bin/llvm-profdata
Binary files differ
diff --git a/bin/llvm-readobj b/bin/llvm-readobj
new file mode 100755
index 0000000..a0a320c
--- /dev/null
+++ b/bin/llvm-readobj
Binary files differ
diff --git a/bin/llvm-rtdyld b/bin/llvm-rtdyld
new file mode 100755
index 0000000..392dbe4
--- /dev/null
+++ b/bin/llvm-rtdyld
Binary files differ
diff --git a/bin/llvm-size b/bin/llvm-size
new file mode 100755
index 0000000..0bdc72a
--- /dev/null
+++ b/bin/llvm-size
Binary files differ
diff --git a/bin/llvm-stress b/bin/llvm-stress
new file mode 100755
index 0000000..913fb37
--- /dev/null
+++ b/bin/llvm-stress
Binary files differ
diff --git a/bin/llvm-symbolizer b/bin/llvm-symbolizer
new file mode 100755
index 0000000..8712d48
--- /dev/null
+++ b/bin/llvm-symbolizer
Binary files differ
diff --git a/bin/llvm-tblgen b/bin/llvm-tblgen
new file mode 100755
index 0000000..3b31b8b
--- /dev/null
+++ b/bin/llvm-tblgen
Binary files differ
diff --git a/bin/macho-dump b/bin/macho-dump
new file mode 100755
index 0000000..e973b85
--- /dev/null
+++ b/bin/macho-dump
Binary files differ
diff --git a/bin/opt b/bin/opt
new file mode 100755
index 0000000..5a42f29
--- /dev/null
+++ b/bin/opt
Binary files differ
diff --git a/include/c++/v1/__bit_reference b/include/c++/v1/__bit_reference
new file mode 100644
index 0000000..d9ebfbe
--- /dev/null
+++ b/include/c++/v1/__bit_reference
@@ -0,0 +1,1287 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_REFERENCE
+#define _LIBCPP___BIT_REFERENCE
+
+#include <__config>
+#include <algorithm>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator;
+template <class _Cp> class __bit_const_reference;
+
+template <class _Tp>
+struct __has_storage_type
+{
+    static const bool value = false;
+};
+
+template <class _Cp, bool = __has_storage_type<_Cp>::value>
+class __bit_reference
+{
+    typedef typename _Cp::__storage_type    __storage_type;
+    typedef typename _Cp::__storage_pointer __storage_pointer;
+
+    __storage_pointer __seg_;
+    __storage_type    __mask_;
+
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
+    friend typename _Cp::__self;
+#else
+    friend class _Cp::__self;
+#endif
+    friend class __bit_const_reference<_Cp>;
+    friend class __bit_iterator<_Cp, false>;
+public:
+    _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
+        {return static_cast<bool>(*__seg_ & __mask_);}
+    _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT
+        {return !static_cast<bool>(*this);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_reference& operator=(bool __x) _NOEXCEPT
+    {
+        if (__x)
+            *__seg_ |= __mask_;
+        else
+            *__seg_ &= ~__mask_;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT
+        {return operator=(static_cast<bool>(__x));}
+
+    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;}
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT
+        {return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
+        : __seg_(__s), __mask_(__m) {}
+};
+
+template <class _Cp>
+class __bit_reference<_Cp, false>
+{
+};
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
+{
+    bool __t = __x;
+    __x = __y;
+    __y = __t;
+}
+
+template <class _Cp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT
+{
+    bool __t = __x;
+    __x = __y;
+    __y = __t;
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT
+{
+    bool __t = __x;
+    __x = __y;
+    __y = __t;
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT
+{
+    bool __t = __x;
+    __x = __y;
+    __y = __t;
+}
+
+template <class _Cp>
+class __bit_const_reference
+{
+    typedef typename _Cp::__storage_type          __storage_type;
+    typedef typename _Cp::__const_storage_pointer __storage_pointer;
+
+    __storage_pointer        __seg_;
+    __storage_type __mask_;
+
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
+    friend typename _Cp::__self;
+#else
+    friend class _Cp::__self;
+#endif
+    friend class __bit_iterator<_Cp, true>;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT
+        : __seg_(__x.__seg_), __mask_(__x.__mask_) {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT
+        {return static_cast<bool>(*__seg_ & __mask_);}
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT
+        {return __bit_iterator<_Cp, true>(__seg_, static_cast<unsigned>(__ctz(__mask_)));}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR
+    __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
+        : __seg_(__s), __mask_(__m) {}
+
+    __bit_const_reference& operator=(const __bit_const_reference& __x);
+};
+
+// find
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, _IsConst>
+__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _It;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        __storage_type __b = *__first.__seg_ & __m;
+        if (__b)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+        if (__n == __dn)
+            return __first + __n;
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
+        if (*__first.__seg_)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(*__first.__seg_)));
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __storage_type __b = *__first.__seg_ & __m;
+        if (__b)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+    }
+    return _It(__first.__seg_, static_cast<unsigned>(__n));
+}
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, _IsConst>
+__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _It;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        __storage_type __b = ~*__first.__seg_ & __m;
+        if (__b)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+        if (__n == __dn)
+            return __first + __n;
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
+    {
+        __storage_type __b = ~*__first.__seg_;
+        if (__b)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+    }
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __storage_type __b = ~*__first.__seg_ & __m;
+        if (__b)
+            return _It(__first.__seg_, static_cast<unsigned>(_VSTD::__ctz(__b)));
+    }
+    return _It(__first.__seg_, static_cast<unsigned>(__n));
+}
+
+template <class _Cp, bool _IsConst, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<_Cp, _IsConst>
+find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
+{
+    if (static_cast<bool>(__value_))
+        return __find_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return __find_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
+}
+
+// count
+
+template <class _Cp, bool _IsConst>
+typename __bit_iterator<_Cp, _IsConst>::difference_type
+__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _It;
+    typedef typename _It::__storage_type __storage_type;
+    typedef typename _It::difference_type difference_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    difference_type __r = 0;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        __r = _VSTD::__pop_count(*__first.__seg_ & __m);
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
+        __r += _VSTD::__pop_count(*__first.__seg_);
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __r += _VSTD::__pop_count(*__first.__seg_ & __m);
+    }
+    return __r;
+}
+
+template <class _Cp, bool _IsConst>
+typename __bit_iterator<_Cp, _IsConst>::difference_type
+__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _It;
+    typedef typename _It::__storage_type __storage_type;
+    typedef typename _It::difference_type difference_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    difference_type __r = 0;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        __r = _VSTD::__pop_count(~*__first.__seg_ & __m);
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
+        __r += _VSTD::__pop_count(~*__first.__seg_);
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __r += _VSTD::__pop_count(~*__first.__seg_ & __m);
+    }
+    return __r;
+}
+
+template <class _Cp, bool _IsConst, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __bit_iterator<_Cp, _IsConst>::difference_type
+count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value_)
+{
+    if (static_cast<bool>(__value_))
+        return __count_bool_true(__first, static_cast<typename _Cp::size_type>(__last - __first));
+    return __count_bool_false(__first, static_cast<typename _Cp::size_type>(__last - __first));
+}
+
+// fill_n
+
+template <class _Cp>
+void
+__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, false> _It;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        *__first.__seg_ &= ~__m;
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    __storage_type __nw = __n / __bits_per_word;
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
+    __n -= __nw * __bits_per_word;
+    // do last partial word
+    if (__n > 0)
+    {
+        __first.__seg_ += __nw;
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        *__first.__seg_ &= ~__m;
+    }
+}
+
+template <class _Cp>
+void
+__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n)
+{
+    typedef __bit_iterator<_Cp, false> _It;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    // do first partial word
+    if (__first.__ctz_ != 0)
+    {
+        __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
+        __storage_type __dn = _VSTD::min(__clz_f, __n);
+        __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+        *__first.__seg_ |= __m;
+        __n -= __dn;
+        ++__first.__seg_;
+    }
+    // do middle whole words
+    __storage_type __nw = __n / __bits_per_word;
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
+    __n -= __nw * __bits_per_word;
+    // do last partial word
+    if (__n > 0)
+    {
+        __first.__seg_ += __nw;
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        *__first.__seg_ |= __m;
+    }
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value_)
+{
+    if (__n > 0)
+    {
+        if (__value_)
+            __fill_n_true(__first, __n);
+        else
+            __fill_n_false(__first, __n);
+    }
+}
+
+// fill
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_)
+{
+    _VSTD::fill_n(__first, static_cast<typename _Cp::size_type>(__last - __first), __value_);
+}
+
+// copy
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, false>
+__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
+                                                     __bit_iterator<_Cp, false> __result)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _In;
+    typedef  typename _In::difference_type difference_type;
+    typedef typename _In::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _In::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first.__ctz_ != 0)
+        {
+            unsigned __clz = __bits_per_word - __first.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
+            __storage_type __b = *__first.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b;
+            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
+            ++__first.__seg_;
+            // __first.__ctz_ = 0;
+        }
+        // __first.__ctz_ == 0;
+        // do middle words
+        __storage_type __nw = __n / __bits_per_word;
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__first.__seg_),
+                       __nw * sizeof(__storage_type));
+        __n -= __nw * __bits_per_word;
+        __result.__seg_ += __nw;
+        // do last word
+        if (__n > 0)
+        {
+            __first.__seg_ += __nw;
+            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            __storage_type __b = *__first.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b;
+            __result.__ctz_ = static_cast<unsigned>(__n);
+        }
+    }
+    return __result;
+}
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, false>
+__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
+                                                       __bit_iterator<_Cp, false> __result)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _In;
+    typedef  typename _In::difference_type difference_type;
+    typedef typename _In::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _In::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first.__ctz_ != 0)
+        {
+            unsigned __clz_f = __bits_per_word - __first.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+            __storage_type __b = *__first.__seg_ & __m;
+            unsigned __clz_r = __bits_per_word - __result.__ctz_;
+            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
+            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
+            *__result.__seg_ &= ~__m;
+            if (__result.__ctz_ > __first.__ctz_)
+                *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_);
+            else
+                *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_);
+            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
+            __dn -= __ddn;
+            if (__dn > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
+                *__result.__seg_ &= ~__m;
+                *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
+                __result.__ctz_ = static_cast<unsigned>(__dn);
+            }
+            ++__first.__seg_;
+            // __first.__ctz_ = 0;
+        }
+        // __first.__ctz_ == 0;
+        // do middle words
+        unsigned __clz_r = __bits_per_word - __result.__ctz_;
+        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
+        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
+        {
+            __storage_type __b = *__first.__seg_;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b << __result.__ctz_;
+            ++__result.__seg_;
+            *__result.__seg_ &= __m;
+            *__result.__seg_ |= __b >> __clz_r;
+        }
+        // do last word
+        if (__n > 0)
+        {
+            __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            __storage_type __b = *__first.__seg_ & __m;
+            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
+            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b << __result.__ctz_;
+            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
+            __n -= __dn;
+            if (__n > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __n);
+                *__result.__seg_ &= ~__m;
+                *__result.__seg_ |= __b >> __dn;
+                __result.__ctz_ = static_cast<unsigned>(__n);
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _Cp, bool _IsConst>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<_Cp, false>
+copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
+{
+    if (__first.__ctz_ == __result.__ctz_)
+        return __copy_aligned(__first, __last, __result);
+    return __copy_unaligned(__first, __last, __result);
+}
+
+// copy_backward
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, false>
+__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
+                                                     __bit_iterator<_Cp, false> __result)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _In;
+    typedef  typename _In::difference_type difference_type;
+    typedef typename _In::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _In::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__last.__ctz_ != 0)
+        {
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
+            __n -= __dn;
+            unsigned __clz = __bits_per_word - __last.__ctz_;
+            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz);
+            __storage_type __b = *__last.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b;
+            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
+                                                       __result.__ctz_)  % __bits_per_word);
+            // __last.__ctz_ = 0
+         }
+        // __last.__ctz_ == 0 || __n == 0
+        // __result.__ctz_ == 0 || __n == 0
+        // do middle words
+        __storage_type __nw = __n / __bits_per_word;
+        __result.__seg_ -= __nw;
+        __last.__seg_ -= __nw;
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__last.__seg_),
+                       __nw * sizeof(__storage_type));
+        __n -= __nw * __bits_per_word;
+        // do last word
+        if (__n > 0)
+        {
+            __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n);
+            __storage_type __b = *--__last.__seg_ & __m;
+            *--__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b;
+            __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
+        }
+    }
+    return __result;
+}
+
+template <class _Cp, bool _IsConst>
+__bit_iterator<_Cp, false>
+__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last,
+                                                       __bit_iterator<_Cp, false> __result)
+{
+    typedef __bit_iterator<_Cp, _IsConst> _In;
+    typedef  typename _In::difference_type difference_type;
+    typedef typename _In::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _In::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__last.__ctz_ != 0)
+        {
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__last.__ctz_), __n);
+            __n -= __dn;
+            unsigned __clz_l = __bits_per_word - __last.__ctz_;
+            __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l);
+            __storage_type __b = *__last.__seg_ & __m;
+            unsigned __clz_r = __bits_per_word - __result.__ctz_;
+            __storage_type __ddn = _VSTD::min(__dn, static_cast<difference_type>(__result.__ctz_));
+            if (__ddn > 0)
+            {
+                __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r);
+                *__result.__seg_ &= ~__m;
+                if (__result.__ctz_ > __last.__ctz_)
+                    *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
+                else
+                    *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_);
+                __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) +
+                                                         __result.__ctz_)  % __bits_per_word);
+                __dn -= __ddn;
+            }
+            if (__dn > 0)
+            {
+                // __result.__ctz_ == 0
+                --__result.__seg_;
+                __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1));
+                __m = ~__storage_type(0) << __result.__ctz_;
+                *__result.__seg_ &= ~__m;
+                __last.__ctz_ -= __dn + __ddn;
+                *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_);
+            }
+            // __last.__ctz_ = 0
+         }
+        // __last.__ctz_ == 0 || __n == 0
+        // __result.__ctz_ != 0 || __n == 0
+        // do middle words
+        unsigned __clz_r = __bits_per_word - __result.__ctz_;
+        __storage_type __m = ~__storage_type(0) >> __clz_r;
+        for (; __n >= __bits_per_word; __n -= __bits_per_word)
+        {
+            __storage_type __b = *--__last.__seg_;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b >> __clz_r;
+            *--__result.__seg_ &= __m;
+            *__result.__seg_ |= __b << __result.__ctz_;
+        }
+        // do last word
+        if (__n > 0)
+        {
+            __m = ~__storage_type(0) << (__bits_per_word - __n);
+            __storage_type __b = *--__last.__seg_ & __m;
+            __clz_r = __bits_per_word - __result.__ctz_;
+            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__result.__ctz_));
+            __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r);
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_);
+            __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) +
+                                                     __result.__ctz_)  % __bits_per_word);
+            __n -= __dn;
+            if (__n > 0)
+            {
+                // __result.__ctz_ == 0
+                --__result.__seg_;
+                __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1));
+                __m = ~__storage_type(0) << __result.__ctz_;
+                *__result.__seg_ &= ~__m;
+                *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _Cp, bool _IsConst>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<_Cp, false>
+copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
+{
+    if (__last.__ctz_ == __result.__ctz_)
+        return __copy_backward_aligned(__first, __last, __result);
+    return __copy_backward_unaligned(__first, __last, __result);
+}
+
+// move
+
+template <class _Cp, bool _IsConst>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<_Cp, false>
+move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
+{
+    return _VSTD::copy(__first, __last, __result);
+}
+
+// move_backward
+
+template <class _Cp, bool _IsConst>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<_Cp, false>
+move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result)
+{
+    return _VSTD::copy(__first, __last, __result);
+}
+
+// swap_ranges
+
+template <class __C1, class __C2>
+__bit_iterator<__C2, false>
+__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
+                      __bit_iterator<__C2, false> __result)
+{
+    typedef __bit_iterator<__C1, false> _I1;
+    typedef  typename _I1::difference_type difference_type;
+    typedef typename _I1::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _I1::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first.__ctz_ != 0)
+        {
+            unsigned __clz = __bits_per_word - __first.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
+            __storage_type __b1 = *__first.__seg_ & __m;
+            *__first.__seg_ &= ~__m;
+            __storage_type __b2 = *__result.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b1;
+            *__first.__seg_  |= __b2;
+            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
+            ++__first.__seg_;
+            // __first.__ctz_ = 0;
+        }
+        // __first.__ctz_ == 0;
+        // do middle words
+        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_)
+            swap(*__first.__seg_, *__result.__seg_);
+        // do last word
+        if (__n > 0)
+        {
+            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            __storage_type __b1 = *__first.__seg_ & __m;
+            *__first.__seg_ &= ~__m;
+            __storage_type __b2 = *__result.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b1;
+            *__first.__seg_  |= __b2;
+            __result.__ctz_ = static_cast<unsigned>(__n);
+        }
+    }
+    return __result;
+}
+
+template <class __C1, class __C2>
+__bit_iterator<__C2, false>
+__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last,
+                        __bit_iterator<__C2, false> __result)
+{
+    typedef __bit_iterator<__C1, false> _I1;
+    typedef  typename _I1::difference_type difference_type;
+    typedef typename _I1::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _I1::__bits_per_word;
+    difference_type __n = __last - __first;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first.__ctz_ != 0)
+        {
+            unsigned __clz_f = __bits_per_word - __first.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+            __storage_type __b1 = *__first.__seg_ & __m;
+            *__first.__seg_ &= ~__m;
+            unsigned __clz_r = __bits_per_word - __result.__ctz_;
+            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
+            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
+            __storage_type __b2 = *__result.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            if (__result.__ctz_ > __first.__ctz_)
+            {
+                unsigned __s = __result.__ctz_ - __first.__ctz_;
+                *__result.__seg_ |= __b1 << __s;
+                *__first.__seg_  |= __b2 >> __s;
+            }
+            else
+            {
+                unsigned __s = __first.__ctz_ - __result.__ctz_;
+                *__result.__seg_ |= __b1 >> __s;
+                *__first.__seg_  |= __b2 << __s;
+            }
+            __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_)  % __bits_per_word);
+            __dn -= __ddn;
+            if (__dn > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
+                __b2 = *__result.__seg_ & __m;
+                *__result.__seg_ &= ~__m;
+                unsigned __s = __first.__ctz_ + __ddn;
+                *__result.__seg_ |= __b1 >> __s;
+                *__first.__seg_  |= __b2 << __s;
+                __result.__ctz_ = static_cast<unsigned>(__dn);
+            }
+            ++__first.__seg_;
+            // __first.__ctz_ = 0;
+        }
+        // __first.__ctz_ == 0;
+        // do middle words
+        __storage_type __m = ~__storage_type(0) << __result.__ctz_;
+        unsigned __clz_r = __bits_per_word - __result.__ctz_;
+        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_)
+        {
+            __storage_type __b1 = *__first.__seg_;
+            __storage_type __b2 = *__result.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b1 << __result.__ctz_;
+            *__first.__seg_  = __b2 >> __result.__ctz_;
+            ++__result.__seg_;
+            __b2 = *__result.__seg_ & ~__m;
+            *__result.__seg_ &= __m;
+            *__result.__seg_ |= __b1 >> __clz_r;
+            *__first.__seg_  |= __b2 << __clz_r;
+        }
+        // do last word
+        if (__n > 0)
+        {
+            __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            __storage_type __b1 = *__first.__seg_ & __m;
+            *__first.__seg_ &= ~__m;
+            __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r);
+            __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
+            __storage_type __b2 = *__result.__seg_ & __m;
+            *__result.__seg_ &= ~__m;
+            *__result.__seg_ |= __b1 << __result.__ctz_;
+            *__first.__seg_  |= __b2 >> __result.__ctz_;
+            __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word;
+            __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_)  % __bits_per_word);
+            __n -= __dn;
+            if (__n > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __n);
+                __b2 = *__result.__seg_ & __m;
+                *__result.__seg_ &= ~__m;
+                *__result.__seg_ |= __b1 >> __dn;
+                *__first.__seg_  |= __b2 << __dn;
+                __result.__ctz_ = static_cast<unsigned>(__n);
+            }
+        }
+    }
+    return __result;
+}
+
+template <class __C1, class __C2>
+inline _LIBCPP_INLINE_VISIBILITY
+__bit_iterator<__C2, false>
+swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1,
+            __bit_iterator<__C2, false> __first2)
+{
+    if (__first1.__ctz_ == __first2.__ctz_)
+        return __swap_ranges_aligned(__first1, __last1, __first2);
+    return __swap_ranges_unaligned(__first1, __last1, __first2);
+}
+
+// rotate
+
+template <class _Cp>
+struct __bit_array
+{
+    typedef typename _Cp::difference_type difference_type;
+    typedef typename _Cp::__storage_type  __storage_type;
+    typedef typename _Cp::__storage_pointer __storage_pointer;
+    typedef typename _Cp::iterator        iterator;
+    static const unsigned __bits_per_word = _Cp::__bits_per_word;
+    static const unsigned _Np = 4;
+
+    difference_type __size_;
+    __storage_type __word_[_Np];
+
+    _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
+        {return static_cast<difference_type>(_Np * __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY iterator begin()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
+    }
+    _LIBCPP_INLINE_VISIBILITY iterator end()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
+                                                  static_cast<unsigned>(__size_ % __bits_per_word));
+    }
+};
+
+template <class _Cp>
+__bit_iterator<_Cp, false>
+rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last)
+{
+    typedef __bit_iterator<_Cp, false> _I1;
+    typedef  typename _I1::difference_type difference_type;
+    typedef typename _I1::__storage_type __storage_type;
+    difference_type __d1 = __middle - __first;
+    difference_type __d2 = __last - __middle;
+    _I1 __r = __first + __d2;
+    while (__d1 != 0 && __d2 != 0)
+    {
+        if (__d1 <= __d2)
+        {
+            if (__d1 <= __bit_array<_Cp>::capacity())
+            {
+                __bit_array<_Cp> __b(__d1);
+                _VSTD::copy(__first, __middle, __b.begin());
+                _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first));
+                break;
+            }
+            else
+            {
+                __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle);
+                __first = __middle;
+                __middle = __mp;
+                __d2 -= __d1;
+            }
+        }
+        else
+        {
+            if (__d2 <= __bit_array<_Cp>::capacity())
+            {
+                __bit_array<_Cp> __b(__d2);
+                _VSTD::copy(__middle, __last, __b.begin());
+                _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last));
+                break;
+            }
+            else
+            {
+                __bit_iterator<_Cp, false> __mp = __first + __d2;
+                _VSTD::swap_ranges(__first, __mp, __middle);
+                __first = __mp;
+                __d1 -= __d2;
+            }
+        }
+    }
+    return __r;
+}
+
+// equal
+
+template <class _Cp, bool _IC1, bool _IC2>
+bool
+__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
+                  __bit_iterator<_Cp, _IC2> __first2)
+{
+    typedef __bit_iterator<_Cp, _IC1> _It;
+    typedef  typename _It::difference_type difference_type;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    difference_type __n = __last1 - __first1;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first1.__ctz_ != 0)
+        {
+            unsigned __clz_f = __bits_per_word - __first1.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz_f), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
+            __storage_type __b = *__first1.__seg_ & __m;
+            unsigned __clz_r = __bits_per_word - __first2.__ctz_;
+            __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r);
+            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn));
+            if (__first2.__ctz_ > __first1.__ctz_)
+            {
+                if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_)))
+                    return false;
+            }
+            else
+            {
+                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_)))
+                    return false;
+            }
+            __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word;
+            __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_)  % __bits_per_word);
+            __dn -= __ddn;
+            if (__dn > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __dn);
+                if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn)))
+                    return false;
+                __first2.__ctz_ = static_cast<unsigned>(__dn);
+            }
+            ++__first1.__seg_;
+            // __first1.__ctz_ = 0;
+        }
+        // __first1.__ctz_ == 0;
+        // do middle words
+        unsigned __clz_r = __bits_per_word - __first2.__ctz_;
+        __storage_type __m = ~__storage_type(0) << __first2.__ctz_;
+        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_)
+        {
+            __storage_type __b = *__first1.__seg_;
+            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
+                return false;
+            ++__first2.__seg_;
+            if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r))
+                return false;
+        }
+        // do last word
+        if (__n > 0)
+        {
+            __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            __storage_type __b = *__first1.__seg_ & __m;
+            __storage_type __dn = _VSTD::min(__n, static_cast<difference_type>(__clz_r));
+            __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn));
+            if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_))
+                return false;
+            __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word;
+            __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_)  % __bits_per_word);
+            __n -= __dn;
+            if (__n > 0)
+            {
+                __m = ~__storage_type(0) >> (__bits_per_word - __n);
+                if ((*__first2.__seg_ & __m) != (__b >> __dn))
+                    return false;
+            }
+        }
+    }
+    return true;
+}
+
+template <class _Cp, bool _IC1, bool _IC2>
+bool
+__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1,
+                __bit_iterator<_Cp, _IC2> __first2)
+{
+    typedef __bit_iterator<_Cp, _IC1> _It;
+    typedef  typename _It::difference_type difference_type;
+    typedef typename _It::__storage_type __storage_type;
+    static const unsigned __bits_per_word = _It::__bits_per_word;
+    difference_type __n = __last1 - __first1;
+    if (__n > 0)
+    {
+        // do first word
+        if (__first1.__ctz_ != 0)
+        {
+            unsigned __clz = __bits_per_word - __first1.__ctz_;
+            difference_type __dn = _VSTD::min(static_cast<difference_type>(__clz), __n);
+            __n -= __dn;
+            __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn));
+            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
+                return false;
+            ++__first2.__seg_;
+            ++__first1.__seg_;
+            // __first1.__ctz_ = 0;
+            // __first2.__ctz_ = 0;
+        }
+        // __first1.__ctz_ == 0;
+        // __first2.__ctz_ == 0;
+        // do middle words
+        for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_)
+            if (*__first2.__seg_ != *__first1.__seg_)
+                return false;
+        // do last word
+        if (__n > 0)
+        {
+            __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+            if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m))
+                return false;
+        }
+    }
+    return true;
+}
+
+template <class _Cp, bool _IC1, bool _IC2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2)
+{
+    if (__first1.__ctz_ == __first2.__ctz_)
+        return __equal_aligned(__first1, __last1, __first2);
+    return __equal_unaligned(__first1, __last1, __first2);
+}
+
+template <class _Cp, bool _IsConst,
+          typename _Cp::__storage_type>
+class __bit_iterator
+{
+public:
+    typedef typename _Cp::difference_type                                                          difference_type;
+    typedef bool                                                                                  value_type;
+    typedef __bit_iterator                                                                        pointer;
+    typedef typename conditional<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >::type reference;
+    typedef random_access_iterator_tag                                                            iterator_category;
+
+private:
+    typedef typename _Cp::__storage_type                                           __storage_type;
+    typedef typename conditional<_IsConst, typename _Cp::__const_storage_pointer,
+                                           typename _Cp::__storage_pointer>::type  __storage_pointer;
+    static const unsigned __bits_per_word = _Cp::__bits_per_word;
+
+    __storage_pointer __seg_;
+    unsigned          __ctz_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __seg_(nullptr), __ctz_(0)
+#endif
+    {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT
+        : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
+        {return reference(__seg_, __storage_type(1) << __ctz_);}
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++()
+    {
+        if (__ctz_ != __bits_per_word-1)
+            ++__ctz_;
+        else
+        {
+            __ctz_ = 0;
+            ++__seg_;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator++(int)
+    {
+        __bit_iterator __tmp = *this;
+        ++(*this);
+        return __tmp;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator--()
+    {
+        if (__ctz_ != 0)
+            --__ctz_;
+        else
+        {
+            __ctz_ = __bits_per_word - 1;
+            --__seg_;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator--(int)
+    {
+        __bit_iterator __tmp = *this;
+        --(*this);
+        return __tmp;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator+=(difference_type __n)
+    {
+        if (__n >= 0)
+            __seg_ += (__n + __ctz_) / __bits_per_word;
+        else
+            __seg_ += static_cast<difference_type>(__n - __bits_per_word + __ctz_ + 1)
+                    / static_cast<difference_type>(__bits_per_word);
+        __n &= (__bits_per_word - 1);
+        __ctz_ = static_cast<unsigned>((__n + __ctz_)  % __bits_per_word);
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator-=(difference_type __n)
+    {
+        return *this += -__n;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator+(difference_type __n) const
+    {
+        __bit_iterator __t(*this);
+        __t += __n;
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __bit_iterator operator-(difference_type __n) const
+    {
+        __bit_iterator __t(*this);
+        __t -= __n;
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const {return *(*this + __n);}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return !(__x == __y);}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return __y < __x;}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return !(__y < __x);}
+
+    _LIBCPP_INLINE_VISIBILITY friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y)
+        {return !(__x < __y);}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
+        : __seg_(__s), __ctz_(__ctz) {}
+
+#if defined(__clang__) || defined(__IBMCPP__) || defined(_LIBCPP_MSVC)
+    friend typename _Cp::__self;
+#else
+    friend class _Cp::__self;
+#endif
+    friend class __bit_reference<_Cp>;
+    friend class __bit_const_reference<_Cp>;
+    friend class __bit_iterator<_Cp, true>;
+    template <class _Dp> friend struct __bit_array;
+    template <class _Dp> friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
+    template <class _Dp> friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first,
+                                                                                  __bit_iterator<_Dp, _IC> __last,
+                                                                                  __bit_iterator<_Dp, false> __result);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first,
+                                                                                    __bit_iterator<_Dp, _IC> __last,
+                                                                                    __bit_iterator<_Dp, false> __result);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first,
+                                                                        __bit_iterator<_Dp, _IC> __last,
+                                                                        __bit_iterator<_Dp, false> __result);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first,
+                                                                                           __bit_iterator<_Dp, _IC> __last,
+                                                                                           __bit_iterator<_Dp, false> __result);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first,
+                                                                                             __bit_iterator<_Dp, _IC> __last,
+                                                                                             __bit_iterator<_Dp, false> __result);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first,
+                                                                                 __bit_iterator<_Dp, _IC> __last,
+                                                                                 __bit_iterator<_Dp, false> __result);
+    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>,
+                                                                                           __bit_iterator<__C1, false>,
+                                                                                           __bit_iterator<__C2, false>);
+    template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>,
+                                                                                             __bit_iterator<__C1, false>,
+                                                                                             __bit_iterator<__C2, false>);
+    template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>,
+                                                                                 __bit_iterator<__C1, false>,
+                                                                                 __bit_iterator<__C2, false>);
+    template <class _Dp> friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>,
+                                                                __bit_iterator<_Dp, false>,
+                                                                __bit_iterator<_Dp, false>);
+    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>,
+                                                    __bit_iterator<_Dp, _IC1>,
+                                                    __bit_iterator<_Dp, _IC2>);
+    template <class _Dp, bool _IC1, bool _IC2> friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>,
+                                                      __bit_iterator<_Dp, _IC1>,
+                                                      __bit_iterator<_Dp, _IC2>);
+    template <class _Dp, bool _IC1, bool _IC2> friend bool equal(__bit_iterator<_Dp, _IC1>,
+                                                                __bit_iterator<_Dp, _IC1>,
+                                                                __bit_iterator<_Dp, _IC2>);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>,
+                                                                          typename _Dp::size_type);
+    template <class _Dp, bool _IC> friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>,
+                                                                           typename _Dp::size_type);
+    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
+                   __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
+    template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::difference_type
+                   __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___BIT_REFERENCE
diff --git a/include/c++/v1/__config b/include/c++/v1/__config
new file mode 100644
index 0000000..ce235af
--- /dev/null
+++ b/include/c++/v1/__config
@@ -0,0 +1,693 @@
+// -*- C++ -*-
+//===--------------------------- __config ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CONFIG
+#define _LIBCPP_CONFIG
+
+#if !defined(_MSC_VER) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+#ifdef __GNUC__
+#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
+#endif
+
+#define _LIBCPP_VERSION 1101
+
+#define _LIBCPP_ABI_VERSION 1
+
+#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y
+#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y)
+
+#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION)
+
+#ifdef __LITTLE_ENDIAN__
+#if __LITTLE_ENDIAN__
+#define _LIBCPP_LITTLE_ENDIAN 1
+#define _LIBCPP_BIG_ENDIAN    0
+#endif  // __LITTLE_ENDIAN__
+#endif  // __LITTLE_ENDIAN__
+
+#ifdef __BIG_ENDIAN__
+#if __BIG_ENDIAN__
+#define _LIBCPP_LITTLE_ENDIAN 0
+#define _LIBCPP_BIG_ENDIAN    1
+#endif  // __BIG_ENDIAN__
+#endif  // __BIG_ENDIAN__
+
+#ifdef __FreeBSD__
+# include <sys/endian.h>
+#  if _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 1
+#   define _LIBCPP_BIG_ENDIAN    0
+# else  // _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 0
+#   define _LIBCPP_BIG_ENDIAN    1
+# endif  // _BYTE_ORDER == _LITTLE_ENDIAN
+# ifndef __LONG_LONG_SUPPORTED
+#  define _LIBCPP_HAS_NO_LONG_LONG
+# endif  // __LONG_LONG_SUPPORTED
+#endif  // __FreeBSD__
+
+#ifdef __NetBSD__
+# include <sys/endian.h>
+#  if _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 1
+#   define _LIBCPP_BIG_ENDIAN    0
+# else  // _BYTE_ORDER == _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 0
+#   define _LIBCPP_BIG_ENDIAN    1
+# endif  // _BYTE_ORDER == _LITTLE_ENDIAN
+# define _LIBCPP_HAS_QUICK_EXIT
+#endif  // __NetBSD__
+
+#ifdef _WIN32
+#  define _LIBCPP_LITTLE_ENDIAN 1
+#  define _LIBCPP_BIG_ENDIAN    0
+// Compiler intrinsics (GCC or MSVC)
+#  if defined(__clang__) \
+   || (defined(_MSC_VER) && _MSC_VER >= 1400) \
+   || (defined(__GNUC__) && _GNUC_VER > 403)
+#    define _LIBCPP_HAS_IS_BASE_OF
+#  endif
+#  if defined(_MSC_VER) && !defined(__clang__)
+#    define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler
+#    define _LIBCPP_TOSTRING2(x) #x
+#    define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
+#    define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x))
+#  endif
+#  // If mingw not explicitly detected, assume using MS C runtime only.
+#  ifndef __MINGW32__
+#    define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library
+#  endif
+#endif  // _WIN32
+
+#ifdef __linux__
+#  if defined(__GNUC__) && _GNUC_VER >= 403
+#    define _LIBCPP_HAS_IS_BASE_OF
+#  endif
+#endif
+
+#ifdef __sun__
+# include <sys/isa_defs.h>
+# ifdef _LITTLE_ENDIAN
+#   define _LIBCPP_LITTLE_ENDIAN 1
+#   define _LIBCPP_BIG_ENDIAN    0
+# else
+#   define _LIBCPP_LITTLE_ENDIAN 0
+#   define _LIBCPP_BIG_ENDIAN    1
+# endif
+#endif // __sun__
+
+#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
+# include <endian.h>
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define _LIBCPP_LITTLE_ENDIAN 1
+#  define _LIBCPP_BIG_ENDIAN    0
+# elif __BYTE_ORDER == __BIG_ENDIAN
+#  define _LIBCPP_LITTLE_ENDIAN 0
+#  define _LIBCPP_BIG_ENDIAN    1
+# else  // __BYTE_ORDER == __BIG_ENDIAN
+#  error unable to determine endian
+# endif
+#endif  // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
+
+#ifdef _WIN32
+
+// only really useful for a DLL
+#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally...
+# ifdef cxx_EXPORTS
+#  define _LIBCPP_HIDDEN
+#  define _LIBCPP_FUNC_VIS __declspec(dllexport)
+#  define _LIBCPP_TYPE_VIS __declspec(dllexport)
+# else
+#  define _LIBCPP_HIDDEN
+#  define _LIBCPP_FUNC_VIS __declspec(dllimport)
+#  define _LIBCPP_TYPE_VIS __declspec(dllimport)
+# endif
+#else
+# define _LIBCPP_HIDDEN
+# define _LIBCPP_FUNC_VIS
+# define _LIBCPP_TYPE_VIS
+#endif
+
+#define _LIBCPP_TYPE_VIS_ONLY
+#define _LIBCPP_FUNC_VIS_ONLY
+
+#ifndef _LIBCPP_INLINE_VISIBILITY
+# ifdef _LIBCPP_MSVC
+#  define _LIBCPP_INLINE_VISIBILITY __forceinline
+# else // MinGW GCC and Clang
+#  define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__))
+# endif
+#endif
+
+#ifndef _LIBCPP_EXCEPTION_ABI
+#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS
+#endif
+
+#ifndef _LIBCPP_ALWAYS_INLINE
+# ifdef _LIBCPP_MSVC
+#  define _LIBCPP_ALWAYS_INLINE __forceinline
+# endif
+#endif
+
+#endif // _WIN32
+
+#ifndef __has_attribute
+#define __has_attribute(__x) 0
+#endif
+
+#ifndef _LIBCPP_HIDDEN
+#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden")))
+#endif
+
+#ifndef _LIBCPP_FUNC_VIS
+#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default")))
+#endif
+
+#ifndef _LIBCPP_TYPE_VIS
+#  if __has_attribute(__type_visibility__)
+#    define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
+#  else
+#    define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
+#  endif
+#endif
+
+#ifndef _LIBCPP_TYPE_VIS_ONLY
+# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS
+#endif
+
+#ifndef _LIBCPP_FUNC_VIS_ONLY
+# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS
+#endif
+
+#ifndef _LIBCPP_INLINE_VISIBILITY
+#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
+#endif
+
+#ifndef _LIBCPP_EXCEPTION_ABI
+#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))
+#endif
+
+#ifndef _LIBCPP_ALWAYS_INLINE
+#define _LIBCPP_ALWAYS_INLINE  __attribute__ ((__visibility__("hidden"), __always_inline__))
+#endif
+
+#if defined(__clang__)
+
+#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) &&        \
+    !defined(__arm__)
+#define _LIBCPP_ALTERNATE_STRING_LAYOUT
+#endif
+
+#if __has_feature(cxx_alignas)
+#  define _ALIGNAS_TYPE(x) alignas(x)
+#  define _ALIGNAS(x) alignas(x)
+#else
+#  define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#  define _ALIGNAS(x) __attribute__((__aligned__(x)))
+#endif
+
+#if !__has_feature(cxx_alias_templates)
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#endif
+
+#if __cplusplus < 201103L
+#ifdef __linux__
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#else
+typedef __char16_t char16_t;
+typedef __char32_t char32_t;
+#endif
+#endif
+
+#if !(__has_feature(cxx_exceptions))
+#define _LIBCPP_NO_EXCEPTIONS
+#endif
+
+#if !(__has_feature(cxx_rtti))
+#define _LIBCPP_NO_RTTI
+#endif
+
+#if !(__has_feature(cxx_strong_enums))
+#define _LIBCPP_HAS_NO_STRONG_ENUMS
+#endif
+
+#if !(__has_feature(cxx_decltype))
+#define _LIBCPP_HAS_NO_DECLTYPE
+#endif
+
+#if __has_feature(cxx_attributes)
+#  define _LIBCPP_NORETURN [[noreturn]]
+#else
+#  define _LIBCPP_NORETURN __attribute__ ((noreturn))
+#endif
+
+#if !(__has_feature(cxx_defaulted_functions))
+#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // !(__has_feature(cxx_defaulted_functions))
+
+#if !(__has_feature(cxx_deleted_functions))
+#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#endif  // !(__has_feature(cxx_deleted_functions))
+
+#if !(__has_feature(cxx_lambdas))
+#define _LIBCPP_HAS_NO_LAMBDAS
+#endif
+
+#if !(__has_feature(cxx_nullptr))
+#define _LIBCPP_HAS_NO_NULLPTR
+#endif
+
+#if !(__has_feature(cxx_rvalue_references))
+#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
+
+#if !(__has_feature(cxx_static_assert))
+#define _LIBCPP_HAS_NO_STATIC_ASSERT
+#endif
+
+#if !(__has_feature(cxx_auto_type))
+#define _LIBCPP_HAS_NO_AUTO_TYPE
+#endif
+
+#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return)
+#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#endif
+
+#if !(__has_feature(cxx_variadic_templates))
+#define _LIBCPP_HAS_NO_VARIADICS
+#endif
+
+#if !(__has_feature(cxx_trailing_return))
+#define _LIBCPP_HAS_NO_TRAILING_RETURN
+#endif
+
+#if !(__has_feature(cxx_generalized_initializers))
+#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#endif
+
+#if __has_feature(is_base_of)
+#  define _LIBCPP_HAS_IS_BASE_OF
+#endif
+
+// Objective-C++ features (opt-in)
+#if __has_feature(objc_arc)
+#define _LIBCPP_HAS_OBJC_ARC
+#endif
+
+#if __has_feature(objc_arc_weak)
+#define _LIBCPP_HAS_OBJC_ARC_WEAK
+#define _LIBCPP_HAS_NO_STRONG_ENUMS
+#endif
+
+#if !(__has_feature(cxx_constexpr))
+#define _LIBCPP_HAS_NO_CONSTEXPR
+#endif
+
+#if !(__has_feature(cxx_relaxed_constexpr))
+#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
+#endif
+
+#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
+#if defined(__FreeBSD__)
+#define _LIBCPP_HAS_QUICK_EXIT
+#define _LIBCPP_HAS_C11_FEATURES
+#elif defined(__ANDROID__)
+#define _LIBCPP_HAS_QUICK_EXIT
+#elif defined(__linux__)
+#include <features.h>
+#if __GLIBC_PREREQ(2, 15)
+#define _LIBCPP_HAS_QUICK_EXIT
+#endif
+#if __GLIBC_PREREQ(2, 17)
+#define _LIBCPP_HAS_C11_FEATURES
+#endif
+#endif
+#endif
+
+#if (__has_feature(cxx_noexcept))
+#  define _NOEXCEPT noexcept
+#  define _NOEXCEPT_(x) noexcept(x)
+#  define _NOEXCEPT_OR_FALSE(x) noexcept(x)
+#else
+#  define _NOEXCEPT throw()
+#  define _NOEXCEPT_(x)
+#  define _NOEXCEPT_OR_FALSE(x) false
+#endif
+
+#if __has_feature(underlying_type)
+#  define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
+#endif
+
+#if __has_feature(is_literal)
+#  define _LIBCPP_IS_LITERAL(T) __is_literal(T)
+#endif
+
+// Inline namespaces are available in Clang regardless of C++ dialect.
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD  } }
+#define _VSTD std::_LIBCPP_NAMESPACE
+
+namespace std {
+  inline namespace _LIBCPP_NAMESPACE {
+  }
+}
+
+#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer)
+#define _LIBCPP_HAS_NO_ASAN
+#endif
+
+#elif defined(__GNUC__)
+
+#define _ALIGNAS(x) __attribute__((__aligned__(x)))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+
+#define _LIBCPP_NORETURN __attribute__((noreturn))
+
+#if _GNUC_VER >= 407
+#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
+#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T)
+#endif
+
+#if !__EXCEPTIONS
+#define _LIBCPP_NO_EXCEPTIONS
+#endif
+
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+// constexpr was added to GCC in 4.6.
+#if _GNUC_VER < 406
+#define _LIBCPP_HAS_NO_CONSTEXPR
+// Can only use constexpr in c++11 mode.
+#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
+#define _LIBCPP_HAS_NO_CONSTEXPR
+#endif
+
+// No version of GCC supports relaxed constexpr rules
+#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
+
+#define _NOEXCEPT throw()
+#define _NOEXCEPT_(x)
+#define _NOEXCEPT_OR_FALSE(x) false
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+
+#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#define _LIBCPP_HAS_NO_DECLTYPE
+#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define _LIBCPP_HAS_NO_NULLPTR
+#define _LIBCPP_HAS_NO_STATIC_ASSERT
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#define _LIBCPP_HAS_NO_VARIADICS
+#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
+#define _LIBCPP_HAS_NO_STRONG_ENUMS
+
+#else  // __GXX_EXPERIMENTAL_CXX0X__
+
+#define _LIBCPP_HAS_NO_TRAILING_RETURN
+#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
+
+#if _GNUC_VER < 403
+#define _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
+
+#if _GNUC_VER < 403
+#define _LIBCPP_HAS_NO_STATIC_ASSERT
+#endif
+
+#if _GNUC_VER < 404
+#define _LIBCPP_HAS_NO_DECLTYPE
+#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#define _LIBCPP_HAS_NO_VARIADICS
+#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#endif  // _GNUC_VER < 404
+
+#if _GNUC_VER < 406
+#define _LIBCPP_HAS_NO_NULLPTR
+#endif
+
+#if _GNUC_VER < 407
+#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif
+
+#endif  // __GXX_EXPERIMENTAL_CXX0X__
+
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD  } }
+#define _VSTD std::_LIBCPP_NAMESPACE
+
+namespace std {
+namespace _LIBCPP_NAMESPACE {
+}
+using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
+}
+
+#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__)
+#define _LIBCPP_HAS_NO_ASAN
+#endif
+
+#elif defined(_LIBCPP_MSVC)
+
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
+#define _LIBCPP_HAS_NO_CONSTEXPR
+#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define __alignof__ __alignof
+#define _LIBCPP_NORETURN __declspec(noreturn)
+#define _ALIGNAS(x) __declspec(align(x))
+#define _LIBCPP_HAS_NO_VARIADICS
+
+#define _NOEXCEPT throw ()
+#define _NOEXCEPT_(x)
+#define _NOEXCEPT_OR_FALSE(x) false
+
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
+#define _LIBCPP_END_NAMESPACE_STD  }
+#define _VSTD std
+
+#  define _LIBCPP_WEAK
+namespace std {
+}
+
+#define _LIBCPP_HAS_NO_ASAN
+
+#elif defined(__IBMCPP__)
+
+#define _ALIGNAS(x) __attribute__((__aligned__(x)))
+#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x))))
+#define _ATTRIBUTE(x) __attribute__((x))
+#define _LIBCPP_NORETURN __attribute__((noreturn))
+
+#define _NOEXCEPT throw()
+#define _NOEXCEPT_(x)
+#define _NOEXCEPT_OR_FALSE(x) false
+
+#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+#define _LIBCPP_HAS_NO_ADVANCED_SFINAE
+#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS
+#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#define _LIBCPP_HAS_NO_NULLPTR
+#define _LIBCPP_HAS_NO_UNICODE_CHARS
+#define _LIBCPP_HAS_IS_BASE_OF
+
+#if defined(_AIX)
+#define __MULTILOCALE_API
+#endif
+
+#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
+#define _LIBCPP_END_NAMESPACE_STD  } }
+#define _VSTD std::_LIBCPP_NAMESPACE
+
+namespace std {
+  inline namespace _LIBCPP_NAMESPACE {
+  }
+}
+
+#define _LIBCPP_HAS_NO_ASAN
+
+#endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__
+
+#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
+typedef unsigned short char16_t;
+typedef unsigned int   char32_t;
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+#ifndef __SIZEOF_INT128__
+#define _LIBCPP_HAS_NO_INT128
+#endif
+
+#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT
+
+template <bool> struct __static_assert_test;
+template <> struct __static_assert_test<true> {};
+template <unsigned> struct __static_assert_check {};
+#define static_assert(__b, __m) \
+    typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \
+    _LIBCPP_CONCAT(__t, __LINE__)
+
+#endif  // _LIBCPP_HAS_NO_STATIC_ASSERT
+
+#ifdef _LIBCPP_HAS_NO_DECLTYPE
+#define decltype(x) __typeof__(x)
+#endif
+
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+#define _LIBCPP_CONSTEXPR
+#else
+#define _LIBCPP_CONSTEXPR constexpr
+#endif
+
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define _LIBCPP_DEFAULT {}
+#else
+#define _LIBCPP_DEFAULT = default;
+#endif
+
+#ifdef __GNUC__
+#define _NOALIAS __attribute__((__malloc__))
+#else
+#define _NOALIAS
+#endif
+
+#ifndef __has_feature
+#define __has_feature(__x) 0
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(__x) 0
+#endif
+
+#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
+#   define _LIBCPP_EXPLICIT explicit
+#else
+#   define _LIBCPP_EXPLICIT
+#endif
+
+#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete)
+#   define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
+#endif
+
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
+#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
+    __lx __v_; \
+    _LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \
+    _LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \
+    _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \
+    };
+#else  // _LIBCPP_HAS_NO_STRONG_ENUMS
+#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x
+#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
+#endif  // _LIBCPP_HAS_NO_STRONG_ENUMS
+
+#ifdef _LIBCPP_DEBUG
+#   if _LIBCPP_DEBUG == 0
+#       define _LIBCPP_DEBUG_LEVEL 1
+#   elif _LIBCPP_DEBUG == 1
+#       define _LIBCPP_DEBUG_LEVEL 2
+#   else
+#       error Supported values for _LIBCPP_DEBUG are 0 and 1
+#   endif
+#   define _LIBCPP_EXTERN_TEMPLATE(...)
+#endif
+
+#ifndef _LIBCPP_EXTERN_TEMPLATE
+#define _LIBCPP_EXTERN_TEMPLATE(...)
+#endif
+
+#ifndef _LIBCPP_EXTERN_TEMPLATE2
+#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
+#endif
+
+#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__)
+#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
+#define _LIBCPP_LOCALE__L_EXTENSIONS 1
+#endif
+
+#ifdef __FreeBSD__
+#define _DECLARE_C99_LDBL_MATH 1
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#define _LIBCPP_HAS_DEFAULTRUNELOCALE
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)
+#define _LIBCPP_WCTYPE_IS_MASK
+#endif
+
+#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+#  define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1
+#endif
+
+#ifndef _LIBCPP_STD_VER
+#  if  __cplusplus <= 201103L
+#    define _LIBCPP_STD_VER 11
+#  elif __cplusplus <= 201402L
+#    define _LIBCPP_STD_VER 14
+#  else
+#    define _LIBCPP_STD_VER 15  // current year, or date of c++17 ratification
+#  endif
+#endif  // _LIBCPP_STD_VER
+
+#if _LIBCPP_STD_VER > 11
+#define _LIBCPP_DEPRECATED [[deprecated]]
+#else
+#define _LIBCPP_DEPRECATED
+#endif
+
+#if _LIBCPP_STD_VER <= 11
+#define _LIBCPP_EXPLICIT_AFTER_CXX11
+#define _LIBCPP_DEPRECATED_AFTER_CXX11
+#else
+#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit
+#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
+#endif
+
+#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR)
+#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr
+#else
+#define _LIBCPP_CONSTEXPR_AFTER_CXX11
+#endif
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" void __sanitizer_annotate_contiguous_container(
+  const void *, const void *, const void *, const void *);
+#endif
+
+// Try to find out if RTTI is disabled.
+// g++ and cl.exe have RTTI on by default and define a macro when it is.
+// g++ only defines the macro in 4.3.2 and onwards.
+#if !defined(_LIBCPP_NO_RTTI)
+#  if defined(__GNUG__) && (__GNUC__ >= 4 && \
+   (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2)) && !defined(__GXX_RTTI)
+#    define _LIBCPP_NO_RTTI
+#  elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI)
+#    define _LIBCPP_NO_RTTI
+#  endif
+#endif
+
+#ifndef _LIBCPP_WEAK
+#  define _LIBCPP_WEAK __attribute__((__weak__))
+#endif
+
+#endif  // _LIBCPP_CONFIG
diff --git a/include/c++/v1/__debug b/include/c++/v1/__debug
new file mode 100644
index 0000000..f1805ad
--- /dev/null
+++ b/include/c++/v1/__debug
@@ -0,0 +1,218 @@
+// -*- C++ -*-
+//===--------------------------- __debug ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_DEBUG_H
+#define _LIBCPP_DEBUG_H
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#if _LIBCPP_DEBUG_LEVEL >= 1
+
+#   include <cstdlib>
+#   include <cstdio>
+#   include <cstddef>
+#   ifndef _LIBCPP_ASSERT
+#      define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::printf("%s\n", m), _VSTD::abort()))
+#   endif
+
+#endif
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_TYPE_VIS __c_node;
+
+struct _LIBCPP_TYPE_VIS __i_node
+{
+    void* __i_;
+    __i_node* __next_;
+    __c_node* __c_;
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    __i_node(const __i_node&) = delete;
+    __i_node& operator=(const __i_node&) = delete;
+#else
+private:
+    __i_node(const __i_node&);
+    __i_node& operator=(const __i_node&);
+public:
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    __i_node(void* __i, __i_node* __next, __c_node* __c)
+        : __i_(__i), __next_(__next), __c_(__c) {}
+    ~__i_node();
+};
+
+struct _LIBCPP_TYPE_VIS __c_node
+{
+    void* __c_;
+    __c_node* __next_;
+    __i_node** beg_;
+    __i_node** end_;
+    __i_node** cap_;
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    __c_node(const __c_node&) = delete;
+    __c_node& operator=(const __c_node&) = delete;
+#else
+private:
+    __c_node(const __c_node&);
+    __c_node& operator=(const __c_node&);
+public:
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    __c_node(void* __c, __c_node* __next)
+        : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
+    virtual ~__c_node();
+
+    virtual bool __dereferenceable(const void*) const = 0;
+    virtual bool __decrementable(const void*) const = 0;
+    virtual bool __addable(const void*, ptrdiff_t) const = 0;
+    virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;
+
+    void __add(__i_node* __i);
+    _LIBCPP_HIDDEN void __remove(__i_node* __i);
+};
+
+template <class _Cont>
+struct _C_node
+    : public __c_node
+{
+    _C_node(void* __c, __c_node* __n)
+        : __c_node(__c, __n) {}
+
+    virtual bool __dereferenceable(const void*) const;
+    virtual bool __decrementable(const void*) const;
+    virtual bool __addable(const void*, ptrdiff_t) const;
+    virtual bool __subscriptable(const void*, ptrdiff_t) const;
+};
+
+template <class _Cont>
+bool
+_C_node<_Cont>::__dereferenceable(const void* __i) const
+{
+    typedef typename _Cont::const_iterator iterator;
+    const iterator* __j = static_cast<const iterator*>(__i);
+    _Cont* _Cp = static_cast<_Cont*>(__c_);
+    return _Cp->__dereferenceable(__j);
+}
+
+template <class _Cont>
+bool
+_C_node<_Cont>::__decrementable(const void* __i) const
+{
+    typedef typename _Cont::const_iterator iterator;
+    const iterator* __j = static_cast<const iterator*>(__i);
+    _Cont* _Cp = static_cast<_Cont*>(__c_);
+    return _Cp->__decrementable(__j);
+}
+
+template <class _Cont>
+bool
+_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
+{
+    typedef typename _Cont::const_iterator iterator;
+    const iterator* __j = static_cast<const iterator*>(__i);
+    _Cont* _Cp = static_cast<_Cont*>(__c_);
+    return _Cp->__addable(__j, __n);
+}
+
+template <class _Cont>
+bool
+_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
+{
+    typedef typename _Cont::const_iterator iterator;
+    const iterator* __j = static_cast<const iterator*>(__i);
+    _Cont* _Cp = static_cast<_Cont*>(__c_);
+    return _Cp->__subscriptable(__j, __n);
+}
+
+class _LIBCPP_TYPE_VIS __libcpp_db
+{
+    __c_node** __cbeg_;
+    __c_node** __cend_;
+    size_t   __csz_;
+    __i_node** __ibeg_;
+    __i_node** __iend_;
+    size_t   __isz_;
+
+    __libcpp_db();
+public:
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    __libcpp_db(const __libcpp_db&) = delete;
+    __libcpp_db& operator=(const __libcpp_db&) = delete;
+#else
+private:
+    __libcpp_db(const __libcpp_db&);
+    __libcpp_db& operator=(const __libcpp_db&);
+public:
+#endif
+    ~__libcpp_db();
+
+    class __db_c_iterator;
+    class __db_c_const_iterator;
+    class __db_i_iterator;
+    class __db_i_const_iterator;
+
+    __db_c_const_iterator __c_end() const;
+    __db_i_const_iterator __i_end() const;
+
+    template <class _Cont>
+    _LIBCPP_INLINE_VISIBILITY
+    void __insert_c(_Cont* __c)
+    {
+        __c_node* __n = __insert_c(static_cast<void*>(__c));
+        ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_);
+    }
+
+    void __insert_i(void* __i);
+    __c_node* __insert_c(void* __c);
+    void __erase_c(void* __c);
+
+    void __insert_ic(void* __i, const void* __c);
+    void __iterator_copy(void* __i, const void* __i0);
+    void __erase_i(void* __i);
+
+    void* __find_c_from_i(void* __i) const;
+    void __invalidate_all(void* __c);
+    __c_node* __find_c_and_lock(void* __c) const;
+    __c_node* __find_c(void* __c) const;
+    void unlock() const;
+
+    void swap(void* __c1, void* __c2);
+
+
+    bool __dereferenceable(const void* __i) const;
+    bool __decrementable(const void* __i) const;
+    bool __addable(const void* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const void* __i, ptrdiff_t __n) const;
+    bool __less_than_comparable(const void* __i, const void* __j) const;
+private:
+    _LIBCPP_HIDDEN
+    __i_node* __insert_iterator(void* __i);
+    _LIBCPP_HIDDEN
+    __i_node* __find_iterator(const void* __i) const;
+
+    friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db();
+};
+
+_LIBCPP_FUNC_VIS __libcpp_db* __get_db();
+_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
+
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif
+
+#endif  // _LIBCPP_DEBUG_H
+
diff --git a/include/c++/v1/__functional_03 b/include/c++/v1/__functional_03
new file mode 100644
index 0000000..d8a9f05
--- /dev/null
+++ b/include/c++/v1/__functional_03
@@ -0,0 +1,2135 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUNCTIONAL_03
+#define _LIBCPP_FUNCTIONAL_03
+
+// manual variadic expansion for <functional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+template <class _Tp>
+class __mem_fn
+    : public __weak_result_type<_Tp>
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type __f_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
+
+    // invoke
+
+    typename __invoke_return<type>::type
+       operator() () const
+       {
+           return __invoke(__f_);
+       }
+
+    template <class _A0>
+       typename __invoke_return0<type, _A0>::type
+          operator() (_A0& __a0) const
+          {
+              return __invoke(__f_, __a0);
+          }
+
+    template <class _A0, class _A1>
+       typename __invoke_return1<type, _A0, _A1>::type
+          operator() (_A0& __a0, _A1& __a1) const
+          {
+              return __invoke(__f_, __a0, __a1);
+          }
+
+    template <class _A0, class _A1, class _A2>
+       typename __invoke_return2<type, _A0, _A1, _A2>::type
+          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
+          {
+              return __invoke(__f_, __a0, __a1, __a2);
+          }
+};
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp _Tp::*>
+mem_fn(_Rp _Tp::* __pm)
+{
+    return __mem_fn<_Rp _Tp::*>(__pm);
+}
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)()>
+mem_fn(_Rp (_Tp::* __pm)())
+{
+    return __mem_fn<_Rp (_Tp::*)()>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0)>
+mem_fn(_Rp (_Tp::* __pm)(_A0))
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1))
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2))
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
+}
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)() const>
+mem_fn(_Rp (_Tp::* __pm)() const)
+{
+    return __mem_fn<_Rp (_Tp::*)() const>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0) const>
+mem_fn(_Rp (_Tp::* __pm)(_A0) const)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0) const>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) const>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>(__pm);
+}
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)() volatile>
+mem_fn(_Rp (_Tp::* __pm)() volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)() volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0) volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0) volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0) volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>(__pm);
+}
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)() const volatile>
+mem_fn(_Rp (_Tp::* __pm)() const volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)() const volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0) const volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0) const volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0) const volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>(__pm);
+}
+
+template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>
+mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const volatile)
+{
+    return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>(__pm);
+}
+
+// bad_function_call
+
+class _LIBCPP_EXCEPTION_ABI bad_function_call
+    : public exception
+{
+};
+
+template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
+
+namespace __function
+{
+
+template<class _Fp>
+struct __maybe_derive_from_unary_function
+{
+};
+
+template<class _Rp, class _A1>
+struct __maybe_derive_from_unary_function<_Rp(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template<class _Fp>
+struct __maybe_derive_from_binary_function
+{
+};
+
+template<class _Rp, class _A1, class _A2>
+struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template<class _Fp> class __base;
+
+template<class _Rp>
+class __base<_Rp()>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()() = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0>
+class __base<_Rp(_A0)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1>
+class __base<_Rp(_A0, _A1)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0, _A1) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1, class _A2>
+class __base<_Rp(_A0, _A1, _A2)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    __base() {}
+    virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_A0, _A1, _A2) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const = 0;
+    virtual const std::type_info& target_type() const = 0;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _FD, class _Alloc, class _FB> class __func;
+
+template<class _Fp, class _Alloc, class _Rp>
+class __func<_Fp, _Alloc, _Rp()>
+    : public  __base<_Rp()>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
+    explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp()>* __clone() const;
+    virtual void __clone(__base<_Rp()>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()();
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp>
+__base<_Rp()>*
+__func<_Fp, _Alloc, _Rp()>::__clone() const
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::__clone(__base<_Rp()>* __p) const
+{
+    ::new (__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+void
+__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+_Rp
+__func<_Fp, _Alloc, _Rp()>::operator()()
+{
+    return __invoke(__f_.first());
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp>
+const void*
+__func<_Fp, _Alloc, _Rp()>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp()>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+class __func<_Fp, _Alloc, _Rp(_A0)>
+    : public  __base<_Rp(_A0)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+__base<_Rp(_A0)>*
+__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::__clone(__base<_Rp(_A0)>* __p) const
+{
+    ::new (__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+void
+__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0)>::operator()(_A0 __a0)
+{
+    return __invoke(__f_.first(), __a0);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+class __func<_Fp, _Alloc, _Rp(_A0, _A1)>
+    : public  __base<_Rp(_A0, _A1)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0, _A1)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0, _A1)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0, _A1);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+__base<_Rp(_A0, _A1)>*
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone(__base<_Rp(_A0, _A1)>* __p) const
+{
+    ::new (__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1)
+{
+    return __invoke(__f_.first(), __a0, __a1);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0, _A1)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>
+    : public  __base<_Rp(_A0, _A1, _A2)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a)
+        : __f_(_VSTD::move(__f), _VSTD::move(__a)) {}
+    virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const;
+    virtual void __clone(__base<_Rp(_A0, _A1, _A2)>*) const;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_A0, _A1, _A2);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const;
+    virtual const std::type_info& target_type() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+__base<_Rp(_A0, _A1, _A2)>*
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone(__base<_Rp(_A0, _A1, _A2)>* __p) const
+{
+    ::new (__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+void
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+_Rp
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2)
+{
+    return __invoke(__f_.first(), __a0, __a1, __a2);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+const void*
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target(const type_info& __ti) const
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class _A0, class _A1, class _A2>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
+{
+    return typeid(_Fp);
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+}  // __function
+
+template<class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp()>
+{
+    typedef __function::__base<_Rp()> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+    template <class _Fp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const _Fp&) {return true;}
+    template <class _R2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (*__p)()) {return __p;}
+    template <class _R2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const function<_R2()>& __p) {return __p;}
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2>
+      bool operator==(const function<_R2()>&) const;// = delete;
+    template<class _R2>
+      bool operator!=(const function<_R2()>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()() const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp>
+function<_Rp()>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp>
+template<class _Alloc>
+function<_Rp()>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp>
+template <class _Fp>
+function<_Rp()>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp()> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp>
+template <class _Fp, class _Alloc>
+function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp()> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<_FF>
+#else
+                rebind_alloc<_FF>::other
+#endif
+                                                         _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp>
+function<_Rp()>&
+function<_Rp()>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp>
+function<_Rp()>&
+function<_Rp()>::operator=(nullptr_t)
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+}
+
+template<class _Rp>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp()>&
+>::type
+function<_Rp()>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp>
+function<_Rp()>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp>
+void
+function<_Rp()>::swap(function& __f)
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp>
+_Rp
+function<_Rp()>::operator()() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__f_ == 0)
+        throw bad_function_call();
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return (*__f_)();
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp>
+const std::type_info&
+function<_Rp()>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp>
+template <typename _Tp>
+_Tp*
+function<_Rp()>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*)__f_->target(typeid(_Tp));
+}
+
+template<class _Rp>
+template <typename _Tp>
+const _Tp*
+function<_Rp()>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0)>
+    : public unary_function<_A0, _Rp>
+{
+    typedef __function::__base<_Rp(_A0)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+    template <class _Fp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const _Fp&) {return true;}
+    template <class _R2, class _B0>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
+    template <class _R2, class _Cp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}
+    template <class _R2, class _Cp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}
+    template <class _R2, class _Cp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}
+    template <class _R2, class _Cp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
+    template <class _R2, class _B0>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0>
+      bool operator==(const function<_R2(_B0)>&) const;// = delete;
+    template<class _R2, class _B0>
+      bool operator!=(const function<_R2(_B0)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0>
+template<class _Alloc>
+function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0>
+template <class _Fp>
+function<_Rp(_A0)>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<_FF>
+#else
+                rebind_alloc<_FF>::other
+#endif
+                                                         _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>&
+function<_Rp(_A0)>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>&
+function<_Rp(_A0)>::operator=(nullptr_t)
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+}
+
+template<class _Rp, class _A0>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0)>&
+>::type
+function<_Rp(_A0)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0>
+function<_Rp(_A0)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0>
+void
+function<_Rp(_A0)>::swap(function& __f)
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0>
+_Rp
+function<_Rp(_A0)>::operator()(_A0 __a0) const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__f_ == 0)
+        throw bad_function_call();
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return (*__f_)(__a0);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0>
+const std::type_info&
+function<_Rp(_A0)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*)__f_->target(typeid(_Tp));
+}
+
+template<class _Rp, class _A0>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1)>
+    : public binary_function<_A0, _A1, _Rp>
+{
+    typedef __function::__base<_Rp(_A0, _A1)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+    template <class _Fp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const _Fp&) {return true;}
+    template <class _R2, class _B0, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
+    template <class _R2, class _Cp, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}
+    template <class _R2, class _Cp, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}
+    template <class _R2, class _Cp, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}
+    template <class _R2, class _Cp, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
+    template <class _R2, class _B0, class _B1>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0, class _B1>
+      bool operator==(const function<_R2(_B0, _B1)>&) const;// = delete;
+    template<class _R2, class _B0, class _B1>
+      bool operator!=(const function<_R2(_B0, _B1)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0, _A1) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1>
+template<class _Alloc>
+function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc&, const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp>
+function<_Rp(_A0, _A1)>::function(_Fp __f,
+                                 typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                 typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<_FF>
+#else
+                rebind_alloc<_FF>::other
+#endif
+                                                         _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>&
+function<_Rp(_A0, _A1)>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>&
+function<_Rp(_A0, _A1)>::operator=(nullptr_t)
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+}
+
+template<class _Rp, class _A0, class _A1>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0, _A1)>&
+>::type
+function<_Rp(_A0, _A1)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1>
+function<_Rp(_A0, _A1)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0, class _A1>
+void
+function<_Rp(_A0, _A1)>::swap(function& __f)
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0, class _A1>
+_Rp
+function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__f_ == 0)
+        throw bad_function_call();
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return (*__f_)(__a0, __a1);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1>
+const std::type_info&
+function<_Rp(_A0, _A1)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0, class _A1>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0, _A1)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*)__f_->target(typeid(_Tp));
+}
+
+template<class _Rp, class _A0, class _A1>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0, _A1)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1, class _A2>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_A0, _A1, _A2)>
+{
+    typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
+    aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+    template <class _Fp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const _Fp&) {return true;}
+    template <class _R2, class _B0, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
+    template <class _R2, class _Cp, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}
+    template <class _R2, class _Cp, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}
+    template <class _R2, class _Cp, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}
+    template <class _R2, class _Cp, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
+    template <class _R2, class _B0, class _B1, class _B2>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;}
+public:
+    typedef _Rp result_type;
+
+    // 20.7.16.2.1, construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY explicit function() : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
+    function(const function&);
+    template<class _Fp>
+      function(_Fp,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<!is_integral<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(nullptr_t);
+    template<class _Fp>
+      typename enable_if
+      <
+        !is_integral<_Fp>::value,
+        function&
+      >::type
+      operator=(_Fp);
+
+    ~function();
+
+    // 20.7.16.2.2, function modifiers:
+    void swap(function&);
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp __f, const _Alloc& __a)
+        {function(allocator_arg, __a, __f).swap(*this);}
+
+    // 20.7.16.2.3, function capacity:
+    _LIBCPP_INLINE_VISIBILITY operator bool() const {return __f_;}
+
+private:
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class _B0, class _B1, class _B2>
+      bool operator==(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
+    template<class _R2, class _B0, class _B1, class _B2>
+      bool operator!=(const function<_R2(_B0, _B1, _B2)>&) const;// = delete;
+public:
+    // 20.7.16.2.4, function invocation:
+    _Rp operator()(_A0, _A1, _A2) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // 20.7.16.2.5, function target access:
+    const std::type_info& target_type() const;
+    template <typename _Tp> _Tp* target();
+    template <typename _Tp> const _Tp* target() const;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template<class _Alloc>
+function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc&,
+                                      const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp>
+function<_Rp(_A0, _A1, _A2)>::function(_Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_A0, _A1, _A2)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp, class _Alloc>
+function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<!is_integral<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_))
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(__f);
+        }
+        else
+        {
+            typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<_FF>
+#else
+                rebind_alloc<_FF>::other
+#endif
+                                                         _Ap;
+            _Ap __a(__a0);
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(__f, _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>&
+function<_Rp(_A0, _A1, _A2)>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>&
+function<_Rp(_A0, _A1, _A2)>::operator=(nullptr_t)
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <class _Fp>
+typename enable_if
+<
+    !is_integral<_Fp>::value,
+    function<_Rp(_A0, _A1, _A2)>&
+>::type
+function<_Rp(_A0, _A1, _A2)>::operator=(_Fp __f)
+{
+    function(_VSTD::move(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+function<_Rp(_A0, _A1, _A2)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+void
+function<_Rp(_A0, _A1, _A2)>::swap(function& __f)
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+_Rp
+function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__f_ == 0)
+        throw bad_function_call();
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return (*__f_)(__a0, __a1, __a2);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class _A0, class _A1, class _A2>
+const std::type_info&
+function<_Rp(_A0, _A1, _A2)>::target_type() const
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <typename _Tp>
+_Tp*
+function<_Rp(_A0, _A1, _A2)>::target()
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*)__f_->target(typeid(_Tp));
+}
+
+template<class _Rp, class _A0, class _A1, class _A2>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_A0, _A1, _A2)>::target() const
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const function<_Fp>& __f, nullptr_t) {return !__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const function<_Fp>& __f) {return !__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const function<_Fp>& __f, nullptr_t) {return (bool)__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const function<_Fp>& __f) {return (bool)__f;}
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(function<_Fp>& __x, function<_Fp>& __y)
+{return __x.swap(__y);}
+
+template<class _Tp> struct __is_bind_expression : public false_type {};
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
+    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
+
+template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
+    : public __is_placeholder<typename remove_cv<_Tp>::type> {};
+
+namespace placeholders
+{
+
+template <int _Np> struct __ph {};
+
+extern __ph<1>   _1;
+extern __ph<2>   _2;
+extern __ph<3>   _3;
+extern __ph<4>   _4;
+extern __ph<5>   _5;
+extern __ph<6>   _6;
+extern __ph<7>   _7;
+extern __ph<8>   _8;
+extern __ph<9>   _9;
+extern __ph<10> _10;
+
+}  // placeholders
+
+template<int _Np>
+struct __is_placeholder<placeholders::__ph<_Np> >
+    : public integral_constant<int, _Np> {};
+
+template <class _Tp, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp&
+__mu(reference_wrapper<_Tp> __t, _Uj&)
+{
+    return __t.get();
+}
+/*
+template <bool _IsBindExpr, class _Ti, class ..._Uj>
+struct __mu_return1 {};
+
+template <class _Ti, class ..._Uj>
+struct __mu_return1<true, _Ti, _Uj...>
+{
+    typedef typename result_of<_Ti(_Uj...)>::type type;
+};
+
+template <class _Ti, class ..._Uj, size_t ..._Indx>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __mu_return1<true, _Ti, _Uj...>::type
+__mu_expand(_Ti& __ti, tuple<_Uj...>&& __uj, __tuple_indices<_Indx...>)
+{
+    __ti(_VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj))...);
+}
+
+template <class _Ti, class ..._Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_bind_expression<_Ti>::value,
+    typename __mu_return1<is_bind_expression<_Ti>::value, _Ti, _Uj...>::type
+>::type
+__mu(_Ti& __ti, tuple<_Uj...>& __uj)
+{
+    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
+    return  __mu_expand(__ti, __uj, __indices());
+}
+
+template <bool IsPh, class _Ti, class _Uj>
+struct __mu_return2 {};
+
+template <class _Ti, class _Uj>
+struct __mu_return2<true, _Ti, _Uj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
+};
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    0 < is_placeholder<_Ti>::value,
+    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
+>::type
+__mu(_Ti&, _Uj& __uj)
+{
+    const size_t _Indx = is_placeholder<_Ti>::value - 1;
+    // compiler bug workaround
+    typename tuple_element<_Indx, _Uj>::type __t = _VSTD::get<_Indx>(__uj);
+    return __t;
+//    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
+}
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_bind_expression<_Ti>::value &&
+    is_placeholder<_Ti>::value == 0 &&
+    !__is_reference_wrapper<_Ti>::value,
+    _Ti&
+>::type
+__mu(_Ti& __ti, _Uj& __uj)
+{
+    return __ti;
+}
+
+template <class _Ti, bool IsBindEx, bool IsPh, class _TupleUj>
+struct ____mu_return;
+
+template <class _Ti, class ..._Uj>
+struct ____mu_return<_Ti, true, false, tuple<_Uj...> >
+{
+    typedef typename result_of<_Ti(_Uj...)>::type type;
+};
+
+template <class _Ti, class _TupleUj>
+struct ____mu_return<_Ti, false, true, _TupleUj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
+                                   _TupleUj>::type&& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct ____mu_return<_Ti, false, false, _TupleUj>
+{
+    typedef _Ti& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return
+    : public ____mu_return<_Ti,
+                           is_bind_expression<_Ti>::value,
+                           0 < is_placeholder<_Ti>::value,
+                           _TupleUj>
+{
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return<reference_wrapper<_Ti>, _TupleUj>
+{
+    typedef _Ti& type;
+};
+
+template <class _Fp, class _BoundArgs, class _TupleUj>
+struct __bind_return;
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
+{
+    typedef typename __ref_return
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
+{
+    typedef typename __ref_return
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            const _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __bind_return<_Fp, _BoundArgs, _Args>::type
+__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
+                _Args&& __args)
+{
+    return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
+}
+
+template<class _Fp, class ..._BoundArgs>
+class __bind
+{
+    _Fp __f_;
+    tuple<_BoundArgs...> __bound_args_;
+
+    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
+public:
+    template <class _Gp, class ..._BA>
+      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
+        : __f_(_VSTD::forward<_Gp>(__f)),
+          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args)
+        {
+            // compiler bug workaround
+            return __apply_functor(__f_, __bound_args_, __indices(),
+                                  tuple<_Args&&...>(__args...));
+        }
+
+    template <class ..._Args>
+        typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args) const
+        {
+            return __apply_functor(__f_, __bound_args_, __indices(),
+                                   tuple<_Args&&...>(__args...));
+        }
+};
+
+template<class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+class __bind_r
+    : public __bind<_Fp, _BoundArgs...>
+{
+    typedef __bind<_Fp, _BoundArgs...> base;
+public:
+    typedef _Rp result_type;
+
+    template <class _Gp, class ..._BA>
+      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
+        : base(_VSTD::forward<_Gp>(__f),
+               _VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        result_type
+        operator()(_Args&& ...__args)
+        {
+            return base::operator()(_VSTD::forward<_Args>(__args)...);
+        }
+
+    template <class ..._Args>
+        result_type
+        operator()(_Args&& ...__args) const
+        {
+            return base::operator()(_VSTD::forward<_Args>(__args)...);
+        }
+};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY
+__bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY
+__bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+*/
+
+#endif  // _LIBCPP_FUNCTIONAL_03
diff --git a/include/c++/v1/__functional_base b/include/c++/v1/__functional_base
new file mode 100644
index 0000000..6766793
--- /dev/null
+++ b/include/c++/v1/__functional_base
@@ -0,0 +1,615 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUNCTIONAL_BASE
+#define _LIBCPP_FUNCTIONAL_BASE
+
+#include <__config>
+#include <type_traits>
+#include <typeinfo>
+#include <exception>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Arg, class _Result>
+struct _LIBCPP_TYPE_VIS_ONLY unary_function
+{
+    typedef _Arg    argument_type;
+    typedef _Result result_type;
+};
+
+template <class _Arg1, class _Arg2, class _Result>
+struct _LIBCPP_TYPE_VIS_ONLY binary_function
+{
+    typedef _Arg1   first_argument_type;
+    typedef _Arg2   second_argument_type;
+    typedef _Result result_type;
+};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
+
+template <class _Tp>
+struct __has_result_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::result_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY less : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x < __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY less<void>
+{
+    template <class _T1, class _T2> 
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+// addressof
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+addressof(_Tp& __x) _NOEXCEPT
+{
+    return (_Tp*)&reinterpret_cast<const volatile char&>(__x);
+}
+
+#if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF)
+// Objective-C++ Automatic Reference Counting uses qualified pointers
+// that require special addressof() signatures. When
+// _LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF is defined, the compiler
+// itself is providing these definitions. Otherwise, we provide them.
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__strong _Tp*
+addressof(__strong _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+#ifdef _LIBCPP_HAS_OBJC_ARC_WEAK
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__weak _Tp*
+addressof(__weak _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__autoreleasing _Tp*
+addressof(__autoreleasing _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__unsafe_unretained _Tp*
+addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT
+{
+  return &__x;
+}
+#endif
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+
+#include <__functional_base_03>
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+// __weak_result_type
+
+template <class _Tp>
+struct __derives_from_unary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _Ap, class _Rp>
+        static unary_function<_Ap, _Rp>
+        __test(const volatile unary_function<_Ap, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp>
+struct __derives_from_binary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _A1, class _A2, class _Rp>
+        static binary_function<_A1, _A2, _Rp>
+        __test(const volatile binary_function<_A1, _A2, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
+struct __maybe_derive_from_unary_function  // bool is true
+    : public __derives_from_unary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_unary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
+struct __maybe_derive_from_binary_function  // bool is true
+    : public __derives_from_binary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_binary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __has_result_type<_Tp>::value>
+struct __weak_result_type_imp // bool is true
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+    typedef typename _Tp::result_type result_type;
+};
+
+template <class _Tp>
+struct __weak_result_type_imp<_Tp, false>
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+};
+
+template <class _Tp>
+struct __weak_result_type
+    : public __weak_result_type_imp<_Tp>
+{
+};
+
+// 0 argument case
+
+template <class _Rp>
+struct __weak_result_type<_Rp ()>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (&)()>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (*)()>
+{
+    typedef _Rp result_type;
+};
+
+// 1 argument case
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (&)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (*)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)()>
+    : public unary_function<_Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const>
+    : public unary_function<const _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() volatile>
+    : public unary_function<volatile _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const volatile>
+    : public unary_function<const volatile _Cp*, _Rp>
+{
+};
+
+// 2 argument case
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (*)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (&)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1)>
+    : public binary_function<_Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
+    : public binary_function<const _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
+    : public binary_function<volatile _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
+    : public binary_function<const volatile _Cp*, _A1, _Rp>
+{
+};
+
+// 3 or more arguments
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
+struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2, class ..._A3>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
+{
+    typedef _Rp result_type;
+};
+
+// __invoke
+
+// bullets 1 and 2
+
+template <class _Fp, class _A0, class ..._Args,
+            class>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
+{
+    return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Fp, class _A0, class ..._Args,
+            class>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
+{
+    return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...);
+}
+
+// bullets 3 and 4
+
+template <class _Fp, class _A0,
+            class>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0)
+    -> decltype(_VSTD::forward<_A0>(__a0).*__f)
+{
+    return _VSTD::forward<_A0>(__a0).*__f;
+}
+
+template <class _Fp, class _A0,
+            class>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0)
+    -> decltype((*_VSTD::forward<_A0>(__a0)).*__f)
+{
+    return (*_VSTD::forward<_A0>(__a0)).*__f;
+}
+
+// bullet 5
+
+template <class _Fp, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _Args&& ...__args)
+    -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
+{
+    return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class ..._Args>
+struct __invoke_return
+{
+    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
+};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
+    : public __weak_result_type<_Tp>
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type* __f_;
+
+public:
+    // construct/copy/destroy
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT
+        : __f_(_VSTD::addressof(__f)) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
+#endif
+
+    // access
+    _LIBCPP_INLINE_VISIBILITY operator type&    () const _NOEXCEPT {return *__f_;}
+    _LIBCPP_INLINE_VISIBILITY          type& get() const _NOEXCEPT {return *__f_;}
+
+    // invoke
+    template <class... _ArgTypes>
+       _LIBCPP_INLINE_VISIBILITY
+       typename __invoke_of<type&, _ArgTypes...>::type
+          operator() (_ArgTypes&&... __args) const
+          {
+              return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
+          }
+};
+
+template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
+template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
+template <class _Tp> struct __is_reference_wrapper
+    : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<_Tp>
+ref(_Tp& __t) _NOEXCEPT
+{
+    return reference_wrapper<_Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<_Tp>
+ref(reference_wrapper<_Tp> __t) _NOEXCEPT
+{
+    return ref(__t.get());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<const _Tp>
+cref(const _Tp& __t) _NOEXCEPT
+{
+    return reference_wrapper<const _Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<const _Tp>
+cref(reference_wrapper<_Tp> __t) _NOEXCEPT
+{
+    return cref(__t.get());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+
+template <class _Tp> void ref(const _Tp&&) = delete;
+template <class _Tp> void cref(const _Tp&&) = delete;
+
+#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+
+template <class _Tp> void ref(const _Tp&&);// = delete;
+template <class _Tp> void cref(const _Tp&&);// = delete;
+
+#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp1, class _Tp2 = void>
+struct __is_transparent
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::is_transparent* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp1>(0)) == 1;
+};
+#endif
+
+// allocator_arg_t
+
+struct _LIBCPP_TYPE_VIS_ONLY allocator_arg_t { };
+
+#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
+extern const allocator_arg_t allocator_arg;
+#else
+constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+#endif
+
+// uses_allocator
+
+template <class _Tp>
+struct __has_allocator_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
+struct __uses_allocator
+    : public integral_constant<bool,
+        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
+{
+};
+
+template <class _Tp, class _Alloc>
+struct __uses_allocator<_Tp, _Alloc, false>
+    : public false_type
+{
+};
+
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator
+    : public __uses_allocator<_Tp, _Alloc>
+{
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// allocator construction
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor_imp
+{
+    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
+    static const bool __ic =
+        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
+    static const int value = __ua ? 2 - __ic : 0;
+};
+
+template <class _Tp, class _Alloc, class ..._Args>
+struct __uses_alloc_ctor
+    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
+    {};
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, const _Allocator &, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args )
+{
+    new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a);
+}
+
+template <class _Tp, class _Allocator, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args)
+{ 
+    __user_alloc_construct_impl( 
+             __uses_alloc_ctor<_Tp, _Allocator>(), 
+             __storage, __a, _VSTD::forward<_Args>(__args)...
+        );
+}
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_FUNCTIONAL_BASE
diff --git a/include/c++/v1/__functional_base_03 b/include/c++/v1/__functional_base_03
new file mode 100644
index 0000000..f297ee0
--- /dev/null
+++ b/include/c++/v1/__functional_base_03
@@ -0,0 +1,1087 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUNCTIONAL_BASE_03
+#define _LIBCPP_FUNCTIONAL_BASE_03
+
+// manual variadic expansion for <functional>
+
+// __weak_result_type
+
+template <class _Tp>
+struct __derives_from_unary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _Ap, class _Rp>
+        static unary_function<_Ap, _Rp>
+        __test(const volatile unary_function<_Ap, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp>
+struct __derives_from_binary_function
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    static __two __test(...);
+    template <class _A1, class _A2, class _Rp>
+        static binary_function<_A1, _A2, _Rp>
+        __test(const volatile binary_function<_A1, _A2, _Rp>*);
+public:
+    static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
+    typedef decltype(__test((_Tp*)0)) type;
+};
+
+template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
+struct __maybe_derive_from_unary_function  // bool is true
+    : public __derives_from_unary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_unary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
+struct __maybe_derive_from_binary_function  // bool is true
+    : public __derives_from_binary_function<_Tp>::type
+{
+};
+
+template <class _Tp>
+struct __maybe_derive_from_binary_function<_Tp, false>
+{
+};
+
+template <class _Tp, bool = __has_result_type<_Tp>::value>
+struct __weak_result_type_imp // bool is true
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+    typedef typename _Tp::result_type result_type;
+};
+
+template <class _Tp>
+struct __weak_result_type_imp<_Tp, false>
+    : public __maybe_derive_from_unary_function<_Tp>,
+      public __maybe_derive_from_binary_function<_Tp>
+{
+};
+
+template <class _Tp>
+struct __weak_result_type
+    : public __weak_result_type_imp<typename remove_reference<_Tp>::type>
+{
+};
+
+// 0 argument case
+
+template <class _Rp>
+struct __weak_result_type<_Rp ()>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (&)()>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp>
+struct __weak_result_type<_Rp (*)()>
+{
+    typedef _Rp result_type;
+};
+
+// 1 argument case
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (&)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _A1>
+struct __weak_result_type<_Rp (*)(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)()>
+    : public unary_function<_Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const>
+    : public unary_function<const _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() volatile>
+    : public unary_function<volatile _Cp*, _Rp>
+{
+};
+
+template <class _Rp, class _Cp>
+struct __weak_result_type<_Rp (_Cp::*)() const volatile>
+    : public unary_function<const volatile _Cp*, _Rp>
+{
+};
+
+// 2 argument case
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (*)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _A1, class _A2>
+struct __weak_result_type<_Rp (&)(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1)>
+    : public binary_function<_Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
+    : public binary_function<const _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
+    : public binary_function<volatile _Cp*, _A1, _Rp>
+{
+};
+
+template <class _Rp, class _Cp, class _A1>
+struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
+    : public binary_function<const volatile _Cp*, _A1, _Rp>
+{
+};
+
+// 3 or more arguments
+
+template <class _Rp, class _A1, class _A2, class _A3>
+struct __weak_result_type<_Rp (_A1, _A2, _A3)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3>
+struct __weak_result_type<_Rp (&)(_A1, _A2, _A3)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _A1, class _A2, class _A3>
+struct __weak_result_type<_Rp (*)(_A1, _A2, _A3)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2)>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) const>
+{
+    typedef _Rp result_type;
+};
+
+template <class _Rp, class _Cp, class _A1, class _A2>
+struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) volatile>
+{
+    typedef _Rp result_type;
+};
+
+// __invoke
+
+// __ref_return0
+//
+// template <class _Tp, bool _HasResultType>
+// struct ________ref_return0  // _HasResultType is true
+// {
+//     typedef typename _Tp::result_type type;
+// };
+//
+// template <class _Tp>
+// struct ________ref_return0<_Tp, false>
+// {
+//     typedef void type;
+// };
+//
+// template <class _Tp, bool _IsClass>
+// struct ____ref_return0  // _IsClass is true
+//     : public ________ref_return0<_Tp, __has_result_type<typename remove_cv<_Tp>::type>::value>
+// {
+// };
+//
+// template <class _Tp, bool _HasResultType>
+// struct ______ref_return0  // _HasResultType is true
+// {
+//     typedef typename __callable_type<_Tp>::result_type type;
+// };
+//
+// template <class _Tp>
+// struct ______ref_return0<_Tp, false>  // pointer to member data
+// {
+//     typedef void type;
+// };
+//
+// template <class _Tp>
+// struct ____ref_return0<_Tp, false>
+//     : public ______ref_return0<typename remove_cv<_Tp>::type,
+//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value>
+// {
+// };
+//
+// template <class _Tp>
+// struct __ref_return0
+//     : public ____ref_return0<typename remove_reference<_Tp>::type,
+//                    is_class<typename remove_reference<_Tp>::type>::value>
+// {
+// };
+//
+// __ref_return1
+//
+// template <class _Tp, bool _IsClass, class _A0>
+// struct ____ref_return1  // _IsClass is true
+// {
+//     typedef typename result_of<_Tp(_A0)>::type type;
+// };
+//
+// template <class _Tp, bool _HasResultType, class _A0>
+// struct ______ref_return1  // _HasResultType is true
+// {
+//     typedef typename __callable_type<_Tp>::result_type type;
+// };
+//
+// template <class _Tp, class _A0, bool>
+// struct __ref_return1_member_data1;
+//
+// template <class _Rp, class _Cp, class _A0>
+// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, true>
+// {
+//     typedef typename __apply_cv<_A0, _Rp>::type& type;
+// };
+//
+// template <class _Rp, class _Cp, class _A0>
+// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, false>
+// {
+//     static _A0 __a;
+//     typedef typename __apply_cv<decltype(*__a), _Rp>::type& type;
+// };
+//
+// template <class _Tp, class _A0>
+// struct __ref_return1_member_data;
+//
+// template <class _Rp, class _Cp, class _A0>
+// struct __ref_return1_member_data<_Rp _Cp::*, _A0>
+//     : public __ref_return1_member_data1<_Rp _Cp::*, _A0,
+//                 is_same<typename remove_cv<_Cp>::type,
+//                         typename remove_cv<typename remove_reference<_A0>::type>::type>::value>
+// {
+// };
+//
+// template <class _Tp, class _A0>
+// struct ______ref_return1<_Tp, false, _A0>  // pointer to member data
+//     : public __ref_return1_member_data<typename remove_cv<_Tp>::type, _A0>
+// {
+// };
+//
+// template <class _Tp, class _A0>
+// struct ____ref_return1<_Tp, false, _A0>
+//     : public ______ref_return1<typename remove_cv<_Tp>::type,
+//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0>
+// {
+// };
+//
+// template <class _Tp, class _A0>
+// struct __ref_return1
+//     : public ____ref_return1<typename remove_reference<_Tp>::type,
+//                    is_class<typename remove_reference<_Tp>::type>::value, _A0>
+// {
+// };
+//
+// __ref_return2
+//
+// template <class _Tp, bool _IsClass, class _A0, class _A1>
+// struct ____ref_return2  // _IsClass is true
+// {
+//     typedef typename result_of<_Tp(_A0, _A1)>::type type;
+// };
+//
+// template <class _Tp, bool _HasResultType, class _A0, class _A1>
+// struct ______ref_return2  // _HasResultType is true
+// {
+//     typedef typename __callable_type<_Tp>::result_type type;
+// };
+//
+// template <class _Tp>
+// struct ______ref_return2<_Tp, false, class _A0, class _A1>  // pointer to member data
+// {
+//     static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
+//                          " to member data with too many arguments.");
+// };
+//
+// template <class _Tp, class _A0, class _A1>
+// struct ____ref_return2<_Tp, false, _A0, _A1>
+//     : public ______ref_return2<typename remove_cv<_Tp>::type,
+//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1>
+// {
+// };
+//
+// template <class _Tp, class _A0, class _A1>
+// struct __ref_return2
+//     : public ____ref_return2<typename remove_reference<_Tp>::type,
+//                    is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1>
+// {
+// };
+//
+// __ref_return3
+//
+// template <class _Tp, bool _IsClass, class _A0, class _A1, class _A2>
+// struct ____ref_return3  // _IsClass is true
+// {
+//     typedef typename result_of<_Tp(_A0, _A1, _A2)>::type type;
+// };
+//
+// template <class _Tp, bool _HasResultType, class _A0, class _A1, class _A2>
+// struct ______ref_return3  // _HasResultType is true
+// {
+//     typedef typename __callable_type<_Tp>::result_type type;
+// };
+//
+// template <class _Tp>
+// struct ______ref_return3<_Tp, false, class _A0, class _A1, class _A2>  // pointer to member data
+// {
+//     static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
+//                          " to member data with too many arguments.");
+// };
+//
+// template <class _Tp, class _A0, class _A1, class _A2>
+// struct ____ref_return3<_Tp, false, _A0, _A1, _A2>
+//     : public ______ref_return3<typename remove_cv<_Tp>::type,
+//                  __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1, _A2>
+// {
+// };
+//
+// template <class _Tp, class _A0, class _A1, class _A2>
+// struct __ref_return3
+//     : public ____ref_return3<typename remove_reference<_Tp>::type,
+//                    is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1, _A2>
+// {
+// };
+
+// first bullet
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(), _T1& __t1)
+{
+    return (__t1.*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0), _T1& __t1, _A0& __a0)
+{
+    return (__t1.*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1& __t1, _A0& __a0, _A1& __a1)
+{
+    return (__t1.*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return (__t1.*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() const, _T1& __t1)
+{
+    return (__t1.*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) const, _T1& __t1, _A0& __a0)
+{
+    return (__t1.*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1& __t1, _A0& __a0, _A1& __a1)
+{
+    return (__t1.*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return (__t1.*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() volatile, _T1& __t1)
+{
+    return (__t1.*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1& __t1, _A0& __a0)
+{
+    return (__t1.*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1& __t1, _A0& __a0, _A1& __a1)
+{
+    return (__t1.*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return (__t1.*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() const volatile, _T1& __t1)
+{
+    return (__t1.*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1& __t1, _A0& __a0)
+{
+    return (__t1.*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1& __t1, _A0& __a0, _A1& __a1)
+{
+    return (__t1.*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return (__t1.*__f)(__a0, __a1, __a2);
+}
+
+// second bullet
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(), _T1 __t1)
+{
+    return ((*__t1).*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0), _T1 __t1, _A0& __a0)
+{
+    return ((*__t1).*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1), _T1 __t1, _A0& __a0, _A1& __a1)
+{
+    return ((*__t1).*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2), _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return ((*__t1).*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() const, _T1 __t1)
+{
+    return ((*__t1).*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) const, _T1 __t1, _A0& __a0)
+{
+    return ((*__t1).*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) const, _T1 __t1, _A0& __a0, _A1& __a1)
+{
+    return ((*__t1).*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return ((*__t1).*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() volatile, _T1 __t1)
+{
+    return ((*__t1).*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) volatile, _T1 __t1, _A0& __a0)
+{
+    return ((*__t1).*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) volatile, _T1 __t1, _A0& __a0, _A1& __a1)
+{
+    return ((*__t1).*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return ((*__t1).*__f)(__a0, __a1, __a2);
+}
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)() const volatile, _T1 __t1)
+{
+    return ((*__t1).*__f)();
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0) const volatile, _T1 __t1, _A0& __a0)
+{
+    return ((*__t1).*__f)(__a0);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1) const volatile, _T1 __t1, _A0& __a0, _A1& __a1)
+{
+    return ((*__t1).*__f)(__a0, __a1);
+}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    _Rp
+>::type
+__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2) const volatile, _T1 __t1, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return ((*__t1).*__f)(__a0, __a1, __a2);
+}
+
+// third bullet
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+    typename __apply_cv<_T1, _Rp>::type&
+>::type
+__invoke(_Rp _Tp::* __f, _T1& __t1)
+{
+    return __t1.*__f;
+}
+
+template <class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__invoke(_Rp _Tp::*)
+{
+}
+
+// template <class _Dp, class _Rp, class _Tp, class _T1>
+// inline _LIBCPP_INLINE_VISIBILITY
+// typename enable_if
+// <
+//     is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+//     typename __ref_return1<_Rp _Tp::*, _T1>::type
+// >::type
+// __invoke(_Rp _Tp::* __f, _T1& __t1)
+// {
+//     return __t1.*__f;
+// }
+
+// forth bullet
+
+template <class _T1, class _Rp, bool>
+struct __4th_helper
+{
+};
+
+template <class _T1, class _Rp>
+struct __4th_helper<_T1, _Rp, true>
+{
+    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Rp>::type type;
+};
+
+template <class _Rp, class _Tp, class _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __4th_helper<_T1, _Rp,
+                      !is_base_of<_Tp,
+                                  typename remove_reference<_T1>::type
+                                 >::value
+                     >::type&
+__invoke(_Rp _Tp::* __f, _T1& __t1)
+{
+    return (*__t1).*__f;
+}
+
+// template <class _Dp, class _Rp, class _Tp, class _T1>
+// inline _LIBCPP_INLINE_VISIBILITY
+// typename enable_if
+// <
+//     !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
+//     typename __ref_return1<_Rp _Tp::*, _T1>::type
+// >::type
+// __invoke(_Rp _Tp::* __f, _T1 __t1)
+// {
+//     return (*__t1).*__f;
+// }
+
+// fifth bullet
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp>()())
+__invoke(_Fp __f)
+{
+    return __f();
+}
+
+template <class _Fp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp>()(declval<_A0&>()))
+__invoke(_Fp __f, _A0& __a0)
+{
+    return __f(__a0);
+}
+
+template <class _Fp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>()))
+__invoke(_Fp __f, _A0& __a0, _A1& __a1)
+{
+    return __f(__a0, __a1);
+}
+
+template <class _Fp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
+__invoke(_Fp __f, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return __f(__a0, __a1, __a2);
+}
+
+// template <class _Rp, class _Fp>
+// inline _LIBCPP_INLINE_VISIBILITY
+// _Rp
+// __invoke(_Fp& __f)
+// {
+//     return __f();
+// }
+//
+// template <class _Rp, class _Fp, class _A0>
+// inline _LIBCPP_INLINE_VISIBILITY
+// typename enable_if
+// <
+//     !is_member_pointer<_Fp>::value,
+//     _Rp
+// >::type
+// __invoke(_Fp& __f, _A0& __a0)
+// {
+//     return __f(__a0);
+// }
+//
+// template <class _Rp, class _Fp, class _A0, class _A1>
+// inline _LIBCPP_INLINE_VISIBILITY
+// _Rp
+// __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
+// {
+//     return __f(__a0, __a1);
+// }
+//
+// template <class _Rp, class _Fp, class _A0, class _A1, class _A2>
+// inline _LIBCPP_INLINE_VISIBILITY
+// _Rp
+// __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
+// {
+//     return __f(__a0, __a1, __a2);
+// }
+
+template <class _Tp>
+struct __has_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
+struct __invoke_return
+{
+    typedef typename __weak_result_type<_Fp>::result_type type;
+};
+
+template <class _Fp>
+struct __invoke_return<_Fp, false>
+{
+    typedef decltype(__invoke(_VSTD::declval<_Fp>())) type;
+};
+
+template <class _Tp, class _A0>
+struct __invoke_return0
+{
+    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>())) type;
+};
+
+template <class _Rp, class _Tp, class _A0>
+struct __invoke_return0<_Rp _Tp::*, _A0>
+{
+    typedef typename __apply_cv<_A0, _Rp>::type& type;
+};
+
+template <class _Rp, class _Tp, class _A0>
+struct __invoke_return0<_Rp _Tp::*, _A0*>
+{
+    typedef typename __apply_cv<_A0, _Rp>::type& type;
+};
+
+template <class _Tp, class _A0, class _A1>
+struct __invoke_return1
+{
+    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
+                                                    _VSTD::declval<_A1>())) type;
+};
+
+template <class _Tp, class _A0, class _A1, class _A2>
+struct __invoke_return2
+{
+    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
+                                                    _VSTD::declval<_A1>(),
+                                                    _VSTD::declval<_A2>())) type;
+};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
+    : public __weak_result_type<_Tp>
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type* __f_;
+
+public:
+    // construct/copy/destroy
+    _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) : __f_(&__f) {}
+
+    // access
+    _LIBCPP_INLINE_VISIBILITY operator type&    () const {return *__f_;}
+    _LIBCPP_INLINE_VISIBILITY          type& get() const {return *__f_;}
+
+    // invoke
+
+    _LIBCPP_INLINE_VISIBILITY
+    typename __invoke_return<type&>::type
+       operator() () const
+       {
+           return __invoke(get());
+       }
+
+    template <class _A0>
+       _LIBCPP_INLINE_VISIBILITY
+       typename __invoke_return0<type&, _A0>::type
+          operator() (_A0& __a0) const
+          {
+              return __invoke(get(), __a0);
+          }
+
+    template <class _A0, class _A1>
+       _LIBCPP_INLINE_VISIBILITY
+       typename __invoke_return1<type&, _A0, _A1>::type
+          operator() (_A0& __a0, _A1& __a1) const
+          {
+              return __invoke(get(), __a0, __a1);
+          }
+
+    template <class _A0, class _A1, class _A2>
+       _LIBCPP_INLINE_VISIBILITY
+       typename __invoke_return2<type&, _A0, _A1, _A2>::type
+          operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
+          {
+              return __invoke(get(), __a0, __a1, __a2);
+          }
+};
+
+template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
+template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
+template <class _Tp> struct __is_reference_wrapper
+    : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<_Tp>
+ref(_Tp& __t)
+{
+    return reference_wrapper<_Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<_Tp>
+ref(reference_wrapper<_Tp> __t)
+{
+    return ref(__t.get());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<const _Tp>
+cref(const _Tp& __t)
+{
+    return reference_wrapper<const _Tp>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+reference_wrapper<const _Tp>
+cref(reference_wrapper<_Tp> __t)
+{
+    return cref(__t.get());
+}
+
+#endif  // _LIBCPP_FUNCTIONAL_BASE_03
diff --git a/include/c++/v1/__hash_table b/include/c++/v1/__hash_table
new file mode 100644
index 0000000..4c4feb0
--- /dev/null
+++ b/include/c++/v1/__hash_table
@@ -0,0 +1,2457 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP__HASH_TABLE
+#define _LIBCPP__HASH_TABLE
+
+#include <__config>
+#include <initializer_list>
+#include <memory>
+#include <iterator>
+#include <algorithm>
+#include <cmath>
+
+#include <__undef_min_max>
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_FUNC_VIS
+size_t __next_prime(size_t __n);
+
+template <class _NodePtr>
+struct __hash_node_base
+{
+    typedef __hash_node_base __first_node;
+
+    _NodePtr    __next_;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
+};
+
+template <class _Tp, class _VoidPtr>
+struct __hash_node
+    : public __hash_node_base
+             <
+                 typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                     rebind<__hash_node<_Tp, _VoidPtr> >
+#else
+                     rebind<__hash_node<_Tp, _VoidPtr> >::other
+#endif
+             >
+{
+    typedef _Tp value_type;
+
+    size_t     __hash_;
+    value_type __value_;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__is_power2(size_t __bc)
+{
+    return __bc > 2 && !(__bc & (__bc - 1));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__constrain_hash(size_t __h, size_t __bc)
+{
+    return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__next_pow2(size_t __n)
+{
+    return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
+template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+    class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+
+template <class _NodePtr>
+class _LIBCPP_TYPE_VIS_ONLY __hash_iterator
+{
+    typedef _NodePtr __node_pointer;
+
+    __node_pointer            __node_;
+
+public:
+    typedef forward_iterator_tag                         iterator_category;
+    typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type;
+    typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
+    typedef value_type&                                  reference;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                     rebind<value_type>
+#else
+                     rebind<value_type>::other
+#endif
+                                                         pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __node_(nullptr)
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator(const __hash_iterator& __i)
+        : __node_(__i.__node_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator& operator=(const __hash_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container iterator");
+#endif
+        __node_ = __node_->__next_;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator operator++(int)
+    {
+        __hash_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __hash_iterator& __x, const __hash_iterator& __y)
+    {
+        return __x.__node_ == __y.__node_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+        : __node_(__node)
+        {
+            __get_db()->__insert_ic(this, __c);
+        }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_iterator(__node_pointer __node) _NOEXCEPT
+        : __node_(__node)
+        {}
+#endif
+
+    template <class, class, class, class> friend class __hash_table;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+};
+
+template <class _ConstNodePtr>
+class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator
+{
+    typedef _ConstNodePtr __node_pointer;
+
+    __node_pointer         __node_;
+
+    typedef typename remove_const<
+        typename pointer_traits<__node_pointer>::element_type
+                                 >::type __node;
+
+public:
+    typedef forward_iterator_tag                       iterator_category;
+    typedef typename __node::value_type                value_type;
+    typedef typename pointer_traits<__node_pointer>::difference_type difference_type;
+    typedef const value_type&                          reference;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                       pointer;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__node>
+#else
+            rebind<__node>::other
+#endif
+                                                      __non_const_node_pointer;
+    typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __node_(nullptr)
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY 
+    __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT
+        : __node_(__x.__node_)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__x);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator(const __hash_const_iterator& __i)
+        : __node_(__i.__node_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_const_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator& operator=(const __hash_const_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container const_iterator");
+#endif
+        __node_ = __node_->__next_;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator operator++(int)
+    {
+        __hash_const_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
+    {
+        return __x.__node_ == __y.__node_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT
+        : __node_(__node)
+        {
+            __get_db()->__insert_ic(this, __c);
+        }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_iterator(__node_pointer __node) _NOEXCEPT
+        : __node_(__node)
+        {}
+#endif
+
+    template <class, class, class, class> friend class __hash_table;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+};
+
+template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+
+template <class _NodePtr>
+class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator
+{
+    typedef _NodePtr __node_pointer;
+
+    __node_pointer         __node_;
+    size_t                 __bucket_;
+    size_t                 __bucket_count_;
+
+    typedef pointer_traits<__node_pointer>          __pointer_traits;
+public:
+    typedef forward_iterator_tag                                iterator_category;
+    typedef typename __pointer_traits::element_type::value_type value_type;
+    typedef typename __pointer_traits::difference_type          difference_type;
+    typedef value_type&                                         reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                                                pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator(const __hash_local_iterator& __i)
+        : __node_(__i.__node_),
+          __bucket_(__i.__bucket_),
+          __bucket_count_(__i.__bucket_count_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_local_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator& operator=(const __hash_local_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+            __bucket_ = __i.__bucket_;
+            __bucket_count_ = __i.__bucket_count_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container local_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container local_iterator");
+#endif
+        __node_ = __node_->__next_;
+        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
+            __node_ = nullptr;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator operator++(int)
+    {
+        __hash_local_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
+    {
+        return __x.__node_ == __y.__node_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator(__node_pointer __node, size_t __bucket,
+                          size_t __bucket_count, const void* __c) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            __get_db()->__insert_ic(this, __c);
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_local_iterator(__node_pointer __node, size_t __bucket,
+                          size_t __bucket_count) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#endif
+    template <class, class, class, class> friend class __hash_table;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
+};
+
+template <class _ConstNodePtr>
+class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator
+{
+    typedef _ConstNodePtr __node_pointer;
+
+    __node_pointer         __node_;
+    size_t                 __bucket_;
+    size_t                 __bucket_count_;
+
+    typedef pointer_traits<__node_pointer>          __pointer_traits;
+    typedef typename __pointer_traits::element_type __node;
+    typedef typename remove_const<__node>::type     __non_const_node;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__non_const_node>
+#else
+            rebind<__non_const_node>::other
+#endif
+                                                    __non_const_node_pointer;
+    typedef __hash_local_iterator<__non_const_node_pointer>
+                                                    __non_const_iterator;
+public:
+    typedef forward_iterator_tag                       iterator_category;
+    typedef typename remove_const<
+                        typename __pointer_traits::element_type::value_type
+                     >::type                           value_type;
+    typedef typename __pointer_traits::difference_type difference_type;
+    typedef const value_type&                          reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                       pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT
+        : __node_(__x.__node_),
+          __bucket_(__x.__bucket_),
+          __bucket_count_(__x.__bucket_count_)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__x);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator(const __hash_const_local_iterator& __i)
+        : __node_(__i.__node_),
+          __bucket_(__i.__bucket_),
+          __bucket_count_(__i.__bucket_count_)
+    {
+        __get_db()->__iterator_copy(this, &__i);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_const_local_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i)
+    {
+        if (this != &__i)
+        {
+            __get_db()->__iterator_copy(this, &__i);
+            __node_ = __i.__node_;
+            __bucket_ = __i.__bucket_;
+            __bucket_count_ = __i.__bucket_count_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+        reference operator*() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+#endif
+            return __node_->__value_;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+        pointer operator->() const
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                           "Attempted to dereference a non-dereferenceable unordered container const_local_iterator");
+#endif
+            return pointer_traits<pointer>::pointer_to(__node_->__value_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable unordered container const_local_iterator");
+#endif
+        __node_ = __node_->__next_;
+        if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_)
+            __node_ = nullptr;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator operator++(int)
+    {
+        __hash_const_local_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
+    {
+        return __x.__node_ == __y.__node_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
+                                size_t __bucket_count, const void* __c) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            __get_db()->__insert_ic(this, __c);
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_const_local_iterator(__node_pointer __node, size_t __bucket,
+                                size_t __bucket_count) _NOEXCEPT
+        : __node_(__node),
+          __bucket_(__bucket),
+          __bucket_count_(__bucket_count)
+        {
+            if (__node_ != nullptr)
+                __node_ = __node_->__next_;
+        }
+#endif
+    template <class, class, class, class> friend class __hash_table;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+};
+
+template <class _Alloc>
+class __bucket_list_deallocator
+{
+    typedef _Alloc                                          allocator_type;
+    typedef allocator_traits<allocator_type>                __alloc_traits;
+    typedef typename __alloc_traits::size_type              size_type;
+
+    __compressed_pair<size_type, allocator_type> __data_;
+public:
+    typedef typename __alloc_traits::pointer pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bucket_list_deallocator()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+        : __data_(0) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bucket_list_deallocator(const allocator_type& __a, size_type __size)
+        _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+        : __data_(__size, __a) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bucket_list_deallocator(__bucket_list_deallocator&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+        : __data_(_VSTD::move(__x.__data_))
+    {
+        __x.size() = 0;
+    }
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type& size() _NOEXCEPT {return __data_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type  size() const _NOEXCEPT {return __data_.first();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type& __alloc() _NOEXCEPT {return __data_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+    {
+        __alloc_traits::deallocate(__alloc(), __p, size());
+    }
+};
+
+template <class _Alloc> class __hash_map_node_destructor;
+
+template <class _Alloc>
+class __hash_node_destructor
+{
+    typedef _Alloc                                          allocator_type;
+    typedef allocator_traits<allocator_type>                __alloc_traits;
+    typedef typename __alloc_traits::value_type::value_type value_type;
+public:
+    typedef typename __alloc_traits::pointer                pointer;
+private:
+
+    allocator_type& __na_;
+
+    __hash_node_destructor& operator=(const __hash_node_destructor&);
+
+public:
+    bool __value_constructed;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __hash_node_destructor(allocator_type& __na,
+                                    bool __constructed = false) _NOEXCEPT
+        : __na_(__na),
+          __value_constructed(__constructed)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+    {
+        if (__value_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));
+        if (__p)
+            __alloc_traits::deallocate(__na_, __p, 1);
+    }
+
+    template <class> friend class __hash_map_node_destructor;
+};
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+class __hash_table
+{
+public:
+    typedef _Tp    value_type;
+    typedef _Hash  hasher;
+    typedef _Equal key_equal;
+    typedef _Alloc allocator_type;
+
+private:
+    typedef allocator_traits<allocator_type> __alloc_traits;
+public:
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+public:
+    // Create __node
+    typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node;
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__node>
+#else
+            rebind_alloc<__node>::other
+#endif
+                                                     __node_allocator;
+    typedef allocator_traits<__node_allocator>       __node_traits;
+    typedef typename __node_traits::pointer          __node_pointer;
+    typedef typename __node_traits::pointer          __node_const_pointer;
+    typedef __hash_node_base<__node_pointer>         __first_node;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__first_node>
+#else
+            rebind<__first_node>::other
+#endif
+                                                     __node_base_pointer;
+
+private:
+
+    typedef typename __node_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__node_pointer>
+#else
+            rebind_alloc<__node_pointer>::other
+#endif
+                                                            __pointer_allocator;
+    typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
+    typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list;
+    typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
+    typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
+
+    // --- Member data begin ---
+    __bucket_list                                     __bucket_list_;
+    __compressed_pair<__first_node, __node_allocator> __p1_;
+    __compressed_pair<size_type, hasher>              __p2_;
+    __compressed_pair<float, key_equal>               __p3_;
+    // --- Member data end ---
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type& size() _NOEXCEPT {return __p2_.first();}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    size_type  size() const _NOEXCEPT {return __p2_.first();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher& hash_function() _NOEXCEPT {return __p2_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const hasher& hash_function() const _NOEXCEPT {return __p2_.second();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    float& max_load_factor() _NOEXCEPT {return __p3_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    float  max_load_factor() const _NOEXCEPT {return __p3_.first();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal& key_eq() _NOEXCEPT {return __p3_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const __node_allocator& __node_alloc() const _NOEXCEPT
+        {return __p1_.second();}
+
+public:
+    typedef __hash_iterator<__node_pointer>                   iterator;
+    typedef __hash_const_iterator<__node_pointer>             const_iterator;
+    typedef __hash_local_iterator<__node_pointer>             local_iterator;
+    typedef __hash_const_local_iterator<__node_pointer>       const_local_iterator;
+
+    __hash_table()
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<__bucket_list>::value &&
+            is_nothrow_default_constructible<__first_node>::value &&
+            is_nothrow_default_constructible<__node_allocator>::value &&
+            is_nothrow_default_constructible<hasher>::value &&
+            is_nothrow_default_constructible<key_equal>::value);
+    __hash_table(const hasher& __hf, const key_equal& __eql);
+    __hash_table(const hasher& __hf, const key_equal& __eql,
+                 const allocator_type& __a);
+    explicit __hash_table(const allocator_type& __a);
+    __hash_table(const __hash_table& __u);
+    __hash_table(const __hash_table& __u, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __hash_table(__hash_table&& __u)
+        _NOEXCEPT_(
+            is_nothrow_move_constructible<__bucket_list>::value &&
+            is_nothrow_move_constructible<__first_node>::value &&
+            is_nothrow_move_constructible<__node_allocator>::value &&
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value);
+    __hash_table(__hash_table&& __u, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~__hash_table();
+
+    __hash_table& operator=(const __hash_table& __u);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __hash_table& operator=(__hash_table&& __u)
+        _NOEXCEPT_(
+            __node_traits::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<__node_allocator>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+#endif
+    template <class _InputIterator>
+        void __assign_unique(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        void __assign_multi(_InputIterator __first, _InputIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT
+    {
+        return allocator_traits<__pointer_allocator>::max_size(
+            __bucket_list_.get_deleter().__alloc());
+    }
+
+    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
+    iterator             __node_insert_multi(__node_pointer __nd);
+    iterator             __node_insert_multi(const_iterator __p,
+                                             __node_pointer __nd);
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        pair<iterator, bool> __emplace_unique(_Args&&... __args);
+    template <class... _Args>
+        iterator __emplace_multi(_Args&&... __args);
+    template <class... _Args>
+        iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+    pair<iterator, bool> __insert_unique(const value_type& __x);
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp>
+        pair<iterator, bool> __insert_unique(_Pp&& __x);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp>
+        iterator __insert_multi(_Pp&& __x);
+    template <class _Pp>
+        iterator __insert_multi(const_iterator __p, _Pp&& __x);
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    iterator __insert_multi(const value_type& __x);
+    iterator __insert_multi(const_iterator __p, const value_type& __x);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    void clear() _NOEXCEPT;
+    void rehash(size_type __n);
+    _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
+        {rehash(static_cast<size_type>(ceil(__n / max_load_factor())));}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const _NOEXCEPT
+    {
+        return __bucket_list_.get_deleter().size();
+    }
+
+    iterator       begin() _NOEXCEPT;
+    iterator       end() _NOEXCEPT;
+    const_iterator begin() const _NOEXCEPT;
+    const_iterator end() const _NOEXCEPT;
+
+    template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
+        size_type bucket(const _Key& __k) const
+        {
+            _LIBCPP_ASSERT(bucket_count() > 0,
+                "unordered container::bucket(key) called when bucket_count() == 0");
+            return __constrain_hash(hash_function()(__k), bucket_count());
+        }
+
+    template <class _Key>
+        iterator       find(const _Key& __x);
+    template <class _Key>
+        const_iterator find(const _Key& __x) const;
+
+    typedef __hash_node_destructor<__node_allocator> _Dp;
+    typedef unique_ptr<__node, _Dp> __node_holder;
+
+    iterator erase(const_iterator __p);
+    iterator erase(const_iterator __first, const_iterator __last);
+    template <class _Key>
+        size_type __erase_unique(const _Key& __k);
+    template <class _Key>
+        size_type __erase_multi(const _Key& __k);
+    __node_holder remove(const_iterator __p) _NOEXCEPT;
+
+    template <class _Key>
+        size_type __count_unique(const _Key& __k) const;
+    template <class _Key>
+        size_type __count_multi(const _Key& __k) const;
+
+    template <class _Key>
+        pair<iterator, iterator>
+        __equal_range_unique(const _Key& __k);
+    template <class _Key>
+        pair<const_iterator, const_iterator>
+        __equal_range_unique(const _Key& __k) const;
+
+    template <class _Key>
+        pair<iterator, iterator>
+        __equal_range_multi(const _Key& __k);
+    template <class _Key>
+        pair<const_iterator, const_iterator>
+        __equal_range_multi(const _Key& __k) const;
+
+    void swap(__hash_table& __u)
+        _NOEXCEPT_(
+            (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<__pointer_allocator>::value) &&
+            (!__node_traits::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<__node_allocator>::value) &&
+            __is_nothrow_swappable<hasher>::value &&
+            __is_nothrow_swappable<key_equal>::value);
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const _NOEXCEPT
+        {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());}
+    size_type bucket_size(size_type __n) const;
+    _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT
+    {
+        size_type __bc = bucket_count();
+        return __bc != 0 ? (float)size() / __bc : 0.f;
+    }
+    _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT
+    {
+        _LIBCPP_ASSERT(__mlf > 0,
+            "unordered container::max_load_factor(lf) called with lf <= 0");
+        max_load_factor() = _VSTD::max(__mlf, load_factor());
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator
+    begin(size_type __n)
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::begin(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+#else
+        return local_iterator(__bucket_list_[__n], __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator
+    end(size_type __n)
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::end(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return local_iterator(nullptr, __n, bucket_count(), this);
+#else
+        return local_iterator(nullptr, __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator
+    cbegin(size_type __n) const
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::cbegin(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this);
+#else
+        return const_local_iterator(__bucket_list_[__n], __n, bucket_count());
+#endif
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator
+    cend(size_type __n) const
+    {
+        _LIBCPP_ASSERT(__n < bucket_count(),
+            "unordered container::cend(n) called with n >= bucket_count()");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_local_iterator(nullptr, __n, bucket_count(), this);
+#else
+        return const_local_iterator(nullptr, __n, bucket_count());
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+    void __rehash(size_type __n);
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class ..._Args>
+        __node_holder __construct_node(_Args&& ...__args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+    __node_holder __construct_node(value_type&& __v, size_t __hash);
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node(const value_type& __v);
+#endif
+    __node_holder __construct_node(const value_type& __v, size_t __hash);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __hash_table& __u)
+        {__copy_assign_alloc(__u, integral_constant<bool,
+             __node_traits::propagate_on_container_copy_assignment::value>());}
+    void __copy_assign_alloc(const __hash_table& __u, true_type);
+    _LIBCPP_INLINE_VISIBILITY
+        void __copy_assign_alloc(const __hash_table&, false_type) {}
+
+    void __move_assign(__hash_table& __u, false_type);
+    void __move_assign(__hash_table& __u, true_type)
+        _NOEXCEPT_(
+            is_nothrow_move_assignable<__node_allocator>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__hash_table& __u)
+        _NOEXCEPT_(
+            !__node_traits::propagate_on_container_move_assignment::value ||
+            (is_nothrow_move_assignable<__pointer_allocator>::value &&
+             is_nothrow_move_assignable<__node_allocator>::value))
+        {__move_assign_alloc(__u, integral_constant<bool,
+             __node_traits::propagate_on_container_move_assignment::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__hash_table& __u, true_type)
+        _NOEXCEPT_(
+            is_nothrow_move_assignable<__pointer_allocator>::value &&
+            is_nothrow_move_assignable<__node_allocator>::value)
+    {
+        __bucket_list_.get_deleter().__alloc() =
+                _VSTD::move(__u.__bucket_list_.get_deleter().__alloc());
+        __node_alloc() = _VSTD::move(__u.__node_alloc());
+    }
+    _LIBCPP_INLINE_VISIBILITY
+        void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
+
+    template <class _Ap>
+    _LIBCPP_INLINE_VISIBILITY
+    static
+    void
+    __swap_alloc(_Ap& __x, _Ap& __y)
+        _NOEXCEPT_(
+            !allocator_traits<_Ap>::propagate_on_container_swap::value ||
+            __is_nothrow_swappable<_Ap>::value)
+    {
+        __swap_alloc(__x, __y,
+                     integral_constant<bool,
+                        allocator_traits<_Ap>::propagate_on_container_swap::value
+                                      >());
+    }
+
+    template <class _Ap>
+    _LIBCPP_INLINE_VISIBILITY
+    static
+    void
+    __swap_alloc(_Ap& __x, _Ap& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
+    {
+        using _VSTD::swap;
+        swap(__x, __y);
+    }
+
+    template <class _Ap>
+    _LIBCPP_INLINE_VISIBILITY
+    static
+    void
+    __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
+
+    void __deallocate(__node_pointer __np) _NOEXCEPT;
+    __node_pointer __detach() _NOEXCEPT;
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+};
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table()
+    _NOEXCEPT_(
+        is_nothrow_default_constructible<__bucket_list>::value &&
+        is_nothrow_default_constructible<__first_node>::value &&
+        is_nothrow_default_constructible<hasher>::value &&
+        is_nothrow_default_constructible<key_equal>::value)
+    : __p2_(0),
+      __p3_(1.0f)
+{
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
+                                                       const key_equal& __eql)
+    : __bucket_list_(nullptr, __bucket_list_deleter()),
+      __p1_(),
+      __p2_(0, __hf),
+      __p3_(1.0f, __eql)
+{
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf,
+                                                       const key_equal& __eql,
+                                                       const allocator_type& __a)
+    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
+      __p1_(__node_allocator(__a)),
+      __p2_(0, __hf),
+      __p3_(1.0f, __eql)
+{
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
+    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
+      __p1_(__node_allocator(__a)),
+      __p2_(0),
+      __p3_(1.0f)
+{
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u)
+    : __bucket_list_(nullptr,
+          __bucket_list_deleter(allocator_traits<__pointer_allocator>::
+              select_on_container_copy_construction(
+                  __u.__bucket_list_.get_deleter().__alloc()), 0)),
+      __p1_(allocator_traits<__node_allocator>::
+          select_on_container_copy_construction(__u.__node_alloc())),
+      __p2_(0, __u.hash_function()),
+      __p3_(__u.__p3_)
+{
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
+                                                       const allocator_type& __a)
+    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
+      __p1_(__node_allocator(__a)),
+      __p2_(0, __u.hash_function()),
+      __p3_(__u.__p3_)
+{
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u)
+        _NOEXCEPT_(
+            is_nothrow_move_constructible<__bucket_list>::value &&
+            is_nothrow_move_constructible<__first_node>::value &&
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value)
+    : __bucket_list_(_VSTD::move(__u.__bucket_list_)),
+      __p1_(_VSTD::move(__u.__p1_)),
+      __p2_(_VSTD::move(__u.__p2_)),
+      __p3_(_VSTD::move(__u.__p3_))
+{
+    if (size() > 0)
+    {
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __u.__p1_.first().__next_ = nullptr;
+        __u.size() = 0;
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
+                                                       const allocator_type& __a)
+    : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
+      __p1_(__node_allocator(__a)),
+      __p2_(0, _VSTD::move(__u.hash_function())),
+      __p3_(_VSTD::move(__u.__p3_))
+{
+    if (__a == allocator_type(__u.__node_alloc()))
+    {
+        __bucket_list_.reset(__u.__bucket_list_.release());
+        __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
+        __u.__bucket_list_.get_deleter().size() = 0;
+        if (__u.size() > 0)
+        {
+            __p1_.first().__next_ = __u.__p1_.first().__next_;
+            __u.__p1_.first().__next_ = nullptr;
+            __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
+                static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+            size() = __u.size();
+            __u.size() = 0;
+        }
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
+{
+    __deallocate(__p1_.first().__next_);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(
+        const __hash_table& __u, true_type)
+{
+    if (__node_alloc() != __u.__node_alloc())
+    {
+        clear();
+        __bucket_list_.reset();
+        __bucket_list_.get_deleter().size() = 0;
+    }
+    __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc();
+    __node_alloc() = __u.__node_alloc();
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>&
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u)
+{
+    if (this != &__u)
+    {
+        __copy_assign_alloc(__u);
+        hash_function() = __u.hash_function();
+        key_eq() = __u.key_eq();
+        max_load_factor() = __u.max_load_factor();
+        __assign_multi(__u.begin(), __u.end());
+    }
+    return *this;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np)
+    _NOEXCEPT
+{
+    __node_allocator& __na = __node_alloc();
+    while (__np != nullptr)
+    {
+        __node_pointer __next = __np->__next_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __c_node* __c = __get_db()->__find_c_and_lock(this);
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            iterator* __i = static_cast<iterator*>((*__p)->__i_);
+            if (__i->__node_ == __np)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+#endif
+        __node_traits::destroy(__na, _VSTD::addressof(__np->__value_));
+        __node_traits::deallocate(__na, __np, 1);
+        __np = __next;
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT
+{
+    size_type __bc = bucket_count();
+    for (size_type __i = 0; __i < __bc; ++__i)
+        __bucket_list_[__i] = nullptr;
+    size() = 0;
+    __node_pointer __cache = __p1_.first().__next_;
+    __p1_.first().__next_ = nullptr;
+    return __cache;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
+        __hash_table& __u, true_type)
+    _NOEXCEPT_(
+        is_nothrow_move_assignable<__node_allocator>::value &&
+        is_nothrow_move_assignable<hasher>::value &&
+        is_nothrow_move_assignable<key_equal>::value)
+{
+    clear();
+    __bucket_list_.reset(__u.__bucket_list_.release());
+    __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
+    __u.__bucket_list_.get_deleter().size() = 0;
+    __move_assign_alloc(__u);
+    size() = __u.size();
+    hash_function() = _VSTD::move(__u.hash_function());
+    max_load_factor() = __u.max_load_factor();
+    key_eq() = _VSTD::move(__u.key_eq());
+    __p1_.first().__next_ = __u.__p1_.first().__next_;
+    if (size() > 0)
+    {
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __u.__p1_.first().__next_ = nullptr;
+        __u.size() = 0;
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(
+        __hash_table& __u, false_type)
+{
+    if (__node_alloc() == __u.__node_alloc())
+        __move_assign(__u, true_type());
+    else
+    {
+        hash_function() = _VSTD::move(__u.hash_function());
+        key_eq() = _VSTD::move(__u.key_eq());
+        max_load_factor() = __u.max_load_factor();
+        if (bucket_count() != 0)
+        {
+            __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            try
+            {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                const_iterator __i = __u.begin();
+                while (__cache != nullptr && __u.size() != 0)
+                {
+                    __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_);
+                    __node_pointer __next = __cache->__next_;
+                    __node_insert_multi(__cache);
+                    __cache = __next;
+                }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            }
+            catch (...)
+            {
+                __deallocate(__cache);
+                throw;
+            }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __deallocate(__cache);
+        }
+        const_iterator __i = __u.begin();
+        while (__u.size() != 0)
+        {
+            __node_holder __h =
+                    __construct_node(_VSTD::move(__u.remove(__i++)->__value_));
+            __node_insert_multi(__h.get());
+            __h.release();
+        }
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__hash_table<_Tp, _Hash, _Equal, _Alloc>&
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
+    _NOEXCEPT_(
+        __node_traits::propagate_on_container_move_assignment::value &&
+        is_nothrow_move_assignable<__node_allocator>::value &&
+        is_nothrow_move_assignable<hasher>::value &&
+        is_nothrow_move_assignable<key_equal>::value)
+{
+    __move_assign(__u, integral_constant<bool,
+                  __node_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _InputIterator>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first,
+                                                          _InputIterator __last)
+{
+    if (bucket_count() != 0)
+    {
+        __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __cache != nullptr && __first != __last; ++__first)
+            {
+                __cache->__value_ = *__first;
+                __node_pointer __next = __cache->__next_;
+                __node_insert_unique(__cache);
+                __cache = __next;
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __deallocate(__cache);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __deallocate(__cache);
+    }
+    for (; __first != __last; ++__first)
+        __insert_unique(*__first);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _InputIterator>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first,
+                                                         _InputIterator __last)
+{
+    if (bucket_count() != 0)
+    {
+        __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __cache != nullptr && __first != __last; ++__first)
+            {
+                __cache->__value_ = *__first;
+                __node_pointer __next = __cache->__next_;
+                __node_insert_multi(__cache);
+                __cache = __next;
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __deallocate(__cache);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __deallocate(__cache);
+    }
+    for (; __first != __last; ++__first)
+        __insert_multi(*__first);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__p1_.first().__next_, this);
+#else
+    return iterator(__p1_.first().__next_);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(nullptr, this);
+#else
+    return iterator(nullptr);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return const_iterator(__p1_.first().__next_, this);
+#else
+    return const_iterator(__p1_.first().__next_);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return const_iterator(nullptr, this);
+#else
+    return const_iterator(nullptr);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT
+{
+    if (size() > 0)
+    {
+        __deallocate(__p1_.first().__next_);
+        __p1_.first().__next_ = nullptr;
+        size_type __bc = bucket_count();
+        for (size_type __i = 0; __i < __bc; ++__i)
+            __bucket_list_[__i] = nullptr;
+        size() = 0;
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd)
+{
+    __nd->__hash_ = hash_function()(__nd->__value_);
+    size_type __bc = bucket_count();
+    bool __inserted = false;
+    __node_pointer __ndptr;
+    size_t __chash;
+    if (__bc != 0)
+    {
+        __chash = __constrain_hash(__nd->__hash_, __bc);
+        __ndptr = __bucket_list_[__chash];
+        if (__ndptr != nullptr)
+        {
+            for (__ndptr = __ndptr->__next_; __ndptr != nullptr &&
+                                             __constrain_hash(__ndptr->__hash_, __bc) == __chash;
+                                                     __ndptr = __ndptr->__next_)
+            {
+                if (key_eq()(__ndptr->__value_, __nd->__value_))
+                    goto __done;
+            }
+        }
+    }
+    {
+        if (size()+1 > __bc * max_load_factor() || __bc == 0)
+        {
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+                           size_type(ceil(float(size() + 1) / max_load_factor()))));
+            __bc = bucket_count();
+            __chash = __constrain_hash(__nd->__hash_, __bc);
+        }
+        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
+        __node_pointer __pn = __bucket_list_[__chash];
+        if (__pn == nullptr)
+        {
+            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+            __nd->__next_ = __pn->__next_;
+            __pn->__next_ = __nd;
+            // fix up __bucket_list_
+            __bucket_list_[__chash] = __pn;
+            if (__nd->__next_ != nullptr)
+                __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd;
+        }
+        else
+        {
+            __nd->__next_ = __pn->__next_;
+            __pn->__next_ = __nd;
+        }
+        __ndptr = __nd;
+        // increment size
+        ++size();
+        __inserted = true;
+    }
+__done:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return pair<iterator, bool>(iterator(__ndptr, this), __inserted);
+#else
+    return pair<iterator, bool>(iterator(__ndptr), __inserted);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp)
+{
+    __cp->__hash_ = hash_function()(__cp->__value_);
+    size_type __bc = bucket_count();
+    if (size()+1 > __bc * max_load_factor() || __bc == 0)
+    {
+        rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+                       size_type(ceil(float(size() + 1) / max_load_factor()))));
+        __bc = bucket_count();
+    }
+    size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+    __node_pointer __pn = __bucket_list_[__chash];
+    if (__pn == nullptr)
+    {
+        __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+        __cp->__next_ = __pn->__next_;
+        __pn->__next_ = __cp;
+        // fix up __bucket_list_
+        __bucket_list_[__chash] = __pn;
+        if (__cp->__next_ != nullptr)
+            __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp;
+    }
+    else
+    {
+        for (bool __found = false; __pn->__next_ != nullptr &&
+                                   __constrain_hash(__pn->__next_->__hash_, __bc) == __chash;
+                                                           __pn = __pn->__next_)
+        {
+            //      __found    key_eq()     action
+            //      false       false       loop
+            //      true        true        loop
+            //      false       true        set __found to true
+            //      true        false       break
+            if (__found != (__pn->__next_->__hash_ == __cp->__hash_ &&
+                            key_eq()(__pn->__next_->__value_, __cp->__value_)))
+            {
+                if (!__found)
+                    __found = true;
+                else
+                    break;
+            }
+        }
+        __cp->__next_ = __pn->__next_;
+        __pn->__next_ = __cp;
+        if (__cp->__next_ != nullptr)
+        {
+            size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc);
+            if (__nhash != __chash)
+                __bucket_list_[__nhash] = __cp;
+        }
+    }
+    ++size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__cp, this);
+#else
+    return iterator(__cp);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(
+        const_iterator __p, __node_pointer __cp)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
+        " referring to this unordered container");
+#endif
+    if (__p != end() && key_eq()(*__p, __cp->__value_))
+    {
+        __node_pointer __np = __p.__node_;
+        __cp->__hash_ = __np->__hash_;
+        size_type __bc = bucket_count();
+        if (size()+1 > __bc * max_load_factor() || __bc == 0)
+        {
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+                           size_type(ceil(float(size() + 1) / max_load_factor()))));
+            __bc = bucket_count();
+        }
+        size_t __chash = __constrain_hash(__cp->__hash_, __bc);
+        __node_pointer __pp = __bucket_list_[__chash];
+        while (__pp->__next_ != __np)
+            __pp = __pp->__next_;
+        __cp->__next_ = __np;
+        __pp->__next_ = __cp;
+        ++size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return iterator(__cp, this);
+#else
+        return iterator(__cp);
+#endif
+    }
+    return __node_insert_multi(__cp);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
+{
+    size_t __hash = hash_function()(__x);
+    size_type __bc = bucket_count();
+    bool __inserted = false;
+    __node_pointer __nd;
+    size_t __chash;
+    if (__bc != 0)
+    {
+        __chash = __constrain_hash(__hash, __bc);
+        __nd = __bucket_list_[__chash];
+        if (__nd != nullptr)
+        {
+            for (__nd = __nd->__next_; __nd != nullptr &&
+                                       __constrain_hash(__nd->__hash_, __bc) == __chash;
+                                                           __nd = __nd->__next_)
+            {
+                if (key_eq()(__nd->__value_, __x))
+                    goto __done;
+            }
+        }
+    }
+    {
+        __node_holder __h = __construct_node(__x, __hash);
+        if (size()+1 > __bc * max_load_factor() || __bc == 0)
+        {
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+                           size_type(ceil(float(size() + 1) / max_load_factor()))));
+            __bc = bucket_count();
+            __chash = __constrain_hash(__hash, __bc);
+        }
+        // insert_after __bucket_list_[__chash], or __first_node if bucket is null
+        __node_pointer __pn = __bucket_list_[__chash];
+        if (__pn == nullptr)
+        {
+            __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+            __h->__next_ = __pn->__next_;
+            __pn->__next_ = __h.get();
+            // fix up __bucket_list_
+            __bucket_list_[__chash] = __pn;
+            if (__h->__next_ != nullptr)
+                __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get();
+        }
+        else
+        {
+            __h->__next_ = __pn->__next_;
+            __pn->__next_ = __h.get();
+        }
+        __nd = __h.release();
+        // increment size
+        ++size();
+        __inserted = true;
+    }
+__done:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return pair<iterator, bool>(iterator(__nd, this), __inserted);
+#else
+    return pair<iterator, bool>(iterator(__nd), __inserted);
+#endif
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class... _Args>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    pair<iterator, bool> __r = __node_insert_unique(__h.get());
+    if (__r.second)
+        __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class... _Args>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __node_insert_multi(__h.get());
+    __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class... _Args>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(
+        const_iterator __p, _Args&&... __args)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::emplace_hint(const_iterator, args...) called with an iterator not"
+        " referring to this unordered container");
+#endif
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __node_insert_multi(__p, __h.get());
+    __h.release();
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Pp>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
+    pair<iterator, bool> __r = __node_insert_unique(__h.get());
+    if (__r.second)
+        __h.release();
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Pp>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
+    iterator __r = __node_insert_multi(__h.get());
+    __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Pp>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
+                                                         _Pp&& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::insert(const_iterator, rvalue) called with an iterator not"
+        " referring to this unordered container");
+#endif
+    __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x));
+    iterator __r = __node_insert_multi(__p, __h.get());
+    __h.release();
+    return __r;
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x)
+{
+    __node_holder __h = __construct_node(__x);
+    iterator __r = __node_insert_multi(__h.get());
+    __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
+                                                         const value_type& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container::insert(const_iterator, lvalue) called with an iterator not"
+        " referring to this unordered container");
+#endif
+    __node_holder __h = __construct_node(__x);
+    iterator __r = __node_insert_multi(__p, __h.get());
+    __h.release();
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)
+{
+    if (__n == 1)
+        __n = 2;
+    else if (__n & (__n - 1))
+        __n = __next_prime(__n);
+    size_type __bc = bucket_count();
+    if (__n > __bc)
+        __rehash(__n);
+    else if (__n < __bc)
+    {
+        __n = _VSTD::max<size_type>
+              (
+                  __n,
+                  __is_power2(__bc) ? __next_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
+                                      __next_prime(size_t(ceil(float(size()) / max_load_factor())))
+              );
+        if (__n < __bc)
+            __rehash(__n);
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+    __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
+    __bucket_list_.reset(__nbc > 0 ?
+                      __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
+    __bucket_list_.get_deleter().size() = __nbc;
+    if (__nbc > 0)
+    {
+        for (size_type __i = 0; __i < __nbc; ++__i)
+            __bucket_list_[__i] = nullptr;
+        __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())));
+        __node_pointer __cp = __pp->__next_;
+        if (__cp != nullptr)
+        {
+            size_type __chash = __constrain_hash(__cp->__hash_, __nbc);
+            __bucket_list_[__chash] = __pp;
+            size_type __phash = __chash;
+            for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
+                                                           __cp = __pp->__next_)
+            {
+                __chash = __constrain_hash(__cp->__hash_, __nbc);
+                if (__chash == __phash)
+                    __pp = __cp;
+                else
+                {
+                    if (__bucket_list_[__chash] == nullptr)
+                    {
+                        __bucket_list_[__chash] = __pp;
+                        __pp = __cp;
+                        __phash = __chash;
+                    }
+                    else
+                    {
+                        __node_pointer __np = __cp;
+                        for (; __np->__next_ != nullptr &&
+                               key_eq()(__cp->__value_, __np->__next_->__value_);
+                                                           __np = __np->__next_)
+                            ;
+                        __pp->__next_ = __np->__next_;
+                        __np->__next_ = __bucket_list_[__chash]->__next_;
+                        __bucket_list_[__chash]->__next_ = __cp;
+
+                    }
+                }
+            }
+        }
+    }
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k)
+{
+    size_t __hash = hash_function()(__k);
+    size_type __bc = bucket_count();
+    if (__bc != 0)
+    {
+        size_t __chash = __constrain_hash(__hash, __bc);
+        __node_pointer __nd = __bucket_list_[__chash];
+        if (__nd != nullptr)
+        {
+            for (__nd = __nd->__next_; __nd != nullptr &&
+                                       __constrain_hash(__nd->__hash_, __bc) == __chash;
+                                                           __nd = __nd->__next_)
+            {
+                if (key_eq()(__nd->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                    return iterator(__nd, this);
+#else
+                    return iterator(__nd);
+#endif
+            }
+        }
+    }
+    return end();
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const
+{
+    size_t __hash = hash_function()(__k);
+    size_type __bc = bucket_count();
+    if (__bc != 0)
+    {
+        size_t __chash = __constrain_hash(__hash, __bc);
+        __node_const_pointer __nd = __bucket_list_[__chash];
+        if (__nd != nullptr)
+        {
+            for (__nd = __nd->__next_; __nd != nullptr &&
+                                           __constrain_hash(__nd->__hash_, __bc) == __chash;
+                                                           __nd = __nd->__next_)
+            {
+                if (key_eq()(__nd->__value_, __k))
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                    return const_iterator(__nd, this);
+#else
+                    return const_iterator(__nd);
+#endif
+            }
+        }
+
+    }
+    return end();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class ..._Args>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__value_constructed = true;
+    __h->__hash_ = hash_function()(__h->__value_);
+    __h->__next_ = nullptr;
+    return __h;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v,
+                                                           size_t __hash)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
+    __h.get_deleter().__value_constructed = true;
+    __h->__hash_ = __hash;
+    __h->__next_ = nullptr;
+    return __h;
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
+    __h.get_deleter().__value_constructed = true;
+    __h->__hash_ = hash_function()(__h->__value_);
+    __h->__next_ = nullptr;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v,
+                                                           size_t __hash)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
+    __h.get_deleter().__value_constructed = true;
+    __h->__hash_ = __hash;
+    __h->__next_ = nullptr;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
+{
+    __node_pointer __np = __p.__node_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "unordered container erase(iterator) called with an iterator not"
+        " referring to this container");
+    _LIBCPP_ASSERT(__p != end(),
+        "unordered container erase(iterator) called with a non-dereferenceable iterator");
+    iterator __r(__np, this);
+#else
+    iterator __r(__np);
+#endif
+    ++__r;
+    remove(__p);
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first,
+                                                const_iterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "unodered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this unodered container");
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this,
+        "unodered container::erase(iterator, iterator) called with an iterator not"
+        " referring to this unodered container");
+#endif
+    for (const_iterator __p = __first; __first != __last; __p = __first)
+    {
+        ++__first;
+        erase(__p);
+    }
+    __node_pointer __np = __last.__node_;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator (__np, this);
+#else
+    return iterator (__np);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k)
+{
+    iterator __i = find(__k);
+    if (__i == end())
+        return 0;
+    erase(__i);
+    return 1;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k)
+{
+    size_type __r = 0;
+    iterator __i = find(__k);
+    if (__i != end())
+    {
+        iterator __e = end();
+        do
+        {
+            erase(__i++);
+            ++__r;
+        } while (__i != __e && key_eq()(*__i, __k));
+    }
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT
+{
+    // current node
+    __node_pointer __cn = __p.__node_;
+    size_type __bc = bucket_count();
+    size_t __chash = __constrain_hash(__cn->__hash_, __bc);
+    // find previous node
+    __node_pointer __pn = __bucket_list_[__chash];
+    for (; __pn->__next_ != __cn; __pn = __pn->__next_)
+        ;
+    // Fix up __bucket_list_
+        // if __pn is not in same bucket (before begin is not in same bucket) &&
+        //    if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
+    if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))
+                            || __constrain_hash(__pn->__hash_, __bc) != __chash)
+    {
+        if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash)
+            __bucket_list_[__chash] = nullptr;
+    }
+        // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
+    if (__cn->__next_ != nullptr)
+    {
+        size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc);
+        if (__nhash != __chash)
+            __bucket_list_[__nhash] = __pn;
+    }
+    // remove __cn
+    __pn->__next_ = __cn->__next_;
+    __cn->__next_ = nullptr;
+    --size();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    {
+        --__p;
+        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        if (__i->__node_ == __cn)
+        {
+            (*__p)->__c_ = nullptr;
+            if (--__c->end_ != __p)
+                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+        }
+    }
+    __get_db()->unlock();
+#endif
+    return __node_holder(__cn, _Dp(__node_alloc(), true));
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const
+{
+    return static_cast<size_type>(find(__k) != end());
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const
+{
+    size_type __r = 0;
+    const_iterator __i = find(__k);
+    if (__i != end())
+    {
+        const_iterator __e = end();
+        do
+        {
+            ++__i;
+            ++__r;
+        } while (__i != __e && key_eq()(*__i, __k));
+    }
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
+     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
+        const _Key& __k)
+{
+    iterator __i = find(__k);
+    iterator __j = __i;
+    if (__i != end())
+        ++__j;
+    return pair<iterator, iterator>(__i, __j);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
+     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(
+        const _Key& __k) const
+{
+    const_iterator __i = find(__k);
+    const_iterator __j = __i;
+    if (__i != end())
+        ++__j;
+    return pair<const_iterator, const_iterator>(__i, __j);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator,
+     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
+        const _Key& __k)
+{
+    iterator __i = find(__k);
+    iterator __j = __i;
+    if (__i != end())
+    {
+        iterator __e = end();
+        do
+        {
+            ++__j;
+        } while (__j != __e && key_eq()(*__j, __k));
+    }
+    return pair<iterator, iterator>(__i, __j);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _Key>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator,
+     typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(
+        const _Key& __k) const
+{
+    const_iterator __i = find(__k);
+    const_iterator __j = __i;
+    if (__i != end())
+    {
+        const_iterator __e = end();
+        do
+        {
+            ++__j;
+        } while (__j != __e && key_eq()(*__j, __k));
+    }
+    return pair<const_iterator, const_iterator>(__i, __j);
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+void
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
+    _NOEXCEPT_(
+        (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
+         __is_nothrow_swappable<__pointer_allocator>::value) &&
+        (!__node_traits::propagate_on_container_swap::value ||
+         __is_nothrow_swappable<__node_allocator>::value) &&
+        __is_nothrow_swappable<hasher>::value &&
+        __is_nothrow_swappable<key_equal>::value)
+{
+    {
+    __node_pointer_pointer __npp = __bucket_list_.release();
+    __bucket_list_.reset(__u.__bucket_list_.release());
+    __u.__bucket_list_.reset(__npp);
+    }
+    _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
+    __swap_alloc(__bucket_list_.get_deleter().__alloc(),
+             __u.__bucket_list_.get_deleter().__alloc());
+    __swap_alloc(__node_alloc(), __u.__node_alloc());
+    _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
+    __p2_.swap(__u.__p2_);
+    __p3_.swap(__u.__p3_);
+    if (size() > 0)
+        __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] =
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()));
+    if (__u.size() > 0)
+        __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] =
+            static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first()));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const
+{
+    _LIBCPP_ASSERT(__n < bucket_count(),
+        "unordered container::bucket_size(n) called with n >= bucket_count()");
+    __node_const_pointer __np = __bucket_list_[__n];
+    size_type __bc = bucket_count();
+    size_type __r = 0;
+    if (__np != nullptr)
+    {
+        for (__np = __np->__next_; __np != nullptr &&
+                                   __constrain_hash(__np->__hash_, __bc) == __n;
+                                                    __np = __np->__next_, ++__r)
+            ;
+    }
+    return __r;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x,
+     __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const
+{
+    return __i->__node_ != nullptr;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const
+{
+    return false;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const
+{
+    return false;
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+bool
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const
+{
+    return false;
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP__HASH_TABLE
diff --git a/include/c++/v1/__locale b/include/c++/v1/__locale
new file mode 100644
index 0000000..3daa1f1
--- /dev/null
+++ b/include/c++/v1/__locale
@@ -0,0 +1,1454 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___LOCALE
+#define _LIBCPP___LOCALE
+
+#include <__config>
+#include <string>
+#include <memory>
+#include <utility>
+#include <mutex>
+#include <cstdint>
+#include <cctype>
+#include <locale.h>
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+# include <support/win32/locale_win32.h>
+#elif defined(_AIX)
+# include <support/ibm/xlocale.h>
+#elif defined(__ANDROID__)
+// Android gained the locale aware functions in L (API level 21)
+# include <android/api-level.h>
+# if __ANDROID_API__ <= 20
+#  include <support/android/locale_bionic.h>
+# endif
+#elif (defined(__GLIBC__) || defined(__APPLE__)      || defined(__FreeBSD__) \
+    || defined(__sun__)   || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
+# include <xlocale.h>
+#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS locale;
+
+template <class _Facet>
+_LIBCPP_INLINE_VISIBILITY
+bool
+has_facet(const locale&) _NOEXCEPT;
+
+template <class _Facet>
+_LIBCPP_INLINE_VISIBILITY
+const _Facet&
+use_facet(const locale&);
+
+class _LIBCPP_TYPE_VIS locale
+{
+public:
+    // types:
+    class _LIBCPP_TYPE_VIS facet;
+    class _LIBCPP_TYPE_VIS id;
+
+    typedef int category;
+    static const category // values assigned here are for exposition only
+        none     = 0,
+        collate  = LC_COLLATE_MASK,
+        ctype    = LC_CTYPE_MASK,
+        monetary = LC_MONETARY_MASK,
+        numeric  = LC_NUMERIC_MASK,
+        time     = LC_TIME_MASK,
+        messages = LC_MESSAGES_MASK,
+        all = collate | ctype | monetary | numeric | time | messages;
+
+    // construct/copy/destroy:
+    locale()  _NOEXCEPT;
+    locale(const locale&)  _NOEXCEPT;
+    explicit locale(const char*);
+    explicit locale(const string&);
+    locale(const locale&, const char*, category);
+    locale(const locale&, const string&, category);
+    template <class _Facet>
+        _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
+    locale(const locale&, const locale&, category);
+
+    ~locale();
+
+    const locale& operator=(const locale&)  _NOEXCEPT;
+
+    template <class _Facet> locale combine(const locale&) const;
+
+    // locale operations:
+    string name() const;
+    bool operator==(const locale&) const;
+    bool operator!=(const locale& __y) const {return !(*this == __y);}
+    template <class _CharT, class _Traits, class _Allocator>
+      bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
+                      const basic_string<_CharT, _Traits, _Allocator>&) const;
+
+    // global locale objects:
+    static locale global(const locale&);
+    static const locale& classic();
+
+private:
+    class __imp;
+    __imp* __locale_;
+
+    void __install_ctor(const locale&, facet*, long);
+    static locale& __global();
+    bool has_facet(id&) const;
+    const facet* use_facet(id&) const;
+
+    template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;
+    template <class _Facet> friend const _Facet& use_facet(const locale&);
+};
+
+class _LIBCPP_TYPE_VIS locale::facet
+    : public __shared_count
+{
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit facet(size_t __refs = 0)
+        : __shared_count(static_cast<long>(__refs)-1) {}
+
+    virtual ~facet();
+
+//    facet(const facet&) = delete;     // effectively done in __shared_count
+//    void operator=(const facet&) = delete;
+private:
+    virtual void __on_zero_shared() _NOEXCEPT;
+};
+
+class _LIBCPP_TYPE_VIS locale::id
+{
+    once_flag      __flag_;
+    int32_t        __id_;
+
+    static int32_t __next_id;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
+private:
+    void __init();
+    void operator=(const id&); // = delete;
+    id(const id&); // = delete;
+public:  // only needed for tests
+    long __get();
+
+    friend class locale;
+    friend class locale::__imp;
+};
+
+template <class _Facet>
+inline _LIBCPP_INLINE_VISIBILITY
+locale::locale(const locale& __other, _Facet* __f)
+{
+    __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
+}
+
+template <class _Facet>
+locale
+locale::combine(const locale& __other) const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (!_VSTD::has_facet<_Facet>(__other))
+        throw runtime_error("locale::combine: locale missing facet");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
+}
+
+template <class _Facet>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+has_facet(const locale& __l)  _NOEXCEPT
+{
+    return __l.has_facet(_Facet::id);
+}
+
+template <class _Facet>
+inline _LIBCPP_INLINE_VISIBILITY
+const _Facet&
+use_facet(const locale& __l)
+{
+    return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
+}
+
+// template <class _CharT> class collate;
+
+template <class _CharT>
+class _LIBCPP_TYPE_VIS_ONLY collate
+    : public locale::facet
+{
+public:
+    typedef _CharT char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit collate(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(const char_type* __lo1, const char_type* __hi1,
+                const char_type* __lo2, const char_type* __hi2) const
+    {
+        return do_compare(__lo1, __hi1, __lo2, __hi2);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    string_type transform(const char_type* __lo, const char_type* __hi) const
+    {
+        return do_transform(__lo, __hi);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    long hash(const char_type* __lo, const char_type* __hi) const
+    {
+        return do_hash(__lo, __hi);
+    }
+
+    static locale::id id;
+
+protected:
+    ~collate();
+    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
+                           const char_type* __lo2, const char_type* __hi2) const;
+    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
+        {return string_type(__lo, __hi);}
+    virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
+};
+
+template <class _CharT> locale::id collate<_CharT>::id;
+
+template <class _CharT>
+collate<_CharT>::~collate()
+{
+}
+
+template <class _CharT>
+int
+collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
+                            const char_type* __lo2, const char_type* __hi2) const
+{
+    for (; __lo2 != __hi2; ++__lo1, ++__lo2)
+    {
+        if (__lo1 == __hi1 || *__lo1 < *__lo2)
+            return -1;
+        if (*__lo2 < *__lo1)
+            return 1;
+    }
+    return __lo1 != __hi1;
+}
+
+template <class _CharT>
+long
+collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
+{
+    size_t __h = 0;
+    const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
+    const size_t __mask = size_t(0xF) << (__sr + 4);
+    for(const char_type* __p = __lo; __p != __hi; ++__p)
+    {
+        __h = (__h << 4) + static_cast<size_t>(*__p);
+        size_t __g = __h & __mask;
+        __h ^= __g | (__g >> __sr);
+    }
+    return static_cast<long>(__h);
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
+
+// template <class CharT> class collate_byname;
+
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
+
+template <>
+class _LIBCPP_TYPE_VIS collate_byname<char>
+    : public collate<char>
+{
+    locale_t __l;
+public:
+    typedef char char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit collate_byname(const char* __n, size_t __refs = 0);
+    explicit collate_byname(const string& __n, size_t __refs = 0);
+
+protected:
+    ~collate_byname();
+    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
+                           const char_type* __lo2, const char_type* __hi2) const;
+    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
+};
+
+template <>
+class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
+    : public collate<wchar_t>
+{
+    locale_t __l;
+public:
+    typedef wchar_t char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit collate_byname(const char* __n, size_t __refs = 0);
+    explicit collate_byname(const string& __n, size_t __refs = 0);
+
+protected:
+    ~collate_byname();
+
+    virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
+                           const char_type* __lo2, const char_type* __hi2) const;
+    virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+bool
+locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
+                   const basic_string<_CharT, _Traits, _Allocator>& __y) const
+{
+    return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
+                                       __x.data(), __x.data() + __x.size(),
+                                       __y.data(), __y.data() + __y.size()) < 0;
+}
+
+// template <class charT> class ctype
+
+class _LIBCPP_TYPE_VIS ctype_base
+{
+public:
+#ifdef __GLIBC__
+    typedef unsigned short mask;
+    static const mask space  = _ISspace;
+    static const mask print  = _ISprint;
+    static const mask cntrl  = _IScntrl;
+    static const mask upper  = _ISupper;
+    static const mask lower  = _ISlower;
+    static const mask alpha  = _ISalpha;
+    static const mask digit  = _ISdigit;
+    static const mask punct  = _ISpunct;
+    static const mask xdigit = _ISxdigit;
+    static const mask blank  = _ISblank;
+#elif defined(_WIN32)
+    typedef unsigned short mask;
+    static const mask space  = _SPACE;
+    static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
+    static const mask cntrl  = _CONTROL;
+    static const mask upper  = _UPPER;
+    static const mask lower  = _LOWER;
+    static const mask alpha  = _ALPHA;
+    static const mask digit  = _DIGIT;
+    static const mask punct  = _PUNCT;
+    static const mask xdigit = _HEX;
+    static const mask blank  = _BLANK;
+#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__ANDROID__)
+#ifdef __APPLE__
+    typedef __uint32_t mask;
+#elif defined(__FreeBSD__)
+    typedef unsigned long mask;
+#elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__)
+    typedef unsigned short mask;
+#elif defined(__ANDROID__)
+    typedef char mask;
+#endif
+    static const mask space  = _CTYPE_S;
+    static const mask print  = _CTYPE_R;
+    static const mask cntrl  = _CTYPE_C;
+    static const mask upper  = _CTYPE_U;
+    static const mask lower  = _CTYPE_L;
+    static const mask alpha  = _CTYPE_A;
+    static const mask digit  = _CTYPE_D;
+    static const mask punct  = _CTYPE_P;
+    static const mask xdigit = _CTYPE_X;
+# if defined(__NetBSD__)
+    static const mask blank  = _CTYPE_BL;
+# else
+    static const mask blank  = _CTYPE_B;
+# endif
+#elif defined(__sun__) || defined(_AIX)
+    typedef unsigned int mask;
+    static const mask space  = _ISSPACE;
+    static const mask print  = _ISPRINT;
+    static const mask cntrl  = _ISCNTRL;
+    static const mask upper  = _ISUPPER;
+    static const mask lower  = _ISLOWER;
+    static const mask alpha  = _ISALPHA;
+    static const mask digit  = _ISDIGIT;
+    static const mask punct  = _ISPUNCT;
+    static const mask xdigit = _ISXDIGIT;
+    static const mask blank  = _ISBLANK;
+#else  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__
+    typedef unsigned long mask;
+    static const mask space  = 1<<0;
+    static const mask print  = 1<<1;
+    static const mask cntrl  = 1<<2;
+    static const mask upper  = 1<<3;
+    static const mask lower  = 1<<4;
+    static const mask alpha  = 1<<5;
+    static const mask digit  = 1<<6;
+    static const mask punct  = 1<<7;
+    static const mask xdigit = 1<<8;
+    static const mask blank  = 1<<9;
+#endif  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
+    static const mask alnum  = alpha | digit;
+    static const mask graph  = alnum | punct;
+
+    _LIBCPP_ALWAYS_INLINE ctype_base() {}
+};
+
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype;
+
+template <>
+class _LIBCPP_TYPE_VIS ctype<wchar_t>
+    : public locale::facet,
+      public ctype_base
+{
+public:
+    typedef wchar_t char_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit ctype(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    bool is(mask __m, char_type __c) const
+    {
+        return do_is(__m, __c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
+    {
+        return do_is(__low, __high, __vec);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
+    {
+        return do_scan_is(__m, __low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
+    {
+        return do_scan_not(__m, __low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type toupper(char_type __c) const
+    {
+        return do_toupper(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* toupper(char_type* __low, const char_type* __high) const
+    {
+        return do_toupper(__low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type tolower(char_type __c) const
+    {
+        return do_tolower(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* tolower(char_type* __low, const char_type* __high) const
+    {
+        return do_tolower(__low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type widen(char __c) const
+    {
+        return do_widen(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char* widen(const char* __low, const char* __high, char_type* __to) const
+    {
+        return do_widen(__low, __high, __to);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char narrow(char_type __c, char __dfault) const
+    {
+        return do_narrow(__c, __dfault);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
+    {
+        return do_narrow(__low, __high, __dfault, __to);
+    }
+
+    static locale::id id;
+
+protected:
+    ~ctype();
+    virtual bool do_is(mask __m, char_type __c) const;
+    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
+    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
+    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
+    virtual char_type do_toupper(char_type) const;
+    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
+    virtual char_type do_tolower(char_type) const;
+    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
+    virtual char_type do_widen(char) const;
+    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
+    virtual char do_narrow(char_type, char __dfault) const;
+    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
+};
+
+template <>
+class _LIBCPP_TYPE_VIS ctype<char>
+    : public locale::facet, public ctype_base
+{
+    const mask* __tab_;
+    bool        __del_;
+public:
+    typedef char char_type;
+
+    explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
+
+    _LIBCPP_ALWAYS_INLINE
+    bool is(mask __m, char_type __c) const
+    {
+        return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
+    {
+        for (; __low != __high; ++__low, ++__vec)
+            *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
+        return __low;
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
+    {
+        for (; __low != __high; ++__low)
+            if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
+                break;
+        return __low;
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
+    {
+        for (; __low != __high; ++__low)
+            if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
+                break;
+        return __low;
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type toupper(char_type __c) const
+    {
+        return do_toupper(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* toupper(char_type* __low, const char_type* __high) const
+    {
+        return do_toupper(__low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type tolower(char_type __c) const
+    {
+        return do_tolower(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char_type* tolower(char_type* __low, const char_type* __high) const
+    {
+        return do_tolower(__low, __high);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char_type widen(char __c) const
+    {
+        return do_widen(__c);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char* widen(const char* __low, const char* __high, char_type* __to) const
+    {
+        return do_widen(__low, __high, __to);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    char narrow(char_type __c, char __dfault) const
+    {
+        return do_narrow(__c, __dfault);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
+    {
+        return do_narrow(__low, __high, __dfault, __to);
+    }
+
+    static locale::id id;
+
+#ifdef _CACHED_RUNES
+    static const size_t table_size = _CACHED_RUNES;
+#else
+    static const size_t table_size = 256;  // FIXME: Don't hardcode this.
+#endif
+    _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}
+    static const mask* classic_table()  _NOEXCEPT;
+#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
+    static const int* __classic_upper_table() _NOEXCEPT;
+    static const int* __classic_lower_table() _NOEXCEPT;
+#endif
+#if defined(__NetBSD__)
+    static const short* __classic_upper_table() _NOEXCEPT;
+    static const short* __classic_lower_table() _NOEXCEPT;
+#endif
+
+protected:
+    ~ctype();
+    virtual char_type do_toupper(char_type __c) const;
+    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
+    virtual char_type do_tolower(char_type __c) const;
+    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
+    virtual char_type do_widen(char __c) const;
+    virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
+    virtual char do_narrow(char_type __c, char __dfault) const;
+    virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
+};
+
+// template <class CharT> class ctype_byname;
+
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY ctype_byname;
+
+template <>
+class _LIBCPP_TYPE_VIS ctype_byname<char>
+    : public ctype<char>
+{
+    locale_t __l;
+
+public:
+    explicit ctype_byname(const char*, size_t = 0);
+    explicit ctype_byname(const string&, size_t = 0);
+
+protected:
+    ~ctype_byname();
+    virtual char_type do_toupper(char_type) const;
+    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
+    virtual char_type do_tolower(char_type) const;
+    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
+};
+
+template <>
+class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
+    : public ctype<wchar_t>
+{
+    locale_t __l;
+
+public:
+    explicit ctype_byname(const char*, size_t = 0);
+    explicit ctype_byname(const string&, size_t = 0);
+
+protected:
+    ~ctype_byname();
+    virtual bool do_is(mask __m, char_type __c) const;
+    virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
+    virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
+    virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
+    virtual char_type do_toupper(char_type) const;
+    virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
+    virtual char_type do_tolower(char_type) const;
+    virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
+    virtual char_type do_widen(char) const;
+    virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
+    virtual char do_narrow(char_type, char __dfault) const;
+    virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
+};
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isspace(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isprint(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+iscntrl(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isupper(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+islower(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isalpha(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isdigit(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+ispunct(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isxdigit(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isalnum(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+isgraph(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT
+toupper(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).toupper(__c);
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT
+tolower(_CharT __c, const locale& __loc)
+{
+    return use_facet<ctype<_CharT> >(__loc).tolower(__c);
+}
+
+// codecvt_base
+
+class _LIBCPP_TYPE_VIS codecvt_base
+{
+public:
+    _LIBCPP_ALWAYS_INLINE codecvt_base() {}
+    enum result {ok, partial, error, noconv};
+};
+
+// template <class internT, class externT, class stateT> class codecvt;
+
+template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS_ONLY codecvt;
+
+// template <> class codecvt<char, char, mbstate_t>
+
+template <>
+class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+public:
+    typedef char      intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(const char*, size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+// template <> class codecvt<wchar_t, char, mbstate_t>
+
+template <>
+class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+    locale_t __l;
+public:
+    typedef wchar_t   intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    explicit codecvt(size_t __refs = 0);
+
+    _LIBCPP_ALWAYS_INLINE
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    explicit codecvt(const char*, size_t __refs = 0);
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+// template <> class codecvt<char16_t, char, mbstate_t>
+
+template <>
+class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+public:
+    typedef char16_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(const char*, size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+// template <> class codecvt<char32_t, char, mbstate_t>
+
+template <>
+class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
+    : public locale::facet,
+      public codecvt_base
+{
+public:
+    typedef char32_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    result out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
+    {
+        return do_unshift(__st, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    result in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
+    {
+        return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int encoding() const  _NOEXCEPT
+    {
+        return do_encoding();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    bool always_noconv() const  _NOEXCEPT
+    {
+        return do_always_noconv();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
+    {
+        return do_length(__st, __frm, __end, __mx);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int max_length() const  _NOEXCEPT
+    {
+        return do_max_length();
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt(const char*, size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    ~codecvt();
+
+    virtual result do_out(state_type& __st,
+                          const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+                          extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result do_in(state_type& __st,
+                         const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+                         intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result do_unshift(state_type& __st,
+                              extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const  _NOEXCEPT;
+    virtual bool do_always_noconv() const  _NOEXCEPT;
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
+    virtual int do_max_length() const  _NOEXCEPT;
+};
+
+// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
+
+template <class _InternT, class _ExternT, class _StateT>
+class _LIBCPP_TYPE_VIS_ONLY codecvt_byname
+    : public codecvt<_InternT, _ExternT, _StateT>
+{
+public:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt_byname(const char* __nm, size_t __refs = 0)
+        : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt_byname(const string& __nm, size_t __refs = 0)
+        : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
+protected:
+    ~codecvt_byname();
+};
+
+template <class _InternT, class _ExternT, class _StateT>
+codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
+{
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
+
+_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
+
+template <size_t _Np>
+struct __narrow_to_utf8
+{
+    template <class _OutputIterator, class _CharT>
+    _OutputIterator
+    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
+};
+
+template <>
+struct __narrow_to_utf8<8>
+{
+    template <class _OutputIterator, class _CharT>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
+    {
+        for (; __wb < __we; ++__wb, ++__s)
+            *__s = *__wb;
+        return __s;
+    }
+};
+
+template <>
+struct __narrow_to_utf8<16>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    _LIBCPP_ALWAYS_INLINE
+    __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
+
+    ~__narrow_to_utf8();
+
+    template <class _OutputIterator, class _CharT>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
+    {
+        result __r = ok;
+        mbstate_t __mb;
+        while (__wb < __we && __r != error)
+        {
+            const int __sz = 32;
+            char __buf[__sz];
+            char* __bn;
+            const char16_t* __wn = (const char16_t*)__wb;
+            __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
+                         __buf, __buf+__sz, __bn);
+            if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
+                __throw_runtime_error("locale not supported");
+            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
+                *__s = *__p;
+            __wb = (const _CharT*)__wn;
+        }
+        return __s;
+    }
+};
+
+template <>
+struct __narrow_to_utf8<32>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    _LIBCPP_ALWAYS_INLINE
+    __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
+
+    ~__narrow_to_utf8();
+
+    template <class _OutputIterator, class _CharT>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
+    {
+        result __r = ok;
+        mbstate_t __mb;
+        while (__wb < __we && __r != error)
+        {
+            const int __sz = 32;
+            char __buf[__sz];
+            char* __bn;
+            const char32_t* __wn = (const char32_t*)__wb;
+            __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
+                         __buf, __buf+__sz, __bn);
+            if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
+                __throw_runtime_error("locale not supported");
+            for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
+                *__s = *__p;
+            __wb = (const _CharT*)__wn;
+        }
+        return __s;
+    }
+};
+
+template <size_t _Np>
+struct __widen_from_utf8
+{
+    template <class _OutputIterator>
+    _OutputIterator
+    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
+};
+
+template <>
+struct __widen_from_utf8<8>
+{
+    template <class _OutputIterator>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
+    {
+        for (; __nb < __ne; ++__nb, ++__s)
+            *__s = *__nb;
+        return __s;
+    }
+};
+
+template <>
+struct __widen_from_utf8<16>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    _LIBCPP_ALWAYS_INLINE
+    __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
+
+    ~__widen_from_utf8();
+
+    template <class _OutputIterator>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
+    {
+        result __r = ok;
+        mbstate_t __mb;
+        while (__nb < __ne && __r != error)
+        {
+            const int __sz = 32;
+            char16_t __buf[__sz];
+            char16_t* __bn;
+            const char* __nn = __nb;
+            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
+                        __buf, __buf+__sz, __bn);
+            if (__r == codecvt_base::error || __nn == __nb)
+                __throw_runtime_error("locale not supported");
+            for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
+                *__s = (wchar_t)*__p;
+            __nb = __nn;
+        }
+        return __s;
+    }
+};
+
+template <>
+struct __widen_from_utf8<32>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    _LIBCPP_ALWAYS_INLINE
+    __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
+
+    ~__widen_from_utf8();
+
+    template <class _OutputIterator>
+    _LIBCPP_ALWAYS_INLINE
+    _OutputIterator
+    operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
+    {
+        result __r = ok;
+        mbstate_t __mb;
+        while (__nb < __ne && __r != error)
+        {
+            const int __sz = 32;
+            char32_t __buf[__sz];
+            char32_t* __bn;
+            const char* __nn = __nb;
+            __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
+                        __buf, __buf+__sz, __bn);
+            if (__r == codecvt_base::error || __nn == __nb)
+                __throw_runtime_error("locale not supported");
+            for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
+                *__s = (wchar_t)*__p;
+            __nb = __nn;
+        }
+        return __s;
+    }
+};
+
+// template <class charT> class numpunct
+
+template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY numpunct;
+
+template <>
+class _LIBCPP_TYPE_VIS numpunct<char>
+    : public locale::facet
+{
+public:
+    typedef char char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit numpunct(size_t __refs = 0);
+
+    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
+    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
+    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
+    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
+    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
+
+    static locale::id id;
+
+protected:
+    ~numpunct();
+    virtual char_type do_decimal_point() const;
+    virtual char_type do_thousands_sep() const;
+    virtual string do_grouping() const;
+    virtual string_type do_truename() const;
+    virtual string_type do_falsename() const;
+
+    char_type __decimal_point_;
+    char_type __thousands_sep_;
+    string __grouping_;
+};
+
+template <>
+class _LIBCPP_TYPE_VIS numpunct<wchar_t>
+    : public locale::facet
+{
+public:
+    typedef wchar_t char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit numpunct(size_t __refs = 0);
+
+    _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
+    _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
+    _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
+    _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
+    _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
+
+    static locale::id id;
+
+protected:
+    ~numpunct();
+    virtual char_type do_decimal_point() const;
+    virtual char_type do_thousands_sep() const;
+    virtual string do_grouping() const;
+    virtual string_type do_truename() const;
+    virtual string_type do_falsename() const;
+
+    char_type __decimal_point_;
+    char_type __thousands_sep_;
+    string __grouping_;
+};
+
+// template <class charT> class numpunct_byname
+
+template <class charT> class _LIBCPP_TYPE_VIS_ONLY numpunct_byname;
+
+template <>
+class _LIBCPP_TYPE_VIS numpunct_byname<char>
+: public numpunct<char>
+{
+public:
+    typedef char char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
+    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
+
+protected:
+    ~numpunct_byname();
+
+private:
+    void __init(const char*);
+};
+
+template <>
+class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
+: public numpunct<wchar_t>
+{
+public:
+    typedef wchar_t char_type;
+    typedef basic_string<char_type> string_type;
+
+    explicit numpunct_byname(const char* __nm, size_t __refs = 0);
+    explicit numpunct_byname(const string& __nm, size_t __refs = 0);
+
+protected:
+    ~numpunct_byname();
+
+private:
+    void __init(const char*);
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___LOCALE
diff --git a/include/c++/v1/__mutex_base b/include/c++/v1/__mutex_base
new file mode 100644
index 0000000..293fead
--- /dev/null
+++ b/include/c++/v1/__mutex_base
@@ -0,0 +1,401 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MUTEX_BASE
+#define _LIBCPP___MUTEX_BASE
+
+#include <__config>
+#include <chrono>
+#include <system_error>
+#include <pthread.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS mutex
+{
+    pthread_mutex_t __m_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_CONSTEXPR
+     constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
+#else
+     mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;}
+#endif
+     ~mutex();
+
+private:
+    mutex(const mutex&);// = delete;
+    mutex& operator=(const mutex&);// = delete;
+
+public:
+    void lock();
+    bool try_lock() _NOEXCEPT;
+    void unlock() _NOEXCEPT;
+
+    typedef pthread_mutex_t* native_handle_type;
+    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
+};
+
+struct _LIBCPP_TYPE_VIS defer_lock_t {};
+struct _LIBCPP_TYPE_VIS try_to_lock_t {};
+struct _LIBCPP_TYPE_VIS adopt_lock_t {};
+
+#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX)
+
+extern const defer_lock_t  defer_lock;
+extern const try_to_lock_t try_to_lock;
+extern const adopt_lock_t  adopt_lock;
+
+#else
+
+constexpr defer_lock_t  defer_lock  = defer_lock_t();
+constexpr try_to_lock_t try_to_lock = try_to_lock_t();
+constexpr adopt_lock_t  adopt_lock  = adopt_lock_t();
+
+#endif
+
+template <class _Mutex>
+class _LIBCPP_TYPE_VIS_ONLY lock_guard
+{
+public:
+    typedef _Mutex mutex_type;
+
+private:
+    mutex_type& __m_;
+public:
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lock_guard(mutex_type& __m)
+        : __m_(__m) {__m_.lock();}
+    _LIBCPP_INLINE_VISIBILITY
+    lock_guard(mutex_type& __m, adopt_lock_t)
+        : __m_(__m) {}
+    _LIBCPP_INLINE_VISIBILITY
+    ~lock_guard() {__m_.unlock();}
+
+private:
+    lock_guard(lock_guard const&);// = delete;
+    lock_guard& operator=(lock_guard const&);// = delete;
+};
+
+template <class _Mutex>
+class _LIBCPP_TYPE_VIS_ONLY unique_lock
+{
+public:
+    typedef _Mutex mutex_type;
+
+private:
+    mutex_type* __m_;
+    bool __owns_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit unique_lock(mutex_type& __m)
+        : __m_(&__m), __owns_(true) {__m_->lock();}
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT
+        : __m_(&__m), __owns_(false) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock(mutex_type& __m, try_to_lock_t)
+        : __m_(&__m), __owns_(__m.try_lock()) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock(mutex_type& __m, adopt_lock_t)
+        : __m_(&__m), __owns_(true) {}
+    template <class _Clock, class _Duration>
+    _LIBCPP_INLINE_VISIBILITY
+        unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t)
+            : __m_(&__m), __owns_(__m.try_lock_until(__t)) {}
+    template <class _Rep, class _Period>
+    _LIBCPP_INLINE_VISIBILITY
+        unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d)
+            : __m_(&__m), __owns_(__m.try_lock_for(__d)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    ~unique_lock()
+    {
+        if (__owns_)
+            __m_->unlock();
+    }
+
+private:
+    unique_lock(unique_lock const&); // = delete;
+    unique_lock& operator=(unique_lock const&); // = delete;
+
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock(unique_lock&& __u) _NOEXCEPT
+        : __m_(__u.__m_), __owns_(__u.__owns_)
+        {__u.__m_ = nullptr; __u.__owns_ = false;}
+    _LIBCPP_INLINE_VISIBILITY
+    unique_lock& operator=(unique_lock&& __u) _NOEXCEPT
+        {
+            if (__owns_)
+                __m_->unlock();
+            __m_ = __u.__m_;
+            __owns_ = __u.__owns_;
+            __u.__m_ = nullptr;
+            __u.__owns_ = false;
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    void lock();
+    bool try_lock();
+
+    template <class _Rep, class _Period>
+        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d);
+    template <class _Clock, class _Duration>
+        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+
+    void unlock();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(unique_lock& __u) _NOEXCEPT
+    {
+        _VSTD::swap(__m_, __u.__m_);
+        _VSTD::swap(__owns_, __u.__owns_);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* release() _NOEXCEPT
+    {
+        mutex_type* __m = __m_;
+        __m_ = nullptr;
+        __owns_ = false;
+        return __m;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool owns_lock() const _NOEXCEPT {return __owns_;}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_EXPLICIT
+        operator bool () const _NOEXCEPT {return __owns_;}
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* mutex() const _NOEXCEPT {return __m_;}
+};
+
+template <class _Mutex>
+void
+unique_lock<_Mutex>::lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "unique_lock::lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "unique_lock::lock: already locked");
+    __m_->lock();
+    __owns_ = true;
+}
+
+template <class _Mutex>
+bool
+unique_lock<_Mutex>::try_lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked");
+    __owns_ = __m_->try_lock();
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Rep, class _Period>
+bool
+unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked");
+    __owns_ = __m_->try_lock_for(__d);
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Clock, class _Duration>
+bool
+unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked");
+    __owns_ = __m_->try_lock_until(__t);
+    return __owns_;
+}
+
+template <class _Mutex>
+void
+unique_lock<_Mutex>::unlock()
+{
+    if (!__owns_)
+        __throw_system_error(EPERM, "unique_lock::unlock: not locked");
+    __m_->unlock();
+    __owns_ = false;
+}
+
+template <class _Mutex>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT
+    {__x.swap(__y);}
+
+//enum class cv_status
+_LIBCPP_DECLARE_STRONG_ENUM(cv_status)
+{
+    no_timeout,
+    timeout
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
+
+class _LIBCPP_TYPE_VIS condition_variable
+{
+    pthread_cond_t __cv_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_CONSTEXPR
+    constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {}
+#else
+    condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;}
+#endif
+    ~condition_variable();
+
+private:
+    condition_variable(const condition_variable&); // = delete;
+    condition_variable& operator=(const condition_variable&); // = delete;
+
+public:
+    void notify_one() _NOEXCEPT;
+    void notify_all() _NOEXCEPT;
+
+    void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
+    template <class _Predicate>
+        void wait(unique_lock<mutex>& __lk, _Predicate __pred);
+
+    template <class _Clock, class _Duration>
+        cv_status
+        wait_until(unique_lock<mutex>& __lk,
+                   const chrono::time_point<_Clock, _Duration>& __t);
+
+    template <class _Clock, class _Duration, class _Predicate>
+        bool
+        wait_until(unique_lock<mutex>& __lk,
+                   const chrono::time_point<_Clock, _Duration>& __t,
+                   _Predicate __pred);
+
+    template <class _Rep, class _Period>
+        cv_status
+        wait_for(unique_lock<mutex>& __lk,
+                 const chrono::duration<_Rep, _Period>& __d);
+
+    template <class _Rep, class _Period, class _Predicate>
+        bool
+        wait_for(unique_lock<mutex>& __lk,
+                 const chrono::duration<_Rep, _Period>& __d,
+                 _Predicate __pred);
+
+    typedef pthread_cond_t* native_handle_type;
+    _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
+
+private:
+    void __do_timed_wait(unique_lock<mutex>& __lk,
+       chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
+};
+
+template <class _To, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    chrono::__is_duration<_To>::value,
+    _To
+>::type
+__ceil(chrono::duration<_Rep, _Period> __d)
+{
+    using namespace chrono;
+    _To __r = duration_cast<_To>(__d);
+    if (__r < __d)
+        ++__r;
+    return __r;
+}
+
+template <class _Predicate>
+void
+condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
+{
+    while (!__pred())
+        wait(__lk);
+}
+
+template <class _Clock, class _Duration>
+cv_status
+condition_variable::wait_until(unique_lock<mutex>& __lk,
+                               const chrono::time_point<_Clock, _Duration>& __t)
+{
+    using namespace chrono;
+    wait_for(__lk, __t - _Clock::now());
+    return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
+}
+
+template <class _Clock, class _Duration, class _Predicate>
+bool
+condition_variable::wait_until(unique_lock<mutex>& __lk,
+                   const chrono::time_point<_Clock, _Duration>& __t,
+                   _Predicate __pred)
+{
+    while (!__pred())
+    {
+        if (wait_until(__lk, __t) == cv_status::timeout)
+            return __pred();
+    }
+    return true;
+}
+
+template <class _Rep, class _Period>
+cv_status
+condition_variable::wait_for(unique_lock<mutex>& __lk,
+                             const chrono::duration<_Rep, _Period>& __d)
+{
+    using namespace chrono;
+    if (__d <= __d.zero())
+        return cv_status::timeout;
+    typedef time_point<system_clock, duration<long double, nano> > __sys_tpf;
+    typedef time_point<system_clock, nanoseconds> __sys_tpi;
+    __sys_tpf _Max = __sys_tpi::max();
+    system_clock::time_point __s_now = system_clock::now();
+    steady_clock::time_point __c_now = steady_clock::now();
+    if (_Max - __d > __s_now)
+        __do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d));
+    else
+        __do_timed_wait(__lk, __sys_tpi::max());
+    return steady_clock::now() - __c_now < __d ? cv_status::no_timeout :
+                                                 cv_status::timeout;
+}
+
+template <class _Rep, class _Period, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+condition_variable::wait_for(unique_lock<mutex>& __lk,
+                             const chrono::duration<_Rep, _Period>& __d,
+                             _Predicate __pred)
+{
+    return wait_until(__lk, chrono::steady_clock::now() + __d,
+                      _VSTD::move(__pred));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___MUTEX_BASE
diff --git a/include/c++/v1/__refstring b/include/c++/v1/__refstring
new file mode 100644
index 0000000..6866bf1
--- /dev/null
+++ b/include/c++/v1/__refstring
@@ -0,0 +1,139 @@
+//===------------------------ __refstring ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___REFSTRING
+#define _LIBCPP___REFSTRING
+
+#include <__config>
+#include <cstddef>
+#include <cstring>
+#if __APPLE__
+#include <dlfcn.h>
+#include <mach-o/dyld.h>
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_HIDDEN __libcpp_refstring
+{
+private:
+    const char* str_;
+
+    typedef int count_t;
+
+    struct _Rep_base
+    {
+        std::size_t len;
+        std::size_t cap;
+        count_t     count;
+    };
+
+    static
+    _Rep_base*
+    rep_from_data(const char *data_) _NOEXCEPT
+    {
+        char *data = const_cast<char *>(data_);
+        return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base));
+    }
+    static
+    char *
+    data_from_rep(_Rep_base *rep) _NOEXCEPT
+    {
+        char *data = reinterpret_cast<char *>(rep);
+        return data + sizeof(*rep);
+    }
+
+#if __APPLE__
+    static
+    const char*
+    compute_gcc_empty_string_storage() _NOEXCEPT
+    {
+        void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD);
+        if (handle == nullptr)
+            return nullptr;
+        void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE");
+        if (sym == nullptr)
+            return nullptr;
+        return data_from_rep(reinterpret_cast<_Rep_base *>(sym));
+    }
+
+    static
+    const char*
+    get_gcc_empty_string_storage() _NOEXCEPT
+    {
+        static const char* p = compute_gcc_empty_string_storage();
+        return p;
+    }
+
+    bool
+    uses_refcount() const
+    {
+        return str_ != get_gcc_empty_string_storage();
+    }
+#else
+    bool
+    uses_refcount() const
+    {
+        return true;
+    }
+#endif
+
+public:
+    explicit __libcpp_refstring(const char* msg) {
+        std::size_t len = strlen(msg);
+        _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1));
+        rep->len = len;
+        rep->cap = len;
+        rep->count = 0;
+        char *data = data_from_rep(rep);
+        std::memcpy(data, msg, len + 1);
+        str_ = data;
+    }
+
+    __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT : str_(s.str_)
+    {
+        if (uses_refcount())
+            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);
+    }
+
+    __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT
+    {
+        bool adjust_old_count = uses_refcount();
+        struct _Rep_base *old_rep = rep_from_data(str_);
+        str_ = s.str_;
+        if (uses_refcount())
+            __sync_add_and_fetch(&rep_from_data(str_)->count, 1);
+        if (adjust_old_count)
+        {
+            if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0)
+            {
+                ::operator delete(old_rep);
+            }
+        }
+        return *this;
+    }
+
+    ~__libcpp_refstring()
+    {
+        if (uses_refcount())
+        {
+            _Rep_base* rep = rep_from_data(str_);
+            if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0)
+            {
+                ::operator delete(rep);
+            }
+        }
+    }
+
+    const char* c_str() const _NOEXCEPT {return str_;}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif //_LIBCPP___REFSTRING
diff --git a/include/c++/v1/__split_buffer b/include/c++/v1/__split_buffer
new file mode 100644
index 0000000..1d529cb
--- /dev/null
+++ b/include/c++/v1/__split_buffer
@@ -0,0 +1,654 @@
+// -*- C++ -*-
+#ifndef _LIBCPP_SPLIT_BUFFER
+#define _LIBCPP_SPLIT_BUFFER
+
+#include <__config>
+#include <type_traits>
+#include <algorithm>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool>
+class __split_buffer_common
+{
+protected:
+    void __throw_length_error() const;
+    void __throw_out_of_range() const;
+};
+
+template <class _Tp, class _Allocator = allocator<_Tp> >
+struct __split_buffer
+    : private __split_buffer_common<true>
+{
+private:
+    __split_buffer(const __split_buffer&);
+    __split_buffer& operator=(const __split_buffer&);
+public:
+    typedef _Tp                                             value_type;
+    typedef _Allocator                                      allocator_type;
+    typedef typename remove_reference<allocator_type>::type __alloc_rr;
+    typedef allocator_traits<__alloc_rr>                    __alloc_traits;
+    typedef value_type&                                     reference;
+    typedef const value_type&                               const_reference;
+    typedef typename __alloc_traits::size_type              size_type;
+    typedef typename __alloc_traits::difference_type        difference_type;
+    typedef typename __alloc_traits::pointer                pointer;
+    typedef typename __alloc_traits::const_pointer          const_pointer;
+    typedef pointer                                         iterator;
+    typedef const_pointer                                   const_iterator;
+
+    pointer                                         __first_;
+    pointer                                         __begin_;
+    pointer                                         __end_;
+    __compressed_pair<pointer, allocator_type> __end_cap_;
+
+    typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref;
+    typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref;
+
+    _LIBCPP_INLINE_VISIBILITY __alloc_rr&           __alloc() _NOEXCEPT         {return __end_cap_.second();}
+    _LIBCPP_INLINE_VISIBILITY const __alloc_rr&     __alloc() const _NOEXCEPT   {return __end_cap_.second();}
+    _LIBCPP_INLINE_VISIBILITY pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}
+    _LIBCPP_INLINE_VISIBILITY const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}
+
+    __split_buffer()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    explicit __split_buffer(__alloc_rr& __a);
+    explicit __split_buffer(const __alloc_rr& __a);
+    __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
+    ~__split_buffer();
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __split_buffer(__split_buffer&& __c)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+    __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
+    __split_buffer& operator=(__split_buffer&& __c)
+        _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
+                is_nothrow_move_assignable<allocator_type>::value) ||
+               !__alloc_traits::propagate_on_container_move_assignment::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY       iterator begin() _NOEXCEPT       {return __begin_;}
+    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
+    _LIBCPP_INLINE_VISIBILITY       iterator end() _NOEXCEPT         {return __end_;}
+    _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT   {return __end_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT
+        {__destruct_at_end(__begin_);}
+    _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
+    _LIBCPP_INLINE_VISIBILITY bool empty()     const {return __end_ == __begin_;}
+    _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
+    _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
+    _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
+
+    _LIBCPP_INLINE_VISIBILITY       reference front()       {return *__begin_;}
+    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}
+    _LIBCPP_INLINE_VISIBILITY       reference back()        {return *(__end_ - 1);}
+    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return *(__end_ - 1);}
+
+    void reserve(size_type __n);
+    void shrink_to_fit() _NOEXCEPT;
+    void push_front(const_reference __x);
+    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    void push_front(value_type&& __x);
+    void push_back(value_type&& __x);
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        void emplace_back(_Args&&... __args);
+#endif  // !defined(_LIBCPP_HAS_NO_VARIADICS)
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
+    _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
+
+    void __construct_at_end(size_type __n);
+    void __construct_at_end(size_type __n, const_reference __x);
+    template <class _InputIter>
+        typename enable_if
+        <
+            __is_input_iterator<_InputIter>::value &&
+           !__is_forward_iterator<_InputIter>::value,
+            void
+        >::type
+        __construct_at_end(_InputIter __first, _InputIter __last);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            void
+        >::type
+        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
+        {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
+        void __destruct_at_begin(pointer __new_begin, false_type);
+        void __destruct_at_begin(pointer __new_begin, true_type);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT
+        {__destruct_at_end(__new_last, false_type());}
+    _LIBCPP_INLINE_VISIBILITY
+        void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+        void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
+
+    void swap(__split_buffer& __x)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
+                   __is_nothrow_swappable<__alloc_rr>::value);
+
+    bool __invariants() const;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__split_buffer& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            __alloc() = _VSTD::move(__c.__alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
+                   __is_nothrow_swappable<__alloc_rr>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_swap::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT
+        {}
+};
+
+template <class _Tp, class _Allocator>
+bool
+__split_buffer<_Tp, _Allocator>::__invariants() const
+{
+    if (__first_ == nullptr)
+    {
+        if (__begin_ != nullptr)
+            return false;
+        if (__end_ != nullptr)
+            return false;
+        if (__end_cap() != nullptr)
+            return false;
+    }
+    else
+    {
+        if (__begin_ < __first_)
+            return false;
+        if (__end_ < __begin_)
+            return false;
+        if (__end_cap() < __end_)
+            return false;
+    }
+    return true;
+}
+
+//  Default constructs __n objects starting at __end_
+//  throws if construction throws
+//  Precondition:  __n > 0
+//  Precondition:  size() + __n <= capacity()
+//  Postcondition:  size() == size() + __n
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
+{
+    __alloc_rr& __a = this->__alloc();
+    do
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
+        ++this->__end_;
+        --__n;
+    } while (__n > 0);
+}
+
+//  Copy constructs __n objects starting at __end_ from __x
+//  throws if construction throws
+//  Precondition:  __n > 0
+//  Precondition:  size() + __n <= capacity()
+//  Postcondition:  size() == old size() + __n
+//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
+{
+    __alloc_rr& __a = this->__alloc();
+    do
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
+        ++this->__end_;
+        --__n;
+    } while (__n > 0);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIter>
+typename enable_if
+<
+     __is_input_iterator<_InputIter>::value &&
+    !__is_forward_iterator<_InputIter>::value,
+    void
+>::type
+__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
+{
+    __alloc_rr& __a = this->__alloc();
+    for (; __first != __last; ++__first)
+    {
+        if (__end_ == __end_cap())
+        {
+            size_type __old_cap = __end_cap() - __first_;
+            size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8);
+            __split_buffer __buf(__new_cap, 0, __a);
+            for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_)
+                __alloc_traits::construct(__buf.__alloc(),
+                        _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p));
+            swap(__buf);
+        }
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
+        ++this->__end_;
+    }
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    void
+>::type
+__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
+{
+    __alloc_rr& __a = this->__alloc();
+    for (; __first != __last; ++__first)
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
+        ++this->__end_;
+    }
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
+{
+    while (__begin_ != __new_begin)
+        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
+{
+    __begin_ = __new_begin;
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
+{
+    while (__new_last != __end_)
+        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT
+{
+    __end_ = __new_last;
+}
+
+template <class _Tp, class _Allocator>
+__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
+    : __end_cap_(nullptr, __a)
+{
+    __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;
+    __begin_ = __end_ = __first_ + __start;
+    __end_cap() = __first_ + __cap;
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__split_buffer<_Tp, _Allocator>::__split_buffer()
+    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)
+{
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
+{
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
+    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
+{
+}
+
+template <class _Tp, class _Allocator>
+__split_buffer<_Tp, _Allocator>::~__split_buffer()
+{
+    clear();
+    if (__first_)
+        __alloc_traits::deallocate(__alloc(), __first_, capacity());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
+    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+    : __first_(_VSTD::move(__c.__first_)),
+      __begin_(_VSTD::move(__c.__begin_)),
+      __end_(_VSTD::move(__c.__end_)),
+      __end_cap_(_VSTD::move(__c.__end_cap_))
+{
+    __c.__first_ = nullptr;
+    __c.__begin_ = nullptr;
+    __c.__end_ = nullptr;
+    __c.__end_cap() = nullptr;
+}
+
+template <class _Tp, class _Allocator>
+__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
+    : __end_cap_(__a)
+{
+    if (__a == __c.__alloc())
+    {
+        __first_ = __c.__first_;
+        __begin_ = __c.__begin_;
+        __end_ = __c.__end_;
+        __end_cap() = __c.__end_cap();
+        __c.__first_ = nullptr;
+        __c.__begin_ = nullptr;
+        __c.__end_ = nullptr;
+        __c.__end_cap() = nullptr;
+    }
+    else
+    {
+        size_type __cap = __c.size();
+        __first_ = __alloc_traits::allocate(__alloc(), __cap);
+        __begin_ = __end_ = __first_;
+        __end_cap() = __first_ + __cap;
+        typedef move_iterator<iterator> _Ip;
+        __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+}
+
+template <class _Tp, class _Allocator>
+__split_buffer<_Tp, _Allocator>&
+__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
+    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
+                is_nothrow_move_assignable<allocator_type>::value) ||
+               !__alloc_traits::propagate_on_container_move_assignment::value)
+{
+    clear();
+    shrink_to_fit();
+    __first_ = __c.__first_;
+    __begin_ = __c.__begin_;
+    __end_ = __c.__end_;
+    __end_cap() = __c.__end_cap();
+    __move_assign_alloc(__c,
+        integral_constant<bool,
+                          __alloc_traits::propagate_on_container_move_assignment::value>());
+    __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
+                   __is_nothrow_swappable<__alloc_rr>::value)
+{
+    _VSTD::swap(__first_, __x.__first_);
+    _VSTD::swap(__begin_, __x.__begin_);
+    _VSTD::swap(__end_, __x.__end_);
+    _VSTD::swap(__end_cap(), __x.__end_cap());
+    __swap_alloc(__alloc(), __x.__alloc());
+}
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::reserve(size_type __n)
+{
+    if (__n < capacity())
+    {
+        __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
+        __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                               move_iterator<pointer>(__end_));
+        _VSTD::swap(__first_, __t.__first_);
+        _VSTD::swap(__begin_, __t.__begin_);
+        _VSTD::swap(__end_, __t.__end_);
+        _VSTD::swap(__end_cap(), __t.__end_cap());
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
+{
+    if (capacity() > size())
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            __t.__end_ = __t.__begin_ + (__end_ - __begin_);
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
+{
+    if (__begin_ == __first_)
+    {
+        if (__end_ < __end_cap())
+        {
+            difference_type __d = __end_cap() - __end_;
+            __d = (__d + 1) / 2;
+            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
+            __end_ += __d;
+        }
+        else
+        {
+            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+        }
+    }
+    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x);
+    --__begin_;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
+{
+    if (__begin_ == __first_)
+    {
+        if (__end_ < __end_cap())
+        {
+            difference_type __d = __end_cap() - __end_;
+            __d = (__d + 1) / 2;
+            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
+            __end_ += __d;
+        }
+        else
+        {
+            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+        }
+    }
+    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1),
+            _VSTD::move(__x));
+    --__begin_;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
+{
+    if (__end_ == __end_cap())
+    {
+        if (__begin_ > __first_)
+        {
+            difference_type __d = __begin_ - __first_;
+            __d = (__d + 1) / 2;
+            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
+            __begin_ -= __d;
+        }
+        else
+        {
+            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+        }
+    }
+    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x);
+    ++__end_;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
+{
+    if (__end_ == __end_cap())
+    {
+        if (__begin_ > __first_)
+        {
+            difference_type __d = __begin_ - __first_;
+            __d = (__d + 1) / 2;
+            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
+            __begin_ -= __d;
+        }
+        else
+        {
+            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+        }
+    }
+    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
+            _VSTD::move(__x));
+    ++__end_;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+void
+__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
+{
+    if (__end_ == __end_cap())
+    {
+        if (__begin_ > __first_)
+        {
+            difference_type __d = __begin_ - __first_;
+            __d = (__d + 1) / 2;
+            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
+            __begin_ -= __d;
+        }
+        else
+        {
+            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
+            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
+            __t.__construct_at_end(move_iterator<pointer>(__begin_),
+                                   move_iterator<pointer>(__end_));
+            _VSTD::swap(__first_, __t.__first_);
+            _VSTD::swap(__begin_, __t.__begin_);
+            _VSTD::swap(__end_, __t.__end_);
+            _VSTD::swap(__end_cap(), __t.__end_cap());
+        }
+    }
+    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
+                              _VSTD::forward<_Args>(__args)...);
+    ++__end_;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
+        _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_SPLIT_BUFFER
diff --git a/include/c++/v1/__sso_allocator b/include/c++/v1/__sso_allocator
new file mode 100644
index 0000000..645f2ba
--- /dev/null
+++ b/include/c++/v1/__sso_allocator
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___SSO_ALLOCATOR
+#define _LIBCPP___SSO_ALLOCATOR
+
+#include <__config>
+#include <type_traits>
+#include <new>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, size_t _Np> class _LIBCPP_HIDDEN __sso_allocator;
+
+template <size_t _Np>
+class _LIBCPP_HIDDEN __sso_allocator<void, _Np>
+{
+public:
+    typedef const void*       const_pointer;
+    typedef void              value_type;
+};
+
+template <class _Tp, size_t _Np>
+class _LIBCPP_HIDDEN __sso_allocator
+{
+    typename aligned_storage<sizeof(_Tp) * _Np>::type buf_;
+    bool __allocated_;
+public:
+    typedef size_t            size_type;
+    typedef _Tp*              pointer;
+    typedef _Tp               value_type;
+
+    _LIBCPP_INLINE_VISIBILITY __sso_allocator() throw() : __allocated_(false) {}
+    _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator&) throw() : __allocated_(false) {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY __sso_allocator(const __sso_allocator<_Up, _Np>&) throw()
+         : __allocated_(false) {}
+private:
+    __sso_allocator& operator=(const __sso_allocator&);
+public:
+    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, typename __sso_allocator<void, _Np>::const_pointer = 0)
+    {
+        if (!__allocated_ && __n <= _Np)
+        {
+            __allocated_ = true;
+            return (pointer)&buf_;
+        }
+        return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
+    }
+    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type)
+    {
+        if (__p == (pointer)&buf_)
+            __allocated_ = false;
+        else
+            _VSTD::__deallocate(__p);
+    }
+    _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator==(__sso_allocator& __a) const {return &buf_ == &__a.buf_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(__sso_allocator& __a) const {return &buf_ != &__a.buf_;}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___SSO_ALLOCATOR
diff --git a/include/c++/v1/__std_stream b/include/c++/v1/__std_stream
new file mode 100644
index 0000000..5403ada
--- /dev/null
+++ b/include/c++/v1/__std_stream
@@ -0,0 +1,359 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___STD_STREAM
+#define _LIBCPP___STD_STREAM
+
+#include <__config>
+#include <ostream>
+#include <istream>
+#include <__locale>
+#include <cstdio>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+static const int __limit = 8;
+
+// __stdinbuf
+
+template <class _CharT>
+class _LIBCPP_HIDDEN __stdinbuf
+    : public basic_streambuf<_CharT, char_traits<_CharT> >
+{
+public:
+    typedef _CharT                           char_type;
+    typedef char_traits<char_type>           traits_type;
+    typedef typename traits_type::int_type   int_type;
+    typedef typename traits_type::pos_type   pos_type;
+    typedef typename traits_type::off_type   off_type;
+    typedef typename traits_type::state_type state_type;
+
+    __stdinbuf(FILE* __fp, state_type* __st);
+
+protected:
+    virtual int_type underflow();
+    virtual int_type uflow();
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
+    virtual void imbue(const locale& __loc);
+
+private:
+
+    FILE* __file_;
+    const codecvt<char_type, char, state_type>* __cv_;
+    state_type* __st_;
+    int __encoding_;
+    int_type __last_consumed_;
+    bool __last_consumed_is_next_;
+    bool __always_noconv_;
+
+    __stdinbuf(const __stdinbuf&);
+    __stdinbuf& operator=(const __stdinbuf&);
+
+    int_type __getchar(bool __consume);
+};
+
+template <class _CharT>
+__stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st)
+    : __file_(__fp),
+      __st_(__st),
+      __last_consumed_(traits_type::eof()),
+      __last_consumed_is_next_(false)
+{
+    imbue(this->getloc());
+}
+
+template <class _CharT>
+void
+__stdinbuf<_CharT>::imbue(const locale& __loc)
+{
+    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+    __encoding_ = __cv_->encoding();
+    __always_noconv_ = __cv_->always_noconv();
+    if (__encoding_ > __limit)
+        __throw_runtime_error("unsupported locale for standard input");
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::underflow()
+{
+    return __getchar(false);
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::uflow()
+{
+    return __getchar(true);
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::__getchar(bool __consume)
+{
+    if (__last_consumed_is_next_)
+    {
+        int_type __result = __last_consumed_;
+        if (__consume)
+        {
+            __last_consumed_ = traits_type::eof();
+            __last_consumed_is_next_ = false;
+        }
+        return __result;
+    }
+    char __extbuf[__limit];
+    int __nread = _VSTD::max(1, __encoding_);
+    for (int __i = 0; __i < __nread; ++__i)
+    {
+        int __c = getc(__file_);
+        if (__c == EOF)
+            return traits_type::eof();
+        __extbuf[__i] = static_cast<char>(__c);
+    }
+    char_type __1buf;
+    if (__always_noconv_)
+        __1buf = static_cast<char_type>(__extbuf[0]);
+    else
+    {
+        const char* __enxt;
+        char_type* __inxt;
+        codecvt_base::result __r;
+        do
+        {
+            state_type __sv_st = *__st_;
+            __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt,
+                                   &__1buf, &__1buf + 1, __inxt);
+            switch (__r)
+            {
+            case _VSTD::codecvt_base::ok:
+                break;
+            case codecvt_base::partial:
+                *__st_ = __sv_st;
+                if (__nread == sizeof(__extbuf))
+                    return traits_type::eof();
+                {
+                    int __c = getc(__file_);
+                    if (__c == EOF)
+                        return traits_type::eof();
+                    __extbuf[__nread] = static_cast<char>(__c);
+                }
+                ++__nread;
+                break;
+            case codecvt_base::error:
+                return traits_type::eof();
+            case _VSTD::codecvt_base::noconv:
+                __1buf = static_cast<char_type>(__extbuf[0]);
+                break;
+            }
+        } while (__r == _VSTD::codecvt_base::partial);
+    }
+    if (!__consume)
+    {
+        for (int __i = __nread; __i > 0;)
+        {
+            if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
+                return traits_type::eof();
+        }
+    }
+    else
+        __last_consumed_ = traits_type::to_int_type(__1buf);
+    return traits_type::to_int_type(__1buf);
+}
+
+template <class _CharT>
+typename __stdinbuf<_CharT>::int_type
+__stdinbuf<_CharT>::pbackfail(int_type __c)
+{
+    if (traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        if (!__last_consumed_is_next_)
+        {
+            __c = __last_consumed_;
+            __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_,
+                                                                 traits_type::eof());
+        }
+        return __c;
+    }
+    if (__last_consumed_is_next_)
+    {
+        char __extbuf[__limit];
+        char* __enxt;
+        const char_type __ci = traits_type::to_char_type(__last_consumed_);
+        const char_type* __inxt;
+        switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt,
+                                  __extbuf, __extbuf + sizeof(__extbuf), __enxt))
+        {
+        case _VSTD::codecvt_base::ok:
+            break;
+        case _VSTD::codecvt_base::noconv:
+            __extbuf[0] = static_cast<char>(__last_consumed_);
+            __enxt = __extbuf + 1;
+            break;
+        case codecvt_base::partial:
+        case codecvt_base::error:
+            return traits_type::eof();
+        }
+        while (__enxt > __extbuf)
+            if (ungetc(*--__enxt, __file_) == EOF)
+                return traits_type::eof();
+    }
+    __last_consumed_ = __c;
+    __last_consumed_is_next_ = true;
+    return __c;
+}
+
+// __stdoutbuf
+
+template <class _CharT>
+class _LIBCPP_HIDDEN __stdoutbuf
+    : public basic_streambuf<_CharT, char_traits<_CharT> >
+{
+public:
+    typedef _CharT                           char_type;
+    typedef char_traits<char_type>           traits_type;
+    typedef typename traits_type::int_type   int_type;
+    typedef typename traits_type::pos_type   pos_type;
+    typedef typename traits_type::off_type   off_type;
+    typedef typename traits_type::state_type state_type;
+
+    __stdoutbuf(FILE* __fp, state_type* __st);
+
+protected:
+    virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual streamsize xsputn(const char_type* __s, streamsize __n);
+    virtual int sync();
+    virtual void imbue(const locale& __loc);
+
+private:
+    FILE* __file_;
+    const codecvt<char_type, char, state_type>* __cv_;
+    state_type* __st_;
+    bool __always_noconv_;
+
+    __stdoutbuf(const __stdoutbuf&);
+    __stdoutbuf& operator=(const __stdoutbuf&);
+};
+
+template <class _CharT>
+__stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st)
+    : __file_(__fp),
+      __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),
+      __st_(__st),
+      __always_noconv_(__cv_->always_noconv())
+{
+}
+
+template <class _CharT>
+typename __stdoutbuf<_CharT>::int_type
+__stdoutbuf<_CharT>::overflow(int_type __c)
+{
+    char __extbuf[__limit];
+    char_type __1buf;
+    if (!traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        __1buf = traits_type::to_char_type(__c);
+        if (__always_noconv_)
+        {
+            if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1)
+                return traits_type::eof();
+        }
+        else
+        {
+            char* __extbe = __extbuf;
+            codecvt_base::result __r;
+            char_type* pbase = &__1buf;
+            char_type* pptr = pbase + 1;
+            char_type* epptr = pptr;
+            do
+            {
+                const char_type* __e;
+                __r = __cv_->out(*__st_, pbase, pptr, __e,
+                                        __extbuf,
+                                        __extbuf + sizeof(__extbuf),
+                                        __extbe);
+                if (__e == pbase)
+                    return traits_type::eof();
+                if (__r == codecvt_base::noconv)
+                {
+                    if (fwrite(pbase, 1, 1, __file_) != 1)
+                        return traits_type::eof();
+                }
+                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+                {
+                    size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
+                    if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
+                        return traits_type::eof();
+                    if (__r == codecvt_base::partial)
+                    {
+                        pbase = (char_type*)__e;
+                    }
+                }
+                else
+                    return traits_type::eof();
+            } while (__r == codecvt_base::partial);
+        }
+    }
+    return traits_type::not_eof(__c);
+}
+
+template <class _CharT>
+streamsize
+__stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n)
+{
+    if (__always_noconv_)
+        return fwrite(__s, sizeof(char_type), __n, __file_);
+    streamsize __i = 0;
+    for (; __i < __n; ++__i, ++__s)
+        if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
+            break;
+    return __i;
+}
+
+template <class _CharT>
+int
+__stdoutbuf<_CharT>::sync()
+{
+    char __extbuf[__limit];
+    codecvt_base::result __r;
+    do
+    {
+        char* __extbe;
+        __r = __cv_->unshift(*__st_, __extbuf,
+                                    __extbuf + sizeof(__extbuf),
+                                    __extbe);
+        size_t __nmemb = static_cast<size_t>(__extbe - __extbuf);
+        if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb)
+            return -1;
+    } while (__r == codecvt_base::partial);
+    if (__r == codecvt_base::error)
+        return -1;
+    if (fflush(__file_))
+        return -1;
+    return 0;
+}
+
+template <class _CharT>
+void
+__stdoutbuf<_CharT>::imbue(const locale& __loc)
+{
+    sync();
+    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+    __always_noconv_ = __cv_->always_noconv();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___STD_STREAM
diff --git a/include/c++/v1/__tree b/include/c++/v1/__tree
new file mode 100644
index 0000000..8e5447a
--- /dev/null
+++ b/include/c++/v1/__tree
@@ -0,0 +1,2309 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TREE
+#define _LIBCPP___TREE
+
+#include <__config>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+#include <algorithm>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Compare, class _Allocator> class __tree;
+template <class _Tp, class _NodePtr, class _DiffType>
+    class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
+template <class _Tp, class _ConstNodePtr, class _DiffType>
+    class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+    class _LIBCPP_TYPE_VIS_ONLY map;
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+    class _LIBCPP_TYPE_VIS_ONLY multimap;
+template <class _Key, class _Compare, class _Allocator>
+    class _LIBCPP_TYPE_VIS_ONLY set;
+template <class _Key, class _Compare, class _Allocator>
+    class _LIBCPP_TYPE_VIS_ONLY multiset;
+
+/*
+
+_NodePtr algorithms
+
+The algorithms taking _NodePtr are red black tree algorithms.  Those
+algorithms taking a parameter named __root should assume that __root
+points to a proper red black tree (unless otherwise specified).
+
+Each algorithm herein assumes that __root->__parent_ points to a non-null
+structure which has a member __left_ which points back to __root.  No other
+member is read or written to at __root->__parent_.
+
+__root->__parent_ will be referred to below (in comments only) as end_node.
+end_node->__left_ is an externably accessible lvalue for __root, and can be
+changed by node insertion and removal (without explicit reference to end_node).
+
+All nodes (with the exception of end_node), even the node referred to as
+__root, have a non-null __parent_ field.
+
+*/
+
+// Returns:  true if __x is a left child of its parent, else false
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__tree_is_left_child(_NodePtr __x) _NOEXCEPT
+{
+    return __x == __x->__parent_->__left_;
+}
+
+// Determintes if the subtree rooted at __x is a proper red black subtree.  If
+//    __x is a proper subtree, returns the black height (null counts as 1).  If
+//    __x is an improper subtree, returns 0.
+template <class _NodePtr>
+unsigned
+__tree_sub_invariant(_NodePtr __x)
+{
+    if (__x == nullptr)
+        return 1;
+    // parent consistency checked by caller
+    // check __x->__left_ consistency
+    if (__x->__left_ != nullptr && __x->__left_->__parent_ != __x)
+        return 0;
+    // check __x->__right_ consistency
+    if (__x->__right_ != nullptr && __x->__right_->__parent_ != __x)
+        return 0;
+    // check __x->__left_ != __x->__right_ unless both are nullptr
+    if (__x->__left_ == __x->__right_ && __x->__left_ != nullptr)
+        return 0;
+    // If this is red, neither child can be red
+    if (!__x->__is_black_)
+    {
+        if (__x->__left_ && !__x->__left_->__is_black_)
+            return 0;
+        if (__x->__right_ && !__x->__right_->__is_black_)
+            return 0;
+    }
+    unsigned __h = __tree_sub_invariant(__x->__left_);
+    if (__h == 0)
+        return 0;  // invalid left subtree
+    if (__h != __tree_sub_invariant(__x->__right_))
+        return 0;  // invalid or different height right subtree
+    return __h + __x->__is_black_;  // return black height of this node
+}
+
+// Determintes if the red black tree rooted at __root is a proper red black tree.
+//    __root == nullptr is a proper tree.  Returns true is __root is a proper
+//    red black tree, else returns false.
+template <class _NodePtr>
+bool
+__tree_invariant(_NodePtr __root)
+{
+    if (__root == nullptr)
+        return true;
+    // check __x->__parent_ consistency
+    if (__root->__parent_ == nullptr)
+        return false;
+    if (!__tree_is_left_child(__root))
+        return false;
+    // root must be black
+    if (!__root->__is_black_)
+        return false;
+    // do normal node checks
+    return __tree_sub_invariant(__root) != 0;
+}
+
+// Returns:  pointer to the left-most node under __x.
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+inline _LIBCPP_INLINE_VISIBILITY
+_NodePtr
+__tree_min(_NodePtr __x) _NOEXCEPT
+{
+    while (__x->__left_ != nullptr)
+        __x = __x->__left_;
+    return __x;
+}
+
+// Returns:  pointer to the right-most node under __x.
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+inline _LIBCPP_INLINE_VISIBILITY
+_NodePtr
+__tree_max(_NodePtr __x) _NOEXCEPT
+{
+    while (__x->__right_ != nullptr)
+        __x = __x->__right_;
+    return __x;
+}
+
+// Returns:  pointer to the next in-order node after __x.
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+_NodePtr
+__tree_next(_NodePtr __x) _NOEXCEPT
+{
+    if (__x->__right_ != nullptr)
+        return __tree_min(__x->__right_);
+    while (!__tree_is_left_child(__x))
+        __x = __x->__parent_;
+    return __x->__parent_;
+}
+
+// Returns:  pointer to the previous in-order node before __x.
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+_NodePtr
+__tree_prev(_NodePtr __x) _NOEXCEPT
+{
+    if (__x->__left_ != nullptr)
+        return __tree_max(__x->__left_);
+    while (__tree_is_left_child(__x))
+        __x = __x->__parent_;
+    return __x->__parent_;
+}
+
+// Returns:  pointer to a node which has no children
+// Precondition:  __x != nullptr.
+template <class _NodePtr>
+_NodePtr
+__tree_leaf(_NodePtr __x) _NOEXCEPT
+{
+    while (true)
+    {
+        if (__x->__left_ != nullptr)
+        {
+            __x = __x->__left_;
+            continue;
+        }
+        if (__x->__right_ != nullptr)
+        {
+            __x = __x->__right_;
+            continue;
+        }
+        break;
+    }
+    return __x;
+}
+
+// Effects:  Makes __x->__right_ the subtree root with __x as its left child
+//           while preserving in-order order.
+// Precondition:  __x->__right_ != nullptr
+template <class _NodePtr>
+void
+__tree_left_rotate(_NodePtr __x) _NOEXCEPT
+{
+    _NodePtr __y = __x->__right_;
+    __x->__right_ = __y->__left_;
+    if (__x->__right_ != nullptr)
+        __x->__right_->__parent_ = __x;
+    __y->__parent_ = __x->__parent_;
+    if (__tree_is_left_child(__x))
+        __x->__parent_->__left_ = __y;
+    else
+        __x->__parent_->__right_ = __y;
+    __y->__left_ = __x;
+    __x->__parent_ = __y;
+}
+
+// Effects:  Makes __x->__left_ the subtree root with __x as its right child
+//           while preserving in-order order.
+// Precondition:  __x->__left_ != nullptr
+template <class _NodePtr>
+void
+__tree_right_rotate(_NodePtr __x) _NOEXCEPT
+{
+    _NodePtr __y = __x->__left_;
+    __x->__left_ = __y->__right_;
+    if (__x->__left_ != nullptr)
+        __x->__left_->__parent_ = __x;
+    __y->__parent_ = __x->__parent_;
+    if (__tree_is_left_child(__x))
+        __x->__parent_->__left_ = __y;
+    else
+        __x->__parent_->__right_ = __y;
+    __y->__right_ = __x;
+    __x->__parent_ = __y;
+}
+
+// Effects:  Rebalances __root after attaching __x to a leaf.
+// Precondition:  __root != nulptr && __x != nullptr.
+//                __x has no children.
+//                __x == __root or == a direct or indirect child of __root.
+//                If __x were to be unlinked from __root (setting __root to
+//                  nullptr if __root == __x), __tree_invariant(__root) == true.
+// Postcondition: __tree_invariant(end_node->__left_) == true.  end_node->__left_
+//                may be different than the value passed in as __root.
+template <class _NodePtr>
+void
+__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT
+{
+    __x->__is_black_ = __x == __root;
+    while (__x != __root && !__x->__parent_->__is_black_)
+    {
+        // __x->__parent_ != __root because __x->__parent_->__is_black == false
+        if (__tree_is_left_child(__x->__parent_))
+        {
+            _NodePtr __y = __x->__parent_->__parent_->__right_;
+            if (__y != nullptr && !__y->__is_black_)
+            {
+                __x = __x->__parent_;
+                __x->__is_black_ = true;
+                __x = __x->__parent_;
+                __x->__is_black_ = __x == __root;
+                __y->__is_black_ = true;
+            }
+            else
+            {
+                if (!__tree_is_left_child(__x))
+                {
+                    __x = __x->__parent_;
+                    __tree_left_rotate(__x);
+                }
+                __x = __x->__parent_;
+                __x->__is_black_ = true;
+                __x = __x->__parent_;
+                __x->__is_black_ = false;
+                __tree_right_rotate(__x);
+                break;
+            }
+        }
+        else
+        {
+            _NodePtr __y = __x->__parent_->__parent_->__left_;
+            if (__y != nullptr && !__y->__is_black_)
+            {
+                __x = __x->__parent_;
+                __x->__is_black_ = true;
+                __x = __x->__parent_;
+                __x->__is_black_ = __x == __root;
+                __y->__is_black_ = true;
+            }
+            else
+            {
+                if (__tree_is_left_child(__x))
+                {
+                    __x = __x->__parent_;
+                    __tree_right_rotate(__x);
+                }
+                __x = __x->__parent_;
+                __x->__is_black_ = true;
+                __x = __x->__parent_;
+                __x->__is_black_ = false;
+                __tree_left_rotate(__x);
+                break;
+            }
+        }
+    }
+}
+
+// Precondition:  __root != nullptr && __z != nullptr.
+//                __tree_invariant(__root) == true.
+//                __z == __root or == a direct or indirect child of __root.
+// Effects:  unlinks __z from the tree rooted at __root, rebalancing as needed.
+// Postcondition: __tree_invariant(end_node->__left_) == true && end_node->__left_
+//                nor any of its children refer to __z.  end_node->__left_
+//                may be different than the value passed in as __root.
+template <class _NodePtr>
+void
+__tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT
+{
+    // __z will be removed from the tree.  Client still needs to destruct/deallocate it
+    // __y is either __z, or if __z has two children, __tree_next(__z).
+    // __y will have at most one child.
+    // __y will be the initial hole in the tree (make the hole at a leaf)
+    _NodePtr __y = (__z->__left_ == nullptr || __z->__right_ == nullptr) ?
+                    __z : __tree_next(__z);
+    // __x is __y's possibly null single child
+    _NodePtr __x = __y->__left_ != nullptr ? __y->__left_ : __y->__right_;
+    // __w is __x's possibly null uncle (will become __x's sibling)
+    _NodePtr __w = nullptr;
+    // link __x to __y's parent, and find __w
+    if (__x != nullptr)
+        __x->__parent_ = __y->__parent_;
+    if (__tree_is_left_child(__y))
+    {
+        __y->__parent_->__left_ = __x;
+        if (__y != __root)
+            __w = __y->__parent_->__right_;
+        else
+            __root = __x;  // __w == nullptr
+    }
+    else
+    {
+        __y->__parent_->__right_ = __x;
+        // __y can't be root if it is a right child
+        __w = __y->__parent_->__left_;
+    }
+    bool __removed_black = __y->__is_black_;
+    // If we didn't remove __z, do so now by splicing in __y for __z,
+    //    but copy __z's color.  This does not impact __x or __w.
+    if (__y != __z)
+    {
+        // __z->__left_ != nulptr but __z->__right_ might == __x == nullptr
+        __y->__parent_ = __z->__parent_;
+        if (__tree_is_left_child(__z))
+            __y->__parent_->__left_ = __y;
+        else
+            __y->__parent_->__right_ = __y;
+        __y->__left_ = __z->__left_;
+        __y->__left_->__parent_ = __y;
+        __y->__right_ = __z->__right_;
+        if (__y->__right_ != nullptr)
+            __y->__right_->__parent_ = __y;
+        __y->__is_black_ = __z->__is_black_;
+        if (__root == __z)
+            __root = __y;
+    }
+    // There is no need to rebalance if we removed a red, or if we removed
+    //     the last node.
+    if (__removed_black && __root != nullptr)
+    {
+        // Rebalance:
+        // __x has an implicit black color (transferred from the removed __y)
+        //    associated with it, no matter what its color is.
+        // If __x is __root (in which case it can't be null), it is supposed
+        //    to be black anyway, and if it is doubly black, then the double
+        //    can just be ignored.
+        // If __x is red (in which case it can't be null), then it can absorb
+        //    the implicit black just by setting its color to black.
+        // Since __y was black and only had one child (which __x points to), __x
+        //   is either red with no children, else null, otherwise __y would have
+        //   different black heights under left and right pointers.
+        // if (__x == __root || __x != nullptr && !__x->__is_black_)
+        if (__x != nullptr)
+            __x->__is_black_ = true;
+        else
+        {
+            //  Else __x isn't root, and is "doubly black", even though it may
+            //     be null.  __w can not be null here, else the parent would
+            //     see a black height >= 2 on the __x side and a black height
+            //     of 1 on the __w side (__w must be a non-null black or a red
+            //     with a non-null black child).
+            while (true)
+            {
+                if (!__tree_is_left_child(__w))  // if x is left child
+                {
+                    if (!__w->__is_black_)
+                    {
+                        __w->__is_black_ = true;
+                        __w->__parent_->__is_black_ = false;
+                        __tree_left_rotate(__w->__parent_);
+                        // __x is still valid
+                        // reset __root only if necessary
+                        if (__root == __w->__left_)
+                            __root = __w;
+                        // reset sibling, and it still can't be null
+                        __w = __w->__left_->__right_;
+                    }
+                    // __w->__is_black_ is now true, __w may have null children
+                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
+                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
+                    {
+                        __w->__is_black_ = false;
+                        __x = __w->__parent_;
+                        // __x can no longer be null
+                        if (__x == __root || !__x->__is_black_)
+                        {
+                            __x->__is_black_ = true;
+                            break;
+                        }
+                        // reset sibling, and it still can't be null
+                        __w = __tree_is_left_child(__x) ?
+                                    __x->__parent_->__right_ :
+                                    __x->__parent_->__left_;
+                        // continue;
+                    }
+                    else  // __w has a red child
+                    {
+                        if (__w->__right_ == nullptr || __w->__right_->__is_black_)
+                        {
+                            // __w left child is non-null and red
+                            __w->__left_->__is_black_ = true;
+                            __w->__is_black_ = false;
+                            __tree_right_rotate(__w);
+                            // __w is known not to be root, so root hasn't changed
+                            // reset sibling, and it still can't be null
+                            __w = __w->__parent_;
+                        }
+                        // __w has a right red child, left child may be null
+                        __w->__is_black_ = __w->__parent_->__is_black_;
+                        __w->__parent_->__is_black_ = true;
+                        __w->__right_->__is_black_ = true;
+                        __tree_left_rotate(__w->__parent_);
+                        break;
+                    }
+                }
+                else
+                {
+                    if (!__w->__is_black_)
+                    {
+                        __w->__is_black_ = true;
+                        __w->__parent_->__is_black_ = false;
+                        __tree_right_rotate(__w->__parent_);
+                        // __x is still valid
+                        // reset __root only if necessary
+                        if (__root == __w->__right_)
+                            __root = __w;
+                        // reset sibling, and it still can't be null
+                        __w = __w->__right_->__left_;
+                    }
+                    // __w->__is_black_ is now true, __w may have null children
+                    if ((__w->__left_  == nullptr || __w->__left_->__is_black_) &&
+                        (__w->__right_ == nullptr || __w->__right_->__is_black_))
+                    {
+                        __w->__is_black_ = false;
+                        __x = __w->__parent_;
+                        // __x can no longer be null
+                        if (!__x->__is_black_ || __x == __root)
+                        {
+                            __x->__is_black_ = true;
+                            break;
+                        }
+                        // reset sibling, and it still can't be null
+                        __w = __tree_is_left_child(__x) ?
+                                    __x->__parent_->__right_ :
+                                    __x->__parent_->__left_;
+                        // continue;
+                    }
+                    else  // __w has a red child
+                    {
+                        if (__w->__left_ == nullptr || __w->__left_->__is_black_)
+                        {
+                            // __w right child is non-null and red
+                            __w->__right_->__is_black_ = true;
+                            __w->__is_black_ = false;
+                            __tree_left_rotate(__w);
+                            // __w is known not to be root, so root hasn't changed
+                            // reset sibling, and it still can't be null
+                            __w = __w->__parent_;
+                        }
+                        // __w has a left red child, right child may be null
+                        __w->__is_black_ = __w->__parent_->__is_black_;
+                        __w->__parent_->__is_black_ = true;
+                        __w->__left_->__is_black_ = true;
+                        __tree_right_rotate(__w->__parent_);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+}
+
+template <class _Allocator> class __map_node_destructor;
+
+template <class _Allocator>
+class __tree_node_destructor
+{
+    typedef _Allocator                                      allocator_type;
+    typedef allocator_traits<allocator_type>                __alloc_traits;
+    typedef typename __alloc_traits::value_type::value_type value_type;
+public:
+    typedef typename __alloc_traits::pointer                pointer;
+private:
+
+    allocator_type& __na_;
+
+    __tree_node_destructor& operator=(const __tree_node_destructor&);
+
+public:
+    bool __value_constructed;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_node_destructor(allocator_type& __na) _NOEXCEPT
+        : __na_(__na),
+          __value_constructed(false)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+    {
+        if (__value_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_));
+        if (__p)
+            __alloc_traits::deallocate(__na_, __p, 1);
+    }
+
+    template <class> friend class __map_node_destructor;
+};
+
+// node
+
+template <class _Pointer>
+class __tree_end_node
+{
+public:
+    typedef _Pointer pointer;
+    pointer __left_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_end_node() _NOEXCEPT : __left_() {}
+};
+
+template <class _VoidPtr>
+class __tree_node_base
+    : public __tree_end_node
+             <
+                typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                     rebind<__tree_node_base<_VoidPtr> >
+#else
+                     rebind<__tree_node_base<_VoidPtr> >::other
+#endif
+             >
+{
+    __tree_node_base(const __tree_node_base&);
+    __tree_node_base& operator=(const __tree_node_base&);
+public:
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__tree_node_base>
+#else
+            rebind<__tree_node_base>::other
+#endif
+                                                pointer;
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const __tree_node_base>
+#else
+            rebind<const __tree_node_base>::other
+#endif
+                                                const_pointer;
+    typedef __tree_end_node<pointer> base;
+
+    pointer __right_;
+    pointer __parent_;
+    bool __is_black_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_node_base() _NOEXCEPT
+        : __right_(), __parent_(), __is_black_(false) {}
+};
+
+template <class _Tp, class _VoidPtr>
+class __tree_node
+    : public __tree_node_base<_VoidPtr>
+{
+public:
+    typedef __tree_node_base<_VoidPtr> base;
+    typedef _Tp value_type;
+
+    value_type __value_;
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tree_node(_Args&& ...__args)
+            : __value_(_VSTD::forward<_Args>(__args)...) {}
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_node(const value_type& __v)
+            : __value_(__v) {}
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+};
+
+template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+
+template <class _Tp, class _NodePtr, class _DiffType>
+class _LIBCPP_TYPE_VIS_ONLY __tree_iterator
+{
+    typedef _NodePtr                                              __node_pointer;
+    typedef typename pointer_traits<__node_pointer>::element_type __node;
+    typedef typename __node::base                                 __node_base;
+    typedef typename __node_base::pointer                         __node_base_pointer;
+
+    __node_pointer __ptr_;
+
+    typedef pointer_traits<__node_pointer> __pointer_traits;
+public:
+    typedef bidirectional_iterator_tag iterator_category;
+    typedef _Tp                        value_type;
+    typedef _DiffType                  difference_type;
+    typedef value_type&                reference;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                       pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __ptr_(nullptr)
+#endif
+    {}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
+        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_iterator& operator++()
+        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
+         return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_iterator operator++(int)
+        {__tree_iterator __t(*this); ++(*this); return __t;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_iterator& operator--()
+        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
+         return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_iterator operator--(int)
+        {__tree_iterator __t(*this); --(*this); return __t;}
+
+    friend _LIBCPP_INLINE_VISIBILITY 
+        bool operator==(const __tree_iterator& __x, const __tree_iterator& __y)
+        {return __x.__ptr_ == __y.__ptr_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+    template <class, class, class> friend class __tree;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
+};
+
+template <class _Tp, class _ConstNodePtr, class _DiffType>
+class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator
+{
+    typedef _ConstNodePtr                                         __node_pointer;
+    typedef typename pointer_traits<__node_pointer>::element_type __node;
+    typedef typename __node::base                                 __node_base;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__node_base>
+#else
+            rebind<__node_base>::other
+#endif
+                                                                  __node_base_pointer;
+
+    __node_pointer __ptr_;
+
+    typedef pointer_traits<__node_pointer> __pointer_traits;
+public:
+    typedef bidirectional_iterator_tag       iterator_category;
+    typedef _Tp                              value_type;
+    typedef _DiffType                        difference_type;
+    typedef const value_type&                reference;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                       pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+    : __ptr_(nullptr)
+#endif
+    {}
+
+private:
+    typedef typename remove_const<__node>::type  __non_const_node;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__non_const_node>
+#else
+            rebind<__non_const_node>::other
+#endif
+                                                 __non_const_node_pointer;
+    typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type>
+                                                 __non_const_iterator;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
+        : __ptr_(__p.__ptr_) {}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const
+        {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_const_iterator& operator++()
+        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
+         return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_const_iterator operator++(int)
+        {__tree_const_iterator __t(*this); ++(*this); return __t;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_const_iterator& operator--()
+        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
+         return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __tree_const_iterator operator--(int)
+        {__tree_const_iterator __t(*this); --(*this); return __t;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
+        {return __x.__ptr_ == __y.__ptr_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y)
+        {return !(__x == __y);}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
+        : __ptr_(__p) {}
+    template <class, class, class> friend class __tree;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+};
+
+template <class _Tp, class _Compare, class _Allocator>
+class __tree
+{
+public:
+    typedef _Tp                                      value_type;
+    typedef _Compare                                 value_compare;
+    typedef _Allocator                               allocator_type;
+    typedef allocator_traits<allocator_type>         __alloc_traits;
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+
+    typedef typename __alloc_traits::void_pointer  __void_pointer;
+
+    typedef __tree_node<value_type, __void_pointer> __node;
+    typedef __tree_node_base<__void_pointer>        __node_base;
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__node>
+#else
+            rebind_alloc<__node>::other
+#endif
+                                                     __node_allocator;
+    typedef allocator_traits<__node_allocator>       __node_traits;
+    typedef typename __node_traits::pointer          __node_pointer;
+    typedef typename __node_traits::pointer          __node_const_pointer;
+    typedef typename __node_base::pointer            __node_base_pointer;
+    typedef typename __node_base::pointer            __node_base_const_pointer;
+private:
+    typedef typename __node_base::base __end_node_t;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__end_node_t>
+#else
+            rebind<__end_node_t>::other
+#endif
+                                                     __end_node_ptr;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__end_node_t>
+#else
+            rebind<__end_node_t>::other
+#endif
+                                                     __end_node_const_ptr;
+
+    __node_pointer                                          __begin_node_;
+    __compressed_pair<__end_node_t, __node_allocator>  __pair1_;
+    __compressed_pair<size_type, value_compare>        __pair3_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __end_node() _NOEXCEPT
+    {
+        return static_cast<__node_pointer>
+               (
+                   pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first())
+               );
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __node_const_pointer __end_node() const _NOEXCEPT
+    {
+        return static_cast<__node_const_pointer>
+               (
+                   pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first()))
+               );
+    }
+    _LIBCPP_INLINE_VISIBILITY
+          __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    const __node_allocator& __node_alloc() const _NOEXCEPT
+        {return __pair1_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+          __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type __alloc() const _NOEXCEPT
+        {return allocator_type(__node_alloc());}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+          size_type& size() _NOEXCEPT {return __pair3_.first();}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    const size_type& size() const _NOEXCEPT {return __pair3_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+          value_compare& value_comp() _NOEXCEPT {return __pair3_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const value_compare& value_comp() const _NOEXCEPT
+        {return __pair3_.second();}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer __root() _NOEXCEPT
+        {return static_cast<__node_pointer>      (__end_node()->__left_);}
+    _LIBCPP_INLINE_VISIBILITY
+    __node_const_pointer __root() const _NOEXCEPT
+        {return static_cast<__node_const_pointer>(__end_node()->__left_);}
+
+    typedef __tree_iterator<value_type, __node_pointer, difference_type>             iterator;
+    typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator;
+
+    explicit __tree(const value_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<__node_allocator>::value &&
+            is_nothrow_copy_constructible<value_compare>::value);
+    explicit __tree(const allocator_type& __a);
+    __tree(const value_compare& __comp, const allocator_type& __a);
+    __tree(const __tree& __t);
+    __tree& operator=(const __tree& __t);
+    template <class _InputIterator>
+        void __assign_unique(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        void __assign_multi(_InputIterator __first, _InputIterator __last);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __tree(__tree&& __t)
+        _NOEXCEPT_(
+            is_nothrow_move_constructible<__node_allocator>::value &&
+            is_nothrow_move_constructible<value_compare>::value);
+    __tree(__tree&& __t, const allocator_type& __a);
+    __tree& operator=(__tree&& __t)
+        _NOEXCEPT_(
+            __node_traits::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<value_compare>::value &&
+            is_nothrow_move_assignable<__node_allocator>::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    ~__tree();
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin()  _NOEXCEPT {return       iterator(__begin_node());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return const_iterator(__begin_node());}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT {return       iterator(__end_node());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT {return const_iterator(__end_node());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT
+        {return __node_traits::max_size(__node_alloc());}
+
+    void clear() _NOEXCEPT;
+
+    void swap(__tree& __t)
+        _NOEXCEPT_(
+            __is_nothrow_swappable<value_compare>::value &&
+            (!__node_traits::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<__node_allocator>::value));
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        pair<iterator, bool>
+        __emplace_unique(_Args&&... __args);
+    template <class... _Args>
+        iterator
+        __emplace_multi(_Args&&... __args);
+
+    template <class... _Args>
+        iterator
+        __emplace_hint_unique(const_iterator __p, _Args&&... __args);
+    template <class... _Args>
+        iterator
+        __emplace_hint_multi(const_iterator __p, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    template <class _Vp>
+        pair<iterator, bool> __insert_unique(_Vp&& __v);
+    template <class _Vp>
+        iterator __insert_unique(const_iterator __p, _Vp&& __v);
+    template <class _Vp>
+        iterator __insert_multi(_Vp&& __v);
+    template <class _Vp>
+        iterator __insert_multi(const_iterator __p, _Vp&& __v);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    pair<iterator, bool> __insert_unique(const value_type& __v);
+    iterator __insert_unique(const_iterator __p, const value_type& __v);
+    iterator __insert_multi(const value_type& __v);
+    iterator __insert_multi(const_iterator __p, const value_type& __v);
+
+    pair<iterator, bool> __node_insert_unique(__node_pointer __nd);
+    iterator             __node_insert_unique(const_iterator __p,
+                                              __node_pointer __nd);
+
+    iterator __node_insert_multi(__node_pointer __nd);
+    iterator __node_insert_multi(const_iterator __p, __node_pointer __nd);
+
+    iterator erase(const_iterator __p);
+    iterator erase(const_iterator __f, const_iterator __l);
+    template <class _Key>
+        size_type __erase_unique(const _Key& __k);
+    template <class _Key>
+        size_type __erase_multi(const _Key& __k);
+
+    void __insert_node_at(__node_base_pointer __parent,
+                          __node_base_pointer& __child,
+                          __node_base_pointer __new_node);
+
+    template <class _Key>
+        iterator find(const _Key& __v);
+    template <class _Key>
+        const_iterator find(const _Key& __v) const;
+
+    template <class _Key>
+        size_type __count_unique(const _Key& __k) const;
+    template <class _Key>
+        size_type __count_multi(const _Key& __k) const;
+
+    template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator lower_bound(const _Key& __v)
+            {return __lower_bound(__v, __root(), __end_node());}
+    template <class _Key>
+        iterator __lower_bound(const _Key& __v,
+                               __node_pointer __root,
+                               __node_pointer __result);
+    template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
+        const_iterator lower_bound(const _Key& __v) const
+            {return __lower_bound(__v, __root(), __end_node());}
+    template <class _Key>
+        const_iterator __lower_bound(const _Key& __v,
+                                     __node_const_pointer __root,
+                                     __node_const_pointer __result) const;
+    template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator upper_bound(const _Key& __v)
+            {return __upper_bound(__v, __root(), __end_node());}
+    template <class _Key>
+        iterator __upper_bound(const _Key& __v,
+                               __node_pointer __root,
+                               __node_pointer __result);
+    template <class _Key>
+        _LIBCPP_INLINE_VISIBILITY
+        const_iterator upper_bound(const _Key& __v) const
+            {return __upper_bound(__v, __root(), __end_node());}
+    template <class _Key>
+        const_iterator __upper_bound(const _Key& __v,
+                                     __node_const_pointer __root,
+                                     __node_const_pointer __result) const;
+    template <class _Key>
+        pair<iterator, iterator>
+        __equal_range_unique(const _Key& __k);
+    template <class _Key>
+        pair<const_iterator, const_iterator>
+        __equal_range_unique(const _Key& __k) const;
+
+    template <class _Key>
+        pair<iterator, iterator>
+        __equal_range_multi(const _Key& __k);
+    template <class _Key>
+        pair<const_iterator, const_iterator>
+        __equal_range_multi(const _Key& __k) const;
+
+    typedef __tree_node_destructor<__node_allocator> _Dp;
+    typedef unique_ptr<__node, _Dp> __node_holder;
+
+    __node_holder remove(const_iterator __p) _NOEXCEPT;
+private:
+    typename __node_base::pointer&
+        __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v);
+    typename __node_base::pointer&
+        __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v);
+    typename __node_base::pointer&
+        __find_leaf(const_iterator __hint,
+                    typename __node_base::pointer& __parent, const value_type& __v);
+    template <class _Key>
+        typename __node_base::pointer&
+        __find_equal(typename __node_base::pointer& __parent, const _Key& __v);
+    template <class _Key>
+        typename __node_base::pointer&
+        __find_equal(const_iterator __hint, typename __node_base::pointer& __parent,
+                     const _Key& __v);
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class ..._Args>
+        __node_holder __construct_node(_Args&& ...__args);
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+        __node_holder __construct_node(const value_type& __v);
+#endif
+
+    void destroy(__node_pointer __nd) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __tree& __t)
+        {__copy_assign_alloc(__t, integral_constant<bool,
+             __node_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __tree& __t, true_type)
+        {__node_alloc() = __t.__node_alloc();}
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __tree& __t, false_type) {}
+
+    void __move_assign(__tree& __t, false_type);
+    void __move_assign(__tree& __t, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
+                   is_nothrow_move_assignable<__node_allocator>::value);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__tree& __t)
+        _NOEXCEPT_(
+            !__node_traits::propagate_on_container_move_assignment::value ||
+            is_nothrow_move_assignable<__node_allocator>::value)
+        {__move_assign_alloc(__t, integral_constant<bool,
+             __node_traits::propagate_on_container_move_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__tree& __t, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
+        {__node_alloc() = _VSTD::move(__t.__node_alloc());}
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
+        _NOEXCEPT_(
+            !__node_traits::propagate_on_container_swap::value ||
+            __is_nothrow_swappable<__node_allocator>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __node_traits::propagate_on_container_swap::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
+        _NOEXCEPT
+        {}
+
+    __node_pointer __detach();
+    static __node_pointer __detach(__node_pointer);
+
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+};
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<__node_allocator>::value &&
+            is_nothrow_copy_constructible<value_compare>::value)
+    : __pair3_(0, __comp)
+{
+    __begin_node() = __end_node();
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
+    : __pair1_(__node_allocator(__a)),
+      __begin_node_(__node_pointer()),
+      __pair3_(0)
+{
+    __begin_node() = __end_node();
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
+                                           const allocator_type& __a)
+    : __pair1_(__node_allocator(__a)),
+      __begin_node_(__node_pointer()),
+      __pair3_(0, __comp)
+{
+    __begin_node() = __end_node();
+}
+
+// Precondition:  size() != 0
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
+__tree<_Tp, _Compare, _Allocator>::__detach()
+{
+    __node_pointer __cache = __begin_node();
+    __begin_node() = __end_node();
+    __end_node()->__left_->__parent_ = nullptr;
+    __end_node()->__left_ = nullptr;
+    size() = 0;
+    // __cache->__left_ == nullptr
+    if (__cache->__right_ != nullptr)
+        __cache = static_cast<__node_pointer>(__cache->__right_);
+    // __cache->__left_ == nullptr
+    // __cache->__right_ == nullptr
+    return __cache;
+}
+
+// Precondition:  __cache != nullptr
+//    __cache->left_ == nullptr
+//    __cache->right_ == nullptr
+//    This is no longer a red-black tree
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_pointer
+__tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache)
+{
+    if (__cache->__parent_ == nullptr)
+        return nullptr;
+    if (__tree_is_left_child(static_cast<__node_base_pointer>(__cache)))
+    {
+        __cache->__parent_->__left_ = nullptr;
+        __cache = static_cast<__node_pointer>(__cache->__parent_);
+        if (__cache->__right_ == nullptr)
+            return __cache;
+        return static_cast<__node_pointer>(__tree_leaf(__cache->__right_));
+    }
+    // __cache is right child
+    __cache->__parent_->__right_ = nullptr;
+    __cache = static_cast<__node_pointer>(__cache->__parent_);
+    if (__cache->__left_ == nullptr)
+        return __cache;
+    return static_cast<__node_pointer>(__tree_leaf(__cache->__left_));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>&
+__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t)
+{
+    if (this != &__t)
+    {
+        value_comp() = __t.value_comp();
+        __copy_assign_alloc(__t);
+        __assign_multi(__t.begin(), __t.end());
+    }
+    return *this;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _InputIterator>
+void
+__tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last)
+{
+    if (size() != 0)
+    {
+        __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __cache != nullptr && __first != __last; ++__first)
+            {
+                __cache->__value_ = *__first;
+                __node_pointer __next = __detach(__cache);
+                __node_insert_unique(__cache);
+                __cache = __next;
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (__cache->__parent_ != nullptr)
+                __cache = static_cast<__node_pointer>(__cache->__parent_);
+            destroy(__cache);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        if (__cache != nullptr)
+        {
+            while (__cache->__parent_ != nullptr)
+                __cache = static_cast<__node_pointer>(__cache->__parent_);
+            destroy(__cache);
+        }
+    }
+    for (; __first != __last; ++__first)
+        __insert_unique(*__first);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _InputIterator>
+void
+__tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last)
+{
+    if (size() != 0)
+    {
+        __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __cache != nullptr && __first != __last; ++__first)
+            {
+                __cache->__value_ = *__first;
+                __node_pointer __next = __detach(__cache);
+                __node_insert_multi(__cache);
+                __cache = __next;
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (__cache->__parent_ != nullptr)
+                __cache = static_cast<__node_pointer>(__cache->__parent_);
+            destroy(__cache);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        if (__cache != nullptr)
+        {
+            while (__cache->__parent_ != nullptr)
+                __cache = static_cast<__node_pointer>(__cache->__parent_);
+            destroy(__cache);
+        }
+    }
+    for (; __first != __last; ++__first)
+        __insert_multi(*__first);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
+    : __begin_node_(__node_pointer()),
+      __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
+      __pair3_(0, __t.value_comp())
+{
+    __begin_node() = __end_node();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t)
+    _NOEXCEPT_(
+        is_nothrow_move_constructible<__node_allocator>::value &&
+        is_nothrow_move_constructible<value_compare>::value)
+    : __begin_node_(_VSTD::move(__t.__begin_node_)),
+      __pair1_(_VSTD::move(__t.__pair1_)),
+      __pair3_(_VSTD::move(__t.__pair3_))
+{
+    if (size() == 0)
+        __begin_node() = __end_node();
+    else
+    {
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+        __t.__begin_node() = __t.__end_node();
+        __t.__end_node()->__left_ = nullptr;
+        __t.size() = 0;
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
+    : __pair1_(__node_allocator(__a)),
+      __pair3_(0, _VSTD::move(__t.value_comp()))
+{
+    if (__a == __t.__alloc())
+    {
+        if (__t.size() == 0)
+            __begin_node() = __end_node();
+        else
+        {
+            __begin_node() = __t.__begin_node();
+            __end_node()->__left_ = __t.__end_node()->__left_;
+            __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+            size() = __t.size();
+            __t.__begin_node() = __t.__end_node();
+            __t.__end_node()->__left_ = nullptr;
+            __t.size() = 0;
+        }
+    }
+    else
+    {
+        __begin_node() = __end_node();
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
+               is_nothrow_move_assignable<__node_allocator>::value)
+{
+    destroy(static_cast<__node_pointer>(__end_node()->__left_));
+    __begin_node_ = __t.__begin_node_;
+    __pair1_.first() = __t.__pair1_.first();
+    __move_assign_alloc(__t);
+    __pair3_ = _VSTD::move(__t.__pair3_);
+    if (size() == 0)
+        __begin_node() = __end_node();
+    else
+    {
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+        __t.__begin_node() = __t.__end_node();
+        __t.__end_node()->__left_ = nullptr;
+        __t.size() = 0;
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type)
+{
+    if (__node_alloc() == __t.__node_alloc())
+        __move_assign(__t, true_type());
+    else
+    {
+        value_comp() = _VSTD::move(__t.value_comp());
+        const_iterator __e = end();
+        if (size() != 0)
+        {
+            __node_pointer __cache = __detach();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            try
+            {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                while (__cache != nullptr && __t.size() != 0)
+                {
+                    __cache->__value_ = _VSTD::move(__t.remove(__t.begin())->__value_);
+                    __node_pointer __next = __detach(__cache);
+                    __node_insert_multi(__cache);
+                    __cache = __next;
+                }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            }
+            catch (...)
+            {
+                while (__cache->__parent_ != nullptr)
+                    __cache = static_cast<__node_pointer>(__cache->__parent_);
+                destroy(__cache);
+                throw;
+            }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            if (__cache != nullptr)
+            {
+                while (__cache->__parent_ != nullptr)
+                    __cache = static_cast<__node_pointer>(__cache->__parent_);
+                destroy(__cache);
+            }
+        }
+        while (__t.size() != 0)
+            __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_));
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>&
+__tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t)
+    _NOEXCEPT_(
+        __node_traits::propagate_on_container_move_assignment::value &&
+        is_nothrow_move_assignable<value_compare>::value &&
+        is_nothrow_move_assignable<__node_allocator>::value)
+        
+{
+    __move_assign(__t, integral_constant<bool,
+                  __node_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Compare, class _Allocator>
+__tree<_Tp, _Compare, _Allocator>::~__tree()
+{
+    destroy(__root());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT
+{
+    if (__nd != nullptr)
+    {
+        destroy(static_cast<__node_pointer>(__nd->__left_));
+        destroy(static_cast<__node_pointer>(__nd->__right_));
+        __node_allocator& __na = __node_alloc();
+        __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_));
+        __node_traits::deallocate(__na, __nd, 1);
+    }
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
+    _NOEXCEPT_(
+        __is_nothrow_swappable<value_compare>::value &&
+        (!__node_traits::propagate_on_container_swap::value ||
+         __is_nothrow_swappable<__node_allocator>::value))
+{
+    using _VSTD::swap;
+    swap(__begin_node_, __t.__begin_node_);
+    swap(__pair1_.first(), __t.__pair1_.first());
+    __swap_alloc(__node_alloc(), __t.__node_alloc());
+    __pair3_.swap(__t.__pair3_);
+    if (size() == 0)
+        __begin_node() = __end_node();
+    else
+        __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node());
+    if (__t.size() == 0)
+        __t.__begin_node() = __t.__end_node();
+    else
+        __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT
+{
+    destroy(__root());
+    size() = 0;
+    __begin_node() = __end_node();
+    __end_node()->__left_ = nullptr;
+}
+
+// Find lower_bound place to insert
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent,
+                                                   const value_type& __v)
+{
+    __node_pointer __nd = __root();
+    if (__nd != nullptr)
+    {
+        while (true)
+        {
+            if (value_comp()(__nd->__value_, __v))
+            {
+                if (__nd->__right_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__right_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__right_;
+                }
+            }
+            else
+            {
+                if (__nd->__left_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__left_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__left_;
+                }
+            }
+        }
+    }
+    __parent = static_cast<__node_base_pointer>(__end_node());
+    return __parent->__left_;
+}
+
+// Find upper_bound place to insert
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent,
+                                                    const value_type& __v)
+{
+    __node_pointer __nd = __root();
+    if (__nd != nullptr)
+    {
+        while (true)
+        {
+            if (value_comp()(__v, __nd->__value_))
+            {
+                if (__nd->__left_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__left_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__left_;
+                }
+            }
+            else
+            {
+                if (__nd->__right_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__right_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__right_;
+                }
+            }
+        }
+    }
+    __parent = static_cast<__node_base_pointer>(__end_node());
+    return __parent->__left_;
+}
+
+// Find leaf place to insert closest to __hint
+// First check prior to __hint.
+// Next check after __hint.
+// Next do O(log N) search.
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint,
+                                               typename __node_base::pointer& __parent,
+                                               const value_type& __v)
+{
+    if (__hint == end() || !value_comp()(*__hint, __v))  // check before
+    {
+        // __v <= *__hint
+        const_iterator __prior = __hint;
+        if (__prior == begin() || !value_comp()(__v, *--__prior))
+        {
+            // *prev(__hint) <= __v <= *__hint
+            if (__hint.__ptr_->__left_ == nullptr)
+            {
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+                return __parent->__left_;
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
+                return __parent->__right_;
+            }
+        }
+        // __v < *prev(__hint)
+        return __find_leaf_high(__parent, __v);
+    }
+    // else __v > *__hint
+    return __find_leaf_low(__parent, __v);
+}
+
+// Find place to insert if __v doesn't exist
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+// If __v exists, set parent to node of __v and return reference to node of __v
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent,
+                                                const _Key& __v)
+{
+    __node_pointer __nd = __root();
+    if (__nd != nullptr)
+    {
+        while (true)
+        {
+            if (value_comp()(__v, __nd->__value_))
+            {
+                if (__nd->__left_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__left_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__left_;
+                }
+            }
+            else if (value_comp()(__nd->__value_, __v))
+            {
+                if (__nd->__right_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__right_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__right_;
+                }
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__nd);
+                return __parent;
+            }
+        }
+    }
+    __parent = static_cast<__node_base_pointer>(__end_node());
+    return __parent->__left_;
+}
+
+// Find place to insert if __v doesn't exist
+// First check prior to __hint.
+// Next check after __hint.
+// Next do O(log N) search.
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+// If __v exists, set parent to node of __v and return reference to node of __v
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint,
+                                                typename __node_base::pointer& __parent,
+                                                const _Key& __v)
+{
+    if (__hint == end() || value_comp()(__v, *__hint))  // check before
+    {
+        // __v < *__hint
+        const_iterator __prior = __hint;
+        if (__prior == begin() || value_comp()(*--__prior, __v))
+        {
+            // *prev(__hint) < __v < *__hint
+            if (__hint.__ptr_->__left_ == nullptr)
+            {
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+                return __parent->__left_;
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__prior.__ptr_);
+                return __parent->__right_;
+            }
+        }
+        // __v <= *prev(__hint)
+        return __find_equal(__parent, __v);
+    }
+    else if (value_comp()(*__hint, __v))  // check after
+    {
+        // *__hint < __v
+        const_iterator __next = _VSTD::next(__hint);
+        if (__next == end() || value_comp()(__v, *__next))
+        {
+            // *__hint < __v < *_VSTD::next(__hint)
+            if (__hint.__ptr_->__right_ == nullptr)
+            {
+                __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+                return __parent->__right_;
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__next.__ptr_);
+                return __parent->__left_;
+            }
+        }
+        // *next(__hint) <= __v
+        return __find_equal(__parent, __v);
+    }
+    // else __v == *__hint
+    __parent = static_cast<__node_base_pointer>(__hint.__ptr_);
+    return __parent;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+void
+__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent,
+                                                    __node_base_pointer& __child,
+                                                    __node_base_pointer __new_node)
+{
+    __new_node->__left_   = nullptr;
+    __new_node->__right_  = nullptr;
+    __new_node->__parent_ = __parent;
+    __child = __new_node;
+    if (__begin_node()->__left_ != nullptr)
+        __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_);
+    __tree_balance_after_insert(__end_node()->__left_, __child);
+    ++size();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class ..._Args>
+typename __tree<_Tp, _Compare, _Allocator>::__node_holder
+__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__value_constructed = true;
+    return __h;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class... _Args>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
+__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    bool __inserted = false;
+    if (__child == nullptr)
+    {
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+        __inserted = true;
+    }
+    return pair<iterator, bool>(iterator(__r), __inserted);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class... _Args>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class... _Args>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(static_cast<__node_pointer>(__h.release()));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class... _Args>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p,
+                                                        _Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(static_cast<__node_pointer>(__h.release()));
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Vp>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
+__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
+    pair<iterator, bool> __r = __node_insert_unique(__h.get());
+    if (__r.second)
+        __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Vp>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
+    iterator __r = __node_insert_unique(__p, __h.get());
+    if (__r.__ptr_ == __h.get())
+        __h.release();
+    return __r;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Vp>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(__h.release());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Vp>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v));
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(__h.release());
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_holder
+__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v)
+{
+    __node_allocator& __na = __node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v);
+    __h.get_deleter().__value_constructed = true;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Compare, class _Allocator>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
+__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent, __v);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    bool __inserted = false;
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node(__v);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+        __inserted = true;
+    }
+    return pair<iterator, bool>(iterator(__r), __inserted);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __v);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node(__v);
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, __v);
+    __node_holder __h = __construct_node(__v);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(__h.release());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, __v);
+    __node_holder __h = __construct_node(__v);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+    return iterator(__h.release());
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
+__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    bool __inserted = false;
+    if (__child == nullptr)
+    {
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+        __r = __nd;
+        __inserted = true;
+    }
+    return pair<iterator, bool>(iterator(__r), __inserted);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p,
+                                                        __node_pointer __nd)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+        __r = __nd;
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+    return iterator(__nd);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p,
+                                                       __node_pointer __nd)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
+    __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
+    return iterator(__nd);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p)
+{
+    __node_pointer __np = __p.__ptr_;
+    iterator __r(__np);
+    ++__r;
+    if (__begin_node() == __np)
+        __begin_node() = __r.__ptr_;
+    --size();
+    __node_allocator& __na = __node_alloc();
+    __tree_remove(__end_node()->__left_,
+                  static_cast<__node_base_pointer>(__np));
+    __node_traits::destroy(__na, const_cast<value_type*>(_VSTD::addressof(*__p)));
+    __node_traits::deallocate(__na, __np, 1);
+    return __r;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
+{
+    while (__f != __l)
+        __f = erase(__f);
+    return iterator(__l.__ptr_);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::size_type
+__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k)
+{
+    iterator __i = find(__k);
+    if (__i == end())
+        return 0;
+    erase(__i);
+    return 1;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::size_type
+__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k)
+{
+    pair<iterator, iterator> __p = __equal_range_multi(__k);
+    size_type __r = 0;
+    for (; __p.first != __p.second; ++__r)
+        __p.first = erase(__p.first);
+    return __r;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v)
+{
+    iterator __p = __lower_bound(__v, __root(), __end_node());
+    if (__p != end() && !value_comp()(__v, *__p))
+        return __p;
+    return end();
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::const_iterator
+__tree<_Tp, _Compare, _Allocator>::find(const _Key& __v) const
+{
+    const_iterator __p = __lower_bound(__v, __root(), __end_node());
+    if (__p != end() && !value_comp()(__v, *__p))
+        return __p;
+    return end();
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::size_type
+__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const
+{
+    __node_const_pointer __result = __end_node();
+    __node_const_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+        else
+            return 1;
+    }
+    return 0;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::size_type
+__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
+{
+    typedef pair<const_iterator, const_iterator> _Pp;
+    __node_const_pointer __result = __end_node();
+    __node_const_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+        else
+            return _VSTD::distance(
+                __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
+                __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)
+            );
+    }
+    return 0;
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
+                                                 __node_pointer __root,
+                                                 __node_pointer __result)
+{
+    while (__root != nullptr)
+    {
+        if (!value_comp()(__root->__value_, __v))
+        {
+            __result = __root;
+            __root = static_cast<__node_pointer>(__root->__left_);
+        }
+        else
+            __root = static_cast<__node_pointer>(__root->__right_);
+    }
+    return iterator(__result);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::const_iterator
+__tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v,
+                                                 __node_const_pointer __root,
+                                                 __node_const_pointer __result) const
+{
+    while (__root != nullptr)
+    {
+        if (!value_comp()(__root->__value_, __v))
+        {
+            __result = __root;
+            __root = static_cast<__node_const_pointer>(__root->__left_);
+        }
+        else
+            __root = static_cast<__node_const_pointer>(__root->__right_);
+    }
+    return const_iterator(__result);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
+                                                 __node_pointer __root,
+                                                 __node_pointer __result)
+{
+    while (__root != nullptr)
+    {
+        if (value_comp()(__v, __root->__value_))
+        {
+            __result = __root;
+            __root = static_cast<__node_pointer>(__root->__left_);
+        }
+        else
+            __root = static_cast<__node_pointer>(__root->__right_);
+    }
+    return iterator(__result);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+typename __tree<_Tp, _Compare, _Allocator>::const_iterator
+__tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v,
+                                                 __node_const_pointer __root,
+                                                 __node_const_pointer __result) const
+{
+    while (__root != nullptr)
+    {
+        if (value_comp()(__v, __root->__value_))
+        {
+            __result = __root;
+            __root = static_cast<__node_const_pointer>(__root->__left_);
+        }
+        else
+            __root = static_cast<__node_const_pointer>(__root->__right_);
+    }
+    return const_iterator(__result);
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
+     typename __tree<_Tp, _Compare, _Allocator>::iterator>
+__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k)
+{
+    typedef pair<iterator, iterator> _Pp;
+    __node_pointer __result = __end_node();
+    __node_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_pointer>(__rt->__right_);
+        else
+            return _Pp(iterator(__rt),
+                      iterator(
+                          __rt->__right_ != nullptr ?
+                              static_cast<__node_pointer>(__tree_min(__rt->__right_))
+                            : __result));
+    }
+    return _Pp(iterator(__result), iterator(__result));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
+     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
+__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const
+{
+    typedef pair<const_iterator, const_iterator> _Pp;
+    __node_const_pointer __result = __end_node();
+    __node_const_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+        else
+            return _Pp(const_iterator(__rt),
+                      const_iterator(
+                          __rt->__right_ != nullptr ?
+                              static_cast<__node_const_pointer>(__tree_min(__rt->__right_))
+                            : __result));
+    }
+    return _Pp(const_iterator(__result), const_iterator(__result));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+pair<typename __tree<_Tp, _Compare, _Allocator>::iterator,
+     typename __tree<_Tp, _Compare, _Allocator>::iterator>
+__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k)
+{
+    typedef pair<iterator, iterator> _Pp;
+    __node_pointer __result = __end_node();
+    __node_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_pointer>(__rt->__right_);
+        else
+            return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt),
+                      __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result));
+    }
+    return _Pp(iterator(__result), iterator(__result));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+template <class _Key>
+pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
+     typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
+__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const
+{
+    typedef pair<const_iterator, const_iterator> _Pp;
+    __node_const_pointer __result = __end_node();
+    __node_const_pointer __rt = __root();
+    while (__rt != nullptr)
+    {
+        if (value_comp()(__k, __rt->__value_))
+        {
+            __result = __rt;
+            __rt = static_cast<__node_const_pointer>(__rt->__left_);
+        }
+        else if (value_comp()(__rt->__value_, __k))
+            __rt = static_cast<__node_const_pointer>(__rt->__right_);
+        else
+            return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt),
+                      __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result));
+    }
+    return _Pp(const_iterator(__result), const_iterator(__result));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+typename __tree<_Tp, _Compare, _Allocator>::__node_holder
+__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT
+{
+    __node_pointer __np = __p.__ptr_;
+    if (__begin_node() == __np)
+    {
+        if (__np->__right_ != nullptr)
+            __begin_node() = static_cast<__node_pointer>(__np->__right_);
+        else
+            __begin_node() = static_cast<__node_pointer>(__np->__parent_);
+    }
+    --size();
+    __tree_remove(__end_node()->__left_,
+                  static_cast<__node_base_pointer>(__np));
+    return __node_holder(__np, _Dp(__node_alloc()));
+}
+
+template <class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__tree<_Tp, _Compare, _Allocator>& __x,
+     __tree<_Tp, _Compare, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___TREE
diff --git a/include/c++/v1/__tuple b/include/c++/v1/__tuple
new file mode 100644
index 0000000..de35cb8
--- /dev/null
+++ b/include/c++/v1/__tuple
@@ -0,0 +1,305 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TUPLE
+#define _LIBCPP___TUPLE
+
+#include <__config>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+
+#include <__tuple_03>
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp>
+    : public tuple_size<_Tp> {};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<volatile _Tp>
+    : public tuple_size<_Tp> {};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const volatile _Tp>
+    : public tuple_size<_Tp> {};
+
+template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
+
+template <size_t _Ip, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const _Tp>
+{
+public:
+    typedef typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type;
+};
+
+template <size_t _Ip, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, volatile _Tp>
+{
+public:
+    typedef typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type;
+};
+
+template <size_t _Ip, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const volatile _Tp>
+{
+public:
+    typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
+};
+
+template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
+template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
+
+template <class _Tp> struct __tuple_like : false_type {};
+
+template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
+template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
+template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
+
+template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
+template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
+template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
+
+template <size_t _Ip, class ..._Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, tuple<_Tp...> >::type&
+get(tuple<_Tp...>&) _NOEXCEPT;
+
+template <size_t _Ip, class ..._Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, tuple<_Tp...> >::type&
+get(const tuple<_Tp...>&) _NOEXCEPT;
+
+template <size_t _Ip, class ..._Tp>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+get(tuple<_Tp...>&&) _NOEXCEPT;
+
+template <size_t _Ip, class _T1, class _T2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&
+get(pair<_T1, _T2>&) _NOEXCEPT;
+
+template <size_t _Ip, class _T1, class _T2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
+get(const pair<_T1, _T2>&) _NOEXCEPT;
+
+template <size_t _Ip, class _T1, class _T2>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
+get(pair<_T1, _T2>&&) _NOEXCEPT;
+
+template <size_t _Ip, class _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&
+get(array<_Tp, _Size>&) _NOEXCEPT;
+
+template <size_t _Ip, class _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+get(const array<_Tp, _Size>&) _NOEXCEPT;
+
+template <size_t _Ip, class _Tp, size_t _Size>
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&&
+get(array<_Tp, _Size>&&) _NOEXCEPT;
+
+// __make_tuple_indices
+
+template <size_t...> struct __tuple_indices {};
+
+template <size_t _Sp, class _IntTuple, size_t _Ep>
+struct __make_indices_imp;
+
+template <size_t _Sp, size_t ..._Indices, size_t _Ep>
+struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep>
+{
+    typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type;
+};
+
+template <size_t _Ep, size_t ..._Indices>
+struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep>
+{
+    typedef __tuple_indices<_Indices...> type;
+};
+
+template <size_t _Ep, size_t _Sp = 0>
+struct __make_tuple_indices
+{
+    static_assert(_Sp <= _Ep, "__make_tuple_indices input error");
+    typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type;
+};
+
+// __tuple_types
+
+template <class ..._Tp> struct __tuple_types {};
+
+template <size_t _Ip>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> >
+{
+public:
+    static_assert(_Ip == 0, "tuple_element index out of range");
+    static_assert(_Ip != 0, "tuple_element index out of range");
+};
+
+template <class _Hp, class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> >
+{
+public:
+    typedef _Hp type;
+};
+
+template <size_t _Ip, class _Hp, class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> >
+{
+public:
+    typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type;
+};
+
+template <class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> >
+    : public integral_constant<size_t, sizeof...(_Tp)>
+{
+};
+
+template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {};
+
+// __make_tuple_types
+
+// __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a
+// __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep).
+// _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>.  If _Tuple is a
+// lvalue_reference type, then __tuple_types<_Types&...> is the result.
+
+template <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep>
+struct __make_tuple_types_imp;
+
+template <class ..._Types, class _Tp, size_t _Sp, size_t _Ep>
+struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep>
+{
+    typedef typename remove_reference<_Tp>::type _Tpr;
+    typedef typename __make_tuple_types_imp<__tuple_types<_Types...,
+                                            typename conditional<is_lvalue_reference<_Tp>::value,
+                                                typename tuple_element<_Sp, _Tpr>::type&,
+                                                typename tuple_element<_Sp, _Tpr>::type>::type>,
+                                            _Tp, _Sp+1, _Ep>::type type;
+};
+
+template <class ..._Types, class _Tp, size_t _Ep>
+struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep>
+{
+    typedef __tuple_types<_Types...> type;
+};
+
+template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0>
+struct __make_tuple_types
+{
+    static_assert(_Sp <= _Ep, "__make_tuple_types input error");
+    typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type;
+};
+
+// __tuple_convertible
+
+template <bool, class _Tp, class _Up>
+struct __tuple_convertible_imp : public false_type {};
+
+template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
+struct __tuple_convertible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
+    : public integral_constant<bool,
+                               is_convertible<_Tp0, _Up0>::value &&
+                               __tuple_convertible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
+
+template <>
+struct __tuple_convertible_imp<true, __tuple_types<>, __tuple_types<> >
+    : public true_type {};
+
+template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
+                                bool = __tuple_like<_Up>::value>
+struct __tuple_convertible
+    : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_convertible<_Tp, _Up, true, true>
+    : public __tuple_convertible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                     tuple_size<_Up>::value,
+             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+{};
+
+// __tuple_constructible
+
+template <bool, class _Tp, class _Up>
+struct __tuple_constructible_imp : public false_type {};
+
+template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
+struct __tuple_constructible_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
+    : public integral_constant<bool,
+                               is_constructible<_Up0, _Tp0>::value &&
+                               __tuple_constructible_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
+
+template <>
+struct __tuple_constructible_imp<true, __tuple_types<>, __tuple_types<> >
+    : public true_type {};
+
+template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
+                                bool = __tuple_like<_Up>::value>
+struct __tuple_constructible
+    : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_constructible<_Tp, _Up, true, true>
+    : public __tuple_constructible_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                     tuple_size<_Up>::value,
+             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+{};
+
+// __tuple_assignable
+
+template <bool, class _Tp, class _Up>
+struct __tuple_assignable_imp : public false_type {};
+
+template <class _Tp0, class ..._Tp, class _Up0, class ..._Up>
+struct __tuple_assignable_imp<true, __tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> >
+    : public integral_constant<bool,
+                               is_assignable<_Up0&, _Tp0>::value &&
+                               __tuple_assignable_imp<true, __tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {};
+
+template <>
+struct __tuple_assignable_imp<true, __tuple_types<>, __tuple_types<> >
+    : public true_type {};
+
+template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value,
+                                bool = __tuple_like<_Up>::value>
+struct __tuple_assignable
+    : public false_type {};
+
+template <class _Tp, class _Up>
+struct __tuple_assignable<_Tp, _Up, true, true>
+    : public __tuple_assignable_imp<tuple_size<typename remove_reference<_Tp>::type>::value ==
+                                    tuple_size<_Up>::value,
+             typename __make_tuple_types<_Tp>::type, typename __make_tuple_types<_Up>::type>
+{};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#endif  // _LIBCPP___TUPLE
diff --git a/include/c++/v1/__tuple_03 b/include/c++/v1/__tuple_03
new file mode 100644
index 0000000..b91c2cd
--- /dev/null
+++ b/include/c++/v1/__tuple_03
@@ -0,0 +1,27 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TUPLE_03
+#define _LIBCPP___TUPLE_03
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
+template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP___TUPLE_03
diff --git a/include/c++/v1/__undef_min_max b/include/c++/v1/__undef_min_max
new file mode 100644
index 0000000..5df9412
--- /dev/null
+++ b/include/c++/v1/__undef_min_max
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef min
+#if defined(_MSC_VER) && ! defined(__clang__)
+_LIBCPP_WARNING("macro min is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing min")
+#else
+#warning: macro min is incompatible with C++.  #undefing min
+#endif
+#undef min
+#endif
+
+#ifdef max
+#if defined(_MSC_VER) && ! defined(__clang__)
+_LIBCPP_WARNING("macro max is incompatible with C++.  Try #define NOMINMAX "
+                "before any Windows header. #undefing max")
+#else
+#warning: macro max is incompatible with C++.  #undefing max
+#endif
+#undef max
+#endif
diff --git a/include/c++/v1/algorithm b/include/c++/v1/algorithm
new file mode 100644
index 0000000..3b74a6b
--- /dev/null
+++ b/include/c++/v1/algorithm
@@ -0,0 +1,5749 @@
+// -*- C++ -*-
+//===-------------------------- algorithm ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ALGORITHM
+#define _LIBCPP_ALGORITHM
+
+/*
+    algorithm synopsis
+
+#include <initializer_list>
+
+namespace std
+{
+
+template <class InputIterator, class Predicate>
+    bool
+    all_of(InputIterator first, InputIterator last, Predicate pred);
+
+template <class InputIterator, class Predicate>
+    bool
+    any_of(InputIterator first, InputIterator last, Predicate pred);
+
+template <class InputIterator, class Predicate>
+    bool
+    none_of(InputIterator first, InputIterator last, Predicate pred);
+
+template <class InputIterator, class Function>
+    Function
+    for_each(InputIterator first, InputIterator last, Function f);
+
+template <class InputIterator, class T>
+    InputIterator
+    find(InputIterator first, InputIterator last, const T& value);
+
+template <class InputIterator, class Predicate>
+    InputIterator
+    find_if(InputIterator first, InputIterator last, Predicate pred);
+
+template<class InputIterator, class Predicate>
+    InputIterator
+    find_if_not(InputIterator first, InputIterator last, Predicate pred);
+
+template <class ForwardIterator1, class ForwardIterator2>
+    ForwardIterator1
+    find_end(ForwardIterator1 first1, ForwardIterator1 last1,
+             ForwardIterator2 first2, ForwardIterator2 last2);
+
+template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    ForwardIterator1
+    find_end(ForwardIterator1 first1, ForwardIterator1 last1,
+             ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
+
+template <class ForwardIterator1, class ForwardIterator2>
+    ForwardIterator1
+    find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
+                  ForwardIterator2 first2, ForwardIterator2 last2);
+
+template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    ForwardIterator1
+    find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
+                  ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
+
+template <class ForwardIterator>
+    ForwardIterator
+    adjacent_find(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class BinaryPredicate>
+    ForwardIterator
+    adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
+
+template <class InputIterator, class T>
+    typename iterator_traits<InputIterator>::difference_type
+    count(InputIterator first, InputIterator last, const T& value);
+
+template <class InputIterator, class Predicate>
+    typename iterator_traits<InputIterator>::difference_type
+    count_if(InputIterator first, InputIterator last, Predicate pred);
+
+template <class InputIterator1, class InputIterator2>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
+
+template <class InputIterator1, class InputIterator2>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1, 
+             InputIterator2 first2, InputIterator2 last2); // **C++14**
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1,
+             InputIterator2 first2, BinaryPredicate pred);
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    pair<InputIterator1, InputIterator2>
+    mismatch(InputIterator1 first1, InputIterator1 last1,
+             InputIterator2 first2, InputIterator2 last2,
+             BinaryPredicate pred); // **C++14**
+
+template <class InputIterator1, class InputIterator2>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
+
+template <class InputIterator1, class InputIterator2>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1, 
+          InputIterator2 first2, InputIterator2 last2); // **C++14**
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1,
+          InputIterator2 first2, BinaryPredicate pred);
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+    bool
+    equal(InputIterator1 first1, InputIterator1 last1,
+          InputIterator2 first2, InputIterator2 last2,
+          BinaryPredicate pred); // **C++14**
+
+template<class ForwardIterator1, class ForwardIterator2>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2);
+
+template<class ForwardIterator1, class ForwardIterator2>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2, ForwardIterator2 last2); // **C++14**
+
+template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2, BinaryPredicate pred);
+
+template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    bool
+    is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
+                   ForwardIterator2 first2, ForwardIterator2 last2,
+                   BinaryPredicate pred);  // **C++14**
+
+template <class ForwardIterator1, class ForwardIterator2>
+    ForwardIterator1
+    search(ForwardIterator1 first1, ForwardIterator1 last1,
+           ForwardIterator2 first2, ForwardIterator2 last2);
+
+template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
+    ForwardIterator1
+    search(ForwardIterator1 first1, ForwardIterator1 last1,
+           ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
+
+template <class ForwardIterator, class Size, class T>
+    ForwardIterator
+    search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value);
+
+template <class ForwardIterator, class Size, class T, class BinaryPredicate>
+    ForwardIterator
+    search_n(ForwardIterator first, ForwardIterator last,
+             Size count, const T& value, BinaryPredicate pred);
+
+template <class InputIterator, class OutputIterator>
+    OutputIterator
+    copy(InputIterator first, InputIterator last, OutputIterator result);
+
+template<class InputIterator, class OutputIterator, class Predicate>
+    OutputIterator
+    copy_if(InputIterator first, InputIterator last,
+            OutputIterator result, Predicate pred);
+
+template<class InputIterator, class Size, class OutputIterator>
+    OutputIterator
+    copy_n(InputIterator first, Size n, OutputIterator result);
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+    BidirectionalIterator2
+    copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
+                  BidirectionalIterator2 result);
+
+template <class ForwardIterator1, class ForwardIterator2>
+    ForwardIterator2
+    swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
+
+template <class ForwardIterator1, class ForwardIterator2>
+    void
+    iter_swap(ForwardIterator1 a, ForwardIterator2 b);
+
+template <class InputIterator, class OutputIterator, class UnaryOperation>
+    OutputIterator
+    transform(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation>
+    OutputIterator
+    transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
+              OutputIterator result, BinaryOperation binary_op);
+
+template <class ForwardIterator, class T>
+    void
+    replace(ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value);
+
+template <class ForwardIterator, class Predicate, class T>
+    void
+    replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value);
+
+template <class InputIterator, class OutputIterator, class T>
+    OutputIterator
+    replace_copy(InputIterator first, InputIterator last, OutputIterator result,
+                 const T& old_value, const T& new_value);
+
+template <class InputIterator, class OutputIterator, class Predicate, class T>
+    OutputIterator
+    replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value);
+
+template <class ForwardIterator, class T>
+    void
+    fill(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class OutputIterator, class Size, class T>
+    OutputIterator
+    fill_n(OutputIterator first, Size n, const T& value);
+
+template <class ForwardIterator, class Generator>
+    void
+    generate(ForwardIterator first, ForwardIterator last, Generator gen);
+
+template <class OutputIterator, class Size, class Generator>
+    OutputIterator
+    generate_n(OutputIterator first, Size n, Generator gen);
+
+template <class ForwardIterator, class T>
+    ForwardIterator
+    remove(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class ForwardIterator, class Predicate>
+    ForwardIterator
+    remove_if(ForwardIterator first, ForwardIterator last, Predicate pred);
+
+template <class InputIterator, class OutputIterator, class T>
+    OutputIterator
+    remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value);
+
+template <class InputIterator, class OutputIterator, class Predicate>
+    OutputIterator
+    remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred);
+
+template <class ForwardIterator>
+    ForwardIterator
+    unique(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class BinaryPredicate>
+    ForwardIterator
+    unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred);
+
+template <class InputIterator, class OutputIterator>
+    OutputIterator
+    unique_copy(InputIterator first, InputIterator last, OutputIterator result);
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate>
+    OutputIterator
+    unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred);
+
+template <class BidirectionalIterator>
+    void
+    reverse(BidirectionalIterator first, BidirectionalIterator last);
+
+template <class BidirectionalIterator, class OutputIterator>
+    OutputIterator
+    reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator result);
+
+template <class ForwardIterator>
+    ForwardIterator
+    rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last);
+
+template <class ForwardIterator, class OutputIterator>
+    OutputIterator
+    rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result);
+
+template <class RandomAccessIterator>
+    void
+    random_shuffle(RandomAccessIterator first, RandomAccessIterator last); // deprecated in C++14
+
+template <class RandomAccessIterator, class RandomNumberGenerator>
+    void
+    random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+                   RandomNumberGenerator& rand);  // deprecated in C++14
+
+template<class RandomAccessIterator, class UniformRandomNumberGenerator>
+    void shuffle(RandomAccessIterator first, RandomAccessIterator last,
+                 UniformRandomNumberGenerator&& g);
+
+template <class InputIterator, class Predicate>
+    bool
+    is_partitioned(InputIterator first, InputIterator last, Predicate pred);
+
+template <class ForwardIterator, class Predicate>
+    ForwardIterator
+    partition(ForwardIterator first, ForwardIterator last, Predicate pred);
+
+template <class InputIterator, class OutputIterator1,
+          class OutputIterator2, class Predicate>
+    pair<OutputIterator1, OutputIterator2>
+    partition_copy(InputIterator first, InputIterator last,
+                   OutputIterator1 out_true, OutputIterator2 out_false,
+                   Predicate pred);
+
+template <class ForwardIterator, class Predicate>
+    ForwardIterator
+    stable_partition(ForwardIterator first, ForwardIterator last, Predicate pred);
+
+template<class ForwardIterator, class Predicate>
+    ForwardIterator
+    partition_point(ForwardIterator first, ForwardIterator last, Predicate pred);
+
+template <class ForwardIterator>
+    bool
+    is_sorted(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class Compare>
+    bool
+    is_sorted(ForwardIterator first, ForwardIterator last, Compare comp);
+
+template<class ForwardIterator>
+    ForwardIterator
+    is_sorted_until(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class Compare>
+    ForwardIterator
+    is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    sort(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    stable_sort(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);
+
+template <class InputIterator, class RandomAccessIterator>
+    RandomAccessIterator
+    partial_sort_copy(InputIterator first, InputIterator last,
+                      RandomAccessIterator result_first, RandomAccessIterator result_last);
+
+template <class InputIterator, class RandomAccessIterator, class Compare>
+    RandomAccessIterator
+    partial_sort_copy(InputIterator first, InputIterator last,
+                      RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
+
+template <class ForwardIterator, class T>
+    ForwardIterator
+    lower_bound(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class ForwardIterator, class T, class Compare>
+    ForwardIterator
+    lower_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
+
+template <class ForwardIterator, class T>
+    ForwardIterator
+    upper_bound(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class ForwardIterator, class T, class Compare>
+    ForwardIterator
+    upper_bound(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
+
+template <class ForwardIterator, class T>
+    pair<ForwardIterator, ForwardIterator>
+    equal_range(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class ForwardIterator, class T, class Compare>
+    pair<ForwardIterator, ForwardIterator>
+    equal_range(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
+
+template <class ForwardIterator, class T>
+    bool
+    binary_search(ForwardIterator first, ForwardIterator last, const T& value);
+
+template <class ForwardIterator, class T, class Compare>
+    bool
+    binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+    OutputIterator
+    merge(InputIterator1 first1, InputIterator1 last1,
+          InputIterator2 first2, InputIterator2 last2, OutputIterator result);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
+    OutputIterator
+    merge(InputIterator1 first1, InputIterator1 last1,
+          InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
+
+template <class BidirectionalIterator>
+    void
+    inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);
+
+template <class BidirectionalIterator, class Compare>
+    void
+    inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);
+
+template <class InputIterator1, class InputIterator2>
+    bool
+    includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
+
+template <class InputIterator1, class InputIterator2, class Compare>
+    bool
+    includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Compare comp);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+    OutputIterator
+    set_union(InputIterator1 first1, InputIterator1 last1,
+              InputIterator2 first2, InputIterator2 last2, OutputIterator result);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
+    OutputIterator
+    set_union(InputIterator1 first1, InputIterator1 last1,
+              InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+    OutputIterator
+    set_intersection(InputIterator1 first1, InputIterator1 last1,
+                     InputIterator2 first2, InputIterator2 last2, OutputIterator result);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
+    OutputIterator
+    set_intersection(InputIterator1 first1, InputIterator1 last1,
+                     InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+    OutputIterator
+    set_difference(InputIterator1 first1, InputIterator1 last1,
+                   InputIterator2 first2, InputIterator2 last2, OutputIterator result);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
+    OutputIterator
+    set_difference(InputIterator1 first1, InputIterator1 last1,
+                   InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+    OutputIterator
+    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
+                             InputIterator2 first2, InputIterator2 last2, OutputIterator result);
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare>
+    OutputIterator
+    set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
+                             InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    push_heap(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    pop_heap(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    make_heap(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    void
+    sort_heap(RandomAccessIterator first, RandomAccessIterator last);
+
+template <class RandomAccessIterator, class Compare>
+    void
+    sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    bool
+    is_heap(RandomAccessIterator first, RandomAccessiterator last);
+
+template <class RandomAccessIterator, class Compare>
+    bool
+    is_heap(RandomAccessIterator first, RandomAccessiterator last, Compare comp);
+
+template <class RandomAccessIterator>
+    RandomAccessIterator
+    is_heap_until(RandomAccessIterator first, RandomAccessiterator last);
+
+template <class RandomAccessIterator, class Compare>
+    RandomAccessIterator
+    is_heap_until(RandomAccessIterator first, RandomAccessiterator last, Compare comp);
+
+template <class ForwardIterator>
+    ForwardIterator
+    min_element(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class Compare>
+    ForwardIterator
+    min_element(ForwardIterator first, ForwardIterator last, Compare comp);
+
+template <class T>
+    const T&
+    min(const T& a, const T& b);  // constexpr in C++14
+
+template <class T, class Compare>
+    const T&
+    min(const T& a, const T& b, Compare comp);  // constexpr in C++14
+
+template<class T>
+    T
+    min(initializer_list<T> t);  // constexpr in C++14
+
+template<class T, class Compare>
+    T
+    min(initializer_list<T> t, Compare comp);  // constexpr in C++14
+
+template <class ForwardIterator>
+    ForwardIterator
+    max_element(ForwardIterator first, ForwardIterator last);
+
+template <class ForwardIterator, class Compare>
+    ForwardIterator
+    max_element(ForwardIterator first, ForwardIterator last, Compare comp);
+
+template <class T>
+    const T&
+    max(const T& a, const T& b); // constexpr in C++14
+
+template <class T, class Compare>
+    const T&
+    max(const T& a, const T& b, Compare comp);  // constexpr in C++14
+
+template<class T>
+    T
+    max(initializer_list<T> t);  // constexpr in C++14
+
+template<class T, class Compare>
+    T
+    max(initializer_list<T> t, Compare comp);  // constexpr in C++14
+
+template<class ForwardIterator>
+    pair<ForwardIterator, ForwardIterator>
+    minmax_element(ForwardIterator first, ForwardIterator last);
+
+template<class ForwardIterator, class Compare>
+    pair<ForwardIterator, ForwardIterator>
+    minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
+
+template<class T>
+    pair<const T&, const T&>
+    minmax(const T& a, const T& b);  // constexpr in C++14
+
+template<class T, class Compare>
+    pair<const T&, const T&>
+    minmax(const T& a, const T& b, Compare comp);  // constexpr in C++14
+
+template<class T>
+    pair<T, T>
+    minmax(initializer_list<T> t);  // constexpr in C++14
+
+template<class T, class Compare>
+    pair<T, T>
+    minmax(initializer_list<T> t, Compare comp);  // constexpr in C++14
+
+template <class InputIterator1, class InputIterator2>
+    bool
+    lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
+
+template <class InputIterator1, class InputIterator2, class Compare>
+    bool
+    lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
+                            InputIterator2 first2, InputIterator2 last2, Compare comp);
+
+template <class BidirectionalIterator>
+    bool
+    next_permutation(BidirectionalIterator first, BidirectionalIterator last);
+
+template <class BidirectionalIterator, class Compare>
+    bool
+    next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
+
+template <class BidirectionalIterator>
+    bool
+    prev_permutation(BidirectionalIterator first, BidirectionalIterator last);
+
+template <class BidirectionalIterator, class Compare>
+    bool
+    prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <initializer_list>
+#include <type_traits>
+#include <cstring>
+#include <utility>
+#include <memory>
+#include <iterator>
+#include <cstddef>
+
+#if defined(__IBMCPP__)
+#include "support/ibm/support.h"
+#endif
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#include "support/win32/support.h"
+#endif
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// I'd like to replace these with _VSTD::equal_to<void>, but can't because:
+//   * That only works with C++14 and later, and
+//   * We haven't included <functional> here.
+template <class _T1, class _T2 = _T1>
+struct __equal_to
+{
+    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T2& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T1& __y) const {return __x == __y;}
+    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T2& __x, const _T2& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<_T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<const _T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1>
+struct __equal_to<_T1, const _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
+};
+
+template <class _T1, class _T2 = _T1>
+struct __less
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<_T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<const _T1, _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+template <class _T1>
+struct __less<_T1, const _T1>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;}
+};
+
+template <class _Predicate>
+class __negate
+{
+private:
+    _Predicate __p_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __negate() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __negate(_Predicate __p) : __p_(__p) {}
+
+    template <class _T1>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _T1& __x) {return !__p_(__x);}
+
+    template <class _T1, class _T2>
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);}
+};
+
+#ifdef _LIBCPP_DEBUG
+
+template <class _Compare>
+struct __debug_less
+{
+    _Compare __comp_;
+    __debug_less(_Compare& __c) : __comp_(__c) {}
+    template <class _Tp, class _Up>
+    bool operator()(const _Tp& __x, const _Up& __y)
+    {
+        bool __r = __comp_(__x, __y);
+        if (__r)
+            _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering");
+        return __r;
+    }
+};
+
+#endif  // _LIBCPP_DEBUG
+
+// Precondition:  __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned
+__ctz(unsigned __x)
+{
+    return static_cast<unsigned>(__builtin_ctz(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long
+__ctz(unsigned long __x)
+{
+    return static_cast<unsigned long>(__builtin_ctzl(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+__ctz(unsigned long long __x)
+{
+    return static_cast<unsigned long long>(__builtin_ctzll(__x));
+}
+
+// Precondition:  __x != 0
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned
+__clz(unsigned __x)
+{
+    return static_cast<unsigned>(__builtin_clz(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long
+__clz(unsigned long __x)
+{
+    return static_cast<unsigned long>(__builtin_clzl (__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+__clz(unsigned long long __x)
+{
+    return static_cast<unsigned long long>(__builtin_clzll(__x));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned           __x) {return __builtin_popcount  (__x);}
+inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned      long __x) {return __builtin_popcountl (__x);}
+inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) {return __builtin_popcountll(__x);}
+
+// all_of
+
+template <class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (!__pred(*__first))
+            return false;
+    return true;
+}
+
+// any_of
+
+template <class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            return true;
+    return false;
+}
+
+// none_of
+
+template <class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            return false;
+    return true;
+}
+
+// for_each
+
+template <class _InputIterator, class _Function>
+inline _LIBCPP_INLINE_VISIBILITY
+_Function
+for_each(_InputIterator __first, _InputIterator __last, _Function __f)
+{
+    for (; __first != __last; ++__first)
+        __f(*__first);
+    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03
+}
+
+// find
+
+template <class _InputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_InputIterator
+find(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
+{
+    for (; __first != __last; ++__first)
+        if (*__first == __value_)
+            break;
+    return __first;
+}
+
+// find_if
+
+template <class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_InputIterator
+find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            break;
+    return __first;
+}
+
+// find_if_not
+
+template<class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_InputIterator
+find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (!__pred(*__first))
+            break;
+    return __first;
+}
+
+// find_end
+
+template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+_ForwardIterator1
+__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+           _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
+           forward_iterator_tag, forward_iterator_tag)
+{
+    // modeled after search algorithm
+    _ForwardIterator1 __r = __last1;  // __last1 is the "default" answer
+    if (__first2 == __last2)
+        return __r;
+    while (true)
+    {
+        while (true)
+        {
+            if (__first1 == __last1)         // if source exhausted return last correct answer
+                return __r;                  //    (or __last1 if never found)
+            if (__pred(*__first1, *__first2))
+                break;
+            ++__first1;
+        }
+        // *__first1 matches *__first2, now match elements after here
+        _ForwardIterator1 __m1 = __first1;
+        _ForwardIterator2 __m2 = __first2;
+        while (true)
+        {
+            if (++__m2 == __last2)
+            {                         // Pattern exhaused, record answer and search for another one
+                __r = __first1;
+                ++__first1;
+                break;
+            }
+            if (++__m1 == __last1)     // Source exhausted, return last answer
+                return __r;
+            if (!__pred(*__m1, *__m2))  // mismatch, restart with a new __first
+            {
+                ++__first1;
+                break;
+            }  // else there is a match, check next elements
+        }
+    }
+}
+
+template <class _BinaryPredicate, class _BidirectionalIterator1, class _BidirectionalIterator2>
+_BidirectionalIterator1
+__find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1,
+           _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BinaryPredicate __pred,
+           bidirectional_iterator_tag, bidirectional_iterator_tag)
+{
+    // modeled after search algorithm (in reverse)
+    if (__first2 == __last2)
+        return __last1;  // Everything matches an empty sequence
+    _BidirectionalIterator1 __l1 = __last1;
+    _BidirectionalIterator2 __l2 = __last2;
+    --__l2;
+    while (true)
+    {
+        // Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
+        while (true)
+        {
+            if (__first1 == __l1)  // return __last1 if no element matches *__first2
+                return __last1;
+            if (__pred(*--__l1, *__l2))
+                break;
+        }
+        // *__l1 matches *__l2, now match elements before here
+        _BidirectionalIterator1 __m1 = __l1;
+        _BidirectionalIterator2 __m2 = __l2;
+        while (true)
+        {
+            if (__m2 == __first2)  // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
+                return __m1;
+            if (__m1 == __first1)  // Otherwise if source exhaused, pattern not found
+                return __last1;
+            if (!__pred(*--__m1, *--__m2))  // if there is a mismatch, restart with a new __l1
+            {
+                break;
+            }  // else there is a match, check next elements
+        }
+    }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
+__find_end(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
+           _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
+           random_access_iterator_tag, random_access_iterator_tag)
+{
+    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
+    typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2;
+    if (__len2 == 0)
+        return __last1;
+    typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1;
+    if (__len1 < __len2)
+        return __last1;
+    const _RandomAccessIterator1 __s = __first1 + (__len2 - 1);  // End of pattern match can't go before here
+    _RandomAccessIterator1 __l1 = __last1;
+    _RandomAccessIterator2 __l2 = __last2;
+    --__l2;
+    while (true)
+    {
+        while (true)
+        {
+            if (__s == __l1)
+                return __last1;
+            if (__pred(*--__l1, *__l2))
+                break;
+        }
+        _RandomAccessIterator1 __m1 = __l1;
+        _RandomAccessIterator2 __m2 = __l2;
+        while (true)
+        {
+            if (__m2 == __first2)
+                return __m1;
+                                 // no need to check range on __m1 because __s guarantees we have enough source
+            if (!__pred(*--__m1, *--__m2))
+            {
+                break;
+            }
+        }
+    }
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
+{
+    return _VSTD::__find_end<typename add_lvalue_reference<_BinaryPredicate>::type>
+                         (__first1, __last1, __first2, __last2, __pred,
+                          typename iterator_traits<_ForwardIterator1>::iterator_category(),
+                          typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+{
+    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::find_end(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+
+// find_first_of
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator1
+__find_first_of_ce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
+{
+    for (; __first1 != __last1; ++__first1)
+        for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+            if (__pred(*__first1, *__j))
+                return __first1;
+    return __last1;
+}
+
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
+{
+    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+              _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+{
+    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+
+// adjacent_find
+
+template <class _ForwardIterator, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__pred(*__first, *__i))
+                return __first;
+            __first = __i;
+        }
+    }
+    return __last;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+    return _VSTD::adjacent_find(__first, __last, __equal_to<__v>());
+}
+
+// count
+
+template <class _InputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_InputIterator>::difference_type
+count(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
+{
+    typename iterator_traits<_InputIterator>::difference_type __r(0);
+    for (; __first != __last; ++__first)
+        if (*__first == __value_)
+            ++__r;
+    return __r;
+}
+
+// count_if
+
+template <class _InputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_InputIterator>::difference_type
+count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    typename iterator_traits<_InputIterator>::difference_type __r(0);
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            ++__r;
+    return __r;
+}
+
+// mismatch
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+         _InputIterator2 __first2, _BinaryPredicate __pred)
+{
+    for (; __first1 != __last1; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            break;
+    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::mismatch(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+         _InputIterator2 __first2, _InputIterator2 __last2,
+         _BinaryPredicate __pred)
+{
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            break;
+    return pair<_InputIterator1, _InputIterator2>(__first1, __first2);
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIterator1, _InputIterator2>
+mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
+         _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::mismatch(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+#endif
+
+// equal
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)
+{
+    for (; __first1 != __last1; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            return false;
+    return true;
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+        _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred,
+        input_iterator_tag, input_iterator_tag )
+{
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            return false;
+    return __first1 == __last1 && __first2 == __last2;
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, 
+        _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, 
+      random_access_iterator_tag, random_access_iterator_tag )
+{
+    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+        return false;
+    return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2,
+                        typename add_lvalue_reference<_BinaryPredicate>::type>
+                       (__first1, __last1, __first2, __pred );
+}
+
+template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+      _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred )
+{
+    return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type>
+       (__first1, __last1, __first2, __last2, __pred, 
+        typename iterator_traits<_InputIterator1>::iterator_category(),
+        typename iterator_traits<_InputIterator2>::iterator_category());
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+equal(_InputIterator1 __first1, _InputIterator1 __last1, 
+      _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return _VSTD::__equal(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>(),
+        typename iterator_traits<_InputIterator1>::iterator_category(),
+        typename iterator_traits<_InputIterator2>::iterator_category());
+}
+#endif
+
+// is_permutation
+
+template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2, _BinaryPredicate __pred)
+{
+    // shorten sequences as much as possible by lopping of any equal parts
+    for (; __first1 != __last1; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            goto __not_done;
+    return true;
+__not_done:
+    // __first1 != __last1 && *__first1 != *__first2
+    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
+    _D1 __l1 = _VSTD::distance(__first1, __last1);
+    if (__l1 == _D1(1))
+        return false;
+    _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
+    // For each element in [f1, l1) see if there are the same number of
+    //    equal elements in [f2, l2)
+    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
+    {
+        // Have we already counted the number of *__i in [f1, l1)?
+        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)
+            if (__pred(*__j, *__i))
+                goto __next_iter;
+        {
+            // Count number of *__i in [f2, l2)
+            _D1 __c2 = 0;
+            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c2;
+            if (__c2 == 0)
+                return false;
+            // Count number of *__i in [__i, l1) (we can start with 1)
+            _D1 __c1 = 1;
+            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c1;
+            if (__c1 != __c2)
+                return false;
+        }
+__next_iter:;
+    }
+    return true;
+}
+
+template<class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2)
+{
+    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::is_permutation(__first1, __last1, __first2, __equal_to<__v1, __v2>());
+}
+
+#if _LIBCPP_STD_VER > 11
+template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+bool
+__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+                 _ForwardIterator2 __first2, _ForwardIterator2 __last2, 
+                 _BinaryPredicate __pred,
+                 forward_iterator_tag, forward_iterator_tag )
+{
+    // shorten sequences as much as possible by lopping of any equal parts
+    for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+        if (!__pred(*__first1, *__first2))
+            goto __not_done;
+    return __first1 == __last1 && __first2 == __last2;
+__not_done:
+    // __first1 != __last1 && __first2 != __last2 && *__first1 != *__first2
+    typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
+    _D1 __l1 = _VSTD::distance(__first1, __last1);
+
+    typedef typename iterator_traits<_ForwardIterator2>::difference_type _D2;
+    _D2 __l2 = _VSTD::distance(__first2, __last2);
+    if (__l1 != __l2)
+        return false;
+
+    // For each element in [f1, l1) see if there are the same number of
+    //    equal elements in [f2, l2)
+    for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i)
+    {
+        // Have we already counted the number of *__i in [f1, l1)?
+        for (_ForwardIterator1 __j = __first1; __j != __i; ++__j)
+            if (__pred(*__j, *__i))
+                goto __next_iter;
+        {
+            // Count number of *__i in [f2, l2)
+            _D1 __c2 = 0;
+            for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c2;
+            if (__c2 == 0)
+                return false;
+            // Count number of *__i in [__i, l1) (we can start with 1)
+            _D1 __c1 = 1;
+            for (_ForwardIterator1 __j = _VSTD::next(__i); __j != __last1; ++__j)
+                if (__pred(*__i, *__j))
+                    ++__c1;
+            if (__c1 != __c2)
+                return false;
+        }
+__next_iter:;
+    }
+    return true;
+}
+
+template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+bool
+__is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1,
+               _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, 
+               _BinaryPredicate __pred,
+               random_access_iterator_tag, random_access_iterator_tag )
+{
+    if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2))
+        return false;
+    return _VSTD::is_permutation<_RandomAccessIterator1, _RandomAccessIterator2,
+                                 typename add_lvalue_reference<_BinaryPredicate>::type>
+                                (__first1, __last1, __first2, __pred );
+}
+
+template<class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2, _ForwardIterator2 __last2,
+               _BinaryPredicate __pred )
+{
+    return _VSTD::__is_permutation<typename add_lvalue_reference<_BinaryPredicate>::type>
+       (__first1, __last1, __first2, __last2, __pred,
+        typename iterator_traits<_ForwardIterator1>::iterator_category(),
+        typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template<class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+               _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+{
+    typedef typename iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::__is_permutation(__first1, __last1, __first2, __last2,
+        __equal_to<__v1, __v2>(),
+        typename iterator_traits<_ForwardIterator1>::iterator_category(),
+        typename iterator_traits<_ForwardIterator2>::iterator_category());
+}
+#endif
+
+// search
+
+template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2>
+_ForwardIterator1
+__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred,
+         forward_iterator_tag, forward_iterator_tag)
+{
+    if (__first2 == __last2)
+        return __first1;  // Everything matches an empty sequence
+    while (true)
+    {
+        // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
+        while (true)
+        {
+            if (__first1 == __last1)  // return __last1 if no element matches *__first2
+                return __last1;
+            if (__pred(*__first1, *__first2))
+                break;
+            ++__first1;
+        }
+        // *__first1 matches *__first2, now match elements after here
+        _ForwardIterator1 __m1 = __first1;
+        _ForwardIterator2 __m2 = __first2;
+        while (true)
+        {
+            if (++__m2 == __last2)  // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
+                return __first1;
+            if (++__m1 == __last1)  // Otherwise if source exhaused, pattern not found
+                return __last1;
+            if (!__pred(*__m1, *__m2))  // if there is a mismatch, restart with a new __first1
+            {
+                ++__first1;
+                break;
+            }  // else there is a match, check next elements
+        }
+    }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
+_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1
+__search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
+           _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred,
+           random_access_iterator_tag, random_access_iterator_tag)
+{
+    typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1;
+    typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2;
+    // Take advantage of knowing source and pattern lengths.  Stop short when source is smaller than pattern
+    _D2 __len2 = __last2 - __first2;
+    if (__len2 == 0)
+        return __first1;
+    _D1 __len1 = __last1 - __first1;
+    if (__len1 < __len2)
+        return __last1;
+    const _RandomAccessIterator1 __s = __last1 - (__len2 - 1);  // Start of pattern match can't go beyond here
+    while (true)
+    {
+#if !_LIBCPP_UNROLL_LOOPS
+        while (true)
+        {
+            if (__first1 == __s)
+                return __last1;
+            if (__pred(*__first1, *__first2))
+                break;
+            ++__first1;
+        }
+#else  // !_LIBCPP_UNROLL_LOOPS
+        for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll)
+        {
+            if (__pred(*__first1, *__first2))
+                goto __phase2;
+            if (__pred(*++__first1, *__first2))
+                goto __phase2;
+            if (__pred(*++__first1, *__first2))
+                goto __phase2;
+            if (__pred(*++__first1, *__first2))
+                goto __phase2;
+            ++__first1;
+        }
+        switch (__s - __first1)
+        {
+        case 3:
+            if (__pred(*__first1, *__first2))
+                break;
+            ++__first1;
+        case 2:
+            if (__pred(*__first1, *__first2))
+                break;
+            ++__first1;
+        case 1:
+            if (__pred(*__first1, *__first2))
+                break;
+        case 0:
+            return __last1;
+        }
+    __phase2:
+#endif  // !_LIBCPP_UNROLL_LOOPS
+        _RandomAccessIterator1 __m1 = __first1;
+        _RandomAccessIterator2 __m2 = __first2;
+#if !_LIBCPP_UNROLL_LOOPS
+         while (true)
+         {
+             if (++__m2 == __last2)
+                 return __first1;
+             ++__m1;          // no need to check range on __m1 because __s guarantees we have enough source
+             if (!__pred(*__m1, *__m2))
+             {
+                 ++__first1;
+                 break;
+             }
+         }
+#else  // !_LIBCPP_UNROLL_LOOPS
+        ++__m2;
+        ++__m1;
+        for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll)
+        {
+            if (!__pred(*__m1, *__m2))
+                goto __continue;
+            if (!__pred(*++__m1, *++__m2))
+                goto __continue;
+            if (!__pred(*++__m1, *++__m2))
+                goto __continue;
+            if (!__pred(*++__m1, *++__m2))
+                goto __continue;
+            ++__m1;
+            ++__m2;
+        }
+        switch (__last2 - __m2)
+        {
+        case 3:
+            if (!__pred(*__m1, *__m2))
+                break;
+            ++__m1;
+            ++__m2;
+        case 2:
+            if (!__pred(*__m1, *__m2))
+                break;
+            ++__m1;
+            ++__m2;
+        case 1:
+            if (!__pred(*__m1, *__m2))
+                break;
+        case 0:
+            return __first1;
+        }
+    __continue:
+        ++__first1;
+#endif  // !_LIBCPP_UNROLL_LOOPS
+    }
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+       _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred)
+{
+    return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>
+                         (__first1, __last1, __first2, __last2, __pred,
+                          typename std::iterator_traits<_ForwardIterator1>::iterator_category(),
+                          typename std::iterator_traits<_ForwardIterator2>::iterator_category());
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator1
+search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
+       _ForwardIterator2 __first2, _ForwardIterator2 __last2)
+{
+    typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1;
+    typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2;
+    return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>());
+}
+
+// search_n
+
+template <class _BinaryPredicate, class _ForwardIterator, class _Size, class _Tp>
+_ForwardIterator
+__search_n(_ForwardIterator __first, _ForwardIterator __last,
+           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, forward_iterator_tag)
+{
+    if (__count <= 0)
+        return __first;
+    while (true)
+    {
+        // Find first element in sequence that matchs __value_, with a mininum of loop checks
+        while (true)
+        {
+            if (__first == __last)  // return __last if no element matches __value_
+                return __last;
+            if (__pred(*__first, __value_))
+                break;
+            ++__first;
+        }
+        // *__first matches __value_, now match elements after here
+        _ForwardIterator __m = __first;
+        _Size __c(0);
+        while (true)
+        {
+            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)
+                return __first;
+            if (++__m == __last)  // Otherwise if source exhaused, pattern not found
+                return __last;
+            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first
+            {
+                __first = __m;
+                ++__first;
+                break;
+            }  // else there is a match, check next elements
+        }
+    }
+}
+
+template <class _BinaryPredicate, class _RandomAccessIterator, class _Size, class _Tp>
+_RandomAccessIterator
+__search_n(_RandomAccessIterator __first, _RandomAccessIterator __last,
+           _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag)
+{
+    if (__count <= 0)
+        return __first;
+    _Size __len = static_cast<_Size>(__last - __first);
+    if (__len < __count)
+        return __last;
+    const _RandomAccessIterator __s = __last - (__count - 1);  // Start of pattern match can't go beyond here
+    while (true)
+    {
+        // Find first element in sequence that matchs __value_, with a mininum of loop checks
+        while (true)
+        {
+            if (__first >= __s)  // return __last if no element matches __value_
+                return __last;
+            if (__pred(*__first, __value_))
+                break;
+            ++__first;
+        }
+        // *__first matches __value_, now match elements after here
+        _RandomAccessIterator __m = __first;
+        _Size __c(0);
+        while (true)
+        {
+            if (++__c == __count)  // If pattern exhausted, __first is the answer (works for 1 element pattern)
+                return __first;
+             ++__m;          // no need to check range on __m because __s guarantees we have enough source
+            if (!__pred(*__m, __value_))  // if there is a mismatch, restart with a new __first
+            {
+                __first = __m;
+                ++__first;
+                break;
+            }  // else there is a match, check next elements
+        }
+    }
+}
+
+template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+search_n(_ForwardIterator __first, _ForwardIterator __last,
+         _Size __count, const _Tp& __value_, _BinaryPredicate __pred)
+{
+    return _VSTD::__search_n<typename add_lvalue_reference<_BinaryPredicate>::type>
+           (__first, __last, __count, __value_, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+template <class _ForwardIterator, class _Size, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value_)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+    return _VSTD::search_n(__first, __last, __count, __value_, __equal_to<__v, _Tp>());
+}
+
+// copy
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator
+{
+    static const bool value = is_pointer<_Iter>::value;
+};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<move_iterator<_Iter> >
+{
+    static const bool value = is_pointer<_Iter>::value;
+};
+
+template <class _Iter>
+struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> >
+{
+    static const bool value = is_pointer<_Iter>::value;
+};
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+_Iter
+__unwrap_iter(_Iter __i)
+{
+    return __i;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_trivially_copy_assignable<_Tp>::value,
+    _Tp*
+>::type
+__unwrap_iter(move_iterator<_Tp*> __i)
+{
+    return __i.base();
+}
+
+#if _LIBCPP_DEBUG_LEVEL < 2
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_trivially_copy_assignable<_Tp>::value,
+    _Tp*
+>::type
+__unwrap_iter(__wrap_iter<_Tp*> __i)
+{
+    return __i.base();
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL < 2
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__first, ++__result)
+        *__result = *__first;
+    return __result;
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__copy(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result + __n;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+}
+
+// copy_backward
+
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    while (__first != __last)
+        *--__result = *--__last;
+    return __result;
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    __result -= __n;
+    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result;
+}
+
+template <class _BidirectionalIterator1, class _BidirectionalIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_BidirectionalIterator2
+copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
+              _BidirectionalIterator2 __result)
+{
+    return _VSTD::__copy_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+}
+
+// copy_if
+
+template<class _InputIterator, class _OutputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+copy_if(_InputIterator __first, _InputIterator __last,
+        _OutputIterator __result, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (__pred(*__first))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+// copy_n
+
+template<class _InputIterator, class _Size, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_input_iterator<_InputIterator>::value &&
+   !__is_random_access_iterator<_InputIterator>::value,
+    _OutputIterator
+>::type
+copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
+{
+    if (__n > 0)
+    {
+        *__result = *__first;
+        ++__result;
+        for (--__n; __n > 0; --__n)
+        {
+            ++__first;
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+template<class _InputIterator, class _Size, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_random_access_iterator<_InputIterator>::value,
+    _OutputIterator
+>::type
+copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
+{
+    return _VSTD::copy(__first, __first + __n, __result);
+}
+
+// move
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__first, ++__result)
+        *__result = _VSTD::move(*__first);
+    return __result;
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__move(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result + __n;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+move(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    return _VSTD::__move(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+}
+
+// move_backward
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__move_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    while (__first != __last)
+        *--__result = _VSTD::move(*--__last);
+    return __result;
+}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_same<typename remove_const<_Tp>::type, _Up>::value &&
+    is_trivially_copy_assignable<_Up>::value,
+    _Up*
+>::type
+__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
+{
+    const size_t __n = static_cast<size_t>(__last - __first);
+    __result -= __n;
+    _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+    return __result;
+}
+
+template <class _BidirectionalIterator1, class _BidirectionalIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_BidirectionalIterator2
+move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last,
+              _BidirectionalIterator2 __result)
+{
+    return _VSTD::__move_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result));
+}
+
+// iter_swap
+
+// moved to <type_traits> for better swap / noexcept support
+
+// transform
+
+template <class _InputIterator, class _OutputIterator, class _UnaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
+{
+    for (; __first != __last; ++__first, ++__result)
+        *__result = __op(*__first);
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _BinaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
+          _OutputIterator __result, _BinaryOperation __binary_op)
+{
+    for (; __first1 != __last1; ++__first1, ++__first2, ++__result)
+        *__result = __binary_op(*__first1, *__first2);
+    return __result;
+}
+
+// replace
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first)
+        if (*__first == __old_value)
+            *__first = __new_value;
+}
+
+// replace_if
+
+template <class _ForwardIterator, class _Predicate, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            *__first = __new_value;
+}
+
+// replace_copy
+
+template <class _InputIterator, class _OutputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+             const _Tp& __old_value, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first, ++__result)
+        if (*__first == __old_value)
+            *__result = __new_value;
+        else
+            *__result = *__first;
+    return __result;
+}
+
+// replace_copy_if
+
+template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+                _Predicate __pred, const _Tp& __new_value)
+{
+    for (; __first != __last; ++__first, ++__result)
+        if (__pred(*__first))
+            *__result = __new_value;
+        else
+            *__result = *__first;
+    return __result;
+}
+
+// fill_n
+
+template <class _OutputIterator, class _Size, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+{
+    for (; __n > 0; ++__first, --__n)
+        *__first = __value_;
+    return __first;
+}
+
+template <class _Tp, class _Size, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && sizeof(_Tp) == 1 &&
+    !is_same<_Tp, bool>::value &&
+    is_integral<_Up>::value && sizeof(_Up) == 1,
+    _Tp*
+>::type
+__fill_n(_Tp* __first, _Size __n,_Up __value_)
+{
+    if (__n > 0)
+        _VSTD::memset(__first, (unsigned char)__value_, (size_t)(__n));
+    return __first + __n;
+}
+
+template <class _OutputIterator, class _Size, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+fill_n(_OutputIterator __first, _Size __n, const _Tp& __value_)
+{
+   return _VSTD::__fill_n(__first, __n, __value_);
+}
+
+// fill
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, forward_iterator_tag)
+{
+    for (; __first != __last; ++__first)
+        *__first = __value_;
+}
+
+template <class _RandomAccessIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value_, random_access_iterator_tag)
+{
+    _VSTD::fill_n(__first, __last - __first, __value_);
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    _VSTD::__fill(__first, __last, __value_, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+// generate
+
+template <class _ForwardIterator, class _Generator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen)
+{
+    for (; __first != __last; ++__first)
+        *__first = __gen();
+}
+
+// generate_n
+
+template <class _OutputIterator, class _Size, class _Generator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
+{
+    for (; __n > 0; ++__first, --__n)
+        *__first = __gen();
+    return __first;
+}
+
+// remove
+
+template <class _ForwardIterator, class _Tp>
+_ForwardIterator
+remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    __first = _VSTD::find(__first, __last, __value_);
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (!(*__i == __value_))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+        }
+    }
+    return __first;
+}
+
+// remove_if
+
+template <class _ForwardIterator, class _Predicate>
+_ForwardIterator
+remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    __first = _VSTD::find_if<_ForwardIterator, typename add_lvalue_reference<_Predicate>::type>
+                           (__first, __last, __pred);
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (!__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+        }
+    }
+    return __first;
+}
+
+// remove_copy
+
+template <class _InputIterator, class _OutputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value_)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (!(*__first == __value_))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+// remove_copy_if
+
+template <class _InputIterator, class _OutputIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (!__pred(*__first))
+        {
+            *__result = *__first;
+            ++__result;
+        }
+    }
+    return __result;
+}
+
+// unique
+
+template <class _ForwardIterator, class _BinaryPredicate>
+_ForwardIterator
+unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
+{
+    __first = _VSTD::adjacent_find<_ForwardIterator, typename add_lvalue_reference<_BinaryPredicate>::type>
+                                 (__first, __last, __pred);
+    if (__first != __last)
+    {
+        // ...  a  a  ?  ...
+        //      f     i
+        _ForwardIterator __i = __first;
+        for (++__i; ++__i != __last;)
+            if (!__pred(*__first, *__i))
+                *++__first = _VSTD::move(*__i);
+        ++__first;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+unique(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type __v;
+    return _VSTD::unique(__first, __last, __equal_to<__v>());
+}
+
+// unique_copy
+
+template <class _BinaryPredicate, class _InputIterator, class _OutputIterator>
+_OutputIterator
+__unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
+              input_iterator_tag, output_iterator_tag)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t(*__first);
+        *__result = __t;
+        ++__result;
+        while (++__first != __last)
+        {
+            if (!__pred(__t, *__first))
+            {
+                __t = *__first;
+                *__result = __t;
+                ++__result;
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _BinaryPredicate, class _ForwardIterator, class _OutputIterator>
+_OutputIterator
+__unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred,
+              forward_iterator_tag, output_iterator_tag)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        *__result = *__i;
+        ++__result;
+        while (++__first != __last)
+        {
+            if (!__pred(*__i, *__first))
+            {
+                *__result = *__first;
+                ++__result;
+                __i = __first;
+            }
+        }
+    }
+    return __result;
+}
+
+template <class _BinaryPredicate, class _InputIterator, class _ForwardIterator>
+_ForwardIterator
+__unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __pred,
+              input_iterator_tag, forward_iterator_tag)
+{
+    if (__first != __last)
+    {
+        *__result = *__first;
+        while (++__first != __last)
+            if (!__pred(*__result, *__first))
+                *++__result = *__first;
+        ++__result;
+    }
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator, class _BinaryPredicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __pred)
+{
+    return _VSTD::__unique_copy<typename add_lvalue_reference<_BinaryPredicate>::type>
+                              (__first, __last, __result, __pred,
+                               typename iterator_traits<_InputIterator>::iterator_category(),
+                               typename iterator_traits<_OutputIterator>::iterator_category());
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    typedef typename iterator_traits<_InputIterator>::value_type __v;
+    return _VSTD::unique_copy(__first, __last, __result, __equal_to<__v>());
+}
+
+// reverse
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
+{
+    while (__first != __last)
+    {
+        if (__first == --__last)
+            break;
+        swap(*__first, *__last);
+        ++__first;
+    }
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
+{
+    if (__first != __last)
+        for (; __first < --__last; ++__first)
+            swap(*__first, *__last);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    _VSTD::__reverse(__first, __last, typename iterator_traits<_BidirectionalIterator>::iterator_category());
+}
+
+// reverse_copy
+
+template <class _BidirectionalIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
+{
+    for (; __first != __last; ++__result)
+        *__result = *--__last;
+    return __result;
+}
+
+// rotate
+
+template <class _ForwardIterator>
+_ForwardIterator
+__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+    value_type __tmp = _VSTD::move(*__first);
+    _ForwardIterator __lm1 = _VSTD::move(_VSTD::next(__first), __last, __first);
+    *__lm1 = _VSTD::move(__tmp);
+    return __lm1;
+}
+
+template <class _BidirectionalIterator>
+_BidirectionalIterator
+__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    _BidirectionalIterator __lm1 = _VSTD::prev(__last);
+    value_type __tmp = _VSTD::move(*__lm1);
+    _BidirectionalIterator __fp1 = _VSTD::move_backward(__first, __lm1, __last);
+    *__first = _VSTD::move(__tmp);
+    return __fp1;
+}
+
+template <class _ForwardIterator>
+_ForwardIterator
+__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
+{
+    _ForwardIterator __i = __middle;
+    while (true)
+    {
+        swap(*__first, *__i);
+        ++__first;
+        if (++__i == __last)
+            break;
+        if (__first == __middle)
+            __middle = __i;
+    }
+    _ForwardIterator __r = __first;
+    if (__first != __middle)
+    {
+        __i = __middle;
+        while (true)
+        {
+            swap(*__first, *__i);
+            ++__first;
+            if (++__i == __last)
+            {
+                if (__first == __middle)
+                    break;
+                __i = __middle;
+            }
+            else if (__first == __middle)
+                __middle = __i;
+        }
+    }
+    return __r;
+}
+
+template<typename _Integral>
+inline _LIBCPP_INLINE_VISIBILITY
+_Integral
+__gcd(_Integral __x, _Integral __y)
+{
+    do
+    {
+        _Integral __t = __x % __y;
+        __x = __y;
+        __y = __t;
+    } while (__y);
+    return __x;
+}
+
+template<typename _RandomAccessIterator>
+_RandomAccessIterator
+__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+
+    const difference_type __m1 = __middle - __first;
+    const difference_type __m2 = __last - __middle;
+    if (__m1 == __m2)
+    {
+        _VSTD::swap_ranges(__first, __middle, __middle);
+        return __middle;
+    }
+    const difference_type __g = _VSTD::__gcd(__m1, __m2);
+    for (_RandomAccessIterator __p = __first + __g; __p != __first;)
+    {
+        value_type __t(_VSTD::move(*--__p));
+        _RandomAccessIterator __p1 = __p;
+        _RandomAccessIterator __p2 = __p1 + __m1;
+        do
+        {
+            *__p1 = _VSTD::move(*__p2);
+            __p1 = __p2;
+            const difference_type __d = __last - __p2;
+            if (__m1 < __d)
+                __p2 += __m1;
+            else
+                __p2 = __first + (__m1 - __d);
+        } while (__p2 != __p);
+        *__p1 = _VSTD::move(__t);
+    }
+    return __first + __m2;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+__rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
+         _VSTD::forward_iterator_tag)
+{
+    typedef typename _VSTD::iterator_traits<_ForwardIterator>::value_type value_type;
+    if (_VSTD::is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_BidirectionalIterator
+__rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+         _VSTD::bidirectional_iterator_tag)
+{
+    typedef typename _VSTD::iterator_traits<_BidirectionalIterator>::value_type value_type;
+    if (_VSTD::is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+        if (_VSTD::next(__middle) == __last)
+            return _VSTD::__rotate_right(__first, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_RandomAccessIterator
+__rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+         _VSTD::random_access_iterator_tag)
+{
+    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::value_type value_type;
+    if (_VSTD::is_trivially_move_assignable<value_type>::value)
+    {
+        if (_VSTD::next(__first) == __middle)
+            return _VSTD::__rotate_left(__first, __last);
+        if (_VSTD::next(__middle) == __last)
+            return _VSTD::__rotate_right(__first, __last);
+        return _VSTD::__rotate_gcd(__first, __middle, __last);
+    }
+    return _VSTD::__rotate_forward(__first, __middle, __last);
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
+{
+    if (__first == __middle)
+        return __last;
+    if (__middle == __last)
+        return __first;
+    return _VSTD::__rotate(__first, __middle, __last,
+                           typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+// rotate_copy
+
+template <class _ForwardIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
+{
+    return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result));
+}
+
+// min_element
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+            if (__comp(*__i, *__first))
+                __first = __i;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return __min_element(__first, __last, __comp);
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+min_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return __min_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// min
+
+template <class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+min(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__b, __a) ? __b : __a;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+min(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::min(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+min(initializer_list<_Tp> __t, _Compare __comp)
+{
+    return *__min_element(__t.begin(), __t.end(), __comp);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+min(initializer_list<_Tp> __t)
+{
+    return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+// max_element
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_ForwardIterator
+__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+            if (__comp(*__first, *__i))
+                __first = __i;
+    }
+    return __first;
+}
+
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return __max_element(__first, __last, __comp);
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+max_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return __max_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// max
+
+template <class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+max(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__a, __b) ? __b : __a;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+max(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::max(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+max(initializer_list<_Tp> __t, _Compare __comp)
+{
+    return *__max_element(__t.begin(), __t.end(), __comp);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+max(initializer_list<_Tp> __t)
+{
+    return *__max_element(__t.begin(), __t.end(), __less<_Tp>());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+// minmax_element
+
+template <class _ForwardIterator, class _Compare>
+std::pair<_ForwardIterator, _ForwardIterator>
+minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+  std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first);
+  if (__first != __last)
+  {
+      if (++__first != __last)
+      {
+          if (__comp(*__first, *__result.first))
+              __result.first = __first;
+          else
+              __result.second = __first;
+          while (++__first != __last)
+          {
+              _ForwardIterator __i = __first;
+              if (++__first == __last)
+              {
+                  if (__comp(*__i, *__result.first))
+                      __result.first = __i;
+                  else if (!__comp(*__i, *__result.second))
+                      __result.second = __i;
+                  break;
+              }
+              else
+              {
+                  if (__comp(*__first, *__i))
+                  {
+                      if (__comp(*__first, *__result.first))
+                          __result.first = __first;
+                      if (!__comp(*__i, *__result.second))
+                          __result.second = __i;
+                  }
+                  else
+                  {
+                      if (__comp(*__i, *__result.first))
+                          __result.first = __i;
+                      if (!__comp(*__first, *__result.second))
+                          __result.second = __first;
+                  }
+              }
+          }
+      }
+  }
+  return __result;
+}
+
+template <class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+std::pair<_ForwardIterator, _ForwardIterator>
+minmax_element(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::minmax_element(__first, __last,
+              __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// minmax
+
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<const _Tp&, const _Tp&>
+minmax(const _Tp& __a, const _Tp& __b, _Compare __comp)
+{
+    return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) :
+                              pair<const _Tp&, const _Tp&>(__a, __b);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<const _Tp&, const _Tp&>
+minmax(const _Tp& __a, const _Tp& __b)
+{
+    return _VSTD::minmax(__a, __b, __less<_Tp>());
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Tp, _Tp>
+minmax(initializer_list<_Tp> __t, _Compare __comp)
+{
+    typedef typename initializer_list<_Tp>::const_iterator _Iter;
+    _Iter __first = __t.begin();
+    _Iter __last  = __t.end();
+    std::pair<_Tp, _Tp> __result ( *__first, *__first );
+
+    ++__first;
+    if (__t.size() % 2 == 0)
+    {
+        if (__comp(*__first,  __result.first))
+            __result.first  = *__first;
+        else
+            __result.second = *__first;
+        ++__first;
+    }
+    
+    while (__first != __last)
+    {
+        _Tp __prev = *__first++;
+        if (__comp(__prev, *__first)) {
+            if (__comp(__prev, __result.first))    __result.first  = __prev;
+            if (__comp(__result.second, *__first)) __result.second = *__first;
+            }
+        else {
+            if (__comp(*__first, __result.first)) __result.first  = *__first;
+            if (__comp(__result.second, __prev))  __result.second = __prev;
+            }
+                
+        __first++;
+    }
+    return __result;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<_Tp, _Tp>
+minmax(initializer_list<_Tp> __t)
+{
+    return _VSTD::minmax(__t, __less<_Tp>());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+// random_shuffle
+
+// __independent_bits_engine
+
+template <unsigned long long _Xp, size_t _Rp>
+struct __log2_imp
+{
+    static const size_t value = _Xp & ((unsigned long long)(1) << _Rp) ? _Rp
+                                           : __log2_imp<_Xp, _Rp - 1>::value;
+};
+
+template <unsigned long long _Xp>
+struct __log2_imp<_Xp, 0>
+{
+    static const size_t value = 0;
+};
+
+template <size_t _Rp>
+struct __log2_imp<0, _Rp>
+{
+    static const size_t value = _Rp + 1;
+};
+
+template <class _UI, _UI _Xp>
+struct __log2
+{
+    static const size_t value = __log2_imp<_Xp,
+                                         sizeof(_UI) * __CHAR_BIT__ - 1>::value;
+};
+
+template<class _Engine, class _UIntType>
+class __independent_bits_engine
+{
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    typedef typename _Engine::result_type _Engine_result_type;
+    typedef typename conditional
+        <
+            sizeof(_Engine_result_type) <= sizeof(result_type),
+                result_type,
+                _Engine_result_type
+        >::type _Working_result_type;
+
+    _Engine& __e_;
+    size_t __w_;
+    size_t __w0_;
+    size_t __n_;
+    size_t __n0_;
+    _Working_result_type __y0_;
+    _Working_result_type __y1_;
+    _Engine_result_type __mask0_;
+    _Engine_result_type __mask1_;
+
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
+                                          + _Working_result_type(1);
+#else
+    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
+                                                      + _Working_result_type(1);
+#endif
+    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
+    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
+    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
+
+public:
+    // constructors and seeding functions
+    __independent_bits_engine(_Engine& __e, size_t __w);
+
+    // generating functions
+    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
+
+private:
+    result_type __eval(false_type);
+    result_type __eval(true_type);
+};
+
+template<class _Engine, class _UIntType>
+__independent_bits_engine<_Engine, _UIntType>
+    ::__independent_bits_engine(_Engine& __e, size_t __w)
+        : __e_(__e),
+          __w_(__w)
+{
+    __n_ = __w_ / __m + (__w_ % __m != 0);
+    __w0_ = __w_ / __n_;
+    if (_Rp == 0)
+        __y0_ = _Rp;
+    else if (__w0_ < _WDt)
+        __y0_ = (_Rp >> __w0_) << __w0_;
+    else
+        __y0_ = 0;
+    if (_Rp - __y0_ > __y0_ / __n_)
+    {
+        ++__n_;
+        __w0_ = __w_ / __n_;
+        if (__w0_ < _WDt)
+            __y0_ = (_Rp >> __w0_) << __w0_;
+        else
+            __y0_ = 0;
+    }
+    __n0_ = __n_ - __w_ % __n_;
+    if (__w0_ < _WDt - 1)
+        __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
+    else
+        __y1_ = 0;
+    __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) :
+                          _Engine_result_type(0);
+    __mask1_ = __w0_ < _EDt - 1 ?
+                               _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) :
+                               _Engine_result_type(~0);
+}
+
+template<class _Engine, class _UIntType>
+inline
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(false_type)
+{
+    return static_cast<result_type>(__e_() & __mask0_);
+}
+
+template<class _Engine, class _UIntType>
+_UIntType
+__independent_bits_engine<_Engine, _UIntType>::__eval(true_type)
+{
+    result_type _Sp = 0;
+    for (size_t __k = 0; __k < __n0_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y0_);
+        if (__w0_ < _WDt)
+            _Sp <<= __w0_;
+        else
+            _Sp = 0;
+        _Sp += __u & __mask0_;
+    }
+    for (size_t __k = __n0_; __k < __n_; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y1_);
+        if (__w0_ < _WDt - 1)
+            _Sp <<= __w0_ + 1;
+        else
+            _Sp = 0;
+        _Sp += __u & __mask1_;
+    }
+    return _Sp;
+}
+
+// uniform_int_distribution
+
+template<class _IntType = int>
+class uniform_int_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef uniform_int_distribution distribution_type;
+
+        explicit param_type(result_type __a = 0,
+                            result_type __b = numeric_limits<result_type>::max())
+            : __a_(__a), __b_(__b) {}
+
+        result_type a() const {return __a_;}
+        result_type b() const {return __b_;}
+
+        friend bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    explicit uniform_int_distribution(result_type __a = 0,
+                                      result_type __b = numeric_limits<result_type>::max())
+        : __p_(param_type(__a, __b)) {}
+    explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
+    void reset() {}
+
+    // generating functions
+    template<class _URNG> result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    result_type a() const {return __p_.a();}
+    result_type b() const {return __p_.b();}
+
+    param_type param() const {return __p_;}
+    void param(const param_type& __p) {__p_ = __p;}
+
+    result_type min() const {return a();}
+    result_type max() const {return b();}
+
+    friend bool operator==(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend bool operator!=(const uniform_int_distribution& __x,
+                           const uniform_int_distribution& __y)
+            {return !(__x == __y);}
+};
+
+template<class _IntType>
+template<class _URNG>
+typename uniform_int_distribution<_IntType>::result_type
+uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+{
+    typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t),
+                                            uint32_t, uint64_t>::type _UIntType;
+    const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
+    if (_Rp == 1)
+        return __p.a();
+    const size_t _Dt = numeric_limits<_UIntType>::digits;
+    typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
+    if (_Rp == 0)
+        return static_cast<result_type>(_Eng(__g, _Dt)());
+    size_t __w = _Dt - __clz(_Rp) - 1;
+    if ((_Rp & (_UIntType(~0) >> (_Dt - __w))) != 0)
+        ++__w;
+    _Eng __e(__g, __w);
+    _UIntType __u;
+    do
+    {
+        __u = __e();
+    } while (__u >= _Rp);
+    return static_cast<result_type>(__u + __p.a());
+}
+
+class _LIBCPP_TYPE_VIS __rs_default;
+
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
+
+class _LIBCPP_TYPE_VIS __rs_default
+{
+    static unsigned __c_;
+
+    __rs_default();
+public:
+    typedef uint_fast32_t result_type;
+
+    static const result_type _Min = 0;
+    static const result_type _Max = 0xFFFFFFFF;
+
+    __rs_default(const __rs_default&);
+    ~__rs_default();
+
+    result_type operator()();
+
+    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
+    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
+
+    friend _LIBCPP_FUNC_VIS __rs_default __rs_get();
+};
+
+_LIBCPP_FUNC_VIS __rs_default __rs_get();
+
+template <class _RandomAccessIterator>
+void
+random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _Dp;
+    typedef typename _Dp::param_type _Pp;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        _Dp __uid;
+        __rs_default __g = __rs_get();
+        for (--__last, --__d; __first < __last; ++__first, --__d)
+        {
+            difference_type __i = __uid(__g, _Pp(0, __d));
+            if (__i != difference_type(0))
+                swap(*__first, *(__first + __i));
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _RandomNumberGenerator>
+void
+random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+               _RandomNumberGenerator&& __rand)
+#else
+               _RandomNumberGenerator& __rand)
+#endif
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        for (--__last; __first < __last; ++__first, --__d)
+        {
+            difference_type __i = __rand(__d);
+            swap(*__first, *(__first + __i));
+        }
+    }
+}
+
+template<class _RandomAccessIterator, class _UniformRandomNumberGenerator>
+    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+                 _UniformRandomNumberGenerator&& __g)
+#else
+                 _UniformRandomNumberGenerator& __g)
+#endif
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef uniform_int_distribution<ptrdiff_t> _Dp;
+    typedef typename _Dp::param_type _Pp;
+    difference_type __d = __last - __first;
+    if (__d > 1)
+    {
+        _Dp __uid;
+        for (--__last, --__d; __first < __last; ++__first, --__d)
+        {
+            difference_type __i = __uid(__g, _Pp(0, __d));
+            if (__i != difference_type(0))
+                swap(*__first, *(__first + __i));
+        }
+    }
+}
+
+template <class _InputIterator, class _Predicate>
+bool
+is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+        if (!__pred(*__first))
+            break;
+    for (; __first != __last; ++__first)
+        if (__pred(*__first))
+            return false;
+    return true;
+}
+
+// partition
+
+template <class _Predicate, class _ForwardIterator>
+_ForwardIterator
+__partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag)
+{
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    for (_ForwardIterator __p = __first; ++__p != __last;)
+    {
+        if (__pred(*__p))
+        {
+            swap(*__first, *__p);
+            ++__first;
+        }
+    }
+    return __first;
+}
+
+template <class _Predicate, class _BidirectionalIterator>
+_BidirectionalIterator
+__partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+            bidirectional_iterator_tag)
+{
+    while (true)
+    {
+        while (true)
+        {
+            if (__first == __last)
+                return __first;
+            if (!__pred(*__first))
+                break;
+            ++__first;
+        }
+        do
+        {
+            if (__first == --__last)
+                return __first;
+        } while (!__pred(*__last));
+        swap(*__first, *__last);
+        ++__first;
+    }
+}
+
+template <class _ForwardIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    return _VSTD::__partition<typename add_lvalue_reference<_Predicate>::type>
+                            (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+// partition_copy
+
+template <class _InputIterator, class _OutputIterator1,
+          class _OutputIterator2, class _Predicate>
+pair<_OutputIterator1, _OutputIterator2>
+partition_copy(_InputIterator __first, _InputIterator __last,
+               _OutputIterator1 __out_true, _OutputIterator2 __out_false,
+               _Predicate __pred)
+{
+    for (; __first != __last; ++__first)
+    {
+        if (__pred(*__first))
+        {
+            *__out_true = *__first;
+            ++__out_true;
+        }
+        else
+        {
+            *__out_false = *__first;
+            ++__out_false;
+        }
+    }
+    return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
+}
+
+// partition_point
+
+template<class _ForwardIterator, class _Predicate>
+_ForwardIterator
+partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = __len / 2;
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__pred(*__m))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else
+            __len = __l2;
+    }
+    return __first;
+}
+
+// stable_partition
+
+template <class _Predicate, class _ForwardIterator, class _Distance, class _Pair>
+_ForwardIterator
+__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
+                   _Distance __len, _Pair __p, forward_iterator_tag __fit)
+{
+    // *__first is known to be false
+    // __len >= 1
+    if (__len == 1)
+        return __first;
+    if (__len == 2)
+    {
+        _ForwardIterator __m = __first;
+        if (__pred(*++__m))
+        {
+            swap(*__first, *__m);
+            return __m;
+        }
+        return __first;
+    }
+    if (__len <= __p.second)
+    {   // The buffer is big enough to use
+        typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
+        // Move the falses into the temporary buffer, and the trues to the front of the line
+        // Update __first to always point to the end of the trues
+        value_type* __t = __p.first;
+        ::new(__t) value_type(_VSTD::move(*__first));
+        __d.__incr((value_type*)0);
+        ++__t;
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+            else
+            {
+                ::new(__t) value_type(_VSTD::move(*__i));
+                __d.__incr((value_type*)0);
+                ++__t;
+            }
+        }
+        // All trues now at start of range, all falses in buffer
+        // Move falses back into range, but don't mess up __first which points to first false
+        __i = __first;
+        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)
+            *__i = _VSTD::move(*__t2);
+        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
+        return __first;
+    }
+    // Else not enough buffer, do in place
+    // __len >= 3
+    _ForwardIterator __m = __first;
+    _Distance __len2 = __len / 2;  // __len2 >= 2
+    _VSTD::advance(__m, __len2);
+    // recurse on [__first, __m), *__first know to be false
+    // F?????????????????
+    // f       m         l
+    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
+    _ForwardIterator __first_false = __stable_partition<_PredRef>(__first, __m, __pred, __len2, __p, __fit);
+    // TTTFFFFF??????????
+    // f  ff   m         l
+    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
+    _ForwardIterator __m1 = __m;
+    _ForwardIterator __second_false = __last;
+    _Distance __len_half = __len - __len2;
+    while (__pred(*__m1))
+    {
+        if (++__m1 == __last)
+            goto __second_half_done;
+        --__len_half;
+    }
+    // TTTFFFFFTTTF??????
+    // f  ff   m  m1     l
+    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __fit);
+__second_half_done:
+    // TTTFFFFFTTTTTFFFFF
+    // f  ff   m    sf   l
+    return _VSTD::rotate(__first_false, __m, __second_false);
+    // TTTTTTTTFFFFFFFFFF
+    //         |
+}
+
+struct __return_temporary_buffer
+{
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) const {_VSTD::return_temporary_buffer(__p);}
+};
+
+template <class _Predicate, class _ForwardIterator>
+_ForwardIterator
+__stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
+                   forward_iterator_tag)
+{
+    const unsigned __alloc_limit = 3;  // might want to make this a function of trivial assignment
+    // Either prove all true and return __first or point to first false
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    // We now have a reduced range [__first, __last)
+    // *__first is known to be false
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    pair<value_type*, ptrdiff_t> __p(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len >= __alloc_limit)
+    {
+        __p = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__p.first);
+    }
+    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, __len, __p, forward_iterator_tag());
+}
+
+template <class _Predicate, class _BidirectionalIterator, class _Distance, class _Pair>
+_BidirectionalIterator
+__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+                   _Distance __len, _Pair __p, bidirectional_iterator_tag __bit)
+{
+    // *__first is known to be false
+    // *__last is known to be true
+    // __len >= 2
+    if (__len == 2)
+    {
+        swap(*__first, *__last);
+        return __last;
+    }
+    if (__len == 3)
+    {
+        _BidirectionalIterator __m = __first;
+        if (__pred(*++__m))
+        {
+            swap(*__first, *__m);
+            swap(*__m, *__last);
+            return __last;
+        }
+        swap(*__m, *__last);
+        swap(*__first, *__m);
+        return __m;
+    }
+    if (__len <= __p.second)
+    {   // The buffer is big enough to use
+        typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__p.first, __d);
+        // Move the falses into the temporary buffer, and the trues to the front of the line
+        // Update __first to always point to the end of the trues
+        value_type* __t = __p.first;
+        ::new(__t) value_type(_VSTD::move(*__first));
+        __d.__incr((value_type*)0);
+        ++__t;
+        _BidirectionalIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__pred(*__i))
+            {
+                *__first = _VSTD::move(*__i);
+                ++__first;
+            }
+            else
+            {
+                ::new(__t) value_type(_VSTD::move(*__i));
+                __d.__incr((value_type*)0);
+                ++__t;
+            }
+        }
+        // move *__last, known to be true
+        *__first = _VSTD::move(*__i);
+        __i = ++__first;
+        // All trues now at start of range, all falses in buffer
+        // Move falses back into range, but don't mess up __first which points to first false
+        for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i)
+            *__i = _VSTD::move(*__t2);
+        // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer
+        return __first;
+    }
+    // Else not enough buffer, do in place
+    // __len >= 4
+    _BidirectionalIterator __m = __first;
+    _Distance __len2 = __len / 2;  // __len2 >= 2
+    _VSTD::advance(__m, __len2);
+    // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false
+    // F????????????????T
+    // f       m        l
+    _BidirectionalIterator __m1 = __m;
+    _BidirectionalIterator __first_false = __first;
+    _Distance __len_half = __len2;
+    while (!__pred(*--__m1))
+    {
+        if (__m1 == __first)
+            goto __first_half_done;
+        --__len_half;
+    }
+    // F???TFFF?????????T
+    // f   m1  m        l
+    typedef typename add_lvalue_reference<_Predicate>::type _PredRef;
+    __first_false = __stable_partition<_PredRef>(__first, __m1, __pred, __len_half, __p, __bit);
+__first_half_done:
+    // TTTFFFFF?????????T
+    // f  ff   m        l
+    // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true
+    __m1 = __m;
+    _BidirectionalIterator __second_false = __last;
+    ++__second_false;
+    __len_half = __len - __len2;
+    while (__pred(*__m1))
+    {
+        if (++__m1 == __last)
+            goto __second_half_done;
+        --__len_half;
+    }
+    // TTTFFFFFTTTF?????T
+    // f  ff   m  m1    l
+    __second_false = __stable_partition<_PredRef>(__m1, __last, __pred, __len_half, __p, __bit);
+__second_half_done:
+    // TTTFFFFFTTTTTFFFFF
+    // f  ff   m    sf  l
+    return _VSTD::rotate(__first_false, __m, __second_false);
+    // TTTTTTTTFFFFFFFFFF
+    //         |
+}
+
+template <class _Predicate, class _BidirectionalIterator>
+_BidirectionalIterator
+__stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred,
+                   bidirectional_iterator_tag)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    const difference_type __alloc_limit = 4;  // might want to make this a function of trivial assignment
+    // Either prove all true and return __first or point to first false
+    while (true)
+    {
+        if (__first == __last)
+            return __first;
+        if (!__pred(*__first))
+            break;
+        ++__first;
+    }
+    // __first points to first false, everything prior to __first is already set.
+    // Either prove [__first, __last) is all false and return __first, or point __last to last true
+    do
+    {
+        if (__first == --__last)
+            return __first;
+    } while (!__pred(*__last));
+    // We now have a reduced range [__first, __last]
+    // *__first is known to be false
+    // *__last is known to be true
+    // __len >= 2
+    difference_type __len = _VSTD::distance(__first, __last) + 1;
+    pair<value_type*, ptrdiff_t> __p(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len >= __alloc_limit)
+    {
+        __p = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__p.first);
+    }
+    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, __len, __p, bidirectional_iterator_tag());
+}
+
+template <class _ForwardIterator, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
+{
+    return __stable_partition<typename add_lvalue_reference<_Predicate>::type>
+                             (__first, __last, __pred, typename iterator_traits<_ForwardIterator>::iterator_category());
+}
+
+// is_sorted_until
+
+template <class _ForwardIterator, class _Compare>
+_ForwardIterator
+is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __i = __first;
+        while (++__i != __last)
+        {
+            if (__comp(*__i, *__first))
+                return __i;
+            __first = __i;
+        }
+    }
+    return __last;
+}
+
+template<class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// is_sorted
+
+template <class _ForwardIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+{
+    return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
+}
+
+template<class _ForwardIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_sorted(_ForwardIterator __first, _ForwardIterator __last)
+{
+    return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// sort
+
+// stable, 2-3 compares, 0-2 swaps
+
+template <class _Compare, class _ForwardIterator>
+unsigned
+__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
+{
+    unsigned __r = 0;
+    if (!__c(*__y, *__x))          // if x <= y
+    {
+        if (!__c(*__z, *__y))      // if y <= z
+            return __r;            // x <= y && y <= z
+                                   // x <= y && y > z
+        swap(*__y, *__z);          // x <= z && y < z
+        __r = 1;
+        if (__c(*__y, *__x))       // if x > y
+        {
+            swap(*__x, *__y);      // x < y && y <= z
+            __r = 2;
+        }
+        return __r;                // x <= y && y < z
+    }
+    if (__c(*__z, *__y))           // x > y, if y > z
+    {
+        swap(*__x, *__z);          // x < y && y < z
+        __r = 1;
+        return __r;
+    }
+    swap(*__x, *__y);              // x > y && y <= z
+    __r = 1;                       // x < y && x <= z
+    if (__c(*__z, *__y))           // if y > z
+    {
+        swap(*__y, *__z);          // x <= y && y < z
+        __r = 2;
+    }
+    return __r;
+}                                  // x <= y && y <= z
+
+// stable, 3-6 compares, 0-5 swaps
+
+template <class _Compare, class _ForwardIterator>
+unsigned
+__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+            _ForwardIterator __x4, _Compare __c)
+{
+    unsigned __r = __sort3<_Compare>(__x1, __x2, __x3, __c);
+    if (__c(*__x4, *__x3))
+    {
+        swap(*__x3, *__x4);
+        ++__r;
+        if (__c(*__x3, *__x2))
+        {
+            swap(*__x2, *__x3);
+            ++__r;
+            if (__c(*__x2, *__x1))
+            {
+                swap(*__x1, *__x2);
+                ++__r;
+            }
+        }
+    }
+    return __r;
+}
+
+// stable, 4-10 compares, 0-9 swaps
+
+template <class _Compare, class _ForwardIterator>
+unsigned
+__sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3,
+            _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c)
+{
+    unsigned __r = __sort4<_Compare>(__x1, __x2, __x3, __x4, __c);
+    if (__c(*__x5, *__x4))
+    {
+        swap(*__x4, *__x5);
+        ++__r;
+        if (__c(*__x4, *__x3))
+        {
+            swap(*__x3, *__x4);
+            ++__r;
+            if (__c(*__x3, *__x2))
+            {
+                swap(*__x2, *__x3);
+                ++__r;
+                if (__c(*__x2, *__x1))
+                {
+                    swap(*__x1, *__x2);
+                    ++__r;
+                }
+            }
+        }
+    }
+    return __r;
+}
+
+// Assumes size > 0
+template <class _Compare, class _BirdirectionalIterator>
+void
+__selection_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)
+{
+    _BirdirectionalIterator __lm1 = __last;
+    for (--__lm1; __first != __lm1; ++__first)
+    {
+        _BirdirectionalIterator __i = _VSTD::min_element<_BirdirectionalIterator,
+                                                        typename add_lvalue_reference<_Compare>::type>
+                                                       (__first, __last, __comp);
+        if (__i != __first)
+            swap(*__first, *__i);
+    }
+}
+
+template <class _Compare, class _BirdirectionalIterator>
+void
+__insertion_sort(_BirdirectionalIterator __first, _BirdirectionalIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;
+    if (__first != __last)
+    {
+        _BirdirectionalIterator __i = __first;
+        for (++__i; __i != __last; ++__i)
+        {
+            _BirdirectionalIterator __j = __i;
+            value_type __t(_VSTD::move(*__j));
+            for (_BirdirectionalIterator __k = __i; __k != __first && __comp(__t,  *--__k); --__j)
+                *__j = _VSTD::move(*__k);
+            *__j = _VSTD::move(__t);
+        }
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    _RandomAccessIterator __j = __first+2;
+    __sort3<_Compare>(__first, __first+1, __j, __comp);
+    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__j))
+        {
+            value_type __t(_VSTD::move(*__i));
+            _RandomAccessIterator __k = __j;
+            __j = __i;
+            do
+            {
+                *__j = _VSTD::move(*__k);
+                __j = __k;
+            } while (__j != __first && __comp(__t, *--__k));
+            *__j = _VSTD::move(__t);
+        }
+        __j = __i;
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+bool
+__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    switch (__last - __first)
+    {
+    case 0:
+    case 1:
+        return true;
+    case 2:
+        if (__comp(*--__last, *__first))
+            swap(*__first, *__last);
+        return true;
+    case 3:
+        _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
+        return true;
+    case 4:
+        _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
+        return true;
+    case 5:
+        _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
+        return true;
+    }
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    _RandomAccessIterator __j = __first+2;
+    __sort3<_Compare>(__first, __first+1, __j, __comp);
+    const unsigned __limit = 8;
+    unsigned __count = 0;
+    for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__j))
+        {
+            value_type __t(_VSTD::move(*__i));
+            _RandomAccessIterator __k = __j;
+            __j = __i;
+            do
+            {
+                *__j = _VSTD::move(*__k);
+                __j = __k;
+            } while (__j != __first && __comp(__t, *--__k));
+            *__j = _VSTD::move(__t);
+            if (++__count == __limit)
+                return ++__i == __last;
+        }
+        __j = __i;
+    }
+    return true;
+}
+
+template <class _Compare, class _BirdirectionalIterator>
+void
+__insertion_sort_move(_BirdirectionalIterator __first1, _BirdirectionalIterator __last1,
+                      typename iterator_traits<_BirdirectionalIterator>::value_type* __first2, _Compare __comp)
+{
+    typedef typename iterator_traits<_BirdirectionalIterator>::value_type value_type;
+    if (__first1 != __last1)
+    {
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h(__first2, __d);
+        value_type* __last2 = __first2;
+        ::new(__last2) value_type(_VSTD::move(*__first1));
+        __d.__incr((value_type*)0);
+        for (++__last2; ++__first1 != __last1; ++__last2)
+        {
+            value_type* __j2 = __last2;
+            value_type* __i2 = __j2;
+            if (__comp(*__first1, *--__i2))
+            {
+                ::new(__j2) value_type(_VSTD::move(*__i2));
+                __d.__incr((value_type*)0);
+                for (--__j2; __i2 != __first2 && __comp(*__first1,  *--__i2); --__j2)
+                    *__j2 = _VSTD::move(*__i2);
+                *__j2 = _VSTD::move(*__first1);
+            }
+            else
+            {
+                ::new(__j2) value_type(_VSTD::move(*__first1));
+                __d.__incr((value_type*)0);
+            }
+        }
+        __h.release();
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    // _Compare is known to be a reference type
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    const difference_type __limit = is_trivially_copy_constructible<value_type>::value &&
+                                    is_trivially_copy_assignable<value_type>::value ? 30 : 6;
+    while (true)
+    {
+    __restart:
+        difference_type __len = __last - __first;
+        switch (__len)
+        {
+        case 0:
+        case 1:
+            return;
+        case 2:
+            if (__comp(*--__last, *__first))
+                swap(*__first, *__last);
+            return;
+        case 3:
+            _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp);
+            return;
+        case 4:
+            _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp);
+            return;
+        case 5:
+            _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp);
+            return;
+        }
+        if (__len <= __limit)
+        {
+            _VSTD::__insertion_sort_3<_Compare>(__first, __last, __comp);
+            return;
+        }
+        // __len > 5
+        _RandomAccessIterator __m = __first;
+        _RandomAccessIterator __lm1 = __last;
+        --__lm1;
+        unsigned __n_swaps;
+        {
+        difference_type __delta;
+        if (__len >= 1000)
+        {
+            __delta = __len/2;
+            __m += __delta;
+            __delta /= 2;
+            __n_swaps = _VSTD::__sort5<_Compare>(__first, __first + __delta, __m, __m+__delta, __lm1, __comp);
+        }
+        else
+        {
+            __delta = __len/2;
+            __m += __delta;
+            __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, __lm1, __comp);
+        }
+        }
+        // *__m is median
+        // partition [__first, __m) < *__m and *__m <= [__m, __last)
+        // (this inhibits tossing elements equivalent to __m around unnecessarily)
+        _RandomAccessIterator __i = __first;
+        _RandomAccessIterator __j = __lm1;
+        // j points beyond range to be tested, *__m is known to be <= *__lm1
+        // The search going up is known to be guarded but the search coming down isn't.
+        // Prime the downward search with a guard.
+        if (!__comp(*__i, *__m))  // if *__first == *__m
+        {
+            // *__first == *__m, *__first doesn't go in first part
+            // manually guard downward moving __j against __i
+            while (true)
+            {
+                if (__i == --__j)
+                {
+                    // *__first == *__m, *__m <= all other elements
+                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
+                    ++__i;  // __first + 1
+                    __j = __last;
+                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
+                    {
+                        while (true)
+                        {
+                            if (__i == __j)
+                                return;  // [__first, __last) all equivalent elements
+                            if (__comp(*__first, *__i))
+                            {
+                                swap(*__i, *__j);
+                                ++__n_swaps;
+                                ++__i;
+                                break;
+                            }
+                            ++__i;
+                        }
+                    }
+                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+                    if (__i == __j)
+                        return;
+                    while (true)
+                    {
+                        while (!__comp(*__first, *__i))
+                            ++__i;
+                        while (__comp(*__first, *--__j))
+                            ;
+                        if (__i >= __j)
+                            break;
+                        swap(*__i, *__j);
+                        ++__n_swaps;
+                        ++__i;
+                    }
+                    // [__first, __i) == *__first and *__first < [__i, __last)
+                    // The first part is sorted, sort the secod part
+                    // _VSTD::__sort<_Compare>(__i, __last, __comp);
+                    __first = __i;
+                    goto __restart;
+                }
+                if (__comp(*__j, *__m))
+                {
+                    swap(*__i, *__j);
+                    ++__n_swaps;
+                    break;  // found guard for downward moving __j, now use unguarded partition
+                }
+            }
+        }
+        // It is known that *__i < *__m
+        ++__i;
+        // j points beyond range to be tested, *__m is known to be <= *__lm1
+        // if not yet partitioned...
+        if (__i < __j)
+        {
+            // known that *(__i - 1) < *__m
+            // known that __i <= __m
+            while (true)
+            {
+                // __m still guards upward moving __i
+                while (__comp(*__i, *__m))
+                    ++__i;
+                // It is now known that a guard exists for downward moving __j
+                while (!__comp(*--__j, *__m))
+                    ;
+                if (__i > __j)
+                    break;
+                swap(*__i, *__j);
+                ++__n_swaps;
+                // It is known that __m != __j
+                // If __m just moved, follow it
+                if (__m == __i)
+                    __m = __j;
+                ++__i;
+            }
+        }
+        // [__first, __i) < *__m and *__m <= [__i, __last)
+        if (__i != __m && __comp(*__m, *__i))
+        {
+            swap(*__i, *__m);
+            ++__n_swaps;
+        }
+        // [__first, __i) < *__i and *__i <= [__i+1, __last)
+        // If we were given a perfect partition, see if insertion sort is quick...
+        if (__n_swaps == 0)
+        {
+            bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp);
+            if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp))
+            {
+                if (__fs)
+                    return;
+                __last = __i;
+                continue;
+            }
+            else
+            {
+                if (__fs)
+                {
+                    __first = ++__i;
+                    continue;
+                }
+            }
+        }
+        // sort smaller range with recursive call and larger with tail recursion elimination
+        if (__i - __first < __last - __i)
+        {
+            _VSTD::__sort<_Compare>(__first, __i, __comp);
+            // _VSTD::__sort<_Compare>(__i+1, __last, __comp);
+            __first = ++__i;
+        }
+        else
+        {
+            _VSTD::__sort<_Compare>(__i+1, __last, __comp);
+            // _VSTD::__sort<_Compare>(__first, __i, __comp);
+            __last = __i;
+        }
+    }
+}
+
+// This forwarder keeps the top call and the recursive calls using the same instantiation, forcing a reference _Compare
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __sort<_Comp_ref>(__first, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __sort<_Comp_ref>(__first, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort(_Tp** __first, _Tp** __last)
+{
+    _VSTD::sort((size_t*)__first, (size_t*)__last, __less<size_t>());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last)
+{
+    _VSTD::sort(__first.base(), __last.base());
+}
+
+template <class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp)
+{
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp);
+}
+
+#ifdef _LIBCPP_MSVC
+#pragma warning( push )
+#pragma warning( disable: 4231)
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&))
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&))
+#ifdef _LIBCPP_MSVC
+#pragma warning( pop )
+#endif  // _LIBCPP_MSVC
+
+// lower_bound
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+_ForwardIterator
+__lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = __len / 2;
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(*__m, __value_))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else
+            __len = __l2;
+    }
+    return __first;
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __lower_bound<_Comp_ref>(__first, __last, __value_, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::lower_bound(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+// upper_bound
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+_ForwardIterator
+__upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = __len / 2;
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(__value_, *__m))
+            __len = __l2;
+        else
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+    }
+    return __first;
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator
+upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::upper_bound(__first, __last, __value_,
+                             __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>());
+}
+
+// equal_range
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+pair<_ForwardIterator, _ForwardIterator>
+__equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
+    difference_type __len = _VSTD::distance(__first, __last);
+    while (__len != 0)
+    {
+        difference_type __l2 = __len / 2;
+        _ForwardIterator __m = __first;
+        _VSTD::advance(__m, __l2);
+        if (__comp(*__m, __value_))
+        {
+            __first = ++__m;
+            __len -= __l2 + 1;
+        }
+        else if (__comp(__value_, *__m))
+        {
+            __last = __m;
+            __len = __l2;
+        }
+        else
+        {
+            _ForwardIterator __mp1 = __m;
+            return pair<_ForwardIterator, _ForwardIterator>
+                   (
+                      __lower_bound<_Compare>(__first, __m, __value_, __comp),
+                      __upper_bound<_Compare>(++__mp1, __last, __value_, __comp)
+                   );
+        }
+    }
+    return pair<_ForwardIterator, _ForwardIterator>(__first, __first);
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_ForwardIterator, _ForwardIterator>
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __equal_range<_Comp_ref>(__first, __last, __value_, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __equal_range<_Comp_ref>(__first, __last, __value_, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_ForwardIterator, _ForwardIterator>
+equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::equal_range(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+// binary_search
+
+template <class _Compare, class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+    __first = __lower_bound<_Compare>(__first, __last, __value_, __comp);
+    return __first != __last && !__comp(__value_, *__first);
+}
+
+template <class _ForwardIterator, class _Tp, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __binary_search<_Comp_ref>(__first, __last, __value_, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __binary_search<_Comp_ref>(__first, __last, __value_, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_)
+{
+    return _VSTD::binary_search(__first, __last, __value_,
+                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
+}
+
+// merge
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_OutputIterator
+__merge(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = *__first2;
+            ++__first2;
+        }
+        else
+        {
+            *__result = *__first1;
+            ++__first1;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+merge(_InputIterator1 __first1, _InputIterator1 __last1,
+      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+merge(_InputIterator1 __first1, _InputIterator1 __last1,
+      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type __v1;
+    typedef typename iterator_traits<_InputIterator2>::value_type __v2;
+    return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>());
+}
+
+// inplace_merge
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
+                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
+                typename iterator_traits<_BidirectionalIterator>::value_type* __buff)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::pointer pointer;
+    __destruct_n __d(0);
+    unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
+    if (__len1 <= __len2)
+    {
+        value_type* __p = __buff;
+        for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), ++__i, ++__p)
+            ::new(__p) value_type(_VSTD::move(*__i));
+        __merge<_Compare>(move_iterator<value_type*>(__buff),
+                          move_iterator<value_type*>(__p),
+                          move_iterator<_BidirectionalIterator>(__middle),
+                          move_iterator<_BidirectionalIterator>(__last),
+                          __first, __comp);
+    }
+    else
+    {
+        value_type* __p = __buff;
+        for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), ++__i, ++__p)
+            ::new(__p) value_type(_VSTD::move(*__i));
+        typedef reverse_iterator<_BidirectionalIterator> _RBi;
+        typedef reverse_iterator<value_type*> _Rv;
+        __merge(move_iterator<_RBi>(_RBi(__middle)), move_iterator<_RBi>(_RBi(__first)),
+                move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)),
+                _RBi(__last), __negate<_Compare>(__comp));
+    }
+}
+
+template <class _Compare, class _BidirectionalIterator>
+void
+__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+                _Compare __comp, typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
+                                 typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
+                typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    while (true)
+    {
+        // if __middle == __last, we're done
+        if (__len2 == 0)
+            return;
+        // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
+        for (; true; ++__first, --__len1)
+        {
+            if (__len1 == 0)
+                return;
+            if (__comp(*__middle, *__first))
+                break;
+        }
+        if (__len1 <= __buff_size || __len2 <= __buff_size)
+        {
+            __buffered_inplace_merge<_Compare>(__first, __middle, __last, __comp, __len1, __len2, __buff);
+            return;
+        }
+        // __first < __middle < __last
+        // *__first > *__middle
+        // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
+        //     all elements in:
+        //         [__first, __m1)  <= [__middle, __m2)
+        //         [__middle, __m2) <  [__m1, __middle)
+        //         [__m1, __middle) <= [__m2, __last)
+        //     and __m1 or __m2 is in the middle of its range
+        _BidirectionalIterator __m1;  // "median" of [__first, __middle)
+        _BidirectionalIterator __m2;  // "median" of [__middle, __last)
+        difference_type __len11;      // distance(__first, __m1)
+        difference_type __len21;      // distance(__middle, __m2)
+        // binary search smaller range
+        if (__len1 < __len2)
+        {   // __len >= 1, __len2 >= 2
+            __len21 = __len2 / 2;
+            __m2 = __middle;
+            _VSTD::advance(__m2, __len21);
+            __m1 = __upper_bound<_Compare>(__first, __middle, *__m2, __comp);
+            __len11 = _VSTD::distance(__first, __m1);
+        }
+        else
+        {
+            if (__len1 == 1)
+            {   // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
+                // It is known *__first > *__middle
+                swap(*__first, *__middle);
+                return;
+            }
+            // __len1 >= 2, __len2 >= 1
+            __len11 = __len1 / 2;
+            __m1 = __first;
+            _VSTD::advance(__m1, __len11);
+            __m2 = __lower_bound<_Compare>(__middle, __last, *__m1, __comp);
+            __len21 = _VSTD::distance(__middle, __m2);
+        }
+        difference_type __len12 = __len1 - __len11;  // distance(__m1, __middle)
+        difference_type __len22 = __len2 - __len21;  // distance(__m2, __last)
+        // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
+        // swap middle two partitions
+        __middle = _VSTD::rotate(__m1, __middle, __m2);
+        // __len12 and __len21 now have swapped meanings
+        // merge smaller range with recurisve call and larger with tail recursion elimination
+        if (__len11 + __len21 < __len12 + __len22)
+        {
+            __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
+//          __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
+            __first = __middle;
+            __middle = __m2;
+            __len1 = __len12;
+            __len2 = __len22;
+        }
+        else
+        {
+            __inplace_merge<_Compare>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
+//          __inplace_merge<_Compare>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
+            __last = __middle;
+            __middle = __m1;
+            __len1 = __len11;
+            __len2 = __len21;
+        }
+    }
+}
+
+template <class _Tp>
+struct __inplace_merge_switch
+{
+    static const unsigned value = is_trivially_copy_assignable<_Tp>::value;
+};
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
+              _Compare __comp)
+{
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    difference_type __len1 = _VSTD::distance(__first, __middle);
+    difference_type __len2 = _VSTD::distance(__middle, __last);
+    difference_type __buf_size = _VSTD::min(__len1, __len2);
+    pair<value_type*, ptrdiff_t> __buf(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__inplace_merge_switch<value_type>::value && __buf_size > 8)
+    {
+        __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size);
+        __h.reset(__buf.first);
+    }
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2,
+                                            __buf.first, __buf.second);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2,
+                                            __buf.first, __buf.second);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last)
+{
+    _VSTD::inplace_merge(__first, __middle, __last,
+                        __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+// stable_sort
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+void
+__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2,
+        typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp)
+{
+    typedef typename iterator_traits<_InputIterator1>::value_type value_type;
+    __destruct_n __d(0);
+    unique_ptr<value_type, __destruct_n&> __h(__result, __d);
+    for (; true; ++__result)
+    {
+        if (__first1 == __last1)
+        {
+            for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0))
+                ::new (__result) value_type(_VSTD::move(*__first2));
+            __h.release();
+            return;
+        }
+        if (__first2 == __last2)
+        {
+            for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0))
+                ::new (__result) value_type(_VSTD::move(*__first1));
+            __h.release();
+            return;
+        }
+        if (__comp(*__first2, *__first1))
+        {
+            ::new (__result) value_type(_VSTD::move(*__first2));
+            __d.__incr((value_type*)0);
+            ++__first2;
+        }
+        else
+        {
+            ::new (__result) value_type(_VSTD::move(*__first1));
+            __d.__incr((value_type*)0);
+            ++__first1;
+        }
+    }
+}
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+void
+__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1,
+        _InputIterator2 __first2, _InputIterator2 __last2,
+        _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+        {
+            for (; __first1 != __last1; ++__first1, ++__result)
+                *__result = _VSTD::move(*__first1);
+            return;
+        }
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = _VSTD::move(*__first2);
+            ++__first2;
+        }
+        else
+        {
+            *__result = _VSTD::move(*__first1);
+            ++__first1;
+        }
+    }
+    for (; __first2 != __last2; ++__first2, ++__result)
+        *__result = _VSTD::move(*__first2);
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size);
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp,
+                   typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+                   typename iterator_traits<_RandomAccessIterator>::value_type* __first2)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    switch (__len)
+    {
+    case 0:
+        return;
+    case 1:
+        ::new(__first2) value_type(_VSTD::move(*__first1));
+        return;
+    case 2:
+       __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h2(__first2, __d);
+         if (__comp(*--__last1, *__first1))
+        {
+            ::new(__first2) value_type(_VSTD::move(*__last1));
+            __d.__incr((value_type*)0);
+            ++__first2;
+            ::new(__first2) value_type(_VSTD::move(*__first1));
+        }
+        else
+        {
+            ::new(__first2) value_type(_VSTD::move(*__first1));
+            __d.__incr((value_type*)0);
+            ++__first2;
+            ::new(__first2) value_type(_VSTD::move(*__last1));
+        }
+        __h2.release();
+        return;
+    }
+    if (__len <= 8)
+    {
+        __insertion_sort_move<_Compare>(__first1, __last1, __first2, __comp);
+        return;
+    }
+    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
+    _RandomAccessIterator __m = __first1 + __l2;
+    __stable_sort<_Compare>(__first1, __m, __comp, __l2, __first2, __l2);
+    __stable_sort<_Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2);
+    __merge_move_construct<_Compare>(__first1, __m, __m, __last1, __first2, __comp);
+}
+
+template <class _Tp>
+struct __stable_sort_switch
+{
+    static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value;
+};
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+              typename iterator_traits<_RandomAccessIterator>::difference_type __len,
+              typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    switch (__len)
+    {
+    case 0:
+    case 1:
+        return;
+    case 2:
+        if (__comp(*--__last, *__first))
+            swap(*__first, *__last);
+        return;
+    }
+    if (__len <= static_cast<difference_type>(__stable_sort_switch<value_type>::value))
+    {
+        __insertion_sort<_Compare>(__first, __last, __comp);
+        return;
+    }
+    typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2;
+    _RandomAccessIterator __m = __first + __l2;
+    if (__len <= __buff_size)
+    {
+        __destruct_n __d(0);
+        unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
+        __stable_sort_move<_Compare>(__first, __m, __comp, __l2, __buff);
+        __d.__set(__l2, (value_type*)0);
+        __stable_sort_move<_Compare>(__m, __last, __comp, __len - __l2, __buff + __l2);
+        __d.__set(__len, (value_type*)0);
+        __merge_move_assign<_Compare>(__buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp);
+//         __merge<_Compare>(move_iterator<value_type*>(__buff),
+//                           move_iterator<value_type*>(__buff + __l2),
+//                           move_iterator<_RandomAccessIterator>(__buff + __l2),
+//                           move_iterator<_RandomAccessIterator>(__buff + __len),
+//                           __first, __comp);
+        return;
+    }
+    __stable_sort<_Compare>(__first, __m, __comp, __l2, __buff, __buff_size);
+    __stable_sort<_Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size);
+    __inplace_merge<_Compare>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __len = __last - __first;
+    pair<value_type*, ptrdiff_t> __buf(0, 0);
+    unique_ptr<value_type, __return_temporary_buffer> __h;
+    if (__len > static_cast<difference_type>(__stable_sort_switch<value_type>::value))
+    {
+        __buf = _VSTD::get_temporary_buffer<value_type>(__len);
+        __h.reset(__buf.first);
+    }
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// is_heap_until
+
+template <class _RandomAccessIterator, class _Compare>
+_RandomAccessIterator
+is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename _VSTD::iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __len = __last - __first;
+    difference_type __p = 0;
+    difference_type __c = 1;
+    _RandomAccessIterator __pp = __first;
+    while (__c < __len)
+    {
+        _RandomAccessIterator __cp = __first + __c;
+        if (__comp(*__pp, *__cp))
+            return __cp;
+        ++__c;
+        ++__cp;
+        if (__c == __len)
+            return __last;
+        if (__comp(*__pp, *__cp))
+            return __cp;
+        ++__p;
+        ++__pp;
+        __c = 2 * __p + 1;
+    }
+    return __last;
+}
+
+template<class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_RandomAccessIterator
+is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// is_heap
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    return _VSTD::is_heap_until(__first, __last, __comp) == __last;
+}
+
+template<class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// push_heap
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__push_heap_front(_RandomAccessIterator __first, _RandomAccessIterator, _Compare __comp,
+                  typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    if (__len > 1)
+    {
+        difference_type __p = 0;
+        _RandomAccessIterator __pp = __first;
+        difference_type __c = 2;
+        _RandomAccessIterator __cp = __first + __c;
+        if (__c == __len || __comp(*__cp, *(__cp - 1)))
+        {
+            --__c;
+            --__cp;
+        }
+        if (__comp(*__pp, *__cp))
+        {
+            value_type __t(_VSTD::move(*__pp));
+            do
+            {
+                *__pp = _VSTD::move(*__cp);
+                __pp = __cp;
+                __p = __c;
+                __c = (__p + 1) * 2;
+                if (__c > __len)
+                    break;
+                __cp = __first + __c;
+                if (__c == __len || __comp(*__cp, *(__cp - 1)))
+                {
+                    --__c;
+                    --__cp;
+                }
+            } while (__comp(__t, *__cp));
+            *__pp = _VSTD::move(__t);
+        }
+    }
+}
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__push_heap_back(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+                 typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
+    if (__len > 1)
+    {
+        __len = (__len - 2) / 2;
+        _RandomAccessIterator __ptr = __first + __len;
+        if (__comp(*__ptr, *--__last))
+        {
+            value_type __t(_VSTD::move(*__last));
+            do
+            {
+                *__last = _VSTD::move(*__ptr);
+                __last = __ptr;
+                if (__len == 0)
+                    break;
+                __len = (__len - 1) / 2;
+                __ptr = __first + __len;
+            } while (__comp(*__ptr, __t));
+            *__last = _VSTD::move(__t);
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __push_heap_back<_Comp_ref>(__first, __last, __c, __last - __first);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __push_heap_back<_Comp_ref>(__first, __last, __comp, __last - __first);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::push_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// pop_heap
+
+template <class _Compare, class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+           typename iterator_traits<_RandomAccessIterator>::difference_type __len)
+{
+    if (__len > 1)
+    {
+        swap(*__first, *--__last);
+        __push_heap_front<_Compare>(__first, __last, __comp, __len-1);
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::pop_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// make_heap
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    difference_type __n = __last - __first;
+    if (__n > 1)
+    {
+        __last = __first;
+        ++__last;
+        for (difference_type __i = 1; __i < __n;)
+            __push_heap_back<_Compare>(__first, ++__last, __comp, ++__i);
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __make_heap<_Comp_ref>(__first, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __make_heap<_Comp_ref>(__first, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::make_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// sort_heap
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    for (difference_type __n = __last - __first; __n > 1; --__last, --__n)
+        __pop_heap<_Compare>(__first, __last, __comp, __n);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __sort_heap<_Comp_ref>(__first, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __sort_heap<_Comp_ref>(__first, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    _VSTD::sort_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// partial_sort
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+             _Compare __comp)
+{
+    __make_heap<_Compare>(__first, __middle, __comp);
+    typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
+    for (_RandomAccessIterator __i = __middle; __i != __last; ++__i)
+    {
+        if (__comp(*__i, *__first))
+        {
+            swap(*__i, *__first);
+            __push_heap_front<_Compare>(__first, __middle, __comp, __len);
+        }
+    }
+    __sort_heap<_Compare>(__first, __middle, __comp);
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
+             _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __partial_sort<_Comp_ref>(__first, __middle, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __partial_sort<_Comp_ref>(__first, __middle, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
+{
+    _VSTD::partial_sort(__first, __middle, __last,
+                       __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// partial_sort_copy
+
+template <class _Compare, class _InputIterator, class _RandomAccessIterator>
+_RandomAccessIterator
+__partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                    _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
+{
+    _RandomAccessIterator __r = __result_first;
+    if (__r != __result_last)
+    {
+        typename iterator_traits<_RandomAccessIterator>::difference_type __len = 0;
+        for (; __first != __last && __r != __result_last; ++__first, ++__r, ++__len)
+            *__r = *__first;
+        __make_heap<_Compare>(__result_first, __r, __comp);
+        for (; __first != __last; ++__first)
+            if (__comp(*__first, *__result_first))
+            {
+                *__result_first = *__first;
+                __push_heap_front<_Compare>(__result_first, __r, __comp, __len);
+            }
+        __sort_heap<_Compare>(__result_first, __r, __comp);
+    }
+    return __r;
+}
+
+template <class _InputIterator, class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_RandomAccessIterator
+partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator, class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_RandomAccessIterator
+partial_sort_copy(_InputIterator __first, _InputIterator __last,
+                  _RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
+{
+    return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last,
+                                   __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// nth_element
+
+template <class _Compare, class _RandomAccessIterator>
+void
+__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
+{
+    // _Compare is known to be a reference type
+    typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
+    const difference_type __limit = 7;
+    while (true)
+    {
+    __restart:
+        if (__nth == __last)
+            return;
+        difference_type __len = __last - __first;
+        switch (__len)
+        {
+        case 0:
+        case 1:
+            return;
+        case 2:
+            if (__comp(*--__last, *__first))
+                swap(*__first, *__last);
+            return;
+        case 3:
+            {
+            _RandomAccessIterator __m = __first;
+            _VSTD::__sort3<_Compare>(__first, ++__m, --__last, __comp);
+            return;
+            }
+        }
+        if (__len <= __limit)
+        {
+            __selection_sort<_Compare>(__first, __last, __comp);
+            return;
+        }
+        // __len > __limit >= 3
+        _RandomAccessIterator __m = __first + __len/2;
+        _RandomAccessIterator __lm1 = __last;
+        unsigned __n_swaps = _VSTD::__sort3<_Compare>(__first, __m, --__lm1, __comp);
+        // *__m is median
+        // partition [__first, __m) < *__m and *__m <= [__m, __last)
+        // (this inhibits tossing elements equivalent to __m around unnecessarily)
+        _RandomAccessIterator __i = __first;
+        _RandomAccessIterator __j = __lm1;
+        // j points beyond range to be tested, *__lm1 is known to be <= *__m
+        // The search going up is known to be guarded but the search coming down isn't.
+        // Prime the downward search with a guard.
+        if (!__comp(*__i, *__m))  // if *__first == *__m
+        {
+            // *__first == *__m, *__first doesn't go in first part
+            // manually guard downward moving __j against __i
+            while (true)
+            {
+                if (__i == --__j)
+                {
+                    // *__first == *__m, *__m <= all other elements
+                    // Parition instead into [__first, __i) == *__first and *__first < [__i, __last)
+                    ++__i;  // __first + 1
+                    __j = __last;
+                    if (!__comp(*__first, *--__j))  // we need a guard if *__first == *(__last-1)
+                    {
+                        while (true)
+                        {
+                            if (__i == __j)
+                                return;  // [__first, __last) all equivalent elements
+                            if (__comp(*__first, *__i))
+                            {
+                                swap(*__i, *__j);
+                                ++__n_swaps;
+                                ++__i;
+                                break;
+                            }
+                            ++__i;
+                        }
+                    }
+                    // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+                    if (__i == __j)
+                        return;
+                    while (true)
+                    {
+                        while (!__comp(*__first, *__i))
+                            ++__i;
+                        while (__comp(*__first, *--__j))
+                            ;
+                        if (__i >= __j)
+                            break;
+                        swap(*__i, *__j);
+                        ++__n_swaps;
+                        ++__i;
+                    }
+                    // [__first, __i) == *__first and *__first < [__i, __last)
+                    // The first part is sorted,
+                    if (__nth < __i)
+                        return;
+                    // __nth_element the secod part
+                    // __nth_element<_Compare>(__i, __nth, __last, __comp);
+                    __first = __i;
+                    goto __restart;
+                }
+                if (__comp(*__j, *__m))
+                {
+                    swap(*__i, *__j);
+                    ++__n_swaps;
+                    break;  // found guard for downward moving __j, now use unguarded partition
+                }
+            }
+        }
+        ++__i;
+        // j points beyond range to be tested, *__lm1 is known to be <= *__m
+        // if not yet partitioned...
+        if (__i < __j)
+        {
+            // known that *(__i - 1) < *__m
+            while (true)
+            {
+                // __m still guards upward moving __i
+                while (__comp(*__i, *__m))
+                    ++__i;
+                // It is now known that a guard exists for downward moving __j
+                while (!__comp(*--__j, *__m))
+                    ;
+                if (__i >= __j)
+                    break;
+                swap(*__i, *__j);
+                ++__n_swaps;
+                // It is known that __m != __j
+                // If __m just moved, follow it
+                if (__m == __i)
+                    __m = __j;
+                ++__i;
+            }
+        }
+        // [__first, __i) < *__m and *__m <= [__i, __last)
+        if (__i != __m && __comp(*__m, *__i))
+        {
+            swap(*__i, *__m);
+            ++__n_swaps;
+        }
+        // [__first, __i) < *__i and *__i <= [__i+1, __last)
+        if (__nth == __i)
+            return;
+        if (__n_swaps == 0)
+        {
+            // We were given a perfectly partitioned sequence.  Coincidence?
+            if (__nth < __i)
+            {
+                // Check for [__first, __i) already sorted
+                __j = __m = __first;
+                while (++__j != __i)
+                {
+                    if (__comp(*__j, *__m))
+                        // not yet sorted, so sort
+                        goto not_sorted;
+                    __m = __j;
+                }
+                // [__first, __i) sorted
+                return;
+            }
+            else
+            {
+                // Check for [__i, __last) already sorted
+                __j = __m = __i;
+                while (++__j != __last)
+                {
+                    if (__comp(*__j, *__m))
+                        // not yet sorted, so sort
+                        goto not_sorted;
+                    __m = __j;
+                }
+                // [__i, __last) sorted
+                return;
+            }
+        }
+not_sorted:
+        // __nth_element on range containing __nth
+        if (__nth < __i)
+        {
+            // __nth_element<_Compare>(__first, __nth, __i, __comp);
+            __last = __i;
+        }
+        else
+        {
+            // __nth_element<_Compare>(__i+1, __nth, __last, __comp);
+            __first = ++__i;
+        }
+    }
+}
+
+template <class _RandomAccessIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    __nth_element<_Comp_ref>(__first, __nth, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    __nth_element<_Comp_ref>(__first, __nth, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _RandomAccessIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
+{
+    _VSTD::nth_element(__first, __nth, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
+}
+
+// includes
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+bool
+__includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+           _Compare __comp)
+{
+    for (; __first2 != __last2; ++__first1)
+    {
+        if (__first1 == __last1 || __comp(*__first2, *__first1))
+            return false;
+        if (!__comp(*__first1, *__first2))
+            ++__first2;
+    }
+    return true;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2,
+         _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    return _VSTD::includes(__first1, __last1, __first2, __last2,
+                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// set_union
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_OutputIterator
+__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+            _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    for (; __first1 != __last1; ++__result)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first2, *__first1))
+        {
+            *__result = *__first2;
+            ++__first2;
+        }
+        else
+        {
+            *__result = *__first1;
+            if (!__comp(*__first1, *__first2))
+                ++__first2;
+            ++__first1;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_union(_InputIterator1 __first1, _InputIterator1 __last1,
+          _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_union(__first1, __last1, __first2, __last2, __result,
+                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// set_intersection
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_OutputIterator
+__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                   _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1 && __first2 != __last2)
+    {
+        if (__comp(*__first1, *__first2))
+            ++__first1;
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+            {
+                *__result = *__first1;
+                ++__result;
+                ++__first1;
+            }
+            ++__first2;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_intersection(__first1, __last1, __first2, __last2, __result,
+                                  __less<typename iterator_traits<_InputIterator1>::value_type,
+                                         typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// set_difference
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_OutputIterator
+__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                 _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first1, *__first2))
+        {
+            *__result = *__first1;
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (!__comp(*__first2, *__first1))
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+               _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_difference(__first1, __last1, __first2, __last2, __result,
+                                __less<typename iterator_traits<_InputIterator1>::value_type,
+                                       typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// set_symmetric_difference
+
+template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
+_OutputIterator
+__set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                           _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+    while (__first1 != __last1)
+    {
+        if (__first2 == __last2)
+            return _VSTD::copy(__first1, __last1, __result);
+        if (__comp(*__first1, *__first2))
+        {
+            *__result = *__first1;
+            ++__result;
+            ++__first1;
+        }
+        else
+        {
+            if (__comp(*__first2, *__first1))
+            {
+                *__result = *__first2;
+                ++__result;
+            }
+            else
+                ++__first1;
+            ++__first2;
+        }
+    }
+    return _VSTD::copy(__first2, __last2, __result);
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
+                         _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)
+{
+    return _VSTD::set_symmetric_difference(__first1, __last1, __first2, __last2, __result,
+                                          __less<typename iterator_traits<_InputIterator1>::value_type,
+                                                 typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// lexicographical_compare
+
+template <class _Compare, class _InputIterator1, class _InputIterator2>
+bool
+__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                          _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
+{
+    for (; __first2 != __last2; ++__first1, ++__first2)
+    {
+        if (__first1 == __last1 || __comp(*__first1, *__first2))
+            return true;
+        if (__comp(*__first2, *__first1))
+            return false;
+    }
+    return false;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                        _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _InputIterator1, class _InputIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1,
+                        _InputIterator2 __first2, _InputIterator2 __last2)
+{
+    return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2,
+                                         __less<typename iterator_traits<_InputIterator1>::value_type,
+                                                typename iterator_traits<_InputIterator2>::value_type>());
+}
+
+// next_permutation
+
+template <class _Compare, class _BidirectionalIterator>
+bool
+__next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    _BidirectionalIterator __i = __last;
+    if (__first == __last || __first == --__i)
+        return false;
+    while (true)
+    {
+        _BidirectionalIterator __ip1 = __i;
+        if (__comp(*--__i, *__ip1))
+        {
+            _BidirectionalIterator __j = __last;
+            while (!__comp(*__i, *--__j))
+                ;
+            swap(*__i, *__j);
+            _VSTD::reverse(__ip1, __last);
+            return true;
+        }
+        if (__i == __first)
+        {
+            _VSTD::reverse(__first, __last);
+            return false;
+        }
+    }
+}
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __next_permutation<_Comp_ref>(__first, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __next_permutation<_Comp_ref>(__first, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    return _VSTD::next_permutation(__first, __last,
+                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+// prev_permutation
+
+template <class _Compare, class _BidirectionalIterator>
+bool
+__prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+    _BidirectionalIterator __i = __last;
+    if (__first == __last || __first == --__i)
+        return false;
+    while (true)
+    {
+        _BidirectionalIterator __ip1 = __i;
+        if (__comp(*__ip1, *--__i))
+        {
+            _BidirectionalIterator __j = __last;
+            while (!__comp(*--__j, *__i))
+                ;
+            swap(*__i, *__j);
+            _VSTD::reverse(__ip1, __last);
+            return true;
+        }
+        if (__i == __first)
+        {
+            _VSTD::reverse(__first, __last);
+            return false;
+        }
+    }
+}
+
+template <class _BidirectionalIterator, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
+{
+#ifdef _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
+    __debug_less<_Compare> __c(__comp);
+    return __prev_permutation<_Comp_ref>(__first, __last, __c);
+#else  // _LIBCPP_DEBUG
+    typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
+    return __prev_permutation<_Comp_ref>(__first, __last, __comp);
+#endif  // _LIBCPP_DEBUG
+}
+
+template <class _BidirectionalIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
+{
+    return _VSTD::prev_permutation(__first, __last,
+                                  __less<typename iterator_traits<_BidirectionalIterator>::value_type>());
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    _Tp
+>::type
+__rotate_left(_Tp __t, _Tp __n = 1)
+{
+    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);
+    __n &= __bits;
+    return static_cast<_Tp>((__t << __n) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> (__bits - __n)));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    _Tp
+>::type
+__rotate_right(_Tp __t, _Tp __n = 1)
+{
+    const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1);
+    __n &= __bits;
+    return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> __n));
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_ALGORITHM
diff --git a/include/c++/v1/array b/include/c++/v1/array
new file mode 100644
index 0000000..d37075d
--- /dev/null
+++ b/include/c++/v1/array
@@ -0,0 +1,342 @@
+// -*- C++ -*-
+//===---------------------------- array -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ARRAY
+#define _LIBCPP_ARRAY
+
+/*
+    array synopsis
+
+namespace std
+{
+template <class T, size_t N >
+struct array
+{
+    // types:
+    typedef T & reference;
+    typedef const T & const_reference;
+    typedef implementation defined iterator;
+    typedef implementation defined const_iterator;
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef T value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef std::reverse_iterator<iterator> reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    // No explicit construct/copy/destroy for aggregate type
+    void fill(const T& u);
+    void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
+
+    // iterators:
+    iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+    iterator end() noexcept;
+    const_iterator end() const noexcept;
+
+    reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+    reverse_iterator rend() noexcept;
+    const_reverse_iterator rend() const noexcept;
+
+    const_iterator cbegin() const noexcept;
+    const_iterator cend() const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend() const noexcept;
+
+    // capacity:
+    constexpr size_type size() const noexcept;
+    constexpr size_type max_size() const noexcept;
+    constexpr bool empty() const noexcept;
+
+    // element access:
+    reference operator[](size_type n);
+    const_reference operator[](size_type n) const; // constexpr in C++14
+    const_reference at(size_type n) const; // constexpr in C++14
+    reference at(size_type n);
+
+    reference front();
+    const_reference front() const; // constexpr in C++14
+    reference back();
+    const_reference back() const; // constexpr in C++14
+
+    T* data() noexcept;
+    const T* data() const noexcept;
+};
+
+template <class T, size_t N>
+  bool operator==(const array<T,N>& x, const array<T,N>& y);
+template <class T, size_t N>
+  bool operator!=(const array<T,N>& x, const array<T,N>& y);
+template <class T, size_t N>
+  bool operator<(const array<T,N>& x, const array<T,N>& y);
+template <class T, size_t N>
+  bool operator>(const array<T,N>& x, const array<T,N>& y);
+template <class T, size_t N>
+  bool operator<=(const array<T,N>& x, const array<T,N>& y);
+template <class T, size_t N>
+  bool operator>=(const array<T,N>& x, const array<T,N>& y);
+
+template <class T, size_t N >
+  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));
+
+template <class T> class tuple_size;
+template <int I, class T> class tuple_element;
+template <class T, size_t N> struct tuple_size<array<T, N>>;
+template <int I, class T, size_t N> struct tuple_element<I, array<T, N>>;
+template <int I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
+template <int I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
+template <int I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__tuple>
+#include <type_traits>
+#include <utility>
+#include <iterator>
+#include <algorithm>
+#include <stdexcept>
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, size_t _Size>
+struct _LIBCPP_TYPE_VIS_ONLY array
+{
+    // types:
+    typedef array __self;
+    typedef _Tp                                   value_type;
+    typedef value_type&                           reference;
+    typedef const value_type&                     const_reference;
+    typedef value_type*                           iterator;
+    typedef const value_type*                     const_iterator;
+    typedef value_type*                           pointer;
+    typedef const value_type*                     const_pointer;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef std::reverse_iterator<iterator>       reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    value_type __elems_[_Size > 0 ? _Size : 1];
+
+    // No explicit construct/copy/destroy for aggregate type
+    _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
+        {_VSTD::fill_n(__elems_, _Size, __u);}
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
+        {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
+
+    // iterators:
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT {return iterator(__elems_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    // capacity:
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
+
+    // element access:
+    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference operator[](size_type __n) const {return __elems_[__n];}
+    reference at(size_type __n);
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
+
+    _LIBCPP_INLINE_VISIBILITY reference front()             {return __elems_[0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const {return __elems_[0];}
+    _LIBCPP_INLINE_VISIBILITY reference back()              {return __elems_[_Size > 0 ? _Size-1 : 0];}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  {return __elems_[_Size > 0 ? _Size-1 : 0];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type* data() _NOEXCEPT {return __elems_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type* data() const _NOEXCEPT {return __elems_;}
+};
+
+template <class _Tp, size_t _Size>
+typename array<_Tp, _Size>::reference
+array<_Tp, _Size>::at(size_type __n)
+{
+    if (__n >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("array::at");
+#else
+        assert(!"array::at out_of_range");
+#endif
+    return __elems_[__n];
+}
+
+template <class _Tp, size_t _Size>
+_LIBCPP_CONSTEXPR_AFTER_CXX11
+typename array<_Tp, _Size>::const_reference
+array<_Tp, _Size>::at(size_type __n) const
+{
+    if (__n >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("array::at");
+#else
+        assert(!"array::at out_of_range");
+#endif
+    return __elems_[__n];
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return _VSTD::equal(__x.__elems_, __x.__elems_ + _Size, __y.__elems_);
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.__elems_, __x.__elems_ + _Size, __y.__elems_, __y.__elems_ + _Size);
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_swappable<_Tp>::value,
+    void
+>::type
+swap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
+                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
+{
+    __x.swap(__y);
+}
+
+template <class _Tp, size_t _Size>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
+    : public integral_constant<size_t, _Size> {};
+
+template <class _Tp, size_t _Size>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
+    : public integral_constant<size_t, _Size> {};
+
+template <size_t _Ip, class _Tp, size_t _Size>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
+{
+public:
+    typedef _Tp type;
+};
+
+template <size_t _Ip, class _Tp, size_t _Size>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
+{
+public:
+    typedef const _Tp type;
+};
+
+template <size_t _Ip, class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&
+get(array<_Tp, _Size>& __a) _NOEXCEPT
+{
+    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
+    return __a.__elems_[_Ip];
+}
+
+template <size_t _Ip, class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Tp&
+get(const array<_Tp, _Size>& __a) _NOEXCEPT
+{
+    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
+    return __a.__elems_[_Ip];
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <size_t _Ip, class _Tp, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&&
+get(array<_Tp, _Size>&& __a) _NOEXCEPT
+{
+    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
+    return _VSTD::move(__a.__elems_[_Ip]);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_ARRAY
diff --git a/include/c++/v1/atomic b/include/c++/v1/atomic
new file mode 100644
index 0000000..f6ab1cb
--- /dev/null
+++ b/include/c++/v1/atomic
@@ -0,0 +1,1531 @@
+// -*- C++ -*-
+//===--------------------------- atomic -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ATOMIC
+#define _LIBCPP_ATOMIC
+
+/*
+    atomic synopsis
+
+namespace std
+{
+
+// order and consistency
+
+typedef enum memory_order
+{
+    memory_order_relaxed,
+    memory_order_consume,  // load-consume
+    memory_order_acquire,  // load-acquire
+    memory_order_release,  // store-release
+    memory_order_acq_rel,  // store-release load-acquire
+    memory_order_seq_cst   // store-release load-acquire
+} memory_order;
+
+template <class T> T kill_dependency(T y) noexcept;
+
+// lock-free property
+
+#define ATOMIC_BOOL_LOCK_FREE unspecified
+#define ATOMIC_CHAR_LOCK_FREE unspecified
+#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
+#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
+#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
+#define ATOMIC_SHORT_LOCK_FREE unspecified
+#define ATOMIC_INT_LOCK_FREE unspecified
+#define ATOMIC_LONG_LOCK_FREE unspecified
+#define ATOMIC_LLONG_LOCK_FREE unspecified
+#define ATOMIC_POINTER_LOCK_FREE unspecified
+
+// flag type and operations
+
+typedef struct atomic_flag
+{
+    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
+    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
+    void clear(memory_order m = memory_order_seq_cst) noexcept;
+    atomic_flag()  noexcept = default;
+    atomic_flag(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) volatile = delete;
+} atomic_flag;
+
+bool
+    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
+
+bool
+    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
+
+bool
+    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
+                                      memory_order m) noexcept;
+
+bool
+    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
+
+void
+    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
+
+void
+    atomic_flag_clear(atomic_flag* obj) noexcept;
+
+void
+    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
+
+void
+    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
+
+#define ATOMIC_FLAG_INIT see below
+#define ATOMIC_VAR_INIT(value) see below
+
+template <class T>
+struct atomic
+{
+    bool is_lock_free() const volatile noexcept;
+    bool is_lock_free() const noexcept;
+    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
+    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
+    T load(memory_order m = memory_order_seq_cst) const noexcept;
+    operator T() const volatile noexcept;
+    operator T() const noexcept;
+    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_weak(T& expc, T desr,
+                               memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
+    bool compare_exchange_strong(T& expc, T desr,
+                                 memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_strong(T& expc, T desr,
+                                 memory_order s, memory_order f) noexcept;
+    bool compare_exchange_weak(T& expc, T desr,
+                               memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_weak(T& expc, T desr,
+                               memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_strong(T& expc, T desr,
+                                memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_strong(T& expc, T desr,
+                                 memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default;
+    constexpr atomic(T desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+    T operator=(T) volatile noexcept;
+    T operator=(T) noexcept;
+};
+
+template <>
+struct atomic<integral>
+{
+    bool is_lock_free() const volatile noexcept;
+    bool is_lock_free() const noexcept;
+    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
+    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
+    integral load(memory_order m = memory_order_seq_cst) const noexcept;
+    operator integral() const volatile noexcept;
+    operator integral() const noexcept;
+    integral exchange(integral desr,
+                      memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_weak(integral& expc, integral desr,
+                               memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_weak(integral& expc, integral desr,
+                               memory_order s, memory_order f) noexcept;
+    bool compare_exchange_strong(integral& expc, integral desr,
+                                 memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_strong(integral& expc, integral desr,
+                                 memory_order s, memory_order f) noexcept;
+    bool compare_exchange_weak(integral& expc, integral desr,
+                               memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_weak(integral& expc, integral desr,
+                               memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_strong(integral& expc, integral desr,
+                                memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_strong(integral& expc, integral desr,
+                                 memory_order m = memory_order_seq_cst) noexcept;
+
+    integral
+        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
+    integral
+        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
+    integral
+        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
+    integral
+        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
+    integral
+        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default;
+    constexpr atomic(integral desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+    integral operator=(integral desr) volatile noexcept;
+    integral operator=(integral desr) noexcept;
+
+    integral operator++(int) volatile noexcept;
+    integral operator++(int) noexcept;
+    integral operator--(int) volatile noexcept;
+    integral operator--(int) noexcept;
+    integral operator++() volatile noexcept;
+    integral operator++() noexcept;
+    integral operator--() volatile noexcept;
+    integral operator--() noexcept;
+    integral operator+=(integral op) volatile noexcept;
+    integral operator+=(integral op) noexcept;
+    integral operator-=(integral op) volatile noexcept;
+    integral operator-=(integral op) noexcept;
+    integral operator&=(integral op) volatile noexcept;
+    integral operator&=(integral op) noexcept;
+    integral operator|=(integral op) volatile noexcept;
+    integral operator|=(integral op) noexcept;
+    integral operator^=(integral op) volatile noexcept;
+    integral operator^=(integral op) noexcept;
+};
+
+template <class T>
+struct atomic<T*>
+{
+    bool is_lock_free() const volatile noexcept;
+    bool is_lock_free() const noexcept;
+    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
+    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
+    T* load(memory_order m = memory_order_seq_cst) const noexcept;
+    operator T*() const volatile noexcept;
+    operator T*() const noexcept;
+    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
+    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_weak(T*& expc, T* desr,
+                               memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_weak(T*& expc, T* desr,
+                               memory_order s, memory_order f) noexcept;
+    bool compare_exchange_strong(T*& expc, T* desr,
+                                 memory_order s, memory_order f) volatile noexcept;
+    bool compare_exchange_strong(T*& expc, T* desr,
+                                 memory_order s, memory_order f) noexcept;
+    bool compare_exchange_weak(T*& expc, T* desr,
+                               memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_weak(T*& expc, T* desr,
+                               memory_order m = memory_order_seq_cst) noexcept;
+    bool compare_exchange_strong(T*& expc, T* desr,
+                                memory_order m = memory_order_seq_cst) volatile noexcept;
+    bool compare_exchange_strong(T*& expc, T* desr,
+                                 memory_order m = memory_order_seq_cst) noexcept;
+    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
+    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
+    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
+
+    atomic() noexcept = default;
+    constexpr atomic(T* desr) noexcept;
+    atomic(const atomic&) = delete;
+    atomic& operator=(const atomic&) = delete;
+    atomic& operator=(const atomic&) volatile = delete;
+
+    T* operator=(T*) volatile noexcept;
+    T* operator=(T*) noexcept;
+    T* operator++(int) volatile noexcept;
+    T* operator++(int) noexcept;
+    T* operator--(int) volatile noexcept;
+    T* operator--(int) noexcept;
+    T* operator++() volatile noexcept;
+    T* operator++() noexcept;
+    T* operator--() volatile noexcept;
+    T* operator--() noexcept;
+    T* operator+=(ptrdiff_t op) volatile noexcept;
+    T* operator+=(ptrdiff_t op) noexcept;
+    T* operator-=(ptrdiff_t op) volatile noexcept;
+    T* operator-=(ptrdiff_t op) noexcept;
+};
+
+
+template <class T>
+    bool
+    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
+
+template <class T>
+    bool
+    atomic_is_lock_free(const atomic<T>* obj) noexcept;
+
+template <class T>
+    void
+    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    void
+    atomic_init(atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    void
+    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    void
+    atomic_store(atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    void
+    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
+
+template <class T>
+    void
+    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
+
+template <class T>
+    T
+    atomic_load(const volatile atomic<T>* obj) noexcept;
+
+template <class T>
+    T
+    atomic_load(const atomic<T>* obj) noexcept;
+
+template <class T>
+    T
+    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
+
+template <class T>
+    T
+    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
+
+template <class T>
+    T
+    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    T
+    atomic_exchange(atomic<T>* obj, T desr) noexcept;
+
+template <class T>
+    T
+    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
+
+template <class T>
+    T
+    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
+                                          T desr,
+                                          memory_order s, memory_order f) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
+                                          memory_order s, memory_order f) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
+                                            T* expc, T desr,
+                                            memory_order s, memory_order f) noexcept;
+
+template <class T>
+    bool
+    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
+                                            T desr,
+                                            memory_order s, memory_order f) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
+                             memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
+                             memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
+
+template <class Integral>
+    Integral
+    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+template <class Integral>
+    Integral
+    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
+                              memory_order m) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
+                              memory_order m) noexcept;
+template <class T>
+    T*
+    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
+
+template <class T>
+    T*
+    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
+                              memory_order m) noexcept;
+template <class T>
+    T*
+    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
+
+// Atomics for standard typedef types
+
+typedef atomic<bool>               atomic_bool;
+typedef atomic<char>               atomic_char;
+typedef atomic<signed char>        atomic_schar;
+typedef atomic<unsigned char>      atomic_uchar;
+typedef atomic<short>              atomic_short;
+typedef atomic<unsigned short>     atomic_ushort;
+typedef atomic<int>                atomic_int;
+typedef atomic<unsigned int>       atomic_uint;
+typedef atomic<long>               atomic_long;
+typedef atomic<unsigned long>      atomic_ulong;
+typedef atomic<long long>          atomic_llong;
+typedef atomic<unsigned long long> atomic_ullong;
+typedef atomic<char16_t>           atomic_char16_t;
+typedef atomic<char32_t>           atomic_char32_t;
+typedef atomic<wchar_t>            atomic_wchar_t;
+
+typedef atomic<int_least8_t>   atomic_int_least8_t;
+typedef atomic<uint_least8_t>  atomic_uint_least8_t;
+typedef atomic<int_least16_t>  atomic_int_least16_t;
+typedef atomic<uint_least16_t> atomic_uint_least16_t;
+typedef atomic<int_least32_t>  atomic_int_least32_t;
+typedef atomic<uint_least32_t> atomic_uint_least32_t;
+typedef atomic<int_least64_t>  atomic_int_least64_t;
+typedef atomic<uint_least64_t> atomic_uint_least64_t;
+
+typedef atomic<int_fast8_t>   atomic_int_fast8_t;
+typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
+typedef atomic<int_fast16_t>  atomic_int_fast16_t;
+typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
+typedef atomic<int_fast32_t>  atomic_int_fast32_t;
+typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
+typedef atomic<int_fast64_t>  atomic_int_fast64_t;
+typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
+
+typedef atomic<intptr_t>  atomic_intptr_t;
+typedef atomic<uintptr_t> atomic_uintptr_t;
+typedef atomic<size_t>    atomic_size_t;
+typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
+typedef atomic<intmax_t>  atomic_intmax_t;
+typedef atomic<uintmax_t> atomic_uintmax_t;
+
+// fences
+
+void atomic_thread_fence(memory_order m) noexcept;
+void atomic_signal_fence(memory_order m) noexcept;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !__has_feature(cxx_atomic)
+#error <atomic> is not implemented
+#else
+
+typedef enum memory_order
+{
+    memory_order_relaxed, memory_order_consume, memory_order_acquire,
+    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+kill_dependency(_Tp __y) _NOEXCEPT
+{
+    return __y;
+}
+
+// general atomic<T>
+
+template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
+struct __atomic_base  // false
+{
+    mutable _Atomic(_Tp) __a_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool is_lock_free() const volatile _NOEXCEPT
+        {return __c11_atomic_is_lock_free(sizeof(_Tp));}
+    _LIBCPP_INLINE_VISIBILITY
+    bool is_lock_free() const _NOEXCEPT
+        {return __c11_atomic_is_lock_free(sizeof(_Tp));}
+    _LIBCPP_INLINE_VISIBILITY
+    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {__c11_atomic_store(&__a_, __d, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {__c11_atomic_store(&__a_, __d, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
+        {return __c11_atomic_load(&__a_, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
+        {return __c11_atomic_load(&__a_, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    operator _Tp() const volatile _NOEXCEPT {return load();}
+    _LIBCPP_INLINE_VISIBILITY
+    operator _Tp() const _NOEXCEPT          {return load();}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_exchange(&__a_, __d, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_exchange(&__a_, __d, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_weak(_Tp& __e, _Tp __d,
+                               memory_order __s, memory_order __f) volatile _NOEXCEPT
+        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_weak(_Tp& __e, _Tp __d,
+                               memory_order __s, memory_order __f) _NOEXCEPT
+        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_strong(_Tp& __e, _Tp __d,
+                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
+        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_strong(_Tp& __e, _Tp __d,
+                                 memory_order __s, memory_order __f) _NOEXCEPT
+        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_weak(_Tp& __e, _Tp __d,
+                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_weak(_Tp& __e, _Tp __d,
+                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_strong(_Tp& __e, _Tp __d,
+                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool compare_exchange_strong(_Tp& __e, _Tp __d,
+                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
+
+    _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    __atomic_base() _NOEXCEPT = default;
+#else
+    __atomic_base() _NOEXCEPT : __a_() {}
+#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    __atomic_base(const __atomic_base&) = delete;
+    __atomic_base& operator=(const __atomic_base&) = delete;
+    __atomic_base& operator=(const __atomic_base&) volatile = delete;
+#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+private:
+    __atomic_base(const __atomic_base&);
+    __atomic_base& operator=(const __atomic_base&);
+    __atomic_base& operator=(const __atomic_base&) volatile;
+#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+};
+
+// atomic<Integral>
+
+template <class _Tp>
+struct __atomic_base<_Tp, true>
+    : public __atomic_base<_Tp, false>
+{
+    typedef __atomic_base<_Tp, false> __base;
+    _LIBCPP_INLINE_VISIBILITY
+    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
+};
+
+// atomic<T>
+
+template <class _Tp>
+struct atomic
+    : public __atomic_base<_Tp>
+{
+    typedef __atomic_base<_Tp> __base;
+    _LIBCPP_INLINE_VISIBILITY
+    atomic() _NOEXCEPT _LIBCPP_DEFAULT
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator=(_Tp __d) volatile _NOEXCEPT
+        {__base::store(__d); return __d;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator=(_Tp __d) _NOEXCEPT
+        {__base::store(__d); return __d;}
+};
+
+// atomic<T*>
+
+template <class _Tp>
+struct atomic<_Tp*>
+    : public __atomic_base<_Tp*>
+{
+    typedef __atomic_base<_Tp*> __base;
+    _LIBCPP_INLINE_VISIBILITY
+    atomic() _NOEXCEPT _LIBCPP_DEFAULT
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
+        {__base::store(__d); return __d;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator=(_Tp* __d) _NOEXCEPT
+        {__base::store(__d); return __d;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
+                                                                        volatile _NOEXCEPT
+        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
+                                                                        volatile _NOEXCEPT
+        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
+};
+
+// atomic_is_lock_free
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->is_lock_free();
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->is_lock_free();
+}
+
+// atomic_init
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    __c11_atomic_init(&__o->__a_, __d);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    __c11_atomic_init(&__o->__a_, __d);
+}
+
+// atomic_store
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    __o->store(__d);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    __o->store(__d);
+}
+
+// atomic_store_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
+{
+    __o->store(__d, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
+{
+    __o->store(__d, __m);
+}
+
+// atomic_load
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->load();
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
+{
+    return __o->load();
+}
+
+// atomic_load_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->load(__m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->load(__m);
+}
+
+// atomic_exchange
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    return __o->exchange(__d);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
+{
+    return __o->exchange(__d);
+}
+
+// atomic_exchange_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
+{
+    return __o->exchange(__d, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
+{
+    return __o->exchange(__d, __m);
+}
+
+// atomic_compare_exchange_weak
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d);
+}
+
+// atomic_compare_exchange_strong
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d);
+}
+
+// atomic_compare_exchange_weak_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
+                                      _Tp __d,
+                                      memory_order __s, memory_order __f) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d, __s, __f);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
+                                      memory_order __s, memory_order __f) _NOEXCEPT
+{
+    return __o->compare_exchange_weak(*__e, __d, __s, __f);
+}
+
+// atomic_compare_exchange_strong_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
+                                        _Tp* __e, _Tp __d,
+                                        memory_order __s, memory_order __f) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d, __s, __f);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
+                                        _Tp __d,
+                                        memory_order __s, memory_order __f) _NOEXCEPT
+{
+    return __o->compare_exchange_strong(*__e, __d, __s, __f);
+}
+
+// atomic_fetch_add
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
+{
+    return __o->fetch_add(__op);
+}
+
+// atomic_fetch_add_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
+                          memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_add(__op, __m);
+}
+
+// atomic_fetch_sub
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
+{
+    return __o->fetch_sub(__op);
+}
+
+// atomic_fetch_sub_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
+                          memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_sub(__op, __m);
+}
+
+// atomic_fetch_and
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_and(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_and(__op);
+}
+
+// atomic_fetch_and_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_and(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_and(__op, __m);
+}
+
+// atomic_fetch_or
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_or(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_or(__op);
+}
+
+// atomic_fetch_or_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_or(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_or(__op, __m);
+}
+
+// atomic_fetch_xor
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_xor(__op);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
+{
+    return __o->fetch_xor(__op);
+}
+
+// atomic_fetch_xor_explicit
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_xor(__op, __m);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
+    _Tp
+>::type
+atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
+{
+    return __o->fetch_xor(__op, __m);
+}
+
+// flag type and operations
+
+typedef struct atomic_flag
+{
+    _Atomic(bool) __a_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {return __c11_atomic_exchange(&__a_, true, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {return __c11_atomic_exchange(&__a_, true, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        {__c11_atomic_store(&__a_, false, __m);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        {__c11_atomic_store(&__a_, false, __m);}
+
+    _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    atomic_flag() _NOEXCEPT = default;
+#else
+    atomic_flag() _NOEXCEPT : __a_() {}
+#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    _LIBCPP_INLINE_VISIBILITY
+    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
+
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    atomic_flag(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) = delete;
+    atomic_flag& operator=(const atomic_flag&) volatile = delete;
+#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+private:
+    atomic_flag(const atomic_flag&);
+    atomic_flag& operator=(const atomic_flag&);
+    atomic_flag& operator=(const atomic_flag&) volatile;
+#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+} atomic_flag;
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test_and_set();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
+{
+    return __o->test_and_set();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test_and_set(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    return __o->test_and_set(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
+{
+    __o->clear();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
+{
+    __o->clear();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    __o->clear(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
+{
+    __o->clear(__m);
+}
+
+// fences
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_thread_fence(memory_order __m) _NOEXCEPT
+{
+    __c11_atomic_thread_fence(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_signal_fence(memory_order __m) _NOEXCEPT
+{
+    __c11_atomic_signal_fence(__m);
+}
+
+// Atomics for standard typedef types
+
+typedef atomic<bool>               atomic_bool;
+typedef atomic<char>               atomic_char;
+typedef atomic<signed char>        atomic_schar;
+typedef atomic<unsigned char>      atomic_uchar;
+typedef atomic<short>              atomic_short;
+typedef atomic<unsigned short>     atomic_ushort;
+typedef atomic<int>                atomic_int;
+typedef atomic<unsigned int>       atomic_uint;
+typedef atomic<long>               atomic_long;
+typedef atomic<unsigned long>      atomic_ulong;
+typedef atomic<long long>          atomic_llong;
+typedef atomic<unsigned long long> atomic_ullong;
+typedef atomic<char16_t>           atomic_char16_t;
+typedef atomic<char32_t>           atomic_char32_t;
+typedef atomic<wchar_t>            atomic_wchar_t;
+
+typedef atomic<int_least8_t>   atomic_int_least8_t;
+typedef atomic<uint_least8_t>  atomic_uint_least8_t;
+typedef atomic<int_least16_t>  atomic_int_least16_t;
+typedef atomic<uint_least16_t> atomic_uint_least16_t;
+typedef atomic<int_least32_t>  atomic_int_least32_t;
+typedef atomic<uint_least32_t> atomic_uint_least32_t;
+typedef atomic<int_least64_t>  atomic_int_least64_t;
+typedef atomic<uint_least64_t> atomic_uint_least64_t;
+
+typedef atomic<int_fast8_t>   atomic_int_fast8_t;
+typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
+typedef atomic<int_fast16_t>  atomic_int_fast16_t;
+typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
+typedef atomic<int_fast32_t>  atomic_int_fast32_t;
+typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
+typedef atomic<int_fast64_t>  atomic_int_fast64_t;
+typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
+
+typedef atomic<intptr_t>  atomic_intptr_t;
+typedef atomic<uintptr_t> atomic_uintptr_t;
+typedef atomic<size_t>    atomic_size_t;
+typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
+typedef atomic<intmax_t>  atomic_intmax_t;
+typedef atomic<uintmax_t> atomic_uintmax_t;
+
+#define ATOMIC_FLAG_INIT {false}
+#define ATOMIC_VAR_INIT(__v) {__v}
+
+// lock-free property
+
+#define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
+#define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
+#define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
+#define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
+#define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
+#define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
+#define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
+#define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
+#define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
+#define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
+
+#endif  //  !__has_feature(cxx_atomic)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_ATOMIC
diff --git a/include/c++/v1/bitset b/include/c++/v1/bitset
new file mode 100644
index 0000000..8c278cc
--- /dev/null
+++ b/include/c++/v1/bitset
@@ -0,0 +1,1081 @@
+// -*- C++ -*-
+//===---------------------------- bitset ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_BITSET
+#define _LIBCPP_BITSET
+
+/*
+    bitset synopsis
+
+namespace std
+{
+
+namespace std {
+
+template <size_t N>
+class bitset
+{
+public:
+    // bit reference:
+    class reference
+    {
+        friend class bitset;
+        reference() noexcept;
+    public:
+        ~reference() noexcept;
+        reference& operator=(bool x) noexcept;           // for b[i] = x;
+        reference& operator=(const reference&) noexcept; // for b[i] = b[j];
+        bool operator~() const noexcept;                 // flips the bit
+        operator bool() const noexcept;                  // for x = b[i];
+        reference& flip() noexcept;                      // for b[i].flip();
+    };
+
+    // 23.3.5.1 constructors:
+    constexpr bitset() noexcept;
+    constexpr bitset(unsigned long long val) noexcept;
+    template <class charT>
+        explicit bitset(const charT* str,
+                        typename basic_string<charT>::size_type n = basic_string<charT>::npos,
+                        charT zero = charT('0'), charT one = charT('1'));
+    template<class charT, class traits, class Allocator>
+        explicit bitset(const basic_string<charT,traits,Allocator>& str,
+                        typename basic_string<charT,traits,Allocator>::size_type pos = 0,
+                        typename basic_string<charT,traits,Allocator>::size_type n =
+                                 basic_string<charT,traits,Allocator>::npos,
+                        charT zero = charT('0'), charT one = charT('1'));
+
+    // 23.3.5.2 bitset operations:
+    bitset& operator&=(const bitset& rhs) noexcept;
+    bitset& operator|=(const bitset& rhs) noexcept;
+    bitset& operator^=(const bitset& rhs) noexcept;
+    bitset& operator<<=(size_t pos) noexcept;
+    bitset& operator>>=(size_t pos) noexcept;
+    bitset& set() noexcept;
+    bitset& set(size_t pos, bool val = true);
+    bitset& reset() noexcept;
+    bitset& reset(size_t pos);
+    bitset operator~() const noexcept;
+    bitset& flip() noexcept;
+    bitset& flip(size_t pos);
+
+    // element access:
+    constexpr bool operator[](size_t pos) const; // for b[i];
+    reference operator[](size_t pos);            // for b[i];
+    unsigned long to_ulong() const;
+    unsigned long long to_ullong() const;
+    template <class charT, class traits, class Allocator>
+        basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
+    template <class charT, class traits>
+        basic_string<charT, traits, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
+    template <class charT>
+        basic_string<charT, char_traits<charT>, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
+    basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const;
+    size_t count() const noexcept;
+    constexpr size_t size() const noexcept;
+    bool operator==(const bitset& rhs) const noexcept;
+    bool operator!=(const bitset& rhs) const noexcept;
+    bool test(size_t pos) const;
+    bool all() const noexcept;
+    bool any() const noexcept;
+    bool none() const noexcept;
+    bitset operator<<(size_t pos) const noexcept;
+    bitset operator>>(size_t pos) const noexcept;
+};
+
+// 23.3.5.3 bitset operators:
+template <size_t N>
+bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
+
+template <size_t N>
+bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
+
+template <size_t N>
+bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
+
+template <class charT, class traits, size_t N>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
+
+template <class charT, class traits, size_t N>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
+
+template <size_t N> struct hash<std::bitset<N>>;
+
+}  // std
+
+*/
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include <__config>
+#include <__bit_reference>
+#include <cstddef>
+#include <climits>
+#include <string>
+#include <stdexcept>
+#include <iosfwd>
+#include <__functional_base>
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#include <__undef_min_max>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <size_t _N_words, size_t _Size>
+class __bitset;
+
+template <size_t _N_words, size_t _Size>
+struct __has_storage_type<__bitset<_N_words, _Size> >
+{
+    static const bool value = true;
+};
+
+template <size_t _N_words, size_t _Size>
+class __bitset
+{
+public:
+    typedef ptrdiff_t              difference_type;
+    typedef size_t                 size_type;
+    typedef size_type              __storage_type;
+protected:
+    typedef __bitset __self;
+    typedef       __storage_type*  __storage_pointer;
+    typedef const __storage_type*  __const_storage_pointer;
+    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
+
+    friend class __bit_reference<__bitset>;
+    friend class __bit_const_reference<__bitset>;
+    friend class __bit_iterator<__bitset, false>;
+    friend class __bit_iterator<__bitset, true>;
+    friend struct __bit_array<__bitset>;
+
+    __storage_type __first_[_N_words];
+
+    typedef __bit_reference<__bitset>                  reference;
+    typedef __bit_const_reference<__bitset>            const_reference;
+    typedef __bit_iterator<__bitset, false>            iterator;
+    typedef __bit_iterator<__bitset, true>             const_iterator;
+
+    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
+        {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
+        {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
+        {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
+        {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
+
+    void operator&=(const __bitset& __v) _NOEXCEPT;
+    void operator|=(const __bitset& __v) _NOEXCEPT;
+    void operator^=(const __bitset& __v) _NOEXCEPT;
+
+    void flip() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const
+        {return to_ulong(integral_constant<bool, _Size < sizeof(unsigned long) * CHAR_BIT>());}
+    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const
+        {return to_ullong(integral_constant<bool, _Size < sizeof(unsigned long long) * CHAR_BIT>());}
+
+    bool all() const _NOEXCEPT;
+    bool any() const _NOEXCEPT;
+    size_t __hash_code() const _NOEXCEPT;
+private:
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    void __init(unsigned long long __v, false_type) _NOEXCEPT;
+    void __init(unsigned long long __v, true_type) _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_CONSTEXPR
+    unsigned long to_ulong(false_type) const;
+    unsigned long to_ulong(true_type) const;
+    unsigned long long to_ullong(false_type) const;
+    unsigned long long to_ullong(true_type) const;
+    unsigned long long to_ullong(true_type, false_type) const;
+    unsigned long long to_ullong(true_type, true_type) const;
+};
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<_N_words, _Size>::__bitset() _NOEXCEPT
+#ifndef _LIBCPP_HAS_NO_CONSTEXPR
+    : __first_{0}
+#endif
+{
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    _VSTD::fill_n(__first_, _N_words, __storage_type(0));
+#endif
+}
+
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+
+template <size_t _N_words, size_t _Size>
+void
+__bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT
+{
+    __storage_type __t[sizeof(unsigned long long) / sizeof(__storage_type)];
+    for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word)
+        __t[__i] = static_cast<__storage_type>(__v);
+    _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_);
+    _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]),
+               __storage_type(0));
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT
+{
+    __first_[0] = __v;
+    _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));
+}
+
+#endif  // _LIBCPP_HAS_NO_CONSTEXPR
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
+#ifndef _LIBCPP_HAS_NO_CONSTEXPR
+#if __SIZEOF_SIZE_T__ == 8
+    : __first_{__v}
+#elif __SIZEOF_SIZE_T__ == 4
+    : __first_{__v, __v >> __bits_per_word}
+#else
+#error This constructor has not been ported to this platform
+#endif
+#endif
+{
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
+#endif
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
+{
+    for (size_type __i = 0; __i < _N_words; ++__i)
+        __first_[__i] &= __v.__first_[__i];
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
+{
+    for (size_type __i = 0; __i < _N_words; ++__i)
+        __first_[__i] |= __v.__first_[__i];
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
+{
+    for (size_type __i = 0; __i < _N_words; ++__i)
+        __first_[__i] ^= __v.__first_[__i];
+}
+
+template <size_t _N_words, size_t _Size>
+void
+__bitset<_N_words, _Size>::flip() _NOEXCEPT
+{
+    // do middle whole words
+    size_type __n = _Size;
+    __storage_pointer __p = __first_;
+    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+        *__p = ~*__p;
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __storage_type __b = *__p & __m;
+        *__p &= ~__m;
+        *__p |= ~__b & __m;
+    }
+}
+
+template <size_t _N_words, size_t _Size>
+unsigned long
+__bitset<_N_words, _Size>::to_ulong(false_type) const
+{
+    const_iterator __e = __make_iter(_Size);
+    const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true);
+    if (__i != __e)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw overflow_error("bitset to_ulong overflow error");
+#else
+        assert(!"bitset to_ulong overflow error");
+#endif
+    return __first_[0];
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long
+__bitset<_N_words, _Size>::to_ulong(true_type) const
+{
+    return __first_[0];
+}
+
+template <size_t _N_words, size_t _Size>
+unsigned long long
+__bitset<_N_words, _Size>::to_ullong(false_type) const
+{
+    const_iterator __e = __make_iter(_Size);
+    const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true);
+    if (__i != __e)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw overflow_error("bitset to_ullong overflow error");
+#else
+        assert(!"bitset to_ullong overflow error");
+#endif
+    return to_ullong(true_type());
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+__bitset<_N_words, _Size>::to_ullong(true_type) const
+{
+    return to_ullong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long long)>());
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const
+{
+    return __first_[0];
+}
+
+template <size_t _N_words, size_t _Size>
+unsigned long long
+__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const
+{
+    unsigned long long __r = __first_[0];
+    for (std::size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i)
+        __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT);
+    return __r;
+}
+
+template <size_t _N_words, size_t _Size>
+bool
+__bitset<_N_words, _Size>::all() const _NOEXCEPT
+{
+    // do middle whole words
+    size_type __n = _Size;
+    __const_storage_pointer __p = __first_;
+    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+        if (~*__p)
+            return false;
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        if (~*__p & __m)
+            return false;
+    }
+    return true;
+}
+
+template <size_t _N_words, size_t _Size>
+bool
+__bitset<_N_words, _Size>::any() const _NOEXCEPT
+{
+    // do middle whole words
+    size_type __n = _Size;
+    __const_storage_pointer __p = __first_;
+    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+        if (*__p)
+            return true;
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        if (*__p & __m)
+            return true;
+    }
+    return false;
+}
+
+template <size_t _N_words, size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT
+{
+    size_t __h = 0;
+    for (size_type __i = 0; __i < _N_words; ++__i)
+        __h ^= __first_[__i];
+    return __h;
+}
+
+template <size_t _Size>
+class __bitset<1, _Size>
+{
+public:
+    typedef ptrdiff_t              difference_type;
+    typedef size_t                 size_type;
+    typedef size_type              __storage_type;
+protected:
+    typedef __bitset __self;
+    typedef       __storage_type*  __storage_pointer;
+    typedef const __storage_type*  __const_storage_pointer;
+    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
+
+    friend class __bit_reference<__bitset>;
+    friend class __bit_const_reference<__bitset>;
+    friend class __bit_iterator<__bitset, false>;
+    friend class __bit_iterator<__bitset, true>;
+    friend struct __bit_array<__bitset>;
+
+    __storage_type __first_;
+
+    typedef __bit_reference<__bitset>                  reference;
+    typedef __bit_const_reference<__bitset>            const_reference;
+    typedef __bit_iterator<__bitset, false>            iterator;
+    typedef __bit_iterator<__bitset, true>             const_iterator;
+
+    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
+        {return reference(&__first_, __storage_type(1) << __pos);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
+        {return const_reference(&__first_, __storage_type(1) << __pos);}
+    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
+        {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
+        {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
+
+    void operator&=(const __bitset& __v) _NOEXCEPT;
+    void operator|=(const __bitset& __v) _NOEXCEPT;
+    void operator^=(const __bitset& __v) _NOEXCEPT;
+
+    void flip() _NOEXCEPT;
+
+    unsigned long to_ulong() const;
+    unsigned long long to_ullong() const;
+
+    bool all() const _NOEXCEPT;
+    bool any() const _NOEXCEPT;
+
+    size_t __hash_code() const _NOEXCEPT;
+};
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<1, _Size>::__bitset() _NOEXCEPT
+    : __first_(0)
+{
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
+    : __first_(static_cast<__storage_type>(__v))
+{
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
+{
+    __first_ &= __v.__first_;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
+{
+    __first_ |= __v.__first_;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
+{
+    __first_ ^= __v.__first_;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__bitset<1, _Size>::flip() _NOEXCEPT
+{
+    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
+    __first_ = ~__first_;
+    __first_ &= __m;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long
+__bitset<1, _Size>::to_ulong() const
+{
+    return __first_;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+__bitset<1, _Size>::to_ullong() const
+{
+    return __first_;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__bitset<1, _Size>::all() const _NOEXCEPT
+{
+    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
+    return !(~__first_ & __m);
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__bitset<1, _Size>::any() const _NOEXCEPT
+{
+    __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
+    return __first_ & __m;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+__bitset<1, _Size>::__hash_code() const _NOEXCEPT
+{
+    return __first_;
+}
+
+template <>
+class __bitset<0, 0>
+{
+public:
+    typedef ptrdiff_t              difference_type;
+    typedef size_t                 size_type;
+    typedef size_type              __storage_type;
+protected:
+    typedef __bitset __self;
+    typedef       __storage_type*  __storage_pointer;
+    typedef const __storage_type*  __const_storage_pointer;
+    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
+
+    friend class __bit_reference<__bitset>;
+    friend class __bit_const_reference<__bitset>;
+    friend class __bit_iterator<__bitset, false>;
+    friend class __bit_iterator<__bitset, true>;
+    friend struct __bit_array<__bitset>;
+
+    typedef __bit_reference<__bitset>                  reference;
+    typedef __bit_const_reference<__bitset>            const_reference;
+    typedef __bit_iterator<__bitset, false>            iterator;
+    typedef __bit_iterator<__bitset, true>             const_iterator;
+
+    _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
+    explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT
+        {return reference(0, 1);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT
+        {return const_reference(0, 1);}
+    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT
+        {return iterator(0, 0);}
+    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT
+        {return const_iterator(0, 0);}
+
+    _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY void operator^=(const __bitset&) _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const {return 0;}
+
+    _LIBCPP_INLINE_VISIBILITY bool all() const _NOEXCEPT {return true;}
+    _LIBCPP_INLINE_VISIBILITY bool any() const _NOEXCEPT {return false;}
+
+    _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<0, 0>::__bitset() _NOEXCEPT
+{
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+__bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT
+{
+}
+
+template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset;
+template <size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >;
+
+template <size_t _Size>
+class _LIBCPP_TYPE_VIS_ONLY bitset
+    : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size>
+{
+public:
+    static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1;
+    typedef __bitset<__n_words, _Size> base;
+
+public:
+    typedef typename base::reference       reference;
+    typedef typename base::const_reference const_reference;
+
+    // 23.3.5.1 constructors:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+        bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
+    template<class _CharT>
+        explicit bitset(const _CharT* __str,
+                        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
+                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
+    template<class _CharT, class _Traits, class _Allocator>
+        explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
+                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
+                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
+                                (basic_string<_CharT,_Traits,_Allocator>::npos),
+                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
+
+    // 23.3.5.2 bitset operations:
+    bitset& operator&=(const bitset& __rhs) _NOEXCEPT;
+    bitset& operator|=(const bitset& __rhs) _NOEXCEPT;
+    bitset& operator^=(const bitset& __rhs) _NOEXCEPT;
+    bitset& operator<<=(size_t __pos) _NOEXCEPT;
+    bitset& operator>>=(size_t __pos) _NOEXCEPT;
+    bitset& set() _NOEXCEPT;
+    bitset& set(size_t __pos, bool __val = true);
+    bitset& reset() _NOEXCEPT;
+    bitset& reset(size_t __pos);
+    bitset  operator~() const _NOEXCEPT;
+    bitset& flip() _NOEXCEPT;
+    bitset& flip(size_t __pos);
+
+    // element access:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+                              const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
+    _LIBCPP_INLINE_VISIBILITY       reference operator[](size_t __p)       {return base::__make_ref(__p);}
+    unsigned long to_ulong() const;
+    unsigned long long to_ullong() const;
+    template <class _CharT, class _Traits, class _Allocator>
+        basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'),
+                                                            _CharT __one = _CharT('1')) const;
+    template <class _CharT, class _Traits>
+        basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
+                                                                    _CharT __one = _CharT('1')) const;
+    template <class _CharT>
+        basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
+                                                                                _CharT __one = _CharT('1')) const;
+    basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0',
+                                                                      char __one = '1') const;
+    size_t count() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
+    bool operator==(const bitset& __rhs) const _NOEXCEPT;
+    bool operator!=(const bitset& __rhs) const _NOEXCEPT;
+    bool test(size_t __pos) const;
+    bool all() const _NOEXCEPT;
+    bool any() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();}
+    bitset operator<<(size_t __pos) const _NOEXCEPT;
+    bitset operator>>(size_t __pos) const _NOEXCEPT;
+
+private:
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}
+
+    friend struct hash<bitset>;
+};
+
+template <size_t _Size>
+template<class _CharT>
+bitset<_Size>::bitset(const _CharT* __str,
+                      typename basic_string<_CharT>::size_type __n,
+                      _CharT __zero, _CharT __one)
+{
+    size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));
+    for (size_t __i = 0; __i < __rlen; ++__i)
+        if (__str[__i] != __zero && __str[__i] != __one)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            throw invalid_argument("bitset string ctor has invalid argument");
+#else
+            assert(!"bitset string ctor has invalid argument");
+#endif
+    size_t _Mp = _VSTD::min(__rlen, _Size);
+    size_t __i = 0;
+    for (; __i < _Mp; ++__i)
+    {
+        _CharT __c = __str[_Mp - 1 - __i];
+        if (__c == __zero)
+            (*this)[__i] = false;
+        else
+            (*this)[__i] = true;
+    }
+    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
+}
+
+template <size_t _Size>
+template<class _CharT, class _Traits, class _Allocator>
+bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
+       typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
+       typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
+       _CharT __zero, _CharT __one)
+{
+    if (__pos > __str.size())
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("bitset string pos out of range");
+#else
+        assert(!"bitset string pos out of range");
+#endif
+    size_t __rlen = _VSTD::min(__n, __str.size() - __pos);
+    for (size_t __i = __pos; __i < __pos + __rlen; ++__i)
+        if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            throw invalid_argument("bitset string ctor has invalid argument");
+#else
+            assert(!"bitset string ctor has invalid argument");
+#endif
+    size_t _Mp = _VSTD::min(__rlen, _Size);
+    size_t __i = 0;
+    for (; __i < _Mp; ++__i)
+    {
+        _CharT __c = __str[__pos + _Mp - 1 - __i];
+        if (_Traits::eq(__c, __zero))
+            (*this)[__i] = false;
+        else
+            (*this)[__i] = true;
+    }
+    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT
+{
+    base::operator&=(__rhs);
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT
+{
+    base::operator|=(__rhs);
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT
+{
+    base::operator^=(__rhs);
+    return *this;
+}
+
+template <size_t _Size>
+bitset<_Size>&
+bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT
+{
+    __pos = _VSTD::min(__pos, _Size);
+    _VSTD::copy_backward(base::__make_iter(0), base::__make_iter(_Size - __pos), base::__make_iter(_Size));
+    _VSTD::fill_n(base::__make_iter(0), __pos, false);
+    return *this;
+}
+
+template <size_t _Size>
+bitset<_Size>&
+bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT
+{
+    __pos = _VSTD::min(__pos, _Size);
+    _VSTD::copy(base::__make_iter(__pos), base::__make_iter(_Size), base::__make_iter(0));
+    _VSTD::fill_n(base::__make_iter(_Size - __pos), __pos, false);
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::set() _NOEXCEPT
+{
+    _VSTD::fill_n(base::__make_iter(0), _Size, true);
+    return *this;
+}
+
+template <size_t _Size>
+bitset<_Size>&
+bitset<_Size>::set(size_t __pos, bool __val)
+{
+    if (__pos >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("bitset set argument out of range");
+#else
+        assert(!"bitset set argument out of range");
+#endif
+    (*this)[__pos] = __val;
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::reset() _NOEXCEPT
+{
+    _VSTD::fill_n(base::__make_iter(0), _Size, false);
+    return *this;
+}
+
+template <size_t _Size>
+bitset<_Size>&
+bitset<_Size>::reset(size_t __pos)
+{
+    if (__pos >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("bitset reset argument out of range");
+#else
+        assert(!"bitset reset argument out of range");
+#endif
+    (*this)[__pos] = false;
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+bitset<_Size>::operator~() const _NOEXCEPT
+{
+    bitset __x(*this);
+    __x.flip();
+    return __x;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>&
+bitset<_Size>::flip() _NOEXCEPT
+{
+    base::flip();
+    return *this;
+}
+
+template <size_t _Size>
+bitset<_Size>&
+bitset<_Size>::flip(size_t __pos)
+{
+    if (__pos >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("bitset flip argument out of range");
+#else
+        assert(!"bitset flip argument out of range");
+#endif
+    reference r = base::__make_ref(__pos);
+    r = ~r;
+    return *this;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long
+bitset<_Size>::to_ulong() const
+{
+    return base::to_ulong();
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+unsigned long long
+bitset<_Size>::to_ullong() const
+{
+    return base::to_ullong();
+}
+
+template <size_t _Size>
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero);
+    for (size_t __i = 0; __i < _Size; ++__i)
+    {
+        if ((*this)[__i])
+            __r[_Size - 1 - __i] = __one;
+    }
+    return __r;
+}
+
+template <size_t _Size>
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, allocator<_CharT> >
+bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
+{
+    return to_string<_CharT, _Traits, allocator<_CharT> >(__zero, __one);
+}
+
+template <size_t _Size>
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
+bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
+{
+    return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(__zero, __one);
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<char, char_traits<char>, allocator<char> >
+bitset<_Size>::to_string(char __zero, char __one) const
+{
+    return to_string<char, char_traits<char>, allocator<char> >(__zero, __one);
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+bitset<_Size>::count() const _NOEXCEPT
+{
+    return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true));
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
+{
+    return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
+{
+    return !(*this == __rhs);
+}
+
+template <size_t _Size>
+bool
+bitset<_Size>::test(size_t __pos) const
+{
+    if (__pos >= _Size)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("bitset test argument out of range");
+#else
+        assert(!"bitset test argument out of range");
+#endif
+    return (*this)[__pos];
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+bitset<_Size>::all() const _NOEXCEPT
+{
+    return base::all();
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+bitset<_Size>::any() const _NOEXCEPT
+{
+    return base::any();
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT
+{
+    bitset __r = *this;
+    __r <<= __pos;
+    return __r;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT
+{
+    bitset __r = *this;
+    __r >>= __pos;
+    return __r;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
+{
+    bitset<_Size> __r = __x;
+    __r &= __y;
+    return __r;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
+{
+    bitset<_Size> __r = __x;
+    __r |= __y;
+    return __r;
+}
+
+template <size_t _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+bitset<_Size>
+operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
+{
+    bitset<_Size> __r = __x;
+    __r ^= __y;
+    return __r;
+}
+
+template <size_t _Size>
+struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >
+    : public unary_function<bitset<_Size>, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT
+        {return __bs.__hash_code();}
+};
+
+template <class _CharT, class _Traits, size_t _Size>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x);
+
+template <class _CharT, class _Traits, size_t _Size>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_BITSET
diff --git a/include/c++/v1/cassert b/include/c++/v1/cassert
new file mode 100644
index 0000000..3775990
--- /dev/null
+++ b/include/c++/v1/cassert
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+//===-------------------------- cassert -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/*
+    cassert synopsis
+
+Macros:
+
+    assert
+
+*/
+
+#include <__config>
+#include <assert.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
diff --git a/include/c++/v1/ccomplex b/include/c++/v1/ccomplex
new file mode 100644
index 0000000..6ed1164
--- /dev/null
+++ b/include/c++/v1/ccomplex
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===--------------------------- ccomplex ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CCOMPLEX
+#define _LIBCPP_CCOMPLEX
+
+/*
+    ccomplex synopsis
+
+#include <complex>
+
+*/
+
+#include <complex>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+// hh 080623 Created
+
+#endif  // _LIBCPP_CCOMPLEX
diff --git a/include/c++/v1/cctype b/include/c++/v1/cctype
new file mode 100644
index 0000000..b647903
--- /dev/null
+++ b/include/c++/v1/cctype
@@ -0,0 +1,164 @@
+// -*- C++ -*-
+//===---------------------------- cctype ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CCTYPE
+#define _LIBCPP_CCTYPE
+
+/*
+    cctype synopsis
+
+namespace std
+{
+
+int isalnum(int c);
+int isalpha(int c);
+int isblank(int c);  // C99
+int iscntrl(int c);
+int isdigit(int c);
+int isgraph(int c);
+int islower(int c);
+int isprint(int c);
+int ispunct(int c);
+int isspace(int c);
+int isupper(int c);
+int isxdigit(int c);
+int tolower(int c);
+int toupper(int c);
+
+}  // std
+*/
+
+#include <__config>
+#include <ctype.h>
+#if defined(_LIBCPP_MSVCRT)
+#include "support/win32/support.h"
+#endif // _LIBCPP_MSVCRT
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifdef isalnum
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}
+#undef isalnum
+inline _LIBCPP_INLINE_VISIBILITY int isalnum(int __c) {return __libcpp_isalnum(__c);}
+#else  // isalnum
+using ::isalnum;
+#endif  // isalnum
+
+#ifdef isalpha
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalpha(int __c) {return isalpha(__c);}
+#undef isalpha
+inline _LIBCPP_INLINE_VISIBILITY int isalpha(int __c) {return __libcpp_isalpha(__c);}
+#else  // isalpha
+using ::isalpha;
+#endif  // isalpha
+
+#ifdef isblank
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isblank(int __c) {return isblank(__c);}
+#undef isblank
+inline _LIBCPP_INLINE_VISIBILITY int isblank(int __c) {return __libcpp_isblank(__c);}
+#else  // isblank
+using ::isblank;
+#endif  // isblank
+
+#ifdef iscntrl
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iscntrl(int __c) {return iscntrl(__c);}
+#undef iscntrl
+inline _LIBCPP_INLINE_VISIBILITY int iscntrl(int __c) {return __libcpp_iscntrl(__c);}
+#else  // iscntrl
+using ::iscntrl;
+#endif  // iscntrl
+
+#ifdef isdigit
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isdigit(int __c) {return isdigit(__c);}
+#undef isdigit
+inline _LIBCPP_INLINE_VISIBILITY int isdigit(int __c) {return __libcpp_isdigit(__c);}
+#else  // isdigit
+using ::isdigit;
+#endif  // isdigit
+
+#ifdef isgraph
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isgraph(int __c) {return isgraph(__c);}
+#undef isgraph
+inline _LIBCPP_INLINE_VISIBILITY int isgraph(int __c) {return __libcpp_isgraph(__c);}
+#else  // isgraph
+using ::isgraph;
+#endif  // isgraph
+
+#ifdef islower
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_islower(int __c) {return islower(__c);}
+#undef islower
+inline _LIBCPP_INLINE_VISIBILITY int islower(int __c) {return __libcpp_islower(__c);}
+#else  // islower
+using ::islower;
+#endif  // islower
+
+#ifdef isprint
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isprint(int __c) {return isprint(__c);}
+#undef isprint
+inline _LIBCPP_INLINE_VISIBILITY int isprint(int __c) {return __libcpp_isprint(__c);}
+#else  // isprint
+using ::isprint;
+#endif  // isprint
+
+#ifdef ispunct
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_ispunct(int __c) {return ispunct(__c);}
+#undef ispunct
+inline _LIBCPP_INLINE_VISIBILITY int ispunct(int __c) {return __libcpp_ispunct(__c);}
+#else  // ispunct
+using ::ispunct;
+#endif  // ispunct
+
+#ifdef isspace
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isspace(int __c) {return isspace(__c);}
+#undef isspace
+inline _LIBCPP_INLINE_VISIBILITY int isspace(int __c) {return __libcpp_isspace(__c);}
+#else  // isspace
+using ::isspace;
+#endif  // isspace
+
+#ifdef isupper
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isupper(int __c) {return isupper(__c);}
+#undef isupper
+inline _LIBCPP_INLINE_VISIBILITY int isupper(int __c) {return __libcpp_isupper(__c);}
+#else  // isupper
+using ::isupper;
+#endif  // isupper
+
+#ifdef isxdigit
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isxdigit(int __c) {return isxdigit(__c);}
+#undef isxdigit
+inline _LIBCPP_INLINE_VISIBILITY int isxdigit(int __c) {return __libcpp_isxdigit(__c);}
+#else  // isxdigit
+using ::isxdigit;
+#endif  // isxdigit
+
+#ifdef tolower
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_tolower(int __c) {return tolower(__c);}
+#undef tolower
+inline _LIBCPP_INLINE_VISIBILITY int tolower(int __c) {return __libcpp_tolower(__c);}
+#else  // tolower
+using ::tolower;
+#endif  // tolower
+
+#ifdef toupper
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_toupper(int __c) {return toupper(__c);}
+#undef toupper
+inline _LIBCPP_INLINE_VISIBILITY int toupper(int __c) {return __libcpp_toupper(__c);}
+#else  // toupper
+using ::toupper;
+#endif  // toupper
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CCTYPE
diff --git a/include/c++/v1/cerrno b/include/c++/v1/cerrno
new file mode 100644
index 0000000..9804e4e
--- /dev/null
+++ b/include/c++/v1/cerrno
@@ -0,0 +1,393 @@
+// -*- C++ -*-
+//===-------------------------- cerrno ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CERRNO
+#define _LIBCPP_CERRNO
+
+/*
+    cerrno synopsis
+
+Macros:
+
+    EDOM
+    EILSEQ  // C99
+    ERANGE
+    errno
+
+*/
+
+#include <__config>
+#include <errno.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#if !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
+
+#ifdef ELAST
+
+const int __elast1 = ELAST+1;
+const int __elast2 = ELAST+2;
+
+#else
+
+const int __elast1 = 104;
+const int __elast2 = 105;
+
+#endif
+
+#ifdef ENOTRECOVERABLE
+
+#define EOWNERDEAD __elast1
+
+#ifdef ELAST
+#undef ELAST
+#define ELAST EOWNERDEAD
+#endif
+
+#elif defined(EOWNERDEAD)
+
+#define ENOTRECOVERABLE __elast1
+#ifdef ELAST
+#undef ELAST
+#define ELAST ENOTRECOVERABLE
+#endif
+
+#else  // defined(EOWNERDEAD)
+
+#define EOWNERDEAD __elast1
+#define ENOTRECOVERABLE __elast2
+#ifdef ELAST
+#undef ELAST
+#define ELAST ENOTRECOVERABLE
+#endif
+
+#endif  // defined(EOWNERDEAD)
+
+#endif  // !defined(EOWNERDEAD) || !defined(ENOTRECOVERABLE)
+
+//  supply errno values likely to be missing, particularly on Windows
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT 9901
+#endif
+
+#ifndef EADDRINUSE
+#define EADDRINUSE 9902
+#endif
+
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL 9903
+#endif
+
+#ifndef EISCONN
+#define EISCONN 9904
+#endif
+
+#ifndef EBADMSG
+#define EBADMSG 9905
+#endif
+
+#ifndef ECONNABORTED
+#define ECONNABORTED 9906
+#endif
+
+#ifndef EALREADY
+#define EALREADY 9907
+#endif
+
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 9908
+#endif
+
+#ifndef ECONNRESET
+#define ECONNRESET 9909
+#endif
+
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ 9910
+#endif
+
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH 9911
+#endif
+
+#ifndef EIDRM
+#define EIDRM 9912
+#endif
+
+#ifndef EMSGSIZE
+#define EMSGSIZE 9913
+#endif
+
+#ifndef ENETDOWN
+#define ENETDOWN 9914
+#endif
+
+#ifndef ENETRESET
+#define ENETRESET 9915
+#endif
+
+#ifndef ENETUNREACH
+#define ENETUNREACH 9916
+#endif
+
+#ifndef ENOBUFS
+#define ENOBUFS 9917
+#endif
+
+#ifndef ENOLINK
+#define ENOLINK 9918
+#endif
+
+#ifndef ENODATA
+#define ENODATA 9919
+#endif
+
+#ifndef ENOMSG
+#define ENOMSG 9920
+#endif
+
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 9921
+#endif
+
+#ifndef ENOSR
+#define ENOSR 9922
+#endif
+
+#ifndef ENOTSOCK
+#define ENOTSOCK 9923
+#endif
+
+#ifndef ENOSTR
+#define ENOSTR 9924
+#endif
+
+#ifndef ENOTCONN
+#define ENOTCONN 9925
+#endif
+
+#ifndef ENOTSUP
+#define ENOTSUP 9926
+#endif
+
+#ifndef ECANCELED
+#define ECANCELED 9927
+#endif
+
+#ifndef EINPROGRESS
+#define EINPROGRESS 9928
+#endif
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 9929
+#endif
+
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK 9930
+#endif
+
+#ifndef EOWNERDEAD
+#define EOWNERDEAD  9931
+#endif
+
+#ifndef EPROTO
+#define EPROTO 9932
+#endif
+
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT 9933
+#endif
+
+#ifndef ENOTRECOVERABLE
+#define ENOTRECOVERABLE 9934
+#endif
+
+#ifndef ETIME
+#define ETIME 9935
+#endif
+
+#ifndef ETXTBSY
+#define ETXTBSY 9936
+#endif
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 9938
+#endif
+
+#ifndef ELOOP
+#define ELOOP 9939
+#endif
+
+#ifndef EOVERFLOW
+#define EOVERFLOW 9940
+#endif
+
+#ifndef EPROTOTYPE
+#define EPROTOTYPE 9941
+#endif
+
+#ifndef ENOSYS
+#define ENOSYS 9942
+#endif
+
+#ifndef EINVAL
+#define EINVAL 9943
+#endif
+
+#ifndef ERANGE
+#define ERANGE 9944
+#endif
+
+#ifndef EILSEQ
+#define EILSEQ 9945
+#endif
+
+//  Windows Mobile doesn't appear to define these:
+
+#ifndef E2BIG
+#define E2BIG 9946
+#endif
+
+#ifndef EDOM
+#define EDOM 9947
+#endif
+
+#ifndef EFAULT
+#define EFAULT 9948
+#endif
+
+#ifndef EBADF
+#define EBADF 9949
+#endif
+
+#ifndef EPIPE
+#define EPIPE 9950
+#endif
+
+#ifndef EXDEV
+#define EXDEV 9951
+#endif
+
+#ifndef EBUSY
+#define EBUSY 9952
+#endif
+
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 9953
+#endif
+
+#ifndef ENOEXEC
+#define ENOEXEC 9954
+#endif
+
+#ifndef EEXIST
+#define EEXIST 9955
+#endif
+
+#ifndef EFBIG
+#define EFBIG 9956
+#endif
+
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 9957
+#endif
+
+#ifndef ENOTTY
+#define ENOTTY 9958
+#endif
+
+#ifndef EINTR
+#define EINTR 9959
+#endif
+
+#ifndef ESPIPE
+#define ESPIPE 9960
+#endif
+
+#ifndef EIO
+#define EIO 9961
+#endif
+
+#ifndef EISDIR
+#define EISDIR 9962
+#endif
+
+#ifndef ECHILD
+#define ECHILD 9963
+#endif
+
+#ifndef ENOLCK
+#define ENOLCK 9964
+#endif
+
+#ifndef ENOSPC
+#define ENOSPC 9965
+#endif
+
+#ifndef ENXIO
+#define ENXIO 9966
+#endif
+
+#ifndef ENODEV
+#define ENODEV 9967
+#endif
+
+#ifndef ENOENT
+#define ENOENT 9968
+#endif
+
+#ifndef ESRCH
+#define ESRCH 9969
+#endif
+
+#ifndef ENOTDIR
+#define ENOTDIR 9970
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM 9971
+#endif
+
+#ifndef EPERM
+#define EPERM 9972
+#endif
+
+#ifndef EACCES
+#define EACCES 9973
+#endif
+
+#ifndef EROFS
+#define EROFS 9974
+#endif
+
+#ifndef EDEADLK
+#define EDEADLK 9975
+#endif
+
+#ifndef EAGAIN
+#define EAGAIN 9976
+#endif
+
+#ifndef ENFILE
+#define ENFILE 9977
+#endif
+
+#ifndef EMFILE
+#define EMFILE 9978
+#endif
+
+#ifndef EMLINK
+#define EMLINK 9979
+#endif
+
+#endif  // _LIBCPP_CERRNO
diff --git a/include/c++/v1/cfenv b/include/c++/v1/cfenv
new file mode 100644
index 0000000..dd7db37
--- /dev/null
+++ b/include/c++/v1/cfenv
@@ -0,0 +1,82 @@
+// -*- C++ -*-
+//===---------------------------- cctype ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CFENV
+#define _LIBCPP_CFENV
+
+/*
+    cfenv synopsis
+
+This entire header is C99 / C++0X
+
+Macros:
+
+    FE_DIVBYZERO
+    FE_INEXACT
+    FE_INVALID
+    FE_OVERFLOW
+    FE_UNDERFLOW
+    FE_ALL_EXCEPT
+    FE_DOWNWARD
+    FE_TONEAREST
+    FE_TOWARDZERO
+    FE_UPWARD
+    FE_DFL_ENV
+
+namespace std
+{
+
+Types:
+
+    fenv_t
+    fexcept_t
+
+int feclearexcept(int excepts);
+int fegetexceptflag(fexcept_t* flagp, int excepts);
+int feraiseexcept(int excepts);
+int fesetexceptflag(const fexcept_t* flagp, int excepts);
+int fetestexcept(int excepts);
+int fegetround();
+int fesetround(int round);
+int fegetenv(fenv_t* envp);
+int feholdexcept(fenv_t* envp);
+int fesetenv(const fenv_t* envp);
+int feupdateenv(const fenv_t* envp);
+
+}  // std
+*/
+
+#include <__config>
+#include <fenv.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::fenv_t;
+using ::fexcept_t;
+
+using ::feclearexcept;
+using ::fegetexceptflag;
+using ::feraiseexcept;
+using ::fesetexceptflag;
+using ::fetestexcept;
+using ::fegetround;
+using ::fesetround;
+using ::fegetenv;
+using ::feholdexcept;
+using ::fesetenv;
+using ::feupdateenv;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CFENV
diff --git a/include/c++/v1/cfloat b/include/c++/v1/cfloat
new file mode 100644
index 0000000..5fa5655
--- /dev/null
+++ b/include/c++/v1/cfloat
@@ -0,0 +1,78 @@
+// -*- C++ -*-
+//===--------------------------- cfloat -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CFLOAT
+#define _LIBCPP_CFLOAT
+
+/*
+    cfloat synopsis
+
+Macros:
+
+    FLT_ROUNDS
+    FLT_EVAL_METHOD     // C99
+    FLT_RADIX
+
+    FLT_MANT_DIG
+    DBL_MANT_DIG
+    LDBL_MANT_DIG
+
+    DECIMAL_DIG         // C99
+
+    FLT_DIG
+    DBL_DIG
+    LDBL_DIG
+
+    FLT_MIN_EXP
+    DBL_MIN_EXP
+    LDBL_MIN_EXP
+
+    FLT_MIN_10_EXP
+    DBL_MIN_10_EXP
+    LDBL_MIN_10_EXP
+
+    FLT_MAX_EXP
+    DBL_MAX_EXP
+    LDBL_MAX_EXP
+
+    FLT_MAX_10_EXP
+    DBL_MAX_10_EXP
+    LDBL_MAX_10_EXP
+
+    FLT_MAX
+    DBL_MAX
+    LDBL_MAX
+
+    FLT_EPSILON
+    DBL_EPSILON
+    LDBL_EPSILON
+
+    FLT_MIN
+    DBL_MIN
+    LDBL_MIN
+
+*/
+
+#include <__config>
+#include <float.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifndef FLT_EVAL_METHOD
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#endif
+
+#ifndef DECIMAL_DIG
+#define DECIMAL_DIG __DECIMAL_DIG__
+#endif
+
+#endif  // _LIBCPP_CFLOAT
diff --git a/include/c++/v1/chrono b/include/c++/v1/chrono
new file mode 100644
index 0000000..2c65eee
--- /dev/null
+++ b/include/c++/v1/chrono
@@ -0,0 +1,1027 @@
+// -*- C++ -*-
+//===---------------------------- chrono ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CHRONO
+#define _LIBCPP_CHRONO
+
+/*
+    chrono synopsis
+
+namespace std
+{
+namespace chrono
+{
+
+template <class ToDuration, class Rep, class Period>
+constexpr
+ToDuration
+duration_cast(const duration<Rep, Period>& fd);
+
+template <class Rep> struct treat_as_floating_point : is_floating_point<Rep> {};
+
+template <class Rep>
+struct duration_values
+{
+public:
+    static constexpr Rep zero();
+    static constexpr Rep max();
+    static constexpr Rep min();
+};
+
+// duration
+
+template <class Rep, class Period = ratio<1>>
+class duration
+{
+    static_assert(!__is_duration<Rep>::value, "A duration representation can not be a duration");
+    static_assert(__is_ratio<Period>::value, "Second template parameter of duration must be a std::ratio");
+    static_assert(Period::num > 0, "duration period must be positive");
+public:
+    typedef Rep rep;
+    typedef Period period;
+
+    constexpr duration() = default;
+    template <class Rep2>
+        constexpr explicit duration(const Rep2& r,
+            typename enable_if
+            <
+               is_convertible<Rep2, rep>::value &&
+               (treat_as_floating_point<rep>::value ||
+               !treat_as_floating_point<rep>::value && !treat_as_floating_point<Rep2>::value)
+            >::type* = 0);
+
+    // conversions
+    template <class Rep2, class Period2>
+        constexpr duration(const duration<Rep2, Period2>& d,
+            typename enable_if
+            <
+                treat_as_floating_point<rep>::value ||
+                ratio_divide<Period2, period>::type::den == 1
+            >::type* = 0);
+
+    // observer
+
+    constexpr rep count() const;
+
+    // arithmetic
+
+    constexpr duration  operator+() const;
+    constexpr duration  operator-() const;
+    duration& operator++();
+    duration  operator++(int);
+    duration& operator--();
+    duration  operator--(int);
+
+    duration& operator+=(const duration& d);
+    duration& operator-=(const duration& d);
+
+    duration& operator*=(const rep& rhs);
+    duration& operator/=(const rep& rhs);
+
+    // special values
+
+    static constexpr duration zero();
+    static constexpr duration min();
+    static constexpr duration max();
+};
+
+typedef duration<long long,         nano> nanoseconds;
+typedef duration<long long,        micro> microseconds;
+typedef duration<long long,        milli> milliseconds;
+typedef duration<long long              > seconds;
+typedef duration<     long, ratio<  60> > minutes;
+typedef duration<     long, ratio<3600> > hours;
+
+template <class Clock, class Duration = typename Clock::duration>
+class time_point
+{
+public:
+    typedef Clock                     clock;
+    typedef Duration                  duration;
+    typedef typename duration::rep    rep;
+    typedef typename duration::period period;
+private:
+    duration d_;  // exposition only
+
+public:
+    time_point();  // has value "epoch" // constexpr in C++14
+    explicit time_point(const duration& d);  // same as time_point() + d // constexpr in C++14
+
+    // conversions
+    template <class Duration2>
+       time_point(const time_point<clock, Duration2>& t); // constexpr in C++14
+
+    // observer
+
+    duration time_since_epoch() const; // constexpr in C++14
+
+    // arithmetic
+
+    time_point& operator+=(const duration& d);
+    time_point& operator-=(const duration& d);
+
+    // special values
+
+    static constexpr time_point min();
+    static constexpr time_point max();
+};
+
+} // chrono
+
+// common_type traits
+template <class Rep1, class Period1, class Rep2, class Period2>
+  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>>;
+
+template <class Clock, class Duration1, class Duration2>
+  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>>;
+
+namespace chrono {
+
+// duration arithmetic
+template <class Rep1, class Period1, class Rep2, class Period2>
+  constexpr
+  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
+  operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+  constexpr
+  typename common_type<duration<Rep1, Period1>, duration<Rep2, Period2>>::type
+  operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period, class Rep2>
+  constexpr
+  duration<typename common_type<Rep1, Rep2>::type, Period>
+  operator*(const duration<Rep1, Period>& d, const Rep2& s);
+template <class Rep1, class Period, class Rep2>
+  constexpr
+  duration<typename common_type<Rep1, Rep2>::type, Period>
+  operator*(const Rep1& s, const duration<Rep2, Period>& d);
+template <class Rep1, class Period, class Rep2>
+  constexpr
+  duration<typename common_type<Rep1, Rep2>::type, Period>
+  operator/(const duration<Rep1, Period>& d, const Rep2& s);
+template <class Rep1, class Period1, class Rep2, class Period2>
+  constexpr
+  typename common_type<Rep1, Rep2>::type
+  operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+
+// duration comparisons
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator<=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator> (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Rep2, class Period2>
+   constexpr
+   bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
+
+// duration_cast
+template <class ToDuration, class Rep, class Period>
+  ToDuration duration_cast(const duration<Rep, Period>& d);
+
+// time_point arithmetic (all constexpr in C++14)
+template <class Clock, class Duration1, class Rep2, class Period2>
+  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
+  operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Rep1, class Period1, class Clock, class Duration2>
+  time_point<Clock, typename common_type<duration<Rep1, Period1>, Duration2>::type>
+  operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Rep2, class Period2>
+  time_point<Clock, typename common_type<Duration1, duration<Rep2, Period2>>::type>
+  operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+  typename common_type<Duration1, Duration2>::type
+  operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+// time_point comparisons (all constexpr in C++14)
+template <class Clock, class Duration1, class Duration2>
+   bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+   bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+   bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+   bool operator<=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+   bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+template <class Clock, class Duration1, class Duration2>
+   bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
+
+// time_point_cast (constexpr in C++14)
+
+template <class ToDuration, class Clock, class Duration>
+  time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
+
+// Clocks
+
+class system_clock
+{
+public:
+    typedef microseconds                     duration;
+    typedef duration::rep                    rep;
+    typedef duration::period                 period;
+    typedef chrono::time_point<system_clock> time_point;
+    static const bool is_steady =            false; // constexpr in C++14
+
+    static time_point now() noexcept;
+    static time_t     to_time_t  (const time_point& __t) noexcept;
+    static time_point from_time_t(time_t __t) noexcept;
+};
+
+class steady_clock
+{
+public:
+    typedef nanoseconds                                   duration;
+    typedef duration::rep                                 rep;
+    typedef duration::period                              period;
+    typedef chrono::time_point<steady_clock, duration>    time_point;
+    static const bool is_steady =                         true; // constexpr in C++14
+
+    static time_point now() noexcept;
+};
+
+typedef steady_clock high_resolution_clock;
+
+}  // chrono
+
+constexpr chrono::hours                                 operator "" h(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , ratio<3600,1>> operator "" h(long double); // C++14
+constexpr chrono::minutes                               operator "" min(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , ratio<60,1>>   operator "" min(long double); // C++14
+constexpr chrono::seconds                               operator "" s(unsigned long long); // C++14
+constexpr chrono::duration<unspecified >                operator "" s(long double); // C++14
+constexpr chrono::milliseconds                          operator "" ms(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , milli>         operator "" ms(long double); // C++14
+constexpr chrono::microseconds                          operator "" us(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , micro>         operator "" us(long double); // C++14
+constexpr chrono::nanoseconds                           operator "" ns(unsigned long long); // C++14
+constexpr chrono::duration<unspecified , nano>          operator "" ns(long double); // C++14
+
+}  // std
+*/
+
+#include <__config>
+#include <ctime>
+#include <type_traits>
+#include <ratio>
+#include <limits>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace chrono
+{
+
+template <class _Rep, class _Period = ratio<1> > class _LIBCPP_TYPE_VIS_ONLY duration;
+
+template <class _Tp>
+struct __is_duration : false_type {};
+
+template <class _Rep, class _Period>
+struct __is_duration<duration<_Rep, _Period> > : true_type  {};
+
+template <class _Rep, class _Period>
+struct __is_duration<const duration<_Rep, _Period> > : true_type  {};
+
+template <class _Rep, class _Period>
+struct __is_duration<volatile duration<_Rep, _Period> > : true_type  {};
+
+template <class _Rep, class _Period>
+struct __is_duration<const volatile duration<_Rep, _Period> > : true_type  {};
+
+} // chrono
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::duration<_Rep1, _Period1>,
+                                         chrono::duration<_Rep2, _Period2> >
+{
+    typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
+                             typename __ratio_gcd<_Period1, _Period2>::type> type;
+};
+
+namespace chrono {
+
+// duration_cast
+
+template <class _FromDuration, class _ToDuration,
+          class _Period = typename ratio_divide<typename _FromDuration::period, typename _ToDuration::period>::type,
+          bool = _Period::num == 1,
+          bool = _Period::den == 1>
+struct __duration_cast;
+
+template <class _FromDuration, class _ToDuration, class _Period>
+struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _ToDuration operator()(const _FromDuration& __fd) const
+    {
+        return _ToDuration(static_cast<typename _ToDuration::rep>(__fd.count()));
+    }
+};
+
+template <class _FromDuration, class _ToDuration, class _Period>
+struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _ToDuration operator()(const _FromDuration& __fd) const
+    {
+        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
+        return _ToDuration(static_cast<typename _ToDuration::rep>(
+                           static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den)));
+    }
+};
+
+template <class _FromDuration, class _ToDuration, class _Period>
+struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _ToDuration operator()(const _FromDuration& __fd) const
+    {
+        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
+        return _ToDuration(static_cast<typename _ToDuration::rep>(
+                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)));
+    }
+};
+
+template <class _FromDuration, class _ToDuration, class _Period>
+struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _ToDuration operator()(const _FromDuration& __fd) const
+    {
+        typedef typename common_type<typename _ToDuration::rep, typename _FromDuration::rep, intmax_t>::type _Ct;
+        return _ToDuration(static_cast<typename _ToDuration::rep>(
+                           static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num)
+                                                          / static_cast<_Ct>(_Period::den)));
+    }
+};
+
+template <class _ToDuration, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename enable_if
+<
+    __is_duration<_ToDuration>::value,
+    _ToDuration
+>::type
+duration_cast(const duration<_Rep, _Period>& __fd)
+{
+    return __duration_cast<duration<_Rep, _Period>, _ToDuration>()(__fd);
+}
+
+template <class _Rep>
+struct _LIBCPP_TYPE_VIS_ONLY treat_as_floating_point : is_floating_point<_Rep> {};
+
+template <class _Rep>
+struct _LIBCPP_TYPE_VIS_ONLY duration_values
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max()  {return numeric_limits<_Rep>::max();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min()  {return numeric_limits<_Rep>::lowest();}
+};
+
+// duration
+
+template <class _Rep, class _Period>
+class _LIBCPP_TYPE_VIS_ONLY duration
+{
+    static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration");
+    static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio");
+    static_assert(_Period::num > 0, "duration period must be positive");
+
+    template <class _R1, class _R2>
+    struct __no_overflow
+    {
+    private:
+        static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
+        static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+        static const intmax_t __n1 = _R1::num / __gcd_n1_n2;
+        static const intmax_t __d1 = _R1::den / __gcd_d1_d2;
+        static const intmax_t __n2 = _R2::num / __gcd_n1_n2;
+        static const intmax_t __d2 = _R2::den / __gcd_d1_d2;
+        static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1);
+
+        template <intmax_t _Xp, intmax_t _Yp, bool __overflow>
+        struct __mul    // __overflow == false
+        {
+            static const intmax_t value = _Xp * _Yp;
+        };
+
+        template <intmax_t _Xp, intmax_t _Yp>
+        struct __mul<_Xp, _Yp, true>
+        {
+            static const intmax_t value = 1;
+        };
+
+    public:
+        static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1);
+        typedef ratio<__mul<__n1, __d2, !value>::value,
+                      __mul<__n2, __d1, !value>::value> type;
+    };
+    
+public:
+    typedef _Rep rep;
+    typedef _Period period;
+private:
+    rep __rep_;
+public:
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+        duration() = default;
+#else
+        duration() {}
+#endif
+
+    template <class _Rep2>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+        explicit duration(const _Rep2& __r,
+            typename enable_if
+            <
+               is_convertible<_Rep2, rep>::value &&
+               (treat_as_floating_point<rep>::value ||
+               !treat_as_floating_point<_Rep2>::value)
+            >::type* = 0)
+                : __rep_(__r) {}
+
+    // conversions
+    template <class _Rep2, class _Period2>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+        duration(const duration<_Rep2, _Period2>& __d,
+            typename enable_if
+            <
+                __no_overflow<_Period2, period>::value && (
+                treat_as_floating_point<rep>::value ||
+                (__no_overflow<_Period2, period>::type::den == 1 &&
+                 !treat_as_floating_point<_Rep2>::value))
+            >::type* = 0)
+                : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
+
+    // observer
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;}
+
+    // arithmetic
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration  operator+() const {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR duration  operator-() const {return duration(-__rep_);}
+    _LIBCPP_INLINE_VISIBILITY duration& operator++()      {++__rep_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration  operator++(int)   {return duration(__rep_++);}
+    _LIBCPP_INLINE_VISIBILITY duration& operator--()      {--__rep_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration  operator--(int)   {return duration(__rep_--);}
+
+    _LIBCPP_INLINE_VISIBILITY duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY duration& operator*=(const rep& rhs) {__rep_ *= rhs; return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration& operator/=(const rep& rhs) {__rep_ /= rhs; return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const rep& rhs) {__rep_ %= rhs; return *this;}
+    _LIBCPP_INLINE_VISIBILITY duration& operator%=(const duration& rhs) {__rep_ %= rhs.count(); return *this;}
+
+    // special values
+
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() {return duration(duration_values<rep>::zero());}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min()  {return duration(duration_values<rep>::min());}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max()  {return duration(duration_values<rep>::max());}
+};
+
+typedef duration<long long,         nano> nanoseconds;
+typedef duration<long long,        micro> microseconds;
+typedef duration<long long,        milli> milliseconds;
+typedef duration<long long              > seconds;
+typedef duration<     long, ratio<  60> > minutes;
+typedef duration<     long, ratio<3600> > hours;
+
+// Duration ==
+
+template <class _LhsDuration, class _RhsDuration>
+struct __duration_eq
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
+        {
+            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
+            return _Ct(__lhs).count() == _Ct(__rhs).count();
+        }
+};
+
+template <class _LhsDuration>
+struct __duration_eq<_LhsDuration, _LhsDuration>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
+        {return __lhs.count() == __rhs.count();}
+};
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
+}
+
+// Duration !=
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return !(__lhs == __rhs);
+}
+
+// Duration <
+
+template <class _LhsDuration, class _RhsDuration>
+struct __duration_lt
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const
+        {
+            typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct;
+            return _Ct(__lhs).count() < _Ct(__rhs).count();
+        }
+};
+
+template <class _LhsDuration>
+struct __duration_lt<_LhsDuration, _LhsDuration>
+{
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const
+        {return __lhs.count() < __rhs.count();}
+};
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return __duration_lt<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs);
+}
+
+// Duration >
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return __rhs < __lhs;
+}
+
+// Duration <=
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return !(__rhs < __lhs);
+}
+
+// Duration >=
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+bool
+operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return !(__lhs < __rhs);
+}
+
+// Duration +
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
+operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
+    return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count());
+}
+
+// Duration -
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
+operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
+    return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count());
+}
+
+// Duration *
+
+template <class _Rep1, class _Period, class _Rep2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename enable_if
+<
+    is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value,
+    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
+>::type
+operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
+{
+    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
+    typedef duration<_Cr, _Period> _Cd;
+    return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s));
+}
+
+template <class _Rep1, class _Period, class _Rep2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename enable_if
+<
+    is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value,
+    duration<typename common_type<_Rep1, _Rep2>::type, _Period>
+>::type
+operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)
+{
+    return __d * __s;
+}
+
+// Duration /
+
+template <class _Duration, class _Rep, bool = __is_duration<_Rep>::value>
+struct __duration_divide_result
+{
+};
+
+template <class _Duration, class _Rep2,
+    bool = is_convertible<_Rep2,
+                          typename common_type<typename _Duration::rep, _Rep2>::type>::value>
+struct __duration_divide_imp
+{
+};
+
+template <class _Rep1, class _Period, class _Rep2>
+struct __duration_divide_imp<duration<_Rep1, _Period>, _Rep2, true>
+{
+    typedef duration<typename common_type<_Rep1, _Rep2>::type, _Period> type;
+};
+
+template <class _Rep1, class _Period, class _Rep2>
+struct __duration_divide_result<duration<_Rep1, _Period>, _Rep2, false>
+    : __duration_divide_imp<duration<_Rep1, _Period>, _Rep2>
+{
+};
+
+template <class _Rep1, class _Period, class _Rep2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
+operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
+{
+    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
+    typedef duration<_Cr, _Period> _Cd;
+    return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s));
+}
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename common_type<_Rep1, _Rep2>::type
+operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Ct;
+    return _Ct(__lhs).count() / _Ct(__rhs).count();
+}
+
+// Duration %
+
+template <class _Rep1, class _Period, class _Rep2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename __duration_divide_result<duration<_Rep1, _Period>, _Rep2>::type
+operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
+{
+    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
+    typedef duration<_Cr, _Period> _Cd;
+    return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s));
+}
+
+template <class _Rep1, class _Period1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type
+operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    typedef typename common_type<_Rep1, _Rep2>::type _Cr;
+    typedef typename common_type<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >::type _Cd;
+    return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count()));
+}
+
+//////////////////////////////////////////////////////////
+///////////////////// time_point /////////////////////////
+//////////////////////////////////////////////////////////
+
+template <class _Clock, class _Duration = typename _Clock::duration>
+class _LIBCPP_TYPE_VIS_ONLY time_point
+{
+    static_assert(__is_duration<_Duration>::value,
+                  "Second template parameter of time_point must be a std::chrono::duration");
+public:
+    typedef _Clock                    clock;
+    typedef _Duration                 duration;
+    typedef typename duration::rep    rep;
+    typedef typename duration::period period;
+private:
+    duration __d_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point() : __d_(duration::zero()) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit time_point(const duration& __d) : __d_(__d) {}
+
+    // conversions
+    template <class _Duration2>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    time_point(const time_point<clock, _Duration2>& t,
+        typename enable_if
+        <
+            is_convertible<_Duration2, duration>::value
+        >::type* = 0)
+            : __d_(t.time_since_epoch()) {}
+
+    // observer
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 duration time_since_epoch() const {return __d_;}
+
+    // arithmetic
+
+    _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}
+    _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;}
+
+    // special values
+
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() {return time_point(duration::min());}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() {return time_point(duration::max());}
+};
+
+} // chrono
+
+template <class _Clock, class _Duration1, class _Duration2>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<chrono::time_point<_Clock, _Duration1>,
+                                         chrono::time_point<_Clock, _Duration2> >
+{
+    typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type;
+};
+
+namespace chrono {
+
+template <class _ToDuration, class _Clock, class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+time_point<_Clock, _ToDuration>
+time_point_cast(const time_point<_Clock, _Duration>& __t)
+{
+    return time_point<_Clock, _ToDuration>(_VSTD::chrono::duration_cast<_ToDuration>(__t.time_since_epoch()));
+}
+
+// time_point ==
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return __lhs.time_since_epoch() == __rhs.time_since_epoch();
+}
+
+// time_point !=
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return !(__lhs == __rhs);
+}
+
+// time_point <
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return __lhs.time_since_epoch() < __rhs.time_since_epoch();
+}
+
+// time_point >
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return __rhs < __lhs;
+}
+
+// time_point <=
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return !(__rhs < __lhs);
+}
+
+// time_point >=
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return !(__lhs < __rhs);
+}
+
+// time_point operator+(time_point x, duration y);
+
+template <class _Clock, class _Duration1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
+operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr;
+    return _Tr (__lhs.time_since_epoch() + __rhs);
+}
+
+// time_point operator+(duration x, time_point y);
+
+template <class _Rep1, class _Period1, class _Clock, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+time_point<_Clock, typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
+operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return __rhs + __lhs;
+}
+
+// time_point operator-(time_point x, duration y);
+
+template <class _Clock, class _Duration1, class _Rep2, class _Period2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type>
+operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs)
+{
+    return __lhs + (-__rhs);
+}
+
+// duration operator-(time_point x, time_point y);
+
+template <class _Clock, class _Duration1, class _Duration2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename common_type<_Duration1, _Duration2>::type
+operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs)
+{
+    return __lhs.time_since_epoch() - __rhs.time_since_epoch();
+}
+
+//////////////////////////////////////////////////////////
+/////////////////////// clocks ///////////////////////////
+//////////////////////////////////////////////////////////
+
+class _LIBCPP_TYPE_VIS system_clock
+{
+public:
+    typedef microseconds                     duration;
+    typedef duration::rep                    rep;
+    typedef duration::period                 period;
+    typedef chrono::time_point<system_clock> time_point;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
+
+    static time_point now() _NOEXCEPT;
+    static time_t     to_time_t  (const time_point& __t) _NOEXCEPT;
+    static time_point from_time_t(time_t __t) _NOEXCEPT;
+};
+
+class _LIBCPP_TYPE_VIS steady_clock
+{
+public:
+    typedef nanoseconds                                   duration;
+    typedef duration::rep                                 rep;
+    typedef duration::period                              period;
+    typedef chrono::time_point<steady_clock, duration>    time_point;
+    static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = true;
+
+    static time_point now() _NOEXCEPT;
+};
+
+typedef steady_clock high_resolution_clock;
+
+} // chrono
+
+#if _LIBCPP_STD_VER > 11
+// Suffixes for duration literals [time.duration.literals]
+inline namespace literals
+{ 
+  inline namespace chrono_literals
+  {
+
+    constexpr chrono::hours operator"" h(unsigned long long __h)
+    {
+        return chrono::hours(static_cast<chrono::hours::rep>(__h));
+    }
+
+    constexpr chrono::duration<long double, ratio<3600,1>> operator"" h(long double __h)
+    {
+        return chrono::duration<long double, ratio<3600,1>>(__h);
+    }
+
+
+    constexpr chrono::minutes operator"" min(unsigned long long __m)
+    {
+        return chrono::minutes(static_cast<chrono::minutes::rep>(__m));
+    }
+
+    constexpr chrono::duration<long double, ratio<60,1>> operator"" min(long double __m)
+    {
+        return chrono::duration<long double, ratio<60,1>> (__m);
+    }
+
+
+    constexpr chrono::seconds operator"" s(unsigned long long __s)
+    {
+        return chrono::seconds(static_cast<chrono::seconds::rep>(__s));
+    }
+
+    constexpr chrono::duration<long double> operator"" s(long double __s)
+    {
+        return chrono::duration<long double> (__s);
+    }
+
+
+    constexpr chrono::milliseconds operator"" ms(unsigned long long __ms)
+    {
+        return chrono::milliseconds(static_cast<chrono::milliseconds::rep>(__ms));
+    }
+
+    constexpr chrono::duration<long double, milli> operator"" ms(long double __ms)
+    {
+        return chrono::duration<long double, milli>(__ms);
+    }
+
+
+    constexpr chrono::microseconds operator"" us(unsigned long long __us)
+    {
+        return chrono::microseconds(static_cast<chrono::microseconds::rep>(__us));
+    }
+
+    constexpr chrono::duration<long double, micro> operator"" us(long double __us)
+    {
+        return chrono::duration<long double, micro> (__us);
+    }
+    
+
+    constexpr chrono::nanoseconds operator"" ns(unsigned long long __ns)
+    {
+        return chrono::nanoseconds(static_cast<chrono::nanoseconds::rep>(__ns));
+    }
+
+    constexpr chrono::duration<long double, nano> operator"" ns(long double __ns)
+    {
+        return chrono::duration<long double, nano> (__ns);
+    }
+
+}}
+
+namespace chrono { // hoist the literals into namespace std::chrono
+   using namespace literals::chrono_literals;
+}
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CHRONO
diff --git a/include/c++/v1/cinttypes b/include/c++/v1/cinttypes
new file mode 100644
index 0000000..786692b
--- /dev/null
+++ b/include/c++/v1/cinttypes
@@ -0,0 +1,259 @@
+// -*- C++ -*-
+//===--------------------------- cinttypes --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CINTTYPES
+#define _LIBCPP_CINTTYPES
+
+/*
+    cinttypes synopsis
+
+This entire header is C99 / C++0X
+
+#include <cstdint>  // <cinttypes> includes <cstdint>
+
+Macros:
+
+    PRId8
+    PRId16
+    PRId32
+    PRId64
+
+    PRIdLEAST8
+    PRIdLEAST16
+    PRIdLEAST32
+    PRIdLEAST64
+
+    PRIdFAST8
+    PRIdFAST16
+    PRIdFAST32
+    PRIdFAST64
+
+    PRIdMAX
+    PRIdPTR
+
+    PRIi8
+    PRIi16
+    PRIi32
+    PRIi64
+
+    PRIiLEAST8
+    PRIiLEAST16
+    PRIiLEAST32
+    PRIiLEAST64
+
+    PRIiFAST8
+    PRIiFAST16
+    PRIiFAST32
+    PRIiFAST64
+
+    PRIiMAX
+    PRIiPTR
+
+    PRIo8
+    PRIo16
+    PRIo32
+    PRIo64
+
+    PRIoLEAST8
+    PRIoLEAST16
+    PRIoLEAST32
+    PRIoLEAST64
+
+    PRIoFAST8
+    PRIoFAST16
+    PRIoFAST32
+    PRIoFAST64
+
+    PRIoMAX
+    PRIoPTR
+
+    PRIu8
+    PRIu16
+    PRIu32
+    PRIu64
+
+    PRIuLEAST8
+    PRIuLEAST16
+    PRIuLEAST32
+    PRIuLEAST64
+
+    PRIuFAST8
+    PRIuFAST16
+    PRIuFAST32
+    PRIuFAST64
+
+    PRIuMAX
+    PRIuPTR
+
+    PRIx8
+    PRIx16
+    PRIx32
+    PRIx64
+
+    PRIxLEAST8
+    PRIxLEAST16
+    PRIxLEAST32
+    PRIxLEAST64
+
+    PRIxFAST8
+    PRIxFAST16
+    PRIxFAST32
+    PRIxFAST64
+
+    PRIxMAX
+    PRIxPTR
+
+    PRIX8
+    PRIX16
+    PRIX32
+    PRIX64
+
+    PRIXLEAST8
+    PRIXLEAST16
+    PRIXLEAST32
+    PRIXLEAST64
+
+    PRIXFAST8
+    PRIXFAST16
+    PRIXFAST32
+    PRIXFAST64
+
+    PRIXMAX
+    PRIXPTR
+
+    SCNd8
+    SCNd16
+    SCNd32
+    SCNd64
+
+    SCNdLEAST8
+    SCNdLEAST16
+    SCNdLEAST32
+    SCNdLEAST64
+
+    SCNdFAST8
+    SCNdFAST16
+    SCNdFAST32
+    SCNdFAST64
+
+    SCNdMAX
+    SCNdPTR
+
+    SCNi8
+    SCNi16
+    SCNi32
+    SCNi64
+
+    SCNiLEAST8
+    SCNiLEAST16
+    SCNiLEAST32
+    SCNiLEAST64
+
+    SCNiFAST8
+    SCNiFAST16
+    SCNiFAST32
+    SCNiFAST64
+
+    SCNiMAX
+    SCNiPTR
+
+    SCNo8
+    SCNo16
+    SCNo32
+    SCNo64
+
+    SCNoLEAST8
+    SCNoLEAST16
+    SCNoLEAST32
+    SCNoLEAST64
+
+    SCNoFAST8
+    SCNoFAST16
+    SCNoFAST32
+    SCNoFAST64
+
+    SCNoMAX
+    SCNoPTR
+
+    SCNu8
+    SCNu16
+    SCNu32
+    SCNu64
+
+    SCNuLEAST8
+    SCNuLEAST16
+    SCNuLEAST32
+    SCNuLEAST64
+
+    SCNuFAST8
+    SCNuFAST16
+    SCNuFAST32
+    SCNuFAST64
+
+    SCNuMAX
+    SCNuPTR
+
+    SCNx8
+    SCNx16
+    SCNx32
+    SCNx64
+
+    SCNxLEAST8
+    SCNxLEAST16
+    SCNxLEAST32
+    SCNxLEAST64
+
+    SCNxFAST8
+    SCNxFAST16
+    SCNxFAST32
+    SCNxFAST64
+
+    SCNxMAX
+    SCNxPTR
+
+namespace std
+{
+
+Types:
+
+    imaxdiv_t
+
+intmax_t  imaxabs(intmax_t j);
+imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
+intmax_t  strtoimax(const char* restrict nptr, char** restrict endptr, int base);
+uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr, int base);
+intmax_t  wcstoimax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+
+}  // std
+*/
+
+#include <__config>
+#include <cstdint>
+#include <inttypes.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using::imaxdiv_t;
+
+using::imaxabs;
+using::imaxdiv;
+using::strtoimax;
+using::strtoumax;
+using::wcstoimax;
+using::wcstoumax;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CINTTYPES
diff --git a/include/c++/v1/ciso646 b/include/c++/v1/ciso646
new file mode 100644
index 0000000..b2efc72
--- /dev/null
+++ b/include/c++/v1/ciso646
@@ -0,0 +1,25 @@
+// -*- C++ -*-
+//===--------------------------- ciso646 ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CISO646
+#define _LIBCPP_CISO646
+
+/*
+    ciso646 synopsis
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#endif  // _LIBCPP_CISO646
diff --git a/include/c++/v1/climits b/include/c++/v1/climits
new file mode 100644
index 0000000..81ffecd
--- /dev/null
+++ b/include/c++/v1/climits
@@ -0,0 +1,48 @@
+// -*- C++ -*-
+//===--------------------------- climits ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CLIMITS
+#define _LIBCPP_CLIMITS
+
+/*
+    climits synopsis
+
+Macros:
+
+    CHAR_BIT
+    SCHAR_MIN
+    SCHAR_MAX
+    UCHAR_MAX
+    CHAR_MIN
+    CHAR_MAX
+    MB_LEN_MAX
+    SHRT_MIN
+    SHRT_MAX
+    USHRT_MAX
+    INT_MIN
+    INT_MAX
+    UINT_MAX
+    LONG_MIN
+    LONG_MAX
+    ULONG_MAX
+    LLONG_MIN   // C99
+    LLONG_MAX   // C99
+    ULLONG_MAX  // C99
+
+*/
+
+#include <__config>
+#include <limits.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#endif  // _LIBCPP_CLIMITS
diff --git a/include/c++/v1/clocale b/include/c++/v1/clocale
new file mode 100644
index 0000000..f8b8f0d
--- /dev/null
+++ b/include/c++/v1/clocale
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+//===--------------------------- clocale ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CLOCALE
+#define _LIBCPP_CLOCALE
+
+/*
+    clocale synopsis
+
+Macros:
+
+    LC_ALL
+    LC_COLLATE
+    LC_CTYPE
+    LC_MONETARY
+    LC_NUMERIC
+    LC_TIME
+    NULL
+
+namespace std
+{
+
+struct lconv;
+char* setlocale(int category, const char* locale);
+lconv* localeconv();
+
+}  // std
+
+*/
+
+#include <__config>
+#include <locale.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::lconv;
+using ::setlocale;
+using ::localeconv;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CLOCALE
diff --git a/include/c++/v1/cmath b/include/c++/v1/cmath
new file mode 100644
index 0000000..964c672
--- /dev/null
+++ b/include/c++/v1/cmath
@@ -0,0 +1,1685 @@
+// -*- C++ -*-
+//===---------------------------- cmath -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CMATH
+#define _LIBCPP_CMATH
+
+/*
+    cmath synopsis
+
+Macros:
+
+    HUGE_VAL
+    HUGE_VALF               // C99
+    HUGE_VALL               // C99
+    INFINITY                // C99
+    NAN                     // C99
+    FP_INFINITE             // C99
+    FP_NAN                  // C99
+    FP_NORMAL               // C99
+    FP_SUBNORMAL            // C99
+    FP_ZERO                 // C99
+    FP_FAST_FMA             // C99
+    FP_FAST_FMAF            // C99
+    FP_FAST_FMAL            // C99
+    FP_ILOGB0               // C99
+    FP_ILOGBNAN             // C99
+    MATH_ERRNO              // C99
+    MATH_ERREXCEPT          // C99
+    math_errhandling        // C99
+
+namespace std
+{
+
+Types:
+
+    float_t                 // C99
+    double_t                // C99
+
+// C90
+
+floating_point abs(floating_point x);
+
+floating_point acos (arithmetic x);
+float          acosf(float x);
+long double    acosl(long double x);
+
+floating_point asin (arithmetic x);
+float          asinf(float x);
+long double    asinl(long double x);
+
+floating_point atan (arithmetic x);
+float          atanf(float x);
+long double    atanl(long double x);
+
+floating_point atan2 (arithmetic y, arithmetic x);
+float          atan2f(float y, float x);
+long double    atan2l(long double y, long double x);
+
+floating_point ceil (arithmetic x);
+float          ceilf(float x);
+long double    ceill(long double x);
+
+floating_point cos (arithmetic x);
+float          cosf(float x);
+long double    cosl(long double x);
+
+floating_point cosh (arithmetic x);
+float          coshf(float x);
+long double    coshl(long double x);
+
+floating_point exp (arithmetic x);
+float          expf(float x);
+long double    expl(long double x);
+
+floating_point fabs (arithmetic x);
+float          fabsf(float x);
+long double    fabsl(long double x);
+
+floating_point floor (arithmetic x);
+float          floorf(float x);
+long double    floorl(long double x);
+
+floating_point fmod (arithmetic x, arithmetic y);
+float          fmodf(float x, float y);
+long double    fmodl(long double x, long double y);
+
+floating_point frexp (arithmetic value, int* exp);
+float          frexpf(float value, int* exp);
+long double    frexpl(long double value, int* exp);
+
+floating_point ldexp (arithmetic value, int exp);
+float          ldexpf(float value, int exp);
+long double    ldexpl(long double value, int exp);
+
+floating_point log (arithmetic x);
+float          logf(float x);
+long double    logl(long double x);
+
+floating_point log10 (arithmetic x);
+float          log10f(float x);
+long double    log10l(long double x);
+
+floating_point modf (floating_point value, floating_point* iptr);
+float          modff(float value, float* iptr);
+long double    modfl(long double value, long double* iptr);
+
+floating_point pow (arithmetic x, arithmetic y);
+float          powf(float x, float y);
+long double    powl(long double x, long double y);
+
+floating_point sin (arithmetic x);
+float          sinf(float x);
+long double    sinl(long double x);
+
+floating_point sinh (arithmetic x);
+float          sinhf(float x);
+long double    sinhl(long double x);
+
+floating_point sqrt (arithmetic x);
+float          sqrtf(float x);
+long double    sqrtl(long double x);
+
+floating_point tan (arithmetic x);
+float          tanf(float x);
+long double    tanl(long double x);
+
+floating_point tanh (arithmetic x);
+float          tanhf(float x);
+long double    tanhl(long double x);
+
+//  C99
+
+bool signbit(arithmetic x);
+
+int fpclassify(arithmetic x);
+
+bool isfinite(arithmetic x);
+bool isinf(arithmetic x);
+bool isnan(arithmetic x);
+bool isnormal(arithmetic x);
+
+bool isgreater(arithmetic x, arithmetic y);
+bool isgreaterequal(arithmetic x, arithmetic y);
+bool isless(arithmetic x, arithmetic y);
+bool islessequal(arithmetic x, arithmetic y);
+bool islessgreater(arithmetic x, arithmetic y);
+bool isunordered(arithmetic x, arithmetic y);
+
+floating_point acosh (arithmetic x);
+float          acoshf(float x);
+long double    acoshl(long double x);
+
+floating_point asinh (arithmetic x);
+float          asinhf(float x);
+long double    asinhl(long double x);
+
+floating_point atanh (arithmetic x);
+float          atanhf(float x);
+long double    atanhl(long double x);
+
+floating_point cbrt (arithmetic x);
+float          cbrtf(float x);
+long double    cbrtl(long double x);
+
+floating_point copysign (arithmetic x, arithmetic y);
+float          copysignf(float x, float y);
+long double    copysignl(long double x, long double y);
+
+floating_point erf (arithmetic x);
+float          erff(float x);
+long double    erfl(long double x);
+
+floating_point erfc (arithmetic x);
+float          erfcf(float x);
+long double    erfcl(long double x);
+
+floating_point exp2 (arithmetic x);
+float          exp2f(float x);
+long double    exp2l(long double x);
+
+floating_point expm1 (arithmetic x);
+float          expm1f(float x);
+long double    expm1l(long double x);
+
+floating_point fdim (arithmetic x, arithmetic y);
+float          fdimf(float x, float y);
+long double    fdiml(long double x, long double y);
+
+floating_point fma (arithmetic x, arithmetic y, arithmetic z);
+float          fmaf(float x, float y, float z);
+long double    fmal(long double x, long double y, long double z);
+
+floating_point fmax (arithmetic x, arithmetic y);
+float          fmaxf(float x, float y);
+long double    fmaxl(long double x, long double y);
+
+floating_point fmin (arithmetic x, arithmetic y);
+float          fminf(float x, float y);
+long double    fminl(long double x, long double y);
+
+floating_point hypot (arithmetic x, arithmetic y);
+float          hypotf(float x, float y);
+long double    hypotl(long double x, long double y);
+
+int ilogb (arithmetic x);
+int ilogbf(float x);
+int ilogbl(long double x);
+
+floating_point lgamma (arithmetic x);
+float          lgammaf(float x);
+long double    lgammal(long double x);
+
+long long llrint (arithmetic x);
+long long llrintf(float x);
+long long llrintl(long double x);
+
+long long llround (arithmetic x);
+long long llroundf(float x);
+long long llroundl(long double x);
+
+floating_point log1p (arithmetic x);
+float          log1pf(float x);
+long double    log1pl(long double x);
+
+floating_point log2 (arithmetic x);
+float          log2f(float x);
+long double    log2l(long double x);
+
+floating_point logb (arithmetic x);
+float          logbf(float x);
+long double    logbl(long double x);
+
+long lrint (arithmetic x);
+long lrintf(float x);
+long lrintl(long double x);
+
+long lround (arithmetic x);
+long lroundf(float x);
+long lroundl(long double x);
+
+double      nan (const char* str);
+float       nanf(const char* str);
+long double nanl(const char* str);
+
+floating_point nearbyint (arithmetic x);
+float          nearbyintf(float x);
+long double    nearbyintl(long double x);
+
+floating_point nextafter (arithmetic x, arithmetic y);
+float          nextafterf(float x, float y);
+long double    nextafterl(long double x, long double y);
+
+floating_point nexttoward (arithmetic x, long double y);
+float          nexttowardf(float x, long double y);
+long double    nexttowardl(long double x, long double y);
+
+floating_point remainder (arithmetic x, arithmetic y);
+float          remainderf(float x, float y);
+long double    remainderl(long double x, long double y);
+
+floating_point remquo (arithmetic x, arithmetic y, int* pquo);
+float          remquof(float x, float y, int* pquo);
+long double    remquol(long double x, long double y, int* pquo);
+
+floating_point rint (arithmetic x);
+float          rintf(float x);
+long double    rintl(long double x);
+
+floating_point round (arithmetic x);
+float          roundf(float x);
+long double    roundl(long double x);
+
+floating_point scalbln (arithmetic x, long ex);
+float          scalblnf(float x, long ex);
+long double    scalblnl(long double x, long ex);
+
+floating_point scalbn (arithmetic x, int ex);
+float          scalbnf(float x, int ex);
+long double    scalbnl(long double x, int ex);
+
+floating_point tgamma (arithmetic x);
+float          tgammaf(float x);
+long double    tgammal(long double x);
+
+floating_point trunc (arithmetic x);
+float          truncf(float x);
+long double    truncl(long double x);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <math.h>
+#include <type_traits>
+
+#ifdef _LIBCPP_MSVCRT
+#include "support/win32/math_win32.h"
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+// signbit
+
+#ifdef signbit
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_signbit(_A1 __x) _NOEXCEPT
+{
+    return signbit(__x);
+}
+
+#undef signbit
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+signbit(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_signbit((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // signbit
+
+// fpclassify
+
+#ifdef fpclassify
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+int
+__libcpp_fpclassify(_A1 __x) _NOEXCEPT
+{
+    return fpclassify(__x);
+}
+
+#undef fpclassify
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, int>::type
+fpclassify(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_fpclassify((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // fpclassify
+
+// isfinite
+
+#ifdef isfinite
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isfinite(_A1 __x) _NOEXCEPT
+{
+    return isfinite(__x);
+}
+
+#undef isfinite
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isfinite(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_isfinite((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // isfinite
+
+// isinf
+
+#ifdef isinf
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isinf(_A1 __x) _NOEXCEPT
+{
+    return isinf(__x);
+}
+
+#undef isinf
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isinf(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_isinf((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // isinf
+
+// isnan
+
+#ifdef isnan
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isnan(_A1 __x) _NOEXCEPT
+{
+    return isnan(__x);
+}
+
+#undef isnan
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isnan(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_isnan((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // isnan
+
+// isnormal
+
+#ifdef isnormal
+
+template <class _A1>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isnormal(_A1 __x) _NOEXCEPT
+{
+    return isnormal(__x);
+}
+
+#undef isnormal
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
+isnormal(_A1 __x) _NOEXCEPT
+{
+    return __libcpp_isnormal((typename std::__promote<_A1>::type)__x);
+}
+
+#endif  // isnormal
+
+// isgreater
+
+#ifdef isgreater
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isgreater(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return isgreater(__x, __y);
+}
+
+#undef isgreater
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isgreater(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isgreater((type)__x, (type)__y);
+}
+
+#endif  // isgreater
+
+// isgreaterequal
+
+#ifdef isgreaterequal
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return isgreaterequal(__x, __y);
+}
+
+#undef isgreaterequal
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isgreaterequal((type)__x, (type)__y);
+}
+
+#endif  // isgreaterequal
+
+// isless
+
+#ifdef isless
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isless(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return isless(__x, __y);
+}
+
+#undef isless
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isless(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isless((type)__x, (type)__y);
+}
+
+#endif  // isless
+
+// islessequal
+
+#ifdef islessequal
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_islessequal(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return islessequal(__x, __y);
+}
+
+#undef islessequal
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+islessequal(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_islessequal((type)__x, (type)__y);
+}
+
+#endif  // islessequal
+
+// islessgreater
+
+#ifdef islessgreater
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_islessgreater(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return islessgreater(__x, __y);
+}
+
+#undef islessgreater
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+islessgreater(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_islessgreater((type)__x, (type)__y);
+}
+
+#endif  // islessgreater
+
+// isunordered
+
+#ifdef isunordered
+
+template <class _A1, class _A2>
+_LIBCPP_ALWAYS_INLINE
+bool
+__libcpp_isunordered(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    return isunordered(__x, __y);
+}
+
+#undef isunordered
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename std::enable_if
+<
+    std::is_arithmetic<_A1>::value &&
+    std::is_arithmetic<_A2>::value,
+    bool
+>::type
+isunordered(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename std::__promote<_A1, _A2>::type type;
+    return __libcpp_isunordered((type)__x, (type)__y);
+}
+
+#endif  // isunordered
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::signbit;
+using ::fpclassify;
+using ::isfinite;
+using ::isinf;
+using ::isnan;
+using ::isnormal;
+using ::isgreater;
+using ::isgreaterequal;
+using ::isless;
+using ::islessequal;
+using ::islessgreater;
+using ::isunordered;
+using ::isunordered;
+
+using ::float_t;
+using ::double_t;
+
+// abs
+
+#if !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY
+float
+abs(float __x) _NOEXCEPT {return fabsf(__x);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+double
+abs(double __x) _NOEXCEPT {return fabs(__x);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+long double
+abs(long double __x) _NOEXCEPT {return fabsl(__x);}
+#endif // !defined(_AIX)
+
+#ifndef __sun__
+
+// acos
+
+using ::acos;
+using ::acosf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       acos(float __x) _NOEXCEPT       {return acosf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __x) _NOEXCEPT {return acosl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+acos(_A1 __x) _NOEXCEPT {return acos((double)__x);}
+
+// asin
+
+using ::asin;
+using ::asinf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       asin(float __x) _NOEXCEPT       {return asinf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __x) _NOEXCEPT {return asinl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+asin(_A1 __x) _NOEXCEPT {return asin((double)__x);}
+
+// atan
+
+using ::atan;
+using ::atanf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       atan(float __x) _NOEXCEPT       {return atanf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __x) _NOEXCEPT {return atanl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+atan(_A1 __x) _NOEXCEPT {return atan((double)__x);}
+
+// atan2
+
+using ::atan2;
+using ::atan2f;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       atan2(float __y, float __x) _NOEXCEPT             {return atan2f(__y, __x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __y, long double __x) _NOEXCEPT {return atan2l(__y, __x);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+atan2(_A1 __y, _A2 __x) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return atan2((__result_type)__y, (__result_type)__x);
+}
+
+// ceil
+
+using ::ceil;
+using ::ceilf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       ceil(float __x) _NOEXCEPT       {return ceilf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __x) _NOEXCEPT {return ceill(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+ceil(_A1 __x) _NOEXCEPT {return ceil((double)__x);}
+
+// cos
+
+using ::cos;
+using ::cosf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       cos(float __x) _NOEXCEPT       {return cosf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __x) _NOEXCEPT {return cosl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+cos(_A1 __x) _NOEXCEPT {return cos((double)__x);}
+
+// cosh
+
+using ::cosh;
+using ::coshf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       cosh(float __x) _NOEXCEPT       {return coshf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __x) _NOEXCEPT {return coshl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+cosh(_A1 __x) _NOEXCEPT {return cosh((double)__x);}
+
+#endif // __sun__
+// exp
+
+using ::exp;
+using ::expf;
+
+#ifndef __sun__
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       exp(float __x) _NOEXCEPT       {return expf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __x) _NOEXCEPT {return expl(__x);}
+#endif
+
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+exp(_A1 __x) _NOEXCEPT {return exp((double)__x);}
+
+// fabs
+
+using ::fabs;
+using ::fabsf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       fabs(float __x) _NOEXCEPT       {return fabsf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __x) _NOEXCEPT {return fabsl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+fabs(_A1 __x) _NOEXCEPT {return fabs((double)__x);}
+
+// floor
+
+using ::floor;
+using ::floorf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       floor(float __x) _NOEXCEPT       {return floorf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __x) _NOEXCEPT {return floorl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+floor(_A1 __x) _NOEXCEPT {return floor((double)__x);}
+
+// fmod
+
+#endif //__sun__
+using ::fmod;
+using ::fmodf;
+#ifndef __sun__
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       fmod(float __x, float __y) _NOEXCEPT             {return fmodf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __x, long double __y) _NOEXCEPT {return fmodl(__x, __y);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+fmod(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return fmod((__result_type)__x, (__result_type)__y);
+}
+
+
+// frexp
+
+using ::frexp;
+using ::frexpf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       frexp(float __x, int* __e) _NOEXCEPT       {return frexpf(__x, __e);}
+inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __x, int* __e) _NOEXCEPT {return frexpl(__x, __e);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+frexp(_A1 __x, int* __e) _NOEXCEPT {return frexp((double)__x, __e);}
+
+// ldexp
+
+using ::ldexp;
+using ::ldexpf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       ldexp(float __x, int __e) _NOEXCEPT       {return ldexpf(__x, __e);}
+inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __x, int __e) _NOEXCEPT {return ldexpl(__x, __e);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+ldexp(_A1 __x, int __e) _NOEXCEPT {return ldexp((double)__x, __e);}
+
+// log
+
+#endif // __sun__
+using ::log;
+using ::logf;
+#ifndef __sun__
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       log(float __x) _NOEXCEPT       {return logf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log(long double __x) _NOEXCEPT {return logl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+log(_A1 __x) _NOEXCEPT {return log((double)__x);}
+
+
+// log10
+
+using ::log10;
+using ::log10f;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       log10(float __x) _NOEXCEPT       {return log10f(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __x) _NOEXCEPT {return log10l(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+log10(_A1 __x) _NOEXCEPT {return log10((double)__x);}
+
+// modf
+
+using ::modf;
+using ::modff;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       modf(float __x, float* __y) _NOEXCEPT             {return modff(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __x, long double* __y) _NOEXCEPT {return modfl(__x, __y);}
+#endif
+
+// pow
+
+#endif // __sun__ 
+using ::pow;
+using ::powf;
+
+#ifndef __sun__
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       pow(float __x, float __y) _NOEXCEPT             {return powf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __x, long double __y) _NOEXCEPT {return powl(__x, __y);}
+#endif
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+pow(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return pow((__result_type)__x, (__result_type)__y);
+}
+
+// sin
+
+using ::sin;
+using ::sinf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sin(float __x) _NOEXCEPT       {return sinf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __x) _NOEXCEPT {return sinl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+sin(_A1 __x) _NOEXCEPT {return sin((double)__x);}
+
+// sinh
+
+using ::sinh;
+using ::sinhf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sinh(float __x) _NOEXCEPT       {return sinhf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __x) _NOEXCEPT {return sinhl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+sinh(_A1 __x) _NOEXCEPT {return sinh((double)__x);}
+
+// sqrt
+
+#endif // __sun__
+using ::sqrt;
+using ::sqrtf;
+
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(__sun__) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       sqrt(float __x) _NOEXCEPT       {return sqrtf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __x) _NOEXCEPT {return sqrtl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+sqrt(_A1 __x) _NOEXCEPT {return sqrt((double)__x);}
+
+// tan
+
+using ::tan;
+using ::tanf;
+#ifndef __sun__
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       tan(float __x) _NOEXCEPT       {return tanf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __x) _NOEXCEPT {return tanl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+tan(_A1 __x) _NOEXCEPT {return tan((double)__x);}
+
+// tanh
+
+using ::tanh;
+using ::tanhf;
+
+#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX))
+inline _LIBCPP_INLINE_VISIBILITY float       tanh(float __x) _NOEXCEPT       {return tanhf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __x) _NOEXCEPT {return tanhl(__x);}
+#endif
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+tanh(_A1 __x) _NOEXCEPT {return tanh((double)__x);}
+
+// acosh
+
+#ifndef _LIBCPP_MSVCRT
+using ::acosh;
+using ::acoshf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       acosh(float __x) _NOEXCEPT       {return acoshf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double acosh(long double __x) _NOEXCEPT {return acoshl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+acosh(_A1 __x) _NOEXCEPT {return acosh((double)__x);}
+#endif
+
+// asinh
+
+#ifndef _LIBCPP_MSVCRT
+using ::asinh;
+using ::asinhf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       asinh(float __x) _NOEXCEPT       {return asinhf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double asinh(long double __x) _NOEXCEPT {return asinhl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+asinh(_A1 __x) _NOEXCEPT {return asinh((double)__x);}
+#endif
+
+// atanh
+
+#ifndef _LIBCPP_MSVCRT
+using ::atanh;
+using ::atanhf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       atanh(float __x) _NOEXCEPT       {return atanhf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double atanh(long double __x) _NOEXCEPT {return atanhl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+atanh(_A1 __x) _NOEXCEPT {return atanh((double)__x);}
+#endif
+
+// cbrt
+
+#ifndef _LIBCPP_MSVCRT
+using ::cbrt;
+using ::cbrtf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       cbrt(float __x) _NOEXCEPT       {return cbrtf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double cbrt(long double __x) _NOEXCEPT {return cbrtl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+cbrt(_A1 __x) _NOEXCEPT {return cbrt((double)__x);}
+#endif
+
+// copysign
+
+using ::copysign;
+using ::copysignf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       copysign(float __x, float __y) _NOEXCEPT             {return copysignf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double copysign(long double __x, long double __y) _NOEXCEPT {return copysignl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+copysign(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return copysign((__result_type)__x, (__result_type)__y);
+}
+
+#ifndef _LIBCPP_MSVCRT
+
+// erf
+
+using ::erf;
+using ::erff;
+
+inline _LIBCPP_INLINE_VISIBILITY float       erf(float __x) _NOEXCEPT       {return erff(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erf(long double __x) _NOEXCEPT {return erfl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+erf(_A1 __x) _NOEXCEPT {return erf((double)__x);}
+
+// erfc
+
+using ::erfc;
+using ::erfcf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       erfc(float __x) _NOEXCEPT       {return erfcf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double erfc(long double __x) _NOEXCEPT {return erfcl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+erfc(_A1 __x) _NOEXCEPT {return erfc((double)__x);}
+
+// exp2
+
+using ::exp2;
+using ::exp2f;
+
+inline _LIBCPP_INLINE_VISIBILITY float       exp2(float __x) _NOEXCEPT       {return exp2f(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double exp2(long double __x) _NOEXCEPT {return exp2l(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+exp2(_A1 __x) _NOEXCEPT {return exp2((double)__x);}
+
+// expm1
+
+using ::expm1;
+using ::expm1f;
+
+inline _LIBCPP_INLINE_VISIBILITY float       expm1(float __x) _NOEXCEPT       {return expm1f(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double expm1(long double __x) _NOEXCEPT {return expm1l(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+expm1(_A1 __x) _NOEXCEPT {return expm1((double)__x);}
+
+// fdim
+
+using ::fdim;
+using ::fdimf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       fdim(float __x, float __y) _NOEXCEPT             {return fdimf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __x, long double __y) _NOEXCEPT {return fdiml(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+fdim(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return fdim((__result_type)__x, (__result_type)__y);
+}
+
+// fma
+
+using ::fmaf;
+using ::fma;
+
+inline _LIBCPP_INLINE_VISIBILITY float       fma(float __x, float __y, float __z) _NOEXCEPT                   {return fmaf(__x, __y, __z);}
+inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __x, long double __y, long double __z) _NOEXCEPT {return fmal(__x, __y, __z);}
+
+template <class _A1, class _A2, class _A3>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value &&
+    is_arithmetic<_A3>::value,
+    typename __promote<_A1, _A2, _A3>::type
+>::type
+fma(_A1 __x, _A2 __y, _A3 __z) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2, _A3>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value &&
+                      is_same<_A3, __result_type>::value)), "");
+    return fma((__result_type)__x, (__result_type)__y, (__result_type)__z);
+}
+
+// fmax
+
+using ::fmax;
+using ::fmaxf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       fmax(float __x, float __y) _NOEXCEPT             {return fmaxf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __x, long double __y) _NOEXCEPT {return fmaxl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+fmax(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return fmax((__result_type)__x, (__result_type)__y);
+}
+
+// fmin
+
+using ::fmin;
+using ::fminf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       fmin(float __x, float __y) _NOEXCEPT             {return fminf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __x, long double __y) _NOEXCEPT {return fminl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+fmin(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return fmin((__result_type)__x, (__result_type)__y);
+}
+
+// hypot
+
+using ::hypot;
+using ::hypotf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       hypot(float __x, float __y) _NOEXCEPT             {return hypotf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __x, long double __y) _NOEXCEPT {return hypotl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+hypot(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return hypot((__result_type)__x, (__result_type)__y);
+}
+
+// ilogb
+
+using ::ilogb;
+using ::ilogbf;
+
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(float __x) _NOEXCEPT       {return ilogbf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY int ilogb(long double __x) _NOEXCEPT {return ilogbl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, int>::type
+ilogb(_A1 __x) _NOEXCEPT {return ilogb((double)__x);}
+
+// lgamma
+
+using ::lgamma;
+using ::lgammaf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       lgamma(float __x) _NOEXCEPT       {return lgammaf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double lgamma(long double __x) _NOEXCEPT {return lgammal(__x);}
+
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+lgamma(_A1 __x) _NOEXCEPT {return lgamma((double)__x);}
+
+
+// llrint
+
+using ::llrint;
+using ::llrintf;
+
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(float __x) _NOEXCEPT       {return llrintf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llrint(long double __x) _NOEXCEPT {return llrintl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, long long>::type
+llrint(_A1 __x) _NOEXCEPT {return llrint((double)__x);}
+
+// llround
+
+using ::llround;
+using ::llroundf;
+
+inline _LIBCPP_INLINE_VISIBILITY long long llround(float __x) _NOEXCEPT       {return llroundf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long long llround(long double __x) _NOEXCEPT {return llroundl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, long long>::type
+llround(_A1 __x) _NOEXCEPT {return llround((double)__x);}
+
+// log1p
+
+using ::log1p;
+using ::log1pf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       log1p(float __x) _NOEXCEPT       {return log1pf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log1p(long double __x) _NOEXCEPT {return log1pl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+log1p(_A1 __x) _NOEXCEPT {return log1p((double)__x);}
+
+// log2
+
+using ::log2;
+using ::log2f;
+
+inline _LIBCPP_INLINE_VISIBILITY float       log2(float __x) _NOEXCEPT       {return log2f(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return log2l(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+log2(_A1 __x) _NOEXCEPT {return log2((double)__x);}
+
+// logb
+
+using ::logb;
+using ::logbf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       logb(float __x) _NOEXCEPT       {return logbf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return logbl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+logb(_A1 __x) _NOEXCEPT {return logb((double)__x);}
+
+// lrint
+
+using ::lrint;
+using ::lrintf;
+
+inline _LIBCPP_INLINE_VISIBILITY long lrint(float __x) _NOEXCEPT       {return lrintf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long lrint(long double __x) _NOEXCEPT {return lrintl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, long>::type
+lrint(_A1 __x) _NOEXCEPT {return lrint((double)__x);}
+
+// lround
+
+using ::lround;
+using ::lroundf;
+
+inline _LIBCPP_INLINE_VISIBILITY long lround(float __x) _NOEXCEPT       {return lroundf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long lround(long double __x) _NOEXCEPT {return lroundl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, long>::type
+lround(_A1 __x) _NOEXCEPT {return lround((double)__x);}
+
+#endif // _LIBCPP_MSVCRT
+#endif // __sun__
+
+// nan
+
+#ifndef _LIBCPP_MSVCRT
+using ::nan;
+using ::nanf;
+#endif // _LIBCPP_MSVCRT
+
+#ifndef __sun__
+#ifndef _LIBCPP_MSVCRT
+
+// nearbyint
+
+using ::nearbyint;
+using ::nearbyintf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       nearbyint(float __x) _NOEXCEPT       {return nearbyintf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double nearbyint(long double __x) _NOEXCEPT {return nearbyintl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+nearbyint(_A1 __x) _NOEXCEPT {return nearbyint((double)__x);}
+
+// nextafter
+
+using ::nextafter;
+using ::nextafterf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       nextafter(float __x, float __y) _NOEXCEPT             {return nextafterf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __x, long double __y) _NOEXCEPT {return nextafterl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+nextafter(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return nextafter((__result_type)__x, (__result_type)__y);
+}
+
+// nexttoward
+
+using ::nexttoward;
+using ::nexttowardf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       nexttoward(float __x, long double __y) _NOEXCEPT       {return nexttowardf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __x, long double __y) _NOEXCEPT {return nexttowardl(__x, __y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+nexttoward(_A1 __x, long double __y) _NOEXCEPT {return nexttoward((double)__x, __y);}
+
+// remainder
+
+using ::remainder;
+using ::remainderf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       remainder(float __x, float __y) _NOEXCEPT             {return remainderf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __x, long double __y) _NOEXCEPT {return remainderl(__x, __y);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+remainder(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return remainder((__result_type)__x, (__result_type)__y);
+}
+
+// remquo
+
+using ::remquo;
+using ::remquof;
+
+inline _LIBCPP_INLINE_VISIBILITY float       remquo(float __x, float __y, int* __z) _NOEXCEPT             {return remquof(__x, __y, __z);}
+inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __x, long double __y, int* __z) _NOEXCEPT {return remquol(__x, __y, __z);}
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_A1>::value &&
+    is_arithmetic<_A2>::value,
+    typename __promote<_A1, _A2>::type
+>::type
+remquo(_A1 __x, _A2 __y, int* __z) _NOEXCEPT
+{
+    typedef typename __promote<_A1, _A2>::type __result_type;
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                      is_same<_A2, __result_type>::value)), "");
+    return remquo((__result_type)__x, (__result_type)__y, __z);
+}
+
+// rint
+
+using ::rint;
+using ::rintf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       rint(float __x) _NOEXCEPT       {return rintf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double rint(long double __x) _NOEXCEPT {return rintl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+rint(_A1 __x) _NOEXCEPT {return rint((double)__x);}
+
+// round
+
+using ::round;
+using ::roundf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       round(float __x) _NOEXCEPT       {return roundf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double round(long double __x) _NOEXCEPT {return roundl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+round(_A1 __x) _NOEXCEPT {return round((double)__x);}
+
+// scalbln
+
+using ::scalbln;
+using ::scalblnf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       scalbln(float __x, long __y) _NOEXCEPT       {return scalblnf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbln(long double __x, long __y) _NOEXCEPT {return scalblnl(__x, __y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+scalbln(_A1 __x, long __y) _NOEXCEPT {return scalbln((double)__x, __y);}
+
+// scalbn
+
+using ::scalbn;
+using ::scalbnf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       scalbn(float __x, int __y) _NOEXCEPT       {return scalbnf(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double scalbn(long double __x, int __y) _NOEXCEPT {return scalbnl(__x, __y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+scalbn(_A1 __x, int __y) _NOEXCEPT {return scalbn((double)__x, __y);}
+
+// tgamma
+
+using ::tgamma;
+using ::tgammaf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       tgamma(float __x) _NOEXCEPT       {return tgammaf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double tgamma(long double __x) _NOEXCEPT {return tgammal(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+tgamma(_A1 __x) _NOEXCEPT {return tgamma((double)__x);}
+
+// trunc
+
+using ::trunc;
+using ::truncf;
+
+inline _LIBCPP_INLINE_VISIBILITY float       trunc(float __x) _NOEXCEPT       {return truncf(__x);}
+inline _LIBCPP_INLINE_VISIBILITY long double trunc(long double __x) _NOEXCEPT {return truncl(__x);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+trunc(_A1 __x) _NOEXCEPT {return trunc((double)__x);}
+
+#endif // !_LIBCPP_MSVCRT
+
+using ::acosl;
+using ::asinl;
+using ::atanl;
+using ::atan2l;
+using ::ceill;
+using ::cosl;
+using ::coshl;
+using ::expl;
+using ::fabsl;
+using ::floorl;
+using ::fmodl;
+using ::frexpl;
+using ::ldexpl;
+using ::logl;
+using ::log10l;
+using ::modfl;
+using ::powl;
+using ::sinl;
+using ::sinhl;
+using ::sqrtl;
+using ::tanl;
+#ifndef _LIBCPP_MSVCRT
+using ::tanhl;
+using ::acoshl;
+using ::asinhl;
+using ::atanhl;
+using ::cbrtl;
+#endif  // !_LIBCPP_MSVCRT
+using ::copysignl;
+#ifndef _LIBCPP_MSVCRT
+using ::erfl;
+using ::erfcl;
+using ::exp2l;
+using ::expm1l;
+using ::fdiml;
+using ::fmal;
+using ::fmaxl;
+using ::fminl;
+using ::hypotl;
+using ::ilogbl;
+using ::lgammal;
+using ::llrintl;
+using ::llroundl;
+using ::log1pl;
+using ::log2l;
+using ::logbl;
+using ::lrintl;
+using ::lroundl;
+using ::nanl;
+using ::nearbyintl;
+using ::nextafterl;
+using ::nexttowardl;
+using ::remainderl;
+using ::remquol;
+using ::rintl;
+using ::roundl;
+using ::scalblnl;
+using ::scalbnl;
+using ::tgammal;
+using ::truncl;
+#endif // !_LIBCPP_MSVCRT
+
+#else 
+using ::lgamma;
+using ::lgammaf;
+#endif // __sun__
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CMATH
diff --git a/include/c++/v1/codecvt b/include/c++/v1/codecvt
new file mode 100644
index 0000000..6eff107
--- /dev/null
+++ b/include/c++/v1/codecvt
@@ -0,0 +1,550 @@
+// -*- C++ -*-
+//===-------------------------- codecvt -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CODECVT
+#define _LIBCPP_CODECVT
+
+/*
+    codecvt synopsis
+
+namespace std
+{
+
+enum codecvt_mode
+{
+    consume_header = 4,
+    generate_header = 2,
+    little_endian = 1
+};
+
+template <class Elem, unsigned long Maxcode = 0x10ffff,
+          codecvt_mode Mode = (codecvt_mode)0>
+class codecvt_utf8
+    : public codecvt<Elem, char, mbstate_t>
+{
+    explicit codecvt_utf8(size_t refs = 0);
+    ~codecvt_utf8();
+};
+
+template <class Elem, unsigned long Maxcode = 0x10ffff,
+          codecvt_mode Mode = (codecvt_mode)0>
+class codecvt_utf16
+    : public codecvt<Elem, char, mbstate_t>
+{
+    explicit codecvt_utf16(size_t refs = 0);
+    ~codecvt_utf16();
+};
+
+template <class Elem, unsigned long Maxcode = 0x10ffff,
+          codecvt_mode Mode = (codecvt_mode)0>
+class codecvt_utf8_utf16
+    : public codecvt<Elem, char, mbstate_t>
+{
+    explicit codecvt_utf8_utf16(size_t refs = 0);
+    ~codecvt_utf8_utf16();
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__locale>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum codecvt_mode
+{
+    consume_header = 4,
+    generate_header = 2,
+    little_endian = 1
+};
+
+// codecvt_utf8
+
+template <class _Elem> class __codecvt_utf8;
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t>
+    : public codecvt<wchar_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef wchar_t   intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char16_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char32_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <class _Elem, unsigned long _Maxcode = 0x10ffff,
+          codecvt_mode _Mode = (codecvt_mode)0>
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8
+    : public __codecvt_utf8<_Elem>
+{
+public:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt_utf8(size_t __refs = 0)
+        : __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    ~codecvt_utf8() {}
+};
+
+// codecvt_utf16
+
+template <class _Elem, bool _LittleEndian> class __codecvt_utf16;
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false>
+    : public codecvt<wchar_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef wchar_t   intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true>
+    : public codecvt<wchar_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef wchar_t   intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char16_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char16_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char32_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char32_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <class _Elem, unsigned long _Maxcode = 0x10ffff,
+          codecvt_mode _Mode = (codecvt_mode)0>
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf16
+    : public __codecvt_utf16<_Elem, _Mode & little_endian>
+{
+public:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt_utf16(size_t __refs = 0)
+        : __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    ~codecvt_utf16() {}
+};
+
+// codecvt_utf8_utf16
+
+template <class _Elem> class __codecvt_utf8_utf16;
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t>
+    : public codecvt<wchar_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef wchar_t   intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t>
+    : public codecvt<char32_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char32_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <>
+class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t>
+    : public codecvt<char16_t, char, mbstate_t>
+{
+    unsigned long _Maxcode_;
+    codecvt_mode _Mode_;
+public:
+    typedef char16_t  intern_type;
+    typedef char      extern_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode,
+                            codecvt_mode _Mode)
+        : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode),
+          _Mode_(_Mode) {}
+protected:
+    virtual result
+        do_out(state_type& __st,
+               const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
+               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual result
+        do_in(state_type& __st,
+              const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
+              intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
+    virtual result
+        do_unshift(state_type& __st,
+                   extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
+    virtual int do_encoding() const throw();
+    virtual bool do_always_noconv() const throw();
+    virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
+                          size_t __mx) const;
+    virtual int do_max_length() const throw();
+};
+
+template <class _Elem, unsigned long _Maxcode = 0x10ffff,
+          codecvt_mode _Mode = (codecvt_mode)0>
+class _LIBCPP_TYPE_VIS_ONLY codecvt_utf8_utf16
+    : public __codecvt_utf8_utf16<_Elem>
+{
+public:
+    _LIBCPP_ALWAYS_INLINE
+    explicit codecvt_utf8_utf16(size_t __refs = 0)
+        : __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    ~codecvt_utf8_utf16() {}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CODECVT
diff --git a/include/c++/v1/complex b/include/c++/v1/complex
new file mode 100644
index 0000000..2943da1
--- /dev/null
+++ b/include/c++/v1/complex
@@ -0,0 +1,1567 @@
+// -*- C++ -*-
+//===--------------------------- complex ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_COMPLEX
+#define _LIBCPP_COMPLEX
+
+/*
+    complex synopsis
+
+namespace std
+{
+
+template<class T>
+class complex
+{
+public:
+    typedef T value_type;
+
+    complex(const T& re = T(), const T& im = T()); // constexpr in C++14
+    complex(const complex&);  // constexpr in C++14
+    template<class X> complex(const complex<X>&);  // constexpr in C++14
+
+    T real() const; // constexpr in C++14
+    T imag() const; // constexpr in C++14
+
+    void real(T);
+    void imag(T);
+
+    complex<T>& operator= (const T&);
+    complex<T>& operator+=(const T&);
+    complex<T>& operator-=(const T&);
+    complex<T>& operator*=(const T&);
+    complex<T>& operator/=(const T&);
+
+    complex& operator=(const complex&);
+    template<class X> complex<T>& operator= (const complex<X>&);
+    template<class X> complex<T>& operator+=(const complex<X>&);
+    template<class X> complex<T>& operator-=(const complex<X>&);
+    template<class X> complex<T>& operator*=(const complex<X>&);
+    template<class X> complex<T>& operator/=(const complex<X>&);
+};
+
+template<>
+class complex<float>
+{
+public:
+    typedef float value_type;
+
+    constexpr complex(float re = 0.0f, float im = 0.0f);
+    explicit constexpr complex(const complex<double>&);
+    explicit constexpr complex(const complex<long double>&);
+
+    constexpr float real() const;
+    void real(float);
+    constexpr float imag() const;
+    void imag(float);
+
+    complex<float>& operator= (float);
+    complex<float>& operator+=(float);
+    complex<float>& operator-=(float);
+    complex<float>& operator*=(float);
+    complex<float>& operator/=(float);
+
+    complex<float>& operator=(const complex<float>&);
+    template<class X> complex<float>& operator= (const complex<X>&);
+    template<class X> complex<float>& operator+=(const complex<X>&);
+    template<class X> complex<float>& operator-=(const complex<X>&);
+    template<class X> complex<float>& operator*=(const complex<X>&);
+    template<class X> complex<float>& operator/=(const complex<X>&);
+};
+
+template<>
+class complex<double>
+{
+public:
+    typedef double value_type;
+
+    constexpr complex(double re = 0.0, double im = 0.0);
+    constexpr complex(const complex<float>&);
+    explicit constexpr complex(const complex<long double>&);
+
+    constexpr double real() const;
+    void real(double);
+    constexpr double imag() const;
+    void imag(double);
+
+    complex<double>& operator= (double);
+    complex<double>& operator+=(double);
+    complex<double>& operator-=(double);
+    complex<double>& operator*=(double);
+    complex<double>& operator/=(double);
+    complex<double>& operator=(const complex<double>&);
+
+    template<class X> complex<double>& operator= (const complex<X>&);
+    template<class X> complex<double>& operator+=(const complex<X>&);
+    template<class X> complex<double>& operator-=(const complex<X>&);
+    template<class X> complex<double>& operator*=(const complex<X>&);
+    template<class X> complex<double>& operator/=(const complex<X>&);
+};
+
+template<>
+class complex<long double>
+{
+public:
+    typedef long double value_type;
+
+    constexpr complex(long double re = 0.0L, long double im = 0.0L);
+    constexpr complex(const complex<float>&);
+    constexpr complex(const complex<double>&);
+
+    constexpr long double real() const;
+    void real(long double);
+    constexpr long double imag() const;
+    void imag(long double);
+
+    complex<long double>& operator=(const complex<long double>&);
+    complex<long double>& operator= (long double);
+    complex<long double>& operator+=(long double);
+    complex<long double>& operator-=(long double);
+    complex<long double>& operator*=(long double);
+    complex<long double>& operator/=(long double);
+
+    template<class X> complex<long double>& operator= (const complex<X>&);
+    template<class X> complex<long double>& operator+=(const complex<X>&);
+    template<class X> complex<long double>& operator-=(const complex<X>&);
+    template<class X> complex<long double>& operator*=(const complex<X>&);
+    template<class X> complex<long double>& operator/=(const complex<X>&);
+};
+
+// 26.3.6 operators:
+template<class T> complex<T> operator+(const complex<T>&, const complex<T>&);
+template<class T> complex<T> operator+(const complex<T>&, const T&);
+template<class T> complex<T> operator+(const T&, const complex<T>&);
+template<class T> complex<T> operator-(const complex<T>&, const complex<T>&);
+template<class T> complex<T> operator-(const complex<T>&, const T&);
+template<class T> complex<T> operator-(const T&, const complex<T>&);
+template<class T> complex<T> operator*(const complex<T>&, const complex<T>&);
+template<class T> complex<T> operator*(const complex<T>&, const T&);
+template<class T> complex<T> operator*(const T&, const complex<T>&);
+template<class T> complex<T> operator/(const complex<T>&, const complex<T>&);
+template<class T> complex<T> operator/(const complex<T>&, const T&);
+template<class T> complex<T> operator/(const T&, const complex<T>&);
+template<class T> complex<T> operator+(const complex<T>&);
+template<class T> complex<T> operator-(const complex<T>&);
+template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14
+template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14
+template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14
+
+template<class T, class charT, class traits>
+  basic_istream<charT, traits>&
+  operator>>(basic_istream<charT, traits>&, complex<T>&);
+template<class T, class charT, class traits>
+  basic_ostream<charT, traits>&
+  operator<<(basic_ostream<charT, traits>&, const complex<T>&);
+
+// 26.3.7 values:
+
+template<class T>              T real(const complex<T>&); // constexpr in C++14
+                     long double real(long double);       // constexpr in C++14
+                          double real(double);            // constexpr in C++14
+template<Integral T>      double real(T);                 // constexpr in C++14
+                          float  real(float);             // constexpr in C++14
+
+template<class T>              T imag(const complex<T>&); // constexpr in C++14
+                     long double imag(long double);       // constexpr in C++14
+                          double imag(double);            // constexpr in C++14
+template<Integral T>      double imag(T);                 // constexpr in C++14
+                          float  imag(float);             // constexpr in C++14
+
+template<class T> T abs(const complex<T>&);
+
+template<class T>              T arg(const complex<T>&);
+                     long double arg(long double);
+                          double arg(double);
+template<Integral T>      double arg(T);
+                          float  arg(float);
+
+template<class T>              T norm(const complex<T>&);
+                     long double norm(long double);
+                          double norm(double);
+template<Integral T>      double norm(T);
+                          float  norm(float);
+
+template<class T>      complex<T>           conj(const complex<T>&);
+                       complex<long double> conj(long double);
+                       complex<double>      conj(double);
+template<Integral T>   complex<double>      conj(T);
+                       complex<float>       conj(float);
+
+template<class T>    complex<T>           proj(const complex<T>&);
+                     complex<long double> proj(long double);
+                     complex<double>      proj(double);
+template<Integral T> complex<double>      proj(T);
+                     complex<float>       proj(float);
+
+template<class T> complex<T> polar(const T&, const T& = 0);
+
+// 26.3.8 transcendentals:
+template<class T> complex<T> acos(const complex<T>&);
+template<class T> complex<T> asin(const complex<T>&);
+template<class T> complex<T> atan(const complex<T>&);
+template<class T> complex<T> acosh(const complex<T>&);
+template<class T> complex<T> asinh(const complex<T>&);
+template<class T> complex<T> atanh(const complex<T>&);
+template<class T> complex<T> cos (const complex<T>&);
+template<class T> complex<T> cosh (const complex<T>&);
+template<class T> complex<T> exp (const complex<T>&);
+template<class T> complex<T> log (const complex<T>&);
+template<class T> complex<T> log10(const complex<T>&);
+
+template<class T> complex<T> pow(const complex<T>&, const T&);
+template<class T> complex<T> pow(const complex<T>&, const complex<T>&);
+template<class T> complex<T> pow(const T&, const complex<T>&);
+
+template<class T> complex<T> sin (const complex<T>&);
+template<class T> complex<T> sinh (const complex<T>&);
+template<class T> complex<T> sqrt (const complex<T>&);
+template<class T> complex<T> tan (const complex<T>&);
+template<class T> complex<T> tanh (const complex<T>&);
+
+template<class T, class charT, class traits>
+  basic_istream<charT, traits>&
+  operator>>(basic_istream<charT, traits>& is, complex<T>& x);
+
+template<class T, class charT, class traits>
+  basic_ostream<charT, traits>&
+  operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <type_traits>
+#include <stdexcept>
+#include <cmath>
+#include <sstream>
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY complex;
+
+template<class _Tp> complex<_Tp> operator*(const complex<_Tp>& __z, const complex<_Tp>& __w);
+template<class _Tp> complex<_Tp> operator/(const complex<_Tp>& __x, const complex<_Tp>& __y);
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY complex
+{
+public:
+    typedef _Tp value_type;
+private:
+    value_type __re_;
+    value_type __im_;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    complex(const value_type& __re = value_type(), const value_type& __im = value_type())
+        : __re_(__re), __im_(__im) {}
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    complex(const complex<_Xp>& __c)
+        : __re_(__c.real()), __im_(__c.imag()) {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type real() const {return __re_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 value_type imag() const {return __im_;}
+
+    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
+    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+
+    _LIBCPP_INLINE_VISIBILITY complex& operator= (const value_type& __re)
+        {__re_ = __re; __im_ = value_type(); return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator+=(const value_type& __re) {__re_ += __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator-=(const value_type& __re) {__re_ -= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator*=(const value_type& __re) {__re_ *= __re; __im_ *= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator/=(const value_type& __re) {__re_ /= __re; __im_ /= __re; return *this;}
+
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+        {
+            __re_ = __c.real();
+            __im_ = __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+        {
+            __re_ += __c.real();
+            __im_ += __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+        {
+            __re_ -= __c.real();
+            __im_ -= __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+        {
+            *this = *this * complex(__c.real(), __c.imag());
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+        {
+            *this = *this / complex(__c.real(), __c.imag());
+            return *this;
+        }
+};
+
+template<> class _LIBCPP_TYPE_VIS_ONLY complex<double>;
+template<> class _LIBCPP_TYPE_VIS_ONLY complex<long double>;
+
+template<>
+class _LIBCPP_TYPE_VIS_ONLY complex<float>
+{
+    float __re_;
+    float __im_;
+public:
+    typedef float value_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f)
+        : __re_(__re), __im_(__im) {}
+    explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
+    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float imag() const {return __im_;}
+
+    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
+    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+
+    _LIBCPP_INLINE_VISIBILITY complex& operator= (float __re)
+        {__re_ = __re; __im_ = value_type(); return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator+=(float __re) {__re_ += __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator-=(float __re) {__re_ -= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator*=(float __re) {__re_ *= __re; __im_ *= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator/=(float __re) {__re_ /= __re; __im_ /= __re; return *this;}
+
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+        {
+            __re_ = __c.real();
+            __im_ = __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+        {
+            __re_ += __c.real();
+            __im_ += __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+        {
+            __re_ -= __c.real();
+            __im_ -= __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+        {
+            *this = *this * complex(__c.real(), __c.imag());
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+        {
+            *this = *this / complex(__c.real(), __c.imag());
+            return *this;
+        }
+};
+
+template<>
+class _LIBCPP_TYPE_VIS_ONLY complex<double>
+{
+    double __re_;
+    double __im_;
+public:
+    typedef double value_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0)
+        : __re_(__re), __im_(__im) {}
+    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
+    explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c);
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double imag() const {return __im_;}
+
+    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
+    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+
+    _LIBCPP_INLINE_VISIBILITY complex& operator= (double __re)
+        {__re_ = __re; __im_ = value_type(); return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator+=(double __re) {__re_ += __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator-=(double __re) {__re_ -= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator*=(double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator/=(double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+        {
+            __re_ = __c.real();
+            __im_ = __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+        {
+            __re_ += __c.real();
+            __im_ += __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+        {
+            __re_ -= __c.real();
+            __im_ -= __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+        {
+            *this = *this * complex(__c.real(), __c.imag());
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+        {
+            *this = *this / complex(__c.real(), __c.imag());
+            return *this;
+        }
+};
+
+template<>
+class _LIBCPP_TYPE_VIS_ONLY complex<long double>
+{
+    long double __re_;
+    long double __im_;
+public:
+    typedef long double value_type;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L)
+        : __re_(__re), __im_(__im) {}
+    _LIBCPP_CONSTEXPR complex(const complex<float>& __c);
+    _LIBCPP_CONSTEXPR complex(const complex<double>& __c);
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double imag() const {return __im_;}
+
+    _LIBCPP_INLINE_VISIBILITY void real(value_type __re) {__re_ = __re;}
+    _LIBCPP_INLINE_VISIBILITY void imag(value_type __im) {__im_ = __im;}
+
+    _LIBCPP_INLINE_VISIBILITY complex& operator= (long double __re)
+        {__re_ = __re; __im_ = value_type(); return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator+=(long double __re) {__re_ += __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator-=(long double __re) {__re_ -= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator*=(long double __re) {__re_ *= __re; __im_ *= __re; return *this;}
+    _LIBCPP_INLINE_VISIBILITY complex& operator/=(long double __re) {__re_ /= __re; __im_ /= __re; return *this;}
+
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator= (const complex<_Xp>& __c)
+        {
+            __re_ = __c.real();
+            __im_ = __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator+=(const complex<_Xp>& __c)
+        {
+            __re_ += __c.real();
+            __im_ += __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator-=(const complex<_Xp>& __c)
+        {
+            __re_ -= __c.real();
+            __im_ -= __c.imag();
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator*=(const complex<_Xp>& __c)
+        {
+            *this = *this * complex(__c.real(), __c.imag());
+            return *this;
+        }
+    template<class _Xp> _LIBCPP_INLINE_VISIBILITY complex& operator/=(const complex<_Xp>& __c)
+        {
+            *this = *this / complex(__c.real(), __c.imag());
+            return *this;
+        }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<float>::complex(const complex<double>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<float>::complex(const complex<long double>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<double>::complex(const complex<float>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<double>::complex(const complex<long double>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<long double>::complex(const complex<float>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+complex<long double>::complex(const complex<double>& __c)
+    : __re_(__c.real()), __im_(__c.imag()) {}
+
+// 26.3.6 operators:
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator+(const complex<_Tp>& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(__x);
+    __t += __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator+(const complex<_Tp>& __x, const _Tp& __y)
+{
+    complex<_Tp> __t(__x);
+    __t += __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator+(const _Tp& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(__y);
+    __t += __x;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator-(const complex<_Tp>& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(__x);
+    __t -= __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator-(const complex<_Tp>& __x, const _Tp& __y)
+{
+    complex<_Tp> __t(__x);
+    __t -= __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator-(const _Tp& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(-__y);
+    __t += __x;
+    return __t;
+}
+
+template<class _Tp>
+complex<_Tp>
+operator*(const complex<_Tp>& __z, const complex<_Tp>& __w)
+{
+    _Tp __a = __z.real();
+    _Tp __b = __z.imag();
+    _Tp __c = __w.real();
+    _Tp __d = __w.imag();
+    _Tp __ac = __a * __c;
+    _Tp __bd = __b * __d;
+    _Tp __ad = __a * __d;
+    _Tp __bc = __b * __c;
+    _Tp __x = __ac - __bd;
+    _Tp __y = __ad + __bc;
+    if (isnan(__x) && isnan(__y))
+    {
+        bool __recalc = false;
+        if (isinf(__a) || isinf(__b))
+        {
+            __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);
+            __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);
+            if (isnan(__c))
+                __c = copysign(_Tp(0), __c);
+            if (isnan(__d))
+                __d = copysign(_Tp(0), __d);
+            __recalc = true;
+        }
+        if (isinf(__c) || isinf(__d))
+        {
+            __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);
+            __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);
+            if (isnan(__a))
+                __a = copysign(_Tp(0), __a);
+            if (isnan(__b))
+                __b = copysign(_Tp(0), __b);
+            __recalc = true;
+        }
+        if (!__recalc && (isinf(__ac) || isinf(__bd) ||
+                          isinf(__ad) || isinf(__bc)))
+        {
+            if (isnan(__a))
+                __a = copysign(_Tp(0), __a);
+            if (isnan(__b))
+                __b = copysign(_Tp(0), __b);
+            if (isnan(__c))
+                __c = copysign(_Tp(0), __c);
+            if (isnan(__d))
+                __d = copysign(_Tp(0), __d);
+            __recalc = true;
+        }
+        if (__recalc)
+        {
+            __x = _Tp(INFINITY) * (__a * __c - __b * __d);
+            __y = _Tp(INFINITY) * (__a * __d + __b * __c);
+        }
+    }
+    return complex<_Tp>(__x, __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator*(const complex<_Tp>& __x, const _Tp& __y)
+{
+    complex<_Tp> __t(__x);
+    __t *= __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator*(const _Tp& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(__y);
+    __t *= __x;
+    return __t;
+}
+
+template<class _Tp>
+complex<_Tp>
+operator/(const complex<_Tp>& __z, const complex<_Tp>& __w)
+{
+    int __ilogbw = 0;
+    _Tp __a = __z.real();
+    _Tp __b = __z.imag();
+    _Tp __c = __w.real();
+    _Tp __d = __w.imag();
+    _Tp __logbw = logb(fmax(fabs(__c), fabs(__d)));
+    if (isfinite(__logbw))
+    {
+        __ilogbw = static_cast<int>(__logbw);
+        __c = scalbn(__c, -__ilogbw);
+        __d = scalbn(__d, -__ilogbw);
+    }
+    _Tp __denom = __c * __c + __d * __d;
+    _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw);
+    _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw);
+    if (isnan(__x) && isnan(__y))
+    {
+        if ((__denom == _Tp(0)) && (!isnan(__a) || !isnan(__b)))
+        {
+            __x = copysign(_Tp(INFINITY), __c) * __a;
+            __y = copysign(_Tp(INFINITY), __c) * __b;
+        }
+        else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d))
+        {
+            __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a);
+            __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b);
+            __x = _Tp(INFINITY) * (__a * __c + __b * __d);
+            __y = _Tp(INFINITY) * (__b * __c - __a * __d);
+        }
+        else if (isinf(__logbw) && __logbw > _Tp(0) && isfinite(__a) && isfinite(__b))
+        {
+            __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c);
+            __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d);
+            __x = _Tp(0) * (__a * __c + __b * __d);
+            __y = _Tp(0) * (__b * __c - __a * __d);
+        }
+    }
+    return complex<_Tp>(__x, __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator/(const complex<_Tp>& __x, const _Tp& __y)
+{
+    return complex<_Tp>(__x.real() / __y, __x.imag() / __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator/(const _Tp& __x, const complex<_Tp>& __y)
+{
+    complex<_Tp> __t(__x);
+    __t /= __y;
+    return __t;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator+(const complex<_Tp>& __x)
+{
+    return __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+operator-(const complex<_Tp>& __x)
+{
+    return complex<_Tp>(-__x.real(), -__x.imag());
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const complex<_Tp>& __x, const complex<_Tp>& __y)
+{
+    return __x.real() == __y.real() && __x.imag() == __y.imag();
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const complex<_Tp>& __x, const _Tp& __y)
+{
+    return __x.real() == __y && __x.imag() == 0;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const _Tp& __x, const complex<_Tp>& __y)
+{
+    return __x == __y.real() && 0 == __y.imag();
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y)
+{
+    return !(__x == __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const complex<_Tp>& __x, const _Tp& __y)
+{
+    return !(__x == __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const _Tp& __x, const complex<_Tp>& __y)
+{
+    return !(__x == __y);
+}
+
+// 26.3.7 values:
+
+// real
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+real(const complex<_Tp>& __c)
+{
+    return __c.real();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+long double
+real(long double __re)
+{
+    return __re;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+double
+real(double __re)
+{
+    return __re;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    double
+>::type
+real(_Tp  __re)
+{
+    return __re;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+float
+real(float  __re)
+{
+    return __re;
+}
+
+// imag
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp
+imag(const complex<_Tp>& __c)
+{
+    return __c.imag();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+long double
+imag(long double __re)
+{
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+double
+imag(double __re)
+{
+    return 0;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    double
+>::type
+imag(_Tp  __re)
+{
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+float
+imag(float  __re)
+{
+    return 0;
+}
+
+// abs
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+abs(const complex<_Tp>& __c)
+{
+    return hypot(__c.real(), __c.imag());
+}
+
+// arg
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+arg(const complex<_Tp>& __c)
+{
+    return atan2(__c.imag(), __c.real());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+long double
+arg(long double __re)
+{
+    return atan2l(0.L, __re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+double
+arg(double __re)
+{
+    return atan2(0., __re);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    double
+>::type
+arg(_Tp __re)
+{
+    return atan2(0., __re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+float
+arg(float __re)
+{
+    return atan2f(0.F, __re);
+}
+
+// norm
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+norm(const complex<_Tp>& __c)
+{
+    if (isinf(__c.real()))
+        return abs(__c.real());
+    if (isinf(__c.imag()))
+        return abs(__c.imag());
+    return __c.real() * __c.real() + __c.imag() * __c.imag();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+long double
+norm(long double __re)
+{
+    return __re * __re;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+double
+norm(double __re)
+{
+    return __re * __re;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    double
+>::type
+norm(_Tp __re)
+{
+    return (double)__re * __re;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+float
+norm(float __re)
+{
+    return __re * __re;
+}
+
+// conj
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+conj(const complex<_Tp>& __c)
+{
+    return complex<_Tp>(__c.real(), -__c.imag());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<long double>
+conj(long double __re)
+{
+    return complex<long double>(__re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<double>
+conj(double __re)
+{
+    return complex<double>(__re);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    complex<double>
+>::type
+conj(_Tp __re)
+{
+    return complex<double>(__re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<float>
+conj(float __re)
+{
+    return complex<float>(__re);
+}
+
+// proj
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+proj(const complex<_Tp>& __c)
+{
+    std::complex<_Tp> __r = __c;
+    if (isinf(__c.real()) || isinf(__c.imag()))
+        __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag()));
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<long double>
+proj(long double __re)
+{
+    if (isinf(__re))
+        __re = abs(__re);
+    return complex<long double>(__re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<double>
+proj(double __re)
+{
+    if (isinf(__re))
+        __re = abs(__re);
+    return complex<double>(__re);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_integral<_Tp>::value,
+    complex<double>
+>::type
+proj(_Tp __re)
+{
+    return complex<double>(__re);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+complex<float>
+proj(float __re)
+{
+    if (isinf(__re))
+        __re = abs(__re);
+    return complex<float>(__re);
+}
+
+// polar
+
+template<class _Tp>
+complex<_Tp>
+polar(const _Tp& __rho, const _Tp& __theta = _Tp(0))
+{
+    if (isnan(__rho) || signbit(__rho))
+        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
+    if (isnan(__theta))
+    {
+        if (isinf(__rho))
+            return complex<_Tp>(__rho, __theta);
+        return complex<_Tp>(__theta, __theta);
+    }
+    if (isinf(__theta))
+    {
+        if (isinf(__rho))
+            return complex<_Tp>(__rho, _Tp(NAN));
+        return complex<_Tp>(_Tp(NAN), _Tp(NAN));
+    }
+    _Tp __x = __rho * cos(__theta);
+    if (isnan(__x))
+        __x = 0;
+    _Tp __y = __rho * sin(__theta);
+    if (isnan(__y))
+        __y = 0;
+    return complex<_Tp>(__x, __y);
+}
+
+// log
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+log(const complex<_Tp>& __x)
+{
+    return complex<_Tp>(log(abs(__x)), arg(__x));
+}
+
+// log10
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+log10(const complex<_Tp>& __x)
+{
+    return log(__x) / log(_Tp(10));
+}
+
+// sqrt
+
+template<class _Tp>
+complex<_Tp>
+sqrt(const complex<_Tp>& __x)
+{
+    if (isinf(__x.imag()))
+        return complex<_Tp>(_Tp(INFINITY), __x.imag());
+    if (isinf(__x.real()))
+    {
+        if (__x.real() > _Tp(0))
+            return complex<_Tp>(__x.real(), isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag()));
+        return complex<_Tp>(isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag()));
+    }
+    return polar(sqrt(abs(__x)), arg(__x) / _Tp(2));
+}
+
+// exp
+
+template<class _Tp>
+complex<_Tp>
+exp(const complex<_Tp>& __x)
+{
+    _Tp __i = __x.imag();
+    if (isinf(__x.real()))
+    {
+        if (__x.real() < _Tp(0))
+        {
+            if (!isfinite(__i))
+                __i = _Tp(1);
+        }
+        else if (__i == 0 || !isfinite(__i))
+        {
+            if (isinf(__i))
+                __i = _Tp(NAN);
+            return complex<_Tp>(__x.real(), __i);
+        }
+    }
+    else if (isnan(__x.real()) && __x.imag() == 0)
+        return __x;
+    _Tp __e = exp(__x.real());
+    return complex<_Tp>(__e * cos(__i), __e * sin(__i));
+}
+
+// pow
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+pow(const complex<_Tp>& __x, const complex<_Tp>& __y)
+{
+    return exp(__y * log(__x));
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<typename __promote<_Tp, _Up>::type>
+pow(const complex<_Tp>& __x, const complex<_Up>& __y)
+{
+    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
+    return _VSTD::pow(result_type(__x), result_type(__y));
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_Up>::value,
+    complex<typename __promote<_Tp, _Up>::type>
+>::type
+pow(const complex<_Tp>& __x, const _Up& __y)
+{
+    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
+    return _VSTD::pow(result_type(__x), result_type(__y));
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_arithmetic<_Tp>::value,
+    complex<typename __promote<_Tp, _Up>::type>
+>::type
+pow(const _Tp& __x, const complex<_Up>& __y)
+{
+    typedef complex<typename __promote<_Tp, _Up>::type> result_type;
+    return _VSTD::pow(result_type(__x), result_type(__y));
+}
+
+// asinh
+
+template<class _Tp>
+complex<_Tp>
+asinh(const complex<_Tp>& __x)
+{
+    const _Tp __pi(atan2(+0., -0.));
+    if (isinf(__x.real()))
+    {
+        if (isnan(__x.imag()))
+            return __x;
+        if (isinf(__x.imag()))
+            return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
+        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
+    }
+    if (isnan(__x.real()))
+    {
+        if (isinf(__x.imag()))
+            return complex<_Tp>(__x.imag(), __x.real());
+        if (__x.imag() == 0)
+            return __x;
+        return complex<_Tp>(__x.real(), __x.real());
+    }
+    if (isinf(__x.imag()))
+        return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
+    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1)));
+    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
+}
+
+// acosh
+
+template<class _Tp>
+complex<_Tp>
+acosh(const complex<_Tp>& __x)
+{
+    const _Tp __pi(atan2(+0., -0.));
+    if (isinf(__x.real()))
+    {
+        if (isnan(__x.imag()))
+            return complex<_Tp>(abs(__x.real()), __x.imag());
+        if (isinf(__x.imag()))
+        {
+            if (__x.real() > 0)
+                return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag()));
+            else
+                return complex<_Tp>(-__x.real(), copysign(__pi * _Tp(0.75), __x.imag()));
+        }
+        if (__x.real() < 0)
+            return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag()));
+        return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag()));
+    }
+    if (isnan(__x.real()))
+    {
+        if (isinf(__x.imag()))
+            return complex<_Tp>(abs(__x.imag()), __x.real());
+        return complex<_Tp>(__x.real(), __x.real());
+    }
+    if (isinf(__x.imag()))
+        return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag()));
+    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));
+    return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag()));
+}
+
+// atanh
+
+template<class _Tp>
+complex<_Tp>
+atanh(const complex<_Tp>& __x)
+{
+    const _Tp __pi(atan2(+0., -0.));
+    if (isinf(__x.imag()))
+    {
+        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
+    }
+    if (isnan(__x.imag()))
+    {
+        if (isinf(__x.real()) || __x.real() == 0)
+            return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag());
+        return complex<_Tp>(__x.imag(), __x.imag());
+    }
+    if (isnan(__x.real()))
+    {
+        return complex<_Tp>(__x.real(), __x.real());
+    }
+    if (isinf(__x.real()))
+    {
+        return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag()));
+    }
+    if (abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0))
+    {
+        return complex<_Tp>(copysign(_Tp(INFINITY), __x.real()), copysign(_Tp(0), __x.imag()));
+    }
+    complex<_Tp> __z = log((_Tp(1) + __x) / (_Tp(1) - __x)) / _Tp(2);
+    return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag()));
+}
+
+// sinh
+
+template<class _Tp>
+complex<_Tp>
+sinh(const complex<_Tp>& __x)
+{
+    if (isinf(__x.real()) && !isfinite(__x.imag()))
+        return complex<_Tp>(__x.real(), _Tp(NAN));
+    if (__x.real() == 0 && !isfinite(__x.imag()))
+        return complex<_Tp>(__x.real(), _Tp(NAN));
+    if (__x.imag() == 0 && !isfinite(__x.real()))
+        return __x;
+    return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag()));
+}
+
+// cosh
+
+template<class _Tp>
+complex<_Tp>
+cosh(const complex<_Tp>& __x)
+{
+    if (isinf(__x.real()) && !isfinite(__x.imag()))
+        return complex<_Tp>(abs(__x.real()), _Tp(NAN));
+    if (__x.real() == 0 && !isfinite(__x.imag()))
+        return complex<_Tp>(_Tp(NAN), __x.real());
+    if (__x.real() == 0 && __x.imag() == 0)
+        return complex<_Tp>(_Tp(1), __x.imag());
+    if (__x.imag() == 0 && !isfinite(__x.real()))
+        return complex<_Tp>(abs(__x.real()), __x.imag());
+    return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag()));
+}
+
+// tanh
+
+template<class _Tp>
+complex<_Tp>
+tanh(const complex<_Tp>& __x)
+{
+    if (isinf(__x.real()))
+    {
+        if (!isfinite(__x.imag()))
+            return complex<_Tp>(_Tp(1), _Tp(0));
+        return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag())));
+    }
+    if (isnan(__x.real()) && __x.imag() == 0)
+        return __x;
+    _Tp __2r(_Tp(2) * __x.real());
+    _Tp __2i(_Tp(2) * __x.imag());
+    _Tp __d(cosh(__2r) + cos(__2i));
+    _Tp __2rsh(sinh(__2r));
+    if (isinf(__2rsh) && isinf(__d))
+        return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1),
+                            __2i > _Tp(0) ? _Tp(0) : _Tp(-0.));
+    return  complex<_Tp>(__2rsh/__d, sin(__2i)/__d);
+}
+
+// asin
+
+template<class _Tp>
+complex<_Tp>
+asin(const complex<_Tp>& __x)
+{
+    complex<_Tp> __z = asinh(complex<_Tp>(-__x.imag(), __x.real()));
+    return complex<_Tp>(__z.imag(), -__z.real());
+}
+
+// acos
+
+template<class _Tp>
+complex<_Tp>
+acos(const complex<_Tp>& __x)
+{
+    const _Tp __pi(atan2(+0., -0.));
+    if (isinf(__x.real()))
+    {
+        if (isnan(__x.imag()))
+            return complex<_Tp>(__x.imag(), __x.real());
+        if (isinf(__x.imag()))
+        {
+            if (__x.real() < _Tp(0))
+                return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag());
+            return complex<_Tp>(_Tp(0.25) * __pi, -__x.imag());
+        }
+        if (__x.real() < _Tp(0))
+            return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real());
+        return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real());
+    }
+    if (isnan(__x.real()))
+    {
+        if (isinf(__x.imag()))
+            return complex<_Tp>(__x.real(), -__x.imag());
+        return complex<_Tp>(__x.real(), __x.real());
+    }
+    if (isinf(__x.imag()))
+        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
+    if (__x.real() == 0)
+        return complex<_Tp>(__pi/_Tp(2), -__x.imag());
+    complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1)));
+    if (signbit(__x.imag()))
+        return complex<_Tp>(abs(__z.imag()), abs(__z.real()));
+    return complex<_Tp>(abs(__z.imag()), -abs(__z.real()));
+}
+
+// atan
+
+template<class _Tp>
+complex<_Tp>
+atan(const complex<_Tp>& __x)
+{
+    complex<_Tp> __z = atanh(complex<_Tp>(-__x.imag(), __x.real()));
+    return complex<_Tp>(__z.imag(), -__z.real());
+}
+
+// sin
+
+template<class _Tp>
+complex<_Tp>
+sin(const complex<_Tp>& __x)
+{
+    complex<_Tp> __z = sinh(complex<_Tp>(-__x.imag(), __x.real()));
+    return complex<_Tp>(__z.imag(), -__z.real());
+}
+
+// cos
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+complex<_Tp>
+cos(const complex<_Tp>& __x)
+{
+    return cosh(complex<_Tp>(-__x.imag(), __x.real()));
+}
+
+// tan
+
+template<class _Tp>
+complex<_Tp>
+tan(const complex<_Tp>& __x)
+{
+    complex<_Tp> __z = tanh(complex<_Tp>(-__x.imag(), __x.real()));
+    return complex<_Tp>(__z.imag(), -__z.real());
+}
+
+template<class _Tp, class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
+{
+    if (__is.good())
+    {
+        ws(__is);
+        if (__is.peek() == _CharT('('))
+        {
+            __is.get();
+            _Tp __r;
+            __is >> __r;
+            if (!__is.fail())
+            {
+                ws(__is);
+                _CharT __c = __is.peek();
+                if (__c == _CharT(','))
+                {
+                    __is.get();
+                    _Tp __i;
+                    __is >> __i;
+                    if (!__is.fail())
+                    {
+                        ws(__is);
+                        __c = __is.peek();
+                        if (__c == _CharT(')'))
+                        {
+                            __is.get();
+                            __x = complex<_Tp>(__r, __i);
+                        }
+                        else
+                            __is.setstate(ios_base::failbit);
+                    }
+                    else
+                        __is.setstate(ios_base::failbit);
+                }
+                else if (__c == _CharT(')'))
+                {
+                    __is.get();
+                    __x = complex<_Tp>(__r, _Tp(0));
+                }
+                else
+                    __is.setstate(ios_base::failbit);
+            }
+            else
+                __is.setstate(ios_base::failbit);
+        }
+        else
+        {
+            _Tp __r;
+            __is >> __r;
+            if (!__is.fail())
+                __x = complex<_Tp>(__r, _Tp(0));
+            else
+                __is.setstate(ios_base::failbit);
+        }
+    }
+    else
+        __is.setstate(ios_base::failbit);
+    return __is;
+}
+
+template<class _Tp, class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
+{
+    basic_ostringstream<_CharT, _Traits> __s;
+    __s.flags(__os.flags());
+    __s.imbue(__os.getloc());
+    __s.precision(__os.precision());
+    __s << '(' << __x.real() << ',' << __x.imag() << ')';
+    return __os << __s.str();
+}
+
+#if _LIBCPP_STD_VER > 11 
+// Literal suffix for complex number literals [complex.literals]
+inline namespace literals
+{ 
+  inline namespace complex_literals
+  {
+    constexpr complex<long double> operator""il(long double __im)
+    {
+        return { 0.0l, __im };
+    }
+
+    constexpr complex<long double> operator""il(unsigned long long __im)
+    {
+        return { 0.0l, static_cast<long double>(__im) };
+    }
+
+
+    constexpr complex<double> operator""i(long double __im)
+    {
+        return { 0.0, static_cast<double>(__im) };
+    }
+
+    constexpr complex<double> operator""i(unsigned long long __im)
+    {
+        return { 0.0, static_cast<double>(__im) };
+    }
+
+
+    constexpr complex<float> operator""if(long double __im)
+    {
+        return { 0.0f, static_cast<float>(__im) };
+    }
+
+    constexpr complex<float> operator""if(unsigned long long __im)
+    {
+        return { 0.0f, static_cast<float>(__im) };
+    }
+  }
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_COMPLEX
diff --git a/include/c++/v1/complex.h b/include/c++/v1/complex.h
new file mode 100644
index 0000000..7003d31
--- /dev/null
+++ b/include/c++/v1/complex.h
@@ -0,0 +1,35 @@
+// -*- C++ -*-
+//===--------------------------- complex.h --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_COMPLEX_H
+#define _LIBCPP_COMPLEX_H
+
+/*
+    complex.h synopsis
+
+#include <ccomplex>
+
+*/
+
+#ifdef __cplusplus
+
+#include <ccomplex>
+
+#else  // __cplusplus
+
+#include_next <complex.h>
+
+#endif  // __cplusplus
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#endif  // _LIBCPP_COMPLEX_H
diff --git a/include/c++/v1/condition_variable b/include/c++/v1/condition_variable
new file mode 100644
index 0000000..dc67266
--- /dev/null
+++ b/include/c++/v1/condition_variable
@@ -0,0 +1,256 @@
+// -*- C++ -*-
+//===---------------------- condition_variable ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CONDITION_VARIABLE
+#define _LIBCPP_CONDITION_VARIABLE
+
+/*
+    condition_variable synopsis
+
+namespace std
+{
+
+enum class cv_status { no_timeout, timeout };
+
+class condition_variable
+{
+public:
+    condition_variable();
+    ~condition_variable();
+
+    condition_variable(const condition_variable&) = delete;
+    condition_variable& operator=(const condition_variable&) = delete;
+
+    void notify_one() noexcept;
+    void notify_all() noexcept;
+
+    void wait(unique_lock<mutex>& lock);
+    template <class Predicate>
+        void wait(unique_lock<mutex>& lock, Predicate pred);
+
+    template <class Clock, class Duration>
+        cv_status
+        wait_until(unique_lock<mutex>& lock,
+                   const chrono::time_point<Clock, Duration>& abs_time);
+
+    template <class Clock, class Duration, class Predicate>
+        bool
+        wait_until(unique_lock<mutex>& lock,
+                   const chrono::time_point<Clock, Duration>& abs_time,
+                   Predicate pred);
+
+    template <class Rep, class Period>
+        cv_status
+        wait_for(unique_lock<mutex>& lock,
+                 const chrono::duration<Rep, Period>& rel_time);
+
+    template <class Rep, class Period, class Predicate>
+        bool
+        wait_for(unique_lock<mutex>& lock,
+                 const chrono::duration<Rep, Period>& rel_time,
+                 Predicate pred);
+
+    typedef pthread_cond_t* native_handle_type;
+    native_handle_type native_handle();
+};
+
+void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+class condition_variable_any
+{
+public:
+    condition_variable_any();
+    ~condition_variable_any();
+
+    condition_variable_any(const condition_variable_any&) = delete;
+    condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+    void notify_one() noexcept;
+    void notify_all() noexcept;
+
+    template <class Lock>
+        void wait(Lock& lock);
+    template <class Lock, class Predicate>
+        void wait(Lock& lock, Predicate pred);
+
+    template <class Lock, class Clock, class Duration>
+        cv_status
+        wait_until(Lock& lock,
+                   const chrono::time_point<Clock, Duration>& abs_time);
+
+    template <class Lock, class Clock, class Duration, class Predicate>
+        bool
+        wait_until(Lock& lock,
+                   const chrono::time_point<Clock, Duration>& abs_time,
+                   Predicate pred);
+
+    template <class Lock, class Rep, class Period>
+        cv_status
+        wait_for(Lock& lock,
+                 const chrono::duration<Rep, Period>& rel_time);
+
+    template <class Lock, class Rep, class Period, class Predicate>
+        bool
+        wait_for(Lock& lock,
+                 const chrono::duration<Rep, Period>& rel_time,
+                 Predicate pred);
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__mutex_base>
+#include <memory>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS condition_variable_any
+{
+    condition_variable __cv_;
+    shared_ptr<mutex>  __mut_;
+public:
+    condition_variable_any();
+
+    void notify_one() _NOEXCEPT;
+    void notify_all() _NOEXCEPT;
+
+    template <class _Lock>
+        void wait(_Lock& __lock);
+    template <class _Lock, class _Predicate>
+        void wait(_Lock& __lock, _Predicate __pred);
+
+    template <class _Lock, class _Clock, class _Duration>
+        cv_status
+        wait_until(_Lock& __lock,
+                   const chrono::time_point<_Clock, _Duration>& __t);
+
+    template <class _Lock, class _Clock, class _Duration, class _Predicate>
+        bool
+        wait_until(_Lock& __lock,
+                   const chrono::time_point<_Clock, _Duration>& __t,
+                   _Predicate __pred);
+
+    template <class _Lock, class _Rep, class _Period>
+        cv_status
+        wait_for(_Lock& __lock,
+                 const chrono::duration<_Rep, _Period>& __d);
+
+    template <class _Lock, class _Rep, class _Period, class _Predicate>
+        bool
+        wait_for(_Lock& __lock,
+                 const chrono::duration<_Rep, _Period>& __d,
+                 _Predicate __pred);
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+condition_variable_any::condition_variable_any()
+    : __mut_(make_shared<mutex>()) {}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+condition_variable_any::notify_one() _NOEXCEPT
+{
+    {lock_guard<mutex> __lx(*__mut_);}
+    __cv_.notify_one();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+condition_variable_any::notify_all() _NOEXCEPT
+{
+    {lock_guard<mutex> __lx(*__mut_);}
+    __cv_.notify_all();
+}
+
+struct __lock_external
+{
+    template <class _Lock>
+    void operator()(_Lock* __m) {__m->lock();}
+};
+
+template <class _Lock>
+void
+condition_variable_any::wait(_Lock& __lock)
+{
+    shared_ptr<mutex> __mut = __mut_;
+    unique_lock<mutex> __lk(*__mut);
+    __lock.unlock();
+    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
+    __cv_.wait(__lk);
+}  // __mut_.unlock(), __lock.lock()
+
+template <class _Lock, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+condition_variable_any::wait(_Lock& __lock, _Predicate __pred)
+{
+    while (!__pred())
+        wait(__lock);
+}
+
+template <class _Lock, class _Clock, class _Duration>
+cv_status
+condition_variable_any::wait_until(_Lock& __lock,
+                                   const chrono::time_point<_Clock, _Duration>& __t)
+{
+    shared_ptr<mutex> __mut = __mut_;
+    unique_lock<mutex> __lk(*__mut);
+    __lock.unlock();
+    unique_ptr<_Lock, __lock_external> __lxx(&__lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock);
+    return __cv_.wait_until(__lk, __t);
+}  // __mut_.unlock(), __lock.lock()
+
+template <class _Lock, class _Clock, class _Duration, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+condition_variable_any::wait_until(_Lock& __lock,
+                                   const chrono::time_point<_Clock, _Duration>& __t,
+                                   _Predicate __pred)
+{
+    while (!__pred())
+        if (wait_until(__lock, __t) == cv_status::timeout)
+            return __pred();
+    return true;
+}
+
+template <class _Lock, class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+cv_status
+condition_variable_any::wait_for(_Lock& __lock,
+                                 const chrono::duration<_Rep, _Period>& __d)
+{
+    return wait_until(__lock, chrono::steady_clock::now() + __d);
+}
+
+template <class _Lock, class _Rep, class _Period, class _Predicate>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+condition_variable_any::wait_for(_Lock& __lock,
+                                 const chrono::duration<_Rep, _Period>& __d,
+                                 _Predicate __pred)
+{
+    return wait_until(__lock, chrono::steady_clock::now() + __d,
+                      _VSTD::move(__pred));
+}
+
+_LIBCPP_FUNC_VIS
+void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CONDITION_VARIABLE
diff --git a/include/c++/v1/csetjmp b/include/c++/v1/csetjmp
new file mode 100644
index 0000000..d0b2c07
--- /dev/null
+++ b/include/c++/v1/csetjmp
@@ -0,0 +1,52 @@
+// -*- C++ -*-
+//===--------------------------- csetjmp ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSETJMP
+#define _LIBCPP_CSETJMP
+
+/*
+    csetjmp synopsis
+
+Macros:
+
+    setjmp
+
+namespace std
+{
+
+Types:
+
+    jmp_buf
+
+void longjmp(jmp_buf env, int val);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <setjmp.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifndef setjmp
+#define setjmp(env) setjmp(env)
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::jmp_buf;
+using ::longjmp;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSETJMP
diff --git a/include/c++/v1/csignal b/include/c++/v1/csignal
new file mode 100644
index 0000000..9728266
--- /dev/null
+++ b/include/c++/v1/csignal
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===--------------------------- csignal ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSIGNAL
+#define _LIBCPP_CSIGNAL
+
+/*
+    csignal synopsis
+
+Macros:
+
+    SIG_DFL
+    SIG_ERR
+    SIG_IGN
+    SIGABRT
+    SIGFPE
+    SIGILL
+    SIGINT
+    SIGSEGV
+    SIGTERM
+
+namespace std
+{
+
+Types:
+
+    sig_atomic_t
+
+void (*signal(int sig, void (*func)(int)))(int);
+int raise(int sig);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <signal.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::sig_atomic_t;
+using ::signal;
+using ::raise;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSIGNAL
diff --git a/include/c++/v1/cstdarg b/include/c++/v1/cstdarg
new file mode 100644
index 0000000..c8b6999
--- /dev/null
+++ b/include/c++/v1/cstdarg
@@ -0,0 +1,48 @@
+// -*- C++ -*-
+//===--------------------------- cstdarg ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDARG
+#define _LIBCPP_CSTDARG
+
+/*
+    cstdarg synopsis
+
+Macros:
+
+    type va_arg(va_list ap, type);
+    void va_copy(va_list dest, va_list src);  // C99
+    void va_end(va_list ap);
+    void va_start(va_list ap, parmN);
+
+namespace std
+{
+
+Types:
+
+    va_list
+
+}  // std
+
+*/
+
+#include <__config>
+#include <stdarg.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::va_list;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSTDARG
diff --git a/include/c++/v1/cstdbool b/include/c++/v1/cstdbool
new file mode 100644
index 0000000..2c764a6
--- /dev/null
+++ b/include/c++/v1/cstdbool
@@ -0,0 +1,32 @@
+// -*- C++ -*-
+//===--------------------------- cstdbool ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDBOOL
+#define _LIBCPP_CSTDBOOL
+
+/*
+    cstdbool synopsis
+
+Macros:
+
+    __bool_true_false_are_defined
+
+*/
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#undef __bool_true_false_are_defined
+#define __bool_true_false_are_defined 1
+
+#endif  // _LIBCPP_CSTDBOOL
diff --git a/include/c++/v1/cstddef b/include/c++/v1/cstddef
new file mode 100644
index 0000000..c3ca64a
--- /dev/null
+++ b/include/c++/v1/cstddef
@@ -0,0 +1,102 @@
+// -*- C++ -*-
+//===--------------------------- cstddef ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDDEF
+#define _LIBCPP_CSTDDEF
+
+/*
+    cstddef synopsis
+
+Macros:
+
+    offsetof(type,member-designator)
+    NULL
+
+namespace std
+{
+
+Types:
+
+    ptrdiff_t
+    size_t
+    max_align_t
+    nullptr_t
+
+}  // std
+
+*/
+
+#include <__config>
+
+#include <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::ptrdiff_t;
+using ::size_t;
+
+#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T)
+// Re-use the compiler's <stddef.h> max_align_t where possible.
+using ::max_align_t;
+#else
+typedef long double max_align_t;
+#endif
+
+#ifdef _LIBCPP_HAS_NO_NULLPTR
+
+struct _LIBCPP_TYPE_VIS_ONLY nullptr_t
+{
+    void* __lx;
+
+    struct __nat {int __for_bool_;};
+
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
+
+    _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
+
+    template <class _Tp>
+        _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
+        operator _Tp* () const {return 0;}
+
+    template <class _Tp, class _Up>
+        _LIBCPP_ALWAYS_INLINE
+        operator _Tp _Up::* () const {return 0;}
+
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;}
+    friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;}
+};
+
+inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
+
+#define nullptr _VSTD::__get_nullptr_t()
+
+#endif  // _LIBCPP_HAS_NO_NULLPTR
+
+_LIBCPP_END_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_NULLPTR
+
+namespace std
+{
+    typedef decltype(nullptr) nullptr_t;
+}
+
+#endif  // _LIBCPP_HAS_NO_NULLPTR
+
+#endif  // _LIBCPP_CSTDDEF
diff --git a/include/c++/v1/cstdint b/include/c++/v1/cstdint
new file mode 100644
index 0000000..7a187d3
--- /dev/null
+++ b/include/c++/v1/cstdint
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+//===--------------------------- cstdint ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDINT
+#define _LIBCPP_CSTDINT
+
+/*
+    cstdint synopsis
+
+Macros:
+
+    INT8_MIN
+    INT16_MIN
+    INT32_MIN
+    INT64_MIN
+
+    INT8_MAX
+    INT16_MAX
+    INT32_MAX
+    INT64_MAX
+
+    UINT8_MAX
+    UINT16_MAX
+    UINT32_MAX
+    UINT64_MAX
+
+    INT_LEAST8_MIN
+    INT_LEAST16_MIN
+    INT_LEAST32_MIN
+    INT_LEAST64_MIN
+
+    INT_LEAST8_MAX
+    INT_LEAST16_MAX
+    INT_LEAST32_MAX
+    INT_LEAST64_MAX
+
+    UINT_LEAST8_MAX
+    UINT_LEAST16_MAX
+    UINT_LEAST32_MAX
+    UINT_LEAST64_MAX
+
+    INT_FAST8_MIN
+    INT_FAST16_MIN
+    INT_FAST32_MIN
+    INT_FAST64_MIN
+
+    INT_FAST8_MAX
+    INT_FAST16_MAX
+    INT_FAST32_MAX
+    INT_FAST64_MAX
+
+    UINT_FAST8_MAX
+    UINT_FAST16_MAX
+    UINT_FAST32_MAX
+    UINT_FAST64_MAX
+
+    INTPTR_MIN
+    INTPTR_MAX
+    UINTPTR_MAX
+
+    INTMAX_MIN
+    INTMAX_MAX
+
+    UINTMAX_MAX
+
+    PTRDIFF_MIN
+    PTRDIFF_MAX
+
+    SIG_ATOMIC_MIN
+    SIG_ATOMIC_MAX
+
+    SIZE_MAX
+
+    WCHAR_MIN
+    WCHAR_MAX
+
+    WINT_MIN
+    WINT_MAX
+
+    INT8_C(value)
+    INT16_C(value)
+    INT32_C(value)
+    INT64_C(value)
+
+    UINT8_C(value)
+    UINT16_C(value)
+    UINT32_C(value)
+    UINT64_C(value)
+
+    INTMAX_C(value)
+    UINTMAX_C(value)
+
+namespace std
+{
+
+Types:
+
+    int8_t
+    int16_t
+    int32_t
+    int64_t
+
+    uint8_t
+    uint16_t
+    uint32_t
+    uint64_t
+
+    int_least8_t
+    int_least16_t
+    int_least32_t
+    int_least64_t
+
+    uint_least8_t
+    uint_least16_t
+    uint_least32_t
+    uint_least64_t
+
+    int_fast8_t
+    int_fast16_t
+    int_fast32_t
+    int_fast64_t
+
+    uint_fast8_t
+    uint_fast16_t
+    uint_fast32_t
+    uint_fast64_t
+
+    intptr_t
+    uintptr_t
+
+    intmax_t
+    uintmax_t
+
+}  // std
+*/
+
+#include <__config>
+#include <stdint.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using::int8_t;
+using::int16_t;
+using::int32_t;
+using::int64_t;
+
+using::uint8_t;
+using::uint16_t;
+using::uint32_t;
+using::uint64_t;
+
+using::int_least8_t;
+using::int_least16_t;
+using::int_least32_t;
+using::int_least64_t;
+
+using::uint_least8_t;
+using::uint_least16_t;
+using::uint_least32_t;
+using::uint_least64_t;
+
+using::int_fast8_t;
+using::int_fast16_t;
+using::int_fast32_t;
+using::int_fast64_t;
+
+using::uint_fast8_t;
+using::uint_fast16_t;
+using::uint_fast32_t;
+using::uint_fast64_t;
+
+using::intptr_t;
+using::uintptr_t;
+
+using::intmax_t;
+using::uintmax_t;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSTDINT
diff --git a/include/c++/v1/cstdio b/include/c++/v1/cstdio
new file mode 100644
index 0000000..ce3af4d
--- /dev/null
+++ b/include/c++/v1/cstdio
@@ -0,0 +1,182 @@
+// -*- C++ -*-
+//===---------------------------- cstdio ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDIO
+#define _LIBCPP_CSTDIO
+
+/*
+    cstdio synopsis
+
+Macros:
+
+    BUFSIZ
+    EOF
+    FILENAME_MAX
+    FOPEN_MAX
+    L_tmpnam
+    NULL
+    SEEK_CUR
+    SEEK_END
+    SEEK_SET
+    TMP_MAX
+    _IOFBF
+    _IOLBF
+    _IONBF
+    stderr
+    stdin
+    stdout
+
+namespace std
+{
+
+Types:
+
+FILE
+fpos_t
+size_t
+
+int remove(const char* filename);
+int rename(const char* old, const char* new);
+FILE* tmpfile(void);
+char* tmpnam(char* s);
+int fclose(FILE* stream);
+int fflush(FILE* stream);
+FILE* fopen(const char* restrict filename, const char* restrict mode);
+FILE* freopen(const char* restrict filename, const char * restrict mode,
+              FILE * restrict stream);
+void setbuf(FILE* restrict stream, char* restrict buf);
+int setvbuf(FILE* restrict stream, char* restrict buf, int mode, size_t size);
+int fprintf(FILE* restrict stream, const char* restrict format, ...);
+int fscanf(FILE* restrict stream, const char * restrict format, ...);
+int printf(const char* restrict format, ...);
+int scanf(const char* restrict format, ...);
+int snprintf(char* restrict s, size_t n, const char* restrict format, ...);    // C99
+int sprintf(char* restrict s, const char* restrict format, ...);
+int sscanf(const char* restrict s, const char* restrict format, ...);
+int vfprintf(FILE* restrict stream, const char* restrict format, va_list arg);
+int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);  // C99
+int vprintf(const char* restrict format, va_list arg);
+int vscanf(const char* restrict format, va_list arg);                          // C99
+int vsnprintf(char* restrict s, size_t n, const char* restrict format,         // C99
+              va_list arg);
+int vsprintf(char* restrict s, const char* restrict format, va_list arg);
+int vsscanf(const char* restrict s, const char* restrict format, va_list arg); // C99
+int fgetc(FILE* stream);
+char* fgets(char* restrict s, int n, FILE* restrict stream);
+int fputc(int c, FILE* stream);
+int fputs(const char* restrict s, FILE* restrict stream);
+int getc(FILE* stream);
+int getchar(void);
+char* gets(char* s);  // removed in C++14
+int putc(int c, FILE* stream);
+int putchar(int c);
+int puts(const char* s);
+int ungetc(int c, FILE* stream);
+size_t fread(void* restrict ptr, size_t size, size_t nmemb,
+             FILE* restrict stream);
+size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb,
+              FILE* restrict stream);
+int fgetpos(FILE* restrict stream, fpos_t* restrict pos);
+int fseek(FILE* stream, long offset, int whence);
+int fsetpos(FILE*stream, const fpos_t* pos);
+long ftell(FILE* stream);
+void rewind(FILE* stream);
+void clearerr(FILE* stream);
+int feof(FILE* stream);
+int ferror(FILE* stream);
+void perror(const char* s);
+
+}  // std
+*/
+
+#include <__config>
+#include <stdio.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+// snprintf
+#if defined(_LIBCPP_MSVCRT)
+#include "support/win32/support.h"
+#endif
+
+#ifdef getc
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_getc(FILE* __stream) {return getc(__stream);}
+#undef getc
+inline _LIBCPP_INLINE_VISIBILITY int getc(FILE* __stream) {return __libcpp_getc(__stream);}
+#endif  // getc
+
+#ifdef putc
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_putc(int __c, FILE* __stream) {return putc(__c, __stream);}
+#undef putc
+inline _LIBCPP_INLINE_VISIBILITY int putc(int __c, FILE* __stream) {return __libcpp_putc(__c, __stream);}
+#endif  // putc
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::FILE;
+using ::fpos_t;
+using ::size_t;
+
+using ::remove;
+using ::rename;
+using ::tmpfile;
+using ::tmpnam;
+using ::fclose;
+using ::fflush;
+using ::fopen;
+using ::freopen;
+using ::setbuf;
+using ::setvbuf;
+using ::fprintf;
+using ::fscanf;
+using ::printf;
+using ::scanf;
+using ::snprintf;
+using ::sprintf;
+using ::sscanf;
+#ifndef _LIBCPP_MSVCRT
+using ::vfprintf;
+using ::vfscanf;
+using ::vscanf;
+using ::vsscanf;
+#endif // _LIBCPP_MSVCRT
+using ::vprintf;
+using ::vsnprintf;
+using ::vsprintf;
+using ::fgetc;
+using ::fgets;
+using ::fputc;
+using ::fputs;
+using ::getc;
+using ::getchar;
+#if _LIBCPP_STD_VER <= 11
+using ::gets;
+#endif
+using ::putc;
+using ::putchar;
+using ::puts;
+using ::ungetc;
+using ::fread;
+using ::fwrite;
+using ::fgetpos;
+using ::fseek;
+using ::fsetpos;
+using ::ftell;
+using ::rewind;
+using ::clearerr;
+using ::feof;
+using ::ferror;
+using ::perror;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSTDIO
diff --git a/include/c++/v1/cstdlib b/include/c++/v1/cstdlib
new file mode 100644
index 0000000..152b891
--- /dev/null
+++ b/include/c++/v1/cstdlib
@@ -0,0 +1,172 @@
+// -*- C++ -*-
+//===--------------------------- cstdlib ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTDLIB
+#define _LIBCPP_CSTDLIB
+
+/*
+    cstdlib synopsis
+
+Macros:
+
+    EXIT_FAILURE
+    EXIT_SUCCESS
+    MB_CUR_MAX
+    NULL
+    RAND_MAX
+
+namespace std
+{
+
+Types:
+
+    size_t
+    div_t
+    ldiv_t
+    lldiv_t                                                               // C99
+
+double    atof (const char* nptr);
+int       atoi (const char* nptr);
+long      atol (const char* nptr);
+long long atoll(const char* nptr);                                        // C99
+double             strtod  (const char* restrict nptr, char** restrict endptr);
+float              strtof  (const char* restrict nptr, char** restrict endptr); // C99
+long double        strtold (const char* restrict nptr, char** restrict endptr); // C99
+long               strtol  (const char* restrict nptr, char** restrict endptr, int base);
+long long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99
+unsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);
+unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99
+int rand(void);
+void srand(unsigned int seed);
+void* calloc(size_t nmemb, size_t size);
+void free(void* ptr);
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+void abort(void);
+int atexit(void (*func)(void));
+void exit(int status);
+void _Exit(int status);
+char* getenv(const char* name);
+int system(const char* string);
+void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
+              int (*compar)(const void *, const void *));
+void qsort(void* base, size_t nmemb, size_t size,
+           int (*compar)(const void *, const void *));
+int         abs(      int j);
+long        abs(     long j);
+long long   abs(long long j);                                             // C++0X
+long       labs(     long j);
+long long llabs(long long j);                                             // C99
+div_t     div(      int numer,       int denom);
+ldiv_t    div(     long numer,      long denom);
+lldiv_t   div(long long numer, long long denom);                          // C++0X
+ldiv_t   ldiv(     long numer,      long denom);
+lldiv_t lldiv(long long numer, long long denom);                          // C99
+int mblen(const char* s, size_t n);
+int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
+int wctomb(char* s, wchar_t wchar);
+size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);
+size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);
+int at_quick_exit(void (*func)(void))                                     // C++11
+void quick_exit(int status);                                              // C++11
+void *aligned_alloc(size_t alignment, size_t size);                       // C11
+
+}  // std
+
+*/
+
+#include <__config>
+#include <stdlib.h>
+#ifdef _LIBCPP_MSVCRT
+#include "support/win32/locale_win32.h"
+#endif // _LIBCPP_MSVCRT
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::size_t;
+using ::div_t;
+using ::ldiv_t;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::lldiv_t;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::atof;
+using ::atoi;
+using ::atol;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::atoll;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::strtod;
+using ::strtof;
+using ::strtold;
+using ::strtol;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::strtoll;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::strtoul;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::strtoull;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::rand;
+using ::srand;
+using ::calloc;
+using ::free;
+using ::malloc;
+using ::realloc;
+using ::abort;
+using ::atexit;
+using ::exit;
+using ::_Exit;
+using ::getenv;
+using ::system;
+using ::bsearch;
+using ::qsort;
+using ::abs;
+using ::labs;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::llabs;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::div;
+using ::ldiv;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::lldiv;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::mblen;
+using ::mbtowc;
+using ::wctomb;
+using ::mbstowcs;
+using ::wcstombs;
+#ifdef _LIBCPP_HAS_QUICK_EXIT
+using ::at_quick_exit;
+using ::quick_exit;
+#endif
+#ifdef _LIBCPP_HAS_C11_FEATURES
+using ::aligned_alloc;
+#endif
+
+// MSVCRT already has the correct prototype in <stdlib.h> #ifdef __cplusplus
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+
+inline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+#endif // _LIBCPP_MSVCRT
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSTDLIB
diff --git a/include/c++/v1/cstring b/include/c++/v1/cstring
new file mode 100644
index 0000000..21c9155
--- /dev/null
+++ b/include/c++/v1/cstring
@@ -0,0 +1,112 @@
+// -*- C++ -*-
+//===--------------------------- cstring ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CSTRING
+#define _LIBCPP_CSTRING
+
+/*
+    cstring synopsis
+
+Macros:
+
+    NULL
+
+namespace std
+{
+
+Types:
+
+    size_t
+
+void* memcpy(void* restrict s1, const void* restrict s2, size_t n);
+void* memmove(void* s1, const void* s2, size_t n);
+char* strcpy (char* restrict s1, const char* restrict s2);
+char* strncpy(char* restrict s1, const char* restrict s2, size_t n);
+char* strcat (char* restrict s1, const char* restrict s2);
+char* strncat(char* restrict s1, const char* restrict s2, size_t n);
+int memcmp(const void* s1, const void* s2, size_t n);
+int strcmp (const char* s1, const char* s2);
+int strncmp(const char* s1, const char* s2, size_t n);
+int strcoll(const char* s1, const char* s2);
+size_t strxfrm(char* restrict s1, const char* restrict s2, size_t n);
+const void* memchr(const void* s, int c, size_t n);
+      void* memchr(      void* s, int c, size_t n);
+const char* strchr(const char* s, int c);
+      char* strchr(      char* s, int c);
+size_t strcspn(const char* s1, const char* s2);
+const char* strpbrk(const char* s1, const char* s2);
+      char* strpbrk(      char* s1, const char* s2);
+const char* strrchr(const char* s, int c);
+      char* strrchr(      char* s, int c);
+size_t strspn(const char* s1, const char* s2);
+const char* strstr(const char* s1, const char* s2);
+      char* strstr(      char* s1, const char* s2);
+char* strtok(char* restrict s1, const char* restrict s2);
+void* memset(void* s, int c, size_t n);
+char* strerror(int errnum);
+size_t strlen(const char* s);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::size_t;
+using ::memcpy;
+using ::memmove;
+using ::strcpy;
+using ::strncpy;
+using ::strcat;
+using ::strncat;
+using ::memcmp;
+using ::strcmp;
+using ::strncmp;
+using ::strcoll;
+using ::strxfrm;
+
+using ::memchr;
+
+using ::strchr;
+
+using ::strcspn;
+
+using ::strpbrk;
+
+using ::strrchr;
+
+using ::strspn;
+
+using ::strstr;
+
+// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus
+#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
+inline _LIBCPP_INLINE_VISIBILITY       char* strchr(      char* __s, int __c) {return ::strchr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY       char* strpbrk(      char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);}
+inline _LIBCPP_INLINE_VISIBILITY       char* strrchr(      char* __s, int __c) {return ::strrchr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY       void* memchr(      void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);}
+inline _LIBCPP_INLINE_VISIBILITY       char* strstr(      char* __s1, const char* __s2) {return ::strstr(__s1, __s2);}
+#endif
+
+using ::strtok;
+using ::memset;
+using ::strerror;
+using ::strlen;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CSTRING
diff --git a/include/c++/v1/ctgmath b/include/c++/v1/ctgmath
new file mode 100644
index 0000000..535eb7d
--- /dev/null
+++ b/include/c++/v1/ctgmath
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===-------------------------- ctgmath -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CTGMATH
+#define _LIBCPP_CTGMATH
+
+/*
+    ctgmath synopsis
+
+#include <ccomplex>
+#include <cmath>
+
+*/
+
+#include <ccomplex>
+#include <cmath>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#endif  // _LIBCPP_CTGMATH
diff --git a/include/c++/v1/ctime b/include/c++/v1/ctime
new file mode 100644
index 0000000..fc4eb26
--- /dev/null
+++ b/include/c++/v1/ctime
@@ -0,0 +1,72 @@
+// -*- C++ -*-
+//===---------------------------- ctime -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CTIME
+#define _LIBCPP_CTIME
+
+/*
+    ctime synopsis
+
+Macros:
+
+    NULL
+    CLOCKS_PER_SEC
+
+namespace std
+{
+
+Types:
+
+    clock_t
+    size_t
+    time_t
+    tm
+
+clock_t clock();
+double difftime(time_t time1, time_t time0);
+time_t mktime(tm* timeptr);
+time_t time(time_t* timer);
+char* asctime(const tm* timeptr);
+char* ctime(const time_t* timer);
+tm*    gmtime(const time_t* timer);
+tm* localtime(const time_t* timer);
+size_t strftime(char* restrict s, size_t maxsize, const char* restrict format,
+                const tm* restrict timeptr);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <time.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::clock_t;
+using ::size_t;
+using ::time_t;
+using ::tm;
+using ::clock;
+using ::difftime;
+using ::mktime;
+using ::time;
+using ::asctime;
+using ::ctime;
+using ::gmtime;
+using ::localtime;
+using ::strftime;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CTIME
diff --git a/include/c++/v1/cwchar b/include/c++/v1/cwchar
new file mode 100644
index 0000000..9f51587
--- /dev/null
+++ b/include/c++/v1/cwchar
@@ -0,0 +1,217 @@
+// -*- C++ -*-
+//===--------------------------- cwchar -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CWCHAR
+#define _LIBCPP_CWCHAR
+
+/*
+    cwchar synopsis
+
+Macros:
+
+    NULL
+    WCHAR_MAX
+    WCHAR_MIN
+    WEOF
+
+namespace std
+{
+
+Types:
+
+    mbstate_t
+    size_t
+    tm
+    wint_t
+
+int fwprintf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int swprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, ...);
+int swscanf(const wchar_t* restrict s, const wchar_t* restrict format, ...);
+int vfwprintf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);
+int vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);  // C99
+int vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, va_list arg);
+int vswscanf(const wchar_t* restrict s, const wchar_t* restrict format, va_list arg);  // C99
+int vwprintf(const wchar_t* restrict format, va_list arg);
+int vwscanf(const wchar_t* restrict format, va_list arg);  // C99
+int wprintf(const wchar_t* restrict format, ...);
+int wscanf(const wchar_t* restrict format, ...);
+wint_t fgetwc(FILE* stream);
+wchar_t* fgetws(wchar_t* restrict s, int n, FILE* restrict stream);
+wint_t fputwc(wchar_t c, FILE* stream);
+int fputws(const wchar_t* restrict s, FILE* restrict stream);
+int fwide(FILE* stream, int mode);
+wint_t getwc(FILE* stream);
+wint_t getwchar();
+wint_t putwc(wchar_t c, FILE* stream);
+wint_t putwchar(wchar_t c);
+wint_t ungetwc(wint_t c, FILE* stream);
+double wcstod(const wchar_t* restrict nptr, wchar_t** restrict endptr);
+float wcstof(const wchar_t* restrict nptr, wchar_t** restrict endptr);         // C99
+long double wcstold(const wchar_t* restrict nptr, wchar_t** restrict endptr);  // C99
+long wcstol(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+long long wcstoll(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+unsigned long wcstoul(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+unsigned long long wcstoull(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+wchar_t* wcscpy(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wcscat(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncat(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+int wcscmp(const wchar_t* s1, const wchar_t* s2);
+int wcscoll(const wchar_t* s1, const wchar_t* s2);
+int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);
+size_t wcsxfrm(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+const wchar_t* wcschr(const wchar_t* s, wchar_t c);
+      wchar_t* wcschr(      wchar_t* s, wchar_t c);
+size_t wcscspn(const wchar_t* s1, const wchar_t* s2);
+size_t wcslen(const wchar_t* s);
+const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcspbrk(      wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);
+      wchar_t* wcsrchr(      wchar_t* s, wchar_t c);
+size_t wcsspn(const wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcsstr(      wchar_t* s1, const wchar_t* s2);
+wchar_t* wcstok(wchar_t* restrict s1, const wchar_t* restrict s2, wchar_t** restrict ptr);
+const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
+      wchar_t* wmemchr(      wchar_t* s, wchar_t c, size_t n);
+int wmemcmp(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemcpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);
+wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);
+size_t wcsftime(wchar_t* restrict s, size_t maxsize, const wchar_t* restrict format,
+                const tm* restrict timeptr);
+wint_t btowc(int c);
+int wctob(wint_t c);
+int mbsinit(const mbstate_t* ps);
+size_t mbrlen(const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t mbrtowc(wchar_t* restrict pwc, const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t wcrtomb(char* restrict s, wchar_t wc, mbstate_t* restrict ps);
+size_t mbsrtowcs(wchar_t* restrict dst, const char** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cwctype>
+#include <wchar.h>
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#include <support/win32/support.h> // pull in *swprintf defines
+#endif // _LIBCPP_MSVCRT
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::mbstate_t;
+using ::size_t;
+using ::tm;
+using ::wint_t;
+using ::FILE;
+using ::fwprintf;
+using ::fwscanf;
+using ::swprintf;
+using ::vfwprintf;
+using ::vswprintf;
+using ::vwprintf;
+#ifndef _LIBCPP_MSVCRT
+using ::swscanf;
+using ::vfwscanf;
+using ::vswscanf;
+using ::vwscanf;
+#endif // _LIBCPP_MSVCRT
+using ::wprintf;
+using ::wscanf;
+using ::fgetwc;
+using ::fgetws;
+using ::fputwc;
+using ::fputws;
+using ::fwide;
+using ::getwc;
+using ::getwchar;
+using ::putwc;
+using ::putwchar;
+using ::ungetwc;
+using ::wcstod;
+#ifndef _LIBCPP_MSVCRT
+using ::wcstof;
+using ::wcstold;
+#endif // _LIBCPP_MSVCRT
+using ::wcstol;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::wcstoll;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::wcstoul;
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+using ::wcstoull;
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+using ::wcscpy;
+using ::wcsncpy;
+using ::wcscat;
+using ::wcsncat;
+using ::wcscmp;
+using ::wcscoll;
+using ::wcsncmp;
+using ::wcsxfrm;
+
+#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)
+
+using ::wcschr;
+using ::wcspbrk;
+using ::wcsrchr;
+using ::wcsstr;
+using ::wmemchr;
+
+#else
+
+inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcschr(      wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}
+
+inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);}
+inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcspbrk(      wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);}
+
+inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcsrchr(      wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);}
+
+inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);}
+inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcsstr(      wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);}
+
+inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}
+inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wmemchr(      wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}
+
+#endif
+
+using ::wcscspn;
+using ::wcslen;
+using ::wcsspn;
+using ::wcstok;
+using ::wmemcmp;
+using ::wmemcpy;
+using ::wmemmove;
+using ::wmemset;
+using ::wcsftime;
+using ::btowc;
+using ::wctob;
+using ::mbsinit;
+using ::mbrlen;
+using ::mbrtowc;
+using ::wcrtomb;
+using ::mbsrtowcs;
+using ::wcsrtombs;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CWCHAR
diff --git a/include/c++/v1/cwctype b/include/c++/v1/cwctype
new file mode 100644
index 0000000..4f89b52
--- /dev/null
+++ b/include/c++/v1/cwctype
@@ -0,0 +1,213 @@
+// -*- C++ -*-
+//===--------------------------- cwctype ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_CWCTYPE
+#define _LIBCPP_CWCTYPE
+
+/*
+    cwctype synopsis
+
+Macros:
+
+    WEOF
+
+namespace std
+{
+
+Types:
+
+    wint_t
+    wctrans_t
+    wctype_t
+
+int iswalnum(wint_t wc);
+int iswalpha(wint_t wc);
+int iswblank(wint_t wc);  // C99
+int iswcntrl(wint_t wc);
+int iswdigit(wint_t wc);
+int iswgraph(wint_t wc);
+int iswlower(wint_t wc);
+int iswprint(wint_t wc);
+int iswpunct(wint_t wc);
+int iswspace(wint_t wc);
+int iswupper(wint_t wc);
+int iswxdigit(wint_t wc);
+int iswctype(wint_t wc, wctype_t desc);
+wctype_t wctype(const char* property);
+wint_t towlower(wint_t wc);
+wint_t towupper(wint_t wc);
+wint_t towctrans(wint_t wc, wctrans_t desc);
+wctrans_t wctrans(const char* property);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cctype>
+#include <wctype.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::wint_t;
+using ::wctrans_t;
+using ::wctype_t;
+
+#ifdef iswalnum
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalnum(wint_t __wc) {return iswalnum(__wc);}
+#undef iswalnum
+inline _LIBCPP_INLINE_VISIBILITY int iswalnum(wint_t __wc) {return __libcpp_iswalnum(__wc);}
+#else  // iswalnum
+using ::iswalnum;
+#endif
+
+#ifdef iswalpha
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswalpha(wint_t __wc) {return iswalpha(__wc);}
+#undef iswalpha
+inline _LIBCPP_INLINE_VISIBILITY int iswalpha(wint_t __wc) {return __libcpp_iswalpha(__wc);}
+#else  // iswalpha
+using ::iswalpha;
+#endif
+
+#ifdef iswblank
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswblank(wint_t __wc) {return iswblank(__wc);}
+#undef iswblank
+inline _LIBCPP_INLINE_VISIBILITY int iswblank(wint_t __wc) {return __libcpp_iswblank(__wc);}
+#else  // iswblank
+using ::iswblank;
+#endif
+
+#ifdef iswcntrl
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswcntrl(wint_t __wc) {return iswcntrl(__wc);}
+#undef iswcntrl
+inline _LIBCPP_INLINE_VISIBILITY int iswcntrl(wint_t __wc) {return __libcpp_iswcntrl(__wc);}
+#else  // iswcntrl
+using ::iswcntrl;
+#endif
+
+#ifdef iswdigit
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswdigit(wint_t __wc) {return iswdigit(__wc);}
+#undef iswdigit
+inline _LIBCPP_INLINE_VISIBILITY int iswdigit(wint_t __wc) {return __libcpp_iswdigit(__wc);}
+#else  // iswdigit
+using ::iswdigit;
+#endif
+
+#ifdef iswgraph
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswgraph(wint_t __wc) {return iswgraph(__wc);}
+#undef iswgraph
+inline _LIBCPP_INLINE_VISIBILITY int iswgraph(wint_t __wc) {return __libcpp_iswgraph(__wc);}
+#else  // iswgraph
+using ::iswgraph;
+#endif
+
+#ifdef iswlower
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswlower(wint_t __wc) {return iswlower(__wc);}
+#undef iswlower
+inline _LIBCPP_INLINE_VISIBILITY int iswlower(wint_t __wc) {return __libcpp_iswlower(__wc);}
+#else  // iswlower
+using ::iswlower;
+#endif
+
+#ifdef iswprint
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswprint(wint_t __wc) {return iswprint(__wc);}
+#undef iswprint
+inline _LIBCPP_INLINE_VISIBILITY int iswprint(wint_t __wc) {return __libcpp_iswprint(__wc);}
+#else  // iswprint
+using ::iswprint;
+#endif
+
+#ifdef iswpunct
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswpunct(wint_t __wc) {return iswpunct(__wc);}
+#undef iswpunct
+inline _LIBCPP_INLINE_VISIBILITY int iswpunct(wint_t __wc) {return __libcpp_iswpunct(__wc);}
+#else  // iswpunct
+using ::iswpunct;
+#endif
+
+#ifdef iswspace
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswspace(wint_t __wc) {return iswspace(__wc);}
+#undef iswspace
+inline _LIBCPP_INLINE_VISIBILITY int iswspace(wint_t __wc) {return __libcpp_iswspace(__wc);}
+#else  // iswspace
+using ::iswspace;
+#endif
+
+#ifdef iswupper
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswupper(wint_t __wc) {return iswupper(__wc);}
+#undef iswupper
+inline _LIBCPP_INLINE_VISIBILITY int iswupper(wint_t __wc) {return __libcpp_iswupper(__wc);}
+#else  // iswupper
+using ::iswupper;
+#endif
+
+#ifdef iswxdigit
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswxdigit(wint_t __wc) {return iswxdigit(__wc);}
+#undef iswxdigit
+inline _LIBCPP_INLINE_VISIBILITY int iswxdigit(wint_t __wc) {return __libcpp_iswxdigit(__wc);}
+#else  // iswxdigit
+using ::iswxdigit;
+#endif
+
+#ifdef iswctype
+inline _LIBCPP_INLINE_VISIBILITY int __libcpp_iswctype(wint_t __w, wctype_t __d) {return iswctype(__w, __d);}
+#undef iswctype
+inline _LIBCPP_INLINE_VISIBILITY int iswctype(wint_t __w, wctype_t __d) {return __libcpp_iswctype(__w, __d);}
+#else  // iswctype
+using ::iswctype;
+#endif
+
+#ifdef wctype
+inline _LIBCPP_INLINE_VISIBILITY wctype_t __libcpp_wctype(const char* __p) {return wctype(__p);}
+#undef wctype
+inline _LIBCPP_INLINE_VISIBILITY wctype_t wctype(const char* __p) {return __libcpp_wctype(__p);}
+#else  // wctype
+using ::wctype;
+#endif
+
+#ifdef towlower
+inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towlower(wint_t __wc) {return towlower(__wc);}
+#undef towlower
+inline _LIBCPP_INLINE_VISIBILITY wint_t towlower(wint_t __wc) {return __libcpp_towlower(__wc);}
+#else  // towlower
+using ::towlower;
+#endif
+
+#ifdef towupper
+inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towupper(wint_t __wc) {return towupper(__wc);}
+#undef towupper
+inline _LIBCPP_INLINE_VISIBILITY wint_t towupper(wint_t __wc) {return __libcpp_towupper(__wc);}
+#else  // towupper
+using ::towupper;
+#endif
+
+#ifdef towctrans
+inline _LIBCPP_INLINE_VISIBILITY wint_t __libcpp_towctrans(wint_t __wc, wctype_t __d) {return towctrans(__wc, __d);}
+#undef towctrans
+inline _LIBCPP_INLINE_VISIBILITY wint_t towctrans(wint_t __wc, wctype_t __d) {return __libcpp_towctrans(__wc, __d);}
+#else  // towctrans
+using ::towctrans;
+#endif
+
+#ifdef wctrans
+inline _LIBCPP_INLINE_VISIBILITY wctrans_t __libcpp_wctrans(const char* __p) {return wctrans(__p);}
+#undef wctrans
+inline _LIBCPP_INLINE_VISIBILITY wctrans_t wctrans(const char* __p) {return __libcpp_wctrans(__p);}
+#else  // wctrans
+using ::wctrans;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_CWCTYPE
diff --git a/include/c++/v1/cxxabi.h b/include/c++/v1/cxxabi.h
new file mode 100644
index 0000000..867ba72
--- /dev/null
+++ b/include/c++/v1/cxxabi.h
@@ -0,0 +1,187 @@
+//===--------------------------- cxxabi.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __CXXABI_H
+#define __CXXABI_H 
+
+/*
+ * This header provides the interface to the C++ ABI as defined at:
+ *       http://www.codesourcery.com/cxx-abi/
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define _LIBCPPABI_VERSION 1001
+#define LIBCXXABI_NORETURN  __attribute__((noreturn))
+
+// FIXME: This is also in unwind.h and libunwind.h, can we consolidate?
+#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
+    !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
+#define LIBCXXABI_ARM_EHABI 1
+#else
+#define LIBCXXABI_ARM_EHABI 0
+#endif
+
+#ifdef __cplusplus
+
+namespace std {
+    class type_info; // forward declaration
+}
+
+
+// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
+namespace __cxxabiv1 {  
+  extern "C"  {
+
+// 2.4.2 Allocating the Exception Object
+extern void * __cxa_allocate_exception(size_t thrown_size) throw();
+extern void __cxa_free_exception(void * thrown_exception) throw();
+
+// 2.4.3 Throwing the Exception Object
+extern LIBCXXABI_NORETURN void __cxa_throw(void * thrown_exception, 
+        std::type_info * tinfo, void (*dest)(void *));
+
+// 2.5.3 Exception Handlers
+extern void * __cxa_get_exception_ptr(void * exceptionObject) throw();
+extern void * __cxa_begin_catch(void * exceptionObject) throw();
+extern void __cxa_end_catch();
+#if LIBCXXABI_ARM_EHABI
+extern bool __cxa_begin_cleanup(void * exceptionObject) throw();
+extern void __cxa_end_cleanup();
+#endif
+extern std::type_info * __cxa_current_exception_type();
+
+// 2.5.4 Rethrowing Exceptions
+extern LIBCXXABI_NORETURN void __cxa_rethrow();
+
+
+
+// 2.6 Auxiliary Runtime APIs
+extern LIBCXXABI_NORETURN void __cxa_bad_cast(void);
+extern LIBCXXABI_NORETURN void __cxa_bad_typeid(void);
+
+
+
+// 3.2.6 Pure Virtual Function API
+extern LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
+
+// 3.2.7 Deleted Virtual Function API
+extern LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
+
+// 3.3.2 One-time Construction API
+#if __arm__
+extern int  __cxa_guard_acquire(uint32_t*);
+extern void __cxa_guard_release(uint32_t*);
+extern void __cxa_guard_abort(uint32_t*);
+#else
+extern int  __cxa_guard_acquire(uint64_t*);
+extern void __cxa_guard_release(uint64_t*);
+extern void __cxa_guard_abort(uint64_t*);
+#endif
+
+// 3.3.3 Array Construction and Destruction API
+extern void* __cxa_vec_new(size_t element_count, 
+                           size_t element_size, 
+                           size_t padding_size, 
+                           void (*constructor)(void*),
+                           void (*destructor)(void*) );
+
+extern void* __cxa_vec_new2(size_t element_count,
+                            size_t element_size, 
+                            size_t padding_size,
+                            void  (*constructor)(void*),
+                            void  (*destructor)(void*),
+                            void* (*alloc)(size_t), 
+                            void  (*dealloc)(void*) );
+
+extern void* __cxa_vec_new3(size_t element_count,
+                            size_t element_size, 
+                            size_t padding_size,
+                            void  (*constructor)(void*),
+                            void  (*destructor)(void*),
+                            void* (*alloc)(size_t), 
+                            void  (*dealloc)(void*, size_t) );
+  
+extern void __cxa_vec_ctor(void*  array_address, 
+                           size_t element_count,
+                           size_t element_size, 
+                           void (*constructor)(void*),
+                           void (*destructor)(void*) );
+
+
+extern void __cxa_vec_dtor(void*  array_address, 
+                           size_t element_count,
+                           size_t element_size, 
+                           void (*destructor)(void*) );
+
+
+extern void __cxa_vec_cleanup(void* array_address, 
+                             size_t element_count,
+                             size_t element_size, 
+                             void  (*destructor)(void*) );
+
+
+extern void __cxa_vec_delete(void*  array_address, 
+                             size_t element_size, 
+                             size_t padding_size, 
+                             void  (*destructor)(void*) );
+
+
+extern void __cxa_vec_delete2(void* array_address, 
+                             size_t element_size, 
+                             size_t padding_size, 
+                             void  (*destructor)(void*),
+                             void  (*dealloc)(void*) );
+  
+
+extern void __cxa_vec_delete3(void* __array_address, 
+                             size_t element_size, 
+                             size_t padding_size, 
+                             void  (*destructor)(void*),
+                             void  (*dealloc) (void*, size_t));
+
+
+extern void __cxa_vec_cctor(void*  dest_array, 
+                            void*  src_array, 
+                            size_t element_count, 
+                            size_t element_size, 
+                            void  (*constructor) (void*, void*), 
+                            void  (*destructor)(void*) );
+
+
+// 3.3.5.3 Runtime API
+extern int __cxa_atexit(void (*f)(void*), void* p, void* d);
+extern int __cxa_finalize(void*);
+
+
+// 3.4 Demangler API
+extern char* __cxa_demangle(const char* mangled_name, 
+                            char*       output_buffer,
+                            size_t*     length, 
+                            int*        status);
+
+// Apple additions to support C++ 0x exception_ptr class
+// These are primitives to wrap a smart pointer around an exception object
+extern void * __cxa_current_primary_exception() throw();
+extern void __cxa_rethrow_primary_exception(void* primary_exception);
+extern void __cxa_increment_exception_refcount(void* primary_exception) throw();
+extern void __cxa_decrement_exception_refcount(void* primary_exception) throw();
+
+// Apple addition to support std::uncaught_exception()
+extern bool __cxa_uncaught_exception() throw();
+
+  } // extern "C"
+} // namespace __cxxabiv1
+
+namespace abi = __cxxabiv1;
+
+#endif // __cplusplus
+
+#endif // __CXXABI_H 
diff --git a/include/c++/v1/deque b/include/c++/v1/deque
new file mode 100644
index 0000000..9b256b7
--- /dev/null
+++ b/include/c++/v1/deque
@@ -0,0 +1,2873 @@
+// -*- C++ -*-
+//===---------------------------- deque -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_DEQUE
+#define _LIBCPP_DEQUE
+
+/*
+    deque synopsis
+
+namespace std
+{
+
+template <class T, class Allocator = allocator<T> >
+class deque
+{
+public:
+    // types:
+    typedef T value_type;
+    typedef Allocator allocator_type;
+
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    // construct/copy/destroy:
+    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit deque(const allocator_type& a);
+    explicit deque(size_type n);
+    explicit deque(size_type n, const allocator_type& a); // C++14
+    deque(size_type n, const value_type& v);
+    deque(size_type n, const value_type& v, const allocator_type& a);
+    template <class InputIterator>
+        deque(InputIterator f, InputIterator l);
+    template <class InputIterator>
+        deque(InputIterator f, InputIterator l, const allocator_type& a);
+    deque(const deque& c);
+    deque(deque&& c)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
+    deque(const deque& c, const allocator_type& a);
+    deque(deque&& c, const allocator_type& a);
+    ~deque();
+
+    deque& operator=(const deque& c);
+    deque& operator=(deque&& c)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    deque& operator=(initializer_list<value_type> il);
+
+    template <class InputIterator>
+        void assign(InputIterator f, InputIterator l);
+    void assign(size_type n, const value_type& v);
+    void assign(initializer_list<value_type> il);
+
+    allocator_type get_allocator() const noexcept;
+
+    // iterators:
+
+    iterator       begin() noexcept;
+    const_iterator begin() const noexcept;
+    iterator       end() noexcept;
+    const_iterator end() const noexcept;
+
+    reverse_iterator       rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+    reverse_iterator       rend() noexcept;
+    const_reverse_iterator rend() const noexcept;
+
+    const_iterator         cbegin() const noexcept;
+    const_iterator         cend() const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend() const noexcept;
+
+    // capacity:
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+    void resize(size_type n);
+    void resize(size_type n, const value_type& v);
+    void shrink_to_fit();
+    bool empty() const noexcept;
+
+    // element access:
+    reference operator[](size_type i);
+    const_reference operator[](size_type i) const;
+    reference at(size_type i);
+    const_reference at(size_type i) const;
+    reference front();
+    const_reference front() const;
+    reference back();
+    const_reference back() const;
+
+    // modifiers:
+    void push_front(const value_type& v);
+    void push_front(value_type&& v);
+    void push_back(const value_type& v);
+    void push_back(value_type&& v);
+    template <class... Args> void emplace_front(Args&&... args);
+    template <class... Args> void emplace_back(Args&&... args);
+    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
+    iterator insert(const_iterator p, const value_type& v);
+    iterator insert(const_iterator p, value_type&& v);
+    iterator insert(const_iterator p, size_type n, const value_type& v);
+    template <class InputIterator>
+        iterator insert (const_iterator p, InputIterator f, InputIterator l);
+    iterator insert(const_iterator p, initializer_list<value_type> il);
+    void pop_front();
+    void pop_back();
+    iterator erase(const_iterator p);
+    iterator erase(const_iterator f, const_iterator l);
+    void swap(deque& c)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value);
+    void clear() noexcept;
+};
+
+template <class T, class Allocator>
+    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+template <class T, class Allocator>
+    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+template <class T, class Allocator>
+    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+template <class T, class Allocator>
+    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+template <class T, class Allocator>
+    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+template <class T, class Allocator>
+    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
+
+// specialized algorithms:
+template <class T, class Allocator>
+    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
+         noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include <__config>
+#include <__split_buffer>
+#include <type_traits>
+#include <initializer_list>
+#include <iterator>
+#include <algorithm>
+#include <stdexcept>
+
+#include <__undef_min_max>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Allocator> class __deque_base;
+
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
+          class _DiffType, _DiffType _BlockSize>
+class _LIBCPP_TYPE_VIS_ONLY __deque_iterator;
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy(_RAIter __f,
+     _RAIter __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     _OutputIterator __r);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy_backward(_RAIter __f,
+              _RAIter __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              _OutputIterator __r);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move(_RAIter __f,
+     _RAIter __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     _OutputIterator __r);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move_backward(_RAIter __f,
+              _RAIter __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              _OutputIterator __r);
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
+          class _DiffType, _DiffType _BlockSize>
+class _LIBCPP_TYPE_VIS_ONLY __deque_iterator
+{
+    typedef _MapPointer __map_iterator;
+public:
+    typedef _Pointer  pointer;
+    typedef _DiffType difference_type;
+private:
+    __map_iterator __m_iter_;
+    pointer        __ptr_;
+
+    static const difference_type __block_size = _BlockSize;
+public:
+    typedef _ValueType                  value_type;
+    typedef random_access_iterator_tag  iterator_category;
+    typedef _Reference                  reference;
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+     : __m_iter_(nullptr), __ptr_(nullptr)
+#endif
+     {}
+
+    template <class _Pp, class _Rp, class _MP>
+    _LIBCPP_INLINE_VISIBILITY
+    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, __block_size>& __it,
+                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
+        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *__ptr_;}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return __ptr_;}
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator++()
+    {
+        if (++__ptr_ - *__m_iter_ == __block_size)
+        {
+            ++__m_iter_;
+            __ptr_ = *__m_iter_;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator++(int)
+    {
+        __deque_iterator __tmp = *this;
+        ++(*this);
+        return __tmp;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator--()
+    {
+        if (__ptr_ == *__m_iter_)
+        {
+            --__m_iter_;
+            __ptr_ = *__m_iter_ + __block_size;
+        }
+        --__ptr_;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator--(int)
+    {
+        __deque_iterator __tmp = *this;
+        --(*this);
+        return __tmp;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator+=(difference_type __n)
+    {
+        if (__n != 0)
+        {
+            __n += __ptr_ - *__m_iter_;
+            if (__n > 0)
+            {
+                __m_iter_ += __n / __block_size;
+                __ptr_ = *__m_iter_ + __n % __block_size;
+            }
+            else // (__n < 0)
+            {
+                difference_type __z = __block_size - 1 - __n;
+                __m_iter_ -= __z / __block_size;
+                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
+            }
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator& operator-=(difference_type __n)
+    {
+        return *this += -__n;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator+(difference_type __n) const
+    {
+        __deque_iterator __t(*this);
+        __t += __n;
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator operator-(difference_type __n) const
+    {
+        __deque_iterator __t(*this);
+        __t -= __n;
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
+        {return __it + __n;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
+    {
+        if (__x != __y)
+            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
+                 + (__x.__ptr_ - *__x.__m_iter_)
+                 - (__y.__ptr_ - *__y.__m_iter_);
+        return 0;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
+        {return *(*this + __n);}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return __x.__ptr_ == __y.__ptr_;}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return !(__x == __y);}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return __x.__m_iter_ < __y.__m_iter_ ||
+               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return __y < __x;}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return !(__y < __x);}
+
+    _LIBCPP_INLINE_VISIBILITY friend
+        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
+        {return !(__x < __y);}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
+        : __m_iter_(__m), __ptr_(__p) {}
+
+    template <class _Tp, class _Ap> friend class __deque_base;
+    template <class _Tp, class _Ap> friend class _LIBCPP_TYPE_VIS_ONLY deque;
+    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
+        friend class _LIBCPP_TYPE_VIS_ONLY __deque_iterator;
+
+    template <class _RAIter,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    copy(_RAIter __f,
+         _RAIter __l,
+         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _OutputIterator>
+    friend
+    _OutputIterator
+    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+         _OutputIterator __r);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+    template <class _RAIter,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    copy_backward(_RAIter __f,
+                  _RAIter __l,
+                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _OutputIterator>
+    friend
+    _OutputIterator
+    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+                  _OutputIterator __r);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+    template <class _RAIter,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    move(_RAIter __f,
+         _RAIter __l,
+         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+         typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _OutputIterator>
+    friend
+    _OutputIterator
+    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+         _OutputIterator __r);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+         __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+         __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+
+    template <class _RAIter,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    move_backward(_RAIter __f,
+                  _RAIter __l,
+                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+                  typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _OutputIterator>
+    friend
+    _OutputIterator
+    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+                  _OutputIterator __r);
+
+    template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+              class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+    friend
+    __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+    move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+                  __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+                  __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r);
+};
+
+// copy
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy(_RAIter __f,
+     _RAIter __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
+{
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    while (__f != __l)
+    {
+        pointer __rb = __r.__ptr_;
+        pointer __re = *__r.__m_iter_ + _B2;
+        difference_type __bs = __re - __rb;
+        difference_type __n = __l - __f;
+        _RAIter __m = __l;
+        if (__n > __bs)
+        {
+            __n = __bs;
+            __m = __f + __n;
+        }
+        _VSTD::copy(__f, __m, __rb);
+        __f = __m;
+        __r += __n;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     _OutputIterator __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + _B1;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        __r = _VSTD::copy(__fb, __fe, __r);
+        __n -= __bs;
+        __f += __bs;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + _B1;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        __r = _VSTD::copy(__fb, __fe, __r);
+        __n -= __bs;
+        __f += __bs;
+    }
+    return __r;
+}
+
+// copy_backward
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy_backward(_RAIter __f,
+              _RAIter __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
+{
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    while (__f != __l)
+    {
+        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
+        pointer __rb = *__rp.__m_iter_;
+        pointer __re = __rp.__ptr_ + 1;
+        difference_type __bs = __re - __rb;
+        difference_type __n = __l - __f;
+        _RAIter __m = __f;
+        if (__n > __bs)
+        {
+            __n = __bs;
+            __m = __l - __n;
+        }
+        _VSTD::copy_backward(__m, __l, __re);
+        __l = __m;
+        __r -= __n;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              _OutputIterator __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        __r = _VSTD::copy_backward(__lb, __le, __r);
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+copy_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        __r = _VSTD::copy_backward(__lb, __le, __r);
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+    return __r;
+}
+
+// move
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move(_RAIter __f,
+     _RAIter __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+     typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
+{
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    while (__f != __l)
+    {
+        pointer __rb = __r.__ptr_;
+        pointer __re = *__r.__m_iter_ + _B2;
+        difference_type __bs = __re - __rb;
+        difference_type __n = __l - __f;
+        _RAIter __m = __l;
+        if (__n > __bs)
+        {
+            __n = __bs;
+            __m = __f + __n;
+        }
+        _VSTD::move(__f, __m, __rb);
+        __f = __m;
+        __r += __n;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     _OutputIterator __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + _B1;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        __r = _VSTD::move(__fb, __fe, __r);
+        __n -= __bs;
+        __f += __bs;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+     __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+     __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + _B1;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        __r = _VSTD::move(__fb, __fe, __r);
+        __n -= __bs;
+        __f += __bs;
+    }
+    return __r;
+}
+
+// move_backward
+
+template <class _RAIter,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move_backward(_RAIter __f,
+              _RAIter __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r,
+              typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
+{
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type;
+    typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer;
+    while (__f != __l)
+    {
+        __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __rp = _VSTD::prev(__r);
+        pointer __rb = *__rp.__m_iter_;
+        pointer __re = __rp.__ptr_ + 1;
+        difference_type __bs = __re - __rb;
+        difference_type __n = __l - __f;
+        _RAIter __m = __f;
+        if (__n > __bs)
+        {
+            __n = __bs;
+            __m = __l - __n;
+        }
+        _VSTD::move_backward(__m, __l, __re);
+        __l = __m;
+        __r -= __n;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _OutputIterator>
+_OutputIterator
+move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              _OutputIterator __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        __r = _VSTD::move_backward(__lb, __le, __r);
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+    return __r;
+}
+
+template <class _V1, class _P1, class _R1, class _M1, class _D1, _D1 _B1,
+          class _V2, class _P2, class _R2, class _M2, class _D2, _D2 _B2>
+__deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>
+move_backward(__deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __f,
+              __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1> __l,
+              __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r)
+{
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::difference_type difference_type;
+    typedef typename __deque_iterator<_V1, _P1, _R1, _M1, _D1, _B1>::pointer pointer;
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        __r = _VSTD::move_backward(__lb, __le, __r);
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+    return __r;
+}
+
+template <bool>
+class __deque_base_common
+{
+protected:
+    void __throw_length_error() const;
+    void __throw_out_of_range() const;
+};
+
+template <bool __b>
+void
+__deque_base_common<__b>::__throw_length_error() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw length_error("deque");
+#endif
+}
+
+template <bool __b>
+void
+__deque_base_common<__b>::__throw_out_of_range() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw out_of_range("deque");
+#endif
+}
+
+template <class _Tp, class _Allocator>
+class __deque_base
+    : protected __deque_base_common<true>
+{
+    __deque_base(const __deque_base& __c);
+    __deque_base& operator=(const __deque_base& __c);
+protected:
+    typedef _Tp                                      value_type;
+    typedef _Allocator                               allocator_type;
+    typedef allocator_traits<allocator_type>         __alloc_traits;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+
+    static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
+
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<pointer>
+#else
+                rebind_alloc<pointer>::other
+#endif
+                                                         __pointer_allocator;
+    typedef allocator_traits<__pointer_allocator>        __map_traits;
+    typedef typename __map_traits::pointer               __map_pointer;
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<const_pointer>
+#else
+                rebind_alloc<const_pointer>::other
+#endif
+                                                         __const_pointer_allocator;
+    typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
+    typedef __split_buffer<pointer, __pointer_allocator> __map;
+
+    typedef __deque_iterator<value_type, pointer, reference, __map_pointer,
+                             difference_type, __block_size>    iterator;
+    typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
+                             difference_type, __block_size>    const_iterator;
+
+    __map __map_;
+    size_type __start_;
+    __compressed_pair<size_type, allocator_type> __size_;
+
+    iterator       begin() _NOEXCEPT;
+    const_iterator begin() const _NOEXCEPT;
+    iterator       end() _NOEXCEPT;
+    const_iterator end() const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY size_type&            size()          {return __size_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    const size_type& size() const _NOEXCEPT {return __size_.first();}
+    _LIBCPP_INLINE_VISIBILITY allocator_type&       __alloc()       {return __size_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const allocator_type& __alloc() const _NOEXCEPT {return __size_.second();}
+
+    __deque_base()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    explicit __deque_base(const allocator_type& __a);
+public:
+    ~__deque_base();
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    __deque_base(__deque_base&& __c)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+    __deque_base(__deque_base&& __c, const allocator_type& __a);
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void swap(__deque_base& __c)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value);
+protected:
+    void clear() _NOEXCEPT;
+
+    bool __invariants() const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign(__deque_base& __c)
+        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+                   is_nothrow_move_assignable<allocator_type>::value)
+    {
+        __map_ = _VSTD::move(__c.__map_);
+        __start_ = __c.__start_;
+        size() = __c.size();
+        __move_assign_alloc(__c);
+        __c.__start_ = __c.size() = 0;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__deque_base& __c)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_move_assignment::value ||
+                   is_nothrow_move_assignable<allocator_type>::value)
+        {__move_assign_alloc(__c, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_move_assignment::value>());}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__deque_base& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            __alloc() = _VSTD::move(__c.__alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_swap::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type&, allocator_type&, false_type)
+        _NOEXCEPT
+        {}
+};
+
+template <class _Tp, class _Allocator>
+bool
+__deque_base<_Tp, _Allocator>::__invariants() const
+{
+    if (!__map_.__invariants())
+        return false;
+    if (__map_.size() >= size_type(-1) / __block_size)
+        return false;
+    for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end();
+         __i != __e; ++__i)
+        if (*__i == nullptr)
+            return false;
+    if (__map_.size() != 0)
+    {
+        if (size() >= __map_.size() * __block_size)
+            return false;
+        if (__start_ >= __map_.size() * __block_size - size())
+            return false;
+    }
+    else
+    {
+        if (size() != 0)
+            return false;
+        if (__start_ != 0)
+            return false;
+    }
+    return true;
+}
+
+template <class _Tp, class _Allocator>
+typename __deque_base<_Tp, _Allocator>::iterator
+__deque_base<_Tp, _Allocator>::begin() _NOEXCEPT
+{
+    __map_pointer __mp = __map_.begin() + __start_ / __block_size;
+    return iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
+}
+
+template <class _Tp, class _Allocator>
+typename __deque_base<_Tp, _Allocator>::const_iterator
+__deque_base<_Tp, _Allocator>::begin() const _NOEXCEPT
+{
+    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __start_ / __block_size);
+    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __start_ % __block_size);
+}
+
+template <class _Tp, class _Allocator>
+typename __deque_base<_Tp, _Allocator>::iterator
+__deque_base<_Tp, _Allocator>::end() _NOEXCEPT
+{
+    size_type __p = size() + __start_;
+    __map_pointer __mp = __map_.begin() + __p / __block_size;
+    return iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
+}
+
+template <class _Tp, class _Allocator>
+typename __deque_base<_Tp, _Allocator>::const_iterator
+__deque_base<_Tp, _Allocator>::end() const _NOEXCEPT
+{
+    size_type __p = size() + __start_;
+    __map_const_pointer __mp = static_cast<__map_const_pointer>(__map_.begin() + __p / __block_size);
+    return const_iterator(__mp, __map_.empty() ? 0 : *__mp + __p % __block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__deque_base<_Tp, _Allocator>::__deque_base()
+    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+    : __start_(0), __size_(0) {}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__deque_base<_Tp, _Allocator>::__deque_base(const allocator_type& __a)
+    : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {}
+
+template <class _Tp, class _Allocator>
+__deque_base<_Tp, _Allocator>::~__deque_base()
+{
+    clear();
+    typename __map::iterator __i = __map_.begin();
+    typename __map::iterator __e = __map_.end();
+    for (; __i != __e; ++__i)
+        __alloc_traits::deallocate(__alloc(), *__i, __block_size);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c)
+    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+    : __map_(_VSTD::move(__c.__map_)),
+      __start_(_VSTD::move(__c.__start_)),
+      __size_(_VSTD::move(__c.__size_))
+{
+    __c.__start_ = 0;
+    __c.size() = 0;
+}
+
+template <class _Tp, class _Allocator>
+__deque_base<_Tp, _Allocator>::__deque_base(__deque_base&& __c, const allocator_type& __a)
+    : __map_(_VSTD::move(__c.__map_), __pointer_allocator(__a)),
+      __start_(_VSTD::move(__c.__start_)),
+      __size_(_VSTD::move(__c.size()), __a)
+{
+    if (__a == __c.__alloc())
+    {
+        __c.__start_ = 0;
+        __c.size() = 0;
+    }
+    else
+    {
+        __map_.clear();
+        __start_ = 0;
+        size() = 0;
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
+                   __is_nothrow_swappable<allocator_type>::value)
+{
+    __map_.swap(__c.__map_);
+    _VSTD::swap(__start_, __c.__start_);
+    _VSTD::swap(size(), __c.size());
+    __swap_alloc(__alloc(), __c.__alloc());
+}
+
+template <class _Tp, class _Allocator>
+void
+__deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
+{
+    allocator_type& __a = __alloc();
+    for (iterator __i = begin(), __e = end(); __i != __e; ++__i)
+        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
+    size() = 0;
+    while (__map_.size() > 2)
+    {
+        __alloc_traits::deallocate(__a, __map_.front(), __block_size);
+        __map_.pop_front();
+    }
+    switch (__map_.size())
+    {
+    case 1:
+        __start_ = __block_size / 2;
+        break;
+    case 2:
+        __start_ = __block_size;
+        break;
+    }
+}
+
+template <class _Tp, class _Allocator = allocator<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY deque
+    : private __deque_base<_Tp, _Allocator>
+{
+public:
+    // types:
+
+    typedef _Tp value_type;
+    typedef _Allocator allocator_type;
+
+    typedef __deque_base<value_type, allocator_type> __base;
+
+    typedef typename __base::__alloc_traits        __alloc_traits;
+    typedef typename __base::reference             reference;
+    typedef typename __base::const_reference       const_reference;
+    typedef typename __base::iterator              iterator;
+    typedef typename __base::const_iterator        const_iterator;
+    typedef typename __base::size_type             size_type;
+    typedef typename __base::difference_type       difference_type;
+
+    typedef typename __base::pointer               pointer;
+    typedef typename __base::const_pointer         const_pointer;
+    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    deque()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+        {}
+    _LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
+    explicit deque(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit deque(size_type __n, const _Allocator& __a);
+#endif
+    deque(size_type __n, const value_type& __v);
+    deque(size_type __n, const value_type& __v, const allocator_type& __a);
+    template <class _InputIter>
+        deque(_InputIter __f, _InputIter __l,
+              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
+    template <class _InputIter>
+        deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
+              typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0);
+    deque(const deque& __c);
+    deque(const deque& __c, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    deque(initializer_list<value_type> __il);
+    deque(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    deque& operator=(const deque& __c);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
+#endif   // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
+    deque(deque&& __c, const allocator_type& __a);
+    deque& operator=(deque&& __c)
+        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+                   is_nothrow_move_assignable<allocator_type>::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class _InputIter>
+        void assign(_InputIter __f, _InputIter __l,
+                    typename enable_if<__is_input_iterator<_InputIter>::value &&
+                                      !__is_random_access_iterator<_InputIter>::value>::type* = 0);
+    template <class _RAIter>
+        void assign(_RAIter __f, _RAIter __l,
+                    typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0);
+    void assign(size_type __n, const value_type& __v);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void assign(initializer_list<value_type> __il) {assign(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    allocator_type get_allocator() const _NOEXCEPT;
+
+    // iterators:
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT       {return __base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return __base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT         {return __base::end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()   const _NOEXCEPT {return __base::end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator       rbegin() _NOEXCEPT
+        {return       reverse_iterator(__base::end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(__base::end());}
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator       rend() _NOEXCEPT
+        {return       reverse_iterator(__base::begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend()   const _NOEXCEPT
+        {return const_reverse_iterator(__base::begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cbegin()  const _NOEXCEPT
+        {return __base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cend()    const _NOEXCEPT
+        {return __base::end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT
+        {return const_reverse_iterator(__base::end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend()   const _NOEXCEPT
+        {return const_reverse_iterator(__base::begin());}
+
+    // capacity:
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT {return __base::size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT
+        {return __alloc_traits::max_size(__base::__alloc());}
+    void resize(size_type __n);
+    void resize(size_type __n, const value_type& __v);
+    void shrink_to_fit() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT {return __base::size() == 0;}
+
+    // element access:
+    reference operator[](size_type __i);
+    const_reference operator[](size_type __i) const;
+    reference at(size_type __i);
+    const_reference at(size_type __i) const;
+    reference front();
+    const_reference front() const;
+    reference back();
+    const_reference back() const;
+
+    // 23.2.2.3 modifiers:
+    void push_front(const value_type& __v);
+    void push_back(const value_type& __v);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args> void emplace_front(_Args&&... __args);
+    template <class... _Args> void emplace_back(_Args&&... __args);
+    template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+    void push_front(value_type&& __v);
+    void push_back(value_type&& __v);
+    iterator insert(const_iterator __p, value_type&& __v);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    iterator insert(const_iterator __p, const value_type& __v);
+    iterator insert(const_iterator __p, size_type __n, const value_type& __v);
+    template <class _InputIter>
+        iterator insert (const_iterator __p, _InputIter __f, _InputIter __l,
+                         typename enable_if<__is_input_iterator<_InputIter>::value
+                                         &&!__is_bidirectional_iterator<_InputIter>::value>::type* = 0);
+    template <class _BiIter>
+        iterator insert (const_iterator __p, _BiIter __f, _BiIter __l,
+                         typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, initializer_list<value_type> __il)
+        {return insert(__p, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    void pop_front();
+    void pop_back();
+    iterator erase(const_iterator __p);
+    iterator erase(const_iterator __f, const_iterator __l);
+
+    void swap(deque& __c)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value);
+    void clear() _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __invariants() const {return __base::__invariants();}
+private:
+    typedef typename __base::__map_const_pointer __map_const_pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __recommend_blocks(size_type __n)
+    {
+        return __n / __base::__block_size + (__n % __base::__block_size != 0);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __capacity() const
+    {
+        return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __front_spare() const
+    {
+        return __base::__start_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __back_spare() const
+    {
+        return __capacity() - (__base::__start_ + __base::size());
+    }
+
+    template <class _InpIter>
+        void __append(_InpIter __f, _InpIter __l,
+                 typename enable_if<__is_input_iterator<_InpIter>::value &&
+                                   !__is_forward_iterator<_InpIter>::value>::type* = 0);
+    template <class _ForIter>
+        void __append(_ForIter __f, _ForIter __l,
+                      typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0);
+    void __append(size_type __n);
+    void __append(size_type __n, const value_type& __v);
+    void __erase_to_end(const_iterator __f);
+    void __add_front_capacity();
+    void __add_front_capacity(size_type __n);
+    void __add_back_capacity();
+    void __add_back_capacity(size_type __n);
+    iterator __move_and_check(iterator __f, iterator __l, iterator __r,
+                              const_pointer& __vt);
+    iterator __move_backward_and_check(iterator __f, iterator __l, iterator __r,
+                                       const_pointer& __vt);
+    void __move_construct_and_check(iterator __f, iterator __l,
+                                    iterator __r, const_pointer& __vt);
+    void __move_construct_backward_and_check(iterator __f, iterator __l,
+                                             iterator __r, const_pointer& __vt);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const deque& __c)
+        {__copy_assign_alloc(__c, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const deque& __c, true_type)
+        {
+            if (__base::__alloc() != __c.__alloc())
+            {
+                clear();
+                shrink_to_fit();
+            }
+            __base::__alloc() = __c.__alloc();
+            __base::__map_.__alloc() = __c.__map_.__alloc();
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const deque&, false_type)
+        {}
+
+    void __move_assign(deque& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+    void __move_assign(deque& __c, false_type);
+};
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(size_type __n)
+{
+    if (__n > 0)
+        __append(__n);
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
+    : __base(__a)
+{
+    if (__n > 0)
+        __append(__n);
+}
+#endif
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
+{
+    if (__n > 0)
+        __append(__n, __v);
+}
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
+    : __base(__a)
+{
+    if (__n > 0)
+        __append(__n, __v);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIter>
+deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
+              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
+{
+    __append(__f, __l);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIter>
+deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
+              typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
+    : __base(__a)
+{
+    __append(__f, __l);
+}
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(const deque& __c)
+    : __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
+{
+    __append(__c.begin(), __c.end());
+}
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
+    : __base(__a)
+{
+    __append(__c.begin(), __c.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
+{
+    __append(__il.begin(), __il.end());
+}
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
+    : __base(__a)
+{
+    __append(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Allocator>
+deque<_Tp, _Allocator>&
+deque<_Tp, _Allocator>::operator=(const deque& __c)
+{
+    if (this != &__c)
+    {
+        __copy_assign_alloc(__c);
+        assign(__c.begin(), __c.end());
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+deque<_Tp, _Allocator>::deque(deque&& __c)
+    _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
+    : __base(_VSTD::move(__c))
+{
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
+    : __base(_VSTD::move(__c), __a)
+{
+    if (__a != __c.__alloc())
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+deque<_Tp, _Allocator>&
+deque<_Tp, _Allocator>::operator=(deque&& __c)
+        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+                   is_nothrow_move_assignable<allocator_type>::value)
+{
+    __move_assign(__c, integral_constant<bool,
+          __alloc_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
+{
+    if (__base::__alloc() != __c.__alloc())
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+    else
+        __move_assign(__c, true_type());
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+{
+    clear();
+    shrink_to_fit();
+    __base::__move_assign(__c);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+template <class _InputIter>
+void
+deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l,
+                               typename enable_if<__is_input_iterator<_InputIter>::value &&
+                                                 !__is_random_access_iterator<_InputIter>::value>::type*)
+{
+    iterator __i = __base::begin();
+    iterator __e = __base::end();
+    for (; __f != __l && __i != __e; ++__f, ++__i)
+        *__i = *__f;
+    if (__f != __l)
+        __append(__f, __l);
+    else
+        __erase_to_end(__i);
+}
+
+template <class _Tp, class _Allocator>
+template <class _RAIter>
+void
+deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l,
+                               typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*)
+{
+    if (static_cast<size_type>(__l - __f) > __base::size())
+    {
+        _RAIter __m = __f + __base::size();
+        _VSTD::copy(__f, __m, __base::begin());
+        __append(__m, __l);
+    }
+    else
+        __erase_to_end(_VSTD::copy(__f, __l, __base::begin()));
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::assign(size_type __n, const value_type& __v)
+{
+    if (__n > __base::size())
+    {
+        _VSTD::fill_n(__base::begin(), __base::size(), __v);
+        __n -= __base::size();
+        __append(__n, __v);
+    }
+    else
+        __erase_to_end(_VSTD::fill_n(__base::begin(), __n, __v));
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+_Allocator
+deque<_Tp, _Allocator>::get_allocator() const _NOEXCEPT
+{
+    return __base::__alloc();
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::resize(size_type __n)
+{
+    if (__n > __base::size())
+        __append(__n - __base::size());
+    else if (__n < __base::size())
+        __erase_to_end(__base::begin() + __n);
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
+{
+    if (__n > __base::size())
+        __append(__n - __base::size(), __v);
+    else if (__n < __base::size())
+        __erase_to_end(__base::begin() + __n);
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
+{
+    allocator_type& __a = __base::__alloc();
+    if (empty())
+    {
+        while (__base::__map_.size() > 0)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+            __base::__map_.pop_back();
+        }
+        __base::__start_ = 0;
+    }
+    else
+    {
+        if (__front_spare() >= __base::__block_size)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
+            __base::__map_.pop_front();
+            __base::__start_ -= __base::__block_size;
+        }
+        if (__back_spare() >= __base::__block_size)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+            __base::__map_.pop_back();
+        }
+    }
+    __base::__map_.shrink_to_fit();
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::reference
+deque<_Tp, _Allocator>::operator[](size_type __i)
+{
+    size_type __p = __base::__start_ + __i;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::const_reference
+deque<_Tp, _Allocator>::operator[](size_type __i) const
+{
+    size_type __p = __base::__start_ + __i;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::reference
+deque<_Tp, _Allocator>::at(size_type __i)
+{
+    if (__i >= __base::size())
+        __base::__throw_out_of_range();
+    size_type __p = __base::__start_ + __i;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::const_reference
+deque<_Tp, _Allocator>::at(size_type __i) const
+{
+    if (__i >= __base::size())
+        __base::__throw_out_of_range();
+    size_type __p = __base::__start_ + __i;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::reference
+deque<_Tp, _Allocator>::front()
+{
+    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
+                                      + __base::__start_ % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::const_reference
+deque<_Tp, _Allocator>::front() const
+{
+    return *(*(__base::__map_.begin() + __base::__start_ / __base::__block_size)
+                                      + __base::__start_ % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::reference
+deque<_Tp, _Allocator>::back()
+{
+    size_type __p = __base::size() + __base::__start_ - 1;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename deque<_Tp, _Allocator>::const_reference
+deque<_Tp, _Allocator>::back() const
+{
+    size_type __p = __base::size() + __base::__start_ - 1;
+    return *(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size);
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::push_back(const value_type& __v)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__back_spare() == 0)
+        __add_back_capacity();
+    // __back_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
+    ++__base::size();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::push_back(value_type&& __v)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__back_spare() == 0)
+        __add_back_capacity();
+    // __back_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
+    ++__base::size();
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+void
+deque<_Tp, _Allocator>::emplace_back(_Args&&... __args)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__back_spare() == 0)
+        __add_back_capacity();
+    // __back_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
+    ++__base::size();
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::push_front(const value_type& __v)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__front_spare() == 0)
+        __add_front_capacity();
+    // __front_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
+    --__base::__start_;
+    ++__base::size();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::push_front(value_type&& __v)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__front_spare() == 0)
+        __add_front_capacity();
+    // __front_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
+    --__base::__start_;
+    ++__base::size();
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+void
+deque<_Tp, _Allocator>::emplace_front(_Args&&... __args)
+{
+    allocator_type& __a = __base::__alloc();
+    if (__front_spare() == 0)
+        __add_front_capacity();
+    // __front_spare() >= 1
+    __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
+    --__base::__start_;
+    ++__base::size();
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v)
+{
+    size_type __pos = __p - __base::begin();
+    size_type __to_end = __base::size() - __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < __to_end)
+    {   // insert by shifting things backward
+        if (__front_spare() == 0)
+            __add_front_capacity();
+        // __front_spare() >= 1
+        if (__pos == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), __v);
+            --__base::__start_;
+            ++__base::size();
+        }
+        else
+        {
+            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
+            iterator __b = __base::begin();
+            iterator __bm1 = _VSTD::prev(__b);
+            if (__vt == pointer_traits<const_pointer>::pointer_to(*__b))
+                __vt = pointer_traits<const_pointer>::pointer_to(*__bm1);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
+            --__base::__start_;
+            ++__base::size();
+            if (__pos > 1)
+                __b = __move_and_check(_VSTD::next(__b), __b + __pos, __b, __vt);
+            *__b = *__vt;
+        }
+    }
+    else
+    {   // insert by shifting things forward
+        if (__back_spare() == 0)
+            __add_back_capacity();
+        // __back_capacity >= 1
+        size_type __de = __base::size() - __pos;
+        if (__de == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), __v);
+            ++__base::size();
+        }
+        else
+        {
+            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
+            iterator __e = __base::end();
+            iterator __em1 = _VSTD::prev(__e);
+            if (__vt == pointer_traits<const_pointer>::pointer_to(*__em1))
+                __vt = pointer_traits<const_pointer>::pointer_to(*__e);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
+            ++__base::size();
+            if (__de > 1)
+                __e = __move_backward_and_check(__e - __de, __em1, __e, __vt);
+            *--__e = *__vt;
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v)
+{
+    size_type __pos = __p - __base::begin();
+    size_type __to_end = __base::size() - __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < __to_end)
+    {   // insert by shifting things backward
+        if (__front_spare() == 0)
+            __add_front_capacity();
+        // __front_spare() >= 1
+        if (__pos == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::move(__v));
+            --__base::__start_;
+            ++__base::size();
+        }
+        else
+        {
+            iterator __b = __base::begin();
+            iterator __bm1 = _VSTD::prev(__b);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
+            --__base::__start_;
+            ++__base::size();
+            if (__pos > 1)
+                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
+            *__b = _VSTD::move(__v);
+        }
+    }
+    else
+    {   // insert by shifting things forward
+        if (__back_spare() == 0)
+            __add_back_capacity();
+        // __back_capacity >= 1
+        size_type __de = __base::size() - __pos;
+        if (__de == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::move(__v));
+            ++__base::size();
+        }
+        else
+        {
+            iterator __e = __base::end();
+            iterator __em1 = _VSTD::prev(__e);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
+            ++__base::size();
+            if (__de > 1)
+                __e = _VSTD::move_backward(__e - __de, __em1, __e);
+            *--__e = _VSTD::move(__v);
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
+{
+    size_type __pos = __p - __base::begin();
+    size_type __to_end = __base::size() - __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < __to_end)
+    {   // insert by shifting things backward
+        if (__front_spare() == 0)
+            __add_front_capacity();
+        // __front_spare() >= 1
+        if (__pos == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...);
+            --__base::__start_;
+            ++__base::size();
+        }
+        else
+        {
+            value_type __tmp(_VSTD::forward<_Args>(__args)...);
+            iterator __b = __base::begin();
+            iterator __bm1 = _VSTD::prev(__b);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b));
+            --__base::__start_;
+            ++__base::size();
+            if (__pos > 1)
+                __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
+            *__b = _VSTD::move(__tmp);
+        }
+    }
+    else
+    {   // insert by shifting things forward
+        if (__back_spare() == 0)
+            __add_back_capacity();
+        // __back_capacity >= 1
+        size_type __de = __base::size() - __pos;
+        if (__de == 0)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...);
+            ++__base::size();
+        }
+        else
+        {
+            value_type __tmp(_VSTD::forward<_Args>(__args)...);
+            iterator __e = __base::end();
+            iterator __em1 = _VSTD::prev(__e);
+            __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
+            ++__base::size();
+            if (__de > 1)
+                __e = _VSTD::move_backward(__e - __de, __em1, __e);
+            *--__e = _VSTD::move(__tmp);
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_type& __v)
+{
+    size_type __pos = __p - __base::begin();
+    size_type __to_end = __base::size() - __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < __to_end)
+    {   // insert by shifting things backward
+        if (__n > __front_spare())
+            __add_front_capacity(__n - __front_spare());
+        // __n <= __front_spare()
+        size_type __old_n = __n;
+        iterator __old_begin = __base::begin();
+        iterator __i = __old_begin;
+        if (__n > __pos)
+        {
+            for (size_type __m = __n - __pos; __m; --__m, --__base::__start_, ++__base::size())
+                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), __v);
+            __n = __pos;
+        }
+        if (__n > 0)
+        {
+            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
+            iterator __obn = __old_begin + __n;
+            __move_construct_backward_and_check(__old_begin, __obn, __i, __vt);
+            if (__n < __pos)
+                __old_begin = __move_and_check(__obn, __old_begin + __pos, __old_begin, __vt);
+            _VSTD::fill_n(__old_begin, __n, *__vt);
+        }
+    }
+    else
+    {   // insert by shifting things forward
+        size_type __back_capacity = __back_spare();
+        if (__n > __back_capacity)
+            __add_back_capacity(__n - __back_capacity);
+        // __n <= __back_capacity
+        size_type __old_n = __n;
+        iterator __old_end = __base::end();
+        iterator __i = __old_end;
+        size_type __de = __base::size() - __pos;
+        if (__n > __de)
+        {
+            for (size_type __m = __n - __de; __m; --__m, ++__i, ++__base::size())
+                __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
+            __n = __de;
+        }
+        if (__n > 0)
+        {
+            const_pointer __vt = pointer_traits<const_pointer>::pointer_to(__v);
+            iterator __oen = __old_end - __n;
+            __move_construct_and_check(__oen, __old_end, __i, __vt);
+            if (__n < __de)
+                __old_end = __move_backward_and_check(__old_end - __de, __oen, __old_end, __vt);
+            _VSTD::fill_n(__old_end - __n, __n, *__vt);
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIter>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l,
+                               typename enable_if<__is_input_iterator<_InputIter>::value
+                                               &&!__is_bidirectional_iterator<_InputIter>::value>::type*)
+{
+    __split_buffer<value_type, allocator_type&> __buf(__base::__alloc());
+    __buf.__construct_at_end(__f, __l);
+    typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi;
+    return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end()));
+}
+
+template <class _Tp, class _Allocator>
+template <class _BiIter>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l,
+                               typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*)
+{
+    size_type __n = _VSTD::distance(__f, __l);
+    size_type __pos = __p - __base::begin();
+    size_type __to_end = __base::size() - __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < __to_end)
+    {   // insert by shifting things backward
+        if (__n > __front_spare())
+            __add_front_capacity(__n - __front_spare());
+        // __n <= __front_spare()
+        size_type __old_n = __n;
+        iterator __old_begin = __base::begin();
+        iterator __i = __old_begin;
+        _BiIter __m = __f;
+        if (__n > __pos)
+        {
+            __m = __pos < __n / 2 ? _VSTD::prev(__l, __pos) : _VSTD::next(__f, __n - __pos);
+            for (_BiIter __j = __m; __j != __f; --__base::__start_, ++__base::size())
+                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), *--__j);
+            __n = __pos;
+        }
+        if (__n > 0)
+        {
+            iterator __obn = __old_begin + __n;
+            for (iterator __j = __obn; __j != __old_begin;)
+            {
+                __alloc_traits::construct(__a, _VSTD::addressof(*--__i), _VSTD::move(*--__j));
+                --__base::__start_;
+                ++__base::size();
+            }
+            if (__n < __pos)
+                __old_begin = _VSTD::move(__obn, __old_begin + __pos, __old_begin);
+            _VSTD::copy(__m, __l, __old_begin);
+        }
+    }
+    else
+    {   // insert by shifting things forward
+        size_type __back_capacity = __back_spare();
+        if (__n > __back_capacity)
+            __add_back_capacity(__n - __back_capacity);
+        // __n <= __back_capacity
+        size_type __old_n = __n;
+        iterator __old_end = __base::end();
+        iterator __i = __old_end;
+        _BiIter __m = __l;
+        size_type __de = __base::size() - __pos;
+        if (__n > __de)
+        {
+            __m = __de < __n / 2 ? _VSTD::next(__f, __de) : _VSTD::prev(__l, __n - __de);
+            for (_BiIter __j = __m; __j != __l; ++__i, ++__j, ++__base::size())
+                __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__j);
+            __n = __de;
+        }
+        if (__n > 0)
+        {
+            iterator __oen = __old_end - __n;
+            for (iterator __j = __oen; __j != __old_end; ++__i, ++__j, ++__base::size())
+                __alloc_traits::construct(__a, _VSTD::addressof(*__i), _VSTD::move(*__j));
+            if (__n < __de)
+                __old_end = _VSTD::move_backward(__old_end - __de, __oen, __old_end);
+            _VSTD::copy_backward(__f, __m, __old_end);
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+template <class _Tp, class _Allocator>
+template <class _InpIter>
+void
+deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l,
+                                 typename enable_if<__is_input_iterator<_InpIter>::value &&
+                                                   !__is_forward_iterator<_InpIter>::value>::type*)
+{
+    for (; __f != __l; ++__f)
+        push_back(*__f);
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForIter>
+void
+deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l,
+                                 typename enable_if<__is_forward_iterator<_ForIter>::value>::type*)
+{
+    size_type __n = _VSTD::distance(__f, __l);
+    allocator_type& __a = __base::__alloc();
+    size_type __back_capacity = __back_spare();
+    if (__n > __back_capacity)
+        __add_back_capacity(__n - __back_capacity);
+    // __n <= __back_capacity
+    for (iterator __i = __base::end(); __f != __l; ++__i, ++__f, ++__base::size())
+        __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f);
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__append(size_type __n)
+{
+    allocator_type& __a = __base::__alloc();
+    size_type __back_capacity = __back_spare();
+    if (__n > __back_capacity)
+        __add_back_capacity(__n - __back_capacity);
+    // __n <= __back_capacity
+    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
+        __alloc_traits::construct(__a, _VSTD::addressof(*__i));
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v)
+{
+    allocator_type& __a = __base::__alloc();
+    size_type __back_capacity = __back_spare();
+    if (__n > __back_capacity)
+        __add_back_capacity(__n - __back_capacity);
+    // __n <= __back_capacity
+    for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size())
+        __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v);
+}
+
+// Create front capacity for one block of elements.
+// Strong guarantee.  Either do it or don't touch anything.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__add_front_capacity()
+{
+    allocator_type& __a = __base::__alloc();
+    if (__back_spare() >= __base::__block_size)
+    {
+        __base::__start_ += __base::__block_size;
+        pointer __pt = __base::__map_.back();
+        __base::__map_.pop_back();
+        __base::__map_.push_front(__pt);
+    }
+    // Else if __base::__map_.size() < __base::__map_.capacity() then we need to allocate 1 buffer
+    else if (__base::__map_.size() < __base::__map_.capacity())
+    {   // we can put the new buffer into the map, but don't shift things around
+        // until all buffers are allocated.  If we throw, we don't need to fix
+        // anything up (any added buffers are undetectible)
+        if (__base::__map_.__front_spare() > 0)
+            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
+        else
+        {
+            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+            // Done allocating, reorder capacity
+            pointer __pt = __base::__map_.back();
+            __base::__map_.pop_back();
+            __base::__map_.push_front(__pt);
+        }
+        __base::__start_ = __base::__map_.size() == 1 ?
+                               __base::__block_size / 2 :
+                               __base::__start_ + __base::__block_size;
+    }
+    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
+    else
+    {
+        __split_buffer<pointer, typename __base::__pointer_allocator&>
+            __buf(max<size_type>(2 * __base::__map_.capacity(), 1),
+                  0, __base::__map_.__alloc());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __alloc_traits::deallocate(__a, __buf.front(), __base::__block_size);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (typename __base::__map_pointer __i = __base::__map_.begin();
+                __i != __base::__map_.end(); ++__i)
+            __buf.push_back(*__i);
+        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
+        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
+        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
+        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
+        __base::__start_ = __base::__map_.size() == 1 ?
+                               __base::__block_size / 2 :
+                               __base::__start_ + __base::__block_size;
+    }
+}
+
+// Create front capacity for __n elements.
+// Strong guarantee.  Either do it or don't touch anything.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__add_front_capacity(size_type __n)
+{
+    allocator_type& __a = __base::__alloc();
+    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
+    // Number of unused blocks at back:
+    size_type __back_capacity = __back_spare() / __base::__block_size;
+    __back_capacity = _VSTD::min(__back_capacity, __nb);  // don't take more than you need
+    __nb -= __back_capacity;  // number of blocks need to allocate
+    // If __nb == 0, then we have sufficient capacity.
+    if (__nb == 0)
+    {
+        __base::__start_ += __base::__block_size * __back_capacity;
+        for (; __back_capacity > 0; --__back_capacity)
+        {
+            pointer __pt = __base::__map_.back();
+            __base::__map_.pop_back();
+            __base::__map_.push_front(__pt);
+        }
+    }
+    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
+    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
+    {   // we can put the new buffers into the map, but don't shift things around
+        // until all buffers are allocated.  If we throw, we don't need to fix
+        // anything up (any added buffers are undetectible)
+        for (; __nb > 0; --__nb, __base::__start_ += __base::__block_size - (__base::__map_.size() == 1))
+        {
+            if (__base::__map_.__front_spare() == 0)
+                break;
+            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
+        }
+        for (; __nb > 0; --__nb, ++__back_capacity)
+            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+        // Done allocating, reorder capacity
+        __base::__start_ += __back_capacity * __base::__block_size;
+        for (; __back_capacity > 0; --__back_capacity)
+        {
+            pointer __pt = __base::__map_.back();
+            __base::__map_.pop_back();
+            __base::__map_.push_front(__pt);
+        }
+    }
+    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
+    else
+    {
+        size_type __ds = (__nb + __back_capacity) * __base::__block_size - __base::__map_.empty();
+        __split_buffer<pointer, typename __base::__pointer_allocator&>
+            __buf(max<size_type>(2* __base::__map_.capacity(),
+                                 __nb + __base::__map_.size()),
+                  0, __base::__map_.__alloc());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __nb > 0; --__nb)
+                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            for (typename __base::__map_pointer __i = __buf.begin();
+                    __i != __buf.end(); ++__i)
+                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (; __back_capacity > 0; --__back_capacity)
+        {
+            __buf.push_back(__base::__map_.back());
+            __base::__map_.pop_back();
+        }
+        for (typename __base::__map_pointer __i = __base::__map_.begin();
+                __i != __base::__map_.end(); ++__i)
+            __buf.push_back(*__i);
+        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
+        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
+        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
+        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
+        __base::__start_ += __ds;
+    }
+}
+
+// Create back capacity for one block of elements.
+// Strong guarantee.  Either do it or don't touch anything.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__add_back_capacity()
+{
+    allocator_type& __a = __base::__alloc();
+    if (__front_spare() >= __base::__block_size)
+    {
+        __base::__start_ -= __base::__block_size;
+        pointer __pt = __base::__map_.front();
+        __base::__map_.pop_front();
+        __base::__map_.push_back(__pt);
+    }
+    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
+    else if (__base::__map_.size() < __base::__map_.capacity())
+    {   // we can put the new buffer into the map, but don't shift things around
+        // until it is allocated.  If we throw, we don't need to fix
+        // anything up (any added buffers are undetectible)
+        if (__base::__map_.__back_spare() != 0)
+            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+        else
+        {
+            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
+            // Done allocating, reorder capacity
+            pointer __pt = __base::__map_.front();
+            __base::__map_.pop_front();
+            __base::__map_.push_back(__pt);
+        }
+    }
+    // Else need to allocate 1 buffer, *and* we need to reallocate __map_.
+    else
+    {
+        __split_buffer<pointer, typename __base::__pointer_allocator&>
+            __buf(max<size_type>(2* __base::__map_.capacity(), 1),
+                  __base::__map_.size(),
+                  __base::__map_.__alloc());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            __alloc_traits::deallocate(__a, __buf.back(), __base::__block_size);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (typename __base::__map_pointer __i = __base::__map_.end();
+                __i != __base::__map_.begin();)
+            __buf.push_front(*--__i);
+        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
+        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
+        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
+        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
+    }
+}
+
+// Create back capacity for __n elements.
+// Strong guarantee.  Either do it or don't touch anything.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__add_back_capacity(size_type __n)
+{
+    allocator_type& __a = __base::__alloc();
+    size_type __nb = __recommend_blocks(__n + __base::__map_.empty());
+    // Number of unused blocks at front:
+    size_type __front_capacity = __front_spare() / __base::__block_size;
+    __front_capacity = _VSTD::min(__front_capacity, __nb);  // don't take more than you need
+    __nb -= __front_capacity;  // number of blocks need to allocate
+    // If __nb == 0, then we have sufficient capacity.
+    if (__nb == 0)
+    {
+        __base::__start_ -= __base::__block_size * __front_capacity;
+        for (; __front_capacity > 0; --__front_capacity)
+        {
+            pointer __pt = __base::__map_.front();
+            __base::__map_.pop_front();
+            __base::__map_.push_back(__pt);
+        }
+    }
+    // Else if __nb <= __map_.capacity() - __map_.size() then we need to allocate __nb buffers
+    else if (__nb <= __base::__map_.capacity() - __base::__map_.size())
+    {   // we can put the new buffers into the map, but don't shift things around
+        // until all buffers are allocated.  If we throw, we don't need to fix
+        // anything up (any added buffers are undetectible)
+        for (; __nb > 0; --__nb)
+        {
+            if (__base::__map_.__back_spare() == 0)
+                break;
+            __base::__map_.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+        }
+        for (; __nb > 0; --__nb, ++__front_capacity, __base::__start_ +=
+                                 __base::__block_size - (__base::__map_.size() == 1))
+            __base::__map_.push_front(__alloc_traits::allocate(__a, __base::__block_size));
+        // Done allocating, reorder capacity
+        __base::__start_ -= __base::__block_size * __front_capacity;
+        for (; __front_capacity > 0; --__front_capacity)
+        {
+            pointer __pt = __base::__map_.front();
+            __base::__map_.pop_front();
+            __base::__map_.push_back(__pt);
+        }
+    }
+    // Else need to allocate __nb buffers, *and* we need to reallocate __map_.
+    else
+    {
+        size_type __ds = __front_capacity * __base::__block_size;
+        __split_buffer<pointer, typename __base::__pointer_allocator&>
+            __buf(max<size_type>(2* __base::__map_.capacity(),
+                                 __nb + __base::__map_.size()),
+                  __base::__map_.size() - __front_capacity,
+                  __base::__map_.__alloc());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __nb > 0; --__nb)
+                __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            for (typename __base::__map_pointer __i = __buf.begin();
+                    __i != __buf.end(); ++__i)
+                __alloc_traits::deallocate(__a, *__i, __base::__block_size);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (; __front_capacity > 0; --__front_capacity)
+        {
+            __buf.push_back(__base::__map_.front());
+            __base::__map_.pop_front();
+        }
+        for (typename __base::__map_pointer __i = __base::__map_.end();
+                __i != __base::__map_.begin();)
+            __buf.push_front(*--__i);
+        _VSTD::swap(__base::__map_.__first_, __buf.__first_);
+        _VSTD::swap(__base::__map_.__begin_, __buf.__begin_);
+        _VSTD::swap(__base::__map_.__end_, __buf.__end_);
+        _VSTD::swap(__base::__map_.__end_cap(), __buf.__end_cap());
+        __base::__start_ -= __ds;
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::pop_front()
+{
+    allocator_type& __a = __base::__alloc();
+    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
+                                                    __base::__start_ / __base::__block_size) +
+                                                    __base::__start_ % __base::__block_size));
+    --__base::size();
+    if (++__base::__start_ >= 2 * __base::__block_size)
+    {
+        __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
+        __base::__map_.pop_front();
+        __base::__start_ -= __base::__block_size;
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::pop_back()
+{
+    allocator_type& __a = __base::__alloc();
+    size_type __p = __base::size() + __base::__start_ - 1;
+    __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() +
+                                                    __p / __base::__block_size) +
+                                                    __p % __base::__block_size));
+    --__base::size();
+    if (__back_spare() >= 2 * __base::__block_size)
+    {
+        __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+        __base::__map_.pop_back();
+    }
+}
+
+// move assign [__f, __l) to [__r, __r + (__l-__f)).
+// If __vt points into [__f, __l), then subtract (__f - __r) from __vt.
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__move_and_check(iterator __f, iterator __l, iterator __r,
+                                         const_pointer& __vt)
+{
+    // as if
+    //   for (; __f != __l; ++__f, ++__r)
+    //       *__r = _VSTD::move(*__f);
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + __base::__block_size;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        if (__fb <= __vt && __vt < __fe)
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) -= __f - __r).__ptr_;
+        __r = _VSTD::move(__fb, __fe, __r);
+        __n -= __bs;
+        __f += __bs;
+    }
+    return __r;
+}
+
+// move assign [__f, __l) to [__r - (__l-__f), __r) backwards.
+// If __vt points into [__f, __l), then add (__r - __l) to __vt.
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::__move_backward_and_check(iterator __f, iterator __l, iterator __r,
+                                                  const_pointer& __vt)
+{
+    // as if
+    //   while (__f != __l)
+    //       *--__r = _VSTD::move(*--__l);
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        if (__lb <= __vt && __vt < __le)
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) += __r - __l - 1).__ptr_;
+        __r = _VSTD::move_backward(__lb, __le, __r);
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+    return __r;
+}
+
+// move construct [__f, __l) to [__r, __r + (__l-__f)).
+// If __vt points into [__f, __l), then add (__r - __f) to __vt.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__move_construct_and_check(iterator __f, iterator __l,
+                                                   iterator __r, const_pointer& __vt)
+{
+    allocator_type& __a = __base::__alloc();
+    // as if
+    //   for (; __f != __l; ++__r, ++__f, ++__base::size())
+    //       __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__f));
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        pointer __fb = __f.__ptr_;
+        pointer __fe = *__f.__m_iter_ + __base::__block_size;
+        difference_type __bs = __fe - __fb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __fe = __fb + __bs;
+        }
+        if (__fb <= __vt && __vt < __fe)
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__f.__m_iter_), __vt) += __r - __f).__ptr_;
+        for (; __fb != __fe; ++__fb, ++__r, ++__base::size())
+            __alloc_traits::construct(__a, _VSTD::addressof(*__r), _VSTD::move(*__fb));
+        __n -= __bs;
+        __f += __bs;
+    }
+}
+
+// move construct [__f, __l) to [__r - (__l-__f), __r) backwards.
+// If __vt points into [__f, __l), then subtract (__l - __r) from __vt.
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__move_construct_backward_and_check(iterator __f, iterator __l,
+                                                            iterator __r, const_pointer& __vt)
+{
+    allocator_type& __a = __base::__alloc();
+    // as if
+    //   for (iterator __j = __l; __j != __f;)
+    //   {
+    //       __alloc_traitsconstruct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__j));
+    //       --__base::__start_;
+    //       ++__base::size();
+    //   }
+    difference_type __n = __l - __f;
+    while (__n > 0)
+    {
+        --__l;
+        pointer __lb = *__l.__m_iter_;
+        pointer __le = __l.__ptr_ + 1;
+        difference_type __bs = __le - __lb;
+        if (__bs > __n)
+        {
+            __bs = __n;
+            __lb = __le - __bs;
+        }
+        if (__lb <= __vt && __vt < __le)
+            __vt = (const_iterator(static_cast<__map_const_pointer>(__l.__m_iter_), __vt) -= __l - __r + 1).__ptr_;
+        while (__le != __lb)
+        {
+            __alloc_traits::construct(__a, _VSTD::addressof(*--__r), _VSTD::move(*--__le));
+            --__base::__start_;
+            ++__base::size();
+        }
+        __n -= __bs;
+        __l -= __bs - 1;
+    }
+}
+
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::erase(const_iterator __f)
+{
+    difference_type __n = 1;
+    iterator __b = __base::begin();
+    difference_type __pos = __f - __b;
+    iterator __p = __b + __pos;
+    allocator_type& __a = __base::__alloc();
+    if (__pos < (__base::size() - 1) / 2)
+    {   // erase from front
+        _VSTD::move_backward(__b, __p, _VSTD::next(__p));
+        __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
+        --__base::size();
+        ++__base::__start_;
+        if (__front_spare() >= 2 * __base::__block_size)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
+            __base::__map_.pop_front();
+            __base::__start_ -= __base::__block_size;
+        }
+    }
+    else
+    {   // erase from back
+        iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p);
+        __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
+        --__base::size();
+        if (__back_spare() >= 2 * __base::__block_size)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+            __base::__map_.pop_back();
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+template <class _Tp, class _Allocator>
+typename deque<_Tp, _Allocator>::iterator
+deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l)
+{
+    difference_type __n = __l - __f;
+    iterator __b = __base::begin();
+    difference_type __pos = __f - __b;
+    iterator __p = __b + __pos;
+    if (__n > 0)
+    {
+        allocator_type& __a = __base::__alloc();
+        if (__pos < (__base::size() - __n) / 2)
+        {   // erase from front
+            iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
+            for (; __b != __i; ++__b)
+                __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
+            __base::size() -= __n;
+            __base::__start_ += __n;
+            while (__front_spare() >= 2 * __base::__block_size)
+            {
+                __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size);
+                __base::__map_.pop_front();
+                __base::__start_ -= __base::__block_size;
+            }
+        }
+        else
+        {   // erase from back
+            iterator __i = _VSTD::move(__p + __n, __base::end(), __p);
+            for (iterator __e = __base::end(); __i != __e; ++__i)
+                __alloc_traits::destroy(__a, _VSTD::addressof(*__i));
+            __base::size() -= __n;
+            while (__back_spare() >= 2 * __base::__block_size)
+            {
+                __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+                __base::__map_.pop_back();
+            }
+        }
+    }
+    return __base::begin() + __pos;
+}
+
+template <class _Tp, class _Allocator>
+void
+deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f)
+{
+    iterator __e = __base::end();
+    difference_type __n = __e - __f;
+    if (__n > 0)
+    {
+        allocator_type& __a = __base::__alloc();
+        iterator __b = __base::begin();
+        difference_type __pos = __f - __b;
+        for (iterator __p = __b + __pos; __p != __e; ++__p)
+            __alloc_traits::destroy(__a, _VSTD::addressof(*__p));
+        __base::size() -= __n;
+        while (__back_spare() >= 2 * __base::__block_size)
+        {
+            __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size);
+            __base::__map_.pop_back();
+        }
+    }
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+deque<_Tp, _Allocator>::swap(deque& __c)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+{
+    __base::swap(__c);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+deque<_Tp, _Allocator>::clear() _NOEXCEPT
+{
+    __base::clear();
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    const typename deque<_Tp, _Allocator>::size_type __sz = __x.size();
+    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_DEQUE
diff --git a/include/c++/v1/exception b/include/c++/v1/exception
new file mode 100644
index 0000000..cad802e
--- /dev/null
+++ b/include/c++/v1/exception
@@ -0,0 +1,250 @@
+// -*- C++ -*-
+//===-------------------------- exception ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXCEPTION
+#define _LIBCPP_EXCEPTION
+
+/*
+    exception synopsis
+
+namespace std
+{
+
+class exception
+{
+public:
+    exception() noexcept;
+    exception(const exception&) noexcept;
+    exception& operator=(const exception&) noexcept;
+    virtual ~exception() noexcept;
+    virtual const char* what() const noexcept;
+};
+
+class bad_exception
+    : public exception
+{
+public:
+    bad_exception() noexcept;
+    bad_exception(const bad_exception&) noexcept;
+    bad_exception& operator=(const bad_exception&) noexcept;
+    virtual ~bad_exception() noexcept;
+    virtual const char* what() const noexcept;
+};
+
+typedef void (*unexpected_handler)();
+unexpected_handler set_unexpected(unexpected_handler  f ) noexcept;
+unexpected_handler get_unexpected() noexcept;
+[[noreturn]] void unexpected();
+
+typedef void (*terminate_handler)();
+terminate_handler set_terminate(terminate_handler  f ) noexcept;
+terminate_handler get_terminate() noexcept;
+[[noreturn]] void terminate() noexcept;
+
+bool uncaught_exception() noexcept;
+
+typedef unspecified exception_ptr;
+
+exception_ptr current_exception() noexcept;
+void rethrow_exception [[noreturn]] (exception_ptr p);
+template<class E> exception_ptr make_exception_ptr(E e) noexcept;
+
+class nested_exception
+{
+public:
+    nested_exception() noexcept;
+    nested_exception(const nested_exception&) noexcept = default;
+    nested_exception& operator=(const nested_exception&) noexcept = default;
+    virtual ~nested_exception() = default;
+
+    // access functions
+    [[noreturn]] void rethrow_nested() const;
+    exception_ptr nested_ptr() const noexcept;
+};
+
+template <class T> [[noreturn]] void throw_with_nested(T&& t);
+template <class E> void rethrow_if_nested(const E& e);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cstddef>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std  // purposefully not using versioning namespace
+{
+
+class _LIBCPP_EXCEPTION_ABI exception
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
+    virtual ~exception() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI bad_exception
+    : public exception
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
+    virtual ~bad_exception() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+typedef void (*unexpected_handler)();
+_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
+
+typedef void (*terminate_handler)();
+_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
+
+class _LIBCPP_TYPE_VIS exception_ptr;
+
+_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
+
+class _LIBCPP_TYPE_VIS exception_ptr
+{
+    void* __ptr_;
+public:
+    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
+    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
+    exception_ptr(const exception_ptr&) _NOEXCEPT;
+    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+    ~exception_ptr() _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_EXPLICIT
+        operator bool() const _NOEXCEPT {return __ptr_ != nullptr;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
+        {return __x.__ptr_ == __y.__ptr_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
+        {return !(__x == __y);}
+
+    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
+};
+
+template<class _Ep>
+exception_ptr
+make_exception_ptr(_Ep __e) _NOEXCEPT
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+        throw __e;
+    }
+    catch (...)
+    {
+        return current_exception();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+// nested_exception
+
+class _LIBCPP_EXCEPTION_ABI nested_exception
+{
+    exception_ptr __ptr_;
+public:
+    nested_exception() _NOEXCEPT;
+//     nested_exception(const nested_exception&) noexcept = default;
+//     nested_exception& operator=(const nested_exception&) noexcept = default;
+    virtual ~nested_exception() _NOEXCEPT;
+
+    // access functions
+    _LIBCPP_NORETURN void rethrow_nested() const;
+    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
+};
+
+template <class _Tp>
+struct __nested
+    : public _Tp,
+      public nested_exception
+{
+    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
+};
+
+template <class _Tp>
+_LIBCPP_NORETURN
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+throw_with_nested(_Tp&& __t, typename enable_if<
+                  is_class<typename remove_reference<_Tp>::type>::value &&
+                  !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+                                    >::type* = 0)
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+throw_with_nested (_Tp& __t, typename enable_if<
+                  is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value
+                                    >::type* = 0)
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t));
+#endif
+}
+
+template <class _Tp>
+_LIBCPP_NORETURN
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+throw_with_nested(_Tp&& __t, typename enable_if<
+                  !is_class<typename remove_reference<_Tp>::type>::value ||
+                  is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+                                    >::type* = 0)
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+throw_with_nested (_Tp& __t, typename enable_if<
+                  !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value
+                                    >::type* = 0)
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw _VSTD::forward<_Tp>(__t);
+#endif
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+rethrow_if_nested(const _Ep& __e, typename enable_if<
+                                   is_polymorphic<_Ep>::value
+                                                   >::type* = 0)
+{
+    const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
+    if (__nep)
+        __nep->rethrow_nested();
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+rethrow_if_nested(const _Ep&, typename enable_if<
+                                   !is_polymorphic<_Ep>::value
+                                                   >::type* = 0)
+{
+}
+
+}  // std
+
+#endif  // _LIBCPP_EXCEPTION
diff --git a/include/c++/v1/experimental/__config b/include/c++/v1/experimental/__config
new file mode 100644
index 0000000..684a3b4
--- /dev/null
+++ b/include/c++/v1/experimental/__config
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+//===--------------------------- __config ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_CONFIG
+#define _LIBCPP_EXPERIMENTAL_CONFIG
+
+#include <__config>
+
+#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental {
+#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL  } }
+#define _VSTD_EXPERIMENTAL std::experimental
+
+#define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 {
+#define _LIBCPP_END_NAMESPACE_LFTS  } } }
+#define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1
+
+#endif
diff --git a/include/c++/v1/experimental/dynarray b/include/c++/v1/experimental/dynarray
new file mode 100644
index 0000000..d2a4298
--- /dev/null
+++ b/include/c++/v1/experimental/dynarray
@@ -0,0 +1,314 @@
+// -*- C++ -*-
+//===-------------------------- dynarray ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_DYNARRAY
+#define _LIBCPP_DYNARRAY
+
+#include <__config>
+#if _LIBCPP_STD_VER > 11
+
+/*
+    dynarray synopsis
+
+namespace std { namespace experimental {
+
+template< typename T >
+class dynarray
+{
+    // types:
+    typedef       T                               value_type;
+    typedef       T&                              reference;
+    typedef const T&                              const_reference;
+    typedef       T*                              pointer;
+    typedef const T*                              const_pointer;
+    typedef       implementation-defined          iterator;
+    typedef       implementation-defined          const_iterator;
+    typedef reverse_iterator<iterator>            reverse_iterator;
+    typedef reverse_iterator<const_iterator>      const_reverse_iterator;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+
+public:
+    // construct/copy/destroy:
+    explicit dynarray(size_type c);
+    template <typename Alloc>
+      dynarray(size_type c, const Alloc& alloc);
+    dynarray(size_type c, const T& v);
+    template <typename Alloc>
+      dynarray(size_type c, const T& v, const Alloc& alloc);
+    dynarray(const dynarray& d);
+    template <typename Alloc>
+      dynarray(const dynarray& d, const Alloc& alloc);
+    dynarray(initializer_list<T>);
+    template <typename Alloc>
+      dynarray(initializer_list<T>, const Alloc& alloc);
+
+    dynarray& operator=(const dynarray&) = delete;
+    ~dynarray();
+
+    // iterators:
+    iterator       begin()        noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator cbegin() const noexcept;
+    iterator       end()          noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cend()   const noexcept;
+
+    reverse_iterator       rbegin()        noexcept;
+    const_reverse_iterator rbegin()  const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    reverse_iterator       rend()          noexcept;
+    const_reverse_iterator rend()    const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+    bool      empty()    const noexcept;
+
+    // element access:
+    reference       operator[](size_type n);
+    const_reference operator[](size_type n) const;
+
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back()  const;
+
+    const_reference at(size_type n) const;
+    reference       at(size_type n);
+
+    // data access:
+    T*       data()       noexcept;
+    const T* data() const noexcept;
+
+    // mutating member functions:
+    void fill(const T& v);
+};
+
+}}  // std::experimental
+
+*/
+
+#include <__functional_base>
+#include <iterator>
+#include <stdexcept>
+#include <initializer_list>
+#include <new>
+#include <algorithm>
+
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std { namespace experimental { inline namespace __array_extensions_v1 {
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY dynarray
+{
+public:
+    // types:
+    typedef dynarray __self;
+    typedef _Tp                                   value_type;
+    typedef value_type&                           reference;
+    typedef const value_type&                     const_reference;
+    typedef value_type*                           iterator;
+    typedef const value_type*                     const_iterator;
+    typedef value_type*                           pointer;
+    typedef const value_type*                     const_pointer;
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef std::reverse_iterator<iterator>       reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+private:
+    size_t                  __size_;
+    value_type *            __base_;
+    _LIBCPP_ALWAYS_INLINE dynarray () noexcept : __base_(nullptr), __size_(0) {}
+    
+    static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count )
+    {
+        if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count )
+        {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            throw bad_array_length();
+#else
+            assert(!"dynarray::allocation");
+#endif
+        }
+        return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count));
+    }
+
+    static inline _LIBCPP_INLINE_VISIBILITY void __deallocate ( value_type* __ptr ) noexcept
+    {
+        _VSTD::__deallocate (static_cast<void *> (__ptr));
+    }
+
+public:
+
+    explicit dynarray(size_type __c);
+    dynarray(size_type __c, const value_type& __v);
+    dynarray(const dynarray& __d);
+    dynarray(initializer_list<value_type>);
+
+//  We're not implementing these right now.
+//  Waiting for the resolution of LWG issue #2235
+//     template <typename _Alloc>
+//       dynarray(size_type __c, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(size_type __c, const value_type& __v, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(const dynarray& __d, const _Alloc& __alloc);
+//     template <typename _Alloc>
+//       dynarray(initializer_list<value_type>, const _Alloc& __alloc);
+
+    dynarray& operator=(const dynarray&) = delete;
+    ~dynarray();
+
+    // iterators:
+    inline _LIBCPP_INLINE_VISIBILITY iterator       begin()        noexcept { return iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator begin()  const noexcept { return const_iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); }
+    inline _LIBCPP_INLINE_VISIBILITY iterator       end()          noexcept { return iterator(data() + __size_); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator end()    const noexcept { return const_iterator(data() + __size_); }
+    inline _LIBCPP_INLINE_VISIBILITY const_iterator cend()   const noexcept { return const_iterator(data() + __size_); }
+
+    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rbegin()        noexcept { return reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin()  const noexcept { return const_reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
+    inline _LIBCPP_INLINE_VISIBILITY reverse_iterator       rend()          noexcept { return reverse_iterator(begin()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend()    const noexcept { return const_reverse_iterator(begin()); }
+    inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend()   const noexcept { return const_reverse_iterator(begin()); }
+
+    // capacity:
+    inline _LIBCPP_INLINE_VISIBILITY size_type size()     const noexcept { return __size_; }
+    inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; }
+    inline _LIBCPP_INLINE_VISIBILITY bool      empty()    const noexcept { return __size_ == 0; }
+
+    // element access:
+    inline _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       { return data()[__n]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; }
+
+    inline _LIBCPP_INLINE_VISIBILITY reference       front()       { return data()[0]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; }
+    inline _LIBCPP_INLINE_VISIBILITY reference       back()        { return data()[__size_-1]; }
+    inline _LIBCPP_INLINE_VISIBILITY const_reference back()  const { return data()[__size_-1]; }
+
+    inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const;
+    inline _LIBCPP_INLINE_VISIBILITY reference       at(size_type __n);
+
+    // data access:
+    inline _LIBCPP_INLINE_VISIBILITY _Tp*       data()       noexcept { return __base_; }
+    inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; }
+
+    // mutating member functions:
+    inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); }
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(size_type __c) : dynarray ()
+{
+    __base_ = __allocate (__c);
+    value_type *__data = data ();
+    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
+        ::new (__data) value_type;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray ()
+{
+    __base_ = __allocate (__c);
+    value_type *__data = data ();
+    for ( __size_ = 0; __size_ < __c; ++__size_, ++__data )
+        ::new (__data) value_type (__v);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray ()
+{
+    size_t sz = __il.size();
+    __base_ = __allocate (sz);
+    value_type *__data = data ();
+    auto src = __il.begin();
+    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
+        ::new (__data) value_type (*src);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray ()
+{
+    size_t sz = __d.size();
+    __base_ = __allocate (sz);
+    value_type *__data = data ();
+    auto src = __d.begin();
+    for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src )
+        ::new (__data) value_type (*src);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+dynarray<_Tp>::~dynarray()
+{ 
+    value_type *__data = data () + __size_;
+    for ( size_t i = 0; i < __size_; ++i )
+        (--__data)->value_type::~value_type();
+    __deallocate ( __base_ );
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename dynarray<_Tp>::reference
+dynarray<_Tp>::at(size_type __n)
+{
+    if (__n >= __size_)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("dynarray::at");
+#else
+        assert(!"dynarray::at out_of_range");
+#endif
+    }
+    return data()[__n];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename dynarray<_Tp>::const_reference
+dynarray<_Tp>::at(size_type __n) const
+{
+    if (__n >= __size_)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw out_of_range("dynarray::at");
+#else
+        assert(!"dynarray::at out_of_range");
+#endif
+    }
+    return data()[__n];
+}
+
+}}}
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {};
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // if _LIBCPP_STD_VER > 11 
+#endif  // _LIBCPP_DYNARRAY
diff --git a/include/c++/v1/experimental/optional b/include/c++/v1/experimental/optional
new file mode 100644
index 0000000..3848da8
--- /dev/null
+++ b/include/c++/v1/experimental/optional
@@ -0,0 +1,699 @@
+// -*- C++ -*-
+//===-------------------------- optional ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_OPTIONAL
+#define _LIBCPP_OPTIONAL
+
+/*
+    optional synopsis
+
+// C++1y
+
+#include <initializer_list>
+
+namespace std { namespace experimental {
+
+// optional for object types
+template <class T>
+class optional
+{
+public:
+    typedef T value_type;
+
+    // constructors
+    constexpr optional() noexcept;
+    constexpr optional(nullopt_t) noexcept;
+    optional(const optional&);
+    optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
+    constexpr optional(const T&);
+    constexpr optional(T&&);
+    template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
+    template <class U, class... Args>
+        constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
+
+    // destructor
+    ~optional();
+
+    // assignment
+    optional& operator=(nullopt_t) noexcept;
+    optional& operator=(const optional&);
+    optional& operator=(optional&&)
+        noexcept(is_nothrow_move_assignable<T>::value &&
+                 is_nothrow_move_constructible<T>::value);
+    template <class U> optional& operator=(U&&);
+    template <class... Args> void emplace(Args&&...);
+    template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
+
+    // swap
+    void swap(optional&)
+        noexcept(is_nothrow_move_constructible<T>::value &&
+                 noexcept(swap(declval<T&>(), declval<T&>())));
+
+    // observers
+    constexpr T const* operator->() const;
+    T* operator->();
+    constexpr T const& operator*() const;
+    T& operator*();
+    constexpr explicit operator bool() const noexcept;
+    constexpr T const& value() const;
+    T& value();
+    template <class U> constexpr T value_or(U&&) const&;
+    template <class U> T value_or(U&&) &&;
+};
+
+// In-place construction
+struct in_place_t{};
+constexpr in_place_t in_place{};
+
+// Disengaged state indicator
+struct nullopt_t{see below};
+constexpr nullopt_t nullopt(unspecified);
+
+// class bad_optional_access
+class bad_optional_access
+    : public logic_error
+{
+public:
+    explicit bad_optional_access(const string& what_arg);
+    explicit bad_optional_access(const char* what_arg);
+};
+
+// Relational operators
+template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
+template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&);
+
+// Comparison with nullopt
+template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
+template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
+template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
+template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
+
+// Comparison with T
+template <class T> constexpr bool operator==(const optional<T>&, const T&);
+template <class T> constexpr bool operator==(const T&, const optional<T>&);
+template <class T> constexpr bool operator<(const optional<T>&, const T&);
+template <class T> constexpr bool operator<(const T&, const optional<T>&);
+
+// Specialized algorithms
+template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
+template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&);
+
+// hash support
+template <class T> struct hash;
+template <class T> struct hash<optional<T>>;
+
+}}  // std::experimental
+
+*/
+
+#include <__config>
+#include <functional>
+#include <stdexcept>
+
+namespace std { namespace experimental {
+
+class _LIBCPP_EXCEPTION_ABI bad_optional_access
+    : public logic_error
+{
+public:
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
+        : logic_error(__arg) {}
+    _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
+        : logic_error(__arg) {}
+    _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default;
+    _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default;
+#else
+private:
+    bad_optional_access(const bad_optional_access&);
+    bad_optional_access& operator=(const bad_optional_access&);
+public:
+#endif  // _LIBCPP_STD_VER > 11
+    // Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y
+    virtual ~bad_optional_access() _NOEXCEPT;
+};
+
+}}  // std::experimental
+
+#if _LIBCPP_STD_VER > 11
+
+#include <initializer_list>
+#include <type_traits>
+#include <new>
+#include <__functional_base>
+
+#include <__undef_min_max>
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
+
+struct in_place_t {};
+constexpr in_place_t in_place{};
+
+struct nullopt_t
+{
+    explicit constexpr nullopt_t(int) noexcept {}
+};
+
+constexpr nullopt_t nullopt{0};
+
+template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
+class __optional_storage
+{
+protected:
+    typedef _Tp value_type;
+    union
+    {
+        char __null_state_;
+        value_type __val_;
+    };
+    bool __engaged_ = false;
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__optional_storage()
+    {
+        if (__engaged_)
+            __val_.~value_type();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage() noexcept
+        :  __null_state_('\0') {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(const __optional_storage& __x)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(__optional_storage&& __x)
+                      noexcept(is_nothrow_move_constructible<value_type>::value)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(const value_type& __v)
+        :  __val_(__v),
+           __engaged_(true) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(value_type&& __v)
+        :  __val_(_VSTD::move(__v)),
+           __engaged_(true) {}
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit __optional_storage(in_place_t, _Args&&... __args)
+       :  __val_(_VSTD::forward<_Args>(__args)...),
+           __engaged_(true) {}
+};
+
+template <class _Tp>
+class __optional_storage<_Tp, true>
+{
+protected:
+    typedef _Tp value_type;
+    union
+    {
+        char __null_state_;
+        value_type __val_;
+    };
+    bool __engaged_ = false;
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage() noexcept
+        :  __null_state_('\0') {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(const __optional_storage& __x)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __optional_storage(__optional_storage&& __x)
+                      noexcept(is_nothrow_move_constructible<value_type>::value)
+        :  __engaged_(__x.__engaged_)
+        {
+            if (__engaged_)
+                ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(const value_type& __v)
+        :  __val_(__v),
+           __engaged_(true) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __optional_storage(value_type&& __v)
+        :  __val_(_VSTD::move(__v)),
+           __engaged_(true) {}
+
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit __optional_storage(in_place_t, _Args&&... __args)
+       :  __val_(_VSTD::forward<_Args>(__args)...),
+           __engaged_(true) {}
+};
+
+template <class _Tp>
+class optional
+    : private __optional_storage<_Tp>
+{
+    typedef __optional_storage<_Tp> __base;
+public:
+    typedef _Tp value_type;
+
+    static_assert(!is_reference<value_type>::value,
+              "Instantiation of optional with a reference type is ill-formed.");
+    static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
+              "Instantiation of optional with a in_place_t type is ill-formed.");
+    static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
+              "Instantiation of optional with a nullopt_t type is ill-formed.");
+    static_assert(is_object<value_type>::value,
+        "Instantiation of optional with a non-object type is undefined behavior.");
+    static_assert(is_nothrow_destructible<value_type>::value,
+        "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
+
+    _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
+    _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
+    _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
+    _LIBCPP_INLINE_VISIBILITY ~optional() = default;
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
+        : __base(__v) {}
+    _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
+        : __base(_VSTD::move(__v)) {}
+
+    template <class... _Args,
+              class = typename enable_if
+                      <
+                           is_constructible<value_type, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit optional(in_place_t, _Args&&... __args)
+        : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
+
+    template <class _Up, class... _Args,
+              class = typename enable_if
+                      <
+                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
+        : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional& operator=(nullopt_t) noexcept
+    {
+        if (this->__engaged_)
+        {
+            this->__val_.~value_type();
+            this->__engaged_ = false;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(const optional& __opt)
+    {
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                this->__val_ = __opt.__val_;
+        }
+        else
+        {
+            if (this->__engaged_)
+                this->__val_.~value_type();
+            else
+                ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
+            this->__engaged_ = __opt.__engaged_;
+        }
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(optional&& __opt)
+        noexcept(is_nothrow_move_assignable<value_type>::value &&
+                 is_nothrow_move_constructible<value_type>::value)
+    {
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                this->__val_ = _VSTD::move(__opt.__val_);
+        }
+        else
+        {
+            if (this->__engaged_)
+                this->__val_.~value_type();
+            else
+                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
+            this->__engaged_ = __opt.__engaged_;
+        }
+        return *this;
+    }
+
+    template <class _Up,
+              class = typename enable_if
+                      <
+                          is_same<typename remove_reference<_Up>::type, value_type>::value &&
+                          is_constructible<value_type, _Up>::value &&
+                          is_assignable<value_type&, _Up>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    optional&
+    operator=(_Up&& __v)
+    {
+        if (this->__engaged_)
+            this->__val_ = _VSTD::forward<_Up>(__v);
+        else
+        {
+            ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
+            this->__engaged_ = true;
+        }
+        return *this;
+    }
+
+    template <class... _Args,
+              class = typename enable_if
+                      <
+                          is_constructible<value_type, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    emplace(_Args&&... __args)
+    {
+        *this = nullopt;
+        ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
+        this->__engaged_ = true;
+    }
+
+    template <class _Up, class... _Args,
+              class = typename enable_if
+                      <
+                          is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
+                      >::type
+             >
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    emplace(initializer_list<_Up> __il, _Args&&... __args)
+    {
+        *this = nullopt;
+        ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
+        this->__engaged_ = true;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    swap(optional& __opt)
+        noexcept(is_nothrow_move_constructible<value_type>::value &&
+                 __is_nothrow_swappable<value_type>::value)
+    {
+        using _VSTD::swap;
+        if (this->__engaged_ == __opt.__engaged_)
+        {
+            if (this->__engaged_)
+                swap(this->__val_, __opt.__val_);
+        }
+        else
+        {
+            if (this->__engaged_)
+            {
+                ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
+                this->__val_.~value_type();
+            }
+            else
+            {
+                ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
+                __opt.__val_.~value_type();
+            }
+            swap(this->__engaged_, __opt.__engaged_);
+        }
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    value_type const*
+    operator->() const
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
+        return __operator_arrow(__has_operator_addressof<value_type>{});
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type*
+    operator->()
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
+        return _VSTD::addressof(this->__val_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    const value_type&
+    operator*() const
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type&
+    operator*()
+    {
+        _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr explicit operator bool() const noexcept {return this->__engaged_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr value_type const& value() const
+    {
+        if (!this->__engaged_)
+            throw bad_optional_access("optional<T>::value: not engaged");
+        return this->__val_;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type& value()
+    {
+        if (!this->__engaged_)
+            throw bad_optional_access("optional<T>::value: not engaged");
+        return this->__val_;
+    }
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr value_type value_or(_Up&& __v) const&
+    {
+        static_assert(is_copy_constructible<value_type>::value,
+                      "optional<T>::value_or: T must be copy constructible");
+        static_assert(is_convertible<_Up, value_type>::value,
+                      "optional<T>::value_or: U must be convertible to T");
+        return this->__engaged_ ? this->__val_ :
+                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
+    }
+
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+    value_type value_or(_Up&& __v) &&
+    {
+        static_assert(is_move_constructible<value_type>::value,
+                      "optional<T>::value_or: T must be move constructible");
+        static_assert(is_convertible<_Up, value_type>::value,
+                      "optional<T>::value_or: U must be convertible to T");
+        return this->__engaged_ ? _VSTD::move(this->__val_) :
+                                  static_cast<value_type>(_VSTD::forward<_Up>(__v));
+    }
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    value_type const*
+    __operator_arrow(true_type) const
+    {
+        return _VSTD::addressof(this->__val_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    value_type const*
+    __operator_arrow(false_type) const
+    {
+        return &this->__val_;
+    }
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
+{
+    if (static_cast<bool>(__x) != static_cast<bool>(__y))
+        return false;
+    if (!static_cast<bool>(__x))
+        return true;
+    return *__x == *__y;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
+{
+    if (!static_cast<bool>(__y))
+        return false;
+    if (!static_cast<bool>(__x))
+        return true;
+    return less<_Tp>{}(*__x, *__y);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, nullopt_t) noexcept
+{
+    return !static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(nullopt_t, const optional<_Tp>& __x) noexcept
+{
+    return !static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>&, nullopt_t) noexcept
+{
+    return false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(nullopt_t, const optional<_Tp>& __x) noexcept
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const optional<_Tp>& __x, const _Tp& __v)
+{
+    return static_cast<bool>(__x) ? *__x == __v : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator==(const _Tp& __v, const optional<_Tp>& __x)
+{
+    return static_cast<bool>(__x) ? *__x == __v : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const optional<_Tp>& __x, const _Tp& __v)
+{
+    return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+bool
+operator<(const _Tp& __v, const optional<_Tp>& __x)
+{
+    return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr
+optional<typename decay<_Tp>::type>
+make_optional(_Tp&& __v)
+{
+    return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
+}
+
+}}}  // namespace std::experimental::__library_fundamentals_v1
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
+{
+    typedef std::experimental::optional<_Tp> argument_type;
+    typedef size_t        result_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(const argument_type& __opt) const _NOEXCEPT
+    {
+        return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
+    }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STD_VER > 11
+
+#endif  // _LIBCPP_ARRAY
diff --git a/include/c++/v1/experimental/string_view b/include/c++/v1/experimental/string_view
new file mode 100644
index 0000000..c38548b
--- /dev/null
+++ b/include/c++/v1/experimental/string_view
@@ -0,0 +1,814 @@
+// -*- C++ -*-
+//===------------------------ string_view ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LFTS_STRING_VIEW
+#define _LIBCPP_LFTS_STRING_VIEW
+
+/*
+string_view synopsis
+
+namespace std {
+ namespace experimental {
+  inline namespace library_fundamentals_v1 {
+
+    // 7.2, Class template basic_string_view
+    template<class charT, class traits = char_traits<charT>>
+        class basic_string_view;
+
+    // 7.9, basic_string_view non-member comparison functions
+    template<class charT, class traits>
+    constexpr bool operator==(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator!=(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator< (basic_string_view<charT, traits> x,
+                                 basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator> (basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator<=(basic_string_view<charT, traits> x,
+                                 basic_string_view<charT, traits> y) noexcept;
+    template<class charT, class traits>
+    constexpr bool operator>=(basic_string_view<charT, traits> x,
+                              basic_string_view<charT, traits> y) noexcept;
+    // see below, sufficient additional overloads of comparison functions
+
+    // 7.10, Inserters and extractors
+    template<class charT, class traits>
+      basic_ostream<charT, traits>&
+        operator<<(basic_ostream<charT, traits>& os,
+                   basic_string_view<charT, traits> str);
+
+    // basic_string_view typedef names
+    typedef basic_string_view<char> string_view;
+    typedef basic_string_view<char16_t> u16string_view;
+    typedef basic_string_view<char32_t> u32string_view;
+    typedef basic_string_view<wchar_t> wstring_view;
+
+    template<class charT, class traits = char_traits<charT>>
+    class basic_string_view {
+      public:
+      // types
+      typedef traits traits_type;
+      typedef charT value_type;
+      typedef charT* pointer;
+      typedef const charT* const_pointer;
+      typedef charT& reference;
+      typedef const charT& const_reference;
+      typedef implementation-defined const_iterator;
+      typedef const_iterator iterator;
+      typedef reverse_iterator<const_iterator> const_reverse_iterator;
+      typedef const_reverse_iterator reverse_iterator;
+      typedef size_t size_type;
+      typedef ptrdiff_t difference_type;
+      static constexpr size_type npos = size_type(-1);
+
+      // 7.3, basic_string_view constructors and assignment operators
+      constexpr basic_string_view() noexcept;
+      constexpr basic_string_view(const basic_string_view&) noexcept = default;
+      basic_string_view& operator=(const basic_string_view&) noexcept = default;
+      template<class Allocator>
+      basic_string_view(const basic_string<charT, traits, Allocator>& str) noexcept;
+      constexpr basic_string_view(const charT* str);
+      constexpr basic_string_view(const charT* str, size_type len);
+
+      // 7.4, basic_string_view iterator support
+      constexpr const_iterator begin() const noexcept;
+      constexpr const_iterator end() const noexcept;
+      constexpr const_iterator cbegin() const noexcept;
+      constexpr const_iterator cend() const noexcept;
+      const_reverse_iterator rbegin() const noexcept;
+      const_reverse_iterator rend() const noexcept;
+      const_reverse_iterator crbegin() const noexcept;
+      const_reverse_iterator crend() const noexcept;
+
+      // 7.5, basic_string_view capacity
+      constexpr size_type size() const noexcept;
+      constexpr size_type length() const noexcept;
+      constexpr size_type max_size() const noexcept;
+      constexpr bool empty() const noexcept;
+
+      // 7.6, basic_string_view element access
+      constexpr const_reference operator[](size_type pos) const;
+      constexpr const_reference at(size_type pos) const;
+      constexpr const_reference front() const;
+      constexpr const_reference back() const;
+      constexpr const_pointer data() const noexcept;
+
+      // 7.7, basic_string_view modifiers
+      constexpr void clear() noexcept;
+      constexpr void remove_prefix(size_type n);
+      constexpr void remove_suffix(size_type n);
+      constexpr void swap(basic_string_view& s) noexcept;
+
+      // 7.8, basic_string_view string operations
+      template<class Allocator>
+      explicit operator basic_string<charT, traits, Allocator>() const;
+      template<class Allocator = allocator<charT>>
+      basic_string<charT, traits, Allocator> to_string(
+        const Allocator& a = Allocator()) const;
+
+      size_type copy(charT* s, size_type n, size_type pos = 0) const;
+
+      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
+      constexpr int compare(basic_string_view s) const noexcept;
+      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
+      constexpr int compare(size_type pos1, size_type n1,
+                            basic_string_view s, size_type pos2, size_type n2) const;
+      constexpr int compare(const charT* s) const;
+      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
+      constexpr int compare(size_type pos1, size_type n1,
+                            const charT* s, size_type n2) const;
+      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find(const charT* s, size_type pos = 0) const;
+      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type rfind(const charT* s, size_type pos = npos) const;
+      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
+      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
+      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
+      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
+      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
+      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
+      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
+
+     private:
+      const_pointer data_;  // exposition only
+      size_type     size_;  // exposition only
+    };
+
+  }  // namespace fundamentals_v1
+ }  // namespace experimental
+
+  // 7.11, Hash support
+  template <class T> struct hash;
+  template <> struct hash<experimental::string_view>;
+  template <> struct hash<experimental::u16string_view>;
+  template <> struct hash<experimental::u32string_view>;
+  template <> struct hash<experimental::wstring_view>;
+
+}  // namespace std
+
+
+*/
+
+#include <experimental/__config>
+
+#include <string>
+#include <algorithm>
+#include <iterator>
+#include <ostream>
+#include <iomanip>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+    
+    template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_string_view {
+    public:
+        // types
+        typedef _Traits                                    traits_type;
+        typedef _CharT                                     value_type;
+        typedef const _CharT*                              pointer;
+        typedef const _CharT*                              const_pointer;
+        typedef const _CharT&                              reference;
+        typedef const _CharT&                              const_reference;
+        typedef const_pointer                              const_iterator; // See [string.view.iterators]
+        typedef const_iterator                             iterator;
+        typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
+        typedef const_reverse_iterator                     reverse_iterator;
+        typedef size_t                                     size_type;
+        typedef ptrdiff_t                                  difference_type;
+        static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
+
+        // [string.view.cons], construct/copy
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const basic_string_view&) _NOEXCEPT = default;
+        
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
+
+        template<class _Allocator>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT
+            : __data (__str.data()), __size(__str.size()) {}
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const _CharT* __s, size_type __len)
+            : __data(__s), __size(__len)
+        {
+//             _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr");
+        }
+            
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        basic_string_view(const _CharT* __s)
+            : __data(__s), __size(_Traits::length(__s)) {}
+
+        // [string.view.iterators], iterators
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator begin()  const _NOEXCEPT { return cbegin(); }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator end()    const _NOEXCEPT { return cend(); }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator cbegin() const _NOEXCEPT { return __data; }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_iterator cend()   const _NOEXCEPT { return __data + __size; }
+
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
+        
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
+        
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
+        
+        _LIBCPP_INLINE_VISIBILITY
+        const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
+
+        // [string.view.capacity], capacity
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type size()     const _NOEXCEPT { return __size; }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type length()   const _NOEXCEPT { return __size; }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); }
+        
+        _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY
+        empty()         const _NOEXCEPT { return __size == 0; }
+
+        // [string.view.access], element access
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference operator[](size_type __pos) const { return __data[__pos]; }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference at(size_type __pos) const
+        {
+            return __pos >= size()
+                ? throw out_of_range("string_view::at")
+                : __data[__pos];
+//             if (__pos >= size())
+//                 throw out_of_range("string_view::at");
+//             return __data[__pos]; 
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference front() const
+        {
+            return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
+        }
+        
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_reference back() const
+        {
+            return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
+        }
+
+        _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+        const_pointer data() const _NOEXCEPT { return __data; }
+
+        // [string.view.modifiers], modifiers:
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void clear() _NOEXCEPT
+        {
+            __data = nullptr;
+            __size = 0;
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void remove_prefix(size_type __n) _NOEXCEPT
+        {
+            if (__n > __size)
+                __n = __size;
+            __data += __n;
+            __size -= __n;
+        }
+            
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void remove_suffix(size_type __n) _NOEXCEPT
+        {
+            if (__n > __size)
+                __n = __size;
+            __size -= __n;
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        void swap(basic_string_view& __other) _NOEXCEPT
+        {
+            const value_type *__p = __data;
+            __data = __other.__data;
+            __other.__data = __p;
+            
+            size_type __sz = __size;
+            __size = __other.__size;
+            __other.__size = __sz;
+//             _VSTD::swap( __data, __other.__data );
+//             _VSTD::swap( __size, __other.__size );
+        }
+                    
+        // [string.view.ops], string operations:
+        template<class _Allocator>
+        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const
+        { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }
+        
+        template<class _Allocator = allocator<_CharT> >
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string<_CharT, _Traits, _Allocator> to_string( const _Allocator& __a = _Allocator())
+        { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }
+
+        size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
+        {
+            if ( __pos > size())
+                throw out_of_range("string_view::copy");
+            size_type __rlen = _VSTD::min( __n, size() - __pos );
+            _VSTD::copy_n(begin() + __pos, __rlen, __s );
+            return __rlen;
+        }
+        
+        _LIBCPP_CONSTEXPR
+        basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
+        {
+//             if (__pos > size())
+//                 throw out_of_range("string_view::substr");
+//             size_type __rlen = _VSTD::min( __n, size() - __pos );
+//             return basic_string_view(data() + __pos, __rlen);
+			return __pos > size()
+			       ? throw out_of_range("string_view::substr")
+			       : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
+        {
+            size_type __rlen = _VSTD::min( size(), __sv.size());
+            int __retval = _Traits::compare(data(), __sv.data(), __rlen);
+            if ( __retval == 0 ) // first __rlen chars matched
+                __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
+            return __retval;
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
+        {
+            return substr(__pos1, __n1).compare(__sv);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(                       size_type __pos1, size_type __n1, 
+                    basic_string_view _sv, size_type __pos2, size_type __n2) const
+        {
+            return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(const _CharT* __s) const
+        {
+            return compare(basic_string_view(__s));
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
+        {
+            return substr(__pos1, __n1).compare(basic_string_view(__s));
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
+        {
+            return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
+        }
+
+        // find
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
+        {
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find(const _CharT* __s, size_type __pos = 0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // rfind
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
+        {
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type rfind(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr");
+            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_first_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+    
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
+        { return find(__c, __pos); }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_of(const _CharT* __s, size_type __pos=0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr");
+            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_last_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
+        { return rfind(__c, __pos); }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr");
+            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+        // find_first_not_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
+        {
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
+            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+        
+        // find_last_not_of
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
+        {
+            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s.data(), __pos, __s.size());
+        }       
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
+        {
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __c, __pos);
+        }
+        
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
+        {
+            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, __n);
+        }
+
+        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+        size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
+        {
+            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
+            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+                (data(), size(), __s, __pos, traits_type::length(__s));
+        }
+
+    private:   
+        const   value_type* __data;
+        size_type           __size;
+    };
+
+
+    // [string.view.comparison]
+    // operator ==
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size()) return false;
+        return __lhs.compare(__rhs) == 0;
+    }
+
+
+    // operator !=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+  
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        if ( __lhs.size() != __rhs.size())
+            return true;
+        return __lhs.compare(__rhs) != 0;
+    }
+
+
+    // operator <
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) < 0;
+    }
+
+
+    // operator >
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) > 0;
+    }
+
+
+    // operator <=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) <= 0;
+    }
+
+
+    // operator >=
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
+                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+    template<class _CharT, class _Traits>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
+                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
+    {
+        return __lhs.compare(__rhs) >= 0;
+    }
+
+
+    // [string.view.io]
+    template<class _CharT, class _Traits>
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
+    {
+        return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());
+    }
+
+  typedef basic_string_view<char>     string_view;
+  typedef basic_string_view<char16_t> u16string_view;
+  typedef basic_string_view<char32_t> u32string_view;
+  typedef basic_string_view<wchar_t>  wstring_view;
+
+_LIBCPP_END_NAMESPACE_LFTS
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// [string.view.hash]
+// Shamelessly stolen from <string>
+template<class _CharT, class _Traits>
+struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::basic_string_view<_CharT, _Traits> >
+    : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t>
+{
+    size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;
+};
+
+template<class _CharT, class _Traits>
+size_t
+hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(
+        const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT
+{
+    return __do_string_hash(__val.data(), __val.data() + __val.size());
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _CharT, class _Traits>
+__quoted_output_proxy<_CharT, const _CharT *, _Traits>
+quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,
+             _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_output_proxy<_CharT, const _CharT *, _Traits> 
+         ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_LFTS_STRING_VIEW
diff --git a/include/c++/v1/experimental/utility b/include/c++/v1/experimental/utility
new file mode 100644
index 0000000..12a7d05
--- /dev/null
+++ b/include/c++/v1/experimental/utility
@@ -0,0 +1,48 @@
+// -*- C++ -*-
+//===-------------------------- utility ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_UTILITY
+#define _LIBCPP_EXPERIMENTAL_UTILITY
+
+/*
+    experimental/utility synopsis
+
+// C++1y
+
+#include <utility>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+  3.1.2, erased-type placeholder
+  struct erased_type { };
+
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+ */
+
+# include <experimental/__config>
+
+#if _LIBCPP_STD_VER > 11
+
+# include <utility>
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+  struct _LIBCPP_TYPE_VIS_ONLY erased_type { };
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_STD_VER > 11 */
+
+#endif /* _LIBCPP_EXPERIMENTAL_UTILITY */
diff --git a/include/c++/v1/ext/__hash b/include/c++/v1/ext/__hash
new file mode 100644
index 0000000..5675d54
--- /dev/null
+++ b/include/c++/v1/ext/__hash
@@ -0,0 +1,135 @@
+// -*- C++ -*-
+//===------------------------- hash_set ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXT_HASH
+#define _LIBCPP_EXT_HASH
+
+#pragma GCC system_header
+
+#include <string>
+#include <cstring>
+
+namespace __gnu_cxx {
+using namespace std;
+
+template <typename _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash { };
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<const char*>
+    : public unary_function<const char*, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const char *__c) const _NOEXCEPT
+    {
+        return __do_string_hash(__c, __c + strlen(__c));
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<char *>
+    : public unary_function<char*, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char *__c) const _NOEXCEPT
+    {
+        return __do_string_hash<const char *>(__c, __c + strlen(__c));
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<char>
+    : public unary_function<char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<signed char>
+    : public unary_function<signed char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(signed char __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned char>
+    : public unary_function<unsigned char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned char __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<short>
+    : public unary_function<short, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(short __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned short>
+    : public unary_function<unsigned short, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned short __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<int>
+    : public unary_function<int, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(int __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned int>
+    : public unary_function<unsigned int, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned int __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<long>
+    : public unary_function<long, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(long __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long>
+    : public unary_function<unsigned long, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned long __c) const _NOEXCEPT
+    {
+        return __c;
+    }
+};
+}
+
+#endif  // _LIBCPP_EXT_HASH
diff --git a/include/c++/v1/ext/hash_map b/include/c++/v1/ext/hash_map
new file mode 100644
index 0000000..36cd595
--- /dev/null
+++ b/include/c++/v1/ext/hash_map
@@ -0,0 +1,1007 @@
+// -*- C++ -*-
+//===-------------------------- hash_map ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_HASH_MAP
+#define _LIBCPP_HASH_MAP
+
+/*
+
+    hash_map synopsis
+
+namespace __gnu_cxx
+{
+
+template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+          class Alloc = allocator<pair<const Key, T>>>
+class hash_map
+{
+public:
+    // types
+    typedef Key                                                        key_type;
+    typedef T                                                          mapped_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef pair<const key_type, mapped_type>                          value_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+
+    explicit hash_map(size_type n = 193, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        hash_map(InputIterator f, InputIterator l,
+                      size_type n = 193, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    hash_map(const hash_map&);
+    ~hash_map();
+    hash_map& operator=(const hash_map&);
+
+    allocator_type get_allocator() const;
+
+    bool      empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    iterator       begin();
+    iterator       end();
+    const_iterator begin()  const;
+    const_iterator end()    const;
+
+    pair<iterator, bool> insert(const value_type& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+
+    void erase(const_iterator position);
+    size_type erase(const key_type& k);
+    void erase(const_iterator first, const_iterator last);
+    void clear();
+
+    void swap(hash_map&);
+
+    hasher hash_funct() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    mapped_type& operator[](const key_type& k);
+
+    size_type bucket_count() const;
+    size_type max_bucket_count() const;
+
+    size_type elems_in_bucket(size_type n) const;
+
+    void resize(size_type n);
+};
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    void swap(hash_map<Key, T, Hash, Pred, Alloc>& x,
+              hash_map<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const hash_map<Key, T, Hash, Pred, Alloc>& x,
+               const hash_map<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const hash_map<Key, T, Hash, Pred, Alloc>& x,
+               const hash_map<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+          class Alloc = allocator<pair<const Key, T>>>
+class hash_multimap
+{
+public:
+    // types
+    typedef Key                                                        key_type;
+    typedef T                                                          mapped_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef pair<const key_type, mapped_type>                          value_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+
+    explicit hash_multimap(size_type n = 193, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        hash_multimap(InputIterator f, InputIterator l,
+                      size_type n = 193, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    explicit hash_multimap(const allocator_type&);
+    hash_multimap(const hash_multimap&);
+    ~hash_multimap();
+    hash_multimap& operator=(const hash_multimap&);
+
+    allocator_type get_allocator() const;
+
+    bool      empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    iterator       begin();
+    iterator       end();
+    const_iterator begin()  const;
+    const_iterator end()    const;
+
+    iterator insert(const value_type& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+
+    void erase(const_iterator position);
+    size_type erase(const key_type& k);
+    void erase(const_iterator first, const_iterator last);
+    void clear();
+
+    void swap(hash_multimap&);
+
+    hasher hash_funct() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const;
+    size_type max_bucket_count() const;
+
+    size_type elems_in_bucket(size_type n) const;
+
+    void resize(size_type n);
+};
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    void swap(hash_multimap<Key, T, Hash, Pred, Alloc>& x,
+              hash_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
+               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const hash_multimap<Key, T, Hash, Pred, Alloc>& x,
+               const hash_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+}  // __gnu_cxx
+
+*/
+
+#include <__config>
+#include <__hash_table>
+#include <functional>
+#include <stdexcept>
+#include <ext/__hash>
+
+#if __DEPRECATED
+#if defined(_MSC_VER) && ! defined(__clang__)
+    _LIBCPP_WARNING("Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>")
+#else
+#   warning Use of the header <ext/hash_map> is deprecated.  Migrate to <unordered_map>
+#endif
+#endif
+
+#pragma GCC system_header
+
+namespace __gnu_cxx {
+
+using namespace std;
+
+template <class _Tp, class _Hash, bool = is_empty<_Hash>::value
+#if __has_feature(is_final)
+                                         && !__is_final(_Hash)
+#endif
+        >
+class __hash_map_hasher
+    : private _Hash
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : _Hash() {}
+    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : _Hash(__h) {}
+    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Tp& __x) const
+        {return static_cast<const _Hash&>(*this)(__x.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const typename _Tp::first_type& __x) const
+        {return static_cast<const _Hash&>(*this)(__x);}
+};
+
+template <class _Tp, class _Hash>
+class __hash_map_hasher<_Tp, _Hash, false>
+{
+    _Hash __hash_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher() : __hash_() {}
+    _LIBCPP_INLINE_VISIBILITY __hash_map_hasher(const _Hash& __h) : __hash_(__h) {}
+    _LIBCPP_INLINE_VISIBILITY const _Hash& hash_function() const {return __hash_;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Tp& __x) const
+        {return __hash_(__x.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const typename _Tp::first_type& __x) const
+        {return __hash_(__x);}
+};
+
+template <class _Tp, class _Pred, bool = is_empty<_Pred>::value
+#if __has_feature(is_final)
+                                         && !__is_final(_Pred)
+#endif
+         >
+class __hash_map_equal
+    : private _Pred
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : _Pred() {}
+    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : _Pred(__p) {}
+    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return static_cast<const _Pred&>(*this)(__x.first, __y.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
+        {return static_cast<const _Pred&>(*this)(__x, __y.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
+        {return static_cast<const _Pred&>(*this)(__x.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Tp::first_type& __x,
+                    const typename _Tp::first_type& __y) const
+        {return static_cast<const _Pred&>(*this)(__x, __y);}
+};
+
+template <class _Tp, class _Pred>
+class __hash_map_equal<_Tp, _Pred, false>
+{
+    _Pred __pred_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __hash_map_equal() : __pred_() {}
+    _LIBCPP_INLINE_VISIBILITY __hash_map_equal(const _Pred& __p) : __pred_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY const _Pred& key_eq() const {return __pred_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __pred_(__x.first, __y.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Tp::first_type& __x, const _Tp& __y) const
+        {return __pred_(__x, __y.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const typename _Tp::first_type& __y) const
+        {return __pred_(__x.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Tp::first_type& __x,
+                    const typename _Tp::first_type& __y) const
+        {return __pred_(__x, __y);}
+};
+
+template <class _Alloc>
+class __hash_map_node_destructor
+{
+    typedef _Alloc                              allocator_type;
+    typedef allocator_traits<allocator_type>    __alloc_traits;
+    typedef typename __alloc_traits::value_type::value_type value_type;
+public:
+    typedef typename __alloc_traits::pointer    pointer;
+private:
+    typedef typename value_type::first_type     first_type;
+    typedef typename value_type::second_type    second_type;
+
+    allocator_type& __na_;
+
+    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
+
+public:
+    bool __first_constructed;
+    bool __second_constructed;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __hash_map_node_destructor(allocator_type& __na)
+        : __na_(__na),
+          __first_constructed(false),
+          __second_constructed(false)
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
+        : __na_(__x.__na_),
+          __first_constructed(__x.__value_constructed),
+          __second_constructed(__x.__value_constructed)
+        {
+            __x.__value_constructed = false;
+        }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
+        : __na_(__x.__na_),
+          __first_constructed(__x.__value_constructed),
+          __second_constructed(__x.__value_constructed)
+        {
+            const_cast<bool&>(__x.__value_constructed) = false;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p)
+    {
+        if (__second_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.second));
+        if (__first_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.first));
+        if (__p)
+            __alloc_traits::deallocate(__na_, __p, 1);
+    }
+};
+
+template <class _HashIterator>
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator
+{
+    _HashIterator __i_;
+
+    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
+    typedef const typename _HashIterator::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::second_type      mapped_type;
+public:
+    typedef forward_iterator_tag                                 iterator_category;
+    typedef pair<key_type, mapped_type>                          value_type;
+    typedef typename _HashIterator::difference_type              difference_type;
+    typedef value_type&                                          reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() {}
+
+    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator(_HashIterator __i) : __i_(__i) {}
+
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return (pointer)__i_.operator->();}
+
+    _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_iterator operator++(int)
+    {
+        __hash_map_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY 
+    bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend _LIBCPP_INLINE_VISIBILITY 
+    bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+};
+
+template <class _HashIterator>
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator
+{
+    _HashIterator __i_;
+
+    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
+    typedef const typename _HashIterator::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::second_type      mapped_type;
+public:
+    typedef forward_iterator_tag                                 iterator_category;
+    typedef pair<key_type, mapped_type>                          value_type;
+    typedef typename _HashIterator::difference_type              difference_type;
+    typedef const value_type&                                    reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator(
+            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
+                : __i_(__i.__i_) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return *operator->();}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return (pointer)__i_.operator->();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator operator++(int)
+    {
+        __hash_map_const_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY hash_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+};
+
+template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
+          class _Alloc = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY hash_map
+{
+public:
+    // types
+    typedef _Key                                           key_type;
+    typedef _Tp                                            mapped_type;
+    typedef _Tp                                            data_type;
+    typedef _Hash                                          hasher;
+    typedef _Pred                                          key_equal;
+    typedef _Alloc                                         allocator_type;
+    typedef pair<const key_type, mapped_type>              value_type;
+    typedef value_type&                                    reference;
+    typedef const value_type&                              const_reference;
+
+private:
+    typedef pair<key_type, mapped_type>                    __value_type;
+    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
+    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                           __allocator_type;
+
+    typedef __hash_table<__value_type, __hasher,
+                         __key_equal,  __allocator_type>   __table;
+
+    __table __table_;
+
+    typedef typename __table::__node_pointer               __node_pointer;
+    typedef typename __table::__node_const_pointer         __node_const_pointer;
+    typedef typename __table::__node_traits                __node_traits;
+    typedef typename __table::__node_allocator             __node_allocator;
+    typedef typename __table::__node                       __node;
+    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
+    typedef unique_ptr<__node, _Dp>                         __node_holder;
+    typedef allocator_traits<allocator_type>               __alloc_traits;
+public:
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+
+    typedef __hash_map_iterator<typename __table::iterator>       iterator;
+    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);}
+    explicit hash_map(size_type __n, const hasher& __hf = hasher(),
+                           const key_equal& __eql = key_equal());
+    hash_map(size_type __n, const hasher& __hf,
+                  const key_equal& __eql,
+                  const allocator_type& __a);
+    template <class _InputIterator>
+        hash_map(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        hash_map(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        hash_map(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf,
+                      const key_equal& __eql,
+                      const allocator_type& __a);
+    hash_map(const hash_map& __u);
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin()        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end()          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const {return __table_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> insert(const value_type& __x)
+        {return __table_.__insert_unique(__x);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __first, const_iterator __last)
+        {__table_.erase(__first.__i_, __last.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(hash_map& __u) {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_funct() const
+        {return __table_.hash_function().hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const
+        {return __table_.key_eq().key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_unique(__k);}
+
+    mapped_type& operator[](const key_type& __k);
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type elems_in_bucket(size_type __n) const
+        {return __table_.bucket_size(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void resize(size_type __n) {__table_.rehash(__n);}
+
+private:
+    __node_holder __construct_node(const key_type& __k);
+};
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        _InputIterator __first, _InputIterator __last)
+{
+    __table_.rehash(193);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map(
+        const hash_map& __u)
+    : __table_(__u.__table_)
+{
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.first), __k);
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
+    __h.get_deleter().__second_constructed = true;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                       _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_unique(*__first);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+_Tp&
+hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
+{
+    iterator __i = find(__k);
+    if (__i != end())
+        return __i->second;
+    __node_holder __h = __construct_node(__k);
+    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
+    __h.release();
+    return __r.first->second;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+     hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
+            __i != __ex; ++__i)
+    {
+        const_iterator __j = __y.find(__i->first);
+        if (__j == __ey || !(*__i == *__j))
+            return false;
+    }
+    return true;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
+          class _Alloc = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY hash_multimap
+{
+public:
+    // types
+    typedef _Key                                           key_type;
+    typedef _Tp                                            mapped_type;
+    typedef _Tp                                            data_type;
+    typedef _Hash                                          hasher;
+    typedef _Pred                                          key_equal;
+    typedef _Alloc                                         allocator_type;
+    typedef pair<const key_type, mapped_type>              value_type;
+    typedef value_type&                                    reference;
+    typedef const value_type&                              const_reference;
+
+private:
+    typedef pair<key_type, mapped_type>                    __value_type;
+    typedef __hash_map_hasher<__value_type, hasher>   __hasher;
+    typedef __hash_map_equal<__value_type, key_equal> __key_equal;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                           __allocator_type;
+
+    typedef __hash_table<__value_type, __hasher,
+                         __key_equal,  __allocator_type>   __table;
+
+    __table __table_;
+
+    typedef typename __table::__node_traits                __node_traits;
+    typedef typename __table::__node_allocator             __node_allocator;
+    typedef typename __table::__node                       __node;
+    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
+    typedef unique_ptr<__node, _Dp>                         __node_holder;
+    typedef allocator_traits<allocator_type>               __alloc_traits;
+public:
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+
+    typedef __hash_map_iterator<typename __table::iterator>       iterator;
+    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    hash_multimap() {__table_.rehash(193);}
+    explicit hash_multimap(size_type __n, const hasher& __hf = hasher(),
+                                const key_equal& __eql = key_equal());
+    hash_multimap(size_type __n, const hasher& __hf,
+                                const key_equal& __eql,
+                                const allocator_type& __a);
+    template <class _InputIterator>
+        hash_multimap(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        hash_multimap(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        hash_multimap(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf,
+                      const key_equal& __eql,
+                      const allocator_type& __a);
+    hash_multimap(const hash_multimap& __u);
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin()        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end()          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const {return __table_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __p) {__table_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __first, const_iterator __last)
+        {__table_.erase(__first.__i_, __last.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(hash_multimap& __u) {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_funct() const
+        {return __table_.hash_function().hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const
+        {return __table_.key_eq().key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_multi(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type elems_in_bucket(size_type __n) const
+        {return __table_.bucket_size(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void resize(size_type __n) {__table_.rehash(__n);}
+};
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        _InputIterator __first, _InputIterator __last)
+{
+    __table_.rehash(193);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap(
+        const hash_multimap& __u)
+    : __table_(__u.__table_)
+{
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                            _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_multi(*__first);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+     hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    typedef pair<const_iterator, const_iterator> _EqRng;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
+    {
+        _EqRng __xeq = __x.equal_range(__i->first);
+        _EqRng __yeq = __y.equal_range(__i->first);
+        if (_VSTD::distance(__xeq.first, __xeq.second) !=
+            _VSTD::distance(__yeq.first, __yeq.second) ||
+                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
+            return false;
+        __i = __xeq.second;
+    }
+    return true;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+} // __gnu_cxx
+
+#endif  // _LIBCPP_HASH_MAP
diff --git a/include/c++/v1/ext/hash_set b/include/c++/v1/ext/hash_set
new file mode 100644
index 0000000..c4bb898
--- /dev/null
+++ b/include/c++/v1/ext/hash_set
@@ -0,0 +1,661 @@
+// -*- C++ -*-
+//===------------------------- hash_set ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_HASH_SET
+#define _LIBCPP_HASH_SET
+
+/*
+
+    hash_set synopsis
+
+namespace __gnu_cxx
+{
+
+template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+          class Alloc = allocator<Value>>
+class hash_set
+{
+public:
+    // types
+    typedef Value                                                      key_type;
+    typedef key_type                                                   value_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+
+    explicit hash_set(size_type n = 193, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        hash_set(InputIterator f, InputIterator l,
+                      size_type n = 193, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    hash_set(const hash_set&);
+    ~hash_set();
+    hash_set& operator=(const hash_set&);
+
+    allocator_type get_allocator() const;
+
+    bool      empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    iterator       begin();
+    iterator       end();
+    const_iterator begin()  const;
+    const_iterator end()    const;
+
+    pair<iterator, bool> insert(const value_type& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+
+    void erase(const_iterator position);
+    size_type erase(const key_type& k);
+    void erase(const_iterator first, const_iterator last);
+    void clear();
+
+    void swap(hash_set&);
+
+    hasher hash_funct() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const;
+    size_type max_bucket_count() const;
+
+    size_type elems_in_bucket(size_type n) const;
+
+    void resize(size_type n);
+};
+
+template <class Value, class Hash, class Pred, class Alloc>
+    void swap(hash_set<Value, Hash, Pred, Alloc>& x,
+              hash_set<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const hash_set<Value, Hash, Pred, Alloc>& x,
+               const hash_set<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const hash_set<Value, Hash, Pred, Alloc>& x,
+               const hash_set<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+          class Alloc = allocator<Value>>
+class hash_multiset
+{
+public:
+    // types
+    typedef Value                                                      key_type;
+    typedef key_type                                                   value_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+
+    explicit hash_multiset(size_type n = 193, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        hash_multiset(InputIterator f, InputIterator l,
+                      size_type n = 193, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    hash_multiset(const hash_multiset&);
+    ~hash_multiset();
+    hash_multiset& operator=(const hash_multiset&);
+
+    allocator_type get_allocator() const;
+
+    bool      empty() const;
+    size_type size() const;
+    size_type max_size() const;
+
+    iterator       begin();
+    iterator       end();
+    const_iterator begin()  const;
+    const_iterator end()    const;
+
+    iterator insert(const value_type& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+
+    void erase(const_iterator position);
+    size_type erase(const key_type& k);
+    void erase(const_iterator first, const_iterator last);
+    void clear();
+
+    void swap(hash_multiset&);
+
+    hasher hash_funct() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const;
+    size_type max_bucket_count() const;
+
+    size_type elems_in_bucket(size_type n) const;
+
+    void resize(size_type n);
+};
+
+template <class Value, class Hash, class Pred, class Alloc>
+    void swap(hash_multiset<Value, Hash, Pred, Alloc>& x,
+              hash_multiset<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const hash_multiset<Value, Hash, Pred, Alloc>& x,
+               const hash_multiset<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const hash_multiset<Value, Hash, Pred, Alloc>& x,
+               const hash_multiset<Value, Hash, Pred, Alloc>& y);
+}  // __gnu_cxx
+
+*/
+
+#include <__config>
+#include <__hash_table>
+#include <functional>
+#include <ext/__hash>
+
+#if __DEPRECATED
+#if defined(_MSC_VER) && ! defined(__clang__)
+    _LIBCPP_WARNING("Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>")
+#else
+#   warning Use of the header <ext/hash_set> is deprecated.  Migrate to <unordered_set>
+#endif
+#endif
+
+namespace __gnu_cxx {
+
+using namespace std;
+
+template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
+          class _Alloc = allocator<_Value> >
+class _LIBCPP_TYPE_VIS_ONLY hash_set
+{
+public:
+    // types
+    typedef _Value                                                     key_type;
+    typedef key_type                                                   value_type;
+    typedef _Hash                                                      hasher;
+    typedef _Pred                                                      key_equal;
+    typedef _Alloc                                                     allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+
+private:
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+
+    __table __table_;
+
+public:
+    typedef typename __table::pointer         pointer;
+    typedef typename __table::const_pointer   const_pointer;
+    typedef typename __table::size_type       size_type;
+    typedef typename __table::difference_type difference_type;
+
+    typedef typename __table::const_iterator       iterator;
+    typedef typename __table::const_iterator       const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    hash_set() {__table_.rehash(193);}
+    explicit hash_set(size_type __n, const hasher& __hf = hasher(),
+                           const key_equal& __eql = key_equal());
+    hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+                  const allocator_type& __a);
+    template <class _InputIterator>
+        hash_set(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        hash_set(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        hash_set(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf, const key_equal& __eql,
+                      const allocator_type& __a);
+    hash_set(const hash_set& __u);
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin()        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end()          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const {return __table_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> insert(const value_type& __x)
+        {return __table_.__insert_unique(__x);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;}
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __p) {__table_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __first, const_iterator __last)
+        {__table_.erase(__first, __last);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(hash_set& __u) {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_funct() const {return __table_.hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const {return __table_.key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_unique(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void resize(size_type __n) {__table_.rehash(__n);}
+};
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
+        _InputIterator __first, _InputIterator __last)
+{
+    __table_.rehash(193);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set(
+        const hash_set& __u)
+    : __table_(__u.__table_)
+{
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                    _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_unique(*__first);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
+     hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
+           const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename hash_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
+            __i != __ex; ++__i)
+    {
+        const_iterator __j = __y.find(*__i);
+        if (__j == __ey || !(*__i == *__j))
+            return false;
+    }
+    return true;
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const hash_set<_Value, _Hash, _Pred, _Alloc>& __x,
+           const hash_set<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
+          class _Alloc = allocator<_Value> >
+class _LIBCPP_TYPE_VIS_ONLY hash_multiset
+{
+public:
+    // types
+    typedef _Value                                                     key_type;
+    typedef key_type                                                   value_type;
+    typedef _Hash                                                      hasher;
+    typedef _Pred                                                      key_equal;
+    typedef _Alloc                                                     allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+
+private:
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+
+    __table __table_;
+
+public:
+    typedef typename __table::pointer         pointer;
+    typedef typename __table::const_pointer   const_pointer;
+    typedef typename __table::size_type       size_type;
+    typedef typename __table::difference_type difference_type;
+
+    typedef typename __table::const_iterator       iterator;
+    typedef typename __table::const_iterator       const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    hash_multiset() {__table_.rehash(193);}
+    explicit hash_multiset(size_type __n, const hasher& __hf = hasher(),
+                                const key_equal& __eql = key_equal());
+    hash_multiset(size_type __n, const hasher& __hf,
+                       const key_equal& __eql, const allocator_type& __a);
+    template <class _InputIterator>
+        hash_multiset(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        hash_multiset(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        hash_multiset(_InputIterator __first, _InputIterator __last,
+                      size_type __n , const hasher& __hf,
+                      const key_equal& __eql, const allocator_type& __a);
+    hash_multiset(const hash_multiset& __u);
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin()        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end()          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const {return __table_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator, const value_type& __x) {return insert(__x);}
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __p) {__table_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    void erase(const_iterator __first, const_iterator __last)
+        {__table_.erase(__first, __last);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(hash_multiset& __u) {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_funct() const {return __table_.hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const {return __table_.key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_multi(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type elems_in_bucket(size_type __n) const {return __table_.bucket_size(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void resize(size_type __n) {__table_.rehash(__n);}
+};
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        _InputIterator __first, _InputIterator __last)
+{
+    __table_.rehash(193);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset(
+        const hash_multiset& __u)
+    : __table_(__u.__table_)
+{
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                         _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_multi(*__first);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+     hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+           const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename hash_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    typedef pair<const_iterator, const_iterator> _EqRng;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
+    {
+        _EqRng __xeq = __x.equal_range(*__i);
+        _EqRng __yeq = __y.equal_range(*__i);
+        if (_VSTD::distance(__xeq.first, __xeq.second) !=
+            _VSTD::distance(__yeq.first, __yeq.second) ||
+                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
+            return false;
+        __i = __xeq.second;
+    }
+    return true;
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+           const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+} // __gnu_cxx
+
+#endif  // _LIBCPP_HASH_SET
diff --git a/include/c++/v1/forward_list b/include/c++/v1/forward_list
new file mode 100644
index 0000000..72d31dc
--- /dev/null
+++ b/include/c++/v1/forward_list
@@ -0,0 +1,1668 @@
+// -*- C++ -*-
+//===----------------------- forward_list ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FORWARD_LIST
+#define _LIBCPP_FORWARD_LIST
+
+/*
+    forward_list synopsis
+
+namespace std
+{
+
+template <class T, class Allocator = allocator<T>>
+class forward_list
+{
+public:
+    typedef T         value_type;
+    typedef Allocator allocator_type;
+
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef <details> iterator;
+    typedef <details> const_iterator;
+
+    forward_list()
+        noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit forward_list(const allocator_type& a);
+    explicit forward_list(size_type n);
+    explicit forward_list(size_type n, const allocator_type& a); // C++14
+    forward_list(size_type n, const value_type& v);
+    forward_list(size_type n, const value_type& v, const allocator_type& a);
+    template <class InputIterator>
+        forward_list(InputIterator first, InputIterator last);
+    template <class InputIterator>
+        forward_list(InputIterator first, InputIterator last, const allocator_type& a);
+    forward_list(const forward_list& x);
+    forward_list(const forward_list& x, const allocator_type& a);
+    forward_list(forward_list&& x)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    forward_list(forward_list&& x, const allocator_type& a);
+    forward_list(initializer_list<value_type> il);
+    forward_list(initializer_list<value_type> il, const allocator_type& a);
+
+    ~forward_list();
+
+    forward_list& operator=(const forward_list& x);
+    forward_list& operator=(forward_list&& x)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    forward_list& operator=(initializer_list<value_type> il);
+
+    template <class InputIterator>
+        void assign(InputIterator first, InputIterator last);
+    void assign(size_type n, const value_type& v);
+    void assign(initializer_list<value_type> il);
+
+    allocator_type get_allocator() const noexcept;
+
+    iterator       begin() noexcept;
+    const_iterator begin() const noexcept;
+    iterator       end() noexcept;
+    const_iterator end() const noexcept;
+
+    const_iterator cbegin() const noexcept;
+    const_iterator cend() const noexcept;
+
+    iterator       before_begin() noexcept;
+    const_iterator before_begin() const noexcept;
+    const_iterator cbefore_begin() const noexcept;
+
+    bool empty() const noexcept;
+    size_type max_size() const noexcept;
+
+    reference       front();
+    const_reference front() const;
+
+    template <class... Args> void emplace_front(Args&&... args);
+    void push_front(const value_type& v);
+    void push_front(value_type&& v);
+
+    void pop_front();
+
+    template <class... Args>
+        iterator emplace_after(const_iterator p, Args&&... args);
+    iterator insert_after(const_iterator p, const value_type& v);
+    iterator insert_after(const_iterator p, value_type&& v);
+    iterator insert_after(const_iterator p, size_type n, const value_type& v);
+    template <class InputIterator>
+        iterator insert_after(const_iterator p,
+                              InputIterator first, InputIterator last);
+    iterator insert_after(const_iterator p, initializer_list<value_type> il);
+
+    iterator erase_after(const_iterator p);
+    iterator erase_after(const_iterator first, const_iterator last);
+
+    void swap(forward_list& x)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value);
+
+    void resize(size_type n);
+    void resize(size_type n, const value_type& v);
+    void clear() noexcept;
+
+    void splice_after(const_iterator p, forward_list& x);
+    void splice_after(const_iterator p, forward_list&& x);
+    void splice_after(const_iterator p, forward_list& x, const_iterator i);
+    void splice_after(const_iterator p, forward_list&& x, const_iterator i);
+    void splice_after(const_iterator p, forward_list& x,
+                      const_iterator first, const_iterator last);
+    void splice_after(const_iterator p, forward_list&& x,
+                      const_iterator first, const_iterator last);
+    void remove(const value_type& v);
+    template <class Predicate> void remove_if(Predicate pred);
+    void unique();
+    template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
+    void merge(forward_list& x);
+    void merge(forward_list&& x);
+    template <class Compare> void merge(forward_list& x, Compare comp);
+    template <class Compare> void merge(forward_list&& x, Compare comp);
+    void sort();
+    template <class Compare> void sort(Compare comp);
+    void reverse() noexcept;
+};
+
+template <class T, class Allocator>
+    bool operator==(const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    bool operator< (const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    bool operator!=(const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    bool operator> (const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    bool operator>=(const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    bool operator<=(const forward_list<T, Allocator>& x,
+                    const forward_list<T, Allocator>& y);
+
+template <class T, class Allocator>
+    void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y)
+         noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+
+#include <initializer_list>
+#include <memory>
+#include <limits>
+#include <iterator>
+#include <algorithm>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _VoidPtr> struct __forward_list_node;
+
+template <class _NodePtr>
+struct __forward_begin_node
+{
+    typedef _NodePtr pointer;
+
+    pointer __next_;
+
+     _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {}
+};
+
+template <class _Tp, class _VoidPtr>
+struct _LIBCPP_HIDDEN __begin_node_of
+{
+    typedef __forward_begin_node
+        <
+             typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                 rebind<__forward_list_node<_Tp, _VoidPtr> >
+#else
+                 rebind<__forward_list_node<_Tp, _VoidPtr> >::other
+#endif
+         > type;
+};
+
+template <class _Tp, class _VoidPtr>
+struct __forward_list_node
+    : public __begin_node_of<_Tp, _VoidPtr>::type
+{
+    typedef _Tp value_type;
+
+    value_type __value_;
+};
+
+template<class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY forward_list;
+template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
+
+template <class _NodePtr>
+class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator
+{
+    typedef _NodePtr __node_pointer;
+
+    __node_pointer __ptr_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+
+    template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list;
+    template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator;
+
+public:
+    typedef forward_iterator_tag                              iterator_category;
+    typedef typename pointer_traits<__node_pointer>::element_type::value_type
+                                                              value_type;
+    typedef value_type&                                       reference;
+    typedef typename pointer_traits<__node_pointer>::difference_type
+                                                              difference_type;
+    typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                                              pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_iterator& operator++()
+    {
+        __ptr_ = __ptr_->__next_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_iterator operator++(int)
+    {
+        __forward_list_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __forward_list_iterator& __x,
+                    const __forward_list_iterator& __y)
+        {return __x.__ptr_ == __y.__ptr_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __forward_list_iterator& __x,
+                    const __forward_list_iterator& __y)
+        {return !(__x == __y);}
+};
+
+template <class _NodeConstPtr>
+class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator
+{
+    typedef _NodeConstPtr __node_const_pointer;
+
+    __node_const_pointer __ptr_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT
+        : __ptr_(__p) {}
+
+    typedef typename remove_const
+        <
+            typename pointer_traits<__node_const_pointer>::element_type
+        >::type                                               __node;
+    typedef typename pointer_traits<__node_const_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<__node>
+#else
+            rebind<__node>::other
+#endif
+                                                              __node_pointer;
+
+    template<class, class> friend class forward_list;
+
+public:
+    typedef forward_iterator_tag                              iterator_category;
+    typedef typename __node::value_type                       value_type;
+    typedef const value_type&                                 reference;
+    typedef typename pointer_traits<__node_const_pointer>::difference_type
+                                                              difference_type;
+    typedef typename pointer_traits<__node_const_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                              pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_const_iterator(__forward_list_iterator<__node_pointer> __p) _NOEXCEPT
+        : __ptr_(__p.__ptr_) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __ptr_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_const_iterator& operator++()
+    {
+        __ptr_ = __ptr_->__next_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_const_iterator operator++(int)
+    {
+        __forward_list_const_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __forward_list_const_iterator& __x,
+                    const __forward_list_const_iterator& __y)
+        {return __x.__ptr_ == __y.__ptr_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __forward_list_const_iterator& __x,
+                           const __forward_list_const_iterator& __y)
+        {return !(__x == __y);}
+};
+
+template <class _Tp, class _Alloc>
+class __forward_list_base
+{
+protected:
+    typedef _Tp    value_type;
+    typedef _Alloc allocator_type;
+
+    typedef typename allocator_traits<allocator_type>::void_pointer  void_pointer;
+    typedef __forward_list_node<value_type, void_pointer>            __node;
+    typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__node>
+#else
+                rebind_alloc<__node>::other
+#endif
+                                                      __node_allocator;
+    typedef allocator_traits<__node_allocator>        __node_traits;
+    typedef typename __node_traits::pointer           __node_pointer;
+    typedef typename __node_traits::pointer           __node_const_pointer;
+
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__begin_node>
+#else
+                rebind_alloc<__begin_node>::other
+#endif
+                                                      __begin_node_allocator;
+    typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
+
+    __compressed_pair<__begin_node, __node_allocator> __before_begin_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node_pointer        __before_begin() _NOEXCEPT
+        {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(__before_begin_.first()));}
+    _LIBCPP_INLINE_VISIBILITY
+    __node_const_pointer  __before_begin() const _NOEXCEPT
+        {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(const_cast<__begin_node&>(__before_begin_.first())));}
+
+    _LIBCPP_INLINE_VISIBILITY
+          __node_allocator& __alloc() _NOEXCEPT
+            {return __before_begin_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const __node_allocator& __alloc() const _NOEXCEPT
+        {return __before_begin_.second();}
+
+    typedef __forward_list_iterator<__node_pointer>             iterator;
+    typedef __forward_list_const_iterator<__node_pointer>       const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_base()
+        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
+        : __before_begin_(__begin_node()) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __forward_list_base(const allocator_type& __a)
+        : __before_begin_(__begin_node(), __node_allocator(__a)) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+public:
+    __forward_list_base(__forward_list_base&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
+    __forward_list_base(__forward_list_base&& __x, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+private:
+    __forward_list_base(const __forward_list_base&);
+    __forward_list_base& operator=(const __forward_list_base&);
+
+public:
+    ~__forward_list_base();
+
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __forward_list_base& __x)
+        {__copy_assign_alloc(__x, integral_constant<bool,
+              __node_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__forward_list_base& __x)
+        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
+                   is_nothrow_move_assignable<__node_allocator>::value)
+        {__move_assign_alloc(__x, integral_constant<bool,
+              __node_traits::propagate_on_container_move_assignment::value>());}
+
+public:
+    void swap(__forward_list_base& __x)
+        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value);
+protected:
+    void clear() _NOEXCEPT;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __forward_list_base&, false_type) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __forward_list_base& __x, true_type)
+    {
+        if (__alloc() != __x.__alloc())
+            clear();
+        __alloc() = __x.__alloc();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT
+        {}
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__forward_list_base& __x, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
+        {__alloc() = _VSTD::move(__x.__alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
+        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                         __node_traits::propagate_on_container_swap::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
+                                                                     false_type)
+        _NOEXCEPT
+        {}
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
+                                                                      true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
+    : __before_begin_(_VSTD::move(__x.__before_begin_))
+{
+    __x.__before_begin()->__next_ = nullptr;
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x,
+                                                      const allocator_type& __a)
+    : __before_begin_(__begin_node(), __node_allocator(__a))
+{
+    if (__alloc() == __x.__alloc())
+    {
+        __before_begin()->__next_ = __x.__before_begin()->__next_;
+        __x.__before_begin()->__next_ = nullptr;
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+__forward_list_base<_Tp, _Alloc>::~__forward_list_base()
+{
+    clear();
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
+        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+{
+    __swap_alloc(__alloc(), __x.__alloc());
+    using _VSTD::swap;
+    swap(__before_begin()->__next_, __x.__before_begin()->__next_);
+}
+
+template <class _Tp, class _Alloc>
+void
+__forward_list_base<_Tp, _Alloc>::clear() _NOEXCEPT
+{
+    __node_allocator& __a = __alloc();
+    for (__node_pointer __p = __before_begin()->__next_; __p != nullptr;)
+    {
+        __node_pointer __next = __p->__next_;
+        __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
+        __node_traits::deallocate(__a, __p, 1);
+        __p = __next;
+    }
+    __before_begin()->__next_ = nullptr;
+}
+
+template <class _Tp, class _Alloc = allocator<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY forward_list
+    : private __forward_list_base<_Tp, _Alloc>
+{
+    typedef __forward_list_base<_Tp, _Alloc> base;
+    typedef typename base::__node_allocator  __node_allocator;
+    typedef typename base::__node            __node;
+    typedef typename base::__node_traits     __node_traits;
+    typedef typename base::__node_pointer    __node_pointer;
+
+public:
+    typedef _Tp    value_type;
+    typedef _Alloc allocator_type;
+
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef typename base::iterator       iterator;
+    typedef typename base::const_iterator const_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    forward_list()
+        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
+        {} // = default;
+    explicit forward_list(const allocator_type& __a);
+    explicit forward_list(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit forward_list(size_type __n, const allocator_type& __a);
+#endif
+    forward_list(size_type __n, const value_type& __v);
+    forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
+    template <class _InputIterator>
+        forward_list(_InputIterator __f, _InputIterator __l,
+                     typename enable_if<
+                       __is_input_iterator<_InputIterator>::value
+                     >::type* = nullptr);
+    template <class _InputIterator>
+        forward_list(_InputIterator __f, _InputIterator __l,
+                     const allocator_type& __a,
+                     typename enable_if<
+                       __is_input_iterator<_InputIterator>::value
+                     >::type* = nullptr);
+    forward_list(const forward_list& __x);
+    forward_list(const forward_list& __x, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    forward_list(forward_list&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<base>::value)
+        : base(_VSTD::move(__x)) {}
+    forward_list(forward_list&& __x, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    forward_list(initializer_list<value_type> __il);
+    forward_list(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    // ~forward_list() = default;
+
+    forward_list& operator=(const forward_list& __x);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    forward_list& operator=(forward_list&& __x)
+        _NOEXCEPT_(
+             __node_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+#endif
+#ifndef  _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    forward_list& operator=(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template <class _InputIterator>
+        typename enable_if
+        <
+            __is_input_iterator<_InputIterator>::value,
+            void
+        >::type
+        assign(_InputIterator __f, _InputIterator __l);
+    void assign(size_type __n, const value_type& __v);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    void assign(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(base::__alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT
+        {return       iterator(base::__before_begin()->__next_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return const_iterator(base::__before_begin()->__next_);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT
+        {return       iterator(nullptr);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+        {return const_iterator(nullptr);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT
+        {return const_iterator(base::__before_begin()->__next_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT
+        {return const_iterator(nullptr);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       before_begin() _NOEXCEPT
+        {return       iterator(base::__before_begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator before_begin() const _NOEXCEPT
+        {return const_iterator(base::__before_begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbefore_begin() const _NOEXCEPT
+        {return const_iterator(base::__before_begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT
+        {return base::__before_begin()->__next_ == nullptr;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT
+        {return numeric_limits<size_type>::max();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference       front()       {return base::__before_begin()->__next_->__value_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference front() const {return base::__before_begin()->__next_->__value_;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args> void emplace_front(_Args&&... __args);
+#endif
+    void push_front(value_type&& __v);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void push_front(const value_type& __v);
+
+    void pop_front();
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        iterator emplace_after(const_iterator __p, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+    iterator insert_after(const_iterator __p, value_type&& __v);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    iterator insert_after(const_iterator __p, const value_type& __v);
+    iterator insert_after(const_iterator __p, size_type __n, const value_type& __v);
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_input_iterator<_InputIterator>::value,
+            iterator
+        >::type
+        insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    iterator insert_after(const_iterator __p, initializer_list<value_type> __il)
+        {return insert_after(__p, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    iterator erase_after(const_iterator __p);
+    iterator erase_after(const_iterator __f, const_iterator __l);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(forward_list& __x)
+        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+        {base::swap(__x);}
+
+    void resize(size_type __n);
+    void resize(size_type __n, const value_type& __v);
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {base::clear();}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void splice_after(const_iterator __p, forward_list&& __x);
+    _LIBCPP_INLINE_VISIBILITY
+    void splice_after(const_iterator __p, forward_list&& __x, const_iterator __i);
+    _LIBCPP_INLINE_VISIBILITY
+    void splice_after(const_iterator __p, forward_list&& __x,
+                      const_iterator __f, const_iterator __l);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void splice_after(const_iterator __p, forward_list& __x);
+    void splice_after(const_iterator __p, forward_list& __x, const_iterator __i);
+    void splice_after(const_iterator __p, forward_list& __x,
+                      const_iterator __f, const_iterator __l);
+    void remove(const value_type& __v);
+    template <class _Predicate> void remove_if(_Predicate __pred);
+    _LIBCPP_INLINE_VISIBILITY
+    void unique() {unique(__equal_to<value_type>());}
+    template <class _BinaryPredicate> void unique(_BinaryPredicate __binary_pred);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void merge(forward_list&& __x) {merge(__x, __less<value_type>());}
+    template <class _Compare>
+        _LIBCPP_INLINE_VISIBILITY
+        void merge(forward_list&& __x, _Compare __comp)
+        {merge(__x, _VSTD::move(__comp));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void merge(forward_list& __x) {merge(__x, __less<value_type>());}
+    template <class _Compare> void merge(forward_list& __x, _Compare __comp);
+    _LIBCPP_INLINE_VISIBILITY
+    void sort() {sort(__less<value_type>());}
+    template <class _Compare> void sort(_Compare __comp);
+    void reverse() _NOEXCEPT;
+
+private:
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void __move_assign(forward_list& __x, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+    void __move_assign(forward_list& __x, false_type);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class _Compare>
+        static
+        __node_pointer
+        __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp);
+
+    template <class _Compare>
+        static
+        __node_pointer
+        __sort(__node_pointer __f, difference_type __sz, _Compare& __comp);
+};
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a)
+    : base(__a)
+{
+}
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(size_type __n)
+{
+    if (__n > 0)
+    {
+        __node_allocator& __a = base::__alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
+        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
+                                                             __p = __p->__next_)
+        {
+            __h.reset(__node_traits::allocate(__a, 1));
+            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
+            __h->__next_ = nullptr;
+            __p->__next_ = __h.release();
+        }
+    }
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a)
+    : base ( __a )
+{
+    if (__n > 0)
+    {
+        __node_allocator& __a = base::__alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
+        for (__node_pointer __p = base::__before_begin(); __n > 0; --__n,
+                                                             __p = __p->__next_)
+        {
+            __h.reset(__node_traits::allocate(__a, 1));
+            __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
+            __h->__next_ = nullptr;
+            __p->__next_ = __h.release();
+        }
+    }
+}
+#endif
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
+{
+    insert_after(cbefore_begin(), __n, __v);
+}
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
+                                        const allocator_type& __a)
+    : base(__a)
+{
+    insert_after(cbefore_begin(), __n, __v);
+}
+
+template <class _Tp, class _Alloc>
+template <class _InputIterator>
+forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
+                                        typename enable_if<
+                                          __is_input_iterator<_InputIterator>::value
+                                        >::type*)
+{
+    insert_after(cbefore_begin(), __f, __l);
+}
+
+template <class _Tp, class _Alloc>
+template <class _InputIterator>
+forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
+                                        const allocator_type& __a,
+                                        typename enable_if<
+                                          __is_input_iterator<_InputIterator>::value
+                                        >::type*)
+    : base(__a)
+{
+    insert_after(cbefore_begin(), __f, __l);
+}
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x)
+    : base(allocator_type(
+             __node_traits::select_on_container_copy_construction(__x.__alloc())
+                         )
+          )
+{
+    insert_after(cbefore_begin(), __x.begin(), __x.end());
+}
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(const forward_list& __x,
+                                        const allocator_type& __a)
+    : base(__a)
+{
+    insert_after(cbefore_begin(), __x.begin(), __x.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(forward_list&& __x,
+                                        const allocator_type& __a)
+    : base(_VSTD::move(__x), __a)
+{
+    if (base::__alloc() != __x.__alloc())
+    {
+        typedef move_iterator<iterator> _Ip;
+        insert_after(cbefore_begin(), _Ip(__x.begin()), _Ip(__x.end()));
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il)
+{
+    insert_after(cbefore_begin(), __il.begin(), __il.end());
+}
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>::forward_list(initializer_list<value_type> __il,
+                                        const allocator_type& __a)
+    : base(__a)
+{
+    insert_after(cbefore_begin(), __il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+forward_list<_Tp, _Alloc>&
+forward_list<_Tp, _Alloc>::operator=(const forward_list& __x)
+{
+    if (this != &__x)
+    {
+        base::__copy_assign_alloc(__x);
+        assign(__x.begin(), __x.end());
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+{
+    clear();
+    base::__move_assign_alloc(__x);
+    base::__before_begin()->__next_ = __x.__before_begin()->__next_;
+    __x.__before_begin()->__next_ = nullptr;
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type)
+{
+    if (base::__alloc() == __x.__alloc())
+        __move_assign(__x, true_type());
+    else
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__x.begin()), _Ip(__x.end()));
+    }
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+forward_list<_Tp, _Alloc>&
+forward_list<_Tp, _Alloc>::operator=(forward_list&& __x)
+    _NOEXCEPT_(
+             __node_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value)
+{
+    __move_assign(__x, integral_constant<bool,
+          __node_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+forward_list<_Tp, _Alloc>&
+forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il)
+{
+    assign(__il.begin(), __il.end());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+template <class _InputIterator>
+typename enable_if
+<
+    __is_input_iterator<_InputIterator>::value,
+    void
+>::type
+forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l)
+{
+    iterator __i = before_begin();
+    iterator __j = _VSTD::next(__i);
+    iterator __e = end();
+    for (; __j != __e && __f != __l; ++__i, ++__j, ++__f)
+        *__j = *__f;
+    if (__j == __e)
+        insert_after(__i, __f, __l);
+    else
+        erase_after(__i, __e);
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v)
+{
+    iterator __i = before_begin();
+    iterator __j = _VSTD::next(__i);
+    iterator __e = end();
+    for (; __j != __e && __n > 0; --__n, ++__i, ++__j)
+        *__j = __v;
+    if (__j == __e)
+        insert_after(__i, __n, __v);
+    else
+        erase_after(__i, __e);
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il)
+{
+    assign(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+template <class... _Args>
+void
+forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
+{
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
+                                  _VSTD::forward<_Args>(__args)...);
+    __h->__next_ = base::__before_begin()->__next_;
+    base::__before_begin()->__next_ = __h.release();
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::push_front(value_type&& __v)
+{
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
+    __h->__next_ = base::__before_begin()->__next_;
+    base::__before_begin()->__next_ = __h.release();
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::push_front(const value_type& __v)
+{
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
+    __h->__next_ = base::__before_begin()->__next_;
+    base::__before_begin()->__next_ = __h.release();
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::pop_front()
+{
+    __node_allocator& __a = base::__alloc();
+    __node_pointer __p = base::__before_begin()->__next_;
+    base::__before_begin()->__next_ = __p->__next_;
+    __node_traits::destroy(__a, _VSTD::addressof(__p->__value_));
+    __node_traits::deallocate(__a, __p, 1);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+template <class... _Args>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
+{
+    __node_pointer const __r = __p.__ptr_;
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_),
+                                  _VSTD::forward<_Args>(__args)...);
+    __h->__next_ = __r->__next_;
+    __r->__next_ = __h.release();
+    return iterator(__r->__next_);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
+{
+    __node_pointer const __r = __p.__ptr_;
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v));
+    __h->__next_ = __r->__next_;
+    __r->__next_ = __h.release();
+    return iterator(__r->__next_);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
+{
+    __node_pointer const __r = __p.__ptr_;
+    __node_allocator& __a = base::__alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+    __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
+    __h->__next_ = __r->__next_;
+    __r->__next_ = __h.release();
+    return iterator(__r->__next_);
+}
+
+template <class _Tp, class _Alloc>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
+                                        const value_type& __v)
+{
+    __node_pointer __r = __p.__ptr_;
+    if (__n > 0)
+    {
+        __node_allocator& __a = base::__alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
+        __node_pointer __first = __h.release();
+        __node_pointer __last = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (--__n; __n != 0; --__n, __last = __last->__next_)
+            {
+                __h.reset(__node_traits::allocate(__a, 1));
+                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
+                __last->__next_ = __h.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (__first != nullptr)
+            {
+                __node_pointer __next = __first->__next_;
+                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
+                __node_traits::deallocate(__a, __first, 1);
+                __first = __next;
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __last->__next_ = __r->__next_;
+        __r->__next_ = __first;
+        __r = __last;
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Alloc>
+template <class _InputIterator>
+typename enable_if
+<
+    __is_input_iterator<_InputIterator>::value,
+    typename forward_list<_Tp, _Alloc>::iterator
+>::type
+forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
+                                        _InputIterator __f, _InputIterator __l)
+{
+    __node_pointer __r = __p.__ptr_;
+    if (__f != __l)
+    {
+        __node_allocator& __a = base::__alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
+        __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
+        __node_pointer __first = __h.release();
+        __node_pointer __last = __first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (++__f; __f != __l; ++__f, __last = __last->__next_)
+            {
+                __h.reset(__node_traits::allocate(__a, 1));
+                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f);
+                __last->__next_ = __h.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (__first != nullptr)
+            {
+                __node_pointer __next = __first->__next_;
+                __node_traits::destroy(__a, _VSTD::addressof(__first->__value_));
+                __node_traits::deallocate(__a, __first, 1);
+                __first = __next;
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __last->__next_ = __r->__next_;
+        __r->__next_ = __first;
+        __r = __last;
+    }
+    return iterator(__r);
+}
+
+template <class _Tp, class _Alloc>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
+{
+    __node_pointer __p = __f.__ptr_;
+    __node_pointer __n = __p->__next_;
+    __p->__next_ = __n->__next_;
+    __node_allocator& __a = base::__alloc();
+    __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
+    __node_traits::deallocate(__a, __n, 1);
+    return iterator(__p->__next_);
+}
+
+template <class _Tp, class _Alloc>
+typename forward_list<_Tp, _Alloc>::iterator
+forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
+{
+    __node_pointer __e = __l.__ptr_;
+    if (__f != __l)
+    {
+        __node_pointer __p = __f.__ptr_;
+        __node_pointer __n = __p->__next_;
+        if (__n != __e)
+        {
+            __p->__next_ = __e;
+            __node_allocator& __a = base::__alloc();
+            do
+            {
+                __p = __n->__next_;
+                __node_traits::destroy(__a, _VSTD::addressof(__n->__value_));
+                __node_traits::deallocate(__a, __n, 1);
+                __n = __p;
+            } while (__n != __e);
+        }
+    }
+    return iterator(__e);
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::resize(size_type __n)
+{
+    size_type __sz = 0;
+    iterator __p = before_begin();
+    iterator __i = begin();
+    iterator __e = end();
+    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
+        ;
+    if (__i != __e)
+        erase_after(__p, __e);
+    else
+    {
+        __n -= __sz;
+        if (__n > 0)
+        {
+            __node_allocator& __a = base::__alloc();
+            typedef __allocator_destructor<__node_allocator> _Dp;
+            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
+            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
+                                                         __ptr = __ptr->__next_)
+            {
+                __h.reset(__node_traits::allocate(__a, 1));
+                __node_traits::construct(__a, _VSTD::addressof(__h->__value_));
+                __h->__next_ = nullptr;
+                __ptr->__next_ = __h.release();
+            }
+        }
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v)
+{
+    size_type __sz = 0;
+    iterator __p = before_begin();
+    iterator __i = begin();
+    iterator __e = end();
+    for (; __i != __e && __sz < __n; ++__p, ++__i, ++__sz)
+        ;
+    if (__i != __e)
+        erase_after(__p, __e);
+    else
+    {
+        __n -= __sz;
+        if (__n > 0)
+        {
+            __node_allocator& __a = base::__alloc();
+            typedef __allocator_destructor<__node_allocator> _Dp;
+            unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1));
+            for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n,
+                                                         __ptr = __ptr->__next_)
+            {
+                __h.reset(__node_traits::allocate(__a, 1));
+                __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v);
+                __h->__next_ = nullptr;
+                __ptr->__next_ = __h.release();
+            }
+        }
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list& __x)
+{
+    if (!__x.empty())
+    {
+        if (__p.__ptr_->__next_ != nullptr)
+        {
+            const_iterator __lm1 = __x.before_begin();
+            while (__lm1.__ptr_->__next_ != nullptr)
+                ++__lm1;
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+        }
+        __p.__ptr_->__next_ = __x.__before_begin()->__next_;
+        __x.__before_begin()->__next_ = nullptr;
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list& __x,
+                                        const_iterator __i)
+{
+    const_iterator __lm1 = _VSTD::next(__i);
+    if (__p != __i && __p != __lm1)
+    {
+        __i.__ptr_->__next_ = __lm1.__ptr_->__next_;
+        __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+        __p.__ptr_->__next_ = __lm1.__ptr_;
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list& __x,
+                                        const_iterator __f, const_iterator __l)
+{
+    if (__f != __l && __p != __f)
+    {
+        const_iterator __lm1 = __f;
+        while (__lm1.__ptr_->__next_ != __l.__ptr_)
+            ++__lm1;
+        if (__f != __lm1)
+        {
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+            __p.__ptr_->__next_ = __f.__ptr_->__next_;
+            __f.__ptr_->__next_ = __l.__ptr_;
+        }
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list&& __x)
+{
+    splice_after(__p, __x);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list&& __x,
+                                        const_iterator __i)
+{
+    splice_after(__p, __x, __i);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+forward_list<_Tp, _Alloc>::splice_after(const_iterator __p,
+                                        forward_list&& __x,
+                                        const_iterator __f, const_iterator __l)
+{
+    splice_after(__p, __x, __f, __l);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::remove(const value_type& __v)
+{
+    iterator __e = end();
+    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
+    {
+        if (__i.__ptr_->__next_->__value_ == __v)
+        {
+            iterator __j = _VSTD::next(__i, 2);
+            for (; __j != __e && *__j == __v; ++__j)
+                ;
+            erase_after(__i, __j);
+            if (__j == __e)
+                break;
+            __i = __j;
+        }
+        else
+            ++__i;
+    }
+}
+
+template <class _Tp, class _Alloc>
+template <class _Predicate>
+void
+forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred)
+{
+    iterator __e = end();
+    for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;)
+    {
+        if (__pred(__i.__ptr_->__next_->__value_))
+        {
+            iterator __j = _VSTD::next(__i, 2);
+            for (; __j != __e && __pred(*__j); ++__j)
+                ;
+            erase_after(__i, __j);
+            if (__j == __e)
+                break;
+            __i = __j;
+        }
+        else
+            ++__i;
+    }
+}
+
+template <class _Tp, class _Alloc>
+template <class _BinaryPredicate>
+void
+forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
+{
+    for (iterator __i = begin(), __e = end(); __i != __e;)
+    {
+        iterator __j = _VSTD::next(__i);
+        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
+            ;
+        if (__i.__ptr_->__next_ != __j.__ptr_)
+            erase_after(__i, __j);
+        __i = __j;
+    }
+}
+
+template <class _Tp, class _Alloc>
+template <class _Compare>
+void
+forward_list<_Tp, _Alloc>::merge(forward_list& __x, _Compare __comp)
+{
+    if (this != &__x)
+    {
+        base::__before_begin()->__next_ = __merge(base::__before_begin()->__next_,
+                                                    __x.__before_begin()->__next_,
+                                                    __comp);
+        __x.__before_begin()->__next_ = nullptr;
+    }
+}
+
+template <class _Tp, class _Alloc>
+template <class _Compare>
+typename forward_list<_Tp, _Alloc>::__node_pointer
+forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2,
+                                   _Compare& __comp)
+{
+    if (__f1 == nullptr)
+        return __f2;
+    if (__f2 == nullptr)
+        return __f1;
+    __node_pointer __r;
+    if (__comp(__f2->__value_, __f1->__value_))
+    {
+        __node_pointer __t = __f2;
+        while (__t->__next_ != nullptr &&
+                             __comp(__t->__next_->__value_, __f1->__value_))
+            __t = __t->__next_;
+        __r = __f2;
+        __f2 = __t->__next_;
+        __t->__next_ = __f1;
+    }
+    else
+        __r = __f1;
+    __node_pointer __p = __f1;
+    __f1 = __f1->__next_;
+    while (__f1 != nullptr && __f2 != nullptr)
+    {
+        if (__comp(__f2->__value_, __f1->__value_))
+        {
+            __node_pointer __t = __f2;
+            while (__t->__next_ != nullptr &&
+                                 __comp(__t->__next_->__value_, __f1->__value_))
+                __t = __t->__next_;
+            __p->__next_ = __f2;
+            __f2 = __t->__next_;
+            __t->__next_ = __f1;
+        }
+        __p = __f1;
+        __f1 = __f1->__next_;
+    }
+    if (__f2 != nullptr)
+        __p->__next_ = __f2;
+    return __r;
+}
+
+template <class _Tp, class _Alloc>
+template <class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+forward_list<_Tp, _Alloc>::sort(_Compare __comp)
+{
+    base::__before_begin()->__next_ = __sort(base::__before_begin()->__next_,
+                                       _VSTD::distance(begin(), end()), __comp);
+}
+
+template <class _Tp, class _Alloc>
+template <class _Compare>
+typename forward_list<_Tp, _Alloc>::__node_pointer
+forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz,
+                                  _Compare& __comp)
+{
+    switch (__sz)
+    {
+    case 0:
+    case 1:
+        return __f1;
+    case 2:
+        if (__comp(__f1->__next_->__value_, __f1->__value_))
+        {
+            __node_pointer __t = __f1->__next_;
+            __t->__next_ = __f1;
+            __f1->__next_ = nullptr;
+            __f1 = __t;
+        }
+        return __f1;
+    }
+    difference_type __sz1 = __sz / 2;
+    difference_type __sz2 = __sz - __sz1;
+    __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_;
+    __node_pointer __f2 = __t->__next_;
+    __t->__next_ = nullptr;
+    return __merge(__sort(__f1, __sz1, __comp),
+                   __sort(__f2, __sz2, __comp), __comp);
+}
+
+template <class _Tp, class _Alloc>
+void
+forward_list<_Tp, _Alloc>::reverse() _NOEXCEPT
+{
+    __node_pointer __p = base::__before_begin()->__next_;
+    if (__p != nullptr)
+    {
+        __node_pointer __f = __p->__next_;
+        __p->__next_ = nullptr;
+        while (__f != nullptr)
+        {
+            __node_pointer __t = __f->__next_;
+            __f->__next_ = __p;
+            __p = __f;
+            __f = __t;
+        }
+        base::__before_begin()->__next_ = __p;
+    }
+}
+
+template <class _Tp, class _Alloc>
+bool operator==(const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    typedef forward_list<_Tp, _Alloc> _Cp;
+    typedef typename _Cp::const_iterator _Ip;
+    _Ip __ix = __x.begin();
+    _Ip __ex = __x.end();
+    _Ip __iy = __y.begin();
+    _Ip __ey = __y.end();
+    for (; __ix != __ex && __iy != __ey; ++__ix, ++__iy)
+        if (!(*__ix == *__iy))
+            return false;
+    return (__ix == __ex) == (__iy == __ey);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator< (const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
+                                         __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator> (const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>=(const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator<=(const forward_list<_Tp, _Alloc>& __x,
+                const forward_list<_Tp, _Alloc>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_FORWARD_LIST
diff --git a/include/c++/v1/fstream b/include/c++/v1/fstream
new file mode 100644
index 0000000..38778c6
--- /dev/null
+++ b/include/c++/v1/fstream
@@ -0,0 +1,1431 @@
+// -*- C++ -*-
+//===------------------------- fstream ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FSTREAM
+#define _LIBCPP_FSTREAM
+
+/*
+    fstream synopsis
+
+template <class charT, class traits = char_traits<charT> >
+class basic_filebuf
+    : public basic_streambuf<charT, traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // 27.9.1.2 Constructors/destructor:
+    basic_filebuf();
+    basic_filebuf(basic_filebuf&& rhs);
+    virtual ~basic_filebuf();
+
+    // 27.9.1.3 Assign/swap:
+    basic_filebuf& operator=(basic_filebuf&& rhs);
+    void swap(basic_filebuf& rhs);
+
+    // 27.9.1.4 Members:
+    bool is_open() const;
+    basic_filebuf* open(const char* s, ios_base::openmode mode);
+    basic_filebuf* open(const string& s, ios_base::openmode mode);
+    basic_filebuf* close();
+
+protected:
+    // 27.9.1.5 Overridden virtual functions:
+    virtual streamsize showmanyc();
+    virtual int_type underflow();
+    virtual int_type uflow();
+    virtual int_type pbackfail(int_type c = traits_type::eof());
+    virtual int_type overflow (int_type c = traits_type::eof());
+    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
+    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type sp,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual int sync();
+    virtual void imbue(const locale& loc);
+};
+
+template <class charT, class traits>
+  void
+  swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
+
+typedef basic_filebuf<char>    filebuf;
+typedef basic_filebuf<wchar_t> wfilebuf;
+
+template <class charT, class traits = char_traits<charT> >
+class basic_ifstream
+    : public basic_istream<charT,traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_ifstream();
+    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
+    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
+    basic_ifstream(basic_ifstream&& rhs);
+
+    basic_ifstream& operator=(basic_ifstream&& rhs);
+    void swap(basic_ifstream& rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* s, ios_base::openmode mode = ios_base::in);
+    void open(const string& s, ios_base::openmode mode = ios_base::in);
+    void close();
+};
+
+template <class charT, class traits>
+  void
+  swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
+
+typedef basic_ifstream<char>    ifstream;
+typedef basic_ifstream<wchar_t> wifstream;
+
+template <class charT, class traits = char_traits<charT> >
+class basic_ofstream
+    : public basic_ostream<charT,traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_ofstream();
+    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
+    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
+    basic_ofstream(basic_ofstream&& rhs);
+
+    basic_ofstream& operator=(basic_ofstream&& rhs);
+    void swap(basic_ofstream& rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* s, ios_base::openmode mode = ios_base::out);
+    void open(const string& s, ios_base::openmode mode = ios_base::out);
+    void close();
+};
+
+template <class charT, class traits>
+  void
+  swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
+
+typedef basic_ofstream<char>    ofstream;
+typedef basic_ofstream<wchar_t> wofstream;
+
+template <class charT, class traits=char_traits<charT> >
+class basic_fstream
+    : public basic_iostream<charT,traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_fstream();
+    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
+    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
+    basic_fstream(basic_fstream&& rhs);
+
+    basic_fstream& operator=(basic_fstream&& rhs);
+    void swap(basic_fstream& rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
+    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
+    void close();
+};
+
+template <class charT, class traits>
+  void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
+
+typedef basic_fstream<char>    fstream;
+typedef basic_fstream<wchar_t> wfstream;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ostream>
+#include <istream>
+#include <__locale>
+#include <cstdio>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_filebuf
+    : public basic_streambuf<_CharT, _Traits>
+{
+public:
+    typedef _CharT                           char_type;
+    typedef _Traits                          traits_type;
+    typedef typename traits_type::int_type   int_type;
+    typedef typename traits_type::pos_type   pos_type;
+    typedef typename traits_type::off_type   off_type;
+    typedef typename traits_type::state_type state_type;
+
+    // 27.9.1.2 Constructors/destructor:
+    basic_filebuf();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_filebuf(basic_filebuf&& __rhs);
+#endif
+    virtual ~basic_filebuf();
+
+    // 27.9.1.3 Assign/swap:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_filebuf& operator=(basic_filebuf&& __rhs);
+#endif
+    void swap(basic_filebuf& __rhs);
+
+    // 27.9.1.4 Members:
+    bool is_open() const;
+    basic_filebuf* open(const char* __s, ios_base::openmode __mode);
+    basic_filebuf* open(const string& __s, ios_base::openmode __mode);
+    basic_filebuf* close();
+
+protected:
+    // 27.9.1.5 Overridden virtual functions:
+    virtual int_type underflow();
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
+    virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual int sync();
+    virtual void imbue(const locale& __loc);
+
+private:
+    char*       __extbuf_;
+    const char* __extbufnext_;
+    const char* __extbufend_;
+    char __extbuf_min_[8];
+    size_t __ebs_;
+    char_type* __intbuf_;
+    size_t __ibs_;
+    FILE* __file_;
+    const codecvt<char_type, char, state_type>* __cv_;
+    state_type __st_;
+    state_type __st_last_;
+    ios_base::openmode __om_;
+    ios_base::openmode __cm_;
+    bool __owns_eb_;
+    bool __owns_ib_;
+    bool __always_noconv_;
+
+    bool __read_mode();
+    void __write_mode();
+};
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>::basic_filebuf()
+    : __extbuf_(0),
+      __extbufnext_(0),
+      __extbufend_(0),
+      __ebs_(0),
+      __intbuf_(0),
+      __ibs_(0),
+      __file_(0),
+      __cv_(nullptr),
+      __st_(),
+      __st_last_(),
+      __om_(0),
+      __cm_(0),
+      __owns_eb_(false),
+      __owns_ib_(false),
+      __always_noconv_(false)
+{
+    if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
+    {
+        __cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());
+        __always_noconv_ = __cv_->always_noconv();
+    }
+    setbuf(0, 4096);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
+    : basic_streambuf<_CharT, _Traits>(__rhs)
+{
+    if (__rhs.__extbuf_ == __rhs.__extbuf_min_)
+    {
+        __extbuf_ = __extbuf_min_;
+        __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
+        __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
+    }
+    else
+    {
+        __extbuf_ = __rhs.__extbuf_;
+        __extbufnext_ = __rhs.__extbufnext_;
+        __extbufend_ = __rhs.__extbufend_;
+    }
+    __ebs_ = __rhs.__ebs_;
+    __intbuf_ = __rhs.__intbuf_;
+    __ibs_ = __rhs.__ibs_;
+    __file_ = __rhs.__file_;
+    __cv_ = __rhs.__cv_;
+    __st_ = __rhs.__st_;
+    __st_last_ = __rhs.__st_last_;
+    __om_ = __rhs.__om_;
+    __cm_ = __rhs.__cm_;
+    __owns_eb_ = __rhs.__owns_eb_;
+    __owns_ib_ = __rhs.__owns_ib_;
+    __always_noconv_ = __rhs.__always_noconv_;
+    if (__rhs.pbase())
+    {
+        if (__rhs.pbase() == __rhs.__intbuf_)
+            this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));
+        else
+            this->setp((char_type*)__extbuf_,
+                       (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));
+        this->pbump(__rhs. pptr() - __rhs.pbase());
+    }
+    else if (__rhs.eback())
+    {
+        if (__rhs.eback() == __rhs.__intbuf_)
+            this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),
+                                  __intbuf_ + (__rhs.egptr() - __rhs.eback()));
+        else
+            this->setg((char_type*)__extbuf_,
+                       (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
+                       (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
+    }
+    __rhs.__extbuf_ = 0;
+    __rhs.__extbufnext_ = 0;
+    __rhs.__extbufend_ = 0;
+    __rhs.__ebs_ = 0;
+    __rhs.__intbuf_ = 0;
+    __rhs.__ibs_ = 0;
+    __rhs.__file_ = 0;
+    __rhs.__st_ = state_type();
+    __rhs.__st_last_ = state_type();
+    __rhs.__om_ = 0;
+    __rhs.__cm_ = 0;
+    __rhs.__owns_eb_ = false;
+    __rhs.__owns_ib_ = false;
+    __rhs.setg(0, 0, 0);
+    __rhs.setp(0, 0);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_filebuf<_CharT, _Traits>&
+basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
+{
+    close();
+    swap(__rhs);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>::~basic_filebuf()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        close();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
+{
+    basic_streambuf<char_type, traits_type>::swap(__rhs);
+    if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
+    {
+        _VSTD::swap(__extbuf_, __rhs.__extbuf_);
+        _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
+        _VSTD::swap(__extbufend_, __rhs.__extbufend_);
+    }
+    else
+    {
+        ptrdiff_t __ln = __extbufnext_ - __extbuf_;
+        ptrdiff_t __le = __extbufend_ - __extbuf_;
+        ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
+        ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
+        if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
+        {
+            __extbuf_ = __rhs.__extbuf_;
+            __rhs.__extbuf_ = __rhs.__extbuf_min_;
+        }
+        else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
+        {
+            __rhs.__extbuf_ = __extbuf_;
+            __extbuf_ = __extbuf_min_;
+        }
+        __extbufnext_ = __extbuf_ + __rn;
+        __extbufend_ = __extbuf_ + __re;
+        __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
+        __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
+    }
+    _VSTD::swap(__ebs_, __rhs.__ebs_);
+    _VSTD::swap(__intbuf_, __rhs.__intbuf_);
+    _VSTD::swap(__ibs_, __rhs.__ibs_);
+    _VSTD::swap(__file_, __rhs.__file_);
+    _VSTD::swap(__cv_, __rhs.__cv_);
+    _VSTD::swap(__st_, __rhs.__st_);
+    _VSTD::swap(__st_last_, __rhs.__st_last_);
+    _VSTD::swap(__om_, __rhs.__om_);
+    _VSTD::swap(__cm_, __rhs.__cm_);
+    _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
+    _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
+    _VSTD::swap(__always_noconv_, __rhs.__always_noconv_);
+    if (this->eback() == (char_type*)__rhs.__extbuf_min_)
+    {
+        ptrdiff_t __n = this->gptr() - this->eback();
+        ptrdiff_t __e = this->egptr() - this->eback();
+        this->setg((char_type*)__extbuf_min_,
+                   (char_type*)__extbuf_min_ + __n,
+                   (char_type*)__extbuf_min_ + __e);
+    }
+    else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)
+    {
+        ptrdiff_t __n = this->pptr() - this->pbase();
+        ptrdiff_t __e = this->epptr() - this->pbase();
+        this->setp((char_type*)__extbuf_min_,
+                   (char_type*)__extbuf_min_ + __e);
+        this->pbump(__n);
+    }
+    if (__rhs.eback() == (char_type*)__extbuf_min_)
+    {
+        ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
+        ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
+        __rhs.setg((char_type*)__rhs.__extbuf_min_,
+                   (char_type*)__rhs.__extbuf_min_ + __n,
+                   (char_type*)__rhs.__extbuf_min_ + __e);
+    }
+    else if (__rhs.pbase() == (char_type*)__extbuf_min_)
+    {
+        ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
+        ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
+        __rhs.setp((char_type*)__rhs.__extbuf_min_,
+                   (char_type*)__rhs.__extbuf_min_ + __e);
+        __rhs.pbump(__n);
+    }
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+basic_filebuf<_CharT, _Traits>::is_open() const
+{
+    return __file_ != 0;
+}
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>*
+basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
+{
+    basic_filebuf<_CharT, _Traits>* __rt = 0;
+    if (__file_ == 0)
+    {
+        __rt = this;
+        const char* __mdstr;
+        switch (__mode & ~ios_base::ate)
+        {
+        case ios_base::out:
+        case ios_base::out | ios_base::trunc:
+            __mdstr = "w";
+            break;
+        case ios_base::out | ios_base::app:
+        case ios_base::app:
+            __mdstr = "a";
+            break;
+        case ios_base::in:
+            __mdstr = "r";
+            break;
+        case ios_base::in | ios_base::out:
+            __mdstr = "r+";
+            break;
+        case ios_base::in | ios_base::out | ios_base::trunc:
+            __mdstr = "w+";
+            break;
+        case ios_base::in | ios_base::out | ios_base::app:
+        case ios_base::in | ios_base::app:
+            __mdstr = "a+";
+            break;
+        case ios_base::out | ios_base::binary:
+        case ios_base::out | ios_base::trunc | ios_base::binary:
+            __mdstr = "wb";
+            break;
+        case ios_base::out | ios_base::app | ios_base::binary:
+        case ios_base::app | ios_base::binary:
+            __mdstr = "ab";
+            break;
+        case ios_base::in | ios_base::binary:
+            __mdstr = "rb";
+            break;
+        case ios_base::in | ios_base::out | ios_base::binary:
+            __mdstr = "r+b";
+            break;
+        case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
+            __mdstr = "w+b";
+            break;
+        case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
+        case ios_base::in | ios_base::app | ios_base::binary:
+            __mdstr = "a+b";
+            break;
+        default:
+            __rt = 0;
+            break;
+        }
+        if (__rt)
+        {
+            __file_ = fopen(__s, __mdstr);
+            if (__file_)
+            {
+                __om_ = __mode;
+                if (__mode & ios_base::ate)
+                {
+                    if (fseek(__file_, 0, SEEK_END))
+                    {
+                        fclose(__file_);
+                        __file_ = 0;
+                        __rt = 0;
+                    }
+                }
+            }
+            else
+                __rt = 0;
+        }
+    }
+    return __rt;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_filebuf<_CharT, _Traits>*
+basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
+{
+    return open(__s.c_str(), __mode);
+}
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>*
+basic_filebuf<_CharT, _Traits>::close()
+{
+    basic_filebuf<_CharT, _Traits>* __rt = 0;
+    if (__file_)
+    {
+        __rt = this;
+        unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);
+        if (sync())
+            __rt = 0;
+        if (fclose(__h.release()) == 0)
+            __file_ = 0;
+        else
+            __rt = 0;
+    }
+    return __rt;
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::int_type
+basic_filebuf<_CharT, _Traits>::underflow()
+{
+    if (__file_ == 0)
+        return traits_type::eof();
+    bool __initial = __read_mode();
+    char_type __1buf;
+    if (this->gptr() == 0)
+        this->setg(&__1buf, &__1buf+1, &__1buf+1);
+    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
+    int_type __c = traits_type::eof();
+    if (this->gptr() == this->egptr())
+    {
+        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
+        if (__always_noconv_)
+        {
+            size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
+            __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
+            if (__nmemb != 0)
+            {
+                this->setg(this->eback(),
+                           this->eback() + __unget_sz,
+                           this->eback() + __unget_sz + __nmemb);
+                __c = traits_type::to_int_type(*this->gptr());
+            }
+        }
+        else
+        {
+            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
+            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
+            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
+            size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),
+                                 static_cast<size_t>(__extbufend_ - __extbufnext_));
+            codecvt_base::result __r;
+            __st_last_ = __st_;
+            size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_);
+            if (__nr != 0)
+            {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (!__cv_)
+                    throw bad_cast();
+#endif
+                __extbufend_ = __extbufnext_ + __nr;
+                char_type*  __inext;
+                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
+                                       this->eback() + __unget_sz,
+                                       this->eback() + __ibs_, __inext);
+                if (__r == codecvt_base::noconv)
+                {
+                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
+                    __c = traits_type::to_int_type(*this->gptr());
+                }
+                else if (__inext != this->eback() + __unget_sz)
+                {
+                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
+                    __c = traits_type::to_int_type(*this->gptr());
+                }
+            }
+        }
+    }
+    else
+        __c = traits_type::to_int_type(*this->gptr());
+    if (this->eback() == &__1buf)
+        this->setg(0, 0, 0);
+    return __c;
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::int_type
+basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
+{
+    if (__file_ && this->eback() < this->gptr())
+    {
+        if (traits_type::eq_int_type(__c, traits_type::eof()))
+        {
+            this->gbump(-1);
+            return traits_type::not_eof(__c);
+        }
+        if ((__om_ & ios_base::out) ||
+            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
+        {
+            this->gbump(-1);
+            *this->gptr() = traits_type::to_char_type(__c);
+            return __c;
+        }
+    }
+    return traits_type::eof();
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::int_type
+basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
+{
+    if (__file_ == 0)
+        return traits_type::eof();
+    __write_mode();
+    char_type __1buf;
+    char_type* __pb_save = this->pbase();
+    char_type* __epb_save = this->epptr();
+    if (!traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        if (this->pptr() == 0)
+            this->setp(&__1buf, &__1buf+1);
+        *this->pptr() = traits_type::to_char_type(__c);
+        this->pbump(1);
+    }
+    if (this->pptr() != this->pbase())
+    {
+        if (__always_noconv_)
+        {
+            size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
+            if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
+                return traits_type::eof();
+        }
+        else
+        {
+            char* __extbe = __extbuf_;
+            codecvt_base::result __r;
+            do
+            {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (!__cv_)
+                    throw bad_cast();
+#endif
+                const char_type* __e;
+                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
+                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
+                if (__e == this->pbase())
+                    return traits_type::eof();
+                if (__r == codecvt_base::noconv)
+                {
+                    size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
+                    if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
+                        return traits_type::eof();
+                }
+                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+                {
+                    size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
+                    if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
+                        return traits_type::eof();
+                    if (__r == codecvt_base::partial)
+                    {
+                        this->setp((char_type*)__e, this->pptr());
+                        this->pbump(this->epptr() - this->pbase());
+                    }
+                }
+                else
+                    return traits_type::eof();
+            } while (__r == codecvt_base::partial);
+        }
+        this->setp(__pb_save, __epb_save);
+    }
+    return traits_type::not_eof(__c);
+}
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>*
+basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)
+{
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+    __ebs_ = __n;
+    if (__ebs_ > sizeof(__extbuf_min_))
+    {
+        if (__always_noconv_ && __s)
+        {
+            __extbuf_ = (char*)__s;
+            __owns_eb_ = false;
+        }
+        else
+        {
+            __extbuf_ = new char[__ebs_];
+            __owns_eb_ = true;
+        }
+    }
+    else
+    {
+        __extbuf_ = __extbuf_min_;
+        __ebs_ = sizeof(__extbuf_min_);
+        __owns_eb_ = false;
+    }
+    if (!__always_noconv_)
+    {
+        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
+        if (__s && __ibs_ >= sizeof(__extbuf_min_))
+        {
+            __intbuf_ = __s;
+            __owns_ib_ = false;
+        }
+        else
+        {
+            __intbuf_ = new char_type[__ibs_];
+            __owns_ib_ = true;
+        }
+    }
+    else
+    {
+        __ibs_ = 0;
+        __intbuf_ = 0;
+        __owns_ib_ = false;
+    }
+    return this;
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::pos_type
+basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
+                                        ios_base::openmode)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (!__cv_)
+        throw bad_cast();
+#endif
+    int __width = __cv_->encoding();
+    if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())
+        return pos_type(off_type(-1));
+    // __width > 0 || __off == 0
+    int __whence;
+    switch (__way)
+    {
+    case ios_base::beg:
+        __whence = SEEK_SET;
+        break;
+    case ios_base::cur:
+        __whence = SEEK_CUR;
+        break;
+    case ios_base::end:
+        __whence = SEEK_END;
+        break;
+    default:
+        return pos_type(off_type(-1));
+    }
+#if _WIN32
+    if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
+        return pos_type(off_type(-1));
+    pos_type __r = ftell(__file_);
+#else
+    if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
+        return pos_type(off_type(-1));
+    pos_type __r = ftello(__file_);
+#endif
+    __r.state(__st_);
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+typename basic_filebuf<_CharT, _Traits>::pos_type
+basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
+{
+    if (__file_ == 0 || sync())
+        return pos_type(off_type(-1));
+#if _WIN32
+    if (fseek(__file_, __sp, SEEK_SET))
+        return pos_type(off_type(-1));
+#else
+    if (fseeko(__file_, __sp, SEEK_SET))
+        return pos_type(off_type(-1));
+#endif
+    __st_ = __sp.state();
+    return __sp;
+}
+
+template <class _CharT, class _Traits>
+int
+basic_filebuf<_CharT, _Traits>::sync()
+{
+    if (__file_ == 0)
+        return 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (!__cv_)
+        throw bad_cast();
+#endif
+    if (__cm_ & ios_base::out)
+    {
+        if (this->pptr() != this->pbase())
+            if (overflow() == traits_type::eof())
+                return -1;
+        codecvt_base::result __r;
+        do
+        {
+            char* __extbe;
+            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
+            size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
+            if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
+                return -1;
+        } while (__r == codecvt_base::partial);
+        if (__r == codecvt_base::error)
+            return -1;
+        if (fflush(__file_))
+            return -1;
+    }
+    else if (__cm_ & ios_base::in)
+    {
+        off_type __c;
+        state_type __state = __st_last_;
+        bool __update_st = false;
+        if (__always_noconv_)
+            __c = this->egptr() - this->gptr();
+        else
+        {
+            int __width = __cv_->encoding();
+            __c = __extbufend_ - __extbufnext_;
+            if (__width > 0)
+                __c += __width * (this->egptr() - this->gptr());
+            else
+            {
+                if (this->gptr() != this->egptr())
+                {
+                    const int __off =  __cv_->length(__state, __extbuf_,
+                                                     __extbufnext_,
+                                                     this->gptr() - this->eback());
+                    __c += __extbufnext_ - __extbuf_ - __off;
+                    __update_st = true;
+                }
+            }
+        }
+#if _WIN32
+        if (fseek(__file_, -__c, SEEK_CUR))
+            return -1;
+#else
+        if (fseeko(__file_, -__c, SEEK_CUR))
+            return -1;
+#endif
+        if (__update_st)
+            __st_ = __state;
+        __extbufnext_ = __extbufend_ = __extbuf_;
+        this->setg(0, 0, 0);
+        __cm_ = 0;
+    }
+    return 0;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
+{
+    sync();
+    __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
+    bool __old_anc = __always_noconv_;
+    __always_noconv_ = __cv_->always_noconv();
+    if (__old_anc != __always_noconv_)
+    {
+        this->setg(0, 0, 0);
+        this->setp(0, 0);
+        // invariant, char_type is char, else we couldn't get here
+        if (__always_noconv_)  // need to dump __intbuf_
+        {
+            if (__owns_eb_)
+                delete [] __extbuf_;
+            __owns_eb_ = __owns_ib_;
+            __ebs_ = __ibs_;
+            __extbuf_ = (char*)__intbuf_;
+            __ibs_ = 0;
+            __intbuf_ = 0;
+            __owns_ib_ = false;
+        }
+        else  // need to obtain an __intbuf_.
+        {     // If __extbuf_ is user-supplied, use it, else new __intbuf_
+            if (!__owns_eb_ && __extbuf_ != __extbuf_min_)
+            {
+                __ibs_ = __ebs_;
+                __intbuf_ = (char_type*)__extbuf_;
+                __owns_ib_ = false;
+                __extbuf_ = new char[__ebs_];
+                __owns_eb_ = true;
+            }
+            else
+            {
+                __ibs_ = __ebs_;
+                __intbuf_ = new char_type[__ibs_];
+                __owns_ib_ = true;
+            }
+        }
+    }
+}
+
+template <class _CharT, class _Traits>
+bool
+basic_filebuf<_CharT, _Traits>::__read_mode()
+{
+    if (!(__cm_ & ios_base::in))
+    {
+        this->setp(0, 0);
+        if (__always_noconv_)
+            this->setg((char_type*)__extbuf_,
+                       (char_type*)__extbuf_ + __ebs_,
+                       (char_type*)__extbuf_ + __ebs_);
+        else
+            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
+        __cm_ = ios_base::in;
+        return true;
+    }
+    return false;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_filebuf<_CharT, _Traits>::__write_mode()
+{
+    if (!(__cm_ & ios_base::out))
+    {
+        this->setg(0, 0, 0);
+        if (__ebs_ > sizeof(__extbuf_min_))
+        {
+            if (__always_noconv_)
+                this->setp((char_type*)__extbuf_,
+                           (char_type*)__extbuf_ + (__ebs_ - 1));
+            else
+                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
+        }
+        else
+            this->setp(0, 0);
+        __cm_ = ios_base::out;
+    }
+}
+
+// basic_ifstream
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_ifstream
+    : public basic_istream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_ifstream();
+    explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
+    explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_ifstream(basic_ifstream&& __rhs);
+#endif
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_ifstream& operator=(basic_ifstream&& __rhs);
+#endif
+    void swap(basic_ifstream& __rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* __s, ios_base::openmode __mode = ios_base::in);
+    void open(const string& __s, ios_base::openmode __mode = ios_base::in);
+    void close();
+
+private:
+    basic_filebuf<char_type, traits_type> __sb_;
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ifstream<_CharT, _Traits>::basic_ifstream()
+    : basic_istream<char_type, traits_type>(&__sb_)
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
+    : basic_istream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode | ios_base::in) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
+    : basic_istream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode | ios_base::in) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
+    : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    this->set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ifstream<_CharT, _Traits>&
+basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
+{
+    basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)
+{
+    basic_istream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_filebuf<_CharT, _Traits>*
+basic_ifstream<_CharT, _Traits>::rdbuf() const
+{
+    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+basic_ifstream<_CharT, _Traits>::is_open() const
+{
+    return __sb_.is_open();
+}
+
+template <class _CharT, class _Traits>
+void
+basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode | ios_base::in))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+void
+basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode | ios_base::in))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ifstream<_CharT, _Traits>::close()
+{
+    if (__sb_.close() == 0)
+        this->setstate(ios_base::failbit);
+}
+
+// basic_ofstream
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_ofstream
+    : public basic_ostream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_ofstream();
+    explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
+    explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_ofstream(basic_ofstream&& __rhs);
+#endif
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_ofstream& operator=(basic_ofstream&& __rhs);
+#endif
+    void swap(basic_ofstream& __rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* __s, ios_base::openmode __mode = ios_base::out);
+    void open(const string& __s, ios_base::openmode __mode = ios_base::out);
+    void close();
+
+private:
+    basic_filebuf<char_type, traits_type> __sb_;
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ofstream<_CharT, _Traits>::basic_ofstream()
+    : basic_ostream<char_type, traits_type>(&__sb_)
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
+    : basic_ostream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode | ios_base::out) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
+    : basic_ostream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode | ios_base::out) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
+    : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    this->set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ofstream<_CharT, _Traits>&
+basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
+{
+    basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)
+{
+    basic_ostream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_filebuf<_CharT, _Traits>*
+basic_ofstream<_CharT, _Traits>::rdbuf() const
+{
+    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+basic_ofstream<_CharT, _Traits>::is_open() const
+{
+    return __sb_.is_open();
+}
+
+template <class _CharT, class _Traits>
+void
+basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode | ios_base::out))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+void
+basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode | ios_base::out))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ofstream<_CharT, _Traits>::close()
+{
+    if (__sb_.close() == 0)
+        this->setstate(ios_base::failbit);
+}
+
+// basic_fstream
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_fstream
+    : public basic_iostream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    basic_fstream();
+    explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+    explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_fstream(basic_fstream&& __rhs);
+#endif
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_fstream& operator=(basic_fstream&& __rhs);
+#endif
+    void swap(basic_fstream& __rhs);
+
+    basic_filebuf<char_type, traits_type>* rdbuf() const;
+    bool is_open() const;
+    void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+    void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+    void close();
+
+private:
+    basic_filebuf<char_type, traits_type> __sb_;
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_fstream<_CharT, _Traits>::basic_fstream()
+    : basic_iostream<char_type, traits_type>(&__sb_)
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
+    : basic_iostream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
+    : basic_iostream<char_type, traits_type>(&__sb_)
+{
+    if (__sb_.open(__s, __mode) == 0)
+        this->setstate(ios_base::failbit);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
+    : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    this->set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_fstream<_CharT, _Traits>&
+basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
+{
+    basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)
+{
+    basic_iostream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_filebuf<_CharT, _Traits>*
+basic_fstream<_CharT, _Traits>::rdbuf() const
+{
+    return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+basic_fstream<_CharT, _Traits>::is_open() const
+{
+    return __sb_.is_open();
+}
+
+template <class _CharT, class _Traits>
+void
+basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+void
+basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
+{
+    if (__sb_.open(__s, __mode))
+        this->clear();
+    else
+        this->setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_fstream<_CharT, _Traits>::close()
+{
+    if (__sb_.close() == 0)
+        this->setstate(ios_base::failbit);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_FSTREAM
diff --git a/include/c++/v1/functional b/include/c++/v1/functional
new file mode 100644
index 0000000..416a9a9
--- /dev/null
+++ b/include/c++/v1/functional
@@ -0,0 +1,2419 @@
+// -*- C++ -*-
+//===------------------------ functional ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUNCTIONAL
+#define _LIBCPP_FUNCTIONAL
+
+/*
+    functional synopsis
+
+namespace std
+{
+
+template <class Arg, class Result>
+struct unary_function
+{
+    typedef Arg    argument_type;
+    typedef Result result_type;
+};
+
+template <class Arg1, class Arg2, class Result>
+struct binary_function
+{
+    typedef Arg1   first_argument_type;
+    typedef Arg2   second_argument_type;
+    typedef Result result_type;
+};
+
+template <class T>
+class reference_wrapper
+    : public unary_function<T1, R> // if wrapping a unary functor
+    : public binary_function<T1, T2, R> // if wraping a binary functor
+{
+public:
+    // types
+    typedef T type;
+    typedef see below result_type; // Not always defined
+
+    // construct/copy/destroy
+    reference_wrapper(T&) noexcept;
+    reference_wrapper(T&&) = delete; // do not bind to temps
+    reference_wrapper(const reference_wrapper<T>& x) noexcept;
+
+    // assignment
+    reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
+
+    // access
+    operator T& () const noexcept;
+    T& get() const noexcept;
+
+    // invoke
+    template <class... ArgTypes>
+      typename result_of<T&(ArgTypes&&...)>::type
+          operator() (ArgTypes&&...) const;
+};
+
+template <class T> reference_wrapper<T> ref(T& t) noexcept;
+template <class T> void ref(const T&& t) = delete;
+template <class T> reference_wrapper<T> ref(reference_wrapper<T>t) noexcept;
+
+template <class T> reference_wrapper<const T> cref(const T& t) noexcept;
+template <class T> void cref(const T&& t) = delete;
+template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept;
+
+template <class T> // <class T=void> in C++14
+struct plus : binary_function<T, T, T>
+{
+    T operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct minus : binary_function<T, T, T>
+{
+    T operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct multiplies : binary_function<T, T, T>
+{
+    T operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct divides : binary_function<T, T, T>
+{
+    T operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct modulus : binary_function<T, T, T>
+{
+    T operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct negate : unary_function<T, T>
+{
+    T operator()(const T& x) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct equal_to : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct not_equal_to : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct greater : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct less : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct greater_equal : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct less_equal : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct logical_and : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct logical_or : binary_function<T, T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct logical_not : unary_function<T, bool>
+{
+    bool operator()(const T& x) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct bit_and : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct bit_or : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T> // <class T=void> in C++14
+struct bit_xor : unary_function<T, bool>
+{
+    bool operator()(const T& x, const T& y) const;
+};
+
+template <class T=void> // C++14
+struct bit_xor : unary_function<T, bool>
+{
+    bool operator()(const T& x) const;
+};
+
+template <class Predicate>
+class unary_negate
+    : public unary_function<typename Predicate::argument_type, bool>
+{
+public:
+    explicit unary_negate(const Predicate& pred);
+    bool operator()(const typename Predicate::argument_type& x) const;
+};
+
+template <class Predicate> unary_negate<Predicate> not1(const Predicate& pred);
+
+template <class Predicate>
+class binary_negate
+    : public binary_function<typename Predicate::first_argument_type,
+                             typename Predicate::second_argument_type,
+                             bool>
+{
+public:
+    explicit binary_negate(const Predicate& pred);
+    bool operator()(const typename Predicate::first_argument_type& x,
+                    const typename Predicate::second_argument_type& y) const;
+};
+
+template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred);
+
+template<class T> struct is_bind_expression;
+template<class T> struct is_placeholder;
+
+template<class Fn, class... BoundArgs>
+  unspecified bind(Fn&&, BoundArgs&&...);
+template<class R, class Fn, class... BoundArgs>
+  unspecified bind(Fn&&, BoundArgs&&...);
+
+namespace placeholders {
+  // M is the implementation-defined number of placeholders
+  extern unspecified _1;
+  extern unspecified _2;
+  .
+  .
+  .
+  extern unspecified _Mp;
+}
+
+template <class Operation>
+class binder1st
+    : public unary_function<typename Operation::second_argument_type,
+                            typename Operation::result_type>
+{
+protected:
+    Operation                               op;
+    typename Operation::first_argument_type value;
+public:
+    binder1st(const Operation& x, const typename Operation::first_argument_type y);
+    typename Operation::result_type operator()(      typename Operation::second_argument_type& x) const;
+    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;
+};
+
+template <class Operation, class T>
+binder1st<Operation> bind1st(const Operation& op, const T& x);
+
+template <class Operation>
+class binder2nd
+    : public unary_function<typename Operation::first_argument_type,
+                            typename Operation::result_type>
+{
+protected:
+    Operation                                op;
+    typename Operation::second_argument_type value;
+public:
+    binder2nd(const Operation& x, const typename Operation::second_argument_type y);
+    typename Operation::result_type operator()(      typename Operation::first_argument_type& x) const;
+    typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const;
+};
+
+template <class Operation, class T>
+binder2nd<Operation> bind2nd(const Operation& op, const T& x);
+
+template <class Arg, class Result>
+class pointer_to_unary_function : public unary_function<Arg, Result>
+{
+public:
+    explicit pointer_to_unary_function(Result (*f)(Arg));
+    Result operator()(Arg x) const;
+};
+
+template <class Arg, class Result>
+pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg));
+
+template <class Arg1, class Arg2, class Result>
+class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result>
+{
+public:
+    explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2));
+    Result operator()(Arg1 x, Arg2 y) const;
+};
+
+template <class Arg1, class Arg2, class Result>
+pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2));
+
+template<class S, class T>
+class mem_fun_t : public unary_function<T*, S>
+{
+public:
+    explicit mem_fun_t(S (T::*p)());
+    S operator()(T* p) const;
+};
+
+template<class S, class T, class A>
+class mem_fun1_t : public binary_function<T*, A, S>
+{
+public:
+    explicit mem_fun1_t(S (T::*p)(A));
+    S operator()(T* p, A x) const;
+};
+
+template<class S, class T>          mem_fun_t<S,T>    mem_fun(S (T::*f)());
+template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A));
+
+template<class S, class T>
+class mem_fun_ref_t : public unary_function<T, S>
+{
+public:
+    explicit mem_fun_ref_t(S (T::*p)());
+    S operator()(T& p) const;
+};
+
+template<class S, class T, class A>
+class mem_fun1_ref_t : public binary_function<T, A, S>
+{
+public:
+    explicit mem_fun1_ref_t(S (T::*p)(A));
+    S operator()(T& p, A x) const;
+};
+
+template<class S, class T>          mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)());
+template<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A));
+
+template <class S, class T>
+class const_mem_fun_t : public unary_function<const T*, S>
+{
+public:
+    explicit const_mem_fun_t(S (T::*p)() const);
+    S operator()(const T* p) const;
+};
+
+template <class S, class T, class A>
+class const_mem_fun1_t : public binary_function<const T*, A, S>
+{
+public:
+    explicit const_mem_fun1_t(S (T::*p)(A) const);
+    S operator()(const T* p, A x) const;
+};
+
+template <class S, class T>          const_mem_fun_t<S,T>    mem_fun(S (T::*f)() const);
+template <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const);
+
+template <class S, class T>
+class const_mem_fun_ref_t : public unary_function<T, S>
+{
+public:
+    explicit const_mem_fun_ref_t(S (T::*p)() const);
+    S operator()(const T& p) const;
+};
+
+template <class S, class T, class A>
+class const_mem_fun1_ref_t : public binary_function<T, A, S>
+{
+public:
+    explicit const_mem_fun1_ref_t(S (T::*p)(A) const);
+    S operator()(const T& p, A x) const;
+};
+
+template <class S, class T>          const_mem_fun_ref_t<S,T>    mem_fun_ref(S (T::*f)() const);
+template <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const);
+
+template<class R, class T> unspecified mem_fn(R T::*);
+
+class bad_function_call
+    : public exception
+{
+};
+
+template<class> class function; // undefined
+
+template<class R, class... ArgTypes>
+class function<R(ArgTypes...)>
+  : public unary_function<T1, R>      // iff sizeof...(ArgTypes) == 1 and
+                                      // ArgTypes contains T1
+  : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and
+                                      // ArgTypes contains T1 and T2
+{
+public:
+    typedef R result_type;
+
+    // construct/copy/destroy:
+    function() noexcept;
+    function(nullptr_t) noexcept;
+    function(const function&);
+    function(function&&) noexcept;
+    template<class F>
+      function(F);
+    template<Allocator Alloc>
+      function(allocator_arg_t, const Alloc&) noexcept;
+    template<Allocator Alloc>
+      function(allocator_arg_t, const Alloc&, nullptr_t) noexcept;
+    template<Allocator Alloc>
+      function(allocator_arg_t, const Alloc&, const function&);
+    template<Allocator Alloc>
+      function(allocator_arg_t, const Alloc&, function&&);
+    template<class F, Allocator Alloc>
+      function(allocator_arg_t, const Alloc&, F);
+
+    function& operator=(const function&);
+    function& operator=(function&&) noexcept;
+    function& operator=(nullptr_t) noexcept;
+    template<class F>
+      function& operator=(F&&);
+    template<class F>
+      function& operator=(reference_wrapper<F>) noexcept;
+
+    ~function();
+
+    // function modifiers:
+    void swap(function&) noexcept;
+    template<class F, class Alloc>
+      void assign(F&&, const Alloc&);
+
+    // function capacity:
+    explicit operator bool() const noexcept;
+
+    // function invocation:
+    R operator()(ArgTypes...) const;
+
+    // function target access:
+    const std::type_info& target_type() const noexcept;
+    template <typename T>       T* target() noexcept;
+    template <typename T> const T* target() const noexcept;
+};
+
+// Null pointer comparisons:
+template <class R, class ... ArgTypes>
+  bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
+
+template <class R, class ... ArgTypes>
+  bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+
+template <class R, class ... ArgTypes>
+  bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
+
+template <class  R, class ... ArgTypes>
+  bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+
+// specialized algorithms:
+template <class  R, class ... ArgTypes>
+  void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
+
+template <class T> struct hash;
+
+template <> struct hash<bool>;
+template <> struct hash<char>;
+template <> struct hash<signed char>;
+template <> struct hash<unsigned char>;
+template <> struct hash<char16_t>;
+template <> struct hash<char32_t>;
+template <> struct hash<wchar_t>;
+template <> struct hash<short>;
+template <> struct hash<unsigned short>;
+template <> struct hash<int>;
+template <> struct hash<unsigned int>;
+template <> struct hash<long>;
+template <> struct hash<long long>;
+template <> struct hash<unsigned long>;
+template <> struct hash<unsigned long long>;
+
+template <> struct hash<float>;
+template <> struct hash<double>;
+template <> struct hash<long double>;
+
+template<class T> struct hash<T*>;
+
+}  // std
+
+POLICY:  For non-variadic implementations, the number of arguments is limited
+         to 3.  It is hoped that the need for non-variadic implementations
+         will be minimal.
+
+*/
+
+#include <__config>
+#include <type_traits>
+#include <typeinfo>
+#include <exception>
+#include <memory>
+#include <tuple>
+
+#include <__functional_base>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY plus : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x + __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY plus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY minus : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x - __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY minus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY multiplies : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x * __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY multiplies<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY divides : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x / __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY divides<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY modulus : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x % __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY modulus<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY negate : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return -__x;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY negate<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return -_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY equal_to : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x == __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY equal_to<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY not_equal_to : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x != __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY not_equal_to<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY greater : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x > __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY greater<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+// less in <__functional_base>
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY greater_equal : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x >= __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY greater_equal<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY less_equal : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x <= __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY less_equal<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_and : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x && __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_and<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_or : binary_function<_Tp, _Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x || __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_or<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY logical_not : unary_function<_Tp, bool>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Tp& __x) const
+        {return !__x;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY logical_not<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return !_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_and : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x & __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_and<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_or : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x | __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_or<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+#else
+template <class _Tp>
+#endif
+struct _LIBCPP_TYPE_VIS_ONLY bit_xor : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x ^ __y;}
+};
+
+#if _LIBCPP_STD_VER > 11
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_xor<void>
+{
+    template <class _T1, class _T2>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_T1&& __t, _T2&& __u) const
+        { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); }
+    typedef void is_transparent;
+};
+#endif
+
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp = void>
+struct _LIBCPP_TYPE_VIS_ONLY bit_not : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return ~__x;}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY bit_not<void>
+{
+    template <class _Tp>
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    auto operator()(_Tp&& __x) const
+        { return ~_VSTD::forward<_Tp>(__x); }
+    typedef void is_transparent;
+};
+#endif
+
+template <class _Predicate>
+class _LIBCPP_TYPE_VIS_ONLY unary_negate
+    : public unary_function<typename _Predicate::argument_type, bool>
+{
+    _Predicate __pred_;
+public:
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    explicit unary_negate(const _Predicate& __pred)
+        : __pred_(__pred) {}
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::argument_type& __x) const
+        {return !__pred_(__x);}
+};
+
+template <class _Predicate>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+unary_negate<_Predicate>
+not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);}
+
+template <class _Predicate>
+class _LIBCPP_TYPE_VIS_ONLY binary_negate
+    : public binary_function<typename _Predicate::first_argument_type,
+                             typename _Predicate::second_argument_type,
+                             bool>
+{
+    _Predicate __pred_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 
+    binary_negate(const _Predicate& __pred) : __pred_(__pred) {}
+
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const typename _Predicate::first_argument_type& __x,
+                    const typename _Predicate::second_argument_type& __y) const
+        {return !__pred_(__x, __y);}
+};
+
+template <class _Predicate>
+inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+binary_negate<_Predicate>
+not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);}
+
+template <class __Operation>
+class _LIBCPP_TYPE_VIS_ONLY binder1st
+    : public unary_function<typename __Operation::second_argument_type,
+                            typename __Operation::result_type>
+{
+protected:
+    __Operation                               op;
+    typename __Operation::first_argument_type value;
+public:
+    _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x,
+                               const typename __Operation::first_argument_type __y)
+        : op(__x), value(__y) {}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (typename __Operation::second_argument_type& __x) const
+            {return op(value, __x);}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (const typename __Operation::second_argument_type& __x) const
+            {return op(value, __x);}
+};
+
+template <class __Operation, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+binder1st<__Operation>
+bind1st(const __Operation& __op, const _Tp& __x)
+    {return binder1st<__Operation>(__op, __x);}
+
+template <class __Operation>
+class _LIBCPP_TYPE_VIS_ONLY binder2nd
+    : public unary_function<typename __Operation::first_argument_type,
+                            typename __Operation::result_type>
+{
+protected:
+    __Operation                                op;
+    typename __Operation::second_argument_type value;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y)
+        : op(__x), value(__y) {}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (      typename __Operation::first_argument_type& __x) const
+            {return op(__x, value);}
+    _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator()
+        (const typename __Operation::first_argument_type& __x) const
+            {return op(__x, value);}
+};
+
+template <class __Operation, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+binder2nd<__Operation>
+bind2nd(const __Operation& __op, const _Tp& __x)
+    {return binder2nd<__Operation>(__op, __x);}
+
+template <class _Arg, class _Result>
+class _LIBCPP_TYPE_VIS_ONLY pointer_to_unary_function
+    : public unary_function<_Arg, _Result>
+{
+    _Result (*__f_)(_Arg);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg))
+        : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const
+        {return __f_(__x);}
+};
+
+template <class _Arg, class _Result>
+inline _LIBCPP_INLINE_VISIBILITY
+pointer_to_unary_function<_Arg,_Result>
+ptr_fun(_Result (*__f)(_Arg))
+    {return pointer_to_unary_function<_Arg,_Result>(__f);}
+
+template <class _Arg1, class _Arg2, class _Result>
+class _LIBCPP_TYPE_VIS_ONLY pointer_to_binary_function
+    : public binary_function<_Arg1, _Arg2, _Result>
+{
+    _Result (*__f_)(_Arg1, _Arg2);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2))
+        : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const
+        {return __f_(__x, __y);}
+};
+
+template <class _Arg1, class _Arg2, class _Result>
+inline _LIBCPP_INLINE_VISIBILITY
+pointer_to_binary_function<_Arg1,_Arg2,_Result>
+ptr_fun(_Result (*__f)(_Arg1,_Arg2))
+    {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);}
+
+template<class _Sp, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun_t : public unary_function<_Tp*, _Sp>
+{
+    _Sp (_Tp::*__p_)();
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)())
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const
+        {return (__p->*__p_)();}
+};
+
+template<class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap))
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const
+        {return (__p->*__p_)(__x);}
+};
+
+template<class _Sp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+mem_fun_t<_Sp,_Tp>
+mem_fun(_Sp (_Tp::*__f)())
+    {return mem_fun_t<_Sp,_Tp>(__f);}
+
+template<class _Sp, class _Tp, class _Ap>
+inline _LIBCPP_INLINE_VISIBILITY
+mem_fun1_t<_Sp,_Tp,_Ap>
+mem_fun(_Sp (_Tp::*__f)(_Ap))
+    {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
+
+template<class _Sp, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun_ref_t : public unary_function<_Tp, _Sp>
+{
+    _Sp (_Tp::*__p_)();
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)())
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const
+        {return (__p.*__p_)();}
+};
+
+template<class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TYPE_VIS_ONLY mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap);
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap))
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const
+        {return (__p.*__p_)(__x);}
+};
+
+template<class _Sp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+mem_fun_ref_t<_Sp,_Tp>
+mem_fun_ref(_Sp (_Tp::*__f)())
+    {return mem_fun_ref_t<_Sp,_Tp>(__f);}
+
+template<class _Sp, class _Tp, class _Ap>
+inline _LIBCPP_INLINE_VISIBILITY
+mem_fun1_ref_t<_Sp,_Tp,_Ap>
+mem_fun_ref(_Sp (_Tp::*__f)(_Ap))
+    {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
+
+template <class _Sp, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_t : public unary_function<const _Tp*, _Sp>
+{
+    _Sp (_Tp::*__p_)() const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const
+        {return (__p->*__p_)();}
+};
+
+template <class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap) const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const
+        {return (__p->*__p_)(__x);}
+};
+
+template <class _Sp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun_t<_Sp,_Tp>
+mem_fun(_Sp (_Tp::*__f)() const)
+    {return const_mem_fun_t<_Sp,_Tp>(__f);}
+
+template <class _Sp, class _Tp, class _Ap>
+inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun1_t<_Sp,_Tp,_Ap>
+mem_fun(_Sp (_Tp::*__f)(_Ap) const)
+    {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);}
+
+template <class _Sp, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun_ref_t : public unary_function<_Tp, _Sp>
+{
+    _Sp (_Tp::*__p_)() const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const
+        {return (__p.*__p_)();}
+};
+
+template <class _Sp, class _Tp, class _Ap>
+class _LIBCPP_TYPE_VIS_ONLY const_mem_fun1_ref_t
+    : public binary_function<_Tp, _Ap, _Sp>
+{
+    _Sp (_Tp::*__p_)(_Ap) const;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const
+        {return (__p.*__p_)(__x);}
+};
+
+template <class _Sp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun_ref_t<_Sp,_Tp>
+mem_fun_ref(_Sp (_Tp::*__f)() const)
+    {return const_mem_fun_ref_t<_Sp,_Tp>(__f);}
+
+template <class _Sp, class _Tp, class _Ap>
+inline _LIBCPP_INLINE_VISIBILITY
+const_mem_fun1_ref_t<_Sp,_Tp,_Ap>
+mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
+    {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+
+#include <__functional_03>
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp>
+class __mem_fn
+    : public __weak_result_type<_Tp>
+{
+public:
+    // types
+    typedef _Tp type;
+private:
+    type __f_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
+
+    // invoke
+    template <class... _ArgTypes>
+       _LIBCPP_INLINE_VISIBILITY
+       typename __invoke_return<type, _ArgTypes...>::type
+          operator() (_ArgTypes&&... __args) const
+          {
+              return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
+          }
+};
+
+template<class _Rp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__mem_fn<_Rp _Tp::*>
+mem_fn(_Rp _Tp::* __pm)
+{
+    return __mem_fn<_Rp _Tp::*>(__pm);
+}
+
+// bad_function_call
+
+class _LIBCPP_EXCEPTION_ABI bad_function_call
+    : public exception
+{
+};
+
+template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
+
+namespace __function
+{
+
+template<class _Rp, class ..._ArgTypes>
+struct __maybe_derive_from_unary_function
+{
+};
+
+template<class _Rp, class _A1>
+struct __maybe_derive_from_unary_function<_Rp(_A1)>
+    : public unary_function<_A1, _Rp>
+{
+};
+
+template<class _Rp, class ..._ArgTypes>
+struct __maybe_derive_from_binary_function
+{
+};
+
+template<class _Rp, class _A1, class _A2>
+struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
+    : public binary_function<_A1, _A2, _Rp>
+{
+};
+
+template<class _Fp> class __base;
+
+template<class _Rp, class ..._ArgTypes>
+class __base<_Rp(_ArgTypes...)>
+{
+    __base(const __base&);
+    __base& operator=(const __base&);
+public:
+    _LIBCPP_INLINE_VISIBILITY __base() {}
+    _LIBCPP_INLINE_VISIBILITY virtual ~__base() {}
+    virtual __base* __clone() const = 0;
+    virtual void __clone(__base*) const = 0;
+    virtual void destroy() _NOEXCEPT = 0;
+    virtual void destroy_deallocate() _NOEXCEPT = 0;
+    virtual _Rp operator()(_ArgTypes&& ...) = 0;
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const _NOEXCEPT = 0;
+    virtual const std::type_info& target_type() const _NOEXCEPT = 0;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _FD, class _Alloc, class _FB> class __func;
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+class __func<_Fp, _Alloc, _Rp(_ArgTypes...)>
+    : public  __base<_Rp(_ArgTypes...)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(_Fp&& __f)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+                                    _VSTD::forward_as_tuple()) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(const _Fp& __f, const _Alloc& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+                                    _VSTD::forward_as_tuple(__a)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(const _Fp& __f, _Alloc&& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
+                                    _VSTD::forward_as_tuple(_VSTD::move(__a))) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __func(_Fp&& __f, _Alloc&& __a)
+        : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
+                                    _VSTD::forward_as_tuple(_VSTD::move(__a))) {}
+    virtual __base<_Rp(_ArgTypes...)>* __clone() const;
+    virtual void __clone(__base<_Rp(_ArgTypes...)>*) const;
+    virtual void destroy() _NOEXCEPT;
+    virtual void destroy_deallocate() _NOEXCEPT;
+    virtual _Rp operator()(_ArgTypes&& ... __arg);
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* target(const type_info&) const _NOEXCEPT;
+    virtual const std::type_info& target_type() const _NOEXCEPT;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+__base<_Rp(_ArgTypes...)>*
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    typedef __allocator_destructor<_Ap> _Dp;
+    unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+    ::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
+    return __hold.release();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const
+{
+    ::new (__p) __func(__f_.first(), __f_.second());
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
+{
+    typedef typename _Alloc::template rebind<__func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+_Rp
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
+{
+    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+const void*
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT
+{
+    if (__ti == typeid(_Fp))
+        return &__f_.first();
+    return (const void*)0;
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+const std::type_info&
+__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
+{
+    return typeid(_Fp);
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+}  // __function
+
+template<class _Rp, class ..._ArgTypes>
+class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)>
+    : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>,
+      public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)>
+{
+    typedef __function::__base<_Rp(_ArgTypes...)> __base;
+    typename aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+    template <class _Fp>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const _Fp&) {return true;}
+    template <class _R2, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;}
+    template <class _R2, class _Cp, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;}
+    template <class _R2, class _Cp, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;}
+    template <class _R2, class _Cp, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;}
+    template <class _R2, class _Cp, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;}
+    template <class _R2, class ..._Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;}
+
+    template <class _Fp, bool = !is_same<_Fp, function>::value &&
+                                __invokable<_Fp&, _ArgTypes...>::value>
+        struct __callable;
+    template <class _Fp>
+        struct __callable<_Fp, true>
+        {
+            static const bool value =
+                is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
+                               _Rp>::value;
+        };
+    template <class _Fp>
+        struct __callable<_Fp, false>
+        {
+            static const bool value = false;
+        };
+public:
+    typedef _Rp result_type;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    function() _NOEXCEPT : __f_(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    function(nullptr_t) _NOEXCEPT : __f_(0) {}
+    function(const function&);
+    function(function&&) _NOEXCEPT;
+    template<class _Fp>
+      function(_Fp, typename enable_if
+                                     <
+                                        __callable<_Fp>::value &&
+                                        !is_same<_Fp, function>::value
+                                      >::type* = 0);
+
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {}
+    template<class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {}
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, const function&);
+    template<class _Alloc>
+      function(allocator_arg_t, const _Alloc&, function&&);
+    template<class _Fp, class _Alloc>
+      function(allocator_arg_t, const _Alloc& __a, _Fp __f,
+               typename enable_if<__callable<_Fp>::value>::type* = 0);
+
+    function& operator=(const function&);
+    function& operator=(function&&) _NOEXCEPT;
+    function& operator=(nullptr_t) _NOEXCEPT;
+    template<class _Fp>
+      typename enable_if
+      <
+        __callable<typename decay<_Fp>::type>::value &&
+        !is_same<typename remove_reference<_Fp>::type, function>::value,
+        function&
+      >::type
+      operator=(_Fp&&);
+
+    ~function();
+
+    // function modifiers:
+    void swap(function&) _NOEXCEPT;
+    template<class _Fp, class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      void assign(_Fp&& __f, const _Alloc& __a)
+        {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);}
+
+    // function capacity:
+    _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;}
+
+    // deleted overloads close possible hole in the type system
+    template<class _R2, class... _ArgTypes2>
+      bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete;
+    template<class _R2, class... _ArgTypes2>
+      bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete;
+public:
+    // function invocation:
+    _Rp operator()(_ArgTypes...) const;
+
+#ifndef _LIBCPP_NO_RTTI
+    // function target access:
+    const std::type_info& target_type() const _NOEXCEPT;
+    template <typename _Tp> _Tp* target() _NOEXCEPT;
+    template <typename _Tp> const _Tp* target() const _NOEXCEPT;
+#endif  // _LIBCPP_NO_RTTI
+};
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>::function(const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
+                                     const function& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (const __base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+        __f_ = __f.__f_->__clone();
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+    {
+        __f_ = __f.__f_;
+        __f.__f_ = 0;
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
+                                     function&& __f)
+{
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+    {
+        __f_ = __f.__f_;
+        __f.__f_ = 0;
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp>
+function<_Rp(_ArgTypes...)>::function(_Fp __f,
+                                     typename enable_if
+                                     <
+                                        __callable<_Fp>::value &&
+                                        !is_same<_Fp, function>::value
+                                     >::type*)
+    : __f_(0)
+{
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF;
+        if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value)
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(_VSTD::move(__f));
+        }
+        else
+        {
+            typedef allocator<_FF> _Ap;
+            _Ap __a;
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp, class _Alloc>
+function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
+                                     typename enable_if<__callable<_Fp>::value>::type*)
+    : __f_(0)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    if (__not_null(__f))
+    {
+        typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
+        typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<_FF>
+#else
+            rebind_alloc<_FF>::other
+#endif
+            _Ap;
+        _Ap __a(__a0);
+        if (sizeof(_FF) <= sizeof(__buf_) && 
+            is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
+        {
+            __f_ = (__base*)&__buf_;
+            ::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a));
+        }
+        else
+        {
+            typedef __allocator_destructor<_Ap> _Dp;
+            unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+            ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a));
+            __f_ = __hold.release();
+        }
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(const function& __f)
+{
+    function(__f).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+    if (__f.__f_ == 0)
+        __f_ = 0;
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__clone(__f_);
+    }
+    else
+    {
+        __f_ = __f.__f_;
+        __f.__f_ = 0;
+    }
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>&
+function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = 0;
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp>
+typename enable_if
+<
+    function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value &&
+    !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value,
+    function<_Rp(_ArgTypes...)>&
+>::type
+function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
+{
+    function(_VSTD::forward<_Fp>(__f)).swap(*this);
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+function<_Rp(_ArgTypes...)>::~function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class ..._ArgTypes>
+void
+function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__clone(__t);
+        __f_->destroy();
+        __f_ = 0;
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = 0;
+        __f_ = (__base*)&__buf_;
+        __t->__clone((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__clone((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__clone((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class ..._ArgTypes>
+_Rp
+function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__f_ == 0)
+        throw bad_function_call();
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Rp, class ..._ArgTypes>
+const std::type_info&
+function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT
+{
+    if (__f_ == 0)
+        return typeid(void);
+    return __f_->target_type();
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <typename _Tp>
+_Tp*
+function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
+{
+    if (__f_ == 0)
+        return (_Tp*)0;
+    return (_Tp*)__f_->target(typeid(_Tp));
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <typename _Tp>
+const _Tp*
+function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
+{
+    if (__f_ == 0)
+        return (const _Tp*)0;
+    return (const _Tp*)__f_->target(typeid(_Tp));
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;}
+
+template <class _Rp, class... _ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
+{return __x.swap(__y);}
+
+template<class _Tp> struct __is_bind_expression : public false_type {};
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
+    : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
+
+template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
+template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
+    : public __is_placeholder<typename remove_cv<_Tp>::type> {};
+
+namespace placeholders
+{
+
+template <int _Np> struct __ph {};
+
+_LIBCPP_FUNC_VIS extern __ph<1>   _1;
+_LIBCPP_FUNC_VIS extern __ph<2>   _2;
+_LIBCPP_FUNC_VIS extern __ph<3>   _3;
+_LIBCPP_FUNC_VIS extern __ph<4>   _4;
+_LIBCPP_FUNC_VIS extern __ph<5>   _5;
+_LIBCPP_FUNC_VIS extern __ph<6>   _6;
+_LIBCPP_FUNC_VIS extern __ph<7>   _7;
+_LIBCPP_FUNC_VIS extern __ph<8>   _8;
+_LIBCPP_FUNC_VIS extern __ph<9>   _9;
+_LIBCPP_FUNC_VIS extern __ph<10> _10;
+
+}  // placeholders
+
+template<int _Np>
+struct __is_placeholder<placeholders::__ph<_Np> >
+    : public integral_constant<int, _Np> {};
+
+template <class _Tp, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp&
+__mu(reference_wrapper<_Tp> __t, _Uj&)
+{
+    return __t.get();
+}
+
+template <class _Ti, class ..._Uj, size_t ..._Indx>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __invoke_of<_Ti&, _Uj...>::type
+__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>)
+{
+    return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...);
+}
+
+template <class _Ti, class ..._Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_bind_expression<_Ti>::value,
+    typename __invoke_of<_Ti&, _Uj...>::type
+>::type
+__mu(_Ti& __ti, tuple<_Uj...>& __uj)
+{
+    typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
+    return  __mu_expand(__ti, __uj, __indices());
+}
+
+template <bool IsPh, class _Ti, class _Uj>
+struct __mu_return2 {};
+
+template <class _Ti, class _Uj>
+struct __mu_return2<true, _Ti, _Uj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
+};
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    0 < is_placeholder<_Ti>::value,
+    typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
+>::type
+__mu(_Ti&, _Uj& __uj)
+{
+    const size_t _Indx = is_placeholder<_Ti>::value - 1;
+    return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
+}
+
+template <class _Ti, class _Uj>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_bind_expression<_Ti>::value &&
+    is_placeholder<_Ti>::value == 0 &&
+    !__is_reference_wrapper<_Ti>::value,
+    _Ti&
+>::type
+__mu(_Ti& __ti, _Uj&)
+{
+    return __ti;
+}
+
+template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh,
+          class _TupleUj>
+struct ____mu_return;
+
+template <bool _Invokable, class _Ti, class ..._Uj>
+struct ____mu_return_invokable  // false
+{
+    typedef __nat type;
+};
+
+template <class _Ti, class ..._Uj>
+struct ____mu_return_invokable<true, _Ti, _Uj...>
+{
+    typedef typename __invoke_of<_Ti&, _Uj...>::type type;
+};
+
+template <class _Ti, class ..._Uj>
+struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> >
+    : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...>
+{
+};
+
+template <class _Ti, class _TupleUj>
+struct ____mu_return<_Ti, false, false, true, _TupleUj>
+{
+    typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
+                                   _TupleUj>::type&& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct ____mu_return<_Ti, true, false, false, _TupleUj>
+{
+    typedef typename _Ti::type& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct ____mu_return<_Ti, false, false, false, _TupleUj>
+{
+    typedef _Ti& type;
+};
+
+template <class _Ti, class _TupleUj>
+struct __mu_return
+    : public ____mu_return<_Ti,
+                           __is_reference_wrapper<_Ti>::value,
+                           is_bind_expression<_Ti>::value,
+                           0 < is_placeholder<_Ti>::value &&
+                           is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value,
+                           _TupleUj>
+{
+};
+
+template <class _Fp, class _BoundArgs, class _TupleUj>
+struct _is_valid_bind_return
+{
+    static const bool value = false;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct _is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
+{
+    static const bool value = __invokable<_Fp,
+                    typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct _is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
+{
+    static const bool value = __invokable<_Fp,
+                    typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
+};
+
+template <class _Fp, class _BoundArgs, class _TupleUj,
+          bool = _is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
+struct __bind_return;
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true>
+{
+    typedef typename __invoke_of
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class ..._BoundArgs, class _TupleUj>
+struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true>
+{
+    typedef typename __invoke_of
+    <
+        _Fp&,
+        typename __mu_return
+        <
+            const _BoundArgs,
+            _TupleUj
+        >::type...
+    >::type type;
+};
+
+template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __bind_return<_Fp, _BoundArgs, _Args>::type
+__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
+                _Args&& __args)
+{
+    return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
+}
+
+template<class _Fp, class ..._BoundArgs>
+class __bind
+    : public __weak_result_type<typename decay<_Fp>::type>
+{
+protected:
+    typedef typename decay<_Fp>::type _Fd;
+    typedef tuple<typename decay<_BoundArgs>::type...> _Td;
+private:
+    _Fd __f_;
+    _Td __bound_args_;
+
+    typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
+public:
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind(const __bind& __b)
+        : __f_(__b.__f_),
+          __bound_args_(__b.__bound_args_) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind& operator=(const __bind& __b)
+    {
+        __f_ = __b.__f_;
+        __bound_args_ = __b.__bound_args_;
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind(__bind&& __b)
+        : __f_(_VSTD::move(__b.__f_)),
+          __bound_args_(_VSTD::move(__b.__bound_args_)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind& operator=(__bind&& __b)
+    {
+        __f_ = _VSTD::move(__b.__f_);
+        __bound_args_ = _VSTD::move(__b.__bound_args_);
+        return *this;
+    }
+
+#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    template <class _Gp, class ..._BA,
+              class = typename enable_if
+                               <
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind>::value
+                               >::type>
+      _LIBCPP_INLINE_VISIBILITY
+      explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
+        : __f_(_VSTD::forward<_Gp>(__f)),
+          __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args)
+        {
+            return __apply_functor(__f_, __bound_args_, __indices(),
+                                  tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
+        }
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
+        operator()(_Args&& ...__args) const
+        {
+            return __apply_functor(__f_, __bound_args_, __indices(),
+                                   tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
+        }
+};
+
+template<class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+class __bind_r
+    : public __bind<_Fp, _BoundArgs...>
+{
+    typedef __bind<_Fp, _BoundArgs...> base;
+    typedef typename base::_Fd _Fd;
+    typedef typename base::_Td _Td;
+public:
+    typedef _Rp result_type;
+
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind_r(const __bind_r& __b)
+        : base(_VSTD::forward<const base&>(__b)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind_r& operator=(const __bind_r& __b)
+    {
+        base::operator=(_VSTD::forward<const base&>(__b));
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind_r(__bind_r&& __b)
+        : base(_VSTD::forward<base>(__b)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bind_r& operator=(__bind_r&& __b)
+    {
+        base::operator=(_VSTD::forward<base>(__b));
+        return *this;
+    }
+
+#endif  // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
+    template <class _Gp, class ..._BA,
+              class = typename enable_if
+                               <
+                                  is_constructible<_Fd, _Gp>::value &&
+                                  !is_same<typename remove_reference<_Gp>::type,
+                                           __bind_r>::value
+                               >::type>
+      _LIBCPP_INLINE_VISIBILITY
+      explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
+        : base(_VSTD::forward<_Gp>(__f),
+               _VSTD::forward<_BA>(__bound_args)...) {}
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
+                           result_type>::value,
+            result_type
+        >::type
+        operator()(_Args&& ...__args)
+        {
+            return base::operator()(_VSTD::forward<_Args>(__args)...);
+        }
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
+                           result_type>::value,
+            result_type
+        >::type
+        operator()(_Args&& ...__args) const
+        {
+            return base::operator()(_VSTD::forward<_Args>(__args)...);
+        }
+};
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
+
+template<class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY
+__bind<_Fp, _BoundArgs...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind<_Fp, _BoundArgs...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+
+template<class _Rp, class _Fp, class ..._BoundArgs>
+inline _LIBCPP_INLINE_VISIBILITY
+__bind_r<_Rp, _Fp, _BoundArgs...>
+bind(_Fp&& __f, _BoundArgs&&... __bound_args)
+{
+    typedef __bind_r<_Rp, _Fp, _BoundArgs...> type;
+    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<bool>
+    : public unary_function<bool, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char>
+    : public unary_function<char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<signed char>
+    : public unary_function<signed char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned char>
+    : public unary_function<unsigned char, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char16_t>
+    : public unary_function<char16_t, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<char32_t>
+    : public unary_function<char32_t, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<wchar_t>
+    : public unary_function<wchar_t, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<short>
+    : public unary_function<short, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned short>
+    : public unary_function<unsigned short, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<int>
+    : public unary_function<int, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned int>
+    : public unary_function<unsigned int, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long>
+    : public unary_function<long, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long>
+    : public unary_function<unsigned long, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);}
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long long>
+    : public __scalar_hash<long long>
+{
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long long>
+    : public __scalar_hash<unsigned long long>
+{
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<float>
+    : public __scalar_hash<float>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(float __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+       if (__v == 0)
+           return 0;
+        return __scalar_hash<float>::operator()(__v);
+    }
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<double>
+    : public __scalar_hash<double>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(double __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+       if (__v == 0)
+           return 0;
+        return __scalar_hash<double>::operator()(__v);
+    }
+};
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<long double>
+    : public __scalar_hash<long double>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(long double __v) const _NOEXCEPT
+    {
+        // -0.0 and 0.0 should return same hash
+        if (__v == 0)
+            return 0;
+#if defined(__i386__)
+        // Zero out padding bits
+        union
+        {
+            long double __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+                size_t __d;
+            };
+        } __u;
+        __u.__a = 0;
+        __u.__b = 0;
+        __u.__c = 0;
+        __u.__d = 0;
+        __u.__t = __v;
+        return __u.__a ^ __u.__b ^ __u.__c ^ __u.__d;
+#elif defined(__x86_64__)
+        // Zero out padding bits
+        union
+        {
+            long double __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+            };
+        } __u;
+        __u.__a = 0;
+        __u.__b = 0;
+        __u.__t = __v;
+        return __u.__a ^ __u.__b;
+#else
+        return __scalar_hash<long double>::operator()(__v);
+#endif
+    }
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash
+    : public unary_function<_Tp, size_t>
+{
+    static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types");
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        typedef typename underlying_type<_Tp>::type type;
+        return hash<type>{}(static_cast<type>(__v));
+    }
+};
+#endif
+
+// struct hash<T*> in <memory>
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_FUNCTIONAL
diff --git a/include/c++/v1/future b/include/c++/v1/future
new file mode 100644
index 0000000..de00f25
--- /dev/null
+++ b/include/c++/v1/future
@@ -0,0 +1,2615 @@
+// -*- C++ -*-
+//===--------------------------- future -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_FUTURE
+#define _LIBCPP_FUTURE
+
+/*
+    future synopsis
+
+namespace std
+{
+
+enum class future_errc
+{
+    future_already_retrieved = 1,
+    promise_already_satisfied,
+    no_state,
+    broken_promise
+};
+
+enum class launch
+{
+    async = 1,
+    deferred = 2,
+    any = async | deferred
+};
+
+enum class future_status
+{
+    ready,
+    timeout,
+    deferred
+};
+
+template <> struct is_error_code_enum<future_errc> : public true_type { };
+error_code make_error_code(future_errc e) noexcept;
+error_condition make_error_condition(future_errc e) noexcept;
+
+const error_category& future_category() noexcept;
+
+class future_error
+    : public logic_error
+{
+public:
+    future_error(error_code ec);  // exposition only
+
+    const error_code& code() const noexcept;
+    const char*       what() const noexcept;
+};
+
+template <class R>
+class promise
+{
+public:
+    promise();
+    template <class Allocator>
+        promise(allocator_arg_t, const Allocator& a);
+    promise(promise&& rhs) noexcept;
+    promise(const promise& rhs) = delete;
+    ~promise();
+
+    // assignment
+    promise& operator=(promise&& rhs) noexcept;
+    promise& operator=(const promise& rhs) = delete;
+    void swap(promise& other) noexcept;
+
+    // retrieving the result
+    future<R> get_future();
+
+    // setting the result
+    void set_value(const R& r);
+    void set_value(R&& r);
+    void set_exception(exception_ptr p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit(const R& r);
+    void set_value_at_thread_exit(R&& r);
+    void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <class R>
+class promise<R&>
+{
+public:
+    promise();
+    template <class Allocator>
+        promise(allocator_arg_t, const Allocator& a);
+    promise(promise&& rhs) noexcept;
+    promise(const promise& rhs) = delete;
+    ~promise();
+
+    // assignment
+    promise& operator=(promise&& rhs) noexcept;
+    promise& operator=(const promise& rhs) = delete;
+    void swap(promise& other) noexcept;
+
+    // retrieving the result
+    future<R&> get_future();
+
+    // setting the result
+    void set_value(R& r);
+    void set_exception(exception_ptr p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit(R&);
+    void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <>
+class promise<void>
+{
+public:
+    promise();
+    template <class Allocator>
+        promise(allocator_arg_t, const Allocator& a);
+    promise(promise&& rhs) noexcept;
+    promise(const promise& rhs) = delete;
+    ~promise();
+
+    // assignment
+    promise& operator=(promise&& rhs) noexcept;
+    promise& operator=(const promise& rhs) = delete;
+    void swap(promise& other) noexcept;
+
+    // retrieving the result
+    future<void> get_future();
+
+    // setting the result
+    void set_value();
+    void set_exception(exception_ptr p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit();
+    void set_exception_at_thread_exit(exception_ptr p);
+};
+
+template <class R> void swap(promise<R>& x, promise<R>& y) noexcept;
+
+template <class R, class Alloc>
+    struct uses_allocator<promise<R>, Alloc> : public true_type {};
+
+template <class R>
+class future
+{
+public:
+    future() noexcept;
+    future(future&&) noexcept;
+    future(const future& rhs) = delete;
+    ~future();
+    future& operator=(const future& rhs) = delete;
+    future& operator=(future&&) noexcept;
+    shared_future<R> share();
+
+    // retrieving the value
+    R get();
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class future<R&>
+{
+public:
+    future() noexcept;
+    future(future&&) noexcept;
+    future(const future& rhs) = delete;
+    ~future();
+    future& operator=(const future& rhs) = delete;
+    future& operator=(future&&) noexcept;
+    shared_future<R&> share();
+
+    // retrieving the value
+    R& get();
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <>
+class future<void>
+{
+public:
+    future() noexcept;
+    future(future&&) noexcept;
+    future(const future& rhs) = delete;
+    ~future();
+    future& operator=(const future& rhs) = delete;
+    future& operator=(future&&) noexcept;
+    shared_future<void> share();
+
+    // retrieving the value
+    void get();
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class shared_future
+{
+public:
+    shared_future() noexcept;
+    shared_future(const shared_future& rhs);
+    shared_future(future<R>&&) noexcept;
+    shared_future(shared_future&& rhs) noexcept;
+    ~shared_future();
+    shared_future& operator=(const shared_future& rhs);
+    shared_future& operator=(shared_future&& rhs) noexcept;
+
+    // retrieving the value
+    const R& get() const;
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class R>
+class shared_future<R&>
+{
+public:
+    shared_future() noexcept;
+    shared_future(const shared_future& rhs);
+    shared_future(future<R&>&&) noexcept;
+    shared_future(shared_future&& rhs) noexcept;
+    ~shared_future();
+    shared_future& operator=(const shared_future& rhs);
+    shared_future& operator=(shared_future&& rhs) noexcept;
+
+    // retrieving the value
+    R& get() const;
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <>
+class shared_future<void>
+{
+public:
+    shared_future() noexcept;
+    shared_future(const shared_future& rhs);
+    shared_future(future<void>&&) noexcept;
+    shared_future(shared_future&& rhs) noexcept;
+    ~shared_future();
+    shared_future& operator=(const shared_future& rhs);
+    shared_future& operator=(shared_future&& rhs) noexcept;
+
+    // retrieving the value
+    void get() const;
+
+    // functions to check state
+    bool valid() const noexcept;
+
+    void wait() const;
+    template <class Rep, class Period>
+        future_status
+        wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+    template <class Clock, class Duration>
+        future_status
+        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+};
+
+template <class F, class... Args>
+  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
+  async(F&& f, Args&&... args);
+
+template <class F, class... Args>
+  future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
+  async(launch policy, F&& f, Args&&... args);
+
+template <class> class packaged_task; // undefined
+
+template <class R, class... ArgTypes>
+class packaged_task<R(ArgTypes...)>
+{
+public:
+    typedef R result_type;
+
+    // construction and destruction
+    packaged_task() noexcept;
+    template <class F>
+        explicit packaged_task(F&& f);
+    template <class F, class Allocator>
+        explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+    ~packaged_task();
+
+    // no copy
+    packaged_task(const packaged_task&) = delete;
+    packaged_task& operator=(const packaged_task&) = delete;
+
+    // move support
+    packaged_task(packaged_task&& other) noexcept;
+    packaged_task& operator=(packaged_task&& other) noexcept;
+    void swap(packaged_task& other) noexcept;
+
+    bool valid() const noexcept;
+
+    // result retrieval
+    future<R> get_future();
+
+    // execution
+    void operator()(ArgTypes... );
+    void make_ready_at_thread_exit(ArgTypes...);
+
+    void reset();
+};
+
+template <class R>
+  void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
+
+template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <system_error>
+#include <memory>
+#include <chrono>
+#include <exception>
+#include <mutex>
+#include <thread>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+//enum class future_errc
+_LIBCPP_DECLARE_STRONG_ENUM(future_errc)
+{
+    future_already_retrieved = 1,
+    promise_already_satisfied,
+    no_state,
+    broken_promise
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_errc)
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc> : public true_type {};
+
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<future_errc::__lx> : public true_type { };
+#endif
+
+//enum class launch
+_LIBCPP_DECLARE_STRONG_ENUM(launch)
+{
+    async = 1,
+    deferred = 2,
+    any = async | deferred
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(launch)
+
+#ifndef _LIBCPP_HAS_NO_STRONG_ENUMS
+
+#ifdef _LIBCXX_UNDERLYING_TYPE
+typedef underlying_type<launch>::type __launch_underlying_type;
+#else
+typedef int __launch_underlying_type;
+#endif
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator&(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) &
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator|(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) |
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator^(launch __x, launch __y)
+{
+    return static_cast<launch>(static_cast<__launch_underlying_type>(__x) ^
+                               static_cast<__launch_underlying_type>(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+launch
+operator~(launch __x)
+{
+    return static_cast<launch>(~static_cast<__launch_underlying_type>(__x) & 3);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator&=(launch& __x, launch __y)
+{
+    __x = __x & __y; return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator|=(launch& __x, launch __y)
+{
+    __x = __x | __y; return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+launch&
+operator^=(launch& __x, launch __y)
+{
+    __x = __x ^ __y; return __x;
+}
+
+#endif  // !_LIBCPP_HAS_NO_STRONG_ENUMS
+
+//enum class future_status
+_LIBCPP_DECLARE_STRONG_ENUM(future_status)
+{
+    ready,
+    timeout,
+    deferred
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status)
+
+_LIBCPP_FUNC_VIS
+const error_category& future_category() _NOEXCEPT;
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_code
+make_error_code(future_errc __e) _NOEXCEPT
+{
+    return error_code(static_cast<int>(__e), future_category());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_condition
+make_error_condition(future_errc __e) _NOEXCEPT
+{
+    return error_condition(static_cast<int>(__e), future_category());
+}
+
+class _LIBCPP_EXCEPTION_ABI future_error
+    : public logic_error
+{
+    error_code __ec_;
+public:
+    future_error(error_code __ec);
+
+    _LIBCPP_INLINE_VISIBILITY
+    const error_code& code() const _NOEXCEPT {return __ec_;}
+
+    virtual ~future_error() _NOEXCEPT;
+};
+
+class _LIBCPP_TYPE_VIS __assoc_sub_state
+    : public __shared_count
+{
+protected:
+    exception_ptr __exception_;
+    mutable mutex __mut_;
+    mutable condition_variable __cv_;
+    unsigned __state_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+    void __sub_wait(unique_lock<mutex>& __lk);
+public:
+    enum
+    {
+        __constructed = 1,
+        __future_attached = 2,
+        ready = 4,
+        deferred = 8
+    };
+
+    _LIBCPP_INLINE_VISIBILITY
+    __assoc_sub_state() : __state_(0) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __has_value() const
+        {return (__state_ & __constructed) || (__exception_ != nullptr);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_future_attached()
+    {
+        lock_guard<mutex> __lk(__mut_);
+        __state_ |= __future_attached;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    bool __has_future_attached() const {return (__state_ & __future_attached) != 0;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_deferred() {__state_ |= deferred;}
+
+    void __make_ready();
+    _LIBCPP_INLINE_VISIBILITY
+    bool __is_ready() const {return (__state_ & ready) != 0;}
+
+    void set_value();
+    void set_value_at_thread_exit();
+
+    void set_exception(exception_ptr __p);
+    void set_exception_at_thread_exit(exception_ptr __p);
+
+    void copy();
+
+    void wait();
+    template <class _Rep, class _Period>
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
+    template <class _Clock, class _Duration>
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
+
+    virtual void __execute();
+};
+
+template <class _Clock, class _Duration>
+future_status
+__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+{
+    unique_lock<mutex> __lk(__mut_);
+    if (__state_ & deferred)
+        return future_status::deferred;
+    while (!(__state_ & ready) && _Clock::now() < __abs_time)
+        __cv_.wait_until(__lk, __abs_time);
+    if (__state_ & ready)
+        return future_status::ready;
+    return future_status::timeout;
+}
+
+template <class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+future_status
+__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+{
+    return wait_until(chrono::steady_clock::now() + __rel_time);
+}
+
+template <class _Rp>
+class __assoc_state
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+    typedef typename aligned_storage<sizeof(_Rp), alignment_of<_Rp>::value>::type _Up;
+protected:
+    _Up __value_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+
+    template <class _Arg>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        void set_value(_Arg&& __arg);
+#else
+        void set_value(_Arg& __arg);
+#endif
+
+    template <class _Arg>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        void set_value_at_thread_exit(_Arg&& __arg);
+#else
+        void set_value_at_thread_exit(_Arg& __arg);
+#endif
+
+    _Rp move();
+    typename add_lvalue_reference<_Rp>::type copy();
+};
+
+template <class _Rp>
+void
+__assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
+{
+    if (this->__state_ & base::__constructed)
+        reinterpret_cast<_Rp*>(&__value_)->~_Rp();
+    delete this;
+}
+
+template <class _Rp>
+template <class _Arg>
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__assoc_state<_Rp>::set_value(_Arg&& __arg)
+#else
+__assoc_state<_Rp>::set_value(_Arg& __arg)
+#endif
+{
+    unique_lock<mutex> __lk(this->__mut_);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+#endif
+    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
+    this->__state_ |= base::__constructed | base::ready;
+    __lk.unlock();
+    __cv_.notify_all();
+}
+
+template <class _Rp>
+template <class _Arg>
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__assoc_state<_Rp>::set_value_at_thread_exit(_Arg&& __arg)
+#else
+__assoc_state<_Rp>::set_value_at_thread_exit(_Arg& __arg)
+#endif
+{
+    unique_lock<mutex> __lk(this->__mut_);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+#endif
+    ::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
+    this->__state_ |= base::__constructed;
+    __thread_local_data()->__make_ready_at_thread_exit(this);
+    __lk.unlock();
+}
+
+template <class _Rp>
+_Rp
+__assoc_state<_Rp>::move()
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    this->__sub_wait(__lk);
+    if (this->__exception_ != nullptr)
+        rethrow_exception(this->__exception_);
+    return _VSTD::move(*reinterpret_cast<_Rp*>(&__value_));
+}
+
+template <class _Rp>
+typename add_lvalue_reference<_Rp>::type
+__assoc_state<_Rp>::copy()
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    this->__sub_wait(__lk);
+    if (this->__exception_ != nullptr)
+        rethrow_exception(this->__exception_);
+    return *reinterpret_cast<_Rp*>(&__value_);
+}
+
+template <class _Rp>
+class __assoc_state<_Rp&>
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+    typedef _Rp* _Up;
+protected:
+    _Up __value_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+
+    void set_value(_Rp& __arg);
+    void set_value_at_thread_exit(_Rp& __arg);
+
+    _Rp& copy();
+};
+
+template <class _Rp>
+void
+__assoc_state<_Rp&>::__on_zero_shared() _NOEXCEPT
+{
+    delete this;
+}
+
+template <class _Rp>
+void
+__assoc_state<_Rp&>::set_value(_Rp& __arg)
+{
+    unique_lock<mutex> __lk(this->__mut_);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+#endif
+    __value_ = _VSTD::addressof(__arg);
+    this->__state_ |= base::__constructed | base::ready;
+    __lk.unlock();
+    __cv_.notify_all();
+}
+
+template <class _Rp>
+void
+__assoc_state<_Rp&>::set_value_at_thread_exit(_Rp& __arg)
+{
+    unique_lock<mutex> __lk(this->__mut_);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+#endif
+    __value_ = _VSTD::addressof(__arg);
+    this->__state_ |= base::__constructed;
+    __thread_local_data()->__make_ready_at_thread_exit(this);
+    __lk.unlock();
+}
+
+template <class _Rp>
+_Rp&
+__assoc_state<_Rp&>::copy()
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    this->__sub_wait(__lk);
+    if (this->__exception_ != nullptr)
+        rethrow_exception(this->__exception_);
+    return *__value_;
+}
+
+template <class _Rp, class _Alloc>
+class __assoc_state_alloc
+    : public __assoc_state<_Rp>
+{
+    typedef __assoc_state<_Rp> base;
+    _Alloc __alloc_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __assoc_state_alloc(const _Alloc& __a)
+        : __alloc_(__a) {}
+};
+
+template <class _Rp, class _Alloc>
+void
+__assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    if (this->__state_ & base::__constructed)
+        reinterpret_cast<_Rp*>(_VSTD::addressof(this->__value_))->~_Rp();
+    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    this->~__assoc_state_alloc();
+    __a.deallocate(this, 1);
+}
+
+template <class _Rp, class _Alloc>
+class __assoc_state_alloc<_Rp&, _Alloc>
+    : public __assoc_state<_Rp&>
+{
+    typedef __assoc_state<_Rp&> base;
+    _Alloc __alloc_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __assoc_state_alloc(const _Alloc& __a)
+        : __alloc_(__a) {}
+};
+
+template <class _Rp, class _Alloc>
+void
+__assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    this->~__assoc_state_alloc();
+    __a.deallocate(this, 1);
+}
+
+template <class _Alloc>
+class __assoc_sub_state_alloc
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+    _Alloc __alloc_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __assoc_sub_state_alloc(const _Alloc& __a)
+        : __alloc_(__a) {}
+};
+
+template <class _Alloc>
+void
+__assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
+    this->~__assoc_sub_state_alloc();
+    __a.deallocate(this, 1);
+}
+
+template <class _Rp, class _Fp>
+class __deferred_assoc_state
+    : public __assoc_state<_Rp>
+{
+    typedef __assoc_state<_Rp> base;
+
+    _Fp __func_;
+
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    explicit __deferred_assoc_state(_Fp&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp, class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<_Rp, _Fp>::__deferred_assoc_state(_Fp&& __f)
+    : __func_(_VSTD::forward<_Fp>(__f))
+{
+    this->__set_deferred();
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp, class _Fp>
+void
+__deferred_assoc_state<_Rp, _Fp>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        this->set_value(__func_());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Fp>
+class __deferred_assoc_state<void, _Fp>
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+
+    _Fp __func_;
+
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    explicit __deferred_assoc_state(_Fp&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+__deferred_assoc_state<void, _Fp>::__deferred_assoc_state(_Fp&& __f)
+    : __func_(_VSTD::forward<_Fp>(__f))
+{
+    this->__set_deferred();
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Fp>
+void
+__deferred_assoc_state<void, _Fp>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __func_();
+        this->set_value();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Rp, class _Fp>
+class __async_assoc_state
+    : public __assoc_state<_Rp>
+{
+    typedef __assoc_state<_Rp> base;
+
+    _Fp __func_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    explicit __async_assoc_state(_Fp&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp, class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+__async_assoc_state<_Rp, _Fp>::__async_assoc_state(_Fp&& __f)
+    : __func_(_VSTD::forward<_Fp>(__f))
+{
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp, class _Fp>
+void
+__async_assoc_state<_Rp, _Fp>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        this->set_value(__func_());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Rp, class _Fp>
+void
+__async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
+{
+    this->wait();
+    base::__on_zero_shared();
+}
+
+template <class _Fp>
+class __async_assoc_state<void, _Fp>
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+
+    _Fp __func_;
+
+    virtual void __on_zero_shared() _NOEXCEPT;
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    explicit __async_assoc_state(_Fp&& __f);
+#endif
+
+    virtual void __execute();
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+__async_assoc_state<void, _Fp>::__async_assoc_state(_Fp&& __f)
+    : __func_(_VSTD::forward<_Fp>(__f))
+{
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Fp>
+void
+__async_assoc_state<void, _Fp>::__execute()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __func_();
+        this->set_value();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Fp>
+void
+__async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT
+{
+    this->wait();
+    base::__on_zero_shared();
+}
+
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY promise;
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY shared_future;
+
+// future
+
+template <class _Rp> class _LIBCPP_TYPE_VIS_ONLY future;
+
+template <class _Rp, class _Fp>
+future<_Rp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__make_deferred_assoc_state(_Fp&& __f);
+#else
+__make_deferred_assoc_state(_Fp __f);
+#endif
+
+template <class _Rp, class _Fp>
+future<_Rp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__make_async_assoc_state(_Fp&& __f);
+#else
+__make_async_assoc_state(_Fp __f);
+#endif
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY future
+{
+    __assoc_state<_Rp>* __state_;
+
+    explicit future(__assoc_state<_Rp>* __state);
+
+    template <class> friend class promise;
+    template <class> friend class shared_future;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
+#else
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp __f);
+#endif
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    future() _NOEXCEPT : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    future(future&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    future(const future&) = delete;
+    future& operator=(const future&) = delete;
+    _LIBCPP_INLINE_VISIBILITY
+    future& operator=(future&& __rhs) _NOEXCEPT
+        {
+            future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    future(const future&);
+    future& operator=(const future&);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~future();
+    shared_future<_Rp> share();
+
+    // retrieving the value
+    _Rp get();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+future<_Rp>::future(__assoc_state<_Rp>* __state)
+    : __state_(__state)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_->__has_future_attached())
+        throw future_error(make_error_code(future_errc::future_already_retrieved));
+#endif
+    __state_->__add_shared();
+    __state_->__set_future_attached();
+}
+
+struct __release_shared_count
+{
+    void operator()(__shared_count* p) {p->__release_shared();}
+};
+
+template <class _Rp>
+future<_Rp>::~future()
+{
+    if (__state_)
+        __state_->__release_shared();
+}
+
+template <class _Rp>
+_Rp
+future<_Rp>::get()
+{
+    unique_ptr<__shared_count, __release_shared_count> __(__state_);
+    __assoc_state<_Rp>* __s = __state_;
+    __state_ = nullptr;
+    return __s->move();
+}
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY future<_Rp&>
+{
+    __assoc_state<_Rp&>* __state_;
+
+    explicit future(__assoc_state<_Rp&>* __state);
+
+    template <class> friend class promise;
+    template <class> friend class shared_future;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
+#else
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp __f);
+#endif
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    future() _NOEXCEPT : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    future(future&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    future(const future&) = delete;
+    future& operator=(const future&) = delete;
+    _LIBCPP_INLINE_VISIBILITY
+    future& operator=(future&& __rhs) _NOEXCEPT
+        {
+            future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    future(const future&);
+    future& operator=(const future&);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~future();
+    shared_future<_Rp&> share();
+
+    // retrieving the value
+    _Rp& get();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+future<_Rp&>::future(__assoc_state<_Rp&>* __state)
+    : __state_(__state)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_->__has_future_attached())
+        throw future_error(make_error_code(future_errc::future_already_retrieved));
+#endif
+    __state_->__add_shared();
+    __state_->__set_future_attached();
+}
+
+template <class _Rp>
+future<_Rp&>::~future()
+{
+    if (__state_)
+        __state_->__release_shared();
+}
+
+template <class _Rp>
+_Rp&
+future<_Rp&>::get()
+{
+    unique_ptr<__shared_count, __release_shared_count> __(__state_);
+    __assoc_state<_Rp&>* __s = __state_;
+    __state_ = nullptr;
+    return __s->copy();
+}
+
+template <>
+class _LIBCPP_TYPE_VIS future<void>
+{
+    __assoc_sub_state* __state_;
+
+    explicit future(__assoc_sub_state* __state);
+
+    template <class> friend class promise;
+    template <class> friend class shared_future;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp&& __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp&& __f);
+#else
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_deferred_assoc_state(_Fp __f);
+    template <class _R1, class _Fp>
+        friend future<_R1> __make_async_assoc_state(_Fp __f);
+#endif
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    future() _NOEXCEPT : __state_(nullptr) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    future(future&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    future(const future&) = delete;
+    future& operator=(const future&) = delete;
+    _LIBCPP_INLINE_VISIBILITY
+    future& operator=(future&& __rhs) _NOEXCEPT
+        {
+            future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    future(const future&);
+    future& operator=(const future&);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~future();
+    shared_future<void> share();
+
+    // retrieving the value
+    void get();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+// promise<R>
+
+template <class _Callable> class packaged_task;
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY promise
+{
+    __assoc_state<_Rp>* __state_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
+public:
+    promise();
+    template <class _Alloc>
+        promise(allocator_arg_t, const _Alloc& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise(promise&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    promise(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~promise();
+
+    // assignment
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise& operator=(promise&& __rhs) _NOEXCEPT
+        {
+            promise(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+    promise& operator=(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise& operator=(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // retrieving the result
+    future<_Rp> get_future();
+
+    // setting the result
+    void set_value(const _Rp& __r);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void set_value(_Rp&& __r);
+#endif
+    void set_exception(exception_ptr __p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit(const _Rp& __r);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void set_value_at_thread_exit(_Rp&& __r);
+#endif
+    void set_exception_at_thread_exit(exception_ptr __p);
+};
+
+template <class _Rp>
+promise<_Rp>::promise()
+    : __state_(new __assoc_state<_Rp>)
+{
+}
+
+template <class _Rp>
+template <class _Alloc>
+promise<_Rp>::promise(allocator_arg_t, const _Alloc& __a0)
+{
+    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp, _Alloc> >::other _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a(__a0);
+    unique_ptr<__assoc_state_alloc<_Rp, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(__hold.get()) __assoc_state_alloc<_Rp, _Alloc>(__a0);
+    __state_ = __hold.release();
+}
+
+template <class _Rp>
+promise<_Rp>::~promise()
+{
+    if (__state_)
+    {
+        if (!__state_->__has_value() && __state_->use_count() > 1)
+            __state_->set_exception(make_exception_ptr(
+                      future_error(make_error_code(future_errc::broken_promise))
+                                                      ));
+        __state_->__release_shared();
+    }
+}
+
+template <class _Rp>
+future<_Rp>
+promise<_Rp>::get_future()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    return future<_Rp>(__state_);
+}
+
+template <class _Rp>
+void
+promise<_Rp>::set_value(const _Rp& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value(__r);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp>
+void
+promise<_Rp>::set_value(_Rp&& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value(_VSTD::move(__r));
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp>
+void
+promise<_Rp>::set_exception(exception_ptr __p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_exception(__p);
+}
+
+template <class _Rp>
+void
+promise<_Rp>::set_value_at_thread_exit(const _Rp& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value_at_thread_exit(__r);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp>
+void
+promise<_Rp>::set_value_at_thread_exit(_Rp&& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value_at_thread_exit(_VSTD::move(__r));
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Rp>
+void
+promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_exception_at_thread_exit(__p);
+}
+
+// promise<R&>
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY promise<_Rp&>
+{
+    __assoc_state<_Rp&>* __state_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
+
+public:
+    promise();
+    template <class _Allocator>
+        promise(allocator_arg_t, const _Allocator& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise(promise&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    promise(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~promise();
+
+    // assignment
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise& operator=(promise&& __rhs) _NOEXCEPT
+        {
+            promise(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+    promise& operator=(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise& operator=(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // retrieving the result
+    future<_Rp&> get_future();
+
+    // setting the result
+    void set_value(_Rp& __r);
+    void set_exception(exception_ptr __p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit(_Rp&);
+    void set_exception_at_thread_exit(exception_ptr __p);
+};
+
+template <class _Rp>
+promise<_Rp&>::promise()
+    : __state_(new __assoc_state<_Rp&>)
+{
+}
+
+template <class _Rp>
+template <class _Alloc>
+promise<_Rp&>::promise(allocator_arg_t, const _Alloc& __a0)
+{
+    typedef typename _Alloc::template rebind<__assoc_state_alloc<_Rp&, _Alloc> >::other _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a(__a0);
+    unique_ptr<__assoc_state_alloc<_Rp&, _Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(__hold.get()) __assoc_state_alloc<_Rp&, _Alloc>(__a0);
+    __state_ = __hold.release();
+}
+
+template <class _Rp>
+promise<_Rp&>::~promise()
+{
+    if (__state_)
+    {
+        if (!__state_->__has_value() && __state_->use_count() > 1)
+            __state_->set_exception(make_exception_ptr(
+                      future_error(make_error_code(future_errc::broken_promise))
+                                                      ));
+        __state_->__release_shared();
+    }
+}
+
+template <class _Rp>
+future<_Rp&>
+promise<_Rp&>::get_future()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    return future<_Rp&>(__state_);
+}
+
+template <class _Rp>
+void
+promise<_Rp&>::set_value(_Rp& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value(__r);
+}
+
+template <class _Rp>
+void
+promise<_Rp&>::set_exception(exception_ptr __p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_exception(__p);
+}
+
+template <class _Rp>
+void
+promise<_Rp&>::set_value_at_thread_exit(_Rp& __r)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_value_at_thread_exit(__r);
+}
+
+template <class _Rp>
+void
+promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+#endif
+    __state_->set_exception_at_thread_exit(__p);
+}
+
+// promise<void>
+
+template <>
+class _LIBCPP_TYPE_VIS promise<void>
+{
+    __assoc_sub_state* __state_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit promise(nullptr_t) _NOEXCEPT : __state_(nullptr) {}
+
+    template <class> friend class packaged_task;
+
+public:
+    promise();
+    template <class _Allocator>
+        promise(allocator_arg_t, const _Allocator& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise(promise&& __rhs) _NOEXCEPT
+        : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;}
+    promise(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~promise();
+
+    // assignment
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    promise& operator=(promise&& __rhs) _NOEXCEPT
+        {
+            promise(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+    promise& operator=(const promise& __rhs) = delete;
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+private:
+    promise& operator=(const promise& __rhs);
+public:
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // retrieving the result
+    future<void> get_future();
+
+    // setting the result
+    void set_value();
+    void set_exception(exception_ptr __p);
+
+    // setting the result with deferred notification
+    void set_value_at_thread_exit();
+    void set_exception_at_thread_exit(exception_ptr __p);
+};
+
+template <class _Alloc>
+promise<void>::promise(allocator_arg_t, const _Alloc& __a0)
+{
+    typedef typename _Alloc::template rebind<__assoc_sub_state_alloc<_Alloc> >::other _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a(__a0);
+    unique_ptr<__assoc_sub_state_alloc<_Alloc>, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new(__hold.get()) __assoc_sub_state_alloc<_Alloc>(__a0);
+    __state_ = __hold.release();
+}
+
+template <class _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template <class _Rp, class _Alloc>
+    struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<promise<_Rp>, _Alloc>
+        : public true_type {};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// packaged_task
+
+template<class _Fp> class __packaged_task_base;
+
+template<class _Rp, class ..._ArgTypes>
+class __packaged_task_base<_Rp(_ArgTypes...)>
+{
+    __packaged_task_base(const __packaged_task_base&);
+    __packaged_task_base& operator=(const __packaged_task_base&);
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __packaged_task_base() {}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual ~__packaged_task_base() {}
+    virtual void __move_to(__packaged_task_base*) _NOEXCEPT = 0;
+    virtual void destroy() = 0;
+    virtual void destroy_deallocate() = 0;
+    virtual _Rp operator()(_ArgTypes&& ...) = 0;
+};
+
+template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
+    : public  __packaged_task_base<_Rp(_ArgTypes...)>
+{
+    __compressed_pair<_Fp, _Alloc> __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __packaged_task_func(const _Fp& __f, const _Alloc& __a)
+        : __f_(__f, __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __packaged_task_func(_Fp&& __f, const _Alloc& __a)
+        : __f_(_VSTD::move(__f), __a) {}
+    virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT;
+    virtual void destroy();
+    virtual void destroy_deallocate();
+    virtual _Rp operator()(_ArgTypes&& ... __args);
+};
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__move_to(
+                              __packaged_task_base<_Rp(_ArgTypes...)>* __p) _NOEXCEPT
+{
+    ::new (__p) __packaged_task_func(_VSTD::move(__f_.first()), _VSTD::move(__f_.second()));
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy()
+{
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+void
+__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate()
+{
+    typedef typename _Alloc::template rebind<__packaged_task_func>::other _Ap;
+    _Ap __a(__f_.second());
+    __f_.~__compressed_pair<_Fp, _Alloc>();
+    __a.deallocate(this, 1);
+}
+
+template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
+_Rp
+__packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg)
+{
+    return __invoke(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+template <class _Callable> class __packaged_task_function;
+
+template<class _Rp, class ..._ArgTypes>
+class __packaged_task_function<_Rp(_ArgTypes...)>
+{
+    typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
+    typename aligned_storage<3*sizeof(void*)>::type __buf_;
+    __base* __f_;
+
+public:
+    typedef _Rp result_type;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
+    template<class _Fp>
+      __packaged_task_function(_Fp&& __f);
+    template<class _Fp, class _Alloc>
+      __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
+
+    __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
+    __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
+
+    __packaged_task_function(const __packaged_task_function&) =  delete;
+    __packaged_task_function& operator=(const __packaged_task_function&) =  delete;
+
+    ~__packaged_task_function();
+
+    void swap(__packaged_task_function&) _NOEXCEPT;
+
+    _Rp operator()(_ArgTypes...) const;
+};
+
+template<class _Rp, class ..._ArgTypes>
+__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(__packaged_task_function&& __f) _NOEXCEPT
+{
+    if (__f.__f_ == nullptr)
+        __f_ = nullptr;
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__move_to(__f_);
+    }
+    else
+    {
+        __f_ = __f.__f_;
+        __f.__f_ = nullptr;
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp>
+__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
+    : __f_(nullptr)
+{
+    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
+    typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF;
+    if (sizeof(_FF) <= sizeof(__buf_))
+    {
+        __f_ = (__base*)&__buf_;
+        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
+    }
+    else
+    {
+        typedef allocator<_FF> _Ap;
+        _Ap __a;
+        typedef __allocator_destructor<_Ap> _Dp;
+        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), allocator<_FR>(__a));
+        __f_ = __hold.release();
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+template <class _Fp, class _Alloc>
+__packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(
+                                  allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
+    : __f_(nullptr)
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+    typedef typename remove_reference<typename decay<_Fp>::type>::type _FR;
+    typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF;
+    if (sizeof(_FF) <= sizeof(__buf_))
+    {
+        __f_ = (__base*)&__buf_;
+        ::new (__f_) _FF(_VSTD::forward<_Fp>(__f));
+    }
+    else
+    {
+        typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<_FF>
+#else
+            rebind_alloc<_FF>::other
+#endif
+                                                     _Ap;
+        _Ap __a(__a0);
+        typedef __allocator_destructor<_Ap> _Dp;
+        unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+        ::new (__hold.get()) _FF(_VSTD::forward<_Fp>(__f), _Alloc(__a));
+        __f_ = __hold.release();
+    }
+}
+
+template<class _Rp, class ..._ArgTypes>
+__packaged_task_function<_Rp(_ArgTypes...)>&
+__packaged_task_function<_Rp(_ArgTypes...)>::operator=(__packaged_task_function&& __f) _NOEXCEPT
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+    __f_ = nullptr;
+    if (__f.__f_ == nullptr)
+        __f_ = nullptr;
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f_ = (__base*)&__buf_;
+        __f.__f_->__move_to(__f_);
+    }
+    else
+    {
+        __f_ = __f.__f_;
+        __f.__f_ = nullptr;
+    }
+    return *this;
+}
+
+template<class _Rp, class ..._ArgTypes>
+__packaged_task_function<_Rp(_ArgTypes...)>::~__packaged_task_function()
+{
+    if (__f_ == (__base*)&__buf_)
+        __f_->destroy();
+    else if (__f_)
+        __f_->destroy_deallocate();
+}
+
+template<class _Rp, class ..._ArgTypes>
+void
+__packaged_task_function<_Rp(_ArgTypes...)>::swap(__packaged_task_function& __f) _NOEXCEPT
+{
+    if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_)
+    {
+        typename aligned_storage<sizeof(__buf_)>::type __tempbuf;
+        __base* __t = (__base*)&__tempbuf;
+        __f_->__move_to(__t);
+        __f_->destroy();
+        __f_ = nullptr;
+        __f.__f_->__move_to((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = nullptr;
+        __f_ = (__base*)&__buf_;
+        __t->__move_to((__base*)&__f.__buf_);
+        __t->destroy();
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f_ == (__base*)&__buf_)
+    {
+        __f_->__move_to((__base*)&__f.__buf_);
+        __f_->destroy();
+        __f_ = __f.__f_;
+        __f.__f_ = (__base*)&__f.__buf_;
+    }
+    else if (__f.__f_ == (__base*)&__f.__buf_)
+    {
+        __f.__f_->__move_to((__base*)&__buf_);
+        __f.__f_->destroy();
+        __f.__f_ = __f_;
+        __f_ = (__base*)&__buf_;
+    }
+    else
+        _VSTD::swap(__f_, __f.__f_);
+}
+
+template<class _Rp, class ..._ArgTypes>
+inline _LIBCPP_INLINE_VISIBILITY
+_Rp
+__packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const
+{
+    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);
+}
+
+template<class _Rp, class ..._ArgTypes>
+class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)>
+{
+public:
+    typedef _Rp result_type;
+
+private:
+    __packaged_task_function<result_type(_ArgTypes...)> __f_;
+    promise<result_type>                                __p_;
+
+public:
+    // construction and destruction
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task() _NOEXCEPT : __p_(nullptr) {}
+    template <class _Fp,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
+    template <class _Fp, class _Allocator,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >
+        _LIBCPP_INLINE_VISIBILITY
+        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
+             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
+               __p_(allocator_arg, __a) {}
+    // ~packaged_task() = default;
+
+    // no copy
+    packaged_task(const packaged_task&) = delete;
+    packaged_task& operator=(const packaged_task&) = delete;
+
+    // move support
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task(packaged_task&& __other) _NOEXCEPT
+        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
+    {
+        __f_ = _VSTD::move(__other.__f_);
+        __p_ = _VSTD::move(__other.__p_);
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(packaged_task& __other) _NOEXCEPT
+    {
+        __f_.swap(__other.__f_);
+        __p_.swap(__other.__p_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
+
+    // result retrieval
+    _LIBCPP_INLINE_VISIBILITY
+    future<result_type> get_future() {return __p_.get_future();}
+
+    // execution
+    void operator()(_ArgTypes... __args);
+    void make_ready_at_thread_exit(_ArgTypes... __args);
+
+    void reset();
+};
+
+template<class _Rp, class ..._ArgTypes>
+void
+packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__p_.__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+    if (__p_.__state_->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __p_.set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Rp, class ..._ArgTypes>
+void
+packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__p_.__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+    if (__p_.__state_->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __p_.set_exception_at_thread_exit(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Rp, class ..._ArgTypes>
+void
+packaged_task<_Rp(_ArgTypes...)>::reset()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (!valid())
+        throw future_error(make_error_code(future_errc::no_state));
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    __p_ = promise<result_type>();
+}
+
+template<class ..._ArgTypes>
+class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)>
+{
+public:
+    typedef void result_type;
+
+private:
+    __packaged_task_function<result_type(_ArgTypes...)> __f_;
+    promise<result_type>                                __p_;
+
+public:
+    // construction and destruction
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task() _NOEXCEPT : __p_(nullptr) {}
+    template <class _Fp,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >
+        _LIBCPP_INLINE_VISIBILITY
+        explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
+    template <class _Fp, class _Allocator,
+              class = typename enable_if
+              <
+                  !is_same<
+                      typename decay<_Fp>::type, 
+                      packaged_task
+                      >::value
+                  >::type
+              >    
+        _LIBCPP_INLINE_VISIBILITY
+        explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
+             : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
+               __p_(allocator_arg, __a) {}
+    // ~packaged_task() = default;
+
+    // no copy
+    packaged_task(const packaged_task&) = delete;
+    packaged_task& operator=(const packaged_task&) = delete;
+
+    // move support
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task(packaged_task&& __other) _NOEXCEPT
+        : __f_(_VSTD::move(__other.__f_)), __p_(_VSTD::move(__other.__p_)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    packaged_task& operator=(packaged_task&& __other) _NOEXCEPT
+    {
+        __f_ = _VSTD::move(__other.__f_);
+        __p_ = _VSTD::move(__other.__p_);
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(packaged_task& __other) _NOEXCEPT
+    {
+        __f_.swap(__other.__f_);
+        __p_.swap(__other.__p_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __p_.__state_ != nullptr;}
+
+    // result retrieval
+    _LIBCPP_INLINE_VISIBILITY
+    future<result_type> get_future() {return __p_.get_future();}
+
+    // execution
+    void operator()(_ArgTypes... __args);
+    void make_ready_at_thread_exit(_ArgTypes... __args);
+
+    void reset();
+};
+
+template<class ..._ArgTypes>
+void
+packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__p_.__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+    if (__p_.__state_->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __f_(_VSTD::forward<_ArgTypes>(__args)...);
+        __p_.set_value();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __p_.set_exception(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class ..._ArgTypes>
+void
+packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__p_.__state_ == nullptr)
+        throw future_error(make_error_code(future_errc::no_state));
+    if (__p_.__state_->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __f_(_VSTD::forward<_ArgTypes>(__args)...);
+        __p_.set_value_at_thread_exit();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __p_.set_exception_at_thread_exit(current_exception());
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class ..._ArgTypes>
+void
+packaged_task<void(_ArgTypes...)>::reset()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (!valid())
+        throw future_error(make_error_code(future_errc::no_state));
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    __p_ = promise<result_type>();
+}
+
+template <class _Callable>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(packaged_task<_Callable>& __x, packaged_task<_Callable>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template <class _Callable, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<packaged_task<_Callable>, _Alloc>
+    : public true_type {};
+
+template <class _Rp, class _Fp>
+future<_Rp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__make_deferred_assoc_state(_Fp&& __f)
+#else
+__make_deferred_assoc_state(_Fp __f)
+#endif
+{
+    unique_ptr<__deferred_assoc_state<_Rp, _Fp>, __release_shared_count>
+        __h(new __deferred_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
+    return future<_Rp>(__h.get());
+}
+
+template <class _Rp, class _Fp>
+future<_Rp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__make_async_assoc_state(_Fp&& __f)
+#else
+__make_async_assoc_state(_Fp __f)
+#endif
+{
+    unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count>
+        __h(new __async_assoc_state<_Rp, _Fp>(_VSTD::forward<_Fp>(__f)));
+    _VSTD::thread(&__async_assoc_state<_Rp, _Fp>::__execute, __h.get()).detach();
+    return future<_Rp>(__h.get());
+}
+
+template <class _Fp, class... _Args>
+class __async_func
+{
+    tuple<_Fp, _Args...> __f_;
+
+public:
+    typedef typename __invoke_of<_Fp, _Args...>::type _Rp;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __async_func(_Fp&& __f, _Args&&... __args)
+        : __f_(_VSTD::move(__f), _VSTD::move(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {}
+
+    _Rp operator()()
+    {
+        typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index;
+        return __execute(_Index());
+    }
+private:
+    template <size_t ..._Indices>
+    _Rp
+    __execute(__tuple_indices<_Indices...>)
+    {
+        return __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, launch __value )
+{ return (int(__policy) & int(__value)) != 0; }
+
+template <class _Fp, class... _Args>
+future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
+async(launch __policy, _Fp&& __f, _Args&&... __args)
+{
+    typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF;
+    typedef typename _BF::_Rp _Rp;
+
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif
+        if (__does_policy_contain(__policy, launch::async))
+        return _VSTD::__make_async_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
+                                                     __decay_copy(_VSTD::forward<_Args>(__args))...));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch ( ... ) { if (__policy == launch::async) throw ; }
+#endif
+
+    if (__does_policy_contain(__policy, launch::deferred))
+        return _VSTD::__make_deferred_assoc_state<_Rp>(_BF(__decay_copy(_VSTD::forward<_Fp>(__f)),
+                                                        __decay_copy(_VSTD::forward<_Args>(__args))...));
+    return future<_Rp>{};
+}
+
+template <class _Fp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type>
+async(_Fp&& __f, _Args&&... __args)
+{
+    return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f),
+                                    _VSTD::forward<_Args>(__args)...);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+// shared_future
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY shared_future
+{
+    __assoc_state<_Rp>* __state_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future() _NOEXCEPT : __state_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
+        {if (__state_) __state_->__add_shared();}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(future<_Rp>&& __f) _NOEXCEPT : __state_(__f.__state_)
+        {__f.__state_ = nullptr;}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
+        {__rhs.__state_ = nullptr;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~shared_future();
+    shared_future& operator=(const shared_future& __rhs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
+        {
+            shared_future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    // retrieving the value
+    _LIBCPP_INLINE_VISIBILITY
+    const _Rp& get() const {return __state_->copy();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+shared_future<_Rp>::~shared_future()
+{
+    if (__state_)
+        __state_->__release_shared();
+}
+
+template <class _Rp>
+shared_future<_Rp>&
+shared_future<_Rp>::operator=(const shared_future& __rhs)
+{
+    if (__rhs.__state_)
+        __rhs.__state_->__add_shared();
+    if (__state_)
+        __state_->__release_shared();
+    __state_ = __rhs.__state_;
+    return *this;
+}
+
+template <class _Rp>
+class _LIBCPP_TYPE_VIS_ONLY shared_future<_Rp&>
+{
+    __assoc_state<_Rp&>* __state_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future() _NOEXCEPT : __state_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
+        {if (__state_) __state_->__add_shared();}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(future<_Rp&>&& __f) _NOEXCEPT : __state_(__f.__state_)
+        {__f.__state_ = nullptr;}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
+        {__rhs.__state_ = nullptr;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~shared_future();
+    shared_future& operator=(const shared_future& __rhs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
+        {
+            shared_future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    // retrieving the value
+    _LIBCPP_INLINE_VISIBILITY
+    _Rp& get() const {return __state_->copy();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+shared_future<_Rp&>::~shared_future()
+{
+    if (__state_)
+        __state_->__release_shared();
+}
+
+template <class _Rp>
+shared_future<_Rp&>&
+shared_future<_Rp&>::operator=(const shared_future& __rhs)
+{
+    if (__rhs.__state_)
+        __rhs.__state_->__add_shared();
+    if (__state_)
+        __state_->__release_shared();
+    __state_ = __rhs.__state_;
+    return *this;
+}
+
+template <>
+class _LIBCPP_TYPE_VIS shared_future<void>
+{
+    __assoc_sub_state* __state_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future() _NOEXCEPT : __state_(nullptr) {}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(const shared_future& __rhs) : __state_(__rhs.__state_)
+        {if (__state_) __state_->__add_shared();}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(future<void>&& __f) _NOEXCEPT : __state_(__f.__state_)
+        {__f.__state_ = nullptr;}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_)
+        {__rhs.__state_ = nullptr;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~shared_future();
+    shared_future& operator=(const shared_future& __rhs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    shared_future& operator=(shared_future&& __rhs) _NOEXCEPT
+        {
+            shared_future(std::move(__rhs)).swap(*this);
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    // retrieving the value
+    _LIBCPP_INLINE_VISIBILITY
+    void get() const {__state_->copy();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);}
+
+    // functions to check state
+    _LIBCPP_INLINE_VISIBILITY
+    bool valid() const _NOEXCEPT {return __state_ != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void wait() const {__state_->wait();}
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+            {return __state_->wait_for(__rel_time);}
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        future_status
+        wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+            {return __state_->wait_until(__abs_time);}
+};
+
+template <class _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(shared_future<_Rp>& __x, shared_future<_Rp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template <class _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_future<_Rp>
+future<_Rp>::share()
+{
+    return shared_future<_Rp>(_VSTD::move(*this));
+}
+
+template <class _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_future<_Rp&>
+future<_Rp&>::share()
+{
+    return shared_future<_Rp&>(_VSTD::move(*this));
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+inline _LIBCPP_INLINE_VISIBILITY
+shared_future<void>
+future<void>::share()
+{
+    return shared_future<void>(_VSTD::move(*this));
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_FUTURE
diff --git a/include/c++/v1/initializer_list b/include/c++/v1/initializer_list
new file mode 100644
index 0000000..663e49b
--- /dev/null
+++ b/include/c++/v1/initializer_list
@@ -0,0 +1,118 @@
+// -*- C++ -*-
+//===----------------------- initializer_list -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_INITIALIZER_LIST
+#define _LIBCPP_INITIALIZER_LIST
+
+/*
+    initializer_list synopsis
+
+namespace std
+{
+
+template<class E>
+class initializer_list
+{
+public:
+    typedef E        value_type;
+    typedef const E& reference;
+    typedef const E& const_reference;
+    typedef size_t   size_type;
+
+    typedef const E* iterator;
+    typedef const E* const_iterator;
+
+    initializer_list() noexcept; // constexpr in C++14
+
+    size_t   size()  const noexcept; // constexpr in C++14
+    const E* begin() const noexcept; // constexpr in C++14
+    const E* end()   const noexcept; // constexpr in C++14
+};
+
+template<class E> const E* begin(initializer_list<E> il) noexcept; // constexpr in C++14
+template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in C++14
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std  // purposefully not versioned
+{
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _Ep>
+class _LIBCPP_TYPE_VIS_ONLY initializer_list
+{
+    const _Ep* __begin_;
+    size_t    __size_;
+
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    initializer_list(const _Ep* __b, size_t __s) _NOEXCEPT
+        : __begin_(__b),
+          __size_(__s)
+        {}
+public:
+    typedef _Ep        value_type;
+    typedef const _Ep& reference;
+    typedef const _Ep& const_reference;
+    typedef size_t    size_type;
+
+    typedef const _Ep* iterator;
+    typedef const _Ep* const_iterator;
+
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    initializer_list() _NOEXCEPT : __begin_(nullptr), __size_(0) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    size_t    size()  const _NOEXCEPT {return __size_;}
+    
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _Ep* begin() const _NOEXCEPT {return __begin_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _Ep* end()   const _NOEXCEPT {return __begin_ + __size_;}
+};
+
+template<class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Ep*
+begin(initializer_list<_Ep> __il) _NOEXCEPT
+{
+    return __il.begin();
+}
+
+template<class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR_AFTER_CXX11
+const _Ep*
+end(initializer_list<_Ep> __il) _NOEXCEPT
+{
+    return __il.end();
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+}  // std
+
+#endif  // _LIBCPP_INITIALIZER_LIST
diff --git a/include/c++/v1/iomanip b/include/c++/v1/iomanip
new file mode 100644
index 0000000..a5042c7
--- /dev/null
+++ b/include/c++/v1/iomanip
@@ -0,0 +1,654 @@
+// -*- C++ -*-
+//===--------------------------- iomanip ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_IOMANIP
+#define _LIBCPP_IOMANIP
+
+/*
+    iomanip synopsis
+
+namespace std {
+
+// types T1, T2, ... are unspecified implementation types
+T1 resetiosflags(ios_base::fmtflags mask);
+T2 setiosflags (ios_base::fmtflags mask);
+T3 setbase(int base);
+template<charT> T4 setfill(charT c);
+T5 setprecision(int n);
+T6 setw(int n);
+template <class moneyT> T7 get_money(moneyT& mon, bool intl = false);
+template <class charT, class moneyT> T8 put_money(const moneyT& mon, bool intl = false);
+template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
+template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);
+
+template <class charT>
+  T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
+template <class charT, class traits, class Allocator>
+  T12 quoted(const basic_string<charT, traits, Allocator>& s,
+             charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
+template <class charT, class traits, class Allocator>
+  T13 quoted(basic_string<charT, traits, Allocator>& s,
+             charT delim=charT('"'), charT escape=charT('\\')); // C++14
+
+}  // std
+
+*/
+
+#include <__config>
+#include <istream>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// resetiosflags
+
+class __iom_t1
+{
+    ios_base::fmtflags __mask_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {}
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x)
+    {
+        __is.unsetf(__x.__mask_);
+        return __is;
+    }
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x)
+    {
+        __os.unsetf(__x.__mask_);
+        return __os;
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t1
+resetiosflags(ios_base::fmtflags __mask)
+{
+    return __iom_t1(__mask);
+}
+
+// setiosflags
+
+class __iom_t2
+{
+    ios_base::fmtflags __mask_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {}
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x)
+    {
+        __is.setf(__x.__mask_);
+        return __is;
+    }
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x)
+    {
+        __os.setf(__x.__mask_);
+        return __os;
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t2
+setiosflags(ios_base::fmtflags __mask)
+{
+    return __iom_t2(__mask);
+}
+
+// setbase
+
+class __iom_t3
+{
+    int __base_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t3(int __b) : __base_(__b) {}
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x)
+    {
+        __is.setf(__x.__base_ == 8  ? ios_base::oct :
+                  __x.__base_ == 10 ? ios_base::dec :
+                  __x.__base_ == 16 ? ios_base::hex :
+                  ios_base::fmtflags(0), ios_base::basefield);
+        return __is;
+    }
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x)
+    {
+        __os.setf(__x.__base_ == 8  ? ios_base::oct :
+                  __x.__base_ == 10 ? ios_base::dec :
+                  __x.__base_ == 16 ? ios_base::hex :
+                  ios_base::fmtflags(0), ios_base::basefield);
+        return __os;
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t3
+setbase(int __base)
+{
+    return __iom_t3(__base);
+}
+
+// setfill
+
+template<class _CharT>
+class __iom_t4
+{
+    _CharT __fill_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t4(_CharT __c) : __fill_(__c) {}
+
+    template <class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x)
+    {
+        __os.fill(__x.__fill_);
+        return __os;
+    }
+};
+
+template<class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t4<_CharT>
+setfill(_CharT __c)
+{
+    return __iom_t4<_CharT>(__c);
+}
+
+// setprecision
+
+class __iom_t5
+{
+    int __n_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t5(int __n) : __n_(__n) {}
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x)
+    {
+        __is.precision(__x.__n_);
+        return __is;
+    }
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x)
+    {
+        __os.precision(__x.__n_);
+        return __os;
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t5
+setprecision(int __n)
+{
+    return __iom_t5(__n);
+}
+
+// setw
+
+class __iom_t6
+{
+    int __n_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __iom_t6(int __n) : __n_(__n) {}
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x)
+    {
+        __is.width(__x.__n_);
+        return __is;
+    }
+
+    template <class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x)
+    {
+        __os.width(__x.__n_);
+        return __os;
+    }
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t6
+setw(int __n)
+{
+    return __iom_t6(__n);
+}
+
+// get_money
+
+template <class _MoneyT> class __iom_t7;
+
+template <class _CharT, class _Traits, class _MoneyT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x);
+
+template <class _MoneyT>
+class __iom_t7
+{
+    _MoneyT& __mon_;
+    bool __intl_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __iom_t7(_MoneyT& __mon, bool __intl)
+        : __mon_(__mon), __intl_(__intl) {}
+
+    template <class _CharT, class _Traits, class _Mp>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x);
+};
+
+template <class _CharT, class _Traits, class _MoneyT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __s(__is);
+        if (__s)
+        {
+            typedef istreambuf_iterator<_CharT, _Traits> _Ip;
+            typedef money_get<_CharT, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            const _Fp& __mf = use_facet<_Fp>(__is.getloc());
+            __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
+            __is.setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template <class _MoneyT>
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t7<_MoneyT>
+get_money(_MoneyT& __mon, bool __intl = false)
+{
+    return __iom_t7<_MoneyT>(__mon, __intl);
+}
+
+// put_money
+
+template <class _MoneyT> class __iom_t8;
+
+template <class _CharT, class _Traits, class _MoneyT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x);
+
+template <class _MoneyT>
+class __iom_t8
+{
+    const _MoneyT& __mon_;
+    bool __intl_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __iom_t8(const _MoneyT& __mon, bool __intl)
+        : __mon_(__mon), __intl_(__intl) {}
+
+    template <class _CharT, class _Traits, class _Mp>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x);
+};
+
+template <class _CharT, class _Traits, class _MoneyT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
+        if (__s)
+        {
+            typedef ostreambuf_iterator<_CharT, _Traits> _Op;
+            typedef money_put<_CharT, _Op> _Fp;
+            const _Fp& __mf = use_facet<_Fp>(__os.getloc());
+            if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
+                __os.setstate(ios_base::badbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __os.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __os;
+}
+
+template <class _MoneyT>
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t8<_MoneyT>
+put_money(const _MoneyT& __mon, bool __intl = false)
+{
+    return __iom_t8<_MoneyT>(__mon, __intl);
+}
+
+// get_time
+
+template <class _CharT> class __iom_t9;
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x);
+
+template <class _CharT>
+class __iom_t9
+{
+    tm* __tm_;
+    const _CharT* __fmt_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __iom_t9(tm* __tm, const _CharT* __fmt)
+        : __tm_(__tm), __fmt_(__fmt) {}
+
+    template <class _Cp, class _Traits>
+    friend
+    basic_istream<_Cp, _Traits>&
+    operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x);
+};
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __s(__is);
+        if (__s)
+        {
+            typedef istreambuf_iterator<_CharT, _Traits> _Ip;
+            typedef time_get<_CharT, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            const _Fp& __tf = use_facet<_Fp>(__is.getloc());
+            __tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_,
+                     __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
+            __is.setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t9<_CharT>
+get_time(tm* __tm, const _CharT* __fmt)
+{
+    return __iom_t9<_CharT>(__tm, __fmt);
+}
+
+// put_time
+
+template <class _CharT> class __iom_t10;
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x);
+
+template <class _CharT>
+class __iom_t10
+{
+    const tm* __tm_;
+    const _CharT* __fmt_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __iom_t10(const tm* __tm, const _CharT* __fmt)
+        : __tm_(__tm), __fmt_(__fmt) {}
+
+    template <class _Cp, class _Traits>
+    friend
+    basic_ostream<_Cp, _Traits>&
+    operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x);
+};
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
+        if (__s)
+        {
+            typedef ostreambuf_iterator<_CharT, _Traits> _Op;
+            typedef time_put<_CharT, _Op> _Fp;
+            const _Fp& __tf = use_facet<_Fp>(__os.getloc());
+            if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_,
+                         __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed())
+                __os.setstate(ios_base::badbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __os.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __os;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+__iom_t10<_CharT>
+put_time(const tm* __tm, const _CharT* __fmt)
+{
+    return __iom_t10<_CharT>(__tm, __fmt);
+}
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _CharT, class _Traits, class _ForwardIterator>
+std::basic_ostream<_CharT, _Traits> &
+__quoted_output ( basic_ostream<_CharT, _Traits> &__os, 
+        _ForwardIterator __first, _ForwardIterator __last, _CharT __delim, _CharT __escape )
+{
+    _VSTD::basic_string<_CharT, _Traits> __str;
+    __str.push_back(__delim);
+    for ( ; __first != __last; ++ __first )
+    {
+        if (_Traits::eq (*__first, __escape) || _Traits::eq (*__first, __delim))
+            __str.push_back(__escape);
+        __str.push_back(*__first);
+    }
+    __str.push_back(__delim);
+    return __put_character_sequence(__os, __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _String>
+basic_istream<_CharT, _Traits> &
+__quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _CharT __delim, _CharT __escape )
+{
+    __string.clear ();
+    _CharT __c;
+    __is >> __c;
+    if ( __is.fail ())
+        return __is;
+
+    if (!_Traits::eq (__c, __delim))    // no delimiter, read the whole string
+    {
+        __is.unget ();
+        __is >> __string;
+        return __is;
+    }
+
+    __save_flags<_CharT, _Traits> sf(__is);
+    noskipws (__is);
+    while (true)
+        {
+        __is >> __c;
+        if ( __is.fail ())
+            break;
+        if (_Traits::eq (__c, __escape))
+        {
+            __is >> __c;
+            if ( __is.fail ())
+                break;
+        }
+        else if (_Traits::eq (__c, __delim))
+            break;
+        __string.push_back ( __c );
+        }
+    return __is;
+}
+
+
+template <class _CharT, class _Iter, class _Traits=char_traits<_CharT>>
+struct __quoted_output_proxy
+{
+    _Iter  __first;
+    _Iter  __last;
+    _CharT  __delim;
+    _CharT  __escape;
+
+    __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
+    : __first(__f), __last(__l), __delim(__d), __escape(__e) {}
+    //  This would be a nice place for a string_ref 
+};
+
+template <class _CharT, class _Traits, class _Iter>
+basic_ostream<_CharT, _Traits>& operator<<(
+         basic_ostream<_CharT, _Traits>& __os, 
+         const __quoted_output_proxy<_CharT, _Iter, _Traits> & __proxy)
+{
+    return __quoted_output (__os, __proxy.__first, __proxy.__last, __proxy.__delim, __proxy.__escape);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+struct __quoted_proxy
+{
+    basic_string<_CharT, _Traits, _Allocator> &__string;
+    _CharT  __delim;
+    _CharT  __escape;
+
+    __quoted_proxy(basic_string<_CharT, _Traits, _Allocator> &__s, _CharT __d, _CharT __e)
+    : __string(__s), __delim(__d), __escape(__e) {}
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>& operator<<(
+        basic_ostream<_CharT, _Traits>& __os, 
+        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
+{
+    return __quoted_output (__os, __proxy.__string.cbegin (), __proxy.__string.cend (), __proxy.__delim, __proxy.__escape);
+}
+
+//  extractor for non-const basic_string& proxies
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>& operator>>(
+        basic_istream<_CharT, _Traits>& __is, 
+        const __quoted_proxy<_CharT, _Traits, _Allocator> & __proxy)
+{
+    return __quoted_input ( __is, __proxy.__string, __proxy.__delim, __proxy.__escape );
+}
+
+
+template <class _CharT>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_output_proxy<_CharT, const _CharT *>
+quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_CharT('\\'))
+{
+    const _CharT *__end = __s;
+    while ( *__end ) ++__end;
+    return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape );
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_INLINE_VISIBILITY
+__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator>
+quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_output_proxy<_CharT, 
+            typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> 
+                    ( __s.cbegin(), __s.cend (), __delim, __escape );
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+__quoted_proxy<_CharT, _Traits, _Allocator>
+quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
+{
+    return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape );
+}
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_IOMANIP
diff --git a/include/c++/v1/ios b/include/c++/v1/ios
new file mode 100644
index 0000000..d95f18a
--- /dev/null
+++ b/include/c++/v1/ios
@@ -0,0 +1,1023 @@
+// -*- C++ -*-
+//===---------------------------- ios -------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_IOS
+#define _LIBCPP_IOS
+
+/*
+    ios synopsis
+
+#include <iosfwd>
+
+namespace std
+{
+
+typedef OFF_T streamoff;
+typedef SZ_T streamsize;
+template <class stateT> class fpos;
+
+class ios_base
+{
+public:
+    class failure;
+
+    typedef T1 fmtflags;
+    static constexpr fmtflags boolalpha;
+    static constexpr fmtflags dec;
+    static constexpr fmtflags fixed;
+    static constexpr fmtflags hex;
+    static constexpr fmtflags internal;
+    static constexpr fmtflags left;
+    static constexpr fmtflags oct;
+    static constexpr fmtflags right;
+    static constexpr fmtflags scientific;
+    static constexpr fmtflags showbase;
+    static constexpr fmtflags showpoint;
+    static constexpr fmtflags showpos;
+    static constexpr fmtflags skipws;
+    static constexpr fmtflags unitbuf;
+    static constexpr fmtflags uppercase;
+    static constexpr fmtflags adjustfield;
+    static constexpr fmtflags basefield;
+    static constexpr fmtflags floatfield;
+
+    typedef T2 iostate;
+    static constexpr iostate badbit;
+    static constexpr iostate eofbit;
+    static constexpr iostate failbit;
+    static constexpr iostate goodbit;
+
+    typedef T3 openmode;
+    static constexpr openmode app;
+    static constexpr openmode ate;
+    static constexpr openmode binary;
+    static constexpr openmode in;
+    static constexpr openmode out;
+    static constexpr openmode trunc;
+
+    typedef T4 seekdir;
+    static constexpr seekdir beg;
+    static constexpr seekdir cur;
+    static constexpr seekdir end;
+
+    class Init;
+
+    // 27.5.2.2 fmtflags state:
+    fmtflags flags() const;
+    fmtflags flags(fmtflags fmtfl);
+    fmtflags setf(fmtflags fmtfl);
+    fmtflags setf(fmtflags fmtfl, fmtflags mask);
+    void unsetf(fmtflags mask);
+
+    streamsize precision() const;
+    streamsize precision(streamsize prec);
+    streamsize width() const;
+    streamsize width(streamsize wide);
+
+    // 27.5.2.3 locales:
+    locale imbue(const locale& loc);
+    locale getloc() const;
+
+    // 27.5.2.5 storage:
+    static int xalloc();
+    long& iword(int index);
+    void*& pword(int index);
+
+    // destructor
+    virtual ~ios_base();
+
+    // 27.5.2.6 callbacks;
+    enum event { erase_event, imbue_event, copyfmt_event };
+    typedef void (*event_callback)(event, ios_base&, int index);
+    void register_callback(event_callback fn, int index);
+
+    ios_base(const ios_base&) = delete;
+    ios_base& operator=(const ios_base&) = delete;
+
+    static bool sync_with_stdio(bool sync = true);
+
+protected:
+    ios_base();
+};
+
+template <class charT, class traits = char_traits<charT> >
+class basic_ios
+    : public ios_base
+{
+public:
+    // types:
+    typedef charT char_type;
+    typedef typename traits::int_type int_type;
+    typedef typename traits::pos_type pos_type;
+    typedef typename traits::off_type off_type;
+    typedef traits traits_type;
+
+    operator unspecified-bool-type() const;
+    bool operator!() const;
+    iostate rdstate() const;
+    void clear(iostate state = goodbit);
+    void setstate(iostate state);
+    bool good() const;
+    bool eof() const;
+    bool fail() const;
+    bool bad() const;
+
+    iostate exceptions() const;
+    void exceptions(iostate except);
+
+    // 27.5.4.1 Constructor/destructor:
+    explicit basic_ios(basic_streambuf<charT,traits>* sb);
+    virtual ~basic_ios();
+
+    // 27.5.4.2 Members:
+    basic_ostream<charT,traits>* tie() const;
+    basic_ostream<charT,traits>* tie(basic_ostream<charT,traits>* tiestr);
+
+    basic_streambuf<charT,traits>* rdbuf() const;
+    basic_streambuf<charT,traits>* rdbuf(basic_streambuf<charT,traits>* sb);
+
+    basic_ios& copyfmt(const basic_ios& rhs);
+
+    char_type fill() const;
+    char_type fill(char_type ch);
+
+    locale imbue(const locale& loc);
+
+    char narrow(char_type c, char dfault) const;
+    char_type widen(char c) const;
+
+    basic_ios(const basic_ios& ) = delete;
+    basic_ios& operator=(const basic_ios&) = delete;
+
+protected:
+    basic_ios();
+    void init(basic_streambuf<charT,traits>* sb);
+    void move(basic_ios& rhs);
+    void swap(basic_ios& rhs) noexcept;
+    void set_rdbuf(basic_streambuf<charT, traits>* sb);
+};
+
+// 27.5.5, manipulators:
+ios_base& boolalpha (ios_base& str);
+ios_base& noboolalpha(ios_base& str);
+ios_base& showbase (ios_base& str);
+ios_base& noshowbase (ios_base& str);
+ios_base& showpoint (ios_base& str);
+ios_base& noshowpoint(ios_base& str);
+ios_base& showpos (ios_base& str);
+ios_base& noshowpos (ios_base& str);
+ios_base& skipws (ios_base& str);
+ios_base& noskipws (ios_base& str);
+ios_base& uppercase (ios_base& str);
+ios_base& nouppercase(ios_base& str);
+ios_base& unitbuf (ios_base& str);
+ios_base& nounitbuf (ios_base& str);
+
+// 27.5.5.2 adjustfield:
+ios_base& internal (ios_base& str);
+ios_base& left (ios_base& str);
+ios_base& right (ios_base& str);
+
+// 27.5.5.3 basefield:
+ios_base& dec (ios_base& str);
+ios_base& hex (ios_base& str);
+ios_base& oct (ios_base& str);
+
+// 27.5.5.4 floatfield:
+ios_base& fixed (ios_base& str);
+ios_base& scientific (ios_base& str);
+ios_base& hexfloat (ios_base& str);
+ios_base& defaultfloat(ios_base& str);
+
+// 27.5.5.5 error reporting:
+enum class io_errc
+{
+    stream = 1
+};
+
+concept_map ErrorCodeEnum<io_errc> { };
+error_code make_error_code(io_errc e) noexcept; 
+error_condition make_error_condition(io_errc e) noexcept; 
+storage-class-specifier const error_category& iostream_category() noexcept;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <iosfwd>
+#include <__locale>
+#include <system_error>
+
+#if __has_feature(cxx_atomic)
+#include <atomic>     // for __xindex_
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+typedef ptrdiff_t streamsize;
+
+class _LIBCPP_TYPE_VIS ios_base
+{
+public:
+    class _LIBCPP_TYPE_VIS failure;
+
+    typedef unsigned int fmtflags;
+    static const fmtflags boolalpha   = 0x0001;
+    static const fmtflags dec         = 0x0002;
+    static const fmtflags fixed       = 0x0004;
+    static const fmtflags hex         = 0x0008;
+    static const fmtflags internal    = 0x0010;
+    static const fmtflags left        = 0x0020;
+    static const fmtflags oct         = 0x0040;
+    static const fmtflags right       = 0x0080;
+    static const fmtflags scientific  = 0x0100;
+    static const fmtflags showbase    = 0x0200;
+    static const fmtflags showpoint   = 0x0400;
+    static const fmtflags showpos     = 0x0800;
+    static const fmtflags skipws      = 0x1000;
+    static const fmtflags unitbuf     = 0x2000;
+    static const fmtflags uppercase   = 0x4000;
+    static const fmtflags adjustfield = left | right | internal;
+    static const fmtflags basefield   = dec | oct | hex;
+    static const fmtflags floatfield  = scientific | fixed;
+
+    typedef unsigned int iostate;
+    typedef iostate      io_state;
+    static const iostate badbit  = 0x1;
+    static const iostate eofbit  = 0x2;
+    static const iostate failbit = 0x4;
+    static const iostate goodbit = 0x0;
+
+    typedef unsigned int openmode;
+    typedef openmode     open_mode;
+    static const openmode app    = 0x01;
+    static const openmode ate    = 0x02;
+    static const openmode binary = 0x04;
+    static const openmode in     = 0x08;
+    static const openmode out    = 0x10;
+    static const openmode trunc  = 0x20;
+
+    enum seekdir {beg, cur, end};
+    typedef seekdir seek_dir;
+
+    typedef _VSTD::streamoff streamoff;
+    typedef _VSTD::streampos streampos;
+
+    class _LIBCPP_TYPE_VIS Init;
+
+    // 27.5.2.2 fmtflags state:
+    _LIBCPP_INLINE_VISIBILITY fmtflags flags() const;
+    _LIBCPP_INLINE_VISIBILITY fmtflags flags(fmtflags __fmtfl);
+    _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl);
+    _LIBCPP_INLINE_VISIBILITY fmtflags setf(fmtflags __fmtfl, fmtflags __mask);
+    _LIBCPP_INLINE_VISIBILITY void unsetf(fmtflags __mask);
+
+    _LIBCPP_INLINE_VISIBILITY streamsize precision() const;
+    _LIBCPP_INLINE_VISIBILITY streamsize precision(streamsize __prec);
+    _LIBCPP_INLINE_VISIBILITY streamsize width() const;
+    _LIBCPP_INLINE_VISIBILITY streamsize width(streamsize __wide);
+
+    // 27.5.2.3 locales:
+    locale imbue(const locale& __loc);
+    locale getloc() const;
+
+    // 27.5.2.5 storage:
+    static int xalloc();
+    long& iword(int __index);
+    void*& pword(int __index);
+
+    // destructor
+    virtual ~ios_base();
+
+    // 27.5.2.6 callbacks;
+    enum event { erase_event, imbue_event, copyfmt_event };
+    typedef void (*event_callback)(event, ios_base&, int __index);
+    void register_callback(event_callback __fn, int __index);
+
+private:
+    ios_base(const ios_base&); // = delete;
+    ios_base& operator=(const ios_base&); // = delete;
+
+public:
+    static bool sync_with_stdio(bool __sync = true);
+
+    _LIBCPP_INLINE_VISIBILITY iostate rdstate() const;
+    void clear(iostate __state = goodbit);
+    _LIBCPP_INLINE_VISIBILITY void setstate(iostate __state);
+
+    _LIBCPP_INLINE_VISIBILITY bool good() const;
+    _LIBCPP_INLINE_VISIBILITY bool eof() const;
+    _LIBCPP_INLINE_VISIBILITY bool fail() const;
+    _LIBCPP_INLINE_VISIBILITY bool bad() const;
+
+    _LIBCPP_INLINE_VISIBILITY iostate exceptions() const;
+    _LIBCPP_INLINE_VISIBILITY void exceptions(iostate __iostate);
+
+    void __set_badbit_and_consider_rethrow();
+    void __set_failbit_and_consider_rethrow();
+
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    ios_base() {// purposefully does no initialization
+               }
+
+    void init(void* __sb);
+    _LIBCPP_ALWAYS_INLINE void* rdbuf() const {return __rdbuf_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    void rdbuf(void* __sb)
+    {
+        __rdbuf_ = __sb;
+        clear();
+    }
+
+    void __call_callbacks(event);
+    void copyfmt(const ios_base&);
+    void move(ios_base&);
+    void swap(ios_base&) _NOEXCEPT;
+
+    _LIBCPP_ALWAYS_INLINE
+    void set_rdbuf(void* __sb)
+    {
+        __rdbuf_ = __sb;
+    }
+
+private:
+    // All data members must be scalars
+    fmtflags        __fmtflags_;
+    streamsize      __precision_;
+    streamsize      __width_;
+    iostate         __rdstate_;
+    iostate         __exceptions_;
+    void*           __rdbuf_;
+    void*           __loc_;
+    event_callback* __fn_;
+    int*            __index_;
+    size_t          __event_size_;
+    size_t          __event_cap_;
+#if __has_feature(cxx_atomic)
+    static atomic<int> __xindex_;
+#else
+    static int      __xindex_;
+#endif
+    long*           __iarray_;
+    size_t          __iarray_size_;
+    size_t          __iarray_cap_;
+    void**          __parray_;
+    size_t          __parray_size_;
+    size_t          __parray_cap_;
+};
+
+//enum class io_errc
+_LIBCPP_DECLARE_STRONG_ENUM(io_errc)
+{
+    stream = 1
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(io_errc)
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc> : public true_type { };
+
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum<io_errc::__lx> : public true_type { };
+#endif
+
+_LIBCPP_FUNC_VIS
+const error_category& iostream_category() _NOEXCEPT;
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_code
+make_error_code(io_errc __e) _NOEXCEPT
+{
+    return error_code(static_cast<int>(__e), iostream_category());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_condition
+make_error_condition(io_errc __e) _NOEXCEPT
+{
+    return error_condition(static_cast<int>(__e), iostream_category());
+}
+
+class _LIBCPP_EXCEPTION_ABI ios_base::failure
+    : public system_error
+{
+public:
+    explicit failure(const string& __msg, const error_code& __ec = io_errc::stream);
+    explicit failure(const char* __msg, const error_code& __ec = io_errc::stream);
+    virtual ~failure() throw();
+};
+
+class _LIBCPP_TYPE_VIS ios_base::Init
+{
+public:
+    Init();
+    ~Init();
+};
+
+// fmtflags
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::fmtflags
+ios_base::flags() const
+{
+    return __fmtflags_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::fmtflags
+ios_base::flags(fmtflags __fmtfl)
+{
+    fmtflags __r = __fmtflags_;
+    __fmtflags_ = __fmtfl;
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::fmtflags
+ios_base::setf(fmtflags __fmtfl)
+{
+    fmtflags __r = __fmtflags_;
+    __fmtflags_ |= __fmtfl;
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+ios_base::unsetf(fmtflags __mask)
+{
+    __fmtflags_ &= ~__mask;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::fmtflags
+ios_base::setf(fmtflags __fmtfl, fmtflags __mask)
+{
+    fmtflags __r = __fmtflags_;
+    unsetf(__mask);
+    __fmtflags_ |= __fmtfl & __mask;
+    return __r;
+}
+
+// precision
+
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+ios_base::precision() const
+{
+    return __precision_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+ios_base::precision(streamsize __prec)
+{
+    streamsize __r = __precision_;
+    __precision_ = __prec;
+    return __r;
+}
+
+// width
+
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+ios_base::width() const
+{
+    return __width_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+ios_base::width(streamsize __wide)
+{
+    streamsize __r = __width_;
+    __width_ = __wide;
+    return __r;
+}
+
+// iostate
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::iostate
+ios_base::rdstate() const
+{
+    return __rdstate_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+ios_base::setstate(iostate __state)
+{
+    clear(__rdstate_ | __state);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+ios_base::good() const
+{
+    return __rdstate_ == 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+ios_base::eof() const
+{
+    return (__rdstate_ & eofbit) != 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+ios_base::fail() const
+{
+    return (__rdstate_ & (failbit | badbit)) != 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+ios_base::bad() const
+{
+    return (__rdstate_ & badbit) != 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base::iostate
+ios_base::exceptions() const
+{
+    return __exceptions_;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void
+ios_base::exceptions(iostate __iostate)
+{
+    __exceptions_ = __iostate;
+    clear(__rdstate_);
+}
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_ios
+    : public ios_base
+{
+public:
+    // types:
+    typedef _CharT char_type;
+    typedef _Traits traits_type;
+
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    _LIBCPP_ALWAYS_INLINE
+        _LIBCPP_EXPLICIT
+        operator bool() const {return !fail();}
+    _LIBCPP_ALWAYS_INLINE bool operator!() const    {return  fail();}
+    _LIBCPP_ALWAYS_INLINE iostate rdstate() const   {return ios_base::rdstate();}
+    _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);}
+    _LIBCPP_ALWAYS_INLINE void setstate(iostate __state) {ios_base::setstate(__state);}
+    _LIBCPP_ALWAYS_INLINE bool good() const {return ios_base::good();}
+    _LIBCPP_ALWAYS_INLINE bool eof() const  {return ios_base::eof();}
+    _LIBCPP_ALWAYS_INLINE bool fail() const {return ios_base::fail();}
+    _LIBCPP_ALWAYS_INLINE bool bad() const  {return ios_base::bad();}
+
+    _LIBCPP_ALWAYS_INLINE iostate exceptions() const {return ios_base::exceptions();}
+    _LIBCPP_ALWAYS_INLINE void exceptions(iostate __iostate) {ios_base::exceptions(__iostate);}
+
+    // 27.5.4.1 Constructor/destructor:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_ios(basic_streambuf<char_type,traits_type>* __sb);
+    virtual ~basic_ios();
+
+    // 27.5.4.2 Members:
+    _LIBCPP_INLINE_VISIBILITY 
+    basic_ostream<char_type, traits_type>* tie() const;
+    _LIBCPP_INLINE_VISIBILITY 
+    basic_ostream<char_type, traits_type>* tie(basic_ostream<char_type, traits_type>* __tiestr);
+
+    _LIBCPP_INLINE_VISIBILITY 
+    basic_streambuf<char_type, traits_type>* rdbuf() const;
+    _LIBCPP_INLINE_VISIBILITY 
+    basic_streambuf<char_type, traits_type>* rdbuf(basic_streambuf<char_type, traits_type>* __sb);
+
+    basic_ios& copyfmt(const basic_ios& __rhs);
+
+    _LIBCPP_INLINE_VISIBILITY 
+    char_type fill() const;
+    _LIBCPP_INLINE_VISIBILITY 
+    char_type fill(char_type __ch);
+
+    _LIBCPP_INLINE_VISIBILITY 
+    locale imbue(const locale& __loc);
+
+    _LIBCPP_INLINE_VISIBILITY 
+    char narrow(char_type __c, char __dfault) const;
+    _LIBCPP_INLINE_VISIBILITY 
+    char_type widen(char __c) const;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    basic_ios() {// purposefully does no initialization
+                }
+    _LIBCPP_INLINE_VISIBILITY 
+    void init(basic_streambuf<char_type, traits_type>* __sb);
+
+    _LIBCPP_INLINE_VISIBILITY 
+    void move(basic_ios& __rhs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_ALWAYS_INLINE
+    void move(basic_ios&& __rhs) {move(__rhs);}
+#endif
+    _LIBCPP_INLINE_VISIBILITY 
+    void swap(basic_ios& __rhs) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY 
+    void set_rdbuf(basic_streambuf<char_type, traits_type>* __sb);
+private:
+    basic_ostream<char_type, traits_type>* __tie_;
+     mutable int_type __fill_;
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ios<_CharT, _Traits>::basic_ios(basic_streambuf<char_type,traits_type>* __sb)
+{
+    init(__sb);
+}
+
+template <class _CharT, class _Traits>
+basic_ios<_CharT, _Traits>::~basic_ios()
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ios<_CharT, _Traits>::init(basic_streambuf<char_type, traits_type>* __sb)
+{
+    ios_base::init(__sb);
+    __tie_ = 0;
+    __fill_ = traits_type::eof();
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>*
+basic_ios<_CharT, _Traits>::tie() const
+{
+    return __tie_;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>*
+basic_ios<_CharT, _Traits>::tie(basic_ostream<char_type, traits_type>* __tiestr)
+{
+    basic_ostream<char_type, traits_type>* __r = __tie_;
+    __tie_ = __tiestr;
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_streambuf<_CharT, _Traits>*
+basic_ios<_CharT, _Traits>::rdbuf() const
+{
+    return static_cast<basic_streambuf<char_type, traits_type>*>(ios_base::rdbuf());
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_streambuf<_CharT, _Traits>*
+basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<char_type, traits_type>* __sb)
+{
+    basic_streambuf<char_type, traits_type>* __r = rdbuf();
+    ios_base::rdbuf(__sb);
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+locale
+basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
+{
+    locale __r = getloc();
+    ios_base::imbue(__loc);
+    if (rdbuf())
+        rdbuf()->pubimbue(__loc);
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+char
+basic_ios<_CharT, _Traits>::narrow(char_type __c, char __dfault) const
+{
+    return use_facet<ctype<char_type> >(getloc()).narrow(__c, __dfault);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT
+basic_ios<_CharT, _Traits>::widen(char __c) const
+{
+    return use_facet<ctype<char_type> >(getloc()).widen(__c);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT
+basic_ios<_CharT, _Traits>::fill() const
+{
+    if (traits_type::eq_int_type(traits_type::eof(), __fill_))
+        __fill_ = widen(' ');
+    return __fill_;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT
+basic_ios<_CharT, _Traits>::fill(char_type __ch)
+{
+    char_type __r = __fill_;
+    __fill_ = __ch;
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+basic_ios<_CharT, _Traits>&
+basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)
+{
+    if (this != &__rhs)
+    {
+        __call_callbacks(erase_event);
+        ios_base::copyfmt(__rhs);
+        __tie_ = __rhs.__tie_;
+        __fill_ = __rhs.__fill_;
+        __call_callbacks(copyfmt_event);
+        exceptions(__rhs.exceptions());
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ios<_CharT, _Traits>::move(basic_ios& __rhs)
+{
+    ios_base::move(__rhs);
+    __tie_ = __rhs.__tie_;
+    __rhs.__tie_ = 0;
+    __fill_ = __rhs.__fill_;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ios<_CharT, _Traits>::swap(basic_ios& __rhs) _NOEXCEPT
+{
+    ios_base::swap(__rhs);
+    _VSTD::swap(__tie_, __rhs.__tie_);
+    _VSTD::swap(__fill_, __rhs.__fill_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* __sb)
+{
+    ios_base::set_rdbuf(__sb);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+boolalpha(ios_base& __str)
+{
+    __str.setf(ios_base::boolalpha);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+noboolalpha(ios_base& __str)
+{
+    __str.unsetf(ios_base::boolalpha);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+showbase(ios_base& __str)
+{
+    __str.setf(ios_base::showbase);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+noshowbase(ios_base& __str)
+{
+    __str.unsetf(ios_base::showbase);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+showpoint(ios_base& __str)
+{
+    __str.setf(ios_base::showpoint);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+noshowpoint(ios_base& __str)
+{
+    __str.unsetf(ios_base::showpoint);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+showpos(ios_base& __str)
+{
+    __str.setf(ios_base::showpos);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+noshowpos(ios_base& __str)
+{
+    __str.unsetf(ios_base::showpos);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+skipws(ios_base& __str)
+{
+    __str.setf(ios_base::skipws);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+noskipws(ios_base& __str)
+{
+    __str.unsetf(ios_base::skipws);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+uppercase(ios_base& __str)
+{
+    __str.setf(ios_base::uppercase);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+nouppercase(ios_base& __str)
+{
+    __str.unsetf(ios_base::uppercase);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+unitbuf(ios_base& __str)
+{
+    __str.setf(ios_base::unitbuf);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+nounitbuf(ios_base& __str)
+{
+    __str.unsetf(ios_base::unitbuf);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+internal(ios_base& __str)
+{
+    __str.setf(ios_base::internal, ios_base::adjustfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+left(ios_base& __str)
+{
+    __str.setf(ios_base::left, ios_base::adjustfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+right(ios_base& __str)
+{
+    __str.setf(ios_base::right, ios_base::adjustfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+dec(ios_base& __str)
+{
+    __str.setf(ios_base::dec, ios_base::basefield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+hex(ios_base& __str)
+{
+    __str.setf(ios_base::hex, ios_base::basefield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+oct(ios_base& __str)
+{
+    __str.setf(ios_base::oct, ios_base::basefield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+fixed(ios_base& __str)
+{
+    __str.setf(ios_base::fixed, ios_base::floatfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+scientific(ios_base& __str)
+{
+    __str.setf(ios_base::scientific, ios_base::floatfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+hexfloat(ios_base& __str)
+{
+    __str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield);
+    return __str;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+ios_base&
+defaultfloat(ios_base& __str)
+{
+    __str.unsetf(ios_base::floatfield);
+    return __str;
+}
+
+template <class _CharT, class _Traits>
+class __save_flags
+{
+    typedef basic_ios<_CharT, _Traits> __stream_type;
+    typedef typename __stream_type::fmtflags fmtflags;
+
+    __stream_type& __stream_;
+    fmtflags       __fmtflags_;
+    _CharT         __fill_;
+
+    __save_flags(const __save_flags&);
+    __save_flags& operator=(const __save_flags&);
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __save_flags(__stream_type& __stream)
+        : __stream_(__stream),
+          __fmtflags_(__stream.flags()),
+          __fill_(__stream.fill())
+        {}
+    _LIBCPP_INLINE_VISIBILITY
+    ~__save_flags()
+    {
+        __stream_.flags(__fmtflags_);
+        __stream_.fill(__fill_);
+    }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_IOS
diff --git a/include/c++/v1/iosfwd b/include/c++/v1/iosfwd
new file mode 100644
index 0000000..d24c227
--- /dev/null
+++ b/include/c++/v1/iosfwd
@@ -0,0 +1,194 @@
+// -*- C++ -*-
+//===--------------------------- iosfwd -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_IOSFWD
+#define _LIBCPP_IOSFWD
+
+/*
+    iosfwd synopsis
+
+namespace std
+{
+
+template<class charT> struct char_traits;
+template<class T>     class allocator;
+
+class ios_base;
+template <class charT, class traits = char_traits<charT> > class basic_ios;
+
+template <class charT, class traits = char_traits<charT> > class basic_streambuf;
+template <class charT, class traits = char_traits<charT> > class basic_istream;
+template <class charT, class traits = char_traits<charT> > class basic_ostream;
+template <class charT, class traits = char_traits<charT> > class basic_iostream;
+
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+    class basic_stringbuf;
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+    class basic_istringstream;
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+    class basic_ostringstream;
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+    class basic_stringstream;
+
+template <class charT, class traits = char_traits<charT> > class basic_filebuf;
+template <class charT, class traits = char_traits<charT> > class basic_ifstream;
+template <class charT, class traits = char_traits<charT> > class basic_ofstream;
+template <class charT, class traits = char_traits<charT> > class basic_fstream;
+
+template <class charT, class traits = char_traits<charT> > class istreambuf_iterator;
+template <class charT, class traits = char_traits<charT> > class ostreambuf_iterator;
+
+typedef basic_ios<char>              ios;
+typedef basic_ios<wchar_t>           wios;
+
+typedef basic_streambuf<char>        streambuf;
+typedef basic_istream<char>          istream;
+typedef basic_ostream<char>          ostream;
+typedef basic_iostream<char>         iostream;
+
+typedef basic_stringbuf<char>        stringbuf;
+typedef basic_istringstream<char>    istringstream;
+typedef basic_ostringstream<char>    ostringstream;
+typedef basic_stringstream<char>     stringstream;
+
+typedef basic_filebuf<char>          filebuf;
+typedef basic_ifstream<char>         ifstream;
+typedef basic_ofstream<char>         ofstream;
+typedef basic_fstream<char>          fstream;
+
+typedef basic_streambuf<wchar_t>     wstreambuf;
+typedef basic_istream<wchar_t>       wistream;
+typedef basic_ostream<wchar_t>       wostream;
+typedef basic_iostream<wchar_t>      wiostream;
+
+typedef basic_stringbuf<wchar_t>     wstringbuf;
+typedef basic_istringstream<wchar_t> wistringstream;
+typedef basic_ostringstream<wchar_t> wostringstream;
+typedef basic_stringstream<wchar_t>  wstringstream;
+
+typedef basic_filebuf<wchar_t>       wfilebuf;
+typedef basic_ifstream<wchar_t>      wifstream;
+typedef basic_ofstream<wchar_t>      wofstream;
+typedef basic_fstream<wchar_t>       wfstream;
+
+template <class state> class fpos;
+typedef fpos<char_traits<char>::state_type>    streampos;
+typedef fpos<char_traits<wchar_t>::state_type> wstreampos;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <wchar.h>  // for mbstate_t
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS ios_base;
+
+template<class _CharT>  struct _LIBCPP_TYPE_VIS_ONLY char_traits;
+template<class _Tp>     class _LIBCPP_TYPE_VIS_ONLY allocator;
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_ios;
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_streambuf;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_istream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_ostream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_iostream;
+
+template <class _CharT, class _Traits = char_traits<_CharT>,
+          class _Allocator = allocator<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf;
+template <class _CharT, class _Traits = char_traits<_CharT>,
+          class _Allocator = allocator<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_istringstream;
+template <class _CharT, class _Traits = char_traits<_CharT>,
+          class _Allocator = allocator<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream;
+template <class _CharT, class _Traits = char_traits<_CharT>,
+          class _Allocator = allocator<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_stringstream;
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_filebuf;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_ifstream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_ofstream;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_fstream;
+
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator;
+template <class _CharT, class _Traits = char_traits<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator;
+
+typedef basic_ios<char>              ios;
+typedef basic_ios<wchar_t>           wios;
+
+typedef basic_streambuf<char>        streambuf;
+typedef basic_istream<char>          istream;
+typedef basic_ostream<char>          ostream;
+typedef basic_iostream<char>         iostream;
+
+typedef basic_stringbuf<char>        stringbuf;
+typedef basic_istringstream<char>    istringstream;
+typedef basic_ostringstream<char>    ostringstream;
+typedef basic_stringstream<char>     stringstream;
+
+typedef basic_filebuf<char>          filebuf;
+typedef basic_ifstream<char>         ifstream;
+typedef basic_ofstream<char>         ofstream;
+typedef basic_fstream<char>          fstream;
+
+typedef basic_streambuf<wchar_t>     wstreambuf;
+typedef basic_istream<wchar_t>       wistream;
+typedef basic_ostream<wchar_t>       wostream;
+typedef basic_iostream<wchar_t>      wiostream;
+
+typedef basic_stringbuf<wchar_t>     wstringbuf;
+typedef basic_istringstream<wchar_t> wistringstream;
+typedef basic_ostringstream<wchar_t> wostringstream;
+typedef basic_stringstream<wchar_t>  wstringstream;
+
+typedef basic_filebuf<wchar_t>       wfilebuf;
+typedef basic_ifstream<wchar_t>      wifstream;
+typedef basic_ofstream<wchar_t>      wofstream;
+typedef basic_fstream<wchar_t>       wfstream;
+
+template <class _State>             class _LIBCPP_TYPE_VIS_ONLY fpos;
+typedef fpos<mbstate_t>    streampos;
+typedef fpos<mbstate_t>    wstreampos;
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+typedef fpos<mbstate_t>    u16streampos;
+typedef fpos<mbstate_t>    u32streampos;
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+typedef long long streamoff;        // for char_traits in <string>
+
+template <class _CharT,             // for <stdexcept>
+          class _Traits = char_traits<_CharT>,
+          class _Allocator = allocator<_CharT> >
+    class _LIBCPP_TYPE_VIS_ONLY basic_string;
+typedef basic_string<char, char_traits<char>, allocator<char> > string;
+typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_IOSFWD
diff --git a/include/c++/v1/iostream b/include/c++/v1/iostream
new file mode 100644
index 0000000..ddf2484
--- /dev/null
+++ b/include/c++/v1/iostream
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+//===--------------------------- iostream ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_IOSTREAM
+#define _LIBCPP_IOSTREAM
+
+/*
+    iostream synopsis
+
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+
+namespace std {
+
+extern istream cin;
+extern ostream cout;
+extern ostream cerr;
+extern ostream clog;
+extern wistream wcin;
+extern wostream wcout;
+extern wostream wcerr;
+extern wostream wclog;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+extern _LIBCPP_FUNC_VIS istream cin;
+extern _LIBCPP_FUNC_VIS ostream cout;
+extern _LIBCPP_FUNC_VIS ostream cerr;
+extern _LIBCPP_FUNC_VIS ostream clog;
+extern _LIBCPP_FUNC_VIS wistream wcin;
+extern _LIBCPP_FUNC_VIS wostream wcout;
+extern _LIBCPP_FUNC_VIS wostream wcerr;
+extern _LIBCPP_FUNC_VIS wostream wclog;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_IOSTREAM
diff --git a/include/c++/v1/istream b/include/c++/v1/istream
new file mode 100644
index 0000000..14fa466
--- /dev/null
+++ b/include/c++/v1/istream
@@ -0,0 +1,1716 @@
+// -*- C++ -*-
+//===--------------------------- istream ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ISTREAM
+#define _LIBCPP_ISTREAM
+
+/*
+    istream synopsis
+
+template <class charT, class traits = char_traits<charT> >
+class basic_istream
+    : virtual public basic_ios<charT,traits>
+{
+public:
+    // types (inherited from basic_ios (27.5.4)):
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // 27.7.1.1.1 Constructor/destructor:
+    explicit basic_istream(basic_streambuf<char_type, traits_type>* sb);
+    basic_istream(basic_istream&& rhs);
+    virtual ~basic_istream();
+
+    // 27.7.1.1.2 Assign/swap:
+    basic_istream& operator=(basic_istream&& rhs);
+    void swap(basic_istream& rhs);
+
+    // 27.7.1.1.3 Prefix/suffix:
+    class sentry;
+
+    // 27.7.1.2 Formatted input:
+    basic_istream& operator>>(basic_istream& (*pf)(basic_istream&));
+    basic_istream& operator>>(basic_ios<char_type, traits_type>&
+                              (*pf)(basic_ios<char_type, traits_type>&));
+    basic_istream& operator>>(ios_base& (*pf)(ios_base&));
+    basic_istream& operator>>(basic_streambuf<char_type, traits_type>* sb);
+    basic_istream& operator>>(bool& n);
+    basic_istream& operator>>(short& n);
+    basic_istream& operator>>(unsigned short& n);
+    basic_istream& operator>>(int& n);
+    basic_istream& operator>>(unsigned int& n);
+    basic_istream& operator>>(long& n);
+    basic_istream& operator>>(unsigned long& n);
+    basic_istream& operator>>(long long& n);
+    basic_istream& operator>>(unsigned long long& n);
+    basic_istream& operator>>(float& f);
+    basic_istream& operator>>(double& f);
+    basic_istream& operator>>(long double& f);
+    basic_istream& operator>>(void*& p);
+
+    // 27.7.1.3 Unformatted input:
+    streamsize gcount() const;
+    int_type get();
+    basic_istream& get(char_type& c);
+    basic_istream& get(char_type* s, streamsize n);
+    basic_istream& get(char_type* s, streamsize n, char_type delim);
+    basic_istream& get(basic_streambuf<char_type,traits_type>& sb);
+    basic_istream& get(basic_streambuf<char_type,traits_type>& sb, char_type delim);
+
+    basic_istream& getline(char_type* s, streamsize n);
+    basic_istream& getline(char_type* s, streamsize n, char_type delim);
+
+    basic_istream& ignore(streamsize n = 1, int_type delim = traits_type::eof());
+    int_type peek();
+    basic_istream& read (char_type* s, streamsize n);
+    streamsize readsome(char_type* s, streamsize n);
+
+    basic_istream& putback(char_type c);
+    basic_istream& unget();
+    int sync();
+
+    pos_type tellg();
+    basic_istream& seekg(pos_type);
+    basic_istream& seekg(off_type, ios_base::seekdir);
+};
+
+// 27.7.1.2.3 character extraction templates:
+template<class charT, class traits>
+  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT&);
+
+template<class traits>
+  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char&);
+
+template<class traits>
+  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char&);
+
+template<class charT, class traits>
+  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT*);
+
+template<class traits>
+  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char*);
+
+template<class traits>
+  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char*);
+
+template <class charT, class traits>
+  void
+  swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y);
+
+typedef basic_istream<char> istream;
+typedef basic_istream<wchar_t> wistream;
+
+template <class charT, class traits = char_traits<charT> >
+class basic_iostream :
+    public basic_istream<charT,traits>,
+    public basic_ostream<charT,traits>
+{
+public:
+    // types:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // constructor/destructor
+    explicit basic_iostream(basic_streambuf<char_type, traits_type>* sb);
+    basic_iostream(basic_iostream&& rhs);
+    virtual ~basic_iostream();
+
+    // assign/swap
+    basic_iostream& operator=(basic_iostream&& rhs);
+    void swap(basic_iostream& rhs);
+};
+
+template <class charT, class traits>
+  void
+  swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y);
+
+typedef basic_iostream<char> iostream;
+typedef basic_iostream<wchar_t> wiostream;
+
+template <class charT, class traits>
+  basic_istream<charT,traits>&
+  ws(basic_istream<charT,traits>& is);
+
+template <class charT, class traits, class T>
+  basic_istream<charT, traits>&
+  operator>>(basic_istream<charT, traits>&& is, T& x);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ostream>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_istream
+    : virtual public basic_ios<_CharT, _Traits>
+{
+    streamsize __gc_;
+public:
+    // types (inherited from basic_ios (27.5.4)):
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // 27.7.1.1.1 Constructor/destructor:
+    explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb);
+    virtual ~basic_istream();
+protected:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream(basic_istream&& __rhs);
+#endif
+
+    // 27.7.1.1.2 Assign/swap:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istream& operator=(basic_istream&& __rhs);
+#endif
+    void swap(basic_istream& __rhs);
+public:
+
+    // 27.7.1.1.3 Prefix/suffix:
+    class _LIBCPP_TYPE_VIS_ONLY sentry;
+
+    // 27.7.1.2 Formatted input:
+    basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&));
+    basic_istream& operator>>(basic_ios<char_type, traits_type>&
+                              (*__pf)(basic_ios<char_type, traits_type>&));
+    basic_istream& operator>>(ios_base& (*__pf)(ios_base&));
+    basic_istream& operator>>(basic_streambuf<char_type, traits_type>* __sb);
+    basic_istream& operator>>(bool& __n);
+    basic_istream& operator>>(short& __n);
+    basic_istream& operator>>(unsigned short& __n);
+    basic_istream& operator>>(int& __n);
+    basic_istream& operator>>(unsigned int& __n);
+    basic_istream& operator>>(long& __n);
+    basic_istream& operator>>(unsigned long& __n);
+    basic_istream& operator>>(long long& __n);
+    basic_istream& operator>>(unsigned long long& __n);
+    basic_istream& operator>>(float& __f);
+    basic_istream& operator>>(double& __f);
+    basic_istream& operator>>(long double& __f);
+    basic_istream& operator>>(void*& __p);
+
+    // 27.7.1.3 Unformatted input:
+    _LIBCPP_INLINE_VISIBILITY
+    streamsize gcount() const {return __gc_;}
+    int_type get();
+    basic_istream& get(char_type& __c);
+    basic_istream& get(char_type* __s, streamsize __n);
+    basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);
+    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb);
+    basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);
+
+    basic_istream& getline(char_type* __s, streamsize __n);
+    basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);
+
+    basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof());
+    int_type peek();
+    basic_istream& read (char_type* __s, streamsize __n);
+    streamsize readsome(char_type* __s, streamsize __n);
+
+    basic_istream& putback(char_type __c);
+    basic_istream& unget();
+    int sync();
+
+    pos_type tellg();
+    basic_istream& seekg(pos_type __pos);
+    basic_istream& seekg(off_type __off, ios_base::seekdir __dir);
+};
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_istream<_CharT, _Traits>::sentry
+{
+    bool __ok_;
+
+    sentry(const sentry&); // = delete;
+    sentry& operator=(const sentry&); // = delete;
+
+public:
+    explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false);
+//    ~sentry() = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT
+        operator bool() const {return __ok_;}
+};
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& __is,
+                                               bool __noskipws)
+    : __ok_(false)
+{
+    if (__is.good())
+    {
+        if (__is.tie())
+            __is.tie()->flush();
+        if (!__noskipws && (__is.flags() & ios_base::skipws))
+        {
+            typedef istreambuf_iterator<_CharT, _Traits> _Ip;
+            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+            _Ip __i(__is);
+            _Ip __eof;
+            for (; __i != __eof; ++__i)
+                if (!__ct.is(__ct.space, *__i))
+                    break;
+            if (__i == __eof)
+                __is.setstate(ios_base::failbit | ios_base::eofbit);
+        }
+        __ok_ = __is.good();
+    }
+    else
+        __is.setstate(ios_base::failbit);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf<char_type, traits_type>* __sb)
+    : __gc_(0)
+{
+    this->init(__sb);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs)
+    : __gc_(__rhs.__gc_)
+{
+    __rhs.__gc_ = 0;
+    this->move(__rhs);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs)
+{
+    swap(__rhs);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>::~basic_istream()
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs)
+{
+    _VSTD::swap(__gc_, __rhs.__gc_);
+    basic_ios<char_type, traits_type>::swap(__rhs);
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(unsigned int& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(long& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(unsigned long& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(long long& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(float& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(double& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(long double& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(bool& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(void*& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __n);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(short& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            long __temp;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);
+            if (__temp < numeric_limits<short>::min())
+            {
+                __err |= ios_base::failbit;
+                __n = numeric_limits<short>::min();
+            }
+            else if (__temp > numeric_limits<short>::max())
+            {
+                __err |= ios_base::failbit;
+                __n = numeric_limits<short>::max();
+            }
+            else
+                __n = static_cast<short>(__temp);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(int& __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef istreambuf_iterator<char_type, traits_type> _Ip;
+            typedef num_get<char_type, _Ip> _Fp;
+            ios_base::iostate __err = ios_base::goodbit;
+            long __temp;
+            use_facet<_Fp>(this->getloc()).get(_Ip(*this), _Ip(), *this, __err, __temp);
+            if (__temp < numeric_limits<int>::min())
+            {
+                __err |= ios_base::failbit;
+                __n = numeric_limits<int>::min();
+            }
+            else if (__temp > numeric_limits<int>::max())
+            {
+                __err |= ios_base::failbit;
+                __n = numeric_limits<int>::max();
+            }
+            else
+                __n = static_cast<int>(__temp);
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&))
+{
+    return __pf(*this);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(basic_ios<char_type, traits_type>&
+                                           (*__pf)(basic_ios<char_type, traits_type>&))
+{
+    __pf(*this);
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&))
+{
+    __pf(*this);
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+        if (__sen)
+        {
+            streamsize __n = __is.width();
+            if (__n <= 0)
+                __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
+            streamsize __c = 0;
+            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+            ios_base::iostate __err = ios_base::goodbit;
+            while (__c < __n-1)
+            {
+                typename _Traits::int_type __i = __is.rdbuf()->sgetc();
+                if (_Traits::eq_int_type(__i, _Traits::eof()))
+                {
+                   __err |= ios_base::eofbit;
+                   break;
+                }
+                _CharT __ch = _Traits::to_char_type(__i);
+                if (__ct.is(__ct.space, __ch))
+                    break;
+                *__s++ = __ch;
+                ++__c;
+                 __is.rdbuf()->sbumpc();
+            }
+            *__s = _CharT();
+            __is.width(0);
+            if (__c == 0)
+               __err |= ios_base::failbit;
+            __is.setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template<class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, unsigned char* __s)
+{
+    return __is >> (char*)__s;
+}
+
+template<class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
+{
+    return __is >> (char*)__s;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+        if (__sen)
+        {
+            typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
+            if (_Traits::eq_int_type(__i, _Traits::eof()))
+                __is.setstate(ios_base::eofbit | ios_base::failbit);
+            else
+                __c = _Traits::to_char_type(__i);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template<class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, unsigned char& __c)
+{
+    return __is >> (char&)__c;
+}
+
+template<class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<char, _Traits>&
+operator>>(basic_istream<char, _Traits>& __is, signed char& __c)
+{
+    return __is >> (char&)__c;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_type>* __sb)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this, true);
+        if (__s)
+        {
+            if (__sb)
+            {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                try
+                {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    ios_base::iostate __err = ios_base::goodbit;
+                    while (true)
+                    {
+                        typename traits_type::int_type __i = this->rdbuf()->sgetc();
+                        if (traits_type::eq_int_type(__i, _Traits::eof()))
+                        {
+                           __err |= ios_base::eofbit;
+                           break;
+                        }
+                        if (traits_type::eq_int_type(
+                                __sb->sputc(traits_type::to_char_type(__i)),
+                                traits_type::eof()))
+                            break;
+                        ++__gc_;
+                        this->rdbuf()->sbumpc();
+                    }
+                    if (__gc_ == 0)
+                       __err |= ios_base::failbit;
+                    this->setstate(__err);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                }
+                catch (...)
+                {
+                    if (__gc_ == 0)
+                        this->__set_failbit_and_consider_rethrow();
+                }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            }
+            else
+                this->setstate(ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+typename basic_istream<_CharT, _Traits>::int_type
+basic_istream<_CharT, _Traits>::get()
+{
+    __gc_ = 0;
+    int_type __r = traits_type::eof();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this, true);
+        if (__s)
+        {
+            __r = this->rdbuf()->sbumpc();
+            if (traits_type::eq_int_type(__r, traits_type::eof()))
+               this->setstate(ios_base::failbit | ios_base::eofbit);
+            else
+                __gc_ = 1;
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __r;
+}
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::get(char_type& __c)
+{
+    int_type __ch = get();
+    if (__ch != traits_type::eof())
+        __c = traits_type::to_char_type(__ch);
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (__n > 0)
+            {
+                ios_base::iostate __err = ios_base::goodbit;
+                while (__gc_ < __n-1)
+                {
+                    int_type __i = this->rdbuf()->sgetc();
+                    if (traits_type::eq_int_type(__i, traits_type::eof()))
+                    {
+                       __err |= ios_base::eofbit;
+                       break;
+                    }
+                    char_type __ch = traits_type::to_char_type(__i);
+                    if (traits_type::eq(__ch, __dlm))
+                        break;
+                    *__s++ = __ch;
+                    ++__gc_;
+                     this->rdbuf()->sbumpc();
+                }
+                *__s = char_type();
+                if (__gc_ == 0)
+                   __err |= ios_base::failbit;
+                this->setstate(__err);
+            }
+            else
+                this->setstate(ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n)
+{
+    return get(__s, __n, this->widen('\n'));
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb,
+                                    char_type __dlm)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            ios_base::iostate __err = ios_base::goodbit;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            try
+            {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                while (true)
+                {
+                    typename traits_type::int_type __i = this->rdbuf()->sgetc();
+                    if (traits_type::eq_int_type(__i, traits_type::eof()))
+                    {
+                       __err |= ios_base::eofbit;
+                       break;
+                    }
+                    char_type __ch = traits_type::to_char_type(__i);
+                    if (traits_type::eq(__ch, __dlm))
+                        break;
+                    if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof()))
+                        break;
+                    ++__gc_;
+                    this->rdbuf()->sbumpc();
+                }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            }
+            catch (...)
+            {
+            }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            if (__gc_ == 0)
+               __err |= ios_base::failbit;
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb)
+{
+    return get(__sb, this->widen('\n'));
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            ios_base::iostate __err = ios_base::goodbit;
+            while (true)
+            {
+                typename traits_type::int_type __i = this->rdbuf()->sgetc();
+                if (traits_type::eq_int_type(__i, traits_type::eof()))
+                {
+                   __err |= ios_base::eofbit;
+                   break;
+                }
+                char_type __ch = traits_type::to_char_type(__i);
+                if (traits_type::eq(__ch, __dlm))
+                {
+                    this->rdbuf()->sbumpc();
+                    ++__gc_;
+                    break;
+                }
+                if (__gc_ >= __n-1)
+                {
+                    __err |= ios_base::failbit;
+                    break;
+                }
+                *__s++ = __ch;
+                this->rdbuf()->sbumpc();
+                ++__gc_;
+            }
+            if (__n > 0)
+                *__s = char_type();
+            if (__gc_ == 0)
+               __err |= ios_base::failbit;
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n)
+{
+    return getline(__s, __n, this->widen('\n'));
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            ios_base::iostate __err = ios_base::goodbit;
+            if (__n == numeric_limits<streamsize>::max())
+            {
+                while (true)
+                {
+                    typename traits_type::int_type __i = this->rdbuf()->sbumpc();
+                    if (traits_type::eq_int_type(__i, traits_type::eof()))
+                    {
+                       __err |= ios_base::eofbit;
+                       break;
+                    }
+                    ++__gc_;
+                    if (traits_type::eq_int_type(__i, __dlm))
+                        break;
+                }
+            }
+            else
+            {
+                while (__gc_ < __n)
+                {
+                    typename traits_type::int_type __i = this->rdbuf()->sbumpc();
+                    if (traits_type::eq_int_type(__i, traits_type::eof()))
+                    {
+                       __err |= ios_base::eofbit;
+                       break;
+                    }
+                    ++__gc_;
+                    if (traits_type::eq_int_type(__i, __dlm))
+                        break;
+                }
+            }
+            this->setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+typename basic_istream<_CharT, _Traits>::int_type
+basic_istream<_CharT, _Traits>::peek()
+{
+    __gc_ = 0;
+    int_type __r = traits_type::eof();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            __r = this->rdbuf()->sgetc();
+            if (traits_type::eq_int_type(__r, traits_type::eof()))
+                this->setstate(ios_base::eofbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __r;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            __gc_ = this->rdbuf()->sgetn(__s, __n);
+            if (__gc_ != __n)
+                this->setstate(ios_base::failbit | ios_base::eofbit);
+        }
+        else
+            this->setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+streamsize
+basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n)
+{
+    __gc_ = 0;
+    streamsize __c = this->rdbuf()->in_avail();
+    switch (__c)
+    {
+    case -1:
+        this->setstate(ios_base::eofbit);
+        break;
+    case 0:
+        break;
+    default:
+        read(__s, _VSTD::min(__c, __n));
+        break;
+    }
+    return __gc_;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::putback(char_type __c)
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        this->clear(this->rdstate() & ~ios_base::eofbit);
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (this->rdbuf() == 0 || this->rdbuf()->sputbackc(__c) == traits_type::eof())
+                this->setstate(ios_base::badbit);
+        }
+        else
+            this->setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::unget()
+{
+    __gc_ = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        this->clear(this->rdstate() & ~ios_base::eofbit);
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (this->rdbuf() == 0 || this->rdbuf()->sungetc() == traits_type::eof())
+                this->setstate(ios_base::badbit);
+        }
+        else
+            this->setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+int
+basic_istream<_CharT, _Traits>::sync()
+{
+    int __r = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (this->rdbuf() == 0)
+                return -1;
+            if (this->rdbuf()->pubsync() == -1)
+            {
+                this->setstate(ios_base::badbit);
+                return -1;
+            }
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __r;
+}
+
+template<class _CharT, class _Traits>
+typename basic_istream<_CharT, _Traits>::pos_type
+basic_istream<_CharT, _Traits>::tellg()
+{
+    pos_type __r(-1);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+            __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __r;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::seekg(pos_type __pos)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        this->clear(this->rdstate() & ~ios_base::eofbit);
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
+                this->setstate(ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this, true);
+        if (__sen)
+        {
+            if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
+                this->setstate(ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+ws(basic_istream<_CharT, _Traits>& __is)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
+        if (__sen)
+        {
+            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+            while (true)
+            {
+                typename _Traits::int_type __i = __is.rdbuf()->sgetc();
+                if (_Traits::eq_int_type(__i, _Traits::eof()))
+                {
+                   __is.setstate(ios_base::eofbit);
+                   break;
+                }
+                if (!__ct.is(__ct.space, _Traits::to_char_type(__i)))
+                    break;
+                __is.rdbuf()->sbumpc();
+            }
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
+{
+    __is >> __x;
+    return __is;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_iostream
+    : public basic_istream<_CharT, _Traits>,
+      public basic_ostream<_CharT, _Traits>
+{
+public:
+    // types:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // constructor/destructor
+    explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb);
+    virtual ~basic_iostream();
+protected:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_iostream(basic_iostream&& __rhs);
+#endif
+
+    // assign/swap
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_iostream& operator=(basic_iostream&& __rhs);
+#endif
+    void swap(basic_iostream& __rhs);
+public:
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
+    : basic_istream<_CharT, _Traits>(__sb)
+{
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs)
+    : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_iostream<_CharT, _Traits>&
+basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs)
+{
+    swap(__rhs);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+basic_iostream<_CharT, _Traits>::~basic_iostream()
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs)
+{
+    basic_istream<char_type, traits_type>::swap(__rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           basic_string<_CharT, _Traits, _Allocator>& __str)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+        if (__sen)
+        {
+            __str.clear();
+            streamsize __n = __is.width();
+            if (__n <= 0)
+                __n = __str.max_size();
+            if (__n <= 0)
+                __n = numeric_limits<streamsize>::max();
+            streamsize __c = 0;
+            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+            ios_base::iostate __err = ios_base::goodbit;
+            while (__c < __n)
+            {
+                typename _Traits::int_type __i = __is.rdbuf()->sgetc();
+                if (_Traits::eq_int_type(__i, _Traits::eof()))
+                {
+                   __err |= ios_base::eofbit;
+                   break;
+                }
+                _CharT __ch = _Traits::to_char_type(__i);
+                if (__ct.is(__ct.space, __ch))
+                    break;
+                __str.push_back(__ch);
+                ++__c;
+                 __is.rdbuf()->sbumpc();
+            }
+            __is.width(0);
+            if (__c == 0)
+               __err |= ios_base::failbit;
+            __is.setstate(__err);
+        }
+        else
+            __is.setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
+        if (__sen)
+        {
+            __str.clear();
+            ios_base::iostate __err = ios_base::goodbit;
+            streamsize __extr = 0;
+            while (true)
+            {
+                typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
+                if (_Traits::eq_int_type(__i, _Traits::eof()))
+                {
+                   __err |= ios_base::eofbit;
+                   break;
+                }
+                ++__extr;
+                _CharT __ch = _Traits::to_char_type(__i);
+                if (_Traits::eq(__ch, __dlm))
+                    break;
+                __str.push_back(__ch);
+                if (__str.size() == __str.max_size())
+                {
+                    __err |= ios_base::failbit;
+                    break;
+                }
+            }
+            if (__extr == 0)
+               __err |= ios_base::failbit;
+            __is.setstate(__err);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str)
+{
+    return getline(__is, __str, __is.widen('\n'));
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>&& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)
+{
+    return getline(__is, __str, __dlm);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>&& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str)
+{
+    return getline(__is, __str, __is.widen('\n'));
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, size_t _Size>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
+        if (__sen)
+        {
+            basic_string<_CharT, _Traits> __str;
+            const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc());
+            streamsize __c = 0;
+            ios_base::iostate __err = ios_base::goodbit;
+            _CharT __zero = __ct.widen('0');
+            _CharT __one = __ct.widen('1');
+            while (__c < _Size)
+            {
+                typename _Traits::int_type __i = __is.rdbuf()->sgetc();
+                if (_Traits::eq_int_type(__i, _Traits::eof()))
+                {
+                   __err |= ios_base::eofbit;
+                   break;
+                }
+                _CharT __ch = _Traits::to_char_type(__i);
+                if (!_Traits::eq(__ch, __zero) && !_Traits::eq(__ch, __one))
+                    break;
+                __str.push_back(__ch);
+                ++__c;
+                 __is.rdbuf()->sbumpc();
+            }
+            __x = bitset<_Size>(__str);
+            if (__c == 0)
+               __err |= ios_base::failbit;
+            __is.setstate(__err);
+        }
+        else
+            __is.setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __is.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __is;
+}
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_iostream<char>)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_ISTREAM
diff --git a/include/c++/v1/iterator b/include/c++/v1/iterator
new file mode 100644
index 0000000..f338e01
--- /dev/null
+++ b/include/c++/v1/iterator
@@ -0,0 +1,1577 @@
+// -*- C++ -*-
+//===-------------------------- iterator ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_ITERATOR
+#define _LIBCPP_ITERATOR
+
+/*
+    iterator synopsis
+
+namespace std
+{
+
+template<class Iterator>
+struct iterator_traits
+{
+    typedef typename Iterator::difference_type difference_type;
+    typedef typename Iterator::value_type value_type;
+    typedef typename Iterator::pointer pointer;
+    typedef typename Iterator::reference reference;
+    typedef typename Iterator::iterator_category iterator_category;
+};
+
+template<class T>
+struct iterator_traits<T*>
+{
+    typedef ptrdiff_t difference_type;
+    typedef T value_type;
+    typedef T* pointer;
+    typedef T& reference;
+    typedef random_access_iterator_tag iterator_category;
+};
+
+template<class T>
+struct iterator_traits<const T*>
+{
+    typedef ptrdiff_t difference_type;
+    typedef T value_type;
+    typedef const T* pointer;
+    typedef const T& reference;
+    typedef random_access_iterator_tag iterator_category;
+};
+
+template<class Category, class T, class Distance = ptrdiff_t,
+         class Pointer = T*, class Reference = T&>
+struct iterator
+{
+    typedef T         value_type;
+    typedef Distance  difference_type;
+    typedef Pointer   pointer;
+    typedef Reference reference;
+    typedef Category  iterator_category;
+};
+
+struct input_iterator_tag  {};
+struct output_iterator_tag {};
+struct forward_iterator_tag       : public input_iterator_tag         {};
+struct bidirectional_iterator_tag : public forward_iterator_tag       {};
+struct random_access_iterator_tag : public bidirectional_iterator_tag {};
+
+// extension: second argument not conforming to C++03
+template <class InputIterator>
+void advance(InputIterator& i,
+             typename iterator_traits<InputIterator>::difference_type n);
+
+template <class InputIterator>
+typename iterator_traits<InputIterator>::difference_type
+distance(InputIterator first, InputIterator last);
+
+template <class Iterator>
+class reverse_iterator
+    : public iterator<typename iterator_traits<Iterator>::iterator_category,
+                      typename iterator_traits<Iterator>::value_type,
+                      typename iterator_traits<Iterator>::difference_type,
+                      typename iterator_traits<Iterator>::pointer,
+                      typename iterator_traits<Iterator>::reference>
+{
+protected:
+    Iterator current;
+public:
+    typedef Iterator                                            iterator_type;
+    typedef typename iterator_traits<Iterator>::difference_type difference_type;
+    typedef typename iterator_traits<Iterator>::reference       reference;
+    typedef typename iterator_traits<Iterator>::pointer         pointer;
+
+    reverse_iterator();
+    explicit reverse_iterator(Iterator x);
+    template <class U> reverse_iterator(const reverse_iterator<U>& u);
+    Iterator base() const;
+    reference operator*() const;
+    pointer   operator->() const;
+    reverse_iterator& operator++();
+    reverse_iterator  operator++(int);
+    reverse_iterator& operator--();
+    reverse_iterator  operator--(int);
+    reverse_iterator  operator+ (difference_type n) const;
+    reverse_iterator& operator+=(difference_type n);
+    reverse_iterator  operator- (difference_type n) const;
+    reverse_iterator& operator-=(difference_type n);
+    reference         operator[](difference_type n) const;
+};
+
+template <class Iterator1, class Iterator2>
+bool
+operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+bool
+operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+bool
+operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+bool
+operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+bool
+operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+bool
+operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator1, class Iterator2>
+typename reverse_iterator<Iterator1>::difference_type
+operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y);
+
+template <class Iterator>
+reverse_iterator<Iterator>
+operator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x);
+
+template <class Iterator> reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14
+
+template <class Container>
+class back_insert_iterator
+{
+protected:
+    Container* container;
+public:
+    typedef Container                   container_type;
+    typedef void                        value_type;
+    typedef void                        difference_type;
+    typedef back_insert_iterator<Cont>& reference;
+    typedef void                        pointer;
+
+    explicit back_insert_iterator(Container& x);
+    back_insert_iterator& operator=(const typename Container::value_type& value);
+    back_insert_iterator& operator*();
+    back_insert_iterator& operator++();
+    back_insert_iterator  operator++(int);
+};
+
+template <class Container> back_insert_iterator<Container> back_inserter(Container& x);
+
+template <class Container>
+class front_insert_iterator
+{
+protected:
+    Container* container;
+public:
+    typedef Container                    container_type;
+    typedef void                         value_type;
+    typedef void                         difference_type;
+    typedef front_insert_iterator<Cont>& reference;
+    typedef void                         pointer;
+
+    explicit front_insert_iterator(Container& x);
+    front_insert_iterator& operator=(const typename Container::value_type& value);
+    front_insert_iterator& operator*();
+    front_insert_iterator& operator++();
+    front_insert_iterator  operator++(int);
+};
+
+template <class Container> front_insert_iterator<Container> front_inserter(Container& x);
+
+template <class Container>
+class insert_iterator
+{
+protected:
+    Container* container;
+    typename Container::iterator iter;
+public:
+    typedef Container              container_type;
+    typedef void                   value_type;
+    typedef void                   difference_type;
+    typedef insert_iterator<Cont>& reference;
+    typedef void                   pointer;
+
+    insert_iterator(Container& x, typename Container::iterator i);
+    insert_iterator& operator=(const typename Container::value_type& value);
+    insert_iterator& operator*();
+    insert_iterator& operator++();
+    insert_iterator& operator++(int);
+};
+
+template <class Container, class Iterator>
+insert_iterator<Container> inserter(Container& x, Iterator i);
+
+template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
+class istream_iterator
+    : public iterator<input_iterator_tag, T, Distance, const T*, const T&>
+{
+public:
+    typedef charT char_type;
+    typedef traits traits_type;
+    typedef basic_istream<charT,traits> istream_type;
+
+    istream_iterator();
+    istream_iterator(istream_type& s);
+    istream_iterator(const istream_iterator& x);
+    ~istream_iterator();
+
+    const T& operator*() const;
+    const T* operator->() const;
+    istream_iterator& operator++();
+    istream_iterator  operator++(int);
+};
+
+template <class T, class charT, class traits, class Distance>
+bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
+                const istream_iterator<T,charT,traits,Distance>& y);
+template <class T, class charT, class traits, class Distance>
+bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
+                const istream_iterator<T,charT,traits,Distance>& y);
+
+template <class T, class charT = char, class traits = char_traits<charT> >
+class ostream_iterator
+    : public iterator<output_iterator_tag, void, void, void ,void>
+{
+public:
+    typedef charT char_type;
+    typedef traits traits_type;
+    typedef basic_ostream<charT,traits> ostream_type;
+
+    ostream_iterator(ostream_type& s);
+    ostream_iterator(ostream_type& s, const charT* delimiter);
+    ostream_iterator(const ostream_iterator& x);
+    ~ostream_iterator();
+    ostream_iterator& operator=(const T& value);
+
+    ostream_iterator& operator*();
+    ostream_iterator& operator++();
+    ostream_iterator& operator++(int);
+};
+
+template<class charT, class traits = char_traits<charT> >
+class istreambuf_iterator
+    : public iterator<input_iterator_tag, charT,
+                      typename traits::off_type, unspecified,
+                      charT>
+{
+public:
+    typedef charT                         char_type;
+    typedef traits                        traits_type;
+    typedef typename traits::int_type     int_type;
+    typedef basic_streambuf<charT,traits> streambuf_type;
+    typedef basic_istream<charT,traits>   istream_type;
+
+    istreambuf_iterator() noexcept;
+    istreambuf_iterator(istream_type& s) noexcept;
+    istreambuf_iterator(streambuf_type* s) noexcept;
+    istreambuf_iterator(a-private-type) noexcept;
+
+    charT                operator*() const;
+    pointer operator->() const;
+    istreambuf_iterator& operator++();
+    a-private-type       operator++(int);
+
+    bool equal(const istreambuf_iterator& b) const;
+};
+
+template <class charT, class traits>
+bool operator==(const istreambuf_iterator<charT,traits>& a,
+                const istreambuf_iterator<charT,traits>& b);
+template <class charT, class traits>
+bool operator!=(const istreambuf_iterator<charT,traits>& a,
+                const istreambuf_iterator<charT,traits>& b);
+
+template <class charT, class traits = char_traits<charT> >
+class ostreambuf_iterator
+    : public iterator<output_iterator_tag, void, void, void, void>
+{
+public:
+    typedef charT                         char_type;
+    typedef traits                        traits_type;
+    typedef basic_streambuf<charT,traits> streambuf_type;
+    typedef basic_ostream<charT,traits>   ostream_type;
+
+    ostreambuf_iterator(ostream_type& s) noexcept;
+    ostreambuf_iterator(streambuf_type* s) noexcept;
+    ostreambuf_iterator& operator=(charT c);
+    ostreambuf_iterator& operator*();
+    ostreambuf_iterator& operator++();
+    ostreambuf_iterator& operator++(int);
+    bool failed() const noexcept;
+};
+
+template <class C> auto begin(C& c) -> decltype(c.begin());
+template <class C> auto begin(const C& c) -> decltype(c.begin());
+template <class C> auto end(C& c) -> decltype(c.end());
+template <class C> auto end(const C& c) -> decltype(c.end());
+template <class T, size_t N> T* begin(T (&array)[N]);
+template <class T, size_t N> T* end(T (&array)[N]);
+
+template <class C> auto cbegin(const C& c) -> decltype(std::begin(c));        // C++14
+template <class C> auto cend(const C& c) -> decltype(std::end(c));            // C++14
+template <class C> auto rbegin(C& c) -> decltype(c.rbegin());                 // C++14
+template <class C> auto rbegin(const C& c) -> decltype(c.rbegin());           // C++14
+template <class C> auto rend(C& c) -> decltype(c.rend());                     // C++14
+template <class C> auto rend(const C& c) -> decltype(c.rend());               // C++14
+template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); // C++14
+template <class E> reverse_iterator<const E*> rend(initializer_list<E> il);   // C++14
+template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]);      // C++14
+template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]);        // C++14
+template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c));      // C++14
+template <class C> auto crend(const C& c) -> decltype(std::rend(c));          // C++14
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__functional_base>
+#include <type_traits>
+#include <cstddef>
+#include <iosfwd>
+#include <initializer_list>
+#ifdef __APPLE__
+#include <Availability.h>
+#endif
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct _LIBCPP_TYPE_VIS_ONLY input_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY output_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY forward_iterator_tag       : public input_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY bidirectional_iterator_tag : public forward_iterator_tag {};
+struct _LIBCPP_TYPE_VIS_ONLY random_access_iterator_tag : public bidirectional_iterator_tag {};
+
+template <class _Tp>
+struct __has_iterator_category
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::iterator_category* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Iter, bool> struct __iterator_traits_impl {};
+
+template <class _Iter>
+struct __iterator_traits_impl<_Iter, true>
+{
+    typedef typename _Iter::difference_type   difference_type;
+    typedef typename _Iter::value_type        value_type;
+    typedef typename _Iter::pointer           pointer;
+    typedef typename _Iter::reference         reference;
+    typedef typename _Iter::iterator_category iterator_category;
+};
+
+template <class _Iter, bool> struct __iterator_traits {};
+
+template <class _Iter>
+struct __iterator_traits<_Iter, true>
+    :  __iterator_traits_impl
+      <
+        _Iter,
+        is_convertible<typename _Iter::iterator_category, input_iterator_tag>::value ||
+        is_convertible<typename _Iter::iterator_category, output_iterator_tag>::value
+      >
+{};
+
+// iterator_traits<Iterator> will only have the nested types if Iterator::iterator_category
+//    exists.  Else iterator_traits<Iterator> will be an empty class.  This is a
+//    conforming extension which allows some programs to compile and behave as
+//    the client expects instead of failing at compile time.
+
+template <class _Iter>
+struct _LIBCPP_TYPE_VIS_ONLY iterator_traits
+    : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {};
+
+template<class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY iterator_traits<_Tp*>
+{
+    typedef ptrdiff_t difference_type;
+    typedef typename remove_const<_Tp>::type value_type;
+    typedef _Tp* pointer;
+    typedef _Tp& reference;
+    typedef random_access_iterator_tag iterator_category;
+};
+
+template <class _Tp, class _Up, bool = __has_iterator_category<iterator_traits<_Tp> >::value>
+struct __has_iterator_category_convertible_to
+    : public integral_constant<bool, is_convertible<typename iterator_traits<_Tp>::iterator_category, _Up>::value>
+{};
+
+template <class _Tp, class _Up>
+struct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {};
+
+template <class _Tp>
+struct __is_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {};
+
+template <class _Tp>
+struct __is_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {};
+
+template <class _Tp>
+struct __is_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {};
+
+template <class _Tp>
+struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {};
+
+template<class _Category, class _Tp, class _Distance = ptrdiff_t,
+         class _Pointer = _Tp*, class _Reference = _Tp&>
+struct _LIBCPP_TYPE_VIS_ONLY iterator
+{
+    typedef _Tp        value_type;
+    typedef _Distance  difference_type;
+    typedef _Pointer   pointer;
+    typedef _Reference reference;
+    typedef _Category  iterator_category;
+};
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+void __advance(_InputIter& __i,
+             typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag)
+{
+    for (; __n > 0; --__n)
+        ++__i;
+}
+
+template <class _BiDirIter>
+inline _LIBCPP_INLINE_VISIBILITY
+void __advance(_BiDirIter& __i,
+             typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag)
+{
+    if (__n >= 0)
+        for (; __n > 0; --__n)
+            ++__i;
+    else
+        for (; __n < 0; ++__n)
+            --__i;
+}
+
+template <class _RandIter>
+inline _LIBCPP_INLINE_VISIBILITY
+void __advance(_RandIter& __i,
+             typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag)
+{
+   __i += __n;
+}
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+void advance(_InputIter& __i,
+             typename iterator_traits<_InputIter>::difference_type __n)
+{
+    __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
+}
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_InputIter>::difference_type
+__distance(_InputIter __first, _InputIter __last, input_iterator_tag)
+{
+    typename iterator_traits<_InputIter>::difference_type __r(0);
+    for (; __first != __last; ++__first)
+        ++__r;
+    return __r;
+}
+
+template <class _RandIter>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_RandIter>::difference_type
+__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag)
+{
+    return __last - __first;
+}
+
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+typename iterator_traits<_InputIter>::difference_type
+distance(_InputIter __first, _InputIter __last)
+{
+    return __distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category());
+}
+
+template <class _ForwardIter>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIter
+next(_ForwardIter __x,
+     typename iterator_traits<_ForwardIter>::difference_type __n = 1,
+     typename enable_if<__is_forward_iterator<_ForwardIter>::value>::type* = 0)
+{
+    _VSTD::advance(__x, __n);
+    return __x;
+}
+
+template <class _BidiretionalIter>
+inline _LIBCPP_INLINE_VISIBILITY
+_BidiretionalIter
+prev(_BidiretionalIter __x,
+     typename iterator_traits<_BidiretionalIter>::difference_type __n = 1,
+     typename enable_if<__is_bidirectional_iterator<_BidiretionalIter>::value>::type* = 0)
+{
+    _VSTD::advance(__x, -__n);
+    return __x;
+}
+
+template <class _Iter>
+class _LIBCPP_TYPE_VIS_ONLY reverse_iterator
+    : public iterator<typename iterator_traits<_Iter>::iterator_category,
+                      typename iterator_traits<_Iter>::value_type,
+                      typename iterator_traits<_Iter>::difference_type,
+                      typename iterator_traits<_Iter>::pointer,
+                      typename iterator_traits<_Iter>::reference>
+{
+private:
+    mutable _Iter __t;  // no longer used as of LWG #2360, not removed due to ABI break
+protected:
+    _Iter current;
+public:
+    typedef _Iter                                            iterator_type;
+    typedef typename iterator_traits<_Iter>::difference_type difference_type;
+    typedef typename iterator_traits<_Iter>::reference       reference;
+    typedef typename iterator_traits<_Iter>::pointer         pointer;
+
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {}
+    _LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u)
+        : __t(__u.base()), current(__u.base()) {}
+    _LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;}
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;}
+    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const {return _VSTD::addressof(operator*());}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator++(int)
+        {reverse_iterator __tmp(*this); --current; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator--(int)
+        {reverse_iterator __tmp(*this); ++current; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator+ (difference_type __n) const
+        {return reverse_iterator(current - __n);}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n)
+        {current -= __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator  operator- (difference_type __n) const
+        {return reverse_iterator(current + __n);}
+    _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n)
+        {current += __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reference         operator[](difference_type __n) const
+        {return current[-__n-1];}
+};
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() > __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() != __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() <= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __x.base() >= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename reverse_iterator<_Iter1>::difference_type
+operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __y.base() - __x.base();
+}
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Iter>
+operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)
+{
+    return reverse_iterator<_Iter>(__x.base() - __n);
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Iter> make_reverse_iterator(_Iter __i)
+{
+    return reverse_iterator<_Iter>(__i);
+}
+#endif
+
+template <class _Container>
+class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator
+    : public iterator<output_iterator_tag,
+                      void,
+                      void,
+                      void,
+                      back_insert_iterator<_Container>&>
+{
+protected:
+    _Container* container;
+public:
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {container->push_back(__value_); return *this;}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {container->push_back(_VSTD::move(__value_)); return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY back_insert_iterator  operator++(int) {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+back_insert_iterator<_Container>
+back_inserter(_Container& __x)
+{
+    return back_insert_iterator<_Container>(__x);
+}
+
+template <class _Container>
+class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator
+    : public iterator<output_iterator_tag,
+                      void,
+                      void,
+                      void,
+                      front_insert_iterator<_Container>&>
+{
+protected:
+    _Container* container;
+public:
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {container->push_front(__value_); return *this;}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {container->push_front(_VSTD::move(__value_)); return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY front_insert_iterator  operator++(int) {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+front_insert_iterator<_Container>
+front_inserter(_Container& __x)
+{
+    return front_insert_iterator<_Container>(__x);
+}
+
+template <class _Container>
+class _LIBCPP_TYPE_VIS_ONLY insert_iterator
+    : public iterator<output_iterator_tag,
+                      void,
+                      void,
+                      void,
+                      insert_iterator<_Container>&>
+{
+protected:
+    _Container* container;
+    typename _Container::iterator iter;
+public:
+    typedef _Container container_type;
+
+    _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
+        : container(_VSTD::addressof(__x)), iter(__i) {}
+    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
+        {iter = container->insert(iter, __value_); ++iter; return *this;}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
+        {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*()        {return *this;}
+    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++()       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int)    {return *this;}
+};
+
+template <class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+insert_iterator<_Container>
+inserter(_Container& __x, typename _Container::iterator __i)
+{
+    return insert_iterator<_Container>(__x, __i);
+}
+
+template <class _Tp, class _CharT = char,
+          class _Traits = char_traits<_CharT>, class _Distance = ptrdiff_t>
+class _LIBCPP_TYPE_VIS_ONLY istream_iterator
+    : public iterator<input_iterator_tag, _Tp, _Distance, const _Tp*, const _Tp&>
+{
+public:
+    typedef _CharT char_type;
+    typedef _Traits traits_type;
+    typedef basic_istream<_CharT,_Traits> istream_type;
+private:
+    istream_type* __in_stream_;
+    _Tp __value_;
+public:
+    _LIBCPP_INLINE_VISIBILITY istream_iterator() : __in_stream_(0) {}
+    _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s)
+        {
+            if (!(*__in_stream_ >> __value_))
+                __in_stream_ = 0;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;}
+    _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());}
+    _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++()
+        {
+            if (!(*__in_stream_ >> __value_))
+                __in_stream_ = 0;
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY istream_iterator  operator++(int)
+        {istream_iterator __t(*this); ++(*this); return __t;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const istream_iterator& __x, const istream_iterator& __y)
+        {return __x.__in_stream_ == __y.__in_stream_;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const istream_iterator& __x, const istream_iterator& __y)
+        {return !(__x == __y);}
+};
+
+template <class _Tp, class _CharT = char, class _Traits = char_traits<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY ostream_iterator
+    : public iterator<output_iterator_tag, void, void, void, void>
+{
+public:
+    typedef _CharT char_type;
+    typedef _Traits traits_type;
+    typedef basic_ostream<_CharT,_Traits> ostream_type;
+private:
+    ostream_type* __out_stream_;
+    const char_type* __delim_;
+public:
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s)
+        : __out_stream_(&__s), __delim_(0) {}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter)
+        : __out_stream_(&__s), __delim_(__delimiter) {}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_)
+        {
+            *__out_stream_ << __value_;
+            if (__delim_)
+                *__out_stream_ << __delim_;
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;}
+};
+
+template<class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY istreambuf_iterator
+    : public iterator<input_iterator_tag, _CharT,
+                      typename _Traits::off_type, _CharT*,
+                      _CharT>
+{
+public:
+    typedef _CharT                          char_type;
+    typedef _Traits                         traits_type;
+    typedef typename _Traits::int_type      int_type;
+    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
+    typedef basic_istream<_CharT,_Traits>   istream_type;
+private:
+    mutable streambuf_type* __sbuf_;
+
+    class __proxy
+    {
+        char_type __keep_;
+        streambuf_type* __sbuf_;
+        _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s)
+            : __keep_(__c), __sbuf_(__s) {}
+        friend class istreambuf_iterator;
+    public:
+        _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;}
+    };
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __test_for_eof() const
+    {
+        if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
+            __sbuf_ = 0;
+        return __sbuf_ == 0;
+    }
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
+        : __sbuf_(__s.rdbuf()) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
+        : __sbuf_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT
+        : __sbuf_(__p.__sbuf_) {}
+
+    _LIBCPP_INLINE_VISIBILITY char_type  operator*() const
+        {return static_cast<char_type>(__sbuf_->sgetc());}
+    _LIBCPP_INLINE_VISIBILITY char_type* operator->() const {return nullptr;}
+    _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
+        {
+            __sbuf_->sbumpc();
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY __proxy              operator++(int)
+        {
+            return __proxy(__sbuf_->sbumpc(), __sbuf_);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
+        {return __test_for_eof() == __b.__test_for_eof();}
+};
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
+                const istreambuf_iterator<_CharT,_Traits>& __b)
+                {return __a.equal(__b);}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
+                const istreambuf_iterator<_CharT,_Traits>& __b)
+                {return !__a.equal(__b);}
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY ostreambuf_iterator
+    : public iterator<output_iterator_tag, void, void, void, void>
+{
+public:
+    typedef _CharT                          char_type;
+    typedef _Traits                         traits_type;
+    typedef basic_streambuf<_CharT,_Traits> streambuf_type;
+    typedef basic_ostream<_CharT,_Traits>   ostream_type;
+private:
+    streambuf_type* __sbuf_;
+public:
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
+        : __sbuf_(__s.rdbuf()) {}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
+        : __sbuf_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c)
+        {
+            if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof()))
+                __sbuf_ = 0;
+            return *this;
+        }
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
+    _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}
+
+#if !defined(__APPLE__) || \
+    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
+    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
+
+    template <class _Ch, class _Tr>
+    friend
+    _LIBCPP_HIDDEN
+    ostreambuf_iterator<_Ch, _Tr>
+    __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
+                     const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
+                     ios_base& __iob, _Ch __fl);
+#endif
+};
+
+template <class _Iter>
+class _LIBCPP_TYPE_VIS_ONLY move_iterator
+{
+private:
+    _Iter __i;
+public:
+    typedef _Iter                                            iterator_type;
+    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
+    typedef typename iterator_traits<iterator_type>::value_type value_type;
+    typedef typename iterator_traits<iterator_type>::difference_type difference_type;
+    typedef typename iterator_traits<iterator_type>::pointer pointer;
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    typedef value_type&& reference;
+#else
+    typedef typename iterator_traits<iterator_type>::reference reference;
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY move_iterator() : __i() {}
+    _LIBCPP_INLINE_VISIBILITY explicit move_iterator(_Iter __x) : __i(__x) {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY move_iterator(const move_iterator<_Up>& __u)
+        : __i(__u.base()) {}
+    _LIBCPP_INLINE_VISIBILITY _Iter base() const {return __i;}
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const {
+      return static_cast<reference>(*__i);
+    }
+    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const {
+      typename iterator_traits<iterator_type>::reference __ref = *__i;
+      return &__ref;
+    }
+    _LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;}
+    _LIBCPP_INLINE_VISIBILITY move_iterator  operator++(int)
+        {move_iterator __tmp(*this); ++__i; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY move_iterator& operator--() {--__i; return *this;}
+    _LIBCPP_INLINE_VISIBILITY move_iterator  operator--(int)
+        {move_iterator __tmp(*this); --__i; return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY move_iterator  operator+ (difference_type __n) const
+        {return move_iterator(__i + __n);}
+    _LIBCPP_INLINE_VISIBILITY move_iterator& operator+=(difference_type __n)
+        {__i += __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY move_iterator  operator- (difference_type __n) const
+        {return move_iterator(__i - __n);}
+    _LIBCPP_INLINE_VISIBILITY move_iterator& operator-=(difference_type __n)
+        {__i -= __n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reference         operator[](difference_type __n) const
+    {
+      return static_cast<reference>(__i[__n]);
+    }
+};
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() != __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() > __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() >= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() <= __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename move_iterator<_Iter1>::difference_type
+operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y)
+{
+    return __x.base() - __y.base();
+}
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+move_iterator<_Iter>
+operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x)
+{
+    return move_iterator<_Iter>(__x.base() + __n);
+}
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+move_iterator<_Iter>
+make_move_iterator(_Iter __i)
+{
+    return move_iterator<_Iter>(__i);
+}
+
+// __wrap_iter
+
+template <class _Iter> class __wrap_iter;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter1, class _Iter2>
+_LIBCPP_INLINE_VISIBILITY
+typename __wrap_iter<_Iter1>::difference_type
+operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+template <class _Iter>
+_LIBCPP_INLINE_VISIBILITY
+__wrap_iter<_Iter>
+operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
+
+template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op);
+template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2);
+template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op);
+template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2);
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_trivially_copy_assignable<_Tp>::value,
+    _Tp*
+>::type
+__unwrap_iter(__wrap_iter<_Tp*>);
+
+template <class _Iter>
+class __wrap_iter
+{
+public:
+    typedef _Iter                                                      iterator_type;
+    typedef typename iterator_traits<iterator_type>::iterator_category iterator_category;
+    typedef typename iterator_traits<iterator_type>::value_type        value_type;
+    typedef typename iterator_traits<iterator_type>::difference_type   difference_type;
+    typedef typename iterator_traits<iterator_type>::pointer           pointer;
+    typedef typename iterator_traits<iterator_type>::reference         reference;
+private:
+    iterator_type __i;
+public:
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT
+#if _LIBCPP_STD_VER > 11
+                : __i{}
+#endif
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u,
+        typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT
+        : __i(__u.base())
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__u);
+#endif
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    __wrap_iter(const __wrap_iter& __x)
+        : __i(__x.base())
+    {
+        __get_db()->__iterator_copy(this, &__x);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __wrap_iter& operator=(const __wrap_iter& __x)
+    {
+        if (this != &__x)
+        {
+            __get_db()->__iterator_copy(this, &__x);
+            __i = __x.__i;
+        }
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    ~__wrap_iter()
+    {
+        __get_db()->__erase_i(this);
+    }
+#endif
+    _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return *__i;
+    }
+    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return (pointer)&reinterpret_cast<const volatile char&>(*__i);
+    }
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable iterator");
+#endif
+        ++__i;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator++(int) _NOEXCEPT
+        {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
+                       "Attempted to decrement non-decrementable iterator");
+#endif
+        --__i;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator--(int) _NOEXCEPT
+        {__wrap_iter __tmp(*this); --(*this); return __tmp;}
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT
+        {__wrap_iter __w(*this); __w += __n; return __w;}
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
+                   "Attempted to add/subtract iterator outside of valid range");
+#endif
+        __i += __n;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter  operator- (difference_type __n) const _NOEXCEPT
+        {return *this + (-__n);}
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
+        {*this += -__n; return *this;}
+    _LIBCPP_INLINE_VISIBILITY reference        operator[](difference_type __n) const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
+                   "Attempted to subscript iterator outside of valid range");
+#endif
+        return __i[__n];
+    }
+
+    _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;}
+
+private:
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
+    {
+        __get_db()->__insert_ic(this, __p);
+    }
+#else
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
+#endif
+
+    template <class _Up> friend class __wrap_iter;
+    template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
+    template <class _Tp, class _Alloc> friend class vector;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    bool
+    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1, class _Iter2>
+    friend
+    typename __wrap_iter<_Iter1>::difference_type
+    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
+
+    template <class _Iter1>
+    friend
+    __wrap_iter<_Iter1>
+    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
+
+    template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
+    template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);
+    template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op);
+    template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2);
+
+    template <class _Tp>
+    friend
+    typename enable_if
+    <
+        is_trivially_copy_assignable<_Tp>::value,
+        _Tp*
+    >::type
+    __unwrap_iter(__wrap_iter<_Tp*>);
+};
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return __x.base() == __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
+                   "Attempted to compare incomparable iterators");
+#endif
+    return __x.base() < __y.base();
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template <class _Iter1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template <class _Iter1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template <class _Iter1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template <class _Iter1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template <class _Iter1, class _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __wrap_iter<_Iter1>::difference_type
+operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
+                   "Attempted to subtract incompatible iterators");
+#endif
+    return __x.base() - __y.base();
+}
+
+template <class _Iter>
+inline _LIBCPP_INLINE_VISIBILITY
+__wrap_iter<_Iter>
+operator+(typename __wrap_iter<_Iter>::difference_type __n,
+          __wrap_iter<_Iter> __x) _NOEXCEPT
+{
+    __x += __n;
+    return __x;
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp*
+begin(_Tp (&__array)[_Np])
+{
+    return __array;
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp*
+end(_Tp (&__array)[_Np])
+{
+    return __array + _Np;
+}
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+begin(_Cp& __c) -> decltype(__c.begin())
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+begin(const _Cp& __c) -> decltype(__c.begin())
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+end(_Cp& __c) -> decltype(__c.end())
+{
+    return __c.end();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto
+end(const _Cp& __c) -> decltype(__c.end())
+{
+    return __c.end();
+}
+
+#if _LIBCPP_STD_VER > 11
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array + _Np);
+}
+
+template <class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np])
+{
+    return reverse_iterator<_Tp*>(__array);
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rbegin(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.end());
+}
+
+template <class _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il)
+{
+    return reverse_iterator<const _Ep*>(__il.begin());
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+auto cbegin(const _Cp& __c) -> decltype(begin(__c))
+{
+    return begin(__c);
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+auto cend(const _Cp& __c) -> decltype(end(__c))
+{
+    return end(__c);
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(_Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rbegin(const _Cp& __c) -> decltype(__c.rbegin())
+{
+    return __c.rbegin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(_Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto rend(const _Cp& __c) -> decltype(__c.rend())
+{
+    return __c.rend();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
+{
+    return rbegin(__c);
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+auto crend(const _Cp& __c) -> decltype(rend(__c))
+{
+    return rend(__c);
+}
+
+#endif
+
+
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename _Cp::iterator
+begin(_Cp& __c)
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename _Cp::const_iterator
+begin(const _Cp& __c)
+{
+    return __c.begin();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename _Cp::iterator
+end(_Cp& __c)
+{
+    return __c.end();
+}
+
+template <class _Cp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename _Cp::const_iterator
+end(const _Cp& __c)
+{
+    return __c.end();
+}
+
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_ITERATOR
diff --git a/include/c++/v1/limits b/include/c++/v1/limits
new file mode 100644
index 0000000..2216966
--- /dev/null
+++ b/include/c++/v1/limits
@@ -0,0 +1,813 @@
+// -*- C++ -*-
+//===---------------------------- limits ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LIMITS
+#define _LIBCPP_LIMITS
+
+/*
+    limits synopsis
+
+namespace std
+{
+
+template<class T>
+class numeric_limits
+{
+public:
+    static constexpr bool is_specialized = false;
+    static constexpr T min() noexcept;
+    static constexpr T max() noexcept;
+    static constexpr T lowest() noexcept;
+
+    static constexpr int  digits = 0;
+    static constexpr int  digits10 = 0;
+    static constexpr int  max_digits10 = 0;
+    static constexpr bool is_signed = false;
+    static constexpr bool is_integer = false;
+    static constexpr bool is_exact = false;
+    static constexpr int  radix = 0;
+    static constexpr T epsilon() noexcept;
+    static constexpr T round_error() noexcept;
+
+    static constexpr int  min_exponent = 0;
+    static constexpr int  min_exponent10 = 0;
+    static constexpr int  max_exponent = 0;
+    static constexpr int  max_exponent10 = 0;
+
+    static constexpr bool has_infinity = false;
+    static constexpr bool has_quiet_NaN = false;
+    static constexpr bool has_signaling_NaN = false;
+    static constexpr float_denorm_style has_denorm = denorm_absent;
+    static constexpr bool has_denorm_loss = false;
+    static constexpr T infinity() noexcept;
+    static constexpr T quiet_NaN() noexcept;
+    static constexpr T signaling_NaN() noexcept;
+    static constexpr T denorm_min() noexcept;
+
+    static constexpr bool is_iec559 = false;
+    static constexpr bool is_bounded = false;
+    static constexpr bool is_modulo = false;
+
+    static constexpr bool traps = false;
+    static constexpr bool tinyness_before = false;
+    static constexpr float_round_style round_style = round_toward_zero;
+};
+
+enum float_round_style
+{
+    round_indeterminate       = -1,
+    round_toward_zero         =  0,
+    round_to_nearest          =  1,
+    round_toward_infinity     =  2,
+    round_toward_neg_infinity =  3
+};
+
+enum float_denorm_style
+{
+    denorm_indeterminate = -1,
+    denorm_absent = 0,
+    denorm_present = 1
+};
+
+template<> class numeric_limits<cv bool>;
+
+template<> class numeric_limits<cv char>;
+template<> class numeric_limits<cv signed char>;
+template<> class numeric_limits<cv unsigned char>;
+template<> class numeric_limits<cv wchar_t>;
+template<> class numeric_limits<cv char16_t>;
+template<> class numeric_limits<cv char32_t>;
+
+template<> class numeric_limits<cv short>;
+template<> class numeric_limits<cv int>;
+template<> class numeric_limits<cv long>;
+template<> class numeric_limits<cv long long>;
+template<> class numeric_limits<cv unsigned short>;
+template<> class numeric_limits<cv unsigned int>;
+template<> class numeric_limits<cv unsigned long>;
+template<> class numeric_limits<cv unsigned long long>;
+
+template<> class numeric_limits<cv float>;
+template<> class numeric_limits<cv double>;
+template<> class numeric_limits<cv long double>;
+
+}  // std
+
+*/
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#include <__config>
+#include <type_traits>
+
+#include <__undef_min_max>
+
+#if defined(_LIBCPP_MSVCRT)
+#include "support/win32/limits_win32.h"
+#endif // _LIBCPP_MSVCRT
+
+#if defined(__IBMCPP__)
+#include "support/ibm/limits.h"
+#endif // __IBMCPP__
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+enum float_round_style
+{
+    round_indeterminate       = -1,
+    round_toward_zero         =  0,
+    round_to_nearest          =  1,
+    round_toward_infinity     =  2,
+    round_toward_neg_infinity =  3
+};
+
+enum float_denorm_style
+{
+    denorm_indeterminate = -1,
+    denorm_absent = 0,
+    denorm_present = 1
+};
+
+template <class _Tp, bool = is_arithmetic<_Tp>::value>
+class __libcpp_numeric_limits
+{
+protected:
+    typedef _Tp type;
+
+    static _LIBCPP_CONSTEXPR const  bool is_specialized = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return type();}
+
+    static _LIBCPP_CONSTEXPR const int  digits = 0;
+    static _LIBCPP_CONSTEXPR const int  digits10 = 0;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;
+    static _LIBCPP_CONSTEXPR const bool is_signed = false;
+    static _LIBCPP_CONSTEXPR const bool is_integer = false;
+    static _LIBCPP_CONSTEXPR const bool is_exact = false;
+    static _LIBCPP_CONSTEXPR const int  radix = 0;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type();}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = false;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type();}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = false;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = false;
+
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;
+};
+
+template <class _Tp, int digits, bool is_signed>
+struct __libcpp_compute_min
+{
+    static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << digits);
+};
+
+template <class _Tp, int digits>
+struct __libcpp_compute_min<_Tp, digits, false>
+{
+    static _LIBCPP_CONSTEXPR const _Tp value = _Tp(0);
+};
+
+template <class _Tp>
+class __libcpp_numeric_limits<_Tp, true>
+{
+protected:
+    typedef _Tp type;
+
+    static _LIBCPP_CONSTEXPR const bool is_specialized = true;
+
+    static _LIBCPP_CONSTEXPR const bool is_signed = type(-1) < type(0);
+    static _LIBCPP_CONSTEXPR const int  digits = static_cast<int>(sizeof(type) * __CHAR_BIT__ - is_signed);
+    static _LIBCPP_CONSTEXPR const int  digits10 = digits * 3 / 10;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;
+    static _LIBCPP_CONSTEXPR const type __min = __libcpp_compute_min<type, digits, is_signed>::value;
+    static _LIBCPP_CONSTEXPR const type __max = is_signed ? type(type(~0) ^ __min) : type(~0);
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_integer = true;
+    static _LIBCPP_CONSTEXPR const bool is_exact = true;
+    static _LIBCPP_CONSTEXPR const int  radix = 2;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = false;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = true;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = true;
+
+#if __i386__ || __x86_64__
+    static _LIBCPP_CONSTEXPR const bool traps = true;
+#else
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+#endif
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;
+};
+
+template <>
+class __libcpp_numeric_limits<bool, true>
+{
+protected:
+    typedef bool type;
+
+    static _LIBCPP_CONSTEXPR const bool is_specialized = true;
+
+    static _LIBCPP_CONSTEXPR const bool is_signed = false;
+    static _LIBCPP_CONSTEXPR const int  digits = 1;
+    static _LIBCPP_CONSTEXPR const int  digits10 = 0;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 0;
+    static _LIBCPP_CONSTEXPR const type __min = false;
+    static _LIBCPP_CONSTEXPR const type __max = true;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __min;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __max;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_integer = true;
+    static _LIBCPP_CONSTEXPR const bool is_exact = true;
+    static _LIBCPP_CONSTEXPR const int  radix = 2;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return type(0);}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = 0;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = 0;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = false;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = false;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = false;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_absent;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return type(0);}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return type(0);}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = true;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = false;
+
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero;
+};
+
+template <>
+class __libcpp_numeric_limits<float, true>
+{
+protected:
+    typedef float type;
+
+    static _LIBCPP_CONSTEXPR const bool is_specialized = true;
+
+    static _LIBCPP_CONSTEXPR const bool is_signed = true;
+    static _LIBCPP_CONSTEXPR const int  digits = __FLT_MANT_DIG__;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __FLT_DIG__;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __FLT_MIN__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __FLT_MAX__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}
+
+    static _LIBCPP_CONSTEXPR const bool is_integer = false;
+    static _LIBCPP_CONSTEXPR const bool is_exact = false;
+    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __FLT_EPSILON__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5F;}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __FLT_MIN_EXP__;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __FLT_MIN_10_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __FLT_MAX_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __FLT_MAX_10_EXP__;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = true;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_valf();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanf("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansf("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __FLT_DENORM_MIN__;}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = true;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = false;
+
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
+};
+
+template <>
+class __libcpp_numeric_limits<double, true>
+{
+protected:
+    typedef double type;
+
+    static _LIBCPP_CONSTEXPR const bool is_specialized = true;
+
+    static _LIBCPP_CONSTEXPR const bool is_signed = true;
+    static _LIBCPP_CONSTEXPR const int  digits = __DBL_MANT_DIG__;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __DBL_DIG__;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __DBL_MIN__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __DBL_MAX__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}
+
+    static _LIBCPP_CONSTEXPR const bool is_integer = false;
+    static _LIBCPP_CONSTEXPR const bool is_exact = false;
+    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __DBL_EPSILON__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __DBL_MIN_EXP__;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __DBL_MIN_10_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __DBL_MAX_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __DBL_MAX_10_EXP__;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = true;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_val();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nan("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nans("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __DBL_DENORM_MIN__;}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = true;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = false;
+
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
+};
+
+template <>
+class __libcpp_numeric_limits<long double, true>
+{
+protected:
+    typedef long double type;
+
+    static _LIBCPP_CONSTEXPR const bool is_specialized = true;
+
+    static _LIBCPP_CONSTEXPR const bool is_signed = true;
+    static _LIBCPP_CONSTEXPR const int  digits = __LDBL_MANT_DIG__;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __LDBL_DIG__;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = 2+(digits * 30103)/100000;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __LDBL_MIN__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __LDBL_MAX__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();}
+
+    static _LIBCPP_CONSTEXPR const bool is_integer = false;
+    static _LIBCPP_CONSTEXPR const bool is_exact = false;
+    static _LIBCPP_CONSTEXPR const int  radix = __FLT_RADIX__;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __LDBL_EPSILON__;}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return 0.5;}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __LDBL_MIN_EXP__;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __LDBL_MIN_10_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __LDBL_MAX_EXP__;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __LDBL_MAX_10_EXP__;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = true;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = true;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = true;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = denorm_present;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = false;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __builtin_huge_vall();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __builtin_nanl("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __builtin_nansl("");}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __LDBL_DENORM_MIN__;}
+
+#if (defined(__ppc__) || defined(__ppc64__))
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = false;
+#else
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = true;
+#endif
+    static _LIBCPP_CONSTEXPR const bool is_bounded = true;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = false;
+
+    static _LIBCPP_CONSTEXPR const bool traps = false;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = false;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = round_to_nearest;
+};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits
+    : private __libcpp_numeric_limits<typename remove_cv<_Tp>::type>
+{
+    typedef __libcpp_numeric_limits<typename remove_cv<_Tp>::type> __base;
+    typedef typename __base::type type;
+public:
+    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}
+
+    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;
+    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
+    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
+    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
+    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
+
+    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
+};
+
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_specialized;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_signed;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_integer;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_exact;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::radix;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_infinity;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_quiet_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_signaling_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<_Tp>::has_denorm;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_denorm_loss;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_iec559;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_bounded;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_modulo;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::traps;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::tinyness_before;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style;
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<const _Tp>
+    : private numeric_limits<_Tp>
+{
+    typedef numeric_limits<_Tp> __base;
+    typedef _Tp type;
+public:
+    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}
+
+    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;
+    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
+    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
+    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
+    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
+
+    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
+};
+
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_specialized;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_signed;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_integer;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_exact;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::radix;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::min_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const _Tp>::max_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_infinity;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_quiet_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_signaling_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const _Tp>::has_denorm;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::has_denorm_loss;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_iec559;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_bounded;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::is_modulo;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::traps;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const _Tp>::tinyness_before;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<const _Tp>::round_style;
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<volatile _Tp>
+    : private numeric_limits<_Tp>
+{
+    typedef numeric_limits<_Tp> __base;
+    typedef _Tp type;
+public:
+    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}
+
+    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;
+    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
+    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
+    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
+    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
+
+    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
+};
+
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_specialized;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_signed;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_integer;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_exact;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::radix;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::min_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<volatile _Tp>::max_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_infinity;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_quiet_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_signaling_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<volatile _Tp>::has_denorm;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::has_denorm_loss;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_iec559;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_bounded;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::is_modulo;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::traps;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<volatile _Tp>::tinyness_before;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<volatile _Tp>::round_style;
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY numeric_limits<const volatile _Tp>
+    : private numeric_limits<_Tp>
+{
+    typedef numeric_limits<_Tp> __base;
+    typedef _Tp type;
+public:
+    static _LIBCPP_CONSTEXPR const bool is_specialized = __base::is_specialized;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __base::min();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __base::max();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return __base::lowest();}
+
+    static _LIBCPP_CONSTEXPR const int  digits = __base::digits;
+    static _LIBCPP_CONSTEXPR const int  digits10 = __base::digits10;
+    static _LIBCPP_CONSTEXPR const int  max_digits10 = __base::max_digits10;
+    static _LIBCPP_CONSTEXPR const bool is_signed = __base::is_signed;
+    static _LIBCPP_CONSTEXPR const bool is_integer = __base::is_integer;
+    static _LIBCPP_CONSTEXPR const bool is_exact = __base::is_exact;
+    static _LIBCPP_CONSTEXPR const int  radix = __base::radix;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type epsilon() _NOEXCEPT {return __base::epsilon();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type round_error() _NOEXCEPT {return __base::round_error();}
+
+    static _LIBCPP_CONSTEXPR const int  min_exponent = __base::min_exponent;
+    static _LIBCPP_CONSTEXPR const int  min_exponent10 = __base::min_exponent10;
+    static _LIBCPP_CONSTEXPR const int  max_exponent = __base::max_exponent;
+    static _LIBCPP_CONSTEXPR const int  max_exponent10 = __base::max_exponent10;
+
+    static _LIBCPP_CONSTEXPR const bool has_infinity = __base::has_infinity;
+    static _LIBCPP_CONSTEXPR const bool has_quiet_NaN = __base::has_quiet_NaN;
+    static _LIBCPP_CONSTEXPR const bool has_signaling_NaN = __base::has_signaling_NaN;
+    static _LIBCPP_CONSTEXPR const float_denorm_style has_denorm = __base::has_denorm;
+    static _LIBCPP_CONSTEXPR const bool has_denorm_loss = __base::has_denorm_loss;
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type infinity() _NOEXCEPT {return __base::infinity();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type quiet_NaN() _NOEXCEPT {return __base::quiet_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type signaling_NaN() _NOEXCEPT {return __base::signaling_NaN();}
+    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type denorm_min() _NOEXCEPT {return __base::denorm_min();}
+
+    static _LIBCPP_CONSTEXPR const bool is_iec559 = __base::is_iec559;
+    static _LIBCPP_CONSTEXPR const bool is_bounded = __base::is_bounded;
+    static _LIBCPP_CONSTEXPR const bool is_modulo = __base::is_modulo;
+
+    static _LIBCPP_CONSTEXPR const bool traps = __base::traps;
+    static _LIBCPP_CONSTEXPR const bool tinyness_before = __base::tinyness_before;
+    static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style;
+};
+
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_specialized;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_digits10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_signed;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_integer;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_exact;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::radix;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::min_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const int numeric_limits<const volatile _Tp>::max_exponent10;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_infinity;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_quiet_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_signaling_NaN;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<const volatile _Tp>::has_denorm;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::has_denorm_loss;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_iec559;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_bounded;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::is_modulo;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::traps;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const bool numeric_limits<const volatile _Tp>::tinyness_before;
+template <class _Tp>
+    _LIBCPP_CONSTEXPR const float_round_style numeric_limits<const volatile _Tp>::round_style;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_LIMITS
diff --git a/include/c++/v1/list b/include/c++/v1/list
new file mode 100644
index 0000000..800a1a3
--- /dev/null
+++ b/include/c++/v1/list
@@ -0,0 +1,2355 @@
+// -*- C++ -*-
+//===---------------------------- list ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LIST
+#define _LIBCPP_LIST
+
+/*
+    list synopsis
+
+namespace std
+{
+
+template <class T, class Alloc = allocator<T> >
+class list
+{
+public:
+
+    // types:
+    typedef T value_type;
+    typedef Alloc allocator_type;
+    typedef typename allocator_type::reference reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::pointer pointer;
+    typedef typename allocator_type::const_pointer const_pointer;
+    typedef implementation-defined iterator;
+    typedef implementation-defined const_iterator;
+    typedef implementation-defined size_type;
+    typedef implementation-defined difference_type;
+    typedef reverse_iterator<iterator> reverse_iterator;
+    typedef reverse_iterator<const_iterator> const_reverse_iterator;
+
+    list()
+        noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit list(const allocator_type& a);
+    explicit list(size_type n);
+    explicit list(size_type n, const allocator_type& a); // C++14
+    list(size_type n, const value_type& value);
+    list(size_type n, const value_type& value, const allocator_type& a);
+    template <class Iter>
+        list(Iter first, Iter last);
+    template <class Iter>
+        list(Iter first, Iter last, const allocator_type& a);
+    list(const list& x);
+    list(const list&, const allocator_type& a);
+    list(list&& x)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    list(list&&, const allocator_type& a);
+    list(initializer_list<value_type>);
+    list(initializer_list<value_type>, const allocator_type& a);
+
+    ~list();
+
+    list& operator=(const list& x);
+    list& operator=(list&& x)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    list& operator=(initializer_list<value_type>);
+    template <class Iter>
+        void assign(Iter first, Iter last);
+    void assign(size_type n, const value_type& t);
+    void assign(initializer_list<value_type>);
+
+    allocator_type get_allocator() const noexcept;
+
+    iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+    iterator end() noexcept;
+    const_iterator end() const noexcept;
+    reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+    reverse_iterator rend() noexcept;
+    const_reverse_iterator rend() const noexcept;
+    const_iterator cbegin() const noexcept;
+    const_iterator cend() const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend() const noexcept;
+
+    reference front();
+    const_reference front() const;
+    reference back();
+    const_reference back() const;
+
+    bool empty() const noexcept;
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+
+    template <class... Args>
+        void emplace_front(Args&&... args);
+    void pop_front();
+    template <class... Args>
+        void emplace_back(Args&&... args);
+    void pop_back();
+    void push_front(const value_type& x);
+    void push_front(value_type&& x);
+    void push_back(const value_type& x);
+    void push_back(value_type&& x);
+    template <class... Args>
+        iterator emplace(const_iterator position, Args&&... args);
+    iterator insert(const_iterator position, const value_type& x);
+    iterator insert(const_iterator position, value_type&& x);
+    iterator insert(const_iterator position, size_type n, const value_type& x);
+    template <class Iter>
+        iterator insert(const_iterator position, Iter first, Iter last);
+    iterator insert(const_iterator position, initializer_list<value_type> il);
+
+    iterator erase(const_iterator position);
+    iterator erase(const_iterator position, const_iterator last);
+
+    void resize(size_type sz);
+    void resize(size_type sz, const value_type& c);
+
+    void swap(list&)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value);
+    void clear() noexcept;
+
+    void splice(const_iterator position, list& x);
+    void splice(const_iterator position, list&& x);
+    void splice(const_iterator position, list& x, const_iterator i);
+    void splice(const_iterator position, list&& x, const_iterator i);
+    void splice(const_iterator position, list& x, const_iterator first,
+                                                  const_iterator last);
+    void splice(const_iterator position, list&& x, const_iterator first,
+                                                  const_iterator last);
+
+    void remove(const value_type& value);
+    template <class Pred> void remove_if(Pred pred);
+    void unique();
+    template <class BinaryPredicate>
+        void unique(BinaryPredicate binary_pred);
+    void merge(list& x);
+    void merge(list&& x);
+    template <class Compare>
+        void merge(list& x, Compare comp);
+    template <class Compare>
+        void merge(list&& x, Compare comp);
+    void sort();
+    template <class Compare>
+        void sort(Compare comp);
+    void reverse() noexcept;
+};
+
+template <class T, class Alloc>
+    bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y);
+template <class T, class Alloc>
+    bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y);
+template <class T, class Alloc>
+    bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+template <class T, class Alloc>
+    bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y);
+template <class T, class Alloc>
+    bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+template <class T, class Alloc>
+    bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y);
+
+template <class T, class Alloc>
+    void swap(list<T,Alloc>& x, list<T,Alloc>& y)
+         noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+
+#include <memory>
+#include <limits>
+#include <initializer_list>
+#include <iterator>
+#include <algorithm>
+
+#include <__undef_min_max>
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _VoidPtr> struct __list_node;
+
+template <class _Tp, class _VoidPtr>
+struct __list_node_base
+{
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+        rebind<__list_node<_Tp, _VoidPtr> > pointer;
+#else
+        rebind<__list_node<_Tp, _VoidPtr> >::other pointer;
+#endif
+
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+        rebind<__list_node_base> __base_pointer;
+#else
+        rebind<__list_node_base>::other __base_pointer;
+#endif
+
+    pointer __prev_;
+    pointer __next_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_node_base()
+        : __prev_(static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this))),
+          __next_(static_cast<pointer>(pointer_traits<__base_pointer>::pointer_to(*this)))
+          {}
+};
+
+template <class _Tp, class _VoidPtr>
+struct __list_node
+    : public __list_node_base<_Tp, _VoidPtr>
+{
+    _Tp __value_;
+};
+
+template <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY list;
+template <class _Tp, class _Alloc> class __list_imp;
+template <class _Tp, class _VoidPtr> class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator;
+
+template <class _Tp, class _VoidPtr>
+class _LIBCPP_TYPE_VIS_ONLY __list_iterator
+{
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
+#else
+        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
+#endif
+
+    __node_pointer __ptr_;
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
+        : __ptr_(__p)
+    {
+        __get_db()->__insert_ic(this, __c);
+    }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+#endif
+
+
+
+    template<class, class> friend class list;
+    template<class, class> friend class __list_imp;
+    template<class, class> friend class __list_const_iterator;
+public:
+    typedef bidirectional_iterator_tag       iterator_category;
+    typedef _Tp                              value_type;
+    typedef value_type&                      reference;
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                             pointer;
+    typedef typename pointer_traits<pointer>::difference_type difference_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator() _NOEXCEPT : __ptr_(nullptr)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator(const __list_iterator& __p)
+        : __ptr_(__p.__ptr_)
+    {
+        __get_db()->__iterator_copy(this, &__p);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__list_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator& operator=(const __list_iterator& __p)
+    {
+        if (this != &__p)
+        {
+            __get_db()->__iterator_copy(this, &__p);
+            __ptr_ = __p.__ptr_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::iterator");
+#endif
+        return __ptr_->__value_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::iterator");
+#endif
+        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable list::iterator");
+#endif
+        __ptr_ = __ptr_->__next_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator& operator--()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
+                       "Attempted to decrement non-decrementable list::iterator");
+#endif
+        __ptr_ = __ptr_->__prev_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __list_iterator& __x, const __list_iterator& __y)
+    {
+        return __x.__ptr_ == __y.__ptr_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+     bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
+        {return !(__x == __y);}
+};
+
+template <class _Tp, class _VoidPtr>
+class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator
+{
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+        rebind<__list_node<_Tp, _VoidPtr> > __node_pointer;
+#else
+        rebind<__list_node<_Tp, _VoidPtr> >::other __node_pointer;
+#endif
+
+    __node_pointer __ptr_;
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT
+        : __ptr_(__p)
+    {
+        __get_db()->__insert_ic(this, __c);
+    }
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+#endif
+
+    template<class, class> friend class list;
+    template<class, class> friend class __list_imp;
+public:
+    typedef bidirectional_iterator_tag       iterator_category;
+    typedef _Tp                              value_type;
+    typedef const value_type&                reference;
+    typedef typename pointer_traits<_VoidPtr>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                             pointer;
+    typedef typename pointer_traits<pointer>::difference_type difference_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator() _NOEXCEPT : __ptr_(nullptr)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_i(this);
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT
+        : __ptr_(__p.__ptr_)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__iterator_copy(this, &__p);
+#endif
+    }
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator(const __list_const_iterator& __p)
+        : __ptr_(__p.__ptr_)
+    {
+        __get_db()->__iterator_copy(this, &__p);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__list_const_iterator()
+    {
+        __get_db()->__erase_i(this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator& operator=(const __list_const_iterator& __p)
+    {
+        if (this != &__p)
+        {
+            __get_db()->__iterator_copy(this, &__p);
+            __ptr_ = __p.__ptr_;
+        }
+        return *this;
+    }
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::const_iterator");
+#endif
+        return __ptr_->__value_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable list::iterator");
+#endif
+        return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator& operator++()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to increment non-incrementable list::const_iterator");
+#endif
+        __ptr_ = __ptr_->__next_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator& operator--()
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
+                       "Attempted to decrement non-decrementable list::const_iterator");
+#endif
+        __ptr_ = __ptr_->__prev_;
+        return *this;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y)
+    {
+        return __x.__ptr_ == __y.__ptr_;
+    }
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y)
+        {return !(__x == __y);}
+};
+
+template <class _Tp, class _Alloc>
+class __list_imp
+{
+    __list_imp(const __list_imp&);
+    __list_imp& operator=(const __list_imp&);
+protected:
+    typedef _Tp                                                     value_type;
+    typedef _Alloc                                                  allocator_type;
+    typedef allocator_traits<allocator_type>                        __alloc_traits;
+    typedef typename __alloc_traits::size_type                      size_type;
+    typedef typename __alloc_traits::void_pointer                   __void_pointer;
+    typedef __list_iterator<value_type, __void_pointer>             iterator;
+    typedef __list_const_iterator<value_type, __void_pointer>       const_iterator;
+    typedef __list_node_base<value_type, __void_pointer>            __node_base;
+    typedef __list_node<value_type, __void_pointer>                 __node;
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__node>
+#else
+                rebind_alloc<__node>::other
+#endif
+                                                                     __node_allocator;
+    typedef allocator_traits<__node_allocator>                       __node_alloc_traits;
+    typedef typename __node_alloc_traits::pointer                    __node_pointer;
+    typedef typename __node_alloc_traits::pointer                    __node_const_pointer;
+    typedef typename __alloc_traits::pointer                         pointer;
+    typedef typename __alloc_traits::const_pointer                   const_pointer;
+    typedef typename __alloc_traits::difference_type                 difference_type;
+
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__node_base>
+#else
+                rebind_alloc<__node_base>::other
+#endif
+                                                                     __node_base_allocator;
+    typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;
+
+    __node_base __end_;
+    __compressed_pair<size_type, __node_allocator> __size_alloc_;
+
+    _LIBCPP_INLINE_VISIBILITY
+          size_type& __sz() _NOEXCEPT {return __size_alloc_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    const size_type& __sz() const _NOEXCEPT
+        {return __size_alloc_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+          __node_allocator& __node_alloc() _NOEXCEPT
+          {return __size_alloc_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const __node_allocator& __node_alloc() const _NOEXCEPT
+        {return __size_alloc_.second();}
+
+    static void __unlink_nodes(__node_pointer __f, __node_pointer __l) _NOEXCEPT;
+
+    __list_imp()
+        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
+    __list_imp(const allocator_type& __a);
+    ~__list_imp();
+    void clear() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT {return __sz() == 0;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return iterator(__end_.__next_, this);
+#else
+        return iterator(__end_.__next_);
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const  _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_iterator(__end_.__next_, this);
+#else
+        return const_iterator(__end_.__next_);
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return iterator(static_cast<__node_pointer>(
+                pointer_traits<__node_base_pointer>::pointer_to(__end_)), this);
+#else
+        return iterator(static_cast<__node_pointer>(
+                      pointer_traits<__node_base_pointer>::pointer_to(__end_)));
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        return const_iterator(static_cast<__node_const_pointer>(
+        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))), this);
+#else
+        return const_iterator(static_cast<__node_const_pointer>(
+        pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(__end_))));
+#endif
+    }
+
+    void swap(__list_imp& __c)
+        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __list_imp& __c)
+        {__copy_assign_alloc(__c, integral_constant<bool,
+                      __node_alloc_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__list_imp& __c)
+        _NOEXCEPT_(
+            !__node_alloc_traits::propagate_on_container_move_assignment::value ||
+            is_nothrow_move_assignable<__node_allocator>::value)
+        {__move_assign_alloc(__c, integral_constant<bool,
+                      __node_alloc_traits::propagate_on_container_move_assignment::value>());}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
+        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __node_alloc_traits::propagate_on_container_swap::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
+        _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __list_imp& __c, true_type)
+        {
+            if (__node_alloc() != __c.__node_alloc())
+                clear();
+            __node_alloc() = __c.__node_alloc();
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __list_imp& __c, false_type)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__list_imp& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
+        {
+            __node_alloc() = _VSTD::move(__c.__node_alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__list_imp& __c, false_type)
+        _NOEXCEPT
+        {}
+};
+
+// Unlink nodes [__f, __l]
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__list_imp<_Tp, _Alloc>::__unlink_nodes(__node_pointer __f, __node_pointer __l)
+    _NOEXCEPT
+{
+    __f->__prev_->__next_ = __l->__next_;
+    __l->__next_->__prev_ = __f->__prev_;
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__list_imp<_Tp, _Alloc>::__list_imp()
+        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
+    : __size_alloc_(0)
+{
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+__list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a)
+    : __size_alloc_(0, __node_allocator(__a))
+{
+}
+
+template <class _Tp, class _Alloc>
+__list_imp<_Tp, _Alloc>::~__list_imp()
+{
+    clear();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
+}
+
+template <class _Tp, class _Alloc>
+void
+__list_imp<_Tp, _Alloc>::clear() _NOEXCEPT
+{
+    if (!empty())
+    {
+        __node_allocator& __na = __node_alloc();
+        __node_pointer __f = __end_.__next_;
+        __node_pointer __l = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
+        __unlink_nodes(__f, __l->__prev_);
+        __sz() = 0;
+        while (__f != __l)
+        {
+            __node_pointer __n = __f;
+            __f = __f->__next_;
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+            __node_alloc_traits::deallocate(__na, __n, 1);
+        }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __c_node* __c = __get_db()->__find_c_and_lock(this);
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->__ptr_ != __l)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+#endif
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
+        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+{
+    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
+                   this->__node_alloc() == __c.__node_alloc(),
+                   "list::swap: Either propagate_on_container_swap must be true"
+                   " or the allocators must compare equal");
+    using _VSTD::swap;
+    __swap_alloc(__node_alloc(), __c.__node_alloc());
+    swap(__sz(), __c.__sz());
+    swap(__end_, __c.__end_);
+    if (__sz() == 0)
+        __end_.__next_ = __end_.__prev_ = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
+    else
+        __end_.__prev_->__next_ = __end_.__next_->__prev_
+                                = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_));
+    if (__c.__sz() == 0)
+        __c.__end_.__next_ = __c.__end_.__prev_
+                           = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_));
+    else
+        __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_
+                                    = static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __libcpp_db* __db = __get_db();
+    __c_node* __cn1 = __db->__find_c_and_lock(this);
+    __c_node* __cn2 = __db->__find_c(&__c);
+    std::swap(__cn1->beg_, __cn2->beg_);
+    std::swap(__cn1->end_, __cn2->end_);
+    std::swap(__cn1->cap_, __cn2->cap_);
+    for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;)
+    {
+        --__p;
+        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+        if (__i->__ptr_ == static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+        {
+            __cn2->__add(*__p);
+            if (--__cn1->end_ != __p)
+                memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*));
+        }
+        else
+            (*__p)->__c_ = __cn1;
+    }
+    for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
+    {
+        --__p;
+        const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+        if (__i->__ptr_ == static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__end_)))
+        {
+            __cn1->__add(*__p);
+            if (--__cn2->end_ != __p)
+                memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
+        }
+        else
+            (*__p)->__c_ = __cn2;
+    }
+    __db->unlock();
+#endif
+}
+
+template <class _Tp, class _Alloc = allocator<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY list
+    : private __list_imp<_Tp, _Alloc>
+{
+    typedef __list_imp<_Tp, _Alloc> base;
+    typedef typename base::__node              __node;
+    typedef typename base::__node_allocator    __node_allocator;
+    typedef typename base::__node_pointer      __node_pointer;
+    typedef typename base::__node_alloc_traits __node_alloc_traits;
+    typedef typename base::__node_base         __node_base;
+    typedef typename base::__node_base_pointer __node_base_pointer;
+
+public:
+    typedef _Tp                                      value_type;
+    typedef _Alloc                                   allocator_type;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+    typedef typename base::pointer                   pointer;
+    typedef typename base::const_pointer             const_pointer;
+    typedef typename base::size_type                 size_type;
+    typedef typename base::difference_type           difference_type;
+    typedef typename base::iterator                  iterator;
+    typedef typename base::const_iterator            const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    list()
+        _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_c(this);
+#endif
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    explicit list(const allocator_type& __a) : base(__a)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_c(this);
+#endif
+    }
+    explicit list(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit list(size_type __n, const allocator_type& __a);
+#endif
+    list(size_type __n, const value_type& __x);
+    list(size_type __n, const value_type& __x, const allocator_type& __a);
+    template <class _InpIter>
+        list(_InpIter __f, _InpIter __l,
+             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
+    template <class _InpIter>
+        list(_InpIter __f, _InpIter __l, const allocator_type& __a,
+             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
+
+    list(const list& __c);
+    list(const list& __c, const allocator_type& __a);
+    list& operator=(const list& __c);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    list(initializer_list<value_type> __il);
+    list(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    list(list&& __c)
+        _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value);
+    list(list&& __c, const allocator_type& __a);
+    list& operator=(list&& __c)
+        _NOEXCEPT_(
+            __node_alloc_traits::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<__node_allocator>::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    list& operator=(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end()); return *this;}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template <class _InpIter>
+        void assign(_InpIter __f, _InpIter __l,
+             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
+    void assign(size_type __n, const value_type& __x);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void assign(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    allocator_type get_allocator() const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT     {return base::__sz();}
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT         {return base::empty();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT
+        {return numeric_limits<difference_type>::max();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin() _NOEXCEPT        {return base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const _NOEXCEPT {return base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT          {return base::end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const _NOEXCEPT {return base::end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return base::begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend()   const _NOEXCEPT {return base::end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rbegin() _NOEXCEPT
+            {return       reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin()  const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rend() _NOEXCEPT
+            {return       reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend()    const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend()   const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference front()
+    {
+        _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
+        return base::__end_.__next_->__value_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference front() const
+    {
+        _LIBCPP_ASSERT(!empty(), "list::front called on empty list");
+        return base::__end_.__next_->__value_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    reference back()
+    {
+        _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
+        return base::__end_.__prev_->__value_;
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference back() const
+    {
+        _LIBCPP_ASSERT(!empty(), "list::back called on empty list");
+        return base::__end_.__prev_->__value_;
+    }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void push_front(value_type&& __x);
+    void push_back(value_type&& __x);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+       void emplace_front(_Args&&... __args);
+    template <class... _Args>
+        void emplace_back(_Args&&... __args);
+    template <class... _Args>
+        iterator emplace(const_iterator __p, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+    iterator insert(const_iterator __p, value_type&& __x);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    void push_front(const value_type& __x);
+    void push_back(const value_type& __x);
+
+    iterator insert(const_iterator __p, const value_type& __x);
+    iterator insert(const_iterator __p, size_type __n, const value_type& __x);
+    template <class _InpIter>
+        iterator insert(const_iterator __p, _InpIter __f, _InpIter __l,
+             typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, initializer_list<value_type> __il)
+        {return insert(__p, __il.begin(), __il.end());}
+#endif   // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(list& __c)
+        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<__node_allocator>::value)
+        {base::swap(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {base::clear();}
+
+    void pop_front();
+    void pop_back();
+
+    iterator erase(const_iterator __p);
+    iterator erase(const_iterator __f, const_iterator __l);
+
+    void resize(size_type __n);
+    void resize(size_type __n, const value_type& __x);
+
+    void splice(const_iterator __p, list& __c);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void splice(const_iterator __p, list&& __c) {splice(__p, __c);}
+#endif
+    void splice(const_iterator __p, list& __c, const_iterator __i);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void splice(const_iterator __p, list&& __c, const_iterator __i)
+        {splice(__p, __c, __i);}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l)
+        {splice(__p, __c, __f, __l);}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    void remove(const value_type& __x);
+    template <class _Pred> void remove_if(_Pred __pred);
+    void unique();
+    template <class _BinaryPred>
+        void unique(_BinaryPred __binary_pred);
+    void merge(list& __c);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void merge(list&& __c) {merge(__c);}
+#endif
+    template <class _Comp>
+        void merge(list& __c, _Comp __comp);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Comp>
+    _LIBCPP_INLINE_VISIBILITY
+        void merge(list&& __c, _Comp __comp) {merge(__c, __comp);}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void sort();
+    template <class _Comp>
+        void sort(_Comp __comp);
+
+    void reverse() _NOEXCEPT;
+
+    bool __invariants() const;
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+    static void __link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l);
+    iterator __iterator(size_type __n);
+    template <class _Comp>
+        static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp);
+
+    void __move_assign(list& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value);
+    void __move_assign(list& __c, false_type);
+};
+
+// Link in nodes [__f, __l] just prior to __p
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+list<_Tp, _Alloc>::__link_nodes(__node_pointer __p, __node_pointer __f, __node_pointer __l)
+{
+    __p->__prev_->__next_ = __f;
+    __f->__prev_ = __p->__prev_;
+    __p->__prev_ = __l;
+    __l->__next_ = __p;
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::__iterator(size_type __n)
+{
+    return __n <= base::__sz() / 2 ? _VSTD::next(begin(), __n)
+                                   : _VSTD::prev(end(), base::__sz() - __n);
+}
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(size_type __n)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __n > 0; --__n)
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        emplace_back();
+#else
+        push_back(value_type());
+#endif
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __n > 0; --__n)
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        emplace_back();
+#else
+        push_back(value_type());
+#endif
+}
+#endif
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __n > 0; --__n)
+        push_back(__x);
+}
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a)
+    : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __n > 0; --__n)
+        push_back(__x);
+}
+
+template <class _Tp, class _Alloc>
+template <class _InpIter>
+list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
+                        typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __f != __l; ++__f)
+        push_back(*__f);
+}
+
+template <class _Tp, class _Alloc>
+template <class _InpIter>
+list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a,
+                        typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
+    : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __f != __l; ++__f)
+        push_back(*__f);
+}
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(const list& __c)
+    : base(allocator_type(
+           __node_alloc_traits::select_on_container_copy_construction(
+                __c.__node_alloc())))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
+        push_back(*__i);
+}
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a)
+    : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i)
+        push_back(*__i);
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a)
+    : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
+            __e = __il.end(); __i != __e; ++__i)
+        push_back(*__i);
+}
+
+template <class _Tp, class _Alloc>
+list<_Tp, _Alloc>::list(initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (typename initializer_list<value_type>::const_iterator __i = __il.begin(),
+            __e = __il.end(); __i != __e; ++__i)
+        push_back(*__i);
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+list<_Tp, _Alloc>&
+list<_Tp, _Alloc>::operator=(const list& __c)
+{
+    if (this != &__c)
+    {
+        base::__copy_assign_alloc(__c);
+        assign(__c.begin(), __c.end());
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+list<_Tp, _Alloc>::list(list&& __c)
+    _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value)
+    : base(allocator_type(_VSTD::move(__c.__node_alloc())))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    splice(end(), __c);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a)
+    : base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a == __c.get_allocator())
+        splice(end(), __c);
+    else
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+list<_Tp, _Alloc>&
+list<_Tp, _Alloc>::operator=(list&& __c)
+        _NOEXCEPT_(
+            __node_alloc_traits::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<__node_allocator>::value)
+{
+    __move_assign(__c, integral_constant<bool,
+          __node_alloc_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::__move_assign(list& __c, false_type)
+{
+    if (base::__node_alloc() != __c.__node_alloc())
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+    else
+        __move_assign(__c, true_type());
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::__move_assign(list& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
+{
+    clear();
+    base::__move_assign_alloc(__c);
+    splice(end(), __c);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+template <class _InpIter>
+void
+list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l,
+                          typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
+{
+    iterator __i = begin();
+    iterator __e = end();
+    for (; __f != __l && __i != __e; ++__f, ++__i)
+        *__i = *__f;
+    if (__i == __e)
+        insert(__e, __f, __l);
+    else
+        erase(__i, __e);
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x)
+{
+    iterator __i = begin();
+    iterator __e = end();
+    for (; __n > 0 && __i != __e; --__n, ++__i)
+        *__i = __x;
+    if (__i == __e)
+        insert(__e, __n, __x);
+    else
+        erase(__i, __e);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+_Alloc
+list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT
+{
+    return allocator_type(base::__node_alloc());
+}
+
+template <class _Tp, class _Alloc>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::insert(iterator, x) called with an iterator not"
+        " referring to this list");
+#endif
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __hold->__prev_ = 0;
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    ++base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__hold.release(), this);
+#else
+    return iterator(__hold.release());
+#endif
+}
+
+template <class _Tp, class _Alloc>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::insert(iterator, n, x) called with an iterator not"
+        " referring to this list");
+    iterator __r(__p.__ptr_, this);
+#else
+    iterator __r(__p.__ptr_);
+#endif
+    if (__n > 0)
+    {
+        size_type __ds = 0;
+        __node_allocator& __na = base::__node_alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+        __hold->__prev_ = 0;
+        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+        ++__ds;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __r = iterator(__hold.get(), this);
+#else
+        __r = iterator(__hold.get());
+#endif
+        __hold.release();
+        iterator __e = __r;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (--__n; __n != 0; --__n, ++__e, ++__ds)
+            {
+                __hold.reset(__node_alloc_traits::allocate(__na, 1));
+                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+                __e.__ptr_->__next_ = __hold.get();
+                __hold->__prev_ = __e.__ptr_;
+                __hold.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (true)
+            {
+                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
+                __node_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                if (__prev == 0)
+                    break;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                __e = iterator(__prev, this);
+#else
+                __e = iterator(__prev);
+#endif
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
+        base::__sz() += __ds;
+    }
+    return __r;
+}
+
+template <class _Tp, class _Alloc>
+template <class _InpIter>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l,
+             typename enable_if<__is_input_iterator<_InpIter>::value>::type*)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::insert(iterator, range) called with an iterator not"
+        " referring to this list");
+    iterator __r(__p.__ptr_, this);
+#else
+    iterator __r(__p.__ptr_);
+#endif
+    if (__f != __l)
+    {
+        size_type __ds = 0;
+        __node_allocator& __na = base::__node_alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+        __hold->__prev_ = 0;
+        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
+        ++__ds;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __r = iterator(__hold.get(), this);
+#else
+        __r = iterator(__hold.get());
+#endif
+        __hold.release();
+        iterator __e = __r;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (++__f; __f != __l; ++__f, ++__e, ++__ds)
+            {
+                __hold.reset(__node_alloc_traits::allocate(__na, 1));
+                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
+                __e.__ptr_->__next_ = __hold.get();
+                __hold->__prev_ = __e.__ptr_;
+                __hold.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (true)
+            {
+                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
+                __node_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                if (__prev == 0)
+                    break;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                __e = iterator(__prev, this);
+#else
+                __e = iterator(__prev);
+#endif
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_);
+        base::__sz() += __ds;
+    }
+    return __r;
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::push_front(const value_type& __x)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::push_back(const value_type& __x)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::push_front(value_type&& __x)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::push_back(value_type&& __x)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+template <class... _Args>
+void
+list<_Tp, _Alloc>::emplace_front(_Args&&... __args)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
+    __link_nodes(base::__end_.__next_, __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+template <class _Tp, class _Alloc>
+template <class... _Args>
+void
+list<_Tp, _Alloc>::emplace_back(_Args&&... __args)
+{
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
+    __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __hold.get(), __hold.get());
+    ++base::__sz();
+    __hold.release();
+}
+
+template <class _Tp, class _Alloc>
+template <class... _Args>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::emplace(iterator, args...) called with an iterator not"
+        " referring to this list");
+#endif
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __hold->__prev_ = 0;
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...);
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    ++base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__hold.release(), this);
+#else
+    return iterator(__hold.release());
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Alloc>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::insert(iterator, x) called with an iterator not"
+        " referring to this list");
+#endif
+    __node_allocator& __na = base::__node_alloc();
+    typedef __allocator_destructor<__node_allocator> _Dp;
+    unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+    __hold->__prev_ = 0;
+    __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x));
+    __link_nodes(__p.__ptr_, __hold.get(), __hold.get());
+    ++base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__hold.release(), this);
+#else
+    return iterator(__hold.release());
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::pop_front()
+{
+    _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list");
+    __node_allocator& __na = base::__node_alloc();
+    __node_pointer __n = base::__end_.__next_;
+    base::__unlink_nodes(__n, __n);
+    --base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    {
+        --__p;
+        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        if (__i->__ptr_ == __n)
+        {
+            (*__p)->__c_ = nullptr;
+            if (--__c->end_ != __p)
+                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+        }
+    }
+    __get_db()->unlock();
+#endif
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::pop_back()
+{
+    _LIBCPP_ASSERT(!empty(), "list::pop_back() called with empty list");
+    __node_allocator& __na = base::__node_alloc();
+    __node_pointer __n = base::__end_.__prev_;
+    base::__unlink_nodes(__n, __n);
+    --base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    {
+        --__p;
+        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        if (__i->__ptr_ == __n)
+        {
+            (*__p)->__c_ = nullptr;
+            if (--__c->end_ != __p)
+                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+        }
+    }
+    __get_db()->unlock();
+#endif
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
+}
+
+template <class _Tp, class _Alloc>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::erase(const_iterator __p)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::erase(iterator) called with an iterator not"
+        " referring to this list");
+#endif
+    _LIBCPP_ASSERT(__p != end(),
+        "list::erase(iterator) called with a non-dereferenceable iterator");
+    __node_allocator& __na = base::__node_alloc();
+    __node_pointer __n = __p.__ptr_;
+    __node_pointer __r = __n->__next_;
+    base::__unlink_nodes(__n, __n);
+    --base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    for (__i_node** __p = __c->end_; __p != __c->beg_; )
+    {
+        --__p;
+        iterator* __i = static_cast<iterator*>((*__p)->__i_);
+        if (__i->__ptr_ == __n)
+        {
+            (*__p)->__c_ = nullptr;
+            if (--__c->end_ != __p)
+                memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+        }
+    }
+    __get_db()->unlock();
+#endif
+    __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+    __node_alloc_traits::deallocate(__na, __n, 1);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__r, this);
+#else
+    return iterator(__r);
+#endif
+}
+
+template <class _Tp, class _Alloc>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == this,
+        "list::erase(iterator, iterator) called with an iterator not"
+        " referring to this list");
+#endif
+    if (__f != __l)
+    {
+        __node_allocator& __na = base::__node_alloc();
+        base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
+        while (__f != __l)
+        {
+            __node_pointer __n = __f.__ptr_;
+            ++__f;
+            --base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __c_node* __c = __get_db()->__find_c_and_lock(this);
+            for (__i_node** __p = __c->end_; __p != __c->beg_; )
+            {
+                --__p;
+                iterator* __i = static_cast<iterator*>((*__p)->__i_);
+                if (__i->__ptr_ == __n)
+                {
+                    (*__p)->__c_ = nullptr;
+                    if (--__c->end_ != __p)
+                        memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+                }
+            }
+            __get_db()->unlock();
+#endif
+            __node_alloc_traits::destroy(__na, _VSTD::addressof(__n->__value_));
+            __node_alloc_traits::deallocate(__na, __n, 1);
+        }
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(__l.__ptr_, this);
+#else
+    return iterator(__l.__ptr_);
+#endif
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::resize(size_type __n)
+{
+    if (__n < base::__sz())
+        erase(__iterator(__n), end());
+    else if (__n > base::__sz())
+    {
+        __n -= base::__sz();
+        size_type __ds = 0;
+        __node_allocator& __na = base::__node_alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+        __hold->__prev_ = 0;
+        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
+        ++__ds;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator __r = iterator(__hold.release(), this);
+#else
+        iterator __r = iterator(__hold.release());
+#endif
+        iterator __e = __r;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (--__n; __n != 0; --__n, ++__e, ++__ds)
+            {
+                __hold.reset(__node_alloc_traits::allocate(__na, 1));
+                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_));
+                __e.__ptr_->__next_ = __hold.get();
+                __hold->__prev_ = __e.__ptr_;
+                __hold.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (true)
+            {
+                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
+                __node_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                if (__prev == 0)
+                    break;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                __e = iterator(__prev, this);
+#else
+                __e = iterator(__prev);
+#endif
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
+        base::__sz() += __ds;
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x)
+{
+    if (__n < base::__sz())
+        erase(__iterator(__n), end());
+    else if (__n > base::__sz())
+    {
+        __n -= base::__sz();
+        size_type __ds = 0;
+        __node_allocator& __na = base::__node_alloc();
+        typedef __allocator_destructor<__node_allocator> _Dp;
+        unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1));
+        __hold->__prev_ = 0;
+        __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+        ++__ds;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator __r = iterator(__hold.release(), this);
+#else
+        iterator __r = iterator(__hold.release());
+#endif
+        iterator __e = __r;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (--__n; __n != 0; --__n, ++__e, ++__ds)
+            {
+                __hold.reset(__node_alloc_traits::allocate(__na, 1));
+                __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x);
+                __e.__ptr_->__next_ = __hold.get();
+                __hold->__prev_ = __e.__ptr_;
+                __hold.release();
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            while (true)
+            {
+                __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e));
+                __node_pointer __prev = __e.__ptr_->__prev_;
+                __node_alloc_traits::deallocate(__na, __e.__ptr_, 1);
+                if (__prev == 0)
+                    break;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                __e = iterator(__prev, this);
+#else
+                __e = iterator(__prev);
+#endif
+            }
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __link_nodes(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::
+                         pointer_to(base::__end_)), __r.__ptr_, __e.__ptr_);
+        base::__sz() += __ds;
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::splice(const_iterator __p, list& __c)
+{
+    _LIBCPP_ASSERT(this != &__c,
+                   "list::splice(iterator, list) called with this == &list");
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::splice(iterator, list) called with an iterator not"
+        " referring to this list");
+#endif
+    if (!__c.empty())
+    {
+        __node_pointer __f = __c.__end_.__next_;
+        __node_pointer __l = __c.__end_.__prev_;
+        base::__unlink_nodes(__f, __l);
+        __link_nodes(__p.__ptr_, __f, __l);
+        base::__sz() += __c.__sz();
+        __c.__sz() = 0;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __libcpp_db* __db = __get_db();
+        __c_node* __cn1 = __db->__find_c_and_lock(this);
+        __c_node* __cn2 = __db->__find_c(&__c);
+        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
+        {
+            --__p;
+            iterator* __i = static_cast<iterator*>((*__p)->__i_);
+            if (__i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+            {
+                __cn1->__add(*__p);
+                (*__p)->__c_ = __cn1;
+                if (--__cn2->end_ != __p)
+                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __db->unlock();
+#endif
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::splice(iterator, list, iterator) called with first iterator not"
+        " referring to this list");
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__i) == &__c,
+        "list::splice(iterator, list, iterator) called with second iterator not"
+        " referring to list argument");
+    _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(&__i),
+        "list::splice(iterator, list, iterator) called with second iterator not"
+        " derefereceable");
+#endif
+    if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_)
+    {
+        __node_pointer __f = __i.__ptr_;
+        base::__unlink_nodes(__f, __f);
+        __link_nodes(__p.__ptr_, __f, __f);
+        --__c.__sz();
+        ++base::__sz();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __libcpp_db* __db = __get_db();
+        __c_node* __cn1 = __db->__find_c_and_lock(this);
+        __c_node* __cn2 = __db->__find_c(&__c);
+        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
+        {
+            --__p;
+            iterator* __j = static_cast<iterator*>((*__p)->__i_);
+            if (__j->__ptr_ == __f)
+            {
+                __cn1->__add(*__p);
+                (*__p)->__c_ = __cn1;
+                if (--__cn2->end_ != __p)
+                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __db->unlock();
+#endif
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+        "list::splice(iterator, list, iterator, iterator) called with first iterator not"
+        " referring to this list");
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == &__c,
+        "list::splice(iterator, list, iterator, iterator) called with second iterator not"
+        " referring to list argument");
+    if (this == &__c)
+    {
+        for (const_iterator __i = __f; __i != __l; ++__i)
+            _LIBCPP_ASSERT(__i != __p,
+                           "list::splice(iterator, list, iterator, iterator)"
+                           " called with the first iterator within the range"
+                           " of the second and third iterators");
+    }
+#endif
+    if (__f != __l)
+    {
+        if (this != &__c)
+        {
+            size_type __s = _VSTD::distance(__f, __l);
+            __c.__sz() -= __s;
+            base::__sz() += __s;
+        }
+        __node_pointer __first = __f.__ptr_;
+        --__l;
+        __node_pointer __last = __l.__ptr_;
+        base::__unlink_nodes(__first, __last);
+        __link_nodes(__p.__ptr_, __first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __libcpp_db* __db = __get_db();
+        __c_node* __cn1 = __db->__find_c_and_lock(this);
+        __c_node* __cn2 = __db->__find_c(&__c);
+        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
+        {
+            --__p;
+            iterator* __j = static_cast<iterator*>((*__p)->__i_);
+            for (__node_pointer __k = __f.__ptr_;
+                                          __k != __l.__ptr_; __k = __k->__next_)
+            {
+                if (__j->__ptr_ == __k)
+                {
+                    __cn1->__add(*__p);
+                    (*__p)->__c_ = __cn1;
+                    if (--__cn2->end_ != __p)
+                        memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
+                }
+            }
+        }
+        __db->unlock();
+#endif
+    }
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::remove(const value_type& __x)
+{
+    for (iterator __i = begin(), __e = end(); __i != __e;)
+    {
+        if (*__i == __x)
+        {
+            iterator __j = _VSTD::next(__i);
+            for (; __j != __e && *__j == __x; ++__j)
+                ;
+            __i = erase(__i, __j);
+        }
+        else
+            ++__i;
+    }
+}
+
+template <class _Tp, class _Alloc>
+template <class _Pred>
+void
+list<_Tp, _Alloc>::remove_if(_Pred __pred)
+{
+    for (iterator __i = begin(), __e = end(); __i != __e;)
+    {
+        if (__pred(*__i))
+        {
+            iterator __j = _VSTD::next(__i);
+            for (; __j != __e && __pred(*__j); ++__j)
+                ;
+            __i = erase(__i, __j);
+        }
+        else
+            ++__i;
+    }
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+list<_Tp, _Alloc>::unique()
+{
+    unique(__equal_to<value_type>());
+}
+
+template <class _Tp, class _Alloc>
+template <class _BinaryPred>
+void
+list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred)
+{
+    for (iterator __i = begin(), __e = end(); __i != __e;)
+    {
+        iterator __j = _VSTD::next(__i);
+        for (; __j != __e && __binary_pred(*__i, *__j); ++__j)
+            ;
+        if (++__i != __j)
+            __i = erase(__i, __j);
+    }
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+list<_Tp, _Alloc>::merge(list& __c)
+{
+    merge(__c, __less<value_type>());
+}
+
+template <class _Tp, class _Alloc>
+template <class _Comp>
+void
+list<_Tp, _Alloc>::merge(list& __c, _Comp __comp)
+{
+    if (this != &__c)
+    {
+        iterator __f1 = begin();
+        iterator __e1 = end();
+        iterator __f2 = __c.begin();
+        iterator __e2 = __c.end();
+        while (__f1 != __e1 && __f2 != __e2)
+        {
+            if (__comp(*__f2, *__f1))
+            {
+                size_type __ds = 1;
+                iterator __m2 = _VSTD::next(__f2);
+                for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2, ++__ds)
+                    ;
+                base::__sz() += __ds;
+                __c.__sz() -= __ds;
+                __node_pointer __f = __f2.__ptr_;
+                __node_pointer __l = __m2.__ptr_->__prev_;
+                __f2 = __m2;
+                base::__unlink_nodes(__f, __l);
+                __m2 = _VSTD::next(__f1);
+                __link_nodes(__f1.__ptr_, __f, __l);
+                __f1 = __m2;
+            }
+            else
+                ++__f1;
+        }
+        splice(__e1, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __libcpp_db* __db = __get_db();
+        __c_node* __cn1 = __db->__find_c_and_lock(this);
+        __c_node* __cn2 = __db->__find_c(&__c);
+        for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;)
+        {
+            --__p;
+            iterator* __i = static_cast<iterator*>((*__p)->__i_);
+            if (__i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(__c.__end_)))
+            {
+                __cn1->__add(*__p);
+                (*__p)->__c_ = __cn1;
+                if (--__cn2->end_ != __p)
+                    memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __db->unlock();
+#endif
+    }
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+list<_Tp, _Alloc>::sort()
+{
+    sort(__less<value_type>());
+}
+
+template <class _Tp, class _Alloc>
+template <class _Comp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+list<_Tp, _Alloc>::sort(_Comp __comp)
+{
+    __sort(begin(), end(), base::__sz(), __comp);
+}
+
+template <class _Tp, class _Alloc>
+template <class _Comp>
+typename list<_Tp, _Alloc>::iterator
+list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp)
+{
+    switch (__n)
+    {
+    case 0:
+    case 1:
+        return __f1;
+    case 2:
+        if (__comp(*--__e2, *__f1))
+        {
+            __node_pointer __f = __e2.__ptr_;
+            base::__unlink_nodes(__f, __f);
+            __link_nodes(__f1.__ptr_, __f, __f);
+            return __e2;
+        }
+        return __f1;
+    }
+    size_type __n2 = __n / 2;
+    iterator __e1 = _VSTD::next(__f1, __n2);
+    iterator  __r = __f1 = __sort(__f1, __e1, __n2, __comp);
+    iterator __f2 = __e1 = __sort(__e1, __e2, __n - __n2, __comp);
+    if (__comp(*__f2, *__f1))
+    {
+        iterator __m2 = _VSTD::next(__f2);
+        for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
+            ;
+        __node_pointer __f = __f2.__ptr_;
+        __node_pointer __l = __m2.__ptr_->__prev_;
+        __r = __f2;
+        __e1 = __f2 = __m2;
+        base::__unlink_nodes(__f, __l);
+        __m2 = _VSTD::next(__f1);
+        __link_nodes(__f1.__ptr_, __f, __l);
+        __f1 = __m2;
+    }
+    else
+        ++__f1;
+    while (__f1 != __e1 && __f2 != __e2)
+    {
+        if (__comp(*__f2, *__f1))
+        {
+            iterator __m2 = _VSTD::next(__f2);
+            for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
+                ;
+            __node_pointer __f = __f2.__ptr_;
+            __node_pointer __l = __m2.__ptr_->__prev_;
+            if (__e1 == __f2)
+                __e1 = __m2;
+            __f2 = __m2;
+            base::__unlink_nodes(__f, __l);
+            __m2 = _VSTD::next(__f1);
+            __link_nodes(__f1.__ptr_, __f, __l);
+            __f1 = __m2;
+        }
+        else
+            ++__f1;
+    }
+    return __r;
+}
+
+template <class _Tp, class _Alloc>
+void
+list<_Tp, _Alloc>::reverse() _NOEXCEPT
+{
+    if (base::__sz() > 1)
+    {
+        iterator __e = end();
+        for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;)
+        {
+            _VSTD::swap(__i.__ptr_->__prev_, __i.__ptr_->__next_);
+            __i.__ptr_ = __i.__ptr_->__prev_;
+        }
+        _VSTD::swap(__e.__ptr_->__prev_, __e.__ptr_->__next_);
+    }
+}
+
+template <class _Tp, class _Alloc>
+bool
+list<_Tp, _Alloc>::__invariants() const
+{
+    return size() == _VSTD::distance(begin(), end());
+}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Alloc>
+bool
+list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const
+{
+    return __i->__ptr_ != static_cast<__node_pointer>(
+                       pointer_traits<__node_base_pointer>::pointer_to(const_cast<__node_base&>(this->__end_)));
+}
+
+template <class _Tp, class _Alloc>
+bool
+list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const
+{
+    return !empty() &&  __i->__ptr_ != base::__end_.__next_;
+}
+
+template <class _Tp, class _Alloc>
+bool
+list<_Tp, _Alloc>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    return false;
+}
+
+template <class _Tp, class _Alloc>
+bool
+list<_Tp, _Alloc>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    return false;
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_LIST
diff --git a/include/c++/v1/locale b/include/c++/v1/locale
new file mode 100644
index 0000000..fcff402
--- /dev/null
+++ b/include/c++/v1/locale
@@ -0,0 +1,4465 @@
+// -*- C++ -*-
+//===-------------------------- locale ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_LOCALE
+#define _LIBCPP_LOCALE
+
+/*
+    locale synopsis
+
+namespace std
+{
+
+class locale
+{
+public:
+    // types:
+    class facet;
+    class id;
+
+    typedef int category;
+    static const category // values assigned here are for exposition only
+        none     = 0x000,
+        collate  = 0x010,
+        ctype    = 0x020,
+        monetary = 0x040,
+        numeric  = 0x080,
+        time     = 0x100,
+        messages = 0x200,
+        all = collate | ctype | monetary | numeric | time | messages;
+
+    // construct/copy/destroy:
+    locale() noexcept;
+    locale(const locale& other) noexcept;
+    explicit locale(const char* std_name);
+    explicit locale(const string& std_name);
+    locale(const locale& other, const char* std_name, category);
+    locale(const locale& other, const string& std_name, category);
+    template <class Facet> locale(const locale& other, Facet* f);
+    locale(const locale& other, const locale& one, category);
+
+    ~locale(); // not virtual
+
+    const locale& operator=(const locale& other) noexcept;
+
+    template <class Facet> locale combine(const locale& other) const;
+
+    // locale operations:
+    basic_string<char> name() const;
+    bool operator==(const locale& other) const;
+    bool operator!=(const locale& other) const;
+    template <class charT, class Traits, class Allocator>
+      bool operator()(const basic_string<charT,Traits,Allocator>& s1,
+                      const basic_string<charT,Traits,Allocator>& s2) const;
+
+    // global locale objects:
+    static locale global(const locale&);
+    static const locale& classic();
+};
+
+template <class Facet> const Facet& use_facet(const locale&);
+template <class Facet> bool has_facet(const locale&) noexcept;
+
+// 22.3.3, convenience interfaces:
+template <class charT> bool isspace (charT c, const locale& loc);
+template <class charT> bool isprint (charT c, const locale& loc);
+template <class charT> bool iscntrl (charT c, const locale& loc);
+template <class charT> bool isupper (charT c, const locale& loc);
+template <class charT> bool islower (charT c, const locale& loc);
+template <class charT> bool isalpha (charT c, const locale& loc);
+template <class charT> bool isdigit (charT c, const locale& loc);
+template <class charT> bool ispunct (charT c, const locale& loc);
+template <class charT> bool isxdigit(charT c, const locale& loc);
+template <class charT> bool isalnum (charT c, const locale& loc);
+template <class charT> bool isgraph (charT c, const locale& loc);
+template <class charT> charT toupper(charT c, const locale& loc);
+template <class charT> charT tolower(charT c, const locale& loc);
+
+template<class Codecvt, class Elem = wchar_t,
+         class Wide_alloc = allocator<Elem>,
+         class Byte_alloc = allocator<char>>
+class wstring_convert
+{
+public:
+    typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
+    typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string;
+    typedef typename Codecvt::state_type                      state_type;
+    typedef typename wide_string::traits_type::int_type       int_type;
+
+    explicit wstring_convert(Codecvt* pcvt = new Codecvt);          // explicit in C++14
+    wstring_convert(Codecvt* pcvt, state_type state);
+    explicit wstring_convert(const byte_string& byte_err,           // explicit in C++14
+                    const wide_string& wide_err = wide_string());
+    wstring_convert(const wstring_convert&) = delete;               // C++14
+    wstring_convert & operator=(const wstring_convert &) = delete;  // C++14
+    ~wstring_convert();
+
+    wide_string from_bytes(char byte);
+    wide_string from_bytes(const char* ptr);
+    wide_string from_bytes(const byte_string& str);
+    wide_string from_bytes(const char* first, const char* last);
+
+    byte_string to_bytes(Elem wchar);
+    byte_string to_bytes(const Elem* wptr);
+    byte_string to_bytes(const wide_string& wstr);
+    byte_string to_bytes(const Elem* first, const Elem* last);
+
+    size_t converted() const; // noexcept in C++14
+    state_type state() const;
+};
+
+template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
+class wbuffer_convert
+    : public basic_streambuf<Elem, Tr>
+{
+public:
+    typedef typename Tr::state_type state_type;
+
+    explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
+                    state_type state = state_type());       // explicit in C++14
+    wbuffer_convert(const wbuffer_convert&) = delete;               // C++14
+    wbuffer_convert & operator=(const wbuffer_convert &) = delete;  // C++14
+    ~wbuffer_convert();                                             // C++14
+    
+    streambuf* rdbuf() const;
+    streambuf* rdbuf(streambuf* bytebuf);
+
+    state_type state() const;
+};
+
+// 22.4.1 and 22.4.1.3, ctype:
+class ctype_base;
+template <class charT> class ctype;
+template <> class ctype<char>; // specialization
+template <class charT> class ctype_byname;
+template <> class ctype_byname<char>; // specialization
+
+class codecvt_base;
+template <class internT, class externT, class stateT> class codecvt;
+template <class internT, class externT, class stateT> class codecvt_byname;
+
+// 22.4.2 and 22.4.3, numeric:
+template <class charT, class InputIterator> class num_get;
+template <class charT, class OutputIterator> class num_put;
+template <class charT> class numpunct;
+template <class charT> class numpunct_byname;
+
+// 22.4.4, col lation:
+template <class charT> class collate;
+template <class charT> class collate_byname;
+
+// 22.4.5, date and time:
+class time_base;
+template <class charT, class InputIterator> class time_get;
+template <class charT, class InputIterator> class time_get_byname;
+template <class charT, class OutputIterator> class time_put;
+template <class charT, class OutputIterator> class time_put_byname;
+
+// 22.4.6, money:
+class money_base;
+template <class charT, class InputIterator> class money_get;
+template <class charT, class OutputIterator> class money_put;
+template <class charT, bool Intl> class moneypunct;
+template <class charT, bool Intl> class moneypunct_byname;
+
+// 22.4.7, message retrieval:
+class messages_base;
+template <class charT> class messages;
+template <class charT> class messages_byname;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__locale>
+#include <algorithm>
+#include <memory>
+#include <ios>
+#include <streambuf>
+#include <iterator>
+#include <limits>
+#ifndef __APPLE__
+#include <cstdarg>
+#endif
+#include <cstdlib>
+#include <ctime>
+#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
+#include <support/win32/locale_win32.h>
+#elif !defined(__ANDROID__)
+#include <nl_types.h>
+#endif
+
+#ifdef __APPLE__
+#include <Availability.h>
+#endif
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if defined(__APPLE__) || defined(__FreeBSD__)
+#  define _LIBCPP_GET_C_LOCALE 0
+#elif defined(__NetBSD__)
+#  define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
+#else
+#  define _LIBCPP_GET_C_LOCALE __cloc()
+   // Get the C locale object
+   _LIBCPP_FUNC_VIS locale_t __cloc();
+#define __cloc_defined
+#endif
+
+typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
+typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr;
+#ifndef _LIBCPP_LOCALE__L_EXTENSIONS
+typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
+#endif
+
+// OSX has nice foo_l() functions that let you turn off use of the global
+// locale.  Linux, not so much.  The following functions avoid the locale when
+// that's possible and otherwise do the wrong thing.  FIXME.
+#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX)
+
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
+inline _LIBCPP_INLINE_VISIBILITY
+__mb_cur_max_l(locale_t __l)
+{
+  return MB_CUR_MAX_L(__l);
+}
+#else  // _LIBCPP_LOCALE__L_EXTENSIONS
+inline _LIBCPP_ALWAYS_INLINE
+decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l)
+{
+  __locale_raii __current(uselocale(__l), uselocale);
+  return MB_CUR_MAX;
+}
+#endif // _LIBCPP_LOCALE__L_EXTENSIONS
+
+inline _LIBCPP_ALWAYS_INLINE
+wint_t __btowc_l(int __c, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return btowc_l(__c, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return btowc(__c);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+int __wctob_l(wint_t __c, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return wctob_l(__c, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return wctob(__c);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc,
+                      size_t __len, mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return wcsnrtombs(__dest, __src, __nwc, __len, __ps);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return wcrtomb_l(__s, __wc, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return wcrtomb(__s, __wc, __ps);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms,
+                      size_t __len, mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return mbsnrtowcs(__dest, __src, __nms, __len, __ps);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
+                   mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return mbrtowc_l(__pwc, __s, __n, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return mbrtowc(__pwc, __s, __n, __ps);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return mbtowc_l(__pwc, __pmb, __max, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return mbtowc(__pwc, __pmb, __max);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return mbrlen_l(__s, __n, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return mbrlen(__s, __n, __ps);
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+lconv *__localeconv_l(locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return localeconv_l(__l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return localeconv();
+#endif
+}
+
+inline _LIBCPP_ALWAYS_INLINE
+size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
+                     mbstate_t *__ps, locale_t __l)
+{
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  return mbsrtowcs_l(__dest, __src, __len, __ps, __l);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  return mbsrtowcs(__dest, __src, __len, __ps);
+#endif
+}
+
+inline
+int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  int __res = vsnprintf_l(__s, __n, __l, __format, __va);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  int __res = vsnprintf(__s, __n, __format, __va);
+#endif
+  va_end(__va);
+  return __res;
+}
+
+inline
+int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  int __res = vasprintf_l(__s, __l, __format, __va);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  int __res = vasprintf(__s, __format, __va);
+#endif
+  va_end(__va);
+  return __res;
+}
+
+inline
+int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+  int __res = vsscanf_l(__s, __l, __format, __va);
+#else
+  __locale_raii __current(uselocale(__l), uselocale);
+  int __res = vsscanf(__s, __format, __va);
+#endif
+  va_end(__va);
+  return __res;
+}
+
+#endif  // __linux__
+
+// __scan_keyword
+// Scans [__b, __e) until a match is found in the basic_strings range
+//  [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
+//  __b will be incremented (visibly), consuming CharT until a match is found
+//  or proved to not exist.  A keyword may be "", in which will match anything.
+//  If one keyword is a prefix of another, and the next CharT in the input
+//  might match another keyword, the algorithm will attempt to find the longest
+//  matching keyword.  If the longer matching keyword ends up not matching, then
+//  no keyword match is found.  If no keyword match is found, __ke is returned
+//  and failbit is set in __err.
+//  Else an iterator pointing to the matching keyword is found.  If more than
+//  one keyword matches, an iterator to the first matching keyword is returned.
+//  If on exit __b == __e, eofbit is set in __err.  If __case_sensitive is false,
+//  __ct is used to force to lower case before comparing characters.
+//  Examples:
+//  Keywords:  "a", "abb"
+//  If the input is "a", the first keyword matches and eofbit is set.
+//  If the input is "abc", no match is found and "ab" are consumed.
+template <class _InputIterator, class _ForwardIterator, class _Ctype>
+_LIBCPP_HIDDEN
+_ForwardIterator
+__scan_keyword(_InputIterator& __b, _InputIterator __e,
+               _ForwardIterator __kb, _ForwardIterator __ke,
+               const _Ctype& __ct, ios_base::iostate& __err,
+               bool __case_sensitive = true)
+{
+    typedef typename iterator_traits<_InputIterator>::value_type _CharT;
+    size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke));
+    const unsigned char __doesnt_match = '\0';
+    const unsigned char __might_match = '\1';
+    const unsigned char __does_match = '\2';
+    unsigned char __statbuf[100];
+    unsigned char* __status = __statbuf;
+    unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free);
+    if (__nkw > sizeof(__statbuf))
+    {
+        __status = (unsigned char*)malloc(__nkw);
+        if (__status == 0)
+            __throw_bad_alloc();
+        __stat_hold.reset(__status);
+    }
+    size_t __n_might_match = __nkw;  // At this point, any keyword might match
+    size_t __n_does_match = 0;       // but none of them definitely do
+    // Initialize all statuses to __might_match, except for "" keywords are __does_match
+    unsigned char* __st = __status;
+    for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+    {
+        if (!__ky->empty())
+            *__st = __might_match;
+        else
+        {
+            *__st = __does_match;
+            --__n_might_match;
+            ++__n_does_match;
+        }
+    }
+    // While there might be a match, test keywords against the next CharT
+    for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx)
+    {
+        // Peek at the next CharT but don't consume it
+        _CharT __c = *__b;
+        if (!__case_sensitive)
+            __c = __ct.toupper(__c);
+        bool __consume = false;
+        // For each keyword which might match, see if the __indx character is __c
+        // If a match if found, consume __c
+        // If a match is found, and that is the last character in the keyword,
+        //    then that keyword matches.
+        // If the keyword doesn't match this character, then change the keyword
+        //    to doesn't match
+        __st = __status;
+        for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+        {
+            if (*__st == __might_match)
+            {
+                _CharT __kc = (*__ky)[__indx];
+                if (!__case_sensitive)
+                    __kc = __ct.toupper(__kc);
+                if (__c == __kc)
+                {
+                    __consume = true;
+                    if (__ky->size() == __indx+1)
+                    {
+                        *__st = __does_match;
+                        --__n_might_match;
+                        ++__n_does_match;
+                    }
+                }
+                else
+                {
+                    *__st = __doesnt_match;
+                    --__n_might_match;
+                }
+            }
+        }
+        // consume if we matched a character
+        if (__consume)
+        {
+            ++__b;
+            // If we consumed a character and there might be a matched keyword that
+            //   was marked matched on a previous iteration, then such keywords
+            //   which are now marked as not matching.
+            if (__n_might_match + __n_does_match > 1)
+            {
+                __st = __status;
+                for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st)
+                {
+                    if (*__st == __does_match && __ky->size() != __indx+1)
+                    {
+                        *__st = __doesnt_match;
+                        --__n_does_match;
+                    }
+                }
+            }
+        }
+    }
+    // We've exited the loop because we hit eof and/or we have no more "might matches".
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    // Return the first matching result
+    for (__st = __status; __kb != __ke; ++__kb, ++__st)
+        if (*__st == __does_match)
+            break;
+    if (__kb == __ke)
+        __err |= ios_base::failbit;
+    return __kb;
+}
+
+struct _LIBCPP_TYPE_VIS __num_get_base
+{
+    static const int __num_get_buf_sz = 40;
+
+    static int __get_base(ios_base&);
+    static const char __src[33];
+};
+
+_LIBCPP_FUNC_VIS
+void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
+                      ios_base::iostate& __err);
+
+template <class _CharT>
+struct __num_get
+    : protected __num_get_base
+{
+    static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
+    static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
+                                      _CharT& __thousands_sep);
+    static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
+                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
+                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
+    static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
+                                   char* __a, char*& __a_end,
+                                   _CharT __decimal_point, _CharT __thousands_sep,
+                                   const string& __grouping, unsigned* __g,
+                                   unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
+};
+
+template <class _CharT>
+string
+__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
+{
+    locale __loc = __iob.getloc();
+    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms);
+    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+    __thousands_sep = __np.thousands_sep();
+    return __np.grouping();
+}
+
+template <class _CharT>
+string
+__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
+                    _CharT& __thousands_sep)
+{
+    locale __loc = __iob.getloc();
+    use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms);
+    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
+    __decimal_point = __np.decimal_point();
+    __thousands_sep = __np.thousands_sep();
+    return __np.grouping();
+}
+
+template <class _CharT>
+int
+__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
+                  unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
+                  unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
+{
+    if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
+    {
+        *__a_end++ = __ct == __atoms[24] ? '+' : '-';
+        __dc = 0;
+        return 0;
+    }
+    if (__grouping.size() != 0 && __ct == __thousands_sep)
+    {
+        if (__g_end-__g < __num_get_buf_sz)
+        {
+            *__g_end++ = __dc;
+            __dc = 0;
+        }
+        return 0;
+    }
+    ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms;
+    if (__f >= 24)
+        return -1;
+    switch (__base)
+    {
+    case 8:
+    case 10:
+        if (__f >= __base)
+            return -1;
+        break;
+    case 16:
+        if (__f < 22)
+            break;
+        if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0')
+        {
+            __dc = 0;
+            *__a_end++ = __src[__f];
+            return 0;
+        }
+        return -1;
+    }
+    *__a_end++ = __src[__f];
+    ++__dc;
+    return 0;
+}
+
+template <class _CharT>
+int
+__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end,
+                    _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping,
+                    unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms)
+{
+    if (__ct == __decimal_point)
+    {
+        if (!__in_units)
+            return -1;
+        __in_units = false;
+        *__a_end++ = '.';
+        if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
+            *__g_end++ = __dc;
+        return 0;
+    }
+    if (__ct == __thousands_sep && __grouping.size() != 0)
+    {
+        if (!__in_units)
+            return -1;
+        if (__g_end-__g < __num_get_buf_sz)
+        {
+            *__g_end++ = __dc;
+            __dc = 0;
+        }
+        return 0;
+    }
+    ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms;
+    if (__f >= 32)
+        return -1;
+    char __x = __src[__f];
+    if (__x == '-' || __x == '+')
+    {
+        if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F))
+        {
+            *__a_end++ = __x;
+            return 0;
+        }
+        return -1;
+    }
+    if (__x == 'x' || __x == 'X')
+        __exp = 'P';
+    else if ((__x & 0x5F) == __exp)
+    {
+        __exp |= 0x80;
+        if (__in_units)
+        {
+            __in_units = false;
+            if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz)
+                *__g_end++ = __dc;
+        }
+    }
+    *__a_end++ = __x;
+    if (__f >= 22)
+        return 0;
+    ++__dc;
+    return 0;
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
+
+template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY num_get
+    : public locale::facet,
+      private __num_get<_CharT>
+{
+public:
+    typedef _CharT char_type;
+    typedef _InputIterator iter_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit num_get(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, bool& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, long& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, long long& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, unsigned short& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, unsigned int& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, unsigned long& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, unsigned long long& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, float& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, double& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, long double& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, void*& __v) const
+    {
+        return do_get(__b, __e, __iob, __err, __v);
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~num_get() {}
+
+    template <class _Fp>
+    iter_type __do_get_floating_point
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Fp& __v) const;
+
+    template <class _Signed>
+    iter_type __do_get_signed
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Signed& __v) const;
+
+    template <class _Unsigned>
+    iter_type __do_get_unsigned
+                            (iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, _Unsigned& __v) const;
+
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, bool& __v) const;
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, long& __v) const
+    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, long long& __v) const
+    { return this->__do_get_signed ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, unsigned short& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, unsigned int& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, unsigned long& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, unsigned long long& __v) const
+    { return this->__do_get_unsigned ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, float& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, double& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, long double& __v) const
+    { return this->__do_get_floating_point ( __b, __e, __iob, __err, __v ); }
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, void*& __v) const;
+};
+
+template <class _CharT, class _InputIterator>
+locale::id
+num_get<_CharT, _InputIterator>::id;
+
+template <class _Tp>
+_Tp
+__num_get_signed_integral(const char* __a, const char* __a_end,
+                          ios_base::iostate& __err, int __base)
+{
+    if (__a != __a_end)
+    {
+        typename remove_reference<decltype(errno)>::type __save_errno = errno;
+        errno = 0;
+        char *__p2;
+        long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
+        typename remove_reference<decltype(errno)>::type __current_errno = errno;
+        if (__current_errno == 0)
+            errno = __save_errno;
+        if (__p2 != __a_end)
+        {
+            __err = ios_base::failbit;
+            return 0;
+        }
+        else if (__current_errno == ERANGE         ||
+                 __ll < numeric_limits<_Tp>::min() ||
+                 numeric_limits<_Tp>::max() < __ll)
+        {
+            __err = ios_base::failbit;
+            if (__ll > 0)
+                return numeric_limits<_Tp>::max();
+            else
+                return numeric_limits<_Tp>::min();
+        }
+        return static_cast<_Tp>(__ll);
+    }
+    __err = ios_base::failbit;
+    return 0;
+}
+
+template <class _Tp>
+_Tp
+__num_get_unsigned_integral(const char* __a, const char* __a_end,
+                            ios_base::iostate& __err, int __base)
+{
+    if (__a != __a_end)
+    {
+        if (*__a == '-')
+        {
+            __err = ios_base::failbit;
+            return 0;
+        }
+        typename remove_reference<decltype(errno)>::type __save_errno = errno;
+        errno = 0;
+        char *__p2;
+        unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
+        typename remove_reference<decltype(errno)>::type __current_errno = errno;
+        if (__current_errno == 0)
+            errno = __save_errno;
+        if (__p2 != __a_end)
+        {
+            __err = ios_base::failbit;
+            return 0;
+        }
+        else if (__current_errno == ERANGE ||
+                 numeric_limits<_Tp>::max() < __ll)
+        {
+            __err = ios_base::failbit;
+            return numeric_limits<_Tp>::max();
+        }
+        return static_cast<_Tp>(__ll);
+    }
+    __err = ios_base::failbit;
+    return 0;
+}
+
+template <class _Tp>
+_Tp
+__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err)
+{
+    if (__a != __a_end)
+    {
+        typename remove_reference<decltype(errno)>::type __save_errno = errno;
+        errno = 0;
+        char *__p2;
+        long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE);
+        typename remove_reference<decltype(errno)>::type __current_errno = errno;
+        if (__current_errno == 0)
+            errno = __save_errno;
+        if (__p2 != __a_end)
+        {
+            __err = ios_base::failbit;
+            return 0;
+        }
+        else if (__current_errno == ERANGE)
+            __err = ios_base::failbit;
+        return static_cast<_Tp>(__ld);
+    }
+    __err = ios_base::failbit;
+    return 0;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+                                        ios_base& __iob,
+                                        ios_base::iostate& __err,
+                                        bool& __v) const
+{
+    if ((__iob.flags() & ios_base::boolalpha) == 0)
+    {
+        long __lv = -1;
+        __b = do_get(__b, __e, __iob, __err, __lv);
+        switch (__lv)
+        {
+        case 0:
+            __v = false;
+            break;
+        case 1:
+            __v = true;
+            break;
+        default:
+            __v = true;
+            __err = ios_base::failbit;
+            break;
+        }
+        return __b;
+    }
+    const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc());
+    const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc());
+    typedef typename numpunct<_CharT>::string_type string_type;
+    const string_type __names[2] = {__np.truename(), __np.falsename()};
+    const string_type* __i = __scan_keyword(__b, __e, __names, __names+2,
+                                            __ct, __err);
+    __v = __i == __names;
+    return __b;
+}
+
+// signed
+
+template <class _CharT, class _InputIterator>
+template <class _Signed>
+_InputIterator
+num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
+                                        ios_base& __iob,
+                                        ios_base::iostate& __err,
+                                        _Signed& __v) const
+{
+    // Stage 1
+    int __base = this->__get_base(__iob);
+    // Stage 2
+    char_type __atoms[26];
+    char_type __thousands_sep;
+    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc = 0;
+    for (; __b != __e; ++__b)
+    {
+        if (__a_end == __a + __buf.size())
+        {
+            size_t __tmp = __buf.size();
+            __buf.resize(2*__buf.size());
+            __buf.resize(__buf.capacity());
+            __a = &__buf[0];
+            __a_end = __a + __tmp;
+        }
+        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
+                                    __thousands_sep, __grouping, __g, __g_end,
+                                    __atoms))
+            break;
+    }
+    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
+        *__g_end++ = __dc;
+    // Stage 3
+    __v = __num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+// unsigned
+
+template <class _CharT, class _InputIterator>
+template <class _Unsigned>
+_InputIterator
+num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
+                                        ios_base& __iob,
+                                        ios_base::iostate& __err,
+                                        _Unsigned& __v) const
+{
+    // Stage 1
+    int __base = this->__get_base(__iob);
+    // Stage 2
+    char_type __atoms[26];
+    char_type __thousands_sep;
+    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc = 0;
+    for (; __b != __e; ++__b)
+    {
+        if (__a_end == __a + __buf.size())
+        {
+            size_t __tmp = __buf.size();
+            __buf.resize(2*__buf.size());
+            __buf.resize(__buf.capacity());
+            __a = &__buf[0];
+            __a_end = __a + __tmp;
+        }
+        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
+                                    __thousands_sep, __grouping, __g, __g_end,
+                                    __atoms))
+            break;
+    }
+    if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz)
+        *__g_end++ = __dc;
+    // Stage 3
+    __v = __num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+// floating point
+
+template <class _CharT, class _InputIterator>
+template <class _Fp>
+_InputIterator
+num_get<_CharT, _InputIterator>::__do_get_floating_point(iter_type __b, iter_type __e,
+                                        ios_base& __iob,
+                                        ios_base::iostate& __err,
+                                        _Fp& __v) const
+{
+    // Stage 1, nothing to do
+    // Stage 2
+    char_type __atoms[32];
+    char_type __decimal_point;
+    char_type __thousands_sep;
+    string __grouping = this->__stage2_float_prep(__iob, __atoms,
+                                                  __decimal_point,
+                                                  __thousands_sep);
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc = 0;
+    bool __in_units = true;
+    char __exp = 'E';
+    for (; __b != __e; ++__b)
+    {
+        if (__a_end == __a + __buf.size())
+        {
+            size_t __tmp = __buf.size();
+            __buf.resize(2*__buf.size());
+            __buf.resize(__buf.capacity());
+            __a = &__buf[0];
+            __a_end = __a + __tmp;
+        }
+        if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end,
+                                      __decimal_point, __thousands_sep,
+                                      __grouping, __g, __g_end,
+                                      __dc, __atoms))
+            break;
+    }
+    if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz)
+        *__g_end++ = __dc;
+    // Stage 3
+    __v = __num_get_float<_Fp>(__a, __a_end, __err);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+                                        ios_base& __iob,
+                                        ios_base::iostate& __err,
+                                        void*& __v) const
+{
+    // Stage 1
+    int __base = 16;
+    // Stage 2
+    char_type __atoms[26];
+    char_type __thousands_sep = 0;
+    string __grouping;
+    use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src,
+                                                    __num_get_base::__src + 26, __atoms);
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc = 0;
+    for (; __b != __e; ++__b)
+    {
+        if (__a_end == __a + __buf.size())
+        {
+            size_t __tmp = __buf.size();
+            __buf.resize(2*__buf.size());
+            __buf.resize(__buf.capacity());
+            __a = &__buf[0];
+            __a_end = __a + __tmp;
+        }
+        if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc,
+                                    __thousands_sep, __grouping,
+                                    __g, __g_end, __atoms))
+            break;
+    }
+    // Stage 3
+    __buf.resize(__a_end - __a);
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
+#else
+    if (__sscanf_l(__buf.c_str(), __cloc(), "%p", &__v) != 1)
+#endif
+        __err = ios_base::failbit;
+    // EOF checked
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
+
+struct _LIBCPP_TYPE_VIS __num_put_base
+{
+protected:
+    static void __format_int(char* __fmt, const char* __len, bool __signd,
+                             ios_base::fmtflags __flags);
+    static bool __format_float(char* __fmt, const char* __len,
+                               ios_base::fmtflags __flags);
+    static char* __identify_padding(char* __nb, char* __ne,
+                                    const ios_base& __iob);
+};
+
+template <class _CharT>
+struct __num_put
+    : protected __num_put_base
+{
+    static void __widen_and_group_int(char* __nb, char* __np, char* __ne,
+                                      _CharT* __ob, _CharT*& __op, _CharT*& __oe,
+                                      const locale& __loc);
+    static void __widen_and_group_float(char* __nb, char* __np, char* __ne,
+                                        _CharT* __ob, _CharT*& __op, _CharT*& __oe,
+                                        const locale& __loc);
+};
+
+template <class _CharT>
+void
+__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne,
+                                         _CharT* __ob, _CharT*& __op, _CharT*& __oe,
+                                         const locale& __loc)
+{
+    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
+    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
+    string __grouping = __npt.grouping();
+    if (__grouping.empty())
+    {
+        __ct.widen(__nb, __ne, __ob);
+        __oe = __ob + (__ne - __nb);
+    }
+    else
+    {
+        __oe = __ob;
+        char* __nf = __nb;
+        if (*__nf == '-' || *__nf == '+')
+            *__oe++ = __ct.widen(*__nf++);
+        if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
+                                                   __nf[1] == 'X'))
+        {
+            *__oe++ = __ct.widen(*__nf++);
+            *__oe++ = __ct.widen(*__nf++);
+        }
+        reverse(__nf, __ne);
+        _CharT __thousands_sep = __npt.thousands_sep();
+        unsigned __dc = 0;
+        unsigned __dg = 0;
+        for (char* __p = __nf; __p < __ne; ++__p)
+        {
+            if (static_cast<unsigned>(__grouping[__dg]) > 0 &&
+                __dc == static_cast<unsigned>(__grouping[__dg]))
+            {
+                *__oe++ = __thousands_sep;
+                __dc = 0;
+                if (__dg < __grouping.size()-1)
+                    ++__dg;
+            }
+            *__oe++ = __ct.widen(*__p);
+            ++__dc;
+        }
+        reverse(__ob + (__nf - __nb), __oe);
+    }
+    if (__np == __ne)
+        __op = __oe;
+    else
+        __op = __ob + (__np - __nb);
+}
+
+template <class _CharT>
+void
+__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne,
+                                           _CharT* __ob, _CharT*& __op, _CharT*& __oe,
+                                           const locale& __loc)
+{
+    const ctype<_CharT>&    __ct = use_facet<ctype<_CharT> >   (__loc);
+    const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc);
+    string __grouping = __npt.grouping();
+    __oe = __ob;
+    char* __nf = __nb;
+    if (*__nf == '-' || *__nf == '+')
+        *__oe++ = __ct.widen(*__nf++);
+    char* __ns;
+    if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' ||
+                                               __nf[1] == 'X'))
+    {
+        *__oe++ = __ct.widen(*__nf++);
+        *__oe++ = __ct.widen(*__nf++);
+        for (__ns = __nf; __ns < __ne; ++__ns)
+            if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
+                break;
+    }
+    else
+    {
+        for (__ns = __nf; __ns < __ne; ++__ns)
+            if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE))
+                break;
+    }
+    if (__grouping.empty())
+    {
+        __ct.widen(__nf, __ns, __oe);
+        __oe += __ns - __nf;
+    }
+    else
+    {
+        reverse(__nf, __ns);
+        _CharT __thousands_sep = __npt.thousands_sep();
+        unsigned __dc = 0;
+        unsigned __dg = 0;
+        for (char* __p = __nf; __p < __ns; ++__p)
+        {
+            if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg]))
+            {
+                *__oe++ = __thousands_sep;
+                __dc = 0;
+                if (__dg < __grouping.size()-1)
+                    ++__dg;
+            }
+            *__oe++ = __ct.widen(*__p);
+            ++__dc;
+        }
+        reverse(__ob + (__nf - __nb), __oe);
+    }
+    for (__nf = __ns; __nf < __ne; ++__nf)
+    {
+        if (*__nf == '.')
+        {
+            *__oe++ = __npt.decimal_point();
+            ++__nf;
+            break;
+        }
+        else
+            *__oe++ = __ct.widen(*__nf);
+    }
+    __ct.widen(__nf, __ne, __oe);
+    __oe += __ne - __nf;
+    if (__np == __ne)
+        __op = __oe;
+    else
+        __op = __ob + (__np - __nb);
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
+
+template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY num_put
+    : public locale::facet,
+      private __num_put<_CharT>
+{
+public:
+    typedef _CharT char_type;
+    typedef _OutputIterator iter_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit num_put(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  bool __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  long __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  long long __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  unsigned long __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  unsigned long long __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  double __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  long double __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  const void* __v) const
+    {
+        return do_put(__s, __iob, __fl, __v);
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~num_put() {}
+
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             bool __v) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             long __v) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             long long __v) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             unsigned long) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             unsigned long long) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             double __v) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             long double __v) const;
+    virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl,
+                             const void* __v) const;
+};
+
+template <class _CharT, class _OutputIterator>
+locale::id
+num_put<_CharT, _OutputIterator>::id;
+
+template <class _CharT, class _OutputIterator>
+_LIBCPP_HIDDEN
+_OutputIterator
+__pad_and_output(_OutputIterator __s,
+                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
+                 ios_base& __iob, _CharT __fl)
+{
+    streamsize __sz = __oe - __ob;
+    streamsize __ns = __iob.width();
+    if (__ns > __sz)
+        __ns -= __sz;
+    else
+        __ns = 0;
+    for (;__ob < __op; ++__ob, ++__s)
+        *__s = *__ob;
+    for (; __ns; --__ns, ++__s)
+        *__s = __fl;
+    for (; __ob < __oe; ++__ob, ++__s)
+        *__s = *__ob;
+    __iob.width(0);
+    return __s;
+}
+
+#if !defined(__APPLE__) || \
+    (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
+    (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDDEN
+ostreambuf_iterator<_CharT, _Traits>
+__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
+                 const _CharT* __ob, const _CharT* __op, const _CharT* __oe,
+                 ios_base& __iob, _CharT __fl)
+{
+    if (__s.__sbuf_ == nullptr)
+        return __s;
+    streamsize __sz = __oe - __ob;
+    streamsize __ns = __iob.width();
+    if (__ns > __sz)
+        __ns -= __sz;
+    else
+        __ns = 0;
+    streamsize __np = __op - __ob;
+    if (__np > 0)
+    {
+        if (__s.__sbuf_->sputn(__ob, __np) != __np)
+        {
+            __s.__sbuf_ = nullptr;
+            return __s;
+        }
+    }
+    if (__ns > 0)
+    {
+        basic_string<_CharT, _Traits> __sp(__ns, __fl);
+        if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns)
+        {
+            __s.__sbuf_ = nullptr;
+            return __s;
+        }
+    }
+    __np = __oe - __op;
+    if (__np > 0)
+    {
+        if (__s.__sbuf_->sputn(__op, __np) != __np)
+        {
+            __s.__sbuf_ = nullptr;
+            return __s;
+        }
+    }
+    __iob.width(0);
+    return __s;
+}
+
+#endif
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, bool __v) const
+{
+    if ((__iob.flags() & ios_base::boolalpha) == 0)
+        return do_put(__s, __iob, __fl, (unsigned long)__v);
+    const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
+    typedef typename numpunct<char_type>::string_type string_type;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    string_type __tmp(__v ? __np.truename() : __np.falsename());
+    string_type __nm = _VSTD::move(__tmp);
+#else
+    string_type __nm = __v ? __np.truename() : __np.falsename();
+#endif
+    for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
+        *__s = *__i;
+    return __s;
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, long __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[6] = {'%', 0};
+    const char* __len = "l";
+    this->__format_int(__fmt+1, __len, true, __iob.flags());
+    const unsigned __nbuf = (numeric_limits<long>::digits / 3)
+                          + ((numeric_limits<long>::digits % 3) != 0)
+                          + 1;
+    char __nar[__nbuf];
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+#endif
+    char* __ne = __nar + __nc;
+    char* __np = this->__identify_padding(__nar, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, long long __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[8] = {'%', 0};
+    const char* __len = "ll";
+    this->__format_int(__fmt+1, __len, true, __iob.flags());
+    const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
+                          + ((numeric_limits<long long>::digits % 3) != 0)
+                          + 1;
+    char __nar[__nbuf];
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+#endif
+    char* __ne = __nar + __nc;
+    char* __np = this->__identify_padding(__nar, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, unsigned long __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[6] = {'%', 0};
+    const char* __len = "l";
+    this->__format_int(__fmt+1, __len, false, __iob.flags());
+    const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
+                          + ((numeric_limits<unsigned long>::digits % 3) != 0)
+                          + 1;
+    char __nar[__nbuf];
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+#endif
+    char* __ne = __nar + __nc;
+    char* __np = this->__identify_padding(__nar, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, unsigned long long __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[8] = {'%', 0};
+    const char* __len = "ll";
+    this->__format_int(__fmt+1, __len, false, __iob.flags());
+    const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
+                          + ((numeric_limits<unsigned long long>::digits % 3) != 0)
+                          + 1;
+    char __nar[__nbuf];
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+#endif
+    char* __ne = __nar + __nc;
+    char* __np = this->__identify_padding(__nar, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, double __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[8] = {'%', 0};
+    const char* __len = "";
+    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
+    const unsigned __nbuf = 30;
+    char __nar[__nbuf];
+    char* __nb = __nar;
+    int __nc;
+    if (__specify_precision)
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
+                                   (int)__iob.precision(), __v);
+#else
+        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
+                            (int)__iob.precision(), __v);
+#endif
+    else
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
+#endif
+    unique_ptr<char, void(*)(void*)> __nbh(0, free);
+    if (__nc > static_cast<int>(__nbuf-1))
+    {
+        if (__specify_precision)
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
+#else
+            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
+                              (int)__iob.precision(), __v);
+#endif
+        else
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+            __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
+#endif
+        if (__nb == 0)
+            __throw_bad_alloc();
+        __nbh.reset(__nb);
+    }
+    char* __ne = __nb + __nc;
+    char* __np = this->__identify_padding(__nb, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __ob = __o;
+    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
+    if (__nb != __nar)
+    {
+        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
+        if (__ob == 0)
+            __throw_bad_alloc();
+        __obh.reset(__ob);
+    }
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
+    return __s;
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, long double __v) const
+{
+    // Stage 1 - Get number in narrow char
+    char __fmt[8] = {'%', 0};
+    const char* __len = "L";
+    bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags());
+    const unsigned __nbuf = 30;
+    char __nar[__nbuf];
+    char* __nb = __nar;
+    int __nc;
+    if (__specify_precision)
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
+                                   (int)__iob.precision(), __v);
+#else
+        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
+                            (int)__iob.precision(), __v);
+#endif
+    else
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+        __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+        __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
+#endif
+    unique_ptr<char, void(*)(void*)> __nbh(0, free);
+    if (__nc > static_cast<int>(__nbuf-1))
+    {
+        if (__specify_precision)
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
+#else
+            __nc = __asprintf_l(&__nb, __cloc(), __fmt,
+                              (int)__iob.precision(), __v);
+#endif
+        else
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+            __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+            __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
+#endif
+        if (__nb == 0)
+            __throw_bad_alloc();
+        __nbh.reset(__nb);
+    }
+    char* __ne = __nb + __nc;
+    char* __np = this->__identify_padding(__nb, __ne, __iob);
+    // Stage 2 - Widen __nar while adding thousands separators
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __ob = __o;
+    unique_ptr<char_type, void(*)(void*)> __obh(0, free);
+    if (__nb != __nar)
+    {
+        __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type));
+        if (__ob == 0)
+            __throw_bad_alloc();
+        __obh.reset(__ob);
+    }
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc());
+    // [__o, __oe) contains thousands_sep'd wide number
+    // Stage 3 & 4
+    __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl);
+    return __s;
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
+                                         char_type __fl, const void* __v) const
+{
+    // Stage 1 - Get pointer in narrow char
+    char __fmt[6] = "%p";
+    const unsigned __nbuf = 20;
+    char __nar[__nbuf];
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+    int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
+#else
+    int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+#endif
+    char* __ne = __nar + __nc;
+    char* __np = this->__identify_padding(__nar, __ne, __iob);
+    // Stage 2 - Widen __nar
+    char_type __o[2*(__nbuf-1) - 1];
+    char_type* __op;  // pad here
+    char_type* __oe;  // end of output
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    __ct.widen(__nar, __ne, __o);
+    __oe = __o + (__ne - __nar);
+    if (__np == __ne)
+        __op = __oe;
+    else
+        __op = __o + (__np - __nar);
+    // [__o, __oe) contains wide number
+    // Stage 3 & 4
+    return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
+
+template <class _CharT, class _InputIterator>
+_LIBCPP_HIDDEN
+int
+__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e,
+                     ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n)
+{
+    // Precondition:  __n >= 1
+    if (__b == __e)
+    {
+        __err |= ios_base::eofbit | ios_base::failbit;
+        return 0;
+    }
+    // get first digit
+    _CharT __c = *__b;
+    if (!__ct.is(ctype_base::digit, __c))
+    {
+        __err |= ios_base::failbit;
+        return 0;
+    }
+    int __r = __ct.narrow(__c, 0) - '0';
+    for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n)
+    {
+        // get next digit
+        __c = *__b;
+        if (!__ct.is(ctype_base::digit, __c))
+            return __r;
+        __r = __r * 10 + __ct.narrow(__c, 0) - '0';
+    }
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __r;
+}
+
+class _LIBCPP_TYPE_VIS time_base
+{
+public:
+    enum dateorder {no_order, dmy, mdy, ymd, ydm};
+};
+
+template <class _CharT>
+class _LIBCPP_TYPE_VIS_ONLY __time_get_c_storage
+{
+protected:
+    typedef basic_string<_CharT> string_type;
+
+    virtual const string_type* __weeks() const;
+    virtual const string_type* __months() const;
+    virtual const string_type* __am_pm() const;
+    virtual const string_type& __c() const;
+    virtual const string_type& __r() const;
+    virtual const string_type& __x() const;
+    virtual const string_type& __X() const;
+};
+
+template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY time_get
+    : public locale::facet,
+      public time_base,
+      private __time_get_c_storage<_CharT>
+{
+public:
+    typedef _CharT                  char_type;
+    typedef _InputIterator          iter_type;
+    typedef time_base::dateorder    dateorder;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_get(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    dateorder date_order() const
+    {
+        return this->do_date_order();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob,
+                       ios_base::iostate& __err, tm* __tm) const
+    {
+        return do_get_time(__b, __e, __iob, __err, __tm);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob,
+                       ios_base::iostate& __err, tm* __tm) const
+    {
+        return do_get_date(__b, __e, __iob, __err, __tm);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
+                          ios_base::iostate& __err, tm* __tm) const
+    {
+        return do_get_weekday(__b, __e, __iob, __err, __tm);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
+                            ios_base::iostate& __err, tm* __tm) const
+    {
+        return do_get_monthname(__b, __e, __iob, __err, __tm);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob,
+                       ios_base::iostate& __err, tm* __tm) const
+    {
+        return do_get_year(__b, __e, __iob, __err, __tm);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, tm *__tm,
+                  char __fmt, char __mod = 0) const
+    {
+        return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod);
+    }
+
+    iter_type get(iter_type __b, iter_type __e, ios_base& __iob,
+                  ios_base::iostate& __err, tm* __tm,
+                  const char_type* __fmtb, const char_type* __fmte) const;
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~time_get() {}
+
+    virtual dateorder do_date_order() const;
+    virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob,
+                                  ios_base::iostate& __err, tm* __tm) const;
+    virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob,
+                                  ios_base::iostate& __err, tm* __tm) const;
+    virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob,
+                                     ios_base::iostate& __err, tm* __tm) const;
+    virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob,
+                                       ios_base::iostate& __err, tm* __tm) const;
+    virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob,
+                                  ios_base::iostate& __err, tm* __tm) const;
+    virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob,
+                             ios_base::iostate& __err, tm* __tm,
+                             char __fmt, char __mod) const;
+private:
+    void __get_white_space(iter_type& __b, iter_type __e,
+                           ios_base::iostate& __err, const ctype<char_type>& __ct) const;
+    void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err,
+                       const ctype<char_type>& __ct) const;
+
+    void __get_weekdayname(int& __m,
+                           iter_type& __b, iter_type __e,
+                           ios_base::iostate& __err,
+                           const ctype<char_type>& __ct) const;
+    void __get_monthname(int& __m,
+                         iter_type& __b, iter_type __e,
+                         ios_base::iostate& __err,
+                         const ctype<char_type>& __ct) const;
+    void __get_day(int& __d,
+                   iter_type& __b, iter_type __e,
+                   ios_base::iostate& __err,
+                   const ctype<char_type>& __ct) const;
+    void __get_month(int& __m,
+                     iter_type& __b, iter_type __e,
+                     ios_base::iostate& __err,
+                     const ctype<char_type>& __ct) const;
+    void __get_year(int& __y,
+                   iter_type& __b, iter_type __e,
+                   ios_base::iostate& __err,
+                   const ctype<char_type>& __ct) const;
+    void __get_year4(int& __y,
+                    iter_type& __b, iter_type __e,
+                    ios_base::iostate& __err,
+                    const ctype<char_type>& __ct) const;
+    void __get_hour(int& __d,
+                    iter_type& __b, iter_type __e,
+                    ios_base::iostate& __err,
+                    const ctype<char_type>& __ct) const;
+    void __get_12_hour(int& __h,
+                       iter_type& __b, iter_type __e,
+                       ios_base::iostate& __err,
+                       const ctype<char_type>& __ct) const;
+    void __get_am_pm(int& __h,
+                     iter_type& __b, iter_type __e,
+                     ios_base::iostate& __err,
+                     const ctype<char_type>& __ct) const;
+    void __get_minute(int& __m,
+                      iter_type& __b, iter_type __e,
+                      ios_base::iostate& __err,
+                      const ctype<char_type>& __ct) const;
+    void __get_second(int& __s,
+                      iter_type& __b, iter_type __e,
+                      ios_base::iostate& __err,
+                      const ctype<char_type>& __ct) const;
+    void __get_weekday(int& __w,
+                       iter_type& __b, iter_type __e,
+                       ios_base::iostate& __err,
+                       const ctype<char_type>& __ct) const;
+    void __get_day_year_num(int& __w,
+                            iter_type& __b, iter_type __e,
+                            ios_base::iostate& __err,
+                            const ctype<char_type>& __ct) const;
+};
+
+template <class _CharT, class _InputIterator>
+locale::id
+time_get<_CharT, _InputIterator>::id;
+
+// time_get primitives
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w,
+                                                    iter_type& __b, iter_type __e,
+                                                    ios_base::iostate& __err,
+                                                    const ctype<char_type>& __ct) const
+{
+    // Note:  ignoring case comes from the POSIX strptime spec
+    const string_type* __wk = this->__weeks();
+    ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk;
+    if (__i < 14)
+        __w = __i % 7;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_monthname(int& __m,
+                                                  iter_type& __b, iter_type __e,
+                                                  ios_base::iostate& __err,
+                                                  const ctype<char_type>& __ct) const
+{
+    // Note:  ignoring case comes from the POSIX strptime spec
+    const string_type* __month = this->__months();
+    ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month;
+    if (__i < 24)
+        __m = __i % 12;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_day(int& __d,
+                                            iter_type& __b, iter_type __e,
+                                            ios_base::iostate& __err,
+                                            const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31)
+        __d = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_month(int& __m,
+                                              iter_type& __b, iter_type __e,
+                                              ios_base::iostate& __err,
+                                              const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1;
+    if (!(__err & ios_base::failbit) && __t <= 11)
+        __m = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_year(int& __y,
+                                             iter_type& __b, iter_type __e,
+                                             ios_base::iostate& __err,
+                                             const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
+    if (!(__err & ios_base::failbit))
+    {
+        if (__t < 69)
+            __t += 2000;
+        else if (69 <= __t && __t <= 99)
+            __t += 1900;
+        __y = __t - 1900;
+    }
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_year4(int& __y,
+                                              iter_type& __b, iter_type __e,
+                                              ios_base::iostate& __err,
+                                              const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4);
+    if (!(__err & ios_base::failbit))
+        __y = __t - 1900;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_hour(int& __h,
+                                             iter_type& __b, iter_type __e,
+                                             ios_base::iostate& __err,
+                                             const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+    if (!(__err & ios_base::failbit) && __t <= 23)
+        __h = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_12_hour(int& __h,
+                                                iter_type& __b, iter_type __e,
+                                                ios_base::iostate& __err,
+                                                const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+    if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12)
+        __h = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_minute(int& __m,
+                                               iter_type& __b, iter_type __e,
+                                               ios_base::iostate& __err,
+                                               const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+    if (!(__err & ios_base::failbit) && __t <= 59)
+        __m = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_second(int& __s,
+                                               iter_type& __b, iter_type __e,
+                                               ios_base::iostate& __err,
+                                               const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2);
+    if (!(__err & ios_base::failbit) && __t <= 60)
+        __s = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_weekday(int& __w,
+                                                iter_type& __b, iter_type __e,
+                                                ios_base::iostate& __err,
+                                                const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1);
+    if (!(__err & ios_base::failbit) && __t <= 6)
+        __w = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d,
+                                                     iter_type& __b, iter_type __e,
+                                                     ios_base::iostate& __err,
+                                                     const ctype<char_type>& __ct) const
+{
+    int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3);
+    if (!(__err & ios_base::failbit) && __t <= 365)
+        __d = __t;
+    else
+        __err |= ios_base::failbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e,
+                                                    ios_base::iostate& __err,
+                                                    const ctype<char_type>& __ct) const
+{
+    for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b)
+        ;
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_am_pm(int& __h,
+                                              iter_type& __b, iter_type __e,
+                                              ios_base::iostate& __err,
+                                              const ctype<char_type>& __ct) const
+{
+    const string_type* __ap = this->__am_pm();
+    if (__ap[0].size() + __ap[1].size() == 0)
+    {
+        __err |= ios_base::failbit;
+        return;
+    }
+    ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap;
+    if (__i == 0 && __h == 12)
+        __h = 0;
+    else if (__i == 1 && __h < 12)
+        __h += 12;
+}
+
+template <class _CharT, class _InputIterator>
+void
+time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e,
+                                                ios_base::iostate& __err,
+                                                const ctype<char_type>& __ct) const
+{
+    if (__b == __e)
+    {
+        __err |= ios_base::eofbit | ios_base::failbit;
+        return;
+    }
+    if (__ct.narrow(*__b, 0) != '%')
+        __err |= ios_base::failbit;
+    else if(++__b == __e)
+        __err |= ios_base::eofbit;
+}
+
+// time_get end primitives
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e,
+                                      ios_base& __iob,
+                                      ios_base::iostate& __err, tm* __tm,
+                                      const char_type* __fmtb, const char_type* __fmte) const
+{
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    __err = ios_base::goodbit;
+    while (__fmtb != __fmte && __err == ios_base::goodbit)
+    {
+        if (__b == __e)
+        {
+            __err = ios_base::failbit;
+            break;
+        }
+        if (__ct.narrow(*__fmtb, 0) == '%')
+        {
+            if (++__fmtb == __fmte)
+            {
+                __err = ios_base::failbit;
+                break;
+            }
+            char __cmd = __ct.narrow(*__fmtb, 0);
+            char __opt = '\0';
+            if (__cmd == 'E' || __cmd == '0')
+            {
+                if (++__fmtb == __fmte)
+                {
+                    __err = ios_base::failbit;
+                    break;
+                }
+                __opt = __cmd;
+                __cmd = __ct.narrow(*__fmtb, 0);
+            }
+            __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt);
+            ++__fmtb;
+        }
+        else if (__ct.is(ctype_base::space, *__fmtb))
+        {
+            for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb)
+                ;
+            for (        ;    __b != __e    && __ct.is(ctype_base::space, *__b);    ++__b)
+                ;
+        }
+        else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb))
+        {
+            ++__b;
+            ++__fmtb;
+        }
+        else
+            __err = ios_base::failbit;
+    }
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+typename time_get<_CharT, _InputIterator>::dateorder
+time_get<_CharT, _InputIterator>::do_date_order() const
+{
+    return mdy;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e,
+                                              ios_base& __iob,
+                                              ios_base::iostate& __err,
+                                              tm* __tm) const
+{
+    const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
+    return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0]));
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e,
+                                              ios_base& __iob,
+                                              ios_base::iostate& __err,
+                                              tm* __tm) const
+{
+    const string_type& __fmt = this->__x();
+    return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size());
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e,
+                                                 ios_base& __iob,
+                                                 ios_base::iostate& __err,
+                                                 tm* __tm) const
+{
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e,
+                                                   ios_base& __iob,
+                                                   ios_base::iostate& __err,
+                                                   tm* __tm) const
+{
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e,
+                                              ios_base& __iob,
+                                              ios_base::iostate& __err,
+                                              tm* __tm) const
+{
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    __get_year(__tm->tm_year, __b, __e, __err, __ct);
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+                                         ios_base& __iob,
+                                         ios_base::iostate& __err, tm* __tm,
+                                         char __fmt, char) const
+{
+    __err = ios_base::goodbit;
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    switch (__fmt)
+    {
+    case 'a':
+    case 'A':
+        __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct);
+        break;
+    case 'b':
+    case 'B':
+    case 'h':
+        __get_monthname(__tm->tm_mon, __b, __e, __err, __ct);
+        break;
+    case 'c':
+        {
+        const string_type& __fm = this->__c();
+        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
+        }
+        break;
+    case 'd':
+    case 'e':
+        __get_day(__tm->tm_mday, __b, __e, __err, __ct);
+        break;
+    case 'D':
+        {
+        const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
+        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
+        }
+        break;
+    case 'F':
+        {
+        const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
+        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
+        }
+        break;
+    case 'H':
+        __get_hour(__tm->tm_hour, __b, __e, __err, __ct);
+        break;
+    case 'I':
+        __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct);
+        break;
+    case 'j':
+        __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct);
+        break;
+    case 'm':
+        __get_month(__tm->tm_mon, __b, __e, __err, __ct);
+        break;
+    case 'M':
+        __get_minute(__tm->tm_min, __b, __e, __err, __ct);
+        break;
+    case 'n':
+    case 't':
+        __get_white_space(__b, __e, __err, __ct);
+        break;
+    case 'p':
+        __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct);
+        break;
+    case 'r':
+        {
+        const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
+        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
+        }
+        break;
+    case 'R':
+        {
+        const char_type __fm[] = {'%', 'H', ':', '%', 'M'};
+        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
+        }
+        break;
+    case 'S':
+        __get_second(__tm->tm_sec, __b, __e, __err, __ct);
+        break;
+    case 'T':
+        {
+        const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
+        __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0]));
+        }
+        break;
+    case 'w':
+        __get_weekday(__tm->tm_wday, __b, __e, __err, __ct);
+        break;
+    case 'x':
+        return do_get_date(__b, __e, __iob, __err, __tm);
+    case 'X':
+        {
+        const string_type& __fm = this->__X();
+        __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size());
+        }
+        break;
+    case 'y':
+        __get_year(__tm->tm_year, __b, __e, __err, __ct);
+        break;
+    case 'Y':
+        __get_year4(__tm->tm_year, __b, __e, __err, __ct);
+        break;
+    case '%':
+        __get_percent(__b, __e, __err, __ct);
+        break;
+    default:
+        __err |= ios_base::failbit;
+    }
+    return __b;
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
+
+class _LIBCPP_TYPE_VIS __time_get
+{
+protected:
+    locale_t __loc_;
+
+    __time_get(const char* __nm);
+    __time_get(const string& __nm);
+    ~__time_get();
+};
+
+template <class _CharT>
+class _LIBCPP_TYPE_VIS_ONLY __time_get_storage
+    : public __time_get
+{
+protected:
+    typedef basic_string<_CharT> string_type;
+
+    string_type __weeks_[14];
+    string_type __months_[24];
+    string_type __am_pm_[2];
+    string_type __c_;
+    string_type __r_;
+    string_type __x_;
+    string_type __X_;
+
+    explicit __time_get_storage(const char* __nm);
+    explicit __time_get_storage(const string& __nm);
+
+    _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {}
+
+    time_base::dateorder __do_date_order() const;
+
+private:
+    void init(const ctype<_CharT>&);
+    string_type __analyze(char __fmt, const ctype<_CharT>&);
+};
+
+template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY time_get_byname
+    : public time_get<_CharT, _InputIterator>,
+      private __time_get_storage<_CharT>
+{
+public:
+    typedef time_base::dateorder    dateorder;
+    typedef _InputIterator          iter_type;
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit time_get_byname(const char* __nm, size_t __refs = 0)
+        : time_get<_CharT, _InputIterator>(__refs),
+          __time_get_storage<_CharT>(__nm) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit time_get_byname(const string& __nm, size_t __refs = 0)
+        : time_get<_CharT, _InputIterator>(__refs),
+          __time_get_storage<_CharT>(__nm) {}
+
+protected:
+    _LIBCPP_INLINE_VISIBILITY
+    ~time_get_byname() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    virtual dateorder do_date_order() const {return this->__do_date_order();}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type* __weeks() const  {return this->__weeks_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type* __months() const {return this->__months_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type* __am_pm() const  {return this->__am_pm_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type& __c() const      {return this->__c_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type& __r() const      {return this->__r_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type& __x() const      {return this->__x_;}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual const string_type& __X() const      {return this->__X_;}
+};
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
+
+class _LIBCPP_TYPE_VIS __time_put
+{
+    locale_t __loc_;
+protected:
+    _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {}
+    __time_put(const char* __nm);
+    __time_put(const string& __nm);
+    ~__time_put();
+    void __do_put(char* __nb, char*& __ne, const tm* __tm,
+                  char __fmt, char __mod) const;
+    void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
+                  char __fmt, char __mod) const;
+};
+
+template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY time_put
+    : public locale::facet,
+      private __time_put
+{
+public:
+    typedef _CharT char_type;
+    typedef _OutputIterator iter_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_put(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm,
+                  const char_type* __pb, const char_type* __pe) const;
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, ios_base& __iob, char_type __fl,
+                  const tm* __tm, char __fmt, char __mod = 0) const
+    {
+        return do_put(__s, __iob, __fl, __tm, __fmt, __mod);
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~time_put() {}
+    virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm,
+                             char __fmt, char __mod) const;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_put(const char* __nm, size_t __refs)
+        : locale::facet(__refs),
+          __time_put(__nm) {}
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_put(const string& __nm, size_t __refs)
+        : locale::facet(__refs),
+          __time_put(__nm) {}
+};
+
+template <class _CharT, class _OutputIterator>
+locale::id
+time_put<_CharT, _OutputIterator>::id;
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob,
+                                       char_type __fl, const tm* __tm,
+                                       const char_type* __pb,
+                                       const char_type* __pe) const
+{
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc());
+    for (; __pb != __pe; ++__pb)
+    {
+        if (__ct.narrow(*__pb, 0) == '%')
+        {
+            if (++__pb == __pe)
+            {
+                *__s++ = __pb[-1];
+                break;
+            }
+            char __mod = 0;
+            char __fmt = __ct.narrow(*__pb, 0);
+            if (__fmt == 'E' || __fmt == 'O')
+            {
+                if (++__pb == __pe)
+                {
+                    *__s++ = __pb[-2];
+                    *__s++ = __pb[-1];
+                    break;
+                }
+                __mod = __fmt;
+                __fmt = __ct.narrow(*__pb, 0);
+            }
+            __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod);
+        }
+        else
+            *__s++ = *__pb;
+    }
+    return __s;
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&,
+                                          char_type, const tm* __tm,
+                                          char __fmt, char __mod) const
+{
+    char_type __nar[100];
+    char_type* __nb = __nar;
+    char_type* __ne = __nb + 100;
+    __do_put(__nb, __ne, __tm, __fmt, __mod);
+    return _VSTD::copy(__nb, __ne, __s);
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
+
+template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY time_put_byname
+    : public time_put<_CharT, _OutputIterator>
+{
+public:
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_put_byname(const char* __nm, size_t __refs = 0)
+        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit time_put_byname(const string& __nm, size_t __refs = 0)
+        : time_put<_CharT, _OutputIterator>(__nm, __refs) {}
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~time_put_byname() {}
+};
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
+
+// money_base
+
+class _LIBCPP_TYPE_VIS money_base
+{
+public:
+    enum part {none, space, symbol, sign, value};
+    struct pattern {char field[4];};
+
+    _LIBCPP_ALWAYS_INLINE money_base() {}
+};
+
+// moneypunct
+
+template <class _CharT, bool _International = false>
+class _LIBCPP_TYPE_VIS_ONLY moneypunct
+    : public locale::facet,
+      public money_base
+{
+public:
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit moneypunct(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE char_type   decimal_point() const {return do_decimal_point();}
+    _LIBCPP_ALWAYS_INLINE char_type   thousands_sep() const {return do_thousands_sep();}
+    _LIBCPP_ALWAYS_INLINE string      grouping()      const {return do_grouping();}
+    _LIBCPP_ALWAYS_INLINE string_type curr_symbol()   const {return do_curr_symbol();}
+    _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();}
+    _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();}
+    _LIBCPP_ALWAYS_INLINE int         frac_digits()   const {return do_frac_digits();}
+    _LIBCPP_ALWAYS_INLINE pattern     pos_format()    const {return do_pos_format();}
+    _LIBCPP_ALWAYS_INLINE pattern     neg_format()    const {return do_neg_format();}
+
+    static locale::id id;
+    static const bool intl = _International;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~moneypunct() {}
+
+    virtual char_type   do_decimal_point() const {return numeric_limits<char_type>::max();}
+    virtual char_type   do_thousands_sep() const {return numeric_limits<char_type>::max();}
+    virtual string      do_grouping()      const {return string();}
+    virtual string_type do_curr_symbol()   const {return string_type();}
+    virtual string_type do_positive_sign() const {return string_type();}
+    virtual string_type do_negative_sign() const {return string_type(1, '-');}
+    virtual int         do_frac_digits()   const {return 0;}
+    virtual pattern     do_pos_format()    const
+        {pattern __p = {{symbol, sign, none, value}}; return __p;}
+    virtual pattern     do_neg_format()    const
+        {pattern __p = {{symbol, sign, none, value}}; return __p;}
+};
+
+template <class _CharT, bool _International>
+locale::id
+moneypunct<_CharT, _International>::id;
+
+template <class _CharT, bool _International>
+const bool
+moneypunct<_CharT, _International>::intl;
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
+
+// moneypunct_byname
+
+template <class _CharT, bool _International = false>
+class _LIBCPP_TYPE_VIS_ONLY moneypunct_byname
+    : public moneypunct<_CharT, _International>
+{
+public:
+    typedef money_base::pattern  pattern;
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit moneypunct_byname(const char* __nm, size_t __refs = 0)
+        : moneypunct<_CharT, _International>(__refs) {init(__nm);}
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit moneypunct_byname(const string& __nm, size_t __refs = 0)
+        : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());}
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~moneypunct_byname() {}
+
+    virtual char_type   do_decimal_point() const {return __decimal_point_;}
+    virtual char_type   do_thousands_sep() const {return __thousands_sep_;}
+    virtual string      do_grouping()      const {return __grouping_;}
+    virtual string_type do_curr_symbol()   const {return __curr_symbol_;}
+    virtual string_type do_positive_sign() const {return __positive_sign_;}
+    virtual string_type do_negative_sign() const {return __negative_sign_;}
+    virtual int         do_frac_digits()   const {return __frac_digits_;}
+    virtual pattern     do_pos_format()    const {return __pos_format_;}
+    virtual pattern     do_neg_format()    const {return __neg_format_;}
+
+private:
+    char_type   __decimal_point_;
+    char_type   __thousands_sep_;
+    string      __grouping_;
+    string_type __curr_symbol_;
+    string_type __positive_sign_;
+    string_type __negative_sign_;
+    int         __frac_digits_;
+    pattern     __pos_format_;
+    pattern     __neg_format_;
+
+    void init(const char*);
+};
+
+template<> void moneypunct_byname<char, false>::init(const char*);
+template<> void moneypunct_byname<char, true>::init(const char*);
+template<> void moneypunct_byname<wchar_t, false>::init(const char*);
+template<> void moneypunct_byname<wchar_t, true>::init(const char*);
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
+
+// money_get
+
+template <class _CharT>
+class __money_get
+{
+protected:
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE __money_get() {}
+
+    static void __gather_info(bool __intl, const locale& __loc,
+                              money_base::pattern& __pat, char_type& __dp,
+                              char_type& __ts, string& __grp,
+                              string_type& __sym, string_type& __psn,
+                              string_type& __nsn, int& __fd);
+};
+
+template <class _CharT>
+void
+__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc,
+                                   money_base::pattern& __pat, char_type& __dp,
+                                   char_type& __ts, string& __grp,
+                                   string_type& __sym, string_type& __psn,
+                                   string_type& __nsn, int& __fd)
+{
+    if (__intl)
+    {
+        const moneypunct<char_type, true>& __mp =
+            use_facet<moneypunct<char_type, true> >(__loc);
+        __pat = __mp.neg_format();
+        __nsn = __mp.negative_sign();
+        __psn = __mp.positive_sign();
+        __dp = __mp.decimal_point();
+        __ts = __mp.thousands_sep();
+        __grp = __mp.grouping();
+        __sym = __mp.curr_symbol();
+        __fd = __mp.frac_digits();
+    }
+    else
+    {
+        const moneypunct<char_type, false>& __mp =
+            use_facet<moneypunct<char_type, false> >(__loc);
+        __pat = __mp.neg_format();
+        __nsn = __mp.negative_sign();
+        __psn = __mp.positive_sign();
+        __dp = __mp.decimal_point();
+        __ts = __mp.thousands_sep();
+        __grp = __mp.grouping();
+        __sym = __mp.curr_symbol();
+        __fd = __mp.frac_digits();
+    }
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
+
+template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY money_get
+    : public locale::facet,
+      private __money_get<_CharT>
+{
+public:
+    typedef _CharT                  char_type;
+    typedef _InputIterator          iter_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit money_get(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
+                  ios_base::iostate& __err, long double& __v) const
+    {
+        return do_get(__b, __e, __intl, __iob, __err, __v);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob,
+                  ios_base::iostate& __err, string_type& __v) const
+    {
+        return do_get(__b, __e, __intl, __iob, __err, __v);
+    }
+
+    static locale::id id;
+
+protected:
+
+    _LIBCPP_ALWAYS_INLINE
+    ~money_get() {}
+
+    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
+                             ios_base& __iob, ios_base::iostate& __err,
+                             long double& __v) const;
+    virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl,
+                             ios_base& __iob, ios_base::iostate& __err,
+                             string_type& __v) const;
+
+private:
+    static bool __do_get(iter_type& __b, iter_type __e,
+                         bool __intl, const locale& __loc,
+                         ios_base::fmtflags __flags, ios_base::iostate& __err,
+                         bool& __neg, const ctype<char_type>& __ct,
+                         unique_ptr<char_type, void(*)(void*)>& __wb,
+                         char_type*& __wn, char_type* __we);
+};
+
+template <class _CharT, class _InputIterator>
+locale::id
+money_get<_CharT, _InputIterator>::id;
+
+_LIBCPP_FUNC_VIS void __do_nothing(void*);
+
+template <class _Tp>
+_LIBCPP_HIDDEN
+void
+__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e)
+{
+    bool __owns = __b.get_deleter() != __do_nothing;
+    size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp);
+    size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ?
+                       2 * __cur_cap : numeric_limits<size_t>::max();
+    size_t __n_off = static_cast<size_t>(__n - __b.get());
+    _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap);
+    if (__t == 0)
+        __throw_bad_alloc();
+    if (__owns)
+        __b.release();
+    __b = unique_ptr<_Tp, void(*)(void*)>(__t, free);
+    __new_cap /= sizeof(_Tp);
+    __n = __b.get() + __n_off;
+    __e = __b.get() + __new_cap;
+}
+
+// true == success
+template <class _CharT, class _InputIterator>
+bool
+money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
+                                            bool __intl, const locale& __loc,
+                                            ios_base::fmtflags __flags,
+                                            ios_base::iostate& __err,
+                                            bool& __neg,
+                                            const ctype<char_type>& __ct,
+                                            unique_ptr<char_type, void(*)(void*)>& __wb,
+                                            char_type*& __wn, char_type* __we)
+{
+    const unsigned __bz = 100;
+    unsigned __gbuf[__bz];
+    unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing);
+    unsigned* __gn = __gb.get();
+    unsigned* __ge = __gn + __bz;
+    money_base::pattern __pat;
+    char_type __dp;
+    char_type __ts;
+    string __grp;
+    string_type __sym;
+    string_type __psn;
+    string_type __nsn;
+    // Capture the spaces read into money_base::{space,none} so they
+    // can be compared to initial spaces in __sym.
+    string_type __spaces;
+    int __fd;
+    __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp,
+                                       __sym, __psn, __nsn, __fd);
+    const string_type* __trailing_sign = 0;
+    __wn = __wb.get();
+    for (unsigned __p = 0; __p < 4 && __b != __e; ++__p)
+    {
+        switch (__pat.field[__p])
+        {
+        case money_base::space:
+            if (__p != 3)
+            {
+                if (__ct.is(ctype_base::space, *__b))
+                    __spaces.push_back(*__b++);
+                else
+                {
+                    __err |= ios_base::failbit;
+                    return false;
+                }
+            }
+            // drop through
+        case money_base::none:
+            if (__p != 3)
+            {
+                while (__b != __e && __ct.is(ctype_base::space, *__b))
+                    __spaces.push_back(*__b++);
+            }
+            break;
+        case money_base::sign:
+            if (__psn.size() + __nsn.size() > 0)
+            {
+                if (__psn.size() == 0 || __nsn.size() == 0)
+                {   // sign is optional
+                    if (__psn.size() > 0)
+                    {   // __nsn.size() == 0
+                        if (*__b == __psn[0])
+                        {
+                            ++__b;
+                            if (__psn.size() > 1)
+                                __trailing_sign = &__psn;
+                        }
+                        else
+                            __neg = true;
+                    }
+                    else if (*__b == __nsn[0])  // __nsn.size() > 0 &&  __psn.size() == 0
+                    {
+                        ++__b;
+                        __neg = true;
+                        if (__nsn.size() > 1)
+                            __trailing_sign = &__nsn;
+                    }
+                }
+                else  // sign is required
+                {
+                    if (*__b == __psn[0])
+                    {
+                        ++__b;
+                        if (__psn.size() > 1)
+                            __trailing_sign = &__psn;
+                    }
+                    else if (*__b == __nsn[0])
+                    {
+                        ++__b;
+                        __neg = true;
+                        if (__nsn.size() > 1)
+                            __trailing_sign = &__nsn;
+                    }
+                    else
+                    {
+                        __err |= ios_base::failbit;
+                        return false;
+                    }
+                }
+            }
+            break;
+        case money_base::symbol:
+            {
+            bool __more_needed = __trailing_sign ||
+                                 (__p < 2)       ||
+                                 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none));
+            bool __sb = (__flags & ios_base::showbase) != 0;
+            if (__sb || __more_needed)
+            {
+                typename string_type::const_iterator __sym_space_end = __sym.begin();
+                if (__p > 0 && (__pat.field[__p - 1] == money_base::none ||
+                                __pat.field[__p - 1] == money_base::space)) {
+                    // Match spaces we've already read against spaces at
+                    // the beginning of __sym.
+                    while (__sym_space_end != __sym.end() &&
+                           __ct.is(ctype_base::space, *__sym_space_end))
+                        ++__sym_space_end;
+                    const size_t __num_spaces = __sym_space_end - __sym.begin();
+                    if (__num_spaces > __spaces.size() ||
+                        !equal(__spaces.end() - __num_spaces, __spaces.end(),
+                               __sym.begin())) {
+                        // No match. Put __sym_space_end back at the
+                        // beginning of __sym, which will prevent a
+                        // match in the next loop.
+                        __sym_space_end = __sym.begin();
+                    }
+                }
+                typename string_type::const_iterator __sym_curr_char = __sym_space_end;
+                while (__sym_curr_char != __sym.end() && __b != __e &&
+                       *__b == *__sym_curr_char) {
+                    ++__b;
+                    ++__sym_curr_char;
+                }
+                if (__sb && __sym_curr_char != __sym.end())
+                {
+                    __err |= ios_base::failbit;
+                    return false;
+                }
+            }
+            }
+            break;
+        case money_base::value:
+            {
+            unsigned __ng = 0;
+            for (; __b != __e; ++__b)
+            {
+                char_type __c = *__b;
+                if (__ct.is(ctype_base::digit, __c))
+                {
+                    if (__wn == __we)
+                        __double_or_nothing(__wb, __wn, __we);
+                    *__wn++ = __c;
+                    ++__ng;
+                }
+                else if (__grp.size() > 0 && __ng > 0 && __c == __ts)
+                {
+                    if (__gn == __ge)
+                        __double_or_nothing(__gb, __gn, __ge);
+                    *__gn++ = __ng;
+                    __ng = 0;
+                }
+                else
+                    break;
+            }
+            if (__gb.get() != __gn && __ng > 0)
+            {
+                if (__gn == __ge)
+                    __double_or_nothing(__gb, __gn, __ge);
+                *__gn++ = __ng;
+            }
+            if (__fd > 0)
+            {
+                if (__b == __e || *__b != __dp)
+                {
+                    __err |= ios_base::failbit;
+                    return false;
+                }
+                for (++__b; __fd > 0; --__fd, ++__b)
+                {
+                    if (__b == __e || !__ct.is(ctype_base::digit, *__b))
+                    {
+                        __err |= ios_base::failbit;
+                        return false;
+                    }
+                    if (__wn == __we)
+                        __double_or_nothing(__wb, __wn, __we);
+                    *__wn++ = *__b;
+                }
+            }
+            if (__wn == __wb.get())
+            {
+                __err |= ios_base::failbit;
+                return false;
+            }
+            }
+            break;
+        }
+    }
+    if (__trailing_sign)
+    {
+        for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b)
+        {
+            if (__b == __e || *__b != (*__trailing_sign)[__i])
+            {
+                __err |= ios_base::failbit;
+                return false;
+            }
+        }
+    }
+    if (__gb.get() != __gn)
+    {
+        ios_base::iostate __et = ios_base::goodbit;
+        __check_grouping(__grp, __gb.get(), __gn, __et);
+        if (__et)
+        {
+            __err |= ios_base::failbit;
+            return false;
+        }
+    }
+    return true;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+                                          bool __intl, ios_base& __iob,
+                                          ios_base::iostate& __err,
+                                          long double& __v) const
+{
+    const int __bz = 100;
+    char_type __wbuf[__bz];
+    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
+    char_type* __wn;
+    char_type* __we = __wbuf + __bz;
+    locale __loc = __iob.getloc();
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+    bool __neg = false;
+    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
+                 __wb, __wn, __we))
+    {
+        const char __src[] = "0123456789";
+        char_type __atoms[sizeof(__src)-1];
+        __ct.widen(__src, __src + (sizeof(__src)-1), __atoms);
+        char __nbuf[__bz];
+        char* __nc = __nbuf;
+        unique_ptr<char, void(*)(void*)> __h(0, free);
+        if (__wn - __wb.get() > __bz-2)
+        {
+            __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2)));
+            if (__h.get() == 0)
+                __throw_bad_alloc();
+            __nc = __h.get();
+        }
+        if (__neg)
+            *__nc++ = '-';
+        for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc)
+            *__nc = __src[find(__atoms, _VSTD::end(__atoms), *__w) - __atoms];
+        *__nc = char();
+        if (sscanf(__nbuf, "%Lf", &__v) != 1)
+            __throw_runtime_error("money_get error");
+    }
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+template <class _CharT, class _InputIterator>
+_InputIterator
+money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e,
+                                          bool __intl, ios_base& __iob,
+                                          ios_base::iostate& __err,
+                                          string_type& __v) const
+{
+    const int __bz = 100;
+    char_type __wbuf[__bz];
+    unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing);
+    char_type* __wn;
+    char_type* __we = __wbuf + __bz;
+    locale __loc = __iob.getloc();
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+    bool __neg = false;
+    if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct,
+                 __wb, __wn, __we))
+    {
+        __v.clear();
+        if (__neg)
+            __v.push_back(__ct.widen('-'));
+        char_type __z = __ct.widen('0');
+        char_type* __w;
+        for (__w = __wb.get(); __w < __wn-1; ++__w)
+            if (*__w != __z)
+                break;
+        __v.append(__w, __wn);
+    }
+    if (__b == __e)
+        __err |= ios_base::eofbit;
+    return __b;
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
+
+// money_put
+
+template <class _CharT>
+class __money_put
+{
+protected:
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE __money_put() {}
+
+    static void __gather_info(bool __intl, bool __neg, const locale& __loc,
+                              money_base::pattern& __pat, char_type& __dp,
+                              char_type& __ts, string& __grp,
+                              string_type& __sym, string_type& __sn,
+                              int& __fd);
+    static void __format(char_type* __mb, char_type*& __mi, char_type*& __me,
+                         ios_base::fmtflags __flags,
+                         const char_type* __db, const char_type* __de,
+                         const ctype<char_type>& __ct, bool __neg,
+                         const money_base::pattern& __pat, char_type __dp,
+                         char_type __ts, const string& __grp,
+                         const string_type& __sym, const string_type& __sn,
+                         int __fd);
+};
+
+template <class _CharT>
+void
+__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc,
+                                   money_base::pattern& __pat, char_type& __dp,
+                                   char_type& __ts, string& __grp,
+                                   string_type& __sym, string_type& __sn,
+                                   int& __fd)
+{
+    if (__intl)
+    {
+        const moneypunct<char_type, true>& __mp =
+            use_facet<moneypunct<char_type, true> >(__loc);
+        if (__neg)
+        {
+            __pat = __mp.neg_format();
+            __sn = __mp.negative_sign();
+        }
+        else
+        {
+            __pat = __mp.pos_format();
+            __sn = __mp.positive_sign();
+        }
+        __dp = __mp.decimal_point();
+        __ts = __mp.thousands_sep();
+        __grp = __mp.grouping();
+        __sym = __mp.curr_symbol();
+        __fd = __mp.frac_digits();
+    }
+    else
+    {
+        const moneypunct<char_type, false>& __mp =
+            use_facet<moneypunct<char_type, false> >(__loc);
+        if (__neg)
+        {
+            __pat = __mp.neg_format();
+            __sn = __mp.negative_sign();
+        }
+        else
+        {
+            __pat = __mp.pos_format();
+            __sn = __mp.positive_sign();
+        }
+        __dp = __mp.decimal_point();
+        __ts = __mp.thousands_sep();
+        __grp = __mp.grouping();
+        __sym = __mp.curr_symbol();
+        __fd = __mp.frac_digits();
+    }
+}
+
+template <class _CharT>
+void
+__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me,
+                              ios_base::fmtflags __flags,
+                              const char_type* __db, const char_type* __de,
+                              const ctype<char_type>& __ct, bool __neg,
+                              const money_base::pattern& __pat, char_type __dp,
+                              char_type __ts, const string& __grp,
+                              const string_type& __sym, const string_type& __sn,
+                              int __fd)
+{
+    __me = __mb;
+    for (unsigned __p = 0; __p < 4; ++__p)
+    {
+        switch (__pat.field[__p])
+        {
+        case money_base::none:
+            __mi = __me;
+            break;
+        case money_base::space:
+            __mi = __me;
+            *__me++ = __ct.widen(' ');
+            break;
+        case money_base::sign:
+            if (!__sn.empty())
+                *__me++ = __sn[0];
+            break;
+        case money_base::symbol:
+            if (!__sym.empty() && (__flags & ios_base::showbase))
+                __me = _VSTD::copy(__sym.begin(), __sym.end(), __me);
+            break;
+        case money_base::value:
+            {
+            // remember start of value so we can reverse it
+            char_type* __t = __me;
+            // find beginning of digits
+            if (__neg)
+                ++__db;
+            // find end of digits
+            const char_type* __d;
+            for (__d = __db; __d < __de; ++__d)
+                if (!__ct.is(ctype_base::digit, *__d))
+                    break;
+            // print fractional part
+            if (__fd > 0)
+            {
+                int __f;
+                for (__f = __fd; __d > __db && __f > 0; --__f)
+                    *__me++ = *--__d;
+                char_type __z = __f > 0 ? __ct.widen('0') : char_type();
+                for (; __f > 0; --__f)
+                    *__me++ = __z;
+                *__me++ = __dp;
+            }
+            // print units part
+            if (__d == __db)
+            {
+                *__me++ = __ct.widen('0');
+            }
+            else
+            {
+                unsigned __ng = 0;
+                unsigned __ig = 0;
+                unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max()
+                                              : static_cast<unsigned>(__grp[__ig]);
+                while (__d != __db)
+                {
+                    if (__ng == __gl)
+                    {
+                        *__me++ = __ts;
+                        __ng = 0;
+                        if (++__ig < __grp.size())
+                            __gl = __grp[__ig] == numeric_limits<char>::max() ?
+                                        numeric_limits<unsigned>::max() :
+                                        static_cast<unsigned>(__grp[__ig]);
+                    }
+                    *__me++ = *--__d;
+                    ++__ng;
+                }
+            }
+            // reverse it
+            reverse(__t, __me);
+            }
+            break;
+        }
+    }
+    // print rest of sign, if any
+    if (__sn.size() > 1)
+        __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me);
+    // set alignment
+    if ((__flags & ios_base::adjustfield) == ios_base::left)
+        __mi = __me;
+    else if ((__flags & ios_base::adjustfield) != ios_base::internal)
+        __mi = __mb;
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
+
+template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY money_put
+    : public locale::facet,
+      private __money_put<_CharT>
+{
+public:
+    typedef _CharT                  char_type;
+    typedef _OutputIterator         iter_type;
+    typedef basic_string<char_type> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit money_put(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
+                  long double __units) const
+    {
+        return do_put(__s, __intl, __iob, __fl, __units);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl,
+                  const string_type& __digits) const
+    {
+        return do_put(__s, __intl, __iob, __fl, __digits);
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~money_put() {}
+
+    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
+                             char_type __fl, long double __units) const;
+    virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob,
+                             char_type __fl, const string_type& __digits) const;
+};
+
+template <class _CharT, class _OutputIterator>
+locale::id
+money_put<_CharT, _OutputIterator>::id;
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
+                                           ios_base& __iob, char_type __fl,
+                                           long double __units) const
+{
+    // convert to char
+    const size_t __bs = 100;
+    char __buf[__bs];
+    char* __bb = __buf;
+    char_type __digits[__bs];
+    char_type* __db = __digits;
+    size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units));
+    unique_ptr<char, void(*)(void*)> __hn(0, free);
+    unique_ptr<char_type, void(*)(void*)> __hd(0, free);
+    // secure memory for digit storage
+    if (__n > __bs-1)
+    {
+#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
+        __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
+#else
+        __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
+#endif
+        if (__bb == 0)
+            __throw_bad_alloc();
+        __hn.reset(__bb);
+        __hd.reset((char_type*)malloc(__n * sizeof(char_type)));
+        if (__hd == nullptr)
+            __throw_bad_alloc();
+        __db = __hd.get();
+    }
+    // gather info
+    locale __loc = __iob.getloc();
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+    __ct.widen(__bb, __bb + __n, __db);
+    bool __neg = __n > 0 && __bb[0] == '-';
+    money_base::pattern __pat;
+    char_type __dp;
+    char_type __ts;
+    string __grp;
+    string_type __sym;
+    string_type __sn;
+    int __fd;
+    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
+    // secure memory for formatting
+    char_type __mbuf[__bs];
+    char_type* __mb = __mbuf;
+    unique_ptr<char_type, void(*)(void*)> __hw(0, free);
+    size_t __exn = static_cast<int>(__n) > __fd ?
+                   (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() +
+                    __sym.size() + static_cast<size_t>(__fd) + 1
+                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
+    if (__exn > __bs)
+    {
+        __hw.reset((char_type*)malloc(__exn * sizeof(char_type)));
+        __mb = __hw.get();
+        if (__mb == 0)
+            __throw_bad_alloc();
+    }
+    // format
+    char_type* __mi;
+    char_type* __me;
+    this->__format(__mb, __mi, __me, __iob.flags(),
+                   __db, __db + __n, __ct,
+                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
+    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
+}
+
+template <class _CharT, class _OutputIterator>
+_OutputIterator
+money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl,
+                                           ios_base& __iob, char_type __fl,
+                                           const string_type& __digits) const
+{
+    // gather info
+    locale __loc = __iob.getloc();
+    const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc);
+    bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-');
+    money_base::pattern __pat;
+    char_type __dp;
+    char_type __ts;
+    string __grp;
+    string_type __sym;
+    string_type __sn;
+    int __fd;
+    this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
+    // secure memory for formatting
+    char_type __mbuf[100];
+    char_type* __mb = __mbuf;
+    unique_ptr<char_type, void(*)(void*)> __h(0, free);
+    size_t __exn = static_cast<int>(__digits.size()) > __fd ?
+                   (__digits.size() - static_cast<size_t>(__fd)) * 2 +
+                    __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1
+                 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2;
+    if (__exn > 100)
+    {
+        __h.reset((char_type*)malloc(__exn * sizeof(char_type)));
+        __mb = __h.get();
+        if (__mb == 0)
+            __throw_bad_alloc();
+    }
+    // format
+    char_type* __mi;
+    char_type* __me;
+    this->__format(__mb, __mi, __me, __iob.flags(),
+                   __digits.data(), __digits.data() + __digits.size(), __ct,
+                   __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd);
+    return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
+
+// messages
+
+class _LIBCPP_TYPE_VIS messages_base
+{
+public:
+    typedef ptrdiff_t catalog;
+
+    _LIBCPP_ALWAYS_INLINE messages_base() {}
+};
+
+template <class _CharT>
+class _LIBCPP_TYPE_VIS_ONLY messages
+    : public locale::facet,
+      public messages_base
+{
+public:
+    typedef _CharT               char_type;
+    typedef basic_string<_CharT> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit messages(size_t __refs = 0)
+        : locale::facet(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    catalog open(const basic_string<char>& __nm, const locale& __loc) const
+    {
+        return do_open(__nm, __loc);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    string_type get(catalog __c, int __set, int __msgid,
+                    const string_type& __dflt) const
+    {
+        return do_get(__c, __set, __msgid, __dflt);
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    void close(catalog __c) const
+    {
+        do_close(__c);
+    }
+
+    static locale::id id;
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~messages() {}
+
+    virtual catalog do_open(const basic_string<char>&, const locale&) const;
+    virtual string_type do_get(catalog, int __set, int __msgid,
+                               const string_type& __dflt) const;
+    virtual void do_close(catalog) const;
+};
+
+template <class _CharT>
+locale::id
+messages<_CharT>::id;
+
+template <class _CharT>
+typename messages<_CharT>::catalog
+messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
+{
+#if defined(_WIN32) || defined(__ANDROID__)
+    return -1;
+#else // _WIN32 || __ANDROID__
+    catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
+    if (__cat != -1)
+        __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
+    return __cat;
+#endif // _WIN32 || __ANDROID__
+}
+
+template <class _CharT>
+typename messages<_CharT>::string_type
+messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
+                         const string_type& __dflt) const
+{
+#if defined(_WIN32) || defined(__ANDROID__)
+    return __dflt;
+#else // _WIN32
+    string __ndflt;
+    __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
+                                                       __dflt.c_str(),
+                                                       __dflt.c_str() + __dflt.size());
+    if (__c != -1)
+        __c <<= 1;
+    nl_catd __cat = (nl_catd)__c;
+    char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str());
+    string_type __w;
+    __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
+                                                        __n, __n + strlen(__n));
+    return __w;
+#endif // _WIN32
+}
+
+template <class _CharT>
+void
+messages<_CharT>::do_close(catalog __c) const
+{
+#if !defined(_WIN32) && !defined(__ANDROID__)
+    if (__c != -1)
+        __c <<= 1;
+    nl_catd __cat = (nl_catd)__c;
+    catclose(__cat);
+#endif // !_WIN32
+}
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
+
+template <class _CharT>
+class _LIBCPP_TYPE_VIS_ONLY messages_byname
+    : public messages<_CharT>
+{
+public:
+    typedef messages_base::catalog catalog;
+    typedef basic_string<_CharT> string_type;
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit messages_byname(const char*, size_t __refs = 0)
+        : messages<_CharT>(__refs) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    explicit messages_byname(const string&, size_t __refs = 0)
+        : messages<_CharT>(__refs) {}
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    ~messages_byname() {}
+};
+
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
+
+template<class _Codecvt, class _Elem = wchar_t,
+         class _Wide_alloc = allocator<_Elem>,
+         class _Byte_alloc = allocator<char> >
+class _LIBCPP_TYPE_VIS_ONLY wstring_convert
+{
+public:
+    typedef basic_string<char, char_traits<char>, _Byte_alloc>   byte_string;
+    typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
+    typedef typename _Codecvt::state_type                        state_type;
+    typedef typename wide_string::traits_type::int_type          int_type;
+
+private:
+    byte_string __byte_err_string_;
+    wide_string __wide_err_string_;
+    _Codecvt* __cvtptr_;
+    state_type __cvtstate_;
+    size_t __cvtcount_;
+
+    wstring_convert(const wstring_convert& __wc);
+    wstring_convert& operator=(const wstring_convert& __wc);
+public:
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
+    wstring_convert(_Codecvt* __pcvt, state_type __state);
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
+                    const wide_string& __wide_err = wide_string());
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    wstring_convert(wstring_convert&& __wc);
+#endif
+    ~wstring_convert();
+
+    _LIBCPP_ALWAYS_INLINE
+    wide_string from_bytes(char __byte)
+        {return from_bytes(&__byte, &__byte+1);}
+    _LIBCPP_ALWAYS_INLINE
+    wide_string from_bytes(const char* __ptr)
+        {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));}
+    _LIBCPP_ALWAYS_INLINE
+    wide_string from_bytes(const byte_string& __str)
+        {return from_bytes(__str.data(), __str.data() + __str.size());}
+    wide_string from_bytes(const char* __first, const char* __last);
+
+    _LIBCPP_ALWAYS_INLINE
+    byte_string to_bytes(_Elem __wchar)
+        {return to_bytes(&__wchar, &__wchar+1);}
+    _LIBCPP_ALWAYS_INLINE
+    byte_string to_bytes(const _Elem* __wptr)
+        {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));}
+    _LIBCPP_ALWAYS_INLINE
+    byte_string to_bytes(const wide_string& __wstr)
+        {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());}
+    byte_string to_bytes(const _Elem* __first, const _Elem* __last);
+
+    _LIBCPP_ALWAYS_INLINE
+    size_t converted() const _NOEXCEPT {return __cvtcount_;}
+    _LIBCPP_ALWAYS_INLINE
+    state_type state() const {return __cvtstate_;}
+};
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+inline _LIBCPP_ALWAYS_INLINE
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    wstring_convert(_Codecvt* __pcvt)
+        : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0)
+{
+}
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+inline _LIBCPP_ALWAYS_INLINE
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    wstring_convert(_Codecvt* __pcvt, state_type __state)
+        : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0)
+{
+}
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err)
+        : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err),
+          __cvtstate_(), __cvtcount_(0)
+{
+    __cvtptr_ = new _Codecvt;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+inline _LIBCPP_ALWAYS_INLINE
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    wstring_convert(wstring_convert&& __wc)
+        : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)),
+          __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)),
+          __cvtptr_(__wc.__cvtptr_),
+          __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
+{
+    __wc.__cvtptr_ = nullptr;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert()
+{
+    delete __cvtptr_;
+}
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    from_bytes(const char* __frm, const char* __frm_end)
+{
+    __cvtcount_ = 0;
+    if (__cvtptr_ != nullptr)
+    {
+        wide_string __ws(2*(__frm_end - __frm), _Elem());
+        if (__frm != __frm_end)
+            __ws.resize(__ws.capacity());
+        codecvt_base::result __r = codecvt_base::ok;
+        state_type __st = __cvtstate_;
+        if (__frm != __frm_end)
+        {
+            _Elem* __to = &__ws[0];
+            _Elem* __to_end = __to + __ws.size();
+            const char* __frm_nxt;
+            do
+            {
+                _Elem* __to_nxt;
+                __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt,
+                                          __to, __to_end, __to_nxt);
+                __cvtcount_ += __frm_nxt - __frm;
+                if (__frm_nxt == __frm)
+                {
+                    __r = codecvt_base::error;
+                }
+                else if (__r == codecvt_base::noconv)
+                {
+                    __ws.resize(__to - &__ws[0]);
+                    // This only gets executed if _Elem is char
+                    __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end);
+                    __frm = __frm_nxt;
+                    __r = codecvt_base::ok;
+                }
+                else if (__r == codecvt_base::ok)
+                {
+                    __ws.resize(__to_nxt - &__ws[0]);
+                    __frm = __frm_nxt;
+                }
+                else if (__r == codecvt_base::partial)
+                {
+                    ptrdiff_t __s = __to_nxt - &__ws[0];
+                    __ws.resize(2 * __s);
+                    __to = &__ws[0] + __s;
+                    __to_end = &__ws[0] + __ws.size();
+                    __frm = __frm_nxt;
+                }
+            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
+        }
+        if (__r == codecvt_base::ok)
+            return __ws;
+    }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__wide_err_string_.empty())
+        throw range_error("wstring_convert: from_bytes error");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __wide_err_string_;
+}
+
+template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc>
+typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string
+wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::
+    to_bytes(const _Elem* __frm, const _Elem* __frm_end)
+{
+    __cvtcount_ = 0;
+    if (__cvtptr_ != nullptr)
+    {
+        byte_string __bs(2*(__frm_end - __frm), char());
+        if (__frm != __frm_end)
+            __bs.resize(__bs.capacity());
+        codecvt_base::result __r = codecvt_base::ok;
+        state_type __st = __cvtstate_;
+        if (__frm != __frm_end)
+        {
+            char* __to = &__bs[0];
+            char* __to_end = __to + __bs.size();
+            const _Elem* __frm_nxt;
+            do
+            {
+                char* __to_nxt;
+                __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt,
+                                           __to, __to_end, __to_nxt);
+                __cvtcount_ += __frm_nxt - __frm;
+                if (__frm_nxt == __frm)
+                {
+                    __r = codecvt_base::error;
+                }
+                else if (__r == codecvt_base::noconv)
+                {
+                    __bs.resize(__to - &__bs[0]);
+                    // This only gets executed if _Elem is char
+                    __bs.append((const char*)__frm, (const char*)__frm_end);
+                    __frm = __frm_nxt;
+                    __r = codecvt_base::ok;
+                }
+                else if (__r == codecvt_base::ok)
+                {
+                    __bs.resize(__to_nxt - &__bs[0]);
+                    __frm = __frm_nxt;
+                }
+                else if (__r == codecvt_base::partial)
+                {
+                    ptrdiff_t __s = __to_nxt - &__bs[0];
+                    __bs.resize(2 * __s);
+                    __to = &__bs[0] + __s;
+                    __to_end = &__bs[0] + __bs.size();
+                    __frm = __frm_nxt;
+                }
+            } while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
+        }
+        if (__r == codecvt_base::ok)
+        {
+            size_t __s = __bs.size();
+            __bs.resize(__bs.capacity());
+            char* __to = &__bs[0] + __s;
+            char* __to_end = __to + __bs.size();
+            do
+            {
+                char* __to_nxt;
+                __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
+                if (__r == codecvt_base::noconv)
+                {
+                    __bs.resize(__to - &__bs[0]);
+                    __r = codecvt_base::ok;
+                }
+                else if (__r == codecvt_base::ok)
+                {
+                    __bs.resize(__to_nxt - &__bs[0]);
+                }
+                else if (__r == codecvt_base::partial)
+                {
+                    ptrdiff_t __sp = __to_nxt - &__bs[0];
+                    __bs.resize(2 * __sp);
+                    __to = &__bs[0] + __sp;
+                    __to_end = &__bs[0] + __bs.size();
+                }
+            } while (__r == codecvt_base::partial);
+            if (__r == codecvt_base::ok)
+                return __bs;
+        }
+    }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__byte_err_string_.empty())
+        throw range_error("wstring_convert: to_bytes error");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __byte_err_string_;
+}
+
+template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> >
+class _LIBCPP_TYPE_VIS_ONLY wbuffer_convert
+    : public basic_streambuf<_Elem, _Tr>
+{
+public:
+    // types:
+    typedef _Elem                          char_type;
+    typedef _Tr                            traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef typename _Codecvt::state_type  state_type;
+
+private:
+    char*       __extbuf_;
+    const char* __extbufnext_;
+    const char* __extbufend_;
+    char __extbuf_min_[8];
+    size_t __ebs_;
+    char_type* __intbuf_;
+    size_t __ibs_;
+    streambuf* __bufptr_;
+    _Codecvt* __cv_;
+    state_type __st_;
+    ios_base::openmode __cm_;
+    bool __owns_eb_;
+    bool __owns_ib_;
+    bool __always_noconv_;
+
+    wbuffer_convert(const wbuffer_convert&);
+    wbuffer_convert& operator=(const wbuffer_convert&);
+public:
+    _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = 0, 
+            _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
+    ~wbuffer_convert();
+
+    _LIBCPP_INLINE_VISIBILITY
+    streambuf* rdbuf() const {return __bufptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    streambuf* rdbuf(streambuf* __bytebuf)
+    {
+        streambuf* __r = __bufptr_;
+        __bufptr_ = __bytebuf;
+        return __r;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    state_type state() const {return __st_;}
+
+protected:
+    virtual int_type underflow();
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
+    virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s,
+                                                            streamsize __n);
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual int sync();
+
+private:
+    bool __read_mode();
+    void __write_mode();
+    wbuffer_convert* __close();
+};
+
+template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>::
+    wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state)
+    : __extbuf_(0),
+      __extbufnext_(0),
+      __extbufend_(0),
+      __ebs_(0),
+      __intbuf_(0),
+      __ibs_(0),
+      __bufptr_(__bytebuf),
+      __cv_(__pcvt),
+      __st_(__state),
+      __cm_(0),
+      __owns_eb_(false),
+      __owns_ib_(false),
+      __always_noconv_(__cv_ ? __cv_->always_noconv() : false)
+{
+    setbuf(0, 4096);
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert()
+{
+    __close();
+    delete __cv_;
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
+{
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return traits_type::eof();
+    bool __initial = __read_mode();
+    char_type __1buf;
+    if (this->gptr() == 0)
+        this->setg(&__1buf, &__1buf+1, &__1buf+1);
+    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
+    int_type __c = traits_type::eof();
+    if (this->gptr() == this->egptr())
+    {
+        memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
+        if (__always_noconv_)
+        {
+            streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz);
+            __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb);
+            if (__nmemb != 0)
+            {
+                this->setg(this->eback(),
+                           this->eback() + __unget_sz,
+                           this->eback() + __unget_sz + __nmemb);
+                __c = *this->gptr();
+            }
+        }
+        else
+        {
+            memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
+            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
+            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
+            streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz),
+                                 static_cast<streamsize>(__extbufend_ - __extbufnext_));
+            codecvt_base::result __r;
+            state_type __svs = __st_;
+            streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb);
+            if (__nr != 0)
+            {
+                __extbufend_ = __extbufnext_ + __nr;
+                char_type*  __inext;
+                __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
+                                       this->eback() + __unget_sz,
+                                       this->egptr(), __inext);
+                if (__r == codecvt_base::noconv)
+                {
+                    this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
+                    __c = *this->gptr();
+                }
+                else if (__inext != this->eback() + __unget_sz)
+                {
+                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
+                    __c = *this->gptr();
+                }
+            }
+        }
+    }
+    else
+        __c = *this->gptr();
+    if (this->eback() == &__1buf)
+        this->setg(0, 0, 0);
+    return __c;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c)
+{
+    if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr())
+    {
+        if (traits_type::eq_int_type(__c, traits_type::eof()))
+        {
+            this->gbump(-1);
+            return traits_type::not_eof(__c);
+        }
+        if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
+        {
+            this->gbump(-1);
+            *this->gptr() = traits_type::to_char_type(__c);
+            return __c;
+        }
+    }
+    return traits_type::eof();
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
+{
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return traits_type::eof();
+    __write_mode();
+    char_type __1buf;
+    char_type* __pb_save = this->pbase();
+    char_type* __epb_save = this->epptr();
+    if (!traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        if (this->pptr() == 0)
+            this->setp(&__1buf, &__1buf+1);
+        *this->pptr() = traits_type::to_char_type(__c);
+        this->pbump(1);
+    }
+    if (this->pptr() != this->pbase())
+    {
+        if (__always_noconv_)
+        {
+            streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase());
+            if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
+                return traits_type::eof();
+        }
+        else
+        {
+            char* __extbe = __extbuf_;
+            codecvt_base::result __r;
+            do
+            {
+                const char_type* __e;
+                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
+                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
+                if (__e == this->pbase())
+                    return traits_type::eof();
+                if (__r == codecvt_base::noconv)
+                {
+                    streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
+                    if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb)
+                        return traits_type::eof();
+                }
+                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+                {
+                    streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_);
+                    if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
+                        return traits_type::eof();
+                    if (__r == codecvt_base::partial)
+                    {
+                        this->setp((char_type*)__e, this->pptr());
+                        this->pbump(this->epptr() - this->pbase());
+                    }
+                }
+                else
+                    return traits_type::eof();
+            } while (__r == codecvt_base::partial);
+        }
+        this->setp(__pb_save, __epb_save);
+    }
+    return traits_type::not_eof(__c);
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+basic_streambuf<_Elem, _Tr>*
+wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n)
+{
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+    if (__owns_eb_)
+        delete [] __extbuf_;
+    if (__owns_ib_)
+        delete [] __intbuf_;
+    __ebs_ = __n;
+    if (__ebs_ > sizeof(__extbuf_min_))
+    {
+        if (__always_noconv_ && __s)
+        {
+            __extbuf_ = (char*)__s;
+            __owns_eb_ = false;
+        }
+        else
+        {
+            __extbuf_ = new char[__ebs_];
+            __owns_eb_ = true;
+        }
+    }
+    else
+    {
+        __extbuf_ = __extbuf_min_;
+        __ebs_ = sizeof(__extbuf_min_);
+        __owns_eb_ = false;
+    }
+    if (!__always_noconv_)
+    {
+        __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
+        if (__s && __ibs_ >= sizeof(__extbuf_min_))
+        {
+            __intbuf_ = __s;
+            __owns_ib_ = false;
+        }
+        else
+        {
+            __intbuf_ = new char_type[__ibs_];
+            __owns_ib_ = true;
+        }
+    }
+    else
+    {
+        __ibs_ = 0;
+        __intbuf_ = 0;
+        __owns_ib_ = false;
+    }
+    return this;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way,
+                                        ios_base::openmode __om)
+{
+    int __width = __cv_->encoding();
+    if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync())
+        return pos_type(off_type(-1));
+    // __width > 0 || __off == 0
+    switch (__way)
+    {
+    case ios_base::beg:
+        break;
+    case ios_base::cur:
+        break;
+    case ios_base::end:
+        break;
+    default:
+        return pos_type(off_type(-1));
+    }
+    pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om);
+    __r.state(__st_);
+    return __r;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type
+wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch)
+{
+    if (__cv_ == 0 || __bufptr_ == 0 || sync())
+        return pos_type(off_type(-1));
+    if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1)))
+        return pos_type(off_type(-1));
+    return __sp;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+int
+wbuffer_convert<_Codecvt, _Elem, _Tr>::sync()
+{
+    if (__cv_ == 0 || __bufptr_ == 0)
+        return 0;
+    if (__cm_ & ios_base::out)
+    {
+        if (this->pptr() != this->pbase())
+            if (overflow() == traits_type::eof())
+                return -1;
+        codecvt_base::result __r;
+        do
+        {
+            char* __extbe;
+            __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
+            streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_);
+            if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb)
+                return -1;
+        } while (__r == codecvt_base::partial);
+        if (__r == codecvt_base::error)
+            return -1;
+        if (__bufptr_->pubsync())
+            return -1;
+    }
+    else if (__cm_ & ios_base::in)
+    {
+        off_type __c;
+        if (__always_noconv_)
+            __c = this->egptr() - this->gptr();
+        else
+        {
+            int __width = __cv_->encoding();
+            __c = __extbufend_ - __extbufnext_;
+            if (__width > 0)
+                __c += __width * (this->egptr() - this->gptr());
+            else
+            {
+                if (this->gptr() != this->egptr())
+                {
+                    reverse(this->gptr(), this->egptr());
+                    codecvt_base::result __r;
+                    const char_type* __e = this->gptr();
+                    char* __extbe;
+                    do
+                    {
+                        __r = __cv_->out(__st_, __e, this->egptr(), __e,
+                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
+                        switch (__r)
+                        {
+                        case codecvt_base::noconv:
+                            __c += this->egptr() - this->gptr();
+                            break;
+                        case codecvt_base::ok:
+                        case codecvt_base::partial:
+                            __c += __extbe - __extbuf_;
+                            break;
+                        default:
+                            return -1;
+                        }
+                    } while (__r == codecvt_base::partial);
+                }
+            }
+        }
+        if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1)))
+            return -1;
+        this->setg(0, 0, 0);
+        __cm_ = 0;
+    }
+    return 0;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+bool
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode()
+{
+    if (!(__cm_ & ios_base::in))
+    {
+        this->setp(0, 0);
+        if (__always_noconv_)
+            this->setg((char_type*)__extbuf_,
+                       (char_type*)__extbuf_ + __ebs_,
+                       (char_type*)__extbuf_ + __ebs_);
+        else
+            this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
+        __cm_ = ios_base::in;
+        return true;
+    }
+    return false;
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+void
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode()
+{
+    if (!(__cm_ & ios_base::out))
+    {
+        this->setg(0, 0, 0);
+        if (__ebs_ > sizeof(__extbuf_min_))
+        {
+            if (__always_noconv_)
+                this->setp((char_type*)__extbuf_,
+                           (char_type*)__extbuf_ + (__ebs_ - 1));
+            else
+                this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
+        }
+        else
+            this->setp(0, 0);
+        __cm_ = ios_base::out;
+    }
+}
+
+template <class _Codecvt, class _Elem, class _Tr>
+wbuffer_convert<_Codecvt, _Elem, _Tr>*
+wbuffer_convert<_Codecvt, _Elem, _Tr>::__close()
+{
+    wbuffer_convert* __rt = 0;
+    if (__cv_ != 0 && __bufptr_ != 0)
+    {
+        __rt = this;
+        if ((__cm_ & ios_base::out) && sync())
+            __rt = 0;
+    }
+    return __rt;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_LOCALE
diff --git a/include/c++/v1/map b/include/c++/v1/map
new file mode 100644
index 0000000..5534e40
--- /dev/null
+++ b/include/c++/v1/map
@@ -0,0 +1,2063 @@
+// -*- C++ -*-
+//===----------------------------- map ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_MAP
+#define _LIBCPP_MAP
+
+/*
+
+    map synopsis
+
+namespace std
+{
+
+template <class Key, class T, class Compare = less<Key>,
+          class Allocator = allocator<pair<const Key, T>>>
+class map
+{
+public:
+    // types:
+    typedef Key                                      key_type;
+    typedef T                                        mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef Compare                                  key_compare;
+    typedef Allocator                                allocator_type;
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    class value_compare
+        : public binary_function<value_type, value_type, bool>
+    {
+        friend class map;
+    protected:
+        key_compare comp;
+
+        value_compare(key_compare c);
+    public:
+        bool operator()(const value_type& x, const value_type& y) const;
+    };
+
+    // construct/copy/destroy:
+    map()
+        noexcept(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value);
+    explicit map(const key_compare& comp);
+    map(const key_compare& comp, const allocator_type& a);
+    template <class InputIterator>
+        map(InputIterator first, InputIterator last,
+            const key_compare& comp = key_compare());
+    template <class InputIterator>
+        map(InputIterator first, InputIterator last,
+            const key_compare& comp, const allocator_type& a);
+    map(const map& m);
+    map(map&& m)
+        noexcept(
+            is_nothrow_move_constructible<allocator_type>::value &&
+            is_nothrow_move_constructible<key_compare>::value);
+    explicit map(const allocator_type& a);
+    map(const map& m, const allocator_type& a);
+    map(map&& m, const allocator_type& a);
+    map(initializer_list<value_type> il, const key_compare& comp = key_compare());
+    map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
+    template <class InputIterator>
+        map(InputIterator first, InputIterator last, const allocator_type& a)
+            : map(first, last, Compare(), a) {}  // C++14
+    map(initializer_list<value_type> il, const allocator_type& a)
+        : map(il, Compare(), a) {}  // C++14
+   ~map();
+
+    map& operator=(const map& m);
+    map& operator=(map&& m)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<key_compare>::value);
+    map& operator=(initializer_list<value_type> il);
+
+    // iterators:
+          iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+          iterator end() noexcept;
+    const_iterator end()   const noexcept;
+
+          reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+          reverse_iterator rend() noexcept;
+    const_reverse_iterator rend()   const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    bool      empty()    const noexcept;
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+
+    // element access:
+    mapped_type& operator[](const key_type& k);
+    mapped_type& operator[](key_type&& k);
+
+          mapped_type& at(const key_type& k);
+    const mapped_type& at(const key_type& k) const;
+
+    // modifiers:
+    template <class... Args>
+        pair<iterator, bool> emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    pair<iterator, bool> insert(const value_type& v);
+    template <class P>
+        pair<iterator, bool> insert(P&& p);
+    iterator insert(const_iterator position, const value_type& v);
+    template <class P>
+        iterator insert(const_iterator position, P&& p);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type> il);
+
+    iterator  erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator  erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(map& m)
+        noexcept(
+            __is_nothrow_swappable<key_compare>::value &&
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value));
+
+    // observers:
+    allocator_type get_allocator() const noexcept;
+    key_compare    key_comp()      const;
+    value_compare  value_comp()    const;
+
+    // map operations:
+          iterator find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);              // C++14
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;
+
+    size_type      count(const key_type& k) const;
+          iterator lower_bound(const key_type& k);
+    const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
+          iterator upper_bound(const key_type& k);
+    const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
+    pair<iterator,iterator>             equal_range(const key_type& k);
+    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
+};
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator==(const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator< (const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator!=(const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator> (const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator>=(const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator<=(const map<Key, T, Compare, Allocator>& x,
+           const map<Key, T, Compare, Allocator>& y);
+
+// specialized algorithms:
+template <class Key, class T, class Compare, class Allocator>
+void
+swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
+    noexcept(noexcept(x.swap(y)));
+
+template <class Key, class T, class Compare = less<Key>,
+          class Allocator = allocator<pair<const Key, T>>>
+class multimap
+{
+public:
+    // types:
+    typedef Key                                      key_type;
+    typedef T                                        mapped_type;
+    typedef pair<const key_type,mapped_type>         value_type;
+    typedef Compare                                  key_compare;
+    typedef Allocator                                allocator_type;
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    class value_compare
+        : public binary_function<value_type,value_type,bool>
+    {
+        friend class multimap;
+    protected:
+        key_compare comp;
+        value_compare(key_compare c);
+    public:
+        bool operator()(const value_type& x, const value_type& y) const;
+    };
+
+    // construct/copy/destroy:
+    multimap()
+        noexcept(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value);
+    explicit multimap(const key_compare& comp);
+    multimap(const key_compare& comp, const allocator_type& a);
+    template <class InputIterator>
+        multimap(InputIterator first, InputIterator last, const key_compare& comp);
+    template <class InputIterator>
+        multimap(InputIterator first, InputIterator last, const key_compare& comp,
+                 const allocator_type& a);
+    multimap(const multimap& m);
+    multimap(multimap&& m)
+        noexcept(
+            is_nothrow_move_constructible<allocator_type>::value &&
+            is_nothrow_move_constructible<key_compare>::value);
+    explicit multimap(const allocator_type& a);
+    multimap(const multimap& m, const allocator_type& a);
+    multimap(multimap&& m, const allocator_type& a);
+    multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());
+    multimap(initializer_list<value_type> il, const key_compare& comp,
+             const allocator_type& a);
+    template <class InputIterator>
+        multimap(InputIterator first, InputIterator last, const allocator_type& a)
+            : multimap(first, last, Compare(), a) {} // C++14
+    multimap(initializer_list<value_type> il, const allocator_type& a)
+        : multimap(il, Compare(), a) {} // C++14
+    ~multimap();
+
+    multimap& operator=(const multimap& m);
+    multimap& operator=(multimap&& m)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<key_compare>::value);
+    multimap& operator=(initializer_list<value_type> il);
+
+    // iterators:
+          iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+          iterator end() noexcept;
+    const_iterator end()   const noexcept;
+
+          reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+          reverse_iterator rend() noexcept;
+    const_reverse_iterator rend()   const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    bool      empty()    const noexcept;
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+
+    // modifiers:
+    template <class... Args>
+        iterator emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    iterator insert(const value_type& v);
+    template <class P>
+        iterator insert(P&& p);
+    iterator insert(const_iterator position, const value_type& v);
+    template <class P>
+        iterator insert(const_iterator position, P&& p);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type> il);
+
+    iterator  erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator  erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(multimap& m)
+        noexcept(
+            __is_nothrow_swappable<key_compare>::value &&
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value));
+
+    // observers:
+    allocator_type get_allocator() const noexcept;
+    key_compare    key_comp()      const;
+    value_compare  value_comp()    const;
+
+    // map operations:
+          iterator find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);              // C++14
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;
+
+    size_type      count(const key_type& k) const;
+          iterator lower_bound(const key_type& k);
+    const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
+          iterator upper_bound(const key_type& k);
+    const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
+    pair<iterator,iterator>             equal_range(const key_type& k);
+    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
+};
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator==(const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator< (const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator!=(const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator> (const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator>=(const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+template <class Key, class T, class Compare, class Allocator>
+bool
+operator<=(const multimap<Key, T, Compare, Allocator>& x,
+           const multimap<Key, T, Compare, Allocator>& y);
+
+// specialized algorithms:
+template <class Key, class T, class Compare, class Allocator>
+void
+swap(multimap<Key, T, Compare, Allocator>& x,
+     multimap<Key, T, Compare, Allocator>& y)
+    noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__tree>
+#include <iterator>
+#include <memory>
+#include <utility>
+#include <functional>
+#include <initializer_list>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
+#if __has_feature(is_final)
+                                                        && !__is_final(_Compare)
+#endif
+         >
+class __map_value_compare
+    : private _Compare
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __map_value_compare()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
+        : _Compare() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_value_compare(_Compare c)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
+        : _Compare(c) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Compare& key_comp() const _NOEXCEPT {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _CP& __x, const _CP& __y) const
+        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _CP& __x, const _Key& __y) const
+        {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Key& __x, const _CP& __y) const
+        {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
+
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () ( const _K2& __x, const _CP& __y ) const
+        {return static_cast<const _Compare&>(*this) (__x, __y.__cc.first);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () (const _CP& __x, const _K2& __y) const
+        {return static_cast<const _Compare&>(*this) (__x.__cc.first, __y);}
+#endif
+};
+
+template <class _Key, class _CP, class _Compare>
+class __map_value_compare<_Key, _CP, _Compare, false>
+{
+    _Compare comp;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __map_value_compare()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
+        : comp() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_value_compare(_Compare c)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
+        : comp(c) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Compare& key_comp() const _NOEXCEPT {return comp;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _CP& __x, const _CP& __y) const
+        {return comp(__x.__cc.first, __y.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _CP& __x, const _Key& __y) const
+        {return comp(__x.__cc.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Key& __x, const _CP& __y) const
+        {return comp(__x, __y.__cc.first);}
+
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () ( const _K2& __x, const _CP& __y ) const
+        {return comp (__x, __y.__cc.first);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type
+    operator () (const _CP& __x, const _K2& __y) const
+        {return comp (__x.__cc.first, __y);}
+#endif
+};
+
+template <class _Allocator>
+class __map_node_destructor
+{
+    typedef _Allocator                          allocator_type;
+    typedef allocator_traits<allocator_type>    __alloc_traits;
+    typedef typename __alloc_traits::value_type::value_type value_type;
+public:
+    typedef typename __alloc_traits::pointer    pointer;
+private:
+    typedef typename value_type::value_type::first_type     first_type;
+    typedef typename value_type::value_type::second_type    second_type;
+
+    allocator_type& __na_;
+
+    __map_node_destructor& operator=(const __map_node_destructor&);
+
+public:
+    bool __first_constructed;
+    bool __second_constructed;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT
+        : __na_(__na),
+          __first_constructed(false),
+          __second_constructed(false)
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT
+        : __na_(__x.__na_),
+          __first_constructed(__x.__value_constructed),
+          __second_constructed(__x.__value_constructed)
+        {
+            __x.__value_constructed = false;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+    {
+        if (__second_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
+        if (__first_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
+        if (__p)
+            __alloc_traits::deallocate(__na_, __p, 1);
+    }
+};
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+    class map;
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+    class multimap;
+template <class _TreeIterator> class __map_const_iterator;
+
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const __value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(const __value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(__value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
+template <class _TreeIterator>
+class _LIBCPP_TYPE_VIS_ONLY __map_iterator
+{
+    _TreeIterator __i_;
+
+    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
+    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
+public:
+    typedef bidirectional_iterator_tag                           iterator_category;
+    typedef pair<__key_type, __mapped_type>                      value_type;
+    typedef typename _TreeIterator::difference_type              difference_type;
+    typedef value_type&                                          reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator() _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __i_->__cc;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator operator++(int)
+    {
+        __map_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator& operator--() {--__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_iterator operator--(int)
+    {
+        __map_iterator __t(*this);
+        --(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __map_iterator& __x, const __map_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend 
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __map_iterator& __x, const __map_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+};
+
+template <class _TreeIterator>
+class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator
+{
+    _TreeIterator __i_;
+
+    typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
+    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
+    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
+public:
+    typedef bidirectional_iterator_tag                           iterator_category;
+    typedef pair<__key_type, __mapped_type>                      value_type;
+    typedef typename _TreeIterator::difference_type              difference_type;
+    typedef const value_type&                                    reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator() _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator(
+            __map_iterator<typename _TreeIterator::__non_const_iterator> __i)
+                _NOEXCEPT
+                : __i_(__i.__i_) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __i_->__cc;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator operator++(int)
+    {
+        __map_const_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator& operator--() {--__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __map_const_iterator operator--(int)
+    {
+        __map_const_iterator __t(*this);
+        --(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
+    template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
+};
+
+template <class _Key, class _Tp, class _Compare = less<_Key>,
+          class _Allocator = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY map
+{
+public:
+    // types:
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+    typedef _Compare                                 key_compare;
+    typedef _Allocator                               allocator_type;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+
+    class _LIBCPP_TYPE_VIS_ONLY value_compare
+        : public binary_function<value_type, value_type, bool>
+    {
+        friend class map;
+    protected:
+        key_compare comp;
+
+        _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {}
+    public:
+        _LIBCPP_INLINE_VISIBILITY
+        bool operator()(const value_type& __x, const value_type& __y) const
+            {return comp(__x.first, __y.first);}
+    };
+
+private:
+
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
+    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                           __allocator_type;
+    typedef __tree<__value_type, __vc, __allocator_type>   __base;
+    typedef typename __base::__node_traits                 __node_traits;
+    typedef allocator_traits<allocator_type>               __alloc_traits;
+
+    __base __tree_;
+
+public:
+    typedef typename __alloc_traits::pointer               pointer;
+    typedef typename __alloc_traits::const_pointer         const_pointer;
+    typedef typename __alloc_traits::size_type             size_type;
+    typedef typename __alloc_traits::difference_type       difference_type;
+    typedef __map_iterator<typename __base::iterator>      iterator;
+    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    map()
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__vc(key_compare())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit map(const key_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__vc(__comp)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit map(const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a) {}
+
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+        map(_InputIterator __f, _InputIterator __l,
+            const key_compare& __comp = key_compare())
+        : __tree_(__vc(__comp))
+        {
+            insert(__f, __l);
+        }
+
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+        map(_InputIterator __f, _InputIterator __l,
+            const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a)
+        {
+            insert(__f, __l);
+        }
+
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY 
+    map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+        : map(__f, __l, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    map(const map& __m)
+        : __tree_(__m.__tree_)
+        {
+            insert(__m.begin(), __m.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    map& operator=(const map& __m)
+        {
+#if __cplusplus >= 201103L
+            __tree_ = __m.__tree_;
+#else
+            if (this != &__m) {
+                __tree_.clear();
+                __tree_.value_comp() = __m.__tree_.value_comp();
+                __tree_.__copy_assign_alloc(__m.__tree_);
+                insert(__m.begin(), __m.end());
+            }
+#endif
+            return *this;
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    map(map&& __m)
+        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
+        : __tree_(_VSTD::move(__m.__tree_))
+        {
+        }
+
+    map(map&& __m, const allocator_type& __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    map& operator=(map&& __m)
+        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
+        {
+            __tree_ = _VSTD::move(__m.__tree_);
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
+        : __tree_(__vc(__comp))
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    map(initializer_list<value_type> __il, const allocator_type& __a)
+        : map(__il, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    map& operator=(initializer_list<value_type> __il)
+        {
+            __tree_.__assign_unique(__il.begin(), __il.end());
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit map(const allocator_type& __a)
+        : __tree_(__a)
+        {
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    map(const map& __m, const allocator_type& __a)
+        : __tree_(__m.__tree_.value_comp(), __a)
+        {
+            insert(__m.begin(), __m.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin() _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT {return __tree_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT {return __tree_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rend() _NOEXCEPT
+            {return       reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const _NOEXCEPT {return __tree_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT {return __tree_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
+
+    mapped_type& operator[](const key_type& __k);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    mapped_type& operator[](key_type&& __k);
+#endif
+
+          mapped_type& at(const key_type& __k);
+    const mapped_type& at(const key_type& __k) const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_compare    key_comp()      const {return __tree_.value_comp().key_comp();}
+    _LIBCPP_INLINE_VISIBILITY
+    value_compare  value_comp()    const {return value_compare(__tree_.value_comp().key_comp());}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class ..._Args>
+        pair<iterator, bool>
+        emplace(_Args&& ...__args);
+
+    template <class ..._Args>
+        iterator
+        emplace_hint(const_iterator __p, _Args&& ...__args);
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        pair<iterator, bool> insert(_Pp&& __p)
+            {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));}
+
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator insert(const_iterator __pos, _Pp&& __p)
+            {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool>
+        insert(const value_type& __v) {return __tree_.__insert_unique(__v);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator
+        insert(const_iterator __p, const value_type& __v)
+            {return __tree_.__insert_unique(__p.__i_, __v);}
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        void insert(_InputIterator __f, _InputIterator __l)
+        {
+            for (const_iterator __e = cend(); __f != __l; ++__f)
+                insert(__e.__i_, *__f);
+        }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k)
+        {return __tree_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __f, const_iterator __l)
+        {return __tree_.erase(__f.__i_, __l.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__tree_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(map& __m)
+        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
+        {__tree_.swap(__m.__tree_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator find(const key_type& __k)             {return __tree_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type      count(const key_type& __k) const
+        {return __tree_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator lower_bound(const key_type& __k)
+        {return __tree_.lower_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator lower_bound(const key_type& __k) const
+        {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator upper_bound(const key_type& __k)
+        {return __tree_.upper_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator upper_bound(const key_type& __k) const
+        {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,iterator> equal_range(const key_type& __k)
+        {return __tree_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
+        {return __tree_.__equal_range_unique(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+#endif
+
+private:
+    typedef typename __base::__node                    __node;
+    typedef typename __base::__node_allocator          __node_allocator;
+    typedef typename __base::__node_pointer            __node_pointer;
+    typedef typename __base::__node_const_pointer      __node_const_pointer;
+    typedef typename __base::__node_base_pointer       __node_base_pointer;
+    typedef typename __base::__node_base_const_pointer __node_base_const_pointer;
+    typedef __map_node_destructor<__node_allocator> _Dp;
+    typedef unique_ptr<__node, _Dp> __node_holder;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node();
+    template <class _A0>
+        __node_holder __construct_node(_A0&& __a0);
+    __node_holder __construct_node_with_key(key_type&& __k);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _A0, class _A1, class ..._Args>
+        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif
+    __node_holder __construct_node_with_key(const key_type& __k);
+
+    __node_base_pointer&
+        __find_equal_key(__node_base_pointer& __parent, const key_type& __k);
+    __node_base_const_pointer
+        __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const;
+};
+
+// Find place to insert if __k doesn't exist
+// Set __parent to parent of null leaf
+// Return reference to null leaf
+// If __k exists, set parent to node of __k and return reference to node of __k
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer&
+map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent,
+                                                       const key_type& __k)
+{
+    __node_pointer __nd = __tree_.__root();
+    if (__nd != nullptr)
+    {
+        while (true)
+        {
+            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
+            {
+                if (__nd->__left_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__left_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__left_;
+                }
+            }
+            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
+            {
+                if (__nd->__right_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__right_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return __parent->__right_;
+                }
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__nd);
+                return __parent;
+            }
+        }
+    }
+    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
+    return __parent->__left_;
+}
+
+// Find __k
+// Set __parent to parent of null leaf and
+//    return reference to null leaf iv __k does not exist.
+// If __k exists, set parent to node of __k and return reference to node of __k
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer
+map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent,
+                                                       const key_type& __k) const
+{
+    __node_const_pointer __nd = __tree_.__root();
+    if (__nd != nullptr)
+    {
+        while (true)
+        {
+            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
+            {
+                if (__nd->__left_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__left_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return const_cast<const __node_base_const_pointer&>(__parent->__left_);
+                }
+            }
+            else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k))
+            {
+                if (__nd->__right_ != nullptr)
+                    __nd = static_cast<__node_pointer>(__nd->__right_);
+                else
+                {
+                    __parent = static_cast<__node_base_pointer>(__nd);
+                    return const_cast<const __node_base_const_pointer&>(__parent->__right_);
+                }
+            }
+            else
+            {
+                __parent = static_cast<__node_base_pointer>(__nd);
+                return __parent;
+            }
+        }
+    }
+    __parent = static_cast<__node_base_pointer>(__tree_.__end_node());
+    return const_cast<const __node_base_const_pointer&>(__parent->__left_);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
+    : __tree_(_VSTD::move(__m.__tree_), __a)
+{
+    if (__a != __m.get_allocator())
+    {
+        const_iterator __e = cend();
+        while (!__m.empty())
+            __tree_.__insert_unique(__e.__i_,
+                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
+    }
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node()
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class _A0>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class _A0, class _A1, class ..._Args>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
+                             _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
+map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+_Tp&
+map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal_key(__parent, __k);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node_with_key(__k);
+        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+    }
+    return __r->__value_.__cc.second;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+_Tp&
+map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal_key(__parent, __k);
+    __node_pointer __r = static_cast<__node_pointer>(__child);
+    if (__child == nullptr)
+    {
+        __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
+        __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
+        __r = __h.release();
+    }
+    return __r->__value_.__cc.second;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+_Tp&
+map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k)
+{
+    __node_base_pointer __parent;
+    __node_base_pointer& __child = __find_equal_key(__parent, __k);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__child == nullptr)
+        throw out_of_range("map::at:  key not found");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return static_cast<__node_pointer>(__child)->__value_.__cc.second;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+const _Tp&
+map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const
+{
+    __node_base_const_pointer __parent;
+    __node_base_const_pointer __child = __find_equal_key(__parent, __k);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__child == nullptr)
+        throw out_of_range("map::at:  key not found");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return static_cast<__node_const_pointer>(__child)->__value_.__cc.second;
+}
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class ..._Args>
+pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool>
+map<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get());
+    if (__r.second)
+        __h.release();
+    return __r;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class ..._Args>
+typename map<_Key, _Tp, _Compare, _Allocator>::iterator
+map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
+                                                   _Args&& ...__args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get());
+    if (__r.__i_.__ptr_ == __h.get())
+        __h.release();
+    return __r;
+}
+
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x,
+           const map<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
+     map<_Key, _Tp, _Compare, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Tp, class _Compare = less<_Key>,
+          class _Allocator = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY multimap
+{
+public:
+    // types:
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+    typedef _Compare                                 key_compare;
+    typedef _Allocator                               allocator_type;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+
+    class _LIBCPP_TYPE_VIS_ONLY value_compare
+        : public binary_function<value_type, value_type, bool>
+    {
+        friend class multimap;
+    protected:
+        key_compare comp;
+
+        _LIBCPP_INLINE_VISIBILITY
+        value_compare(key_compare c) : comp(c) {}
+    public:
+        _LIBCPP_INLINE_VISIBILITY
+        bool operator()(const value_type& __x, const value_type& __y) const
+            {return comp(__x.first, __y.first);}
+    };
+
+private:
+
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
+    typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                                    __allocator_type;
+    typedef __tree<__value_type, __vc, __allocator_type>            __base;
+    typedef typename __base::__node_traits                          __node_traits;
+    typedef allocator_traits<allocator_type>                        __alloc_traits;
+
+    __base __tree_;
+
+public:
+    typedef typename __alloc_traits::pointer               pointer;
+    typedef typename __alloc_traits::const_pointer         const_pointer;
+    typedef typename __alloc_traits::size_type             size_type;
+    typedef typename __alloc_traits::difference_type       difference_type;
+    typedef __map_iterator<typename __base::iterator>      iterator;
+    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap()
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__vc(key_compare())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multimap(const key_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__vc(__comp)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multimap(const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a) {}
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        multimap(_InputIterator __f, _InputIterator __l,
+            const key_compare& __comp = key_compare())
+        : __tree_(__vc(__comp))
+        {
+            insert(__f, __l);
+        }
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        multimap(_InputIterator __f, _InputIterator __l,
+            const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a)
+        {
+            insert(__f, __l);
+        }
+
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY 
+    multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+        : multimap(__f, __l, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap(const multimap& __m)
+        : __tree_(__m.__tree_.value_comp(),
+          __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc()))
+        {
+            insert(__m.begin(), __m.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap& operator=(const multimap& __m)
+        {
+#if __cplusplus >= 201103L
+            __tree_ = __m.__tree_;
+#else
+            if (this != &__m) {
+                __tree_.clear();
+                __tree_.value_comp() = __m.__tree_.value_comp();
+                __tree_.__copy_assign_alloc(__m.__tree_);
+                insert(__m.begin(), __m.end());
+            }
+#endif
+            return *this;
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap(multimap&& __m)
+        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
+        : __tree_(_VSTD::move(__m.__tree_))
+        {
+        }
+
+    multimap(multimap&& __m, const allocator_type& __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap& operator=(multimap&& __m)
+        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
+        {
+            __tree_ = _VSTD::move(__m.__tree_);
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
+        : __tree_(__vc(__comp))
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
+        : __tree_(__vc(__comp), __a)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    multimap(initializer_list<value_type> __il, const allocator_type& __a)
+        : multimap(__il, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap& operator=(initializer_list<value_type> __il)
+        {
+            __tree_.__assign_multi(__il.begin(), __il.end());
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multimap(const allocator_type& __a)
+        : __tree_(__a)
+        {
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multimap(const multimap& __m, const allocator_type& __a)
+        : __tree_(__m.__tree_.value_comp(), __a)
+        {
+            insert(__m.begin(), __m.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin() _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT {return __tree_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT {return __tree_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin()  const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT {return __tree_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_compare    key_comp() const {return __tree_.value_comp().key_comp();}
+    _LIBCPP_INLINE_VISIBILITY
+    value_compare  value_comp() const
+        {return value_compare(__tree_.value_comp().key_comp());}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class ..._Args>
+        iterator
+        emplace(_Args&& ...__args);
+
+    template <class ..._Args>
+        iterator
+        emplace_hint(const_iterator __p, _Args&& ...__args);
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator insert(_Pp&& __p)
+            {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));}
+
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator insert(const_iterator __pos, _Pp&& __p)
+            {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, const value_type& __v)
+            {return __tree_.__insert_multi(__p.__i_, __v);}
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        void insert(_InputIterator __f, _InputIterator __l)
+        {
+            for (const_iterator __e = cend(); __f != __l; ++__f)
+                __tree_.__insert_multi(__e.__i_, *__f);
+        }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __f, const_iterator __l)
+        {return __tree_.erase(__f.__i_, __l.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() {__tree_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(multimap& __m)
+        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
+        {__tree_.swap(__m.__tree_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator find(const key_type& __k)             {return __tree_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type      count(const key_type& __k) const
+        {return __tree_.__count_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator lower_bound(const key_type& __k)
+        {return __tree_.lower_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator lower_bound(const key_type& __k) const
+            {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator upper_bound(const key_type& __k)
+            {return __tree_.upper_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator upper_bound(const key_type& __k) const
+            {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,iterator>             equal_range(const key_type& __k)
+            {return __tree_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
+            {return __tree_.__equal_range_multi(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
+#endif
+
+private:
+    typedef typename __base::__node                    __node;
+    typedef typename __base::__node_allocator          __node_allocator;
+    typedef typename __base::__node_pointer            __node_pointer;
+    typedef typename __base::__node_const_pointer      __node_const_pointer;
+    typedef __map_node_destructor<__node_allocator> _Dp;
+    typedef unique_ptr<__node, _Dp> __node_holder;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node();
+    template <class _A0>
+        __node_holder
+         __construct_node(_A0&& __a0);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _A0, class _A1, class ..._Args>
+        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a)
+    : __tree_(_VSTD::move(__m.__tree_), __a)
+{
+    if (__a != __m.get_allocator())
+    {
+        const_iterator __e = cend();
+        while (!__m.empty())
+            __tree_.__insert_multi(__e.__i_,
+                    _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
+    }
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
+multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node()
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first));
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class _A0>
+typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
+multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class _A0, class _A1, class ..._Args>
+typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder
+multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args)
+{
+    __node_allocator& __na = __tree_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
+                             _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class ..._Args>
+typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
+multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __tree_.__node_insert_multi(__h.get());
+    __h.release();
+    return __r;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+template <class ..._Args>
+typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator
+multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p,
+                                                        _Args&& ...__args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get());
+    __h.release();
+    return __r;
+}
+
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+           const multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Key, class _Tp, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
+     multimap<_Key, _Tp, _Compare, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_MAP
diff --git a/include/c++/v1/memory b/include/c++/v1/memory
new file mode 100644
index 0000000..dc9aeba
--- /dev/null
+++ b/include/c++/v1/memory
@@ -0,0 +1,5429 @@
+// -*- C++ -*-
+//===-------------------------- memory ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_MEMORY
+#define _LIBCPP_MEMORY
+
+/*
+    memory synopsis
+
+namespace std
+{
+
+struct allocator_arg_t { };
+constexpr allocator_arg_t allocator_arg = allocator_arg_t();
+
+template <class T, class Alloc> struct uses_allocator;
+
+template <class Ptr>
+struct pointer_traits
+{
+    typedef Ptr pointer;
+    typedef <details> element_type;
+    typedef <details> difference_type;
+
+    template <class U> using rebind = <details>;
+
+    static pointer pointer_to(<details>);
+};
+
+template <class T>
+struct pointer_traits<T*>
+{
+    typedef T* pointer;
+    typedef T element_type;
+    typedef ptrdiff_t difference_type;
+
+    template <class U> using rebind = U*;
+
+    static pointer pointer_to(<details>) noexcept;
+};
+
+template <class Alloc>
+struct allocator_traits
+{
+    typedef Alloc                        allocator_type;
+    typedef typename allocator_type::value_type
+                                         value_type;
+
+    typedef Alloc::pointer | value_type* pointer;
+    typedef Alloc::const_pointer
+          | pointer_traits<pointer>::rebind<const value_type>
+                                         const_pointer;
+    typedef Alloc::void_pointer
+          | pointer_traits<pointer>::rebind<void>
+                                         void_pointer;
+    typedef Alloc::const_void_pointer
+          | pointer_traits<pointer>::rebind<const void>
+                                         const_void_pointer;
+    typedef Alloc::difference_type
+          | pointer_traits<pointer>::difference_type
+                                         difference_type;
+    typedef Alloc::size_type
+          | make_unsigned<difference_type>::type
+                                         size_type;
+    typedef Alloc::propagate_on_container_copy_assignment
+          | false_type                   propagate_on_container_copy_assignment;
+    typedef Alloc::propagate_on_container_move_assignment
+          | false_type                   propagate_on_container_move_assignment;
+    typedef Alloc::propagate_on_container_swap
+          | false_type                   propagate_on_container_swap;
+
+    template <class T> using rebind_alloc  = Alloc::rebind<U>::other | Alloc<T, Args...>;
+    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
+
+    static pointer allocate(allocator_type& a, size_type n);
+    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint);
+
+    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept;
+
+    template <class T, class... Args>
+        static void construct(allocator_type& a, T* p, Args&&... args);
+
+    template <class T>
+        static void destroy(allocator_type& a, T* p);
+
+    static size_type max_size(const allocator_type& a); // noexcept in C++14
+
+    static allocator_type
+        select_on_container_copy_construction(const allocator_type& a);
+};
+
+template <>
+class allocator<void>
+{
+public:
+    typedef void*                                 pointer;
+    typedef const void*                           const_pointer;
+    typedef void                                  value_type;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+};
+
+template <class T>
+class allocator
+{
+public:
+    typedef size_t                                size_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef T*                                    pointer;
+    typedef const T*                              const_pointer;
+    typedef typename add_lvalue_reference<T>::type       reference;
+    typedef typename add_lvalue_reference<const T>::type const_reference;
+    typedef T                                     value_type;
+
+    template <class U> struct rebind {typedef allocator<U> other;};
+
+    allocator() noexcept;
+    allocator(const allocator&) noexcept;
+    template <class U> allocator(const allocator<U>&) noexcept;
+    ~allocator();
+    pointer address(reference x) const noexcept;
+    const_pointer address(const_reference x) const noexcept;
+    pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
+    void deallocate(pointer p, size_type n) noexcept;
+    size_type max_size() const noexcept;
+    template<class U, class... Args>
+        void construct(U* p, Args&&... args);
+    template <class U>
+        void destroy(U* p);
+};
+
+template <class T, class U>
+bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
+
+template <class T, class U>
+bool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
+
+template <class OutputIterator, class T>
+class raw_storage_iterator
+    : public iterator<output_iterator_tag,
+                      T,                               // purposefully not C++03
+                      ptrdiff_t,                       // purposefully not C++03
+                      T*,                              // purposefully not C++03
+                      raw_storage_iterator&>           // purposefully not C++03
+{
+public:
+    explicit raw_storage_iterator(OutputIterator x);
+    raw_storage_iterator& operator*();
+    raw_storage_iterator& operator=(const T& element);
+    raw_storage_iterator& operator++();
+    raw_storage_iterator  operator++(int);
+};
+
+template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
+template <class T> void               return_temporary_buffer(T* p) noexcept;
+
+template <class T> T* addressof(T& r) noexcept;
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator
+uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
+
+template <class InputIterator, class Size, class ForwardIterator>
+ForwardIterator
+uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
+
+template <class ForwardIterator, class T>
+void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
+
+template <class ForwardIterator, class Size, class T>
+ForwardIterator
+uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
+
+template <class Y> struct auto_ptr_ref {};
+
+template<class X>
+class auto_ptr
+{
+public:
+    typedef X element_type;
+
+    explicit auto_ptr(X* p =0) throw();
+    auto_ptr(auto_ptr&) throw();
+    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
+    auto_ptr& operator=(auto_ptr&) throw();
+    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
+    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
+    ~auto_ptr() throw();
+
+    typename add_lvalue_reference<X>::type operator*() const throw();
+    X* operator->() const throw();
+    X* get() const throw();
+    X* release() throw();
+    void reset(X* p =0) throw();
+
+    auto_ptr(auto_ptr_ref<X>) throw();
+    template<class Y> operator auto_ptr_ref<Y>() throw();
+    template<class Y> operator auto_ptr<Y>() throw();
+};
+
+template <class T>
+struct default_delete
+{
+    constexpr default_delete() noexcept = default;
+    template <class U> default_delete(const default_delete<U>&) noexcept;
+
+    void operator()(T*) const noexcept;
+};
+
+template <class T>
+struct default_delete<T[]>
+{
+    constexpr default_delete() noexcept = default;
+    void operator()(T*) const noexcept;
+    template <class U> void operator()(U*) const = delete;
+};
+
+template <class T, class D = default_delete<T>>
+class unique_ptr
+{
+public:
+    typedef see below pointer;
+    typedef T element_type;
+    typedef D deleter_type;
+
+    // constructors
+    constexpr unique_ptr() noexcept;
+    explicit unique_ptr(pointer p) noexcept;
+    unique_ptr(pointer p, see below d1) noexcept;
+    unique_ptr(pointer p, see below d2) noexcept;
+    unique_ptr(unique_ptr&& u) noexcept;
+    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+    template <class U, class E>
+        unique_ptr(unique_ptr<U, E>&& u) noexcept;
+    template <class U>
+        unique_ptr(auto_ptr<U>&& u) noexcept;
+
+    // destructor
+    ~unique_ptr();
+
+    // assignment
+    unique_ptr& operator=(unique_ptr&& u) noexcept;
+    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
+    unique_ptr& operator=(nullptr_t) noexcept;
+
+    // observers
+    typename add_lvalue_reference<T>::type operator*() const;
+    pointer operator->() const noexcept;
+    pointer get() const noexcept;
+    deleter_type& get_deleter() noexcept;
+    const deleter_type& get_deleter() const noexcept;
+    explicit operator bool() const noexcept;
+
+    // modifiers
+    pointer release() noexcept;
+    void reset(pointer p = pointer()) noexcept;
+    void swap(unique_ptr& u) noexcept;
+};
+
+template <class T, class D>
+class unique_ptr<T[], D>
+{
+public:
+    typedef implementation-defined pointer;
+    typedef T element_type;
+    typedef D deleter_type;
+
+    // constructors
+    constexpr unique_ptr() noexcept;
+    explicit unique_ptr(pointer p) noexcept;
+    unique_ptr(pointer p, see below d) noexcept;
+    unique_ptr(pointer p, see below d) noexcept;
+    unique_ptr(unique_ptr&& u) noexcept;
+    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+
+    // destructor
+    ~unique_ptr();
+
+    // assignment
+    unique_ptr& operator=(unique_ptr&& u) noexcept;
+    unique_ptr& operator=(nullptr_t) noexcept;
+
+    // observers
+    T& operator[](size_t i) const;
+    pointer get() const noexcept;
+    deleter_type& get_deleter() noexcept;
+    const deleter_type& get_deleter() const noexcept;
+    explicit operator bool() const noexcept;
+
+    // modifiers
+    pointer release() noexcept;
+    void reset(pointer p = pointer()) noexcept;
+    void reset(nullptr_t) noexcept;
+    template <class U> void reset(U) = delete;
+    void swap(unique_ptr& u) noexcept;
+};
+
+template <class T, class D>
+    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
+
+template <class T1, class D1, class T2, class D2>
+    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template <class T1, class D1, class T2, class D2>
+    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template <class T1, class D1, class T2, class D2>
+    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template <class T1, class D1, class T2, class D2>
+    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template <class T1, class D1, class T2, class D2>
+    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template <class T1, class D1, class T2, class D2>
+    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+template <class T, class D>
+    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+template <class T, class D>
+    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+template <class T, class D>
+    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+template <class T, class D>
+    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+
+template <class T, class D>
+    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
+template <class T, class D>
+    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
+template <class T, class D>
+    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
+template <class T, class D>
+    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
+template <class T, class D>
+    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
+template <class T, class D>
+    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
+template <class T, class D>
+    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
+template <class T, class D>
+    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
+
+class bad_weak_ptr
+    : public std::exception
+{
+    bad_weak_ptr() noexcept;
+};
+
+template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
+template<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
+template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
+
+template<class T>
+class shared_ptr
+{
+public:
+    typedef T element_type;
+
+    // constructors:
+    constexpr shared_ptr() noexcept;
+    template<class Y> explicit shared_ptr(Y* p);
+    template<class Y, class D> shared_ptr(Y* p, D d);
+    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
+    template <class D> shared_ptr(nullptr_t p, D d);
+    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
+    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
+    shared_ptr(const shared_ptr& r) noexcept;
+    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
+    shared_ptr(shared_ptr&& r) noexcept;
+    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
+    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
+    template<class Y> shared_ptr(auto_ptr<Y>&& r);
+    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
+    shared_ptr(nullptr_t) : shared_ptr() { }
+
+    // destructor:
+    ~shared_ptr();
+
+    // assignment:
+    shared_ptr& operator=(const shared_ptr& r) noexcept;
+    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
+    shared_ptr& operator=(shared_ptr&& r) noexcept;
+    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
+    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r);
+    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
+
+    // modifiers:
+    void swap(shared_ptr& r) noexcept;
+    void reset() noexcept;
+    template<class Y> void reset(Y* p);
+    template<class Y, class D> void reset(Y* p, D d);
+    template<class Y, class D, class A> void reset(Y* p, D d, A a);
+
+    // observers:
+    T* get() const noexcept;
+    T& operator*() const noexcept;
+    T* operator->() const noexcept;
+    long use_count() const noexcept;
+    bool unique() const noexcept;
+    explicit operator bool() const noexcept;
+    template<class U> bool owner_before(shared_ptr<U> const& b) const;
+    template<class U> bool owner_before(weak_ptr<U> const& b) const;
+};
+
+// shared_ptr comparisons:
+template<class T, class U>
+    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+template<class T, class U>
+    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+template<class T, class U>
+    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+template<class T, class U>
+    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+template<class T, class U>
+    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+template<class T, class U>
+    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
+
+template <class T>
+    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
+template <class T>
+    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
+template <class T>
+    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
+template <class T>
+    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
+template <class T>
+    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
+template <class T>
+    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
+template <class T>
+    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
+
+// shared_ptr specialized algorithms:
+template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
+
+// shared_ptr casts:
+template<class T, class U>
+    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
+template<class T, class U>
+    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
+template<class T, class U>
+    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
+
+// shared_ptr I/O:
+template<class E, class T, class Y>
+    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
+
+// shared_ptr get_deleter:
+template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
+
+template<class T, class... Args>
+    shared_ptr<T> make_shared(Args&&... args);
+template<class T, class A, class... Args>
+    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+
+template<class T>
+class weak_ptr
+{
+public:
+    typedef T element_type;
+
+    // constructors
+    constexpr weak_ptr() noexcept;
+    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
+    weak_ptr(weak_ptr const& r) noexcept;
+    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
+    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
+    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
+
+    // destructor
+    ~weak_ptr();
+
+    // assignment
+    weak_ptr& operator=(weak_ptr const& r) noexcept;
+    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
+    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
+    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
+    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
+
+    // modifiers
+    void swap(weak_ptr& r) noexcept;
+    void reset() noexcept;
+
+    // observers
+    long use_count() const noexcept;
+    bool expired() const noexcept;
+    shared_ptr<T> lock() const noexcept;
+    template<class U> bool owner_before(shared_ptr<U> const& b) const;
+    template<class U> bool owner_before(weak_ptr<U> const& b) const;
+};
+
+// weak_ptr specialized algorithms:
+template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
+
+// class owner_less:
+template<class T> struct owner_less;
+
+template<class T>
+struct owner_less<shared_ptr<T>>
+    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
+{
+    typedef bool result_type;
+    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const;
+    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
+    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
+};
+
+template<class T>
+struct owner_less<weak_ptr<T>>
+    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
+{
+    typedef bool result_type;
+    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const;
+    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const;
+    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const;
+};
+
+template<class T>
+class enable_shared_from_this
+{
+protected:
+    constexpr enable_shared_from_this() noexcept;
+    enable_shared_from_this(enable_shared_from_this const&) noexcept;
+    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
+    ~enable_shared_from_this();
+public:
+    shared_ptr<T> shared_from_this();
+    shared_ptr<T const> shared_from_this() const;
+};
+
+template<class T>
+    bool atomic_is_lock_free(const shared_ptr<T>* p);
+template<class T>
+    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
+template<class T>
+    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
+template<class T>
+    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
+template<class T>
+    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
+template<class T>
+    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
+template<class T>
+    shared_ptr<T>
+    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
+template<class T>
+    bool
+    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
+template<class T>
+    bool
+    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
+template<class T>
+    bool
+    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
+                                          shared_ptr<T> w, memory_order success,
+                                          memory_order failure);
+template<class T>
+    bool
+    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
+                                            shared_ptr<T> w, memory_order success,
+                                            memory_order failure);
+// Hash support
+template <class T> struct hash;
+template <class T, class D> struct hash<unique_ptr<T, D> >;
+template <class T> struct hash<shared_ptr<T> >;
+
+// Pointer safety
+enum class pointer_safety { relaxed, preferred, strict };
+void declare_reachable(void *p);
+template <class T> T *undeclare_reachable(T *p);
+void declare_no_pointers(char *p, size_t n);
+void undeclare_no_pointers(char *p, size_t n);
+pointer_safety get_pointer_safety() noexcept;
+
+void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <type_traits>
+#include <typeinfo>
+#include <cstddef>
+#include <cstdint>
+#include <new>
+#include <utility>
+#include <limits>
+#include <iterator>
+#include <__functional_base>
+#include <iosfwd>
+#include <tuple>
+#include <cstring>
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+    #include <cassert>
+#endif
+
+#if __has_feature(cxx_atomic)
+#  include <atomic>
+#endif
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// addressof moved to <__functional_base>
+
+template <class _Tp> class allocator;
+
+template <>
+class _LIBCPP_TYPE_VIS_ONLY allocator<void>
+{
+public:
+    typedef void*             pointer;
+    typedef const void*       const_pointer;
+    typedef void              value_type;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+};
+
+template <>
+class _LIBCPP_TYPE_VIS_ONLY allocator<const void>
+{
+public:
+    typedef const void*       pointer;
+    typedef const void*       const_pointer;
+    typedef const void        value_type;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+};
+
+// pointer_traits
+
+template <class _Tp>
+struct __has_element_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::element_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Ptr, bool = __has_element_type<_Ptr>::value>
+struct __pointer_traits_element_type;
+
+template <class _Ptr>
+struct __pointer_traits_element_type<_Ptr, true>
+{
+    typedef typename _Ptr::element_type type;
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args>
+struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
+{
+    typedef typename _Sp<_Tp, _Args...>::element_type type;
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args>
+struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
+{
+    typedef _Tp type;
+};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class> class _Sp, class _Tp>
+struct __pointer_traits_element_type<_Sp<_Tp>, true>
+{
+    typedef typename _Sp<_Tp>::element_type type;
+};
+
+template <template <class> class _Sp, class _Tp>
+struct __pointer_traits_element_type<_Sp<_Tp>, false>
+{
+    typedef _Tp type;
+};
+
+template <template <class, class> class _Sp, class _Tp, class _A0>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0>, true>
+{
+    typedef typename _Sp<_Tp, _A0>::element_type type;
+};
+
+template <template <class, class> class _Sp, class _Tp, class _A0>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0>, false>
+{
+    typedef _Tp type;
+};
+
+template <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, true>
+{
+    typedef typename _Sp<_Tp, _A0, _A1>::element_type type;
+};
+
+template <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, false>
+{
+    typedef _Tp type;
+};
+
+template <template <class, class, class, class> class _Sp, class _Tp, class _A0,
+                                                           class _A1, class _A2>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, true>
+{
+    typedef typename _Sp<_Tp, _A0, _A1, _A2>::element_type type;
+};
+
+template <template <class, class, class, class> class _Sp, class _Tp, class _A0,
+                                                           class _A1, class _A2>
+struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>
+{
+    typedef _Tp type;
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp>
+struct __has_difference_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::difference_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
+struct __pointer_traits_difference_type
+{
+    typedef ptrdiff_t type;
+};
+
+template <class _Ptr>
+struct __pointer_traits_difference_type<_Ptr, true>
+{
+    typedef typename _Ptr::difference_type type;
+};
+
+template <class _Tp, class _Up>
+struct __has_rebind
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Xp> static __two __test(...);
+    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
+struct __pointer_traits_rebind
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Tp::template rebind<_Up> type;
+#else
+    typedef typename _Tp::template rebind<_Up>::other type;
+#endif
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
+#else
+    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
+{
+    typedef _Sp<_Up, _Args...> type;
+};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class> class _Sp, class _Tp, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp>, _Up, true>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Sp<_Tp>::template rebind<_Up> type;
+#else
+    typedef typename _Sp<_Tp>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class> class _Sp, class _Tp, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp>, _Up, false>
+{
+    typedef _Sp<_Up> type;
+};
+
+template <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, true>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Sp<_Tp, _A0>::template rebind<_Up> type;
+#else
+    typedef typename _Sp<_Tp, _A0>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, false>
+{
+    typedef _Sp<_Up, _A0> type;
+};
+
+template <template <class, class, class> class _Sp, class _Tp, class _A0,
+                                         class _A1, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, true>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up> type;
+#else
+    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class, class> class _Sp, class _Tp, class _A0,
+                                         class _A1, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, false>
+{
+    typedef _Sp<_Up, _A0, _A1> type;
+};
+
+template <template <class, class, class, class> class _Sp, class _Tp, class _A0,
+                                                class _A1, class _A2, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, true>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up> type;
+#else
+    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
+#endif
+};
+
+template <template <class, class, class, class> class _Sp, class _Tp, class _A0,
+                                                class _A1, class _A2, class _Up>
+struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, false>
+{
+    typedef _Sp<_Up, _A0, _A1, _A2> type;
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Ptr>
+struct _LIBCPP_TYPE_VIS_ONLY pointer_traits
+{
+    typedef _Ptr                                                     pointer;
+    typedef typename __pointer_traits_element_type<pointer>::type    element_type;
+    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
+#else
+    template <class _Up> struct rebind
+        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+private:
+    struct __nat {};
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer pointer_to(typename conditional<is_void<element_type>::value,
+                                           __nat, element_type>::type& __r)
+        {return pointer::pointer_to(__r);}
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY pointer_traits<_Tp*>
+{
+    typedef _Tp*      pointer;
+    typedef _Tp       element_type;
+    typedef ptrdiff_t difference_type;
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    template <class _Up> using rebind = _Up*;
+#else
+    template <class _Up> struct rebind {typedef _Up* other;};
+#endif
+
+private:
+    struct __nat {};
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer pointer_to(typename conditional<is_void<element_type>::value,
+                                      __nat, element_type>::type& __r) _NOEXCEPT
+        {return _VSTD::addressof(__r);}
+};
+
+// allocator_traits
+
+namespace __has_pointer_type_imp
+{
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::pointer* = 0);
+}
+
+template <class _Tp>
+struct __has_pointer_type
+    : public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>
+{
+};
+
+namespace __pointer_type_imp
+{
+
+template <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
+struct __pointer_type
+{
+    typedef typename _Dp::pointer type;
+};
+
+template <class _Tp, class _Dp>
+struct __pointer_type<_Tp, _Dp, false>
+{
+    typedef _Tp* type;
+};
+
+}  // __pointer_type_imp
+
+template <class _Tp, class _Dp>
+struct __pointer_type
+{
+    typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
+};
+
+template <class _Tp>
+struct __has_const_pointer
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::const_pointer* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
+struct __const_pointer
+{
+    typedef typename _Alloc::const_pointer type;
+};
+
+template <class _Tp, class _Ptr, class _Alloc>
+struct __const_pointer<_Tp, _Ptr, _Alloc, false>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
+#else
+    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;
+#endif
+};
+
+template <class _Tp>
+struct __has_void_pointer
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::void_pointer* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
+struct __void_pointer
+{
+    typedef typename _Alloc::void_pointer type;
+};
+
+template <class _Ptr, class _Alloc>
+struct __void_pointer<_Ptr, _Alloc, false>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename pointer_traits<_Ptr>::template rebind<void> type;
+#else
+    typedef typename pointer_traits<_Ptr>::template rebind<void>::other type;
+#endif
+};
+
+template <class _Tp>
+struct __has_const_void_pointer
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::const_void_pointer* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
+struct __const_void_pointer
+{
+    typedef typename _Alloc::const_void_pointer type;
+};
+
+template <class _Ptr, class _Alloc>
+struct __const_void_pointer<_Ptr, _Alloc, false>
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    typedef typename pointer_traits<_Ptr>::template rebind<const void> type;
+#else
+    typedef typename pointer_traits<_Ptr>::template rebind<const void>::other type;
+#endif
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+__to_raw_pointer(_Tp* __p) _NOEXCEPT
+{
+    return __p;
+}
+
+template <class _Pointer>
+inline _LIBCPP_INLINE_VISIBILITY
+typename pointer_traits<_Pointer>::element_type*
+__to_raw_pointer(_Pointer __p) _NOEXCEPT
+{
+    return _VSTD::__to_raw_pointer(__p.operator->());
+}
+
+template <class _Tp>
+struct __has_size_type
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::size_type* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
+struct __size_type
+{
+    typedef typename make_unsigned<_DiffType>::type type;
+};
+
+template <class _Alloc, class _DiffType>
+struct __size_type<_Alloc, _DiffType, true>
+{
+    typedef typename _Alloc::size_type type;
+};
+
+template <class _Tp>
+struct __has_propagate_on_container_copy_assignment
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::propagate_on_container_copy_assignment* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
+struct __propagate_on_container_copy_assignment
+{
+    typedef false_type type;
+};
+
+template <class _Alloc>
+struct __propagate_on_container_copy_assignment<_Alloc, true>
+{
+    typedef typename _Alloc::propagate_on_container_copy_assignment type;
+};
+
+template <class _Tp>
+struct __has_propagate_on_container_move_assignment
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::propagate_on_container_move_assignment* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
+struct __propagate_on_container_move_assignment
+{
+    typedef false_type type;
+};
+
+template <class _Alloc>
+struct __propagate_on_container_move_assignment<_Alloc, true>
+{
+    typedef typename _Alloc::propagate_on_container_move_assignment type;
+};
+
+template <class _Tp>
+struct __has_propagate_on_container_swap
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Up> static __two __test(...);
+    template <class _Up> static char __test(typename _Up::propagate_on_container_swap* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
+struct __propagate_on_container_swap
+{
+    typedef false_type type;
+};
+
+template <class _Alloc>
+struct __propagate_on_container_swap<_Alloc, true>
+{
+    typedef typename _Alloc::propagate_on_container_swap type;
+};
+
+template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
+struct __has_rebind_other
+{
+private:
+    struct __two {char __lx; char __lxx;};
+    template <class _Xp> static __two __test(...);
+    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);
+public:
+    static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Tp, class _Up>
+struct __has_rebind_other<_Tp, _Up, false>
+{
+    static const bool value = false;
+};
+
+template <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
+struct __allocator_traits_rebind
+{
+    typedef typename _Tp::template rebind<_Up>::other type;
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
+{
+    typedef typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
+};
+
+template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
+{
+    typedef _Alloc<_Up, _Args...> type;
+};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <template <class> class _Alloc, class _Tp, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>
+{
+    typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;
+};
+
+template <template <class> class _Alloc, class _Tp, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>
+{
+    typedef _Alloc<_Up> type;
+};
+
+template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>
+{
+    typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;
+};
+
+template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>
+{
+    typedef _Alloc<_Up, _A0> type;
+};
+
+template <template <class, class, class> class _Alloc, class _Tp, class _A0,
+                                         class _A1, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>
+{
+    typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;
+};
+
+template <template <class, class, class> class _Alloc, class _Tp, class _A0,
+                                         class _A1, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>
+{
+    typedef _Alloc<_Up, _A0, _A1> type;
+};
+
+template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
+                                                class _A1, class _A2, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>
+{
+    typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
+};
+
+template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
+                                                class _A1, class _A2, class _Up>
+struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>
+{
+    typedef _Alloc<_Up, _A0, _A1, _A2> type;
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+template <class _Alloc, class _SizeType, class _ConstVoidPtr>
+auto
+__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
+    -> decltype(__a.allocate(__sz, __p), true_type());
+
+template <class _Alloc, class _SizeType, class _ConstVoidPtr>
+auto
+__has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
+    -> false_type;
+
+template <class _Alloc, class _SizeType, class _ConstVoidPtr>
+struct __has_allocate_hint
+    : integral_constant<bool,
+        is_same<
+            decltype(__has_allocate_hint_test(declval<_Alloc>(),
+                                          declval<_SizeType>(),
+                                          declval<_ConstVoidPtr>())),
+            true_type>::value>
+{
+};
+
+#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+template <class _Alloc, class _SizeType, class _ConstVoidPtr>
+struct __has_allocate_hint
+    : true_type
+{
+};
+
+#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+#if !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+template <class _Alloc, class _Tp, class ..._Args>
+decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),
+                                           _VSTD::declval<_Args>()...),
+                                           true_type())
+__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);
+
+template <class _Alloc, class _Pointer, class ..._Args>
+false_type
+__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);
+
+template <class _Alloc, class _Pointer, class ..._Args>
+struct __has_construct
+    : integral_constant<bool,
+        is_same<
+            decltype(__has_construct_test(declval<_Alloc>(),
+                                          declval<_Pointer>(),
+                                          declval<_Args>()...)),
+            true_type>::value>
+{
+};
+
+template <class _Alloc, class _Pointer>
+auto
+__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
+    -> decltype(__a.destroy(__p), true_type());
+
+template <class _Alloc, class _Pointer>
+auto
+__has_destroy_test(const _Alloc& __a, _Pointer&& __p)
+    -> false_type;
+
+template <class _Alloc, class _Pointer>
+struct __has_destroy
+    : integral_constant<bool,
+        is_same<
+            decltype(__has_destroy_test(declval<_Alloc>(),
+                                        declval<_Pointer>())),
+            true_type>::value>
+{
+};
+
+template <class _Alloc>
+auto
+__has_max_size_test(_Alloc&& __a)
+    -> decltype(__a.max_size(), true_type());
+
+template <class _Alloc>
+auto
+__has_max_size_test(const volatile _Alloc& __a)
+    -> false_type;
+
+template <class _Alloc>
+struct __has_max_size
+    : integral_constant<bool,
+        is_same<
+            decltype(__has_max_size_test(declval<_Alloc&>())),
+            true_type>::value>
+{
+};
+
+template <class _Alloc>
+auto
+__has_select_on_container_copy_construction_test(_Alloc&& __a)
+    -> decltype(__a.select_on_container_copy_construction(), true_type());
+
+template <class _Alloc>
+auto
+__has_select_on_container_copy_construction_test(const volatile _Alloc& __a)
+    -> false_type;
+
+template <class _Alloc>
+struct __has_select_on_container_copy_construction
+    : integral_constant<bool,
+        is_same<
+            decltype(__has_select_on_container_copy_construction_test(declval<_Alloc&>())),
+            true_type>::value>
+{
+};
+
+#else  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Alloc, class _Pointer, class ..._Args>
+struct __has_construct
+    : false_type
+{
+};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Alloc, class _Pointer, class _Args>
+struct __has_construct
+    : false_type
+{
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Alloc, class _Pointer>
+struct __has_destroy
+    : false_type
+{
+};
+
+template <class _Alloc>
+struct __has_max_size
+    : true_type
+{
+};
+
+template <class _Alloc>
+struct __has_select_on_container_copy_construction
+    : false_type
+{
+};
+
+#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+template <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
+struct __alloc_traits_difference_type
+{
+    typedef typename pointer_traits<_Ptr>::difference_type type;
+};
+
+template <class _Alloc, class _Ptr>
+struct __alloc_traits_difference_type<_Alloc, _Ptr, true>
+{
+    typedef typename _Alloc::difference_type type;
+};
+
+template <class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY allocator_traits
+{
+    typedef _Alloc                              allocator_type;
+    typedef typename allocator_type::value_type value_type;
+
+    typedef typename __pointer_type<value_type, allocator_type>::type pointer;
+    typedef typename __const_pointer<value_type, pointer, allocator_type>::type const_pointer;
+    typedef typename __void_pointer<pointer, allocator_type>::type void_pointer;
+    typedef typename __const_void_pointer<pointer, allocator_type>::type const_void_pointer;
+
+    typedef typename __alloc_traits_difference_type<allocator_type, pointer>::type difference_type;
+    typedef typename __size_type<allocator_type, difference_type>::type size_type;
+
+    typedef typename __propagate_on_container_copy_assignment<allocator_type>::type
+                     propagate_on_container_copy_assignment;
+    typedef typename __propagate_on_container_move_assignment<allocator_type>::type
+                     propagate_on_container_move_assignment;
+    typedef typename __propagate_on_container_swap<allocator_type>::type
+                     propagate_on_container_swap;
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    template <class _Tp> using rebind_alloc =
+                  typename __allocator_traits_rebind<allocator_type, _Tp>::type;
+    template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
+#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+    template <class _Tp> struct rebind_alloc
+        {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;};
+    template <class _Tp> struct rebind_traits
+        {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;};
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer allocate(allocator_type& __a, size_type __n)
+        {return __a.allocate(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
+        {return allocate(__a, __n, __hint,
+            __has_allocate_hint<allocator_type, size_type, const_void_pointer>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
+        {__a.deallocate(__p, __n);}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
+            {__construct(__has_construct<allocator_type, pointer, _Args...>(),
+                         __a, __p, _VSTD::forward<_Args>(__args)...);}
+#else  // _LIBCPP_HAS_NO_VARIADICS
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static void construct(allocator_type& __a, _Tp* __p)
+            {
+                ::new ((void*)__p) _Tp();
+            }
+    template <class _Tp, class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
+            {
+                ::new ((void*)__p) _Tp(__a0);
+            }
+    template <class _Tp, class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0,
+                              const _A1& __a1)
+            {
+                ::new ((void*)__p) _Tp(__a0, __a1);
+            }
+    template <class _Tp, class _A0, class _A1, class _A2>
+        _LIBCPP_INLINE_VISIBILITY
+        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0,
+                              const _A1& __a1, const _A2& __a2)
+            {
+                ::new ((void*)__p) _Tp(__a0, __a1, __a2);
+            }
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static void destroy(allocator_type& __a, _Tp* __p)
+            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type max_size(const allocator_type& __a) _NOEXCEPT
+        {return __max_size(__has_max_size<const allocator_type>(), __a);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static allocator_type
+        select_on_container_copy_construction(const allocator_type& __a)
+            {return select_on_container_copy_construction(
+                __has_select_on_container_copy_construction<const allocator_type>(),
+                __a);}
+
+    template <class _Ptr>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        void
+        __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
+        {
+            for (; __begin1 != __end1; ++__begin1, ++__begin2)
+                construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));
+        }
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            (is_same<allocator_type, allocator<_Tp> >::value
+                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+             is_trivially_move_constructible<_Tp>::value,
+            void
+        >::type
+        __construct_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
+        {
+            ptrdiff_t _Np = __end1 - __begin1;
+            _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
+            __begin2 += _Np;
+        }
+
+    template <class _Ptr>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        void
+        __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)
+        {
+            while (__end1 != __begin1)
+            {
+                construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1));
+                --__end2;
+            }
+        }
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            (is_same<allocator_type, allocator<_Tp> >::value
+                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+             is_trivially_move_constructible<_Tp>::value,
+            void
+        >::type
+        __construct_backward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)
+        {
+            ptrdiff_t _Np = __end1 - __begin1;
+            __end2 -= _Np;
+            _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
+        }
+
+private:
+
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer allocate(allocator_type& __a, size_type __n,
+        const_void_pointer __hint, true_type)
+        {return __a.allocate(__n, __hint);}
+    _LIBCPP_INLINE_VISIBILITY
+    static pointer allocate(allocator_type& __a, size_type __n,
+        const_void_pointer, false_type)
+        {return __a.allocate(__n);}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
+            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
+            {
+                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
+            }
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static void __destroy(true_type, allocator_type& __a, _Tp* __p)
+            {__a.destroy(__p);}
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        static void __destroy(false_type, allocator_type&, _Tp* __p)
+            {
+                __p->~_Tp();
+            }
+
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __max_size(true_type, const allocator_type& __a)
+            {return __a.max_size();}
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __max_size(false_type, const allocator_type&)
+            {return numeric_limits<size_type>::max();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static allocator_type
+        select_on_container_copy_construction(true_type, const allocator_type& __a)
+            {return __a.select_on_container_copy_construction();}
+    _LIBCPP_INLINE_VISIBILITY
+    static allocator_type
+        select_on_container_copy_construction(false_type, const allocator_type& __a)
+            {return __a;}
+};
+
+// allocator
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY allocator
+{
+public:
+    typedef size_t            size_type;
+    typedef ptrdiff_t         difference_type;
+    typedef _Tp*              pointer;
+    typedef const _Tp*        const_pointer;
+    typedef _Tp&              reference;
+    typedef const _Tp&        const_reference;
+    typedef _Tp               value_type;
+
+    typedef true_type propagate_on_container_move_assignment;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+
+    _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
+        {return _VSTD::addressof(__x);}
+    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
+        {return _VSTD::addressof(__x);}
+    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
+        {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));}
+    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
+        {_VSTD::__deallocate((void*)__p);}
+    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
+        {return size_type(~0) / sizeof(_Tp);}
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class _Up, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(_Up* __p, _Args&&... __args)
+        {
+            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
+        }
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p)
+        {
+            ::new((void*)__p) _Tp();
+        }
+# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
+};
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY allocator<const _Tp>
+{
+public:
+    typedef size_t            size_type;
+    typedef ptrdiff_t         difference_type;
+    typedef const _Tp*        pointer;
+    typedef const _Tp*        const_pointer;
+    typedef const _Tp&        reference;
+    typedef const _Tp&        const_reference;
+    typedef const _Tp         value_type;
+
+    typedef true_type propagate_on_container_move_assignment;
+
+    template <class _Up> struct rebind {typedef allocator<_Up> other;};
+
+    _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
+    template <class _Up> _LIBCPP_INLINE_VISIBILITY allocator(const allocator<_Up>&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
+        {return _VSTD::addressof(__x);}
+    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
+        {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));}
+    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
+        {_VSTD::__deallocate((void*)__p);}
+    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
+        {return size_type(~0) / sizeof(_Tp);}
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class _Up, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(_Up* __p, _Args&&... __args)
+        {
+            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
+        }
+#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p)
+        {
+            ::new((void*)__p) _Tp();
+        }
+# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0)
+        {
+            ::new((void*)__p) _Tp(__a0);
+        }
+# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        construct(pointer __p, const _A0& __a0, const _A1& __a1)
+        {
+            ::new((void*)__p) _Tp(__a0, __a1);
+        }
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
+};
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
+
+template <class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
+
+template <class _OutputIterator, class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY raw_storage_iterator
+    : public iterator<output_iterator_tag,
+                      _Tp,                                         // purposefully not C++03
+                      ptrdiff_t,                                   // purposefully not C++03
+                      _Tp*,                                        // purposefully not C++03
+                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
+{
+private:
+    _OutputIterator __x_;
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
+        {::new(&*__x_) _Tp(__element); return *this;}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
+        {raw_storage_iterator __t(*this); ++__x_; return __t;}
+};
+
+template <class _Tp>
+pair<_Tp*, ptrdiff_t>
+get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
+{
+    pair<_Tp*, ptrdiff_t> __r(0, 0);
+    const ptrdiff_t __m = (~ptrdiff_t(0) ^
+                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
+                           / sizeof(_Tp);
+    if (__n > __m)
+        __n = __m;
+    while (__n > 0)
+    {
+        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
+        if (__r.first)
+        {
+            __r.second = __n;
+            break;
+        }
+        __n /= 2;
+    }
+    return __r;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);}
+
+template <class _Tp>
+struct auto_ptr_ref
+{
+    _Tp* __ptr_;
+};
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY auto_ptr
+{
+private:
+    _Tp* __ptr_;
+public:
+    typedef _Tp element_type;
+
+    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) throw() : __ptr_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) throw() : __ptr_(__p.release()) {}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) throw()
+        : __ptr_(__p.release()) {}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) throw()
+        {reset(__p.release()); return *this;}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) throw()
+        {reset(__p.release()); return *this;}
+    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) throw()
+        {reset(__p.__ptr_); return *this;}
+    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() throw() {delete __ptr_;}
+
+    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const throw()
+        {return *__ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const throw() {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* get() const throw() {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY _Tp* release() throw()
+    {
+        _Tp* __t = __ptr_;
+        __ptr_ = 0;
+        return __t;
+    }
+    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) throw()
+    {
+        if (__ptr_ != __p)
+            delete __ptr_;
+        __ptr_ = __p;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) throw() : __ptr_(__p.__ptr_) {}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() throw()
+        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
+    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() throw()
+        {return auto_ptr<_Up>(release());}
+};
+
+template <>
+class _LIBCPP_TYPE_VIS_ONLY auto_ptr<void>
+{
+public:
+    typedef void element_type;
+};
+
+template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type,
+                                                     typename remove_cv<_T2>::type>::value,
+                                bool = is_empty<_T1>::value
+#if __has_feature(is_final)
+                                       && !__is_final(_T1)
+#endif
+                                ,
+                                bool = is_empty<_T2>::value
+#if __has_feature(is_final)
+                                       && !__is_final(_T2)
+#endif
+         >
+struct __libcpp_compressed_pair_switch;
+
+template <class _T1, class _T2, bool IsSame>
+struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, false> {enum {value = 0};};
+
+template <class _T1, class _T2, bool IsSame>
+struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, true, false>  {enum {value = 1};};
+
+template <class _T1, class _T2, bool IsSame>
+struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, true>  {enum {value = 2};};
+
+template <class _T1, class _T2>
+struct __libcpp_compressed_pair_switch<_T1, _T2, false, true, true>    {enum {value = 3};};
+
+template <class _T1, class _T2>
+struct __libcpp_compressed_pair_switch<_T1, _T2, true, true, true>     {enum {value = 1};};
+
+template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
+class __libcpp_compressed_pair_imp;
+
+template <class _T1, class _T2>
+class __libcpp_compressed_pair_imp<_T1, _T2, 0>
+{
+private:
+    _T1 __first_;
+    _T2 __second_;
+public:
+    typedef _T1 _T1_param;
+    typedef _T2 _T2_param;
+
+    typedef typename remove_reference<_T1>::type& _T1_reference;
+    typedef typename remove_reference<_T2>::type& _T2_reference;
+
+    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
+    typedef const typename remove_reference<_T2>::type& _T2_const_reference;
+
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
+        : __first_(_VSTD::forward<_T1_param>(__t1)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
+        : __second_(_VSTD::forward<_T2_param>(__t2)) {}
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
+        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
+
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
+                   is_nothrow_copy_constructible<_T2>::value)
+        : __first_(__p.first()),
+          __second_(__p.second()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
+                   is_nothrow_copy_assignable<_T2>::value)
+        {
+            __first_ = __p.first();
+            __second_ = __p.second();
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : __first_(_VSTD::forward<_T1>(__p.first())),
+          __second_(_VSTD::forward<_T2>(__p.second())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
+                   is_nothrow_move_assignable<_T2>::value)
+        {
+            __first_ = _VSTD::forward<_T1>(__p.first());
+            __second_ = _VSTD::forward<_T2>(__p.second());
+            return *this;
+        }
+
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+        _LIBCPP_INLINE_VISIBILITY
+        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                     tuple<_Args1...> __first_args,
+                                     tuple<_Args2...> __second_args,
+                                     __tuple_indices<_I1...>,
+                                     __tuple_indices<_I2...>)
+            : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
+              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
+            {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
+    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}
+
+    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}
+    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}
+
+    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+    {
+        using _VSTD::swap;
+        swap(__first_, __x.__first_);
+        swap(__second_, __x.__second_);
+    }
+};
+
+template <class _T1, class _T2>
+class __libcpp_compressed_pair_imp<_T1, _T2, 1>
+    : private _T1
+{
+private:
+    _T2 __second_;
+public:
+    typedef _T1 _T1_param;
+    typedef _T2 _T2_param;
+
+    typedef _T1&                                        _T1_reference;
+    typedef typename remove_reference<_T2>::type& _T2_reference;
+
+    typedef const _T1&                                        _T1_const_reference;
+    typedef const typename remove_reference<_T2>::type& _T2_const_reference;
+
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
+        : _T1(_VSTD::forward<_T1_param>(__t1)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
+        : __second_(_VSTD::forward<_T2_param>(__t2)) {}
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
+        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
+
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
+                   is_nothrow_copy_constructible<_T2>::value)
+        : _T1(__p.first()), __second_(__p.second()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
+                   is_nothrow_copy_assignable<_T2>::value)
+        {
+            _T1::operator=(__p.first());
+            __second_ = __p.second();
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : _T1(_VSTD::move(__p.first())), __second_(_VSTD::forward<_T2>(__p.second())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
+                   is_nothrow_move_assignable<_T2>::value)
+        {
+            _T1::operator=(_VSTD::move(__p.first()));
+            __second_ = _VSTD::forward<_T2>(__p.second());
+            return *this;
+        }
+
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+        _LIBCPP_INLINE_VISIBILITY
+        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                     tuple<_Args1...> __first_args,
+                                     tuple<_Args2...> __second_args,
+                                     __tuple_indices<_I1...>,
+                                     __tuple_indices<_I2...>)
+            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
+              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
+            {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return __second_;}
+    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;}
+
+    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+    {
+        using _VSTD::swap;
+        swap(__second_, __x.__second_);
+    }
+};
+
+template <class _T1, class _T2>
+class __libcpp_compressed_pair_imp<_T1, _T2, 2>
+    : private _T2
+{
+private:
+    _T1 __first_;
+public:
+    typedef _T1 _T1_param;
+    typedef _T2 _T2_param;
+
+    typedef typename remove_reference<_T1>::type& _T1_reference;
+    typedef _T2&                                        _T2_reference;
+
+    typedef const typename remove_reference<_T1>::type& _T1_const_reference;
+    typedef const _T2&                                        _T2_const_reference;
+
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
+        : __first_(_VSTD::forward<_T1_param>(__t1)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
+        : _T2(_VSTD::forward<_T2_param>(__t2)) {}
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}
+
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
+                   is_nothrow_copy_constructible<_T2>::value)
+        : _T2(__p.second()), __first_(__p.first()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
+                   is_nothrow_copy_assignable<_T2>::value)
+        {
+            _T2::operator=(__p.second());
+            __first_ = __p.first();
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : _T2(_VSTD::forward<_T2>(__p.second())), __first_(_VSTD::move(__p.first())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
+                   is_nothrow_move_assignable<_T2>::value)
+        {
+            _T2::operator=(_VSTD::forward<_T2>(__p.second()));
+            __first_ = _VSTD::move(__p.first());
+            return *this;
+        }
+
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+        _LIBCPP_INLINE_VISIBILITY
+        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                     tuple<_Args1...> __first_args,
+                                     tuple<_Args2...> __second_args,
+                                     __tuple_indices<_I1...>,
+                                     __tuple_indices<_I2...>)
+            : _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...),
+              __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...)
+              
+            {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
+    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}
+
+    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+    {
+        using _VSTD::swap;
+        swap(__first_, __x.__first_);
+    }
+};
+
+template <class _T1, class _T2>
+class __libcpp_compressed_pair_imp<_T1, _T2, 3>
+    : private _T1,
+      private _T2
+{
+public:
+    typedef _T1 _T1_param;
+    typedef _T2 _T2_param;
+
+    typedef _T1& _T1_reference;
+    typedef _T2& _T2_reference;
+
+    typedef const _T1& _T1_const_reference;
+    typedef const _T2& _T2_const_reference;
+
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
+        : _T1(_VSTD::forward<_T1_param>(__t1)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
+        : _T2(_VSTD::forward<_T2_param>(__t2)) {}
+    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
+        : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}
+
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
+                   is_nothrow_copy_constructible<_T2>::value)
+        : _T1(__p.first()), _T2(__p.second()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
+                   is_nothrow_copy_assignable<_T2>::value)
+        {
+            _T1::operator=(__p.first());
+            _T2::operator=(__p.second());
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : _T1(_VSTD::move(__p.first())), _T2(_VSTD::move(__p.second())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
+                   is_nothrow_move_assignable<_T2>::value)
+        {
+            _T1::operator=(_VSTD::move(__p.first()));
+            _T2::operator=(_VSTD::move(__p.second()));
+            return *this;
+        }
+
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+        _LIBCPP_INLINE_VISIBILITY
+        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                     tuple<_Args1...> __first_args,
+                                     tuple<_Args2...> __second_args,
+                                     __tuple_indices<_I1...>,
+                                     __tuple_indices<_I2...>)
+            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
+              _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
+            {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+    {
+    }
+};
+
+template <class _T1, class _T2>
+class __compressed_pair
+    : private __libcpp_compressed_pair_imp<_T1, _T2>
+{
+    typedef __libcpp_compressed_pair_imp<_T1, _T2> base;
+public:
+    typedef typename base::_T1_param _T1_param;
+    typedef typename base::_T2_param _T2_param;
+
+    typedef typename base::_T1_reference _T1_reference;
+    typedef typename base::_T2_reference _T2_reference;
+
+    typedef typename base::_T1_const_reference _T1_const_reference;
+    typedef typename base::_T2_const_reference _T2_const_reference;
+
+    _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
+    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
+        : base(_VSTD::forward<_T1_param>(__t1)) {}
+    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
+        : base(_VSTD::forward<_T2_param>(__t2)) {}
+    _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
+        : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}
+
+#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair(const __compressed_pair& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value &&
+                   is_nothrow_copy_constructible<_T2>::value)
+        : base(__p) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair& operator=(const __compressed_pair& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value &&
+                   is_nothrow_copy_assignable<_T2>::value)
+        {
+            base::operator=(__p);
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair(__compressed_pair&& __p)
+        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
+                   is_nothrow_move_constructible<_T2>::value)
+        : base(_VSTD::move(__p)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair& operator=(__compressed_pair&& __p)
+        _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value &&
+                   is_nothrow_move_assignable<_T2>::value)
+        {
+            base::operator=(_VSTD::move(__p));
+            return *this;
+        }
+
+#endif  // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args1, class... _Args2>
+        _LIBCPP_INLINE_VISIBILITY
+        __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
+                                                      tuple<_Args2...> __second_args)
+            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
+                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),
+                   typename __make_tuple_indices<sizeof...(_Args2) >::type())
+            {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return base::first();}
+    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return base::first();}
+
+    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return base::second();}
+    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return base::second();}
+
+    _LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+        {base::swap(__x);}
+};
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
+        _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
+                   __is_nothrow_swappable<_T2>::value)
+    {__x.swap(__y);}
+
+// __same_or_less_cv_qualified
+
+template <class _Ptr1, class _Ptr2,
+          bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,
+                         typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type
+                        >::value
+         >
+struct __same_or_less_cv_qualified_imp
+    : is_convertible<_Ptr1, _Ptr2> {};
+
+template <class _Ptr1, class _Ptr2>
+struct __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>
+    : false_type {};
+
+template <class _Ptr1, class _Ptr2, bool = is_pointer<_Ptr1>::value ||
+                                           is_same<_Ptr1, _Ptr2>::value ||
+                                           __has_element_type<_Ptr1>::value>
+struct __same_or_less_cv_qualified
+    : __same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};
+
+template <class _Ptr1, class _Ptr2>
+struct __same_or_less_cv_qualified<_Ptr1, _Ptr2, false>
+    : false_type {};
+
+// default_delete
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY default_delete
+{
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
+#else
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}
+#endif
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up>&,
+             typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY void operator() (_Tp* __ptr) const _NOEXCEPT
+        {
+            static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
+            static_assert(!is_void<_Tp>::value, "default_delete can not delete incomplete type");
+            delete __ptr;
+        }
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY default_delete<_Tp[]>
+{
+public:
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
+#else
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}
+#endif
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY default_delete(const default_delete<_Up[]>&,
+             typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) _NOEXCEPT {}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        void operator() (_Up* __ptr,
+                         typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) const _NOEXCEPT
+        {
+            static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
+            static_assert(!is_void<_Tp>::value, "default_delete can not delete incomplete type");
+            delete [] __ptr;
+        }
+};
+
+template <class _Tp, class _Dp = default_delete<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY unique_ptr
+{
+public:
+    typedef _Tp element_type;
+    typedef _Dp deleter_type;
+    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
+private:
+    __compressed_pair<pointer, deleter_type> __ptr_;
+
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unique_ptr(unique_ptr&);
+    template <class _Up, class _Ep>
+        unique_ptr(unique_ptr<_Up, _Ep>&);
+    unique_ptr& operator=(unique_ptr&);
+    template <class _Up, class _Ep>
+        unique_ptr& operator=(unique_ptr<_Up, _Ep>&);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    struct __nat {int __for_bool_;};
+
+    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;
+    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
+        : __ptr_(pointer())
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT
+        : __ptr_(pointer())
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p) _NOEXCEPT
+        : __ptr_(_VSTD::move(__p))
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename conditional<
+                                        is_reference<deleter_type>::value,
+                                        deleter_type,
+                                        typename add_lvalue_reference<const deleter_type>::type>::type __d)
+             _NOEXCEPT
+        : __ptr_(__p, __d) {}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d)
+             _NOEXCEPT
+        : __ptr_(__p, _VSTD::move(__d))
+        {
+            static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
+        }
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
+        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
+    template <class _Up, class _Ep>
+        _LIBCPP_INLINE_VISIBILITY
+        unique_ptr(unique_ptr<_Up, _Ep>&& __u,
+                   typename enable_if
+                      <
+                        !is_array<_Up>::value &&
+                         is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+                         is_convertible<_Ep, deleter_type>::value &&
+                         (
+                            !is_reference<deleter_type>::value ||
+                            is_same<deleter_type, _Ep>::value
+                         ),
+                         __nat
+                      >::type = __nat()) _NOEXCEPT
+            : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
+
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY unique_ptr(auto_ptr<_Up>&& __p,
+                typename enable_if<
+                                      is_convertible<_Up*, _Tp*>::value &&
+                                      is_same<_Dp, default_delete<_Tp> >::value,
+                                      __nat
+                                  >::type = __nat()) _NOEXCEPT
+            : __ptr_(__p.release())
+            {
+            }
+
+        _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT
+            {
+                reset(__u.release());
+                __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+                return *this;
+            }
+
+        template <class _Up, class _Ep>
+            _LIBCPP_INLINE_VISIBILITY
+            typename enable_if
+            <
+                !is_array<_Up>::value &&
+                is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+                is_assignable<deleter_type&, _Ep&&>::value,
+                unique_ptr&
+            >::type
+            operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+            {
+                reset(__u.release());
+                __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+                return *this;
+            }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY operator __rv<unique_ptr>()
+    {
+        return __rv<unique_ptr>(*this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(__rv<unique_ptr> __u)
+        : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}
+
+    template <class _Up, class _Ep>
+    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr<_Up, _Ep> __u)
+    {
+        reset(__u.release());
+        __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, deleter_type __d)
+        : __ptr_(_VSTD::move(__p), _VSTD::move(__d)) {}
+
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+                typename enable_if<
+                                      is_convertible<_Up*, _Tp*>::value &&
+                                      is_same<_Dp, default_delete<_Tp> >::value,
+                                      unique_ptr&
+                                  >::type
+        operator=(auto_ptr<_Up> __p)
+            {reset(__p.release()); return *this;}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(nullptr_t) _NOEXCEPT
+    {
+        reset();
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator*() const
+        {return *__ptr_.first();}
+    _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return __ptr_.first();}
+    _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();}
+    _LIBCPP_INLINE_VISIBILITY       _Dp_reference get_deleter() _NOEXCEPT
+        {return __ptr_.second();}
+    _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT
+        {return __ptr_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
+        {return __ptr_.first() != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT
+    {
+        pointer __t = __ptr_.first();
+        __ptr_.first() = pointer();
+        return __t;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer()) _NOEXCEPT
+    {
+        pointer __tmp = __ptr_.first();
+        __ptr_.first() = __p;
+        if (__tmp)
+            __ptr_.second()(__tmp);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) _NOEXCEPT
+        {__ptr_.swap(__u.__ptr_);}
+};
+
+template <class _Tp, class _Dp>
+class _LIBCPP_TYPE_VIS_ONLY unique_ptr<_Tp[], _Dp>
+{
+public:
+    typedef _Tp element_type;
+    typedef _Dp deleter_type;
+    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
+private:
+    __compressed_pair<pointer, deleter_type> __ptr_;
+
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unique_ptr(unique_ptr&);
+    template <class _Up>
+        unique_ptr(unique_ptr<_Up>&);
+    unique_ptr& operator=(unique_ptr&);
+    template <class _Up>
+        unique_ptr& operator=(unique_ptr<_Up>&);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    struct __nat {int __for_bool_;};
+
+    typedef       typename remove_reference<deleter_type>::type& _Dp_reference;
+    typedef const typename remove_reference<deleter_type>::type& _Dp_const_reference;
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
+        : __ptr_(pointer())
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT
+        : __ptr_(pointer())
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(_Pp __p,
+            typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat()) _NOEXCEPT
+        : __ptr_(__p)
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, typename conditional<
+                                       is_reference<deleter_type>::value,
+                                       deleter_type,
+                                       typename add_lvalue_reference<const deleter_type>::type>::type __d,
+                                       typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat())
+             _NOEXCEPT
+        : __ptr_(__p, __d) {}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, typename conditional<
+                                       is_reference<deleter_type>::value,
+                                       deleter_type,
+                                       typename add_lvalue_reference<const deleter_type>::type>::type __d)
+             _NOEXCEPT
+        : __ptr_(pointer(), __d) {}
+
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p,
+                                         typename remove_reference<deleter_type>::type&& __d,
+                                         typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, __nat>::type = __nat())
+             _NOEXCEPT
+        : __ptr_(__p, _VSTD::move(__d))
+        {
+            static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
+        }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, typename remove_reference<deleter_type>::type&& __d)
+             _NOEXCEPT
+        : __ptr_(pointer(), _VSTD::move(__d))
+        {
+            static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference");
+        }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
+        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT
+        {
+            reset(__u.release());
+            __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+            return *this;
+        }
+
+    template <class _Up, class _Ep>
+        _LIBCPP_INLINE_VISIBILITY
+        unique_ptr(unique_ptr<_Up, _Ep>&& __u,
+                   typename enable_if
+                            <
+                                is_array<_Up>::value &&
+                                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value
+                                && is_convertible<_Ep, deleter_type>::value &&
+                                (
+                                    !is_reference<deleter_type>::value ||
+                                    is_same<deleter_type, _Ep>::value
+                                ),
+                                __nat
+                            >::type = __nat()
+                  ) _NOEXCEPT
+        : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {}
+
+
+        template <class _Up, class _Ep>
+            _LIBCPP_INLINE_VISIBILITY
+            typename enable_if
+            <
+                is_array<_Up>::value &&
+                __same_or_less_cv_qualified<typename unique_ptr<_Up, _Ep>::pointer, pointer>::value &&
+                is_assignable<deleter_type&, _Ep&&>::value,
+                unique_ptr&
+            >::type
+            operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+            {
+                reset(__u.release());
+                __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+                return *this;
+            }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p)
+        : __ptr_(__p)
+        {
+            static_assert(!is_pointer<deleter_type>::value,
+                "unique_ptr constructed with null function pointer deleter");
+        }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, deleter_type __d)
+        : __ptr_(__p, _VSTD::forward<deleter_type>(__d)) {}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(nullptr_t, deleter_type __d)
+        : __ptr_(pointer(), _VSTD::forward<deleter_type>(__d)) {}
+
+    _LIBCPP_INLINE_VISIBILITY operator __rv<unique_ptr>()
+    {
+        return __rv<unique_ptr>(*this);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr(__rv<unique_ptr> __u)
+        : __ptr_(__u->release(), _VSTD::forward<deleter_type>(__u->get_deleter())) {}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(__rv<unique_ptr> __u)
+    {
+        reset(__u->release());
+        __ptr_.second() = _VSTD::forward<deleter_type>(__u->get_deleter());
+        return *this;
+    }
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
+
+    _LIBCPP_INLINE_VISIBILITY unique_ptr& operator=(nullptr_t) _NOEXCEPT
+    {
+        reset();
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const
+        {return __ptr_.first()[__i];}
+    _LIBCPP_INLINE_VISIBILITY pointer get() const _NOEXCEPT {return __ptr_.first();}
+    _LIBCPP_INLINE_VISIBILITY       _Dp_reference get_deleter() _NOEXCEPT
+        {return __ptr_.second();}
+    _LIBCPP_INLINE_VISIBILITY _Dp_const_reference get_deleter() const _NOEXCEPT
+        {return __ptr_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
+        {return __ptr_.first() != nullptr;}
+
+    _LIBCPP_INLINE_VISIBILITY pointer release() _NOEXCEPT
+    {
+        pointer __t = __ptr_.first();
+        __ptr_.first() = pointer();
+        return __t;
+    }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, void>::type
+    reset(_Pp __p) _NOEXCEPT
+    {
+        pointer __tmp = __ptr_.first();
+        __ptr_.first() = __p;
+        if (__tmp)
+            __ptr_.second()(__tmp);
+    }
+    _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t) _NOEXCEPT
+    {
+        pointer __tmp = __ptr_.first();
+        __ptr_.first() = nullptr;
+        if (__tmp)
+            __ptr_.second()(__tmp);
+    }
+    _LIBCPP_INLINE_VISIBILITY void reset() _NOEXCEPT
+    {
+        pointer __tmp = __ptr_.first();
+        __ptr_.first() = nullptr;
+        if (__tmp)
+            __ptr_.second()(__tmp);
+    }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer())
+    {
+        pointer __tmp = __ptr_.first();
+        __ptr_.first() = __p;
+        if (__tmp)
+            __ptr_.second()(__tmp);
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) {__ptr_.swap(__u.__ptr_);}
+private:
+
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Up>
+        explicit unique_ptr(_Up);
+    template <class _Up>
+        unique_ptr(_Up __u,
+                   typename conditional<
+                                       is_reference<deleter_type>::value,
+                                       deleter_type,
+                                       typename add_lvalue_reference<const deleter_type>::type>::type,
+                   typename enable_if
+                      <
+                         is_convertible<_Up, pointer>::value,
+                         __nat
+                      >::type = __nat());
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+};
+
+template <class _Tp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
+    typedef typename common_type<_P1, _P2>::type _V;
+    return less<_V>()(__x.get(), __y.get());
+}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(__x.get(), nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
+    return less<_P1>()(nullptr, __x.get());
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return nullptr < __x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return __x < nullptr;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(nullptr < __x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(nullptr < __x);
+}
+
+#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+unique_ptr<_Tp, _Dp>
+move(unique_ptr<_Tp, _Dp>& __t)
+{
+    return unique_ptr<_Tp, _Dp>(__rv<unique_ptr<_Tp, _Dp> >(__t));
+}
+
+#endif
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp>
+struct __unique_if
+{
+    typedef unique_ptr<_Tp> __unique_single;
+};
+
+template<class _Tp>
+struct __unique_if<_Tp[]>
+{
+    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
+};
+
+template<class _Tp, size_t _Np>
+struct __unique_if<_Tp[_Np]>
+{
+    typedef void __unique_array_known_bound;
+};
+
+template<class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_single
+make_unique(_Args&&... __args)
+{
+    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique(size_t __n)
+{
+    typedef typename remove_extent<_Tp>::type _Up;
+    return unique_ptr<_Tp>(new _Up[__n]());
+}
+
+template<class _Tp, class... _Args>
+    typename __unique_if<_Tp>::__unique_array_known_bound
+    make_unique(_Args&&...) = delete;
+
+#endif  // _LIBCPP_STD_VER > 11
+
+template <class _Tp> struct hash;
+
+template <class _Size>
+inline _LIBCPP_INLINE_VISIBILITY
+_Size
+__loadword(const void* __p)
+{
+    _Size __r;
+    std::memcpy(&__r, __p, sizeof(__r));
+    return __r;
+}
+
+// We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
+// is 64 bits.  This is because cityhash64 uses 64bit x 64bit
+// multiplication, which can be very slow on 32-bit systems.
+template <class _Size, size_t = sizeof(_Size)*__CHAR_BIT__>
+struct __murmur2_or_cityhash;
+
+template <class _Size>
+struct __murmur2_or_cityhash<_Size, 32>
+{
+    _Size operator()(const void* __key, _Size __len);
+};
+
+// murmur2
+template <class _Size>
+_Size
+__murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len)
+{
+    const _Size __m = 0x5bd1e995;
+    const _Size __r = 24;
+    _Size __h = __len;
+    const unsigned char* __data = static_cast<const unsigned char*>(__key);
+    for (; __len >= 4; __data += 4, __len -= 4)
+    {
+        _Size __k = __loadword<_Size>(__data);
+        __k *= __m;
+        __k ^= __k >> __r;
+        __k *= __m;
+        __h *= __m;
+        __h ^= __k;
+    }
+    switch (__len)
+    {
+    case 3:
+        __h ^= __data[2] << 16;
+    case 2:
+        __h ^= __data[1] << 8;
+    case 1:
+        __h ^= __data[0];
+        __h *= __m;
+    }
+    __h ^= __h >> 13;
+    __h *= __m;
+    __h ^= __h >> 15;
+    return __h;
+}
+
+template <class _Size>
+struct __murmur2_or_cityhash<_Size, 64>
+{
+    _Size operator()(const void* __key, _Size __len);
+
+ private:
+  // Some primes between 2^63 and 2^64.
+  static const _Size __k0 = 0xc3a5c85c97cb3127ULL;
+  static const _Size __k1 = 0xb492b66fbe98f273ULL;
+  static const _Size __k2 = 0x9ae16a3b2f90404fULL;
+  static const _Size __k3 = 0xc949d7c7509e6557ULL;
+
+  static _Size __rotate(_Size __val, int __shift) {
+    return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift)));
+  }
+
+  static _Size __rotate_by_at_least_1(_Size __val, int __shift) {
+    return (__val >> __shift) | (__val << (64 - __shift));
+  }
+
+  static _Size __shift_mix(_Size __val) {
+    return __val ^ (__val >> 47);
+  }
+
+  static _Size __hash_len_16(_Size __u, _Size __v) {
+    const _Size __mul = 0x9ddfea08eb382d69ULL;
+    _Size __a = (__u ^ __v) * __mul;
+    __a ^= (__a >> 47);
+    _Size __b = (__v ^ __a) * __mul;
+    __b ^= (__b >> 47);
+    __b *= __mul;
+    return __b;
+  }
+
+  static _Size __hash_len_0_to_16(const char* __s, _Size __len) {
+    if (__len > 8) {
+      const _Size __a = __loadword<_Size>(__s);
+      const _Size __b = __loadword<_Size>(__s + __len - 8);
+      return __hash_len_16(__a, __rotate_by_at_least_1(__b + __len, __len)) ^ __b;
+    }
+    if (__len >= 4) {
+      const uint32_t __a = __loadword<uint32_t>(__s);
+      const uint32_t __b = __loadword<uint32_t>(__s + __len - 4);
+      return __hash_len_16(__len + (__a << 3), __b);
+    }
+    if (__len > 0) {
+      const unsigned char __a = __s[0];
+      const unsigned char __b = __s[__len >> 1];
+      const unsigned char __c = __s[__len - 1];
+      const uint32_t __y = static_cast<uint32_t>(__a) +
+                           (static_cast<uint32_t>(__b) << 8);
+      const uint32_t __z = __len + (static_cast<uint32_t>(__c) << 2);
+      return __shift_mix(__y * __k2 ^ __z * __k3) * __k2;
+    }
+    return __k2;
+  }
+
+  static _Size __hash_len_17_to_32(const char *__s, _Size __len) {
+    const _Size __a = __loadword<_Size>(__s) * __k1;
+    const _Size __b = __loadword<_Size>(__s + 8);
+    const _Size __c = __loadword<_Size>(__s + __len - 8) * __k2;
+    const _Size __d = __loadword<_Size>(__s + __len - 16) * __k0;
+    return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d,
+                         __a + __rotate(__b ^ __k3, 20) - __c + __len);
+  }
+
+  // Return a 16-byte hash for 48 bytes.  Quick and dirty.
+  // Callers do best to use "random-looking" values for a and b.
+  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
+      _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) {
+    __a += __w;
+    __b = __rotate(__b + __a + __z, 21);
+    const _Size __c = __a;
+    __a += __x;
+    __a += __y;
+    __b += __rotate(__a, 44);
+    return pair<_Size, _Size>(__a + __z, __b + __c);
+  }
+
+  // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
+  static pair<_Size, _Size> __weak_hash_len_32_with_seeds(
+      const char* __s, _Size __a, _Size __b) {
+    return __weak_hash_len_32_with_seeds(__loadword<_Size>(__s),
+                                         __loadword<_Size>(__s + 8),
+                                         __loadword<_Size>(__s + 16),
+                                         __loadword<_Size>(__s + 24),
+                                         __a,
+                                         __b);
+  }
+
+  // Return an 8-byte hash for 33 to 64 bytes.
+  static _Size __hash_len_33_to_64(const char *__s, size_t __len) {
+    _Size __z = __loadword<_Size>(__s + 24);
+    _Size __a = __loadword<_Size>(__s) +
+                (__len + __loadword<_Size>(__s + __len - 16)) * __k0;
+    _Size __b = __rotate(__a + __z, 52);
+    _Size __c = __rotate(__a, 37);
+    __a += __loadword<_Size>(__s + 8);
+    __c += __rotate(__a, 7);
+    __a += __loadword<_Size>(__s + 16);
+    _Size __vf = __a + __z;
+    _Size __vs = __b + __rotate(__a, 31) + __c;
+    __a = __loadword<_Size>(__s + 16) + __loadword<_Size>(__s + __len - 32);
+    __z += __loadword<_Size>(__s + __len - 8);
+    __b = __rotate(__a + __z, 52);
+    __c = __rotate(__a, 37);
+    __a += __loadword<_Size>(__s + __len - 24);
+    __c += __rotate(__a, 7);
+    __a += __loadword<_Size>(__s + __len - 16);
+    _Size __wf = __a + __z;
+    _Size __ws = __b + __rotate(__a, 31) + __c;
+    _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0);
+    return __shift_mix(__r * __k0 + __vs) * __k2;
+  }
+};
+
+// cityhash64
+template <class _Size>
+_Size
+__murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len)
+{
+  const char* __s = static_cast<const char*>(__key);
+  if (__len <= 32) {
+    if (__len <= 16) {
+      return __hash_len_0_to_16(__s, __len);
+    } else {
+      return __hash_len_17_to_32(__s, __len);
+    }
+  } else if (__len <= 64) {
+    return __hash_len_33_to_64(__s, __len);
+  }
+
+  // For strings over 64 bytes we hash the end first, and then as we
+  // loop we keep 56 bytes of state: v, w, x, y, and z.
+  _Size __x = __loadword<_Size>(__s + __len - 40);
+  _Size __y = __loadword<_Size>(__s + __len - 16) +
+              __loadword<_Size>(__s + __len - 56);
+  _Size __z = __hash_len_16(__loadword<_Size>(__s + __len - 48) + __len,
+                          __loadword<_Size>(__s + __len - 24));
+  pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
+  pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
+  __x = __x * __k1 + __loadword<_Size>(__s);
+
+  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
+  __len = (__len - 1) & ~static_cast<_Size>(63);
+  do {
+    __x = __rotate(__x + __y + __v.first + __loadword<_Size>(__s + 8), 37) * __k1;
+    __y = __rotate(__y + __v.second + __loadword<_Size>(__s + 48), 42) * __k1;
+    __x ^= __w.second;
+    __y += __v.first + __loadword<_Size>(__s + 40);
+    __z = __rotate(__z + __w.first, 33) * __k1;
+    __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first);
+    __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second,
+                                        __y + __loadword<_Size>(__s + 16));
+    std::swap(__z, __x);
+    __s += 64;
+    __len -= 64;
+  } while (__len != 0);
+  return __hash_len_16(
+      __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z,
+      __hash_len_16(__v.second, __w.second) + __x);
+}
+
+template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)>
+struct __scalar_hash;
+
+template <class _Tp>
+struct __scalar_hash<_Tp, 0>
+    : public unary_function<_Tp, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp    __t;
+            size_t __a;
+        } __u;
+        __u.__a = 0;
+        __u.__t = __v;
+        return __u.__a;
+    }
+};
+
+template <class _Tp>
+struct __scalar_hash<_Tp, 1>
+    : public unary_function<_Tp, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp    __t;
+            size_t __a;
+        } __u;
+        __u.__t = __v;
+        return __u.__a;
+    }
+};
+
+template <class _Tp>
+struct __scalar_hash<_Tp, 2>
+    : public unary_function<_Tp, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+            };
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+template <class _Tp>
+struct __scalar_hash<_Tp, 3>
+    : public unary_function<_Tp, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+            };
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+template <class _Tp>
+struct __scalar_hash<_Tp, 4>
+    : public unary_function<_Tp, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp __t;
+            struct
+            {
+                size_t __a;
+                size_t __b;
+                size_t __c;
+                size_t __d;
+            };
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+template<class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash<_Tp*>
+    : public unary_function<_Tp*, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(_Tp* __v) const _NOEXCEPT
+    {
+        union
+        {
+            _Tp* __t;
+            size_t __a;
+        } __u;
+        __u.__t = __v;
+        return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
+    }
+};
+
+template <class _Tp, class _Dp>
+struct _LIBCPP_TYPE_VIS_ONLY hash<unique_ptr<_Tp, _Dp> >
+{
+    typedef unique_ptr<_Tp, _Dp> argument_type;
+    typedef size_t               result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
+    {
+        typedef typename argument_type::pointer pointer;
+        return hash<pointer>()(__ptr.get());
+    }
+};
+
+struct __destruct_n
+{
+private:
+    size_t size;
+
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
+        {for (size_t __i = 0; __i < size; ++__i, ++__p) __p->~_Tp();}
+
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
+        {++size;}
+    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
+        {size = __s;}
+    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
+        {}
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
+        : size(__s) {}
+
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void __incr(_Tp*) _NOEXCEPT
+        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
+
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
+        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
+
+    template <class _Tp>
+    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
+        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
+};
+
+template <class _Alloc>
+class __allocator_destructor
+{
+    typedef allocator_traits<_Alloc> __alloc_traits;
+public:
+    typedef typename __alloc_traits::pointer pointer;
+    typedef typename __alloc_traits::size_type size_type;
+private:
+    _Alloc& __alloc_;
+    size_type __s_;
+public:
+    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
+             _NOEXCEPT
+        : __alloc_(__a), __s_(__s) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
+};
+
+template <class _InputIterator, class _ForwardIterator>
+_ForwardIterator
+uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __r;
+    try
+    {
+#endif
+        for (; __f != __l; ++__f, ++__r)
+            ::new(&*__r) value_type(*__f);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __r; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __r;
+}
+
+template <class _InputIterator, class _Size, class _ForwardIterator>
+_ForwardIterator
+uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __r;
+    try
+    {
+#endif
+        for (; __n > 0; ++__f, ++__r, --__n)
+            ::new(&*__r) value_type(*__f);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __r; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __r;
+}
+
+template <class _ForwardIterator, class _Tp>
+void
+uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __f;
+    try
+    {
+#endif
+        for (; __f != __l; ++__f)
+            ::new(&*__f) value_type(__x);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __f; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+}
+
+template <class _ForwardIterator, class _Size, class _Tp>
+_ForwardIterator
+uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
+{
+    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    _ForwardIterator __s = __f;
+    try
+    {
+#endif
+        for (; __n > 0; ++__f, --__n)
+            ::new(&*__f) value_type(__x);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        for (; __s != __f; ++__s)
+            __s->~value_type();
+        throw;
+    }
+#endif
+    return __f;
+}
+
+class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
+    : public std::exception
+{
+public:
+    virtual ~bad_weak_ptr() _NOEXCEPT;
+    virtual const char* what() const  _NOEXCEPT;
+};
+
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
+
+class _LIBCPP_TYPE_VIS __shared_count
+{
+    __shared_count(const __shared_count&);
+    __shared_count& operator=(const __shared_count&);
+
+protected:
+    long __shared_owners_;
+    virtual ~__shared_count();
+private:
+    virtual void __on_zero_shared() _NOEXCEPT = 0;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __shared_count(long __refs = 0) _NOEXCEPT
+        : __shared_owners_(__refs) {}
+
+    void __add_shared() _NOEXCEPT;
+    bool __release_shared() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {return __shared_owners_ + 1;}
+};
+
+class _LIBCPP_TYPE_VIS __shared_weak_count
+    : private __shared_count
+{
+    long __shared_weak_owners_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
+        : __shared_count(__refs),
+          __shared_weak_owners_(__refs) {}
+protected:
+    virtual ~__shared_weak_count();
+
+public:
+    void __add_shared() _NOEXCEPT;
+    void __add_weak() _NOEXCEPT;
+    void __release_shared() _NOEXCEPT;
+    void __release_weak() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
+    __shared_weak_count* lock() _NOEXCEPT;
+
+    // Define the function out only if we build static libc++ without RTTI.
+    // Otherwise we may break clients who need to compile their projects with
+    // -fno-rtti and yet link against a libc++.dylib compiled
+    // without -fno-rtti.
+#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
+    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
+#endif
+private:
+    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
+};
+
+template <class _Tp, class _Dp, class _Alloc>
+class __shared_ptr_pointer
+    : public __shared_weak_count
+{
+    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
+        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
+
+#ifndef _LIBCPP_NO_RTTI
+    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
+#endif
+
+private:
+    virtual void __on_zero_shared() _NOEXCEPT;
+    virtual void __on_zero_shared_weak() _NOEXCEPT;
+};
+
+#ifndef _LIBCPP_NO_RTTI
+
+template <class _Tp, class _Dp, class _Alloc>
+const void*
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
+{
+    return __t == typeid(_Dp) ? &__data_.first().second() : 0;
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template <class _Tp, class _Dp, class _Alloc>
+void
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    __data_.first().second()(__data_.first().first());
+    __data_.first().second().~_Dp();
+}
+
+template <class _Tp, class _Dp, class _Alloc>
+void
+__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
+{
+    typename _Alloc::template rebind<__shared_ptr_pointer>::other __a(__data_.second());
+    __data_.second().~_Alloc();
+    __a.deallocate(this, 1);
+}
+
+template <class _Tp, class _Alloc>
+class __shared_ptr_emplace
+    : public __shared_weak_count
+{
+    __compressed_pair<_Alloc, _Tp> __data_;
+public:
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY
+    __shared_ptr_emplace(_Alloc __a)
+        :  __data_(_VSTD::move(__a)) {}
+
+    template <class ..._Args>
+        _LIBCPP_INLINE_VISIBILITY
+        __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
+            :  __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
+                   _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)) {}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+    _LIBCPP_INLINE_VISIBILITY
+    __shared_ptr_emplace(_Alloc __a)
+        :  __data_(__a) {}
+
+    template <class _A0>
+        _LIBCPP_INLINE_VISIBILITY
+        __shared_ptr_emplace(_Alloc __a, _A0& __a0)
+            :  __data_(__a, _Tp(__a0)) {}
+
+    template <class _A0, class _A1>
+        _LIBCPP_INLINE_VISIBILITY
+        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1)
+            :  __data_(__a, _Tp(__a0, __a1)) {}
+
+    template <class _A0, class _A1, class _A2>
+        _LIBCPP_INLINE_VISIBILITY
+        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1, _A2& __a2)
+            :  __data_(__a, _Tp(__a0, __a1, __a2)) {}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+private:
+    virtual void __on_zero_shared() _NOEXCEPT;
+    virtual void __on_zero_shared_weak() _NOEXCEPT;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp* get() _NOEXCEPT {return &__data_.second();}
+};
+
+template <class _Tp, class _Alloc>
+void
+__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT
+{
+    __data_.second().~_Tp();
+}
+
+template <class _Tp, class _Alloc>
+void
+__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
+{
+    typename _Alloc::template rebind<__shared_ptr_emplace>::other __a(__data_.first());
+    __data_.first().~_Alloc();
+    __a.deallocate(this, 1);
+}
+
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this;
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY shared_ptr
+{
+public:
+    typedef _Tp element_type;
+private:
+    element_type*      __ptr_;
+    __shared_weak_count* __cntrl_;
+
+    struct __nat {int __for_bool_;};
+public:
+    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
+    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
+    template<class _Yp>
+        explicit shared_ptr(_Yp* __p,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+    template<class _Yp, class _Dp>
+        shared_ptr(_Yp* __p, _Dp __d,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+    template<class _Yp, class _Dp, class _Alloc>
+        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
+    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
+    template<class _Yp> shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
+    shared_ptr(const shared_ptr& __r) _NOEXCEPT;
+    template<class _Yp>
+        shared_ptr(const shared_ptr<_Yp>& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())
+                       _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
+    template<class _Yp> shared_ptr(shared_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type = __nat())
+                       _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type= __nat());
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template<class _Yp>
+        shared_ptr(auto_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+#else
+    template<class _Yp>
+        shared_ptr(auto_ptr<_Yp> __r,
+                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
+#endif
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>&&,
+                   typename enable_if
+                   <
+                       !is_lvalue_reference<_Dp>::value &&
+                       !is_array<_Yp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>&&,
+                   typename enable_if
+                   <
+                       is_lvalue_reference<_Dp>::value &&
+                       !is_array<_Yp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>,
+                   typename enable_if
+                   <
+                       !is_lvalue_reference<_Dp>::value &&
+                       !is_array<_Yp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+    template <class _Yp, class _Dp>
+        shared_ptr(unique_ptr<_Yp, _Dp>,
+                   typename enable_if
+                   <
+                       is_lvalue_reference<_Dp>::value &&
+                       !is_array<_Yp>::value &&
+                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                       __nat
+                   >::type = __nat());
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    ~shared_ptr();
+
+    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr&
+        >::type
+        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr<_Tp>&
+        >::type
+        operator=(shared_ptr<_Yp>&& __r);
+    template<class _Yp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr
+        >::type&
+        operator=(auto_ptr<_Yp>&& __r);
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template<class _Yp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<_Yp*, element_type*>::value,
+            shared_ptr&
+        >::type
+        operator=(auto_ptr<_Yp> __r);
+#endif
+    template <class _Yp, class _Dp>
+        typename enable_if
+        <
+            !is_array<_Yp>::value &&
+            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+            shared_ptr&
+        >::type
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        operator=(unique_ptr<_Yp, _Dp>&& __r);
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        operator=(unique_ptr<_Yp, _Dp> __r);
+#endif
+
+    void swap(shared_ptr& __r) _NOEXCEPT;
+    void reset() _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p);
+    template<class _Yp, class _Dp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p, _Dp __d);
+    template<class _Yp, class _Dp, class _Alloc>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            void
+        >::type
+        reset(_Yp* __p, _Dp __d, _Alloc __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    element_type* get() const _NOEXCEPT {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
+        {return *__ptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    element_type* operator->() const _NOEXCEPT {return __ptr_;}
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool unique() const _NOEXCEPT {return use_count() == 1;}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != 0;}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(shared_ptr<_Up> const& __p) const
+        {return __cntrl_ < __p.__cntrl_;}
+    template <class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(weak_ptr<_Up> const& __p) const
+        {return __cntrl_ < __p.__cntrl_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool
+    __owner_equivalent(const shared_ptr& __p) const
+        {return __cntrl_ == __p.__cntrl_;}
+
+#ifndef _LIBCPP_NO_RTTI
+    template <class _Dp>
+        _LIBCPP_INLINE_VISIBILITY
+        _Dp* __get_deleter() const _NOEXCEPT
+            {return (_Dp*)(__cntrl_ ? __cntrl_->__get_deleter(typeid(_Dp)) : 0);}
+#endif  // _LIBCPP_NO_RTTI
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template<class ..._Args>
+        static
+        shared_ptr<_Tp>
+        make_shared(_Args&& ...__args);
+
+    template<class _Alloc, class ..._Args>
+        static
+        shared_ptr<_Tp>
+        allocate_shared(const _Alloc& __a, _Args&& ...__args);
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+    static shared_ptr<_Tp> make_shared();
+
+    template<class _A0>
+        static shared_ptr<_Tp> make_shared(_A0&);
+
+    template<class _A0, class _A1>
+        static shared_ptr<_Tp> make_shared(_A0&, _A1&);
+
+    template<class _A0, class _A1, class _A2>
+        static shared_ptr<_Tp> make_shared(_A0&, _A1&, _A2&);
+
+    template<class _Alloc>
+        static shared_ptr<_Tp>
+        allocate_shared(const _Alloc& __a);
+
+    template<class _Alloc, class _A0>
+        static shared_ptr<_Tp>
+        allocate_shared(const _Alloc& __a, _A0& __a0);
+
+    template<class _Alloc, class _A0, class _A1>
+        static shared_ptr<_Tp>
+        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1);
+
+    template<class _Alloc, class _A0, class _A1, class _A2>
+        static shared_ptr<_Tp>
+        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2);
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+private:
+
+    template <class _Yp>
+        _LIBCPP_INLINE_VISIBILITY
+        void
+        __enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT
+        {
+            if (__e)
+                __e->__weak_this_ = *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __enable_weak_this(const void*) _NOEXCEPT {}
+
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
+};
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+shared_ptr<_Tp>::shared_ptr() _NOEXCEPT
+    : __ptr_(0),
+      __cntrl_(0)
+{
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
+    : __ptr_(0),
+      __cntrl_(0)
+{
+}
+
+template<class _Tp>
+template<class _Yp>
+shared_ptr<_Tp>::shared_ptr(_Yp* __p,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__p)
+{
+    unique_ptr<_Yp> __hold(__p);
+    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
+    __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>());
+    __hold.release();
+    __enable_weak_this(__p);
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp>
+shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;
+        __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Yp>());
+        __enable_weak_this(__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Dp>
+shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
+    : __ptr_(0)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<nullptr_t, _Dp, allocator<_Tp> > _CntrlBlk;
+        __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Tp>());
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp, class _Alloc>
+shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__p)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
+        typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+        typedef __allocator_destructor<_A2> _D2;
+        _A2 __a2(__a);
+        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+        ::new(__hold2.get()) _CntrlBlk(__p, __d, __a);
+        __cntrl_ = __hold2.release();
+        __enable_weak_this(__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Dp, class _Alloc>
+shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
+    : __ptr_(0)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
+        typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+        typedef __allocator_destructor<_A2> _D2;
+        _A2 __a2(__a);
+        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+        ::new(__hold2.get()) _CntrlBlk(__p, __d, __a);
+        __cntrl_ = __hold2.release();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __d(__p);
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
+    : __ptr_(__p),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
+                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_shared();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
+                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+template<class _Yp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
+#else
+shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,
+#endif
+                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
+    : __ptr_(__r.get())
+{
+    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
+    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
+    __enable_weak_this(__r.get());
+    __r.release();
+}
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
+#else
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
+#endif
+                            typename enable_if
+                            <
+                                !is_lvalue_reference<_Dp>::value &&
+                                !is_array<_Yp>::value &&
+                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                                __nat
+                            >::type)
+    : __ptr_(__r.get())
+{
+    typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;
+    __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>());
+    __enable_weak_this(__r.get());
+    __r.release();
+}
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
+#else
+shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
+#endif
+                            typename enable_if
+                            <
+                                is_lvalue_reference<_Dp>::value &&
+                                !is_array<_Yp>::value &&
+                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
+                                __nat
+                            >::type)
+    : __ptr_(__r.get())
+{
+    typedef __shared_ptr_pointer<_Yp*,
+                                 reference_wrapper<typename remove_reference<_Dp>::type>,
+                                 allocator<_Yp> > _CntrlBlk;
+    __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>());
+    __enable_weak_this(__r.get());
+    __r.release();
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp>
+template<class ..._Args>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::make_shared(_Args&& ...__args)
+{
+    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
+    typedef allocator<_CntrlBlk> _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a2;
+    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _Alloc, class ..._Args>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
+{
+    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
+    typedef typename _Alloc::template rebind<_CntrlBlk>::other _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a2(__a);
+    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::make_shared()
+{
+    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
+    typedef allocator<_CntrlBlk> _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2;
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__alloc2);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _A0>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::make_shared(_A0& __a0)
+{
+    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
+    typedef allocator<_CntrlBlk> _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2;
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _A0, class _A1>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1)
+{
+    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
+    typedef allocator<_CntrlBlk> _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2;
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _A0, class _A1, class _A2>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2)
+{
+    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
+    typedef allocator<_CntrlBlk> _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2;
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1, __a2);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _Alloc>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::allocate_shared(const _Alloc& __a)
+{
+    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
+    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2(__a);
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _Alloc, class _A0>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0)
+{
+    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
+    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2(__a);
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a, __a0);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _Alloc, class _A0, class _A1>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
+{
+    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
+    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2(__a);
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+template<class _Tp>
+template<class _Alloc, class _A0, class _A1, class _A2>
+shared_ptr<_Tp>
+shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
+    typedef typename _Alloc::template rebind<_CntrlBlk>::other _Alloc2;
+    typedef __allocator_destructor<_Alloc2> _D2;
+    _Alloc2 __alloc2(__a);
+    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
+    ::new(__hold2.get()) _CntrlBlk(__a, __a0, __a1, __a2);
+    shared_ptr<_Tp> __r;
+    __r.__ptr_ = __hold2.get()->get();
+    __r.__cntrl_ = __hold2.release();
+    __r.__enable_weak_this(__r.__ptr_);
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp>
+shared_ptr<_Tp>::~shared_ptr()
+{
+    if (__cntrl_)
+        __cntrl_->__release_shared();
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>&
+shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
+{
+    shared_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
+{
+    shared_ptr(__r).swap(*this);
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>&
+shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>
+>::type&
+shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<_Yp*, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(auto_ptr<_Yp> __r)
+{
+    shared_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template <class _Yp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Yp>::value &&
+    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, _Tp*>::value,
+    shared_ptr<_Tp>&
+>::type
+shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp> __r)
+{
+    shared_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
+{
+    _VSTD::swap(__ptr_, __r.__ptr_);
+    _VSTD::swap(__cntrl_, __r.__cntrl_);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+shared_ptr<_Tp>::reset() _NOEXCEPT
+{
+    shared_ptr().swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p)
+{
+    shared_ptr(__p).swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
+{
+    shared_ptr(__p, __d).swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp, class _Dp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    void
+>::type
+shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
+{
+    shared_ptr(__p, __d, __a).swap(*this);
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Tp>::value,
+    shared_ptr<_Tp>
+>::type
+make_shared(_Args&& ...__args)
+{
+    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
+}
+
+template<class _Tp, class _Alloc, class ..._Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Tp>::value,
+    shared_ptr<_Tp>
+>::type
+allocate_shared(const _Alloc& __a, _Args&& ...__args)
+{
+    return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);
+}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+make_shared()
+{
+    return shared_ptr<_Tp>::make_shared();
+}
+
+template<class _Tp, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+make_shared(_A0& __a0)
+{
+    return shared_ptr<_Tp>::make_shared(__a0);
+}
+
+template<class _Tp, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+make_shared(_A0& __a0, _A1& __a1)
+{
+    return shared_ptr<_Tp>::make_shared(__a0, __a1);
+}
+
+template<class _Tp, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+make_shared(_A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return shared_ptr<_Tp>::make_shared(__a0, __a1, __a2);
+}
+
+template<class _Tp, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a)
+{
+    return shared_ptr<_Tp>::allocate_shared(__a);
+}
+
+template<class _Tp, class _Alloc, class _A0>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, _A0& __a0)
+{
+    return shared_ptr<_Tp>::allocate_shared(__a, __a0);
+}
+
+template<class _Tp, class _Alloc, class _A0, class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
+{
+    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1);
+}
+
+template<class _Tp, class _Alloc, class _A0, class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
+{
+    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1, __a2);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return __x.get() == __y.get();
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__x == __y);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    typedef typename common_type<_Tp*, _Up*>::type _V;
+    return less<_V>()(__x.get(), __y.get());
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return __y < __x;
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__y < __x);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
+{
+    return !(__x < __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return less<_Tp*>()(__x.get(), nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return less<_Tp*>()(nullptr, __x.get());
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return nullptr < __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return __x < nullptr;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(nullptr < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
+{
+    return !(__x < nullptr);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
+{
+    return !(nullptr < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Tp>::value && !is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
+static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
+}
+
+template<class _Tp, class _Up>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_array<_Tp>::value && !is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
+dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    _Tp* __p = dynamic_cast<_Tp*>(__r.get());
+    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
+}
+
+template<class _Tp, class _Up>
+typename enable_if
+<
+    is_array<_Tp>::value == is_array<_Up>::value,
+    shared_ptr<_Tp>
+>::type
+const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
+{
+    typedef typename remove_extent<_Tp>::type _RTp;
+    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
+}
+
+#ifndef _LIBCPP_NO_RTTI
+
+template<class _Dp, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Dp*
+get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
+{
+    return __p.template __get_deleter<_Dp>();
+}
+
+#endif  // _LIBCPP_NO_RTTI
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY weak_ptr
+{
+public:
+    typedef _Tp element_type;
+private:
+    element_type*        __ptr_;
+    __shared_weak_count* __cntrl_;
+
+public:
+    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
+    template<class _Yp> weak_ptr(shared_ptr<_Yp> const& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                        _NOEXCEPT;
+    weak_ptr(weak_ptr const& __r) _NOEXCEPT;
+    template<class _Yp> weak_ptr(weak_ptr<_Yp> const& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                         _NOEXCEPT;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp> weak_ptr(weak_ptr<_Yp>&& __r,
+                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
+                         _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    ~weak_ptr();
+
+    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template<class _Yp>
+        typename enable_if
+        <
+            is_convertible<_Yp*, element_type*>::value,
+            weak_ptr&
+        >::type
+        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
+
+    void swap(weak_ptr& __r) _NOEXCEPT;
+    void reset() _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    long use_count() const _NOEXCEPT
+        {return __cntrl_ ? __cntrl_->use_count() : 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool expired() const _NOEXCEPT
+        {return __cntrl_ == 0 || __cntrl_->use_count() == 0;}
+    shared_ptr<_Tp> lock() const _NOEXCEPT;
+    template<class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(const shared_ptr<_Up>& __r) const
+        {return __cntrl_ < __r.__cntrl_;}
+    template<class _Up>
+        _LIBCPP_INLINE_VISIBILITY
+        bool owner_before(const weak_ptr<_Up>& __r) const
+        {return __cntrl_ < __r.__cntrl_;}
+
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
+    template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;
+};
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+weak_ptr<_Tp>::weak_ptr() _NOEXCEPT
+    : __ptr_(0),
+      __cntrl_(0)
+{
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+                         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    if (__cntrl_)
+        __cntrl_->__add_weak();
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
+                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
+         _NOEXCEPT
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_)
+{
+    __r.__ptr_ = 0;
+    __r.__cntrl_ = 0;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+weak_ptr<_Tp>::~weak_ptr()
+{
+    if (__cntrl_)
+        __cntrl_->__release_weak();
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>&
+weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+weak_ptr<_Tp>&
+weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
+{
+    weak_ptr(_VSTD::move(__r)).swap(*this);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _Tp>
+template<class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    is_convertible<_Yp*, _Tp*>::value,
+    weak_ptr<_Tp>&
+>::type
+weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
+{
+    weak_ptr(__r).swap(*this);
+    return *this;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
+{
+    _VSTD::swap(__ptr_, __r.__ptr_);
+    _VSTD::swap(__cntrl_, __r.__cntrl_);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+weak_ptr<_Tp>::reset() _NOEXCEPT
+{
+    weak_ptr().swap(*this);
+}
+
+template<class _Tp>
+template<class _Yp>
+shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
+                            typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat>::type)
+    : __ptr_(__r.__ptr_),
+      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
+{
+    if (__cntrl_ == 0)
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        throw bad_weak_ptr();
+#else
+        assert(!"bad_weak_ptr");
+#endif
+}
+
+template<class _Tp>
+shared_ptr<_Tp>
+weak_ptr<_Tp>::lock() const _NOEXCEPT
+{
+    shared_ptr<_Tp> __r;
+    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
+    if (__r.__cntrl_)
+        __r.__ptr_ = __ptr_;
+    return __r;
+}
+
+template <class _Tp> struct owner_less;
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY owner_less<shared_ptr<_Tp> >
+    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
+{
+    typedef bool result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY owner_less<weak_ptr<_Tp> >
+    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
+{
+    typedef bool result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const
+        {return __x.owner_before(__y);}
+};
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY enable_shared_from_this
+{
+    mutable weak_ptr<_Tp> __weak_this_;
+protected:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    enable_shared_from_this() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY
+    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY
+    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
+        {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    ~enable_shared_from_this() {}
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr<_Tp> shared_from_this()
+        {return shared_ptr<_Tp>(__weak_this_);}
+    _LIBCPP_INLINE_VISIBILITY
+    shared_ptr<_Tp const> shared_from_this() const
+        {return shared_ptr<const _Tp>(__weak_this_);}
+
+    template <class _Up> friend class shared_ptr;
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY hash<shared_ptr<_Tp> >
+{
+    typedef shared_ptr<_Tp>      argument_type;
+    typedef size_t               result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
+    {
+        return hash<_Tp*>()(__ptr.get());
+    }
+};
+
+template<class _CharT, class _Traits, class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
+
+#if __has_feature(cxx_atomic)
+
+class _LIBCPP_TYPE_VIS __sp_mut
+{
+    void* __lx;
+public:
+    void lock() _NOEXCEPT;
+    void unlock() _NOEXCEPT;
+
+private:
+    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
+    __sp_mut(const __sp_mut&);
+    __sp_mut& operator=(const __sp_mut&);
+
+    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
+};
+
+_LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_is_lock_free(const shared_ptr<_Tp>*)
+{
+    return false;
+}
+
+template <class _Tp>
+shared_ptr<_Tp>
+atomic_load(const shared_ptr<_Tp>* __p)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    shared_ptr<_Tp> __q = *__p;
+    __m.unlock();
+    return __q;
+}
+  
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
+{
+    return atomic_load(__p);
+}
+
+template <class _Tp>
+void
+atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    __p->swap(__r);
+    __m.unlock();
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
+{
+    atomic_store(__p, __r);
+}
+
+template <class _Tp>
+shared_ptr<_Tp>
+atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    __p->swap(__r);
+    __m.unlock();
+    return __r;
+}
+  
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+shared_ptr<_Tp>
+atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
+{
+    return atomic_exchange(__p, __r);
+}
+
+template <class _Tp>
+bool
+atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
+{
+    __sp_mut& __m = __get_sp_mut(__p);
+    __m.lock();
+    if (__p->__owner_equivalent(*__v))
+    {
+        *__p = __w;
+        __m.unlock();
+        return true;
+    }
+    *__v = *__p;
+    __m.unlock();
+    return false;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
+{
+    return atomic_compare_exchange_strong(__p, __v, __w);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
+                                        shared_ptr<_Tp> __w, memory_order, memory_order)
+{
+    return atomic_compare_exchange_strong(__p, __v, __w);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
+                                      shared_ptr<_Tp> __w, memory_order, memory_order)
+{
+    return atomic_compare_exchange_weak(__p, __v, __w);
+}
+
+#endif  // __has_feature(cxx_atomic)
+
+//enum class
+struct _LIBCPP_TYPE_VIS pointer_safety
+{
+    enum __lx
+    {
+        relaxed,
+        preferred,
+        strict
+    };
+
+    __lx __v_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    pointer_safety(__lx __v) : __v_(__v) {}
+    _LIBCPP_INLINE_VISIBILITY
+    operator int() const {return __v_;}
+};
+
+_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
+_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
+_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
+_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+undeclare_reachable(_Tp* __p)
+{
+    return static_cast<_Tp*>(__undeclare_reachable(__p));
+}
+
+_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_MEMORY
diff --git a/include/c++/v1/module.modulemap b/include/c++/v1/module.modulemap
new file mode 100644
index 0000000..a0f4254
--- /dev/null
+++ b/include/c++/v1/module.modulemap
@@ -0,0 +1,471 @@
+module std [system] {
+  // FIXME: The standard does not require that each of these submodules
+  // re-exports its imported modules. We should provide an alternative form of
+  // export that issues a warning if a name from the submodule is used, and
+  // use that to provide a 'strict mode' for libc++.
+  module algorithm {
+    header "algorithm"
+    export initializer_list
+    export *
+  }
+  module array {
+    header "array"
+    export initializer_list
+    export *
+  }
+  module atomic {
+    header "atomic"
+    export *
+  }
+  module bitset {
+    header "bitset"
+    export string
+    export iosfwd
+    export *
+  }
+  // No submodule for cassert. It fundamentally needs repeated, textual inclusion.
+  module ccomplex {
+    header "ccomplex"
+    export complex
+    export *
+  }
+  module cctype {
+    header "cctype"
+    export *
+  }
+  module cerrno {
+    header "cerrno"
+/*
+    export_macros    ECONNREFUSED, EIO,          ENODEV,      ENOTEMPTY,       ERANGE,
+      E2BIG,         ECONNRESET,   EISCONN,      ENOENT,      ENOTRECOVERABLE, EROFS,
+      EACCES,        EDEADLK,      EISDIR,       ENOEXEC,     ENOTSOCK,        ESPIPE,
+      EADDRINUSE,    EDESTADDRREQ, ELOOP,        ENOLCK,      ENOTSUP,         ESRCH,
+      EADDRNOTAVAIL, EDOM,         EMFILE,       ENOLINK,     ENOTTY,          ETIME,
+      EAFNOSUPPORT,  EEXIST,       EMLINK,       ENOMEM,      ENXIO,           ETIMEDOUT,
+      EAGAIN,        EFAULT,       EMSGSIZE,     ENOMSG,      EOPNOTSUPP,      ETXTBSY,
+      EALREADY,      EFBIG,        ENAMETOOLONG, ENOPROTOOPT, EOVERFLOW,       EWOULDBLOCK,
+      EBADF,         EHOSTUNREACH, ENETDOWN,     ENOSPC,      EOWNERDEAD,      EXDEV,
+      EBADMSG,       EIDRM,        ENETRESET,    ENOSR,       EPERM,           errno,
+      EBUSY,         EILSEQ,       ENETUNREACH,  ENOSTR,      EPIPE,
+      ECANCELED,     EINPROGRESS,  ENFILE,       ENOSYS,      EPROTO,
+      ECHILD,        EINTR,        ENOBUFS,      ENOTCONN,    EPROTONOSUPPORT,
+      ECONNABORTED,  EINVAL,       ENODATA,      ENOTDIR,     EPROTOTYPE
+*/
+    export *
+  }
+  module cfenv {
+    header "cfenv"
+/*
+    export_macros FE_ALL_EXCEPT, FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW,
+                  FE_UNDERFLOW, FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD,
+                  FE_DFL_ENV
+*/
+    export *
+  }
+  module cfloat {
+    header "cfloat"
+/*
+    export_macros FLT_EVAL_METHOD, FLT_RADIX, FLT_ROUNDS,
+                  FLT_DIG, FLT_EPSILON, FLT_MANT_DIG,
+                  FLT_MAX, FLT_MAX_10_EXP, FLT_MAX_EXP,
+                  FLT_MIN, FLT_MIN_10_EXP, FLT_MIN_EXP,
+                  DBL_DIG, DBL_EPSILON, DBL_MANT_DIG,
+                  DBL_MAX, DBL_MAX_10_EXP, DBL_MAX_EXP,
+                  DBL_MIN, DBL_MIN_10_EXP, DBL_MIN_EXP,
+                  LDBL_DIG, LDBL_EPSILON, LDBL_MANT_DIG,
+                  LDBL_MAX, LDBL_MAX_10_EXP, LDBL_MAX_EXP,
+                  LDBL_MIN, LDBL_MIN_10_EXP, LDBL_MIN_EXP
+*/
+    export *
+  }
+  module chrono {
+    header "chrono"
+    export *
+  }
+  module cinttypes {
+    header "cinttypes"
+    export cstdint
+/*
+    export_macros
+      PRId8, PRId16, PRId32, PRId64, PRIdFAST8, PRIdFAST16, PRIdFAST32, PRIdFAST64, PRIdLEAST8, PRIdLEAST16, PRIdLEAST32, PRIdLEAST64, PRIdMAX, PRIdPTR,
+      PRIi8, PRIi16, PRIi32, PRIi64, PRIiFAST8, PRIiFAST16, PRIiFAST32, PRIiFAST64, PRIiLEAST8, PRIiLEAST16, PRIiLEAST32, PRIiLEAST64, PRIiMAX, PRIiPTR,
+      PRIo8, PRIo16, PRIo32, PRIo64, PRIoFAST8, PRIoFAST16, PRIoFAST32, PRIoFAST64, PRIoLEAST8, PRIoLEAST16, PRIoLEAST32, PRIoLEAST64, PRIoMAX, PRIoPTR,
+      PRIu8, PRIu16, PRIu32, PRIu64, PRIuFAST8, PRIuFAST16, PRIuFAST32, PRIuFAST64, PRIuLEAST8, PRIuLEAST16, PRIuLEAST32, PRIuLEAST64, PRIuMAX, PRIuPTR,
+      PRIx8, PRIx16, PRIx32, PRIx64, PRIxFAST8, PRIxFAST16, PRIxFAST32, PRIxFAST64, PRIxLEAST8, PRIxLEAST16, PRIxLEAST32, PRIxLEAST64, PRIxMAX, PRIxPTR,
+      PRIX8, PRIX16, PRIX32, PRIX64, PRIXFAST8, PRIXFAST16, PRIXFAST32, PRIXFAST64, PRIXLEAST8, PRIXLEAST16, PRIXLEAST32, PRIXLEAST64, PRIXMAX, PRIXPTR,
+      SCNd8, SCNd16, SCNd32, SCNd64, SCNdFAST8, SCNdFAST16, SCNdFAST32, SCNdFAST64, SCNdLEAST8, SCNdLEAST16, SCNdLEAST32, SCNdLEAST64, SCNdMAX, SCNdPTR,
+      SCNi8, SCNi16, SCNi32, SCNi64, SCNiFAST8, SCNiFAST16, SCNiFAST32, SCNiFAST64, SCNiLEAST8, SCNiLEAST16, SCNiLEAST32, SCNiLEAST64, SCNiMAX, SCNiPTR,
+      SCNo8, SCNo16, SCNo32, SCNo64, SCNoFAST8, SCNoFAST16, SCNoFAST32, SCNoFAST64, SCNoLEAST8, SCNoLEAST16, SCNoLEAST32, SCNoLEAST64, SCNoMAX, SCNoPTR,
+      SCNu8, SCNu16, SCNu32, SCNu64, SCNuFAST8, SCNuFAST16, SCNuFAST32, SCNuFAST64, SCNuLEAST8, SCNuLEAST16, SCNuLEAST32, SCNuLEAST64, SCNuMAX, SCNuPTR,
+      SCNx8, SCNx16, SCNx32, SCNx64, SCNxFAST8, SCNxFAST16, SCNxFAST32, SCNxFAST64, SCNxLEAST8, SCNxLEAST16, SCNxLEAST32, SCNxLEAST64, SCNxMAX, SCNxPTR,
+      SCNX8, SCNX16, SCNX32, SCNX64, SCNXFAST8, SCNXFAST16, SCNXFAST32, SCNXFAST64, SCNXLEAST8, SCNXLEAST16, SCNXLEAST32, SCNXLEAST64, SCNXMAX, SCNXPTR
+*/
+    export *
+  }
+  module ciso646 {
+    header "ciso646"
+    export *
+  }
+  module climits {
+    header "climits"
+/*
+    export_macros CHAR_BIT,  CHAR_MIN,  CHAR_MAX,
+                  SCHAR_MIN, SCHAR_MAX, UCHAR_MAX,
+                  SHRT_MIN,  SHRT_MAX,  USHRT_MAX,
+                  INT_MIN,   INT_MAX,   UINT_MAX,
+                  LONG_MIN,  LONG_MAX,  ULONG_MAX,
+                  LLONG_MIN, LLONG_MAX, ULLONG_MAX,
+                  MB_LEN_MAX
+*/
+    export *
+  }
+  module clocale {
+    header "clocale"
+/*
+    export_macros LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, NULL
+*/
+    export *
+  }
+  module cmath {
+    header "cmath"
+/*
+    export_macros FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL, FP_ILOGBO, FP_ILOGBNAN,
+                  FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO,
+                  HUGE_VAL, HUGE_VALF, HUGE_VALL, INFINITY, NAN,
+                  MATH_ERRNO, MATH_ERREXCEPT, math_errhandling
+*/
+    export *
+  }
+  module codecvt {
+    header "codecvt"
+    export *
+  }
+  module complex {
+    header "complex"
+    export *
+  }
+  module condition_variable {
+    header "condition_variable"
+    export *
+  }
+  module csetjmp {
+    header "csetjmp"
+/*
+    export_macros setjmp
+*/
+    export *
+  }
+  module csignal {
+    header "csignal"
+/*
+    export_macros SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM,
+                  SIG_DFL, SIG_IGN, SIG_ERR
+*/
+    export *
+  }
+  module cstdarg {
+    header "cstdarg"
+/*
+    export_macros va_arg, va_start, va_end, va_copy
+*/
+    export *
+  }
+  module cstdbool {
+    header "cstdbool"
+/*
+    export_macros __bool_true_false_are_defined
+*/
+    export *
+  }
+  module cstddef {
+    header "cstddef"
+/*
+    export_macros NULL, offsetof
+*/
+    export *
+  }
+  module cstdint {
+    header "cstdint"
+/*
+    export_macros
+      INT_8_MIN, INT_8_MAX, UINT_8_MAX, INT_16_MIN, INT_16_MAX, UINT_16_MAX,
+      INT_32_MIN, INT_32_MAX, UINT_32_MAX, INT_64_MIN, INT_64_MAX, UINT_64_MAX,
+      INT_FAST8_MIN, INT_FAST8_MAX, UINT_FAST8_MAX, INT_FAST16_MIN, INT_FAST16_MAX, UINT_FAST16_MAX,
+      INT_FAST32_MIN, INT_FAST32_MAX, UINT_FAST32_MAX, INT_FAST64_MIN, INT_FAST64_MAX, UINT_FAST64_MAX,
+      INT_LEAST8_MIN, INT_LEAST8_MAX, UINT_LEAST8_MAX, INT_LEAST16_MIN, INT_LEAST16_MAX, UINT_LEAST16_MAX,
+      INT_LEAST32_MIN, INT_LEAST32_MAX, UINT_LEAST32_MAX, INT_LEAST64_MIN, INT_LEAST64_MAX, UINT_LEAST64_MAX,
+      INT_MAX_MIN, INT_MAX_MAX, UINT_MAX_MAX, INT_PTR_MIN, INT_PTR_MAX, UINT_PTR_MAX,
+      PTRDIFF_MIN, PTRDIFF_MAX, SIG_ATOMIC_MIN, SIG_ATOMIC_MAX, WCHAR_MIN, WCHAR_MAX, WINT_MIN, WINT_MAX,
+      SIZE_MAX
+*/
+    export *
+  }
+  module cstdio {
+    header "cstdio"
+/*
+    export_macros BUFSIZ, EOF, FILENAME_MAX, FOPEN_MAX, L_tmpnam, NULL,
+                  SEEK_CUR, SEEK_END, SEEK_SET, TMP_MAX, _IOFBF, _IOLBF,
+                  stdin, stdout, stderr
+*/
+    export *
+  }
+  module cstdlib {
+    header "cstdlib"
+/*
+    export_macros RAND_MAX
+*/
+    export *
+  }
+  module cstring {
+    header "cstring"
+/*
+    export_macros NULL
+*/
+    export *
+  }
+  module ctgmath {
+    header "ctgmath"
+    export ccomplex
+    export cmath
+    export *
+  }
+  module ctime {
+    header "ctime"
+/*
+    export_macros NULL, CLOCKS_PER_SEC
+*/
+    export *
+  }
+  module cwchar {
+    header "cwchar"
+/*
+    export_macros NULL, WCHAR_MAX, WCHAR_MIN, WEOF
+*/
+    export *
+  }
+  module cwctype {
+    header "cwctype"
+/*
+    export_macros WEOF
+*/
+    export *
+  }
+  module deque {
+    header "deque"
+    export initializer_list
+    export *
+  }
+  module exception {
+    header "exception"
+    export *
+  }
+  module forward_list {
+    header "forward_list"
+    export initializer_list
+    export *
+  }
+  module fstream {
+    header "fstream"
+    export *
+  }
+  module functional {
+    header "functional"
+    export *
+  }
+  module future {
+    header "future"
+    export *
+  }
+  module initializer_list {
+    header "initializer_list"
+    export *
+  }
+  module iomanip {
+    header "iomanip"
+    export *
+  }
+  module ios {
+    header "ios"
+    export iosfwd
+    export *
+  }
+  module iosfwd {
+    header "iosfwd"
+    export *
+  }
+  module iostream {
+    header "iostream"
+    export ios
+    export streambuf
+    export istream
+    export ostream
+    export *
+  }
+  module istream {
+    header "istream"
+    // FIXME: should re-export ios, streambuf?
+    export *
+  }
+  module iterator {
+    header "iterator"
+    export *
+  }
+  module limits {
+    header "limits"
+    export *
+  }
+  module list {
+    header "list"
+    export initializer_list
+    export *
+  }
+  module locale {
+    header "locale"
+    export *
+  }
+  module map {
+    header "map"
+    export initializer_list
+    export *
+  }
+  module memory {
+    header "memory"
+    export *
+  }
+  module mutex {
+    header "mutex"
+    export *
+  }
+  module new {
+    header "new"
+    export *
+  }
+  module numeric {
+    header "numeric"
+    export *
+  }
+  module ostream {
+    header "ostream"
+    // FIXME: should re-export ios, streambuf?
+    export *
+  }
+  module queue {
+    header "queue"
+    export initializer_list
+    export *
+  }
+  module random {
+    header "random"
+    export initializer_list
+    export *
+  }
+  module ratio {
+    header "ratio"
+    export *
+  }
+  module regex {
+    header "regex"
+    export initializer_list
+    export *
+  }
+  module scoped_allocator {
+    header "scoped_allocator"
+    export *
+  }
+  module set {
+    header "set"
+    export initializer_list
+    export *
+  }
+  module sstream {
+    header "sstream"
+    // FIXME: should re-export istream, ostream, ios, streambuf, string?
+    export *
+  }
+  module stack {
+    header "stack"
+    export initializer_list
+    export *
+  }
+  module stdexcept {
+    header "stdexcept"
+    export *
+  }
+  module streambuf {
+    header "streambuf"
+    export *
+  }
+  module string {
+    header "string"
+    export initializer_list
+    export *
+  }
+  module strstream {
+    header "strstream"
+    requires !cplusplus11
+  }
+  module system_error {
+    header "system_error"
+    export *
+  }
+  module thread {
+    header "thread"
+    export *
+  }
+  module tuple {
+    header "tuple"
+    export *
+  }
+  module type_traits {
+    header "type_traits"
+    export *
+  }
+  module typeindex {
+    header "typeindex"
+    export *
+  }
+  module typeinfo {
+    header "typeinfo"
+    export *
+  }
+  module unordered_map {
+    header "unordered_map"
+    export initializer_list
+    export *
+  }
+  module unordered_set {
+    header "unordered_set"
+    export initializer_list
+    export *
+  }
+  module utility {
+    header "utility"
+    export initializer_list
+    export *
+  }
+  module valarray {
+    header "valarray"
+    export initializer_list
+    export *
+  }
+  module vector {
+    header "vector"
+    export initializer_list
+    export *
+  }
+
+  // FIXME: These should be private.
+  module __bit_reference { header "__bit_reference" export * }
+  module __config { header "__config" export * }
+  module __debug { header "__debug" export * }
+  module __functional_base { header "__functional_base" export * }
+  module __hash_table { header "__hash_table" export * }
+  module __locale { header "__locale" export * }
+  module __mutex_base { header "__mutex_base" export * }
+  module __split_buffer { header "__split_buffer" export * }
+  module __sso_allocator { header "__sso_allocator" export * }
+  module __std_stream { header "__std_stream" export * }
+  module __tree { header "__tree" export * }
+  module __tuple { header "__tuple" export * }
+  module __undef_min_max { header "__undef_min_max" export * }
+}
diff --git a/include/c++/v1/mutex b/include/c++/v1/mutex
new file mode 100644
index 0000000..e0c02ad
--- /dev/null
+++ b/include/c++/v1/mutex
@@ -0,0 +1,566 @@
+// -*- C++ -*-
+//===--------------------------- mutex ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_MUTEX
+#define _LIBCPP_MUTEX
+
+/*
+    mutex synopsis
+
+namespace std
+{
+
+class mutex
+{
+public:
+     constexpr mutex() noexcept;
+     ~mutex();
+
+    mutex(const mutex&) = delete;
+    mutex& operator=(const mutex&) = delete;
+
+    void lock();
+    bool try_lock();
+    void unlock();
+
+    typedef pthread_mutex_t* native_handle_type;
+    native_handle_type native_handle();
+};
+
+class recursive_mutex
+{
+public:
+     recursive_mutex();
+     ~recursive_mutex();
+
+    recursive_mutex(const recursive_mutex&) = delete;
+    recursive_mutex& operator=(const recursive_mutex&) = delete;
+
+    void lock();
+    bool try_lock() noexcept;
+    void unlock();
+
+    typedef pthread_mutex_t* native_handle_type;
+    native_handle_type native_handle();
+};
+
+class timed_mutex
+{
+public:
+     timed_mutex();
+     ~timed_mutex();
+
+    timed_mutex(const timed_mutex&) = delete;
+    timed_mutex& operator=(const timed_mutex&) = delete;
+
+    void lock();
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+};
+
+class recursive_timed_mutex
+{
+public:
+     recursive_timed_mutex();
+     ~recursive_timed_mutex();
+
+    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+    void lock();
+    bool try_lock() noexcept;
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+};
+
+struct defer_lock_t {};
+struct try_to_lock_t {};
+struct adopt_lock_t {};
+
+constexpr defer_lock_t  defer_lock{};
+constexpr try_to_lock_t try_to_lock{};
+constexpr adopt_lock_t  adopt_lock{};
+
+template <class Mutex>
+class lock_guard
+{
+public:
+    typedef Mutex mutex_type;
+
+    explicit lock_guard(mutex_type& m);
+    lock_guard(mutex_type& m, adopt_lock_t);
+    ~lock_guard();
+
+    lock_guard(lock_guard const&) = delete;
+    lock_guard& operator=(lock_guard const&) = delete;
+};
+
+template <class Mutex>
+class unique_lock
+{
+public:
+    typedef Mutex mutex_type;
+    unique_lock() noexcept;
+    explicit unique_lock(mutex_type& m);
+    unique_lock(mutex_type& m, defer_lock_t) noexcept;
+    unique_lock(mutex_type& m, try_to_lock_t);
+    unique_lock(mutex_type& m, adopt_lock_t);
+    template <class Clock, class Duration>
+        unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+    template <class Rep, class Period>
+        unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+    ~unique_lock();
+
+    unique_lock(unique_lock const&) = delete;
+    unique_lock& operator=(unique_lock const&) = delete;
+
+    unique_lock(unique_lock&& u) noexcept;
+    unique_lock& operator=(unique_lock&& u) noexcept;
+
+    void lock();
+    bool try_lock();
+
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+    void unlock();
+
+    void swap(unique_lock& u) noexcept;
+    mutex_type* release() noexcept;
+
+    bool owns_lock() const noexcept;
+    explicit operator bool () const noexcept;
+    mutex_type* mutex() const noexcept;
+};
+
+template <class Mutex>
+  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
+
+template <class L1, class L2, class... L3>
+  int try_lock(L1&, L2&, L3&...);
+template <class L1, class L2, class... L3>
+  void lock(L1&, L2&, L3&...);
+
+struct once_flag
+{
+    constexpr once_flag() noexcept;
+
+    once_flag(const once_flag&) = delete;
+    once_flag& operator=(const once_flag&) = delete;
+};
+
+template<class Callable, class ...Args>
+  void call_once(once_flag& flag, Callable&& func, Args&&... args);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__mutex_base>
+#include <functional>
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+#include <tuple>
+#endif
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS recursive_mutex
+{
+    pthread_mutex_t __m_;
+
+public:
+     recursive_mutex();
+     ~recursive_mutex();
+
+private:
+    recursive_mutex(const recursive_mutex&); // = delete;
+    recursive_mutex& operator=(const recursive_mutex&); // = delete;
+
+public:
+    void lock();
+    bool try_lock() _NOEXCEPT;
+    void unlock()  _NOEXCEPT;
+
+    typedef pthread_mutex_t* native_handle_type;
+    _LIBCPP_INLINE_VISIBILITY
+    native_handle_type native_handle() {return &__m_;}
+};
+
+class _LIBCPP_TYPE_VIS timed_mutex
+{
+    mutex              __m_;
+    condition_variable __cv_;
+    bool               __locked_;
+public:
+     timed_mutex();
+     ~timed_mutex();
+
+private:
+    timed_mutex(const timed_mutex&); // = delete;
+    timed_mutex& operator=(const timed_mutex&); // = delete;
+
+public:
+    void lock();
+    bool try_lock() _NOEXCEPT;
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
+            {return try_lock_until(chrono::steady_clock::now() + __d);}
+    template <class _Clock, class _Duration>
+        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+    void unlock() _NOEXCEPT;
+};
+
+template <class _Clock, class _Duration>
+bool
+timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    using namespace chrono;
+    unique_lock<mutex> __lk(__m_);
+    bool no_timeout = _Clock::now() < __t;
+    while (no_timeout && __locked_)
+        no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
+    if (!__locked_)
+    {
+        __locked_ = true;
+        return true;
+    }
+    return false;
+}
+
+class _LIBCPP_TYPE_VIS recursive_timed_mutex
+{
+    mutex              __m_;
+    condition_variable __cv_;
+    size_t             __count_;
+    pthread_t          __id_;
+public:
+     recursive_timed_mutex();
+     ~recursive_timed_mutex();
+
+private:
+    recursive_timed_mutex(const recursive_timed_mutex&); // = delete;
+    recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete;
+
+public:
+    void lock();
+    bool try_lock() _NOEXCEPT;
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool try_lock_for(const chrono::duration<_Rep, _Period>& __d)
+            {return try_lock_until(chrono::steady_clock::now() + __d);}
+    template <class _Clock, class _Duration>
+        bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+    void unlock() _NOEXCEPT;
+};
+
+template <class _Clock, class _Duration>
+bool
+recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    using namespace chrono;
+    pthread_t __id = pthread_self();
+    unique_lock<mutex> lk(__m_);
+    if (pthread_equal(__id, __id_))
+    {
+        if (__count_ == numeric_limits<size_t>::max())
+            return false;
+        ++__count_;
+        return true;
+    }
+    bool no_timeout = _Clock::now() < __t;
+    while (no_timeout && __count_ != 0)
+        no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout;
+    if (__count_ == 0)
+    {
+        __count_ = 1;
+        __id_ = __id;
+        return true;
+    }
+    return false;
+}
+
+template <class _L0, class _L1>
+int
+try_lock(_L0& __l0, _L1& __l1)
+{
+    unique_lock<_L0> __u0(__l0, try_to_lock);
+    if (__u0.owns_lock())
+    {
+        if (__l1.try_lock())
+        {
+            __u0.release();
+            return -1;
+        }
+        else
+            return 1;
+    }
+    return 0;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _L0, class _L1, class _L2, class... _L3>
+int
+try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3)
+{
+    int __r = 0;
+    unique_lock<_L0> __u0(__l0, try_to_lock);
+    if (__u0.owns_lock())
+    {
+        __r = try_lock(__l1, __l2, __l3...);
+        if (__r == -1)
+            __u0.release();
+        else
+            ++__r;
+    }
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _L0, class _L1>
+void
+lock(_L0& __l0, _L1& __l1)
+{
+    while (true)
+    {
+        {
+            unique_lock<_L0> __u0(__l0);
+            if (__l1.try_lock())
+            {
+                __u0.release();
+                break;
+            }
+        }
+        sched_yield();
+        {
+            unique_lock<_L1> __u1(__l1);
+            if (__l0.try_lock())
+            {
+                __u1.release();
+                break;
+            }
+        }
+        sched_yield();
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _L0, class _L1, class _L2, class ..._L3>
+void
+__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
+{
+    while (true)
+    {
+        switch (__i)
+        {
+        case 0:
+            {
+                unique_lock<_L0> __u0(__l0);
+                __i = try_lock(__l1, __l2, __l3...);
+                if (__i == -1)
+                {
+                    __u0.release();
+                    return;
+                }
+            }
+            ++__i;
+            sched_yield();
+            break;
+        case 1:
+            {
+                unique_lock<_L1> __u1(__l1);
+                __i = try_lock(__l2, __l3..., __l0);
+                if (__i == -1)
+                {
+                    __u1.release();
+                    return;
+                }
+            }
+            if (__i == sizeof...(_L3) + 1)
+                __i = 0;
+            else
+                __i += 2;
+            sched_yield();
+            break;
+        default:
+            __lock_first(__i - 2, __l2, __l3..., __l0, __l1);
+            return;
+        }
+    }
+}
+
+template <class _L0, class _L1, class _L2, class ..._L3>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
+{
+    __lock_first(0, __l0, __l1, __l2, __l3...);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+struct _LIBCPP_TYPE_VIS once_flag;
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Callable, class... _Args>
+_LIBCPP_INLINE_VISIBILITY
+void call_once(once_flag&, _Callable&&, _Args&&...);
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Callable>
+_LIBCPP_INLINE_VISIBILITY
+void call_once(once_flag&, _Callable);
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+struct _LIBCPP_TYPE_VIS_ONLY once_flag
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR
+        once_flag() _NOEXCEPT : __state_(0) {}
+
+private:
+    once_flag(const once_flag&); // = delete;
+    once_flag& operator=(const once_flag&); // = delete;
+
+    unsigned long __state_;
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template<class _Callable, class... _Args>
+    friend
+    void call_once(once_flag&, _Callable&&, _Args&&...);
+#else  // _LIBCPP_HAS_NO_VARIADICS
+    template<class _Callable>
+    friend
+    void call_once(once_flag&, _Callable);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Fp>
+class __call_once_param
+{
+    _Fp __f_;
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()()
+    {
+        typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
+        __execute(_Index());
+    }
+
+private:
+    template <size_t ..._Indices>
+    _LIBCPP_INLINE_VISIBILITY
+    void __execute(__tuple_indices<_Indices...>)
+    {
+        __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
+    }
+};
+
+#else
+
+template <class _Fp>
+class __call_once_param
+{
+    _Fp __f_;
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()()
+    {
+        __f_();
+    }
+};
+
+#endif
+
+template <class _Fp>
+void
+__call_once_proxy(void* __vp)
+{
+    __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);
+    (*__p)();
+}
+
+_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*));
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Callable, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
+{
+    if (__flag.__state_ != ~0ul)
+    {
+        typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp;
+        __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)),
+                                __decay_copy(_VSTD::forward<_Args>(__args))...));
+        __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
+    }
+}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template<class _Callable>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+call_once(once_flag& __flag, _Callable __func)
+{
+    if (__flag.__state_ != ~0ul)
+    {
+        __call_once_param<_Callable> __p(__func);
+        __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_MUTEX
diff --git a/include/c++/v1/new b/include/c++/v1/new
new file mode 100644
index 0000000..a710ed9
--- /dev/null
+++ b/include/c++/v1/new
@@ -0,0 +1,170 @@
+// -*- C++ -*-
+//===----------------------------- new ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_NEW
+#define _LIBCPP_NEW
+
+/*
+    new synopsis
+
+namespace std
+{
+
+class bad_alloc
+    : public exception
+{
+public:
+    bad_alloc() noexcept;
+    bad_alloc(const bad_alloc&) noexcept;
+    bad_alloc& operator=(const bad_alloc&) noexcept;
+    virtual const char* what() const noexcept;
+};
+
+class bad_array_length : public bad_alloc // C++14
+{
+public:
+    bad_array_length() noexcept;
+};
+
+class bad_array_new_length : public bad_alloc
+{
+public:
+    bad_array_new_length() noexcept;
+};
+
+struct nothrow_t {};
+extern const nothrow_t nothrow;
+typedef void (*new_handler)();
+new_handler set_new_handler(new_handler new_p) noexcept;
+new_handler get_new_handler() noexcept;
+
+}  // std
+
+void* operator new(std::size_t size);                                   // replaceable
+void* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable
+void  operator delete(void* ptr) noexcept;                              // replaceable
+void  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
+
+void* operator new[](std::size_t size);                                 // replaceable
+void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
+void  operator delete[](void* ptr) noexcept;                            // replaceable
+void  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
+
+void* operator new  (std::size_t size, void* ptr) noexcept;
+void* operator new[](std::size_t size, void* ptr) noexcept;
+void  operator delete  (void* ptr, void*) noexcept;
+void  operator delete[](void* ptr, void*) noexcept;
+
+*/
+
+#include <__config>
+#include <exception>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std  // purposefully not using versioning namespace
+{
+
+class _LIBCPP_EXCEPTION_ABI bad_alloc
+    : public exception
+{
+public:
+    bad_alloc() _NOEXCEPT;
+    virtual ~bad_alloc() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI bad_array_new_length
+    : public bad_alloc
+{
+public:
+    bad_array_new_length() _NOEXCEPT;
+    virtual ~bad_array_new_length() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+#if defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+
+class _LIBCPP_EXCEPTION_ABI bad_array_length
+    : public bad_alloc
+{
+public:
+    bad_array_length() _NOEXCEPT;
+    virtual ~bad_array_length() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
+
+#endif  // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
+
+_LIBCPP_FUNC_VIS void __throw_bad_alloc();  // not in C++ spec
+
+struct _LIBCPP_TYPE_VIS nothrow_t {};
+extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
+typedef void (*new_handler)();
+_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
+
+}  // std
+
+#if defined(_WIN32) && !defined(cxx_EXPORTS)
+# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS_ONLY
+#else
+# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS
+#endif
+
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz)
+#if !__has_feature(cxx_noexcept)
+    throw(std::bad_alloc)
+#endif
+;
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
+
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)
+#if !__has_feature(cxx_noexcept)
+    throw(std::bad_alloc)
+#endif
+;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
+
+inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
+inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
+inline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
+inline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {}
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
+#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
+  return ::operator new(__size);
+#else
+  return __builtin_operator_new(__size);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY void __deallocate(void *__ptr) {
+#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
+  ::operator delete(__ptr);
+#else
+  __builtin_operator_delete(__ptr);
+#endif
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_NEW
diff --git a/include/c++/v1/numeric b/include/c++/v1/numeric
new file mode 100644
index 0000000..e520c8e
--- /dev/null
+++ b/include/c++/v1/numeric
@@ -0,0 +1,197 @@
+// -*- C++ -*-
+//===---------------------------- numeric ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_NUMERIC
+#define _LIBCPP_NUMERIC
+
+/*
+    numeric synopsis
+
+namespace std
+{
+
+template <class InputIterator, class T>
+    T
+    accumulate(InputIterator first, InputIterator last, T init);
+
+template <class InputIterator, class T, class BinaryOperation>
+    T
+    accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
+
+template <class InputIterator1, class InputIterator2, class T>
+    T
+    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
+
+template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
+    T
+    inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
+                  T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
+
+template <class InputIterator, class OutputIterator>
+    OutputIterator
+    partial_sum(InputIterator first, InputIterator last, OutputIterator result);
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+    OutputIterator
+    partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
+
+template <class InputIterator, class OutputIterator>
+    OutputIterator
+    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+    OutputIterator
+    adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);
+
+template <class ForwardIterator, class T>
+    void iota(ForwardIterator first, ForwardIterator last, T value);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <iterator>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _InputIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
+{
+    for (; __first != __last; ++__first)
+        __init = __init + *__first;
+    return __init;
+}
+
+template <class _InputIterator, class _Tp, class _BinaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
+{
+    for (; __first != __last; ++__first)
+        __init = __binary_op(__init, *__first);
+    return __init;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init)
+{
+    for (; __first1 != __last1; ++__first1, ++__first2)
+        __init = __init + *__first1 * *__first2;
+    return __init;
+}
+
+template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2,
+              _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
+{
+    for (; __first1 != __last1; ++__first1, ++__first2)
+        __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
+    return __init;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t(*__first);
+        *__result = __t;
+        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        {
+            __t = __t + *__first;
+            *__result = __t;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+              _BinaryOperation __binary_op)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t(*__first);
+        *__result = __t;
+        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        {
+            __t = __binary_op(__t, *__first);
+            *__result = __t;
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
+        *__result = __t1;
+        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        {
+            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
+            *__result = __t2 - __t1;
+            __t1 = _VSTD::move(__t2);
+        }
+    }
+    return __result;
+}
+
+template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
+                      _BinaryOperation __binary_op)
+{
+    if (__first != __last)
+    {
+        typename iterator_traits<_InputIterator>::value_type __t1(*__first);
+        *__result = __t1;
+        for (++__first, ++__result; __first != __last; ++__first, ++__result)
+        {
+            typename iterator_traits<_InputIterator>::value_type __t2(*__first);
+            *__result = __binary_op(__t2, __t1);
+            __t1 = _VSTD::move(__t2);
+        }
+    }
+    return __result;
+}
+
+template <class _ForwardIterator, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_)
+{
+    for (; __first != __last; ++__first, ++__value_)
+        *__first = __value_;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_NUMERIC
diff --git a/include/c++/v1/ostream b/include/c++/v1/ostream
new file mode 100644
index 0000000..9d96fd8
--- /dev/null
+++ b/include/c++/v1/ostream
@@ -0,0 +1,1101 @@
+// -*- C++ -*-
+//===-------------------------- ostream -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_OSTREAM
+#define _LIBCPP_OSTREAM
+
+/*
+    ostream synopsis
+
+template <class charT, class traits = char_traits<charT> >
+class basic_ostream
+    : virtual public basic_ios<charT,traits>
+{
+public:
+    // types (inherited from basic_ios (27.5.4)):
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // 27.7.2.2 Constructor/destructor:
+    explicit basic_ostream(basic_streambuf<char_type,traits>* sb);
+    basic_ostream(basic_ostream&& rhs);
+    virtual ~basic_ostream();
+
+    // 27.7.2.3 Assign/swap
+    basic_ostream& operator=(const basic_ostream& rhs) = delete; // C++14
+    basic_ostream& operator=(basic_ostream&& rhs);
+    void swap(basic_ostream& rhs);
+
+    // 27.7.2.4 Prefix/suffix:
+    class sentry;
+
+    // 27.7.2.6 Formatted output:
+    basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&));
+    basic_ostream& operator<<(basic_ios<charT, traits>& (*pf)(basic_ios<charT,traits>&));
+    basic_ostream& operator<<(ios_base& (*pf)(ios_base&));
+    basic_ostream& operator<<(bool n);
+    basic_ostream& operator<<(short n);
+    basic_ostream& operator<<(unsigned short n);
+    basic_ostream& operator<<(int n);
+    basic_ostream& operator<<(unsigned int n);
+    basic_ostream& operator<<(long n);
+    basic_ostream& operator<<(unsigned long n);
+    basic_ostream& operator<<(long long n);
+    basic_ostream& operator<<(unsigned long long n);
+    basic_ostream& operator<<(float f);
+    basic_ostream& operator<<(double f);
+    basic_ostream& operator<<(long double f);
+    basic_ostream& operator<<(const void* p);
+    basic_ostream& operator<<(basic_streambuf<char_type,traits>* sb);
+
+    // 27.7.2.7 Unformatted output:
+    basic_ostream& put(char_type c);
+    basic_ostream& write(const char_type* s, streamsize n);
+    basic_ostream& flush();
+
+    // 27.7.2.5 seeks:
+    pos_type tellp();
+    basic_ostream& seekp(pos_type);
+    basic_ostream& seekp(off_type, ios_base::seekdir);
+};
+
+// 27.7.2.6.4 character inserters
+
+template<class charT, class traits>
+  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, charT);
+
+template<class charT, class traits>
+  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, char);
+
+template<class traits>
+  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, char);
+
+// signed and unsigned
+
+template<class traits>
+  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, signed char);
+
+template<class traits>
+  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, unsigned char);
+
+// NTBS
+template<class charT, class traits>
+  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
+
+template<class charT, class traits>
+  basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const char*);
+
+template<class traits>
+  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const char*);
+
+// signed and unsigned
+template<class traits>
+basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const signed char*);
+
+template<class traits>
+  basic_ostream<char,traits>& operator<<(basic_ostream<char,traits>&, const unsigned char*);
+
+// swap:
+template <class charT, class traits>
+  void swap(basic_ostream<charT, traits>& x, basic_ostream<charT, traits>& y);
+
+template <class charT, class traits>
+  basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
+
+template <class charT, class traits>
+  basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os);
+
+template <class charT, class traits>
+  basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);
+
+// rvalue stream insertion
+template <class charT, class traits, class T>
+  basic_ostream<charT, traits>&
+  operator<<(basic_ostream<charT, traits>&& os, const T& x);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ios>
+#include <streambuf>
+#include <locale>
+#include <iterator>
+#include <bitset>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_ostream
+    : virtual public basic_ios<_CharT, _Traits>
+{
+public:
+    // types (inherited from basic_ios (27.5.4)):
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    // 27.7.2.2 Constructor/destructor:
+    explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb);
+    virtual ~basic_ostream();
+protected:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream(basic_ostream&& __rhs);
+#endif
+
+    // 27.7.2.3 Assign/swap
+#if _LIBCPP_STD_VER > 11
+    basic_ostream& operator=(const basic_ostream&) = delete;
+#endif
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream& operator=(basic_ostream&& __rhs);
+#endif
+    void swap(basic_ostream& __rhs);
+public:
+
+    // 27.7.2.4 Prefix/suffix:
+    class _LIBCPP_TYPE_VIS_ONLY sentry;
+
+    // 27.7.2.6 Formatted output:
+    basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&));
+    basic_ostream& operator<<(basic_ios<char_type, traits_type>&
+                              (*__pf)(basic_ios<char_type,traits_type>&));
+    basic_ostream& operator<<(ios_base& (*__pf)(ios_base&));
+    basic_ostream& operator<<(bool __n);
+    basic_ostream& operator<<(short __n);
+    basic_ostream& operator<<(unsigned short __n);
+    basic_ostream& operator<<(int __n);
+    basic_ostream& operator<<(unsigned int __n);
+    basic_ostream& operator<<(long __n);
+    basic_ostream& operator<<(unsigned long __n);
+    basic_ostream& operator<<(long long __n);
+    basic_ostream& operator<<(unsigned long long __n);
+    basic_ostream& operator<<(float __f);
+    basic_ostream& operator<<(double __f);
+    basic_ostream& operator<<(long double __f);
+    basic_ostream& operator<<(const void* __p);
+    basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
+
+    // 27.7.2.7 Unformatted output:
+    basic_ostream& put(char_type __c);
+    basic_ostream& write(const char_type* __s, streamsize __n);
+    basic_ostream& flush();
+
+    // 27.7.2.5 seeks:
+    pos_type tellp();
+    basic_ostream& seekp(pos_type __pos);
+    basic_ostream& seekp(off_type __off, ios_base::seekdir __dir);
+
+protected:
+    _LIBCPP_ALWAYS_INLINE
+    basic_ostream() {}  // extension, intentially does not initialize
+};
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_ostream<_CharT, _Traits>::sentry
+{
+    bool __ok_;
+    basic_ostream<_CharT, _Traits>& __os_;
+
+    sentry(const sentry&); // = delete;
+    sentry& operator=(const sentry&); // = delete;
+
+public:
+    explicit sentry(basic_ostream<_CharT, _Traits>& __os);
+    ~sentry();
+
+    _LIBCPP_ALWAYS_INLINE
+        _LIBCPP_EXPLICIT
+        operator bool() const {return __ok_;}
+};
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>::sentry::sentry(basic_ostream<_CharT, _Traits>& __os)
+    : __ok_(false),
+      __os_(__os)
+{
+    if (__os.good())
+    {
+        if (__os.tie())
+            __os.tie()->flush();
+        __ok_ = true;
+    }
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>::sentry::~sentry()
+{
+    if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf)
+                      && !uncaught_exception())
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            if (__os_.rdbuf()->pubsync() == -1)
+                __os_.setstate(ios_base::badbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<char_type, traits_type>* __sb)
+{
+    this->init(__sb);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs)
+{
+    this->move(__rhs);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs)
+{
+    swap(__rhs);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>::~basic_ostream()
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ostream<_CharT, _Traits>::swap(basic_ostream& __rhs)
+{
+    basic_ios<char_type, traits_type>::swap(__rhs);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(basic_ostream& (*__pf)(basic_ostream&))
+{
+    return __pf(*this);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(basic_ios<char_type, traits_type>&
+                                           (*__pf)(basic_ios<char_type,traits_type>&))
+{
+    __pf(*this);
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&))
+{
+    __pf(*this);
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            if (__sb)
+            {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                try
+                {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    typedef istreambuf_iterator<_CharT, _Traits> _Ip;
+                    typedef ostreambuf_iterator<_CharT, _Traits> _Op;
+                    _Ip __i(__sb);
+                    _Ip __eof;
+                    _Op __o(*this);
+                    size_t __c = 0;
+                    for (; __i != __eof; ++__i, ++__o, ++__c)
+                    {
+                        *__o = *__i;
+                        if (__o.failed())
+                            break;
+                    }
+                    if (__c == 0)
+                        this->setstate(ios_base::failbit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                }
+                catch (...)
+                {
+                    this->__set_failbit_and_consider_rethrow();
+                }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            }
+            else
+                this->setstate(ios_base::badbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(bool __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(short __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(),
+                        __flags == ios_base::oct || __flags == ios_base::hex ?
+                        static_cast<long>(static_cast<unsigned short>(__n))  :
+                        static_cast<long>(__n)).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(int __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            ios_base::fmtflags __flags = ios_base::flags() & ios_base::basefield;
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(),
+                        __flags == ios_base::oct || __flags == ios_base::hex ?
+                        static_cast<long>(static_cast<unsigned int>(__n))  :
+                        static_cast<long>(__n)).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(long __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(long long __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(float __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(double __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(long double __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef num_put<char_type, ostreambuf_iterator<char_type, traits_type> > _Fp;
+            const _Fp& __f = use_facet<_Fp>(this->getloc());
+            if (__f.put(*this, *this, this->fill(), __n).failed())
+                this->setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template<class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+__put_character_sequence(basic_ostream<_CharT, _Traits>& __os,
+                          const _CharT* __str, size_t __len)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
+        if (__s)
+        {
+            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
+            if (__pad_and_output(_Ip(__os),
+                                 __str,
+                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+                                     __str + __len :
+                                     __str,
+                                 __str + __len,
+                                 __os,
+                                 __os.fill()).failed())
+                __os.setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __os.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __os;
+}
+
+
+template<class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, _CharT __c)
+{
+    return _VSTD::__put_character_sequence(__os, &__c, 1);
+}
+
+template<class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
+        if (__s)
+        {
+            _CharT __c = __os.widen(__cn);
+            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
+            if (__pad_and_output(_Ip(__os),
+                                 &__c,
+                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+                                     &__c + 1 :
+                                     &__c,
+                                 &__c + 1,
+                                 __os,
+                                 __os.fill()).failed())
+                __os.setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __os.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __os;
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, char __c)
+{
+    return _VSTD::__put_character_sequence(__os, &__c, 1);
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, signed char __c)
+{
+    return _VSTD::__put_character_sequence(__os, (char *) &__c, 1);
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, unsigned char __c)
+{
+    return _VSTD::__put_character_sequence(__os, (char *) &__c, 1);
+}
+
+template<class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str)
+{
+    return _VSTD::__put_character_sequence(__os, __str, _Traits::length(__str));
+}
+
+template<class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
+        if (__s)
+        {
+            typedef ostreambuf_iterator<_CharT, _Traits> _Ip;
+            size_t __len = char_traits<char>::length(__strn);
+            const int __bs = 100;
+            _CharT __wbb[__bs];
+            _CharT* __wb = __wbb;
+            unique_ptr<_CharT, void(*)(void*)> __h(0, free);
+            if (__len > __bs)
+            {
+                __wb = (_CharT*)malloc(__len*sizeof(_CharT));
+                if (__wb == 0)
+                    __throw_bad_alloc();
+                __h.reset(__wb);
+            }
+            for (_CharT* __p = __wb; *__strn != '\0'; ++__strn, ++__p)
+                *__p = __os.widen(*__strn);
+            if (__pad_and_output(_Ip(__os),
+                                 __wb,
+                                 (__os.flags() & ios_base::adjustfield) == ios_base::left ?
+                                     __wb + __len :
+                                     __wb,
+                                 __wb + __len,
+                                 __os,
+                                 __os.fill()).failed())
+                __os.setstate(ios_base::badbit | ios_base::failbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        __os.__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __os;
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, const char* __str)
+{
+    return _VSTD::__put_character_sequence(__os, __str, _Traits::length(__str));
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, const signed char* __str)
+{
+    const char *__s = (const char *) __str;
+    return _VSTD::__put_character_sequence(__os, __s, _Traits::length(__s));
+}
+
+template<class _Traits>
+basic_ostream<char, _Traits>&
+operator<<(basic_ostream<char, _Traits>& __os, const unsigned char* __str)
+{
+    const char *__s = (const char *) __str;
+    return _VSTD::__put_character_sequence(__os, __s, _Traits::length(__s));
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::put(char_type __c)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __s(*this);
+        if (__s)
+        {
+            typedef ostreambuf_iterator<_CharT, _Traits> _Op;
+            _Op __o(*this);
+            *__o = __c;
+            if (__o.failed())
+                this->setstate(ios_base::badbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        sentry __sen(*this);
+        if (__sen && __n)
+        {
+            if (this->rdbuf()->sputn(__s, __n) != __n)
+                this->setstate(ios_base::badbit);
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::flush()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        if (this->rdbuf())
+        {
+            sentry __s(*this);
+            if (__s)
+            {
+                if (this->rdbuf()->pubsync() == -1)
+                    this->setstate(ios_base::badbit);
+            }
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        this->__set_badbit_and_consider_rethrow();
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_ostream<_CharT, _Traits>::pos_type
+basic_ostream<_CharT, _Traits>::tellp()
+{
+    if (this->fail())
+        return pos_type(-1);
+    return this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
+{
+    sentry __s(*this);
+    if (__s)
+    {
+        if (this->rdbuf()->pubseekpos(__pos, ios_base::out) == pos_type(-1))
+            this->setstate(ios_base::failbit);
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
+{
+    sentry __s(*this);
+    if (__s)
+    {
+        if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::out) == pos_type(-1))
+            this->setstate(ios_base::failbit);
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+endl(basic_ostream<_CharT, _Traits>& __os)
+{
+    __os.put(__os.widen('\n'));
+    __os.flush();
+    return __os;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+ends(basic_ostream<_CharT, _Traits>& __os)
+{
+    __os.put(_CharT());
+    return __os;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+flush(basic_ostream<_CharT, _Traits>& __os)
+{
+    __os.flush();
+    return __os;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Stream, class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    !is_lvalue_reference<_Stream>::value &&
+    is_base_of<ios_base, _Stream>::value,
+    _Stream&&
+>::type
+operator<<(_Stream&& __os, const _Tp& __x)
+{
+    __os << __x;
+    return _VSTD::move(__os);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const basic_string<_CharT, _Traits, _Allocator>& __str)
+{
+    return _VSTD::__put_character_sequence(__os, __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec)
+{
+    return __os << __ec.category().name() << ':' << __ec.value();
+}
+
+template<class _CharT, class _Traits, class _Yp>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p)
+{
+    return __os << __p.get();
+}
+
+template <class _CharT, class _Traits, size_t _Size>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
+{
+    return __os << __x.template to_string<_CharT, _Traits>
+                        (use_facet<ctype<_CharT> >(__os.getloc()).widen('0'),
+                         use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
+}
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<wchar_t>)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_OSTREAM
diff --git a/include/c++/v1/queue b/include/c++/v1/queue
new file mode 100644
index 0000000..bdfd706
--- /dev/null
+++ b/include/c++/v1/queue
@@ -0,0 +1,717 @@
+// -*- C++ -*-
+//===--------------------------- queue ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_QUEUE
+#define _LIBCPP_QUEUE
+
+/*
+    queue synopsis
+
+namespace std
+{
+
+template <class T, class Container = deque<T>>
+class queue
+{
+public:
+    typedef Container                                container_type;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+
+public:
+    queue() = default;
+    ~queue() = default;
+
+    queue(const queue& q) = default;
+    queue(queue&& q) = default;
+
+    queue& operator=(const queue& q) = default;
+    queue& operator=(queue&& q) = default;
+
+    explicit queue(const container_type& c);
+    explicit queue(container_type&& c)
+    template <class Alloc>
+        explicit queue(const Alloc& a);
+    template <class Alloc>
+        queue(const container_type& c, const Alloc& a);
+    template <class Alloc>
+        queue(container_type&& c, const Alloc& a);
+    template <class Alloc>
+        queue(const queue& q, const Alloc& a);
+    template <class Alloc>
+        queue(queue&& q, const Alloc& a);
+
+    bool      empty() const;
+    size_type size() const;
+
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back() const;
+
+    void push(const value_type& v);
+    void push(value_type&& v);
+    template <class... Args> void emplace(Args&&... args);
+    void pop();
+
+    void swap(queue& q) noexcept(noexcept(swap(c, q.c)));
+};
+
+template <class T, class Container>
+  bool operator==(const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  bool operator< (const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  bool operator!=(const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  bool operator> (const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  bool operator>=(const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y);
+
+template <class T, class Container>
+  void swap(queue<T, Container>& x, queue<T, Container>& y)
+  noexcept(noexcept(x.swap(y)));
+
+template <class T, class Container = vector<T>,
+          class Compare = less<typename Container::value_type>>
+class priority_queue
+{
+public:
+    typedef Container                                container_type;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+    Compare comp;
+
+public:
+    priority_queue() = default;
+    ~priority_queue() = default;
+
+    priority_queue(const priority_queue& q) = default;
+    priority_queue(priority_queue&& q) = default;
+
+    priority_queue& operator=(const priority_queue& q) = default;
+    priority_queue& operator=(priority_queue&& q) = default;
+
+    explicit priority_queue(const Compare& comp);
+    priority_queue(const Compare& comp, const container_type& c);
+    explicit priority_queue(const Compare& comp, container_type&& c);
+    template <class InputIterator>
+        priority_queue(InputIterator first, InputIterator last,
+                       const Compare& comp = Compare());
+    template <class InputIterator>
+        priority_queue(InputIterator first, InputIterator last,
+                       const Compare& comp, const container_type& c);
+    template <class InputIterator>
+        priority_queue(InputIterator first, InputIterator last,
+                       const Compare& comp, container_type&& c);
+    template <class Alloc>
+        explicit priority_queue(const Alloc& a);
+    template <class Alloc>
+        priority_queue(const Compare& comp, const Alloc& a);
+    template <class Alloc>
+        priority_queue(const Compare& comp, const container_type& c,
+                       const Alloc& a);
+    template <class Alloc>
+        priority_queue(const Compare& comp, container_type&& c,
+                       const Alloc& a);
+    template <class Alloc>
+        priority_queue(const priority_queue& q, const Alloc& a);
+    template <class Alloc>
+        priority_queue(priority_queue&& q, const Alloc& a);
+
+    bool            empty() const;
+    size_type       size() const;
+    const_reference top() const;
+
+    void push(const value_type& v);
+    void push(value_type&& v);
+    template <class... Args> void emplace(Args&&... args);
+    void pop();
+
+    void swap(priority_queue& q)
+        noexcept(noexcept(swap(c, q.c)) && noexcept(swap(comp.q.comp)));
+};
+
+template <class T, class Container, class Compare>
+  void swap(priority_queue<T, Container, Compare>& x,
+            priority_queue<T, Container, Compare>& y)
+            noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <deque>
+#include <vector>
+#include <functional>
+#include <algorithm>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS_ONLY queue;
+
+template <class _Tp, class _Container>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);
+
+template <class _Tp, class _Container>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y);
+
+template <class _Tp, class _Container = deque<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY queue
+{
+public:
+    typedef _Container                               container_type;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    queue()
+        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
+        : c() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    queue(const queue& __q) : c(__q.c) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    queue(queue&& __q)
+        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
+        : c(_VSTD::move(__q.c)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    queue& operator=(const queue& __q) {c = __q.c; return *this;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    queue& operator=(queue&& __q)
+        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
+        {c = _VSTD::move(__q.c); return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit queue(const container_type& __c)  : c(__c) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit queue(container_type&& __c) : c(_VSTD::move(__c)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit queue(const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(__a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        queue(const queue& __q, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(__q.c, __a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        queue(const container_type& __c, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(__c, __a) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        queue(container_type&& __c, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(_VSTD::move(__c), __a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        queue(queue&& __q, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(_VSTD::move(__q.c), __a) {}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const {return c.empty();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const  {return c.size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference       front()       {return c.front();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference front() const {return c.front();}
+    _LIBCPP_INLINE_VISIBILITY
+    reference       back()        {return c.back();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference back() const  {return c.back();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void push(const value_type& __v) {c.push_back(__v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void push(value_type&& __v)      {c.push_back(_VSTD::move(__v));}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void emplace(_Args&&... __args)
+            {c.emplace_back(_VSTD::forward<_Args>(__args)...);}
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void pop() {c.pop_front();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(queue& __q)
+        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)
+    {
+        using _VSTD::swap;
+        swap(c, __q.c);
+    }
+
+    template <class _T1, class _C1>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    bool
+    operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
+
+    template <class _T1, class _C1>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    bool
+    operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y);
+};
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return __x.c == __y.c;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return __x.c < __y.c;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Tp, class _Container, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<queue<_Tp, _Container>, _Alloc>
+    : public uses_allocator<_Container, _Alloc>
+{
+};
+
+template <class _Tp, class _Container = vector<_Tp>,
+          class _Compare = less<typename _Container::value_type> >
+class _LIBCPP_TYPE_VIS_ONLY priority_queue
+{
+public:
+    typedef _Container                               container_type;
+    typedef _Compare                                 value_compare;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+    value_compare comp;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    priority_queue()
+        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value &&
+                   is_nothrow_default_constructible<value_compare>::value)
+        : c(), comp() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    priority_queue(const priority_queue& __q) : c(__q.c), comp(__q.comp) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    priority_queue(priority_queue&& __q)
+        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value &&
+                   is_nothrow_move_constructible<value_compare>::value)
+        : c(_VSTD::move(__q.c)), comp(_VSTD::move(__q.comp)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    priority_queue& operator=(const priority_queue& __q)
+        {c = __q.c; comp = __q.comp; return *this;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    priority_queue& operator=(priority_queue&& __q)
+        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value &&
+                   is_nothrow_move_assignable<value_compare>::value)
+        {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit priority_queue(const value_compare& __comp)
+        : c(), comp(__comp) {}
+    priority_queue(const value_compare& __comp, const container_type& __c);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    explicit priority_queue(const value_compare& __comp, container_type&& __c);
+#endif
+    template <class _InputIter>
+        priority_queue(_InputIter __f, _InputIter __l,
+                       const value_compare& __comp = value_compare());
+    template <class _InputIter>
+        priority_queue(_InputIter __f, _InputIter __l,
+                       const value_compare& __comp, const container_type& __c);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIter>
+        priority_queue(_InputIter __f, _InputIter __l,
+                       const value_compare& __comp, container_type&& __c);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        explicit priority_queue(const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+    template <class _Alloc>
+        priority_queue(const value_compare& __comp, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+    template <class _Alloc>
+        priority_queue(const value_compare& __comp, const container_type& __c,
+                       const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+    template <class _Alloc>
+        priority_queue(const priority_queue& __q, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        priority_queue(const value_compare& __comp, container_type&& __c,
+                       const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+    template <class _Alloc>
+        priority_queue(priority_queue&& __q, const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool            empty() const {return c.empty();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type       size() const  {return c.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference top() const   {return c.front();}
+
+    void push(const value_type& __v);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void push(value_type&& __v);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args> void emplace(_Args&&... __args);
+#endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void pop();
+
+    void swap(priority_queue& __q)
+        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
+                   __is_nothrow_swappable<value_compare>::value);
+};
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp,
+                                                          const container_type& __c)
+    : c(__c),
+      comp(__comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
+                                                          container_type&& __c)
+    : c(_VSTD::move(__c)),
+      comp(__comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
+                                                          const value_compare& __comp)
+    : c(__f, __l),
+      comp(__comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+template <class _Tp, class _Container, class _Compare>
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
+                                                          const value_compare& __comp,
+                                                          const container_type& __c)
+    : c(__c),
+      comp(__comp)
+{
+    c.insert(c.end(), __f, __l);
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+template <class _InputIter>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l,
+                                                          const value_compare& __comp,
+                                                          container_type&& __c)
+    : c(_VSTD::move(__c)),
+      comp(__comp)
+{
+    c.insert(c.end(), __f, __l);
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(__a)
+{
+}
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
+                                                          const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(__a),
+      comp(__comp)
+{
+}
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
+                                                          const container_type& __c,
+                                                          const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(__c, __a),
+      comp(__comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q,
+                                                          const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(__q.c, __a),
+      comp(__q.comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp,
+                                                          container_type&& __c,
+                                                          const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(_VSTD::move(__c), __a),
+      comp(__comp)
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+template <class _Tp, class _Container, class _Compare>
+template <class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q,
+                                                          const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type*)
+    : c(_VSTD::move(__q.c), __a),
+      comp(_VSTD::move(__q.comp))
+{
+    _VSTD::make_heap(c.begin(), c.end(), comp);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v)
+{
+    c.push_back(__v);
+    _VSTD::push_heap(c.begin(), c.end(), comp);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v)
+{
+    c.push_back(_VSTD::move(__v));
+    _VSTD::push_heap(c.begin(), c.end(), comp);
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Container, class _Compare>
+template <class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args)
+{
+    c.emplace_back(_VSTD::forward<_Args>(__args)...);
+    _VSTD::push_heap(c.begin(), c.end(), comp);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+priority_queue<_Tp, _Container, _Compare>::pop()
+{
+    _VSTD::pop_heap(c.begin(), c.end(), comp);
+    c.pop_back();
+}
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q)
+        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value &&
+                   __is_nothrow_swappable<value_compare>::value)
+{
+    using _VSTD::swap;
+    swap(c, __q.c);
+    swap(comp, __q.comp);
+}
+
+template <class _Tp, class _Container, class _Compare>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(priority_queue<_Tp, _Container, _Compare>& __x,
+     priority_queue<_Tp, _Container, _Compare>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Tp, class _Container, class _Compare, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<priority_queue<_Tp, _Container, _Compare>, _Alloc>
+    : public uses_allocator<_Container, _Alloc>
+{
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_QUEUE
diff --git a/include/c++/v1/random b/include/c++/v1/random
new file mode 100644
index 0000000..c0db1ab
--- /dev/null
+++ b/include/c++/v1/random
@@ -0,0 +1,6725 @@
+// -*- C++ -*-
+//===--------------------------- random -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_RANDOM
+#define _LIBCPP_RANDOM
+
+/*
+    random synopsis
+
+#include <initializer_list>
+
+namespace std
+{
+
+// Engines
+
+template <class UIntType, UIntType a, UIntType c, UIntType m>
+class linear_congruential_engine
+{
+public:
+    // types
+    typedef UIntType result_type;
+
+    // engine characteristics
+    static constexpr result_type multiplier = a;
+    static constexpr result_type increment = c;
+    static constexpr result_type modulus = m;
+    static constexpr result_type min() { return c == 0u ? 1u: 0u;}
+    static constexpr result_type max() { return m - 1u;}
+    static constexpr result_type default_seed = 1u;
+
+    // constructors and seeding functions
+    explicit linear_congruential_engine(result_type s = default_seed);
+    template<class Sseq> explicit linear_congruential_engine(Sseq& q);
+    void seed(result_type s = default_seed);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()();
+    void discard(unsigned long long z);
+};
+
+template <class UIntType, UIntType a, UIntType c, UIntType m>
+bool
+operator==(const linear_congruential_engine<UIntType, a, c, m>& x,
+           const linear_congruential_engine<UIntType, a, c, m>& y);
+
+template <class UIntType, UIntType a, UIntType c, UIntType m>
+bool
+operator!=(const linear_congruential_engine<UIntType, a, c, m>& x,
+           const linear_congruential_engine<UIntType, a, c, m>& y);
+
+template <class charT, class traits,
+          class UIntType, UIntType a, UIntType c, UIntType m>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const linear_congruential_engine<UIntType, a, c, m>& x);
+
+template <class charT, class traits,
+          class UIntType, UIntType a, UIntType c, UIntType m>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           linear_congruential_engine<UIntType, a, c, m>& x);
+
+template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
+class mersenne_twister_engine
+{
+public:
+    // types
+    typedef UIntType result_type;
+
+    // engine characteristics
+    static constexpr size_t word_size = w;
+    static constexpr size_t state_size = n;
+    static constexpr size_t shift_size = m;
+    static constexpr size_t mask_bits = r;
+    static constexpr result_type xor_mask = a;
+    static constexpr size_t tempering_u = u;
+    static constexpr result_type tempering_d = d;
+    static constexpr size_t tempering_s = s;
+    static constexpr result_type tempering_b = b;
+    static constexpr size_t tempering_t = t;
+    static constexpr result_type tempering_c = c;
+    static constexpr size_t tempering_l = l;
+    static constexpr result_type initialization_multiplier = f;
+    static constexpr result_type min () { return 0; }
+    static constexpr result_type max() { return 2^w - 1; }
+    static constexpr result_type default_seed = 5489u;
+
+    // constructors and seeding functions
+    explicit mersenne_twister_engine(result_type value = default_seed);
+    template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
+    void seed(result_type value = default_seed);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()();
+    void discard(unsigned long long z);
+};
+
+template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
+bool
+operator==(
+    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,
+    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);
+
+template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
+bool
+operator!=(
+    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,
+    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);
+
+template <class charT, class traits,
+          class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);
+
+template <class charT, class traits,
+          class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);
+
+template<class UIntType, size_t w, size_t s, size_t r>
+class subtract_with_carry_engine
+{
+public:
+    // types
+    typedef UIntType result_type;
+
+    // engine characteristics
+    static constexpr size_t word_size = w;
+    static constexpr size_t short_lag = s;
+    static constexpr size_t long_lag = r;
+    static constexpr result_type min() { return 0; }
+    static constexpr result_type max() { return m-1; }
+    static constexpr result_type default_seed = 19780503u;
+
+    // constructors and seeding functions
+    explicit subtract_with_carry_engine(result_type value = default_seed);
+    template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
+    void seed(result_type value = default_seed);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()();
+    void discard(unsigned long long z);
+};
+
+template<class UIntType, size_t w, size_t s, size_t r>
+bool
+operator==(
+    const subtract_with_carry_engine<UIntType, w, s, r>& x,
+    const subtract_with_carry_engine<UIntType, w, s, r>& y);
+
+template<class UIntType, size_t w, size_t s, size_t r>
+bool
+operator!=(
+    const subtract_with_carry_engine<UIntType, w, s, r>& x,
+    const subtract_with_carry_engine<UIntType, w, s, r>& y);
+
+template <class charT, class traits,
+          class UIntType, size_t w, size_t s, size_t r>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const subtract_with_carry_engine<UIntType, w, s, r>& x);
+
+template <class charT, class traits,
+          class UIntType, size_t w, size_t s, size_t r>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           subtract_with_carry_engine<UIntType, w, s, r>& x);
+
+template<class Engine, size_t p, size_t r>
+class discard_block_engine
+{
+public:
+    // types
+    typedef typename Engine::result_type result_type;
+
+    // engine characteristics
+    static constexpr size_t block_size = p;
+    static constexpr size_t used_block = r;
+    static constexpr result_type min() { return Engine::min(); }
+    static constexpr result_type max() { return Engine::max(); }
+
+    // constructors and seeding functions
+    discard_block_engine();
+    explicit discard_block_engine(const Engine& e);
+    explicit discard_block_engine(Engine&& e);
+    explicit discard_block_engine(result_type s);
+    template<class Sseq> explicit discard_block_engine(Sseq& q);
+    void seed();
+    void seed(result_type s);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()();
+    void discard(unsigned long long z);
+
+    // property functions
+    const Engine& base() const noexcept;
+};
+
+template<class Engine, size_t p, size_t r>
+bool
+operator==(
+    const discard_block_engine<Engine, p, r>& x,
+    const discard_block_engine<Engine, p, r>& y);
+
+template<class Engine, size_t p, size_t r>
+bool
+operator!=(
+    const discard_block_engine<Engine, p, r>& x,
+    const discard_block_engine<Engine, p, r>& y);
+
+template <class charT, class traits,
+          class Engine, size_t p, size_t r>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const discard_block_engine<Engine, p, r>& x);
+
+template <class charT, class traits,
+          class Engine, size_t p, size_t r>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           discard_block_engine<Engine, p, r>& x);
+
+template<class Engine, size_t w, class UIntType>
+class independent_bits_engine
+{
+public:
+    // types
+    typedef UIntType result_type;
+
+    // engine characteristics
+    static constexpr result_type min() { return 0; }
+    static constexpr result_type max() { return 2^w - 1; }
+
+    // constructors and seeding functions
+    independent_bits_engine();
+    explicit independent_bits_engine(const Engine& e);
+    explicit independent_bits_engine(Engine&& e);
+    explicit independent_bits_engine(result_type s);
+    template<class Sseq> explicit independent_bits_engine(Sseq& q);
+    void seed();
+    void seed(result_type s);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()(); void discard(unsigned long long z);
+
+    // property functions
+    const Engine& base() const noexcept;
+};
+
+template<class Engine, size_t w, class UIntType>
+bool
+operator==(
+    const independent_bits_engine<Engine, w, UIntType>& x,
+    const independent_bits_engine<Engine, w, UIntType>& y);
+
+template<class Engine, size_t w, class UIntType>
+bool
+operator!=(
+    const independent_bits_engine<Engine, w, UIntType>& x,
+    const independent_bits_engine<Engine, w, UIntType>& y);
+
+template <class charT, class traits,
+          class Engine, size_t w, class UIntType>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const independent_bits_engine<Engine, w, UIntType>& x);
+
+template <class charT, class traits,
+          class Engine, size_t w, class UIntType>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           independent_bits_engine<Engine, w, UIntType>& x);
+
+template<class Engine, size_t k>
+class shuffle_order_engine
+{
+public:
+    // types
+    typedef typename Engine::result_type result_type;
+
+    // engine characteristics
+    static constexpr size_t table_size = k;
+    static constexpr result_type min() { return Engine::min; }
+    static constexpr result_type max() { return Engine::max; }
+
+    // constructors and seeding functions
+    shuffle_order_engine();
+    explicit shuffle_order_engine(const Engine& e);
+    explicit shuffle_order_engine(Engine&& e);
+    explicit shuffle_order_engine(result_type s);
+    template<class Sseq> explicit shuffle_order_engine(Sseq& q);
+    void seed();
+    void seed(result_type s);
+    template<class Sseq> void seed(Sseq& q);
+
+    // generating functions
+    result_type operator()();
+    void discard(unsigned long long z);
+
+    // property functions
+    const Engine& base() const noexcept;
+};
+
+template<class Engine, size_t k>
+bool
+operator==(
+    const shuffle_order_engine<Engine, k>& x,
+    const shuffle_order_engine<Engine, k>& y);
+
+template<class Engine, size_t k>
+bool
+operator!=(
+    const shuffle_order_engine<Engine, k>& x,
+    const shuffle_order_engine<Engine, k>& y);
+
+template <class charT, class traits,
+          class Engine, size_t k>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os,
+           const shuffle_order_engine<Engine, k>& x);
+
+template <class charT, class traits,
+          class Engine, size_t k>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is,
+           shuffle_order_engine<Engine, k>& x);
+
+typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
+                                                                   minstd_rand0;
+typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
+                                                                    minstd_rand;
+typedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
+                                0x9908b0df,
+                                11, 0xffffffff,
+                                7,  0x9d2c5680,
+                                15, 0xefc60000,
+                                18, 1812433253>                         mt19937;
+typedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
+                                0xb5026f5aa96619e9,
+                                29, 0x5555555555555555,
+                                17, 0x71d67fffeda60000,
+                                37, 0xfff7eee000000000,
+                                43, 6364136223846793005>             mt19937_64;
+typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;
+typedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;
+typedef discard_block_engine<ranlux24_base, 223, 23>                   ranlux24;
+typedef discard_block_engine<ranlux48_base, 389, 11>                   ranlux48;
+typedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;
+typedef minstd_rand                                       default_random_engine;
+
+// Generators
+
+class random_device
+{
+public:
+    // types
+    typedef unsigned int result_type;
+
+    // generator characteristics
+    static constexpr result_type min() { return numeric_limits<result_type>::min(); }
+    static constexpr result_type max() { return numeric_limits<result_type>::max(); }
+
+    // constructors
+    explicit random_device(const string& token = "/dev/urandom");
+
+    // generating functions
+    result_type operator()();
+
+    // property functions
+    double entropy() const noexcept;
+
+    // no copy functions
+    random_device(const random_device& ) = delete;
+    void operator=(const random_device& ) = delete;
+};
+
+// Utilities
+
+class seed_seq
+{
+public:
+    // types
+    typedef uint_least32_t result_type;
+
+    // constructors
+    seed_seq();
+    template<class T>
+        seed_seq(initializer_list<T> il);
+    template<class InputIterator>
+        seed_seq(InputIterator begin, InputIterator end);
+
+    // generating functions
+    template<class RandomAccessIterator>
+        void generate(RandomAccessIterator begin, RandomAccessIterator end);
+
+    // property functions
+    size_t size() const;
+    template<class OutputIterator>
+        void param(OutputIterator dest) const;
+
+    // no copy functions
+    seed_seq(const seed_seq&) = delete;
+    void operator=(const seed_seq& ) = delete;
+};
+
+template<class RealType, size_t bits, class URNG>
+    RealType generate_canonical(URNG& g);
+
+// Distributions
+
+template<class IntType = int>
+class uniform_int_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef uniform_int_distribution distribution_type;
+
+        explicit param_type(IntType a = 0,
+                                    IntType b = numeric_limits<IntType>::max());
+
+        result_type a() const;
+        result_type b() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit uniform_int_distribution(IntType a = 0,
+                                    IntType b = numeric_limits<IntType>::max());
+    explicit uniform_int_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type a() const;
+    result_type b() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const uniform_int_distribution& x,
+                           const uniform_int_distribution& y);
+    friend bool operator!=(const uniform_int_distribution& x,
+                           const uniform_int_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const uniform_int_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               uniform_int_distribution& x);
+};
+
+template<class RealType = double>
+class uniform_real_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef uniform_real_distribution distribution_type;
+
+        explicit param_type(RealType a = 0,
+                            RealType b = 1);
+
+        result_type a() const;
+        result_type b() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
+    explicit uniform_real_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type a() const;
+    result_type b() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const uniform_real_distribution& x,
+                           const uniform_real_distribution& y);
+    friend bool operator!=(const uniform_real_distribution& x,
+                           const uniform_real_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const uniform_real_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               uniform_real_distribution& x);
+};
+
+class bernoulli_distribution
+{
+public:
+    // types
+    typedef bool result_type;
+
+    class param_type
+    {
+    public:
+        typedef bernoulli_distribution distribution_type;
+
+        explicit param_type(double p = 0.5);
+
+        double p() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit bernoulli_distribution(double p = 0.5);
+    explicit bernoulli_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    double p() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const bernoulli_distribution& x,
+                           const bernoulli_distribution& y);
+    friend bool operator!=(const bernoulli_distribution& x,
+                           const bernoulli_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const bernoulli_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               bernoulli_distribution& x);
+};
+
+template<class IntType = int>
+class binomial_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef binomial_distribution distribution_type;
+
+        explicit param_type(IntType t = 1, double p = 0.5);
+
+        IntType t() const;
+        double p() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit binomial_distribution(IntType t = 1, double p = 0.5);
+    explicit binomial_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    IntType t() const;
+    double p() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const binomial_distribution& x,
+                           const binomial_distribution& y);
+    friend bool operator!=(const binomial_distribution& x,
+                           const binomial_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const binomial_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               binomial_distribution& x);
+};
+
+template<class IntType = int>
+class geometric_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef geometric_distribution distribution_type;
+
+        explicit param_type(double p = 0.5);
+
+        double p() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit geometric_distribution(double p = 0.5);
+    explicit geometric_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    double p() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const geometric_distribution& x,
+                           const geometric_distribution& y);
+    friend bool operator!=(const geometric_distribution& x,
+                           const geometric_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const geometric_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               geometric_distribution& x);
+};
+
+template<class IntType = int>
+class negative_binomial_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef negative_binomial_distribution distribution_type;
+
+        explicit param_type(result_type k = 1, double p = 0.5);
+
+        result_type k() const;
+        double p() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit negative_binomial_distribution(result_type k = 1, double p = 0.5);
+    explicit negative_binomial_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type k() const;
+    double p() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const negative_binomial_distribution& x,
+                           const negative_binomial_distribution& y);
+    friend bool operator!=(const negative_binomial_distribution& x,
+                           const negative_binomial_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const negative_binomial_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               negative_binomial_distribution& x);
+};
+
+template<class IntType = int>
+class poisson_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef poisson_distribution distribution_type;
+
+        explicit param_type(double mean = 1.0);
+
+        double mean() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit poisson_distribution(double mean = 1.0);
+    explicit poisson_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    double mean() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const poisson_distribution& x,
+                           const poisson_distribution& y);
+    friend bool operator!=(const poisson_distribution& x,
+                           const poisson_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const poisson_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               poisson_distribution& x);
+};
+
+template<class RealType = double>
+class exponential_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef exponential_distribution distribution_type;
+
+        explicit param_type(result_type lambda = 1.0);
+
+        result_type lambda() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit exponential_distribution(result_type lambda = 1.0);
+    explicit exponential_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type lambda() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const exponential_distribution& x,
+                           const exponential_distribution& y);
+    friend bool operator!=(const exponential_distribution& x,
+                           const exponential_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const exponential_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               exponential_distribution& x);
+};
+
+template<class RealType = double>
+class gamma_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef gamma_distribution distribution_type;
+
+        explicit param_type(result_type alpha = 1, result_type beta = 1);
+
+        result_type alpha() const;
+        result_type beta() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit gamma_distribution(result_type alpha = 1, result_type beta = 1);
+    explicit gamma_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type alpha() const;
+    result_type beta() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const gamma_distribution& x,
+                           const gamma_distribution& y);
+    friend bool operator!=(const gamma_distribution& x,
+                           const gamma_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const gamma_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               gamma_distribution& x);
+};
+
+template<class RealType = double>
+class weibull_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef weibull_distribution distribution_type;
+
+        explicit param_type(result_type alpha = 1, result_type beta = 1);
+
+        result_type a() const;
+        result_type b() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit weibull_distribution(result_type a = 1, result_type b = 1);
+    explicit weibull_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type a() const;
+    result_type b() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const weibull_distribution& x,
+                           const weibull_distribution& y);
+    friend bool operator!=(const weibull_distribution& x,
+                           const weibull_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const weibull_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               weibull_distribution& x);
+};
+
+template<class RealType = double>
+class extreme_value_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef extreme_value_distribution distribution_type;
+
+        explicit param_type(result_type a = 0, result_type b = 1);
+
+        result_type a() const;
+        result_type b() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit extreme_value_distribution(result_type a = 0, result_type b = 1);
+    explicit extreme_value_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type a() const;
+    result_type b() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const extreme_value_distribution& x,
+                           const extreme_value_distribution& y);
+    friend bool operator!=(const extreme_value_distribution& x,
+                           const extreme_value_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const extreme_value_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               extreme_value_distribution& x);
+};
+
+template<class RealType = double>
+class normal_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef normal_distribution distribution_type;
+
+        explicit param_type(result_type mean = 0, result_type stddev = 1);
+
+        result_type mean() const;
+        result_type stddev() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructors and reset functions
+    explicit normal_distribution(result_type mean = 0, result_type stddev = 1);
+    explicit normal_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type mean() const;
+    result_type stddev() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const normal_distribution& x,
+                           const normal_distribution& y);
+    friend bool operator!=(const normal_distribution& x,
+                           const normal_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const normal_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               normal_distribution& x);
+};
+
+template<class RealType = double>
+class lognormal_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef lognormal_distribution distribution_type;
+
+        explicit param_type(result_type m = 0, result_type s = 1);
+
+        result_type m() const;
+        result_type s() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit lognormal_distribution(result_type m = 0, result_type s = 1);
+    explicit lognormal_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type m() const;
+    result_type s() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const lognormal_distribution& x,
+                           const lognormal_distribution& y);
+    friend bool operator!=(const lognormal_distribution& x,
+                           const lognormal_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const lognormal_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               lognormal_distribution& x);
+};
+
+template<class RealType = double>
+class chi_squared_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef chi_squared_distribution distribution_type;
+
+        explicit param_type(result_type n = 1);
+
+        result_type n() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit chi_squared_distribution(result_type n = 1);
+    explicit chi_squared_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type n() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const chi_squared_distribution& x,
+                           const chi_squared_distribution& y);
+    friend bool operator!=(const chi_squared_distribution& x,
+                           const chi_squared_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const chi_squared_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               chi_squared_distribution& x);
+};
+
+template<class RealType = double>
+class cauchy_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef cauchy_distribution distribution_type;
+
+        explicit param_type(result_type a = 0, result_type b = 1);
+
+        result_type a() const;
+        result_type b() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit cauchy_distribution(result_type a = 0, result_type b = 1);
+    explicit cauchy_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type a() const;
+    result_type b() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const cauchy_distribution& x,
+                           const cauchy_distribution& y);
+    friend bool operator!=(const cauchy_distribution& x,
+                           const cauchy_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const cauchy_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               cauchy_distribution& x);
+};
+
+template<class RealType = double>
+class fisher_f_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef fisher_f_distribution distribution_type;
+
+        explicit param_type(result_type m = 1, result_type n = 1);
+
+        result_type m() const;
+        result_type n() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit fisher_f_distribution(result_type m = 1, result_type n = 1);
+    explicit fisher_f_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type m() const;
+    result_type n() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const fisher_f_distribution& x,
+                           const fisher_f_distribution& y);
+    friend bool operator!=(const fisher_f_distribution& x,
+                           const fisher_f_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const fisher_f_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               fisher_f_distribution& x);
+};
+
+template<class RealType = double>
+class student_t_distribution
+{
+public:
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef student_t_distribution distribution_type;
+
+        explicit param_type(result_type n = 1);
+
+        result_type n() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    explicit student_t_distribution(result_type n = 1);
+    explicit student_t_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    result_type n() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const student_t_distribution& x,
+                           const student_t_distribution& y);
+    friend bool operator!=(const student_t_distribution& x,
+                           const student_t_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const student_t_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               student_t_distribution& x);
+};
+
+template<class IntType = int>
+class discrete_distribution
+{
+public:
+    // types
+    typedef IntType result_type;
+
+    class param_type
+    {
+    public:
+        typedef discrete_distribution distribution_type;
+
+        param_type();
+        template<class InputIterator>
+            param_type(InputIterator firstW, InputIterator lastW);
+        param_type(initializer_list<double> wl);
+        template<class UnaryOperation>
+            param_type(size_t nw, double xmin, double xmax, UnaryOperation fw);
+
+        vector<double> probabilities() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    discrete_distribution();
+    template<class InputIterator>
+        discrete_distribution(InputIterator firstW, InputIterator lastW);
+    discrete_distribution(initializer_list<double> wl);
+    template<class UnaryOperation>
+        discrete_distribution(size_t nw, double xmin, double xmax,
+                              UnaryOperation fw);
+    explicit discrete_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    vector<double> probabilities() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const discrete_distribution& x,
+                           const discrete_distribution& y);
+    friend bool operator!=(const discrete_distribution& x,
+                           const discrete_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const discrete_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               discrete_distribution& x);
+};
+
+template<class RealType = double>
+class piecewise_constant_distribution
+{
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef piecewise_constant_distribution distribution_type;
+
+        param_type();
+        template<class InputIteratorB, class InputIteratorW>
+            param_type(InputIteratorB firstB, InputIteratorB lastB,
+                       InputIteratorW firstW);
+        template<class UnaryOperation>
+            param_type(initializer_list<result_type> bl, UnaryOperation fw);
+        template<class UnaryOperation>
+            param_type(size_t nw, result_type xmin, result_type xmax,
+                       UnaryOperation fw);
+
+        vector<result_type> intervals() const;
+        vector<result_type> densities() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    piecewise_constant_distribution();
+    template<class InputIteratorB, class InputIteratorW>
+        piecewise_constant_distribution(InputIteratorB firstB,
+                                        InputIteratorB lastB,
+                                        InputIteratorW firstW);
+    template<class UnaryOperation>
+        piecewise_constant_distribution(initializer_list<result_type> bl,
+                                        UnaryOperation fw);
+    template<class UnaryOperation>
+        piecewise_constant_distribution(size_t nw, result_type xmin,
+                                        result_type xmax, UnaryOperation fw);
+    explicit piecewise_constant_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    vector<result_type> intervals() const;
+    vector<result_type> densities() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const piecewise_constant_distribution& x,
+                           const piecewise_constant_distribution& y);
+    friend bool operator!=(const piecewise_constant_distribution& x,
+                           const piecewise_constant_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const piecewise_constant_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               piecewise_constant_distribution& x);
+};
+
+template<class RealType = double>
+class piecewise_linear_distribution
+{
+    // types
+    typedef RealType result_type;
+
+    class param_type
+    {
+    public:
+        typedef piecewise_linear_distribution distribution_type;
+
+        param_type();
+        template<class InputIteratorB, class InputIteratorW>
+            param_type(InputIteratorB firstB, InputIteratorB lastB,
+                       InputIteratorW firstW);
+        template<class UnaryOperation>
+            param_type(initializer_list<result_type> bl, UnaryOperation fw);
+        template<class UnaryOperation>
+            param_type(size_t nw, result_type xmin, result_type xmax,
+                       UnaryOperation fw);
+
+        vector<result_type> intervals() const;
+        vector<result_type> densities() const;
+
+        friend bool operator==(const param_type& x, const param_type& y);
+        friend bool operator!=(const param_type& x, const param_type& y);
+    };
+
+    // constructor and reset functions
+    piecewise_linear_distribution();
+    template<class InputIteratorB, class InputIteratorW>
+        piecewise_linear_distribution(InputIteratorB firstB,
+                                      InputIteratorB lastB,
+                                      InputIteratorW firstW);
+
+    template<class UnaryOperation>
+        piecewise_linear_distribution(initializer_list<result_type> bl,
+                                      UnaryOperation fw);
+
+    template<class UnaryOperation>
+        piecewise_linear_distribution(size_t nw, result_type xmin,
+                                      result_type xmax, UnaryOperation fw);
+
+    explicit piecewise_linear_distribution(const param_type& parm);
+    void reset();
+
+    // generating functions
+    template<class URNG> result_type operator()(URNG& g);
+    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
+
+    // property functions
+    vector<result_type> intervals() const;
+    vector<result_type> densities() const;
+
+    param_type param() const;
+    void param(const param_type& parm);
+
+    result_type min() const;
+    result_type max() const;
+
+    friend bool operator==(const piecewise_linear_distribution& x,
+                           const piecewise_linear_distribution& y);
+    friend bool operator!=(const piecewise_linear_distribution& x,
+                           const piecewise_linear_distribution& y);
+
+    template <class charT, class traits>
+    friend
+    basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os,
+               const piecewise_linear_distribution& x);
+
+    template <class charT, class traits>
+    friend
+    basic_istream<charT, traits>&
+    operator>>(basic_istream<charT, traits>& is,
+               piecewise_linear_distribution& x);
+};
+
+} // std
+*/
+
+#include <__config>
+#include <cstddef>
+#include <type_traits>
+#include <initializer_list>
+#include <cstdint>
+#include <limits>
+#include <algorithm>
+#include <numeric>
+#include <vector>
+#include <string>
+#include <istream>
+#include <ostream>
+#include <cmath>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __is_seed_sequence
+
+template <class _Sseq, class _Engine>
+struct __is_seed_sequence
+{
+    static _LIBCPP_CONSTEXPR const bool value =
+              !is_convertible<_Sseq, typename _Engine::result_type>::value &&
+              !is_same<typename remove_cv<_Sseq>::type, _Engine>::value;
+};
+
+// linear_congruential_engine
+
+template <unsigned long long __a, unsigned long long __c,
+          unsigned long long __m, unsigned long long _Mp,
+          bool _MightOverflow = (__a != 0 && __m != 0 && __m-1 > (_Mp-__c)/__a)>
+struct __lce_ta;
+
+// 64
+
+template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
+struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true>
+{
+    typedef unsigned long long result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        // Schrage's algorithm
+        const result_type __q = __m / __a;
+        const result_type __r = __m % __a;
+        const result_type __t0 = __a * (__x % __q);
+        const result_type __t1 = __r * (__x / __q);
+        __x = __t0 + (__t0 < __t1) * __m - __t1;
+        __x += __c - (__x >= __m - __c) * __m;
+        return __x;
+    }
+};
+
+template <unsigned long long __a, unsigned long long __m>
+struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true>
+{
+    typedef unsigned long long result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        // Schrage's algorithm
+        const result_type __q = __m / __a;
+        const result_type __r = __m % __a;
+        const result_type __t0 = __a * (__x % __q);
+        const result_type __t1 = __r * (__x / __q);
+        __x = __t0 + (__t0 < __t1) * __m - __t1;
+        return __x;
+    }
+};
+
+template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
+struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false>
+{
+    typedef unsigned long long result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        return (__a * __x + __c) % __m;
+    }
+};
+
+template <unsigned long long __a, unsigned long long __c>
+struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false>
+{
+    typedef unsigned long long result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        return __a * __x + __c;
+    }
+};
+
+// 32
+
+template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
+struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true>
+{
+    typedef unsigned result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        const result_type __a = static_cast<result_type>(_Ap);
+        const result_type __c = static_cast<result_type>(_Cp);
+        const result_type __m = static_cast<result_type>(_Mp);
+        // Schrage's algorithm
+        const result_type __q = __m / __a;
+        const result_type __r = __m % __a;
+        const result_type __t0 = __a * (__x % __q);
+        const result_type __t1 = __r * (__x / __q);
+        __x = __t0 + (__t0 < __t1) * __m - __t1;
+        __x += __c - (__x >= __m - __c) * __m;
+        return __x;
+    }
+};
+
+template <unsigned long long _Ap, unsigned long long _Mp>
+struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true>
+{
+    typedef unsigned result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        const result_type __a = static_cast<result_type>(_Ap);
+        const result_type __m = static_cast<result_type>(_Mp);
+        // Schrage's algorithm
+        const result_type __q = __m / __a;
+        const result_type __r = __m % __a;
+        const result_type __t0 = __a * (__x % __q);
+        const result_type __t1 = __r * (__x / __q);
+        __x = __t0 + (__t0 < __t1) * __m - __t1;
+        return __x;
+    }
+};
+
+template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
+struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false>
+{
+    typedef unsigned result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        const result_type __a = static_cast<result_type>(_Ap);
+        const result_type __c = static_cast<result_type>(_Cp);
+        const result_type __m = static_cast<result_type>(_Mp);
+        return (__a * __x + __c) % __m;
+    }
+};
+
+template <unsigned long long _Ap, unsigned long long _Cp>
+struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false>
+{
+    typedef unsigned result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        const result_type __a = static_cast<result_type>(_Ap);
+        const result_type __c = static_cast<result_type>(_Cp);
+        return __a * __x + __c;
+    }
+};
+
+// 16
+
+template <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b>
+struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b>
+{
+    typedef unsigned short result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type next(result_type __x)
+    {
+        return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x));
+    }
+};
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+class _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine;
+
+template <class _CharT, class _Traits,
+          class _Up, _Up _Ap, _Up _Cp, _Up _Np>
+_LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
+
+template <class _CharT, class _Traits,
+          class _Up, _Up _Ap, _Up _Cp, _Up _Np>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+class _LIBCPP_TYPE_VIS_ONLY linear_congruential_engine
+{
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    result_type __x_;
+
+    static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0);
+
+    static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters");
+    static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
+public:
+    static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u;
+    static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u;
+    static_assert(_Min < _Max,           "linear_congruential_engine invalid parameters");
+
+    // engine characteristics
+    static _LIBCPP_CONSTEXPR const result_type multiplier = __a;
+    static _LIBCPP_CONSTEXPR const result_type increment = __c;
+    static _LIBCPP_CONSTEXPR const result_type modulus = __m;
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
+    static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit linear_congruential_engine(result_type __s = default_seed)
+        {seed(__s);}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit linear_congruential_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0)
+        {seed(__q);}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(result_type __s = default_seed)
+        {seed(integral_constant<bool, __m == 0>(),
+              integral_constant<bool, __c == 0>(), __s);}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, linear_congruential_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q)
+            {__seed(__q, integral_constant<unsigned,
+                1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1)/32
+                             :  (__m > 0x100000000ull))>());}
+
+    // generating functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()()
+        {return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_));}
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const linear_congruential_engine& __x,
+                    const linear_congruential_engine& __y)
+        {return __x.__x_ == __y.__x_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const linear_congruential_engine& __x,
+                    const linear_congruential_engine& __y)
+        {return !(__x == __y);}
+
+private:
+
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(true_type, false_type, result_type __s) {__x_ = __s;}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ?
+                                                                 1 : __s % __m;}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}
+
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+
+    template <class _CharT, class _Traits,
+              class _Up, _Up _Ap, _Up _Cp, _Up _Np>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
+
+    template <class _CharT, class _Traits,
+              class _Up, _Up _Ap, _Up _Cp, _Up _Np>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
+};
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
+    linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
+    linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
+    linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
+    linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+template<class _Sseq>
+void
+linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
+                                                 integral_constant<unsigned, 1>)
+{
+    const unsigned __k = 1;
+    uint32_t __ar[__k+3];
+    __q.generate(__ar, __ar + __k + 3);
+    result_type __s = static_cast<result_type>(__ar[3] % __m);
+    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
+}
+
+template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+template<class _Sseq>
+void
+linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
+                                                 integral_constant<unsigned, 2>)
+{
+    const unsigned __k = 2;
+    uint32_t __ar[__k+3];
+    __q.generate(__ar, __ar + __k + 3);
+    result_type __s = static_cast<result_type>((__ar[3] +
+                                              ((uint64_t)__ar[4] << 32)) % __m);
+    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
+}
+
+template <class _CharT, class _Traits,
+          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    __os.fill(__os.widen(' '));
+    return __os << __x.__x_;
+}
+
+template <class _CharT, class _Traits,
+          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    _UIntType __t;
+    __is >> __t;
+    if (!__is.fail())
+        __x.__x_ = __t;
+    return __is;
+}
+
+typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
+                                                                   minstd_rand0;
+typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
+                                                                    minstd_rand;
+typedef minstd_rand                                       default_random_engine;
+// mersenne_twister_engine
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+class _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine;
+
+template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+bool
+operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
+
+template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+class _LIBCPP_TYPE_VIS_ONLY mersenne_twister_engine
+{
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    result_type __x_[__n];
+    size_t      __i_;
+
+    static_assert(  0 <  __m, "mersenne_twister_engine invalid parameters");
+    static_assert(__m <= __n, "mersenne_twister_engine invalid parameters");
+    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
+    static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters");
+    static_assert(  2 <= __w, "mersenne_twister_engine invalid parameters");
+    static_assert(__r <= __w, "mersenne_twister_engine invalid parameters");
+    static_assert(__u <= __w, "mersenne_twister_engine invalid parameters");
+    static_assert(__s <= __w, "mersenne_twister_engine invalid parameters");
+    static_assert(__t <= __w, "mersenne_twister_engine invalid parameters");
+    static_assert(__l <= __w, "mersenne_twister_engine invalid parameters");
+public:
+    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
+    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
+                                                      (result_type(1) << __w) - result_type(1);
+    static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters");
+    static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters");
+    static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters");
+    static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters");
+    static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters");
+    static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters");
+
+    // engine characteristics
+    static _LIBCPP_CONSTEXPR const size_t word_size = __w;
+    static _LIBCPP_CONSTEXPR const size_t state_size = __n;
+    static _LIBCPP_CONSTEXPR const size_t shift_size = __m;
+    static _LIBCPP_CONSTEXPR const size_t mask_bits = __r;
+    static _LIBCPP_CONSTEXPR const result_type xor_mask = __a;
+    static _LIBCPP_CONSTEXPR const size_t tempering_u = __u;
+    static _LIBCPP_CONSTEXPR const result_type tempering_d = __d;
+    static _LIBCPP_CONSTEXPR const size_t tempering_s = __s;
+    static _LIBCPP_CONSTEXPR const result_type tempering_b = __b;
+    static _LIBCPP_CONSTEXPR const size_t tempering_t = __t;
+    static _LIBCPP_CONSTEXPR const result_type tempering_c = __c;
+    static _LIBCPP_CONSTEXPR const size_t tempering_l = __l;
+    static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f;
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
+    static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit mersenne_twister_engine(result_type __sd = default_seed)
+        {seed(__sd);}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit mersenne_twister_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)
+        {seed(__q);}
+    void seed(result_type __sd = default_seed);
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, mersenne_twister_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q)
+            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
+
+    // generating functions
+    result_type operator()();
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+    friend
+    bool
+    operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
+
+    template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+    friend
+    bool
+    operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
+
+    template <class _CharT, class _Traits,
+              class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
+
+    template <class _CharT, class _Traits,
+              class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+              _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+              _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                       _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
+private:
+
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            __count < __w,
+            result_type
+        >::type
+        __lshift(result_type __x) {return (__x << __count) & _Max;}
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            (__count >= __w),
+            result_type
+        >::type
+        __lshift(result_type) {return result_type(0);}
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            __count < _Dt,
+            result_type
+        >::type
+        __rshift(result_type __x) {return __x >> __count;}
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            (__count >= _Dt),
+            result_type
+        >::type
+        __rshift(result_type) {return result_type(0);}
+};
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const size_t 
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
+    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed;
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+void
+mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
+    __t, __c, __l, __f>::seed(result_type __sd)
+{   // __w >= 2
+    __x_[0] = __sd & _Max;
+    for (size_t __i = 1; __i < __n; ++__i)
+        __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max;
+    __i_ = 0;
+}
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+template<class _Sseq>
+void
+mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
+    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 1>)
+{
+    const unsigned __k = 1;
+    uint32_t __ar[__n * __k];
+    __q.generate(__ar, __ar + __n * __k);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
+    const result_type __mask = __r == _Dt ? result_type(~0) :
+                                       (result_type(1) << __r) - result_type(1);
+    __i_ = 0;
+    if ((__x_[0] & ~__mask) == 0)
+    {
+        for (size_t __i = 1; __i < __n; ++__i)
+            if (__x_[__i] != 0)
+                return;
+        __x_[0] = _Max;
+    }
+}
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+template<class _Sseq>
+void
+mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
+    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 2>)
+{
+    const unsigned __k = 2;
+    uint32_t __ar[__n * __k];
+    __q.generate(__ar, __ar + __n * __k);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __x_[__i] = static_cast<result_type>(
+            (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
+    const result_type __mask = __r == _Dt ? result_type(~0) :
+                                       (result_type(1) << __r) - result_type(1);
+    __i_ = 0;
+    if ((__x_[0] & ~__mask) == 0)
+    {
+        for (size_t __i = 1; __i < __n; ++__i)
+            if (__x_[__i] != 0)
+                return;
+        __x_[0] = _Max;
+    }
+}
+
+template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
+          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
+          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
+_UIntType
+mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
+    __t, __c, __l, __f>::operator()()
+{
+    const size_t __j = (__i_ + 1) % __n;
+    const result_type __mask = __r == _Dt ? result_type(~0) :
+                                       (result_type(1) << __r) - result_type(1);
+    const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
+    const size_t __k = (__i_ + __m) % __n;
+    __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1));
+    result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
+    __i_ = __j;
+    __z ^= __lshift<__s>(__z) & __b;
+    __z ^= __lshift<__t>(__z) & __c;
+    return __z ^ __rshift<__l>(__z);
+}
+
+template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+bool
+operator==(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
+{
+    if (__x.__i_ == __y.__i_)
+        return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_);
+    if (__x.__i_ == 0 || __y.__i_ == 0)
+    {
+        size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_);
+        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,
+                         __y.__x_ + __y.__i_))
+            return false;
+        if (__x.__i_ == 0)
+            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_);
+        return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j);
+    }
+    if (__x.__i_ < __y.__i_)
+    {
+        size_t __j = _Np - __y.__i_;
+        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),
+                         __y.__x_ + __y.__i_))
+            return false;
+        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np,
+                         __y.__x_))
+            return false;
+        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,
+                           __y.__x_ + (_Np - (__x.__i_ + __j)));
+    }
+    size_t __j = _Np - __x.__i_;
+    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),
+                     __x.__x_ + __x.__i_))
+        return false;
+    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np,
+                     __x.__x_))
+        return false;
+    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,
+                       __x.__x_ + (_Np - (__y.__i_ + __j)));
+}
+
+template <class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.__x_[__x.__i_];
+    for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j)
+        __os << __sp << __x.__x_[__j];
+    for (size_t __j = 0; __j < __x.__i_; ++__j)
+        __os << __sp << __x.__x_[__j];
+    return __os;
+}
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
+          _UI _Ap, size_t _Up, _UI _Dp, size_t _Sp,
+          _UI _Bp, size_t _Tp, _UI _Cp, size_t _Lp, _UI _Fp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           mersenne_twister_engine<_UI, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
+                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    _UI __t[_Np];
+    for (size_t __i = 0; __i < _Np; ++__i)
+        __is >> __t[__i];
+    if (!__is.fail())
+    {
+        for (size_t __i = 0; __i < _Np; ++__i)
+            __x.__x_[__i] = __t[__i];
+        __x.__i_ = 0;
+    }
+    return __is;
+}
+
+typedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
+                                0x9908b0df, 11, 0xffffffff,
+                                7,  0x9d2c5680,
+                                15, 0xefc60000,
+                                18, 1812433253>                         mt19937;
+typedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
+                                0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL,
+                                17, 0x71d67fffeda60000ULL,
+                                37, 0xfff7eee000000000ULL,
+                                43, 6364136223846793005ULL>          mt19937_64;
+
+// subtract_with_carry_engine
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+class _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine;
+
+template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+bool
+operator==(
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+
+template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+class _LIBCPP_TYPE_VIS_ONLY subtract_with_carry_engine
+{
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    result_type __x_[__r];
+    result_type  __c_;
+    size_t      __i_;
+
+    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
+    static_assert(  0 <  __w, "subtract_with_carry_engine invalid parameters");
+    static_assert(__w <= _Dt, "subtract_with_carry_engine invalid parameters");
+    static_assert(  0 <  __s, "subtract_with_carry_engine invalid parameters");
+    static_assert(__s <  __r, "subtract_with_carry_engine invalid parameters");
+public:
+    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
+    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
+                                                      (result_type(1) << __w) - result_type(1);
+    static_assert(_Min < _Max, "subtract_with_carry_engine invalid parameters");
+
+    // engine characteristics
+    static _LIBCPP_CONSTEXPR const size_t word_size = __w;
+    static _LIBCPP_CONSTEXPR const size_t short_lag = __s;
+    static _LIBCPP_CONSTEXPR const size_t long_lag = __r;
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
+    static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u;
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit subtract_with_carry_engine(result_type __sd = default_seed)
+        {seed(__sd);}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit subtract_with_carry_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, subtract_with_carry_engine>::value>::type* = 0)
+        {seed(__q);}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(result_type __sd = default_seed)
+        {seed(__sd, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, subtract_with_carry_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q)
+            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
+
+    // generating functions
+    result_type operator()();
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+    friend
+    bool
+    operator==(
+        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+
+    template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+    friend
+    bool
+    operator!=(
+        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+        const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y);
+
+    template <class _CharT, class _Traits,
+              class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+
+    template <class _CharT, class _Traits,
+              class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x);
+
+private:
+
+    void seed(result_type __sd, integral_constant<unsigned, 1>);
+    void seed(result_type __sd, integral_constant<unsigned, 2>);
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
+    template<class _Sseq>
+        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
+};
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+    _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type
+    subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+void
+subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,
+        integral_constant<unsigned, 1>)
+{
+    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
+        __e(__sd == 0u ? default_seed : __sd);
+    for (size_t __i = 0; __i < __r; ++__i)
+        __x_[__i] = static_cast<result_type>(__e() & _Max);
+    __c_ = __x_[__r-1] == 0;
+    __i_ = 0;
+}
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+void
+subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,
+        integral_constant<unsigned, 2>)
+{
+    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
+        __e(__sd == 0u ? default_seed : __sd);
+    for (size_t __i = 0; __i < __r; ++__i)
+    {
+        result_type __e0 = __e();
+        __x_[__i] = static_cast<result_type>(
+                                    (__e0 + ((uint64_t)__e() << 32)) & _Max);
+    }
+    __c_ = __x_[__r-1] == 0;
+    __i_ = 0;
+}
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+template<class _Sseq>
+void
+subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,
+        integral_constant<unsigned, 1>)
+{
+    const unsigned __k = 1;
+    uint32_t __ar[__r * __k];
+    __q.generate(__ar, __ar + __r * __k);
+    for (size_t __i = 0; __i < __r; ++__i)
+        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
+    __c_ = __x_[__r-1] == 0;
+    __i_ = 0;
+}
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+template<class _Sseq>
+void
+subtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,
+        integral_constant<unsigned, 2>)
+{
+    const unsigned __k = 2;
+    uint32_t __ar[__r * __k];
+    __q.generate(__ar, __ar + __r * __k);
+    for (size_t __i = 0; __i < __r; ++__i)
+        __x_[__i] = static_cast<result_type>(
+                  (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
+    __c_ = __x_[__r-1] == 0;
+    __i_ = 0;
+}
+
+template<class _UIntType, size_t __w, size_t __s, size_t __r>
+_UIntType
+subtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()()
+{
+    const result_type& __xs = __x_[(__i_ + (__r - __s)) % __r];
+    result_type& __xr = __x_[__i_];
+    result_type __new_c = __c_ == 0 ? __xs < __xr : __xs != 0 ? __xs <= __xr : 1;
+    __xr = (__xs - __xr - __c_) & _Max;
+    __c_ = __new_c;
+    __i_ = (__i_ + 1) % __r;
+    return __xr;
+}
+
+template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+bool
+operator==(
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)
+{
+    if (__x.__c_ != __y.__c_)
+        return false;
+    if (__x.__i_ == __y.__i_)
+        return _VSTD::equal(__x.__x_, __x.__x_ + _Rp, __y.__x_);
+    if (__x.__i_ == 0 || __y.__i_ == 0)
+    {
+        size_t __j = _VSTD::min(_Rp - __x.__i_, _Rp - __y.__i_);
+        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,
+                         __y.__x_ + __y.__i_))
+            return false;
+        if (__x.__i_ == 0)
+            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Rp, __y.__x_);
+        return _VSTD::equal(__x.__x_, __x.__x_ + (_Rp - __j), __y.__x_ + __j);
+    }
+    if (__x.__i_ < __y.__i_)
+    {
+        size_t __j = _Rp - __y.__i_;
+        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),
+                         __y.__x_ + __y.__i_))
+            return false;
+        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Rp,
+                         __y.__x_))
+            return false;
+        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,
+                           __y.__x_ + (_Rp - (__x.__i_ + __j)));
+    }
+    size_t __j = _Rp - __x.__i_;
+    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),
+                     __x.__x_ + __x.__i_))
+        return false;
+    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Rp,
+                     __x.__x_))
+        return false;
+    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,
+                       __x.__x_ + (_Rp - (__y.__i_ + __j)));
+}
+
+template<class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x,
+    const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.__x_[__x.__i_];
+    for (size_t __j = __x.__i_ + 1; __j < _Rp; ++__j)
+        __os << __sp << __x.__x_[__j];
+    for (size_t __j = 0; __j < __x.__i_; ++__j)
+        __os << __sp << __x.__x_[__j];
+    __os << __sp << __x.__c_;
+    return __os;
+}
+
+template <class _CharT, class _Traits,
+          class _UI, size_t _Wp, size_t _Sp, size_t _Rp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           subtract_with_carry_engine<_UI, _Wp, _Sp, _Rp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    _UI __t[_Rp+1];
+    for (size_t __i = 0; __i < _Rp+1; ++__i)
+        __is >> __t[__i];
+    if (!__is.fail())
+    {
+        for (size_t __i = 0; __i < _Rp; ++__i)
+            __x.__x_[__i] = __t[__i];
+        __x.__c_ = __t[_Rp];
+        __x.__i_ = 0;
+    }
+    return __is;
+}
+
+typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;
+typedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;
+
+// discard_block_engine
+
+template<class _Engine, size_t __p, size_t __r>
+class _LIBCPP_TYPE_VIS_ONLY discard_block_engine
+{
+    _Engine __e_;
+    int     __n_;
+
+    static_assert(  0 <  __r, "discard_block_engine invalid parameters");
+    static_assert(__r <= __p, "discard_block_engine invalid parameters");
+public:
+    // types
+    typedef typename _Engine::result_type result_type;
+
+    // engine characteristics
+    static _LIBCPP_CONSTEXPR const size_t block_size = __p;
+    static _LIBCPP_CONSTEXPR const size_t used_block = __r;
+
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    static const result_type _Min = _Engine::_Min;
+    static const result_type _Max = _Engine::_Max;
+#else
+    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
+    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); }
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); }
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    discard_block_engine() : __n_(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit discard_block_engine(const _Engine& __e)
+        : __e_(__e), __n_(0) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit discard_block_engine(_Engine&& __e)
+        : __e_(_VSTD::move(__e)), __n_(0) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit discard_block_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value &&
+                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
+        : __e_(__q), __n_(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed() {__e_.seed(); __n_ = 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, discard_block_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
+
+    // generating functions
+    result_type operator()();
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    const _Engine& base() const _NOEXCEPT {return __e_;}
+
+    template<class _Eng, size_t _Pp, size_t _Rp>
+    friend
+    bool
+    operator==(
+        const discard_block_engine<_Eng, _Pp, _Rp>& __x,
+        const discard_block_engine<_Eng, _Pp, _Rp>& __y);
+
+    template<class _Eng, size_t _Pp, size_t _Rp>
+    friend
+    bool
+    operator!=(
+        const discard_block_engine<_Eng, _Pp, _Rp>& __x,
+        const discard_block_engine<_Eng, _Pp, _Rp>& __y);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Pp, size_t _Rp>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const discard_block_engine<_Eng, _Pp, _Rp>& __x);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Pp, size_t _Rp>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               discard_block_engine<_Eng, _Pp, _Rp>& __x);
+};
+
+template<class _Engine, size_t __p, size_t __r>
+    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size;
+
+template<class _Engine, size_t __p, size_t __r>
+    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block;
+
+template<class _Engine, size_t __p, size_t __r>
+typename discard_block_engine<_Engine, __p, __r>::result_type
+discard_block_engine<_Engine, __p, __r>::operator()()
+{
+    if (__n_ >= __r)
+    {
+        __e_.discard(__p - __r);
+        __n_ = 0;
+    }
+    ++__n_;
+    return __e_();
+}
+
+template<class _Eng, size_t _Pp, size_t _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
+           const discard_block_engine<_Eng, _Pp, _Rp>& __y)
+{
+    return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_;
+}
+
+template<class _Eng, size_t _Pp, size_t _Rp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
+           const discard_block_engine<_Eng, _Pp, _Rp>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Pp, size_t _Rp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const discard_block_engine<_Eng, _Pp, _Rp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.__e_ << __sp << __x.__n_;
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Pp, size_t _Rp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           discard_block_engine<_Eng, _Pp, _Rp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    _Eng __e;
+    int __n;
+    __is >> __e >> __n;
+    if (!__is.fail())
+    {
+        __x.__e_ = __e;
+        __x.__n_ = __n;
+    }
+    return __is;
+}
+
+typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
+typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
+
+// independent_bits_engine
+
+template<class _Engine, size_t __w, class _UIntType>
+class _LIBCPP_TYPE_VIS_ONLY independent_bits_engine
+{
+    template <class _UI, _UI _R0, size_t _Wp, size_t _Mp>
+    class __get_n
+    {
+        static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UI>::digits;
+        static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0);
+        static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np;
+        static _LIBCPP_CONSTEXPR const _UI _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0;
+    public:
+        static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np;
+    };
+public:
+    // types
+    typedef _UIntType result_type;
+
+private:
+    _Engine __e_;
+
+    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
+    static_assert(  0 <  __w, "independent_bits_engine invalid parameters");
+    static_assert(__w <= _Dt, "independent_bits_engine invalid parameters");
+
+    typedef typename _Engine::result_type _Engine_result_type;
+    typedef typename conditional
+        <
+            sizeof(_Engine_result_type) <= sizeof(result_type),
+                result_type,
+                _Engine_result_type
+        >::type _Working_result_type;
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
+                                          + _Working_result_type(1);
+#else
+    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
+                                                            + _Working_result_type(1);
+#endif
+    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
+    static _LIBCPP_CONSTEXPR const size_t __n = __get_n<_Working_result_type, _Rp, __w, __m>::value;
+    static _LIBCPP_CONSTEXPR const size_t __w0 = __w / __n;
+    static _LIBCPP_CONSTEXPR const size_t __n0 = __n - __w % __n;
+    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
+    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
+    static _LIBCPP_CONSTEXPR const _Working_result_type __y0 = __w0 >= _WDt ? 0 :
+                                                               (_Rp >> __w0) << __w0;
+    static _LIBCPP_CONSTEXPR const _Working_result_type __y1 = __w0 >= _WDt - 1 ? 0 :
+                                                               (_Rp >> (__w0+1)) << (__w0+1);
+    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask0 = __w0 > 0 ?
+                                _Engine_result_type(~0) >> (_EDt - __w0) :
+                                _Engine_result_type(0);
+    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask1 = __w0 < _EDt - 1 ?
+                                _Engine_result_type(~0) >> (_EDt - (__w0 + 1)) :
+                                _Engine_result_type(~0);
+public:
+    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
+    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
+                                                      (result_type(1) << __w) - result_type(1);
+    static_assert(_Min < _Max, "independent_bits_engine invalid parameters");
+
+    // engine characteristics
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    independent_bits_engine() {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit independent_bits_engine(const _Engine& __e)
+        : __e_(__e) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit independent_bits_engine(_Engine&& __e)
+        : __e_(_VSTD::move(__e)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit independent_bits_engine(result_type __sd) : __e_(__sd) {}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit independent_bits_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, independent_bits_engine>::value &&
+                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
+         : __e_(__q) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed() {__e_.seed();}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(result_type __sd) {__e_.seed(__sd);}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, independent_bits_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q) {__e_.seed(__q);}
+
+    // generating functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    const _Engine& base() const _NOEXCEPT {return __e_;}
+
+    template<class _Eng, size_t _Wp, class _UI>
+    friend
+    bool
+    operator==(
+        const independent_bits_engine<_Eng, _Wp, _UI>& __x,
+        const independent_bits_engine<_Eng, _Wp, _UI>& __y);
+
+    template<class _Eng, size_t _Wp, class _UI>
+    friend
+    bool
+    operator!=(
+        const independent_bits_engine<_Eng, _Wp, _UI>& __x,
+        const independent_bits_engine<_Eng, _Wp, _UI>& __y);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Wp, class _UI>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const independent_bits_engine<_Eng, _Wp, _UI>& __x);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Wp, class _UI>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               independent_bits_engine<_Eng, _Wp, _UI>& __x);
+
+private:
+    result_type __eval(false_type);
+    result_type __eval(true_type);
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            __count < _Dt,
+            result_type
+        >::type
+        __lshift(result_type __x) {return __x << __count;}
+
+    template <size_t __count>
+        _LIBCPP_INLINE_VISIBILITY
+        static
+        typename enable_if
+        <
+            (__count >= _Dt),
+            result_type
+        >::type
+        __lshift(result_type) {return result_type(0);}
+};
+
+template<class _Engine, size_t __w, class _UIntType>
+inline _LIBCPP_INLINE_VISIBILITY
+_UIntType
+independent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type)
+{
+    return static_cast<result_type>(__e_() & __mask0);
+}
+
+template<class _Engine, size_t __w, class _UIntType>
+_UIntType
+independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
+{
+    result_type _Sp = 0;
+    for (size_t __k = 0; __k < __n0; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y0);
+        _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0));
+    }
+    for (size_t __k = __n0; __k < __n; ++__k)
+    {
+        _Engine_result_type __u;
+        do
+        {
+            __u = __e_() - _Engine::min();
+        } while (__u >= __y1);
+        _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1));
+    }
+    return _Sp;
+}
+
+template<class _Eng, size_t _Wp, class _UI>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(
+    const independent_bits_engine<_Eng, _Wp, _UI>& __x,
+    const independent_bits_engine<_Eng, _Wp, _UI>& __y)
+{
+    return __x.base() == __y.base();
+}
+
+template<class _Eng, size_t _Wp, class _UI>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(
+    const independent_bits_engine<_Eng, _Wp, _UI>& __x,
+    const independent_bits_engine<_Eng, _Wp, _UI>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Wp, class _UI>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const independent_bits_engine<_Eng, _Wp, _UI>& __x)
+{
+    return __os << __x.base();
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Wp, class _UI>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           independent_bits_engine<_Eng, _Wp, _UI>& __x)
+{
+    _Eng __e;
+    __is >> __e;
+    if (!__is.fail())
+        __x.__e_ = __e;
+    return __is;
+}
+
+// shuffle_order_engine
+
+template <uint64_t _Xp, uint64_t _Yp>
+struct __ugcd
+{
+    static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value;
+};
+
+template <uint64_t _Xp>
+struct __ugcd<_Xp, 0>
+{
+    static _LIBCPP_CONSTEXPR const uint64_t value = _Xp;
+};
+
+template <uint64_t _Np, uint64_t _Dp>
+class __uratio
+{
+    static_assert(_Dp != 0, "__uratio divide by 0");
+    static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value;
+public:
+    static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd;
+    static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd;
+
+    typedef __uratio<num, den> type;
+};
+
+template<class _Engine, size_t __k>
+class _LIBCPP_TYPE_VIS_ONLY shuffle_order_engine
+{
+    static_assert(0 < __k, "shuffle_order_engine invalid parameters");
+public:
+    // types
+    typedef typename _Engine::result_type result_type;
+
+private:
+    _Engine __e_;
+    result_type _V_[__k];
+    result_type _Y_;
+
+public:
+    // engine characteristics
+    static _LIBCPP_CONSTEXPR const size_t table_size = __k;
+
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    static const result_type _Min = _Engine::_Min;
+    static const result_type _Max = _Engine::_Max;
+#else
+    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
+    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
+#endif
+    static_assert(_Min < _Max, "shuffle_order_engine invalid parameters");
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
+
+    static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull;
+
+    // constructors and seeding functions
+    _LIBCPP_INLINE_VISIBILITY
+    shuffle_order_engine() {__init();}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit shuffle_order_engine(const _Engine& __e)
+        : __e_(__e) {__init();}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit shuffle_order_engine(_Engine&& __e)
+        : __e_(_VSTD::move(__e)) {__init();}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit shuffle_order_engine(_Sseq& __q,
+        typename enable_if<__is_seed_sequence<_Sseq, shuffle_order_engine>::value &&
+                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
+         : __e_(__q) {__init();}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed() {__e_.seed(); __init();}
+    _LIBCPP_INLINE_VISIBILITY
+    void seed(result_type __sd) {__e_.seed(__sd); __init();}
+    template<class _Sseq>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_seed_sequence<_Sseq, shuffle_order_engine>::value,
+            void
+        >::type
+        seed(_Sseq& __q) {__e_.seed(__q); __init();}
+
+    // generating functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
+    _LIBCPP_INLINE_VISIBILITY
+    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    const _Engine& base() const _NOEXCEPT {return __e_;}
+
+private:
+    template<class _Eng, size_t _Kp>
+    friend
+    bool
+    operator==(
+        const shuffle_order_engine<_Eng, _Kp>& __x,
+        const shuffle_order_engine<_Eng, _Kp>& __y);
+
+    template<class _Eng, size_t _Kp>
+    friend
+    bool
+    operator!=(
+        const shuffle_order_engine<_Eng, _Kp>& __x,
+        const shuffle_order_engine<_Eng, _Kp>& __y);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Kp>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const shuffle_order_engine<_Eng, _Kp>& __x);
+
+    template <class _CharT, class _Traits,
+              class _Eng, size_t _Kp>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               shuffle_order_engine<_Eng, _Kp>& __x);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __init()
+    {
+        for (size_t __i = 0; __i < __k; ++__i)
+            _V_[__i] = __e_();
+        _Y_ = __e_();
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type __eval(false_type) {return __eval2(integral_constant<bool, __k & 1>());}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type __eval(true_type) {return __eval(__uratio<__k, _Rp>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type __eval2(false_type) {return __eval(__uratio<__k/2, 0x8000000000000000ull>());}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type __eval2(true_type) {return __evalf<__k, 0>();}
+
+    template <uint64_t _Np, uint64_t _Dp>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            (__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)),
+            result_type
+        >::type
+        __eval(__uratio<_Np, _Dp>)
+            {return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();}
+
+    template <uint64_t _Np, uint64_t _Dp>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min),
+            result_type
+        >::type
+        __eval(__uratio<_Np, _Dp>)
+        {
+            const size_t __j = static_cast<size_t>(__uratio<_Np, _Dp>::num * (_Y_ - _Min)
+                                                   / __uratio<_Np, _Dp>::den);
+            _Y_ = _V_[__j];
+            _V_[__j] = __e_();
+            return _Y_;
+        }
+
+    template <uint64_t __n, uint64_t __d>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type __evalf()
+        {
+            const double _Fp = __d == 0 ?
+                __n / (2. * 0x8000000000000000ull) :
+                __n / (double)__d;
+            const size_t __j = static_cast<size_t>(_Fp * (_Y_ - _Min));
+            _Y_ = _V_[__j];
+            _V_[__j] = __e_();
+            return _Y_;
+        }
+};
+
+template<class _Engine, size_t __k>
+    _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size;
+
+template<class _Eng, size_t _Kp>
+bool
+operator==(
+    const shuffle_order_engine<_Eng, _Kp>& __x,
+    const shuffle_order_engine<_Eng, _Kp>& __y)
+{
+    return __x._Y_ == __y._Y_ && _VSTD::equal(__x._V_, __x._V_ + _Kp, __y._V_) &&
+           __x.__e_ == __y.__e_;
+}
+
+template<class _Eng, size_t _Kp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(
+    const shuffle_order_engine<_Eng, _Kp>& __x,
+    const shuffle_order_engine<_Eng, _Kp>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Kp>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const shuffle_order_engine<_Eng, _Kp>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.__e_ << __sp << __x._V_[0];
+    for (size_t __i = 1; __i < _Kp; ++__i)
+        __os << __sp << __x._V_[__i];
+    return __os << __sp << __x._Y_;
+}
+
+template <class _CharT, class _Traits,
+          class _Eng, size_t _Kp>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           shuffle_order_engine<_Eng, _Kp>& __x)
+{
+    typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    _Eng __e;
+    result_type _Vp[_Kp+1];
+    __is >> __e;
+    for (size_t __i = 0; __i < _Kp+1; ++__i)
+        __is >> _Vp[__i];
+    if (!__is.fail())
+    {
+        __x.__e_ = __e;
+        for (size_t __i = 0; __i < _Kp; ++__i)
+            __x._V_[__i] = _Vp[__i];
+        __x._Y_ = _Vp[_Kp];
+    }
+    return __is;
+}
+
+typedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;
+
+// random_device
+
+class _LIBCPP_TYPE_VIS random_device
+{
+#if !defined(_WIN32)
+    int __f_;
+#endif // defined(_WIN32)
+public:
+    // types
+    typedef unsigned result_type;
+
+    // generator characteristics
+    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
+    static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type min() { return _Min;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR result_type max() { return _Max;}
+
+    // constructors
+    explicit random_device(const string& __token = "/dev/urandom");
+    ~random_device();
+
+    // generating functions
+    result_type operator()();
+
+    // property functions
+    double entropy() const _NOEXCEPT;
+
+private:
+    // no copy functions
+    random_device(const random_device&); // = delete;
+    random_device& operator=(const random_device&); // = delete;
+};
+
+// seed_seq
+
+class _LIBCPP_TYPE_VIS_ONLY seed_seq
+{
+public:
+    // types
+    typedef uint32_t result_type;
+
+private:
+    vector<result_type> __v_;
+
+    template<class _InputIterator>
+        void init(_InputIterator __first, _InputIterator __last);
+public:
+    // constructors
+    _LIBCPP_INLINE_VISIBILITY
+    seed_seq() _NOEXCEPT {}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template<class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template<class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        seed_seq(_InputIterator __first, _InputIterator __last)
+             {init(__first, __last);}
+
+    // generating functions
+    template<class _RandomAccessIterator>
+        void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const _NOEXCEPT {return __v_.size();}
+    template<class _OutputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        void param(_OutputIterator __dest) const
+            {_VSTD::copy(__v_.begin(), __v_.end(), __dest);}
+
+private:
+    // no copy functions
+    seed_seq(const seed_seq&); // = delete;
+    void operator=(const seed_seq&); // = delete;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);}
+};
+
+template<class _InputIterator>
+void
+seed_seq::init(_InputIterator __first, _InputIterator __last)
+{
+    for (_InputIterator __s = __first; __s != __last; ++__s)
+        __v_.push_back(*__s & 0xFFFFFFFF);
+}
+
+template<class _RandomAccessIterator>
+void
+seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last)
+{
+    if (__first != __last)
+    {
+        _VSTD::fill(__first, __last, 0x8b8b8b8b);
+        const size_t __n = static_cast<size_t>(__last - __first);
+        const size_t __s = __v_.size();
+        const size_t __t = (__n >= 623) ? 11
+                         : (__n >= 68) ? 7
+                         : (__n >= 39) ? 5
+                         : (__n >= 7)  ? 3
+                         : (__n - 1) / 2;
+        const size_t __p = (__n - __t) / 2;
+        const size_t __q = __p + __t;
+        const size_t __m = _VSTD::max(__s + 1, __n);
+        // __k = 0;
+        {
+            result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p]
+                                                      ^  __first[__n - 1]);
+            __first[__p] += __r;
+            __r += __s;
+            __first[__q] += __r;
+            __first[0] = __r;
+        }
+        for (size_t __k = 1; __k <= __s; ++__k)
+        {
+            const size_t __kmodn = __k % __n;
+            const size_t __kpmodn = (__k + __p) % __n;
+            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
+                                           ^ __first[(__k - 1) % __n]);
+            __first[__kpmodn] += __r;
+            __r +=  __kmodn + __v_[__k-1];
+            __first[(__k + __q) % __n] += __r;
+            __first[__kmodn] = __r;
+        }
+        for (size_t __k = __s + 1; __k < __m; ++__k)
+        {
+            const size_t __kmodn = __k % __n;
+            const size_t __kpmodn = (__k + __p) % __n;
+            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
+                                           ^ __first[(__k - 1) % __n]);
+            __first[__kpmodn] += __r;
+            __r +=  __kmodn;
+            __first[(__k + __q) % __n] += __r;
+            __first[__kmodn] = __r;
+        }
+        for (size_t __k = __m; __k < __m + __n; ++__k)
+        {
+            const size_t __kmodn = __k % __n;
+            const size_t __kpmodn = (__k + __p) % __n;
+            result_type __r = 1566083941 * _Tp(__first[__kmodn] +
+                                              __first[__kpmodn] +
+                                              __first[(__k - 1) % __n]);
+            __first[__kpmodn] ^= __r;
+            __r -= __kmodn;
+            __first[(__k + __q) % __n] ^= __r;
+            __first[__kmodn] = __r;
+        }
+    }
+}
+
+// generate_canonical
+
+template<class _RealType, size_t __bits, class _URNG>
+_RealType
+generate_canonical(_URNG& __g)
+{
+    const size_t _Dt = numeric_limits<_RealType>::digits;
+    const size_t __b = _Dt < __bits ? _Dt : __bits;
+#ifdef _LIBCPP_HAS_NO_CONSTEXPR
+    const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
+#else
+    const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
+#endif
+    const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0);
+    const _RealType _Rp = _URNG::max() - _URNG::min() + _RealType(1);
+    _RealType __base = _Rp;
+    _RealType _Sp = __g() - _URNG::min();
+    for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp)
+        _Sp += (__g() - _URNG::min()) * __base;
+    return _Sp / __base;
+}
+
+// uniform_int_distribution
+
+// in <algorithm>
+
+template <class _CharT, class _Traits, class _IT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const uniform_int_distribution<_IT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.a() << __sp << __x.b();
+}
+
+template <class _CharT, class _Traits, class _IT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           uniform_int_distribution<_IT>& __x)
+{
+    typedef uniform_int_distribution<_IT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+// uniform_real_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY uniform_real_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef uniform_real_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __a = 0,
+                            result_type __b = 1)
+            : __a_(__a), __b_(__b) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type a() const {return __a_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type b() const {return __b_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type a() const {return __p_.a();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type b() const {return __p_.b();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return a();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return b();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const uniform_real_distribution& __x,
+                        const uniform_real_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const uniform_real_distribution& __x,
+                        const uniform_real_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template<class _RealType>
+template<class _URNG>
+inline _LIBCPP_INLINE_VISIBILITY
+typename uniform_real_distribution<_RealType>::result_type
+uniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    return (__p.b() - __p.a())
+        * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g)
+        + __p.a();
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const uniform_real_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.a() << __sp << __x.b();
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           uniform_real_distribution<_RT>& __x)
+{
+    typedef uniform_real_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+// bernoulli_distribution
+
+class _LIBCPP_TYPE_VIS_ONLY bernoulli_distribution
+{
+public:
+    // types
+    typedef bool result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        double __p_;
+    public:
+        typedef bernoulli_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(double __p = 0.5) : __p_(__p) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        double p() const {return __p_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__p_ == __y.__p_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit bernoulli_distribution(double __p = 0.5)
+        : __p_(param_type(__p)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    double p() const {return __p_.p();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return false;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return true;}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const bernoulli_distribution& __x,
+                        const bernoulli_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const bernoulli_distribution& __x,
+                        const bernoulli_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template<class _URNG>
+inline _LIBCPP_INLINE_VISIBILITY
+bernoulli_distribution::result_type
+bernoulli_distribution::operator()(_URNG& __g, const param_type& __p)
+{
+    uniform_real_distribution<double> __gen;
+    return __gen(__g) < __p.p();
+}
+
+template <class _CharT, class _Traits>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.p();
+}
+
+template <class _CharT, class _Traits>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x)
+{
+    typedef bernoulli_distribution _Eng;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    double __p;
+    __is >> __p;
+    if (!__is.fail())
+        __x.param(param_type(__p));
+    return __is;
+}
+
+// binomial_distribution
+
+template<class _IntType = int>
+class _LIBCPP_TYPE_VIS_ONLY binomial_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __t_;
+        double __p_;
+        double __pr_;
+        double __odds_ratio_;
+        result_type __r0_;
+    public:
+        typedef binomial_distribution distribution_type;
+
+        explicit param_type(result_type __t = 1, double __p = 0.5);
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type t() const {return __t_;}
+        _LIBCPP_INLINE_VISIBILITY
+        double p() const {return __p_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+
+        friend class binomial_distribution;
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit binomial_distribution(result_type __t = 1, double __p = 0.5)
+        : __p_(param_type(__t, __p)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit binomial_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type t() const {return __p_.t();}
+    _LIBCPP_INLINE_VISIBILITY
+    double p() const {return __p_.p();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return t();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const binomial_distribution& __x,
+                        const binomial_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const binomial_distribution& __x,
+                        const binomial_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template<class _IntType>
+binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p)
+    : __t_(__t), __p_(__p)
+{
+    if (0 < __p_ && __p_ < 1)
+    {
+        __r0_ = static_cast<result_type>((__t_ + 1) * __p_);
+        __pr_ = _VSTD::exp(_VSTD::lgamma(__t_ + 1.) - _VSTD::lgamma(__r0_ + 1.) -
+                          _VSTD::lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
+                          (__t_ - __r0_) * _VSTD::log(1 - __p_));
+        __odds_ratio_ = __p_ / (1 - __p_);
+    }
+}
+
+template<class _IntType>
+template<class _URNG>
+_IntType
+binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
+{
+    if (__pr.__t_ == 0 || __pr.__p_ == 0)
+        return 0;
+    if (__pr.__p_ == 1)
+        return __pr.__t_;
+    uniform_real_distribution<double> __gen;
+    double __u = __gen(__g) - __pr.__pr_;
+    if (__u < 0)
+        return __pr.__r0_;
+    double __pu = __pr.__pr_;
+    double __pd = __pu;
+    result_type __ru = __pr.__r0_;
+    result_type __rd = __ru;
+    while (true)
+    {
+        if (__rd >= 1)
+        {
+            __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1));
+            __u -= __pd;
+            if (__u < 0)
+                return __rd - 1;
+        }
+        --__rd;
+        ++__ru;
+        if (__ru <= __pr.__t_)
+        {
+            __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru;
+            __u -= __pu;
+            if (__u < 0)
+                return __ru;
+        }
+    }
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const binomial_distribution<_IntType>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.t() << __sp << __x.p();
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           binomial_distribution<_IntType>& __x)
+{
+    typedef binomial_distribution<_IntType> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __t;
+    double __p;
+    __is >> __t >> __p;
+    if (!__is.fail())
+        __x.param(param_type(__t, __p));
+    return __is;
+}
+
+// exponential_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY exponential_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __lambda_;
+    public:
+        typedef exponential_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type lambda() const {return __lambda_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__lambda_ == __y.__lambda_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit exponential_distribution(result_type __lambda = 1)
+        : __p_(param_type(__lambda)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit exponential_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type lambda() const {return __p_.lambda();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const exponential_distribution& __x,
+                        const exponential_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const exponential_distribution& __x,
+                        const exponential_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _RealType>
+template<class _URNG>
+_RealType
+exponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    return -_VSTD::log
+                  (
+                      result_type(1) -
+                      _VSTD::generate_canonical<result_type,
+                                       numeric_limits<result_type>::digits>(__g)
+                  )
+                  / __p.lambda();
+}
+
+template <class _CharT, class _Traits, class _RealType>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const exponential_distribution<_RealType>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    return __os << __x.lambda();
+}
+
+template <class _CharT, class _Traits, class _RealType>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           exponential_distribution<_RealType>& __x)
+{
+    typedef exponential_distribution<_RealType> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __lambda;
+    __is >> __lambda;
+    if (!__is.fail())
+        __x.param(param_type(__lambda));
+    return __is;
+}
+
+// normal_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY normal_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __mean_;
+        result_type __stddev_;
+    public:
+        typedef normal_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __mean = 0, result_type __stddev = 1)
+            : __mean_(__mean), __stddev_(__stddev) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type mean() const {return __mean_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type stddev() const {return __stddev_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+    result_type _V_;
+    bool _V_hot_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit normal_distribution(result_type __mean = 0, result_type __stddev = 1)
+        : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit normal_distribution(const param_type& __p)
+        : __p_(__p), _V_hot_(false) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {_V_hot_ = false;}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type mean() const {return __p_.mean();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type stddev() const {return __p_.stddev();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return -numeric_limits<result_type>::infinity();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const normal_distribution& __x,
+                        const normal_distribution& __y)
+        {return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ &&
+                (!__x._V_hot_ || __x._V_ == __y._V_);}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const normal_distribution& __x,
+                        const normal_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const normal_distribution<_RT>& __x);
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               normal_distribution<_RT>& __x);
+};
+
+template <class _RealType>
+template<class _URNG>
+_RealType
+normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    result_type _Up;
+    if (_V_hot_)
+    {
+        _V_hot_ = false;
+        _Up = _V_;
+    }
+    else
+    {
+        uniform_real_distribution<result_type> _Uni(-1, 1);
+        result_type __u;
+        result_type __v;
+        result_type __s;
+        do
+        {
+            __u = _Uni(__g);
+            __v = _Uni(__g);
+            __s = __u * __u + __v * __v;
+        } while (__s > 1 || __s == 0);
+        result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
+        _V_ = __v * _Fp;
+        _V_hot_ = true;
+        _Up = __u * _Fp;
+    }
+    return _Up * __p.stddev() + __p.mean();
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const normal_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;
+    if (__x._V_hot_)
+        __os << __sp << __x._V_;
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           normal_distribution<_RT>& __x)
+{
+    typedef normal_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __mean;
+    result_type __stddev;
+    result_type _Vp = 0;
+    bool _V_hot = false;
+    __is >> __mean >> __stddev >> _V_hot;
+    if (_V_hot)
+        __is >> _Vp;
+    if (!__is.fail())
+    {
+        __x.param(param_type(__mean, __stddev));
+        __x._V_hot_ = _V_hot;
+        __x._V_ = _Vp;
+    }
+    return __is;
+}
+
+// lognormal_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY lognormal_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        normal_distribution<result_type> __nd_;
+    public:
+        typedef lognormal_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __m = 0, result_type __s = 1)
+            : __nd_(__m, __s) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type m() const {return __nd_.mean();}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type s() const {return __nd_.stddev();}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__nd_ == __y.__nd_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+        friend class lognormal_distribution;
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_ostream<_CharT, _Traits>&
+        operator<<(basic_ostream<_CharT, _Traits>& __os,
+                   const lognormal_distribution<_RT>& __x);
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_istream<_CharT, _Traits>&
+        operator>>(basic_istream<_CharT, _Traits>& __is,
+                   lognormal_distribution<_RT>& __x);
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(result_type __m = 0, result_type __s = 1)
+        : __p_(param_type(__m, __s)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {__p_.__nd_.reset();}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g, const param_type& __p)
+        {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type m() const {return __p_.m();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type s() const {return __p_.s();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const lognormal_distribution& __x,
+                        const lognormal_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const lognormal_distribution& __x,
+                        const lognormal_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const lognormal_distribution<_RT>& __x);
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               lognormal_distribution<_RT>& __x);
+};
+
+template <class _CharT, class _Traits, class _RT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const lognormal_distribution<_RT>& __x)
+{
+    return __os << __x.__p_.__nd_;
+}
+
+template <class _CharT, class _Traits, class _RT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           lognormal_distribution<_RT>& __x)
+{
+    return __is >> __x.__p_.__nd_;
+}
+
+// poisson_distribution
+
+template<class _IntType = int>
+class _LIBCPP_TYPE_VIS_ONLY poisson_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        double __mean_;
+        double __s_;
+        double __d_;
+        double __l_;
+        double __omega_;
+        double __c0_;
+        double __c1_;
+        double __c2_;
+        double __c3_;
+        double __c_;
+
+    public:
+        typedef poisson_distribution distribution_type;
+
+        explicit param_type(double __mean = 1.0);
+
+        _LIBCPP_INLINE_VISIBILITY
+        double mean() const {return __mean_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__mean_ == __y.__mean_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+
+        friend class poisson_distribution;
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit poisson_distribution(double __mean = 1.0) : __p_(__mean) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit poisson_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    double mean() const {return __p_.mean();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::max();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const poisson_distribution& __x,
+                        const poisson_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const poisson_distribution& __x,
+                        const poisson_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template<class _IntType>
+poisson_distribution<_IntType>::param_type::param_type(double __mean)
+    : __mean_(__mean)
+{
+    if (__mean_ < 10)
+    {
+        __s_ = 0;
+        __d_ = 0;
+        __l_ = _VSTD::exp(-__mean_);
+        __omega_ = 0;
+        __c3_ = 0;
+        __c2_ = 0;
+        __c1_ = 0;
+        __c0_ = 0;
+        __c_ = 0;
+    }
+    else
+    {
+        __s_ = _VSTD::sqrt(__mean_);
+        __d_ = 6 * __mean_ * __mean_;
+        __l_ = static_cast<result_type>(__mean_ - 1.1484);
+        __omega_ = .3989423 / __s_;
+        double __b1_ = .4166667E-1 / __mean_;
+        double __b2_ = .3 * __b1_ * __b1_;
+        __c3_ = .1428571 * __b1_ * __b2_;
+        __c2_ = __b2_ - 15. * __c3_;
+        __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_;
+        __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_;
+        __c_ = .1069 / __mean_;
+    }
+}
+
+template <class _IntType>
+template<class _URNG>
+_IntType
+poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
+{
+    result_type __x;
+    uniform_real_distribution<double> __urd;
+    if (__pr.__mean_ < 10)
+    {
+         __x = 0;
+        for (double __p = __urd(__urng); __p > __pr.__l_; ++__x)
+            __p *= __urd(__urng);
+    }
+    else
+    {
+        double __difmuk;
+        double __g = __pr.__mean_ + __pr.__s_ * normal_distribution<double>()(__urng);
+        double __u;
+        if (__g > 0)
+        {
+            __x = static_cast<result_type>(__g);
+            if (__x >= __pr.__l_)
+                return __x;
+            __difmuk = __pr.__mean_ - __x;
+            __u = __urd(__urng);
+            if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk)
+                return __x;
+        }
+        exponential_distribution<double> __edist;
+        for (bool __using_exp_dist = false; true; __using_exp_dist = true)
+        {
+            double __e;
+            if (__using_exp_dist || __g < 0)
+            {
+                double __t;
+                do
+                {
+                    __e = __edist(__urng);
+                    __u = __urd(__urng);
+                    __u += __u - 1;
+                    __t = 1.8 + (__u < 0 ? -__e : __e);
+                } while (__t <= -.6744);
+                __x = __pr.__mean_ + __pr.__s_ * __t;
+                __difmuk = __pr.__mean_ - __x;
+                __using_exp_dist = true;
+            }
+            double __px;
+            double __py;
+            if (__x < 10)
+            {
+                const result_type __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040,
+                                             40320, 362880};
+                __px = -__pr.__mean_;
+                __py = _VSTD::pow(__pr.__mean_, (double)__x) / __fac[__x];
+            }
+            else
+            {
+                double __del = .8333333E-1 / __x;
+                __del -= 4.8 * __del * __del * __del;
+                double __v = __difmuk / __x;
+                if (_VSTD::abs(__v) > 0.25)
+                    __px = __x * _VSTD::log(1 + __v) - __difmuk - __del;
+                else
+                    __px = __x * __v * __v * (((((((.1250060 * __v + -.1384794) *
+                           __v + .1421878) * __v + -.1661269) * __v + .2000118) *
+                           __v + -.2500068) * __v + .3333333) * __v + -.5) - __del;
+                __py = .3989423 / _VSTD::sqrt(__x);
+            }
+            double __r = (0.5 - __difmuk) / __pr.__s_;
+            double __r2 = __r * __r;
+            double __fx = -0.5 * __r2;
+            double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) *
+                                        __r2 + __pr.__c1_) * __r2 + __pr.__c0_);
+            if (__using_exp_dist)
+            {
+                if (__pr.__c_ * _VSTD::abs(__u) <= __py * _VSTD::exp(__px + __e) -
+                                                   __fy * _VSTD::exp(__fx + __e))
+                    break;
+            }
+            else
+            {
+                if (__fy - __u * __fy <= __py * _VSTD::exp(__px - __fx))
+                    break;
+            }
+        }
+    }
+    return __x;
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const poisson_distribution<_IntType>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    return __os << __x.mean();
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           poisson_distribution<_IntType>& __x)
+{
+    typedef poisson_distribution<_IntType> _Eng;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    double __mean;
+    __is >> __mean;
+    if (!__is.fail())
+        __x.param(param_type(__mean));
+    return __is;
+}
+
+// weibull_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY weibull_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef weibull_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __a = 1, result_type __b = 1)
+            : __a_(__a), __b_(__b) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type a() const {return __a_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type b() const {return __b_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit weibull_distribution(result_type __a = 1, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit weibull_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g, const param_type& __p)
+        {return __p.b() *
+            _VSTD::pow(exponential_distribution<result_type>()(__g), 1/__p.a());}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type a() const {return __p_.a();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type b() const {return __p_.b();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const weibull_distribution& __x,
+                        const weibull_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const weibull_distribution& __x,
+                        const weibull_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const weibull_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.a() << __sp << __x.b();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           weibull_distribution<_RT>& __x)
+{
+    typedef weibull_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY extreme_value_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef extreme_value_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __a = 0, result_type __b = 1)
+            : __a_(__a), __b_(__b) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type a() const {return __a_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type b() const {return __b_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit extreme_value_distribution(result_type __a = 0, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit extreme_value_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type a() const {return __p_.a();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type b() const {return __p_.b();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return -numeric_limits<result_type>::infinity();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const extreme_value_distribution& __x,
+                        const extreme_value_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const extreme_value_distribution& __x,
+                        const extreme_value_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template<class _RealType>
+template<class _URNG>
+_RealType
+extreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    return __p.a() - __p.b() *
+         _VSTD::log(-_VSTD::log(1-uniform_real_distribution<result_type>()(__g)));
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const extreme_value_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.a() << __sp << __x.b();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           extreme_value_distribution<_RT>& __x)
+{
+    typedef extreme_value_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+// gamma_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY gamma_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __alpha_;
+        result_type __beta_;
+    public:
+        typedef gamma_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __alpha = 1, result_type __beta = 1)
+            : __alpha_(__alpha), __beta_(__beta) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type alpha() const {return __alpha_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type beta() const {return __beta_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__alpha_ == __y.__alpha_ && __x.__beta_ == __y.__beta_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit gamma_distribution(result_type __alpha = 1, result_type __beta = 1)
+        : __p_(param_type(__alpha, __beta)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit gamma_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type alpha() const {return __p_.alpha();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type beta() const {return __p_.beta();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const gamma_distribution& __x,
+                        const gamma_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const gamma_distribution& __x,
+                        const gamma_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _RealType>
+template<class _URNG>
+_RealType
+gamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    result_type __a = __p.alpha();
+    uniform_real_distribution<result_type> __gen(0, 1);
+    exponential_distribution<result_type> __egen;
+    result_type __x;
+    if (__a == 1)
+        __x = __egen(__g);
+    else if (__a > 1)
+    {
+        const result_type __b = __a - 1;
+        const result_type __c = 3 * __a - result_type(0.75);
+        while (true)
+        {
+            const result_type __u = __gen(__g);
+            const result_type __v = __gen(__g);
+            const result_type __w = __u * (1 - __u);
+            if (__w != 0)
+            {
+                const result_type __y = _VSTD::sqrt(__c / __w) *
+                                        (__u - result_type(0.5));
+                __x = __b + __y;
+                if (__x >= 0)
+                {
+                    const result_type __z = 64 * __w * __w * __w * __v * __v;
+                    if (__z <= 1 - 2 * __y * __y / __x)
+                        break;
+                    if (_VSTD::log(__z) <= 2 * (__b * _VSTD::log(__x / __b) - __y))
+                        break;
+                }
+            }
+        }
+    }
+    else  // __a < 1
+    {
+        while (true)
+        {
+            const result_type __u = __gen(__g);
+            const result_type __es = __egen(__g);
+            if (__u <= 1 - __a)
+            {
+                __x = _VSTD::pow(__u, 1 / __a);
+                if (__x <= __es)
+                    break;
+            }
+            else
+            {
+                const result_type __e = -_VSTD::log((1-__u)/__a);
+                __x = _VSTD::pow(1 - __a + __a * __e, 1 / __a);
+                if (__x <= __e + __es)
+                    break;
+            }
+        }
+    }
+    return __x * __p.beta();
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const gamma_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.alpha() << __sp << __x.beta();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           gamma_distribution<_RT>& __x)
+{
+    typedef gamma_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __alpha;
+    result_type __beta;
+    __is >> __alpha >> __beta;
+    if (!__is.fail())
+        __x.param(param_type(__alpha, __beta));
+    return __is;
+}
+
+// negative_binomial_distribution
+
+template<class _IntType = int>
+class _LIBCPP_TYPE_VIS_ONLY negative_binomial_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __k_;
+        double __p_;
+    public:
+        typedef negative_binomial_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __k = 1, double __p = 0.5)
+            : __k_(__k), __p_(__p) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type k() const {return __k_;}
+        _LIBCPP_INLINE_VISIBILITY
+        double p() const {return __p_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit negative_binomial_distribution(result_type __k = 1, double __p = 0.5)
+        : __p_(__k, __p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type k() const {return __p_.k();}
+    _LIBCPP_INLINE_VISIBILITY
+    double p() const {return __p_.p();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::max();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const negative_binomial_distribution& __x,
+                        const negative_binomial_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const negative_binomial_distribution& __x,
+                        const negative_binomial_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _IntType>
+template<class _URNG>
+_IntType
+negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
+{
+    result_type __k = __pr.k();
+    double __p = __pr.p();
+    if (__k <= 21 * __p)
+    {
+        bernoulli_distribution __gen(__p);
+        result_type __f = 0;
+        result_type __s = 0;
+        while (__s < __k)
+        {
+            if (__gen(__urng))
+                ++__s;
+            else
+                ++__f;
+        }
+        return __f;
+    }
+    return poisson_distribution<result_type>(gamma_distribution<double>
+                                            (__k, (1-__p)/__p)(__urng))(__urng);
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const negative_binomial_distribution<_IntType>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    return __os << __x.k() << __sp << __x.p();
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           negative_binomial_distribution<_IntType>& __x)
+{
+    typedef negative_binomial_distribution<_IntType> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __k;
+    double __p;
+    __is >> __k >> __p;
+    if (!__is.fail())
+        __x.param(param_type(__k, __p));
+    return __is;
+}
+
+// geometric_distribution
+
+template<class _IntType = int>
+class _LIBCPP_TYPE_VIS_ONLY geometric_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        double __p_;
+    public:
+        typedef geometric_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(double __p = 0.5) : __p_(__p) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        double p() const {return __p_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__p_ == __y.__p_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructors and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit geometric_distribution(double __p = 0.5) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit geometric_distribution(const param_type& __p) : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g, const param_type& __p)
+        {return negative_binomial_distribution<result_type>(1, __p.p())(__g);}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    double p() const {return __p_.p();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::max();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const geometric_distribution& __x,
+                        const geometric_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const geometric_distribution& __x,
+                        const geometric_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _CharT, class _Traits, class _IntType>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const geometric_distribution<_IntType>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    return __os << __x.p();
+}
+
+template <class _CharT, class _Traits, class _IntType>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           geometric_distribution<_IntType>& __x)
+{
+    typedef geometric_distribution<_IntType> _Eng;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    double __p;
+    __is >> __p;
+    if (!__is.fail())
+        __x.param(param_type(__p));
+    return __is;
+}
+
+// chi_squared_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY chi_squared_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __n_;
+    public:
+        typedef chi_squared_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __n = 1) : __n_(__n) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type n() const {return __n_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__n_ == __y.__n_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit chi_squared_distribution(result_type __n = 1)
+        : __p_(param_type(__n)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit chi_squared_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g, const param_type& __p)
+        {return gamma_distribution<result_type>(__p.n() / 2, 2)(__g);}
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type n() const {return __p_.n();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const chi_squared_distribution& __x,
+                        const chi_squared_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const chi_squared_distribution& __x,
+                        const chi_squared_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const chi_squared_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    __os << __x.n();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           chi_squared_distribution<_RT>& __x)
+{
+    typedef chi_squared_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __n;
+    __is >> __n;
+    if (!__is.fail())
+        __x.param(param_type(__n));
+    return __is;
+}
+
+// cauchy_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY cauchy_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __a_;
+        result_type __b_;
+    public:
+        typedef cauchy_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __a = 0, result_type __b = 1)
+            : __a_(__a), __b_(__b) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type a() const {return __a_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type b() const {return __b_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit cauchy_distribution(result_type __a = 0, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit cauchy_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type a() const {return __p_.a();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type b() const {return __p_.b();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return -numeric_limits<result_type>::infinity();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const cauchy_distribution& __x,
+                        const cauchy_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const cauchy_distribution& __x,
+                        const cauchy_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _RealType>
+template<class _URNG>
+inline _LIBCPP_INLINE_VISIBILITY
+_RealType
+cauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    uniform_real_distribution<result_type> __gen;
+    // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite
+    return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g));
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const cauchy_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.a() << __sp << __x.b();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           cauchy_distribution<_RT>& __x)
+{
+    typedef cauchy_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __a;
+    result_type __b;
+    __is >> __a >> __b;
+    if (!__is.fail())
+        __x.param(param_type(__a, __b));
+    return __is;
+}
+
+// fisher_f_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY fisher_f_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __m_;
+        result_type __n_;
+    public:
+        typedef fisher_f_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __m = 1, result_type __n = 1)
+            : __m_(__m), __n_(__n) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type m() const {return __m_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type n() const {return __n_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1)
+        : __p_(param_type(__m, __n)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit fisher_f_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type m() const {return __p_.m();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type n() const {return __p_.n();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const fisher_f_distribution& __x,
+                        const fisher_f_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const fisher_f_distribution& __x,
+                        const fisher_f_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _RealType>
+template<class _URNG>
+_RealType
+fisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    gamma_distribution<result_type> __gdm(__p.m() * result_type(.5));
+    gamma_distribution<result_type> __gdn(__p.n() * result_type(.5));
+    return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g));
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const fisher_f_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    __os << __x.m() << __sp << __x.n();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           fisher_f_distribution<_RT>& __x)
+{
+    typedef fisher_f_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __m;
+    result_type __n;
+    __is >> __m >> __n;
+    if (!__is.fail())
+        __x.param(param_type(__m, __n));
+    return __is;
+}
+
+// student_t_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY student_t_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        result_type __n_;
+    public:
+        typedef student_t_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __n = 1) : __n_(__n) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type n() const {return __n_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__n_ == __y.__n_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    param_type __p_;
+    normal_distribution<result_type> __nd_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    explicit student_t_distribution(result_type __n = 1)
+        : __p_(param_type(__n)) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit student_t_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {__nd_.reset();}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type n() const {return __p_.n();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return -numeric_limits<result_type>::infinity();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const student_t_distribution& __x,
+                        const student_t_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const student_t_distribution& __x,
+                        const student_t_distribution& __y)
+        {return !(__x == __y);}
+};
+
+template <class _RealType>
+template<class _URNG>
+_RealType
+student_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    gamma_distribution<result_type> __gd(__p.n() * .5, 2);
+    return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g));
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const student_t_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    __os << __x.n();
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           student_t_distribution<_RT>& __x)
+{
+    typedef student_t_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    result_type __n;
+    __is >> __n;
+    if (!__is.fail())
+        __x.param(param_type(__n));
+    return __is;
+}
+
+// discrete_distribution
+
+template<class _IntType = int>
+class _LIBCPP_TYPE_VIS_ONLY discrete_distribution
+{
+public:
+    // types
+    typedef _IntType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        vector<double> __p_;
+    public:
+        typedef discrete_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        param_type() {}
+        template<class _InputIterator>
+            _LIBCPP_INLINE_VISIBILITY
+            param_type(_InputIterator __f, _InputIterator __l)
+            : __p_(__f, __l) {__init();}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        _LIBCPP_INLINE_VISIBILITY
+        param_type(initializer_list<double> __wl)
+            : __p_(__wl.begin(), __wl.end()) {__init();}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        template<class _UnaryOperation>
+            param_type(size_t __nw, double __xmin, double __xmax,
+                       _UnaryOperation __fw);
+
+        vector<double> probabilities() const;
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__p_ == __y.__p_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+
+    private:
+        void __init();
+
+        friend class discrete_distribution;
+
+        template <class _CharT, class _Traits, class _IT>
+        friend
+        basic_ostream<_CharT, _Traits>&
+        operator<<(basic_ostream<_CharT, _Traits>& __os,
+                   const discrete_distribution<_IT>& __x);
+
+        template <class _CharT, class _Traits, class _IT>
+        friend
+        basic_istream<_CharT, _Traits>&
+        operator>>(basic_istream<_CharT, _Traits>& __is,
+                   discrete_distribution<_IT>& __x);
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    discrete_distribution() {}
+    template<class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        discrete_distribution(_InputIterator __f, _InputIterator __l)
+            : __p_(__f, __l) {}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    discrete_distribution(initializer_list<double> __wl)
+        : __p_(__wl) {}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template<class _UnaryOperation>
+        _LIBCPP_INLINE_VISIBILITY
+        discrete_distribution(size_t __nw, double __xmin, double __xmax,
+                              _UnaryOperation __fw)
+        : __p_(__nw, __xmin, __xmax, __fw) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit discrete_distribution(const param_type& __p)
+        : __p_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    vector<double> probabilities() const {return __p_.probabilities();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return __p_.__p_.size();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const discrete_distribution& __x,
+                        const discrete_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const discrete_distribution& __x,
+                        const discrete_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _IT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const discrete_distribution<_IT>& __x);
+
+    template <class _CharT, class _Traits, class _IT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               discrete_distribution<_IT>& __x);
+};
+
+template<class _IntType>
+template<class _UnaryOperation>
+discrete_distribution<_IntType>::param_type::param_type(size_t __nw,
+                                                        double __xmin,
+                                                        double __xmax,
+                                                        _UnaryOperation __fw)
+{
+    if (__nw > 1)
+    {
+        __p_.reserve(__nw - 1);
+        double __d = (__xmax - __xmin) / __nw;
+        double __d2 = __d / 2;
+        for (size_t __k = 0; __k < __nw; ++__k)
+            __p_.push_back(__fw(__xmin + __k * __d + __d2));
+        __init();
+    }
+}
+
+template<class _IntType>
+void
+discrete_distribution<_IntType>::param_type::__init()
+{
+    if (!__p_.empty())
+    {
+        if (__p_.size() > 1)
+        {
+            double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0);
+            for (_VSTD::vector<double>::iterator __i = __p_.begin(), __e = __p_.end();
+                                                                       __i < __e; ++__i)
+                *__i /= __s;
+            vector<double> __t(__p_.size() - 1);
+            _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin());
+            swap(__p_, __t);
+        }
+        else
+        {
+            __p_.clear();
+            __p_.shrink_to_fit();
+        }
+    }
+}
+
+template<class _IntType>
+vector<double>
+discrete_distribution<_IntType>::param_type::probabilities() const
+{
+    size_t __n = __p_.size();
+    _VSTD::vector<double> __p(__n+1);
+    _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin());
+    if (__n > 0)
+        __p[__n] = 1 - __p_[__n-1];
+    else
+        __p[0] = 1;
+    return __p;
+}
+
+template<class _IntType>
+template<class _URNG>
+_IntType
+discrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
+{
+    uniform_real_distribution<double> __gen;
+    return static_cast<_IntType>(
+           _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) -
+                                                              __p.__p_.begin());
+}
+
+template <class _CharT, class _Traits, class _IT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const discrete_distribution<_IT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    size_t __n = __x.__p_.__p_.size();
+    __os << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__p_[__i];
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _IT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           discrete_distribution<_IT>& __x)
+{
+    typedef discrete_distribution<_IT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    size_t __n;
+    __is >> __n;
+    vector<double> __p(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __p[__i];
+    if (!__is.fail())
+        swap(__x.__p_.__p_, __p);
+    return __is;
+}
+
+// piecewise_constant_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY piecewise_constant_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        vector<result_type> __b_;
+        vector<result_type> __densities_;
+        vector<result_type> __areas_;
+    public:
+        typedef piecewise_constant_distribution distribution_type;
+
+        param_type();
+        template<class _InputIteratorB, class _InputIteratorW>
+            param_type(_InputIteratorB __fB, _InputIteratorB __lB,
+                       _InputIteratorW __fW);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        template<class _UnaryOperation>
+            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        template<class _UnaryOperation>
+            param_type(size_t __nw, result_type __xmin, result_type __xmax,
+                       _UnaryOperation __fw);
+        param_type & operator=(const param_type& __rhs);
+
+        _LIBCPP_INLINE_VISIBILITY
+        vector<result_type> intervals() const {return __b_;}
+        _LIBCPP_INLINE_VISIBILITY
+        vector<result_type> densities() const {return __densities_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+
+    private:
+        void __init();
+
+        friend class piecewise_constant_distribution;
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_ostream<_CharT, _Traits>&
+        operator<<(basic_ostream<_CharT, _Traits>& __os,
+                   const piecewise_constant_distribution<_RT>& __x);
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_istream<_CharT, _Traits>&
+        operator>>(basic_istream<_CharT, _Traits>& __is,
+                   piecewise_constant_distribution<_RT>& __x);
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    piecewise_constant_distribution() {}
+    template<class _InputIteratorB, class _InputIteratorW>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_constant_distribution(_InputIteratorB __fB,
+                                        _InputIteratorB __lB,
+                                        _InputIteratorW __fW)
+        : __p_(__fB, __lB, __fW) {}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template<class _UnaryOperation>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_constant_distribution(initializer_list<result_type> __bl,
+                                        _UnaryOperation __fw)
+        : __p_(__bl, __fw) {}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template<class _UnaryOperation>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_constant_distribution(size_t __nw, result_type __xmin,
+                                        result_type __xmax, _UnaryOperation __fw)
+        : __p_(__nw, __xmin, __xmax, __fw) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit piecewise_constant_distribution(const param_type& __p)
+        : __p_(__p) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    vector<result_type> intervals() const {return __p_.intervals();}
+    _LIBCPP_INLINE_VISIBILITY
+    vector<result_type> densities() const {return __p_.densities();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return __p_.__b_.front();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return __p_.__b_.back();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const piecewise_constant_distribution& __x,
+                        const piecewise_constant_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const piecewise_constant_distribution& __x,
+                           const piecewise_constant_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const piecewise_constant_distribution<_RT>& __x);
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               piecewise_constant_distribution<_RT>& __x);
+};
+
+template<class _RealType>
+typename piecewise_constant_distribution<_RealType>::param_type &
+piecewise_constant_distribution<_RealType>::param_type::operator=
+                                                       (const param_type& __rhs)
+{
+//  These can throw
+    __b_.reserve        (__rhs.__b_.size ());
+    __densities_.reserve(__rhs.__densities_.size());
+    __areas_.reserve    (__rhs.__areas_.size());
+
+//  These can not throw
+    __b_         = __rhs.__b_;
+    __densities_ = __rhs.__densities_;
+    __areas_     =  __rhs.__areas_;
+    return *this;
+}
+
+template<class _RealType>
+void
+piecewise_constant_distribution<_RealType>::param_type::__init()
+{
+    // __densities_ contains non-normalized areas
+    result_type __total_area = _VSTD::accumulate(__densities_.begin(),
+                                                __densities_.end(),
+                                                result_type());
+    for (size_t __i = 0; __i < __densities_.size(); ++__i)
+        __densities_[__i] /= __total_area;
+    // __densities_ contains normalized areas
+    __areas_.assign(__densities_.size(), result_type());
+    _VSTD::partial_sum(__densities_.begin(), __densities_.end() - 1,
+                                                          __areas_.begin() + 1);
+    // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1]
+    __densities_.back() = 1 - __areas_.back();  // correct round off error
+    for (size_t __i = 0; __i < __densities_.size(); ++__i)
+        __densities_[__i] /= (__b_[__i+1] - __b_[__i]);
+    // __densities_ now contains __densities_
+}
+
+template<class _RealType>
+piecewise_constant_distribution<_RealType>::param_type::param_type()
+    : __b_(2),
+      __densities_(1, 1.0),
+      __areas_(1, 0.0)
+{
+    __b_[1] = 1;
+}
+
+template<class _RealType>
+template<class _InputIteratorB, class _InputIteratorW>
+piecewise_constant_distribution<_RealType>::param_type::param_type(
+        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
+    : __b_(__fB, __lB)
+{
+    if (__b_.size() < 2)
+    {
+        __b_.resize(2);
+        __b_[0] = 0;
+        __b_[1] = 1;
+        __densities_.assign(1, 1.0);
+        __areas_.assign(1, 0.0);
+    }
+    else
+    {
+        __densities_.reserve(__b_.size() - 1);
+        for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW)
+            __densities_.push_back(*__fW);
+        __init();
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _RealType>
+template<class _UnaryOperation>
+piecewise_constant_distribution<_RealType>::param_type::param_type(
+        initializer_list<result_type> __bl, _UnaryOperation __fw)
+    : __b_(__bl.begin(), __bl.end())
+{
+    if (__b_.size() < 2)
+    {
+        __b_.resize(2);
+        __b_[0] = 0;
+        __b_[1] = 1;
+        __densities_.assign(1, 1.0);
+        __areas_.assign(1, 0.0);
+    }
+    else
+    {
+        __densities_.reserve(__b_.size() - 1);
+        for (size_t __i = 0; __i < __b_.size() - 1; ++__i)
+            __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5));
+        __init();
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _RealType>
+template<class _UnaryOperation>
+piecewise_constant_distribution<_RealType>::param_type::param_type(
+        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)
+    : __b_(__nw == 0 ? 2 : __nw + 1)
+{
+    size_t __n = __b_.size() - 1;
+    result_type __d = (__xmax - __xmin) / __n;
+    __densities_.reserve(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+    {
+        __b_[__i] = __xmin + __i * __d;
+        __densities_.push_back(__fw(__b_[__i] + __d*.5));
+    }
+    __b_[__n] = __xmax;
+    __init();
+}
+
+template<class _RealType>
+template<class _URNG>
+_RealType
+piecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    typedef uniform_real_distribution<result_type> _Gen;
+    result_type __u = _Gen()(__g);
+    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
+                                      __u) - __p.__areas_.begin() - 1;
+    return (__u - __p.__areas_[__k]) / __p.__densities_[__k] + __p.__b_[__k];
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const piecewise_constant_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    size_t __n = __x.__p_.__b_.size();
+    __os << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__b_[__i];
+    __n = __x.__p_.__densities_.size();
+    __os << __sp << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__densities_[__i];
+    __n = __x.__p_.__areas_.size();
+    __os << __sp << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__areas_[__i];
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           piecewise_constant_distribution<_RT>& __x)
+{
+    typedef piecewise_constant_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    size_t __n;
+    __is >> __n;
+    vector<result_type> __b(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __b[__i];
+    __is >> __n;
+    vector<result_type> __densities(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __densities[__i];
+    __is >> __n;
+    vector<result_type> __areas(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __areas[__i];
+    if (!__is.fail())
+    {
+        swap(__x.__p_.__b_, __b);
+        swap(__x.__p_.__densities_, __densities);
+        swap(__x.__p_.__areas_, __areas);
+    }
+    return __is;
+}
+
+// piecewise_linear_distribution
+
+template<class _RealType = double>
+class _LIBCPP_TYPE_VIS_ONLY piecewise_linear_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TYPE_VIS_ONLY param_type
+    {
+        vector<result_type> __b_;
+        vector<result_type> __densities_;
+        vector<result_type> __areas_;
+    public:
+        typedef piecewise_linear_distribution distribution_type;
+
+        param_type();
+        template<class _InputIteratorB, class _InputIteratorW>
+            param_type(_InputIteratorB __fB, _InputIteratorB __lB,
+                       _InputIteratorW __fW);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        template<class _UnaryOperation>
+            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+        template<class _UnaryOperation>
+            param_type(size_t __nw, result_type __xmin, result_type __xmax,
+                       _UnaryOperation __fw);
+        param_type & operator=(const param_type& __rhs);
+        
+        _LIBCPP_INLINE_VISIBILITY
+        vector<result_type> intervals() const {return __b_;}
+        _LIBCPP_INLINE_VISIBILITY
+        vector<result_type> densities() const {return __densities_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+            bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+
+    private:
+        void __init();
+
+        friend class piecewise_linear_distribution;
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_ostream<_CharT, _Traits>&
+        operator<<(basic_ostream<_CharT, _Traits>& __os,
+                   const piecewise_linear_distribution<_RT>& __x);
+
+        template <class _CharT, class _Traits, class _RT>
+        friend
+        basic_istream<_CharT, _Traits>&
+        operator>>(basic_istream<_CharT, _Traits>& __is,
+                   piecewise_linear_distribution<_RT>& __x);
+    };
+
+private:
+    param_type __p_;
+
+public:
+    // constructor and reset functions
+    _LIBCPP_INLINE_VISIBILITY
+    piecewise_linear_distribution() {}
+    template<class _InputIteratorB, class _InputIteratorW>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_linear_distribution(_InputIteratorB __fB,
+                                      _InputIteratorB __lB,
+                                      _InputIteratorW __fW)
+        : __p_(__fB, __lB, __fW) {}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template<class _UnaryOperation>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_linear_distribution(initializer_list<result_type> __bl,
+                                      _UnaryOperation __fw)
+        : __p_(__bl, __fw) {}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template<class _UnaryOperation>
+        _LIBCPP_INLINE_VISIBILITY
+        piecewise_linear_distribution(size_t __nw, result_type __xmin,
+                                      result_type __xmax, _UnaryOperation __fw)
+        : __p_(__nw, __xmin, __xmax, __fw) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit piecewise_linear_distribution(const param_type& __p)
+        : __p_(__p) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {}
+
+    // generating functions
+    template<class _URNG>
+        _LIBCPP_INLINE_VISIBILITY
+        result_type operator()(_URNG& __g)
+        {return (*this)(__g, __p_);}
+    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    vector<result_type> intervals() const {return __p_.intervals();}
+    _LIBCPP_INLINE_VISIBILITY
+    vector<result_type> densities() const {return __p_.densities();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return __p_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p) {__p_ = __p;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return __p_.__b_.front();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return __p_.__b_.back();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const piecewise_linear_distribution& __x,
+                        const piecewise_linear_distribution& __y)
+        {return __x.__p_ == __y.__p_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const piecewise_linear_distribution& __x,
+                        const piecewise_linear_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const piecewise_linear_distribution<_RT>& __x);
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               piecewise_linear_distribution<_RT>& __x);
+};
+
+template<class _RealType>
+typename piecewise_linear_distribution<_RealType>::param_type &
+piecewise_linear_distribution<_RealType>::param_type::operator=
+                                                       (const param_type& __rhs)
+{
+//  These can throw
+    __b_.reserve        (__rhs.__b_.size ());
+    __densities_.reserve(__rhs.__densities_.size());
+    __areas_.reserve    (__rhs.__areas_.size());
+
+//  These can not throw
+    __b_         = __rhs.__b_;
+    __densities_ = __rhs.__densities_;
+    __areas_     =  __rhs.__areas_;
+    return *this;
+}
+
+
+template<class _RealType>
+void
+piecewise_linear_distribution<_RealType>::param_type::__init()
+{
+    __areas_.assign(__densities_.size() - 1, result_type());
+    result_type _Sp = 0;
+    for (size_t __i = 0; __i < __areas_.size(); ++__i)
+    {
+        __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) *
+                        (__b_[__i+1] - __b_[__i]) * .5;
+        _Sp += __areas_[__i];
+    }
+    for (size_t __i = __areas_.size(); __i > 1;)
+    {
+        --__i;
+        __areas_[__i] = __areas_[__i-1] / _Sp;
+    }
+    __areas_[0] = 0;
+    for (size_t __i = 1; __i < __areas_.size(); ++__i)
+        __areas_[__i] += __areas_[__i-1];
+    for (size_t __i = 0; __i < __densities_.size(); ++__i)
+        __densities_[__i] /= _Sp;
+}
+
+template<class _RealType>
+piecewise_linear_distribution<_RealType>::param_type::param_type()
+    : __b_(2),
+      __densities_(2, 1.0),
+      __areas_(1, 0.0)
+{
+    __b_[1] = 1;
+}
+
+template<class _RealType>
+template<class _InputIteratorB, class _InputIteratorW>
+piecewise_linear_distribution<_RealType>::param_type::param_type(
+        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
+    : __b_(__fB, __lB)
+{
+    if (__b_.size() < 2)
+    {
+        __b_.resize(2);
+        __b_[0] = 0;
+        __b_[1] = 1;
+        __densities_.assign(2, 1.0);
+        __areas_.assign(1, 0.0);
+    }
+    else
+    {
+        __densities_.reserve(__b_.size());
+        for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW)
+            __densities_.push_back(*__fW);
+        __init();
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _RealType>
+template<class _UnaryOperation>
+piecewise_linear_distribution<_RealType>::param_type::param_type(
+        initializer_list<result_type> __bl, _UnaryOperation __fw)
+    : __b_(__bl.begin(), __bl.end())
+{
+    if (__b_.size() < 2)
+    {
+        __b_.resize(2);
+        __b_[0] = 0;
+        __b_[1] = 1;
+        __densities_.assign(2, 1.0);
+        __areas_.assign(1, 0.0);
+    }
+    else
+    {
+        __densities_.reserve(__b_.size());
+        for (size_t __i = 0; __i < __b_.size(); ++__i)
+            __densities_.push_back(__fw(__b_[__i]));
+        __init();
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template<class _RealType>
+template<class _UnaryOperation>
+piecewise_linear_distribution<_RealType>::param_type::param_type(
+        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)
+    : __b_(__nw == 0 ? 2 : __nw + 1)
+{
+    size_t __n = __b_.size() - 1;
+    result_type __d = (__xmax - __xmin) / __n;
+    __densities_.reserve(__b_.size());
+    for (size_t __i = 0; __i < __n; ++__i)
+    {
+        __b_[__i] = __xmin + __i * __d;
+        __densities_.push_back(__fw(__b_[__i]));
+    }
+    __b_[__n] = __xmax;
+    __densities_.push_back(__fw(__b_[__n]));
+    __init();
+}
+
+template<class _RealType>
+template<class _URNG>
+_RealType
+piecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
+{
+    typedef uniform_real_distribution<result_type> _Gen;
+    result_type __u = _Gen()(__g);
+    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
+                                      __u) - __p.__areas_.begin() - 1;
+    __u -= __p.__areas_[__k];
+    const result_type __dk = __p.__densities_[__k];
+    const result_type __dk1 = __p.__densities_[__k+1];
+    const result_type __deltad = __dk1 - __dk;
+    const result_type __bk = __p.__b_[__k];
+    if (__deltad == 0)
+        return __u / __dk + __bk;
+    const result_type __bk1 = __p.__b_[__k+1];
+    const result_type __deltab = __bk1 - __bk;
+    return (__bk * __dk1 - __bk1 * __dk +
+        _VSTD::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) /
+        __deltad;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const piecewise_linear_distribution<_RT>& __x)
+{
+    __save_flags<_CharT, _Traits> __lx(__os);
+    __os.flags(ios_base::dec | ios_base::left | ios_base::fixed |
+               ios_base::scientific);
+    _CharT __sp = __os.widen(' ');
+    __os.fill(__sp);
+    size_t __n = __x.__p_.__b_.size();
+    __os << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__b_[__i];
+    __n = __x.__p_.__densities_.size();
+    __os << __sp << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__densities_[__i];
+    __n = __x.__p_.__areas_.size();
+    __os << __sp << __n;
+    for (size_t __i = 0; __i < __n; ++__i)
+        __os << __sp << __x.__p_.__areas_[__i];
+    return __os;
+}
+
+template <class _CharT, class _Traits, class _RT>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           piecewise_linear_distribution<_RT>& __x)
+{
+    typedef piecewise_linear_distribution<_RT> _Eng;
+    typedef typename _Eng::result_type result_type;
+    typedef typename _Eng::param_type param_type;
+    __save_flags<_CharT, _Traits> __lx(__is);
+    __is.flags(ios_base::dec | ios_base::skipws);
+    size_t __n;
+    __is >> __n;
+    vector<result_type> __b(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __b[__i];
+    __is >> __n;
+    vector<result_type> __densities(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __densities[__i];
+    __is >> __n;
+    vector<result_type> __areas(__n);
+    for (size_t __i = 0; __i < __n; ++__i)
+        __is >> __areas[__i];
+    if (!__is.fail())
+    {
+        swap(__x.__p_.__b_, __b);
+        swap(__x.__p_.__densities_, __densities);
+        swap(__x.__p_.__areas_, __areas);
+    }
+    return __is;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_RANDOM
diff --git a/include/c++/v1/ratio b/include/c++/v1/ratio
new file mode 100644
index 0000000..48dcd81
--- /dev/null
+++ b/include/c++/v1/ratio
@@ -0,0 +1,487 @@
+// -*- C++ -*-
+//===---------------------------- ratio -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_RATIO
+#define _LIBCPP_RATIO
+
+/*
+    ratio synopsis
+
+namespace std
+{
+
+template <intmax_t N, intmax_t D = 1>
+class ratio
+{
+public:
+    static const intmax_t num;
+    static const intmax_t den;
+    typedef ratio<num, den> type;
+};
+
+// ratio arithmetic
+template <class R1, class R2> using ratio_add = ...;
+template <class R1, class R2> using ratio_subtract = ...;
+template <class R1, class R2> using ratio_multiply = ...;
+template <class R1, class R2> using ratio_divide = ...;
+
+// ratio comparison
+template <class R1, class R2> struct ratio_equal;
+template <class R1, class R2> struct ratio_not_equal;
+template <class R1, class R2> struct ratio_less;
+template <class R1, class R2> struct ratio_less_equal;
+template <class R1, class R2> struct ratio_greater;
+template <class R1, class R2> struct ratio_greater_equal;
+
+// convenience SI typedefs
+typedef ratio<1, 1000000000000000000000000> yocto;  // not supported
+typedef ratio<1,    1000000000000000000000> zepto;  // not supported
+typedef ratio<1,       1000000000000000000> atto;
+typedef ratio<1,          1000000000000000> femto;
+typedef ratio<1,             1000000000000> pico;
+typedef ratio<1,                1000000000> nano;
+typedef ratio<1,                   1000000> micro;
+typedef ratio<1,                      1000> milli;
+typedef ratio<1,                       100> centi;
+typedef ratio<1,                        10> deci;
+typedef ratio<                       10, 1> deca;
+typedef ratio<                      100, 1> hecto;
+typedef ratio<                     1000, 1> kilo;
+typedef ratio<                  1000000, 1> mega;
+typedef ratio<               1000000000, 1> giga;
+typedef ratio<            1000000000000, 1> tera;
+typedef ratio<         1000000000000000, 1> peta;
+typedef ratio<      1000000000000000000, 1> exa;
+typedef ratio<   1000000000000000000000, 1> zetta;  // not supported
+typedef ratio<1000000000000000000000000, 1> yotta;  // not supported
+
+}
+*/
+
+#include <__config>
+#include <cstdint>
+#include <climits>
+#include <type_traits>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// __static_gcd
+
+template <intmax_t _Xp, intmax_t _Yp>
+struct __static_gcd
+{
+    static const intmax_t value = __static_gcd<_Yp, _Xp % _Yp>::value;
+};
+
+template <intmax_t _Xp>
+struct __static_gcd<_Xp, 0>
+{
+    static const intmax_t value = _Xp;
+};
+
+template <>
+struct __static_gcd<0, 0>
+{
+    static const intmax_t value = 1;
+};
+
+// __static_lcm
+
+template <intmax_t _Xp, intmax_t _Yp>
+struct __static_lcm
+{
+    static const intmax_t value = _Xp / __static_gcd<_Xp, _Yp>::value * _Yp;
+};
+
+template <intmax_t _Xp>
+struct __static_abs
+{
+    static const intmax_t value = _Xp < 0 ? -_Xp : _Xp;
+};
+
+template <intmax_t _Xp>
+struct __static_sign
+{
+    static const intmax_t value = _Xp == 0 ? 0 : (_Xp < 0 ? -1 : 1);
+};
+
+template <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
+class __ll_add;
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_add<_Xp, _Yp, 1>
+{
+    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+    static const intmax_t max = -min;
+
+    static_assert(_Xp <= max - _Yp, "overflow in __ll_add");
+public:
+    static const intmax_t value = _Xp + _Yp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_add<_Xp, _Yp, 0>
+{
+public:
+    static const intmax_t value = _Xp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_add<_Xp, _Yp, -1>
+{
+    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+    static const intmax_t max = -min;
+
+    static_assert(min - _Yp <= _Xp, "overflow in __ll_add");
+public:
+    static const intmax_t value = _Xp + _Yp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp, intmax_t = __static_sign<_Yp>::value>
+class __ll_sub;
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_sub<_Xp, _Yp, 1>
+{
+    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+    static const intmax_t max = -min;
+
+    static_assert(min + _Yp <= _Xp, "overflow in __ll_sub");
+public:
+    static const intmax_t value = _Xp - _Yp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_sub<_Xp, _Yp, 0>
+{
+public:
+    static const intmax_t value = _Xp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_sub<_Xp, _Yp, -1>
+{
+    static const intmax_t min = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1;
+    static const intmax_t max = -min;
+
+    static_assert(_Xp <= max + _Yp, "overflow in __ll_sub");
+public:
+    static const intmax_t value = _Xp - _Yp;
+};
+
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_mul
+{
+    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
+    static const intmax_t min = nan + 1;
+    static const intmax_t max = -min;
+    static const intmax_t __a_x = __static_abs<_Xp>::value;
+    static const intmax_t __a_y = __static_abs<_Yp>::value;
+
+    static_assert(_Xp != nan && _Yp != nan && __a_x <= max / __a_y, "overflow in __ll_mul");
+public:
+    static const intmax_t value = _Xp * _Yp;
+};
+
+template <intmax_t _Yp>
+class __ll_mul<0, _Yp>
+{
+public:
+    static const intmax_t value = 0;
+};
+
+template <intmax_t _Xp>
+class __ll_mul<_Xp, 0>
+{
+public:
+    static const intmax_t value = 0;
+};
+
+template <>
+class __ll_mul<0, 0>
+{
+public:
+    static const intmax_t value = 0;
+};
+
+// Not actually used but left here in case needed in future maintenance
+template <intmax_t _Xp, intmax_t _Yp>
+class __ll_div
+{
+    static const intmax_t nan = (1LL << (sizeof(intmax_t) * CHAR_BIT - 1));
+    static const intmax_t min = nan + 1;
+    static const intmax_t max = -min;
+
+    static_assert(_Xp != nan && _Yp != nan && _Yp != 0, "overflow in __ll_div");
+public:
+    static const intmax_t value = _Xp / _Yp;
+};
+
+template <intmax_t _Num, intmax_t _Den = 1>
+class _LIBCPP_TYPE_VIS_ONLY ratio
+{
+    static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
+    static_assert(_Den != 0, "ratio divide by 0");
+    static_assert(__static_abs<_Den>::value >  0, "ratio denominator is out of range");
+    static const intmax_t __na = __static_abs<_Num>::value;
+    static const intmax_t __da = __static_abs<_Den>::value;
+    static const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
+    static const intmax_t __gcd = __static_gcd<__na, __da>::value;
+public:
+    static const intmax_t num = __s * __na / __gcd;
+    static const intmax_t den = __da / __gcd;
+
+    typedef ratio<num, den> type;
+};
+
+template <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::num;
+template <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::den;
+
+template <class _Tp>                    struct __is_ratio                     : false_type {};
+template <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type  {};
+
+typedef ratio<1LL, 1000000000000000000LL> atto;
+typedef ratio<1LL,    1000000000000000LL> femto;
+typedef ratio<1LL,       1000000000000LL> pico;
+typedef ratio<1LL,          1000000000LL> nano;
+typedef ratio<1LL,             1000000LL> micro;
+typedef ratio<1LL,                1000LL> milli;
+typedef ratio<1LL,                 100LL> centi;
+typedef ratio<1LL,                  10LL> deci;
+typedef ratio<                 10LL, 1LL> deca;
+typedef ratio<                100LL, 1LL> hecto;
+typedef ratio<               1000LL, 1LL> kilo;
+typedef ratio<            1000000LL, 1LL> mega;
+typedef ratio<         1000000000LL, 1LL> giga;
+typedef ratio<      1000000000000LL, 1LL> tera;
+typedef ratio<   1000000000000000LL, 1LL> peta;
+typedef ratio<1000000000000000000LL, 1LL> exa;
+
+template <class _R1, class _R2>
+struct __ratio_multiply
+{
+private:
+    static const intmax_t __gcd_n1_d2 = __static_gcd<_R1::num, _R2::den>::value;
+    static const intmax_t __gcd_d1_n2 = __static_gcd<_R1::den, _R2::num>::value;
+public:
+    typedef typename ratio
+        <
+            __ll_mul<_R1::num / __gcd_n1_d2, _R2::num / __gcd_d1_n2>::value,
+            __ll_mul<_R2::den / __gcd_n1_d2, _R1::den / __gcd_d1_n2>::value
+        >::type type;
+};
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2> using ratio_multiply
+                                    = typename __ratio_multiply<_R1, _R2>::type;
+
+#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_multiply
+    : public __ratio_multiply<_R1, _R2>::type {};
+
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct __ratio_divide
+{
+private:
+    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
+    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+public:
+    typedef typename ratio
+        <
+            __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
+            __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
+        >::type type;
+};
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2> using ratio_divide
+                                      = typename __ratio_divide<_R1, _R2>::type;
+
+#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_divide
+    : public __ratio_divide<_R1, _R2>::type {};
+
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct __ratio_add
+{
+private:
+    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
+    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+public:
+    typedef typename ratio_multiply
+        <
+            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
+            ratio
+            <
+                __ll_add
+                <
+                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
+                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
+                >::value,
+                _R2::den
+            >
+        >::type type;
+};
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2> using ratio_add
+                                         = typename __ratio_add<_R1, _R2>::type;
+
+#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_add
+    : public __ratio_add<_R1, _R2>::type {};
+
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct __ratio_subtract
+{
+private:
+    static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value;
+    static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value;
+public:
+    typedef typename ratio_multiply
+        <
+            ratio<__gcd_n1_n2, _R1::den / __gcd_d1_d2>,
+            ratio
+            <
+                __ll_sub
+                <
+                    __ll_mul<_R1::num / __gcd_n1_n2, _R2::den / __gcd_d1_d2>::value,
+                    __ll_mul<_R2::num / __gcd_n1_n2, _R1::den / __gcd_d1_d2>::value
+                >::value,
+                _R2::den
+            >
+        >::type type;
+};
+
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2> using ratio_subtract
+                                    = typename __ratio_subtract<_R1, _R2>::type;
+
+#else  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_subtract
+    : public __ratio_subtract<_R1, _R2>::type {};
+
+#endif  // _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+
+// ratio_equal
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_equal
+    : public integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> {};
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal
+    : public integral_constant<bool, !ratio_equal<_R1, _R2>::value> {};
+
+// ratio_less
+
+template <class _R1, class _R2, bool _Odd = false,
+          intmax_t _Q1 = _R1::num / _R1::den, intmax_t _M1 = _R1::num % _R1::den,
+          intmax_t _Q2 = _R2::num / _R2::den, intmax_t _M2 = _R2::num % _R2::den>
+struct __ratio_less1
+{
+    static const bool value = _Odd ? _Q2 < _Q1 : _Q1 < _Q2;
+};
+
+template <class _R1, class _R2, bool _Odd, intmax_t _Qp>
+struct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, 0>
+{
+    static const bool value = false;
+};
+
+template <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M2>
+struct __ratio_less1<_R1, _R2, _Odd, _Qp, 0, _Qp, _M2>
+{
+    static const bool value = !_Odd;
+};
+
+template <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1>
+struct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, 0>
+{
+    static const bool value = _Odd;
+};
+
+template <class _R1, class _R2, bool _Odd, intmax_t _Qp, intmax_t _M1,
+                                                        intmax_t _M2>
+struct __ratio_less1<_R1, _R2, _Odd, _Qp, _M1, _Qp, _M2>
+{
+    static const bool value = __ratio_less1<ratio<_R1::den, _M1>,
+                                            ratio<_R2::den, _M2>, !_Odd>::value;
+};
+
+template <class _R1, class _R2, intmax_t _S1 = __static_sign<_R1::num>::value,
+                                intmax_t _S2 = __static_sign<_R2::num>::value>
+struct __ratio_less
+{
+    static const bool value = _S1 < _S2;
+};
+
+template <class _R1, class _R2>
+struct __ratio_less<_R1, _R2, 1LL, 1LL>
+{
+    static const bool value = __ratio_less1<_R1, _R2>::value;
+};
+
+template <class _R1, class _R2>
+struct __ratio_less<_R1, _R2, -1LL, -1LL>
+{
+    static const bool value = __ratio_less1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::value;
+};
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_less
+    : public integral_constant<bool, __ratio_less<_R1, _R2>::value> {};
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal
+    : public integral_constant<bool, !ratio_less<_R2, _R1>::value> {};
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_greater
+    : public integral_constant<bool, ratio_less<_R2, _R1>::value> {};
+
+template <class _R1, class _R2>
+struct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal
+    : public integral_constant<bool, !ratio_less<_R1, _R2>::value> {};
+
+template <class _R1, class _R2>
+struct __ratio_gcd
+{
+    typedef ratio<__static_gcd<_R1::num, _R2::num>::value,
+                  __static_lcm<_R1::den, _R2::den>::value> type;
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_RATIO
diff --git a/include/c++/v1/regex b/include/c++/v1/regex
new file mode 100644
index 0000000..bebbaf0
--- /dev/null
+++ b/include/c++/v1/regex
@@ -0,0 +1,6590 @@
+// -*- C++ -*-
+//===--------------------------- regex ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_REGEX
+#define _LIBCPP_REGEX
+
+/*
+    regex synopsis
+
+#include <initializer_list>
+
+namespace std
+{
+
+namespace regex_constants
+{
+
+emum syntax_option_type
+{
+    icase      = unspecified,
+    nosubs     = unspecified,
+    optimize   = unspecified,
+    collate    = unspecified,
+    ECMAScript = unspecified,
+    basic      = unspecified,
+    extended   = unspecified,
+    awk        = unspecified,
+    grep       = unspecified,
+    egrep      = unspecified
+};
+
+constexpr syntax_option_type operator~(syntax_option_type f);
+constexpr syntax_option_type operator&(syntax_option_type lhs, syntax_option_type rhs);
+constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);
+
+enum match_flag_type
+{
+    match_default     = 0,
+    match_not_bol     = unspecified,
+    match_not_eol     = unspecified,
+    match_not_bow     = unspecified,
+    match_not_eow     = unspecified,
+    match_any         = unspecified,
+    match_not_null    = unspecified,
+    match_continuous  = unspecified,
+    match_prev_avail  = unspecified,
+    format_default    = 0,
+    format_sed        = unspecified,
+    format_no_copy    = unspecified,
+    format_first_only = unspecified
+};
+
+constexpr match_flag_type operator~(match_flag_type f);
+constexpr match_flag_type operator&(match_flag_type lhs, match_flag_type rhs);
+constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);
+
+enum error_type
+{
+    error_collate    = unspecified,
+    error_ctype      = unspecified,
+    error_escape     = unspecified,
+    error_backref    = unspecified,
+    error_brack      = unspecified,
+    error_paren      = unspecified,
+    error_brace      = unspecified,
+    error_badbrace   = unspecified,
+    error_range      = unspecified,
+    error_space      = unspecified,
+    error_badrepeat  = unspecified,
+    error_complexity = unspecified,
+    error_stack      = unspecified
+};
+
+}  // regex_constants
+
+class regex_error
+    : public runtime_error
+{
+public:
+    explicit regex_error(regex_constants::error_type ecode);
+    regex_constants::error_type code() const;
+};
+
+template <class charT>
+struct regex_traits
+{
+public:
+    typedef charT                   char_type;
+    typedef basic_string<char_type> string_type;
+    typedef locale                  locale_type;
+    typedef /bitmask_type/          char_class_type;
+
+    regex_traits();
+
+    static size_t length(const char_type* p);
+    charT translate(charT c) const;
+    charT translate_nocase(charT c) const;
+    template <class ForwardIterator>
+        string_type
+        transform(ForwardIterator first, ForwardIterator last) const;
+    template <class ForwardIterator>
+        string_type
+        transform_primary( ForwardIterator first, ForwardIterator last) const;
+    template <class ForwardIterator>
+        string_type
+        lookup_collatename(ForwardIterator first, ForwardIterator last) const;
+    template <class ForwardIterator>
+        char_class_type
+        lookup_classname(ForwardIterator first, ForwardIterator last,
+                         bool icase = false) const;
+    bool isctype(charT c, char_class_type f) const;
+    int value(charT ch, int radix) const;
+    locale_type imbue(locale_type l);
+    locale_type getloc()const;
+};
+
+template <class charT, class traits = regex_traits<charT>>
+class basic_regex
+{
+public:
+    // types:
+    typedef charT                               value_type;
+    typedef regex_constants::syntax_option_type flag_type;
+    typedef typename traits::locale_type        locale_type;
+
+    // constants:
+    static constexpr regex_constants::syntax_option_type icase = regex_constants::icase;
+    static constexpr regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
+    static constexpr regex_constants::syntax_option_type optimize = regex_constants::optimize;
+    static constexpr regex_constants::syntax_option_type collate = regex_constants::collate;
+    static constexpr regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
+    static constexpr regex_constants::syntax_option_type basic = regex_constants::basic;
+    static constexpr regex_constants::syntax_option_type extended = regex_constants::extended;
+    static constexpr regex_constants::syntax_option_type awk = regex_constants::awk;
+    static constexpr regex_constants::syntax_option_type grep = regex_constants::grep;
+    static constexpr regex_constants::syntax_option_type egrep = regex_constants::egrep;
+
+    // construct/copy/destroy:
+    basic_regex();
+    explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript);
+    basic_regex(const charT* p, size_t len, flag_type f);
+    basic_regex(const basic_regex&);
+    basic_regex(basic_regex&&) noexcept;
+    template <class ST, class SA>
+        explicit basic_regex(const basic_string<charT, ST, SA>& p,
+                             flag_type f = regex_constants::ECMAScript);
+    template <class ForwardIterator>
+        basic_regex(ForwardIterator first, ForwardIterator last,
+                    flag_type f = regex_constants::ECMAScript);
+    basic_regex(initializer_list<charT>, flag_type = regex_constants::ECMAScript);
+
+    ~basic_regex();
+
+    basic_regex& operator=(const basic_regex&);
+    basic_regex& operator=(basic_regex&&) noexcept;
+    basic_regex& operator=(const charT* ptr);
+    basic_regex& operator=(initializer_list<charT> il);
+    template <class ST, class SA>
+        basic_regex& operator=(const basic_string<charT, ST, SA>& p);
+
+    // assign:
+    basic_regex& assign(const basic_regex& that);
+    basic_regex& assign(basic_regex&& that) noexcept;
+    basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript);
+    basic_regex& assign(const charT* p, size_t len, flag_type f);
+    template <class string_traits, class A>
+        basic_regex& assign(const basic_string<charT, string_traits, A>& s,
+                            flag_type f = regex_constants::ECMAScript);
+    template <class InputIterator>
+        basic_regex& assign(InputIterator first, InputIterator last,
+                            flag_type f = regex_constants::ECMAScript);
+    basic_regex& assign(initializer_list<charT>, flag_type = regex_constants::ECMAScript);
+
+    // const operations:
+    unsigned mark_count() const;
+    flag_type flags() const;
+
+    // locale:
+    locale_type imbue(locale_type loc);
+    locale_type getloc() const;
+
+    // swap:
+    void swap(basic_regex&);
+};
+
+typedef basic_regex<char>    regex;
+typedef basic_regex<wchar_t> wregex;
+
+template <class charT, class traits>
+    void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2);
+
+template <class BidirectionalIterator>
+class sub_match
+    : public pair<BidirectionalIterator, BidirectionalIterator>
+{
+public:
+    typedef typename iterator_traits<BidirectionalIterator>::value_type value_type;
+    typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
+    typedef BidirectionalIterator                                      iterator;
+    typedef basic_string<value_type>                                string_type;
+
+    bool matched;
+
+    constexpr sub_match();
+
+    difference_type length() const;
+    operator string_type() const;
+    string_type str() const;
+
+    int compare(const sub_match& s) const;
+    int compare(const string_type& s) const;
+    int compare(const value_type* s) const;
+};
+
+typedef sub_match<const char*>             csub_match;
+typedef sub_match<const wchar_t*>          wcsub_match;
+typedef sub_match<string::const_iterator>  ssub_match;
+typedef sub_match<wstring::const_iterator> wssub_match;
+
+template <class BiIter>
+    bool
+    operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+                    const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator==(const sub_match<BiIter>& lhs,
+               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator!=(const sub_match<BiIter>& lhs,
+               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator<(const sub_match<BiIter>& lhs,
+              const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool operator>(const sub_match<BiIter>& lhs,
+                   const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator>=(const sub_match<BiIter>& lhs,
+               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter, class ST, class SA>
+    bool
+    operator<=(const sub_match<BiIter>& lhs,
+               const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs);
+
+template <class BiIter>
+    bool
+    operator==(typename iterator_traits<BiIter>::value_type const* lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator!=(typename iterator_traits<BiIter>::value_type const* lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<(typename iterator_traits<BiIter>::value_type const* lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>(typename iterator_traits<BiIter>::value_type const* lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>=(typename iterator_traits<BiIter>::value_type const* lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<=(typename iterator_traits<BiIter>::value_type const* lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator==(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator!=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator<(const sub_match<BiIter>& lhs,
+              typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator>(const sub_match<BiIter>& lhs,
+              typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator>=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator<=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const* rhs);
+
+template <class BiIter>
+    bool
+    operator==(typename iterator_traits<BiIter>::value_type const& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator!=(typename iterator_traits<BiIter>::value_type const& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<(typename iterator_traits<BiIter>::value_type const& lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>(typename iterator_traits<BiIter>::value_type const& lhs,
+              const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator>=(typename iterator_traits<BiIter>::value_type const& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator<=(typename iterator_traits<BiIter>::value_type const& lhs,
+               const sub_match<BiIter>& rhs);
+
+template <class BiIter>
+    bool
+    operator==(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>
+    bool
+    operator!=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>
+    bool
+    operator<(const sub_match<BiIter>& lhs,
+              typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>
+    bool
+    operator>(const sub_match<BiIter>& lhs,
+              typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>
+    bool
+    operator>=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class BiIter>
+    bool
+    operator<=(const sub_match<BiIter>& lhs,
+               typename iterator_traits<BiIter>::value_type const& rhs);
+
+template <class charT, class ST, class BiIter>
+    basic_ostream<charT, ST>&
+    operator<<(basic_ostream<charT, ST>& os, const sub_match<BiIter>& m);
+
+template <class BidirectionalIterator,
+          class Allocator = allocator<sub_match<BidirectionalIterator>>>
+class match_results
+{
+public:
+    typedef sub_match<BidirectionalIterator>                  value_type;
+    typedef const value_type&                                 const_reference;
+    typedef value_type&                                       reference;
+    typedef /implementation-defined/                          const_iterator;
+    typedef const_iterator                                    iterator;
+    typedef typename iterator_traits<BidirectionalIterator>::difference_type difference_type;
+    typedef typename allocator_traits<Allocator>::size_type   size_type;
+    typedef Allocator                                         allocator_type;
+    typedef typename iterator_traits<BidirectionalIterator>::value_type char_type;
+    typedef basic_string<char_type>                           string_type;
+
+    // construct/copy/destroy:
+    explicit match_results(const Allocator& a = Allocator());
+    match_results(const match_results& m);
+    match_results(match_results&& m) noexcept;
+    match_results& operator=(const match_results& m);
+    match_results& operator=(match_results&& m);
+    ~match_results();
+
+    bool ready() const;
+
+    // size:
+    size_type size() const;
+    size_type max_size() const;
+    bool empty() const;
+
+    // element access:
+    difference_type length(size_type sub = 0) const;
+    difference_type position(size_type sub = 0) const;
+    string_type str(size_type sub = 0) const;
+    const_reference operator[](size_type n) const;
+
+    const_reference prefix() const;
+    const_reference suffix() const;
+
+    const_iterator begin() const;
+    const_iterator end() const;
+    const_iterator cbegin() const;
+    const_iterator cend() const;
+
+    // format:
+    template <class OutputIter>
+        OutputIter
+        format(OutputIter out, const char_type* fmt_first,
+               const char_type* fmt_last,
+               regex_constants::match_flag_type flags = regex_constants::format_default) const;
+    template <class OutputIter, class ST, class SA>
+        OutputIter
+        format(OutputIter out, const basic_string<char_type, ST, SA>& fmt,
+               regex_constants::match_flag_type flags = regex_constants::format_default) const;
+    template <class ST, class SA>
+        basic_string<char_type, ST, SA>
+        format(const basic_string<char_type, ST, SA>& fmt,
+               regex_constants::match_flag_type flags = regex_constants::format_default) const;
+    string_type
+        format(const char_type* fmt,
+               regex_constants::match_flag_type flags = regex_constants::format_default) const;
+
+    // allocator:
+    allocator_type get_allocator() const;
+
+    // swap:
+    void swap(match_results& that);
+};
+
+typedef match_results<const char*>             cmatch;
+typedef match_results<const wchar_t*>          wcmatch;
+typedef match_results<string::const_iterator>  smatch;
+typedef match_results<wstring::const_iterator> wsmatch;
+
+template <class BidirectionalIterator, class Allocator>
+    bool
+    operator==(const match_results<BidirectionalIterator, Allocator>& m1,
+               const match_results<BidirectionalIterator, Allocator>& m2);
+
+template <class BidirectionalIterator, class Allocator>
+    bool
+    operator!=(const match_results<BidirectionalIterator, Allocator>& m1,
+               const match_results<BidirectionalIterator, Allocator>& m2);
+
+template <class BidirectionalIterator, class Allocator>
+    void
+    swap(match_results<BidirectionalIterator, Allocator>& m1,
+         match_results<BidirectionalIterator, Allocator>& m2);
+
+template <class BidirectionalIterator, class Allocator, class charT, class traits>
+    bool
+    regex_match(BidirectionalIterator first, BidirectionalIterator last,
+                match_results<BidirectionalIterator, Allocator>& m,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class BidirectionalIterator, class charT, class traits>
+    bool
+    regex_match(BidirectionalIterator first, BidirectionalIterator last,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class charT, class Allocator, class traits>
+    bool
+    regex_match(const charT* str, match_results<const charT*, Allocator>& m,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+    bool
+    regex_match(const basic_string<charT, ST, SA>& s,
+                match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+    bool
+    regex_match(const basic_string<charT, ST, SA>&& s,
+                match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14
+
+template <class charT, class traits>
+    bool
+    regex_match(const charT* str, const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class charT, class traits>
+    bool
+    regex_match(const basic_string<charT, ST, SA>& s,
+                const basic_regex<charT, traits>& e,
+                regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class BidirectionalIterator, class Allocator, class charT, class traits>
+    bool
+    regex_search(BidirectionalIterator first, BidirectionalIterator last,
+                 match_results<BidirectionalIterator, Allocator>& m,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class BidirectionalIterator, class charT, class traits>
+    bool
+    regex_search(BidirectionalIterator first, BidirectionalIterator last,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class charT, class Allocator, class traits>
+    bool
+    regex_search(const charT* str, match_results<const charT*, Allocator>& m,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class charT, class traits>
+    bool
+    regex_search(const charT* str, const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class charT, class traits>
+    bool
+    regex_search(const basic_string<charT, ST, SA>& s,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+    bool
+    regex_search(const basic_string<charT, ST, SA>& s,
+                 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class ST, class SA, class Allocator, class charT, class traits>
+    bool
+    regex_search(const basic_string<charT, ST, SA>&& s,
+                 match_results<typename basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
+                 const basic_regex<charT, traits>& e,
+                 regex_constants::match_flag_type flags = regex_constants::match_default) = delete; // C++14
+
+template <class OutputIterator, class BidirectionalIterator,
+          class traits, class charT, class ST, class SA>
+    OutputIterator
+    regex_replace(OutputIterator out,
+                  BidirectionalIterator first, BidirectionalIterator last,
+                  const basic_regex<charT, traits>& e,
+                  const basic_string<charT, ST, SA>& fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class OutputIterator, class BidirectionalIterator,
+          class traits, class charT>
+    OutputIterator
+    regex_replace(OutputIterator out,
+                  BidirectionalIterator first, BidirectionalIterator last,
+                  const basic_regex<charT, traits>& e, const charT* fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class traits, class charT, class ST, class SA, class FST, class FSA>>
+    basic_string<charT, ST, SA>
+    regex_replace(const basic_string<charT, ST, SA>& s,
+                  const basic_regex<charT, traits>& e,
+                  const basic_string<charT, FST, FSA>& fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class traits, class charT, class ST, class SA>
+    basic_string<charT, ST, SA>
+    regex_replace(const basic_string<charT, ST, SA>& s,
+                  const basic_regex<charT, traits>& e, const charT* fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class traits, class charT, class ST, class SA>
+    basic_string<charT>
+    regex_replace(const charT* s,
+                  const basic_regex<charT, traits>& e,
+                  const basic_string<charT, ST, SA>& fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class traits, class charT>
+    basic_string<charT>
+    regex_replace(const charT* s,
+                  const basic_regex<charT, traits>& e,
+                  const charT* fmt,
+                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+template <class BidirectionalIterator,
+          class charT = typename iterator_traits< BidirectionalIterator>::value_type,
+          class traits = regex_traits<charT>>
+class regex_iterator
+{
+public:
+    typedef basic_regex<charT, traits>           regex_type;
+    typedef match_results<BidirectionalIterator> value_type;
+    typedef ptrdiff_t                            difference_type;
+    typedef const value_type*                    pointer;
+    typedef const value_type&                    reference;
+    typedef forward_iterator_tag                 iterator_category;
+
+    regex_iterator();
+    regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                   const regex_type& re,
+                   regex_constants::match_flag_type m = regex_constants::match_default);
+    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                   const regex_type&& __re,
+                   regex_constants::match_flag_type __m 
+                                     = regex_constants::match_default) = delete; // C++14
+    regex_iterator(const regex_iterator&);
+    regex_iterator& operator=(const regex_iterator&);
+
+    bool operator==(const regex_iterator&) const;
+    bool operator!=(const regex_iterator&) const;
+
+    const value_type& operator*() const;
+    const value_type* operator->() const;
+
+    regex_iterator& operator++();
+    regex_iterator operator++(int);
+};
+
+typedef regex_iterator<const char*>             cregex_iterator;
+typedef regex_iterator<const wchar_t*>          wcregex_iterator;
+typedef regex_iterator<string::const_iterator>  sregex_iterator;
+typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
+
+template <class BidirectionalIterator,
+          class charT = typename iterator_traits< BidirectionalIterator>::value_type,
+          class traits = regex_traits<charT>>
+class regex_token_iterator
+{
+public:
+    typedef basic_regex<charT, traits>       regex_type;
+    typedef sub_match<BidirectionalIterator> value_type;
+    typedef ptrdiff_t                        difference_type;
+    typedef const value_type*                pointer;
+    typedef const value_type&                reference;
+    typedef forward_iterator_tag             iterator_category;
+
+    regex_token_iterator();
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type& re, int submatch = 0,
+                         regex_constants::match_flag_type m = regex_constants::match_default);
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type&& re, int submatch = 0,
+                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type& re, const vector<int>& submatches,
+                         regex_constants::match_flag_type m = regex_constants::match_default);
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type&& re, const vector<int>& submatches,
+                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type& re, initializer_list<int> submatches,
+                         regex_constants::match_flag_type m = regex_constants::match_default);
+    regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                         const regex_type&& re, initializer_list<int> submatches,
+                         regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
+    template <size_t N>
+        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                             const regex_type& re, const int (&submatches)[N],
+                             regex_constants::match_flag_type m = regex_constants::match_default);
+    template <size_t N>
+        regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
+                             const regex_type& re, const int (&submatches)[N],
+                             regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14;
+    regex_token_iterator(const regex_token_iterator&);
+    regex_token_iterator& operator=(const regex_token_iterator&);
+
+    bool operator==(const regex_token_iterator&) const;
+    bool operator!=(const regex_token_iterator&) const;
+
+    const value_type& operator*() const;
+    const value_type* operator->() const;
+
+    regex_token_iterator& operator++();
+    regex_token_iterator operator++(int);
+};
+
+typedef regex_token_iterator<const char*>             cregex_token_iterator;
+typedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;
+typedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;
+typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
+
+} // std
+*/
+
+#include <__config>
+#include <stdexcept>
+#include <__locale>
+#include <initializer_list>
+#include <utility>
+#include <iterator>
+#include <string>
+#include <memory>
+#include <vector>
+#include <deque>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace regex_constants
+{
+
+// syntax_option_type
+
+enum syntax_option_type
+{
+    icase      = 1 << 0,
+    nosubs     = 1 << 1,
+    optimize   = 1 << 2,
+    collate    = 1 << 3,
+    ECMAScript = 0,
+    basic      = 1 << 4,
+    extended   = 1 << 5,
+    awk        = 1 << 6,
+    grep       = 1 << 7,
+    egrep      = 1 << 8
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+syntax_option_type
+operator~(syntax_option_type __x)
+{
+    return syntax_option_type(~int(__x) & 0x1FF);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+syntax_option_type
+operator&(syntax_option_type __x, syntax_option_type __y)
+{
+    return syntax_option_type(int(__x) & int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+syntax_option_type
+operator|(syntax_option_type __x, syntax_option_type __y)
+{
+    return syntax_option_type(int(__x) | int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+syntax_option_type
+operator^(syntax_option_type __x, syntax_option_type __y)
+{
+    return syntax_option_type(int(__x) ^ int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+syntax_option_type&
+operator&=(syntax_option_type& __x, syntax_option_type __y)
+{
+    __x = __x & __y;
+    return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+syntax_option_type&
+operator|=(syntax_option_type& __x, syntax_option_type __y)
+{
+    __x = __x | __y;
+    return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+syntax_option_type&
+operator^=(syntax_option_type& __x, syntax_option_type __y)
+{
+    __x = __x ^ __y;
+    return __x;
+}
+
+// match_flag_type
+
+enum match_flag_type
+{
+    match_default     = 0,
+    match_not_bol     = 1 << 0,
+    match_not_eol     = 1 << 1,
+    match_not_bow     = 1 << 2,
+    match_not_eow     = 1 << 3,
+    match_any         = 1 << 4,
+    match_not_null    = 1 << 5,
+    match_continuous  = 1 << 6,
+    match_prev_avail  = 1 << 7,
+    format_default    = 0,
+    format_sed        = 1 << 8,
+    format_no_copy    = 1 << 9,
+    format_first_only = 1 << 10,
+    __no_update_pos   = 1 << 11
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+match_flag_type
+operator~(match_flag_type __x)
+{
+    return match_flag_type(~int(__x) & 0x0FFF);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+match_flag_type
+operator&(match_flag_type __x, match_flag_type __y)
+{
+    return match_flag_type(int(__x) & int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+match_flag_type
+operator|(match_flag_type __x, match_flag_type __y)
+{
+    return match_flag_type(int(__x) | int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+_LIBCPP_CONSTEXPR
+match_flag_type
+operator^(match_flag_type __x, match_flag_type __y)
+{
+    return match_flag_type(int(__x) ^ int(__y));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+match_flag_type&
+operator&=(match_flag_type& __x, match_flag_type __y)
+{
+    __x = __x & __y;
+    return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+match_flag_type&
+operator|=(match_flag_type& __x, match_flag_type __y)
+{
+    __x = __x | __y;
+    return __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+match_flag_type&
+operator^=(match_flag_type& __x, match_flag_type __y)
+{
+    __x = __x ^ __y;
+    return __x;
+}
+
+enum error_type
+{
+    error_collate = 1,
+    error_ctype,
+    error_escape,
+    error_backref,
+    error_brack,
+    error_paren,
+    error_brace,
+    error_badbrace,
+    error_range,
+    error_space,
+    error_badrepeat,
+    error_complexity,
+    error_stack,
+    __re_err_grammar,
+    __re_err_empty,
+    __re_err_unknown
+};
+
+}  // regex_constants
+
+class _LIBCPP_EXCEPTION_ABI regex_error
+    : public runtime_error
+{
+    regex_constants::error_type __code_;
+public:
+    explicit regex_error(regex_constants::error_type __ecode);
+    virtual ~regex_error() throw();
+     _LIBCPP_INLINE_VISIBILITY
+    regex_constants::error_type code() const {return __code_;}
+};
+
+template <class _CharT>
+struct _LIBCPP_TYPE_VIS_ONLY regex_traits
+{
+public:
+    typedef _CharT                  char_type;
+    typedef basic_string<char_type> string_type;
+    typedef locale                  locale_type;
+    typedef ctype_base::mask        char_class_type;
+
+    static const char_class_type __regex_word = 0x80;
+private:
+    locale __loc_;
+    const ctype<char_type>* __ct_;
+    const collate<char_type>* __col_;
+
+public:
+    regex_traits();
+
+    _LIBCPP_INLINE_VISIBILITY
+    static size_t length(const char_type* __p)
+        {return char_traits<char_type>::length(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    char_type translate(char_type __c) const {return __c;}
+    char_type translate_nocase(char_type __c) const;
+    template <class _ForwardIterator>
+        string_type
+        transform(_ForwardIterator __f, _ForwardIterator __l) const;
+    template <class _ForwardIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        string_type
+        transform_primary( _ForwardIterator __f, _ForwardIterator __l) const
+            {return __transform_primary(__f, __l, char_type());}
+    template <class _ForwardIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        string_type
+        lookup_collatename(_ForwardIterator __f, _ForwardIterator __l) const
+            {return __lookup_collatename(__f, __l, char_type());}
+    template <class _ForwardIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        char_class_type
+        lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
+                         bool __icase = false) const
+            {return __lookup_classname(__f, __l, __icase, char_type());}
+    bool isctype(char_type __c, char_class_type __m) const;
+    _LIBCPP_INLINE_VISIBILITY
+    int value(char_type __ch, int __radix) const
+        {return __regex_traits_value(__ch, __radix);}
+    locale_type imbue(locale_type __l);
+    _LIBCPP_INLINE_VISIBILITY
+    locale_type getloc()const {return __loc_;}
+
+private:
+    void __init();
+
+    template <class _ForwardIterator>
+        string_type
+        __transform_primary(_ForwardIterator __f, _ForwardIterator __l, char) const;
+    template <class _ForwardIterator>
+        string_type
+        __transform_primary(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
+
+    template <class _ForwardIterator>
+        string_type
+        __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, char) const;
+    template <class _ForwardIterator>
+        string_type
+        __lookup_collatename(_ForwardIterator __f, _ForwardIterator __l, wchar_t) const;
+
+    template <class _ForwardIterator>
+        char_class_type
+        __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
+                           bool __icase, char) const;
+    template <class _ForwardIterator>
+        char_class_type
+        __lookup_classname(_ForwardIterator __f, _ForwardIterator __l,
+                           bool __icase, wchar_t) const;
+
+    static int __regex_traits_value(unsigned char __ch, int __radix);
+    _LIBCPP_INLINE_VISIBILITY
+    int __regex_traits_value(char __ch, int __radix) const
+        {return __regex_traits_value(static_cast<unsigned char>(__ch), __radix);}
+    int __regex_traits_value(wchar_t __ch, int __radix) const;
+};
+
+template <class _CharT>
+const typename regex_traits<_CharT>::char_class_type
+regex_traits<_CharT>::__regex_word;
+
+template <class _CharT>
+regex_traits<_CharT>::regex_traits()
+{
+    __init();
+}
+
+template <class _CharT>
+typename regex_traits<_CharT>::char_type
+regex_traits<_CharT>::translate_nocase(char_type __c) const
+{
+    return __ct_->tolower(__c);
+}
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::string_type
+regex_traits<_CharT>::transform(_ForwardIterator __f, _ForwardIterator __l) const
+{
+    string_type __s(__f, __l);
+    return __col_->transform(__s.data(), __s.data() + __s.size());
+}
+
+template <class _CharT>
+void
+regex_traits<_CharT>::__init()
+{
+    __ct_ = &use_facet<ctype<char_type> >(__loc_);
+    __col_ = &use_facet<collate<char_type> >(__loc_);
+}
+
+template <class _CharT>
+typename regex_traits<_CharT>::locale_type
+regex_traits<_CharT>::imbue(locale_type __l)
+{
+    locale __r = __loc_;
+    __loc_ = __l;
+    __init();
+    return __r;
+}
+
+// transform_primary is very FreeBSD-specific
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::string_type
+regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
+                                          _ForwardIterator __l, char) const
+{
+    const string_type __s(__f, __l);
+    string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
+    switch (__d.size())
+    {
+    case 1:
+        break;
+    case 12:
+        __d[11] = __d[3];
+        break;
+    default:
+        __d.clear();
+        break;
+    }
+    return __d;
+}
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::string_type
+regex_traits<_CharT>::__transform_primary(_ForwardIterator __f,
+                                          _ForwardIterator __l, wchar_t) const
+{
+    const string_type __s(__f, __l);
+    string_type __d = __col_->transform(__s.data(), __s.data() + __s.size());
+    switch (__d.size())
+    {
+    case 1:
+        break;
+    case 3:
+        __d[2] = __d[0];
+        break;
+    default:
+        __d.clear();
+        break;
+    }
+    return __d;
+}
+
+// lookup_collatename is very FreeBSD-specific
+
+_LIBCPP_FUNC_VIS string __get_collation_name(const char* __s);
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::string_type
+regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
+                                           _ForwardIterator __l, char) const
+{
+    string_type __s(__f, __l);
+    string_type __r;
+    if (!__s.empty())
+    {
+        __r = __get_collation_name(__s.c_str());
+        if (__r.empty() && __s.size() <= 2)
+        {
+            __r = __col_->transform(__s.data(), __s.data() + __s.size());
+            if (__r.size() == 1 || __r.size() == 12)
+                __r = __s;
+            else
+                __r.clear();
+        }
+    }
+    return __r;
+}
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::string_type
+regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f,
+                                           _ForwardIterator __l, wchar_t) const
+{
+    string_type __s(__f, __l);
+    string __n;
+    __n.reserve(__s.size());
+    for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
+                                                              __i != __e; ++__i)
+    {
+        if (static_cast<unsigned>(*__i) >= 127)
+            return string_type();
+        __n.push_back(char(*__i));
+    }
+    string_type __r;
+    if (!__s.empty())
+    {
+        __n = __get_collation_name(__n.c_str());
+        if (!__n.empty())
+            __r.assign(__n.begin(), __n.end());
+        else if (__s.size() <= 2)
+        {
+            __r = __col_->transform(__s.data(), __s.data() + __s.size());
+            if (__r.size() == 1 || __r.size() == 3)
+                __r = __s;
+            else
+                __r.clear();
+        }
+    }
+    return __r;
+}
+
+// lookup_classname
+
+ctype_base::mask _LIBCPP_FUNC_VIS __get_classname(const char* __s, bool __icase);
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::char_class_type
+regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
+                                         _ForwardIterator __l,
+                                         bool __icase, char) const
+{
+    string_type __s(__f, __l);
+    __ct_->tolower(&__s[0], &__s[0] + __s.size());
+    return __get_classname(__s.c_str(), __icase);
+}
+
+template <class _CharT>
+template <class _ForwardIterator>
+typename regex_traits<_CharT>::char_class_type
+regex_traits<_CharT>::__lookup_classname(_ForwardIterator __f,
+                                         _ForwardIterator __l,
+                                         bool __icase, wchar_t) const
+{
+    string_type __s(__f, __l);
+    __ct_->tolower(&__s[0], &__s[0] + __s.size());
+    string __n;
+    __n.reserve(__s.size());
+    for (typename string_type::const_iterator __i = __s.begin(), __e = __s.end();
+                                                              __i != __e; ++__i)
+    {
+        if (static_cast<unsigned>(*__i) >= 127)
+            return char_class_type();
+        __n.push_back(char(*__i));
+    }
+    return __get_classname(__n.c_str(), __icase);
+}
+
+template <class _CharT>
+bool
+regex_traits<_CharT>::isctype(char_type __c, char_class_type __m) const
+{
+    if (__ct_->is(__m, __c))
+        return true;
+    return (__c == '_' && (__m & __regex_word));
+}
+
+template <class _CharT>
+int
+regex_traits<_CharT>::__regex_traits_value(unsigned char __ch, int __radix)
+{
+    if ((__ch & 0xF8u) == 0x30)  // '0' <= __ch && __ch <= '7'
+        return __ch - '0';
+    if (__radix != 8)
+    {
+        if ((__ch & 0xFEu) == 0x38)  // '8' <= __ch && __ch <= '9'
+            return __ch - '0';
+        if (__radix == 16)
+        {
+            __ch |= 0x20;  // tolower
+            if ('a' <= __ch && __ch <= 'f')
+                return __ch - ('a' - 10);
+        }
+    }
+    return -1;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+int
+regex_traits<_CharT>::__regex_traits_value(wchar_t __ch, int __radix) const
+{
+    return __regex_traits_value(static_cast<unsigned char>(__ct_->narrow(__ch, char_type())), __radix);
+}
+
+template <class _CharT> class __node;
+
+template <class _BidirectionalIterator> class _LIBCPP_TYPE_VIS_ONLY sub_match;
+
+template <class _BidirectionalIterator,
+          class _Allocator = allocator<sub_match<_BidirectionalIterator> > >
+class _LIBCPP_TYPE_VIS_ONLY match_results;
+
+template <class _CharT>
+struct __state
+{
+    enum
+    {
+        __end_state = -1000,
+        __consume_input,  // -999
+        __begin_marked_expr, // -998
+        __end_marked_expr,   // -997
+        __pop_state,           // -996
+        __accept_and_consume,  // -995
+        __accept_but_not_consume,  // -994
+        __reject,                  // -993
+        __split,
+        __repeat
+    };
+
+    int __do_;
+    const _CharT* __first_;
+    const _CharT* __current_;
+    const _CharT* __last_;
+    vector<sub_match<const _CharT*> > __sub_matches_;
+    vector<pair<size_t, const _CharT*> > __loop_data_;
+    const __node<_CharT>* __node_;
+    regex_constants::match_flag_type __flags_;
+    bool __at_first_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __state()
+        : __do_(0), __first_(nullptr), __current_(nullptr), __last_(nullptr),
+          __node_(nullptr), __flags_() {}
+};
+
+// __node
+
+template <class _CharT>
+class __node
+{
+    __node(const __node&);
+    __node& operator=(const __node&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node() {}
+    _LIBCPP_INLINE_VISIBILITY
+    virtual ~__node() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    virtual void __exec(__state&) const {};
+    _LIBCPP_INLINE_VISIBILITY
+    virtual void __exec_split(bool, __state&) const {};
+};
+
+// __end_state
+
+template <class _CharT>
+class __end_state
+    : public __node<_CharT>
+{
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __end_state() {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__end_state<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__end_state;
+}
+
+// __has_one_state
+
+template <class _CharT>
+class __has_one_state
+    : public __node<_CharT>
+{
+    __node<_CharT>* __first_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __has_one_state(__node<_CharT>* __s)
+        : __first_(__s) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __node<_CharT>*  first() const {return __first_;}
+    _LIBCPP_INLINE_VISIBILITY
+    __node<_CharT>*& first()       {return __first_;}
+};
+
+// __owns_one_state
+
+template <class _CharT>
+class __owns_one_state
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __owns_one_state(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual ~__owns_one_state();
+};
+
+template <class _CharT>
+__owns_one_state<_CharT>::~__owns_one_state()
+{
+    delete this->first();
+}
+
+// __empty_state
+
+template <class _CharT>
+class __empty_state
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __empty_state(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__empty_state<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__node_ = this->first();
+}
+
+// __empty_non_own_state
+
+template <class _CharT>
+class __empty_non_own_state
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __empty_non_own_state(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__empty_non_own_state<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__node_ = this->first();
+}
+
+// __repeat_one_loop
+
+template <class _CharT>
+class __repeat_one_loop
+    : public __has_one_state<_CharT>
+{
+    typedef __has_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __repeat_one_loop(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__repeat_one_loop<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__repeat;
+    __s.__node_ = this->first();
+}
+
+// __owns_two_states
+
+template <class _CharT>
+class __owns_two_states
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    base* __second_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
+        : base(__s1), __second_(__s2) {}
+
+    virtual ~__owns_two_states();
+
+    _LIBCPP_INLINE_VISIBILITY
+    base*  second() const {return __second_;}
+    _LIBCPP_INLINE_VISIBILITY
+    base*& second()       {return __second_;}
+};
+
+template <class _CharT>
+__owns_two_states<_CharT>::~__owns_two_states()
+{
+    delete __second_;
+}
+
+// __loop
+
+template <class _CharT>
+class __loop
+    : public __owns_two_states<_CharT>
+{
+    typedef __owns_two_states<_CharT> base;
+
+    size_t __min_;
+    size_t __max_;
+    unsigned __loop_id_;
+    unsigned __mexp_begin_;
+    unsigned __mexp_end_;
+    bool __greedy_;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __loop(unsigned __loop_id,
+                          __node<_CharT>* __s1, __owns_one_state<_CharT>* __s2,
+                          unsigned __mexp_begin, unsigned __mexp_end,
+                          bool __greedy = true,
+                          size_t __min = 0,
+                          size_t __max = numeric_limits<size_t>::max())
+        : base(__s1, __s2), __min_(__min), __max_(__max), __loop_id_(__loop_id),
+          __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end),
+          __greedy_(__greedy) {}
+
+    virtual void __exec(__state& __s) const;
+    virtual void __exec_split(bool __second, __state& __s) const;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __init_repeat(__state& __s) const
+    {
+        __s.__loop_data_[__loop_id_].second = __s.__current_;
+        for (size_t __i = __mexp_begin_-1; __i != __mexp_end_-1; ++__i)
+        {
+            __s.__sub_matches_[__i].first = __s.__last_;
+            __s.__sub_matches_[__i].second = __s.__last_;
+            __s.__sub_matches_[__i].matched = false;
+        }
+    }
+};
+
+template <class _CharT>
+void
+__loop<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__do_ == __state::__repeat)
+    {
+        bool __do_repeat = ++__s.__loop_data_[__loop_id_].first < __max_;
+        bool __do_alt = __s.__loop_data_[__loop_id_].first >= __min_;
+        if (__do_repeat && __do_alt &&
+                               __s.__loop_data_[__loop_id_].second == __s.__current_)
+            __do_repeat = false;
+        if (__do_repeat && __do_alt)
+            __s.__do_ = __state::__split;
+        else if (__do_repeat)
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->first();
+            __init_repeat(__s);
+        }
+        else
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->second();
+        }
+    }
+    else
+    {
+        __s.__loop_data_[__loop_id_].first = 0;
+        bool __do_repeat = 0 < __max_;
+        bool __do_alt = 0 >= __min_;
+        if (__do_repeat && __do_alt)
+            __s.__do_ = __state::__split;
+        else if (__do_repeat)
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->first();
+            __init_repeat(__s);
+        }
+        else
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__node_ = this->second();
+        }
+    }
+}
+
+template <class _CharT>
+void
+__loop<_CharT>::__exec_split(bool __second, __state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    if (__greedy_ != __second)
+    {
+        __s.__node_ = this->first();
+        __init_repeat(__s);
+    }
+    else
+        __s.__node_ = this->second();
+}
+
+// __alternate
+
+template <class _CharT>
+class __alternate
+    : public __owns_two_states<_CharT>
+{
+    typedef __owns_two_states<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __alternate(__owns_one_state<_CharT>* __s1,
+                         __owns_one_state<_CharT>* __s2)
+        : base(__s1, __s2) {}
+
+    virtual void __exec(__state& __s) const;
+    virtual void __exec_split(bool __second, __state& __s) const;
+};
+
+template <class _CharT>
+void
+__alternate<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__split;
+}
+
+template <class _CharT>
+void
+__alternate<_CharT>::__exec_split(bool __second, __state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    if (__second)
+        __s.__node_ = this->second();
+    else
+        __s.__node_ = this->first();
+}
+
+// __begin_marked_subexpression
+
+template <class _CharT>
+class __begin_marked_subexpression
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    unsigned __mexp_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
+        : base(__s), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__begin_marked_subexpression<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__sub_matches_[__mexp_-1].first = __s.__current_;
+    __s.__node_ = this->first();
+}
+
+// __end_marked_subexpression
+
+template <class _CharT>
+class __end_marked_subexpression
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    unsigned __mexp_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s)
+        : base(__s), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__end_marked_subexpression<_CharT>::__exec(__state& __s) const
+{
+    __s.__do_ = __state::__accept_but_not_consume;
+    __s.__sub_matches_[__mexp_-1].second = __s.__current_;
+    __s.__sub_matches_[__mexp_-1].matched = true;
+    __s.__node_ = this->first();
+}
+
+// __back_ref
+
+template <class _CharT>
+class __back_ref
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    unsigned __mexp_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __back_ref(unsigned __mexp, __node<_CharT>* __s)
+        : base(__s), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__back_ref<_CharT>::__exec(__state& __s) const
+{
+    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
+    if (__sm.matched)
+    {
+        ptrdiff_t __len = __sm.second - __sm.first;
+        if (__s.__last_ - __s.__current_ >= __len &&
+            _VSTD::equal(__sm.first, __sm.second, __s.__current_))
+        {
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__current_ += __len;
+            __s.__node_ = this->first();
+        }
+        else
+        {
+            __s.__do_ = __state::__reject;
+            __s.__node_ = nullptr;
+        }
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __back_ref_icase
+
+template <class _CharT, class _Traits>
+class __back_ref_icase
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _Traits __traits_;
+    unsigned __mexp_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp,
+                              __node<_CharT>* __s)
+        : base(__s), __traits_(__traits), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const
+{
+    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
+    if (__sm.matched)
+    {
+        ptrdiff_t __len = __sm.second - __sm.first;
+        if (__s.__last_ - __s.__current_ >= __len)
+        {
+            for (ptrdiff_t __i = 0; __i < __len; ++__i)
+            {
+                if (__traits_.translate_nocase(__sm.first[__i]) !=
+                                __traits_.translate_nocase(__s.__current_[__i]))
+                    goto __not_equal;
+            }
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__current_ += __len;
+            __s.__node_ = this->first();
+        }
+        else
+        {
+            __s.__do_ = __state::__reject;
+            __s.__node_ = nullptr;
+        }
+    }
+    else
+    {
+__not_equal:
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __back_ref_collate
+
+template <class _CharT, class _Traits>
+class __back_ref_collate
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _Traits __traits_;
+    unsigned __mexp_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp,
+                              __node<_CharT>* __s)
+        : base(__s), __traits_(__traits), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const
+{
+    sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
+    if (__sm.matched)
+    {
+        ptrdiff_t __len = __sm.second - __sm.first;
+        if (__s.__last_ - __s.__current_ >= __len)
+        {
+            for (ptrdiff_t __i = 0; __i < __len; ++__i)
+            {
+                if (__traits_.translate(__sm.first[__i]) !=
+                                       __traits_.translate(__s.__current_[__i]))
+                    goto __not_equal;
+            }
+            __s.__do_ = __state::__accept_but_not_consume;
+            __s.__current_ += __len;
+            __s.__node_ = this->first();
+        }
+        else
+        {
+            __s.__do_ = __state::__reject;
+            __s.__node_ = nullptr;
+        }
+    }
+    else
+    {
+__not_equal:
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __word_boundary
+
+template <class _CharT, class _Traits>
+class __word_boundary
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _Traits __traits_;
+    bool __invert_;
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __word_boundary(const _Traits& __traits, bool __invert,
+                             __node<_CharT>* __s)
+        : base(__s), __traits_(__traits), __invert_(__invert) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__word_boundary<_CharT, _Traits>::__exec(__state& __s) const
+{
+    bool __is_word_b = false;
+    if (__s.__first_ != __s.__last_)
+    {
+        if (__s.__current_ == __s.__last_)
+        {
+            if (!(__s.__flags_ & regex_constants::match_not_eow))
+            {
+                _CharT __c = __s.__current_[-1];
+                __is_word_b = __c == '_' ||
+                              __traits_.isctype(__c, ctype_base::alnum);
+            }
+        }
+        else if (__s.__current_ == __s.__first_ &&
+                !(__s.__flags_ & regex_constants::match_prev_avail))
+        {
+            if (!(__s.__flags_ & regex_constants::match_not_bow))
+            {
+                _CharT __c = *__s.__current_;
+                __is_word_b = __c == '_' ||
+                              __traits_.isctype(__c, ctype_base::alnum);
+            }
+        }
+        else
+        {
+            _CharT __c1 = __s.__current_[-1];
+            _CharT __c2 = *__s.__current_;
+            bool __is_c1_b = __c1 == '_' ||
+                             __traits_.isctype(__c1, ctype_base::alnum);
+            bool __is_c2_b = __c2 == '_' ||
+                             __traits_.isctype(__c2, ctype_base::alnum);
+            __is_word_b = __is_c1_b != __is_c2_b;
+        }
+    }
+    if (__is_word_b != __invert_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __l_anchor
+
+template <class _CharT>
+class __l_anchor
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __l_anchor(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__l_anchor<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__at_first_ && __s.__current_ == __s.__first_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __r_anchor
+
+template <class _CharT>
+class __r_anchor
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __r_anchor(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__r_anchor<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__current_ == __s.__last_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __match_any
+
+template <class _CharT>
+class __match_any
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __match_any(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__match_any<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__current_ != __s.__last_ && *__s.__current_ != 0)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __match_any_but_newline
+
+template <class _CharT>
+class __match_any_but_newline
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __match_any_but_newline(__node<_CharT>* __s)
+        : base(__s) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const;
+template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const;
+
+// __match_char
+
+template <class _CharT>
+class __match_char
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _CharT __c_;
+
+    __match_char(const __match_char&);
+    __match_char& operator=(const __match_char&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __match_char(_CharT __c, __node<_CharT>* __s)
+        : base(__s), __c_(__c) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT>
+void
+__match_char<_CharT>::__exec(__state& __s) const
+{
+    if (__s.__current_ != __s.__last_ && *__s.__current_ == __c_)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __match_char_icase
+
+template <class _CharT, class _Traits>
+class __match_char_icase
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _Traits __traits_;
+    _CharT __c_;
+
+    __match_char_icase(const __match_char_icase&);
+    __match_char_icase& operator=(const __match_char_icase&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
+        : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__match_char_icase<_CharT, _Traits>::__exec(__state& __s) const
+{
+    if (__s.__current_ != __s.__last_ &&
+        __traits_.translate_nocase(*__s.__current_) == __c_)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __match_char_collate
+
+template <class _CharT, class _Traits>
+class __match_char_collate
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    _Traits __traits_;
+    _CharT __c_;
+
+    __match_char_collate(const __match_char_collate&);
+    __match_char_collate& operator=(const __match_char_collate&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
+        : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__match_char_collate<_CharT, _Traits>::__exec(__state& __s) const
+{
+    if (__s.__current_ != __s.__last_ &&
+        __traits_.translate(*__s.__current_) == __c_)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        ++__s.__current_;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+// __bracket_expression
+
+template <class _CharT, class _Traits>
+class __bracket_expression
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+    typedef typename _Traits::string_type string_type;
+
+    _Traits __traits_;
+    vector<_CharT> __chars_;
+    vector<_CharT> __neg_chars_;
+    vector<pair<string_type, string_type> > __ranges_;
+    vector<pair<_CharT, _CharT> > __digraphs_;
+    vector<string_type> __equivalences_;
+    ctype_base::mask __mask_;
+    ctype_base::mask __neg_mask_;
+    bool __negate_;
+    bool __icase_;
+    bool __collate_;
+    bool __might_have_digraph_;
+
+    __bracket_expression(const __bracket_expression&);
+    __bracket_expression& operator=(const __bracket_expression&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __bracket_expression(const _Traits& __traits, __node<_CharT>* __s,
+                                 bool __negate, bool __icase, bool __collate)
+        : base(__s), __traits_(__traits), __mask_(), __neg_mask_(),
+          __negate_(__negate), __icase_(__icase), __collate_(__collate),
+          __might_have_digraph_(__traits_.getloc().name() != "C") {}
+
+    virtual void __exec(__state&) const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __negated() const {return __negate_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_char(_CharT __c)
+        {
+            if (__icase_)
+                __chars_.push_back(__traits_.translate_nocase(__c));
+            else if (__collate_)
+                __chars_.push_back(__traits_.translate(__c));
+            else
+                __chars_.push_back(__c);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_neg_char(_CharT __c)
+        {
+            if (__icase_)
+                __neg_chars_.push_back(__traits_.translate_nocase(__c));
+            else if (__collate_)
+                __neg_chars_.push_back(__traits_.translate(__c));
+            else
+                __neg_chars_.push_back(__c);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_range(string_type __b, string_type __e)
+        {
+            if (__collate_)
+            {
+                if (__icase_)
+                {
+                    for (size_t __i = 0; __i < __b.size(); ++__i)
+                        __b[__i] = __traits_.translate_nocase(__b[__i]);
+                    for (size_t __i = 0; __i < __e.size(); ++__i)
+                        __e[__i] = __traits_.translate_nocase(__e[__i]);
+                }
+                else
+                {
+                    for (size_t __i = 0; __i < __b.size(); ++__i)
+                        __b[__i] = __traits_.translate(__b[__i]);
+                    for (size_t __i = 0; __i < __e.size(); ++__i)
+                        __e[__i] = __traits_.translate(__e[__i]);
+                }
+                __ranges_.push_back(make_pair(
+                                  __traits_.transform(__b.begin(), __b.end()),
+                                  __traits_.transform(__e.begin(), __e.end())));
+            }
+            else
+            {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__b.size() != 1 || __e.size() != 1)
+                    throw regex_error(regex_constants::error_collate);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                if (__icase_)
+                {
+                    __b[0] = __traits_.translate_nocase(__b[0]);
+                    __e[0] = __traits_.translate_nocase(__e[0]);
+                }
+                __ranges_.push_back(make_pair(_VSTD::move(__b), _VSTD::move(__e)));
+            }
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_digraph(_CharT __c1, _CharT __c2)
+        {
+            if (__icase_)
+                __digraphs_.push_back(make_pair(__traits_.translate_nocase(__c1),
+                                                __traits_.translate_nocase(__c2)));
+            else if (__collate_)
+                __digraphs_.push_back(make_pair(__traits_.translate(__c1),
+                                                __traits_.translate(__c2)));
+            else
+                __digraphs_.push_back(make_pair(__c1, __c2));
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_equivalence(const string_type& __s)
+        {__equivalences_.push_back(__s);}
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_class(ctype_base::mask __mask)
+        {__mask_ |= __mask;}
+    _LIBCPP_INLINE_VISIBILITY
+    void __add_neg_class(ctype_base::mask __mask)
+        {__neg_mask_ |= __mask;}
+};
+
+template <class _CharT, class _Traits>
+void
+__bracket_expression<_CharT, _Traits>::__exec(__state& __s) const
+{
+    bool __found = false;
+    unsigned __consumed = 0;
+    if (__s.__current_ != __s.__last_)
+    {
+        ++__consumed;
+        if (__might_have_digraph_)
+        {
+            const _CharT* __next = _VSTD::next(__s.__current_);
+            if (__next != __s.__last_)
+            {
+                pair<_CharT, _CharT> __ch2(*__s.__current_, *__next);
+                if (__icase_)
+                {
+                    __ch2.first = __traits_.translate_nocase(__ch2.first);
+                    __ch2.second = __traits_.translate_nocase(__ch2.second);
+                }
+                else if (__collate_)
+                {
+                    __ch2.first = __traits_.translate(__ch2.first);
+                    __ch2.second = __traits_.translate(__ch2.second);
+                }
+                if (!__traits_.lookup_collatename(&__ch2.first, &__ch2.first+2).empty())
+                {
+                    // __ch2 is a digraph in this locale
+                    ++__consumed;
+                    for (size_t __i = 0; __i < __digraphs_.size(); ++__i)
+                    {
+                        if (__ch2 == __digraphs_[__i])
+                        {
+                            __found = true;
+                            goto __exit;
+                        }
+                    }
+                    if (__collate_ && !__ranges_.empty())
+                    {
+                        string_type __s2 = __traits_.transform(&__ch2.first,
+                                                               &__ch2.first + 2);
+                        for (size_t __i = 0; __i < __ranges_.size(); ++__i)
+                        {
+                            if (__ranges_[__i].first <= __s2 &&
+                                __s2 <= __ranges_[__i].second)
+                            {
+                                __found = true;
+                                goto __exit;
+                            }
+                        }
+                    }
+                    if (!__equivalences_.empty())
+                    {
+                        string_type __s2 = __traits_.transform_primary(&__ch2.first,
+                                                                       &__ch2.first + 2);
+                        for (size_t __i = 0; __i < __equivalences_.size(); ++__i)
+                        {
+                            if (__s2 == __equivalences_[__i])
+                            {
+                                __found = true;
+                                goto __exit;
+                            }
+                        }
+                    }
+                    if (__traits_.isctype(__ch2.first, __mask_) &&
+                        __traits_.isctype(__ch2.second, __mask_))
+                    {
+                        __found = true;
+                        goto __exit;
+                    }
+                    if (!__traits_.isctype(__ch2.first, __neg_mask_) &&
+                        !__traits_.isctype(__ch2.second, __neg_mask_))
+                    {
+                        __found = true;
+                        goto __exit;
+                    }
+                    goto __exit;
+                }
+            }
+        }
+        // test *__s.__current_ as not a digraph
+        _CharT __ch = *__s.__current_;
+        if (__icase_)
+            __ch = __traits_.translate_nocase(__ch);
+        else if (__collate_)
+            __ch = __traits_.translate(__ch);
+        for (size_t __i = 0; __i < __chars_.size(); ++__i)
+        {
+            if (__ch == __chars_[__i])
+            {
+                __found = true;
+                goto __exit;
+            }
+        }
+        if (!__neg_chars_.empty())
+        {
+            for (size_t __i = 0; __i < __neg_chars_.size(); ++__i)
+            {
+                if (__ch == __neg_chars_[__i])
+                    goto __is_neg_char;
+            }
+            __found = true;
+            goto __exit;
+        }
+__is_neg_char:
+        if (!__ranges_.empty())
+        {
+            string_type __s2 = __collate_ ?
+                                   __traits_.transform(&__ch, &__ch + 1) :
+                                   string_type(1, __ch);
+            for (size_t __i = 0; __i < __ranges_.size(); ++__i)
+            {
+                if (__ranges_[__i].first <= __s2 && __s2 <= __ranges_[__i].second)
+                {
+                    __found = true;
+                    goto __exit;
+                }
+            }
+        }
+        if (!__equivalences_.empty())
+        {
+            string_type __s2 = __traits_.transform_primary(&__ch, &__ch + 1);
+            for (size_t __i = 0; __i < __equivalences_.size(); ++__i)
+            {
+                if (__s2 == __equivalences_[__i])
+                {
+                    __found = true;
+                    goto __exit;
+                }
+            }
+        }
+        if (__traits_.isctype(__ch, __mask_))
+        {
+            __found = true;
+            goto __exit;
+        }
+        if (__neg_mask_ && !__traits_.isctype(__ch, __neg_mask_))
+        {
+            __found = true;
+            goto __exit;
+        }
+    }
+    else
+        __found = __negate_;  // force reject
+__exit:
+    if (__found != __negate_)
+    {
+        __s.__do_ = __state::__accept_and_consume;
+        __s.__current_ += __consumed;
+        __s.__node_ = this->first();
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+template <class _CharT, class _Traits> class __lookahead;
+
+template <class _CharT, class _Traits = regex_traits<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY basic_regex
+{
+public:
+    // types:
+    typedef _CharT                              value_type;
+    typedef regex_constants::syntax_option_type flag_type;
+    typedef typename _Traits::locale_type       locale_type;
+
+private:
+    _Traits   __traits_;
+    flag_type __flags_;
+    unsigned __marked_count_;
+    unsigned __loop_count_;
+    int __open_count_;
+    shared_ptr<__empty_state<_CharT> > __start_;
+    __owns_one_state<_CharT>* __end_;
+
+    typedef _VSTD::__state<_CharT> __state;
+    typedef _VSTD::__node<_CharT> __node;
+
+public:
+    // constants:
+    static const regex_constants::syntax_option_type icase = regex_constants::icase;
+    static const regex_constants::syntax_option_type nosubs = regex_constants::nosubs;
+    static const regex_constants::syntax_option_type optimize = regex_constants::optimize;
+    static const regex_constants::syntax_option_type collate = regex_constants::collate;
+    static const regex_constants::syntax_option_type ECMAScript = regex_constants::ECMAScript;
+    static const regex_constants::syntax_option_type basic = regex_constants::basic;
+    static const regex_constants::syntax_option_type extended = regex_constants::extended;
+    static const regex_constants::syntax_option_type awk = regex_constants::awk;
+    static const regex_constants::syntax_option_type grep = regex_constants::grep;
+    static const regex_constants::syntax_option_type egrep = regex_constants::egrep;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex()
+        : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {__parse(__p, __p + __traits_.length(__p));}
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex(const value_type* __p, size_t __len, flag_type __f)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {__parse(__p, __p + __len);}
+//     basic_regex(const basic_regex&) = default;
+//     basic_regex(basic_regex&&) = default;
+    template <class _ST, class _SA>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit basic_regex(const basic_string<value_type, _ST, _SA>& __p,
+                             flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {__parse(__p.begin(), __p.end());}
+    template <class _ForwardIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_regex(_ForwardIterator __first, _ForwardIterator __last,
+                    flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {__parse(__first, __last);}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex(initializer_list<value_type> __il,
+                flag_type __f = regex_constants::ECMAScript)
+        : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
+          __end_(0)
+        {__parse(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+//    ~basic_regex() = default;
+
+//     basic_regex& operator=(const basic_regex&) = default;
+//     basic_regex& operator=(basic_regex&&) = default;
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& operator=(const value_type* __p)
+        {return assign(__p);}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& operator=(initializer_list<value_type> __il)
+        {return assign(__il);}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template <class _ST, class _SA>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_regex& operator=(const basic_string<value_type, _ST, _SA>& __p)
+        {return assign(__p);}
+
+    // assign:
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& assign(const basic_regex& __that)
+        {return *this = __that;}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& assign(basic_regex&& __that) _NOEXCEPT
+        {return *this = _VSTD::move(__that);}
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
+        {return assign(__p, __p + __traits_.length(__p), __f);}
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& assign(const value_type* __p, size_t __len, flag_type __f)
+        {return assign(__p, __p + __len, __f);}
+    template <class _ST, class _SA>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_regex& assign(const basic_string<value_type, _ST, _SA>& __s,
+                            flag_type __f = regex_constants::ECMAScript)
+            {return assign(__s.begin(), __s.end(), __f);}
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value,
+            basic_regex&
+        >::type
+        assign(_InputIterator __first, _InputIterator __last,
+                            flag_type __f = regex_constants::ECMAScript)
+        {
+            basic_string<_CharT> __t(__first, __last);
+            return assign(__t.begin(), __t.end(), __f);
+        }
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __member_init(flag_type __f)
+    {
+        __flags_ = __f;
+        __marked_count_ = 0;
+        __loop_count_ = 0;
+        __open_count_ = 0;
+        __end_ = nullptr;
+    }
+public:
+
+    template <class _ForwardIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            basic_regex&
+        >::type
+        assign(_ForwardIterator __first, _ForwardIterator __last,
+                            flag_type __f = regex_constants::ECMAScript)
+        {
+            __member_init(__f);
+            __parse(__first, __last);
+            return *this;
+        }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    basic_regex& assign(initializer_list<value_type> __il,
+                        flag_type __f = regex_constants::ECMAScript)
+        {return assign(__il.begin(), __il.end(), __f);}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    // const operations:
+    _LIBCPP_INLINE_VISIBILITY
+    unsigned mark_count() const {return __marked_count_;}
+    _LIBCPP_INLINE_VISIBILITY
+    flag_type flags() const {return __flags_;}
+
+    // locale:
+    _LIBCPP_INLINE_VISIBILITY
+    locale_type imbue(locale_type __loc)
+    {
+        __member_init(ECMAScript);
+        __start_.reset();
+        return __traits_.imbue(__loc);
+    }
+    _LIBCPP_INLINE_VISIBILITY
+    locale_type getloc() const {return __traits_.getloc();}
+
+    // swap:
+    void swap(basic_regex& __r);
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    unsigned __loop_count() const {return __loop_count_;}
+
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_basic_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_RE_expression(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_simple_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_nondupl_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_one_char_or_coll_elem_RE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_open_paren(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_close_paren(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_open_brace(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_Back_close_brace(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_BACKREF(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ORD_CHAR(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_QUOTED_CHAR(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_RE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,
+                               __owns_one_state<_CharT>* __s,
+                               unsigned __mexp_begin, unsigned __mexp_end);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ERE_dupl_symbol(_ForwardIterator __first, _ForwardIterator __last,
+                                __owns_one_state<_CharT>* __s,
+                                unsigned __mexp_begin, unsigned __mexp_end);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_bracket_expression(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_follow_list(_ForwardIterator __first, _ForwardIterator __last,
+                            __bracket_expression<_CharT, _Traits>* __ml);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_expression_term(_ForwardIterator __first, _ForwardIterator __last,
+                                __bracket_expression<_CharT, _Traits>* __ml);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_equivalence_class(_ForwardIterator __first, _ForwardIterator __last,
+                                  __bracket_expression<_CharT, _Traits>* __ml);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_character_class(_ForwardIterator __first, _ForwardIterator __last,
+                                __bracket_expression<_CharT, _Traits>* __ml);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_collating_symbol(_ForwardIterator __first, _ForwardIterator __last,
+                                 basic_string<_CharT>& __col_sym);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_DUP_COUNT(_ForwardIterator __first, _ForwardIterator __last, int& __c);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_extended_reg_exp(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ERE_branch(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ERE_expression(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_one_char_or_coll_elem_ERE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ORD_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_QUOTED_CHAR_ERE(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_ecma_exp(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_alternative(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_term(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_assertion(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_atom(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_atom_escape(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_decimal_escape(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_character_class_escape(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_character_escape(_ForwardIterator __first, _ForwardIterator __last,
+                                 basic_string<_CharT>* __str = nullptr);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_pattern_character(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_grep(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_egrep(_ForwardIterator __first, _ForwardIterator __last);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_class_escape(_ForwardIterator __first, _ForwardIterator __last,
+                          basic_string<_CharT>& __str,
+                          __bracket_expression<_CharT, _Traits>* __ml);
+    template <class _ForwardIterator>
+        _ForwardIterator
+        __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,
+                          basic_string<_CharT>* __str = nullptr);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __push_l_anchor();
+    void __push_r_anchor();
+    void __push_match_any();
+    void __push_match_any_but_newline();
+    _LIBCPP_INLINE_VISIBILITY
+    void __push_greedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s,
+                                  unsigned __mexp_begin = 0, unsigned __mexp_end = 0)
+        {__push_loop(__min, numeric_limits<size_t>::max(), __s,
+                     __mexp_begin, __mexp_end);}
+    _LIBCPP_INLINE_VISIBILITY
+    void __push_nongreedy_inf_repeat(size_t __min, __owns_one_state<_CharT>* __s,
+                                  unsigned __mexp_begin = 0, unsigned __mexp_end = 0)
+        {__push_loop(__min, numeric_limits<size_t>::max(), __s,
+                     __mexp_begin, __mexp_end, false);}
+    void __push_loop(size_t __min, size_t __max, __owns_one_state<_CharT>* __s,
+                     size_t __mexp_begin = 0, size_t __mexp_end = 0,
+                     bool __greedy = true);
+    __bracket_expression<_CharT, _Traits>* __start_matching_list(bool __negate);
+    void __push_char(value_type __c);
+    void __push_back_ref(int __i);
+    void __push_alternation(__owns_one_state<_CharT>* __sa,
+                            __owns_one_state<_CharT>* __sb);
+    void __push_begin_marked_subexpression();
+    void __push_end_marked_subexpression(unsigned);
+    void __push_empty();
+    void __push_word_boundary(bool);
+    void __push_lookahead(const basic_regex&, bool, unsigned);
+
+    template <class _Allocator>
+        bool
+        __search(const _CharT* __first, const _CharT* __last,
+                 match_results<const _CharT*, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags) const;
+
+    template <class _Allocator>
+        bool
+        __match_at_start(const _CharT* __first, const _CharT* __last,
+                 match_results<const _CharT*, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags, bool) const;
+    template <class _Allocator>
+        bool
+        __match_at_start_ecma(const _CharT* __first, const _CharT* __last,
+                 match_results<const _CharT*, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags, bool) const;
+    template <class _Allocator>
+        bool
+        __match_at_start_posix_nosubs(const _CharT* __first, const _CharT* __last,
+                 match_results<const _CharT*, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags, bool) const;
+    template <class _Allocator>
+        bool
+        __match_at_start_posix_subs(const _CharT* __first, const _CharT* __last,
+                 match_results<const _CharT*, _Allocator>& __m,
+                 regex_constants::match_flag_type __flags, bool) const;
+
+    template <class _Bp, class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&,
+                 regex_constants::match_flag_type);
+
+    template <class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(const _Cp*, const _Cp*, match_results<const _Cp*, _Ap>&,
+                 const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
+
+    template <class _Bp, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(_Bp, _Bp, const basic_regex<_Cp, _Tp>&,
+                 regex_constants::match_flag_type);
+
+    template <class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(const _Cp*, const _Cp*,
+                 const basic_regex<_Cp, _Tp>&, regex_constants::match_flag_type);
+
+    template <class _Cp, class _Ap, class _Tp>
+    friend
+    bool
+    regex_search(const _Cp*, match_results<const _Cp*, _Ap>&, const basic_regex<_Cp, _Tp>&,
+                 regex_constants::match_flag_type);
+
+    template <class _ST, class _SA, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(const basic_string<_Cp, _ST, _SA>& __s,
+                 const basic_regex<_Cp, _Tp>& __e,
+                 regex_constants::match_flag_type __flags);
+
+    template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(const basic_string<_Cp, _ST, _SA>& __s,
+                 match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
+                 const basic_regex<_Cp, _Tp>& __e,
+                 regex_constants::match_flag_type __flags);
+
+    template <class _Iter, class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_search(__wrap_iter<_Iter> __first,
+                 __wrap_iter<_Iter> __last,
+                 match_results<__wrap_iter<_Iter>, _Ap>& __m,
+                 const basic_regex<_Cp, _Tp>& __e,
+                 regex_constants::match_flag_type __flags);
+
+    template <class, class> friend class __lookahead;
+};
+
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep;
+template <class _CharT, class _Traits>
+    const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep;
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::swap(basic_regex& __r)
+{
+    using _VSTD::swap;
+    swap(__traits_, __r.__traits_);
+    swap(__flags_, __r.__flags_);
+    swap(__marked_count_, __r.__marked_count_);
+    swap(__loop_count_, __r.__loop_count_);
+    swap(__open_count_, __r.__open_count_);
+    swap(__start_, __r.__start_);
+    swap(__end_, __r.__end_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_regex<_CharT, _Traits>& __x, basic_regex<_CharT, _Traits>& __y)
+{
+    return __x.swap(__y);
+}
+
+// __lookahead
+
+template <class _CharT, class _Traits>
+class __lookahead
+    : public __owns_one_state<_CharT>
+{
+    typedef __owns_one_state<_CharT> base;
+
+    basic_regex<_CharT, _Traits> __exp_;
+    unsigned __mexp_;
+    bool __invert_;
+
+    __lookahead(const __lookahead&);
+    __lookahead& operator=(const __lookahead&);
+public:
+    typedef _VSTD::__state<_CharT> __state;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
+        : base(__s), __exp_(__exp), __invert_(__invert), __mexp_(__mexp) {}
+
+    virtual void __exec(__state&) const;
+};
+
+template <class _CharT, class _Traits>
+void
+__lookahead<_CharT, _Traits>::__exec(__state& __s) const
+{
+    match_results<const _CharT*> __m;
+    __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
+    bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,
+                                                  __m,
+                                                  __s.__flags_ | regex_constants::match_continuous,
+                                                  __s.__at_first_ && __s.__current_ == __s.__first_);
+    if (__matched != __invert_)
+    {
+        __s.__do_ = __state::__accept_but_not_consume;
+        __s.__node_ = this->first();
+        for (unsigned __i = 1; __i < __m.size(); ++__i) {
+            __s.__sub_matches_[__mexp_ + __i - 1] = __m.__matches_[__i];
+        }
+    }
+    else
+    {
+        __s.__do_ = __state::__reject;
+        __s.__node_ = nullptr;
+    }
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse(_ForwardIterator __first,
+                                      _ForwardIterator __last)
+{
+    {
+        unique_ptr<__node> __h(new __end_state<_CharT>);
+        __start_.reset(new __empty_state<_CharT>(__h.get()));
+        __h.release();
+        __end_ = __start_.get();
+    }
+    switch (__flags_ & 0x1F0)
+    {
+    case ECMAScript:
+        __first = __parse_ecma_exp(__first, __last);
+        break;
+    case basic:
+        __first = __parse_basic_reg_exp(__first, __last);
+        break;
+    case extended:
+    case awk:
+        __first = __parse_extended_reg_exp(__first, __last);
+        break;
+    case grep:
+        __first = __parse_grep(__first, __last);
+        break;
+    case egrep:
+        __first = __parse_egrep(__first, __last);
+        break;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    default:
+        throw regex_error(regex_constants::__re_err_grammar);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_basic_reg_exp(_ForwardIterator __first,
+                                                    _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        if (*__first == '^')
+        {
+            __push_l_anchor();
+            ++__first;
+        }
+        if (__first != __last)
+        {
+            __first = __parse_RE_expression(__first, __last);
+            if (__first != __last)
+            {
+                _ForwardIterator __temp = _VSTD::next(__first);
+                if (__temp == __last && *__first == '$')
+                {
+                    __push_r_anchor();
+                    ++__first;
+                }
+            }
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__first != __last)
+            throw regex_error(regex_constants::__re_err_empty);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_extended_reg_exp(_ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    __owns_one_state<_CharT>* __sa = __end_;
+    _ForwardIterator __temp = __parse_ERE_branch(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__temp == __first)
+        throw regex_error(regex_constants::__re_err_empty);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    __first = __temp;
+    while (__first != __last && *__first == '|')
+    {
+        __owns_one_state<_CharT>* __sb = __end_;
+        __temp = __parse_ERE_branch(++__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__temp == __first)
+            throw regex_error(regex_constants::__re_err_empty);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        __push_alternation(__sa, __sb);
+        __first = __temp;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ERE_branch(_ForwardIterator __first,
+                                                 _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __parse_ERE_expression(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__temp == __first)
+        throw regex_error(regex_constants::__re_err_empty);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    do
+    {
+        __first = __temp;
+        __temp = __parse_ERE_expression(__first, __last);
+    } while (__temp != __first);
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ERE_expression(_ForwardIterator __first,
+                                                     _ForwardIterator __last)
+{
+    __owns_one_state<_CharT>* __e = __end_;
+    unsigned __mexp_begin = __marked_count_;
+    _ForwardIterator __temp = __parse_one_char_or_coll_elem_ERE(__first, __last);
+    if (__temp == __first && __temp != __last)
+    {
+        switch (*__temp)
+        {
+        case '^':
+            __push_l_anchor();
+            ++__temp;
+            break;
+        case '$':
+            __push_r_anchor();
+            ++__temp;
+            break;
+        case '(':
+            __push_begin_marked_subexpression();
+            unsigned __temp_count = __marked_count_;
+            ++__open_count_;
+            __temp = __parse_extended_reg_exp(++__temp, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__temp == __last || *__temp != ')')
+                throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __push_end_marked_subexpression(__temp_count);
+            --__open_count_;
+            ++__temp;
+            break;
+        }
+    }
+    if (__temp != __first)
+        __temp = __parse_ERE_dupl_symbol(__temp, __last, __e, __mexp_begin+1,
+                                         __marked_count_+1);
+    __first = __temp;
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_RE_expression(_ForwardIterator __first,
+                                                    _ForwardIterator __last)
+{
+    while (true)
+    {
+        _ForwardIterator __temp = __parse_simple_RE(__first, __last);
+        if (__temp == __first)
+            break;
+        __first = __temp;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_simple_RE(_ForwardIterator __first,
+                                                _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        __owns_one_state<_CharT>* __e = __end_;
+        unsigned __mexp_begin = __marked_count_;
+        _ForwardIterator __temp = __parse_nondupl_RE(__first, __last);
+        if (__temp != __first)
+            __first = __parse_RE_dupl_symbol(__temp, __last, __e,
+                                             __mexp_begin+1, __marked_count_+1);
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_nondupl_RE(_ForwardIterator __first,
+                                                 _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __first;
+    __first = __parse_one_char_or_coll_elem_RE(__first, __last);
+    if (__temp == __first)
+    {
+        __temp = __parse_Back_open_paren(__first, __last);
+        if (__temp != __first)
+        {
+            __push_begin_marked_subexpression();
+            unsigned __temp_count = __marked_count_;
+            __first = __parse_RE_expression(__temp, __last);
+            __temp = __parse_Back_close_paren(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__temp == __first)
+                throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __push_end_marked_subexpression(__temp_count);
+            __first = __temp;
+        }
+        else
+            __first = __parse_BACKREF(__first, __last);
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_RE(
+                                                       _ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __parse_ORD_CHAR(__first, __last);
+    if (__temp == __first)
+    {
+        __temp = __parse_QUOTED_CHAR(__first, __last);
+        if (__temp == __first)
+        {
+            if (__temp != __last && *__temp == '.')
+            {
+                __push_match_any();
+                ++__temp;
+            }
+            else
+                __temp = __parse_bracket_expression(__first, __last);
+        }
+    }
+    __first = __temp;
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_one_char_or_coll_elem_ERE(
+                                                       _ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __parse_ORD_CHAR_ERE(__first, __last);
+    if (__temp == __first)
+    {
+        __temp = __parse_QUOTED_CHAR_ERE(__first, __last);
+        if (__temp == __first)
+        {
+            if (__temp != __last && *__temp == '.')
+            {
+                __push_match_any();
+                ++__temp;
+            }
+            else
+                __temp = __parse_bracket_expression(__first, __last);
+        }
+    }
+    __first = __temp;
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_open_paren(_ForwardIterator __first,
+                                                      _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '(')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_close_paren(_ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == ')')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_open_brace(_ForwardIterator __first,
+                                                      _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '{')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_Back_close_brace(_ForwardIterator __first,
+                                                       _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\' && *__temp == '}')
+                __first = ++__temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
+                                              _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\')
+            { 
+                int __val = __traits_.value(*__temp, 10);
+                if (__val >= 1 && __val <= 9)
+                {
+                    __push_back_ref(__val);
+                    __first = ++__temp;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ORD_CHAR(_ForwardIterator __first,
+                                               _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp == __last && *__first == '$')
+            return __first;
+        // Not called inside a bracket
+        if (*__first == '.' || *__first == '\\' || *__first == '[')
+            return __first;
+        __push_char(*__first);
+        ++__first;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ORD_CHAR_ERE(_ForwardIterator __first,
+                                                   _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        switch (*__first)
+        {
+        case '^':
+        case '.':
+        case '[':
+        case '$':
+        case '(':
+        case '|':
+        case '*':
+        case '+':
+        case '?':
+        case '{':
+        case '\\':
+            break;
+        case ')':
+            if (__open_count_ == 0)
+            {
+                __push_char(*__first);
+                ++__first;
+            }
+            break;
+        default:
+            __push_char(*__first);
+            ++__first;
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR(_ForwardIterator __first,
+                                                  _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\')
+            {
+                switch (*__temp)
+                {
+                case '^':
+                case '.':
+                case '*':
+                case '[':
+                case '$':
+                case '\\':
+                    __push_char(*__temp);
+                    __first = ++__temp;
+                    break;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
+                                                      _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        if (__temp != __last)
+        {
+            if (*__first == '\\')
+            {
+                switch (*__temp)
+                {
+                case '^':
+                case '.':
+                case '*':
+                case '[':
+                case '$':
+                case '\\':
+                case '(':
+                case ')':
+                case '|':
+                case '+':
+                case '?':
+                case '{':
+                case '}':
+                    __push_char(*__temp);
+                    __first = ++__temp;
+                    break;
+                default:
+                    if ((__flags_ & 0x1F0) == awk)
+                        __first = __parse_awk_escape(++__first, __last);
+                    break;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_RE_dupl_symbol(_ForwardIterator __first,
+                                                     _ForwardIterator __last,
+                                                     __owns_one_state<_CharT>* __s,
+                                                     unsigned __mexp_begin,
+                                                     unsigned __mexp_end)
+{
+    if (__first != __last)
+    {
+        if (*__first == '*')
+        {
+            __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
+            ++__first;
+        }
+        else
+        {
+            _ForwardIterator __temp = __parse_Back_open_brace(__first, __last);
+            if (__temp != __first)
+            {
+                int __min = 0;
+                __first = __temp;
+                __temp = __parse_DUP_COUNT(__first, __last, __min);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__temp == __first)
+                    throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                __first = __temp;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__first == __last)
+                    throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                if (*__first != ',')
+                {
+                    __temp = __parse_Back_close_brace(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (__temp == __first)
+                        throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    __push_loop(__min, __min, __s, __mexp_begin, __mexp_end,
+                                    true);
+                    __first = __temp;
+                }
+                else
+                {
+                    ++__first;  // consume ','
+                    int __max = -1;
+                    __first = __parse_DUP_COUNT(__first, __last, __max);
+                    __temp = __parse_Back_close_brace(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (__temp == __first)
+                        throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    if (__max == -1)
+                        __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
+                    else
+                    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                        if (__max < __min)
+                            throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                        __push_loop(__min, __max, __s, __mexp_begin, __mexp_end,
+                                    true);
+                    }
+                    __first = __temp;
+                }
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ERE_dupl_symbol(_ForwardIterator __first,
+                                                      _ForwardIterator __last,
+                                                      __owns_one_state<_CharT>* __s,
+                                                      unsigned __mexp_begin,
+                                                      unsigned __mexp_end)
+{
+    if (__first != __last)
+    {
+        unsigned __grammar = __flags_ & 0x1F0;
+        switch (*__first)
+        {
+        case '*':
+            ++__first;
+            if (__grammar == ECMAScript && __first != __last && *__first == '?')
+            {
+                ++__first;
+                __push_nongreedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
+            }
+            else
+                __push_greedy_inf_repeat(0, __s, __mexp_begin, __mexp_end);
+            break;
+        case '+':
+            ++__first;
+            if (__grammar == ECMAScript && __first != __last && *__first == '?')
+            {
+                ++__first;
+                __push_nongreedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);
+            }
+            else
+                __push_greedy_inf_repeat(1, __s, __mexp_begin, __mexp_end);
+            break;
+        case '?':
+            ++__first;
+            if (__grammar == ECMAScript && __first != __last && *__first == '?')
+            {
+                ++__first;
+                __push_loop(0, 1, __s, __mexp_begin, __mexp_end, false);
+            }
+            else
+                __push_loop(0, 1, __s, __mexp_begin, __mexp_end);
+            break;
+        case '{':
+            {
+                int __min;
+                _ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__temp == __first)
+                    throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                __first = __temp;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__first == __last)
+                    throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                switch (*__first)
+                {
+                case '}':
+                    ++__first;
+                    if (__grammar == ECMAScript && __first != __last && *__first == '?')
+                    {
+                        ++__first;
+                        __push_loop(__min, __min, __s, __mexp_begin, __mexp_end, false);
+                    }
+                    else
+                        __push_loop(__min, __min, __s, __mexp_begin, __mexp_end);
+                    break;
+                case ',':
+                    ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (__first == __last)
+                        throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    if (*__first == '}')
+                    {
+                        ++__first;
+                        if (__grammar == ECMAScript && __first != __last && *__first == '?')
+                        {
+                            ++__first;
+                            __push_nongreedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
+                        }
+                        else
+                            __push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
+                    }
+                    else
+                    {
+                        int __max = -1;
+                        __temp = __parse_DUP_COUNT(__first, __last, __max);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                        if (__temp == __first)
+                            throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                        __first = __temp;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                        if (__first == __last || *__first != '}')
+                            throw regex_error(regex_constants::error_brace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                        ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                        if (__max < __min)
+                            throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                        if (__grammar == ECMAScript && __first != __last && *__first == '?')
+                        {
+                            ++__first;
+                            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end, false);
+                        }
+                        else
+                            __push_loop(__min, __max, __s, __mexp_begin, __mexp_end);
+                    }
+                    break;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                default:
+                    throw regex_error(regex_constants::error_badbrace);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                }
+            }
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_bracket_expression(_ForwardIterator __first,
+                                                         _ForwardIterator __last)
+{
+    if (__first != __last && *__first == '[')
+    {
+        ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__first == __last)
+            throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        bool __negate = false;
+        if (*__first == '^')
+        {
+            ++__first;
+            __negate = true;
+        }
+        __bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate);
+        // __ml owned by *this
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__first == __last)
+            throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        if ((__flags_ & 0x1F0) != ECMAScript && *__first == ']')
+        {
+            __ml->__add_char(']');
+            ++__first;
+        }
+        __first = __parse_follow_list(__first, __last, __ml);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__first == __last)
+            throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        if (*__first == '-')
+        {
+            __ml->__add_char('-');
+            ++__first;
+        }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        if (__first == __last || *__first != ']')
+            throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        ++__first;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_follow_list(_ForwardIterator __first,
+                                    _ForwardIterator __last,
+                                    __bracket_expression<_CharT, _Traits>* __ml)
+{
+    if (__first != __last)
+    {
+        while (true)
+        {
+            _ForwardIterator __temp = __parse_expression_term(__first, __last,
+                                                              __ml);
+            if (__temp == __first)
+                break;
+            __first = __temp;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_expression_term(_ForwardIterator __first,
+                                    _ForwardIterator __last,
+                                    __bracket_expression<_CharT, _Traits>* __ml)
+{
+    if (__first != __last && *__first != ']')
+    {
+        _ForwardIterator __temp = _VSTD::next(__first);
+        basic_string<_CharT> __start_range;
+        if (__temp != __last && *__first == '[')
+        {
+            if (*__temp == '=')
+                return __parse_equivalence_class(++__temp, __last, __ml);
+            else if (*__temp == ':')
+                return __parse_character_class(++__temp, __last, __ml);
+            else if (*__temp == '.')
+                __first = __parse_collating_symbol(++__temp, __last, __start_range);
+        }
+        unsigned __grammar = __flags_ & 0x1F0;
+        if (__start_range.empty())
+        {
+            if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\')
+            {
+                if (__grammar == ECMAScript)
+                    __first = __parse_class_escape(++__first, __last, __start_range, __ml);
+                else
+                    __first = __parse_awk_escape(++__first, __last, &__start_range);
+            }
+            else
+            {
+                __start_range = *__first;
+                ++__first;
+            }
+        }
+        if (__first != __last && *__first != ']')
+        {
+            __temp = _VSTD::next(__first);
+            if (__temp != __last && *__first == '-' && *__temp != ']')
+            {
+                // parse a range
+                basic_string<_CharT> __end_range;
+                __first = __temp;
+                ++__temp;
+                if (__temp != __last && *__first == '[' && *__temp == '.')
+                    __first = __parse_collating_symbol(++__temp, __last, __end_range);
+                else
+                {
+                    if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\')
+                    {
+                        if (__grammar == ECMAScript)
+                            __first = __parse_class_escape(++__first, __last,
+                                                           __end_range, __ml);
+                        else
+                            __first = __parse_awk_escape(++__first, __last,
+                                                         &__end_range);
+                    }
+                    else
+                    {
+                        __end_range = *__first;
+                        ++__first;
+                    }
+                }
+                __ml->__add_range(_VSTD::move(__start_range), _VSTD::move(__end_range));
+            }
+            else if (!__start_range.empty())
+            {
+                if (__start_range.size() == 1)
+                    __ml->__add_char(__start_range[0]);
+                else
+                    __ml->__add_digraph(__start_range[0], __start_range[1]);
+            }
+        }
+        else if (!__start_range.empty())
+        {
+            if (__start_range.size() == 1)
+                __ml->__add_char(__start_range[0]);
+            else
+                __ml->__add_digraph(__start_range[0], __start_range[1]);
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_class_escape(_ForwardIterator __first,
+                          _ForwardIterator __last,
+                          basic_string<_CharT>& __str,
+                          __bracket_expression<_CharT, _Traits>* __ml)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__first == __last)
+        throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    switch (*__first)
+    {
+    case 0:
+        __str = *__first;
+        return ++__first;
+    case 'b':
+        __str = _CharT(8);
+        return ++__first;
+    case 'd':
+        __ml->__add_class(ctype_base::digit);
+        return ++__first;
+    case 'D':
+        __ml->__add_neg_class(ctype_base::digit);
+        return ++__first;
+    case 's':
+        __ml->__add_class(ctype_base::space);
+        return ++__first;
+    case 'S':
+        __ml->__add_neg_class(ctype_base::space);
+        return ++__first;
+    case 'w':
+        __ml->__add_class(ctype_base::alnum);
+        __ml->__add_char('_');
+        return ++__first;
+    case 'W':
+        __ml->__add_neg_class(ctype_base::alnum);
+        __ml->__add_neg_char('_');
+        return ++__first;
+    }
+    __first = __parse_character_escape(__first, __last, &__str);
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_awk_escape(_ForwardIterator __first,
+                          _ForwardIterator __last,
+                          basic_string<_CharT>* __str)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__first == __last)
+        throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    switch (*__first)
+    {
+    case '\\':
+    case '"':
+    case '/':
+        if (__str)
+            *__str = *__first;
+        else
+            __push_char(*__first);
+        return ++__first;
+    case 'a':
+        if (__str)
+            *__str = _CharT(7);
+        else
+            __push_char(_CharT(7));
+        return ++__first;
+    case 'b':
+        if (__str)
+            *__str = _CharT(8);
+        else
+            __push_char(_CharT(8));
+        return ++__first;
+    case 'f':
+        if (__str)
+            *__str = _CharT(0xC);
+        else
+            __push_char(_CharT(0xC));
+        return ++__first;
+    case 'n':
+        if (__str)
+            *__str = _CharT(0xA);
+        else
+            __push_char(_CharT(0xA));
+        return ++__first;
+    case 'r':
+        if (__str)
+            *__str = _CharT(0xD);
+        else
+            __push_char(_CharT(0xD));
+        return ++__first;
+    case 't':
+        if (__str)
+            *__str = _CharT(0x9);
+        else
+            __push_char(_CharT(0x9));
+        return ++__first;
+    case 'v':
+        if (__str)
+            *__str = _CharT(0xB);
+        else
+            __push_char(_CharT(0xB));
+        return ++__first;
+    }
+    if ('0' <= *__first && *__first <= '7')
+    {
+        unsigned __val = *__first - '0';
+        if (++__first != __last && ('0' <= *__first && *__first <= '7'))
+        {
+            __val = 8 * __val + *__first - '0';
+            if (++__first != __last && ('0' <= *__first && *__first <= '7'))
+                __val = 8 * __val + *__first++ - '0';
+        }
+        if (__str)
+            *__str = _CharT(__val);
+        else
+            __push_char(_CharT(__val));
+    }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    else
+        throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first,
+                                    _ForwardIterator __last,
+                                    __bracket_expression<_CharT, _Traits>* __ml)
+{
+    // Found [=
+    //   This means =] must exist
+    value_type _Equal_close[2] = {'=', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close,
+                                                            _Equal_close+2);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__temp == __last)
+        throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    // [__first, __temp) contains all text in [= ... =]
+    typedef typename _Traits::string_type string_type;
+    string_type __collate_name =
+        __traits_.lookup_collatename(__first, __temp);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__collate_name.empty())
+        throw regex_error(regex_constants::error_collate);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    string_type __equiv_name =
+        __traits_.transform_primary(__collate_name.begin(),
+                                    __collate_name.end());
+    if (!__equiv_name.empty())
+        __ml->__add_equivalence(__equiv_name);
+    else
+    {
+        switch (__collate_name.size())
+        {
+        case 1:
+            __ml->__add_char(__collate_name[0]);
+            break;
+        case 2:
+            __ml->__add_digraph(__collate_name[0], __collate_name[1]);
+            break;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        default:
+            throw regex_error(regex_constants::error_collate);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        }
+    }
+    __first = _VSTD::next(__temp, 2);
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first,
+                                    _ForwardIterator __last,
+                                    __bracket_expression<_CharT, _Traits>* __ml)
+{
+    // Found [:
+    //   This means :] must exist
+    value_type _Colon_close[2] = {':', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close,
+                                                            _Colon_close+2);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__temp == __last)
+        throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    // [__first, __temp) contains all text in [: ... :]
+    typedef typename _Traits::char_class_type char_class_type;
+    char_class_type __class_type =
+        __traits_.lookup_classname(__first, __temp, __flags_ & icase);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__class_type == 0)
+        throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    __ml->__add_class(__class_type);
+    __first = _VSTD::next(__temp, 2);
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first,
+                                                _ForwardIterator __last,
+                                                basic_string<_CharT>& __col_sym)
+{
+    // Found [.
+    //   This means .] must exist
+    value_type _Dot_close[2] = {'.', ']'};
+    _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close,
+                                                            _Dot_close+2);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__temp == __last)
+        throw regex_error(regex_constants::error_brack);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    // [__first, __temp) contains all text in [. ... .]
+    typedef typename _Traits::string_type string_type;
+    __col_sym = __traits_.lookup_collatename(__first, __temp);
+    switch (__col_sym.size())
+    {
+    case 1:
+    case 2:
+        break;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    default:
+        throw regex_error(regex_constants::error_collate);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    __first = _VSTD::next(__temp, 2);
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_DUP_COUNT(_ForwardIterator __first,
+                                                _ForwardIterator __last,
+                                                int& __c)
+{
+    if (__first != __last )
+    {
+        int __val = __traits_.value(*__first, 10);
+        if ( __val != -1 )
+        {
+            __c = __val;
+            for (++__first; 
+                 __first != __last && ( __val = __traits_.value(*__first, 10)) != -1;
+                 ++__first)
+            {
+                __c *= 10;
+                __c += __val;
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_ecma_exp(_ForwardIterator __first,
+                                               _ForwardIterator __last)
+{
+    __owns_one_state<_CharT>* __sa = __end_;
+    _ForwardIterator __temp = __parse_alternative(__first, __last);
+    if (__temp == __first)
+        __push_empty();
+    __first = __temp;
+    while (__first != __last && *__first == '|')
+    {
+        __owns_one_state<_CharT>* __sb = __end_;
+        __temp = __parse_alternative(++__first, __last);
+        if (__temp == __first)
+            __push_empty();
+        __push_alternation(__sa, __sb);
+        __first = __temp;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_alternative(_ForwardIterator __first,
+                                                  _ForwardIterator __last)
+{
+    while (true)
+    {
+        _ForwardIterator __temp = __parse_term(__first, __last);
+        if (__temp == __first)
+            break;
+        __first = __temp;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_term(_ForwardIterator __first,
+                                           _ForwardIterator __last)
+{
+    _ForwardIterator __temp = __parse_assertion(__first, __last);
+    if (__temp == __first)
+    {
+        __owns_one_state<_CharT>* __e = __end_;
+        unsigned __mexp_begin = __marked_count_;
+        __temp = __parse_atom(__first, __last);
+        if (__temp != __first)
+            __first = __parse_ERE_dupl_symbol(__temp, __last, __e,
+                                              __mexp_begin+1, __marked_count_+1);
+    }
+    else
+        __first = __temp;
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_assertion(_ForwardIterator __first,
+                                                _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        switch (*__first)
+        {
+        case '^':
+            __push_l_anchor();
+            ++__first;
+            break;
+        case '$':
+            __push_r_anchor();
+            ++__first;
+            break;
+        case '\\':
+            {
+                _ForwardIterator __temp = _VSTD::next(__first);
+                if (__temp != __last)
+                {
+                    if (*__temp == 'b')
+                    {
+                        __push_word_boundary(false);
+                        __first = ++__temp;
+                    }
+                    else if (*__temp == 'B')
+                    {
+                        __push_word_boundary(true);
+                        __first = ++__temp;
+                    }
+                }
+            }
+            break;
+        case '(':
+            {
+                _ForwardIterator __temp = _VSTD::next(__first);
+                if (__temp != __last && *__temp == '?')
+                {
+                    if (++__temp != __last)
+                    {
+                        switch (*__temp)
+                        {
+                        case '=':
+                            {
+                                basic_regex __exp;
+                                __exp.__flags_ = __flags_;
+                                __temp = __exp.__parse(++__temp, __last);
+                                unsigned __mexp = __exp.__marked_count_;
+                                __push_lookahead(_VSTD::move(__exp), false, __marked_count_);
+                                __marked_count_ += __mexp;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                                if (__temp == __last || *__temp != ')')
+                                    throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                                __first = ++__temp;
+                            }
+                            break;
+                        case '!':
+                            {
+                                basic_regex __exp;
+                                __exp.__flags_ = __flags_;
+                                __temp = __exp.__parse(++__temp, __last);
+                                unsigned __mexp = __exp.__marked_count_;
+                                __push_lookahead(_VSTD::move(__exp), true, __marked_count_);
+                                __marked_count_ += __mexp;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                                if (__temp == __last || *__temp != ')')
+                                    throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                                __first = ++__temp;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_atom(_ForwardIterator __first,
+                                           _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        switch (*__first)
+        {
+        case '.':
+            __push_match_any_but_newline();
+            ++__first;
+            break;
+        case '\\':
+            __first = __parse_atom_escape(__first, __last);
+            break;
+        case '[':
+            __first = __parse_bracket_expression(__first, __last);
+            break;
+        case '(':
+            {
+                ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                if (__first == __last)
+                    throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                _ForwardIterator __temp = _VSTD::next(__first);
+                if (__temp != __last && *__first == '?' && *__temp == ':')
+                {
+                    ++__open_count_;
+                    __first = __parse_ecma_exp(++__temp, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (__first == __last || *__first != ')')
+                        throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    --__open_count_;
+                    ++__first;
+                }
+                else
+                {
+                    __push_begin_marked_subexpression();
+                    unsigned __temp_count = __marked_count_;
+                    ++__open_count_;
+                    __first = __parse_ecma_exp(__first, __last);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                    if (__first == __last || *__first != ')')
+                        throw regex_error(regex_constants::error_paren);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                    __push_end_marked_subexpression(__temp_count);
+                    --__open_count_;
+                    ++__first;
+                }
+            }
+            break;
+        default:
+            __first = __parse_pattern_character(__first, __last);
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_atom_escape(_ForwardIterator __first,
+                                                  _ForwardIterator __last)
+{
+    if (__first != __last && *__first == '\\')
+    {
+        _ForwardIterator __t1 = _VSTD::next(__first);
+        _ForwardIterator __t2 = __parse_decimal_escape(__t1, __last);
+        if (__t2 != __t1)
+            __first = __t2;
+        else
+        {
+            __t2 = __parse_character_class_escape(__t1, __last);
+            if (__t2 != __t1)
+                __first = __t2;
+            else
+            {
+                __t2 = __parse_character_escape(__t1, __last);
+                if (__t2 != __t1)
+                    __first = __t2;
+            }
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first,
+                                                     _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        if (*__first == '0')
+        {
+            __push_char(_CharT());
+            ++__first;
+        }
+        else if ('1' <= *__first && *__first <= '9')
+        {
+            unsigned __v = *__first - '0';
+            for (++__first; '0' <= *__first && *__first <= '9'; ++__first)
+                __v = 10 * __v + *__first - '0';
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__v > mark_count())
+                throw regex_error(regex_constants::error_backref);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __push_back_ref(__v);
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_character_class_escape(_ForwardIterator __first,
+                                                             _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        __bracket_expression<_CharT, _Traits>* __ml;
+        switch (*__first)
+        {
+        case 'd':
+            __ml = __start_matching_list(false);
+            __ml->__add_class(ctype_base::digit);
+            ++__first;
+            break;
+        case 'D':
+            __ml = __start_matching_list(true);
+            __ml->__add_class(ctype_base::digit);
+            ++__first;
+            break;
+        case 's':
+            __ml = __start_matching_list(false);
+            __ml->__add_class(ctype_base::space);
+            ++__first;
+            break;
+        case 'S':
+            __ml = __start_matching_list(true);
+            __ml->__add_class(ctype_base::space);
+            ++__first;
+            break;
+        case 'w':
+            __ml = __start_matching_list(false);
+            __ml->__add_class(ctype_base::alnum);
+            __ml->__add_char('_');
+            ++__first;
+            break;
+        case 'W':
+            __ml = __start_matching_list(true);
+            __ml->__add_class(ctype_base::alnum);
+            __ml->__add_char('_');
+            ++__first;
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_character_escape(_ForwardIterator __first,
+                                                    _ForwardIterator __last,
+                                                    basic_string<_CharT>* __str)
+{
+    if (__first != __last)
+    {
+        _ForwardIterator __t;
+        unsigned __sum = 0;
+        int __hd;
+        switch (*__first)
+        {
+        case 'f':
+            if (__str)
+                *__str = _CharT(0xC);
+            else
+                __push_char(_CharT(0xC));
+            ++__first;
+            break;
+        case 'n':
+            if (__str)
+                *__str = _CharT(0xA);
+            else
+                __push_char(_CharT(0xA));
+            ++__first;
+            break;
+        case 'r':
+            if (__str)
+                *__str = _CharT(0xD);
+            else
+                __push_char(_CharT(0xD));
+            ++__first;
+            break;
+        case 't':
+            if (__str)
+                *__str = _CharT(0x9);
+            else
+                __push_char(_CharT(0x9));
+            ++__first;
+            break;
+        case 'v':
+            if (__str)
+                *__str = _CharT(0xB);
+            else
+                __push_char(_CharT(0xB));
+            ++__first;
+            break;
+        case 'c':
+            if ((__t = _VSTD::next(__first)) != __last)
+            {
+                if (('A' <= *__t && *__t <= 'Z') || 
+                    ('a' <= *__t && *__t <= 'z'))
+                {
+                    if (__str)
+                        *__str = _CharT(*__t % 32);
+                    else
+                        __push_char(_CharT(*__t % 32));
+                    __first = ++__t;
+                }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                else 
+                    throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            else
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            break;
+        case 'u':
+            ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__first == __last)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __hd = __traits_.value(*__first, 16);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__hd == -1)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __sum = 16 * __sum + static_cast<unsigned>(__hd);
+            ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__first == __last)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __hd = __traits_.value(*__first, 16);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__hd == -1)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __sum = 16 * __sum + static_cast<unsigned>(__hd);
+            // drop through
+        case 'x':
+            ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__first == __last)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __hd = __traits_.value(*__first, 16);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__hd == -1)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __sum = 16 * __sum + static_cast<unsigned>(__hd);
+            ++__first;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__first == __last)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __hd = __traits_.value(*__first, 16);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            if (__hd == -1)
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __sum = 16 * __sum + static_cast<unsigned>(__hd);
+            if (__str)
+                *__str = _CharT(__sum);
+            else
+                __push_char(_CharT(__sum));
+            ++__first;
+            break;
+        case '0':
+            if (__str)
+                *__str = _CharT(0);
+            else
+                __push_char(_CharT(0));
+            ++__first;
+            break;
+        default:
+            if (*__first != '_' && !__traits_.isctype(*__first, ctype_base::alnum))
+            {
+                if (__str)
+                    *__str = *__first;
+                else
+                    __push_char(*__first);
+                ++__first;
+            }
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            else
+                throw regex_error(regex_constants::error_escape);
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_pattern_character(_ForwardIterator __first,
+                                                        _ForwardIterator __last)
+{
+    if (__first != __last)
+    {
+        switch (*__first)
+        {
+        case '^':
+        case '$':
+        case '\\':
+        case '.':
+        case '*':
+        case '+':
+        case '?':
+        case '(':
+        case ')':
+        case '[':
+        case ']':
+        case '{':
+        case '}':
+        case '|':
+            break;
+        default:
+            __push_char(*__first);
+            ++__first;
+            break;
+        }
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_grep(_ForwardIterator __first,
+                                           _ForwardIterator __last)
+{
+    __owns_one_state<_CharT>* __sa = __end_;
+    _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\n'));
+    if (__t1 != __first)
+        __parse_basic_reg_exp(__first, __t1);
+    else
+        __push_empty();
+    __first = __t1;
+    if (__first != __last)
+        ++__first;
+    while (__first != __last)
+    {
+        __t1 = _VSTD::find(__first, __last, _CharT('\n'));
+        __owns_one_state<_CharT>* __sb = __end_;
+        if (__t1 != __first)
+            __parse_basic_reg_exp(__first, __t1);
+        else
+            __push_empty();
+        __push_alternation(__sa, __sb);
+        __first = __t1;
+        if (__first != __last)
+            ++__first;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+template <class _ForwardIterator>
+_ForwardIterator
+basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,
+                                            _ForwardIterator __last)
+{
+    __owns_one_state<_CharT>* __sa = __end_;
+    _ForwardIterator __t1 = _VSTD::find(__first, __last, _CharT('\n'));
+    if (__t1 != __first)
+        __parse_extended_reg_exp(__first, __t1);
+    else
+        __push_empty();
+    __first = __t1;
+    if (__first != __last)
+        ++__first;
+    while (__first != __last)
+    {
+        __t1 = _VSTD::find(__first, __last, _CharT('\n'));
+        __owns_one_state<_CharT>* __sb = __end_;
+        if (__t1 != __first)
+            __parse_extended_reg_exp(__first, __t1);
+        else
+            __push_empty();
+        __push_alternation(__sa, __sb);
+        __first = __t1;
+        if (__first != __last)
+            ++__first;
+    }
+    return __first;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,
+        __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end,
+        bool __greedy)
+{
+    unique_ptr<__empty_state<_CharT> > __e1(new __empty_state<_CharT>(__end_->first()));
+    __end_->first() = nullptr;
+    unique_ptr<__loop<_CharT> > __e2(new __loop<_CharT>(__loop_count_,
+                __s->first(), __e1.get(), __mexp_begin, __mexp_end, __greedy,
+                __min, __max));
+    __s->first() = nullptr;
+    __e1.release();
+    __end_->first() = new __repeat_one_loop<_CharT>(__e2.get());
+    __end_ = __e2->second();
+    __s->first() = __e2.release();
+    ++__loop_count_;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_char(value_type __c)
+{
+    if (flags() & icase)
+        __end_->first() = new __match_char_icase<_CharT, _Traits>
+                                              (__traits_, __c, __end_->first());
+    else if (flags() & collate)
+        __end_->first() = new __match_char_collate<_CharT, _Traits>
+                                              (__traits_, __c, __end_->first());
+    else
+        __end_->first() = new __match_char<_CharT>(__c, __end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_begin_marked_subexpression()
+{
+    if (!(__flags_ & nosubs))
+    {
+        __end_->first() =
+                new __begin_marked_subexpression<_CharT>(++__marked_count_,
+                                                         __end_->first());
+        __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+    }
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_end_marked_subexpression(unsigned __sub)
+{
+    if (!(__flags_ & nosubs))
+    {
+        __end_->first() =
+                new __end_marked_subexpression<_CharT>(__sub, __end_->first());
+        __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+    }
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_l_anchor()
+{
+    __end_->first() = new __l_anchor<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_r_anchor()
+{
+    __end_->first() = new __r_anchor<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_match_any()
+{
+    __end_->first() = new __match_any<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_match_any_but_newline()
+{
+    __end_->first() = new __match_any_but_newline<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_empty()
+{
+    __end_->first() = new __empty_state<_CharT>(__end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_word_boundary(bool __invert)
+{
+    __end_->first() = new __word_boundary<_CharT, _Traits>(__traits_, __invert,
+                                                           __end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_back_ref(int __i)
+{
+    if (flags() & icase)
+        __end_->first() = new __back_ref_icase<_CharT, _Traits>
+                                              (__traits_, __i, __end_->first());
+    else if (flags() & collate)
+        __end_->first() = new __back_ref_collate<_CharT, _Traits>
+                                              (__traits_, __i, __end_->first());
+    else
+        __end_->first() = new __back_ref<_CharT>(__i, __end_->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_alternation(__owns_one_state<_CharT>* __sa,
+                                                 __owns_one_state<_CharT>* __ea)
+{
+    __sa->first() = new __alternate<_CharT>(
+                         static_cast<__owns_one_state<_CharT>*>(__sa->first()),
+                         static_cast<__owns_one_state<_CharT>*>(__ea->first()));
+    __ea->first() = nullptr;
+    __ea->first() = new __empty_state<_CharT>(__end_->first());
+    __end_->first() = nullptr;
+    __end_->first() = new __empty_non_own_state<_CharT>(__ea->first());
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__ea->first());
+}
+
+template <class _CharT, class _Traits>
+__bracket_expression<_CharT, _Traits>*
+basic_regex<_CharT, _Traits>::__start_matching_list(bool __negate)
+{
+    __bracket_expression<_CharT, _Traits>* __r =
+        new __bracket_expression<_CharT, _Traits>(__traits_, __end_->first(),
+                                                  __negate, __flags_ & icase,
+                                                  __flags_ & collate);
+    __end_->first() = __r;
+    __end_ = __r;
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp,
+                                               bool __invert,
+                                               unsigned __mexp)
+{
+    __end_->first() = new __lookahead<_CharT, _Traits>(__exp, __invert,
+                                                           __end_->first(), __mexp);
+    __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
+}
+
+typedef basic_regex<char>    regex;
+typedef basic_regex<wchar_t> wregex;
+
+// sub_match
+
+template <class _BidirectionalIterator>
+class _LIBCPP_TYPE_VIS_ONLY sub_match
+    : public pair<_BidirectionalIterator, _BidirectionalIterator>
+{
+public:
+    typedef _BidirectionalIterator                              iterator;
+    typedef typename iterator_traits<iterator>::value_type      value_type;
+    typedef typename iterator_traits<iterator>::difference_type difference_type;
+    typedef basic_string<value_type>                            string_type;
+
+    bool matched;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR sub_match() : matched() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    difference_type length() const
+        {return matched ? _VSTD::distance(this->first, this->second) : 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    string_type str() const
+        {return matched ? string_type(this->first, this->second) : string_type();}
+    _LIBCPP_INLINE_VISIBILITY
+    operator string_type() const
+        {return str();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(const sub_match& __s) const
+        {return str().compare(__s.str());}
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(const string_type& __s) const
+        {return str().compare(__s);}
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(const value_type* __s) const
+        {return str().compare(__s);}
+};
+
+typedef sub_match<const char*>             csub_match;
+typedef sub_match<const wchar_t*>          wcsub_match;
+typedef sub_match<string::const_iterator>  ssub_match;
+typedef sub_match<wstring::const_iterator> wssub_match;
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return __x.compare(__y) == 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return __x.compare(__y) < 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return __y.compare(__x.c_str()) == 0;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+          const sub_match<_BiIter>& __y)
+{
+    return __y.compare(__x.c_str()) > 0;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+          const sub_match<_BiIter>& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+                const sub_match<_BiIter>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const sub_match<_BiIter>& __x,
+           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return __x.compare(__y.c_str()) == 0;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const sub_match<_BiIter>& __x,
+           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const sub_match<_BiIter>& __x,
+          const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return __x.compare(__y.c_str()) < 0;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator>(const sub_match<_BiIter>& __x,
+               const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const sub_match<_BiIter>& __x,
+           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const sub_match<_BiIter>& __x,
+           const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(typename iterator_traits<_BiIter>::value_type const* __x,
+           const sub_match<_BiIter>& __y)
+{
+    return __y.compare(__x) == 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(typename iterator_traits<_BiIter>::value_type const* __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(typename iterator_traits<_BiIter>::value_type const* __x,
+          const sub_match<_BiIter>& __y)
+{
+    return __y.compare(__x) > 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(typename iterator_traits<_BiIter>::value_type const* __x,
+          const sub_match<_BiIter>& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(typename iterator_traits<_BiIter>::value_type const* __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(typename iterator_traits<_BiIter>::value_type const* __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return __x.compare(__y) == 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const sub_match<_BiIter>& __x,
+          typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return __x.compare(__y) < 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const sub_match<_BiIter>& __x,
+          typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const* __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(typename iterator_traits<_BiIter>::value_type const& __x,
+           const sub_match<_BiIter>& __y)
+{
+    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
+    return __y.compare(string_type(1, __x)) == 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(typename iterator_traits<_BiIter>::value_type const& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(typename iterator_traits<_BiIter>::value_type const& __x,
+          const sub_match<_BiIter>& __y)
+{
+    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
+    return __y.compare(string_type(1, __x)) > 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(typename iterator_traits<_BiIter>::value_type const& __x,
+          const sub_match<_BiIter>& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(typename iterator_traits<_BiIter>::value_type const& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(typename iterator_traits<_BiIter>::value_type const& __x,
+           const sub_match<_BiIter>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
+    return __x.compare(string_type(1, __y)) == 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const sub_match<_BiIter>& __x,
+          typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    typedef basic_string<typename iterator_traits<_BiIter>::value_type> string_type;
+    return __x.compare(string_type(1, __y)) < 0;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const sub_match<_BiIter>& __x,
+          typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    return __y < __x;
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const sub_match<_BiIter>& __x,
+           typename iterator_traits<_BiIter>::value_type const& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _CharT, class _ST, class _BiIter>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _ST>&
+operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m)
+{
+    return __os << __m.str();
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY match_results
+{
+public:
+    typedef _Allocator                                        allocator_type;
+    typedef sub_match<_BidirectionalIterator>                 value_type;
+private:
+    typedef vector<value_type, allocator_type>                __container_type;
+
+    __container_type  __matches_;
+    value_type __unmatched_;
+    value_type __prefix_;
+    value_type __suffix_;
+    bool       __ready_;
+public:
+    _BidirectionalIterator __position_start_;
+    typedef const value_type&                                 const_reference;
+    typedef value_type&                                       reference;
+    typedef typename __container_type::const_iterator         const_iterator;
+    typedef const_iterator                                    iterator;
+    typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
+    typedef typename allocator_traits<allocator_type>::size_type size_type;
+    typedef typename iterator_traits<_BidirectionalIterator>::value_type char_type;
+    typedef basic_string<char_type>                           string_type;
+
+    // construct/copy/destroy:
+    explicit match_results(const allocator_type& __a = allocator_type());
+//    match_results(const match_results&) = default;
+//    match_results& operator=(const match_results&) = default;
+//    match_results(match_results&& __m) = default;
+//    match_results& operator=(match_results&& __m) = default;
+//    ~match_results() = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool ready() const {return __ready_;}
+
+    // size:
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const {return __matches_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const {return __matches_.max_size();}
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const {return size() == 0;}
+
+    // element access:
+    _LIBCPP_INLINE_VISIBILITY
+    difference_type length(size_type __sub = 0) const
+        {return (*this)[__sub].length();}
+    _LIBCPP_INLINE_VISIBILITY
+    difference_type position(size_type __sub = 0) const
+        {return _VSTD::distance(__position_start_, (*this)[__sub].first);}
+    _LIBCPP_INLINE_VISIBILITY
+    string_type str(size_type __sub = 0) const
+        {return (*this)[__sub].str();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference operator[](size_type __n) const
+        {return __n < __matches_.size() ? __matches_[__n] : __unmatched_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference prefix() const {return __prefix_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference suffix() const {return __suffix_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const {return empty() ? __matches_.end() : __matches_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const {return __matches_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const {return empty() ? __matches_.end() : __matches_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const {return __matches_.end();}
+
+    // format:
+    template <class _OutputIter>
+        _OutputIter
+        format(_OutputIter __out, const char_type* __fmt_first,
+               const char_type* __fmt_last,
+               regex_constants::match_flag_type __flags = regex_constants::format_default) const;
+    template <class _OutputIter, class _ST, class _SA>
+        _LIBCPP_INLINE_VISIBILITY
+        _OutputIter
+        format(_OutputIter __out, const basic_string<char_type, _ST, _SA>& __fmt,
+               regex_constants::match_flag_type __flags = regex_constants::format_default) const
+            {return format(__out, __fmt.data(), __fmt.data() + __fmt.size(), __flags);}
+    template <class _ST, class _SA>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string<char_type, _ST, _SA>
+        format(const basic_string<char_type, _ST, _SA>& __fmt,
+               regex_constants::match_flag_type __flags = regex_constants::format_default) const
+        {
+            basic_string<char_type, _ST, _SA> __r;
+            format(back_inserter(__r), __fmt.data(), __fmt.data() + __fmt.size(),
+                   __flags);
+            return __r;
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    string_type
+        format(const char_type* __fmt,
+               regex_constants::match_flag_type __flags = regex_constants::format_default) const
+        {
+            string_type __r;
+            format(back_inserter(__r), __fmt,
+                   __fmt + char_traits<char_type>::length(__fmt), __flags);
+            return __r;
+        }
+
+    // allocator:
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const {return __matches_.get_allocator();}
+
+    // swap:
+    void swap(match_results& __m);
+
+    template <class _Bp, class _Ap>
+        _LIBCPP_INLINE_VISIBILITY
+        void __assign(_BidirectionalIterator __f, _BidirectionalIterator __l,
+                      const match_results<_Bp, _Ap>& __m, bool __no_update_pos)
+    {
+        _Bp __mf = __m.prefix().first;
+        __matches_.resize(__m.size());
+        for (size_type __i = 0; __i < __matches_.size(); ++__i)
+        {
+            __matches_[__i].first = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].first));
+            __matches_[__i].second = _VSTD::next(__f, _VSTD::distance(__mf, __m[__i].second));
+            __matches_[__i].matched = __m[__i].matched;
+        }
+        __unmatched_.first   = __l;
+        __unmatched_.second  = __l;
+        __unmatched_.matched = false;
+        __prefix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().first));
+        __prefix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.prefix().second));
+        __prefix_.matched = __m.prefix().matched;
+        __suffix_.first = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().first));
+        __suffix_.second = _VSTD::next(__f, _VSTD::distance(__mf, __m.suffix().second));
+        __suffix_.matched = __m.suffix().matched;
+        if (!__no_update_pos)
+            __position_start_ = __prefix_.first;
+        __ready_ = __m.ready();
+    }
+
+private:
+    void __init(unsigned __s,
+                _BidirectionalIterator __f, _BidirectionalIterator __l,
+                bool __no_update_pos = false);
+
+    template <class, class> friend class basic_regex;
+
+    template <class _Bp, class _Ap, class _Cp, class _Tp>
+    friend
+    bool
+    regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Tp>&,
+                regex_constants::match_flag_type);
+
+    template <class _Bp, class _Ap>
+    friend
+    bool
+    operator==(const match_results<_Bp, _Ap>&, const match_results<_Bp, _Ap>&);
+
+    template <class, class> friend class __lookahead;
+};
+
+template <class _BidirectionalIterator, class _Allocator>
+match_results<_BidirectionalIterator, _Allocator>::match_results(
+        const allocator_type& __a)
+    : __matches_(__a),
+      __unmatched_(),
+      __prefix_(),
+      __suffix_(),
+      __position_start_(),
+      __ready_(false)
+{
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+void
+match_results<_BidirectionalIterator, _Allocator>::__init(unsigned __s,
+                         _BidirectionalIterator __f, _BidirectionalIterator __l,
+                         bool __no_update_pos)
+{
+    __unmatched_.first   = __l;
+    __unmatched_.second  = __l;
+    __unmatched_.matched = false;
+    __matches_.assign(__s, __unmatched_);
+    __prefix_.first      = __f;
+    __prefix_.second     = __f;
+    __prefix_.matched    = false;
+    __suffix_ = __unmatched_;
+    if (!__no_update_pos)
+        __position_start_ = __prefix_.first;
+    __ready_ = true;
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+template <class _OutputIter>
+_OutputIter
+match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __out,
+        const char_type* __fmt_first, const char_type* __fmt_last,
+        regex_constants::match_flag_type __flags) const
+{
+    if (__flags & regex_constants::format_sed)
+    {
+        for (; __fmt_first != __fmt_last; ++__fmt_first)
+        {
+            if (*__fmt_first == '&')
+                __out = _VSTD::copy(__matches_[0].first, __matches_[0].second,
+                                   __out);
+            else if (*__fmt_first == '\\' && __fmt_first + 1 != __fmt_last)
+            {
+                ++__fmt_first;
+                if ('0' <= *__fmt_first && *__fmt_first <= '9')
+                {
+                    size_t __i = *__fmt_first - '0';
+                    __out = _VSTD::copy(__matches_[__i].first,
+                                       __matches_[__i].second, __out);
+                }
+                else
+                {
+                    *__out = *__fmt_first;
+                    ++__out;
+                }
+            }
+            else
+            {
+                *__out = *__fmt_first;
+                ++__out;
+            }
+        }
+    }
+    else
+    {
+        for (; __fmt_first != __fmt_last; ++__fmt_first)
+        {
+            if (*__fmt_first == '$' && __fmt_first + 1 != __fmt_last)
+            {
+                switch (__fmt_first[1])
+                {
+                case '$':
+                    *__out = *++__fmt_first;
+                    ++__out;
+                    break;
+                case '&':
+                    ++__fmt_first;
+                    __out = _VSTD::copy(__matches_[0].first, __matches_[0].second,
+                                       __out);
+                    break;
+                case '`':
+                    ++__fmt_first;
+                    __out = _VSTD::copy(__prefix_.first, __prefix_.second, __out);
+                    break;
+                case '\'':
+                    ++__fmt_first;
+                    __out = _VSTD::copy(__suffix_.first, __suffix_.second, __out);
+                    break;
+                default:
+                    if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')
+                    {
+                        ++__fmt_first;
+                        size_t __i = *__fmt_first - '0';
+                        if (__fmt_first + 1 != __fmt_last &&
+                            '0' <= __fmt_first[1] && __fmt_first[1] <= '9')
+                        {
+                            ++__fmt_first;
+                            __i = 10 * __i + *__fmt_first - '0';
+                        }
+                        __out = _VSTD::copy(__matches_[__i].first,
+                                           __matches_[__i].second, __out);
+                    }
+                    else
+                    {
+                        *__out = *__fmt_first;
+                        ++__out;
+                    }
+                    break;
+                }
+            }
+            else
+            {
+                *__out = *__fmt_first;
+                ++__out;
+            }
+        }
+    }
+    return __out;
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+void
+match_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m)
+{
+    using _VSTD::swap;
+    swap(__matches_, __m.__matches_);
+    swap(__unmatched_, __m.__unmatched_);
+    swap(__prefix_, __m.__prefix_);
+    swap(__suffix_, __m.__suffix_);
+    swap(__position_start_, __m.__position_start_);
+    swap(__ready_, __m.__ready_);
+}
+
+typedef match_results<const char*>             cmatch;
+typedef match_results<const wchar_t*>          wcmatch;
+typedef match_results<string::const_iterator>  smatch;
+typedef match_results<wstring::const_iterator> wsmatch;
+
+template <class _BidirectionalIterator, class _Allocator>
+bool
+operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
+           const match_results<_BidirectionalIterator, _Allocator>& __y)
+{
+    if (__x.__ready_ != __y.__ready_)
+        return false;
+    if (!__x.__ready_)
+        return true;
+    return __x.__matches_ == __y.__matches_ &&
+           __x.__prefix_ == __y.__prefix_ &&
+           __x.__suffix_ == __y.__suffix_;
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x,
+           const match_results<_BidirectionalIterator, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _BidirectionalIterator, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(match_results<_BidirectionalIterator, _Allocator>& __x,
+     match_results<_BidirectionalIterator, _Allocator>& __y)
+{
+    __x.swap(__y);
+}
+
+// regex_search
+
+template <class _CharT, class _Traits>
+template <class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start_ecma(
+        const _CharT* __first, const _CharT* __last,
+        match_results<const _CharT*, _Allocator>& __m,
+        regex_constants::match_flag_type __flags, bool __at_first) const
+{
+    vector<__state> __states;
+    __node* __st = __start_.get();
+    if (__st)
+    {
+        __states.push_back(__state());
+        __states.back().__do_ = 0;
+        __states.back().__first_ = __first;
+        __states.back().__current_ = __first;
+        __states.back().__last_ = __last;
+        __states.back().__sub_matches_.resize(mark_count());
+        __states.back().__loop_data_.resize(__loop_count());
+        __states.back().__node_ = __st;
+        __states.back().__flags_ = __flags;
+        __states.back().__at_first_ = __at_first;
+        do
+        {
+            __state& __s = __states.back();
+            if (__s.__node_)
+                __s.__node_->__exec(__s);
+            switch (__s.__do_)
+            {
+            case __state::__end_state:
+                __m.__matches_[0].first = __first;
+                __m.__matches_[0].second = _VSTD::next(__first, __s.__current_ - __first);
+                __m.__matches_[0].matched = true;
+                for (unsigned __i = 0; __i < __s.__sub_matches_.size(); ++__i)
+                    __m.__matches_[__i+1] = __s.__sub_matches_[__i];
+                return true;
+            case __state::__accept_and_consume:
+            case __state::__repeat:
+            case __state::__accept_but_not_consume:
+                break;
+            case __state::__split:
+                {
+                __state __snext = __s;
+                __s.__node_->__exec_split(true, __s);
+                __snext.__node_->__exec_split(false, __snext);
+                __states.push_back(_VSTD::move(__snext));
+                }
+                break;
+            case __state::__reject:
+                __states.pop_back();
+                break;
+            default:
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                throw regex_error(regex_constants::__re_err_unknown);
+#endif
+                break;
+
+            }
+        } while (!__states.empty());
+    }
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
+        const _CharT* __first, const _CharT* __last,
+        match_results<const _CharT*, _Allocator>& __m,
+        regex_constants::match_flag_type __flags, bool __at_first) const
+{
+    deque<__state> __states;
+    ptrdiff_t __highest_j = 0;
+    ptrdiff_t _Np = _VSTD::distance(__first, __last);
+    __node* __st = __start_.get();
+    if (__st)
+    {
+        __states.push_back(__state());
+        __states.back().__do_ = 0;
+        __states.back().__first_ = __first;
+        __states.back().__current_ = __first;
+        __states.back().__last_ = __last;
+        __states.back().__loop_data_.resize(__loop_count());
+        __states.back().__node_ = __st;
+        __states.back().__flags_ = __flags;
+        __states.back().__at_first_ = __at_first;
+        bool __matched = false;
+        do
+        {
+            __state& __s = __states.back();
+            if (__s.__node_)
+                __s.__node_->__exec(__s);
+            switch (__s.__do_)
+            {
+            case __state::__end_state:
+                if (!__matched || __highest_j < __s.__current_ - __s.__first_)
+                    __highest_j = __s.__current_ - __s.__first_;
+                __matched = true;
+                if (__highest_j == _Np)
+                    __states.clear();
+                else
+                    __states.pop_back();
+                break;
+            case __state::__consume_input:
+                break;
+            case __state::__accept_and_consume:
+                __states.push_front(_VSTD::move(__s));
+                __states.pop_back();
+                break;
+            case __state::__repeat:
+            case __state::__accept_but_not_consume:
+                break;
+            case __state::__split:
+                {
+                __state __snext = __s;
+                __s.__node_->__exec_split(true, __s);
+                __snext.__node_->__exec_split(false, __snext);
+                __states.push_back(_VSTD::move(__snext));
+                }
+                break;
+            case __state::__reject:
+                __states.pop_back();
+                break;
+            default:
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                throw regex_error(regex_constants::__re_err_unknown);
+#endif
+                break;
+            }
+        } while (!__states.empty());
+        if (__matched)
+        {
+            __m.__matches_[0].first = __first;
+            __m.__matches_[0].second = _VSTD::next(__first, __highest_j);
+            __m.__matches_[0].matched = true;
+            return true;
+        }
+    }
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
+        const _CharT* __first, const _CharT* __last,
+        match_results<const _CharT*, _Allocator>& __m,
+        regex_constants::match_flag_type __flags, bool __at_first) const
+{
+    vector<__state> __states;
+    __state __best_state;
+    ptrdiff_t __j = 0;
+    ptrdiff_t __highest_j = 0;
+    ptrdiff_t _Np = _VSTD::distance(__first, __last);
+    __node* __st = __start_.get();
+    if (__st)
+    {
+        __states.push_back(__state());
+        __states.back().__do_ = 0;
+        __states.back().__first_ = __first;
+        __states.back().__current_ = __first;
+        __states.back().__last_ = __last;
+        __states.back().__sub_matches_.resize(mark_count());
+        __states.back().__loop_data_.resize(__loop_count());
+        __states.back().__node_ = __st;
+        __states.back().__flags_ = __flags;
+        __states.back().__at_first_ = __at_first;
+        const _CharT* __current = __first;
+        bool __matched = false;
+        do
+        {
+            __state& __s = __states.back();
+            if (__s.__node_)
+                __s.__node_->__exec(__s);
+            switch (__s.__do_)
+            {
+            case __state::__end_state:
+                if (!__matched || __highest_j < __s.__current_ - __s.__first_)
+                {
+                    __highest_j = __s.__current_ - __s.__first_;
+                    __best_state = __s;
+                }
+                __matched = true;
+                if (__highest_j == _Np)
+                    __states.clear();
+                else
+                    __states.pop_back();
+                break;
+            case __state::__accept_and_consume:
+                __j += __s.__current_ - __current;
+                __current = __s.__current_;
+                break;
+            case __state::__repeat:
+            case __state::__accept_but_not_consume:
+                break;
+            case __state::__split:
+                {
+                __state __snext = __s;
+                __s.__node_->__exec_split(true, __s);
+                __snext.__node_->__exec_split(false, __snext);
+                __states.push_back(_VSTD::move(__snext));
+                }
+                break;
+            case __state::__reject:
+                __states.pop_back();
+                break;
+            default:
+#ifndef _LIBCPP_NO_EXCEPTIONS
+                throw regex_error(regex_constants::__re_err_unknown);
+#endif
+                break;
+            }
+        } while (!__states.empty());
+        if (__matched)
+        {
+            __m.__matches_[0].first = __first;
+            __m.__matches_[0].second = _VSTD::next(__first, __highest_j);
+            __m.__matches_[0].matched = true;
+            for (unsigned __i = 0; __i < __best_state.__sub_matches_.size(); ++__i)
+                __m.__matches_[__i+1] = __best_state.__sub_matches_[__i];
+            return true;
+        }
+    }
+    return false;
+}
+
+template <class _CharT, class _Traits>
+template <class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__match_at_start(
+        const _CharT* __first, const _CharT* __last,
+        match_results<const _CharT*, _Allocator>& __m,
+        regex_constants::match_flag_type __flags, bool __at_first) const
+{
+    if ((__flags_ & 0x1F0) == ECMAScript)
+        return __match_at_start_ecma(__first, __last, __m, __flags, __at_first);
+    if (mark_count() == 0)
+        return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first);
+    return __match_at_start_posix_subs(__first, __last, __m, __flags, __at_first);
+}
+
+template <class _CharT, class _Traits>
+template <class _Allocator>
+bool
+basic_regex<_CharT, _Traits>::__search(
+        const _CharT* __first, const _CharT* __last,
+        match_results<const _CharT*, _Allocator>& __m,
+        regex_constants::match_flag_type __flags) const
+{
+    __m.__init(1 + mark_count(), __first, __last,
+                                    __flags & regex_constants::__no_update_pos);
+    if (__match_at_start(__first, __last, __m, __flags, 
+                                    !(__flags & regex_constants::__no_update_pos)))
+    {
+        __m.__prefix_.second = __m[0].first;
+        __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+        __m.__suffix_.first = __m[0].second;
+        __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+        return true;
+    }
+    if (__first != __last && !(__flags & regex_constants::match_continuous))
+    {
+        __flags |= regex_constants::match_prev_avail;
+        for (++__first; __first != __last; ++__first)
+        {
+            __m.__matches_.assign(__m.size(), __m.__unmatched_);
+            if (__match_at_start(__first, __last, __m, __flags, false))
+            {
+                __m.__prefix_.second = __m[0].first;
+                __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+                __m.__suffix_.first = __m[0].second;
+                __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+                return true;
+            }
+            __m.__matches_.assign(__m.size(), __m.__unmatched_);
+        }
+    }
+    __m.__matches_.clear();
+    return false;
+}
+
+template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
+             match_results<_BidirectionalIterator, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    int __offset = (__flags & regex_constants::match_prev_avail) ? 1 : 0;
+    basic_string<_CharT> __s(_VSTD::prev(__first, __offset), __last);
+    match_results<const _CharT*> __mc;
+    bool __r = __e.__search(__s.data() + __offset, __s.data() + __s.size(), __mc, __flags);
+    __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
+    return __r;
+}
+
+template <class _Iter, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(__wrap_iter<_Iter> __first,
+             __wrap_iter<_Iter> __last,
+             match_results<__wrap_iter<_Iter>, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __mc;
+    bool __r = __e.__search(__first.base(), __last.base(), __mc, __flags);
+    __m.__assign(__first, __last, __mc, __flags & regex_constants::__no_update_pos);
+    return __r;
+}
+
+template <class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const _CharT* __first, const _CharT* __last,
+             match_results<const _CharT*, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return __e.__search(__first, __last, __m, __flags);
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    basic_string<_CharT> __s(__first, __last);
+    match_results<const _CharT*> __mc;
+    return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const _CharT* __first, const _CharT* __last,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __mc;
+    return __e.__search(__first, __last, __mc, __flags);
+}
+
+template <class _CharT, class _Allocator, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return __e.__search(__str, __str + _Traits::length(__str), __m, __flags);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __m;
+    return _VSTD::regex_search(__str, __m, __e, __flags);
+}
+
+template <class _ST, class _SA, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const basic_string<_CharT, _ST, _SA>& __s,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __mc;
+    return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
+}
+
+template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_search(const basic_string<_CharT, _ST, _SA>& __s,
+             match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
+             const basic_regex<_CharT, _Traits>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<const _CharT*> __mc;
+    bool __r = __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
+    __m.__assign(__s.begin(), __s.end(), __mc, __flags & regex_constants::__no_update_pos);
+    return __r;
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _ST, class _SA, class _Ap, class _Cp, class _Tp>
+bool
+regex_search(const basic_string<_Cp, _ST, _SA>&& __s,
+             match_results<typename basic_string<_Cp, _ST, _SA>::const_iterator, _Ap>&,
+             const basic_regex<_Cp, _Tp>& __e,
+             regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; 
+#endif
+
+// regex_match
+
+template <class _BidirectionalIterator, class _Allocator, class _CharT, class _Traits>
+bool
+regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
+            match_results<_BidirectionalIterator, _Allocator>& __m,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    bool __r = _VSTD::regex_search(__first, __last, __m, __e,
+                            __flags | regex_constants::match_continuous);
+    if (__r)
+    {
+        __r = !__m.suffix().matched;
+        if (!__r)
+            __m.__matches_.clear();
+    }
+    return __r;
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    match_results<_BidirectionalIterator> __m;
+    return _VSTD::regex_match(__first, __last, __m, __e, __flags);
+}
+
+template <class _CharT, class _Allocator, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(const _CharT* __str, match_results<const _CharT*, _Allocator>& __m,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return _VSTD::regex_match(__str, __str + _Traits::length(__str), __m, __e, __flags);
+}
+
+template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(const basic_string<_CharT, _ST, _SA>& __s,
+            match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags);
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(const basic_string<_CharT, _ST, _SA>&& __s,
+            match_results<typename basic_string<_CharT, _ST, _SA>::const_iterator, _Allocator>& __m,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default) = delete; 
+#endif
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(const _CharT* __str, const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return _VSTD::regex_match(__str, __str + _Traits::length(__str), __e, __flags);
+}
+
+template <class _ST, class _SA, class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+regex_match(const basic_string<_CharT, _ST, _SA>& __s,
+            const basic_regex<_CharT, _Traits>& __e,
+            regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return _VSTD::regex_match(__s.begin(), __s.end(), __e, __flags);
+}
+
+// regex_iterator
+
+template <class _BidirectionalIterator,
+          class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
+          class _Traits = regex_traits<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY regex_iterator
+{
+public:
+    typedef basic_regex<_CharT, _Traits>          regex_type;
+    typedef match_results<_BidirectionalIterator> value_type;
+    typedef ptrdiff_t                             difference_type;
+    typedef const value_type*                     pointer;
+    typedef const value_type&                     reference;
+    typedef forward_iterator_tag                  iterator_category;
+
+private:
+    _BidirectionalIterator           __begin_;
+    _BidirectionalIterator           __end_;
+    const regex_type*                __pregex_;
+    regex_constants::match_flag_type __flags_;
+    value_type                       __match_;
+
+public:
+    regex_iterator();
+    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                   const regex_type& __re,
+                   regex_constants::match_flag_type __m
+                                              = regex_constants::match_default);
+#if _LIBCPP_STD_VER > 11
+    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                   const regex_type&& __re,
+                   regex_constants::match_flag_type __m 
+                                     = regex_constants::match_default) = delete;
+#endif
+
+    bool operator==(const regex_iterator& __x) const;
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const regex_iterator& __x) const {return !(*this == __x);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return  __match_;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const  {return &__match_;}
+
+    regex_iterator& operator++();
+    _LIBCPP_INLINE_VISIBILITY
+    regex_iterator operator++(int)
+    {
+        regex_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+};
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_iterator<_BidirectionalIterator, _CharT, _Traits>::regex_iterator()
+    : __begin_(), __end_(), __pregex_(nullptr), __flags_(), __match_()
+{
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                   const regex_type& __re, regex_constants::match_flag_type __m)
+    : __begin_(__a),
+      __end_(__b),
+      __pregex_(&__re),
+      __flags_(__m)
+{
+    _VSTD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_);
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+bool
+regex_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    operator==(const regex_iterator& __x) const
+{
+    if (__match_.empty() && __x.__match_.empty())
+        return true;
+    if (__match_.empty() || __x.__match_.empty())
+        return false;
+    return __begin_ == __x.__begin_       &&
+           __end_ == __x.__end_           &&
+           __pregex_ == __x.__pregex_     &&
+           __flags_ == __x.__flags_       &&
+           __match_[0] == __x.__match_[0];
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_iterator<_BidirectionalIterator, _CharT, _Traits>&
+regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()
+{
+    __flags_ |= regex_constants::__no_update_pos;
+    _BidirectionalIterator __start = __match_[0].second;
+    if (__match_.empty())
+    {
+        if (__start == __end_)
+        {
+            __match_ = value_type();
+            return *this;
+        }
+        else if (_VSTD::regex_search(__start, __end_, __match_, *__pregex_,
+                                    __flags_ | regex_constants::match_not_null |
+                                    regex_constants::match_continuous))
+            return *this;
+        else
+            ++__start;
+    }
+    __flags_ |= regex_constants::match_prev_avail;
+    if (!_VSTD::regex_search(__start, __end_, __match_, *__pregex_, __flags_))
+        __match_ = value_type();
+    return *this;
+}
+
+typedef regex_iterator<const char*>             cregex_iterator;
+typedef regex_iterator<const wchar_t*>          wcregex_iterator;
+typedef regex_iterator<string::const_iterator>  sregex_iterator;
+typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
+
+// regex_token_iterator
+
+template <class _BidirectionalIterator,
+          class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
+          class _Traits = regex_traits<_CharT> >
+class _LIBCPP_TYPE_VIS_ONLY regex_token_iterator
+{
+public:
+    typedef basic_regex<_CharT, _Traits>      regex_type;
+    typedef sub_match<_BidirectionalIterator> value_type;
+    typedef ptrdiff_t                         difference_type;
+    typedef const value_type*                 pointer;
+    typedef const value_type&                 reference;
+    typedef forward_iterator_tag              iterator_category;
+
+private:
+    typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Position;
+
+    _Position         __position_;
+    const value_type* __result_;
+    value_type        __suffix_;
+    ptrdiff_t         _N_;
+    vector<int>       __subs_;
+
+public:
+    regex_token_iterator();
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re, int __submatch = 0,
+                         regex_constants::match_flag_type __m =
+                                                regex_constants::match_default);
+#if _LIBCPP_STD_VER > 11
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type&& __re, int __submatch = 0,
+                         regex_constants::match_flag_type __m =
+                                       regex_constants::match_default) = delete;
+#endif
+
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re, const vector<int>& __submatches,
+                         regex_constants::match_flag_type __m =
+                                                regex_constants::match_default);
+#if _LIBCPP_STD_VER > 11
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type&& __re, const vector<int>& __submatches,
+                         regex_constants::match_flag_type __m =
+                                     regex_constants::match_default) = delete;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re,
+                         initializer_list<int> __submatches,
+                         regex_constants::match_flag_type __m =
+                                                regex_constants::match_default);
+
+#if _LIBCPP_STD_VER > 11
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type&& __re,
+                         initializer_list<int> __submatches,
+                         regex_constants::match_flag_type __m =
+                                       regex_constants::match_default) = delete;
+#endif
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    template <size_t _Np>
+        regex_token_iterator(_BidirectionalIterator __a,
+                             _BidirectionalIterator __b,
+                             const regex_type& __re,
+                             const int (&__submatches)[_Np],
+                             regex_constants::match_flag_type __m =
+                                                regex_constants::match_default);
+#if _LIBCPP_STD_VER > 11
+    template <std::size_t _Np>
+        regex_token_iterator(_BidirectionalIterator __a,
+                             _BidirectionalIterator __b,
+                             const regex_type&& __re,
+                             const int (&__submatches)[_Np],
+                             regex_constants::match_flag_type __m =
+                                      regex_constants::match_default) = delete;
+#endif
+
+    regex_token_iterator(const regex_token_iterator&);
+    regex_token_iterator& operator=(const regex_token_iterator&);
+
+    bool operator==(const regex_token_iterator& __x) const;
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type& operator*() const {return *__result_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type* operator->() const {return __result_;}
+
+    regex_token_iterator& operator++();
+    _LIBCPP_INLINE_VISIBILITY
+    regex_token_iterator operator++(int)
+    {
+        regex_token_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+private:
+    void __init(_BidirectionalIterator __a, _BidirectionalIterator __b);
+    void __establish_result () {
+        if (__subs_[_N_] == -1)
+            __result_ = &__position_->prefix();
+        else
+            __result_ = &(*__position_)[__subs_[_N_]];
+        }       
+};
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator()
+    : __result_(nullptr),
+      __suffix_(),
+      _N_(0)
+{
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+void
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    __init(_BidirectionalIterator __a, _BidirectionalIterator __b)
+{
+    if (__position_ != _Position())
+        __establish_result ();
+    else if (__subs_[_N_] == -1)
+    {
+        __suffix_.matched = true;
+        __suffix_.first = __a;
+        __suffix_.second = __b;
+        __result_ = &__suffix_;
+    }
+    else
+        __result_ = nullptr;
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re, int __submatch,
+                         regex_constants::match_flag_type __m)
+    : __position_(__a, __b, __re, __m),
+      _N_(0),
+      __subs_(1, __submatch)
+{
+    __init(__a, __b);
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re, const vector<int>& __submatches,
+                         regex_constants::match_flag_type __m)
+    : __position_(__a, __b, __re, __m),
+      _N_(0),
+      __subs_(__submatches)
+{
+    __init(__a, __b);
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                         const regex_type& __re,
+                         initializer_list<int> __submatches,
+                         regex_constants::match_flag_type __m)
+    : __position_(__a, __b, __re, __m),
+      _N_(0),
+      __subs_(__submatches)
+{
+    __init(__a, __b);
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+template <size_t _Np>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
+                             const regex_type& __re,
+                             const int (&__submatches)[_Np],
+                             regex_constants::match_flag_type __m)
+    : __position_(__a, __b, __re, __m),
+      _N_(0),
+      __subs_(__submatches, __submatches + _Np)
+{
+    __init(__a, __b);
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    regex_token_iterator(const regex_token_iterator& __x)
+    : __position_(__x.__position_),
+      __result_(__x.__result_),
+      __suffix_(__x.__suffix_),
+      _N_(__x._N_),
+      __subs_(__x.__subs_)
+{
+    if (__x.__result_ == &__x.__suffix_)
+        __result_ = &__suffix_;
+    else if ( __result_ != nullptr )
+        __establish_result ();
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    operator=(const regex_token_iterator& __x)
+{
+    if (this != &__x)
+    {
+        __position_ = __x.__position_;
+        if (__x.__result_ == &__x.__suffix_)
+            __result_ = &__suffix_;
+        else
+            __result_ = __x.__result_;
+        __suffix_ = __x.__suffix_;
+        _N_ = __x._N_;
+        __subs_ = __x.__subs_;
+
+        if ( __result_ != nullptr && __result_ != &__suffix_ )
+            __establish_result();
+    }
+    return *this;
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+bool
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
+    operator==(const regex_token_iterator& __x) const
+{
+    if (__result_ == nullptr && __x.__result_ == nullptr)
+        return true;
+    if (__result_ == &__suffix_ && __x.__result_ == &__x.__suffix_ &&
+            __suffix_ == __x.__suffix_)
+        return true;
+    if (__result_ == nullptr || __x.__result_ == nullptr)
+        return false;
+    if (__result_ == &__suffix_ || __x.__result_ == &__x.__suffix_)
+        return false;
+    return __position_ == __x.__position_ && _N_ == __x._N_ &&
+           __subs_ == __x.__subs_;
+}
+
+template <class _BidirectionalIterator, class _CharT, class _Traits>
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>&
+regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()
+{
+    _Position __prev = __position_;
+    if (__result_ == &__suffix_)
+        __result_ = nullptr;
+    else if (_N_ + 1 < __subs_.size())
+    {
+        ++_N_;
+        __establish_result();
+    }
+    else
+    {
+        _N_ = 0;
+        ++__position_;
+        if (__position_ != _Position())
+            __establish_result();
+        else
+        {
+            if (_VSTD::find(__subs_.begin(), __subs_.end(), -1) != __subs_.end()
+                && __prev->suffix().length() != 0)
+            {
+                __suffix_.matched = true;
+                __suffix_.first = __prev->suffix().first;
+                __suffix_.second = __prev->suffix().second;
+                __result_ = &__suffix_;
+            }
+            else
+                __result_ = nullptr;
+        }
+    }
+    return *this;
+}
+
+typedef regex_token_iterator<const char*>             cregex_token_iterator;
+typedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;
+typedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;
+typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
+
+// regex_replace
+
+template <class _OutputIterator, class _BidirectionalIterator,
+          class _Traits, class _CharT>
+_OutputIterator
+regex_replace(_OutputIterator __out,
+              _BidirectionalIterator __first, _BidirectionalIterator __last,
+              const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    typedef regex_iterator<_BidirectionalIterator, _CharT, _Traits> _Iter;
+    _Iter __i(__first, __last, __e, __flags);
+    _Iter __eof;
+    if (__i == __eof)
+    {
+        if (!(__flags & regex_constants::format_no_copy))
+            __out = _VSTD::copy(__first, __last, __out);
+    }
+    else
+    {
+        sub_match<_BidirectionalIterator> __lm;
+        for (size_t __len = char_traits<_CharT>::length(__fmt); __i != __eof; ++__i)
+        {
+            if (!(__flags & regex_constants::format_no_copy))
+                __out = _VSTD::copy(__i->prefix().first, __i->prefix().second, __out);
+            __out = __i->format(__out, __fmt, __fmt + __len, __flags);
+            __lm = __i->suffix();
+            if (__flags & regex_constants::format_first_only)
+                break;
+        }
+        if (!(__flags & regex_constants::format_no_copy))
+            __out = _VSTD::copy(__lm.first, __lm.second, __out);
+    }
+    return __out;
+}
+
+template <class _OutputIterator, class _BidirectionalIterator,
+          class _Traits, class _CharT, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+_OutputIterator
+regex_replace(_OutputIterator __out,
+              _BidirectionalIterator __first, _BidirectionalIterator __last,
+              const basic_regex<_CharT, _Traits>& __e,
+              const basic_string<_CharT, _ST, _SA>& __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    return _VSTD::regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags);
+}
+
+template <class _Traits, class _CharT, class _ST, class _SA, class _FST,
+          class _FSA>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _ST, _SA>
+regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
+              const basic_regex<_CharT, _Traits>& __e,
+              const basic_string<_CharT, _FST, _FSA>& __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    basic_string<_CharT, _ST, _SA> __r;
+    _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,
+                        __fmt.c_str(), __flags);
+    return __r;
+}
+
+template <class _Traits, class _CharT, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _ST, _SA>
+regex_replace(const basic_string<_CharT, _ST, _SA>& __s,
+              const basic_regex<_CharT, _Traits>& __e, const _CharT* __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    basic_string<_CharT, _ST, _SA> __r;
+    _VSTD::regex_replace(back_inserter(__r), __s.begin(), __s.end(), __e,
+                        __fmt, __flags);
+    return __r;
+}
+
+template <class _Traits, class _CharT, class _ST, class _SA>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT>
+regex_replace(const _CharT* __s,
+              const basic_regex<_CharT, _Traits>& __e,
+              const basic_string<_CharT, _ST, _SA>& __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    basic_string<_CharT> __r;
+    _VSTD::regex_replace(back_inserter(__r), __s,
+                        __s + char_traits<_CharT>::length(__s), __e,
+                        __fmt.c_str(), __flags);
+    return __r;
+}
+
+template <class _Traits, class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT>
+regex_replace(const _CharT* __s,
+              const basic_regex<_CharT, _Traits>& __e,
+              const _CharT* __fmt,
+              regex_constants::match_flag_type __flags = regex_constants::match_default)
+{
+    basic_string<_CharT> __r;
+    _VSTD::regex_replace(back_inserter(__r), __s,
+                        __s + char_traits<_CharT>::length(__s), __e,
+                        __fmt, __flags);
+    return __r;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_REGEX
diff --git a/include/c++/v1/scoped_allocator b/include/c++/v1/scoped_allocator
new file mode 100644
index 0000000..aa8bece
--- /dev/null
+++ b/include/c++/v1/scoped_allocator
@@ -0,0 +1,578 @@
+// -*- C++ -*-
+//===-------------------------- scoped_allocator --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SCOPED_ALLOCATOR
+#define _LIBCPP_SCOPED_ALLOCATOR
+
+/*
+    scoped_allocator synopsis
+
+namespace std
+{
+
+template <class OuterAlloc, class... InnerAllocs>
+class scoped_allocator_adaptor : public OuterAlloc
+{
+    typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only
+    scoped_allocator_adaptor<InnerAllocs...> inner;   // exposition only
+public:
+
+    typedef OuterAlloc outer_allocator_type;
+    typedef see below inner_allocator_type;
+
+    typedef typename OuterTraits::value_type value_type;
+    typedef typename OuterTraits::size_type size_type;
+    typedef typename OuterTraits::difference_type difference_type;
+    typedef typename OuterTraits::pointer pointer;
+    typedef typename OuterTraits::const_pointer const_pointer;
+    typedef typename OuterTraits::void_pointer void_pointer;
+    typedef typename OuterTraits::const_void_pointer const_void_pointer;
+
+    typedef see below propagate_on_container_copy_assignment;
+    typedef see below propagate_on_container_move_assignment;
+    typedef see below propagate_on_container_swap;
+
+    template <class Tp>
+        struct rebind
+        {
+            typedef scoped_allocator_adaptor<
+                OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other;
+        };
+
+    scoped_allocator_adaptor();
+    template <class OuterA2>
+        scoped_allocator_adaptor(OuterA2&& outerAlloc,
+                                 const InnerAllocs&... innerAllocs) noexcept;
+    scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept;
+    scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept;
+    template <class OuterA2>
+        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept;
+    template <class OuterA2>
+        scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept;
+
+    ~scoped_allocator_adaptor();
+
+    inner_allocator_type& inner_allocator() noexcept;
+    const inner_allocator_type& inner_allocator() const noexcept;
+
+    outer_allocator_type& outer_allocator() noexcept;
+    const outer_allocator_type& outer_allocator() const noexcept;
+
+    pointer allocate(size_type n);
+    pointer allocate(size_type n, const_void_pointer hint);
+    void deallocate(pointer p, size_type n) noexcept;
+
+    size_type max_size() const;
+    template <class T, class... Args> void construct(T* p, Args&& args);
+    template <class T1, class T2, class... Args1, class... Args2>
+        void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x,
+                       tuple<Args2...> y);
+    template <class T1, class T2>
+        void construct(pair<T1, T2>* p);
+    template <class T1, class T2, class U, class V>
+        void construct(pair<T1, T2>* p, U&& x, V&& y);
+    template <class T1, class T2, class U, class V>
+        void construct(pair<T1, T2>* p, const pair<U, V>& x);
+    template <class T1, class T2, class U, class V>
+        void construct(pair<T1, T2>* p, pair<U, V>&& x);
+    template <class T> void destroy(T* p);
+
+    template <class T> void destroy(T* p) noexcept;
+
+    scoped_allocator_adaptor select_on_container_copy_construction() const noexcept;
+};
+
+template <class OuterA1, class OuterA2, class... InnerAllocs>
+    bool
+    operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
+               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
+
+template <class OuterA1, class OuterA2, class... InnerAllocs>
+    bool
+    operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
+               const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <memory>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
+
+// scoped_allocator_adaptor
+
+template <class ..._Allocs>
+class scoped_allocator_adaptor;
+
+template <class ..._Allocs> struct __get_poc_copy_assignment;
+
+template <class _A0>
+struct __get_poc_copy_assignment<_A0>
+{
+    static const bool value = allocator_traits<_A0>::
+                              propagate_on_container_copy_assignment::value;
+};
+
+template <class _A0, class ..._Allocs>
+struct __get_poc_copy_assignment<_A0, _Allocs...>
+{
+    static const bool value =
+        allocator_traits<_A0>::propagate_on_container_copy_assignment::value ||
+        __get_poc_copy_assignment<_Allocs...>::value;
+};
+
+template <class ..._Allocs> struct __get_poc_move_assignment;
+
+template <class _A0>
+struct __get_poc_move_assignment<_A0>
+{
+    static const bool value = allocator_traits<_A0>::
+                              propagate_on_container_move_assignment::value;
+};
+
+template <class _A0, class ..._Allocs>
+struct __get_poc_move_assignment<_A0, _Allocs...>
+{
+    static const bool value =
+        allocator_traits<_A0>::propagate_on_container_move_assignment::value ||
+        __get_poc_move_assignment<_Allocs...>::value;
+};
+
+template <class ..._Allocs> struct __get_poc_swap;
+
+template <class _A0>
+struct __get_poc_swap<_A0>
+{
+    static const bool value = allocator_traits<_A0>::
+                              propagate_on_container_swap::value;
+};
+
+template <class _A0, class ..._Allocs>
+struct __get_poc_swap<_A0, _Allocs...>
+{
+    static const bool value =
+        allocator_traits<_A0>::propagate_on_container_swap::value ||
+        __get_poc_swap<_Allocs...>::value;
+};
+
+template <class ..._Allocs>
+class __scoped_allocator_storage;
+
+template <class _OuterAlloc, class... _InnerAllocs>
+class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
+    : public _OuterAlloc
+{
+    typedef _OuterAlloc outer_allocator_type;
+protected:
+    typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type;
+
+private:
+    inner_allocator_type __inner_;
+
+protected:
+
+    _LIBCPP_INLINE_VISIBILITY
+    __scoped_allocator_storage() _NOEXCEPT {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(_OuterA2&& __outerAlloc,
+                                   const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
+            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)),
+              __inner_(__innerAllocs...) {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, const _OuterA2&>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(
+            const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
+            : outer_allocator_type(__other.outer_allocator()),
+              __inner_(__other.inner_allocator()) {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(
+            __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
+            : outer_allocator_type(_VSTD::move(__other.outer_allocator())),
+              __inner_(_VSTD::move(__other.inner_allocator())) {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(_OuterA2&& __o,
+                                   const inner_allocator_type& __i) _NOEXCEPT
+            : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)),
+              __inner_(__i)
+        {
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    inner_allocator_type& inner_allocator() _NOEXCEPT             {return __inner_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    outer_allocator_type& outer_allocator() _NOEXCEPT
+        {return static_cast<outer_allocator_type&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY
+    const outer_allocator_type& outer_allocator() const _NOEXCEPT
+        {return static_cast<const outer_allocator_type&>(*this);}
+
+    scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
+    _LIBCPP_INLINE_VISIBILITY
+    select_on_container_copy_construction() const _NOEXCEPT
+        {
+            return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>
+            (
+                allocator_traits<outer_allocator_type>::
+                    select_on_container_copy_construction(outer_allocator()),
+                allocator_traits<inner_allocator_type>::
+                    select_on_container_copy_construction(inner_allocator())
+            );
+        }
+
+    template <class...> friend class __scoped_allocator_storage;
+};
+
+template <class _OuterAlloc>
+class __scoped_allocator_storage<_OuterAlloc>
+    : public _OuterAlloc
+{
+    typedef _OuterAlloc outer_allocator_type;
+protected:
+    typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __scoped_allocator_storage() _NOEXCEPT {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT
+            : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, const _OuterA2&>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(
+            const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT
+            : outer_allocator_type(__other.outer_allocator()) {}
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        __scoped_allocator_storage(
+            __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT
+            : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    inner_allocator_type& inner_allocator() _NOEXCEPT
+        {return static_cast<inner_allocator_type&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY
+    const inner_allocator_type& inner_allocator() const _NOEXCEPT
+        {return static_cast<const inner_allocator_type&>(*this);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    outer_allocator_type& outer_allocator() _NOEXCEPT
+        {return static_cast<outer_allocator_type&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY
+    const outer_allocator_type& outer_allocator() const _NOEXCEPT
+        {return static_cast<const outer_allocator_type&>(*this);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    scoped_allocator_adaptor<outer_allocator_type>
+    select_on_container_copy_construction() const _NOEXCEPT
+        {return scoped_allocator_adaptor<outer_allocator_type>(
+            allocator_traits<outer_allocator_type>::
+                select_on_container_copy_construction(outer_allocator())
+        );}
+
+    __scoped_allocator_storage(const outer_allocator_type& __o,
+                               const inner_allocator_type& __i) _NOEXCEPT;
+
+    template <class...> friend class __scoped_allocator_storage;
+};
+
+// __outermost
+
+template <class _Alloc>
+decltype(declval<_Alloc>().outer_allocator(), true_type())
+__has_outer_allocator_test(_Alloc&& __a);
+
+template <class _Alloc>
+false_type
+__has_outer_allocator_test(const volatile _Alloc& __a);
+
+template <class _Alloc>
+struct __has_outer_allocator
+    : public common_type
+             <
+                 decltype(__has_outer_allocator_test(declval<_Alloc&>()))
+             >::type
+{
+};
+
+template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value>
+struct __outermost
+{
+    typedef _Alloc type;
+    _LIBCPP_INLINE_VISIBILITY
+    type& operator()(type& __a) const _NOEXCEPT {return __a;}
+};
+
+template <class _Alloc>
+struct __outermost<_Alloc, true>
+{
+    typedef typename remove_reference
+                     <
+                        decltype(_VSTD::declval<_Alloc>().outer_allocator())
+                     >::type                                    _OuterAlloc;
+    typedef typename __outermost<_OuterAlloc>::type             type;
+    _LIBCPP_INLINE_VISIBILITY
+    type& operator()(_Alloc& __a) const _NOEXCEPT
+        {return __outermost<_OuterAlloc>()(__a.outer_allocator());}
+};
+
+template <class _OuterAlloc, class... _InnerAllocs>
+class _LIBCPP_TYPE_VIS_ONLY scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>
+    : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...>
+{
+    typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base;
+    typedef allocator_traits<_OuterAlloc>             _OuterTraits;
+public:
+    typedef _OuterAlloc                               outer_allocator_type;
+    typedef typename base::inner_allocator_type       inner_allocator_type;
+    typedef typename _OuterTraits::size_type          size_type;
+    typedef typename _OuterTraits::difference_type    difference_type;
+    typedef typename _OuterTraits::pointer            pointer;
+    typedef typename _OuterTraits::const_pointer      const_pointer;
+    typedef typename _OuterTraits::void_pointer       void_pointer;
+    typedef typename _OuterTraits::const_void_pointer const_void_pointer;
+
+    typedef integral_constant
+            <
+                bool,
+                __get_poc_copy_assignment<outer_allocator_type,
+                                          _InnerAllocs...>::value
+            > propagate_on_container_copy_assignment;
+    typedef integral_constant
+            <
+                bool,
+                __get_poc_move_assignment<outer_allocator_type,
+                                          _InnerAllocs...>::value
+            > propagate_on_container_move_assignment;
+    typedef integral_constant
+            <
+                bool,
+                __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
+            > propagate_on_container_swap;
+
+    template <class _Tp>
+    struct rebind
+    {
+        typedef scoped_allocator_adaptor
+        <
+            typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs...
+        > other;
+    };
+
+    _LIBCPP_INLINE_VISIBILITY
+    scoped_allocator_adaptor() _NOEXCEPT {}
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        scoped_allocator_adaptor(_OuterA2&& __outerAlloc,
+                                 const _InnerAllocs& ...__innerAllocs) _NOEXCEPT
+            : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {}
+    // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default;
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, const _OuterA2&>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        scoped_allocator_adaptor(
+            const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT
+                : base(__other) {}
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+        _LIBCPP_INLINE_VISIBILITY
+        scoped_allocator_adaptor(
+            scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT
+                : base(_VSTD::move(__other)) {}
+
+    // ~scoped_allocator_adaptor() = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    inner_allocator_type& inner_allocator() _NOEXCEPT
+        {return base::inner_allocator();}
+    _LIBCPP_INLINE_VISIBILITY
+    const inner_allocator_type& inner_allocator() const _NOEXCEPT
+        {return base::inner_allocator();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    outer_allocator_type& outer_allocator() _NOEXCEPT
+        {return base::outer_allocator();}
+    _LIBCPP_INLINE_VISIBILITY
+    const outer_allocator_type& outer_allocator() const _NOEXCEPT
+        {return base::outer_allocator();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    pointer allocate(size_type __n)
+        {return allocator_traits<outer_allocator_type>::
+            allocate(outer_allocator(), __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer allocate(size_type __n, const_void_pointer __hint)
+        {return allocator_traits<outer_allocator_type>::
+            allocate(outer_allocator(), __n, __hint);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void deallocate(pointer __p, size_type __n) _NOEXCEPT
+        {allocator_traits<outer_allocator_type>::
+            deallocate(outer_allocator(), __p, __n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const
+        {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());}
+
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void construct(_Tp* __p, _Args&& ...__args)
+            {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(),
+                         __p, _VSTD::forward<_Args>(__args)...);}
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        void destroy(_Tp* __p)
+            {
+                typedef __outermost<outer_allocator_type> _OM;
+                allocator_traits<typename _OM::type>::
+                                         destroy(_OM()(outer_allocator()), __p);
+            }
+
+    _LIBCPP_INLINE_VISIBILITY
+    scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT
+        {return base::select_on_container_copy_construction();}
+
+private:
+
+    template <class _OuterA2,
+              class = typename enable_if<
+                        is_constructible<outer_allocator_type, _OuterA2>::value
+                      >::type>
+    _LIBCPP_INLINE_VISIBILITY
+    scoped_allocator_adaptor(_OuterA2&& __o,
+                             const inner_allocator_type& __i) _NOEXCEPT
+        : base(_VSTD::forward<_OuterA2>(__o), __i) {}
+
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args)
+            {
+                typedef __outermost<outer_allocator_type> _OM;
+                allocator_traits<typename _OM::type>::construct
+                (
+                    _OM()(outer_allocator()),
+                    __p,
+                    _VSTD::forward<_Args>(__args)...
+                );
+            }
+
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args)
+            {
+                typedef __outermost<outer_allocator_type> _OM;
+                allocator_traits<typename _OM::type>::construct
+                (
+                    _OM()(outer_allocator()),
+                    __p,
+                    allocator_arg,
+                    inner_allocator(),
+                    _VSTD::forward<_Args>(__args)...
+                );
+            }
+
+    template <class _Tp, class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args)
+            {
+                typedef __outermost<outer_allocator_type> _OM;
+                allocator_traits<typename _OM::type>::construct
+                (
+                    _OM()(outer_allocator()),
+                    __p,
+                    _VSTD::forward<_Args>(__args)...,
+                    inner_allocator()
+                );
+            }
+
+    template <class...> friend class __scoped_allocator_storage;
+};
+
+template <class _OuterA1, class _OuterA2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const scoped_allocator_adaptor<_OuterA1>& __a,
+           const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT
+{
+    return __a.outer_allocator() == __b.outer_allocator();
+}
+
+template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a,
+           const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT
+{
+    return __a.outer_allocator() == __b.outer_allocator() &&
+           __a.inner_allocator() == __b.inner_allocator();
+}
+
+template <class _OuterA1, class _OuterA2, class... _InnerAllocs>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a,
+           const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT
+{
+    return !(__a == __b);
+}
+
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_SCOPED_ALLOCATOR
diff --git a/include/c++/v1/set b/include/c++/v1/set
new file mode 100644
index 0000000..b9e776d
--- /dev/null
+++ b/include/c++/v1/set
@@ -0,0 +1,1205 @@
+// -*- C++ -*-
+//===---------------------------- set -------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SET
+#define _LIBCPP_SET
+
+/*
+
+    set synopsis
+
+namespace std
+{
+
+template <class Key, class Compare = less<Key>,
+          class Allocator = allocator<Key>>
+class set
+{
+public:
+    // types:
+    typedef Key                                      key_type;
+    typedef key_type                                 value_type;
+    typedef Compare                                  key_compare;
+    typedef key_compare                              value_compare;
+    typedef Allocator                                allocator_type;
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    // construct/copy/destroy:
+    set()
+        noexcept(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value);
+    explicit set(const value_compare& comp);
+    set(const value_compare& comp, const allocator_type& a);
+    template <class InputIterator>
+        set(InputIterator first, InputIterator last,
+            const value_compare& comp = value_compare());
+    template <class InputIterator>
+        set(InputIterator first, InputIterator last, const value_compare& comp,
+            const allocator_type& a);
+    set(const set& s);
+    set(set&& s)
+        noexcept(
+            is_nothrow_move_constructible<allocator_type>::value &&
+            is_nothrow_move_constructible<key_compare>::value);
+    explicit set(const allocator_type& a);
+    set(const set& s, const allocator_type& a);
+    set(set&& s, const allocator_type& a);
+    set(initializer_list<value_type> il, const value_compare& comp = value_compare());
+    set(initializer_list<value_type> il, const value_compare& comp,
+        const allocator_type& a);
+    template <class InputIterator>
+        set(InputIterator first, InputIterator last, const allocator_type& a)
+            : set(first, last, Compare(), a) {}  // C++14
+    set(initializer_list<value_type> il, const allocator_type& a)
+        : set(il, Compare(), a) {}  // C++14
+    ~set();
+
+    set& operator=(const set& s);
+    set& operator=(set&& s)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<key_compare>::value);
+    set& operator=(initializer_list<value_type> il);
+
+    // iterators:
+          iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+          iterator end() noexcept;
+    const_iterator end()   const noexcept;
+
+          reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+          reverse_iterator rend() noexcept;
+    const_reverse_iterator rend()   const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    bool      empty()    const noexcept;
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+
+    // modifiers:
+    template <class... Args>
+        pair<iterator, bool> emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    pair<iterator,bool> insert(const value_type& v);
+    pair<iterator,bool> insert(value_type&& v);
+    iterator insert(const_iterator position, const value_type& v);
+    iterator insert(const_iterator position, value_type&& v);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type> il);
+
+    iterator  erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator  erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(set& s)
+        noexcept(
+            __is_nothrow_swappable<key_compare>::value &&
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value));
+
+    // observers:
+    allocator_type get_allocator() const noexcept;
+    key_compare    key_comp()      const;
+    value_compare  value_comp()    const;
+
+    // set operations:
+          iterator find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+    template<typename K>
+      size_type count(const K& x) const;        // C++14
+
+    size_type      count(const key_type& k) const;
+          iterator lower_bound(const key_type& k);
+    const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
+          iterator upper_bound(const key_type& k);
+    const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+    pair<iterator,iterator>             equal_range(const key_type& k);
+    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
+};
+
+template <class Key, class Compare, class Allocator>
+bool
+operator==(const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator< (const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator!=(const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator> (const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator>=(const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator<=(const set<Key, Compare, Allocator>& x,
+           const set<Key, Compare, Allocator>& y);
+
+// specialized algorithms:
+template <class Key, class Compare, class Allocator>
+void
+swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
+    noexcept(noexcept(x.swap(y)));
+
+template <class Key, class Compare = less<Key>,
+          class Allocator = allocator<Key>>
+class multiset
+{
+public:
+    // types:
+    typedef Key                                      key_type;
+    typedef key_type                                 value_type;
+    typedef Compare                                  key_compare;
+    typedef key_compare                              value_compare;
+    typedef Allocator                                allocator_type;
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    // construct/copy/destroy:
+    multiset()
+        noexcept(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value);
+    explicit multiset(const value_compare& comp);
+    multiset(const value_compare& comp, const allocator_type& a);
+    template <class InputIterator>
+        multiset(InputIterator first, InputIterator last,
+                 const value_compare& comp = value_compare());
+    template <class InputIterator>
+        multiset(InputIterator first, InputIterator last,
+                 const value_compare& comp, const allocator_type& a);
+    multiset(const multiset& s);
+    multiset(multiset&& s)
+        noexcept(
+            is_nothrow_move_constructible<allocator_type>::value &&
+            is_nothrow_move_constructible<key_compare>::value);
+    explicit multiset(const allocator_type& a);
+    multiset(const multiset& s, const allocator_type& a);
+    multiset(multiset&& s, const allocator_type& a);
+    multiset(initializer_list<value_type> il, const value_compare& comp = value_compare());
+    multiset(initializer_list<value_type> il, const value_compare& comp,
+             const allocator_type& a);
+    template <class InputIterator>
+        multiset(InputIterator first, InputIterator last, const allocator_type& a)
+            : set(first, last, Compare(), a) {}  // C++14
+    multiset(initializer_list<value_type> il, const allocator_type& a)
+        : set(il, Compare(), a) {}  // C++14
+    ~multiset();
+
+    multiset& operator=(const multiset& s);
+    multiset& operator=(multiset&& s)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<key_compare>::value);
+    multiset& operator=(initializer_list<value_type> il);
+
+    // iterators:
+          iterator begin() noexcept;
+    const_iterator begin() const noexcept;
+          iterator end() noexcept;
+    const_iterator end()   const noexcept;
+
+          reverse_iterator rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+          reverse_iterator rend() noexcept;
+    const_reverse_iterator rend()   const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    // capacity:
+    bool      empty()    const noexcept;
+    size_type size()     const noexcept;
+    size_type max_size() const noexcept;
+
+    // modifiers:
+    template <class... Args>
+        iterator emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    iterator insert(const value_type& v);
+    iterator insert(value_type&& v);
+    iterator insert(const_iterator position, const value_type& v);
+    iterator insert(const_iterator position, value_type&& v);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type> il);
+
+    iterator  erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator  erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(multiset& s)
+        noexcept(
+            __is_nothrow_swappable<key_compare>::value &&
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value));
+
+    // observers:
+    allocator_type get_allocator() const noexcept;
+    key_compare    key_comp()      const;
+    value_compare  value_comp()    const;
+
+    // set operations:
+          iterator find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    template<typename K>
+        iterator find(const K& x);
+    template<typename K>
+        const_iterator find(const K& x) const;  // C++14
+
+    size_type      count(const key_type& k) const;
+          iterator lower_bound(const key_type& k);
+    const_iterator lower_bound(const key_type& k) const;
+    template<typename K>
+        iterator lower_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator lower_bound(const K& x) const;  // C++14
+
+          iterator upper_bound(const key_type& k);
+    const_iterator upper_bound(const key_type& k) const;
+    template<typename K>
+        iterator upper_bound(const K& x);              // C++14
+    template<typename K>
+        const_iterator upper_bound(const K& x) const;  // C++14
+
+    pair<iterator,iterator>             equal_range(const key_type& k);
+    pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+    template<typename K>
+        pair<iterator,iterator>             equal_range(const K& x);        // C++14
+    template<typename K>
+        pair<const_iterator,const_iterator> equal_range(const K& x) const;  // C++14
+};
+
+template <class Key, class Compare, class Allocator>
+bool
+operator==(const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator< (const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator!=(const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator> (const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator>=(const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+template <class Key, class Compare, class Allocator>
+bool
+operator<=(const multiset<Key, Compare, Allocator>& x,
+           const multiset<Key, Compare, Allocator>& y);
+
+// specialized algorithms:
+template <class Key, class Compare, class Allocator>
+void
+swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
+    noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__tree>
+#include <functional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key, class _Compare = less<_Key>,
+          class _Allocator = allocator<_Key> >
+class _LIBCPP_TYPE_VIS_ONLY set
+{
+public:
+    // types:
+    typedef _Key                                     key_type;
+    typedef key_type                                 value_type;
+    typedef _Compare                                 key_compare;
+    typedef key_compare                              value_compare;
+    typedef _Allocator                               allocator_type;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+
+private:
+    typedef __tree<value_type, value_compare, allocator_type> __base;
+    typedef allocator_traits<allocator_type>                  __alloc_traits;
+    typedef typename __base::__node_holder                    __node_holder;
+
+    __base __tree_;
+
+public:
+    typedef typename __base::pointer               pointer;
+    typedef typename __base::const_pointer         const_pointer;
+    typedef typename __base::size_type             size_type;
+    typedef typename __base::difference_type       difference_type;
+    typedef typename __base::const_iterator        iterator;
+    typedef typename __base::const_iterator        const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    set()
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(value_compare()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit set(const value_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__comp) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit set(const value_compare& __comp, const allocator_type& __a)
+        : __tree_(__comp, __a) {}
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        set(_InputIterator __f, _InputIterator __l,
+            const value_compare& __comp = value_compare())
+        : __tree_(__comp)
+        {
+            insert(__f, __l);
+        }
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        set(_InputIterator __f, _InputIterator __l, const value_compare& __comp,
+            const allocator_type& __a)
+        : __tree_(__comp, __a)
+        {
+            insert(__f, __l);
+        }
+
+#if _LIBCPP_STD_VER > 11
+        template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY 
+        set(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+            : set(__f, __l, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    set(const set& __s)
+        : __tree_(__s.__tree_)
+        {
+            insert(__s.begin(), __s.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    set& operator=(const set& __s)
+        {
+            __tree_ = __s.__tree_;
+            return *this;
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    set(set&& __s)
+        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
+        : __tree_(_VSTD::move(__s.__tree_)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit set(const allocator_type& __a)
+        : __tree_(__a) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    set(const set& __s, const allocator_type& __a)
+        : __tree_(__s.__tree_.value_comp(), __a)
+        {
+            insert(__s.begin(), __s.end());
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    set(set&& __s, const allocator_type& __a);
+#endif
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    set(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
+        : __tree_(__comp)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    set(initializer_list<value_type> __il, const value_compare& __comp,
+        const allocator_type& __a)
+        : __tree_(__comp, __a)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    set(initializer_list<value_type> __il, const allocator_type& __a)
+        : set(__il, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    set& operator=(initializer_list<value_type> __il)
+        {
+            __tree_.__assign_unique(__il.begin(), __il.end());
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    set& operator=(set&& __s)
+        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
+        {
+            __tree_ = _VSTD::move(__s.__tree_);
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin() _NOEXCEPT       {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT         {return __tree_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()   const _NOEXCEPT {return __tree_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rbegin() _NOEXCEPT
+            {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rend() _NOEXCEPT
+            {return reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin()  const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT {return __tree_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
+
+    // modifiers:
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        pair<iterator, bool> emplace(_Args&&... __args)
+            {return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+            {return __tree_.__emplace_hint_unique(__p, _VSTD::forward<_Args>(__args)...);}
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,bool> insert(const value_type& __v)
+        {return __tree_.__insert_unique(__v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,bool> insert(value_type&& __v)
+        {return __tree_.__insert_unique(_VSTD::move(__v));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, const value_type& __v)
+        {return __tree_.__insert_unique(__p, __v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, value_type&& __v)
+        {return __tree_.__insert_unique(__p, _VSTD::move(__v));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        void insert(_InputIterator __f, _InputIterator __l)
+        {
+            for (const_iterator __e = cend(); __f != __l; ++__f)
+                __tree_.__insert_unique(__e, *__f);
+        }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __p) {return __tree_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k)
+        {return __tree_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __f, const_iterator __l)
+        {return __tree_.erase(__f, __l);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__tree_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(set& __s) _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
+        {__tree_.swap(__s.__tree_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_compare    key_comp()      const {return __tree_.value_comp();}
+    _LIBCPP_INLINE_VISIBILITY
+    value_compare  value_comp()    const {return __tree_.value_comp();}
+
+    // set operations:
+    _LIBCPP_INLINE_VISIBILITY
+    iterator find(const key_type& __k)             {return __tree_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type      count(const key_type& __k) const
+        {return __tree_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator lower_bound(const key_type& __k)
+        {return __tree_.lower_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator lower_bound(const key_type& __k) const
+        {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator upper_bound(const key_type& __k)
+        {return __tree_.upper_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator upper_bound(const key_type& __k) const
+        {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,iterator> equal_range(const key_type& __k)
+        {return __tree_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
+        {return __tree_.__equal_range_unique(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_unique(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+#endif
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Compare, class _Allocator>
+set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a)
+    : __tree_(_VSTD::move(__s.__tree_), __a)
+{
+    if (__a != __s.get_allocator())
+    {
+        const_iterator __e = cend();
+        while (!__s.empty())
+            insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const set<_Key, _Compare, _Allocator>& __x,
+           const set<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+// specialized algorithms:
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(set<_Key, _Compare, _Allocator>& __x,
+     set<_Key, _Compare, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Compare = less<_Key>,
+          class _Allocator = allocator<_Key> >
+class _LIBCPP_TYPE_VIS_ONLY multiset
+{
+public:
+    // types:
+    typedef _Key                                      key_type;
+    typedef key_type                                 value_type;
+    typedef _Compare                                  key_compare;
+    typedef key_compare                              value_compare;
+    typedef _Allocator                                allocator_type;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+
+private:
+    typedef __tree<value_type, value_compare, allocator_type> __base;
+    typedef allocator_traits<allocator_type>                  __alloc_traits;
+    typedef typename __base::__node_holder                    __node_holder;
+
+    __base __tree_;
+
+public:
+    typedef typename __base::pointer               pointer;
+    typedef typename __base::const_pointer         const_pointer;
+    typedef typename __base::size_type             size_type;
+    typedef typename __base::difference_type       difference_type;
+    typedef typename __base::const_iterator        iterator;
+    typedef typename __base::const_iterator        const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    // construct/copy/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    multiset()
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_default_constructible<key_compare>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(value_compare()) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multiset(const value_compare& __comp)
+        _NOEXCEPT_(
+            is_nothrow_default_constructible<allocator_type>::value &&
+            is_nothrow_copy_constructible<key_compare>::value)
+        : __tree_(__comp) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multiset(const value_compare& __comp, const allocator_type& __a)
+        : __tree_(__comp, __a) {}
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        multiset(_InputIterator __f, _InputIterator __l,
+                 const value_compare& __comp = value_compare())
+        : __tree_(__comp)
+        {
+            insert(__f, __l);
+        }
+
+#if _LIBCPP_STD_VER > 11
+        template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY 
+        multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+            : multiset(__f, __l, key_compare(), __a) {}
+#endif
+
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        multiset(_InputIterator __f, _InputIterator __l,
+                 const value_compare& __comp, const allocator_type& __a)
+        : __tree_(__comp, __a)
+        {
+            insert(__f, __l);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multiset(const multiset& __s)
+        : __tree_(__s.__tree_.value_comp(),
+          __alloc_traits::select_on_container_copy_construction(__s.__tree_.__alloc()))
+        {
+            insert(__s.begin(), __s.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multiset& operator=(const multiset& __s)
+        {
+            __tree_ = __s.__tree_;
+            return *this;
+        }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    multiset(multiset&& __s)
+        _NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
+        : __tree_(_VSTD::move(__s.__tree_)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit multiset(const allocator_type& __a)
+        : __tree_(__a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    multiset(const multiset& __s, const allocator_type& __a)
+        : __tree_(__s.__tree_.value_comp(), __a)
+        {
+            insert(__s.begin(), __s.end());
+        }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    multiset(multiset&& __s, const allocator_type& __a);
+#endif
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    multiset(initializer_list<value_type> __il, const value_compare& __comp = value_compare())
+        : __tree_(__comp)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    multiset(initializer_list<value_type> __il, const value_compare& __comp,
+        const allocator_type& __a)
+        : __tree_(__comp, __a)
+        {
+            insert(__il.begin(), __il.end());
+        }
+
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY 
+    multiset(initializer_list<value_type> __il, const allocator_type& __a)
+        : multiset(__il, key_compare(), __a) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    multiset& operator=(initializer_list<value_type> __il)
+        {
+            __tree_.__assign_multi(__il.begin(), __il.end());
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    multiset& operator=(multiset&& __s)
+        _NOEXCEPT_(is_nothrow_move_assignable<__base>::value)
+        {
+            __tree_ = _VSTD::move(__s.__tree_);
+            return *this;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+          iterator begin() _NOEXCEPT       {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT {return __tree_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+          iterator end() _NOEXCEPT         {return __tree_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()   const _NOEXCEPT {return __tree_.end();}
+
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rbegin() _NOEXCEPT
+            {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+          reverse_iterator rend() _NOEXCEPT
+            {return       reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin()  const _NOEXCEPT {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT {return __tree_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT {return __tree_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __tree_.max_size();}
+
+    // modifiers:
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator emplace(_Args&&... __args)
+            {return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+            {return __tree_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __v)
+        {return __tree_.__insert_multi(__v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(value_type&& __v)
+        {return __tree_.__insert_multi(_VSTD::move(__v));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, const value_type& __v)
+        {return __tree_.__insert_multi(__p, __v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, value_type&& __v)
+        {return __tree_.__insert_multi(_VSTD::move(__v));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        void insert(_InputIterator __f, _InputIterator __l)
+        {
+            for (const_iterator __e = cend(); __f != __l; ++__f)
+                __tree_.__insert_multi(__e, *__f);
+        }
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __p) {return __tree_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator  erase(const_iterator __f, const_iterator __l)
+        {return __tree_.erase(__f, __l);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__tree_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(multiset& __s)
+        _NOEXCEPT_(__is_nothrow_swappable<__base>::value)
+        {__tree_.swap(__s.__tree_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_compare    key_comp()      const {return __tree_.value_comp();}
+    _LIBCPP_INLINE_VISIBILITY
+    value_compare  value_comp()    const {return __tree_.value_comp();}
+
+    // set operations:
+    _LIBCPP_INLINE_VISIBILITY
+    iterator find(const key_type& __k)             {return __tree_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __tree_.find(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    find(const _K2& __k)                           {return __tree_.find(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    find(const _K2& __k) const                     {return __tree_.find(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type      count(const key_type& __k) const
+        {return __tree_.__count_multi(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator lower_bound(const key_type& __k)
+        {return __tree_.lower_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator lower_bound(const key_type& __k) const
+            {return __tree_.lower_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    lower_bound(const _K2& __k)       {return __tree_.lower_bound(__k);}
+
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator upper_bound(const key_type& __k)
+            {return __tree_.upper_bound(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator upper_bound(const key_type& __k) const
+            {return __tree_.upper_bound(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type
+    upper_bound(const _K2& __k)       {return __tree_.upper_bound(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type
+    upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator,iterator>             equal_range(const key_type& __k)
+            {return __tree_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
+            {return __tree_.__equal_range_multi(__k);}
+#if _LIBCPP_STD_VER > 11
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
+    equal_range(const _K2& __k)       {return __tree_.__equal_range_multi(__k);}
+    template <typename _K2>
+    _LIBCPP_INLINE_VISIBILITY
+    typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
+    equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
+#endif
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Compare, class _Allocator>
+multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_type& __a)
+    : __tree_(_VSTD::move(__s.__tree_), __a)
+{
+    if (__a != __s.get_allocator())
+    {
+        const_iterator __e = cend();
+        while (!__s.empty())
+            insert(__e, _VSTD::move(__s.__tree_.remove(__s.begin())->__value_));
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const multiset<_Key, _Compare, _Allocator>& __x,
+           const multiset<_Key, _Compare, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Key, class _Compare, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(multiset<_Key, _Compare, _Allocator>& __x,
+     multiset<_Key, _Compare, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_SET
diff --git a/include/c++/v1/shared_mutex b/include/c++/v1/shared_mutex
new file mode 100644
index 0000000..7661054
--- /dev/null
+++ b/include/c++/v1/shared_mutex
@@ -0,0 +1,419 @@
+// -*- C++ -*-
+//===------------------------ shared_mutex --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SHARED_MUTEX
+#define _LIBCPP_SHARED_MUTEX
+
+/*
+    shared_mutex synopsis
+
+// C++1y
+
+namespace std
+{
+
+class shared_timed_mutex
+{
+public:
+    shared_timed_mutex();
+    ~shared_timed_mutex();
+
+    shared_timed_mutex(const shared_timed_mutex&) = delete;
+    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+    // Exclusive ownership
+    void lock(); // blocking
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Shared ownership
+    void lock_shared(); // blocking
+    bool try_lock_shared();
+    template <class Rep, class Period>
+        bool
+        try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool
+        try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock_shared();
+};
+
+template <class Mutex>
+class shared_lock
+{
+public:
+    typedef Mutex mutex_type;
+
+    // Shared locking
+    shared_lock() noexcept;
+    explicit shared_lock(mutex_type& m); // blocking
+    shared_lock(mutex_type& m, defer_lock_t) noexcept;
+    shared_lock(mutex_type& m, try_to_lock_t);
+    shared_lock(mutex_type& m, adopt_lock_t);
+    template <class Clock, class Duration>
+        shared_lock(mutex_type& m,
+                    const chrono::time_point<Clock, Duration>& abs_time);
+    template <class Rep, class Period>
+        shared_lock(mutex_type& m,
+                    const chrono::duration<Rep, Period>& rel_time);
+    ~shared_lock();
+
+    shared_lock(shared_lock const&) = delete;
+    shared_lock& operator=(shared_lock const&) = delete;
+
+    shared_lock(shared_lock&& u) noexcept;
+    shared_lock& operator=(shared_lock&& u) noexcept;
+
+    void lock(); // blocking
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Setters
+    void swap(shared_lock& u) noexcept;
+    mutex_type* release() noexcept;
+
+    // Getters
+    bool owns_lock() const noexcept;
+    explicit operator bool () const noexcept;
+    mutex_type* mutex() const noexcept;
+};
+
+template <class Mutex>
+    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
+
+}  // std
+
+*/
+
+#include <__config>
+
+#if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_SHARED_MUTEX)
+
+#include <__mutex_base>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS shared_timed_mutex
+{
+    mutex               __mut_;
+    condition_variable  __gate1_;
+    condition_variable  __gate2_;
+    unsigned            __state_;
+
+    static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
+    static const unsigned __n_readers_ = ~__write_entered_;
+public:
+    shared_timed_mutex();
+    _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
+
+    shared_timed_mutex(const shared_timed_mutex&) = delete;
+    shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+    // Exclusive ownership
+    void lock();
+    bool try_lock();
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool
+        try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+        {
+            return try_lock_until(chrono::steady_clock::now() + __rel_time);
+        }
+    template <class _Clock, class _Duration>
+        bool
+        try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
+    void unlock();
+
+    // Shared ownership
+    void lock_shared();
+    bool try_lock_shared();
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        bool
+        try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
+        {
+            return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
+        }
+    template <class _Clock, class _Duration>
+        bool
+        try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time);
+    void unlock_shared();
+};
+
+template <class _Clock, class _Duration>
+bool
+shared_timed_mutex::try_lock_until(
+                        const chrono::time_point<_Clock, _Duration>& __abs_time)
+{
+    unique_lock<mutex> __lk(__mut_);
+    if (__state_ & __write_entered_)
+    {
+        while (true)
+        {
+            cv_status __status = __gate1_.wait_until(__lk, __abs_time);
+            if ((__state_ & __write_entered_) == 0)
+                break;
+            if (__status == cv_status::timeout)
+                return false;
+        }
+    }
+    __state_ |= __write_entered_;
+    if (__state_ & __n_readers_)
+    {
+        while (true)
+        {
+            cv_status __status = __gate2_.wait_until(__lk, __abs_time);
+            if ((__state_ & __n_readers_) == 0)
+                break;
+            if (__status == cv_status::timeout)
+            {
+                __state_ &= ~__write_entered_;
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+template <class _Clock, class _Duration>
+bool
+shared_timed_mutex::try_lock_shared_until(
+                        const chrono::time_point<_Clock, _Duration>& __abs_time)
+{
+    unique_lock<mutex> __lk(__mut_);
+    if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+    {
+        while (true)
+        {
+            cv_status status = __gate1_.wait_until(__lk, __abs_time);
+            if ((__state_ & __write_entered_) == 0 &&
+                                       (__state_ & __n_readers_) < __n_readers_)
+                break;
+            if (status == cv_status::timeout)
+                return false;
+        }
+    }
+    unsigned __num_readers = (__state_ & __n_readers_) + 1;
+    __state_ &= ~__n_readers_;
+    __state_ |= __num_readers;
+    return true;
+}
+
+template <class _Mutex>
+class shared_lock
+{
+public:
+    typedef _Mutex mutex_type;
+
+private:
+    mutex_type* __m_;
+    bool __owns_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock() noexcept
+        : __m_(nullptr),
+          __owns_(false)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit shared_lock(mutex_type& __m)
+        : __m_(&__m),
+          __owns_(true)
+        {__m_->lock_shared();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, defer_lock_t) noexcept
+        : __m_(&__m),
+          __owns_(false)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, try_to_lock_t)
+        : __m_(&__m),
+          __owns_(__m.try_lock_shared())
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(mutex_type& __m, adopt_lock_t)
+        : __m_(&__m),
+          __owns_(true)
+        {}
+
+    template <class _Clock, class _Duration>
+        _LIBCPP_INLINE_VISIBILITY
+        shared_lock(mutex_type& __m,
+                    const chrono::time_point<_Clock, _Duration>& __abs_time)
+            : __m_(&__m),
+              __owns_(__m.try_lock_shared_until(__abs_time))
+            {}
+
+    template <class _Rep, class _Period>
+        _LIBCPP_INLINE_VISIBILITY
+        shared_lock(mutex_type& __m,
+                    const chrono::duration<_Rep, _Period>& __rel_time)
+            : __m_(&__m),
+              __owns_(__m.try_lock_shared_for(__rel_time))
+            {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~shared_lock()
+    {
+        if (__owns_)
+            __m_->unlock_shared();
+    }
+
+    shared_lock(shared_lock const&) = delete;
+    shared_lock& operator=(shared_lock const&) = delete;
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock(shared_lock&& __u) noexcept
+        : __m_(__u.__m_),
+          __owns_(__u.__owns_)
+        {
+            __u.__m_ = nullptr;
+            __u.__owns_ = false;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    shared_lock& operator=(shared_lock&& __u) noexcept
+    {
+        if (__owns_)
+            __m_->unlock_shared();
+        __m_ = nullptr;
+        __owns_ = false;
+        __m_ = __u.__m_;
+        __owns_ = __u.__owns_;
+        __u.__m_ = nullptr;
+        __u.__owns_ = false;
+        return *this;
+    }
+
+    void lock();
+    bool try_lock();
+    template <class Rep, class Period>
+        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+    template <class Clock, class Duration>
+        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+    void unlock();
+
+    // Setters
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(shared_lock& __u) noexcept
+    {
+        _VSTD::swap(__m_, __u.__m_);
+        _VSTD::swap(__owns_, __u.__owns_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* release() noexcept
+    {
+        mutex_type* __m = __m_;
+        __m_ = nullptr;
+        __owns_ = false;
+        return __m;
+    }
+
+    // Getters
+    _LIBCPP_INLINE_VISIBILITY
+    bool owns_lock() const noexcept {return __owns_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit operator bool () const noexcept {return __owns_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    mutex_type* mutex() const noexcept {return __m_;}
+};
+
+template <class _Mutex>
+void
+shared_lock<_Mutex>::lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::lock: already locked");
+    __m_->lock_shared();
+    __owns_ = true;
+}
+
+template <class _Mutex>
+bool
+shared_lock<_Mutex>::try_lock()
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked");
+    __owns_ = __m_->try_lock_shared();
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Rep, class _Period>
+bool
+shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked");
+    __owns_ = __m_->try_lock_shared_for(__d);
+    return __owns_;
+}
+
+template <class _Mutex>
+template <class _Clock, class _Duration>
+bool
+shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    if (__m_ == nullptr)
+        __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex");
+    if (__owns_)
+        __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked");
+    __owns_ = __m_->try_lock_shared_until(__t);
+    return __owns_;
+}
+
+template <class _Mutex>
+void
+shared_lock<_Mutex>::unlock()
+{
+    if (!__owns_)
+        __throw_system_error(EPERM, "shared_lock::unlock: not locked");
+    __m_->unlock_shared();
+    __owns_ = false;
+}
+
+template <class _Mutex>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept
+    {__x.swap(__y);}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STD_VER > 11
+
+#endif  // _LIBCPP_SHARED_MUTEX
diff --git a/include/c++/v1/sstream b/include/c++/v1/sstream
new file mode 100644
index 0000000..f90d446
--- /dev/null
+++ b/include/c++/v1/sstream
@@ -0,0 +1,972 @@
+// -*- C++ -*-
+//===--------------------------- sstream ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SSTREAM
+#define _LIBCPP_SSTREAM
+
+/*
+    sstream synopsis
+
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+class basic_stringbuf
+    : public basic_streambuf<charT, traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef Allocator                      allocator_type;
+
+    // 27.8.1.1 Constructors:
+    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out);
+    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    basic_stringbuf(basic_stringbuf&& rhs);
+
+    // 27.8.1.2 Assign and swap:
+    basic_stringbuf& operator=(basic_stringbuf&& rhs);
+    void swap(basic_stringbuf& rhs);
+
+    // 27.8.1.3 Get and set:
+    basic_string<char_type, traits_type, allocator_type> str() const;
+    void str(const basic_string<char_type, traits_type, allocator_type>& s);
+
+protected:
+    // 27.8.1.4 Overridden virtual functions:
+    virtual int_type underflow();
+    virtual int_type pbackfail(int_type c = traits_type::eof());
+    virtual int_type overflow (int_type c = traits_type::eof());
+    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);
+    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type sp,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+};
+
+template <class charT, class traits, class Allocator>
+  void swap(basic_stringbuf<charT, traits, Allocator>& x,
+            basic_stringbuf<charT, traits, Allocator>& y);
+
+typedef basic_stringbuf<char>    stringbuf;
+typedef basic_stringbuf<wchar_t> wstringbuf;
+
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+class basic_istringstream
+    : public basic_istream<charT, traits>
+{
+public:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef Allocator                      allocator_type;
+
+    // 27.8.2.1 Constructors:
+    explicit basic_istringstream(ios_base::openmode which = ios_base::in);
+    explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
+                                 ios_base::openmode which = ios_base::in);
+    basic_istringstream(basic_istringstream&& rhs);
+
+    // 27.8.2.2 Assign and swap:
+    basic_istringstream& operator=(basic_istringstream&& rhs);
+    void swap(basic_istringstream& rhs);
+
+    // 27.8.2.3 Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    basic_string<char_type, traits_type, allocator_type> str() const;
+    void str(const basic_string<char_type, traits_type, allocator_type>& s);
+};
+
+template <class charT, class traits, class Allocator>
+  void swap(basic_istringstream<charT, traits, Allocator>& x,
+            basic_istringstream<charT, traits, Allocator>& y);
+
+typedef basic_istringstream<char>    istringstream;
+typedef basic_istringstream<wchar_t> wistringstream;
+
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+class basic_ostringstream
+    : public basic_ostream<charT, traits>
+{
+public:
+    // types:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef Allocator                      allocator_type;
+
+    // 27.8.3.1 Constructors/destructor:
+    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);
+    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,
+                                 ios_base::openmode which = ios_base::out);
+    basic_ostringstream(basic_ostringstream&& rhs);
+
+    // 27.8.3.2 Assign/swap:
+    basic_ostringstream& operator=(basic_ostringstream&& rhs);
+    void swap(basic_ostringstream& rhs);
+
+    // 27.8.3.3 Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    basic_string<char_type, traits_type, allocator_type> str() const;
+    void str(const basic_string<char_type, traits_type, allocator_type>& s);
+};
+
+template <class charT, class traits, class Allocator>
+  void swap(basic_ostringstream<charT, traits, Allocator>& x,
+            basic_ostringstream<charT, traits, Allocator>& y);
+
+typedef basic_ostringstream<char>    ostringstream;
+typedef basic_ostringstream<wchar_t> wostringstream;
+
+template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+class basic_stringstream
+    : public basic_iostream<charT, traits>
+{
+public:
+    // types:
+    typedef charT                          char_type;
+    typedef traits                         traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef Allocator                      allocator_type;
+
+    // constructors/destructor
+    explicit basic_stringstream(ios_base::openmode which = ios_base::out|ios_base::in);
+    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,
+                                ios_base::openmode which = ios_base::out|ios_base::in);
+    basic_stringstream(basic_stringstream&& rhs);
+
+    // 27.8.5.1 Assign/swap:
+    basic_stringstream& operator=(basic_stringstream&& rhs);
+    void swap(basic_stringstream& rhs);
+
+    // Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    basic_string<char_type, traits_type, allocator_type> str() const;
+    void str(const basic_string<char_type, traits_type, allocator_type>& str);
+};
+
+template <class charT, class traits, class Allocator>
+  void swap(basic_stringstream<charT, traits, Allocator>& x,
+            basic_stringstream<charT, traits, Allocator>& y);
+
+typedef basic_stringstream<char>    stringstream;
+typedef basic_stringstream<wchar_t> wstringstream;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ostream>
+#include <istream>
+#include <string>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// basic_stringbuf
+
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY basic_stringbuf
+    : public basic_streambuf<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef _Allocator                     allocator_type;
+
+    typedef basic_string<char_type, traits_type, allocator_type> string_type;
+
+private:
+
+    string_type __str_;
+    mutable char_type* __hm_;
+    ios_base::openmode __mode_;
+
+public:
+    // 27.8.1.1 Constructors:
+    explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in | ios_base::out);
+    explicit basic_stringbuf(const string_type& __s,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_stringbuf(basic_stringbuf&& __rhs);
+#endif
+
+    // 27.8.1.2 Assign and swap:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_stringbuf& operator=(basic_stringbuf&& __rhs);
+#endif
+    void swap(basic_stringbuf& __rhs);
+
+    // 27.8.1.3 Get and set:
+    string_type str() const;
+    void str(const string_type& __s);
+
+protected:
+    // 27.8.1.4 Overridden virtual functions:
+    virtual int_type underflow();
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
+    virtual int_type overflow (int_type __c = traits_type::eof());
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __wch = ios_base::in | ios_base::out);
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(ios_base::openmode __wch)
+    : __hm_(0),
+      __mode_(__wch)
+{
+    str(string_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(const string_type& __s,
+                             ios_base::openmode __wch)
+    : __hm_(0),
+      __mode_(__wch)
+{
+    str(__s);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
+    : __mode_(__rhs.__mode_)
+{
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __binp = -1;
+    ptrdiff_t __ninp = -1;
+    ptrdiff_t __einp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __binp = __rhs.eback() - __p;
+        __ninp = __rhs.gptr() - __p;
+        __einp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __bout = -1;
+    ptrdiff_t __nout = -1;
+    ptrdiff_t __eout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __bout = __rhs.pbase() - __p;
+        __nout = __rhs.pptr() - __p;
+        __eout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
+    __str_ = _VSTD::move(__rhs.__str_);
+    __p = const_cast<char_type*>(__str_.data());
+    if (__binp != -1)
+        this->setg(__p + __binp, __p + __ninp, __p + __einp);
+    if (__bout != -1)
+    {
+        this->setp(__p + __bout, __p + __eout);
+        this->pbump(__nout);
+    }
+    __hm_ = __hm == -1 ? nullptr : __p + __hm;
+    __p = const_cast<char_type*>(__rhs.__str_.data());
+    __rhs.setg(__p, __p, __p);
+    __rhs.setp(__p, __p);
+    __rhs.__hm_ = __p;
+    this->pubimbue(__rhs.getloc());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_stringbuf<_CharT, _Traits, _Allocator>&
+basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
+{
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __binp = -1;
+    ptrdiff_t __ninp = -1;
+    ptrdiff_t __einp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __binp = __rhs.eback() - __p;
+        __ninp = __rhs.gptr() - __p;
+        __einp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __bout = -1;
+    ptrdiff_t __nout = -1;
+    ptrdiff_t __eout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __bout = __rhs.pbase() - __p;
+        __nout = __rhs.pptr() - __p;
+        __eout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
+    __str_ = _VSTD::move(__rhs.__str_);
+    __p = const_cast<char_type*>(__str_.data());
+    if (__binp != -1)
+        this->setg(__p + __binp, __p + __ninp, __p + __einp);
+    if (__bout != -1)
+    {
+        this->setp(__p + __bout, __p + __eout);
+        this->pbump(__nout);
+    }
+    __hm_ = __hm == -1 ? nullptr : __p + __hm;
+    __mode_ = __rhs.__mode_;
+    __p = const_cast<char_type*>(__rhs.__str_.data());
+    __rhs.setg(__p, __p, __p);
+    __rhs.setp(__p, __p);
+    __rhs.__hm_ = __p;
+    this->pubimbue(__rhs.getloc());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
+{
+    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
+    ptrdiff_t __rbinp = -1;
+    ptrdiff_t __rninp = -1;
+    ptrdiff_t __reinp = -1;
+    if (__rhs.eback() != nullptr)
+    {
+        __rbinp = __rhs.eback() - __p;
+        __rninp = __rhs.gptr() - __p;
+        __reinp = __rhs.egptr() - __p;
+    }
+    ptrdiff_t __rbout = -1;
+    ptrdiff_t __rnout = -1;
+    ptrdiff_t __reout = -1;
+    if (__rhs.pbase() != nullptr)
+    {
+        __rbout = __rhs.pbase() - __p;
+        __rnout = __rhs.pptr() - __p;
+        __reout = __rhs.epptr() - __p;
+    }
+    ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
+    __p = const_cast<char_type*>(__str_.data());
+    ptrdiff_t __lbinp = -1;
+    ptrdiff_t __lninp = -1;
+    ptrdiff_t __leinp = -1;
+    if (this->eback() != nullptr)
+    {
+        __lbinp = this->eback() - __p;
+        __lninp = this->gptr() - __p;
+        __leinp = this->egptr() - __p;
+    }
+    ptrdiff_t __lbout = -1;
+    ptrdiff_t __lnout = -1;
+    ptrdiff_t __leout = -1;
+    if (this->pbase() != nullptr)
+    {
+        __lbout = this->pbase() - __p;
+        __lnout = this->pptr() - __p;
+        __leout = this->epptr() - __p;
+    }
+    ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
+    _VSTD::swap(__mode_, __rhs.__mode_);
+    __str_.swap(__rhs.__str_);
+    __p = const_cast<char_type*>(__str_.data());
+    if (__rbinp != -1)
+        this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
+    else
+        this->setg(nullptr, nullptr, nullptr);
+    if (__rbout != -1)
+    {
+        this->setp(__p + __rbout, __p + __reout);
+        this->pbump(__rnout);
+    }
+    else
+        this->setp(nullptr, nullptr);
+    __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
+    __p = const_cast<char_type*>(__rhs.__str_.data());
+    if (__lbinp != -1)
+        __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
+    else
+        __rhs.setg(nullptr, nullptr, nullptr);
+    if (__lbout != -1)
+    {
+        __rhs.setp(__p + __lbout, __p + __leout);
+        __rhs.pbump(__lnout);
+    }
+    else
+        __rhs.setp(nullptr, nullptr);
+    __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
+    locale __tl = __rhs.getloc();
+    __rhs.pubimbue(this->getloc());
+    this->pubimbue(__tl);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
+     basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
+{
+    if (__mode_ & ios_base::out)
+    {
+        if (__hm_ < this->pptr())
+            __hm_ = this->pptr();
+        return string_type(this->pbase(), __hm_, __str_.get_allocator());
+    }
+    else if (__mode_ & ios_base::in)
+        return string_type(this->eback(), this->egptr(), __str_.get_allocator());
+    return string_type(__str_.get_allocator());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
+{
+    __str_ = __s;
+    __hm_ = 0;
+    if (__mode_ & ios_base::in)
+    {
+        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
+        this->setg(const_cast<char_type*>(__str_.data()),
+                   const_cast<char_type*>(__str_.data()),
+                   __hm_);
+    }
+    if (__mode_ & ios_base::out)
+    {
+        typename string_type::size_type __sz = __str_.size();
+        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
+        __str_.resize(__str_.capacity());
+        this->setp(const_cast<char_type*>(__str_.data()),
+                   const_cast<char_type*>(__str_.data()) + __str_.size());
+        if (__mode_ & (ios_base::app | ios_base::ate))
+            this->pbump(__sz);
+    }
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
+basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
+{
+    if (__hm_ < this->pptr())
+        __hm_ = this->pptr();
+    if (__mode_ & ios_base::in)
+    {
+        if (this->egptr() < __hm_)
+            this->setg(this->eback(), this->gptr(), __hm_);
+        if (this->gptr() < this->egptr())
+            return traits_type::to_int_type(*this->gptr());
+    }
+    return traits_type::eof();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
+basic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c)
+{
+    if (__hm_ < this->pptr())
+        __hm_ = this->pptr();
+    if (this->eback() < this->gptr())
+    {
+        if (traits_type::eq_int_type(__c, traits_type::eof()))
+        {
+            this->setg(this->eback(), this->gptr()-1, __hm_);
+            return traits_type::not_eof(__c);
+        }
+        if ((__mode_ & ios_base::out) ||
+            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
+        {
+            this->setg(this->eback(), this->gptr()-1, __hm_);
+            *this->gptr() = traits_type::to_char_type(__c);
+            return __c;
+        }
+    }
+    return traits_type::eof();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
+basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
+{
+    if (!traits_type::eq_int_type(__c, traits_type::eof()))
+    {
+        ptrdiff_t __ninp = this->gptr()  - this->eback();
+        if (this->pptr() == this->epptr())
+        {
+            if (!(__mode_ & ios_base::out))
+                return traits_type::eof();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            try
+            {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+                ptrdiff_t __nout = this->pptr()  - this->pbase();
+                ptrdiff_t __hm = __hm_ - this->pbase();
+                __str_.push_back(char_type());
+                __str_.resize(__str_.capacity());
+                char_type* __p = const_cast<char_type*>(__str_.data());
+                this->setp(__p, __p + __str_.size());
+                this->pbump(__nout);
+                __hm_ = this->pbase() + __hm;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+            }
+            catch (...)
+            {
+                return traits_type::eof();
+            }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        }
+        __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
+        if (__mode_ & ios_base::in)
+        {
+            char_type* __p = const_cast<char_type*>(__str_.data());
+            this->setg(__p, __p + __ninp, __hm_);
+        }
+        return this->sputc(__c);
+    }
+    return traits_type::not_eof(__c);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
+basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
+                                                      ios_base::seekdir __way,
+                                                      ios_base::openmode __wch)
+{
+    if (__hm_ < this->pptr())
+        __hm_ = this->pptr();
+    if ((__wch & (ios_base::in | ios_base::out)) == 0)
+        return pos_type(-1);
+    if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
+        && __way == ios_base::cur)
+        return pos_type(-1);
+    off_type __noff;
+    switch (__way)
+    {
+    case ios_base::beg:
+        __noff = 0;
+        break;
+    case ios_base::cur:
+        if (__wch & ios_base::in)
+            __noff = this->gptr() - this->eback();
+        else
+            __noff = this->pptr() - this->pbase();
+        break;
+    case ios_base::end:
+        __noff = __hm_ - __str_.data();
+        break;
+    default:
+        return pos_type(-1);
+    }
+    __noff += __off;
+    if (__noff < 0 || __hm_ - __str_.data() < __noff)
+        return pos_type(-1);
+    if (__noff != 0)
+    {
+        if ((__wch & ios_base::in) && this->gptr() == 0)
+            return pos_type(-1);
+        if ((__wch & ios_base::out) && this->pptr() == 0)
+            return pos_type(-1);
+    }
+    if (__wch & ios_base::in)
+        this->setg(this->eback(), this->eback() + __noff, __hm_);
+    if (__wch & ios_base::out)
+    {
+        this->setp(this->pbase(), this->epptr());
+        this->pbump(__noff);
+    }
+    return pos_type(__noff);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
+basic_stringbuf<_CharT, _Traits, _Allocator>::seekpos(pos_type __sp,
+                                                      ios_base::openmode __wch)
+{
+    return seekoff(__sp, ios_base::beg, __wch);
+}
+
+// basic_istringstream
+
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY basic_istringstream
+    : public basic_istream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef _Allocator                     allocator_type;
+
+    typedef basic_string<char_type, traits_type, allocator_type> string_type;
+
+private:
+    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
+
+public:
+    // 27.8.2.1 Constructors:
+    explicit basic_istringstream(ios_base::openmode __wch = ios_base::in);
+    explicit basic_istringstream(const string_type& __s,
+                                 ios_base::openmode __wch = ios_base::in);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_istringstream(basic_istringstream&& __rhs);
+
+    // 27.8.2.2 Assign and swap:
+    basic_istringstream& operator=(basic_istringstream&& __rhs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void swap(basic_istringstream& __rhs);
+
+    // 27.8.2.3 Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    string_type str() const;
+    void str(const string_type& __s);
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(ios_base::openmode __wch)
+    : basic_istream<_CharT, _Traits>(&__sb_),
+      __sb_(__wch | ios_base::in)
+{
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(const string_type& __s,
+                                                                      ios_base::openmode __wch)
+    : basic_istream<_CharT, _Traits>(&__sb_),
+      __sb_(__s, __wch | ios_base::in)
+{
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(basic_istringstream&& __rhs)
+    : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_istringstream<_CharT, _Traits, _Allocator>&
+basic_istringstream<_CharT, _Traits, _Allocator>::operator=(basic_istringstream&& __rhs)
+{
+    basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_istringstream<_CharT, _Traits, _Allocator>::swap(basic_istringstream& __rhs)
+{
+    basic_istream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
+     basic_istringstream<_CharT, _Traits, _Allocator>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringbuf<_CharT, _Traits, _Allocator>*
+basic_istringstream<_CharT, _Traits, _Allocator>::rdbuf() const
+{
+    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+basic_istringstream<_CharT, _Traits, _Allocator>::str() const
+{
+    return __sb_.str();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_istringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)
+{
+    __sb_.str(__s);
+}
+
+// basic_ostringstream
+
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY basic_ostringstream
+    : public basic_ostream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef _Allocator                     allocator_type;
+
+    typedef basic_string<char_type, traits_type, allocator_type> string_type;
+
+private:
+    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
+
+public:
+    // 27.8.2.1 Constructors:
+    explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out);
+    explicit basic_ostringstream(const string_type& __s,
+                                 ios_base::openmode __wch = ios_base::out);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_ostringstream(basic_ostringstream&& __rhs);
+
+    // 27.8.2.2 Assign and swap:
+    basic_ostringstream& operator=(basic_ostringstream&& __rhs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void swap(basic_ostringstream& __rhs);
+
+    // 27.8.2.3 Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    string_type str() const;
+    void str(const string_type& __s);
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(ios_base::openmode __wch)
+    : basic_ostream<_CharT, _Traits>(&__sb_),
+      __sb_(__wch | ios_base::out)
+{
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(const string_type& __s,
+                                                                      ios_base::openmode __wch)
+    : basic_ostream<_CharT, _Traits>(&__sb_),
+      __sb_(__s, __wch | ios_base::out)
+{
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(basic_ostringstream&& __rhs)
+    : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    basic_ostream<_CharT, _Traits>::set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_ostringstream<_CharT, _Traits, _Allocator>&
+basic_ostringstream<_CharT, _Traits, _Allocator>::operator=(basic_ostringstream&& __rhs)
+{
+    basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ostringstream<_CharT, _Traits, _Allocator>::swap(basic_ostringstream& __rhs)
+{
+    basic_ostream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
+     basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringbuf<_CharT, _Traits, _Allocator>*
+basic_ostringstream<_CharT, _Traits, _Allocator>::rdbuf() const
+{
+    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+basic_ostringstream<_CharT, _Traits, _Allocator>::str() const
+{
+    return __sb_.str();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_ostringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)
+{
+    __sb_.str(__s);
+}
+
+// basic_stringstream
+
+template <class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY basic_stringstream
+    : public basic_iostream<_CharT, _Traits>
+{
+public:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+    typedef _Allocator                     allocator_type;
+
+    typedef basic_string<char_type, traits_type, allocator_type> string_type;
+
+private:
+    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
+
+public:
+    // 27.8.2.1 Constructors:
+    explicit basic_stringstream(ios_base::openmode __wch = ios_base::in | ios_base::out);
+    explicit basic_stringstream(const string_type& __s,
+                                ios_base::openmode __wch = ios_base::in | ios_base::out);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    basic_stringstream(basic_stringstream&& __rhs);
+
+    // 27.8.2.2 Assign and swap:
+    basic_stringstream& operator=(basic_stringstream&& __rhs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void swap(basic_stringstream& __rhs);
+
+    // 27.8.2.3 Members:
+    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
+    string_type str() const;
+    void str(const string_type& __s);
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(ios_base::openmode __wch)
+    : basic_iostream<_CharT, _Traits>(&__sb_),
+      __sb_(__wch)
+{
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(const string_type& __s,
+                                                                    ios_base::openmode __wch)
+    : basic_iostream<_CharT, _Traits>(&__sb_),
+      __sb_(__s, __wch)
+{
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(basic_stringstream&& __rhs)
+    : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs)),
+      __sb_(_VSTD::move(__rhs.__sb_))
+{
+    basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_stringstream<_CharT, _Traits, _Allocator>&
+basic_stringstream<_CharT, _Traits, _Allocator>::operator=(basic_stringstream&& __rhs)
+{
+    basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
+    __sb_ = _VSTD::move(__rhs.__sb_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_stringstream<_CharT, _Traits, _Allocator>::swap(basic_stringstream& __rhs)
+{
+    basic_iostream<char_type, traits_type>::swap(__rhs);
+    __sb_.swap(__rhs.__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
+     basic_stringstream<_CharT, _Traits, _Allocator>& __y)
+{
+    __x.swap(__y);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_stringbuf<_CharT, _Traits, _Allocator>*
+basic_stringstream<_CharT, _Traits, _Allocator>::rdbuf() const
+{
+    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+basic_stringstream<_CharT, _Traits, _Allocator>::str() const
+{
+    return __sb_.str();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_stringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s)
+{
+    __sb_.str(__s);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_SSTREAM
diff --git a/include/c++/v1/stack b/include/c++/v1/stack
new file mode 100644
index 0000000..30909c1
--- /dev/null
+++ b/include/c++/v1/stack
@@ -0,0 +1,292 @@
+// -*- C++ -*-
+//===---------------------------- stack -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STACK
+#define _LIBCPP_STACK
+
+/*
+    stack synopsis
+
+namespace std
+{
+
+template <class T, class Container = deque<T>>
+class stack
+{
+public:
+    typedef Container                                container_type;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+
+public:
+    stack() = default;
+    ~stack() = default;
+
+    stack(const stack& q) = default;
+    stack(stack&& q) = default;
+
+    stack& operator=(const stack& q) = default;
+    stack& operator=(stack&& q) = default;
+
+    explicit stack(const container_type& c);
+    explicit stack(container_type&& c);
+    template <class Alloc> explicit stack(const Alloc& a);
+    template <class Alloc> stack(const container_type& c, const Alloc& a);
+    template <class Alloc> stack(container_type&& c, const Alloc& a);
+    template <class Alloc> stack(const stack& c, const Alloc& a);
+    template <class Alloc> stack(stack&& c, const Alloc& a);
+
+    bool empty() const;
+    size_type size() const;
+    reference top();
+    const_reference top() const;
+
+    void push(const value_type& x);
+    void push(value_type&& x);
+    template <class... Args> void emplace(Args&&... args);
+    void pop();
+
+    void swap(stack& c) noexcept(noexcept(swap(c, q.c)));
+};
+
+template <class T, class Container>
+  bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
+template <class T, class Container>
+  bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
+template <class T, class Container>
+  bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
+template <class T, class Container>
+  bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
+template <class T, class Container>
+  bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
+template <class T, class Container>
+  bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
+
+template <class T, class Container>
+  void swap(stack<T, Container>& x, stack<T, Container>& y)
+  noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <deque>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp, class _Container> class _LIBCPP_TYPE_VIS_ONLY stack;
+
+template <class _Tp, class _Container>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
+
+template <class _Tp, class _Container>
+_LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
+
+template <class _Tp, class _Container = deque<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY stack
+{
+public:
+    typedef _Container                               container_type;
+    typedef typename container_type::value_type      value_type;
+    typedef typename container_type::reference       reference;
+    typedef typename container_type::const_reference const_reference;
+    typedef typename container_type::size_type       size_type;
+
+protected:
+    container_type c;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    stack()
+        _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
+        : c() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    stack(const stack& __q) : c(__q.c) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    stack(stack&& __q)
+        _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
+        : c(_VSTD::move(__q.c)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    stack& operator=(const stack& __q) {c = __q.c; return *this;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    stack& operator=(stack&& __q)
+        _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
+        {c = _VSTD::move(__q.c); return *this;}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit stack(const container_type& __c) : c(__c) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit stack(const _Alloc& __a,
+                       typename enable_if<uses_allocator<container_type,
+                                                         _Alloc>::value>::type* = 0)
+            : c(__a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        stack(const container_type& __c, const _Alloc& __a,
+              typename enable_if<uses_allocator<container_type,
+                                                _Alloc>::value>::type* = 0)
+            : c(__c, __a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        stack(const stack& __s, const _Alloc& __a,
+              typename enable_if<uses_allocator<container_type,
+                                                _Alloc>::value>::type* = 0)
+            : c(__s.c, __a) {}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        stack(container_type&& __c, const _Alloc& __a,
+              typename enable_if<uses_allocator<container_type,
+                                                _Alloc>::value>::type* = 0)
+            : c(_VSTD::move(__c), __a) {}
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        stack(stack&& __s, const _Alloc& __a,
+              typename enable_if<uses_allocator<container_type,
+                                                _Alloc>::value>::type* = 0)
+            : c(_VSTD::move(__s.c), __a) {}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty()     const      {return c.empty();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const      {return c.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    reference top()             {return c.back();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference top() const {return c.back();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void push(const value_type& __v) {c.push_back(__v);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        void emplace(_Args&&... __args)
+        {c.emplace_back(_VSTD::forward<_Args>(__args)...);}
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void pop() {c.pop_back();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(stack& __s)
+        _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)
+    {
+        using _VSTD::swap;
+        swap(c, __s.c);
+    }
+
+    template <class T1, class _C1>
+    friend
+    bool
+    operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
+
+    template <class T1, class _C1>
+    friend
+    bool
+    operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
+};
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return __x.c == __y.c;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return __x.c < __y.c;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Container>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Tp, class _Container, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<stack<_Tp, _Container>, _Alloc>
+    : public uses_allocator<_Container, _Alloc>
+{
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STACK
diff --git a/include/c++/v1/stdexcept b/include/c++/v1/stdexcept
new file mode 100644
index 0000000..5fc912a
--- /dev/null
+++ b/include/c++/v1/stdexcept
@@ -0,0 +1,170 @@
+// -*- C++ -*-
+//===--------------------------- stdexcept --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STDEXCEPT
+#define _LIBCPP_STDEXCEPT
+
+/*
+    stdexcept synopsis
+
+namespace std
+{
+
+class logic_error;
+    class domain_error;
+    class invalid_argument;
+    class length_error;
+    class out_of_range;
+class runtime_error;
+    class range_error;
+    class overflow_error;
+    class underflow_error;
+
+for each class xxx_error:
+
+class xxx_error : public exception // at least indirectly
+{
+public:
+    explicit xxx_error(const string& what_arg);
+    explicit xxx_error(const char*   what_arg);
+
+    virtual const char* what() const noexcept // returns what_arg
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <exception>
+#include <iosfwd>  // for string forward decl
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP___REFSTRING
+_LIBCPP_BEGIN_NAMESPACE_STD
+class _LIBCPP_HIDDEN __libcpp_refstring {
+    const char *__imp_;
+};
+_LIBCPP_END_NAMESPACE_STD
+#endif
+
+namespace std  // purposefully not using versioning namespace
+{
+
+class _LIBCPP_EXCEPTION_ABI logic_error
+    : public exception
+{
+private:
+    _VSTD::__libcpp_refstring __imp_;
+public:
+    explicit logic_error(const string&);
+    explicit logic_error(const char*);
+
+    logic_error(const logic_error&) _NOEXCEPT;
+    logic_error& operator=(const logic_error&) _NOEXCEPT;
+
+    virtual ~logic_error() _NOEXCEPT;
+
+    virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI runtime_error
+    : public exception
+{
+private:
+    _VSTD::__libcpp_refstring __imp_;
+public:
+    explicit runtime_error(const string&);
+    explicit runtime_error(const char*);
+
+    runtime_error(const runtime_error&) _NOEXCEPT;
+    runtime_error& operator=(const runtime_error&) _NOEXCEPT;
+
+    virtual ~runtime_error() _NOEXCEPT;
+
+    virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI domain_error
+    : public logic_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit domain_error(const string& __s) : logic_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s)   : logic_error(__s) {}
+
+    virtual ~domain_error() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI invalid_argument
+    : public logic_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const string& __s) : logic_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s)   : logic_error(__s) {}
+
+    virtual ~invalid_argument() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI length_error
+    : public logic_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s)   : logic_error(__s) {}
+
+    virtual ~length_error() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI out_of_range
+    : public logic_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const string& __s) : logic_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s)   : logic_error(__s) {}
+
+    virtual ~out_of_range() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI range_error
+    : public runtime_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit range_error(const string& __s) : runtime_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s)   : runtime_error(__s) {}
+
+    virtual ~range_error() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI overflow_error
+    : public runtime_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const string& __s) : runtime_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s)   : runtime_error(__s) {}
+
+    virtual ~overflow_error() _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI underflow_error
+    : public runtime_error
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const string& __s) : runtime_error(__s) {}
+    _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s)   : runtime_error(__s) {}
+
+    virtual ~underflow_error() _NOEXCEPT;
+};
+
+}  // std
+
+#endif  // _LIBCPP_STDEXCEPT
diff --git a/include/c++/v1/streambuf b/include/c++/v1/streambuf
new file mode 100644
index 0000000..6adfc92
--- /dev/null
+++ b/include/c++/v1/streambuf
@@ -0,0 +1,564 @@
+// -*- C++ -*-
+//===------------------------- streambuf ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STEAMBUF
+#define _LIBCPP_STEAMBUF
+
+/*
+    streambuf synopsis
+
+namespace std
+{
+
+template <class charT, class traits = char_traits<charT> >
+class basic_streambuf
+{
+public:
+    // types:
+    typedef charT char_type;
+    typedef traits traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    virtual ~basic_streambuf();
+
+    // 27.6.2.2.1 locales:
+    locale pubimbue(const locale& loc);
+    locale getloc() const;
+
+    // 27.6.2.2.2 buffer and positioning:
+    basic_streambuf* pubsetbuf(char_type* s, streamsize n);
+    pos_type pubseekoff(off_type off, ios_base::seekdir way,
+                        ios_base::openmode which = ios_base::in | ios_base::out);
+    pos_type pubseekpos(pos_type sp,
+                        ios_base::openmode which = ios_base::in | ios_base::out);
+    int pubsync();
+
+    // Get and put areas:
+    // 27.6.2.2.3 Get area:
+    streamsize in_avail();
+    int_type snextc();
+    int_type sbumpc();
+    int_type sgetc();
+    streamsize sgetn(char_type* s, streamsize n);
+
+    // 27.6.2.2.4 Putback:
+    int_type sputbackc(char_type c);
+    int_type sungetc();
+
+    // 27.6.2.2.5 Put area:
+    int_type sputc(char_type c);
+    streamsize sputn(const char_type* s, streamsize n);
+
+protected:
+    basic_streambuf();
+    basic_streambuf(const basic_streambuf& rhs);
+    basic_streambuf& operator=(const basic_streambuf& rhs);
+    void swap(basic_streambuf& rhs);
+
+    // 27.6.2.3.2 Get area:
+    char_type* eback() const;
+    char_type* gptr() const;
+    char_type* egptr() const;
+    void gbump(int n);
+    void setg(char_type* gbeg, char_type* gnext, char_type* gend);
+
+    // 27.6.2.3.3 Put area:
+    char_type* pbase() const;
+    char_type* pptr() const;
+    char_type* epptr() const;
+    void pbump(int n);
+    void setp(char_type* pbeg, char_type* pend);
+
+    // 27.6.2.4 virtual functions:
+    // 27.6.2.4.1 Locales:
+    virtual void imbue(const locale& loc);
+
+    // 27.6.2.4.2 Buffer management and positioning:
+    virtual basic_streambuf* setbuf(char_type* s, streamsize n);
+    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type sp,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual int sync();
+
+    // 27.6.2.4.3 Get area:
+    virtual streamsize showmanyc();
+    virtual streamsize xsgetn(char_type* s, streamsize n);
+    virtual int_type underflow();
+    virtual int_type uflow();
+
+    // 27.6.2.4.4 Putback:
+    virtual int_type pbackfail(int_type c = traits_type::eof());
+
+    // 27.6.2.4.5 Put area:
+    virtual streamsize xsputn(const char_type* s, streamsize n);
+    virtual int_type overflow (int_type c = traits_type::eof());
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <iosfwd>
+#include <ios>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _CharT, class _Traits>
+class _LIBCPP_TYPE_VIS_ONLY basic_streambuf
+{
+public:
+    // types:
+    typedef _CharT                         char_type;
+    typedef _Traits                        traits_type;
+    typedef typename traits_type::int_type int_type;
+    typedef typename traits_type::pos_type pos_type;
+    typedef typename traits_type::off_type off_type;
+
+    virtual ~basic_streambuf();
+
+    // 27.6.2.2.1 locales:
+    locale pubimbue(const locale& __loc);
+    locale getloc() const;
+
+    // 27.6.2.2.2 buffer and positioning:
+    basic_streambuf* pubsetbuf(char_type* __s, streamsize __n);
+    pos_type pubseekoff(off_type __off, ios_base::seekdir __way,
+                        ios_base::openmode __which = ios_base::in | ios_base::out);
+    pos_type pubseekpos(pos_type __sp,
+                        ios_base::openmode __which = ios_base::in | ios_base::out);
+    int pubsync();
+
+    // Get and put areas:
+    // 27.6.2.2.3 Get area:
+    streamsize in_avail();
+    int_type snextc();
+    int_type sbumpc();
+    int_type sgetc();
+    streamsize sgetn(char_type* __s, streamsize __n);
+
+    // 27.6.2.2.4 Putback:
+    int_type sputbackc(char_type __c);
+    int_type sungetc();
+
+    // 27.6.2.2.5 Put area:
+    int_type sputc(char_type __c);
+    streamsize sputn(const char_type* __s, streamsize __n);
+
+protected:
+    basic_streambuf();
+    basic_streambuf(const basic_streambuf& __rhs);
+    basic_streambuf& operator=(const basic_streambuf& __rhs);
+    void swap(basic_streambuf& __rhs);
+
+    // 27.6.2.3.2 Get area:
+    _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;}
+    _LIBCPP_ALWAYS_INLINE char_type* gptr()  const {return __ninp_;}
+    _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;}
+    void gbump(int __n);
+    void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend);
+
+    // 27.6.2.3.3 Put area:
+    _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;}
+    _LIBCPP_ALWAYS_INLINE char_type* pptr()  const {return __nout_;}
+    _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;}
+    void pbump(int __n);
+    void setp(char_type* __pbeg, char_type* __pend);
+
+    // 27.6.2.4 virtual functions:
+    // 27.6.2.4.1 Locales:
+    virtual void imbue(const locale& __loc);
+
+    // 27.6.2.4.2 Buffer management and positioning:
+    virtual basic_streambuf* setbuf(char_type* __s, streamsize __n);
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __which = ios_base::in | ios_base::out);
+    virtual int sync();
+
+    // 27.6.2.4.3 Get area:
+    virtual streamsize showmanyc();
+    virtual streamsize xsgetn(char_type* __s, streamsize __n);
+    virtual int_type underflow();
+    virtual int_type uflow();
+
+    // 27.6.2.4.4 Putback:
+    virtual int_type pbackfail(int_type __c = traits_type::eof());
+
+    // 27.6.2.4.5 Put area:
+    virtual streamsize xsputn(const char_type* __s, streamsize __n);
+    virtual int_type overflow(int_type __c = traits_type::eof());
+
+private:
+    locale __loc_;
+    char_type* __binp_;
+    char_type* __ninp_;
+    char_type* __einp_;
+    char_type* __bout_;
+    char_type* __nout_;
+    char_type* __eout_;
+};
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>::~basic_streambuf()
+{
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+locale
+basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc)
+{
+    imbue(__loc);
+    locale __r = __loc_;
+    __loc_ = __loc;
+    return __r;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+locale
+basic_streambuf<_CharT, _Traits>::getloc() const
+{
+    return __loc_;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_streambuf<_CharT, _Traits>*
+basic_streambuf<_CharT, _Traits>::pubsetbuf(char_type* __s, streamsize __n)
+{
+    return setbuf(__s, __n);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::pos_type
+basic_streambuf<_CharT, _Traits>::pubseekoff(off_type __off,
+                                             ios_base::seekdir __way,
+                                             ios_base::openmode __which)
+{
+    return seekoff(__off, __way, __which);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::pos_type
+basic_streambuf<_CharT, _Traits>::pubseekpos(pos_type __sp,
+                                             ios_base::openmode __which)
+{
+    return seekpos(__sp, __which);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+int
+basic_streambuf<_CharT, _Traits>::pubsync()
+{
+    return sync();
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+basic_streambuf<_CharT, _Traits>::in_avail()
+{
+    if (__ninp_ < __einp_)
+        return static_cast<streamsize>(__einp_ - __ninp_);
+    return showmanyc();
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::snextc()
+{
+    if (sbumpc() == traits_type::eof())
+        return traits_type::eof();
+    return sgetc();
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::sbumpc()
+{
+    if (__ninp_ == __einp_)
+        return uflow();
+    return traits_type::to_int_type(*__ninp_++);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::sgetc()
+{
+    if (__ninp_ == __einp_)
+        return underflow();
+    return traits_type::to_int_type(*__ninp_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+basic_streambuf<_CharT, _Traits>::sgetn(char_type* __s, streamsize __n)
+{
+    return xsgetn(__s, __n);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::sputbackc(char_type __c)
+{
+    if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
+        return pbackfail(traits_type::to_int_type(__c));
+    return traits_type::to_int_type(*--__ninp_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::sungetc()
+{
+    if (__binp_ == __ninp_)
+        return pbackfail();
+    return traits_type::to_int_type(*--__ninp_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::sputc(char_type __c)
+{
+    if (__nout_ == __eout_)
+        return overflow(traits_type::to_int_type(__c));
+    *__nout_++ = __c;
+    return traits_type::to_int_type(__c);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+streamsize
+basic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n)
+{
+    return xsputn(__s, __n);
+}
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>::basic_streambuf()
+    : __binp_(0),
+      __ninp_(0),
+      __einp_(0),
+      __bout_(0),
+      __nout_(0),
+      __eout_(0)
+{
+}
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>::basic_streambuf(const basic_streambuf& __sb)
+    : __loc_(__sb.__loc_),
+      __binp_(__sb.__binp_),
+      __ninp_(__sb.__ninp_),
+      __einp_(__sb.__einp_),
+      __bout_(__sb.__bout_),
+      __nout_(__sb.__nout_),
+      __eout_(__sb.__eout_)
+{
+}
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>&
+basic_streambuf<_CharT, _Traits>::operator=(const basic_streambuf& __sb)
+{
+    __loc_ = __sb.__loc_;
+    __binp_ = __sb.__binp_;
+    __ninp_ = __sb.__ninp_;
+    __einp_ = __sb.__einp_;
+    __bout_ = __sb.__bout_;
+    __nout_ = __sb.__nout_;
+    __eout_ = __sb.__eout_;
+    return *this;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb)
+{
+    _VSTD::swap(__loc_, __sb.__loc_);
+    _VSTD::swap(__binp_, __sb.__binp_);
+    _VSTD::swap(__ninp_, __sb.__ninp_);
+    _VSTD::swap(__einp_, __sb.__einp_);
+    _VSTD::swap(__bout_, __sb.__bout_);
+    _VSTD::swap(__nout_, __sb.__nout_);
+    _VSTD::swap(__eout_, __sb.__eout_);
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_streambuf<_CharT, _Traits>::gbump(int __n)
+{
+    __ninp_ += __n;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_streambuf<_CharT, _Traits>::setg(char_type* __gbeg, char_type* __gnext,
+                                                          char_type* __gend)
+{
+    __binp_ = __gbeg;
+    __ninp_ = __gnext;
+    __einp_ = __gend;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_streambuf<_CharT, _Traits>::pbump(int __n)
+{
+    __nout_ += __n;
+}
+
+template <class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend)
+{
+    __bout_ = __nout_ = __pbeg;
+    __eout_ = __pend;
+}
+
+template <class _CharT, class _Traits>
+void
+basic_streambuf<_CharT, _Traits>::imbue(const locale&)
+{
+}
+
+template <class _CharT, class _Traits>
+basic_streambuf<_CharT, _Traits>*
+basic_streambuf<_CharT, _Traits>::setbuf(char_type*, streamsize)
+{
+    return this;
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::pos_type
+basic_streambuf<_CharT, _Traits>::seekoff(off_type, ios_base::seekdir,
+                                          ios_base::openmode)
+{
+    return pos_type(off_type(-1));
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::pos_type
+basic_streambuf<_CharT, _Traits>::seekpos(pos_type, ios_base::openmode)
+{
+    return pos_type(off_type(-1));
+}
+
+template <class _CharT, class _Traits>
+int
+basic_streambuf<_CharT, _Traits>::sync()
+{
+    return 0;
+}
+
+template <class _CharT, class _Traits>
+streamsize
+basic_streambuf<_CharT, _Traits>::showmanyc()
+{
+    return 0;
+}
+
+template <class _CharT, class _Traits>
+streamsize
+basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n)
+{
+    const int_type __eof = traits_type::eof();
+    int_type __c;
+    streamsize __i = 0;
+    for (;__i < __n; ++__i, ++__s)
+    {
+        if (__ninp_ < __einp_)
+            *__s = *__ninp_++;
+        else if ((__c = uflow()) != __eof)
+            *__s = traits_type::to_char_type(__c);
+        else
+            break;
+    }
+    return __i;
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::underflow()
+{
+    return traits_type::eof();
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::uflow()
+{
+    if (underflow() == traits_type::eof())
+        return traits_type::eof();
+    return traits_type::to_int_type(*__ninp_++);
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::pbackfail(int_type)
+{
+    return traits_type::eof();
+}
+
+template <class _CharT, class _Traits>
+streamsize
+basic_streambuf<_CharT, _Traits>::xsputn(const char_type* __s, streamsize __n)
+{
+    streamsize __i = 0;
+    int_type __eof = traits_type::eof();
+    for (; __i < __n; ++__s, ++__i)
+    {
+        if (__nout_ < __eout_)
+            *__nout_++ = *__s;
+        else if (overflow(traits_type::to_int_type(*__s)) == __eof)
+            break;
+    }
+    return __i;
+}
+
+template <class _CharT, class _Traits>
+typename basic_streambuf<_CharT, _Traits>::int_type
+basic_streambuf<_CharT, _Traits>::overflow(int_type)
+{
+    return traits_type::eof();
+}
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<wchar_t>)
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<wchar_t>)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STEAMBUF
diff --git a/include/c++/v1/string b/include/c++/v1/string
new file mode 100644
index 0000000..d6c148a
--- /dev/null
+++ b/include/c++/v1/string
@@ -0,0 +1,4299 @@
+// -*- C++ -*-
+//===--------------------------- string -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STRING
+#define _LIBCPP_STRING
+
+/*
+    string synopsis
+
+namespace std
+{
+
+template <class stateT>
+class fpos
+{
+private:
+    stateT st;
+public:
+    fpos(streamoff = streamoff());
+
+    operator streamoff() const;
+
+    stateT state() const;
+    void state(stateT);
+
+    fpos& operator+=(streamoff);
+    fpos  operator+ (streamoff) const;
+    fpos& operator-=(streamoff);
+    fpos  operator- (streamoff) const;
+};
+
+template <class stateT> streamoff operator-(const fpos<stateT>& x, const fpos<stateT>& y);
+
+template <class stateT> bool operator==(const fpos<stateT>& x, const fpos<stateT>& y);
+template <class stateT> bool operator!=(const fpos<stateT>& x, const fpos<stateT>& y);
+
+template <class charT>
+struct char_traits
+{
+    typedef charT     char_type;
+    typedef ...       int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    static void assign(char_type& c1, const char_type& c2) noexcept;
+    static constexpr bool eq(char_type c1, char_type c2) noexcept;
+    static constexpr bool lt(char_type c1, char_type c2) noexcept;
+
+    static int              compare(const char_type* s1, const char_type* s2, size_t n);
+    static size_t           length(const char_type* s);
+    static const char_type* find(const char_type* s, size_t n, const char_type& a);
+    static char_type*       move(char_type* s1, const char_type* s2, size_t n);
+    static char_type*       copy(char_type* s1, const char_type* s2, size_t n);
+    static char_type*       assign(char_type* s, size_t n, char_type a);
+
+    static constexpr int_type  not_eof(int_type c) noexcept;
+    static constexpr char_type to_char_type(int_type c) noexcept;
+    static constexpr int_type  to_int_type(char_type c) noexcept;
+    static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept;
+    static constexpr int_type  eof() noexcept;
+};
+
+template <> struct char_traits<char>;
+template <> struct char_traits<wchar_t>;
+
+template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
+class basic_string
+{
+public:
+// types:
+    typedef traits traits_type;
+    typedef typename traits_type::char_type value_type;
+    typedef Allocator allocator_type;
+    typedef typename allocator_type::size_type size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef typename allocator_type::reference reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef typename allocator_type::pointer pointer;
+    typedef typename allocator_type::const_pointer const_pointer;
+    typedef implementation-defined iterator;
+    typedef implementation-defined const_iterator;
+    typedef std::reverse_iterator<iterator> reverse_iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    static const size_type npos = -1;
+
+    basic_string()
+        noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit basic_string(const allocator_type& a);
+    basic_string(const basic_string& str);
+    basic_string(basic_string&& str)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    basic_string(const basic_string& str, size_type pos, size_type n = npos,
+                 const allocator_type& a = allocator_type());
+    basic_string(const value_type* s, const allocator_type& a = allocator_type());
+    basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
+    basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
+    template<class InputIterator>
+        basic_string(InputIterator begin, InputIterator end,
+                     const allocator_type& a = allocator_type());
+    basic_string(initializer_list<value_type>, const Allocator& = Allocator());
+    basic_string(const basic_string&, const Allocator&);
+    basic_string(basic_string&&, const Allocator&);
+
+    ~basic_string();
+
+    basic_string& operator=(const basic_string& str);
+    basic_string& operator=(basic_string&& str)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    basic_string& operator=(const value_type* s);
+    basic_string& operator=(value_type c);
+    basic_string& operator=(initializer_list<value_type>);
+
+    iterator       begin() noexcept;
+    const_iterator begin() const noexcept;
+    iterator       end() noexcept;
+    const_iterator end() const noexcept;
+
+    reverse_iterator       rbegin() noexcept;
+    const_reverse_iterator rbegin() const noexcept;
+    reverse_iterator       rend() noexcept;
+    const_reverse_iterator rend() const noexcept;
+
+    const_iterator         cbegin() const noexcept;
+    const_iterator         cend() const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend() const noexcept;
+
+    size_type size() const noexcept;
+    size_type length() const noexcept;
+    size_type max_size() const noexcept;
+    size_type capacity() const noexcept;
+
+    void resize(size_type n, value_type c);
+    void resize(size_type n);
+
+    void reserve(size_type res_arg = 0);
+    void shrink_to_fit();
+    void clear() noexcept;
+    bool empty() const noexcept;
+
+    const_reference operator[](size_type pos) const;
+    reference       operator[](size_type pos);
+
+    const_reference at(size_type n) const;
+    reference       at(size_type n);
+
+    basic_string& operator+=(const basic_string& str);
+    basic_string& operator+=(const value_type* s);
+    basic_string& operator+=(value_type c);
+    basic_string& operator+=(initializer_list<value_type>);
+
+    basic_string& append(const basic_string& str);
+    basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14
+    basic_string& append(const value_type* s, size_type n);
+    basic_string& append(const value_type* s);
+    basic_string& append(size_type n, value_type c);
+    template<class InputIterator>
+        basic_string& append(InputIterator first, InputIterator last);
+    basic_string& append(initializer_list<value_type>);
+
+    void push_back(value_type c);
+    void pop_back();
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back() const;
+
+    basic_string& assign(const basic_string& str);
+    basic_string& assign(basic_string&& str);
+    basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14
+    basic_string& assign(const value_type* s, size_type n);
+    basic_string& assign(const value_type* s);
+    basic_string& assign(size_type n, value_type c);
+    template<class InputIterator>
+        basic_string& assign(InputIterator first, InputIterator last);
+    basic_string& assign(initializer_list<value_type>);
+
+    basic_string& insert(size_type pos1, const basic_string& str);
+    basic_string& insert(size_type pos1, const basic_string& str,
+                         size_type pos2, size_type n);
+    basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14
+    basic_string& insert(size_type pos, const value_type* s);
+    basic_string& insert(size_type pos, size_type n, value_type c);
+    iterator      insert(const_iterator p, value_type c);
+    iterator      insert(const_iterator p, size_type n, value_type c);
+    template<class InputIterator>
+        iterator insert(const_iterator p, InputIterator first, InputIterator last);
+    iterator      insert(const_iterator p, initializer_list<value_type>);
+
+    basic_string& erase(size_type pos = 0, size_type n = npos);
+    iterator      erase(const_iterator position);
+    iterator      erase(const_iterator first, const_iterator last);
+
+    basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
+    basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
+                          size_type pos2, size_type n2=npos); // C++14
+    basic_string& replace(size_type pos, size_type n1, const value_type* s, size_type n2);
+    basic_string& replace(size_type pos, size_type n1, const value_type* s);
+    basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c);
+    basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str);
+    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n);
+    basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s);
+    basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c);
+    template<class InputIterator>
+        basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2);
+    basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>);
+
+    size_type copy(value_type* s, size_type n, size_type pos = 0) const;
+    basic_string substr(size_type pos = 0, size_type n = npos) const;
+
+    void swap(basic_string& str)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value)
+
+    const value_type* c_str() const noexcept;
+    const value_type* data() const noexcept;
+
+    allocator_type get_allocator() const noexcept;
+
+    size_type find(const basic_string& str, size_type pos = 0) const noexcept;
+    size_type find(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find(const value_type* s, size_type pos = 0) const noexcept;
+    size_type find(value_type c, size_type pos = 0) const noexcept;
+
+    size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
+    size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type rfind(const value_type* s, size_type pos = npos) const noexcept;
+    size_type rfind(value_type c, size_type pos = npos) const noexcept;
+
+    size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
+    size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept;
+    size_type find_first_of(value_type c, size_type pos = 0) const noexcept;
+
+    size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
+    size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept;
+    size_type find_last_of(value_type c, size_type pos = npos) const noexcept;
+
+    size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
+    size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept;
+    size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept;
+
+    size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
+    size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept;
+    size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept;
+    size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept;
+
+    int compare(const basic_string& str) const noexcept;
+    int compare(size_type pos1, size_type n1, const basic_string& str) const;
+    int compare(size_type pos1, size_type n1, const basic_string& str,
+                size_type pos2, size_type n2=npos) const; // C++14
+    int compare(const value_type* s) const noexcept;
+    int compare(size_type pos1, size_type n1, const value_type* s) const;
+    int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const;
+
+    bool __invariants() const;
+};
+
+template<class charT, class traits, class Allocator>
+basic_string<charT, traits, Allocator>
+operator+(const basic_string<charT, traits, Allocator>& lhs,
+          const basic_string<charT, traits, Allocator>& rhs);
+
+template<class charT, class traits, class Allocator>
+basic_string<charT, traits, Allocator>
+operator+(const charT* lhs , const basic_string<charT,traits,Allocator>&rhs);
+
+template<class charT, class traits, class Allocator>
+basic_string<charT, traits, Allocator>
+operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);
+
+template<class charT, class traits, class Allocator>
+basic_string<charT, traits, Allocator>
+operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
+
+template<class charT, class traits, class Allocator>
+basic_string<charT, traits, Allocator>
+operator+(const basic_string<charT, traits, Allocator>& lhs, charT rhs);
+
+template<class charT, class traits, class Allocator>
+bool operator==(const basic_string<charT, traits, Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator==(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator!=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator!=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator< (const basic_string<charT, traits, Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator< (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator< (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator> (const basic_string<charT, traits, Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator> (const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator> (const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator<=(const basic_string<charT, traits, Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator<=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator<=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator>=(const basic_string<charT, traits, Allocator>& lhs,
+                const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator>=(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+bool operator>=(const charT* lhs, const basic_string<charT, traits, Allocator>& rhs) noexcept;
+
+template<class charT, class traits, class Allocator>
+void swap(basic_string<charT, traits, Allocator>& lhs,
+          basic_string<charT, traits, Allocator>& rhs)
+            noexcept(noexcept(lhs.swap(rhs)));
+
+template<class charT, class traits, class Allocator>
+basic_istream<charT, traits>&
+operator>>(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
+
+template<class charT, class traits, class Allocator>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
+
+template<class charT, class traits, class Allocator>
+basic_istream<charT, traits>&
+getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str,
+        charT delim);
+
+template<class charT, class traits, class Allocator>
+basic_istream<charT, traits>&
+getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
+
+typedef basic_string<char>    string;
+typedef basic_string<wchar_t> wstring;
+typedef basic_string<char16_t> u16string;
+typedef basic_string<char32_t> u32string;
+
+int                stoi  (const string& str, size_t* idx = 0, int base = 10);
+long               stol  (const string& str, size_t* idx = 0, int base = 10);
+unsigned long      stoul (const string& str, size_t* idx = 0, int base = 10);
+long long          stoll (const string& str, size_t* idx = 0, int base = 10);
+unsigned long long stoull(const string& str, size_t* idx = 0, int base = 10);
+
+float       stof (const string& str, size_t* idx = 0);
+double      stod (const string& str, size_t* idx = 0);
+long double stold(const string& str, size_t* idx = 0);
+
+string to_string(int val);
+string to_string(unsigned val);
+string to_string(long val);
+string to_string(unsigned long val);
+string to_string(long long val);
+string to_string(unsigned long long val);
+string to_string(float val);
+string to_string(double val);
+string to_string(long double val);
+
+int                stoi  (const wstring& str, size_t* idx = 0, int base = 10);
+long               stol  (const wstring& str, size_t* idx = 0, int base = 10);
+unsigned long      stoul (const wstring& str, size_t* idx = 0, int base = 10);
+long long          stoll (const wstring& str, size_t* idx = 0, int base = 10);
+unsigned long long stoull(const wstring& str, size_t* idx = 0, int base = 10);
+
+float       stof (const wstring& str, size_t* idx = 0);
+double      stod (const wstring& str, size_t* idx = 0);
+long double stold(const wstring& str, size_t* idx = 0);
+
+wstring to_wstring(int val);
+wstring to_wstring(unsigned val);
+wstring to_wstring(long val);
+wstring to_wstring(unsigned long val);
+wstring to_wstring(long long val);
+wstring to_wstring(unsigned long long val);
+wstring to_wstring(float val);
+wstring to_wstring(double val);
+wstring to_wstring(long double val);
+
+template <> struct hash<string>;
+template <> struct hash<u16string>;
+template <> struct hash<u32string>;
+template <> struct hash<wstring>;
+
+basic_string<char>     operator "" s( const char *str,     size_t len ); // C++14
+basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len ); // C++14
+basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14
+basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14
+
+}  // std
+
+*/
+
+#include <__config>
+#include <iosfwd>
+#include <cstring>
+#include <cstdio>  // For EOF.
+#include <cwchar>
+#include <algorithm>
+#include <iterator>
+#include <utility>
+#include <memory>
+#include <stdexcept>
+#include <type_traits>
+#include <initializer_list>
+#include <__functional_base>
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+#include <cstdint>
+#endif
+#if defined(_LIBCPP_NO_EXCEPTIONS)
+#include <cassert>
+#endif
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// fpos
+
+template <class _StateT>
+class _LIBCPP_TYPE_VIS_ONLY fpos
+{
+private:
+    _StateT __st_;
+    streamoff __off_;
+public:
+    _LIBCPP_INLINE_VISIBILITY fpos(streamoff __off = streamoff()) : __st_(), __off_(__off) {}
+
+    _LIBCPP_INLINE_VISIBILITY operator streamoff() const {return __off_;}
+
+    _LIBCPP_INLINE_VISIBILITY _StateT state() const {return __st_;}
+    _LIBCPP_INLINE_VISIBILITY void state(_StateT __st) {__st_ = __st;}
+
+    _LIBCPP_INLINE_VISIBILITY fpos& operator+=(streamoff __off) {__off_ += __off; return *this;}
+    _LIBCPP_INLINE_VISIBILITY fpos  operator+ (streamoff __off) const {fpos __t(*this); __t += __off; return __t;}
+    _LIBCPP_INLINE_VISIBILITY fpos& operator-=(streamoff __off) {__off_ -= __off; return *this;}
+    _LIBCPP_INLINE_VISIBILITY fpos  operator- (streamoff __off) const {fpos __t(*this); __t -= __off; return __t;}
+};
+
+template <class _StateT>
+inline _LIBCPP_INLINE_VISIBILITY
+streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
+    {return streamoff(__x) - streamoff(__y);}
+
+template <class _StateT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
+    {return streamoff(__x) == streamoff(__y);}
+
+template <class _StateT>
+inline _LIBCPP_INLINE_VISIBILITY
+bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y)
+    {return streamoff(__x) != streamoff(__y);}
+
+// char_traits
+
+template <class _CharT>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits
+{
+    typedef _CharT    char_type;
+    typedef int       int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+        {__c1 = __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    static size_t           length(const char_type* __s);
+    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       assign(char_type* __s, size_t __n, char_type __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+        {return int_type(EOF);}
+};
+
+template <class _CharT>
+int
+char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+char_traits<_CharT>::length(const char_type* __s)
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+const _CharT*
+char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return 0;
+}
+
+template <class _CharT>
+_CharT*
+char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT*
+char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+template <class _CharT>
+inline _LIBCPP_INLINE_VISIBILITY
+_CharT*
+char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+// char_traits<char>
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char>
+{
+    typedef char      char_type;
+    typedef int       int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+        {__c1 = __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+            {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return (unsigned char)__c1 < (unsigned char)__c2;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static int compare(const char_type* __s1, const char_type* __s2, size_t __n)
+        {return memcmp(__s1, __s2, __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static size_t length(const char_type* __s) {return strlen(__s);}
+    _LIBCPP_INLINE_VISIBILITY
+    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
+        {return (const char_type*)memchr(__s, to_int_type(__a), __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
+        {return (char_type*)memmove(__s1, __s2, __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return (char_type*)memcpy(__s1, __s2, __n);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* assign(char_type* __s, size_t __n, char_type __a)
+        {return (char_type*)memset(__s, to_int_type(__a), __n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type((unsigned char)__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
+        {return int_type(EOF);}
+};
+
+// char_traits<wchar_t>
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t>
+{
+    typedef wchar_t   char_type;
+    typedef wint_t    int_type;
+    typedef streamoff off_type;
+    typedef streampos pos_type;
+    typedef mbstate_t state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+        {__c1 = __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static int compare(const char_type* __s1, const char_type* __s2, size_t __n)
+        {return wmemcmp(__s1, __s2, __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static size_t length(const char_type* __s)
+        {return wcslen(__s);}
+    _LIBCPP_INLINE_VISIBILITY
+    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a)
+        {return (const char_type*)wmemchr(__s, __a, __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* move(char_type* __s1, const char_type* __s2, size_t __n)
+        {return (char_type*)wmemmove(__s1, __s2, __n);}
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return (char_type*)wmemcpy(__s1, __s2, __n);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static char_type* assign(char_type* __s, size_t __n, char_type __a)
+        {return (char_type*)wmemset(__s, __a, __n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(WEOF);}
+};
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t>
+{
+    typedef char16_t       char_type;
+    typedef uint_least16_t int_type;
+    typedef streamoff      off_type;
+    typedef u16streampos   pos_type;
+    typedef mbstate_t      state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+        {__c1 = __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    static size_t           length(const char_type* __s);
+    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       assign(char_type* __s, size_t __n, char_type __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(0xDFFF);}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+int
+char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+char_traits<char16_t>::length(const char_type* __s)
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+const char16_t*
+char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a)
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char16_t*
+char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char16_t*
+char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char16_t*
+char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a)
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t>
+{
+    typedef char32_t       char_type;
+    typedef uint_least32_t int_type;
+    typedef streamoff      off_type;
+    typedef u32streampos   pos_type;
+    typedef mbstate_t      state_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT
+        {__c1 = __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
+        {return __c1 < __c2;}
+
+    static int              compare(const char_type* __s1, const char_type* __s2, size_t __n);
+    static size_t           length(const char_type* __s);
+    static const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
+    static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n);
+    static char_type*       assign(char_type* __s, size_t __n, char_type __a);
+
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
+        {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
+        {return char_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
+        {return int_type(__c);}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
+        {return __c1 == __c2;}
+    _LIBCPP_INLINE_VISIBILITY
+    static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
+        {return int_type(0xFFFFFFFF);}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+int
+char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
+{
+    for (; __n; --__n, ++__s1, ++__s2)
+    {
+        if (lt(*__s1, *__s2))
+            return -1;
+        if (lt(*__s2, *__s1))
+            return 1;
+    }
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+size_t
+char_traits<char32_t>::length(const char_type* __s)
+{
+    size_t __len = 0;
+    for (; !eq(*__s, char_type(0)); ++__s)
+        ++__len;
+    return __len;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+const char32_t*
+char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a)
+{
+    for (; __n; --__n)
+    {
+        if (eq(*__s, __a))
+            return __s;
+        ++__s;
+    }
+    return 0;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char32_t*
+char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    char_type* __r = __s1;
+    if (__s1 < __s2)
+    {
+        for (; __n; --__n, ++__s1, ++__s2)
+            assign(*__s1, *__s2);
+    }
+    else if (__s2 < __s1)
+    {
+        __s1 += __n;
+        __s2 += __n;
+        for (; __n; --__n)
+            assign(*--__s1, *--__s2);
+    }
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char32_t*
+char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
+{
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+    char_type* __r = __s1;
+    for (; __n; --__n, ++__s1, ++__s2)
+        assign(*__s1, *__s2);
+    return __r;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+char32_t*
+char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a)
+{
+    char_type* __r = __s;
+    for (; __n; --__n, ++__s)
+        assign(*__s, __a);
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+// helper fns for basic_string
+
+// __str_find
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find(const _CharT *__p, _SizeT __sz, 
+             _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos >= __sz)
+        return __npos;
+    const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
+    if (__r == 0)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find(const _CharT *__p, _SizeT __sz, 
+       const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    if (__pos > __sz || __sz - __pos < __n)
+        return __npos;
+    if (__n == 0)
+        return __pos;
+    const _CharT* __r = 
+        _VSTD::__search(__p + __pos, __p + __sz,
+                        __s, __s + __n, _Traits::eq,
+                        random_access_iterator_tag(), random_access_iterator_tag());
+    if (__r == __p + __sz)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+
+// __str_rfind
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_rfind(const _CharT *__p, _SizeT __sz, 
+              _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__sz < 1)
+        return __npos;
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+    {
+        if (_Traits::eq(*--__ps, __c))
+            return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_rfind(const _CharT *__p, _SizeT __sz, 
+        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    __pos = _VSTD::min(__pos, __sz);
+    if (__n < __sz - __pos)
+        __pos += __n;
+    else
+        __pos = __sz;
+    const _CharT* __r = _VSTD::__find_end(
+                  __p, __p + __pos, __s, __s + __n, _Traits::eq, 
+                        random_access_iterator_tag(), random_access_iterator_tag());
+    if (__n > 0 && __r == __p + __pos)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+// __str_find_first_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_first_of(const _CharT *__p, _SizeT __sz,
+                const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    if (__pos >= __sz || __n == 0)
+        return __npos;
+    const _CharT* __r = _VSTD::__find_first_of_ce
+        (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
+    if (__r == __p + __sz)
+        return __npos;
+    return static_cast<_SizeT>(__r - __p);
+}
+
+
+// __str_find_last_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY 
+__str_find_last_of(const _CharT *__p, _SizeT __sz,
+               const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+    {
+    if (__n != 0)
+    {
+        if (__pos < __sz)
+            ++__pos;
+        else
+            __pos = __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        {
+            const _CharT* __r = _Traits::find(__s, __n, *--__ps);
+            if (__r)
+                return static_cast<_SizeT>(__ps - __p);
+        }
+    }
+    return __npos;
+}
+
+
+// __str_find_first_not_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
+                    const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    if (__pos < __sz)
+    {
+        const _CharT* __pe = __p + __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
+            if (_Traits::find(__s, __n, *__ps) == 0)
+                return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
+                          _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos < __sz)
+    {
+        const _CharT* __pe = __p + __sz;
+        for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
+            if (!_Traits::eq(*__ps, __c))
+                return static_cast<_SizeT>(__ps - __p);
+    }
+    return __npos;
+}
+
+
+// __str_find_last_not_of
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
+                   const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
+{
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        if (_Traits::find(__s, __n, *--__ps) == 0)
+            return static_cast<_SizeT>(__ps - __p);
+    return __npos;
+}
+
+
+template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
+_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
+                         _CharT __c, _SizeT __pos) _NOEXCEPT
+{
+    if (__pos < __sz)
+        ++__pos;
+    else
+        __pos = __sz;
+    for (const _CharT* __ps = __p + __pos; __ps != __p;)
+        if (!_Traits::eq(*--__ps, __c))
+            return static_cast<_SizeT>(__ps - __p);
+    return __npos;
+}
+
+template<class _Ptr>
+size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e)
+{
+    typedef typename iterator_traits<_Ptr>::value_type value_type;
+    return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
+}
+
+// basic_string
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __x,
+          const basic_string<_CharT, _Traits, _Allocator>& __y);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const _CharT* __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y);
+
+template <bool>
+class _LIBCPP_TYPE_VIS_ONLY __basic_string_common
+{
+protected:
+    void __throw_length_error() const;
+    void __throw_out_of_range() const;
+};
+
+template <bool __b>
+void
+__basic_string_common<__b>::__throw_length_error() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw length_error("basic_string");
+#else
+    assert(!"basic_string length_error");
+#endif
+}
+
+template <bool __b>
+void
+__basic_string_common<__b>::__throw_out_of_range() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw out_of_range("basic_string");
+#else
+    assert(!"basic_string out_of_range");
+#endif
+}
+
+#ifdef _LIBCPP_MSVC
+#pragma warning( push )
+#pragma warning( disable: 4231 )
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>)
+#ifdef _LIBCPP_MSVC
+#pragma warning( pop )
+#endif // _LIBCPP_MSVC
+
+#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+template <class _CharT, size_t = sizeof(_CharT)>
+struct __padding
+{
+    unsigned char __xx[sizeof(_CharT)-1];
+};
+
+template <class _CharT>
+struct __padding<_CharT, 1>
+{
+};
+
+#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+template<class _CharT, class _Traits, class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY basic_string
+    : private __basic_string_common<true>
+{
+public:
+    typedef basic_string                                 __self;
+    typedef _Traits                                      traits_type;
+    typedef typename traits_type::char_type              value_type;
+    typedef _Allocator                                   allocator_type;
+    typedef allocator_traits<allocator_type>             __alloc_traits;
+    typedef typename __alloc_traits::size_type           size_type;
+    typedef typename __alloc_traits::difference_type     difference_type;
+    typedef value_type&                                  reference;
+    typedef const value_type&                            const_reference;
+    typedef typename __alloc_traits::pointer             pointer;
+    typedef typename __alloc_traits::const_pointer       const_pointer;
+
+    static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
+    static_assert((is_same<_CharT, value_type>::value),
+                  "traits_type::char_type must be the same type as CharT");
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+#if defined(_LIBCPP_RAW_ITERATORS)
+    typedef pointer                                      iterator;
+    typedef const_pointer                                const_iterator;
+#else  // defined(_LIBCPP_RAW_ITERATORS)
+    typedef __wrap_iter<pointer>                         iterator;
+    typedef __wrap_iter<const_pointer>                   const_iterator;
+#endif  // defined(_LIBCPP_RAW_ITERATORS)
+    typedef _VSTD::reverse_iterator<iterator>             reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>       const_reverse_iterator;
+
+private:
+
+#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+    struct __long
+    {
+        pointer   __data_;
+        size_type __size_;
+        size_type __cap_;
+    };
+
+#if _LIBCPP_BIG_ENDIAN
+    enum {__short_mask = 0x01};
+    enum {__long_mask  = 0x1ul};
+#else  // _LIBCPP_BIG_ENDIAN
+    enum {__short_mask = 0x80};
+    enum {__long_mask  = ~(size_type(~0) >> 1)};
+#endif  // _LIBCPP_BIG_ENDIAN
+
+    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
+                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
+
+    struct __short
+    {
+        value_type __data_[__min_cap];
+        struct
+            : __padding<value_type>
+        {
+            unsigned char __size_;
+        };
+    };
+
+#else
+
+    struct __long
+    {
+        size_type __cap_;
+        size_type __size_;
+        pointer   __data_;
+    };
+
+#if _LIBCPP_BIG_ENDIAN
+    enum {__short_mask = 0x80};
+    enum {__long_mask  = ~(size_type(~0) >> 1)};
+#else  // _LIBCPP_BIG_ENDIAN
+    enum {__short_mask = 0x01};
+    enum {__long_mask  = 0x1ul};
+#endif  // _LIBCPP_BIG_ENDIAN
+
+    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
+                      (sizeof(__long) - 1)/sizeof(value_type) : 2};
+
+    struct __short
+    {
+        union
+        {
+            unsigned char __size_;
+            value_type __lx;
+        };
+        value_type __data_[__min_cap];
+    };
+
+#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+    union __ulx{__long __lx; __short __lxx;};
+
+    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
+
+    struct __raw
+    {
+        size_type __words[__n_words];
+    };
+
+    struct __rep
+    {
+        union
+        {
+            __long  __l;
+            __short __s;
+            __raw   __r;
+        };
+    };
+
+    __compressed_pair<__rep, allocator_type> __r_;
+
+public:
+    static const size_type npos = -1;
+
+    _LIBCPP_INLINE_VISIBILITY basic_string()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a);
+    basic_string(const basic_string& __str);
+    basic_string(const basic_string& __str, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(basic_string&& __str)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(basic_string&& __str, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(const value_type* __s, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(const value_type* __s, size_type __n);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(size_type __n, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(size_type __n, value_type __c, const allocator_type& __a);
+    basic_string(const basic_string& __str, size_type __pos, size_type __n = npos,
+                 const allocator_type& __a = allocator_type());
+    template<class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string(_InputIterator __first, _InputIterator __last);
+    template<class _InputIterator>
+        _LIBCPP_INLINE_VISIBILITY
+        basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(initializer_list<value_type> __il);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    ~basic_string();
+
+    basic_string& operator=(const basic_string& __str);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& operator=(basic_string&& __str)
+        _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+                   is_nothrow_move_assignable<allocator_type>::value);
+#endif
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);}
+    basic_string& operator=(value_type __c);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+        {return iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+        {return iterator(this, __get_pointer() + size());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer() + size());}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+        {return iterator(__get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return const_iterator(__get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+        {return iterator(__get_pointer() + size());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+        {return const_iterator(__get_pointer() + size());}
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rbegin() _NOEXCEPT
+        {return reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rend() _NOEXCEPT
+        {return reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend() const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT
+        {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend() const _NOEXCEPT
+        {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT
+        {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend() const _NOEXCEPT
+        {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY size_type size() const _NOEXCEPT
+        {return __is_long() ? __get_long_size() : __get_short_size();}
+    _LIBCPP_INLINE_VISIBILITY size_type length() const _NOEXCEPT {return size();}
+    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY size_type capacity() const _NOEXCEPT
+        {return (__is_long() ? __get_long_cap() : __min_cap) - 1;}
+
+    void resize(size_type __n, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());}
+
+    void reserve(size_type res_arg = 0);
+    _LIBCPP_INLINE_VISIBILITY
+    void shrink_to_fit() _NOEXCEPT {reserve();}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;}
+
+    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const;
+    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __pos);
+
+    const_reference at(size_type __n) const;
+    reference       at(size_type __n);
+
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);}
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)         {return append(__s);}
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;}
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& append(const basic_string& __str);
+    basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
+    basic_string& append(const value_type* __s, size_type __n);
+    basic_string& append(const value_type* __s);
+    basic_string& append(size_type __n, value_type __c);
+    template<class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value,
+            basic_string&
+        >::type
+        append(_InputIterator __first, _InputIterator __last);
+    template<class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            basic_string&
+        >::type
+        append(_ForwardIterator __first, _ForwardIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    void push_back(value_type __c);
+    _LIBCPP_INLINE_VISIBILITY
+    void pop_back();
+    _LIBCPP_INLINE_VISIBILITY reference       front();
+    _LIBCPP_INLINE_VISIBILITY const_reference front() const;
+    _LIBCPP_INLINE_VISIBILITY reference       back();
+    _LIBCPP_INLINE_VISIBILITY const_reference back() const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& assign(const basic_string& __str);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& assign(basic_string&& str)
+        {*this = _VSTD::move(str); return *this;}
+#endif
+    basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
+    basic_string& assign(const value_type* __s, size_type __n);
+    basic_string& assign(const value_type* __s);
+    basic_string& assign(size_type __n, value_type __c);
+    template<class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value,
+            basic_string&
+        >::type
+        assign(_InputIterator __first, _InputIterator __last);
+    template<class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            basic_string&
+        >::type
+        assign(_ForwardIterator __first, _ForwardIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& insert(size_type __pos1, const basic_string& __str);
+    basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
+    basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
+    basic_string& insert(size_type __pos, const value_type* __s);
+    basic_string& insert(size_type __pos, size_type __n, value_type __c);
+    iterator      insert(const_iterator __pos, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY
+    iterator      insert(const_iterator __pos, size_type __n, value_type __c);
+    template<class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value,
+            iterator
+        >::type
+        insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
+    template<class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            iterator
+        >::type
+        insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __pos, initializer_list<value_type> __il)
+                    {return insert(__pos, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    basic_string& erase(size_type __pos = 0, size_type __n = npos);
+    _LIBCPP_INLINE_VISIBILITY
+    iterator      erase(const_iterator __pos);
+    _LIBCPP_INLINE_VISIBILITY
+    iterator      erase(const_iterator __first, const_iterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str);
+    basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
+    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
+    basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
+    basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s);
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
+    template<class _InputIterator>
+        typename enable_if
+        <
+            __is_input_iterator<_InputIterator>::value,
+            basic_string&
+        >::type
+        replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il)
+        {return replace(__i1, __i2, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
+    _LIBCPP_INLINE_VISIBILITY
+    basic_string substr(size_type __pos = 0, size_type __n = npos) const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(basic_string& __str)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value);
+
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type* c_str() const _NOEXCEPT {return data();}
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type* data() const _NOEXCEPT  {return _VSTD::__to_raw_pointer(__get_pointer());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT {return __alloc();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
+    size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
+    size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
+    size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
+    size_type rfind(value_type __c, size_type __pos = npos) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
+    size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
+    size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
+    size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_first_not_of(value_type __c, size_type __pos = 0) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
+    size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type find_last_not_of(value_type __c, size_type __pos = npos) const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(const basic_string& __str) const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    int compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
+    int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const;
+    int compare(const value_type* __s) const _NOEXCEPT;
+    int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
+    int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const;
+
+    _LIBCPP_INLINE_VISIBILITY bool __invariants() const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool __is_long() const _NOEXCEPT
+        {return bool(__r_.first().__s.__size_ & __short_mask);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type& __alloc() _NOEXCEPT
+        {return __r_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const allocator_type& __alloc() const _NOEXCEPT
+        {return __r_.second();}
+
+#ifdef _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_short_size(size_type __s) _NOEXCEPT
+#   if _LIBCPP_BIG_ENDIAN
+        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
+#   else
+        {__r_.first().__s.__size_ = (unsigned char)(__s);}
+#   endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __get_short_size() const _NOEXCEPT
+#   if _LIBCPP_BIG_ENDIAN
+        {return __r_.first().__s.__size_ >> 1;}
+#   else
+        {return __r_.first().__s.__size_;}
+#   endif
+
+#else  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_short_size(size_type __s) _NOEXCEPT
+#   if _LIBCPP_BIG_ENDIAN
+        {__r_.first().__s.__size_ = (unsigned char)(__s);}
+#   else
+        {__r_.first().__s.__size_ = (unsigned char)(__s << 1);}
+#   endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __get_short_size() const _NOEXCEPT
+#   if _LIBCPP_BIG_ENDIAN
+        {return __r_.first().__s.__size_;}
+#   else
+        {return __r_.first().__s.__size_ >> 1;}
+#   endif
+
+#endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_long_size(size_type __s) _NOEXCEPT
+        {__r_.first().__l.__size_ = __s;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __get_long_size() const _NOEXCEPT
+        {return __r_.first().__l.__size_;}
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_size(size_type __s) _NOEXCEPT
+        {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_long_cap(size_type __s) _NOEXCEPT
+        {__r_.first().__l.__cap_  = __long_mask | __s;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type __get_long_cap() const _NOEXCEPT
+        {return __r_.first().__l.__cap_ & size_type(~__long_mask);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __set_long_pointer(pointer __p) _NOEXCEPT
+        {__r_.first().__l.__data_ = __p;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer __get_long_pointer() _NOEXCEPT
+        {return __r_.first().__l.__data_;}
+    _LIBCPP_INLINE_VISIBILITY
+    const_pointer __get_long_pointer() const _NOEXCEPT
+        {return __r_.first().__l.__data_;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer __get_short_pointer() _NOEXCEPT
+        {return pointer_traits<pointer>::pointer_to(__r_.first().__s.__data_[0]);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_pointer __get_short_pointer() const _NOEXCEPT
+        {return pointer_traits<const_pointer>::pointer_to(__r_.first().__s.__data_[0]);}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer __get_pointer() _NOEXCEPT
+        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_pointer __get_pointer() const _NOEXCEPT
+        {return __is_long() ? __get_long_pointer() : __get_short_pointer();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __zero() _NOEXCEPT
+        {
+            size_type (&__a)[__n_words] = __r_.first().__r.__words;
+            for (unsigned __i = 0; __i < __n_words; ++__i)
+                __a[__i] = 0;
+        }
+
+    template <size_type __a> static
+        _LIBCPP_INLINE_VISIBILITY
+        size_type __align_it(size_type __s) _NOEXCEPT
+            {return __s + (__a-1) & ~(__a-1);}
+    enum {__alignment = 16};
+    static _LIBCPP_INLINE_VISIBILITY
+    size_type __recommend(size_type __s) _NOEXCEPT
+        {return (__s < __min_cap ? __min_cap :
+                 __align_it<sizeof(value_type) < __alignment ?
+                            __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;}
+
+    void __init(const value_type* __s, size_type __sz, size_type __reserve);
+    void __init(const value_type* __s, size_type __sz);
+    void __init(size_type __n, value_type __c);
+
+    template <class _InputIterator>
+    typename enable_if
+    <
+         __is_input_iterator  <_InputIterator>::value &&
+        !__is_forward_iterator<_InputIterator>::value,
+        void
+    >::type
+    __init(_InputIterator __first, _InputIterator __last);
+
+    template <class _ForwardIterator>
+    typename enable_if
+    <
+        __is_forward_iterator<_ForwardIterator>::value,
+        void
+    >::type
+    __init(_ForwardIterator __first, _ForwardIterator __last);
+
+    void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
+                   size_type __n_copy,  size_type __n_del,     size_type __n_add = 0);
+    void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
+                               size_type __n_copy,  size_type __n_del,
+                               size_type __n_add, const value_type* __p_new_stuff);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __erase_to_end(size_type __pos);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const basic_string& __str)
+        {__copy_assign_alloc(__str, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const basic_string& __str, true_type)
+        {
+            if (__alloc() != __str.__alloc())
+            {
+                clear();
+                shrink_to_fit();
+            }
+            __alloc() = __str.__alloc();
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const basic_string&, false_type) _NOEXCEPT
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign(basic_string& __str, false_type);
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign(basic_string& __str, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    __move_assign_alloc(basic_string& __str)
+        _NOEXCEPT_(
+            !__alloc_traits::propagate_on_container_move_assignment::value ||
+            is_nothrow_move_assignable<allocator_type>::value)
+    {__move_assign_alloc(__str, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_move_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(basic_string& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            __alloc() = _VSTD::move(__c.__alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(basic_string&, false_type)
+        _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_swap::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type&, allocator_type&, false_type) _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
+    _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
+
+    friend basic_string operator+<>(const basic_string&, const basic_string&);
+    friend basic_string operator+<>(const value_type*, const basic_string&);
+    friend basic_string operator+<>(value_type, const basic_string&);
+    friend basic_string operator+<>(const basic_string&, const value_type*);
+    friend basic_string operator+<>(const basic_string&, value_type);
+};
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
+#if _LIBCPP_DEBUG_LEVEL >= 2
+                                                                        __pos
+#endif
+                                                                      )
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    if (__c)
+    {
+        const_pointer __new_last = __get_pointer() + __pos;
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->base() > __new_last)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+    }
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string()
+    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __zero();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
+    : __r_(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __zero();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve)
+{
+    if (__reserve > max_size())
+        this->__throw_length_error();
+    pointer __p;
+    if (__reserve < __min_cap)
+    {
+        __set_short_size(__sz);
+        __p = __get_short_pointer();
+    }
+    else
+    {
+        size_type __cap = __recommend(__reserve);
+        __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __set_long_pointer(__p);
+        __set_long_cap(__cap+1);
+        __set_long_size(__sz);
+    }
+    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
+    traits_type::assign(__p[__sz], value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
+{
+    if (__sz > max_size())
+        this->__throw_length_error();
+    pointer __p;
+    if (__sz < __min_cap)
+    {
+        __set_short_size(__sz);
+        __p = __get_short_pointer();
+    }
+    else
+    {
+        size_type __cap = __recommend(__sz);
+        __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __set_long_pointer(__p);
+        __set_long_cap(__cap+1);
+        __set_long_size(__sz);
+    }
+    traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
+    traits_type::assign(__p[__sz], value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
+    __init(__s, traits_type::length(__s));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
+    : __r_(__a)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
+    __init(__s, traits_type::length(__s));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
+    __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
+    : __r_(__a)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
+    __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
+    : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))
+{
+    if (!__str.__is_long())
+        __r_.first().__r = __str.__r_.first().__r;
+    else
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
+    : __r_(__a)
+{
+    if (!__str.__is_long())
+        __r_.first().__r = __str.__r_.first().__r;
+    else
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+    : __r_(_VSTD::move(__str.__r_))
+{
+    __str.__zero();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
+    : __r_(__a)
+{
+    if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
+        __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+    else
+    {
+        __r_.first().__r = __str.__r_.first().__r;
+        __str.__zero();
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
+{
+    if (__n > max_size())
+        this->__throw_length_error();
+    pointer __p;
+    if (__n < __min_cap)
+    {
+        __set_short_size(__n);
+        __p = __get_short_pointer();
+    }
+    else
+    {
+        size_type __cap = __recommend(__n);
+        __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __set_long_pointer(__p);
+        __set_long_cap(__cap+1);
+        __set_long_size(__n);
+    }
+    traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c);
+    traits_type::assign(__p[__n], value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
+{
+    __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
+    : __r_(__a)
+{
+    __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
+                                                        const allocator_type& __a)
+    : __r_(__a)
+{
+    size_type __str_sz = __str.size();
+    if (__pos > __str_sz)
+        this->__throw_out_of_range();
+    __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template <class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value,
+    void
+>::type
+basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
+{
+    __zero();
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        if (__is_long())
+            __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    void
+>::type
+basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
+{
+    size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__sz > max_size())
+        this->__throw_length_error();
+    pointer __p;
+    if (__sz < __min_cap)
+    {
+        __set_short_size(__sz);
+        __p = __get_short_pointer();
+    }
+    else
+    {
+        size_type __cap = __recommend(__sz);
+        __p = __alloc_traits::allocate(__alloc(), __cap+1);
+        __set_long_pointer(__p);
+        __set_long_cap(__cap+1);
+        __set_long_size(__sz);
+    }
+    for (; __first != __last; ++__first, ++__p)
+        traits_type::assign(*__p, *__first);
+    traits_type::assign(*__p, value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
+{
+    __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
+                                                        const allocator_type& __a)
+    : __r_(__a)
+{
+    __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
+{
+    __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
+    : __r_(__a)
+{
+    __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>::~basic_string()
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
+    if (__is_long())
+        __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace
+    (size_type __old_cap, size_type __delta_cap, size_type __old_sz,
+     size_type __n_copy,  size_type __n_del,     size_type __n_add, const value_type* __p_new_stuff)
+{
+    size_type __ms = max_size();
+    if (__delta_cap > __ms - __old_cap - 1)
+        this->__throw_length_error();
+    pointer __old_p = __get_pointer();
+    size_type __cap = __old_cap < __ms / 2 - __alignment ?
+                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
+                          __ms - 1;
+    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
+    __invalidate_all_iterators();
+    if (__n_copy != 0)
+        traits_type::copy(_VSTD::__to_raw_pointer(__p),
+                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
+    if (__n_add != 0)
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add);
+    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
+    if (__sec_cp_sz != 0)
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
+                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz);
+    if (__old_cap+1 != __min_cap)
+        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
+    __set_long_pointer(__p);
+    __set_long_cap(__cap+1);
+    __old_sz = __n_copy + __n_add + __sec_cp_sz;
+    __set_long_size(__old_sz);
+    traits_type::assign(__p[__old_sz], value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
+                                                     size_type __n_copy,  size_type __n_del,     size_type __n_add)
+{
+    size_type __ms = max_size();
+    if (__delta_cap > __ms - __old_cap)
+        this->__throw_length_error();
+    pointer __old_p = __get_pointer();
+    size_type __cap = __old_cap < __ms / 2 - __alignment ?
+                          __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) :
+                          __ms - 1;
+    pointer __p = __alloc_traits::allocate(__alloc(), __cap+1);
+    __invalidate_all_iterators();
+    if (__n_copy != 0)
+        traits_type::copy(_VSTD::__to_raw_pointer(__p),
+                          _VSTD::__to_raw_pointer(__old_p), __n_copy);
+    size_type __sec_cp_sz = __old_sz - __n_del - __n_copy;
+    if (__sec_cp_sz != 0)
+        traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add,
+                          _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del,
+                          __sec_cp_sz);
+    if (__old_cap+1 != __min_cap)
+        __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1);
+    __set_long_pointer(__p);
+    __set_long_cap(__cap+1);
+}
+
+// assign
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
+    size_type __cap = capacity();
+    if (__cap >= __n)
+    {
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+        traits_type::move(__p, __s, __n);
+        traits_type::assign(__p[__n], value_type());
+        __set_size(__n);
+        __invalidate_iterators_past(__n);
+    }
+    else
+    {
+        size_type __sz = size();
+        __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c)
+{
+    size_type __cap = capacity();
+    if (__cap < __n)
+    {
+        size_type __sz = size();
+        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
+    }
+    else
+        __invalidate_iterators_past(__n);
+    value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+    traits_type::assign(__p, __n, __c);
+    traits_type::assign(__p[__n], value_type());
+    __set_size(__n);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c)
+{
+    pointer __p;
+    if (__is_long())
+    {
+        __p = __get_long_pointer();
+        __set_long_size(1);
+    }
+    else
+    {
+        __p = __get_short_pointer();
+        __set_short_size(1);
+    }
+    traits_type::assign(*__p, __c);
+    traits_type::assign(*++__p, value_type());
+    __invalidate_iterators_past(1);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
+{
+    if (this != &__str)
+    {
+        __copy_assign_alloc(__str);
+        assign(__str);
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type)
+{
+    if (__alloc() != __str.__alloc())
+        assign(__str);
+    else
+        __move_assign(__str, true_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+{
+    clear();
+    shrink_to_fit();
+    __r_.first() = __str.__r_.first();
+    __move_assign_alloc(__str);
+    __str.__zero();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
+    _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+               is_nothrow_move_assignable<allocator_type>::value)
+{
+    __move_assign(__str, integral_constant<bool,
+          __alloc_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+#endif
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value,
+    basic_string<_CharT, _Traits, _Allocator>&
+>::type
+basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
+{
+    clear();
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    basic_string<_CharT, _Traits, _Allocator>&
+>::type
+basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
+{
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    size_type __cap = capacity();
+    if (__cap < __n)
+    {
+        size_type __sz = size();
+        __grow_by(__cap, __n - __cap, __sz, 0, __sz);
+    }
+    else
+        __invalidate_iterators_past(__n);
+    pointer __p = __get_pointer();
+    for (; __first != __last; ++__first, ++__p)
+        traits_type::assign(*__p, *__first);
+    traits_type::assign(*__p, value_type());
+    __set_size(__n);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str)
+{
+    return assign(__str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n)
+{
+    size_type __sz = __str.size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    return assign(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
+    return assign(__s, traits_type::length(__s));
+}
+
+// append
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr");
+    size_type __cap = capacity();
+    size_type __sz = size();
+    if (__cap - __sz >= __n)
+    {
+        if (__n)
+        {
+            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+            traits_type::copy(__p + __sz, __s, __n);
+            __sz += __n;
+            __set_size(__sz);
+            traits_type::assign(__p[__sz], value_type());
+        }
+    }
+    else
+        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __sz, 0, __n, __s);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c)
+{
+    if (__n)
+    {
+        size_type __cap = capacity();
+        size_type __sz = size();
+        if (__cap - __sz < __n)
+            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+        pointer __p = __get_pointer();
+        traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c);
+        __sz += __n;
+        __set_size(__sz);
+        traits_type::assign(__p[__sz], value_type());
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c)
+{
+    bool __is_short = !__is_long();
+    size_type __cap;
+    size_type __sz;
+    if (__is_short)
+    {
+        __cap = __min_cap - 1;
+        __sz = __get_short_size();
+    }
+    else
+    {
+        __cap = __get_long_cap() - 1;
+        __sz = __get_long_size();
+    }
+    if (__sz == __cap)
+    {
+        __grow_by(__cap, 1, __sz, __sz, 0);
+        __is_short = !__is_long();
+    }
+    pointer __p;
+    if (__is_short)
+    {
+        __p = __get_short_pointer() + __sz;
+        __set_short_size(__sz+1);
+    }
+    else
+    {
+        __p = __get_long_pointer() + __sz;
+        __set_long_size(__sz+1);
+    }
+    traits_type::assign(*__p, __c);
+    traits_type::assign(*++__p, value_type());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value,
+    basic_string<_CharT, _Traits, _Allocator>&
+>::type
+basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    basic_string<_CharT, _Traits, _Allocator>&
+>::type
+basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last)
+{
+    size_type __sz = size();
+    size_type __cap = capacity();
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n)
+    {
+        if (__cap - __sz < __n)
+            __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0);
+        pointer __p = __get_pointer() + __sz;
+        for (; __first != __last; ++__p, ++__first)
+            traits_type::assign(*__p, *__first);
+        traits_type::assign(*__p, value_type());
+        __set_size(__sz + __n);
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
+{
+    return append(__str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n)
+{
+    size_type __sz = __str.size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    return append(__str.data() + __pos, _VSTD::min(__n, __sz - __pos));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr");
+    return append(__s, traits_type::length(__s));
+}
+
+// insert
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr");
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    size_type __cap = capacity();
+    if (__cap - __sz >= __n)
+    {
+        if (__n)
+        {
+            value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+            size_type __n_move = __sz - __pos;
+            if (__n_move != 0)
+            {
+                if (__p + __pos <= __s && __s < __p + __sz)
+                    __s += __n;
+                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
+            }
+            traits_type::move(__p + __pos, __s, __n);
+            __sz += __n;
+            __set_size(__sz);
+            traits_type::assign(__p[__sz], value_type());
+        }
+    }
+    else
+        __grow_by_and_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n, __s);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n, value_type __c)
+{
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    if (__n)
+    {
+        size_type __cap = capacity();
+        value_type* __p;
+        if (__cap - __sz >= __n)
+        {
+            __p = _VSTD::__to_raw_pointer(__get_pointer());
+            size_type __n_move = __sz - __pos;
+            if (__n_move != 0)
+                traits_type::move(__p + __pos + __n, __p + __pos, __n_move);
+        }
+        else
+        {
+            __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n);
+            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
+        }
+        traits_type::assign(__p + __pos, __n, __c);
+        __sz += __n;
+        __set_size(__sz);
+        traits_type::assign(__p[__sz], value_type());
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value,
+    typename basic_string<_CharT, _Traits, _Allocator>::iterator
+>::type
+basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
+    size_type __old_sz = size();
+    difference_type __ip = __pos - begin();
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+    pointer __p = __get_pointer();
+    _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(this, __p + __ip);
+#else
+    return iterator(__p + __ip);
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    typename basic_string<_CharT, _Traits, _Allocator>::iterator
+>::type
+basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
+    size_type __ip = static_cast<size_type>(__pos - begin());
+    size_type __sz = size();
+    size_type __cap = capacity();
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n)
+    {
+        value_type* __p;
+        if (__cap - __sz >= __n)
+        {
+            __p = _VSTD::__to_raw_pointer(__get_pointer());
+            size_type __n_move = __sz - __ip;
+            if (__n_move != 0)
+                traits_type::move(__p + __ip + __n, __p + __ip, __n_move);
+        }
+        else
+        {
+            __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n);
+            __p = _VSTD::__to_raw_pointer(__get_long_pointer());
+        }
+        __sz += __n;
+        __set_size(__sz);
+        traits_type::assign(__p[__sz], value_type());
+        for (__p += __ip; __first != __last; ++__p, ++__first)
+            traits_type::assign(*__p, *__first);
+    }
+    return begin() + __ip;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str)
+{
+    return insert(__pos1, __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str,
+                                                  size_type __pos2, size_type __n)
+{
+    size_type __str_sz = __str.size();
+    if (__pos2 > __str_sz)
+        this->__throw_out_of_range();
+    return insert(__pos1, __str.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr");
+    return insert(__pos, __s, traits_type::length(__s));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::iterator
+basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c)
+{
+    size_type __ip = static_cast<size_type>(__pos - begin());
+    size_type __sz = size();
+    size_type __cap = capacity();
+    value_type* __p;
+    if (__cap == __sz)
+    {
+        __grow_by(__cap, 1, __sz, __ip, 0, 1);
+        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
+    }
+    else
+    {
+        __p = _VSTD::__to_raw_pointer(__get_pointer());
+        size_type __n_move = __sz - __ip;
+        if (__n_move != 0)
+            traits_type::move(__p + __ip + 1, __p + __ip, __n_move);
+    }
+    traits_type::assign(__p[__ip], __c);
+    traits_type::assign(__p[++__sz], value_type());
+    __set_size(__sz);
+    return begin() + static_cast<difference_type>(__ip);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::iterator
+basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, n, value) called with an iterator not"
+        " referring to this string");
+#endif
+    difference_type __p = __pos - begin();
+    insert(static_cast<size_type>(__p), __n, __c);
+    return begin() + __p;
+}
+
+// replace
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
+{
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr");
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    __n1 = _VSTD::min(__n1, __sz - __pos);
+    size_type __cap = capacity();
+    if (__cap - __sz + __n1 >= __n2)
+    {
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+        if (__n1 != __n2)
+        {
+            size_type __n_move = __sz - __pos - __n1;
+            if (__n_move != 0)
+            {
+                if (__n1 > __n2)
+                {
+                    traits_type::move(__p + __pos, __s, __n2);
+                    traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
+                    goto __finish;
+                }
+                if (__p + __pos < __s && __s < __p + __sz)
+                {
+                    if (__p + __pos + __n1 <= __s)
+                        __s += __n2 - __n1;
+                    else // __p + __pos < __s < __p + __pos + __n1
+                    {
+                        traits_type::move(__p + __pos, __s, __n1);
+                        __pos += __n1;
+                        __s += __n2;
+                        __n2 -= __n1;
+                        __n1 = 0;
+                    }
+                }
+                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
+            }
+        }
+        traits_type::move(__p + __pos, __s, __n2);
+__finish:
+        __sz += __n2 - __n1;
+        __set_size(__sz);
+        __invalidate_iterators_past(__sz);
+        traits_type::assign(__p[__sz], value_type());
+    }
+    else
+        __grow_by_and_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2, __s);
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, size_type __n2, value_type __c)
+{
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    __n1 = _VSTD::min(__n1, __sz - __pos);
+    size_type __cap = capacity();
+    value_type* __p;
+    if (__cap - __sz + __n1 >= __n2)
+    {
+        __p = _VSTD::__to_raw_pointer(__get_pointer());
+        if (__n1 != __n2)
+        {
+            size_type __n_move = __sz - __pos - __n1;
+            if (__n_move != 0)
+                traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
+        }
+    }
+    else
+    {
+        __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2);
+        __p = _VSTD::__to_raw_pointer(__get_long_pointer());
+    }
+    traits_type::assign(__p + __pos, __n2, __c);
+    __sz += __n2 - __n1;
+    __set_size(__sz);
+    __invalidate_iterators_past(__sz);
+    traits_type::assign(__p[__sz], value_type());
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+template<class _InputIterator>
+typename enable_if
+<
+    __is_input_iterator<_InputIterator>::value,
+    basic_string<_CharT, _Traits, _Allocator>&
+>::type
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
+                                                   _InputIterator __j1, _InputIterator __j2)
+{
+    for (; true; ++__i1, ++__j1)
+    {
+        if (__i1 == __i2)
+        {
+            if (__j1 != __j2)
+                insert(__i1, __j1, __j2);
+            break;
+        }
+        if (__j1 == __j2)
+        {
+            erase(__i1, __i2);
+            break;
+        }
+        traits_type::assign(const_cast<value_type&>(*__i1), *__j1);
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str)
+{
+    return replace(__pos1, __n1, __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str,
+                                                   size_type __pos2, size_type __n2)
+{
+    size_type __str_sz = __str.size();
+    if (__pos2 > __str_sz)
+        this->__throw_out_of_range();
+    return replace(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr");
+    return replace(__pos, __n1, __s, traits_type::length(__s));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str)
+{
+    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1),
+                   __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n)
+{
+    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s, __n);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s)
+{
+    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __s);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c)
+{
+    return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c);
+}
+
+// erase
+
+template <class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>&
+basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
+{
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    if (__n)
+    {
+        value_type* __p = _VSTD::__to_raw_pointer(__get_pointer());
+        __n = _VSTD::min(__n, __sz - __pos);
+        size_type __n_move = __sz - __pos - __n;
+        if (__n_move != 0)
+            traits_type::move(__p + __pos, __p + __pos + __n, __n_move);
+        __sz -= __n;
+        __set_size(__sz);
+        __invalidate_iterators_past(__sz);
+        traits_type::assign(__p[__sz], value_type());
+    }
+    return *this;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::iterator
+basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::erase(iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__pos != end(),
+        "string::erase(iterator) called with a non-dereferenceable iterator");
+    iterator __b = begin();
+    size_type __r = static_cast<size_type>(__pos - __b);
+    erase(__r, 1);
+    return __b + static_cast<difference_type>(__r);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::iterator
+basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "string::erase(iterator,  iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
+    iterator __b = begin();
+    size_type __r = static_cast<size_type>(__first - __b);
+    erase(__r, static_cast<size_type>(__last - __first));
+    return __b + static_cast<difference_type>(__r);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::pop_back()
+{
+    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
+    size_type __sz;
+    if (__is_long())
+    {
+        __sz = __get_long_size() - 1;
+        __set_long_size(__sz);
+        traits_type::assign(*(__get_long_pointer() + __sz), value_type());
+    }
+    else
+    {
+        __sz = __get_short_size() - 1;
+        __set_short_size(__sz);
+        traits_type::assign(*(__get_short_pointer() + __sz), value_type());
+    }
+    __invalidate_iterators_past(__sz);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT
+{
+    __invalidate_all_iterators();
+    if (__is_long())
+    {
+        traits_type::assign(*__get_long_pointer(), value_type());
+        __set_long_size(0);
+    }
+    else
+    {
+        traits_type::assign(*__get_short_pointer(), value_type());
+        __set_short_size(0);
+    }
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos)
+{
+    if (__is_long())
+    {
+        traits_type::assign(*(__get_long_pointer() + __pos), value_type());
+        __set_long_size(__pos);
+    }
+    else
+    {
+        traits_type::assign(*(__get_short_pointer() + __pos), value_type());
+        __set_short_size(__pos);
+    }
+    __invalidate_iterators_past(__pos);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c)
+{
+    size_type __sz = size();
+    if (__n > __sz)
+        append(__n - __sz, __c);
+    else
+        __erase_to_end(__n);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT
+{
+    size_type __m = __alloc_traits::max_size(__alloc());
+#if _LIBCPP_BIG_ENDIAN
+    return (__m <= ~__long_mask ? __m : __m/2) - __alignment;
+#else
+    return __m - __alignment;
+#endif
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+void
+basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg)
+{
+    if (__res_arg > max_size())
+        this->__throw_length_error();
+    size_type __cap = capacity();
+    size_type __sz = size();
+    __res_arg = _VSTD::max(__res_arg, __sz);
+    __res_arg = __recommend(__res_arg);
+    if (__res_arg != __cap)
+    {
+        pointer __new_data, __p;
+        bool __was_long, __now_long;
+        if (__res_arg == __min_cap - 1)
+        {
+            __was_long = true;
+            __now_long = false;
+            __new_data = __get_short_pointer();
+            __p = __get_long_pointer();
+        }
+        else
+        {
+            if (__res_arg > __cap)
+                __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
+            else
+            {
+            #ifndef _LIBCPP_NO_EXCEPTIONS
+                try
+                {
+            #endif  // _LIBCPP_NO_EXCEPTIONS
+                    __new_data = __alloc_traits::allocate(__alloc(), __res_arg+1);
+            #ifndef _LIBCPP_NO_EXCEPTIONS
+                }
+                catch (...)
+                {
+                    return;
+                }
+            #else  // _LIBCPP_NO_EXCEPTIONS
+                if (__new_data == nullptr)
+                    return;
+            #endif  // _LIBCPP_NO_EXCEPTIONS
+            }
+            __now_long = true;
+            __was_long = __is_long();
+            __p = __get_pointer();
+        }
+        traits_type::copy(_VSTD::__to_raw_pointer(__new_data),
+                          _VSTD::__to_raw_pointer(__p), size()+1);
+        if (__was_long)
+            __alloc_traits::deallocate(__alloc(), __p, __cap+1);
+        if (__now_long)
+        {
+            __set_long_cap(__res_arg+1);
+            __set_long_size(__sz);
+            __set_long_pointer(__new_data);
+        }
+        else
+            __set_short_size(__sz);
+        __invalidate_all_iterators();
+    }
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::const_reference
+basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
+{
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
+    return *(data() + __pos);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::reference
+basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
+{
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
+    return *(__get_pointer() + __pos);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::const_reference
+basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return (*this)[__n];
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::reference
+basic_string<_CharT, _Traits, _Allocator>::at(size_type __n)
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return (*this)[__n];
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::reference
+basic_string<_CharT, _Traits, _Allocator>::front()
+{
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
+    return *__get_pointer();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::const_reference
+basic_string<_CharT, _Traits, _Allocator>::front() const
+{
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
+    return *data();
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::reference
+basic_string<_CharT, _Traits, _Allocator>::back()
+{
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
+    return *(__get_pointer() + size() - 1);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::const_reference
+basic_string<_CharT, _Traits, _Allocator>::back() const
+{
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
+    return *(data() + size() - 1);
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, size_type __pos) const
+{
+    size_type __sz = size();
+    if (__pos > __sz)
+        this->__throw_out_of_range();
+    size_type __rlen = _VSTD::min(__n, __sz - __pos);
+    traits_type::copy(__s, data() + __pos, __rlen);
+    return __rlen;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const
+{
+    return basic_string(*this, __pos, __n, __alloc());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    if (!__is_long())
+        __get_db()->__invalidate_all(this);
+    if (!__str.__is_long())
+        __get_db()->__invalidate_all(&__str);
+    __get_db()->swap(this, &__str);
+#endif
+    _VSTD::swap(__r_.first(), __str.__r_.first());
+    __swap_alloc(__alloc(), __str.__alloc());
+}
+
+// find
+
+template <class _Traits>
+struct _LIBCPP_HIDDEN __traits_eq
+{
+    typedef typename _Traits::char_type char_type;
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const char_type& __x, const char_type& __y) _NOEXCEPT
+        {return _Traits::eq(__x, __y);}
+};
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
+                                                size_type __pos,
+                                                size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr");
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
+                                                size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
+                                                size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr");
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find(value_type __c,
+                                                size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find<value_type, size_type, traits_type, npos>
+        (data(), size(), __c, __pos);
+}
+
+// rfind
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
+                                                 size_type __pos,
+                                                 size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr");
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
+                                                 size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
+                                                 size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr");
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c,
+                                                 size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
+        (data(), size(), __c, __pos);
+}
+
+// find_first_of
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
+                                                         size_type __pos,
+                                                         size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr");
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str,
+                                                         size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
+                                                         size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr");
+    return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c,
+                                                         size_type __pos) const _NOEXCEPT
+{
+    return find(__c, __pos);
+}
+
+// find_last_of
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
+                                                        size_type __pos,
+                                                        size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr");
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str,
+                                                        size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
+                                                        size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr");
+    return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c,
+                                                        size_type __pos) const _NOEXCEPT
+{
+    return rfind(__c, __pos);
+}
+
+// find_first_not_of
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
+                                                             size_type __pos,
+                                                             size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr");
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str,
+                                                             size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
+                                                             size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr");
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c,
+                                                             size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __c, __pos);
+}
+
+// find_last_not_of
+
+template<class _CharT, class _Traits, class _Allocator>
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
+                                                            size_type __pos,
+                                                            size_type __n) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr");
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, __n);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str,
+                                                            size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __str.data(), __pos, __str.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
+                                                            size_type __pos) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr");
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __s, __pos, traits_type::length(__s));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename basic_string<_CharT, _Traits, _Allocator>::size_type
+basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
+                                                            size_type __pos) const _NOEXCEPT
+{
+    return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
+        (data(), size(), __c, __pos);
+}
+
+// compare
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT
+{
+    size_t __lhs_sz = size();
+    size_t __rhs_sz = __str.size();
+    int __result = traits_type::compare(data(), __str.data(),
+                                        _VSTD::min(__lhs_sz, __rhs_sz));
+    if (__result != 0)
+        return __result;
+    if (__lhs_sz < __rhs_sz)
+        return -1;
+    if (__lhs_sz > __rhs_sz)
+        return 1;
+    return 0;
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
+                                                   size_type __n1,
+                                                   const basic_string& __str) const
+{
+    return compare(__pos1, __n1, __str.data(), __str.size());
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
+                                                   size_type __n1,
+                                                   const basic_string& __str,
+                                                   size_type __pos2,
+                                                   size_type __n2) const
+{
+    size_type __sz = __str.size();
+    if (__pos2 > __sz)
+        this->__throw_out_of_range();
+    return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2,
+                                                                  __sz - __pos2));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
+    return compare(0, npos, __s, traits_type::length(__s));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
+                                                   size_type __n1,
+                                                   const value_type* __s) const
+{
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
+    return compare(__pos1, __n1, __s, traits_type::length(__s));
+}
+
+template <class _CharT, class _Traits, class _Allocator>
+int
+basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
+                                                   size_type __n1,
+                                                   const value_type* __s,
+                                                   size_type __n2) const
+{
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr");
+    size_type __sz = size();
+    if (__pos1 > __sz || __n2 == npos)
+        this->__throw_out_of_range();
+    size_type __rlen = _VSTD::min(__n1, __sz - __pos1);
+    int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2));
+    if (__r == 0)
+    {
+        if (__rlen < __n2)
+            __r = -1;
+        else if (__rlen > __n2)
+            __r = 1;
+    }
+    return __r;
+}
+
+// __invariants
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+basic_string<_CharT, _Traits, _Allocator>::__invariants() const
+{
+    if (size() > capacity())
+        return false;
+    if (capacity() < __min_cap - 1)
+        return false;
+    if (data() == 0)
+        return false;
+    if (data()[size()] != value_type(0))
+        return false;
+    return true;
+}
+
+// operator==
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    size_t __lhs_sz = __lhs.size();
+    return __lhs_sz == __rhs.size() && _Traits::compare(__lhs.data(),
+                                                        __rhs.data(),
+                                                        __lhs_sz) == 0;
+}
+
+template<class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const basic_string<char, char_traits<char>, _Allocator>& __lhs,
+           const basic_string<char, char_traits<char>, _Allocator>& __rhs) _NOEXCEPT
+{
+    size_t __lhs_sz = __lhs.size();
+    if (__lhs_sz != __rhs.size())
+        return false;
+    const char* __lp = __lhs.data();
+    const char* __rp = __rhs.data();
+    if (__lhs.__is_long())
+        return char_traits<char>::compare(__lp, __rp, __lhs_sz) == 0;
+    for (; __lhs_sz != 0; --__lhs_sz, ++__lp, ++__rp)
+        if (*__lp != *__rp)
+            return false;
+    return true;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return __rhs.compare(__lhs) == 0;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return __lhs.compare(__rhs) == 0;
+}
+
+// operator!=
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__lhs == __rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__lhs == __rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return !(__lhs == __rhs);
+}
+
+// operator<
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return __lhs.compare(__rhs) < 0;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return __lhs.compare(__rhs) < 0;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return __rhs.compare(__lhs) > 0;
+}
+
+// operator>
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return __rhs < __lhs;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return __rhs < __lhs;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return __rhs < __lhs;
+}
+
+// operator<=
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__rhs < __lhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return !(__rhs < __lhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__rhs < __lhs);
+}
+
+// operator>=
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__lhs < __rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+           const _CharT* __rhs) _NOEXCEPT
+{
+    return !(__lhs < __rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const _CharT* __lhs,
+           const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT
+{
+    return !(__lhs < __rhs);
+}
+
+// operator +
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
+          const basic_string<_CharT, _Traits, _Allocator>& __rhs)
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
+    __r.append(__rhs.data(), __rhs_sz);
+    return __r;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const _CharT* __lhs , const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = _Traits::length(__lhs);
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__init(__lhs, __lhs_sz, __lhs_sz + __rhs_sz);
+    __r.append(__rhs.data(), __rhs_sz);
+    return __r;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs)
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(__rhs.get_allocator());
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = __rhs.size();
+    __r.__init(&__lhs, 1, 1 + __rhs_sz);
+    __r.append(__rhs.data(), __rhs_sz);
+    return __r;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
+    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
+    __r.append(__rhs, __rhs_sz);
+    return __r;
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, _CharT __rhs)
+{
+    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
+    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
+    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + 1);
+    __r.push_back(__rhs);
+    return __r;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const basic_string<_CharT, _Traits, _Allocator>& __rhs)
+{
+    return _VSTD::move(__lhs.append(__rhs));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
+{
+    return _VSTD::move(__rhs.insert(0, __lhs));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits, _Allocator>&& __rhs)
+{
+    return _VSTD::move(__lhs.append(__rhs));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(const _CharT* __lhs , basic_string<_CharT,_Traits,_Allocator>&& __rhs)
+{
+    return _VSTD::move(__rhs.insert(0, __lhs));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(_CharT __lhs, basic_string<_CharT,_Traits,_Allocator>&& __rhs)
+{
+    __rhs.insert(__rhs.begin(), __lhs);
+    return _VSTD::move(__rhs);
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const _CharT* __rhs)
+{
+    return _VSTD::move(__lhs.append(__rhs));
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_string<_CharT, _Traits, _Allocator>
+operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT __rhs)
+{
+    __lhs.push_back(__rhs);
+    return _VSTD::move(__lhs);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+// swap
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
+     basic_string<_CharT, _Traits, _Allocator>& __rhs)
+     _NOEXCEPT_(_NOEXCEPT_(__lhs.swap(__rhs)))
+{
+    __lhs.swap(__rhs);
+}
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+
+typedef basic_string<char16_t> u16string;
+typedef basic_string<char32_t> u32string;
+
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
+_LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long long          stoll (const string& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10);
+
+_LIBCPP_FUNC_VIS float       stof (const string& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = 0);
+
+_LIBCPP_FUNC_VIS string to_string(int __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned __val);
+_LIBCPP_FUNC_VIS string to_string(long __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned long __val);
+_LIBCPP_FUNC_VIS string to_string(long long __val);
+_LIBCPP_FUNC_VIS string to_string(unsigned long long __val);
+_LIBCPP_FUNC_VIS string to_string(float __val);
+_LIBCPP_FUNC_VIS string to_string(double __val);
+_LIBCPP_FUNC_VIS string to_string(long double __val);
+
+_LIBCPP_FUNC_VIS int                stoi  (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long               stol  (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long      stoul (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS long long          stoll (const wstring& __str, size_t* __idx = 0, int __base = 10);
+_LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10);
+
+_LIBCPP_FUNC_VIS float       stof (const wstring& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = 0);
+_LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = 0);
+
+_LIBCPP_FUNC_VIS wstring to_wstring(int __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(float __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(double __val);
+_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
+
+template<class _CharT, class _Traits, class _Allocator>
+    const typename basic_string<_CharT, _Traits, _Allocator>::size_type
+                   basic_string<_CharT, _Traits, _Allocator>::npos;
+
+template<class _CharT, class _Traits, class _Allocator>
+struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string<_CharT, _Traits, _Allocator> >
+    : public unary_function<basic_string<_CharT, _Traits, _Allocator>, size_t>
+{
+    size_t
+        operator()(const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT;
+};
+
+template<class _CharT, class _Traits, class _Allocator>
+size_t
+hash<basic_string<_CharT, _Traits, _Allocator> >::operator()(
+        const basic_string<_CharT, _Traits, _Allocator>& __val) const _NOEXCEPT
+{
+    return __do_string_hash(__val.data(), __val.data() + __val.size());
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const basic_string<_CharT, _Traits, _Allocator>& __str);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           basic_string<_CharT, _Traits, _Allocator>& __str);
+
+template<class _CharT, class _Traits, class _Allocator>
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str);
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>&& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm);
+
+template<class _CharT, class _Traits, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+getline(basic_istream<_CharT, _Traits>&& __is,
+        basic_string<_CharT, _Traits, _Allocator>& __str);
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+    return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+    return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p < this->data() + this->size();
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+#if _LIBCPP_STD_VER > 11 
+// Literal suffixes for basic_string [basic.string.literals]
+inline namespace literals
+{
+  inline namespace string_literals
+  {
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char> operator "" s( const char *__str, size_t __len )
+    {
+        return basic_string<char> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len )
+    {
+        return basic_string<wchar_t> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len )
+    {
+        return basic_string<char16_t> (__str, __len);
+    }
+
+    inline _LIBCPP_INLINE_VISIBILITY
+    basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len )
+    {
+        return basic_string<char32_t> (__str, __len);
+    }
+  }
+}
+#endif
+
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STRING
diff --git a/include/c++/v1/strstream b/include/c++/v1/strstream
new file mode 100644
index 0000000..81eef2a
--- /dev/null
+++ b/include/c++/v1/strstream
@@ -0,0 +1,400 @@
+// -*- C++ -*-
+//===--------------------------- strstream --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STRSTREAM
+#define _LIBCPP_STRSTREAM
+
+/*
+    strstream synopsis
+
+class strstreambuf
+    : public basic_streambuf<char>
+{
+public:
+    explicit strstreambuf(streamsize alsize_arg = 0);
+    strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
+    strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0);
+    strstreambuf(const char* gnext_arg, streamsize n);
+
+    strstreambuf(signed char* gnext_arg, streamsize n, signed char* pbeg_arg = 0);
+    strstreambuf(const signed char* gnext_arg, streamsize n);
+    strstreambuf(unsigned char* gnext_arg, streamsize n, unsigned char* pbeg_arg = 0);
+    strstreambuf(const unsigned char* gnext_arg, streamsize n);
+
+    strstreambuf(strstreambuf&& rhs);
+    strstreambuf& operator=(strstreambuf&& rhs);
+
+    virtual ~strstreambuf();
+
+    void swap(strstreambuf& rhs);
+
+    void freeze(bool freezefl = true);
+    char* str();
+    int pcount() const;
+
+protected:
+    virtual int_type overflow (int_type c = EOF);
+    virtual int_type pbackfail(int_type c = EOF);
+    virtual int_type underflow();
+    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type sp,
+                             ios_base::openmode which = ios_base::in | ios_base::out);
+    virtual streambuf* setbuf(char* s, streamsize n);
+
+private:
+    typedef T1 strstate;                // exposition only
+    static const strstate allocated;    // exposition only
+    static const strstate constant;     // exposition only
+    static const strstate dynamic;      // exposition only
+    static const strstate frozen;       // exposition only
+    strstate strmode;                   // exposition only
+    streamsize alsize;                  // exposition only
+    void* (*palloc)(size_t);            // exposition only
+    void (*pfree)(void*);               // exposition only
+};
+
+class istrstream
+    : public basic_istream<char>
+{
+public:
+    explicit istrstream(const char* s);
+    explicit istrstream(char* s);
+    istrstream(const char* s, streamsize n);
+    istrstream(char* s, streamsize n);
+
+    virtual ~istrstream();
+
+    strstreambuf* rdbuf() const;
+    char *str();
+
+private:
+    strstreambuf sb; // exposition only
+};
+
+class ostrstream
+    : public basic_ostream<char>
+{
+public:
+    ostrstream();
+    ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);
+
+    virtual ~ostrstream();
+
+    strstreambuf* rdbuf() const;
+    void freeze(bool freezefl = true);
+    char* str();
+    int pcount() const;
+
+private:
+    strstreambuf sb; // exposition only
+};
+
+class strstream
+    : public basic_iostream<char>
+{
+public:
+    // Types
+    typedef char                        char_type;
+    typedef char_traits<char>::int_type int_type;
+    typedef char_traits<char>::pos_type pos_type;
+    typedef char_traits<char>::off_type off_type;
+
+    // constructors/destructor
+    strstream();
+    strstream(char* s, int n, ios_base::openmode mode = ios_base::in | ios_base::out);
+
+    virtual ~strstream();
+
+    // Members:
+    strstreambuf* rdbuf() const;
+    void freeze(bool freezefl = true);
+    int pcount() const;
+    char* str();
+
+private:
+    strstreambuf sb; // exposition only
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <ostream>
+#include <istream>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS strstreambuf
+    : public streambuf
+{
+public:
+    explicit strstreambuf(streamsize __alsize = 0);
+    strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*));
+    strstreambuf(char* __gnext, streamsize __n, char* __pbeg = 0);
+    strstreambuf(const char* __gnext, streamsize __n);
+
+    strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg = 0);
+    strstreambuf(const signed char* __gnext, streamsize __n);
+    strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg = 0);
+    strstreambuf(const unsigned char* __gnext, streamsize __n);
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    strstreambuf(strstreambuf&& __rhs);
+    _LIBCPP_INLINE_VISIBILITY
+    strstreambuf& operator=(strstreambuf&& __rhs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    virtual ~strstreambuf();
+
+    void swap(strstreambuf& __rhs);
+
+    void freeze(bool __freezefl = true);
+    char* str();
+    int pcount() const;
+
+protected:
+    virtual int_type overflow (int_type __c = EOF);
+    virtual int_type pbackfail(int_type __c = EOF);
+    virtual int_type underflow();
+    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
+                             ios_base::openmode __which = ios_base::in | ios_base::out);
+    virtual pos_type seekpos(pos_type __sp,
+                             ios_base::openmode __which = ios_base::in | ios_base::out);
+
+private:
+    typedef unsigned __mode_type;
+    static const __mode_type __allocated = 0x01;
+    static const __mode_type __constant  = 0x02;
+    static const __mode_type __dynamic   = 0x04;
+    static const __mode_type __frozen    = 0x08;
+    static const streamsize    __default_alsize = 4096;
+
+    __mode_type __strmode_;
+    streamsize __alsize_;
+    void* (*__palloc_)(size_t);
+    void (*__pfree_)(void*);
+
+    void __init(char* __gnext, streamsize __n, char* __pbeg);
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+inline _LIBCPP_INLINE_VISIBILITY
+strstreambuf::strstreambuf(strstreambuf&& __rhs)
+    : streambuf(__rhs),
+      __strmode_(__rhs.__strmode_),
+      __alsize_(__rhs.__alsize_),
+      __palloc_(__rhs.__palloc_),
+      __pfree_(__rhs.__pfree_)
+{
+    __rhs.setg(nullptr, nullptr, nullptr);
+    __rhs.setp(nullptr, nullptr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+strstreambuf&
+strstreambuf::operator=(strstreambuf&& __rhs)
+{
+    if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
+    {
+        if (__pfree_)
+            __pfree_(eback());
+        else
+            delete [] eback();
+    }
+    streambuf::operator=(__rhs);
+    __strmode_ = __rhs.__strmode_;
+    __alsize_ = __rhs.__alsize_;
+    __palloc_ = __rhs.__palloc_;
+    __pfree_ = __rhs.__pfree_;
+    __rhs.setg(nullptr, nullptr, nullptr);
+    __rhs.setp(nullptr, nullptr);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+class _LIBCPP_TYPE_VIS istrstream
+    : public istream
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit istrstream(const char* __s)
+        : istream(&__sb_), __sb_(__s, 0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit istrstream(char* __s)
+        : istream(&__sb_), __sb_(__s, 0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    istrstream(const char* __s, streamsize __n)
+        : istream(&__sb_), __sb_(__s, __n) {}
+    _LIBCPP_INLINE_VISIBILITY
+    istrstream(char* __s, streamsize __n)
+        : istream(&__sb_), __sb_(__s, __n) {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    istrstream(istrstream&& __rhs)
+        : istream(_VSTD::move(__rhs)),
+          __sb_(_VSTD::move(__rhs.__sb_))
+    {
+        istream::set_rdbuf(&__sb_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    istrstream& operator=(istrstream&& __rhs)
+    {
+        istream::operator=(_VSTD::move(__rhs));
+        __sb_ = _VSTD::move(__rhs.__sb_);
+        return *this;
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    virtual ~istrstream();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(istrstream& __rhs)
+    {
+        istream::swap(__rhs);
+        __sb_.swap(__rhs.__sb_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
+    _LIBCPP_INLINE_VISIBILITY
+    char *str() {return __sb_.str();}
+
+private:
+    strstreambuf __sb_;
+};
+
+class _LIBCPP_TYPE_VIS ostrstream
+    : public ostream
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    ostrstream()
+        : ostream(&__sb_) {}
+    _LIBCPP_INLINE_VISIBILITY
+    ostrstream(char* __s, int __n, ios_base::openmode __mode = ios_base::out)
+        : ostream(&__sb_),
+          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    ostrstream(ostrstream&& __rhs)
+        : ostream(_VSTD::move(__rhs)),
+          __sb_(_VSTD::move(__rhs.__sb_))
+    {
+        ostream::set_rdbuf(&__sb_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    ostrstream& operator=(ostrstream&& __rhs)
+    {
+        ostream::operator=(_VSTD::move(__rhs));
+        __sb_ = _VSTD::move(__rhs.__sb_);
+        return *this;
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    virtual ~ostrstream();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(ostrstream& __rhs)
+    {
+        ostream::swap(__rhs);
+        __sb_.swap(__rhs.__sb_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}
+    _LIBCPP_INLINE_VISIBILITY
+    char* str()         {return __sb_.str();}
+    _LIBCPP_INLINE_VISIBILITY
+    int pcount() const  {return __sb_.pcount();}
+
+private:
+    strstreambuf __sb_; // exposition only
+};
+
+class _LIBCPP_TYPE_VIS strstream
+    : public iostream
+{
+public:
+    // Types
+    typedef char                        char_type;
+    typedef char_traits<char>::int_type int_type;
+    typedef char_traits<char>::pos_type pos_type;
+    typedef char_traits<char>::off_type off_type;
+
+    // constructors/destructor
+    _LIBCPP_INLINE_VISIBILITY
+    strstream()
+        : iostream(&__sb_) {}
+    _LIBCPP_INLINE_VISIBILITY
+    strstream(char* __s, int __n, ios_base::openmode __mode = ios_base::in | ios_base::out)
+        : iostream(&__sb_),
+          __sb_(__s, __n, __s + (__mode & ios::app ? strlen(__s) : 0))
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    strstream(strstream&& __rhs)
+        : iostream(_VSTD::move(__rhs)),
+          __sb_(_VSTD::move(__rhs.__sb_))
+    {
+        iostream::set_rdbuf(&__sb_);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    strstream& operator=(strstream&& __rhs)
+    {
+        iostream::operator=(_VSTD::move(__rhs));
+        __sb_ = _VSTD::move(__rhs.__sb_);
+        return *this;
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    virtual ~strstream();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(strstream& __rhs)
+    {
+        iostream::swap(__rhs);
+        __sb_.swap(__rhs.__sb_);
+    }
+
+    // Members:
+    _LIBCPP_INLINE_VISIBILITY
+    strstreambuf* rdbuf() const {return const_cast<strstreambuf*>(&__sb_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void freeze(bool __freezefl = true) {__sb_.freeze(__freezefl);}
+    _LIBCPP_INLINE_VISIBILITY
+    int pcount() const {return __sb_.pcount();}
+    _LIBCPP_INLINE_VISIBILITY
+    char* str()        {return __sb_.str();}
+
+private:
+    strstreambuf __sb_; // exposition only
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_STRSTREAM
diff --git a/include/c++/v1/support/android/locale_bionic.h b/include/c++/v1/support/android/locale_bionic.h
new file mode 100644
index 0000000..354fcfe
--- /dev/null
+++ b/include/c++/v1/support/android/locale_bionic.h
@@ -0,0 +1,192 @@
+// -*- C++ -*-
+//===------------------- support/android/locale_bionic.h ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
+#define _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
+
+#if defined(__ANDROID__)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <xlocale.h>
+
+static inline int isalnum_l(int c, locale_t) {
+  return isalnum(c);
+}
+
+static inline int isalpha_l(int c, locale_t) {
+  return isalpha(c);
+}
+
+static inline int isblank_l(int c, locale_t) {
+  return isblank(c);
+}
+
+static inline int iscntrl_l(int c, locale_t) {
+  return iscntrl(c);
+}
+
+static inline int isdigit_l(int c, locale_t) {
+  return isdigit(c);
+}
+
+static inline int isgraph_l(int c, locale_t) {
+  return isgraph(c);
+}
+
+static inline int islower_l(int c, locale_t) {
+  return islower(c);
+}
+
+static inline int isprint_l(int c, locale_t) {
+  return isprint(c);
+}
+
+static inline int ispunct_l(int c, locale_t) {
+  return ispunct(c);
+}
+
+static inline int isspace_l(int c, locale_t) {
+  return isspace(c);
+}
+
+static inline int isupper_l(int c, locale_t) {
+  return isupper(c);
+}
+
+static inline int isxdigit_l(int c, locale_t) {
+  return isxdigit(c);
+}
+
+static inline int iswalnum_l(wint_t c, locale_t) {
+  return iswalnum(c);
+}
+
+static inline int iswalpha_l(wint_t c, locale_t) {
+  return iswalpha(c);
+}
+
+static inline int iswblank_l(wint_t c, locale_t) {
+  return iswblank(c);
+}
+
+static inline int iswcntrl_l(wint_t c, locale_t) {
+  return iswcntrl(c);
+}
+
+static inline int iswdigit_l(wint_t c, locale_t) {
+  return iswdigit(c);
+}
+
+static inline int iswgraph_l(wint_t c, locale_t) {
+  return iswgraph(c);
+}
+
+static inline int iswlower_l(wint_t c, locale_t) {
+  return iswlower(c);
+}
+
+static inline int iswprint_l(wint_t c, locale_t) {
+  return iswprint(c);
+}
+
+static inline int iswpunct_l(wint_t c, locale_t) {
+  return iswpunct(c);
+}
+
+static inline int iswspace_l(wint_t c, locale_t) {
+  return iswspace(c);
+}
+
+static inline int iswupper_l(wint_t c, locale_t) {
+  return iswupper(c);
+}
+
+static inline int iswxdigit_l(wint_t c, locale_t) {
+  return iswxdigit(c);
+}
+
+static inline int toupper_l(int c, locale_t) {
+  return toupper(c);
+}
+
+static inline int tolower_l(int c, locale_t) {
+  return tolower(c);
+}
+
+static inline int towupper_l(int c, locale_t) {
+  return towupper(c);
+}
+
+static inline int towlower_l(int c, locale_t) {
+  return towlower(c);
+}
+
+static inline int strcoll_l(const char *s1, const char *s2, locale_t) {
+  return strcoll(s1, s2);
+}
+
+static inline size_t strxfrm_l(char *dest, const char *src, size_t n,
+                               locale_t) {
+  return strxfrm(dest, src, n);
+}
+
+static inline size_t strftime_l(char *s, size_t max, const char *format,
+                                const struct tm *tm, locale_t) {
+  return strftime(s, max, format, tm);
+}
+
+static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
+  return wcscoll(ws1, ws2);
+}
+
+static inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n,
+                               locale_t) {
+  return wcsxfrm(dest, src, n);
+}
+
+static inline long double strtold_l(const char *nptr, char **endptr, locale_t) {
+  return strtold(nptr, endptr);
+}
+
+static inline long long strtoll_l(const char *nptr, char **endptr, size_t base,
+                                  locale_t) {
+  return strtoll(nptr, endptr, base);
+}
+
+static inline unsigned long long strtoull_l(const char *nptr, char **endptr,
+                                            size_t base, locale_t) {
+  return strtoull(nptr, endptr, base);
+}
+
+static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr,
+                                  size_t base, locale_t) {
+  return wcstoll(nptr, endptr, base);
+}
+
+static inline unsigned long long wcstoull_l(const wchar_t *nptr,
+                                            wchar_t **endptr, size_t base,
+                                            locale_t) {
+  return wcstoull(nptr, endptr, base);
+}
+
+static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr,
+                                    locale_t) {
+  return wcstold(nptr, endptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif // defined(__ANDROID__)
+#endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H
diff --git a/include/c++/v1/support/ibm/limits.h b/include/c++/v1/support/ibm/limits.h
new file mode 100644
index 0000000..efdb359
--- /dev/null
+++ b/include/c++/v1/support/ibm/limits.h
@@ -0,0 +1,99 @@
+// -*- C++ -*-
+//===--------------------- support/ibm/limits.h ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_LIMITS_H
+#define _LIBCPP_SUPPORT_IBM_LIMITS_H
+
+#if !defined(_AIX) // Linux
+#include <math.h> // for HUGE_VAL, HUGE_VALF, HUGE_VALL, and NAN
+
+static const unsigned int _QNAN_F = 0x7fc00000;
+#define NANF (*((float *)(&_QNAN_F)))
+static const unsigned int _QNAN_LDBL128[4] = {0x7ff80000, 0x0, 0x0, 0x0};
+#define NANL (*((long double *)(&_QNAN_LDBL128)))
+static const unsigned int _SNAN_F= 0x7f855555;
+#define NANSF (*((float *)(&_SNAN_F)))
+static const unsigned int _SNAN_D[2] = {0x7ff55555, 0x55555555};
+#define NANS (*((double *)(&_SNAN_D)))
+static const unsigned int _SNAN_LDBL128[4] = {0x7ff55555, 0x55555555, 0x0, 0x0};
+#define NANSL (*((long double *)(&_SNAN_LDBL128)))
+
+#define __builtin_huge_val()     HUGE_VAL
+#define __builtin_huge_valf()    HUGE_VALF
+#define __builtin_huge_vall()    HUGE_VALL
+#define __builtin_nan(__dummy)   NAN
+#define __builtin_nanf(__dummy)  NANF
+#define __builtin_nanl(__dummy)  NANL
+#define __builtin_nans(__dummy)  NANS
+#define __builtin_nansf(__dummy) NANSF
+#define __builtin_nansl(__dummy) NANSL
+
+#else
+
+#include <math.h>
+#include <float.h> // limit constants
+
+#define __builtin_huge_val()     HUGE_VAL  //0x7ff0000000000000
+#define __builtin_huge_valf()    HUGE_VALF //0x7f800000
+#define __builtin_huge_vall()    HUGE_VALL //0x7ff0000000000000
+#define __builtin_nan(__dummy)   nan(__dummy) //0x7ff8000000000000
+#define __builtin_nanf(__dummy)  nanf(__dummy) // 0x7ff80000
+#define __builtin_nanl(__dummy)  nanl(__dummy) //0x7ff8000000000000
+#define __builtin_nans(__dummy)  DBL_SNAN //0x7ff5555555555555
+#define __builtin_nansf(__dummy) FLT_SNAN //0x7f855555
+#define __builtin_nansl(__dummy) DBL_SNAN //0x7ff5555555555555
+
+#define __FLT_MANT_DIG__   FLT_MANT_DIG
+#define __FLT_DIG__        FLT_DIG
+#define __FLT_RADIX__      FLT_RADIX
+#define __FLT_MIN_EXP__    FLT_MIN_EXP
+#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP
+#define __FLT_MAX_EXP__    FLT_MAX_EXP
+#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP
+#define __FLT_MIN__        FLT_MIN
+#define __FLT_MAX__        FLT_MAX
+#define __FLT_EPSILON__    FLT_EPSILON
+// predefined by XLC on LoP
+#define __FLT_DENORM_MIN__ 1.40129846e-45F
+
+#define __DBL_MANT_DIG__   DBL_MANT_DIG
+#define __DBL_DIG__        DBL_DIG
+#define __DBL_MIN_EXP__    DBL_MIN_EXP
+#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP
+#define __DBL_MAX_EXP__    DBL_MAX_EXP
+#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP
+#define __DBL_MIN__        DBL_MIN
+#define __DBL_MAX__        DBL_MAX
+#define __DBL_EPSILON__    DBL_EPSILON
+// predefined by XLC on LoP
+#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+
+#define __LDBL_MANT_DIG__   LDBL_MANT_DIG
+#define __LDBL_DIG__        LDBL_DIG
+#define __LDBL_MIN_EXP__    LDBL_MIN_EXP
+#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP
+#define __LDBL_MAX_EXP__    LDBL_MAX_EXP
+#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP
+#define __LDBL_MIN__        LDBL_MIN
+#define __LDBL_MAX__        LDBL_MAX
+#define __LDBL_EPSILON__    LDBL_EPSILON
+// predefined by XLC on LoP
+#if __LONGDOUBLE128
+#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
+#else
+#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+#endif
+
+// predefined by XLC on LoP
+#define __CHAR_BIT__    8
+
+#endif // _AIX
+
+#endif // _LIBCPP_SUPPORT_IBM_LIMITS_H
diff --git a/include/c++/v1/support/ibm/support.h b/include/c++/v1/support/ibm/support.h
new file mode 100644
index 0000000..0abfa7f
--- /dev/null
+++ b/include/c++/v1/support/ibm/support.h
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===----------------------- support/ibm/support.h ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_SUPPORT_H
+#define _LIBCPP_SUPPORT_IBM_SUPPORT_H
+
+extern "builtin" int __popcnt4(unsigned int);
+extern "builtin" int __popcnt8(unsigned long long);
+extern "builtin" unsigned int __cnttz4(unsigned int);
+extern "builtin" unsigned int __cnttz8(unsigned long long);
+extern "builtin" unsigned int __cntlz4(unsigned int);
+extern "builtin" unsigned int __cntlz8(unsigned long long);
+
+// Builtin functions for counting population
+#define __builtin_popcount(x) __popcnt4(x)
+#define __builtin_popcountll(x) __popcnt8(x)
+#if defined(__64BIT__)
+#define __builtin_popcountl(x) __builtin_popcountll(x)
+#else
+#define __builtin_popcountl(x) __builtin_popcount(x)
+#endif
+
+// Builtin functions for counting trailing zeros
+#define __builtin_ctz(x) __cnttz4(x)
+#define __builtin_ctzll(x) __cnttz8(x)
+#if defined(__64BIT__)
+#define __builtin_ctzl(x) __builtin_ctzll(x)
+#else
+#define __builtin_ctzl(x) __builtin_ctz(x)
+#endif
+
+// Builtin functions for counting leading zeros
+#define __builtin_clz(x) __cntlz4(x)
+#define __builtin_clzll(x) __cntlz8(x)
+#if defined(__64BIT__)
+#define __builtin_clzl(x) __builtin_clzll(x)
+#else
+#define __builtin_clzl(x) __builtin_clz(x)
+#endif
+
+#if defined(__64BIT__)
+#define __SIZE_WIDTH__ 64
+#else
+#define __SIZE_WIDTH__ 32
+#endif
+
+#endif // _LIBCPP_SUPPORT_IBM_SUPPORT_H
diff --git a/include/c++/v1/support/ibm/xlocale.h b/include/c++/v1/support/ibm/xlocale.h
new file mode 100644
index 0000000..8d99a5c
--- /dev/null
+++ b/include/c++/v1/support/ibm/xlocale.h
@@ -0,0 +1,326 @@
+// -*- C++ -*-
+//===--------------------- support/ibm/xlocale.h -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
+#define _LIBCPP_SUPPORT_IBM_XLOCALE_H
+
+#if defined(_AIX)
+#include "cstdlib"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_AIX71)
+// AIX 7.1 and higher has these definitions.  Definitions and stubs
+// are provied here as a temporary workaround on AIX 6.1.
+
+#define LC_COLLATE_MASK         1
+#define LC_CTYPE_MASK           2
+#define LC_MESSAGES_MASK        4
+#define LC_MONETARY_MASK        8
+#define LC_NUMERIC_MASK         16
+#define LC_TIME_MASK            32
+#define LC_ALL_MASK             (LC_COLLATE_MASK | LC_CTYPE_MASK | \
+                                 LC_MESSAGES_MASK | LC_MONETARY_MASK |\
+                                 LC_NUMERIC_MASK | LC_TIME_MASK)
+
+typedef void* locale_t;
+
+// The following are stubs.  They are not supported on AIX 6.1.
+static inline
+locale_t newlocale(int category_mask, const char *locale, locale_t base)
+{
+  _LC_locale_t *newloc, *loc;
+  if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL)
+  {
+    errno = EINVAL;
+    return (locale_t)0;
+  }
+  if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL)
+  {
+    errno = ENOMEM;
+    return (locale_t)0;
+  }
+  if (!base)
+    base = (_LC_locale_t *)__xopen_locale("C");
+  memcpy(newloc, base, sizeof (_LC_locale_t));
+  if (category_mask & LC_COLLATE_MASK) 
+    newloc->lc_collate = loc->lc_collate;
+  if (category_mask & LC_CTYPE_MASK)
+    newloc->lc_ctype = loc->lc_ctype;
+  //if (category_mask & LC_MESSAGES_MASK)
+  //  newloc->lc_messages = loc->lc_messages;
+  if (category_mask & LC_MONETARY_MASK)
+    newloc->lc_monetary = loc->lc_monetary;
+  if (category_mask & LC_TIME_MASK)
+    newloc->lc_time = loc->lc_time;
+  if (category_mask & LC_NUMERIC_MASK)
+    newloc->lc_numeric = loc->lc_numeric;
+  return (locale_t)newloc; 
+}
+static inline
+void freelocale(locale_t locobj)
+{
+  free(locobj);
+}
+static inline
+locale_t uselocale(locale_t newloc)
+{
+  return (locale_t)0;
+}
+
+static inline
+int isalnum_l(int c, locale_t locale)
+{
+  return __xisalnum(locale, c);
+}
+static inline
+int isalpha_l(int c, locale_t locale)
+{
+  return __xisalpha(locale, c);
+}
+static inline
+int isblank_l(int c, locale_t locale)
+{
+  return __xisblank(locale, c);
+}
+static inline
+int iscntrl_l(int c, locale_t locale)
+{
+  return __xiscntrl(locale, c);
+}
+static inline
+int isdigit_l(int c, locale_t locale)
+{
+  return __xisdigit(locale, c);
+}
+static inline
+int isgraph_l(int c, locale_t locale)
+{
+  return __xisgraph(locale, c);
+}
+static inline
+int islower_l(int c, locale_t locale)
+{
+  return __xislower(locale, c);
+}
+static inline
+int isprint_l(int c, locale_t locale)
+{
+  return __xisprint(locale, c);
+}
+
+static inline
+int ispunct_l(int c, locale_t locale)
+{
+  return __xispunct(locale, c);
+}
+static inline
+int isspace_l(int c, locale_t locale)
+{
+  return __xisspace(locale, c);
+}
+static inline
+int isupper_l(int c, locale_t locale)
+{
+  return __xisupper(locale, c);
+}
+
+static inline
+int isxdigit_l(int c, locale_t locale)
+{
+  return __xisxdigit(locale, c);
+}
+
+static inline
+int iswalnum_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalnum(locale, wc); 
+}
+
+static inline
+int iswalpha_l(wchar_t wc, locale_t locale)
+{
+  return __xiswalpha(locale, wc);
+}
+
+static inline
+int iswblank_l(wchar_t wc, locale_t locale)
+{
+  return __xiswblank(locale, wc);
+}
+
+static inline
+int iswcntrl_l(wchar_t wc, locale_t locale)
+{
+  return __xiswcntrl(locale, wc);
+}
+
+static inline
+int iswdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswdigit(locale, wc);
+}
+
+static inline
+int iswgraph_l(wchar_t wc, locale_t locale)
+{
+  return __xiswgraph(locale, wc);
+}
+
+static inline
+int iswlower_l(wchar_t wc, locale_t locale)
+{
+  return __xiswlower(locale, wc);
+}
+
+static inline
+int iswprint_l(wchar_t wc, locale_t locale)
+{
+  return __xiswprint(locale, wc);
+}
+
+static inline
+int iswpunct_l(wchar_t wc, locale_t locale)
+{
+  return __xiswpunct(locale, wc);
+}
+
+static inline
+int iswspace_l(wchar_t wc, locale_t locale)
+{
+  return __xiswspace(locale, wc);
+}
+
+static inline
+int iswupper_l(wchar_t wc, locale_t locale)
+{
+  return __xiswupper(locale, wc);
+}
+
+static inline
+int iswxdigit_l(wchar_t wc, locale_t locale)
+{
+  return __xiswxdigit(locale, wc);
+}
+
+static inline
+int iswctype_l(wint_t wc, wctype_t desc, locale_t locale)
+{
+  return __xiswctype(locale, wc, desc); 
+}
+
+static inline
+int toupper_l(int c, locale_t locale)
+{
+  return __xtoupper(locale, c);
+}
+static inline
+int tolower_l(int c, locale_t locale)
+{
+  return __xtolower(locale, c);
+}
+static inline
+wint_t towupper_l(wint_t wc, locale_t locale)
+{
+  return __xtowupper(locale, wc);
+}
+static inline
+wint_t towlower_l(wint_t wc, locale_t locale)
+{
+  return __xtowlower(locale, wc);
+}
+
+static inline
+int strcoll_l(const char *__s1, const char *__s2, locale_t locale)
+{
+  return __xstrcoll(locale, __s1, __s2);
+}
+static inline
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale)
+{
+  return __xwcscoll(locale, __s1, __s2);
+}
+static inline
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale)
+{
+  return __xstrxfrm(locale, __s1, __s2, __n);
+}
+
+static inline
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t locale)
+{
+  return __xwcsxfrm(locale, __ws1, __ws2, __n);
+}
+#endif // !defined(_AIX71)
+
+// strftime_l() is defined by POSIX. However, AIX 7.1 does not have it
+// implemented yet.
+static inline
+size_t strftime_l(char *__s, size_t __size, const char *__fmt,
+                  const struct tm *__tm, locale_t locale) {
+  return __xstrftime(locale, __s, __size, __fmt, __tm);
+}
+
+// The following are not POSIX routines.  These are quick-and-dirty hacks
+// to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoll(__nptr, __endptr, __base);
+}
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtol(__nptr, __endptr, __base);
+}
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t locale) {
+  return strtold(__nptr, __endptr);
+}
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoull(__nptr, __endptr, __base);
+}
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t locale) {
+  return strtoul(__nptr, __endptr, __base);
+}
+
+static inline
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+  const size_t buff_size = 256;
+  int str_size;
+  if ((*strp = (char *)malloc(buff_size)) == NULL)
+  {
+    return -1;
+  }
+  if ((str_size = vsnprintf(*strp, buff_size, fmt,  ap)) >= buff_size)
+  {
+    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)
+    {
+      return -1;
+    }
+    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
+  }
+  return str_size;
+}  
+
+#ifdef __cplusplus
+}
+#endif
+#endif // defined(_AIX)
+#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H
diff --git a/include/c++/v1/support/solaris/floatingpoint.h b/include/c++/v1/support/solaris/floatingpoint.h
new file mode 100644
index 0000000..999d144
--- /dev/null
+++ b/include/c++/v1/support/solaris/floatingpoint.h
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define atof sun_atof
+#define strtod sun_strtod
+#include_next "floatingpoint.h"
+#undef atof
+#undef strtod
diff --git a/include/c++/v1/support/solaris/wchar.h b/include/c++/v1/support/solaris/wchar.h
new file mode 100644
index 0000000..0e8e660
--- /dev/null
+++ b/include/c++/v1/support/solaris/wchar.h
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define iswalpha sun_iswalpha
+#define iswupper sun_iswupper
+#define iswlower sun_iswlower
+#define iswdigit sun_iswdigit
+#define iswxdigit sun_iswxdigit
+#define iswalnum sun_iswalnum
+#define iswspace sun_iswspace
+#define iswpunct sun_iswpunct
+#define iswprint sun_iswprint
+#define iswgraph sun_iswgraph
+#define iswcntrl sun_iswcntrl
+#define iswctype sun_iswctype
+#define towlower sun_towlower
+#define towupper sun_towupper
+#define wcswcs sun_wcswcs
+#define wcswidth sun_wcswidth
+#define wcwidth sun_wcwidth
+#define wctype sun_wctype
+#define _WCHAR_T 1
+#include_next "wchar.h"
+#undef iswalpha 
+#undef iswupper
+#undef iswlower
+#undef iswdigit
+#undef iswxdigit
+#undef iswalnum
+#undef iswspace
+#undef iswpunct
+#undef iswprint
+#undef iswgraph
+#undef iswcntrl
+#undef iswctype
+#undef towlower
+#undef towupper
+#undef wcswcs
+#undef wcswidth
+#undef wcwidth
+#undef wctype
diff --git a/include/c++/v1/support/solaris/xlocale.h b/include/c++/v1/support/solaris/xlocale.h
new file mode 100644
index 0000000..875a39a
--- /dev/null
+++ b/include/c++/v1/support/solaris/xlocale.h
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+////////////////////////////////////////////////////////////////////////////////
+// Minimal xlocale implementation for Solaris.  This implements the subset of
+// the xlocale APIs that libc++ depends on.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef __XLOCALE_H_INCLUDED
+#define __XLOCALE_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _LC_locale_t* locale_t;
+
+#define LC_COLLATE_MASK  (1<<0)
+#define LC_CTYPE_MASK    (1<<1)
+#define LC_MESSAGES_MASK (1<<2)
+#define LC_MONETARY_MASK (1<<3)
+#define LC_NUMERIC_MASK  (1<<4)
+#define LC_TIME_MASK     (1<<5)
+#define LC_ALL_MASK      (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \
+                LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+size_t __mb_cur_max(locale_t l);
+#define MB_CUR_MAX_L(l) __mb_cur_max(l) 
+
+locale_t newlocale(int mask, const char * locale, locale_t base);
+void freelocale(locale_t loc);
+
+wint_t btowc_l(int __c, locale_t __l);
+
+int wctob_l(wint_t __c, locale_t __l);
+
+size_t wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l);
+
+size_t mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
+                 mbstate_t *__ps, locale_t __l);
+
+int mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l);
+
+size_t mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l);
+
+struct lconv *localeconv_l(locale_t __l);
+
+size_t mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
+                   mbstate_t *__ps, locale_t __l);
+
+int sprintf_l(char *__s, locale_t __l, const char *__format, ...);
+
+int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);
+
+int asprintf_l(char **__s, locale_t __l, const char *__format, ...);
+
+int sscanf_l(const char *__s, locale_t __l, const char *__format, ...);
+
+int isalnum_l(int,locale_t);
+int isalpha_l(int,locale_t);
+int isblank_l(int,locale_t);
+int iscntrl_l(int,locale_t);
+int isdigit_l(int,locale_t);
+int isgraph_l(int,locale_t);
+int islower_l(int,locale_t);
+int isprint_l(int,locale_t);
+int ispunct_l(int,locale_t);
+int isspace_l(int,locale_t);
+int isupper_l(int,locale_t);
+int isxdigit_l(int,locale_t);
+
+int iswalnum_l(wchar_t,locale_t);
+int iswalpha_l(wchar_t,locale_t);
+int iswblank_l(wchar_t,locale_t);
+int iswcntrl_l(wchar_t,locale_t);
+int iswdigit_l(wchar_t,locale_t);
+int iswgraph_l(wchar_t,locale_t);
+int iswlower_l(wchar_t,locale_t);
+int iswprint_l(wchar_t,locale_t);
+int iswpunct_l(wchar_t,locale_t);
+int iswspace_l(wchar_t,locale_t);
+int iswupper_l(wchar_t,locale_t);
+int iswxdigit_l(wchar_t,locale_t);
+
+int iswctype_l(wint_t, wctype_t, locale_t);
+
+int toupper_l(int __c, locale_t __l);
+int tolower_l(int __c, locale_t __l);
+wint_t towupper_l(wint_t __c, locale_t __l);
+wint_t towlower_l(wint_t __c, locale_t __l);
+
+
+int strcoll_l(const char *__s1, const char *__s2, locale_t __l);
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t __l);
+size_t strftime_l(char *__s, size_t __size, const char *__fmt, const struct tm
+    *__tm, locale_t __l);
+
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t __l);
+
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t __l);
+
+
+
+size_t
+mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,
+    size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc);
+
+
+size_t
+wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
+    size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc);
+
+locale_t __cloc(void);
+
+// FIXME: These are quick-and-dirty hacks to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoll(__nptr, __endptr, __base);
+}
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtol(__nptr, __endptr, __base);
+}
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t __loc) {
+  return strtold(__nptr, __endptr);
+}
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoull(__nptr, __endptr, __base);
+}
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoul(__nptr, __endptr, __base);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/c++/v1/support/win32/limits_win32.h b/include/c++/v1/support/win32/limits_win32.h
new file mode 100644
index 0000000..406cd30
--- /dev/null
+++ b/include/c++/v1/support/win32/limits_win32.h
@@ -0,0 +1,79 @@
+// -*- C++ -*-
+//===--------------------- support/win32/limits_win32.h -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
+
+#if !defined(_LIBCPP_MSVCRT)
+#error "This header complements the Microsoft C Runtime library, and should not be included otherwise."
+#else
+
+#include <limits.h> // CHAR_BIT
+#include <float.h> // limit constants
+
+#if ! defined(__clang__)
+#define __CHAR_BIT__       CHAR_BIT
+
+#define __FLT_MANT_DIG__   FLT_MANT_DIG
+#define __FLT_DIG__        FLT_DIG
+#define __FLT_RADIX__      FLT_RADIX
+#define __FLT_MIN_EXP__    FLT_MIN_EXP
+#define __FLT_MIN_10_EXP__ FLT_MIN_10_EXP
+#define __FLT_MAX_EXP__    FLT_MAX_EXP
+#define __FLT_MAX_10_EXP__ FLT_MAX_10_EXP
+#define __FLT_MIN__        FLT_MIN
+#define __FLT_MAX__        FLT_MAX
+#define __FLT_EPSILON__    FLT_EPSILON
+// predefined by MinGW GCC
+#define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F
+
+#define __DBL_MANT_DIG__   DBL_MANT_DIG
+#define __DBL_DIG__        DBL_DIG
+#define __DBL_RADIX__      DBL_RADIX
+#define __DBL_MIN_EXP__    DBL_MIN_EXP
+#define __DBL_MIN_10_EXP__ DBL_MIN_10_EXP
+#define __DBL_MAX_EXP__    DBL_MAX_EXP
+#define __DBL_MAX_10_EXP__ DBL_MAX_10_EXP
+#define __DBL_MIN__        DBL_MIN
+#define __DBL_MAX__        DBL_MAX
+#define __DBL_EPSILON__    DBL_EPSILON
+// predefined by MinGW GCC
+#define __DBL_DENORM_MIN__ double(4.94065645841246544177e-324L)
+
+#define __LDBL_MANT_DIG__   LDBL_MANT_DIG
+#define __LDBL_DIG__        LDBL_DIG
+#define __LDBL_RADIX__      LDBL_RADIX
+#define __LDBL_MIN_EXP__    LDBL_MIN_EXP
+#define __LDBL_MIN_10_EXP__ LDBL_MIN_10_EXP
+#define __LDBL_MAX_EXP__    LDBL_MAX_EXP
+#define __LDBL_MAX_10_EXP__ LDBL_MAX_10_EXP
+#define __LDBL_MIN__        LDBL_MIN
+#define __LDBL_MAX__        LDBL_MAX
+#define __LDBL_EPSILON__    LDBL_EPSILON
+// predefined by MinGW GCC
+#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+
+// __builtin replacements/workarounds
+#include <math.h> // HUGE_VAL
+#include <ymath.h> // internal MSVC header providing the needed functionality
+#define __builtin_huge_val()     HUGE_VAL
+#define __builtin_huge_valf()    _FInf._Float
+#define __builtin_huge_vall()    _LInf._Long_double
+#define __builtin_nan(__dummy)   _Nan._Double
+#define __builtin_nanf(__dummy)  _FNan._Float
+#define __builtin_nanl(__dummmy) _LNan._Long_double
+#define __builtin_nans(__dummy)  _Snan._Double
+#define __builtin_nansf(__dummy) _FSnan._Float
+#define __builtin_nansl(__dummy) _LSnan._Long_double
+#endif // ! defined(__clang__)
+
+#endif // _LIBCPP_MSVCRT
+
+#endif // _LIBCPP_SUPPORT_WIN32_LIMITS_WIN32_H
diff --git a/include/c++/v1/support/win32/locale_win32.h b/include/c++/v1/support/win32/locale_win32.h
new file mode 100644
index 0000000..f728d23
--- /dev/null
+++ b/include/c++/v1/support/win32/locale_win32.h
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+//===--------------------- support/win32/locale_win32.h -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
+
+// ctype mask table defined in msvcrt.dll
+extern "C" unsigned short  __declspec(dllimport) _ctype[];
+
+#include "support/win32/support.h"
+#include <stdio.h>
+#include <memory>
+#include <xlocinfo.h> // _locale_t
+#define locale_t _locale_t
+#define LC_COLLATE_MASK _M_COLLATE
+#define LC_CTYPE_MASK _M_CTYPE
+#define LC_MONETARY_MASK _M_MONETARY
+#define LC_NUMERIC_MASK _M_NUMERIC
+#define LC_TIME_MASK _M_TIME
+#define LC_MESSAGES_MASK _M_MESSAGES
+#define LC_ALL_MASK (  LC_COLLATE_MASK \
+                     | LC_CTYPE_MASK \
+                     | LC_MESSAGES_MASK \
+                     | LC_MONETARY_MASK \
+                     | LC_NUMERIC_MASK \
+                     | LC_TIME_MASK )
+#define freelocale _free_locale
+// FIXME: base currently unused. Needs manual work to construct the new locale
+locale_t newlocale( int mask, const char * locale, locale_t base );
+locale_t uselocale( locale_t newloc );
+lconv *localeconv_l( locale_t loc );
+size_t mbrlen_l( const char *__restrict s, size_t n,
+                 mbstate_t *__restrict ps, locale_t loc);
+size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                    size_t len, mbstate_t *__restrict ps, locale_t loc );
+size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
+                  locale_t loc);
+size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
+                  size_t n, mbstate_t *__restrict ps, locale_t loc);
+size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
+                     size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc);
+size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
+                     size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc);
+wint_t btowc_l( int c, locale_t loc );
+int wctob_l( wint_t c, locale_t loc );
+typedef _VSTD::remove_pointer<locale_t>::type __locale_struct;
+typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii;
+inline _LIBCPP_ALWAYS_INLINE
+decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
+{
+  __locale_raii __current( uselocale(__l), uselocale );
+  return MB_CUR_MAX;
+}
+
+// the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+
+#define mbtowc_l _mbtowc_l
+#define strtoll_l _strtoi64_l
+#define strtoull_l _strtoui64_l
+// FIXME: current msvcrt does not know about long double
+#define strtold_l _strtod_l
+
+inline _LIBCPP_INLINE_VISIBILITY
+int
+islower_l(int c, _locale_t loc)
+{
+ return _islower_l((int)c, loc);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int
+isupper_l(int c, _locale_t loc)
+{
+ return _isupper_l((int)c, loc);
+}
+
+#define isdigit_l _isdigit_l
+#define isxdigit_l _isxdigit_l
+#define strcoll_l _strcoll_l
+#define strxfrm_l _strxfrm_l
+#define wcscoll_l _wcscoll_l
+#define wcsxfrm_l _wcsxfrm_l
+#define toupper_l _toupper_l
+#define tolower_l _tolower_l
+#define iswspace_l _iswspace_l
+#define iswprint_l _iswprint_l
+#define iswcntrl_l _iswcntrl_l
+#define iswupper_l _iswupper_l
+#define iswlower_l _iswlower_l
+#define iswalpha_l _iswalpha_l
+#define iswdigit_l _iswdigit_l
+#define iswpunct_l _iswpunct_l
+#define iswxdigit_l _iswxdigit_l
+#define towupper_l _towupper_l
+#define towlower_l _towlower_l
+#define strftime_l _strftime_l
+#define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )
+#define vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ )
+#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ )
+#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ )
+#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ )
+int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...);
+int asprintf_l( char **ret, locale_t loc, const char *format, ... );
+int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap );
+
+
+// not-so-pressing FIXME: use locale to determine blank characters
+inline int isblank_l( int c, locale_t /*loc*/ )
+{
+    return ( c == ' ' || c == '\t' );
+}
+inline int iswblank_l( wint_t c, locale_t /*loc*/ )
+{
+    return ( c == L' ' || c == L'\t' );
+}
+
+#if defined(_LIBCPP_MSVCRT)
+inline int isblank( int c, locale_t /*loc*/ )
+{ return ( c == ' ' || c == '\t' ); }
+inline int iswblank( wint_t c, locale_t /*loc*/ )
+{ return ( c == L' ' || c == L'\t' ); }
+#endif // _LIBCPP_MSVCRT
+#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H
diff --git a/include/c++/v1/support/win32/math_win32.h b/include/c++/v1/support/win32/math_win32.h
new file mode 100644
index 0000000..c62c54e
--- /dev/null
+++ b/include/c++/v1/support/win32/math_win32.h
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+//===---------------------- support/win32/math_win32.h --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
+
+#if !defined(_LIBCPP_MSVCRT)
+#error "This header complements Microsoft's C Runtime library, and should not be included otherwise."
+#else
+
+#include <math.h>
+#include <float.h> // _FPCLASS_PN etc.
+
+// Necessary?
+typedef float float_t;
+typedef double double_t;
+
+_LIBCPP_ALWAYS_INLINE bool isfinite( double num )
+{
+    return _finite(num) != 0;
+}
+_LIBCPP_ALWAYS_INLINE bool isinf( double num )
+{
+    return !isfinite(num) && !_isnan(num);
+}
+_LIBCPP_ALWAYS_INLINE bool isnan( double num )
+{
+    return _isnan(num) != 0;
+}
+_LIBCPP_ALWAYS_INLINE bool isnormal( double num )
+{
+    int class_ = _fpclass(num);
+    return class_ == _FPCLASS_NN || class_ == _FPCLASS_PN;
+}
+
+_LIBCPP_ALWAYS_INLINE bool isgreater( double x, double y )
+{
+    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;
+    else return x > y;
+}
+
+_LIBCPP_ALWAYS_INLINE bool isgreaterequal( double x, double y )
+{
+    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;
+    else return x >= y;
+}
+
+_LIBCPP_ALWAYS_INLINE bool isless( double x, double y )
+{
+    if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false;
+    else return x < y;
+}
+
+_LIBCPP_ALWAYS_INLINE bool islessequal( double x, double y )
+{
+    if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false;
+    else return x <= y;
+}
+
+_LIBCPP_ALWAYS_INLINE bool islessgreater( double x, double y )
+{
+    if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false;
+    else return x < y || x > y;
+}
+
+_LIBCPP_ALWAYS_INLINE bool isunordered( double x, double y )
+{
+    return isnan(x) || isnan(y);
+}
+_LIBCPP_ALWAYS_INLINE bool signbit( double num )
+{
+    switch(_fpclass(num))
+    {
+        case _FPCLASS_SNAN:
+        case _FPCLASS_QNAN:
+        case _FPCLASS_NINF:
+        case _FPCLASS_NN:
+        case _FPCLASS_ND:
+        case _FPCLASS_NZ:
+            return true;
+        case _FPCLASS_PZ:
+        case _FPCLASS_PD:
+        case _FPCLASS_PN:
+        case _FPCLASS_PINF:
+            return false;
+    }
+    return false;
+}
+_LIBCPP_ALWAYS_INLINE float copysignf( float x, float y )
+{
+    return (signbit (x) != signbit (y) ? - x : x);
+}
+_LIBCPP_ALWAYS_INLINE double copysign( double x, double y )
+{
+    return ::_copysign(x,y);
+}
+_LIBCPP_ALWAYS_INLINE double copysignl( long double x, long double y )
+{
+    return ::_copysignl(x,y);
+}
+_LIBCPP_ALWAYS_INLINE int fpclassify( double num )
+{
+    return _fpclass(num);
+}
+
+#endif // _LIBCPP_MSVCRT
+
+#endif // _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H
diff --git a/include/c++/v1/support/win32/support.h b/include/c++/v1/support/win32/support.h
new file mode 100644
index 0000000..bc96587
--- /dev/null
+++ b/include/c++/v1/support/win32/support.h
@@ -0,0 +1,203 @@
+// -*- C++ -*-
+//===----------------------- support/win32/support.h ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_SUPPORT_H
+#define _LIBCPP_SUPPORT_WIN32_SUPPORT_H
+
+// Functions and constants used in libc++ that
+// are missing from the Windows C library.
+
+#include <wchar.h> // mbstate_t
+#include <cstdarg> // va_ macros
+// "builtins" not implemented here for Clang or GCC as they provide
+// implementations. Assuming required for elsewhere else, certainly MSVC.
+#if defined(_LIBCPP_MSVC)
+#include <intrin.h>
+#endif
+#if defined(_LIBCPP_MSVCRT)
+#include <xlocinfo.h>
+#endif
+#define swprintf _snwprintf
+#define vswprintf _vsnwprintf
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+extern "C" {
+
+int vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
+int asprintf(char **sptr, const char *__restrict fmt, ...);
+size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src,
+                  size_t nmc, size_t len, mbstate_t *__restrict ps);
+size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,
+                  size_t nwc, size_t len, mbstate_t *__restrict ps);
+}
+
+#if defined(_LIBCPP_MSVCRT)
+#define snprintf _snprintf
+#define atoll _atoi64
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#define wcstoll _wcstoi64
+#define wcstoull _wcstoui64
+_LIBCPP_ALWAYS_INLINE float strtof(const char *nptr, char **endptr)
+{
+  return _Stof(nptr, endptr, 0);
+}
+_LIBCPP_ALWAYS_INLINE double strtod(const char *nptr, char **endptr)
+{
+  return _Stod(nptr, endptr, 0);
+}
+_LIBCPP_ALWAYS_INLINE long double strtold(const char *nptr, char **endptr)
+{
+  return _Stold(nptr, endptr, 0);
+}
+
+#define _Exit _exit
+#endif
+
+#if defined(_LIBCPP_MSVC)
+
+// Bit builtin's make these assumptions when calling _BitScanForward/Reverse
+// etc. These assumptions are expected to be true for Win32/Win64 which this
+// file supports.
+static_assert(sizeof(unsigned long long) == 8, "");
+static_assert(sizeof(unsigned long) == 4, "");
+static_assert(sizeof(unsigned int) == 4, "");
+
+_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x)
+{
+  // Binary: 0101...
+  static const unsigned int m1 = 0x55555555;
+  // Binary: 00110011..
+  static const unsigned int m2 = 0x33333333;
+  // Binary:  4 zeros,  4 ones ...
+  static const unsigned int m4 = 0x0f0f0f0f;
+  // The sum of 256 to the power of 0,1,2,3...
+  static const unsigned int h01 = 0x01010101;
+  // Put count of each 2 bits into those 2 bits.
+  x -= (x >> 1) & m1;
+  // Put count of each 4 bits into those 4 bits.
+  x = (x & m2) + ((x >> 2) & m2);
+  // Put count of each 8 bits into those 8 bits.
+  x = (x + (x >> 4)) & m4;
+  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24).
+  return (x * h01) >> 24;
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_popcountl(unsigned long x)
+{
+  return __builtin_popcount(static_cast<int>(x));
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x)
+{
+  // Binary: 0101...
+  static const unsigned long long m1 = 0x5555555555555555;
+  // Binary: 00110011..
+  static const unsigned long long m2 = 0x3333333333333333;
+  // Binary:  4 zeros,  4 ones ...
+  static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f;
+  // The sum of 256 to the power of 0,1,2,3...
+  static const unsigned long long h01 = 0x0101010101010101;
+  // Put count of each 2 bits into those 2 bits.
+  x -= (x >> 1) & m1;
+  // Put count of each 4 bits into those 4 bits.
+  x = (x & m2) + ((x >> 2) & m2);
+  // Put count of each 8 bits into those 8 bits.
+  x = (x + (x >> 4)) & m4;
+  // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
+  return static_cast<int>((x * h01) >> 56);
+}
+
+// Returns the number of trailing 0-bits in x, starting at the least significant
+// bit position. If x is 0, the result is undefined.
+_LIBCPP_ALWAYS_INLINE int __builtin_ctzll(unsigned long long mask)
+{
+  unsigned long where;
+// Search from LSB to MSB for first set bit.
+// Returns zero if no set bit is found.
+#if defined(_WIN64)
+  if (_BitScanForward64(&where, mask))
+    return static_cast<int>(where);
+#elif defined(_WIN32)
+  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
+  // Scan the Low Word.
+  if (_BitScanForward(&where, static_cast<unsigned long>(mask)))
+    return static_cast<int>(where);
+  // Scan the High Word.
+  if (_BitScanForward(&where, static_cast<unsigned long>(mask >> 32)))
+    return static_cast<int>(where + 32); // Create a bit offset from the LSB.
+#else
+#error "Implementation of __builtin_ctzll required"
+#endif
+  return 64;
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_ctzl(unsigned long mask)
+{
+  unsigned long where;
+  // Search from LSB to MSB for first set bit.
+  // Returns zero if no set bit is found.
+  if (_BitScanForward(&where, mask))
+    return static_cast<int>(where);
+  return 32;
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_ctz(unsigned int mask)
+{
+  // Win32 and Win64 expectations.
+  static_assert(sizeof(mask) == 4, "");
+  static_assert(sizeof(unsigned long) == 4, "");
+  return __builtin_ctzl(static_cast<unsigned long>(mask));
+}
+
+// Returns the number of leading 0-bits in x, starting at the most significant
+// bit position. If x is 0, the result is undefined.
+_LIBCPP_ALWAYS_INLINE int __builtin_clzll(unsigned long long mask)
+{
+  unsigned long where;
+// BitScanReverse scans from MSB to LSB for first set bit.
+// Returns 0 if no set bit is found.
+#if defined(_WIN64)
+  if (_BitScanReverse64(&where, mask))
+    return static_cast<int>(63 - where);
+#elif defined(_WIN32)
+  // Scan the high 32 bits.
+  if (_BitScanReverse(&where, static_cast<unsigned long>(mask >> 32)))
+    return static_cast<int>(63 -
+                            (where + 32)); // Create a bit offset from the MSB.
+  // Scan the low 32 bits.
+  if (_BitScanReverse(&where, static_cast<unsigned long>(mask)))
+    return static_cast<int>(63 - where);
+#else
+#error "Implementation of __builtin_clzll required"
+#endif
+  return 64; // Undefined Behavior.
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_clzl(unsigned long mask)
+{
+  unsigned long where;
+  // Search from LSB to MSB for first set bit.
+  // Returns zero if no set bit is found.
+  if (_BitScanReverse(&where, mask))
+    return static_cast<int>(31 - where);
+  return 32; // Undefined Behavior.
+}
+
+_LIBCPP_ALWAYS_INLINE int __builtin_clz(unsigned int x)
+{
+  return __builtin_clzl(x);
+}
+#endif // _LIBCPP_MSVC
+
+#endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H
diff --git a/include/c++/v1/system_error b/include/c++/v1/system_error
new file mode 100644
index 0000000..66bf6d6
--- /dev/null
+++ b/include/c++/v1/system_error
@@ -0,0 +1,642 @@
+// -*- C++ -*-
+//===---------------------------- system_error ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SYSTEM_ERROR
+#define _LIBCPP_SYSTEM_ERROR
+
+/*
+    system_error synopsis
+
+namespace std
+{
+
+class error_category
+{
+public:
+    virtual ~error_category() noexcept;
+
+    constexpr error_category();
+    error_category(const error_category&) = delete;
+    error_category& operator=(const error_category&) = delete;
+
+    virtual const char* name() const noexcept = 0;
+    virtual error_condition default_error_condition(int ev) const noexcept;
+    virtual bool equivalent(int code, const error_condition& condition) const noexcept;
+    virtual bool equivalent(const error_code& code, int condition) const noexcept;
+    virtual string message(int ev) const = 0;
+
+    bool operator==(const error_category& rhs) const noexcept;
+    bool operator!=(const error_category& rhs) const noexcept;
+    bool operator<(const error_category& rhs) const noexcept;
+};
+
+const error_category& generic_category() noexcept;
+const error_category& system_category() noexcept;
+
+template <class T> struct is_error_code_enum
+    : public false_type {};
+
+template <class T> struct is_error_condition_enum
+    : public false_type {};
+
+class error_code
+{
+public:
+    // constructors:
+    error_code() noexcept;
+    error_code(int val, const error_category& cat) noexcept;
+    template <class ErrorCodeEnum>
+        error_code(ErrorCodeEnum e) noexcept;
+
+    // modifiers:
+    void assign(int val, const error_category& cat) noexcept;
+    template <class ErrorCodeEnum>
+        error_code& operator=(ErrorCodeEnum e) noexcept;
+    void clear() noexcept;
+
+    // observers:
+    int value() const noexcept;
+    const error_category& category() const noexcept;
+    error_condition default_error_condition() const noexcept;
+    string message() const;
+    explicit operator bool() const noexcept;
+};
+
+// non-member functions:
+bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
+template <class charT, class traits>
+    basic_ostream<charT,traits>&
+    operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
+
+class error_condition
+{
+public:
+    // constructors:
+    error_condition() noexcept;
+    error_condition(int val, const error_category& cat) noexcept;
+    template <class ErrorConditionEnum>
+        error_condition(ErrorConditionEnum e) noexcept;
+
+    // modifiers:
+    void assign(int val, const error_category& cat) noexcept;
+    template <class ErrorConditionEnum>
+        error_condition& operator=(ErrorConditionEnum e) noexcept;
+    void clear() noexcept;
+
+    // observers:
+    int value() const noexcept;
+    const error_category& category() const noexcept;
+    string message() const noexcept;
+    explicit operator bool() const noexcept;
+};
+
+bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
+
+class system_error
+    : public runtime_error
+{
+public:
+    system_error(error_code ec, const string& what_arg);
+    system_error(error_code ec, const char* what_arg);
+    system_error(error_code ec);
+    system_error(int ev, const error_category& ecat, const string& what_arg);
+    system_error(int ev, const error_category& ecat, const char* what_arg);
+    system_error(int ev, const error_category& ecat);
+
+    const error_code& code() const noexcept;
+    const char* what() const noexcept;
+};
+
+enum class errc
+{
+    address_family_not_supported,       // EAFNOSUPPORT
+    address_in_use,                     // EADDRINUSE
+    address_not_available,              // EADDRNOTAVAIL
+    already_connected,                  // EISCONN
+    argument_list_too_long,             // E2BIG
+    argument_out_of_domain,             // EDOM
+    bad_address,                        // EFAULT
+    bad_file_descriptor,                // EBADF
+    bad_message,                        // EBADMSG
+    broken_pipe,                        // EPIPE
+    connection_aborted,                 // ECONNABORTED
+    connection_already_in_progress,     // EALREADY
+    connection_refused,                 // ECONNREFUSED
+    connection_reset,                   // ECONNRESET
+    cross_device_link,                  // EXDEV
+    destination_address_required,       // EDESTADDRREQ
+    device_or_resource_busy,            // EBUSY
+    directory_not_empty,                // ENOTEMPTY
+    executable_format_error,            // ENOEXEC
+    file_exists,                        // EEXIST
+    file_too_large,                     // EFBIG
+    filename_too_long,                  // ENAMETOOLONG
+    function_not_supported,             // ENOSYS
+    host_unreachable,                   // EHOSTUNREACH
+    identifier_removed,                 // EIDRM
+    illegal_byte_sequence,              // EILSEQ
+    inappropriate_io_control_operation, // ENOTTY
+    interrupted,                        // EINTR
+    invalid_argument,                   // EINVAL
+    invalid_seek,                       // ESPIPE
+    io_error,                           // EIO
+    is_a_directory,                     // EISDIR
+    message_size,                       // EMSGSIZE
+    network_down,                       // ENETDOWN
+    network_reset,                      // ENETRESET
+    network_unreachable,                // ENETUNREACH
+    no_buffer_space,                    // ENOBUFS
+    no_child_process,                   // ECHILD
+    no_link,                            // ENOLINK
+    no_lock_available,                  // ENOLCK
+    no_message_available,               // ENODATA
+    no_message,                         // ENOMSG
+    no_protocol_option,                 // ENOPROTOOPT
+    no_space_on_device,                 // ENOSPC
+    no_stream_resources,                // ENOSR
+    no_such_device_or_address,          // ENXIO
+    no_such_device,                     // ENODEV
+    no_such_file_or_directory,          // ENOENT
+    no_such_process,                    // ESRCH
+    not_a_directory,                    // ENOTDIR
+    not_a_socket,                       // ENOTSOCK
+    not_a_stream,                       // ENOSTR
+    not_connected,                      // ENOTCONN
+    not_enough_memory,                  // ENOMEM
+    not_supported,                      // ENOTSUP
+    operation_canceled,                 // ECANCELED
+    operation_in_progress,              // EINPROGRESS
+    operation_not_permitted,            // EPERM
+    operation_not_supported,            // EOPNOTSUPP
+    operation_would_block,              // EWOULDBLOCK
+    owner_dead,                         // EOWNERDEAD
+    permission_denied,                  // EACCES
+    protocol_error,                     // EPROTO
+    protocol_not_supported,             // EPROTONOSUPPORT
+    read_only_file_system,              // EROFS
+    resource_deadlock_would_occur,      // EDEADLK
+    resource_unavailable_try_again,     // EAGAIN
+    result_out_of_range,                // ERANGE
+    state_not_recoverable,              // ENOTRECOVERABLE
+    stream_timeout,                     // ETIME
+    text_file_busy,                     // ETXTBSY
+    timed_out,                          // ETIMEDOUT
+    too_many_files_open_in_system,      // ENFILE
+    too_many_files_open,                // EMFILE
+    too_many_links,                     // EMLINK
+    too_many_symbolic_link_levels,      // ELOOP
+    value_too_large,                    // EOVERFLOW
+    wrong_protocol_type                 // EPROTOTYPE
+};
+
+template <> struct is_error_condition_enum<errc>
+    : true_type { }
+
+error_code make_error_code(errc e) noexcept;
+error_condition make_error_condition(errc e) noexcept;
+
+// Comparison operators:
+bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
+bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
+bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
+bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
+bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
+bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
+bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
+bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
+
+template <> struct hash<std::error_code>;
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cerrno>
+#include <type_traits>
+#include <stdexcept>
+#include <__functional_base>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// is_error_code_enum
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum
+    : public false_type {};
+
+// is_error_condition_enum
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum
+    : public false_type {};
+
+// Some error codes are not present on all platforms, so we provide equivalents
+// for them:
+
+//enum class errc
+_LIBCPP_DECLARE_STRONG_ENUM(errc)
+{
+    address_family_not_supported        = EAFNOSUPPORT,
+    address_in_use                      = EADDRINUSE,
+    address_not_available               = EADDRNOTAVAIL,
+    already_connected                   = EISCONN,
+    argument_list_too_long              = E2BIG,
+    argument_out_of_domain              = EDOM,
+    bad_address                         = EFAULT,
+    bad_file_descriptor                 = EBADF,
+    bad_message                         = EBADMSG,
+    broken_pipe                         = EPIPE,
+    connection_aborted                  = ECONNABORTED,
+    connection_already_in_progress      = EALREADY,
+    connection_refused                  = ECONNREFUSED,
+    connection_reset                    = ECONNRESET,
+    cross_device_link                   = EXDEV,
+    destination_address_required        = EDESTADDRREQ,
+    device_or_resource_busy             = EBUSY,
+    directory_not_empty                 = ENOTEMPTY,
+    executable_format_error             = ENOEXEC,
+    file_exists                         = EEXIST,
+    file_too_large                      = EFBIG,
+    filename_too_long                   = ENAMETOOLONG,
+    function_not_supported              = ENOSYS,
+    host_unreachable                    = EHOSTUNREACH,
+    identifier_removed                  = EIDRM,
+    illegal_byte_sequence               = EILSEQ,
+    inappropriate_io_control_operation  = ENOTTY,
+    interrupted                         = EINTR,
+    invalid_argument                    = EINVAL,
+    invalid_seek                        = ESPIPE,
+    io_error                            = EIO,
+    is_a_directory                      = EISDIR,
+    message_size                        = EMSGSIZE,
+    network_down                        = ENETDOWN,
+    network_reset                       = ENETRESET,
+    network_unreachable                 = ENETUNREACH,
+    no_buffer_space                     = ENOBUFS,
+    no_child_process                    = ECHILD,
+    no_link                             = ENOLINK,
+    no_lock_available                   = ENOLCK,
+#ifdef ENODATA
+    no_message_available                = ENODATA,
+#else
+    no_message_available                = ENOMSG,
+#endif
+    no_message                          = ENOMSG,
+    no_protocol_option                  = ENOPROTOOPT,
+    no_space_on_device                  = ENOSPC,
+#ifdef ENOSR
+    no_stream_resources                 = ENOSR,
+#else
+    no_stream_resources                 = ENOMEM,
+#endif
+    no_such_device_or_address           = ENXIO,
+    no_such_device                      = ENODEV,
+    no_such_file_or_directory           = ENOENT,
+    no_such_process                     = ESRCH,
+    not_a_directory                     = ENOTDIR,
+    not_a_socket                        = ENOTSOCK,
+#ifdef ENOSTR
+    not_a_stream                        = ENOSTR,
+#else
+    not_a_stream                        = EINVAL,
+#endif
+    not_connected                       = ENOTCONN,
+    not_enough_memory                   = ENOMEM,
+    not_supported                       = ENOTSUP,
+    operation_canceled                  = ECANCELED,
+    operation_in_progress               = EINPROGRESS,
+    operation_not_permitted             = EPERM,
+    operation_not_supported             = EOPNOTSUPP,
+    operation_would_block               = EWOULDBLOCK,
+    owner_dead                          = EOWNERDEAD,
+    permission_denied                   = EACCES,
+    protocol_error                      = EPROTO,
+    protocol_not_supported              = EPROTONOSUPPORT,
+    read_only_file_system               = EROFS,
+    resource_deadlock_would_occur       = EDEADLK,
+    resource_unavailable_try_again      = EAGAIN,
+    result_out_of_range                 = ERANGE,
+    state_not_recoverable               = ENOTRECOVERABLE,
+#ifdef ETIME
+    stream_timeout                      = ETIME,
+#else
+    stream_timeout                      = ETIMEDOUT,
+#endif
+    text_file_busy                      = ETXTBSY,
+    timed_out                           = ETIMEDOUT,
+    too_many_files_open_in_system       = ENFILE,
+    too_many_files_open                 = EMFILE,
+    too_many_links                      = EMLINK,
+    too_many_symbolic_link_levels       = ELOOP,
+    value_too_large                     = EOVERFLOW,
+    wrong_protocol_type                 = EPROTOTYPE
+};
+_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc)
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc>
+    : true_type { };
+
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum<errc::__lx>
+    : true_type { };
+#endif
+
+class _LIBCPP_TYPE_VIS error_condition;
+class _LIBCPP_TYPE_VIS error_code;
+
+// class error_category
+
+class _LIBCPP_HIDDEN __do_message;
+
+class _LIBCPP_TYPE_VIS error_category
+{
+public:
+    virtual ~error_category() _NOEXCEPT;
+
+#ifdef _LIBCPP_BUILDING_SYSTEM_ERROR
+    error_category() _NOEXCEPT;
+#else
+    _LIBCPP_ALWAYS_INLINE
+    _LIBCPP_CONSTEXPR_AFTER_CXX11 error_category() _NOEXCEPT _LIBCPP_DEFAULT;
+#endif
+private:
+    error_category(const error_category&);// = delete;
+    error_category& operator=(const error_category&);// = delete;
+
+public:
+    virtual const char* name() const _NOEXCEPT = 0;
+    virtual error_condition default_error_condition(int __ev) const _NOEXCEPT;
+    virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT;
+    virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT;
+    virtual string message(int __ev) const = 0;
+
+    _LIBCPP_ALWAYS_INLINE
+    bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;}
+
+    _LIBCPP_ALWAYS_INLINE
+    bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);}
+
+    _LIBCPP_ALWAYS_INLINE
+    bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;}
+
+    friend class _LIBCPP_HIDDEN __do_message;
+};
+
+class _LIBCPP_HIDDEN __do_message
+    : public error_category
+{
+public:
+    virtual string message(int ev) const;
+};
+
+_LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT;
+_LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT;
+
+class _LIBCPP_TYPE_VIS error_condition
+{
+    int __val_;
+    const error_category* __cat_;
+public:
+    _LIBCPP_ALWAYS_INLINE
+    error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    error_condition(int __val, const error_category& __cat) _NOEXCEPT
+        : __val_(__val), __cat_(&__cat) {}
+
+    template <class _Ep>
+        _LIBCPP_ALWAYS_INLINE
+        error_condition(_Ep __e,
+              typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0
+                                                                     ) _NOEXCEPT
+            {*this = make_error_condition(__e);}
+
+    _LIBCPP_ALWAYS_INLINE
+    void assign(int __val, const error_category& __cat) _NOEXCEPT
+    {
+        __val_ = __val;
+        __cat_ = &__cat;
+    }
+
+    template <class _Ep>
+        _LIBCPP_ALWAYS_INLINE
+        typename enable_if
+        <
+            is_error_condition_enum<_Ep>::value,
+            error_condition&
+        >::type
+        operator=(_Ep __e) _NOEXCEPT
+            {*this = make_error_condition(__e); return *this;}
+
+    _LIBCPP_ALWAYS_INLINE
+    void clear() _NOEXCEPT
+    {
+        __val_ = 0;
+        __cat_ = &generic_category();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int value() const _NOEXCEPT {return __val_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    const error_category& category() const _NOEXCEPT {return *__cat_;}
+    string message() const;
+
+    _LIBCPP_ALWAYS_INLINE
+        _LIBCPP_EXPLICIT
+        operator bool() const _NOEXCEPT {return __val_ != 0;}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_condition
+make_error_condition(errc __e) _NOEXCEPT
+{
+    return error_condition(static_cast<int>(__e), generic_category());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT
+{
+    return __x.category() < __y.category()
+        || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+// error_code
+
+class _LIBCPP_TYPE_VIS error_code
+{
+    int __val_;
+    const error_category* __cat_;
+public:
+    _LIBCPP_ALWAYS_INLINE
+    error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {}
+
+    _LIBCPP_ALWAYS_INLINE
+    error_code(int __val, const error_category& __cat) _NOEXCEPT
+        : __val_(__val), __cat_(&__cat) {}
+
+    template <class _Ep>
+        _LIBCPP_ALWAYS_INLINE
+        error_code(_Ep __e,
+                   typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0
+                                                                     ) _NOEXCEPT
+            {*this = make_error_code(__e);}
+
+    _LIBCPP_ALWAYS_INLINE
+    void assign(int __val, const error_category& __cat) _NOEXCEPT
+    {
+        __val_ = __val;
+        __cat_ = &__cat;
+    }
+
+    template <class _Ep>
+        _LIBCPP_ALWAYS_INLINE
+        typename enable_if
+        <
+            is_error_code_enum<_Ep>::value,
+            error_code&
+        >::type
+        operator=(_Ep __e) _NOEXCEPT
+            {*this = make_error_code(__e); return *this;}
+
+    _LIBCPP_ALWAYS_INLINE
+    void clear() _NOEXCEPT
+    {
+        __val_ = 0;
+        __cat_ = &system_category();
+    }
+
+    _LIBCPP_ALWAYS_INLINE
+    int value() const _NOEXCEPT {return __val_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    const error_category& category() const _NOEXCEPT {return *__cat_;}
+
+    _LIBCPP_ALWAYS_INLINE
+    error_condition default_error_condition() const _NOEXCEPT
+        {return __cat_->default_error_condition(__val_);}
+
+    string message() const;
+
+    _LIBCPP_ALWAYS_INLINE
+        _LIBCPP_EXPLICIT
+        operator bool() const _NOEXCEPT {return __val_ != 0;}
+};
+
+inline _LIBCPP_INLINE_VISIBILITY
+error_code
+make_error_code(errc __e) _NOEXCEPT
+{
+    return error_code(static_cast<int>(__e), generic_category());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<(const error_code& __x, const error_code& __y) _NOEXCEPT
+{
+    return __x.category() < __y.category()
+        || (__x.category() == __y.category() && __x.value() < __y.value());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const error_code& __x, const error_code& __y) _NOEXCEPT
+{
+    return __x.category() == __y.category() && __x.value() == __y.value();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT
+{
+    return __x.category().equivalent(__x.value(), __y)
+        || __y.category().equivalent(__x, __y.value());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT
+{
+    return __y == __x;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT
+{
+    return __x.category() == __y.category() && __x.value() == __y.value();
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT
+{return !(__x == __y);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT
+{return !(__x == __y);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT
+{return !(__x == __y);}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT
+{return !(__x == __y);}
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<error_code>
+    : public unary_function<error_code, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const error_code& __ec) const _NOEXCEPT
+    {
+        return static_cast<size_t>(__ec.value());
+    }
+};
+
+// system_error
+
+class _LIBCPP_TYPE_VIS system_error
+    : public runtime_error
+{
+    error_code __ec_;
+public:
+    system_error(error_code __ec, const string& __what_arg);
+    system_error(error_code __ec, const char* __what_arg);
+    system_error(error_code __ec);
+    system_error(int __ev, const error_category& __ecat, const string& __what_arg);
+    system_error(int __ev, const error_category& __ecat, const char* __what_arg);
+    system_error(int __ev, const error_category& __ecat);
+    ~system_error() _NOEXCEPT;
+
+    _LIBCPP_ALWAYS_INLINE
+    const error_code& code() const _NOEXCEPT {return __ec_;}
+
+private:
+    static string __init(const error_code&, string);
+};
+
+_LIBCPP_FUNC_VIS void __throw_system_error(int ev, const char* what_arg);
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_SYSTEM_ERROR
diff --git a/include/c++/v1/tgmath.h b/include/c++/v1/tgmath.h
new file mode 100644
index 0000000..fbe1e82
--- /dev/null
+++ b/include/c++/v1/tgmath.h
@@ -0,0 +1,29 @@
+// -*- C++ -*-
+//===-------------------------- tgmath.h ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_TGMATH_H
+#define _LIBCPP_TGMATH_H
+
+/*
+    tgmath.h synopsis
+
+#include <complex.h>
+#include <math.h>
+
+*/
+
+#include <complex.h>
+#include <math.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#endif  // _LIBCPP_TGMATH_H
diff --git a/include/c++/v1/thread b/include/c++/v1/thread
new file mode 100644
index 0000000..1f1e4a2
--- /dev/null
+++ b/include/c++/v1/thread
@@ -0,0 +1,458 @@
+// -*- C++ -*-
+//===--------------------------- thread -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_THREAD
+#define _LIBCPP_THREAD
+
+/*
+
+    thread synopsis
+
+#define __STDCPP_THREADS__ __cplusplus
+
+namespace std
+{
+
+class thread
+{
+public:
+    class id;
+    typedef pthread_t native_handle_type;
+
+    thread() noexcept;
+    template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
+    ~thread();
+
+    thread(const thread&) = delete;
+    thread(thread&& t) noexcept;
+
+    thread& operator=(const thread&) = delete;
+    thread& operator=(thread&& t) noexcept;
+
+    void swap(thread& t) noexcept;
+
+    bool joinable() const noexcept;
+    void join();
+    void detach();
+    id get_id() const noexcept;
+    native_handle_type native_handle();
+
+    static unsigned hardware_concurrency() noexcept;
+};
+
+void swap(thread& x, thread& y) noexcept;
+
+class thread::id
+{
+public:
+    id() noexcept;
+};
+
+bool operator==(thread::id x, thread::id y) noexcept;
+bool operator!=(thread::id x, thread::id y) noexcept;
+bool operator< (thread::id x, thread::id y) noexcept;
+bool operator<=(thread::id x, thread::id y) noexcept;
+bool operator> (thread::id x, thread::id y) noexcept;
+bool operator>=(thread::id x, thread::id y) noexcept;
+
+template<class charT, class traits>
+basic_ostream<charT, traits>&
+operator<<(basic_ostream<charT, traits>& out, thread::id id);
+
+namespace this_thread
+{
+
+thread::id get_id() noexcept;
+
+void yield() noexcept;
+
+template <class Clock, class Duration>
+void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+template <class Rep, class Period>
+void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+}  // this_thread
+
+}  // std
+
+*/
+
+#include <__config>
+#include <iosfwd>
+#include <__functional_base>
+#include <type_traits>
+#include <cstddef>
+#include <functional>
+#include <memory>
+#include <system_error>
+#include <chrono>
+#include <__mutex_base>
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+#include <tuple>
+#endif
+#include <pthread.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#define __STDCPP_THREADS__ __cplusplus
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+class __thread_specific_ptr
+{
+    pthread_key_t __key_;
+
+    __thread_specific_ptr(const __thread_specific_ptr&);
+    __thread_specific_ptr& operator=(const __thread_specific_ptr&);
+
+    static void __at_thread_exit(void*);
+public:
+    typedef _Tp* pointer;
+
+    __thread_specific_ptr();
+    ~__thread_specific_ptr();
+
+    _LIBCPP_INLINE_VISIBILITY
+    pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator*() const {return *get();}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return get();}
+    pointer release();
+    void reset(pointer __p = nullptr);
+};
+
+template <class _Tp>
+void
+__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
+{
+    delete static_cast<pointer>(__p);
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::__thread_specific_ptr()
+{
+    int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__ec)
+        throw system_error(error_code(__ec, system_category()),
+                           "__thread_specific_ptr construction failed");
+#endif
+}
+
+template <class _Tp>
+__thread_specific_ptr<_Tp>::~__thread_specific_ptr()
+{
+    pthread_key_delete(__key_);
+}
+
+template <class _Tp>
+typename __thread_specific_ptr<_Tp>::pointer
+__thread_specific_ptr<_Tp>::release()
+{
+    pointer __p = get();
+    pthread_setspecific(__key_, 0);
+    return __p;
+}
+
+template <class _Tp>
+void
+__thread_specific_ptr<_Tp>::reset(pointer __p)
+{
+    pointer __p_old = get();
+    pthread_setspecific(__key_, __p);
+    delete __p_old;
+}
+
+class _LIBCPP_TYPE_VIS thread;
+class _LIBCPP_TYPE_VIS __thread_id;
+
+namespace this_thread
+{
+
+_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
+
+}  // this_thread
+
+template<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;
+
+class _LIBCPP_TYPE_VIS_ONLY __thread_id
+{
+    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
+    // NULL is the no-thread value on Darwin.  Someone needs to check
+    // on other platforms.  We assume 0 works everywhere for now.
+    pthread_t __id_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __thread_id() _NOEXCEPT : __id_(0) {}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return __x.__id_ == __y.__id_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return !(__x == __y);}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return __x.__id_ < __y.__id_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return !(__y < __x);}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return   __y < __x ;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
+        {return !(__x < __y);}
+
+    template<class _CharT, class _Traits>
+    friend
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id)
+        {return __os << __id.__id_;}
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    __thread_id(pthread_t __id) : __id_(__id) {}
+
+    friend __thread_id this_thread::get_id() _NOEXCEPT;
+    friend class _LIBCPP_TYPE_VIS thread;
+    friend struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>;
+};
+
+template<>
+struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>
+    : public unary_function<__thread_id, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(__thread_id __v) const
+    {
+        return hash<pthread_t>()(__v.__id_);
+    }
+};
+
+namespace this_thread
+{
+
+inline _LIBCPP_INLINE_VISIBILITY
+__thread_id
+get_id() _NOEXCEPT
+{
+    return pthread_self();
+}
+
+}  // this_thread
+
+class _LIBCPP_TYPE_VIS thread
+{
+    pthread_t __t_;
+
+    thread(const thread&);
+    thread& operator=(const thread&);
+public:
+    typedef __thread_id id;
+    typedef pthread_t native_handle_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    thread() _NOEXCEPT : __t_(0) {}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _Fp, class ..._Args,
+              class = typename enable_if
+              <
+                   !is_same<typename decay<_Fp>::type, thread>::value
+              >::type
+             >
+        explicit thread(_Fp&& __f, _Args&&... __args);
+#else  // _LIBCPP_HAS_NO_VARIADICS
+    template <class _Fp> explicit thread(_Fp __f);
+#endif
+    ~thread();
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = 0;}
+    thread& operator=(thread&& __t) _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool joinable() const _NOEXCEPT {return __t_ != 0;}
+    void join();
+    void detach();
+    _LIBCPP_INLINE_VISIBILITY
+    id get_id() const _NOEXCEPT {return __t_;}
+    _LIBCPP_INLINE_VISIBILITY
+    native_handle_type native_handle() _NOEXCEPT {return __t_;}
+
+    static unsigned hardware_concurrency() _NOEXCEPT;
+};
+
+class __assoc_sub_state;
+
+class _LIBCPP_HIDDEN __thread_struct_imp;
+
+class _LIBCPP_TYPE_VIS __thread_struct
+{
+    __thread_struct_imp* __p_;
+
+    __thread_struct(const __thread_struct&);
+    __thread_struct& operator=(const __thread_struct&);
+public:
+    __thread_struct();
+    ~__thread_struct();
+
+    void notify_all_at_thread_exit(condition_variable*, mutex*);
+    void __make_ready_at_thread_exit(__assoc_sub_state*);
+};
+
+_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data();
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Fp, class ..._Args, size_t ..._Indices>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>)
+{
+    __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
+}
+
+template <class _Fp>
+void*
+__thread_proxy(void* __vp)
+{
+    __thread_local_data().reset(new __thread_struct);
+    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
+    __thread_execute(*__p, _Index());
+    return nullptr;
+}
+
+template <class _Fp, class ..._Args,
+          class
+         >
+thread::thread(_Fp&& __f, _Args&&... __args)
+{
+    typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp;
+    _VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)),
+                                __decay_copy(_VSTD::forward<_Args>(__args))...));
+    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
+    if (__ec == 0)
+        __p.release();
+    else
+        __throw_system_error(__ec, "thread constructor failed");
+}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Fp>
+void*
+__thread_proxy(void* __vp)
+{
+    __thread_local_data().reset(new __thread_struct);
+    std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
+    (*__p)();
+    return nullptr;
+}
+
+template <class _Fp>
+thread::thread(_Fp __f)
+{
+    std::unique_ptr<_Fp> __p(new _Fp(__f));
+    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());
+    if (__ec == 0)
+        __p.release();
+    else
+        __throw_system_error(__ec, "thread constructor failed");
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+inline _LIBCPP_INLINE_VISIBILITY
+thread&
+thread::operator=(thread&& __t) _NOEXCEPT
+{
+    if (__t_ != 0)
+        terminate();
+    __t_ = __t.__t_;
+    __t.__t_ = 0;
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);}
+
+namespace this_thread
+{
+
+_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns);
+
+template <class _Rep, class _Period>
+void
+sleep_for(const chrono::duration<_Rep, _Period>& __d)
+{
+    using namespace chrono;
+    if (__d > duration<_Rep, _Period>::zero())
+    {
+        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
+        nanoseconds __ns;
+        if (__d < _Max)
+        {
+            __ns = duration_cast<nanoseconds>(__d);
+            if (__ns < __d)
+                ++__ns;
+        }
+        else
+            __ns = nanoseconds::max();
+        sleep_for(__ns);
+    }
+}
+
+template <class _Clock, class _Duration>
+void
+sleep_until(const chrono::time_point<_Clock, _Duration>& __t)
+{
+    using namespace chrono;
+    mutex __mut;
+    condition_variable __cv;
+    unique_lock<mutex> __lk(__mut);
+    while (_Clock::now() < __t)
+        __cv.wait_until(__lk, __t);
+}
+
+template <class _Duration>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
+{
+    using namespace chrono;
+    sleep_for(__t - steady_clock::now());
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void yield() _NOEXCEPT {sched_yield();}
+
+}  // this_thread
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_THREAD
diff --git a/include/c++/v1/tuple b/include/c++/v1/tuple
new file mode 100644
index 0000000..e98ae72
--- /dev/null
+++ b/include/c++/v1/tuple
@@ -0,0 +1,1100 @@
+// -*- C++ -*-
+//===--------------------------- tuple ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_TUPLE
+#define _LIBCPP_TUPLE
+
+/*
+    tuple synopsis
+
+namespace std
+{
+
+template <class... T>
+class tuple {
+public:
+    constexpr tuple();
+    explicit tuple(const T&...);  // constexpr in C++14
+    template <class... U>
+        explicit tuple(U&&...);  // constexpr in C++14
+    tuple(const tuple&) = default;
+    tuple(tuple&&) = default;
+    template <class... U>
+        tuple(const tuple<U...>&);  // constexpr in C++14
+    template <class... U>
+        tuple(tuple<U...>&&);  // constexpr in C++14
+    template <class U1, class U2>
+        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
+    template <class U1, class U2>
+        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
+
+    // allocator-extended constructors
+    template <class Alloc>
+        tuple(allocator_arg_t, const Alloc& a);
+    template <class Alloc>
+        tuple(allocator_arg_t, const Alloc& a, const T&...);
+    template <class Alloc, class... U>
+        tuple(allocator_arg_t, const Alloc& a, U&&...);
+    template <class Alloc>
+        tuple(allocator_arg_t, const Alloc& a, const tuple&);
+    template <class Alloc>
+        tuple(allocator_arg_t, const Alloc& a, tuple&&);
+    template <class Alloc, class... U>
+        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
+    template <class Alloc, class... U>
+        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
+    template <class Alloc, class U1, class U2>
+        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
+    template <class Alloc, class U1, class U2>
+        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
+
+    tuple& operator=(const tuple&);
+    tuple&
+        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
+    template <class... U>
+        tuple& operator=(const tuple<U...>&);
+    template <class... U>
+        tuple& operator=(tuple<U...>&&);
+    template <class U1, class U2>
+        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
+    template <class U1, class U2>
+        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
+
+    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
+};
+
+const unspecified ignore;
+
+template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
+template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
+template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
+template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
+  
+// 20.4.1.4, tuple helper classes:
+template <class T> class tuple_size; // undefined
+template <class... T> class tuple_size<tuple<T...>>;
+template <intsize_t I, class T> class tuple_element; // undefined
+template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
+template <size_t _Ip, class ..._Tp>
+  using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; // C++14
+
+// 20.4.1.5, element access:
+template <intsize_t I, class... T>
+    typename tuple_element<I, tuple<T...>>::type&
+    get(tuple<T...>&) noexcept; // constexpr in C++14
+template <intsize_t I, class... T>
+    typename const tuple_element<I, tuple<T...>>::type &
+    get(const tuple<T...>&) noexcept; // constexpr in C++14
+template <intsize_t I, class... T>
+    typename tuple_element<I, tuple<T...>>::type&&
+    get(tuple<T...>&&) noexcept; // constexpr in C++14
+
+template <class T1, class... T>
+    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
+template <class T1, class... T>
+    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
+template <class T1, class... T>
+    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
+
+// 20.4.1.6, relational operators:
+template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
+template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
+template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
+
+template <class... Types, class Alloc>
+  struct uses_allocator<tuple<Types...>, Alloc>;
+
+template <class... Types>
+  void
+  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__tuple>
+#include <cstddef>
+#include <type_traits>
+#include <__functional_base>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// tuple_size
+
+template <class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >
+    : public integral_constant<size_t, sizeof...(_Tp)>
+{
+};
+
+// tuple_element
+
+template <size_t _Ip, class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
+{
+public:
+    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Ip, class ..._Tp>
+using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
+#endif
+
+// __tuple_leaf
+
+template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
+#if __has_feature(is_final)
+                                 && !__is_final(_Hp)
+#endif
+         >
+class __tuple_leaf;
+
+template <size_t _Ip, class _Hp, bool _Ep>
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
+    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
+{
+    swap(__x.get(), __y.get());
+}
+
+template <size_t _Ip, class _Hp, bool>
+class __tuple_leaf
+{
+    _Hp value;
+
+    __tuple_leaf& operator=(const __tuple_leaf&);
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
+             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
+       {static_assert(!is_reference<_Hp>::value,
+              "Attempted to default construct a reference element in a tuple");}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
+            : value()
+        {static_assert(!is_reference<_Hp>::value,
+              "Attempted to default construct a reference element in a tuple");}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
+            : value(allocator_arg_t(), __a)
+        {static_assert(!is_reference<_Hp>::value,
+              "Attempted to default construct a reference element in a tuple");}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
+            : value(__a)
+        {static_assert(!is_reference<_Hp>::value,
+              "Attempted to default construct a reference element in a tuple");}
+
+    template <class _Tp,
+              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
+            : value(_VSTD::forward<_Tp>(__t))
+        {static_assert(!is_reference<_Hp>::value ||
+                       (is_lvalue_reference<_Hp>::value &&
+                        (is_lvalue_reference<_Tp>::value ||
+                         is_same<typename remove_reference<_Tp>::type,
+                                 reference_wrapper<
+                                    typename remove_reference<_Hp>::type
+                                 >
+                                >::value)) ||
+                        (is_rvalue_reference<_Hp>::value &&
+                         !is_lvalue_reference<_Tp>::value),
+       "Attempted to construct a reference element in a tuple with an rvalue");}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
+            : value(_VSTD::forward<_Tp>(__t))
+        {static_assert(!is_lvalue_reference<_Hp>::value ||
+                       (is_lvalue_reference<_Hp>::value &&
+                        (is_lvalue_reference<_Tp>::value ||
+                         is_same<typename remove_reference<_Tp>::type,
+                                 reference_wrapper<
+                                    typename remove_reference<_Hp>::type
+                                 >
+                                >::value)),
+       "Attempted to construct a reference element in a tuple with an rvalue");}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
+            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
+        {static_assert(!is_lvalue_reference<_Hp>::value ||
+                       (is_lvalue_reference<_Hp>::value &&
+                        (is_lvalue_reference<_Tp>::value ||
+                         is_same<typename remove_reference<_Tp>::type,
+                                 reference_wrapper<
+                                    typename remove_reference<_Hp>::type
+                                 >
+                                >::value)),
+       "Attempted to construct a reference element in a tuple with an rvalue");}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
+            : value(_VSTD::forward<_Tp>(__t), __a)
+        {static_assert(!is_lvalue_reference<_Hp>::value ||
+                       (is_lvalue_reference<_Hp>::value &&
+                        (is_lvalue_reference<_Tp>::value ||
+                         is_same<typename remove_reference<_Tp>::type,
+                                 reference_wrapper<
+                                    typename remove_reference<_Hp>::type
+                                 >
+                                >::value)),
+       "Attempted to construct a reference element in a tuple with an rvalue");}
+
+    __tuple_leaf(const __tuple_leaf& __t) = default;
+    __tuple_leaf(__tuple_leaf&& __t) = default;
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf&
+        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
+        {
+            value = _VSTD::forward<_Tp>(__t);
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
+    {
+        _VSTD::swap(*this, __t);
+        return 0;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
+};
+
+template <size_t _Ip, class _Hp>
+class __tuple_leaf<_Ip, _Hp, true>
+    : private _Hp
+{
+
+    __tuple_leaf& operator=(const __tuple_leaf&);
+public:
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
+             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
+            : _Hp(allocator_arg_t(), __a) {}
+
+    template <class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
+            : _Hp(__a) {}
+
+    template <class _Tp,
+              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
+            : _Hp(_VSTD::forward<_Tp>(__t)) {}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
+            : _Hp(_VSTD::forward<_Tp>(__t)) {}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
+            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
+
+    template <class _Tp, class _Alloc>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
+            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
+
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_leaf&
+        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
+        {
+            _Hp::operator=(_VSTD::forward<_Tp>(__t));
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    int
+    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
+    {
+        _VSTD::swap(*this, __t);
+        return 0;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
+};
+
+template <class ..._Tp>
+_LIBCPP_INLINE_VISIBILITY
+void __swallow(_Tp&&...) _NOEXCEPT {}
+
+template <bool ...> struct __all;
+
+template <>
+struct __all<>
+{
+    static const bool value = true;
+};
+
+template <bool _B0, bool ... _Bp>
+struct __all<_B0, _Bp...>
+{
+    static const bool value = _B0 && __all<_Bp...>::value;
+};
+
+// __tuple_impl
+
+template<class _Indx, class ..._Tp> struct __tuple_impl;
+
+template<size_t ..._Indx, class ..._Tp>
+struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
+    : public __tuple_leaf<_Indx, _Tp>...
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR __tuple_impl()
+        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
+
+    template <size_t ..._Uf, class ..._Tf,
+              size_t ..._Ul, class ..._Tl, class ..._Up>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        explicit
+        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
+                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
+                     _Up&&... __u)
+                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
+                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
+            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
+            __tuple_leaf<_Ul, _Tl>()...
+            {}
+
+    template <class _Alloc, size_t ..._Uf, class ..._Tf,
+              size_t ..._Ul, class ..._Tl, class ..._Up>
+        _LIBCPP_INLINE_VISIBILITY
+        explicit
+        __tuple_impl(allocator_arg_t, const _Alloc& __a,
+                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
+                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
+                     _Up&&... __u) :
+            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
+            _VSTD::forward<_Up>(__u))...,
+            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
+            {}
+
+    template <class _Tuple,
+              class = typename enable_if
+                      <
+                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
+                      >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
+            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
+            {}
+
+    template <class _Alloc, class _Tuple,
+              class = typename enable_if
+                      <
+                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
+                      >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
+            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
+                                       _VSTD::forward<typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
+            {}
+
+    template <class _Tuple>
+        _LIBCPP_INLINE_VISIBILITY
+        typename enable_if
+        <
+            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
+            __tuple_impl&
+        >::type
+        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
+        {
+            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
+                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
+            return *this;
+        }
+
+    __tuple_impl(const __tuple_impl&) = default;
+    __tuple_impl(__tuple_impl&&) = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tuple_impl&
+    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
+    {
+        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __tuple_impl&
+    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
+    {
+        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
+        return *this;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(__tuple_impl& __t)
+        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
+    {
+        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
+    }
+};
+
+template <class ..._Tp>
+class _LIBCPP_TYPE_VIS_ONLY tuple
+{
+    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
+
+    base base_;
+
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
+        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
+        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
+    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
+        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
+public:
+
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR tuple()
+        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
+        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
+                typename __make_tuple_indices<0>::type(),
+                typename __make_tuple_types<tuple, 0>::type(),
+                __t...
+               ) {}
+
+    template <class _Alloc>
+      _LIBCPP_INLINE_VISIBILITY
+      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
+        : base_(allocator_arg_t(), __a,
+                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
+                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
+                typename __make_tuple_indices<0>::type(),
+                typename __make_tuple_types<tuple, 0>::type(),
+                __t...
+               ) {}
+
+    template <class ..._Up,
+              typename enable_if
+                      <
+                         sizeof...(_Up) <= sizeof...(_Tp) &&
+                         __tuple_convertible
+                         <
+                            tuple<_Up...>,
+                            typename __make_tuple_types<tuple,
+                                     sizeof...(_Up) < sizeof...(_Tp) ?
+                                        sizeof...(_Up) :
+                                        sizeof...(_Tp)>::type
+                         >::value,
+                         bool
+                      >::type = false
+             >
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        tuple(_Up&&... __u)
+            _NOEXCEPT_((
+                is_nothrow_constructible<
+                    typename __make_tuple_indices<sizeof...(_Up)>::type,
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
+                    _Up...
+                >::value
+            ))
+            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    _VSTD::forward<_Up>(__u)...) {}
+
+    template <class ..._Up,
+              typename enable_if
+                      <
+                         sizeof...(_Up) <= sizeof...(_Tp) &&
+                         __tuple_constructible
+                         <
+                            tuple<_Up...>,
+                            typename __make_tuple_types<tuple,
+                                     sizeof...(_Up) < sizeof...(_Tp) ?
+                                        sizeof...(_Up) :
+                                        sizeof...(_Tp)>::type
+                         >::value &&
+                         !__tuple_convertible
+                         <
+                            tuple<_Up...>,
+                            typename __make_tuple_types<tuple,
+                                     sizeof...(_Up) < sizeof...(_Tp) ?
+                                        sizeof...(_Up) :
+                                        sizeof...(_Tp)>::type
+                         >::value,
+                         bool
+                      >::type =false
+             >
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        explicit
+        tuple(_Up&&... __u)
+            _NOEXCEPT_((
+                is_nothrow_constructible<
+                    typename __make_tuple_indices<sizeof...(_Up)>::type,
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
+                    _Up...
+                >::value
+            ))
+            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    _VSTD::forward<_Up>(__u)...) {}
+
+    template <class _Alloc, class ..._Up,
+              class = typename enable_if
+                      <
+                         sizeof...(_Up) <= sizeof...(_Tp) &&
+                         __tuple_convertible
+                         <
+                            tuple<_Up...>,
+                            typename __make_tuple_types<tuple,
+                                     sizeof...(_Up) < sizeof...(_Tp) ?
+                                        sizeof...(_Up) :
+                                        sizeof...(_Tp)>::type
+                         >::value
+                      >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
+            : base_(allocator_arg_t(), __a,
+                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
+                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
+                    _VSTD::forward<_Up>(__u)...) {}
+
+    template <class _Tuple,
+              typename enable_if
+                      <
+                         __tuple_convertible<_Tuple, tuple>::value,
+                         bool
+                      >::type = false
+             >
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
+            : base_(_VSTD::forward<_Tuple>(__t)) {}
+
+    template <class _Tuple,
+              typename enable_if
+                      <
+                         __tuple_constructible<_Tuple, tuple>::value &&
+                         !__tuple_convertible<_Tuple, tuple>::value,
+                         bool
+                      >::type = false
+             >
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        explicit
+        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
+            : base_(_VSTD::forward<_Tuple>(__t)) {}
+
+    template <class _Alloc, class _Tuple,
+              class = typename enable_if
+                      <
+                         __tuple_convertible<_Tuple, tuple>::value
+                      >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
+            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
+
+    template <class _Tuple,
+              class = typename enable_if
+                      <
+                         __tuple_assignable<_Tuple, tuple>::value
+                      >::type
+             >
+        _LIBCPP_INLINE_VISIBILITY
+        tuple&
+        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
+        {
+            base_.operator=(_VSTD::forward<_Tuple>(__t));
+            return *this;
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
+        {base_.swap(__t.base_);}
+};
+
+template <>
+class _LIBCPP_TYPE_VIS_ONLY tuple<>
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
+    template <class _Alloc>
+    _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
+    template <class _Alloc>
+    _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
+    template <class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+        tuple(array<_Up, 0>) _NOEXCEPT {}
+    template <class _Alloc, class _Up>
+    _LIBCPP_INLINE_VISIBILITY
+        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(tuple&) _NOEXCEPT {}
+};
+
+template <class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __all<__is_swappable<_Tp>::value...>::value,
+    void
+>::type
+swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
+                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
+    {__t.swap(__u);}
+
+// get
+
+template <size_t _Ip, class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, tuple<_Tp...> >::type&
+get(tuple<_Tp...>& __t) _NOEXCEPT
+{
+    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
+}
+
+template <size_t _Ip, class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, tuple<_Tp...> >::type&
+get(const tuple<_Tp...>& __t) _NOEXCEPT
+{
+    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
+}
+
+template <size_t _Ip, class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, tuple<_Tp...> >::type&&
+get(tuple<_Tp...>&& __t) _NOEXCEPT
+{
+    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
+    return static_cast<type&&>(
+             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
+}
+
+#if _LIBCPP_STD_VER > 11
+// get by type
+template <typename _T1, size_t _Idx, typename... _Args>
+struct __find_exactly_one_t_helper;
+
+// -- find exactly one
+template <typename _T1, size_t _Idx, typename... _Args>
+struct __find_exactly_one_t_checker {
+    static constexpr size_t value = _Idx;
+//  Check the rest of the list to make sure there's only one
+    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
+    };
+
+
+template <typename _T1, size_t _Idx>
+struct __find_exactly_one_t_helper <_T1, _Idx> {
+    static constexpr size_t value = -1;
+    };
+
+template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
+struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
+    static constexpr size_t value =
+        std::conditional<
+            std::is_same<_T1, _Head>::value,
+            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
+            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
+        >::type::value;
+    };
+
+template <typename _T1, typename... _Args>
+struct __find_exactly_one_t {
+    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
+    static_assert ( value != -1, "type not found in type list" );
+    };
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1& get(tuple<_Args...>& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
+}
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
+}
+
+template <class _T1, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
+{
+    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
+}
+
+#endif
+
+// tie
+
+template <class ..._Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+tuple<_Tp&...>
+tie(_Tp&... __t) _NOEXCEPT
+{
+    return tuple<_Tp&...>(__t...);
+}
+
+template <class _Up>
+struct __ignore_t
+{
+    template <class _Tp>
+        _LIBCPP_INLINE_VISIBILITY
+        const __ignore_t& operator=(_Tp&&) const {return *this;}
+};
+
+namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
+
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
+
+template <class _Tp>
+struct __make_tuple_return_impl
+{
+    typedef _Tp type;
+};
+
+template <class _Tp>
+struct __make_tuple_return_impl<reference_wrapper<_Tp> >
+{
+    typedef _Tp& type;
+};
+
+template <class _Tp>
+struct __make_tuple_return
+{
+    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
+};
+
+template <class... _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+tuple<typename __make_tuple_return<_Tp>::type...>
+make_tuple(_Tp&&... __t)
+{
+    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
+}
+
+template <class... _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+tuple<_Tp&&...>
+forward_as_tuple(_Tp&&... __t) _NOEXCEPT
+{
+    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
+}
+
+template <size_t _Ip>
+struct __tuple_equal
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _Tp& __x, const _Up& __y)
+    {
+        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
+    }
+};
+
+template <>
+struct __tuple_equal<0>
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _Tp&, const _Up&)
+    {
+        return true;
+    }
+};
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
+}
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return !(__x == __y);
+}
+
+template <size_t _Ip>
+struct __tuple_less
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _Tp& __x, const _Up& __y)
+    {
+        return __tuple_less<_Ip-1>()(__x, __y) ||
+             (!__tuple_less<_Ip-1>()(__y, __x) && _VSTD::get<_Ip-1>(__x) < _VSTD::get<_Ip-1>(__y));
+    }
+};
+
+template <>
+struct __tuple_less<0>
+{
+    template <class _Tp, class _Up>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    bool operator()(const _Tp&, const _Up&)
+    {
+        return false;
+    }
+};
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
+}
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return __y < __x;
+}
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class ..._Tp, class ..._Up>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
+{
+    return !(__y < __x);
+}
+
+// tuple_cat
+
+template <class _Tp, class _Up> struct __tuple_cat_type;
+
+template <class ..._Ttypes, class ..._Utypes>
+struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
+{
+    typedef tuple<_Ttypes..., _Utypes...> type;
+};
+
+template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
+struct __tuple_cat_return_1
+{
+};
+
+template <class ..._Types, class _Tuple0>
+struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
+{
+    typedef typename __tuple_cat_type<tuple<_Types...>,
+            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
+                                                                           type;
+};
+
+template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
+struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
+    : public __tuple_cat_return_1<
+                 typename __tuple_cat_type<
+                     tuple<_Types...>,
+                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
+                 >::type,
+                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
+                 _Tuple1, _Tuples...>
+{
+};
+
+template <class ..._Tuples> struct __tuple_cat_return;
+
+template <class _Tuple0, class ..._Tuples>
+struct __tuple_cat_return<_Tuple0, _Tuples...>
+    : public __tuple_cat_return_1<tuple<>,
+         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
+                                                                     _Tuples...>
+{
+};
+
+template <>
+struct __tuple_cat_return<>
+{
+    typedef tuple<> type;
+};
+
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+tuple<>
+tuple_cat()
+{
+    return tuple<>();
+}
+
+template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
+struct __tuple_cat_return_ref_imp;
+
+template <class ..._Types, size_t ..._I0, class _Tuple0>
+struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
+{
+    typedef typename remove_reference<_Tuple0>::type _T0;
+    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
+                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
+};
+
+template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
+struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
+                                  _Tuple0, _Tuple1, _Tuples...>
+    : public __tuple_cat_return_ref_imp<
+         tuple<_Types..., typename __apply_cv<_Tuple0,
+               typename tuple_element<_I0,
+                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
+         typename __make_tuple_indices<tuple_size<typename
+                                 remove_reference<_Tuple1>::type>::value>::type,
+         _Tuple1, _Tuples...>
+{
+};
+
+template <class _Tuple0, class ..._Tuples>
+struct __tuple_cat_return_ref
+    : public __tuple_cat_return_ref_imp<tuple<>,
+               typename __make_tuple_indices<
+                        tuple_size<typename remove_reference<_Tuple0>::type>::value
+               >::type, _Tuple0, _Tuples...>
+{
+};
+
+template <class _Types, class _I0, class _J0>
+struct __tuple_cat;
+
+template <class ..._Types, size_t ..._I0, size_t ..._J0>
+struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
+{
+    template <class _Tuple0>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
+    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
+    {
+        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
+                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
+    }
+
+    template <class _Tuple0, class _Tuple1, class ..._Tuples>
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
+    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
+    {
+        typedef typename remove_reference<_Tuple0>::type _T0;
+        typedef typename remove_reference<_Tuple1>::type _T1;
+        return __tuple_cat<
+           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
+           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
+           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
+                           (forward_as_tuple(
+                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
+                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
+                            ),
+                            _VSTD::forward<_Tuple1>(__t1),
+                            _VSTD::forward<_Tuples>(__tpls)...);
+    }
+};
+
+template <class _Tuple0, class... _Tuples>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename __tuple_cat_return<_Tuple0, _Tuples...>::type
+tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
+{
+    typedef typename remove_reference<_Tuple0>::type _T0;
+    return __tuple_cat<tuple<>, __tuple_indices<>,
+                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
+                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
+                                            _VSTD::forward<_Tuples>(__tpls)...);
+}
+
+template <class ..._Tp, class _Alloc>
+struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
+    : true_type {};
+
+template <class _T1, class _T2>
+template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_T1, _T2>::pair(piecewise_construct_t,
+                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
+                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
+    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
+      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
+{
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_TUPLE
diff --git a/include/c++/v1/type_traits b/include/c++/v1/type_traits
new file mode 100644
index 0000000..371a15e
--- /dev/null
+++ b/include/c++/v1/type_traits
@@ -0,0 +1,3428 @@
+// -*- C++ -*-
+//===------------------------ type_traits ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_TYPE_TRAITS
+#define _LIBCPP_TYPE_TRAITS
+
+/*
+    type_traits synopsis
+
+namespace std
+{
+
+    // helper class:
+    template <class T, T v> struct integral_constant;
+    typedef integral_constant<bool, true>  true_type;
+    typedef integral_constant<bool, false> false_type;
+
+    // helper traits
+    template <bool, class T = void> struct enable_if;
+    template <bool, class T, class F> struct conditional;
+
+    // Primary classification traits:
+    template <class T> struct is_void;
+    template <class T> struct is_null_pointer;  // C++14
+    template <class T> struct is_integral;
+    template <class T> struct is_floating_point;
+    template <class T> struct is_array;
+    template <class T> struct is_pointer;
+    template <class T> struct is_lvalue_reference;
+    template <class T> struct is_rvalue_reference;
+    template <class T> struct is_member_object_pointer;
+    template <class T> struct is_member_function_pointer;
+    template <class T> struct is_enum;
+    template <class T> struct is_union;
+    template <class T> struct is_class;
+    template <class T> struct is_function;
+
+    // Secondary classification traits:
+    template <class T> struct is_reference;
+    template <class T> struct is_arithmetic;
+    template <class T> struct is_fundamental;
+    template <class T> struct is_member_pointer;
+    template <class T> struct is_scalar;
+    template <class T> struct is_object;
+    template <class T> struct is_compound;
+
+    // Const-volatile properties and transformations:
+    template <class T> struct is_const;
+    template <class T> struct is_volatile;
+    template <class T> struct remove_const;
+    template <class T> struct remove_volatile;
+    template <class T> struct remove_cv;
+    template <class T> struct add_const;
+    template <class T> struct add_volatile;
+    template <class T> struct add_cv;
+
+    // Reference transformations:
+    template <class T> struct remove_reference;
+    template <class T> struct add_lvalue_reference;
+    template <class T> struct add_rvalue_reference;
+
+    // Pointer transformations:
+    template <class T> struct remove_pointer;
+    template <class T> struct add_pointer;
+
+    // Integral properties:
+    template <class T> struct is_signed;
+    template <class T> struct is_unsigned;
+    template <class T> struct make_signed;
+    template <class T> struct make_unsigned;
+
+    // Array properties and transformations:
+    template <class T> struct rank;
+    template <class T, unsigned I = 0> struct extent;
+    template <class T> struct remove_extent;
+    template <class T> struct remove_all_extents;
+
+    // Member introspection:
+    template <class T> struct is_pod;
+    template <class T> struct is_trivial;
+    template <class T> struct is_trivially_copyable;
+    template <class T> struct is_standard_layout;
+    template <class T> struct is_literal_type;
+    template <class T> struct is_empty;
+    template <class T> struct is_polymorphic;
+    template <class T> struct is_abstract;
+    template <class T> struct is_final; // C++14
+
+    template <class T, class... Args> struct is_constructible;
+    template <class T>                struct is_default_constructible;
+    template <class T>                struct is_copy_constructible;
+    template <class T>                struct is_move_constructible;
+    template <class T, class U>       struct is_assignable;
+    template <class T>                struct is_copy_assignable;
+    template <class T>                struct is_move_assignable;
+    template <class T>                struct is_destructible;
+
+    template <class T, class... Args> struct is_trivially_constructible;
+    template <class T>                struct is_trivially_default_constructible;
+    template <class T>                struct is_trivially_copy_constructible;
+    template <class T>                struct is_trivially_move_constructible;
+    template <class T, class U>       struct is_trivially_assignable;
+    template <class T>                struct is_trivially_copy_assignable;
+    template <class T>                struct is_trivially_move_assignable;
+    template <class T>                struct is_trivially_destructible;
+
+    template <class T, class... Args> struct is_nothrow_constructible;
+    template <class T>                struct is_nothrow_default_constructible;
+    template <class T>                struct is_nothrow_copy_constructible;
+    template <class T>                struct is_nothrow_move_constructible;
+    template <class T, class U>       struct is_nothrow_assignable;
+    template <class T>                struct is_nothrow_copy_assignable;
+    template <class T>                struct is_nothrow_move_assignable;
+    template <class T>                struct is_nothrow_destructible;
+
+    template <class T> struct has_virtual_destructor;
+
+    // Relationships between types:
+    template <class T, class U> struct is_same;
+    template <class Base, class Derived> struct is_base_of;
+    template <class From, class To> struct is_convertible;
+
+    // Alignment properties and transformations:
+    template <class T> struct alignment_of;
+    template <size_t Len, size_t Align = most_stringent_alignment_requirement>
+        struct aligned_storage;
+    template <size_t Len, class... Types> struct aligned_union;
+
+    template <class T> struct decay;
+    template <class... T> struct common_type;
+    template <class T> struct underlying_type;
+    template <class> class result_of; // undefined
+    template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;
+
+    // const-volatile modifications:
+    template <class T>
+      using remove_const_t    = typename remove_const<T>::type;  // C++14
+    template <class T>
+      using remove_volatile_t = typename remove_volatile<T>::type;  // C++14
+    template <class T>
+      using remove_cv_t       = typename remove_cv<T>::type;  // C++14
+    template <class T>
+      using add_const_t       = typename add_const<T>::type;  // C++14
+    template <class T>
+      using add_volatile_t    = typename add_volatile<T>::type;  // C++14
+    template <class T>
+      using add_cv_t          = typename add_cv<T>::type;  // C++14
+  
+    // reference modifications:
+    template <class T>
+      using remove_reference_t     = typename remove_reference<T>::type;  // C++14
+    template <class T>
+      using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;  // C++14
+    template <class T>
+      using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;  // C++14
+  
+    // sign modifications:
+    template <class T>
+      using make_signed_t   = typename make_signed<T>::type;  // C++14
+    template <class T>
+      using make_unsigned_t = typename make_unsigned<T>::type;  // C++14
+  
+    // array modifications:
+    template <class T>
+      using remove_extent_t      = typename remove_extent<T>::type;  // C++14
+    template <class T>
+      using remove_all_extents_t = typename remove_all_extents<T>::type;  // C++14
+
+    // pointer modifications:
+    template <class T>
+      using remove_pointer_t = typename remove_pointer<T>::type;  // C++14
+    template <class T>
+      using add_pointer_t    = typename add_pointer<T>::type;  // C++14
+
+    // other transformations:
+    template <size_t Len, std::size_t Align=default-alignment>
+      using aligned_storage_t = typename aligned_storage<Len,Align>::type;  // C++14
+    template <std::size_t Len, class... Types>
+      using aligned_union_t   = typename aligned_union<Len,Types...>::type;  // C++14
+    template <class T>
+      using decay_t           = typename decay<T>::type;  // C++14
+    template <bool b, class T=void>
+      using enable_if_t       = typename enable_if<b,T>::type;  // C++14
+    template <bool b, class T, class F>
+      using conditional_t     = typename conditional<b,T,F>::type;  // C++14
+    template <class... T>
+      using common_type_t     = typename common_type<T...>::type;  // C++14
+    template <class T>
+      using underlying_type_t = typename underlying_type<T>::type;  // C++14
+    template <class F, class... ArgTypes>
+      using result_of_t       = typename result_of<F(ArgTypes...)>::type;  // C++14
+
+}  // std
+
+*/
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool _Bp, class _If, class _Then>
+    struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _If type;};
+template <class _If, class _Then>
+    struct _LIBCPP_TYPE_VIS_ONLY conditional<false, _If, _Then> {typedef _Then type;};
+
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
+#endif
+
+template <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS_ONLY enable_if {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY enable_if<true, _Tp> {typedef _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
+#endif
+
+
+struct __two {char __lx[2];};
+
+// helper class:
+
+template <class _Tp, _Tp __v>
+struct _LIBCPP_TYPE_VIS_ONLY integral_constant
+{
+    static _LIBCPP_CONSTEXPR const _Tp      value = __v;
+    typedef _Tp               value_type;
+    typedef integral_constant type;
+    _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;}
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+         constexpr value_type operator ()() const _NOEXCEPT {return value;}
+#endif
+};
+
+template <class _Tp, _Tp __v>
+_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
+
+typedef integral_constant<bool, true>  true_type;
+typedef integral_constant<bool, false> false_type;
+
+// is_const
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const            : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const<_Tp const> : public true_type {};
+
+// is_volatile
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile               : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile<_Tp volatile> : public true_type {};
+
+// remove_const
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const            {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const<const _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
+#endif
+
+// remove_volatile
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile               {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile<volatile _Tp> {typedef _Tp type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
+#endif
+
+// remove_cv
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_cv
+{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
+#endif
+
+// is_void
+
+template <class _Tp> struct __libcpp_is_void       : public false_type {};
+template <>          struct __libcpp_is_void<void> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
+    : public __libcpp_is_void<typename remove_cv<_Tp>::type> {};
+
+// __is_nullptr_t
+
+template <class _Tp> struct __is_nullptr_t_impl       : public false_type {};
+template <>          struct __is_nullptr_t_impl<nullptr_t> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __is_nullptr_t
+    : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer
+    : public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {};
+#endif
+
+// is_integral
+
+template <class _Tp> struct __libcpp_is_integral                     : public false_type {};
+template <>          struct __libcpp_is_integral<bool>               : public true_type {};
+template <>          struct __libcpp_is_integral<char>               : public true_type {};
+template <>          struct __libcpp_is_integral<signed char>        : public true_type {};
+template <>          struct __libcpp_is_integral<unsigned char>      : public true_type {};
+template <>          struct __libcpp_is_integral<wchar_t>            : public true_type {};
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+template <>          struct __libcpp_is_integral<char16_t>           : public true_type {};
+template <>          struct __libcpp_is_integral<char32_t>           : public true_type {};
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+template <>          struct __libcpp_is_integral<short>              : public true_type {};
+template <>          struct __libcpp_is_integral<unsigned short>     : public true_type {};
+template <>          struct __libcpp_is_integral<int>                : public true_type {};
+template <>          struct __libcpp_is_integral<unsigned int>       : public true_type {};
+template <>          struct __libcpp_is_integral<long>               : public true_type {};
+template <>          struct __libcpp_is_integral<unsigned long>      : public true_type {};
+template <>          struct __libcpp_is_integral<long long>          : public true_type {};
+template <>          struct __libcpp_is_integral<unsigned long long> : public true_type {};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <>          struct __libcpp_is_integral<__int128_t>         : public true_type {};
+template <>          struct __libcpp_is_integral<__uint128_t>        : public true_type {};
+#endif
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_integral
+    : public __libcpp_is_integral<typename remove_cv<_Tp>::type> {};
+
+// is_floating_point
+
+template <class _Tp> struct __libcpp_is_floating_point              : public false_type {};
+template <>          struct __libcpp_is_floating_point<float>       : public true_type {};
+template <>          struct __libcpp_is_floating_point<double>      : public true_type {};
+template <>          struct __libcpp_is_floating_point<long double> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_floating_point
+    : public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {};
+
+// is_array
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array
+    : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[]>
+    : public true_type {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[_Np]>
+    : public true_type {};
+
+// is_pointer
+
+template <class _Tp> struct __libcpp_is_pointer       : public false_type {};
+template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pointer
+    : public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {};
+
+// is_reference
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference       : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference<_Tp&> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference        : public false_type {};
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference<_Tp&&> : public true_type {};
+#endif
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference        : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&>  : public true_type {};
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&&> : public true_type {};
+#endif
+
+// is_union
+
+#if __has_feature(is_union) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union
+    : public integral_constant<bool, __is_union(_Tp)> {};
+
+#else
+
+template <class _Tp> struct __libcpp_union : public false_type {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union
+    : public __libcpp_union<typename remove_cv<_Tp>::type> {};
+
+#endif
+
+// is_class
+
+#if __has_feature(is_class) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class
+    : public integral_constant<bool, __is_class(_Tp)> {};
+
+#else
+
+namespace __is_class_imp
+{
+template <class _Tp> char  __test(int _Tp::*);
+template <class _Tp> __two __test(...);
+}
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class
+    : public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {};
+
+#endif
+
+// is_same
+
+template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY is_same           : public false_type {};
+template <class _Tp>            struct _LIBCPP_TYPE_VIS_ONLY is_same<_Tp, _Tp> : public true_type {};
+
+// is_function
+
+namespace __libcpp_is_function_imp
+{
+template <class _Tp> char  __test(_Tp*);
+template <class _Tp> __two __test(...);
+template <class _Tp> _Tp&  __source();
+}
+
+template <class _Tp, bool = is_class<_Tp>::value ||
+                            is_union<_Tp>::value ||
+                            is_void<_Tp>::value  ||
+                            is_reference<_Tp>::value ||
+                            __is_nullptr_t<_Tp>::value >
+struct __libcpp_is_function
+    : public integral_constant<bool, sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>())) == 1>
+    {};
+template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_function
+    : public __libcpp_is_function<_Tp> {};
+
+// is_member_function_pointer
+
+// template <class _Tp> struct            __libcpp_is_member_function_pointer             : public false_type {};
+// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {};
+// 
+
+template <class _MP, bool _IsMemberFuctionPtr, bool _IsMemberObjectPtr>
+struct __member_pointer_traits_imp
+{  // forward declaration; specializations later
+};
+
+
+namespace __libcpp_is_member_function_pointer_imp {
+    template <typename _Tp>
+    char __test(typename std::__member_pointer_traits_imp<_Tp, true, false>::_FnType *);
+
+    template <typename>
+    std::__two __test(...);
+};
+    
+template <class _Tp> struct __libcpp_is_member_function_pointer
+    : public integral_constant<bool, sizeof(__libcpp_is_member_function_pointer_imp::__test<_Tp>(nullptr)) == 1> {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_function_pointer
+    : public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type> {};
+
+// is_member_pointer
+
+template <class _Tp>            struct __libcpp_is_member_pointer             : public false_type {};
+template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_pointer
+    : public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {};
+
+// is_member_object_pointer
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_object_pointer
+    : public integral_constant<bool, is_member_pointer<_Tp>::value &&
+                                    !is_member_function_pointer<_Tp>::value> {};
+
+// is_enum
+
+#if __has_feature(is_enum) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum
+    : public integral_constant<bool, __is_enum(_Tp)> {};
+
+#else
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum
+    : public integral_constant<bool, !is_void<_Tp>::value             &&
+                                     !is_integral<_Tp>::value         &&
+                                     !is_floating_point<_Tp>::value   &&
+                                     !is_array<_Tp>::value            &&
+                                     !is_pointer<_Tp>::value          &&
+                                     !is_reference<_Tp>::value        &&
+                                     !is_member_pointer<_Tp>::value   &&
+                                     !is_union<_Tp>::value            &&
+                                     !is_class<_Tp>::value            &&
+                                     !is_function<_Tp>::value         > {};
+
+#endif
+
+// is_arithmetic
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_arithmetic
+    : public integral_constant<bool, is_integral<_Tp>::value      ||
+                                     is_floating_point<_Tp>::value> {};
+
+// is_fundamental
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_fundamental
+    : public integral_constant<bool, is_void<_Tp>::value        ||
+                                     __is_nullptr_t<_Tp>::value ||
+                                     is_arithmetic<_Tp>::value> {};
+
+// is_scalar
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_scalar
+    : public integral_constant<bool, is_arithmetic<_Tp>::value     ||
+                                     is_member_pointer<_Tp>::value ||
+                                     is_pointer<_Tp>::value        ||
+                                     __is_nullptr_t<_Tp>::value    ||
+                                     is_enum<_Tp>::value           > {};
+
+template <> struct _LIBCPP_TYPE_VIS_ONLY is_scalar<nullptr_t> : public true_type {};
+
+// is_object
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_object
+    : public integral_constant<bool, is_scalar<_Tp>::value ||
+                                     is_array<_Tp>::value  ||
+                                     is_union<_Tp>::value  ||
+                                     is_class<_Tp>::value  > {};
+
+// is_compound
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_compound
+    : public integral_constant<bool, !is_fundamental<_Tp>::value> {};
+
+// add_const
+
+template <class _Tp, bool = is_reference<_Tp>::value ||
+                            is_function<_Tp>::value  ||
+                            is_const<_Tp>::value     >
+struct __add_const             {typedef _Tp type;};
+
+template <class _Tp>
+struct __add_const<_Tp, false> {typedef const _Tp type;};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_const
+    {typedef typename __add_const<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
+#endif
+
+// add_volatile
+
+template <class _Tp, bool = is_reference<_Tp>::value ||
+                            is_function<_Tp>::value  ||
+                            is_volatile<_Tp>::value  >
+struct __add_volatile             {typedef _Tp type;};
+
+template <class _Tp>
+struct __add_volatile<_Tp, false> {typedef volatile _Tp type;};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_volatile
+    {typedef typename __add_volatile<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
+#endif
+
+// add_cv
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_cv
+    {typedef typename add_const<typename add_volatile<_Tp>::type>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
+#endif
+
+// remove_reference
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference        {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&>  {typedef _Tp type;};
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&&> {typedef _Tp type;};
+#endif
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
+#endif
+
+// add_lvalue_reference
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference                      {typedef _Tp& type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&>                {typedef _Tp& type;};  // for older compiler
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void>                {typedef void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void>          {typedef const void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void>       {typedef volatile void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY  add_rvalue_reference                     {typedef _Tp&& type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void>                {typedef void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void>          {typedef const void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void>       {typedef volatile void type;};
+template <>          struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type;
+#endif
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+typename add_rvalue_reference<_Tp>::type
+declval() _NOEXCEPT;
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+typename add_lvalue_reference<_Tp>::type
+declval();
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+struct __any
+{
+    __any(...);
+};
+
+// remove_pointer
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer                      {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp*>                {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const>          {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* volatile>       {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const volatile> {typedef _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type;
+#endif
+
+// add_pointer
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer
+    {typedef typename remove_reference<_Tp>::type* type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type;
+#endif
+
+// is_signed
+
+template <class _Tp, bool = is_integral<_Tp>::value>
+struct __libcpp_is_signed_impl : public integral_constant<bool, _Tp(-1) < _Tp(0)> {};
+
+template <class _Tp>
+struct __libcpp_is_signed_impl<_Tp, false> : public true_type {};  // floating point
+
+template <class _Tp, bool = is_arithmetic<_Tp>::value>
+struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {};
+
+template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_signed : public __libcpp_is_signed<_Tp> {};
+
+// is_unsigned
+
+template <class _Tp, bool = is_integral<_Tp>::value>
+struct __libcpp_is_unsigned_impl : public integral_constant<bool, _Tp(0) < _Tp(-1)> {};
+
+template <class _Tp>
+struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {};  // floating point
+
+template <class _Tp, bool = is_arithmetic<_Tp>::value>
+struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
+
+template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __libcpp_is_unsigned<_Tp> {};
+
+// rank
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank
+    : public integral_constant<size_t, 0> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[]>
+    : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[_Np]>
+    : public integral_constant<size_t, rank<_Tp>::value + 1> {};
+
+// extent
+
+template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS_ONLY extent
+    : public integral_constant<size_t, 0> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], 0>
+    : public integral_constant<size_t, 0> {};
+template <class _Tp, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], _Ip>
+    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], 0>
+    : public integral_constant<size_t, _Np> {};
+template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], _Ip>
+    : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {};
+
+// remove_extent
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent
+    {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[]>
+    {typedef _Tp type;};
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[_Np]>
+    {typedef _Tp type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type;
+#endif
+
+// remove_all_extents
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents
+    {typedef _Tp type;};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[]>
+    {typedef typename remove_all_extents<_Tp>::type type;};
+template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[_Np]>
+    {typedef typename remove_all_extents<_Tp>::type type;};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type;
+#endif
+
+// decay
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY decay
+{
+private:
+    typedef typename remove_reference<_Tp>::type _Up;
+public:
+    typedef typename conditional
+                     <
+                         is_array<_Up>::value,
+                         typename remove_extent<_Up>::type*,
+                         typename conditional
+                         <
+                              is_function<_Up>::value,
+                              typename add_pointer<_Up>::type,
+                              typename remove_cv<_Up>::type
+                         >::type
+                     >::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using decay_t = typename decay<_Tp>::type;
+#endif
+
+// is_abstract
+
+namespace __is_abstract_imp
+{
+template <class _Tp> char  __test(_Tp (*)[1]);
+template <class _Tp> __two __test(...);
+}
+
+template <class _Tp, bool = is_class<_Tp>::value>
+struct __libcpp_abstract : public integral_constant<bool, sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1> {};
+
+template <class _Tp> struct __libcpp_abstract<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_abstract<_Tp> {};
+
+// is_final
+
+#if _LIBCPP_STD_VER > 11 && __has_feature(is_final)
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY 
+is_final : public integral_constant<bool, __is_final(_Tp)> {};
+#endif
+
+// is_base_of
+
+#ifdef _LIBCPP_HAS_IS_BASE_OF
+
+template <class _Bp, class _Dp>
+struct _LIBCPP_TYPE_VIS_ONLY is_base_of
+    : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {};
+
+#else  // _LIBCPP_HAS_IS_BASE_OF
+
+namespace __is_base_of_imp
+{
+template <class _Tp>
+struct _Dst
+{
+    _Dst(const volatile _Tp &);
+};
+template <class _Tp>
+struct _Src
+{
+    operator const volatile _Tp &();
+    template <class _Up> operator const _Dst<_Up> &();
+};
+template <size_t> struct __one { typedef char type; };
+template <class _Bp, class _Dp> typename __one<sizeof(_Dst<_Bp>(declval<_Src<_Dp> >()))>::type __test(int);
+template <class _Bp, class _Dp> __two __test(...);
+}
+
+template <class _Bp, class _Dp>
+struct _LIBCPP_TYPE_VIS_ONLY is_base_of
+    : public integral_constant<bool, is_class<_Bp>::value &&
+                                     sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {};
+
+#endif  // _LIBCPP_HAS_IS_BASE_OF
+
+// is_convertible
+
+#if __has_feature(is_convertible_to)
+
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible
+    : public integral_constant<bool, __is_convertible_to(_T1, _T2) &&
+                                     !is_abstract<_T2>::value> {};
+
+#else  // __has_feature(is_convertible_to)
+
+namespace __is_convertible_imp
+{
+template <class _Tp> char  __test(_Tp);
+template <class _Tp> __two __test(...);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp> _Tp&& __source();
+#else
+template <class _Tp> typename remove_reference<_Tp>::type& __source();
+#endif
+
+template <class _Tp, bool _IsArray =    is_array<_Tp>::value,
+                     bool _IsFunction = is_function<_Tp>::value,
+                     bool _IsVoid =     is_void<_Tp>::value>
+                     struct __is_array_function_or_void                          {enum {value = 0};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};};
+template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};};
+}
+
+template <class _Tp,
+    unsigned = __is_convertible_imp::__is_array_function_or_void<typename remove_reference<_Tp>::type>::value>
+struct __is_convertible_check
+{
+    static const size_t __v = 0;
+};
+
+template <class _Tp>
+struct __is_convertible_check<_Tp, 0>
+{
+    static const size_t __v = sizeof(_Tp);
+};
+
+template <class _T1, class _T2,
+    unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value,
+    unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
+struct __is_convertible
+    : public integral_constant<bool,
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
+#else
+        sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
+         && !(!is_function<_T1>::value && !is_reference<_T1>::value && is_reference<_T2>::value
+              && (!is_const<typename remove_reference<_T2>::type>::value
+                  || is_volatile<typename remove_reference<_T2>::type>::value)
+                  && (is_same<typename remove_cv<_T1>::type,
+                              typename remove_cv<typename remove_reference<_T2>::type>::type>::value
+                      || is_base_of<typename remove_reference<_T2>::type, _T1>::value))
+#endif
+    >
+{};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {};
+
+template <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {};
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {};
+template <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {};
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2*, 1, 0>
+    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*>::value> {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const, 1, 0>
+    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const>::value> {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2* volatile, 1, 0>
+    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*volatile>::value> {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const volatile, 1, 0>
+    : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const volatile>::value> {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 0>                : public false_type {};
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _T1>            struct __is_convertible<_T1, _T1&&, 2, 0>               : public true_type {};
+#endif
+template <class _T1>            struct __is_convertible<_T1, _T1&, 2, 0>               : public true_type {};
+template <class _T1>            struct __is_convertible<_T1, _T1*, 2, 0>               : public true_type {};
+template <class _T1>            struct __is_convertible<_T1, _T1*const, 2, 0>          : public true_type {};
+template <class _T1>            struct __is_convertible<_T1, _T1*volatile, 2, 0>       : public true_type {};
+template <class _T1>            struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 0> : public false_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {};
+
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {};
+template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {};
+
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible
+    : public __is_convertible<_T1, _T2>
+{
+    static const size_t __complete_check1 = __is_convertible_check<_T1>::__v;
+    static const size_t __complete_check2 = __is_convertible_check<_T2>::__v;
+};
+
+#endif  // __has_feature(is_convertible_to)
+
+// is_empty
+
+#if __has_feature(is_empty) || (_GNUC_VER >= 407)
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_empty
+    : public integral_constant<bool, __is_empty(_Tp)> {};
+
+#else  // __has_feature(is_empty)
+
+template <class _Tp>
+struct __is_empty1
+    : public _Tp
+{
+    double __lx;
+};
+
+struct __is_empty2
+{
+    double __lx;
+};
+
+template <class _Tp, bool = is_class<_Tp>::value>
+struct __libcpp_empty : public integral_constant<bool, sizeof(__is_empty1<_Tp>) == sizeof(__is_empty2)> {};
+
+template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_empty : public __libcpp_empty<_Tp> {};
+
+#endif  // __has_feature(is_empty)
+
+// is_polymorphic
+
+#if __has_feature(is_polymorphic) || defined(_LIBCPP_MSVC)
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic
+    : public integral_constant<bool, __is_polymorphic(_Tp)> {};
+
+#else
+
+template<typename _Tp> char &__is_polymorphic_impl(
+    typename enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0,
+                       int>::type);
+template<typename _Tp> __two &__is_polymorphic_impl(...);
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic
+    : public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {};
+
+#endif // __has_feature(is_polymorphic)
+
+// has_virtual_destructor
+
+#if __has_feature(has_virtual_destructor) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor
+    : public integral_constant<bool, __has_virtual_destructor(_Tp)> {};
+
+#else
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor
+    : public false_type {};
+
+#endif
+
+// alignment_of
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY alignment_of
+    : public integral_constant<size_t, __alignof__(_Tp)> {};
+
+// aligned_storage
+
+template <class _Hp, class _Tp>
+struct __type_list
+{
+    typedef _Hp _Head;
+    typedef _Tp _Tail;
+};
+
+struct __nat
+{
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+    __nat() = delete;
+    __nat(const __nat&) = delete;
+    __nat& operator=(const __nat&) = delete;
+    ~__nat() = delete;
+#endif
+};
+
+template <class _Tp>
+struct __align_type
+{
+    static const size_t value = alignment_of<_Tp>::value;
+    typedef _Tp type;
+};
+
+struct __struct_double {long double __lx;};
+struct __struct_double4 {double __lx[4];};
+
+typedef
+    __type_list<__align_type<unsigned char>,
+    __type_list<__align_type<unsigned short>,
+    __type_list<__align_type<unsigned int>,
+    __type_list<__align_type<unsigned long>,
+    __type_list<__align_type<unsigned long long>,
+    __type_list<__align_type<double>,
+    __type_list<__align_type<long double>,
+    __type_list<__align_type<__struct_double>,
+    __type_list<__align_type<__struct_double4>,
+    __type_list<__align_type<int*>,
+    __nat
+    > > > > > > > > > > __all_types;
+
+template <class _TL, size_t _Align> struct __find_pod;
+
+template <class _Hp, size_t _Align>
+struct __find_pod<__type_list<_Hp, __nat>, _Align>
+{
+    typedef typename conditional<
+                             _Align == _Hp::value,
+                             typename _Hp::type,
+                             void
+                         >::type type;
+};
+
+template <class _Hp, class _Tp, size_t _Align>
+struct __find_pod<__type_list<_Hp, _Tp>, _Align>
+{
+    typedef typename conditional<
+                             _Align == _Hp::value,
+                             typename _Hp::type,
+                             typename __find_pod<_Tp, _Align>::type
+                         >::type type;
+};
+
+template <class _TL, size_t _Len> struct __find_max_align;
+
+template <class _Hp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {};
+
+template <size_t _Len, size_t _A1, size_t _A2>
+struct __select_align
+{
+private:
+    static const size_t __min = _A2 < _A1 ? _A2 : _A1;
+    static const size_t __max = _A1 < _A2 ? _A2 : _A1;
+public:
+    static const size_t value = _Len < __max ? __min : __max;
+};
+
+template <class _Hp, class _Tp, size_t _Len>
+struct __find_max_align<__type_list<_Hp, _Tp>, _Len>
+    : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {};
+
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+struct _LIBCPP_TYPE_VIS_ONLY aligned_storage
+{
+    typedef typename __find_pod<__all_types, _Align>::type _Aligner;
+    static_assert(!is_void<_Aligner>::value, "");
+    union type
+    {
+        _Aligner __align;
+        unsigned char __data[_Len];
+    };
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value>
+    using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;
+#endif
+
+#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \
+template <size_t _Len>\
+struct _LIBCPP_TYPE_VIS_ONLY aligned_storage<_Len, n>\
+{\
+    struct _ALIGNAS(n) type\
+    {\
+        unsigned char __lx[_Len];\
+    };\
+}
+
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000);
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000);
+// MSDN says that MSVC does not support alignment beyond 8192 (=0x2000)
+#if !defined(_LIBCPP_MSVC)
+_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000);
+#endif // !_LIBCPP_MSVC
+
+#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// aligned_union
+
+template <size_t _I0, size_t ..._In>
+struct __static_max;
+
+template <size_t _I0>
+struct __static_max<_I0>
+{
+    static const size_t value = _I0;
+};
+
+template <size_t _I0, size_t _I1, size_t ..._In>
+struct __static_max<_I0, _I1, _In...>
+{
+    static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value :
+                                             __static_max<_I1, _In...>::value;
+};
+
+template <size_t _Len, class _Type0, class ..._Types>
+struct aligned_union
+{
+    static const size_t alignment_value = __static_max<__alignof__(_Type0),
+                                                       __alignof__(_Types)...>::value;
+    static const size_t __len = __static_max<_Len, sizeof(_Type0),
+                                             sizeof(_Types)...>::value;
+    typedef typename aligned_storage<__len, alignment_value>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type;
+#endif
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp>
+struct __numeric_type
+{
+   static void __test(...);
+   static float __test(float);
+   static double __test(char);
+   static double __test(int);
+   static double __test(unsigned);
+   static double __test(long);
+   static double __test(unsigned long);
+   static double __test(long long);
+   static double __test(unsigned long long);
+   static double __test(double);
+   static long double __test(long double);
+
+   typedef decltype(__test(declval<_Tp>())) type;
+   static const bool value = !is_same<type, void>::value;
+};
+
+template <>
+struct __numeric_type<void>
+{
+   static const bool value = true;
+};
+
+// __promote
+
+template <class _A1, class _A2 = void, class _A3 = void,
+          bool = __numeric_type<_A1>::value &&
+                 __numeric_type<_A2>::value &&
+                 __numeric_type<_A3>::value>
+class __promote
+{
+    static const bool value = false;
+};
+
+template <class _A1, class _A2, class _A3>
+class __promote<_A1, _A2, _A3, true>
+{
+private:
+    typedef typename __promote<_A1>::type __type1;
+    typedef typename __promote<_A2>::type __type2;
+    typedef typename __promote<_A3>::type __type3;
+public:
+    typedef decltype(__type1() + __type2() + __type3()) type;
+    static const bool value = true;
+};
+
+template <class _A1, class _A2>
+class __promote<_A1, _A2, void, true>
+{
+private:
+    typedef typename __promote<_A1>::type __type1;
+    typedef typename __promote<_A2>::type __type2;
+public:
+    typedef decltype(__type1() + __type2()) type;
+    static const bool value = true;
+};
+
+template <class _A1>
+class __promote<_A1, void, void, true>
+{
+public:
+    typedef typename __numeric_type<_A1>::type type;
+    static const bool value = true;
+    static const bool __does_not_throw = _NOEXCEPT_OR_FALSE(static_cast<type>(declval<_A1>()));
+};
+
+#ifdef _LIBCPP_STORE_AS_OPTIMIZATION
+
+// __transform
+
+template <class _Tp, size_t = sizeof(_Tp), bool = is_scalar<_Tp>::value> struct __transform {typedef _Tp type;};
+template <class _Tp> struct __transform<_Tp, 1, true> {typedef unsigned char      type;};
+template <class _Tp> struct __transform<_Tp, 2, true> {typedef unsigned short     type;};
+template <class _Tp> struct __transform<_Tp, 4, true> {typedef unsigned int       type;};
+template <class _Tp> struct __transform<_Tp, 8, true> {typedef unsigned long long type;};
+
+#endif  // _LIBCPP_STORE_AS_OPTIMIZATION
+
+// make_signed / make_unsigned
+
+typedef
+    __type_list<signed char,
+    __type_list<signed short,
+    __type_list<signed int,
+    __type_list<signed long,
+    __type_list<signed long long,
+#ifndef _LIBCPP_HAS_NO_INT128
+    __type_list<__int128_t,
+#endif
+    __nat
+#ifndef _LIBCPP_HAS_NO_INT128
+    >
+#endif
+    > > > > > __signed_types;
+
+typedef
+    __type_list<unsigned char,
+    __type_list<unsigned short,
+    __type_list<unsigned int,
+    __type_list<unsigned long,
+    __type_list<unsigned long long,
+#ifndef _LIBCPP_HAS_NO_INT128
+    __type_list<__uint128_t,
+#endif
+    __nat
+#ifndef _LIBCPP_HAS_NO_INT128
+    >
+#endif
+    > > > > > __unsigned_types;
+
+template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first;
+
+template <class _Hp, class _Tp, size_t _Size>
+struct __find_first<__type_list<_Hp, _Tp>, _Size, true>
+{
+    typedef _Hp type;
+};
+
+template <class _Hp, class _Tp, size_t _Size>
+struct __find_first<__type_list<_Hp, _Tp>, _Size, false>
+{
+    typedef typename __find_first<_Tp, _Size>::type type;
+};
+
+template <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value,
+                             bool = is_volatile<typename remove_reference<_Tp>::type>::value>
+struct __apply_cv
+{
+    typedef _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, true, false>
+{
+    typedef const _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, false, true>
+{
+    typedef volatile _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp, _Up, true, true>
+{
+    typedef const volatile _Up type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, false, false>
+{
+    typedef _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, true, false>
+{
+    typedef const _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, false, true>
+{
+    typedef volatile _Up& type;
+};
+
+template <class _Tp, class _Up>
+struct __apply_cv<_Tp&, _Up, true, true>
+{
+    typedef const volatile _Up& type;
+};
+
+template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+struct __make_signed {};
+
+template <class _Tp>
+struct __make_signed<_Tp, true>
+{
+    typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
+};
+
+template <> struct __make_signed<bool,               true> {};
+template <> struct __make_signed<  signed short,     true> {typedef short     type;};
+template <> struct __make_signed<unsigned short,     true> {typedef short     type;};
+template <> struct __make_signed<  signed int,       true> {typedef int       type;};
+template <> struct __make_signed<unsigned int,       true> {typedef int       type;};
+template <> struct __make_signed<  signed long,      true> {typedef long      type;};
+template <> struct __make_signed<unsigned long,      true> {typedef long      type;};
+template <> struct __make_signed<  signed long long, true> {typedef long long type;};
+template <> struct __make_signed<unsigned long long, true> {typedef long long type;};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __make_signed<__int128_t,         true> {typedef __int128_t type;};
+template <> struct __make_signed<__uint128_t,        true> {typedef __int128_t type;};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY make_signed
+{
+    typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_signed_t = typename make_signed<_Tp>::type;
+#endif
+
+template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
+struct __make_unsigned {};
+
+template <class _Tp>
+struct __make_unsigned<_Tp, true>
+{
+    typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
+};
+
+template <> struct __make_unsigned<bool,               true> {};
+template <> struct __make_unsigned<  signed short,     true> {typedef unsigned short     type;};
+template <> struct __make_unsigned<unsigned short,     true> {typedef unsigned short     type;};
+template <> struct __make_unsigned<  signed int,       true> {typedef unsigned int       type;};
+template <> struct __make_unsigned<unsigned int,       true> {typedef unsigned int       type;};
+template <> struct __make_unsigned<  signed long,      true> {typedef unsigned long      type;};
+template <> struct __make_unsigned<unsigned long,      true> {typedef unsigned long      type;};
+template <> struct __make_unsigned<  signed long long, true> {typedef unsigned long long type;};
+template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
+#ifndef _LIBCPP_HAS_NO_INT128
+template <> struct __make_unsigned<__int128_t,         true> {typedef __uint128_t        type;};
+template <> struct __make_unsigned<__uint128_t,        true> {typedef __uint128_t        type;};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY make_unsigned
+{
+    typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
+#endif
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Up = void, class V = void>
+struct _LIBCPP_TYPE_VIS_ONLY common_type
+{
+public:
+    typedef typename common_type<typename common_type<_Tp, _Up>::type, V>::type type;
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, void, void>
+{
+public:
+    typedef typename decay<_Tp>::type type;
+};
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, void>
+{
+private:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    static _Tp&& __t();
+    static _Up&& __u();
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    static _Tp __t();
+    static _Up __u();
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+public:
+    typedef typename remove_reference<decltype(true ? __t() : __u())>::type type;
+};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class ..._Tp> struct common_type;
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp>
+{
+    typedef typename decay<_Tp>::type type;
+};
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up>
+{
+private:
+    static _Tp&& __t();
+    static _Up&& __u();
+    static bool __f();
+public:
+    typedef typename decay<decltype(__f() ? __t() : __u())>::type type;
+};
+
+template <class _Tp, class _Up, class ..._Vp>
+struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...>
+{
+    typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type;
+#endif
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+// is_assignable
+
+template<typename, typename _Tp> struct __select_2nd { typedef _Tp type; };
+
+template <class _Tp, class _Arg>
+typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__is_assignable_test(_Tp&&, _Arg&&);
+#else
+__is_assignable_test(_Tp, _Arg&);
+#endif
+
+template <class _Arg>
+false_type
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+__is_assignable_test(__any, _Arg&&);
+#else
+__is_assignable_test(__any, _Arg&);
+#endif
+
+template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value>
+struct __is_assignable_imp
+    : public common_type
+        <
+            decltype(__is_assignable_test(declval<_Tp>(), declval<_Arg>()))
+        >::type {};
+
+template <class _Tp, class _Arg>
+struct __is_assignable_imp<_Tp, _Arg, true>
+    : public false_type
+{
+};
+
+template <class _Tp, class _Arg>
+struct is_assignable
+    : public __is_assignable_imp<_Tp, _Arg> {};
+
+// is_copy_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_copy_assignable
+    : public is_assignable<typename add_lvalue_reference<_Tp>::type,
+                     const typename add_lvalue_reference<_Tp>::type> {};
+
+// is_move_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    : public is_assignable<typename add_lvalue_reference<_Tp>::type,
+                     const typename add_rvalue_reference<_Tp>::type> {};
+#else
+    : public is_copy_assignable<_Tp> {};
+#endif
+
+// is_destructible
+
+//	if it's a reference, return true
+//	if it's a function, return false
+//	if it's   void,     return false
+//	if it's an array of unknown bound, return false
+//	Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed
+//    where _Up is remove_all_extents<_Tp>::type
+
+template <class>
+struct __is_destructible_apply { typedef int type; };
+
+template <typename _Tp>
+struct __is_destructor_wellformed {
+	template <typename _Tp1>
+	static char  __test (
+        typename __is_destructible_apply<decltype(_VSTD::declval<_Tp1&>().~_Tp1())>::type
+    );
+
+	template <typename _Tp1>
+	static __two __test (...);
+	
+	static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char);
+};
+
+template <class _Tp, bool>
+struct __destructible_imp;
+
+template <class _Tp>
+struct __destructible_imp<_Tp, false> 
+   : public _VSTD::integral_constant<bool, 
+        __is_destructor_wellformed<typename _VSTD::remove_all_extents<_Tp>::type>::value> {};
+
+template <class _Tp>
+struct __destructible_imp<_Tp, true>
+    : public _VSTD::true_type {};
+
+template <class _Tp, bool>
+struct __destructible_false;
+
+template <class _Tp>
+struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, _VSTD::is_reference<_Tp>::value> {};
+
+template <class _Tp>
+struct __destructible_false<_Tp, true> : public _VSTD::false_type {};
+
+template <class _Tp>
+struct is_destructible
+    : public __destructible_false<_Tp, _VSTD::is_function<_Tp>::value> {};
+
+template <class _Tp>
+struct is_destructible<_Tp[]>
+    : public _VSTD::false_type {};
+
+template <>
+struct is_destructible<void>
+    : public _VSTD::false_type {};
+
+// move
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename remove_reference<_Tp>::type&&
+move(_Tp&& __t) _NOEXCEPT
+{
+    typedef typename remove_reference<_Tp>::type _Up;
+    return static_cast<_Up&&>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&&
+forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
+{
+    return static_cast<_Tp&&>(__t);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+_Tp&&
+forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT
+{
+    static_assert(!std::is_lvalue_reference<_Tp>::value,
+                  "Can not forward an rvalue as an lvalue.");
+    return static_cast<_Tp&&>(__t);
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp&
+move(_Tp& __t)
+{
+    return __t;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const _Tp&
+move(const _Tp& __t)
+{
+    return __t;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp&
+forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
+{
+    return __t;
+}
+
+
+template <class _Tp>
+class __rv
+{
+    typedef typename remove_reference<_Tp>::type _Trr;
+    _Trr& t_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    _Trr* operator->() {return &t_;}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __rv(_Trr& __t) : t_(__t) {}
+};
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename decay<_Tp>::type
+__decay_copy(_Tp&& __t)
+{
+    return _VSTD::forward<_Tp>(__t);
+}
+
+#else
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename decay<_Tp>::type
+__decay_copy(const _Tp& __t)
+{
+    return _VSTD::forward<_Tp>(__t);
+}
+
+#endif
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
+{
+    typedef _Class const _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
+{
+    typedef _Class volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
+{
+    typedef _Class const volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+#if __has_feature(cxx_reference_qualified_functions)
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
+{
+    typedef _Class& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
+{
+    typedef _Class const& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
+{
+    typedef _Class volatile& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
+{
+    typedef _Class const volatile& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
+{
+    typedef _Class&& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
+{
+    typedef _Class const&& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
+{
+    typedef _Class volatile&& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
+{
+    typedef _Class const volatile&& _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_Param...);
+};
+
+#endif  // __has_feature(cxx_reference_qualified_functions)
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(), true, false>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) ();
+};
+
+template <class _Rp, class _Class, class _P0>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0), true, false>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1), true, false>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2), true, false>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1, _P2);
+};
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp (_Class::*)() const, true, false>
+{
+    typedef _Class const _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) ();
+};
+
+template <class _Rp, class _Class, class _P0>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const, true, false>
+{
+    typedef _Class const _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const, true, false>
+{
+    typedef _Class const _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const, true, false>
+{
+    typedef _Class const _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1, _P2);
+};
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp (_Class::*)() volatile, true, false>
+{
+    typedef _Class volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) ();
+};
+
+template <class _Rp, class _Class, class _P0>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) volatile, true, false>
+{
+    typedef _Class volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) volatile, true, false>
+{
+    typedef _Class volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) volatile, true, false>
+{
+    typedef _Class volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1, _P2);
+};
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp (_Class::*)() const volatile, true, false>
+{
+    typedef _Class const volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) ();
+};
+
+template <class _Rp, class _Class, class _P0>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const volatile, true, false>
+{
+    typedef _Class const volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const volatile, true, false>
+{
+    typedef _Class const volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1);
+};
+
+template <class _Rp, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const volatile, true, false>
+{
+    typedef _Class const volatile _ClassType;
+    typedef _Rp _ReturnType;
+    typedef _Rp (_FnType) (_P0, _P1, _P2);
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Rp, class _Class>
+struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
+{
+    typedef _Class _ClassType;
+    typedef _Rp _ReturnType;
+};
+
+template <class _MP>
+struct __member_pointer_traits
+    : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
+                    is_member_function_pointer<_MP>::value,
+                    is_member_object_pointer<_MP>::value>
+{
+//     typedef ... _ClassType;
+//     typedef ... _ReturnType;
+//     typedef ... _FnType;
+};
+
+// result_of
+
+template <class _Callable> class result_of;
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Fn, bool, bool>
+class __result_of
+{
+};
+
+template <class _Fn>
+class __result_of<_Fn(), true, false>
+{
+public:
+    typedef decltype(declval<_Fn>()()) type;
+};
+
+template <class _Fn, class _A0>
+class __result_of<_Fn(_A0), true, false>
+{
+public:
+    typedef decltype(declval<_Fn>()(declval<_A0>())) type;
+};
+
+template <class _Fn, class _A0, class _A1>
+class __result_of<_Fn(_A0, _A1), true, false>
+{
+public:
+    typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>())) type;
+};
+
+template <class _Fn, class _A0, class _A1, class _A2>
+class __result_of<_Fn(_A0, _A1, _A2), true, false>
+{
+public:
+    typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>(), declval<_A2>())) type;
+};
+
+template <class _MP, class _Tp, bool _IsMemberFunctionPtr>
+struct __result_of_mp;
+
+// member function pointer
+
+template <class _MP, class _Tp>
+struct __result_of_mp<_MP, _Tp, true>
+    : public common_type<typename __member_pointer_traits<_MP>::_ReturnType>
+{
+};
+
+// member data pointer
+
+template <class _MP, class _Tp, bool>
+struct __result_of_mdp;
+
+template <class _Rp, class _Class, class _Tp>
+struct __result_of_mdp<_Rp _Class::*, _Tp, false>
+{
+    typedef typename __apply_cv<decltype(*_VSTD::declval<_Tp>()), _Rp>::type& type;
+};
+
+template <class _Rp, class _Class, class _Tp>
+struct __result_of_mdp<_Rp _Class::*, _Tp, true>
+{
+    typedef typename __apply_cv<_Tp, _Rp>::type& type;
+};
+
+template <class _Rp, class _Class, class _Tp>
+struct __result_of_mp<_Rp _Class::*, _Tp, false>
+    : public __result_of_mdp<_Rp _Class::*, _Tp,
+            is_base_of<_Class, typename remove_reference<_Tp>::type>::value>
+{
+};
+
+
+
+template <class _Fn, class _Tp>
+class __result_of<_Fn(_Tp), false, true>  // _Fn must be member pointer
+    : public __result_of_mp<typename remove_reference<_Fn>::type,
+                            _Tp,
+                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0>
+class __result_of<_Fn(_Tp, _A0), false, true>  // _Fn must be member pointer
+    : public __result_of_mp<typename remove_reference<_Fn>::type,
+                            _Tp,
+                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0, class _A1>
+class __result_of<_Fn(_Tp, _A0, _A1), false, true>  // _Fn must be member pointer
+    : public __result_of_mp<typename remove_reference<_Fn>::type,
+                            _Tp,
+                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0, class _A1, class _A2>
+class __result_of<_Fn(_Tp, _A0, _A1, _A2), false, true>  // _Fn must be member pointer
+    : public __result_of_mp<typename remove_reference<_Fn>::type,
+                            _Tp,
+                            is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+// result_of
+
+template <class _Fn>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()>
+    : public __result_of<_Fn(),
+                         is_class<typename remove_reference<_Fn>::type>::value ||
+                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_member_pointer<typename remove_reference<_Fn>::type>::value
+                        >
+{
+};
+
+template <class _Fn, class _A0>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)>
+    : public __result_of<_Fn(_A0),
+                         is_class<typename remove_reference<_Fn>::type>::value ||
+                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_member_pointer<typename remove_reference<_Fn>::type>::value
+                        >
+{
+};
+
+template <class _Fn, class _A0, class _A1>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)>
+    : public __result_of<_Fn(_A0, _A1),
+                         is_class<typename remove_reference<_Fn>::type>::value ||
+                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_member_pointer<typename remove_reference<_Fn>::type>::value
+                        >
+{
+};
+
+template <class _Fn, class _A0, class _A1, class _A2>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)>
+    : public __result_of<_Fn(_A0, _A1, _A2),
+                         is_class<typename remove_reference<_Fn>::type>::value ||
+                         is_function<typename remove_reference<_Fn>::type>::value,
+                         is_member_pointer<typename remove_reference<_Fn>::type>::value
+                        >
+{
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+// template <class T, class... Args> struct is_constructible;
+
+namespace __is_construct
+{
+struct __nat {};
+}
+
+#if __has_feature(is_constructible)
+
+template <class _Tp, class ..._Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible
+    : public integral_constant<bool, __is_constructible(_Tp, _Args...)>
+    {};
+
+#else
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+//      main is_constructible test
+
+template <class _Tp, class ..._Args>
+typename __select_2nd<decltype(_VSTD::move(_Tp(_VSTD::declval<_Args>()...))), true_type>::type
+__is_constructible_test(_Tp&&, _Args&& ...);
+
+template <class ..._Args>
+false_type
+__is_constructible_test(__any, _Args&& ...);
+
+template <bool, class _Tp, class... _Args>
+struct __libcpp_is_constructible // false, _Tp is not a scalar
+    : public common_type
+             <
+                 decltype(__is_constructible_test(declval<_Tp>(), declval<_Args>()...))
+             >::type
+    {};
+
+//      function types are not constructible
+
+template <class _Rp, class... _A1, class... _A2>
+struct __libcpp_is_constructible<false, _Rp(_A1...), _A2...>
+    : public false_type
+    {};
+
+//      handle scalars and reference types
+
+//      Scalars are default constructible, references are not
+
+template <class _Tp>
+struct __libcpp_is_constructible<true, _Tp>
+    : public is_scalar<_Tp>
+    {};
+
+//      Scalars and references are constructible from one arg if that arg is
+//          implicitly convertible to the scalar or reference.
+
+template <class _Tp>
+struct __is_constructible_ref
+{
+    true_type static __lxx(_Tp);
+    false_type static __lxx(...);
+};
+
+template <class _Tp, class _A0>
+struct __libcpp_is_constructible<true, _Tp, _A0>
+    : public common_type
+             <
+                 decltype(__is_constructible_ref<_Tp>::__lxx(declval<_A0>()))
+             >::type
+    {};
+
+//      Scalars and references are not constructible from multiple args.
+
+template <class _Tp, class _A0, class ..._Args>
+struct __libcpp_is_constructible<true, _Tp, _A0, _Args...>
+    : public false_type
+    {};
+
+//      Treat scalars and reference types separately
+
+template <bool, class _Tp, class... _Args>
+struct __is_constructible_void_check
+    : public __libcpp_is_constructible<is_scalar<_Tp>::value || is_reference<_Tp>::value,
+                                _Tp, _Args...>
+    {};
+
+//      If any of T or Args is void, is_constructible should be false
+
+template <class _Tp, class... _Args>
+struct __is_constructible_void_check<true, _Tp, _Args...>
+    : public false_type
+    {};
+
+template <class ..._Args> struct __contains_void;
+
+template <> struct __contains_void<> : false_type {};
+
+template <class _A0, class ..._Args>
+struct __contains_void<_A0, _Args...>
+{
+    static const bool value = is_void<_A0>::value ||
+                              __contains_void<_Args...>::value;
+};
+
+//      is_constructible entry point
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible
+    : public __is_constructible_void_check<__contains_void<_Tp, _Args...>::value
+                                        || is_abstract<_Tp>::value,
+                                           _Tp, _Args...>
+    {};
+
+//      Array types are default constructible if their element type
+//      is default constructible
+
+template <class _Ap, size_t _Np>
+struct __libcpp_is_constructible<false, _Ap[_Np]>
+    : public is_constructible<typename remove_all_extents<_Ap>::type>
+    {};
+
+//      Otherwise array types are not constructible by this syntax
+
+template <class _Ap, size_t _Np, class ..._Args>
+struct __libcpp_is_constructible<false, _Ap[_Np], _Args...>
+    : public false_type
+    {};
+
+//      Incomplete array types are not constructible
+
+template <class _Ap, class ..._Args>
+struct __libcpp_is_constructible<false, _Ap[], _Args...>
+    : public false_type
+    {};
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+// template <class T> struct is_constructible0;
+
+//      main is_constructible0 test
+
+template <class _Tp>
+decltype((_Tp(), true_type()))
+__is_constructible0_test(_Tp&);
+
+false_type
+__is_constructible0_test(__any);
+
+template <class _Tp, class _A0>
+decltype((_Tp(_VSTD::declval<_A0>()), true_type()))
+__is_constructible1_test(_Tp&, _A0&);
+
+template <class _A0>
+false_type
+__is_constructible1_test(__any, _A0&);
+
+template <class _Tp, class _A0, class _A1>
+decltype((_Tp(_VSTD::declval<_A0>(), _VSTD::declval<_A1>()), true_type()))
+__is_constructible2_test(_Tp&, _A0&, _A1&);
+
+template <class _A0, class _A1>
+false_type
+__is_constructible2_test(__any, _A0&, _A1&);
+
+template <bool, class _Tp>
+struct __is_constructible0_imp // false, _Tp is not a scalar
+    : public common_type
+             <
+                 decltype(__is_constructible0_test(declval<_Tp&>()))
+             >::type
+    {};
+
+template <bool, class _Tp, class _A0>
+struct __is_constructible1_imp // false, _Tp is not a scalar
+    : public common_type
+             <
+                 decltype(__is_constructible1_test(declval<_Tp&>(), declval<_A0&>()))
+             >::type
+    {};
+
+template <bool, class _Tp, class _A0, class _A1>
+struct __is_constructible2_imp // false, _Tp is not a scalar
+    : public common_type
+             <
+                 decltype(__is_constructible2_test(declval<_Tp&>(), declval<_A0>(), declval<_A1>()))
+             >::type
+    {};
+
+//      handle scalars and reference types
+
+//      Scalars are default constructible, references are not
+
+template <class _Tp>
+struct __is_constructible0_imp<true, _Tp>
+    : public is_scalar<_Tp>
+    {};
+
+template <class _Tp, class _A0>
+struct __is_constructible1_imp<true, _Tp, _A0>
+    : public is_convertible<_A0, _Tp>
+    {};
+
+template <class _Tp, class _A0, class _A1>
+struct __is_constructible2_imp<true, _Tp, _A0, _A1>
+    : public false_type
+    {};
+
+//      Treat scalars and reference types separately
+
+template <bool, class _Tp>
+struct __is_constructible0_void_check
+    : public __is_constructible0_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,
+                                _Tp>
+    {};
+
+template <bool, class _Tp, class _A0>
+struct __is_constructible1_void_check
+    : public __is_constructible1_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,
+                                _Tp, _A0>
+    {};
+
+template <bool, class _Tp, class _A0, class _A1>
+struct __is_constructible2_void_check
+    : public __is_constructible2_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,
+                                _Tp, _A0, _A1>
+    {};
+
+//      If any of T or Args is void, is_constructible should be false
+
+template <class _Tp>
+struct __is_constructible0_void_check<true, _Tp>
+    : public false_type
+    {};
+
+template <class _Tp, class _A0>
+struct __is_constructible1_void_check<true, _Tp, _A0>
+    : public false_type
+    {};
+
+template <class _Tp, class _A0, class _A1>
+struct __is_constructible2_void_check<true, _Tp, _A0, _A1>
+    : public false_type
+    {};
+
+//      is_constructible entry point
+
+template <class _Tp, class _A0 = __is_construct::__nat,
+                     class _A1 = __is_construct::__nat>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible
+    : public __is_constructible2_void_check<is_void<_Tp>::value
+                                        || is_abstract<_Tp>::value
+                                        || is_function<_Tp>::value
+                                        || is_void<_A0>::value
+                                        || is_void<_A1>::value,
+                                           _Tp, _A0, _A1>
+    {};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat>
+    : public __is_constructible0_void_check<is_void<_Tp>::value
+                                        || is_abstract<_Tp>::value
+                                        || is_function<_Tp>::value,
+                                           _Tp>
+    {};
+
+template <class _Tp, class _A0>
+struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, _A0, __is_construct::__nat>
+    : public __is_constructible1_void_check<is_void<_Tp>::value
+                                        || is_abstract<_Tp>::value
+                                        || is_function<_Tp>::value
+                                        || is_void<_A0>::value,
+                                           _Tp, _A0>
+    {};
+
+//      Array types are default constructible if their element type
+//      is default constructible
+
+template <class _Ap, size_t _Np>
+struct __is_constructible0_imp<false, _Ap[_Np]>
+    : public is_constructible<typename remove_all_extents<_Ap>::type>
+    {};
+
+template <class _Ap, size_t _Np, class _A0>
+struct __is_constructible1_imp<false, _Ap[_Np], _A0>
+    : public false_type
+    {};
+
+template <class _Ap, size_t _Np, class _A0, class _A1>
+struct __is_constructible2_imp<false, _Ap[_Np], _A0, _A1>
+    : public false_type
+    {};
+
+//      Incomplete array types are not constructible
+
+template <class _Ap>
+struct __is_constructible0_imp<false, _Ap[]>
+    : public false_type
+    {};
+
+template <class _Ap, class _A0>
+struct __is_constructible1_imp<false, _Ap[], _A0>
+    : public false_type
+    {};
+
+template <class _Ap, class _A0, class _A1>
+struct __is_constructible2_imp<false, _Ap[], _A0, _A1>
+    : public false_type
+    {};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // __has_feature(is_constructible)
+
+// is_default_constructible
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_default_constructible
+    : public is_constructible<_Tp>
+    {};
+
+// is_copy_constructible
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible
+    : public is_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
+    {};
+
+// is_move_constructible
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_move_constructible
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+#else
+    : public is_copy_constructible<_Tp>
+#endif
+    {};
+
+// is_trivially_constructible
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+#if __has_feature(is_trivially_constructible)
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
+    : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
+{
+};
+
+#else  // !__has_feature(is_trivially_constructible)
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
+    : false_type
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp>
+#if __has_feature(has_trivial_constructor) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_trivial_constructor(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&&>
+#else
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp>
+#endif
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+#endif  // !__has_feature(is_trivially_constructible)
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _A0 = __is_construct::__nat,
+                     class _A1 = __is_construct::__nat>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
+    : false_type
+{
+};
+
+#if __has_feature(is_trivially_constructible)
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, __is_trivially_constructible(_Tp)>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp)>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&)>
+{
+};
+
+#else  // !__has_feature(is_trivially_constructible)
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&,
+                                                       __is_construct::__nat>
+    : integral_constant<bool, is_scalar<_Tp>::value>
+{
+};
+
+#endif  // !__has_feature(is_trivially_constructible)
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+// is_trivially_default_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_constructible
+    : public is_trivially_constructible<_Tp>
+    {};
+
+// is_trivially_copy_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible
+    : public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
+    {};
+
+// is_trivially_move_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_constructible
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+#else
+    : public is_trivially_copy_constructible<_Tp>
+#endif
+    {};
+
+// is_trivially_assignable
+
+#if __has_feature(is_trivially_assignable)
+
+template <class _Tp, class _Arg>
+struct is_trivially_assignable
+    : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
+{
+};
+
+#else  // !__has_feature(is_trivially_assignable)
+
+template <class _Tp, class _Arg>
+struct is_trivially_assignable
+    : public false_type {};
+
+template <class _Tp>
+struct is_trivially_assignable<_Tp&, _Tp>
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+
+template <class _Tp>
+struct is_trivially_assignable<_Tp&, _Tp&>
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+
+template <class _Tp>
+struct is_trivially_assignable<_Tp&, const _Tp&>
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+struct is_trivially_assignable<_Tp&, _Tp&&>
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#endif  // !__has_feature(is_trivially_assignable)
+
+// is_trivially_copy_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable
+    : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
+                               const typename add_lvalue_reference<_Tp>::type>
+    {};
+
+// is_trivially_move_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_assignable
+    : public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type,
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+                                     typename add_rvalue_reference<_Tp>::type>
+#else
+                                     typename add_lvalue_reference<_Tp>::type>
+#endif
+    {};
+
+// is_trivially_destructible
+
+#if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
+    : public integral_constant<bool, __has_trivial_destructor(_Tp)> {};
+
+#else
+
+template <class _Tp> struct __libcpp_trivial_destructor
+    : public integral_constant<bool, is_scalar<_Tp>::value ||
+                                     is_reference<_Tp>::value> {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
+    : public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};
+
+#endif
+
+// is_nothrow_constructible
+
+#if 0
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
+    : public integral_constant<bool, __is_nothrow_constructible(_Tp(_Args...))>
+{
+};
+
+#else
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
+
+template <bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible;
+
+template <class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible<true, _Tp, _Args...>
+    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
+{
+};
+
+template <class _Tp, class... _Args>
+struct __libcpp_is_nothrow_constructible<false, _Tp, _Args...>
+    : public false_type
+{
+};
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, _Tp, _Args...>
+{
+};
+
+template <class _Tp, size_t _Ns>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]>
+    : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, _Tp>
+{
+};
+
+#else  // __has_feature(cxx_noexcept)
+
+template <class _Tp, class... _Args>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
+    : false_type
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp>
+#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_constructor(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&&>
+#else
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp>
+#endif
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&>
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&>
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+#endif  // __has_feature(cxx_noexcept)
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _A0 = __is_construct::__nat,
+                     class _A1 = __is_construct::__nat>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible
+    : false_type
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, __is_construct::__nat,
+                                                       __is_construct::__nat>
+#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_constructor(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp,
+                                                       __is_construct::__nat>
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&,
+                                                       __is_construct::__nat>
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&,
+                                                       __is_construct::__nat>
+#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_copy(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value>
+#endif
+{
+};
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // __has_feature(is_nothrow_constructible)
+
+// is_nothrow_default_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_default_constructible
+    : public is_nothrow_constructible<_Tp>
+    {};
+
+// is_nothrow_copy_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_constructible
+    : public is_nothrow_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
+    {};
+
+// is_nothrow_move_constructible
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_constructible
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type>
+#else
+    : public is_nothrow_copy_constructible<_Tp>
+#endif
+    {};
+
+// is_nothrow_assignable
+
+#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
+
+template <bool, class _Tp, class _Arg> struct __libcpp_is_nothrow_assignable;
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_assignable<false, _Tp, _Arg>
+    : public false_type
+{
+};
+
+template <class _Tp, class _Arg>
+struct __libcpp_is_nothrow_assignable<true, _Tp, _Arg>
+    : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>()) >
+{
+};
+
+template <class _Tp, class _Arg>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable
+    : public __libcpp_is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg>
+{
+};
+
+#else  // __has_feature(cxx_noexcept)
+
+template <class _Tp, class _Arg>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable
+    : public false_type {};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp>
+#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp&>
+#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+#endif
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, const _Tp&>
+#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+#endif
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+struct is_nothrow_assignable<_Tp&, _Tp&&>
+#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403)
+    : integral_constant<bool, __has_nothrow_assign(_Tp)> {};
+#else
+    : integral_constant<bool, is_scalar<_Tp>::value> {};
+#endif
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#endif  // __has_feature(cxx_noexcept)
+
+// is_nothrow_copy_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable
+    : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
+                               const typename add_lvalue_reference<_Tp>::type>
+    {};
+
+// is_nothrow_move_assignable
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_assignable
+    : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+                                     typename add_rvalue_reference<_Tp>::type>
+#else
+                                     typename add_lvalue_reference<_Tp>::type>
+#endif
+    {};
+
+// is_nothrow_destructible
+
+#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
+
+template <bool, class _Tp> struct __libcpp_is_nothrow_destructible;
+
+template <class _Tp>
+struct __libcpp_is_nothrow_destructible<false, _Tp>
+    : public false_type
+{
+};
+
+template <class _Tp>
+struct __libcpp_is_nothrow_destructible<true, _Tp>
+    : public integral_constant<bool, noexcept(_VSTD::declval<_Tp>().~_Tp()) >
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible
+    : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
+{
+};
+
+template <class _Tp, size_t _Ns>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[_Ns]>
+    : public is_nothrow_destructible<_Tp>
+{
+};
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&>
+    : public true_type
+{
+};
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&&>
+    : public true_type
+{
+};
+
+#endif
+
+#else
+
+template <class _Tp> struct __libcpp_nothrow_destructor
+    : public integral_constant<bool, is_scalar<_Tp>::value ||
+                                     is_reference<_Tp>::value> {};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible
+    : public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};
+
+#endif
+
+// is_pod
+
+#if __has_feature(is_pod) || (_GNUC_VER >= 403)
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod
+    : public integral_constant<bool, __is_pod(_Tp)> {};
+
+#else
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod
+    : public integral_constant<bool, is_trivially_default_constructible<_Tp>::value   &&
+                                     is_trivially_copy_constructible<_Tp>::value      &&
+                                     is_trivially_copy_assignable<_Tp>::value    &&
+                                     is_trivially_destructible<_Tp>::value> {};
+
+#endif
+
+// is_literal_type;
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_literal_type
+#ifdef _LIBCPP_IS_LITERAL
+    : public integral_constant<bool, _LIBCPP_IS_LITERAL(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value ||
+                              is_reference<typename remove_all_extents<_Tp>::type>::value>
+#endif
+    {};
+    
+// is_standard_layout;
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_standard_layout
+#if __has_feature(is_standard_layout) || (_GNUC_VER >= 407)
+    : public integral_constant<bool, __is_standard_layout(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
+#endif
+    {};
+    
+// is_trivially_copyable;
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable
+#if __has_feature(is_trivially_copyable)
+    : public integral_constant<bool, __is_trivially_copyable(_Tp)>
+#else
+    : integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
+#endif
+    {};
+    
+// is_trivial;
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial
+#if __has_feature(is_trivial) || (_GNUC_VER >= 407)
+    : public integral_constant<bool, __is_trivial(_Tp)>
+#else
+    : integral_constant<bool, is_trivially_copyable<_Tp>::value &&
+                                 is_trivially_default_constructible<_Tp>::value>
+#endif
+    {};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+// Check for complete types
+
+template <class ..._Tp> struct __check_complete;
+
+template <>
+struct __check_complete<>
+{
+};
+
+template <class _Hp, class _T0, class ..._Tp>
+struct __check_complete<_Hp, _T0, _Tp...>
+    : private __check_complete<_Hp>,
+      private __check_complete<_T0, _Tp...>
+{
+};
+
+template <class _Hp>
+struct __check_complete<_Hp, _Hp>
+    : private __check_complete<_Hp>
+{
+};
+
+template <class _Tp>
+struct __check_complete<_Tp>
+{
+    static_assert(sizeof(_Tp) > 0, "Type must be complete.");
+};
+
+template <class _Tp>
+struct __check_complete<_Tp&>
+    : private __check_complete<_Tp>
+{
+};
+
+template <class _Tp>
+struct __check_complete<_Tp&&>
+    : private __check_complete<_Tp>
+{
+};
+
+template <class _Rp, class ..._Param>
+struct __check_complete<_Rp (*)(_Param...)>
+    : private __check_complete<_Rp>
+{
+};
+
+template <class ..._Param>
+struct __check_complete<void (*)(_Param...)>
+{
+};
+
+template <class _Rp, class ..._Param>
+struct __check_complete<_Rp (_Param...)>
+    : private __check_complete<_Rp>
+{
+};
+
+template <class ..._Param>
+struct __check_complete<void (_Param...)>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...)>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) volatile>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const volatile>
+    : private __check_complete<_Class>
+{
+};
+
+#if __has_feature(cxx_reference_qualified_functions)
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) &>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) volatile&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) &&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const&&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) volatile&&>
+    : private __check_complete<_Class>
+{
+};
+
+template <class _Rp, class _Class, class ..._Param>
+struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&>
+    : private __check_complete<_Class>
+{
+};
+
+#endif
+
+template <class _Rp, class _Class>
+struct __check_complete<_Rp _Class::*>
+    : private __check_complete<_Class>
+{
+};
+
+// __invoke forward declarations
+
+// fall back - none of the bullets
+
+template <class ..._Args>
+auto
+__invoke(__any, _Args&& ...__args)
+    -> __nat;
+
+// bullets 1 and 2
+
+template <class _Fp, class _A0, class ..._Args,
+            class = typename enable_if
+            <
+                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
+                is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
+_LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...));
+
+template <class _Fp, class _A0, class ..._Args,
+            class = typename enable_if
+            <
+                is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
+                !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
+_LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...));
+
+// bullets 3 and 4
+
+template <class _Fp, class _A0,
+            class = typename enable_if
+            <
+                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
+                is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
+_LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0)
+    -> decltype(_VSTD::forward<_A0>(__a0).*__f);
+
+template <class _Fp, class _A0,
+            class = typename enable_if
+            <
+                is_member_object_pointer<typename remove_reference<_Fp>::type>::value &&
+                !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+                           typename remove_reference<_A0>::type>::value
+            >::type
+         >
+_LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _A0&& __a0)
+    -> decltype((*_VSTD::forward<_A0>(__a0)).*__f);
+
+// bullet 5
+
+template <class _Fp, class ..._Args>
+_LIBCPP_INLINE_VISIBILITY
+auto
+__invoke(_Fp&& __f, _Args&& ...__args)
+    -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...));
+
+// __invokable
+
+template <class _Fp, class ..._Args>
+struct __invokable_imp
+    : private __check_complete<_Fp>
+{
+    typedef decltype(
+            __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)
+                    ) type;
+    static const bool value = !is_same<type, __nat>::value;
+};
+
+template <class _Fp, class ..._Args>
+struct __invokable
+    : public integral_constant<bool,
+          __invokable_imp<_Fp, _Args...>::value>
+{
+};
+
+// __invoke_of
+
+template <bool _Invokable, class _Fp, class ..._Args>
+struct __invoke_of_imp  // false
+{
+};
+
+template <class _Fp, class ..._Args>
+struct __invoke_of_imp<true, _Fp, _Args...>
+{
+    typedef typename __invokable_imp<_Fp, _Args...>::type type;
+};
+
+template <class _Fp, class ..._Args>
+struct __invoke_of
+    : public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...>
+{
+};
+
+template <class _Fp, class ..._Args>
+class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)>
+    : public __invoke_of<_Fp, _Args...>
+{
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
+#endif
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+typename enable_if
+<
+    is_move_constructible<_Tp>::value &&
+    is_move_assignable<_Tp>::value
+>::type
+#else
+void
+#endif
+swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
+                                    is_nothrow_move_assignable<_Tp>::value)
+{
+    _Tp __t(_VSTD::move(__x));
+    __x = _VSTD::move(__y);
+    __y = _VSTD::move(__t);
+}
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
+    //                                  _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
+               _NOEXCEPT_(_NOEXCEPT_(swap(*_VSTD::declval<_ForwardIterator1>(),
+                                          *_VSTD::declval<_ForwardIterator2>())))
+{
+    swap(*__a, *__b);
+}
+
+// __swappable
+
+namespace __detail
+{
+
+using _VSTD::swap;
+__nat swap(__any, __any);
+
+template <class _Tp>
+struct __swappable
+{
+    typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type;
+    static const bool value = !is_same<type, __nat>::value;
+};
+
+}  // __detail
+
+template <class _Tp>
+struct __is_swappable
+    : public integral_constant<bool, __detail::__swappable<_Tp>::value>
+{
+};
+
+#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
+
+template <bool, class _Tp>
+struct __is_nothrow_swappable_imp
+    : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(),
+                                                   _VSTD::declval<_Tp&>()))>
+{
+};
+
+template <class _Tp>
+struct __is_nothrow_swappable_imp<false, _Tp>
+    : public false_type
+{
+};
+
+template <class _Tp>
+struct __is_nothrow_swappable
+    : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>
+{
+};
+
+#else  // __has_feature(cxx_noexcept)
+
+template <class _Tp>
+struct __is_nothrow_swappable
+    : public false_type
+{
+};
+
+#endif  // __has_feature(cxx_noexcept)
+
+#ifdef _LIBCPP_UNDERLYING_TYPE
+
+template <class _Tp>
+struct underlying_type
+{
+    typedef _LIBCPP_UNDERLYING_TYPE(_Tp) type;
+};
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
+#endif
+
+#else  // _LIBCPP_UNDERLYING_TYPE
+
+template <class _Tp, bool _Support = false>
+struct underlying_type
+{
+    static_assert(_Support, "The underyling_type trait requires compiler "
+                            "support. Either no such support exists or "
+                            "libc++ does not know how to use it.");
+};
+
+#endif // _LIBCPP_UNDERLYING_TYPE
+
+#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+template <class _Tp>
+struct __has_operator_addressof_imp
+{
+    template <class>
+        static auto __test(__any) -> false_type;
+    template <class _Up>
+        static auto __test(_Up* __u)
+            -> typename __select_2nd<decltype(__u->operator&()), true_type>::type;
+
+    static const bool value = decltype(__test<_Tp>(nullptr))::value;
+};
+
+template <class _Tp>
+struct __has_operator_addressof
+    : public integral_constant<bool, __has_operator_addressof_imp<_Tp>::value>
+{};
+
+#endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_TYPE_TRAITS
diff --git a/include/c++/v1/typeindex b/include/c++/v1/typeindex
new file mode 100644
index 0000000..d4d6ca9
--- /dev/null
+++ b/include/c++/v1/typeindex
@@ -0,0 +1,103 @@
+// -*- C++ -*-
+//===-------------------------- typeindex ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_TYPEINDEX
+#define _LIBCPP_TYPEINDEX
+
+/*
+
+    typeindex synopsis
+
+namespace std
+{
+
+class type_index
+{
+public:
+    type_index(const type_info& rhs) noexcept;
+
+    bool operator==(const type_index& rhs) const noexcept;
+    bool operator!=(const type_index& rhs) const noexcept;
+    bool operator< (const type_index& rhs) const noexcept;
+    bool operator<=(const type_index& rhs) const noexcept;
+    bool operator> (const type_index& rhs) const noexcept;
+    bool operator>=(const type_index& rhs) const noexcept;
+
+    size_t hash_code() const noexcept;
+    const char* name() const noexcept;
+};
+
+template <>
+struct hash<type_index>
+    : public unary_function<type_index, size_t>
+{
+    size_t operator()(type_index index) const noexcept;
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <typeinfo>
+#include <__functional_base>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+class _LIBCPP_TYPE_VIS_ONLY type_index
+{
+    const type_info* __t_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    type_index(const type_info& __y) _NOEXCEPT : __t_(&__y) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const type_index& __y) const _NOEXCEPT
+        {return *__t_ == *__y.__t_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const type_index& __y) const _NOEXCEPT
+        {return *__t_ != *__y.__t_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator< (const type_index& __y) const _NOEXCEPT
+        {return  __t_->before(*__y.__t_);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator<=(const type_index& __y) const _NOEXCEPT
+        {return !__y.__t_->before(*__t_);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator> (const type_index& __y) const _NOEXCEPT
+        {return  __y.__t_->before(*__t_);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator>=(const type_index& __y) const _NOEXCEPT
+        {return !__t_->before(*__y.__t_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t hash_code() const _NOEXCEPT {return __t_->hash_code();}
+    _LIBCPP_INLINE_VISIBILITY
+    const char* name() const _NOEXCEPT {return __t_->name();}
+};
+
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash;
+
+template <>
+struct _LIBCPP_TYPE_VIS_ONLY hash<type_index>
+    : public unary_function<type_index, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(type_index __index) const _NOEXCEPT
+        {return __index.hash_code();}
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_TYPEINDEX
diff --git a/include/c++/v1/typeinfo b/include/c++/v1/typeinfo
new file mode 100644
index 0000000..14ef77b
--- /dev/null
+++ b/include/c++/v1/typeinfo
@@ -0,0 +1,168 @@
+// -*- C++ -*-
+//===-------------------------- typeinfo ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LIBCPP_TYPEINFO
+#define __LIBCPP_TYPEINFO
+
+/*
+
+    typeinfo synopsis
+
+namespace std {
+
+class type_info
+{
+public:
+    virtual ~type_info();
+
+    bool operator==(const type_info& rhs) const noexcept;
+    bool operator!=(const type_info& rhs) const noexcept;
+
+    bool before(const type_info& rhs) const noexcept;
+    size_t hash_code() const noexcept;
+    const char* name() const noexcept;
+
+    type_info(const type_info& rhs) = delete;
+    type_info& operator=(const type_info& rhs) = delete;
+};
+
+class bad_cast
+    : public exception
+{
+public:
+    bad_cast() noexcept;
+    bad_cast(const bad_cast&) noexcept;
+    bad_cast& operator=(const bad_cast&) noexcept;
+    virtual const char* what() const noexcept;
+};
+
+class bad_typeid
+    : public exception
+{
+public:
+    bad_typeid() noexcept;
+    bad_typeid(const bad_typeid&) noexcept;
+    bad_typeid& operator=(const bad_typeid&) noexcept;
+    virtual const char* what() const noexcept;
+};
+
+}  // std
+
+*/
+
+#include <__config>
+#include <exception>
+#include <cstddef>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+namespace std  // purposefully not using versioning namespace
+{
+
+class _LIBCPP_EXCEPTION_ABI type_info
+{
+    type_info& operator=(const type_info&);
+    type_info(const type_info&);
+protected:
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+    const char* __type_name;
+#else
+    // A const char* with the non-unique RTTI bit possibly set.
+    uintptr_t __type_name;
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit type_info(const char* __n)
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+        : __type_name(__n) {}
+#else
+        : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
+#endif
+
+public:
+    virtual ~type_info();
+
+    _LIBCPP_INLINE_VISIBILITY
+    const char* name() const _NOEXCEPT
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+        {return __type_name;}
+#else
+        {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool before(const type_info& __arg) const _NOEXCEPT
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+        {return __type_name < __arg.__type_name;}
+#else
+        {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
+           return __type_name < __arg.__type_name;
+         return __compare_nonunique_names(__arg) < 0;}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t hash_code() const _NOEXCEPT
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+        {return *reinterpret_cast<const size_t*>(&__type_name);}
+#else
+        {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
+         const char *__ptr = name();
+         size_t __hash = 5381;
+         while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
+           __hash = (__hash * 33) ^ __c;
+         return __hash;}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const type_info& __arg) const _NOEXCEPT
+#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
+        {return __type_name == __arg.__type_name;}
+#else
+        {if (__type_name == __arg.__type_name) return true;
+         if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
+           return false;
+         return __compare_nonunique_names(__arg) == 0;}
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator!=(const type_info& __arg) const _NOEXCEPT
+        {return !operator==(__arg);}
+
+#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
+  private:
+    _LIBCPP_INLINE_VISIBILITY
+    int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
+        {return __builtin_strcmp(name(), __arg.name());}
+#endif
+};
+
+class _LIBCPP_EXCEPTION_ABI bad_cast
+    : public exception
+{
+public:
+    bad_cast() _NOEXCEPT;
+    virtual ~bad_cast() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI bad_typeid
+    : public exception
+{
+public:
+    bad_typeid() _NOEXCEPT;
+    virtual ~bad_typeid() _NOEXCEPT;
+    virtual const char* what() const _NOEXCEPT;
+};
+
+}  // std
+
+#endif  // __LIBCPP_TYPEINFO
diff --git a/include/c++/v1/unordered_map b/include/c++/v1/unordered_map
new file mode 100644
index 0000000..4e2298b
--- /dev/null
+++ b/include/c++/v1/unordered_map
@@ -0,0 +1,2082 @@
+// -*- C++ -*-
+//===-------------------------- unordered_map -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_UNORDERED_MAP
+#define _LIBCPP_UNORDERED_MAP
+
+/*
+
+    unordered_map synopsis
+
+#include <initializer_list>
+
+namespace std
+{
+
+template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+          class Alloc = allocator<pair<const Key, T>>>
+class unordered_map
+{
+public:
+    // types
+    typedef Key                                                        key_type;
+    typedef T                                                          mapped_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef pair<const key_type, mapped_type>                          value_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+    typedef /unspecified/ local_iterator;
+    typedef /unspecified/ const_local_iterator;
+
+    unordered_map()
+        noexcept(
+            is_nothrow_default_constructible<hasher>::value &&
+            is_nothrow_default_constructible<key_equal>::value &&
+            is_nothrow_default_constructible<allocator_type>::value);
+    explicit unordered_map(size_type n, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        unordered_map(InputIterator f, InputIterator l,
+                      size_type n = 0, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    explicit unordered_map(const allocator_type&);
+    unordered_map(const unordered_map&);
+    unordered_map(const unordered_map&, const Allocator&);
+    unordered_map(unordered_map&&)
+        noexcept(
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value &&
+            is_nothrow_move_constructible<allocator_type>::value);
+    unordered_map(unordered_map&&, const Allocator&);
+    unordered_map(initializer_list<value_type>, size_type n = 0,
+                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+                  const allocator_type& a = allocator_type());
+    unordered_map(size_type n, const allocator_type& a)
+      : unordered_map(n, hasher(), key_equal(), a) {}  // C++14
+    unordered_map(size_type n, const hasher& hf, const allocator_type& a)
+      : unordered_map(n, hf, key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
+      : unordered_map(f, l, n, hasher(), key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
+        const allocator_type& a)
+      : unordered_map(f, l, n, hf, key_equal(), a) {}  // C++14
+    unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
+      : unordered_map(il, n, hasher(), key_equal(), a) {}  // C++14
+    unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, 
+      const allocator_type& a)
+      : unordered_map(il, n, hf, key_equal(), a) {}  // C++14
+    ~unordered_map();
+    unordered_map& operator=(const unordered_map&);
+    unordered_map& operator=(unordered_map&&)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+    unordered_map& operator=(initializer_list<value_type>);
+
+    allocator_type get_allocator() const noexcept;
+
+    bool      empty() const noexcept;
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+
+    iterator       begin() noexcept;
+    iterator       end() noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cbegin() const noexcept;
+    const_iterator cend()   const noexcept;
+
+    template <class... Args>
+        pair<iterator, bool> emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    pair<iterator, bool> insert(const value_type& obj);
+    template <class P>
+        pair<iterator, bool> insert(P&& obj);
+    iterator insert(const_iterator hint, const value_type& obj);
+    template <class P>
+        iterator insert(const_iterator hint, P&& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type>);
+
+    iterator erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(unordered_map&)
+        noexcept(
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value) &&
+            __is_nothrow_swappable<hasher>::value &&
+            __is_nothrow_swappable<key_equal>::value);
+
+    hasher hash_function() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    mapped_type& operator[](const key_type& k);
+    mapped_type& operator[](key_type&& k);
+
+    mapped_type&       at(const key_type& k);
+    const mapped_type& at(const key_type& k) const;
+
+    size_type bucket_count() const noexcept;
+    size_type max_bucket_count() const noexcept;
+
+    size_type bucket_size(size_type n) const;
+    size_type bucket(const key_type& k) const;
+
+    local_iterator       begin(size_type n);
+    local_iterator       end(size_type n);
+    const_local_iterator begin(size_type n) const;
+    const_local_iterator end(size_type n) const;
+    const_local_iterator cbegin(size_type n) const;
+    const_local_iterator cend(size_type n) const;
+
+    float load_factor() const noexcept;
+    float max_load_factor() const noexcept;
+    void max_load_factor(float z);
+    void rehash(size_type n);
+    void reserve(size_type n);
+};
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x,
+              unordered_map<Key, T, Hash, Pred, Alloc>& y)
+              noexcept(noexcept(x.swap(y)));
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
+               const unordered_map<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
+               const unordered_map<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
+          class Alloc = allocator<pair<const Key, T>>>
+class unordered_multimap
+{
+public:
+    // types
+    typedef Key                                                        key_type;
+    typedef T                                                          mapped_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef pair<const key_type, mapped_type>                          value_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+    typedef /unspecified/ local_iterator;
+    typedef /unspecified/ const_local_iterator;
+
+    unordered_multimap()
+        noexcept(
+            is_nothrow_default_constructible<hasher>::value &&
+            is_nothrow_default_constructible<key_equal>::value &&
+            is_nothrow_default_constructible<allocator_type>::value);
+    explicit unordered_multimap(size_type n, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        unordered_multimap(InputIterator f, InputIterator l,
+                      size_type n = 0, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    explicit unordered_multimap(const allocator_type&);
+    unordered_multimap(const unordered_multimap&);
+    unordered_multimap(const unordered_multimap&, const Allocator&);
+    unordered_multimap(unordered_multimap&&)
+        noexcept(
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value &&
+            is_nothrow_move_constructible<allocator_type>::value);
+    unordered_multimap(unordered_multimap&&, const Allocator&);
+    unordered_multimap(initializer_list<value_type>, size_type n = 0,
+                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+                  const allocator_type& a = allocator_type());
+    unordered_multimap(size_type n, const allocator_type& a)
+      : unordered_multimap(n, hasher(), key_equal(), a) {}  // C++14
+    unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
+      : unordered_multimap(n, hf, key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
+      : unordered_multimap(f, l, n, hasher(), key_equal(), a) {}  // C++14
+    template <class InputIterator>
+      unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, 
+        const allocator_type& a)
+      : unordered_multimap(f, l, n, hf, key_equal(), a) {}  // C++14
+    unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
+      : unordered_multimap(il, n, hasher(), key_equal(), a) {}  // C++14
+    unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, 
+      const allocator_type& a)
+      : unordered_multimap(il, n, hf, key_equal(), a) {}  // C++14
+    ~unordered_multimap();
+    unordered_multimap& operator=(const unordered_multimap&);
+    unordered_multimap& operator=(unordered_multimap&&)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+    unordered_multimap& operator=(initializer_list<value_type>);
+
+    allocator_type get_allocator() const noexcept;
+
+    bool      empty() const noexcept;
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+
+    iterator       begin() noexcept;
+    iterator       end() noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cbegin() const noexcept;
+    const_iterator cend()   const noexcept;
+
+    template <class... Args>
+        iterator emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    iterator insert(const value_type& obj);
+    template <class P>
+        iterator insert(P&& obj);
+    iterator insert(const_iterator hint, const value_type& obj);
+    template <class P>
+        iterator insert(const_iterator hint, P&& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type>);
+
+    iterator erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(unordered_multimap&)
+        noexcept(
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value) &&
+            __is_nothrow_swappable<hasher>::value &&
+            __is_nothrow_swappable<key_equal>::value);
+
+    hasher hash_function() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const noexcept;
+    size_type max_bucket_count() const noexcept;
+
+    size_type bucket_size(size_type n) const;
+    size_type bucket(const key_type& k) const;
+
+    local_iterator       begin(size_type n);
+    local_iterator       end(size_type n);
+    const_local_iterator begin(size_type n) const;
+    const_local_iterator end(size_type n) const;
+    const_local_iterator cbegin(size_type n) const;
+    const_local_iterator cend(size_type n) const;
+
+    float load_factor() const noexcept;
+    float max_load_factor() const noexcept;
+    void max_load_factor(float z);
+    void rehash(size_type n);
+    void reserve(size_type n);
+};
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
+              unordered_multimap<Key, T, Hash, Pred, Alloc>& y)
+              noexcept(noexcept(x.swap(y)));
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
+               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+template <class Key, class T, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
+               const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__hash_table>
+#include <functional>
+#include <stdexcept>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value
+#if __has_feature(is_final)
+                                         && !__is_final(_Hash)
+#endif
+         >
+class __unordered_map_hasher
+    : private _Hash
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_hasher()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)
+        : _Hash() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_hasher(const _Hash& __h)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)
+        : _Hash(__h) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Hash& hash_function() const _NOEXCEPT {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Cp& __x) const
+        {return static_cast<const _Hash&>(*this)(__x.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Key& __x) const
+        {return static_cast<const _Hash&>(*this)(__x);}
+};
+
+template <class _Key, class _Cp, class _Hash>
+class __unordered_map_hasher<_Key, _Cp, _Hash, false>
+{
+    _Hash __hash_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_hasher()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value)
+        : __hash_() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_hasher(const _Hash& __h)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value)
+        : __hash_(__h) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Hash& hash_function() const _NOEXCEPT {return __hash_;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Cp& __x) const
+        {return __hash_(__x.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const _Key& __x) const
+        {return __hash_(__x);}
+};
+
+template <class _Key, class _Cp, class _Pred, bool = is_empty<_Pred>::value
+#if __has_feature(is_final)
+                                         && !__is_final(_Pred)
+#endif
+         >
+class __unordered_map_equal
+    : private _Pred
+{
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_equal()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)
+        : _Pred() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_equal(const _Pred& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)
+        : _Pred(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Pred& key_eq() const _NOEXCEPT {return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Cp& __x, const _Cp& __y) const
+        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Cp& __x, const _Key& __y) const
+        {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Key& __x, const _Cp& __y) const
+        {return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}
+};
+
+template <class _Key, class _Cp, class _Pred>
+class __unordered_map_equal<_Key, _Cp, _Pred, false>
+{
+    _Pred __pred_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_equal()
+        _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value)
+        : __pred_() {}
+    _LIBCPP_INLINE_VISIBILITY
+    __unordered_map_equal(const _Pred& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value)
+        : __pred_(__p) {}
+    _LIBCPP_INLINE_VISIBILITY
+    const _Pred& key_eq() const _NOEXCEPT {return __pred_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Cp& __x, const _Cp& __y) const
+        {return __pred_(__x.__cc.first, __y.__cc.first);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Cp& __x, const _Key& __y) const
+        {return __pred_(__x.__cc.first, __y);}
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator()(const _Key& __x, const _Cp& __y) const
+        {return __pred_(__x, __y.__cc.first);}
+};
+
+template <class _Alloc>
+class __hash_map_node_destructor
+{
+    typedef _Alloc                              allocator_type;
+    typedef allocator_traits<allocator_type>    __alloc_traits;
+    typedef typename __alloc_traits::value_type::value_type value_type;
+public:
+    typedef typename __alloc_traits::pointer    pointer;
+private:
+    typedef typename value_type::value_type::first_type     first_type;
+    typedef typename value_type::value_type::second_type    second_type;
+
+    allocator_type& __na_;
+
+    __hash_map_node_destructor& operator=(const __hash_map_node_destructor&);
+
+public:
+    bool __first_constructed;
+    bool __second_constructed;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT
+        : __na_(__na),
+          __first_constructed(false),
+          __second_constructed(false)
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_node_destructor(__hash_node_destructor<allocator_type>&& __x)
+        _NOEXCEPT
+        : __na_(__x.__na_),
+          __first_constructed(__x.__value_constructed),
+          __second_constructed(__x.__value_constructed)
+        {
+            __x.__value_constructed = false;
+        }
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_node_destructor(const __hash_node_destructor<allocator_type>& __x)
+        : __na_(__x.__na_),
+          __first_constructed(__x.__value_constructed),
+          __second_constructed(__x.__value_constructed)
+        {
+            const_cast<bool&>(__x.__value_constructed) = false;
+        }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()(pointer __p) _NOEXCEPT
+    {
+        if (__second_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second));
+        if (__first_constructed)
+            __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first));
+        if (__p)
+            __alloc_traits::deallocate(__na_, __p, 1);
+    }
+};
+
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const __hash_value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(__hash_value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(const __hash_value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(__hash_value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
+template <class _HashIterator>
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator
+{
+    _HashIterator __i_;
+
+    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
+    typedef const typename _HashIterator::value_type::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;
+public:
+    typedef forward_iterator_tag                                 iterator_category;
+    typedef pair<key_type, mapped_type>                          value_type;
+    typedef typename _HashIterator::difference_type              difference_type;
+    typedef value_type&                                          reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<value_type>
+#else
+            rebind<value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_iterator() _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __i_->__cc;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_iterator operator++(int)
+    {
+        __hash_map_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
+};
+
+template <class _HashIterator>
+class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator
+{
+    _HashIterator __i_;
+
+    typedef pointer_traits<typename _HashIterator::pointer>      __pointer_traits;
+    typedef const typename _HashIterator::value_type::value_type::first_type key_type;
+    typedef typename _HashIterator::value_type::value_type::second_type      mapped_type;
+public:
+    typedef forward_iterator_tag                                 iterator_category;
+    typedef pair<key_type, mapped_type>                          value_type;
+    typedef typename _HashIterator::difference_type              difference_type;
+    typedef const value_type&                                    reference;
+    typedef typename __pointer_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind<const value_type>
+#else
+            rebind<const value_type>::other
+#endif
+                                                                 pointer;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator() _NOEXCEPT {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator(
+            __hash_map_iterator<typename _HashIterator::__non_const_iterator> __i)
+                 _NOEXCEPT
+                : __i_(__i.__i_) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reference operator*() const {return __i_->__cc;}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator& operator++() {++__i_; return *this;}
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_map_const_iterator operator++(int)
+    {
+        __hash_map_const_iterator __t(*this);
+        ++(*this);
+        return __t;
+    }
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
+        {return __x.__i_ == __y.__i_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y)
+        {return __x.__i_ != __y.__i_;}
+
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map;
+    template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator;
+};
+
+template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
+          class _Alloc = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY unordered_map
+{
+public:
+    // types
+    typedef _Key                                           key_type;
+    typedef _Tp                                            mapped_type;
+    typedef _Hash                                          hasher;
+    typedef _Pred                                          key_equal;
+    typedef _Alloc                                         allocator_type;
+    typedef pair<const key_type, mapped_type>              value_type;
+    typedef pair<key_type, mapped_type>                    __nc_value_type;
+    typedef value_type&                                    reference;
+    typedef const value_type&                              const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
+
+private:
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
+    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
+    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                           __allocator_type;
+
+    typedef __hash_table<__value_type, __hasher,
+                         __key_equal,  __allocator_type>   __table;
+
+    __table __table_;
+
+    typedef typename __table::__node_pointer               __node_pointer;
+    typedef typename __table::__node_const_pointer         __node_const_pointer;
+    typedef typename __table::__node_traits                __node_traits;
+    typedef typename __table::__node_allocator             __node_allocator;
+    typedef typename __table::__node                       __node;
+    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
+    typedef unique_ptr<__node, _Dp>                         __node_holder;
+    typedef allocator_traits<allocator_type>               __alloc_traits;
+public:
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+
+    typedef __hash_map_iterator<typename __table::iterator>       iterator;
+    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
+    typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
+    typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map()
+        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    explicit unordered_map(size_type __n, const hasher& __hf = hasher(),
+                           const key_equal& __eql = key_equal());
+    unordered_map(size_type __n, const hasher& __hf,
+                  const key_equal& __eql,
+                  const allocator_type& __a);
+    template <class _InputIterator>
+        unordered_map(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        unordered_map(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        unordered_map(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf,
+                      const key_equal& __eql,
+                      const allocator_type& __a);
+    explicit unordered_map(const allocator_type& __a);
+    unordered_map(const unordered_map& __u);
+    unordered_map(const unordered_map& __u, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_map(unordered_map&& __u)
+        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
+    unordered_map(unordered_map&& __u, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_map(initializer_list<value_type> __il);
+    unordered_map(initializer_list<value_type> __il, size_type __n,
+                  const hasher& __hf = hasher(), const key_equal& __eql = key_equal());
+    unordered_map(initializer_list<value_type> __il, size_type __n,
+                  const hasher& __hf, const key_equal& __eql,
+                  const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(size_type __n, const allocator_type& __a)
+      : unordered_map(__n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_map(__n, __hf, key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
+      : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, 
+        const allocator_type& __a)
+      : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_map(__il, __n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map(initializer_list<value_type> __il, size_type __n, const hasher& __hf, 
+      const allocator_type& __a)
+      : unordered_map(__il, __n, __hf, key_equal(), __a) {}
+#endif
+    // ~unordered_map() = default;
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_map& operator=(const unordered_map& __u)
+    {
+#if __cplusplus >= 201103L
+        __table_ = __u.__table_;
+#else
+        if (this != &__u) {
+            __table_.clear();
+            __table_.hash_function() = __u.__table_.hash_function();
+            __table_.key_eq() = __u.__table_.key_eq();
+            __table_.max_load_factor() = __u.__table_.max_load_factor();
+            __table_.__copy_assign_alloc(__u.__table_);
+            insert(__u.begin(), __u.end());
+        }
+#endif
+        return *this;
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_map& operator=(unordered_map&& __u)
+        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
+#endif
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_map& operator=(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const _NOEXCEPT {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args>
+        pair<iterator, bool> emplace(_Args&&... __args);
+
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
+                " referring to this unordered_map");
+            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
+        }
+#else
+        iterator emplace_hint(const_iterator, _Args&&... __args)
+            {return emplace(_VSTD::forward<_Args>(__args)...).first;}
+#endif
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> insert(const value_type& __x)
+        {return __table_.__insert_unique(__x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        pair<iterator, bool> insert(_Pp&& __x)
+            {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, const value_type& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
+                " referring to this unordered_map");
+            return insert(__x).first;
+        }
+#else
+    iterator insert(const_iterator, const value_type& __x)
+        {return insert(__x).first;}
+#endif
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator insert(const_iterator __p, _Pp&& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
+                " referring to this unordered_map");
+            return insert(_VSTD::forward<_Pp>(__x)).first;
+        }
+#else
+        iterator insert(const_iterator, _Pp&& __x)
+            {return insert(_VSTD::forward<_Pp>(__x)).first;}
+#endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __first, const_iterator __last)
+        {return __table_.erase(__first.__i_, __last.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(unordered_map& __u)
+        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
+        {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_function() const
+        {return __table_.hash_function().hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const
+        {return __table_.key_eq().key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_unique(__k);}
+
+    mapped_type& operator[](const key_type& __k);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    mapped_type& operator[](key_type&& __k);
+#endif
+
+    mapped_type&       at(const key_type& __k);
+    const mapped_type& at(const key_type& __k) const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_size(size_type __n) const
+        {return __table_.bucket_size(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       end(size_type __n)          {return __table_.end(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
+    _LIBCPP_INLINE_VISIBILITY
+    void rehash(size_type __n) {__table_.rehash(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(&__i->__i_);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(&__i->__i_);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node();
+    template <class _A0>
+        __node_holder
+         __construct_node(_A0&& __a0);
+    __node_holder __construct_node_with_key(key_type&& __k);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _A0, class _A1, class ..._Args>
+        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node_with_key(const key_type& __k);
+};
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        const allocator_type& __a)
+    : __table_(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        const unordered_map& __u)
+    : __table_(__u.__table_)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        const unordered_map& __u, const allocator_type& __a)
+    : __table_(__u.__table_, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        unordered_map&& __u)
+    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
+    : __table_(_VSTD::move(__u.__table_))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        unordered_map&& __u, const allocator_type& __a)
+    : __table_(_VSTD::move(__u.__table_), __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a != __u.get_allocator())
+    {
+        iterator __i = __u.begin();
+        while (__u.size() != 0)
+            __table_.__insert_unique(
+                _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)
+                                    );
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u)
+    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
+{
+    __table_ = _VSTD::move(__u.__table_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
+        initializer_list<value_type> __il)
+{
+    __table_.__assign_unique(__il.begin(), __il.end());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _A0>
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(key_type&& __k)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k));
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _A0, class _A1, class ..._Args>
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0,
+                                                                 _A1&& __a1,
+                                                                 _Args&&... __args)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
+                             _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class... _Args>
+pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool>
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
+    if (__r.second)
+        __h.release();
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k);
+    __h.get_deleter().__first_constructed = true;
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second));
+    __h.get_deleter().__second_constructed = true;
+    return _VSTD::move(__h);  // explicitly moved for C++03
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                       _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_unique(*__first);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+_Tp&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k)
+{
+    iterator __i = find(__k);
+    if (__i != end())
+        return __i->second;
+    __node_holder __h = __construct_node_with_key(__k);
+    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
+    __h.release();
+    return __r.first->second;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+_Tp&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k)
+{
+    iterator __i = find(__k);
+    if (__i != end())
+        return __i->second;
+    __node_holder __h = __construct_node_with_key(_VSTD::move(__k));
+    pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
+    __h.release();
+    return __r.first->second;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+_Tp&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k)
+{
+    iterator __i = find(__k);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__i == end())
+        throw out_of_range("unordered_map::at: key not found");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __i->second;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+const _Tp&
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const
+{
+    const_iterator __i = find(__k);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    if (__i == end())
+        throw out_of_range("unordered_map::at: key not found");
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return __i->second;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+     unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
+            __i != __ex; ++__i)
+    {
+        const_iterator __j = __y.find(__i->first);
+        if (__j == __ey || !(*__i == *__j))
+            return false;
+    }
+    return true;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>,
+          class _Alloc = allocator<pair<const _Key, _Tp> > >
+class _LIBCPP_TYPE_VIS_ONLY unordered_multimap
+{
+public:
+    // types
+    typedef _Key                                           key_type;
+    typedef _Tp                                            mapped_type;
+    typedef _Hash                                          hasher;
+    typedef _Pred                                          key_equal;
+    typedef _Alloc                                         allocator_type;
+    typedef pair<const key_type, mapped_type>              value_type;
+    typedef pair<key_type, mapped_type>                    __nc_value_type;
+    typedef value_type&                                    reference;
+    typedef const value_type&                              const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
+
+private:
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
+    typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
+    typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+            rebind_alloc<__value_type>
+#else
+            rebind_alloc<__value_type>::other
+#endif
+                                                           __allocator_type;
+
+    typedef __hash_table<__value_type, __hasher,
+                         __key_equal,  __allocator_type>   __table;
+
+    __table __table_;
+
+    typedef typename __table::__node_traits                __node_traits;
+    typedef typename __table::__node_allocator             __node_allocator;
+    typedef typename __table::__node                       __node;
+    typedef __hash_map_node_destructor<__node_allocator>   _Dp;
+    typedef unique_ptr<__node, _Dp>                         __node_holder;
+    typedef allocator_traits<allocator_type>               __alloc_traits;
+public:
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+
+    typedef __hash_map_iterator<typename __table::iterator>       iterator;
+    typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator;
+    typedef __hash_map_iterator<typename __table::local_iterator> local_iterator;
+    typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap()
+        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(),
+                                const key_equal& __eql = key_equal());
+    unordered_multimap(size_type __n, const hasher& __hf,
+                                const key_equal& __eql,
+                                const allocator_type& __a);
+    template <class _InputIterator>
+        unordered_multimap(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        unordered_multimap(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        unordered_multimap(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf,
+                      const key_equal& __eql,
+                      const allocator_type& __a);
+    explicit unordered_multimap(const allocator_type& __a);
+    unordered_multimap(const unordered_multimap& __u);
+    unordered_multimap(const unordered_multimap& __u, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_multimap(unordered_multimap&& __u)
+        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
+    unordered_multimap(unordered_multimap&& __u, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_multimap(initializer_list<value_type> __il);
+    unordered_multimap(initializer_list<value_type> __il, size_type __n,
+                       const hasher& __hf = hasher(),
+                       const key_equal& __eql = key_equal());
+    unordered_multimap(initializer_list<value_type> __il, size_type __n,
+                       const hasher& __hf, const key_equal& __eql,
+                       const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 11
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(size_type __n, const allocator_type& __a)
+      : unordered_multimap(__n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_multimap(__n, __hf, key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a)
+      : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    _LIBCPP_INLINE_VISIBILITY
+      unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, 
+        const allocator_type& __a)
+      : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {}
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap(initializer_list<value_type> __il, size_type __n, const hasher& __hf, 
+      const allocator_type& __a)
+      : unordered_multimap(__il, __n, __hf, key_equal(), __a) {}
+#endif
+    // ~unordered_multimap() = default;
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multimap& operator=(const unordered_multimap& __u)
+    {
+#if __cplusplus >= 201103L
+        __table_ = __u.__table_;
+#else
+        if (this != &__u) {
+            __table_.clear();
+            __table_.hash_function() = __u.__table_.hash_function();
+            __table_.key_eq() = __u.__table_.key_eq();
+            __table_.max_load_factor() = __u.__table_.max_load_factor();
+            __table_.__copy_assign_alloc(__u.__table_);
+            insert(__u.begin(), __u.end());
+        }
+#endif
+        return *this;
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_multimap& operator=(unordered_multimap&& __u)
+        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
+#endif
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_multimap& operator=(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const _NOEXCEPT {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template <class... _Args>
+        iterator emplace(_Args&&... __args);
+
+    template <class... _Args>
+        iterator emplace_hint(const_iterator __p, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator insert(_Pp&& __x)
+            {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, const value_type& __x)
+        {return __table_.__insert_multi(__p.__i_, __x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _Pp,
+              class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator insert(const_iterator __p, _Pp&& __x)
+            {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __first, const_iterator __last)
+        {return __table_.erase(__first.__i_, __last.__i_);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(unordered_multimap& __u)
+        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
+        {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_function() const
+        {return __table_.hash_function().hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const
+        {return __table_.key_eq().key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_multi(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const _NOEXCEPT
+        {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_size(size_type __n) const
+        {return __table_.bucket_size(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       end(size_type __n)          {return __table_.end(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
+    _LIBCPP_INLINE_VISIBILITY
+    void rehash(size_type __n) {__table_.rehash(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(&__i->__i_);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(&__i->__i_);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(&__i->__i_, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __node_holder __construct_node();
+    template <class _A0>
+        __node_holder
+         __construct_node(_A0&& __a0);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _A0, class _A1, class ..._Args>
+        __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+};
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        const allocator_type& __a)
+    : __table_(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        const unordered_multimap& __u)
+    : __table_(__u.__table_)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        const unordered_multimap& __u, const allocator_type& __a)
+    : __table_(__u.__table_, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        unordered_multimap&& __u)
+    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
+    : __table_(_VSTD::move(__u.__table_))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        unordered_multimap&& __u, const allocator_type& __a)
+    : __table_(_VSTD::move(__u.__table_), __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a != __u.get_allocator())
+    {
+        iterator __i = __u.begin();
+        while (__u.size() != 0)
+        {
+            __table_.__insert_multi(
+                _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_)
+                                   );
+        }
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u)
+    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
+{
+    __table_ = _VSTD::move(__u.__table_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
+        initializer_list<value_type> __il)
+{
+    __table_.__assign_multi(__il.begin(), __il.end());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _A0>
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0));
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _A0, class _A1, class ..._Args>
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(
+        _A0&& __a0, _A1&& __a1, _Args&&... __args)
+{
+    __node_allocator& __na = __table_.__node_alloc();
+    __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
+    __node_traits::construct(__na, _VSTD::addressof(__h->__value_),
+                             _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
+                             _VSTD::forward<_Args>(__args)...);
+    __h.get_deleter().__first_constructed = true;
+    __h.get_deleter().__second_constructed = true;
+    return __h;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class... _Args>
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __table_.__node_insert_multi(__h.get());
+    __h.release();
+    return __r;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class... _Args>
+typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint(
+        const_iterator __p, _Args&&... __args)
+{
+    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
+    iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get());
+    __h.release();
+    return __r;
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                            _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_multi(*__first);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+     unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    typedef pair<const_iterator, const_iterator> _EqRng;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
+    {
+        _EqRng __xeq = __x.equal_range(__i->first);
+        _EqRng __yeq = __y.equal_range(__i->first);
+        if (_VSTD::distance(__xeq.first, __xeq.second) !=
+            _VSTD::distance(__yeq.first, __yeq.second) ||
+                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
+            return false;
+        __i = __xeq.second;
+    }
+    return true;
+}
+
+template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+           const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_UNORDERED_MAP
diff --git a/include/c++/v1/unordered_set b/include/c++/v1/unordered_set
new file mode 100644
index 0000000..fd378fa
--- /dev/null
+++ b/include/c++/v1/unordered_set
@@ -0,0 +1,1379 @@
+// -*- C++ -*-
+//===-------------------------- unordered_set -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_UNORDERED_SET
+#define _LIBCPP_UNORDERED_SET
+
+/*
+
+    unordered_set synopsis
+
+#include <initializer_list>
+
+namespace std
+{
+
+template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+          class Alloc = allocator<Value>>
+class unordered_set
+{
+public:
+    // types
+    typedef Value                                                      key_type;
+    typedef key_type                                                   value_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+    typedef /unspecified/ local_iterator;
+    typedef /unspecified/ const_local_iterator;
+
+    unordered_set()
+        noexcept(
+            is_nothrow_default_constructible<hasher>::value &&
+            is_nothrow_default_constructible<key_equal>::value &&
+            is_nothrow_default_constructible<allocator_type>::value);
+    explicit unordered_set(size_type n, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        unordered_set(InputIterator f, InputIterator l,
+                      size_type n = 0, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    explicit unordered_set(const allocator_type&);
+    unordered_set(const unordered_set&);
+    unordered_set(const unordered_set&, const Allocator&);
+    unordered_set(unordered_set&&)
+        noexcept(
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value &&
+            is_nothrow_move_constructible<allocator_type>::value);
+    unordered_set(unordered_set&&, const Allocator&);
+    unordered_set(initializer_list<value_type>, size_type n = 0,
+                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+                  const allocator_type& a = allocator_type());
+    unordered_set(size_type n, const allocator_type& a); // C++14
+    unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_set(InputIterator f, InputIterator l, size_type n, 
+                    const hasher& hf,  const allocator_type& a); // C++14
+    unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
+    unordered_set(initializer_list<value_type> il, size_type n,
+                  const hasher& hf,  const allocator_type& a); // C++14
+    ~unordered_set();
+    unordered_set& operator=(const unordered_set&);
+    unordered_set& operator=(unordered_set&&)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+    unordered_set& operator=(initializer_list<value_type>);
+
+    allocator_type get_allocator() const noexcept;
+
+    bool      empty() const noexcept;
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+
+    iterator       begin() noexcept;
+    iterator       end() noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cbegin() const noexcept;
+    const_iterator cend()   const noexcept;
+
+    template <class... Args>
+        pair<iterator, bool> emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    pair<iterator, bool> insert(const value_type& obj);
+    pair<iterator, bool> insert(value_type&& obj);
+    iterator insert(const_iterator hint, const value_type& obj);
+    iterator insert(const_iterator hint, value_type&& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type>);
+
+    iterator erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(unordered_set&)
+        noexcept(
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value) &&
+            __is_nothrow_swappable<hasher>::value &&
+            __is_nothrow_swappable<key_equal>::value);
+
+    hasher hash_function() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const noexcept;
+    size_type max_bucket_count() const noexcept;
+
+    size_type bucket_size(size_type n) const;
+    size_type bucket(const key_type& k) const;
+
+    local_iterator       begin(size_type n);
+    local_iterator       end(size_type n);
+    const_local_iterator begin(size_type n) const;
+    const_local_iterator end(size_type n) const;
+    const_local_iterator cbegin(size_type n) const;
+    const_local_iterator cend(size_type n) const;
+
+    float load_factor() const noexcept;
+    float max_load_factor() const noexcept;
+    void max_load_factor(float z);
+    void rehash(size_type n);
+    void reserve(size_type n);
+};
+
+template <class Value, class Hash, class Pred, class Alloc>
+    void swap(unordered_set<Value, Hash, Pred, Alloc>& x,
+              unordered_set<Value, Hash, Pred, Alloc>& y)
+              noexcept(noexcept(x.swap(y)));
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const unordered_set<Value, Hash, Pred, Alloc>& x,
+               const unordered_set<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x,
+               const unordered_set<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+          class Alloc = allocator<Value>>
+class unordered_multiset
+{
+public:
+    // types
+    typedef Value                                                      key_type;
+    typedef key_type                                                   value_type;
+    typedef Hash                                                       hasher;
+    typedef Pred                                                       key_equal;
+    typedef Alloc                                                      allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    typedef typename allocator_traits<allocator_type>::pointer         pointer;
+    typedef typename allocator_traits<allocator_type>::const_pointer   const_pointer;
+    typedef typename allocator_traits<allocator_type>::size_type       size_type;
+    typedef typename allocator_traits<allocator_type>::difference_type difference_type;
+
+    typedef /unspecified/ iterator;
+    typedef /unspecified/ const_iterator;
+    typedef /unspecified/ local_iterator;
+    typedef /unspecified/ const_local_iterator;
+
+    unordered_multiset()
+        noexcept(
+            is_nothrow_default_constructible<hasher>::value &&
+            is_nothrow_default_constructible<key_equal>::value &&
+            is_nothrow_default_constructible<allocator_type>::value);
+    explicit unordered_multiset(size_type n, const hasher& hf = hasher(),
+                           const key_equal& eql = key_equal(),
+                           const allocator_type& a = allocator_type());
+    template <class InputIterator>
+        unordered_multiset(InputIterator f, InputIterator l,
+                      size_type n = 0, const hasher& hf = hasher(),
+                      const key_equal& eql = key_equal(),
+                      const allocator_type& a = allocator_type());
+    explicit unordered_multiset(const allocator_type&);
+    unordered_multiset(const unordered_multiset&);
+    unordered_multiset(const unordered_multiset&, const Allocator&);
+    unordered_multiset(unordered_multiset&&)
+        noexcept(
+            is_nothrow_move_constructible<hasher>::value &&
+            is_nothrow_move_constructible<key_equal>::value &&
+            is_nothrow_move_constructible<allocator_type>::value);
+    unordered_multiset(unordered_multiset&&, const Allocator&);
+    unordered_multiset(initializer_list<value_type>, size_type n = /see below/,
+                  const hasher& hf = hasher(), const key_equal& eql = key_equal(),
+                  const allocator_type& a = allocator_type());
+    unordered_multiset(size_type n, const allocator_type& a); // C++14
+    unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14
+    template <class InputIterator>
+      unordered_multiset(InputIterator f, InputIterator l, size_type n,
+                         const hasher& hf, const allocator_type& a); // C++14
+    unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14
+    unordered_multiset(initializer_list<value_type> il, size_type n, 
+                       const hasher& hf,  const allocator_type& a); // C++14
+    ~unordered_multiset();
+    unordered_multiset& operator=(const unordered_multiset&);
+    unordered_multiset& operator=(unordered_multiset&&)
+        noexcept(
+            allocator_type::propagate_on_container_move_assignment::value &&
+            is_nothrow_move_assignable<allocator_type>::value &&
+            is_nothrow_move_assignable<hasher>::value &&
+            is_nothrow_move_assignable<key_equal>::value);
+    unordered_multiset& operator=(initializer_list<value_type>);
+
+    allocator_type get_allocator() const noexcept;
+
+    bool      empty() const noexcept;
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+
+    iterator       begin() noexcept;
+    iterator       end() noexcept;
+    const_iterator begin()  const noexcept;
+    const_iterator end()    const noexcept;
+    const_iterator cbegin() const noexcept;
+    const_iterator cend()   const noexcept;
+
+    template <class... Args>
+        iterator emplace(Args&&... args);
+    template <class... Args>
+        iterator emplace_hint(const_iterator position, Args&&... args);
+    iterator insert(const value_type& obj);
+    iterator insert(value_type&& obj);
+    iterator insert(const_iterator hint, const value_type& obj);
+    iterator insert(const_iterator hint, value_type&& obj);
+    template <class InputIterator>
+        void insert(InputIterator first, InputIterator last);
+    void insert(initializer_list<value_type>);
+
+    iterator erase(const_iterator position);
+    size_type erase(const key_type& k);
+    iterator erase(const_iterator first, const_iterator last);
+    void clear() noexcept;
+
+    void swap(unordered_multiset&)
+        noexcept(
+            (!allocator_type::propagate_on_container_swap::value ||
+             __is_nothrow_swappable<allocator_type>::value) &&
+            __is_nothrow_swappable<hasher>::value &&
+            __is_nothrow_swappable<key_equal>::value);
+
+    hasher hash_function() const;
+    key_equal key_eq() const;
+
+    iterator       find(const key_type& k);
+    const_iterator find(const key_type& k) const;
+    size_type count(const key_type& k) const;
+    pair<iterator, iterator>             equal_range(const key_type& k);
+    pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
+
+    size_type bucket_count() const noexcept;
+    size_type max_bucket_count() const noexcept;
+
+    size_type bucket_size(size_type n) const;
+    size_type bucket(const key_type& k) const;
+
+    local_iterator       begin(size_type n);
+    local_iterator       end(size_type n);
+    const_local_iterator begin(size_type n) const;
+    const_local_iterator end(size_type n) const;
+    const_local_iterator cbegin(size_type n) const;
+    const_local_iterator cend(size_type n) const;
+
+    float load_factor() const noexcept;
+    float max_load_factor() const noexcept;
+    void max_load_factor(float z);
+    void rehash(size_type n);
+    void reserve(size_type n);
+};
+
+template <class Value, class Hash, class Pred, class Alloc>
+    void swap(unordered_multiset<Value, Hash, Pred, Alloc>& x,
+              unordered_multiset<Value, Hash, Pred, Alloc>& y)
+              noexcept(noexcept(x.swap(y)));
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
+               const unordered_multiset<Value, Hash, Pred, Alloc>& y);
+
+template <class Value, class Hash, class Pred, class Alloc>
+    bool
+    operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x,
+               const unordered_multiset<Value, Hash, Pred, Alloc>& y);
+}  // std
+
+*/
+
+#include <__config>
+#include <__hash_table>
+#include <functional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
+          class _Alloc = allocator<_Value> >
+class _LIBCPP_TYPE_VIS_ONLY unordered_set
+{
+public:
+    // types
+    typedef _Value                                                     key_type;
+    typedef key_type                                                   value_type;
+    typedef _Hash                                                      hasher;
+    typedef _Pred                                                      key_equal;
+    typedef _Alloc                                                     allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
+
+private:
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+
+    __table __table_;
+
+public:
+    typedef typename __table::pointer         pointer;
+    typedef typename __table::const_pointer   const_pointer;
+    typedef typename __table::size_type       size_type;
+    typedef typename __table::difference_type difference_type;
+
+    typedef typename __table::const_iterator       iterator;
+    typedef typename __table::const_iterator       const_iterator;
+    typedef typename __table::const_local_iterator local_iterator;
+    typedef typename __table::const_local_iterator const_local_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_set()
+        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    explicit unordered_set(size_type __n, const hasher& __hf = hasher(),
+                           const key_equal& __eql = key_equal());
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(size_type __n, const allocator_type& __a)
+        : unordered_set(__n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_set(__n, __hf, key_equal(), __a) {}
+#endif
+    unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+                  const allocator_type& __a);
+    template <class _InputIterator>
+        unordered_set(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        unordered_set(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        unordered_set(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf, const key_equal& __eql,
+                      const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+        unordered_set(_InputIterator __first, _InputIterator __last, 
+                    size_type __n, const allocator_type& __a)
+            : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+        unordered_set(_InputIterator __first, _InputIterator __last, 
+                      size_type __n, const hasher& __hf, const allocator_type& __a)
+            : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {}
+#endif
+    explicit unordered_set(const allocator_type& __a);
+    unordered_set(const unordered_set& __u);
+    unordered_set(const unordered_set& __u, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_set(unordered_set&& __u)
+        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
+    unordered_set(unordered_set&& __u, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_set(initializer_list<value_type> __il);
+    unordered_set(initializer_list<value_type> __il, size_type __n,
+                  const hasher& __hf = hasher(),
+                  const key_equal& __eql = key_equal());
+    unordered_set(initializer_list<value_type> __il, size_type __n,
+                  const hasher& __hf, const key_equal& __eql,
+                  const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(initializer_list<value_type> __il, size_type __n,
+                                                      const allocator_type& __a)
+        : unordered_set(__il, __n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_set(initializer_list<value_type> __il, size_type __n, 
+                                  const hasher& __hf, const allocator_type& __a)
+        : unordered_set(__il, __n, __hf, key_equal(), __a) {}
+#endif
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    // ~unordered_set() = default;
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_set& operator=(const unordered_set& __u)
+    {
+        __table_ = __u.__table_;
+        return *this;
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_set& operator=(unordered_set&& __u)
+        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
+#endif
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_set& operator=(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const _NOEXCEPT {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        pair<iterator, bool> emplace(_Args&&... __args)
+            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
+                " referring to this unordered_set");
+            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
+        }
+#else
+        iterator emplace_hint(const_iterator, _Args&&... __args)
+            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}
+#endif
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> insert(const value_type& __x)
+        {return __table_.__insert_unique(__x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, bool> insert(value_type&& __x)
+        {return __table_.__insert_unique(_VSTD::move(__x));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, const value_type& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
+                " referring to this unordered_set");
+            return insert(__x).first;
+        }
+#else
+    iterator insert(const_iterator, const value_type& __x)
+        {return insert(__x).first;}
+#endif
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    iterator insert(const_iterator __p, value_type&& __x)
+        {
+            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
+                "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
+                " referring to this unordered_set");
+            return insert(_VSTD::move(__x)).first;
+        }
+#else
+    iterator insert(const_iterator, value_type&& __x)
+        {return insert(_VSTD::move(__x)).first;}
+#endif
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __table_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __first, const_iterator __last)
+        {return __table_.erase(__first, __last);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(unordered_set& __u)
+        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
+        {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_function() const {return __table_.hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const {return __table_.key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_unique(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_unique(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       end(size_type __n)          {return __table_.end(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
+    _LIBCPP_INLINE_VISIBILITY
+    void rehash(size_type __n) {__table_.rehash(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(__i);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(__i);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+};
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        const allocator_type& __a)
+    : __table_(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        const unordered_set& __u)
+    : __table_(__u.__table_)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        const unordered_set& __u, const allocator_type& __a)
+    : __table_(__u.__table_, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        unordered_set&& __u)
+    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
+    : __table_(_VSTD::move(__u.__table_))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        unordered_set&& __u, const allocator_type& __a)
+    : __table_(_VSTD::move(__u.__table_), __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a != __u.get_allocator())
+    {
+        iterator __i = __u.begin();
+        while (__u.size() != 0)
+            __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_));
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_set<_Value, _Hash, _Pred, _Alloc>&
+unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u)
+    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
+{
+    __table_ = _VSTD::move(__u.__table_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_set<_Value, _Hash, _Pred, _Alloc>&
+unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(
+        initializer_list<value_type> __il)
+{
+    __table_.__assign_unique(__il.begin(), __il.end());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                    _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_unique(*__first);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename unordered_set<_Value, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(), __ey = __y.end();
+            __i != __ex; ++__i)
+    {
+        const_iterator __j = __y.find(*__i);
+        if (__j == __ey || !(*__i == *__j))
+            return false;
+    }
+    return true;
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+           const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>,
+          class _Alloc = allocator<_Value> >
+class _LIBCPP_TYPE_VIS_ONLY unordered_multiset
+{
+public:
+    // types
+    typedef _Value                                                     key_type;
+    typedef key_type                                                   value_type;
+    typedef _Hash                                                      hasher;
+    typedef _Pred                                                      key_equal;
+    typedef _Alloc                                                     allocator_type;
+    typedef value_type&                                                reference;
+    typedef const value_type&                                          const_reference;
+    static_assert((is_same<value_type, typename allocator_type::value_type>::value),
+                  "Invalid allocator::value_type");
+
+private:
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+
+    __table __table_;
+
+public:
+    typedef typename __table::pointer         pointer;
+    typedef typename __table::const_pointer   const_pointer;
+    typedef typename __table::size_type       size_type;
+    typedef typename __table::difference_type difference_type;
+
+    typedef typename __table::const_iterator       iterator;
+    typedef typename __table::const_iterator       const_iterator;
+    typedef typename __table::const_local_iterator local_iterator;
+    typedef typename __table::const_local_iterator const_local_iterator;
+
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset()
+        _NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(),
+                                const key_equal& __eql = key_equal());
+    unordered_multiset(size_type __n, const hasher& __hf,
+                       const key_equal& __eql, const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(size_type __n, const allocator_type& __a)
+        : unordered_multiset(__n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multiset(__n, __hf, key_equal(), __a) {}
+#endif
+    template <class _InputIterator>
+        unordered_multiset(_InputIterator __first, _InputIterator __last);
+    template <class _InputIterator>
+        unordered_multiset(_InputIterator __first, _InputIterator __last,
+                      size_type __n, const hasher& __hf = hasher(),
+                      const key_equal& __eql = key_equal());
+    template <class _InputIterator>
+        unordered_multiset(_InputIterator __first, _InputIterator __last,
+                      size_type __n , const hasher& __hf,
+                      const key_equal& __eql, const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(_InputIterator __first, _InputIterator __last, 
+                       size_type __n, const allocator_type& __a)
+        : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) {}
+    template <class _InputIterator>
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(_InputIterator __first, _InputIterator __last,
+                       size_type __n, const hasher& __hf, const allocator_type& __a)
+        : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {}
+#endif
+    explicit unordered_multiset(const allocator_type& __a);
+    unordered_multiset(const unordered_multiset& __u);
+    unordered_multiset(const unordered_multiset& __u, const allocator_type& __a);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_multiset(unordered_multiset&& __u)
+        _NOEXCEPT_(is_nothrow_move_constructible<__table>::value);
+    unordered_multiset(unordered_multiset&& __u, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_multiset(initializer_list<value_type> __il);
+    unordered_multiset(initializer_list<value_type> __il, size_type __n,
+                       const hasher& __hf = hasher(),
+                       const key_equal& __eql = key_equal());
+    unordered_multiset(initializer_list<value_type> __il, size_type __n,
+                       const hasher& __hf, const key_equal& __eql,
+                       const allocator_type& __a);
+#if _LIBCPP_STD_VER > 11
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a)
+      : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {}
+    inline _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset(initializer_list<value_type> __il, size_type __n, const hasher& __hf, const allocator_type& __a)
+      : unordered_multiset(__il, __n, __hf, key_equal(), __a) {}
+#endif
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    // ~unordered_multiset() = default;
+    _LIBCPP_INLINE_VISIBILITY
+    unordered_multiset& operator=(const unordered_multiset& __u)
+    {
+        __table_ = __u.__table_;
+        return *this;
+    }
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    unordered_multiset& operator=(unordered_multiset&& __u)
+        _NOEXCEPT_(is_nothrow_move_assignable<__table>::value);
+#endif
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    unordered_multiset& operator=(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(__table_.__node_alloc());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool      empty() const _NOEXCEPT {return __table_.size() == 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT  {return __table_.size();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_size() const _NOEXCEPT {return __table_.max_size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       begin() _NOEXCEPT        {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       end() _NOEXCEPT          {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin()  const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()    const _NOEXCEPT {return __table_.end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cbegin() const _NOEXCEPT {return __table_.begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator cend()   const _NOEXCEPT {return __table_.end();}
+
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator emplace(_Args&&... __args)
+            {return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);}
+    template <class... _Args>
+        _LIBCPP_INLINE_VISIBILITY
+        iterator emplace_hint(const_iterator __p, _Args&&... __args)
+            {return __table_.__emplace_hint_multi(__p, _VSTD::forward<_Args>(__args)...);}
+#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, const value_type& __x)
+        {return __table_.__insert_multi(__p, __x);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __p, value_type&& __x)
+        {return __table_.__insert_multi(__p, _VSTD::move(__x));}
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    template <class _InputIterator>
+        void insert(_InputIterator __first, _InputIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void insert(initializer_list<value_type> __il)
+        {insert(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __p) {return __table_.erase(__p);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator erase(const_iterator __first, const_iterator __last)
+        {return __table_.erase(__first, __last);}
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__table_.clear();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void swap(unordered_multiset& __u)
+        _NOEXCEPT_(__is_nothrow_swappable<__table>::value)
+        {__table_.swap(__u.__table_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    hasher hash_function() const {return __table_.hash_function();}
+    _LIBCPP_INLINE_VISIBILITY
+    key_equal key_eq() const {return __table_.key_eq();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       find(const key_type& __k)       {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator find(const key_type& __k) const {return __table_.find(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type count(const key_type& __k) const {return __table_.__count_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<iterator, iterator>             equal_range(const key_type& __k)
+        {return __table_.__equal_range_multi(__k);}
+    _LIBCPP_INLINE_VISIBILITY
+    pair<const_iterator, const_iterator> equal_range(const key_type& __k) const
+        {return __table_.__equal_range_multi(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket_size(size_type __n) const {return __table_.bucket_size(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type bucket(const key_type& __k) const {return __table_.bucket(__k);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       begin(size_type __n)        {return __table_.begin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    local_iterator       end(size_type __n)          {return __table_.end(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator begin(size_type __n) const  {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator end(size_type __n) const    {return __table_.cend(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_local_iterator cend(size_type __n) const   {return __table_.cend(__n);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    float load_factor() const _NOEXCEPT {return __table_.load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();}
+    _LIBCPP_INLINE_VISIBILITY
+    void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);}
+    _LIBCPP_INLINE_VISIBILITY
+    void rehash(size_type __n) {__table_.rehash(__n);}
+    _LIBCPP_INLINE_VISIBILITY
+    void reserve(size_type __n) {__table_.reserve(__n);}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const
+        {return __table_.__dereferenceable(__i);}
+    bool __decrementable(const const_iterator* __i) const
+        {return __table_.__decrementable(__i);}
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+        {return __table_.__addable(__i, __n);}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+};
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        size_type __n, const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        size_type __n, const hasher& __hf, const key_equal& __eql,
+        const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        _InputIterator __first, _InputIterator __last, size_type __n,
+        const hasher& __hf, const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__first, __last);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        const allocator_type& __a)
+    : __table_(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        const unordered_multiset& __u)
+    : __table_(__u.__table_)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        const unordered_multiset& __u, const allocator_type& __a)
+    : __table_(__u.__table_, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__u.bucket_count());
+    insert(__u.begin(), __u.end());
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        unordered_multiset&& __u)
+    _NOEXCEPT_(is_nothrow_move_constructible<__table>::value)
+    : __table_(_VSTD::move(__u.__table_))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__u);
+#endif
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        unordered_multiset&& __u, const allocator_type& __a)
+    : __table_(_VSTD::move(__u.__table_), __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a != __u.get_allocator())
+    {
+        iterator __i = __u.begin();
+        while (__u.size() != 0)
+            __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_));
+    }
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    else
+        __get_db()->swap(this, &__u);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql)
+    : __table_(__hf, __eql)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset(
+        initializer_list<value_type> __il, size_type __n, const hasher& __hf,
+        const key_equal& __eql, const allocator_type& __a)
+    : __table_(__hf, __eql, __a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    __table_.rehash(__n);
+    insert(__il.begin(), __il.end());
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
+        unordered_multiset&& __u)
+    _NOEXCEPT_(is_nothrow_move_assignable<__table>::value)
+{
+    __table_ = _VSTD::move(__u.__table_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>&
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=(
+        initializer_list<value_type> __il)
+{
+    __table_.__assign_multi(__il.begin(), __il.end());
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+template <class _InputIterator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first,
+                                                         _InputIterator __last)
+{
+    for (; __first != __last; ++__first)
+        __table_.__insert_multi(*__first);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+bool
+operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    if (__x.size() != __y.size())
+        return false;
+    typedef typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::const_iterator
+                                                                 const_iterator;
+    typedef pair<const_iterator, const_iterator> _EqRng;
+    for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;)
+    {
+        _EqRng __xeq = __x.equal_range(*__i);
+        _EqRng __yeq = __y.equal_range(*__i);
+        if (_VSTD::distance(__xeq.first, __xeq.second) !=
+            _VSTD::distance(__yeq.first, __yeq.second) ||
+                  !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first))
+            return false;
+        __i = __xeq.second;
+    }
+    return true;
+}
+
+template <class _Value, class _Hash, class _Pred, class _Alloc>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+{
+    return !(__x == __y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_UNORDERED_SET
diff --git a/include/c++/v1/utility b/include/c++/v1/utility
new file mode 100644
index 0000000..4eafda4
--- /dev/null
+++ b/include/c++/v1/utility
@@ -0,0 +1,768 @@
+// -*- C++ -*-
+//===-------------------------- utility -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_UTILITY
+#define _LIBCPP_UTILITY
+
+/*
+    utility synopsis
+
+namespace std
+{
+
+template <class T>
+    void
+    swap(T& a, T& b);
+
+namespace rel_ops
+{
+    template<class T> bool operator!=(const T&, const T&);
+    template<class T> bool operator> (const T&, const T&);
+    template<class T> bool operator<=(const T&, const T&);
+    template<class T> bool operator>=(const T&, const T&);
+}
+
+template<class T>
+void
+swap(T& a, T& b) noexcept(is_nothrow_move_constructible<T>::value &&
+                          is_nothrow_move_assignable<T>::value);
+
+template <class T, size_t N>
+void
+swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
+
+template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;  // constexpr in C++14
+template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; // constexpr in C++14
+
+template <class T> typename remove_reference<T>::type&& move(T&&) noexcept;      // constexpr in C++14
+
+template <class T>
+    typename conditional
+    <
+        !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
+        const T&,
+        T&&
+    >::type
+    move_if_noexcept(T& x) noexcept; // constexpr in C++14
+
+template <class T> typename add_rvalue_reference<T>::type declval() noexcept;
+
+template <class T1, class T2>
+struct pair
+{
+    typedef T1 first_type;
+    typedef T2 second_type;
+
+    T1 first;
+    T2 second;
+
+    pair(const pair&) = default;
+    pair(pair&&) = default;
+    constexpr pair();
+    pair(const T1& x, const T2& y);                          // constexpr in C++14
+    template <class U, class V> pair(U&& x, V&& y);          // constexpr in C++14
+    template <class U, class V> pair(const pair<U, V>& p);   // constexpr in C++14
+    template <class U, class V> pair(pair<U, V>&& p);        // constexpr in C++14
+    template <class... Args1, class... Args2>
+        pair(piecewise_construct_t, tuple<Args1...> first_args,
+             tuple<Args2...> second_args);
+
+    template <class U, class V> pair& operator=(const pair<U, V>& p);
+    pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
+                                       is_nothrow_move_assignable<T2>::value);
+    template <class U, class V> pair& operator=(pair<U, V>&& p);
+
+    void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
+                                noexcept(swap(second, p.second)));
+};
+
+template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
+
+template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);   // constexpr in C++14
+template <class T1, class T2>
+void
+swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
+
+struct piecewise_construct_t { };
+constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+
+template <class T> class tuple_size;
+template <size_t I, class T> class tuple_element;
+
+template <class T1, class T2> struct tuple_size<pair<T1, T2> >;
+template <class T1, class T2> struct tuple_element<0, pair<T1, T2> >;
+template <class T1, class T2> struct tuple_element<1, pair<T1, T2> >;
+
+template<size_t I, class T1, class T2>
+    typename tuple_element<I, pair<T1, T2> >::type&
+    get(pair<T1, T2>&) noexcept; // constexpr in C++14
+
+template<size_t I, class T1, class T2>
+    const typename const tuple_element<I, pair<T1, T2> >::type&
+    get(const pair<T1, T2>&) noexcept; // constexpr in C++14
+
+template<size_t I, class T1, class T2>
+    typename tuple_element<I, pair<T1, T2> >::type&&
+    get(pair<T1, T2>&&) noexcept; // constexpr in C++14
+
+template<class T1, class T2>
+    constexpr T1& get(pair<T1, T2>&) noexcept; // C++14
+
+template<size_t I, class T1, class T2>
+    constexpr T1 const& get(pair<T1, T2> const &) noexcept; // C++14
+
+template<size_t I, class T1, class T2>
+    constexpr T1&& get(pair<T1, T2>&&) noexcept; // C++14
+
+// C++14
+
+template<class T, T... I>
+struct integer_sequence
+{
+    typedef T value_type;
+
+    static constexpr size_t size() noexcept;
+};
+
+template<size_t... I>
+  using index_sequence = integer_sequence<size_t, I...>;
+
+template<class T, T N>
+  using make_integer_sequence = integer_sequence<T, 0, 1, ..., N-1>;
+template<size_t N>
+  using make_index_sequence = make_integer_sequence<size_t, N>;
+
+template<class... T>
+  using index_sequence_for = make_index_sequence<sizeof...(T)>;
+
+template<class T, class U=T> 
+    T exchange(T& obj, U&& new_value);
+}  // std
+
+*/
+
+#include <__config>
+#include <__tuple>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace rel_ops
+{
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__x == __y);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const _Tp& __x, const _Tp& __y)
+{
+    return __y < __x;
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__y < __x);
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const _Tp& __x, const _Tp& __y)
+{
+    return !(__x < __y);
+}
+
+}  // rel_ops
+
+// swap_ranges
+
+template <class _ForwardIterator1, class _ForwardIterator2>
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator2
+swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)
+{
+    for(; __first1 != __last1; ++__first1, ++__first2)
+        swap(*__first1, *__first2);
+    return __first2;
+}
+
+template<class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
+{
+    _VSTD::swap_ranges(__a, __a + _Np, __b);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+typename conditional
+<
+    !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value,
+    const _Tp&,
+    _Tp&&
+>::type
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+const _Tp&
+#endif
+move_if_noexcept(_Tp& __x) _NOEXCEPT
+{
+    return _VSTD::move(__x);
+}
+
+struct _LIBCPP_TYPE_VIS_ONLY piecewise_construct_t { };
+#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_UTILITY)
+extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
+#else
+constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
+#endif
+
+template <class _T1, class _T2>
+struct _LIBCPP_TYPE_VIS_ONLY pair
+{
+    typedef _T1 first_type;
+    typedef _T2 second_type;
+
+    _T1 first;
+    _T2 second;
+
+    // pair(const pair&) = default;
+    // pair(pair&&) = default;
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {}
+
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    pair(const _T1& __x, const _T2& __y)
+        : first(__x), second(__y) {}
+
+    template<class _U1, class _U2>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        pair(const pair<_U1, _U2>& __p
+#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+                 ,typename enable_if<is_convertible<const _U1&, _T1>::value &&
+                                    is_convertible<const _U2&, _T2>::value>::type* = 0
+#endif
+                                      )
+            : first(__p.first), second(__p.second) {}
+
+#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+    _LIBCPP_INLINE_VISIBILITY
+    pair(const pair& __p) = default;
+#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+    _LIBCPP_INLINE_VISIBILITY
+    pair(const pair& __p)
+        _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
+                   is_nothrow_copy_constructible<second_type>::value)
+        : first(__p.first),
+          second(__p.second)
+    {
+    }
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair& operator=(const pair& __p)
+        _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
+                   is_nothrow_copy_assignable<second_type>::value)
+    {
+        first = __p.first;
+        second = __p.second;
+        return *this;
+    }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class _U1, class _U2,
+              class = typename enable_if<is_convertible<_U1, first_type>::value &&
+                                         is_convertible<_U2, second_type>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        pair(_U1&& __u1, _U2&& __u2)
+            : first(_VSTD::forward<_U1>(__u1)),
+              second(_VSTD::forward<_U2>(__u2))
+            {}
+
+    template<class _U1, class _U2>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        pair(pair<_U1, _U2>&& __p,
+                 typename enable_if<is_convertible<_U1, _T1>::value &&
+                                    is_convertible<_U2, _T2>::value>::type* = 0)
+            : first(_VSTD::forward<_U1>(__p.first)),
+              second(_VSTD::forward<_U2>(__p.second)) {}
+
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    _LIBCPP_INLINE_VISIBILITY
+    pair(pair&& __p) = default;
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value &&
+                                is_nothrow_move_constructible<second_type>::value)
+        : first(_VSTD::forward<first_type>(__p.first)),
+          second(_VSTD::forward<second_type>(__p.second))
+    {
+    }
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    pair&
+    operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
+                                     is_nothrow_move_assignable<second_type>::value)
+    {
+        first = _VSTD::forward<first_type>(__p.first);
+        second = _VSTD::forward<second_type>(__p.second);
+        return *this;
+    }
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+    template<class _Tuple,
+             class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+        pair(_Tuple&& __p)
+            : first(_VSTD::forward<typename tuple_element<0,
+                                  typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<0>(__p))),
+              second(_VSTD::forward<typename tuple_element<1,
+                                   typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<1>(__p)))
+            {}
+
+
+
+    template <class... _Args1, class... _Args2>
+        _LIBCPP_INLINE_VISIBILITY
+        pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
+                                    tuple<_Args2...> __second_args)
+            : pair(__pc, __first_args, __second_args,
+                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),
+                   typename __make_tuple_indices<sizeof...(_Args2) >::type())
+            {}
+
+    template <class _Tuple,
+              class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type>
+        _LIBCPP_INLINE_VISIBILITY
+        pair&
+        operator=(_Tuple&& __p)
+        {
+            typedef typename __make_tuple_types<_Tuple>::type _TupleRef;
+            typedef typename tuple_element<0, _TupleRef>::type _U0;
+            typedef typename tuple_element<1, _TupleRef>::type _U1;
+            first  = _VSTD::forward<_U0>(_VSTD::get<0>(__p));
+            second = _VSTD::forward<_U1>(_VSTD::get<1>(__p));
+            return *this;
+        }
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    void
+    swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
+                               __is_nothrow_swappable<second_type>::value)
+    {
+        _VSTD::iter_swap(&first, &__p.first);
+        _VSTD::iter_swap(&second, &__p.second);
+    }
+private:
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
+        _LIBCPP_INLINE_VISIBILITY
+        pair(piecewise_construct_t,
+             tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
+             __tuple_indices<_I1...>, __tuple_indices<_I2...>);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+};
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __x.first == __y.first && __x.second == __y.second;
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return __y < __x;
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+bool
+operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_swappable<_T1>::value &&
+    __is_swappable<_T2>::value,
+    void
+>::type
+swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
+                     _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
+                                 __is_nothrow_swappable<_T2>::value))
+{
+    __x.swap(__y);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
+
+template <class _Tp>
+struct __make_pair_return_impl
+{
+    typedef _Tp type;
+};
+
+template <class _Tp>
+struct __make_pair_return_impl<reference_wrapper<_Tp>>
+{
+    typedef _Tp& type;
+};
+
+template <class _Tp>
+struct __make_pair_return
+{
+    typedef typename __make_pair_return_impl<typename decay<_Tp>::type>::type type;
+};
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
+make_pair(_T1&& __t1, _T2&& __t2)
+{
+    return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type>
+               (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
+}
+
+#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_T1,_T2>
+make_pair(_T1 __x, _T2 __y)
+{
+    return pair<_T1, _T2>(__x, __y);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _T1, class _T2>
+  class _LIBCPP_TYPE_VIS_ONLY tuple_size<pair<_T1, _T2> >
+    : public integral_constant<size_t, 2> {};
+
+template <class _T1, class _T2>
+  class _LIBCPP_TYPE_VIS_ONLY tuple_size<const pair<_T1, _T2> >
+    : public integral_constant<size_t, 2> {};
+
+template <class _T1, class _T2>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> >
+{
+public:
+    typedef _T1 type;
+};
+
+template <class _T1, class _T2>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, pair<_T1, _T2> >
+{
+public:
+    typedef _T2 type;
+};
+
+template <class _T1, class _T2>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, const pair<_T1, _T2> >
+{
+public:
+    typedef const _T1 type;
+};
+
+template <class _T1, class _T2>
+class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, const pair<_T1, _T2> >
+{
+public:
+    typedef const _T2 type;
+};
+
+template <size_t _Ip> struct __get_pair;
+
+template <>
+struct __get_pair<0>
+{
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T1&
+    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
+
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _T1&
+    get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T1&&
+    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+};
+
+template <>
+struct __get_pair<1>
+{
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T2&
+    get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
+
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    const _T2&
+    get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class _T1, class _T2>
+    static
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+    _T2&&
+    get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+};
+
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&
+get(pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<_Ip>::get(__p);
+}
+
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
+get(const pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<_Ip>::get(__p);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <size_t _Ip, class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
+get(pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    return __get_pair<_Ip>::get(_VSTD::move(__p));
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#if _LIBCPP_STD_VER > 11
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
+{
+    return __get_pair<0>::get(_VSTD::move(__p));
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(__p);
+}
+
+template <class _T1, class _T2>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
+{
+    return __get_pair<1>::get(_VSTD::move(__p));
+}
+
+#endif
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp, _Tp... _Ip>
+struct _LIBCPP_TYPE_VIS_ONLY integer_sequence
+{
+    typedef _Tp value_type;
+    static_assert( is_integral<_Tp>::value,
+                  "std::integer_sequence can only be instantiated with an integral type" );
+    static
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr
+    size_t
+    size() noexcept { return sizeof...(_Ip); }
+};
+
+template<size_t... _Ip>
+    using index_sequence = integer_sequence<size_t, _Ip...>;
+
+namespace __detail {
+
+template<typename _Tp, size_t ..._Extra> struct __repeat;
+template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...> {
+  typedef integer_sequence<_Tp,
+                           _Np...,
+                           sizeof...(_Np) + _Np...,
+                           2 * sizeof...(_Np) + _Np...,
+                           3 * sizeof...(_Np) + _Np...,
+                           4 * sizeof...(_Np) + _Np...,
+                           5 * sizeof...(_Np) + _Np...,
+                           6 * sizeof...(_Np) + _Np...,
+                           7 * sizeof...(_Np) + _Np...,
+                           _Extra...> type;
+};
+
+template<size_t _Np> struct __parity;
+template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {};
+
+template<> struct __make<0> { typedef integer_sequence<size_t> type; };
+template<> struct __make<1> { typedef integer_sequence<size_t, 0> type; };
+template<> struct __make<2> { typedef integer_sequence<size_t, 0, 1> type; };
+template<> struct __make<3> { typedef integer_sequence<size_t, 0, 1, 2> type; };
+template<> struct __make<4> { typedef integer_sequence<size_t, 0, 1, 2, 3> type; };
+template<> struct __make<5> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4> type; };
+template<> struct __make<6> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; };
+template<> struct __make<7> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; };
+
+template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; };
+template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; };
+template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; };
+
+template<typename _Tp, typename _Up> struct __convert {
+  template<typename> struct __result;
+  template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...> > { typedef integer_sequence<_Up, _Np...> type; };
+};
+template<typename _Tp> struct __convert<_Tp, _Tp> { template<typename _Up> struct __result { typedef _Up type; }; };
+
+}
+
+template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked =
+  typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type;
+
+template <class _Tp, _Tp _Ep>
+struct __make_integer_sequence
+{
+    static_assert(is_integral<_Tp>::value,
+                  "std::make_integer_sequence can only be instantiated with an integral type" );
+    static_assert(0 <= _Ep, "std::make_integer_sequence input shall not be negative");
+    typedef __make_integer_sequence_unchecked<_Tp, _Ep> type;
+};
+
+template<class _Tp, _Tp _Np>
+    using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type;
+
+template<size_t _Np>
+    using make_index_sequence = make_integer_sequence<size_t, _Np>;
+
+template<class... _Tp>
+    using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
+  
+#endif  // _LIBCPP_STD_VER > 11
+
+#if _LIBCPP_STD_VER > 11
+template<class _T1, class _T2 = _T1>
+inline _LIBCPP_INLINE_VISIBILITY
+_T1 exchange(_T1& __obj, _T2 && __new_value)
+{
+    _T1 __old_value = _VSTD::move(__obj);
+    __obj = _VSTD::forward<_T2>(__new_value);
+    return __old_value;
+}    
+#endif  // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_UTILITY
diff --git a/include/c++/v1/valarray b/include/c++/v1/valarray
new file mode 100644
index 0000000..3714350
--- /dev/null
+++ b/include/c++/v1/valarray
@@ -0,0 +1,4780 @@
+// -*- C++ -*-
+//===-------------------------- valarray ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_VALARRAY
+#define _LIBCPP_VALARRAY
+
+/*
+    valarray synopsis
+
+namespace std
+{
+
+template<class T>
+class valarray
+{
+public:
+    typedef T value_type;
+
+    // construct/destroy:
+    valarray();
+    explicit valarray(size_t n);
+    valarray(const value_type& x, size_t n);
+    valarray(const value_type* px, size_t n);
+    valarray(const valarray& v);
+    valarray(valarray&& v) noexcept;
+    valarray(const slice_array<value_type>& sa);
+    valarray(const gslice_array<value_type>& ga);
+    valarray(const mask_array<value_type>& ma);
+    valarray(const indirect_array<value_type>& ia);
+    valarray(initializer_list<value_type> il);
+    ~valarray();
+
+    // assignment:
+    valarray& operator=(const valarray& v);
+    valarray& operator=(valarray&& v) noexcept;
+    valarray& operator=(initializer_list<value_type> il);
+    valarray& operator=(const value_type& x);
+    valarray& operator=(const slice_array<value_type>& sa);
+    valarray& operator=(const gslice_array<value_type>& ga);
+    valarray& operator=(const mask_array<value_type>& ma);
+    valarray& operator=(const indirect_array<value_type>& ia);
+
+    // element access:
+    const value_type& operator[](size_t i) const;
+    value_type&       operator[](size_t i);
+
+    // subset operations:
+    valarray                   operator[](slice s) const;
+    slice_array<value_type>    operator[](slice s);
+    valarray                   operator[](const gslice& gs) const;
+    gslice_array<value_type>   operator[](const gslice& gs);
+    valarray                   operator[](const valarray<bool>& vb) const;
+    mask_array<value_type>     operator[](const valarray<bool>& vb);
+    valarray                   operator[](const valarray<size_t>& vs) const;
+    indirect_array<value_type> operator[](const valarray<size_t>& vs);
+
+    // unary operators:
+    valarray       operator+() const;
+    valarray       operator-() const;
+    valarray       operator~() const;
+    valarray<bool> operator!() const;
+
+    // computed assignment:
+    valarray& operator*= (const value_type& x);
+    valarray& operator/= (const value_type& x);
+    valarray& operator%= (const value_type& x);
+    valarray& operator+= (const value_type& x);
+    valarray& operator-= (const value_type& x);
+    valarray& operator^= (const value_type& x);
+    valarray& operator&= (const value_type& x);
+    valarray& operator|= (const value_type& x);
+    valarray& operator<<=(const value_type& x);
+    valarray& operator>>=(const value_type& x);
+
+    valarray& operator*= (const valarray& v);
+    valarray& operator/= (const valarray& v);
+    valarray& operator%= (const valarray& v);
+    valarray& operator+= (const valarray& v);
+    valarray& operator-= (const valarray& v);
+    valarray& operator^= (const valarray& v);
+    valarray& operator|= (const valarray& v);
+    valarray& operator&= (const valarray& v);
+    valarray& operator<<=(const valarray& v);
+    valarray& operator>>=(const valarray& v);
+
+    // member functions:
+    void swap(valarray& v) noexcept;
+
+    size_t size() const;
+
+    value_type sum() const;
+    value_type min() const;
+    value_type max() const;
+
+    valarray shift (int i) const;
+    valarray cshift(int i) const;
+    valarray apply(value_type f(value_type)) const;
+    valarray apply(value_type f(const value_type&)) const;
+    void resize(size_t n, value_type x = value_type());
+};
+
+class slice
+{
+public:
+    slice();
+    slice(size_t start, size_t size, size_t stride);
+
+    size_t start()  const;
+    size_t size()   const;
+    size_t stride() const;
+};
+
+template <class T>
+class slice_array
+{
+public:
+    typedef T value_type;
+
+    const slice_array& operator=(const slice_array& sa) const;
+    void operator=  (const valarray<value_type>& v) const;
+    void operator*= (const valarray<value_type>& v) const;
+    void operator/= (const valarray<value_type>& v) const;
+    void operator%= (const valarray<value_type>& v) const;
+    void operator+= (const valarray<value_type>& v) const;
+    void operator-= (const valarray<value_type>& v) const;
+    void operator^= (const valarray<value_type>& v) const;
+    void operator&= (const valarray<value_type>& v) const;
+    void operator|= (const valarray<value_type>& v) const;
+    void operator<<=(const valarray<value_type>& v) const;
+    void operator>>=(const valarray<value_type>& v) const;
+
+    void operator=(const value_type& x) const;
+
+    slice_array() = delete;
+};
+
+class gslice
+{
+public:
+    gslice();
+    gslice(size_t start, const valarray<size_t>& size,
+                         const valarray<size_t>& stride);
+
+    size_t           start()  const;
+    valarray<size_t> size()   const;
+    valarray<size_t> stride() const;
+};
+
+template <class T>
+class gslice_array
+{
+public:
+    typedef T value_type;
+
+    void operator=  (const valarray<value_type>& v) const;
+    void operator*= (const valarray<value_type>& v) const;
+    void operator/= (const valarray<value_type>& v) const;
+    void operator%= (const valarray<value_type>& v) const;
+    void operator+= (const valarray<value_type>& v) const;
+    void operator-= (const valarray<value_type>& v) const;
+    void operator^= (const valarray<value_type>& v) const;
+    void operator&= (const valarray<value_type>& v) const;
+    void operator|= (const valarray<value_type>& v) const;
+    void operator<<=(const valarray<value_type>& v) const;
+    void operator>>=(const valarray<value_type>& v) const;
+
+    gslice_array(const gslice_array& ga);
+    ~gslice_array();
+    const gslice_array& operator=(const gslice_array& ga) const;
+    void operator=(const value_type& x) const;
+
+    gslice_array() = delete;
+};
+
+template <class T>
+class mask_array
+{
+public:
+    typedef T value_type;
+
+    void operator=  (const valarray<value_type>& v) const;
+    void operator*= (const valarray<value_type>& v) const;
+    void operator/= (const valarray<value_type>& v) const;
+    void operator%= (const valarray<value_type>& v) const;
+    void operator+= (const valarray<value_type>& v) const;
+    void operator-= (const valarray<value_type>& v) const;
+    void operator^= (const valarray<value_type>& v) const;
+    void operator&= (const valarray<value_type>& v) const;
+    void operator|= (const valarray<value_type>& v) const;
+    void operator<<=(const valarray<value_type>& v) const;
+    void operator>>=(const valarray<value_type>& v) const;
+
+    mask_array(const mask_array& ma);
+    ~mask_array();
+    const mask_array& operator=(const mask_array& ma) const;
+    void operator=(const value_type& x) const;
+
+    mask_array() = delete;
+};
+
+template <class T>
+class indirect_array
+{
+public:
+    typedef T value_type;
+
+    void operator=  (const valarray<value_type>& v) const;
+    void operator*= (const valarray<value_type>& v) const;
+    void operator/= (const valarray<value_type>& v) const;
+    void operator%= (const valarray<value_type>& v) const;
+    void operator+= (const valarray<value_type>& v) const;
+    void operator-= (const valarray<value_type>& v) const;
+    void operator^= (const valarray<value_type>& v) const;
+    void operator&= (const valarray<value_type>& v) const;
+    void operator|= (const valarray<value_type>& v) const;
+    void operator<<=(const valarray<value_type>& v) const;
+    void operator>>=(const valarray<value_type>& v) const;
+
+    indirect_array(const indirect_array& ia);
+    ~indirect_array();
+    const indirect_array& operator=(const indirect_array& ia) const;
+    void operator=(const value_type& x) const;
+
+    indirect_array() = delete;
+};
+
+template<class T> void swap(valarray<T>& x, valarray<T>& y) noexcept;
+
+template<class T> valarray<T> operator* (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator* (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator* (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator/ (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator/ (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator/ (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator% (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator% (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator% (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator+ (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator+ (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator+ (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator- (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator- (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator- (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator^ (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator^ (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator^ (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator& (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator& (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator& (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator| (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator| (const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator| (const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator<<(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator<<(const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator<<(const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> operator>>(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> operator>>(const valarray<T>& x, const T& y);
+template<class T> valarray<T> operator>>(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator&&(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator&&(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator&&(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator||(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator||(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator||(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator==(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator==(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator==(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator!=(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator!=(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator!=(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator< (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator< (const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator< (const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator> (const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator> (const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator> (const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator<=(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator<=(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator<=(const T& x, const valarray<T>& y);
+
+template<class T> valarray<bool> operator>=(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<bool> operator>=(const valarray<T>& x, const T& y);
+template<class T> valarray<bool> operator>=(const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> abs (const valarray<T>& x);
+template<class T> valarray<T> acos (const valarray<T>& x);
+template<class T> valarray<T> asin (const valarray<T>& x);
+template<class T> valarray<T> atan (const valarray<T>& x);
+
+template<class T> valarray<T> atan2(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> atan2(const valarray<T>& x, const T& y);
+template<class T> valarray<T> atan2(const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> cos (const valarray<T>& x);
+template<class T> valarray<T> cosh (const valarray<T>& x);
+template<class T> valarray<T> exp (const valarray<T>& x);
+template<class T> valarray<T> log (const valarray<T>& x);
+template<class T> valarray<T> log10(const valarray<T>& x);
+
+template<class T> valarray<T> pow(const valarray<T>& x, const valarray<T>& y);
+template<class T> valarray<T> pow(const valarray<T>& x, const T& y);
+template<class T> valarray<T> pow(const T& x, const valarray<T>& y);
+
+template<class T> valarray<T> sin (const valarray<T>& x);
+template<class T> valarray<T> sinh (const valarray<T>& x);
+template<class T> valarray<T> sqrt (const valarray<T>& x);
+template<class T> valarray<T> tan (const valarray<T>& x);
+template<class T> valarray<T> tanh (const valarray<T>& x);
+
+template <class T> unspecified1 begin(valarray<T>& v);
+template <class T> unspecified2 begin(const valarray<T>& v);
+template <class T> unspecified1 end(valarray<T>& v);
+template <class T> unspecified2 end(const valarray<T>& v);
+
+}  // std
+
+*/
+
+#include <__config>
+#include <cstddef>
+#include <cmath>
+#include <initializer_list>
+#include <algorithm>
+#include <functional>
+#include <new>
+
+#include <__undef_min_max>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY valarray;
+
+class _LIBCPP_TYPE_VIS_ONLY slice
+{
+    size_t __start_;
+    size_t __size_;
+    size_t __stride_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    slice()
+        : __start_(0),
+          __size_(0),
+          __stride_(0)
+          {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    slice(size_t __start, size_t __size, size_t __stride)
+        : __start_(__start),
+          __size_(__size),
+          __stride_(__stride)
+          {}
+
+    _LIBCPP_INLINE_VISIBILITY size_t start()  const {return __start_;}
+    _LIBCPP_INLINE_VISIBILITY size_t size()   const {return __size_;}
+    _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;}
+};
+
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY slice_array;
+class _LIBCPP_TYPE_VIS gslice;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY gslice_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY mask_array;
+template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY indirect_array;
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY
+_Tp*
+begin(valarray<_Tp>& __v);
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY
+const _Tp*
+begin(const valarray<_Tp>& __v);
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY
+_Tp*
+end(valarray<_Tp>& __v);
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY
+const _Tp*
+end(const valarray<_Tp>& __v);
+
+template <class _Op, class _A0>
+struct _UnaryOp
+{
+    typedef typename _Op::result_type result_type;
+    typedef typename _A0::value_type value_type;
+
+    _Op __op_;
+    _A0 __a0_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _UnaryOp(const _Op& __op, const _A0& __a0) : __op_(__op), __a0_(__a0) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+template <class _Op, class _A0, class _A1>
+struct _BinaryOp
+{
+    typedef typename _Op::result_type result_type;
+    typedef typename _A0::value_type value_type;
+
+    _Op __op_;
+    _A0 __a0_;
+    _A1 __a1_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _BinaryOp(const _Op& __op, const _A0& __a0, const _A1& __a1)
+        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+template <class _Tp>
+class __scalar_expr
+{
+public:
+    typedef _Tp        value_type;
+    typedef const _Tp& result_type;
+private:
+    const value_type& __t_;
+    size_t __s_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __scalar_expr(const value_type& __t, size_t __s) : __t_(__t), __s_(__s) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t) const {return __t_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __s_;}
+};
+
+template <class _Tp>
+struct __unary_plus : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return +__x;}
+};
+
+template <class _Tp>
+struct __bit_not  : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return ~__x;}
+};
+
+template <class _Tp>
+struct __bit_shift_left : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x << __y;}
+};
+
+template <class _Tp>
+struct __bit_shift_right : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return __x >> __y;}
+};
+
+template <class _Tp, class _Fp>
+struct __apply_expr   : unary_function<_Tp, _Tp>
+{
+private:
+    _Fp __f_;
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __apply_expr(_Fp __f) : __f_(__f) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return __f_(__x);}
+};
+
+template <class _Tp>
+struct __abs_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return abs(__x);}
+};
+
+template <class _Tp>
+struct __acos_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return acos(__x);}
+};
+
+template <class _Tp>
+struct __asin_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return asin(__x);}
+};
+
+template <class _Tp>
+struct __atan_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return atan(__x);}
+};
+
+template <class _Tp>
+struct __atan2_expr : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return atan2(__x, __y);}
+};
+
+template <class _Tp>
+struct __cos_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return cos(__x);}
+};
+
+template <class _Tp>
+struct __cosh_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return cosh(__x);}
+};
+
+template <class _Tp>
+struct __exp_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return exp(__x);}
+};
+
+template <class _Tp>
+struct __log_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return log(__x);}
+};
+
+template <class _Tp>
+struct __log10_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return log10(__x);}
+};
+
+template <class _Tp>
+struct __pow_expr : binary_function<_Tp, _Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x, const _Tp& __y) const
+        {return pow(__x, __y);}
+};
+
+template <class _Tp>
+struct __sin_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return sin(__x);}
+};
+
+template <class _Tp>
+struct __sinh_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return sinh(__x);}
+};
+
+template <class _Tp>
+struct __sqrt_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return sqrt(__x);}
+};
+
+template <class _Tp>
+struct __tan_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return tan(__x);}
+};
+
+template <class _Tp>
+struct __tanh_expr : unary_function<_Tp, _Tp>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    _Tp operator()(const _Tp& __x) const
+        {return tanh(__x);}
+};
+
+template <class _ValExpr>
+class __slice_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef value_type result_type;
+
+private:
+    _ValExpr __expr_;
+    size_t __start_;
+    size_t __size_;
+    size_t __stride_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __slice_expr(const slice& __sl, const _RmExpr& __e)
+        : __expr_(__e),
+          __start_(__sl.start()),
+          __size_(__sl.size()),
+          __stride_(__sl.stride())
+        {}
+public:
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const
+        {return __expr_[__start_ + __i * __stride_];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __size_;}
+
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
+};
+
+template <class _ValExpr>
+class __mask_expr;
+
+template <class _ValExpr>
+class __indirect_expr;
+
+template <class _ValExpr>
+class __shift_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef value_type result_type;
+
+private:
+    _ValExpr __expr_;
+    size_t __size_;
+    ptrdiff_t __ul_;
+    ptrdiff_t __sn_;
+    ptrdiff_t __n_;
+    static const ptrdiff_t _Np = static_cast<ptrdiff_t>(
+                                    sizeof(ptrdiff_t) * __CHAR_BIT__ - 1);
+
+    _LIBCPP_INLINE_VISIBILITY
+    __shift_expr(int __n, const _RmExpr& __e)
+        : __expr_(__e),
+          __size_(__e.size()),
+          __n_(__n)
+        {
+            ptrdiff_t __neg_n = static_cast<ptrdiff_t>(__n_ >> _Np);
+            __sn_ = __neg_n | static_cast<ptrdiff_t>(static_cast<size_t>(-__n_) >> _Np);
+            __ul_ = ((__size_ - __n_) & ~__neg_n) | ((__n_ + 1) & __neg_n);
+        }
+public:
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __j) const
+        {
+            ptrdiff_t __i = static_cast<ptrdiff_t>(__j);
+            ptrdiff_t __m = (__sn_ * __i - __ul_) >> _Np;
+            return (__expr_[(__i + __n_) & __m] & __m) | (value_type() & ~__m);
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __size_;}
+
+    template <class> friend class __val_expr;
+};
+
+template <class _ValExpr>
+class __cshift_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef value_type result_type;
+
+private:
+    _ValExpr __expr_;
+    size_t __size_;
+    size_t __m_;
+    size_t __o1_;
+    size_t __o2_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __cshift_expr(int __n, const _RmExpr& __e)
+        : __expr_(__e),
+          __size_(__e.size())
+        {
+            __n %= static_cast<int>(__size_);
+            if (__n >= 0)
+            {
+                __m_ = __size_ - __n;
+                __o1_ = __n;
+                __o2_ = __n - __size_;
+            }
+            else
+            {
+                __m_ = -__n;
+                __o1_ = __n + __size_;
+                __o2_ = __n;
+            }
+        }
+public:
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const
+        {
+            if (__i < __m_)
+                return __expr_[__i + __o1_];
+            return __expr_[__i + __o2_];
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __size_;}
+
+    template <class> friend class __val_expr;
+};
+
+template<class _ValExpr>
+class __val_expr;
+
+template<class _ValExpr>
+struct __is_val_expr : false_type {};
+
+template<class _ValExpr>
+struct __is_val_expr<__val_expr<_ValExpr> > : true_type {};
+
+template<class _Tp>
+struct __is_val_expr<valarray<_Tp> > : true_type {};
+
+template<class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY valarray
+{
+public:
+    typedef _Tp value_type;
+    typedef _Tp result_type;
+
+private:
+    value_type* __begin_;
+    value_type* __end_;
+
+public:
+    // construct/destroy:
+    _LIBCPP_INLINE_VISIBILITY
+    valarray() : __begin_(0), __end_(0) {}
+    explicit valarray(size_t __n);
+    valarray(const value_type& __x, size_t __n);
+    valarray(const value_type* __p, size_t __n);
+    valarray(const valarray& __v);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    valarray(valarray&& __v) _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    valarray(initializer_list<value_type> __il);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    valarray(const slice_array<value_type>& __sa);
+    valarray(const gslice_array<value_type>& __ga);
+    valarray(const mask_array<value_type>& __ma);
+    valarray(const indirect_array<value_type>& __ia);
+    ~valarray();
+
+    // assignment:
+    valarray& operator=(const valarray& __v);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    valarray& operator=(valarray&& __v) _NOEXCEPT;
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    valarray& operator=(initializer_list<value_type>);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    valarray& operator=(const value_type& __x);
+    valarray& operator=(const slice_array<value_type>& __sa);
+    valarray& operator=(const gslice_array<value_type>& __ga);
+    valarray& operator=(const mask_array<value_type>& __ma);
+    valarray& operator=(const indirect_array<value_type>& __ia);
+    template <class _ValExpr>
+        valarray& operator=(const __val_expr<_ValExpr>& __v);
+
+    // element access:
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type& operator[](size_t __i) const {return __begin_[__i];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type&       operator[](size_t __i)       {return __begin_[__i];}
+
+    // subset operations:
+    __val_expr<__slice_expr<const valarray&> >    operator[](slice __s) const;
+    slice_array<value_type>                       operator[](slice __s);
+    __val_expr<__indirect_expr<const valarray&> > operator[](const gslice& __gs) const;
+    gslice_array<value_type>   operator[](const gslice& __gs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __val_expr<__indirect_expr<const valarray&> > operator[](gslice&& __gs) const;
+    gslice_array<value_type>                      operator[](gslice&& __gs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __val_expr<__mask_expr<const valarray&> >     operator[](const valarray<bool>& __vb) const;
+    mask_array<value_type>                        operator[](const valarray<bool>& __vb);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __val_expr<__mask_expr<const valarray&> >     operator[](valarray<bool>&& __vb) const;
+    mask_array<value_type>                        operator[](valarray<bool>&& __vb);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __val_expr<__indirect_expr<const valarray&> > operator[](const valarray<size_t>& __vs) const;
+    indirect_array<value_type>                    operator[](const valarray<size_t>& __vs);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    __val_expr<__indirect_expr<const valarray&> > operator[](valarray<size_t>&& __vs) const;
+    indirect_array<value_type>                    operator[](valarray<size_t>&& __vs);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    // unary operators:
+    valarray       operator+() const;
+    valarray       operator-() const;
+    valarray       operator~() const;
+    valarray<bool> operator!() const;
+
+    // computed assignment:
+    valarray& operator*= (const value_type& __x);
+    valarray& operator/= (const value_type& __x);
+    valarray& operator%= (const value_type& __x);
+    valarray& operator+= (const value_type& __x);
+    valarray& operator-= (const value_type& __x);
+    valarray& operator^= (const value_type& __x);
+    valarray& operator&= (const value_type& __x);
+    valarray& operator|= (const value_type& __x);
+    valarray& operator<<=(const value_type& __x);
+    valarray& operator>>=(const value_type& __x);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator*= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator/= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator%= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator+= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator-= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator^= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator|= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator&= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator<<= (const _Expr& __v);
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        valarray&
+    >::type
+    operator>>= (const _Expr& __v);
+
+    // member functions:
+    void swap(valarray& __v) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return static_cast<size_t>(__end_ - __begin_);}
+
+    value_type sum() const;
+    value_type min() const;
+    value_type max() const;
+
+    valarray shift (int __i) const;
+    valarray cshift(int __i) const;
+    valarray apply(value_type __f(value_type)) const;
+    valarray apply(value_type __f(const value_type&)) const;
+    void     resize(size_t __n, value_type __x = value_type());
+
+private:
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY slice_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY gslice_array;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY mask_array;
+    template <class> friend class __mask_expr;
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY indirect_array;
+    template <class> friend class __indirect_expr;
+    template <class> friend class __val_expr;
+
+    template <class _Up>
+    friend
+    _Up*
+    begin(valarray<_Up>& __v);
+
+    template <class _Up>
+    friend
+    const _Up*
+    begin(const valarray<_Up>& __v);
+
+    template <class _Up>
+    friend
+    _Up*
+    end(valarray<_Up>& __v);
+
+    template <class _Up>
+    friend
+    const _Up*
+    end(const valarray<_Up>& __v);
+};
+
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t))
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS valarray<size_t>::~valarray())
+_LIBCPP_EXTERN_TEMPLATE(_LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t))
+
+template <class _Op, class _Tp>
+struct _UnaryOp<_Op, valarray<_Tp> >
+{
+    typedef typename _Op::result_type result_type;
+    typedef _Tp value_type;
+
+    _Op __op_;
+    const valarray<_Tp>& __a0_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _UnaryOp(const _Op& __op, const valarray<_Tp>& __a0) : __op_(__op), __a0_(__a0) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const {return __op_(__a0_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+template <class _Op, class _Tp, class _A1>
+struct _BinaryOp<_Op, valarray<_Tp>, _A1>
+{
+    typedef typename _Op::result_type result_type;
+    typedef _Tp value_type;
+
+    _Op __op_;
+    const valarray<_Tp>& __a0_;
+    _A1 __a1_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const _A1& __a1)
+        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+template <class _Op, class _A0, class _Tp>
+struct _BinaryOp<_Op, _A0, valarray<_Tp> >
+{
+    typedef typename _Op::result_type result_type;
+    typedef _Tp value_type;
+
+    _Op __op_;
+    _A0 __a0_;
+    const valarray<_Tp>& __a1_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _BinaryOp(const _Op& __op, const _A0& __a0, const valarray<_Tp>& __a1)
+        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+template <class _Op, class _Tp>
+struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> >
+{
+    typedef typename _Op::result_type result_type;
+    typedef _Tp value_type;
+
+    _Op __op_;
+    const valarray<_Tp>& __a0_;
+    const valarray<_Tp>& __a1_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    _BinaryOp(const _Op& __op, const valarray<_Tp>& __a0, const valarray<_Tp>& __a1)
+        : __op_(__op), __a0_(__a0), __a1_(__a1) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type operator[](size_t __i) const {return __op_(__a0_[__i], __a1_[__i]);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __a0_.size();}
+};
+
+// slice_array
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY slice_array
+{
+public:
+    typedef _Tp value_type;
+
+private:
+    value_type* __vp_;
+    size_t __size_;
+    size_t __stride_;
+
+public:
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator*=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator/=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator%=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator+=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator-=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator^=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator&=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator|=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator<<=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator>>=(const _Expr& __v) const;
+
+    const slice_array& operator=(const slice_array& __sa) const;
+
+    void operator=(const value_type& __x) const;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    slice_array(const slice& __sl, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_ + __sl.start())),
+          __size_(__sl.size()),
+          __stride_(__sl.stride())
+        {}
+
+    template <class> friend class valarray;
+    template <class> friend class sliceExpr;
+};
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const slice_array<_Tp>&
+slice_array<_Tp>::operator=(const slice_array& __sa) const
+{
+    value_type* __t = __vp_;
+    const value_type* __s = __sa.__vp_;
+    for (size_t __n = __size_; __n; --__n, __t += __stride_, __s += __sa.__stride_)
+        *__t = *__s;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t = __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator*=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t *= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator/=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t /= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator%=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t %= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator+=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t += __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator-=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t -= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator^=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t ^= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator&=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t &= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator|=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t |= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator<<=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t <<= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+slice_array<_Tp>::operator>>=(const _Expr& __v) const
+{
+    value_type* __t = __vp_;
+    for (size_t __i = 0; __i < __size_; ++__i, __t += __stride_)
+        *__t >>= __v[__i];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+slice_array<_Tp>::operator=(const value_type& __x) const
+{
+    value_type* __t = __vp_;
+    for (size_t __n = __size_; __n; --__n, __t += __stride_)
+        *__t = __x;
+}
+
+// gslice
+
+class _LIBCPP_TYPE_VIS gslice
+{
+    valarray<size_t> __size_;
+    valarray<size_t> __stride_;
+    valarray<size_t> __1d_;
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    gslice() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    gslice(size_t __start, const valarray<size_t>& __size,
+                           const valarray<size_t>& __stride)
+        : __size_(__size),
+          __stride_(__stride)
+        {__init(__start);}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    gslice(size_t __start, const valarray<size_t>&  __size,
+                                 valarray<size_t>&& __stride)
+        : __size_(__size),
+          __stride_(move(__stride))
+        {__init(__start);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    gslice(size_t __start,       valarray<size_t>&& __size,
+                           const valarray<size_t>&  __stride)
+        : __size_(move(__size)),
+          __stride_(__stride)
+        {__init(__start);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    gslice(size_t __start,       valarray<size_t>&& __size,
+                                 valarray<size_t>&& __stride)
+        : __size_(move(__size)),
+          __stride_(move(__stride))
+        {__init(__start);}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+//  gslice(const gslice&)            = default;
+//  gslice(gslice&&)                 = default;
+//  gslice& operator=(const gslice&) = default;
+//  gslice& operator=(gslice&&)      = default;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t           start()  const {return __1d_.size() ? __1d_[0] : 0;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    valarray<size_t> size()   const {return __size_;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    valarray<size_t> stride() const {return __stride_;}
+
+private:
+    void __init(size_t __start);
+
+    template <class> friend class gslice_array;
+    template <class> friend class valarray;
+    template <class> friend class __val_expr;
+};
+
+// gslice_array
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY gslice_array
+{
+public:
+    typedef _Tp value_type;
+
+private:
+    value_type*      __vp_;
+    valarray<size_t> __1d_;
+
+public:
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator*=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator/=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator%=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator+=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator-=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator^=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator&=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator|=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator<<=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator>>=(const _Expr& __v) const;
+
+    const gslice_array& operator=(const gslice_array& __ga) const;
+
+    void operator=(const value_type& __x) const;
+
+//  gslice_array(const gslice_array&)            = default;
+//  gslice_array(gslice_array&&)                 = default;
+//  gslice_array& operator=(const gslice_array&) = default;
+//  gslice_array& operator=(gslice_array&&)      = default;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    gslice_array(const gslice& __gs, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_)),
+          __1d_(__gs.__1d_)
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    gslice_array(gslice&& __gs, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_)),
+          __1d_(move(__gs.__1d_))
+        {}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class> friend class valarray;
+};
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] = __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator*=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] *= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator/=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] /= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator%=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] %= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator+=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] += __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator-=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] -= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator^=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] ^= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator&=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] &= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator|=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] |= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator<<=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] <<= __v[__j];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+gslice_array<_Tp>::operator>>=(const _Expr& __v) const
+{
+    typedef const size_t* _Ip;
+    size_t __j = 0;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i, ++__j)
+        __vp_[*__i] >>= __v[__j];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const gslice_array<_Tp>&
+gslice_array<_Tp>::operator=(const gslice_array& __ga) const
+{
+    typedef const size_t* _Ip;
+    const value_type* __s = __ga.__vp_;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ga.__1d_.__begin_;
+            __i != __e; ++__i, ++__j)
+        __vp_[*__i] = __s[*__j];
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+gslice_array<_Tp>::operator=(const value_type& __x) const
+{
+    typedef const size_t* _Ip;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)
+        __vp_[*__i] = __x;
+}
+
+// mask_array
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY mask_array
+{
+public:
+    typedef _Tp value_type;
+
+private:
+    value_type*      __vp_;
+    valarray<size_t> __1d_;
+
+public:
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator*=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator/=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator%=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator+=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator-=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator^=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator&=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator|=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator<<=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator>>=(const _Expr& __v) const;
+
+    const mask_array& operator=(const mask_array& __ma) const;
+
+    void operator=(const value_type& __x) const;
+
+//  mask_array(const mask_array&)            = default;
+//  mask_array(mask_array&&)                 = default;
+//  mask_array& operator=(const mask_array&) = default;
+//  mask_array& operator=(mask_array&&)      = default;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    mask_array(const valarray<bool>& __vb, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_)),
+          __1d_(static_cast<size_t>(count(__vb.__begin_, __vb.__end_, true)))
+          {
+              size_t __j = 0;
+              for (size_t __i = 0; __i < __vb.size(); ++__i)
+                  if (__vb[__i])
+                      __1d_[__j++] = __i;
+          }
+
+    template <class> friend class valarray;
+};
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] = __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator*=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] *= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator/=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] /= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator%=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] %= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator+=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] += __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator-=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] -= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator^=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] ^= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator&=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] &= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator|=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] |= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator<<=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] <<= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+mask_array<_Tp>::operator>>=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] >>= __v[__i];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const mask_array<_Tp>&
+mask_array<_Tp>::operator=(const mask_array& __ma) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] = __ma.__vp_[__1d_[__i]];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+mask_array<_Tp>::operator=(const value_type& __x) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] = __x;
+}
+
+template <class _ValExpr>
+class __mask_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef value_type result_type;
+
+private:
+    _ValExpr __expr_;
+    valarray<size_t> __1d_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __mask_expr(const valarray<bool>& __vb, const _RmExpr& __e)
+        : __expr_(__e),
+          __1d_(static_cast<size_t>(count(__vb.__begin_, __vb.__end_, true)))
+          {
+              size_t __j = 0;
+              for (size_t __i = 0; __i < __vb.size(); ++__i)
+                  if (__vb[__i])
+                      __1d_[__j++] = __i;
+          }
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const
+        {return __expr_[__1d_[__i]];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __1d_.size();}
+
+    template <class> friend class valarray;
+};
+
+// indirect_array
+
+template <class _Tp>
+class _LIBCPP_TYPE_VIS_ONLY indirect_array
+{
+public:
+    typedef _Tp value_type;
+
+private:
+    value_type*      __vp_;
+    valarray<size_t> __1d_;
+
+public:
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator*=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator/=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator%=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator+=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator-=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator^=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator&=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator|=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator<<=(const _Expr& __v) const;
+
+    template <class _Expr>
+    typename enable_if
+    <
+        __is_val_expr<_Expr>::value,
+        void
+    >::type
+    operator>>=(const _Expr& __v) const;
+
+    const indirect_array& operator=(const indirect_array& __ia) const;
+
+    void operator=(const value_type& __x) const;
+
+//  indirect_array(const indirect_array&)            = default;
+//  indirect_array(indirect_array&&)                 = default;
+//  indirect_array& operator=(const indirect_array&) = default;
+//  indirect_array& operator=(indirect_array&&)      = default;
+
+private:
+     _LIBCPP_INLINE_VISIBILITY
+   indirect_array(const valarray<size_t>& __ia, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_)),
+          __1d_(__ia)
+        {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    indirect_array(valarray<size_t>&& __ia, const valarray<value_type>& __v)
+        : __vp_(const_cast<value_type*>(__v.__begin_)),
+          __1d_(move(__ia))
+        {}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    template <class> friend class valarray;
+};
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] = __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator*=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] *= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator/=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] /= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator%=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] %= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator+=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] += __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator-=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] -= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator^=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] ^= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator&=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] &= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator|=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] |= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator<<=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] <<= __v[__i];
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    void
+>::type
+indirect_array<_Tp>::operator>>=(const _Expr& __v) const
+{
+    size_t __n = __1d_.size();
+    for (size_t __i = 0; __i < __n; ++__i)
+        __vp_[__1d_[__i]] >>= __v[__i];
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const indirect_array<_Tp>&
+indirect_array<_Tp>::operator=(const indirect_array& __ia) const
+{
+    typedef const size_t* _Ip;
+    const value_type* __s = __ia.__vp_;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_, __j = __ia.__1d_.__begin_;
+            __i != __e; ++__i, ++__j)
+        __vp_[*__i] = __s[*__j];
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+indirect_array<_Tp>::operator=(const value_type& __x) const
+{
+    typedef const size_t* _Ip;
+    for (_Ip __i = __1d_.__begin_, __e = __1d_.__end_; __i != __e; ++__i)
+        __vp_[*__i] = __x;
+}
+
+template <class _ValExpr>
+class __indirect_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef value_type result_type;
+
+private:
+    _ValExpr __expr_;
+    valarray<size_t> __1d_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __indirect_expr(const valarray<size_t>& __ia, const _RmExpr& __e)
+        : __expr_(__e),
+          __1d_(__ia)
+          {}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+    _LIBCPP_INLINE_VISIBILITY
+    __indirect_expr(valarray<size_t>&& __ia, const _RmExpr& __e)
+        : __expr_(__e),
+          __1d_(move(__ia))
+          {}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const
+        {return __expr_[__1d_[__i]];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __1d_.size();}
+
+    template <class> friend class _LIBCPP_TYPE_VIS_ONLY valarray;
+};
+
+template<class _ValExpr>
+class __val_expr
+{
+    typedef typename remove_reference<_ValExpr>::type  _RmExpr;
+
+    _ValExpr __expr_;
+public:
+    typedef typename _RmExpr::value_type value_type;
+    typedef typename _RmExpr::result_type result_type;
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __val_expr(const _RmExpr& __e) : __expr_(__e) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator[](size_t __i) const
+        {return __expr_[__i];}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__slice_expr<_ValExpr> > operator[](slice __s) const
+        {return __val_expr<__slice_expr<_ValExpr> >(__expr_, __s);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__indirect_expr<_ValExpr> > operator[](const gslice& __gs) const
+        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __gs.__1d_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__mask_expr<_ValExpr> > operator[](const valarray<bool>& __vb) const
+        {return __val_expr<__mask_expr<_ValExpr> >(__expr_, __vb);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__indirect_expr<_ValExpr> > operator[](const valarray<size_t>& __vs) const
+        {return __val_expr<__indirect_expr<_ValExpr> >(__expr_, __vs);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<__unary_plus<value_type>, _ValExpr> >
+    operator+() const
+    {
+        typedef _UnaryOp<__unary_plus<value_type>, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(__unary_plus<value_type>(), __expr_));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<negate<value_type>, _ValExpr> >
+    operator-() const
+    {
+        typedef _UnaryOp<negate<value_type>, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(negate<value_type>(), __expr_));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<__bit_not<value_type>, _ValExpr> >
+    operator~() const
+    {
+        typedef _UnaryOp<__bit_not<value_type>, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(__bit_not<value_type>(), __expr_));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<logical_not<value_type>, _ValExpr> >
+    operator!() const
+    {
+        typedef _UnaryOp<logical_not<value_type>, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(logical_not<value_type>(), __expr_));
+    }
+
+    operator valarray<result_type>() const;
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_t size() const {return __expr_.size();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type sum() const
+    {
+        size_t __n = __expr_.size();
+        result_type __r = __n ? __expr_[0] : result_type();
+        for (size_t __i = 1; __i < __n; ++__i)
+            __r += __expr_[__i];
+        return __r;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const
+    {
+        size_t __n = size();
+        result_type __r = __n ? (*this)[0] : result_type();
+        for (size_t __i = 1; __i < __n; ++__i)
+        {
+            result_type __x = __expr_[__i];
+            if (__x < __r)
+                __r = __x;
+        }
+        return __r;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const
+    {
+        size_t __n = size();
+        result_type __r = __n ? (*this)[0] : result_type();
+        for (size_t __i = 1; __i < __n; ++__i)
+        {
+            result_type __x = __expr_[__i];
+            if (__r < __x)
+                __r = __x;
+        }
+        return __r;
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__shift_expr<_ValExpr> > shift (int __i) const
+        {return __val_expr<__shift_expr<_ValExpr> >(__shift_expr<_ValExpr>(__i, __expr_));}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<__cshift_expr<_ValExpr> > cshift(int __i) const
+        {return __val_expr<__cshift_expr<_ValExpr> >(__cshift_expr<_ValExpr>(__i, __expr_));}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(value_type)>, _ValExpr> >
+    apply(value_type __f(value_type)) const
+    {
+        typedef __apply_expr<value_type, value_type(*)(value_type)> _Op;
+        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    __val_expr<_UnaryOp<__apply_expr<value_type, value_type(*)(const value_type&)>, _ValExpr> >
+    apply(value_type __f(const value_type&)) const
+    {
+        typedef __apply_expr<value_type, value_type(*)(const value_type&)> _Op;
+        typedef _UnaryOp<_Op, _ValExpr> _NewExpr;
+        return __val_expr<_NewExpr>(_NewExpr(_Op(__f), __expr_));
+    }
+};
+
+template<class _ValExpr>
+__val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const
+{
+    valarray<result_type> __r;
+    size_t __n = __expr_.size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<result_type*>(_VSTD::__allocate(__n * sizeof(result_type)));
+        for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i)
+            ::new (__r.__end_) result_type(__expr_[__i]);
+    }
+    return __r;
+}
+
+// valarray
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>::valarray(size_t __n)
+    : __begin_(0),
+      __end_(0)
+{
+    resize(__n);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>::valarray(const value_type& __x, size_t __n)
+    : __begin_(0),
+      __end_(0)
+{
+    resize(__n, __x);
+}
+
+template <class _Tp>
+valarray<_Tp>::valarray(const value_type* __p, size_t __n)
+    : __begin_(0),
+      __end_(0)
+{
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __n; ++__end_, ++__p, --__n)
+                ::new (__end_) value_type(*__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp>
+valarray<_Tp>::valarray(const valarray& __v)
+    : __begin_(0),
+      __end_(0)
+{
+    if (__v.size())
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__v.size() * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p)
+                ::new (__end_) value_type(*__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>::valarray(valarray&& __v) _NOEXCEPT
+    : __begin_(__v.__begin_),
+      __end_(__v.__end_)
+{
+    __v.__begin_ = __v.__end_ = nullptr;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp>
+valarray<_Tp>::valarray(initializer_list<value_type> __il)
+    : __begin_(0),
+      __end_(0)
+{
+    size_t __n = __il.size();
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n)
+                ::new (__end_) value_type(*__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp>
+valarray<_Tp>::valarray(const slice_array<value_type>& __sa)
+    : __begin_(0),
+      __end_(0)
+{
+    size_t __n = __sa.__size_;
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n)
+                ::new (__end_) value_type(*__p);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp>
+valarray<_Tp>::valarray(const gslice_array<value_type>& __ga)
+    : __begin_(0),
+      __end_(0)
+{
+    size_t __n = __ga.__1d_.size();
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            typedef const size_t* _Ip;
+            const value_type* __s = __ga.__vp_;
+            for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
+                    __i != __e; ++__i, ++__end_)
+                ::new (__end_) value_type(__s[*__i]);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp>
+valarray<_Tp>::valarray(const mask_array<value_type>& __ma)
+    : __begin_(0),
+      __end_(0)
+{
+    size_t __n = __ma.__1d_.size();
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            typedef const size_t* _Ip;
+            const value_type* __s = __ma.__vp_;
+            for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
+                    __i != __e; ++__i, ++__end_)
+                ::new (__end_) value_type(__s[*__i]);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp>
+valarray<_Tp>::valarray(const indirect_array<value_type>& __ia)
+    : __begin_(0),
+      __end_(0)
+{
+    size_t __n = __ia.__1d_.size();
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            typedef const size_t* _Ip;
+            const value_type* __s = __ia.__vp_;
+            for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
+                    __i != __e; ++__i, ++__end_)
+                ::new (__end_) value_type(__s[*__i]);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>::~valarray()
+{
+    resize(0);
+}
+
+template <class _Tp>
+valarray<_Tp>&
+valarray<_Tp>::operator=(const valarray& __v)
+{
+    if (this != &__v)
+    {
+        if (size() != __v.size())
+            resize(__v.size());
+        _VSTD::copy(__v.__begin_, __v.__end_, __begin_);
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT
+{
+    resize(0);
+    __begin_ = __v.__begin_;
+    __end_ = __v.__end_;
+    __v.__begin_ = nullptr;
+    __v.__end_ = nullptr;
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(initializer_list<value_type> __il)
+{
+    if (size() != __il.size())
+        resize(__il.size());
+    _VSTD::copy(__il.begin(), __il.end(), __begin_);
+    return *this;
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const value_type& __x)
+{
+    _VSTD::fill(__begin_, __end_, __x);
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const slice_array<value_type>& __sa)
+{
+    value_type* __t = __begin_;
+    const value_type* __s = __sa.__vp_;
+    for (size_t __n = __sa.__size_; __n; --__n, __s += __sa.__stride_, ++__t)
+        *__t = *__s;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const gslice_array<value_type>& __ga)
+{
+    typedef const size_t* _Ip;
+    value_type* __t = __begin_;
+    const value_type* __s = __ga.__vp_;
+    for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_;
+                    __i != __e; ++__i, ++__t)
+        *__t = __s[*__i];
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const mask_array<value_type>& __ma)
+{
+    typedef const size_t* _Ip;
+    value_type* __t = __begin_;
+    const value_type* __s = __ma.__vp_;
+    for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_;
+                    __i != __e; ++__i, ++__t)
+        *__t = __s[*__i];
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const indirect_array<value_type>& __ia)
+{
+    typedef const size_t* _Ip;
+    value_type* __t = __begin_;
+    const value_type* __s = __ia.__vp_;
+    for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_;
+                    __i != __e; ++__i, ++__t)
+        *__t = __s[*__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _ValExpr>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator=(const __val_expr<_ValExpr>& __v)
+{
+    size_t __n = __v.size();
+    if (size() != __n)
+        resize(__n);
+    value_type* __t = __begin_;
+    for (size_t __i = 0; __i != __n; ++__t, ++__i)
+        *__t = result_type(__v[__i]);
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__slice_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](slice __s) const
+{
+    return __val_expr<__slice_expr<const valarray&> >(__slice_expr<const valarray&>(__s, *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+slice_array<_Tp>
+valarray<_Tp>::operator[](slice __s)
+{
+    return slice_array<value_type>(__s, *this);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__indirect_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](const gslice& __gs) const
+{
+    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__gs.__1d_, *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+gslice_array<_Tp>
+valarray<_Tp>::operator[](const gslice& __gs)
+{
+    return gslice_array<value_type>(__gs, *this);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__indirect_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](gslice&& __gs) const
+{
+    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__gs.__1d_), *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+gslice_array<_Tp>
+valarray<_Tp>::operator[](gslice&& __gs)
+{
+    return gslice_array<value_type>(move(__gs), *this);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__mask_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](const valarray<bool>& __vb) const
+{
+    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(__vb, *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+mask_array<_Tp>
+valarray<_Tp>::operator[](const valarray<bool>& __vb)
+{
+    return mask_array<value_type>(__vb, *this);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__mask_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](valarray<bool>&& __vb) const
+{
+    return __val_expr<__mask_expr<const valarray&> >(__mask_expr<const valarray&>(move(__vb), *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+mask_array<_Tp>
+valarray<_Tp>::operator[](valarray<bool>&& __vb)
+{
+    return mask_array<value_type>(move(__vb), *this);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__indirect_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](const valarray<size_t>& __vs) const
+{
+    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(__vs, *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+indirect_array<_Tp>
+valarray<_Tp>::operator[](const valarray<size_t>& __vs)
+{
+    return indirect_array<value_type>(__vs, *this);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+__val_expr<__indirect_expr<const valarray<_Tp>&> >
+valarray<_Tp>::operator[](valarray<size_t>&& __vs) const
+{
+    return __val_expr<__indirect_expr<const valarray&> >(__indirect_expr<const valarray&>(move(__vs), *this));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+indirect_array<_Tp>
+valarray<_Tp>::operator[](valarray<size_t>&& __vs)
+{
+    return indirect_array<value_type>(move(__vs), *this);
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::operator+() const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) value_type(+*__p);
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::operator-() const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) value_type(-*__p);
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::operator~() const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) value_type(~*__p);
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<bool>
+valarray<_Tp>::operator!() const
+{
+    valarray<bool> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<bool*>(_VSTD::__allocate(__n * sizeof(bool)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) bool(!*__p);
+    }
+    return __r;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator*=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p *= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator/=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p /= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator%=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p %= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator+=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p += __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator-=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p -= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator^=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p ^= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator&=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p &= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator|=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p |= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator<<=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p <<= __x;
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+valarray<_Tp>&
+valarray<_Tp>::operator>>=(const value_type& __x)
+{
+    for (value_type* __p = __begin_; __p != __end_; ++__p)
+        *__p >>= __x;
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator*=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t *= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator/=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t /= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator%=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t %= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator+=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t += __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator-=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t -= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator^=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t ^= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator|=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t |= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator&=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t &= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator<<=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t <<= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+template <class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    valarray<_Tp>&
+>::type
+valarray<_Tp>::operator>>=(const _Expr& __v)
+{
+    size_t __i = 0;
+    for (value_type* __t = __begin_; __t != __end_ ; ++__t, ++__i)
+        *__t >>= __v[__i];
+    return *this;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+valarray<_Tp>::swap(valarray& __v) _NOEXCEPT
+{
+    _VSTD::swap(__begin_, __v.__begin_);
+    _VSTD::swap(__end_, __v.__end_);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+valarray<_Tp>::sum() const
+{
+    if (__begin_ == __end_)
+        return value_type();
+    const value_type* __p = __begin_;
+    _Tp __r = *__p;
+    for (++__p; __p != __end_; ++__p)
+        __r += *__p;
+    return __r;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+valarray<_Tp>::min() const
+{
+    if (__begin_ == __end_)
+        return value_type();
+    return *_VSTD::min_element(__begin_, __end_);
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp
+valarray<_Tp>::max() const
+{
+    if (__begin_ == __end_)
+        return value_type();
+    return *_VSTD::max_element(__begin_, __end_);
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::shift(int __i) const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        const value_type* __sb;
+        value_type* __tb;
+        value_type* __te;
+        if (__i >= 0)
+        {
+            __i = _VSTD::min(__i, static_cast<int>(__n));
+            __sb = __begin_ + __i;
+            __tb = __r.__begin_;
+            __te = __r.__begin_ + (__n - __i);
+        }
+        else
+        {
+            __i = _VSTD::min(-__i, static_cast<int>(__n));
+            __sb = __begin_;
+            __tb = __r.__begin_ + __i;
+            __te = __r.__begin_ + __n;
+        }
+        for (; __r.__end_ != __tb; ++__r.__end_)
+            ::new (__r.__end_) value_type();
+        for (; __r.__end_ != __te; ++__r.__end_, ++__sb)
+            ::new (__r.__end_) value_type(*__sb);
+        for (__te = __r.__begin_ + __n; __r.__end_ != __te; ++__r.__end_)
+            ::new (__r.__end_) value_type();
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::cshift(int __i) const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        __i %= static_cast<int>(__n);
+        const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i;
+        for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s)
+            ::new (__r.__end_) value_type(*__s);
+        for (const value_type* __s = __begin_; __s != __m; ++__r.__end_, ++__s)
+            ::new (__r.__end_) value_type(*__s);
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::apply(value_type __f(value_type)) const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) value_type(__f(*__p));
+    }
+    return __r;
+}
+
+template <class _Tp>
+valarray<_Tp>
+valarray<_Tp>::apply(value_type __f(const value_type&)) const
+{
+    valarray<value_type> __r;
+    size_t __n = size();
+    if (__n)
+    {
+        __r.__begin_ =
+            __r.__end_ =
+                static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+        for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n)
+            ::new (__r.__end_) value_type(__f(*__p));
+    }
+    return __r;
+}
+
+template <class _Tp>
+void
+valarray<_Tp>::resize(size_t __n, value_type __x)
+{
+    if (__begin_ != nullptr)
+    {
+        while (__end_ != __begin_)
+            (--__end_)->~value_type();
+        _VSTD::__deallocate(__begin_);
+        __begin_ = __end_ = nullptr;
+    }
+    if (__n)
+    {
+        __begin_ = __end_ = static_cast<value_type*>(_VSTD::__allocate(__n * sizeof(value_type)));
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            for (; __n; --__n, ++__end_)
+                ::new (__end_) value_type(__x);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            resize(0);
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(valarray<_Tp>& __x, valarray<_Tp>& __y) _NOEXCEPT
+{
+    __x.swap(__y);
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<multiplies<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator*(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<multiplies<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(multiplies<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator*(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<multiplies<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(multiplies<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<multiplies<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator*(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<multiplies<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(multiplies<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<divides<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator/(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<divides<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(divides<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator/(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<divides<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(divides<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<divides<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator/(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<divides<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(divides<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<modulus<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator%(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<modulus<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(modulus<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator%(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<modulus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(modulus<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<modulus<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator%(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<modulus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(modulus<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<plus<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator+(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<plus<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(plus<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator+(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<plus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(plus<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<plus<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator+(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<plus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(plus<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<minus<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator-(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<minus<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(minus<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator-(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<minus<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(minus<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<minus<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator-(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<minus<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(minus<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<bit_xor<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator^(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<bit_xor<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(bit_xor<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator^(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_xor<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(bit_xor<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_xor<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator^(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_xor<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(bit_xor<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<bit_and<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator&(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<bit_and<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(bit_and<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator&(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(bit_and<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_and<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator&(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(bit_and<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<bit_or<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator|(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<bit_or<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(bit_or<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator|(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(bit_or<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<bit_or<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator|(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<bit_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(bit_or<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator<<(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator<<(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__bit_shift_left<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__bit_shift_left<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator<<(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__bit_shift_left<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_left<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator>>(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator>>(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__bit_shift_right<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__bit_shift_right<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator>>(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__bit_shift_right<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__bit_shift_right<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<logical_and<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator&&(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<logical_and<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(logical_and<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator&&(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<logical_and<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(logical_and<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<logical_and<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator&&(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<logical_and<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(logical_and<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<logical_or<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator||(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<logical_or<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(logical_or<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator||(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<logical_or<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(logical_or<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<logical_or<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator||(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<logical_or<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(logical_or<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator==(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<equal_to<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(equal_to<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator==(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(equal_to<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<equal_to<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator==(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(equal_to<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<not_equal_to<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator!=(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<not_equal_to<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(not_equal_to<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator!=(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<not_equal_to<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<not_equal_to<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator!=(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<not_equal_to<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(not_equal_to<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<less<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator<(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<less<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(less<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<less<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator<(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<less<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(less<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<less<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator<(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<less<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(less<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<greater<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator>(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<greater<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(greater<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator>(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<greater<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(greater<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<greater<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator>(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<greater<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(greater<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<less_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator<=(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<less_equal<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(less_equal<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator<=(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<less_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(less_equal<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<less_equal<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator<=(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<less_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(less_equal<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<greater_equal<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+operator>=(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<greater_equal<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(greater_equal<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+operator>=(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<greater_equal<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(greater_equal<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<greater_equal<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+operator>=(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<greater_equal<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(greater_equal<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__abs_expr<typename _Expr::value_type>, _Expr> >
+>::type
+abs(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__abs_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__abs_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__acos_expr<typename _Expr::value_type>, _Expr> >
+>::type
+acos(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__acos_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__acos_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__asin_expr<typename _Expr::value_type>, _Expr> >
+>::type
+asin(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__asin_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__asin_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__atan_expr<typename _Expr::value_type>, _Expr> >
+>::type
+atan(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__atan_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__atan_expr<value_type>(), __x));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<__atan2_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+atan2(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+atan2(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__atan2_expr<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+atan2(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__atan2_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__atan2_expr<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__cos_expr<typename _Expr::value_type>, _Expr> >
+>::type
+cos(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__cos_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__cos_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__cosh_expr<typename _Expr::value_type>, _Expr> >
+>::type
+cosh(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__cosh_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__cosh_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__exp_expr<typename _Expr::value_type>, _Expr> >
+>::type
+exp(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__exp_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__exp_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__log_expr<typename _Expr::value_type>, _Expr> >
+>::type
+log(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__log_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__log_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__log10_expr<typename _Expr::value_type>, _Expr> >
+>::type
+log10(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__log10_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__log10_expr<value_type>(), __x));
+}
+
+template<class _Expr1, class _Expr2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr1>::value && __is_val_expr<_Expr2>::value,
+    __val_expr<_BinaryOp<__pow_expr<typename _Expr1::value_type>, _Expr1, _Expr2> >
+>::type
+pow(const _Expr1& __x, const _Expr2& __y)
+{
+    typedef typename _Expr1::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, _Expr1, _Expr2> _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<value_type>(), __x, __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
+               _Expr, __scalar_expr<typename _Expr::value_type> > >
+>::type
+pow(const _Expr& __x, const typename _Expr::value_type& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, _Expr, __scalar_expr<value_type> > _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
+                           __x, __scalar_expr<value_type>(__y, __x.size())));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_BinaryOp<__pow_expr<typename _Expr::value_type>,
+               __scalar_expr<typename _Expr::value_type>, _Expr> >
+>::type
+pow(const typename _Expr::value_type& __x, const _Expr& __y)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _BinaryOp<__pow_expr<value_type>, __scalar_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__pow_expr<value_type>(),
+                           __scalar_expr<value_type>(__x, __y.size()), __y));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__sin_expr<typename _Expr::value_type>, _Expr> >
+>::type
+sin(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__sin_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__sin_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__sinh_expr<typename _Expr::value_type>, _Expr> >
+>::type
+sinh(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__sinh_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__sinh_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__sqrt_expr<typename _Expr::value_type>, _Expr> >
+>::type
+sqrt(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__sqrt_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__sqrt_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__tan_expr<typename _Expr::value_type>, _Expr> >
+>::type
+tan(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__tan_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__tan_expr<value_type>(), __x));
+}
+
+template<class _Expr>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if
+<
+    __is_val_expr<_Expr>::value,
+    __val_expr<_UnaryOp<__tanh_expr<typename _Expr::value_type>, _Expr> >
+>::type
+tanh(const _Expr& __x)
+{
+    typedef typename _Expr::value_type value_type;
+    typedef _UnaryOp<__tanh_expr<value_type>, _Expr> _Op;
+    return __val_expr<_Op>(_Op(__tanh_expr<value_type>(), __x));
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+begin(valarray<_Tp>& __v)
+{
+    return __v.__begin_;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const _Tp*
+begin(const valarray<_Tp>& __v)
+{
+    return __v.__begin_;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+_Tp*
+end(valarray<_Tp>& __v)
+{
+    return __v.__end_;
+}
+
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+const _Tp*
+end(const valarray<_Tp>& __v)
+{
+    return __v.__end_;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_VALARRAY
diff --git a/include/c++/v1/vector b/include/c++/v1/vector
new file mode 100644
index 0000000..1e638b9
--- /dev/null
+++ b/include/c++/v1/vector
@@ -0,0 +1,3301 @@
+// -*- C++ -*-
+//===------------------------------ vector --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_VECTOR
+#define _LIBCPP_VECTOR
+
+/*
+    vector synopsis
+
+namespace std
+{
+
+template <class T, class Allocator = allocator<T> >
+class vector
+{
+public:
+    typedef T                                        value_type;
+    typedef Allocator                                allocator_type;
+    typedef typename allocator_type::reference       reference;
+    typedef typename allocator_type::const_reference const_reference;
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef typename allocator_type::pointer         pointer;
+    typedef typename allocator_type::const_pointer   const_pointer;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    vector()
+        noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit vector(const allocator_type&);
+    explicit vector(size_type n);
+    explicit vector(size_type n, const allocator_type&); // C++14
+    vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
+    template <class InputIterator>
+        vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
+    vector(const vector& x);
+    vector(vector&& x)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    vector(initializer_list<value_type> il);
+    vector(initializer_list<value_type> il, const allocator_type& a);
+    ~vector();
+    vector& operator=(const vector& x);
+    vector& operator=(vector&& x)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    vector& operator=(initializer_list<value_type> il);
+    template <class InputIterator>
+        void assign(InputIterator first, InputIterator last);
+    void assign(size_type n, const value_type& u);
+    void assign(initializer_list<value_type> il);
+
+    allocator_type get_allocator() const noexcept;
+
+    iterator               begin() noexcept;
+    const_iterator         begin()   const noexcept;
+    iterator               end() noexcept;
+    const_iterator         end()     const noexcept;
+
+    reverse_iterator       rbegin() noexcept;
+    const_reverse_iterator rbegin()  const noexcept;
+    reverse_iterator       rend() noexcept;
+    const_reverse_iterator rend()    const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+    size_type capacity() const noexcept;
+    bool empty() const noexcept;
+    void reserve(size_type n);
+    void shrink_to_fit() noexcept;
+
+    reference       operator[](size_type n);
+    const_reference operator[](size_type n) const;
+    reference       at(size_type n);
+    const_reference at(size_type n) const;
+
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back() const;
+
+    value_type*       data() noexcept;
+    const value_type* data() const noexcept;
+
+    void push_back(const value_type& x);
+    void push_back(value_type&& x);
+    template <class... Args>
+        void emplace_back(Args&&... args);
+    void pop_back();
+
+    template <class... Args> iterator emplace(const_iterator position, Args&&... args);
+    iterator insert(const_iterator position, const value_type& x);
+    iterator insert(const_iterator position, value_type&& x);
+    iterator insert(const_iterator position, size_type n, const value_type& x);
+    template <class InputIterator>
+        iterator insert(const_iterator position, InputIterator first, InputIterator last);
+    iterator insert(const_iterator position, initializer_list<value_type> il);
+
+    iterator erase(const_iterator position);
+    iterator erase(const_iterator first, const_iterator last);
+
+    void clear() noexcept;
+
+    void resize(size_type sz);
+    void resize(size_type sz, const value_type& c);
+
+    void swap(vector&)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value);
+
+    bool __invariants() const;
+};
+
+template <class Allocator = allocator<T> >
+class vector<bool, Allocator>
+{
+public:
+    typedef bool                                     value_type;
+    typedef Allocator                                allocator_type;
+    typedef implementation-defined                   iterator;
+    typedef implementation-defined                   const_iterator;
+    typedef typename allocator_type::size_type       size_type;
+    typedef typename allocator_type::difference_type difference_type;
+    typedef iterator                                 pointer;
+    typedef const_iterator                           const_pointer;
+    typedef std::reverse_iterator<iterator>          reverse_iterator;
+    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+    class reference
+    {
+    public:
+        reference(const reference&) noexcept;
+        operator bool() const noexcept;
+        reference& operator=(const bool x) noexcept;
+        reference& operator=(const reference& x) noexcept;
+        iterator operator&() const noexcept;
+        void flip() noexcept;
+    };
+
+    class const_reference
+    {
+    public:
+        const_reference(const reference&) noexcept;
+        operator bool() const noexcept;
+        const_iterator operator&() const noexcept;
+    };
+
+    vector()
+        noexcept(is_nothrow_default_constructible<allocator_type>::value);
+    explicit vector(const allocator_type&);
+    explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14
+    vector(size_type n, const value_type& value, const allocator_type& = allocator_type());
+    template <class InputIterator>
+        vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type());
+    vector(const vector& x);
+    vector(vector&& x)
+        noexcept(is_nothrow_move_constructible<allocator_type>::value);
+    vector(initializer_list<value_type> il);
+    vector(initializer_list<value_type> il, const allocator_type& a);
+    ~vector();
+    vector& operator=(const vector& x);
+    vector& operator=(vector&& x)
+        noexcept(
+             allocator_type::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+    vector& operator=(initializer_list<value_type> il);
+    template <class InputIterator>
+        void assign(InputIterator first, InputIterator last);
+    void assign(size_type n, const value_type& u);
+    void assign(initializer_list<value_type> il);
+
+    allocator_type get_allocator() const noexcept;
+
+    iterator               begin() noexcept;
+    const_iterator         begin()   const noexcept;
+    iterator               end() noexcept;
+    const_iterator         end()     const noexcept;
+
+    reverse_iterator       rbegin() noexcept;
+    const_reverse_iterator rbegin()  const noexcept;
+    reverse_iterator       rend() noexcept;
+    const_reverse_iterator rend()    const noexcept;
+
+    const_iterator         cbegin()  const noexcept;
+    const_iterator         cend()    const noexcept;
+    const_reverse_iterator crbegin() const noexcept;
+    const_reverse_iterator crend()   const noexcept;
+
+    size_type size() const noexcept;
+    size_type max_size() const noexcept;
+    size_type capacity() const noexcept;
+    bool empty() const noexcept;
+    void reserve(size_type n);
+    void shrink_to_fit() noexcept;
+
+    reference       operator[](size_type n);
+    const_reference operator[](size_type n) const;
+    reference       at(size_type n);
+    const_reference at(size_type n) const;
+
+    reference       front();
+    const_reference front() const;
+    reference       back();
+    const_reference back() const;
+
+    void push_back(const value_type& x);
+    template <class... Args> void emplace_back(Args&&... args);  // C++14
+    void pop_back();
+
+    template <class... Args> iterator emplace(const_iterator position, Args&&... args);  // C++14
+    iterator insert(const_iterator position, const value_type& x);
+    iterator insert(const_iterator position, size_type n, const value_type& x);
+    template <class InputIterator>
+        iterator insert(const_iterator position, InputIterator first, InputIterator last);
+    iterator insert(const_iterator position, initializer_list<value_type> il);
+
+    iterator erase(const_iterator position);
+    iterator erase(const_iterator first, const_iterator last);
+
+    void clear() noexcept;
+
+    void resize(size_type sz);
+    void resize(size_type sz, value_type x);
+
+    void swap(vector&)
+        noexcept(!allocator_type::propagate_on_container_swap::value ||
+                 __is_nothrow_swappable<allocator_type>::value);
+    void flip() noexcept;
+
+    bool __invariants() const;
+};
+
+template <class Allocator> struct hash<std::vector<bool, Allocator>>;
+
+template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y);
+
+template <class T, class Allocator>
+void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
+    noexcept(noexcept(x.swap(y)));
+
+}  // std
+
+*/
+
+#include <__config>
+#include <__bit_reference>
+#include <type_traits>
+#include <climits>
+#include <limits>
+#include <initializer_list>
+#include <memory>
+#include <stdexcept>
+#include <algorithm>
+#include <cstring>
+#include <__split_buffer>
+#include <__functional_base>
+
+#include <__undef_min_max>
+
+#ifdef _LIBCPP_DEBUG
+#   include <__debug>
+#else
+#   define _LIBCPP_ASSERT(x, m) ((void)0)
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <bool>
+class __vector_base_common
+{
+protected:
+    _LIBCPP_ALWAYS_INLINE __vector_base_common() {}
+    void __throw_length_error() const;
+    void __throw_out_of_range() const;
+};
+
+template <bool __b>
+void
+__vector_base_common<__b>::__throw_length_error() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw length_error("vector");
+#else
+    assert(!"vector length_error");
+#endif
+}
+
+template <bool __b>
+void
+__vector_base_common<__b>::__throw_out_of_range() const
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    throw out_of_range("vector");
+#else
+    assert(!"vector out_of_range");
+#endif
+}
+
+#ifdef _LIBCPP_MSVC
+#pragma warning( push )
+#pragma warning( disable: 4231 )
+#endif // _LIBCPP_MSVC
+_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>)
+#ifdef _LIBCPP_MSVC
+#pragma warning( pop )
+#endif // _LIBCPP_MSVC
+
+template <class _Tp, class _Allocator>
+class __vector_base
+    : protected __vector_base_common<true>
+{
+protected:
+    typedef _Tp                                      value_type;
+    typedef _Allocator                               allocator_type;
+    typedef allocator_traits<allocator_type>         __alloc_traits;
+    typedef value_type&                              reference;
+    typedef const value_type&                        const_reference;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+    typedef typename __alloc_traits::pointer         pointer;
+    typedef typename __alloc_traits::const_pointer   const_pointer;
+    typedef pointer                                  iterator;
+    typedef const_pointer                            const_iterator;
+
+    pointer                                         __begin_;
+    pointer                                         __end_;
+    __compressed_pair<pointer, allocator_type> __end_cap_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type& __alloc() _NOEXCEPT
+        {return __end_cap_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const allocator_type& __alloc() const _NOEXCEPT
+        {return __end_cap_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    pointer& __end_cap() _NOEXCEPT
+        {return __end_cap_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    const pointer& __end_cap() const _NOEXCEPT
+        {return __end_cap_.first();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __vector_base()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY __vector_base(const allocator_type& __a);
+    ~__vector_base();
+
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type capacity() const _NOEXCEPT
+        {return static_cast<size_type>(__end_cap() - __begin_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __vector_base& __c)
+        {__copy_assign_alloc(__c, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_copy_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__vector_base& __c)
+        _NOEXCEPT_(
+            !__alloc_traits::propagate_on_container_move_assignment::value ||
+            is_nothrow_move_assignable<allocator_type>::value)
+        {__move_assign_alloc(__c, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_move_assignment::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y)
+        _NOEXCEPT_(
+            !__alloc_traits::propagate_on_container_swap::value ||
+            __is_nothrow_swappable<allocator_type>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __alloc_traits::propagate_on_container_swap::value>());}
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __vector_base& __c, true_type)
+        {
+            if (__alloc() != __c.__alloc())
+            {
+                clear();
+                __alloc_traits::deallocate(__alloc(), __begin_, capacity());
+                __begin_ = __end_ = __end_cap() = nullptr;
+            }
+            __alloc() = __c.__alloc();
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const __vector_base&, false_type)
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__vector_base& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            __alloc() = _VSTD::move(__c.__alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(__vector_base&, false_type)
+        _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(allocator_type&, allocator_type&, false_type)
+        _NOEXCEPT
+        {}
+};
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
+{
+    while (__new_last != __end_)
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__vector_base<_Tp, _Allocator>::__vector_base()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr)
+{
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+__vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr, __a)
+{
+}
+
+template <class _Tp, class _Allocator>
+__vector_base<_Tp, _Allocator>::~__vector_base()
+{
+    if (__begin_ != nullptr)
+    {
+        clear();
+        __alloc_traits::deallocate(__alloc(), __begin_, capacity());
+    }
+}
+
+template <class _Tp, class _Allocator = allocator<_Tp> >
+class _LIBCPP_TYPE_VIS_ONLY vector
+    : private __vector_base<_Tp, _Allocator>
+{
+private:
+    typedef __vector_base<_Tp, _Allocator>           __base;
+    typedef allocator<_Tp>                           __default_allocator_type;
+public:
+    typedef vector                                   __self;
+    typedef _Tp                                      value_type;
+    typedef _Allocator                               allocator_type;
+    typedef typename __base::__alloc_traits          __alloc_traits;
+    typedef typename __base::reference               reference;
+    typedef typename __base::const_reference         const_reference;
+    typedef typename __base::size_type               size_type;
+    typedef typename __base::difference_type         difference_type;
+    typedef typename __base::pointer                 pointer;
+    typedef typename __base::const_pointer           const_pointer;
+    typedef __wrap_iter<pointer>                     iterator;
+    typedef __wrap_iter<const_pointer>               const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;
+
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+
+    _LIBCPP_INLINE_VISIBILITY
+    vector()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+        {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
+        : __base(__a)
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->__insert_c(this);
+#endif
+    }
+    explicit vector(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit vector(size_type __n, const allocator_type& __a);
+#endif
+    vector(size_type __n, const_reference __x);
+    vector(size_type __n, const_reference __x, const allocator_type& __a);
+    template <class _InputIterator>
+        vector(_InputIterator __first,
+               typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                                 !__is_forward_iterator<_InputIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_InputIterator>::reference>::value,
+                                 _InputIterator>::type __last);
+    template <class _InputIterator>
+        vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
+               typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                                 !__is_forward_iterator<_InputIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_InputIterator>::reference>::value>::type* = 0);
+    template <class _ForwardIterator>
+        vector(_ForwardIterator __first,
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_ForwardIterator>::reference>::value,
+                                 _ForwardIterator>::type __last);
+    template <class _ForwardIterator>
+        vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                 is_constructible<
+                                    value_type,
+                                    typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    vector(initializer_list<value_type> __il);
+    _LIBCPP_INLINE_VISIBILITY
+    vector(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    ~vector()
+    {
+        __get_db()->__erase_c(this);
+    }
+#endif
+
+    vector(const vector& __x);
+    vector(const vector& __x, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
+    vector& operator=(const vector& __x);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    vector(vector&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY
+    vector(vector&& __x, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
+    vector& operator=(vector&& __x)
+        _NOEXCEPT_(
+             __alloc_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    vector& operator=(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end()); return *this;}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template <class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_InputIterator>::reference>::value,
+            void
+        >::type
+        assign(_InputIterator __first, _InputIterator __last);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_ForwardIterator>::reference>::value,
+            void
+        >::type
+        assign(_ForwardIterator __first, _ForwardIterator __last);
+
+    void assign(size_type __n, const_reference __u);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void assign(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY
+    allocator_type get_allocator() const _NOEXCEPT
+        {return this->__alloc();}
+
+    _LIBCPP_INLINE_VISIBILITY iterator               begin() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY const_iterator         begin()   const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY iterator               end() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY const_iterator         end()     const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator       rbegin() _NOEXCEPT
+        {return       reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin()  const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator       rend() _NOEXCEPT
+        {return       reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend()    const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cbegin()  const _NOEXCEPT
+        {return begin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cend()    const _NOEXCEPT
+        {return end();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT
+        {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend()   const _NOEXCEPT
+        {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT
+        {return static_cast<size_type>(this->__end_ - this->__begin_);}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type capacity() const _NOEXCEPT
+        {return __base::capacity();}
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT
+        {return this->__begin_ == this->__end_;}
+    size_type max_size() const _NOEXCEPT;
+    void reserve(size_type __n);
+    void shrink_to_fit() _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n);
+    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const;
+    reference       at(size_type __n);
+    const_reference at(size_type __n) const;
+
+    _LIBCPP_INLINE_VISIBILITY reference       front()
+    {
+        _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+        return *this->__begin_;
+    }
+    _LIBCPP_INLINE_VISIBILITY const_reference front() const
+    {
+        _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+        return *this->__begin_;
+    }
+    _LIBCPP_INLINE_VISIBILITY reference       back()
+    {
+        _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+        return *(this->__end_ - 1);
+    }
+    _LIBCPP_INLINE_VISIBILITY const_reference back()  const
+    {
+        _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+        return *(this->__end_ - 1);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    value_type*       data() _NOEXCEPT
+        {return _VSTD::__to_raw_pointer(this->__begin_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const value_type* data() const _NOEXCEPT
+        {return _VSTD::__to_raw_pointer(this->__begin_);}
+
+    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        void emplace_back(_Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    void pop_back();
+
+    iterator insert(const_iterator __position, const_reference __x);
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    iterator insert(const_iterator __position, value_type&& __x);
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class... _Args>
+        iterator emplace(const_iterator __position, _Args&&... __args);
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    iterator insert(const_iterator __position, size_type __n, const_reference __x);
+    template <class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_InputIterator>::reference>::value,
+            iterator
+        >::type
+        insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value &&
+            is_constructible<
+                 value_type,
+                 typename iterator_traits<_ForwardIterator>::reference>::value,
+            iterator
+        >::type
+        insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __position, initializer_list<value_type> __il)
+        {return insert(__position, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);
+    iterator erase(const_iterator __first, const_iterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT
+    {
+        size_type __old_size = size();
+        __base::clear();
+        __annotate_shrink(__old_size);
+        __invalidate_all_iterators();
+    }
+
+    void resize(size_type __sz);
+    void resize(size_type __sz, const_reference __x);
+
+    void swap(vector&)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value);
+
+    bool __invariants() const;
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+private:
+    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
+    void allocate(size_type __n);
+    void deallocate() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const;
+    void __construct_at_end(size_type __n);
+    void __construct_at_end(size_type __n, const_reference __x);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            void
+        >::type
+        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+    void __move_construct_at_end(pointer __first, pointer __last);
+    void __append(size_type __n);
+    void __append(size_type __n, const_reference __x);
+    _LIBCPP_INLINE_VISIBILITY
+    iterator       __make_iter(pointer __p) _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator __make_iter(const_pointer __p) const _NOEXCEPT;
+    void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v);
+    pointer __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p);
+    void __move_range(pointer __from_s, pointer __from_e, pointer __to);
+    void __move_assign(vector& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+    void __move_assign(vector& __c, false_type);
+    _LIBCPP_INLINE_VISIBILITY
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __c_node* __c = __get_db()->__find_c_and_lock(this);
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->base() > __new_last)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+#endif
+        size_type __old_size = size();
+        __base::__destruct_at_end(__new_last);
+        __annotate_shrink(__old_size);
+    }
+    template <class _Up>
+        void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+        __push_back_slow_path(_Up&& __x);
+#else
+        __push_back_slow_path(_Up& __x);
+#endif
+#if !defined(_LIBCPP_HAS_NO_VARIADICS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+    template <class... _Args>
+        void
+        __emplace_back_slow_path(_Args&&... __args);
+#endif
+    // The following functions are no-ops outside of AddressSanitizer mode.
+    // We call annotatations only for the default Allocator because other allocators
+    // may not meet the AddressSanitizer alignment constraints.
+    // See the documentation for __sanitizer_annotate_contiguous_container for more details.
+    void __annotate_contiguous_container
+    (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid)
+    {
+#ifndef _LIBCPP_HAS_NO_ASAN
+      if (__beg && is_same<allocator_type, __default_allocator_type>::value)
+        __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
+#endif
+    }
+
+    void __annotate_new(size_type __current_size)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + capacity(), data() + __current_size);
+    }
+    void __annotate_delete()
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + size(), data() + capacity());
+    }
+    void __annotate_increase(size_type __n)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + size(), data() + size() + __n);
+    }
+    void __annotate_shrink(size_type __old_size)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + __old_size, data() + size());
+    }
+};
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
+{
+    __annotate_delete();
+    __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
+    _VSTD::swap(this->__begin_, __v.__begin_);
+    _VSTD::swap(this->__end_, __v.__end_);
+    _VSTD::swap(this->__end_cap(), __v.__end_cap());
+    __v.__first_ = __v.__begin_;
+    __annotate_new(size());
+    __invalidate_all_iterators();
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::pointer
+vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)
+{
+    __annotate_delete();
+    pointer __r = __v.__begin_;
+    __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
+    __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
+    _VSTD::swap(this->__begin_, __v.__begin_);
+    _VSTD::swap(this->__end_, __v.__end_);
+    _VSTD::swap(this->__end_cap(), __v.__end_cap());
+    __v.__first_ = __v.__begin_;
+    __annotate_new(size());
+    __invalidate_all_iterators();
+    return __r;
+}
+
+//  Allocate space for __n objects
+//  throws length_error if __n > max_size()
+//  throws (probably bad_alloc) if memory run out
+//  Precondition:  __begin_ == __end_ == __end_cap() == 0
+//  Precondition:  __n > 0
+//  Postcondition:  capacity() == __n
+//  Postcondition:  size() == 0
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::allocate(size_type __n)
+{
+    if (__n > max_size())
+        this->__throw_length_error();
+    this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);
+    this->__end_cap() = this->__begin_ + __n;
+    __annotate_new(0);
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::deallocate() _NOEXCEPT
+{
+    if (this->__begin_ != nullptr)
+    {
+        clear();
+        __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
+        this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
+    }
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::size_type
+vector<_Tp, _Allocator>::max_size() const _NOEXCEPT
+{
+    return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), numeric_limits<size_type>::max() / 2);  // end() >= begin(), always
+}
+
+//  Precondition:  __new_size > capacity()
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::size_type
+vector<_Tp, _Allocator>::__recommend(size_type __new_size) const
+{
+    const size_type __ms = max_size();
+    if (__new_size > __ms)
+        this->__throw_length_error();
+    const size_type __cap = capacity();
+    if (__cap >= __ms / 2)
+        return __ms;
+    return _VSTD::max<size_type>(2*__cap, __new_size);
+}
+
+//  Default constructs __n objects starting at __end_
+//  throws if construction throws
+//  Precondition:  __n > 0
+//  Precondition:  size() + __n <= capacity()
+//  Postcondition:  size() == size() + __n
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
+{
+    allocator_type& __a = this->__alloc();
+    __annotate_increase(__n);
+    do
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
+        ++this->__end_;
+        --__n;
+    } while (__n > 0);
+}
+
+//  Copy constructs __n objects starting at __end_ from __x
+//  throws if construction throws
+//  Precondition:  __n > 0
+//  Precondition:  size() + __n <= capacity()
+//  Postcondition:  size() == old size() + __n
+//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
+{
+    allocator_type& __a = this->__alloc();
+    __annotate_increase(__n);
+    do
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
+        ++this->__end_;
+        --__n;
+    } while (__n > 0);
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    void
+>::type
+vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
+{
+    allocator_type& __a = this->__alloc();
+    for (; __first != __last; ++__first)
+    {
+        __annotate_increase(1);
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
+        ++this->__end_;
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__move_construct_at_end(pointer __first, pointer __last)
+{
+    allocator_type& __a = this->__alloc();
+    for (; __first != __last; ++__first)
+    {
+        __annotate_increase(1);
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
+                                  _VSTD::move(*__first));
+        ++this->__end_;
+    }
+}
+
+//  Default constructs __n objects starting at __end_
+//  throws if construction throws
+//  Postcondition:  size() == size() + __n
+//  Exception safety: strong.
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__append(size_type __n)
+{
+    if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)
+        this->__construct_at_end(__n);
+    else
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);
+        __v.__construct_at_end(__n);
+        __swap_out_circular_buffer(__v);
+    }
+}
+
+//  Default constructs __n objects starting at __end_
+//  throws if construction throws
+//  Postcondition:  size() == size() + __n
+//  Exception safety: strong.
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x)
+{
+    if (static_cast<size_type>(this->__end_cap() - this->__end_) >= __n)
+        this->__construct_at_end(__n, __x);
+    else
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), size(), __a);
+        __v.__construct_at_end(__n, __x);
+        __swap_out_circular_buffer(__v);
+    }
+}
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(size_type __n)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n);
+    }
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n);
+    }
+}
+#endif
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, __x);
+    }
+}
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, __x);
+    }
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator>
+vector<_Tp, _Allocator>::vector(_InputIterator __first,
+       typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                         !__is_forward_iterator<_InputIterator>::value &&
+                         is_constructible<
+                            value_type,
+                            typename iterator_traits<_InputIterator>::reference>::value,
+                          _InputIterator>::type __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator>
+vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
+       typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                         !__is_forward_iterator<_InputIterator>::value &&
+                         is_constructible<
+                            value_type,
+                            typename iterator_traits<_InputIterator>::reference>::value>::type*)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                is_constructible<
+                                   value_type,
+                                   typename iterator_traits<_ForwardIterator>::reference>::value,
+                                                   _ForwardIterator>::type __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__first, __last);
+    }
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
+                                is_constructible<
+                                   value_type,
+                                   typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__first, __last);
+    }
+}
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(const vector& __x)
+    : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc()))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    size_type __n = __x.size();
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__x.__begin_, __x.__end_);
+    }
+}
+
+template <class _Tp, class _Allocator>
+vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    size_type __n = __x.size();
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__x.__begin_, __x.__end_);
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>::vector(vector&& __x)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+    : __base(_VSTD::move(__x.__alloc()))
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    __get_db()->swap(this, &__x);
+#endif
+    this->__begin_ = __x.__begin_;
+    this->__end_ = __x.__end_;
+    this->__end_cap() = __x.__end_cap();
+    __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__a == __x.__alloc())
+    {
+        this->__begin_ = __x.__begin_;
+        this->__end_ = __x.__end_;
+        this->__end_cap() = __x.__end_cap();
+        __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        __get_db()->swap(this, &__x);
+#endif
+    }
+    else
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__x.begin()), _Ip(__x.end()));
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__il.size() > 0)
+    {
+        allocate(__il.size());
+        __construct_at_end(__il.begin(), __il.end());
+    }
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
+    : __base(__a)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
+    if (__il.size() > 0)
+    {
+        allocate(__il.size());
+        __construct_at_end(__il.begin(), __il.end());
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>&
+vector<_Tp, _Allocator>::operator=(vector&& __x)
+        _NOEXCEPT_(
+             __alloc_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value)
+{
+    __move_assign(__x, integral_constant<bool,
+          __alloc_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type)
+{
+    if (__base::__alloc() != __c.__alloc())
+    {
+        typedef move_iterator<iterator> _Ip;
+        assign(_Ip(__c.begin()), _Ip(__c.end()));
+    }
+    else
+        __move_assign(__c, true_type());
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+{
+    deallocate();
+    __base::__move_assign_alloc(__c); // this can throw
+    this->__begin_ = __c.__begin_;
+    this->__end_ = __c.__end_;
+    this->__end_cap() = __c.__end_cap();
+    __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__c);
+#endif
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<_Tp, _Allocator>&
+vector<_Tp, _Allocator>::operator=(const vector& __x)
+{
+    if (this != &__x)
+    {
+        __base::__copy_assign_alloc(__x);
+        assign(__x.__begin_, __x.__end_);
+    }
+    return *this;
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_InputIterator>::reference>::value,
+    void
+>::type
+vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
+{
+    clear();
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_ForwardIterator>::reference>::value,
+    void
+>::type
+vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
+{
+    typename iterator_traits<_ForwardIterator>::difference_type __new_size = _VSTD::distance(__first, __last);
+    if (static_cast<size_type>(__new_size) <= capacity())
+    {
+        _ForwardIterator __mid = __last;
+        bool __growing = false;
+        if (static_cast<size_type>(__new_size) > size())
+        {
+            __growing = true;
+            __mid =  __first;
+            _VSTD::advance(__mid, size());
+        }
+        pointer __m = _VSTD::copy(__first, __mid, this->__begin_);
+        if (__growing)
+            __construct_at_end(__mid, __last);
+        else
+            this->__destruct_at_end(__m);
+    }
+    else
+    {
+        deallocate();
+        allocate(__recommend(static_cast<size_type>(__new_size)));
+        __construct_at_end(__first, __last);
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u)
+{
+    if (__n <= capacity())
+    {
+        size_type __s = size();
+        _VSTD::fill_n(this->__begin_, _VSTD::min(__n, __s), __u);
+        if (__n > __s)
+            __construct_at_end(__n - __s, __u);
+        else
+            this->__destruct_at_end(this->__begin_ + __n);
+    }
+    else
+    {
+        deallocate();
+        allocate(__recommend(static_cast<size_type>(__n)));
+        __construct_at_end(__n, __u);
+    }
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(this, __p);
+#else
+    return iterator(__p);
+#endif
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::const_iterator
+vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return const_iterator(this, __p);
+#else
+    return const_iterator(__p);
+#endif
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::begin() _NOEXCEPT
+{
+    return __make_iter(this->__begin_);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::const_iterator
+vector<_Tp, _Allocator>::begin() const _NOEXCEPT
+{
+    return __make_iter(this->__begin_);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::end() _NOEXCEPT
+{
+    return __make_iter(this->__end_);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::const_iterator
+vector<_Tp, _Allocator>::end() const _NOEXCEPT
+{
+    return __make_iter(this->__end_);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::reference
+vector<_Tp, _Allocator>::operator[](size_type __n)
+{
+    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
+    return this->__begin_[__n];
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::const_reference
+vector<_Tp, _Allocator>::operator[](size_type __n) const
+{
+    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
+    return this->__begin_[__n];
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::reference
+vector<_Tp, _Allocator>::at(size_type __n)
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return this->__begin_[__n];
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::const_reference
+vector<_Tp, _Allocator>::at(size_type __n) const
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return this->__begin_[__n];
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::reserve(size_type __n)
+{
+    if (__n > capacity())
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__n, size(), __a);
+        __swap_out_circular_buffer(__v);
+    }
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
+{
+    if (capacity() > size())
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            allocator_type& __a = this->__alloc();
+            __split_buffer<value_type, allocator_type&> __v(size(), size(), __a);
+            __swap_out_circular_buffer(__v);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Tp, class _Allocator>
+template <class _Up>
+void
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+vector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x)
+#else
+vector<_Tp, _Allocator>::__push_back_slow_path(_Up& __x)
+#endif
+{
+    allocator_type& __a = this->__alloc();
+    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);
+    // __v.push_back(_VSTD::forward<_Up>(__x));
+    __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Up>(__x));
+    __v.__end_++;
+    __swap_out_circular_buffer(__v);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::push_back(const_reference __x)
+{
+    if (this->__end_ != this->__end_cap())
+    {
+        __annotate_increase(1);
+        __alloc_traits::construct(this->__alloc(),
+                                  _VSTD::__to_raw_pointer(this->__end_), __x);
+        ++this->__end_;
+    }
+    else
+        __push_back_slow_path(__x);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::push_back(value_type&& __x)
+{
+    if (this->__end_ < this->__end_cap())
+    {
+        __annotate_increase(1);
+        __alloc_traits::construct(this->__alloc(),
+                                  _VSTD::__to_raw_pointer(this->__end_),
+                                  _VSTD::move(__x));
+        ++this->__end_;
+    }
+    else
+        __push_back_slow_path(_VSTD::move(__x));
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+void
+vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args)
+{
+    allocator_type& __a = this->__alloc();
+    __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), size(), __a);
+//    __v.emplace_back(_VSTD::forward<_Args>(__args)...);
+    __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Args>(__args)...);
+    __v.__end_++;
+    __swap_out_circular_buffer(__v);
+}
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::emplace_back(_Args&&... __args)
+{
+    if (this->__end_ < this->__end_cap())
+    {
+        __annotate_increase(1);
+        __alloc_traits::construct(this->__alloc(),
+                                  _VSTD::__to_raw_pointer(this->__end_),
+                                  _VSTD::forward<_Args>(__args)...);
+        ++this->__end_;
+    }
+    else
+        __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::pop_back()
+{
+    _LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector");
+    this->__destruct_at_end(this->__end_ - 1);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::erase(const_iterator __position)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::erase(iterator) called with an iterator not"
+        " referring to this vector");
+#endif
+    _LIBCPP_ASSERT(__position != end(),
+        "vector::erase(iterator) called with a non-dereferenceable iterator");
+    difference_type __ps = __position - cbegin();
+    pointer __p = this->__begin_ + __ps;
+    iterator __r = __make_iter(__p);
+    this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
+    return __r;
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "vector::erase(iterator,  iterator) called with an iterator not"
+        " referring to this vector");
+#endif
+    _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
+    pointer __p = this->__begin_ + (__first - begin());
+    iterator __r = __make_iter(__p);
+    if (__first != __last)
+        this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
+    return __r;
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to)
+{
+    pointer __old_last = this->__end_;
+    difference_type __n = __old_last - __to;
+    for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)
+        __alloc_traits::construct(this->__alloc(),
+                                  _VSTD::__to_raw_pointer(this->__end_),
+                                  _VSTD::move(*__i));
+    _VSTD::move_backward(__from_s, __from_s + __n, __old_last);
+}
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, x) called with an iterator not"
+        " referring to this vector");
+#endif
+    pointer __p = this->__begin_ + (__position - begin());
+    if (this->__end_ < this->__end_cap())
+    {
+        __annotate_increase(1);
+        if (__p == this->__end_)
+        {
+            __alloc_traits::construct(this->__alloc(),
+                                      _VSTD::__to_raw_pointer(this->__end_), __x);
+            ++this->__end_;
+        }
+        else
+        {
+            __move_range(__p, this->__end_, __p + 1);
+            const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
+            if (__p <= __xr && __xr < this->__end_)
+                ++__xr;
+            *__p = *__xr;
+        }
+    }
+    else
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
+        __v.push_back(__x);
+        __p = __swap_out_circular_buffer(__v, __p);
+    }
+    return __make_iter(__p);
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, x) called with an iterator not"
+        " referring to this vector");
+#endif
+    pointer __p = this->__begin_ + (__position - begin());
+    if (this->__end_ < this->__end_cap())
+    {
+        __annotate_increase(1);
+        if (__p == this->__end_)
+        {
+            __alloc_traits::construct(this->__alloc(),
+                                      _VSTD::__to_raw_pointer(this->__end_),
+                                      _VSTD::move(__x));
+            ++this->__end_;
+        }
+        else
+        {
+            __move_range(__p, this->__end_, __p + 1);
+            *__p = _VSTD::move(__x);
+        }
+    }
+    else
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
+        __v.push_back(_VSTD::move(__x));
+        __p = __swap_out_circular_buffer(__v, __p);
+    }
+    return __make_iter(__p);
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Tp, class _Allocator>
+template <class... _Args>
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::emplace(iterator, x) called with an iterator not"
+        " referring to this vector");
+#endif
+    pointer __p = this->__begin_ + (__position - begin());
+    if (this->__end_ < this->__end_cap())
+    {
+        __annotate_increase(1);
+        if (__p == this->__end_)
+        {
+            __alloc_traits::construct(this->__alloc(),
+                                      _VSTD::__to_raw_pointer(this->__end_),
+                                      _VSTD::forward<_Args>(__args)...);
+            ++this->__end_;
+        }
+        else
+        {
+            value_type __tmp(_VSTD::forward<_Args>(__args)...);
+            __move_range(__p, this->__end_, __p + 1);
+            *__p = _VSTD::move(__tmp);
+        }
+    }
+    else
+    {
+        allocator_type& __a = this->__alloc();
+        __split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
+        __v.emplace_back(_VSTD::forward<_Args>(__args)...);
+        __p = __swap_out_circular_buffer(__v, __p);
+    }
+    return __make_iter(__p);
+}
+
+#endif  // _LIBCPP_HAS_NO_VARIADICS
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Tp, class _Allocator>
+typename vector<_Tp, _Allocator>::iterator
+vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, n, x) called with an iterator not"
+        " referring to this vector");
+#endif
+    pointer __p = this->__begin_ + (__position - begin());
+    if (__n > 0)
+    {
+        if (__n <= static_cast<size_type>(this->__end_cap() - this->__end_))
+        {
+            size_type __old_n = __n;
+            pointer __old_last = this->__end_;
+            if (__n > static_cast<size_type>(this->__end_ - __p))
+            {
+                size_type __cx = __n - (this->__end_ - __p);
+                __construct_at_end(__cx, __x);
+                __n -= __cx;
+            }
+            if (__n > 0)
+            {
+                __annotate_increase(__n);
+                __move_range(__p, __old_last, __p + __old_n);
+                const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
+                if (__p <= __xr && __xr < this->__end_)
+                    __xr += __old_n;
+                _VSTD::fill_n(__p, __n, *__xr);
+            }
+        }
+        else
+        {
+            allocator_type& __a = this->__alloc();
+            __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
+            __v.__construct_at_end(__n, __x);
+            __p = __swap_out_circular_buffer(__v, __p);
+        }
+    }
+    return __make_iter(__p);
+}
+
+template <class _Tp, class _Allocator>
+template <class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_InputIterator>::reference>::value,
+    typename vector<_Tp, _Allocator>::iterator
+>::type
+vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, range) called with an iterator not"
+        " referring to this vector");
+#endif
+    difference_type __off = __position - begin();
+    pointer __p = this->__begin_ + __off;
+    allocator_type& __a = this->__alloc();
+    pointer __old_last = this->__end_;
+    for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)
+    {
+        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
+                                  *__first);
+        ++this->__end_;
+    }
+    __split_buffer<value_type, allocator_type&> __v(__a);
+    if (__first != __last)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __v.__construct_at_end(__first, __last);
+            difference_type __old_size = __old_last - this->__begin_;
+            difference_type __old_p = __p - this->__begin_;
+            reserve(__recommend(size() + __v.size()));
+            __p = this->__begin_ + __old_p;
+            __old_last = this->__begin_ + __old_size;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            erase(__make_iter(__old_last), end());
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    __p = _VSTD::rotate(__p, __old_last, this->__end_);
+    insert(__make_iter(__p), make_move_iterator(__v.begin()),
+                                    make_move_iterator(__v.end()));
+    return begin() + __off;
+}
+
+template <class _Tp, class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value &&
+    is_constructible<
+       _Tp,
+       typename iterator_traits<_ForwardIterator>::reference>::value,
+    typename vector<_Tp, _Allocator>::iterator
+>::type
+vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, range) called with an iterator not"
+        " referring to this vector");
+#endif
+    pointer __p = this->__begin_ + (__position - begin());
+    difference_type __n = _VSTD::distance(__first, __last);
+    if (__n > 0)
+    {
+        if (__n <= this->__end_cap() - this->__end_)
+        {
+            size_type __old_n = __n;
+            pointer __old_last = this->__end_;
+            _ForwardIterator __m = __last;
+            difference_type __dx = this->__end_ - __p;
+            if (__n > __dx)
+            {
+                __m = __first;
+                _VSTD::advance(__m, this->__end_ - __p);
+                __construct_at_end(__m, __last);
+                __n = __dx;
+            }
+            if (__n > 0)
+            {
+                __annotate_increase(__n);
+                __move_range(__p, __old_last, __p + __old_n);
+                _VSTD::copy(__first, __m, __p);
+            }
+        }
+        else
+        {
+            allocator_type& __a = this->__alloc();
+            __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a);
+            __v.__construct_at_end(__first, __last);
+            __p = __swap_out_circular_buffer(__v, __p);
+        }
+    }
+    return __make_iter(__p);
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::resize(size_type __sz)
+{
+    size_type __cs = size();
+    if (__cs < __sz)
+        this->__append(__sz - __cs);
+    else if (__cs > __sz)
+        this->__destruct_at_end(this->__begin_ + __sz);
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x)
+{
+    size_type __cs = size();
+    if (__cs < __sz)
+        this->__append(__sz - __cs, __x);
+    else if (__cs > __sz)
+        this->__destruct_at_end(this->__begin_ + __sz);
+}
+
+template <class _Tp, class _Allocator>
+void
+vector<_Tp, _Allocator>::swap(vector& __x)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+{
+    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
+                   this->__alloc() == __x.__alloc(),
+                   "vector::swap: Either propagate_on_container_swap must be true"
+                   " or the allocators must compare equal");
+    _VSTD::swap(this->__begin_, __x.__begin_);
+    _VSTD::swap(this->__end_, __x.__end_);
+    _VSTD::swap(this->__end_cap(), __x.__end_cap());
+    __base::__swap_alloc(this->__alloc(), __x.__alloc());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->swap(this, &__x);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__invariants() const
+{
+    if (this->__begin_ == nullptr)
+    {
+        if (this->__end_ != nullptr || this->__end_cap() != nullptr)
+            return false;
+    }
+    else
+    {
+        if (this->__begin_ > this->__end_)
+            return false;
+        if (this->__begin_ == this->__end_cap())
+            return false;
+        if (this->__end_ > this->__end_cap())
+            return false;
+    }
+    return true;
+}
+
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+    return this->__begin_ <= __i->base() && __i->base() < this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+    return this->__begin_ < __i->base() && __i->base() <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const_pointer __p = __i->base() + __n;
+    return this->__begin_ <= __p && __p <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const_pointer __p = __i->base() + __n;
+    return this->__begin_ <= __p && __p < this->__end_;
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<_Tp, _Allocator>::__invalidate_all_iterators()
+{
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+}
+
+// vector<bool>
+
+template <class _Allocator> class vector<bool, _Allocator>;
+
+template <class _Allocator> struct hash<vector<bool, _Allocator> >;
+
+template <class _Allocator>
+struct __has_storage_type<vector<bool, _Allocator> >
+{
+    static const bool value = true;
+};
+
+template <class _Allocator>
+class _LIBCPP_TYPE_VIS_ONLY vector<bool, _Allocator>
+    : private __vector_base_common<true>
+{
+public:
+    typedef vector                                   __self;
+    typedef bool                                     value_type;
+    typedef _Allocator                               allocator_type;
+    typedef allocator_traits<allocator_type>         __alloc_traits;
+    typedef typename __alloc_traits::size_type       size_type;
+    typedef typename __alloc_traits::difference_type difference_type;
+    typedef size_type __storage_type;
+    typedef __bit_iterator<vector, false>            pointer;
+    typedef __bit_iterator<vector, true>             const_pointer;
+    typedef pointer                                  iterator;
+    typedef const_pointer                            const_iterator;
+    typedef _VSTD::reverse_iterator<iterator>         reverse_iterator;
+    typedef _VSTD::reverse_iterator<const_iterator>   const_reverse_iterator;
+
+private:
+    typedef typename __alloc_traits::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__storage_type>
+#else
+                rebind_alloc<__storage_type>::other
+#endif
+                                                     __storage_allocator;
+    typedef allocator_traits<__storage_allocator>    __storage_traits;
+    typedef typename __storage_traits::pointer       __storage_pointer;
+    typedef typename __storage_traits::const_pointer __const_storage_pointer;
+
+    __storage_pointer                                      __begin_;
+    size_type                                              __size_;
+    __compressed_pair<size_type, __storage_allocator> __cap_alloc_;
+public:
+    typedef __bit_reference<vector>                  reference;
+    typedef __bit_const_reference<vector>            const_reference;
+private:
+    _LIBCPP_INLINE_VISIBILITY
+    size_type& __cap() _NOEXCEPT
+        {return __cap_alloc_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    const size_type& __cap() const _NOEXCEPT
+        {return __cap_alloc_.first();}
+    _LIBCPP_INLINE_VISIBILITY
+    __storage_allocator& __alloc() _NOEXCEPT
+        {return __cap_alloc_.second();}
+    _LIBCPP_INLINE_VISIBILITY
+    const __storage_allocator& __alloc() const _NOEXCEPT
+        {return __cap_alloc_.second();}
+
+    static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
+
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __internal_cap_to_external(size_type __n) _NOEXCEPT
+        {return __n * __bits_per_word;}
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __external_cap_to_internal(size_type __n) _NOEXCEPT
+        {return (__n - 1) / __bits_per_word + 1;}
+
+public:
+    _LIBCPP_INLINE_VISIBILITY
+    vector()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a);
+    ~vector();
+    explicit vector(size_type __n);
+#if _LIBCPP_STD_VER > 11
+    explicit vector(size_type __n, const allocator_type& __a);
+#endif
+    vector(size_type __n, const value_type& __v);
+    vector(size_type __n, const value_type& __v, const allocator_type& __a);
+    template <class _InputIterator>
+        vector(_InputIterator __first, _InputIterator __last,
+               typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);
+    template <class _InputIterator>
+        vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
+               typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                                 !__is_forward_iterator<_InputIterator>::value>::type* = 0);
+    template <class _ForwardIterator>
+        vector(_ForwardIterator __first, _ForwardIterator __last,
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
+    template <class _ForwardIterator>
+        vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
+               typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type* = 0);
+
+    vector(const vector& __v);
+    vector(const vector& __v, const allocator_type& __a);
+    vector& operator=(const vector& __v);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    vector(initializer_list<value_type> __il);
+    vector(initializer_list<value_type> __il, const allocator_type& __a);
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    vector(vector&& __v)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+    vector(vector&& __v, const allocator_type& __a);
+    _LIBCPP_INLINE_VISIBILITY
+    vector& operator=(vector&& __v)
+        _NOEXCEPT_(
+             __alloc_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value);
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    vector& operator=(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end()); return *this;}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    template <class _InputIterator>
+        typename enable_if
+        <
+            __is_input_iterator<_InputIterator>::value &&
+           !__is_forward_iterator<_InputIterator>::value,
+           void
+        >::type
+        assign(_InputIterator __first, _InputIterator __last);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+           void
+        >::type
+        assign(_ForwardIterator __first, _ForwardIterator __last);
+
+    void assign(size_type __n, const value_type& __x);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    void assign(initializer_list<value_type> __il)
+        {assign(__il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT
+        {return allocator_type(this->__alloc());}
+
+    size_type max_size() const _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    size_type capacity() const _NOEXCEPT
+        {return __internal_cap_to_external(__cap());}
+    _LIBCPP_INLINE_VISIBILITY
+    size_type size() const _NOEXCEPT
+        {return __size_;}
+    _LIBCPP_INLINE_VISIBILITY
+    bool empty() const _NOEXCEPT
+        {return __size_ == 0;}
+    void reserve(size_type __n);
+    void shrink_to_fit() _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+        {return __make_iter(0);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return __make_iter(0);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+        {return __make_iter(__size_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end()   const _NOEXCEPT
+        {return __make_iter(__size_);}
+
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rbegin() _NOEXCEPT
+        {return       reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rbegin() const _NOEXCEPT
+        {return const_reverse_iterator(end());}
+    _LIBCPP_INLINE_VISIBILITY
+    reverse_iterator rend() _NOEXCEPT
+        {return       reverse_iterator(begin());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator rend()   const _NOEXCEPT
+        {return const_reverse_iterator(begin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cbegin()  const _NOEXCEPT
+        {return __make_iter(0);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator         cend()    const _NOEXCEPT
+        {return __make_iter(__size_);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crbegin() const _NOEXCEPT
+        {return rbegin();}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reverse_iterator crend()   const _NOEXCEPT
+        {return rend();}
+
+    _LIBCPP_INLINE_VISIBILITY reference       operator[](size_type __n)       {return __make_ref(__n);}
+    _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {return __make_ref(__n);}
+    reference       at(size_type __n);
+    const_reference at(size_type __n) const;
+
+    _LIBCPP_INLINE_VISIBILITY reference       front()       {return __make_ref(0);}
+    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return __make_ref(0);}
+    _LIBCPP_INLINE_VISIBILITY reference       back()        {return __make_ref(__size_ - 1);}
+    _LIBCPP_INLINE_VISIBILITY const_reference back()  const {return __make_ref(__size_ - 1);}
+
+    void push_back(const value_type& __x);
+#if _LIBCPP_STD_VER > 11
+    template <class... _Args>
+    _LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args)
+        { push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); }
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;}
+
+#if _LIBCPP_STD_VER > 11
+    template <class... _Args>
+   _LIBCPP_INLINE_VISIBILITY iterator emplace(const_iterator position, _Args&&... __args)
+        { return insert ( position, value_type ( _VSTD::forward<_Args>(__args)... )); }
+#endif
+
+    iterator insert(const_iterator __position, const value_type& __x);
+    iterator insert(const_iterator __position, size_type __n, const value_type& __x);
+    iterator insert(const_iterator __position, size_type __n, const_reference __x);
+    template <class _InputIterator>
+        typename enable_if
+        <
+             __is_input_iterator  <_InputIterator>::value &&
+            !__is_forward_iterator<_InputIterator>::value,
+            iterator
+        >::type
+        insert(const_iterator __position, _InputIterator __first, _InputIterator __last);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            iterator
+        >::type
+        insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last);
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+    _LIBCPP_INLINE_VISIBILITY
+    iterator insert(const_iterator __position, initializer_list<value_type> __il)
+        {return insert(__position, __il.begin(), __il.end());}
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+    _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __position);
+    iterator erase(const_iterator __first, const_iterator __last);
+
+    _LIBCPP_INLINE_VISIBILITY
+    void clear() _NOEXCEPT {__size_ = 0;}
+
+    void swap(vector&)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value);
+
+    void resize(size_type __sz, value_type __x = false);
+    void flip() _NOEXCEPT;
+
+    bool __invariants() const;
+
+private:
+    _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
+    void allocate(size_type __n);
+    void deallocate() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY
+    static size_type __align_it(size_type __new_size) _NOEXCEPT
+        {return __new_size + (__bits_per_word-1) & ~(__bits_per_word-1);};
+    _LIBCPP_INLINE_VISIBILITY  size_type __recommend(size_type __new_size) const;
+    _LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x);
+    template <class _ForwardIterator>
+        typename enable_if
+        <
+            __is_forward_iterator<_ForwardIterator>::value,
+            void
+        >::type
+        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+    void __append(size_type __n, const_reference __x);
+    _LIBCPP_INLINE_VISIBILITY
+    reference __make_ref(size_type __pos) _NOEXCEPT
+        {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY
+    const_reference __make_ref(size_type __pos) const _NOEXCEPT
+        {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __make_iter(size_type __pos) _NOEXCEPT
+        {return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator __make_iter(size_type __pos) const _NOEXCEPT
+        {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT
+        {return begin() + (__p - cbegin());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const vector& __v)
+        {__copy_assign_alloc(__v, integral_constant<bool,
+                      __storage_traits::propagate_on_container_copy_assignment::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const vector& __c, true_type)
+        {
+            if (__alloc() != __c.__alloc())
+                deallocate();
+            __alloc() = __c.__alloc();
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __copy_assign_alloc(const vector&, false_type)
+        {}
+
+    void __move_assign(vector& __c, false_type);
+    void __move_assign(vector& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(vector& __c)
+        _NOEXCEPT_(
+            !__storage_traits::propagate_on_container_move_assignment::value ||
+            is_nothrow_move_assignable<allocator_type>::value)
+        {__move_assign_alloc(__c, integral_constant<bool,
+                      __storage_traits::propagate_on_container_move_assignment::value>());}
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(vector& __c, true_type)
+        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+        {
+            __alloc() = _VSTD::move(__c.__alloc());
+        }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __move_assign_alloc(vector&, false_type)
+        _NOEXCEPT
+        {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y)
+        _NOEXCEPT_(
+            !__storage_traits::propagate_on_container_swap::value ||
+            __is_nothrow_swappable<allocator_type>::value)
+        {__swap_alloc(__x, __y, integral_constant<bool,
+                      __storage_traits::propagate_on_container_swap::value>());}
+
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y, true_type)
+        _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
+        {
+            using _VSTD::swap;
+            swap(__x, __y);
+        }
+    _LIBCPP_INLINE_VISIBILITY
+    static void __swap_alloc(__storage_allocator&, __storage_allocator&, false_type)
+        _NOEXCEPT
+        {}
+
+    size_t __hash_code() const _NOEXCEPT;
+
+    friend class __bit_reference<vector>;
+    friend class __bit_const_reference<vector>;
+    friend class __bit_iterator<vector, false>;
+    friend class __bit_iterator<vector, true>;
+    friend struct __bit_array<vector>;
+    friend struct _LIBCPP_TYPE_VIS_ONLY hash<vector>;
+};
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<bool, _Allocator>::__invalidate_all_iterators()
+{
+}
+
+//  Allocate space for __n objects
+//  throws length_error if __n > max_size()
+//  throws (probably bad_alloc) if memory run out
+//  Precondition:  __begin_ == __end_ == __cap() == 0
+//  Precondition:  __n > 0
+//  Postcondition:  capacity() == __n
+//  Postcondition:  size() == 0
+template <class _Allocator>
+void
+vector<bool, _Allocator>::allocate(size_type __n)
+{
+    if (__n > max_size())
+        this->__throw_length_error();
+    __n = __external_cap_to_internal(__n);
+    this->__begin_ = __storage_traits::allocate(this->__alloc(), __n);
+    this->__size_ = 0;
+    this->__cap() = __n;
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::deallocate() _NOEXCEPT
+{
+    if (this->__begin_ != nullptr)
+    {
+        __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
+        __invalidate_all_iterators();
+        this->__begin_ = nullptr;
+        this->__size_ = this->__cap() = 0;
+    }
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::size_type
+vector<bool, _Allocator>::max_size() const _NOEXCEPT
+{
+    size_type __amax = __storage_traits::max_size(__alloc());
+    size_type __nmax = numeric_limits<size_type>::max() / 2;  // end() >= begin(), always
+    if (__nmax / __bits_per_word <= __amax)
+        return __nmax;
+    return __internal_cap_to_external(__amax);
+}
+
+//  Precondition:  __new_size > capacity()
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<bool, _Allocator>::size_type
+vector<bool, _Allocator>::__recommend(size_type __new_size) const
+{
+    const size_type __ms = max_size();
+    if (__new_size > __ms)
+        this->__throw_length_error();
+    const size_type __cap = capacity();
+    if (__cap >= __ms / 2)
+        return __ms;
+    return _VSTD::max(2*__cap, __align_it(__new_size));
+}
+
+//  Default constructs __n objects starting at __end_
+//  Precondition:  __n > 0
+//  Precondition:  size() + __n <= capacity()
+//  Postcondition:  size() == size() + __n
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x)
+{
+    size_type __old_size = this->__size_;
+    this->__size_ += __n;
+    _VSTD::fill_n(__make_iter(__old_size), __n, __x);
+}
+
+template <class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    void
+>::type
+vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
+{
+    size_type __old_size = this->__size_;
+    this->__size_ += _VSTD::distance(__first, __last);
+    _VSTD::copy(__first, __last, __make_iter(__old_size));
+}
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<bool, _Allocator>::vector()
+        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+}
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<bool, _Allocator>::vector(const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(size_type __n)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, false);
+    }
+}
+
+#if _LIBCPP_STD_VER > 11
+template <class _Allocator>
+vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, false);
+    }
+}
+#endif
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(size_type __n, const value_type& __x)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, __x);
+    }
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__n, __x);
+    }
+}
+
+template <class _Allocator>
+template <class _InputIterator>
+vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
+       typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                         !__is_forward_iterator<_InputIterator>::value>::type*)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (; __first != __last; ++__first)
+            push_back(*__first);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        if (__begin_ != nullptr)
+            __storage_traits::deallocate(__alloc(), __begin_, __cap());
+        __invalidate_all_iterators();
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Allocator>
+template <class _InputIterator>
+vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
+       typename enable_if<__is_input_iterator  <_InputIterator>::value &&
+                         !__is_forward_iterator<_InputIterator>::value>::type*)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        for (; __first != __last; ++__first)
+            push_back(*__first);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+        if (__begin_ != nullptr)
+            __storage_traits::deallocate(__alloc(), __begin_, __cap());
+        __invalidate_all_iterators();
+        throw;
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+}
+
+template <class _Allocator>
+template <class _ForwardIterator>
+vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__first, __last);
+    }
+}
+
+template <class _Allocator>
+template <class _ForwardIterator>
+vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
+                                typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+    size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__first, __last);
+    }
+}
+
+#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0)
+{
+    size_type __n = static_cast<size_type>(__il.size());
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__il.begin(), __il.end());
+    }
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, static_cast<__storage_allocator>(__a))
+{
+    size_type __n = static_cast<size_type>(__il.size());
+    if (__n > 0)
+    {
+        allocate(__n);
+        __construct_at_end(__il.begin(), __il.end());
+    }
+}
+
+#endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+
+template <class _Allocator>
+vector<bool, _Allocator>::~vector()
+{
+    if (__begin_ != nullptr)
+        __storage_traits::deallocate(__alloc(), __begin_, __cap());
+    __invalidate_all_iterators();
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(const vector& __v)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))
+{
+    if (__v.size() > 0)
+    {
+        allocate(__v.size());
+        __construct_at_end(__v.begin(), __v.end());
+    }
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, __a)
+{
+    if (__v.size() > 0)
+    {
+        allocate(__v.size());
+        __construct_at_end(__v.begin(), __v.end());
+    }
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>&
+vector<bool, _Allocator>::operator=(const vector& __v)
+{
+    if (this != &__v)
+    {
+        __copy_assign_alloc(__v);
+        if (__v.__size_)
+        {
+            if (__v.__size_ > capacity())
+            {
+                deallocate();
+                allocate(__v.__size_);
+            }
+            _VSTD::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_);
+        }
+        __size_ = __v.__size_;
+    }
+    return *this;
+}
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<bool, _Allocator>::vector(vector&& __v)
+        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+    : __begin_(__v.__begin_),
+      __size_(__v.__size_),
+      __cap_alloc_(__v.__cap_alloc_)
+{
+    __v.__begin_ = nullptr;
+    __v.__size_ = 0;
+    __v.__cap() = 0;
+}
+
+template <class _Allocator>
+vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
+    : __begin_(nullptr),
+      __size_(0),
+      __cap_alloc_(0, __a)
+{
+    if (__a == allocator_type(__v.__alloc()))
+    {
+        this->__begin_ = __v.__begin_;
+        this->__size_ = __v.__size_;
+        this->__cap() = __v.__cap();
+        __v.__begin_ = nullptr;
+        __v.__cap() = __v.__size_ = 0;
+    }
+    else if (__v.size() > 0)
+    {
+        allocate(__v.size());
+        __construct_at_end(__v.begin(), __v.end());
+    }
+}
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+vector<bool, _Allocator>&
+vector<bool, _Allocator>::operator=(vector&& __v)
+        _NOEXCEPT_(
+             __alloc_traits::propagate_on_container_move_assignment::value &&
+             is_nothrow_move_assignable<allocator_type>::value)
+{
+    __move_assign(__v, integral_constant<bool,
+          __storage_traits::propagate_on_container_move_assignment::value>());
+    return *this;
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::__move_assign(vector& __c, false_type)
+{
+    if (__alloc() != __c.__alloc())
+        assign(__c.begin(), __c.end());
+    else
+        __move_assign(__c, true_type());
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::__move_assign(vector& __c, true_type)
+    _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
+{
+    deallocate();
+    __move_assign_alloc(__c);
+    this->__begin_ = __c.__begin_;
+    this->__size_ = __c.__size_;
+    this->__cap() = __c.__cap();
+    __c.__begin_ = nullptr;
+    __c.__cap() = __c.__size_ = 0;
+}
+
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::assign(size_type __n, const value_type& __x)
+{
+    __size_ = 0;
+    if (__n > 0)
+    {
+        size_type __c = capacity();
+        if (__n <= __c)
+            __size_ = __n;
+        else
+        {
+            vector __v(__alloc());
+            __v.reserve(__recommend(__n));
+            __v.__size_ = __n;
+            swap(__v);
+        }
+        _VSTD::fill_n(begin(), __n, __x);
+    }
+}
+
+template <class _Allocator>
+template <class _InputIterator>
+typename enable_if
+<
+    __is_input_iterator<_InputIterator>::value &&
+   !__is_forward_iterator<_InputIterator>::value,
+   void
+>::type
+vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
+{
+    clear();
+    for (; __first != __last; ++__first)
+        push_back(*__first);
+}
+
+template <class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+   void
+>::type
+vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
+{
+    clear();
+    difference_type __n = _VSTD::distance(__first, __last);
+    if (__n)
+    {
+        if (__n > capacity())
+        {
+            deallocate();
+            allocate(__n);
+        }
+        __construct_at_end(__first, __last);
+    }
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::reserve(size_type __n)
+{
+    if (__n > capacity())
+    {
+        vector __v(this->__alloc());
+        __v.allocate(__n);
+        __v.__construct_at_end(this->begin(), this->end());
+        swap(__v);
+        __invalidate_all_iterators();
+    }
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT
+{
+    if (__external_cap_to_internal(size()) > __cap())
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            vector(*this, allocator_type(__alloc())).swap(*this);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::reference
+vector<bool, _Allocator>::at(size_type __n)
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return (*this)[__n];
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::const_reference
+vector<bool, _Allocator>::at(size_type __n) const
+{
+    if (__n >= size())
+        this->__throw_out_of_range();
+    return (*this)[__n];
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::push_back(const value_type& __x)
+{
+    if (this->__size_ == this->capacity())
+        reserve(__recommend(this->__size_ + 1));
+    ++this->__size_;
+    back() = __x;
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::insert(const_iterator __position, const value_type& __x)
+{
+    iterator __r;
+    if (size() < capacity())
+    {
+        const_iterator __old_end = end();
+        ++__size_;
+        _VSTD::copy_backward(__position, __old_end, end());
+        __r = __const_iterator_cast(__position);
+    }
+    else
+    {
+        vector __v(__alloc());
+        __v.reserve(__recommend(__size_ + 1));
+        __v.__size_ = __size_ + 1;
+        __r = _VSTD::copy(cbegin(), __position, __v.begin());
+        _VSTD::copy_backward(__position, cend(), __v.end());
+        swap(__v);
+    }
+    *__r = __x;
+    return __r;
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const value_type& __x)
+{
+    iterator __r;
+    size_type __c = capacity();
+    if (__n <= __c && size() <= __c - __n)
+    {
+        const_iterator __old_end = end();
+        __size_ += __n;
+        _VSTD::copy_backward(__position, __old_end, end());
+        __r = __const_iterator_cast(__position);
+    }
+    else
+    {
+        vector __v(__alloc());
+        __v.reserve(__recommend(__size_ + __n));
+        __v.__size_ = __size_ + __n;
+        __r = _VSTD::copy(cbegin(), __position, __v.begin());
+        _VSTD::copy_backward(__position, cend(), __v.end());
+        swap(__v);
+    }
+    _VSTD::fill_n(__r, __n, __x);
+    return __r;
+}
+
+template <class _Allocator>
+template <class _InputIterator>
+typename enable_if
+<
+     __is_input_iterator  <_InputIterator>::value &&
+    !__is_forward_iterator<_InputIterator>::value,
+    typename vector<bool, _Allocator>::iterator
+>::type
+vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
+{
+    difference_type __off = __position - begin();
+    iterator __p = __const_iterator_cast(__position);
+    iterator __old_end = end();
+    for (; size() != capacity() && __first != __last; ++__first)
+    {
+        ++this->__size_;
+        back() = *__first;
+    }
+    vector __v(__alloc());
+    if (__first != __last)
+    {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        try
+        {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+            __v.assign(__first, __last);
+            difference_type __old_size = static_cast<difference_type>(__old_end - begin());
+            difference_type __old_p = __p - begin();
+            reserve(__recommend(size() + __v.size()));
+            __p = begin() + __old_p;
+            __old_end = begin() + __old_size;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+        }
+        catch (...)
+        {
+            erase(__old_end, end());
+            throw;
+        }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    }
+    __p = _VSTD::rotate(__p, __old_end, end());
+    insert(__p, __v.begin(), __v.end());
+    return begin() + __off;
+}
+
+template <class _Allocator>
+template <class _ForwardIterator>
+typename enable_if
+<
+    __is_forward_iterator<_ForwardIterator>::value,
+    typename vector<bool, _Allocator>::iterator
+>::type
+vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
+{
+    difference_type __n = _VSTD::distance(__first, __last);
+    iterator __r;
+    size_type __c = capacity();
+    if (__n <= __c && size() <= __c - __n)
+    {
+        const_iterator __old_end = end();
+        __size_ += __n;
+        _VSTD::copy_backward(__position, __old_end, end());
+        __r = __const_iterator_cast(__position);
+    }
+    else
+    {
+        vector __v(__alloc());
+        __v.reserve(__recommend(__size_ + __n));
+        __v.__size_ = __size_ + __n;
+        __r = _VSTD::copy(cbegin(), __position, __v.begin());
+        _VSTD::copy_backward(__position, cend(), __v.end());
+        swap(__v);
+    }
+    _VSTD::copy(__first, __last, __r);
+    return __r;
+}
+
+template <class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::erase(const_iterator __position)
+{
+    iterator __r = __const_iterator_cast(__position);
+    _VSTD::copy(__position + 1, this->cend(), __r);
+    --__size_;
+    return __r;
+}
+
+template <class _Allocator>
+typename vector<bool, _Allocator>::iterator
+vector<bool, _Allocator>::erase(const_iterator __first, const_iterator __last)
+{
+    iterator __r = __const_iterator_cast(__first);
+    difference_type __d = __last - __first;
+    _VSTD::copy(__last, this->cend(), __r);
+    __size_ -= __d;
+    return __r;
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::swap(vector& __x)
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+                   __is_nothrow_swappable<allocator_type>::value)
+{
+    _VSTD::swap(this->__begin_, __x.__begin_);
+    _VSTD::swap(this->__size_, __x.__size_);
+    _VSTD::swap(this->__cap(), __x.__cap());
+    __swap_alloc(this->__alloc(), __x.__alloc());
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::resize(size_type __sz, value_type __x)
+{
+    size_type __cs = size();
+    if (__cs < __sz)
+    {
+        iterator __r;
+        size_type __c = capacity();
+        size_type __n = __sz - __cs;
+        if (__n <= __c && __cs <= __c - __n)
+        {
+            __r = end();
+            __size_ += __n;
+        }
+        else
+        {
+            vector __v(__alloc());
+            __v.reserve(__recommend(__size_ + __n));
+            __v.__size_ = __size_ + __n;
+            __r = _VSTD::copy(cbegin(), cend(), __v.begin());
+            swap(__v);
+        }
+        _VSTD::fill_n(__r, __n, __x);
+    }
+    else
+        __size_ = __sz;
+}
+
+template <class _Allocator>
+void
+vector<bool, _Allocator>::flip() _NOEXCEPT
+{
+    // do middle whole words
+    size_type __n = __size_;
+    __storage_pointer __p = __begin_;
+    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+        *__p = ~*__p;
+    // do last partial word
+    if (__n > 0)
+    {
+        __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __storage_type __b = *__p & __m;
+        *__p &= ~__m;
+        *__p |= ~__b & __m;
+    }
+}
+
+template <class _Allocator>
+bool
+vector<bool, _Allocator>::__invariants() const
+{
+    if (this->__begin_ == nullptr)
+    {
+        if (this->__size_ != 0 || this->__cap() != 0)
+            return false;
+    }
+    else
+    {
+        if (this->__cap() == 0)
+            return false;
+        if (this->__size_ > this->capacity())
+            return false;
+    }
+    return true;
+}
+
+template <class _Allocator>
+size_t
+vector<bool, _Allocator>::__hash_code() const _NOEXCEPT
+{
+    size_t __h = 0;
+    // do middle whole words
+    size_type __n = __size_;
+    __storage_pointer __p = __begin_;
+    for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+        __h ^= *__p;
+    // do last partial word
+    if (__n > 0)
+    {
+        const __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+        __h ^= *__p & __m;
+    }
+    return __h;
+}
+
+template <class _Allocator>
+struct _LIBCPP_TYPE_VIS_ONLY hash<vector<bool, _Allocator> >
+    : public unary_function<vector<bool, _Allocator>, size_t>
+{
+    _LIBCPP_INLINE_VISIBILITY
+    size_t operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT
+        {return __vec.__hash_code();}
+};
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    const typename vector<_Tp, _Allocator>::size_type __sz = __x.size();
+    return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin());
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    return !(__x == __y);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    return __y < __x;
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    return !(__x < __y);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y)
+{
+    return !(__y < __x);
+}
+
+template <class _Tp, class _Allocator>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
+    _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+    __x.swap(__y);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif  // _LIBCPP_VECTOR
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
new file mode 100644
index 0000000..ed3e8d9
--- /dev/null
+++ b/include/clang-c/BuildSystem.h
@@ -0,0 +1,148 @@
+/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides various utilities for use by build systems.           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_BUILD_SYSTEM_H
+#define CLANG_C_BUILD_SYSTEM_H
+
+#include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup BUILD_SYSTEM Build system utilities
+ * @{
+ */
+
+/**
+ * \brief Return the timestamp for use with Clang's
+ * \c -fbuild-session-timestamp= option.
+ */
+CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
+
+/**
+ * \brief Object encapsulating information about overlaying virtual
+ * file/directories over the real file system.
+ */
+typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
+
+/**
+ * \brief Create a \c CXVirtualFileOverlay object.
+ * Must be disposed with \c clang_VirtualFileOverlay_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXVirtualFileOverlay
+clang_VirtualFileOverlay_create(unsigned options);
+
+/**
+ * \brief Map an absolute virtual file path to an absolute real one.
+ * The virtual path must be canonicalized (not contain "."/"..").
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
+                                        const char *virtualPath,
+                                        const char *realPath);
+
+/**
+ * \brief Set the case sensitivity for the \c CXVirtualFileOverlay object.
+ * The \c CXVirtualFileOverlay object is case-sensitive by default, this
+ * option can be used to override the default.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
+											int caseSensitive);
+
+/**
+ * \brief Write out the \c CXVirtualFileOverlay object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXVirtualFileOverlay object.
+ */
+CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
+
+/**
+ * \brief Object encapsulating information about a module.map file.
+ */
+typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
+
+/**
+ * \brief Create a \c CXModuleMapDescriptor object.
+ * Must be disposed with \c clang_ModuleMapDescriptor_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXModuleMapDescriptor
+clang_ModuleMapDescriptor_create(unsigned options);
+
+/**
+ * \brief Sets the framework module name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
+                                                 const char *name);
+
+/**
+ * \brief Sets the umbrealla header name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
+                                            const char *name);
+
+/**
+ * \brief Write out the \c CXModuleMapDescriptor object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXModuleMapDescriptor object.
+ */
+CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_BUILD_SYSTEM_H */
+
diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h
new file mode 100644
index 0000000..fd65418
--- /dev/null
+++ b/include/clang-c/CXCompilationDatabase.h
@@ -0,0 +1,170 @@
+/*===-- clang-c/CXCompilationDatabase.h - Compilation database  ---*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public inferface to use CompilationDatabase without *|
+|* the full Clang C++ API.                                                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_CXCOMPILATIONDATABASE_H
+#define CLANG_CXCOMPILATIONDATABASE_H
+
+#include "clang-c/Platform.h"
+#include "clang-c/CXString.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup COMPILATIONDB CompilationDatabase functions
+ * \ingroup CINDEX
+ *
+ * @{
+ */
+
+/**
+ * A compilation database holds all information used to compile files in a
+ * project. For each file in the database, it can be queried for the working
+ * directory or the command line used for the compiler invocation.
+ *
+ * Must be freed by \c clang_CompilationDatabase_dispose
+ */
+typedef void * CXCompilationDatabase;
+
+/**
+ * \brief Contains the results of a search in the compilation database
+ *
+ * When searching for the compile command for a file, the compilation db can
+ * return several commands, as the file may have been compiled with
+ * different options in different places of the project. This choice of compile
+ * commands is wrapped in this opaque data structure. It must be freed by
+ * \c clang_CompileCommands_dispose.
+ */
+typedef void * CXCompileCommands;
+
+/**
+ * \brief Represents the command line invocation to compile a specific file.
+ */
+typedef void * CXCompileCommand;
+
+/**
+ * \brief Error codes for Compilation Database
+ */
+typedef enum  {
+  /*
+   * \brief No error occurred
+   */
+  CXCompilationDatabase_NoError = 0,
+
+  /*
+   * \brief Database can not be loaded
+   */
+  CXCompilationDatabase_CanNotLoadDatabase = 1
+
+} CXCompilationDatabase_Error;
+
+/**
+ * \brief Creates a compilation database from the database found in directory
+ * buildDir. For example, CMake can output a compile_commands.json which can
+ * be used to build the database.
+ *
+ * It must be freed by \c clang_CompilationDatabase_dispose.
+ */
+CINDEX_LINKAGE CXCompilationDatabase
+clang_CompilationDatabase_fromDirectory(const char *BuildDir,
+                                        CXCompilationDatabase_Error *ErrorCode);
+
+/**
+ * \brief Free the given compilation database
+ */
+CINDEX_LINKAGE void
+clang_CompilationDatabase_dispose(CXCompilationDatabase);
+
+/**
+ * \brief Find the compile commands used for a file. The compile commands
+ * must be freed by \c clang_CompileCommands_dispose.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
+                                             const char *CompleteFileName);
+
+/**
+ * \brief Get all the compile commands in the given compilation database.
+ */
+CINDEX_LINKAGE CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
+
+/**
+ * \brief Free the given CompileCommands
+ */
+CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
+
+/**
+ * \brief Get the number of CompileCommand we have for a file
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommands_getSize(CXCompileCommands);
+
+/**
+ * \brief Get the I'th CompileCommand for a file
+ *
+ * Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands)
+ */
+CINDEX_LINKAGE CXCompileCommand
+clang_CompileCommands_getCommand(CXCompileCommands, unsigned I);
+
+/**
+ * \brief Get the working directory where the CompileCommand was executed from
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getDirectory(CXCompileCommand);
+
+/**
+ * \brief Get the number of arguments in the compiler invocation.
+ *
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommand_getNumArgs(CXCompileCommand);
+
+/**
+ * \brief Get the I'th argument value in the compiler invocations
+ *
+ * Invariant :
+ *  - argument 0 is the compiler executable
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
+
+/**
+ * \brief Get the number of source mappings for the compiler invocation.
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommand_getNumMappedSources(CXCompileCommand);
+
+/**
+ * \brief Get the I'th mapped source path for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I);
+
+/**
+ * \brief Get the I'th mapped source content for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
new file mode 100644
index 0000000..a026c95
--- /dev/null
+++ b/include/clang-c/CXErrorCode.h
@@ -0,0 +1,64 @@
+/*===-- clang-c/CXErrorCode.h - C Index Error Codes  --------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides the CXErrorCode enumerators.                          *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_CXERRORCODE_H
+#define CLANG_C_CXERRORCODE_H
+
+#include "clang-c/Platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Error codes returned by libclang routines.
+ *
+ * Zero (\c CXError_Success) is the only error code indicating success.  Other
+ * error codes, including not yet assigned non-zero values, indicate errors.
+ */
+enum CXErrorCode {
+  /**
+   * \brief No error.
+   */
+  CXError_Success = 0,
+
+  /**
+   * \brief A generic error code, no further details are available.
+   *
+   * Errors of this kind can get their own specific error codes in future
+   * libclang versions.
+   */
+  CXError_Failure = 1,
+
+  /**
+   * \brief libclang crashed while performing the requested operation.
+   */
+  CXError_Crashed = 2,
+
+  /**
+   * \brief The function detected that the arguments violate the function
+   * contract.
+   */
+  CXError_InvalidArguments = 3,
+
+  /**
+   * \brief An AST deserialization error has occurred.
+   */
+  CXError_ASTReadError = 4
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
new file mode 100644
index 0000000..cf198cb
--- /dev/null
+++ b/include/clang-c/CXString.h
@@ -0,0 +1,61 @@
+/*===-- clang-c/CXString.h - C Index strings  --------------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides the interface to C Index strings.                     *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_CXSTRING_H
+#define CLANG_CXSTRING_H
+
+#include "clang-c/Platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CINDEX_STRING String manipulation routines
+ * \ingroup CINDEX
+ *
+ * @{
+ */
+
+/**
+ * \brief A character string.
+ *
+ * The \c CXString type is used to return strings from the interface when
+ * the ownership of that string might differ from one call to the next.
+ * Use \c clang_getCString() to retrieve the string data and, once finished
+ * with the string data, call \c clang_disposeString() to free the string.
+ */
+typedef struct {
+  const void *data;
+  unsigned private_flags;
+} CXString;
+
+/**
+ * \brief Retrieve the character data associated with the given string.
+ */
+CINDEX_LINKAGE const char *clang_getCString(CXString string);
+
+/**
+ * \brief Free the given string.
+ */
+CINDEX_LINKAGE void clang_disposeString(CXString string);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h
new file mode 100644
index 0000000..ad2da07
--- /dev/null
+++ b/include/clang-c/Documentation.h
@@ -0,0 +1,554 @@
+/*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a supplementary interface for inspecting              *|
+|* documentation comments.                                                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_DOCUMENTATION_H
+#define CLANG_C_DOCUMENTATION_H
+
+#include "clang-c/Index.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CINDEX_COMMENT Comment introspection
+ *
+ * The routines in this group provide access to information in documentation
+ * comments. These facilities are distinct from the core and may be subject to
+ * their own schedule of stability and deprecation.
+ *
+ * @{
+ */
+
+/**
+ * \brief A parsed comment.
+ */
+typedef struct {
+  const void *ASTNode;
+  CXTranslationUnit TranslationUnit;
+} CXComment;
+
+/**
+ * \brief Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated parsed comment as a
+ * \c CXComment_FullComment AST node.
+ */
+CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
+
+/**
+ * \brief Describes the type of the comment AST node (\c CXComment).  A comment
+ * node can be considered block content (e. g., paragraph), inline content
+ * (plain text) or neither (the root AST node).
+ */
+enum CXCommentKind {
+  /**
+   * \brief Null comment.  No AST node is constructed at the requested location
+   * because there is no text or a syntax error.
+   */
+  CXComment_Null = 0,
+
+  /**
+   * \brief Plain text.  Inline content.
+   */
+  CXComment_Text = 1,
+
+  /**
+   * \brief A command with word-like arguments that is considered inline content.
+   *
+   * For example: \\c command.
+   */
+  CXComment_InlineCommand = 2,
+
+  /**
+   * \brief HTML start tag with attributes (name-value pairs).  Considered
+   * inline content.
+   *
+   * For example:
+   * \verbatim
+   * <br> <br /> <a href="http://example.org/">
+   * \endverbatim
+   */
+  CXComment_HTMLStartTag = 3,
+
+  /**
+   * \brief HTML end tag.  Considered inline content.
+   *
+   * For example:
+   * \verbatim
+   * </a>
+   * \endverbatim
+   */
+  CXComment_HTMLEndTag = 4,
+
+  /**
+   * \brief A paragraph, contains inline comment.  The paragraph itself is
+   * block content.
+   */
+  CXComment_Paragraph = 5,
+
+  /**
+   * \brief A command that has zero or more word-like arguments (number of
+   * word-like arguments depends on command name) and a paragraph as an
+   * argument.  Block command is block content.
+   *
+   * Paragraph argument is also a child of the block command.
+   *
+   * For example: \\brief has 0 word-like arguments and a paragraph argument.
+   *
+   * AST nodes of special kinds that parser knows about (e. g., \\param
+   * command) have their own node kinds.
+   */
+  CXComment_BlockCommand = 6,
+
+  /**
+   * \brief A \\param or \\arg command that describes the function parameter
+   * (name, passing direction, description).
+   *
+   * For example: \\param [in] ParamName description.
+   */
+  CXComment_ParamCommand = 7,
+
+  /**
+   * \brief A \\tparam command that describes a template parameter (name and
+   * description).
+   *
+   * For example: \\tparam T description.
+   */
+  CXComment_TParamCommand = 8,
+
+  /**
+   * \brief A verbatim block command (e. g., preformatted code).  Verbatim
+   * block has an opening and a closing command and contains multiple lines of
+   * text (\c CXComment_VerbatimBlockLine child nodes).
+   *
+   * For example:
+   * \\verbatim
+   * aaa
+   * \\endverbatim
+   */
+  CXComment_VerbatimBlockCommand = 9,
+
+  /**
+   * \brief A line of text that is contained within a
+   * CXComment_VerbatimBlockCommand node.
+   */
+  CXComment_VerbatimBlockLine = 10,
+
+  /**
+   * \brief A verbatim line command.  Verbatim line has an opening command,
+   * a single line of text (up to the newline after the opening command) and
+   * has no closing command.
+   */
+  CXComment_VerbatimLine = 11,
+
+  /**
+   * \brief A full comment attached to a declaration, contains block content.
+   */
+  CXComment_FullComment = 12
+};
+
+/**
+ * \brief The most appropriate rendering mode for an inline command, chosen on
+ * command semantics in Doxygen.
+ */
+enum CXCommentInlineCommandRenderKind {
+  /**
+   * \brief Command argument should be rendered in a normal font.
+   */
+  CXCommentInlineCommandRenderKind_Normal,
+
+  /**
+   * \brief Command argument should be rendered in a bold font.
+   */
+  CXCommentInlineCommandRenderKind_Bold,
+
+  /**
+   * \brief Command argument should be rendered in a monospaced font.
+   */
+  CXCommentInlineCommandRenderKind_Monospaced,
+
+  /**
+   * \brief Command argument should be rendered emphasized (typically italic
+   * font).
+   */
+  CXCommentInlineCommandRenderKind_Emphasized
+};
+
+/**
+ * \brief Describes parameter passing direction for \\param or \\arg command.
+ */
+enum CXCommentParamPassDirection {
+  /**
+   * \brief The parameter is an input parameter.
+   */
+  CXCommentParamPassDirection_In,
+
+  /**
+   * \brief The parameter is an output parameter.
+   */
+  CXCommentParamPassDirection_Out,
+
+  /**
+   * \brief The parameter is an input and output parameter.
+   */
+  CXCommentParamPassDirection_InOut
+};
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns the type of the AST node.
+ */
+CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns number of children of the AST node.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \param ChildIdx child index (zero-based).
+ *
+ * \returns the specified child of the AST node.
+ */
+CINDEX_LINKAGE
+CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
+
+/**
+ * \brief A \c CXComment_Paragraph node is considered whitespace if it contains
+ * only \c CXComment_Text nodes that are empty or whitespace.
+ *
+ * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
+ * never considered whitespace.
+ *
+ * \returns non-zero if \c Comment is whitespace.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
+
+/**
+ * \returns non-zero if \c Comment is inline content and has a newline
+ * immediately following it in the comment text.  Newlines between paragraphs
+ * do not count.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_Text AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns name of the inline command.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns the most appropriate rendering mode, chosen on command
+ * semantics in Doxygen.
+ */
+CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
+clang_InlineCommandComment_getRenderKind(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns number of command arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified argument.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getArgText(CXComment Comment,
+                                               unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns HTML tag name.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns non-zero if tag is self-closing (for example, &lt;br /&gt;).
+ */
+CINDEX_LINKAGE
+unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns number of attributes (name-value pairs) attached to the start tag.
+ */
+CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns name of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns value of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns name of the block command.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns number of word-like arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified word-like argument.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getArgText(CXComment Comment,
+                                              unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand or
+ * \c CXComment_VerbatimBlockCommand AST node.
+ *
+ * \returns paragraph argument of the block command.
+ */
+CINDEX_LINKAGE
+CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_ParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the function prototype and \c clang_ParamCommandComment_getParamIndex
+ * function will return a meaningful value.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns zero-based parameter index in function prototype.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if parameter passing direction was specified explicitly in
+ * the comment.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter passing direction.
+ */
+CINDEX_LINKAGE
+enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
+                                                            CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns template parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_TParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the template parameter list and
+ * \c clang_TParamCommandComment_getDepth and
+ * \c clang_TParamCommandComment_getIndex functions will return a meaningful
+ * value.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based nesting depth of this parameter in the template parameter list.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0,
+ * for T nesting depth is 1.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based parameter index in the template parameter list at a
+ * given nesting depth.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0, so we can ask for index at depth 0:
+ * at depth 0 C's index is 0, TT's index is 1.
+ *
+ * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
+ * at depth 0 T's index is 1 (same as TT's),
+ * at depth 1 T's index is 0.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
+
+/**
+ * \param Comment a \c CXComment_VerbatimBlockLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE
+CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_VerbatimLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
+
+/**
+ * \brief Convert an HTML tag AST node to string.
+ *
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns string containing an HTML tag.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an HTML fragment.
+ *
+ * Specific details of HTML layout are subject to change.  Don't try to parse
+ * this HTML back into an AST, use other APIs instead.
+ *
+ * Currently the following CSS classes are used:
+ * \li "para-brief" for \\brief paragraph and equivalent commands;
+ * \li "para-returns" for \\returns paragraph and equivalent commands;
+ * \li "word-returns" for the "Returns" word in \\returns paragraph.
+ *
+ * Function argument documentation is rendered as a \<dl\> list with arguments
+ * sorted in function prototype order.  CSS classes used:
+ * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
+ * parameter index is invalid.
+ *
+ * Template parameter documentation is rendered as a \<dl\> list with
+ * parameters sorted in template parameter list order.  CSS classes used:
+ * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
+ * names inside template template parameters;
+ * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
+ * parameter position is invalid.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an HTML fragment.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an XML document.
+ *
+ * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
+ * inside clang source tree.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an XML document.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_DOCUMENTATION_H */
+
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
new file mode 100644
index 0000000..f69f567
--- /dev/null
+++ b/include/clang-c/Index.h
@@ -0,0 +1,5494 @@
+/*===-- clang-c/Index.h - Indexing Public C Interface -------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public inferface to a Clang library for extracting  *|
+|* high-level symbol information from source files without exposing the full  *|
+|* Clang C++ API.                                                             *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_INDEX_H
+#define CLANG_C_INDEX_H
+
+#include <time.h>
+
+#include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+#include "clang-c/BuildSystem.h"
+
+/**
+ * \brief The version constants for the libclang API.
+ * CINDEX_VERSION_MINOR should increase when there are API additions.
+ * CINDEX_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
+ *
+ * The policy about the libclang API was always to keep it source and ABI
+ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
+ */
+#define CINDEX_VERSION_MAJOR 0
+#define CINDEX_VERSION_MINOR 27
+
+#define CINDEX_VERSION_ENCODE(major, minor) ( \
+      ((major) * 10000)                       \
+    + ((minor) *     1))
+
+#define CINDEX_VERSION CINDEX_VERSION_ENCODE( \
+    CINDEX_VERSION_MAJOR,                     \
+    CINDEX_VERSION_MINOR )
+
+#define CINDEX_VERSION_STRINGIZE_(major, minor)   \
+    #major"."#minor
+#define CINDEX_VERSION_STRINGIZE(major, minor)    \
+    CINDEX_VERSION_STRINGIZE_(major, minor)
+
+#define CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE( \
+    CINDEX_VERSION_MAJOR,                               \
+    CINDEX_VERSION_MINOR)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup CINDEX libclang: C Interface to Clang
+ *
+ * The C Interface to Clang provides a relatively small API that exposes
+ * facilities for parsing source code into an abstract syntax tree (AST),
+ * loading already-parsed ASTs, traversing the AST, associating
+ * physical source locations with elements within the AST, and other
+ * facilities that support Clang-based development tools.
+ *
+ * This C interface to Clang will never provide all of the information
+ * representation stored in Clang's C++ AST, nor should it: the intent is to
+ * maintain an API that is relatively stable from one release to the next,
+ * providing only the basic functionality needed to support development tools.
+ *
+ * To avoid namespace pollution, data types are prefixed with "CX" and
+ * functions are prefixed with "clang_".
+ *
+ * @{
+ */
+
+/**
+ * \brief An "index" that consists of a set of translation units that would
+ * typically be linked together into an executable or library.
+ */
+typedef void *CXIndex;
+
+/**
+ * \brief A single translation unit, which resides in an index.
+ */
+typedef struct CXTranslationUnitImpl *CXTranslationUnit;
+
+/**
+ * \brief Opaque pointer representing client data that will be passed through
+ * to various callbacks and visitors.
+ */
+typedef void *CXClientData;
+
+/**
+ * \brief Provides the contents of a file that has not yet been saved to disk.
+ *
+ * Each CXUnsavedFile instance provides the name of a file on the
+ * system along with the current contents of that file that have not
+ * yet been saved to disk.
+ */
+struct CXUnsavedFile {
+  /**
+   * \brief The file whose contents have not yet been saved.
+   *
+   * This file must already exist in the file system.
+   */
+  const char *Filename;
+
+  /**
+   * \brief A buffer containing the unsaved contents of this file.
+   */
+  const char *Contents;
+
+  /**
+   * \brief The length of the unsaved contents of this buffer.
+   */
+  unsigned long Length;
+};
+
+/**
+ * \brief Describes the availability of a particular entity, which indicates
+ * whether the use of this entity will result in a warning or error due to
+ * it being deprecated or unavailable.
+ */
+enum CXAvailabilityKind {
+  /**
+   * \brief The entity is available.
+   */
+  CXAvailability_Available,
+  /**
+   * \brief The entity is available, but has been deprecated (and its use is
+   * not recommended).
+   */
+  CXAvailability_Deprecated,
+  /**
+   * \brief The entity is not available; any use of it will be an error.
+   */
+  CXAvailability_NotAvailable,
+  /**
+   * \brief The entity is available, but not accessible; any use of it will be
+   * an error.
+   */
+  CXAvailability_NotAccessible
+};
+
+/**
+ * \brief Describes a version number of the form major.minor.subminor.
+ */
+typedef struct CXVersion {
+  /**
+   * \brief The major version number, e.g., the '10' in '10.7.3'. A negative
+   * value indicates that there is no version number at all.
+   */
+  int Major;
+  /**
+   * \brief The minor version number, e.g., the '7' in '10.7.3'. This value
+   * will be negative if no minor version number was provided, e.g., for 
+   * version '10'.
+   */
+  int Minor;
+  /**
+   * \brief The subminor version number, e.g., the '3' in '10.7.3'. This value
+   * will be negative if no minor or subminor version number was provided,
+   * e.g., in version '10' or '10.7'.
+   */
+  int Subminor;
+} CXVersion;
+  
+/**
+ * \brief Provides a shared context for creating translation units.
+ *
+ * It provides two options:
+ *
+ * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+ * declarations (when loading any new translation units). A "local" declaration
+ * is one that belongs in the translation unit itself and not in a precompiled
+ * header that was used by the translation unit. If zero, all declarations
+ * will be enumerated.
+ *
+ * Here is an example:
+ *
+ * \code
+ *   // excludeDeclsFromPCH = 1, displayDiagnostics=1
+ *   Idx = clang_createIndex(1, 1);
+ *
+ *   // IndexTest.pch was produced with the following command:
+ *   // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+ *   TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+ *
+ *   // This will load all the symbols from 'IndexTest.pch'
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ *
+ *   // This will load all the symbols from 'IndexTest.c', excluding symbols
+ *   // from 'IndexTest.pch'.
+ *   char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
+ *   TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
+ *                                                  0, 0);
+ *   clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ *                       TranslationUnitVisitor, 0);
+ *   clang_disposeTranslationUnit(TU);
+ * \endcode
+ *
+ * This process of creating the 'pch', loading it separately, and using it (via
+ * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+ * (which gives the indexer the same performance benefit as the compiler).
+ */
+CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+                                         int displayDiagnostics);
+
+/**
+ * \brief Destroy the given index.
+ *
+ * The index must not be destroyed until all of the translation units created
+ * within that index have been destroyed.
+ */
+CINDEX_LINKAGE void clang_disposeIndex(CXIndex index);
+
+typedef enum {
+  /**
+   * \brief Used to indicate that no special CXIndex options are needed.
+   */
+  CXGlobalOpt_None = 0x0,
+
+  /**
+   * \brief Used to indicate that threads that libclang creates for indexing
+   * purposes should use background priority.
+   *
+   * Affects #clang_indexSourceFile, #clang_indexTranslationUnit,
+   * #clang_parseTranslationUnit, #clang_saveTranslationUnit.
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 0x1,
+
+  /**
+   * \brief Used to indicate that threads that libclang creates for editing
+   * purposes should use background priority.
+   *
+   * Affects #clang_reparseTranslationUnit, #clang_codeCompleteAt,
+   * #clang_annotateTokens
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForEditing = 0x2,
+
+  /**
+   * \brief Used to indicate that all threads that libclang creates should use
+   * background priority.
+   */
+  CXGlobalOpt_ThreadBackgroundPriorityForAll =
+      CXGlobalOpt_ThreadBackgroundPriorityForIndexing |
+      CXGlobalOpt_ThreadBackgroundPriorityForEditing
+
+} CXGlobalOptFlags;
+
+/**
+ * \brief Sets general options associated with a CXIndex.
+ *
+ * For example:
+ * \code
+ * CXIndex idx = ...;
+ * clang_CXIndex_setGlobalOptions(idx,
+ *     clang_CXIndex_getGlobalOptions(idx) |
+ *     CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
+ * \endcode
+ *
+ * \param options A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags.
+ */
+CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);
+
+/**
+ * \brief Gets the general options associated with a CXIndex.
+ *
+ * \returns A bitmask of options, a bitwise OR of CXGlobalOpt_XXX flags that
+ * are associated with the given CXIndex object.
+ */
+CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex);
+
+/**
+ * \defgroup CINDEX_FILES File manipulation routines
+ *
+ * @{
+ */
+
+/**
+ * \brief A particular source file that is part of a translation unit.
+ */
+typedef void *CXFile;
+
+
+/**
+ * \brief Retrieve the complete file and path name of the given file.
+ */
+CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
+
+/**
+ * \brief Retrieve the last modification time of the given file.
+ */
+CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
+
+/**
+ * \brief Uniquely identifies a CXFile, that refers to the same underlying file,
+ * across an indexing session.
+ */
+typedef struct {
+  unsigned long long data[3];
+} CXFileUniqueID;
+
+/**
+ * \brief Retrieve the unique ID for the given \c file.
+ *
+ * \param file the file to get the ID for.
+ * \param outID stores the returned CXFileUniqueID.
+ * \returns If there was a failure getting the unique ID, returns non-zero,
+ * otherwise returns 0.
+*/
+CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID);
+
+/**
+ * \brief Determine whether the given header is guarded against
+ * multiple inclusions, either with the conventional
+ * \#ifndef/\#define/\#endif macro guards or with \#pragma once.
+ */
+CINDEX_LINKAGE unsigned 
+clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
+
+/**
+ * \brief Retrieve a file handle within the given translation unit.
+ *
+ * \param tu the translation unit
+ *
+ * \param file_name the name of the file.
+ *
+ * \returns the file handle for the named file in the translation unit \p tu,
+ * or a NULL file handle if the file was not a part of this translation unit.
+ */
+CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
+                                    const char *file_name);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LOCATIONS Physical source locations
+ *
+ * Clang represents physical source locations in its abstract syntax tree in
+ * great detail, with file, line, and column information for the majority of
+ * the tokens parsed in the source code. These data types and functions are
+ * used to represent source location information, either for a particular
+ * point in the program or for a range of points in the program, and extract
+ * specific location information from those data types.
+ *
+ * @{
+ */
+
+/**
+ * \brief Identifies a specific source location within a translation
+ * unit.
+ *
+ * Use clang_getExpansionLocation() or clang_getSpellingLocation()
+ * to map a source location to a particular file, line, and column.
+ */
+typedef struct {
+  const void *ptr_data[2];
+  unsigned int_data;
+} CXSourceLocation;
+
+/**
+ * \brief Identifies a half-open character range in the source code.
+ *
+ * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
+ * starting and end locations from a source range, respectively.
+ */
+typedef struct {
+  const void *ptr_data[2];
+  unsigned begin_int_data;
+  unsigned end_int_data;
+} CXSourceRange;
+
+/**
+ * \brief Retrieve a NULL (invalid) source location.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(void);
+
+/**
+ * \brief Determine whether two source locations, which must refer into
+ * the same translation unit, refer to exactly the same point in the source
+ * code.
+ *
+ * \returns non-zero if the source locations refer to the same location, zero
+ * if they refer to different locations.
+ */
+CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1,
+                                             CXSourceLocation loc2);
+
+/**
+ * \brief Retrieves the source location associated with a given file/line/column
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+                                                  CXFile file,
+                                                  unsigned line,
+                                                  unsigned column);
+/**
+ * \brief Retrieves the source location associated with a given character offset
+ * in a particular translation unit.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
+                                                           CXFile file,
+                                                           unsigned offset);
+
+/**
+ * \brief Returns non-zero if the given source location is in a system header.
+ */
+CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location);
+
+/**
+ * \brief Returns non-zero if the given source location is in the main file of
+ * the corresponding translation unit.
+ */
+CINDEX_LINKAGE int clang_Location_isFromMainFile(CXSourceLocation location);
+
+/**
+ * \brief Retrieve a NULL (invalid) source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getNullRange(void);
+
+/**
+ * \brief Retrieve a source range given the beginning and ending source
+ * locations.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin,
+                                            CXSourceLocation end);
+
+/**
+ * \brief Determine whether two ranges are equivalent.
+ *
+ * \returns non-zero if the ranges are the same, zero if they differ.
+ */
+CINDEX_LINKAGE unsigned clang_equalRanges(CXSourceRange range1,
+                                          CXSourceRange range2);
+
+/**
+ * \brief Returns non-zero if \p range is null.
+ */
+CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro expansion, retrieves the
+ * location of the macro expansion.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location,
+                                               CXFile *file,
+                                               unsigned *line,
+                                               unsigned *column,
+                                               unsigned *offset);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location, as specified in a # line directive.
+ *
+ * Example: given the following source code in a file somefile.c
+ *
+ * \code
+ * #123 "dummy.c" 1
+ *
+ * static int func(void)
+ * {
+ *     return 0;
+ * }
+ * \endcode
+ *
+ * the location information returned by this function would be
+ *
+ * File: dummy.c Line: 124 Column: 12
+ *
+ * whereas clang_getExpansionLocation would have returned
+ *
+ * File: somefile.c Line: 3 Column: 12
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param filename [out] if non-NULL, will be set to the filename of the
+ * source location. Note that filenames returned will be for "virtual" files,
+ * which don't necessarily exist on the machine running clang - e.g. when
+ * parsing preprocessed output obtained from a different environment. If
+ * a non-NULL value is passed in, remember to dispose of the returned value
+ * using \c clang_disposeString() once you've finished with it. For an invalid
+ * source location, an empty string is returned.
+ *
+ * \param line [out] if non-NULL, will be set to the line number of the
+ * source location. For an invalid source location, zero is returned.
+ *
+ * \param column [out] if non-NULL, will be set to the column number of the
+ * source location. For an invalid source location, zero is returned.
+ */
+CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location,
+                                              CXString *filename,
+                                              unsigned *line,
+                                              unsigned *column);
+
+/**
+ * \brief Legacy API to retrieve the file, line, column, and offset represented
+ * by the given source location.
+ *
+ * This interface has been replaced by the newer interface
+ * #clang_getExpansionLocation(). See that interface's documentation for
+ * details.
+ */
+CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro instantiation, return where the
+ * location was originally spelled in the source file.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location,
+                                              CXFile *file,
+                                              unsigned *line,
+                                              unsigned *column,
+                                              unsigned *offset);
+
+/**
+ * \brief Retrieve the file, line, column, and offset represented by
+ * the given source location.
+ *
+ * If the location refers into a macro expansion, return where the macro was
+ * expanded or where the macro argument was written, if the location points at
+ * a macro argument.
+ *
+ * \param location the location within a source file that will be decomposed
+ * into its parts.
+ *
+ * \param file [out] if non-NULL, will be set to the file to which the given
+ * source location points.
+ *
+ * \param line [out] if non-NULL, will be set to the line to which the given
+ * source location points.
+ *
+ * \param column [out] if non-NULL, will be set to the column to which the given
+ * source location points.
+ *
+ * \param offset [out] if non-NULL, will be set to the offset into the
+ * buffer to which the given source location points.
+ */
+CINDEX_LINKAGE void clang_getFileLocation(CXSourceLocation location,
+                                          CXFile *file,
+                                          unsigned *line,
+                                          unsigned *column,
+                                          unsigned *offset);
+
+/**
+ * \brief Retrieve a source location representing the first character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
+
+/**
+ * \brief Retrieve a source location representing the last character within a
+ * source range.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
+
+/**
+ * \brief Identifies an array of ranges.
+ */
+typedef struct {
+  /** \brief The number of ranges in the \c ranges array. */
+  unsigned count;
+  /**
+   * \brief An array of \c CXSourceRanges.
+   */
+  CXSourceRange *ranges;
+} CXSourceRangeList;
+
+/**
+ * \brief Retrieve all ranges that were skipped by the preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
+                                                         CXFile file);
+
+/**
+ * \brief Destroy the given \c CXSourceRangeList.
+ */
+CINDEX_LINKAGE void clang_disposeSourceRangeList(CXSourceRangeList *ranges);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DIAG Diagnostic reporting
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the severity of a particular diagnostic.
+ */
+enum CXDiagnosticSeverity {
+  /**
+   * \brief A diagnostic that has been suppressed, e.g., by a command-line
+   * option.
+   */
+  CXDiagnostic_Ignored = 0,
+
+  /**
+   * \brief This diagnostic is a note that should be attached to the
+   * previous (non-note) diagnostic.
+   */
+  CXDiagnostic_Note    = 1,
+
+  /**
+   * \brief This diagnostic indicates suspicious code that may not be
+   * wrong.
+   */
+  CXDiagnostic_Warning = 2,
+
+  /**
+   * \brief This diagnostic indicates that the code is ill-formed.
+   */
+  CXDiagnostic_Error   = 3,
+
+  /**
+   * \brief This diagnostic indicates that the code is ill-formed such
+   * that future parser recovery is unlikely to produce useful
+   * results.
+   */
+  CXDiagnostic_Fatal   = 4
+};
+
+/**
+ * \brief A single diagnostic, containing the diagnostic's severity,
+ * location, text, source ranges, and fix-it hints.
+ */
+typedef void *CXDiagnostic;
+
+/**
+ * \brief A group of CXDiagnostics.
+ */
+typedef void *CXDiagnosticSet;
+  
+/**
+ * \brief Determine the number of diagnostics in a CXDiagnosticSet.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given CXDiagnosticSet.
+ *
+ * \param Diags the CXDiagnosticSet to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
+                                                     unsigned Index);  
+
+
+/**
+ * \brief Describes the kind of error that occurred (if any) in a call to
+ * \c clang_loadDiagnostics.
+ */
+enum CXLoadDiag_Error {
+  /**
+   * \brief Indicates that no error occurred.
+   */
+  CXLoadDiag_None = 0,
+  
+  /**
+   * \brief Indicates that an unknown error occurred while attempting to
+   * deserialize diagnostics.
+   */
+  CXLoadDiag_Unknown = 1,
+  
+  /**
+   * \brief Indicates that the file containing the serialized diagnostics
+   * could not be opened.
+   */
+  CXLoadDiag_CannotLoad = 2,
+  
+  /**
+   * \brief Indicates that the serialized diagnostics file is invalid or
+   * corrupt.
+   */
+  CXLoadDiag_InvalidFile = 3
+};
+  
+/**
+ * \brief Deserialize a set of diagnostics from a Clang diagnostics bitcode
+ * file.
+ *
+ * \param file The name of the file to deserialize.
+ * \param error A pointer to a enum value recording if there was a problem
+ *        deserializing the diagnostics.
+ * \param errorString A pointer to a CXString for recording the error string
+ *        if the file was not successfully loaded.
+ *
+ * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise.  These
+ * diagnostics should be released using clang_disposeDiagnosticSet().
+ */
+CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file,
+                                                  enum CXLoadDiag_Error *error,
+                                                  CXString *errorString);
+
+/**
+ * \brief Release a CXDiagnosticSet and all of its contained diagnostics.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags);
+
+/**
+ * \brief Retrieve the child diagnostics of a CXDiagnostic. 
+ *
+ * This CXDiagnosticSet does not need to be released by
+ * clang_disposeDiagnosticSet.
+ */
+CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);
+
+/**
+ * \brief Determine the number of diagnostics produced for the given
+ * translation unit.
+ */
+CINDEX_LINKAGE unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given translation unit.
+ *
+ * \param Unit the translation unit to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit,
+                                                unsigned Index);
+
+/**
+ * \brief Retrieve the complete set of diagnostics associated with a
+ *        translation unit.
+ *
+ * \param Unit the translation unit to query.
+ */
+CINDEX_LINKAGE CXDiagnosticSet
+  clang_getDiagnosticSetFromTU(CXTranslationUnit Unit);  
+
+/**
+ * \brief Destroy a diagnostic.
+ */
+CINDEX_LINKAGE void clang_disposeDiagnostic(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Options to control the display of diagnostics.
+ *
+ * The values in this enum are meant to be combined to customize the
+ * behavior of \c clang_formatDiagnostic().
+ */
+enum CXDiagnosticDisplayOptions {
+  /**
+   * \brief Display the source-location information where the
+   * diagnostic was located.
+   *
+   * When set, diagnostics will be prefixed by the file, line, and
+   * (optionally) column to which the diagnostic refers. For example,
+   *
+   * \code
+   * test.c:28: warning: extra tokens at end of #endif directive
+   * \endcode
+   *
+   * This option corresponds to the clang flag \c -fshow-source-location.
+   */
+  CXDiagnostic_DisplaySourceLocation = 0x01,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include the column number.
+   *
+   * This option corresponds to the clang flag \c -fshow-column.
+   */
+  CXDiagnostic_DisplayColumn = 0x02,
+
+  /**
+   * \brief If displaying the source-location information of the
+   * diagnostic, also include information about source ranges in a
+   * machine-parsable format.
+   *
+   * This option corresponds to the clang flag
+   * \c -fdiagnostics-print-source-range-info.
+   */
+  CXDiagnostic_DisplaySourceRanges = 0x04,
+  
+  /**
+   * \brief Display the option name associated with this diagnostic, if any.
+   *
+   * The option name displayed (e.g., -Wconversion) will be placed in brackets
+   * after the diagnostic text. This option corresponds to the clang flag
+   * \c -fdiagnostics-show-option.
+   */
+  CXDiagnostic_DisplayOption = 0x08,
+  
+  /**
+   * \brief Display the category number associated with this diagnostic, if any.
+   *
+   * The category number is displayed within brackets after the diagnostic text.
+   * This option corresponds to the clang flag 
+   * \c -fdiagnostics-show-category=id.
+   */
+  CXDiagnostic_DisplayCategoryId = 0x10,
+
+  /**
+   * \brief Display the category name associated with this diagnostic, if any.
+   *
+   * The category name is displayed within brackets after the diagnostic text.
+   * This option corresponds to the clang flag 
+   * \c -fdiagnostics-show-category=name.
+   */
+  CXDiagnostic_DisplayCategoryName = 0x20
+};
+
+/**
+ * \brief Format the given diagnostic in a manner that is suitable for display.
+ *
+ * This routine will format the given diagnostic to a string, rendering
+ * the diagnostic according to the various options given. The
+ * \c clang_defaultDiagnosticDisplayOptions() function returns the set of
+ * options that most closely mimics the behavior of the clang compiler.
+ *
+ * \param Diagnostic The diagnostic to print.
+ *
+ * \param Options A set of options that control the diagnostic display,
+ * created by combining \c CXDiagnosticDisplayOptions values.
+ *
+ * \returns A new string containing for formatted diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
+                                               unsigned Options);
+
+/**
+ * \brief Retrieve the set of display options most similar to the
+ * default behavior of the clang compiler.
+ *
+ * \returns A set of display options suitable for use with \c
+ * clang_formatDiagnostic().
+ */
+CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
+
+/**
+ * \brief Determine the severity of the given diagnostic.
+ */
+CINDEX_LINKAGE enum CXDiagnosticSeverity
+clang_getDiagnosticSeverity(CXDiagnostic);
+
+/**
+ * \brief Retrieve the source location of the given diagnostic.
+ *
+ * This location is where Clang would print the caret ('^') when
+ * displaying the diagnostic on the command line.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
+
+/**
+ * \brief Retrieve the text of the given diagnostic.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic);
+
+/**
+ * \brief Retrieve the name of the command-line option that enabled this
+ * diagnostic.
+ *
+ * \param Diag The diagnostic to be queried.
+ *
+ * \param Disable If non-NULL, will be set to the option that disables this
+ * diagnostic (if any).
+ *
+ * \returns A string that contains the command-line option used to enable this
+ * warning, such as "-Wconversion" or "-pedantic". 
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag,
+                                                  CXString *Disable);
+
+/**
+ * \brief Retrieve the category number for this diagnostic.
+ *
+ * Diagnostics can be categorized into groups along with other, related
+ * diagnostics (e.g., diagnostics under the same warning flag). This routine 
+ * retrieves the category number for the given diagnostic.
+ *
+ * \returns The number of the category that contains this diagnostic, or zero
+ * if this diagnostic is uncategorized.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic);
+
+/**
+ * \brief Retrieve the name of a particular diagnostic category.  This
+ *  is now deprecated.  Use clang_getDiagnosticCategoryText()
+ *  instead.
+ *
+ * \param Category A diagnostic category number, as returned by 
+ * \c clang_getDiagnosticCategory().
+ *
+ * \returns The name of the given diagnostic category.
+ */
+CINDEX_DEPRECATED CINDEX_LINKAGE
+CXString clang_getDiagnosticCategoryName(unsigned Category);
+
+/**
+ * \brief Retrieve the diagnostic category text for a given diagnostic.
+ *
+ * \returns The text of the given diagnostic category.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticCategoryText(CXDiagnostic);
+  
+/**
+ * \brief Determine the number of source ranges associated with the given
+ * diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumRanges(CXDiagnostic);
+
+/**
+ * \brief Retrieve a source range associated with the diagnostic.
+ *
+ * A diagnostic's source ranges highlight important elements in the source
+ * code. On the command line, Clang displays source ranges by
+ * underlining them with '~' characters.
+ *
+ * \param Diagnostic the diagnostic whose range is being extracted.
+ *
+ * \param Range the zero-based index specifying which range to
+ *
+ * \returns the requested source range.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,
+                                                      unsigned Range);
+
+/**
+ * \brief Determine the number of fix-it hints associated with the
+ * given diagnostic.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);
+
+/**
+ * \brief Retrieve the replacement information for a given fix-it.
+ *
+ * Fix-its are described in terms of a source range whose contents
+ * should be replaced by a string. This approach generalizes over
+ * three kinds of operations: removal of source code (the range covers
+ * the code to be removed and the replacement string is empty),
+ * replacement of source code (the range covers the code to be
+ * replaced and the replacement string provides the new code), and
+ * insertion (both the start and end of the range point at the
+ * insertion location, and the replacement string provides the text to
+ * insert).
+ *
+ * \param Diagnostic The diagnostic whose fix-its are being queried.
+ *
+ * \param FixIt The zero-based index of the fix-it.
+ *
+ * \param ReplacementRange The source range whose contents will be
+ * replaced with the returned replacement string. Note that source
+ * ranges are half-open ranges [a, b), so the source code should be
+ * replaced from a and up to (but not including) b.
+ *
+ * \returns A string containing text that should be replace the source
+ * code indicated by the \c ReplacementRange.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,
+                                                 unsigned FixIt,
+                                               CXSourceRange *ReplacementRange);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_TRANSLATION_UNIT Translation unit manipulation
+ *
+ * The routines in this group provide the ability to create and destroy
+ * translation units from files, either by parsing the contents of the files or
+ * by reading in a serialized representation of a translation unit.
+ *
+ * @{
+ */
+
+/**
+ * \brief Get the original translation unit source file name.
+ */
+CINDEX_LINKAGE CXString
+clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+
+/**
+ * \brief Return the CXTranslationUnit for a given source file and the provided
+ * command line arguments one would pass to the compiler.
+ *
+ * Note: The 'source_filename' argument is optional.  If the caller provides a
+ * NULL pointer, the name of the source file is expected to reside in the
+ * specified command line arguments.
+ *
+ * Note: When encountered in 'clang_command_line_args', the following options
+ * are ignored:
+ *
+ *   '-c'
+ *   '-emit-ast'
+ *   '-fsyntax-only'
+ *   '-o \<output file>'  (both '-o' and '\<output file>' are ignored)
+ *
+ * \param CIdx The index object with which the translation unit will be
+ * associated.
+ *
+ * \param source_filename The name of the source file to load, or NULL if the
+ * source file is included in \p clang_command_line_args.
+ *
+ * \param num_clang_command_line_args The number of command-line arguments in
+ * \p clang_command_line_args.
+ *
+ * \param clang_command_line_args The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed. Note that the following options are ignored: '-c',
+ * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for code completion, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+                                         CXIndex CIdx,
+                                         const char *source_filename,
+                                         int num_clang_command_line_args,
+                                   const char * const *clang_command_line_args,
+                                         unsigned num_unsaved_files,
+                                         struct CXUnsavedFile *unsaved_files);
+
+/**
+ * \brief Same as \c clang_createTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
+    CXIndex CIdx,
+    const char *ast_filename);
+
+/**
+ * \brief Create a translation unit from an AST file (\c -emit-ast).
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(
+    CXIndex CIdx,
+    const char *ast_filename,
+    CXTranslationUnit *out_TU);
+
+/**
+ * \brief Flags that control the creation of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * constructing the translation unit.
+ */
+enum CXTranslationUnit_Flags {
+  /**
+   * \brief Used to indicate that no special translation-unit options are
+   * needed.
+   */
+  CXTranslationUnit_None = 0x0,
+
+  /**
+   * \brief Used to indicate that the parser should construct a "detailed"
+   * preprocessing record, including all macro definitions and instantiations.
+   *
+   * Constructing a detailed preprocessing record requires more memory
+   * and time to parse, since the information contained in the record
+   * is usually not retained. However, it can be useful for
+   * applications that require more detailed information about the
+   * behavior of the preprocessor.
+   */
+  CXTranslationUnit_DetailedPreprocessingRecord = 0x01,
+
+  /**
+   * \brief Used to indicate that the translation unit is incomplete.
+   *
+   * When a translation unit is considered "incomplete", semantic
+   * analysis that is typically performed at the end of the
+   * translation unit will be suppressed. For example, this suppresses
+   * the completion of tentative declarations in C and of
+   * instantiation of implicitly-instantiation function templates in
+   * C++. This option is typically used when parsing a header with the
+   * intent of producing a precompiled header.
+   */
+  CXTranslationUnit_Incomplete = 0x02,
+  
+  /**
+   * \brief Used to indicate that the translation unit should be built with an 
+   * implicit precompiled header for the preamble.
+   *
+   * An implicit precompiled header is used as an optimization when a
+   * particular translation unit is likely to be reparsed many times
+   * when the sources aren't changing that often. In this case, an
+   * implicit precompiled header will be built containing all of the
+   * initial includes at the top of the main file (what we refer to as
+   * the "preamble" of the file). In subsequent parses, if the
+   * preamble or the files in it have not changed, \c
+   * clang_reparseTranslationUnit() will re-use the implicit
+   * precompiled header to improve parsing performance.
+   */
+  CXTranslationUnit_PrecompiledPreamble = 0x04,
+  
+  /**
+   * \brief Used to indicate that the translation unit should cache some
+   * code-completion results with each reparse of the source file.
+   *
+   * Caching of code-completion results is a performance optimization that
+   * introduces some overhead to reparsing but improves the performance of
+   * code-completion operations.
+   */
+  CXTranslationUnit_CacheCompletionResults = 0x08,
+
+  /**
+   * \brief Used to indicate that the translation unit will be serialized with
+   * \c clang_saveTranslationUnit.
+   *
+   * This option is typically used when parsing a header with the intent of
+   * producing a precompiled header.
+   */
+  CXTranslationUnit_ForSerialization = 0x10,
+
+  /**
+   * \brief DEPRECATED: Enabled chained precompiled preambles in C++.
+   *
+   * Note: this is a *temporary* option that is available only while
+   * we are testing C++ precompiled preamble support. It is deprecated.
+   */
+  CXTranslationUnit_CXXChainedPCH = 0x20,
+
+  /**
+   * \brief Used to indicate that function/method bodies should be skipped while
+   * parsing.
+   *
+   * This option can be used to search for declarations/definitions while
+   * ignoring the usages.
+   */
+  CXTranslationUnit_SkipFunctionBodies = 0x40,
+
+  /**
+   * \brief Used to indicate that brief documentation comments should be
+   * included into the set of code completions returned from this translation
+   * unit.
+   */
+  CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
+};
+
+/**
+ * \brief Returns the set of flags that is suitable for parsing a translation
+ * unit that is being edited.
+ *
+ * The set of flags returned provide options for \c clang_parseTranslationUnit()
+ * to indicate that the translation unit is likely to be reparsed many times,
+ * either explicitly (via \c clang_reparseTranslationUnit()) or implicitly
+ * (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag
+ * set contains an unspecified set of optimizations (e.g., the precompiled 
+ * preamble) geared toward improving the performance of these routines. The
+ * set of optimizations enabled may change from one version to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
+
+/**
+ * \brief Same as \c clang_parseTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+                           const char *source_filename,
+                           const char *const *command_line_args,
+                           int num_command_line_args,
+                           struct CXUnsavedFile *unsaved_files,
+                           unsigned num_unsaved_files,
+                           unsigned options);
+
+/**
+ * \brief Parse the given source file and the translation unit corresponding
+ * to that file.
+ *
+ * This routine is the main entry point for the Clang C API, providing the
+ * ability to parse a source file into a translation unit that can then be
+ * queried by other functions in the API. This routine accepts a set of
+ * command-line arguments so that the compilation can be configured in the same
+ * way that the compiler is configured on the command line.
+ *
+ * \param CIdx The index object with which the translation unit will be 
+ * associated.
+ *
+ * \param source_filename The name of the source file to load, or NULL if the
+ * source file is included in \c command_line_args.
+ *
+ * \param command_line_args The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed. Note that the following options are ignored: '-c', 
+ * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
+ *
+ * \param num_command_line_args The number of command-line arguments in
+ * \c command_line_args.
+ *
+ * \param unsaved_files the files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param num_unsaved_files the number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is managed but not its compilation. This should be a bitwise OR of the
+ * CXTranslationUnit_XXX flags.
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit, describing the parsed code and containing any
+ * diagnostics produced by the compiler.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_parseTranslationUnit2(CXIndex CIdx,
+                            const char *source_filename,
+                            const char *const *command_line_args,
+                            int num_command_line_args,
+                            struct CXUnsavedFile *unsaved_files,
+                            unsigned num_unsaved_files,
+                            unsigned options,
+                            CXTranslationUnit *out_TU);
+
+/**
+ * \brief Flags that control how translation units are saved.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * saving the translation unit.
+ */
+enum CXSaveTranslationUnit_Flags {
+  /**
+   * \brief Used to indicate that no special saving options are needed.
+   */
+  CXSaveTranslationUnit_None = 0x0
+};
+
+/**
+ * \brief Returns the set of flags that is suitable for saving a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_saveTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of options that save translation units with
+ * the most commonly-requested data.
+ */
+CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
+
+/**
+ * \brief Describes the kind of error that occurred (if any) in a call to
+ * \c clang_saveTranslationUnit().
+ */
+enum CXSaveError {
+  /**
+   * \brief Indicates that no error occurred while saving a translation unit.
+   */
+  CXSaveError_None = 0,
+  
+  /**
+   * \brief Indicates that an unknown error occurred while attempting to save
+   * the file.
+   *
+   * This error typically indicates that file I/O failed when attempting to 
+   * write the file.
+   */
+  CXSaveError_Unknown = 1,
+  
+  /**
+   * \brief Indicates that errors during translation prevented this attempt
+   * to save the translation unit.
+   * 
+   * Errors that prevent the translation unit from being saved can be
+   * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic().
+   */
+  CXSaveError_TranslationErrors = 2,
+  
+  /**
+   * \brief Indicates that the translation unit to be saved was somehow
+   * invalid (e.g., NULL).
+   */
+  CXSaveError_InvalidTU = 3
+};
+  
+/**
+ * \brief Saves a translation unit into a serialized representation of
+ * that translation unit on disk.
+ *
+ * Any translation unit that was parsed without error can be saved
+ * into a file. The translation unit can then be deserialized into a
+ * new \c CXTranslationUnit with \c clang_createTranslationUnit() or,
+ * if it is an incomplete translation unit that corresponds to a
+ * header, used as a precompiled header when parsing other translation
+ * units.
+ *
+ * \param TU The translation unit to save.
+ *
+ * \param FileName The file to which the translation unit will be saved.
+ *
+ * \param options A bitmask of options that affects how the translation unit
+ * is saved. This should be a bitwise OR of the
+ * CXSaveTranslationUnit_XXX flags.
+ *
+ * \returns A value that will match one of the enumerators of the CXSaveError
+ * enumeration. Zero (CXSaveError_None) indicates that the translation unit was 
+ * saved successfully, while a non-zero value indicates that a problem occurred.
+ */
+CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
+                                             const char *FileName,
+                                             unsigned options);
+
+/**
+ * \brief Destroy the specified CXTranslationUnit object.
+ */
+CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
+
+/**
+ * \brief Flags that control the reparsing of translation units.
+ *
+ * The enumerators in this enumeration type are meant to be bitwise
+ * ORed together to specify which options should be used when
+ * reparsing the translation unit.
+ */
+enum CXReparse_Flags {
+  /**
+   * \brief Used to indicate that no special reparsing options are needed.
+   */
+  CXReparse_None = 0x0
+};
+ 
+/**
+ * \brief Returns the set of flags that is suitable for reparsing a translation
+ * unit.
+ *
+ * The set of flags returned provide options for
+ * \c clang_reparseTranslationUnit() by default. The returned flag
+ * set contains an unspecified set of optimizations geared toward common uses
+ * of reparsing. The set of optimizations enabled may change from one version 
+ * to the next.
+ */
+CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU);
+
+/**
+ * \brief Reparse the source files that produced this translation unit.
+ *
+ * This routine can be used to re-parse the source files that originally
+ * created the given translation unit, for example because those source files
+ * have changed (either on disk or as passed via \p unsaved_files). The
+ * source code will be reparsed with the same command-line options as it
+ * was originally parsed. 
+ *
+ * Reparsing a translation unit invalidates all cursors and source locations
+ * that refer into that translation unit. This makes reparsing a translation
+ * unit semantically equivalent to destroying the translation unit and then
+ * creating a new translation unit with the same command-line arguments.
+ * However, it may be more efficient to reparse a translation 
+ * unit using this routine.
+ *
+ * \param TU The translation unit whose contents will be re-parsed. The
+ * translation unit must originally have been built with 
+ * \c clang_createTranslationUnitFromSourceFile().
+ *
+ * \param num_unsaved_files The number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param unsaved_files The files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ * 
+ * \param options A bitset of options composed of the flags in CXReparse_Flags.
+ * The function \c clang_defaultReparseOptions() produces a default set of
+ * options recommended for most uses, based on the translation unit.
+ *
+ * \returns 0 if the sources could be reparsed.  A non-zero error code will be
+ * returned if reparsing was impossible, such that the translation unit is
+ * invalid. In such cases, the only valid call for \c TU is
+ * \c clang_disposeTranslationUnit(TU).  The error codes returned by this
+ * routine are described by the \c CXErrorCode enum.
+ */
+CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
+                                                unsigned num_unsaved_files,
+                                          struct CXUnsavedFile *unsaved_files,
+                                                unsigned options);
+
+/**
+  * \brief Categorizes how memory is being used by a translation unit.
+  */
+enum CXTUResourceUsageKind {
+  CXTUResourceUsage_AST = 1,
+  CXTUResourceUsage_Identifiers = 2,
+  CXTUResourceUsage_Selectors = 3,
+  CXTUResourceUsage_GlobalCompletionResults = 4,
+  CXTUResourceUsage_SourceManagerContentCache = 5,
+  CXTUResourceUsage_AST_SideTables = 6,
+  CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7,
+  CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,
+  CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, 
+  CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, 
+  CXTUResourceUsage_Preprocessor = 11,
+  CXTUResourceUsage_PreprocessingRecord = 12,
+  CXTUResourceUsage_SourceManager_DataStructures = 13,
+  CXTUResourceUsage_Preprocessor_HeaderSearch = 14,
+  CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST,
+  CXTUResourceUsage_MEMORY_IN_BYTES_END =
+    CXTUResourceUsage_Preprocessor_HeaderSearch,
+
+  CXTUResourceUsage_First = CXTUResourceUsage_AST,
+  CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch
+};
+
+/**
+  * \brief Returns the human-readable null-terminated C string that represents
+  *  the name of the memory category.  This string should never be freed.
+  */
+CINDEX_LINKAGE
+const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind);
+
+typedef struct CXTUResourceUsageEntry {
+  /* \brief The memory usage category. */
+  enum CXTUResourceUsageKind kind;  
+  /* \brief Amount of resources used. 
+      The units will depend on the resource kind. */
+  unsigned long amount;
+} CXTUResourceUsageEntry;
+
+/**
+  * \brief The memory usage of a CXTranslationUnit, broken into categories.
+  */
+typedef struct CXTUResourceUsage {
+  /* \brief Private data member, used for queries. */
+  void *data;
+
+  /* \brief The number of entries in the 'entries' array. */
+  unsigned numEntries;
+
+  /* \brief An array of key-value pairs, representing the breakdown of memory
+            usage. */
+  CXTUResourceUsageEntry *entries;
+
+} CXTUResourceUsage;
+
+/**
+  * \brief Return the memory usage of a translation unit.  This object
+  *  should be released with clang_disposeCXTUResourceUsage().
+  */
+CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU);
+
+CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage);
+
+/**
+ * @}
+ */
+
+/**
+ * \brief Describes the kind of entity that a cursor refers to.
+ */
+enum CXCursorKind {
+  /* Declarations */
+  /**
+   * \brief A declaration whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed declarations have the same operations as any other kind
+   * of declaration; one can extract their location information,
+   * spelling, find their definitions, etc. However, the specific kind
+   * of the declaration is not reported.
+   */
+  CXCursor_UnexposedDecl                 = 1,
+  /** \brief A C or C++ struct. */
+  CXCursor_StructDecl                    = 2,
+  /** \brief A C or C++ union. */
+  CXCursor_UnionDecl                     = 3,
+  /** \brief A C++ class. */
+  CXCursor_ClassDecl                     = 4,
+  /** \brief An enumeration. */
+  CXCursor_EnumDecl                      = 5,
+  /**
+   * \brief A field (in C) or non-static data member (in C++) in a
+   * struct, union, or C++ class.
+   */
+  CXCursor_FieldDecl                     = 6,
+  /** \brief An enumerator constant. */
+  CXCursor_EnumConstantDecl              = 7,
+  /** \brief A function. */
+  CXCursor_FunctionDecl                  = 8,
+  /** \brief A variable. */
+  CXCursor_VarDecl                       = 9,
+  /** \brief A function or method parameter. */
+  CXCursor_ParmDecl                      = 10,
+  /** \brief An Objective-C \@interface. */
+  CXCursor_ObjCInterfaceDecl             = 11,
+  /** \brief An Objective-C \@interface for a category. */
+  CXCursor_ObjCCategoryDecl              = 12,
+  /** \brief An Objective-C \@protocol declaration. */
+  CXCursor_ObjCProtocolDecl              = 13,
+  /** \brief An Objective-C \@property declaration. */
+  CXCursor_ObjCPropertyDecl              = 14,
+  /** \brief An Objective-C instance variable. */
+  CXCursor_ObjCIvarDecl                  = 15,
+  /** \brief An Objective-C instance method. */
+  CXCursor_ObjCInstanceMethodDecl        = 16,
+  /** \brief An Objective-C class method. */
+  CXCursor_ObjCClassMethodDecl           = 17,
+  /** \brief An Objective-C \@implementation. */
+  CXCursor_ObjCImplementationDecl        = 18,
+  /** \brief An Objective-C \@implementation for a category. */
+  CXCursor_ObjCCategoryImplDecl          = 19,
+  /** \brief A typedef */
+  CXCursor_TypedefDecl                   = 20,
+  /** \brief A C++ class method. */
+  CXCursor_CXXMethod                     = 21,
+  /** \brief A C++ namespace. */
+  CXCursor_Namespace                     = 22,
+  /** \brief A linkage specification, e.g. 'extern "C"'. */
+  CXCursor_LinkageSpec                   = 23,
+  /** \brief A C++ constructor. */
+  CXCursor_Constructor                   = 24,
+  /** \brief A C++ destructor. */
+  CXCursor_Destructor                    = 25,
+  /** \brief A C++ conversion function. */
+  CXCursor_ConversionFunction            = 26,
+  /** \brief A C++ template type parameter. */
+  CXCursor_TemplateTypeParameter         = 27,
+  /** \brief A C++ non-type template parameter. */
+  CXCursor_NonTypeTemplateParameter      = 28,
+  /** \brief A C++ template template parameter. */
+  CXCursor_TemplateTemplateParameter     = 29,
+  /** \brief A C++ function template. */
+  CXCursor_FunctionTemplate              = 30,
+  /** \brief A C++ class template. */
+  CXCursor_ClassTemplate                 = 31,
+  /** \brief A C++ class template partial specialization. */
+  CXCursor_ClassTemplatePartialSpecialization = 32,
+  /** \brief A C++ namespace alias declaration. */
+  CXCursor_NamespaceAlias                = 33,
+  /** \brief A C++ using directive. */
+  CXCursor_UsingDirective                = 34,
+  /** \brief A C++ using declaration. */
+  CXCursor_UsingDeclaration              = 35,
+  /** \brief A C++ alias declaration */
+  CXCursor_TypeAliasDecl                 = 36,
+  /** \brief An Objective-C \@synthesize definition. */
+  CXCursor_ObjCSynthesizeDecl            = 37,
+  /** \brief An Objective-C \@dynamic definition. */
+  CXCursor_ObjCDynamicDecl               = 38,
+  /** \brief An access specifier. */
+  CXCursor_CXXAccessSpecifier            = 39,
+
+  CXCursor_FirstDecl                     = CXCursor_UnexposedDecl,
+  CXCursor_LastDecl                      = CXCursor_CXXAccessSpecifier,
+
+  /* References */
+  CXCursor_FirstRef                      = 40, /* Decl references */
+  CXCursor_ObjCSuperClassRef             = 40,
+  CXCursor_ObjCProtocolRef               = 41,
+  CXCursor_ObjCClassRef                  = 42,
+  /**
+   * \brief A reference to a type declaration.
+   *
+   * A type reference occurs anywhere where a type is named but not
+   * declared. For example, given:
+   *
+   * \code
+   * typedef unsigned size_type;
+   * size_type size;
+   * \endcode
+   *
+   * The typedef is a declaration of size_type (CXCursor_TypedefDecl),
+   * while the type of the variable "size" is referenced. The cursor
+   * referenced by the type of size is the typedef for size_type.
+   */
+  CXCursor_TypeRef                       = 43,
+  CXCursor_CXXBaseSpecifier              = 44,
+  /** 
+   * \brief A reference to a class template, function template, template
+   * template parameter, or class template partial specialization.
+   */
+  CXCursor_TemplateRef                   = 45,
+  /**
+   * \brief A reference to a namespace or namespace alias.
+   */
+  CXCursor_NamespaceRef                  = 46,
+  /**
+   * \brief A reference to a member of a struct, union, or class that occurs in 
+   * some non-expression context, e.g., a designated initializer.
+   */
+  CXCursor_MemberRef                     = 47,
+  /**
+   * \brief A reference to a labeled statement.
+   *
+   * This cursor kind is used to describe the jump to "start_over" in the 
+   * goto statement in the following example:
+   *
+   * \code
+   *   start_over:
+   *     ++counter;
+   *
+   *     goto start_over;
+   * \endcode
+   *
+   * A label reference cursor refers to a label statement.
+   */
+  CXCursor_LabelRef                      = 48,
+  
+  /**
+   * \brief A reference to a set of overloaded functions or function templates
+   * that has not yet been resolved to a specific function or function template.
+   *
+   * An overloaded declaration reference cursor occurs in C++ templates where
+   * a dependent name refers to a function. For example:
+   *
+   * \code
+   * template<typename T> void swap(T&, T&);
+   *
+   * struct X { ... };
+   * void swap(X&, X&);
+   *
+   * template<typename T>
+   * void reverse(T* first, T* last) {
+   *   while (first < last - 1) {
+   *     swap(*first, *--last);
+   *     ++first;
+   *   }
+   * }
+   *
+   * struct Y { };
+   * void swap(Y&, Y&);
+   * \endcode
+   *
+   * Here, the identifier "swap" is associated with an overloaded declaration
+   * reference. In the template definition, "swap" refers to either of the two
+   * "swap" functions declared above, so both results will be available. At
+   * instantiation time, "swap" may also refer to other functions found via
+   * argument-dependent lookup (e.g., the "swap" function at the end of the
+   * example).
+   *
+   * The functions \c clang_getNumOverloadedDecls() and 
+   * \c clang_getOverloadedDecl() can be used to retrieve the definitions
+   * referenced by this cursor.
+   */
+  CXCursor_OverloadedDeclRef             = 49,
+  
+  /**
+   * \brief A reference to a variable that occurs in some non-expression 
+   * context, e.g., a C++ lambda capture list.
+   */
+  CXCursor_VariableRef                   = 50,
+  
+  CXCursor_LastRef                       = CXCursor_VariableRef,
+
+  /* Error conditions */
+  CXCursor_FirstInvalid                  = 70,
+  CXCursor_InvalidFile                   = 70,
+  CXCursor_NoDeclFound                   = 71,
+  CXCursor_NotImplemented                = 72,
+  CXCursor_InvalidCode                   = 73,
+  CXCursor_LastInvalid                   = CXCursor_InvalidCode,
+
+  /* Expressions */
+  CXCursor_FirstExpr                     = 100,
+
+  /**
+   * \brief An expression whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed expressions have the same operations as any other kind
+   * of expression; one can extract their location information,
+   * spelling, children, etc. However, the specific kind of the
+   * expression is not reported.
+   */
+  CXCursor_UnexposedExpr                 = 100,
+
+  /**
+   * \brief An expression that refers to some value declaration, such
+   * as a function, variable, or enumerator.
+   */
+  CXCursor_DeclRefExpr                   = 101,
+
+  /**
+   * \brief An expression that refers to a member of a struct, union,
+   * class, Objective-C class, etc.
+   */
+  CXCursor_MemberRefExpr                 = 102,
+
+  /** \brief An expression that calls a function. */
+  CXCursor_CallExpr                      = 103,
+
+  /** \brief An expression that sends a message to an Objective-C
+   object or class. */
+  CXCursor_ObjCMessageExpr               = 104,
+
+  /** \brief An expression that represents a block literal. */
+  CXCursor_BlockExpr                     = 105,
+
+  /** \brief An integer literal.
+   */
+  CXCursor_IntegerLiteral                = 106,
+
+  /** \brief A floating point number literal.
+   */
+  CXCursor_FloatingLiteral               = 107,
+
+  /** \brief An imaginary number literal.
+   */
+  CXCursor_ImaginaryLiteral              = 108,
+
+  /** \brief A string literal.
+   */
+  CXCursor_StringLiteral                 = 109,
+
+  /** \brief A character literal.
+   */
+  CXCursor_CharacterLiteral              = 110,
+
+  /** \brief A parenthesized expression, e.g. "(1)".
+   *
+   * This AST node is only formed if full location information is requested.
+   */
+  CXCursor_ParenExpr                     = 111,
+
+  /** \brief This represents the unary-expression's (except sizeof and
+   * alignof).
+   */
+  CXCursor_UnaryOperator                 = 112,
+
+  /** \brief [C99 6.5.2.1] Array Subscripting.
+   */
+  CXCursor_ArraySubscriptExpr            = 113,
+
+  /** \brief A builtin binary operation expression such as "x + y" or
+   * "x <= y".
+   */
+  CXCursor_BinaryOperator                = 114,
+
+  /** \brief Compound assignment such as "+=".
+   */
+  CXCursor_CompoundAssignOperator        = 115,
+
+  /** \brief The ?: ternary operator.
+   */
+  CXCursor_ConditionalOperator           = 116,
+
+  /** \brief An explicit cast in C (C99 6.5.4) or a C-style cast in C++
+   * (C++ [expr.cast]), which uses the syntax (Type)expr.
+   *
+   * For example: (int)f.
+   */
+  CXCursor_CStyleCastExpr                = 117,
+
+  /** \brief [C99 6.5.2.5]
+   */
+  CXCursor_CompoundLiteralExpr           = 118,
+
+  /** \brief Describes an C or C++ initializer list.
+   */
+  CXCursor_InitListExpr                  = 119,
+
+  /** \brief The GNU address of label extension, representing &&label.
+   */
+  CXCursor_AddrLabelExpr                 = 120,
+
+  /** \brief This is the GNU Statement Expression extension: ({int X=4; X;})
+   */
+  CXCursor_StmtExpr                      = 121,
+
+  /** \brief Represents a C11 generic selection.
+   */
+  CXCursor_GenericSelectionExpr          = 122,
+
+  /** \brief Implements the GNU __null extension, which is a name for a null
+   * pointer constant that has integral type (e.g., int or long) and is the same
+   * size and alignment as a pointer.
+   *
+   * The __null extension is typically only used by system headers, which define
+   * NULL as __null in C++ rather than using 0 (which is an integer that may not
+   * match the size of a pointer).
+   */
+  CXCursor_GNUNullExpr                   = 123,
+
+  /** \brief C++'s static_cast<> expression.
+   */
+  CXCursor_CXXStaticCastExpr             = 124,
+
+  /** \brief C++'s dynamic_cast<> expression.
+   */
+  CXCursor_CXXDynamicCastExpr            = 125,
+
+  /** \brief C++'s reinterpret_cast<> expression.
+   */
+  CXCursor_CXXReinterpretCastExpr        = 126,
+
+  /** \brief C++'s const_cast<> expression.
+   */
+  CXCursor_CXXConstCastExpr              = 127,
+
+  /** \brief Represents an explicit C++ type conversion that uses "functional"
+   * notion (C++ [expr.type.conv]).
+   *
+   * Example:
+   * \code
+   *   x = int(0.5);
+   * \endcode
+   */
+  CXCursor_CXXFunctionalCastExpr         = 128,
+
+  /** \brief A C++ typeid expression (C++ [expr.typeid]).
+   */
+  CXCursor_CXXTypeidExpr                 = 129,
+
+  /** \brief [C++ 2.13.5] C++ Boolean Literal.
+   */
+  CXCursor_CXXBoolLiteralExpr            = 130,
+
+  /** \brief [C++0x 2.14.7] C++ Pointer Literal.
+   */
+  CXCursor_CXXNullPtrLiteralExpr         = 131,
+
+  /** \brief Represents the "this" expression in C++
+   */
+  CXCursor_CXXThisExpr                   = 132,
+
+  /** \brief [C++ 15] C++ Throw Expression.
+   *
+   * This handles 'throw' and 'throw' assignment-expression. When
+   * assignment-expression isn't present, Op will be null.
+   */
+  CXCursor_CXXThrowExpr                  = 133,
+
+  /** \brief A new expression for memory allocation and constructor calls, e.g:
+   * "new CXXNewExpr(foo)".
+   */
+  CXCursor_CXXNewExpr                    = 134,
+
+  /** \brief A delete expression for memory deallocation and destructor calls,
+   * e.g. "delete[] pArray".
+   */
+  CXCursor_CXXDeleteExpr                 = 135,
+
+  /** \brief A unary expression.
+   */
+  CXCursor_UnaryExpr                     = 136,
+
+  /** \brief An Objective-C string literal i.e. @"foo".
+   */
+  CXCursor_ObjCStringLiteral             = 137,
+
+  /** \brief An Objective-C \@encode expression.
+   */
+  CXCursor_ObjCEncodeExpr                = 138,
+
+  /** \brief An Objective-C \@selector expression.
+   */
+  CXCursor_ObjCSelectorExpr              = 139,
+
+  /** \brief An Objective-C \@protocol expression.
+   */
+  CXCursor_ObjCProtocolExpr              = 140,
+
+  /** \brief An Objective-C "bridged" cast expression, which casts between
+   * Objective-C pointers and C pointers, transferring ownership in the process.
+   *
+   * \code
+   *   NSString *str = (__bridge_transfer NSString *)CFCreateString();
+   * \endcode
+   */
+  CXCursor_ObjCBridgedCastExpr           = 141,
+
+  /** \brief Represents a C++0x pack expansion that produces a sequence of
+   * expressions.
+   *
+   * A pack expansion expression contains a pattern (which itself is an
+   * expression) followed by an ellipsis. For example:
+   *
+   * \code
+   * template<typename F, typename ...Types>
+   * void forward(F f, Types &&...args) {
+   *  f(static_cast<Types&&>(args)...);
+   * }
+   * \endcode
+   */
+  CXCursor_PackExpansionExpr             = 142,
+
+  /** \brief Represents an expression that computes the length of a parameter
+   * pack.
+   *
+   * \code
+   * template<typename ...Types>
+   * struct count {
+   *   static const unsigned value = sizeof...(Types);
+   * };
+   * \endcode
+   */
+  CXCursor_SizeOfPackExpr                = 143,
+
+  /* \brief Represents a C++ lambda expression that produces a local function
+   * object.
+   *
+   * \code
+   * void abssort(float *x, unsigned N) {
+   *   std::sort(x, x + N,
+   *             [](float a, float b) {
+   *               return std::abs(a) < std::abs(b);
+   *             });
+   * }
+   * \endcode
+   */
+  CXCursor_LambdaExpr                    = 144,
+  
+  /** \brief Objective-c Boolean Literal.
+   */
+  CXCursor_ObjCBoolLiteralExpr           = 145,
+
+  /** \brief Represents the "self" expression in an Objective-C method.
+   */
+  CXCursor_ObjCSelfExpr                  = 146,
+
+  CXCursor_LastExpr                      = CXCursor_ObjCSelfExpr,
+
+  /* Statements */
+  CXCursor_FirstStmt                     = 200,
+  /**
+   * \brief A statement whose specific kind is not exposed via this
+   * interface.
+   *
+   * Unexposed statements have the same operations as any other kind of
+   * statement; one can extract their location information, spelling,
+   * children, etc. However, the specific kind of the statement is not
+   * reported.
+   */
+  CXCursor_UnexposedStmt                 = 200,
+  
+  /** \brief A labelled statement in a function. 
+   *
+   * This cursor kind is used to describe the "start_over:" label statement in 
+   * the following example:
+   *
+   * \code
+   *   start_over:
+   *     ++counter;
+   * \endcode
+   *
+   */
+  CXCursor_LabelStmt                     = 201,
+
+  /** \brief A group of statements like { stmt stmt }.
+   *
+   * This cursor kind is used to describe compound statements, e.g. function
+   * bodies.
+   */
+  CXCursor_CompoundStmt                  = 202,
+
+  /** \brief A case statement.
+   */
+  CXCursor_CaseStmt                      = 203,
+
+  /** \brief A default statement.
+   */
+  CXCursor_DefaultStmt                   = 204,
+
+  /** \brief An if statement
+   */
+  CXCursor_IfStmt                        = 205,
+
+  /** \brief A switch statement.
+   */
+  CXCursor_SwitchStmt                    = 206,
+
+  /** \brief A while statement.
+   */
+  CXCursor_WhileStmt                     = 207,
+
+  /** \brief A do statement.
+   */
+  CXCursor_DoStmt                        = 208,
+
+  /** \brief A for statement.
+   */
+  CXCursor_ForStmt                       = 209,
+
+  /** \brief A goto statement.
+   */
+  CXCursor_GotoStmt                      = 210,
+
+  /** \brief An indirect goto statement.
+   */
+  CXCursor_IndirectGotoStmt              = 211,
+
+  /** \brief A continue statement.
+   */
+  CXCursor_ContinueStmt                  = 212,
+
+  /** \brief A break statement.
+   */
+  CXCursor_BreakStmt                     = 213,
+
+  /** \brief A return statement.
+   */
+  CXCursor_ReturnStmt                    = 214,
+
+  /** \brief A GCC inline assembly statement extension.
+   */
+  CXCursor_GCCAsmStmt                    = 215,
+  CXCursor_AsmStmt                       = CXCursor_GCCAsmStmt,
+
+  /** \brief Objective-C's overall \@try-\@catch-\@finally statement.
+   */
+  CXCursor_ObjCAtTryStmt                 = 216,
+
+  /** \brief Objective-C's \@catch statement.
+   */
+  CXCursor_ObjCAtCatchStmt               = 217,
+
+  /** \brief Objective-C's \@finally statement.
+   */
+  CXCursor_ObjCAtFinallyStmt             = 218,
+
+  /** \brief Objective-C's \@throw statement.
+   */
+  CXCursor_ObjCAtThrowStmt               = 219,
+
+  /** \brief Objective-C's \@synchronized statement.
+   */
+  CXCursor_ObjCAtSynchronizedStmt        = 220,
+
+  /** \brief Objective-C's autorelease pool statement.
+   */
+  CXCursor_ObjCAutoreleasePoolStmt       = 221,
+
+  /** \brief Objective-C's collection statement.
+   */
+  CXCursor_ObjCForCollectionStmt         = 222,
+
+  /** \brief C++'s catch statement.
+   */
+  CXCursor_CXXCatchStmt                  = 223,
+
+  /** \brief C++'s try statement.
+   */
+  CXCursor_CXXTryStmt                    = 224,
+
+  /** \brief C++'s for (* : *) statement.
+   */
+  CXCursor_CXXForRangeStmt               = 225,
+
+  /** \brief Windows Structured Exception Handling's try statement.
+   */
+  CXCursor_SEHTryStmt                    = 226,
+
+  /** \brief Windows Structured Exception Handling's except statement.
+   */
+  CXCursor_SEHExceptStmt                 = 227,
+
+  /** \brief Windows Structured Exception Handling's finally statement.
+   */
+  CXCursor_SEHFinallyStmt                = 228,
+
+  /** \brief A MS inline assembly statement extension.
+   */
+  CXCursor_MSAsmStmt                     = 229,
+
+  /** \brief The null satement ";": C99 6.8.3p3.
+   *
+   * This cursor kind is used to describe the null statement.
+   */
+  CXCursor_NullStmt                      = 230,
+
+  /** \brief Adaptor class for mixing declarations with statements and
+   * expressions.
+   */
+  CXCursor_DeclStmt                      = 231,
+
+  /** \brief OpenMP parallel directive.
+   */
+  CXCursor_OMPParallelDirective          = 232,
+
+  /** \brief OpenMP simd directive.
+   */
+  CXCursor_OMPSimdDirective              = 233,
+
+  /** \brief OpenMP for directive.
+   */
+  CXCursor_OMPForDirective               = 234,
+
+  /** \brief OpenMP sections directive.
+   */
+  CXCursor_OMPSectionsDirective          = 235,
+
+  /** \brief OpenMP section directive.
+   */
+  CXCursor_OMPSectionDirective           = 236,
+
+  /** \brief OpenMP single directive.
+   */
+  CXCursor_OMPSingleDirective            = 237,
+
+  /** \brief OpenMP parallel for directive.
+   */
+  CXCursor_OMPParallelForDirective       = 238,
+
+  /** \brief OpenMP parallel sections directive.
+   */
+  CXCursor_OMPParallelSectionsDirective  = 239,
+
+  /** \brief OpenMP task directive.
+   */
+  CXCursor_OMPTaskDirective              = 240,
+
+  /** \brief OpenMP master directive.
+   */
+  CXCursor_OMPMasterDirective            = 241,
+
+  /** \brief OpenMP critical directive.
+   */
+  CXCursor_OMPCriticalDirective          = 242,
+
+  /** \brief OpenMP taskyield directive.
+   */
+  CXCursor_OMPTaskyieldDirective         = 243,
+
+  /** \brief OpenMP barrier directive.
+   */
+  CXCursor_OMPBarrierDirective           = 244,
+
+  /** \brief OpenMP taskwait directive.
+   */
+  CXCursor_OMPTaskwaitDirective          = 245,
+
+  /** \brief OpenMP flush directive.
+   */
+  CXCursor_OMPFlushDirective             = 246,
+
+  /** \brief Windows Structured Exception Handling's leave statement.
+   */
+  CXCursor_SEHLeaveStmt                  = 247,
+
+  CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
+
+  /**
+   * \brief Cursor that represents the translation unit itself.
+   *
+   * The translation unit cursor exists primarily to act as the root
+   * cursor for traversing the contents of a translation unit.
+   */
+  CXCursor_TranslationUnit               = 300,
+
+  /* Attributes */
+  CXCursor_FirstAttr                     = 400,
+  /**
+   * \brief An attribute whose specific kind is not exposed via this
+   * interface.
+   */
+  CXCursor_UnexposedAttr                 = 400,
+
+  CXCursor_IBActionAttr                  = 401,
+  CXCursor_IBOutletAttr                  = 402,
+  CXCursor_IBOutletCollectionAttr        = 403,
+  CXCursor_CXXFinalAttr                  = 404,
+  CXCursor_CXXOverrideAttr               = 405,
+  CXCursor_AnnotateAttr                  = 406,
+  CXCursor_AsmLabelAttr                  = 407,
+  CXCursor_PackedAttr                    = 408,
+  CXCursor_PureAttr                      = 409,
+  CXCursor_ConstAttr                     = 410,
+  CXCursor_NoDuplicateAttr               = 411,
+  CXCursor_CUDAConstantAttr              = 412,
+  CXCursor_CUDADeviceAttr                = 413,
+  CXCursor_CUDAGlobalAttr                = 414,
+  CXCursor_CUDAHostAttr                  = 415,
+  CXCursor_LastAttr                      = CXCursor_CUDAHostAttr,
+
+  /* Preprocessing */
+  CXCursor_PreprocessingDirective        = 500,
+  CXCursor_MacroDefinition               = 501,
+  CXCursor_MacroExpansion                = 502,
+  CXCursor_MacroInstantiation            = CXCursor_MacroExpansion,
+  CXCursor_InclusionDirective            = 503,
+  CXCursor_FirstPreprocessing            = CXCursor_PreprocessingDirective,
+  CXCursor_LastPreprocessing             = CXCursor_InclusionDirective,
+
+  /* Extra Declarations */
+  /**
+   * \brief A module import declaration.
+   */
+  CXCursor_ModuleImportDecl              = 600,
+  CXCursor_FirstExtraDecl                = CXCursor_ModuleImportDecl,
+  CXCursor_LastExtraDecl                 = CXCursor_ModuleImportDecl
+};
+
+/**
+ * \brief A cursor representing some element in the abstract syntax tree for
+ * a translation unit.
+ *
+ * The cursor abstraction unifies the different kinds of entities in a
+ * program--declaration, statements, expressions, references to declarations,
+ * etc.--under a single "cursor" abstraction with a common set of operations.
+ * Common operation for a cursor include: getting the physical location in
+ * a source file where the cursor points, getting the name associated with a
+ * cursor, and retrieving cursors for any child nodes of a particular cursor.
+ *
+ * Cursors can be produced in two specific ways.
+ * clang_getTranslationUnitCursor() produces a cursor for a translation unit,
+ * from which one can use clang_visitChildren() to explore the rest of the
+ * translation unit. clang_getCursor() maps from a physical source location
+ * to the entity that resides at that location, allowing one to map from the
+ * source code into the AST.
+ */
+typedef struct {
+  enum CXCursorKind kind;
+  int xdata;
+  const void *data[3];
+} CXCursor;
+
+/**
+ * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve the NULL cursor, which represents no entity.
+ */
+CINDEX_LINKAGE CXCursor clang_getNullCursor(void);
+
+/**
+ * \brief Retrieve the cursor that represents the given translation unit.
+ *
+ * The translation unit cursor can be used to start traversing the
+ * various declarations within the given translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
+
+/**
+ * \brief Determine whether two cursors are equivalent.
+ */
+CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor);
+
+/**
+ * \brief Returns non-zero if \p cursor is null.
+ */
+CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor cursor);
+
+/**
+ * \brief Compute a hash value for the given cursor.
+ */
+CINDEX_LINKAGE unsigned clang_hashCursor(CXCursor);
+  
+/**
+ * \brief Retrieve the kind of the given cursor.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor);
+
+/**
+ * \brief Determine whether the given cursor kind represents a declaration.
+ */
+CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a simple
+ * reference.
+ *
+ * Note that other kinds of cursors (such as expressions) can also refer to
+ * other cursors. Use clang_getCursorReferenced() to determine whether a
+ * particular cursor refers to another entity.
+ */
+CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an expression.
+ */
+CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a statement.
+ */
+CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an attribute.
+ */
+CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents an invalid
+ * cursor.
+ */
+CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
+
+/**
+ * \brief Determine whether the given cursor kind represents a translation
+ * unit.
+ */
+CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
+
+/***
+ * \brief Determine whether the given cursor represents a preprocessing
+ * element, such as a preprocessor directive or macro instantiation.
+ */
+CINDEX_LINKAGE unsigned clang_isPreprocessing(enum CXCursorKind);
+  
+/***
+ * \brief Determine whether the given cursor represents a currently
+ *  unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+ */
+CINDEX_LINKAGE unsigned clang_isUnexposed(enum CXCursorKind);
+
+/**
+ * \brief Describe the linkage of the entity referred to by a cursor.
+ */
+enum CXLinkageKind {
+  /** \brief This value indicates that no linkage information is available
+   * for a provided CXCursor. */
+  CXLinkage_Invalid,
+  /**
+   * \brief This is the linkage for variables, parameters, and so on that
+   *  have automatic storage.  This covers normal (non-extern) local variables.
+   */
+  CXLinkage_NoLinkage,
+  /** \brief This is the linkage for static variables and static functions. */
+  CXLinkage_Internal,
+  /** \brief This is the linkage for entities with external linkage that live
+   * in C++ anonymous namespaces.*/
+  CXLinkage_UniqueExternal,
+  /** \brief This is the linkage for entities with true, external linkage. */
+  CXLinkage_External
+};
+
+/**
+ * \brief Determine the linkage of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);
+
+/**
+ * \brief Determine the availability of the entity that this cursor refers to,
+ * taking the current target platform into account.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns The availability of the cursor.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind 
+clang_getCursorAvailability(CXCursor cursor);
+
+/**
+ * Describes the availability of a given entity on a particular platform, e.g.,
+ * a particular class might only be available on Mac OS 10.7 or newer.
+ */
+typedef struct CXPlatformAvailability {
+  /**
+   * \brief A string that describes the platform for which this structure
+   * provides availability information.
+   *
+   * Possible values are "ios" or "macosx".
+   */
+  CXString Platform;
+  /**
+   * \brief The version number in which this entity was introduced.
+   */
+  CXVersion Introduced;
+  /**
+   * \brief The version number in which this entity was deprecated (but is
+   * still available).
+   */
+  CXVersion Deprecated;
+  /**
+   * \brief The version number in which this entity was obsoleted, and therefore
+   * is no longer available.
+   */
+  CXVersion Obsoleted;
+  /**
+   * \brief Whether the entity is unconditionally unavailable on this platform.
+   */
+  int Unavailable;
+  /**
+   * \brief An optional message to provide to a user of this API, e.g., to
+   * suggest replacement APIs.
+   */
+  CXString Message;
+} CXPlatformAvailability;
+
+/**
+ * \brief Determine the availability of the entity that this cursor refers to
+ * on any platforms for which availability information is known.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \param always_deprecated If non-NULL, will be set to indicate whether the 
+ * entity is deprecated on all platforms.
+ *
+ * \param deprecated_message If non-NULL, will be set to the message text 
+ * provided along with the unconditional deprecation of this entity. The client
+ * is responsible for deallocating this string.
+ *
+ * \param always_unavailable If non-NULL, will be set to indicate whether the
+ * entity is unavailable on all platforms.
+ *
+ * \param unavailable_message If non-NULL, will be set to the message text
+ * provided along with the unconditional unavailability of this entity. The 
+ * client is responsible for deallocating this string.
+ *
+ * \param availability If non-NULL, an array of CXPlatformAvailability instances
+ * that will be populated with platform availability information, up to either
+ * the number of platforms for which availability information is available (as
+ * returned by this function) or \c availability_size, whichever is smaller.
+ *
+ * \param availability_size The number of elements available in the 
+ * \c availability array.
+ *
+ * \returns The number of platforms (N) for which availability information is
+ * available (which is unrelated to \c availability_size).
+ *
+ * Note that the client is responsible for calling 
+ * \c clang_disposeCXPlatformAvailability to free each of the 
+ * platform-availability structures returned. There are 
+ * \c min(N, availability_size) such structures.
+ */
+CINDEX_LINKAGE int
+clang_getCursorPlatformAvailability(CXCursor cursor,
+                                    int *always_deprecated,
+                                    CXString *deprecated_message,
+                                    int *always_unavailable,
+                                    CXString *unavailable_message,
+                                    CXPlatformAvailability *availability,
+                                    int availability_size);
+
+/**
+ * \brief Free the memory associated with a \c CXPlatformAvailability structure.
+ */
+CINDEX_LINKAGE void
+clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability);
+  
+/**
+ * \brief Describe the "language" of the entity referred to by a cursor.
+ */
+enum CXLanguageKind {
+  CXLanguage_Invalid = 0,
+  CXLanguage_C,
+  CXLanguage_ObjC,
+  CXLanguage_CPlusPlus
+};
+
+/**
+ * \brief Determine the "language" of the entity referred to by a given cursor.
+ */
+CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
+
+/**
+ * \brief Returns the translation unit that a cursor originated from.
+ */
+CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor);
+
+
+/**
+ * \brief A fast container representing a set of CXCursors.
+ */
+typedef struct CXCursorSetImpl *CXCursorSet;
+
+/**
+ * \brief Creates an empty CXCursorSet.
+ */
+CINDEX_LINKAGE CXCursorSet clang_createCXCursorSet(void);
+
+/**
+ * \brief Disposes a CXCursorSet and releases its associated memory.
+ */
+CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset);
+
+/**
+ * \brief Queries a CXCursorSet to see if it contains a specific CXCursor.
+ *
+ * \returns non-zero if the set contains the specified cursor.
+*/
+CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset,
+                                                   CXCursor cursor);
+
+/**
+ * \brief Inserts a CXCursor into a CXCursorSet.
+ *
+ * \returns zero if the CXCursor was already in the set, and non-zero otherwise.
+*/
+CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset,
+                                                 CXCursor cursor);
+
+/**
+ * \brief Determine the semantic parent of the given cursor.
+ *
+ * The semantic parent of a cursor is the cursor that semantically contains
+ * the given \p cursor. For many declarations, the lexical and semantic parents
+ * are equivalent (the lexical parent is returned by 
+ * \c clang_getCursorLexicalParent()). They diverge when declarations or
+ * definitions are provided out-of-line. For example:
+ *
+ * \code
+ * class C {
+ *  void f();
+ * };
+ *
+ * void C::f() { }
+ * \endcode
+ *
+ * In the out-of-line definition of \c C::f, the semantic parent is
+ * the class \c C, of which this function is a member. The lexical parent is
+ * the place where the declaration actually occurs in the source code; in this
+ * case, the definition occurs in the translation unit. In general, the
+ * lexical parent for a given entity can change without affecting the semantics
+ * of the program, and the lexical parent of different declarations of the
+ * same entity may be different. Changing the semantic parent of a declaration,
+ * on the other hand, can have a major impact on semantics, and redeclarations
+ * of a particular entity should all have the same semantic context.
+ *
+ * In the example above, both declarations of \c C::f have \c C as their
+ * semantic context, while the lexical context of the first \c C::f is \c C
+ * and the lexical context of the second \c C::f is the translation unit.
+ *
+ * For global declarations, the semantic parent is the translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor);
+
+/**
+ * \brief Determine the lexical parent of the given cursor.
+ *
+ * The lexical parent of a cursor is the cursor in which the given \p cursor
+ * was actually written. For many declarations, the lexical and semantic parents
+ * are equivalent (the semantic parent is returned by 
+ * \c clang_getCursorSemanticParent()). They diverge when declarations or
+ * definitions are provided out-of-line. For example:
+ *
+ * \code
+ * class C {
+ *  void f();
+ * };
+ *
+ * void C::f() { }
+ * \endcode
+ *
+ * In the out-of-line definition of \c C::f, the semantic parent is
+ * the class \c C, of which this function is a member. The lexical parent is
+ * the place where the declaration actually occurs in the source code; in this
+ * case, the definition occurs in the translation unit. In general, the
+ * lexical parent for a given entity can change without affecting the semantics
+ * of the program, and the lexical parent of different declarations of the
+ * same entity may be different. Changing the semantic parent of a declaration,
+ * on the other hand, can have a major impact on semantics, and redeclarations
+ * of a particular entity should all have the same semantic context.
+ *
+ * In the example above, both declarations of \c C::f have \c C as their
+ * semantic context, while the lexical context of the first \c C::f is \c C
+ * and the lexical context of the second \c C::f is the translation unit.
+ *
+ * For declarations written in the global scope, the lexical parent is
+ * the translation unit.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor);
+
+/**
+ * \brief Determine the set of methods that are overridden by the given
+ * method.
+ *
+ * In both Objective-C and C++, a method (aka virtual member function,
+ * in C++) can override a virtual method in a base class. For
+ * Objective-C, a method is said to override any method in the class's
+ * base class, its protocols, or its categories' protocols, that has the same
+ * selector and is of the same kind (class or instance).
+ * If no such method exists, the search continues to the class's superclass,
+ * its protocols, and its categories, and so on. A method from an Objective-C
+ * implementation is considered to override the same methods as its
+ * corresponding method in the interface.
+ *
+ * For C++, a virtual member function overrides any virtual member
+ * function with the same signature that occurs in its base
+ * classes. With multiple inheritance, a virtual member function can
+ * override several virtual member functions coming from different
+ * base classes.
+ *
+ * In all cases, this function determines the immediate overridden
+ * method, rather than all of the overridden methods. For example, if
+ * a method is originally declared in a class A, then overridden in B
+ * (which in inherits from A) and also in C (which inherited from B),
+ * then the only overridden method returned from this function when
+ * invoked on C's method will be B's method. The client may then
+ * invoke this function again, given the previously-found overridden
+ * methods, to map out the complete method-override set.
+ *
+ * \param cursor A cursor representing an Objective-C or C++
+ * method. This routine will compute the set of methods that this
+ * method overrides.
+ * 
+ * \param overridden A pointer whose pointee will be replaced with a
+ * pointer to an array of cursors, representing the set of overridden
+ * methods. If there are no overridden methods, the pointee will be
+ * set to NULL. The pointee must be freed via a call to 
+ * \c clang_disposeOverriddenCursors().
+ *
+ * \param num_overridden A pointer to the number of overridden
+ * functions, will be set to the number of overridden functions in the
+ * array pointed to by \p overridden.
+ */
+CINDEX_LINKAGE void clang_getOverriddenCursors(CXCursor cursor, 
+                                               CXCursor **overridden,
+                                               unsigned *num_overridden);
+
+/**
+ * \brief Free the set of overridden cursors returned by \c
+ * clang_getOverriddenCursors().
+ */
+CINDEX_LINKAGE void clang_disposeOverriddenCursors(CXCursor *overridden);
+
+/**
+ * \brief Retrieve the file that is included by the given inclusion directive
+ * cursor.
+ */
+CINDEX_LINKAGE CXFile clang_getIncludedFile(CXCursor cursor);
+  
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_SOURCE Mapping between cursors and source code
+ *
+ * Cursors represent a location within the Abstract Syntax Tree (AST). These
+ * routines help map between cursors and the physical locations where the
+ * described entities occur in the source code. The mapping is provided in
+ * both directions, so one can map from source code to the AST and back.
+ *
+ * @{
+ */
+
+/**
+ * \brief Map a source location to the cursor that describes the entity at that
+ * location in the source code.
+ *
+ * clang_getCursor() maps an arbitrary source location within a translation
+ * unit down to the most specific cursor that describes the entity at that
+ * location. For example, given an expression \c x + y, invoking
+ * clang_getCursor() with a source location pointing to "x" will return the
+ * cursor for "x"; similarly for "y". If the cursor points anywhere between
+ * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor()
+ * will return a cursor referring to the "+" expression.
+ *
+ * \returns a cursor representing the entity at the given source location, or
+ * a NULL cursor if no such entity can be found.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);
+
+/**
+ * \brief Retrieve the physical location of the source constructor referenced
+ * by the given cursor.
+ *
+ * The location of a declaration is typically the location of the name of that
+ * declaration, where the name of that declaration would occur if it is
+ * unnamed, or some keyword that introduces that particular declaration.
+ * The location of a reference is where that reference occurs within the
+ * source code.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
+
+/**
+ * \brief Retrieve the physical extent of the source construct referenced by
+ * the given cursor.
+ *
+ * The extent of a cursor starts with the file/line/column pointing at the
+ * first character within the source construct that the cursor refers to and
+ * ends with the last character within that source construct. For a
+ * declaration, the extent covers the declaration itself. For a reference,
+ * the extent covers the location of the reference (e.g., where the referenced
+ * entity was actually used).
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
+
+/**
+ * @}
+ */
+    
+/**
+ * \defgroup CINDEX_TYPES Type information for CXCursors
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes the kind of type
+ */
+enum CXTypeKind {
+  /**
+   * \brief Represents an invalid type (e.g., where no type is available).
+   */
+  CXType_Invalid = 0,
+
+  /**
+   * \brief A type whose specific kind is not exposed via this
+   * interface.
+   */
+  CXType_Unexposed = 1,
+
+  /* Builtin types */
+  CXType_Void = 2,
+  CXType_Bool = 3,
+  CXType_Char_U = 4,
+  CXType_UChar = 5,
+  CXType_Char16 = 6,
+  CXType_Char32 = 7,
+  CXType_UShort = 8,
+  CXType_UInt = 9,
+  CXType_ULong = 10,
+  CXType_ULongLong = 11,
+  CXType_UInt128 = 12,
+  CXType_Char_S = 13,
+  CXType_SChar = 14,
+  CXType_WChar = 15,
+  CXType_Short = 16,
+  CXType_Int = 17,
+  CXType_Long = 18,
+  CXType_LongLong = 19,
+  CXType_Int128 = 20,
+  CXType_Float = 21,
+  CXType_Double = 22,
+  CXType_LongDouble = 23,
+  CXType_NullPtr = 24,
+  CXType_Overload = 25,
+  CXType_Dependent = 26,
+  CXType_ObjCId = 27,
+  CXType_ObjCClass = 28,
+  CXType_ObjCSel = 29,
+  CXType_FirstBuiltin = CXType_Void,
+  CXType_LastBuiltin  = CXType_ObjCSel,
+
+  CXType_Complex = 100,
+  CXType_Pointer = 101,
+  CXType_BlockPointer = 102,
+  CXType_LValueReference = 103,
+  CXType_RValueReference = 104,
+  CXType_Record = 105,
+  CXType_Enum = 106,
+  CXType_Typedef = 107,
+  CXType_ObjCInterface = 108,
+  CXType_ObjCObjectPointer = 109,
+  CXType_FunctionNoProto = 110,
+  CXType_FunctionProto = 111,
+  CXType_ConstantArray = 112,
+  CXType_Vector = 113,
+  CXType_IncompleteArray = 114,
+  CXType_VariableArray = 115,
+  CXType_DependentSizedArray = 116,
+  CXType_MemberPointer = 117
+};
+
+/**
+ * \brief Describes the calling convention of a function type
+ */
+enum CXCallingConv {
+  CXCallingConv_Default = 0,
+  CXCallingConv_C = 1,
+  CXCallingConv_X86StdCall = 2,
+  CXCallingConv_X86FastCall = 3,
+  CXCallingConv_X86ThisCall = 4,
+  CXCallingConv_X86Pascal = 5,
+  CXCallingConv_AAPCS = 6,
+  CXCallingConv_AAPCS_VFP = 7,
+  CXCallingConv_PnaclCall = 8,
+  CXCallingConv_IntelOclBicc = 9,
+  CXCallingConv_X86_64Win64 = 10,
+  CXCallingConv_X86_64SysV = 11,
+
+  CXCallingConv_Invalid = 100,
+  CXCallingConv_Unexposed = 200
+};
+
+
+/**
+ * \brief The type of an element in the abstract syntax tree.
+ *
+ */
+typedef struct {
+  enum CXTypeKind kind;
+  void *data[2];
+} CXType;
+
+/**
+ * \brief Retrieve the type of a CXCursor (if any).
+ */
+CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
+
+/**
+ * \brief Pretty-print the underlying type using the rules of the
+ * language of the translation unit from which it came.
+ *
+ * If the type is invalid, an empty string is returned.
+ */
+CINDEX_LINKAGE CXString clang_getTypeSpelling(CXType CT);
+
+/**
+ * \brief Retrieve the underlying type of a typedef declaration.
+ *
+ * If the cursor does not reference a typedef declaration, an invalid type is
+ * returned.
+ */
+CINDEX_LINKAGE CXType clang_getTypedefDeclUnderlyingType(CXCursor C);
+
+/**
+ * \brief Retrieve the integer type of an enum declaration.
+ *
+ * If the cursor does not reference an enum declaration, an invalid type is
+ * returned.
+ */
+CINDEX_LINKAGE CXType clang_getEnumDeclIntegerType(CXCursor C);
+
+/**
+ * \brief Retrieve the integer value of an enum constant declaration as a signed
+ *  long long.
+ *
+ * If the cursor does not reference an enum constant declaration, LLONG_MIN is returned.
+ * Since this is also potentially a valid constant value, the kind of the cursor
+ * must be verified before calling this function.
+ */
+CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C);
+
+/**
+ * \brief Retrieve the integer value of an enum constant declaration as an unsigned
+ *  long long.
+ *
+ * If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned.
+ * Since this is also potentially a valid constant value, the kind of the cursor
+ * must be verified before calling this function.
+ */
+CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C);
+
+/**
+ * \brief Retrieve the bit width of a bit field declaration as an integer.
+ *
+ * If a cursor that is not a bit field declaration is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
+
+/**
+ * \brief Retrieve the number of non-variadic arguments associated with a given
+ * cursor.
+ *
+ * The number of arguments can be determined for calls as well as for
+ * declarations of functions or methods. For other cursors -1 is returned.
+ */
+CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
+
+/**
+ * \brief Retrieve the argument cursor of a function or method.
+ *
+ * The argument cursor can be determined for calls as well as for declarations
+ * of functions or methods. For other cursors and for invalid indices, an
+ * invalid cursor is returned.
+ */
+CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
+
+/**
+ * \brief Determine whether two CXTypes represent the same type.
+ *
+ * \returns non-zero if the CXTypes represent the same type and
+ *          zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
+
+/**
+ * \brief Return the canonical type for a CXType.
+ *
+ * Clang's type system explicitly models typedefs and all the ways
+ * a specific type can be represented.  The canonical type is the underlying
+ * type with all the "sugar" removed.  For example, if 'T' is a typedef
+ * for 'int', the canonical type for 'T' would be 'int'.
+ */
+CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
+
+/**
+ * \brief Determine whether a CXType has the "const" qualifier set,
+ * without looking through typedefs that may have added "const" at a
+ * different level.
+ */
+CINDEX_LINKAGE unsigned clang_isConstQualifiedType(CXType T);
+
+/**
+ * \brief Determine whether a CXType has the "volatile" qualifier set,
+ * without looking through typedefs that may have added "volatile" at
+ * a different level.
+ */
+CINDEX_LINKAGE unsigned clang_isVolatileQualifiedType(CXType T);
+
+/**
+ * \brief Determine whether a CXType has the "restrict" qualifier set,
+ * without looking through typedefs that may have added "restrict" at a
+ * different level.
+ */
+CINDEX_LINKAGE unsigned clang_isRestrictQualifiedType(CXType T);
+
+/**
+ * \brief For pointer types, returns the type of the pointee.
+ */
+CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
+
+/**
+ * \brief Return the cursor for the declaration of the given type.
+ */
+CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
+
+/**
+ * Returns the Objective-C type encoding for the specified declaration.
+ */
+CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C);
+
+/**
+ * \brief Retrieve the spelling of a given CXTypeKind.
+ */
+CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
+
+/**
+ * \brief Retrieve the calling convention associated with a function type.
+ *
+ * If a non-function type is passed in, CXCallingConv_Invalid is returned.
+ */
+CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);
+
+/**
+ * \brief Retrieve the return type associated with a function type.
+ *
+ * If a non-function type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getResultType(CXType T);
+
+/**
+ * \brief Retrieve the number of non-variadic parameters associated with a
+ * function type.
+ *
+ * If a non-function type is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
+
+/**
+ * \brief Retrieve the type of a parameter of a function type.
+ *
+ * If a non-function type is passed in or the function does not have enough
+ * parameters, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i);
+
+/**
+ * \brief Return 1 if the CXType is a variadic function type, and 0 otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
+
+/**
+ * \brief Retrieve the return type associated with a given cursor.
+ *
+ * This only returns a valid type if the cursor refers to a function or method.
+ */
+CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C);
+
+/**
+ * \brief Return 1 if the CXType is a POD (plain old data) type, and 0
+ *  otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_isPODType(CXType T);
+
+/**
+ * \brief Return the element type of an array, complex, or vector type.
+ *
+ * If a type is passed in that is not an array, complex, or vector type,
+ * an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getElementType(CXType T);
+
+/**
+ * \brief Return the number of elements of an array or vector type.
+ *
+ * If a type is passed in that is not an array or vector type,
+ * -1 is returned.
+ */
+CINDEX_LINKAGE long long clang_getNumElements(CXType T);
+
+/**
+ * \brief Return the element type of an array type.
+ *
+ * If a non-array type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T);
+
+/**
+ * \brief Return the array size of a constant array.
+ *
+ * If a non-array type is passed in, -1 is returned.
+ */
+CINDEX_LINKAGE long long clang_getArraySize(CXType T);
+
+/**
+ * \brief List the possible error codes for \c clang_Type_getSizeOf,
+ *   \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
+ *   \c clang_Cursor_getOffsetOf.
+ *
+ * A value of this enumeration type can be returned if the target type is not
+ * a valid argument to sizeof, alignof or offsetof.
+ */
+enum CXTypeLayoutError {
+  /**
+   * \brief Type is of kind CXType_Invalid.
+   */
+  CXTypeLayoutError_Invalid = -1,
+  /**
+   * \brief The type is an incomplete Type.
+   */
+  CXTypeLayoutError_Incomplete = -2,
+  /**
+   * \brief The type is a dependent Type.
+   */
+  CXTypeLayoutError_Dependent = -3,
+  /**
+   * \brief The type is not a constant size type.
+   */
+  CXTypeLayoutError_NotConstantSize = -4,
+  /**
+   * \brief The Field name is not valid for this record.
+   */
+  CXTypeLayoutError_InvalidFieldName = -5
+};
+
+/**
+ * \brief Return the alignment of a type in bytes as per C++[expr.alignof]
+ *   standard.
+ *
+ * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+ * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+ *   is returned.
+ * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+ *   returned.
+ * If the type declaration is not a constant size type,
+ *   CXTypeLayoutError_NotConstantSize is returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T);
+
+/**
+ * \brief Return the class type of an member pointer type.
+ *
+ * If a non-member-pointer type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getClassType(CXType T);
+
+/**
+ * \brief Return the size of a type in bytes as per C++[expr.sizeof] standard.
+ *
+ * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
+ * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete
+ *   is returned.
+ * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is
+ *   returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T);
+
+/**
+ * \brief Return the offset of a field named S in a record of type T in bits
+ *   as it would be returned by __offsetof__ as per C++11[18.2p4]
+ *
+ * If the cursor is not a record field declaration, CXTypeLayoutError_Invalid
+ *   is returned.
+ * If the field's type declaration is an incomplete type,
+ *   CXTypeLayoutError_Incomplete is returned.
+ * If the field's type declaration is a dependent type,
+ *   CXTypeLayoutError_Dependent is returned.
+ * If the field's name S is not found,
+ *   CXTypeLayoutError_InvalidFieldName is returned.
+ */
+CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
+
+enum CXRefQualifierKind {
+  /** \brief No ref-qualifier was provided. */
+  CXRefQualifier_None = 0,
+  /** \brief An lvalue ref-qualifier was provided (\c &). */
+  CXRefQualifier_LValue,
+  /** \brief An rvalue ref-qualifier was provided (\c &&). */
+  CXRefQualifier_RValue
+};
+
+/**
+ * \brief Returns the number of template arguments for given class template
+ * specialization, or -1 if type \c T is not a class template specialization.
+ *
+ * Variadic argument packs count as only one argument, and can not be inspected
+ * further.
+ */
+CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
+
+/**
+ * \brief Returns the type template argument of a template class specialization
+ * at given index.
+ *
+ * This function only returns template type arguments and does not handle
+ * template template arguments or variadic packs.
+ */
+CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i);
+
+/**
+ * \brief Retrieve the ref-qualifier kind of a function or method.
+ *
+ * The ref-qualifier is returned for C++ functions or methods. For other types
+ * or non-C++ declarations, CXRefQualifier_None is returned.
+ */
+CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);
+
+/**
+ * \brief Returns non-zero if the cursor specifies a Record member that is a
+ *   bitfield.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isBitField(CXCursor C);
+
+/**
+ * \brief Returns 1 if the base class specified by the cursor with kind
+ *   CX_CXXBaseSpecifier is virtual.
+ */
+CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor);
+    
+/**
+ * \brief Represents the C++ access control level to a base class for a
+ * cursor with kind CX_CXXBaseSpecifier.
+ */
+enum CX_CXXAccessSpecifier {
+  CX_CXXInvalidAccessSpecifier,
+  CX_CXXPublic,
+  CX_CXXProtected,
+  CX_CXXPrivate
+};
+
+/**
+ * \brief Returns the access control level for the referenced object.
+ *
+ * If the cursor refers to a C++ declaration, its access control level within its
+ * parent scope is returned. Otherwise, if the cursor refers to a base specifier or
+ * access specifier, the specifier itself is returned.
+ */
+CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
+
+/**
+ * \brief Determine the number of overloaded declarations referenced by a 
+ * \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \returns The number of overloaded declarations referenced by \c cursor. If it
+ * is not a \c CXCursor_OverloadedDeclRef cursor, returns 0.
+ */
+CINDEX_LINKAGE unsigned clang_getNumOverloadedDecls(CXCursor cursor);
+
+/**
+ * \brief Retrieve a cursor for one of the overloaded declarations referenced
+ * by a \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \param index The zero-based index into the set of overloaded declarations in
+ * the cursor.
+ *
+ * \returns A cursor representing the declaration referenced by the given 
+ * \c cursor at the specified \c index. If the cursor does not have an 
+ * associated set of overloaded declarations, or if the index is out of bounds,
+ * returns \c clang_getNullCursor();
+ */
+CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, 
+                                                unsigned index);
+  
+/**
+ * @}
+ */
+  
+/**
+ * \defgroup CINDEX_ATTRIBUTES Information for attributes
+ *
+ * @{
+ */
+
+
+/**
+ * \brief For cursors representing an iboutletcollection attribute,
+ *  this function returns the collection element type.
+ *
+ */
+CINDEX_LINKAGE CXType clang_getIBOutletCollectionType(CXCursor);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors
+ *
+ * These routines provide the ability to traverse the abstract syntax tree
+ * using cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes how the traversal of the children of a particular
+ * cursor should proceed after visiting a particular child cursor.
+ *
+ * A value of this enumeration type should be returned by each
+ * \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
+ */
+enum CXChildVisitResult {
+  /**
+   * \brief Terminates the cursor traversal.
+   */
+  CXChildVisit_Break,
+  /**
+   * \brief Continues the cursor traversal with the next sibling of
+   * the cursor just visited, without visiting its children.
+   */
+  CXChildVisit_Continue,
+  /**
+   * \brief Recursively traverse the children of this cursor, using
+   * the same visitor and client data.
+   */
+  CXChildVisit_Recurse
+};
+
+/**
+ * \brief Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor function will be invoked for each cursor found by
+ * clang_visitCursorChildren(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor,
+ * and its third argument is the client data provided to
+ * clang_visitCursorChildren().
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitCursorChildren().
+ */
+typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor,
+                                                   CXCursor parent,
+                                                   CXClientData client_data);
+
+/**
+ * \brief Visit the children of a particular cursor.
+ *
+ * This function visits all the direct children of the given cursor,
+ * invoking the given \p visitor function with the cursors of each
+ * visited child. The traversal may be recursive, if the visitor returns
+ * \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
+ * the visitor returns \c CXChildVisit_Break.
+ *
+ * \param parent the cursor whose child may be visited. All kinds of
+ * cursors can be visited, including invalid cursors (which, by
+ * definition, have no children).
+ *
+ * \param visitor the visitor function that will be invoked for each
+ * child of \p parent.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the visitor each time it is invoked.
+ *
+ * \returns a non-zero value if the traversal was terminated
+ * prematurely by the visitor returning \c CXChildVisit_Break.
+ */
+CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent,
+                                            CXCursorVisitor visitor,
+                                            CXClientData client_data);
+#ifdef __has_feature
+#  if __has_feature(blocks)
+/**
+ * \brief Visitor invoked for each cursor found by a traversal.
+ *
+ * This visitor block will be invoked for each cursor found by
+ * clang_visitChildrenWithBlock(). Its first argument is the cursor being
+ * visited, its second argument is the parent visitor for that cursor.
+ *
+ * The visitor should return one of the \c CXChildVisitResult values
+ * to direct clang_visitChildrenWithBlock().
+ */
+typedef enum CXChildVisitResult 
+     (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
+
+/**
+ * Visits the children of a cursor using the specified block.  Behaves
+ * identically to clang_visitChildren() in all other respects.
+ */
+unsigned clang_visitChildrenWithBlock(CXCursor parent,
+                                      CXCursorVisitorBlock block);
+#  endif
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CURSOR_XREF Cross-referencing in the AST
+ *
+ * These routines provide the ability to determine references within and
+ * across translation units, by providing the names of the entities referenced
+ * by cursors, follow reference cursors to the declarations they reference,
+ * and associate declarations with their definitions.
+ *
+ * @{
+ */
+
+/**
+ * \brief Retrieve a Unified Symbol Resolution (USR) for the entity referenced
+ * by the given cursor.
+ *
+ * A Unified Symbol Resolution (USR) is a string that identifies a particular
+ * entity (function, class, variable, etc.) within a program. USRs can be
+ * compared across translation units to determine, e.g., when references in
+ * one translation refer to an entity defined in another translation unit.
+ */
+CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor);
+
+/**
+ * \brief Construct a USR for a specified Objective-C class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C category.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCCategory(const char *class_name,
+                                 const char *category_name);
+
+/**
+ * \brief Construct a USR for a specified Objective-C protocol.
+ */
+CINDEX_LINKAGE CXString
+  clang_constructUSR_ObjCProtocol(const char *protocol_name);
+
+
+/**
+ * \brief Construct a USR for a specified Objective-C instance variable and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCIvar(const char *name,
+                                                    CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C method and
+ *   the USR for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCMethod(const char *name,
+                                                      unsigned isInstanceMethod,
+                                                      CXString classUSR);
+
+/**
+ * \brief Construct a USR for a specified Objective-C property and the USR
+ *  for its containing class.
+ */
+CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
+                                                        CXString classUSR);
+
+/**
+ * \brief Retrieve a name for the entity referenced by this cursor.
+ */
+CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
+
+/**
+ * \brief Retrieve a range for a piece that forms the cursors spelling name.
+ * Most of the times there is only one range for the complete spelling but for
+ * Objective-C methods and Objective-C message expressions, there are multiple
+ * pieces for each selector identifier.
+ * 
+ * \param pieceIndex the index of the spelling name piece. If this is greater
+ * than the actual number of pieces, it will return a NULL (invalid) range.
+ *  
+ * \param options Reserved.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,
+                                                          unsigned pieceIndex,
+                                                          unsigned options);
+
+/**
+ * \brief Retrieve the display name for the entity referenced by this cursor.
+ *
+ * The display name contains extra information that helps identify the cursor,
+ * such as the parameters of a function or template or the arguments of a 
+ * class template specialization.
+ */
+CINDEX_LINKAGE CXString clang_getCursorDisplayName(CXCursor);
+  
+/** \brief For a cursor that is a reference, retrieve a cursor representing the
+ * entity that it references.
+ *
+ * Reference cursors refer to other entities in the AST. For example, an
+ * Objective-C superclass reference cursor refers to an Objective-C class.
+ * This function produces the cursor for the Objective-C class from the
+ * cursor for the superclass reference. If the input cursor is a declaration or
+ * definition, it returns that declaration or definition unchanged.
+ * Otherwise, returns the NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor);
+
+/**
+ *  \brief For a cursor that is either a reference to or a declaration
+ *  of some entity, retrieve a cursor that describes the definition of
+ *  that entity.
+ *
+ *  Some entities can be declared multiple times within a translation
+ *  unit, but only one of those declarations can also be a
+ *  definition. For example, given:
+ *
+ *  \code
+ *  int f(int, int);
+ *  int g(int x, int y) { return f(x, y); }
+ *  int f(int a, int b) { return a + b; }
+ *  int f(int, int);
+ *  \endcode
+ *
+ *  there are three declarations of the function "f", but only the
+ *  second one is a definition. The clang_getCursorDefinition()
+ *  function will take any cursor pointing to a declaration of "f"
+ *  (the first or fourth lines of the example) or a cursor referenced
+ *  that uses "f" (the call to "f' inside "g") and will return a
+ *  declaration cursor pointing to the definition (the second "f"
+ *  declaration).
+ *
+ *  If given a cursor for which there is no corresponding definition,
+ *  e.g., because there is no definition of that entity within this
+ *  translation unit, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
+
+/**
+ * \brief Determine whether the declaration pointed to by this cursor
+ * is also a definition of that entity.
+ */
+CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
+
+/**
+ * \brief Retrieve the canonical cursor corresponding to the given cursor.
+ *
+ * In the C family of languages, many kinds of entities can be declared several
+ * times within a single translation unit. For example, a structure type can
+ * be forward-declared (possibly multiple times) and later defined:
+ *
+ * \code
+ * struct X;
+ * struct X;
+ * struct X {
+ *   int member;
+ * };
+ * \endcode
+ *
+ * The declarations and the definition of \c X are represented by three 
+ * different cursors, all of which are declarations of the same underlying 
+ * entity. One of these cursor is considered the "canonical" cursor, which
+ * is effectively the representative for the underlying entity. One can 
+ * determine if two cursors are declarations of the same underlying entity by
+ * comparing their canonical cursors.
+ *
+ * \returns The canonical cursor for the entity referred to by the given cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor);
+
+
+/**
+ * \brief If the cursor points to a selector identifier in an Objective-C
+ * method or message expression, this returns the selector index.
+ *
+ * After getting a cursor with #clang_getCursor, this can be called to
+ * determine if the location points to a selector identifier.
+ *
+ * \returns The selector index if the cursor is an Objective-C method or message
+ * expression and the cursor is pointing to a selector identifier, or -1
+ * otherwise.
+ */
+CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
+
+/**
+ * \brief Given a cursor pointing to a C++ method call or an Objective-C
+ * message, returns non-zero if the method/message is "dynamic", meaning:
+ * 
+ * For a C++ method: the call is virtual.
+ * For an Objective-C message: the receiver is an object instance, not 'super'
+ * or a specific class.
+ * 
+ * If the method/message is "static" or the cursor does not point to a
+ * method/message, it will return zero.
+ */
+CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
+
+/**
+ * \brief Given a cursor pointing to an Objective-C message, returns the CXType
+ * of the receiver.
+ */
+CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
+
+/**
+ * \brief Property attributes for a \c CXCursor_ObjCPropertyDecl.
+ */
+typedef enum {
+  CXObjCPropertyAttr_noattr    = 0x00,
+  CXObjCPropertyAttr_readonly  = 0x01,
+  CXObjCPropertyAttr_getter    = 0x02,
+  CXObjCPropertyAttr_assign    = 0x04,
+  CXObjCPropertyAttr_readwrite = 0x08,
+  CXObjCPropertyAttr_retain    = 0x10,
+  CXObjCPropertyAttr_copy      = 0x20,
+  CXObjCPropertyAttr_nonatomic = 0x40,
+  CXObjCPropertyAttr_setter    = 0x80,
+  CXObjCPropertyAttr_atomic    = 0x100,
+  CXObjCPropertyAttr_weak      = 0x200,
+  CXObjCPropertyAttr_strong    = 0x400,
+  CXObjCPropertyAttr_unsafe_unretained = 0x800
+} CXObjCPropertyAttrKind;
+
+/**
+ * \brief Given a cursor that represents a property declaration, return the
+ * associated property attributes. The bits are formed from
+ * \c CXObjCPropertyAttrKind.
+ *
+ * \param reserved Reserved for future use, pass 0.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
+                                                             unsigned reserved);
+
+/**
+ * \brief 'Qualifiers' written next to the return and parameter types in
+ * Objective-C method declarations.
+ */
+typedef enum {
+  CXObjCDeclQualifier_None = 0x0,
+  CXObjCDeclQualifier_In = 0x1,
+  CXObjCDeclQualifier_Inout = 0x2,
+  CXObjCDeclQualifier_Out = 0x4,
+  CXObjCDeclQualifier_Bycopy = 0x8,
+  CXObjCDeclQualifier_Byref = 0x10,
+  CXObjCDeclQualifier_Oneway = 0x20
+} CXObjCDeclQualifierKind;
+
+/**
+ * \brief Given a cursor that represents an Objective-C method or parameter
+ * declaration, return the associated Objective-C qualifiers for the return
+ * type or the parameter respectively. The bits are formed from
+ * CXObjCDeclQualifierKind.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
+
+/**
+ * \brief Given a cursor that represents an Objective-C method or property
+ * declaration, return non-zero if the declaration was affected by "@optional".
+ * Returns zero if the cursor is not such a declaration or it is "@required".
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
+
+/**
+ * \brief Returns non-zero if the given cursor is a variadic function or method.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
+
+/**
+ * \brief Given a cursor that represents a declaration, return the associated
+ * comment's source range.  The range may include multiple consecutive comments
+ * with whitespace in between.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getCommentRange(CXCursor C);
+
+/**
+ * \brief Given a cursor that represents a declaration, return the associated
+ * comment text, including comment markers.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getRawCommentText(CXCursor C);
+
+/**
+ * \brief Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated \\brief paragraph; otherwise return the
+ * first paragraph.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_MODULE Module introspection
+ *
+ * The functions in this group provide access to information about modules.
+ *
+ * @{
+ */
+
+typedef void *CXModule;
+
+/**
+ * \brief Given a CXCursor_ModuleImportDecl cursor, return the associated module.
+ */
+CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C);
+
+/**
+ * \brief Given a CXFile header file, return the module that contains it, if one
+ * exists.
+ */
+CINDEX_LINKAGE CXModule clang_getModuleForFile(CXTranslationUnit, CXFile);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the module file where the provided module object came from.
+ */
+CINDEX_LINKAGE CXFile clang_Module_getASTFile(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the parent of a sub-module or NULL if the given module is top-level,
+ * e.g. for 'std.vector' it will return the 'std' module.
+ */
+CINDEX_LINKAGE CXModule clang_Module_getParent(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the name of the module, e.g. for the 'std.vector' sub-module it
+ * will return "vector".
+ */
+CINDEX_LINKAGE CXString clang_Module_getName(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the full name of the module, e.g. "std.vector".
+ */
+CINDEX_LINKAGE CXString clang_Module_getFullName(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns non-zero if the module is a system one.
+ */
+CINDEX_LINKAGE int clang_Module_isSystem(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \returns the number of top level headers associated with this module.
+ */
+CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit,
+                                                           CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
+ * \param Index top level header index (zero-based).
+ *
+ * \returns the specified top level header associated with the module.
+ */
+CINDEX_LINKAGE
+CXFile clang_Module_getTopLevelHeader(CXTranslationUnit,
+                                      CXModule Module, unsigned Index);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CPP C++ AST introspection
+ *
+ * The routines in this group provide access information in the ASTs specific
+ * to C++ language features.
+ *
+ * @{
+ */
+
+/**
+ * \brief Determine if a C++ member function or member function template is
+ * pure virtual.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C);
+
+/**
+ * \brief Determine if a C++ member function or member function template is 
+ * declared 'static'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
+
+/**
+ * \brief Determine if a C++ member function or member function template is
+ * explicitly declared 'virtual' or if it overrides a virtual method from
+ * one of the base classes.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
+
+/**
+ * \brief Determine if a C++ member function or member function template is
+ * declared 'const'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
+
+/**
+ * \brief Given a cursor that represents a template, determine
+ * the cursor kind of the specializations would be generated by instantiating
+ * the template.
+ *
+ * This routine can be used to determine what flavor of function template,
+ * class template, or class template partial specialization is stored in the
+ * cursor. For example, it can describe whether a class template cursor is
+ * declared with "struct", "class" or "union".
+ *
+ * \param C The cursor to query. This cursor should represent a template
+ * declaration.
+ *
+ * \returns The cursor kind of the specializations that would be generated
+ * by instantiating the template \p C. If \p C is not a template, returns
+ * \c CXCursor_NoDeclFound.
+ */
+CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C);
+  
+/**
+ * \brief Given a cursor that may represent a specialization or instantiation
+ * of a template, retrieve the cursor that represents the template that it
+ * specializes or from which it was instantiated.
+ *
+ * This routine determines the template involved both for explicit 
+ * specializations of templates and for implicit instantiations of the template,
+ * both of which are referred to as "specializations". For a class template
+ * specialization (e.g., \c std::vector<bool>), this routine will return 
+ * either the primary template (\c std::vector) or, if the specialization was
+ * instantiated from a class template partial specialization, the class template
+ * partial specialization. For a class template partial specialization and a
+ * function template specialization (including instantiations), this
+ * this routine will return the specialized template.
+ *
+ * For members of a class template (e.g., member functions, member classes, or
+ * static data members), returns the specialized or instantiated member. 
+ * Although not strictly "templates" in the C++ language, members of class
+ * templates have the same notions of specializations and instantiations that
+ * templates do, so this routine treats them similarly.
+ *
+ * \param C A cursor that may be a specialization of a template or a member
+ * of a template.
+ *
+ * \returns If the given cursor is a specialization or instantiation of a 
+ * template or a member thereof, the template or member that it specializes or
+ * from which it was instantiated. Otherwise, returns a NULL cursor.
+ */
+CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C);
+
+/**
+ * \brief Given a cursor that references something else, return the source range
+ * covering that reference.
+ *
+ * \param C A cursor pointing to a member reference, a declaration reference, or
+ * an operator call.
+ * \param NameFlags A bitset with three independent flags: 
+ * CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and
+ * CXNameRange_WantSinglePiece.
+ * \param PieceIndex For contiguous names or when passing the flag 
+ * CXNameRange_WantSinglePiece, only one piece with index 0 is 
+ * available. When the CXNameRange_WantSinglePiece flag is not passed for a
+ * non-contiguous names, this index can be used to retrieve the individual
+ * pieces of the name. See also CXNameRange_WantSinglePiece.
+ *
+ * \returns The piece of the name pointed to by the given cursor. If there is no
+ * name, or if the PieceIndex is out-of-range, a null-cursor will be returned.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C,
+                                                unsigned NameFlags, 
+                                                unsigned PieceIndex);
+
+enum CXNameRefFlags {
+  /**
+   * \brief Include the nested-name-specifier, e.g. Foo:: in x.Foo::y, in the
+   * range.
+   */
+  CXNameRange_WantQualifier = 0x1,
+  
+  /**
+   * \brief Include the explicit template arguments, e.g. \<int> in x.f<int>,
+   * in the range.
+   */
+  CXNameRange_WantTemplateArgs = 0x2,
+
+  /**
+   * \brief If the name is non-contiguous, return the full spanning range.
+   *
+   * Non-contiguous names occur in Objective-C when a selector with two or more
+   * parameters is used, or in C++ when using an operator:
+   * \code
+   * [object doSomething:here withValue:there]; // Objective-C
+   * return some_vector[1]; // C++
+   * \endcode
+   */
+  CXNameRange_WantSinglePiece = 0x4
+};
+  
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_LEX Token extraction and manipulation
+ *
+ * The routines in this group provide access to the tokens within a
+ * translation unit, along with a semantic mapping of those tokens to
+ * their corresponding cursors.
+ *
+ * @{
+ */
+
+/**
+ * \brief Describes a kind of token.
+ */
+typedef enum CXTokenKind {
+  /**
+   * \brief A token that contains some kind of punctuation.
+   */
+  CXToken_Punctuation,
+
+  /**
+   * \brief A language keyword.
+   */
+  CXToken_Keyword,
+
+  /**
+   * \brief An identifier (that is not a keyword).
+   */
+  CXToken_Identifier,
+
+  /**
+   * \brief A numeric, string, or character literal.
+   */
+  CXToken_Literal,
+
+  /**
+   * \brief A comment.
+   */
+  CXToken_Comment
+} CXTokenKind;
+
+/**
+ * \brief Describes a single preprocessing token.
+ */
+typedef struct {
+  unsigned int_data[4];
+  void *ptr_data;
+} CXToken;
+
+/**
+ * \brief Determine the kind of the given token.
+ */
+CINDEX_LINKAGE CXTokenKind clang_getTokenKind(CXToken);
+
+/**
+ * \brief Determine the spelling of the given token.
+ *
+ * The spelling of a token is the textual representation of that token, e.g.,
+ * the text of an identifier or keyword.
+ */
+CINDEX_LINKAGE CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Retrieve the source location of the given token.
+ */
+CINDEX_LINKAGE CXSourceLocation clang_getTokenLocation(CXTranslationUnit,
+                                                       CXToken);
+
+/**
+ * \brief Retrieve a source range that covers the given token.
+ */
+CINDEX_LINKAGE CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);
+
+/**
+ * \brief Tokenize the source code described by the given range into raw
+ * lexical tokens.
+ *
+ * \param TU the translation unit whose text is being tokenized.
+ *
+ * \param Range the source range in which text should be tokenized. All of the
+ * tokens produced by tokenization will fall within this source range,
+ *
+ * \param Tokens this pointer will be set to point to the array of tokens
+ * that occur within the given source range. The returned pointer must be
+ * freed with clang_disposeTokens() before the translation unit is destroyed.
+ *
+ * \param NumTokens will be set to the number of tokens in the \c *Tokens
+ * array.
+ *
+ */
+CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+                                   CXToken **Tokens, unsigned *NumTokens);
+
+/**
+ * \brief Annotate the given set of tokens by providing cursors for each token
+ * that can be mapped to a specific entity within the abstract syntax tree.
+ *
+ * This token-annotation routine is equivalent to invoking
+ * clang_getCursor() for the source locations of each of the
+ * tokens. The cursors provided are filtered, so that only those
+ * cursors that have a direct correspondence to the token are
+ * accepted. For example, given a function call \c f(x),
+ * clang_getCursor() would provide the following cursors:
+ *
+ *   * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'.
+ *   * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'.
+ *   * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'.
+ *
+ * Only the first and last of these cursors will occur within the
+ * annotate, since the tokens "f" and "x' directly refer to a function
+ * and a variable, respectively, but the parentheses are just a small
+ * part of the full syntax of the function call expression, which is
+ * not provided as an annotation.
+ *
+ * \param TU the translation unit that owns the given tokens.
+ *
+ * \param Tokens the set of tokens to annotate.
+ *
+ * \param NumTokens the number of tokens in \p Tokens.
+ *
+ * \param Cursors an array of \p NumTokens cursors, whose contents will be
+ * replaced with the cursors corresponding to each token.
+ */
+CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU,
+                                         CXToken *Tokens, unsigned NumTokens,
+                                         CXCursor *Cursors);
+
+/**
+ * \brief Free the given set of tokens.
+ */
+CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU,
+                                        CXToken *Tokens, unsigned NumTokens);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_DEBUG Debugging facilities
+ *
+ * These routines are used for testing and debugging, only, and should not
+ * be relied upon.
+ *
+ * @{
+ */
+
+/* for debug/testing */
+CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);
+CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor,
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn);
+CINDEX_LINKAGE void clang_enableStackTraces(void);
+CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void*), void *user_data,
+                                          unsigned stack_size);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_CODE_COMPLET Code completion
+ *
+ * Code completion involves taking an (incomplete) source file, along with
+ * knowledge of where the user is actively editing that file, and suggesting
+ * syntactically- and semantically-valid constructs that the user might want to
+ * use at that particular point in the source code. These data structures and
+ * routines provide support for code completion.
+ *
+ * @{
+ */
+
+/**
+ * \brief A semantic string that describes a code-completion result.
+ *
+ * A semantic string that describes the formatting of a code-completion
+ * result as a single "template" of text that should be inserted into the
+ * source buffer when a particular code-completion result is selected.
+ * Each semantic string is made up of some number of "chunks", each of which
+ * contains some text along with a description of what that text means, e.g.,
+ * the name of the entity being referenced, whether the text chunk is part of
+ * the template, or whether it is a "placeholder" that the user should replace
+ * with actual code,of a specific kind. See \c CXCompletionChunkKind for a
+ * description of the different kinds of chunks.
+ */
+typedef void *CXCompletionString;
+
+/**
+ * \brief A single result of code completion.
+ */
+typedef struct {
+  /**
+   * \brief The kind of entity that this completion refers to.
+   *
+   * The cursor kind will be a macro, keyword, or a declaration (one of the
+   * *Decl cursor kinds), describing the entity that the completion is
+   * referring to.
+   *
+   * \todo In the future, we would like to provide a full cursor, to allow
+   * the client to extract additional information from declaration.
+   */
+  enum CXCursorKind CursorKind;
+
+  /**
+   * \brief The code-completion string that describes how to insert this
+   * code-completion result into the editing buffer.
+   */
+  CXCompletionString CompletionString;
+} CXCompletionResult;
+
+/**
+ * \brief Describes a single piece of text within a code-completion string.
+ *
+ * Each "chunk" within a code-completion string (\c CXCompletionString) is
+ * either a piece of text with a specific "kind" that describes how that text
+ * should be interpreted by the client or is another completion string.
+ */
+enum CXCompletionChunkKind {
+  /**
+   * \brief A code-completion string that describes "optional" text that
+   * could be a part of the template (but is not required).
+   *
+   * The Optional chunk is the only kind of chunk that has a code-completion
+   * string for its representation, which is accessible via
+   * \c clang_getCompletionChunkCompletionString(). The code-completion string
+   * describes an additional part of the template that is completely optional.
+   * For example, optional chunks can be used to describe the placeholders for
+   * arguments that match up with defaulted function parameters, e.g. given:
+   *
+   * \code
+   * void f(int x, float y = 3.14, double z = 2.71828);
+   * \endcode
+   *
+   * The code-completion string for this function would contain:
+   *   - a TypedText chunk for "f".
+   *   - a LeftParen chunk for "(".
+   *   - a Placeholder chunk for "int x"
+   *   - an Optional chunk containing the remaining defaulted arguments, e.g.,
+   *       - a Comma chunk for ","
+   *       - a Placeholder chunk for "float y"
+   *       - an Optional chunk containing the last defaulted argument:
+   *           - a Comma chunk for ","
+   *           - a Placeholder chunk for "double z"
+   *   - a RightParen chunk for ")"
+   *
+   * There are many ways to handle Optional chunks. Two simple approaches are:
+   *   - Completely ignore optional chunks, in which case the template for the
+   *     function "f" would only include the first parameter ("int x").
+   *   - Fully expand all optional chunks, in which case the template for the
+   *     function "f" would have all of the parameters.
+   */
+  CXCompletionChunk_Optional,
+  /**
+   * \brief Text that a user would be expected to type to get this
+   * code-completion result.
+   *
+   * There will be exactly one "typed text" chunk in a semantic string, which
+   * will typically provide the spelling of a keyword or the name of a
+   * declaration that could be used at the current code point. Clients are
+   * expected to filter the code-completion results based on the text in this
+   * chunk.
+   */
+  CXCompletionChunk_TypedText,
+  /**
+   * \brief Text that should be inserted as part of a code-completion result.
+   *
+   * A "text" chunk represents text that is part of the template to be
+   * inserted into user code should this particular code-completion result
+   * be selected.
+   */
+  CXCompletionChunk_Text,
+  /**
+   * \brief Placeholder text that should be replaced by the user.
+   *
+   * A "placeholder" chunk marks a place where the user should insert text
+   * into the code-completion template. For example, placeholders might mark
+   * the function parameters for a function declaration, to indicate that the
+   * user should provide arguments for each of those parameters. The actual
+   * text in a placeholder is a suggestion for the text to display before
+   * the user replaces the placeholder with real code.
+   */
+  CXCompletionChunk_Placeholder,
+  /**
+   * \brief Informative text that should be displayed but never inserted as
+   * part of the template.
+   *
+   * An "informative" chunk contains annotations that can be displayed to
+   * help the user decide whether a particular code-completion result is the
+   * right option, but which is not part of the actual template to be inserted
+   * by code completion.
+   */
+  CXCompletionChunk_Informative,
+  /**
+   * \brief Text that describes the current parameter when code-completion is
+   * referring to function call, message send, or template specialization.
+   *
+   * A "current parameter" chunk occurs when code-completion is providing
+   * information about a parameter corresponding to the argument at the
+   * code-completion point. For example, given a function
+   *
+   * \code
+   * int add(int x, int y);
+   * \endcode
+   *
+   * and the source code \c add(, where the code-completion point is after the
+   * "(", the code-completion string will contain a "current parameter" chunk
+   * for "int x", indicating that the current argument will initialize that
+   * parameter. After typing further, to \c add(17, (where the code-completion
+   * point is after the ","), the code-completion string will contain a
+   * "current paremeter" chunk to "int y".
+   */
+  CXCompletionChunk_CurrentParameter,
+  /**
+   * \brief A left parenthesis ('('), used to initiate a function call or
+   * signal the beginning of a function parameter list.
+   */
+  CXCompletionChunk_LeftParen,
+  /**
+   * \brief A right parenthesis (')'), used to finish a function call or
+   * signal the end of a function parameter list.
+   */
+  CXCompletionChunk_RightParen,
+  /**
+   * \brief A left bracket ('[').
+   */
+  CXCompletionChunk_LeftBracket,
+  /**
+   * \brief A right bracket (']').
+   */
+  CXCompletionChunk_RightBracket,
+  /**
+   * \brief A left brace ('{').
+   */
+  CXCompletionChunk_LeftBrace,
+  /**
+   * \brief A right brace ('}').
+   */
+  CXCompletionChunk_RightBrace,
+  /**
+   * \brief A left angle bracket ('<').
+   */
+  CXCompletionChunk_LeftAngle,
+  /**
+   * \brief A right angle bracket ('>').
+   */
+  CXCompletionChunk_RightAngle,
+  /**
+   * \brief A comma separator (',').
+   */
+  CXCompletionChunk_Comma,
+  /**
+   * \brief Text that specifies the result type of a given result.
+   *
+   * This special kind of informative chunk is not meant to be inserted into
+   * the text buffer. Rather, it is meant to illustrate the type that an
+   * expression using the given completion string would have.
+   */
+  CXCompletionChunk_ResultType,
+  /**
+   * \brief A colon (':').
+   */
+  CXCompletionChunk_Colon,
+  /**
+   * \brief A semicolon (';').
+   */
+  CXCompletionChunk_SemiColon,
+  /**
+   * \brief An '=' sign.
+   */
+  CXCompletionChunk_Equal,
+  /**
+   * Horizontal space (' ').
+   */
+  CXCompletionChunk_HorizontalSpace,
+  /**
+   * Vertical space ('\n'), after which it is generally a good idea to
+   * perform indentation.
+   */
+  CXCompletionChunk_VerticalSpace
+};
+
+/**
+ * \brief Determine the kind of a particular chunk within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the kind of the chunk at the index \c chunk_number.
+ */
+CINDEX_LINKAGE enum CXCompletionChunkKind
+clang_getCompletionChunkKind(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * \brief Retrieve the text associated with a particular chunk within a
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the text associated with the chunk at index \c chunk_number.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionChunkText(CXCompletionString completion_string,
+                             unsigned chunk_number);
+
+/**
+ * \brief Retrieve the completion string associated with a particular chunk
+ * within a completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param chunk_number the 0-based index of the chunk in the completion string.
+ *
+ * \returns the completion string associated with the chunk at index
+ * \c chunk_number.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
+                                         unsigned chunk_number);
+
+/**
+ * \brief Retrieve the number of chunks in the given code-completion string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getNumCompletionChunks(CXCompletionString completion_string);
+
+/**
+ * \brief Determine the priority of this code completion.
+ *
+ * The priority of a code completion indicates how likely it is that this 
+ * particular completion is the completion that the user will select. The
+ * priority is selected by various internal heuristics.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The priority of this completion string. Smaller values indicate
+ * higher-priority (more likely) completions.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionPriority(CXCompletionString completion_string);
+  
+/**
+ * \brief Determine the availability of the entity that this code-completion
+ * string refers to.
+ *
+ * \param completion_string The completion string to query.
+ *
+ * \returns The availability of the completion string.
+ */
+CINDEX_LINKAGE enum CXAvailabilityKind 
+clang_getCompletionAvailability(CXCompletionString completion_string);
+
+/**
+ * \brief Retrieve the number of annotations associated with the given
+ * completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \returns the number of annotations associated with the given completion
+ * string.
+ */
+CINDEX_LINKAGE unsigned
+clang_getCompletionNumAnnotations(CXCompletionString completion_string);
+
+/**
+ * \brief Retrieve the annotation associated with the given completion string.
+ *
+ * \param completion_string the completion string to query.
+ *
+ * \param annotation_number the 0-based index of the annotation of the
+ * completion string.
+ *
+ * \returns annotation string associated with the completion at index
+ * \c annotation_number, or a NULL string if that annotation is not available.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionAnnotation(CXCompletionString completion_string,
+                              unsigned annotation_number);
+
+/**
+ * \brief Retrieve the parent context of the given completion string.
+ *
+ * The parent context of a completion string is the semantic parent of 
+ * the declaration (if any) that the code completion represents. For example,
+ * a code completion for an Objective-C method would have the method's class
+ * or protocol as its context.
+ *
+ * \param completion_string The code completion string whose parent is
+ * being queried.
+ *
+ * \param kind DEPRECATED: always set to CXCursor_NotImplemented if non-NULL.
+ *
+ * \returns The name of the completion parent, e.g., "NSObject" if
+ * the completion string represents a method in the NSObject class.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionParent(CXCompletionString completion_string,
+                          enum CXCursorKind *kind);
+
+/**
+ * \brief Retrieve the brief documentation comment attached to the declaration
+ * that corresponds to the given completion string.
+ */
+CINDEX_LINKAGE CXString
+clang_getCompletionBriefComment(CXCompletionString completion_string);
+
+/**
+ * \brief Retrieve a completion string for an arbitrary declaration or macro
+ * definition cursor.
+ *
+ * \param cursor The cursor to query.
+ *
+ * \returns A non-context-sensitive completion string for declaration and macro
+ * definition cursors, or NULL for other kinds of cursors.
+ */
+CINDEX_LINKAGE CXCompletionString
+clang_getCursorCompletionString(CXCursor cursor);
+  
+/**
+ * \brief Contains the results of code-completion.
+ *
+ * This data structure contains the results of code completion, as
+ * produced by \c clang_codeCompleteAt(). Its contents must be freed by
+ * \c clang_disposeCodeCompleteResults.
+ */
+typedef struct {
+  /**
+   * \brief The code-completion results.
+   */
+  CXCompletionResult *Results;
+
+  /**
+   * \brief The number of code-completion results stored in the
+   * \c Results array.
+   */
+  unsigned NumResults;
+} CXCodeCompleteResults;
+
+/**
+ * \brief Flags that can be passed to \c clang_codeCompleteAt() to
+ * modify its behavior.
+ *
+ * The enumerators in this enumeration can be bitwise-OR'd together to
+ * provide multiple options to \c clang_codeCompleteAt().
+ */
+enum CXCodeComplete_Flags {
+  /**
+   * \brief Whether to include macros within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeMacros = 0x01,
+
+  /**
+   * \brief Whether to include code patterns for language constructs
+   * within the set of code completions, e.g., for loops.
+   */
+  CXCodeComplete_IncludeCodePatterns = 0x02,
+
+  /**
+   * \brief Whether to include brief documentation within the set of code
+   * completions returned.
+   */
+  CXCodeComplete_IncludeBriefComments = 0x04
+};
+
+/**
+ * \brief Bits that represent the context under which completion is occurring.
+ *
+ * The enumerators in this enumeration may be bitwise-OR'd together if multiple
+ * contexts are occurring simultaneously.
+ */
+enum CXCompletionContext {
+  /**
+   * \brief The context for completions is unexposed, as only Clang results
+   * should be included. (This is equivalent to having no context bits set.)
+   */
+  CXCompletionContext_Unexposed = 0,
+  
+  /**
+   * \brief Completions for any possible type should be included in the results.
+   */
+  CXCompletionContext_AnyType = 1 << 0,
+  
+  /**
+   * \brief Completions for any possible value (variables, function calls, etc.)
+   * should be included in the results.
+   */
+  CXCompletionContext_AnyValue = 1 << 1,
+  /**
+   * \brief Completions for values that resolve to an Objective-C object should
+   * be included in the results.
+   */
+  CXCompletionContext_ObjCObjectValue = 1 << 2,
+  /**
+   * \brief Completions for values that resolve to an Objective-C selector
+   * should be included in the results.
+   */
+  CXCompletionContext_ObjCSelectorValue = 1 << 3,
+  /**
+   * \brief Completions for values that resolve to a C++ class type should be
+   * included in the results.
+   */
+  CXCompletionContext_CXXClassTypeValue = 1 << 4,
+  
+  /**
+   * \brief Completions for fields of the member being accessed using the dot
+   * operator should be included in the results.
+   */
+  CXCompletionContext_DotMemberAccess = 1 << 5,
+  /**
+   * \brief Completions for fields of the member being accessed using the arrow
+   * operator should be included in the results.
+   */
+  CXCompletionContext_ArrowMemberAccess = 1 << 6,
+  /**
+   * \brief Completions for properties of the Objective-C object being accessed
+   * using the dot operator should be included in the results.
+   */
+  CXCompletionContext_ObjCPropertyAccess = 1 << 7,
+  
+  /**
+   * \brief Completions for enum tags should be included in the results.
+   */
+  CXCompletionContext_EnumTag = 1 << 8,
+  /**
+   * \brief Completions for union tags should be included in the results.
+   */
+  CXCompletionContext_UnionTag = 1 << 9,
+  /**
+   * \brief Completions for struct tags should be included in the results.
+   */
+  CXCompletionContext_StructTag = 1 << 10,
+  
+  /**
+   * \brief Completions for C++ class names should be included in the results.
+   */
+  CXCompletionContext_ClassTag = 1 << 11,
+  /**
+   * \brief Completions for C++ namespaces and namespace aliases should be
+   * included in the results.
+   */
+  CXCompletionContext_Namespace = 1 << 12,
+  /**
+   * \brief Completions for C++ nested name specifiers should be included in
+   * the results.
+   */
+  CXCompletionContext_NestedNameSpecifier = 1 << 13,
+  
+  /**
+   * \brief Completions for Objective-C interfaces (classes) should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInterface = 1 << 14,
+  /**
+   * \brief Completions for Objective-C protocols should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCProtocol = 1 << 15,
+  /**
+   * \brief Completions for Objective-C categories should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCCategory = 1 << 16,
+  /**
+   * \brief Completions for Objective-C instance messages should be included
+   * in the results.
+   */
+  CXCompletionContext_ObjCInstanceMessage = 1 << 17,
+  /**
+   * \brief Completions for Objective-C class messages should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCClassMessage = 1 << 18,
+  /**
+   * \brief Completions for Objective-C selector names should be included in
+   * the results.
+   */
+  CXCompletionContext_ObjCSelectorName = 1 << 19,
+  
+  /**
+   * \brief Completions for preprocessor macro names should be included in
+   * the results.
+   */
+  CXCompletionContext_MacroName = 1 << 20,
+  
+  /**
+   * \brief Natural language completions should be included in the results.
+   */
+  CXCompletionContext_NaturalLanguage = 1 << 21,
+  
+  /**
+   * \brief The current context is unknown, so set all contexts.
+   */
+  CXCompletionContext_Unknown = ((1 << 22) - 1)
+};
+  
+/**
+ * \brief Returns a default set of code-completion options that can be
+ * passed to\c clang_codeCompleteAt(). 
+ */
+CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void);
+
+/**
+ * \brief Perform code completion at a given location in a translation unit.
+ *
+ * This function performs code completion at a particular file, line, and
+ * column within source code, providing results that suggest potential
+ * code snippets based on the context of the completion. The basic model
+ * for code completion is that Clang will parse a complete source file,
+ * performing syntax checking up to the location where code-completion has
+ * been requested. At that point, a special code-completion token is passed
+ * to the parser, which recognizes this token and determines, based on the
+ * current location in the C/Objective-C/C++ grammar and the state of
+ * semantic analysis, what completions to provide. These completions are
+ * returned via a new \c CXCodeCompleteResults structure.
+ *
+ * Code completion itself is meant to be triggered by the client when the
+ * user types punctuation characters or whitespace, at which point the
+ * code-completion location will coincide with the cursor. For example, if \c p
+ * is a pointer, code-completion might be triggered after the "-" and then
+ * after the ">" in \c p->. When the code-completion location is afer the ">",
+ * the completion results will provide, e.g., the members of the struct that
+ * "p" points to. The client is responsible for placing the cursor at the
+ * beginning of the token currently being typed, then filtering the results
+ * based on the contents of the token. For example, when code-completing for
+ * the expression \c p->get, the client should provide the location just after
+ * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the
+ * client can filter the results based on the current token text ("get"), only
+ * showing those results that start with "get". The intent of this interface
+ * is to separate the relatively high-latency acquisition of code-completion
+ * results from the filtering of results on a per-character basis, which must
+ * have a lower latency.
+ *
+ * \param TU The translation unit in which code-completion should
+ * occur. The source files for this translation unit need not be
+ * completely up-to-date (and the contents of those source files may
+ * be overridden via \p unsaved_files). Cursors referring into the
+ * translation unit may be invalidated by this invocation.
+ *
+ * \param complete_filename The name of the source file where code
+ * completion should be performed. This filename may be any file
+ * included in the translation unit.
+ *
+ * \param complete_line The line at which code-completion should occur.
+ *
+ * \param complete_column The column at which code-completion should occur.
+ * Note that the column should point just after the syntactic construct that
+ * initiated code completion, and not in the middle of a lexical token.
+ *
+ * \param unsaved_files the Tiles that have not yet been saved to disk
+ * but may be required for parsing or code completion, including the
+ * contents of those files.  The contents and name of these files (as
+ * specified by CXUnsavedFile) are copied when necessary, so the
+ * client only needs to guarantee their validity until the call to
+ * this function returns.
+ *
+ * \param num_unsaved_files The number of unsaved file entries in \p
+ * unsaved_files.
+ *
+ * \param options Extra options that control the behavior of code
+ * completion, expressed as a bitwise OR of the enumerators of the
+ * CXCodeComplete_Flags enumeration. The 
+ * \c clang_defaultCodeCompleteOptions() function returns a default set
+ * of code-completion options.
+ *
+ * \returns If successful, a new \c CXCodeCompleteResults structure
+ * containing code-completion results, which should eventually be
+ * freed with \c clang_disposeCodeCompleteResults(). If code
+ * completion fails, returns NULL.
+ */
+CINDEX_LINKAGE
+CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
+                                            const char *complete_filename,
+                                            unsigned complete_line,
+                                            unsigned complete_column,
+                                            struct CXUnsavedFile *unsaved_files,
+                                            unsigned num_unsaved_files,
+                                            unsigned options);
+
+/**
+ * \brief Sort the code-completion results in case-insensitive alphabetical 
+ * order.
+ *
+ * \param Results The set of results to sort.
+ * \param NumResults The number of results in \p Results.
+ */
+CINDEX_LINKAGE
+void clang_sortCodeCompletionResults(CXCompletionResult *Results,
+                                     unsigned NumResults);
+  
+/**
+ * \brief Free the given set of code-completion results.
+ */
+CINDEX_LINKAGE
+void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);
+  
+/**
+ * \brief Determine the number of diagnostics produced prior to the
+ * location where code completion was performed.
+ */
+CINDEX_LINKAGE
+unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);
+
+/**
+ * \brief Retrieve a diagnostic associated with the given code completion.
+ *
+ * \param Results the code completion results to query.
+ * \param Index the zero-based diagnostic number to retrieve.
+ *
+ * \returns the requested diagnostic. This diagnostic must be freed
+ * via a call to \c clang_disposeDiagnostic().
+ */
+CINDEX_LINKAGE
+CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
+                                             unsigned Index);
+
+/**
+ * \brief Determines what completions are appropriate for the context
+ * the given code completion.
+ * 
+ * \param Results the code completion results to query
+ *
+ * \returns the kinds of completions that are appropriate for use
+ * along with the given code completion results.
+ */
+CINDEX_LINKAGE
+unsigned long long clang_codeCompleteGetContexts(
+                                                CXCodeCompleteResults *Results);
+
+/**
+ * \brief Returns the cursor kind for the container for the current code
+ * completion context. The container is only guaranteed to be set for
+ * contexts where a container exists (i.e. member accesses or Objective-C
+ * message sends); if there is not a container, this function will return
+ * CXCursor_InvalidCode.
+ *
+ * \param Results the code completion results to query
+ *
+ * \param IsIncomplete on return, this value will be false if Clang has complete
+ * information about the container. If Clang does not have complete
+ * information, this value will be true.
+ *
+ * \returns the container kind, or CXCursor_InvalidCode if there is not a
+ * container
+ */
+CINDEX_LINKAGE
+enum CXCursorKind clang_codeCompleteGetContainerKind(
+                                                 CXCodeCompleteResults *Results,
+                                                     unsigned *IsIncomplete);
+
+/**
+ * \brief Returns the USR for the container for the current code completion
+ * context. If there is not a container for the current context, this
+ * function will return the empty string.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the USR for the container
+ */
+CINDEX_LINKAGE
+CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results);
+  
+  
+/**
+ * \brief Returns the currently-entered selector for an Objective-C message
+ * send, formatted like "initWithFoo:bar:". Only guaranteed to return a
+ * non-empty string for CXCompletionContext_ObjCInstanceMessage and
+ * CXCompletionContext_ObjCClassMessage.
+ *
+ * \param Results the code completion results to query
+ *
+ * \returns the selector (or partial selector) that has been entered thus far
+ * for an Objective-C message send.
+ */
+CINDEX_LINKAGE
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);
+  
+/**
+ * @}
+ */
+
+
+/**
+ * \defgroup CINDEX_MISC Miscellaneous utility functions
+ *
+ * @{
+ */
+
+/**
+ * \brief Return a version string, suitable for showing to a user, but not
+ *        intended to be parsed (the format is not guaranteed to be stable).
+ */
+CINDEX_LINKAGE CXString clang_getClangVersion(void);
+
+  
+/**
+ * \brief Enable/disable crash recovery.
+ *
+ * \param isEnabled Flag to indicate if crash recovery is enabled.  A non-zero
+ *        value enables crash recovery, while 0 disables it.
+ */
+CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled);
+  
+ /**
+  * \brief Visitor invoked for each file in a translation unit
+  *        (used with clang_getInclusions()).
+  *
+  * This visitor function will be invoked by clang_getInclusions() for each
+  * file included (either at the top-level or by \#include directives) within
+  * a translation unit.  The first argument is the file being included, and
+  * the second and third arguments provide the inclusion stack.  The
+  * array is sorted in order of immediate inclusion.  For example,
+  * the first element refers to the location that included 'included_file'.
+  */
+typedef void (*CXInclusionVisitor)(CXFile included_file,
+                                   CXSourceLocation* inclusion_stack,
+                                   unsigned include_len,
+                                   CXClientData client_data);
+
+/**
+ * \brief Visit the set of preprocessor inclusions in a translation unit.
+ *   The visitor function is called with the provided data for every included
+ *   file.  This does not include headers included by the PCH file (unless one
+ *   is inspecting the inclusions in the PCH file itself).
+ */
+CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
+                                        CXInclusionVisitor visitor,
+                                        CXClientData client_data);
+
+/**
+ * @}
+ */
+
+/** \defgroup CINDEX_REMAPPING Remapping functions
+ *
+ * @{
+ */
+
+/**
+ * \brief A remapping of original source files and their translated files.
+ */
+typedef void *CXRemapping;
+
+/**
+ * \brief Retrieve a remapping.
+ *
+ * \param path the path that contains metadata about remappings.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path);
+
+/**
+ * \brief Retrieve a remapping.
+ *
+ * \param filePaths pointer to an array of file paths containing remapping info.
+ *
+ * \param numFiles number of file paths.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE
+CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
+                                            unsigned numFiles);
+
+/**
+ * \brief Determine the number of remappings.
+ */
+CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping);
+
+/**
+ * \brief Get the original and the associated filename from the remapping.
+ * 
+ * \param original If non-NULL, will be set to the original filename.
+ *
+ * \param transformed If non-NULL, will be set to the filename that the original
+ * is associated with.
+ */
+CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index,
+                                     CXString *original, CXString *transformed);
+
+/**
+ * \brief Dispose the remapping.
+ */
+CINDEX_LINKAGE void clang_remap_dispose(CXRemapping);
+
+/**
+ * @}
+ */
+
+/** \defgroup CINDEX_HIGH Higher level API functions
+ *
+ * @{
+ */
+
+enum CXVisitorResult {
+  CXVisit_Break,
+  CXVisit_Continue
+};
+
+typedef struct {
+  void *context;
+  enum CXVisitorResult (*visit)(void *context, CXCursor, CXSourceRange);
+} CXCursorAndRangeVisitor;
+
+typedef enum {
+  /**
+   * \brief Function returned successfully.
+   */
+  CXResult_Success = 0,
+  /**
+   * \brief One of the parameters was invalid for the function.
+   */
+  CXResult_Invalid = 1,
+  /**
+   * \brief The function was terminated by a callback (e.g. it returned
+   * CXVisit_Break)
+   */
+  CXResult_VisitBreak = 2
+
+} CXResult;
+
+/**
+ * \brief Find references of a declaration in a specific file.
+ * 
+ * \param cursor pointing to a declaration or a reference of one.
+ *
+ * \param file to search for references.
+ *
+ * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+ * each reference found.
+ * The CXSourceRange will point inside the file; if the reference is inside
+ * a macro (and not a macro argument) the CXSourceRange will be invalid.
+ *
+ * \returns one of the CXResult enumerators.
+ */
+CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
+                                               CXCursorAndRangeVisitor visitor);
+
+/**
+ * \brief Find #import/#include directives in a specific file.
+ *
+ * \param TU translation unit containing the file to query.
+ *
+ * \param file to search for #import/#include directives.
+ *
+ * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for
+ * each directive found.
+ *
+ * \returns one of the CXResult enumerators.
+ */
+CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU,
+                                                 CXFile file,
+                                              CXCursorAndRangeVisitor visitor);
+
+#ifdef __has_feature
+#  if __has_feature(blocks)
+
+typedef enum CXVisitorResult
+    (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange);
+
+CINDEX_LINKAGE
+CXResult clang_findReferencesInFileWithBlock(CXCursor, CXFile,
+                                             CXCursorAndRangeVisitorBlock);
+
+CINDEX_LINKAGE
+CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile,
+                                           CXCursorAndRangeVisitorBlock);
+
+#  endif
+#endif
+
+/**
+ * \brief The client's data object that is associated with a CXFile.
+ */
+typedef void *CXIdxClientFile;
+
+/**
+ * \brief The client's data object that is associated with a semantic entity.
+ */
+typedef void *CXIdxClientEntity;
+
+/**
+ * \brief The client's data object that is associated with a semantic container
+ * of entities.
+ */
+typedef void *CXIdxClientContainer;
+
+/**
+ * \brief The client's data object that is associated with an AST file (PCH
+ * or module).
+ */
+typedef void *CXIdxClientASTFile;
+
+/**
+ * \brief Source location passed to index callbacks.
+ */
+typedef struct {
+  void *ptr_data[2];
+  unsigned int_data;
+} CXIdxLoc;
+
+/**
+ * \brief Data for ppIncludedFile callback.
+ */
+typedef struct {
+  /**
+   * \brief Location of '#' in the \#include/\#import directive.
+   */
+  CXIdxLoc hashLoc;
+  /**
+   * \brief Filename as written in the \#include/\#import directive.
+   */
+  const char *filename;
+  /**
+   * \brief The actual file that the \#include/\#import directive resolved to.
+   */
+  CXFile file;
+  int isImport;
+  int isAngled;
+  /**
+   * \brief Non-zero if the directive was automatically turned into a module
+   * import.
+   */
+  int isModuleImport;
+} CXIdxIncludedFileInfo;
+
+/**
+ * \brief Data for IndexerCallbacks#importedASTFile.
+ */
+typedef struct {
+  /**
+   * \brief Top level AST file containing the imported PCH, module or submodule.
+   */
+  CXFile file;
+  /**
+   * \brief The imported module or NULL if the AST file is a PCH.
+   */
+  CXModule module;
+  /**
+   * \brief Location where the file is imported. Applicable only for modules.
+   */
+  CXIdxLoc loc;
+  /**
+   * \brief Non-zero if an inclusion directive was automatically turned into
+   * a module import. Applicable only for modules.
+   */
+  int isImplicit;
+
+} CXIdxImportedASTFileInfo;
+
+typedef enum {
+  CXIdxEntity_Unexposed     = 0,
+  CXIdxEntity_Typedef       = 1,
+  CXIdxEntity_Function      = 2,
+  CXIdxEntity_Variable      = 3,
+  CXIdxEntity_Field         = 4,
+  CXIdxEntity_EnumConstant  = 5,
+
+  CXIdxEntity_ObjCClass     = 6,
+  CXIdxEntity_ObjCProtocol  = 7,
+  CXIdxEntity_ObjCCategory  = 8,
+
+  CXIdxEntity_ObjCInstanceMethod = 9,
+  CXIdxEntity_ObjCClassMethod    = 10,
+  CXIdxEntity_ObjCProperty  = 11,
+  CXIdxEntity_ObjCIvar      = 12,
+
+  CXIdxEntity_Enum          = 13,
+  CXIdxEntity_Struct        = 14,
+  CXIdxEntity_Union         = 15,
+
+  CXIdxEntity_CXXClass              = 16,
+  CXIdxEntity_CXXNamespace          = 17,
+  CXIdxEntity_CXXNamespaceAlias     = 18,
+  CXIdxEntity_CXXStaticVariable     = 19,
+  CXIdxEntity_CXXStaticMethod       = 20,
+  CXIdxEntity_CXXInstanceMethod     = 21,
+  CXIdxEntity_CXXConstructor        = 22,
+  CXIdxEntity_CXXDestructor         = 23,
+  CXIdxEntity_CXXConversionFunction = 24,
+  CXIdxEntity_CXXTypeAlias          = 25,
+  CXIdxEntity_CXXInterface          = 26
+
+} CXIdxEntityKind;
+
+typedef enum {
+  CXIdxEntityLang_None = 0,
+  CXIdxEntityLang_C    = 1,
+  CXIdxEntityLang_ObjC = 2,
+  CXIdxEntityLang_CXX  = 3
+} CXIdxEntityLanguage;
+
+/**
+ * \brief Extra C++ template information for an entity. This can apply to:
+ * CXIdxEntity_Function
+ * CXIdxEntity_CXXClass
+ * CXIdxEntity_CXXStaticMethod
+ * CXIdxEntity_CXXInstanceMethod
+ * CXIdxEntity_CXXConstructor
+ * CXIdxEntity_CXXConversionFunction
+ * CXIdxEntity_CXXTypeAlias
+ */
+typedef enum {
+  CXIdxEntity_NonTemplate   = 0,
+  CXIdxEntity_Template      = 1,
+  CXIdxEntity_TemplatePartialSpecialization = 2,
+  CXIdxEntity_TemplateSpecialization = 3
+} CXIdxEntityCXXTemplateKind;
+
+typedef enum {
+  CXIdxAttr_Unexposed     = 0,
+  CXIdxAttr_IBAction      = 1,
+  CXIdxAttr_IBOutlet      = 2,
+  CXIdxAttr_IBOutletCollection = 3
+} CXIdxAttrKind;
+
+typedef struct {
+  CXIdxAttrKind kind;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxAttrInfo;
+
+typedef struct {
+  CXIdxEntityKind kind;
+  CXIdxEntityCXXTemplateKind templateKind;
+  CXIdxEntityLanguage lang;
+  const char *name;
+  const char *USR;
+  CXCursor cursor;
+  const CXIdxAttrInfo *const *attributes;
+  unsigned numAttributes;
+} CXIdxEntityInfo;
+
+typedef struct {
+  CXCursor cursor;
+} CXIdxContainerInfo;
+
+typedef struct {
+  const CXIdxAttrInfo *attrInfo;
+  const CXIdxEntityInfo *objcClass;
+  CXCursor classCursor;
+  CXIdxLoc classLoc;
+} CXIdxIBOutletCollectionAttrInfo;
+
+typedef enum {
+  CXIdxDeclFlag_Skipped = 0x1
+} CXIdxDeclInfoFlags;
+
+typedef struct {
+  const CXIdxEntityInfo *entityInfo;
+  CXCursor cursor;
+  CXIdxLoc loc;
+  const CXIdxContainerInfo *semanticContainer;
+  /**
+   * \brief Generally same as #semanticContainer but can be different in
+   * cases like out-of-line C++ member functions.
+   */
+  const CXIdxContainerInfo *lexicalContainer;
+  int isRedeclaration;
+  int isDefinition;
+  int isContainer;
+  const CXIdxContainerInfo *declAsContainer;
+  /**
+   * \brief Whether the declaration exists in code or was created implicitly
+   * by the compiler, e.g. implicit Objective-C methods for properties.
+   */
+  int isImplicit;
+  const CXIdxAttrInfo *const *attributes;
+  unsigned numAttributes;
+
+  unsigned flags;
+
+} CXIdxDeclInfo;
+
+typedef enum {
+  CXIdxObjCContainer_ForwardRef = 0,
+  CXIdxObjCContainer_Interface = 1,
+  CXIdxObjCContainer_Implementation = 2
+} CXIdxObjCContainerKind;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  CXIdxObjCContainerKind kind;
+} CXIdxObjCContainerDeclInfo;
+
+typedef struct {
+  const CXIdxEntityInfo *base;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxBaseClassInfo;
+
+typedef struct {
+  const CXIdxEntityInfo *protocol;
+  CXCursor cursor;
+  CXIdxLoc loc;
+} CXIdxObjCProtocolRefInfo;
+
+typedef struct {
+  const CXIdxObjCProtocolRefInfo *const *protocols;
+  unsigned numProtocols;
+} CXIdxObjCProtocolRefListInfo;
+
+typedef struct {
+  const CXIdxObjCContainerDeclInfo *containerInfo;
+  const CXIdxBaseClassInfo *superInfo;
+  const CXIdxObjCProtocolRefListInfo *protocols;
+} CXIdxObjCInterfaceDeclInfo;
+
+typedef struct {
+  const CXIdxObjCContainerDeclInfo *containerInfo;
+  const CXIdxEntityInfo *objcClass;
+  CXCursor classCursor;
+  CXIdxLoc classLoc;
+  const CXIdxObjCProtocolRefListInfo *protocols;
+} CXIdxObjCCategoryDeclInfo;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  const CXIdxEntityInfo *getter;
+  const CXIdxEntityInfo *setter;
+} CXIdxObjCPropertyDeclInfo;
+
+typedef struct {
+  const CXIdxDeclInfo *declInfo;
+  const CXIdxBaseClassInfo *const *bases;
+  unsigned numBases;
+} CXIdxCXXClassDeclInfo;
+
+/**
+ * \brief Data for IndexerCallbacks#indexEntityReference.
+ */
+typedef enum {
+  /**
+   * \brief The entity is referenced directly in user's code.
+   */
+  CXIdxEntityRef_Direct = 1,
+  /**
+   * \brief An implicit reference, e.g. a reference of an Objective-C method
+   * via the dot syntax.
+   */
+  CXIdxEntityRef_Implicit = 2
+} CXIdxEntityRefKind;
+
+/**
+ * \brief Data for IndexerCallbacks#indexEntityReference.
+ */
+typedef struct {
+  CXIdxEntityRefKind kind;
+  /**
+   * \brief Reference cursor.
+   */
+  CXCursor cursor;
+  CXIdxLoc loc;
+  /**
+   * \brief The entity that gets referenced.
+   */
+  const CXIdxEntityInfo *referencedEntity;
+  /**
+   * \brief Immediate "parent" of the reference. For example:
+   * 
+   * \code
+   * Foo *var;
+   * \endcode
+   * 
+   * The parent of reference of type 'Foo' is the variable 'var'.
+   * For references inside statement bodies of functions/methods,
+   * the parentEntity will be the function/method.
+   */
+  const CXIdxEntityInfo *parentEntity;
+  /**
+   * \brief Lexical container context of the reference.
+   */
+  const CXIdxContainerInfo *container;
+} CXIdxEntityRefInfo;
+
+/**
+ * \brief A group of callbacks used by #clang_indexSourceFile and
+ * #clang_indexTranslationUnit.
+ */
+typedef struct {
+  /**
+   * \brief Called periodically to check whether indexing should be aborted.
+   * Should return 0 to continue, and non-zero to abort.
+   */
+  int (*abortQuery)(CXClientData client_data, void *reserved);
+
+  /**
+   * \brief Called at the end of indexing; passes the complete diagnostic set.
+   */
+  void (*diagnostic)(CXClientData client_data,
+                     CXDiagnosticSet, void *reserved);
+
+  CXIdxClientFile (*enteredMainFile)(CXClientData client_data,
+                                     CXFile mainFile, void *reserved);
+  
+  /**
+   * \brief Called when a file gets \#included/\#imported.
+   */
+  CXIdxClientFile (*ppIncludedFile)(CXClientData client_data,
+                                    const CXIdxIncludedFileInfo *);
+  
+  /**
+   * \brief Called when a AST file (PCH or module) gets imported.
+   * 
+   * AST files will not get indexed (there will not be callbacks to index all
+   * the entities in an AST file). The recommended action is that, if the AST
+   * file is not already indexed, to initiate a new indexing job specific to
+   * the AST file.
+   */
+  CXIdxClientASTFile (*importedASTFile)(CXClientData client_data,
+                                        const CXIdxImportedASTFileInfo *);
+
+  /**
+   * \brief Called at the beginning of indexing a translation unit.
+   */
+  CXIdxClientContainer (*startedTranslationUnit)(CXClientData client_data,
+                                                 void *reserved);
+
+  void (*indexDeclaration)(CXClientData client_data,
+                           const CXIdxDeclInfo *);
+
+  /**
+   * \brief Called to index a reference of an entity.
+   */
+  void (*indexEntityReference)(CXClientData client_data,
+                               const CXIdxEntityRefInfo *);
+
+} IndexerCallbacks;
+
+CINDEX_LINKAGE int clang_index_isEntityObjCContainerKind(CXIdxEntityKind);
+CINDEX_LINKAGE const CXIdxObjCContainerDeclInfo *
+clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCInterfaceDeclInfo *
+clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE
+const CXIdxObjCCategoryDeclInfo *
+clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCProtocolRefListInfo *
+clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxObjCPropertyDeclInfo *
+clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *);
+
+CINDEX_LINKAGE const CXIdxIBOutletCollectionAttrInfo *
+clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *);
+
+CINDEX_LINKAGE const CXIdxCXXClassDeclInfo *
+clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *);
+
+/**
+ * \brief For retrieving a custom CXIdxClientContainer attached to a
+ * container.
+ */
+CINDEX_LINKAGE CXIdxClientContainer
+clang_index_getClientContainer(const CXIdxContainerInfo *);
+
+/**
+ * \brief For setting a custom CXIdxClientContainer attached to a
+ * container.
+ */
+CINDEX_LINKAGE void
+clang_index_setClientContainer(const CXIdxContainerInfo *,CXIdxClientContainer);
+
+/**
+ * \brief For retrieving a custom CXIdxClientEntity attached to an entity.
+ */
+CINDEX_LINKAGE CXIdxClientEntity
+clang_index_getClientEntity(const CXIdxEntityInfo *);
+
+/**
+ * \brief For setting a custom CXIdxClientEntity attached to an entity.
+ */
+CINDEX_LINKAGE void
+clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity);
+
+/**
+ * \brief An indexing action/session, to be applied to one or multiple
+ * translation units.
+ */
+typedef void *CXIndexAction;
+
+/**
+ * \brief An indexing action/session, to be applied to one or multiple
+ * translation units.
+ *
+ * \param CIdx The index object with which the index action will be associated.
+ */
+CINDEX_LINKAGE CXIndexAction clang_IndexAction_create(CXIndex CIdx);
+
+/**
+ * \brief Destroy the given index action.
+ *
+ * The index action must not be destroyed until all of the translation units
+ * created within that index action have been destroyed.
+ */
+CINDEX_LINKAGE void clang_IndexAction_dispose(CXIndexAction);
+
+typedef enum {
+  /**
+   * \brief Used to indicate that no special indexing options are needed.
+   */
+  CXIndexOpt_None = 0x0,
+  
+  /**
+   * \brief Used to indicate that IndexerCallbacks#indexEntityReference should
+   * be invoked for only one reference of an entity per source file that does
+   * not also include a declaration/definition of the entity.
+   */
+  CXIndexOpt_SuppressRedundantRefs = 0x1,
+
+  /**
+   * \brief Function-local symbols should be indexed. If this is not set
+   * function-local symbols will be ignored.
+   */
+  CXIndexOpt_IndexFunctionLocalSymbols = 0x2,
+
+  /**
+   * \brief Implicit function/class template instantiations should be indexed.
+   * If this is not set, implicit instantiations will be ignored.
+   */
+  CXIndexOpt_IndexImplicitTemplateInstantiations = 0x4,
+
+  /**
+   * \brief Suppress all compiler warnings when parsing for indexing.
+   */
+  CXIndexOpt_SuppressWarnings = 0x8,
+
+  /**
+   * \brief Skip a function/method body that was already parsed during an
+   * indexing session associated with a \c CXIndexAction object.
+   * Bodies in system headers are always skipped.
+   */
+  CXIndexOpt_SkipParsedBodiesInSession = 0x10
+
+} CXIndexOptFlags;
+
+/**
+ * \brief Index the given source file and the translation unit corresponding
+ * to that file via callbacks implemented through #IndexerCallbacks.
+ *
+ * \param client_data pointer data supplied by the client, which will
+ * be passed to the invoked callbacks.
+ *
+ * \param index_callbacks Pointer to indexing callbacks that the client
+ * implements.
+ *
+ * \param index_callbacks_size Size of #IndexerCallbacks structure that gets
+ * passed in index_callbacks.
+ *
+ * \param index_options A bitmask of options that affects how indexing is
+ * performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
+ *
+ * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
+ * reused after indexing is finished. Set to \c NULL if you do not require it.
+ *
+ * \returns 0 on success or if there were errors from which the compiler could
+ * recover.  If there is a failure from which the there is no recovery, returns
+ * a non-zero \c CXErrorCode.
+ *
+ * The rest of the parameters are the same as #clang_parseTranslationUnit.
+ */
+CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction,
+                                         CXClientData client_data,
+                                         IndexerCallbacks *index_callbacks,
+                                         unsigned index_callbacks_size,
+                                         unsigned index_options,
+                                         const char *source_filename,
+                                         const char * const *command_line_args,
+                                         int num_command_line_args,
+                                         struct CXUnsavedFile *unsaved_files,
+                                         unsigned num_unsaved_files,
+                                         CXTranslationUnit *out_TU,
+                                         unsigned TU_options);
+
+/**
+ * \brief Index the given translation unit via callbacks implemented through
+ * #IndexerCallbacks.
+ * 
+ * The order of callback invocations is not guaranteed to be the same as
+ * when indexing a source file. The high level order will be:
+ * 
+ *   -Preprocessor callbacks invocations
+ *   -Declaration/reference callbacks invocations
+ *   -Diagnostic callback invocations
+ *
+ * The parameters are the same as #clang_indexSourceFile.
+ * 
+ * \returns If there is a failure from which the there is no recovery, returns
+ * non-zero, otherwise returns 0.
+ */
+CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction,
+                                              CXClientData client_data,
+                                              IndexerCallbacks *index_callbacks,
+                                              unsigned index_callbacks_size,
+                                              unsigned index_options,
+                                              CXTranslationUnit);
+
+/**
+ * \brief Retrieve the CXIdxFile, file, line, column, and offset represented by
+ * the given CXIdxLoc.
+ *
+ * If the location refers into a macro expansion, retrieves the
+ * location of the macro expansion and if it refers into a macro argument
+ * retrieves the location of the argument.
+ */
+CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc,
+                                                   CXIdxClientFile *indexFile,
+                                                   CXFile *file,
+                                                   unsigned *line,
+                                                   unsigned *column,
+                                                   unsigned *offset);
+
+/**
+ * \brief Retrieve the CXSourceLocation represented by the given CXIdxLoc.
+ */
+CINDEX_LINKAGE
+CXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc loc);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Include the comment API for compatibility. This will eventually go away. */
+#include "clang-c/Documentation.h"
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/Platform.h b/include/clang-c/Platform.h
new file mode 100644
index 0000000..0f866c6
--- /dev/null
+++ b/include/clang-c/Platform.h
@@ -0,0 +1,45 @@
+/*===-- clang-c/Platform.h - C Index platform decls   -------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides platform specific macros (dllimport, deprecated, ...) *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_PLATFORM_H
+#define CLANG_C_PLATFORM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MSVC DLL import/export. */
+#ifdef _MSC_VER
+  #ifdef _CINDEX_LIB_
+    #define CINDEX_LINKAGE __declspec(dllexport)
+  #else
+    #define CINDEX_LINKAGE __declspec(dllimport)
+  #endif
+#else
+  #define CINDEX_LINKAGE
+#endif
+
+#ifdef __GNUC__
+  #define CINDEX_DEPRECATED __attribute__((deprecated))
+#else
+  #ifdef _MSC_VER
+    #define CINDEX_DEPRECATED __declspec(deprecated)
+  #else
+    #define CINDEX_DEPRECATED
+  #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
new file mode 100644
index 0000000..ad4f23c
--- /dev/null
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -0,0 +1,125 @@
+//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H
+#define LLVM_CLANG_ARCMIGRATE_ARCMT_H
+
+#include "clang/ARCMigrate/FileRemapper.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/CompilerInvocation.h"
+
+namespace clang {
+  class ASTContext;
+  class DiagnosticConsumer;
+
+namespace arcmt {
+  class MigrationPass;
+
+/// \brief Creates an AST with the provided CompilerInvocation but with these
+/// changes:
+///   -if a PCH/PTH is set, the original header is used instead
+///   -Automatic Reference Counting mode is enabled
+///
+/// It then checks the AST and produces errors/warning for ARC migration issues
+/// that the user needs to handle manually.
+///
+/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
+/// even if the migrator can fix them, but the function will still return false
+/// if all ARC errors can be fixed.
+///
+/// \param plistOut if non-empty, it is the file path to store the plist with
+/// the pre-migration ARC diagnostics.
+///
+/// \returns false if no error is produced, true otherwise.
+bool checkForManualIssues(CompilerInvocation &CI,
+                          const FrontendInputFile &Input,
+                          DiagnosticConsumer *DiagClient,
+                          bool emitPremigrationARCErrors = false,
+                          StringRef plistOut = StringRef());
+
+/// \brief Works similar to checkForManualIssues but instead of checking, it
+/// applies automatic modifications to source files to conform to ARC.
+///
+/// \returns false if no error is produced, true otherwise.
+bool applyTransformations(CompilerInvocation &origCI,
+                          const FrontendInputFile &Input,
+                          DiagnosticConsumer *DiagClient);
+
+/// \brief Applies automatic modifications and produces temporary files
+/// and metadata into the \p outputDir path.
+///
+/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
+/// even if the migrator can fix them, but the function will still return false
+/// if all ARC errors can be fixed.
+///
+/// \param plistOut if non-empty, it is the file path to store the plist with
+/// the pre-migration ARC diagnostics.
+///
+/// \returns false if no error is produced, true otherwise.
+bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
+                               const FrontendInputFile &Input,
+                               DiagnosticConsumer *DiagClient,
+                               StringRef outputDir,
+                               bool emitPremigrationARCErrors,
+                               StringRef plistOut);
+
+/// \brief Get the set of file remappings from the \p outputDir path that
+/// migrateWithTemporaryFiles produced.
+///
+/// \returns false if no error is produced, true otherwise.
+bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
+                       StringRef outputDir,
+                       DiagnosticConsumer *DiagClient);
+
+/// \brief Get the set of file remappings from a list of files with remapping
+/// info.
+///
+/// \returns false if no error is produced, true otherwise.
+bool getFileRemappingsFromFileList(
+                        std::vector<std::pair<std::string,std::string> > &remap,
+                        ArrayRef<StringRef> remapFiles,
+                        DiagnosticConsumer *DiagClient);
+
+typedef void (*TransformFn)(MigrationPass &pass);
+
+std::vector<TransformFn> getAllTransformations(LangOptions::GCMode OrigGCMode,
+                                               bool NoFinalizeRemoval);
+
+class MigrationProcess {
+  CompilerInvocation OrigCI;
+  DiagnosticConsumer *DiagClient;
+  FileRemapper Remapper;
+
+public:
+  bool HadARCErrors;
+
+  MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient,
+                   StringRef outputDir = StringRef());
+
+  class RewriteListener {
+  public:
+    virtual ~RewriteListener();
+
+    virtual void start(ASTContext &Ctx) { }
+    virtual void finish() { }
+
+    virtual void insert(SourceLocation loc, StringRef text) { }
+    virtual void remove(CharSourceRange range) { }
+  };
+
+  bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr);
+
+  FileRemapper &getRemapper() { return Remapper; }
+};
+
+} // end namespace arcmt
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
new file mode 100644
index 0000000..b3e74b9
--- /dev/null
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -0,0 +1,76 @@
+//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
+#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
+
+#include "clang/ARCMigrate/FileRemapper.h"
+#include "clang/Frontend/FrontendAction.h"
+#include <memory>
+
+namespace clang {
+namespace arcmt {
+
+class CheckAction : public WrapperFrontendAction {
+protected:
+  bool BeginInvocation(CompilerInstance &CI) override;
+
+public:
+  CheckAction(FrontendAction *WrappedAction);
+};
+
+class ModifyAction : public WrapperFrontendAction {
+protected:
+  bool BeginInvocation(CompilerInstance &CI) override;
+
+public:
+  ModifyAction(FrontendAction *WrappedAction);
+};
+
+class MigrateSourceAction : public ASTFrontendAction {
+  FileRemapper Remapper;
+protected:
+  bool BeginInvocation(CompilerInstance &CI) override;
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class MigrateAction : public WrapperFrontendAction {
+  std::string MigrateDir;
+  std::string PlistOut;
+  bool EmitPremigrationARCErros;
+protected:
+  bool BeginInvocation(CompilerInstance &CI) override;
+
+public:
+  MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
+                StringRef plistOut,
+                bool emitPremigrationARCErrors);
+};
+
+/// \brief Migrates to modern ObjC syntax.
+class ObjCMigrateAction : public WrapperFrontendAction {
+  std::string MigrateDir;
+  unsigned    ObjCMigAction;
+  FileRemapper Remapper;
+  CompilerInstance *CompInst;
+public:
+  ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
+                    unsigned migrateAction);
+
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  bool BeginInvocation(CompilerInstance &CI) override;
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
new file mode 100644
index 0000000..e094301
--- /dev/null
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -0,0 +1,77 @@
+//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
+#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+  class FileManager;
+  class FileEntry;
+  class DiagnosticsEngine;
+  class PreprocessorOptions;
+
+namespace arcmt {
+
+class FileRemapper {
+  // FIXME: Reuse the same FileManager for multiple ASTContexts.
+  std::unique_ptr<FileManager> FileMgr;
+
+  typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
+  typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
+  MappingsTy FromToMappings;
+
+  llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings;
+
+public:
+  FileRemapper();
+  ~FileRemapper();
+  
+  bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
+                    bool ignoreIfFilesChanged);
+  bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
+                    bool ignoreIfFilesChanged);
+  bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag);
+  bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag);
+
+  bool overwriteOriginal(DiagnosticsEngine &Diag,
+                         StringRef outputDir = StringRef());
+
+  void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
+
+  void applyMappings(PreprocessorOptions &PPOpts) const;
+
+  void clear(StringRef outputDir = StringRef());
+
+private:
+  void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf);
+  void remap(const FileEntry *file, const FileEntry *newfile);
+
+  const FileEntry *getOriginalFile(StringRef filePath);
+  void resetTarget(Target &targ);
+
+  bool report(const Twine &err, DiagnosticsEngine &Diag);
+
+  std::string getRemapInfoFile(StringRef outputDir);
+};
+
+} // end namespace arcmt
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
new file mode 100644
index 0000000..e58c219
--- /dev/null
+++ b/include/clang/AST/APValue.h
@@ -0,0 +1,452 @@
+//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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 APValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_APVALUE_H
+#define LLVM_CLANG_AST_APVALUE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+  class AddrLabelExpr;
+  class ASTContext;
+  class CharUnits;
+  class DiagnosticBuilder;
+  class Expr;
+  class FieldDecl;
+  class Decl;
+  class ValueDecl;
+  class CXXRecordDecl;
+  class QualType;
+
+/// APValue - This class implements a discriminated union of [uninitialized]
+/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
+/// [Vector: N * APValue], [Array: N * APValue]
+class APValue {
+  typedef llvm::APSInt APSInt;
+  typedef llvm::APFloat APFloat;
+public:
+  enum ValueKind {
+    Uninitialized,
+    Int,
+    Float,
+    ComplexInt,
+    ComplexFloat,
+    LValue,
+    Vector,
+    Array,
+    Struct,
+    Union,
+    MemberPointer,
+    AddrLabelDiff
+  };
+  typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
+  typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
+  union LValuePathEntry {
+    /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
+    /// in the path. An opaque value of type BaseOrMemberType.
+    void *BaseOrMember;
+    /// ArrayIndex - The array index of the next item in the path.
+    uint64_t ArrayIndex;
+  };
+  struct NoLValuePath {};
+  struct UninitArray {};
+  struct UninitStruct {};
+private:
+  ValueKind Kind;
+
+  struct ComplexAPSInt {
+    APSInt Real, Imag;
+    ComplexAPSInt() : Real(1), Imag(1) {}
+  };
+  struct ComplexAPFloat {
+    APFloat Real, Imag;
+    ComplexAPFloat() : Real(0.0), Imag(0.0) {}
+  };
+  struct LV;
+  struct Vec {
+    APValue *Elts;
+    unsigned NumElts;
+    Vec() : Elts(nullptr), NumElts(0) {}
+    ~Vec() { delete[] Elts; }
+  };
+  struct Arr {
+    APValue *Elts;
+    unsigned NumElts, ArrSize;
+    Arr(unsigned NumElts, unsigned ArrSize);
+    ~Arr();
+  };
+  struct StructData {
+    APValue *Elts;
+    unsigned NumBases;
+    unsigned NumFields;
+    StructData(unsigned NumBases, unsigned NumFields);
+    ~StructData();
+  };
+  struct UnionData {
+    const FieldDecl *Field;
+    APValue *Value;
+    UnionData();
+    ~UnionData();
+  };
+  struct AddrLabelDiffData {
+    const AddrLabelExpr* LHSExpr;
+    const AddrLabelExpr* RHSExpr;
+  };
+  struct MemberPointerData;
+
+  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
+  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
+                                      ComplexAPFloat, Vec, Arr, StructData,
+                                      UnionData, AddrLabelDiffData> DataType;
+  static const size_t DataSize = sizeof(DataType);
+
+  DataType Data;
+
+public:
+  APValue() : Kind(Uninitialized) {}
+  explicit APValue(APSInt I) : Kind(Uninitialized) {
+    MakeInt(); setInt(std::move(I));
+  }
+  explicit APValue(APFloat F) : Kind(Uninitialized) {
+    MakeFloat(); setFloat(std::move(F));
+  }
+  explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
+    MakeVector(); setVector(E, N);
+  }
+  APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
+    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
+  }
+  APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
+    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
+  }
+  APValue(const APValue &RHS);
+  APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
+  APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
+      : Kind(Uninitialized) {
+    MakeLValue(); setLValue(B, O, N, CallIndex);
+  }
+  APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
+          bool OnePastTheEnd, unsigned CallIndex)
+      : Kind(Uninitialized) {
+    MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex);
+  }
+  APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
+    MakeArray(InitElts, Size);
+  }
+  APValue(UninitStruct, unsigned B, unsigned M) : Kind(Uninitialized) {
+    MakeStruct(B, M);
+  }
+  explicit APValue(const FieldDecl *D, const APValue &V = APValue())
+      : Kind(Uninitialized) {
+    MakeUnion(); setUnion(D, V);
+  }
+  APValue(const ValueDecl *Member, bool IsDerivedMember,
+          ArrayRef<const CXXRecordDecl*> Path) : Kind(Uninitialized) {
+    MakeMemberPointer(Member, IsDerivedMember, Path);
+  }
+  APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
+      : Kind(Uninitialized) {
+    MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
+  }
+
+  ~APValue() {
+    MakeUninit();
+  }
+
+  /// \brief Returns whether the object performed allocations.
+  ///
+  /// If APValues are constructed via placement new, \c needsCleanup()
+  /// indicates whether the destructor must be called in order to correctly
+  /// free all allocated memory.
+  bool needsCleanup() const;
+
+  /// \brief Swaps the contents of this and the given APValue.
+  void swap(APValue &RHS);
+
+  ValueKind getKind() const { return Kind; }
+  bool isUninit() const { return Kind == Uninitialized; }
+  bool isInt() const { return Kind == Int; }
+  bool isFloat() const { return Kind == Float; }
+  bool isComplexInt() const { return Kind == ComplexInt; }
+  bool isComplexFloat() const { return Kind == ComplexFloat; }
+  bool isLValue() const { return Kind == LValue; }
+  bool isVector() const { return Kind == Vector; }
+  bool isArray() const { return Kind == Array; }
+  bool isStruct() const { return Kind == Struct; }
+  bool isUnion() const { return Kind == Union; }
+  bool isMemberPointer() const { return Kind == MemberPointer; }
+  bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; }
+
+  void dump() const;
+  void dump(raw_ostream &OS) const;
+
+  void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
+  std::string getAsString(ASTContext &Ctx, QualType Ty) const;
+
+  APSInt &getInt() {
+    assert(isInt() && "Invalid accessor");
+    return *(APSInt*)(char*)Data.buffer;
+  }
+  const APSInt &getInt() const {
+    return const_cast<APValue*>(this)->getInt();
+  }
+
+  APFloat &getFloat() {
+    assert(isFloat() && "Invalid accessor");
+    return *(APFloat*)(char*)Data.buffer;
+  }
+  const APFloat &getFloat() const {
+    return const_cast<APValue*>(this)->getFloat();
+  }
+
+  APSInt &getComplexIntReal() {
+    assert(isComplexInt() && "Invalid accessor");
+    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
+  }
+  const APSInt &getComplexIntReal() const {
+    return const_cast<APValue*>(this)->getComplexIntReal();
+  }
+
+  APSInt &getComplexIntImag() {
+    assert(isComplexInt() && "Invalid accessor");
+    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
+  }
+  const APSInt &getComplexIntImag() const {
+    return const_cast<APValue*>(this)->getComplexIntImag();
+  }
+
+  APFloat &getComplexFloatReal() {
+    assert(isComplexFloat() && "Invalid accessor");
+    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
+  }
+  const APFloat &getComplexFloatReal() const {
+    return const_cast<APValue*>(this)->getComplexFloatReal();
+  }
+
+  APFloat &getComplexFloatImag() {
+    assert(isComplexFloat() && "Invalid accessor");
+    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
+  }
+  const APFloat &getComplexFloatImag() const {
+    return const_cast<APValue*>(this)->getComplexFloatImag();
+  }
+
+  const LValueBase getLValueBase() const;
+  CharUnits &getLValueOffset();
+  const CharUnits &getLValueOffset() const {
+    return const_cast<APValue*>(this)->getLValueOffset();
+  }
+  bool isLValueOnePastTheEnd() const;
+  bool hasLValuePath() const;
+  ArrayRef<LValuePathEntry> getLValuePath() const;
+  unsigned getLValueCallIndex() const;
+
+  APValue &getVectorElt(unsigned I) {
+    assert(isVector() && "Invalid accessor");
+    assert(I < getVectorLength() && "Index out of range");
+    return ((Vec*)(char*)Data.buffer)->Elts[I];
+  }
+  const APValue &getVectorElt(unsigned I) const {
+    return const_cast<APValue*>(this)->getVectorElt(I);
+  }
+  unsigned getVectorLength() const {
+    assert(isVector() && "Invalid accessor");
+    return ((const Vec*)(const void *)Data.buffer)->NumElts;
+  }
+
+  APValue &getArrayInitializedElt(unsigned I) {
+    assert(isArray() && "Invalid accessor");
+    assert(I < getArrayInitializedElts() && "Index out of range");
+    return ((Arr*)(char*)Data.buffer)->Elts[I];
+  }
+  const APValue &getArrayInitializedElt(unsigned I) const {
+    return const_cast<APValue*>(this)->getArrayInitializedElt(I);
+  }
+  bool hasArrayFiller() const {
+    return getArrayInitializedElts() != getArraySize();
+  }
+  APValue &getArrayFiller() {
+    assert(isArray() && "Invalid accessor");
+    assert(hasArrayFiller() && "No array filler");
+    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
+  }
+  const APValue &getArrayFiller() const {
+    return const_cast<APValue*>(this)->getArrayFiller();
+  }
+  unsigned getArrayInitializedElts() const {
+    assert(isArray() && "Invalid accessor");
+    return ((const Arr*)(const void *)Data.buffer)->NumElts;
+  }
+  unsigned getArraySize() const {
+    assert(isArray() && "Invalid accessor");
+    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
+  }
+
+  unsigned getStructNumBases() const {
+    assert(isStruct() && "Invalid accessor");
+    return ((const StructData*)(const char*)Data.buffer)->NumBases;
+  }
+  unsigned getStructNumFields() const {
+    assert(isStruct() && "Invalid accessor");
+    return ((const StructData*)(const char*)Data.buffer)->NumFields;
+  }
+  APValue &getStructBase(unsigned i) {
+    assert(isStruct() && "Invalid accessor");
+    return ((StructData*)(char*)Data.buffer)->Elts[i];
+  }
+  APValue &getStructField(unsigned i) {
+    assert(isStruct() && "Invalid accessor");
+    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
+  }
+  const APValue &getStructBase(unsigned i) const {
+    return const_cast<APValue*>(this)->getStructBase(i);
+  }
+  const APValue &getStructField(unsigned i) const {
+    return const_cast<APValue*>(this)->getStructField(i);
+  }
+
+  const FieldDecl *getUnionField() const {
+    assert(isUnion() && "Invalid accessor");
+    return ((const UnionData*)(const char*)Data.buffer)->Field;
+  }
+  APValue &getUnionValue() {
+    assert(isUnion() && "Invalid accessor");
+    return *((UnionData*)(char*)Data.buffer)->Value;
+  }
+  const APValue &getUnionValue() const {
+    return const_cast<APValue*>(this)->getUnionValue();
+  }
+
+  const ValueDecl *getMemberPointerDecl() const;
+  bool isMemberPointerToDerivedMember() const;
+  ArrayRef<const CXXRecordDecl*> getMemberPointerPath() const;
+
+  const AddrLabelExpr* getAddrLabelDiffLHS() const {
+    assert(isAddrLabelDiff() && "Invalid accessor");
+    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
+  }
+  const AddrLabelExpr* getAddrLabelDiffRHS() const {
+    assert(isAddrLabelDiff() && "Invalid accessor");
+    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
+  }
+
+  void setInt(APSInt I) {
+    assert(isInt() && "Invalid accessor");
+    *(APSInt *)(char *)Data.buffer = std::move(I);
+  }
+  void setFloat(APFloat F) {
+    assert(isFloat() && "Invalid accessor");
+    *(APFloat *)(char *)Data.buffer = std::move(F);
+  }
+  void setVector(const APValue *E, unsigned N) {
+    assert(isVector() && "Invalid accessor");
+    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
+    ((Vec*)(char*)Data.buffer)->NumElts = N;
+    for (unsigned i = 0; i != N; ++i)
+      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
+  }
+  void setComplexInt(APSInt R, APSInt I) {
+    assert(R.getBitWidth() == I.getBitWidth() &&
+           "Invalid complex int (type mismatch).");
+    assert(isComplexInt() && "Invalid accessor");
+    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
+    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
+  }
+  void setComplexFloat(APFloat R, APFloat I) {
+    assert(&R.getSemantics() == &I.getSemantics() &&
+           "Invalid complex float (type mismatch).");
+    assert(isComplexFloat() && "Invalid accessor");
+    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
+    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
+  }
+  void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+                 unsigned CallIndex);
+  void setLValue(LValueBase B, const CharUnits &O,
+                 ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
+                 unsigned CallIndex);
+  void setUnion(const FieldDecl *Field, const APValue &Value) {
+    assert(isUnion() && "Invalid accessor");
+    ((UnionData*)(char*)Data.buffer)->Field = Field;
+    *((UnionData*)(char*)Data.buffer)->Value = Value;
+  }
+  void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
+                        const AddrLabelExpr* RHSExpr) {
+    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
+    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
+  }
+
+  /// Assign by swapping from a copy of the RHS.
+  APValue &operator=(APValue RHS) {
+    swap(RHS);
+    return *this;
+  }
+
+private:
+  void DestroyDataAndMakeUninit();
+  void MakeUninit() {
+    if (Kind != Uninitialized)
+      DestroyDataAndMakeUninit();
+  }
+  void MakeInt() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)Data.buffer) APSInt(1);
+    Kind = Int;
+  }
+  void MakeFloat() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) APFloat(0.0);
+    Kind = Float;
+  }
+  void MakeVector() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) Vec();
+    Kind = Vector;
+  }
+  void MakeComplexInt() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) ComplexAPSInt();
+    Kind = ComplexInt;
+  }
+  void MakeComplexFloat() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) ComplexAPFloat();
+    Kind = ComplexFloat;
+  }
+  void MakeLValue();
+  void MakeArray(unsigned InitElts, unsigned Size);
+  void MakeStruct(unsigned B, unsigned M) {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) StructData(B, M);
+    Kind = Struct;
+  }
+  void MakeUnion() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) UnionData();
+    Kind = Union;
+  }
+  void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
+                         ArrayRef<const CXXRecordDecl*> Path);
+  void MakeAddrLabelDiff() {
+    assert(isUninit() && "Bad state change");
+    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
+    Kind = AddrLabelDiff;
+  }
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
new file mode 100644
index 0000000..6db351d
--- /dev/null
+++ b/include/clang/AST/AST.h
@@ -0,0 +1,28 @@
+//===--- AST.h - "Umbrella" header for AST library --------------*- 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 interface to the AST classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_AST_H
+#define LLVM_CLANG_AST_AST_H
+
+// This header exports all AST interfaces.
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+
+#endif
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
new file mode 100644
index 0000000..736a10b
--- /dev/null
+++ b/include/clang/AST/ASTConsumer.h
@@ -0,0 +1,163 @@
+//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- 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 ASTConsumer class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
+#define LLVM_CLANG_AST_ASTCONSUMER_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+  class ASTContext;
+  class CXXMethodDecl;
+  class CXXRecordDecl;
+  class Decl;
+  class DeclGroupRef;
+  class ASTMutationListener;
+  class ASTDeserializationListener; // layering violation because void* is ugly
+  class SemaConsumer; // layering violation required for safe SemaConsumer
+  class TagDecl;
+  class VarDecl;
+  class FunctionDecl;
+  class ImportDecl;
+
+/// ASTConsumer - This is an abstract interface that should be implemented by
+/// clients that read ASTs.  This abstraction layer allows the client to be
+/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
+class ASTConsumer {
+  /// \brief Whether this AST consumer also requires information about
+  /// semantic analysis.
+  bool SemaConsumer;
+
+  friend class SemaConsumer;
+
+public:
+  ASTConsumer() : SemaConsumer(false) { }
+
+  virtual ~ASTConsumer() {}
+
+  /// Initialize - This is called to initialize the consumer, providing the
+  /// ASTContext.
+  virtual void Initialize(ASTContext &Context) {}
+
+  /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
+  /// called by the parser to process every top-level Decl*.
+  ///
+  /// \returns true to continue parsing, or false to abort parsing.
+  virtual bool HandleTopLevelDecl(DeclGroupRef D);
+
+  /// \brief This callback is invoked each time an inline method definition is
+  /// completed.
+  virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
+
+  /// HandleInterestingDecl - Handle the specified interesting declaration. This
+  /// is called by the AST reader when deserializing things that might interest
+  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
+  virtual void HandleInterestingDecl(DeclGroupRef D);
+
+  /// HandleTranslationUnit - This method is called when the ASTs for entire
+  /// translation unit have been parsed.
+  virtual void HandleTranslationUnit(ASTContext &Ctx) {}
+
+  /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
+  /// (e.g. struct, union, enum, class) is completed.  This allows the client to
+  /// hack on the type, which can occur at any point in the file (because these
+  /// can be defined in declspecs).
+  virtual void HandleTagDeclDefinition(TagDecl *D) {}
+
+  /// \brief This callback is invoked the first time each TagDecl is required to
+  /// be complete.
+  virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
+
+  /// \brief Invoked when a function is implicitly instantiated.
+  /// Note that at this point point it does not have a body, its body is
+  /// instantiated at the end of the translation unit and passed to
+  /// HandleTopLevelDecl.
+  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
+
+  /// \brief Handle the specified top-level declaration that occurred inside
+  /// and ObjC container.
+  /// The default implementation ignored them.
+  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
+
+  /// \brief Handle an ImportDecl that was implicitly created due to an
+  /// inclusion directive.
+  /// The default implementation passes it to HandleTopLevelDecl.
+  virtual void HandleImplicitImportDecl(ImportDecl *D);
+
+  /// \brief Handle a pragma that appends to Linker Options.  Currently this
+  /// only exists to support Microsoft's #pragma comment(linker, "/foo").
+  virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
+
+  /// \brief Handle a pragma that emits a mismatch identifier and value to the
+  /// object file for the linker to work with.  Currently, this only exists to
+  /// support Microsoft's #pragma detect_mismatch.
+  virtual void HandleDetectMismatch(llvm::StringRef Name,
+                                    llvm::StringRef Value) {}
+
+  /// \brief Handle a dependent library created by a pragma in the source.
+  /// Currently this only exists to support Microsoft's
+  /// #pragma comment(lib, "/foo").
+  virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
+
+  /// CompleteTentativeDefinition - Callback invoked at the end of a translation
+  /// unit to notify the consumer that the given tentative definition should be
+  /// completed.
+  ///
+  /// The variable declaration itself will be a tentative
+  /// definition. If it had an incomplete array type, its type will
+  /// have already been changed to an array of size 1. However, the
+  /// declaration remains a tentative definition and has not been
+  /// modified by the introduction of an implicit zero initializer.
+  virtual void CompleteTentativeDefinition(VarDecl *D) {}
+
+  /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
+  // variable has been instantiated.
+  virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
+
+  /// \brief Callback involved at the end of a translation unit to
+  /// notify the consumer that a vtable for the given C++ class is
+  /// required.
+  ///
+  /// \param RD The class whose vtable was used.
+  ///
+  /// \param DefinitionRequired Whether a definition of this vtable is
+  /// required in this translation unit; otherwise, it is only needed if
+  /// it was actually used.
+  virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+
+  /// \brief If the consumer is interested in entities getting modified after
+  /// their initial creation, it should return a pointer to
+  /// an ASTMutationListener here.
+  virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
+
+  /// \brief If the consumer is interested in entities being deserialized from
+  /// AST files, it should return a pointer to a ASTDeserializationListener here
+  virtual ASTDeserializationListener *GetASTDeserializationListener() {
+    return nullptr;
+  }
+
+  /// PrintStats - If desired, print any statistics.
+  virtual void PrintStats() {}
+
+  /// \brief This callback is called for each function if the Parser was
+  /// initialized with \c SkipFunctionBodies set to \c true.
+  ///
+  /// \return \c true if the function's body should be skipped. The function
+  /// body may be parsed anyway if it is needed (for instance, if it contains
+  /// the code completion point or is constexpr).
+  virtual bool shouldSkipFunctionBody(Decl *D) { return true; }
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
new file mode 100644
index 0000000..8134f6b
--- /dev/null
+++ b/include/clang/AST/ASTContext.h
@@ -0,0 +1,2427 @@
+//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::ASTContext interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
+#define LLVM_CLANG_AST_ASTCONTEXT_H
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RawCommentList.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+  struct fltSemantics;
+}
+
+namespace clang {
+  class FileManager;
+  class AtomicExpr;
+  class ASTRecordLayout;
+  class BlockExpr;
+  class CharUnits;
+  class DiagnosticsEngine;
+  class Expr;
+  class ASTMutationListener;
+  class IdentifierTable;
+  class MaterializeTemporaryExpr;
+  class SelectorTable;
+  class TargetInfo;
+  class CXXABI;
+  class MangleNumberingContext;
+  // Decls
+  class MangleContext;
+  class ObjCIvarDecl;
+  class ObjCPropertyDecl;
+  class UnresolvedSetIterator;
+  class UsingDecl;
+  class UsingShadowDecl;
+  class VTableContextBase;
+
+  namespace Builtin { class Context; }
+
+  namespace comments {
+    class FullComment;
+  }
+
+/// \brief Holds long-lived AST nodes (such as types and decls) that can be
+/// referred to throughout the semantic analysis of a file.
+class ASTContext : public RefCountedBase<ASTContext> {
+  ASTContext &this_() { return *this; }
+
+  mutable SmallVector<Type *, 0> Types;
+  mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
+  mutable llvm::FoldingSet<ComplexType> ComplexTypes;
+  mutable llvm::FoldingSet<PointerType> PointerTypes;
+  mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
+  mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
+  mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
+  mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
+  mutable llvm::FoldingSet<MemberPointerType> MemberPointerTypes;
+  mutable llvm::FoldingSet<ConstantArrayType> ConstantArrayTypes;
+  mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
+  mutable std::vector<VariableArrayType*> VariableArrayTypes;
+  mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
+  mutable llvm::FoldingSet<DependentSizedExtVectorType>
+    DependentSizedExtVectorTypes;
+  mutable llvm::FoldingSet<VectorType> VectorTypes;
+  mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
+  mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
+    FunctionProtoTypes;
+  mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
+  mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
+  mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+  mutable llvm::FoldingSet<SubstTemplateTypeParmType>
+    SubstTemplateTypeParmTypes;
+  mutable llvm::FoldingSet<SubstTemplateTypeParmPackType>
+    SubstTemplateTypeParmPackTypes;
+  mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
+    TemplateSpecializationTypes;
+  mutable llvm::FoldingSet<ParenType> ParenTypes;
+  mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+  mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
+  mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
+                                     ASTContext&>
+    DependentTemplateSpecializationTypes;
+  llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
+  mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
+  mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
+  mutable llvm::FoldingSet<AutoType> AutoTypes;
+  mutable llvm::FoldingSet<AtomicType> AtomicTypes;
+  llvm::FoldingSet<AttributedType> AttributedTypes;
+
+  mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
+  mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
+  mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage> 
+    SubstTemplateTemplateParms;
+  mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
+                                     ASTContext&> 
+    SubstTemplateTemplateParmPacks;
+  
+  /// \brief The set of nested name specifiers.
+  ///
+  /// This set is managed by the NestedNameSpecifier class.
+  mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
+  mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
+  friend class NestedNameSpecifier;
+
+  /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
+  ///
+  /// This is lazily created.  This is intentionally not serialized.
+  mutable llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>
+    ASTRecordLayouts;
+  mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
+    ObjCLayouts;
+
+  /// \brief A cache from types to size and alignment information.
+  typedef llvm::DenseMap<const Type*,
+                         std::pair<uint64_t, unsigned> > TypeInfoMap;
+  mutable TypeInfoMap MemoizedTypeInfo;
+
+  /// \brief A cache mapping from CXXRecordDecls to key functions.
+  llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
+  
+  /// \brief Mapping from ObjCContainers to their ObjCImplementations.
+  llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
+  
+  /// \brief Mapping from ObjCMethod to its duplicate declaration in the same
+  /// interface.
+  llvm::DenseMap<const ObjCMethodDecl*,const ObjCMethodDecl*> ObjCMethodRedecls;
+
+  /// \brief Mapping from __block VarDecls to their copy initialization expr.
+  llvm::DenseMap<const VarDecl*, Expr*> BlockVarCopyInits;
+    
+  /// \brief Mapping from class scope functions specialization to their
+  /// template patterns.
+  llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
+    ClassScopeSpecializationPattern;
+
+  /// \brief Mapping from materialized temporaries with static storage duration
+  /// that appear in constant initializers to their evaluated values.
+  llvm::DenseMap<const MaterializeTemporaryExpr*, APValue>
+    MaterializedTemporaryValues;
+
+  /// \brief Representation of a "canonical" template template parameter that
+  /// is used in canonical template names.
+  class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
+    TemplateTemplateParmDecl *Parm;
+    
+  public:
+    CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) 
+      : Parm(Parm) { }
+    
+    TemplateTemplateParmDecl *getParam() const { return Parm; }
+    
+    void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Parm); }
+    
+    static void Profile(llvm::FoldingSetNodeID &ID, 
+                        TemplateTemplateParmDecl *Parm);
+  };
+  mutable llvm::FoldingSet<CanonicalTemplateTemplateParm>
+    CanonTemplateTemplateParms;
+  
+  TemplateTemplateParmDecl *
+    getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
+
+  /// \brief The typedef for the __int128_t type.
+  mutable TypedefDecl *Int128Decl;
+
+  /// \brief The typedef for the __uint128_t type.
+  mutable TypedefDecl *UInt128Decl;
+
+  /// \brief The typedef for the __float128 stub type.
+  mutable TypeDecl *Float128StubDecl;
+  
+  /// \brief The typedef for the target specific predefined
+  /// __builtin_va_list type.
+  mutable TypedefDecl *BuiltinVaListDecl;
+
+  /// \brief The typedef for the predefined \c id type.
+  mutable TypedefDecl *ObjCIdDecl;
+  
+  /// \brief The typedef for the predefined \c SEL type.
+  mutable TypedefDecl *ObjCSelDecl;
+
+  /// \brief The typedef for the predefined \c Class type.
+  mutable TypedefDecl *ObjCClassDecl;
+
+  /// \brief The typedef for the predefined \c Protocol class in Objective-C.
+  mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
+  
+  /// \brief The typedef for the predefined 'BOOL' type.
+  mutable TypedefDecl *BOOLDecl;
+
+  // Typedefs which may be provided defining the structure of Objective-C
+  // pseudo-builtins
+  QualType ObjCIdRedefinitionType;
+  QualType ObjCClassRedefinitionType;
+  QualType ObjCSelRedefinitionType;
+
+  QualType ObjCConstantStringType;
+  mutable RecordDecl *CFConstantStringTypeDecl;
+  
+  mutable QualType ObjCSuperType;
+  
+  QualType ObjCNSStringType;
+
+  /// \brief The typedef declaration for the Objective-C "instancetype" type.
+  TypedefDecl *ObjCInstanceTypeDecl;
+  
+  /// \brief The type for the C FILE type.
+  TypeDecl *FILEDecl;
+
+  /// \brief The type for the C jmp_buf type.
+  TypeDecl *jmp_bufDecl;
+
+  /// \brief The type for the C sigjmp_buf type.
+  TypeDecl *sigjmp_bufDecl;
+
+  /// \brief The type for the C ucontext_t type.
+  TypeDecl *ucontext_tDecl;
+
+  /// \brief Type for the Block descriptor for Blocks CodeGen.
+  ///
+  /// Since this is only used for generation of debug info, it is not
+  /// serialized.
+  mutable RecordDecl *BlockDescriptorType;
+
+  /// \brief Type for the Block descriptor for Blocks CodeGen.
+  ///
+  /// Since this is only used for generation of debug info, it is not
+  /// serialized.
+  mutable RecordDecl *BlockDescriptorExtendedType;
+
+  /// \brief Declaration for the CUDA cudaConfigureCall function.
+  FunctionDecl *cudaConfigureCallDecl;
+
+  TypeSourceInfo NullTypeSourceInfo;
+
+  /// \brief Keeps track of all declaration attributes.
+  ///
+  /// Since so few decls have attrs, we keep them in a hash map instead of
+  /// wasting space in the Decl class.
+  llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;
+
+  /// \brief A mapping from non-redeclarable declarations in modules that were
+  /// merged with other declarations to the canonical declaration that they were
+  /// merged into.
+  llvm::DenseMap<Decl*, Decl*> MergedDecls;
+
+public:
+  /// \brief A type synonym for the TemplateOrInstantiation mapping.
+  typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
+  TemplateOrSpecializationInfo;
+
+private:
+
+  /// \brief A mapping to contain the template or declaration that
+  /// a variable declaration describes or was instantiated from,
+  /// respectively.
+  ///
+  /// For non-templates, this value will be NULL. For variable
+  /// declarations that describe a variable template, this will be a
+  /// pointer to a VarTemplateDecl. For static data members
+  /// of class template specializations, this will be the
+  /// MemberSpecializationInfo referring to the member variable that was
+  /// instantiated or specialized. Thus, the mapping will keep track of
+  /// the static data member templates from which static data members of
+  /// class template specializations were instantiated.
+  ///
+  /// Given the following example:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   static T value;
+  /// };
+  ///
+  /// template<typename T>
+  ///   T X<T>::value = T(17);
+  ///
+  /// int *x = &X<int>::value;
+  /// \endcode
+  ///
+  /// This mapping will contain an entry that maps from the VarDecl for
+  /// X<int>::value to the corresponding VarDecl for X<T>::value (within the
+  /// class template X) and will be marked TSK_ImplicitInstantiation.
+  llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
+  TemplateOrInstantiation;
+
+  /// \brief Keeps track of the declaration from which a UsingDecl was
+  /// created during instantiation.
+  ///
+  /// The source declaration is always a UsingDecl, an UnresolvedUsingValueDecl,
+  /// or an UnresolvedUsingTypenameDecl.
+  ///
+  /// For example:
+  /// \code
+  /// template<typename T>
+  /// struct A {
+  ///   void f();
+  /// };
+  ///
+  /// template<typename T>
+  /// struct B : A<T> {
+  ///   using A<T>::f;
+  /// };
+  ///
+  /// template struct B<int>;
+  /// \endcode
+  ///
+  /// This mapping will contain an entry that maps from the UsingDecl in
+  /// B<int> to the UnresolvedUsingDecl in B<T>.
+  llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
+
+  llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
+    InstantiatedFromUsingShadowDecl;
+
+  llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
+
+  /// \brief Mapping that stores the methods overridden by a given C++
+  /// member function.
+  ///
+  /// Since most C++ member functions aren't virtual and therefore
+  /// don't override anything, we store the overridden functions in
+  /// this map on the side rather than within the CXXMethodDecl structure.
+  typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
+  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
+
+  /// \brief Mapping from each declaration context to its corresponding
+  /// mangling numbering context (used for constructs like lambdas which
+  /// need to be consistently numbered for the mangler).
+  llvm::DenseMap<const DeclContext *, MangleNumberingContext *>
+      MangleNumberingContexts;
+
+  /// \brief Side-table of mangling numbers for declarations which rarely
+  /// need them (like static local vars).
+  llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
+  llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
+
+  /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
+  /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
+  typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable;
+  ParameterIndexTable ParamIndices;  
+  
+  ImportDecl *FirstLocalImport;
+  ImportDecl *LastLocalImport;
+  
+  TranslationUnitDecl *TUDecl;
+
+  /// \brief The associated SourceManager object.a
+  SourceManager &SourceMgr;
+
+  /// \brief The language options used to create the AST associated with
+  ///  this ASTContext object.
+  LangOptions &LangOpts;
+
+  /// \brief The allocator used to create AST objects.
+  ///
+  /// AST objects are never destructed; rather, all memory associated with the
+  /// AST objects will be released when the ASTContext itself is destroyed.
+  mutable llvm::BumpPtrAllocator BumpAlloc;
+
+  /// \brief Allocator for partial diagnostics.
+  PartialDiagnostic::StorageAllocator DiagAllocator;
+
+  /// \brief The current C++ ABI.
+  std::unique_ptr<CXXABI> ABI;
+  CXXABI *createCXXABI(const TargetInfo &T);
+
+  /// \brief The logical -> physical address space map.
+  const LangAS::Map *AddrSpaceMap;
+
+  /// \brief Address space map mangling must be used with language specific 
+  /// address spaces (e.g. OpenCL/CUDA)
+  bool AddrSpaceMapMangling;
+
+  friend class ASTDeclReader;
+  friend class ASTReader;
+  friend class ASTWriter;
+  friend class CXXRecordDecl;
+
+  const TargetInfo *Target;
+  clang::PrintingPolicy PrintingPolicy;
+  
+public:
+  IdentifierTable &Idents;
+  SelectorTable &Selectors;
+  Builtin::Context &BuiltinInfo;
+  mutable DeclarationNameTable DeclarationNames;
+  IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
+  ASTMutationListener *Listener;
+
+  /// \brief Contains parents of a node.
+  typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
+
+  /// \brief Maps from a node to its parents.
+  typedef llvm::DenseMap<const void *,
+                         llvm::PointerUnion<ast_type_traits::DynTypedNode *,
+                                            ParentVector *>> ParentMap;
+
+  /// \brief Returns the parents of the given node.
+  ///
+  /// Note that this will lazily compute the parents of all nodes
+  /// and store them for later retrieval. Thus, the first call is O(n)
+  /// in the number of AST nodes.
+  ///
+  /// Caveats and FIXMEs:
+  /// Calculating the parent map over all AST nodes will need to load the
+  /// full AST. This can be undesirable in the case where the full AST is
+  /// expensive to create (for example, when using precompiled header
+  /// preambles). Thus, there are good opportunities for optimization here.
+  /// One idea is to walk the given node downwards, looking for references
+  /// to declaration contexts - once a declaration context is found, compute
+  /// the parent map for the declaration context; if that can satisfy the
+  /// request, loading the whole AST can be avoided. Note that this is made
+  /// more complex by statements in templates having multiple parents - those
+  /// problems can be solved by building closure over the templated parts of
+  /// the AST, which also avoids touching large parts of the AST.
+  /// Additionally, we will want to add an interface to already give a hint
+  /// where to search for the parents, for example when looking at a statement
+  /// inside a certain function.
+  ///
+  /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc,
+  /// NestedNameSpecifier or NestedNameSpecifierLoc.
+  template <typename NodeT>
+  ParentVector getParents(const NodeT &Node) {
+    return getParents(ast_type_traits::DynTypedNode::create(Node));
+  }
+
+  ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
+
+  const clang::PrintingPolicy &getPrintingPolicy() const {
+    return PrintingPolicy;
+  }
+
+  void setPrintingPolicy(const clang::PrintingPolicy &Policy) {
+    PrintingPolicy = Policy;
+  }
+  
+  SourceManager& getSourceManager() { return SourceMgr; }
+  const SourceManager& getSourceManager() const { return SourceMgr; }
+
+  llvm::BumpPtrAllocator &getAllocator() const {
+    return BumpAlloc;
+  }
+
+  void *Allocate(size_t Size, unsigned Align = 8) const {
+    return BumpAlloc.Allocate(Size, Align);
+  }
+  void Deallocate(void *Ptr) const { }
+  
+  /// Return the total amount of physical memory allocated for representing
+  /// AST nodes and type information.
+  size_t getASTAllocatedMemory() const {
+    return BumpAlloc.getTotalMemory();
+  }
+  /// Return the total memory used for various side tables.
+  size_t getSideTableAllocatedMemory() const;
+  
+  PartialDiagnostic::StorageAllocator &getDiagAllocator() {
+    return DiagAllocator;
+  }
+
+  const TargetInfo &getTargetInfo() const { return *Target; }
+  
+  /// getIntTypeForBitwidth -
+  /// sets integer QualTy according to specified details:
+  /// bitwidth, signed/unsigned.
+  /// Returns empty type if there is no appropriate target types.
+  QualType getIntTypeForBitwidth(unsigned DestWidth,
+                                 unsigned Signed) const;
+  /// getRealTypeForBitwidth -
+  /// sets floating point QualTy according to specified bitwidth.
+  /// Returns empty type if there is no appropriate target types.
+  QualType getRealTypeForBitwidth(unsigned DestWidth) const;
+
+  bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
+  
+  const LangOptions& getLangOpts() const { return LangOpts; }
+
+  DiagnosticsEngine &getDiagnostics() const;
+
+  FullSourceLoc getFullLoc(SourceLocation Loc) const {
+    return FullSourceLoc(Loc,SourceMgr);
+  }
+
+  /// \brief All comments in this translation unit.
+  RawCommentList Comments;
+
+  /// \brief True if comments are already loaded from ExternalASTSource.
+  mutable bool CommentsLoaded;
+
+  class RawCommentAndCacheFlags {
+  public:
+    enum Kind {
+      /// We searched for a comment attached to the particular declaration, but
+      /// didn't find any.
+      ///
+      /// getRaw() == 0.
+      NoCommentInDecl = 0,
+
+      /// We have found a comment attached to this particular declaration.
+      ///
+      /// getRaw() != 0.
+      FromDecl,
+
+      /// This declaration does not have an attached comment, and we have
+      /// searched the redeclaration chain.
+      ///
+      /// If getRaw() == 0, the whole redeclaration chain does not have any
+      /// comments.
+      ///
+      /// If getRaw() != 0, it is a comment propagated from other
+      /// redeclaration.
+      FromRedecl
+    };
+
+    Kind getKind() const LLVM_READONLY {
+      return Data.getInt();
+    }
+
+    void setKind(Kind K) {
+      Data.setInt(K);
+    }
+
+    const RawComment *getRaw() const LLVM_READONLY {
+      return Data.getPointer();
+    }
+
+    void setRaw(const RawComment *RC) {
+      Data.setPointer(RC);
+    }
+
+    const Decl *getOriginalDecl() const LLVM_READONLY {
+      return OriginalDecl;
+    }
+
+    void setOriginalDecl(const Decl *Orig) {
+      OriginalDecl = Orig;
+    }
+
+  private:
+    llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
+    const Decl *OriginalDecl;
+  };
+
+  /// \brief Mapping from declarations to comments attached to any
+  /// redeclaration.
+  ///
+  /// Raw comments are owned by Comments list.  This mapping is populated
+  /// lazily.
+  mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
+
+  /// \brief Mapping from declarations to parsed comments attached to any
+  /// redeclaration.
+  mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
+
+  /// \brief Return the documentation comment attached to a given declaration,
+  /// without looking into cache.
+  RawComment *getRawCommentForDeclNoCache(const Decl *D) const;
+
+public:
+  RawCommentList &getRawCommentList() {
+    return Comments;
+  }
+
+  void addComment(const RawComment &RC) {
+    assert(LangOpts.RetainCommentsFromSystemHeaders ||
+           !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin()));
+    Comments.addComment(RC, BumpAlloc);
+  }
+
+  /// \brief Return the documentation comment attached to a given declaration.
+  /// Returns NULL if no comment is attached.
+  ///
+  /// \param OriginalDecl if not NULL, is set to declaration AST node that had
+  /// the comment, if the comment we found comes from a redeclaration.
+  const RawComment *
+  getRawCommentForAnyRedecl(const Decl *D,
+                            const Decl **OriginalDecl = nullptr) const;
+
+  /// Return parsed documentation comment attached to a given declaration.
+  /// Returns NULL if no comment is attached.
+  ///
+  /// \param PP the Preprocessor used with this TU.  Could be NULL if
+  /// preprocessor is not available.
+  comments::FullComment *getCommentForDecl(const Decl *D,
+                                           const Preprocessor *PP) const;
+
+  /// Return parsed documentation comment attached to a given declaration.
+  /// Returns NULL if no comment is attached. Does not look at any
+  /// redeclarations of the declaration.
+  comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
+
+  comments::FullComment *cloneFullComment(comments::FullComment *FC,
+                                         const Decl *D) const;
+
+private:
+  mutable comments::CommandTraits CommentCommandTraits;
+
+  /// \brief Iterator that visits import declarations.
+  class import_iterator {
+    ImportDecl *Import;
+
+  public:
+    typedef ImportDecl               *value_type;
+    typedef ImportDecl               *reference;
+    typedef ImportDecl               *pointer;
+    typedef int                       difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    import_iterator() : Import() {}
+    explicit import_iterator(ImportDecl *Import) : Import(Import) {}
+
+    reference operator*() const { return Import; }
+    pointer operator->() const { return Import; }
+
+    import_iterator &operator++() {
+      Import = ASTContext::getNextLocalImport(Import);
+      return *this;
+    }
+
+    import_iterator operator++(int) {
+      import_iterator Other(*this);
+      ++(*this);
+      return Other;
+    }
+
+    friend bool operator==(import_iterator X, import_iterator Y) {
+      return X.Import == Y.Import;
+    }
+
+    friend bool operator!=(import_iterator X, import_iterator Y) {
+      return X.Import != Y.Import;
+    }
+  };
+
+public:
+  comments::CommandTraits &getCommentCommandTraits() const {
+    return CommentCommandTraits;
+  }
+
+  /// \brief Retrieve the attributes for the given declaration.
+  AttrVec& getDeclAttrs(const Decl *D);
+
+  /// \brief Erase the attributes corresponding to the given declaration.
+  void eraseDeclAttrs(const Decl *D);
+
+  /// \brief If this variable is an instantiated static data member of a
+  /// class template specialization, returns the templated static data member
+  /// from which it was instantiated.
+  // FIXME: Remove ?
+  MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
+                                                           const VarDecl *Var);
+
+  TemplateOrSpecializationInfo
+  getTemplateOrSpecializationInfo(const VarDecl *Var);
+
+  FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);
+
+  void setClassScopeSpecializationPattern(FunctionDecl *FD,
+                                          FunctionDecl *Pattern);
+
+  /// \brief Note that the static data member \p Inst is an instantiation of
+  /// the static data member template \p Tmpl of a class template.
+  void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
+                                           TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  void setTemplateOrSpecializationInfo(VarDecl *Inst,
+                                       TemplateOrSpecializationInfo TSI);
+
+  /// \brief If the given using decl \p Inst is an instantiation of a
+  /// (possibly unresolved) using decl from a template instantiation,
+  /// return it.
+  NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
+
+  /// \brief Remember that the using decl \p Inst is an instantiation
+  /// of the using decl \p Pattern of a class template.
+  void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
+
+  void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
+                                          UsingShadowDecl *Pattern);
+  UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
+
+  FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
+
+  void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
+  
+  // Access to the set of methods overridden by the given C++ method.
+  typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
+  overridden_cxx_method_iterator
+  overridden_methods_begin(const CXXMethodDecl *Method) const;
+
+  overridden_cxx_method_iterator
+  overridden_methods_end(const CXXMethodDecl *Method) const;
+
+  unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
+
+  /// \brief Note that the given C++ \p Method overrides the given \p
+  /// Overridden method.
+  void addOverriddenMethod(const CXXMethodDecl *Method, 
+                           const CXXMethodDecl *Overridden);
+
+  /// \brief Return C++ or ObjC overridden methods for the given \p Method.
+  ///
+  /// An ObjC method is considered to override any method in the class's
+  /// base classes, its protocols, or its categories' protocols, that has
+  /// the same selector and is of the same kind (class or instance).
+  /// A method in an implementation is not considered as overriding the same
+  /// method in the interface or its categories.
+  void getOverriddenMethods(
+                        const NamedDecl *Method,
+                        SmallVectorImpl<const NamedDecl *> &Overridden) const;
+  
+  /// \brief Notify the AST context that a new import declaration has been
+  /// parsed or implicitly created within this translation unit.
+  void addedLocalImportDecl(ImportDecl *Import);
+
+  static ImportDecl *getNextLocalImport(ImportDecl *Import) {
+    return Import->NextLocalImport;
+  }
+  
+  typedef llvm::iterator_range<import_iterator> import_range;
+  import_range local_imports() const {
+    return import_range(import_iterator(FirstLocalImport), import_iterator());
+  }
+
+  Decl *getPrimaryMergedDecl(Decl *D) {
+    Decl *Result = MergedDecls.lookup(D);
+    return Result ? Result : D;
+  }
+  void setPrimaryMergedDecl(Decl *D, Decl *Primary) {
+    MergedDecls[D] = Primary;
+  }
+
+  TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
+
+
+  // Builtin Types.
+  CanQualType VoidTy;
+  CanQualType BoolTy;
+  CanQualType CharTy;
+  CanQualType WCharTy;  // [C++ 3.9.1p5].
+  CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
+  CanQualType WIntTy;   // [C99 7.24.1], integer type unchanged by default promotions.
+  CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
+  CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
+  CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
+  CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
+  CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
+  CanQualType FloatTy, DoubleTy, LongDoubleTy;
+  CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
+  CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+  CanQualType VoidPtrTy, NullPtrTy;
+  CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
+  CanQualType BuiltinFnTy;
+  CanQualType PseudoObjectTy, ARCUnbridgedCastTy;
+  CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
+  CanQualType ObjCBuiltinBoolTy;
+  CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy;
+  CanQualType OCLImage2dTy, OCLImage2dArrayTy;
+  CanQualType OCLImage3dTy;
+  CanQualType OCLSamplerTy, OCLEventTy;
+
+  // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
+  mutable QualType AutoDeductTy;     // Deduction against 'auto'.
+  mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
+
+  // Type used to help define __builtin_va_list for some targets.
+  // The type is built when constructing 'BuiltinVaListDecl'.
+  mutable QualType VaListTagTy;
+
+  ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
+             SelectorTable &sels, Builtin::Context &builtins);
+
+  ~ASTContext();
+
+  /// \brief Attach an external AST source to the AST context.
+  ///
+  /// The external AST source provides the ability to load parts of
+  /// the abstract syntax tree as needed from some external storage,
+  /// e.g., a precompiled header.
+  void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);
+
+  /// \brief Retrieve a pointer to the external AST source associated
+  /// with this AST context, if any.
+  ExternalASTSource *getExternalSource() const {
+    return ExternalSource.get();
+  }
+
+  /// \brief Attach an AST mutation listener to the AST context.
+  ///
+  /// The AST mutation listener provides the ability to track modifications to
+  /// the abstract syntax tree entities committed after they were initially
+  /// created.
+  void setASTMutationListener(ASTMutationListener *Listener) {
+    this->Listener = Listener;
+  }
+
+  /// \brief Retrieve a pointer to the AST mutation listener associated
+  /// with this AST context, if any.
+  ASTMutationListener *getASTMutationListener() const { return Listener; }
+
+  void PrintStats() const;
+  const SmallVectorImpl<Type *>& getTypes() const { return Types; }
+
+  /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
+  /// declaration.
+  RecordDecl *buildImplicitRecord(StringRef Name,
+                                  RecordDecl::TagKind TK = TTK_Struct) const;
+
+  /// \brief Create a new implicit TU-level typedef declaration.
+  TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
+
+  /// \brief Retrieve the declaration for the 128-bit signed integer type.
+  TypedefDecl *getInt128Decl() const;
+
+  /// \brief Retrieve the declaration for the 128-bit unsigned integer type.
+  TypedefDecl *getUInt128Decl() const;
+
+  /// \brief Retrieve the declaration for a 128-bit float stub type.
+  TypeDecl *getFloat128StubType() const;
+
+  //===--------------------------------------------------------------------===//
+  //                           Type Constructors
+  //===--------------------------------------------------------------------===//
+
+private:
+  /// \brief Return a type with extended qualifiers.
+  QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
+
+  QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
+
+public:
+  /// \brief Return the uniqued reference to the type for an address space
+  /// qualified type with the specified type and address space.
+  ///
+  /// The resulting type has a union of the qualifiers from T and the address
+  /// space. If T already has an address space specifier, it is silently
+  /// replaced.
+  QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
+
+  /// \brief Return the uniqued reference to the type for an Objective-C
+  /// gc-qualified type.
+  ///
+  /// The retulting type has a union of the qualifiers from T and the gc
+  /// attribute.
+  QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const;
+
+  /// \brief Return the uniqued reference to the type for a \c restrict
+  /// qualified type.
+  ///
+  /// The resulting type has a union of the qualifiers from \p T and
+  /// \c restrict.
+  QualType getRestrictType(QualType T) const {
+    return T.withFastQualifiers(Qualifiers::Restrict);
+  }
+
+  /// \brief Return the uniqued reference to the type for a \c volatile
+  /// qualified type.
+  ///
+  /// The resulting type has a union of the qualifiers from \p T and
+  /// \c volatile.
+  QualType getVolatileType(QualType T) const {
+    return T.withFastQualifiers(Qualifiers::Volatile);
+  }
+
+  /// \brief Return the uniqued reference to the type for a \c const
+  /// qualified type.
+  ///
+  /// The resulting type has a union of the qualifiers from \p T and \c const.
+  ///
+  /// It can be reasonably expected that this will always be equivalent to
+  /// calling T.withConst().
+  QualType getConstType(QualType T) const { return T.withConst(); }
+
+  /// \brief Change the ExtInfo on a function type.
+  const FunctionType *adjustFunctionType(const FunctionType *Fn,
+                                         FunctionType::ExtInfo EInfo);
+
+  /// \brief Change the result type of a function type once it is deduced.
+  void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+
+  /// \brief Return the uniqued reference to the type for a complex
+  /// number with the specified element type.
+  QualType getComplexType(QualType T) const;
+  CanQualType getComplexType(CanQualType T) const {
+    return CanQualType::CreateUnsafe(getComplexType((QualType) T));
+  }
+
+  /// \brief Return the uniqued reference to the type for a pointer to
+  /// the specified type.
+  QualType getPointerType(QualType T) const;
+  CanQualType getPointerType(CanQualType T) const {
+    return CanQualType::CreateUnsafe(getPointerType((QualType) T));
+  }
+
+  /// \brief Return the uniqued reference to a type adjusted from the original
+  /// type to a new type.
+  QualType getAdjustedType(QualType Orig, QualType New) const;
+  CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
+    return CanQualType::CreateUnsafe(
+        getAdjustedType((QualType)Orig, (QualType)New));
+  }
+
+  /// \brief Return the uniqued reference to the decayed version of the given
+  /// type.  Can only be called on array and function types which decay to
+  /// pointer types.
+  QualType getDecayedType(QualType T) const;
+  CanQualType getDecayedType(CanQualType T) const {
+    return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
+  }
+
+  /// \brief Return the uniqued reference to the atomic type for the specified
+  /// type.
+  QualType getAtomicType(QualType T) const;
+
+  /// \brief Return the uniqued reference to the type for a block of the
+  /// specified type.
+  QualType getBlockPointerType(QualType T) const;
+
+  /// Gets the struct used to keep track of the descriptor for pointer to
+  /// blocks.
+  QualType getBlockDescriptorType() const;
+
+  /// Gets the struct used to keep track of the extended descriptor for
+  /// pointer to blocks.
+  QualType getBlockDescriptorExtendedType() const;
+
+  void setcudaConfigureCallDecl(FunctionDecl *FD) {
+    cudaConfigureCallDecl = FD;
+  }
+  FunctionDecl *getcudaConfigureCallDecl() {
+    return cudaConfigureCallDecl;
+  }
+
+  /// Returns true iff we need copy/dispose helpers for the given type.
+  bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
+  
+  
+  /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
+  /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
+  /// has extended lifetime. 
+  bool getByrefLifetime(QualType Ty,
+                        Qualifiers::ObjCLifetime &Lifetime,
+                        bool &HasByrefExtendedLayout) const;
+  
+  /// \brief Return the uniqued reference to the type for an lvalue reference
+  /// to the specified type.
+  QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true)
+    const;
+
+  /// \brief Return the uniqued reference to the type for an rvalue reference
+  /// to the specified type.
+  QualType getRValueReferenceType(QualType T) const;
+
+  /// \brief Return the uniqued reference to the type for a member pointer to
+  /// the specified type in the specified class.
+  ///
+  /// The class \p Cls is a \c Type because it could be a dependent name.
+  QualType getMemberPointerType(QualType T, const Type *Cls) const;
+
+  /// \brief Return a non-unique reference to the type for a variable array of
+  /// the specified element type.
+  QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned IndexTypeQuals,
+                                SourceRange Brackets) const;
+
+  /// \brief Return a non-unique reference to the type for a dependently-sized
+  /// array of the specified element type.
+  ///
+  /// FIXME: We will need these to be uniqued, or at least comparable, at some
+  /// point.
+  QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
+                                      ArrayType::ArraySizeModifier ASM,
+                                      unsigned IndexTypeQuals,
+                                      SourceRange Brackets) const;
+
+  /// \brief Return a unique reference to the type for an incomplete array of
+  /// the specified element type.
+  QualType getIncompleteArrayType(QualType EltTy,
+                                  ArrayType::ArraySizeModifier ASM,
+                                  unsigned IndexTypeQuals) const;
+
+  /// \brief Return the unique reference to the type for a constant array of
+  /// the specified element type.
+  QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
+                                ArrayType::ArraySizeModifier ASM,
+                                unsigned IndexTypeQuals) const;
+  
+  /// \brief Returns a vla type where known sizes are replaced with [*].
+  QualType getVariableArrayDecayedType(QualType Ty) const;
+
+  /// \brief Return the unique reference to a vector type of the specified
+  /// element type and size.
+  ///
+  /// \pre \p VectorType must be a built-in type.
+  QualType getVectorType(QualType VectorType, unsigned NumElts,
+                         VectorType::VectorKind VecKind) const;
+
+  /// \brief Return the unique reference to an extended vector type
+  /// of the specified element type and size.
+  ///
+  /// \pre \p VectorType must be a built-in type.
+  QualType getExtVectorType(QualType VectorType, unsigned NumElts) const;
+
+  /// \pre Return a non-unique reference to the type for a dependently-sized
+  /// vector of the specified element type.
+  ///
+  /// FIXME: We will need these to be uniqued, or at least comparable, at some
+  /// point.
+  QualType getDependentSizedExtVectorType(QualType VectorType,
+                                          Expr *SizeExpr,
+                                          SourceLocation AttrLoc) const;
+
+  /// \brief Return a K&R style C function type like 'int()'.
+  QualType getFunctionNoProtoType(QualType ResultTy,
+                                  const FunctionType::ExtInfo &Info) const;
+
+  QualType getFunctionNoProtoType(QualType ResultTy) const {
+    return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
+  }
+
+  /// \brief Return a normal function type with a typed argument list.
+  QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
+                           const FunctionProtoType::ExtProtoInfo &EPI) const;
+
+  /// \brief Return the unique reference to the type for the specified type
+  /// declaration.
+  QualType getTypeDeclType(const TypeDecl *Decl,
+                           const TypeDecl *PrevDecl = nullptr) const {
+    assert(Decl && "Passed null for Decl param");
+    if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+    if (PrevDecl) {
+      assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+      Decl->TypeForDecl = PrevDecl->TypeForDecl;
+      return QualType(PrevDecl->TypeForDecl, 0);
+    }
+
+    return getTypeDeclTypeSlow(Decl);
+  }
+
+  /// \brief Return the unique reference to the type for the specified
+  /// typedef-name decl.
+  QualType getTypedefType(const TypedefNameDecl *Decl,
+                          QualType Canon = QualType()) const;
+
+  QualType getRecordType(const RecordDecl *Decl) const;
+
+  QualType getEnumType(const EnumDecl *Decl) const;
+
+  QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
+
+  QualType getAttributedType(AttributedType::Kind attrKind,
+                             QualType modifiedType,
+                             QualType equivalentType);
+
+  QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
+                                        QualType Replacement) const;
+  QualType getSubstTemplateTypeParmPackType(
+                                          const TemplateTypeParmType *Replaced,
+                                            const TemplateArgument &ArgPack);
+
+  QualType
+  getTemplateTypeParmType(unsigned Depth, unsigned Index,
+                          bool ParameterPack,
+                          TemplateTypeParmDecl *ParmDecl = nullptr) const;
+
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgument *Args,
+                                         unsigned NumArgs,
+                                         QualType Canon = QualType()) const;
+
+  QualType getCanonicalTemplateSpecializationType(TemplateName T,
+                                                  const TemplateArgument *Args,
+                                                  unsigned NumArgs) const;
+
+  QualType getTemplateSpecializationType(TemplateName T,
+                                         const TemplateArgumentListInfo &Args,
+                                         QualType Canon = QualType()) const;
+
+  TypeSourceInfo *
+  getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
+                                    const TemplateArgumentListInfo &Args,
+                                    QualType Canon = QualType()) const;
+
+  QualType getParenType(QualType NamedType) const;
+
+  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             NestedNameSpecifier *NNS,
+                             QualType NamedType) const;
+  QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+                                NestedNameSpecifier *NNS,
+                                const IdentifierInfo *Name,
+                                QualType Canon = QualType()) const;
+
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                    const TemplateArgumentListInfo &Args) const;
+  QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                                  NestedNameSpecifier *NNS,
+                                                  const IdentifierInfo *Name,
+                                                  unsigned NumArgs,
+                                            const TemplateArgument *Args) const;
+
+  QualType getPackExpansionType(QualType Pattern,
+                                Optional<unsigned> NumExpansions);
+
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                ObjCInterfaceDecl *PrevDecl = nullptr) const;
+
+  QualType getObjCObjectType(QualType Base,
+                             ObjCProtocolDecl * const *Protocols,
+                             unsigned NumProtocols) const;
+  
+  bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+  /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+  /// QT's qualified-id protocol list adopt all protocols in IDecl's list
+  /// of protocols.
+  bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+                                            ObjCInterfaceDecl *IDecl);
+
+  /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
+  QualType getObjCObjectPointerType(QualType OIT) const;
+
+  /// \brief GCC extension.
+  QualType getTypeOfExprType(Expr *e) const;
+  QualType getTypeOfType(QualType t) const;
+
+  /// \brief C++11 decltype.
+  QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
+
+  /// \brief Unary type transforms
+  QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
+                                 UnaryTransformType::UTTKind UKind) const;
+
+  /// \brief C++11 deduced auto type.
+  QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto,
+                       bool IsDependent) const;
+
+  /// \brief C++11 deduction pattern for 'auto' type.
+  QualType getAutoDeductType() const;
+
+  /// \brief C++11 deduction pattern for 'auto &&' type.
+  QualType getAutoRRefDeductType() const;
+
+  /// \brief Return the unique reference to the type for the specified TagDecl
+  /// (struct/union/class/enum) decl.
+  QualType getTagDeclType(const TagDecl *Decl) const;
+
+  /// \brief Return the unique type for "size_t" (C99 7.17), defined in
+  /// <stddef.h>.
+  ///
+  /// The sizeof operator requires this (C99 6.5.3.4p4).
+  CanQualType getSizeType() const;
+
+  /// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
+  /// <stdint.h>.
+  CanQualType getIntMaxType() const;
+
+  /// \brief Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in
+  /// <stdint.h>.
+  CanQualType getUIntMaxType() const;
+
+  /// \brief Return the unique wchar_t type available in C++ (and available as
+  /// __wchar_t as a Microsoft extension).
+  QualType getWCharType() const { return WCharTy; }
+
+  /// \brief Return the type of wide characters. In C++, this returns the
+  /// unique wchar_t type. In C99, this returns a type compatible with the type
+  /// defined in <stddef.h> as defined by the target.
+  QualType getWideCharType() const { return WideCharTy; }
+
+  /// \brief Return the type of "signed wchar_t".
+  ///
+  /// Used when in C++, as a GCC extension.
+  QualType getSignedWCharType() const;
+
+  /// \brief Return the type of "unsigned wchar_t".
+  ///
+  /// Used when in C++, as a GCC extension.
+  QualType getUnsignedWCharType() const;
+
+  /// \brief In C99, this returns a type compatible with the type
+  /// defined in <stddef.h> as defined by the target.
+  QualType getWIntType() const { return WIntTy; }
+
+  /// \brief Return a type compatible with "intptr_t" (C99 7.18.1.4),
+  /// as defined by the target.
+  QualType getIntPtrType() const;
+
+  /// \brief Return a type compatible with "uintptr_t" (C99 7.18.1.4),
+  /// as defined by the target.
+  QualType getUIntPtrType() const;
+
+  /// \brief Return the unique type for "ptrdiff_t" (C99 7.17) defined in
+  /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
+  QualType getPointerDiffType() const;
+
+  /// \brief Return the unique type for "pid_t" defined in
+  /// <sys/types.h>. We need this to compute the correct type for vfork().
+  QualType getProcessIDType() const;
+
+  /// \brief Return the C structure type used to represent constant CFStrings.
+  QualType getCFConstantStringType() const;
+  
+  /// \brief Returns the C struct type for objc_super
+  QualType getObjCSuperType() const;
+  void setObjCSuperType(QualType ST) { ObjCSuperType = ST; }
+  
+  /// Get the structure type used to representation CFStrings, or NULL
+  /// if it hasn't yet been built.
+  QualType getRawCFConstantStringType() const {
+    if (CFConstantStringTypeDecl)
+      return getTagDeclType(CFConstantStringTypeDecl);
+    return QualType();
+  }
+  void setCFConstantStringType(QualType T);
+
+  // This setter/getter represents the ObjC type for an NSConstantString.
+  void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
+  QualType getObjCConstantStringInterface() const {
+    return ObjCConstantStringType;
+  }
+
+  QualType getObjCNSStringType() const {
+    return ObjCNSStringType;
+  }
+  
+  void setObjCNSStringType(QualType T) {
+    ObjCNSStringType = T;
+  }
+  
+  /// \brief Retrieve the type that \c id has been defined to, which may be
+  /// different from the built-in \c id if \c id has been typedef'd.
+  QualType getObjCIdRedefinitionType() const {
+    if (ObjCIdRedefinitionType.isNull())
+      return getObjCIdType();
+    return ObjCIdRedefinitionType;
+  }
+  
+  /// \brief Set the user-written type that redefines \c id.
+  void setObjCIdRedefinitionType(QualType RedefType) {
+    ObjCIdRedefinitionType = RedefType;
+  }
+
+  /// \brief Retrieve the type that \c Class has been defined to, which may be
+  /// different from the built-in \c Class if \c Class has been typedef'd.
+  QualType getObjCClassRedefinitionType() const {
+    if (ObjCClassRedefinitionType.isNull())
+      return getObjCClassType();
+    return ObjCClassRedefinitionType;
+  }
+  
+  /// \brief Set the user-written type that redefines 'SEL'.
+  void setObjCClassRedefinitionType(QualType RedefType) {
+    ObjCClassRedefinitionType = RedefType;
+  }
+
+  /// \brief Retrieve the type that 'SEL' has been defined to, which may be
+  /// different from the built-in 'SEL' if 'SEL' has been typedef'd.
+  QualType getObjCSelRedefinitionType() const {
+    if (ObjCSelRedefinitionType.isNull())
+      return getObjCSelType();
+    return ObjCSelRedefinitionType;
+  }
+
+  
+  /// \brief Set the user-written type that redefines 'SEL'.
+  void setObjCSelRedefinitionType(QualType RedefType) {
+    ObjCSelRedefinitionType = RedefType;
+  }
+
+  /// \brief Retrieve the Objective-C "instancetype" type, if already known;
+  /// otherwise, returns a NULL type;
+  QualType getObjCInstanceType() {
+    return getTypeDeclType(getObjCInstanceTypeDecl());
+  }
+
+  /// \brief Retrieve the typedef declaration corresponding to the Objective-C
+  /// "instancetype" type.
+  TypedefDecl *getObjCInstanceTypeDecl();
+  
+  /// \brief Set the type for the C FILE type.
+  void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
+
+  /// \brief Retrieve the C FILE type.
+  QualType getFILEType() const {
+    if (FILEDecl)
+      return getTypeDeclType(FILEDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C jmp_buf type.
+  void setjmp_bufDecl(TypeDecl *jmp_bufDecl) {
+    this->jmp_bufDecl = jmp_bufDecl;
+  }
+
+  /// \brief Retrieve the C jmp_buf type.
+  QualType getjmp_bufType() const {
+    if (jmp_bufDecl)
+      return getTypeDeclType(jmp_bufDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C sigjmp_buf type.
+  void setsigjmp_bufDecl(TypeDecl *sigjmp_bufDecl) {
+    this->sigjmp_bufDecl = sigjmp_bufDecl;
+  }
+
+  /// \brief Retrieve the C sigjmp_buf type.
+  QualType getsigjmp_bufType() const {
+    if (sigjmp_bufDecl)
+      return getTypeDeclType(sigjmp_bufDecl);
+    return QualType();
+  }
+
+  /// \brief Set the type for the C ucontext_t type.
+  void setucontext_tDecl(TypeDecl *ucontext_tDecl) {
+    this->ucontext_tDecl = ucontext_tDecl;
+  }
+
+  /// \brief Retrieve the C ucontext_t type.
+  QualType getucontext_tType() const {
+    if (ucontext_tDecl)
+      return getTypeDeclType(ucontext_tDecl);
+    return QualType();
+  }
+
+  /// \brief The result type of logical operations, '<', '>', '!=', etc.
+  QualType getLogicalOperationType() const {
+    return getLangOpts().CPlusPlus ? BoolTy : IntTy;
+  }
+
+  /// \brief Emit the Objective-CC type encoding for the given type \p T into
+  /// \p S.
+  ///
+  /// If \p Field is specified then record field names are also encoded.
+  void getObjCEncodingForType(QualType T, std::string &S,
+                              const FieldDecl *Field=nullptr) const;
+
+  /// \brief Emit the Objective-C property type encoding for the given
+  /// type \p T into \p S.
+  void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
+
+  void getLegacyIntegralTypeEncoding(QualType &t) const;
+
+  /// \brief Put the string version of the type qualifiers \p QT into \p S.
+  void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
+                                       std::string &S) const;
+
+  /// \brief Emit the encoded type for the function \p Decl into \p S.
+  ///
+  /// This is in the same format as Objective-C method encodings.
+  ///
+  /// \returns true if an error occurred (e.g., because one of the parameter
+  /// types is incomplete), false otherwise.
+  bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
+
+  /// \brief Emit the encoded type for the method declaration \p Decl into
+  /// \p S.
+  ///
+  /// \returns true if an error occurred (e.g., because one of the parameter
+  /// types is incomplete), false otherwise.
+  bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S,
+                                    bool Extended = false)
+    const;
+
+  /// \brief Return the encoded type for this block declaration.
+  std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const;
+  
+  /// getObjCEncodingForPropertyDecl - Return the encoded type for
+  /// this method declaration. If non-NULL, Container must be either
+  /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
+  /// only be NULL when getting encodings for protocol properties.
+  void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
+                                      const Decl *Container,
+                                      std::string &S) const;
+
+  bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
+                                      ObjCProtocolDecl *rProto) const;
+  
+  ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
+                                                  const ObjCPropertyDecl *PD,
+                                                  const Decl *Container) const;
+
+  /// \brief Return the size of type \p T for Objective-C encoding purpose,
+  /// in characters.
+  CharUnits getObjCEncodingTypeSize(QualType T) const;
+
+  /// \brief Retrieve the typedef corresponding to the predefined \c id type
+  /// in Objective-C.
+  TypedefDecl *getObjCIdDecl() const;
+  
+  /// \brief Represents the Objective-CC \c id type.
+  ///
+  /// This is set up lazily, by Sema.  \c id is always a (typedef for a)
+  /// pointer type, a pointer to a struct.
+  QualType getObjCIdType() const {
+    return getTypeDeclType(getObjCIdDecl());
+  }
+
+  /// \brief Retrieve the typedef corresponding to the predefined 'SEL' type
+  /// in Objective-C.
+  TypedefDecl *getObjCSelDecl() const;
+  
+  /// \brief Retrieve the type that corresponds to the predefined Objective-C
+  /// 'SEL' type.
+  QualType getObjCSelType() const { 
+    return getTypeDeclType(getObjCSelDecl());
+  }
+
+  /// \brief Retrieve the typedef declaration corresponding to the predefined
+  /// Objective-C 'Class' type.
+  TypedefDecl *getObjCClassDecl() const;
+  
+  /// \brief Represents the Objective-C \c Class type.
+  ///
+  /// This is set up lazily, by Sema.  \c Class is always a (typedef for a)
+  /// pointer type, a pointer to a struct.
+  QualType getObjCClassType() const { 
+    return getTypeDeclType(getObjCClassDecl());
+  }
+
+  /// \brief Retrieve the Objective-C class declaration corresponding to 
+  /// the predefined \c Protocol class.
+  ObjCInterfaceDecl *getObjCProtocolDecl() const;
+
+  /// \brief Retrieve declaration of 'BOOL' typedef
+  TypedefDecl *getBOOLDecl() const {
+    return BOOLDecl;
+  }
+
+  /// \brief Save declaration of 'BOOL' typedef
+  void setBOOLDecl(TypedefDecl *TD) {
+    BOOLDecl = TD;
+  }
+
+  /// \brief type of 'BOOL' type.
+  QualType getBOOLType() const {
+    return getTypeDeclType(getBOOLDecl());
+  }
+  
+  /// \brief Retrieve the type of the Objective-C \c Protocol class.
+  QualType getObjCProtoType() const {
+    return getObjCInterfaceType(getObjCProtocolDecl());
+  }
+  
+  /// \brief Retrieve the C type declaration corresponding to the predefined
+  /// \c __builtin_va_list type.
+  TypedefDecl *getBuiltinVaListDecl() const;
+
+  /// \brief Retrieve the type of the \c __builtin_va_list type.
+  QualType getBuiltinVaListType() const {
+    return getTypeDeclType(getBuiltinVaListDecl());
+  }
+
+  /// \brief Retrieve the C type declaration corresponding to the predefined
+  /// \c __va_list_tag type used to help define the \c __builtin_va_list type
+  /// for some targets.
+  QualType getVaListTagType() const;
+
+  /// \brief Return a type with additional \c const, \c volatile, or
+  /// \c restrict qualifiers.
+  QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
+    return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
+  }
+
+  /// \brief Un-split a SplitQualType.
+  QualType getQualifiedType(SplitQualType split) const {
+    return getQualifiedType(split.Ty, split.Quals);
+  }
+
+  /// \brief Return a type with additional qualifiers.
+  QualType getQualifiedType(QualType T, Qualifiers Qs) const {
+    if (!Qs.hasNonFastQualifiers())
+      return T.withFastQualifiers(Qs.getFastQualifiers());
+    QualifierCollector Qc(Qs);
+    const Type *Ptr = Qc.strip(T);
+    return getExtQualType(Ptr, Qc);
+  }
+
+  /// \brief Return a type with additional qualifiers.
+  QualType getQualifiedType(const Type *T, Qualifiers Qs) const {
+    if (!Qs.hasNonFastQualifiers())
+      return QualType(T, Qs.getFastQualifiers());
+    return getExtQualType(T, Qs);
+  }
+
+  /// \brief Return a type with the given lifetime qualifier.
+  ///
+  /// \pre Neither type.ObjCLifetime() nor \p lifetime may be \c OCL_None.
+  QualType getLifetimeQualifiedType(QualType type,
+                                    Qualifiers::ObjCLifetime lifetime) {
+    assert(type.getObjCLifetime() == Qualifiers::OCL_None);
+    assert(lifetime != Qualifiers::OCL_None);
+
+    Qualifiers qs;
+    qs.addObjCLifetime(lifetime);
+    return getQualifiedType(type, qs);
+  }
+  
+  /// getUnqualifiedObjCPointerType - Returns version of
+  /// Objective-C pointer type with lifetime qualifier removed.
+  QualType getUnqualifiedObjCPointerType(QualType type) const {
+    if (!type.getTypePtr()->isObjCObjectPointerType() ||
+        !type.getQualifiers().hasObjCLifetime())
+      return type;
+    Qualifiers Qs = type.getQualifiers();
+    Qs.removeObjCLifetime();
+    return getQualifiedType(type.getUnqualifiedType(), Qs);
+  }
+  
+  DeclarationNameInfo getNameForTemplate(TemplateName Name,
+                                         SourceLocation NameLoc) const;
+
+  TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin,
+                                         UnresolvedSetIterator End) const;
+
+  TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
+                                        bool TemplateKeyword,
+                                        TemplateDecl *Template) const;
+
+  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+                                        const IdentifierInfo *Name) const;
+  TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+                                        OverloadedOperatorKind Operator) const;
+  TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
+                                            TemplateName replacement) const;
+  TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
+                                        const TemplateArgument &ArgPack) const;
+  
+  enum GetBuiltinTypeError {
+    GE_None,              ///< No error
+    GE_Missing_stdio,     ///< Missing a type from <stdio.h>
+    GE_Missing_setjmp,    ///< Missing a type from <setjmp.h>
+    GE_Missing_ucontext   ///< Missing a type from <ucontext.h>
+  };
+
+  /// \brief Return the type for the specified builtin.
+  ///
+  /// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
+  /// arguments to the builtin that are required to be integer constant
+  /// expressions.
+  QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
+                          unsigned *IntegerConstantArgs = nullptr) const;
+
+private:
+  CanQualType getFromTargetType(unsigned Type) const;
+  std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
+
+  //===--------------------------------------------------------------------===//
+  //                         Type Predicates.
+  //===--------------------------------------------------------------------===//
+
+public:
+  /// \brief Return one of the GCNone, Weak or Strong Objective-C garbage
+  /// collection attributes.
+  Qualifiers::GC getObjCGCAttrKind(QualType Ty) const;
+
+  /// \brief Return true if the given vector types are of the same unqualified
+  /// type or if they are equivalent to the same GCC vector type.
+  ///
+  /// \note This ignores whether they are target-specific (AltiVec or Neon)
+  /// types.
+  bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
+
+  /// \brief Return true if this is an \c NSObject object with its \c NSObject
+  /// attribute set.
+  static bool isObjCNSObjectType(QualType Ty) {
+    return Ty->isObjCNSObjectType();
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                         Type Sizing and Analysis
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the APFloat 'semantics' for the specified scalar floating
+  /// point type.
+  const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
+
+  /// \brief Get the size and alignment of the specified complete type in bits.
+  std::pair<uint64_t, unsigned> getTypeInfo(const Type *T) const;
+  std::pair<uint64_t, unsigned> getTypeInfo(QualType T) const {
+    return getTypeInfo(T.getTypePtr());
+  }
+
+  /// \brief Return the size of the specified (complete) type \p T, in bits.
+  uint64_t getTypeSize(QualType T) const {
+    return getTypeInfo(T).first;
+  }
+  uint64_t getTypeSize(const Type *T) const {
+    return getTypeInfo(T).first;
+  }
+
+  /// \brief Return the size of the character type, in bits.
+  uint64_t getCharWidth() const {
+    return getTypeSize(CharTy);
+  }
+  
+  /// \brief Convert a size in bits to a size in characters.
+  CharUnits toCharUnitsFromBits(int64_t BitSize) const;
+
+  /// \brief Convert a size in characters to a size in bits.
+  int64_t toBits(CharUnits CharSize) const;
+
+  /// \brief Return the size of the specified (complete) type \p T, in
+  /// characters.
+  CharUnits getTypeSizeInChars(QualType T) const;
+  CharUnits getTypeSizeInChars(const Type *T) const;
+
+  /// \brief Return the ABI-specified alignment of a (complete) type \p T, in
+  /// bits.
+  unsigned getTypeAlign(QualType T) const {
+    return getTypeInfo(T).second;
+  }
+  unsigned getTypeAlign(const Type *T) const {
+    return getTypeInfo(T).second;
+  }
+
+  /// \brief Return the ABI-specified alignment of a (complete) type \p T, in 
+  /// characters.
+  CharUnits getTypeAlignInChars(QualType T) const;
+  CharUnits getTypeAlignInChars(const Type *T) const;
+  
+  // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
+  // type is a record, its data size is returned.
+  std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
+
+  std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
+  std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
+
+  /// \brief Return the "preferred" alignment of the specified type \p T for
+  /// the current target, in bits.
+  ///
+  /// This can be different than the ABI alignment in cases where it is
+  /// beneficial for performance to overalign a data type.
+  unsigned getPreferredTypeAlign(const Type *T) const;
+
+  /// \brief Return the alignment in bits that should be given to a
+  /// global variable with type \p T.
+  unsigned getAlignOfGlobalVar(QualType T) const;
+
+  /// \brief Return the alignment in characters that should be given to a
+  /// global variable with type \p T.
+  CharUnits getAlignOfGlobalVarInChars(QualType T) const;
+
+  /// \brief Return a conservative estimate of the alignment of the specified
+  /// decl \p D.
+  ///
+  /// \pre \p D must not be a bitfield type, as bitfields do not have a valid
+  /// alignment.
+  ///
+  /// If \p ForAlignof, references are treated like their underlying type
+  /// and  large arrays don't get any special treatment. If not \p ForAlignof
+  /// it computes the value expected by CodeGen: references are treated like
+  /// pointers and large arrays get extra alignment.
+  CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
+
+  /// \brief Get or compute information about the layout of the specified
+  /// record (struct/union/class) \p D, which indicates its size and field
+  /// position information.
+  const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
+  const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const;
+
+  /// \brief Get or compute information about the layout of the specified
+  /// Objective-C interface.
+  const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D)
+    const;
+
+  void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
+                        bool Simple = false) const;
+
+  /// \brief Get or compute information about the layout of the specified
+  /// Objective-C implementation.
+  ///
+  /// This may differ from the interface if synthesized ivars are present.
+  const ASTRecordLayout &
+  getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
+
+  /// \brief Get our current best idea for the key function of the
+  /// given record decl, or NULL if there isn't one.
+  ///
+  /// The key function is, according to the Itanium C++ ABI section 5.2.3:
+  ///   ...the first non-pure virtual function that is not inline at the
+  ///   point of class definition.
+  ///
+  /// Other ABIs use the same idea.  However, the ARM C++ ABI ignores
+  /// virtual functions that are defined 'inline', which means that
+  /// the result of this computation can change.
+  const CXXMethodDecl *getCurrentKeyFunction(const CXXRecordDecl *RD);
+
+  /// \brief Observe that the given method cannot be a key function.
+  /// Checks the key-function cache for the method's class and clears it
+  /// if matches the given declaration.
+  ///
+  /// This is used in ABIs where out-of-line definitions marked
+  /// inline are not considered to be key functions.
+  ///
+  /// \param method should be the declaration from the class definition
+  void setNonKeyFunction(const CXXMethodDecl *method);
+
+  /// Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
+  uint64_t getFieldOffset(const ValueDecl *FD) const;
+
+  bool isNearlyEmpty(const CXXRecordDecl *RD) const;
+
+  VTableContextBase *getVTableContext();
+
+  MangleContext *createMangleContext();
+  
+  void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
+                            SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
+  
+  unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const;
+  void CollectInheritedProtocols(const Decl *CDecl,
+                          llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
+
+  //===--------------------------------------------------------------------===//
+  //                            Type Operators
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the canonical (structural) type corresponding to the
+  /// specified potentially non-canonical type \p T.
+  ///
+  /// The non-canonical version of a type may have many "decorated" versions of
+  /// types.  Decorators can include typedefs, 'typeof' operators, etc. The
+  /// returned type is guaranteed to be free of any of these, allowing two
+  /// canonical types to be compared for exact equality with a simple pointer
+  /// comparison.
+  CanQualType getCanonicalType(QualType T) const {
+    return CanQualType::CreateUnsafe(T.getCanonicalType());
+  }
+
+  const Type *getCanonicalType(const Type *T) const {
+    return T->getCanonicalTypeInternal().getTypePtr();
+  }
+
+  /// \brief Return the canonical parameter type corresponding to the specific
+  /// potentially non-canonical one.
+  ///
+  /// Qualifiers are stripped off, functions are turned into function
+  /// pointers, and arrays decay one level into pointers.
+  CanQualType getCanonicalParamType(QualType T) const;
+
+  /// \brief Determine whether the given types \p T1 and \p T2 are equivalent.
+  bool hasSameType(QualType T1, QualType T2) const {
+    return getCanonicalType(T1) == getCanonicalType(T2);
+  }
+
+  bool hasSameType(const Type *T1, const Type *T2) const {
+    return getCanonicalType(T1) == getCanonicalType(T2);
+  }
+
+  /// \brief Return this type as a completely-unqualified array type,
+  /// capturing the qualifiers in \p Quals.
+  ///
+  /// This will remove the minimal amount of sugaring from the types, similar
+  /// to the behavior of QualType::getUnqualifiedType().
+  ///
+  /// \param T is the qualified type, which may be an ArrayType
+  ///
+  /// \param Quals will receive the full set of qualifiers that were
+  /// applied to the array.
+  ///
+  /// \returns if this is an array type, the completely unqualified array type
+  /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
+  QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
+
+  /// \brief Determine whether the given types are equivalent after
+  /// cvr-qualifiers have been removed.
+  bool hasSameUnqualifiedType(QualType T1, QualType T2) const {
+    return getCanonicalType(T1).getTypePtr() ==
+           getCanonicalType(T2).getTypePtr();
+  }
+
+  bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
+                           const ObjCMethodDecl *MethodImp);
+  
+  bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
+  
+  /// \brief Retrieves the "canonical" nested name specifier for a
+  /// given nested name specifier.
+  ///
+  /// The canonical nested name specifier is a nested name specifier
+  /// that uniquely identifies a type or namespace within the type
+  /// system. For example, given:
+  ///
+  /// \code
+  /// namespace N {
+  ///   struct S {
+  ///     template<typename T> struct X { typename T* type; };
+  ///   };
+  /// }
+  ///
+  /// template<typename T> struct Y {
+  ///   typename N::S::X<T>::type member;
+  /// };
+  /// \endcode
+  ///
+  /// Here, the nested-name-specifier for N::S::X<T>:: will be
+  /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
+  /// by declarations in the type system and the canonical type for
+  /// the template type parameter 'T' is template-param-0-0.
+  NestedNameSpecifier *
+  getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
+
+  /// \brief Retrieves the default calling convention for the current target.
+  CallingConv getDefaultCallingConvention(bool isVariadic,
+                                          bool IsCXXMethod) const;
+
+  /// \brief Retrieves the "canonical" template name that refers to a
+  /// given template.
+  ///
+  /// The canonical template name is the simplest expression that can
+  /// be used to refer to a given template. For most templates, this
+  /// expression is just the template declaration itself. For example,
+  /// the template std::vector can be referred to via a variety of
+  /// names---std::vector, \::std::vector, vector (if vector is in
+  /// scope), etc.---but all of these names map down to the same
+  /// TemplateDecl, which is used to form the canonical template name.
+  ///
+  /// Dependent template names are more interesting. Here, the
+  /// template name could be something like T::template apply or
+  /// std::allocator<T>::template rebind, where the nested name
+  /// specifier itself is dependent. In this case, the canonical
+  /// template name uses the shortest form of the dependent
+  /// nested-name-specifier, which itself contains all canonical
+  /// types, values, and templates.
+  TemplateName getCanonicalTemplateName(TemplateName Name) const;
+
+  /// \brief Determine whether the given template names refer to the same
+  /// template.
+  bool hasSameTemplateName(TemplateName X, TemplateName Y);
+  
+  /// \brief Retrieve the "canonical" template argument.
+  ///
+  /// The canonical template argument is the simplest template argument
+  /// (which may be a type, value, expression, or declaration) that
+  /// expresses the value of the argument.
+  TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg)
+    const;
+
+  /// Type Query functions.  If the type is an instance of the specified class,
+  /// return the Type pointer for the underlying maximally pretty type.  This
+  /// is a member of ASTContext because this may need to do some amount of
+  /// canonicalization, e.g. to move type qualifiers into the element type.
+  const ArrayType *getAsArrayType(QualType T) const;
+  const ConstantArrayType *getAsConstantArrayType(QualType T) const {
+    return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
+  }
+  const VariableArrayType *getAsVariableArrayType(QualType T) const {
+    return dyn_cast_or_null<VariableArrayType>(getAsArrayType(T));
+  }
+  const IncompleteArrayType *getAsIncompleteArrayType(QualType T) const {
+    return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T));
+  }
+  const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T)
+    const {
+    return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T));
+  }
+  
+  /// \brief Return the innermost element type of an array type.
+  ///
+  /// For example, will return "int" for int[m][n]
+  QualType getBaseElementType(const ArrayType *VAT) const;
+
+  /// \brief Return the innermost element type of a type (which needn't
+  /// actually be an array type).
+  QualType getBaseElementType(QualType QT) const;
+
+  /// \brief Return number of constant array elements.
+  uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+
+  /// \brief Perform adjustment on the parameter type of a function.
+  ///
+  /// This routine adjusts the given parameter type @p T to the actual
+  /// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
+  /// C++ [dcl.fct]p3). The adjusted parameter type is returned.
+  QualType getAdjustedParameterType(QualType T) const;
+  
+  /// \brief Retrieve the parameter type as adjusted for use in the signature
+  /// of a function, decaying array and function types and removing top-level
+  /// cv-qualifiers.
+  QualType getSignatureParameterType(QualType T) const;
+  
+  /// \brief Return the properly qualified result of decaying the specified
+  /// array type to a pointer.
+  ///
+  /// This operation is non-trivial when handling typedefs etc.  The canonical
+  /// type of \p T must be an array type, this returns a pointer to a properly
+  /// qualified element of the array.
+  ///
+  /// See C99 6.7.5.3p7 and C99 6.3.2.1p3.
+  QualType getArrayDecayedType(QualType T) const;
+
+  /// \brief Return the type that \p PromotableType will promote to: C99
+  /// 6.3.1.1p2, assuming that \p PromotableType is a promotable integer type.
+  QualType getPromotedIntegerType(QualType PromotableType) const;
+
+  /// \brief Recurses in pointer/array types until it finds an Objective-C
+  /// retainable type and returns its ownership.
+  Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
+
+  /// \brief Whether this is a promotable bitfield reference according
+  /// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
+  ///
+  /// \returns the type this bit-field will promote to, or NULL if no
+  /// promotion occurs.
+  QualType isPromotableBitField(Expr *E) const;
+
+  /// \brief Return the highest ranked integer type, see C99 6.3.1.8p1. 
+  ///
+  /// If \p LHS > \p RHS, returns 1.  If \p LHS == \p RHS, returns 0.  If
+  /// \p LHS < \p RHS, return -1.
+  int getIntegerTypeOrder(QualType LHS, QualType RHS) const;
+
+  /// \brief Compare the rank of the two specified floating point types,
+  /// ignoring the domain of the type (i.e. 'double' == '_Complex double').
+  ///
+  /// If \p LHS > \p RHS, returns 1.  If \p LHS == \p RHS, returns 0.  If
+  /// \p LHS < \p RHS, return -1.
+  int getFloatingTypeOrder(QualType LHS, QualType RHS) const;
+
+  /// \brief Return a real floating point or a complex type (based on
+  /// \p typeDomain/\p typeSize).
+  ///
+  /// \param typeDomain a real floating point or complex type.
+  /// \param typeSize a real floating point or complex type.
+  QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
+                                             QualType typeDomain) const;
+
+  unsigned getTargetAddressSpace(QualType T) const {
+    return getTargetAddressSpace(T.getQualifiers());
+  }
+
+  unsigned getTargetAddressSpace(Qualifiers Q) const {
+    return getTargetAddressSpace(Q.getAddressSpace());
+  }
+
+  unsigned getTargetAddressSpace(unsigned AS) const {
+    if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
+      return AS;
+    else
+      return (*AddrSpaceMap)[AS - LangAS::Offset];
+  }
+
+  bool addressSpaceMapManglingFor(unsigned AS) const {
+    return AddrSpaceMapMangling || 
+           AS < LangAS::Offset || 
+           AS >= LangAS::Offset + LangAS::Count;
+  }
+
+private:
+  // Helper for integer ordering
+  unsigned getIntegerRank(const Type *T) const;
+
+public:
+
+  //===--------------------------------------------------------------------===//
+  //                    Type Compatibility Predicates
+  //===--------------------------------------------------------------------===//
+
+  /// Compatibility predicates used to check assignment expressions.
+  bool typesAreCompatible(QualType T1, QualType T2, 
+                          bool CompareUnqualified = false); // C99 6.2.7p1
+
+  bool propertyTypesAreCompatible(QualType, QualType); 
+  bool typesAreBlockPointerCompatible(QualType, QualType); 
+
+  bool isObjCIdType(QualType T) const {
+    return T == getObjCIdType();
+  }
+  bool isObjCClassType(QualType T) const {
+    return T == getObjCClassType();
+  }
+  bool isObjCSelType(QualType T) const {
+    return T == getObjCSelType();
+  }
+  bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
+                                         bool ForCompare);
+
+  bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS);
+  
+  // Check the safety of assignment from LHS to RHS
+  bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
+                               const ObjCObjectPointerType *RHSOPT);
+  bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
+                               const ObjCObjectType *RHS);
+  bool canAssignObjCInterfacesInBlockPointer(
+                                          const ObjCObjectPointerType *LHSOPT,
+                                          const ObjCObjectPointerType *RHSOPT,
+                                          bool BlockReturnType);
+  bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
+  QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
+                                   const ObjCObjectPointerType *RHSOPT);
+  bool canBindObjCObjectType(QualType To, QualType From);
+
+  // Functions for calculating composite types
+  QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
+                      bool Unqualified = false, bool BlockReturnType = false);
+  QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
+                              bool Unqualified = false);
+  QualType mergeFunctionParameterTypes(QualType, QualType,
+                                       bool OfBlockPointer = false,
+                                       bool Unqualified = false);
+  QualType mergeTransparentUnionType(QualType, QualType,
+                                     bool OfBlockPointer=false,
+                                     bool Unqualified = false);
+  
+  QualType mergeObjCGCQualifiers(QualType, QualType);
+    
+  bool FunctionTypesMatchOnNSConsumedAttrs(
+         const FunctionProtoType *FromFunctionType,
+         const FunctionProtoType *ToFunctionType);
+
+  void ResetObjCLayout(const ObjCContainerDecl *CD) {
+    ObjCLayouts[CD] = nullptr;
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                    Integer Predicates
+  //===--------------------------------------------------------------------===//
+
+  // The width of an integer, as defined in C99 6.2.6.2. This is the number
+  // of bits in an integer type excluding any padding bits.
+  unsigned getIntWidth(QualType T) const;
+
+  // Per C99 6.2.5p6, for every signed integer type, there is a corresponding
+  // unsigned integer type.  This method takes a signed type, and returns the
+  // corresponding unsigned integer type.
+  QualType getCorrespondingUnsignedType(QualType T) const;
+
+  //===--------------------------------------------------------------------===//
+  //                    Type Iterators.
+  //===--------------------------------------------------------------------===//
+  typedef llvm::iterator_range<SmallVectorImpl<Type *>::const_iterator>
+    type_const_range;
+
+  type_const_range types() const {
+    return type_const_range(Types.begin(), Types.end());
+  }
+
+  //===--------------------------------------------------------------------===//
+  //                    Integer Values
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Make an APSInt of the appropriate width and signedness for the
+  /// given \p Value and integer \p Type.
+  llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
+    llvm::APSInt Res(getIntWidth(Type), 
+                     !Type->isSignedIntegerOrEnumerationType());
+    Res = Value;
+    return Res;
+  }
+
+  bool isSentinelNullExpr(const Expr *E);
+
+  /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
+  /// none exists.
+  ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
+  /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
+  /// none exists.
+  ObjCCategoryImplDecl   *getObjCImplementation(ObjCCategoryDecl *D);
+
+  /// \brief Return true if there is at least one \@implementation in the TU.
+  bool AnyObjCImplementation() {
+    return !ObjCImpls.empty();
+  }
+
+  /// \brief Set the implementation of ObjCInterfaceDecl.
+  void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
+                             ObjCImplementationDecl *ImplD);
+  /// \brief Set the implementation of ObjCCategoryDecl.
+  void setObjCImplementation(ObjCCategoryDecl *CatD,
+                             ObjCCategoryImplDecl *ImplD);
+
+  /// \brief Get the duplicate declaration of a ObjCMethod in the same
+  /// interface, or null if none exists.
+  const ObjCMethodDecl *getObjCMethodRedeclaration(
+                                               const ObjCMethodDecl *MD) const {
+    return ObjCMethodRedecls.lookup(MD);
+  }
+
+  void setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
+                                  const ObjCMethodDecl *Redecl) {
+    assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration");
+    ObjCMethodRedecls[MD] = Redecl;
+  }
+
+  /// \brief Returns the Objective-C interface that \p ND belongs to if it is
+  /// an Objective-C method/property/ivar etc. that is part of an interface,
+  /// otherwise returns null.
+  const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
+  
+  /// \brief Set the copy inialization expression of a block var decl.
+  void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
+  /// \brief Get the copy initialization expression of the VarDecl \p VD, or
+  /// NULL if none exists.
+  Expr *getBlockVarCopyInits(const VarDecl* VD);
+
+  /// \brief Allocate an uninitialized TypeSourceInfo.
+  ///
+  /// The caller should initialize the memory held by TypeSourceInfo using
+  /// the TypeLoc wrappers.
+  ///
+  /// \param T the type that will be the basis for type source info. This type
+  /// should refer to how the declarator was written in source code, not to
+  /// what type semantic analysis resolved the declarator to.
+  ///
+  /// \param Size the size of the type info to create, or 0 if the size
+  /// should be calculated based on the type.
+  TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0) const;
+
+  /// \brief Allocate a TypeSourceInfo where all locations have been
+  /// initialized to a given location, which defaults to the empty
+  /// location.
+  TypeSourceInfo *
+  getTrivialTypeSourceInfo(QualType T, 
+                           SourceLocation Loc = SourceLocation()) const;
+
+  TypeSourceInfo *getNullTypeSourceInfo() { return &NullTypeSourceInfo; }
+
+  /// \brief Add a deallocation callback that will be invoked when the 
+  /// ASTContext is destroyed.
+  ///
+  /// \param Callback A callback function that will be invoked on destruction.
+  ///
+  /// \param Data Pointer data that will be provided to the callback function
+  /// when it is called.
+  void AddDeallocation(void (*Callback)(void*), void *Data);
+
+  GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
+  GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+
+  /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
+  /// lazily, only when used; this is only relevant for function or file scoped
+  /// var definitions.
+  ///
+  /// \returns true if the function/var must be CodeGen'ed/deserialized even if
+  /// it is not used.
+  bool DeclMustBeEmitted(const Decl *D);
+
+  void setManglingNumber(const NamedDecl *ND, unsigned Number);
+  unsigned getManglingNumber(const NamedDecl *ND) const;
+
+  void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
+  unsigned getStaticLocalNumber(const VarDecl *VD) const;
+
+  /// \brief Retrieve the context for computing mangling numbers in the given
+  /// DeclContext.
+  MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
+
+  MangleNumberingContext *createMangleNumberingContext() const;
+
+  /// \brief Used by ParmVarDecl to store on the side the
+  /// index of the parameter when it exceeds the size of the normal bitfield.
+  void setParameterIndex(const ParmVarDecl *D, unsigned index);
+
+  /// \brief Used by ParmVarDecl to retrieve on the side the
+  /// index of the parameter when it exceeds the size of the normal bitfield.
+  unsigned getParameterIndex(const ParmVarDecl *D) const;
+
+  /// \brief Get the storage for the constant value of a materialized temporary
+  /// of static storage duration.
+  APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
+                                         bool MayCreate);
+
+  //===--------------------------------------------------------------------===//
+  //                    Statistics
+  //===--------------------------------------------------------------------===//
+
+  /// \brief The number of implicitly-declared default constructors.
+  static unsigned NumImplicitDefaultConstructors;
+  
+  /// \brief The number of implicitly-declared default constructors for 
+  /// which declarations were built.
+  static unsigned NumImplicitDefaultConstructorsDeclared;
+
+  /// \brief The number of implicitly-declared copy constructors.
+  static unsigned NumImplicitCopyConstructors;
+  
+  /// \brief The number of implicitly-declared copy constructors for 
+  /// which declarations were built.
+  static unsigned NumImplicitCopyConstructorsDeclared;
+
+  /// \brief The number of implicitly-declared move constructors.
+  static unsigned NumImplicitMoveConstructors;
+
+  /// \brief The number of implicitly-declared move constructors for
+  /// which declarations were built.
+  static unsigned NumImplicitMoveConstructorsDeclared;
+
+  /// \brief The number of implicitly-declared copy assignment operators.
+  static unsigned NumImplicitCopyAssignmentOperators;
+  
+  /// \brief The number of implicitly-declared copy assignment operators for 
+  /// which declarations were built.
+  static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
+
+  /// \brief The number of implicitly-declared move assignment operators.
+  static unsigned NumImplicitMoveAssignmentOperators;
+  
+  /// \brief The number of implicitly-declared move assignment operators for 
+  /// which declarations were built.
+  static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
+
+  /// \brief The number of implicitly-declared destructors.
+  static unsigned NumImplicitDestructors;
+  
+  /// \brief The number of implicitly-declared destructors for which 
+  /// declarations were built.
+  static unsigned NumImplicitDestructorsDeclared;
+  
+private:
+  ASTContext(const ASTContext &) LLVM_DELETED_FUNCTION;
+  void operator=(const ASTContext &) LLVM_DELETED_FUNCTION;
+
+public:
+  /// \brief Initialize built-in types.
+  ///
+  /// This routine may only be invoked once for a given ASTContext object.
+  /// It is normally invoked after ASTContext construction.
+  ///
+  /// \param Target The target 
+  void InitBuiltinTypes(const TargetInfo &Target);
+  
+private:
+  void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
+
+  // Return the Objective-C type encoding for a given type.
+  void getObjCEncodingForTypeImpl(QualType t, std::string &S,
+                                  bool ExpandPointedToStructures,
+                                  bool ExpandStructures,
+                                  const FieldDecl *Field,
+                                  bool OutermostType = false,
+                                  bool EncodingProperty = false,
+                                  bool StructField = false,
+                                  bool EncodeBlockParameters = false,
+                                  bool EncodeClassNames = false,
+                                  bool EncodePointerToObjCTypedef = false) const;
+
+  // Adds the encoding of the structure's members.
+  void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
+                                       const FieldDecl *Field,
+                                       bool includeVBases = true) const;
+public:
+  // Adds the encoding of a method parameter or return type.
+  void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
+                                         QualType T, std::string& S,
+                                         bool Extended) const;
+
+  /// \brief Returns true if this is an inline-initialized static data member
+  /// which is treated as a definition for MSVC compatibility.
+  bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
+  
+private:
+  const ASTRecordLayout &
+  getObjCLayout(const ObjCInterfaceDecl *D,
+                const ObjCImplementationDecl *Impl) const;
+
+  /// \brief A set of deallocations that should be performed when the
+  /// ASTContext is destroyed.
+  typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> >
+    DeallocationMap;
+  DeallocationMap Deallocations;
+
+  // FIXME: This currently contains the set of StoredDeclMaps used
+  // by DeclContext objects.  This probably should not be in ASTContext,
+  // but we include it here so that ASTContext can quickly deallocate them.
+  llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
+
+  friend class DeclContext;
+  friend class DeclarationNameTable;
+  void ReleaseDeclContextMaps();
+  void ReleaseParentMapEntries();
+
+  std::unique_ptr<ParentMap> AllParents;
+
+  std::unique_ptr<VTableContextBase> VTContext;
+};
+
+/// \brief Utility function for constructing a nullary selector.
+static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(0, &II);
+}
+
+/// \brief Utility function for constructing an unary selector.
+static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(1, &II);
+}
+
+}  // end namespace clang
+
+// operator new and delete aren't allowed inside namespaces.
+
+/// @brief Placement new for using the ASTContext's allocator.
+///
+/// This placement form of operator new uses the ASTContext's allocator for
+/// obtaining memory.
+///
+/// IMPORTANT: These are also declared in clang/AST/AttrIterator.h! Any changes
+/// here need to also be made there.
+///
+/// We intentionally avoid using a nothrow specification here so that the calls
+/// to this operator will not perform a null check on the result -- the
+/// underlying allocator never returns null pointers.
+///
+/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
+/// @code
+/// // Default alignment (8)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments);
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The ASTContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, const clang::ASTContext &C,
+                          size_t Alignment) {
+  return C.Allocate(Bytes, Alignment);
+}
+/// @brief Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the ASTContext throws in the object constructor.
+inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
+  C.Deallocate(Ptr);
+}
+
+/// This placement form of operator new[] uses the ASTContext's allocator for
+/// obtaining memory.
+///
+/// We intentionally avoid using a nothrow specification here so that the calls
+/// to this operator will not perform a null check on the result -- the
+/// underlying allocator never returns null pointers.
+///
+/// Usage looks like this (assuming there's an ASTContext 'Context' in scope):
+/// @code
+/// // Default alignment (8)
+/// char *data = new (Context) char[10];
+/// // Specific alignment
+/// char *data = new (Context, 4) char[10];
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The ASTContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
+                            size_t Alignment = 8) {
+  return C.Allocate(Bytes, Alignment);
+}
+
+/// @brief Placement delete[] companion to the new[] above.
+///
+/// This operator is just a companion to the new[] above. There is no way of
+/// invoking it directly; see the new[] operator for more details. This operator
+/// is called implicitly by the compiler if a placement new[] expression using
+/// the ASTContext throws in the object constructor.
+inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
+  C.Deallocate(Ptr);
+}
+
+/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+template <typename Owner, typename T,
+          void (clang::ExternalASTSource::*Update)(Owner)>
+typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
+        const clang::ASTContext &Ctx, T Value) {
+  // Note, this is implemented here so that ExternalASTSource.h doesn't need to
+  // include ASTContext.h. We explicitly instantiate it for all relevant types
+  // in ASTContext.cpp.
+  if (auto *Source = Ctx.getExternalSource())
+    return new (Ctx) LazyData(Source, Value);
+  return Value;
+}
+
+#endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
new file mode 100644
index 0000000..484ca4c
--- /dev/null
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -0,0 +1,47 @@
+//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICAST_H
+#define LLVM_CLANG_DIAGNOSTICAST_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define ASTSTART
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_AST_DIAGNOSTICS
+    };
+  }  // end namespace diag
+  
+  /// \brief DiagnosticsEngine argument formatting function for diagnostics that
+  /// involve AST nodes.
+  ///
+  /// This function formats diagnostic arguments for various AST nodes, 
+  /// including types, declaration names, nested name specifiers, and
+  /// declaration contexts, into strings that can be printed as part of
+  /// diagnostics. It is meant to be used as the argument to
+  /// \c DiagnosticsEngine::SetArgToStringFn(), where the cookie is an \c
+  /// ASTContext pointer.
+  void FormatASTNodeDiagnosticArgument(
+      DiagnosticsEngine::ArgumentKind Kind,
+      intptr_t Val,
+      StringRef Modifier,
+      StringRef Argument,
+      ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+      SmallVectorImpl<char> &Output,
+      void *Cookie,
+      ArrayRef<intptr_t> QualTypeVals);
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
new file mode 100644
index 0000000..4f32798
--- /dev/null
+++ b/include/clang/AST/ASTFwd.h
@@ -0,0 +1,28 @@
+//===--- ASTFwd.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------===//
+///
+/// \file
+/// \brief Forward declaration of all AST node types.
+///
+//===-------------------------------------------------------------===//
+
+namespace clang {
+
+class Decl;
+#define DECL(DERIVED, BASE) class DERIVED##Decl;
+#include "clang/AST/DeclNodes.inc"
+class Stmt;
+#define STMT(DERIVED, BASE) class DERIVED;
+#include "clang/AST/StmtNodes.inc"
+class Type;
+#define TYPE(DERIVED, BASE) class DERIVED##Type;
+#include "clang/AST/TypeNodes.def"
+class CXXCtorInitializer;
+
+} // end namespace clang
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
new file mode 100644
index 0000000..a335f98
--- /dev/null
+++ b/include/clang/AST/ASTImporter.h
@@ -0,0 +1,290 @@
+//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- 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 ASTImporter class which imports AST nodes from one
+//  context into another context.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
+#define LLVM_CLANG_AST_ASTIMPORTER_H
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+  class DeclContext;
+  class DiagnosticsEngine;
+  class Expr;
+  class FileManager;
+  class IdentifierInfo;
+  class NestedNameSpecifier;
+  class Stmt;
+  class TypeSourceInfo;
+  
+  /// \brief Imports selected nodes from one AST context into another context,
+  /// merging AST nodes where appropriate.
+  class ASTImporter {
+  public:
+    typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
+    
+  private:
+    /// \brief The contexts we're importing to and from.
+    ASTContext &ToContext, &FromContext;
+    
+    /// \brief The file managers we're importing to and from.
+    FileManager &ToFileManager, &FromFileManager;
+
+    /// \brief Whether to perform a minimal import.
+    bool Minimal;
+
+    /// \brief Whether the last diagnostic came from the "from" context.
+    bool LastDiagFromFrom;
+    
+    /// \brief Mapping from the already-imported types in the "from" context
+    /// to the corresponding types in the "to" context.
+    llvm::DenseMap<const Type *, const Type *> ImportedTypes;
+    
+    /// \brief Mapping from the already-imported declarations in the "from"
+    /// context to the corresponding declarations in the "to" context.
+    llvm::DenseMap<Decl *, Decl *> ImportedDecls;
+
+    /// \brief Mapping from the already-imported statements in the "from"
+    /// context to the corresponding statements in the "to" context.
+    llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
+
+    /// \brief Mapping from the already-imported FileIDs in the "from" source
+    /// manager to the corresponding FileIDs in the "to" source manager.
+    llvm::DenseMap<FileID, FileID> ImportedFileIDs;
+    
+    /// \brief Imported, anonymous tag declarations that are missing their 
+    /// corresponding typedefs.
+    SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
+    
+    /// \brief Declaration (from, to) pairs that are known not to be equivalent
+    /// (which we have already complained about).
+    NonEquivalentDeclSet NonEquivalentDecls;
+    
+  public:
+    /// \brief Create a new AST importer.
+    ///
+    /// \param ToContext The context we'll be importing into.
+    ///
+    /// \param ToFileManager The file manager we'll be importing into.
+    ///
+    /// \param FromContext The context we'll be importing from.
+    ///
+    /// \param FromFileManager The file manager we'll be importing into.
+    ///
+    /// \param MinimalImport If true, the importer will attempt to import
+    /// as little as it can, e.g., by importing declarations as forward
+    /// declarations that can be completed at a later point.
+    ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
+                ASTContext &FromContext, FileManager &FromFileManager,
+                bool MinimalImport);
+    
+    virtual ~ASTImporter();
+    
+    /// \brief Whether the importer will perform a minimal import, creating
+    /// to-be-completed forward declarations when possible.
+    bool isMinimalImport() const { return Minimal; }
+    
+    /// \brief Import the given type from the "from" context into the "to"
+    /// context.
+    ///
+    /// \returns the equivalent type in the "to" context, or a NULL type if
+    /// an error occurred.
+    QualType Import(QualType FromT);
+
+    /// \brief Import the given type source information from the
+    /// "from" context into the "to" context.
+    ///
+    /// \returns the equivalent type source information in the "to"
+    /// context, or NULL if an error occurred.
+    TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
+
+    /// \brief Import the given declaration from the "from" context into the 
+    /// "to" context.
+    ///
+    /// \returns the equivalent declaration in the "to" context, or a NULL type 
+    /// if an error occurred.
+    Decl *Import(Decl *FromD);
+
+    /// \brief Import the given declaration context from the "from"
+    /// AST context into the "to" AST context.
+    ///
+    /// \returns the equivalent declaration context in the "to"
+    /// context, or a NULL type if an error occurred.
+    DeclContext *ImportContext(DeclContext *FromDC);
+    
+    /// \brief Import the given expression from the "from" context into the
+    /// "to" context.
+    ///
+    /// \returns the equivalent expression in the "to" context, or NULL if
+    /// an error occurred.
+    Expr *Import(Expr *FromE);
+
+    /// \brief Import the given statement from the "from" context into the
+    /// "to" context.
+    ///
+    /// \returns the equivalent statement in the "to" context, or NULL if
+    /// an error occurred.
+    Stmt *Import(Stmt *FromS);
+
+    /// \brief Import the given nested-name-specifier from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent nested-name-specifier in the "to"
+    /// context, or NULL if an error occurred.
+    NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
+
+    /// \brief Import the given nested-name-specifier from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent nested-name-specifier in the "to"
+    /// context.
+    NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
+
+    /// \brief Import the goven template name from the "from" context into the
+    /// "to" context.
+    TemplateName Import(TemplateName From);
+    
+    /// \brief Import the given source location from the "from" context into
+    /// the "to" context.
+    ///
+    /// \returns the equivalent source location in the "to" context, or an
+    /// invalid source location if an error occurred.
+    SourceLocation Import(SourceLocation FromLoc);
+
+    /// \brief Import the given source range from the "from" context into
+    /// the "to" context.
+    ///
+    /// \returns the equivalent source range in the "to" context, or an
+    /// invalid source location if an error occurred.
+    SourceRange Import(SourceRange FromRange);
+
+    /// \brief Import the given declaration name from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent declaration name in the "to" context,
+    /// or an empty declaration name if an error occurred.
+    DeclarationName Import(DeclarationName FromName);
+
+    /// \brief Import the given identifier from the "from" context
+    /// into the "to" context.
+    ///
+    /// \returns the equivalent identifier in the "to" context.
+    IdentifierInfo *Import(const IdentifierInfo *FromId);
+
+    /// \brief Import the given Objective-C selector from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent selector in the "to" context.
+    Selector Import(Selector FromSel);
+
+    /// \brief Import the given file ID from the "from" context into the 
+    /// "to" context.
+    ///
+    /// \returns the equivalent file ID in the source manager of the "to"
+    /// context.
+    FileID Import(FileID);
+    
+    /// \brief Import the definition of the given declaration, including all of
+    /// the declarations it contains.
+    ///
+    /// This routine is intended to be used 
+    void ImportDefinition(Decl *From);
+
+    /// \brief Cope with a name conflict when importing a declaration into the
+    /// given context.
+    ///
+    /// This routine is invoked whenever there is a name conflict while 
+    /// importing a declaration. The returned name will become the name of the
+    /// imported declaration. By default, the returned name is the same as the
+    /// original name, leaving the conflict unresolve such that name lookup
+    /// for this name is likely to find an ambiguity later.
+    ///
+    /// Subclasses may override this routine to resolve the conflict, e.g., by
+    /// renaming the declaration being imported.
+    ///
+    /// \param Name the name of the declaration being imported, which conflicts
+    /// with other declarations.
+    ///
+    /// \param DC the declaration context (in the "to" AST context) in which 
+    /// the name is being imported.
+    ///
+    /// \param IDNS the identifier namespace in which the name will be found.
+    ///
+    /// \param Decls the set of declarations with the same name as the
+    /// declaration being imported.
+    ///
+    /// \param NumDecls the number of conflicting declarations in \p Decls.
+    ///
+    /// \returns the name that the newly-imported declaration should have.
+    virtual DeclarationName HandleNameConflict(DeclarationName Name,
+                                               DeclContext *DC,
+                                               unsigned IDNS,
+                                               NamedDecl **Decls,
+                                               unsigned NumDecls);
+    
+    /// \brief Retrieve the context that AST nodes are being imported into.
+    ASTContext &getToContext() const { return ToContext; }
+    
+    /// \brief Retrieve the context that AST nodes are being imported from.
+    ASTContext &getFromContext() const { return FromContext; }
+    
+    /// \brief Retrieve the file manager that AST nodes are being imported into.
+    FileManager &getToFileManager() const { return ToFileManager; }
+
+    /// \brief Retrieve the file manager that AST nodes are being imported from.
+    FileManager &getFromFileManager() const { return FromFileManager; }
+    
+    /// \brief Report a diagnostic in the "to" context.
+    DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
+    
+    /// \brief Report a diagnostic in the "from" context.
+    DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
+    
+    /// \brief Return the set of declarations that we know are not equivalent.
+    NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
+
+    /// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
+    /// Mark the Decl as complete, filling it in as much as possible.
+    ///
+    /// \param D A declaration in the "to" context.
+    virtual void CompleteDecl(Decl* D);
+    
+    /// \brief Note that we have imported the "from" declaration by mapping it
+    /// to the (potentially-newly-created) "to" declaration.
+    ///
+    /// Subclasses can override this function to observe all of the \c From ->
+    /// \c To declaration mappings as they are imported.
+    virtual Decl *Imported(Decl *From, Decl *To);
+      
+    /// \brief Called by StructuralEquivalenceContext.  If a RecordDecl is
+    /// being compared to another RecordDecl as part of import, completing the
+    /// other RecordDecl may trigger importation of the first RecordDecl. This
+    /// happens especially for anonymous structs.  If the original of the second
+    /// RecordDecl can be found, we can complete it without the need for
+    /// importation, eliminating this loop.
+    virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
+    
+    /// \brief Determine whether the given types are structurally
+    /// equivalent.
+    bool IsStructurallyEquivalent(QualType From, QualType To,
+                                  bool Complain = true);
+  };
+}
+
+#endif // LLVM_CLANG_AST_ASTIMPORTER_H
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
new file mode 100644
index 0000000..9af016b
--- /dev/null
+++ b/include/clang/AST/ASTLambda.h
@@ -0,0 +1,80 @@
+//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides some common utility functions for processing
+/// Lambda related AST Constructs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDA_H
+#define LLVM_CLANG_AST_LAMBDA_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+inline StringRef getLambdaStaticInvokerName() {
+  return "__invoke";
+}
+// This function returns true if M is a specialization, a template,
+// or a non-generic lambda call operator.
+inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
+  const CXXRecordDecl *LambdaClass = MD->getParent();
+  if (!LambdaClass || !LambdaClass->isLambda()) return false;
+  return MD->getOverloadedOperator() == OO_Call;
+}
+
+inline bool isLambdaCallOperator(const DeclContext *DC) {
+  if (!DC || !isa<CXXMethodDecl>(DC)) return false;
+  return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
+}
+
+inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
+  if (!MD) return false;
+  const CXXRecordDecl *LambdaClass = MD->getParent();
+  if (LambdaClass && LambdaClass->isGenericLambda())
+    return isLambdaCallOperator(MD) && 
+                    MD->isFunctionTemplateSpecialization();
+  return false;
+}
+
+inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
+  return C ? C->getParent()->isLambda() : false;
+}
+
+inline bool isLambdaConversionOperator(Decl *D) {
+  if (!D) return false;
+  if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) 
+    return isLambdaConversionOperator(Conv);  
+  if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D)) 
+    if (CXXConversionDecl *Conv = 
+        dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl())) 
+      return isLambdaConversionOperator(Conv);
+  return false;
+}
+
+inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
+  return isGenericLambdaCallOperatorSpecialization(
+                                          dyn_cast<CXXMethodDecl>(DC));
+}
+
+
+// This returns the parent DeclContext ensuring that the correct
+// parent DeclContext is returned for Lambdas
+inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
+  if (isLambdaCallOperator(DC))
+    return DC->getParent()->getParent();
+  else 
+    return DC->getParent();
+}
+
+} // clang
+
+#endif // LLVM_CLANG_AST_LAMBDA_H
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
new file mode 100644
index 0000000..a89bfed
--- /dev/null
+++ b/include/clang/AST/ASTMutationListener.h
@@ -0,0 +1,111 @@
+//===--- ASTMutationListener.h - AST Mutation Interface --------*- 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 ASTMutationListener interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
+#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+  class CXXRecordDecl;
+  class ClassTemplateDecl;
+  class ClassTemplateSpecializationDecl;
+  class Decl;
+  class DeclContext;
+  class FunctionDecl;
+  class FunctionTemplateDecl;
+  class ObjCCategoryDecl;
+  class ObjCContainerDecl;
+  class ObjCInterfaceDecl;
+  class ObjCPropertyDecl;
+  class QualType;
+  class TagDecl;
+  class VarDecl;
+  class VarTemplateDecl;
+  class VarTemplateSpecializationDecl;
+
+/// \brief An abstract interface that should be implemented by listeners
+/// that want to be notified when an AST entity gets modified after its
+/// initial creation.
+class ASTMutationListener {
+public:
+  virtual ~ASTMutationListener();
+
+  /// \brief A new TagDecl definition was completed.
+  virtual void CompletedTagDefinition(const TagDecl *D) { }
+
+  /// \brief A new declaration with name has been added to a DeclContext.
+  virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {}
+
+  /// \brief An implicit member was added after the definition was completed.
+  virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
+
+  /// \brief A template specialization (or partial one) was added to the
+  /// template declaration.
+  virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                                    const ClassTemplateSpecializationDecl *D) {}
+
+  /// \brief A template specialization (or partial one) was added to the
+  /// template declaration.
+  virtual void
+  AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+                                 const VarTemplateSpecializationDecl *D) {}
+
+  /// \brief A template specialization (or partial one) was added to the
+  /// template declaration.
+  virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+                                              const FunctionDecl *D) {}
+
+  /// \brief A function's exception specification has been evaluated or
+  /// instantiated.
+  virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
+
+  /// \brief A function's return type has been deduced.
+  virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
+
+  /// \brief An implicit member got a definition.
+  virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
+
+  /// \brief A static data member was implicitly instantiated.
+  virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+
+  /// \brief A function template's definition was instantiated.
+  virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
+
+  /// \brief A new objc category class was added for an interface.
+  virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+                                            const ObjCInterfaceDecl *IFD) {}
+
+  /// \brief A objc class extension redeclared or introduced a property.
+  ///
+  /// \param Prop the property in the class extension
+  ///
+  /// \param OrigProp the property from the original interface that was declared
+  /// or null if the property was introduced.
+  ///
+  /// \param ClassExt the class extension.
+  virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                            const ObjCPropertyDecl *OrigProp,
+                                            const ObjCCategoryDecl *ClassExt) {}
+
+  /// \brief A declaration is marked used which was not previously marked used.
+  ///
+  /// \param D the declaration marked used
+  virtual void DeclarationMarkedUsed(const Decl *D) {}
+
+  // NOTE: If new methods are added they should also be added to
+  // MultiplexASTMutationListener.
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
new file mode 100644
index 0000000..0e06e26
--- /dev/null
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -0,0 +1,364 @@
+//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Provides a dynamic type identifier and a dynamically typed node container
+//  that can be used to store an AST base node at runtime in the same storage in
+//  a type safe way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+
+#include "clang/AST/ASTFwd.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/AlignOf.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+}
+
+namespace clang {
+
+struct PrintingPolicy;
+
+namespace ast_type_traits {
+
+/// \brief Kind identifier.
+///
+/// It can be constructed from any node kind and allows for runtime type
+/// hierarchy checks.
+/// Use getFromNodeKind<T>() to construct them.
+class ASTNodeKind {
+public:
+  /// \brief Empty identifier. It matches nothing.
+  ASTNodeKind() : KindId(NKI_None) {}
+
+  /// \brief Construct an identifier for T.
+  template <class T>
+  static ASTNodeKind getFromNodeKind() {
+    return ASTNodeKind(KindToKindId<T>::Id);
+  }
+
+  /// \brief Returns \c true if \c this and \c Other represent the same kind.
+  bool isSame(ASTNodeKind Other) const;
+
+  /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
+  /// \param Distance If non-null, used to return the distance between \c this
+  /// and \c Other in the class hierarchy.
+  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
+
+  /// \brief String representation of the kind.
+  StringRef asStringRef() const;
+
+  /// \brief Strict weak ordering for ASTNodeKind.
+  bool operator<(const ASTNodeKind &Other) const {
+    return KindId < Other.KindId;
+  }
+
+private:
+  /// \brief Kind ids.
+  ///
+  /// Includes all possible base and derived kinds.
+  enum NodeKindId {
+    NKI_None,
+    NKI_CXXCtorInitializer,
+    NKI_TemplateArgument,
+    NKI_NestedNameSpecifier,
+    NKI_NestedNameSpecifierLoc,
+    NKI_QualType,
+    NKI_TypeLoc,
+    NKI_Decl,
+#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
+#include "clang/AST/DeclNodes.inc"
+    NKI_Stmt,
+#define STMT(DERIVED, BASE) NKI_##DERIVED,
+#include "clang/AST/StmtNodes.inc"
+    NKI_Type,
+#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
+#include "clang/AST/TypeNodes.def"
+    NKI_NumberOfKinds
+  };
+
+  /// \brief Use getFromNodeKind<T>() to construct the kind.
+  ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+
+  /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
+  ///   Derived.
+  /// \param Distance If non-null, used to return the distance between \c Base
+  /// and \c Derived in the class hierarchy.
+  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
+
+  /// \brief Helper meta-function to convert a kind T to its enum value.
+  ///
+  /// This struct is specialized below for all known kinds.
+  template <class T> struct KindToKindId {
+    static const NodeKindId Id = NKI_None;
+  };
+
+  /// \brief Per kind info.
+  struct KindInfo {
+    /// \brief The id of the parent kind, or None if it has no parent.
+    NodeKindId ParentId;
+    /// \brief Name of the kind.
+    const char *Name;
+  };
+  static const KindInfo AllKindInfo[NKI_NumberOfKinds];
+
+  NodeKindId KindId;
+};
+
+#define KIND_TO_KIND_ID(Class)                                                 \
+  template <> struct ASTNodeKind::KindToKindId<Class> {                        \
+    static const NodeKindId Id = NKI_##Class;                                  \
+  };
+KIND_TO_KIND_ID(CXXCtorInitializer)
+KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(NestedNameSpecifier)
+KIND_TO_KIND_ID(NestedNameSpecifierLoc)
+KIND_TO_KIND_ID(QualType)
+KIND_TO_KIND_ID(TypeLoc)
+KIND_TO_KIND_ID(Decl)
+KIND_TO_KIND_ID(Stmt)
+KIND_TO_KIND_ID(Type)
+#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
+#include "clang/AST/DeclNodes.inc"
+#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
+#include "clang/AST/StmtNodes.inc"
+#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
+#include "clang/AST/TypeNodes.def"
+#undef KIND_TO_KIND_ID
+
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+  OS << K.asStringRef();
+  return OS;
+}
+
+/// \brief A dynamically typed AST node container.
+///
+/// Stores an AST node in a type safe way. This allows writing code that
+/// works with different kinds of AST nodes, despite the fact that they don't
+/// have a common base class.
+///
+/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
+/// and \c get<T>() to retrieve the node as type T if the types match.
+///
+/// See \c ASTNodeKind for which node base types are currently supported;
+/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
+/// the supported base types.
+class DynTypedNode {
+public:
+  /// \brief Creates a \c DynTypedNode from \c Node.
+  template <typename T>
+  static DynTypedNode create(const T &Node) {
+    return BaseConverter<T>::create(Node);
+  }
+
+  /// \brief Retrieve the stored node as type \c T.
+  ///
+  /// Returns NULL if the stored node does not have a type that is
+  /// convertible to \c T.
+  ///
+  /// For types that have identity via their pointer in the AST
+  /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
+  /// pointer points to the referenced AST node.
+  /// For other types (like \c QualType) the value is stored directly
+  /// in the \c DynTypedNode, and the returned pointer points at
+  /// the storage inside DynTypedNode. For those nodes, do not
+  /// use the pointer outside the scope of the DynTypedNode.
+  template <typename T>
+  const T *get() const {
+    return BaseConverter<T>::get(NodeKind, Storage.buffer);
+  }
+
+  /// \brief Returns a pointer that identifies the stored AST node.
+  ///
+  /// Note that this is not supported by all AST nodes. For AST nodes
+  /// that don't have a pointer-defined identity inside the AST, this
+  /// method returns NULL.
+  const void *getMemoizationData() const;
+
+  /// \brief Prints the node to the given output stream.
+  void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
+
+  /// \brief Dumps the node to the given output stream.
+  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
+
+  /// \brief For nodes which represent textual entities in the source code,
+  /// return their SourceRange.  For all other nodes, return SourceRange().
+  SourceRange getSourceRange() const;
+
+  /// @{
+  /// \brief Imposes an order on \c DynTypedNode.
+  ///
+  /// Supports comparison of nodes that support memoization.
+  /// FIXME: Implement comparsion for other node types (currently
+  /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
+  bool operator<(const DynTypedNode &Other) const {
+    assert(getMemoizationData() && Other.getMemoizationData());
+    return getMemoizationData() < Other.getMemoizationData();
+  }
+  bool operator==(const DynTypedNode &Other) const {
+    if (!NodeKind.isBaseOf(Other.NodeKind) &&
+        !Other.NodeKind.isBaseOf(NodeKind))
+      return false;
+
+    // FIXME: Implement for other types.
+    if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
+      return *get<QualType>() == *Other.get<QualType>();
+    }
+    assert(getMemoizationData() && Other.getMemoizationData());
+    return getMemoizationData() == Other.getMemoizationData();
+  }
+  bool operator!=(const DynTypedNode &Other) const {
+    return !operator==(Other);
+  }
+  /// @}
+
+private:
+  /// \brief Takes care of converting from and to \c T.
+  template <typename T, typename EnablerT = void> struct BaseConverter;
+
+  /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
+  template <typename T, typename BaseT> struct DynCastPtrConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
+        return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+      return nullptr;
+    }
+    static DynTypedNode create(const BaseT &Node) {
+      DynTypedNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) const BaseT * (&Node);
+      return Result;
+    }
+  };
+
+  /// \brief Converter that stores T* (by pointer).
+  template <typename T> struct PtrConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+        return *reinterpret_cast<T *const *>(Storage);
+      return nullptr;
+    }
+    static DynTypedNode create(const T &Node) {
+      DynTypedNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) const T * (&Node);
+      return Result;
+    }
+  };
+
+  /// \brief Converter that stores T (by value).
+  template <typename T> struct ValueConverter {
+    static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+      if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+        return reinterpret_cast<const T *>(Storage);
+      return nullptr;
+    }
+    static DynTypedNode create(const T &Node) {
+      DynTypedNode Result;
+      Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+      new (Result.Storage.buffer) T(Node);
+      return Result;
+    }
+  };
+
+  ASTNodeKind NodeKind;
+
+  /// \brief Stores the data of the node.
+  ///
+  /// Note that we can store \c Decls, \c Stmts, \c Types,
+  /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
+  /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
+  /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
+  /// \c TemplateArguments on the other hand do not have storage or unique
+  /// pointers and thus need to be stored by value.
+  typedef llvm::AlignedCharArrayUnion<
+      Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *>
+      KindsByPointer;
+  llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument,
+                              NestedNameSpecifierLoc, QualType, TypeLoc>
+      Storage;
+};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+    : public DynCastPtrConverter<T, Decl> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+    : public DynCastPtrConverter<T, Stmt> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+    : public DynCastPtrConverter<T, Type> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+    NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+    CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+    TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+    NestedNameSpecifierLoc,
+    void> : public ValueConverter<NestedNameSpecifierLoc> {};
+
+template <>
+struct DynTypedNode::BaseConverter<QualType,
+                                   void> : public ValueConverter<QualType> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+    TypeLoc, void> : public ValueConverter<TypeLoc> {};
+
+// The only operation we allow on unsupported types is \c get.
+// This allows to conveniently use \c DynTypedNode when having an arbitrary
+// AST node that is not supported, but prevents misuse - a user cannot create
+// a DynTypedNode from arbitrary types.
+template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
+  static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+    return NULL;
+  }
+};
+
+inline const void *DynTypedNode::getMemoizationData() const {
+  if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
+    return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
+    return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
+    return BaseConverter<Type>::get(NodeKind, Storage.buffer);
+  } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
+    return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
+  }
+  return nullptr;
+}
+
+} // end namespace ast_type_traits
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_AST_TYPE_TRAITS_H
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
new file mode 100644
index 0000000..84b0842
--- /dev/null
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -0,0 +1,110 @@
+//===-- ASTUnresolvedSet.h - Unresolved sets of declarations  ---*- 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 an UnresolvedSet-like class, whose contents are
+//  allocated using the allocator associated with an ASTContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
+#define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
+
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/UnresolvedSet.h"
+
+namespace clang {
+
+/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
+class ASTUnresolvedSet {
+  struct DeclsTy : ASTVector<DeclAccessPair> {
+    DeclsTy() {}
+    DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
+
+    bool isLazy() const { return getTag(); }
+    void setLazy(bool Lazy) { setTag(Lazy); }
+  };
+
+  DeclsTy Decls;
+
+  friend class LazyASTUnresolvedSet;
+
+public:
+  ASTUnresolvedSet() {}
+  ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
+
+  typedef UnresolvedSetIterator iterator;
+  typedef UnresolvedSetIterator const_iterator;
+
+  iterator begin() { return iterator(Decls.begin()); }
+  iterator end() { return iterator(Decls.end()); }
+
+  const_iterator begin() const { return const_iterator(Decls.begin()); }
+  const_iterator end() const { return const_iterator(Decls.end()); }
+
+  void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) {
+    Decls.push_back(DeclAccessPair::make(D, AS), C);
+  }
+
+  /// Replaces the given declaration with the new one, once.
+  ///
+  /// \return true if the set changed
+  bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
+    for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
+      if (I->getDecl() == Old) {
+        I->set(New, AS);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
+
+  void clear() { Decls.clear(); }
+
+  bool empty() const { return Decls.empty(); }
+  unsigned size() const { return Decls.size(); }
+
+  void reserve(ASTContext &C, unsigned N) {
+    Decls.reserve(C, N);
+  }
+
+  void append(ASTContext &C, iterator I, iterator E) {
+    Decls.append(C, I.ir, E.ir);
+  }
+
+  DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
+  const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
+};
+
+/// \brief An UnresolvedSet-like class that might not have been loaded from the
+/// external AST source yet.
+class LazyASTUnresolvedSet {
+  mutable ASTUnresolvedSet Impl;
+
+  void getFromExternalSource(ASTContext &C) const;
+
+public:
+  ASTUnresolvedSet &get(ASTContext &C) const {
+    if (Impl.Decls.isLazy())
+      getFromExternalSource(C);
+    return Impl;
+  }
+
+  void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
+  void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
+    assert(Impl.empty() || Impl.Decls.isLazy());
+    Impl.Decls.setLazy(true);
+    Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
+  }
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
new file mode 100644
index 0000000..d92167e
--- /dev/null
+++ b/include/clang/AST/ASTVector.h
@@ -0,0 +1,403 @@
+//===- ASTVector.h - Vector that uses ASTContext for allocation  --*- 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 ASTVector, a vector  ADT whose contents are
+//  allocated using the allocator associated with an ASTContext..
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
+// We can refactor this core logic into something common.
+
+#ifndef LLVM_CLANG_AST_VECTOR
+#define LLVM_CLANG_AST_VECTOR
+
+#include "clang/AST/AttrIterator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cstring>
+#include <memory>
+
+namespace clang {
+  class ASTContext;
+
+template<typename T>
+class ASTVector {
+private:
+  T *Begin, *End;
+  llvm::PointerIntPair<T*, 1, bool> Capacity;
+
+  void setEnd(T *P) { this->End = P; }
+
+protected:
+  // Make a tag bit available to users of this class.
+  // FIXME: This is a horrible hack.
+  bool getTag() const { return Capacity.getInt(); }
+  void setTag(bool B) { Capacity.setInt(B); }
+
+public:
+  // Default ctor - Initialize to empty.
+  ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+
+  ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
+    O.Begin = O.End = nullptr;
+    O.Capacity.setPointer(nullptr);
+    O.Capacity.setInt(false);
+  }
+
+  ASTVector(const ASTContext &C, unsigned N)
+      : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
+    reserve(C, N);
+  }
+
+  ASTVector &operator=(ASTVector &&RHS) {
+    ASTVector O(std::move(RHS));
+    using std::swap;
+    swap(Begin, O.Begin);
+    swap(End, O.End);
+    swap(Capacity, O.Capacity);
+    return *this;
+  }
+
+  ~ASTVector() {
+    if (std::is_class<T>::value) {
+      // Destroy the constructed elements in the vector.
+      destroy_range(Begin, End);
+    }
+  }
+
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+
+  // forward iterator creation methods.
+  iterator begin() { return Begin; }
+  const_iterator begin() const { return Begin; }
+  iterator end() { return End; }
+  const_iterator end() const { return End; }
+
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+  bool empty() const { return Begin == End; }
+  size_type size() const { return End-Begin; }
+
+  reference operator[](unsigned idx) {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  const_reference operator[](unsigned idx) const {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+
+  reference front() {
+    return begin()[0];
+  }
+  const_reference front() const {
+    return begin()[0];
+  }
+
+  reference back() {
+    return end()[-1];
+  }
+  const_reference back() const {
+    return end()[-1];
+  }
+
+  void pop_back() {
+    --End;
+    End->~T();
+  }
+
+  T pop_back_val() {
+    T Result = back();
+    pop_back();
+    return Result;
+  }
+
+  void clear() {
+    if (std::is_class<T>::value) {
+      destroy_range(Begin, End);
+    }
+    End = Begin;
+  }
+
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  pointer data() {
+    return pointer(Begin);
+  }
+
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  const_pointer data() const {
+    return const_pointer(Begin);
+  }
+
+  void push_back(const_reference Elt, const ASTContext &C) {
+    if (End < this->capacity_ptr()) {
+    Retry:
+      new (End) T(Elt);
+      ++End;
+      return;
+    }
+    grow(C);
+    goto Retry;
+  }
+
+  void reserve(const ASTContext &C, unsigned N) {
+    if (unsigned(this->capacity_ptr()-Begin) < N)
+      grow(C, N);
+  }
+
+  /// capacity - Return the total number of elements in the currently allocated
+  /// buffer.
+  size_t capacity() const { return this->capacity_ptr() - Begin; }
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  template<typename in_iter>
+  void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
+    size_type NumInputs = std::distance(in_start, in_end);
+
+    if (NumInputs == 0)
+      return;
+
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(C, this->size()+NumInputs);
+
+    // Copy the new elements over.
+    // TODO: NEED To compile time dispatch on whether in_iter is a random access
+    // iterator to use the fast uninitialized_copy.
+    std::uninitialized_copy(in_start, in_end, this->end());
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(C, this->size()+NumInputs);
+
+    // Copy the new elements over.
+    std::uninitialized_fill_n(this->end(), NumInputs, Elt);
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+  /// starting with "Dest", constructing elements into it as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+    std::uninitialized_copy(I, E, Dest);
+  }
+
+  iterator insert(const ASTContext &C, iterator I, const T &Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      push_back(Elt, C);
+      return this->end()-1;
+    }
+
+    if (this->End < this->capacity_ptr()) {
+    Retry:
+      new (this->end()) T(this->back());
+      this->setEnd(this->end()+1);
+      // Push everything else over.
+      std::copy_backward(I, this->end()-1, this->end());
+      *I = Elt;
+      return I;
+    }
+    size_t EltNo = I-this->begin();
+    this->grow(C);
+    I = this->begin()+EltNo;
+    goto Retry;
+  }
+
+  iterator insert(const ASTContext &C, iterator I, size_type NumToInsert,
+                  const T &Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(C, NumToInsert, Elt);
+      return this->end()-1;
+    }
+
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    // Ensure there is enough space.
+    reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(C, this->end()-NumToInsert, this->end());
+
+      // Copy the existing elements that get replaced.
+      std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::fill_n(I, NumToInsert, Elt);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Copy over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    std::fill_n(I, NumOverwritten, Elt);
+
+    // Insert the non-overwritten middle part.
+    std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+    return I;
+  }
+
+  template<typename ItTy>
+  iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(C, From, To);
+      return this->end()-1;
+    }
+
+    size_t NumToInsert = std::distance(From, To);
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    // Ensure there is enough space.
+    reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(C, this->end()-NumToInsert, this->end());
+
+      // Copy the existing elements that get replaced.
+      std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::copy(From, To, I);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Copy over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    for (; NumOverwritten > 0; --NumOverwritten) {
+      *I = *From;
+      ++I; ++From;
+    }
+
+    // Insert the non-overwritten middle part.
+    this->uninitialized_copy(From, To, OldEnd);
+    return I;
+  }
+
+  void resize(const ASTContext &C, unsigned N, const T &NV) {
+    if (N < this->size()) {
+      this->destroy_range(this->begin()+N, this->end());
+      this->setEnd(this->begin()+N);
+    } else if (N > this->size()) {
+      if (this->capacity() < N)
+        this->grow(C, N);
+      construct_range(this->end(), this->begin()+N, NV);
+      this->setEnd(this->begin()+N);
+    }
+  }
+
+private:
+  /// grow - double the size of the allocated memory, guaranteeing space for at
+  /// least one more element or MinSize if specified.
+  void grow(const ASTContext &C, size_type MinSize = 1);
+
+  void construct_range(T *S, T *E, const T &Elt) {
+    for (; S != E; ++S)
+      new (S) T(Elt);
+  }
+
+  void destroy_range(T *S, T *E) {
+    while (S != E) {
+      --E;
+      E->~T();
+    }
+  }
+
+protected:
+  const_iterator capacity_ptr() const {
+    return (iterator) Capacity.getPointer();
+  }
+  iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
+  size_t CurCapacity = this->capacity();
+  size_t CurSize = size();
+  size_t NewCapacity = 2*CurCapacity;
+  if (NewCapacity < MinSize)
+    NewCapacity = MinSize;
+
+  // Allocate the memory from the ASTContext.
+  T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
+
+  // Copy the elements over.
+  if (std::is_class<T>::value) {
+    std::uninitialized_copy(Begin, End, NewElts);
+    // Destroy the original elements.
+    destroy_range(Begin, End);
+  }
+  else {
+    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  }
+
+  // ASTContext never frees any memory.
+  Begin = NewElts;
+  End = NewElts+CurSize;
+  Capacity.setPointer(Begin+NewCapacity);
+}
+
+} // end: clang namespace
+#endif
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
new file mode 100644
index 0000000..fc48816
--- /dev/null
+++ b/include/clang/AST/Attr.h
@@ -0,0 +1,166 @@
+//===--- Attr.h - Classes for representing attributes ----------*- 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 Attr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTR_H
+#define LLVM_CLANG_AST_ATTR_H
+
+#include "clang/AST/AttrIterator.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+
+namespace clang {
+  class ASTContext;
+  class IdentifierInfo;
+  class ObjCInterfaceDecl;
+  class Expr;
+  class QualType;
+  class FunctionDecl;
+  class TypeSourceInfo;
+
+/// Attr - This represents one attribute.
+class Attr {
+private:
+  SourceRange Range;
+  unsigned AttrKind : 16;
+
+protected:
+  /// An index into the spelling list of an
+  /// attribute defined in Attr.td file.
+  unsigned SpellingListIndex : 4;
+  bool Inherited : 1;
+  bool IsPackExpansion : 1;
+  bool Implicit : 1;
+
+  virtual ~Attr();
+
+  void* operator new(size_t bytes) throw() {
+    llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
+  }
+  void operator delete(void* data) throw() {
+    llvm_unreachable("Attrs cannot be released with regular 'delete'.");
+  }
+
+public:
+  // Forward so that the regular new and delete do not hide global ones.
+  void* operator new(size_t Bytes, ASTContext &C,
+                     size_t Alignment = 16) throw() {
+    return ::operator new(Bytes, C, Alignment);
+  }
+  void operator delete(void *Ptr, ASTContext &C,
+                       size_t Alignment) throw() {
+    return ::operator delete(Ptr, C, Alignment);
+  }
+
+protected:
+  Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+    : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
+      Inherited(false), IsPackExpansion(false), Implicit(false) {}
+
+public:
+
+  attr::Kind getKind() const {
+    return static_cast<attr::Kind>(AttrKind);
+  }
+  
+  unsigned getSpellingListIndex() const { return SpellingListIndex; }
+  virtual const char *getSpelling() const = 0;
+
+  SourceLocation getLocation() const { return Range.getBegin(); }
+  SourceRange getRange() const { return Range; }
+  void setRange(SourceRange R) { Range = R; }
+
+  bool isInherited() const { return Inherited; }
+
+  /// \brief Returns true if the attribute has been implicitly created instead
+  /// of explicitly written by the user.
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+
+  void setPackExpansion(bool PE) { IsPackExpansion = PE; }
+  bool isPackExpansion() const { return IsPackExpansion; }
+
+  // Clone this attribute.
+  virtual Attr *clone(ASTContext &C) const = 0;
+
+  virtual bool isLateParsed() const { return false; }
+
+  // Pretty print this attribute.
+  virtual void printPretty(raw_ostream &OS,
+                           const PrintingPolicy &Policy) const = 0;
+
+  /// \brief By default, attributes cannot be duplicated when being merged;
+  /// however, an attribute can override this. Returns true if the attribute
+  /// can be duplicated when merging.
+  virtual bool duplicatesAllowed() const { return false; }
+};
+
+class InheritableAttr : public Attr {
+  virtual void anchor();
+protected:
+  InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+    : Attr(AK, R, SpellingListIndex) {}
+
+public:
+  void setInherited(bool I) { Inherited = I; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() <= attr::LAST_INHERITABLE;
+  }
+};
+
+class InheritableParamAttr : public InheritableAttr {
+  void anchor() override;
+protected:
+  InheritableParamAttr(attr::Kind AK, SourceRange R,
+                       unsigned SpellingListIndex = 0)
+    : InheritableAttr(AK, R, SpellingListIndex) {}
+
+public:
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    // Relies on relative order of enum emission with respect to MS inheritance
+    // attrs.
+    return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
+  }
+};
+
+#include "clang/AST/Attrs.inc"
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const Attr *At) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           const Attr *At) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return PD;
+}
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/AttrDump.inc b/include/clang/AST/AttrDump.inc
new file mode 100644
index 0000000..5e851ea
--- /dev/null
+++ b/include/clang/AST/AttrDump.inc
@@ -0,0 +1,1274 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute dumper                                                            *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+  switch (A->getKind()) {
+  default:
+    llvm_unreachable("Unknown attribute kind!");
+    break;
+  case attr::ARMInterrupt: {
+    const ARMInterruptAttr *SA = cast<ARMInterruptAttr>(A);
+    switch(SA->getInterrupt()) {
+    case ARMInterruptAttr::IRQ:
+      OS << " IRQ";
+      break;
+    case ARMInterruptAttr::FIQ:
+      OS << " FIQ";
+      break;
+    case ARMInterruptAttr::SWI:
+      OS << " SWI";
+      break;
+    case ARMInterruptAttr::ABORT:
+      OS << " ABORT";
+      break;
+    case ARMInterruptAttr::UNDEF:
+      OS << " UNDEF";
+      break;
+    case ARMInterruptAttr::Generic:
+      OS << " Generic";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AcquireCapability: {
+    OS << " " << A->getSpelling();
+    const AcquireCapabilityAttr *SA = cast<AcquireCapabilityAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (AcquireCapabilityAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AcquiredAfter: {
+    const AcquiredAfterAttr *SA = cast<AcquiredAfterAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (AcquiredAfterAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AcquiredBefore: {
+    const AcquiredBeforeAttr *SA = cast<AcquiredBeforeAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (AcquiredBeforeAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Alias: {
+    const AliasAttr *SA = cast<AliasAttr>(A);
+    OS << " \"" << SA->getAliasee() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AlignMac68k: {
+    break;
+  }
+  case attr::Aligned: {
+    OS << " " << A->getSpelling();
+    const AlignedAttr *SA = cast<AlignedAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    if (SA->isAlignmentExpr()) {
+      lastChild();
+      dumpStmt(SA->getAlignmentExpr());
+    } else
+      dumpType(SA->getAlignmentType()->getType());
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AlwaysInline: {
+    OS << " " << A->getSpelling();
+    break;
+  }
+  case attr::AnalyzerNoReturn: {
+    break;
+  }
+  case attr::Annotate: {
+    const AnnotateAttr *SA = cast<AnnotateAttr>(A);
+    OS << " \"" << SA->getAnnotation() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ArcWeakrefUnavailable: {
+    break;
+  }
+  case attr::ArgumentWithTypeTag: {
+    OS << " " << A->getSpelling();
+    const ArgumentWithTypeTagAttr *SA = cast<ArgumentWithTypeTagAttr>(A);
+    OS << " " << SA->getArgumentKind()->getName();
+    OS << " " << SA->getArgumentIdx();
+    OS << " " << SA->getTypeTagIdx();
+    if (SA->getIsPointer()) OS << " IsPointer";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AsmLabel: {
+    const AsmLabelAttr *SA = cast<AsmLabelAttr>(A);
+    OS << " \"" << SA->getLabel() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AssertCapability: {
+    OS << " " << A->getSpelling();
+    const AssertCapabilityAttr *SA = cast<AssertCapabilityAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getExpr());
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AssertExclusiveLock: {
+    const AssertExclusiveLockAttr *SA = cast<AssertExclusiveLockAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (AssertExclusiveLockAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::AssertSharedLock: {
+    const AssertSharedLockAttr *SA = cast<AssertSharedLockAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (AssertSharedLockAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Availability: {
+    const AvailabilityAttr *SA = cast<AvailabilityAttr>(A);
+    OS << " " << SA->getPlatform()->getName();
+    OS << " " << SA->getIntroduced();
+    OS << " " << SA->getDeprecated();
+    OS << " " << SA->getObsoleted();
+    if (SA->getUnavailable()) OS << " Unavailable";
+    OS << " \"" << SA->getMessage() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false || false || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false || false || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Blocks: {
+    const BlocksAttr *SA = cast<BlocksAttr>(A);
+    switch(SA->getType()) {
+    case BlocksAttr::ByRef:
+      OS << " ByRef";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::C11NoReturn: {
+    break;
+  }
+  case attr::CDecl: {
+    break;
+  }
+  case attr::CFAuditedTransfer: {
+    break;
+  }
+  case attr::CFConsumed: {
+    break;
+  }
+  case attr::CFReturnsNotRetained: {
+    break;
+  }
+  case attr::CFReturnsRetained: {
+    break;
+  }
+  case attr::CFUnknownTransfer: {
+    break;
+  }
+  case attr::CUDAConstant: {
+    break;
+  }
+  case attr::CUDADevice: {
+    break;
+  }
+  case attr::CUDAGlobal: {
+    break;
+  }
+  case attr::CUDAHost: {
+    break;
+  }
+  case attr::CUDALaunchBounds: {
+    const CUDALaunchBoundsAttr *SA = cast<CUDALaunchBoundsAttr>(A);
+    OS << " " << SA->getMaxThreads();
+    OS << " " << SA->getMinBlocks();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::CUDAShared: {
+    break;
+  }
+  case attr::CXX11NoReturn: {
+    break;
+  }
+  case attr::CallableWhen: {
+    const CallableWhenAttr *SA = cast<CallableWhenAttr>(A);
+    for (CallableWhenAttr::callableStates_iterator I = SA->callableStates_begin(), E = SA->callableStates_end(); I != E; ++I) {
+      switch(*I) {
+    case CallableWhenAttr::Unknown:
+      OS << " Unknown";
+      break;
+    case CallableWhenAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case CallableWhenAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+      }
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Capability: {
+    OS << " " << A->getSpelling();
+    const CapabilityAttr *SA = cast<CapabilityAttr>(A);
+    OS << " \"" << SA->getName() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::CarriesDependency: {
+    break;
+  }
+  case attr::Cleanup: {
+    const CleanupAttr *SA = cast<CleanupAttr>(A);
+    OS << " ";
+    dumpBareDeclRef(SA->getFunctionDecl());
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Cold: {
+    break;
+  }
+  case attr::Common: {
+    break;
+  }
+  case attr::Const: {
+    break;
+  }
+  case attr::Constructor: {
+    const ConstructorAttr *SA = cast<ConstructorAttr>(A);
+    OS << " " << SA->getPriority();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Consumable: {
+    const ConsumableAttr *SA = cast<ConsumableAttr>(A);
+    switch(SA->getDefaultState()) {
+    case ConsumableAttr::Unknown:
+      OS << " Unknown";
+      break;
+    case ConsumableAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case ConsumableAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ConsumableAutoCast: {
+    break;
+  }
+  case attr::ConsumableSetOnRead: {
+    break;
+  }
+  case attr::DLLExport: {
+    break;
+  }
+  case attr::DLLImport: {
+    break;
+  }
+  case attr::Deprecated: {
+    const DeprecatedAttr *SA = cast<DeprecatedAttr>(A);
+    OS << " \"" << SA->getMessage() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Destructor: {
+    const DestructorAttr *SA = cast<DestructorAttr>(A);
+    OS << " " << SA->getPriority();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::EnableIf: {
+    const EnableIfAttr *SA = cast<EnableIfAttr>(A);
+    OS << " \"" << SA->getMessage() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getCond());
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ExclusiveTrylockFunction: {
+    const ExclusiveTrylockFunctionAttr *SA = cast<ExclusiveTrylockFunctionAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || SA->args_begin() != SA->args_end();
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getSuccessValue());
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (ExclusiveTrylockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::FallThrough: {
+    break;
+  }
+  case attr::FastCall: {
+    break;
+  }
+  case attr::Final: {
+    OS << " " << A->getSpelling();
+    break;
+  }
+  case attr::Flatten: {
+    break;
+  }
+  case attr::Format: {
+    const FormatAttr *SA = cast<FormatAttr>(A);
+    OS << " " << SA->getType()->getName();
+    OS << " " << SA->getFormatIdx();
+    OS << " " << SA->getFirstArg();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::FormatArg: {
+    const FormatArgAttr *SA = cast<FormatArgAttr>(A);
+    OS << " " << SA->getFormatIdx();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::GNUInline: {
+    break;
+  }
+  case attr::GuardedBy: {
+    const GuardedByAttr *SA = cast<GuardedByAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getArg());
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::GuardedVar: {
+    break;
+  }
+  case attr::Hot: {
+    break;
+  }
+  case attr::IBAction: {
+    break;
+  }
+  case attr::IBOutlet: {
+    break;
+  }
+  case attr::IBOutletCollection: {
+    const IBOutletCollectionAttr *SA = cast<IBOutletCollectionAttr>(A);
+    OS << " " << SA->getInterface().getAsString();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::InitPriority: {
+    const InitPriorityAttr *SA = cast<InitPriorityAttr>(A);
+    OS << " " << SA->getPriority();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::InitSeg: {
+    const InitSegAttr *SA = cast<InitSegAttr>(A);
+    OS << " \"" << SA->getSection() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::IntelOclBicc: {
+    break;
+  }
+  case attr::LockReturned: {
+    const LockReturnedAttr *SA = cast<LockReturnedAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getArg());
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::LocksExcluded: {
+    const LocksExcludedAttr *SA = cast<LocksExcludedAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (LocksExcludedAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::LoopHint: {
+    OS << " " << A->getSpelling();
+    const LoopHintAttr *SA = cast<LoopHintAttr>(A);
+    switch(SA->getOption()) {
+    case LoopHintAttr::Vectorize:
+      OS << " Vectorize";
+      break;
+    case LoopHintAttr::VectorizeWidth:
+      OS << " VectorizeWidth";
+      break;
+    case LoopHintAttr::Interleave:
+      OS << " Interleave";
+      break;
+    case LoopHintAttr::InterleaveCount:
+      OS << " InterleaveCount";
+      break;
+    case LoopHintAttr::Unroll:
+      OS << " Unroll";
+      break;
+    case LoopHintAttr::UnrollCount:
+      OS << " UnrollCount";
+      break;
+    }
+    OS << " " << SA->getValue();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::MSABI: {
+    break;
+  }
+  case attr::MSInheritance: {
+    OS << " " << A->getSpelling();
+    const MSInheritanceAttr *SA = cast<MSInheritanceAttr>(A);
+    if (SA->getBestCase()) OS << " BestCase";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::MSP430Interrupt: {
+    const MSP430InterruptAttr *SA = cast<MSP430InterruptAttr>(A);
+    OS << " " << SA->getNumber();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::MSVtorDisp: {
+    const MSVtorDispAttr *SA = cast<MSVtorDispAttr>(A);
+    OS << " " << SA->getVdm();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Malloc: {
+    break;
+  }
+  case attr::MaxFieldAlignment: {
+    const MaxFieldAlignmentAttr *SA = cast<MaxFieldAlignmentAttr>(A);
+    OS << " " << SA->getAlignment();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::MayAlias: {
+    break;
+  }
+  case attr::MinSize: {
+    break;
+  }
+  case attr::Mips16: {
+    break;
+  }
+  case attr::Mode: {
+    const ModeAttr *SA = cast<ModeAttr>(A);
+    OS << " " << SA->getMode()->getName();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::MsStruct: {
+    break;
+  }
+  case attr::NSConsumed: {
+    break;
+  }
+  case attr::NSConsumesSelf: {
+    break;
+  }
+  case attr::NSReturnsAutoreleased: {
+    break;
+  }
+  case attr::NSReturnsNotRetained: {
+    break;
+  }
+  case attr::NSReturnsRetained: {
+    break;
+  }
+  case attr::Naked: {
+    break;
+  }
+  case attr::NoCommon: {
+    break;
+  }
+  case attr::NoDebug: {
+    break;
+  }
+  case attr::NoDuplicate: {
+    break;
+  }
+  case attr::NoInline: {
+    break;
+  }
+  case attr::NoInstrumentFunction: {
+    break;
+  }
+  case attr::NoMips16: {
+    break;
+  }
+  case attr::NoReturn: {
+    break;
+  }
+  case attr::NoSanitizeAddress: {
+    OS << " " << A->getSpelling();
+    break;
+  }
+  case attr::NoSanitizeMemory: {
+    break;
+  }
+  case attr::NoSanitizeThread: {
+    break;
+  }
+  case attr::NoSplitStack: {
+    break;
+  }
+  case attr::NoThreadSafetyAnalysis: {
+    break;
+  }
+  case attr::NoThrow: {
+    break;
+  }
+  case attr::NonNull: {
+    const NonNullAttr *SA = cast<NonNullAttr>(A);
+    for (const auto &Val : SA->args())
+      OS << " " << Val;
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ObjCBridge: {
+    const ObjCBridgeAttr *SA = cast<ObjCBridgeAttr>(A);
+    OS << " " << SA->getBridgedType()->getName();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ObjCBridgeMutable: {
+    const ObjCBridgeMutableAttr *SA = cast<ObjCBridgeMutableAttr>(A);
+    OS << " " << SA->getBridgedType()->getName();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ObjCBridgeRelated: {
+    const ObjCBridgeRelatedAttr *SA = cast<ObjCBridgeRelatedAttr>(A);
+    OS << " " << SA->getRelatedClass()->getName();
+    OS << " " << SA->getClassMethod()->getName();
+    OS << " " << SA->getInstanceMethod()->getName();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ObjCDesignatedInitializer: {
+    break;
+  }
+  case attr::ObjCException: {
+    break;
+  }
+  case attr::ObjCExplicitProtocolImpl: {
+    break;
+  }
+  case attr::ObjCMethodFamily: {
+    const ObjCMethodFamilyAttr *SA = cast<ObjCMethodFamilyAttr>(A);
+    switch(SA->getFamily()) {
+    case ObjCMethodFamilyAttr::OMF_None:
+      OS << " OMF_None";
+      break;
+    case ObjCMethodFamilyAttr::OMF_alloc:
+      OS << " OMF_alloc";
+      break;
+    case ObjCMethodFamilyAttr::OMF_copy:
+      OS << " OMF_copy";
+      break;
+    case ObjCMethodFamilyAttr::OMF_init:
+      OS << " OMF_init";
+      break;
+    case ObjCMethodFamilyAttr::OMF_mutableCopy:
+      OS << " OMF_mutableCopy";
+      break;
+    case ObjCMethodFamilyAttr::OMF_new:
+      OS << " OMF_new";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ObjCNSObject: {
+    break;
+  }
+  case attr::ObjCPreciseLifetime: {
+    break;
+  }
+  case attr::ObjCRequiresPropertyDefs: {
+    break;
+  }
+  case attr::ObjCRequiresSuper: {
+    break;
+  }
+  case attr::ObjCReturnsInnerPointer: {
+    break;
+  }
+  case attr::ObjCRootClass: {
+    break;
+  }
+  case attr::ObjCRuntimeName: {
+    const ObjCRuntimeNameAttr *SA = cast<ObjCRuntimeNameAttr>(A);
+    OS << " \"" << SA->getMetadataName() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::OpenCLImageAccess: {
+    OS << " " << A->getSpelling();
+    break;
+  }
+  case attr::OpenCLKernel: {
+    break;
+  }
+  case attr::OptimizeNone: {
+    break;
+  }
+  case attr::Overloadable: {
+    break;
+  }
+  case attr::Override: {
+    break;
+  }
+  case attr::Ownership: {
+    OS << " " << A->getSpelling();
+    const OwnershipAttr *SA = cast<OwnershipAttr>(A);
+    OS << " " << SA->getModule()->getName();
+    for (const auto &Val : SA->args())
+      OS << " " << Val;
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Packed: {
+    break;
+  }
+  case attr::ParamTypestate: {
+    const ParamTypestateAttr *SA = cast<ParamTypestateAttr>(A);
+    switch(SA->getParamState()) {
+    case ParamTypestateAttr::Unknown:
+      OS << " Unknown";
+      break;
+    case ParamTypestateAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case ParamTypestateAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Pascal: {
+    break;
+  }
+  case attr::Pcs: {
+    const PcsAttr *SA = cast<PcsAttr>(A);
+    switch(SA->getPCS()) {
+    case PcsAttr::AAPCS:
+      OS << " AAPCS";
+      break;
+    case PcsAttr::AAPCS_VFP:
+      OS << " AAPCS_VFP";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::PnaclCall: {
+    break;
+  }
+  case attr::PtGuardedBy: {
+    const PtGuardedByAttr *SA = cast<PtGuardedByAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getArg());
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::PtGuardedVar: {
+    break;
+  }
+  case attr::Pure: {
+    break;
+  }
+  case attr::ReleaseCapability: {
+    OS << " " << A->getSpelling();
+    const ReleaseCapabilityAttr *SA = cast<ReleaseCapabilityAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (ReleaseCapabilityAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ReqdWorkGroupSize: {
+    const ReqdWorkGroupSizeAttr *SA = cast<ReqdWorkGroupSizeAttr>(A);
+    OS << " " << SA->getXDim();
+    OS << " " << SA->getYDim();
+    OS << " " << SA->getZDim();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::RequiresCapability: {
+    OS << " " << A->getSpelling();
+    const RequiresCapabilityAttr *SA = cast<RequiresCapabilityAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (RequiresCapabilityAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ReturnTypestate: {
+    const ReturnTypestateAttr *SA = cast<ReturnTypestateAttr>(A);
+    switch(SA->getState()) {
+    case ReturnTypestateAttr::Unknown:
+      OS << " Unknown";
+      break;
+    case ReturnTypestateAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case ReturnTypestateAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ReturnsNonNull: {
+    break;
+  }
+  case attr::ReturnsTwice: {
+    break;
+  }
+  case attr::ScopedLockable: {
+    break;
+  }
+  case attr::Section: {
+    OS << " " << A->getSpelling();
+    const SectionAttr *SA = cast<SectionAttr>(A);
+    OS << " \"" << SA->getName() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::SelectAny: {
+    break;
+  }
+  case attr::Sentinel: {
+    const SentinelAttr *SA = cast<SentinelAttr>(A);
+    OS << " " << SA->getSentinel();
+    OS << " " << SA->getNullPos();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::SetTypestate: {
+    const SetTypestateAttr *SA = cast<SetTypestateAttr>(A);
+    switch(SA->getNewState()) {
+    case SetTypestateAttr::Unknown:
+      OS << " Unknown";
+      break;
+    case SetTypestateAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case SetTypestateAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::SharedTrylockFunction: {
+    const SharedTrylockFunctionAttr *SA = cast<SharedTrylockFunctionAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || SA->args_begin() != SA->args_end();
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getSuccessValue());
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (SharedTrylockFunctionAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::StdCall: {
+    break;
+  }
+  case attr::SysVABI: {
+    break;
+  }
+  case attr::TLSModel: {
+    const TLSModelAttr *SA = cast<TLSModelAttr>(A);
+    OS << " \"" << SA->getModel() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::TestTypestate: {
+    const TestTypestateAttr *SA = cast<TestTypestateAttr>(A);
+    switch(SA->getTestState()) {
+    case TestTypestateAttr::Consumed:
+      OS << " Consumed";
+      break;
+    case TestTypestateAttr::Unconsumed:
+      OS << " Unconsumed";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::ThisCall: {
+    break;
+  }
+  case attr::Thread: {
+    break;
+  }
+  case attr::TransparentUnion: {
+    break;
+  }
+  case attr::TryAcquireCapability: {
+    OS << " " << A->getSpelling();
+    const TryAcquireCapabilityAttr *SA = cast<TryAcquireCapabilityAttr>(A);
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || SA->args_begin() != SA->args_end();
+    setMoreChildren(MoreChildren);
+    lastChild();
+    dumpStmt(SA->getSuccessValue());
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    for (TryAcquireCapabilityAttr::args_iterator I = SA->args_begin(), E = SA->args_end(); I != E; ++I) {
+      if (I + 1 == E)
+        lastChild();
+      dumpStmt(*I);
+    }
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::TypeTagForDatatype: {
+    const TypeTagForDatatypeAttr *SA = cast<TypeTagForDatatypeAttr>(A);
+    OS << " " << SA->getArgumentKind()->getName();
+    OS << " " << SA->getMatchingCType().getAsString();
+    if (SA->getLayoutCompatible()) OS << " LayoutCompatible";
+    if (SA->getMustBeNull()) OS << " MustBeNull";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::TypeVisibility: {
+    const TypeVisibilityAttr *SA = cast<TypeVisibilityAttr>(A);
+    switch(SA->getVisibility()) {
+    case TypeVisibilityAttr::Default:
+      OS << " Default";
+      break;
+    case TypeVisibilityAttr::Hidden:
+      OS << " Hidden";
+      break;
+    case TypeVisibilityAttr::Protected:
+      OS << " Protected";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Unavailable: {
+    const UnavailableAttr *SA = cast<UnavailableAttr>(A);
+    OS << " \"" << SA->getMessage() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Unused: {
+    break;
+  }
+  case attr::Used: {
+    break;
+  }
+  case attr::Uuid: {
+    const UuidAttr *SA = cast<UuidAttr>(A);
+    OS << " \"" << SA->getGuid() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::VecReturn: {
+    break;
+  }
+  case attr::VecTypeHint: {
+    const VecTypeHintAttr *SA = cast<VecTypeHintAttr>(A);
+    OS << " " << SA->getTypeHint().getAsString();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::Visibility: {
+    const VisibilityAttr *SA = cast<VisibilityAttr>(A);
+    switch(SA->getVisibility()) {
+    case VisibilityAttr::Default:
+      OS << " Default";
+      break;
+    case VisibilityAttr::Hidden:
+      OS << " Hidden";
+      break;
+    case VisibilityAttr::Protected:
+      OS << " Protected";
+      break;
+    }
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::WarnUnused: {
+    break;
+  }
+  case attr::WarnUnusedResult: {
+    break;
+  }
+  case attr::Weak: {
+    break;
+  }
+  case attr::WeakImport: {
+    break;
+  }
+  case attr::WeakRef: {
+    const WeakRefAttr *SA = cast<WeakRefAttr>(A);
+    OS << " \"" << SA->getAliasee() << "\"";
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::WorkGroupSizeHint: {
+    const WorkGroupSizeHintAttr *SA = cast<WorkGroupSizeHintAttr>(A);
+    OS << " " << SA->getXDim();
+    OS << " " << SA->getYDim();
+    OS << " " << SA->getZDim();
+    bool OldMoreChildren = hasMoreChildren();
+    bool MoreChildren;
+    MoreChildren = OldMoreChildren || false || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren || false;
+    setMoreChildren(MoreChildren);
+    MoreChildren = OldMoreChildren;
+    setMoreChildren(MoreChildren);
+    setMoreChildren(OldMoreChildren);
+    break;
+  }
+  case attr::X86ForceAlignArgPointer: {
+    break;
+  }
+  }
diff --git a/include/clang/AST/AttrImpl.inc b/include/clang/AST/AttrImpl.inc
new file mode 100644
index 0000000..071188f
--- /dev/null
+++ b/include/clang/AST/AttrImpl.inc
@@ -0,0 +1,5891 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute classes' member function definitions                              *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+ARMInterruptAttr *ARMInterruptAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ARMInterruptAttr(getLocation(), C, interrupt, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ARMInterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((interrupt(" << getInterrupt() << ")))";
+    break;
+  }
+}
+}
+
+const char *ARMInterruptAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "interrupt";
+  }
+}
+
+AcquireCapabilityAttr *AcquireCapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AcquireCapabilityAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AcquireCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((acquire_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::acquire_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((acquire_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 3 : {
+    OS << " [[clang::acquire_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 4 : {
+    OS << " __attribute__((exclusive_lock_function(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 5 : {
+    OS << " __attribute__((shared_lock_function(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AcquireCapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "acquire_capability";
+  case 1:
+    return "acquire_capability";
+  case 2:
+    return "acquire_shared_capability";
+  case 3:
+    return "acquire_shared_capability";
+  case 4:
+    return "exclusive_lock_function";
+  case 5:
+    return "shared_lock_function";
+  }
+}
+
+AcquiredAfterAttr *AcquiredAfterAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AcquiredAfterAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AcquiredAfterAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((acquired_after(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AcquiredAfterAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "acquired_after";
+  }
+}
+
+AcquiredBeforeAttr *AcquiredBeforeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AcquiredBeforeAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AcquiredBeforeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((acquired_before(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AcquiredBeforeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "acquired_before";
+  }
+}
+
+AliasAttr *AliasAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AliasAttr(getLocation(), C, getAliasee(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((alias(\"" << getAliasee() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::alias(\"" << getAliasee() << "\")]]";
+    break;
+  }
+}
+}
+
+const char *AliasAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "alias";
+  case 1:
+    return "alias";
+  }
+}
+
+AlignMac68kAttr *AlignMac68kAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AlignMac68kAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AlignMac68kAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+}
+
+const char *AlignMac68kAttr::getSpelling() const {
+  return "(No spelling)";
+}
+
+bool AlignedAttr::isAlignmentDependent() const {
+  if (isalignmentExpr)
+    return alignmentExpr && (alignmentExpr->isValueDependent() || alignmentExpr->isTypeDependent());
+  else
+    return alignmentType->getType()->isDependentType();
+}
+unsigned AlignedAttr::getAlignment(ASTContext &Ctx) const {
+  assert(!isAlignmentDependent());
+  if (isalignmentExpr)
+    return (alignmentExpr ? alignmentExpr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)* Ctx.getCharWidth();
+  else
+    return 0; // FIXME
+}
+AlignedAttr *AlignedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AlignedAttr(getLocation(), C, isalignmentExpr, isalignmentExpr ? static_cast<void*>(alignmentExpr) : alignmentType, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AlignedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((aligned(";
+    assert(isalignmentExpr && alignmentExpr != nullptr);
+    alignmentExpr->printPretty(OS, 0, Policy);
+    OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::aligned(";
+    assert(isalignmentExpr && alignmentExpr != nullptr);
+    alignmentExpr->printPretty(OS, 0, Policy);
+    OS << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(align(";
+    assert(isalignmentExpr && alignmentExpr != nullptr);
+    alignmentExpr->printPretty(OS, 0, Policy);
+    OS << "))";
+    break;
+  }
+  case 3 : {
+    OS << " alignas(";
+    assert(isalignmentExpr && alignmentExpr != nullptr);
+    alignmentExpr->printPretty(OS, 0, Policy);
+    OS << ")";
+    break;
+  }
+  case 4 : {
+    OS << " _Alignas(";
+    assert(isalignmentExpr && alignmentExpr != nullptr);
+    alignmentExpr->printPretty(OS, 0, Policy);
+    OS << ")";
+    break;
+  }
+}
+}
+
+const char *AlignedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "aligned";
+  case 1:
+    return "aligned";
+  case 2:
+    return "align";
+  case 3:
+    return "alignas";
+  case 4:
+    return "_Alignas";
+  }
+}
+
+AlwaysInlineAttr *AlwaysInlineAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AlwaysInlineAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AlwaysInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((always_inline))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::always_inline]]";
+    break;
+  }
+  case 2 : {
+    OS << " __forceinline";
+    break;
+  }
+}
+}
+
+const char *AlwaysInlineAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "always_inline";
+  case 1:
+    return "always_inline";
+  case 2:
+    return "__forceinline";
+  }
+}
+
+AnalyzerNoReturnAttr *AnalyzerNoReturnAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AnalyzerNoReturnAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AnalyzerNoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((analyzer_noreturn))";
+    break;
+  }
+}
+}
+
+const char *AnalyzerNoReturnAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "analyzer_noreturn";
+  }
+}
+
+AnnotateAttr *AnnotateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AnnotateAttr(getLocation(), C, getAnnotation(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AnnotateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((annotate(\"" << getAnnotation() << "\")))";
+    break;
+  }
+}
+}
+
+const char *AnnotateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "annotate";
+  }
+}
+
+ArcWeakrefUnavailableAttr *ArcWeakrefUnavailableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ArcWeakrefUnavailableAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ArcWeakrefUnavailableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_arc_weak_reference_unavailable))";
+    break;
+  }
+}
+}
+
+const char *ArcWeakrefUnavailableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_arc_weak_reference_unavailable";
+  }
+}
+
+ArgumentWithTypeTagAttr *ArgumentWithTypeTagAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ArgumentWithTypeTagAttr(getLocation(), C, argumentKind, argumentIdx, typeTagIdx, isPointer, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ArgumentWithTypeTagAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((argument_with_type_tag(" << getArgumentKind()->getName() << ", " << getArgumentIdx() << ", " << getTypeTagIdx() << ", " << getIsPointer() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " __attribute__((pointer_with_type_tag(" << getArgumentKind()->getName() << ", " << getArgumentIdx() << ", " << getTypeTagIdx() << ", " << getIsPointer() << ")))";
+    break;
+  }
+}
+}
+
+const char *ArgumentWithTypeTagAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "argument_with_type_tag";
+  case 1:
+    return "pointer_with_type_tag";
+  }
+}
+
+AsmLabelAttr *AsmLabelAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AsmLabelAttr(getLocation(), C, getLabel(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AsmLabelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " asm(\"" << getLabel() << "\")";
+    break;
+  }
+  case 1 : {
+    OS << " __asm__(\"" << getLabel() << "\")";
+    break;
+  }
+}
+}
+
+const char *AsmLabelAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "asm";
+  case 1:
+    return "__asm__";
+  }
+}
+
+AssertCapabilityAttr *AssertCapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AssertCapabilityAttr(getLocation(), C, expr, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AssertCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((assert_capability(" << getExpr() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::assert_capability(" << getExpr() << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((assert_shared_capability(" << getExpr() << ")))";
+    break;
+  }
+  case 3 : {
+    OS << " [[clang::assert_shared_capability(" << getExpr() << ")]]";
+    break;
+  }
+}
+}
+
+const char *AssertCapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "assert_capability";
+  case 1:
+    return "assert_capability";
+  case 2:
+    return "assert_shared_capability";
+  case 3:
+    return "assert_shared_capability";
+  }
+}
+
+AssertExclusiveLockAttr *AssertExclusiveLockAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AssertExclusiveLockAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AssertExclusiveLockAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((assert_exclusive_lock(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AssertExclusiveLockAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "assert_exclusive_lock";
+  }
+}
+
+AssertSharedLockAttr *AssertSharedLockAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AssertSharedLockAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AssertSharedLockAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((assert_shared_lock(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AssertSharedLockAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "assert_shared_lock";
+  }
+}
+
+AvailabilityAttr *AvailabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) AvailabilityAttr(getLocation(), C, platform, getIntroduced(), getDeprecated(), getObsoleted(), unavailable, getMessage(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void AvailabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((availability(" << getPlatform()->getName();
+  if (!getIntroduced().empty()) OS << ", introduced=" << getIntroduced();
+  if (!getDeprecated().empty()) OS << ", deprecated=" << getDeprecated();
+  if (!getObsoleted().empty()) OS << ", obsoleted=" << getObsoleted();
+  if (getUnavailable()) OS << ", unavailable";
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *AvailabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "availability";
+  }
+}
+
+BlocksAttr *BlocksAttr::clone(ASTContext &C) const {
+  auto *A = new (C) BlocksAttr(getLocation(), C, type, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void BlocksAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((blocks(" << getType() << ")))";
+    break;
+  }
+}
+}
+
+const char *BlocksAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "blocks";
+  }
+}
+
+C11NoReturnAttr *C11NoReturnAttr::clone(ASTContext &C) const {
+  auto *A = new (C) C11NoReturnAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void C11NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " _Noreturn";
+    break;
+  }
+}
+}
+
+const char *C11NoReturnAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "_Noreturn";
+  }
+}
+
+CDeclAttr *CDeclAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CDeclAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CDeclAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cdecl))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::cdecl]]";
+    break;
+  }
+  case 2 : {
+    OS << " __cdecl";
+    break;
+  }
+  case 3 : {
+    OS << " _cdecl";
+    break;
+  }
+}
+}
+
+const char *CDeclAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cdecl";
+  case 1:
+    return "cdecl";
+  case 2:
+    return "__cdecl";
+  case 3:
+    return "_cdecl";
+  }
+}
+
+CFAuditedTransferAttr *CFAuditedTransferAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CFAuditedTransferAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CFAuditedTransferAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cf_audited_transfer))";
+    break;
+  }
+}
+}
+
+const char *CFAuditedTransferAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cf_audited_transfer";
+  }
+}
+
+CFConsumedAttr *CFConsumedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CFConsumedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CFConsumedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cf_consumed))";
+    break;
+  }
+}
+}
+
+const char *CFConsumedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cf_consumed";
+  }
+}
+
+CFReturnsNotRetainedAttr *CFReturnsNotRetainedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CFReturnsNotRetainedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CFReturnsNotRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cf_returns_not_retained))";
+    break;
+  }
+}
+}
+
+const char *CFReturnsNotRetainedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cf_returns_not_retained";
+  }
+}
+
+CFReturnsRetainedAttr *CFReturnsRetainedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CFReturnsRetainedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CFReturnsRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cf_returns_retained))";
+    break;
+  }
+}
+}
+
+const char *CFReturnsRetainedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cf_returns_retained";
+  }
+}
+
+CFUnknownTransferAttr *CFUnknownTransferAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CFUnknownTransferAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CFUnknownTransferAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cf_unknown_transfer))";
+    break;
+  }
+}
+}
+
+const char *CFUnknownTransferAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cf_unknown_transfer";
+  }
+}
+
+CUDAConstantAttr *CUDAConstantAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDAConstantAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDAConstantAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((constant))";
+    break;
+  }
+}
+}
+
+const char *CUDAConstantAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "constant";
+  }
+}
+
+CUDADeviceAttr *CUDADeviceAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDADeviceAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDADeviceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((device))";
+    break;
+  }
+}
+}
+
+const char *CUDADeviceAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "device";
+  }
+}
+
+CUDAGlobalAttr *CUDAGlobalAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDAGlobalAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDAGlobalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((global))";
+    break;
+  }
+}
+}
+
+const char *CUDAGlobalAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "global";
+  }
+}
+
+CUDAHostAttr *CUDAHostAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDAHostAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDAHostAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((host))";
+    break;
+  }
+}
+}
+
+const char *CUDAHostAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "host";
+  }
+}
+
+CUDALaunchBoundsAttr *CUDALaunchBoundsAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDALaunchBoundsAttr(getLocation(), C, maxThreads, minBlocks, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDALaunchBoundsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((launch_bounds(" << getMaxThreads() << ", " << getMinBlocks() << ")))";
+    break;
+  }
+}
+}
+
+const char *CUDALaunchBoundsAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "launch_bounds";
+  }
+}
+
+CUDASharedAttr *CUDASharedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CUDASharedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CUDASharedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((shared))";
+    break;
+  }
+}
+}
+
+const char *CUDASharedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "shared";
+  }
+}
+
+CXX11NoReturnAttr *CXX11NoReturnAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CXX11NoReturnAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CXX11NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " [[noreturn]]";
+    break;
+  }
+}
+}
+
+const char *CXX11NoReturnAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "noreturn";
+  }
+}
+
+CallableWhenAttr *CallableWhenAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CallableWhenAttr(getLocation(), C, callableStates_, callableStates_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CallableWhenAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((callable_when(";
+  bool isFirst = true;
+  for (const auto &Val : callableStates()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *CallableWhenAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "callable_when";
+  }
+}
+
+CapabilityAttr *CapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CapabilityAttr(getLocation(), C, getName(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((capability(\"" << getName() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::capability(\"" << getName() << "\")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((shared_capability(\"" << getName() << "\")))";
+    break;
+  }
+  case 3 : {
+    OS << " [[clang::shared_capability(\"" << getName() << "\")]]";
+    break;
+  }
+}
+}
+
+const char *CapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "capability";
+  case 1:
+    return "capability";
+  case 2:
+    return "shared_capability";
+  case 3:
+    return "shared_capability";
+  }
+}
+
+CarriesDependencyAttr *CarriesDependencyAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CarriesDependencyAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CarriesDependencyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((carries_dependency))";
+    break;
+  }
+  case 1 : {
+    OS << " [[carries_dependency]]";
+    break;
+  }
+}
+}
+
+const char *CarriesDependencyAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "carries_dependency";
+  case 1:
+    return "carries_dependency";
+  }
+}
+
+CleanupAttr *CleanupAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CleanupAttr(getLocation(), C, functionDecl, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CleanupAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cleanup(" << getFunctionDecl()->getNameInfo().getAsString() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::cleanup(" << getFunctionDecl()->getNameInfo().getAsString() << ")]]";
+    break;
+  }
+}
+}
+
+const char *CleanupAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cleanup";
+  case 1:
+    return "cleanup";
+  }
+}
+
+ColdAttr *ColdAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ColdAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ColdAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((cold))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::cold]]";
+    break;
+  }
+}
+}
+
+const char *ColdAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "cold";
+  case 1:
+    return "cold";
+  }
+}
+
+CommonAttr *CommonAttr::clone(ASTContext &C) const {
+  auto *A = new (C) CommonAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void CommonAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((common))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::common]]";
+    break;
+  }
+}
+}
+
+const char *CommonAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "common";
+  case 1:
+    return "common";
+  }
+}
+
+ConstAttr *ConstAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ConstAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ConstAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((const))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::const]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((__const))";
+    break;
+  }
+  case 3 : {
+    OS << " [[gnu::__const]]";
+    break;
+  }
+}
+}
+
+const char *ConstAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "const";
+  case 1:
+    return "const";
+  case 2:
+    return "__const";
+  case 3:
+    return "__const";
+  }
+}
+
+ConstructorAttr *ConstructorAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ConstructorAttr(getLocation(), C, priority, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ConstructorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((constructor(" << getPriority() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::constructor(" << getPriority() << ")]]";
+    break;
+  }
+}
+}
+
+const char *ConstructorAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "constructor";
+  case 1:
+    return "constructor";
+  }
+}
+
+ConsumableAttr *ConsumableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ConsumableAttr(getLocation(), C, defaultState, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ConsumableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((consumable(" << getDefaultState() << ")))";
+    break;
+  }
+}
+}
+
+const char *ConsumableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "consumable";
+  }
+}
+
+ConsumableAutoCastAttr *ConsumableAutoCastAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ConsumableAutoCastAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ConsumableAutoCastAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((consumable_auto_cast_state))";
+    break;
+  }
+}
+}
+
+const char *ConsumableAutoCastAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "consumable_auto_cast_state";
+  }
+}
+
+ConsumableSetOnReadAttr *ConsumableSetOnReadAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ConsumableSetOnReadAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ConsumableSetOnReadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((consumable_set_state_on_read))";
+    break;
+  }
+}
+}
+
+const char *ConsumableSetOnReadAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "consumable_set_state_on_read";
+  }
+}
+
+DLLExportAttr *DLLExportAttr::clone(ASTContext &C) const {
+  auto *A = new (C) DLLExportAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void DLLExportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __declspec(dllexport)";
+    break;
+  }
+  case 1 : {
+    OS << " __attribute__((dllexport))";
+    break;
+  }
+  case 2 : {
+    OS << " [[gnu::dllexport]]";
+    break;
+  }
+}
+}
+
+const char *DLLExportAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "dllexport";
+  case 1:
+    return "dllexport";
+  case 2:
+    return "dllexport";
+  }
+}
+
+DLLImportAttr *DLLImportAttr::clone(ASTContext &C) const {
+  auto *A = new (C) DLLImportAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void DLLImportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __declspec(dllimport)";
+    break;
+  }
+  case 1 : {
+    OS << " __attribute__((dllimport))";
+    break;
+  }
+  case 2 : {
+    OS << " [[gnu::dllimport]]";
+    break;
+  }
+}
+}
+
+const char *DLLImportAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "dllimport";
+  case 1:
+    return "dllimport";
+  case 2:
+    return "dllimport";
+  }
+}
+
+DeprecatedAttr *DeprecatedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) DeprecatedAttr(getLocation(), C, getMessage(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void DeprecatedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((deprecated(\"" << getMessage() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::deprecated(\"" << getMessage() << "\")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(deprecated(\"" << getMessage() << "\"))";
+    break;
+  }
+  case 3 : {
+    OS << " [[deprecated(\"" << getMessage() << "\")]]";
+    break;
+  }
+}
+}
+
+const char *DeprecatedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "deprecated";
+  case 1:
+    return "deprecated";
+  case 2:
+    return "deprecated";
+  case 3:
+    return "deprecated";
+  }
+}
+
+DestructorAttr *DestructorAttr::clone(ASTContext &C) const {
+  auto *A = new (C) DestructorAttr(getLocation(), C, priority, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void DestructorAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((destructor(" << getPriority() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::destructor(" << getPriority() << ")]]";
+    break;
+  }
+}
+}
+
+const char *DestructorAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "destructor";
+  case 1:
+    return "destructor";
+  }
+}
+
+EnableIfAttr *EnableIfAttr::clone(ASTContext &C) const {
+  auto *A = new (C) EnableIfAttr(getLocation(), C, cond, getMessage(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void EnableIfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((enable_if(" << getCond() << ", \"" << getMessage() << "\")))";
+    break;
+  }
+}
+}
+
+const char *EnableIfAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "enable_if";
+  }
+}
+
+ExclusiveTrylockFunctionAttr *ExclusiveTrylockFunctionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ExclusiveTrylockFunctionAttr(getLocation(), C, successValue, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ExclusiveTrylockFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((exclusive_trylock_function(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *ExclusiveTrylockFunctionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "exclusive_trylock_function";
+  }
+}
+
+FallThroughAttr *FallThroughAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FallThroughAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FallThroughAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " [[clang::fallthrough]]";
+    break;
+  }
+}
+}
+
+const char *FallThroughAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "fallthrough";
+  }
+}
+
+FastCallAttr *FastCallAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FastCallAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FastCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((fastcall))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::fastcall]]";
+    break;
+  }
+  case 2 : {
+    OS << " __fastcall";
+    break;
+  }
+  case 3 : {
+    OS << " _fastcall";
+    break;
+  }
+}
+}
+
+const char *FastCallAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "fastcall";
+  case 1:
+    return "fastcall";
+  case 2:
+    return "__fastcall";
+  case 3:
+    return "_fastcall";
+  }
+}
+
+FinalAttr *FinalAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FinalAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FinalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " final";
+    break;
+  }
+  case 1 : {
+    OS << " sealed";
+    break;
+  }
+}
+}
+
+const char *FinalAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "final";
+  case 1:
+    return "sealed";
+  }
+}
+
+FlattenAttr *FlattenAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FlattenAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FlattenAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((flatten))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::flatten]]";
+    break;
+  }
+}
+}
+
+const char *FlattenAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "flatten";
+  case 1:
+    return "flatten";
+  }
+}
+
+FormatAttr *FormatAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FormatAttr(getLocation(), C, type, formatIdx, firstArg, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FormatAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((format(" << getType()->getName() << ", " << getFormatIdx() << ", " << getFirstArg() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::format(" << getType()->getName() << ", " << getFormatIdx() << ", " << getFirstArg() << ")]]";
+    break;
+  }
+}
+}
+
+const char *FormatAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "format";
+  case 1:
+    return "format";
+  }
+}
+
+FormatArgAttr *FormatArgAttr::clone(ASTContext &C) const {
+  auto *A = new (C) FormatArgAttr(getLocation(), C, formatIdx, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void FormatArgAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((format_arg(" << getFormatIdx() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::format_arg(" << getFormatIdx() << ")]]";
+    break;
+  }
+}
+}
+
+const char *FormatArgAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "format_arg";
+  case 1:
+    return "format_arg";
+  }
+}
+
+GNUInlineAttr *GNUInlineAttr::clone(ASTContext &C) const {
+  auto *A = new (C) GNUInlineAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void GNUInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((gnu_inline))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::gnu_inline]]";
+    break;
+  }
+}
+}
+
+const char *GNUInlineAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "gnu_inline";
+  case 1:
+    return "gnu_inline";
+  }
+}
+
+GuardedByAttr *GuardedByAttr::clone(ASTContext &C) const {
+  auto *A = new (C) GuardedByAttr(getLocation(), C, arg, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void GuardedByAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((guarded_by(" << getArg() << ")))";
+    break;
+  }
+}
+}
+
+const char *GuardedByAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "guarded_by";
+  }
+}
+
+GuardedVarAttr *GuardedVarAttr::clone(ASTContext &C) const {
+  auto *A = new (C) GuardedVarAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void GuardedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((guarded_var))";
+    break;
+  }
+}
+}
+
+const char *GuardedVarAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "guarded_var";
+  }
+}
+
+HotAttr *HotAttr::clone(ASTContext &C) const {
+  auto *A = new (C) HotAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void HotAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((hot))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::hot]]";
+    break;
+  }
+}
+}
+
+const char *HotAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "hot";
+  case 1:
+    return "hot";
+  }
+}
+
+IBActionAttr *IBActionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) IBActionAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void IBActionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ibaction))";
+    break;
+  }
+}
+}
+
+const char *IBActionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ibaction";
+  }
+}
+
+IBOutletAttr *IBOutletAttr::clone(ASTContext &C) const {
+  auto *A = new (C) IBOutletAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void IBOutletAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((iboutlet))";
+    break;
+  }
+}
+}
+
+const char *IBOutletAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "iboutlet";
+  }
+}
+
+IBOutletCollectionAttr *IBOutletCollectionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) IBOutletCollectionAttr(getLocation(), C, interface, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void IBOutletCollectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((iboutletcollection(" << getInterface().getAsString() << ")))";
+    break;
+  }
+}
+}
+
+const char *IBOutletCollectionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "iboutletcollection";
+  }
+}
+
+InitPriorityAttr *InitPriorityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) InitPriorityAttr(getLocation(), C, priority, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void InitPriorityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((init_priority(" << getPriority() << ")))";
+    break;
+  }
+}
+}
+
+const char *InitPriorityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "init_priority";
+  }
+}
+
+InitSegAttr *InitSegAttr::clone(ASTContext &C) const {
+  auto *A = new (C) InitSegAttr(getLocation(), C, getSection(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void InitSegAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << "#pragma init_seg ";
+    printPrettyPragma(OS, Policy);
+    break;
+  }
+}
+}
+
+const char *InitSegAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "init_seg";
+  }
+}
+
+IntelOclBiccAttr *IntelOclBiccAttr::clone(ASTContext &C) const {
+  auto *A = new (C) IntelOclBiccAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void IntelOclBiccAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((intel_ocl_bicc))";
+    break;
+  }
+}
+}
+
+const char *IntelOclBiccAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "intel_ocl_bicc";
+  }
+}
+
+LockReturnedAttr *LockReturnedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) LockReturnedAttr(getLocation(), C, arg, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void LockReturnedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((lock_returned(" << getArg() << ")))";
+    break;
+  }
+}
+}
+
+const char *LockReturnedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "lock_returned";
+  }
+}
+
+LocksExcludedAttr *LocksExcludedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) LocksExcludedAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void LocksExcludedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((locks_excluded(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *LocksExcludedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "locks_excluded";
+  }
+}
+
+LoopHintAttr *LoopHintAttr::clone(ASTContext &C) const {
+  auto *A = new (C) LoopHintAttr(getLocation(), C, option, value, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void LoopHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << "#pragma clang loop ";
+    printPrettyPragma(OS, Policy);
+    break;
+  }
+  case 1 : {
+    OS << "#pragma unroll ";
+    printPrettyPragma(OS, Policy);
+    break;
+  }
+}
+}
+
+const char *LoopHintAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "loop";
+  case 1:
+    return "unroll";
+  }
+}
+
+MSABIAttr *MSABIAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MSABIAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MSABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ms_abi))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::ms_abi]]";
+    break;
+  }
+}
+}
+
+const char *MSABIAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ms_abi";
+  case 1:
+    return "ms_abi";
+  }
+}
+
+MSInheritanceAttr *MSInheritanceAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MSInheritanceAttr(getLocation(), C, bestCase, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MSInheritanceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __single_inheritance(" << getBestCase() << ")";
+    break;
+  }
+  case 1 : {
+    OS << " __multiple_inheritance(" << getBestCase() << ")";
+    break;
+  }
+  case 2 : {
+    OS << " __virtual_inheritance(" << getBestCase() << ")";
+    break;
+  }
+  case 3 : {
+    OS << " __unspecified_inheritance(" << getBestCase() << ")";
+    break;
+  }
+}
+}
+
+const char *MSInheritanceAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "__single_inheritance";
+  case 1:
+    return "__multiple_inheritance";
+  case 2:
+    return "__virtual_inheritance";
+  case 3:
+    return "__unspecified_inheritance";
+  }
+}
+
+MSP430InterruptAttr *MSP430InterruptAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MSP430InterruptAttr(getLocation(), C, number, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MSP430InterruptAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((interrupt(" << getNumber() << ")))";
+    break;
+  }
+}
+}
+
+const char *MSP430InterruptAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "interrupt";
+  }
+}
+
+MSVtorDispAttr *MSVtorDispAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MSVtorDispAttr(getLocation(), C, vdm, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MSVtorDispAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+}
+
+const char *MSVtorDispAttr::getSpelling() const {
+  return "(No spelling)";
+}
+
+MallocAttr *MallocAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MallocAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MallocAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((malloc))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::malloc]]";
+    break;
+  }
+}
+}
+
+const char *MallocAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "malloc";
+  case 1:
+    return "malloc";
+  }
+}
+
+MaxFieldAlignmentAttr *MaxFieldAlignmentAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MaxFieldAlignmentAttr(getLocation(), C, alignment, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MaxFieldAlignmentAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+}
+
+const char *MaxFieldAlignmentAttr::getSpelling() const {
+  return "(No spelling)";
+}
+
+MayAliasAttr *MayAliasAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MayAliasAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MayAliasAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((may_alias))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::may_alias]]";
+    break;
+  }
+}
+}
+
+const char *MayAliasAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "may_alias";
+  case 1:
+    return "may_alias";
+  }
+}
+
+MinSizeAttr *MinSizeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MinSizeAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MinSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((minsize))";
+    break;
+  }
+}
+}
+
+const char *MinSizeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "minsize";
+  }
+}
+
+Mips16Attr *Mips16Attr::clone(ASTContext &C) const {
+  auto *A = new (C) Mips16Attr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void Mips16Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((mips16))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::mips16]]";
+    break;
+  }
+}
+}
+
+const char *Mips16Attr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "mips16";
+  case 1:
+    return "mips16";
+  }
+}
+
+ModeAttr *ModeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ModeAttr(getLocation(), C, mode, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ModeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((mode(" << getMode()->getName() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::mode(" << getMode()->getName() << ")]]";
+    break;
+  }
+}
+}
+
+const char *ModeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "mode";
+  case 1:
+    return "mode";
+  }
+}
+
+MsStructAttr *MsStructAttr::clone(ASTContext &C) const {
+  auto *A = new (C) MsStructAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void MsStructAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ms_struct))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::ms_struct]]";
+    break;
+  }
+}
+}
+
+const char *MsStructAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ms_struct";
+  case 1:
+    return "ms_struct";
+  }
+}
+
+NSConsumedAttr *NSConsumedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NSConsumedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NSConsumedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ns_consumed))";
+    break;
+  }
+}
+}
+
+const char *NSConsumedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ns_consumed";
+  }
+}
+
+NSConsumesSelfAttr *NSConsumesSelfAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NSConsumesSelfAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NSConsumesSelfAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ns_consumes_self))";
+    break;
+  }
+}
+}
+
+const char *NSConsumesSelfAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ns_consumes_self";
+  }
+}
+
+NSReturnsAutoreleasedAttr *NSReturnsAutoreleasedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NSReturnsAutoreleasedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NSReturnsAutoreleasedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ns_returns_autoreleased))";
+    break;
+  }
+}
+}
+
+const char *NSReturnsAutoreleasedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ns_returns_autoreleased";
+  }
+}
+
+NSReturnsNotRetainedAttr *NSReturnsNotRetainedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NSReturnsNotRetainedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NSReturnsNotRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ns_returns_not_retained))";
+    break;
+  }
+}
+}
+
+const char *NSReturnsNotRetainedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ns_returns_not_retained";
+  }
+}
+
+NSReturnsRetainedAttr *NSReturnsRetainedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NSReturnsRetainedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NSReturnsRetainedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ns_returns_retained))";
+    break;
+  }
+}
+}
+
+const char *NSReturnsRetainedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ns_returns_retained";
+  }
+}
+
+NakedAttr *NakedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NakedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NakedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((naked))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::naked]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(naked)";
+    break;
+  }
+}
+}
+
+const char *NakedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "naked";
+  case 1:
+    return "naked";
+  case 2:
+    return "naked";
+  }
+}
+
+NoCommonAttr *NoCommonAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoCommonAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoCommonAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((nocommon))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::nocommon]]";
+    break;
+  }
+}
+}
+
+const char *NoCommonAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "nocommon";
+  case 1:
+    return "nocommon";
+  }
+}
+
+NoDebugAttr *NoDebugAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoDebugAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoDebugAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((nodebug))";
+    break;
+  }
+}
+}
+
+const char *NoDebugAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "nodebug";
+  }
+}
+
+NoDuplicateAttr *NoDuplicateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoDuplicateAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoDuplicateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((noduplicate))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::noduplicate]]";
+    break;
+  }
+}
+}
+
+const char *NoDuplicateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "noduplicate";
+  case 1:
+    return "noduplicate";
+  }
+}
+
+NoInlineAttr *NoInlineAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoInlineAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoInlineAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((noinline))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::noinline]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(noinline)";
+    break;
+  }
+}
+}
+
+const char *NoInlineAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "noinline";
+  case 1:
+    return "noinline";
+  case 2:
+    return "noinline";
+  }
+}
+
+NoInstrumentFunctionAttr *NoInstrumentFunctionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoInstrumentFunctionAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoInstrumentFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_instrument_function))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::no_instrument_function]]";
+    break;
+  }
+}
+}
+
+const char *NoInstrumentFunctionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_instrument_function";
+  case 1:
+    return "no_instrument_function";
+  }
+}
+
+NoMips16Attr *NoMips16Attr::clone(ASTContext &C) const {
+  auto *A = new (C) NoMips16Attr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoMips16Attr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((nomips16))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::nomips16]]";
+    break;
+  }
+}
+}
+
+const char *NoMips16Attr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "nomips16";
+  case 1:
+    return "nomips16";
+  }
+}
+
+NoReturnAttr *NoReturnAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoReturnAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((noreturn))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::noreturn]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(noreturn)";
+    break;
+  }
+}
+}
+
+const char *NoReturnAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "noreturn";
+  case 1:
+    return "noreturn";
+  case 2:
+    return "noreturn";
+  }
+}
+
+NoSanitizeAddressAttr *NoSanitizeAddressAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoSanitizeAddressAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoSanitizeAddressAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_address_safety_analysis))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::no_address_safety_analysis]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((no_sanitize_address))";
+    break;
+  }
+  case 3 : {
+    OS << " [[gnu::no_sanitize_address]]";
+    break;
+  }
+}
+}
+
+const char *NoSanitizeAddressAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_address_safety_analysis";
+  case 1:
+    return "no_address_safety_analysis";
+  case 2:
+    return "no_sanitize_address";
+  case 3:
+    return "no_sanitize_address";
+  }
+}
+
+NoSanitizeMemoryAttr *NoSanitizeMemoryAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoSanitizeMemoryAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoSanitizeMemoryAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_sanitize_memory))";
+    break;
+  }
+}
+}
+
+const char *NoSanitizeMemoryAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_sanitize_memory";
+  }
+}
+
+NoSanitizeThreadAttr *NoSanitizeThreadAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoSanitizeThreadAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoSanitizeThreadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_sanitize_thread))";
+    break;
+  }
+}
+}
+
+const char *NoSanitizeThreadAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_sanitize_thread";
+  }
+}
+
+NoSplitStackAttr *NoSplitStackAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoSplitStackAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoSplitStackAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_split_stack))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::no_split_stack]]";
+    break;
+  }
+}
+}
+
+const char *NoSplitStackAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_split_stack";
+  case 1:
+    return "no_split_stack";
+  }
+}
+
+NoThreadSafetyAnalysisAttr *NoThreadSafetyAnalysisAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoThreadSafetyAnalysisAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoThreadSafetyAnalysisAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((no_thread_safety_analysis))";
+    break;
+  }
+}
+}
+
+const char *NoThreadSafetyAnalysisAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "no_thread_safety_analysis";
+  }
+}
+
+NoThrowAttr *NoThrowAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NoThrowAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NoThrowAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((nothrow))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::nothrow]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(nothrow)";
+    break;
+  }
+}
+}
+
+const char *NoThrowAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "nothrow";
+  case 1:
+    return "nothrow";
+  case 2:
+    return "nothrow";
+  }
+}
+
+NonNullAttr *NonNullAttr::clone(ASTContext &C) const {
+  auto *A = new (C) NonNullAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void NonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((nonnull(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::nonnull(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+}
+}
+
+const char *NonNullAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "nonnull";
+  case 1:
+    return "nonnull";
+  }
+}
+
+ObjCBridgeAttr *ObjCBridgeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCBridgeAttr(getLocation(), C, bridgedType, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCBridgeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_bridge(" << getBridgedType()->getName() << ")))";
+    break;
+  }
+}
+}
+
+const char *ObjCBridgeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_bridge";
+  }
+}
+
+ObjCBridgeMutableAttr *ObjCBridgeMutableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCBridgeMutableAttr(getLocation(), C, bridgedType, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCBridgeMutableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_bridge_mutable(" << getBridgedType()->getName() << ")))";
+    break;
+  }
+}
+}
+
+const char *ObjCBridgeMutableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_bridge_mutable";
+  }
+}
+
+ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCBridgeRelatedAttr(getLocation(), C, relatedClass, classMethod, instanceMethod, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCBridgeRelatedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_bridge_related(" << getRelatedClass()->getName() << ", " << getClassMethod()->getName() << ", " << getInstanceMethod()->getName() << ")))";
+    break;
+  }
+}
+}
+
+const char *ObjCBridgeRelatedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_bridge_related";
+  }
+}
+
+ObjCDesignatedInitializerAttr *ObjCDesignatedInitializerAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCDesignatedInitializerAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCDesignatedInitializerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_designated_initializer))";
+    break;
+  }
+}
+}
+
+const char *ObjCDesignatedInitializerAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_designated_initializer";
+  }
+}
+
+ObjCExceptionAttr *ObjCExceptionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCExceptionAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCExceptionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_exception))";
+    break;
+  }
+}
+}
+
+const char *ObjCExceptionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_exception";
+  }
+}
+
+ObjCExplicitProtocolImplAttr *ObjCExplicitProtocolImplAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCExplicitProtocolImplAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCExplicitProtocolImplAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_protocol_requires_explicit_implementation))";
+    break;
+  }
+}
+}
+
+const char *ObjCExplicitProtocolImplAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_protocol_requires_explicit_implementation";
+  }
+}
+
+ObjCMethodFamilyAttr *ObjCMethodFamilyAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCMethodFamilyAttr(getLocation(), C, family, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCMethodFamilyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_method_family(" << getFamily() << ")))";
+    break;
+  }
+}
+}
+
+const char *ObjCMethodFamilyAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_method_family";
+  }
+}
+
+ObjCNSObjectAttr *ObjCNSObjectAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCNSObjectAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCNSObjectAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((NSObject))";
+    break;
+  }
+}
+}
+
+const char *ObjCNSObjectAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "NSObject";
+  }
+}
+
+ObjCPreciseLifetimeAttr *ObjCPreciseLifetimeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCPreciseLifetimeAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCPreciseLifetimeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_precise_lifetime))";
+    break;
+  }
+}
+}
+
+const char *ObjCPreciseLifetimeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_precise_lifetime";
+  }
+}
+
+ObjCRequiresPropertyDefsAttr *ObjCRequiresPropertyDefsAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCRequiresPropertyDefsAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCRequiresPropertyDefsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_requires_property_definitions))";
+    break;
+  }
+}
+}
+
+const char *ObjCRequiresPropertyDefsAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_requires_property_definitions";
+  }
+}
+
+ObjCRequiresSuperAttr *ObjCRequiresSuperAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCRequiresSuperAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCRequiresSuperAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_requires_super))";
+    break;
+  }
+}
+}
+
+const char *ObjCRequiresSuperAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_requires_super";
+  }
+}
+
+ObjCReturnsInnerPointerAttr *ObjCReturnsInnerPointerAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCReturnsInnerPointerAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCReturnsInnerPointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_returns_inner_pointer))";
+    break;
+  }
+}
+}
+
+const char *ObjCReturnsInnerPointerAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_returns_inner_pointer";
+  }
+}
+
+ObjCRootClassAttr *ObjCRootClassAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCRootClassAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCRootClassAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_root_class))";
+    break;
+  }
+}
+}
+
+const char *ObjCRootClassAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_root_class";
+  }
+}
+
+ObjCRuntimeNameAttr *ObjCRuntimeNameAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ObjCRuntimeNameAttr(getLocation(), C, getMetadataName(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ObjCRuntimeNameAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((objc_runtime_name(\"" << getMetadataName() << "\")))";
+    break;
+  }
+}
+}
+
+const char *ObjCRuntimeNameAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "objc_runtime_name";
+  }
+}
+
+OpenCLImageAccessAttr *OpenCLImageAccessAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OpenCLImageAccessAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OpenCLImageAccessAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __read_only";
+    break;
+  }
+  case 1 : {
+    OS << " read_only";
+    break;
+  }
+  case 2 : {
+    OS << " __write_only";
+    break;
+  }
+  case 3 : {
+    OS << " write_only";
+    break;
+  }
+  case 4 : {
+    OS << " __read_write";
+    break;
+  }
+  case 5 : {
+    OS << " read_write";
+    break;
+  }
+}
+}
+
+const char *OpenCLImageAccessAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "__read_only";
+  case 1:
+    return "read_only";
+  case 2:
+    return "__write_only";
+  case 3:
+    return "write_only";
+  case 4:
+    return "__read_write";
+  case 5:
+    return "read_write";
+  }
+}
+
+OpenCLKernelAttr *OpenCLKernelAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OpenCLKernelAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OpenCLKernelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __kernel";
+    break;
+  }
+  case 1 : {
+    OS << " kernel";
+    break;
+  }
+}
+}
+
+const char *OpenCLKernelAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "__kernel";
+  case 1:
+    return "kernel";
+  }
+}
+
+OptimizeNoneAttr *OptimizeNoneAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OptimizeNoneAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OptimizeNoneAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((optnone))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::optnone]]";
+    break;
+  }
+}
+}
+
+const char *OptimizeNoneAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "optnone";
+  case 1:
+    return "optnone";
+  }
+}
+
+OverloadableAttr *OverloadableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OverloadableAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OverloadableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((overloadable))";
+    break;
+  }
+}
+}
+
+const char *OverloadableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "overloadable";
+  }
+}
+
+OverrideAttr *OverrideAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OverrideAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OverrideAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " override";
+    break;
+  }
+}
+}
+
+const char *OverrideAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "override";
+  }
+}
+
+OwnershipAttr *OwnershipAttr::clone(ASTContext &C) const {
+  auto *A = new (C) OwnershipAttr(getLocation(), C, module, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void OwnershipAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((ownership_holds(" << getModule()->getName() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " __attribute__((ownership_returns(" << getModule()->getName() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((ownership_takes(" << getModule()->getName() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *OwnershipAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "ownership_holds";
+  case 1:
+    return "ownership_returns";
+  case 2:
+    return "ownership_takes";
+  }
+}
+
+PackedAttr *PackedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PackedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PackedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((packed))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::packed]]";
+    break;
+  }
+}
+}
+
+const char *PackedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "packed";
+  case 1:
+    return "packed";
+  }
+}
+
+ParamTypestateAttr *ParamTypestateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ParamTypestateAttr(getLocation(), C, paramState, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ParamTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((param_typestate(" << getParamState() << ")))";
+    break;
+  }
+}
+}
+
+const char *ParamTypestateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "param_typestate";
+  }
+}
+
+PascalAttr *PascalAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PascalAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PascalAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pascal))";
+    break;
+  }
+  case 1 : {
+    OS << " __pascal";
+    break;
+  }
+  case 2 : {
+    OS << " _pascal";
+    break;
+  }
+}
+}
+
+const char *PascalAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pascal";
+  case 1:
+    return "__pascal";
+  case 2:
+    return "_pascal";
+  }
+}
+
+PcsAttr *PcsAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PcsAttr(getLocation(), C, pCS, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PcsAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pcs(" << getPCS() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::pcs(" << getPCS() << ")]]";
+    break;
+  }
+}
+}
+
+const char *PcsAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pcs";
+  case 1:
+    return "pcs";
+  }
+}
+
+PnaclCallAttr *PnaclCallAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PnaclCallAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PnaclCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pnaclcall))";
+    break;
+  }
+}
+}
+
+const char *PnaclCallAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pnaclcall";
+  }
+}
+
+PtGuardedByAttr *PtGuardedByAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PtGuardedByAttr(getLocation(), C, arg, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PtGuardedByAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pt_guarded_by(" << getArg() << ")))";
+    break;
+  }
+}
+}
+
+const char *PtGuardedByAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pt_guarded_by";
+  }
+}
+
+PtGuardedVarAttr *PtGuardedVarAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PtGuardedVarAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PtGuardedVarAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pt_guarded_var))";
+    break;
+  }
+}
+}
+
+const char *PtGuardedVarAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pt_guarded_var";
+  }
+}
+
+PureAttr *PureAttr::clone(ASTContext &C) const {
+  auto *A = new (C) PureAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void PureAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((pure))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::pure]]";
+    break;
+  }
+}
+}
+
+const char *PureAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "pure";
+  case 1:
+    return "pure";
+  }
+}
+
+ReleaseCapabilityAttr *ReleaseCapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ReleaseCapabilityAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ReleaseCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((release_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::release_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((release_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 3 : {
+    OS << " [[clang::release_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 4 : {
+    OS << " __attribute__((release_generic_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 5 : {
+    OS << " [[clang::release_generic_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 6 : {
+    OS << " __attribute__((unlock_function(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *ReleaseCapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "release_capability";
+  case 1:
+    return "release_capability";
+  case 2:
+    return "release_shared_capability";
+  case 3:
+    return "release_shared_capability";
+  case 4:
+    return "release_generic_capability";
+  case 5:
+    return "release_generic_capability";
+  case 6:
+    return "unlock_function";
+  }
+}
+
+ReqdWorkGroupSizeAttr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ReqdWorkGroupSizeAttr(getLocation(), C, xDim, yDim, zDim, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ReqdWorkGroupSizeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((reqd_work_group_size(" << getXDim() << ", " << getYDim() << ", " << getZDim() << ")))";
+    break;
+  }
+}
+}
+
+const char *ReqdWorkGroupSizeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "reqd_work_group_size";
+  }
+}
+
+RequiresCapabilityAttr *RequiresCapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) RequiresCapabilityAttr(getLocation(), C, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void RequiresCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((requires_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::requires_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((exclusive_locks_required(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 3 : {
+    OS << " __attribute__((requires_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 4 : {
+    OS << " [[clang::requires_shared_capability(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 5 : {
+    OS << " __attribute__((shared_locks_required(";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *RequiresCapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "requires_capability";
+  case 1:
+    return "requires_capability";
+  case 2:
+    return "exclusive_locks_required";
+  case 3:
+    return "requires_shared_capability";
+  case 4:
+    return "requires_shared_capability";
+  case 5:
+    return "shared_locks_required";
+  }
+}
+
+ReturnTypestateAttr *ReturnTypestateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ReturnTypestateAttr(getLocation(), C, state, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ReturnTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((return_typestate(" << getState() << ")))";
+    break;
+  }
+}
+}
+
+const char *ReturnTypestateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "return_typestate";
+  }
+}
+
+ReturnsNonNullAttr *ReturnsNonNullAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ReturnsNonNullAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ReturnsNonNullAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((returns_nonnull))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::returns_nonnull]]";
+    break;
+  }
+}
+}
+
+const char *ReturnsNonNullAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "returns_nonnull";
+  case 1:
+    return "returns_nonnull";
+  }
+}
+
+ReturnsTwiceAttr *ReturnsTwiceAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ReturnsTwiceAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ReturnsTwiceAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((returns_twice))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::returns_twice]]";
+    break;
+  }
+}
+}
+
+const char *ReturnsTwiceAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "returns_twice";
+  case 1:
+    return "returns_twice";
+  }
+}
+
+ScopedLockableAttr *ScopedLockableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ScopedLockableAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ScopedLockableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((scoped_lockable))";
+    break;
+  }
+}
+}
+
+const char *ScopedLockableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "scoped_lockable";
+  }
+}
+
+SectionAttr *SectionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SectionAttr(getLocation(), C, getName(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SectionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((section(\"" << getName() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::section(\"" << getName() << "\")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __declspec(allocate(\"" << getName() << "\"))";
+    break;
+  }
+}
+}
+
+const char *SectionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "section";
+  case 1:
+    return "section";
+  case 2:
+    return "allocate";
+  }
+}
+
+SelectAnyAttr *SelectAnyAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SelectAnyAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SelectAnyAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __declspec(selectany)";
+    break;
+  }
+}
+}
+
+const char *SelectAnyAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "selectany";
+  }
+}
+
+SentinelAttr *SentinelAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SentinelAttr(getLocation(), C, sentinel, nullPos, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SentinelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((sentinel(" << getSentinel() << ", " << getNullPos() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::sentinel(" << getSentinel() << ", " << getNullPos() << ")]]";
+    break;
+  }
+}
+}
+
+const char *SentinelAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "sentinel";
+  case 1:
+    return "sentinel";
+  }
+}
+
+SetTypestateAttr *SetTypestateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SetTypestateAttr(getLocation(), C, newState, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SetTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((set_typestate(" << getNewState() << ")))";
+    break;
+  }
+}
+}
+
+const char *SetTypestateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "set_typestate";
+  }
+}
+
+SharedTrylockFunctionAttr *SharedTrylockFunctionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SharedTrylockFunctionAttr(getLocation(), C, successValue, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SharedTrylockFunctionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((shared_trylock_function(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+}
+}
+
+const char *SharedTrylockFunctionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "shared_trylock_function";
+  }
+}
+
+StdCallAttr *StdCallAttr::clone(ASTContext &C) const {
+  auto *A = new (C) StdCallAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void StdCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((stdcall))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::stdcall]]";
+    break;
+  }
+  case 2 : {
+    OS << " __stdcall";
+    break;
+  }
+  case 3 : {
+    OS << " _stdcall";
+    break;
+  }
+}
+}
+
+const char *StdCallAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "stdcall";
+  case 1:
+    return "stdcall";
+  case 2:
+    return "__stdcall";
+  case 3:
+    return "_stdcall";
+  }
+}
+
+SysVABIAttr *SysVABIAttr::clone(ASTContext &C) const {
+  auto *A = new (C) SysVABIAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void SysVABIAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((sysv_abi))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::sysv_abi]]";
+    break;
+  }
+}
+}
+
+const char *SysVABIAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "sysv_abi";
+  case 1:
+    return "sysv_abi";
+  }
+}
+
+TLSModelAttr *TLSModelAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TLSModelAttr(getLocation(), C, getModel(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TLSModelAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((tls_model(\"" << getModel() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::tls_model(\"" << getModel() << "\")]]";
+    break;
+  }
+}
+}
+
+const char *TLSModelAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "tls_model";
+  case 1:
+    return "tls_model";
+  }
+}
+
+TestTypestateAttr *TestTypestateAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TestTypestateAttr(getLocation(), C, testState, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TestTypestateAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((test_typestate(" << getTestState() << ")))";
+    break;
+  }
+}
+}
+
+const char *TestTypestateAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "test_typestate";
+  }
+}
+
+ThisCallAttr *ThisCallAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ThisCallAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ThisCallAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((thiscall))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::thiscall]]";
+    break;
+  }
+  case 2 : {
+    OS << " __thiscall";
+    break;
+  }
+  case 3 : {
+    OS << " _thiscall";
+    break;
+  }
+}
+}
+
+const char *ThisCallAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "thiscall";
+  case 1:
+    return "thiscall";
+  case 2:
+    return "__thiscall";
+  case 3:
+    return "_thiscall";
+  }
+}
+
+ThreadAttr *ThreadAttr::clone(ASTContext &C) const {
+  auto *A = new (C) ThreadAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void ThreadAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __declspec(thread)";
+    break;
+  }
+}
+}
+
+const char *ThreadAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "thread";
+  }
+}
+
+TransparentUnionAttr *TransparentUnionAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TransparentUnionAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TransparentUnionAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((transparent_union))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::transparent_union]]";
+    break;
+  }
+}
+}
+
+const char *TransparentUnionAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "transparent_union";
+  case 1:
+    return "transparent_union";
+  }
+}
+
+TryAcquireCapabilityAttr *TryAcquireCapabilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TryAcquireCapabilityAttr(getLocation(), C, successValue, args_, args_Size, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TryAcquireCapabilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((try_acquire_capability(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::try_acquire_capability(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+  case 2 : {
+    OS << " __attribute__((try_acquire_shared_capability(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")))";
+    break;
+  }
+  case 3 : {
+    OS << " [[clang::try_acquire_shared_capability(" << getSuccessValue() << ", ";
+  bool isFirst = true;
+  for (const auto &Val : args()) {
+    if (isFirst) isFirst = false;
+    else OS << ", ";
+    OS << Val;
+  }
+  OS << ")]]";
+    break;
+  }
+}
+}
+
+const char *TryAcquireCapabilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "try_acquire_capability";
+  case 1:
+    return "try_acquire_capability";
+  case 2:
+    return "try_acquire_shared_capability";
+  case 3:
+    return "try_acquire_shared_capability";
+  }
+}
+
+TypeTagForDatatypeAttr *TypeTagForDatatypeAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TypeTagForDatatypeAttr(getLocation(), C, argumentKind, matchingCType, layoutCompatible, mustBeNull, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TypeTagForDatatypeAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((type_tag_for_datatype(" << getArgumentKind()->getName() << ", " << getMatchingCType().getAsString() << ", " << getLayoutCompatible() << ", " << getMustBeNull() << ")))";
+    break;
+  }
+}
+}
+
+const char *TypeTagForDatatypeAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "type_tag_for_datatype";
+  }
+}
+
+TypeVisibilityAttr *TypeVisibilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) TypeVisibilityAttr(getLocation(), C, visibility, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void TypeVisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((type_visibility(" << getVisibility() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[clang::type_visibility(" << getVisibility() << ")]]";
+    break;
+  }
+}
+}
+
+const char *TypeVisibilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "type_visibility";
+  case 1:
+    return "type_visibility";
+  }
+}
+
+UnavailableAttr *UnavailableAttr::clone(ASTContext &C) const {
+  auto *A = new (C) UnavailableAttr(getLocation(), C, getMessage(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void UnavailableAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((unavailable(\"" << getMessage() << "\")))";
+    break;
+  }
+}
+}
+
+const char *UnavailableAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "unavailable";
+  }
+}
+
+UnusedAttr *UnusedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) UnusedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void UnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((unused))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::unused]]";
+    break;
+  }
+}
+}
+
+const char *UnusedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "unused";
+  case 1:
+    return "unused";
+  }
+}
+
+UsedAttr *UsedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) UsedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void UsedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((used))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::used]]";
+    break;
+  }
+}
+}
+
+const char *UsedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "used";
+  case 1:
+    return "used";
+  }
+}
+
+UuidAttr *UuidAttr::clone(ASTContext &C) const {
+  auto *A = new (C) UuidAttr(getLocation(), C, getGuid(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void UuidAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __declspec(uuid(\"" << getGuid() << "\"))";
+    break;
+  }
+}
+}
+
+const char *UuidAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "uuid";
+  }
+}
+
+VecReturnAttr *VecReturnAttr::clone(ASTContext &C) const {
+  auto *A = new (C) VecReturnAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void VecReturnAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((vecreturn))";
+    break;
+  }
+}
+}
+
+const char *VecReturnAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "vecreturn";
+  }
+}
+
+VecTypeHintAttr *VecTypeHintAttr::clone(ASTContext &C) const {
+  auto *A = new (C) VecTypeHintAttr(getLocation(), C, typeHint, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void VecTypeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((vec_type_hint(" << getTypeHint().getAsString() << ")))";
+    break;
+  }
+}
+}
+
+const char *VecTypeHintAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "vec_type_hint";
+  }
+}
+
+VisibilityAttr *VisibilityAttr::clone(ASTContext &C) const {
+  auto *A = new (C) VisibilityAttr(getLocation(), C, visibility, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void VisibilityAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((visibility(" << getVisibility() << ")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::visibility(" << getVisibility() << ")]]";
+    break;
+  }
+}
+}
+
+const char *VisibilityAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "visibility";
+  case 1:
+    return "visibility";
+  }
+}
+
+WarnUnusedAttr *WarnUnusedAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WarnUnusedAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WarnUnusedAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((warn_unused))";
+    break;
+  }
+}
+}
+
+const char *WarnUnusedAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "warn_unused";
+  }
+}
+
+WarnUnusedResultAttr *WarnUnusedResultAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WarnUnusedResultAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WarnUnusedResultAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((warn_unused_result))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::warn_unused_result]]";
+    break;
+  }
+  case 2 : {
+    OS << " [[clang::warn_unused_result]]";
+    break;
+  }
+}
+}
+
+const char *WarnUnusedResultAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "warn_unused_result";
+  case 1:
+    return "warn_unused_result";
+  case 2:
+    return "warn_unused_result";
+  }
+}
+
+WeakAttr *WeakAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WeakAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WeakAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((weak))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::weak]]";
+    break;
+  }
+}
+}
+
+const char *WeakAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "weak";
+  case 1:
+    return "weak";
+  }
+}
+
+WeakImportAttr *WeakImportAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WeakImportAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WeakImportAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((weak_import))";
+    break;
+  }
+}
+}
+
+const char *WeakImportAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "weak_import";
+  }
+}
+
+WeakRefAttr *WeakRefAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WeakRefAttr(getLocation(), C, getAliasee(), getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WeakRefAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((weakref(\"" << getAliasee() << "\")))";
+    break;
+  }
+  case 1 : {
+    OS << " [[gnu::weakref(\"" << getAliasee() << "\")]]";
+    break;
+  }
+}
+}
+
+const char *WeakRefAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "weakref";
+  case 1:
+    return "weakref";
+  }
+}
+
+WorkGroupSizeHintAttr *WorkGroupSizeHintAttr::clone(ASTContext &C) const {
+  auto *A = new (C) WorkGroupSizeHintAttr(getLocation(), C, xDim, yDim, zDim, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void WorkGroupSizeHintAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((work_group_size_hint(" << getXDim() << ", " << getYDim() << ", " << getZDim() << ")))";
+    break;
+  }
+}
+}
+
+const char *WorkGroupSizeHintAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "work_group_size_hint";
+  }
+}
+
+X86ForceAlignArgPointerAttr *X86ForceAlignArgPointerAttr::clone(ASTContext &C) const {
+  auto *A = new (C) X86ForceAlignArgPointerAttr(getLocation(), C, getSpellingListIndex());
+  A->Inherited = Inherited;
+  A->IsPackExpansion = IsPackExpansion;
+  A->Implicit = Implicit;
+  return A;
+}
+
+void X86ForceAlignArgPointerAttr::printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    break;
+  case 0 : {
+    OS << " __attribute__((force_align_arg_pointer))";
+    break;
+  }
+}
+}
+
+const char *X86ForceAlignArgPointerAttr::getSpelling() const {
+  switch (SpellingListIndex) {
+  default:
+    llvm_unreachable("Unknown attribute spelling!");
+    return "(No spelling)";
+  case 0:
+    return "force_align_arg_pointer";
+  }
+}
+
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
new file mode 100644
index 0000000..39ee81f
--- /dev/null
+++ b/include/clang/AST/AttrIterator.h
@@ -0,0 +1,142 @@
+//===--- AttrIterator.h - Classes for attribute iteration -------*- 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 Attr vector and specific_attr_iterator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTRITERATOR_H
+#define LLVM_CLANG_AST_ATTRITERATOR_H
+
+#include "clang/Basic/LLVM.h"
+#include <iterator>
+
+namespace clang {
+  class ASTContext;
+  class Attr;
+}
+
+// Defined in ASTContext.h
+void *operator new(size_t Bytes, const clang::ASTContext &C,
+                   size_t Alignment = 16);
+// FIXME: Being forced to not have a default argument here due to redeclaration
+//        rules on default arguments sucks
+void *operator new[](size_t Bytes, const clang::ASTContext &C,
+                     size_t Alignment);
+
+// It is good practice to pair new/delete operators.  Also, MSVC gives many
+// warnings if a matching delete overload is not declared, even though the
+// throw() spec guarantees it will not be implicitly called.
+void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
+void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
+
+namespace clang {
+
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef SmallVector<Attr*, 2> AttrVec;
+typedef SmallVector<const Attr*, 2> ConstAttrVec;
+
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specific type.
+template <typename SpecificAttr, typename Container = AttrVec>
+class specific_attr_iterator {
+  typedef typename Container::const_iterator Iterator;
+
+  /// Current - The current, underlying iterator.
+  /// In order to ensure we don't dereference an invalid iterator unless
+  /// specifically requested, we don't necessarily advance this all the
+  /// way. Instead, we advance it when an operation is requested; if the
+  /// operation is acting on what should be a past-the-end iterator,
+  /// then we offer no guarantees, but this way we do not dereference a
+  /// past-the-end iterator when we move to a past-the-end position.
+  mutable Iterator Current;
+
+  void AdvanceToNext() const {
+    while (!isa<SpecificAttr>(*Current))
+      ++Current;
+  }
+
+  void AdvanceToNext(Iterator I) const {
+    while (Current != I && !isa<SpecificAttr>(*Current))
+      ++Current;
+  }
+
+public:
+  typedef SpecificAttr*             value_type;
+  typedef SpecificAttr*             reference;
+  typedef SpecificAttr*             pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef std::ptrdiff_t            difference_type;
+
+  specific_attr_iterator() : Current() { }
+  explicit specific_attr_iterator(Iterator i) : Current(i) { }
+
+  reference operator*() const {
+    AdvanceToNext();
+    return cast<SpecificAttr>(*Current);
+  }
+  pointer operator->() const {
+    AdvanceToNext();
+    return cast<SpecificAttr>(*Current);
+  }
+
+  specific_attr_iterator& operator++() {
+    ++Current;
+    return *this;
+  }
+  specific_attr_iterator operator++(int) {
+    specific_attr_iterator Tmp(*this);
+    ++(*this);
+    return Tmp;
+  }
+
+  friend bool operator==(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    assert((Left.Current == nullptr) == (Right.Current == nullptr));
+    if (Left.Current < Right.Current)
+      Left.AdvanceToNext(Right.Current); 
+    else
+      Right.AdvanceToNext(Left.Current);
+    return Left.Current == Right.Current;
+  }
+  friend bool operator!=(specific_attr_iterator Left,
+                         specific_attr_iterator Right) {
+    return !(Left == Right);
+  }
+};
+
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+          specific_attr_begin(const Container& container) {
+  return specific_attr_iterator<SpecificAttr, Container>(container.begin());
+}
+template <typename SpecificAttr, typename Container>
+inline specific_attr_iterator<SpecificAttr, Container>
+          specific_attr_end(const Container& container) {
+  return specific_attr_iterator<SpecificAttr, Container>(container.end());
+}
+
+template <typename SpecificAttr, typename Container>
+inline bool hasSpecificAttr(const Container& container) {
+  return specific_attr_begin<SpecificAttr>(container) !=
+          specific_attr_end<SpecificAttr>(container);
+}
+template <typename SpecificAttr, typename Container>
+inline SpecificAttr *getSpecificAttr(const Container& container) {
+  specific_attr_iterator<SpecificAttr, Container> i =
+      specific_attr_begin<SpecificAttr>(container);
+  if (i != specific_attr_end<SpecificAttr>(container))
+    return *i;
+  else
+    return nullptr;
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/AttrVisitor.inc b/include/clang/AST/AttrVisitor.inc
new file mode 100644
index 0000000..35f1f82
--- /dev/null
+++ b/include/clang/AST/AttrVisitor.inc
@@ -0,0 +1,2573 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Used by RecursiveASTVisitor to visit attributes.                            *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifdef ATTR_VISITOR_DECLS_ONLY
+
+  bool TraverseARMInterruptAttr(ARMInterruptAttr *A);
+  bool VisitARMInterruptAttr(ARMInterruptAttr *A) {
+    return true; 
+  };
+  bool TraverseAcquireCapabilityAttr(AcquireCapabilityAttr *A);
+  bool VisitAcquireCapabilityAttr(AcquireCapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseAcquiredAfterAttr(AcquiredAfterAttr *A);
+  bool VisitAcquiredAfterAttr(AcquiredAfterAttr *A) {
+    return true; 
+  };
+  bool TraverseAcquiredBeforeAttr(AcquiredBeforeAttr *A);
+  bool VisitAcquiredBeforeAttr(AcquiredBeforeAttr *A) {
+    return true; 
+  };
+  bool TraverseAliasAttr(AliasAttr *A);
+  bool VisitAliasAttr(AliasAttr *A) {
+    return true; 
+  };
+  bool TraverseAlignMac68kAttr(AlignMac68kAttr *A);
+  bool VisitAlignMac68kAttr(AlignMac68kAttr *A) {
+    return true; 
+  };
+  bool TraverseAlignedAttr(AlignedAttr *A);
+  bool VisitAlignedAttr(AlignedAttr *A) {
+    return true; 
+  };
+  bool TraverseAlwaysInlineAttr(AlwaysInlineAttr *A);
+  bool VisitAlwaysInlineAttr(AlwaysInlineAttr *A) {
+    return true; 
+  };
+  bool TraverseAnalyzerNoReturnAttr(AnalyzerNoReturnAttr *A);
+  bool VisitAnalyzerNoReturnAttr(AnalyzerNoReturnAttr *A) {
+    return true; 
+  };
+  bool TraverseAnnotateAttr(AnnotateAttr *A);
+  bool VisitAnnotateAttr(AnnotateAttr *A) {
+    return true; 
+  };
+  bool TraverseArcWeakrefUnavailableAttr(ArcWeakrefUnavailableAttr *A);
+  bool VisitArcWeakrefUnavailableAttr(ArcWeakrefUnavailableAttr *A) {
+    return true; 
+  };
+  bool TraverseArgumentWithTypeTagAttr(ArgumentWithTypeTagAttr *A);
+  bool VisitArgumentWithTypeTagAttr(ArgumentWithTypeTagAttr *A) {
+    return true; 
+  };
+  bool TraverseAsmLabelAttr(AsmLabelAttr *A);
+  bool VisitAsmLabelAttr(AsmLabelAttr *A) {
+    return true; 
+  };
+  bool TraverseAssertCapabilityAttr(AssertCapabilityAttr *A);
+  bool VisitAssertCapabilityAttr(AssertCapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseAssertExclusiveLockAttr(AssertExclusiveLockAttr *A);
+  bool VisitAssertExclusiveLockAttr(AssertExclusiveLockAttr *A) {
+    return true; 
+  };
+  bool TraverseAssertSharedLockAttr(AssertSharedLockAttr *A);
+  bool VisitAssertSharedLockAttr(AssertSharedLockAttr *A) {
+    return true; 
+  };
+  bool TraverseAvailabilityAttr(AvailabilityAttr *A);
+  bool VisitAvailabilityAttr(AvailabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseBlocksAttr(BlocksAttr *A);
+  bool VisitBlocksAttr(BlocksAttr *A) {
+    return true; 
+  };
+  bool TraverseC11NoReturnAttr(C11NoReturnAttr *A);
+  bool VisitC11NoReturnAttr(C11NoReturnAttr *A) {
+    return true; 
+  };
+  bool TraverseCDeclAttr(CDeclAttr *A);
+  bool VisitCDeclAttr(CDeclAttr *A) {
+    return true; 
+  };
+  bool TraverseCFAuditedTransferAttr(CFAuditedTransferAttr *A);
+  bool VisitCFAuditedTransferAttr(CFAuditedTransferAttr *A) {
+    return true; 
+  };
+  bool TraverseCFConsumedAttr(CFConsumedAttr *A);
+  bool VisitCFConsumedAttr(CFConsumedAttr *A) {
+    return true; 
+  };
+  bool TraverseCFReturnsNotRetainedAttr(CFReturnsNotRetainedAttr *A);
+  bool VisitCFReturnsNotRetainedAttr(CFReturnsNotRetainedAttr *A) {
+    return true; 
+  };
+  bool TraverseCFReturnsRetainedAttr(CFReturnsRetainedAttr *A);
+  bool VisitCFReturnsRetainedAttr(CFReturnsRetainedAttr *A) {
+    return true; 
+  };
+  bool TraverseCFUnknownTransferAttr(CFUnknownTransferAttr *A);
+  bool VisitCFUnknownTransferAttr(CFUnknownTransferAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDAConstantAttr(CUDAConstantAttr *A);
+  bool VisitCUDAConstantAttr(CUDAConstantAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDADeviceAttr(CUDADeviceAttr *A);
+  bool VisitCUDADeviceAttr(CUDADeviceAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDAGlobalAttr(CUDAGlobalAttr *A);
+  bool VisitCUDAGlobalAttr(CUDAGlobalAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDAHostAttr(CUDAHostAttr *A);
+  bool VisitCUDAHostAttr(CUDAHostAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDALaunchBoundsAttr(CUDALaunchBoundsAttr *A);
+  bool VisitCUDALaunchBoundsAttr(CUDALaunchBoundsAttr *A) {
+    return true; 
+  };
+  bool TraverseCUDASharedAttr(CUDASharedAttr *A);
+  bool VisitCUDASharedAttr(CUDASharedAttr *A) {
+    return true; 
+  };
+  bool TraverseCXX11NoReturnAttr(CXX11NoReturnAttr *A);
+  bool VisitCXX11NoReturnAttr(CXX11NoReturnAttr *A) {
+    return true; 
+  };
+  bool TraverseCallableWhenAttr(CallableWhenAttr *A);
+  bool VisitCallableWhenAttr(CallableWhenAttr *A) {
+    return true; 
+  };
+  bool TraverseCapabilityAttr(CapabilityAttr *A);
+  bool VisitCapabilityAttr(CapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseCarriesDependencyAttr(CarriesDependencyAttr *A);
+  bool VisitCarriesDependencyAttr(CarriesDependencyAttr *A) {
+    return true; 
+  };
+  bool TraverseCleanupAttr(CleanupAttr *A);
+  bool VisitCleanupAttr(CleanupAttr *A) {
+    return true; 
+  };
+  bool TraverseColdAttr(ColdAttr *A);
+  bool VisitColdAttr(ColdAttr *A) {
+    return true; 
+  };
+  bool TraverseCommonAttr(CommonAttr *A);
+  bool VisitCommonAttr(CommonAttr *A) {
+    return true; 
+  };
+  bool TraverseConstAttr(ConstAttr *A);
+  bool VisitConstAttr(ConstAttr *A) {
+    return true; 
+  };
+  bool TraverseConstructorAttr(ConstructorAttr *A);
+  bool VisitConstructorAttr(ConstructorAttr *A) {
+    return true; 
+  };
+  bool TraverseConsumableAttr(ConsumableAttr *A);
+  bool VisitConsumableAttr(ConsumableAttr *A) {
+    return true; 
+  };
+  bool TraverseConsumableAutoCastAttr(ConsumableAutoCastAttr *A);
+  bool VisitConsumableAutoCastAttr(ConsumableAutoCastAttr *A) {
+    return true; 
+  };
+  bool TraverseConsumableSetOnReadAttr(ConsumableSetOnReadAttr *A);
+  bool VisitConsumableSetOnReadAttr(ConsumableSetOnReadAttr *A) {
+    return true; 
+  };
+  bool TraverseDLLExportAttr(DLLExportAttr *A);
+  bool VisitDLLExportAttr(DLLExportAttr *A) {
+    return true; 
+  };
+  bool TraverseDLLImportAttr(DLLImportAttr *A);
+  bool VisitDLLImportAttr(DLLImportAttr *A) {
+    return true; 
+  };
+  bool TraverseDeprecatedAttr(DeprecatedAttr *A);
+  bool VisitDeprecatedAttr(DeprecatedAttr *A) {
+    return true; 
+  };
+  bool TraverseDestructorAttr(DestructorAttr *A);
+  bool VisitDestructorAttr(DestructorAttr *A) {
+    return true; 
+  };
+  bool TraverseEnableIfAttr(EnableIfAttr *A);
+  bool VisitEnableIfAttr(EnableIfAttr *A) {
+    return true; 
+  };
+  bool TraverseExclusiveTrylockFunctionAttr(ExclusiveTrylockFunctionAttr *A);
+  bool VisitExclusiveTrylockFunctionAttr(ExclusiveTrylockFunctionAttr *A) {
+    return true; 
+  };
+  bool TraverseFallThroughAttr(FallThroughAttr *A);
+  bool VisitFallThroughAttr(FallThroughAttr *A) {
+    return true; 
+  };
+  bool TraverseFastCallAttr(FastCallAttr *A);
+  bool VisitFastCallAttr(FastCallAttr *A) {
+    return true; 
+  };
+  bool TraverseFinalAttr(FinalAttr *A);
+  bool VisitFinalAttr(FinalAttr *A) {
+    return true; 
+  };
+  bool TraverseFlattenAttr(FlattenAttr *A);
+  bool VisitFlattenAttr(FlattenAttr *A) {
+    return true; 
+  };
+  bool TraverseFormatAttr(FormatAttr *A);
+  bool VisitFormatAttr(FormatAttr *A) {
+    return true; 
+  };
+  bool TraverseFormatArgAttr(FormatArgAttr *A);
+  bool VisitFormatArgAttr(FormatArgAttr *A) {
+    return true; 
+  };
+  bool TraverseGNUInlineAttr(GNUInlineAttr *A);
+  bool VisitGNUInlineAttr(GNUInlineAttr *A) {
+    return true; 
+  };
+  bool TraverseGuardedByAttr(GuardedByAttr *A);
+  bool VisitGuardedByAttr(GuardedByAttr *A) {
+    return true; 
+  };
+  bool TraverseGuardedVarAttr(GuardedVarAttr *A);
+  bool VisitGuardedVarAttr(GuardedVarAttr *A) {
+    return true; 
+  };
+  bool TraverseHotAttr(HotAttr *A);
+  bool VisitHotAttr(HotAttr *A) {
+    return true; 
+  };
+  bool TraverseIBActionAttr(IBActionAttr *A);
+  bool VisitIBActionAttr(IBActionAttr *A) {
+    return true; 
+  };
+  bool TraverseIBOutletAttr(IBOutletAttr *A);
+  bool VisitIBOutletAttr(IBOutletAttr *A) {
+    return true; 
+  };
+  bool TraverseIBOutletCollectionAttr(IBOutletCollectionAttr *A);
+  bool VisitIBOutletCollectionAttr(IBOutletCollectionAttr *A) {
+    return true; 
+  };
+  bool TraverseInitPriorityAttr(InitPriorityAttr *A);
+  bool VisitInitPriorityAttr(InitPriorityAttr *A) {
+    return true; 
+  };
+  bool TraverseInitSegAttr(InitSegAttr *A);
+  bool VisitInitSegAttr(InitSegAttr *A) {
+    return true; 
+  };
+  bool TraverseIntelOclBiccAttr(IntelOclBiccAttr *A);
+  bool VisitIntelOclBiccAttr(IntelOclBiccAttr *A) {
+    return true; 
+  };
+  bool TraverseLockReturnedAttr(LockReturnedAttr *A);
+  bool VisitLockReturnedAttr(LockReturnedAttr *A) {
+    return true; 
+  };
+  bool TraverseLocksExcludedAttr(LocksExcludedAttr *A);
+  bool VisitLocksExcludedAttr(LocksExcludedAttr *A) {
+    return true; 
+  };
+  bool TraverseLoopHintAttr(LoopHintAttr *A);
+  bool VisitLoopHintAttr(LoopHintAttr *A) {
+    return true; 
+  };
+  bool TraverseMSABIAttr(MSABIAttr *A);
+  bool VisitMSABIAttr(MSABIAttr *A) {
+    return true; 
+  };
+  bool TraverseMSInheritanceAttr(MSInheritanceAttr *A);
+  bool VisitMSInheritanceAttr(MSInheritanceAttr *A) {
+    return true; 
+  };
+  bool TraverseMSP430InterruptAttr(MSP430InterruptAttr *A);
+  bool VisitMSP430InterruptAttr(MSP430InterruptAttr *A) {
+    return true; 
+  };
+  bool TraverseMSVtorDispAttr(MSVtorDispAttr *A);
+  bool VisitMSVtorDispAttr(MSVtorDispAttr *A) {
+    return true; 
+  };
+  bool TraverseMallocAttr(MallocAttr *A);
+  bool VisitMallocAttr(MallocAttr *A) {
+    return true; 
+  };
+  bool TraverseMaxFieldAlignmentAttr(MaxFieldAlignmentAttr *A);
+  bool VisitMaxFieldAlignmentAttr(MaxFieldAlignmentAttr *A) {
+    return true; 
+  };
+  bool TraverseMayAliasAttr(MayAliasAttr *A);
+  bool VisitMayAliasAttr(MayAliasAttr *A) {
+    return true; 
+  };
+  bool TraverseMinSizeAttr(MinSizeAttr *A);
+  bool VisitMinSizeAttr(MinSizeAttr *A) {
+    return true; 
+  };
+  bool TraverseMips16Attr(Mips16Attr *A);
+  bool VisitMips16Attr(Mips16Attr *A) {
+    return true; 
+  };
+  bool TraverseModeAttr(ModeAttr *A);
+  bool VisitModeAttr(ModeAttr *A) {
+    return true; 
+  };
+  bool TraverseMsStructAttr(MsStructAttr *A);
+  bool VisitMsStructAttr(MsStructAttr *A) {
+    return true; 
+  };
+  bool TraverseNSConsumedAttr(NSConsumedAttr *A);
+  bool VisitNSConsumedAttr(NSConsumedAttr *A) {
+    return true; 
+  };
+  bool TraverseNSConsumesSelfAttr(NSConsumesSelfAttr *A);
+  bool VisitNSConsumesSelfAttr(NSConsumesSelfAttr *A) {
+    return true; 
+  };
+  bool TraverseNSReturnsAutoreleasedAttr(NSReturnsAutoreleasedAttr *A);
+  bool VisitNSReturnsAutoreleasedAttr(NSReturnsAutoreleasedAttr *A) {
+    return true; 
+  };
+  bool TraverseNSReturnsNotRetainedAttr(NSReturnsNotRetainedAttr *A);
+  bool VisitNSReturnsNotRetainedAttr(NSReturnsNotRetainedAttr *A) {
+    return true; 
+  };
+  bool TraverseNSReturnsRetainedAttr(NSReturnsRetainedAttr *A);
+  bool VisitNSReturnsRetainedAttr(NSReturnsRetainedAttr *A) {
+    return true; 
+  };
+  bool TraverseNakedAttr(NakedAttr *A);
+  bool VisitNakedAttr(NakedAttr *A) {
+    return true; 
+  };
+  bool TraverseNoCommonAttr(NoCommonAttr *A);
+  bool VisitNoCommonAttr(NoCommonAttr *A) {
+    return true; 
+  };
+  bool TraverseNoDebugAttr(NoDebugAttr *A);
+  bool VisitNoDebugAttr(NoDebugAttr *A) {
+    return true; 
+  };
+  bool TraverseNoDuplicateAttr(NoDuplicateAttr *A);
+  bool VisitNoDuplicateAttr(NoDuplicateAttr *A) {
+    return true; 
+  };
+  bool TraverseNoInlineAttr(NoInlineAttr *A);
+  bool VisitNoInlineAttr(NoInlineAttr *A) {
+    return true; 
+  };
+  bool TraverseNoInstrumentFunctionAttr(NoInstrumentFunctionAttr *A);
+  bool VisitNoInstrumentFunctionAttr(NoInstrumentFunctionAttr *A) {
+    return true; 
+  };
+  bool TraverseNoMips16Attr(NoMips16Attr *A);
+  bool VisitNoMips16Attr(NoMips16Attr *A) {
+    return true; 
+  };
+  bool TraverseNoReturnAttr(NoReturnAttr *A);
+  bool VisitNoReturnAttr(NoReturnAttr *A) {
+    return true; 
+  };
+  bool TraverseNoSanitizeAddressAttr(NoSanitizeAddressAttr *A);
+  bool VisitNoSanitizeAddressAttr(NoSanitizeAddressAttr *A) {
+    return true; 
+  };
+  bool TraverseNoSanitizeMemoryAttr(NoSanitizeMemoryAttr *A);
+  bool VisitNoSanitizeMemoryAttr(NoSanitizeMemoryAttr *A) {
+    return true; 
+  };
+  bool TraverseNoSanitizeThreadAttr(NoSanitizeThreadAttr *A);
+  bool VisitNoSanitizeThreadAttr(NoSanitizeThreadAttr *A) {
+    return true; 
+  };
+  bool TraverseNoSplitStackAttr(NoSplitStackAttr *A);
+  bool VisitNoSplitStackAttr(NoSplitStackAttr *A) {
+    return true; 
+  };
+  bool TraverseNoThreadSafetyAnalysisAttr(NoThreadSafetyAnalysisAttr *A);
+  bool VisitNoThreadSafetyAnalysisAttr(NoThreadSafetyAnalysisAttr *A) {
+    return true; 
+  };
+  bool TraverseNoThrowAttr(NoThrowAttr *A);
+  bool VisitNoThrowAttr(NoThrowAttr *A) {
+    return true; 
+  };
+  bool TraverseNonNullAttr(NonNullAttr *A);
+  bool VisitNonNullAttr(NonNullAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCBridgeAttr(ObjCBridgeAttr *A);
+  bool VisitObjCBridgeAttr(ObjCBridgeAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCBridgeMutableAttr(ObjCBridgeMutableAttr *A);
+  bool VisitObjCBridgeMutableAttr(ObjCBridgeMutableAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCBridgeRelatedAttr(ObjCBridgeRelatedAttr *A);
+  bool VisitObjCBridgeRelatedAttr(ObjCBridgeRelatedAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCDesignatedInitializerAttr(ObjCDesignatedInitializerAttr *A);
+  bool VisitObjCDesignatedInitializerAttr(ObjCDesignatedInitializerAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCExceptionAttr(ObjCExceptionAttr *A);
+  bool VisitObjCExceptionAttr(ObjCExceptionAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCExplicitProtocolImplAttr(ObjCExplicitProtocolImplAttr *A);
+  bool VisitObjCExplicitProtocolImplAttr(ObjCExplicitProtocolImplAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCMethodFamilyAttr(ObjCMethodFamilyAttr *A);
+  bool VisitObjCMethodFamilyAttr(ObjCMethodFamilyAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCNSObjectAttr(ObjCNSObjectAttr *A);
+  bool VisitObjCNSObjectAttr(ObjCNSObjectAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCPreciseLifetimeAttr(ObjCPreciseLifetimeAttr *A);
+  bool VisitObjCPreciseLifetimeAttr(ObjCPreciseLifetimeAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCRequiresPropertyDefsAttr(ObjCRequiresPropertyDefsAttr *A);
+  bool VisitObjCRequiresPropertyDefsAttr(ObjCRequiresPropertyDefsAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCRequiresSuperAttr(ObjCRequiresSuperAttr *A);
+  bool VisitObjCRequiresSuperAttr(ObjCRequiresSuperAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCReturnsInnerPointerAttr(ObjCReturnsInnerPointerAttr *A);
+  bool VisitObjCReturnsInnerPointerAttr(ObjCReturnsInnerPointerAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCRootClassAttr(ObjCRootClassAttr *A);
+  bool VisitObjCRootClassAttr(ObjCRootClassAttr *A) {
+    return true; 
+  };
+  bool TraverseObjCRuntimeNameAttr(ObjCRuntimeNameAttr *A);
+  bool VisitObjCRuntimeNameAttr(ObjCRuntimeNameAttr *A) {
+    return true; 
+  };
+  bool TraverseOpenCLImageAccessAttr(OpenCLImageAccessAttr *A);
+  bool VisitOpenCLImageAccessAttr(OpenCLImageAccessAttr *A) {
+    return true; 
+  };
+  bool TraverseOpenCLKernelAttr(OpenCLKernelAttr *A);
+  bool VisitOpenCLKernelAttr(OpenCLKernelAttr *A) {
+    return true; 
+  };
+  bool TraverseOptimizeNoneAttr(OptimizeNoneAttr *A);
+  bool VisitOptimizeNoneAttr(OptimizeNoneAttr *A) {
+    return true; 
+  };
+  bool TraverseOverloadableAttr(OverloadableAttr *A);
+  bool VisitOverloadableAttr(OverloadableAttr *A) {
+    return true; 
+  };
+  bool TraverseOverrideAttr(OverrideAttr *A);
+  bool VisitOverrideAttr(OverrideAttr *A) {
+    return true; 
+  };
+  bool TraverseOwnershipAttr(OwnershipAttr *A);
+  bool VisitOwnershipAttr(OwnershipAttr *A) {
+    return true; 
+  };
+  bool TraversePackedAttr(PackedAttr *A);
+  bool VisitPackedAttr(PackedAttr *A) {
+    return true; 
+  };
+  bool TraverseParamTypestateAttr(ParamTypestateAttr *A);
+  bool VisitParamTypestateAttr(ParamTypestateAttr *A) {
+    return true; 
+  };
+  bool TraversePascalAttr(PascalAttr *A);
+  bool VisitPascalAttr(PascalAttr *A) {
+    return true; 
+  };
+  bool TraversePcsAttr(PcsAttr *A);
+  bool VisitPcsAttr(PcsAttr *A) {
+    return true; 
+  };
+  bool TraversePnaclCallAttr(PnaclCallAttr *A);
+  bool VisitPnaclCallAttr(PnaclCallAttr *A) {
+    return true; 
+  };
+  bool TraversePtGuardedByAttr(PtGuardedByAttr *A);
+  bool VisitPtGuardedByAttr(PtGuardedByAttr *A) {
+    return true; 
+  };
+  bool TraversePtGuardedVarAttr(PtGuardedVarAttr *A);
+  bool VisitPtGuardedVarAttr(PtGuardedVarAttr *A) {
+    return true; 
+  };
+  bool TraversePureAttr(PureAttr *A);
+  bool VisitPureAttr(PureAttr *A) {
+    return true; 
+  };
+  bool TraverseReleaseCapabilityAttr(ReleaseCapabilityAttr *A);
+  bool VisitReleaseCapabilityAttr(ReleaseCapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseReqdWorkGroupSizeAttr(ReqdWorkGroupSizeAttr *A);
+  bool VisitReqdWorkGroupSizeAttr(ReqdWorkGroupSizeAttr *A) {
+    return true; 
+  };
+  bool TraverseRequiresCapabilityAttr(RequiresCapabilityAttr *A);
+  bool VisitRequiresCapabilityAttr(RequiresCapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseReturnTypestateAttr(ReturnTypestateAttr *A);
+  bool VisitReturnTypestateAttr(ReturnTypestateAttr *A) {
+    return true; 
+  };
+  bool TraverseReturnsNonNullAttr(ReturnsNonNullAttr *A);
+  bool VisitReturnsNonNullAttr(ReturnsNonNullAttr *A) {
+    return true; 
+  };
+  bool TraverseReturnsTwiceAttr(ReturnsTwiceAttr *A);
+  bool VisitReturnsTwiceAttr(ReturnsTwiceAttr *A) {
+    return true; 
+  };
+  bool TraverseScopedLockableAttr(ScopedLockableAttr *A);
+  bool VisitScopedLockableAttr(ScopedLockableAttr *A) {
+    return true; 
+  };
+  bool TraverseSectionAttr(SectionAttr *A);
+  bool VisitSectionAttr(SectionAttr *A) {
+    return true; 
+  };
+  bool TraverseSelectAnyAttr(SelectAnyAttr *A);
+  bool VisitSelectAnyAttr(SelectAnyAttr *A) {
+    return true; 
+  };
+  bool TraverseSentinelAttr(SentinelAttr *A);
+  bool VisitSentinelAttr(SentinelAttr *A) {
+    return true; 
+  };
+  bool TraverseSetTypestateAttr(SetTypestateAttr *A);
+  bool VisitSetTypestateAttr(SetTypestateAttr *A) {
+    return true; 
+  };
+  bool TraverseSharedTrylockFunctionAttr(SharedTrylockFunctionAttr *A);
+  bool VisitSharedTrylockFunctionAttr(SharedTrylockFunctionAttr *A) {
+    return true; 
+  };
+  bool TraverseStdCallAttr(StdCallAttr *A);
+  bool VisitStdCallAttr(StdCallAttr *A) {
+    return true; 
+  };
+  bool TraverseSysVABIAttr(SysVABIAttr *A);
+  bool VisitSysVABIAttr(SysVABIAttr *A) {
+    return true; 
+  };
+  bool TraverseTLSModelAttr(TLSModelAttr *A);
+  bool VisitTLSModelAttr(TLSModelAttr *A) {
+    return true; 
+  };
+  bool TraverseTestTypestateAttr(TestTypestateAttr *A);
+  bool VisitTestTypestateAttr(TestTypestateAttr *A) {
+    return true; 
+  };
+  bool TraverseThisCallAttr(ThisCallAttr *A);
+  bool VisitThisCallAttr(ThisCallAttr *A) {
+    return true; 
+  };
+  bool TraverseThreadAttr(ThreadAttr *A);
+  bool VisitThreadAttr(ThreadAttr *A) {
+    return true; 
+  };
+  bool TraverseTransparentUnionAttr(TransparentUnionAttr *A);
+  bool VisitTransparentUnionAttr(TransparentUnionAttr *A) {
+    return true; 
+  };
+  bool TraverseTryAcquireCapabilityAttr(TryAcquireCapabilityAttr *A);
+  bool VisitTryAcquireCapabilityAttr(TryAcquireCapabilityAttr *A) {
+    return true; 
+  };
+  bool TraverseTypeTagForDatatypeAttr(TypeTagForDatatypeAttr *A);
+  bool VisitTypeTagForDatatypeAttr(TypeTagForDatatypeAttr *A) {
+    return true; 
+  };
+  bool TraverseTypeVisibilityAttr(TypeVisibilityAttr *A);
+  bool VisitTypeVisibilityAttr(TypeVisibilityAttr *A) {
+    return true; 
+  };
+  bool TraverseUnavailableAttr(UnavailableAttr *A);
+  bool VisitUnavailableAttr(UnavailableAttr *A) {
+    return true; 
+  };
+  bool TraverseUnusedAttr(UnusedAttr *A);
+  bool VisitUnusedAttr(UnusedAttr *A) {
+    return true; 
+  };
+  bool TraverseUsedAttr(UsedAttr *A);
+  bool VisitUsedAttr(UsedAttr *A) {
+    return true; 
+  };
+  bool TraverseUuidAttr(UuidAttr *A);
+  bool VisitUuidAttr(UuidAttr *A) {
+    return true; 
+  };
+  bool TraverseVecReturnAttr(VecReturnAttr *A);
+  bool VisitVecReturnAttr(VecReturnAttr *A) {
+    return true; 
+  };
+  bool TraverseVecTypeHintAttr(VecTypeHintAttr *A);
+  bool VisitVecTypeHintAttr(VecTypeHintAttr *A) {
+    return true; 
+  };
+  bool TraverseVisibilityAttr(VisibilityAttr *A);
+  bool VisitVisibilityAttr(VisibilityAttr *A) {
+    return true; 
+  };
+  bool TraverseWarnUnusedAttr(WarnUnusedAttr *A);
+  bool VisitWarnUnusedAttr(WarnUnusedAttr *A) {
+    return true; 
+  };
+  bool TraverseWarnUnusedResultAttr(WarnUnusedResultAttr *A);
+  bool VisitWarnUnusedResultAttr(WarnUnusedResultAttr *A) {
+    return true; 
+  };
+  bool TraverseWeakAttr(WeakAttr *A);
+  bool VisitWeakAttr(WeakAttr *A) {
+    return true; 
+  };
+  bool TraverseWeakImportAttr(WeakImportAttr *A);
+  bool VisitWeakImportAttr(WeakImportAttr *A) {
+    return true; 
+  };
+  bool TraverseWeakRefAttr(WeakRefAttr *A);
+  bool VisitWeakRefAttr(WeakRefAttr *A) {
+    return true; 
+  };
+  bool TraverseWorkGroupSizeHintAttr(WorkGroupSizeHintAttr *A);
+  bool VisitWorkGroupSizeHintAttr(WorkGroupSizeHintAttr *A) {
+    return true; 
+  };
+  bool TraverseX86ForceAlignArgPointerAttr(X86ForceAlignArgPointerAttr *A);
+  bool VisitX86ForceAlignArgPointerAttr(X86ForceAlignArgPointerAttr *A) {
+    return true; 
+  };
+
+#else // ATTR_VISITOR_DECLS_ONLY
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseARMInterruptAttr(ARMInterruptAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitARMInterruptAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAcquireCapabilityAttr(AcquireCapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAcquireCapabilityAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAcquiredAfterAttr(AcquiredAfterAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAcquiredAfterAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAcquiredBeforeAttr(AcquiredBeforeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAcquiredBeforeAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAliasAttr(AliasAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAliasAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAlignMac68kAttr(AlignMac68kAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAlignMac68kAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAlignedAttr(AlignedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAlignedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAlwaysInlineAttr(AlwaysInlineAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAlwaysInlineAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAnalyzerNoReturnAttr(AnalyzerNoReturnAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAnalyzerNoReturnAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAnnotateAttr(AnnotateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAnnotateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseArcWeakrefUnavailableAttr(ArcWeakrefUnavailableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitArcWeakrefUnavailableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseArgumentWithTypeTagAttr(ArgumentWithTypeTagAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitArgumentWithTypeTagAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAsmLabelAttr(AsmLabelAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAsmLabelAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAssertCapabilityAttr(AssertCapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAssertCapabilityAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getExpr()))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAssertExclusiveLockAttr(AssertExclusiveLockAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAssertExclusiveLockAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAssertSharedLockAttr(AssertSharedLockAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAssertSharedLockAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAvailabilityAttr(AvailabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitAvailabilityAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseBlocksAttr(BlocksAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitBlocksAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseC11NoReturnAttr(C11NoReturnAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitC11NoReturnAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCDeclAttr(CDeclAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCDeclAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCFAuditedTransferAttr(CFAuditedTransferAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCFAuditedTransferAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCFConsumedAttr(CFConsumedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCFConsumedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCFReturnsNotRetainedAttr(CFReturnsNotRetainedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCFReturnsNotRetainedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCFReturnsRetainedAttr(CFReturnsRetainedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCFReturnsRetainedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCFUnknownTransferAttr(CFUnknownTransferAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCFUnknownTransferAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDAConstantAttr(CUDAConstantAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDAConstantAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDADeviceAttr(CUDADeviceAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDADeviceAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDAGlobalAttr(CUDAGlobalAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDAGlobalAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDAHostAttr(CUDAHostAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDAHostAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDALaunchBoundsAttr(CUDALaunchBoundsAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDALaunchBoundsAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCUDASharedAttr(CUDASharedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCUDASharedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCXX11NoReturnAttr(CXX11NoReturnAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCXX11NoReturnAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCallableWhenAttr(CallableWhenAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCallableWhenAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCapabilityAttr(CapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCapabilityAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCarriesDependencyAttr(CarriesDependencyAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCarriesDependencyAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCleanupAttr(CleanupAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCleanupAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseColdAttr(ColdAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitColdAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseCommonAttr(CommonAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitCommonAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseConstAttr(ConstAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitConstAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseConstructorAttr(ConstructorAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitConstructorAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseConsumableAttr(ConsumableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitConsumableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseConsumableAutoCastAttr(ConsumableAutoCastAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitConsumableAutoCastAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseConsumableSetOnReadAttr(ConsumableSetOnReadAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitConsumableSetOnReadAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseDLLExportAttr(DLLExportAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitDLLExportAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseDLLImportAttr(DLLImportAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitDLLImportAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseDeprecatedAttr(DeprecatedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitDeprecatedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseDestructorAttr(DestructorAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitDestructorAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseEnableIfAttr(EnableIfAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitEnableIfAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getCond()))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseExclusiveTrylockFunctionAttr(ExclusiveTrylockFunctionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitExclusiveTrylockFunctionAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getSuccessValue()))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFallThroughAttr(FallThroughAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFallThroughAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFastCallAttr(FastCallAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFastCallAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFinalAttr(FinalAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFinalAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFlattenAttr(FlattenAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFlattenAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFormatAttr(FormatAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFormatAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseFormatArgAttr(FormatArgAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitFormatArgAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseGNUInlineAttr(GNUInlineAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitGNUInlineAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseGuardedByAttr(GuardedByAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitGuardedByAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getArg()))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseGuardedVarAttr(GuardedVarAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitGuardedVarAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseHotAttr(HotAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitHotAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseIBActionAttr(IBActionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitIBActionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseIBOutletAttr(IBOutletAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitIBOutletAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseIBOutletCollectionAttr(IBOutletCollectionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitIBOutletCollectionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseInitPriorityAttr(InitPriorityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitInitPriorityAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseInitSegAttr(InitSegAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitInitSegAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseIntelOclBiccAttr(IntelOclBiccAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitIntelOclBiccAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseLockReturnedAttr(LockReturnedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitLockReturnedAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getArg()))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseLocksExcludedAttr(LocksExcludedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitLocksExcludedAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseLoopHintAttr(LoopHintAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitLoopHintAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMSABIAttr(MSABIAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMSABIAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMSInheritanceAttr(MSInheritanceAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMSInheritanceAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMSP430InterruptAttr(MSP430InterruptAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMSP430InterruptAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMSVtorDispAttr(MSVtorDispAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMSVtorDispAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMallocAttr(MallocAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMallocAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMaxFieldAlignmentAttr(MaxFieldAlignmentAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMaxFieldAlignmentAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMayAliasAttr(MayAliasAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMayAliasAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMinSizeAttr(MinSizeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMinSizeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMips16Attr(Mips16Attr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMips16Attr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseModeAttr(ModeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitModeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseMsStructAttr(MsStructAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitMsStructAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNSConsumedAttr(NSConsumedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNSConsumedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNSConsumesSelfAttr(NSConsumesSelfAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNSConsumesSelfAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNSReturnsAutoreleasedAttr(NSReturnsAutoreleasedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNSReturnsAutoreleasedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNSReturnsNotRetainedAttr(NSReturnsNotRetainedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNSReturnsNotRetainedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNSReturnsRetainedAttr(NSReturnsRetainedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNSReturnsRetainedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNakedAttr(NakedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNakedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoCommonAttr(NoCommonAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoCommonAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoDebugAttr(NoDebugAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoDebugAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoDuplicateAttr(NoDuplicateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoDuplicateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoInlineAttr(NoInlineAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoInlineAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoInstrumentFunctionAttr(NoInstrumentFunctionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoInstrumentFunctionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoMips16Attr(NoMips16Attr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoMips16Attr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoReturnAttr(NoReturnAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoReturnAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoSanitizeAddressAttr(NoSanitizeAddressAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoSanitizeAddressAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoSanitizeMemoryAttr(NoSanitizeMemoryAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoSanitizeMemoryAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoSanitizeThreadAttr(NoSanitizeThreadAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoSanitizeThreadAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoSplitStackAttr(NoSplitStackAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoSplitStackAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoThreadSafetyAnalysisAttr(NoThreadSafetyAnalysisAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoThreadSafetyAnalysisAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNoThrowAttr(NoThrowAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNoThrowAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseNonNullAttr(NonNullAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitNonNullAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCBridgeAttr(ObjCBridgeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCBridgeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCBridgeMutableAttr(ObjCBridgeMutableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCBridgeMutableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCBridgeRelatedAttr(ObjCBridgeRelatedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCBridgeRelatedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCDesignatedInitializerAttr(ObjCDesignatedInitializerAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCDesignatedInitializerAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCExceptionAttr(ObjCExceptionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCExceptionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCExplicitProtocolImplAttr(ObjCExplicitProtocolImplAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCExplicitProtocolImplAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCMethodFamilyAttr(ObjCMethodFamilyAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCMethodFamilyAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCNSObjectAttr(ObjCNSObjectAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCNSObjectAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCPreciseLifetimeAttr(ObjCPreciseLifetimeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCPreciseLifetimeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCRequiresPropertyDefsAttr(ObjCRequiresPropertyDefsAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCRequiresPropertyDefsAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCRequiresSuperAttr(ObjCRequiresSuperAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCRequiresSuperAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCReturnsInnerPointerAttr(ObjCReturnsInnerPointerAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCReturnsInnerPointerAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCRootClassAttr(ObjCRootClassAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCRootClassAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseObjCRuntimeNameAttr(ObjCRuntimeNameAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitObjCRuntimeNameAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOpenCLImageAccessAttr(OpenCLImageAccessAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOpenCLImageAccessAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOpenCLKernelAttr(OpenCLKernelAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOpenCLKernelAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOptimizeNoneAttr(OptimizeNoneAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOptimizeNoneAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOverloadableAttr(OverloadableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOverloadableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOverrideAttr(OverrideAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOverrideAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseOwnershipAttr(OwnershipAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitOwnershipAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePackedAttr(PackedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPackedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseParamTypestateAttr(ParamTypestateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitParamTypestateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePascalAttr(PascalAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPascalAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePcsAttr(PcsAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPcsAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePnaclCallAttr(PnaclCallAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPnaclCallAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePtGuardedByAttr(PtGuardedByAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPtGuardedByAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getArg()))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePtGuardedVarAttr(PtGuardedVarAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPtGuardedVarAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraversePureAttr(PureAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitPureAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseReleaseCapabilityAttr(ReleaseCapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitReleaseCapabilityAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseReqdWorkGroupSizeAttr(ReqdWorkGroupSizeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitReqdWorkGroupSizeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseRequiresCapabilityAttr(RequiresCapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitRequiresCapabilityAttr(A))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseReturnTypestateAttr(ReturnTypestateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitReturnTypestateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseReturnsNonNullAttr(ReturnsNonNullAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitReturnsNonNullAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseReturnsTwiceAttr(ReturnsTwiceAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitReturnsTwiceAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseScopedLockableAttr(ScopedLockableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitScopedLockableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSectionAttr(SectionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSectionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSelectAnyAttr(SelectAnyAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSelectAnyAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSentinelAttr(SentinelAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSentinelAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSetTypestateAttr(SetTypestateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSetTypestateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSharedTrylockFunctionAttr(SharedTrylockFunctionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSharedTrylockFunctionAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getSuccessValue()))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseStdCallAttr(StdCallAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitStdCallAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseSysVABIAttr(SysVABIAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitSysVABIAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTLSModelAttr(TLSModelAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTLSModelAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTestTypestateAttr(TestTypestateAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTestTypestateAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseThisCallAttr(ThisCallAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitThisCallAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseThreadAttr(ThreadAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitThreadAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTransparentUnionAttr(TransparentUnionAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTransparentUnionAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTryAcquireCapabilityAttr(TryAcquireCapabilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTryAcquireCapabilityAttr(A))
+    return false;
+  if (!getDerived().TraverseStmt(A->getSuccessValue()))
+    return false;
+  {
+    Expr * *I = A->args_begin();
+    Expr * *E = A->args_end();
+    for (; I != E; ++I) {
+      if (!getDerived().TraverseStmt(*I))
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTypeTagForDatatypeAttr(TypeTagForDatatypeAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTypeTagForDatatypeAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseTypeVisibilityAttr(TypeVisibilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitTypeVisibilityAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseUnavailableAttr(UnavailableAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitUnavailableAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseUnusedAttr(UnusedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitUnusedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseUsedAttr(UsedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitUsedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseUuidAttr(UuidAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitUuidAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseVecReturnAttr(VecReturnAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitVecReturnAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseVecTypeHintAttr(VecTypeHintAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitVecTypeHintAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseVisibilityAttr(VisibilityAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitVisibilityAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWarnUnusedAttr(WarnUnusedAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWarnUnusedAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWarnUnusedResultAttr(WarnUnusedResultAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWarnUnusedResultAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWeakAttr(WeakAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWeakAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWeakImportAttr(WeakImportAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWeakImportAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWeakRefAttr(WeakRefAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWeakRefAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseWorkGroupSizeHintAttr(WorkGroupSizeHintAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitWorkGroupSizeHintAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseX86ForceAlignArgPointerAttr(X86ForceAlignArgPointerAttr *A) {
+  if (!getDerived().VisitAttr(A))
+    return false;
+  if (!getDerived().VisitX86ForceAlignArgPointerAttr(A))
+    return false;
+  return true;
+}
+
+template <typename Derived>
+bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {
+  if (!A)
+    return true;
+
+  switch (A->getKind()) {
+    default:
+      return true;
+    case attr::ARMInterrupt:
+      return getDerived().TraverseARMInterruptAttr(cast<ARMInterruptAttr>(A));
+    case attr::AcquireCapability:
+      return getDerived().TraverseAcquireCapabilityAttr(cast<AcquireCapabilityAttr>(A));
+    case attr::AcquiredAfter:
+      return getDerived().TraverseAcquiredAfterAttr(cast<AcquiredAfterAttr>(A));
+    case attr::AcquiredBefore:
+      return getDerived().TraverseAcquiredBeforeAttr(cast<AcquiredBeforeAttr>(A));
+    case attr::Alias:
+      return getDerived().TraverseAliasAttr(cast<AliasAttr>(A));
+    case attr::AlignMac68k:
+      return getDerived().TraverseAlignMac68kAttr(cast<AlignMac68kAttr>(A));
+    case attr::Aligned:
+      return getDerived().TraverseAlignedAttr(cast<AlignedAttr>(A));
+    case attr::AlwaysInline:
+      return getDerived().TraverseAlwaysInlineAttr(cast<AlwaysInlineAttr>(A));
+    case attr::AnalyzerNoReturn:
+      return getDerived().TraverseAnalyzerNoReturnAttr(cast<AnalyzerNoReturnAttr>(A));
+    case attr::Annotate:
+      return getDerived().TraverseAnnotateAttr(cast<AnnotateAttr>(A));
+    case attr::ArcWeakrefUnavailable:
+      return getDerived().TraverseArcWeakrefUnavailableAttr(cast<ArcWeakrefUnavailableAttr>(A));
+    case attr::ArgumentWithTypeTag:
+      return getDerived().TraverseArgumentWithTypeTagAttr(cast<ArgumentWithTypeTagAttr>(A));
+    case attr::AsmLabel:
+      return getDerived().TraverseAsmLabelAttr(cast<AsmLabelAttr>(A));
+    case attr::AssertCapability:
+      return getDerived().TraverseAssertCapabilityAttr(cast<AssertCapabilityAttr>(A));
+    case attr::AssertExclusiveLock:
+      return getDerived().TraverseAssertExclusiveLockAttr(cast<AssertExclusiveLockAttr>(A));
+    case attr::AssertSharedLock:
+      return getDerived().TraverseAssertSharedLockAttr(cast<AssertSharedLockAttr>(A));
+    case attr::Availability:
+      return getDerived().TraverseAvailabilityAttr(cast<AvailabilityAttr>(A));
+    case attr::Blocks:
+      return getDerived().TraverseBlocksAttr(cast<BlocksAttr>(A));
+    case attr::C11NoReturn:
+      return getDerived().TraverseC11NoReturnAttr(cast<C11NoReturnAttr>(A));
+    case attr::CDecl:
+      return getDerived().TraverseCDeclAttr(cast<CDeclAttr>(A));
+    case attr::CFAuditedTransfer:
+      return getDerived().TraverseCFAuditedTransferAttr(cast<CFAuditedTransferAttr>(A));
+    case attr::CFConsumed:
+      return getDerived().TraverseCFConsumedAttr(cast<CFConsumedAttr>(A));
+    case attr::CFReturnsNotRetained:
+      return getDerived().TraverseCFReturnsNotRetainedAttr(cast<CFReturnsNotRetainedAttr>(A));
+    case attr::CFReturnsRetained:
+      return getDerived().TraverseCFReturnsRetainedAttr(cast<CFReturnsRetainedAttr>(A));
+    case attr::CFUnknownTransfer:
+      return getDerived().TraverseCFUnknownTransferAttr(cast<CFUnknownTransferAttr>(A));
+    case attr::CUDAConstant:
+      return getDerived().TraverseCUDAConstantAttr(cast<CUDAConstantAttr>(A));
+    case attr::CUDADevice:
+      return getDerived().TraverseCUDADeviceAttr(cast<CUDADeviceAttr>(A));
+    case attr::CUDAGlobal:
+      return getDerived().TraverseCUDAGlobalAttr(cast<CUDAGlobalAttr>(A));
+    case attr::CUDAHost:
+      return getDerived().TraverseCUDAHostAttr(cast<CUDAHostAttr>(A));
+    case attr::CUDALaunchBounds:
+      return getDerived().TraverseCUDALaunchBoundsAttr(cast<CUDALaunchBoundsAttr>(A));
+    case attr::CUDAShared:
+      return getDerived().TraverseCUDASharedAttr(cast<CUDASharedAttr>(A));
+    case attr::CXX11NoReturn:
+      return getDerived().TraverseCXX11NoReturnAttr(cast<CXX11NoReturnAttr>(A));
+    case attr::CallableWhen:
+      return getDerived().TraverseCallableWhenAttr(cast<CallableWhenAttr>(A));
+    case attr::Capability:
+      return getDerived().TraverseCapabilityAttr(cast<CapabilityAttr>(A));
+    case attr::CarriesDependency:
+      return getDerived().TraverseCarriesDependencyAttr(cast<CarriesDependencyAttr>(A));
+    case attr::Cleanup:
+      return getDerived().TraverseCleanupAttr(cast<CleanupAttr>(A));
+    case attr::Cold:
+      return getDerived().TraverseColdAttr(cast<ColdAttr>(A));
+    case attr::Common:
+      return getDerived().TraverseCommonAttr(cast<CommonAttr>(A));
+    case attr::Const:
+      return getDerived().TraverseConstAttr(cast<ConstAttr>(A));
+    case attr::Constructor:
+      return getDerived().TraverseConstructorAttr(cast<ConstructorAttr>(A));
+    case attr::Consumable:
+      return getDerived().TraverseConsumableAttr(cast<ConsumableAttr>(A));
+    case attr::ConsumableAutoCast:
+      return getDerived().TraverseConsumableAutoCastAttr(cast<ConsumableAutoCastAttr>(A));
+    case attr::ConsumableSetOnRead:
+      return getDerived().TraverseConsumableSetOnReadAttr(cast<ConsumableSetOnReadAttr>(A));
+    case attr::DLLExport:
+      return getDerived().TraverseDLLExportAttr(cast<DLLExportAttr>(A));
+    case attr::DLLImport:
+      return getDerived().TraverseDLLImportAttr(cast<DLLImportAttr>(A));
+    case attr::Deprecated:
+      return getDerived().TraverseDeprecatedAttr(cast<DeprecatedAttr>(A));
+    case attr::Destructor:
+      return getDerived().TraverseDestructorAttr(cast<DestructorAttr>(A));
+    case attr::EnableIf:
+      return getDerived().TraverseEnableIfAttr(cast<EnableIfAttr>(A));
+    case attr::ExclusiveTrylockFunction:
+      return getDerived().TraverseExclusiveTrylockFunctionAttr(cast<ExclusiveTrylockFunctionAttr>(A));
+    case attr::FallThrough:
+      return getDerived().TraverseFallThroughAttr(cast<FallThroughAttr>(A));
+    case attr::FastCall:
+      return getDerived().TraverseFastCallAttr(cast<FastCallAttr>(A));
+    case attr::Final:
+      return getDerived().TraverseFinalAttr(cast<FinalAttr>(A));
+    case attr::Flatten:
+      return getDerived().TraverseFlattenAttr(cast<FlattenAttr>(A));
+    case attr::Format:
+      return getDerived().TraverseFormatAttr(cast<FormatAttr>(A));
+    case attr::FormatArg:
+      return getDerived().TraverseFormatArgAttr(cast<FormatArgAttr>(A));
+    case attr::GNUInline:
+      return getDerived().TraverseGNUInlineAttr(cast<GNUInlineAttr>(A));
+    case attr::GuardedBy:
+      return getDerived().TraverseGuardedByAttr(cast<GuardedByAttr>(A));
+    case attr::GuardedVar:
+      return getDerived().TraverseGuardedVarAttr(cast<GuardedVarAttr>(A));
+    case attr::Hot:
+      return getDerived().TraverseHotAttr(cast<HotAttr>(A));
+    case attr::IBAction:
+      return getDerived().TraverseIBActionAttr(cast<IBActionAttr>(A));
+    case attr::IBOutlet:
+      return getDerived().TraverseIBOutletAttr(cast<IBOutletAttr>(A));
+    case attr::IBOutletCollection:
+      return getDerived().TraverseIBOutletCollectionAttr(cast<IBOutletCollectionAttr>(A));
+    case attr::InitPriority:
+      return getDerived().TraverseInitPriorityAttr(cast<InitPriorityAttr>(A));
+    case attr::InitSeg:
+      return getDerived().TraverseInitSegAttr(cast<InitSegAttr>(A));
+    case attr::IntelOclBicc:
+      return getDerived().TraverseIntelOclBiccAttr(cast<IntelOclBiccAttr>(A));
+    case attr::LockReturned:
+      return getDerived().TraverseLockReturnedAttr(cast<LockReturnedAttr>(A));
+    case attr::LocksExcluded:
+      return getDerived().TraverseLocksExcludedAttr(cast<LocksExcludedAttr>(A));
+    case attr::LoopHint:
+      return getDerived().TraverseLoopHintAttr(cast<LoopHintAttr>(A));
+    case attr::MSABI:
+      return getDerived().TraverseMSABIAttr(cast<MSABIAttr>(A));
+    case attr::MSInheritance:
+      return getDerived().TraverseMSInheritanceAttr(cast<MSInheritanceAttr>(A));
+    case attr::MSP430Interrupt:
+      return getDerived().TraverseMSP430InterruptAttr(cast<MSP430InterruptAttr>(A));
+    case attr::MSVtorDisp:
+      return getDerived().TraverseMSVtorDispAttr(cast<MSVtorDispAttr>(A));
+    case attr::Malloc:
+      return getDerived().TraverseMallocAttr(cast<MallocAttr>(A));
+    case attr::MaxFieldAlignment:
+      return getDerived().TraverseMaxFieldAlignmentAttr(cast<MaxFieldAlignmentAttr>(A));
+    case attr::MayAlias:
+      return getDerived().TraverseMayAliasAttr(cast<MayAliasAttr>(A));
+    case attr::MinSize:
+      return getDerived().TraverseMinSizeAttr(cast<MinSizeAttr>(A));
+    case attr::Mips16:
+      return getDerived().TraverseMips16Attr(cast<Mips16Attr>(A));
+    case attr::Mode:
+      return getDerived().TraverseModeAttr(cast<ModeAttr>(A));
+    case attr::MsStruct:
+      return getDerived().TraverseMsStructAttr(cast<MsStructAttr>(A));
+    case attr::NSConsumed:
+      return getDerived().TraverseNSConsumedAttr(cast<NSConsumedAttr>(A));
+    case attr::NSConsumesSelf:
+      return getDerived().TraverseNSConsumesSelfAttr(cast<NSConsumesSelfAttr>(A));
+    case attr::NSReturnsAutoreleased:
+      return getDerived().TraverseNSReturnsAutoreleasedAttr(cast<NSReturnsAutoreleasedAttr>(A));
+    case attr::NSReturnsNotRetained:
+      return getDerived().TraverseNSReturnsNotRetainedAttr(cast<NSReturnsNotRetainedAttr>(A));
+    case attr::NSReturnsRetained:
+      return getDerived().TraverseNSReturnsRetainedAttr(cast<NSReturnsRetainedAttr>(A));
+    case attr::Naked:
+      return getDerived().TraverseNakedAttr(cast<NakedAttr>(A));
+    case attr::NoCommon:
+      return getDerived().TraverseNoCommonAttr(cast<NoCommonAttr>(A));
+    case attr::NoDebug:
+      return getDerived().TraverseNoDebugAttr(cast<NoDebugAttr>(A));
+    case attr::NoDuplicate:
+      return getDerived().TraverseNoDuplicateAttr(cast<NoDuplicateAttr>(A));
+    case attr::NoInline:
+      return getDerived().TraverseNoInlineAttr(cast<NoInlineAttr>(A));
+    case attr::NoInstrumentFunction:
+      return getDerived().TraverseNoInstrumentFunctionAttr(cast<NoInstrumentFunctionAttr>(A));
+    case attr::NoMips16:
+      return getDerived().TraverseNoMips16Attr(cast<NoMips16Attr>(A));
+    case attr::NoReturn:
+      return getDerived().TraverseNoReturnAttr(cast<NoReturnAttr>(A));
+    case attr::NoSanitizeAddress:
+      return getDerived().TraverseNoSanitizeAddressAttr(cast<NoSanitizeAddressAttr>(A));
+    case attr::NoSanitizeMemory:
+      return getDerived().TraverseNoSanitizeMemoryAttr(cast<NoSanitizeMemoryAttr>(A));
+    case attr::NoSanitizeThread:
+      return getDerived().TraverseNoSanitizeThreadAttr(cast<NoSanitizeThreadAttr>(A));
+    case attr::NoSplitStack:
+      return getDerived().TraverseNoSplitStackAttr(cast<NoSplitStackAttr>(A));
+    case attr::NoThreadSafetyAnalysis:
+      return getDerived().TraverseNoThreadSafetyAnalysisAttr(cast<NoThreadSafetyAnalysisAttr>(A));
+    case attr::NoThrow:
+      return getDerived().TraverseNoThrowAttr(cast<NoThrowAttr>(A));
+    case attr::NonNull:
+      return getDerived().TraverseNonNullAttr(cast<NonNullAttr>(A));
+    case attr::ObjCBridge:
+      return getDerived().TraverseObjCBridgeAttr(cast<ObjCBridgeAttr>(A));
+    case attr::ObjCBridgeMutable:
+      return getDerived().TraverseObjCBridgeMutableAttr(cast<ObjCBridgeMutableAttr>(A));
+    case attr::ObjCBridgeRelated:
+      return getDerived().TraverseObjCBridgeRelatedAttr(cast<ObjCBridgeRelatedAttr>(A));
+    case attr::ObjCDesignatedInitializer:
+      return getDerived().TraverseObjCDesignatedInitializerAttr(cast<ObjCDesignatedInitializerAttr>(A));
+    case attr::ObjCException:
+      return getDerived().TraverseObjCExceptionAttr(cast<ObjCExceptionAttr>(A));
+    case attr::ObjCExplicitProtocolImpl:
+      return getDerived().TraverseObjCExplicitProtocolImplAttr(cast<ObjCExplicitProtocolImplAttr>(A));
+    case attr::ObjCMethodFamily:
+      return getDerived().TraverseObjCMethodFamilyAttr(cast<ObjCMethodFamilyAttr>(A));
+    case attr::ObjCNSObject:
+      return getDerived().TraverseObjCNSObjectAttr(cast<ObjCNSObjectAttr>(A));
+    case attr::ObjCPreciseLifetime:
+      return getDerived().TraverseObjCPreciseLifetimeAttr(cast<ObjCPreciseLifetimeAttr>(A));
+    case attr::ObjCRequiresPropertyDefs:
+      return getDerived().TraverseObjCRequiresPropertyDefsAttr(cast<ObjCRequiresPropertyDefsAttr>(A));
+    case attr::ObjCRequiresSuper:
+      return getDerived().TraverseObjCRequiresSuperAttr(cast<ObjCRequiresSuperAttr>(A));
+    case attr::ObjCReturnsInnerPointer:
+      return getDerived().TraverseObjCReturnsInnerPointerAttr(cast<ObjCReturnsInnerPointerAttr>(A));
+    case attr::ObjCRootClass:
+      return getDerived().TraverseObjCRootClassAttr(cast<ObjCRootClassAttr>(A));
+    case attr::ObjCRuntimeName:
+      return getDerived().TraverseObjCRuntimeNameAttr(cast<ObjCRuntimeNameAttr>(A));
+    case attr::OpenCLImageAccess:
+      return getDerived().TraverseOpenCLImageAccessAttr(cast<OpenCLImageAccessAttr>(A));
+    case attr::OpenCLKernel:
+      return getDerived().TraverseOpenCLKernelAttr(cast<OpenCLKernelAttr>(A));
+    case attr::OptimizeNone:
+      return getDerived().TraverseOptimizeNoneAttr(cast<OptimizeNoneAttr>(A));
+    case attr::Overloadable:
+      return getDerived().TraverseOverloadableAttr(cast<OverloadableAttr>(A));
+    case attr::Override:
+      return getDerived().TraverseOverrideAttr(cast<OverrideAttr>(A));
+    case attr::Ownership:
+      return getDerived().TraverseOwnershipAttr(cast<OwnershipAttr>(A));
+    case attr::Packed:
+      return getDerived().TraversePackedAttr(cast<PackedAttr>(A));
+    case attr::ParamTypestate:
+      return getDerived().TraverseParamTypestateAttr(cast<ParamTypestateAttr>(A));
+    case attr::Pascal:
+      return getDerived().TraversePascalAttr(cast<PascalAttr>(A));
+    case attr::Pcs:
+      return getDerived().TraversePcsAttr(cast<PcsAttr>(A));
+    case attr::PnaclCall:
+      return getDerived().TraversePnaclCallAttr(cast<PnaclCallAttr>(A));
+    case attr::PtGuardedBy:
+      return getDerived().TraversePtGuardedByAttr(cast<PtGuardedByAttr>(A));
+    case attr::PtGuardedVar:
+      return getDerived().TraversePtGuardedVarAttr(cast<PtGuardedVarAttr>(A));
+    case attr::Pure:
+      return getDerived().TraversePureAttr(cast<PureAttr>(A));
+    case attr::ReleaseCapability:
+      return getDerived().TraverseReleaseCapabilityAttr(cast<ReleaseCapabilityAttr>(A));
+    case attr::ReqdWorkGroupSize:
+      return getDerived().TraverseReqdWorkGroupSizeAttr(cast<ReqdWorkGroupSizeAttr>(A));
+    case attr::RequiresCapability:
+      return getDerived().TraverseRequiresCapabilityAttr(cast<RequiresCapabilityAttr>(A));
+    case attr::ReturnTypestate:
+      return getDerived().TraverseReturnTypestateAttr(cast<ReturnTypestateAttr>(A));
+    case attr::ReturnsNonNull:
+      return getDerived().TraverseReturnsNonNullAttr(cast<ReturnsNonNullAttr>(A));
+    case attr::ReturnsTwice:
+      return getDerived().TraverseReturnsTwiceAttr(cast<ReturnsTwiceAttr>(A));
+    case attr::ScopedLockable:
+      return getDerived().TraverseScopedLockableAttr(cast<ScopedLockableAttr>(A));
+    case attr::Section:
+      return getDerived().TraverseSectionAttr(cast<SectionAttr>(A));
+    case attr::SelectAny:
+      return getDerived().TraverseSelectAnyAttr(cast<SelectAnyAttr>(A));
+    case attr::Sentinel:
+      return getDerived().TraverseSentinelAttr(cast<SentinelAttr>(A));
+    case attr::SetTypestate:
+      return getDerived().TraverseSetTypestateAttr(cast<SetTypestateAttr>(A));
+    case attr::SharedTrylockFunction:
+      return getDerived().TraverseSharedTrylockFunctionAttr(cast<SharedTrylockFunctionAttr>(A));
+    case attr::StdCall:
+      return getDerived().TraverseStdCallAttr(cast<StdCallAttr>(A));
+    case attr::SysVABI:
+      return getDerived().TraverseSysVABIAttr(cast<SysVABIAttr>(A));
+    case attr::TLSModel:
+      return getDerived().TraverseTLSModelAttr(cast<TLSModelAttr>(A));
+    case attr::TestTypestate:
+      return getDerived().TraverseTestTypestateAttr(cast<TestTypestateAttr>(A));
+    case attr::ThisCall:
+      return getDerived().TraverseThisCallAttr(cast<ThisCallAttr>(A));
+    case attr::Thread:
+      return getDerived().TraverseThreadAttr(cast<ThreadAttr>(A));
+    case attr::TransparentUnion:
+      return getDerived().TraverseTransparentUnionAttr(cast<TransparentUnionAttr>(A));
+    case attr::TryAcquireCapability:
+      return getDerived().TraverseTryAcquireCapabilityAttr(cast<TryAcquireCapabilityAttr>(A));
+    case attr::TypeTagForDatatype:
+      return getDerived().TraverseTypeTagForDatatypeAttr(cast<TypeTagForDatatypeAttr>(A));
+    case attr::TypeVisibility:
+      return getDerived().TraverseTypeVisibilityAttr(cast<TypeVisibilityAttr>(A));
+    case attr::Unavailable:
+      return getDerived().TraverseUnavailableAttr(cast<UnavailableAttr>(A));
+    case attr::Unused:
+      return getDerived().TraverseUnusedAttr(cast<UnusedAttr>(A));
+    case attr::Used:
+      return getDerived().TraverseUsedAttr(cast<UsedAttr>(A));
+    case attr::Uuid:
+      return getDerived().TraverseUuidAttr(cast<UuidAttr>(A));
+    case attr::VecReturn:
+      return getDerived().TraverseVecReturnAttr(cast<VecReturnAttr>(A));
+    case attr::VecTypeHint:
+      return getDerived().TraverseVecTypeHintAttr(cast<VecTypeHintAttr>(A));
+    case attr::Visibility:
+      return getDerived().TraverseVisibilityAttr(cast<VisibilityAttr>(A));
+    case attr::WarnUnused:
+      return getDerived().TraverseWarnUnusedAttr(cast<WarnUnusedAttr>(A));
+    case attr::WarnUnusedResult:
+      return getDerived().TraverseWarnUnusedResultAttr(cast<WarnUnusedResultAttr>(A));
+    case attr::Weak:
+      return getDerived().TraverseWeakAttr(cast<WeakAttr>(A));
+    case attr::WeakImport:
+      return getDerived().TraverseWeakImportAttr(cast<WeakImportAttr>(A));
+    case attr::WeakRef:
+      return getDerived().TraverseWeakRefAttr(cast<WeakRefAttr>(A));
+    case attr::WorkGroupSizeHint:
+      return getDerived().TraverseWorkGroupSizeHintAttr(cast<WorkGroupSizeHintAttr>(A));
+    case attr::X86ForceAlignArgPointer:
+      return getDerived().TraverseX86ForceAlignArgPointerAttr(cast<X86ForceAlignArgPointerAttr>(A));
+  }
+}
+#endif  // ATTR_VISITOR_DECLS_ONLY
diff --git a/include/clang/AST/Attrs.inc b/include/clang/AST/Attrs.inc
new file mode 100644
index 0000000..46592a7
--- /dev/null
+++ b/include/clang/AST/Attrs.inc
@@ -0,0 +1,6249 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute classes' definitions                                              *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_ATTR_CLASSES_INC
+#define LLVM_CLANG_ATTR_CLASSES_INC
+
+class ARMInterruptAttr : public InheritableAttr {
+public:
+  enum InterruptType {
+    IRQ,
+    FIQ,
+    SWI,
+    ABORT,
+    UNDEF,
+    Generic
+  };
+private:
+  InterruptType interrupt;
+
+
+public:
+  static ARMInterruptAttr *CreateImplicit(ASTContext &Ctx, InterruptType Interrupt, SourceRange Loc = SourceRange()) {
+    ARMInterruptAttr *A = new (Ctx) ARMInterruptAttr(Loc, Ctx, Interrupt, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ARMInterruptAttr(SourceRange R, ASTContext &Ctx
+              , InterruptType Interrupt
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ARMInterrupt, R, SI)
+              , interrupt(Interrupt)
+  {
+
+  }
+
+  ARMInterruptAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ARMInterrupt, R, SI)
+              , interrupt(InterruptType(0))
+  {
+  }
+
+  ARMInterruptAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  InterruptType getInterrupt() const {
+    return interrupt;
+  }
+
+  static bool ConvertStrToInterruptType(StringRef Val, InterruptType &Out) {
+    Optional<InterruptType> R = llvm::StringSwitch<Optional<InterruptType>>(Val)
+      .Case("IRQ", ARMInterruptAttr::IRQ)
+      .Case("FIQ", ARMInterruptAttr::FIQ)
+      .Case("SWI", ARMInterruptAttr::SWI)
+      .Case("ABORT", ARMInterruptAttr::ABORT)
+      .Case("UNDEF", ARMInterruptAttr::UNDEF)
+      .Case("", ARMInterruptAttr::Generic)
+      .Default(Optional<InterruptType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ARMInterrupt; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AcquireCapabilityAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  enum Spelling {
+    GNU_acquire_capability,
+    CXX11_clang_acquire_capability,
+    GNU_acquire_shared_capability,
+    CXX11_clang_acquire_shared_capability,
+    GNU_exclusive_lock_function,
+    GNU_shared_lock_function
+  };
+
+  static AcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    AcquireCapabilityAttr *A = new (Ctx) AcquireCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquireCapability, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  AcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquireCapability, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  AcquireCapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_acquire_capability;
+    case 1: return CXX11_clang_acquire_capability;
+    case 2: return GNU_acquire_shared_capability;
+    case 3: return CXX11_clang_acquire_shared_capability;
+    case 4: return GNU_exclusive_lock_function;
+    case 5: return GNU_shared_lock_function;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3 ||
+    SpellingListIndex == 5; }
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AcquireCapability; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AcquiredAfterAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static AcquiredAfterAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    AcquiredAfterAttr *A = new (Ctx) AcquiredAfterAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AcquiredAfterAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquiredAfter, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  AcquiredAfterAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquiredAfter, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  AcquiredAfterAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredAfter; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AcquiredBeforeAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static AcquiredBeforeAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    AcquiredBeforeAttr *A = new (Ctx) AcquiredBeforeAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquiredBefore, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  AcquiredBeforeAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AcquiredBefore, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  AcquiredBeforeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AcquiredBefore; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AliasAttr : public Attr {
+unsigned aliaseeLength;
+char *aliasee;
+
+
+public:
+  static AliasAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) {
+    AliasAttr *A = new (Ctx) AliasAttr(Loc, Ctx, Aliasee, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AliasAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Aliasee
+              , unsigned SI
+             )
+    : Attr(attr::Alias, R, SI)
+              , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
+  {
+      std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
+  }
+
+  AliasAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getAliasee() const {
+    return llvm::StringRef(aliasee, aliaseeLength);
+  }
+  unsigned getAliaseeLength() const {
+    return aliaseeLength;
+  }
+  void setAliasee(ASTContext &C, llvm::StringRef S) {
+    aliaseeLength = S.size();
+    this->aliasee = new (C, 1) char [aliaseeLength];
+    std::memcpy(this->aliasee, S.data(), aliaseeLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AlignMac68kAttr : public InheritableAttr {
+
+public:
+  static AlignMac68kAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    AlignMac68kAttr *A = new (Ctx) AlignMac68kAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AlignMac68kAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AlignMac68k, R, SI)
+  {
+  }
+
+  AlignMac68kAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AlignMac68k; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AlignedAttr : public InheritableAttr {
+bool isalignmentExpr;
+union {
+Expr *alignmentExpr;
+TypeSourceInfo *alignmentType;
+};
+
+
+public:
+  enum Spelling {
+    GNU_aligned,
+    CXX11_gnu_aligned,
+    Declspec_align,
+    Keyword_alignas,
+    Keyword_Alignas
+  };
+
+  static AlignedAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool IsAlignmentExpr, void *Alignment, SourceRange Loc = SourceRange()) {
+    AlignedAttr *A = new (Ctx) AlignedAttr(Loc, Ctx, IsAlignmentExpr, Alignment, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AlignedAttr(SourceRange R, ASTContext &Ctx
+              , bool IsAlignmentExpr, void *Alignment
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Aligned, R, SI)
+              , isalignmentExpr(IsAlignmentExpr)
+  {
+    if (isalignmentExpr)
+       alignmentExpr = reinterpret_cast<Expr *>(Alignment);
+    else
+       alignmentType = reinterpret_cast<TypeSourceInfo *>(Alignment);
+  }
+
+  AlignedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Aligned, R, SI)
+              , isalignmentExpr(false)
+  {
+  }
+
+  AlignedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_aligned;
+    case 1: return CXX11_gnu_aligned;
+    case 2: return Declspec_align;
+    case 3: return Keyword_alignas;
+    case 4: return Keyword_Alignas;
+  }
+  }
+  bool isGNU() const { return SpellingListIndex == 0 ||
+    SpellingListIndex == 1; }
+  bool isC11() const { return SpellingListIndex == 4; }
+  bool isAlignas() const { return SpellingListIndex == 3 ||
+    SpellingListIndex == 4; }
+  bool isDeclspec() const { return SpellingListIndex == 2; }
+  bool isAlignmentDependent() const;
+  unsigned getAlignment(ASTContext &Ctx) const;
+  bool isAlignmentExpr() const {
+    return isalignmentExpr;
+  }
+  Expr *getAlignmentExpr() const {
+    assert(isalignmentExpr);
+    return alignmentExpr;
+  }
+  TypeSourceInfo *getAlignmentType() const {
+    assert(!isalignmentExpr);
+    return alignmentType;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Aligned; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AlwaysInlineAttr : public InheritableAttr {
+
+public:
+  enum Spelling {
+    GNU_always_inline,
+    CXX11_gnu_always_inline,
+    Keyword_forceinline
+  };
+
+  static AlwaysInlineAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
+    AlwaysInlineAttr *A = new (Ctx) AlwaysInlineAttr(Loc, Ctx, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AlwaysInlineAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AlwaysInline, R, SI)
+  {
+  }
+
+  AlwaysInlineAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_always_inline;
+    case 1: return CXX11_gnu_always_inline;
+    case 2: return Keyword_forceinline;
+  }
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AlwaysInline; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AnalyzerNoReturnAttr : public InheritableAttr {
+
+public:
+  static AnalyzerNoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    AnalyzerNoReturnAttr *A = new (Ctx) AnalyzerNoReturnAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AnalyzerNoReturnAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AnalyzerNoReturn, R, SI)
+  {
+  }
+
+  AnalyzerNoReturnAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AnalyzerNoReturn; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AnnotateAttr : public InheritableParamAttr {
+unsigned annotationLength;
+char *annotation;
+
+
+public:
+  static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, SourceRange Loc = SourceRange()) {
+    AnnotateAttr *A = new (Ctx) AnnotateAttr(Loc, Ctx, Annotation, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AnnotateAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Annotation
+              , unsigned SI
+             )
+    : InheritableParamAttr(attr::Annotate, R, SI)
+              , annotationLength(Annotation.size()),annotation(new (Ctx, 1) char[annotationLength])
+  {
+      std::memcpy(annotation, Annotation.data(), annotationLength);
+  }
+
+  AnnotateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getAnnotation() const {
+    return llvm::StringRef(annotation, annotationLength);
+  }
+  unsigned getAnnotationLength() const {
+    return annotationLength;
+  }
+  void setAnnotation(ASTContext &C, llvm::StringRef S) {
+    annotationLength = S.size();
+    this->annotation = new (C, 1) char [annotationLength];
+    std::memcpy(this->annotation, S.data(), annotationLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Annotate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ArcWeakrefUnavailableAttr : public InheritableAttr {
+
+public:
+  static ArcWeakrefUnavailableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ArcWeakrefUnavailableAttr *A = new (Ctx) ArcWeakrefUnavailableAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ArcWeakrefUnavailableAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ArcWeakrefUnavailable, R, SI)
+  {
+  }
+
+  ArcWeakrefUnavailableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ArcWeakrefUnavailable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ArgumentWithTypeTagAttr : public InheritableAttr {
+IdentifierInfo * argumentKind;
+
+unsigned argumentIdx;
+
+unsigned typeTagIdx;
+
+bool isPointer;
+
+
+public:
+  enum Spelling {
+    GNU_argument_with_type_tag,
+    GNU_pointer_with_type_tag
+  };
+
+  static ArgumentWithTypeTagAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * ArgumentKind, unsigned ArgumentIdx, unsigned TypeTagIdx, bool IsPointer, SourceRange Loc = SourceRange()) {
+    ArgumentWithTypeTagAttr *A = new (Ctx) ArgumentWithTypeTagAttr(Loc, Ctx, ArgumentKind, ArgumentIdx, TypeTagIdx, IsPointer, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ArgumentWithTypeTagAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * ArgumentKind
+              , unsigned ArgumentIdx
+              , unsigned TypeTagIdx
+              , bool IsPointer
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ArgumentWithTypeTag, R, SI)
+              , argumentKind(ArgumentKind)
+              , argumentIdx(ArgumentIdx)
+              , typeTagIdx(TypeTagIdx)
+              , isPointer(IsPointer)
+  {
+
+
+
+
+  }
+
+  ArgumentWithTypeTagAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_argument_with_type_tag;
+    case 1: return GNU_pointer_with_type_tag;
+  }
+  }
+  IdentifierInfo * getArgumentKind() const {
+    return argumentKind;
+  }
+
+  unsigned getArgumentIdx() const {
+    return argumentIdx;
+  }
+
+  unsigned getTypeTagIdx() const {
+    return typeTagIdx;
+  }
+
+  bool getIsPointer() const {
+    return isPointer;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ArgumentWithTypeTag; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AsmLabelAttr : public InheritableAttr {
+unsigned labelLength;
+char *label;
+
+
+public:
+  static AsmLabelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Label, SourceRange Loc = SourceRange()) {
+    AsmLabelAttr *A = new (Ctx) AsmLabelAttr(Loc, Ctx, Label, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AsmLabelAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Label
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AsmLabel, R, SI)
+              , labelLength(Label.size()),label(new (Ctx, 1) char[labelLength])
+  {
+      std::memcpy(label, Label.data(), labelLength);
+  }
+
+  AsmLabelAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getLabel() const {
+    return llvm::StringRef(label, labelLength);
+  }
+  unsigned getLabelLength() const {
+    return labelLength;
+  }
+  void setLabel(ASTContext &C, llvm::StringRef S) {
+    labelLength = S.size();
+    this->label = new (C, 1) char [labelLength];
+    std::memcpy(this->label, S.data(), labelLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AsmLabel; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class AssertCapabilityAttr : public InheritableAttr {
+Expr * expr;
+
+
+public:
+  enum Spelling {
+    GNU_assert_capability,
+    CXX11_clang_assert_capability,
+    GNU_assert_shared_capability,
+    CXX11_clang_assert_shared_capability
+  };
+
+  static AssertCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * Expr, SourceRange Loc = SourceRange()) {
+    AssertCapabilityAttr *A = new (Ctx) AssertCapabilityAttr(Loc, Ctx, Expr, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AssertCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * Expr
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AssertCapability, R, SI)
+              , expr(Expr)
+  {
+
+  }
+
+  AssertCapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_assert_capability;
+    case 1: return CXX11_clang_assert_capability;
+    case 2: return GNU_assert_shared_capability;
+    case 3: return CXX11_clang_assert_shared_capability;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3; }
+  Expr * getExpr() const {
+    return expr;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AssertCapability; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AssertExclusiveLockAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static AssertExclusiveLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    AssertExclusiveLockAttr *A = new (Ctx) AssertExclusiveLockAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AssertExclusiveLock, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  AssertExclusiveLockAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AssertExclusiveLock, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  AssertExclusiveLockAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AssertExclusiveLock; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AssertSharedLockAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static AssertSharedLockAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    AssertSharedLockAttr *A = new (Ctx) AssertSharedLockAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AssertSharedLockAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AssertSharedLock, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  AssertSharedLockAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::AssertSharedLock, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  AssertSharedLockAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::AssertSharedLock; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class AvailabilityAttr : public InheritableAttr {
+IdentifierInfo * platform;
+
+VersionTuple introduced;
+
+
+VersionTuple deprecated;
+
+
+VersionTuple obsoleted;
+
+
+bool unavailable;
+
+unsigned messageLength;
+char *message;
+
+
+public:
+  static AvailabilityAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Platform, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool Unavailable, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
+    AvailabilityAttr *A = new (Ctx) AvailabilityAttr(Loc, Ctx, Platform, Introduced, Deprecated, Obsoleted, Unavailable, Message, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  AvailabilityAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * Platform
+              , VersionTuple Introduced
+              , VersionTuple Deprecated
+              , VersionTuple Obsoleted
+              , bool Unavailable
+              , llvm::StringRef Message
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Availability, R, SI)
+              , platform(Platform)
+              , introduced(Introduced)
+              , deprecated(Deprecated)
+              , obsoleted(Obsoleted)
+              , unavailable(Unavailable)
+              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
+  {
+
+
+
+
+
+      std::memcpy(message, Message.data(), messageLength);
+  }
+
+  AvailabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getPlatform() const {
+    return platform;
+  }
+
+  VersionTuple getIntroduced() const {
+    return introduced;
+  }
+  void setIntroduced(ASTContext &C, VersionTuple V) {
+    introduced = V;
+  }
+
+  VersionTuple getDeprecated() const {
+    return deprecated;
+  }
+  void setDeprecated(ASTContext &C, VersionTuple V) {
+    deprecated = V;
+  }
+
+  VersionTuple getObsoleted() const {
+    return obsoleted;
+  }
+  void setObsoleted(ASTContext &C, VersionTuple V) {
+    obsoleted = V;
+  }
+
+  bool getUnavailable() const {
+    return unavailable;
+  }
+
+  llvm::StringRef getMessage() const {
+    return llvm::StringRef(message, messageLength);
+  }
+  unsigned getMessageLength() const {
+    return messageLength;
+  }
+  void setMessage(ASTContext &C, llvm::StringRef S) {
+    messageLength = S.size();
+    this->message = new (C, 1) char [messageLength];
+    std::memcpy(this->message, S.data(), messageLength);
+  }
+
+static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
+    return llvm::StringSwitch<llvm::StringRef>(Platform)
+             .Case("ios", "iOS")
+             .Case("macosx", "OS X")
+             .Default(llvm::StringRef());
+} 
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Availability; }
+  bool isLateParsed() const override { return 0; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class BlocksAttr : public InheritableAttr {
+public:
+  enum BlockType {
+    ByRef
+  };
+private:
+  BlockType type;
+
+
+public:
+  static BlocksAttr *CreateImplicit(ASTContext &Ctx, BlockType Type, SourceRange Loc = SourceRange()) {
+    BlocksAttr *A = new (Ctx) BlocksAttr(Loc, Ctx, Type, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  BlocksAttr(SourceRange R, ASTContext &Ctx
+              , BlockType Type
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Blocks, R, SI)
+              , type(Type)
+  {
+
+  }
+
+  BlocksAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  BlockType getType() const {
+    return type;
+  }
+
+  static bool ConvertStrToBlockType(StringRef Val, BlockType &Out) {
+    Optional<BlockType> R = llvm::StringSwitch<Optional<BlockType>>(Val)
+      .Case("byref", BlocksAttr::ByRef)
+      .Default(Optional<BlockType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class C11NoReturnAttr : public InheritableAttr {
+
+public:
+  static C11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    C11NoReturnAttr *A = new (Ctx) C11NoReturnAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  C11NoReturnAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::C11NoReturn, R, SI)
+  {
+  }
+
+  C11NoReturnAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::C11NoReturn; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CDeclAttr : public InheritableAttr {
+
+public:
+  static CDeclAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CDeclAttr *A = new (Ctx) CDeclAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CDeclAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CDecl, R, SI)
+  {
+  }
+
+  CDeclAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CDecl; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CFAuditedTransferAttr : public InheritableAttr {
+
+public:
+  static CFAuditedTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CFAuditedTransferAttr *A = new (Ctx) CFAuditedTransferAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CFAuditedTransferAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CFAuditedTransfer, R, SI)
+  {
+  }
+
+  CFAuditedTransferAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CFAuditedTransfer; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CFConsumedAttr : public InheritableParamAttr {
+
+public:
+  static CFConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CFConsumedAttr *A = new (Ctx) CFConsumedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CFConsumedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableParamAttr(attr::CFConsumed, R, SI)
+  {
+  }
+
+  CFConsumedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CFConsumed; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CFReturnsNotRetainedAttr : public InheritableAttr {
+
+public:
+  static CFReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CFReturnsNotRetainedAttr *A = new (Ctx) CFReturnsNotRetainedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CFReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CFReturnsNotRetained, R, SI)
+  {
+  }
+
+  CFReturnsNotRetainedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsNotRetained; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CFReturnsRetainedAttr : public InheritableAttr {
+
+public:
+  static CFReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CFReturnsRetainedAttr *A = new (Ctx) CFReturnsRetainedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CFReturnsRetainedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CFReturnsRetained, R, SI)
+  {
+  }
+
+  CFReturnsRetainedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CFReturnsRetained; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CFUnknownTransferAttr : public InheritableAttr {
+
+public:
+  static CFUnknownTransferAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CFUnknownTransferAttr *A = new (Ctx) CFUnknownTransferAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CFUnknownTransferAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CFUnknownTransfer, R, SI)
+  {
+  }
+
+  CFUnknownTransferAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CFUnknownTransfer; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDAConstantAttr : public InheritableAttr {
+
+public:
+  static CUDAConstantAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CUDAConstantAttr *A = new (Ctx) CUDAConstantAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDAConstantAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDAConstant, R, SI)
+  {
+  }
+
+  CUDAConstantAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDAConstant; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDADeviceAttr : public InheritableAttr {
+
+public:
+  static CUDADeviceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CUDADeviceAttr *A = new (Ctx) CUDADeviceAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDADeviceAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDADevice, R, SI)
+  {
+  }
+
+  CUDADeviceAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDADevice; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDAGlobalAttr : public InheritableAttr {
+
+public:
+  static CUDAGlobalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CUDAGlobalAttr *A = new (Ctx) CUDAGlobalAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDAGlobalAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDAGlobal, R, SI)
+  {
+  }
+
+  CUDAGlobalAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDAGlobal; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDAHostAttr : public InheritableAttr {
+
+public:
+  static CUDAHostAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CUDAHostAttr *A = new (Ctx) CUDAHostAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDAHostAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDAHost, R, SI)
+  {
+  }
+
+  CUDAHostAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDAHost; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDALaunchBoundsAttr : public InheritableAttr {
+int maxThreads;
+
+int minBlocks;
+
+
+public:
+  static CUDALaunchBoundsAttr *CreateImplicit(ASTContext &Ctx, int MaxThreads, int MinBlocks, SourceRange Loc = SourceRange()) {
+    CUDALaunchBoundsAttr *A = new (Ctx) CUDALaunchBoundsAttr(Loc, Ctx, MaxThreads, MinBlocks, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx
+              , int MaxThreads
+              , int MinBlocks
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDALaunchBounds, R, SI)
+              , maxThreads(MaxThreads)
+              , minBlocks(MinBlocks)
+  {
+
+
+  }
+
+  CUDALaunchBoundsAttr(SourceRange R, ASTContext &Ctx
+              , int MaxThreads
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDALaunchBounds, R, SI)
+              , maxThreads()
+              , minBlocks()
+  {
+
+  }
+
+  CUDALaunchBoundsAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  int getMaxThreads() const {
+    return maxThreads;
+  }
+
+  int getMinBlocks() const {
+    return minBlocks;
+  }
+
+  static const int DefaultMinBlocks = 0;
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDALaunchBounds; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CUDASharedAttr : public InheritableAttr {
+
+public:
+  static CUDASharedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CUDASharedAttr *A = new (Ctx) CUDASharedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CUDASharedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CUDAShared, R, SI)
+  {
+  }
+
+  CUDASharedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CUDAShared; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CXX11NoReturnAttr : public InheritableAttr {
+
+public:
+  static CXX11NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CXX11NoReturnAttr *A = new (Ctx) CXX11NoReturnAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CXX11NoReturnAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CXX11NoReturn, R, SI)
+  {
+  }
+
+  CXX11NoReturnAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CXX11NoReturn; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CallableWhenAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Unknown,
+    Consumed,
+    Unconsumed
+  };
+private:
+  unsigned callableStates_Size;
+  ConsumedState *callableStates_;
+
+
+public:
+  static CallableWhenAttr *CreateImplicit(ASTContext &Ctx, ConsumedState *CallableStates, unsigned CallableStatesSize, SourceRange Loc = SourceRange()) {
+    CallableWhenAttr *A = new (Ctx) CallableWhenAttr(Loc, Ctx, CallableStates, CallableStatesSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CallableWhenAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState *CallableStates, unsigned CallableStatesSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CallableWhen, R, SI)
+              , callableStates_Size(CallableStatesSize), callableStates_(new (Ctx, 16) ConsumedState[callableStates_Size])
+  {
+    std::copy(CallableStates, CallableStates + callableStates_Size, callableStates_);
+  }
+
+  CallableWhenAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::CallableWhen, R, SI)
+              , callableStates_Size(0), callableStates_(nullptr)
+  {
+  }
+
+  CallableWhenAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef ConsumedState* callableStates_iterator;
+  callableStates_iterator callableStates_begin() const { return callableStates_; }
+  callableStates_iterator callableStates_end() const { return callableStates_ + callableStates_Size; }
+  unsigned callableStates_size() const { return callableStates_Size; }
+  llvm::iterator_range<callableStates_iterator> callableStates() const { return llvm::make_range(callableStates_begin(), callableStates_end()); }
+
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("unknown", CallableWhenAttr::Unknown)
+      .Case("consumed", CallableWhenAttr::Consumed)
+      .Case("unconsumed", CallableWhenAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CallableWhen; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CapabilityAttr : public InheritableAttr {
+unsigned nameLength;
+char *name;
+
+
+public:
+  enum Spelling {
+    GNU_capability,
+    CXX11_clang_capability,
+    GNU_shared_capability,
+    CXX11_clang_shared_capability
+  };
+
+  static CapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
+    CapabilityAttr *A = new (Ctx) CapabilityAttr(Loc, Ctx, Name, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CapabilityAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Name
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Capability, R, SI)
+              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
+  {
+      std::memcpy(name, Name.data(), nameLength);
+  }
+
+  CapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_capability;
+    case 1: return CXX11_clang_capability;
+    case 2: return GNU_shared_capability;
+    case 3: return CXX11_clang_shared_capability;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3; }
+  llvm::StringRef getName() const {
+    return llvm::StringRef(name, nameLength);
+  }
+  unsigned getNameLength() const {
+    return nameLength;
+  }
+  void setName(ASTContext &C, llvm::StringRef S) {
+    nameLength = S.size();
+    this->name = new (C, 1) char [nameLength];
+    std::memcpy(this->name, S.data(), nameLength);
+  }
+
+
+    bool isMutex() const { return getName().equals_lower("mutex"); }
+    bool isRole() const { return getName().equals_lower("role"); }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Capability; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CarriesDependencyAttr : public InheritableParamAttr {
+
+public:
+  static CarriesDependencyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CarriesDependencyAttr *A = new (Ctx) CarriesDependencyAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CarriesDependencyAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableParamAttr(attr::CarriesDependency, R, SI)
+  {
+  }
+
+  CarriesDependencyAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::CarriesDependency; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CleanupAttr : public InheritableAttr {
+FunctionDecl * functionDecl;
+
+
+public:
+  static CleanupAttr *CreateImplicit(ASTContext &Ctx, FunctionDecl * FunctionDecl, SourceRange Loc = SourceRange()) {
+    CleanupAttr *A = new (Ctx) CleanupAttr(Loc, Ctx, FunctionDecl, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CleanupAttr(SourceRange R, ASTContext &Ctx
+              , FunctionDecl * FunctionDecl
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Cleanup, R, SI)
+              , functionDecl(FunctionDecl)
+  {
+
+  }
+
+  CleanupAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  FunctionDecl * getFunctionDecl() const {
+    return functionDecl;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ColdAttr : public InheritableAttr {
+
+public:
+  static ColdAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ColdAttr *A = new (Ctx) ColdAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ColdAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Cold, R, SI)
+  {
+  }
+
+  ColdAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Cold; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class CommonAttr : public InheritableAttr {
+
+public:
+  static CommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    CommonAttr *A = new (Ctx) CommonAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  CommonAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Common, R, SI)
+  {
+  }
+
+  CommonAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Common; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ConstAttr : public InheritableAttr {
+
+public:
+  static ConstAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ConstAttr *A = new (Ctx) ConstAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ConstAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Const, R, SI)
+  {
+  }
+
+  ConstAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Const; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ConstructorAttr : public InheritableAttr {
+int priority;
+
+
+public:
+  static ConstructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) {
+    ConstructorAttr *A = new (Ctx) ConstructorAttr(Loc, Ctx, Priority, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ConstructorAttr(SourceRange R, ASTContext &Ctx
+              , int Priority
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Constructor, R, SI)
+              , priority(Priority)
+  {
+
+  }
+
+  ConstructorAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Constructor, R, SI)
+              , priority()
+  {
+  }
+
+  ConstructorAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  int getPriority() const {
+    return priority;
+  }
+
+  static const int DefaultPriority = 65535;
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Constructor; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ConsumableAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Unknown,
+    Consumed,
+    Unconsumed
+  };
+private:
+  ConsumedState defaultState;
+
+
+public:
+  static ConsumableAttr *CreateImplicit(ASTContext &Ctx, ConsumedState DefaultState, SourceRange Loc = SourceRange()) {
+    ConsumableAttr *A = new (Ctx) ConsumableAttr(Loc, Ctx, DefaultState, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ConsumableAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState DefaultState
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Consumable, R, SI)
+              , defaultState(DefaultState)
+  {
+
+  }
+
+  ConsumableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  ConsumedState getDefaultState() const {
+    return defaultState;
+  }
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("unknown", ConsumableAttr::Unknown)
+      .Case("consumed", ConsumableAttr::Consumed)
+      .Case("unconsumed", ConsumableAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Consumable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ConsumableAutoCastAttr : public InheritableAttr {
+
+public:
+  static ConsumableAutoCastAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ConsumableAutoCastAttr *A = new (Ctx) ConsumableAutoCastAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ConsumableAutoCastAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ConsumableAutoCast, R, SI)
+  {
+  }
+
+  ConsumableAutoCastAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableAutoCast; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ConsumableSetOnReadAttr : public InheritableAttr {
+
+public:
+  static ConsumableSetOnReadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ConsumableSetOnReadAttr *A = new (Ctx) ConsumableSetOnReadAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ConsumableSetOnReadAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ConsumableSetOnRead, R, SI)
+  {
+  }
+
+  ConsumableSetOnReadAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ConsumableSetOnRead; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class DLLExportAttr : public InheritableAttr {
+
+public:
+  static DLLExportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    DLLExportAttr *A = new (Ctx) DLLExportAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  DLLExportAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::DLLExport, R, SI)
+  {
+  }
+
+  DLLExportAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::DLLExport; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class DLLImportAttr : public InheritableAttr {
+
+public:
+  static DLLImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    DLLImportAttr *A = new (Ctx) DLLImportAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  DLLImportAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::DLLImport, R, SI)
+  {
+  }
+
+  DLLImportAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::DLLImport; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class DeprecatedAttr : public InheritableAttr {
+unsigned messageLength;
+char *message;
+
+
+public:
+  static DeprecatedAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
+    DeprecatedAttr *A = new (Ctx) DeprecatedAttr(Loc, Ctx, Message, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  DeprecatedAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Message
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Deprecated, R, SI)
+              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
+  {
+      std::memcpy(message, Message.data(), messageLength);
+  }
+
+  DeprecatedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Deprecated, R, SI)
+              , messageLength(0),message(0)
+  {
+  }
+
+  DeprecatedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getMessage() const {
+    return llvm::StringRef(message, messageLength);
+  }
+  unsigned getMessageLength() const {
+    return messageLength;
+  }
+  void setMessage(ASTContext &C, llvm::StringRef S) {
+    messageLength = S.size();
+    this->message = new (C, 1) char [messageLength];
+    std::memcpy(this->message, S.data(), messageLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Deprecated; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class DestructorAttr : public InheritableAttr {
+int priority;
+
+
+public:
+  static DestructorAttr *CreateImplicit(ASTContext &Ctx, int Priority, SourceRange Loc = SourceRange()) {
+    DestructorAttr *A = new (Ctx) DestructorAttr(Loc, Ctx, Priority, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  DestructorAttr(SourceRange R, ASTContext &Ctx
+              , int Priority
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Destructor, R, SI)
+              , priority(Priority)
+  {
+
+  }
+
+  DestructorAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Destructor, R, SI)
+              , priority()
+  {
+  }
+
+  DestructorAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  int getPriority() const {
+    return priority;
+  }
+
+  static const int DefaultPriority = 65535;
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Destructor; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class EnableIfAttr : public InheritableAttr {
+Expr * cond;
+
+unsigned messageLength;
+char *message;
+
+
+public:
+  static EnableIfAttr *CreateImplicit(ASTContext &Ctx, Expr * Cond, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
+    EnableIfAttr *A = new (Ctx) EnableIfAttr(Loc, Ctx, Cond, Message, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  EnableIfAttr(SourceRange R, ASTContext &Ctx
+              , Expr * Cond
+              , llvm::StringRef Message
+              , unsigned SI
+             )
+    : InheritableAttr(attr::EnableIf, R, SI)
+              , cond(Cond)
+              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
+  {
+
+      std::memcpy(message, Message.data(), messageLength);
+  }
+
+  EnableIfAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getCond() const {
+    return cond;
+  }
+
+  llvm::StringRef getMessage() const {
+    return llvm::StringRef(message, messageLength);
+  }
+  unsigned getMessageLength() const {
+    return messageLength;
+  }
+  void setMessage(ASTContext &C, llvm::StringRef S) {
+    messageLength = S.size();
+    this->message = new (C, 1) char [messageLength];
+    std::memcpy(this->message, S.data(), messageLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::EnableIf; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ExclusiveTrylockFunctionAttr : public InheritableAttr {
+Expr * successValue;
+
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static ExclusiveTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    ExclusiveTrylockFunctionAttr *A = new (Ctx) ExclusiveTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI)
+              , successValue(SuccessValue)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  ExclusiveTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ExclusiveTrylockFunction, R, SI)
+              , successValue()
+              , args_Size(0), args_(nullptr)
+  {
+
+  }
+
+  ExclusiveTrylockFunctionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getSuccessValue() const {
+    return successValue;
+  }
+
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ExclusiveTrylockFunction; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class FallThroughAttr : public Attr {
+
+public:
+  static FallThroughAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    FallThroughAttr *A = new (Ctx) FallThroughAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FallThroughAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : Attr(attr::FallThrough, R, SI)
+  {
+  }
+
+  FallThroughAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::FallThrough; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class FastCallAttr : public InheritableAttr {
+
+public:
+  static FastCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    FastCallAttr *A = new (Ctx) FastCallAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FastCallAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::FastCall, R, SI)
+  {
+  }
+
+  FastCallAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::FastCall; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class FinalAttr : public InheritableAttr {
+
+public:
+  enum Spelling {
+    Keyword_final,
+    Keyword_sealed
+  };
+
+  static FinalAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
+    FinalAttr *A = new (Ctx) FinalAttr(Loc, Ctx, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FinalAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Final, R, SI)
+  {
+  }
+
+  FinalAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Keyword_final;
+    case 1: return Keyword_sealed;
+  }
+  }
+  bool isSpelledAsSealed() const { return SpellingListIndex == 1; }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Final; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class FlattenAttr : public InheritableAttr {
+
+public:
+  static FlattenAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    FlattenAttr *A = new (Ctx) FlattenAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FlattenAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Flatten, R, SI)
+  {
+  }
+
+  FlattenAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Flatten; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class FormatAttr : public InheritableAttr {
+IdentifierInfo * type;
+
+int formatIdx;
+
+int firstArg;
+
+
+public:
+  static FormatAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Type, int FormatIdx, int FirstArg, SourceRange Loc = SourceRange()) {
+    FormatAttr *A = new (Ctx) FormatAttr(Loc, Ctx, Type, FormatIdx, FirstArg, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FormatAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * Type
+              , int FormatIdx
+              , int FirstArg
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Format, R, SI)
+              , type(Type)
+              , formatIdx(FormatIdx)
+              , firstArg(FirstArg)
+  {
+
+
+
+  }
+
+  FormatAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getType() const {
+    return type;
+  }
+
+  int getFormatIdx() const {
+    return formatIdx;
+  }
+
+  int getFirstArg() const {
+    return firstArg;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class FormatArgAttr : public InheritableAttr {
+int formatIdx;
+
+
+public:
+  static FormatArgAttr *CreateImplicit(ASTContext &Ctx, int FormatIdx, SourceRange Loc = SourceRange()) {
+    FormatArgAttr *A = new (Ctx) FormatArgAttr(Loc, Ctx, FormatIdx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  FormatArgAttr(SourceRange R, ASTContext &Ctx
+              , int FormatIdx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::FormatArg, R, SI)
+              , formatIdx(FormatIdx)
+  {
+
+  }
+
+  FormatArgAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  int getFormatIdx() const {
+    return formatIdx;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class GNUInlineAttr : public InheritableAttr {
+
+public:
+  static GNUInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    GNUInlineAttr *A = new (Ctx) GNUInlineAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  GNUInlineAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::GNUInline, R, SI)
+  {
+  }
+
+  GNUInlineAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::GNUInline; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class GuardedByAttr : public InheritableAttr {
+Expr * arg;
+
+
+public:
+  static GuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
+    GuardedByAttr *A = new (Ctx) GuardedByAttr(Loc, Ctx, Arg, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  GuardedByAttr(SourceRange R, ASTContext &Ctx
+              , Expr * Arg
+              , unsigned SI
+             )
+    : InheritableAttr(attr::GuardedBy, R, SI)
+              , arg(Arg)
+  {
+
+  }
+
+  GuardedByAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getArg() const {
+    return arg;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::GuardedBy; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class GuardedVarAttr : public InheritableAttr {
+
+public:
+  static GuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    GuardedVarAttr *A = new (Ctx) GuardedVarAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  GuardedVarAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::GuardedVar, R, SI)
+  {
+  }
+
+  GuardedVarAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::GuardedVar; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class HotAttr : public InheritableAttr {
+
+public:
+  static HotAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    HotAttr *A = new (Ctx) HotAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  HotAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Hot, R, SI)
+  {
+  }
+
+  HotAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Hot; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class IBActionAttr : public InheritableAttr {
+
+public:
+  static IBActionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    IBActionAttr *A = new (Ctx) IBActionAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  IBActionAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::IBAction, R, SI)
+  {
+  }
+
+  IBActionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::IBAction; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class IBOutletAttr : public InheritableAttr {
+
+public:
+  static IBOutletAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    IBOutletAttr *A = new (Ctx) IBOutletAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  IBOutletAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::IBOutlet, R, SI)
+  {
+  }
+
+  IBOutletAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::IBOutlet; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class IBOutletCollectionAttr : public InheritableAttr {
+TypeSourceInfo * interface;
+
+
+public:
+  static IBOutletCollectionAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * Interface, SourceRange Loc = SourceRange()) {
+    IBOutletCollectionAttr *A = new (Ctx) IBOutletCollectionAttr(Loc, Ctx, Interface, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx
+              , TypeSourceInfo * Interface
+              , unsigned SI
+             )
+    : InheritableAttr(attr::IBOutletCollection, R, SI)
+              , interface(Interface)
+  {
+
+  }
+
+  IBOutletCollectionAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::IBOutletCollection, R, SI)
+              , interface()
+  {
+  }
+
+  IBOutletCollectionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  QualType getInterface() const {
+    return interface->getType();
+  }  TypeSourceInfo * getInterfaceLoc() const {
+    return interface;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::IBOutletCollection; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class InitPriorityAttr : public InheritableAttr {
+unsigned priority;
+
+
+public:
+  static InitPriorityAttr *CreateImplicit(ASTContext &Ctx, unsigned Priority, SourceRange Loc = SourceRange()) {
+    InitPriorityAttr *A = new (Ctx) InitPriorityAttr(Loc, Ctx, Priority, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  InitPriorityAttr(SourceRange R, ASTContext &Ctx
+              , unsigned Priority
+              , unsigned SI
+             )
+    : InheritableAttr(attr::InitPriority, R, SI)
+              , priority(Priority)
+  {
+
+  }
+
+  InitPriorityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getPriority() const {
+    return priority;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::InitPriority; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class InitSegAttr : public Attr {
+unsigned sectionLength;
+char *section;
+
+
+public:
+  static InitSegAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Section, SourceRange Loc = SourceRange()) {
+    InitSegAttr *A = new (Ctx) InitSegAttr(Loc, Ctx, Section, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  InitSegAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Section
+              , unsigned SI
+             )
+    : Attr(attr::InitSeg, R, SI)
+              , sectionLength(Section.size()),section(new (Ctx, 1) char[sectionLength])
+  {
+      std::memcpy(section, Section.data(), sectionLength);
+  }
+
+  InitSegAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getSection() const {
+    return llvm::StringRef(section, sectionLength);
+  }
+  unsigned getSectionLength() const {
+    return sectionLength;
+  }
+  void setSection(ASTContext &C, llvm::StringRef S) {
+    sectionLength = S.size();
+    this->section = new (C, 1) char [sectionLength];
+    std::memcpy(this->section, S.data(), sectionLength);
+  }
+
+
+  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+    OS << '(' << getSection() << ')';
+  }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::InitSeg; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class IntelOclBiccAttr : public InheritableAttr {
+
+public:
+  static IntelOclBiccAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    IntelOclBiccAttr *A = new (Ctx) IntelOclBiccAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  IntelOclBiccAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::IntelOclBicc, R, SI)
+  {
+  }
+
+  IntelOclBiccAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::IntelOclBicc; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class LockReturnedAttr : public InheritableAttr {
+Expr * arg;
+
+
+public:
+  static LockReturnedAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
+    LockReturnedAttr *A = new (Ctx) LockReturnedAttr(Loc, Ctx, Arg, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  LockReturnedAttr(SourceRange R, ASTContext &Ctx
+              , Expr * Arg
+              , unsigned SI
+             )
+    : InheritableAttr(attr::LockReturned, R, SI)
+              , arg(Arg)
+  {
+
+  }
+
+  LockReturnedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getArg() const {
+    return arg;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::LockReturned; }
+  bool isLateParsed() const override { return 1; }
+};
+
+class LocksExcludedAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static LocksExcludedAttr *CreateImplicit(ASTContext &Ctx, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    LocksExcludedAttr *A = new (Ctx) LocksExcludedAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  LocksExcludedAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::LocksExcluded, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  LocksExcludedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::LocksExcluded, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  LocksExcludedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::LocksExcluded; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class LoopHintAttr : public Attr {
+public:
+  enum OptionType {
+    Vectorize,
+    VectorizeWidth,
+    Interleave,
+    InterleaveCount,
+    Unroll,
+    UnrollCount
+  };
+private:
+  OptionType option;
+
+int value;
+
+
+public:
+  enum Spelling {
+    Pragma_clang_loop,
+    Pragma_unroll
+  };
+
+  static LoopHintAttr *CreateImplicit(ASTContext &Ctx, Spelling S, OptionType Option, int Value, SourceRange Loc = SourceRange()) {
+    LoopHintAttr *A = new (Ctx) LoopHintAttr(Loc, Ctx, Option, Value, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  LoopHintAttr(SourceRange R, ASTContext &Ctx
+              , OptionType Option
+              , int Value
+              , unsigned SI
+             )
+    : Attr(attr::LoopHint, R, SI)
+              , option(Option)
+              , value(Value)
+  {
+
+
+  }
+
+  LoopHintAttr(SourceRange R, ASTContext &Ctx
+              , OptionType Option
+              , unsigned SI
+             )
+    : Attr(attr::LoopHint, R, SI)
+              , option(OptionType(0))
+              , value()
+  {
+
+  }
+
+  LoopHintAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Pragma_clang_loop;
+    case 1: return Pragma_unroll;
+  }
+  }
+  OptionType getOption() const {
+    return option;
+  }
+
+  static bool ConvertStrToOptionType(StringRef Val, OptionType &Out) {
+    Optional<OptionType> R = llvm::StringSwitch<Optional<OptionType>>(Val)
+      .Case("vectorize", LoopHintAttr::Vectorize)
+      .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
+      .Case("interleave", LoopHintAttr::Interleave)
+      .Case("interleave_count", LoopHintAttr::InterleaveCount)
+      .Case("unroll", LoopHintAttr::Unroll)
+      .Case("unroll_count", LoopHintAttr::UnrollCount)
+      .Default(Optional<OptionType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+  int getValue() const {
+    return value;
+  }
+
+  static const int DefaultValue = 1;
+
+
+  static StringRef getOptionName(int Option) {
+    switch(Option) {
+    case Vectorize: return "vectorize";
+    case VectorizeWidth: return "vectorize_width";
+    case Interleave: return "interleave";
+    case InterleaveCount: return "interleave_count";
+    case Unroll: return "unroll";
+    case UnrollCount: return "unroll_count";
+    }
+    llvm_unreachable("Unhandled LoopHint option.");
+  }
+
+  static StringRef getValueName(int Value) {
+    if (Value)
+      return "enable";
+    return "disable";
+  }
+
+  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+    unsigned SpellingIndex = getSpellingListIndex();
+    if (SpellingIndex == Pragma_unroll) {
+      // String "unroll" of "#pragma unroll" is already emitted as the
+      // pragma name.
+      if (option == UnrollCount)
+        printArgument(OS);
+      OS << "\n";
+      return;
+    }
+    assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+    OS << getOptionName(option);
+    printArgument(OS);
+    OS << "\n";
+  }
+
+  // Prints the loop hint argument including the enclosing parentheses to OS.
+  void printArgument(raw_ostream &OS) const {
+    OS << "(";
+    if (option == VectorizeWidth || option == InterleaveCount ||
+        option == UnrollCount)
+      OS << value;
+    else if (value)
+      OS << "enable";
+    else
+      OS << "disable";
+    OS << ")";
+  }
+
+  // Return a string suitable for identifying this attribute in diagnostics.
+  std::string getDiagnosticName() const {
+    std::string DiagnosticName;
+    llvm::raw_string_ostream OS(DiagnosticName);
+    unsigned SpellingIndex = getSpellingListIndex();
+    if (SpellingIndex == Pragma_unroll && option == Unroll)
+      OS << "#pragma unroll";
+    else if (SpellingIndex == Pragma_unroll && option == UnrollCount) {
+      OS << "#pragma unroll";
+      printArgument(OS);
+    } else {
+      assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+      OS << getOptionName(option);
+      printArgument(OS);
+    }
+    return OS.str();
+  }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::LoopHint; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MSABIAttr : public InheritableAttr {
+
+public:
+  static MSABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    MSABIAttr *A = new (Ctx) MSABIAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MSABIAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MSABI, R, SI)
+  {
+  }
+
+  MSABIAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MSABI; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MSInheritanceAttr : public InheritableAttr {
+bool bestCase;
+
+
+public:
+  enum Spelling {
+    Keyword_single_inheritance,
+    Keyword_multiple_inheritance,
+    Keyword_virtual_inheritance,
+    Keyword_unspecified_inheritance
+  };
+
+  static MSInheritanceAttr *CreateImplicit(ASTContext &Ctx, Spelling S, bool BestCase, SourceRange Loc = SourceRange()) {
+    MSInheritanceAttr *A = new (Ctx) MSInheritanceAttr(Loc, Ctx, BestCase, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MSInheritanceAttr(SourceRange R, ASTContext &Ctx
+              , bool BestCase
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MSInheritance, R, SI)
+              , bestCase(BestCase)
+  {
+
+  }
+
+  MSInheritanceAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MSInheritance, R, SI)
+              , bestCase()
+  {
+  }
+
+  MSInheritanceAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Keyword_single_inheritance;
+    case 1: return Keyword_multiple_inheritance;
+    case 2: return Keyword_virtual_inheritance;
+    case 3: return Keyword_unspecified_inheritance;
+  }
+  }
+  bool getBestCase() const {
+    return bestCase;
+  }
+
+  static const bool DefaultBestCase = 1;
+
+
+  static bool hasVBPtrOffsetField(Spelling Inheritance) {
+    return Inheritance == Keyword_unspecified_inheritance;
+  }
+
+  // Only member pointers to functions need a this adjustment, since it can be
+  // combined with the field offset for data pointers.
+  static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
+    return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
+  }
+
+  static bool hasVBTableOffsetField(Spelling Inheritance) {
+    return Inheritance >= Keyword_virtual_inheritance;
+  }
+
+  static bool hasOnlyOneField(bool IsMemberFunction,
+                              Spelling Inheritance) {
+    if (IsMemberFunction)
+      return Inheritance <= Keyword_single_inheritance;
+    return Inheritance <= Keyword_multiple_inheritance;
+  }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MSInheritance; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MSP430InterruptAttr : public InheritableAttr {
+unsigned number;
+
+
+public:
+  static MSP430InterruptAttr *CreateImplicit(ASTContext &Ctx, unsigned Number, SourceRange Loc = SourceRange()) {
+    MSP430InterruptAttr *A = new (Ctx) MSP430InterruptAttr(Loc, Ctx, Number, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MSP430InterruptAttr(SourceRange R, ASTContext &Ctx
+              , unsigned Number
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MSP430Interrupt, R, SI)
+              , number(Number)
+  {
+
+  }
+
+  MSP430InterruptAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getNumber() const {
+    return number;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MSP430Interrupt; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MSVtorDispAttr : public InheritableAttr {
+unsigned vdm;
+
+
+public:
+  static MSVtorDispAttr *CreateImplicit(ASTContext &Ctx, unsigned Vdm, SourceRange Loc = SourceRange()) {
+    MSVtorDispAttr *A = new (Ctx) MSVtorDispAttr(Loc, Ctx, Vdm, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MSVtorDispAttr(SourceRange R, ASTContext &Ctx
+              , unsigned Vdm
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MSVtorDisp, R, SI)
+              , vdm(Vdm)
+  {
+
+  }
+
+  MSVtorDispAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getVdm() const {
+    return vdm;
+  }
+
+
+  enum Mode {
+    Never,
+    ForVBaseOverride,
+    ForVFTable
+  };
+
+  Mode getVtorDispMode() const { return Mode(vdm); }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MSVtorDisp; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MallocAttr : public InheritableAttr {
+
+public:
+  static MallocAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    MallocAttr *A = new (Ctx) MallocAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MallocAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Malloc, R, SI)
+  {
+  }
+
+  MallocAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Malloc; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MaxFieldAlignmentAttr : public InheritableAttr {
+unsigned alignment;
+
+
+public:
+  static MaxFieldAlignmentAttr *CreateImplicit(ASTContext &Ctx, unsigned Alignment, SourceRange Loc = SourceRange()) {
+    MaxFieldAlignmentAttr *A = new (Ctx) MaxFieldAlignmentAttr(Loc, Ctx, Alignment, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MaxFieldAlignmentAttr(SourceRange R, ASTContext &Ctx
+              , unsigned Alignment
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MaxFieldAlignment, R, SI)
+              , alignment(Alignment)
+  {
+
+  }
+
+  MaxFieldAlignmentAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getAlignment() const {
+    return alignment;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MaxFieldAlignment; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MayAliasAttr : public InheritableAttr {
+
+public:
+  static MayAliasAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    MayAliasAttr *A = new (Ctx) MayAliasAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MayAliasAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MayAlias, R, SI)
+  {
+  }
+
+  MayAliasAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MayAlias; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MinSizeAttr : public InheritableAttr {
+
+public:
+  static MinSizeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    MinSizeAttr *A = new (Ctx) MinSizeAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MinSizeAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MinSize, R, SI)
+  {
+  }
+
+  MinSizeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MinSize; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class Mips16Attr : public InheritableAttr {
+
+public:
+  static Mips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    Mips16Attr *A = new (Ctx) Mips16Attr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  Mips16Attr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Mips16, R, SI)
+  {
+  }
+
+  Mips16Attr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Mips16; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ModeAttr : public Attr {
+IdentifierInfo * mode;
+
+
+public:
+  static ModeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * Mode, SourceRange Loc = SourceRange()) {
+    ModeAttr *A = new (Ctx) ModeAttr(Loc, Ctx, Mode, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ModeAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * Mode
+              , unsigned SI
+             )
+    : Attr(attr::Mode, R, SI)
+              , mode(Mode)
+  {
+
+  }
+
+  ModeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getMode() const {
+    return mode;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Mode; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class MsStructAttr : public InheritableAttr {
+
+public:
+  static MsStructAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    MsStructAttr *A = new (Ctx) MsStructAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  MsStructAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::MsStruct, R, SI)
+  {
+  }
+
+  MsStructAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::MsStruct; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NSConsumedAttr : public InheritableParamAttr {
+
+public:
+  static NSConsumedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NSConsumedAttr *A = new (Ctx) NSConsumedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NSConsumedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableParamAttr(attr::NSConsumed, R, SI)
+  {
+  }
+
+  NSConsumedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumed; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NSConsumesSelfAttr : public InheritableAttr {
+
+public:
+  static NSConsumesSelfAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NSConsumesSelfAttr *A = new (Ctx) NSConsumesSelfAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NSConsumesSelfAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NSConsumesSelf, R, SI)
+  {
+  }
+
+  NSConsumesSelfAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NSConsumesSelf; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NSReturnsAutoreleasedAttr : public InheritableAttr {
+
+public:
+  static NSReturnsAutoreleasedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NSReturnsAutoreleasedAttr *A = new (Ctx) NSReturnsAutoreleasedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NSReturnsAutoreleasedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NSReturnsAutoreleased, R, SI)
+  {
+  }
+
+  NSReturnsAutoreleasedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsAutoreleased; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NSReturnsNotRetainedAttr : public InheritableAttr {
+
+public:
+  static NSReturnsNotRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NSReturnsNotRetainedAttr *A = new (Ctx) NSReturnsNotRetainedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NSReturnsNotRetainedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NSReturnsNotRetained, R, SI)
+  {
+  }
+
+  NSReturnsNotRetainedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsNotRetained; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NSReturnsRetainedAttr : public InheritableAttr {
+
+public:
+  static NSReturnsRetainedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NSReturnsRetainedAttr *A = new (Ctx) NSReturnsRetainedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NSReturnsRetainedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NSReturnsRetained, R, SI)
+  {
+  }
+
+  NSReturnsRetainedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NSReturnsRetained; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NakedAttr : public InheritableAttr {
+
+public:
+  static NakedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NakedAttr *A = new (Ctx) NakedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NakedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Naked, R, SI)
+  {
+  }
+
+  NakedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Naked; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoCommonAttr : public InheritableAttr {
+
+public:
+  static NoCommonAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoCommonAttr *A = new (Ctx) NoCommonAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoCommonAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoCommon, R, SI)
+  {
+  }
+
+  NoCommonAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoCommon; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoDebugAttr : public InheritableAttr {
+
+public:
+  static NoDebugAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoDebugAttr *A = new (Ctx) NoDebugAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoDebugAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoDebug, R, SI)
+  {
+  }
+
+  NoDebugAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoDebug; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoDuplicateAttr : public InheritableAttr {
+
+public:
+  static NoDuplicateAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoDuplicateAttr *A = new (Ctx) NoDuplicateAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoDuplicateAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoDuplicate, R, SI)
+  {
+  }
+
+  NoDuplicateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoDuplicate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoInlineAttr : public InheritableAttr {
+
+public:
+  static NoInlineAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoInlineAttr *A = new (Ctx) NoInlineAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoInlineAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoInline, R, SI)
+  {
+  }
+
+  NoInlineAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoInline; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoInstrumentFunctionAttr : public InheritableAttr {
+
+public:
+  static NoInstrumentFunctionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoInstrumentFunctionAttr *A = new (Ctx) NoInstrumentFunctionAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoInstrumentFunctionAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoInstrumentFunction, R, SI)
+  {
+  }
+
+  NoInstrumentFunctionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoInstrumentFunction; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoMips16Attr : public InheritableAttr {
+
+public:
+  static NoMips16Attr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoMips16Attr *A = new (Ctx) NoMips16Attr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoMips16Attr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoMips16, R, SI)
+  {
+  }
+
+  NoMips16Attr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoMips16; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoReturnAttr : public InheritableAttr {
+
+public:
+  static NoReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoReturnAttr *A = new (Ctx) NoReturnAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoReturnAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoReturn, R, SI)
+  {
+  }
+
+  NoReturnAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoReturn; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoSanitizeAddressAttr : public InheritableAttr {
+
+public:
+  enum Spelling {
+    GNU_no_address_safety_analysis,
+    CXX11_gnu_no_address_safety_analysis,
+    GNU_no_sanitize_address,
+    CXX11_gnu_no_sanitize_address
+  };
+
+  static NoSanitizeAddressAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
+    NoSanitizeAddressAttr *A = new (Ctx) NoSanitizeAddressAttr(Loc, Ctx, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoSanitizeAddressAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoSanitizeAddress, R, SI)
+  {
+  }
+
+  NoSanitizeAddressAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_no_address_safety_analysis;
+    case 1: return CXX11_gnu_no_address_safety_analysis;
+    case 2: return GNU_no_sanitize_address;
+    case 3: return CXX11_gnu_no_sanitize_address;
+  }
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoSanitizeAddress; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoSanitizeMemoryAttr : public InheritableAttr {
+
+public:
+  static NoSanitizeMemoryAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoSanitizeMemoryAttr *A = new (Ctx) NoSanitizeMemoryAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoSanitizeMemoryAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoSanitizeMemory, R, SI)
+  {
+  }
+
+  NoSanitizeMemoryAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoSanitizeMemory; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoSanitizeThreadAttr : public InheritableAttr {
+
+public:
+  static NoSanitizeThreadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoSanitizeThreadAttr *A = new (Ctx) NoSanitizeThreadAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoSanitizeThreadAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoSanitizeThread, R, SI)
+  {
+  }
+
+  NoSanitizeThreadAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoSanitizeThread; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoSplitStackAttr : public InheritableAttr {
+
+public:
+  static NoSplitStackAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoSplitStackAttr *A = new (Ctx) NoSplitStackAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoSplitStackAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoSplitStack, R, SI)
+  {
+  }
+
+  NoSplitStackAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoSplitStack; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoThreadSafetyAnalysisAttr : public InheritableAttr {
+
+public:
+  static NoThreadSafetyAnalysisAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoThreadSafetyAnalysisAttr *A = new (Ctx) NoThreadSafetyAnalysisAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoThreadSafetyAnalysisAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoThreadSafetyAnalysis, R, SI)
+  {
+  }
+
+  NoThreadSafetyAnalysisAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoThreadSafetyAnalysis; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NoThrowAttr : public InheritableAttr {
+
+public:
+  static NoThrowAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    NoThrowAttr *A = new (Ctx) NoThrowAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NoThrowAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NoThrow, R, SI)
+  {
+  }
+
+  NoThrowAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NoThrow; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class NonNullAttr : public InheritableAttr {
+  unsigned args_Size;
+  unsigned *args_;
+
+
+public:
+  static NonNullAttr *CreateImplicit(ASTContext &Ctx, unsigned *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    NonNullAttr *A = new (Ctx) NonNullAttr(Loc, Ctx, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  NonNullAttr(SourceRange R, ASTContext &Ctx
+              , unsigned *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NonNull, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) unsigned[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  NonNullAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::NonNull, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  NonNullAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  typedef unsigned* args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+bool isNonNull(unsigned idx) const {
+    for (const auto &V : args())
+      if (V == idx)
+        return true;
+    return false;
+  } 
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCBridgeAttr : public InheritableAttr {
+IdentifierInfo * bridgedType;
+
+
+public:
+  static ObjCBridgeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) {
+    ObjCBridgeAttr *A = new (Ctx) ObjCBridgeAttr(Loc, Ctx, BridgedType, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCBridgeAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * BridgedType
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCBridge, R, SI)
+              , bridgedType(BridgedType)
+  {
+
+  }
+
+  ObjCBridgeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getBridgedType() const {
+    return bridgedType;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridge; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCBridgeMutableAttr : public InheritableAttr {
+IdentifierInfo * bridgedType;
+
+
+public:
+  static ObjCBridgeMutableAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * BridgedType, SourceRange Loc = SourceRange()) {
+    ObjCBridgeMutableAttr *A = new (Ctx) ObjCBridgeMutableAttr(Loc, Ctx, BridgedType, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCBridgeMutableAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * BridgedType
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCBridgeMutable, R, SI)
+              , bridgedType(BridgedType)
+  {
+
+  }
+
+  ObjCBridgeMutableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getBridgedType() const {
+    return bridgedType;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeMutable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCBridgeRelatedAttr : public InheritableAttr {
+IdentifierInfo * relatedClass;
+
+IdentifierInfo * classMethod;
+
+IdentifierInfo * instanceMethod;
+
+
+public:
+  static ObjCBridgeRelatedAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * RelatedClass, IdentifierInfo * ClassMethod, IdentifierInfo * InstanceMethod, SourceRange Loc = SourceRange()) {
+    ObjCBridgeRelatedAttr *A = new (Ctx) ObjCBridgeRelatedAttr(Loc, Ctx, RelatedClass, ClassMethod, InstanceMethod, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCBridgeRelatedAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * RelatedClass
+              , IdentifierInfo * ClassMethod
+              , IdentifierInfo * InstanceMethod
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCBridgeRelated, R, SI)
+              , relatedClass(RelatedClass)
+              , classMethod(ClassMethod)
+              , instanceMethod(InstanceMethod)
+  {
+
+
+
+  }
+
+  ObjCBridgeRelatedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getRelatedClass() const {
+    return relatedClass;
+  }
+
+  IdentifierInfo * getClassMethod() const {
+    return classMethod;
+  }
+
+  IdentifierInfo * getInstanceMethod() const {
+    return instanceMethod;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCBridgeRelated; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCDesignatedInitializerAttr : public Attr {
+
+public:
+  static ObjCDesignatedInitializerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCDesignatedInitializerAttr *A = new (Ctx) ObjCDesignatedInitializerAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCDesignatedInitializerAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : Attr(attr::ObjCDesignatedInitializer, R, SI)
+  {
+  }
+
+  ObjCDesignatedInitializerAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCDesignatedInitializer; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCExceptionAttr : public InheritableAttr {
+
+public:
+  static ObjCExceptionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCExceptionAttr *A = new (Ctx) ObjCExceptionAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCExceptionAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCException, R, SI)
+  {
+  }
+
+  ObjCExceptionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCException; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCExplicitProtocolImplAttr : public InheritableAttr {
+
+public:
+  static ObjCExplicitProtocolImplAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCExplicitProtocolImplAttr *A = new (Ctx) ObjCExplicitProtocolImplAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCExplicitProtocolImplAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCExplicitProtocolImpl, R, SI)
+  {
+  }
+
+  ObjCExplicitProtocolImplAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCExplicitProtocolImpl; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCMethodFamilyAttr : public InheritableAttr {
+public:
+  enum FamilyKind {
+    OMF_None,
+    OMF_alloc,
+    OMF_copy,
+    OMF_init,
+    OMF_mutableCopy,
+    OMF_new
+  };
+private:
+  FamilyKind family;
+
+
+public:
+  static ObjCMethodFamilyAttr *CreateImplicit(ASTContext &Ctx, FamilyKind Family, SourceRange Loc = SourceRange()) {
+    ObjCMethodFamilyAttr *A = new (Ctx) ObjCMethodFamilyAttr(Loc, Ctx, Family, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCMethodFamilyAttr(SourceRange R, ASTContext &Ctx
+              , FamilyKind Family
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCMethodFamily, R, SI)
+              , family(Family)
+  {
+
+  }
+
+  ObjCMethodFamilyAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  FamilyKind getFamily() const {
+    return family;
+  }
+
+  static bool ConvertStrToFamilyKind(StringRef Val, FamilyKind &Out) {
+    Optional<FamilyKind> R = llvm::StringSwitch<Optional<FamilyKind>>(Val)
+      .Case("none", ObjCMethodFamilyAttr::OMF_None)
+      .Case("alloc", ObjCMethodFamilyAttr::OMF_alloc)
+      .Case("copy", ObjCMethodFamilyAttr::OMF_copy)
+      .Case("init", ObjCMethodFamilyAttr::OMF_init)
+      .Case("mutableCopy", ObjCMethodFamilyAttr::OMF_mutableCopy)
+      .Case("new", ObjCMethodFamilyAttr::OMF_new)
+      .Default(Optional<FamilyKind>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCMethodFamily; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCNSObjectAttr : public InheritableAttr {
+
+public:
+  static ObjCNSObjectAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCNSObjectAttr *A = new (Ctx) ObjCNSObjectAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCNSObjectAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCNSObject, R, SI)
+  {
+  }
+
+  ObjCNSObjectAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCNSObject; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCPreciseLifetimeAttr : public InheritableAttr {
+
+public:
+  static ObjCPreciseLifetimeAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCPreciseLifetimeAttr *A = new (Ctx) ObjCPreciseLifetimeAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCPreciseLifetimeAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCPreciseLifetime, R, SI)
+  {
+  }
+
+  ObjCPreciseLifetimeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCPreciseLifetime; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCRequiresPropertyDefsAttr : public InheritableAttr {
+
+public:
+  static ObjCRequiresPropertyDefsAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCRequiresPropertyDefsAttr *A = new (Ctx) ObjCRequiresPropertyDefsAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCRequiresPropertyDefsAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCRequiresPropertyDefs, R, SI)
+  {
+  }
+
+  ObjCRequiresPropertyDefsAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresPropertyDefs; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCRequiresSuperAttr : public InheritableAttr {
+
+public:
+  static ObjCRequiresSuperAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCRequiresSuperAttr *A = new (Ctx) ObjCRequiresSuperAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCRequiresSuperAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCRequiresSuper, R, SI)
+  {
+  }
+
+  ObjCRequiresSuperAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRequiresSuper; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCReturnsInnerPointerAttr : public InheritableAttr {
+
+public:
+  static ObjCReturnsInnerPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCReturnsInnerPointerAttr *A = new (Ctx) ObjCReturnsInnerPointerAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCReturnsInnerPointerAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCReturnsInnerPointer, R, SI)
+  {
+  }
+
+  ObjCReturnsInnerPointerAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCReturnsInnerPointer; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCRootClassAttr : public InheritableAttr {
+
+public:
+  static ObjCRootClassAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ObjCRootClassAttr *A = new (Ctx) ObjCRootClassAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCRootClassAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ObjCRootClass, R, SI)
+  {
+  }
+
+  ObjCRootClassAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRootClass; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ObjCRuntimeNameAttr : public Attr {
+unsigned metadataNameLength;
+char *metadataName;
+
+
+public:
+  static ObjCRuntimeNameAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef MetadataName, SourceRange Loc = SourceRange()) {
+    ObjCRuntimeNameAttr *A = new (Ctx) ObjCRuntimeNameAttr(Loc, Ctx, MetadataName, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ObjCRuntimeNameAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef MetadataName
+              , unsigned SI
+             )
+    : Attr(attr::ObjCRuntimeName, R, SI)
+              , metadataNameLength(MetadataName.size()),metadataName(new (Ctx, 1) char[metadataNameLength])
+  {
+      std::memcpy(metadataName, MetadataName.data(), metadataNameLength);
+  }
+
+  ObjCRuntimeNameAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getMetadataName() const {
+    return llvm::StringRef(metadataName, metadataNameLength);
+  }
+  unsigned getMetadataNameLength() const {
+    return metadataNameLength;
+  }
+  void setMetadataName(ASTContext &C, llvm::StringRef S) {
+    metadataNameLength = S.size();
+    this->metadataName = new (C, 1) char [metadataNameLength];
+    std::memcpy(this->metadataName, S.data(), metadataNameLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ObjCRuntimeName; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OpenCLImageAccessAttr : public Attr {
+
+public:
+  enum Spelling {
+    Keyword_read_only,
+    Keyword_write_only,
+    Keyword_read_write
+  };
+
+  static OpenCLImageAccessAttr *CreateImplicit(ASTContext &Ctx, Spelling S, SourceRange Loc = SourceRange()) {
+    OpenCLImageAccessAttr *A = new (Ctx) OpenCLImageAccessAttr(Loc, Ctx, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OpenCLImageAccessAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : Attr(attr::OpenCLImageAccess, R, SI)
+  {
+  }
+
+  OpenCLImageAccessAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Keyword_read_only;
+    case 1: return Keyword_read_only;
+    case 2: return Keyword_write_only;
+    case 3: return Keyword_write_only;
+    case 4: return Keyword_read_write;
+    case 5: return Keyword_read_write;
+  }
+  }
+  bool isReadOnly() const { return SpellingListIndex == 0 ||
+    SpellingListIndex == 1; }
+  bool isReadWrite() const { return SpellingListIndex == 4 ||
+    SpellingListIndex == 5; }
+  bool isWriteOnly() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3; }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLImageAccess; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OpenCLKernelAttr : public InheritableAttr {
+
+public:
+  static OpenCLKernelAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    OpenCLKernelAttr *A = new (Ctx) OpenCLKernelAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OpenCLKernelAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::OpenCLKernel, R, SI)
+  {
+  }
+
+  OpenCLKernelAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::OpenCLKernel; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OptimizeNoneAttr : public InheritableAttr {
+
+public:
+  static OptimizeNoneAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    OptimizeNoneAttr *A = new (Ctx) OptimizeNoneAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OptimizeNoneAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::OptimizeNone, R, SI)
+  {
+  }
+
+  OptimizeNoneAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::OptimizeNone; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OverloadableAttr : public Attr {
+
+public:
+  static OverloadableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    OverloadableAttr *A = new (Ctx) OverloadableAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OverloadableAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : Attr(attr::Overloadable, R, SI)
+  {
+  }
+
+  OverloadableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Overloadable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OverrideAttr : public InheritableAttr {
+
+public:
+  static OverrideAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    OverrideAttr *A = new (Ctx) OverrideAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OverrideAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Override, R, SI)
+  {
+  }
+
+  OverrideAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Override; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class OwnershipAttr : public InheritableAttr {
+IdentifierInfo * module;
+
+  unsigned args_Size;
+  unsigned *args_;
+
+
+public:
+  enum Spelling {
+    GNU_ownership_holds,
+    GNU_ownership_returns,
+    GNU_ownership_takes
+  };
+
+  static OwnershipAttr *CreateImplicit(ASTContext &Ctx, Spelling S, IdentifierInfo * Module, unsigned *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    OwnershipAttr *A = new (Ctx) OwnershipAttr(Loc, Ctx, Module, Args, ArgsSize, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  OwnershipAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * Module
+              , unsigned *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Ownership, R, SI)
+              , module(Module)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) unsigned[args_Size])
+  {
+
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  OwnershipAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * Module
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Ownership, R, SI)
+              , module()
+              , args_Size(0), args_(nullptr)
+  {
+
+  }
+
+  OwnershipAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_ownership_holds;
+    case 1: return GNU_ownership_returns;
+    case 2: return GNU_ownership_takes;
+  }
+  }
+  bool isHolds() const { return SpellingListIndex == 0; }
+  bool isReturns() const { return SpellingListIndex == 1; }
+  bool isTakes() const { return SpellingListIndex == 2; }
+  IdentifierInfo * getModule() const {
+    return module;
+  }
+
+  typedef unsigned* args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+    enum OwnershipKind { Holds, Returns, Takes };
+    OwnershipKind getOwnKind() const {
+      return isHolds() ? Holds :
+             isTakes() ? Takes :
+             Returns;
+    }
+  
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Ownership; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PackedAttr : public InheritableAttr {
+
+public:
+  static PackedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    PackedAttr *A = new (Ctx) PackedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PackedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Packed, R, SI)
+  {
+  }
+
+  PackedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Packed; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ParamTypestateAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Unknown,
+    Consumed,
+    Unconsumed
+  };
+private:
+  ConsumedState paramState;
+
+
+public:
+  static ParamTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState ParamState, SourceRange Loc = SourceRange()) {
+    ParamTypestateAttr *A = new (Ctx) ParamTypestateAttr(Loc, Ctx, ParamState, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ParamTypestateAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState ParamState
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ParamTypestate, R, SI)
+              , paramState(ParamState)
+  {
+
+  }
+
+  ParamTypestateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  ConsumedState getParamState() const {
+    return paramState;
+  }
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("unknown", ParamTypestateAttr::Unknown)
+      .Case("consumed", ParamTypestateAttr::Consumed)
+      .Case("unconsumed", ParamTypestateAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ParamTypestate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PascalAttr : public InheritableAttr {
+
+public:
+  static PascalAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    PascalAttr *A = new (Ctx) PascalAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PascalAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Pascal, R, SI)
+  {
+  }
+
+  PascalAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Pascal; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PcsAttr : public InheritableAttr {
+public:
+  enum PCSType {
+    AAPCS,
+    AAPCS_VFP
+  };
+private:
+  PCSType pCS;
+
+
+public:
+  static PcsAttr *CreateImplicit(ASTContext &Ctx, PCSType PCS, SourceRange Loc = SourceRange()) {
+    PcsAttr *A = new (Ctx) PcsAttr(Loc, Ctx, PCS, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PcsAttr(SourceRange R, ASTContext &Ctx
+              , PCSType PCS
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Pcs, R, SI)
+              , pCS(PCS)
+  {
+
+  }
+
+  PcsAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  PCSType getPCS() const {
+    return pCS;
+  }
+
+  static bool ConvertStrToPCSType(StringRef Val, PCSType &Out) {
+    Optional<PCSType> R = llvm::StringSwitch<Optional<PCSType>>(Val)
+      .Case("aapcs", PcsAttr::AAPCS)
+      .Case("aapcs-vfp", PcsAttr::AAPCS_VFP)
+      .Default(Optional<PCSType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Pcs; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PnaclCallAttr : public InheritableAttr {
+
+public:
+  static PnaclCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    PnaclCallAttr *A = new (Ctx) PnaclCallAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PnaclCallAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::PnaclCall, R, SI)
+  {
+  }
+
+  PnaclCallAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::PnaclCall; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PtGuardedByAttr : public InheritableAttr {
+Expr * arg;
+
+
+public:
+  static PtGuardedByAttr *CreateImplicit(ASTContext &Ctx, Expr * Arg, SourceRange Loc = SourceRange()) {
+    PtGuardedByAttr *A = new (Ctx) PtGuardedByAttr(Loc, Ctx, Arg, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PtGuardedByAttr(SourceRange R, ASTContext &Ctx
+              , Expr * Arg
+              , unsigned SI
+             )
+    : InheritableAttr(attr::PtGuardedBy, R, SI)
+              , arg(Arg)
+  {
+
+  }
+
+  PtGuardedByAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getArg() const {
+    return arg;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedBy; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class PtGuardedVarAttr : public InheritableAttr {
+
+public:
+  static PtGuardedVarAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    PtGuardedVarAttr *A = new (Ctx) PtGuardedVarAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PtGuardedVarAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::PtGuardedVar, R, SI)
+  {
+  }
+
+  PtGuardedVarAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::PtGuardedVar; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class PureAttr : public InheritableAttr {
+
+public:
+  static PureAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    PureAttr *A = new (Ctx) PureAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  PureAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Pure, R, SI)
+  {
+  }
+
+  PureAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Pure; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ReleaseCapabilityAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  enum Spelling {
+    GNU_release_capability,
+    CXX11_clang_release_capability,
+    GNU_release_shared_capability,
+    CXX11_clang_release_shared_capability,
+    GNU_release_generic_capability,
+    CXX11_clang_release_generic_capability,
+    GNU_unlock_function
+  };
+
+  static ReleaseCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    ReleaseCapabilityAttr *A = new (Ctx) ReleaseCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReleaseCapability, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  ReleaseCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReleaseCapability, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  ReleaseCapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_release_capability;
+    case 1: return CXX11_clang_release_capability;
+    case 2: return GNU_release_shared_capability;
+    case 3: return CXX11_clang_release_shared_capability;
+    case 4: return GNU_release_generic_capability;
+    case 5: return CXX11_clang_release_generic_capability;
+    case 6: return GNU_unlock_function;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3; }
+  bool isGeneric() const { return SpellingListIndex == 4 ||
+    SpellingListIndex == 5 ||
+    SpellingListIndex == 6; }
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ReleaseCapability; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class ReqdWorkGroupSizeAttr : public InheritableAttr {
+unsigned xDim;
+
+unsigned yDim;
+
+unsigned zDim;
+
+
+public:
+  static ReqdWorkGroupSizeAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) {
+    ReqdWorkGroupSizeAttr *A = new (Ctx) ReqdWorkGroupSizeAttr(Loc, Ctx, XDim, YDim, ZDim, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ReqdWorkGroupSizeAttr(SourceRange R, ASTContext &Ctx
+              , unsigned XDim
+              , unsigned YDim
+              , unsigned ZDim
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReqdWorkGroupSize, R, SI)
+              , xDim(XDim)
+              , yDim(YDim)
+              , zDim(ZDim)
+  {
+
+
+
+  }
+
+  ReqdWorkGroupSizeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getXDim() const {
+    return xDim;
+  }
+
+  unsigned getYDim() const {
+    return yDim;
+  }
+
+  unsigned getZDim() const {
+    return zDim;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ReqdWorkGroupSize; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class RequiresCapabilityAttr : public InheritableAttr {
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  enum Spelling {
+    GNU_requires_capability,
+    CXX11_clang_requires_capability,
+    GNU_exclusive_locks_required,
+    GNU_requires_shared_capability,
+    CXX11_clang_requires_shared_capability,
+    GNU_shared_locks_required
+  };
+
+  static RequiresCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    RequiresCapabilityAttr *A = new (Ctx) RequiresCapabilityAttr(Loc, Ctx, Args, ArgsSize, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::RequiresCapability, R, SI)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  RequiresCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::RequiresCapability, R, SI)
+              , args_Size(0), args_(nullptr)
+  {
+  }
+
+  RequiresCapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_requires_capability;
+    case 1: return CXX11_clang_requires_capability;
+    case 2: return GNU_exclusive_locks_required;
+    case 3: return GNU_requires_shared_capability;
+    case 4: return CXX11_clang_requires_shared_capability;
+    case 5: return GNU_shared_locks_required;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 3 ||
+    SpellingListIndex == 5 ||
+    SpellingListIndex == 4; }
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::RequiresCapability; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class ReturnTypestateAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Unknown,
+    Consumed,
+    Unconsumed
+  };
+private:
+  ConsumedState state;
+
+
+public:
+  static ReturnTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState State, SourceRange Loc = SourceRange()) {
+    ReturnTypestateAttr *A = new (Ctx) ReturnTypestateAttr(Loc, Ctx, State, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ReturnTypestateAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState State
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReturnTypestate, R, SI)
+              , state(State)
+  {
+
+  }
+
+  ReturnTypestateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  ConsumedState getState() const {
+    return state;
+  }
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("unknown", ReturnTypestateAttr::Unknown)
+      .Case("consumed", ReturnTypestateAttr::Consumed)
+      .Case("unconsumed", ReturnTypestateAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ReturnTypestate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ReturnsNonNullAttr : public InheritableAttr {
+
+public:
+  static ReturnsNonNullAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ReturnsNonNullAttr *A = new (Ctx) ReturnsNonNullAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ReturnsNonNullAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReturnsNonNull, R, SI)
+  {
+  }
+
+  ReturnsNonNullAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsNonNull; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ReturnsTwiceAttr : public InheritableAttr {
+
+public:
+  static ReturnsTwiceAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ReturnsTwiceAttr *A = new (Ctx) ReturnsTwiceAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ReturnsTwiceAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ReturnsTwice, R, SI)
+  {
+  }
+
+  ReturnsTwiceAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ReturnsTwice; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ScopedLockableAttr : public InheritableAttr {
+
+public:
+  static ScopedLockableAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ScopedLockableAttr *A = new (Ctx) ScopedLockableAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ScopedLockableAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ScopedLockable, R, SI)
+  {
+  }
+
+  ScopedLockableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ScopedLockable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SectionAttr : public InheritableAttr {
+unsigned nameLength;
+char *name;
+
+
+public:
+  enum Spelling {
+    GNU_section,
+    CXX11_gnu_section,
+    Declspec_allocate
+  };
+
+  static SectionAttr *CreateImplicit(ASTContext &Ctx, Spelling S, llvm::StringRef Name, SourceRange Loc = SourceRange()) {
+    SectionAttr *A = new (Ctx) SectionAttr(Loc, Ctx, Name, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SectionAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Name
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Section, R, SI)
+              , nameLength(Name.size()),name(new (Ctx, 1) char[nameLength])
+  {
+      std::memcpy(name, Name.data(), nameLength);
+  }
+
+  SectionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_section;
+    case 1: return CXX11_gnu_section;
+    case 2: return Declspec_allocate;
+  }
+  }
+  llvm::StringRef getName() const {
+    return llvm::StringRef(name, nameLength);
+  }
+  unsigned getNameLength() const {
+    return nameLength;
+  }
+  void setName(ASTContext &C, llvm::StringRef S) {
+    nameLength = S.size();
+    this->name = new (C, 1) char [nameLength];
+    std::memcpy(this->name, S.data(), nameLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Section; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SelectAnyAttr : public InheritableAttr {
+
+public:
+  static SelectAnyAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    SelectAnyAttr *A = new (Ctx) SelectAnyAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SelectAnyAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::SelectAny, R, SI)
+  {
+  }
+
+  SelectAnyAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::SelectAny; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SentinelAttr : public InheritableAttr {
+int sentinel;
+
+int nullPos;
+
+
+public:
+  static SentinelAttr *CreateImplicit(ASTContext &Ctx, int Sentinel, int NullPos, SourceRange Loc = SourceRange()) {
+    SentinelAttr *A = new (Ctx) SentinelAttr(Loc, Ctx, Sentinel, NullPos, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SentinelAttr(SourceRange R, ASTContext &Ctx
+              , int Sentinel
+              , int NullPos
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Sentinel, R, SI)
+              , sentinel(Sentinel)
+              , nullPos(NullPos)
+  {
+
+
+  }
+
+  SentinelAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Sentinel, R, SI)
+              , sentinel()
+              , nullPos()
+  {
+  }
+
+  SentinelAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  int getSentinel() const {
+    return sentinel;
+  }
+
+  static const int DefaultSentinel = 0;
+
+  int getNullPos() const {
+    return nullPos;
+  }
+
+  static const int DefaultNullPos = 0;
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SetTypestateAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Unknown,
+    Consumed,
+    Unconsumed
+  };
+private:
+  ConsumedState newState;
+
+
+public:
+  static SetTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState NewState, SourceRange Loc = SourceRange()) {
+    SetTypestateAttr *A = new (Ctx) SetTypestateAttr(Loc, Ctx, NewState, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SetTypestateAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState NewState
+              , unsigned SI
+             )
+    : InheritableAttr(attr::SetTypestate, R, SI)
+              , newState(NewState)
+  {
+
+  }
+
+  SetTypestateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  ConsumedState getNewState() const {
+    return newState;
+  }
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("unknown", SetTypestateAttr::Unknown)
+      .Case("consumed", SetTypestateAttr::Consumed)
+      .Case("unconsumed", SetTypestateAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::SetTypestate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SharedTrylockFunctionAttr : public InheritableAttr {
+Expr * successValue;
+
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  static SharedTrylockFunctionAttr *CreateImplicit(ASTContext &Ctx, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    SharedTrylockFunctionAttr *A = new (Ctx) SharedTrylockFunctionAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::SharedTrylockFunction, R, SI)
+              , successValue(SuccessValue)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  SharedTrylockFunctionAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , unsigned SI
+             )
+    : InheritableAttr(attr::SharedTrylockFunction, R, SI)
+              , successValue()
+              , args_Size(0), args_(nullptr)
+  {
+
+  }
+
+  SharedTrylockFunctionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Expr * getSuccessValue() const {
+    return successValue;
+  }
+
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::SharedTrylockFunction; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class StdCallAttr : public InheritableAttr {
+
+public:
+  static StdCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    StdCallAttr *A = new (Ctx) StdCallAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  StdCallAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::StdCall, R, SI)
+  {
+  }
+
+  StdCallAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::StdCall; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class SysVABIAttr : public InheritableAttr {
+
+public:
+  static SysVABIAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    SysVABIAttr *A = new (Ctx) SysVABIAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  SysVABIAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::SysVABI, R, SI)
+  {
+  }
+
+  SysVABIAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::SysVABI; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class TLSModelAttr : public InheritableAttr {
+unsigned modelLength;
+char *model;
+
+
+public:
+  static TLSModelAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Model, SourceRange Loc = SourceRange()) {
+    TLSModelAttr *A = new (Ctx) TLSModelAttr(Loc, Ctx, Model, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TLSModelAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Model
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TLSModel, R, SI)
+              , modelLength(Model.size()),model(new (Ctx, 1) char[modelLength])
+  {
+      std::memcpy(model, Model.data(), modelLength);
+  }
+
+  TLSModelAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getModel() const {
+    return llvm::StringRef(model, modelLength);
+  }
+  unsigned getModelLength() const {
+    return modelLength;
+  }
+  void setModel(ASTContext &C, llvm::StringRef S) {
+    modelLength = S.size();
+    this->model = new (C, 1) char [modelLength];
+    std::memcpy(this->model, S.data(), modelLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TLSModel; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class TestTypestateAttr : public InheritableAttr {
+public:
+  enum ConsumedState {
+    Consumed,
+    Unconsumed
+  };
+private:
+  ConsumedState testState;
+
+
+public:
+  static TestTypestateAttr *CreateImplicit(ASTContext &Ctx, ConsumedState TestState, SourceRange Loc = SourceRange()) {
+    TestTypestateAttr *A = new (Ctx) TestTypestateAttr(Loc, Ctx, TestState, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TestTypestateAttr(SourceRange R, ASTContext &Ctx
+              , ConsumedState TestState
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TestTypestate, R, SI)
+              , testState(TestState)
+  {
+
+  }
+
+  TestTypestateAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  ConsumedState getTestState() const {
+    return testState;
+  }
+
+  static bool ConvertStrToConsumedState(StringRef Val, ConsumedState &Out) {
+    Optional<ConsumedState> R = llvm::StringSwitch<Optional<ConsumedState>>(Val)
+      .Case("consumed", TestTypestateAttr::Consumed)
+      .Case("unconsumed", TestTypestateAttr::Unconsumed)
+      .Default(Optional<ConsumedState>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TestTypestate; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ThisCallAttr : public InheritableAttr {
+
+public:
+  static ThisCallAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ThisCallAttr *A = new (Ctx) ThisCallAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ThisCallAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::ThisCall, R, SI)
+  {
+  }
+
+  ThisCallAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::ThisCall; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class ThreadAttr : public Attr {
+
+public:
+  static ThreadAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    ThreadAttr *A = new (Ctx) ThreadAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  ThreadAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : Attr(attr::Thread, R, SI)
+  {
+  }
+
+  ThreadAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Thread; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class TransparentUnionAttr : public InheritableAttr {
+
+public:
+  static TransparentUnionAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    TransparentUnionAttr *A = new (Ctx) TransparentUnionAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TransparentUnionAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TransparentUnion, R, SI)
+  {
+  }
+
+  TransparentUnionAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TransparentUnion; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class TryAcquireCapabilityAttr : public InheritableAttr {
+Expr * successValue;
+
+  unsigned args_Size;
+  Expr * *args_;
+
+
+public:
+  enum Spelling {
+    GNU_try_acquire_capability,
+    CXX11_clang_try_acquire_capability,
+    GNU_try_acquire_shared_capability,
+    CXX11_clang_try_acquire_shared_capability
+  };
+
+  static TryAcquireCapabilityAttr *CreateImplicit(ASTContext &Ctx, Spelling S, Expr * SuccessValue, Expr * *Args, unsigned ArgsSize, SourceRange Loc = SourceRange()) {
+    TryAcquireCapabilityAttr *A = new (Ctx) TryAcquireCapabilityAttr(Loc, Ctx, SuccessValue, Args, ArgsSize, S);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , Expr * *Args, unsigned ArgsSize
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TryAcquireCapability, R, SI)
+              , successValue(SuccessValue)
+              , args_Size(ArgsSize), args_(new (Ctx, 16) Expr *[args_Size])
+  {
+
+    std::copy(Args, Args + args_Size, args_);
+  }
+
+  TryAcquireCapabilityAttr(SourceRange R, ASTContext &Ctx
+              , Expr * SuccessValue
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TryAcquireCapability, R, SI)
+              , successValue()
+              , args_Size(0), args_(nullptr)
+  {
+
+  }
+
+  TryAcquireCapabilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  Spelling getSemanticSpelling() const {
+  switch (SpellingListIndex) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_try_acquire_capability;
+    case 1: return CXX11_clang_try_acquire_capability;
+    case 2: return GNU_try_acquire_shared_capability;
+    case 3: return CXX11_clang_try_acquire_shared_capability;
+  }
+  }
+  bool isShared() const { return SpellingListIndex == 2 ||
+    SpellingListIndex == 3; }
+  Expr * getSuccessValue() const {
+    return successValue;
+  }
+
+  typedef Expr ** args_iterator;
+  args_iterator args_begin() const { return args_; }
+  args_iterator args_end() const { return args_ + args_Size; }
+  unsigned args_size() const { return args_Size; }
+  llvm::iterator_range<args_iterator> args() const { return llvm::make_range(args_begin(), args_end()); }
+
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TryAcquireCapability; }
+  bool isLateParsed() const override { return 1; }
+  bool duplicatesAllowed() const override { return true; }
+
+};
+
+class TypeTagForDatatypeAttr : public InheritableAttr {
+IdentifierInfo * argumentKind;
+
+TypeSourceInfo * matchingCType;
+
+bool layoutCompatible;
+
+bool mustBeNull;
+
+
+public:
+  static TypeTagForDatatypeAttr *CreateImplicit(ASTContext &Ctx, IdentifierInfo * ArgumentKind, TypeSourceInfo * MatchingCType, bool LayoutCompatible, bool MustBeNull, SourceRange Loc = SourceRange()) {
+    TypeTagForDatatypeAttr *A = new (Ctx) TypeTagForDatatypeAttr(Loc, Ctx, ArgumentKind, MatchingCType, LayoutCompatible, MustBeNull, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TypeTagForDatatypeAttr(SourceRange R, ASTContext &Ctx
+              , IdentifierInfo * ArgumentKind
+              , TypeSourceInfo * MatchingCType
+              , bool LayoutCompatible
+              , bool MustBeNull
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TypeTagForDatatype, R, SI)
+              , argumentKind(ArgumentKind)
+              , matchingCType(MatchingCType)
+              , layoutCompatible(LayoutCompatible)
+              , mustBeNull(MustBeNull)
+  {
+
+
+
+
+  }
+
+  TypeTagForDatatypeAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  IdentifierInfo * getArgumentKind() const {
+    return argumentKind;
+  }
+
+  QualType getMatchingCType() const {
+    return matchingCType->getType();
+  }  TypeSourceInfo * getMatchingCTypeLoc() const {
+    return matchingCType;
+  }
+
+  bool getLayoutCompatible() const {
+    return layoutCompatible;
+  }
+
+  bool getMustBeNull() const {
+    return mustBeNull;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TypeTagForDatatype; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class TypeVisibilityAttr : public InheritableAttr {
+public:
+  enum VisibilityType {
+    Default,
+    Hidden,
+    Protected
+  };
+private:
+  VisibilityType visibility;
+
+
+public:
+  static TypeVisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) {
+    TypeVisibilityAttr *A = new (Ctx) TypeVisibilityAttr(Loc, Ctx, Visibility, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  TypeVisibilityAttr(SourceRange R, ASTContext &Ctx
+              , VisibilityType Visibility
+              , unsigned SI
+             )
+    : InheritableAttr(attr::TypeVisibility, R, SI)
+              , visibility(Visibility)
+  {
+
+  }
+
+  TypeVisibilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  VisibilityType getVisibility() const {
+    return visibility;
+  }
+
+  static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
+    Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
+      .Case("default", TypeVisibilityAttr::Default)
+      .Case("hidden", TypeVisibilityAttr::Hidden)
+      .Case("internal", TypeVisibilityAttr::Hidden)
+      .Case("protected", TypeVisibilityAttr::Protected)
+      .Default(Optional<VisibilityType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::TypeVisibility; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class UnavailableAttr : public InheritableAttr {
+unsigned messageLength;
+char *message;
+
+
+public:
+  static UnavailableAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Message, SourceRange Loc = SourceRange()) {
+    UnavailableAttr *A = new (Ctx) UnavailableAttr(Loc, Ctx, Message, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  UnavailableAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Message
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Unavailable, R, SI)
+              , messageLength(Message.size()),message(new (Ctx, 1) char[messageLength])
+  {
+      std::memcpy(message, Message.data(), messageLength);
+  }
+
+  UnavailableAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Unavailable, R, SI)
+              , messageLength(0),message(0)
+  {
+  }
+
+  UnavailableAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getMessage() const {
+    return llvm::StringRef(message, messageLength);
+  }
+  unsigned getMessageLength() const {
+    return messageLength;
+  }
+  void setMessage(ASTContext &C, llvm::StringRef S) {
+    messageLength = S.size();
+    this->message = new (C, 1) char [messageLength];
+    std::memcpy(this->message, S.data(), messageLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Unavailable; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class UnusedAttr : public InheritableAttr {
+
+public:
+  static UnusedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    UnusedAttr *A = new (Ctx) UnusedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  UnusedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Unused, R, SI)
+  {
+  }
+
+  UnusedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Unused; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class UsedAttr : public InheritableAttr {
+
+public:
+  static UsedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    UsedAttr *A = new (Ctx) UsedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  UsedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Used, R, SI)
+  {
+  }
+
+  UsedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Used; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class UuidAttr : public InheritableAttr {
+unsigned guidLength;
+char *guid;
+
+
+public:
+  static UuidAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Guid, SourceRange Loc = SourceRange()) {
+    UuidAttr *A = new (Ctx) UuidAttr(Loc, Ctx, Guid, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  UuidAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Guid
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Uuid, R, SI)
+              , guidLength(Guid.size()),guid(new (Ctx, 1) char[guidLength])
+  {
+      std::memcpy(guid, Guid.data(), guidLength);
+  }
+
+  UuidAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getGuid() const {
+    return llvm::StringRef(guid, guidLength);
+  }
+  unsigned getGuidLength() const {
+    return guidLength;
+  }
+  void setGuid(ASTContext &C, llvm::StringRef S) {
+    guidLength = S.size();
+    this->guid = new (C, 1) char [guidLength];
+    std::memcpy(this->guid, S.data(), guidLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Uuid; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class VecReturnAttr : public InheritableAttr {
+
+public:
+  static VecReturnAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    VecReturnAttr *A = new (Ctx) VecReturnAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  VecReturnAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::VecReturn, R, SI)
+  {
+  }
+
+  VecReturnAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::VecReturn; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class VecTypeHintAttr : public InheritableAttr {
+TypeSourceInfo * typeHint;
+
+
+public:
+  static VecTypeHintAttr *CreateImplicit(ASTContext &Ctx, TypeSourceInfo * TypeHint, SourceRange Loc = SourceRange()) {
+    VecTypeHintAttr *A = new (Ctx) VecTypeHintAttr(Loc, Ctx, TypeHint, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  VecTypeHintAttr(SourceRange R, ASTContext &Ctx
+              , TypeSourceInfo * TypeHint
+              , unsigned SI
+             )
+    : InheritableAttr(attr::VecTypeHint, R, SI)
+              , typeHint(TypeHint)
+  {
+
+  }
+
+  VecTypeHintAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  QualType getTypeHint() const {
+    return typeHint->getType();
+  }  TypeSourceInfo * getTypeHintLoc() const {
+    return typeHint;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::VecTypeHint; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class VisibilityAttr : public InheritableAttr {
+public:
+  enum VisibilityType {
+    Default,
+    Hidden,
+    Protected
+  };
+private:
+  VisibilityType visibility;
+
+
+public:
+  static VisibilityAttr *CreateImplicit(ASTContext &Ctx, VisibilityType Visibility, SourceRange Loc = SourceRange()) {
+    VisibilityAttr *A = new (Ctx) VisibilityAttr(Loc, Ctx, Visibility, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  VisibilityAttr(SourceRange R, ASTContext &Ctx
+              , VisibilityType Visibility
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Visibility, R, SI)
+              , visibility(Visibility)
+  {
+
+  }
+
+  VisibilityAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  VisibilityType getVisibility() const {
+    return visibility;
+  }
+
+  static bool ConvertStrToVisibilityType(StringRef Val, VisibilityType &Out) {
+    Optional<VisibilityType> R = llvm::StringSwitch<Optional<VisibilityType>>(Val)
+      .Case("default", VisibilityAttr::Default)
+      .Case("hidden", VisibilityAttr::Hidden)
+      .Case("internal", VisibilityAttr::Hidden)
+      .Case("protected", VisibilityAttr::Protected)
+      .Default(Optional<VisibilityType>());
+    if (R) {
+      Out = *R;
+      return true;
+    }
+    return false;
+  }
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Visibility; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WarnUnusedAttr : public InheritableAttr {
+
+public:
+  static WarnUnusedAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    WarnUnusedAttr *A = new (Ctx) WarnUnusedAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WarnUnusedAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WarnUnused, R, SI)
+  {
+  }
+
+  WarnUnusedAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnused; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WarnUnusedResultAttr : public InheritableAttr {
+
+public:
+  static WarnUnusedResultAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    WarnUnusedResultAttr *A = new (Ctx) WarnUnusedResultAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WarnUnusedResultAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WarnUnusedResult, R, SI)
+  {
+  }
+
+  WarnUnusedResultAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::WarnUnusedResult; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WeakAttr : public InheritableAttr {
+
+public:
+  static WeakAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    WeakAttr *A = new (Ctx) WeakAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WeakAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::Weak, R, SI)
+  {
+  }
+
+  WeakAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::Weak; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WeakImportAttr : public InheritableAttr {
+
+public:
+  static WeakImportAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    WeakImportAttr *A = new (Ctx) WeakImportAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WeakImportAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WeakImport, R, SI)
+  {
+  }
+
+  WeakImportAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::WeakImport; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WeakRefAttr : public InheritableAttr {
+unsigned aliaseeLength;
+char *aliasee;
+
+
+public:
+  static WeakRefAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Aliasee, SourceRange Loc = SourceRange()) {
+    WeakRefAttr *A = new (Ctx) WeakRefAttr(Loc, Ctx, Aliasee, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WeakRefAttr(SourceRange R, ASTContext &Ctx
+              , llvm::StringRef Aliasee
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WeakRef, R, SI)
+              , aliaseeLength(Aliasee.size()),aliasee(new (Ctx, 1) char[aliaseeLength])
+  {
+      std::memcpy(aliasee, Aliasee.data(), aliaseeLength);
+  }
+
+  WeakRefAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WeakRef, R, SI)
+              , aliaseeLength(0),aliasee(0)
+  {
+  }
+
+  WeakRefAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  llvm::StringRef getAliasee() const {
+    return llvm::StringRef(aliasee, aliaseeLength);
+  }
+  unsigned getAliaseeLength() const {
+    return aliaseeLength;
+  }
+  void setAliasee(ASTContext &C, llvm::StringRef S) {
+    aliaseeLength = S.size();
+    this->aliasee = new (C, 1) char [aliaseeLength];
+    std::memcpy(this->aliasee, S.data(), aliaseeLength);
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::WeakRef; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class WorkGroupSizeHintAttr : public InheritableAttr {
+unsigned xDim;
+
+unsigned yDim;
+
+unsigned zDim;
+
+
+public:
+  static WorkGroupSizeHintAttr *CreateImplicit(ASTContext &Ctx, unsigned XDim, unsigned YDim, unsigned ZDim, SourceRange Loc = SourceRange()) {
+    WorkGroupSizeHintAttr *A = new (Ctx) WorkGroupSizeHintAttr(Loc, Ctx, XDim, YDim, ZDim, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  WorkGroupSizeHintAttr(SourceRange R, ASTContext &Ctx
+              , unsigned XDim
+              , unsigned YDim
+              , unsigned ZDim
+              , unsigned SI
+             )
+    : InheritableAttr(attr::WorkGroupSizeHint, R, SI)
+              , xDim(XDim)
+              , yDim(YDim)
+              , zDim(ZDim)
+  {
+
+
+
+  }
+
+  WorkGroupSizeHintAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+  unsigned getXDim() const {
+    return xDim;
+  }
+
+  unsigned getYDim() const {
+    return yDim;
+  }
+
+  unsigned getZDim() const {
+    return zDim;
+  }
+
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::WorkGroupSizeHint; }
+  bool isLateParsed() const override { return 0; }
+};
+
+class X86ForceAlignArgPointerAttr : public InheritableAttr {
+
+public:
+  static X86ForceAlignArgPointerAttr *CreateImplicit(ASTContext &Ctx, SourceRange Loc = SourceRange()) {
+    X86ForceAlignArgPointerAttr *A = new (Ctx) X86ForceAlignArgPointerAttr(Loc, Ctx, 0);
+    A->setImplicit(true);
+    return A;
+  }
+
+  X86ForceAlignArgPointerAttr(SourceRange R, ASTContext &Ctx
+              , unsigned SI
+             )
+    : InheritableAttr(attr::X86ForceAlignArgPointer, R, SI)
+  {
+  }
+
+  X86ForceAlignArgPointerAttr *clone(ASTContext &C) const override;
+  void printPretty(raw_ostream &OS,
+                   const PrintingPolicy &Policy) const override;
+  const char *getSpelling() const override;
+
+
+  static bool classof(const Attr *A) { return A->getKind() == attr::X86ForceAlignArgPointer; }
+  bool isLateParsed() const override { return 0; }
+};
+
+#endif
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
new file mode 100644
index 0000000..da538e3
--- /dev/null
+++ b/include/clang/AST/BaseSubobject.h
@@ -0,0 +1,87 @@
+//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a definition of the BaseSubobject class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_BASESUBOBJECT_H
+#define LLVM_CLANG_AST_BASESUBOBJECT_H
+
+#include "clang/AST/CharUnits.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/type_traits.h"
+
+namespace clang {
+  class CXXRecordDecl;
+
+// BaseSubobject - Uniquely identifies a direct or indirect base class. 
+// Stores both the base class decl and the offset from the most derived class to
+// the base class. Used for vtable and VTT generation.
+class BaseSubobject {
+  /// Base - The base class declaration.
+  const CXXRecordDecl *Base;
+  
+  /// BaseOffset - The offset from the most derived class to the base class.
+  CharUnits BaseOffset;
+  
+public:
+  BaseSubobject() { }
+  BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
+    : Base(Base), BaseOffset(BaseOffset) { }
+  
+  /// getBase - Returns the base class declaration.
+  const CXXRecordDecl *getBase() const { return Base; }
+
+  /// getBaseOffset - Returns the base class offset.
+  CharUnits getBaseOffset() const { return BaseOffset; }
+
+  friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
+    return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
+ }
+};
+
+} // end namespace clang
+
+namespace llvm {
+
+template<> struct DenseMapInfo<clang::BaseSubobject> {
+  static clang::BaseSubobject getEmptyKey() {
+    return clang::BaseSubobject(
+      DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
+      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey()));
+  }
+
+  static clang::BaseSubobject getTombstoneKey() {
+    return clang::BaseSubobject(
+      DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
+      clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey()));
+  }
+
+  static unsigned getHashValue(const clang::BaseSubobject &Base) {
+    typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy;
+    return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(),
+                                                     Base.getBaseOffset()));
+  }
+
+  static bool isEqual(const clang::BaseSubobject &LHS, 
+                      const clang::BaseSubobject &RHS) {
+    return LHS == RHS;
+  }
+};
+
+// It's OK to treat BaseSubobject as a POD type.
+template <> struct isPodLike<clang::BaseSubobject> {
+  static const bool value = true;
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
new file mode 100644
index 0000000..488cace
--- /dev/null
+++ b/include/clang/AST/BuiltinTypes.def
@@ -0,0 +1,240 @@
+//===-- BuiltinTypeNodes.def - Metadata about BuiltinTypes ------*- 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 database about various builtin singleton types.
+//
+//  BuiltinType::Id is the enumerator defining the type.
+//
+//  Context.SingletonId is the global singleton of this type.  Some global
+//  singletons are shared by multiple types.
+//
+//    BUILTIN_TYPE(Id, SingletonId) - A builtin type that has not been
+//    covered by any other #define.  Defining this macro covers all
+//    the builtins.
+//
+//    SIGNED_TYPE(Id, SingletonId) - A signed integral type.
+//
+//    UNSIGNED_TYPE(Id, SingletonId) - An unsigned integral type.
+//
+//    FLOATING_TYPE(Id, SingletonId) - A floating-point type.
+//
+//    PLACEHOLDER_TYPE(Id, SingletonId) - A placeholder type.  Placeholder
+//    types are used to perform context-sensitive checking of specific
+//    forms of expression.
+//
+//    SHARED_SINGLETON_TYPE(Expansion) - The given expansion corresponds
+//    to a builtin which uses a shared singleton type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SIGNED_TYPE
+#define SIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef UNSIGNED_TYPE
+#define UNSIGNED_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef FLOATING_TYPE
+#define FLOATING_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef PLACEHOLDER_TYPE
+#define PLACEHOLDER_TYPE(Id, SingletonId) BUILTIN_TYPE(Id, SingletonId)
+#endif
+
+#ifndef SHARED_SINGLETON_TYPE
+#define SHARED_SINGLETON_TYPE(Expansion) Expansion
+#endif
+
+//===- Builtin Types ------------------------------------------------------===//
+
+// void
+BUILTIN_TYPE(Void, VoidTy)
+
+//===- Unsigned Types -----------------------------------------------------===//
+
+// 'bool' in C++, '_Bool' in C99
+UNSIGNED_TYPE(Bool, BoolTy)
+
+// 'char' for targets where it's unsigned
+SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(Char_U, CharTy))
+
+// 'unsigned char', explicitly qualified
+UNSIGNED_TYPE(UChar, UnsignedCharTy)
+
+// 'wchar_t' for targets where it's unsigned
+SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
+
+// 'char16_t' in C++
+UNSIGNED_TYPE(Char16, Char16Ty)
+
+// 'char32_t' in C++
+UNSIGNED_TYPE(Char32, Char32Ty)
+
+// 'unsigned short'
+UNSIGNED_TYPE(UShort, UnsignedShortTy)
+
+// 'unsigned int'
+UNSIGNED_TYPE(UInt, UnsignedIntTy)
+
+// 'unsigned long'
+UNSIGNED_TYPE(ULong, UnsignedLongTy)
+
+// 'unsigned long long'
+UNSIGNED_TYPE(ULongLong, UnsignedLongLongTy)
+
+// '__uint128_t'
+UNSIGNED_TYPE(UInt128, UnsignedInt128Ty)
+
+//===- Signed Types -------------------------------------------------------===//
+
+// 'char' for targets where it's signed
+SHARED_SINGLETON_TYPE(SIGNED_TYPE(Char_S, CharTy))
+
+// 'signed char', explicitly qualified
+SIGNED_TYPE(SChar, SignedCharTy)
+
+// 'wchar_t' for targets where it's signed
+SHARED_SINGLETON_TYPE(SIGNED_TYPE(WChar_S, WCharTy))
+
+// 'short' or 'signed short'
+SIGNED_TYPE(Short, ShortTy)
+
+// 'int' or 'signed int'
+SIGNED_TYPE(Int, IntTy)
+
+// 'long' or 'signed long'
+SIGNED_TYPE(Long, LongTy)
+
+// 'long long' or 'signed long long'
+SIGNED_TYPE(LongLong, LongLongTy)
+
+// '__int128_t'
+SIGNED_TYPE(Int128, Int128Ty)
+
+//===- Floating point types -----------------------------------------------===//
+
+// 'half' in OpenCL, '__fp16' in ARM NEON.
+FLOATING_TYPE(Half, HalfTy)
+
+// 'float'
+FLOATING_TYPE(Float, FloatTy)
+
+// 'double'
+FLOATING_TYPE(Double, DoubleTy)
+
+// 'long double'
+FLOATING_TYPE(LongDouble, LongDoubleTy)
+
+//===- Language-specific types --------------------------------------------===//
+
+// This is the type of C++0x 'nullptr'.
+BUILTIN_TYPE(NullPtr, NullPtrTy)
+
+// The primitive Objective C 'id' type.  The user-visible 'id'
+// type is a typedef of an ObjCObjectPointerType to an
+// ObjCObjectType with this as its base.  In fact, this only ever
+// shows up in an AST as the base type of an ObjCObjectType.
+BUILTIN_TYPE(ObjCId, ObjCBuiltinIdTy)
+
+// The primitive Objective C 'Class' type.  The user-visible
+// 'Class' type is a typedef of an ObjCObjectPointerType to an
+// ObjCObjectType with this as its base.  In fact, this only ever
+// shows up in an AST as the base type of an ObjCObjectType.
+BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy)
+
+// The primitive Objective C 'SEL' type.  The user-visible 'SEL'
+// type is a typedef of a PointerType to this.
+BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy)
+
+// OpenCL image types.
+BUILTIN_TYPE(OCLImage1d, OCLImage1dTy)
+BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy)
+BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy)
+BUILTIN_TYPE(OCLImage2d, OCLImage2dTy)
+BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy)
+BUILTIN_TYPE(OCLImage3d, OCLImage3dTy)
+
+// OpenCL sampler_t.
+BUILTIN_TYPE(OCLSampler, OCLSamplerTy)
+
+// OpenCL event_t.
+BUILTIN_TYPE(OCLEvent, OCLEventTy)
+
+// This represents the type of an expression whose type is
+// totally unknown, e.g. 'T::foo'.  It is permitted for this to
+// appear in situations where the structure of the type is
+// theoretically deducible.
+BUILTIN_TYPE(Dependent, DependentTy)
+
+// The type of an unresolved overload set.  A placeholder type.
+// Expressions with this type have one of the following basic
+// forms, with parentheses generally permitted:
+//   foo          # possibly qualified, not if an implicit access
+//   foo          # possibly qualified, not if an implicit access
+//   &foo         # possibly qualified, not if an implicit access
+//   x->foo       # only if might be a static member function
+//   &x->foo      # only if might be a static member function
+//   &Class::foo  # when a pointer-to-member; sub-expr also has this type
+// OverloadExpr::find can be used to analyze the expression.
+//
+// Overload should be the first placeholder type, or else change
+// BuiltinType::isNonOverloadPlaceholderType()
+PLACEHOLDER_TYPE(Overload, OverloadTy)
+
+// The type of a bound C++ non-static member function.
+// A placeholder type.  Expressions with this type have one of the
+// following basic forms:
+//   foo          # if an implicit access
+//   x->foo       # if only contains non-static members
+PLACEHOLDER_TYPE(BoundMember, BoundMemberTy)
+
+// The type of an expression which refers to a pseudo-object,
+// such as those introduced by Objective C's @property or
+// VS.NET's __property declarations.  A placeholder type.  The
+// pseudo-object is actually accessed by emitting a call to
+// some sort of function or method;  typically there is a pair
+// of a setter and a getter, with the setter used if the
+// pseudo-object reference is used syntactically as the
+// left-hand-side of an assignment operator.
+//
+// A pseudo-object reference naming an Objective-C @property is
+// always a dot access with a base of object-pointer type,
+// e.g. 'x.foo'.
+//
+// In VS.NET, a __property declaration creates an implicit
+// member with an associated name, which can then be named
+// in any of the normal ways an ordinary member could be.
+PLACEHOLDER_TYPE(PseudoObject, PseudoObjectTy)
+
+// __builtin_any_type.  A placeholder type.  Useful for clients
+// like debuggers that don't know what type to give something.
+// Only a small number of operations are valid on expressions of
+// unknown type, most notably explicit casts.
+PLACEHOLDER_TYPE(UnknownAny, UnknownAnyTy)
+
+PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy)
+
+// The type of a cast which, in ARC, would normally require a
+// __bridge, but which might be okay depending on the immediate
+// context.
+PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
+
+#ifdef LAST_BUILTIN_TYPE
+LAST_BUILTIN_TYPE(ARCUnbridgedCast)
+#undef LAST_BUILTIN_TYPE
+#endif
+
+#undef SHARED_SINGLETON_TYPE
+#undef PLACEHOLDER_TYPE
+#undef FLOATING_TYPE
+#undef SIGNED_TYPE
+#undef UNSIGNED_TYPE
+#undef BUILTIN_TYPE
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
new file mode 100644
index 0000000..37f6748
--- /dev/null
+++ b/include/clang/AST/CXXInheritance.h
@@ -0,0 +1,369 @@
+//===------ CXXInheritance.h - C++ Inheritance ------------------*- 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 routines that help analyzing C++ inheritance hierarchies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
+#define LLVM_CLANG_AST_CXXINHERITANCE_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeOrdering.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <list>
+#include <map>
+
+namespace clang {
+  
+class CXXBaseSpecifier;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class NamedDecl;
+  
+/// \brief Represents an element in a path from a derived class to a
+/// base class. 
+/// 
+/// Each step in the path references the link from a
+/// derived class to one of its direct base classes, along with a
+/// base "number" that identifies which base subobject of the
+/// original derived class we are referencing.
+struct CXXBasePathElement {
+  /// \brief The base specifier that states the link from a derived
+  /// class to a base class, which will be followed by this base
+  /// path element.
+  const CXXBaseSpecifier *Base;
+  
+  /// \brief The record decl of the class that the base is a base of.
+  const CXXRecordDecl *Class;
+  
+  /// \brief Identifies which base class subobject (of type
+  /// \c Base->getType()) this base path element refers to. 
+  ///
+  /// This value is only valid if \c !Base->isVirtual(), because there
+  /// is no base numbering for the zero or one virtual bases of a
+  /// given type.
+  int SubobjectNumber;
+};
+
+/// \brief Represents a path from a specific derived class
+/// (which is not represented as part of the path) to a particular
+/// (direct or indirect) base class subobject.
+///
+/// Individual elements in the path are described by the \c CXXBasePathElement 
+/// structure, which captures both the link from a derived class to one of its
+/// direct bases and identification describing which base class
+/// subobject is being used.
+class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
+public:
+  CXXBasePath() : Access(AS_public) {}
+
+  /// \brief The access along this inheritance path.  This is only
+  /// calculated when recording paths.  AS_none is a special value
+  /// used to indicate a path which permits no legal access.
+  AccessSpecifier Access;
+
+  /// \brief The set of declarations found inside this base class
+  /// subobject.
+  DeclContext::lookup_result Decls;
+
+  void clear() {
+    SmallVectorImpl<CXXBasePathElement>::clear();
+    Access = AS_public;
+  }
+};
+
+/// BasePaths - Represents the set of paths from a derived class to
+/// one of its (direct or indirect) bases. For example, given the
+/// following class hierarchy:
+///
+/// @code
+/// class A { };
+/// class B : public A { };
+/// class C : public A { };
+/// class D : public B, public C{ };
+/// @endcode
+///
+/// There are two potential BasePaths to represent paths from D to a
+/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
+/// and another is (D,0)->(C,0)->(A,1). These two paths actually
+/// refer to two different base class subobjects of the same type,
+/// so the BasePaths object refers to an ambiguous path. On the
+/// other hand, consider the following class hierarchy:
+///
+/// @code
+/// class A { };
+/// class B : public virtual A { };
+/// class C : public virtual A { };
+/// class D : public B, public C{ };
+/// @endcode
+///
+/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
+/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
+/// refer to the same base class subobject of type A (the virtual
+/// one), there is no ambiguity.
+class CXXBasePaths {
+  /// \brief The type from which this search originated.
+  CXXRecordDecl *Origin;
+  
+  /// Paths - The actual set of paths that can be taken from the
+  /// derived class to the same base class.
+  std::list<CXXBasePath> Paths;
+  
+  /// ClassSubobjects - Records the class subobjects for each class
+  /// type that we've seen. The first element in the pair says
+  /// whether we found a path to a virtual base for that class type,
+  /// while the element contains the number of non-virtual base
+  /// class subobjects for that class type. The key of the map is
+  /// the cv-unqualified canonical type of the base class subobject.
+  llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
+  
+  /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
+  /// ambiguous paths while it is looking for a path from a derived
+  /// type to a base type.
+  bool FindAmbiguities;
+  
+  /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
+  /// while it is determining whether there are paths from a derived
+  /// type to a base type.
+  bool RecordPaths;
+  
+  /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
+  /// if it finds a path that goes across a virtual base. The virtual class
+  /// is also recorded.
+  bool DetectVirtual;
+  
+  /// ScratchPath - A BasePath that is used by Sema::lookupInBases
+  /// to help build the set of paths.
+  CXXBasePath ScratchPath;
+
+  /// DetectedVirtual - The base class that is virtual.
+  const RecordType *DetectedVirtual;
+  
+  /// \brief Array of the declarations that have been found. This
+  /// array is constructed only if needed, e.g., to iterate over the
+  /// results within LookupResult.
+  NamedDecl **DeclsFound;
+  unsigned NumDeclsFound;
+  
+  friend class CXXRecordDecl;
+  
+  void ComputeDeclsFound();
+
+  bool lookupInBases(ASTContext &Context, 
+                     const CXXRecordDecl *Record,
+                     CXXRecordDecl::BaseMatchesCallback *BaseMatches, 
+                     void *UserData);
+public:
+  typedef std::list<CXXBasePath>::iterator paths_iterator;
+  typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
+  typedef NamedDecl **decl_iterator;
+  
+  /// BasePaths - Construct a new BasePaths structure to record the
+  /// paths for a derived-to-base search.
+  explicit CXXBasePaths(bool FindAmbiguities = true,
+                        bool RecordPaths = true,
+                        bool DetectVirtual = true)
+    : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+      DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
+      DeclsFound(nullptr), NumDeclsFound(0) { }
+  
+  ~CXXBasePaths() { delete [] DeclsFound; }
+  
+  paths_iterator begin() { return Paths.begin(); }
+  paths_iterator end()   { return Paths.end(); }
+  const_paths_iterator begin() const { return Paths.begin(); }
+  const_paths_iterator end()   const { return Paths.end(); }
+  
+  CXXBasePath&       front()       { return Paths.front(); }
+  const CXXBasePath& front() const { return Paths.front(); }
+  
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+  decl_range found_decls();
+  
+  /// \brief Determine whether the path from the most-derived type to the
+  /// given base type is ambiguous (i.e., it refers to multiple subobjects of
+  /// the same base type).
+  bool isAmbiguous(CanQualType BaseType);
+  
+  /// \brief Whether we are finding multiple paths to detect ambiguities.
+  bool isFindingAmbiguities() const { return FindAmbiguities; }
+  
+  /// \brief Whether we are recording paths.
+  bool isRecordingPaths() const { return RecordPaths; }
+  
+  /// \brief Specify whether we should be recording paths or not.
+  void setRecordingPaths(bool RP) { RecordPaths = RP; }
+  
+  /// \brief Whether we are detecting virtual bases.
+  bool isDetectingVirtual() const { return DetectVirtual; }
+  
+  /// \brief The virtual base discovered on the path (if we are merely
+  /// detecting virtuals).
+  const RecordType* getDetectedVirtual() const {
+    return DetectedVirtual;
+  }
+
+  /// \brief Retrieve the type from which this base-paths search
+  /// began
+  CXXRecordDecl *getOrigin() const { return Origin; }
+  void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
+  
+  /// \brief Clear the base-paths results.
+  void clear();
+  
+  /// \brief Swap this data structure's contents with another CXXBasePaths 
+  /// object.
+  void swap(CXXBasePaths &Other);
+};
+
+/// \brief Uniquely identifies a virtual method within a class
+/// hierarchy by the method itself and a class subobject number.
+struct UniqueVirtualMethod {
+  UniqueVirtualMethod()
+    : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
+
+  UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
+                      const CXXRecordDecl *InVirtualSubobject)
+    : Method(Method), Subobject(Subobject), 
+      InVirtualSubobject(InVirtualSubobject) { }
+
+  /// \brief The overriding virtual method.
+  CXXMethodDecl *Method;
+
+  /// \brief The subobject in which the overriding virtual method
+  /// resides.
+  unsigned Subobject;
+
+  /// \brief The virtual base class subobject of which this overridden
+  /// virtual method is a part. Note that this records the closest
+  /// derived virtual base class subobject.
+  const CXXRecordDecl *InVirtualSubobject;
+
+  friend bool operator==(const UniqueVirtualMethod &X,
+                         const UniqueVirtualMethod &Y) {
+    return X.Method == Y.Method && X.Subobject == Y.Subobject &&
+      X.InVirtualSubobject == Y.InVirtualSubobject;
+  }
+
+  friend bool operator!=(const UniqueVirtualMethod &X,
+                         const UniqueVirtualMethod &Y) {
+    return !(X == Y);
+  }
+};
+
+/// \brief The set of methods that override a given virtual method in
+/// each subobject where it occurs.
+///
+/// The first part of the pair is the subobject in which the
+/// overridden virtual function occurs, while the second part of the
+/// pair is the virtual method that overrides it (including the
+/// subobject in which that virtual function occurs).
+class OverridingMethods {
+  typedef SmallVector<UniqueVirtualMethod, 4> ValuesT;
+  typedef llvm::MapVector<unsigned, ValuesT> MapType;
+  MapType Overrides;
+
+public:
+  // Iterate over the set of subobjects that have overriding methods.
+  typedef MapType::iterator iterator;
+  typedef MapType::const_iterator const_iterator;
+  iterator begin() { return Overrides.begin(); }
+  const_iterator begin() const { return Overrides.begin(); }
+  iterator end() { return Overrides.end(); }
+  const_iterator end() const { return Overrides.end(); }
+  unsigned size() const { return Overrides.size(); }
+
+  // Iterate over the set of overriding virtual methods in a given
+  // subobject.
+  typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
+    overriding_iterator;
+  typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
+    overriding_const_iterator;
+
+  // Add a new overriding method for a particular subobject.
+  void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
+
+  // Add all of the overriding methods from "other" into overrides for
+  // this method. Used when merging the overrides from multiple base
+  // class subobjects.
+  void add(const OverridingMethods &Other);
+
+  // Replace all overriding virtual methods in all subobjects with the
+  // given virtual method.
+  void replaceAll(UniqueVirtualMethod Overriding);
+};
+
+/// \brief A mapping from each virtual member function to its set of
+/// final overriders.
+///
+/// Within a class hierarchy for a given derived class, each virtual
+/// member function in that hierarchy has one or more "final
+/// overriders" (C++ [class.virtual]p2). A final overrider for a
+/// virtual function "f" is the virtual function that will actually be
+/// invoked when dispatching a call to "f" through the
+/// vtable. Well-formed classes have a single final overrider for each
+/// virtual function; in abstract classes, the final overrider for at
+/// least one virtual function is a pure virtual function. Due to
+/// multiple, virtual inheritance, it is possible for a class to have
+/// more than one final overrider. Athough this is an error (per C++
+/// [class.virtual]p2), it is not considered an error here: the final
+/// overrider map can represent multiple final overriders for a
+/// method, and it is up to the client to determine whether they are
+/// problem. For example, the following class \c D has two final
+/// overriders for the virtual function \c A::f(), one in \c C and one
+/// in \c D:
+///
+/// \code
+///   struct A { virtual void f(); };
+///   struct B : virtual A { virtual void f(); };
+///   struct C : virtual A { virtual void f(); };
+///   struct D : B, C { };
+/// \endcode
+///
+/// This data structure contaings a mapping from every virtual
+/// function *that does not override an existing virtual function* and
+/// in every subobject where that virtual function occurs to the set
+/// of virtual functions that override it. Thus, the same virtual
+/// function \c A::f can actually occur in multiple subobjects of type
+/// \c A due to multiple inheritance, and may be overriden by
+/// different virtual functions in each, as in the following example:
+///
+/// \code
+///   struct A { virtual void f(); };
+///   struct B : A { virtual void f(); };
+///   struct C : A { virtual void f(); };
+///   struct D : B, C { };
+/// \endcode
+///
+/// Unlike in the previous example, where the virtual functions \c
+/// B::f and \c C::f both overrode \c A::f in the same subobject of
+/// type \c A, in this example the two virtual functions both override
+/// \c A::f but in *different* subobjects of type A. This is
+/// represented by numbering the subobjects in which the overridden
+/// and the overriding virtual member functions are located. Subobject
+/// 0 represents the virtua base class subobject of that type, while
+/// subobject numbers greater than 0 refer to non-virtual base class
+/// subobjects of that type.
+class CXXFinalOverriderMap
+  : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { };
+
+/// \brief A set of all the primary bases for a class.
+class CXXIndirectPrimaryBaseSet
+  : public llvm::SmallSet<const CXXRecordDecl*, 32> { };
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
new file mode 100644
index 0000000..7cccef6
--- /dev/null
+++ b/include/clang/AST/CanonicalType.h
@@ -0,0 +1,739 @@
+//===-- CanonicalType.h - C Language Family Type Representation -*- 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 CanQual class template, which provides access to
+//  canonical types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CANONICAL_TYPE_H
+#define LLVM_CLANG_AST_CANONICAL_TYPE_H
+
+#include "clang/AST/Type.h"
+#include "llvm/Support/Casting.h"
+#include <iterator>
+
+namespace clang {
+
+template<typename T> class CanProxy;
+template<typename T> struct CanProxyAdaptor;
+
+//----------------------------------------------------------------------------//
+// Canonical, qualified type template
+//----------------------------------------------------------------------------//
+
+/// \brief Represents a canonical, potentially-qualified type.
+///
+/// The CanQual template is a lightweight smart pointer that provides access
+/// to the canonical representation of a type, where all typedefs and other
+/// syntactic sugar has been eliminated. A CanQualType may also have various
+/// qualifiers (const, volatile, restrict) attached to it.
+///
+/// The template type parameter @p T is one of the Type classes (PointerType,
+/// BuiltinType, etc.). The type stored within @c CanQual<T> will be of that
+/// type (or some subclass of that type). The typedef @c CanQualType is just
+/// a shorthand for @c CanQual<Type>.
+///
+/// An instance of @c CanQual<T> can be implicitly converted to a
+/// @c CanQual<U> when T is derived from U, which essentially provides an
+/// implicit upcast. For example, @c CanQual<LValueReferenceType> can be
+/// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can
+/// be implicitly converted to a QualType, but the reverse operation requires
+/// a call to ASTContext::getCanonicalType().
+///
+///
+template<typename T = Type>
+class CanQual {
+  /// \brief The actual, canonical type.
+  QualType Stored;
+
+public:
+  /// \brief Constructs a NULL canonical type.
+  CanQual() : Stored() { }
+
+  /// \brief Converting constructor that permits implicit upcasting of
+  /// canonical type pointers.
+  template <typename U>
+  CanQual(const CanQual<U> &Other,
+          typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
+
+  /// \brief Retrieve the underlying type pointer, which refers to a
+  /// canonical type.
+  ///
+  /// The underlying pointer must not be NULL.
+  const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
+
+  /// \brief Retrieve the underlying type pointer, which refers to a
+  /// canonical type, or NULL.
+  ///
+  const T *getTypePtrOrNull() const { 
+    return cast_or_null<T>(Stored.getTypePtrOrNull()); 
+  }
+
+  /// \brief Implicit conversion to a qualified type.
+  operator QualType() const { return Stored; }
+
+  /// \brief Implicit conversion to bool.
+  LLVM_EXPLICIT operator bool() const { return !isNull(); }
+  
+  bool isNull() const {
+    return Stored.isNull();
+  }
+
+  SplitQualType split() const { return Stored.split(); }
+
+  /// \brief Retrieve a canonical type pointer with a different static type,
+  /// upcasting or downcasting as needed.
+  ///
+  /// The getAs() function is typically used to try to downcast to a
+  /// more specific (canonical) type in the type system. For example:
+  ///
+  /// @code
+  /// void f(CanQual<Type> T) {
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) {
+  ///     // look at Ptr's pointee type
+  ///   }
+  /// }
+  /// @endcode
+  ///
+  /// \returns A proxy pointer to the same type, but with the specified
+  /// static type (@p U). If the dynamic type is not the specified static type
+  /// or a derived class thereof, a NULL canonical type.
+  template<typename U> CanProxy<U> getAs() const;
+
+  template<typename U> CanProxy<U> castAs() const;
+
+  /// \brief Overloaded arrow operator that produces a canonical type
+  /// proxy.
+  CanProxy<T> operator->() const;
+
+  /// \brief Retrieve all qualifiers.
+  Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
+
+  /// \brief Retrieve the const/volatile/restrict qualifiers.
+  unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
+
+  /// \brief Determines whether this type has any qualifiers
+  bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
+
+  bool isConstQualified() const {
+    return Stored.isLocalConstQualified();
+  }
+  bool isVolatileQualified() const {
+    return Stored.isLocalVolatileQualified();
+  }
+  bool isRestrictQualified() const {
+    return Stored.isLocalRestrictQualified();
+  }
+
+  /// \brief Determines if this canonical type is furthermore
+  /// canonical as a parameter.  The parameter-canonicalization
+  /// process decays arrays to pointers and drops top-level qualifiers.
+  bool isCanonicalAsParam() const {
+    return Stored.isCanonicalAsParam();
+  }
+
+  /// \brief Retrieve the unqualified form of this type.
+  CanQual<T> getUnqualifiedType() const;
+
+  /// \brief Retrieves a version of this type with const applied.
+  /// Note that this does not always yield a canonical type.
+  QualType withConst() const {
+    return Stored.withConst();
+  }
+
+  /// \brief Determines whether this canonical type is more qualified than
+  /// the @p Other canonical type.
+  bool isMoreQualifiedThan(CanQual<T> Other) const {
+    return Stored.isMoreQualifiedThan(Other.Stored);
+  }
+
+  /// \brief Determines whether this canonical type is at least as qualified as
+  /// the @p Other canonical type.
+  bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
+    return Stored.isAtLeastAsQualifiedAs(Other.Stored);
+  }
+
+  /// \brief If the canonical type is a reference type, returns the type that
+  /// it refers to; otherwise, returns the type itself.
+  CanQual<Type> getNonReferenceType() const;
+
+  /// \brief Retrieve the internal representation of this canonical type.
+  void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
+
+  /// \brief Construct a canonical type from its internal representation.
+  static CanQual<T> getFromOpaquePtr(void *Ptr);
+
+  /// \brief Builds a canonical type from a QualType.
+  ///
+  /// This routine is inherently unsafe, because it requires the user to
+  /// ensure that the given type is a canonical type with the correct
+  // (dynamic) type.
+  static CanQual<T> CreateUnsafe(QualType Other);
+
+  void dump() const { Stored.dump(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(getAsOpaquePtr());
+  }
+};
+
+template<typename T, typename U>
+inline bool operator==(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() == y.getAsOpaquePtr();
+}
+
+template<typename T, typename U>
+inline bool operator!=(CanQual<T> x, CanQual<U> y) {
+  return x.getAsOpaquePtr() != y.getAsOpaquePtr();
+}
+
+/// \brief Represents a canonical, potentially-qualified type.
+typedef CanQual<Type> CanQualType;
+
+inline CanQualType Type::getCanonicalTypeUnqualified() const {
+  return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           CanQualType T) {
+  DB << static_cast<QualType>(T);
+  return DB;
+}
+
+//----------------------------------------------------------------------------//
+// Internal proxy classes used by canonical types
+//----------------------------------------------------------------------------//
+
+#define LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(Accessor)                    \
+CanQualType Accessor() const {                                           \
+return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor());      \
+}
+
+#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor)             \
+Type Accessor() const { return this->getTypePtr()->Accessor(); }
+
+/// \brief Base class of all canonical proxy types, which is responsible for
+/// storing the underlying canonical type and providing basic conversions.
+template<typename T>
+class CanProxyBase {
+protected:
+  CanQual<T> Stored;
+
+public:
+  /// \brief Retrieve the pointer to the underlying Type
+  const T *getTypePtr() const { return Stored.getTypePtr(); }
+
+  /// \brief Implicit conversion to the underlying pointer.
+  ///
+  /// Also provides the ability to use canonical type proxies in a Boolean
+  // context,e.g.,
+  /// @code
+  ///   if (CanQual<PointerType> Ptr = T->getAs<PointerType>()) { ... }
+  /// @endcode
+  operator const T*() const { return this->Stored.getTypePtrOrNull(); }
+
+  /// \brief Try to convert the given canonical type to a specific structural
+  /// type.
+  template<typename U> CanProxy<U> getAs() const {
+    return this->Stored.template getAs<U>();
+  }
+
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type::TypeClass, getTypeClass)
+
+  // Type predicates
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBooleanType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isWideCharType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegralOrEnumerationType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyComplexType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFloatingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isRealType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArithmeticType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDerivedType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isScalarType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAggregateType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isAnyPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVoidPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
+
+  /// \brief Retrieve the proxy-adaptor type.
+  ///
+  /// This arrow operator is used when CanProxyAdaptor has been specialized
+  /// for the given type T. In that case, we reference members of the
+  /// CanProxyAdaptor specialization. Otherwise, this operator will be hidden
+  /// by the arrow operator in the primary CanProxyAdaptor template.
+  const CanProxyAdaptor<T> *operator->() const {
+    return static_cast<const CanProxyAdaptor<T> *>(this);
+  }
+};
+
+/// \brief Replacable canonical proxy adaptor class that provides the link
+/// between a canonical type and the accessors of the type.
+///
+/// The CanProxyAdaptor is a replaceable class template that is instantiated
+/// as part of each canonical proxy type. The primary template merely provides
+/// redirection to the underlying type (T), e.g., @c PointerType. One can
+/// provide specializations of this class template for each underlying type
+/// that provide accessors returning canonical types (@c CanQualType) rather
+/// than the more typical @c QualType, to propagate the notion of "canonical"
+/// through the system.
+template<typename T>
+struct CanProxyAdaptor : CanProxyBase<T> { };
+
+/// \brief Canonical proxy type returned when retrieving the members of a
+/// canonical type or as the result of the @c CanQual<T>::getAs member
+/// function.
+///
+/// The CanProxy type mainly exists as a proxy through which operator-> will
+/// look to either map down to a raw T* (e.g., PointerType*) or to a proxy
+/// type that provides canonical-type access to the fields of the type.
+template<typename T>
+class CanProxy : public CanProxyAdaptor<T> {
+public:
+  /// \brief Build a NULL proxy.
+  CanProxy() { }
+
+  /// \brief Build a proxy to the given canonical type.
+  CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
+
+  /// \brief Implicit conversion to the stored canonical type.
+  operator CanQual<T>() const { return this->Stored; }
+};
+
+} // end namespace clang
+
+namespace llvm {
+
+/// Implement simplify_type for CanQual<T>, so that we can dyn_cast from
+/// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
+/// to return smart pointer (proxies?).
+template<typename T>
+struct simplify_type< ::clang::CanQual<T> > {
+  typedef const T *SimpleType;
+  static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) {
+    return Val.getTypePtr();
+  }
+};
+
+// Teach SmallPtrSet that CanQual<T> is "basically a pointer".
+template<typename T>
+class PointerLikeTypeTraits<clang::CanQual<T> > {
+public:
+  static inline void *getAsVoidPointer(clang::CanQual<T> P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::CanQual<T> getFromVoidPointer(void *P) {
+    return clang::CanQual<T>::getFromOpaquePtr(P);
+  }
+  // qualifier information is encoded in the low bits.
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+namespace clang {
+
+//----------------------------------------------------------------------------//
+// Canonical proxy adaptors for canonical type nodes.
+//----------------------------------------------------------------------------//
+
+/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
+/// into an iterator over CanQualTypes.
+template<typename InputIterator>
+class CanTypeIterator {
+  InputIterator Iter;
+
+public:
+  typedef CanQualType    value_type;
+  typedef value_type     reference;
+  typedef CanProxy<Type> pointer;
+  typedef typename std::iterator_traits<InputIterator>::difference_type
+    difference_type;
+  typedef typename std::iterator_traits<InputIterator>::iterator_category
+    iterator_category;
+
+  CanTypeIterator() : Iter() { }
+  explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { }
+
+  // Input iterator
+  reference operator*() const {
+    return CanQualType::CreateUnsafe(*Iter);
+  }
+
+  pointer operator->() const;
+
+  CanTypeIterator &operator++() {
+    ++Iter;
+    return *this;
+  }
+
+  CanTypeIterator operator++(int) {
+    CanTypeIterator Tmp(*this);
+    ++Iter;
+    return Tmp;
+  }
+
+  friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter == Y.Iter;
+  }
+  friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) {
+    return X.Iter != Y.Iter;
+  }
+
+  // Bidirectional iterator
+  CanTypeIterator &operator--() {
+    --Iter;
+    return *this;
+  }
+
+  CanTypeIterator operator--(int) {
+    CanTypeIterator Tmp(*this);
+    --Iter;
+    return Tmp;
+  }
+
+  // Random access iterator
+  reference operator[](difference_type n) const {
+    return CanQualType::CreateUnsafe(Iter[n]);
+  }
+
+  CanTypeIterator &operator+=(difference_type n) {
+    Iter += n;
+    return *this;
+  }
+
+  CanTypeIterator &operator-=(difference_type n) {
+    Iter -= n;
+    return *this;
+  }
+
+  friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) {
+    X += n;
+    return X;
+  }
+
+  friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) {
+    X += n;
+    return X;
+  }
+
+  friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) {
+    X -= n;
+    return X;
+  }
+
+  friend difference_type operator-(const CanTypeIterator &X,
+                                   const CanTypeIterator &Y) {
+    return X - Y;
+  }
+};
+
+template<>
+struct CanProxyAdaptor<ComplexType> : public CanProxyBase<ComplexType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+};
+
+template<>
+struct CanProxyAdaptor<PointerType> : public CanProxyBase<PointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<BlockPointerType>
+  : public CanProxyBase<BlockPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<ReferenceType> : public CanProxyBase<ReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<LValueReferenceType>
+  : public CanProxyBase<LValueReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<RValueReferenceType>
+  : public CanProxyBase<RValueReferenceType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+};
+
+template<>
+struct CanProxyAdaptor<MemberPointerType>
+  : public CanProxyBase<MemberPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
+};
+
+// CanProxyAdaptors for arrays are intentionally unimplemented because
+// they are not safe.
+template<> struct CanProxyAdaptor<ArrayType>;
+template<> struct CanProxyAdaptor<ConstantArrayType>;
+template<> struct CanProxyAdaptor<IncompleteArrayType>;
+template<> struct CanProxyAdaptor<VariableArrayType>;
+template<> struct CanProxyAdaptor<DependentSizedArrayType>;
+
+template<>
+struct CanProxyAdaptor<DependentSizedExtVectorType>
+  : public CanProxyBase<DependentSizedExtVectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Expr *, getSizeExpr)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getAttributeLoc)
+};
+
+template<>
+struct CanProxyAdaptor<VectorType> : public CanProxyBase<VectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumElements)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionNoProtoType>
+  : public CanProxyBase<FunctionNoProtoType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+};
+
+template<>
+struct CanProxyAdaptor<FunctionProtoType>
+  : public CanProxyBase<FunctionProtoType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
+  CanQualType getParamType(unsigned i) const {
+    return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
+  }
+
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
+
+  typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
+  param_type_iterator;
+
+  param_type_iterator param_type_begin() const {
+    return param_type_iterator(this->getTypePtr()->param_type_begin());
+  }
+
+  param_type_iterator param_type_end() const {
+    return param_type_iterator(this->getTypePtr()->param_type_end());
+  }
+
+  // Note: canonical function types never have exception specifications
+};
+
+template<>
+struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template<>
+struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getUnderlyingExpr)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+};
+
+template <>
+struct CanProxyAdaptor<UnaryTransformType>
+    : public CanProxyBase<UnaryTransformType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
+};
+
+template<>
+struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+
+template<>
+struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
+};
+
+template<>
+struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+};
+
+template<>
+struct CanProxyAdaptor<TemplateTypeParmType>
+  : public CanProxyBase<TemplateTypeParmType> {
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
+};
+
+template<>
+struct CanProxyAdaptor<ObjCObjectType>
+  : public CanProxyBase<ObjCObjectType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
+                                      getInterface)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
+
+  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+
+template<>
+struct CanProxyAdaptor<ObjCObjectPointerType>
+  : public CanProxyBase<ObjCObjectPointerType> {
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceType *,
+                                      getInterfaceType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCClassType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
+
+  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
+};
+
+//----------------------------------------------------------------------------//
+// Method and function definitions
+//----------------------------------------------------------------------------//
+template<typename T>
+inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
+  return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
+}
+
+template<typename T>
+inline CanQual<Type> CanQual<T>::getNonReferenceType() const {
+  if (CanQual<ReferenceType> RefType = getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  else
+    return *this;
+}
+
+template<typename T>
+CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
+  CanQual<T> Result;
+  Result.Stored = QualType::getFromOpaquePtr(Ptr);
+  assert((!Result || Result.Stored.getAsOpaquePtr() == (void*)-1 ||
+          Result.Stored.isCanonical()) && "Type is not canonical!");
+  return Result;
+}
+
+template<typename T>
+CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
+  assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
+  assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
+         "Dynamic type does not meet the static type's requires");
+  CanQual<T> Result;
+  Result.Stored = Other;
+  return Result;
+}
+
+template<typename T>
+template<typename U>
+CanProxy<U> CanQual<T>::getAs() const {
+  ArrayType_cannot_be_used_with_getAs<U> at;
+  (void)at;
+
+  if (Stored.isNull())
+    return CanProxy<U>();
+
+  if (isa<U>(Stored.getTypePtr()))
+    return CanQual<U>::CreateUnsafe(Stored);
+
+  return CanProxy<U>();
+}
+
+template<typename T>
+template<typename U>
+CanProxy<U> CanQual<T>::castAs() const {
+  ArrayType_cannot_be_used_with_getAs<U> at;
+  (void)at;
+
+  assert(!Stored.isNull() && isa<U>(Stored.getTypePtr()));
+  return CanQual<U>::CreateUnsafe(Stored);
+}
+
+template<typename T>
+CanProxy<T> CanQual<T>::operator->() const {
+  return CanProxy<T>(*this);
+}
+
+template<typename InputIterator>
+typename CanTypeIterator<InputIterator>::pointer
+CanTypeIterator<InputIterator>::operator->() const {
+  return CanProxy<Type>(*this);
+}
+
+}
+
+
+#endif // LLVM_CLANG_AST_CANONICAL_TYPE_H
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
new file mode 100644
index 0000000..72ca9f5
--- /dev/null
+++ b/include/clang/AST/CharUnits.h
@@ -0,0 +1,222 @@
+//===--- CharUnits.h - Character units for sizes and offsets ----*- 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 CharUnits class
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_CHARUNITS_H
+#define LLVM_CLANG_AST_CHARUNITS_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+
+namespace clang {
+
+  /// CharUnits - This is an opaque type for sizes expressed in character units.
+  /// Instances of this type represent a quantity as a multiple of the size
+  /// of the standard C type, char, on the target architecture. As an opaque
+  /// type, CharUnits protects you from accidentally combining operations on
+  /// quantities in bit units and character units.
+  ///
+  /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
+  /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
+  /// the same quantity of storage. However, we use the term 'character unit'
+  /// rather than 'byte' to avoid an implication that a character unit is
+  /// exactly 8 bits.
+  ///
+  /// For portability, never assume that a target character is 8 bits wide. Use
+  /// CharUnit values wherever you calculate sizes, offsets, or alignments
+  /// in character units.
+  class CharUnits {
+    public:
+      typedef int64_t QuantityType;
+
+    private:
+      QuantityType Quantity;
+
+      explicit CharUnits(QuantityType C) : Quantity(C) {}
+
+    public:
+
+      /// CharUnits - A default constructor.
+      CharUnits() : Quantity(0) {}
+
+      /// Zero - Construct a CharUnits quantity of zero.
+      static CharUnits Zero() {
+        return CharUnits(0);
+      }
+
+      /// One - Construct a CharUnits quantity of one.
+      static CharUnits One() {
+        return CharUnits(1);
+      }
+
+      /// fromQuantity - Construct a CharUnits quantity from a raw integer type.
+      static CharUnits fromQuantity(QuantityType Quantity) {
+        return CharUnits(Quantity); 
+      }
+
+      // Compound assignment.
+      CharUnits& operator+= (const CharUnits &Other) {
+        Quantity += Other.Quantity;
+        return *this;
+      }
+      CharUnits& operator++ () {
+        ++Quantity;
+        return *this;
+      }
+      CharUnits operator++ (int) {
+        return CharUnits(Quantity++);
+      }
+      CharUnits& operator-= (const CharUnits &Other) {
+        Quantity -= Other.Quantity;
+        return *this;
+      }
+      CharUnits& operator-- () {
+        --Quantity;
+        return *this;
+      }
+      CharUnits operator-- (int) {
+        return CharUnits(Quantity--);
+      }
+       
+      // Comparison operators.
+      bool operator== (const CharUnits &Other) const {
+        return Quantity == Other.Quantity;
+      }
+      bool operator!= (const CharUnits &Other) const {
+        return Quantity != Other.Quantity;
+      }
+
+      // Relational operators.
+      bool operator<  (const CharUnits &Other) const { 
+        return Quantity <  Other.Quantity; 
+      }
+      bool operator<= (const CharUnits &Other) const { 
+        return Quantity <= Other.Quantity;
+      }
+      bool operator>  (const CharUnits &Other) const { 
+        return Quantity >  Other.Quantity; 
+      }
+      bool operator>= (const CharUnits &Other) const { 
+        return Quantity >= Other.Quantity; 
+      }
+
+      // Other predicates.
+      
+      /// isZero - Test whether the quantity equals zero.
+      bool isZero() const     { return Quantity == 0; }
+
+      /// isOne - Test whether the quantity equals one.
+      bool isOne() const      { return Quantity == 1; }
+
+      /// isPositive - Test whether the quantity is greater than zero.
+      bool isPositive() const { return Quantity  > 0; }
+
+      /// isNegative - Test whether the quantity is less than zero.
+      bool isNegative() const { return Quantity  < 0; }
+
+      /// isPowerOfTwo - Test whether the quantity is a power of two.
+      /// Zero is not a power of two.
+      bool isPowerOfTwo() const {
+        return (Quantity & -Quantity) == Quantity;
+      }
+
+      // Arithmetic operators.
+      CharUnits operator* (QuantityType N) const {
+        return CharUnits(Quantity * N);
+      }
+      CharUnits operator/ (QuantityType N) const {
+        return CharUnits(Quantity / N);
+      }
+      QuantityType operator/ (const CharUnits &Other) const {
+        return Quantity / Other.Quantity;
+      }
+      CharUnits operator% (QuantityType N) const {
+        return CharUnits(Quantity % N);
+      }
+      QuantityType operator% (const CharUnits &Other) const {
+        return Quantity % Other.Quantity;
+      }
+      CharUnits operator+ (const CharUnits &Other) const {
+        return CharUnits(Quantity + Other.Quantity);
+      }
+      CharUnits operator- (const CharUnits &Other) const {
+        return CharUnits(Quantity - Other.Quantity);
+      }
+      CharUnits operator- () const {
+        return CharUnits(-Quantity);
+      }
+
+      
+      // Conversions.
+
+      /// getQuantity - Get the raw integer representation of this quantity.
+      QuantityType getQuantity() const { return Quantity; }
+
+      /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
+      /// greater than or equal to this quantity and is a multiple of \p Align.
+      /// Align must be non-zero.
+      CharUnits RoundUpToAlignment(const CharUnits &Align) const {
+        return CharUnits(llvm::RoundUpToAlignment(Quantity, 
+                                                  Align.Quantity));
+      }
+
+      /// Given that this is a non-zero alignment value, what is the
+      /// alignment at the given offset?
+      CharUnits alignmentAtOffset(CharUnits offset) {
+        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
+      }
+
+
+  }; // class CharUnit
+} // namespace clang
+
+inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, 
+                                   const clang::CharUnits &CU) {
+  return CU * Scale;
+}
+
+namespace llvm {
+
+template<> struct DenseMapInfo<clang::CharUnits> {
+  static clang::CharUnits getEmptyKey() {
+    clang::CharUnits::QuantityType Quantity =
+      DenseMapInfo<clang::CharUnits::QuantityType>::getEmptyKey();
+
+    return clang::CharUnits::fromQuantity(Quantity);
+  }
+
+  static clang::CharUnits getTombstoneKey() {
+    clang::CharUnits::QuantityType Quantity =
+      DenseMapInfo<clang::CharUnits::QuantityType>::getTombstoneKey();
+    
+    return clang::CharUnits::fromQuantity(Quantity);    
+  }
+
+  static unsigned getHashValue(const clang::CharUnits &CU) {
+    clang::CharUnits::QuantityType Quantity = CU.getQuantity();
+    return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity);
+  }
+
+  static bool isEqual(const clang::CharUnits &LHS, 
+                      const clang::CharUnits &RHS) {
+    return LHS == RHS;
+  }
+};
+
+template <> struct isPodLike<clang::CharUnits> {
+  static const bool value = true;
+};
+  
+} // end namespace llvm
+
+#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
new file mode 100644
index 0000000..e18fe9a
--- /dev/null
+++ b/include/clang/AST/Comment.h
@@ -0,0 +1,1140 @@
+//===--- Comment.h - Comment AST nodes --------------------------*- 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 comment AST nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMMENT_H
+#define LLVM_CLANG_AST_COMMENT_H
+
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+class Decl;
+class ParmVarDecl;
+class TemplateParameterList;
+
+namespace comments {
+class FullComment;
+
+/// Describes the syntax that was used in a documentation command.
+///
+/// Exact values of this enumeration are important because they used to select
+/// parts of diagnostic messages.  Audit diagnostics before changing or adding
+/// a new value.
+enum CommandMarkerKind {
+  /// Command started with a backslash character:
+  /// \code
+  ///   \foo
+  /// \endcode
+  CMK_Backslash = 0,
+
+  /// Command started with an 'at' character:
+  /// \code
+  ///   @foo
+  /// \endcode
+  CMK_At = 1
+};
+
+/// Any part of the comment.
+/// Abstract class.
+class Comment {
+protected:
+  /// Preferred location to show caret.
+  SourceLocation Loc;
+
+  /// Source range of this AST node.
+  SourceRange Range;
+
+  class CommentBitfields {
+    friend class Comment;
+
+    /// Type of this AST node.
+    unsigned Kind : 8;
+  };
+  enum { NumCommentBits = 8 };
+
+  class InlineContentCommentBitfields {
+    friend class InlineContentComment;
+
+    unsigned : NumCommentBits;
+
+    /// True if there is a newline after this inline content node.
+    /// (There is no separate AST node for a newline.)
+    unsigned HasTrailingNewline : 1;
+  };
+  enum { NumInlineContentCommentBits = NumCommentBits + 1 };
+
+  class TextCommentBitfields {
+    friend class TextComment;
+
+    unsigned : NumInlineContentCommentBits;
+
+    /// True if \c IsWhitespace field contains a valid value.
+    mutable unsigned IsWhitespaceValid : 1;
+
+    /// True if this comment AST node contains only whitespace.
+    mutable unsigned IsWhitespace : 1;
+  };
+  enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
+
+  class InlineCommandCommentBitfields {
+    friend class InlineCommandComment;
+
+    unsigned : NumInlineContentCommentBits;
+
+    unsigned RenderKind : 2;
+    unsigned CommandID : 8;
+  };
+  enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
+
+  class HTMLTagCommentBitfields {
+    friend class HTMLTagComment;
+
+    unsigned : NumInlineContentCommentBits;
+
+    /// True if we found that this tag is malformed in some way.
+    unsigned IsMalformed : 1;
+  };
+  enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
+
+  class HTMLStartTagCommentBitfields {
+    friend class HTMLStartTagComment;
+
+    unsigned : NumHTMLTagCommentBits;
+
+    /// True if this tag is self-closing (e. g., <br />).  This is based on tag
+    /// spelling in comment (plain <br> would not set this flag).
+    unsigned IsSelfClosing : 1;
+  };
+  enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
+
+  class ParagraphCommentBitfields {
+    friend class ParagraphComment;
+
+    unsigned : NumCommentBits;
+
+    /// True if \c IsWhitespace field contains a valid value.
+    mutable unsigned IsWhitespaceValid : 1;
+
+    /// True if this comment AST node contains only whitespace.
+    mutable unsigned IsWhitespace : 1;
+  };
+  enum { NumParagraphCommentBits = NumCommentBits + 2 };
+
+  class BlockCommandCommentBitfields {
+    friend class BlockCommandComment;
+
+    unsigned : NumCommentBits;
+
+    unsigned CommandID : 8;
+
+    /// Describes the syntax that was used in a documentation command.
+    /// Contains values from CommandMarkerKind enum.
+    unsigned CommandMarker : 1;
+  };
+  enum { NumBlockCommandCommentBits = NumCommentBits + 9 };
+
+  class ParamCommandCommentBitfields {
+    friend class ParamCommandComment;
+
+    unsigned : NumBlockCommandCommentBits;
+
+    /// Parameter passing direction, see ParamCommandComment::PassDirection.
+    unsigned Direction : 2;
+
+    /// True if direction was specified explicitly in the comment.
+    unsigned IsDirectionExplicit : 1;
+  };
+  enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
+
+  union {
+    CommentBitfields CommentBits;
+    InlineContentCommentBitfields InlineContentCommentBits;
+    TextCommentBitfields TextCommentBits;
+    InlineCommandCommentBitfields InlineCommandCommentBits;
+    HTMLTagCommentBitfields HTMLTagCommentBits;
+    HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
+    ParagraphCommentBitfields ParagraphCommentBits;
+    BlockCommandCommentBitfields BlockCommandCommentBits;
+    ParamCommandCommentBitfields ParamCommandCommentBits;
+  };
+
+  void setSourceRange(SourceRange SR) {
+    Range = SR;
+  }
+
+  void setLocation(SourceLocation L) {
+    Loc = L;
+  }
+
+public:
+  enum CommentKind {
+    NoCommentKind = 0,
+#define COMMENT(CLASS, PARENT) CLASS##Kind,
+#define COMMENT_RANGE(BASE, FIRST, LAST) \
+    First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
+#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
+    First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
+#define ABSTRACT_COMMENT(COMMENT)
+#include "clang/AST/CommentNodes.inc"
+  };
+
+  Comment(CommentKind K,
+          SourceLocation LocBegin,
+          SourceLocation LocEnd) :
+      Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
+    CommentBits.Kind = K;
+  }
+
+  CommentKind getCommentKind() const {
+    return static_cast<CommentKind>(CommentBits.Kind);
+  }
+
+  const char *getCommentKindName() const;
+
+  void dump() const;
+  void dumpColor() const;
+  void dump(const ASTContext &Context) const;
+  void dump(raw_ostream &OS, const CommandTraits *Traits,
+            const SourceManager *SM) const;
+
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return Range.getBegin();
+  }
+
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return Range.getEnd();
+  }
+
+  SourceLocation getLocation() const LLVM_READONLY { return Loc; }
+
+  typedef Comment * const *child_iterator;
+
+  child_iterator child_begin() const;
+  child_iterator child_end() const;
+
+  // TODO: const child iterator
+
+  unsigned child_count() const {
+    return child_end() - child_begin();
+  }
+};
+
+/// Inline content (contained within a block).
+/// Abstract class.
+class InlineContentComment : public Comment {
+protected:
+  InlineContentComment(CommentKind K,
+                       SourceLocation LocBegin,
+                       SourceLocation LocEnd) :
+      Comment(K, LocBegin, LocEnd) {
+    InlineContentCommentBits.HasTrailingNewline = 0;
+  }
+
+public:
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() >= FirstInlineContentCommentConstant &&
+           C->getCommentKind() <= LastInlineContentCommentConstant;
+  }
+
+  void addTrailingNewline() {
+    InlineContentCommentBits.HasTrailingNewline = 1;
+  }
+
+  bool hasTrailingNewline() const {
+    return InlineContentCommentBits.HasTrailingNewline;
+  }
+};
+
+/// Plain text.
+class TextComment : public InlineContentComment {
+  StringRef Text;
+
+public:
+  TextComment(SourceLocation LocBegin,
+              SourceLocation LocEnd,
+              StringRef Text) :
+      InlineContentComment(TextCommentKind, LocBegin, LocEnd),
+      Text(Text) {
+    TextCommentBits.IsWhitespaceValid = false;
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == TextCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+
+  StringRef getText() const LLVM_READONLY { return Text; }
+
+  bool isWhitespace() const {
+    if (TextCommentBits.IsWhitespaceValid)
+      return TextCommentBits.IsWhitespace;
+
+    TextCommentBits.IsWhitespace = isWhitespaceNoCache();
+    TextCommentBits.IsWhitespaceValid = true;
+    return TextCommentBits.IsWhitespace;
+  }
+
+private:
+  bool isWhitespaceNoCache() const;
+};
+
+/// A command with word-like arguments that is considered inline content.
+class InlineCommandComment : public InlineContentComment {
+public:
+  struct Argument {
+    SourceRange Range;
+    StringRef Text;
+
+    Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
+  };
+
+  /// The most appropriate rendering mode for this command, chosen on command
+  /// semantics in Doxygen.
+  enum RenderKind {
+    RenderNormal,
+    RenderBold,
+    RenderMonospaced,
+    RenderEmphasized
+  };
+
+protected:
+  /// Command arguments.
+  ArrayRef<Argument> Args;
+
+public:
+  InlineCommandComment(SourceLocation LocBegin,
+                       SourceLocation LocEnd,
+                       unsigned CommandID,
+                       RenderKind RK,
+                       ArrayRef<Argument> Args) :
+      InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
+      Args(Args) {
+    InlineCommandCommentBits.RenderKind = RK;
+    InlineCommandCommentBits.CommandID = CommandID;
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == InlineCommandCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+
+  unsigned getCommandID() const {
+    return InlineCommandCommentBits.CommandID;
+  }
+
+  StringRef getCommandName(const CommandTraits &Traits) const {
+    return Traits.getCommandInfo(getCommandID())->Name;
+  }
+
+  SourceRange getCommandNameRange() const {
+    return SourceRange(getLocStart().getLocWithOffset(-1),
+                       getLocEnd());
+  }
+
+  RenderKind getRenderKind() const {
+    return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
+  }
+
+  unsigned getNumArgs() const {
+    return Args.size();
+  }
+
+  StringRef getArgText(unsigned Idx) const {
+    return Args[Idx].Text;
+  }
+
+  SourceRange getArgRange(unsigned Idx) const {
+    return Args[Idx].Range;
+  }
+};
+
+/// Abstract class for opening and closing HTML tags.  HTML tags are always
+/// treated as inline content (regardless HTML semantics).
+class HTMLTagComment : public InlineContentComment {
+protected:
+  StringRef TagName;
+  SourceRange TagNameRange;
+
+  HTMLTagComment(CommentKind K,
+                 SourceLocation LocBegin,
+                 SourceLocation LocEnd,
+                 StringRef TagName,
+                 SourceLocation TagNameBegin,
+                 SourceLocation TagNameEnd) :
+      InlineContentComment(K, LocBegin, LocEnd),
+      TagName(TagName),
+      TagNameRange(TagNameBegin, TagNameEnd) {
+    setLocation(TagNameBegin);
+    HTMLTagCommentBits.IsMalformed = 0;
+  }
+
+public:
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
+           C->getCommentKind() <= LastHTMLTagCommentConstant;
+  }
+
+  StringRef getTagName() const LLVM_READONLY { return TagName; }
+
+  SourceRange getTagNameSourceRange() const LLVM_READONLY {
+    SourceLocation L = getLocation();
+    return SourceRange(L.getLocWithOffset(1),
+                       L.getLocWithOffset(1 + TagName.size()));
+  }
+
+  bool isMalformed() const {
+    return HTMLTagCommentBits.IsMalformed;
+  }
+
+  void setIsMalformed() {
+    HTMLTagCommentBits.IsMalformed = 1;
+  }
+};
+
+/// An opening HTML tag with attributes.
+class HTMLStartTagComment : public HTMLTagComment {
+public:
+  class Attribute {
+  public:
+    SourceLocation NameLocBegin;
+    StringRef Name;
+
+    SourceLocation EqualsLoc;
+
+    SourceRange ValueRange;
+    StringRef Value;
+
+    Attribute() { }
+
+    Attribute(SourceLocation NameLocBegin, StringRef Name) :
+        NameLocBegin(NameLocBegin), Name(Name),
+        EqualsLoc(SourceLocation()),
+        ValueRange(SourceRange()), Value(StringRef())
+    { }
+
+    Attribute(SourceLocation NameLocBegin, StringRef Name,
+              SourceLocation EqualsLoc,
+              SourceRange ValueRange, StringRef Value) :
+        NameLocBegin(NameLocBegin), Name(Name),
+        EqualsLoc(EqualsLoc),
+        ValueRange(ValueRange), Value(Value)
+    { }
+
+    SourceLocation getNameLocEnd() const {
+      return NameLocBegin.getLocWithOffset(Name.size());
+    }
+
+    SourceRange getNameRange() const {
+      return SourceRange(NameLocBegin, getNameLocEnd());
+    }
+  };
+
+private:
+  ArrayRef<Attribute> Attributes;
+
+public:
+  HTMLStartTagComment(SourceLocation LocBegin,
+                      StringRef TagName) :
+      HTMLTagComment(HTMLStartTagCommentKind,
+                     LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
+                     TagName,
+                     LocBegin.getLocWithOffset(1),
+                     LocBegin.getLocWithOffset(1 + TagName.size())) {
+    HTMLStartTagCommentBits.IsSelfClosing = false;
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == HTMLStartTagCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+
+  unsigned getNumAttrs() const {
+    return Attributes.size();
+  }
+
+  const Attribute &getAttr(unsigned Idx) const {
+    return Attributes[Idx];
+  }
+
+  void setAttrs(ArrayRef<Attribute> Attrs) {
+    Attributes = Attrs;
+    if (!Attrs.empty()) {
+      const Attribute &Attr = Attrs.back();
+      SourceLocation L = Attr.ValueRange.getEnd();
+      if (L.isValid())
+        Range.setEnd(L);
+      else {
+        Range.setEnd(Attr.getNameLocEnd());
+      }
+    }
+  }
+
+  void setGreaterLoc(SourceLocation GreaterLoc) {
+    Range.setEnd(GreaterLoc);
+  }
+
+  bool isSelfClosing() const {
+    return HTMLStartTagCommentBits.IsSelfClosing;
+  }
+
+  void setSelfClosing() {
+    HTMLStartTagCommentBits.IsSelfClosing = true;
+  }
+};
+
+/// A closing HTML tag.
+class HTMLEndTagComment : public HTMLTagComment {
+public:
+  HTMLEndTagComment(SourceLocation LocBegin,
+                    SourceLocation LocEnd,
+                    StringRef TagName) :
+      HTMLTagComment(HTMLEndTagCommentKind,
+                     LocBegin, LocEnd,
+                     TagName,
+                     LocBegin.getLocWithOffset(2),
+                     LocBegin.getLocWithOffset(2 + TagName.size()))
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == HTMLEndTagCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+};
+
+/// Block content (contains inline content).
+/// Abstract class.
+class BlockContentComment : public Comment {
+protected:
+  BlockContentComment(CommentKind K,
+                      SourceLocation LocBegin,
+                      SourceLocation LocEnd) :
+      Comment(K, LocBegin, LocEnd)
+  { }
+
+public:
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() >= FirstBlockContentCommentConstant &&
+           C->getCommentKind() <= LastBlockContentCommentConstant;
+  }
+};
+
+/// A single paragraph that contains inline content.
+class ParagraphComment : public BlockContentComment {
+  ArrayRef<InlineContentComment *> Content;
+
+public:
+  ParagraphComment(ArrayRef<InlineContentComment *> Content) :
+      BlockContentComment(ParagraphCommentKind,
+                          SourceLocation(),
+                          SourceLocation()),
+      Content(Content) {
+    if (Content.empty()) {
+      ParagraphCommentBits.IsWhitespace = true;
+      ParagraphCommentBits.IsWhitespaceValid = true;
+      return;
+    }
+
+    ParagraphCommentBits.IsWhitespaceValid = false;
+
+    setSourceRange(SourceRange(Content.front()->getLocStart(),
+                               Content.back()->getLocEnd()));
+    setLocation(Content.front()->getLocStart());
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == ParagraphCommentKind;
+  }
+
+  child_iterator child_begin() const {
+    return reinterpret_cast<child_iterator>(Content.begin());
+  }
+
+  child_iterator child_end() const {
+    return reinterpret_cast<child_iterator>(Content.end());
+  }
+
+  bool isWhitespace() const {
+    if (ParagraphCommentBits.IsWhitespaceValid)
+      return ParagraphCommentBits.IsWhitespace;
+
+    ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
+    ParagraphCommentBits.IsWhitespaceValid = true;
+    return ParagraphCommentBits.IsWhitespace;
+  }
+
+private:
+  bool isWhitespaceNoCache() const;
+};
+
+/// A command that has zero or more word-like arguments (number of word-like
+/// arguments depends on command name) and a paragraph as an argument
+/// (e. g., \\brief).
+class BlockCommandComment : public BlockContentComment {
+public:
+  struct Argument {
+    SourceRange Range;
+    StringRef Text;
+
+    Argument() { }
+    Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
+  };
+
+protected:
+  /// Word-like arguments.
+  ArrayRef<Argument> Args;
+
+  /// Paragraph argument.
+  ParagraphComment *Paragraph;
+
+  BlockCommandComment(CommentKind K,
+                      SourceLocation LocBegin,
+                      SourceLocation LocEnd,
+                      unsigned CommandID,
+                      CommandMarkerKind CommandMarker) :
+      BlockContentComment(K, LocBegin, LocEnd),
+      Paragraph(nullptr) {
+    setLocation(getCommandNameBeginLoc());
+    BlockCommandCommentBits.CommandID = CommandID;
+    BlockCommandCommentBits.CommandMarker = CommandMarker;
+  }
+
+public:
+  BlockCommandComment(SourceLocation LocBegin,
+                      SourceLocation LocEnd,
+                      unsigned CommandID,
+                      CommandMarkerKind CommandMarker) :
+      BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
+      Paragraph(nullptr) {
+    setLocation(getCommandNameBeginLoc());
+    BlockCommandCommentBits.CommandID = CommandID;
+    BlockCommandCommentBits.CommandMarker = CommandMarker;
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
+           C->getCommentKind() <= LastBlockCommandCommentConstant;
+  }
+
+  child_iterator child_begin() const {
+    return reinterpret_cast<child_iterator>(&Paragraph);
+  }
+
+  child_iterator child_end() const {
+    return reinterpret_cast<child_iterator>(&Paragraph + 1);
+  }
+
+  unsigned getCommandID() const {
+    return BlockCommandCommentBits.CommandID;
+  }
+
+  StringRef getCommandName(const CommandTraits &Traits) const {
+    return Traits.getCommandInfo(getCommandID())->Name;
+  }
+
+  SourceLocation getCommandNameBeginLoc() const {
+    return getLocStart().getLocWithOffset(1);
+  }
+
+  SourceRange getCommandNameRange(const CommandTraits &Traits) const {
+    StringRef Name = getCommandName(Traits);
+    return SourceRange(getCommandNameBeginLoc(),
+                       getLocStart().getLocWithOffset(1 + Name.size()));
+  }
+
+  unsigned getNumArgs() const {
+    return Args.size();
+  }
+
+  StringRef getArgText(unsigned Idx) const {
+    return Args[Idx].Text;
+  }
+
+  SourceRange getArgRange(unsigned Idx) const {
+    return Args[Idx].Range;
+  }
+
+  void setArgs(ArrayRef<Argument> A) {
+    Args = A;
+    if (Args.size() > 0) {
+      SourceLocation NewLocEnd = Args.back().Range.getEnd();
+      if (NewLocEnd.isValid())
+        setSourceRange(SourceRange(getLocStart(), NewLocEnd));
+    }
+  }
+
+  ParagraphComment *getParagraph() const LLVM_READONLY {
+    return Paragraph;
+  }
+
+  bool hasNonWhitespaceParagraph() const {
+    return Paragraph && !Paragraph->isWhitespace();
+  }
+
+  void setParagraph(ParagraphComment *PC) {
+    Paragraph = PC;
+    SourceLocation NewLocEnd = PC->getLocEnd();
+    if (NewLocEnd.isValid())
+      setSourceRange(SourceRange(getLocStart(), NewLocEnd));
+  }
+
+  CommandMarkerKind getCommandMarker() const LLVM_READONLY {
+    return static_cast<CommandMarkerKind>(
+        BlockCommandCommentBits.CommandMarker);
+  }
+};
+
+/// Doxygen \\param command.
+class ParamCommandComment : public BlockCommandComment {
+private:
+  /// Parameter index in the function declaration.
+  unsigned ParamIndex;
+
+public:
+  enum : unsigned {
+    InvalidParamIndex = ~0U,
+    VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
+  };
+
+  ParamCommandComment(SourceLocation LocBegin,
+                      SourceLocation LocEnd,
+                      unsigned CommandID,
+                      CommandMarkerKind CommandMarker) :
+      BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
+                          CommandID, CommandMarker),
+      ParamIndex(InvalidParamIndex) {
+    ParamCommandCommentBits.Direction = In;
+    ParamCommandCommentBits.IsDirectionExplicit = false;
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == ParamCommandCommentKind;
+  }
+
+  enum PassDirection {
+    In,
+    Out,
+    InOut
+  };
+
+  static const char *getDirectionAsString(PassDirection D);
+
+  PassDirection getDirection() const LLVM_READONLY {
+    return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
+  }
+
+  bool isDirectionExplicit() const LLVM_READONLY {
+    return ParamCommandCommentBits.IsDirectionExplicit;
+  }
+
+  void setDirection(PassDirection Direction, bool Explicit) {
+    ParamCommandCommentBits.Direction = Direction;
+    ParamCommandCommentBits.IsDirectionExplicit = Explicit;
+  }
+
+  bool hasParamName() const {
+    return getNumArgs() > 0;
+  }
+
+  StringRef getParamName(const FullComment *FC) const;
+
+  StringRef getParamNameAsWritten() const {
+    return Args[0].Text;
+  }
+
+  SourceRange getParamNameRange() const {
+    return Args[0].Range;
+  }
+
+  bool isParamIndexValid() const LLVM_READONLY {
+    return ParamIndex != InvalidParamIndex;
+  }
+
+  bool isVarArgParam() const LLVM_READONLY {
+    return ParamIndex == VarArgParamIndex;
+  }
+
+  void setIsVarArgParam() {
+    ParamIndex = VarArgParamIndex;
+    assert(isParamIndexValid());
+  }
+
+  unsigned getParamIndex() const LLVM_READONLY {
+    assert(isParamIndexValid());
+    assert(!isVarArgParam());
+    return ParamIndex;
+  }
+
+  void setParamIndex(unsigned Index) {
+    ParamIndex = Index;
+    assert(isParamIndexValid());
+    assert(!isVarArgParam());
+  }
+};
+
+/// Doxygen \\tparam command, describes a template parameter.
+class TParamCommandComment : public BlockCommandComment {
+private:
+  /// If this template parameter name was resolved (found in template parameter
+  /// list), then this stores a list of position indexes in all template
+  /// parameter lists.
+  ///
+  /// For example:
+  /// \verbatim
+  ///     template<typename C, template<typename T> class TT>
+  ///     void test(TT<int> aaa);
+  /// \endverbatim
+  /// For C:  Position = { 0 }
+  /// For TT: Position = { 1 }
+  /// For T:  Position = { 1, 0 }
+  ArrayRef<unsigned> Position;
+
+public:
+  TParamCommandComment(SourceLocation LocBegin,
+                       SourceLocation LocEnd,
+                       unsigned CommandID,
+                       CommandMarkerKind CommandMarker) :
+      BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
+                          CommandMarker)
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == TParamCommandCommentKind;
+  }
+
+  bool hasParamName() const {
+    return getNumArgs() > 0;
+  }
+
+  StringRef getParamName(const FullComment *FC) const;
+
+  StringRef getParamNameAsWritten() const {
+    return Args[0].Text;
+  }
+
+  SourceRange getParamNameRange() const {
+    return Args[0].Range;
+  }
+
+  bool isPositionValid() const LLVM_READONLY {
+    return !Position.empty();
+  }
+
+  unsigned getDepth() const {
+    assert(isPositionValid());
+    return Position.size();
+  }
+
+  unsigned getIndex(unsigned Depth) const {
+    assert(isPositionValid());
+    return Position[Depth];
+  }
+
+  void setPosition(ArrayRef<unsigned> NewPosition) {
+    Position = NewPosition;
+    assert(isPositionValid());
+  }
+};
+
+/// A line of text contained in a verbatim block.
+class VerbatimBlockLineComment : public Comment {
+  StringRef Text;
+
+public:
+  VerbatimBlockLineComment(SourceLocation LocBegin,
+                           StringRef Text) :
+      Comment(VerbatimBlockLineCommentKind,
+              LocBegin,
+              LocBegin.getLocWithOffset(Text.size())),
+      Text(Text)
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == VerbatimBlockLineCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+
+  StringRef getText() const LLVM_READONLY {
+    return Text;
+  }
+};
+
+/// A verbatim block command (e. g., preformatted code).  Verbatim block has an
+/// opening and a closing command and contains multiple lines of text
+/// (VerbatimBlockLineComment nodes).
+class VerbatimBlockComment : public BlockCommandComment {
+protected:
+  StringRef CloseName;
+  SourceLocation CloseNameLocBegin;
+  ArrayRef<VerbatimBlockLineComment *> Lines;
+
+public:
+  VerbatimBlockComment(SourceLocation LocBegin,
+                       SourceLocation LocEnd,
+                       unsigned CommandID) :
+      BlockCommandComment(VerbatimBlockCommentKind,
+                          LocBegin, LocEnd, CommandID,
+                          CMK_At) // FIXME: improve source fidelity.
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == VerbatimBlockCommentKind;
+  }
+
+  child_iterator child_begin() const {
+    return reinterpret_cast<child_iterator>(Lines.begin());
+  }
+
+  child_iterator child_end() const {
+    return reinterpret_cast<child_iterator>(Lines.end());
+  }
+
+  void setCloseName(StringRef Name, SourceLocation LocBegin) {
+    CloseName = Name;
+    CloseNameLocBegin = LocBegin;
+  }
+
+  void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
+    Lines = L;
+  }
+
+  StringRef getCloseName() const {
+    return CloseName;
+  }
+
+  unsigned getNumLines() const {
+    return Lines.size();
+  }
+
+  StringRef getText(unsigned LineIdx) const {
+    return Lines[LineIdx]->getText();
+  }
+};
+
+/// A verbatim line command.  Verbatim line has an opening command, a single
+/// line of text (up to the newline after the opening command) and has no
+/// closing command.
+class VerbatimLineComment : public BlockCommandComment {
+protected:
+  StringRef Text;
+  SourceLocation TextBegin;
+
+public:
+  VerbatimLineComment(SourceLocation LocBegin,
+                      SourceLocation LocEnd,
+                      unsigned CommandID,
+                      SourceLocation TextBegin,
+                      StringRef Text) :
+      BlockCommandComment(VerbatimLineCommentKind,
+                          LocBegin, LocEnd,
+                          CommandID,
+                          CMK_At), // FIXME: improve source fidelity.
+      Text(Text),
+      TextBegin(TextBegin)
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == VerbatimLineCommentKind;
+  }
+
+  child_iterator child_begin() const { return nullptr; }
+
+  child_iterator child_end() const { return nullptr; }
+
+  StringRef getText() const {
+    return Text;
+  }
+
+  SourceRange getTextRange() const {
+    return SourceRange(TextBegin, getLocEnd());
+  }
+};
+
+/// Information about the declaration, useful to clients of FullComment.
+struct DeclInfo {
+  /// Declaration the comment is actually attached to (in the source).
+  /// Should not be NULL.
+  const Decl *CommentDecl;
+  
+  /// CurrentDecl is the declaration with which the FullComment is associated.
+  ///
+  /// It can be different from \c CommentDecl.  It happens when we we decide
+  /// that the comment originally attached to \c CommentDecl is fine for
+  /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
+  /// \c CommentDecl).
+  ///
+  /// The information in the DeclInfo corresponds to CurrentDecl.
+  const Decl *CurrentDecl;
+  
+  /// Parameters that can be referenced by \\param if \c CommentDecl is something
+  /// that we consider a "function".
+  ArrayRef<const ParmVarDecl *> ParamVars;
+
+  /// Function return type if \c CommentDecl is something that we consider
+  /// a "function".
+  QualType ReturnType;
+
+  /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
+  /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
+  /// true).
+  const TemplateParameterList *TemplateParameters;
+
+  /// A simplified description of \c CommentDecl kind that should be good enough
+  /// for documentation rendering purposes.
+  enum DeclKind {
+    /// Everything else not explicitly mentioned below.
+    OtherKind,
+
+    /// Something that we consider a "function":
+    /// \li function,
+    /// \li function template,
+    /// \li function template specialization,
+    /// \li member function,
+    /// \li member function template,
+    /// \li member function template specialization,
+    /// \li ObjC method,
+    /// \li a typedef for a function pointer, member function pointer,
+    ///     ObjC block.
+    FunctionKind,
+
+    /// Something that we consider a "class":
+    /// \li class/struct,
+    /// \li class template,
+    /// \li class template (partial) specialization.
+    ClassKind,
+
+    /// Something that we consider a "variable":
+    /// \li namespace scope variables;
+    /// \li static and non-static class data members;
+    /// \li enumerators.
+    VariableKind,
+
+    /// A C++ namespace.
+    NamespaceKind,
+
+    /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
+    /// see \c TypedefNameDecl.
+    TypedefKind,
+
+    /// An enumeration or scoped enumeration.
+    EnumKind
+  };
+
+  /// What kind of template specialization \c CommentDecl is.
+  enum TemplateDeclKind {
+    NotTemplate,
+    Template,
+    TemplateSpecialization,
+    TemplatePartialSpecialization
+  };
+
+  /// If false, only \c CommentDecl is valid.
+  unsigned IsFilled : 1;
+
+  /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
+  unsigned Kind : 3;
+
+  /// Is \c CommentDecl a template declaration.
+  unsigned TemplateKind : 2;
+
+  /// Is \c CommentDecl an ObjCMethodDecl.
+  unsigned IsObjCMethod : 1;
+
+  /// Is \c CommentDecl a non-static member function of C++ class or
+  /// instance method of ObjC class.
+  /// Can be true only if \c IsFunctionDecl is true.
+  unsigned IsInstanceMethod : 1;
+
+  /// Is \c CommentDecl a static member function of C++ class or
+  /// class method of ObjC class.
+  /// Can be true only if \c IsFunctionDecl is true.
+  unsigned IsClassMethod : 1;
+
+  void fill();
+
+  DeclKind getKind() const LLVM_READONLY {
+    return static_cast<DeclKind>(Kind);
+  }
+
+  TemplateDeclKind getTemplateKind() const LLVM_READONLY {
+    return static_cast<TemplateDeclKind>(TemplateKind);
+  }
+};
+
+/// A full comment attached to a declaration, contains block content.
+class FullComment : public Comment {
+  ArrayRef<BlockContentComment *> Blocks;
+  DeclInfo *ThisDeclInfo;
+
+public:
+  FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
+      Comment(FullCommentKind, SourceLocation(), SourceLocation()),
+      Blocks(Blocks), ThisDeclInfo(D) {
+    if (Blocks.empty())
+      return;
+
+    setSourceRange(SourceRange(Blocks.front()->getLocStart(),
+                               Blocks.back()->getLocEnd()));
+    setLocation(Blocks.front()->getLocStart());
+  }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == FullCommentKind;
+  }
+
+  child_iterator child_begin() const {
+    return reinterpret_cast<child_iterator>(Blocks.begin());
+  }
+
+  child_iterator child_end() const {
+    return reinterpret_cast<child_iterator>(Blocks.end()); 
+  }
+
+  const Decl *getDecl() const LLVM_READONLY {
+    return ThisDeclInfo->CommentDecl;
+  }
+  
+  const DeclInfo *getDeclInfo() const LLVM_READONLY {
+    if (!ThisDeclInfo->IsFilled)
+      ThisDeclInfo->fill();
+    return ThisDeclInfo;
+  }
+  
+  ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
+  
+};
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
new file mode 100644
index 0000000..5d50886
--- /dev/null
+++ b/include/clang/AST/CommentBriefParser.h
@@ -0,0 +1,55 @@
+//===--- CommentBriefParser.h - Dumb comment parser -------------*- 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 very simple Doxygen comment parser.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
+#define LLVM_CLANG_AST_BRIEF_COMMENT_PARSER_H
+
+#include "clang/AST/CommentLexer.h"
+
+namespace clang {
+namespace comments {
+
+/// A very simple comment parser that extracts "a brief description".
+///
+/// Due to a variety of comment styles, it considers the following as "a brief
+/// description", in order of priority:
+/// \li a \\brief or \\short command,
+/// \li the first paragraph,
+/// \li a \\result or \\return or \\returns paragraph.
+class BriefParser {
+  Lexer &L;
+
+  const CommandTraits &Traits;
+
+  /// Current lookahead token.
+  Token Tok;
+
+  SourceLocation ConsumeToken() {
+    SourceLocation Loc = Tok.getLocation();
+    L.lex(Tok);
+    return Loc;
+  }
+
+public:
+  BriefParser(Lexer &L, const CommandTraits &Traits);
+
+  /// Return the best "brief description" we can find.
+  std::string Parse();
+};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentCommandInfo.inc b/include/clang/AST/CommentCommandInfo.inc
new file mode 100644
index 0000000..a75b516
--- /dev/null
+++ b/include/clang/AST/CommentCommandInfo.inc
@@ -0,0 +1,800 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*A list of commands useable in documentation comments                        *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+namespace {
+const CommandInfo Commands[] = {
+  { "a", "", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "abstract", "", 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "addtogroup", "", 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "arg", "", 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "attention", "", 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "author", "", 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "authors", "", 6, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "b", "", 7, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "brief", "", 8, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "bug", "", 9, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "c", "", 10, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "callback", "", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+  { "category", "", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "class", "", 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
+  { "classdesign", "", 14, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "coclass", "", 15, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "code", "endcode", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endcode", "", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "const", "", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "constant", "", 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "copyright", "", 20, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "date", "", 21, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "def", "", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "defgroup", "", 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "dependency", "", 24, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "deprecated", "", 25, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "details", "", 26, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "discussion", "", 27, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "dot", "enddot", 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "enddot", "", 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "e", "", 30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "em", "", 31, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "enum", "", 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "exception", "", 33, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "f{", "f}", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "f}", "", 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "f[", "f]", 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "f]", "", 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "f$", "f$", 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "fn", "", 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "function", "", 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+  { "functiongroup", "", 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+  { "headerfile", "", 42, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "helper", "", 43, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "helperclass", "", 44, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "helps", "", 45, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "htmlonly", "endhtmlonly", 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endhtmlonly", "", 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "ingroup", "", 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "instancesize", "", 49, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "interface", "", 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
+  { "invariant", "", 51, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "latexonly", "endlatexonly", 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endlatexonly", "", 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "li", "", 54, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "link", "/link", 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "/link", "", 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "mainpage", "", 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "manonly", "endmanonly", 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endmanonly", "", 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "method", "", 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+  { "methodgroup", "", 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+  { "msc", "endmsc", 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endmsc", "", 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "name", "", 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "namespace", "", 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "note", "", 66, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "overload", "", 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "ownership", "", 68, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "p", "", 69, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "par", "", 70, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "paragraph", "", 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "param", "", 72, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "performance", "", 73, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "post", "", 74, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "pre", "", 75, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "property", "", 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "protocol", "", 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
+  { "ref", "", 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "related", "", 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "relatedalso", "", 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "relates", "", 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "relatesalso", "", 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "remark", "", 83, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "remarks", "", 84, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "result", "", 85, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "return", "", 86, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "returns", "", 87, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "rtfonly", "endrtfonly", 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endrtfonly", "", 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "sa", "", 90, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "section", "", 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "security", "", 92, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "see", "", 93, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "seealso", "", 94, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "short", "", 95, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "since", "", 96, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "struct", "", 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
+  { "subpage", "", 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "subsection", "", 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "subsubsection", "", 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "superclass", "", 101, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+  { "template", "", 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "templatefield", "", 103, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "textblock", "/textblock", 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "/textblock", "", 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "throw", "", 106, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "throws", "", 107, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "todo", "", 108, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "tparam", "", 109, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "typedef", "", 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "union", "", 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 },
+  { "var", "", 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
+  { "verbatim", "endverbatim", 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endverbatim", "", 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+  { "version", "", 115, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "warning", "", 116, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { "weakgroup", "", 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
+  { "xmlonly", "endxmlonly", 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+  { "endxmlonly", "", 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
+};
+} // unnamed namespace
+
+const CommandInfo *CommandTraits::getBuiltinCommandInfo(
+                                         StringRef Name) {
+  switch (Name.size()) {
+  default: break;
+  case 1:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      return &Commands[0];	 // "a"
+    case 'b':	 // 1 string to match.
+      return &Commands[7];	 // "b"
+    case 'c':	 // 1 string to match.
+      return &Commands[10];	 // "c"
+    case 'e':	 // 1 string to match.
+      return &Commands[30];	 // "e"
+    case 'p':	 // 1 string to match.
+      return &Commands[69];	 // "p"
+    }
+    break;
+  case 2:	 // 9 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'e':	 // 1 string to match.
+      if (Name[1] != 'm')
+        break;
+      return &Commands[31];	 // "em"
+    case 'f':	 // 6 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case '$':	 // 1 string to match.
+        return &Commands[38];	 // "f$"
+      case '[':	 // 1 string to match.
+        return &Commands[36];	 // "f["
+      case ']':	 // 1 string to match.
+        return &Commands[37];	 // "f]"
+      case 'n':	 // 1 string to match.
+        return &Commands[39];	 // "fn"
+      case '{':	 // 1 string to match.
+        return &Commands[34];	 // "f{"
+      case '}':	 // 1 string to match.
+        return &Commands[35];	 // "f}"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return &Commands[54];	 // "li"
+    case 's':	 // 1 string to match.
+      if (Name[1] != 'a')
+        break;
+      return &Commands[90];	 // "sa"
+    }
+    break;
+  case 3:	 // 10 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rg", 2))
+        break;
+      return &Commands[3];	 // "arg"
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ug", 2))
+        break;
+      return &Commands[9];	 // "bug"
+    case 'd':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (Name[2] != 'f')
+          break;
+        return &Commands[22];	 // "def"
+      case 'o':	 // 1 string to match.
+        if (Name[2] != 't')
+          break;
+        return &Commands[28];	 // "dot"
+      }
+      break;
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "sc", 2))
+        break;
+      return &Commands[62];	 // "msc"
+    case 'p':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (Name[2] != 'r')
+          break;
+        return &Commands[70];	 // "par"
+      case 'r':	 // 1 string to match.
+        if (Name[2] != 'e')
+          break;
+        return &Commands[75];	 // "pre"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ef", 2))
+        break;
+      return &Commands[78];	 // "ref"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ee", 2))
+        break;
+      return &Commands[93];	 // "see"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ar", 2))
+        break;
+      return &Commands[112];	 // "var"
+    }
+    break;
+  case 4:	 // 8 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ode", 3))
+        break;
+      return &Commands[16];	 // "code"
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ate", 3))
+        break;
+      return &Commands[21];	 // "date"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "num", 3))
+        break;
+      return &Commands[32];	 // "enum"
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ink", 3))
+        break;
+      return &Commands[55];	 // "link"
+    case 'n':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "me", 2))
+          break;
+        return &Commands[64];	 // "name"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "te", 2))
+          break;
+        return &Commands[66];	 // "note"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ost", 3))
+        break;
+      return &Commands[74];	 // "post"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "odo", 3))
+        break;
+      return &Commands[108];	 // "todo"
+    }
+    break;
+  case 5:	 // 10 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '/':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "link", 4))
+        break;
+      return &Commands[56];	 // "/link"
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rief", 4))
+        break;
+      return &Commands[8];	 // "brief"
+    case 'c':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ass", 3))
+          break;
+        return &Commands[13];	 // "class"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nst", 3))
+          break;
+        return &Commands[18];	 // "const"
+      }
+      break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elps", 4))
+        break;
+      return &Commands[45];	 // "helps"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "aram", 4))
+        break;
+      return &Commands[72];	 // "param"
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ort", 3))
+          break;
+        return &Commands[95];	 // "short"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nce", 3))
+          break;
+        return &Commands[96];	 // "since"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hrow", 4))
+        break;
+      return &Commands[106];	 // "throw"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nion", 4))
+        break;
+      return &Commands[111];	 // "union"
+    }
+    break;
+  case 6:	 // 11 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uthor", 5))
+        break;
+      return &Commands[5];	 // "author"
+    case 'e':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "nd", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "ot", 2))
+          break;
+        return &Commands[29];	 // "enddot"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "sc", 2))
+          break;
+        return &Commands[63];	 // "endmsc"
+      }
+      break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elper", 5))
+        break;
+      return &Commands[43];	 // "helper"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ethod", 5))
+        break;
+      return &Commands[60];	 // "method"
+    case 'r':	 // 3 strings to match.
+      if (Name[1] != 'e')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ark", 3))
+          break;
+        return &Commands[83];	 // "remark"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ult", 3))
+          break;
+        return &Commands[85];	 // "result"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "urn", 3))
+          break;
+        return &Commands[86];	 // "return"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "truct", 5))
+        break;
+      return &Commands[97];	 // "struct"
+    case 't':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rows", 4))
+          break;
+        return &Commands[107];	 // "throws"
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "aram", 4))
+          break;
+        return &Commands[109];	 // "tparam"
+      }
+      break;
+    }
+    break;
+  case 7:	 // 18 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uthors", 6))
+        break;
+      return &Commands[6];	 // "authors"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "oclass", 6))
+        break;
+      return &Commands[15];	 // "coclass"
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "etails", 6))
+        break;
+      return &Commands[26];	 // "details"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ndcode", 6))
+        break;
+      return &Commands[17];	 // "endcode"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ngroup", 6))
+        break;
+      return &Commands[48];	 // "ingroup"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "anonly", 6))
+        break;
+      return &Commands[58];	 // "manonly"
+    case 'r':	 // 5 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 4 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(Name.data()+3, "ate", 3))
+            break;
+          switch (Name[6]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return &Commands[79];	 // "related"
+          case 's':	 // 1 string to match.
+            return &Commands[81];	 // "relates"
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "arks", 4))
+            break;
+          return &Commands[84];	 // "remarks"
+        case 't':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "urns", 4))
+            break;
+          return &Commands[87];	 // "returns"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "fonly", 5))
+          break;
+        return &Commands[88];	 // "rtfonly"
+      }
+      break;
+    case 's':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "tion", 4))
+            break;
+          return &Commands[91];	 // "section"
+        case 'e':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "also", 4))
+            break;
+          return &Commands[94];	 // "seealso"
+        }
+        break;
+      case 'u':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "bpage", 5))
+          break;
+        return &Commands[98];	 // "subpage"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ypedef", 6))
+        break;
+      return &Commands[110];	 // "typedef"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ersion", 6))
+        break;
+      return &Commands[115];	 // "version"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "arning", 6))
+        break;
+      return &Commands[116];	 // "warning"
+    case 'x':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "mlonly", 6))
+        break;
+      return &Commands[118];	 // "xmlonly"
+    }
+    break;
+  case 8:	 // 14 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bstract", 7))
+        break;
+      return &Commands[1];	 // "abstract"
+    case 'c':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "lback", 5))
+            break;
+          return &Commands[11];	 // "callback"
+        case 't':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "egory", 5))
+            break;
+          return &Commands[12];	 // "category"
+        }
+        break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nstant", 6))
+          break;
+        return &Commands[19];	 // "constant"
+      }
+      break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "efgroup", 7))
+        break;
+      return &Commands[23];	 // "defgroup"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "unction", 7))
+        break;
+      return &Commands[40];	 // "function"
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "tmlonly", 7))
+        break;
+      return &Commands[46];	 // "htmlonly"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ainpage", 7))
+        break;
+      return &Commands[57];	 // "mainpage"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "verload", 7))
+        break;
+      return &Commands[67];	 // "overload"
+    case 'p':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "ro", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "erty", 4))
+          break;
+        return &Commands[76];	 // "property"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "ocol", 4))
+          break;
+        return &Commands[77];	 // "protocol"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ecurity", 7))
+        break;
+      return &Commands[92];	 // "security"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "emplate", 7))
+        break;
+      return &Commands[102];	 // "template"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "erbatim", 7))
+        break;
+      return &Commands[113];	 // "verbatim"
+    }
+    break;
+  case 9:	 // 11 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ttention", 8))
+        break;
+      return &Commands[4];	 // "attention"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "opyright", 8))
+        break;
+      return &Commands[20];	 // "copyright"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "xception", 8))
+        break;
+      return &Commands[33];	 // "exception"
+    case 'i':	 // 2 strings to match.
+      if (Name[1] != 'n')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "erface", 6))
+          break;
+        return &Commands[50];	 // "interface"
+      case 'v':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ariant", 6))
+          break;
+        return &Commands[51];	 // "invariant"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "atexonly", 8))
+        break;
+      return &Commands[52];	 // "latexonly"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "amespace", 8))
+        break;
+      return &Commands[65];	 // "namespace"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "wnership", 8))
+        break;
+      return &Commands[68];	 // "ownership"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "aragraph", 8))
+        break;
+      return &Commands[71];	 // "paragraph"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "extblock", 8))
+        break;
+      return &Commands[104];	 // "textblock"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eakgroup", 8))
+        break;
+      return &Commands[117];	 // "weakgroup"
+    }
+    break;
+  case 10:	 // 11 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '/':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "textblock", 9))
+        break;
+      return &Commands[105];	 // "/textblock"
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ddtogroup", 9))
+        break;
+      return &Commands[2];	 // "addtogroup"
+    case 'd':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        if (Name[2] != 'p')
+          break;
+        switch (Name[3]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(Name.data()+4, "ndency", 6))
+            break;
+          return &Commands[24];	 // "dependency"
+        case 'r':	 // 1 string to match.
+          if (memcmp(Name.data()+4, "ecated", 6))
+            break;
+          return &Commands[25];	 // "deprecated"
+        }
+        break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "scussion", 8))
+          break;
+        return &Commands[27];	 // "discussion"
+      }
+      break;
+    case 'e':	 // 3 strings to match.
+      if (memcmp(Name.data()+1, "nd", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "anonly", 6))
+          break;
+        return &Commands[59];	 // "endmanonly"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "tfonly", 6))
+          break;
+        return &Commands[89];	 // "endrtfonly"
+      case 'x':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "mlonly", 6))
+          break;
+        return &Commands[119];	 // "endxmlonly"
+      }
+      break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eaderfile", 9))
+        break;
+      return &Commands[42];	 // "headerfile"
+    case 's':	 // 2 strings to match.
+      if (Name[1] != 'u')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "section", 7))
+          break;
+        return &Commands[99];	 // "subsection"
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "erclass", 7))
+          break;
+        return &Commands[101];	 // "superclass"
+      }
+      break;
+    }
+    break;
+  case 11:	 // 8 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lassdesign", 10))
+        break;
+      return &Commands[14];	 // "classdesign"
+    case 'e':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "nd", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "tmlonly", 7))
+          break;
+        return &Commands[47];	 // "endhtmlonly"
+      case 'v':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "erbatim", 7))
+          break;
+        return &Commands[114];	 // "endverbatim"
+      }
+      break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elperclass", 10))
+        break;
+      return &Commands[44];	 // "helperclass"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ethodgroup", 10))
+        break;
+      return &Commands[61];	 // "methodgroup"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "erformance", 10))
+        break;
+      return &Commands[73];	 // "performance"
+    case 'r':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "elate", 5))
+        break;
+      switch (Name[6]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "also", 4))
+          break;
+        return &Commands[80];	 // "relatedalso"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "also", 4))
+          break;
+        return &Commands[82];	 // "relatesalso"
+      }
+      break;
+    }
+    break;
+  case 12:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ndlatexonly", 11))
+        break;
+      return &Commands[53];	 // "endlatexonly"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nstancesize", 11))
+        break;
+      return &Commands[49];	 // "instancesize"
+    }
+    break;
+  case 13:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "unctiongroup", 12))
+        break;
+      return &Commands[41];	 // "functiongroup"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ubsubsection", 12))
+        break;
+      return &Commands[100];	 // "subsubsection"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "emplatefield", 12))
+        break;
+      return &Commands[103];	 // "templatefield"
+    }
+    break;
+  }
+  return NULL;
+}
+
diff --git a/include/clang/AST/CommentCommandList.inc b/include/clang/AST/CommentCommandList.inc
new file mode 100644
index 0000000..9b6cf4d
--- /dev/null
+++ b/include/clang/AST/CommentCommandList.inc
@@ -0,0 +1,131 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*A list of commands useable in documentation comments                        *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef COMMENT_COMMAND
+#  define COMMENT_COMMAND(NAME)
+#endif
+COMMENT_COMMAND(a)
+COMMENT_COMMAND(abstract)
+COMMENT_COMMAND(addtogroup)
+COMMENT_COMMAND(arg)
+COMMENT_COMMAND(attention)
+COMMENT_COMMAND(author)
+COMMENT_COMMAND(authors)
+COMMENT_COMMAND(b)
+COMMENT_COMMAND(brief)
+COMMENT_COMMAND(bug)
+COMMENT_COMMAND(c)
+COMMENT_COMMAND(callback)
+COMMENT_COMMAND(category)
+COMMENT_COMMAND(class)
+COMMENT_COMMAND(classdesign)
+COMMENT_COMMAND(coclass)
+COMMENT_COMMAND(code)
+COMMENT_COMMAND(endcode)
+COMMENT_COMMAND(const)
+COMMENT_COMMAND(constant)
+COMMENT_COMMAND(copyright)
+COMMENT_COMMAND(date)
+COMMENT_COMMAND(def)
+COMMENT_COMMAND(defgroup)
+COMMENT_COMMAND(dependency)
+COMMENT_COMMAND(deprecated)
+COMMENT_COMMAND(details)
+COMMENT_COMMAND(discussion)
+COMMENT_COMMAND(dot)
+COMMENT_COMMAND(enddot)
+COMMENT_COMMAND(e)
+COMMENT_COMMAND(em)
+COMMENT_COMMAND(enum)
+COMMENT_COMMAND(exception)
+COMMENT_COMMAND(flbrace)
+COMMENT_COMMAND(frbrace)
+COMMENT_COMMAND(flsquare)
+COMMENT_COMMAND(frsquare)
+COMMENT_COMMAND(fdollar)
+COMMENT_COMMAND(fn)
+COMMENT_COMMAND(function)
+COMMENT_COMMAND(functiongroup)
+COMMENT_COMMAND(headerfile)
+COMMENT_COMMAND(helper)
+COMMENT_COMMAND(helperclass)
+COMMENT_COMMAND(helps)
+COMMENT_COMMAND(htmlonly)
+COMMENT_COMMAND(endhtmlonly)
+COMMENT_COMMAND(ingroup)
+COMMENT_COMMAND(instancesize)
+COMMENT_COMMAND(interface)
+COMMENT_COMMAND(invariant)
+COMMENT_COMMAND(latexonly)
+COMMENT_COMMAND(endlatexonly)
+COMMENT_COMMAND(li)
+COMMENT_COMMAND(link)
+COMMENT_COMMAND(slashlink)
+COMMENT_COMMAND(mainpage)
+COMMENT_COMMAND(manonly)
+COMMENT_COMMAND(endmanonly)
+COMMENT_COMMAND(method)
+COMMENT_COMMAND(methodgroup)
+COMMENT_COMMAND(msc)
+COMMENT_COMMAND(endmsc)
+COMMENT_COMMAND(name)
+COMMENT_COMMAND(namespace)
+COMMENT_COMMAND(note)
+COMMENT_COMMAND(overload)
+COMMENT_COMMAND(ownership)
+COMMENT_COMMAND(p)
+COMMENT_COMMAND(par)
+COMMENT_COMMAND(paragraph)
+COMMENT_COMMAND(param)
+COMMENT_COMMAND(performance)
+COMMENT_COMMAND(post)
+COMMENT_COMMAND(pre)
+COMMENT_COMMAND(property)
+COMMENT_COMMAND(protocol)
+COMMENT_COMMAND(ref)
+COMMENT_COMMAND(related)
+COMMENT_COMMAND(relatedalso)
+COMMENT_COMMAND(relates)
+COMMENT_COMMAND(relatesalso)
+COMMENT_COMMAND(remark)
+COMMENT_COMMAND(remarks)
+COMMENT_COMMAND(result)
+COMMENT_COMMAND(return)
+COMMENT_COMMAND(returns)
+COMMENT_COMMAND(rtfonly)
+COMMENT_COMMAND(endrtfonly)
+COMMENT_COMMAND(sa)
+COMMENT_COMMAND(section)
+COMMENT_COMMAND(security)
+COMMENT_COMMAND(see)
+COMMENT_COMMAND(seealso)
+COMMENT_COMMAND(short)
+COMMENT_COMMAND(since)
+COMMENT_COMMAND(struct)
+COMMENT_COMMAND(subpage)
+COMMENT_COMMAND(subsection)
+COMMENT_COMMAND(subsubsection)
+COMMENT_COMMAND(superclass)
+COMMENT_COMMAND(template)
+COMMENT_COMMAND(templatefield)
+COMMENT_COMMAND(textblock)
+COMMENT_COMMAND(slashtextblock)
+COMMENT_COMMAND(throw)
+COMMENT_COMMAND(throws)
+COMMENT_COMMAND(todo)
+COMMENT_COMMAND(tparam)
+COMMENT_COMMAND(typedef)
+COMMENT_COMMAND(union)
+COMMENT_COMMAND(var)
+COMMENT_COMMAND(verbatim)
+COMMENT_COMMAND(endverbatim)
+COMMENT_COMMAND(version)
+COMMENT_COMMAND(warning)
+COMMENT_COMMAND(weakgroup)
+COMMENT_COMMAND(xmlonly)
+COMMENT_COMMAND(endxmlonly)
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
new file mode 100644
index 0000000..dde7a14
--- /dev/null
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -0,0 +1,185 @@
+//===--- CommentCommandTraits.h - Comment command properties ----*- 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 class that provides information about comment
+//  commands.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+
+#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+namespace comments {
+
+/// \brief Information about a single command.
+///
+/// When reordering, adding or removing members please update the corresponding
+/// TableGen backend.
+struct CommandInfo {
+  unsigned getID() const {
+    return ID;
+  }
+
+  const char *Name;
+
+  /// Name of the command that ends the verbatim block.
+  const char *EndCommandName;
+
+  unsigned ID : 8;
+
+  /// Number of word-like arguments for a given block command, except for
+  /// \\param and \\tparam commands -- these have special argument parsers.
+  unsigned NumArgs : 4;
+
+  /// True if this command is a inline command (of any kind).
+  unsigned IsInlineCommand : 1;
+
+  /// True if this command is a block command (of any kind).
+  unsigned IsBlockCommand : 1;
+
+  /// True if this command is introducing a brief documentation
+  /// paragraph (\\brief or an alias).
+  unsigned IsBriefCommand : 1;
+
+  /// True if this command is \\returns or an alias.
+  unsigned IsReturnsCommand : 1;
+
+  /// True if this command is introducing documentation for a function
+  /// parameter (\\param or an alias).
+  unsigned IsParamCommand : 1;
+
+  /// True if this command is introducing documentation for
+  /// a template parameter (\\tparam or an alias).
+  unsigned IsTParamCommand : 1;
+
+  /// True if this command is \\throws or an alias.
+  unsigned IsThrowsCommand : 1;
+
+  /// True if this command is \\deprecated or an alias.
+  unsigned IsDeprecatedCommand : 1;
+
+  /// \brief True if this is a \\headerfile-like command.
+  unsigned IsHeaderfileCommand : 1;
+
+  /// True if we don't want to warn about this command being passed an empty
+  /// paragraph.  Meaningful only for block commands.
+  unsigned IsEmptyParagraphAllowed : 1;
+
+  /// \brief True if this command is a verbatim-like block command.
+  ///
+  /// A verbatim-like block command eats every character (except line starting
+  /// decorations) until matching end command is seen or comment end is hit.
+  unsigned IsVerbatimBlockCommand : 1;
+
+  /// \brief True if this command is an end command for a verbatim-like block.
+  unsigned IsVerbatimBlockEndCommand : 1;
+
+  /// \brief True if this command is a verbatim line command.
+  ///
+  /// A verbatim-like line command eats everything until a newline is seen or
+  /// comment end is hit.
+  unsigned IsVerbatimLineCommand : 1;
+
+  /// \brief True if this command contains a declaration for the entity being
+  /// documented.
+  ///
+  /// For example:
+  /// \code
+  ///   \fn void f(int a);
+  /// \endcode
+  unsigned IsDeclarationCommand : 1;
+  
+  /// \brief True if verbatim-like line command is a function declaration.
+  unsigned IsFunctionDeclarationCommand : 1;
+
+  /// \brief True if block command is further describing a container API; such
+  /// as \@coclass, \@classdesign, etc.
+  unsigned IsRecordLikeDetailCommand : 1;
+  
+  /// \brief True if block command is a container API; such as \@interface.
+  unsigned IsRecordLikeDeclarationCommand : 1;
+  
+  /// \brief True if this command is unknown.  This \c CommandInfo object was
+  /// created during parsing.
+  unsigned IsUnknownCommand : 1;
+};
+
+/// This class provides information about commands that can be used
+/// in comments.
+class CommandTraits {
+public:
+  enum KnownCommandIDs {
+#define COMMENT_COMMAND(NAME) KCI_##NAME,
+#include "clang/AST/CommentCommandList.inc"
+#undef COMMENT_COMMAND
+    KCI_Last
+  };
+
+  CommandTraits(llvm::BumpPtrAllocator &Allocator,
+                const CommentOptions &CommentOptions);
+
+  void registerCommentOptions(const CommentOptions &CommentOptions);
+
+  /// \returns a CommandInfo object for a given command name or
+  /// NULL if no CommandInfo object exists for this command.
+  const CommandInfo *getCommandInfoOrNULL(StringRef Name) const;
+
+  const CommandInfo *getCommandInfo(StringRef Name) const {
+    if (const CommandInfo *Info = getCommandInfoOrNULL(Name))
+      return Info;
+    llvm_unreachable("the command should be known");
+  }
+
+  const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const;
+  
+  const CommandInfo *getCommandInfo(unsigned CommandID) const;
+
+  const CommandInfo *registerUnknownCommand(StringRef CommandName);
+
+  const CommandInfo *registerBlockCommand(StringRef CommandName);
+
+  /// \returns a CommandInfo object for a given command name or
+  /// NULL if \c Name is not a builtin command.
+  static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
+
+  /// \returns a CommandInfo object for a given command ID or
+  /// NULL if \c CommandID is not a builtin command.
+  static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID);
+
+private:
+  CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION;
+  void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION;
+
+  const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
+  const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
+
+  CommandInfo *createCommandInfoWithName(StringRef CommandName);
+
+  unsigned NextID;
+
+  /// Allocator for CommandInfo objects.
+  llvm::BumpPtrAllocator &Allocator;
+
+  SmallVector<CommandInfo *, 4> RegisteredCommands;
+};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
new file mode 100644
index 0000000..312da06
--- /dev/null
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -0,0 +1,29 @@
+//===--- CommentDiagnostic.h - Diagnostics for the AST library --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_COMMENTDIAGNOSTIC_H
+#define LLVM_CLANG_COMMENTDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define COMMENTSTART
+#include "clang/Basic/DiagnosticCommentKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_COMMENT_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentHTMLNamedCharacterReferences.inc b/include/clang/AST/CommentHTMLNamedCharacterReferences.inc
new file mode 100644
index 0000000..6b2075b
--- /dev/null
+++ b/include/clang/AST/CommentHTMLNamedCharacterReferences.inc
@@ -0,0 +1,815 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*HTML named character reference to UTF-8 translation                         *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+StringRef translateHTMLNamedCharacterReferenceToUTF8(
+                                             StringRef Name) {
+  switch (Name.size()) {
+  default: break;
+  case 2:	 // 15 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'G':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'T':	 // 1 string to match.
+        return "\x3e";	 // "GT"
+      case 't':	 // 1 string to match.
+        return "\x3e";	 // "Gt"
+      }
+      break;
+    case 'L':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'T':	 // 1 string to match.
+        return "\x3c";	 // "LT"
+      case 't':	 // 1 string to match.
+        return "\x3c";	 // "Lt"
+      }
+      break;
+    case 'P':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return "\xce\xa0";	 // "Pi"
+    case 'X':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return "\xce\x9e";	 // "Xi"
+    case 'g':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        return "\xe2\x89\xa5";	 // "ge"
+      case 't':	 // 1 string to match.
+        return "\x3e";	 // "gt"
+      }
+      break;
+    case 'l':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        return "\xe2\x89\xa4";	 // "le"
+      case 't':	 // 1 string to match.
+        return "\x3c";	 // "lt"
+      }
+      break;
+    case 'm':	 // 1 string to match.
+      if (Name[1] != 'u')
+        break;
+      return "\xce\xbc";	 // "mu"
+    case 'n':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        return "\xe2\x89\xa0";	 // "ne"
+      case 'u':	 // 1 string to match.
+        return "\xce\xbd";	 // "nu"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return "\xcf\x80";	 // "pi"
+    case 'x':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return "\xce\xbe";	 // "xi"
+    }
+    break;
+  case 3:	 // 16 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'A':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "MP", 2))
+        break;
+      return "\x26";	 // "AMP"
+    case 'P':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (Name[2] != 'i')
+          break;
+        return "\xce\xa6";	 // "Phi"
+      case 's':	 // 1 string to match.
+        if (Name[2] != 'i')
+          break;
+        return "\xce\xa8";	 // "Psi"
+      }
+      break;
+    case 'R':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "EG", 2))
+        break;
+      return "\xc2\xae";	 // "REG"
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "mp", 2))
+        break;
+      return "\x26";	 // "amp"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hi", 2))
+        break;
+      return "\xcf\x87";	 // "chi"
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eg", 2))
+        break;
+      return "\xc2\xb0";	 // "deg"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ta", 2))
+        break;
+      return "\xce\xb7";	 // "eta"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nt", 2))
+        break;
+      return "\xe2\x88\xab";	 // "int"
+    case 'p':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (Name[2] != 'i')
+          break;
+        return "\xcf\x86";	 // "phi"
+      case 's':	 // 1 string to match.
+        if (Name[2] != 'i')
+          break;
+        return "\xcf\x88";	 // "psi"
+      }
+      break;
+    case 'r':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (Name[2] != 'g')
+          break;
+        return "\xc2\xae";	 // "reg"
+      case 'h':	 // 1 string to match.
+        if (Name[2] != 'o')
+          break;
+        return "\xcf\x81";	 // "rho"
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (Name[2] != 'm')
+          break;
+        return "\xe2\x88\xbc";	 // "sim"
+      case 'u':	 // 1 string to match.
+        if (Name[2] != 'm')
+          break;
+        return "\xe2\x88\x91";	 // "sum"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "au", 2))
+        break;
+      return "\xcf\x84";	 // "tau"
+    }
+    break;
+  case 4:	 // 30 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'A':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\x84";	 // "Auml"
+    case 'C':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "OPY", 3))
+        break;
+      return "\xc2\xa9";	 // "COPY"
+    case 'E':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\x8b";	 // "Euml"
+    case 'I':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\x8f";	 // "Iuml"
+    case 'O':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\x96";	 // "Ouml"
+    case 'Q':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "UOT", 3))
+        break;
+      return "\x22";	 // "QUOT"
+    case 'U':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\x9c";	 // "Uuml"
+    case 'Y':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc5\xb8";	 // "Yuml"
+    case 'a':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "os", 2))
+          break;
+        return "\x27";	 // "apos"
+      case 'u':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ml", 2))
+          break;
+        return "\xc3\xa4";	 // "auml"
+      }
+      break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eta", 3))
+        break;
+      return "\xce\xb2";	 // "beta"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "opy", 3))
+        break;
+      return "\xc2\xa9";	 // "copy"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\xab";	 // "euml"
+    case 'i':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ta", 2))
+          break;
+        return "\xce\xb9";	 // "iota"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "in", 2))
+          break;
+        return "\xe2\x88\x88";	 // "isin"
+      case 'u':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ml", 2))
+          break;
+        return "\xc3\xaf";	 // "iuml"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "arr", 3))
+        break;
+      return "\xe2\x86\x90";	 // "larr"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bsp", 3))
+        break;
+      return "\xc2\xa0";	 // "nbsp"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\xb6";	 // "ouml"
+    case 'p':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rt", 2))
+          break;
+        return "\xe2\x88\x82";	 // "part"
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rp", 2))
+          break;
+        return "\xe2\x8a\xa5";	 // "perp"
+      case 'r':	 // 2 strings to match.
+        if (Name[2] != 'o')
+          break;
+        switch (Name[3]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return "\xe2\x88\x8f";	 // "prod"
+        case 'p':	 // 1 string to match.
+          return "\xe2\x88\x9d";	 // "prop"
+        }
+        break;
+      }
+      break;
+    case 'q':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uot", 3))
+        break;
+      return "\x22";	 // "quot"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "arr", 3))
+        break;
+      return "\xe2\x86\x92";	 // "rarr"
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ot", 2))
+          break;
+        return "\xe2\x8b\x85";	 // "sdot"
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ct", 2))
+          break;
+        return "\xc2\xa7";	 // "sect"
+      }
+      break;
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\xbc";	 // "uuml"
+    case 'y':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uml", 3))
+        break;
+      return "\xc3\xbf";	 // "yuml"
+    case 'z':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eta", 3))
+        break;
+      return "\xce\xb6";	 // "zeta"
+    }
+    break;
+  case 5:	 // 48 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'A':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\x82";	 // "Acirc"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ing", 3))
+          break;
+        return "\xc3\x85";	 // "Aring"
+      }
+      break;
+    case 'D':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elta", 4))
+        break;
+      return "\xce\x94";	 // "Delta"
+    case 'E':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc3\x8a";	 // "Ecirc"
+    case 'G':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "amma", 4))
+        break;
+      return "\xce\x93";	 // "Gamma"
+    case 'I':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc3\x8e";	 // "Icirc"
+    case 'O':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\x94";	 // "Ocirc"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ega", 3))
+          break;
+        return "\xce\xa9";	 // "Omega"
+      }
+      break;
+    case 'P':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rime", 4))
+        break;
+      return "\xe2\x80\xb3";	 // "Prime"
+    case 'S':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "igma", 4))
+        break;
+      return "\xce\xa3";	 // "Sigma"
+    case 'T':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'R':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ADE", 3))
+          break;
+        return "\xe2\x84\xa2";	 // "TRADE"
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "eta", 3))
+          break;
+        return "\xce\x98";	 // "Theta"
+      }
+      break;
+    case 'U':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc3\x9b";	 // "Ucirc"
+    case 'Y':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc5\xb6";	 // "Ycirc"
+    case 'a':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\xa2";	 // "acirc"
+      case 'l':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "pha", 3))
+          break;
+        return "\xce\xb1";	 // "alpha"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ing", 3))
+          break;
+        return "\xc3\xa5";	 // "aring"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ymp", 3))
+          break;
+        return "\xe2\x89\x88";	 // "asymp"
+      }
+      break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elta", 4))
+        break;
+      return "\xce\xb4";	 // "delta"
+    case 'e':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\xaa";	 // "ecirc"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "pty", 3))
+          break;
+        return "\xe2\x88\x85";	 // "empty"
+      case 'q':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "uiv", 3))
+          break;
+        return "\xe2\x89\xa1";	 // "equiv"
+      }
+      break;
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "amma", 4))
+        break;
+      return "\xce\xb3";	 // "gamma"
+    case 'i':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\xae";	 // "icirc"
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "fin", 3))
+          break;
+        return "\xe2\x88\x9e";	 // "infin"
+      }
+      break;
+    case 'k':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "appa", 4))
+        break;
+      return "\xce\xba";	 // "kappa"
+    case 'l':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "eil", 3))
+          break;
+        return "\xe2\x8c\x88";	 // "lceil"
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "quo", 3))
+          break;
+        return "\xe2\x80\x9c";	 // "ldquo"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "quo", 3))
+          break;
+        return "\xe2\x80\x98";	 // "lsquo"
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ash", 3))
+          break;
+        return "\xe2\x80\x94";	 // "mdash"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nus", 3))
+          break;
+        return "\xe2\x88\x92";	 // "minus"
+      }
+      break;
+    case 'n':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "bla", 3))
+          break;
+        return "\xe2\x88\x87";	 // "nabla"
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ash", 3))
+          break;
+        return "\xe2\x80\x93";	 // "ndash"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "tin", 3))
+          break;
+        return "\xe2\x88\x89";	 // "notin"
+      }
+      break;
+    case 'o':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "irc", 3))
+          break;
+        return "\xc3\xb4";	 // "ocirc"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ega", 3))
+          break;
+        return "\xcf\x89";	 // "omega"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rime", 4))
+        break;
+      return "\xe2\x80\xb2";	 // "prime"
+    case 'r':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "dic", 3))
+          break;
+        return "\xe2\x88\x9a";	 // "radic"
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "eil", 3))
+          break;
+        return "\xe2\x8c\x89";	 // "rceil"
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "quo", 3))
+          break;
+        return "\xe2\x80\x9d";	 // "rdquo"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "quo", 3))
+          break;
+        return "\xe2\x80\x99";	 // "rsquo"
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "gma", 3))
+          break;
+        return "\xcf\x83";	 // "sigma"
+      case 'z':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "lig", 3))
+          break;
+        return "\xc3\x9f";	 // "szlig"
+      }
+      break;
+    case 't':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "eta", 3))
+          break;
+        return "\xce\xb8";	 // "theta"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "mes", 3))
+          break;
+        return "\xc3\x97";	 // "times"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ade", 3))
+          break;
+        return "\xe2\x84\xa2";	 // "trade"
+      }
+      break;
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc3\xbb";	 // "ucirc"
+    case 'y':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "circ", 4))
+        break;
+      return "\xc5\xb7";	 // "ycirc"
+    }
+    break;
+  case 6:	 // 37 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'A':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\x81";	 // "Aacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\x80";	 // "Agrave"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ilde", 4))
+          break;
+        return "\xc3\x83";	 // "Atilde"
+      }
+      break;
+    case 'C':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cedil", 5))
+        break;
+      return "\xc3\x87";	 // "Ccedil"
+    case 'E':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\x89";	 // "Eacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\x88";	 // "Egrave"
+      }
+      break;
+    case 'I':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\x8d";	 // "Iacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\x8c";	 // "Igrave"
+      }
+      break;
+    case 'L':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ambda", 5))
+        break;
+      return "\xce\x9b";	 // "Lambda"
+    case 'N':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "tilde", 5))
+        break;
+      return "\xc3\x91";	 // "Ntilde"
+    case 'O':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\x93";	 // "Oacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\x92";	 // "Ograve"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ilde", 4))
+          break;
+        return "\xc3\x95";	 // "Otilde"
+      }
+      break;
+    case 'U':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\x9a";	 // "Uacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\x99";	 // "Ugrave"
+      }
+      break;
+    case 'Y':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "acute", 5))
+        break;
+      return "\xc3\x9d";	 // "Yacute"
+    case 'a':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xa1";	 // "aacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\xa0";	 // "agrave"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ilde", 4))
+          break;
+        return "\xc3\xa3";	 // "atilde"
+      }
+      break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cedil", 5))
+        break;
+      return "\xc3\xa7";	 // "ccedil"
+    case 'e':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xa9";	 // "eacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\xa8";	 // "egrave"
+      }
+      break;
+    case 'i':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xad";	 // "iacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\xac";	 // "igrave"
+      }
+      break;
+    case 'l':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "mbda", 4))
+          break;
+        return "\xce\xbb";	 // "lambda"
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "loor", 4))
+          break;
+        return "\xe2\x8c\x8a";	 // "lfloor"
+      }
+      break;
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "tilde", 5))
+        break;
+      return "\xc3\xb1";	 // "ntilde"
+    case 'o':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xb3";	 // "oacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\xb2";	 // "ograve"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ilde", 4))
+          break;
+        return "\xc3\xb5";	 // "otilde"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lusmn", 5))
+        break;
+      return "\xc2\xb1";	 // "plusmn"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "floor", 5))
+        break;
+      return "\xe2\x8c\x8b";	 // "rfloor"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "igmaf", 5))
+        break;
+      return "\xcf\x82";	 // "sigmaf"
+    case 'u':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xba";	 // "uacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xc3\xb9";	 // "ugrave"
+      }
+      break;
+    case 'y':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "cute", 4))
+          break;
+        return "\xc3\xbd";	 // "yacute"
+      case 'g':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rave", 4))
+          break;
+        return "\xe1\xbb\xb3";	 // "ygrave"
+      }
+      break;
+    }
+    break;
+  case 7:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'U':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "psilon", 6))
+        break;
+      return "\xce\xa5";	 // "Upsilon"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "psilon", 6))
+        break;
+      return "\xce\xb5";	 // "epsilon"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "psilon", 6))
+        break;
+      return "\xcf\x85";	 // "upsilon"
+    }
+    break;
+  }
+  return StringRef();
+}
+
diff --git a/include/clang/AST/CommentHTMLTags.inc b/include/clang/AST/CommentHTMLTags.inc
new file mode 100644
index 0000000..7d9d012
--- /dev/null
+++ b/include/clang/AST/CommentHTMLTags.inc
@@ -0,0 +1,228 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*HTML tag name matcher                                                       *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+bool isHTMLTagName(StringRef Name) {
+  switch (Name.size()) {
+  default: break;
+  case 1:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      return true;	 // "a"
+    case 'b':	 // 1 string to match.
+      return true;	 // "b"
+    case 'i':	 // 1 string to match.
+      return true;	 // "i"
+    case 'p':	 // 1 string to match.
+      return true;	 // "p"
+    case 's':	 // 1 string to match.
+      return true;	 // "s"
+    case 'u':	 // 1 string to match.
+      return true;	 // "u"
+    }
+    break;
+  case 2:	 // 19 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (Name[1] != 'r')
+        break;
+      return true;	 // "br"
+    case 'd':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return true;	 // "dd"
+      case 'l':	 // 1 string to match.
+        return true;	 // "dl"
+      case 't':	 // 1 string to match.
+        return true;	 // "dt"
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (Name[1] != 'm')
+        break;
+      return true;	 // "em"
+    case 'h':	 // 7 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case '1':	 // 1 string to match.
+        return true;	 // "h1"
+      case '2':	 // 1 string to match.
+        return true;	 // "h2"
+      case '3':	 // 1 string to match.
+        return true;	 // "h3"
+      case '4':	 // 1 string to match.
+        return true;	 // "h4"
+      case '5':	 // 1 string to match.
+        return true;	 // "h5"
+      case '6':	 // 1 string to match.
+        return true;	 // "h6"
+      case 'r':	 // 1 string to match.
+        return true;	 // "hr"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return true;	 // "li"
+    case 'o':	 // 1 string to match.
+      if (Name[1] != 'l')
+        break;
+      return true;	 // "ol"
+    case 't':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return true;	 // "td"
+      case 'h':	 // 1 string to match.
+        return true;	 // "th"
+      case 'r':	 // 1 string to match.
+        return true;	 // "tr"
+      case 't':	 // 1 string to match.
+        return true;	 // "tt"
+      }
+      break;
+    case 'u':	 // 1 string to match.
+      if (Name[1] != 'l')
+        break;
+      return true;	 // "ul"
+    }
+    break;
+  case 3:	 // 9 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ig", 2))
+        break;
+      return true;	 // "big"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ol", 2))
+        break;
+      return true;	 // "col"
+    case 'd':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (Name[2] != 'l')
+          break;
+        return true;	 // "del"
+      case 'i':	 // 1 string to match.
+        if (Name[2] != 'v')
+          break;
+        return true;	 // "div"
+      }
+      break;
+    case 'i':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (Name[2] != 'g')
+          break;
+        return true;	 // "img"
+      case 'n':	 // 1 string to match.
+        if (Name[2] != 's')
+          break;
+        return true;	 // "ins"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "re", 2))
+        break;
+      return true;	 // "pre"
+    case 's':	 // 2 strings to match.
+      if (Name[1] != 'u')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        return true;	 // "sub"
+      case 'p':	 // 1 string to match.
+        return true;	 // "sup"
+      }
+      break;
+    }
+    break;
+  case 4:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ode", 3))
+        break;
+      return true;	 // "code"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ont", 3))
+        break;
+      return true;	 // "font"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "pan", 3))
+        break;
+      return true;	 // "span"
+    }
+    break;
+  case 5:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "mall", 4))
+        break;
+      return true;	 // "small"
+    case 't':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ble", 3))
+          break;
+        return true;	 // "table"
+      case 'b':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ody", 3))
+          break;
+        return true;	 // "tbody"
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "oot", 3))
+          break;
+        return true;	 // "tfoot"
+      case 'h':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ead", 3))
+          break;
+        return true;	 // "thead"
+      }
+      break;
+    }
+    break;
+  case 6:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "str", 3))
+      break;
+    switch (Name[3]) {
+    default: break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+4, "ke", 2))
+        break;
+      return true;	 // "strike"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+4, "ng", 2))
+        break;
+      return true;	 // "strong"
+    }
+    break;
+  case 7:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "caption", 7))
+      break;
+    return true;	 // "caption"
+  case 8:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "colgroup", 8))
+      break;
+    return true;	 // "colgroup"
+  case 10:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "blockquote", 10))
+      break;
+    return true;	 // "blockquote"
+  }
+  return false;
+}
+
diff --git a/include/clang/AST/CommentHTMLTagsProperties.inc b/include/clang/AST/CommentHTMLTagsProperties.inc
new file mode 100644
index 0000000..554cf83
--- /dev/null
+++ b/include/clang/AST/CommentHTMLTagsProperties.inc
@@ -0,0 +1,104 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*HTML tag properties                                                         *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+bool isHTMLEndTagOptional(StringRef Name) {
+  switch (Name.size()) {
+  default: break;
+  case 1:	 // 1 string to match.
+    if (Name[0] != 'p')
+      break;
+    return true;	 // "p"
+  case 2:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return true;	 // "dd"
+      case 't':	 // 1 string to match.
+        return true;	 // "dt"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (Name[1] != 'i')
+        break;
+      return true;	 // "li"
+    case 't':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return true;	 // "td"
+      case 'h':	 // 1 string to match.
+        return true;	 // "th"
+      case 'r':	 // 1 string to match.
+        return true;	 // "tr"
+      }
+      break;
+    }
+    break;
+  case 5:	 // 3 strings to match.
+    if (Name[0] != 't')
+      break;
+    switch (Name[1]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+2, "ody", 3))
+        break;
+      return true;	 // "tbody"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+2, "oot", 3))
+        break;
+      return true;	 // "tfoot"
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+2, "ead", 3))
+        break;
+      return true;	 // "thead"
+    }
+    break;
+  case 8:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "colgroup", 8))
+      break;
+    return true;	 // "colgroup"
+  }
+  return false;
+}
+
+bool isHTMLEndTagForbidden(StringRef Name) {
+  switch (Name.size()) {
+  default: break;
+  case 2:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (Name[1] != 'r')
+        break;
+      return true;	 // "br"
+    case 'h':	 // 1 string to match.
+      if (Name[1] != 'r')
+        break;
+      return true;	 // "hr"
+    }
+    break;
+  case 3:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ol", 2))
+        break;
+      return true;	 // "col"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "mg", 2))
+        break;
+      return true;	 // "img"
+    }
+    break;
+  }
+  return false;
+}
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
new file mode 100644
index 0000000..a6e3ed8
--- /dev/null
+++ b/include/clang/AST/CommentLexer.h
@@ -0,0 +1,362 @@
+//===--- CommentLexer.h - Lexer for structured comments ---------*- 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 lexer for structured comments and supporting token class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
+#define LLVM_CLANG_AST_COMMENT_LEXER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace comments {
+
+class Lexer;
+class TextTokenRetokenizer;
+struct CommandInfo;
+class CommandTraits;
+
+namespace tok {
+enum TokenKind {
+  eof,
+  newline,
+  text,
+  unknown_command,   // Command that does not have an ID.
+  backslash_command, // Command with an ID, that used backslash marker.
+  at_command,        // Command with an ID, that used 'at' marker.
+  verbatim_block_begin,
+  verbatim_block_line,
+  verbatim_block_end,
+  verbatim_line_name,
+  verbatim_line_text,
+  html_start_tag,     // <tag
+  html_ident,         // attr
+  html_equals,        // =
+  html_quoted_string, // "blah\"blah" or 'blah\'blah'
+  html_greater,       // >
+  html_slash_greater, // />
+  html_end_tag        // </tag
+};
+} // end namespace tok
+
+/// \brief Comment token.
+class Token {
+  friend class Lexer;
+  friend class TextTokenRetokenizer;
+
+  /// The location of the token.
+  SourceLocation Loc;
+
+  /// The actual kind of the token.
+  tok::TokenKind Kind;
+
+  /// Length of the token spelling in comment.  Can be 0 for synthenized
+  /// tokens.
+  unsigned Length;
+
+  /// Contains text value associated with a token.
+  const char *TextPtr;
+
+  /// Integer value associated with a token.
+  ///
+  /// If the token is a konwn command, contains command ID and TextPtr is
+  /// unused (command spelling can be found with CommandTraits).  Otherwise,
+  /// contains the length of the string that starts at TextPtr.
+  unsigned IntVal;
+  
+public:
+  SourceLocation getLocation() const LLVM_READONLY { return Loc; }
+  void setLocation(SourceLocation SL) { Loc = SL; }
+
+  SourceLocation getEndLocation() const LLVM_READONLY {
+    if (Length == 0 || Length == 1)
+      return Loc;
+    return Loc.getLocWithOffset(Length - 1);
+  }
+
+  tok::TokenKind getKind() const LLVM_READONLY { return Kind; }
+  void setKind(tok::TokenKind K) { Kind = K; }
+
+  bool is(tok::TokenKind K) const LLVM_READONLY { return Kind == K; }
+  bool isNot(tok::TokenKind K) const LLVM_READONLY { return Kind != K; }
+
+  unsigned getLength() const LLVM_READONLY { return Length; }
+  void setLength(unsigned L) { Length = L; }
+
+  StringRef getText() const LLVM_READONLY {
+    assert(is(tok::text));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setText(StringRef Text) {
+    assert(is(tok::text));
+    TextPtr = Text.data();
+    IntVal = Text.size();
+  }
+
+  StringRef getUnknownCommandName() const LLVM_READONLY {
+    assert(is(tok::unknown_command));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setUnknownCommandName(StringRef Name) {
+    assert(is(tok::unknown_command));
+    TextPtr = Name.data();
+    IntVal = Name.size();
+  }
+
+  unsigned getCommandID() const LLVM_READONLY {
+    assert(is(tok::backslash_command) || is(tok::at_command));
+    return IntVal;
+  }
+
+  void setCommandID(unsigned ID) {
+    assert(is(tok::backslash_command) || is(tok::at_command));
+    IntVal = ID;
+  }
+
+  unsigned getVerbatimBlockID() const LLVM_READONLY {
+    assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
+    return IntVal;
+  }
+
+  void setVerbatimBlockID(unsigned ID) {
+    assert(is(tok::verbatim_block_begin) || is(tok::verbatim_block_end));
+    IntVal = ID;
+  }
+
+  StringRef getVerbatimBlockText() const LLVM_READONLY {
+    assert(is(tok::verbatim_block_line));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setVerbatimBlockText(StringRef Text) {
+    assert(is(tok::verbatim_block_line));
+    TextPtr = Text.data();
+    IntVal = Text.size();
+  }
+
+  unsigned getVerbatimLineID() const LLVM_READONLY {
+    assert(is(tok::verbatim_line_name));
+    return IntVal;
+  }
+
+  void setVerbatimLineID(unsigned ID) {
+    assert(is(tok::verbatim_line_name));
+    IntVal = ID;
+  }
+
+  StringRef getVerbatimLineText() const LLVM_READONLY {
+    assert(is(tok::verbatim_line_text));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setVerbatimLineText(StringRef Text) {
+    assert(is(tok::verbatim_line_text));
+    TextPtr = Text.data();
+    IntVal = Text.size();
+  }
+
+  StringRef getHTMLTagStartName() const LLVM_READONLY {
+    assert(is(tok::html_start_tag));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setHTMLTagStartName(StringRef Name) {
+    assert(is(tok::html_start_tag));
+    TextPtr = Name.data();
+    IntVal = Name.size();
+  }
+
+  StringRef getHTMLIdent() const LLVM_READONLY {
+    assert(is(tok::html_ident));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setHTMLIdent(StringRef Name) {
+    assert(is(tok::html_ident));
+    TextPtr = Name.data();
+    IntVal = Name.size();
+  }
+
+  StringRef getHTMLQuotedString() const LLVM_READONLY {
+    assert(is(tok::html_quoted_string));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setHTMLQuotedString(StringRef Str) {
+    assert(is(tok::html_quoted_string));
+    TextPtr = Str.data();
+    IntVal = Str.size();
+  }
+
+  StringRef getHTMLTagEndName() const LLVM_READONLY {
+    assert(is(tok::html_end_tag));
+    return StringRef(TextPtr, IntVal);
+  }
+
+  void setHTMLTagEndName(StringRef Name) {
+    assert(is(tok::html_end_tag));
+    TextPtr = Name.data();
+    IntVal = Name.size();
+  }
+
+  void dump(const Lexer &L, const SourceManager &SM) const;
+};
+
+/// \brief Comment lexer.
+class Lexer {
+private:
+  Lexer(const Lexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const Lexer &) LLVM_DELETED_FUNCTION;
+
+  /// Allocator for strings that are semantic values of tokens and have to be
+  /// computed (for example, resolved decimal character references).
+  llvm::BumpPtrAllocator &Allocator;
+
+  DiagnosticsEngine &Diags;
+  
+  const CommandTraits &Traits;
+
+  const char *const BufferStart;
+  const char *const BufferEnd;
+  SourceLocation FileLoc;
+
+  const char *BufferPtr;
+
+  /// One past end pointer for the current comment.  For BCPL comments points
+  /// to newline or BufferEnd, for C comments points to star in '*/'.
+  const char *CommentEnd;
+
+  enum LexerCommentState {
+    LCS_BeforeComment,
+    LCS_InsideBCPLComment,
+    LCS_InsideCComment,
+    LCS_BetweenComments
+  };
+
+  /// Low-level lexer state, track if we are inside or outside of comment.
+  LexerCommentState CommentState;
+
+  enum LexerState {
+    /// Lexing normal comment text
+    LS_Normal,
+
+    /// Finished lexing verbatim block beginning command, will lex first body
+    /// line.
+    LS_VerbatimBlockFirstLine,
+
+    /// Lexing verbatim block body line-by-line, skipping line-starting
+    /// decorations.
+    LS_VerbatimBlockBody,
+
+    /// Finished lexing verbatim line beginning command, will lex text (one
+    /// line).
+    LS_VerbatimLineText,
+
+    /// Finished lexing \verbatim <TAG \endverbatim part, lexing tag attributes.
+    LS_HTMLStartTag,
+
+    /// Finished lexing \verbatim </TAG \endverbatim part, lexing '>'.
+    LS_HTMLEndTag
+  };
+
+  /// Current lexing mode.
+  LexerState State;
+
+  /// If State is LS_VerbatimBlock, contains the name of verbatim end
+  /// command, including command marker.
+  SmallString<16> VerbatimBlockEndCommandName;
+
+  /// Given a character reference name (e.g., "lt"), return the character that
+  /// it stands for (e.g., "<").
+  StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
+
+  /// Given a Unicode codepoint as base-10 integer, return the character.
+  StringRef resolveHTMLDecimalCharacterReference(StringRef Name) const;
+
+  /// Given a Unicode codepoint as base-16 integer, return the character.
+  StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
+
+  void formTokenWithChars(Token &Result, const char *TokEnd,
+                          tok::TokenKind Kind);
+
+  void formTextToken(Token &Result, const char *TokEnd) {
+    StringRef Text(BufferPtr, TokEnd - BufferPtr);
+    formTokenWithChars(Result, TokEnd, tok::text);
+    Result.setText(Text);
+  }
+
+  SourceLocation getSourceLocation(const char *Loc) const {
+    assert(Loc >= BufferStart && Loc <= BufferEnd &&
+           "Location out of range for this buffer!");
+
+    const unsigned CharNo = Loc - BufferStart;
+    return FileLoc.getLocWithOffset(CharNo);
+  }
+
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+    return Diags.Report(Loc, DiagID);
+  }
+
+  /// Eat string matching regexp \code \s*\* \endcode.
+  void skipLineStartingDecorations();
+
+  /// Lex stuff inside comments.  CommentEnd should be set correctly.
+  void lexCommentText(Token &T);
+
+  void setupAndLexVerbatimBlock(Token &T,
+                                const char *TextBegin,
+                                char Marker, const CommandInfo *Info);
+
+  void lexVerbatimBlockFirstLine(Token &T);
+
+  void lexVerbatimBlockBody(Token &T);
+
+  void setupAndLexVerbatimLine(Token &T, const char *TextBegin,
+                               const CommandInfo *Info);
+
+  void lexVerbatimLineText(Token &T);
+
+  void lexHTMLCharacterReference(Token &T);
+
+  void setupAndLexHTMLStartTag(Token &T);
+
+  void lexHTMLStartTag(Token &T);
+
+  void setupAndLexHTMLEndTag(Token &T);
+
+  void lexHTMLEndTag(Token &T);
+
+public:
+  Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
+        const CommandTraits &Traits,
+        SourceLocation FileLoc,
+        const char *BufferStart, const char *BufferEnd);
+
+  void lex(Token &T);
+
+  StringRef getSpelling(const Token &Tok,
+                        const SourceManager &SourceMgr,
+                        bool *Invalid = nullptr) const;
+};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentNodes.inc b/include/clang/AST/CommentNodes.inc
new file mode 100644
index 0000000..1acef0c
--- /dev/null
+++ b/include/clang/AST/CommentNodes.inc
@@ -0,0 +1,123 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of AST nodes of a particular kind                                      *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef ABSTRACT_COMMENT
+#  define ABSTRACT_COMMENT(Type) Type
+#endif
+#ifndef COMMENT_RANGE
+#  define COMMENT_RANGE(Base, First, Last)
+#endif
+
+#ifndef LAST_COMMENT_RANGE
+#  define LAST_COMMENT_RANGE(Base, First, Last) COMMENT_RANGE(Base, First, Last)
+#endif
+
+#ifndef BLOCKCONTENTCOMMENT
+#  define BLOCKCONTENTCOMMENT(Type, Base) COMMENT(Type, Base)
+#endif
+ABSTRACT_COMMENT(BLOCKCONTENTCOMMENT(BlockContentComment, Comment))
+#ifndef BLOCKCOMMANDCOMMENT
+#  define BLOCKCOMMANDCOMMENT(Type, Base) BLOCKCONTENTCOMMENT(Type, Base)
+#endif
+BLOCKCOMMANDCOMMENT(BlockCommandComment, BlockContentComment)
+#ifndef PARAMCOMMANDCOMMENT
+#  define PARAMCOMMANDCOMMENT(Type, Base) BLOCKCOMMANDCOMMENT(Type, Base)
+#endif
+PARAMCOMMANDCOMMENT(ParamCommandComment, BlockCommandComment)
+#undef PARAMCOMMANDCOMMENT
+
+#ifndef TPARAMCOMMANDCOMMENT
+#  define TPARAMCOMMANDCOMMENT(Type, Base) BLOCKCOMMANDCOMMENT(Type, Base)
+#endif
+TPARAMCOMMANDCOMMENT(TParamCommandComment, BlockCommandComment)
+#undef TPARAMCOMMANDCOMMENT
+
+#ifndef VERBATIMBLOCKCOMMENT
+#  define VERBATIMBLOCKCOMMENT(Type, Base) BLOCKCOMMANDCOMMENT(Type, Base)
+#endif
+VERBATIMBLOCKCOMMENT(VerbatimBlockComment, BlockCommandComment)
+#undef VERBATIMBLOCKCOMMENT
+
+#ifndef VERBATIMLINECOMMENT
+#  define VERBATIMLINECOMMENT(Type, Base) BLOCKCOMMANDCOMMENT(Type, Base)
+#endif
+VERBATIMLINECOMMENT(VerbatimLineComment, BlockCommandComment)
+#undef VERBATIMLINECOMMENT
+
+COMMENT_RANGE(BlockCommandComment, BlockCommandComment, VerbatimLineComment)
+
+#undef BLOCKCOMMANDCOMMENT
+
+#ifndef PARAGRAPHCOMMENT
+#  define PARAGRAPHCOMMENT(Type, Base) BLOCKCONTENTCOMMENT(Type, Base)
+#endif
+PARAGRAPHCOMMENT(ParagraphComment, BlockContentComment)
+#undef PARAGRAPHCOMMENT
+
+COMMENT_RANGE(BlockContentComment, BlockCommandComment, ParagraphComment)
+
+#undef BLOCKCONTENTCOMMENT
+
+#ifndef FULLCOMMENT
+#  define FULLCOMMENT(Type, Base) COMMENT(Type, Base)
+#endif
+FULLCOMMENT(FullComment, Comment)
+#undef FULLCOMMENT
+
+#ifndef INLINECONTENTCOMMENT
+#  define INLINECONTENTCOMMENT(Type, Base) COMMENT(Type, Base)
+#endif
+ABSTRACT_COMMENT(INLINECONTENTCOMMENT(InlineContentComment, Comment))
+#ifndef HTMLTAGCOMMENT
+#  define HTMLTAGCOMMENT(Type, Base) INLINECONTENTCOMMENT(Type, Base)
+#endif
+ABSTRACT_COMMENT(HTMLTAGCOMMENT(HTMLTagComment, InlineContentComment))
+#ifndef HTMLENDTAGCOMMENT
+#  define HTMLENDTAGCOMMENT(Type, Base) HTMLTAGCOMMENT(Type, Base)
+#endif
+HTMLENDTAGCOMMENT(HTMLEndTagComment, HTMLTagComment)
+#undef HTMLENDTAGCOMMENT
+
+#ifndef HTMLSTARTTAGCOMMENT
+#  define HTMLSTARTTAGCOMMENT(Type, Base) HTMLTAGCOMMENT(Type, Base)
+#endif
+HTMLSTARTTAGCOMMENT(HTMLStartTagComment, HTMLTagComment)
+#undef HTMLSTARTTAGCOMMENT
+
+COMMENT_RANGE(HTMLTagComment, HTMLEndTagComment, HTMLStartTagComment)
+
+#undef HTMLTAGCOMMENT
+
+#ifndef INLINECOMMANDCOMMENT
+#  define INLINECOMMANDCOMMENT(Type, Base) INLINECONTENTCOMMENT(Type, Base)
+#endif
+INLINECOMMANDCOMMENT(InlineCommandComment, InlineContentComment)
+#undef INLINECOMMANDCOMMENT
+
+#ifndef TEXTCOMMENT
+#  define TEXTCOMMENT(Type, Base) INLINECONTENTCOMMENT(Type, Base)
+#endif
+TEXTCOMMENT(TextComment, InlineContentComment)
+#undef TEXTCOMMENT
+
+COMMENT_RANGE(InlineContentComment, HTMLEndTagComment, TextComment)
+
+#undef INLINECONTENTCOMMENT
+
+#ifndef VERBATIMBLOCKLINECOMMENT
+#  define VERBATIMBLOCKLINECOMMENT(Type, Base) COMMENT(Type, Base)
+#endif
+VERBATIMBLOCKLINECOMMENT(VerbatimBlockLineComment, Comment)
+#undef VERBATIMBLOCKLINECOMMENT
+
+LAST_COMMENT_RANGE(Comment, BlockCommandComment, VerbatimBlockLineComment)
+
+#undef COMMENT
+#undef COMMENT_RANGE
+#undef LAST_COMMENT_RANGE
+#undef ABSTRACT_COMMENT
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
new file mode 100644
index 0000000..7e00813
--- /dev/null
+++ b/include/clang/AST/CommentParser.h
@@ -0,0 +1,127 @@
+//===--- CommentParser.h - Doxygen comment parser ---------------*- 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 Doxygen comment parser.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMMENT_PARSER_H
+#define LLVM_CLANG_AST_COMMENT_PARSER_H
+
+#include "clang/AST/Comment.h"
+#include "clang/AST/CommentLexer.h"
+#include "clang/AST/CommentSema.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+class SourceManager;
+
+namespace comments {
+class CommandTraits;
+
+/// Doxygen comment parser.
+class Parser {
+  Parser(const Parser &) LLVM_DELETED_FUNCTION;
+  void operator=(const Parser &) LLVM_DELETED_FUNCTION;
+
+  friend class TextTokenRetokenizer;
+
+  Lexer &L;
+
+  Sema &S;
+
+  /// Allocator for anything that goes into AST nodes.
+  llvm::BumpPtrAllocator &Allocator;
+
+  /// Source manager for the comment being parsed.
+  const SourceManager &SourceMgr;
+
+  DiagnosticsEngine &Diags;
+
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+    return Diags.Report(Loc, DiagID);
+  }
+
+  const CommandTraits &Traits;
+
+  /// Current lookahead token.  We can safely assume that all tokens are from
+  /// a single source file.
+  Token Tok;
+
+  /// A stack of additional lookahead tokens.
+  SmallVector<Token, 8> MoreLATokens;
+
+  void consumeToken() {
+    if (MoreLATokens.empty())
+      L.lex(Tok);
+    else
+      Tok = MoreLATokens.pop_back_val();
+  }
+
+  void putBack(const Token &OldTok) {
+    MoreLATokens.push_back(Tok);
+    Tok = OldTok;
+  }
+
+  void putBack(ArrayRef<Token> Toks) {
+    if (Toks.empty())
+      return;
+
+    MoreLATokens.push_back(Tok);
+    for (const Token *I = &Toks.back(),
+         *B = &Toks.front();
+         I != B; --I) {
+      MoreLATokens.push_back(*I);
+    }
+
+    Tok = Toks[0];
+  }
+
+  bool isTokBlockCommand() {
+    return (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) &&
+           Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand;
+  }
+
+public:
+  Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
+         const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+         const CommandTraits &Traits);
+
+  /// Parse arguments for \\param command.
+  void parseParamCommandArgs(ParamCommandComment *PC,
+                             TextTokenRetokenizer &Retokenizer);
+
+  /// Parse arguments for \\tparam command.
+  void parseTParamCommandArgs(TParamCommandComment *TPC,
+                              TextTokenRetokenizer &Retokenizer);
+
+  void parseBlockCommandArgs(BlockCommandComment *BC,
+                             TextTokenRetokenizer &Retokenizer,
+                             unsigned NumArgs);
+
+  BlockCommandComment *parseBlockCommand();
+  InlineCommandComment *parseInlineCommand();
+
+  HTMLStartTagComment *parseHTMLStartTag();
+  HTMLEndTagComment *parseHTMLEndTag();
+
+  BlockContentComment *parseParagraphOrBlockCommand();
+
+  VerbatimBlockComment *parseVerbatimBlock();
+  VerbatimLineComment *parseVerbatimLine();
+  BlockContentComment *parseBlockContent();
+  FullComment *parseFullComment();
+};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
new file mode 100644
index 0000000..027c3b9
--- /dev/null
+++ b/include/clang/AST/CommentSema.h
@@ -0,0 +1,258 @@
+//===--- CommentSema.h - Doxygen comment semantic analysis ------*- 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 semantic analysis class for Doxygen comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMMENT_SEMA_H
+#define LLVM_CLANG_AST_COMMENT_SEMA_H
+
+#include "clang/AST/Comment.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+class Decl;
+class SourceMgr;
+class Preprocessor;
+
+namespace comments {
+class CommandTraits;
+
+class Sema {
+  Sema(const Sema &) LLVM_DELETED_FUNCTION;
+  void operator=(const Sema &) LLVM_DELETED_FUNCTION;
+
+  /// Allocator for AST nodes.
+  llvm::BumpPtrAllocator &Allocator;
+
+  /// Source manager for the comment being parsed.
+  const SourceManager &SourceMgr;
+
+  DiagnosticsEngine &Diags;
+
+  CommandTraits &Traits;
+
+  const Preprocessor *PP;
+
+  /// Information about the declaration this comment is attached to.
+  DeclInfo *ThisDeclInfo;
+
+  /// Comment AST nodes that correspond to parameter names in
+  /// \c TemplateParameters.
+  ///
+  /// Contains a valid value if \c DeclInfo->IsFilled is true.
+  llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
+
+  /// AST node for the \\brief command and its aliases.
+  const BlockCommandComment *BriefCommand;
+
+  /// AST node for the \\headerfile command.
+  const BlockCommandComment *HeaderfileCommand;
+
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+    return Diags.Report(Loc, DiagID);
+  }
+
+  /// A stack of HTML tags that are currently open (not matched with closing
+  /// tags).
+  SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
+
+public:
+  Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
+       DiagnosticsEngine &Diags, CommandTraits &Traits,
+       const Preprocessor *PP);
+
+  void setDecl(const Decl *D);
+
+  /// Returns a copy of array, owned by Sema's allocator.
+  template<typename T>
+  ArrayRef<T> copyArray(ArrayRef<T> Source) {
+    size_t Size = Source.size();
+    if (Size != 0) {
+      T *Mem = Allocator.Allocate<T>(Size);
+      std::uninitialized_copy(Source.begin(), Source.end(), Mem);
+      return llvm::makeArrayRef(Mem, Size);
+    }
+    return ArrayRef<T>();
+  }
+
+  ParagraphComment *actOnParagraphComment(
+      ArrayRef<InlineContentComment *> Content);
+
+  BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
+                                              SourceLocation LocEnd,
+                                              unsigned CommandID,
+                                              CommandMarkerKind CommandMarker);
+
+  void actOnBlockCommandArgs(BlockCommandComment *Command,
+                             ArrayRef<BlockCommandComment::Argument> Args);
+
+  void actOnBlockCommandFinish(BlockCommandComment *Command,
+                               ParagraphComment *Paragraph);
+
+  ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
+                                              SourceLocation LocEnd,
+                                              unsigned CommandID,
+                                              CommandMarkerKind CommandMarker);
+
+  void actOnParamCommandDirectionArg(ParamCommandComment *Command,
+                                     SourceLocation ArgLocBegin,
+                                     SourceLocation ArgLocEnd,
+                                     StringRef Arg);
+
+  void actOnParamCommandParamNameArg(ParamCommandComment *Command,
+                                     SourceLocation ArgLocBegin,
+                                     SourceLocation ArgLocEnd,
+                                     StringRef Arg);
+
+  void actOnParamCommandFinish(ParamCommandComment *Command,
+                               ParagraphComment *Paragraph);
+
+  TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
+                                                SourceLocation LocEnd,
+                                                unsigned CommandID,
+                                                CommandMarkerKind CommandMarker);
+
+  void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
+                                      SourceLocation ArgLocBegin,
+                                      SourceLocation ArgLocEnd,
+                                      StringRef Arg);
+
+  void actOnTParamCommandFinish(TParamCommandComment *Command,
+                                ParagraphComment *Paragraph);
+
+  InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
+                                           SourceLocation CommandLocEnd,
+                                           unsigned CommandID);
+
+  InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
+                                           SourceLocation CommandLocEnd,
+                                           unsigned CommandID,
+                                           SourceLocation ArgLocBegin,
+                                           SourceLocation ArgLocEnd,
+                                           StringRef Arg);
+
+  InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
+                                            SourceLocation LocEnd,
+                                            StringRef CommandName);
+
+  InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
+                                            SourceLocation LocEnd,
+                                            unsigned CommandID);
+
+  TextComment *actOnText(SourceLocation LocBegin,
+                         SourceLocation LocEnd,
+                         StringRef Text);
+
+  VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
+                                                unsigned CommandID);
+
+  VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
+                                                   StringRef Text);
+
+  void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
+                                SourceLocation CloseNameLocBegin,
+                                StringRef CloseName,
+                                ArrayRef<VerbatimBlockLineComment *> Lines);
+
+  VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
+                                         unsigned CommandID,
+                                         SourceLocation TextBegin,
+                                         StringRef Text);
+
+  HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
+                                              StringRef TagName);
+
+  void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
+                               ArrayRef<HTMLStartTagComment::Attribute> Attrs,
+                               SourceLocation GreaterLoc,
+                               bool IsSelfClosing);
+
+  HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
+                                     SourceLocation LocEnd,
+                                     StringRef TagName);
+
+  FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
+
+  void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
+
+  void checkReturnsCommand(const BlockCommandComment *Command);
+
+  /// Emit diagnostics about duplicate block commands that should be
+  /// used only once per comment, e.g., \\brief and \\returns.
+  void checkBlockCommandDuplicate(const BlockCommandComment *Command);
+
+  void checkDeprecatedCommand(const BlockCommandComment *Comment);
+  
+  void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
+  
+  void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
+  
+  void checkContainerDecl(const BlockCommandComment *Comment);
+
+  /// Resolve parameter names to parameter indexes in function declaration.
+  /// Emit diagnostics about unknown parametrs.
+  void resolveParamCommandIndexes(const FullComment *FC);
+
+  bool isFunctionDecl();
+  bool isAnyFunctionDecl();
+
+  /// \returns \c true if declaration that this comment is attached to declares
+  /// a function pointer.
+  bool isFunctionPointerVarDecl();
+  bool isFunctionOrMethodVariadic();
+  bool isObjCMethodDecl();
+  bool isObjCPropertyDecl();
+  bool isTemplateOrSpecialization();
+  bool isRecordLikeDecl();
+  bool isClassOrStructDecl();
+  bool isUnionDecl();
+  bool isObjCInterfaceDecl();
+  bool isObjCProtocolDecl();
+  bool isClassTemplateDecl();
+  bool isFunctionTemplateDecl();
+
+  ArrayRef<const ParmVarDecl *> getParamVars();
+
+  /// Extract all important semantic information from
+  /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
+  void inspectThisDecl();
+
+  /// Returns index of a function parameter with a given name.
+  unsigned resolveParmVarReference(StringRef Name,
+                                   ArrayRef<const ParmVarDecl *> ParamVars);
+
+  /// Returns index of a function parameter with the name closest to a given
+  /// typo.
+  unsigned correctTypoInParmVarReference(StringRef Typo,
+                                         ArrayRef<const ParmVarDecl *> ParamVars);
+
+  bool resolveTParamReference(StringRef Name,
+                              const TemplateParameterList *TemplateParameters,
+                              SmallVectorImpl<unsigned> *Position);
+
+  StringRef correctTypoInTParamReference(
+                              StringRef Typo,
+                              const TemplateParameterList *TemplateParameters);
+
+  InlineCommandComment::RenderKind
+  getInlineCommandRenderKind(StringRef Name) const;
+};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
new file mode 100644
index 0000000..21641bf
--- /dev/null
+++ b/include/clang/AST/CommentVisitor.h
@@ -0,0 +1,70 @@
+//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_COMMENTVISITOR_H
+#define LLVM_CLANG_AST_COMMENTVISITOR_H
+
+#include "clang/AST/Comment.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+namespace comments {
+
+template <typename T> struct make_ptr       { typedef       T *type; };
+template <typename T> struct make_const_ptr { typedef const T *type; };
+
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+class CommentVisitorBase {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass*>(this)->visit ## NAME(static_cast<PTR(CLASS)>(C))
+
+  RetTy visit(PTR(Comment) C) {
+    if (!C)
+      return RetTy();
+
+    switch (C->getCommentKind()) {
+    default: llvm_unreachable("Unknown comment kind!");
+#define ABSTRACT_COMMENT(COMMENT)
+#define COMMENT(CLASS, PARENT) \
+    case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
+#include "clang/AST/CommentNodes.inc"
+#undef ABSTRACT_COMMENT
+#undef COMMENT
+    }
+  }
+
+  // If the derived class does not implement a certain Visit* method, fall back
+  // on Visit* method for the superclass.
+#define ABSTRACT_COMMENT(COMMENT) COMMENT
+#define COMMENT(CLASS, PARENT) \
+  RetTy visit ## CLASS(PTR(CLASS) C) { DISPATCH(PARENT, PARENT); }
+#include "clang/AST/CommentNodes.inc"
+#undef ABSTRACT_COMMENT
+#undef COMMENT
+
+  RetTy visitComment(PTR(Comment) C) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+template<typename ImplClass, typename RetTy=void>
+class CommentVisitor :
+    public CommentVisitorBase<make_ptr, ImplClass, RetTy> {};
+
+template<typename ImplClass, typename RetTy=void>
+class ConstCommentVisitor :
+    public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {};
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
new file mode 100644
index 0000000..9ef0087
--- /dev/null
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -0,0 +1,2519 @@
+//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- 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 DataRecursiveASTVisitor interface, which recursively
+//  traverses the entire AST, using data recursion for Stmts/Exprs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming.  The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST()                                                         \
+  OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
+      OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
+      OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
+      OPERATOR(Extension)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST()                                                           \
+  OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
+      OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
+      OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
+      OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd)     \
+      OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST()                                                             \
+  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
+      OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+
+namespace clang {
+
+// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to
+// make it easier to track changes and keep the two in sync.
+#define RecursiveASTVisitor DataRecursiveASTVisitor
+
+// A helper macro to implement short-circuiting when recursing.  It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR)                                                      \
+  do {                                                                         \
+    if (!getDerived().CALL_EXPR)                                               \
+      return false;                                                            \
+  } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+///   1. traverse the AST (i.e. go to each node);
+///   2. at a given node, walk up the class hierarchy, starting from
+///      the node's dynamic type, until the top-most class (e.g. Stmt,
+///      Decl, or Type) is reached.
+///   3. given a (node, class) combination, where 'class' is some base
+///      class of the dynamic type of 'node', call a user-overridable
+///      function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
+///      for traversing an AST rooted at x.  This method simply
+///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+///      then recursively visits the child nodes of x.
+///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+///      similarly.
+///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
+///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
+///      where Bar is the direct parent class of Foo (unless Foo has
+///      no parent), and then calls VisitFoo(x) (see the next list item).
+///   3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*).  A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamespaceDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together.  In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Stmts are traversed internally using a data queue to avoid a stack overflow
+/// with hugely nested ASTs.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior.  Most users only need to override Visit*.  Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies.  Returning false from one of these overridden
+/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once.  The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations.  Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately.  This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// to return true, in which case all known implicit and explicit
+/// instantiations will be visited at the same time as the pattern
+/// from which they were produced.
+template <typename Derived> class RecursiveASTVisitor {
+public:
+  /// \brief Return a reference to the derived class.
+  Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+  /// \brief Return whether this visitor should recurse into
+  /// template instantiations.
+  bool shouldVisitTemplateInstantiations() const { return false; }
+
+  /// \brief Return whether this visitor should recurse into the types of
+  /// TypeLocs.
+  bool shouldWalkTypesOfTypeLocs() const { return true; }
+
+  /// \brief Recursively visit a statement or expression, by
+  /// dispatching to Traverse*() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseStmt(Stmt *S);
+
+  /// \brief Recursively visit a type, by dispatching to
+  /// Traverse*Type() based on the argument's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type).
+  bool TraverseType(QualType T);
+
+  /// \brief Recursively visit a type with location, by dispatching to
+  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseTypeLoc(TypeLoc TL);
+
+  /// \brief Recursively visit an attribute, by dispatching to
+  /// Traverse*Attr() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseAttr(Attr *At);
+
+  /// \brief Recursively visit a declaration, by dispatching to
+  /// Traverse*Decl() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseDecl(Decl *D);
+
+  /// \brief Recursively visit a C++ nested-name-specifier.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// \brief Recursively visit a C++ nested-name-specifier with location
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+  /// \brief Recursively visit a name with its location information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+  /// \brief Recursively visit a template name and dispatch to the
+  /// appropriate method.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateName(TemplateName Template);
+
+  /// \brief Recursively visit a template argument and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: migrate callers to TemplateArgumentLoc instead.
+  bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+  /// \brief Recursively visit a template argument location and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Recursively visit a set of template arguments.
+  /// This can be overridden by a subclass, but it's not expected that
+  /// will be needed -- this visitor always dispatches to another.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+  bool TraverseTemplateArguments(const TemplateArgument *Args,
+                                 unsigned NumArgs);
+
+  /// \brief Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the name.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+  /// \brief Recursively visit a lambda capture.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+
+  /// \brief Recursively visit the body of a lambda expression.
+  ///
+  /// This provides a hook for visitors that need more context when visiting
+  /// \c LE->getBody().
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaBody(LambdaExpr *LE);
+
+  // ---- Methods on Attrs ----
+
+  // \brief Visit an attribute.
+  bool VisitAttr(Attr *A) { return true; }
+
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+  // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+  bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+  bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT)                                                    \
+  bool WalkUpFrom##CLASS(CLASS *S) {                                           \
+    TRY_TO(WalkUpFrom##PARENT(S));                                             \
+    TRY_TO(Visit##CLASS(S));                                                   \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods.  Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  bool TraverseUnary##NAME(UnaryOperator *S) {                                 \
+    TRY_TO(WalkUpFromUnary##NAME(S));                                          \
+    StmtQueueAction StmtQueue(*this);                                          \
+    StmtQueue.queue(S->getSubExpr());                                          \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
+    TRY_TO(WalkUpFromUnaryOperator(S));                                        \
+    TRY_TO(VisitUnary##NAME(S));                                               \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+  UNARYOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods.  Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
+  bool TraverseBin##NAME(BINOP_TYPE *S) {                                      \
+    TRY_TO(WalkUpFromBin##NAME(S));                                            \
+    StmtQueueAction StmtQueue(*this);                                          \
+    StmtQueue.queue(S->getLHS());                                              \
+    StmtQueue.queue(S->getRHS());                                              \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
+    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
+    TRY_TO(VisitBin##NAME(S));                                                 \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+  BINOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods.  Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+  CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
+
+// Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+  // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+  bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+  bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
+    TRY_TO(WalkUpFrom##BASE(T));                                               \
+    TRY_TO(Visit##CLASS##Type(T));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
+
+// Declare Traverse*() for all concrete TypeLoc classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+  // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+  bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+  // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+  // TypeNodes.def and thus need to be handled specially.
+  bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+  bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
+    TRY_TO(WalkUpFrom##BASE##Loc(TL));                                         \
+    TRY_TO(Visit##CLASS##TypeLoc(TL));                                         \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on Decls ----
+
+// Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+  // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+  bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+  bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
+    TRY_TO(WalkUpFrom##BASE(D));                                               \
+    TRY_TO(Visit##CLASS##Decl(D));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+  // These are helper methods used by more than one Traverse* method.
+  bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+  bool TraverseClassInstantiations(ClassTemplateDecl *D);
+  bool TraverseVariableInstantiations(VarTemplateDecl *D);
+  bool TraverseFunctionInstantiations(FunctionTemplateDecl *D);
+  bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+                                          unsigned Count);
+  bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+  bool TraverseRecordHelper(RecordDecl *D);
+  bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+  bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+  bool TraverseDeclContextHelper(DeclContext *DC);
+  bool TraverseFunctionHelper(FunctionDecl *D);
+  bool TraverseVarHelper(VarDecl *D);
+  bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+  bool TraverseOMPClause(OMPClause *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+  /// \brief Process clauses with list of variables.
+  template <typename T> bool VisitOMPClauseList(T *Node);
+
+  typedef SmallVector<Stmt *, 16> StmtsTy;
+  typedef SmallVector<StmtsTy *, 4> QueuesTy;
+
+  QueuesTy Queues;
+
+  class NewQueueRAII {
+    RecursiveASTVisitor &RAV;
+
+  public:
+    NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
+      RAV.Queues.push_back(&queue);
+    }
+    ~NewQueueRAII() { RAV.Queues.pop_back(); }
+  };
+
+  StmtsTy &getCurrentQueue() {
+    assert(!Queues.empty() && "base TraverseStmt was never called?");
+    return *Queues.back();
+  }
+
+public:
+  class StmtQueueAction {
+    StmtsTy &CurrQueue;
+
+  public:
+    explicit StmtQueueAction(RecursiveASTVisitor &RAV)
+        : CurrQueue(RAV.getCurrentQueue()) {}
+
+    void queue(Stmt *S) { CurrQueue.push_back(S); }
+  };
+};
+
+#define DISPATCH(NAME, CLASS, VAR)                                             \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+  if (!S)
+    return true;
+
+  StmtsTy Queue, StmtsToEnqueue;
+  Queue.push_back(S);
+  NewQueueRAII NQ(StmtsToEnqueue, *this);
+
+  while (!Queue.empty()) {
+    S = Queue.pop_back_val();
+    if (!S)
+      continue;
+
+    StmtsToEnqueue.clear();
+
+#define DISPATCH_STMT(NAME, CLASS, VAR)                                        \
+  TRY_TO(Traverse##NAME(static_cast<CLASS *>(VAR)));                           \
+  break
+
+    // If we have a binary expr, dispatch to the subcode of the binop.  A smart
+    // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+    // below.
+    if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+      switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
+
+        BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
+    DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+        CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
+      }
+    } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+      switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
+
+        UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
+      }
+    } else {
+
+      // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+      switch (S->getStmtClass()) {
+      case Stmt::NoStmtClass:
+        break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_STMT(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+      }
+    }
+
+    for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
+                                                   RE = StmtsToEnqueue.rend();
+         RI != RE; ++RI)
+      Queue.push_back(*RI);
+  }
+
+  return true;
+}
+
+#undef DISPATCH_STMT
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+  if (T.isNull())
+    return true;
+
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  case Type::CLASS:                                                            \
+    DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
+#include "clang/AST/TypeNodes.def"
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+  if (TL.isNull())
+    return true;
+
+  switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  case TypeLoc::CLASS:                                                         \
+    return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+#include "clang/AST/TypeLocNodes.def"
+  }
+
+  return true;
+}
+
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+  if (!D)
+    return true;
+
+  // As a syntax visitor, we want to ignore declarations for
+  // implicitly-defined declarations (ones not typed explicitly by the
+  // user).
+  if (D->isImplicit())
+    return true;
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  case Decl::CLASS:                                                            \
+    if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D)))    \
+      return false;                                                            \
+    break;
+#include "clang/AST/DeclNodes.inc"
+  }
+
+  // Visit any attributes attached to this declaration.
+  for (auto *I : D->attrs()) {
+    if (!getDerived().TraverseAttr(I))
+      return false;
+  }
+  return true;
+}
+
+#undef DISPATCH
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+    NestedNameSpecifier *NNS) {
+  if (!NNS)
+    return true;
+
+  if (NNS->getPrefix())
+    TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+    NestedNameSpecifierLoc NNS) {
+  if (!NNS)
+    return true;
+
+  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+    TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+
+  switch (NNS.getNestedNameSpecifier()->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+    DeclarationNameInfo NameInfo) {
+  switch (NameInfo.getName().getNameKind()) {
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
+      TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
+
+    break;
+
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+    const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type:
+    return getDerived().TraverseType(Arg.getAsType());
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(Arg.getAsExpr());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+    const TemplateArgumentLoc &ArgLoc) {
+  const TemplateArgument &Arg = ArgLoc.getArgument();
+
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type: {
+    // FIXME: how can TSI ever be NULL?
+    if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+      return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+    else
+      return getDerived().TraverseType(Arg.getAsType());
+  }
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    if (ArgLoc.getTemplateQualifierLoc())
+      TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+          ArgLoc.getTemplateQualifierLoc()));
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+    const TemplateArgument *Args, unsigned NumArgs) {
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    TRY_TO(TraverseTemplateArgument(Args[I]));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+    CXXCtorInitializer *Init) {
+  if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
+  if (Init->isWritten())
+    TRY_TO(TraverseStmt(Init->getInit()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+                                                    const LambdaCapture *C) {
+  if (C->isInitCapture())
+    TRY_TO(TraverseDecl(C->getCapturedVar()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(LE->getBody());
+  return true;
+}
+
+// ----------------- Type traversal -----------------
+
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) {                 \
+    TRY_TO(WalkUpFrom##TYPE(T));                                               \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_TYPE(BuiltinType, {})
+
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(BlockPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+  TRY_TO(TraverseType(T->getPointeeType()));
+})
+
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+  TRY_TO(TraverseType(T->getElementType()));
+})
+
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+                  { TRY_TO(TraverseType(T->getReturnType())); })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+  TRY_TO(TraverseType(T->getReturnType()));
+
+  for (const auto &A : T->param_types()) {
+    TRY_TO(TraverseType(A));
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
+
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+
+DEF_TRAVERSE_TYPE(DecltypeType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(UnaryTransformType, {
+  TRY_TO(TraverseType(T->getBaseType()));
+  TRY_TO(TraverseType(T->getUnderlyingType()));
+})
+
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
+
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(T->getTemplateName()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPE(AttributedType,
+                  { TRY_TO(TraverseType(T->getModifiedType())); })
+
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+  if (T->getQualifier()) {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  }
+  TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+                  { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+  TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (T->getBaseType().getTypePtr() != T)
+    TRY_TO(TraverseType(T->getBaseType()));
+})
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
+// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
+// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                       \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) {       \
+    if (getDerived().shouldWalkTypesOfTypeLocs())                              \
+      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr())));           \
+    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                         \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // Move this over to the 'main' typeloc tree.  Note that this is a
+  // move -- we pretend that we were really looking at the unqualified
+  // typeloc all along -- rather than a recursion, so we don't follow
+  // the normal CRTP plan of going through
+  // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
+  // twice for the same type (once as a QualifiedTypeLoc version of
+  // the type, once as an UnqualifiedTypeLoc version of the type),
+  // which in effect means we'd call VisitTypeLoc twice with the
+  // 'same' type.  This solves that problem, at the cost of never
+  // seeing the qualified version of the type (unless the client
+  // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
+  // perfect solution.  A perfect solution probably requires making
+  // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+  // wrapper around Type* -- rather than being its own class in the
+  // type hierarchy.
+  return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(PointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+  TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+DEF_TRAVERSE_TYPELOC(DecayedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+  // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
+  return true;
+}
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+  if (TL.getTypePtr()->getSizeExpr())
+    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+                     { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
+
+// FIXME: location of exception specifications (attributes?)
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+  TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+
+  const FunctionProtoType *T = TL.getTypePtr();
+
+  for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+    if (TL.getParam(I)) {
+      TRY_TO(TraverseDecl(TL.getParam(I)));
+    } else if (I < T->getNumParams()) {
+      TRY_TO(TraverseType(T->getParamType(I)));
+    }
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+                     { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+  TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
+
+DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AutoType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
+
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AttributedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+  TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+  if (!DC)
+    return true;
+
+  for (auto *Child : DC->decls()) {
+    // BlockDecls and CapturedDecls are traversed through BlockExprs and
+    // CapturedStmts respectively.
+    if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+      TRY_TO(TraverseDecl(Child));
+  }
+
+  return true;
+}
+
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) {                 \
+    TRY_TO(WalkUpFrom##DECL(D));                                               \
+    { CODE; }                                                                  \
+    TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));               \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
+
+DEF_TRAVERSE_DECL(BlockDecl, {
+  if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+  TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(CapturedDecl, {
+  TRY_TO(TraverseStmt(D->getBody()));
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(EmptyDecl, {})
+
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+                  { TRY_TO(TraverseStmt(D->getAsmString())); })
+
+DEF_TRAVERSE_DECL(ImportDecl, {})
+
+DEF_TRAVERSE_DECL(FriendDecl, {
+  // Friend is either decl or a type.
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
+
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+  for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(I);
+    for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+         ITPL != ETPL; ++ITPL) {
+      TRY_TO(TraverseDecl(*ITPL));
+    }
+  }
+})
+
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl,
+                  { TRY_TO(TraverseDecl(D->getSpecialization())); })
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+                                        })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+  TRY_TO(TraverseStmt(D->getAssertExpr()));
+  TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+    TranslationUnitDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+  // We shouldn't traverse an aliased namespace, since it will be
+  // defined (and, therefore, traversed) somewhere else.
+  //
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+                             })
+
+DEF_TRAVERSE_DECL(
+    NamespaceDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+                                           })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+                                        })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+                                          })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+                                     })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+  if (D->getReturnTypeSourceInfo()) {
+    TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+  }
+  for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    TRY_TO(TraverseDecl(*I));
+  }
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody()));
+  }
+  return true;
+})
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
+
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+  for (auto *I : D->varlists()) {
+    TRY_TO(TraverseStmt(I));
+  }
+})
+
+// A helper method for TemplateDecl's children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+    TemplateParameterList *TPL) {
+  if (TPL) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  return true;
+}
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+    ClassTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      // We don't want to visit injected-class-names in this traversal.
+      if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+        continue;
+
+      switch (
+          cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+  CXXRecordDecl *TempDecl = D->getTemplatedDecl();
+  TRY_TO(TraverseDecl(TempDecl));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // class templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the class instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseClassInstantiations(D));
+
+  // Note that getInstantiatedFromMemberTemplate() is just a link
+  // from a template instantiation back to the template from which
+  // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
+    VarTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      switch (
+          cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarTemplateDecl, {
+  VarDecl *TempDecl = D->getTemplatedDecl();
+  TRY_TO(TraverseDecl(TempDecl));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // variable templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the variable instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseVariableInstantiations(D));
+
+  // Note that getInstantiatedFromMemberTemplate() is just a link
+  // from a template instantiation back to the template from which
+  // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+    FunctionTemplateDecl *D) {
+  for (auto *FD : D->specializations()) {
+    for (auto *RD : FD->redecls()) {
+      switch (RD->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        // We don't know what kind of FunctionDecl this is.
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // No need to visit explicit instantiations, we'll find the node
+      // eventually.
+      // FIXME: This is incorrect; there is no other node for an explicit
+      // instantiation of a function template specialization.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+        break;
+
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // function templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the function instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseFunctionInstantiations(D));
+})
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+  // D is the "T" in something like
+  //   template <template <typename> class T> class container { };
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  if (D->hasDefaultArgument()) {
+    TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+  }
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+  // D is the "T" in something like "template<typename T> class vector;"
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+  if (D->hasDefaultArgument())
+    TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the typedef, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type alias, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+  // A dependent using declaration which was marked with 'typename'.
+  //   template<class T> class A : public B<T> { using typename B<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // The enumerators are already traversed by
+  // decls_begin()/decls_end().
+})
+
+// Helper methods for RecordDecl and its children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the source.
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
+  if (!TraverseRecordHelper(D))
+    return false;
+  if (D->isCompleteDefinition()) {
+    for (const auto &I : D->bases()) {
+      TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+    }
+    // We don't traverse the friends or the conversions, as they are
+    // already in decls_begin()/decls_end().
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
+  // For implicit instantiations ("set<int> x;"), we don't want to
+  // recurse at all, since the instatiated class isn't written in
+  // the source code anywhere.  (Note the instatiated *type* --
+  // set<int> -- is written, and will still get a callback of
+  // TemplateSpecializationType).  For explicit instantiations
+  // ("template set<int>;"), we do need a callback, since this
+  // is the only callback that's made for this instantiation.
+  // We use getTypeAsWritten() to distinguish.
+  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+  if (!getDerived().shouldVisitTemplateInstantiations() &&
+      D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+    // Returning from here skips traversing the
+    // declaration context of the ClassTemplateSpecializationDecl
+    // (embedded in the DEF_TRAVERSE_DECL() macro)
+    // which contains the instantiated members of the class.
+    return true;
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+    const TemplateArgumentLoc *TAL, unsigned Count) {
+  for (unsigned I = 0; I < Count; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
+  // The partial specialization.
+  if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  // The args that remains unspecialized.
+  TRY_TO(TraverseTemplateArgumentLocsHelper(
+      D->getTemplateArgsAsWritten()->getTemplateArgs(),
+      D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+  // Don't need the ClassTemplatePartialSpecializationHelper, even
+  // though that's our parent class -- we already visit all the
+  // template args here.
+  TRY_TO(TraverseCXXRecordHelper(D));
+
+  // Instantiations will have been visited with the primary template.
+})
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+  // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+  //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
+
+DEF_TRAVERSE_DECL(FieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  else if (D->hasInClassInitializer())
+    TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
+
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+
+  // If we're an explicit template specialization, iterate over the
+  // template args that were explicitly specified.  If we were doing
+  // this in typing order, we'd do it between the return type and
+  // the function args, but both are handled by the FunctionTypeLoc
+  // above, so we have to choose one side.  I've decided to do before.
+  if (const FunctionTemplateSpecializationInfo *FTSI =
+          D->getTemplateSpecializationInfo()) {
+    if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+        FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+      // A specialization might not have explicit template arguments if it has
+      // a templated return type and concrete arguments.
+      if (const ASTTemplateArgumentListInfo *TALI =
+              FTSI->TemplateArgumentsAsWritten) {
+        TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+                                                  TALI->NumTemplateArgs));
+      }
+    }
+  }
+
+  // Visit the function type itself, which can be either
+  // FunctionNoProtoType or FunctionProtoType, or a typedef.  This
+  // also covers the return type and the function parameters,
+  // including exception specifications.
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+
+  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+    // Constructor initializers.
+    for (auto *I : Ctor->inits()) {
+      TRY_TO(TraverseConstructorInitializer(I));
+    }
+  }
+
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody())); // Function body.
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  // Default params are taken care of when we traverse the ParmVarDecl.
+  if (!isa<ParmVarDecl>(D))
+    TRY_TO(TraverseStmt(D->getInit()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
+  // For implicit instantiations, we don't want to
+  // recurse at all, since the instatiated class isn't written in
+  // the source code anywhere.
+  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+  if (!getDerived().shouldVisitTemplateInstantiations() &&
+      D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+    // Returning from here skips traversing the
+    // declaration context of the VarTemplateSpecializationDecl
+    // (embedded in the DEF_TRAVERSE_DECL() macro).
+    return true;
+})
+
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, {
+  // The partial specialization.
+  if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  // The args that remains unspecialized.
+  TRY_TO(TraverseTemplateArgumentLocsHelper(
+      D->getTemplateArgsAsWritten()->getTemplateArgs(),
+      D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+  // Don't need the VarTemplatePartialSpecializationHelper, even
+  // though that's our parent class -- we already visit all the
+  // template args here.
+  TRY_TO(TraverseVarHelper(D));
+
+  // Instantiations will have been visited with the primary
+  // template.
+})
+
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+  // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+  TRY_TO(TraverseDeclaratorHelper(D));
+  TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+  TRY_TO(TraverseVarHelper(D));
+
+  if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+
+  if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in children() (every stmt defines these,
+// though sometimes the range is empty).  Each individual Traverse*
+// method only needs to worry about children other than those.  To see
+// what children() does for a given class, see, e.g.,
+//   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) {                 \
+    TRY_TO(WalkUpFrom##STMT(S));                                               \
+    StmtQueueAction StmtQueue(*this);                                          \
+    { CODE; }                                                                  \
+    for (Stmt::child_range range = S->children(); range; ++range) {            \
+      StmtQueue.queue(*range);                                                 \
+    }                                                                          \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_STMT(GCCAsmStmt, {
+  StmtQueue.queue(S->getAsmString());
+  for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+    StmtQueue.queue(S->getInputConstraintLiteral(I));
+  }
+  for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+    StmtQueue.queue(S->getOutputConstraintLiteral(I));
+  }
+  for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+    StmtQueue.queue(S->getClobberStringLiteral(I));
+  }
+  // children() iterates over inputExpr and outputExpr.
+})
+
+DEF_TRAVERSE_STMT(
+    MSAsmStmt,
+    {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
+     // added this needs to be implemented.
+    })
+
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+  TRY_TO(TraverseDecl(S->getExceptionDecl()));
+  // children() iterates over the handler block.
+})
+
+DEF_TRAVERSE_STMT(DeclStmt, {
+  for (auto *I : S->decls()) {
+    TRY_TO(TraverseDecl(I));
+  }
+  // Suppress the default iteration over children() by
+  // returning.  Here's why: A DeclStmt looks like 'type var [=
+  // initializer]'.  The decls above already traverse over the
+  // initializers, so we don't have to do it again (which
+  // children() would do).
+  return true;
+})
+
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {})
+DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+})
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getExplicitTemplateArgs().getTemplateArgs(),
+        S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(
+    ImplicitCastExpr,
+    {// We don't traverse the cast type, as it's not written in the
+     // source code.
+    })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+  if (InitListExpr *Syn = S->getSyntacticForm())
+    S = Syn;
+  TRY_TO(WalkUpFromInitListExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  // All we need are the default actions.  FIXME: use a helper function.
+  for (Stmt::child_range range = S->children(); range; ++range) {
+    StmtQueue.queue(*range);
+  }
+  return true;
+}
+
+// GenericSelectionExpr is a special case because the types and expressions
+// are interleaved.  We also need to watch out for null types (default
+// generic associations).
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+    GenericSelectionExpr *S) {
+  TRY_TO(WalkUpFromGenericSelectionExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(S->getControllingExpr());
+  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+    if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+      TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+    StmtQueue.queue(S->getAssocExpr(i));
+  }
+  return true;
+}
+
+// PseudoObjectExpr is a special case because of the wierdness with
+// syntactic expressions and opaque values.
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+  TRY_TO(WalkUpFromPseudoObjectExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(S->getSyntacticForm());
+  for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+                                            e = S->semantics_end();
+       i != e; ++i) {
+    Expr *sub = *i;
+    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
+      sub = OVE->getSourceExpr();
+    StmtQueue.queue(sub);
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+  // This is called for code like 'return T()' where T is a built-in
+  // (i.e. non-class) type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+  // The child-iterator will pick up the other arguments.
+  TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+  // The child-iterator will pick up the expression representing
+  // the field.
+  // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+  // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isArgumentType())
+    TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXUuidofExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+    TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+  TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+                  { StmtQueue.queue(S->getQueriedExpression()); })
+
+DEF_TRAVERSE_STMT(VAArgExpr, {
+  // The child-iterator will pick up the expression argument.
+  TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+  // This is called for code like 'return T()' where T is a class type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+  TRY_TO(WalkUpFromLambdaExpr(S));
+
+  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+                                    CEnd = S->explicit_capture_end();
+       C != CEnd; ++C) {
+    TRY_TO(TraverseLambdaCapture(S, C));
+  }
+
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+      }
+    }
+  }
+
+  TRY_TO(TraverseLambdaBody(S));
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
+  // This is called for code like 'T()', where T is a template argument.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// These expressions all might take explicit template arguments.
+// We traverse those if so.  FIXME: implement these.
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
+DEF_TRAVERSE_STMT(BlockExpr, {
+  TRY_TO(TraverseDecl(S->getBlockDecl()));
+  return true; // no child statements to loop through.
+})
+DEF_TRAVERSE_STMT(ChooseExpr, {})
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
+    TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
+  if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
+    TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
+  if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+  if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
+DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(SEHTryStmt, {})
+DEF_TRAVERSE_STMT(SEHExceptStmt, {})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
+
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
+// Traverse OpenCL: AsType, Convert.
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
+
+// OpenMP directives.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+    OMPExecutableDirective *S) {
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+// OpenMP clauses.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+  if (!C)
+    return true;
+  switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
+#include "clang/Basic/OpenMPKinds.def"
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    break;
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  TRY_TO(TraverseStmt(C->getNumThreads()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  TRY_TO(TraverseStmt(C->getSafelen()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+  return true;
+}
+
+template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+    OMPFirstprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything.  These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+//    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+//    Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+#undef RecursiveASTVisitor
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
new file mode 100644
index 0000000..ce8b8b7
--- /dev/null
+++ b/include/clang/AST/Decl.h
@@ -0,0 +1,3645 @@
+//===--- Decl.h - Classes for representing declarations ---------*- 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 Decl subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECL_H
+#define LLVM_CLANG_AST_DECL_H
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Redeclarable.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+struct ASTTemplateArgumentListInfo;
+class CXXTemporary;
+class CompoundStmt;
+class DependentFunctionTemplateSpecializationInfo;
+class Expr;
+class FunctionTemplateDecl;
+class FunctionTemplateSpecializationInfo;
+class LabelStmt;
+class MemberSpecializationInfo;
+class Module;
+class NestedNameSpecifier;
+class Stmt;
+class StringLiteral;
+class TemplateArgumentList;
+class TemplateParameterList;
+class TypeLoc;
+class UnresolvedSetImpl;
+class VarTemplateDecl;
+
+/// \brief A container of type source information.
+///
+/// A client can read the relevant info using TypeLoc wrappers, e.g:
+/// @code
+/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
+/// TL.getStartLoc().print(OS, SrcMgr);
+/// @endcode
+///
+class TypeSourceInfo {
+  QualType Ty;
+  // Contains a memory block after the class, used for type source information,
+  // allocated by ASTContext.
+  friend class ASTContext;
+  TypeSourceInfo(QualType ty) : Ty(ty) { }
+public:
+  /// \brief Return the type wrapped by this type source info.
+  QualType getType() const { return Ty; }
+
+  /// \brief Return the TypeLoc wrapper for the type source info.
+  TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
+};
+
+/// TranslationUnitDecl - The top declaration context.
+class TranslationUnitDecl : public Decl, public DeclContext {
+  virtual void anchor();
+  ASTContext &Ctx;
+
+  /// The (most recently entered) anonymous namespace for this
+  /// translation unit, if one has been created.
+  NamespaceDecl *AnonymousNamespace;
+
+  explicit TranslationUnitDecl(ASTContext &ctx)
+    : Decl(TranslationUnit, nullptr, SourceLocation()),
+      DeclContext(TranslationUnit),
+      Ctx(ctx), AnonymousNamespace(nullptr) {}
+public:
+  ASTContext &getASTContext() const { return Ctx; }
+
+  NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
+  void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
+
+  static TranslationUnitDecl *Create(ASTContext &C);
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == TranslationUnit; }
+  static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
+    return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
+  }
+  static TranslationUnitDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<TranslationUnitDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// NamedDecl - This represents a decl with a name.  Many decls have names such
+/// as ObjCMethodDecl, but not \@class, etc.
+class NamedDecl : public Decl {
+  virtual void anchor();
+  /// Name - The name of this declaration, which is typically a normal
+  /// identifier but may also be a special kind of name (C++
+  /// constructor, Objective-C selector, etc.)
+  DeclarationName Name;
+
+private:
+  NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
+
+protected:
+  NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
+    : Decl(DK, DC, L), Name(N) { }
+
+public:
+  /// getIdentifier - Get the identifier that names this declaration,
+  /// if there is one. This will return NULL if this declaration has
+  /// no name (e.g., for an unnamed class) or if the name is a special
+  /// name (C++ constructor, Objective-C selector, etc.).
+  IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
+
+  /// getName - Get the name of identifier for this declaration as a StringRef.
+  /// This requires that the declaration have a name and that it be a simple
+  /// identifier.
+  StringRef getName() const {
+    assert(Name.isIdentifier() && "Name is not a simple identifier");
+    return getIdentifier() ? getIdentifier()->getName() : "";
+  }
+
+  /// getNameAsString - Get a human-readable name for the declaration, even if
+  /// it is one of the special kinds of names (C++ constructor, Objective-C
+  /// selector, etc).  Creating this name requires expensive string
+  /// manipulation, so it should be called only when performance doesn't matter.
+  /// For simple declarations, getNameAsCString() should suffice.
+  //
+  // FIXME: This function should be renamed to indicate that it is not just an
+  // alternate form of getName(), and clients should move as appropriate.
+  //
+  // FIXME: Deprecated, move clients to getName().
+  std::string getNameAsString() const { return Name.getAsString(); }
+
+  void printName(raw_ostream &os) const { os << Name; }
+
+  /// getDeclName - Get the actual, stored name of the declaration,
+  /// which may be a special name.
+  DeclarationName getDeclName() const { return Name; }
+
+  /// \brief Set the name of this declaration.
+  void setDeclName(DeclarationName N) { Name = N; }
+
+  /// printQualifiedName - Returns human-readable qualified name for
+  /// declaration, like A::B::i, for i being member of namespace A::B.
+  /// If declaration is not member of context which can be named (record,
+  /// namespace), it will return same result as printName().
+  /// Creating this name is expensive, so it should be called only when
+  /// performance doesn't matter.
+  void printQualifiedName(raw_ostream &OS) const;
+  void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+  // FIXME: Remove string version.
+  std::string getQualifiedNameAsString() const;
+
+  /// getNameForDiagnostic - Appends a human-readable name for this
+  /// declaration into the given stream.
+  ///
+  /// This is the method invoked by Sema when displaying a NamedDecl
+  /// in a diagnostic.  It does not necessarily produce the same
+  /// result as printName(); for example, class template
+  /// specializations are printed with their template arguments.
+  virtual void getNameForDiagnostic(raw_ostream &OS,
+                                    const PrintingPolicy &Policy,
+                                    bool Qualified) const;
+
+  /// declarationReplaces - Determine whether this declaration, if
+  /// known to be well-formed within its context, will replace the
+  /// declaration OldD if introduced into scope. A declaration will
+  /// replace another declaration if, for example, it is a
+  /// redeclaration of the same variable or function, but not if it is
+  /// a declaration of a different kind (function vs. class) or an
+  /// overloaded function.
+  bool declarationReplaces(NamedDecl *OldD) const;
+
+  /// \brief Determine whether this declaration has linkage.
+  bool hasLinkage() const;
+
+  using Decl::isModulePrivate;
+  using Decl::setModulePrivate;
+
+  /// \brief Determine whether this declaration is hidden from name lookup.
+  bool isHidden() const { return Hidden; }
+
+  /// \brief Set whether this declaration is hidden from name lookup.
+  void setHidden(bool Hide) { Hidden = Hide; }
+
+  /// \brief Determine whether this declaration is a C++ class member.
+  bool isCXXClassMember() const {
+    const DeclContext *DC = getDeclContext();
+
+    // C++0x [class.mem]p1:
+    //   The enumerators of an unscoped enumeration defined in
+    //   the class are members of the class.
+    if (isa<EnumDecl>(DC))
+      DC = DC->getRedeclContext();
+
+    return DC->isRecord();
+  }
+
+  /// \brief Determine whether the given declaration is an instance member of
+  /// a C++ class.
+  bool isCXXInstanceMember() const;
+
+  /// \brief Determine what kind of linkage this entity has.
+  /// This is not the linkage as defined by the standard or the codegen notion
+  /// of linkage. It is just an implementation detail that is used to compute
+  /// those.
+  Linkage getLinkageInternal() const;
+
+  /// \brief Get the linkage from a semantic point of view. Entities in
+  /// anonymous namespaces are external (in c++98).
+  Linkage getFormalLinkage() const {
+    return clang::getFormalLinkage(getLinkageInternal());
+  }
+
+  /// \brief True if this decl has external linkage.
+  bool hasExternalFormalLinkage() const {
+    return isExternalFormalLinkage(getLinkageInternal());
+  }
+
+  bool isExternallyVisible() const {
+    return clang::isExternallyVisible(getLinkageInternal());
+  }
+
+  /// \brief Determines the visibility of this entity.
+  Visibility getVisibility() const {
+    return getLinkageAndVisibility().getVisibility();
+  }
+
+  /// \brief Determines the linkage and visibility of this entity.
+  LinkageInfo getLinkageAndVisibility() const;
+
+  /// Kinds of explicit visibility.
+  enum ExplicitVisibilityKind {
+    VisibilityForType,
+    VisibilityForValue
+  };
+
+  /// \brief If visibility was explicitly specified for this
+  /// declaration, return that visibility.
+  Optional<Visibility>
+  getExplicitVisibility(ExplicitVisibilityKind kind) const;
+
+  /// \brief True if the computed linkage is valid. Used for consistency
+  /// checking. Should always return true.
+  bool isLinkageValid() const;
+
+  /// \brief True if something has required us to compute the linkage
+  /// of this declaration.
+  ///
+  /// Language features which can retroactively change linkage (like a
+  /// typedef name for linkage purposes) may need to consider this,
+  /// but hopefully only in transitory ways during parsing.
+  bool hasLinkageBeenComputed() const {
+    return hasCachedLinkage();
+  }
+
+  /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
+  /// the underlying named decl.
+  NamedDecl *getUnderlyingDecl() {
+    // Fast-path the common case.
+    if (this->getKind() != UsingShadow &&
+        this->getKind() != ObjCCompatibleAlias)
+      return this;
+
+    return getUnderlyingDeclImpl();
+  }
+  const NamedDecl *getUnderlyingDecl() const {
+    return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
+  }
+
+  NamedDecl *getMostRecentDecl() {
+    return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl());
+  }
+  const NamedDecl *getMostRecentDecl() const {
+    return const_cast<NamedDecl*>(this)->getMostRecentDecl();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
+  ND.printName(OS);
+  return OS;
+}
+
+/// LabelDecl - Represents the declaration of a label.  Labels also have a
+/// corresponding LabelStmt, which indicates the position that the label was
+/// defined at.  For normal labels, the location of the decl is the same as the
+/// location of the statement.  For GNU local labels (__label__), the decl
+/// location is where the __label__ is.
+class LabelDecl : public NamedDecl {
+  void anchor() override;
+  LabelStmt *TheStmt;
+  /// LocStart - For normal labels, this is the same as the main declaration
+  /// label, i.e., the location of the identifier; for GNU local labels,
+  /// this is the location of the __label__ keyword.
+  SourceLocation LocStart;
+
+  LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
+            LabelStmt *S, SourceLocation StartL)
+    : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
+
+public:
+  static LabelDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation IdentL, IdentifierInfo *II);
+  static LabelDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation IdentL, IdentifierInfo *II,
+                           SourceLocation GnuLabelL);
+  static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  LabelStmt *getStmt() const { return TheStmt; }
+  void setStmt(LabelStmt *T) { TheStmt = T; }
+
+  bool isGnuLocal() const { return LocStart != getLocation(); }
+  void setLocStart(SourceLocation L) { LocStart = L; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(LocStart, getLocation());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Label; }
+};
+
+/// NamespaceDecl - Represent a C++ namespace.
+class NamespaceDecl : public NamedDecl, public DeclContext, 
+                      public Redeclarable<NamespaceDecl> 
+{
+  /// LocStart - The starting location of the source range, pointing
+  /// to either the namespace or the inline keyword.
+  SourceLocation LocStart;
+  /// RBraceLoc - The ending location of the source range.
+  SourceLocation RBraceLoc;
+
+  /// \brief A pointer to either the anonymous namespace that lives just inside
+  /// this namespace or to the first namespace in the chain (the latter case
+  /// only when this is not the first in the chain), along with a 
+  /// boolean value indicating whether this is an inline namespace.
+  llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
+
+  NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+                SourceLocation StartLoc, SourceLocation IdLoc,
+                IdentifierInfo *Id, NamespaceDecl *PrevDecl);
+
+  typedef Redeclarable<NamespaceDecl> redeclarable_base;
+  NamespaceDecl *getNextRedeclarationImpl() override;
+  NamespaceDecl *getPreviousDeclImpl() override;
+  NamespaceDecl *getMostRecentDeclImpl() override;
+
+public:
+  static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
+                               bool Inline, SourceLocation StartLoc,
+                               SourceLocation IdLoc, IdentifierInfo *Id,
+                               NamespaceDecl *PrevDecl);
+
+  static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  /// \brief Returns true if this is an anonymous namespace declaration.
+  ///
+  /// For example:
+  /// \code
+  ///   namespace {
+  ///     ...
+  ///   };
+  /// \endcode
+  /// q.v. C++ [namespace.unnamed]
+  bool isAnonymousNamespace() const {
+    return !getIdentifier();
+  }
+
+  /// \brief Returns true if this is an inline namespace declaration.
+  bool isInline() const {
+    return AnonOrFirstNamespaceAndInline.getInt();
+  }
+
+  /// \brief Set whether this is an inline namespace declaration.
+  void setInline(bool Inline) {
+    AnonOrFirstNamespaceAndInline.setInt(Inline);
+  }
+
+  /// \brief Get the original (first) namespace declaration.
+  NamespaceDecl *getOriginalNamespace() {
+    if (isFirstDecl())
+      return this;
+
+    return AnonOrFirstNamespaceAndInline.getPointer();
+  }
+
+  /// \brief Get the original (first) namespace declaration.
+  const NamespaceDecl *getOriginalNamespace() const {
+    if (isFirstDecl())
+      return this;
+
+    return AnonOrFirstNamespaceAndInline.getPointer();
+  }
+
+  /// \brief Return true if this declaration is an original (first) declaration
+  /// of the namespace. This is false for non-original (subsequent) namespace
+  /// declarations and anonymous namespaces.
+  bool isOriginalNamespace() const { return isFirstDecl(); }
+
+  /// \brief Retrieve the anonymous namespace nested inside this namespace,
+  /// if any.
+  NamespaceDecl *getAnonymousNamespace() const {
+    return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
+  }
+
+  void setAnonymousNamespace(NamespaceDecl *D) {
+    getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
+  }
+
+  /// Retrieves the canonical declaration of this namespace.
+  NamespaceDecl *getCanonicalDecl() override {
+    return getOriginalNamespace();
+  }
+  const NamespaceDecl *getCanonicalDecl() const {
+    return getOriginalNamespace();
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(LocStart, RBraceLoc);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setLocStart(SourceLocation L) { LocStart = L; }
+  void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Namespace; }
+  static DeclContext *castToDeclContext(const NamespaceDecl *D) {
+    return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
+  }
+  static NamespaceDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC));
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// an lvalue) a function (in which case it is a function designator) or
+/// an enum constant.
+class ValueDecl : public NamedDecl {
+  void anchor() override;
+  QualType DeclType;
+
+protected:
+  ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
+            DeclarationName N, QualType T)
+    : NamedDecl(DK, DC, L, N), DeclType(T) {}
+public:
+  QualType getType() const { return DeclType; }
+  void setType(QualType newType) { DeclType = newType; }
+
+  /// \brief Determine whether this symbol is weakly-imported,
+  ///        or declared with the weak or weak-ref attr.
+  bool isWeak() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
+};
+
+/// QualifierInfo - A struct with extended info about a syntactic
+/// name qualifier, to be used for the case of out-of-line declarations.
+struct QualifierInfo {
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// NumTemplParamLists - The number of "outer" template parameter lists.
+  /// The count includes all of the template parameter lists that were matched
+  /// against the template-ids occurring into the NNS and possibly (in the
+  /// case of an explicit specialization) a final "template <>".
+  unsigned NumTemplParamLists;
+
+  /// TemplParamLists - A new-allocated array of size NumTemplParamLists,
+  /// containing pointers to the "outer" template parameter lists.
+  /// It includes all of the template parameter lists that were matched
+  /// against the template-ids occurring into the NNS and possibly (in the
+  /// case of an explicit specialization) a final "template <>".
+  TemplateParameterList** TemplParamLists;
+
+  /// Default constructor.
+  QualifierInfo()
+    : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
+
+  /// setTemplateParameterListsInfo - Sets info about "outer" template
+  /// parameter lists.
+  void setTemplateParameterListsInfo(ASTContext &Context,
+                                     unsigned NumTPLists,
+                                     TemplateParameterList **TPLists);
+
+private:
+  // Copy constructor and copy assignment are disabled.
+  QualifierInfo(const QualifierInfo&) LLVM_DELETED_FUNCTION;
+  QualifierInfo& operator=(const QualifierInfo&) LLVM_DELETED_FUNCTION;
+};
+
+/// \brief Represents a ValueDecl that came out of a declarator.
+/// Contains type source information through TypeSourceInfo.
+class DeclaratorDecl : public ValueDecl {
+  // A struct representing both a TInfo and a syntactic qualifier,
+  // to be used for the (uncommon) case of out-of-line declarations.
+  struct ExtInfo : public QualifierInfo {
+    TypeSourceInfo *TInfo;
+  };
+
+  llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
+
+  /// InnerLocStart - The start of the source range for this declaration,
+  /// ignoring outer template declarations.
+  SourceLocation InnerLocStart;
+
+  bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
+  ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
+  const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
+
+protected:
+  DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
+                 DeclarationName N, QualType T, TypeSourceInfo *TInfo,
+                 SourceLocation StartL)
+    : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
+  }
+
+public:
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return hasExtInfo()
+      ? getExtInfo()->TInfo
+      : DeclInfo.get<TypeSourceInfo*>();
+  }
+  void setTypeSourceInfo(TypeSourceInfo *TI) {
+    if (hasExtInfo())
+      getExtInfo()->TInfo = TI;
+    else
+      DeclInfo = TI;
+  }
+
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  SourceLocation getInnerLocStart() const { return InnerLocStart; }
+  void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getOuterLocStart();
+  }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+  /// declaration, if it was present in the source.
+  NestedNameSpecifier *getQualifier() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
+                        : nullptr;
+  }
+
+  /// \brief Retrieve the nested-name-specifier (with source-location
+  /// information) that qualifies the name of this declaration, if it was
+  /// present in the source.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc
+                        : NestedNameSpecifierLoc();
+  }
+
+  void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
+
+  unsigned getNumTemplateParameterLists() const {
+    return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+  }
+  TemplateParameterList *getTemplateParameterList(unsigned index) const {
+    assert(index < getNumTemplateParameterLists());
+    return getExtInfo()->TemplParamLists[index];
+  }
+  void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+                                     TemplateParameterList **TPLists);
+
+  SourceLocation getTypeSpecStartLoc() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstDeclarator && K <= lastDeclarator;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Structure used to store a statement, the constant value to
+/// which it was evaluated (if any), and whether or not the statement
+/// is an integral constant expression (if known).
+struct EvaluatedStmt {
+  EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+                    CheckingICE(false), IsICE(false) { }
+
+  /// \brief Whether this statement was already evaluated.
+  bool WasEvaluated : 1;
+
+  /// \brief Whether this statement is being evaluated.
+  bool IsEvaluating : 1;
+
+  /// \brief Whether we already checked whether this statement was an
+  /// integral constant expression.
+  bool CheckedICE : 1;
+
+  /// \brief Whether we are checking whether this statement is an
+  /// integral constant expression.
+  bool CheckingICE : 1;
+
+  /// \brief Whether this statement is an integral constant expression,
+  /// or in C++11, whether the statement is a constant expression. Only
+  /// valid if CheckedICE is true.
+  bool IsICE : 1;
+
+  Stmt *Value;
+  APValue Evaluated;
+};
+
+/// VarDecl - An instance of this class is created to represent a variable
+/// declaration or definition.
+class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
+public:
+  typedef clang::StorageClass StorageClass;
+
+  /// getStorageClassSpecifierString - Return the string used to
+  /// specify the storage class \p SC.
+  ///
+  /// It is illegal to call this function with SC == None.
+  static const char *getStorageClassSpecifierString(StorageClass SC);
+
+  /// \brief Initialization styles.
+  enum InitializationStyle {
+    CInit,    ///< C-style initialization with assignment
+    CallInit, ///< Call-style initialization (C++98)
+    ListInit  ///< Direct list-initialization (C++11)
+  };
+
+  /// \brief Kinds of thread-local storage.
+  enum TLSKind {
+    TLS_None,   ///< Not a TLS variable.
+    TLS_Static, ///< TLS with a known-constant initializer.
+    TLS_Dynamic ///< TLS with a dynamic initializer.
+  };
+
+protected:
+  /// \brief Placeholder type used in Init to denote an unparsed C++ default
+  /// argument.
+  struct UnparsedDefaultArgument;
+
+  /// \brief Placeholder type used in Init to denote an uninstantiated C++
+  /// default argument.
+  struct UninstantiatedDefaultArgument;
+
+  typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *,
+                              UnparsedDefaultArgument *,
+                              UninstantiatedDefaultArgument *> InitType;
+
+  /// \brief The initializer for this variable or, for a ParmVarDecl, the
+  /// C++ default argument.
+  mutable InitType Init;
+
+private:
+  class VarDeclBitfields {
+    friend class VarDecl;
+    friend class ASTDeclReader;
+
+    unsigned SClass : 3;
+    unsigned TSCSpec : 2;
+    unsigned InitStyle : 2;
+
+    /// \brief Whether this variable is the exception variable in a C++ catch
+    /// or an Objective-C @catch statement.
+    unsigned ExceptionVar : 1;
+
+    /// \brief Whether this local variable could be allocated in the return
+    /// slot of its function, enabling the named return value optimization
+    /// (NRVO).
+    unsigned NRVOVariable : 1;
+
+    /// \brief Whether this variable is the for-range-declaration in a C++0x
+    /// for-range statement.
+    unsigned CXXForRangeDecl : 1;
+
+    /// \brief Whether this variable is an ARC pseudo-__strong
+    /// variable;  see isARCPseudoStrong() for details.
+    unsigned ARCPseudoStrong : 1;
+
+    /// \brief Whether this variable is (C++0x) constexpr.
+    unsigned IsConstexpr : 1;
+
+    /// \brief Whether this variable is the implicit variable for a lambda
+    /// init-capture.
+    unsigned IsInitCapture : 1;
+
+    /// \brief Whether this local extern variable's previous declaration was
+    /// declared in the same block scope. This controls whether we should merge
+    /// the type of this declaration with its previous declaration.
+    unsigned PreviousDeclInSameBlockScope : 1;
+  };
+  enum { NumVarDeclBits = 14 };
+
+  friend class ASTDeclReader;
+  friend class StmtIteratorBase;
+  friend class ASTNodeImporter;
+
+protected:
+  enum { NumParameterIndexBits = 8 };
+
+  class ParmVarDeclBitfields {
+    friend class ParmVarDecl;
+    friend class ASTDeclReader;
+
+    unsigned : NumVarDeclBits;
+
+    /// Whether this parameter inherits a default argument from a
+    /// prior declaration.
+    unsigned HasInheritedDefaultArg : 1;
+
+    /// Whether this parameter undergoes K&R argument promotion.
+    unsigned IsKNRPromoted : 1;
+
+    /// Whether this parameter is an ObjC method parameter or not.
+    unsigned IsObjCMethodParam : 1;
+
+    /// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
+    /// Otherwise, the number of function parameter scopes enclosing
+    /// the function parameter scope in which this parameter was
+    /// declared.
+    unsigned ScopeDepthOrObjCQuals : 7;
+
+    /// The number of parameters preceding this parameter in the
+    /// function parameter scope in which it was declared.
+    unsigned ParameterIndex : NumParameterIndexBits;
+  };
+
+  union {
+    unsigned AllBits;
+    VarDeclBitfields VarDeclBits;
+    ParmVarDeclBitfields ParmVarDeclBits;
+  };
+
+  VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+          SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+          TypeSourceInfo *TInfo, StorageClass SC);
+
+  typedef Redeclarable<VarDecl> redeclarable_base;
+  VarDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  VarDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  VarDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  static VarDecl *Create(ASTContext &C, DeclContext *DC,
+                         SourceLocation StartLoc, SourceLocation IdLoc,
+                         IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+                         StorageClass S);
+
+  static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  /// \brief Returns the storage class as written in the source. For the
+  /// computed linkage of symbol, see getLinkage.
+  StorageClass getStorageClass() const {
+    return (StorageClass) VarDeclBits.SClass;
+  }
+  void setStorageClass(StorageClass SC);
+
+  void setTSCSpec(ThreadStorageClassSpecifier TSC) {
+    VarDeclBits.TSCSpec = TSC;
+    assert(VarDeclBits.TSCSpec == TSC && "truncation");
+  }
+  ThreadStorageClassSpecifier getTSCSpec() const {
+    return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
+  }
+  TLSKind getTLSKind() const;
+
+  /// hasLocalStorage - Returns true if a variable with function scope
+  ///  is a non-static local variable.
+  bool hasLocalStorage() const {
+    if (getStorageClass() == SC_None)
+      // Second check is for C++11 [dcl.stc]p4.
+      return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
+
+    // Global Named Register (GNU extension)
+    if (getStorageClass() == SC_Register && !isLocalVarDecl())
+      return false;
+
+    // Return true for:  Auto, Register.
+    // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
+
+    return getStorageClass() >= SC_Auto;
+  }
+
+  /// isStaticLocal - Returns true if a variable with function scope is a
+  /// static local variable.
+  bool isStaticLocal() const {
+    return (getStorageClass() == SC_Static ||
+            // C++11 [dcl.stc]p4
+            (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
+      && !isFileVarDecl();
+  }
+
+  /// \brief Returns true if a variable has extern or __private_extern__
+  /// storage.
+  bool hasExternalStorage() const {
+    return getStorageClass() == SC_Extern ||
+           getStorageClass() == SC_PrivateExtern;
+  }
+
+  /// \brief Returns true for all variables that do not have local storage.
+  ///
+  /// This includes all global variables as well as static variables declared
+  /// within a function.
+  bool hasGlobalStorage() const { return !hasLocalStorage(); }
+
+  /// \brief Get the storage duration of this variable, per C++ [basic.stc].
+  StorageDuration getStorageDuration() const {
+    return hasLocalStorage() ? SD_Automatic :
+           getTSCSpec() ? SD_Thread : SD_Static;
+  }
+
+  /// \brief Compute the language linkage.
+  LanguageLinkage getLanguageLinkage() const;
+
+  /// \brief Determines whether this variable is a variable with
+  /// external, C linkage.
+  bool isExternC() const;
+
+  /// \brief Determines whether this variable's context is, or is nested within,
+  /// a C++ extern "C" linkage spec.
+  bool isInExternCContext() const;
+
+  /// \brief Determines whether this variable's context is, or is nested within,
+  /// a C++ extern "C++" linkage spec.
+  bool isInExternCXXContext() const;
+
+  /// isLocalVarDecl - Returns true for local variable declarations
+  /// other than parameters.  Note that this includes static variables
+  /// inside of functions. It also includes variables inside blocks.
+  ///
+  ///   void foo() { int x; static int y; extern int z; }
+  ///
+  bool isLocalVarDecl() const {
+    if (getKind() != Decl::Var)
+      return false;
+    if (const DeclContext *DC = getLexicalDeclContext())
+      return DC->getRedeclContext()->isFunctionOrMethod();
+    return false;
+  }
+
+  /// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
+  /// excludes variables declared in blocks.
+  bool isFunctionOrMethodVarDecl() const {
+    if (getKind() != Decl::Var)
+      return false;
+    const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
+    return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
+  }
+
+  /// \brief Determines whether this is a static data member.
+  ///
+  /// This will only be true in C++, and applies to, e.g., the
+  /// variable 'x' in:
+  /// \code
+  /// struct S {
+  ///   static int x;
+  /// };
+  /// \endcode
+  bool isStaticDataMember() const {
+    // If it wasn't static, it would be a FieldDecl.
+    return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
+  }
+
+  VarDecl *getCanonicalDecl() override;
+  const VarDecl *getCanonicalDecl() const {
+    return const_cast<VarDecl*>(this)->getCanonicalDecl();
+  }
+
+  enum DefinitionKind {
+    DeclarationOnly,      ///< This declaration is only a declaration.
+    TentativeDefinition,  ///< This declaration is a tentative definition.
+    Definition            ///< This declaration is definitely a definition.
+  };
+
+  /// \brief Check whether this declaration is a definition. If this could be
+  /// a tentative definition (in C), don't check whether there's an overriding
+  /// definition.
+  DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
+  DefinitionKind isThisDeclarationADefinition() const {
+    return isThisDeclarationADefinition(getASTContext());
+  }
+
+  /// \brief Check whether this variable is defined in this
+  /// translation unit.
+  DefinitionKind hasDefinition(ASTContext &) const;
+  DefinitionKind hasDefinition() const {
+    return hasDefinition(getASTContext());
+  }
+
+  /// \brief Get the tentative definition that acts as the real definition in
+  /// a TU. Returns null if there is a proper definition available.
+  VarDecl *getActingDefinition();
+  const VarDecl *getActingDefinition() const {
+    return const_cast<VarDecl*>(this)->getActingDefinition();
+  }
+
+  /// \brief Get the real (not just tentative) definition for this declaration.
+  VarDecl *getDefinition(ASTContext &);
+  const VarDecl *getDefinition(ASTContext &C) const {
+    return const_cast<VarDecl*>(this)->getDefinition(C);
+  }
+  VarDecl *getDefinition() {
+    return getDefinition(getASTContext());
+  }
+  const VarDecl *getDefinition() const {
+    return const_cast<VarDecl*>(this)->getDefinition();
+  }
+
+  /// \brief Determine whether this is or was instantiated from an out-of-line
+  /// definition of a static data member.
+  bool isOutOfLine() const override;
+
+  /// \brief If this is a static data member, find its out-of-line definition.
+  VarDecl *getOutOfLineDefinition();
+
+  /// isFileVarDecl - Returns true for file scoped variable declaration.
+  bool isFileVarDecl() const {
+    Kind K = getKind();
+    if (K == ParmVar || K == ImplicitParam)
+      return false;
+
+    if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
+      return true;
+
+    if (isStaticDataMember())
+      return true;
+
+    return false;
+  }
+
+  /// getAnyInitializer - Get the initializer for this variable, no matter which
+  /// declaration it is attached to.
+  const Expr *getAnyInitializer() const {
+    const VarDecl *D;
+    return getAnyInitializer(D);
+  }
+
+  /// getAnyInitializer - Get the initializer for this variable, no matter which
+  /// declaration it is attached to. Also get that declaration.
+  const Expr *getAnyInitializer(const VarDecl *&D) const;
+
+  bool hasInit() const {
+    return !Init.isNull() && (Init.is<Stmt *>() || Init.is<EvaluatedStmt *>());
+  }
+  const Expr *getInit() const {
+    if (Init.isNull())
+      return nullptr;
+
+    const Stmt *S = Init.dyn_cast<Stmt *>();
+    if (!S) {
+      if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+        S = ES->Value;
+    }
+    return (const Expr*) S;
+  }
+  Expr *getInit() {
+    if (Init.isNull())
+      return nullptr;
+
+    Stmt *S = Init.dyn_cast<Stmt *>();
+    if (!S) {
+      if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+        S = ES->Value;
+    }
+
+    return (Expr*) S;
+  }
+
+  /// \brief Retrieve the address of the initializer expression.
+  Stmt **getInitAddress() {
+    if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>())
+      return &ES->Value;
+
+    // This union hack tip-toes around strict-aliasing rules.
+    union {
+      InitType *InitPtr;
+      Stmt **StmtPtr;
+    };
+
+    InitPtr = &Init;
+    return StmtPtr;
+  }
+
+  void setInit(Expr *I);
+
+  /// \brief Determine whether this variable's value can be used in a
+  /// constant expression, according to the relevant language standard.
+  /// This only checks properties of the declaration, and does not check
+  /// whether the initializer is in fact a constant expression.
+  bool isUsableInConstantExpressions(ASTContext &C) const;
+
+  EvaluatedStmt *ensureEvaluatedStmt() const;
+
+  /// \brief Attempt to evaluate the value of the initializer attached to this
+  /// declaration, and produce notes explaining why it cannot be evaluated or is
+  /// not a constant expression. Returns a pointer to the value if evaluation
+  /// succeeded, 0 otherwise.
+  APValue *evaluateValue() const;
+  APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+
+  /// \brief Return the already-evaluated value of this variable's
+  /// initializer, or NULL if the value is not yet known. Returns pointer
+  /// to untyped APValue if the value could not be evaluated.
+  APValue *getEvaluatedValue() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      if (Eval->WasEvaluated)
+        return &Eval->Evaluated;
+
+    return nullptr;
+  }
+
+  /// \brief Determines whether it is already known whether the
+  /// initializer is an integral constant expression or not.
+  bool isInitKnownICE() const {
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+      return Eval->CheckedICE;
+
+    return false;
+  }
+
+  /// \brief Determines whether the initializer is an integral constant
+  /// expression, or in C++11, whether the initializer is a constant
+  /// expression.
+  ///
+  /// \pre isInitKnownICE()
+  bool isInitICE() const {
+    assert(isInitKnownICE() &&
+           "Check whether we already know that the initializer is an ICE");
+    return Init.get<EvaluatedStmt *>()->IsICE;
+  }
+
+  /// \brief Determine whether the value of the initializer attached to this
+  /// declaration is an integral constant expression.
+  bool checkInitIsICE() const;
+
+  void setInitStyle(InitializationStyle Style) {
+    VarDeclBits.InitStyle = Style;
+  }
+
+  /// \brief The style of initialization for this declaration.
+  ///
+  /// C-style initialization is "int x = 1;". Call-style initialization is
+  /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
+  /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
+  /// expression for class types. List-style initialization is C++11 syntax,
+  /// e.g. "int x{1};". Clients can distinguish between different forms of
+  /// initialization by checking this value. In particular, "int x = {1};" is
+  /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
+  /// Init expression in all three cases is an InitListExpr.
+  InitializationStyle getInitStyle() const {
+    return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
+  }
+
+  /// \brief Whether the initializer is a direct-initializer (list or call).
+  bool isDirectInit() const {
+    return getInitStyle() != CInit;
+  }
+
+  /// \brief Determine whether this variable is the exception variable in a
+  /// C++ catch statememt or an Objective-C \@catch statement.
+  bool isExceptionVariable() const {
+    return VarDeclBits.ExceptionVar;
+  }
+  void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; }
+
+  /// \brief Determine whether this local variable can be used with the named
+  /// return value optimization (NRVO).
+  ///
+  /// The named return value optimization (NRVO) works by marking certain
+  /// non-volatile local variables of class type as NRVO objects. These
+  /// locals can be allocated within the return slot of their containing
+  /// function, in which case there is no need to copy the object to the
+  /// return slot when returning from the function. Within the function body,
+  /// each return that returns the NRVO object will have this variable as its
+  /// NRVO candidate.
+  bool isNRVOVariable() const { return VarDeclBits.NRVOVariable; }
+  void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; }
+
+  /// \brief Determine whether this variable is the for-range-declaration in
+  /// a C++0x for-range statement.
+  bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
+  void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
+
+  /// \brief Determine whether this variable is an ARC pseudo-__strong
+  /// variable.  A pseudo-__strong variable has a __strong-qualified
+  /// type but does not actually retain the object written into it.
+  /// Generally such variables are also 'const' for safety.
+  bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
+  void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; }
+
+  /// Whether this variable is (C++11) constexpr.
+  bool isConstexpr() const { return VarDeclBits.IsConstexpr; }
+  void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; }
+
+  /// Whether this variable is the implicit variable for a lambda init-capture.
+  bool isInitCapture() const { return VarDeclBits.IsInitCapture; }
+  void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; }
+
+  /// Whether this local extern variable declaration's previous declaration
+  /// was declared in the same block scope. Only correct in C++.
+  bool isPreviousDeclInSameBlockScope() const {
+    return VarDeclBits.PreviousDeclInSameBlockScope;
+  }
+  void setPreviousDeclInSameBlockScope(bool Same) {
+    VarDeclBits.PreviousDeclInSameBlockScope = Same;
+  }
+
+  /// \brief If this variable is an instantiated static data member of a
+  /// class template specialization, returns the templated static data member
+  /// from which it was instantiated.
+  VarDecl *getInstantiatedFromStaticDataMember() const;
+
+  /// \brief If this variable is an instantiation of a variable template or a
+  /// static data member of a class template, determine what kind of
+  /// template specialization or instantiation this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+
+  /// \brief If this variable is an instantiation of a variable template or a
+  /// static data member of a class template, determine its point of
+  /// instantiation.
+  SourceLocation getPointOfInstantiation() const;
+
+  /// \brief If this variable is an instantiation of a static data member of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const;
+
+  /// \brief For a static data member that was instantiated from a static
+  /// data member of a class template, set the template specialiation kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  /// \brief Specify that this variable is an instantiation of the
+  /// static data member VD.
+  void setInstantiationOfStaticDataMember(VarDecl *VD,
+                                          TemplateSpecializationKind TSK);
+
+  /// \brief Retrieves the variable template that is described by this
+  /// variable declaration.
+  ///
+  /// Every variable template is represented as a VarTemplateDecl and a
+  /// VarDecl. The former contains template properties (such as
+  /// the template parameter lists) while the latter contains the
+  /// actual description of the template's
+  /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
+  /// VarDecl that from a VarTemplateDecl, while
+  /// getDescribedVarTemplate() retrieves the VarTemplateDecl from
+  /// a VarDecl.
+  VarTemplateDecl *getDescribedVarTemplate() const;
+
+  void setDescribedVarTemplate(VarTemplateDecl *Template);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
+};
+
+class ImplicitParamDecl : public VarDecl {
+  void anchor() override;
+public:
+  static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation IdLoc, IdentifierInfo *Id,
+                                   QualType T);
+
+  static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
+                    IdentifierInfo *Id, QualType Type)
+    : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
+              /*tinfo*/ nullptr, SC_None) {
+    setImplicit();
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ImplicitParam; }
+};
+
+/// ParmVarDecl - Represents a parameter to a function.
+class ParmVarDecl : public VarDecl {
+public:
+  enum { MaxFunctionScopeDepth = 255 };
+  enum { MaxFunctionScopeIndex = 255 };
+
+protected:
+  ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+              SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+              TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
+      : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
+    assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
+    assert(ParmVarDeclBits.IsKNRPromoted == false);
+    assert(ParmVarDeclBits.IsObjCMethodParam == false);
+    setDefaultArg(DefArg);
+  }
+
+public:
+  static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation StartLoc,
+                             SourceLocation IdLoc, IdentifierInfo *Id,
+                             QualType T, TypeSourceInfo *TInfo,
+                             StorageClass S, Expr *DefArg);
+
+  static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  void setObjCMethodScopeInfo(unsigned parameterIndex) {
+    ParmVarDeclBits.IsObjCMethodParam = true;
+    setParameterIndex(parameterIndex);
+  }
+
+  void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
+    assert(!ParmVarDeclBits.IsObjCMethodParam);
+
+    ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
+    assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth
+           && "truncation!");
+
+    setParameterIndex(parameterIndex);
+  }
+
+  bool isObjCMethodParameter() const {
+    return ParmVarDeclBits.IsObjCMethodParam;
+  }
+
+  unsigned getFunctionScopeDepth() const {
+    if (ParmVarDeclBits.IsObjCMethodParam) return 0;
+    return ParmVarDeclBits.ScopeDepthOrObjCQuals;
+  }
+
+  /// Returns the index of this parameter in its prototype or method scope.
+  unsigned getFunctionScopeIndex() const {
+    return getParameterIndex();
+  }
+
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
+    return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
+  }
+  void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
+    assert(ParmVarDeclBits.IsObjCMethodParam);
+    ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
+  }
+
+  /// True if the value passed to this parameter must undergo
+  /// K&R-style default argument promotion:
+  ///
+  /// C99 6.5.2.2.
+  ///   If the expression that denotes the called function has a type
+  ///   that does not include a prototype, the integer promotions are
+  ///   performed on each argument, and arguments that have type float
+  ///   are promoted to double.
+  bool isKNRPromoted() const {
+    return ParmVarDeclBits.IsKNRPromoted;
+  }
+  void setKNRPromoted(bool promoted) {
+    ParmVarDeclBits.IsKNRPromoted = promoted;
+  }
+
+  Expr *getDefaultArg();
+  const Expr *getDefaultArg() const {
+    return const_cast<ParmVarDecl *>(this)->getDefaultArg();
+  }
+
+  void setDefaultArg(Expr *defarg) {
+    Init = reinterpret_cast<Stmt *>(defarg);
+  }
+
+  /// \brief Retrieve the source range that covers the entire default
+  /// argument.
+  SourceRange getDefaultArgRange() const;
+  void setUninstantiatedDefaultArg(Expr *arg) {
+    Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg);
+  }
+  Expr *getUninstantiatedDefaultArg() {
+    return (Expr *)Init.get<UninstantiatedDefaultArgument *>();
+  }
+  const Expr *getUninstantiatedDefaultArg() const {
+    return (const Expr *)Init.get<UninstantiatedDefaultArgument *>();
+  }
+
+  /// hasDefaultArg - Determines whether this parameter has a default argument,
+  /// either parsed or not.
+  bool hasDefaultArg() const {
+    return getInit() || hasUnparsedDefaultArg() ||
+      hasUninstantiatedDefaultArg();
+  }
+
+  /// hasUnparsedDefaultArg - Determines whether this parameter has a
+  /// default argument that has not yet been parsed. This will occur
+  /// during the processing of a C++ class whose member functions have
+  /// default arguments, e.g.,
+  /// @code
+  ///   class X {
+  ///   public:
+  ///     void f(int x = 17); // x has an unparsed default argument now
+  ///   }; // x has a regular default argument now
+  /// @endcode
+  bool hasUnparsedDefaultArg() const {
+    return Init.is<UnparsedDefaultArgument*>();
+  }
+
+  bool hasUninstantiatedDefaultArg() const {
+    return Init.is<UninstantiatedDefaultArgument*>();
+  }
+
+  /// setUnparsedDefaultArg - Specify that this parameter has an
+  /// unparsed default argument. The argument will be replaced with a
+  /// real default argument via setDefaultArg when the class
+  /// definition enclosing the function declaration that owns this
+  /// default argument is completed.
+  void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; }
+
+  bool hasInheritedDefaultArg() const {
+    return ParmVarDeclBits.HasInheritedDefaultArg;
+  }
+
+  void setHasInheritedDefaultArg(bool I = true) {
+    ParmVarDeclBits.HasInheritedDefaultArg = I;
+  }
+
+  QualType getOriginalType() const;
+
+  /// \brief Determine whether this parameter is actually a function
+  /// parameter pack.
+  bool isParameterPack() const;
+
+  /// setOwningFunction - Sets the function declaration that owns this
+  /// ParmVarDecl. Since ParmVarDecls are often created before the
+  /// FunctionDecls that own them, this routine is required to update
+  /// the DeclContext appropriately.
+  void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ParmVar; }
+
+private:
+  enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
+
+  void setParameterIndex(unsigned parameterIndex) {
+    if (parameterIndex >= ParameterIndexSentinel) {
+      setParameterIndexLarge(parameterIndex);
+      return;
+    }
+
+    ParmVarDeclBits.ParameterIndex = parameterIndex;
+    assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
+  }
+  unsigned getParameterIndex() const {
+    unsigned d = ParmVarDeclBits.ParameterIndex;
+    return d == ParameterIndexSentinel ? getParameterIndexLarge() : d;
+  }
+
+  void setParameterIndexLarge(unsigned parameterIndex);
+  unsigned getParameterIndexLarge() const;
+};
+
+/// FunctionDecl - An instance of this class is created to represent a
+/// function declaration or definition.
+///
+/// Since a given function can be declared several times in a program,
+/// there may be several FunctionDecls that correspond to that
+/// function. Only one of those FunctionDecls will be found when
+/// traversing the list of declarations in the context of the
+/// FunctionDecl (e.g., the translation unit); this FunctionDecl
+/// contains all of the information known about the function. Other,
+/// previous declarations of the function are available via the
+/// getPreviousDecl() chain.
+class FunctionDecl : public DeclaratorDecl, public DeclContext,
+                     public Redeclarable<FunctionDecl> {
+public:
+  typedef clang::StorageClass StorageClass;
+
+  /// \brief The kind of templated function a FunctionDecl can be.
+  enum TemplatedKind {
+    TK_NonTemplate,
+    TK_FunctionTemplate,
+    TK_MemberSpecialization,
+    TK_FunctionTemplateSpecialization,
+    TK_DependentFunctionTemplateSpecialization
+  };
+
+private:
+  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+  /// parameters of this function.  This is null if a prototype or if there are
+  /// no formals.
+  ParmVarDecl **ParamInfo;
+
+  /// DeclsInPrototypeScope - Array of pointers to NamedDecls for
+  /// decls defined in the function prototype that are not parameters. E.g.
+  /// 'enum Y' in 'void f(enum Y {AA} x) {}'.
+  ArrayRef<NamedDecl *> DeclsInPrototypeScope;
+
+  LazyDeclStmtPtr Body;
+
+  // FIXME: This can be packed into the bitfields in Decl.
+  // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
+  unsigned SClass : 2;
+  bool IsInline : 1;
+  bool IsInlineSpecified : 1;
+  bool IsVirtualAsWritten : 1;
+  bool IsPure : 1;
+  bool HasInheritedPrototype : 1;
+  bool HasWrittenPrototype : 1;
+  bool IsDeleted : 1;
+  bool IsTrivial : 1; // sunk from CXXMethodDecl
+  bool IsDefaulted : 1; // sunk from CXXMethoDecl
+  bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
+  bool HasImplicitReturnZero : 1;
+  bool IsLateTemplateParsed : 1;
+  bool IsConstexpr : 1;
+
+  /// \brief Indicates if the function was a definition but its body was
+  /// skipped.
+  unsigned HasSkippedBody : 1;
+
+  /// \brief End part of this FunctionDecl's source range.
+  ///
+  /// We could compute the full range in getSourceRange(). However, when we're
+  /// dealing with a function definition deserialized from a PCH/AST file,
+  /// we can only compute the full range once the function body has been
+  /// de-serialized, so it's far better to have the (sometimes-redundant)
+  /// EndRangeLoc.
+  SourceLocation EndRangeLoc;
+
+  /// \brief The template or declaration that this declaration
+  /// describes or was instantiated from, respectively.
+  ///
+  /// For non-templates, this value will be NULL. For function
+  /// declarations that describe a function template, this will be a
+  /// pointer to a FunctionTemplateDecl. For member functions
+  /// of class template specializations, this will be a MemberSpecializationInfo
+  /// pointer containing information about the specialization.
+  /// For function template specializations, this will be a
+  /// FunctionTemplateSpecializationInfo, which contains information about
+  /// the template being specialized and the template arguments involved in
+  /// that specialization.
+  llvm::PointerUnion4<FunctionTemplateDecl *,
+                      MemberSpecializationInfo *,
+                      FunctionTemplateSpecializationInfo *,
+                      DependentFunctionTemplateSpecializationInfo *>
+    TemplateOrSpecialization;
+
+  /// DNLoc - Provides source/type location info for the
+  /// declaration name embedded in the DeclaratorDecl base class.
+  DeclarationNameLoc DNLoc;
+
+  /// \brief Specify that this function declaration is actually a function
+  /// template specialization.
+  ///
+  /// \param C the ASTContext.
+  ///
+  /// \param Template the function template that this function template
+  /// specialization specializes.
+  ///
+  /// \param TemplateArgs the template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param InsertPos If non-NULL, the position in the function template
+  /// specialization set where the function template specialization data will
+  /// be inserted.
+  ///
+  /// \param TSK the kind of template specialization this is.
+  ///
+  /// \param TemplateArgsAsWritten location info of template arguments.
+  ///
+  /// \param PointOfInstantiation point at which the function template
+  /// specialization was first instantiated.
+  void setFunctionTemplateSpecialization(ASTContext &C,
+                                         FunctionTemplateDecl *Template,
+                                       const TemplateArgumentList *TemplateArgs,
+                                         void *InsertPos,
+                                         TemplateSpecializationKind TSK,
+                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
+                                         SourceLocation PointOfInstantiation);
+
+  /// \brief Specify that this record is an instantiation of the
+  /// member function FD.
+  void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
+                                        TemplateSpecializationKind TSK);
+
+  void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
+
+protected:
+  FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+               const DeclarationNameInfo &NameInfo,
+               QualType T, TypeSourceInfo *TInfo,
+               StorageClass S, bool isInlineSpecified,
+               bool isConstexprSpecified)
+    : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
+                     StartLoc),
+      DeclContext(DK),
+      redeclarable_base(C),
+      ParamInfo(nullptr), Body(),
+      SClass(S),
+      IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
+      IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
+      HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
+      IsDefaulted(false), IsExplicitlyDefaulted(false),
+      HasImplicitReturnZero(false), IsLateTemplateParsed(false),
+      IsConstexpr(isConstexprSpecified), HasSkippedBody(false),
+      EndRangeLoc(NameInfo.getEndLoc()),
+      TemplateOrSpecialization(),
+      DNLoc(NameInfo.getInfo()) {}
+
+  typedef Redeclarable<FunctionDecl> redeclarable_base;
+  FunctionDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  FunctionDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  FunctionDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+                              SourceLocation StartLoc, SourceLocation NLoc,
+                              DeclarationName N, QualType T,
+                              TypeSourceInfo *TInfo,
+                              StorageClass SC,
+                              bool isInlineSpecified = false,
+                              bool hasWrittenPrototype = true,
+                              bool isConstexprSpecified = false) {
+    DeclarationNameInfo NameInfo(N, NLoc);
+    return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
+                                SC,
+                                isInlineSpecified, hasWrittenPrototype,
+                                isConstexprSpecified);
+  }
+
+  static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
+                              SourceLocation StartLoc,
+                              const DeclarationNameInfo &NameInfo,
+                              QualType T, TypeSourceInfo *TInfo,
+                              StorageClass SC,
+                              bool isInlineSpecified,
+                              bool hasWrittenPrototype,
+                              bool isConstexprSpecified = false);
+
+  static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+                       
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
+
+  void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  /// \brief Returns true if the function has a body (definition). The
+  /// function body might be in any of the (re-)declarations of this
+  /// function. The variant that accepts a FunctionDecl pointer will
+  /// set that function declaration to the actual declaration
+  /// containing the body (if there is one).
+  bool hasBody(const FunctionDecl *&Definition) const;
+
+  bool hasBody() const override {
+    const FunctionDecl* Definition;
+    return hasBody(Definition);
+  }
+
+  /// hasTrivialBody - Returns whether the function has a trivial body that does
+  /// not require any specific codegen.
+  bool hasTrivialBody() const;
+
+  /// isDefined - Returns true if the function is defined at all, including
+  /// a deleted definition. Except for the behavior when the function is
+  /// deleted, behaves like hasBody.
+  bool isDefined(const FunctionDecl *&Definition) const;
+
+  virtual bool isDefined() const {
+    const FunctionDecl* Definition;
+    return isDefined(Definition);
+  }
+
+  /// getBody - Retrieve the body (definition) of the function. The
+  /// function body might be in any of the (re-)declarations of this
+  /// function. The variant that accepts a FunctionDecl pointer will
+  /// set that function declaration to the actual declaration
+  /// containing the body (if there is one).
+  /// NOTE: For checking if there is a body, use hasBody() instead, to avoid
+  /// unnecessary AST de-serialization of the body.
+  Stmt *getBody(const FunctionDecl *&Definition) const;
+
+   Stmt *getBody() const override {
+    const FunctionDecl* Definition;
+    return getBody(Definition);
+  }
+
+  /// isThisDeclarationADefinition - Returns whether this specific
+  /// declaration of the function is also a definition. This does not
+  /// determine whether the function has been defined (e.g., in a
+  /// previous definition); for that information, use isDefined. Note
+  /// that this returns false for a defaulted function unless that function
+  /// has been implicitly defined (possibly as deleted).
+  bool isThisDeclarationADefinition() const {
+    return IsDeleted || Body || IsLateTemplateParsed;
+  }
+
+  /// doesThisDeclarationHaveABody - Returns whether this specific
+  /// declaration of the function has a body - that is, if it is a non-
+  /// deleted definition.
+  bool doesThisDeclarationHaveABody() const {
+    return Body || IsLateTemplateParsed;
+  }
+
+  void setBody(Stmt *B);
+  void setLazyBody(uint64_t Offset) { Body = Offset; }
+
+  /// Whether this function is variadic.
+  bool isVariadic() const;
+
+  /// Whether this function is marked as virtual explicitly.
+  bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
+  void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
+
+  /// Whether this virtual function is pure, i.e. makes the containing class
+  /// abstract.
+  bool isPure() const { return IsPure; }
+  void setPure(bool P = true);
+
+  /// Whether this templated function will be late parsed.
+  bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
+  void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
+
+  /// Whether this function is "trivial" in some specialized C++ senses.
+  /// Can only be true for default constructors, copy constructors,
+  /// copy assignment operators, and destructors.  Not meaningful until
+  /// the class has been fully built by Sema.
+  bool isTrivial() const { return IsTrivial; }
+  void setTrivial(bool IT) { IsTrivial = IT; }
+
+  /// Whether this function is defaulted per C++0x. Only valid for
+  /// special member functions.
+  bool isDefaulted() const { return IsDefaulted; }
+  void setDefaulted(bool D = true) { IsDefaulted = D; }
+
+  /// Whether this function is explicitly defaulted per C++0x. Only valid
+  /// for special member functions.
+  bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; }
+  void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; }
+
+  /// Whether falling off this function implicitly returns null/zero.
+  /// If a more specific implicit return value is required, front-ends
+  /// should synthesize the appropriate return statements.
+  bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
+  void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
+
+  /// \brief Whether this function has a prototype, either because one
+  /// was explicitly written or because it was "inherited" by merging
+  /// a declaration without a prototype with a declaration that has a
+  /// prototype.
+  bool hasPrototype() const {
+    return HasWrittenPrototype || HasInheritedPrototype;
+  }
+
+  bool hasWrittenPrototype() const { return HasWrittenPrototype; }
+
+  /// \brief Whether this function inherited its prototype from a
+  /// previous declaration.
+  bool hasInheritedPrototype() const { return HasInheritedPrototype; }
+  void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; }
+
+  /// Whether this is a (C++11) constexpr function or constexpr constructor.
+  bool isConstexpr() const { return IsConstexpr; }
+  void setConstexpr(bool IC) { IsConstexpr = IC; }
+
+  /// \brief Whether this function has been deleted.
+  ///
+  /// A function that is "deleted" (via the C++0x "= delete" syntax)
+  /// acts like a normal function, except that it cannot actually be
+  /// called or have its address taken. Deleted functions are
+  /// typically used in C++ overload resolution to attract arguments
+  /// whose type or lvalue/rvalue-ness would permit the use of a
+  /// different overload that would behave incorrectly. For example,
+  /// one might use deleted functions to ban implicit conversion from
+  /// a floating-point number to an Integer type:
+  ///
+  /// @code
+  /// struct Integer {
+  ///   Integer(long); // construct from a long
+  ///   Integer(double) = delete; // no construction from float or double
+  ///   Integer(long double) = delete; // no construction from long double
+  /// };
+  /// @endcode
+  // If a function is deleted, its first declaration must be.
+  bool isDeleted() const { return getCanonicalDecl()->IsDeleted; }
+  bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
+  void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
+
+  /// \brief Determines whether this function is "main", which is the
+  /// entry point into an executable program.
+  bool isMain() const;
+
+  /// \brief Determines whether this function is a MSVCRT user defined entry
+  /// point.
+  bool isMSVCRTEntryPoint() const;
+
+  /// \brief Determines whether this operator new or delete is one
+  /// of the reserved global placement operators:
+  ///    void *operator new(size_t, void *);
+  ///    void *operator new[](size_t, void *);
+  ///    void operator delete(void *, void *);
+  ///    void operator delete[](void *, void *);
+  /// These functions have special behavior under [new.delete.placement]:
+  ///    These functions are reserved, a C++ program may not define
+  ///    functions that displace the versions in the Standard C++ library.
+  ///    The provisions of [basic.stc.dynamic] do not apply to these
+  ///    reserved placement forms of operator new and operator delete.
+  ///
+  /// This function must be an allocation or deallocation function.
+  bool isReservedGlobalPlacementOperator() const;
+
+  /// \brief Determines whether this function is one of the replaceable
+  /// global allocation functions:
+  ///    void *operator new(size_t);
+  ///    void *operator new(size_t, const std::nothrow_t &) noexcept;
+  ///    void *operator new[](size_t);
+  ///    void *operator new[](size_t, const std::nothrow_t &) noexcept;
+  ///    void operator delete(void *) noexcept;
+  ///    void operator delete(void *, std::size_t) noexcept;      [C++1y]
+  ///    void operator delete(void *, const std::nothrow_t &) noexcept;
+  ///    void operator delete[](void *) noexcept;
+  ///    void operator delete[](void *, std::size_t) noexcept;    [C++1y]
+  ///    void operator delete[](void *, const std::nothrow_t &) noexcept;
+  /// These functions have special behavior under C++1y [expr.new]:
+  ///    An implementation is allowed to omit a call to a replaceable global
+  ///    allocation function. [...]
+  bool isReplaceableGlobalAllocationFunction() const;
+
+  /// \brief Determine whether this function is a sized global deallocation
+  /// function in C++1y. If so, find and return the corresponding unsized
+  /// deallocation function.
+  FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const;
+
+  /// Compute the language linkage.
+  LanguageLinkage getLanguageLinkage() const;
+
+  /// \brief Determines whether this function is a function with
+  /// external, C linkage.
+  bool isExternC() const;
+
+  /// \brief Determines whether this function's context is, or is nested within,
+  /// a C++ extern "C" linkage spec.
+  bool isInExternCContext() const;
+
+  /// \brief Determines whether this function's context is, or is nested within,
+  /// a C++ extern "C++" linkage spec.
+  bool isInExternCXXContext() const;
+
+  /// \brief Determines whether this is a global function.
+  bool isGlobal() const;
+
+  /// \brief Determines whether this function is known to be 'noreturn', through
+  /// an attribute on its declaration or its type.
+  bool isNoReturn() const;
+
+  /// \brief True if the function was a definition but its body was skipped.
+  bool hasSkippedBody() const { return HasSkippedBody; }
+  void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+
+  void setPreviousDeclaration(FunctionDecl * PrevDecl);
+
+  virtual const FunctionDecl *getCanonicalDecl() const;
+  FunctionDecl *getCanonicalDecl() override;
+
+  unsigned getBuiltinID() const;
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return getNumParams(); }
+  typedef ParmVarDecl **param_iterator;
+  typedef ParmVarDecl * const *param_const_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+  param_iterator param_begin() { return param_iterator(ParamInfo); }
+  param_iterator param_end() {
+    return param_iterator(ParamInfo + param_size());
+  }
+  param_range params() { return param_range(param_begin(), param_end()); }
+
+  param_const_iterator param_begin() const {
+    return param_const_iterator(ParamInfo);
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(ParamInfo + param_size());
+  }
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
+
+  /// getNumParams - Return the number of parameters this function must have
+  /// based on its FunctionType.  This is the length of the ParamInfo array
+  /// after it has been created.
+  unsigned getNumParams() const;
+
+  const ParmVarDecl *getParamDecl(unsigned i) const {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
+    setParams(getASTContext(), NewParamInfo);
+  }
+
+  // ArrayRef iterface to parameters.
+  // FIXME: Should one day replace iterator interface.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(ParamInfo, getNumParams());
+  }
+
+  const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
+    return DeclsInPrototypeScope;
+  }
+  void setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls);
+
+  /// getMinRequiredArguments - Returns the minimum number of arguments
+  /// needed to call this function. This may be fewer than the number of
+  /// function parameters, if some of the parameters have default
+  /// arguments (in C++).
+  unsigned getMinRequiredArguments() const;
+
+  QualType getReturnType() const {
+    return getType()->getAs<FunctionType>()->getReturnType();
+  }
+
+  /// \brief Attempt to compute an informative source range covering the
+  /// function return type. This may omit qualifiers and other information with
+  /// limited representation in the AST.
+  SourceRange getReturnTypeSourceRange() const;
+
+  /// \brief Determine the type of an expression that calls this function.
+  QualType getCallResultType() const {
+    return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
+  }
+
+  /// \brief Returns the storage class as written in the source. For the
+  /// computed linkage of symbol, see getLinkage.
+  StorageClass getStorageClass() const { return StorageClass(SClass); }
+
+  /// \brief Determine whether the "inline" keyword was specified for this
+  /// function.
+  bool isInlineSpecified() const { return IsInlineSpecified; }
+
+  /// Set whether the "inline" keyword was specified for this function.
+  void setInlineSpecified(bool I) {
+    IsInlineSpecified = I;
+    IsInline = I;
+  }
+
+  /// Flag that this function is implicitly inline.
+  void setImplicitlyInline() {
+    IsInline = true;
+  }
+
+  /// \brief Determine whether this function should be inlined, because it is
+  /// either marked "inline" or "constexpr" or is a member function of a class
+  /// that was defined in the class body.
+  bool isInlined() const { return IsInline; }
+
+  bool isInlineDefinitionExternallyVisible() const;
+
+  bool isMSExternInline() const;
+
+  bool doesDeclarationForceExternallyVisibleDefinition() const;
+
+  /// isOverloadedOperator - Whether this function declaration
+  /// represents an C++ overloaded operator, e.g., "operator+".
+  bool isOverloadedOperator() const {
+    return getOverloadedOperator() != OO_None;
+  }
+
+  OverloadedOperatorKind getOverloadedOperator() const;
+
+  const IdentifierInfo *getLiteralIdentifier() const;
+
+  /// \brief If this function is an instantiation of a member function
+  /// of a class template specialization, retrieves the function from
+  /// which it was instantiated.
+  ///
+  /// This routine will return non-NULL for (non-templated) member
+  /// functions of class templates and for instantiations of function
+  /// templates. For example, given:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   void f(T);
+  /// };
+  /// \endcode
+  ///
+  /// The declaration for X<int>::f is a (non-templated) FunctionDecl
+  /// whose parent is the class template specialization X<int>. For
+  /// this declaration, getInstantiatedFromFunction() will return
+  /// the FunctionDecl X<T>::A. When a complete definition of
+  /// X<int>::A is required, it will be instantiated from the
+  /// declaration returned by getInstantiatedFromMemberFunction().
+  FunctionDecl *getInstantiatedFromMemberFunction() const;
+
+  /// \brief What kind of templated function this is.
+  TemplatedKind getTemplatedKind() const;
+
+  /// \brief If this function is an instantiation of a member function of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const {
+    return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
+  }
+
+  /// \brief Specify that this record is an instantiation of the
+  /// member function FD.
+  void setInstantiationOfMemberFunction(FunctionDecl *FD,
+                                        TemplateSpecializationKind TSK) {
+    setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
+  }
+
+  /// \brief Retrieves the function template that is described by this
+  /// function declaration.
+  ///
+  /// Every function template is represented as a FunctionTemplateDecl
+  /// and a FunctionDecl (or something derived from FunctionDecl). The
+  /// former contains template properties (such as the template
+  /// parameter lists) while the latter contains the actual
+  /// description of the template's
+  /// contents. FunctionTemplateDecl::getTemplatedDecl() retrieves the
+  /// FunctionDecl that describes the function template,
+  /// getDescribedFunctionTemplate() retrieves the
+  /// FunctionTemplateDecl from a FunctionDecl.
+  FunctionTemplateDecl *getDescribedFunctionTemplate() const {
+    return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>();
+  }
+
+  void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+    TemplateOrSpecialization = Template;
+  }
+
+  /// \brief Determine whether this function is a function template
+  /// specialization.
+  bool isFunctionTemplateSpecialization() const {
+    return getPrimaryTemplate() != nullptr;
+  }
+
+  /// \brief Retrieve the class scope template pattern that this function
+  ///  template specialization is instantiated from.
+  FunctionDecl *getClassScopeSpecializationPattern() const;
+
+  /// \brief If this function is actually a function template specialization,
+  /// retrieve information about this function template specialization.
+  /// Otherwise, returns NULL.
+  FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const {
+    return TemplateOrSpecialization.
+             dyn_cast<FunctionTemplateSpecializationInfo*>();
+  }
+
+  /// \brief Determines whether this function is a function template
+  /// specialization or a member of a class template specialization that can
+  /// be implicitly instantiated.
+  bool isImplicitlyInstantiable() const;
+
+  /// \brief Determines if the given function was instantiated from a
+  /// function template.
+  bool isTemplateInstantiation() const;
+
+  /// \brief Retrieve the function declaration from which this function could
+  /// be instantiated, if it is an instantiation (rather than a non-template
+  /// or a specialization, for example).
+  FunctionDecl *getTemplateInstantiationPattern() const;
+
+  /// \brief Retrieve the primary template that this function template
+  /// specialization either specializes or was instantiated from.
+  ///
+  /// If this function declaration is not a function template specialization,
+  /// returns NULL.
+  FunctionTemplateDecl *getPrimaryTemplate() const;
+
+  /// \brief Retrieve the template arguments used to produce this function
+  /// template specialization from the primary template.
+  ///
+  /// If this function declaration is not a function template specialization,
+  /// returns NULL.
+  const TemplateArgumentList *getTemplateSpecializationArgs() const;
+
+  /// \brief Retrieve the template argument list as written in the sources,
+  /// if any.
+  ///
+  /// If this function declaration is not a function template specialization
+  /// or if it had no explicit template argument list, returns NULL.
+  /// Note that it an explicit template argument list may be written empty,
+  /// e.g., template<> void foo<>(char* s);
+  const ASTTemplateArgumentListInfo*
+  getTemplateSpecializationArgsAsWritten() const;
+
+  /// \brief Specify that this function declaration is actually a function
+  /// template specialization.
+  ///
+  /// \param Template the function template that this function template
+  /// specialization specializes.
+  ///
+  /// \param TemplateArgs the template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param InsertPos If non-NULL, the position in the function template
+  /// specialization set where the function template specialization data will
+  /// be inserted.
+  ///
+  /// \param TSK the kind of template specialization this is.
+  ///
+  /// \param TemplateArgsAsWritten location info of template arguments.
+  ///
+  /// \param PointOfInstantiation point at which the function template
+  /// specialization was first instantiated.
+  void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+                const TemplateArgumentList *TemplateArgs,
+                void *InsertPos,
+                TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+                const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
+                SourceLocation PointOfInstantiation = SourceLocation()) {
+    setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
+                                      InsertPos, TSK, TemplateArgsAsWritten,
+                                      PointOfInstantiation);
+  }
+
+  /// \brief Specifies that this function declaration is actually a
+  /// dependent function template specialization.
+  void setDependentTemplateSpecialization(ASTContext &Context,
+                             const UnresolvedSetImpl &Templates,
+                      const TemplateArgumentListInfo &TemplateArgs);
+
+  DependentFunctionTemplateSpecializationInfo *
+  getDependentSpecializationInfo() const {
+    return TemplateOrSpecialization.
+             dyn_cast<DependentFunctionTemplateSpecializationInfo*>();
+  }
+
+  /// \brief Determine what kind of template instantiation this function
+  /// represents.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+
+  /// \brief Determine what kind of template instantiation this function
+  /// represents.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  /// \brief Retrieve the (first) point of instantiation of a function template
+  /// specialization or a member of a class template specialization.
+  ///
+  /// \returns the first point of instantiation, if this function was
+  /// instantiated from a template; otherwise, returns an invalid source
+  /// location.
+  SourceLocation getPointOfInstantiation() const;
+
+  /// \brief Determine whether this is or was instantiated from an out-of-line
+  /// definition of a member function.
+  bool isOutOfLine() const override;
+
+  /// \brief Identify a memory copying or setting function.
+  /// If the given function is a memory copy or setting function, returns
+  /// the corresponding Builtin ID. If the function is not a memory function,
+  /// returns 0.
+  unsigned getMemoryFunctionKind() const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstFunction && K <= lastFunction;
+  }
+  static DeclContext *castToDeclContext(const FunctionDecl *D) {
+    return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
+  }
+  static FunctionDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC));
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+
+/// FieldDecl - An instance of this class is created by Sema::ActOnField to
+/// represent a member of a struct/union/class.
+class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
+  // FIXME: This can be packed into the bitfields in Decl.
+  bool Mutable : 1;
+  mutable unsigned CachedFieldIndex : 31;
+
+  /// \brief An InClassInitStyle value, and either a bit width expression (if
+  /// the InClassInitStyle value is ICIS_NoInit), or a pointer to the in-class
+  /// initializer for this field (otherwise).
+  ///
+  /// We can safely combine these two because in-class initializers are not
+  /// permitted for bit-fields.
+  ///
+  /// If the InClassInitStyle is not ICIS_NoInit and the initializer is null,
+  /// then this field has an in-class initializer which has not yet been parsed
+  /// and attached.
+  llvm::PointerIntPair<Expr *, 2, unsigned> InitializerOrBitWidth;
+protected:
+  FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+            SourceLocation IdLoc, IdentifierInfo *Id,
+            QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+            InClassInitStyle InitStyle)
+    : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
+      Mutable(Mutable), CachedFieldIndex(0),
+      InitializerOrBitWidth(BW, InitStyle) {
+    assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield");
+  }
+
+public:
+  static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
+                           SourceLocation StartLoc, SourceLocation IdLoc,
+                           IdentifierInfo *Id, QualType T,
+                           TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+                           InClassInitStyle InitStyle);
+
+  static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  /// getFieldIndex - Returns the index of this field within its record,
+  /// as appropriate for passing to ASTRecordLayout::getFieldOffset.
+  unsigned getFieldIndex() const;
+
+  /// isMutable - Determines whether this field is mutable (C++ only).
+  bool isMutable() const { return Mutable; }
+
+  /// isBitfield - Determines whether this field is a bitfield.
+  bool isBitField() const {
+    return getInClassInitStyle() == ICIS_NoInit &&
+           InitializerOrBitWidth.getPointer();
+  }
+
+  /// @brief Determines whether this is an unnamed bitfield.
+  bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
+
+  /// isAnonymousStructOrUnion - Determines whether this field is a
+  /// representative for an anonymous struct or union. Such fields are
+  /// unnamed and are implicitly generated by the implementation to
+  /// store the data for the anonymous union or struct.
+  bool isAnonymousStructOrUnion() const;
+
+  Expr *getBitWidth() const {
+    return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
+  }
+  unsigned getBitWidthValue(const ASTContext &Ctx) const;
+
+  /// setBitWidth - Set the bit-field width for this member.
+  // Note: used by some clients (i.e., do not remove it).
+  void setBitWidth(Expr *Width);
+  /// removeBitWidth - Remove the bit-field width from this member.
+  // Note: used by some clients (i.e., do not remove it).
+  void removeBitWidth() {
+    assert(isBitField() && "no bitfield width to remove");
+    InitializerOrBitWidth.setPointer(nullptr);
+  }
+
+  /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
+  /// this field has.
+  InClassInitStyle getInClassInitStyle() const {
+    return static_cast<InClassInitStyle>(InitializerOrBitWidth.getInt());
+  }
+
+  /// hasInClassInitializer - Determine whether this member has a C++11 in-class
+  /// initializer.
+  bool hasInClassInitializer() const {
+    return getInClassInitStyle() != ICIS_NoInit;
+  }
+  /// getInClassInitializer - Get the C++11 in-class initializer for this
+  /// member, or null if one has not been set. If a valid declaration has an
+  /// in-class initializer, but this returns null, then we have not parsed and
+  /// attached it yet.
+  Expr *getInClassInitializer() const {
+    return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
+                                   : nullptr;
+  }
+  /// setInClassInitializer - Set the C++11 in-class initializer for this
+  /// member.
+  void setInClassInitializer(Expr *Init);
+  /// removeInClassInitializer - Remove the C++11 in-class initializer from this
+  /// member.
+  void removeInClassInitializer() {
+    assert(hasInClassInitializer() && "no initializer to remove");
+    InitializerOrBitWidth.setPointer(nullptr);
+    InitializerOrBitWidth.setInt(ICIS_NoInit);
+  }
+
+  /// getParent - Returns the parent of this field declaration, which
+  /// is the struct in which this method is defined.
+  const RecordDecl *getParent() const {
+    return cast<RecordDecl>(getDeclContext());
+  }
+
+  RecordDecl *getParent() {
+    return cast<RecordDecl>(getDeclContext());
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  /// Retrieves the canonical declaration of this field.
+  FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// EnumConstantDecl - An instance of this object exists for each enum constant
+/// that is defined.  For example, in "enum X {a,b}", each of a/b are
+/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
+/// TagType for the X EnumDecl.
+class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
+  Stmt *Init; // an integer constant expression
+  llvm::APSInt Val; // The value.
+protected:
+  EnumConstantDecl(DeclContext *DC, SourceLocation L,
+                   IdentifierInfo *Id, QualType T, Expr *E,
+                   const llvm::APSInt &V)
+    : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
+
+public:
+
+  static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC,
+                                  SourceLocation L, IdentifierInfo *Id,
+                                  QualType T, Expr *E,
+                                  const llvm::APSInt &V);
+  static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  const Expr *getInitExpr() const { return (const Expr*) Init; }
+  Expr *getInitExpr() { return (Expr*) Init; }
+  const llvm::APSInt &getInitVal() const { return Val; }
+
+  void setInitExpr(Expr *E) { Init = (Stmt*) E; }
+  void setInitVal(const llvm::APSInt &V) { Val = V; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  /// Retrieves the canonical declaration of this enumerator.
+  EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == EnumConstant; }
+
+  friend class StmtIteratorBase;
+};
+
+/// IndirectFieldDecl - An instance of this class is created to represent a
+/// field injected from an anonymous union/struct into the parent scope.
+/// IndirectFieldDecl are always implicit.
+class IndirectFieldDecl : public ValueDecl {
+  void anchor() override;
+  NamedDecl **Chaining;
+  unsigned ChainingSize;
+
+  IndirectFieldDecl(DeclContext *DC, SourceLocation L,
+                    DeclarationName N, QualType T,
+                    NamedDecl **CH, unsigned CHS)
+    : ValueDecl(IndirectField, DC, L, N, T), Chaining(CH), ChainingSize(CHS) {}
+
+public:
+  static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation L, IdentifierInfo *Id,
+                                   QualType T, NamedDecl **CH, unsigned CHS);
+
+  static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  typedef NamedDecl * const *chain_iterator;
+  typedef llvm::iterator_range<chain_iterator> chain_range;
+
+  chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
+  chain_iterator chain_begin() const { return chain_iterator(Chaining); }
+  chain_iterator chain_end() const {
+    return chain_iterator(Chaining + ChainingSize);
+  }
+
+  unsigned getChainingSize() const { return ChainingSize; }
+
+  FieldDecl *getAnonField() const {
+    assert(ChainingSize >= 2);
+    return cast<FieldDecl>(Chaining[ChainingSize - 1]);
+  }
+
+  VarDecl *getVarDecl() const {
+    assert(ChainingSize >= 2);
+    return dyn_cast<VarDecl>(*chain_begin());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == IndirectField; }
+  friend class ASTDeclReader;
+};
+
+/// TypeDecl - Represents a declaration of a type.
+///
+class TypeDecl : public NamedDecl {
+  void anchor() override;
+  /// TypeForDecl - This indicates the Type object that represents
+  /// this TypeDecl.  It is a cache maintained by
+  /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
+  /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
+  mutable const Type *TypeForDecl;
+  /// LocStart - The start of the source range for this declaration.
+  SourceLocation LocStart;
+  friend class ASTContext;
+
+protected:
+  TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+           SourceLocation StartL = SourceLocation())
+    : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
+
+public:
+  // Low-level accessor. If you just want the type defined by this node,
+  // check out ASTContext::getTypeDeclType or one of
+  // ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you
+  // already know the specific kind of node this is.
+  const Type *getTypeForDecl() const { return TypeForDecl; }
+  void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
+  void setLocStart(SourceLocation L) { LocStart = L; }
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    if (LocStart.isValid())
+      return SourceRange(LocStart, getLocation());
+    else
+      return SourceRange(getLocation());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstType && K <= lastType; }
+};
+
+
+/// Base class for declarations which introduce a typedef-name.
+class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
+  void anchor() override;
+  typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
+  llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
+
+protected:
+  TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                  SourceLocation StartLoc, SourceLocation IdLoc,
+                  IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
+        MaybeModedTInfo(TInfo) {}
+
+  typedef Redeclarable<TypedefNameDecl> redeclarable_base;
+  TypedefNameDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  TypedefNameDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  TypedefNameDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return isModed()
+      ? MaybeModedTInfo.get<ModedTInfo*>()->first
+      : MaybeModedTInfo.get<TypeSourceInfo*>();
+  }
+  QualType getUnderlyingType() const {
+    return isModed()
+      ? MaybeModedTInfo.get<ModedTInfo*>()->second
+      : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
+  }
+  void setTypeSourceInfo(TypeSourceInfo *newType) {
+    MaybeModedTInfo = newType;
+  }
+  void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
+    MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
+  }
+
+  /// Retrieves the canonical declaration of this typedef-name.
+  TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstTypedefName && K <= lastTypedefName;
+  }
+};
+
+/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
+/// type specifier.
+class TypedefDecl : public TypedefNameDecl {
+  TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+              SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+  static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             IdentifierInfo *Id, TypeSourceInfo *TInfo);
+  static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Typedef; }
+};
+
+/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
+/// alias-declaration.
+class TypeAliasDecl : public TypedefNameDecl {
+  TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+                SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
+
+public:
+  static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation StartLoc, SourceLocation IdLoc,
+                               IdentifierInfo *Id, TypeSourceInfo *TInfo);
+  static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == TypeAlias; }
+};
+
+/// TagDecl - Represents the declaration of a struct/union/class/enum.
+class TagDecl
+  : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
+public:
+  // This is really ugly.
+  typedef TagTypeKind TagKind;
+
+private:
+  // FIXME: This can be packed into the bitfields in Decl.
+  /// TagDeclKind - The TagKind enum.
+  unsigned TagDeclKind : 3;
+
+  /// IsCompleteDefinition - True if this is a definition ("struct foo
+  /// {};"), false if it is a declaration ("struct foo;").  It is not
+  /// a definition until the definition has been fully processed.
+  bool IsCompleteDefinition : 1;
+
+protected:
+  /// IsBeingDefined - True if this is currently being defined.
+  bool IsBeingDefined : 1;
+
+private:
+  /// IsEmbeddedInDeclarator - True if this tag declaration is
+  /// "embedded" (i.e., defined or declared for the very first time)
+  /// in the syntax of a declarator.
+  bool IsEmbeddedInDeclarator : 1;
+
+  /// \brief True if this tag is free standing, e.g. "struct foo;".
+  bool IsFreeStanding : 1;
+
+protected:
+  // These are used by (and only defined for) EnumDecl.
+  unsigned NumPositiveBits : 8;
+  unsigned NumNegativeBits : 8;
+
+  /// IsScoped - True if this tag declaration is a scoped enumeration. Only
+  /// possible in C++11 mode.
+  bool IsScoped : 1;
+  /// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
+  /// then this is true if the scoped enum was declared using the class
+  /// tag, false if it was declared with the struct tag. No meaning is
+  /// associated if this tag declaration is not a scoped enum.
+  bool IsScopedUsingClassTag : 1;
+
+  /// IsFixed - True if this is an enumeration with fixed underlying type. Only
+  /// possible in C++11, Microsoft extensions, or Objective C mode.
+  bool IsFixed : 1;
+
+  /// \brief Indicates whether it is possible for declarations of this kind
+  /// to have an out-of-date definition.
+  ///
+  /// This option is only enabled when modules are enabled.
+  bool MayHaveOutOfDateDef : 1;
+
+  /// Has the full definition of this type been required by a use somewhere in
+  /// the TU.
+  bool IsCompleteDefinitionRequired : 1;
+private:
+  SourceLocation RBraceLoc;
+
+  // A struct representing syntactic qualifier info,
+  // to be used for the (uncommon) case of out-of-line declarations.
+  typedef QualifierInfo ExtInfo;
+
+  /// \brief If the (out-of-line) tag declaration name
+  /// is qualified, it points to the qualifier info (nns and range);
+  /// otherwise, if the tag declaration is anonymous and it is part of
+  /// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
+  /// otherwise, if the tag declaration is anonymous and it is used as a
+  /// declaration specifier for variables, it points to the first VarDecl (used
+  /// for mangling);
+  /// otherwise, it is a null (TypedefNameDecl) pointer.
+  llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier;
+
+  bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); }
+  ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); }
+  const ExtInfo *getExtInfo() const {
+    return NamedDeclOrQualifier.get<ExtInfo *>();
+  }
+
+protected:
+  TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+          SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
+          SourceLocation StartL)
+      : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
+        TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
+        IsEmbeddedInDeclarator(false), IsFreeStanding(false),
+        IsCompleteDefinitionRequired(false),
+        NamedDeclOrQualifier((NamedDecl *)nullptr) {
+    assert((DK != Enum || TK == TTK_Enum) &&
+           "EnumDecl not matched with TTK_Enum");
+    setPreviousDecl(PrevDecl);
+  }
+
+  typedef Redeclarable<TagDecl> redeclarable_base;
+  TagDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  TagDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  TagDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+  /// @brief Completes the definition of this tag declaration.
+  ///
+  /// This is a helper function for derived classes.
+  void completeDefinition();
+
+public:
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+
+  /// getInnerLocStart - Return SourceLocation representing start of source
+  /// range ignoring outer template declarations.
+  SourceLocation getInnerLocStart() const { return getLocStart(); }
+
+  /// getOuterLocStart - Return SourceLocation representing start of source
+  /// range taking into account any outer template declarations.
+  SourceLocation getOuterLocStart() const;
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  TagDecl *getCanonicalDecl() override;
+  const TagDecl *getCanonicalDecl() const {
+    return const_cast<TagDecl*>(this)->getCanonicalDecl();
+  }
+
+  /// isThisDeclarationADefinition() - Return true if this declaration
+  /// is a completion definintion of the type.  Provided for consistency.
+  bool isThisDeclarationADefinition() const {
+    return isCompleteDefinition();
+  }
+
+  /// isCompleteDefinition - Return true if this decl has its body
+  /// fully specified.
+  bool isCompleteDefinition() const {
+    return IsCompleteDefinition;
+  }
+
+  /// \brief Return true if this complete decl is
+  /// required to be complete for some existing use.
+  bool isCompleteDefinitionRequired() const {
+    return IsCompleteDefinitionRequired;
+  }
+
+  /// isBeingDefined - Return true if this decl is currently being defined.
+  bool isBeingDefined() const {
+    return IsBeingDefined;
+  }
+
+  bool isEmbeddedInDeclarator() const {
+    return IsEmbeddedInDeclarator;
+  }
+  void setEmbeddedInDeclarator(bool isInDeclarator) {
+    IsEmbeddedInDeclarator = isInDeclarator;
+  }
+
+  bool isFreeStanding() const { return IsFreeStanding; }
+  void setFreeStanding(bool isFreeStanding = true) {
+    IsFreeStanding = isFreeStanding;
+  }
+
+  /// \brief Whether this declaration declares a type that is
+  /// dependent, i.e., a type that somehow depends on template
+  /// parameters.
+  bool isDependentType() const { return isDependentContext(); }
+
+  /// @brief Starts the definition of this tag declaration.
+  ///
+  /// This method should be invoked at the beginning of the definition
+  /// of this tag declaration. It will set the tag type into a state
+  /// where it is in the process of being defined.
+  void startDefinition();
+
+  /// getDefinition - Returns the TagDecl that actually defines this
+  ///  struct/union/class/enum.  When determining whether or not a
+  ///  struct/union/class/enum has a definition, one should use this
+  ///  method as opposed to 'isDefinition'.  'isDefinition' indicates
+  ///  whether or not a specific TagDecl is defining declaration, not
+  ///  whether or not the struct/union/class/enum type is defined.
+  ///  This method returns NULL if there is no TagDecl that defines
+  ///  the struct/union/class/enum.
+  TagDecl *getDefinition() const;
+
+  void setCompleteDefinition(bool V) { IsCompleteDefinition = V; }
+
+  void setCompleteDefinitionRequired(bool V = true) {
+    IsCompleteDefinitionRequired = V;
+  }
+
+  StringRef getKindName() const {
+    return TypeWithKeyword::getTagTypeKindName(getTagKind());
+  }
+
+  TagKind getTagKind() const {
+    return TagKind(TagDeclKind);
+  }
+
+  void setTagKind(TagKind TK) { TagDeclKind = TK; }
+
+  bool isStruct() const { return getTagKind() == TTK_Struct; }
+  bool isInterface() const { return getTagKind() == TTK_Interface; }
+  bool isClass()  const { return getTagKind() == TTK_Class; }
+  bool isUnion()  const { return getTagKind() == TTK_Union; }
+  bool isEnum()   const { return getTagKind() == TTK_Enum; }
+
+  /// Is this tag type named, either directly or via being defined in
+  /// a typedef of this type?
+  ///
+  /// C++11 [basic.link]p8:
+  ///   A type is said to have linkage if and only if:
+  ///     - it is a class or enumeration type that is named (or has a
+  ///       name for linkage purposes) and the name has linkage; ...
+  /// C++11 [dcl.typedef]p9:
+  ///   If the typedef declaration defines an unnamed class (or enum),
+  ///   the first typedef-name declared by the declaration to be that
+  ///   class type (or enum type) is used to denote the class type (or
+  ///   enum type) for linkage purposes only.
+  ///
+  /// C does not have an analogous rule, but the same concept is
+  /// nonetheless useful in some places.
+  bool hasNameForLinkage() const {
+    return (getDeclName() || getTypedefNameForAnonDecl());
+  }
+
+  bool hasDeclaratorForAnonDecl() const {
+    return dyn_cast_or_null<DeclaratorDecl>(
+        NamedDeclOrQualifier.get<NamedDecl *>());
+  }
+  DeclaratorDecl *getDeclaratorForAnonDecl() const {
+    return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>(
+                                  NamedDeclOrQualifier.get<NamedDecl *>());
+  }
+
+  TypedefNameDecl *getTypedefNameForAnonDecl() const {
+    return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>(
+                                  NamedDeclOrQualifier.get<NamedDecl *>());
+  }
+
+  void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; }
+
+  void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+  /// declaration, if it was present in the source.
+  NestedNameSpecifier *getQualifier() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
+                        : nullptr;
+  }
+
+  /// \brief Retrieve the nested-name-specifier (with source-location
+  /// information) that qualifies the name of this declaration, if it was
+  /// present in the source.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc
+                        : NestedNameSpecifierLoc();
+  }
+
+  void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
+
+  unsigned getNumTemplateParameterLists() const {
+    return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
+  }
+  TemplateParameterList *getTemplateParameterList(unsigned i) const {
+    assert(i < getNumTemplateParameterLists());
+    return getExtInfo()->TemplParamLists[i];
+  }
+  void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
+                                     TemplateParameterList **TPLists);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K >= firstTag && K <= lastTag; }
+
+  static DeclContext *castToDeclContext(const TagDecl *D) {
+    return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
+  }
+  static TagDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// EnumDecl - Represents an enum.  In C++11, enums can be forward-declared
+/// with a fixed underlying type, and in C we allow them to be forward-declared
+/// with no underlying type as an extension.
+class EnumDecl : public TagDecl {
+  void anchor() override;
+  /// IntegerType - This represent the integer type that the enum corresponds
+  /// to for code generation purposes.  Note that the enumerator constants may
+  /// have a different type than this does.
+  ///
+  /// If the underlying integer type was explicitly stated in the source
+  /// code, this is a TypeSourceInfo* for that type. Otherwise this type
+  /// was automatically deduced somehow, and this is a Type*.
+  ///
+  /// Normally if IsFixed(), this would contain a TypeSourceInfo*, but in
+  /// some cases it won't.
+  ///
+  /// The underlying type of an enumeration never has any qualifiers, so
+  /// we can get away with just storing a raw Type*, and thus save an
+  /// extra pointer when TypeSourceInfo is needed.
+
+  llvm::PointerUnion<const Type*, TypeSourceInfo*> IntegerType;
+
+  /// PromotionType - The integer type that values of this type should
+  /// promote to.  In C, enumerators are generally of an integer type
+  /// directly, but gcc-style large enumerators (and all enumerators
+  /// in C++) are of the enum type instead.
+  QualType PromotionType;
+
+  /// \brief If this enumeration is an instantiation of a member enumeration
+  /// of a class template specialization, this is the member specialization
+  /// information.
+  MemberSpecializationInfo *SpecializationInfo;
+
+  EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+           SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
+           bool Scoped, bool ScopedUsingClassTag, bool Fixed)
+      : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+        SpecializationInfo(nullptr) {
+    assert(Scoped || !ScopedUsingClassTag);
+    IntegerType = (const Type *)nullptr;
+    NumNegativeBits = 0;
+    NumPositiveBits = 0;
+    IsScoped = Scoped;
+    IsScopedUsingClassTag = ScopedUsingClassTag;
+    IsFixed = Fixed;
+  }
+
+  void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
+                                    TemplateSpecializationKind TSK);
+public:
+  EnumDecl *getCanonicalDecl() override {
+    return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+  }
+  const EnumDecl *getCanonicalDecl() const {
+    return const_cast<EnumDecl*>(this)->getCanonicalDecl();
+  }
+
+  EnumDecl *getPreviousDecl() {
+    return cast_or_null<EnumDecl>(
+            static_cast<TagDecl *>(this)->getPreviousDecl());
+  }
+  const EnumDecl *getPreviousDecl() const {
+    return const_cast<EnumDecl*>(this)->getPreviousDecl();
+  }
+
+  EnumDecl *getMostRecentDecl() {
+    return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
+  }
+  const EnumDecl *getMostRecentDecl() const {
+    return const_cast<EnumDecl*>(this)->getMostRecentDecl();
+  }
+
+  EnumDecl *getDefinition() const {
+    return cast_or_null<EnumDecl>(TagDecl::getDefinition());
+  }
+
+  static EnumDecl *Create(ASTContext &C, DeclContext *DC,
+                          SourceLocation StartLoc, SourceLocation IdLoc,
+                          IdentifierInfo *Id, EnumDecl *PrevDecl,
+                          bool IsScoped, bool IsScopedUsingClassTag,
+                          bool IsFixed);
+  static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// completeDefinition - When created, the EnumDecl corresponds to a
+  /// forward-declared enum. This method is used to mark the
+  /// declaration as being defined; it's enumerators have already been
+  /// added (via DeclContext::addDecl). NewType is the new underlying
+  /// type of the enumeration type.
+  void completeDefinition(QualType NewType,
+                          QualType PromotionType,
+                          unsigned NumPositiveBits,
+                          unsigned NumNegativeBits);
+
+  // enumerator_iterator - Iterates through the enumerators of this
+  // enumeration.
+  typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
+    enumerator_range;
+
+  enumerator_range enumerators() const {
+    return enumerator_range(enumerator_begin(), enumerator_end());
+  }
+
+  enumerator_iterator enumerator_begin() const {
+    const EnumDecl *E = getDefinition();
+    if (!E)
+      E = this;
+    return enumerator_iterator(E->decls_begin());
+  }
+
+  enumerator_iterator enumerator_end() const {
+    const EnumDecl *E = getDefinition();
+    if (!E)
+      E = this;
+    return enumerator_iterator(E->decls_end());
+  }
+
+  /// getPromotionType - Return the integer type that enumerators
+  /// should promote to.
+  QualType getPromotionType() const { return PromotionType; }
+
+  /// \brief Set the promotion type.
+  void setPromotionType(QualType T) { PromotionType = T; }
+
+  /// getIntegerType - Return the integer type this enum decl corresponds to.
+  /// This returns a null QualType for an enum forward definition with no fixed
+  /// underlying type.
+  QualType getIntegerType() const {
+    if (!IntegerType)
+      return QualType();
+    if (const Type *T = IntegerType.dyn_cast<const Type*>())
+      return QualType(T, 0);
+    return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
+  }
+
+  /// \brief Set the underlying integer type.
+  void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
+
+  /// \brief Set the underlying integer type source info.
+  void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
+
+  /// \brief Return the type source info for the underlying integer type,
+  /// if no type source info exists, return 0.
+  TypeSourceInfo *getIntegerTypeSourceInfo() const {
+    return IntegerType.dyn_cast<TypeSourceInfo*>();
+  }
+
+  /// \brief Retrieve the source range that covers the underlying type if
+  /// specified.
+  SourceRange getIntegerTypeRange() const LLVM_READONLY;
+
+  /// \brief Returns the width in bits required to store all the
+  /// non-negative enumerators of this enum.
+  unsigned getNumPositiveBits() const {
+    return NumPositiveBits;
+  }
+  void setNumPositiveBits(unsigned Num) {
+    NumPositiveBits = Num;
+    assert(NumPositiveBits == Num && "can't store this bitcount");
+  }
+
+  /// \brief Returns the width in bits required to store all the
+  /// negative enumerators of this enum.  These widths include
+  /// the rightmost leading 1;  that is:
+  ///
+  /// MOST NEGATIVE ENUMERATOR     PATTERN     NUM NEGATIVE BITS
+  /// ------------------------     -------     -----------------
+  ///                       -1     1111111                     1
+  ///                      -10     1110110                     5
+  ///                     -101     1001011                     8
+  unsigned getNumNegativeBits() const {
+    return NumNegativeBits;
+  }
+  void setNumNegativeBits(unsigned Num) {
+    NumNegativeBits = Num;
+  }
+
+  /// \brief Returns true if this is a C++11 scoped enumeration.
+  bool isScoped() const {
+    return IsScoped;
+  }
+
+  /// \brief Returns true if this is a C++11 scoped enumeration.
+  bool isScopedUsingClassTag() const {
+    return IsScopedUsingClassTag;
+  }
+
+  /// \brief Returns true if this is an Objective-C, C++11, or
+  /// Microsoft-style enumeration with a fixed underlying type.
+  bool isFixed() const {
+    return IsFixed;
+  }
+
+  /// \brief Returns true if this can be considered a complete type.
+  bool isComplete() const {
+    return isCompleteDefinition() || isFixed();
+  }
+
+  /// \brief Returns the enumeration (declared within the template)
+  /// from which this enumeration type was instantiated, or NULL if
+  /// this enumeration was not instantiated from any template.
+  EnumDecl *getInstantiatedFromMemberEnum() const;
+
+  /// \brief If this enumeration is a member of a specialization of a
+  /// templated class, determine what kind of template specialization
+  /// or instantiation this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+
+  /// \brief For an enumeration member that was instantiated from a member
+  /// enumeration of a templated class, set the template specialiation kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+                        SourceLocation PointOfInstantiation = SourceLocation());
+
+  /// \brief If this enumeration is an instantiation of a member enumeration of
+  /// a class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const {
+    return SpecializationInfo;
+  }
+
+  /// \brief Specify that this enumeration is an instantiation of the
+  /// member enumeration ED.
+  void setInstantiationOfMemberEnum(EnumDecl *ED,
+                                    TemplateSpecializationKind TSK) {
+    setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Enum; }
+
+  friend class ASTDeclReader;
+};
+
+
+/// RecordDecl - Represents a struct/union/class.  For example:
+///   struct X;                  // Forward declaration, no "body".
+///   union Y { int A, B; };     // Has body with members A and B (FieldDecls).
+/// This decl will be marked invalid if *any* members are invalid.
+///
+class RecordDecl : public TagDecl {
+  // FIXME: This can be packed into the bitfields in Decl.
+  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
+  /// array member (e.g. int X[]) or if this union contains a struct that does.
+  /// If so, this cannot be contained in arrays or other structs as a member.
+  bool HasFlexibleArrayMember : 1;
+
+  /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
+  /// or union.
+  bool AnonymousStructOrUnion : 1;
+
+  /// HasObjectMember - This is true if this struct has at least one member
+  /// containing an Objective-C object pointer type.
+  bool HasObjectMember : 1;
+  
+  /// HasVolatileMember - This is true if struct has at least one member of
+  /// 'volatile' type.
+  bool HasVolatileMember : 1;
+
+  /// \brief Whether the field declarations of this record have been loaded
+  /// from external storage. To avoid unnecessary deserialization of
+  /// methods/nested types we allow deserialization of just the fields
+  /// when needed.
+  mutable bool LoadedFieldsFromExternalStorage : 1;
+  friend class DeclContext;
+
+protected:
+  RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+             SourceLocation StartLoc, SourceLocation IdLoc,
+             IdentifierInfo *Id, RecordDecl *PrevDecl);
+
+public:
+  static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
+                            SourceLocation StartLoc, SourceLocation IdLoc,
+                            IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
+  static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
+
+  RecordDecl *getPreviousDecl() {
+    return cast_or_null<RecordDecl>(
+            static_cast<TagDecl *>(this)->getPreviousDecl());
+  }
+  const RecordDecl *getPreviousDecl() const {
+    return const_cast<RecordDecl*>(this)->getPreviousDecl();
+  }
+
+  RecordDecl *getMostRecentDecl() {
+    return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
+  }
+  const RecordDecl *getMostRecentDecl() const {
+    return const_cast<RecordDecl*>(this)->getMostRecentDecl();
+  }
+
+  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
+  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
+
+  /// isAnonymousStructOrUnion - Whether this is an anonymous struct
+  /// or union. To be an anonymous struct or union, it must have been
+  /// declared without a name and there must be no objects of this
+  /// type declared, e.g.,
+  /// @code
+  ///   union { int i; float f; };
+  /// @endcode
+  /// is an anonymous union but neither of the following are:
+  /// @code
+  ///  union X { int i; float f; };
+  ///  union { int i; float f; } obj;
+  /// @endcode
+  bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; }
+  void setAnonymousStructOrUnion(bool Anon) {
+    AnonymousStructOrUnion = Anon;
+  }
+
+  bool hasObjectMember() const { return HasObjectMember; }
+  void setHasObjectMember (bool val) { HasObjectMember = val; }
+
+  bool hasVolatileMember() const { return HasVolatileMember; }
+  void setHasVolatileMember (bool val) { HasVolatileMember = val; }
+  
+  /// \brief Determines whether this declaration represents the
+  /// injected class name.
+  ///
+  /// The injected class name in C++ is the name of the class that
+  /// appears inside the class itself. For example:
+  ///
+  /// \code
+  /// struct C {
+  ///   // C is implicitly declared here as a synonym for the class name.
+  /// };
+  ///
+  /// C::C c; // same as "C c;"
+  /// \endcode
+  bool isInjectedClassName() const;
+
+  /// getDefinition - Returns the RecordDecl that actually defines
+  ///  this struct/union/class.  When determining whether or not a
+  ///  struct/union/class is completely defined, one should use this
+  ///  method as opposed to 'isCompleteDefinition'.
+  ///  'isCompleteDefinition' indicates whether or not a specific
+  ///  RecordDecl is a completed definition, not whether or not the
+  ///  record type is defined.  This method returns NULL if there is
+  ///  no RecordDecl that defines the struct/union/tag.
+  RecordDecl *getDefinition() const {
+    return cast_or_null<RecordDecl>(TagDecl::getDefinition());
+  }
+
+  // Iterator access to field members. The field iterator only visits
+  // the non-static data members of this class, ignoring any static
+  // data members, functions, constructors, destructors, etc.
+  typedef specific_decl_iterator<FieldDecl> field_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
+
+  field_range fields() const { return field_range(field_begin(), field_end()); }
+  field_iterator field_begin() const;
+
+  field_iterator field_end() const {
+    return field_iterator(decl_iterator());
+  }
+
+  // field_empty - Whether there are any fields (non-static data
+  // members) in this record.
+  bool field_empty() const {
+    return field_begin() == field_end();
+  }
+
+  /// completeDefinition - Notes that the definition of this type is
+  /// now complete.
+  virtual void completeDefinition();
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstRecord && K <= lastRecord;
+  }
+
+  /// isMsStrust - Get whether or not this is an ms_struct which can
+  /// be turned on with an attribute, pragma, or -mms-bitfields
+  /// commandline option.
+  bool isMsStruct(const ASTContext &C) const;
+
+private:
+  /// \brief Deserialize just the fields.
+  void LoadFieldsFromExternalStorage() const;
+};
+
+class FileScopeAsmDecl : public Decl {
+  virtual void anchor();
+  StringLiteral *AsmString;
+  SourceLocation RParenLoc;
+  FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
+                   SourceLocation StartL, SourceLocation EndL)
+    : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
+public:
+  static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
+                                  StringLiteral *Str, SourceLocation AsmLoc,
+                                  SourceLocation RParenLoc);
+
+  static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  SourceLocation getAsmLoc() const { return getLocation(); }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(getAsmLoc(), getRParenLoc());
+  }
+
+  const StringLiteral *getAsmString() const { return AsmString; }
+  StringLiteral *getAsmString() { return AsmString; }
+  void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == FileScopeAsm; }
+};
+
+/// BlockDecl - This represents a block literal declaration, which is like an
+/// unnamed FunctionDecl.  For example:
+/// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
+///
+class BlockDecl : public Decl, public DeclContext {
+public:
+  /// A class which contains all the information about a particular
+  /// captured value.
+  class Capture {
+    enum {
+      flag_isByRef = 0x1,
+      flag_isNested = 0x2
+    };
+
+    /// The variable being captured.
+    llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags;
+
+    /// The copy expression, expressed in terms of a DeclRef (or
+    /// BlockDeclRef) to the captured variable.  Only required if the
+    /// variable has a C++ class type.
+    Expr *CopyExpr;
+
+  public:
+    Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy)
+      : VariableAndFlags(variable,
+                  (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)),
+        CopyExpr(copy) {}
+
+    /// The variable being captured.
+    VarDecl *getVariable() const { return VariableAndFlags.getPointer(); }
+
+    /// Whether this is a "by ref" capture, i.e. a capture of a __block
+    /// variable.
+    bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; }
+
+    /// Whether this is a nested capture, i.e. the variable captured
+    /// is not from outside the immediately enclosing function/block.
+    bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
+
+    bool hasCopyExpr() const { return CopyExpr != nullptr; }
+    Expr *getCopyExpr() const { return CopyExpr; }
+    void setCopyExpr(Expr *e) { CopyExpr = e; }
+  };
+
+private:
+  // FIXME: This can be packed into the bitfields in Decl.
+  bool IsVariadic : 1;
+  bool CapturesCXXThis : 1;
+  bool BlockMissingReturnType : 1;
+  bool IsConversionFromLambda : 1;
+  /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
+  /// parameters of this function.  This is null if a prototype or if there are
+  /// no formals.
+  ParmVarDecl **ParamInfo;
+  unsigned NumParams;
+
+  Stmt *Body;
+  TypeSourceInfo *SignatureAsWritten;
+
+  Capture *Captures;
+  unsigned NumCaptures;
+
+  unsigned ManglingNumber;
+  Decl *ManglingContextDecl;
+
+protected:
+  BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+    : Decl(Block, DC, CaretLoc), DeclContext(Block),
+      IsVariadic(false), CapturesCXXThis(false),
+      BlockMissingReturnType(true), IsConversionFromLambda(false),
+      ParamInfo(nullptr), NumParams(0), Body(nullptr),
+      SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
+      ManglingNumber(0), ManglingContextDecl(nullptr) {}
+
+public:
+  static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); 
+  static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  SourceLocation getCaretLocation() const { return getLocation(); }
+
+  bool isVariadic() const { return IsVariadic; }
+  void setIsVariadic(bool value) { IsVariadic = value; }
+
+  CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
+  Stmt *getBody() const override { return (Stmt*) Body; }
+  void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
+
+  void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
+  TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; }
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return getNumParams(); }
+  typedef ParmVarDecl **param_iterator;
+  typedef ParmVarDecl * const *param_const_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+  // ArrayRef access to formal parameters.
+  // FIXME: Should eventual replace iterator access.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(ParamInfo, param_size());
+  }
+
+  bool param_empty() const { return NumParams == 0; }
+  param_range params() { return param_range(param_begin(), param_end()); }
+  param_iterator param_begin() { return param_iterator(ParamInfo); }
+  param_iterator param_end() {
+    return param_iterator(ParamInfo + param_size());
+  }
+
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
+  param_const_iterator param_begin() const {
+    return param_const_iterator(ParamInfo);
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(ParamInfo + param_size());
+  }
+
+  unsigned getNumParams() const { return NumParams; }
+  const ParmVarDecl *getParamDecl(unsigned i) const {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ArrayRef<ParmVarDecl *> NewParamInfo);
+
+  /// hasCaptures - True if this block (or its nested blocks) captures
+  /// anything of local storage from its enclosing scopes.
+  bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; }
+
+  /// getNumCaptures - Returns the number of captured variables.
+  /// Does not include an entry for 'this'.
+  unsigned getNumCaptures() const { return NumCaptures; }
+
+  typedef const Capture *capture_iterator;
+  typedef const Capture *capture_const_iterator;
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+  typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+  capture_range captures() {
+    return capture_range(capture_begin(), capture_end());
+  }
+  capture_const_range captures() const {
+    return capture_const_range(capture_begin(), capture_end());
+  }
+
+  capture_iterator capture_begin() { return Captures; }
+  capture_iterator capture_end() { return Captures + NumCaptures; }
+  capture_const_iterator capture_begin() const { return Captures; }
+  capture_const_iterator capture_end() const { return Captures + NumCaptures; }
+
+  bool capturesCXXThis() const { return CapturesCXXThis; }
+  bool blockMissingReturnType() const { return BlockMissingReturnType; }
+  void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; }
+
+  bool isConversionFromLambda() const { return IsConversionFromLambda; }
+  void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; }
+
+  bool capturesVariable(const VarDecl *var) const;
+
+  void setCaptures(ASTContext &Context,
+                   const Capture *begin,
+                   const Capture *end,
+                   bool capturesCXXThis);
+
+   unsigned getBlockManglingNumber() const {
+     return ManglingNumber;
+   }
+   Decl *getBlockManglingContextDecl() const {
+     return ManglingContextDecl;    
+   }
+
+  void setBlockMangling(unsigned Number, Decl *Ctx) {
+    ManglingNumber = Number;
+    ManglingContextDecl = Ctx;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Block; }
+  static DeclContext *castToDeclContext(const BlockDecl *D) {
+    return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
+  }
+  static BlockDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<BlockDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// \brief This represents the body of a CapturedStmt, and serves as its
+/// DeclContext.
+class CapturedDecl : public Decl, public DeclContext {
+private:
+  /// \brief The number of parameters to the outlined function.
+  unsigned NumParams;
+  /// \brief The position of context parameter in list of parameters.
+  unsigned ContextParam;
+  /// \brief The body of the outlined function.
+  llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
+
+  explicit CapturedDecl(DeclContext *DC, unsigned NumParams)
+    : Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
+      NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { }
+
+  ImplicitParamDecl **getParams() const {
+    return reinterpret_cast<ImplicitParamDecl **>(
+             const_cast<CapturedDecl *>(this) + 1);
+  }
+
+public:
+  static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
+                              unsigned NumParams);
+  static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+                                          unsigned NumParams);
+
+  Stmt *getBody() const override { return BodyAndNothrow.getPointer(); }
+  void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
+
+  bool isNothrow() const { return BodyAndNothrow.getInt(); }
+  void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); }
+
+  unsigned getNumParams() const { return NumParams; }
+
+  ImplicitParamDecl *getParam(unsigned i) const {
+    assert(i < NumParams);
+    return getParams()[i];
+  }
+  void setParam(unsigned i, ImplicitParamDecl *P) {
+    assert(i < NumParams);
+    getParams()[i] = P;
+  }
+
+  /// \brief Retrieve the parameter containing captured variables.
+  ImplicitParamDecl *getContextParam() const {
+    assert(ContextParam < NumParams);
+    return getParam(ContextParam);
+  }
+  void setContextParam(unsigned i, ImplicitParamDecl *P) {
+    assert(i < NumParams);
+    ContextParam = i;
+    setParam(i, P);
+  }
+  unsigned getContextParamPosition() const { return ContextParam; }
+
+  typedef ImplicitParamDecl **param_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+
+  /// \brief Retrieve an iterator pointing to the first parameter decl.
+  param_iterator param_begin() const { return getParams(); }
+  /// \brief Retrieve an iterator one past the last parameter decl.
+  param_iterator param_end() const { return getParams() + NumParams; }
+
+  /// \brief Retrieve an iterator range for the parameter declarations.
+  param_range params() const { return param_range(param_begin(), param_end()); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Captured; }
+  static DeclContext *castToDeclContext(const CapturedDecl *D) {
+    return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D));
+  }
+  static CapturedDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC));
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Describes a module import declaration, which makes the contents
+/// of the named module visible in the current translation unit.
+///
+/// An import declaration imports the named module (or submodule). For example:
+/// \code
+///   @import std.vector;
+/// \endcode
+///
+/// Import declarations can also be implicitly generated from
+/// \#include/\#import directives.
+class ImportDecl : public Decl {
+  /// \brief The imported module, along with a bit that indicates whether
+  /// we have source-location information for each identifier in the module
+  /// name. 
+  ///
+  /// When the bit is false, we only have a single source location for the
+  /// end of the import declaration.
+  llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete;
+  
+  /// \brief The next import in the list of imports local to the translation
+  /// unit being parsed (not loaded from an AST file).
+  ImportDecl *NextLocalImport;
+  
+  friend class ASTReader;
+  friend class ASTDeclReader;
+  friend class ASTContext;
+  
+  ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
+             ArrayRef<SourceLocation> IdentifierLocs);
+
+  ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
+             SourceLocation EndLoc);
+
+  ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { }
+  
+public:
+  /// \brief Create a new module import declaration.
+  static ImportDecl *Create(ASTContext &C, DeclContext *DC, 
+                            SourceLocation StartLoc, Module *Imported,
+                            ArrayRef<SourceLocation> IdentifierLocs);
+  
+  /// \brief Create a new module import declaration for an implicitly-generated
+  /// import.
+  static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC, 
+                                    SourceLocation StartLoc, Module *Imported, 
+                                    SourceLocation EndLoc);
+  
+  /// \brief Create a new, deserialized module import declaration.
+  static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, 
+                                        unsigned NumLocations);
+  
+  /// \brief Retrieve the module that was imported by the import declaration.
+  Module *getImportedModule() const { return ImportedAndComplete.getPointer(); }
+  
+  /// \brief Retrieves the locations of each of the identifiers that make up
+  /// the complete module name in the import declaration.
+  ///
+  /// This will return an empty array if the locations of the individual
+  /// identifiers aren't available.
+  ArrayRef<SourceLocation> getIdentifierLocs() const;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Import; }
+};
+
+/// \brief Represents an empty-declaration.
+class EmptyDecl : public Decl {
+  virtual void anchor();
+  EmptyDecl(DeclContext *DC, SourceLocation L)
+    : Decl(Empty, DC, L) { }
+
+public:
+  static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation L);
+  static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Empty; }
+};
+
+/// Insertion operator for diagnostics.  This allows sending NamedDecl's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const NamedDecl* ND) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+                  DiagnosticsEngine::ak_nameddecl);
+  return DB;
+}
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           const NamedDecl* ND) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+                  DiagnosticsEngine::ak_nameddecl);
+  return PD;
+}
+
+template<typename decl_type>
+void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
+  // Note: This routine is implemented here because we need both NamedDecl
+  // and Redeclarable to be defined.
+  assert(RedeclLink.NextIsLatest() &&
+         "setPreviousDecl on a decl already in a redeclaration chain");
+
+  decl_type *First;
+
+  if (PrevDecl) {
+    // Point to previous. Make sure that this is actually the most recent
+    // redeclaration, or we can build invalid chains. If the most recent
+    // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
+    First = PrevDecl->getFirstDecl();
+    assert(First->RedeclLink.NextIsLatest() && "Expected first");
+    decl_type *MostRecent = First->getNextRedeclaration();
+    RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
+
+    // If the declaration was previously visible, a redeclaration of it remains
+    // visible even if it wouldn't be visible by itself.
+    static_cast<decl_type*>(this)->IdentifierNamespace |=
+      MostRecent->getIdentifierNamespace() &
+      (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
+  } else {
+    // Make this first.
+    First = static_cast<decl_type*>(this);
+  }
+
+  // First one will point to this one as latest.
+  First->RedeclLink.setLatest(static_cast<decl_type*>(this));
+
+  assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
+         cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
+}
+
+// Inline function definitions.
+
+/// \brief Check if the given decl is complete.
+///
+/// We use this function to break a cycle between the inline definitions in
+/// Type.h and Decl.h.
+inline bool IsEnumDeclComplete(EnumDecl *ED) {
+  return ED->isComplete();
+}
+
+/// \brief Check if the given decl is scoped.
+///
+/// We use this function to break a cycle between the inline definitions in
+/// Type.h and Decl.h.
+inline bool IsEnumDeclScoped(EnumDecl *ED) {
+  return ED->isScoped();
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
new file mode 100644
index 0000000..3c5056c
--- /dev/null
+++ b/include/clang/AST/DeclAccessPair.h
@@ -0,0 +1,72 @@
+//===--- DeclAccessPair.h - A decl bundled with its path access -*- 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 DeclAccessPair class, which provides an
+//  efficient representation of a pair of a NamedDecl* and an
+//  AccessSpecifier.  Generally the access specifier gives the
+//  natural access of a declaration when named in a class, as
+//  defined in C++ [class.access.base]p1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
+#define LLVM_CLANG_AST_DECLACCESSPAIR_H
+
+#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+
+class NamedDecl;
+
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+  uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+
+  enum { Mask = 0x3 };
+
+public:
+  static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
+    DeclAccessPair p;
+    p.set(D, AS);
+    return p;
+  }
+
+  NamedDecl *getDecl() const {
+    return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
+  }
+  AccessSpecifier getAccess() const {
+    return AccessSpecifier(Mask & Ptr);
+  }
+
+  void setDecl(NamedDecl *D) {
+    set(D, getAccess());
+  }
+  void setAccess(AccessSpecifier AS) {
+    set(getDecl(), AS);
+  }
+  void set(NamedDecl *D, AccessSpecifier AS) {
+    Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
+  }
+
+  operator NamedDecl*() const { return getDecl(); }
+  NamedDecl *operator->() const { return getDecl(); }
+};
+}
+
+// Take a moment to tell SmallVector that DeclAccessPair is POD.
+namespace llvm {
+template<typename> struct isPodLike;
+template<> struct isPodLike<clang::DeclAccessPair> {
+   static const bool value = true;
+};
+}
+
+#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
new file mode 100644
index 0000000..607ca4e
--- /dev/null
+++ b/include/clang/AST/DeclBase.h
@@ -0,0 +1,1772 @@
+//===-- DeclBase.h - Base Classes for representing declarations -*- 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 Decl and DeclContext interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLBASE_H
+#define LLVM_CLANG_AST_DECLBASE_H
+
+#include "clang/AST/AttrIterator.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+class ASTMutationListener;
+class BlockDecl;
+class CXXRecordDecl;
+class CompoundStmt;
+class DeclContext;
+class DeclarationName;
+class DependentDiagnostic;
+class EnumDecl;
+class FunctionDecl;
+class FunctionType;
+enum Linkage : unsigned char;
+class LinkageComputer;
+class LinkageSpecDecl;
+class Module;
+class NamedDecl;
+class NamespaceDecl;
+class ObjCCategoryDecl;
+class ObjCCategoryImplDecl;
+class ObjCContainerDecl;
+class ObjCImplDecl;
+class ObjCImplementationDecl;
+class ObjCInterfaceDecl;
+class ObjCMethodDecl;
+class ObjCProtocolDecl;
+struct PrintingPolicy;
+class Stmt;
+class StoredDeclsMap;
+class TranslationUnitDecl;
+class UsingDirectiveDecl;
+}
+
+namespace clang {
+
+  /// \brief Captures the result of checking the availability of a
+  /// declaration.
+  enum AvailabilityResult {
+    AR_Available = 0,
+    AR_NotYetIntroduced,
+    AR_Deprecated,
+    AR_Unavailable
+  };
+
+/// Decl - This represents one declaration (or definition), e.g. a variable,
+/// typedef, function, struct, etc.
+///
+class Decl {
+public:
+  /// \brief Lists the kind of concrete classes of Decl.
+  enum Kind {
+#define DECL(DERIVED, BASE) DERIVED,
+#define ABSTRACT_DECL(DECL)
+#define DECL_RANGE(BASE, START, END) \
+        first##BASE = START, last##BASE = END,
+#define LAST_DECL_RANGE(BASE, START, END) \
+        first##BASE = START, last##BASE = END
+#include "clang/AST/DeclNodes.inc"
+  };
+
+  /// \brief A placeholder type used to construct an empty shell of a
+  /// decl-derived type that will be filled in later (e.g., by some
+  /// deserialization method).
+  struct EmptyShell { };
+
+  /// IdentifierNamespace - The different namespaces in which
+  /// declarations may appear.  According to C99 6.2.3, there are
+  /// four namespaces, labels, tags, members and ordinary
+  /// identifiers.  C++ describes lookup completely differently:
+  /// certain lookups merely "ignore" certain kinds of declarations,
+  /// usually based on whether the declaration is of a type, etc.
+  ///
+  /// These are meant as bitmasks, so that searches in
+  /// C++ can look into the "tag" namespace during ordinary lookup.
+  ///
+  /// Decl currently provides 15 bits of IDNS bits.
+  enum IdentifierNamespace {
+    /// Labels, declared with 'x:' and referenced with 'goto x'.
+    IDNS_Label               = 0x0001,
+
+    /// Tags, declared with 'struct foo;' and referenced with
+    /// 'struct foo'.  All tags are also types.  This is what
+    /// elaborated-type-specifiers look for in C.
+    IDNS_Tag                 = 0x0002,
+
+    /// Types, declared with 'struct foo', typedefs, etc.
+    /// This is what elaborated-type-specifiers look for in C++,
+    /// but note that it's ill-formed to find a non-tag.
+    IDNS_Type                = 0x0004,
+
+    /// Members, declared with object declarations within tag
+    /// definitions.  In C, these can only be found by "qualified"
+    /// lookup in member expressions.  In C++, they're found by
+    /// normal lookup.
+    IDNS_Member              = 0x0008,
+
+    /// Namespaces, declared with 'namespace foo {}'.
+    /// Lookup for nested-name-specifiers find these.
+    IDNS_Namespace           = 0x0010,
+
+    /// Ordinary names.  In C, everything that's not a label, tag,
+    /// or member ends up here.
+    IDNS_Ordinary            = 0x0020,
+
+    /// Objective C \@protocol.
+    IDNS_ObjCProtocol        = 0x0040,
+
+    /// This declaration is a friend function.  A friend function
+    /// declaration is always in this namespace but may also be in
+    /// IDNS_Ordinary if it was previously declared.
+    IDNS_OrdinaryFriend      = 0x0080,
+
+    /// This declaration is a friend class.  A friend class
+    /// declaration is always in this namespace but may also be in
+    /// IDNS_Tag|IDNS_Type if it was previously declared.
+    IDNS_TagFriend           = 0x0100,
+
+    /// This declaration is a using declaration.  A using declaration
+    /// *introduces* a number of other declarations into the current
+    /// scope, and those declarations use the IDNS of their targets,
+    /// but the actual using declarations go in this namespace.
+    IDNS_Using               = 0x0200,
+
+    /// This declaration is a C++ operator declared in a non-class
+    /// context.  All such operators are also in IDNS_Ordinary.
+    /// C++ lexical operator lookup looks for these.
+    IDNS_NonMemberOperator   = 0x0400,
+
+    /// This declaration is a function-local extern declaration of a
+    /// variable or function. This may also be IDNS_Ordinary if it
+    /// has been declared outside any function.
+    IDNS_LocalExtern         = 0x0800
+  };
+
+  /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
+  /// parameter types in method declarations.  Other than remembering
+  /// them and mangling them into the method's signature string, these
+  /// are ignored by the compiler; they are consumed by certain
+  /// remote-messaging frameworks.
+  ///
+  /// in, inout, and out are mutually exclusive and apply only to
+  /// method parameters.  bycopy and byref are mutually exclusive and
+  /// apply only to method parameters (?).  oneway applies only to
+  /// results.  All of these expect their corresponding parameter to
+  /// have a particular type.  None of this is currently enforced by
+  /// clang.
+  ///
+  /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
+  enum ObjCDeclQualifier {
+    OBJC_TQ_None = 0x0,
+    OBJC_TQ_In = 0x1,
+    OBJC_TQ_Inout = 0x2,
+    OBJC_TQ_Out = 0x4,
+    OBJC_TQ_Bycopy = 0x8,
+    OBJC_TQ_Byref = 0x10,
+    OBJC_TQ_Oneway = 0x20
+  };
+
+protected:
+  // Enumeration values used in the bits stored in NextInContextAndBits.
+  enum {
+    /// \brief Whether this declaration is a top-level declaration (function,
+    /// global variable, etc.) that is lexically inside an objc container
+    /// definition.
+    TopLevelDeclInObjCContainerFlag = 0x01,
+    
+    /// \brief Whether this declaration is private to the module in which it was
+    /// defined.
+    ModulePrivateFlag = 0x02
+  };
+  
+  /// \brief The next declaration within the same lexical
+  /// DeclContext. These pointers form the linked list that is
+  /// traversed via DeclContext's decls_begin()/decls_end().
+  ///
+  /// The extra two bits are used for the TopLevelDeclInObjCContainer and
+  /// ModulePrivate bits.
+  llvm::PointerIntPair<Decl *, 2, unsigned> NextInContextAndBits;
+
+private:
+  friend class DeclContext;
+
+  struct MultipleDC {
+    DeclContext *SemanticDC;
+    DeclContext *LexicalDC;
+  };
+
+
+  /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
+  /// For declarations that don't contain C++ scope specifiers, it contains
+  /// the DeclContext where the Decl was declared.
+  /// For declarations with C++ scope specifiers, it contains a MultipleDC*
+  /// with the context where it semantically belongs (SemanticDC) and the
+  /// context where it was lexically declared (LexicalDC).
+  /// e.g.:
+  ///
+  ///   namespace A {
+  ///      void f(); // SemanticDC == LexicalDC == 'namespace A'
+  ///   }
+  ///   void A::f(); // SemanticDC == namespace 'A'
+  ///                // LexicalDC == global namespace
+  llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
+
+  inline bool isInSemaDC() const    { return DeclCtx.is<DeclContext*>(); }
+  inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
+  inline MultipleDC *getMultipleDC() const {
+    return DeclCtx.get<MultipleDC*>();
+  }
+  inline DeclContext *getSemanticDC() const {
+    return DeclCtx.get<DeclContext*>();
+  }
+
+  /// Loc - The location of this decl.
+  SourceLocation Loc;
+
+  /// DeclKind - This indicates which class this is.
+  unsigned DeclKind : 8;
+
+  /// InvalidDecl - This indicates a semantic error occurred.
+  unsigned InvalidDecl :  1;
+
+  /// HasAttrs - This indicates whether the decl has attributes or not.
+  unsigned HasAttrs : 1;
+
+  /// Implicit - Whether this declaration was implicitly generated by
+  /// the implementation rather than explicitly written by the user.
+  unsigned Implicit : 1;
+
+  /// \brief Whether this declaration was "used", meaning that a definition is
+  /// required.
+  unsigned Used : 1;
+
+  /// \brief Whether this declaration was "referenced".
+  /// The difference with 'Used' is whether the reference appears in a
+  /// evaluated context or not, e.g. functions used in uninstantiated templates
+  /// are regarded as "referenced" but not "used".
+  unsigned Referenced : 1;
+
+  /// \brief Whether statistic collection is enabled.
+  static bool StatisticsEnabled;
+
+protected:
+  /// Access - Used by C++ decls for the access specifier.
+  // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+  unsigned Access : 2;
+  friend class CXXClassMemberWrapper;
+
+  /// \brief Whether this declaration was loaded from an AST file.
+  unsigned FromASTFile : 1;
+
+  /// \brief Whether this declaration is hidden from normal name lookup, e.g.,
+  /// because it is was loaded from an AST file is either module-private or
+  /// because its submodule has not been made visible.
+  unsigned Hidden : 1;
+  
+  /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
+  unsigned IdentifierNamespace : 12;
+
+  /// \brief If 0, we have not computed the linkage of this declaration.
+  /// Otherwise, it is the linkage + 1.
+  mutable unsigned CacheValidAndLinkage : 3;
+
+  friend class ASTDeclWriter;
+  friend class ASTDeclReader;
+  friend class ASTReader;
+  friend class LinkageComputer;
+
+  template<typename decl_type> friend class Redeclarable;
+
+  /// \brief Allocate memory for a deserialized declaration.
+  ///
+  /// This routine must be used to allocate memory for any declaration that is
+  /// deserialized from a module file.
+  ///
+  /// \param Size The size of the allocated object.
+  /// \param Ctx The context in which we will allocate memory.
+  /// \param ID The global ID of the deserialized declaration.
+  /// \param Extra The amount of extra space to allocate after the object.
+  void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
+                     std::size_t Extra = 0);
+
+  /// \brief Allocate memory for a non-deserialized declaration.
+  void *operator new(std::size_t Size, const ASTContext &Ctx,
+                     DeclContext *Parent, std::size_t Extra = 0);
+
+private:
+  bool AccessDeclContextSanity() const;
+
+protected:
+
+  Decl(Kind DK, DeclContext *DC, SourceLocation L)
+    : NextInContextAndBits(), DeclCtx(DC),
+      Loc(L), DeclKind(DK), InvalidDecl(0),
+      HasAttrs(false), Implicit(false), Used(false), Referenced(false),
+      Access(AS_none), FromASTFile(0), Hidden(0),
+      IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
+      CacheValidAndLinkage(0)
+  {
+    if (StatisticsEnabled) add(DK);
+  }
+
+  Decl(Kind DK, EmptyShell Empty)
+    : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0),
+      HasAttrs(false), Implicit(false), Used(false), Referenced(false),
+      Access(AS_none), FromASTFile(0), Hidden(0),
+      IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
+      CacheValidAndLinkage(0)
+  {
+    if (StatisticsEnabled) add(DK);
+  }
+
+  virtual ~Decl();
+
+  /// \brief Update a potentially out-of-date declaration.
+  void updateOutOfDate(IdentifierInfo &II) const;
+
+  Linkage getCachedLinkage() const {
+    return Linkage(CacheValidAndLinkage - 1);
+  }
+
+  void setCachedLinkage(Linkage L) const {
+    CacheValidAndLinkage = L + 1;
+  }
+
+  bool hasCachedLinkage() const {
+    return CacheValidAndLinkage;
+  }
+
+public:
+
+  /// \brief Source range that this declaration covers.
+  virtual SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(getLocation(), getLocation());
+  }
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getSourceRange().getBegin();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSourceRange().getEnd();
+  }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  Kind getKind() const { return static_cast<Kind>(DeclKind); }
+  const char *getDeclKindName() const;
+
+  Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
+  const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
+
+  DeclContext *getDeclContext() {
+    if (isInSemaDC())
+      return getSemanticDC();
+    return getMultipleDC()->SemanticDC;
+  }
+  const DeclContext *getDeclContext() const {
+    return const_cast<Decl*>(this)->getDeclContext();
+  }
+
+  /// Find the innermost non-closure ancestor of this declaration,
+  /// walking up through blocks, lambdas, etc.  If that ancestor is
+  /// not a code context (!isFunctionOrMethod()), returns null.
+  ///
+  /// A declaration may be its own non-closure context.
+  Decl *getNonClosureContext();
+  const Decl *getNonClosureContext() const {
+    return const_cast<Decl*>(this)->getNonClosureContext();
+  }
+
+  TranslationUnitDecl *getTranslationUnitDecl();
+  const TranslationUnitDecl *getTranslationUnitDecl() const {
+    return const_cast<Decl*>(this)->getTranslationUnitDecl();
+  }
+
+  bool isInAnonymousNamespace() const;
+
+  bool isInStdNamespace() const;
+
+  ASTContext &getASTContext() const LLVM_READONLY;
+
+  void setAccess(AccessSpecifier AS) {
+    Access = AS;
+    assert(AccessDeclContextSanity());
+  }
+
+  AccessSpecifier getAccess() const {
+    assert(AccessDeclContextSanity());
+    return AccessSpecifier(Access);
+  }
+
+  /// \brief Retrieve the access specifier for this declaration, even though
+  /// it may not yet have been properly set.
+  AccessSpecifier getAccessUnsafe() const {
+    return AccessSpecifier(Access);
+  }
+
+  bool hasAttrs() const { return HasAttrs; }
+  void setAttrs(const AttrVec& Attrs) {
+    return setAttrsImpl(Attrs, getASTContext());
+  }
+  AttrVec &getAttrs() {
+    return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
+  }
+  const AttrVec &getAttrs() const;
+  void dropAttrs();
+
+  void addAttr(Attr *A) {
+    if (hasAttrs())
+      getAttrs().push_back(A);
+    else
+      setAttrs(AttrVec(1, A));
+  }
+
+  typedef AttrVec::const_iterator attr_iterator;
+  typedef llvm::iterator_range<attr_iterator> attr_range;
+
+  attr_range attrs() const {
+    return attr_range(attr_begin(), attr_end());
+  }
+
+  attr_iterator attr_begin() const {
+    return hasAttrs() ? getAttrs().begin() : nullptr;
+  }
+  attr_iterator attr_end() const {
+    return hasAttrs() ? getAttrs().end() : nullptr;
+  }
+
+  template <typename T>
+  void dropAttr() {
+    if (!HasAttrs) return;
+
+    AttrVec &Vec = getAttrs();
+    Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end());
+
+    if (Vec.empty())
+      HasAttrs = false;
+  }
+
+  template <typename T>
+  llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
+    return llvm::iterator_range<specific_attr_iterator<T>>(
+        specific_attr_begin<T>(), specific_attr_end<T>());
+  }
+
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_begin() const {
+    return specific_attr_iterator<T>(attr_begin());
+  }
+  template <typename T>
+  specific_attr_iterator<T> specific_attr_end() const {
+    return specific_attr_iterator<T>(attr_end());
+  }
+
+  template<typename T> T *getAttr() const {
+    return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
+  }
+  template<typename T> bool hasAttr() const {
+    return hasAttrs() && hasSpecificAttr<T>(getAttrs());
+  }
+
+  /// getMaxAlignment - return the maximum alignment specified by attributes
+  /// on this decl, 0 if there are none.
+  unsigned getMaxAlignment() const;
+
+  /// setInvalidDecl - Indicates the Decl had a semantic error. This
+  /// allows for graceful error recovery.
+  void setInvalidDecl(bool Invalid = true);
+  bool isInvalidDecl() const { return (bool) InvalidDecl; }
+
+  /// isImplicit - Indicates whether the declaration was implicitly
+  /// generated by the implementation. If false, this declaration
+  /// was written explicitly in the source code.
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I = true) { Implicit = I; }
+
+  /// \brief Whether this declaration was used, meaning that a definition
+  /// is required.
+  ///
+  /// \param CheckUsedAttr When true, also consider the "used" attribute
+  /// (in addition to the "used" bit set by \c setUsed()) when determining
+  /// whether the function is used.
+  bool isUsed(bool CheckUsedAttr = true) const;
+
+  /// \brief Set whether the declaration is used, in the sense of odr-use.
+  ///
+  /// This should only be used immediately after creating a declaration.
+  void setIsUsed() { Used = true; }
+
+  /// \brief Mark the declaration used, in the sense of odr-use.
+  ///
+  /// This notifies any mutation listeners in addition to setting a bit
+  /// indicating the declaration is used.
+  void markUsed(ASTContext &C);
+
+  /// \brief Whether this declaration was referenced.
+  bool isReferenced() const;
+
+  void setReferenced(bool R = true) { Referenced = R; }
+
+  /// \brief Whether this declaration is a top-level declaration (function,
+  /// global variable, etc.) that is lexically inside an objc container
+  /// definition.
+  bool isTopLevelDeclInObjCContainer() const {
+    return NextInContextAndBits.getInt() & TopLevelDeclInObjCContainerFlag;
+  }
+
+  void setTopLevelDeclInObjCContainer(bool V = true) {
+    unsigned Bits = NextInContextAndBits.getInt();
+    if (V)
+      Bits |= TopLevelDeclInObjCContainerFlag;
+    else
+      Bits &= ~TopLevelDeclInObjCContainerFlag;
+    NextInContextAndBits.setInt(Bits);
+  }
+
+  /// \brief Whether this declaration was marked as being private to the
+  /// module in which it was defined.
+  bool isModulePrivate() const {
+    return NextInContextAndBits.getInt() & ModulePrivateFlag;
+  }
+
+protected:
+  /// \brief Specify whether this declaration was marked as being private
+  /// to the module in which it was defined.
+  void setModulePrivate(bool MP = true) {
+    unsigned Bits = NextInContextAndBits.getInt();
+    if (MP)
+      Bits |= ModulePrivateFlag;
+    else
+      Bits &= ~ModulePrivateFlag;
+    NextInContextAndBits.setInt(Bits);
+  }
+
+  /// \brief Set the owning module ID.
+  void setOwningModuleID(unsigned ID) {
+    assert(isFromASTFile() && "Only works on a deserialized declaration");
+    *((unsigned*)this - 2) = ID;
+  }
+  
+public:
+  
+  /// \brief Determine the availability of the given declaration.
+  ///
+  /// This routine will determine the most restrictive availability of
+  /// the given declaration (e.g., preferring 'unavailable' to
+  /// 'deprecated').
+  ///
+  /// \param Message If non-NULL and the result is not \c
+  /// AR_Available, will be set to a (possibly empty) message
+  /// describing why the declaration has not been introduced, is
+  /// deprecated, or is unavailable.
+  AvailabilityResult getAvailability(std::string *Message = nullptr) const;
+
+  /// \brief Determine whether this declaration is marked 'deprecated'.
+  ///
+  /// \param Message If non-NULL and the declaration is deprecated,
+  /// this will be set to the message describing why the declaration
+  /// was deprecated (which may be empty).
+  bool isDeprecated(std::string *Message = nullptr) const {
+    return getAvailability(Message) == AR_Deprecated;
+  }
+
+  /// \brief Determine whether this declaration is marked 'unavailable'.
+  ///
+  /// \param Message If non-NULL and the declaration is unavailable,
+  /// this will be set to the message describing why the declaration
+  /// was made unavailable (which may be empty).
+  bool isUnavailable(std::string *Message = nullptr) const {
+    return getAvailability(Message) == AR_Unavailable;
+  }
+
+  /// \brief Determine whether this is a weak-imported symbol.
+  ///
+  /// Weak-imported symbols are typically marked with the
+  /// 'weak_import' attribute, but may also be marked with an
+  /// 'availability' attribute where we're targing a platform prior to
+  /// the introduction of this feature.
+  bool isWeakImported() const;
+
+  /// \brief Determines whether this symbol can be weak-imported,
+  /// e.g., whether it would be well-formed to add the weak_import
+  /// attribute.
+  ///
+  /// \param IsDefinition Set to \c true to indicate that this
+  /// declaration cannot be weak-imported because it has a definition.
+  bool canBeWeakImported(bool &IsDefinition) const;
+
+  /// \brief Determine whether this declaration came from an AST file (such as
+  /// a precompiled header or module) rather than having been parsed.
+  bool isFromASTFile() const { return FromASTFile; }
+
+  /// \brief Retrieve the global declaration ID associated with this 
+  /// declaration, which specifies where in the 
+  unsigned getGlobalID() const { 
+    if (isFromASTFile())
+      return *((const unsigned*)this - 1);
+    return 0;
+  }
+  
+  /// \brief Retrieve the global ID of the module that owns this particular
+  /// declaration.
+  unsigned getOwningModuleID() const {
+    if (isFromASTFile())
+      return *((const unsigned*)this - 2);
+    
+    return 0;
+  }
+
+private:
+  Module *getOwningModuleSlow() const;
+
+public:
+  Module *getOwningModule() const {
+    if (!isFromASTFile())
+      return nullptr;
+
+    return getOwningModuleSlow();
+  }
+
+  unsigned getIdentifierNamespace() const {
+    return IdentifierNamespace;
+  }
+  bool isInIdentifierNamespace(unsigned NS) const {
+    return getIdentifierNamespace() & NS;
+  }
+  static unsigned getIdentifierNamespaceForKind(Kind DK);
+
+  bool hasTagIdentifierNamespace() const {
+    return isTagIdentifierNamespace(getIdentifierNamespace());
+  }
+  static bool isTagIdentifierNamespace(unsigned NS) {
+    // TagDecls have Tag and Type set and may also have TagFriend.
+    return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
+  }
+
+  /// getLexicalDeclContext - The declaration context where this Decl was
+  /// lexically declared (LexicalDC). May be different from
+  /// getDeclContext() (SemanticDC).
+  /// e.g.:
+  ///
+  ///   namespace A {
+  ///      void f(); // SemanticDC == LexicalDC == 'namespace A'
+  ///   }
+  ///   void A::f(); // SemanticDC == namespace 'A'
+  ///                // LexicalDC == global namespace
+  DeclContext *getLexicalDeclContext() {
+    if (isInSemaDC())
+      return getSemanticDC();
+    return getMultipleDC()->LexicalDC;
+  }
+  const DeclContext *getLexicalDeclContext() const {
+    return const_cast<Decl*>(this)->getLexicalDeclContext();
+  }
+
+  virtual bool isOutOfLine() const {
+    return getLexicalDeclContext() != getDeclContext();
+  }
+
+  /// setDeclContext - Set both the semantic and lexical DeclContext
+  /// to DC.
+  void setDeclContext(DeclContext *DC);
+
+  void setLexicalDeclContext(DeclContext *DC);
+
+  /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
+  /// scoped decl is defined outside the current function or method.  This is
+  /// roughly global variables and functions, but also handles enums (which
+  /// could be defined inside or outside a function etc).
+  bool isDefinedOutsideFunctionOrMethod() const {
+    return getParentFunctionOrMethod() == nullptr;
+  }
+
+  /// \brief If this decl is defined inside a function/method/block it returns
+  /// the corresponding DeclContext, otherwise it returns null.
+  const DeclContext *getParentFunctionOrMethod() const;
+  DeclContext *getParentFunctionOrMethod() {
+    return const_cast<DeclContext*>(
+                    const_cast<const Decl*>(this)->getParentFunctionOrMethod());
+  }
+
+  /// \brief Retrieves the "canonical" declaration of the given declaration.
+  virtual Decl *getCanonicalDecl() { return this; }
+  const Decl *getCanonicalDecl() const {
+    return const_cast<Decl*>(this)->getCanonicalDecl();
+  }
+
+  /// \brief Whether this particular Decl is a canonical one.
+  bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
+  
+protected:
+  /// \brief Returns the next redeclaration or itself if this is the only decl.
+  ///
+  /// Decl subclasses that can be redeclared should override this method so that
+  /// Decl::redecl_iterator can iterate over them.
+  virtual Decl *getNextRedeclarationImpl() { return this; }
+
+  /// \brief Implementation of getPreviousDecl(), to be overridden by any
+  /// subclass that has a redeclaration chain.
+  virtual Decl *getPreviousDeclImpl() { return nullptr; }
+
+  /// \brief Implementation of getMostRecentDecl(), to be overridden by any
+  /// subclass that has a redeclaration chain.
+  virtual Decl *getMostRecentDeclImpl() { return this; }
+
+public:
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    Decl *Current;
+    Decl *Starter;
+
+  public:
+    typedef Decl *value_type;
+    typedef const value_type &reference;
+    typedef const value_type *pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t difference_type;
+
+    redecl_iterator() : Current(nullptr) { }
+    explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
+
+    reference operator*() const { return Current; }
+    value_type operator->() const { return Current; }
+
+    redecl_iterator& operator++() {
+      assert(Current && "Advancing while iterator has reached end");
+      // Get either previous decl or latest decl.
+      Decl *Next = Current->getNextRedeclarationImpl();
+      assert(Next && "Should return next redeclaration or itself, never null!");
+      Current = (Next != Starter) ? Next : nullptr;
+      return *this;
+    }
+
+    redecl_iterator operator++(int) {
+      redecl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(redecl_iterator x, redecl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(redecl_iterator x, redecl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+  /// \brief Returns an iterator range for all the redeclarations of the same
+  /// decl. It will iterate at least once (when this decl is the only one).
+  redecl_range redecls() const {
+    return redecl_range(redecls_begin(), redecls_end());
+  }
+
+  redecl_iterator redecls_begin() const {
+    return redecl_iterator(const_cast<Decl *>(this));
+  }
+  redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+  /// \brief Retrieve the previous declaration that declares the same entity
+  /// as this declaration, or NULL if there is no previous declaration.
+  Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
+  
+  /// \brief Retrieve the most recent declaration that declares the same entity
+  /// as this declaration, or NULL if there is no previous declaration.
+  const Decl *getPreviousDecl() const { 
+    return const_cast<Decl *>(this)->getPreviousDeclImpl();
+  }
+
+  /// \brief True if this is the first declaration in its redeclaration chain.
+  bool isFirstDecl() const {
+    return getPreviousDecl() == nullptr;
+  }
+
+  /// \brief Retrieve the most recent declaration that declares the same entity
+  /// as this declaration (which may be this declaration).
+  Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
+
+  /// \brief Retrieve the most recent declaration that declares the same entity
+  /// as this declaration (which may be this declaration).
+  const Decl *getMostRecentDecl() const { 
+    return const_cast<Decl *>(this)->getMostRecentDeclImpl();
+  }
+
+  /// getBody - If this Decl represents a declaration for a body of code,
+  ///  such as a function or method definition, this method returns the
+  ///  top-level Stmt* of that body.  Otherwise this method returns null.
+  virtual Stmt* getBody() const { return nullptr; }
+
+  /// \brief Returns true if this \c Decl represents a declaration for a body of
+  /// code, such as a function or method definition.
+  /// Note that \c hasBody can also return true if any redeclaration of this
+  /// \c Decl represents a declaration for a body of code.
+  virtual bool hasBody() const { return getBody() != nullptr; }
+
+  /// getBodyRBrace - Gets the right brace of the body, if a body exists.
+  /// This works whether the body is a CompoundStmt or a CXXTryStmt.
+  SourceLocation getBodyRBrace() const;
+
+  // global temp stats (until we have a per-module visitor)
+  static void add(Kind k);
+  static void EnableStatistics();
+  static void PrintStats();
+
+  /// isTemplateParameter - Determines whether this declaration is a
+  /// template parameter.
+  bool isTemplateParameter() const;
+
+  /// isTemplateParameter - Determines whether this declaration is a
+  /// template parameter pack.
+  bool isTemplateParameterPack() const;
+
+  /// \brief Whether this declaration is a parameter pack.
+  bool isParameterPack() const;
+
+  /// \brief returns true if this declaration is a template
+  bool isTemplateDecl() const;
+
+  /// \brief Whether this declaration is a function or function template.
+  bool isFunctionOrFunctionTemplate() const {
+    return (DeclKind >= Decl::firstFunction &&
+            DeclKind <= Decl::lastFunction) ||
+           DeclKind == FunctionTemplate;
+  }
+
+  /// \brief Returns the function itself, or the templated function if this is a
+  /// function template.
+  FunctionDecl *getAsFunction() LLVM_READONLY;
+
+  const FunctionDecl *getAsFunction() const {
+    return const_cast<Decl *>(this)->getAsFunction();
+  }
+
+  /// \brief Changes the namespace of this declaration to reflect that it's
+  /// a function-local extern declaration.
+  ///
+  /// These declarations appear in the lexical context of the extern
+  /// declaration, but in the semantic context of the enclosing namespace
+  /// scope.
+  void setLocalExternDecl() {
+    assert((IdentifierNamespace == IDNS_Ordinary ||
+            IdentifierNamespace == IDNS_OrdinaryFriend) &&
+           "namespace is not ordinary");
+
+    Decl *Prev = getPreviousDecl();
+    IdentifierNamespace &= ~IDNS_Ordinary;
+
+    IdentifierNamespace |= IDNS_LocalExtern;
+    if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
+      IdentifierNamespace |= IDNS_Ordinary;
+  }
+
+  /// \brief Determine whether this is a block-scope declaration with linkage.
+  /// This will either be a local variable declaration declared 'extern', or a
+  /// local function declaration.
+  bool isLocalExternDecl() {
+    return IdentifierNamespace & IDNS_LocalExtern;
+  }
+
+  /// \brief Changes the namespace of this declaration to reflect that it's
+  /// the object of a friend declaration.
+  ///
+  /// These declarations appear in the lexical context of the friending
+  /// class, but in the semantic context of the actual entity.  This property
+  /// applies only to a specific decl object;  other redeclarations of the
+  /// same entity may not (and probably don't) share this property.
+  void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
+    unsigned OldNS = IdentifierNamespace;
+    assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
+                     IDNS_TagFriend | IDNS_OrdinaryFriend |
+                     IDNS_LocalExtern)) &&
+           "namespace includes neither ordinary nor tag");
+    assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
+                       IDNS_TagFriend | IDNS_OrdinaryFriend |
+                       IDNS_LocalExtern)) &&
+           "namespace includes other than ordinary or tag");
+
+    Decl *Prev = getPreviousDecl();
+    IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
+
+    if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
+      IdentifierNamespace |= IDNS_TagFriend;
+      if (PerformFriendInjection ||
+          (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
+        IdentifierNamespace |= IDNS_Tag | IDNS_Type;
+    }
+
+    if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
+      IdentifierNamespace |= IDNS_OrdinaryFriend;
+      if (PerformFriendInjection ||
+          (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
+        IdentifierNamespace |= IDNS_Ordinary;
+    }
+  }
+
+  enum FriendObjectKind {
+    FOK_None,      ///< Not a friend object.
+    FOK_Declared,  ///< A friend of a previously-declared entity.
+    FOK_Undeclared ///< A friend of a previously-undeclared entity.
+  };
+
+  /// \brief Determines whether this declaration is the object of a
+  /// friend declaration and, if so, what kind.
+  ///
+  /// There is currently no direct way to find the associated FriendDecl.
+  FriendObjectKind getFriendObjectKind() const {
+    unsigned mask =
+        (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
+    if (!mask) return FOK_None;
+    return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared
+                                                             : FOK_Undeclared);
+  }
+
+  /// Specifies that this declaration is a C++ overloaded non-member.
+  void setNonMemberOperator() {
+    assert(getKind() == Function || getKind() == FunctionTemplate);
+    assert((IdentifierNamespace & IDNS_Ordinary) &&
+           "visible non-member operators should be in ordinary namespace");
+    IdentifierNamespace |= IDNS_NonMemberOperator;
+  }
+
+  static bool classofKind(Kind K) { return true; }
+  static DeclContext *castToDeclContext(const Decl *);
+  static Decl *castFromDeclContext(const DeclContext *);
+
+  void print(raw_ostream &Out, unsigned Indentation = 0,
+             bool PrintInstantiation = false) const;
+  void print(raw_ostream &Out, const PrintingPolicy &Policy,
+             unsigned Indentation = 0, bool PrintInstantiation = false) const;
+  static void printGroup(Decl** Begin, unsigned NumDecls,
+                         raw_ostream &Out, const PrintingPolicy &Policy,
+                         unsigned Indentation = 0);
+  // Debuggers don't usually respect default arguments.
+  void dump() const;
+  // Same as dump(), but forces color printing.
+  void dumpColor() const;
+  void dump(raw_ostream &Out) const;
+
+  /// \brief Looks through the Decl's underlying type to extract a FunctionType
+  /// when possible. Will return null if the type underlying the Decl does not
+  /// have a FunctionType.
+  const FunctionType *getFunctionType(bool BlocksToo = true) const;
+
+private:
+  void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
+  void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
+                           ASTContext &Ctx);
+
+protected:
+  ASTMutationListener *getASTMutationListener() const;
+};
+
+/// \brief Determine whether two declarations declare the same entity.
+inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
+  if (!D1 || !D2)
+    return false;
+  
+  if (D1 == D2)
+    return true;
+  
+  return D1->getCanonicalDecl() == D2->getCanonicalDecl();
+}
+  
+/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
+/// doing something to a specific decl.
+class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
+  const Decl *TheDecl;
+  SourceLocation Loc;
+  SourceManager &SM;
+  const char *Message;
+public:
+  PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
+                       SourceManager &sm, const char *Msg)
+  : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
+
+  void print(raw_ostream &OS) const override;
+};
+
+typedef MutableArrayRef<NamedDecl *> DeclContextLookupResult;
+
+typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult;
+
+/// DeclContext - This is used only as base class of specific decl types that
+/// can act as declaration contexts. These decls are (only the top classes
+/// that directly derive from DeclContext are mentioned, not their subclasses):
+///
+///   TranslationUnitDecl
+///   NamespaceDecl
+///   FunctionDecl
+///   TagDecl
+///   ObjCMethodDecl
+///   ObjCContainerDecl
+///   LinkageSpecDecl
+///   BlockDecl
+///
+class DeclContext {
+  /// DeclKind - This indicates which class this is.
+  unsigned DeclKind : 8;
+
+  /// \brief Whether this declaration context also has some external
+  /// storage that contains additional declarations that are lexically
+  /// part of this context.
+  mutable bool ExternalLexicalStorage : 1;
+
+  /// \brief Whether this declaration context also has some external
+  /// storage that contains additional declarations that are visible
+  /// in this context.
+  mutable bool ExternalVisibleStorage : 1;
+
+  /// \brief Whether this declaration context has had external visible
+  /// storage added since the last lookup. In this case, \c LookupPtr's
+  /// invariant may not hold and needs to be fixed before we perform
+  /// another lookup.
+  mutable bool NeedToReconcileExternalVisibleStorage : 1;
+
+  /// \brief Pointer to the data structure used to lookup declarations
+  /// within this context (or a DependentStoredDeclsMap if this is a
+  /// dependent context), and a bool indicating whether we have lazily
+  /// omitted any declarations from the map. We maintain the invariant
+  /// that, if the map contains an entry for a DeclarationName (and we
+  /// haven't lazily omitted anything), then it contains all relevant
+  /// entries for that name.
+  mutable llvm::PointerIntPair<StoredDeclsMap*, 1, bool> LookupPtr;
+
+protected:
+  /// FirstDecl - The first declaration stored within this declaration
+  /// context.
+  mutable Decl *FirstDecl;
+
+  /// LastDecl - The last declaration stored within this declaration
+  /// context. FIXME: We could probably cache this value somewhere
+  /// outside of the DeclContext, to reduce the size of DeclContext by
+  /// another pointer.
+  mutable Decl *LastDecl;
+
+  friend class ExternalASTSource;
+  friend class ASTDeclReader;
+  friend class ASTWriter;
+
+  /// \brief Build up a chain of declarations.
+  ///
+  /// \returns the first/last pair of declarations.
+  static std::pair<Decl *, Decl *>
+  BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
+
+  DeclContext(Decl::Kind K)
+      : DeclKind(K), ExternalLexicalStorage(false),
+        ExternalVisibleStorage(false),
+        NeedToReconcileExternalVisibleStorage(false), LookupPtr(nullptr, false),
+        FirstDecl(nullptr), LastDecl(nullptr) {}
+
+public:
+  ~DeclContext();
+
+  Decl::Kind getDeclKind() const {
+    return static_cast<Decl::Kind>(DeclKind);
+  }
+  const char *getDeclKindName() const;
+
+  /// getParent - Returns the containing DeclContext.
+  DeclContext *getParent() {
+    return cast<Decl>(this)->getDeclContext();
+  }
+  const DeclContext *getParent() const {
+    return const_cast<DeclContext*>(this)->getParent();
+  }
+
+  /// getLexicalParent - Returns the containing lexical DeclContext. May be
+  /// different from getParent, e.g.:
+  ///
+  ///   namespace A {
+  ///      struct S;
+  ///   }
+  ///   struct A::S {}; // getParent() == namespace 'A'
+  ///                   // getLexicalParent() == translation unit
+  ///
+  DeclContext *getLexicalParent() {
+    return cast<Decl>(this)->getLexicalDeclContext();
+  }
+  const DeclContext *getLexicalParent() const {
+    return const_cast<DeclContext*>(this)->getLexicalParent();
+  }
+
+  DeclContext *getLookupParent();
+
+  const DeclContext *getLookupParent() const {
+    return const_cast<DeclContext*>(this)->getLookupParent();
+  }
+
+  ASTContext &getParentASTContext() const {
+    return cast<Decl>(this)->getASTContext();
+  }
+
+  bool isClosure() const {
+    return DeclKind == Decl::Block;
+  }
+
+  bool isObjCContainer() const {
+    switch (DeclKind) {
+        case Decl::ObjCCategory:
+        case Decl::ObjCCategoryImpl:
+        case Decl::ObjCImplementation:
+        case Decl::ObjCInterface:
+        case Decl::ObjCProtocol:
+            return true;
+    }
+    return false;
+  }
+
+  bool isFunctionOrMethod() const {
+    switch (DeclKind) {
+    case Decl::Block:
+    case Decl::Captured:
+    case Decl::ObjCMethod:
+      return true;
+    default:
+      return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction;
+    }
+  }
+
+  bool isFileContext() const {
+    return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
+  }
+
+  bool isTranslationUnit() const {
+    return DeclKind == Decl::TranslationUnit;
+  }
+
+  bool isRecord() const {
+    return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord;
+  }
+
+  bool isNamespace() const {
+    return DeclKind == Decl::Namespace;
+  }
+
+  bool isStdNamespace() const;
+
+  bool isInlineNamespace() const;
+
+  /// \brief Determines whether this context is dependent on a
+  /// template parameter.
+  bool isDependentContext() const;
+
+  /// isTransparentContext - Determines whether this context is a
+  /// "transparent" context, meaning that the members declared in this
+  /// context are semantically declared in the nearest enclosing
+  /// non-transparent (opaque) context but are lexically declared in
+  /// this context. For example, consider the enumerators of an
+  /// enumeration type:
+  /// @code
+  /// enum E {
+  ///   Val1
+  /// };
+  /// @endcode
+  /// Here, E is a transparent context, so its enumerator (Val1) will
+  /// appear (semantically) that it is in the same context of E.
+  /// Examples of transparent contexts include: enumerations (except for
+  /// C++0x scoped enums), and C++ linkage specifications.
+  bool isTransparentContext() const;
+
+  /// \brief Determines whether this context or some of its ancestors is a
+  /// linkage specification context that specifies C linkage.
+  bool isExternCContext() const;
+
+  /// \brief Determines whether this context or some of its ancestors is a
+  /// linkage specification context that specifies C++ linkage.
+  bool isExternCXXContext() const;
+
+  /// \brief Determine whether this declaration context is equivalent
+  /// to the declaration context DC.
+  bool Equals(const DeclContext *DC) const {
+    return DC && this->getPrimaryContext() == DC->getPrimaryContext();
+  }
+
+  /// \brief Determine whether this declaration context encloses the
+  /// declaration context DC.
+  bool Encloses(const DeclContext *DC) const;
+
+  /// \brief Find the nearest non-closure ancestor of this context,
+  /// i.e. the innermost semantic parent of this context which is not
+  /// a closure.  A context may be its own non-closure ancestor.
+  Decl *getNonClosureAncestor();
+  const Decl *getNonClosureAncestor() const {
+    return const_cast<DeclContext*>(this)->getNonClosureAncestor();
+  }
+
+  /// getPrimaryContext - There may be many different
+  /// declarations of the same entity (including forward declarations
+  /// of classes, multiple definitions of namespaces, etc.), each with
+  /// a different set of declarations. This routine returns the
+  /// "primary" DeclContext structure, which will contain the
+  /// information needed to perform name lookup into this context.
+  DeclContext *getPrimaryContext();
+  const DeclContext *getPrimaryContext() const {
+    return const_cast<DeclContext*>(this)->getPrimaryContext();
+  }
+
+  /// getRedeclContext - Retrieve the context in which an entity conflicts with
+  /// other entities of the same name, or where it is a redeclaration if the
+  /// two entities are compatible. This skips through transparent contexts.
+  DeclContext *getRedeclContext();
+  const DeclContext *getRedeclContext() const {
+    return const_cast<DeclContext *>(this)->getRedeclContext();
+  }
+
+  /// \brief Retrieve the nearest enclosing namespace context.
+  DeclContext *getEnclosingNamespaceContext();
+  const DeclContext *getEnclosingNamespaceContext() const {
+    return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
+  }
+
+  /// \brief Test if this context is part of the enclosing namespace set of
+  /// the context NS, as defined in C++0x [namespace.def]p9. If either context
+  /// isn't a namespace, this is equivalent to Equals().
+  ///
+  /// The enclosing namespace set of a namespace is the namespace and, if it is
+  /// inline, its enclosing namespace, recursively.
+  bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
+
+  /// \brief Collects all of the declaration contexts that are semantically
+  /// connected to this declaration context.
+  ///
+  /// For declaration contexts that have multiple semantically connected but
+  /// syntactically distinct contexts, such as C++ namespaces, this routine 
+  /// retrieves the complete set of such declaration contexts in source order.
+  /// For example, given:
+  ///
+  /// \code
+  /// namespace N {
+  ///   int x;
+  /// }
+  /// namespace N {
+  ///   int y;
+  /// }
+  /// \endcode
+  ///
+  /// The \c Contexts parameter will contain both definitions of N.
+  ///
+  /// \param Contexts Will be cleared and set to the set of declaration
+  /// contexts that are semanticaly connected to this declaration context,
+  /// in source order, including this context (which may be the only result,
+  /// for non-namespace contexts).
+  void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts);
+
+  /// decl_iterator - Iterates through the declarations stored
+  /// within this context.
+  class decl_iterator {
+    /// Current - The current declaration.
+    Decl *Current;
+
+  public:
+    typedef Decl *value_type;
+    typedef const value_type &reference;
+    typedef const value_type *pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    decl_iterator() : Current(nullptr) { }
+    explicit decl_iterator(Decl *C) : Current(C) { }
+
+    reference operator*() const { return Current; }
+    // This doesn't meet the iterator requirements, but it's convenient
+    value_type operator->() const { return Current; }
+
+    decl_iterator& operator++() {
+      Current = Current->getNextDeclInContext();
+      return *this;
+    }
+
+    decl_iterator operator++(int) {
+      decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(decl_iterator x, decl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(decl_iterator x, decl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+
+  /// decls_begin/decls_end - Iterate over the declarations stored in
+  /// this context.
+  decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
+  decl_iterator decls_begin() const;
+  decl_iterator decls_end() const { return decl_iterator(); }
+  bool decls_empty() const;
+
+  /// noload_decls_begin/end - Iterate over the declarations stored in this
+  /// context that are currently loaded; don't attempt to retrieve anything
+  /// from an external source.
+  decl_range noload_decls() const {
+    return decl_range(noload_decls_begin(), noload_decls_end());
+  }
+  decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
+  decl_iterator noload_decls_end() const { return decl_iterator(); }
+
+  /// specific_decl_iterator - Iterates over a subrange of
+  /// declarations stored in a DeclContext, providing only those that
+  /// are of type SpecificDecl (or a class derived from it). This
+  /// iterator is used, for example, to provide iteration over just
+  /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
+  template<typename SpecificDecl>
+  class specific_decl_iterator {
+    /// Current - The current, underlying declaration iterator, which
+    /// will either be NULL or will point to a declaration of
+    /// type SpecificDecl.
+    DeclContext::decl_iterator Current;
+
+    /// SkipToNextDecl - Advances the current position up to the next
+    /// declaration of type SpecificDecl that also meets the criteria
+    /// required by Acceptable.
+    void SkipToNextDecl() {
+      while (*Current && !isa<SpecificDecl>(*Current))
+        ++Current;
+    }
+
+  public:
+    typedef SpecificDecl *value_type;
+    // TODO: Add reference and pointer typedefs (with some appropriate proxy
+    // type) if we ever have a need for them.
+    typedef void reference;
+    typedef void pointer;
+    typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
+      difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    specific_decl_iterator() : Current() { }
+
+    /// specific_decl_iterator - Construct a new iterator over a
+    /// subset of the declarations the range [C,
+    /// end-of-declarations). If A is non-NULL, it is a pointer to a
+    /// member function of SpecificDecl that should return true for
+    /// all of the SpecificDecl instances that will be in the subset
+    /// of iterators. For example, if you want Objective-C instance
+    /// methods, SpecificDecl will be ObjCMethodDecl and A will be
+    /// &ObjCMethodDecl::isInstanceMethod.
+    explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
+      SkipToNextDecl();
+    }
+
+    value_type operator*() const { return cast<SpecificDecl>(*Current); }
+    // This doesn't meet the iterator requirements, but it's convenient
+    value_type operator->() const { return **this; }
+
+    specific_decl_iterator& operator++() {
+      ++Current;
+      SkipToNextDecl();
+      return *this;
+    }
+
+    specific_decl_iterator operator++(int) {
+      specific_decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(const specific_decl_iterator& x,
+                           const specific_decl_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool operator!=(const specific_decl_iterator& x,
+                           const specific_decl_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// \brief Iterates over a filtered subrange of declarations stored
+  /// in a DeclContext.
+  ///
+  /// This iterator visits only those declarations that are of type
+  /// SpecificDecl (or a class derived from it) and that meet some
+  /// additional run-time criteria. This iterator is used, for
+  /// example, to provide access to the instance methods within an
+  /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
+  /// Acceptable = ObjCMethodDecl::isInstanceMethod).
+  template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
+  class filtered_decl_iterator {
+    /// Current - The current, underlying declaration iterator, which
+    /// will either be NULL or will point to a declaration of
+    /// type SpecificDecl.
+    DeclContext::decl_iterator Current;
+
+    /// SkipToNextDecl - Advances the current position up to the next
+    /// declaration of type SpecificDecl that also meets the criteria
+    /// required by Acceptable.
+    void SkipToNextDecl() {
+      while (*Current &&
+             (!isa<SpecificDecl>(*Current) ||
+              (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
+        ++Current;
+    }
+
+  public:
+    typedef SpecificDecl *value_type;
+    // TODO: Add reference and pointer typedefs (with some appropriate proxy
+    // type) if we ever have a need for them.
+    typedef void reference;
+    typedef void pointer;
+    typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
+      difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    filtered_decl_iterator() : Current() { }
+
+    /// filtered_decl_iterator - Construct a new iterator over a
+    /// subset of the declarations the range [C,
+    /// end-of-declarations). If A is non-NULL, it is a pointer to a
+    /// member function of SpecificDecl that should return true for
+    /// all of the SpecificDecl instances that will be in the subset
+    /// of iterators. For example, if you want Objective-C instance
+    /// methods, SpecificDecl will be ObjCMethodDecl and A will be
+    /// &ObjCMethodDecl::isInstanceMethod.
+    explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
+      SkipToNextDecl();
+    }
+
+    value_type operator*() const { return cast<SpecificDecl>(*Current); }
+    value_type operator->() const { return cast<SpecificDecl>(*Current); }
+
+    filtered_decl_iterator& operator++() {
+      ++Current;
+      SkipToNextDecl();
+      return *this;
+    }
+
+    filtered_decl_iterator operator++(int) {
+      filtered_decl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(const filtered_decl_iterator& x,
+                           const filtered_decl_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool operator!=(const filtered_decl_iterator& x,
+                           const filtered_decl_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  /// @brief Add the declaration D into this context.
+  ///
+  /// This routine should be invoked when the declaration D has first
+  /// been declared, to place D into the context where it was
+  /// (lexically) defined. Every declaration must be added to one
+  /// (and only one!) context, where it can be visited via
+  /// [decls_begin(), decls_end()). Once a declaration has been added
+  /// to its lexical context, the corresponding DeclContext owns the
+  /// declaration.
+  ///
+  /// If D is also a NamedDecl, it will be made visible within its
+  /// semantic context via makeDeclVisibleInContext.
+  void addDecl(Decl *D);
+
+  /// @brief Add the declaration D into this context, but suppress
+  /// searches for external declarations with the same name.
+  ///
+  /// Although analogous in function to addDecl, this removes an
+  /// important check.  This is only useful if the Decl is being
+  /// added in response to an external search; in all other cases,
+  /// addDecl() is the right function to use.
+  /// See the ASTImporter for use cases.
+  void addDeclInternal(Decl *D);
+
+  /// @brief Add the declaration D to this context without modifying
+  /// any lookup tables.
+  ///
+  /// This is useful for some operations in dependent contexts where
+  /// the semantic context might not be dependent;  this basically
+  /// only happens with friends.
+  void addHiddenDecl(Decl *D);
+
+  /// @brief Removes a declaration from this context.
+  void removeDecl(Decl *D);
+    
+  /// @brief Checks whether a declaration is in this context.
+  bool containsDecl(Decl *D) const;
+
+  /// lookup_iterator - An iterator that provides access to the results
+  /// of looking up a name within this context.
+  typedef NamedDecl **lookup_iterator;
+
+  /// lookup_const_iterator - An iterator that provides non-mutable
+  /// access to the results of lookup up a name within this context.
+  typedef NamedDecl * const * lookup_const_iterator;
+
+  typedef DeclContextLookupResult lookup_result;
+  typedef DeclContextLookupConstResult lookup_const_result;
+
+  /// lookup - Find the declarations (if any) with the given Name in
+  /// this context. Returns a range of iterators that contains all of
+  /// the declarations with this name, with object, function, member,
+  /// and enumerator names preceding any tag name. Note that this
+  /// routine will not look into parent contexts.
+  lookup_result lookup(DeclarationName Name);
+  lookup_const_result lookup(DeclarationName Name) const {
+    return const_cast<DeclContext*>(this)->lookup(Name);
+  }
+
+  /// \brief Find the declarations with the given name that are visible
+  /// within this context; don't attempt to retrieve anything from an
+  /// external source.
+  lookup_result noload_lookup(DeclarationName Name);
+
+  /// \brief A simplistic name lookup mechanism that performs name lookup
+  /// into this declaration context without consulting the external source.
+  ///
+  /// This function should almost never be used, because it subverts the
+  /// usual relationship between a DeclContext and the external source.
+  /// See the ASTImporter for the (few, but important) use cases.
+  ///
+  /// FIXME: This is very inefficient; replace uses of it with uses of
+  /// noload_lookup.
+  void localUncachedLookup(DeclarationName Name,
+                           SmallVectorImpl<NamedDecl *> &Results);
+
+  /// @brief Makes a declaration visible within this context.
+  ///
+  /// This routine makes the declaration D visible to name lookup
+  /// within this context and, if this is a transparent context,
+  /// within its parent contexts up to the first enclosing
+  /// non-transparent context. Making a declaration visible within a
+  /// context does not transfer ownership of a declaration, and a
+  /// declaration can be visible in many contexts that aren't its
+  /// lexical context.
+  ///
+  /// If D is a redeclaration of an existing declaration that is
+  /// visible from this context, as determined by
+  /// NamedDecl::declarationReplaces, the previous declaration will be
+  /// replaced with D.
+  void makeDeclVisibleInContext(NamedDecl *D);
+
+  /// all_lookups_iterator - An iterator that provides a view over the results
+  /// of looking up every possible name.
+  class all_lookups_iterator;
+
+  typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
+
+  lookups_range lookups() const;
+  lookups_range noload_lookups() const;
+
+  /// \brief Iterators over all possible lookups within this context.
+  all_lookups_iterator lookups_begin() const;
+  all_lookups_iterator lookups_end() const;
+
+  /// \brief Iterators over all possible lookups within this context that are
+  /// currently loaded; don't attempt to retrieve anything from an external
+  /// source.
+  all_lookups_iterator noload_lookups_begin() const;
+  all_lookups_iterator noload_lookups_end() const;
+
+  typedef llvm::iterator_range<UsingDirectiveDecl * const *> udir_range;
+
+  udir_range using_directives() const;
+
+  // These are all defined in DependentDiagnostic.h.
+  class ddiag_iterator;
+  typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
+
+  inline ddiag_range ddiags() const;
+
+  // Low-level accessors
+    
+  /// \brief Mark the lookup table as needing to be built.  This should be
+  /// used only if setHasExternalLexicalStorage() has been called on any
+  /// decl context for which this is the primary context.
+  void setMustBuildLookupTable() {
+    LookupPtr.setInt(true);
+  }
+
+  /// \brief Retrieve the internal representation of the lookup structure.
+  /// This may omit some names if we are lazily building the structure.
+  StoredDeclsMap *getLookupPtr() const { return LookupPtr.getPointer(); }
+
+  /// \brief Ensure the lookup structure is fully-built and return it.
+  StoredDeclsMap *buildLookup();
+
+  /// \brief Whether this DeclContext has external storage containing
+  /// additional declarations that are lexically in this context.
+  bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
+
+  /// \brief State whether this DeclContext has external storage for
+  /// declarations lexically in this context.
+  void setHasExternalLexicalStorage(bool ES = true) {
+    ExternalLexicalStorage = ES;
+  }
+
+  /// \brief Whether this DeclContext has external storage containing
+  /// additional declarations that are visible in this context.
+  bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
+
+  /// \brief State whether this DeclContext has external storage for
+  /// declarations visible in this context.
+  void setHasExternalVisibleStorage(bool ES = true) {
+    ExternalVisibleStorage = ES;
+    if (ES && LookupPtr.getPointer())
+      NeedToReconcileExternalVisibleStorage = true;
+  }
+
+  /// \brief Determine whether the given declaration is stored in the list of
+  /// declarations lexically within this context.
+  bool isDeclInLexicalTraversal(const Decl *D) const {
+    return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || 
+                 D == LastDecl);
+  }
+
+  static bool classof(const Decl *D);
+  static bool classof(const DeclContext *D) { return true; }
+
+  void dumpDeclContext() const;
+  void dumpLookups() const;
+  void dumpLookups(llvm::raw_ostream &OS) const;
+
+private:
+  void reconcileExternalVisibleStorage() const;
+  void LoadLexicalDeclsFromExternalStorage() const;
+
+  /// @brief Makes a declaration visible within this context, but
+  /// suppresses searches for external declarations with the same
+  /// name.
+  ///
+  /// Analogous to makeDeclVisibleInContext, but for the exclusive
+  /// use of addDeclInternal().
+  void makeDeclVisibleInContextInternal(NamedDecl *D);
+
+  friend class DependentDiagnostic;
+  StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+
+  template<decl_iterator (DeclContext::*Begin)() const,
+           decl_iterator (DeclContext::*End)() const>
+  void buildLookupImpl(DeclContext *DCtx);
+  void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
+                                         bool Rediscoverable);
+  void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal);
+};
+
+inline bool Decl::isTemplateParameter() const {
+  return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
+         getKind() == TemplateTemplateParm;
+}
+
+// Specialization selected when ToTy is not a known subclass of DeclContext.
+template <class ToTy,
+          bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
+struct cast_convert_decl_context {
+  static const ToTy *doit(const DeclContext *Val) {
+    return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
+  }
+
+  static ToTy *doit(DeclContext *Val) {
+    return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
+  }
+};
+
+// Specialization selected when ToTy is a known subclass of DeclContext.
+template <class ToTy>
+struct cast_convert_decl_context<ToTy, true> {
+  static const ToTy *doit(const DeclContext *Val) {
+    return static_cast<const ToTy*>(Val);
+  }
+
+  static ToTy *doit(DeclContext *Val) {
+    return static_cast<ToTy*>(Val);
+  }
+};
+
+
+} // end clang.
+
+namespace llvm {
+
+/// isa<T>(DeclContext*)
+template <typename To>
+struct isa_impl<To, ::clang::DeclContext> {
+  static bool doit(const ::clang::DeclContext &Val) {
+    return To::classofKind(Val.getDeclKind());
+  }
+};
+
+/// cast<T>(DeclContext*)
+template<class ToTy>
+struct cast_convert_val<ToTy,
+                        const ::clang::DeclContext,const ::clang::DeclContext> {
+  static const ToTy &doit(const ::clang::DeclContext &Val) {
+    return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
+  static ToTy &doit(::clang::DeclContext &Val) {
+    return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy,
+                     const ::clang::DeclContext*, const ::clang::DeclContext*> {
+  static const ToTy *doit(const ::clang::DeclContext *Val) {
+    return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+  }
+};
+template<class ToTy>
+struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
+  static ToTy *doit(::clang::DeclContext *Val) {
+    return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
+  }
+};
+
+/// Implement cast_convert_val for Decl -> DeclContext conversions.
+template<class FromTy>
+struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
+  static ::clang::DeclContext &doit(const FromTy &Val) {
+    return *FromTy::castToDeclContext(&Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
+  static ::clang::DeclContext *doit(const FromTy *Val) {
+    return FromTy::castToDeclContext(Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
+  static const ::clang::DeclContext &doit(const FromTy &Val) {
+    return *FromTy::castToDeclContext(&Val);
+  }
+};
+
+template<class FromTy>
+struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
+  static const ::clang::DeclContext *doit(const FromTy *Val) {
+    return FromTy::castToDeclContext(Val);
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
new file mode 100644
index 0000000..72fad7c
--- /dev/null
+++ b/include/clang/AST/DeclCXX.h
@@ -0,0 +1,3195 @@
+//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the C++ Decl subclasses, other than those for templates
+/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLCXX_H
+#define LLVM_CLANG_AST_DECLCXX_H
+
+#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/LambdaCapture.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+class ClassTemplateDecl;
+class ClassTemplateSpecializationDecl;
+class CXXBasePath;
+class CXXBasePaths;
+class CXXConstructorDecl;
+class CXXConversionDecl;
+class CXXDestructorDecl;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class CXXMemberLookupCriteria;
+class CXXFinalOverriderMap;
+class CXXIndirectPrimaryBaseSet;
+class FriendDecl;
+class LambdaExpr;
+class UsingDecl;
+
+/// \brief Represents any kind of function declaration, whether it is a
+/// concrete function or a function template.
+class AnyFunctionDecl {
+  NamedDecl *Function;
+
+  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+
+public:
+  AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
+  AnyFunctionDecl(FunctionTemplateDecl *FTD);
+
+  /// \brief Implicily converts any function or function template into a
+  /// named declaration.
+  operator NamedDecl *() const { return Function; }
+
+  /// \brief Retrieve the underlying function or function template.
+  NamedDecl *get() const { return Function; }
+
+  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
+    return AnyFunctionDecl(ND);
+  }
+};
+
+} // end namespace clang
+
+namespace llvm {
+  // Provide PointerLikeTypeTraits for non-cvr pointers.
+  template<>
+  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+  public:
+    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+      return F.get();
+    }
+    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+      return ::clang::AnyFunctionDecl::getFromNamedDecl(
+                                      static_cast< ::clang::NamedDecl*>(P));
+    }
+
+    enum { NumLowBitsAvailable = 2 };
+  };
+
+} // end namespace llvm
+
+namespace clang {
+
+/// \brief Represents an access specifier followed by colon ':'.
+///
+/// An objects of this class represents sugar for the syntactic occurrence
+/// of an access specifier followed by a colon in the list of member
+/// specifiers of a C++ class definition.
+///
+/// Note that they do not represent other uses of access specifiers,
+/// such as those occurring in a list of base specifiers.
+/// Also note that this class has nothing to do with so-called
+/// "access declarations" (C++98 11.3 [class.access.dcl]).
+class AccessSpecDecl : public Decl {
+  virtual void anchor();
+  /// \brief The location of the ':'.
+  SourceLocation ColonLoc;
+
+  AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
+                 SourceLocation ASLoc, SourceLocation ColonLoc)
+    : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
+    setAccess(AS);
+  }
+  AccessSpecDecl(EmptyShell Empty)
+    : Decl(AccessSpec, Empty) { }
+public:
+  /// \brief The location of the access specifier.
+  SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
+  /// \brief Sets the location of the access specifier.
+  void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
+
+  /// \brief The location of the colon following the access specifier.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  /// \brief Sets the location of the colon.
+  void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(getAccessSpecifierLoc(), getColonLoc());
+  }
+
+  static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
+                                DeclContext *DC, SourceLocation ASLoc,
+                                SourceLocation ColonLoc) {
+    return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+  }
+  static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == AccessSpec; }
+};
+
+
+/// \brief Represents a base class of a C++ class.
+///
+/// Each CXXBaseSpecifier represents a single, direct base class (or
+/// struct) of a C++ class (or struct). It specifies the type of that
+/// base class, whether it is a virtual or non-virtual base, and what
+/// level of access (public, protected, private) is used for the
+/// derivation. For example:
+///
+/// \code
+///   class A { };
+///   class B { };
+///   class C : public virtual A, protected B { };
+/// \endcode
+///
+/// In this code, C will have two CXXBaseSpecifiers, one for "public
+/// virtual A" and the other for "protected B".
+class CXXBaseSpecifier {
+  /// \brief The source code range that covers the full base
+  /// specifier, including the "virtual" (if present) and access
+  /// specifier (if present).
+  SourceRange Range;
+
+  /// \brief The source location of the ellipsis, if this is a pack
+  /// expansion.
+  SourceLocation EllipsisLoc;
+
+  /// \brief Whether this is a virtual base class or not.
+  bool Virtual : 1;
+
+  /// \brief Whether this is the base of a class (true) or of a struct (false).
+  ///
+  /// This determines the mapping from the access specifier as written in the
+  /// source code to the access specifier used for semantic analysis.
+  bool BaseOfClass : 1;
+
+  /// \brief Access specifier as written in the source code (may be AS_none).
+  ///
+  /// The actual type of data stored here is an AccessSpecifier, but we use
+  /// "unsigned" here to work around a VC++ bug.
+  unsigned Access : 2;
+
+  /// \brief Whether the class contains a using declaration
+  /// to inherit the named class's constructors.
+  bool InheritConstructors : 1;
+
+  /// \brief The type of the base class.
+  ///
+  /// This will be a class or struct (or a typedef of such). The source code
+  /// range does not include the \c virtual or the access specifier.
+  TypeSourceInfo *BaseTypeInfo;
+
+public:
+  CXXBaseSpecifier() { }
+
+  CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
+                   TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
+    : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
+      Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
+
+  /// \brief Retrieves the source range that contains the entire base specifier.
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
+  /// \brief Determines whether the base class is a virtual base class (or not).
+  bool isVirtual() const { return Virtual; }
+
+  /// \brief Determine whether this base class is a base of a class declared
+  /// with the 'class' keyword (vs. one declared with the 'struct' keyword).
+  bool isBaseOfClass() const { return BaseOfClass; }
+
+  /// \brief Determine whether this base specifier is a pack expansion.
+  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+  /// \brief Determine whether this base class's constructors get inherited.
+  bool getInheritConstructors() const { return InheritConstructors; }
+
+  /// \brief Set that this base class's constructors should be inherited.
+  void setInheritConstructors(bool Inherit = true) {
+    InheritConstructors = Inherit;
+  }
+
+  /// \brief For a pack expansion, determine the location of the ellipsis.
+  SourceLocation getEllipsisLoc() const {
+    return EllipsisLoc;
+  }
+
+  /// \brief Returns the access specifier for this base specifier. 
+  ///
+  /// This is the actual base specifier as used for semantic analysis, so
+  /// the result can never be AS_none. To retrieve the access specifier as
+  /// written in the source code, use getAccessSpecifierAsWritten().
+  AccessSpecifier getAccessSpecifier() const {
+    if ((AccessSpecifier)Access == AS_none)
+      return BaseOfClass? AS_private : AS_public;
+    else
+      return (AccessSpecifier)Access;
+  }
+
+  /// \brief Retrieves the access specifier as written in the source code
+  /// (which may mean that no access specifier was explicitly written).
+  ///
+  /// Use getAccessSpecifier() to retrieve the access specifier for use in
+  /// semantic analysis.
+  AccessSpecifier getAccessSpecifierAsWritten() const {
+    return (AccessSpecifier)Access;
+  }
+
+  /// \brief Retrieves the type of the base class.
+  ///
+  /// This type will always be an unqualified class type.
+  QualType getType() const {
+    return BaseTypeInfo->getType().getUnqualifiedType();
+  }
+
+  /// \brief Retrieves the type and source location of the base class.
+  TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
+};
+
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+  llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+  LazyDefinitionDataPtr update() {
+    if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+      if (Canon->isCanonicalDecl())
+        Canon->getMostRecentDecl();
+      else
+        // Declaration isn't canonical any more;
+        // update it and perform path compression.
+        *this = Canon->getPreviousDecl()->DefinitionData.update();
+    }
+    return *this;
+  }
+
+public:
+  LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+  LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+  T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+  T *get() { return update().getNotUpdated(); }
+};
+
+/// \brief Represents a C++ struct/union/class.
+class CXXRecordDecl : public RecordDecl {
+
+  friend void TagDecl::startDefinition();
+
+  /// Values used in DefinitionData fields to represent special members.
+  enum SpecialMemberFlags {
+    SMF_DefaultConstructor = 0x1,
+    SMF_CopyConstructor = 0x2,
+    SMF_MoveConstructor = 0x4,
+    SMF_CopyAssignment = 0x8,
+    SMF_MoveAssignment = 0x10,
+    SMF_Destructor = 0x20,
+    SMF_All = 0x3f
+  };
+
+  struct DefinitionData {
+    DefinitionData(CXXRecordDecl *D);
+
+    /// \brief True if this class has any user-declared constructors.
+    bool UserDeclaredConstructor : 1;
+
+    /// \brief The user-declared special members which this class has.
+    unsigned UserDeclaredSpecialMembers : 6;
+
+    /// \brief True when this class is an aggregate.
+    bool Aggregate : 1;
+
+    /// \brief True when this class is a POD-type.
+    bool PlainOldData : 1;
+
+    /// true when this class is empty for traits purposes,
+    /// i.e. has no data members other than 0-width bit-fields, has no
+    /// virtual function/base, and doesn't inherit from a non-empty
+    /// class. Doesn't take union-ness into account.
+    bool Empty : 1;
+
+    /// \brief True when this class is polymorphic, i.e., has at
+    /// least one virtual member or derives from a polymorphic class.
+    bool Polymorphic : 1;
+
+    /// \brief True when this class is abstract, i.e., has at least
+    /// one pure virtual function, (that can come from a base class).
+    bool Abstract : 1;
+
+    /// \brief True when this class has standard layout.
+    ///
+    /// C++11 [class]p7.  A standard-layout class is a class that:
+    /// * has no non-static data members of type non-standard-layout class (or
+    ///   array of such types) or reference,
+    /// * has no virtual functions (10.3) and no virtual base classes (10.1),
+    /// * has the same access control (Clause 11) for all non-static data
+    ///   members
+    /// * has no non-standard-layout base classes,
+    /// * either has no non-static data members in the most derived class and at
+    ///   most one base class with non-static data members, or has no base
+    ///   classes with non-static data members, and
+    /// * has no base classes of the same type as the first non-static data
+    ///   member.
+    bool IsStandardLayout : 1;
+
+    /// \brief True when there are no non-empty base classes.
+    ///
+    /// This is a helper bit of state used to implement IsStandardLayout more
+    /// efficiently.
+    bool HasNoNonEmptyBases : 1;
+
+    /// \brief True when there are private non-static data members.
+    bool HasPrivateFields : 1;
+
+    /// \brief True when there are protected non-static data members.
+    bool HasProtectedFields : 1;
+
+    /// \brief True when there are private non-static data members.
+    bool HasPublicFields : 1;
+
+    /// \brief True if this class (or any subobject) has mutable fields.
+    bool HasMutableFields : 1;
+
+    /// \brief True if this class (or any nested anonymous struct or union)
+    /// has variant members.
+    bool HasVariantMembers : 1;
+
+    /// \brief True if there no non-field members declared by the user.
+    bool HasOnlyCMembers : 1;
+
+    /// \brief True if any field has an in-class initializer, including those
+    /// within anonymous unions or structs.
+    bool HasInClassInitializer : 1;
+
+    /// \brief True if any field is of reference type, and does not have an
+    /// in-class initializer.
+    ///
+    /// In this case, value-initialization of this class is illegal in C++98
+    /// even if the class has a trivial default constructor.
+    bool HasUninitializedReferenceMember : 1;
+
+    /// \brief These flags are \c true if a defaulted corresponding special
+    /// member can't be fully analyzed without performing overload resolution.
+    /// @{
+    bool NeedOverloadResolutionForMoveConstructor : 1;
+    bool NeedOverloadResolutionForMoveAssignment : 1;
+    bool NeedOverloadResolutionForDestructor : 1;
+    /// @}
+
+    /// \brief These flags are \c true if an implicit defaulted corresponding
+    /// special member would be defined as deleted.
+    /// @{
+    bool DefaultedMoveConstructorIsDeleted : 1;
+    bool DefaultedMoveAssignmentIsDeleted : 1;
+    bool DefaultedDestructorIsDeleted : 1;
+    /// @}
+
+    /// \brief The trivial special members which this class has, per
+    /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25,
+    /// C++11 [class.dtor]p5, or would have if the member were not suppressed.
+    ///
+    /// This excludes any user-declared but not user-provided special members
+    /// which have been declared but not yet defined.
+    unsigned HasTrivialSpecialMembers : 6;
+
+    /// \brief The declared special members of this class which are known to be
+    /// non-trivial.
+    ///
+    /// This excludes any user-declared but not user-provided special members
+    /// which have been declared but not yet defined, and any implicit special
+    /// members which have not yet been declared.
+    unsigned DeclaredNonTrivialSpecialMembers : 6;
+
+    /// \brief True when this class has a destructor with no semantic effect.
+    bool HasIrrelevantDestructor : 1;
+
+    /// \brief True when this class has at least one user-declared constexpr
+    /// constructor which is neither the copy nor move constructor.
+    bool HasConstexprNonCopyMoveConstructor : 1;
+
+    /// \brief True if a defaulted default constructor for this class would
+    /// be constexpr.
+    bool DefaultedDefaultConstructorIsConstexpr : 1;
+
+    /// \brief True if this class has a constexpr default constructor.
+    ///
+    /// This is true for either a user-declared constexpr default constructor
+    /// or an implicitly declared constexpr default constructor.
+    bool HasConstexprDefaultConstructor : 1;
+
+    /// \brief True when this class contains at least one non-static data
+    /// member or base class of non-literal or volatile type.
+    bool HasNonLiteralTypeFieldsOrBases : 1;
+
+    /// \brief True when visible conversion functions are already computed
+    /// and are available.
+    bool ComputedVisibleConversions : 1;
+
+    /// \brief Whether we have a C++11 user-provided default constructor (not
+    /// explicitly deleted or defaulted).
+    bool UserProvidedDefaultConstructor : 1;
+
+    /// \brief The special members which have been declared for this class,
+    /// either by the user or implicitly.
+    unsigned DeclaredSpecialMembers : 6;
+
+    /// \brief Whether an implicit copy constructor would have a const-qualified
+    /// parameter.
+    bool ImplicitCopyConstructorHasConstParam : 1;
+
+    /// \brief Whether an implicit copy assignment operator would have a
+    /// const-qualified parameter.
+    bool ImplicitCopyAssignmentHasConstParam : 1;
+
+    /// \brief Whether any declared copy constructor has a const-qualified
+    /// parameter.
+    bool HasDeclaredCopyConstructorWithConstParam : 1;
+
+    /// \brief Whether any declared copy assignment operator has either a
+    /// const-qualified reference parameter or a non-reference parameter.
+    bool HasDeclaredCopyAssignmentWithConstParam : 1;
+
+    /// \brief Whether this class describes a C++ lambda.
+    bool IsLambda : 1;
+
+    /// \brief Whether we are currently parsing base specifiers.
+    bool IsParsingBaseSpecifiers : 1;
+
+    /// \brief The number of base class specifiers in Bases.
+    unsigned NumBases;
+
+    /// \brief The number of virtual base class specifiers in VBases.
+    unsigned NumVBases;
+
+    /// \brief Base classes of this class.
+    ///
+    /// FIXME: This is wasted space for a union.
+    LazyCXXBaseSpecifiersPtr Bases;
+
+    /// \brief direct and indirect virtual base classes of this class.
+    LazyCXXBaseSpecifiersPtr VBases;
+
+    /// \brief The conversion functions of this C++ class (but not its
+    /// inherited conversion functions).
+    ///
+    /// Each of the entries in this overload set is a CXXConversionDecl.
+    LazyASTUnresolvedSet Conversions;
+
+    /// \brief The conversion functions of this C++ class and all those
+    /// inherited conversion functions that are visible in this class.
+    ///
+    /// Each of the entries in this overload set is a CXXConversionDecl or a
+    /// FunctionTemplateDecl.
+    LazyASTUnresolvedSet VisibleConversions;
+
+    /// \brief The declaration which defines this record.
+    CXXRecordDecl *Definition;
+
+    /// \brief The first friend declaration in this class, or null if there
+    /// aren't any. 
+    ///
+    /// This is actually currently stored in reverse order.
+    LazyDeclPtr FirstFriend;
+
+    /// \brief Retrieve the set of direct base classes.
+    CXXBaseSpecifier *getBases() const {
+      if (!Bases.isOffset())
+        return Bases.get(nullptr);
+      return getBasesSlowCase();
+    }
+
+    /// \brief Retrieve the set of virtual base classes.
+    CXXBaseSpecifier *getVBases() const {
+      if (!VBases.isOffset())
+        return VBases.get(nullptr);
+      return getVBasesSlowCase();
+    }
+
+  private:
+    CXXBaseSpecifier *getBasesSlowCase() const;
+    CXXBaseSpecifier *getVBasesSlowCase() const;
+  };
+
+  typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
+      DefinitionDataPtr;
+  friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
+
+  mutable DefinitionDataPtr DefinitionData;
+
+  /// \brief Describes a C++ closure type (generated by a lambda expression).
+  struct LambdaDefinitionData : public DefinitionData {
+    typedef LambdaCapture Capture;
+
+    LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, 
+                         bool Dependent, bool IsGeneric, 
+                         LambdaCaptureDefault CaptureDefault) 
+      : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), 
+        CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), 
+        ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
+        MethodTyInfo(Info) {
+      IsLambda = true;
+    }
+
+    /// \brief Whether this lambda is known to be dependent, even if its
+    /// context isn't dependent.
+    /// 
+    /// A lambda with a non-dependent context can be dependent if it occurs
+    /// within the default argument of a function template, because the
+    /// lambda will have been created with the enclosing context as its
+    /// declaration context, rather than function. This is an unfortunate
+    /// artifact of having to parse the default arguments before. 
+    unsigned Dependent : 1;
+    
+    /// \brief Whether this lambda is a generic lambda.
+    unsigned IsGenericLambda : 1;
+
+    /// \brief The Default Capture.
+    unsigned CaptureDefault : 2;
+
+    /// \brief The number of captures in this lambda is limited 2^NumCaptures.
+    unsigned NumCaptures : 15;
+
+    /// \brief The number of explicit captures in this lambda.
+    unsigned NumExplicitCaptures : 13;
+
+    /// \brief The number used to indicate this lambda expression for name 
+    /// mangling in the Itanium C++ ABI.
+    unsigned ManglingNumber;
+    
+    /// \brief The declaration that provides context for this lambda, if the
+    /// actual DeclContext does not suffice. This is used for lambdas that
+    /// occur within default arguments of function parameters within the class
+    /// or within a data member initializer.
+    Decl *ContextDecl;
+    
+    /// \brief The list of captures, both explicit and implicit, for this 
+    /// lambda.
+    Capture *Captures;
+
+    /// \brief The type of the call method.
+    TypeSourceInfo *MethodTyInfo;
+       
+  };
+
+  struct DefinitionData &data() const {
+    auto *DD = DefinitionData.get();
+    assert(DD && "queried property of class with no definition");
+    return *DD;
+  }
+
+  struct LambdaDefinitionData &getLambdaData() const {
+    // No update required: a merged definition cannot change any lambda
+    // properties.
+    auto *DD = DefinitionData.getNotUpdated();
+    assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
+    return static_cast<LambdaDefinitionData&>(*DD);
+  }
+
+  /// \brief The template or declaration that this declaration
+  /// describes or was instantiated from, respectively.
+  ///
+  /// For non-templates, this value will be null. For record
+  /// declarations that describe a class template, this will be a
+  /// pointer to a ClassTemplateDecl. For member
+  /// classes of class template specializations, this will be the
+  /// MemberSpecializationInfo referring to the member class that was
+  /// instantiated or specialized.
+  llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
+    TemplateOrInstantiation;
+
+  friend class DeclContext;
+  friend class LambdaExpr;
+
+  /// \brief Called from setBases and addedMember to notify the class that a
+  /// direct or virtual base class or a member of class type has been added.
+  void addedClassSubobject(CXXRecordDecl *Base);
+
+  /// \brief Notify the class that member has been added.
+  ///
+  /// This routine helps maintain information about the class based on which
+  /// members have been added. It will be invoked by DeclContext::addDecl()
+  /// whenever a member is added to this record.
+  void addedMember(Decl *D);
+
+  void markedVirtualFunctionPure();
+  friend void FunctionDecl::setPure(bool);
+
+  friend class ASTNodeImporter;
+
+  /// \brief Get the head of our list of friend declarations, possibly
+  /// deserializing the friends from an external AST source.
+  FriendDecl *getFirstFriend() const;
+
+protected:
+  CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
+                SourceLocation StartLoc, SourceLocation IdLoc,
+                IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
+
+public:
+  /// \brief Iterator that traverses the base classes of a class.
+  typedef CXXBaseSpecifier*       base_class_iterator;
+
+  /// \brief Iterator that traverses the base classes of a class.
+  typedef const CXXBaseSpecifier* base_class_const_iterator;
+
+  CXXRecordDecl *getCanonicalDecl() override {
+    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+  }
+  virtual const CXXRecordDecl *getCanonicalDecl() const {
+    return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+  }
+
+  CXXRecordDecl *getPreviousDecl() {
+    return cast_or_null<CXXRecordDecl>(
+            static_cast<RecordDecl *>(this)->getPreviousDecl());
+  }
+  const CXXRecordDecl *getPreviousDecl() const {
+    return const_cast<CXXRecordDecl*>(this)->getPreviousDecl();
+  }
+
+  CXXRecordDecl *getMostRecentDecl() {
+    return cast<CXXRecordDecl>(
+            static_cast<RecordDecl *>(this)->getMostRecentDecl());
+  }
+
+  const CXXRecordDecl *getMostRecentDecl() const {
+    return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
+  }
+
+  CXXRecordDecl *getDefinition() const {
+    auto *DD = DefinitionData.get();
+    return DD ? DD->Definition : nullptr;
+  }
+
+  bool hasDefinition() const { return DefinitionData.get(); }
+
+  static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
+                               SourceLocation StartLoc, SourceLocation IdLoc,
+                               IdentifierInfo *Id,
+                               CXXRecordDecl *PrevDecl = nullptr,
+                               bool DelayTypeCreation = false);
+  static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
+                                     TypeSourceInfo *Info, SourceLocation Loc,
+                                     bool DependentLambda, bool IsGeneric,
+                                     LambdaCaptureDefault CaptureDefault);
+  static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
+
+  bool isDynamicClass() const {
+    return data().Polymorphic || data().NumVBases != 0;
+  }
+
+  void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+
+  bool isParsingBaseSpecifiers() const {
+    return data().IsParsingBaseSpecifiers;
+  }
+
+  /// \brief Sets the base classes of this struct or class.
+  void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
+
+  /// \brief Retrieves the number of base classes of this class.
+  unsigned getNumBases() const { return data().NumBases; }
+
+  typedef llvm::iterator_range<base_class_iterator> base_class_range;
+  typedef llvm::iterator_range<base_class_const_iterator>
+    base_class_const_range;
+
+  base_class_range bases() {
+    return base_class_range(bases_begin(), bases_end());
+  }
+  base_class_const_range bases() const {
+    return base_class_const_range(bases_begin(), bases_end());
+  }
+
+  base_class_iterator bases_begin() { return data().getBases(); }
+  base_class_const_iterator bases_begin() const { return data().getBases(); }
+  base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
+  base_class_const_iterator bases_end() const {
+    return bases_begin() + data().NumBases;
+  }
+
+  /// \brief Retrieves the number of virtual base classes of this class.
+  unsigned getNumVBases() const { return data().NumVBases; }
+
+  base_class_range vbases() {
+    return base_class_range(vbases_begin(), vbases_end());
+  }
+  base_class_const_range vbases() const {
+    return base_class_const_range(vbases_begin(), vbases_end());
+  }
+
+  base_class_iterator vbases_begin() { return data().getVBases(); }
+  base_class_const_iterator vbases_begin() const { return data().getVBases(); }
+  base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
+  base_class_const_iterator vbases_end() const {
+    return vbases_begin() + data().NumVBases;
+  }
+
+  /// \brief Determine whether this class has any dependent base classes which
+  /// are not the current instantiation.
+  bool hasAnyDependentBases() const;
+
+  /// Iterator access to method members.  The method iterator visits
+  /// all method members of the class, including non-instance methods,
+  /// special methods, etc.
+  typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
+    method_range;
+
+  method_range methods() const {
+    return method_range(method_begin(), method_end());
+  }
+
+  /// \brief Method begin iterator.  Iterates in the order the methods
+  /// were declared.
+  method_iterator method_begin() const {
+    return method_iterator(decls_begin());
+  }
+  /// \brief Method past-the-end iterator.
+  method_iterator method_end() const {
+    return method_iterator(decls_end());
+  }
+
+  /// Iterator access to constructor members.
+  typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
+    ctor_range;
+
+  ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
+
+  ctor_iterator ctor_begin() const {
+    return ctor_iterator(decls_begin());
+  }
+  ctor_iterator ctor_end() const {
+    return ctor_iterator(decls_end());
+  }
+
+  /// An iterator over friend declarations.  All of these are defined
+  /// in DeclFriend.h.
+  class friend_iterator;
+  typedef llvm::iterator_range<friend_iterator> friend_range;
+
+  friend_range friends() const;
+  friend_iterator friend_begin() const;
+  friend_iterator friend_end() const;
+  void pushFriendDecl(FriendDecl *FD);
+
+  /// Determines whether this record has any friends.
+  bool hasFriends() const {
+    return data().FirstFriend.isValid();
+  }
+
+  /// \brief \c true if we know for sure that this class has a single,
+  /// accessible, unambiguous move constructor that is not deleted.
+  bool hasSimpleMoveConstructor() const {
+    return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
+           !data().DefaultedMoveConstructorIsDeleted;
+  }
+  /// \brief \c true if we know for sure that this class has a single,
+  /// accessible, unambiguous move assignment operator that is not deleted.
+  bool hasSimpleMoveAssignment() const {
+    return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
+           !data().DefaultedMoveAssignmentIsDeleted;
+  }
+  /// \brief \c true if we know for sure that this class has an accessible
+  /// destructor that is not deleted.
+  bool hasSimpleDestructor() const {
+    return !hasUserDeclaredDestructor() &&
+           !data().DefaultedDestructorIsDeleted;
+  }
+
+  /// \brief Determine whether this class has any default constructors.
+  bool hasDefaultConstructor() const {
+    return (data().DeclaredSpecialMembers & SMF_DefaultConstructor) ||
+           needsImplicitDefaultConstructor();
+  }
+
+  /// \brief Determine if we need to declare a default constructor for
+  /// this class.
+  ///
+  /// This value is used for lazy creation of default constructors.
+  bool needsImplicitDefaultConstructor() const {
+    return !data().UserDeclaredConstructor &&
+           !(data().DeclaredSpecialMembers & SMF_DefaultConstructor);
+  }
+
+  /// \brief Determine whether this class has any user-declared constructors.
+  ///
+  /// When true, a default constructor will not be implicitly declared.
+  bool hasUserDeclaredConstructor() const {
+    return data().UserDeclaredConstructor;
+  }
+
+  /// \brief Whether this class has a user-provided default constructor
+  /// per C++11.
+  bool hasUserProvidedDefaultConstructor() const {
+    return data().UserProvidedDefaultConstructor;
+  }
+
+  /// \brief Determine whether this class has a user-declared copy constructor.
+  ///
+  /// When false, a copy constructor will be implicitly declared.
+  bool hasUserDeclaredCopyConstructor() const {
+    return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
+  }
+
+  /// \brief Determine whether this class needs an implicit copy
+  /// constructor to be lazily declared.
+  bool needsImplicitCopyConstructor() const {
+    return !(data().DeclaredSpecialMembers & SMF_CopyConstructor);
+  }
+
+  /// \brief Determine whether we need to eagerly declare a defaulted copy
+  /// constructor for this class.
+  bool needsOverloadResolutionForCopyConstructor() const {
+    return data().HasMutableFields;
+  }
+
+  /// \brief Determine whether an implicit copy constructor for this type
+  /// would have a parameter with a const-qualified reference type.
+  bool implicitCopyConstructorHasConstParam() const {
+    return data().ImplicitCopyConstructorHasConstParam;
+  }
+
+  /// \brief Determine whether this class has a copy constructor with
+  /// a parameter type which is a reference to a const-qualified type.
+  bool hasCopyConstructorWithConstParam() const {
+    return data().HasDeclaredCopyConstructorWithConstParam ||
+           (needsImplicitCopyConstructor() &&
+            implicitCopyConstructorHasConstParam());
+  }
+
+  /// \brief Whether this class has a user-declared move constructor or
+  /// assignment operator.
+  ///
+  /// When false, a move constructor and assignment operator may be
+  /// implicitly declared.
+  bool hasUserDeclaredMoveOperation() const {
+    return data().UserDeclaredSpecialMembers &
+             (SMF_MoveConstructor | SMF_MoveAssignment);
+  }
+
+  /// \brief Determine whether this class has had a move constructor
+  /// declared by the user.
+  bool hasUserDeclaredMoveConstructor() const {
+    return data().UserDeclaredSpecialMembers & SMF_MoveConstructor;
+  }
+
+  /// \brief Determine whether this class has a move constructor.
+  bool hasMoveConstructor() const {
+    return (data().DeclaredSpecialMembers & SMF_MoveConstructor) ||
+           needsImplicitMoveConstructor();
+  }
+
+  /// \brief Set that we attempted to declare an implicitly move
+  /// constructor, but overload resolution failed so we deleted it.
+  void setImplicitMoveConstructorIsDeleted() {
+    assert((data().DefaultedMoveConstructorIsDeleted ||
+            needsOverloadResolutionForMoveConstructor()) &&
+           "move constructor should not be deleted");
+    data().DefaultedMoveConstructorIsDeleted = true;
+  }
+
+  /// \brief Determine whether this class should get an implicit move
+  /// constructor or if any existing special member function inhibits this.
+  bool needsImplicitMoveConstructor() const {
+    return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
+           !hasUserDeclaredCopyConstructor() &&
+           !hasUserDeclaredCopyAssignment() &&
+           !hasUserDeclaredMoveAssignment() &&
+           !hasUserDeclaredDestructor();
+  }
+
+  /// \brief Determine whether we need to eagerly declare a defaulted move
+  /// constructor for this class.
+  bool needsOverloadResolutionForMoveConstructor() const {
+    return data().NeedOverloadResolutionForMoveConstructor;
+  }
+
+  /// \brief Determine whether this class has a user-declared copy assignment
+  /// operator.
+  ///
+  /// When false, a copy assigment operator will be implicitly declared.
+  bool hasUserDeclaredCopyAssignment() const {
+    return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
+  }
+
+  /// \brief Determine whether this class needs an implicit copy
+  /// assignment operator to be lazily declared.
+  bool needsImplicitCopyAssignment() const {
+    return !(data().DeclaredSpecialMembers & SMF_CopyAssignment);
+  }
+
+  /// \brief Determine whether we need to eagerly declare a defaulted copy
+  /// assignment operator for this class.
+  bool needsOverloadResolutionForCopyAssignment() const {
+    return data().HasMutableFields;
+  }
+
+  /// \brief Determine whether an implicit copy assignment operator for this
+  /// type would have a parameter with a const-qualified reference type.
+  bool implicitCopyAssignmentHasConstParam() const {
+    return data().ImplicitCopyAssignmentHasConstParam;
+  }
+
+  /// \brief Determine whether this class has a copy assignment operator with
+  /// a parameter type which is a reference to a const-qualified type or is not
+  /// a reference.
+  bool hasCopyAssignmentWithConstParam() const {
+    return data().HasDeclaredCopyAssignmentWithConstParam ||
+           (needsImplicitCopyAssignment() &&
+            implicitCopyAssignmentHasConstParam());
+  }
+
+  /// \brief Determine whether this class has had a move assignment
+  /// declared by the user.
+  bool hasUserDeclaredMoveAssignment() const {
+    return data().UserDeclaredSpecialMembers & SMF_MoveAssignment;
+  }
+
+  /// \brief Determine whether this class has a move assignment operator.
+  bool hasMoveAssignment() const {
+    return (data().DeclaredSpecialMembers & SMF_MoveAssignment) ||
+           needsImplicitMoveAssignment();
+  }
+
+  /// \brief Set that we attempted to declare an implicit move assignment
+  /// operator, but overload resolution failed so we deleted it.
+  void setImplicitMoveAssignmentIsDeleted() {
+    assert((data().DefaultedMoveAssignmentIsDeleted ||
+            needsOverloadResolutionForMoveAssignment()) &&
+           "move assignment should not be deleted");
+    data().DefaultedMoveAssignmentIsDeleted = true;
+  }
+
+  /// \brief Determine whether this class should get an implicit move
+  /// assignment operator or if any existing special member function inhibits
+  /// this.
+  bool needsImplicitMoveAssignment() const {
+    return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
+           !hasUserDeclaredCopyConstructor() &&
+           !hasUserDeclaredCopyAssignment() &&
+           !hasUserDeclaredMoveConstructor() &&
+           !hasUserDeclaredDestructor();
+  }
+
+  /// \brief Determine whether we need to eagerly declare a move assignment
+  /// operator for this class.
+  bool needsOverloadResolutionForMoveAssignment() const {
+    return data().NeedOverloadResolutionForMoveAssignment;
+  }
+
+  /// \brief Determine whether this class has a user-declared destructor.
+  ///
+  /// When false, a destructor will be implicitly declared.
+  bool hasUserDeclaredDestructor() const {
+    return data().UserDeclaredSpecialMembers & SMF_Destructor;
+  }
+
+  /// \brief Determine whether this class needs an implicit destructor to
+  /// be lazily declared.
+  bool needsImplicitDestructor() const {
+    return !(data().DeclaredSpecialMembers & SMF_Destructor);
+  }
+
+  /// \brief Determine whether we need to eagerly declare a destructor for this
+  /// class.
+  bool needsOverloadResolutionForDestructor() const {
+    return data().NeedOverloadResolutionForDestructor;
+  }
+
+  /// \brief Determine whether this class describes a lambda function object.
+  bool isLambda() const {
+    // An update record can't turn a non-lambda into a lambda.
+    auto *DD = DefinitionData.getNotUpdated();
+    return DD && DD->IsLambda;
+  }
+
+  /// \brief Determine whether this class describes a generic 
+  /// lambda function object (i.e. function call operator is
+  /// a template). 
+  bool isGenericLambda() const; 
+
+  /// \brief Retrieve the lambda call operator of the closure type
+  /// if this is a closure type.
+  CXXMethodDecl *getLambdaCallOperator() const; 
+
+  /// \brief Retrieve the lambda static invoker, the address of which
+  /// is returned by the conversion operator, and the body of which
+  /// is forwarded to the lambda call operator. 
+  CXXMethodDecl *getLambdaStaticInvoker() const; 
+
+  /// \brief Retrieve the generic lambda's template parameter list.
+  /// Returns null if the class does not represent a lambda or a generic 
+  /// lambda.
+  TemplateParameterList *getGenericLambdaTemplateParameterList() const;
+
+  LambdaCaptureDefault getLambdaCaptureDefault() const {
+    assert(isLambda());
+    return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
+  }
+
+  /// \brief For a closure type, retrieve the mapping from captured
+  /// variables and \c this to the non-static data members that store the
+  /// values or references of the captures.
+  ///
+  /// \param Captures Will be populated with the mapping from captured
+  /// variables to the corresponding fields.
+  ///
+  /// \param ThisCapture Will be set to the field declaration for the
+  /// \c this capture.
+  ///
+  /// \note No entries will be added for init-captures, as they do not capture
+  /// variables.
+  void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
+                        FieldDecl *&ThisCapture) const;
+
+  typedef const LambdaCapture *capture_const_iterator;
+  typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+  capture_const_range captures() const {
+    return capture_const_range(captures_begin(), captures_end());
+  }
+  capture_const_iterator captures_begin() const {
+    return isLambda() ? getLambdaData().Captures : nullptr;
+  }
+  capture_const_iterator captures_end() const {
+    return isLambda() ? captures_begin() + getLambdaData().NumCaptures
+                      : nullptr;
+  }
+
+  typedef UnresolvedSetIterator conversion_iterator;
+  conversion_iterator conversion_begin() const {
+    return data().Conversions.get(getASTContext()).begin();
+  }
+  conversion_iterator conversion_end() const {
+    return data().Conversions.get(getASTContext()).end();
+  }
+
+  /// Removes a conversion function from this class.  The conversion
+  /// function must currently be a member of this class.  Furthermore,
+  /// this class must currently be in the process of being defined.
+  void removeConversion(const NamedDecl *Old);
+
+  /// \brief Get all conversion functions visible in current class,
+  /// including conversion function templates.
+  std::pair<conversion_iterator, conversion_iterator>
+    getVisibleConversionFunctions();
+
+  /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]),
+  /// which is a class with no user-declared constructors, no private
+  /// or protected non-static data members, no base classes, and no virtual
+  /// functions (C++ [dcl.init.aggr]p1).
+  bool isAggregate() const { return data().Aggregate; }
+
+  /// \brief Whether this class has any in-class initializers
+  /// for non-static data members (including those in anonymous unions or
+  /// structs).
+  bool hasInClassInitializer() const { return data().HasInClassInitializer; }
+
+  /// \brief Whether this class or any of its subobjects has any members of
+  /// reference type which would make value-initialization ill-formed.
+  ///
+  /// Per C++03 [dcl.init]p5:
+  ///  - if T is a non-union class type without a user-declared constructor,
+  ///    then every non-static data member and base-class component of T is
+  ///    value-initialized [...] A program that calls for [...]
+  ///    value-initialization of an entity of reference type is ill-formed.
+  bool hasUninitializedReferenceMember() const {
+    return !isUnion() && !hasUserDeclaredConstructor() &&
+           data().HasUninitializedReferenceMember;
+  }
+
+  /// \brief Whether this class is a POD-type (C++ [class]p4)
+  ///
+  /// For purposes of this function a class is POD if it is an aggregate
+  /// that has no non-static non-POD data members, no reference data
+  /// members, no user-defined copy assignment operator and no
+  /// user-defined destructor.
+  ///
+  /// Note that this is the C++ TR1 definition of POD.
+  bool isPOD() const { return data().PlainOldData; }
+
+  /// \brief True if this class is C-like, without C++-specific features, e.g.
+  /// it contains only public fields, no bases, tag kind is not 'class', etc.
+  bool isCLike() const;
+
+  /// \brief Determine whether this is an empty class in the sense of
+  /// (C++11 [meta.unary.prop]).
+  ///
+  /// A non-union class is empty iff it has a virtual function, virtual base,
+  /// data member (other than 0-width bit-field) or inherits from a non-empty
+  /// class.
+  ///
+  /// \note This does NOT include a check for union-ness.
+  bool isEmpty() const { return data().Empty; }
+
+  /// Whether this class is polymorphic (C++ [class.virtual]),
+  /// which means that the class contains or inherits a virtual function.
+  bool isPolymorphic() const { return data().Polymorphic; }
+
+  /// \brief Determine whether this class has a pure virtual function.
+  ///
+  /// The class is is abstract per (C++ [class.abstract]p2) if it declares
+  /// a pure virtual function or inherits a pure virtual function that is
+  /// not overridden.
+  bool isAbstract() const { return data().Abstract; }
+
+  /// \brief Determine whether this class has standard layout per 
+  /// (C++ [class]p7)
+  bool isStandardLayout() const { return data().IsStandardLayout; }
+
+  /// \brief Determine whether this class, or any of its class subobjects,
+  /// contains a mutable field.
+  bool hasMutableFields() const { return data().HasMutableFields; }
+
+  /// \brief Determine whether this class has any variant members.
+  bool hasVariantMembers() const { return data().HasVariantMembers; }
+
+  /// \brief Determine whether this class has a trivial default constructor
+  /// (C++11 [class.ctor]p5).
+  bool hasTrivialDefaultConstructor() const {
+    return hasDefaultConstructor() &&
+           (data().HasTrivialSpecialMembers & SMF_DefaultConstructor);
+  }
+
+  /// \brief Determine whether this class has a non-trivial default constructor
+  /// (C++11 [class.ctor]p5).
+  bool hasNonTrivialDefaultConstructor() const {
+    return (data().DeclaredNonTrivialSpecialMembers & SMF_DefaultConstructor) ||
+           (needsImplicitDefaultConstructor() &&
+            !(data().HasTrivialSpecialMembers & SMF_DefaultConstructor));
+  }
+
+  /// \brief Determine whether this class has at least one constexpr constructor
+  /// other than the copy or move constructors.
+  bool hasConstexprNonCopyMoveConstructor() const {
+    return data().HasConstexprNonCopyMoveConstructor ||
+           (needsImplicitDefaultConstructor() &&
+            defaultedDefaultConstructorIsConstexpr());
+  }
+
+  /// \brief Determine whether a defaulted default constructor for this class
+  /// would be constexpr.
+  bool defaultedDefaultConstructorIsConstexpr() const {
+    return data().DefaultedDefaultConstructorIsConstexpr &&
+           (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
+  }
+
+  /// \brief Determine whether this class has a constexpr default constructor.
+  bool hasConstexprDefaultConstructor() const {
+    return data().HasConstexprDefaultConstructor ||
+           (needsImplicitDefaultConstructor() &&
+            defaultedDefaultConstructorIsConstexpr());
+  }
+
+  /// \brief Determine whether this class has a trivial copy constructor
+  /// (C++ [class.copy]p6, C++11 [class.copy]p12)
+  bool hasTrivialCopyConstructor() const {
+    return data().HasTrivialSpecialMembers & SMF_CopyConstructor;
+  }
+
+  /// \brief Determine whether this class has a non-trivial copy constructor
+  /// (C++ [class.copy]p6, C++11 [class.copy]p12)
+  bool hasNonTrivialCopyConstructor() const {
+    return data().DeclaredNonTrivialSpecialMembers & SMF_CopyConstructor ||
+           !hasTrivialCopyConstructor();
+  }
+
+  /// \brief Determine whether this class has a trivial move constructor
+  /// (C++11 [class.copy]p12)
+  bool hasTrivialMoveConstructor() const {
+    return hasMoveConstructor() &&
+           (data().HasTrivialSpecialMembers & SMF_MoveConstructor);
+  }
+
+  /// \brief Determine whether this class has a non-trivial move constructor
+  /// (C++11 [class.copy]p12)
+  bool hasNonTrivialMoveConstructor() const {
+    return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveConstructor) ||
+           (needsImplicitMoveConstructor() &&
+            !(data().HasTrivialSpecialMembers & SMF_MoveConstructor));
+  }
+
+  /// \brief Determine whether this class has a trivial copy assignment operator
+  /// (C++ [class.copy]p11, C++11 [class.copy]p25)
+  bool hasTrivialCopyAssignment() const {
+    return data().HasTrivialSpecialMembers & SMF_CopyAssignment;
+  }
+
+  /// \brief Determine whether this class has a non-trivial copy assignment
+  /// operator (C++ [class.copy]p11, C++11 [class.copy]p25)
+  bool hasNonTrivialCopyAssignment() const {
+    return data().DeclaredNonTrivialSpecialMembers & SMF_CopyAssignment ||
+           !hasTrivialCopyAssignment();
+  }
+
+  /// \brief Determine whether this class has a trivial move assignment operator
+  /// (C++11 [class.copy]p25)
+  bool hasTrivialMoveAssignment() const {
+    return hasMoveAssignment() &&
+           (data().HasTrivialSpecialMembers & SMF_MoveAssignment);
+  }
+
+  /// \brief Determine whether this class has a non-trivial move assignment
+  /// operator (C++11 [class.copy]p25)
+  bool hasNonTrivialMoveAssignment() const {
+    return (data().DeclaredNonTrivialSpecialMembers & SMF_MoveAssignment) ||
+           (needsImplicitMoveAssignment() &&
+            !(data().HasTrivialSpecialMembers & SMF_MoveAssignment));
+  }
+
+  /// \brief Determine whether this class has a trivial destructor
+  /// (C++ [class.dtor]p3)
+  bool hasTrivialDestructor() const {
+    return data().HasTrivialSpecialMembers & SMF_Destructor;
+  }
+
+  /// \brief Determine whether this class has a non-trivial destructor
+  /// (C++ [class.dtor]p3)
+  bool hasNonTrivialDestructor() const {
+    return !(data().HasTrivialSpecialMembers & SMF_Destructor);
+  }
+
+  /// \brief Determine whether this class has a destructor which has no
+  /// semantic effect.
+  ///
+  /// Any such destructor will be trivial, public, defaulted and not deleted,
+  /// and will call only irrelevant destructors.
+  bool hasIrrelevantDestructor() const {
+    return data().HasIrrelevantDestructor;
+  }
+
+  /// \brief Determine whether this class has a non-literal or/ volatile type
+  /// non-static data member or base class.
+  bool hasNonLiteralTypeFieldsOrBases() const {
+    return data().HasNonLiteralTypeFieldsOrBases;
+  }
+
+  /// \brief Determine whether this class is considered trivially copyable per
+  /// (C++11 [class]p6).
+  bool isTriviallyCopyable() const;
+
+  /// \brief Determine whether this class is considered trivial.
+  ///
+  /// C++11 [class]p6:
+  ///    "A trivial class is a class that has a trivial default constructor and
+  ///    is trivially copiable."
+  bool isTrivial() const {
+    return isTriviallyCopyable() && hasTrivialDefaultConstructor();
+  }
+
+  /// \brief Determine whether this class is a literal type.
+  ///
+  /// C++11 [basic.types]p10:
+  ///   A class type that has all the following properties:
+  ///     - it has a trivial destructor
+  ///     - every constructor call and full-expression in the
+  ///       brace-or-equal-intializers for non-static data members (if any) is
+  ///       a constant expression.
+  ///     - it is an aggregate type or has at least one constexpr constructor
+  ///       or constructor template that is not a copy or move constructor, and
+  ///     - all of its non-static data members and base classes are of literal
+  ///       types
+  ///
+  /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
+  /// treating types with trivial default constructors as literal types.
+  bool isLiteral() const {
+    return hasTrivialDestructor() &&
+           (isAggregate() || hasConstexprNonCopyMoveConstructor() ||
+            hasTrivialDefaultConstructor()) &&
+           !hasNonLiteralTypeFieldsOrBases();
+  }
+
+  /// \brief If this record is an instantiation of a member class,
+  /// retrieves the member class from which it was instantiated.
+  ///
+  /// This routine will return non-null for (non-templated) member
+  /// classes of class templates. For example, given:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   struct A { };
+  /// };
+  /// \endcode
+  ///
+  /// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
+  /// whose parent is the class template specialization X<int>. For
+  /// this declaration, getInstantiatedFromMemberClass() will return
+  /// the CXXRecordDecl X<T>::A. When a complete definition of
+  /// X<int>::A is required, it will be instantiated from the
+  /// declaration returned by getInstantiatedFromMemberClass().
+  CXXRecordDecl *getInstantiatedFromMemberClass() const;
+
+  /// \brief If this class is an instantiation of a member class of a
+  /// class template specialization, retrieves the member specialization
+  /// information.
+  MemberSpecializationInfo *getMemberSpecializationInfo() const {
+    return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
+  }
+
+  /// \brief Specify that this record is an instantiation of the
+  /// member class \p RD.
+  void setInstantiationOfMemberClass(CXXRecordDecl *RD,
+                                     TemplateSpecializationKind TSK);
+
+  /// \brief Retrieves the class template that is described by this
+  /// class declaration.
+  ///
+  /// Every class template is represented as a ClassTemplateDecl and a
+  /// CXXRecordDecl. The former contains template properties (such as
+  /// the template parameter lists) while the latter contains the
+  /// actual description of the template's
+  /// contents. ClassTemplateDecl::getTemplatedDecl() retrieves the
+  /// CXXRecordDecl that from a ClassTemplateDecl, while
+  /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from
+  /// a CXXRecordDecl.
+  ClassTemplateDecl *getDescribedClassTemplate() const {
+    return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>();
+  }
+
+  void setDescribedClassTemplate(ClassTemplateDecl *Template) {
+    TemplateOrInstantiation = Template;
+  }
+
+  /// \brief Determine whether this particular class is a specialization or
+  /// instantiation of a class template or member class of a class template,
+  /// and how it was instantiated or specialized.
+  TemplateSpecializationKind getTemplateSpecializationKind() const;
+
+  /// \brief Set the kind of specialization or template instantiation this is.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+
+  /// \brief Returns the destructor decl for this class.
+  CXXDestructorDecl *getDestructor() const;
+
+  /// \brief If the class is a local class [class.local], returns
+  /// the enclosing function declaration.
+  const FunctionDecl *isLocalClass() const {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
+      return RD->isLocalClass();
+
+    return dyn_cast<FunctionDecl>(getDeclContext());
+  }
+
+  FunctionDecl *isLocalClass() {
+    return const_cast<FunctionDecl*>(
+        const_cast<const CXXRecordDecl*>(this)->isLocalClass());
+  }
+
+  /// \brief Determine whether this dependent class is a current instantiation,
+  /// when viewed from within the given context.
+  bool isCurrentInstantiation(const DeclContext *CurContext) const;
+
+  /// \brief Determine whether this class is derived from the class \p Base.
+  ///
+  /// This routine only determines whether this class is derived from \p Base,
+  /// but does not account for factors that may make a Derived -> Base class
+  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
+  /// base class subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \returns true if this class is derived from Base, false otherwise.
+  bool isDerivedFrom(const CXXRecordDecl *Base) const;
+
+  /// \brief Determine whether this class is derived from the type \p Base.
+  ///
+  /// This routine only determines whether this class is derived from \p Base,
+  /// but does not account for factors that may make a Derived -> Base class
+  /// ill-formed, such as private/protected inheritance or multiple, ambiguous
+  /// base class subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \param Paths will contain the paths taken from the current class to the
+  /// given \p Base class.
+  ///
+  /// \returns true if this class is derived from \p Base, false otherwise.
+  ///
+  /// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
+  /// tangling input and output in \p Paths
+  bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
+
+  /// \brief Determine whether this class is virtually derived from
+  /// the class \p Base.
+  ///
+  /// This routine only determines whether this class is virtually
+  /// derived from \p Base, but does not account for factors that may
+  /// make a Derived -> Base class ill-formed, such as
+  /// private/protected inheritance or multiple, ambiguous base class
+  /// subobjects.
+  ///
+  /// \param Base the base class we are searching for.
+  ///
+  /// \returns true if this class is virtually derived from Base,
+  /// false otherwise.
+  bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
+
+  /// \brief Determine whether this class is provably not derived from
+  /// the type \p Base.
+  bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
+
+  /// \brief Function type used by forallBases() as a callback.
+  ///
+  /// \param BaseDefinition the definition of the base class
+  ///
+  /// \returns true if this base matched the search criteria
+  typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
+                                   void *UserData);
+
+  /// \brief Determines if the given callback holds for all the direct
+  /// or indirect base classes of this type.
+  ///
+  /// The class itself does not count as a base class.  This routine
+  /// returns false if the class has non-computable base classes.
+  ///
+  /// \param BaseMatches Callback invoked for each (direct or indirect) base
+  /// class of this type, or if \p AllowShortCircuit is true then until a call
+  /// returns false.
+  ///
+  /// \param UserData Passed as the second argument of every call to
+  /// \p BaseMatches.
+  ///
+  /// \param AllowShortCircuit if false, forces the callback to be called
+  /// for every base class, even if a dependent or non-matching base was
+  /// found.
+  bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
+                   bool AllowShortCircuit = true) const;
+
+  /// \brief Function type used by lookupInBases() to determine whether a
+  /// specific base class subobject matches the lookup criteria.
+  ///
+  /// \param Specifier the base-class specifier that describes the inheritance
+  /// from the base class we are trying to match.
+  ///
+  /// \param Path the current path, from the most-derived class down to the
+  /// base named by the \p Specifier.
+  ///
+  /// \param UserData a single pointer to user-specified data, provided to
+  /// lookupInBases().
+  ///
+  /// \returns true if this base matched the search criteria, false otherwise.
+  typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier,
+                                   CXXBasePath &Path,
+                                   void *UserData);
+
+  /// \brief Look for entities within the base classes of this C++ class,
+  /// transitively searching all base class subobjects.
+  ///
+  /// This routine uses the callback function \p BaseMatches to find base
+  /// classes meeting some search criteria, walking all base class subobjects
+  /// and populating the given \p Paths structure with the paths through the
+  /// inheritance hierarchy that resulted in a match. On a successful search,
+  /// the \p Paths structure can be queried to retrieve the matching paths and
+  /// to determine if there were any ambiguities.
+  ///
+  /// \param BaseMatches callback function used to determine whether a given
+  /// base matches the user-defined search criteria.
+  ///
+  /// \param UserData user data pointer that will be provided to \p BaseMatches.
+  ///
+  /// \param Paths used to record the paths from this class to its base class
+  /// subobjects that match the search criteria.
+  ///
+  /// \returns true if there exists any path from this class to a base class
+  /// subobject that matches the search criteria.
+  bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData,
+                     CXXBasePaths &Paths) const;
+
+  /// \brief Base-class lookup callback that determines whether the given
+  /// base class specifier refers to a specific class declaration.
+  ///
+  /// This callback can be used with \c lookupInBases() to determine whether
+  /// a given derived class has is a base class subobject of a particular type.
+  /// The user data pointer should refer to the canonical CXXRecordDecl of the
+  /// base class that we are searching for.
+  static bool FindBaseClass(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *BaseRecord);
+
+  /// \brief Base-class lookup callback that determines whether the
+  /// given base class specifier refers to a specific class
+  /// declaration and describes virtual derivation.
+  ///
+  /// This callback can be used with \c lookupInBases() to determine
+  /// whether a given derived class has is a virtual base class
+  /// subobject of a particular type.  The user data pointer should
+  /// refer to the canonical CXXRecordDecl of the base class that we
+  /// are searching for.
+  static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier,
+                                   CXXBasePath &Path, void *BaseRecord);
+
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a tag with the given name.
+  ///
+  /// This callback can be used with \c lookupInBases() to find tag members
+  /// of the given name within a C++ class hierarchy. The user data pointer
+  /// is an opaque \c DeclarationName pointer.
+  static bool FindTagMember(const CXXBaseSpecifier *Specifier,
+                            CXXBasePath &Path, void *Name);
+
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a member with the given name.
+  ///
+  /// This callback can be used with \c lookupInBases() to find members
+  /// of the given name within a C++ class hierarchy. The user data pointer
+  /// is an opaque \c DeclarationName pointer.
+  static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+                                 CXXBasePath &Path, void *Name);
+
+  /// \brief Base-class lookup callback that determines whether there exists
+  /// a member with the given name that can be used in a nested-name-specifier.
+  ///
+  /// This callback can be used with \c lookupInBases() to find membes of
+  /// the given name within a C++ class hierarchy that can occur within
+  /// nested-name-specifiers.
+  static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
+                                            CXXBasePath &Path,
+                                            void *UserData);
+
+  /// \brief Retrieve the final overriders for each virtual member
+  /// function in the class hierarchy where this class is the
+  /// most-derived class in the class hierarchy.
+  void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
+
+  /// \brief Get the indirect primary bases for this class.
+  void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
+
+  /// Renders and displays an inheritance diagram
+  /// for this C++ class and all of its base classes (transitively) using
+  /// GraphViz.
+  void viewInheritance(ASTContext& Context) const;
+
+  /// \brief Calculates the access of a decl that is reached
+  /// along a path.
+  static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
+                                     AccessSpecifier DeclAccess) {
+    assert(DeclAccess != AS_none);
+    if (DeclAccess == AS_private) return AS_none;
+    return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
+  }
+
+  /// \brief Indicates that the declaration of a defaulted or deleted special
+  /// member function is now complete.
+  void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
+
+  /// \brief Indicates that the definition of this class is now complete.
+  void completeDefinition() override;
+
+  /// \brief Indicates that the definition of this class is now complete,
+  /// and provides a final overrider map to help determine
+  ///
+  /// \param FinalOverriders The final overrider map for this class, which can
+  /// be provided as an optimization for abstract-class checking. If NULL,
+  /// final overriders will be computed if they are needed to complete the
+  /// definition.
+  void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
+
+  /// \brief Determine whether this class may end up being abstract, even though
+  /// it is not yet known to be abstract.
+  ///
+  /// \returns true if this class is not known to be abstract but has any
+  /// base classes that are abstract. In this case, \c completeDefinition()
+  /// will need to compute final overriders to determine whether the class is
+  /// actually abstract.
+  bool mayBeAbstract() const;
+
+  /// \brief If this is the closure type of a lambda expression, retrieve the
+  /// number to be used for name mangling in the Itanium C++ ABI.
+  ///
+  /// Zero indicates that this closure type has internal linkage, so the 
+  /// mangling number does not matter, while a non-zero value indicates which
+  /// lambda expression this is in this particular context.
+  unsigned getLambdaManglingNumber() const {
+    assert(isLambda() && "Not a lambda closure type!");
+    return getLambdaData().ManglingNumber;
+  }
+  
+  /// \brief Retrieve the declaration that provides additional context for a 
+  /// lambda, when the normal declaration context is not specific enough.
+  ///
+  /// Certain contexts (default arguments of in-class function parameters and 
+  /// the initializers of data members) have separate name mangling rules for
+  /// lambdas within the Itanium C++ ABI. For these cases, this routine provides
+  /// the declaration in which the lambda occurs, e.g., the function parameter 
+  /// or the non-static data member. Otherwise, it returns NULL to imply that
+  /// the declaration context suffices.
+  Decl *getLambdaContextDecl() const {
+    assert(isLambda() && "Not a lambda closure type!");
+    return getLambdaData().ContextDecl;    
+  }
+  
+  /// \brief Set the mangling number and context declaration for a lambda
+  /// class.
+  void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) {
+    getLambdaData().ManglingNumber = ManglingNumber;
+    getLambdaData().ContextDecl = ContextDecl;
+  }
+
+  /// \brief Returns the inheritance model used for this record.
+  MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+  /// \brief Calculate what the inheritance model would be for this class.
+  MSInheritanceAttr::Spelling calculateInheritanceModel() const;
+
+  /// In the Microsoft C++ ABI, use zero for the field offset of a null data
+  /// member pointer if we can guarantee that zero is not a valid field offset,
+  /// or if the member pointer has multiple fields.  Polymorphic classes have a
+  /// vfptr at offset zero, so we can use zero for null.  If there are multiple
+  /// fields, we can use zero even if it is a valid field offset because
+  /// null-ness testing will check the other fields.
+  bool nullFieldOffsetIsZero() const {
+    return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
+                                               getMSInheritanceModel()) ||
+           (hasDefinition() && isPolymorphic());
+  }
+
+  /// \brief Controls when vtordisps will be emitted if this record is used as a
+  /// virtual base.
+  MSVtorDispAttr::Mode getMSVtorDispMode() const;
+
+  /// \brief Determine whether this lambda expression was known to be dependent
+  /// at the time it was created, even if its context does not appear to be
+  /// dependent.
+  ///
+  /// This flag is a workaround for an issue with parsing, where default
+  /// arguments are parsed before their enclosing function declarations have
+  /// been created. This means that any lambda expressions within those
+  /// default arguments will have as their DeclContext the context enclosing
+  /// the function declaration, which may be non-dependent even when the
+  /// function declaration itself is dependent. This flag indicates when we
+  /// know that the lambda is dependent despite that.
+  bool isDependentLambda() const {
+    return isLambda() && getLambdaData().Dependent;
+  }
+
+  TypeSourceInfo *getLambdaTypeInfo() const {
+    return getLambdaData().MethodTyInfo;
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstCXXRecord && K <= lastCXXRecord;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+  friend class ASTReader;
+  friend class ASTWriter;
+};
+
+/// \brief Represents a static or instance method of a struct/union/class.
+///
+/// In the terminology of the C++ Standard, these are the (static and
+/// non-static) member functions, whether virtual or not.
+class CXXMethodDecl : public FunctionDecl {
+  void anchor() override;
+protected:
+  CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+                SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
+                QualType T, TypeSourceInfo *TInfo,
+                StorageClass SC, bool isInline,
+                bool isConstexpr, SourceLocation EndLocation)
+    : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
+                   SC, isInline, isConstexpr) {
+    if (EndLocation.isValid())
+      setRangeEnd(EndLocation);
+  }
+
+public:
+  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                               SourceLocation StartLoc,
+                               const DeclarationNameInfo &NameInfo,
+                               QualType T, TypeSourceInfo *TInfo,
+                               StorageClass SC,
+                               bool isInline,
+                               bool isConstexpr,
+                               SourceLocation EndLocation);
+
+  static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  bool isStatic() const;
+  bool isInstance() const { return !isStatic(); }
+
+  /// Returns true if the given operator is implicitly static in a record
+  /// context.
+  static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
+    // [class.free]p1:
+    // Any allocation function for a class T is a static member
+    // (even if not explicitly declared static).
+    // [class.free]p6 Any deallocation function for a class X is a static member
+    // (even if not explicitly declared static).
+    return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete ||
+           OOK == OO_Array_Delete;
+  }
+
+  bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
+  bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
+
+  bool isVirtual() const {
+    CXXMethodDecl *CD =
+      cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
+
+    // Member function is virtual if it is marked explicitly so, or if it is
+    // declared in __interface -- then it is automatically pure virtual.
+    if (CD->isVirtualAsWritten() || CD->isPure())
+      return true;
+
+    return (CD->begin_overridden_methods() != CD->end_overridden_methods());
+  }
+
+  /// \brief Determine whether this is a usual deallocation function
+  /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
+  /// delete or delete[] operator with a particular signature.
+  bool isUsualDeallocationFunction() const;
+
+  /// \brief Determine whether this is a copy-assignment operator, regardless
+  /// of whether it was declared implicitly or explicitly.
+  bool isCopyAssignmentOperator() const;
+
+  /// \brief Determine whether this is a move assignment operator.
+  bool isMoveAssignmentOperator() const;
+
+  CXXMethodDecl *getCanonicalDecl() override {
+    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  const CXXMethodDecl *getCanonicalDecl() const override {
+    return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
+  }
+
+  CXXMethodDecl *getMostRecentDecl() {
+    return cast<CXXMethodDecl>(
+            static_cast<FunctionDecl *>(this)->getMostRecentDecl());
+  }
+  const CXXMethodDecl *getMostRecentDecl() const {
+    return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl();
+  }
+
+  /// True if this method is user-declared and was not
+  /// deleted or defaulted on its first declaration.
+  bool isUserProvided() const {
+    return !(isDeleted() || getCanonicalDecl()->isDefaulted());
+  }
+
+  ///
+  void addOverriddenMethod(const CXXMethodDecl *MD);
+
+  typedef const CXXMethodDecl *const* method_iterator;
+
+  method_iterator begin_overridden_methods() const;
+  method_iterator end_overridden_methods() const;
+  unsigned size_overridden_methods() const;
+
+  /// Returns the parent of this method declaration, which
+  /// is the class in which this method is defined.
+  const CXXRecordDecl *getParent() const {
+    return cast<CXXRecordDecl>(FunctionDecl::getParent());
+  }
+
+  /// Returns the parent of this method declaration, which
+  /// is the class in which this method is defined.
+  CXXRecordDecl *getParent() {
+    return const_cast<CXXRecordDecl *>(
+             cast<CXXRecordDecl>(FunctionDecl::getParent()));
+  }
+
+  /// \brief Returns the type of the \c this pointer.
+  ///
+  /// Should only be called for instance (i.e., non-static) methods.
+  QualType getThisType(ASTContext &C) const;
+
+  unsigned getTypeQualifiers() const {
+    return getType()->getAs<FunctionProtoType>()->getTypeQuals();
+  }
+
+  /// \brief Retrieve the ref-qualifier associated with this method.
+  ///
+  /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
+  /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
+  /// @code
+  /// struct X {
+  ///   void f() &;
+  ///   void g() &&;
+  ///   void h();
+  /// };
+  /// @endcode
+  RefQualifierKind getRefQualifier() const {
+    return getType()->getAs<FunctionProtoType>()->getRefQualifier();
+  }
+
+  bool hasInlineBody() const;
+
+  /// \brief Determine whether this is a lambda closure type's static member
+  /// function that is used for the result of the lambda's conversion to
+  /// function pointer (for a lambda with no captures).
+  ///
+  /// The function itself, if used, will have a placeholder body that will be
+  /// supplied by IR generation to either forward to the function call operator
+  /// or clone the function call operator.
+  bool isLambdaStaticInvoker() const;
+
+  /// \brief Find the method in \p RD that corresponds to this one.
+  ///
+  /// Find if \p RD or one of the classes it inherits from override this method.
+  /// If so, return it. \p RD is assumed to be a subclass of the class defining
+  /// this method (or be the class itself), unless \p MayBeBase is set to true.
+  CXXMethodDecl *
+  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+                                bool MayBeBase = false);
+
+  const CXXMethodDecl *
+  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+                                bool MayBeBase = false) const {
+    return const_cast<CXXMethodDecl *>(this)
+              ->getCorrespondingMethodInClass(RD, MayBeBase);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstCXXMethod && K <= lastCXXMethod;
+  }
+};
+
+/// \brief Represents a C++ base or member initializer.
+///
+/// This is part of a constructor initializer that
+/// initializes one non-static member variable or one base class. For
+/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
+/// initializers:
+///
+/// \code
+/// class A { };
+/// class B : public A {
+///   float f;
+/// public:
+///   B(A& a) : A(a), f(3.14159) { }
+/// };
+/// \endcode
+class CXXCtorInitializer {
+  /// \brief Either the base class name/delegating constructor type (stored as
+  /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
+  /// (IndirectFieldDecl*) being initialized.
+  llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
+    Initializee;
+
+  /// \brief The source location for the field name or, for a base initializer
+  /// pack expansion, the location of the ellipsis.
+  ///
+  /// In the case of a delegating
+  /// constructor, it will still include the type's source location as the
+  /// Initializee points to the CXXConstructorDecl (to allow loop detection).
+  SourceLocation MemberOrEllipsisLocation;
+
+  /// \brief The argument used to initialize the base or member, which may
+  /// end up constructing an object (when multiple arguments are involved).
+  Stmt *Init;
+
+  /// \brief Location of the left paren of the ctor-initializer.
+  SourceLocation LParenLoc;
+
+  /// \brief Location of the right paren of the ctor-initializer.
+  SourceLocation RParenLoc;
+
+  /// \brief If the initializee is a type, whether that type makes this
+  /// a delegating initialization.
+  bool IsDelegating : 1;
+
+  /// \brief If the initializer is a base initializer, this keeps track
+  /// of whether the base is virtual or not.
+  bool IsVirtual : 1;
+
+  /// \brief Whether or not the initializer is explicitly written
+  /// in the sources.
+  bool IsWritten : 1;
+
+  /// If IsWritten is true, then this number keeps track of the textual order
+  /// of this initializer in the original sources, counting from 0; otherwise,
+  /// it stores the number of array index variables stored after this object
+  /// in memory.
+  unsigned SourceOrderOrNumArrayIndices : 13;
+
+  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
+                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+                     SourceLocation R, VarDecl **Indices, unsigned NumIndices);
+
+public:
+  /// \brief Creates a new base-class initializer.
+  explicit
+  CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
+                     SourceLocation L, Expr *Init, SourceLocation R,
+                     SourceLocation EllipsisLoc);
+
+  /// \brief Creates a new member initializer.
+  explicit
+  CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
+                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+                     SourceLocation R);
+
+  /// \brief Creates a new anonymous field initializer.
+  explicit
+  CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
+                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+                     SourceLocation R);
+
+  /// \brief Creates a new delegating initializer.
+  explicit
+  CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
+                     SourceLocation L, Expr *Init, SourceLocation R);
+
+  /// \brief Creates a new member initializer that optionally contains
+  /// array indices used to describe an elementwise initialization.
+  static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
+                                    SourceLocation MemberLoc, SourceLocation L,
+                                    Expr *Init, SourceLocation R,
+                                    VarDecl **Indices, unsigned NumIndices);
+
+  /// \brief Determine whether this initializer is initializing a base class.
+  bool isBaseInitializer() const {
+    return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
+  }
+
+  /// \brief Determine whether this initializer is initializing a non-static
+  /// data member.
+  bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
+
+  bool isAnyMemberInitializer() const {
+    return isMemberInitializer() || isIndirectMemberInitializer();
+  }
+
+  bool isIndirectMemberInitializer() const {
+    return Initializee.is<IndirectFieldDecl*>();
+  }
+
+  /// \brief Determine whether this initializer is an implicit initializer
+  /// generated for a field with an initializer defined on the member
+  /// declaration.
+  ///
+  /// In-class member initializers (also known as "non-static data member
+  /// initializations", NSDMIs) were introduced in C++11.
+  bool isInClassMemberInitializer() const {
+    return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
+  }
+
+  /// \brief Determine whether this initializer is creating a delegating
+  /// constructor.
+  bool isDelegatingInitializer() const {
+    return Initializee.is<TypeSourceInfo*>() && IsDelegating;
+  }
+
+  /// \brief Determine whether this initializer is a pack expansion.
+  bool isPackExpansion() const {
+    return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
+  }
+
+  // \brief For a pack expansion, returns the location of the ellipsis.
+  SourceLocation getEllipsisLoc() const {
+    assert(isPackExpansion() && "Initializer is not a pack expansion");
+    return MemberOrEllipsisLocation;
+  }
+
+  /// If this is a base class initializer, returns the type of the
+  /// base class with location information. Otherwise, returns an NULL
+  /// type location.
+  TypeLoc getBaseClassLoc() const;
+
+  /// If this is a base class initializer, returns the type of the base class.
+  /// Otherwise, returns null.
+  const Type *getBaseClass() const;
+
+  /// Returns whether the base is virtual or not.
+  bool isBaseVirtual() const {
+    assert(isBaseInitializer() && "Must call this on base initializer!");
+
+    return IsVirtual;
+  }
+
+  /// \brief Returns the declarator information for a base class or delegating
+  /// initializer.
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return Initializee.dyn_cast<TypeSourceInfo *>();
+  }
+
+  /// \brief If this is a member initializer, returns the declaration of the
+  /// non-static data member being initialized. Otherwise, returns null.
+  FieldDecl *getMember() const {
+    if (isMemberInitializer())
+      return Initializee.get<FieldDecl*>();
+    return nullptr;
+  }
+  FieldDecl *getAnyMember() const {
+    if (isMemberInitializer())
+      return Initializee.get<FieldDecl*>();
+    if (isIndirectMemberInitializer())
+      return Initializee.get<IndirectFieldDecl*>()->getAnonField();
+    return nullptr;
+  }
+
+  IndirectFieldDecl *getIndirectMember() const {
+    if (isIndirectMemberInitializer())
+      return Initializee.get<IndirectFieldDecl*>();
+    return nullptr;
+  }
+
+  SourceLocation getMemberLocation() const {
+    return MemberOrEllipsisLocation;
+  }
+
+  /// \brief Determine the source location of the initializer.
+  SourceLocation getSourceLocation() const;
+
+  /// \brief Determine the source range covering the entire initializer.
+  SourceRange getSourceRange() const LLVM_READONLY;
+
+  /// \brief Determine whether this initializer is explicitly written
+  /// in the source code.
+  bool isWritten() const { return IsWritten; }
+
+  /// \brief Return the source position of the initializer, counting from 0.
+  /// If the initializer was implicit, -1 is returned.
+  int getSourceOrder() const {
+    return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
+  }
+
+  /// \brief Set the source order of this initializer.
+  ///
+  /// This can only be called once for each initializer; it cannot be called
+  /// on an initializer having a positive number of (implicit) array indices.
+  ///
+  /// This assumes that the initialzier was written in the source code, and
+  /// ensures that isWritten() returns true.
+  void setSourceOrder(int pos) {
+    assert(!IsWritten &&
+           "calling twice setSourceOrder() on the same initializer");
+    assert(SourceOrderOrNumArrayIndices == 0 &&
+           "setSourceOrder() used when there are implicit array indices");
+    assert(pos >= 0 &&
+           "setSourceOrder() used to make an initializer implicit");
+    IsWritten = true;
+    SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
+  }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  /// \brief Determine the number of implicit array indices used while
+  /// described an array member initialization.
+  unsigned getNumArrayIndices() const {
+    return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
+  }
+
+  /// \brief Retrieve a particular array index variable used to
+  /// describe an array member initialization.
+  VarDecl *getArrayIndex(unsigned I) {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    return reinterpret_cast<VarDecl **>(this + 1)[I];
+  }
+  const VarDecl *getArrayIndex(unsigned I) const {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
+  }
+  void setArrayIndex(unsigned I, VarDecl *Index) {
+    assert(I < getNumArrayIndices() && "Out of bounds member array index");
+    reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
+  }
+  ArrayRef<VarDecl *> getArrayIndexes() {
+    assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init");
+    return ArrayRef<VarDecl *>(reinterpret_cast<VarDecl **>(this + 1),
+                               getNumArrayIndices());
+  }
+
+  /// \brief Get the initializer.
+  Expr *getInit() const { return static_cast<Expr*>(Init); }
+};
+
+/// \brief Represents a C++ constructor within a class.
+///
+/// For example:
+///
+/// \code
+/// class X {
+/// public:
+///   explicit X(int); // represented by a CXXConstructorDecl.
+/// };
+/// \endcode
+class CXXConstructorDecl : public CXXMethodDecl {
+  void anchor() override;
+  /// \brief Whether this constructor declaration has the \c explicit keyword
+  /// specified.
+  bool IsExplicitSpecified : 1;
+
+  /// \name Support for base and member initializers.
+  /// \{
+  /// \brief The arguments used to initialize the base or member.
+  CXXCtorInitializer **CtorInitializers;
+  unsigned NumCtorInitializers;
+  /// \}
+
+  CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+                     const DeclarationNameInfo &NameInfo,
+                     QualType T, TypeSourceInfo *TInfo,
+                     bool isExplicitSpecified, bool isInline,
+                     bool isImplicitlyDeclared, bool isConstexpr)
+    : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
+                    SC_None, isInline, isConstexpr, SourceLocation()),
+      IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
+      NumCtorInitializers(0) {
+    setImplicit(isImplicitlyDeclared);
+  }
+
+public:
+  static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                    SourceLocation StartLoc,
+                                    const DeclarationNameInfo &NameInfo,
+                                    QualType T, TypeSourceInfo *TInfo,
+                                    bool isExplicit,
+                                    bool isInline, bool isImplicitlyDeclared,
+                                    bool isConstexpr);
+
+  /// \brief Determine whether this constructor declaration has the
+  /// \c explicit keyword specified.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+  /// \brief Determine whether this constructor was marked "explicit" or not.
+  bool isExplicit() const {
+    return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
+  }
+
+  /// \brief Iterates through the member/base initializer list.
+  typedef CXXCtorInitializer **init_iterator;
+
+  /// \brief Iterates through the member/base initializer list.
+  typedef CXXCtorInitializer * const * init_const_iterator;
+
+  typedef llvm::iterator_range<init_iterator> init_range;
+  typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+  init_range inits() { return init_range(init_begin(), init_end()); }
+  init_const_range inits() const {
+    return init_const_range(init_begin(), init_end());
+  }
+
+  /// \brief Retrieve an iterator to the first initializer.
+  init_iterator       init_begin()       { return CtorInitializers; }
+  /// \brief Retrieve an iterator to the first initializer.
+  init_const_iterator init_begin() const { return CtorInitializers; }
+
+  /// \brief Retrieve an iterator past the last initializer.
+  init_iterator       init_end()       {
+    return CtorInitializers + NumCtorInitializers;
+  }
+  /// \brief Retrieve an iterator past the last initializer.
+  init_const_iterator init_end() const {
+    return CtorInitializers + NumCtorInitializers;
+  }
+
+  typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
+  typedef std::reverse_iterator<init_const_iterator>
+          init_const_reverse_iterator;
+
+  init_reverse_iterator init_rbegin() {
+    return init_reverse_iterator(init_end());
+  }
+  init_const_reverse_iterator init_rbegin() const {
+    return init_const_reverse_iterator(init_end());
+  }
+
+  init_reverse_iterator init_rend() {
+    return init_reverse_iterator(init_begin());
+  }
+  init_const_reverse_iterator init_rend() const {
+    return init_const_reverse_iterator(init_begin());
+  }
+
+  /// \brief Determine the number of arguments used to initialize the member
+  /// or base.
+  unsigned getNumCtorInitializers() const {
+      return NumCtorInitializers;
+  }
+
+  void setNumCtorInitializers(unsigned numCtorInitializers) {
+    NumCtorInitializers = numCtorInitializers;
+  }
+
+  void setCtorInitializers(CXXCtorInitializer ** initializers) {
+    CtorInitializers = initializers;
+  }
+
+  /// \brief Determine whether this constructor is a delegating constructor.
+  bool isDelegatingConstructor() const {
+    return (getNumCtorInitializers() == 1) &&
+      CtorInitializers[0]->isDelegatingInitializer();
+  }
+
+  /// \brief When this constructor delegates to another, retrieve the target.
+  CXXConstructorDecl *getTargetConstructor() const;
+
+  /// Whether this constructor is a default
+  /// constructor (C++ [class.ctor]p5), which can be used to
+  /// default-initialize a class of this type.
+  bool isDefaultConstructor() const;
+
+  /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2,
+  /// which can be used to copy the class.
+  ///
+  /// \p TypeQuals will be set to the qualifiers on the
+  /// argument type. For example, \p TypeQuals would be set to \c
+  /// Qualifiers::Const for the following copy constructor:
+  ///
+  /// \code
+  /// class X {
+  /// public:
+  ///   X(const X&);
+  /// };
+  /// \endcode
+  bool isCopyConstructor(unsigned &TypeQuals) const;
+
+  /// Whether this constructor is a copy
+  /// constructor (C++ [class.copy]p2, which can be used to copy the
+  /// class.
+  bool isCopyConstructor() const {
+    unsigned TypeQuals = 0;
+    return isCopyConstructor(TypeQuals);
+  }
+
+  /// \brief Determine whether this constructor is a move constructor
+  /// (C++0x [class.copy]p3), which can be used to move values of the class.
+  ///
+  /// \param TypeQuals If this constructor is a move constructor, will be set
+  /// to the type qualifiers on the referent of the first parameter's type.
+  bool isMoveConstructor(unsigned &TypeQuals) const;
+
+  /// \brief Determine whether this constructor is a move constructor
+  /// (C++0x [class.copy]p3), which can be used to move values of the class.
+  bool isMoveConstructor() const {
+    unsigned TypeQuals = 0;
+    return isMoveConstructor(TypeQuals);
+  }
+
+  /// \brief Determine whether this is a copy or move constructor.
+  ///
+  /// \param TypeQuals Will be set to the type qualifiers on the reference
+  /// parameter, if in fact this is a copy or move constructor.
+  bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
+
+  /// \brief Determine whether this a copy or move constructor.
+  bool isCopyOrMoveConstructor() const {
+    unsigned Quals;
+    return isCopyOrMoveConstructor(Quals);
+  }
+
+  /// Whether this constructor is a
+  /// converting constructor (C++ [class.conv.ctor]), which can be
+  /// used for user-defined conversions.
+  bool isConvertingConstructor(bool AllowExplicit) const;
+
+  /// \brief Determine whether this is a member template specialization that
+  /// would copy the object to itself. Such constructors are never used to copy
+  /// an object.
+  bool isSpecializationCopyingObject() const;
+
+  /// \brief Get the constructor that this inheriting constructor is based on.
+  const CXXConstructorDecl *getInheritedConstructor() const;
+
+  /// \brief Set the constructor that this inheriting constructor is based on.
+  void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
+
+  const CXXConstructorDecl *getCanonicalDecl() const override {
+    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  CXXConstructorDecl *getCanonicalDecl() override {
+    return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == CXXConstructor; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a C++ destructor within a class.
+///
+/// For example:
+///
+/// \code
+/// class X {
+/// public:
+///   ~X(); // represented by a CXXDestructorDecl.
+/// };
+/// \endcode
+class CXXDestructorDecl : public CXXMethodDecl {
+  void anchor() override;
+
+  FunctionDecl *OperatorDelete;
+
+  CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+                    const DeclarationNameInfo &NameInfo,
+                    QualType T, TypeSourceInfo *TInfo,
+                    bool isInline, bool isImplicitlyDeclared)
+    : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
+                    SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
+      OperatorDelete(nullptr) {
+    setImplicit(isImplicitlyDeclared);
+  }
+
+public:
+  static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                   SourceLocation StartLoc,
+                                   const DeclarationNameInfo &NameInfo,
+                                   QualType T, TypeSourceInfo* TInfo,
+                                   bool isInline,
+                                   bool isImplicitlyDeclared);
+  static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
+
+  void setOperatorDelete(FunctionDecl *OD) {
+    cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+  }
+  const FunctionDecl *getOperatorDelete() const {
+    return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == CXXDestructor; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a C++ conversion function within a class.
+///
+/// For example:
+///
+/// \code
+/// class X {
+/// public:
+///   operator bool();
+/// };
+/// \endcode
+class CXXConversionDecl : public CXXMethodDecl {
+  void anchor() override;
+  /// Whether this conversion function declaration is marked
+  /// "explicit", meaning that it can only be applied when the user
+  /// explicitly wrote a cast. This is a C++0x feature.
+  bool IsExplicitSpecified : 1;
+
+  CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+                    const DeclarationNameInfo &NameInfo,
+                    QualType T, TypeSourceInfo *TInfo,
+                    bool isInline, bool isExplicitSpecified,
+                    bool isConstexpr, SourceLocation EndLocation)
+    : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
+                    SC_None, isInline, isConstexpr, EndLocation),
+      IsExplicitSpecified(isExplicitSpecified) { }
+
+public:
+  static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                                   SourceLocation StartLoc,
+                                   const DeclarationNameInfo &NameInfo,
+                                   QualType T, TypeSourceInfo *TInfo,
+                                   bool isInline, bool isExplicit,
+                                   bool isConstexpr,
+                                   SourceLocation EndLocation);
+  static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// Whether this conversion function declaration is marked
+  /// "explicit", meaning that it can only be used for direct initialization
+  /// (including explitly written casts).  This is a C++11 feature.
+  bool isExplicitSpecified() const { return IsExplicitSpecified; }
+
+  /// \brief Whether this is an explicit conversion operator (C++11 and later).
+  ///
+  /// Explicit conversion operators are only considered for direct
+  /// initialization, e.g., when the user has explicitly written a cast.
+  bool isExplicit() const {
+    return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
+  }
+
+  /// \brief Returns the type that this conversion function is converting to.
+  QualType getConversionType() const {
+    return getType()->getAs<FunctionType>()->getReturnType();
+  }
+
+  /// \brief Determine whether this conversion function is a conversion from
+  /// a lambda closure type to a block pointer.
+  bool isLambdaToBlockPointerConversion() const;
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == CXXConversion; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a linkage specification. 
+///
+/// For example:
+/// \code
+///   extern "C" void foo();
+/// \endcode
+class LinkageSpecDecl : public Decl, public DeclContext {
+  virtual void anchor();
+public:
+  /// \brief Represents the language in a linkage specification.
+  ///
+  /// The values are part of the serialization ABI for
+  /// ASTs and cannot be changed without altering that ABI.  To help
+  /// ensure a stable ABI for this, we choose the DW_LANG_ encodings
+  /// from the dwarf standard.
+  enum LanguageIDs {
+    lang_c = /* DW_LANG_C */ 0x0002,
+    lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
+  };
+private:
+  /// \brief The language for this linkage specification.
+  unsigned Language : 3;
+  /// \brief True if this linkage spec has braces.
+  ///
+  /// This is needed so that hasBraces() returns the correct result while the
+  /// linkage spec body is being parsed.  Once RBraceLoc has been set this is
+  /// not used, so it doesn't need to be serialized.
+  unsigned HasBraces : 1;
+  /// \brief The source location for the extern keyword.
+  SourceLocation ExternLoc;
+  /// \brief The source location for the right brace (if valid).
+  SourceLocation RBraceLoc;
+
+  LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+                  SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
+    : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+      Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc),
+      RBraceLoc(SourceLocation()) { }
+
+public:
+  static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation ExternLoc,
+                                 SourceLocation LangLoc, LanguageIDs Lang,
+                                 bool HasBraces);
+  static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  /// \brief Return the language specified by this linkage specification.
+  LanguageIDs getLanguage() const { return LanguageIDs(Language); }
+  /// \brief Set the language specified by this linkage specification.
+  void setLanguage(LanguageIDs L) { Language = L; }
+
+  /// \brief Determines whether this linkage specification had braces in
+  /// its syntactic form.
+  bool hasBraces() const {
+    assert(!RBraceLoc.isValid() || HasBraces);
+    return HasBraces;
+  }
+
+  SourceLocation getExternLoc() const { return ExternLoc; }
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setExternLoc(SourceLocation L) { ExternLoc = L; }
+  void setRBraceLoc(SourceLocation L) {
+    RBraceLoc = L;
+    HasBraces = RBraceLoc.isValid();
+  }
+
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (hasBraces())
+      return getRBraceLoc();
+    // No braces: get the end location of the (only) declaration in context
+    // (if present).
+    return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(ExternLoc, getLocEnd());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == LinkageSpec; }
+  static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
+    return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
+  }
+  static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// \brief Represents C++ using-directive.
+///
+/// For example:
+/// \code
+///    using namespace std;
+/// \endcode
+///
+/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide
+/// artificial names for all using-directives in order to store
+/// them in DeclContext effectively.
+class UsingDirectiveDecl : public NamedDecl {
+  void anchor() override;
+  /// \brief The location of the \c using keyword.
+  SourceLocation UsingLoc;
+
+  /// \brief The location of the \c namespace keyword.
+  SourceLocation NamespaceLoc;
+
+  /// \brief The nested-name-specifier that precedes the namespace.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief The namespace nominated by this using-directive.
+  NamedDecl *NominatedNamespace;
+
+  /// Enclosing context containing both using-directive and nominated
+  /// namespace.
+  DeclContext *CommonAncestor;
+
+  /// \brief Returns special DeclarationName used by using-directives.
+  ///
+  /// This is only used by DeclContext for storing UsingDirectiveDecls in
+  /// its lookup structure.
+  static DeclarationName getName() {
+    return DeclarationName::getUsingDirectiveName();
+  }
+
+  UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc,
+                     SourceLocation NamespcLoc,
+                     NestedNameSpecifierLoc QualifierLoc,
+                     SourceLocation IdentLoc,
+                     NamedDecl *Nominated,
+                     DeclContext *CommonAncestor)
+    : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc),
+      NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc),
+      NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { }
+
+public:
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace, with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
+  const NamedDecl *getNominatedNamespaceAsWritten() const {
+    return NominatedNamespace;
+  }
+
+  /// \brief Returns the namespace nominated by this using-directive.
+  NamespaceDecl *getNominatedNamespace();
+
+  const NamespaceDecl *getNominatedNamespace() const {
+    return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
+  }
+
+  /// \brief Returns the common ancestor context of this using-directive and
+  /// its nominated namespace.
+  DeclContext *getCommonAncestor() { return CommonAncestor; }
+  const DeclContext *getCommonAncestor() const { return CommonAncestor; }
+
+  /// \brief Return the location of the \c using keyword.
+  SourceLocation getUsingLoc() const { return UsingLoc; }
+
+  // FIXME: Could omit 'Key' in name.
+  /// \brief Returns the location of the \c namespace keyword.
+  SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
+
+  /// \brief Returns the location of this using declaration's identifier.
+  SourceLocation getIdentLocation() const { return getLocation(); }
+
+  static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
+                                    SourceLocation UsingLoc,
+                                    SourceLocation NamespaceLoc,
+                                    NestedNameSpecifierLoc QualifierLoc,
+                                    SourceLocation IdentLoc,
+                                    NamedDecl *Nominated,
+                                    DeclContext *CommonAncestor);
+  static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(UsingLoc, getLocation());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == UsingDirective; }
+
+  // Friend for getUsingDirectiveName.
+  friend class DeclContext;
+
+  friend class ASTDeclReader;
+};
+
+/// \brief Represents a C++ namespace alias.
+///
+/// For example:
+///
+/// \code
+/// namespace Foo = Bar;
+/// \endcode
+class NamespaceAliasDecl : public NamedDecl {
+  void anchor() override;
+
+  /// \brief The location of the \c namespace keyword.
+  SourceLocation NamespaceLoc;
+
+  /// \brief The location of the namespace's identifier.
+  ///
+  /// This is accessed by TargetNameLoc.
+  SourceLocation IdentLoc;
+
+  /// \brief The nested-name-specifier that precedes the namespace.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief The Decl that this alias points to, either a NamespaceDecl or
+  /// a NamespaceAliasDecl.
+  NamedDecl *Namespace;
+
+  NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
+                     SourceLocation AliasLoc, IdentifierInfo *Alias,
+                     NestedNameSpecifierLoc QualifierLoc,
+                     SourceLocation IdentLoc, NamedDecl *Namespace)
+    : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias),
+      NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
+      QualifierLoc(QualifierLoc), Namespace(Namespace) { }
+
+  friend class ASTDeclReader;
+
+public:
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace, with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief Retrieve the namespace declaration aliased by this directive.
+  NamespaceDecl *getNamespace() {
+    if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
+      return AD->getNamespace();
+
+    return cast<NamespaceDecl>(Namespace);
+  }
+
+  const NamespaceDecl *getNamespace() const {
+    return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
+  }
+
+  /// Returns the location of the alias name, i.e. 'foo' in
+  /// "namespace foo = ns::bar;".
+  SourceLocation getAliasLoc() const { return getLocation(); }
+
+  /// Returns the location of the \c namespace keyword.
+  SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
+
+  /// Returns the location of the identifier in the named namespace.
+  SourceLocation getTargetNameLoc() const { return IdentLoc; }
+
+  /// \brief Retrieve the namespace that this alias refers to, which
+  /// may either be a NamespaceDecl or a NamespaceAliasDecl.
+  NamedDecl *getAliasedNamespace() const { return Namespace; }
+
+  static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                                    SourceLocation NamespaceLoc,
+                                    SourceLocation AliasLoc,
+                                    IdentifierInfo *Alias,
+                                    NestedNameSpecifierLoc QualifierLoc,
+                                    SourceLocation IdentLoc,
+                                    NamedDecl *Namespace);
+
+  static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(NamespaceLoc, IdentLoc);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == NamespaceAlias; }
+};
+
+/// \brief Represents a shadow declaration introduced into a scope by a
+/// (resolved) using declaration.
+///
+/// For example,
+/// \code
+/// namespace A {
+///   void foo();
+/// }
+/// namespace B {
+///   using A::foo; // <- a UsingDecl
+///                 // Also creates a UsingShadowDecl for A::foo() in B
+/// }
+/// \endcode
+class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
+  void anchor() override;
+
+  /// The referenced declaration.
+  NamedDecl *Underlying;
+
+  /// \brief The using declaration which introduced this decl or the next using
+  /// shadow declaration contained in the aforementioned using declaration.
+  NamedDecl *UsingOrNextShadow;
+  friend class UsingDecl;
+
+  UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+                  UsingDecl *Using, NamedDecl *Target)
+    : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
+      redeclarable_base(C), Underlying(Target),
+      UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
+    if (Target) {
+      setDeclName(Target->getDeclName());
+      IdentifierNamespace = Target->getIdentifierNamespace();
+    }
+    setImplicit();
+  }
+
+  typedef Redeclarable<UsingShadowDecl> redeclarable_base;
+  UsingShadowDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  UsingShadowDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  UsingShadowDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation Loc, UsingDecl *Using,
+                                 NamedDecl *Target) {
+    return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
+  }
+
+  static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+
+  UsingShadowDecl *getCanonicalDecl() override {
+    return getFirstDecl();
+  }
+  const UsingShadowDecl *getCanonicalDecl() const {
+    return getFirstDecl();
+  }
+
+  /// \brief Gets the underlying declaration which has been brought into the
+  /// local scope.
+  NamedDecl *getTargetDecl() const { return Underlying; }
+
+  /// \brief Sets the underlying declaration which has been brought into the
+  /// local scope.
+  void setTargetDecl(NamedDecl* ND) {
+    assert(ND && "Target decl is null!");
+    Underlying = ND;
+    IdentifierNamespace = ND->getIdentifierNamespace();
+  }
+
+  /// \brief Gets the using declaration to which this declaration is tied.
+  UsingDecl *getUsingDecl() const;
+
+  /// \brief The next using shadow declaration contained in the shadow decl
+  /// chain of the using declaration which introduced this decl.
+  UsingShadowDecl *getNextUsingShadowDecl() const {
+    return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a C++ using-declaration.
+///
+/// For example:
+/// \code
+///    using someNameSpace::someIdentifier;
+/// \endcode
+class UsingDecl : public NamedDecl {
+  void anchor() override;
+
+  /// \brief The source location of the 'using' keyword itself.
+  SourceLocation UsingLocation;
+
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief Provides source/type location info for the declaration name
+  /// embedded in the ValueDecl base class.
+  DeclarationNameLoc DNLoc;
+
+  /// \brief The first shadow declaration of the shadow decl chain associated
+  /// with this using declaration.
+  ///
+  /// The bool member of the pair store whether this decl has the \c typename
+  /// keyword.
+  llvm::PointerIntPair<UsingShadowDecl *, 1, bool> FirstUsingShadow;
+
+  UsingDecl(DeclContext *DC, SourceLocation UL,
+            NestedNameSpecifierLoc QualifierLoc,
+            const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
+    : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
+      UsingLocation(UL), QualifierLoc(QualifierLoc),
+      DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
+  }
+
+public:
+  /// \brief Return the source location of the 'using' keyword.
+  SourceLocation getUsingLoc() const { return UsingLocation; }
+
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
+  /// \brief Return true if it is a C++03 access declaration (no 'using').
+  bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
+
+  /// \brief Return true if the using declaration has 'typename'.
+  bool hasTypename() const { return FirstUsingShadow.getInt(); }
+
+  /// \brief Sets whether the using declaration has 'typename'.
+  void setTypename(bool TN) { FirstUsingShadow.setInt(TN); }
+
+  /// \brief Iterates through the using shadow declarations associated with
+  /// this using declaration.
+  class shadow_iterator {
+    /// \brief The current using shadow declaration.
+    UsingShadowDecl *Current;
+
+  public:
+    typedef UsingShadowDecl*          value_type;
+    typedef UsingShadowDecl*          reference;
+    typedef UsingShadowDecl*          pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    shadow_iterator() : Current(nullptr) { }
+    explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    shadow_iterator& operator++() {
+      Current = Current->getNextUsingShadowDecl();
+      return *this;
+    }
+
+    shadow_iterator operator++(int) {
+      shadow_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(shadow_iterator x, shadow_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(shadow_iterator x, shadow_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  typedef llvm::iterator_range<shadow_iterator> shadow_range;
+
+  shadow_range shadows() const {
+    return shadow_range(shadow_begin(), shadow_end());
+  }
+  shadow_iterator shadow_begin() const {
+    return shadow_iterator(FirstUsingShadow.getPointer());
+  }
+  shadow_iterator shadow_end() const { return shadow_iterator(); }
+
+  /// \brief Return the number of shadowed declarations associated with this
+  /// using declaration.
+  unsigned shadow_size() const {
+    return std::distance(shadow_begin(), shadow_end());
+  }
+
+  void addShadowDecl(UsingShadowDecl *S);
+  void removeShadowDecl(UsingShadowDecl *S);
+
+  static UsingDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation UsingL,
+                           NestedNameSpecifierLoc QualifierLoc,
+                           const DeclarationNameInfo &NameInfo,
+                           bool HasTypenameKeyword);
+
+  static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Using; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a dependent using declaration which was not marked with
+/// \c typename.
+///
+/// Unlike non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// \code
+/// template \<class T> class A : public Base<T> {
+///   using Base<T>::foo;
+/// };
+/// \endcode
+class UnresolvedUsingValueDecl : public ValueDecl {
+  void anchor() override;
+
+  /// \brief The source location of the 'using' keyword
+  SourceLocation UsingLocation;
+
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief Provides source/type location info for the declaration name
+  /// embedded in the ValueDecl base class.
+  DeclarationNameLoc DNLoc;
+
+  UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+                           SourceLocation UsingLoc,
+                           NestedNameSpecifierLoc QualifierLoc,
+                           const DeclarationNameInfo &NameInfo)
+    : ValueDecl(UnresolvedUsingValue, DC,
+                NameInfo.getLoc(), NameInfo.getName(), Ty),
+      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
+      DNLoc(NameInfo.getInfo())
+  { }
+
+public:
+  /// \brief Returns the source location of the 'using' keyword.
+  SourceLocation getUsingLoc() const { return UsingLocation; }
+
+  /// \brief Set the source location of the 'using' keyword.
+  void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+
+  /// \brief Return true if it is a C++03 access declaration (no 'using').
+  bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
+  }
+
+  static UnresolvedUsingValueDecl *
+    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+           NestedNameSpecifierLoc QualifierLoc,
+           const DeclarationNameInfo &NameInfo);
+
+  static UnresolvedUsingValueDecl *
+  CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a dependent using declaration which was marked with
+/// \c typename.
+///
+/// \code
+/// template \<class T> class A : public Base<T> {
+///   using typename Base<T>::foo;
+/// };
+/// \endcode
+///
+/// The type associated with an unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+  void anchor() override;
+
+  /// \brief The source location of the 'typename' keyword
+  SourceLocation TypenameLocation;
+
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+                              SourceLocation TypenameLoc,
+                              NestedNameSpecifierLoc QualifierLoc,
+                              SourceLocation TargetNameLoc,
+                              IdentifierInfo *TargetName)
+    : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
+               UsingLoc),
+      TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
+
+  friend class ASTDeclReader;
+
+public:
+  /// \brief Returns the source location of the 'using' keyword.
+  SourceLocation getUsingLoc() const { return getLocStart(); }
+
+  /// \brief Returns the source location of the 'typename' keyword.
+  SourceLocation getTypenameLoc() const { return TypenameLocation; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  static UnresolvedUsingTypenameDecl *
+    Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+           SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
+           SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+  static UnresolvedUsingTypenameDecl *
+  CreateDeserialized(ASTContext &C, unsigned ID);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
+};
+
+/// \brief Represents a C++11 static_assert declaration.
+class StaticAssertDecl : public Decl {
+  virtual void anchor();
+  llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
+  StringLiteral *Message;
+  SourceLocation RParenLoc;
+
+  StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
+                   Expr *AssertExpr, StringLiteral *Message,
+                   SourceLocation RParenLoc, bool Failed)
+    : Decl(StaticAssert, DC, StaticAssertLoc),
+      AssertExprAndFailed(AssertExpr, Failed), Message(Message),
+      RParenLoc(RParenLoc) { }
+
+public:
+  static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation StaticAssertLoc,
+                                  Expr *AssertExpr, StringLiteral *Message,
+                                  SourceLocation RParenLoc, bool Failed);
+  static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
+  const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
+
+  StringLiteral *getMessage() { return Message; }
+  const StringLiteral *getMessage() const { return Message; }
+
+  bool isFailed() const { return AssertExprAndFailed.getInt(); }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(getLocation(), getRParenLoc());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == StaticAssert; }
+
+  friend class ASTDeclReader;
+};
+
+/// An instance of this class represents the declaration of a property
+/// member.  This is a Microsoft extension to C++, first introduced in
+/// Visual Studio .NET 2003 as a parallel to similar features in C#
+/// and Managed C++.
+///
+/// A property must always be a non-static class member.
+///
+/// A property member superficially resembles a non-static data
+/// member, except preceded by a property attribute:
+///   __declspec(property(get=GetX, put=PutX)) int x;
+/// Either (but not both) of the 'get' and 'put' names may be omitted.
+///
+/// A reference to a property is always an lvalue.  If the lvalue
+/// undergoes lvalue-to-rvalue conversion, then a getter name is
+/// required, and that member is called with no arguments.
+/// If the lvalue is assigned into, then a setter name is required,
+/// and that member is called with one argument, the value assigned.
+/// Both operations are potentially overloaded.  Compound assignments
+/// are permitted, as are the increment and decrement operators.
+///
+/// The getter and putter methods are permitted to be overloaded,
+/// although their return and parameter types are subject to certain
+/// restrictions according to the type of the property.
+///
+/// A property declared using an incomplete array type may
+/// additionally be subscripted, adding extra parameters to the getter
+/// and putter methods.
+class MSPropertyDecl : public DeclaratorDecl {
+  IdentifierInfo *GetterId, *SetterId;
+
+  MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
+                 QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
+                 IdentifierInfo *Getter, IdentifierInfo *Setter)
+      : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
+        GetterId(Getter), SetterId(Setter) {}
+
+public:
+  static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+                                SourceLocation L, DeclarationName N, QualType T,
+                                TypeSourceInfo *TInfo, SourceLocation StartL,
+                                IdentifierInfo *Getter, IdentifierInfo *Setter);
+  static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
+
+  bool hasGetter() const { return GetterId != nullptr; }
+  IdentifierInfo* getGetterId() const { return GetterId; }
+  bool hasSetter() const { return SetterId != nullptr; }
+  IdentifierInfo* getSetterId() const { return SetterId; }
+
+  friend class ASTDeclReader;
+};
+
+/// Insertion operator for diagnostics.  This allows sending an AccessSpecifier
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    AccessSpecifier AS);
+
+const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
+                                    AccessSpecifier AS);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
new file mode 100644
index 0000000..9068c00
--- /dev/null
+++ b/include/clang/AST/DeclContextInternals.h
@@ -0,0 +1,266 @@
+//===-- DeclContextInternals.h - DeclContext Representation -----*- 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 data structures used in the implementation
+//  of DeclContext.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
+#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+
+namespace clang {
+
+class DependentDiagnostic;
+
+/// \brief An array of decls optimized for the common case of only containing
+/// one entry.
+struct StoredDeclsList {
+
+  /// \brief When in vector form, this is what the Data pointer points to.
+  typedef SmallVector<NamedDecl *, 4> DeclsTy;
+
+  /// \brief A collection of declarations, with a flag to indicate if we have
+  /// further external declarations.
+  typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
+
+  /// \brief The stored data, which will be either a pointer to a NamedDecl,
+  /// or a pointer to a vector with a flag to indicate if there are further
+  /// external declarations.
+  llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
+
+public:
+  StoredDeclsList() {}
+
+  StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
+    RHS.Data = (NamedDecl *)nullptr;
+  }
+
+  ~StoredDeclsList() {
+    // If this is a vector-form, free the vector.
+    if (DeclsTy *Vector = getAsVector())
+      delete Vector;
+  }
+
+  StoredDeclsList &operator=(StoredDeclsList &&RHS) {
+    if (DeclsTy *Vector = getAsVector())
+      delete Vector;
+    Data = RHS.Data;
+    RHS.Data = (NamedDecl *)nullptr;
+    return *this;
+  }
+
+  bool isNull() const { return Data.isNull(); }
+
+  NamedDecl *getAsDecl() const {
+    return Data.dyn_cast<NamedDecl *>();
+  }
+
+  DeclsAndHasExternalTy getAsVectorAndHasExternal() const {
+    return Data.dyn_cast<DeclsAndHasExternalTy>();
+  }
+
+  DeclsTy *getAsVector() const {
+    return getAsVectorAndHasExternal().getPointer();
+  }
+
+  bool hasExternalDecls() const {
+    return getAsVectorAndHasExternal().getInt();
+  }
+
+  void setHasExternalDecls() {
+    if (DeclsTy *Vec = getAsVector())
+      Data = DeclsAndHasExternalTy(Vec, true);
+    else {
+      DeclsTy *VT = new DeclsTy();
+      if (NamedDecl *OldD = getAsDecl())
+        VT->push_back(OldD);
+      Data = DeclsAndHasExternalTy(VT, true);
+    }
+  }
+
+  void setOnlyValue(NamedDecl *ND) {
+    assert(!getAsVector() && "Not inline");
+    Data = ND;
+    // Make sure that Data is a plain NamedDecl* so we can use its address
+    // at getLookupResult.
+    assert(*(NamedDecl **)&Data == ND &&
+           "PointerUnion mangles the NamedDecl pointer!");
+  }
+
+  void remove(NamedDecl *D) {
+    assert(!isNull() && "removing from empty list");
+    if (NamedDecl *Singleton = getAsDecl()) {
+      assert(Singleton == D && "list is different singleton");
+      (void)Singleton;
+      Data = (NamedDecl *)nullptr;
+      return;
+    }
+
+    DeclsTy &Vec = *getAsVector();
+    DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
+    assert(I != Vec.end() && "list does not contain decl");
+    Vec.erase(I);
+
+    assert(std::find(Vec.begin(), Vec.end(), D)
+             == Vec.end() && "list still contains decl");
+  }
+
+  /// \brief Remove any declarations which were imported from an external
+  /// AST source.
+  void removeExternalDecls() {
+    if (isNull()) {
+      // Nothing to do.
+    } else if (NamedDecl *Singleton = getAsDecl()) {
+      if (Singleton->isFromASTFile())
+        *this = StoredDeclsList();
+    } else {
+      DeclsTy &Vec = *getAsVector();
+      Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
+                               std::mem_fun(&Decl::isFromASTFile)),
+                Vec.end());
+      // Don't have any external decls any more.
+      Data = DeclsAndHasExternalTy(&Vec, false);
+    }
+  }
+
+  /// getLookupResult - Return an array of all the decls that this list
+  /// represents.
+  DeclContext::lookup_result getLookupResult() {
+    if (isNull())
+      return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr),
+                                        DeclContext::lookup_iterator(nullptr));
+
+    // If we have a single NamedDecl, return it.
+    if (getAsDecl()) {
+      assert(!isNull() && "Empty list isn't allowed");
+
+      // Data is a raw pointer to a NamedDecl*, return it.
+      void *Ptr = &Data;
+      return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
+    }
+
+    assert(getAsVector() && "Must have a vector at this point");
+    DeclsTy &Vector = *getAsVector();
+
+    // Otherwise, we have a range result.
+    return DeclContext::lookup_result(Vector.begin(), Vector.end());
+  }
+
+  /// HandleRedeclaration - If this is a redeclaration of an existing decl,
+  /// replace the old one with D and return true.  Otherwise return false.
+  bool HandleRedeclaration(NamedDecl *D) {
+    // Most decls only have one entry in their list, special case it.
+    if (NamedDecl *OldD = getAsDecl()) {
+      if (!D->declarationReplaces(OldD))
+        return false;
+      setOnlyValue(D);
+      return true;
+    }
+
+    // Determine if this declaration is actually a redeclaration.
+    DeclsTy &Vec = *getAsVector();
+    for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
+         OD != ODEnd; ++OD) {
+      NamedDecl *OldD = *OD;
+      if (D->declarationReplaces(OldD)) {
+        *OD = D;
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /// AddSubsequentDecl - This is called on the second and later decl when it is
+  /// not a redeclaration to merge it into the appropriate place in our list.
+  ///
+  void AddSubsequentDecl(NamedDecl *D) {
+    assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
+
+    // If this is the second decl added to the list, convert this to vector
+    // form.
+    if (NamedDecl *OldD = getAsDecl()) {
+      DeclsTy *VT = new DeclsTy();
+      VT->push_back(OldD);
+      Data = DeclsAndHasExternalTy(VT, false);
+    }
+
+    DeclsTy &Vec = *getAsVector();
+
+    // Using directives end up in a special entry which contains only
+    // other using directives, so all this logic is wasted for them.
+    // But avoiding the logic wastes time in the far-more-common case
+    // that we're *not* adding a new using directive.
+
+    // Tag declarations always go at the end of the list so that an
+    // iterator which points at the first tag will start a span of
+    // decls that only contains tags.
+    if (D->hasTagIdentifierNamespace())
+      Vec.push_back(D);
+
+    // Resolved using declarations go at the front of the list so that
+    // they won't show up in other lookup results.  Unresolved using
+    // declarations (which are always in IDNS_Using | IDNS_Ordinary)
+    // follow that so that the using declarations will be contiguous.
+    else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
+      DeclsTy::iterator I = Vec.begin();
+      if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
+        while (I != Vec.end() &&
+               (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
+          ++I;
+      }
+      Vec.insert(I, D);
+
+    // All other declarations go at the end of the list, but before any
+    // tag declarations.  But we can be clever about tag declarations
+    // because there can only ever be one in a scope.
+    } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
+      NamedDecl *TagD = Vec.back();
+      Vec.back() = D;
+      Vec.push_back(TagD);
+    } else
+      Vec.push_back(D);
+  }
+};
+
+class StoredDeclsMap
+  : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
+
+public:
+  static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
+
+private:
+  friend class ASTContext; // walks the chain deleting these
+  friend class DeclContext;
+  llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
+};
+
+class DependentStoredDeclsMap : public StoredDeclsMap {
+public:
+  DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
+
+private:
+  friend class DependentDiagnostic;
+  friend class DeclContext; // iterates over diagnostics
+
+  DependentDiagnostic *FirstDiagnostic;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
new file mode 100644
index 0000000..12b93b4
--- /dev/null
+++ b/include/clang/AST/DeclFriend.h
@@ -0,0 +1,247 @@
+//===-- DeclFriend.h - Classes for C++ friend declarations -*- 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 section of the AST representing C++ friend
+// declarations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLFRIEND_H
+#define LLVM_CLANG_AST_DECLFRIEND_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+/// FriendDecl - Represents the declaration of a friend entity,
+/// which can be a function, a type, or a templated function or type.
+//  For example:
+///
+/// @code
+/// template <typename T> class A {
+///   friend int foo(T);
+///   friend class B;
+///   friend T; // only in C++0x
+///   template <typename U> friend class C;
+///   template <typename U> friend A& operator+=(A&, const U&) { ... }
+/// };
+/// @endcode
+///
+/// The semantic context of a friend decl is its declaring class.
+class FriendDecl : public Decl {
+  virtual void anchor();
+public:
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+
+private:
+  // The declaration that's a friend of this class.
+  FriendUnion Friend;
+
+  // A pointer to the next friend in the sequence.
+  LazyDeclPtr NextFriend;
+
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
+
+  /// True if this 'friend' declaration is unsupported.  Eventually we
+  /// will support every possible friend declaration, but for now we
+  /// silently ignore some and set this flag to authorize all access.
+  bool UnsupportedFriend : 1;
+
+  // The number of "outer" template parameter lists in non-templatic
+  // (currently unsupported) friend type declarations, such as
+  //     template <class T> friend class A<T>::B;
+  unsigned NumTPLists : 31;
+
+  // The tail-allocated friend type template parameter lists (if any).
+  TemplateParameterList* const *getTPLists() const {
+    return reinterpret_cast<TemplateParameterList* const *>(this + 1);
+  }
+  TemplateParameterList **getTPLists() {
+    return reinterpret_cast<TemplateParameterList**>(this + 1);
+  }
+
+  friend class CXXRecordDecl::friend_iterator;
+  friend class CXXRecordDecl;
+
+  FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
+             SourceLocation FriendL,
+             ArrayRef<TemplateParameterList*> FriendTypeTPLists)
+    : Decl(Decl::Friend, DC, L),
+      Friend(Friend),
+      NextFriend(),
+      FriendLoc(FriendL),
+      UnsupportedFriend(false),
+      NumTPLists(FriendTypeTPLists.size()) {
+    for (unsigned i = 0; i < NumTPLists; ++i)
+      getTPLists()[i] = FriendTypeTPLists[i];
+  }
+
+  FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
+    : Decl(Decl::Friend, Empty), NextFriend(),
+      NumTPLists(NumFriendTypeTPLists) { }
+
+  FriendDecl *getNextFriend() {
+    if (!NextFriend.isOffset())
+      return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
+    return getNextFriendSlowCase();
+  }
+  FriendDecl *getNextFriendSlowCase();
+
+public:
+  static FriendDecl *Create(ASTContext &C, DeclContext *DC,
+                            SourceLocation L, FriendUnion Friend_,
+                            SourceLocation FriendL,
+                            ArrayRef<TemplateParameterList*> FriendTypeTPLists
+                            = None);
+  static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+                                        unsigned FriendTypeNumTPLists);
+
+  /// If this friend declaration names an (untemplated but possibly
+  /// dependent) type, return the type; otherwise return null.  This
+  /// is used for elaborated-type-specifiers and, in C++0x, for
+  /// arbitrary friend type declarations.
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
+  }
+  unsigned getFriendTypeNumTemplateParameterLists() const {
+    return NumTPLists;
+  }
+  TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
+    assert(N < NumTPLists);
+    return getTPLists()[N];
+  }
+
+  /// If this friend declaration doesn't name a type, return the inner
+  /// declaration.
+  NamedDecl *getFriendDecl() const {
+    return Friend.dyn_cast<NamedDecl*>();
+  }
+
+  /// Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
+  }
+
+  /// Retrieves the source range for the friend declaration.
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    if (NamedDecl *ND = getFriendDecl()) {
+      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+        return FD->getSourceRange();
+      if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+        return FTD->getSourceRange();
+      if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+        return CTD->getSourceRange();
+      if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
+        if (DD->getOuterLocStart() != DD->getInnerLocStart())
+          return DD->getSourceRange();
+      }
+      return SourceRange(getFriendLoc(), ND->getLocEnd());
+    }
+    else if (TypeSourceInfo *TInfo = getFriendType()) {
+      SourceLocation StartL = (NumTPLists == 0)
+        ? getFriendLoc()
+        : getTPLists()[0]->getTemplateLoc();
+      return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
+    }
+    else
+      return SourceRange(getFriendLoc(), getLocation());
+  }
+
+  /// Determines if this friend kind is unsupported.
+  bool isUnsupportedFriend() const {
+    return UnsupportedFriend;
+  }
+  void setUnsupportedFriend(bool Unsupported) {
+    UnsupportedFriend = Unsupported;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Decl::Friend; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// An iterator over the friend declarations of a class.
+class CXXRecordDecl::friend_iterator {
+  FriendDecl *Ptr;
+
+  friend class CXXRecordDecl;
+  explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
+public:
+  friend_iterator() {}
+
+  typedef FriendDecl *value_type;
+  typedef FriendDecl *reference;
+  typedef FriendDecl *pointer;
+  typedef int difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+
+  reference operator*() const { return Ptr; }
+
+  friend_iterator &operator++() {
+    assert(Ptr && "attempt to increment past end of friend list");
+    Ptr = Ptr->getNextFriend();
+    return *this;
+  }
+
+  friend_iterator operator++(int) {
+    friend_iterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  bool operator==(const friend_iterator &Other) const {
+    return Ptr == Other.Ptr;
+  }
+
+  bool operator!=(const friend_iterator &Other) const {
+    return Ptr != Other.Ptr;
+  }
+
+  friend_iterator &operator+=(difference_type N) {
+    assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
+    while (N--)
+      ++*this;
+    return *this;
+  }
+
+  friend_iterator operator+(difference_type N) const {
+    friend_iterator tmp = *this;
+    tmp += N;
+    return tmp;
+  }
+};
+
+inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
+  return friend_iterator(getFirstFriend());
+}
+
+inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
+  return friend_iterator(nullptr);
+}
+
+inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
+  return friend_range(friend_begin(), friend_end());
+}
+
+inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
+  assert(!FD->NextFriend && "friend already has next friend?");
+  FD->NextFriend = data().FirstFriend;
+  data().FirstFriend = FD;
+}
+  
+}
+
+#endif
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
new file mode 100644
index 0000000..bd3dbd8
--- /dev/null
+++ b/include/clang/AST/DeclGroup.h
@@ -0,0 +1,155 @@
+//===--- DeclGroup.h - Classes for representing groups of Decls -*- 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 DeclGroup, DeclGroupRef, and OwningDeclGroup classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLGROUP_H
+#define LLVM_CLANG_AST_DECLGROUP_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DeclGroup;
+class DeclGroupIterator;
+
+class DeclGroup {
+  // FIXME: Include a TypeSpecifier object.
+  union {
+    unsigned NumDecls;
+
+    Decl *Aligner;
+  };
+
+private:
+  DeclGroup() : NumDecls(0) {}
+  DeclGroup(unsigned numdecls, Decl** decls);
+
+public:
+  static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls);
+
+  unsigned size() const { return NumDecls; }
+
+  Decl*& operator[](unsigned i) {
+    assert (i < NumDecls && "Out-of-bounds access.");
+    return ((Decl**) (this+1))[i];
+  }
+
+  Decl* const& operator[](unsigned i) const {
+    assert (i < NumDecls && "Out-of-bounds access.");
+    return ((Decl* const*) (this+1))[i];
+  }
+};
+
+class DeclGroupRef {
+  // Note this is not a PointerIntPair because we need the address of the
+  // non-group case to be valid as a Decl** for iteration.
+  enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 };
+  Decl* D;
+
+  Kind getKind() const {
+    return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask);
+  }
+
+public:
+  DeclGroupRef() : D(nullptr) {}
+
+  explicit DeclGroupRef(Decl* d) : D(d) {}
+  explicit DeclGroupRef(DeclGroup* dg)
+    : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {}
+
+  static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
+    if (NumDecls == 0)
+      return DeclGroupRef();
+    if (NumDecls == 1)
+      return DeclGroupRef(Decls[0]);
+    return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls));
+  }
+
+  typedef Decl** iterator;
+  typedef Decl* const * const_iterator;
+
+  bool isNull() const { return D == nullptr; }
+  bool isSingleDecl() const { return getKind() == SingleDeclKind; }
+  bool isDeclGroup() const { return getKind() == DeclGroupKind; }
+
+  Decl *getSingleDecl() {
+    assert(isSingleDecl() && "Isn't a declgroup");
+    return D;
+  }
+  const Decl *getSingleDecl() const {
+    return const_cast<DeclGroupRef*>(this)->getSingleDecl();
+  }
+
+  DeclGroup &getDeclGroup() {
+    assert(isDeclGroup() && "Isn't a declgroup");
+    return *((DeclGroup*)(reinterpret_cast<uintptr_t>(D) & ~Mask));
+  }
+  const DeclGroup &getDeclGroup() const {
+    return const_cast<DeclGroupRef*>(this)->getDeclGroup();
+  }
+
+  iterator begin() {
+    if (isSingleDecl())
+      return D ? &D : nullptr;
+    return &getDeclGroup()[0];
+  }
+
+  iterator end() {
+    if (isSingleDecl())
+      return D ? &D+1 : nullptr;
+    DeclGroup &G = getDeclGroup();
+    return &G[0] + G.size();
+  }
+
+  const_iterator begin() const {
+    if (isSingleDecl())
+      return D ? &D : nullptr;
+    return &getDeclGroup()[0];
+  }
+
+  const_iterator end() const {
+    if (isSingleDecl())
+      return D ? &D+1 : nullptr;
+    const DeclGroup &G = getDeclGroup();
+    return &G[0] + G.size();
+  }
+
+  void *getAsOpaquePtr() const { return D; }
+  static DeclGroupRef getFromOpaquePtr(void *Ptr) {
+    DeclGroupRef X;
+    X.D = static_cast<Decl*>(Ptr);
+    return X;
+  }
+};
+
+} // end clang namespace
+
+namespace llvm {
+  // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits.
+  template <typename T>
+  class PointerLikeTypeTraits;
+  template <>
+  class PointerLikeTypeTraits<clang::DeclGroupRef> {
+  public:
+    static inline void *getAsVoidPointer(clang::DeclGroupRef P) {
+      return P.getAsOpaquePtr();
+    }
+    static inline clang::DeclGroupRef getFromVoidPointer(void *P) {
+      return clang::DeclGroupRef::getFromOpaquePtr(P);
+    }
+    enum { NumLowBitsAvailable = 0 };
+  };
+}
+#endif
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
new file mode 100644
index 0000000..d2016af
--- /dev/null
+++ b/include/clang/AST/DeclLookups.h
@@ -0,0 +1,109 @@
+//===-- DeclLookups.h - Low-level interface to all names in a DC-*- 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 DeclContext::all_lookups_iterator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
+#define LLVM_CLANG_AST_DECLLOOKUPS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/DeclarationName.h"
+
+namespace clang {
+
+/// all_lookups_iterator - An iterator that provides a view over the results
+/// of looking up every possible name.
+class DeclContext::all_lookups_iterator {
+  StoredDeclsMap::iterator It, End;
+public:
+  typedef lookup_result             value_type;
+  typedef lookup_result             reference;
+  typedef lookup_result             pointer;
+  typedef std::forward_iterator_tag iterator_category;
+  typedef std::ptrdiff_t            difference_type;
+
+  all_lookups_iterator() {}
+  all_lookups_iterator(StoredDeclsMap::iterator It,
+                       StoredDeclsMap::iterator End)
+      : It(It), End(End) {}
+
+  DeclarationName getLookupName() const { return It->first; }
+
+  reference operator*() const { return It->second.getLookupResult(); }
+  pointer operator->() const { return It->second.getLookupResult(); }
+
+  all_lookups_iterator& operator++() {
+    // Filter out using directives. They don't belong as results from name
+    // lookup anyways, except as an implementation detail. Users of the API
+    // should not expect to get them (or worse, rely on it).
+    do {
+      ++It;
+    } while (It != End &&
+             It->first == DeclarationName::getUsingDirectiveName());
+             
+    return *this;
+  }
+
+  all_lookups_iterator operator++(int) {
+    all_lookups_iterator tmp(*this);
+    ++(*this);
+    return tmp;
+  }
+
+  friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
+    return x.It == y.It;
+  }
+  friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
+    return x.It != y.It;
+  }
+};
+
+inline DeclContext::lookups_range DeclContext::lookups() const {
+  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+  if (Primary->hasExternalVisibleStorage())
+    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
+  if (StoredDeclsMap *Map = Primary->buildLookup())
+    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+                         all_lookups_iterator(Map->end(), Map->end()));
+  return lookups_range();
+}
+
+inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+  return lookups().begin();
+}
+
+inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
+  return lookups().end();
+}
+
+inline DeclContext::lookups_range DeclContext::noload_lookups() const {
+  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+  if (StoredDeclsMap *Map = Primary->getLookupPtr())
+    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+                         all_lookups_iterator(Map->end(), Map->end()));
+  return lookups_range();
+}
+
+inline
+DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
+  return noload_lookups().begin();
+}
+
+inline
+DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
+  return noload_lookups().end();
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclNodes.inc b/include/clang/AST/DeclNodes.inc
new file mode 100644
index 0000000..fe9ca23
--- /dev/null
+++ b/include/clang/AST/DeclNodes.inc
@@ -0,0 +1,506 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of AST nodes of a particular kind                                      *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef ABSTRACT_DECL
+#  define ABSTRACT_DECL(Type) Type
+#endif
+#ifndef DECL_RANGE
+#  define DECL_RANGE(Base, First, Last)
+#endif
+
+#ifndef LAST_DECL_RANGE
+#  define LAST_DECL_RANGE(Base, First, Last) DECL_RANGE(Base, First, Last)
+#endif
+
+#ifndef ACCESSSPEC
+#  define ACCESSSPEC(Type, Base) DECL(Type, Base)
+#endif
+ACCESSSPEC(AccessSpec, Decl)
+#undef ACCESSSPEC
+
+#ifndef BLOCK
+#  define BLOCK(Type, Base) DECL(Type, Base)
+#endif
+BLOCK(Block, Decl)
+#undef BLOCK
+
+#ifndef CAPTURED
+#  define CAPTURED(Type, Base) DECL(Type, Base)
+#endif
+CAPTURED(Captured, Decl)
+#undef CAPTURED
+
+#ifndef CLASSSCOPEFUNCTIONSPECIALIZATION
+#  define CLASSSCOPEFUNCTIONSPECIALIZATION(Type, Base) DECL(Type, Base)
+#endif
+CLASSSCOPEFUNCTIONSPECIALIZATION(ClassScopeFunctionSpecialization, Decl)
+#undef CLASSSCOPEFUNCTIONSPECIALIZATION
+
+#ifndef EMPTY
+#  define EMPTY(Type, Base) DECL(Type, Base)
+#endif
+EMPTY(Empty, Decl)
+#undef EMPTY
+
+#ifndef FILESCOPEASM
+#  define FILESCOPEASM(Type, Base) DECL(Type, Base)
+#endif
+FILESCOPEASM(FileScopeAsm, Decl)
+#undef FILESCOPEASM
+
+#ifndef FRIEND
+#  define FRIEND(Type, Base) DECL(Type, Base)
+#endif
+FRIEND(Friend, Decl)
+#undef FRIEND
+
+#ifndef FRIENDTEMPLATE
+#  define FRIENDTEMPLATE(Type, Base) DECL(Type, Base)
+#endif
+FRIENDTEMPLATE(FriendTemplate, Decl)
+#undef FRIENDTEMPLATE
+
+#ifndef IMPORT
+#  define IMPORT(Type, Base) DECL(Type, Base)
+#endif
+IMPORT(Import, Decl)
+#undef IMPORT
+
+#ifndef LINKAGESPEC
+#  define LINKAGESPEC(Type, Base) DECL(Type, Base)
+#endif
+LINKAGESPEC(LinkageSpec, Decl)
+#undef LINKAGESPEC
+
+#ifndef NAMED
+#  define NAMED(Type, Base) DECL(Type, Base)
+#endif
+ABSTRACT_DECL(NAMED(Named, Decl))
+#ifndef LABEL
+#  define LABEL(Type, Base) NAMED(Type, Base)
+#endif
+LABEL(Label, NamedDecl)
+#undef LABEL
+
+#ifndef NAMESPACE
+#  define NAMESPACE(Type, Base) NAMED(Type, Base)
+#endif
+NAMESPACE(Namespace, NamedDecl)
+#undef NAMESPACE
+
+#ifndef NAMESPACEALIAS
+#  define NAMESPACEALIAS(Type, Base) NAMED(Type, Base)
+#endif
+NAMESPACEALIAS(NamespaceAlias, NamedDecl)
+#undef NAMESPACEALIAS
+
+#ifndef OBJCCOMPATIBLEALIAS
+#  define OBJCCOMPATIBLEALIAS(Type, Base) NAMED(Type, Base)
+#endif
+OBJCCOMPATIBLEALIAS(ObjCCompatibleAlias, NamedDecl)
+#undef OBJCCOMPATIBLEALIAS
+
+#ifndef OBJCCONTAINER
+#  define OBJCCONTAINER(Type, Base) NAMED(Type, Base)
+#endif
+ABSTRACT_DECL(OBJCCONTAINER(ObjCContainer, NamedDecl))
+#ifndef OBJCCATEGORY
+#  define OBJCCATEGORY(Type, Base) OBJCCONTAINER(Type, Base)
+#endif
+OBJCCATEGORY(ObjCCategory, ObjCContainerDecl)
+#undef OBJCCATEGORY
+
+#ifndef OBJCIMPL
+#  define OBJCIMPL(Type, Base) OBJCCONTAINER(Type, Base)
+#endif
+ABSTRACT_DECL(OBJCIMPL(ObjCImpl, ObjCContainerDecl))
+#ifndef OBJCCATEGORYIMPL
+#  define OBJCCATEGORYIMPL(Type, Base) OBJCIMPL(Type, Base)
+#endif
+OBJCCATEGORYIMPL(ObjCCategoryImpl, ObjCImplDecl)
+#undef OBJCCATEGORYIMPL
+
+#ifndef OBJCIMPLEMENTATION
+#  define OBJCIMPLEMENTATION(Type, Base) OBJCIMPL(Type, Base)
+#endif
+OBJCIMPLEMENTATION(ObjCImplementation, ObjCImplDecl)
+#undef OBJCIMPLEMENTATION
+
+DECL_RANGE(ObjCImpl, ObjCCategoryImpl, ObjCImplementation)
+
+#undef OBJCIMPL
+
+#ifndef OBJCINTERFACE
+#  define OBJCINTERFACE(Type, Base) OBJCCONTAINER(Type, Base)
+#endif
+OBJCINTERFACE(ObjCInterface, ObjCContainerDecl)
+#undef OBJCINTERFACE
+
+#ifndef OBJCPROTOCOL
+#  define OBJCPROTOCOL(Type, Base) OBJCCONTAINER(Type, Base)
+#endif
+OBJCPROTOCOL(ObjCProtocol, ObjCContainerDecl)
+#undef OBJCPROTOCOL
+
+DECL_RANGE(ObjCContainer, ObjCCategory, ObjCProtocol)
+
+#undef OBJCCONTAINER
+
+#ifndef OBJCMETHOD
+#  define OBJCMETHOD(Type, Base) NAMED(Type, Base)
+#endif
+OBJCMETHOD(ObjCMethod, NamedDecl)
+#undef OBJCMETHOD
+
+#ifndef OBJCPROPERTY
+#  define OBJCPROPERTY(Type, Base) NAMED(Type, Base)
+#endif
+OBJCPROPERTY(ObjCProperty, NamedDecl)
+#undef OBJCPROPERTY
+
+#ifndef TEMPLATE
+#  define TEMPLATE(Type, Base) NAMED(Type, Base)
+#endif
+ABSTRACT_DECL(TEMPLATE(Template, NamedDecl))
+#ifndef REDECLARABLETEMPLATE
+#  define REDECLARABLETEMPLATE(Type, Base) TEMPLATE(Type, Base)
+#endif
+ABSTRACT_DECL(REDECLARABLETEMPLATE(RedeclarableTemplate, TemplateDecl))
+#ifndef CLASSTEMPLATE
+#  define CLASSTEMPLATE(Type, Base) REDECLARABLETEMPLATE(Type, Base)
+#endif
+CLASSTEMPLATE(ClassTemplate, RedeclarableTemplateDecl)
+#undef CLASSTEMPLATE
+
+#ifndef FUNCTIONTEMPLATE
+#  define FUNCTIONTEMPLATE(Type, Base) REDECLARABLETEMPLATE(Type, Base)
+#endif
+FUNCTIONTEMPLATE(FunctionTemplate, RedeclarableTemplateDecl)
+#undef FUNCTIONTEMPLATE
+
+#ifndef TYPEALIASTEMPLATE
+#  define TYPEALIASTEMPLATE(Type, Base) REDECLARABLETEMPLATE(Type, Base)
+#endif
+TYPEALIASTEMPLATE(TypeAliasTemplate, RedeclarableTemplateDecl)
+#undef TYPEALIASTEMPLATE
+
+#ifndef VARTEMPLATE
+#  define VARTEMPLATE(Type, Base) REDECLARABLETEMPLATE(Type, Base)
+#endif
+VARTEMPLATE(VarTemplate, RedeclarableTemplateDecl)
+#undef VARTEMPLATE
+
+DECL_RANGE(RedeclarableTemplate, ClassTemplate, VarTemplate)
+
+#undef REDECLARABLETEMPLATE
+
+#ifndef TEMPLATETEMPLATEPARM
+#  define TEMPLATETEMPLATEPARM(Type, Base) TEMPLATE(Type, Base)
+#endif
+TEMPLATETEMPLATEPARM(TemplateTemplateParm, TemplateDecl)
+#undef TEMPLATETEMPLATEPARM
+
+DECL_RANGE(Template, ClassTemplate, TemplateTemplateParm)
+
+#undef TEMPLATE
+
+#ifndef TYPE
+#  define TYPE(Type, Base) NAMED(Type, Base)
+#endif
+ABSTRACT_DECL(TYPE(Type, NamedDecl))
+#ifndef TAG
+#  define TAG(Type, Base) TYPE(Type, Base)
+#endif
+ABSTRACT_DECL(TAG(Tag, TypeDecl))
+#ifndef ENUM
+#  define ENUM(Type, Base) TAG(Type, Base)
+#endif
+ENUM(Enum, TagDecl)
+#undef ENUM
+
+#ifndef RECORD
+#  define RECORD(Type, Base) TAG(Type, Base)
+#endif
+RECORD(Record, TagDecl)
+#ifndef CXXRECORD
+#  define CXXRECORD(Type, Base) RECORD(Type, Base)
+#endif
+CXXRECORD(CXXRecord, RecordDecl)
+#ifndef CLASSTEMPLATESPECIALIZATION
+#  define CLASSTEMPLATESPECIALIZATION(Type, Base) CXXRECORD(Type, Base)
+#endif
+CLASSTEMPLATESPECIALIZATION(ClassTemplateSpecialization, CXXRecordDecl)
+#ifndef CLASSTEMPLATEPARTIALSPECIALIZATION
+#  define CLASSTEMPLATEPARTIALSPECIALIZATION(Type, Base) CLASSTEMPLATESPECIALIZATION(Type, Base)
+#endif
+CLASSTEMPLATEPARTIALSPECIALIZATION(ClassTemplatePartialSpecialization, ClassTemplateSpecializationDecl)
+#undef CLASSTEMPLATEPARTIALSPECIALIZATION
+
+DECL_RANGE(ClassTemplateSpecialization, ClassTemplateSpecialization, ClassTemplatePartialSpecialization)
+
+#undef CLASSTEMPLATESPECIALIZATION
+
+DECL_RANGE(CXXRecord, CXXRecord, ClassTemplatePartialSpecialization)
+
+#undef CXXRECORD
+
+DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization)
+
+#undef RECORD
+
+DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)
+
+#undef TAG
+
+#ifndef TEMPLATETYPEPARM
+#  define TEMPLATETYPEPARM(Type, Base) TYPE(Type, Base)
+#endif
+TEMPLATETYPEPARM(TemplateTypeParm, TypeDecl)
+#undef TEMPLATETYPEPARM
+
+#ifndef TYPEDEFNAME
+#  define TYPEDEFNAME(Type, Base) TYPE(Type, Base)
+#endif
+ABSTRACT_DECL(TYPEDEFNAME(TypedefName, TypeDecl))
+#ifndef TYPEALIAS
+#  define TYPEALIAS(Type, Base) TYPEDEFNAME(Type, Base)
+#endif
+TYPEALIAS(TypeAlias, TypedefNameDecl)
+#undef TYPEALIAS
+
+#ifndef TYPEDEF
+#  define TYPEDEF(Type, Base) TYPEDEFNAME(Type, Base)
+#endif
+TYPEDEF(Typedef, TypedefNameDecl)
+#undef TYPEDEF
+
+DECL_RANGE(TypedefName, TypeAlias, Typedef)
+
+#undef TYPEDEFNAME
+
+#ifndef UNRESOLVEDUSINGTYPENAME
+#  define UNRESOLVEDUSINGTYPENAME(Type, Base) TYPE(Type, Base)
+#endif
+UNRESOLVEDUSINGTYPENAME(UnresolvedUsingTypename, TypeDecl)
+#undef UNRESOLVEDUSINGTYPENAME
+
+DECL_RANGE(Type, Enum, UnresolvedUsingTypename)
+
+#undef TYPE
+
+#ifndef USING
+#  define USING(Type, Base) NAMED(Type, Base)
+#endif
+USING(Using, NamedDecl)
+#undef USING
+
+#ifndef USINGDIRECTIVE
+#  define USINGDIRECTIVE(Type, Base) NAMED(Type, Base)
+#endif
+USINGDIRECTIVE(UsingDirective, NamedDecl)
+#undef USINGDIRECTIVE
+
+#ifndef USINGSHADOW
+#  define USINGSHADOW(Type, Base) NAMED(Type, Base)
+#endif
+USINGSHADOW(UsingShadow, NamedDecl)
+#undef USINGSHADOW
+
+#ifndef VALUE
+#  define VALUE(Type, Base) NAMED(Type, Base)
+#endif
+ABSTRACT_DECL(VALUE(Value, NamedDecl))
+#ifndef DECLARATOR
+#  define DECLARATOR(Type, Base) VALUE(Type, Base)
+#endif
+ABSTRACT_DECL(DECLARATOR(Declarator, ValueDecl))
+#ifndef FIELD
+#  define FIELD(Type, Base) DECLARATOR(Type, Base)
+#endif
+FIELD(Field, DeclaratorDecl)
+#ifndef OBJCATDEFSFIELD
+#  define OBJCATDEFSFIELD(Type, Base) FIELD(Type, Base)
+#endif
+OBJCATDEFSFIELD(ObjCAtDefsField, FieldDecl)
+#undef OBJCATDEFSFIELD
+
+#ifndef OBJCIVAR
+#  define OBJCIVAR(Type, Base) FIELD(Type, Base)
+#endif
+OBJCIVAR(ObjCIvar, FieldDecl)
+#undef OBJCIVAR
+
+DECL_RANGE(Field, Field, ObjCIvar)
+
+#undef FIELD
+
+#ifndef FUNCTION
+#  define FUNCTION(Type, Base) DECLARATOR(Type, Base)
+#endif
+FUNCTION(Function, DeclaratorDecl)
+#ifndef CXXMETHOD
+#  define CXXMETHOD(Type, Base) FUNCTION(Type, Base)
+#endif
+CXXMETHOD(CXXMethod, FunctionDecl)
+#ifndef CXXCONSTRUCTOR
+#  define CXXCONSTRUCTOR(Type, Base) CXXMETHOD(Type, Base)
+#endif
+CXXCONSTRUCTOR(CXXConstructor, CXXMethodDecl)
+#undef CXXCONSTRUCTOR
+
+#ifndef CXXCONVERSION
+#  define CXXCONVERSION(Type, Base) CXXMETHOD(Type, Base)
+#endif
+CXXCONVERSION(CXXConversion, CXXMethodDecl)
+#undef CXXCONVERSION
+
+#ifndef CXXDESTRUCTOR
+#  define CXXDESTRUCTOR(Type, Base) CXXMETHOD(Type, Base)
+#endif
+CXXDESTRUCTOR(CXXDestructor, CXXMethodDecl)
+#undef CXXDESTRUCTOR
+
+DECL_RANGE(CXXMethod, CXXMethod, CXXDestructor)
+
+#undef CXXMETHOD
+
+DECL_RANGE(Function, Function, CXXDestructor)
+
+#undef FUNCTION
+
+#ifndef MSPROPERTY
+#  define MSPROPERTY(Type, Base) DECLARATOR(Type, Base)
+#endif
+MSPROPERTY(MSProperty, DeclaratorDecl)
+#undef MSPROPERTY
+
+#ifndef NONTYPETEMPLATEPARM
+#  define NONTYPETEMPLATEPARM(Type, Base) DECLARATOR(Type, Base)
+#endif
+NONTYPETEMPLATEPARM(NonTypeTemplateParm, DeclaratorDecl)
+#undef NONTYPETEMPLATEPARM
+
+#ifndef VAR
+#  define VAR(Type, Base) DECLARATOR(Type, Base)
+#endif
+VAR(Var, DeclaratorDecl)
+#ifndef IMPLICITPARAM
+#  define IMPLICITPARAM(Type, Base) VAR(Type, Base)
+#endif
+IMPLICITPARAM(ImplicitParam, VarDecl)
+#undef IMPLICITPARAM
+
+#ifndef PARMVAR
+#  define PARMVAR(Type, Base) VAR(Type, Base)
+#endif
+PARMVAR(ParmVar, VarDecl)
+#undef PARMVAR
+
+#ifndef VARTEMPLATESPECIALIZATION
+#  define VARTEMPLATESPECIALIZATION(Type, Base) VAR(Type, Base)
+#endif
+VARTEMPLATESPECIALIZATION(VarTemplateSpecialization, VarDecl)
+#ifndef VARTEMPLATEPARTIALSPECIALIZATION
+#  define VARTEMPLATEPARTIALSPECIALIZATION(Type, Base) VARTEMPLATESPECIALIZATION(Type, Base)
+#endif
+VARTEMPLATEPARTIALSPECIALIZATION(VarTemplatePartialSpecialization, VarTemplateSpecializationDecl)
+#undef VARTEMPLATEPARTIALSPECIALIZATION
+
+DECL_RANGE(VarTemplateSpecialization, VarTemplateSpecialization, VarTemplatePartialSpecialization)
+
+#undef VARTEMPLATESPECIALIZATION
+
+DECL_RANGE(Var, Var, VarTemplatePartialSpecialization)
+
+#undef VAR
+
+DECL_RANGE(Declarator, Field, VarTemplatePartialSpecialization)
+
+#undef DECLARATOR
+
+#ifndef ENUMCONSTANT
+#  define ENUMCONSTANT(Type, Base) VALUE(Type, Base)
+#endif
+ENUMCONSTANT(EnumConstant, ValueDecl)
+#undef ENUMCONSTANT
+
+#ifndef INDIRECTFIELD
+#  define INDIRECTFIELD(Type, Base) VALUE(Type, Base)
+#endif
+INDIRECTFIELD(IndirectField, ValueDecl)
+#undef INDIRECTFIELD
+
+#ifndef UNRESOLVEDUSINGVALUE
+#  define UNRESOLVEDUSINGVALUE(Type, Base) VALUE(Type, Base)
+#endif
+UNRESOLVEDUSINGVALUE(UnresolvedUsingValue, ValueDecl)
+#undef UNRESOLVEDUSINGVALUE
+
+DECL_RANGE(Value, Field, UnresolvedUsingValue)
+
+#undef VALUE
+
+DECL_RANGE(Named, Label, UnresolvedUsingValue)
+
+#undef NAMED
+
+#ifndef OMPTHREADPRIVATE
+#  define OMPTHREADPRIVATE(Type, Base) DECL(Type, Base)
+#endif
+OMPTHREADPRIVATE(OMPThreadPrivate, Decl)
+#undef OMPTHREADPRIVATE
+
+#ifndef OBJCPROPERTYIMPL
+#  define OBJCPROPERTYIMPL(Type, Base) DECL(Type, Base)
+#endif
+OBJCPROPERTYIMPL(ObjCPropertyImpl, Decl)
+#undef OBJCPROPERTYIMPL
+
+#ifndef STATICASSERT
+#  define STATICASSERT(Type, Base) DECL(Type, Base)
+#endif
+STATICASSERT(StaticAssert, Decl)
+#undef STATICASSERT
+
+#ifndef TRANSLATIONUNIT
+#  define TRANSLATIONUNIT(Type, Base) DECL(Type, Base)
+#endif
+TRANSLATIONUNIT(TranslationUnit, Decl)
+#undef TRANSLATIONUNIT
+
+LAST_DECL_RANGE(Decl, AccessSpec, TranslationUnit)
+
+#undef DECL
+#undef DECL_RANGE
+#undef LAST_DECL_RANGE
+#undef ABSTRACT_DECL
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of AST Decl nodes                                                      *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef DECL_CONTEXT
+#  define DECL_CONTEXT(DECL)
+#endif
+#ifndef DECL_CONTEXT_BASE
+#  define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)
+#endif
+DECL_CONTEXT_BASE(Function)
+DECL_CONTEXT_BASE(Tag)
+DECL_CONTEXT_BASE(ObjCContainer)
+DECL_CONTEXT(Block)
+DECL_CONTEXT(Captured)
+DECL_CONTEXT(LinkageSpec)
+DECL_CONTEXT(Namespace)
+DECL_CONTEXT(ObjCMethod)
+DECL_CONTEXT(TranslationUnit)
+#undef DECL_CONTEXT
+#undef DECL_CONTEXT_BASE
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
new file mode 100644
index 0000000..db3b084
--- /dev/null
+++ b/include/clang/AST/DeclObjC.h
@@ -0,0 +1,2504 @@
+//===--- DeclObjC.h - Classes for representing declarations -----*- 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 DeclObjC interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLOBJC_H
+#define LLVM_CLANG_AST_DECLOBJC_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/SelectorLocationsKind.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+class Expr;
+class Stmt;
+class FunctionDecl;
+class RecordDecl;
+class ObjCIvarDecl;
+class ObjCMethodDecl;
+class ObjCProtocolDecl;
+class ObjCCategoryDecl;
+class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
+class CXXCtorInitializer;
+
+class ObjCListBase {
+  ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION;
+  void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION;
+protected:
+  /// List is an array of pointers to objects that are not owned by this object.
+  void **List;
+  unsigned NumElts;
+
+public:
+  ObjCListBase() : List(nullptr), NumElts(0) {}
+  unsigned size() const { return NumElts; }
+  bool empty() const { return NumElts == 0; }
+
+protected:
+  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
+};
+
+
+/// ObjCList - This is a simple template class used to hold various lists of
+/// decls etc, which is heavily used by the ObjC front-end.  This only use case
+/// this supports is setting the list all at once and then reading elements out
+/// of it.
+template <typename T>
+class ObjCList : public ObjCListBase {
+public:
+  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
+    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
+  }
+
+  typedef T* const * iterator;
+  iterator begin() const { return (iterator)List; }
+  iterator end() const { return (iterator)List+NumElts; }
+
+  T* operator[](unsigned Idx) const {
+    assert(Idx < NumElts && "Invalid access");
+    return (T*)List[Idx];
+  }
+};
+
+/// \brief A list of Objective-C protocols, along with the source
+/// locations at which they were referenced.
+class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
+  SourceLocation *Locations;
+
+  using ObjCList<ObjCProtocolDecl>::set;
+
+public:
+  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
+
+  typedef const SourceLocation *loc_iterator;
+  loc_iterator loc_begin() const { return Locations; }
+  loc_iterator loc_end() const { return Locations + size(); }
+
+  void set(ObjCProtocolDecl* const* InList, unsigned Elts,
+           const SourceLocation *Locs, ASTContext &Ctx);
+};
+
+
+/// ObjCMethodDecl - Represents an instance or class method declaration.
+/// ObjC methods can be declared within 4 contexts: class interfaces,
+/// categories, protocols, and class implementations. While C++ member
+/// functions leverage C syntax, Objective-C method syntax is modeled after
+/// Smalltalk (using colons to specify argument types/expressions).
+/// Here are some brief examples:
+///
+/// Setter/getter instance methods:
+/// - (void)setMenu:(NSMenu *)menu;
+/// - (NSMenu *)menu;
+///
+/// Instance method that takes 2 NSView arguments:
+/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
+///
+/// Getter class method:
+/// + (NSMenu *)defaultMenu;
+///
+/// A selector represents a unique name for a method. The selector names for
+/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
+///
+class ObjCMethodDecl : public NamedDecl, public DeclContext {
+public:
+  enum ImplementationControl { None, Required, Optional };
+private:
+  // The conventional meaning of this method; an ObjCMethodFamily.
+  // This is not serialized; instead, it is computed on demand and
+  // cached.
+  mutable unsigned Family : ObjCMethodFamilyBitWidth;
+
+  /// instance (true) or class (false) method.
+  unsigned IsInstance : 1;
+  unsigned IsVariadic : 1;
+
+  /// True if this method is the getter or setter for an explicit property.
+  unsigned IsPropertyAccessor : 1;
+
+  // Method has a definition.
+  unsigned IsDefined : 1;
+
+  /// \brief Method redeclaration in the same interface.
+  unsigned IsRedeclaration : 1;
+
+  /// \brief Is redeclared in the same interface.
+  mutable unsigned HasRedeclaration : 1;
+
+  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
+  /// \@required/\@optional
+  unsigned DeclImplementation : 2;
+
+  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
+  /// in, inout, etc.
+  unsigned objcDeclQualifier : 6;
+
+  /// \brief Indicates whether this method has a related result type.
+  unsigned RelatedResultType : 1;
+
+  /// \brief Whether the locations of the selector identifiers are in a
+  /// "standard" position, a enum SelectorLocationsKind.
+  unsigned SelLocsKind : 2;
+
+  /// \brief Whether this method overrides any other in the class hierarchy.
+  ///
+  /// A method is said to override any method in the class's
+  /// base classes, its protocols, or its categories' protocols, that has
+  /// the same selector and is of the same kind (class or instance).
+  /// A method in an implementation is not considered as overriding the same
+  /// method in the interface or its categories.
+  unsigned IsOverriding : 1;
+
+  /// \brief Indicates if the method was a definition but its body was skipped.
+  unsigned HasSkippedBody : 1;
+
+  // Return type of this method.
+  QualType MethodDeclType;
+
+  // Type source information for the return type.
+  TypeSourceInfo *ReturnTInfo;
+
+  /// \brief Array of ParmVarDecls for the formal parameters of this method
+  /// and optionally followed by selector locations.
+  void *ParamsAndSelLocs;
+  unsigned NumParams;
+
+  /// List of attributes for this method declaration.
+  SourceLocation DeclEndLoc; // the location of the ';' or '{'.
+
+  // The following are only used for method definitions, null otherwise.
+  LazyDeclStmtPtr Body;
+
+  /// SelfDecl - Decl for the implicit self parameter. This is lazily
+  /// constructed by createImplicitParams.
+  ImplicitParamDecl *SelfDecl;
+  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
+  /// constructed by createImplicitParams.
+  ImplicitParamDecl *CmdDecl;
+
+  SelectorLocationsKind getSelLocsKind() const {
+    return (SelectorLocationsKind)SelLocsKind;
+  }
+  bool hasStandardSelLocs() const {
+    return getSelLocsKind() != SelLoc_NonStandard;
+  }
+
+  /// \brief Get a pointer to the stored selector identifiers locations array.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  SourceLocation *getStoredSelLocs() {
+    return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
+  }
+  const SourceLocation *getStoredSelLocs() const {
+    return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
+  }
+
+  /// \brief Get a pointer to the stored selector identifiers locations array.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  ParmVarDecl **getParams() {
+    return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
+  }
+  const ParmVarDecl *const *getParams() const {
+    return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
+  }
+
+  /// \brief Get the number of stored selector identifiers locations.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  unsigned getNumStoredSelLocs() const {
+    if (hasStandardSelLocs())
+      return 0;
+    return getNumSelectorLocs();
+  }
+
+  void setParamsAndSelLocs(ASTContext &C,
+                           ArrayRef<ParmVarDecl*> Params,
+                           ArrayRef<SourceLocation> SelLocs);
+
+  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+                 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+                 DeclContext *contextDecl, bool isInstance = true,
+                 bool isVariadic = false, bool isPropertyAccessor = false,
+                 bool isImplicitlyDeclared = false, bool isDefined = false,
+                 ImplementationControl impControl = None,
+                 bool HasRelatedResultType = false)
+      : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+        DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
+        IsInstance(isInstance), IsVariadic(isVariadic),
+        IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
+        IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
+        objcDeclQualifier(OBJC_TQ_None),
+        RelatedResultType(HasRelatedResultType),
+        SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
+        MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
+        NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
+        CmdDecl(nullptr) {
+    setImplicit(isImplicitlyDeclared);
+  }
+
+  /// \brief A definition will return its interface declaration.
+  /// An interface declaration will return its definition.
+  /// Otherwise it will return itself.
+  ObjCMethodDecl *getNextRedeclarationImpl() override;
+
+public:
+  static ObjCMethodDecl *
+  Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+         Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+         DeclContext *contextDecl, bool isInstance = true,
+         bool isVariadic = false, bool isPropertyAccessor = false,
+         bool isImplicitlyDeclared = false, bool isDefined = false,
+         ImplementationControl impControl = None,
+         bool HasRelatedResultType = false);
+
+  static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  ObjCMethodDecl *getCanonicalDecl() override;
+  const ObjCMethodDecl *getCanonicalDecl() const {
+    return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
+  }
+
+  ObjCDeclQualifier getObjCDeclQualifier() const {
+    return ObjCDeclQualifier(objcDeclQualifier);
+  }
+  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
+
+  /// \brief Determine whether this method has a result type that is related
+  /// to the message receiver's type.
+  bool hasRelatedResultType() const { return RelatedResultType; }
+
+  /// \brief Note whether this method has a related result type.
+  void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
+
+  /// \brief True if this is a method redeclaration in the same interface.
+  bool isRedeclaration() const { return IsRedeclaration; }
+  void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
+
+  /// \brief Returns the location where the declarator ends. It will be
+  /// the location of ';' for a method declaration and the location of '{'
+  /// for a method definition.
+  SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
+
+  // Location information, modeled after the Stmt API.
+  SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(getLocation(), getLocEnd());
+  }
+
+  SourceLocation getSelectorStartLoc() const {
+    if (isImplicit())
+      return getLocStart();
+    return getSelectorLoc(0);
+  }
+  SourceLocation getSelectorLoc(unsigned Index) const {
+    assert(Index < getNumSelectorLocs() && "Index out of range!");
+    if (hasStandardSelLocs())
+      return getStandardSelectorLoc(Index, getSelector(),
+                                   getSelLocsKind() == SelLoc_StandardWithSpace,
+                                    parameters(),
+                                   DeclEndLoc);
+    return getStoredSelLocs()[Index];
+  }
+
+  void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
+
+  unsigned getNumSelectorLocs() const {
+    if (isImplicit())
+      return 0;
+    Selector Sel = getSelector();
+    if (Sel.isUnarySelector())
+      return 1;
+    return Sel.getNumArgs();
+  }
+
+  ObjCInterfaceDecl *getClassInterface();
+  const ObjCInterfaceDecl *getClassInterface() const {
+    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
+  }
+
+  Selector getSelector() const { return getDeclName().getObjCSelector(); }
+
+  QualType getReturnType() const { return MethodDeclType; }
+  void setReturnType(QualType T) { MethodDeclType = T; }
+
+  /// \brief Determine the type of an expression that sends a message to this
+  /// function.
+  QualType getSendResultType() const {
+    return getReturnType().getNonLValueExprType(getASTContext());
+  }
+
+  TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
+  void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
+
+  // Iterator access to formal parameters.
+  unsigned param_size() const { return NumParams; }
+  typedef const ParmVarDecl *const *param_const_iterator;
+  typedef ParmVarDecl *const *param_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+  param_range params() { return param_range(param_begin(), param_end()); }
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
+
+  param_const_iterator param_begin() const {
+    return param_const_iterator(getParams());
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(getParams() + NumParams);
+  }
+  param_iterator param_begin() { return param_iterator(getParams()); }
+  param_iterator param_end() { return param_iterator(getParams() + NumParams); }
+
+  // This method returns and of the parameters which are part of the selector
+  // name mangling requirements.
+  param_const_iterator sel_param_end() const {
+    return param_begin() + getSelector().getNumArgs();
+  }
+
+  // ArrayRef access to formal parameters.  This should eventually
+  // replace the iterator interface above.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
+                              NumParams);
+  }
+
+  /// \brief Sets the method's parameters and selector source locations.
+  /// If the method is implicit (not coming from source) \p SelLocs is
+  /// ignored.
+  void setMethodParams(ASTContext &C,
+                       ArrayRef<ParmVarDecl*> Params,
+                       ArrayRef<SourceLocation> SelLocs =
+                           ArrayRef<SourceLocation>());
+
+  // Iterator access to parameter types.
+  typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
+  typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
+  param_type_iterator;
+
+  param_type_iterator param_type_begin() const {
+    return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
+  }
+  param_type_iterator param_type_end() const {
+    return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
+  }
+
+  /// createImplicitParams - Used to lazily create the self and cmd
+  /// implict parameters. This must be called prior to using getSelfDecl()
+  /// or getCmdDecl(). The call is ignored if the implicit paramters
+  /// have already been created.
+  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
+
+  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
+  void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
+  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
+  void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
+
+  /// Determines the family of this method.
+  ObjCMethodFamily getMethodFamily() const;
+
+  bool isInstanceMethod() const { return IsInstance; }
+  void setInstanceMethod(bool isInst) { IsInstance = isInst; }
+  bool isVariadic() const { return IsVariadic; }
+  void setVariadic(bool isVar) { IsVariadic = isVar; }
+
+  bool isClassMethod() const { return !IsInstance; }
+
+  bool isPropertyAccessor() const { return IsPropertyAccessor; }
+  void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
+
+  bool isDefined() const { return IsDefined; }
+  void setDefined(bool isDefined) { IsDefined = isDefined; }
+
+  /// \brief Whether this method overrides any other in the class hierarchy.
+  ///
+  /// A method is said to override any method in the class's
+  /// base classes, its protocols, or its categories' protocols, that has
+  /// the same selector and is of the same kind (class or instance).
+  /// A method in an implementation is not considered as overriding the same
+  /// method in the interface or its categories.
+  bool isOverriding() const { return IsOverriding; }
+  void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
+
+  /// \brief Return overridden methods for the given \p Method.
+  ///
+  /// An ObjC method is considered to override any method in the class's
+  /// base classes (and base's categories), its protocols, or its categories'
+  /// protocols, that has
+  /// the same selector and is of the same kind (class or instance).
+  /// A method in an implementation is not considered as overriding the same
+  /// method in the interface or its categories.
+  void getOverriddenMethods(
+                     SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
+
+  /// \brief True if the method was a definition but its body was skipped.
+  bool hasSkippedBody() const { return HasSkippedBody; }
+  void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
+
+  /// \brief Returns the property associated with this method's selector.
+  ///
+  /// Note that even if this particular method is not marked as a property
+  /// accessor, it is still possible for it to match a property declared in a
+  /// superclass. Pass \c false if you only want to check the current class.
+  const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
+
+  // Related to protocols declared in  \@protocol
+  void setDeclImplementation(ImplementationControl ic) {
+    DeclImplementation = ic;
+  }
+  ImplementationControl getImplementationControl() const {
+    return ImplementationControl(DeclImplementation);
+  }
+
+  /// Returns true if this specific method declaration is marked with the
+  /// designated initializer attribute.
+  bool isThisDeclarationADesignatedInitializer() const;
+
+  /// Returns true if the method selector resolves to a designated initializer
+  /// in the class's interface.
+  ///
+  /// \param InitMethod if non-null and the function returns true, it receives
+  /// the method declaration that was marked with the designated initializer
+  /// attribute.
+  bool isDesignatedInitializerForTheInterface(
+      const ObjCMethodDecl **InitMethod = nullptr) const;
+
+  /// \brief Determine whether this method has a body.
+  bool hasBody() const override { return Body.isValid(); }
+
+  /// \brief Retrieve the body of this method, if it has one.
+  Stmt *getBody() const override;
+
+  void setLazyBody(uint64_t Offset) { Body = Offset; }
+
+  CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
+  void setBody(Stmt *B) { Body = B; }
+
+  /// \brief Returns whether this specific method is a definition.
+  bool isThisDeclarationADefinition() const { return hasBody(); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCMethod; }
+  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
+    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
+  }
+  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// ObjCContainerDecl - Represents a container for method declarations.
+/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
+/// ObjCProtocolDecl, and ObjCImplDecl.
+///
+class ObjCContainerDecl : public NamedDecl, public DeclContext {
+  void anchor() override;
+
+  SourceLocation AtStart;
+
+  // These two locations in the range mark the end of the method container.
+  // The first points to the '@' token, and the second to the 'end' token.
+  SourceRange AtEnd;
+public:
+
+  ObjCContainerDecl(Kind DK, DeclContext *DC,
+                    IdentifierInfo *Id, SourceLocation nameLoc,
+                    SourceLocation atStartLoc)
+    : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
+
+  // Iterator access to properties.
+  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
+    prop_range;
+
+  prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
+  prop_iterator prop_begin() const {
+    return prop_iterator(decls_begin());
+  }
+  prop_iterator prop_end() const {
+    return prop_iterator(decls_end());
+  }
+
+  // Iterator access to instance/class methods.
+  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
+    method_range;
+
+  method_range methods() const {
+    return method_range(meth_begin(), meth_end());
+  }
+  method_iterator meth_begin() const {
+    return method_iterator(decls_begin());
+  }
+  method_iterator meth_end() const {
+    return method_iterator(decls_end());
+  }
+
+  typedef filtered_decl_iterator<ObjCMethodDecl,
+                                 &ObjCMethodDecl::isInstanceMethod>
+    instmeth_iterator;
+  typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
+
+  instmeth_range instance_methods() const {
+    return instmeth_range(instmeth_begin(), instmeth_end());
+  }
+  instmeth_iterator instmeth_begin() const {
+    return instmeth_iterator(decls_begin());
+  }
+  instmeth_iterator instmeth_end() const {
+    return instmeth_iterator(decls_end());
+  }
+
+  typedef filtered_decl_iterator<ObjCMethodDecl,
+                                 &ObjCMethodDecl::isClassMethod>
+    classmeth_iterator;
+  typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
+
+  classmeth_range class_methods() const {
+    return classmeth_range(classmeth_begin(), classmeth_end());
+  }
+  classmeth_iterator classmeth_begin() const {
+    return classmeth_iterator(decls_begin());
+  }
+  classmeth_iterator classmeth_end() const {
+    return classmeth_iterator(decls_end());
+  }
+
+  // Get the local instance/class method declared in this interface.
+  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance,
+                            bool AllowHidden = false) const;
+  ObjCMethodDecl *getInstanceMethod(Selector Sel,
+                                    bool AllowHidden = false) const {
+    return getMethod(Sel, true/*isInstance*/, AllowHidden);
+  }
+  ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const {
+    return getMethod(Sel, false/*isInstance*/, AllowHidden);
+  }
+  bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const;
+  ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
+
+  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
+
+  typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
+  
+  typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
+            ProtocolPropertyMap;
+  
+  typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
+  
+  /// This routine collects list of properties to be implemented in the class.
+  /// This includes, class's and its conforming protocols' properties.
+  /// Note, the superclass's properties are not included in the list.
+  virtual void collectPropertiesToImplement(PropertyMap &PM,
+                                            PropertyDeclOrder &PO) const {}
+
+  SourceLocation getAtStartLoc() const { return AtStart; }
+  void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
+
+  // Marks the end of the container.
+  SourceRange getAtEndRange() const {
+    return AtEnd;
+  }
+  void setAtEndRange(SourceRange atEnd) {
+    AtEnd = atEnd;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(AtStart, getAtEndRange().getEnd());
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstObjCContainer &&
+           K <= lastObjCContainer;
+  }
+
+  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
+    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
+  }
+  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
+    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
+  }
+};
+
+/// \brief Represents an ObjC class declaration.
+///
+/// For example:
+///
+/// \code
+///   // MostPrimitive declares no super class (not particularly useful).
+///   \@interface MostPrimitive
+///     // no instance variables or methods.
+///   \@end
+///
+///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
+///   \@interface NSResponder : NSObject \<NSCoding>
+///   { // instance variables are represented by ObjCIvarDecl.
+///     id nextResponder; // nextResponder instance variable.
+///   }
+///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
+///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
+///   \@end                                    // to an NSEvent.
+/// \endcode
+///
+///   Unlike C/C++, forward class declarations are accomplished with \@class.
+///   Unlike C/C++, \@class allows for a list of classes to be forward declared.
+///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
+///   typically inherit from NSObject (an exception is NSProxy).
+///
+class ObjCInterfaceDecl : public ObjCContainerDecl
+                        , public Redeclarable<ObjCInterfaceDecl> {
+  void anchor() override;
+
+  /// TypeForDecl - This indicates the Type object that represents this
+  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
+  mutable const Type *TypeForDecl;
+  friend class ASTContext;
+  
+  struct DefinitionData {
+    /// \brief The definition of this class, for quick access from any 
+    /// declaration.
+    ObjCInterfaceDecl *Definition;
+    
+    /// Class's super class.
+    ObjCInterfaceDecl *SuperClass;
+
+    /// Protocols referenced in the \@interface  declaration
+    ObjCProtocolList ReferencedProtocols;
+
+    /// Protocols reference in both the \@interface and class extensions.
+    ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
+
+    /// \brief List of categories and class extensions defined for this class.
+    ///
+    /// Categories are stored as a linked list in the AST, since the categories
+    /// and class extensions come long after the initial interface declaration,
+    /// and we avoid dynamically-resized arrays in the AST wherever possible.
+    ObjCCategoryDecl *CategoryList;
+
+    /// IvarList - List of all ivars defined by this class; including class
+    /// extensions and implementation. This list is built lazily.
+    ObjCIvarDecl *IvarList;
+
+    /// \brief Indicates that the contents of this Objective-C class will be
+    /// completed by the external AST source when required.
+    mutable bool ExternallyCompleted : 1;
+
+    /// \brief Indicates that the ivar cache does not yet include ivars
+    /// declared in the implementation.
+    mutable bool IvarListMissingImplementation : 1;
+
+    /// Indicates that this interface decl contains at least one initializer
+    /// marked with the 'objc_designated_initializer' attribute.
+    bool HasDesignatedInitializers : 1;
+
+    enum InheritedDesignatedInitializersState {
+      /// We didn't calculate whether the designated initializers should be
+      /// inherited or not.
+      IDI_Unknown = 0,
+      /// Designated initializers are inherited for the super class.
+      IDI_Inherited = 1,
+      /// The class does not inherit designated initializers.
+      IDI_NotInherited = 2
+    };
+    /// One of the \c InheritedDesignatedInitializersState enumeratos.
+    mutable unsigned InheritedDesignatedInitializers : 2;
+
+    /// \brief The location of the superclass, if any.
+    SourceLocation SuperClassLoc;
+    
+    /// \brief The location of the last location in this declaration, before
+    /// the properties/methods. For example, this will be the '>', '}', or 
+    /// identifier, 
+    SourceLocation EndLoc; 
+
+    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 
+                       ExternallyCompleted(),
+                       IvarListMissingImplementation(true),
+                       HasDesignatedInitializers(),
+                       InheritedDesignatedInitializers(IDI_Unknown) { }
+  };
+
+  ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+                    IdentifierInfo *Id, SourceLocation CLoc,
+                    ObjCInterfaceDecl *PrevDecl, bool IsInternal);
+
+  void LoadExternalDefinition() const;
+
+  /// \brief Contains a pointer to the data associated with this class,
+  /// which will be NULL if this class has not yet been defined.
+  ///
+  /// The bit indicates when we don't need to check for out-of-date
+  /// declarations. It will be set unless modules are enabled.
+  llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
+
+  DefinitionData &data() const {
+    assert(Data.getPointer() && "Declaration has no definition!");
+    return *Data.getPointer();
+  }
+
+  /// \brief Allocate the definition data for this class.
+  void allocateDefinitionData();
+  
+  typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
+  ObjCInterfaceDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  ObjCInterfaceDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  ObjCInterfaceDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
+                                   SourceLocation atLoc,
+                                   IdentifierInfo *Id,
+                                   ObjCInterfaceDecl *PrevDecl,
+                                   SourceLocation ClassLoc = SourceLocation(),
+                                   bool isInternal = false);
+
+  static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    if (isThisDeclarationADefinition())
+      return ObjCContainerDecl::getSourceRange();
+    
+    return SourceRange(getAtStartLoc(), getLocation());
+  }
+
+  /// \brief Indicate that this Objective-C class is complete, but that
+  /// the external AST source will be responsible for filling in its contents
+  /// when a complete class is required.
+  void setExternallyCompleted();
+
+  /// Indicate that this interface decl contains at least one initializer
+  /// marked with the 'objc_designated_initializer' attribute.
+  void setHasDesignatedInitializers();
+
+  /// Returns true if this interface decl contains at least one initializer
+  /// marked with the 'objc_designated_initializer' attribute.
+  bool hasDesignatedInitializers() const;
+
+  /// Returns true if this interface decl declares a designated initializer
+  /// or it inherites one from its super class.
+  bool declaresOrInheritsDesignatedInitializers() const {
+    return hasDesignatedInitializers() || inheritsDesignatedInitializers();
+  }
+
+  const ObjCProtocolList &getReferencedProtocols() const {
+    assert(hasDefinition() && "Caller did not check for forward reference!");
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().ReferencedProtocols;
+  }
+
+  ObjCImplementationDecl *getImplementation() const;
+  void setImplementation(ObjCImplementationDecl *ImplD);
+
+  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
+
+  // Get the local instance/class method declared in a category.
+  ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
+  ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
+  ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
+    return isInstance ? getInstanceMethod(Sel)
+                      : getClassMethod(Sel);
+  }
+
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
+  protocol_iterator protocol_begin() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_iterator();
+    
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().ReferencedProtocols.begin();
+  }
+  protocol_iterator protocol_end() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_iterator();
+
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().ReferencedProtocols.end();
+  }
+
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
+  protocol_loc_iterator protocol_loc_begin() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().ReferencedProtocols.loc_begin();
+  }
+
+  protocol_loc_iterator protocol_loc_end() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().ReferencedProtocols.loc_end();
+  }
+
+  typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+  typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
+
+  all_protocol_range all_referenced_protocols() const {
+    return all_protocol_range(all_referenced_protocol_begin(),
+                              all_referenced_protocol_end());
+  }
+  all_protocol_iterator all_referenced_protocol_begin() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return all_protocol_iterator();
+
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().AllReferencedProtocols.empty()  
+             ? protocol_begin()
+             : data().AllReferencedProtocols.begin();
+  }
+  all_protocol_iterator all_referenced_protocol_end() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return all_protocol_iterator();
+    
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().AllReferencedProtocols.empty() 
+             ? protocol_end()
+             : data().AllReferencedProtocols.end();
+  }
+
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+  ivar_iterator ivar_begin() const { 
+    if (const ObjCInterfaceDecl *Def = getDefinition())
+      return ivar_iterator(Def->decls_begin()); 
+    
+    // FIXME: Should make sure no callers ever do this.
+    return ivar_iterator();
+  }
+  ivar_iterator ivar_end() const { 
+    if (const ObjCInterfaceDecl *Def = getDefinition())
+      return ivar_iterator(Def->decls_end()); 
+
+    // FIXME: Should make sure no callers ever do this.
+    return ivar_iterator();
+  }
+
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+
+  bool ivar_empty() const { return ivar_begin() == ivar_end(); }
+
+  ObjCIvarDecl *all_declared_ivar_begin();
+  const ObjCIvarDecl *all_declared_ivar_begin() const {
+    // Even though this modifies IvarList, it's conceptually const:
+    // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
+    return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
+  }
+  void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    data().ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  /// mergeClassExtensionProtocolList - Merge class extension's protocol list
+  /// into the protocol list for this class.
+  void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
+                                       unsigned Num,
+                                       ASTContext &C);
+
+  /// Produce a name to be used for class's metadata. It comes either via
+  /// objc_runtime_name attribute or class name.
+  StringRef getObjCRuntimeNameAsString() const;
+
+  /// Returns the designated initializers for the interface.
+  ///
+  /// If this declaration does not have methods marked as designated
+  /// initializers then the interface inherits the designated initializers of
+  /// its super class.
+  void getDesignatedInitializers(
+                  llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
+
+  /// Returns true if the given selector is a designated initializer for the
+  /// interface.
+  ///
+  /// If this declaration does not have methods marked as designated
+  /// initializers then the interface inherits the designated initializers of
+  /// its super class.
+  ///
+  /// \param InitMethod if non-null and the function returns true, it receives
+  /// the method that was marked as a designated initializer.
+  bool
+  isDesignatedInitializer(Selector Sel,
+                          const ObjCMethodDecl **InitMethod = nullptr) const;
+
+  /// \brief Determine whether this particular declaration of this class is
+  /// actually also a definition.
+  bool isThisDeclarationADefinition() const { 
+    return getDefinition() == this;
+  }
+                          
+  /// \brief Determine whether this class has been defined.
+  bool hasDefinition() const {
+    // If the name of this class is out-of-date, bring it up-to-date, which
+    // might bring in a definition.
+    // Note: a null value indicates that we don't have a definition and that
+    // modules are enabled.
+    if (!Data.getOpaqueValue()) {
+      if (IdentifierInfo *II = getIdentifier()) {
+        if (II->isOutOfDate()) {
+          updateOutOfDate(*II);
+        }
+      }
+    }
+
+    return Data.getPointer();
+  }
+                        
+  /// \brief Retrieve the definition of this class, or NULL if this class 
+  /// has been forward-declared (with \@class) but not yet defined (with 
+  /// \@interface).
+  ObjCInterfaceDecl *getDefinition() {
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
+  }
+
+  /// \brief Retrieve the definition of this class, or NULL if this class 
+  /// has been forward-declared (with \@class) but not yet defined (with 
+  /// \@interface).
+  const ObjCInterfaceDecl *getDefinition() const {
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
+  }
+
+  /// \brief Starts the definition of this Objective-C class, taking it from
+  /// a forward declaration (\@class) to a definition (\@interface).
+  void startDefinition();
+  
+  ObjCInterfaceDecl *getSuperClass() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return nullptr;
+    
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().SuperClass;
+  }
+
+  void setSuperClass(ObjCInterfaceDecl * superCls) { 
+    data().SuperClass = 
+      (superCls && superCls->hasDefinition()) ? superCls->getDefinition() 
+                                              : superCls; 
+  }
+
+  /// \brief Iterator that walks over the list of categories, filtering out
+  /// those that do not meet specific criteria.
+  ///
+  /// This class template is used for the various permutations of category
+  /// and extension iterators.
+  template<bool (*Filter)(ObjCCategoryDecl *)>
+  class filtered_category_iterator {
+    ObjCCategoryDecl *Current;
+
+    void findAcceptableCategory();
+    
+  public:
+    typedef ObjCCategoryDecl *      value_type;
+    typedef value_type              reference;
+    typedef value_type              pointer;
+    typedef std::ptrdiff_t          difference_type;
+    typedef std::input_iterator_tag iterator_category;
+
+    filtered_category_iterator() : Current(nullptr) { }
+    explicit filtered_category_iterator(ObjCCategoryDecl *Current)
+      : Current(Current)
+    {
+      findAcceptableCategory();
+    }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    filtered_category_iterator &operator++();
+
+    filtered_category_iterator operator++(int) {
+      filtered_category_iterator Tmp = *this;
+      ++(*this);
+      return Tmp;
+    }
+
+    friend bool operator==(filtered_category_iterator X,
+                           filtered_category_iterator Y) {
+      return X.Current == Y.Current;
+    }
+
+    friend bool operator!=(filtered_category_iterator X,
+                           filtered_category_iterator Y) {
+      return X.Current != Y.Current;
+    }
+  };
+
+private:
+  /// \brief Test whether the given category is visible.
+  ///
+  /// Used in the \c visible_categories_iterator.
+  static bool isVisibleCategory(ObjCCategoryDecl *Cat);
+                        
+public:
+  /// \brief Iterator that walks over the list of categories and extensions
+  /// that are visible, i.e., not hidden in a non-imported submodule.
+  typedef filtered_category_iterator<isVisibleCategory>
+    visible_categories_iterator;
+
+  typedef llvm::iterator_range<visible_categories_iterator>
+    visible_categories_range;
+
+  visible_categories_range visible_categories() const {
+    return visible_categories_range(visible_categories_begin(),
+                                    visible_categories_end());
+  }
+
+  /// \brief Retrieve an iterator to the beginning of the visible-categories
+  /// list.
+  visible_categories_iterator visible_categories_begin() const {
+    return visible_categories_iterator(getCategoryListRaw());
+  }
+
+  /// \brief Retrieve an iterator to the end of the visible-categories list.
+  visible_categories_iterator visible_categories_end() const {
+    return visible_categories_iterator();
+  }
+
+  /// \brief Determine whether the visible-categories list is empty.
+  bool visible_categories_empty() const {
+    return visible_categories_begin() == visible_categories_end();
+  }
+
+private:
+  /// \brief Test whether the given category... is a category.
+  ///
+  /// Used in the \c known_categories_iterator.
+  static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
+
+public:
+  /// \brief Iterator that walks over all of the known categories and
+  /// extensions, including those that are hidden.
+  typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
+  typedef llvm::iterator_range<known_categories_iterator>
+    known_categories_range;
+
+  known_categories_range known_categories() const {
+    return known_categories_range(known_categories_begin(),
+                                  known_categories_end());
+  }
+
+  /// \brief Retrieve an iterator to the beginning of the known-categories
+  /// list.
+  known_categories_iterator known_categories_begin() const {
+    return known_categories_iterator(getCategoryListRaw());
+  }
+
+  /// \brief Retrieve an iterator to the end of the known-categories list.
+  known_categories_iterator known_categories_end() const {
+    return known_categories_iterator();
+  }
+
+  /// \brief Determine whether the known-categories list is empty.
+  bool known_categories_empty() const {
+    return known_categories_begin() == known_categories_end();
+  }
+
+private:
+  /// \brief Test whether the given category is a visible extension.
+  ///
+  /// Used in the \c visible_extensions_iterator.
+  static bool isVisibleExtension(ObjCCategoryDecl *Cat);
+
+public:
+  /// \brief Iterator that walks over all of the visible extensions, skipping
+  /// any that are known but hidden.
+  typedef filtered_category_iterator<isVisibleExtension>
+    visible_extensions_iterator;
+
+  typedef llvm::iterator_range<visible_extensions_iterator>
+    visible_extensions_range;
+
+  visible_extensions_range visible_extensions() const {
+    return visible_extensions_range(visible_extensions_begin(),
+                                    visible_extensions_end());
+  }
+
+  /// \brief Retrieve an iterator to the beginning of the visible-extensions
+  /// list.
+  visible_extensions_iterator visible_extensions_begin() const {
+    return visible_extensions_iterator(getCategoryListRaw());
+  }
+
+  /// \brief Retrieve an iterator to the end of the visible-extensions list.
+  visible_extensions_iterator visible_extensions_end() const {
+    return visible_extensions_iterator();
+  }
+
+  /// \brief Determine whether the visible-extensions list is empty.
+  bool visible_extensions_empty() const {
+    return visible_extensions_begin() == visible_extensions_end();
+  }
+
+private:
+  /// \brief Test whether the given category is an extension.
+  ///
+  /// Used in the \c known_extensions_iterator.
+  static bool isKnownExtension(ObjCCategoryDecl *Cat);
+  
+public:
+  /// \brief Iterator that walks over all of the known extensions.
+  typedef filtered_category_iterator<isKnownExtension>
+    known_extensions_iterator;
+  typedef llvm::iterator_range<known_extensions_iterator>
+    known_extensions_range;
+
+  known_extensions_range known_extensions() const {
+    return known_extensions_range(known_extensions_begin(),
+                                  known_extensions_end());
+  }
+
+  /// \brief Retrieve an iterator to the beginning of the known-extensions
+  /// list.
+  known_extensions_iterator known_extensions_begin() const {
+    return known_extensions_iterator(getCategoryListRaw());
+  }
+  
+  /// \brief Retrieve an iterator to the end of the known-extensions list.
+  known_extensions_iterator known_extensions_end() const {
+    return known_extensions_iterator();
+  }
+
+  /// \brief Determine whether the known-extensions list is empty.
+  bool known_extensions_empty() const {
+    return known_extensions_begin() == known_extensions_end();
+  }
+
+  /// \brief Retrieve the raw pointer to the start of the category/extension
+  /// list.
+  ObjCCategoryDecl* getCategoryListRaw() const {
+    // FIXME: Should make sure no callers ever do this.
+    if (!hasDefinition())
+      return nullptr;
+    
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+
+    return data().CategoryList;
+  }
+
+  /// \brief Set the raw pointer to the start of the category/extension
+  /// list.
+  void setCategoryListRaw(ObjCCategoryDecl *category) {
+    data().CategoryList = category;
+  }
+
+  ObjCPropertyDecl
+    *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
+
+  void collectPropertiesToImplement(PropertyMap &PM,
+                                    PropertyDeclOrder &PO) const override;
+
+  /// isSuperClassOf - Return true if this class is the specified class or is a
+  /// super class of the specified interface class.
+  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
+    // If RHS is derived from LHS it is OK; else it is not OK.
+    while (I != nullptr) {
+      if (declaresSameEntity(this, I))
+        return true;
+      
+      I = I->getSuperClass();
+    }
+    return false;
+  }
+
+  /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
+  /// to be incompatible with __weak references. Returns true if it is.
+  bool isArcWeakrefUnavailable() const;
+
+  /// isObjCRequiresPropertyDefs - Checks that a class or one of its super 
+  /// classes must not be auto-synthesized. Returns class decl. if it must not
+  /// be; 0, otherwise.
+  const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const;
+
+  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
+                                       ObjCInterfaceDecl *&ClassDeclared);
+  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
+    ObjCInterfaceDecl *ClassDeclared;
+    return lookupInstanceVariable(IVarName, ClassDeclared);
+  }
+
+  ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
+                          
+  // Lookup a method. First, we search locally. If a method isn't
+  // found, we search referenced protocols and class categories.
+  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
+                               bool shallowCategoryLookup = false,
+                               bool followSuper = true,
+                               const ObjCCategoryDecl *C = nullptr) const;
+
+  /// Lookup an instance method for a given selector.
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
+  }
+
+  /// Lookup a class method for a given selector.
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
+  }
+  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
+
+  /// \brief Lookup a method in the classes implementation hierarchy.
+  ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
+                                      bool Instance=true) const;
+
+  ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
+    return lookupPrivateMethod(Sel, false);
+  }
+
+  /// \brief Lookup a setter or getter in the class hierarchy,
+  /// including in all categories except for category passed
+  /// as argument.
+  ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
+                                         const ObjCCategoryDecl *Cat) const {
+    return lookupMethod(Sel, true/*isInstance*/,
+                        false/*shallowCategoryLookup*/,
+                        true /* followsSuper */,
+                        Cat);
+  }
+                          
+  SourceLocation getEndOfDefinitionLoc() const { 
+    if (!hasDefinition())
+      return getLocation();
+    
+    return data().EndLoc; 
+  }
+                          
+  void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
+
+  void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
+  SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
+
+  /// isImplicitInterfaceDecl - check that this is an implicitly declared
+  /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
+  /// declaration without an \@interface declaration.
+  bool isImplicitInterfaceDecl() const { 
+    return hasDefinition() ? data().Definition->isImplicit() : isImplicit();
+  }
+
+  /// ClassImplementsProtocol - Checks that 'lProto' protocol
+  /// has been implemented in IDecl class, its super class or categories (if
+  /// lookupCategory is true).
+  bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
+                               bool lookupCategory,
+                               bool RHSIsQualifiedID = false);
+
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  /// Retrieves the canonical declaration of this Objective-C class.
+  ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  // Low-level accessor
+  const Type *getTypeForDecl() const { return TypeForDecl; }
+  void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCInterface; }
+
+  friend class ASTReader;
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+
+private:
+  const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
+  bool inheritsDesignatedInitializers() const;
+};
+
+/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
+/// instance variables are identical to C. The only exception is Objective-C
+/// supports C++ style access control. For example:
+///
+///   \@interface IvarExample : NSObject
+///   {
+///     id defaultToProtected;
+///   \@public:
+///     id canBePublic; // same as C++.
+///   \@protected:
+///     id canBeProtected; // same as C++.
+///   \@package:
+///     id canBePackage; // framework visibility (not available in C++).
+///   }
+///
+class ObjCIvarDecl : public FieldDecl {
+  void anchor() override;
+
+public:
+  enum AccessControl {
+    None, Private, Protected, Public, Package
+  };
+
+private:
+  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
+               SourceLocation IdLoc, IdentifierInfo *Id,
+               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
+               bool synthesized)
+    : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
+                /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
+      NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
+
+public:
+  static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
+                              SourceLocation StartLoc, SourceLocation IdLoc,
+                              IdentifierInfo *Id, QualType T,
+                              TypeSourceInfo *TInfo,
+                              AccessControl ac, Expr *BW = nullptr,
+                              bool synthesized=false);
+
+  static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  /// \brief Return the class interface that this ivar is logically contained
+  /// in; this is either the interface where the ivar was declared, or the
+  /// interface the ivar is conceptually a part of in the case of synthesized
+  /// ivars.
+  const ObjCInterfaceDecl *getContainingInterface() const;
+
+  ObjCIvarDecl *getNextIvar() { return NextIvar; }
+  const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
+  void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
+
+  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
+
+  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
+
+  AccessControl getCanonicalAccessControl() const {
+    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
+  }
+
+  void setSynthesize(bool synth) { Synthesized = synth; }
+  bool getSynthesize() const { return Synthesized; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCIvar; }
+private:
+  /// NextIvar - Next Ivar in the list of ivars declared in class; class's
+  /// extensions and class's implementation
+  ObjCIvarDecl *NextIvar;
+
+  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+  unsigned DeclAccess : 3;
+  unsigned Synthesized : 1;
+};
+
+
+/// \brief Represents a field declaration created by an \@defs(...).
+class ObjCAtDefsFieldDecl : public FieldDecl {
+  void anchor() override;
+  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
+                      SourceLocation IdLoc, IdentifierInfo *Id,
+                      QualType T, Expr *BW)
+    : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
+                /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
+                BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
+
+public:
+  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation StartLoc,
+                                     SourceLocation IdLoc, IdentifierInfo *Id,
+                                     QualType T, Expr *BW);
+
+  static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
+};
+
+/// \brief Represents an Objective-C protocol declaration.
+///
+/// Objective-C protocols declare a pure abstract type (i.e., no instance
+/// variables are permitted).  Protocols originally drew inspiration from
+/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
+/// syntax:-). Here is an example:
+///
+/// \code
+/// \@protocol NSDraggingInfo <refproto1, refproto2>
+/// - (NSWindow *)draggingDestinationWindow;
+/// - (NSImage *)draggedImage;
+/// \@end
+/// \endcode
+///
+/// This says that NSDraggingInfo requires two methods and requires everything
+/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
+/// well.
+///
+/// \code
+/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
+/// \@end
+/// \endcode
+///
+/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
+/// protocols are in distinct namespaces. For example, Cocoa defines both
+/// an NSObject protocol and class (which isn't allowed in Java). As a result,
+/// protocols are referenced using angle brackets as follows:
+///
+/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
+///
+class ObjCProtocolDecl : public ObjCContainerDecl,
+                         public Redeclarable<ObjCProtocolDecl> {
+  void anchor() override;
+
+  struct DefinitionData {
+    // \brief The declaration that defines this protocol.
+    ObjCProtocolDecl *Definition;
+
+    /// \brief Referenced protocols
+    ObjCProtocolList ReferencedProtocols;    
+  };
+
+  /// \brief Contains a pointer to the data associated with this class,
+  /// which will be NULL if this class has not yet been defined.
+  ///
+  /// The bit indicates when we don't need to check for out-of-date
+  /// declarations. It will be set unless modules are enabled.
+  llvm::PointerIntPair<DefinitionData *, 1, bool> Data;
+
+  DefinitionData &data() const {
+    assert(Data.getPointer() && "Objective-C protocol has no definition!");
+    return *Data.getPointer();
+  }
+  
+  ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
+                   SourceLocation nameLoc, SourceLocation atStartLoc,
+                   ObjCProtocolDecl *PrevDecl);
+
+  void allocateDefinitionData();
+
+  typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
+  ObjCProtocolDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  ObjCProtocolDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  ObjCProtocolDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+public:
+  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
+                                  IdentifierInfo *Id,
+                                  SourceLocation nameLoc,
+                                  SourceLocation atStartLoc,
+                                  ObjCProtocolDecl *PrevDecl);
+
+  static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  const ObjCProtocolList &getReferencedProtocols() const {
+    assert(hasDefinition() && "No definition available!");
+    return data().ReferencedProtocols;
+  }
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
+  protocol_iterator protocol_begin() const {
+    if (!hasDefinition())
+      return protocol_iterator();
+    
+    return data().ReferencedProtocols.begin();
+  }
+  protocol_iterator protocol_end() const { 
+    if (!hasDefinition())
+      return protocol_iterator();
+    
+    return data().ReferencedProtocols.end(); 
+  }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
+  protocol_loc_iterator protocol_loc_begin() const {
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+    
+    return data().ReferencedProtocols.loc_begin();
+  }
+  protocol_loc_iterator protocol_loc_end() const {
+    if (!hasDefinition())
+      return protocol_loc_iterator();
+    
+    return data().ReferencedProtocols.loc_end();
+  }
+  unsigned protocol_size() const { 
+    if (!hasDefinition())
+      return 0;
+    
+    return data().ReferencedProtocols.size(); 
+  }
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    assert(hasDefinition() && "Protocol is not defined");
+    data().ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
+
+  // Lookup a method. First, we search locally. If a method isn't
+  // found, we search referenced protocols and class categories.
+  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
+  }
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
+  }
+
+  /// \brief Determine whether this protocol has a definition.
+  bool hasDefinition() const {
+    // If the name of this protocol is out-of-date, bring it up-to-date, which
+    // might bring in a definition.
+    // Note: a null value indicates that we don't have a definition and that
+    // modules are enabled.
+    if (!Data.getOpaqueValue()) {
+      if (IdentifierInfo *II = getIdentifier()) {
+        if (II->isOutOfDate()) {
+          updateOutOfDate(*II);
+        }
+      }
+    }
+
+    return Data.getPointer();
+  }
+
+  /// \brief Retrieve the definition of this protocol, if any.
+  ObjCProtocolDecl *getDefinition() {
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
+  }
+
+  /// \brief Retrieve the definition of this protocol, if any.
+  const ObjCProtocolDecl *getDefinition() const {
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
+  }
+
+  /// \brief Determine whether this particular declaration is also the 
+  /// definition.
+  bool isThisDeclarationADefinition() const {
+    return getDefinition() == this;
+  }
+  
+  /// \brief Starts the definition of this Objective-C protocol.
+  void startDefinition();
+
+  /// Produce a name to be used for protocol's metadata. It comes either via
+  /// objc_runtime_name attribute or protocol name.
+  StringRef getObjCRuntimeNameAsString() const;
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    if (isThisDeclarationADefinition())
+      return ObjCContainerDecl::getSourceRange();
+   
+    return SourceRange(getAtStartLoc(), getLocation());
+  }
+   
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  /// Retrieves the canonical declaration of this Objective-C protocol.
+  ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
+  const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
+  void collectPropertiesToImplement(PropertyMap &PM,
+                                    PropertyDeclOrder &PO) const override;
+
+  void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
+                                          ProtocolPropertyMap &PM) const;
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCProtocol; }
+
+  friend class ASTReader;
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// ObjCCategoryDecl - Represents a category declaration. A category allows
+/// you to add methods to an existing class (without subclassing or modifying
+/// the original class interface or implementation:-). Categories don't allow
+/// you to add instance data. The following example adds "myMethod" to all
+/// NSView's within a process:
+///
+/// \@interface NSView (MyViewMethods)
+/// - myMethod;
+/// \@end
+///
+/// Categories also allow you to split the implementation of a class across
+/// several files (a feature more naturally supported in C++).
+///
+/// Categories were originally inspired by dynamic languages such as Common
+/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
+/// don't support this level of dynamism, which is both powerful and dangerous.
+///
+class ObjCCategoryDecl : public ObjCContainerDecl {
+  void anchor() override;
+
+  /// Interface belonging to this category
+  ObjCInterfaceDecl *ClassInterface;
+
+  /// referenced protocols in this category.
+  ObjCProtocolList ReferencedProtocols;
+
+  /// Next category belonging to this class.
+  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
+  ObjCCategoryDecl *NextClassCategory;
+
+  /// \brief The location of the category name in this declaration.
+  SourceLocation CategoryNameLoc;
+
+  /// class extension may have private ivars.
+  SourceLocation IvarLBraceLoc;
+  SourceLocation IvarRBraceLoc;
+  
+  ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
+                   SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
+                   IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
+                   SourceLocation IvarLBraceLoc=SourceLocation(),
+                   SourceLocation IvarRBraceLoc=SourceLocation())
+    : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
+      ClassInterface(IDecl), NextClassCategory(nullptr),
+      CategoryNameLoc(CategoryNameLoc),
+      IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
+  }
+
+public:
+
+  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation AtLoc,
+                                  SourceLocation ClassNameLoc,
+                                  SourceLocation CategoryNameLoc,
+                                  IdentifierInfo *Id,
+                                  ObjCInterfaceDecl *IDecl,
+                                  SourceLocation IvarLBraceLoc=SourceLocation(),
+                                  SourceLocation IvarRBraceLoc=SourceLocation());
+  static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
+  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
+
+  ObjCCategoryImplDecl *getImplementation() const;
+  void setImplementation(ObjCCategoryImplDecl *ImplD);
+
+  /// setProtocolList - Set the list of protocols that this interface
+  /// implements.
+  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
+                       const SourceLocation *Locs, ASTContext &C) {
+    ReferencedProtocols.set(List, Num, Locs, C);
+  }
+
+  const ObjCProtocolList &getReferencedProtocols() const {
+    return ReferencedProtocols;
+  }
+
+  typedef ObjCProtocolList::iterator protocol_iterator;
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
+  protocol_iterator protocol_begin() const {
+    return ReferencedProtocols.begin();
+  }
+  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
+  unsigned protocol_size() const { return ReferencedProtocols.size(); }
+  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
+  protocol_loc_iterator protocol_loc_begin() const {
+    return ReferencedProtocols.loc_begin();
+  }
+  protocol_loc_iterator protocol_loc_end() const {
+    return ReferencedProtocols.loc_end();
+  }
+
+  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
+
+  /// \brief Retrieve the pointer to the next stored category (or extension),
+  /// which may be hidden.
+  ObjCCategoryDecl *getNextClassCategoryRaw() const {
+    return NextClassCategory;
+  }
+
+  bool IsClassExtension() const { return getIdentifier() == nullptr; }
+
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+  ivar_iterator ivar_begin() const {
+    return ivar_iterator(decls_begin());
+  }
+  ivar_iterator ivar_end() const {
+    return ivar_iterator(decls_end());
+  }
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+  bool ivar_empty() const {
+    return ivar_begin() == ivar_end();
+  }
+
+  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
+  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
+  
+  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
+  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
+  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
+  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCCategory; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+class ObjCImplDecl : public ObjCContainerDecl {
+  void anchor() override;
+
+  /// Class interface for this class/category implementation
+  ObjCInterfaceDecl *ClassInterface;
+
+protected:
+  ObjCImplDecl(Kind DK, DeclContext *DC,
+               ObjCInterfaceDecl *classInterface,
+               SourceLocation nameLoc, SourceLocation atStartLoc)
+    : ObjCContainerDecl(DK, DC,
+                        classInterface? classInterface->getIdentifier()
+                                      : nullptr,
+                        nameLoc, atStartLoc),
+      ClassInterface(classInterface) {}
+
+public:
+  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
+  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
+  void setClassInterface(ObjCInterfaceDecl *IFace);
+
+  void addInstanceMethod(ObjCMethodDecl *method) {
+    // FIXME: Context should be set correctly before we get here.
+    method->setLexicalDeclContext(this);
+    addDecl(method);
+  }
+  void addClassMethod(ObjCMethodDecl *method) {
+    // FIXME: Context should be set correctly before we get here.
+    method->setLexicalDeclContext(this);
+    addDecl(method);
+  }
+
+  void addPropertyImplementation(ObjCPropertyImplDecl *property);
+
+  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
+  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
+
+  // Iterator access to properties.
+  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
+    propimpl_range;
+
+  propimpl_range property_impls() const {
+    return propimpl_range(propimpl_begin(), propimpl_end());
+  }
+  propimpl_iterator propimpl_begin() const {
+    return propimpl_iterator(decls_begin());
+  }
+  propimpl_iterator propimpl_end() const {
+    return propimpl_iterator(decls_end());
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstObjCImpl && K <= lastObjCImpl;
+  }
+};
+
+/// ObjCCategoryImplDecl - An object of this class encapsulates a category
+/// \@implementation declaration. If a category class has declaration of a
+/// property, its implementation must be specified in the category's
+/// \@implementation declaration. Example:
+/// \@interface I \@end
+/// \@interface I(CATEGORY)
+///    \@property int p1, d1;
+/// \@end
+/// \@implementation I(CATEGORY)
+///  \@dynamic p1,d1;
+/// \@end
+///
+/// ObjCCategoryImplDecl
+class ObjCCategoryImplDecl : public ObjCImplDecl {
+  void anchor() override;
+
+  // Category name
+  IdentifierInfo *Id;
+
+  // Category name location
+  SourceLocation CategoryNameLoc;
+
+  ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
+                       ObjCInterfaceDecl *classInterface,
+                       SourceLocation nameLoc, SourceLocation atStartLoc,
+                       SourceLocation CategoryNameLoc)
+    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
+      Id(Id), CategoryNameLoc(CategoryNameLoc) {}
+public:
+  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
+                                      IdentifierInfo *Id,
+                                      ObjCInterfaceDecl *classInterface,
+                                      SourceLocation nameLoc,
+                                      SourceLocation atStartLoc,
+                                      SourceLocation CategoryNameLoc);
+  static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// getIdentifier - Get the identifier that names the category
+  /// interface associated with this implementation.
+  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
+  /// with a different meaning. For example:
+  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
+  /// returns the class interface name, whereas
+  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
+  /// returns the category name.
+  IdentifierInfo *getIdentifier() const {
+    return Id;
+  }
+  void setIdentifier(IdentifierInfo *II) { Id = II; }
+
+  ObjCCategoryDecl *getCategoryDecl() const;
+
+  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
+
+  /// getName - Get the name of identifier for the class interface associated
+  /// with this implementation as a StringRef.
+  //
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
+  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
+
+  /// @brief Get the name of the class associated with this interface.
+  //
+  // FIXME: Deprecated, move clients to getName().
+  std::string getNameAsString() const {
+    return getName();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
+
+/// ObjCImplementationDecl - Represents a class definition - this is where
+/// method definitions are specified. For example:
+///
+/// @code
+/// \@implementation MyClass
+/// - (void)myMethod { /* do something */ }
+/// \@end
+/// @endcode
+///
+/// In a non-fragile runtime, instance variables can appear in the class
+/// interface, class extensions (nameless categories), and in the implementation
+/// itself, as well as being synthesized as backing storage for properties.
+///
+/// In a fragile runtime, instance variables are specified in the class
+/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
+/// we allow instance variables to be specified in the implementation. When
+/// specified, they need to be \em identical to the interface.
+class ObjCImplementationDecl : public ObjCImplDecl {
+  void anchor() override;
+  /// Implementation Class's super class.
+  ObjCInterfaceDecl *SuperClass;
+  SourceLocation SuperLoc;
+
+  /// \@implementation may have private ivars.
+  SourceLocation IvarLBraceLoc;
+  SourceLocation IvarRBraceLoc;
+  
+  /// Support for ivar initialization.
+  /// IvarInitializers - The arguments used to initialize the ivars
+  CXXCtorInitializer **IvarInitializers;
+  unsigned NumIvarInitializers;
+
+  /// Do the ivars of this class require initialization other than
+  /// zero-initialization?
+  bool HasNonZeroConstructors : 1;
+
+  /// Do the ivars of this class require non-trivial destruction?
+  bool HasDestructors : 1;
+
+  ObjCImplementationDecl(DeclContext *DC,
+                         ObjCInterfaceDecl *classInterface,
+                         ObjCInterfaceDecl *superDecl,
+                         SourceLocation nameLoc, SourceLocation atStartLoc,
+                         SourceLocation superLoc = SourceLocation(),
+                         SourceLocation IvarLBraceLoc=SourceLocation(), 
+                         SourceLocation IvarRBraceLoc=SourceLocation())
+    : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
+       SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
+       IvarRBraceLoc(IvarRBraceLoc),
+       IvarInitializers(nullptr), NumIvarInitializers(0),
+       HasNonZeroConstructors(false), HasDestructors(false) {}
+public:
+  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
+                                        ObjCInterfaceDecl *classInterface,
+                                        ObjCInterfaceDecl *superDecl,
+                                        SourceLocation nameLoc,
+                                        SourceLocation atStartLoc,
+                                     SourceLocation superLoc = SourceLocation(),
+                                        SourceLocation IvarLBraceLoc=SourceLocation(), 
+                                        SourceLocation IvarRBraceLoc=SourceLocation());
+
+  static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// init_iterator - Iterates through the ivar initializer list.
+  typedef CXXCtorInitializer **init_iterator;
+
+  /// init_const_iterator - Iterates through the ivar initializer list.
+  typedef CXXCtorInitializer * const * init_const_iterator;
+
+  typedef llvm::iterator_range<init_iterator> init_range;
+  typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+  init_range inits() { return init_range(init_begin(), init_end()); }
+  init_const_range inits() const {
+    return init_const_range(init_begin(), init_end());
+  }
+
+  /// init_begin() - Retrieve an iterator to the first initializer.
+  init_iterator       init_begin()       { return IvarInitializers; }
+  /// begin() - Retrieve an iterator to the first initializer.
+  init_const_iterator init_begin() const { return IvarInitializers; }
+
+  /// init_end() - Retrieve an iterator past the last initializer.
+  init_iterator       init_end()       {
+    return IvarInitializers + NumIvarInitializers;
+  }
+  /// end() - Retrieve an iterator past the last initializer.
+  init_const_iterator init_end() const {
+    return IvarInitializers + NumIvarInitializers;
+  }
+  /// getNumArgs - Number of ivars which must be initialized.
+  unsigned getNumIvarInitializers() const {
+    return NumIvarInitializers;
+  }
+
+  void setNumIvarInitializers(unsigned numNumIvarInitializers) {
+    NumIvarInitializers = numNumIvarInitializers;
+  }
+
+  void setIvarInitializers(ASTContext &C,
+                           CXXCtorInitializer ** initializers,
+                           unsigned numInitializers);
+
+  /// Do any of the ivars of this class (not counting its base classes)
+  /// require construction other than zero-initialization?
+  bool hasNonZeroConstructors() const { return HasNonZeroConstructors; }
+  void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; }
+
+  /// Do any of the ivars of this class (not counting its base classes)
+  /// require non-trivial destruction?
+  bool hasDestructors() const { return HasDestructors; }
+  void setHasDestructors(bool val) { HasDestructors = val; }
+
+  /// getIdentifier - Get the identifier that names the class
+  /// interface associated with this implementation.
+  IdentifierInfo *getIdentifier() const {
+    return getClassInterface()->getIdentifier();
+  }
+
+  /// getName - Get the name of identifier for the class interface associated
+  /// with this implementation as a StringRef.
+  //
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
+  StringRef getName() const {
+    assert(getIdentifier() && "Name is not a simple identifier");
+    return getIdentifier()->getName();
+  }
+
+  /// @brief Get the name of the class associated with this interface.
+  //
+  // FIXME: Move to StringRef API.
+  std::string getNameAsString() const {
+    return getName();
+  }
+    
+  /// Produce a name to be used for class's metadata. It comes either via
+  /// class's objc_runtime_name attribute or class name.
+  StringRef getObjCRuntimeNameAsString() const;
+
+  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
+  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
+  SourceLocation getSuperClassLoc() const { return SuperLoc; }
+
+  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
+
+  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
+  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
+  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
+  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
+  
+  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
+  ivar_iterator ivar_begin() const {
+    return ivar_iterator(decls_begin());
+  }
+  ivar_iterator ivar_end() const {
+    return ivar_iterator(decls_end());
+  }
+  unsigned ivar_size() const {
+    return std::distance(ivar_begin(), ivar_end());
+  }
+  bool ivar_empty() const {
+    return ivar_begin() == ivar_end();
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCImplementation; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
+
+/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
+/// declared as \@compatibility_alias alias class.
+class ObjCCompatibleAliasDecl : public NamedDecl {
+  void anchor() override;
+  /// Class that this is an alias of.
+  ObjCInterfaceDecl *AliasedClass;
+
+  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                          ObjCInterfaceDecl* aliasedClass)
+    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
+public:
+  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
+                                         SourceLocation L, IdentifierInfo *Id,
+                                         ObjCInterfaceDecl* aliasedClass);
+
+  static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, 
+                                                     unsigned ID);
+  
+  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
+  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
+  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
+
+};
+
+/// \brief Represents one property declaration in an Objective-C interface.
+///
+/// For example:
+/// \code{.mm}
+/// \@property (assign, readwrite) int MyProperty;
+/// \endcode
+class ObjCPropertyDecl : public NamedDecl {
+  void anchor() override;
+public:
+  enum PropertyAttributeKind {
+    OBJC_PR_noattr    = 0x00,
+    OBJC_PR_readonly  = 0x01,
+    OBJC_PR_getter    = 0x02,
+    OBJC_PR_assign    = 0x04,
+    OBJC_PR_readwrite = 0x08,
+    OBJC_PR_retain    = 0x10,
+    OBJC_PR_copy      = 0x20,
+    OBJC_PR_nonatomic = 0x40,
+    OBJC_PR_setter    = 0x80,
+    OBJC_PR_atomic    = 0x100,
+    OBJC_PR_weak      = 0x200,
+    OBJC_PR_strong    = 0x400,
+    OBJC_PR_unsafe_unretained = 0x800
+    // Adding a property should change NumPropertyAttrsBits
+  };
+
+  enum {
+    /// \brief Number of bits fitting all the property attributes.
+    NumPropertyAttrsBits = 12
+  };
+
+  enum SetterKind { Assign, Retain, Copy, Weak };
+  enum PropertyControl { None, Required, Optional };
+private:
+  SourceLocation AtLoc;   // location of \@property
+  SourceLocation LParenLoc; // location of '(' starting attribute list or null.
+  TypeSourceInfo *DeclType;
+  unsigned PropertyAttributes : NumPropertyAttrsBits;
+  unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
+  // \@required/\@optional
+  unsigned PropertyImplementation : 2;
+
+  Selector GetterName;    // getter name of NULL if no getter
+  Selector SetterName;    // setter name of NULL if no setter
+
+  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
+  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
+  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
+
+  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+                   SourceLocation AtLocation,  SourceLocation LParenLocation,
+                   TypeSourceInfo *T)
+    : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), 
+      LParenLoc(LParenLocation), DeclType(T),
+      PropertyAttributes(OBJC_PR_noattr),
+      PropertyAttributesAsWritten(OBJC_PR_noattr),
+      PropertyImplementation(None),
+      GetterName(Selector()),
+      SetterName(Selector()),
+      GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
+      PropertyIvarDecl(nullptr) {}
+
+public:
+  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+                                  SourceLocation L,
+                                  IdentifierInfo *Id, SourceLocation AtLocation,
+                                  SourceLocation LParenLocation,
+                                  TypeSourceInfo *T,
+                                  PropertyControl propControl = None);
+  
+  static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+  TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
+  QualType getType() const { return DeclType->getType(); }
+  void setType(TypeSourceInfo *T) { DeclType = T; }
+
+  PropertyAttributeKind getPropertyAttributes() const {
+    return PropertyAttributeKind(PropertyAttributes);
+  }
+  void setPropertyAttributes(PropertyAttributeKind PRVal) {
+    PropertyAttributes |= PRVal;
+  }
+
+  PropertyAttributeKind getPropertyAttributesAsWritten() const {
+    return PropertyAttributeKind(PropertyAttributesAsWritten);
+  }
+
+  bool hasWrittenStorageAttribute() const {
+    return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
+        OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
+        OBJC_PR_weak);
+  }
+
+  void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
+    PropertyAttributesAsWritten = PRVal;
+  }
+
+ void makeitReadWriteAttribute() {
+    PropertyAttributes &= ~OBJC_PR_readonly;
+    PropertyAttributes |= OBJC_PR_readwrite;
+ }
+
+  // Helper methods for accessing attributes.
+
+  /// isReadOnly - Return true iff the property has a setter.
+  bool isReadOnly() const {
+    return (PropertyAttributes & OBJC_PR_readonly);
+  }
+
+  /// isAtomic - Return true if the property is atomic.
+  bool isAtomic() const {
+    return (PropertyAttributes & OBJC_PR_atomic);
+  }
+
+  /// isRetaining - Return true if the property retains its value.
+  bool isRetaining() const {
+    return (PropertyAttributes &
+            (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
+  }
+
+  /// getSetterKind - Return the method used for doing assignment in
+  /// the property setter. This is only valid if the property has been
+  /// defined to have a setter.
+  SetterKind getSetterKind() const {
+    if (PropertyAttributes & OBJC_PR_strong)
+      return getType()->isBlockPointerType() ? Copy : Retain;
+    if (PropertyAttributes & OBJC_PR_retain)
+      return Retain;
+    if (PropertyAttributes & OBJC_PR_copy)
+      return Copy;
+    if (PropertyAttributes & OBJC_PR_weak)
+      return Weak;
+    return Assign;
+  }
+
+  Selector getGetterName() const { return GetterName; }
+  void setGetterName(Selector Sel) { GetterName = Sel; }
+
+  Selector getSetterName() const { return SetterName; }
+  void setSetterName(Selector Sel) { SetterName = Sel; }
+
+  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
+  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
+
+  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
+  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
+
+  // Related to \@optional/\@required declared in \@protocol
+  void setPropertyImplementation(PropertyControl pc) {
+    PropertyImplementation = pc;
+  }
+  PropertyControl getPropertyImplementation() const {
+    return PropertyControl(PropertyImplementation);
+  }
+
+  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
+    PropertyIvarDecl = Ivar;
+  }
+  ObjCIvarDecl *getPropertyIvarDecl() const {
+    return PropertyIvarDecl;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(AtLoc, getLocation());
+  }
+  
+  /// Get the default name of the synthesized ivar.
+  IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
+
+  /// Lookup a property by name in the specified DeclContext.
+  static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
+                                            IdentifierInfo *propertyID);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ObjCProperty; }
+};
+
+/// ObjCPropertyImplDecl - Represents implementation declaration of a property
+/// in a class or category implementation block. For example:
+/// \@synthesize prop1 = ivar1;
+///
+class ObjCPropertyImplDecl : public Decl {
+public:
+  enum Kind {
+    Synthesize,
+    Dynamic
+  };
+private:
+  SourceLocation AtLoc;   // location of \@synthesize or \@dynamic
+
+  /// \brief For \@synthesize, the location of the ivar, if it was written in
+  /// the source code.
+  ///
+  /// \code
+  /// \@synthesize int a = b
+  /// \endcode
+  SourceLocation IvarLoc;
+
+  /// Property declaration being implemented
+  ObjCPropertyDecl *PropertyDecl;
+
+  /// Null for \@dynamic. Required for \@synthesize.
+  ObjCIvarDecl *PropertyIvarDecl;
+
+  /// Null for \@dynamic. Non-null if property must be copy-constructed in
+  /// getter.
+  Expr *GetterCXXConstructor;
+
+  /// Null for \@dynamic. Non-null if property has assignment operator to call
+  /// in Setter synthesis.
+  Expr *SetterCXXAssignment;
+
+  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
+                       ObjCPropertyDecl *property,
+                       Kind PK,
+                       ObjCIvarDecl *ivarDecl,
+                       SourceLocation ivarLoc)
+    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
+      IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+      GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
+    assert (PK == Dynamic || PropertyIvarDecl);
+  }
+
+public:
+  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation atLoc, SourceLocation L,
+                                      ObjCPropertyDecl *property,
+                                      Kind PK,
+                                      ObjCIvarDecl *ivarDecl,
+                                      SourceLocation ivarLoc);
+
+  static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
+
+  ObjCPropertyDecl *getPropertyDecl() const {
+    return PropertyDecl;
+  }
+  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
+
+  Kind getPropertyImplementation() const {
+    return PropertyIvarDecl ? Synthesize : Dynamic;
+  }
+
+  ObjCIvarDecl *getPropertyIvarDecl() const {
+    return PropertyIvarDecl;
+  }
+  SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
+
+  void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
+                           SourceLocation IvarLoc) {
+    PropertyIvarDecl = Ivar;
+    this->IvarLoc = IvarLoc;
+  }
+
+  /// \brief For \@synthesize, returns true if an ivar name was explicitly
+  /// specified.
+  ///
+  /// \code
+  /// \@synthesize int a = b; // true
+  /// \@synthesize int a; // false
+  /// \endcode
+  bool isIvarNameSpecified() const {
+    return IvarLoc.isValid() && IvarLoc != getLocation();
+  }
+
+  Expr *getGetterCXXConstructor() const {
+    return GetterCXXConstructor;
+  }
+  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
+    GetterCXXConstructor = getterCXXConstructor;
+  }
+
+  Expr *getSetterCXXAssignment() const {
+    return SetterCXXAssignment;
+  }
+  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
+    SetterCXXAssignment = setterCXXAssignment;
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
+
+  friend class ASTDeclReader;
+};
+
+template<bool (*Filter)(ObjCCategoryDecl *)>
+void
+ObjCInterfaceDecl::filtered_category_iterator<Filter>::
+findAcceptableCategory() {
+  while (Current && !Filter(Current))
+    Current = Current->getNextClassCategoryRaw();
+}
+
+template<bool (*Filter)(ObjCCategoryDecl *)>
+inline ObjCInterfaceDecl::filtered_category_iterator<Filter> &
+ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
+  Current = Current->getNextClassCategoryRaw();
+  findAcceptableCategory();
+  return *this;
+}
+
+inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
+  return !Cat->isHidden();
+}
+
+inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
+  return Cat->IsClassExtension() && !Cat->isHidden();
+}
+
+inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
+  return Cat->IsClassExtension();
+}
+
+}  // end namespace clang
+#endif
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
new file mode 100644
index 0000000..1b329dc
--- /dev/null
+++ b/include/clang/AST/DeclOpenMP.h
@@ -0,0 +1,90 @@
+//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines OpenMP nodes for declarative directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMP_H
+#define LLVM_CLANG_AST_OPENMP_H
+
+#include "clang/AST/DeclBase.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+
+/// \brief This represents '#pragma omp threadprivate ...' directive.
+/// For example, in the following, both 'a' and 'A::b' are threadprivate:
+///
+/// \code
+/// int a;
+/// #pragma omp threadprivate(a)
+/// struct A {
+///   static int b;
+/// #pragma omp threadprivate(b)
+/// };
+/// \endcode
+///
+class OMPThreadPrivateDecl : public Decl {
+  friend class ASTDeclReader;
+  unsigned NumVars;
+
+  virtual void anchor();
+
+  OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
+    Decl(DK, DC, L), NumVars(0) { }
+
+  ArrayRef<const Expr *> getVars() const {
+    return ArrayRef<const Expr *>(
+                   reinterpret_cast<const Expr * const *>(this + 1),
+                   NumVars);
+  }
+
+  MutableArrayRef<Expr *> getVars() {
+    return MutableArrayRef<Expr *>(
+                           reinterpret_cast<Expr **>(this + 1),
+                           NumVars);
+  }
+
+  void setVars(ArrayRef<Expr *> VL);
+
+public:
+  static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation L,
+                                      ArrayRef<Expr *> VL);
+  static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
+                                                  unsigned ID, unsigned N);
+
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+  typedef llvm::iterator_range<varlist_iterator> varlist_range;
+  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+
+  unsigned varlist_size() const { return NumVars; }
+  bool varlist_empty() const { return NumVars == 0; }
+
+  varlist_range varlists() {
+    return varlist_range(varlist_begin(), varlist_end());
+  }
+  varlist_const_range varlists() const {
+    return varlist_const_range(varlist_begin(), varlist_end());
+  }
+  varlist_iterator varlist_begin() { return getVars().begin(); }
+  varlist_iterator varlist_end() { return getVars().end(); }
+  varlist_const_iterator varlist_begin() const { return getVars().begin(); }
+  varlist_const_iterator varlist_end() const { return getVars().end(); }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
new file mode 100644
index 0000000..980a06e
--- /dev/null
+++ b/include/clang/AST/DeclTemplate.h
@@ -0,0 +1,2799 @@
+//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the C++ template declaration subclasses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
+#define LLVM_CLANG_AST_DECLTEMPLATE_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Redeclarable.h"
+#include "clang/AST/TemplateBase.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Compiler.h"
+#include <limits>
+
+namespace clang {
+
+class TemplateParameterList;
+class TemplateDecl;
+class RedeclarableTemplateDecl;
+class FunctionTemplateDecl;
+class ClassTemplateDecl;
+class ClassTemplatePartialSpecializationDecl;
+class TemplateTypeParmDecl;
+class NonTypeTemplateParmDecl;
+class TemplateTemplateParmDecl;
+class TypeAliasTemplateDecl;
+class VarTemplateDecl;
+class VarTemplatePartialSpecializationDecl;
+
+/// \brief Stores a template parameter of any kind.
+typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
+                            TemplateTemplateParmDecl*> TemplateParameter;
+
+/// \brief Stores a list of template parameters for a TemplateDecl and its
+/// derived classes.
+class TemplateParameterList {
+  /// The location of the 'template' keyword.
+  SourceLocation TemplateLoc;
+
+  /// The locations of the '<' and '>' angle brackets.
+  SourceLocation LAngleLoc, RAngleLoc;
+
+  /// The number of template parameters in this template
+  /// parameter list.
+  unsigned NumParams : 31;
+
+  /// Whether this template parameter list contains an unexpanded parameter
+  /// pack.
+  unsigned ContainsUnexpandedParameterPack : 1;
+
+protected:
+  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+                        NamedDecl **Params, unsigned NumParams,
+                        SourceLocation RAngleLoc);
+
+public:
+  static TemplateParameterList *Create(const ASTContext &C,
+                                       SourceLocation TemplateLoc,
+                                       SourceLocation LAngleLoc,
+                                       NamedDecl **Params,
+                                       unsigned NumParams,
+                                       SourceLocation RAngleLoc);
+
+  /// \brief Iterates through the template parameters in this list.
+  typedef NamedDecl** iterator;
+
+  /// \brief Iterates through the template parameters in this list.
+  typedef NamedDecl* const* const_iterator;
+
+  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
+  const_iterator begin() const {
+    return reinterpret_cast<NamedDecl * const *>(this + 1);
+  }
+  iterator end() { return begin() + NumParams; }
+  const_iterator end() const { return begin() + NumParams; }
+
+  unsigned size() const { return NumParams; }
+
+  ArrayRef<NamedDecl*> asArray() {
+    return ArrayRef<NamedDecl*>(begin(), size());
+  }
+  ArrayRef<const NamedDecl*> asArray() const {
+    return ArrayRef<const NamedDecl*>(begin(), size());
+  }
+
+  NamedDecl* getParam(unsigned Idx) {
+    assert(Idx < size() && "Template parameter index out-of-range");
+    return begin()[Idx];
+  }
+
+  const NamedDecl* getParam(unsigned Idx) const {
+    assert(Idx < size() && "Template parameter index out-of-range");
+    return begin()[Idx];
+  }
+
+  /// \brief Returns the minimum number of arguments needed to form a
+  /// template specialization.
+  ///
+  /// This may be fewer than the number of template parameters, if some of
+  /// the parameters have default arguments or if there is a parameter pack.
+  unsigned getMinRequiredArguments() const;
+
+  /// \brief Get the depth of this template parameter list in the set of
+  /// template parameter lists.
+  ///
+  /// The first template parameter list in a declaration will have depth 0,
+  /// the second template parameter list will have depth 1, etc.
+  unsigned getDepth() const;
+
+  /// \brief Determine whether this template parameter list contains an
+  /// unexpanded parameter pack.
+  bool containsUnexpandedParameterPack() const {
+    return ContainsUnexpandedParameterPack;
+  }
+
+  SourceLocation getTemplateLoc() const { return TemplateLoc; }
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(TemplateLoc, RAngleLoc);
+  }
+};
+
+/// \brief Stores a list of template parameters for a TemplateDecl and its
+/// derived classes. Suitable for creating on the stack.
+template<size_t N>
+class FixedSizeTemplateParameterList : public TemplateParameterList {
+  NamedDecl *Params[N];
+
+public:
+  FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
+                                 SourceLocation LAngleLoc,
+                                 NamedDecl **Params, SourceLocation RAngleLoc) :
+    TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
+  }
+};
+
+/// \brief A template argument list.
+class TemplateArgumentList {
+  /// \brief The template argument list.
+  ///
+  /// The integer value will be non-zero to indicate that this
+  /// template argument list does own the pointer.
+  llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
+
+  /// \brief The number of template arguments in this template
+  /// argument list.
+  unsigned NumArguments;
+
+  TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
+  void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
+
+  TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
+                       bool Owned)
+    : Arguments(Args, Owned), NumArguments(NumArgs) { }
+
+public:
+  /// \brief Type used to indicate that the template argument list itself is a
+  /// stack object. It does not own its template arguments.
+  enum OnStackType { OnStack };
+
+  /// \brief Create a new template argument list that copies the given set of
+  /// template arguments.
+  static TemplateArgumentList *CreateCopy(ASTContext &Context,
+                                          const TemplateArgument *Args,
+                                          unsigned NumArgs);
+
+  /// \brief Construct a new, temporary template argument list on the stack.
+  ///
+  /// The template argument list does not own the template arguments
+  /// provided.
+  explicit TemplateArgumentList(OnStackType,
+                                const TemplateArgument *Args, unsigned NumArgs)
+    : Arguments(Args, false), NumArguments(NumArgs) { }
+
+  /// \brief Produces a shallow copy of the given template argument list.
+  ///
+  /// This operation assumes that the input argument list outlives it.
+  /// This takes the list as a pointer to avoid looking like a copy
+  /// constructor, since this really really isn't safe to use that
+  /// way.
+  explicit TemplateArgumentList(const TemplateArgumentList *Other)
+    : Arguments(Other->data(), false), NumArguments(Other->size()) { }
+
+  /// \brief Retrieve the template argument at a given index.
+  const TemplateArgument &get(unsigned Idx) const {
+    assert(Idx < NumArguments && "Invalid template argument index");
+    return data()[Idx];
+  }
+
+  /// \brief Retrieve the template argument at a given index.
+  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+  /// \brief Produce this as an array ref.
+  ArrayRef<TemplateArgument> asArray() const {
+    return ArrayRef<TemplateArgument>(data(), size());
+  }
+
+  /// \brief Retrieve the number of template arguments in this
+  /// template argument list.
+  unsigned size() const { return NumArguments; }
+
+  /// \brief Retrieve a pointer to the template argument list.
+  const TemplateArgument *data() const {
+    return Arguments.getPointer();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Templates
+//===----------------------------------------------------------------------===//
+
+/// \brief The base class of all kinds of template declarations (e.g.,
+/// class, function, etc.).
+///
+/// The TemplateDecl class stores the list of template parameters and a
+/// reference to the templated scoped declaration: the underlying AST node.
+class TemplateDecl : public NamedDecl {
+  void anchor() override;
+protected:
+  // This is probably never used.
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+      TemplateParams(nullptr) {}
+
+  // Construct a template decl with the given name and parameters.
+  // Used when there is not templated element (tt-params, alias?).
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name, TemplateParameterList *Params)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+      TemplateParams(Params) {}
+
+  // Construct a template decl with name, parameters, and templated element.
+  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
+               DeclarationName Name, TemplateParameterList *Params,
+               NamedDecl *Decl)
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
+      TemplateParams(Params) { }
+public:
+  /// Get the list of template parameters
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  /// Get the underlying, templated declaration.
+  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstTemplate && K <= lastTemplate;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(TemplateParams->getTemplateLoc(),
+                       TemplatedDecl->getSourceRange().getEnd());
+  }
+
+protected:
+  NamedDecl *TemplatedDecl;
+  TemplateParameterList* TemplateParams;
+
+public:
+  /// \brief Initialize the underlying templated declaration and
+  /// template parameters.
+  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
+    assert(!TemplatedDecl && "TemplatedDecl already set!");
+    assert(!TemplateParams && "TemplateParams already set!");
+    TemplatedDecl = templatedDecl;
+    TemplateParams = templateParams;
+  }
+};
+
+/// \brief Provides information about a function template specialization,
+/// which is a FunctionDecl that has been explicitly specialization or
+/// instantiated from a function template.
+class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
+  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
+                                     FunctionTemplateDecl *Template,
+                                     TemplateSpecializationKind TSK,
+                                     const TemplateArgumentList *TemplateArgs,
+                       const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
+                                     SourceLocation POI)
+  : Function(FD),
+    Template(Template, TSK - 1),
+    TemplateArguments(TemplateArgs),
+    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
+    PointOfInstantiation(POI) { }
+
+public:
+  static FunctionTemplateSpecializationInfo *
+  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
+         TemplateSpecializationKind TSK,
+         const TemplateArgumentList *TemplateArgs,
+         const TemplateArgumentListInfo *TemplateArgsAsWritten,
+         SourceLocation POI);
+
+  /// \brief The function template specialization that this structure
+  /// describes.
+  FunctionDecl *Function;
+
+  /// \brief The function template from which this function template
+  /// specialization was generated.
+  ///
+  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
+  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
+
+  /// \brief The template arguments used to produce the function template
+  /// specialization from the function template.
+  const TemplateArgumentList *TemplateArguments;
+
+  /// \brief The template arguments as written in the sources, if provided.
+  const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
+
+  /// \brief The point at which this function template specialization was
+  /// first instantiated.
+  SourceLocation PointOfInstantiation;
+
+  /// \brief Retrieve the template from which this function was specialized.
+  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
+
+  /// \brief Determine what kind of template specialization this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const {
+    return (TemplateSpecializationKind)(Template.getInt() + 1);
+  }
+
+  bool isExplicitSpecialization() const {
+    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+  }
+
+  /// \brief True if this declaration is an explicit specialization,
+  /// explicit instantiation declaration, or explicit instantiation
+  /// definition.
+  bool isExplicitInstantiationOrSpecialization() const {
+    switch (getTemplateSpecializationKind()) {
+    case TSK_ExplicitSpecialization:
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+      return true;
+
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      return false;
+    }
+    llvm_unreachable("bad template specialization kind");
+  }
+
+  /// \brief Set the template specialization kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+    assert(TSK != TSK_Undeclared &&
+         "Cannot encode TSK_Undeclared for a function template specialization");
+    Template.setInt(TSK - 1);
+  }
+
+  /// \brief Retrieve the first point of instantiation of this function
+  /// template specialization.
+  ///
+  /// The point of instantiation may be an invalid source location if this
+  /// function has yet to be instantiated.
+  SourceLocation getPointOfInstantiation() const {
+    return PointOfInstantiation;
+  }
+
+  /// \brief Set the (first) point of instantiation of this function template
+  /// specialization.
+  void setPointOfInstantiation(SourceLocation POI) {
+    PointOfInstantiation = POI;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, TemplateArguments->asArray(),
+            Function->getASTContext());
+  }
+
+  static void
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
+      TemplateArgs[Arg].Profile(ID, Context);
+  }
+};
+
+/// \brief Provides information a specialization of a member of a class
+/// template, which may be a member function, static data member,
+/// member class or member enumeration.
+class MemberSpecializationInfo {
+  // The member declaration from which this member was instantiated, and the
+  // manner in which the instantiation occurred (in the lower two bits).
+  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
+
+  // The point at which this member was first instantiated.
+  SourceLocation PointOfInstantiation;
+
+public:
+  explicit
+  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
+                           SourceLocation POI = SourceLocation())
+    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
+    assert(TSK != TSK_Undeclared &&
+           "Cannot encode undeclared template specializations for members");
+  }
+
+  /// \brief Retrieve the member declaration from which this member was
+  /// instantiated.
+  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
+
+  /// \brief Determine what kind of template specialization this is.
+  TemplateSpecializationKind getTemplateSpecializationKind() const {
+    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
+  }
+
+  bool isExplicitSpecialization() const {
+    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
+  }
+
+  /// \brief Set the template specialization kind.
+  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+    assert(TSK != TSK_Undeclared &&
+           "Cannot encode undeclared template specializations for members");
+    MemberAndTSK.setInt(TSK - 1);
+  }
+
+  /// \brief Retrieve the first point of instantiation of this member.
+  /// If the point of instantiation is an invalid location, then this member
+  /// has not yet been instantiated.
+  SourceLocation getPointOfInstantiation() const {
+    return PointOfInstantiation;
+  }
+
+  /// \brief Set the first point of instantiation.
+  void setPointOfInstantiation(SourceLocation POI) {
+    PointOfInstantiation = POI;
+  }
+};
+
+/// \brief Provides information about a dependent function-template
+/// specialization declaration.
+///
+/// Since explicit function template specialization and instantiation
+/// declarations can only appear in namespace scope, and you can only
+/// specialize a member of a fully-specialized class, the only way to
+/// get one of these is in a friend declaration like the following:
+///
+/// \code
+///   template \<class T> void foo(T);
+///   template \<class T> class A {
+///     friend void foo<>(T);
+///   };
+/// \endcode
+class DependentFunctionTemplateSpecializationInfo {
+  struct CA {
+    /// The number of potential template candidates.
+    unsigned NumTemplates;
+
+    /// The number of template arguments.
+    unsigned NumArgs;
+  };
+
+  union {
+    // Force sizeof to be a multiple of sizeof(void*) so that the
+    // trailing data is aligned.
+    void *Aligner;
+    struct CA d;
+  };
+
+  /// The locations of the left and right angle brackets.
+  SourceRange AngleLocs;
+
+  FunctionTemplateDecl * const *getTemplates() const {
+    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
+  }
+
+public:
+  DependentFunctionTemplateSpecializationInfo(
+                                 const UnresolvedSetImpl &Templates,
+                                 const TemplateArgumentListInfo &TemplateArgs);
+
+  /// \brief Returns the number of function templates that this might
+  /// be a specialization of.
+  unsigned getNumTemplates() const {
+    return d.NumTemplates;
+  }
+
+  /// \brief Returns the i'th template candidate.
+  FunctionTemplateDecl *getTemplate(unsigned I) const {
+    assert(I < getNumTemplates() && "template index out of range");
+    return getTemplates()[I];
+  }
+
+  /// \brief Returns the explicit template arguments that were given.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc*>(
+                                            &getTemplates()[getNumTemplates()]);
+  }
+
+  /// \brief Returns the number of explicit template arguments that were given.
+  unsigned getNumTemplateArgs() const {
+    return d.NumArgs;
+  }
+
+  /// \brief Returns the nth template argument.
+  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
+    assert(I < getNumTemplateArgs() && "template arg index out of range");
+    return getTemplateArgs()[I];
+  }
+
+  SourceLocation getLAngleLoc() const {
+    return AngleLocs.getBegin();
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return AngleLocs.getEnd();
+  }
+};
+
+/// Declaration of a redeclarable template.
+class RedeclarableTemplateDecl : public TemplateDecl, 
+                                 public Redeclarable<RedeclarableTemplateDecl> 
+{
+  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
+  RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  RedeclarableTemplateDecl *getPreviousDeclImpl() override {
+    return getPreviousDecl();
+  }
+  RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
+    return getMostRecentDecl();
+  }
+
+protected:
+  template <typename EntryType> struct SpecEntryTraits {
+    typedef EntryType DeclType;
+
+    static DeclType *getMostRecentDecl(EntryType *D) {
+      return D->getMostRecentDecl();
+    }
+  };
+
+  template <typename EntryType,
+            typename _SETraits = SpecEntryTraits<EntryType>,
+            typename _DeclType = typename _SETraits::DeclType>
+  class SpecIterator : public std::iterator<std::forward_iterator_tag,
+                                            _DeclType*, ptrdiff_t,
+                                            _DeclType*, _DeclType*> {
+    typedef _SETraits SETraits;
+    typedef _DeclType DeclType;
+
+    typedef typename llvm::FoldingSetVector<EntryType>::iterator
+      SetIteratorType;
+
+    SetIteratorType SetIter;
+
+  public:
+    SpecIterator() : SetIter() {}
+    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
+
+    DeclType *operator*() const {
+      return SETraits::getMostRecentDecl(&*SetIter);
+    }
+    DeclType *operator->() const { return **this; }
+
+    SpecIterator &operator++() { ++SetIter; return *this; }
+    SpecIterator operator++(int) {
+      SpecIterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator==(SpecIterator Other) const {
+      return SetIter == Other.SetIter;
+    }
+    bool operator!=(SpecIterator Other) const {
+      return SetIter != Other.SetIter;
+    }
+  };
+
+  template <typename EntryType>
+  static SpecIterator<EntryType>
+  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
+    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
+  }
+
+  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
+  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
+                         ArrayRef<TemplateArgument> Args, void *&InsertPos);
+
+  struct CommonBase {
+    CommonBase() : InstantiatedFromMember(nullptr, false) { }
+
+    /// \brief The template from which this was most
+    /// directly instantiated (or null).
+    ///
+    /// The boolean value indicates whether this template
+    /// was explicitly specialized.
+    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
+      InstantiatedFromMember;
+  };
+
+  /// \brief Pointer to the common data shared by all declarations of this
+  /// template.
+  mutable CommonBase *Common;
+  
+  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
+  /// the same template. Calling this routine may implicitly allocate memory
+  /// for the common pointer.
+  CommonBase *getCommonPtr() const;
+
+  virtual CommonBase *newCommon(ASTContext &C) const = 0;
+
+  // Construct a template decl with name, parameters, and templated element.
+  RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                           SourceLocation L, DeclarationName Name,
+                           TemplateParameterList *Params, NamedDecl *Decl)
+      : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
+        Common() {}
+
+public:
+  template <class decl_type> friend class RedeclarableTemplate;
+
+  /// \brief Retrieves the canonical declaration of this template.
+  RedeclarableTemplateDecl *getCanonicalDecl() override {
+    return getFirstDecl();
+  }
+  const RedeclarableTemplateDecl *getCanonicalDecl() const {
+    return getFirstDecl();
+  }
+
+  /// \brief Determines whether this template was a specialization of a
+  /// member template.
+  ///
+  /// In the following example, the function template \c X<int>::f and the
+  /// member template \c X<int>::Inner are member specializations.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> void f(T, U);
+  ///   template<typename U> struct Inner;
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// void X<int>::f(int, T);
+  /// template<> template<typename T>
+  /// struct X<int>::Inner { /* ... */ };
+  /// \endcode
+  bool isMemberSpecialization() const {
+    return getCommonPtr()->InstantiatedFromMember.getInt();
+  }
+
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    getCommonPtr()->InstantiatedFromMember.setInt(true);
+  }
+
+  /// \brief Retrieve the member template from which this template was
+  /// instantiated, or NULL if this template was not instantiated from a 
+  /// member template.
+  ///
+  /// A template is instantiated from a member template when the member 
+  /// template itself is part of a class template (or member thereof). For
+  /// example, given
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> void f(T, U);
+  /// };
+  ///
+  /// void test(X<int> x) {
+  ///   x.f(1, 'a');
+  /// };
+  /// \endcode
+  ///
+  /// \c X<int>::f is a FunctionTemplateDecl that describes the function
+  /// template
+  ///
+  /// \code
+  /// template<typename U> void X<int>::f(int, U);
+  /// \endcode
+  ///
+  /// which was itself created during the instantiation of \c X<int>. Calling
+  /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
+  /// retrieve the FunctionTemplateDecl for the original template \c f within
+  /// the class template \c X<T>, i.e.,
+  ///
+  /// \code
+  /// template<typename T>
+  /// template<typename U>
+  /// void X<T>::f(T, U);
+  /// \endcode
+  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
+    return getCommonPtr()->InstantiatedFromMember.getPointer();
+  }
+
+  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
+    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
+  }
+
+  typedef redeclarable_base::redecl_range redecl_range;
+  typedef redeclarable_base::redecl_iterator redecl_iterator;
+  using redeclarable_base::redecls_begin;
+  using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
+  using redeclarable_base::getPreviousDecl;
+  using redeclarable_base::getMostRecentDecl;
+  using redeclarable_base::isFirstDecl;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
+  }
+
+  friend class ASTReader;
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+template <> struct RedeclarableTemplateDecl::
+SpecEntryTraits<FunctionTemplateSpecializationInfo> {
+  typedef FunctionDecl DeclType;
+
+  static DeclType *
+  getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
+    return I->Function->getMostRecentDecl();
+  }
+};
+
+/// Declaration of a template function.
+class FunctionTemplateDecl : public RedeclarableTemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+
+protected:
+  /// \brief Data that is common to all of the declarations of a given
+  /// function template.
+  struct Common : CommonBase {
+    Common() : InjectedArgs(), LazySpecializations() { }
+
+    /// \brief The function template specializations for this function
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
+
+    /// \brief The set of "injected" template arguments used within this
+    /// function template.
+    ///
+    /// This pointer refers to the template arguments (there are as
+    /// many template arguments as template parameaters) for the function
+    /// template, and is allocated lazily, since most function templates do not
+    /// require the use of this information.
+    TemplateArgument *InjectedArgs;
+
+    /// \brief If non-null, points to an array of specializations known only
+    /// by their external declaration IDs.
+    ///
+    /// The first value in the array is the number of of specializations
+    /// that follow.
+    uint32_t *LazySpecializations;
+  };
+
+  FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                       DeclarationName Name, TemplateParameterList *Params,
+                       NamedDecl *Decl)
+      : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
+
+  CommonBase *newCommon(ASTContext &C) const override;
+
+  Common *getCommonPtr() const {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
+
+  friend class FunctionDecl;
+
+  /// \brief Load any lazily-loaded specializations from the external source.
+  void LoadLazySpecializations() const;
+
+  /// \brief Retrieve the set of function template specializations of this
+  /// function template.
+  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
+  getSpecializations() const;
+
+  /// \brief Add a specialization of this function template.
+  ///
+  /// \param InsertPos Insert position in the FoldingSetVector, must have been
+  ///        retrieved by an earlier call to findSpecialization().
+  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
+                         void *InsertPos);
+
+public:
+  /// Get the underlying function declaration of the template.
+  FunctionDecl *getTemplatedDecl() const {
+    return static_cast<FunctionDecl*>(TemplatedDecl);
+  }
+
+  /// Returns whether this template declaration defines the primary
+  /// pattern.
+  bool isThisDeclarationADefinition() const {
+    return getTemplatedDecl()->isThisDeclarationADefinition();
+  }
+
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
+                                   void *&InsertPos);
+
+  FunctionTemplateDecl *getCanonicalDecl() override {
+    return cast<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+  const FunctionTemplateDecl *getCanonicalDecl() const {
+    return cast<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  FunctionTemplateDecl *getPreviousDecl() {
+    return cast_or_null<FunctionTemplateDecl>(
+             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  const FunctionTemplateDecl *getPreviousDecl() const {
+    return cast_or_null<FunctionTemplateDecl>(
+       static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+  }
+
+  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return cast_or_null<FunctionTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
+  }
+
+  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
+
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
+  spec_iterator spec_begin() const {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() const {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
+  /// \brief Retrieve the "injected" template arguments that correspond to the
+  /// template parameters of this function template.
+  ///
+  /// Although the C++ standard has no notion of the "injected" template
+  /// arguments for a function template, the notion is convenient when
+  /// we need to perform substitutions inside the definition of a function
+  /// template.
+  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+
+  /// \brief Create a function template node.
+  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation L,
+                                      DeclarationName Name,
+                                      TemplateParameterList *Params,
+                                      NamedDecl *Decl);
+
+  /// \brief Create an empty function template node.
+  static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == FunctionTemplate; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+//===----------------------------------------------------------------------===//
+// Kinds of Template Parameters
+//===----------------------------------------------------------------------===//
+
+/// \brief Defines the position of a template parameter within a template
+/// parameter list.
+///
+/// Because template parameter can be listed
+/// sequentially for out-of-line template members, each template parameter is
+/// given a Depth - the nesting of template parameter scopes - and a Position -
+/// the occurrence within the parameter list.
+/// This class is inheritedly privately by different kinds of template
+/// parameters and is not part of the Decl hierarchy. Just a facility.
+class TemplateParmPosition {
+  TemplateParmPosition() LLVM_DELETED_FUNCTION;
+
+protected:
+  TemplateParmPosition(unsigned D, unsigned P)
+    : Depth(D), Position(P)
+  { }
+
+  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
+  // position? Maybe?
+  unsigned Depth;
+  unsigned Position;
+
+public:
+  /// Get the nesting depth of the template parameter.
+  unsigned getDepth() const { return Depth; }
+  void setDepth(unsigned D) { Depth = D; }
+
+  /// Get the position of the template parameter within its parameter list.
+  unsigned getPosition() const { return Position; }
+  void setPosition(unsigned P) { Position = P; }
+
+  /// Get the index of the template parameter within its parameter list.
+  unsigned getIndex() const { return Position; }
+};
+
+/// \brief Declaration of a template type parameter.
+///
+/// For example, "T" in
+/// \code
+/// template<typename T> class vector;
+/// \endcode
+class TemplateTypeParmDecl : public TypeDecl {
+  /// \brief Whether this template type parameter was declaration with
+  /// the 'typename' keyword.
+  ///
+  /// If false, it was declared with the 'class' keyword.
+  bool Typename : 1;
+
+  /// \brief Whether this template type parameter inherited its
+  /// default argument.
+  bool InheritedDefault : 1;
+
+  /// \brief The default template argument, if any.
+  TypeSourceInfo *DefaultArgument;
+
+  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
+                       SourceLocation IdLoc, IdentifierInfo *Id,
+                       bool Typename)
+    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
+      InheritedDefault(false), DefaultArgument() { }
+
+  /// Sema creates these on the stack during auto type deduction.
+  friend class Sema;
+
+public:
+  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
+                                      SourceLocation KeyLoc,
+                                      SourceLocation NameLoc,
+                                      unsigned D, unsigned P,
+                                      IdentifierInfo *Id, bool Typename,
+                                      bool ParameterPack);
+  static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, 
+                                                  unsigned ID);
+
+  /// \brief Whether this template type parameter was declared with
+  /// the 'typename' keyword.
+  ///
+  /// If not, it was declared with the 'class' keyword.
+  bool wasDeclaredWithTypename() const { return Typename; }
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
+
+  /// \brief Retrieve the default argument, if any.
+  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
+
+  /// \brief Retrieves the default argument's source information, if any.
+  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+  /// \brief Retrieves the location of the default argument declaration.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const { return InheritedDefault; }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
+    DefaultArgument = DefArg;
+    InheritedDefault = Inherited;
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgument = nullptr;
+    InheritedDefault = false;
+  }
+
+  /// \brief Set whether this template type parameter was declared with
+  /// the 'typename' or 'class' keyword.
+  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
+
+  /// \brief Retrieve the depth of the template parameter.
+  unsigned getDepth() const;
+
+  /// \brief Retrieve the index of the template parameter.
+  unsigned getIndex() const;
+
+  /// \brief Returns whether this is a parameter pack.
+  bool isParameterPack() const;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
+};
+
+/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
+/// e.g., "Size" in
+/// @code
+/// template<int Size> class array { };
+/// @endcode
+class NonTypeTemplateParmDecl
+  : public DeclaratorDecl, protected TemplateParmPosition {
+  /// \brief The default template argument, if any, and whether or not
+  /// it was inherited.
+  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
+
+  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
+  // down here to save memory.
+
+  /// \brief Whether this non-type template parameter is a parameter pack.
+  bool ParameterPack;
+
+  /// \brief Whether this non-type template parameter is an "expanded"
+  /// parameter pack, meaning that its type is a pack expansion and we
+  /// already know the set of types that expansion expands to.
+  bool ExpandedParameterPack;
+
+  /// \brief The number of types in an expanded parameter pack.
+  unsigned NumExpandedTypes;
+
+  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
+                          SourceLocation IdLoc, unsigned D, unsigned P,
+                          IdentifierInfo *Id, QualType T,
+                          bool ParameterPack, TypeSourceInfo *TInfo)
+    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
+      TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
+      ParameterPack(ParameterPack), ExpandedParameterPack(false),
+      NumExpandedTypes(0)
+  { }
+
+  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
+                          SourceLocation IdLoc, unsigned D, unsigned P,
+                          IdentifierInfo *Id, QualType T,
+                          TypeSourceInfo *TInfo,
+                          const QualType *ExpandedTypes,
+                          unsigned NumExpandedTypes,
+                          TypeSourceInfo **ExpandedTInfos);
+
+  friend class ASTDeclReader;
+
+public:
+  static NonTypeTemplateParmDecl *
+  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
+
+  static NonTypeTemplateParmDecl *
+  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+         QualType T, TypeSourceInfo *TInfo,
+         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
+         TypeSourceInfo **ExpandedTInfos);
+
+  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, 
+                                                     unsigned ID);
+  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, 
+                                                     unsigned ID,
+                                                     unsigned NumExpandedTypes);
+    
+  using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::setDepth;
+  using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::setPosition;
+  using TemplateParmPosition::getIndex;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const {
+    return DefaultArgumentAndInherited.getPointer() != nullptr;
+  }
+
+  /// \brief Retrieve the default argument, if any.
+  Expr *getDefaultArgument() const {
+    return DefaultArgumentAndInherited.getPointer();
+  }
+
+  /// \brief Retrieve the location of the default argument, if any.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const {
+    return DefaultArgumentAndInherited.getInt();
+  }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(Expr *DefArg, bool Inherited) {
+    DefaultArgumentAndInherited.setPointer(DefArg);
+    DefaultArgumentAndInherited.setInt(Inherited);
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgumentAndInherited.setPointer(nullptr);
+    DefaultArgumentAndInherited.setInt(false);
+  }
+
+  /// \brief Whether this parameter is a non-type template parameter pack.
+  ///
+  /// If the parameter is a parameter pack, the type may be a
+  /// \c PackExpansionType. In the following example, the \c Dims parameter
+  /// is a parameter pack (whose type is 'unsigned').
+  ///
+  /// \code
+  /// template<typename T, unsigned ...Dims> struct multi_array;
+  /// \endcode
+  bool isParameterPack() const { return ParameterPack; }
+
+  /// \brief Whether this parameter pack is a pack expansion.
+  ///
+  /// A non-type template parameter pack is a pack expansion if its type
+  /// contains an unexpanded parameter pack. In this case, we will have
+  /// built a PackExpansionType wrapping the type.
+  bool isPackExpansion() const {
+    return ParameterPack && getType()->getAs<PackExpansionType>();
+  }
+
+  /// \brief Whether this parameter is a non-type template parameter pack
+  /// that has a known list of different types at different positions.
+  ///
+  /// A parameter pack is an expanded parameter pack when the original
+  /// parameter pack's type was itself a pack expansion, and that expansion
+  /// has already been expanded. For example, given:
+  ///
+  /// \code
+  /// template<typename ...Types>
+  /// struct X {
+  ///   template<Types ...Values>
+  ///   struct Y { /* ... */ };
+  /// };
+  /// \endcode
+  ///
+  /// The parameter pack \c Values has a \c PackExpansionType as its type,
+  /// which expands \c Types. When \c Types is supplied with template arguments
+  /// by instantiating \c X, the instantiation of \c Values becomes an
+  /// expanded parameter pack. For example, instantiating
+  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
+  /// pack with expansion types \c int and \c unsigned int.
+  ///
+  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
+  /// return the expansion types.
+  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
+
+  /// \brief Retrieves the number of expansion types in an expanded parameter
+  /// pack.
+  unsigned getNumExpansionTypes() const {
+    assert(ExpandedParameterPack && "Not an expansion parameter pack");
+    return NumExpandedTypes;
+  }
+
+  /// \brief Retrieve a particular expansion type within an expanded parameter
+  /// pack.
+  QualType getExpansionType(unsigned I) const {
+    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
+    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
+    return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
+  }
+
+  /// \brief Retrieve a particular expansion type source info within an
+  /// expanded parameter pack.
+  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
+    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
+    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
+    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
+};
+
+/// TemplateTemplateParmDecl - Declares a template template parameter,
+/// e.g., "T" in
+/// @code
+/// template <template <typename> class T> class container { };
+/// @endcode
+/// A template template parameter is a TemplateDecl because it defines the
+/// name of a template and the template parameters allowable for substitution.
+class TemplateTemplateParmDecl : public TemplateDecl, 
+                                 protected TemplateParmPosition 
+{
+  void anchor() override;
+
+  /// DefaultArgument - The default template argument, if any.
+  TemplateArgumentLoc DefaultArgument;
+  /// Whether or not the default argument was inherited.
+  bool DefaultArgumentWasInherited;
+
+  /// \brief Whether this parameter is a parameter pack.
+  bool ParameterPack;
+
+  /// \brief Whether this template template parameter is an "expanded"
+  /// parameter pack, meaning that it is a pack expansion and we
+  /// already know the set of template parameters that expansion expands to.
+  bool ExpandedParameterPack;
+
+  /// \brief The number of parameters in an expanded parameter pack.
+  unsigned NumExpandedParams;
+
+  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
+                           unsigned D, unsigned P, bool ParameterPack,
+                           IdentifierInfo *Id, TemplateParameterList *Params)
+    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
+      TemplateParmPosition(D, P), DefaultArgument(),
+      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
+      ExpandedParameterPack(false), NumExpandedParams(0)
+    { }
+
+  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
+                           unsigned D, unsigned P,
+                           IdentifierInfo *Id, TemplateParameterList *Params,
+                           unsigned NumExpansions,
+                           TemplateParameterList * const *Expansions);
+
+public:
+  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
+                                          SourceLocation L, unsigned D,
+                                          unsigned P, bool ParameterPack,
+                                          IdentifierInfo *Id,
+                                          TemplateParameterList *Params);
+  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
+                                          SourceLocation L, unsigned D,
+                                          unsigned P,
+                                          IdentifierInfo *Id,
+                                          TemplateParameterList *Params,
+                                 ArrayRef<TemplateParameterList *> Expansions);
+
+  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
+                                                      unsigned ID);
+  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
+                                                      unsigned ID,
+                                                      unsigned NumExpansions);
+  
+  using TemplateParmPosition::getDepth;
+  using TemplateParmPosition::getPosition;
+  using TemplateParmPosition::getIndex;
+
+  /// \brief Whether this template template parameter is a template
+  /// parameter pack.
+  ///
+  /// \code
+  /// template<template <class T> ...MetaFunctions> struct Apply;
+  /// \endcode
+  bool isParameterPack() const { return ParameterPack; }
+
+  /// \brief Whether this parameter pack is a pack expansion.
+  ///
+  /// A template template parameter pack is a pack expansion if its template
+  /// parameter list contains an unexpanded parameter pack.
+  bool isPackExpansion() const {
+    return ParameterPack &&
+           getTemplateParameters()->containsUnexpandedParameterPack();
+  }
+
+  /// \brief Whether this parameter is a template template parameter pack that
+  /// has a known list of different template parameter lists at different
+  /// positions.
+  ///
+  /// A parameter pack is an expanded parameter pack when the original parameter
+  /// pack's template parameter list was itself a pack expansion, and that
+  /// expansion has already been expanded. For exampe, given:
+  ///
+  /// \code
+  /// template<typename...Types> struct Outer {
+  ///   template<template<Types> class...Templates> struct Inner;
+  /// };
+  /// \endcode
+  ///
+  /// The parameter pack \c Templates is a pack expansion, which expands the
+  /// pack \c Types. When \c Types is supplied with template arguments by
+  /// instantiating \c Outer, the instantiation of \c Templates is an expanded
+  /// parameter pack.
+  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
+
+  /// \brief Retrieves the number of expansion template parameters in
+  /// an expanded parameter pack.
+  unsigned getNumExpansionTemplateParameters() const {
+    assert(ExpandedParameterPack && "Not an expansion parameter pack");
+    return NumExpandedParams;
+  }
+
+  /// \brief Retrieve a particular expansion type within an expanded parameter
+  /// pack.
+  TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
+    assert(I < NumExpandedParams && "Out-of-range expansion type index");
+    return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
+  }
+
+  /// \brief Determine whether this template parameter has a default
+  /// argument.
+  bool hasDefaultArgument() const {
+    return !DefaultArgument.getArgument().isNull();
+  }
+
+  /// \brief Retrieve the default argument, if any.
+  const TemplateArgumentLoc &getDefaultArgument() const {
+    return DefaultArgument;
+  }
+
+  /// \brief Retrieve the location of the default argument, if any.
+  SourceLocation getDefaultArgumentLoc() const;
+
+  /// \brief Determines whether the default argument was inherited
+  /// from a previous declaration of this template.
+  bool defaultArgumentWasInherited() const {
+    return DefaultArgumentWasInherited;
+  }
+
+  /// \brief Set the default argument for this template parameter, and
+  /// whether that default argument was inherited from another
+  /// declaration.
+  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
+    DefaultArgument = DefArg;
+    DefaultArgumentWasInherited = Inherited;
+  }
+
+  /// \brief Removes the default argument of this template parameter.
+  void removeDefaultArgument() {
+    DefaultArgument = TemplateArgumentLoc();
+    DefaultArgumentWasInherited = false;
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    SourceLocation End = getLocation();
+    if (hasDefaultArgument() && !defaultArgumentWasInherited())
+      End = getDefaultArgument().getSourceRange().getEnd();
+    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Represents a class template specialization, which refers to
+/// a class template with a given set of template arguments.
+///
+/// Class template specializations represent both explicit
+/// specialization of class templates, as in the example below, and
+/// implicit instantiations of class templates.
+///
+/// \code
+/// template<typename T> class array;
+///
+/// template<>
+/// class array<bool> { }; // class template specialization array<bool>
+/// \endcode
+class ClassTemplateSpecializationDecl
+  : public CXXRecordDecl, public llvm::FoldingSetNode {
+
+  /// \brief Structure that stores information about a class template
+  /// specialization that was instantiated from a class template partial
+  /// specialization.
+  struct SpecializedPartialSpecialization {
+    /// \brief The class template partial specialization from which this
+    /// class template specialization was instantiated.
+    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
+
+    /// \brief The template argument list deduced for the class template
+    /// partial specialization itself.
+    const TemplateArgumentList *TemplateArgs;
+  };
+
+  /// \brief The template that this specialization specializes
+  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
+    SpecializedTemplate;
+
+  /// \brief Further info for explicit template specialization/instantiation.
+  struct ExplicitSpecializationInfo {
+    /// \brief The type-as-written.
+    TypeSourceInfo *TypeAsWritten;
+    /// \brief The location of the extern keyword.
+    SourceLocation ExternLoc;
+    /// \brief The location of the template keyword.
+    SourceLocation TemplateKeywordLoc;
+
+    ExplicitSpecializationInfo()
+      : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
+  };
+
+  /// \brief Further info for explicit template specialization/instantiation.
+  /// Does not apply to implicit specializations.
+  ExplicitSpecializationInfo *ExplicitInfo;
+
+  /// \brief The template arguments used to describe this specialization.
+  const TemplateArgumentList *TemplateArgs;
+
+  /// \brief The point where this template was instantiated (if any)
+  SourceLocation PointOfInstantiation;
+
+  /// \brief The kind of specialization this declaration refers to.
+  /// Really a value of type TemplateSpecializationKind.
+  unsigned SpecializationKind : 3;
+
+protected:
+  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
+                                  DeclContext *DC, SourceLocation StartLoc,
+                                  SourceLocation IdLoc,
+                                  ClassTemplateDecl *SpecializedTemplate,
+                                  const TemplateArgument *Args,
+                                  unsigned NumArgs,
+                                  ClassTemplateSpecializationDecl *PrevDecl);
+
+  explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
+
+public:
+  static ClassTemplateSpecializationDecl *
+  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
+         SourceLocation StartLoc, SourceLocation IdLoc,
+         ClassTemplateDecl *SpecializedTemplate,
+         const TemplateArgument *Args,
+         unsigned NumArgs,
+         ClassTemplateSpecializationDecl *PrevDecl);
+  static ClassTemplateSpecializationDecl *
+  CreateDeserialized(ASTContext &C, unsigned ID);
+
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
+
+  // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
+  // different "most recent" declaration from this function for the same
+  // declaration, because we don't override getMostRecentDeclImpl(). But
+  // it's not clear that we should override that, because the most recent
+  // declaration as a CXXRecordDecl sometimes is the injected-class-name.
+  ClassTemplateSpecializationDecl *getMostRecentDecl() {
+    CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
+                              this)->getMostRecentDecl();
+    while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
+      // FIXME: Does injected class name need to be in the redeclarations chain?
+      assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
+      Recent = Recent->getPreviousDecl();
+    }
+    return cast<ClassTemplateSpecializationDecl>(Recent);
+  }
+
+  /// \brief Retrieve the template that this specialization specializes.
+  ClassTemplateDecl *getSpecializedTemplate() const;
+
+  /// \brief Retrieve the template arguments of the class template
+  /// specialization.
+  const TemplateArgumentList &getTemplateArgs() const {
+    return *TemplateArgs;
+  }
+
+  /// \brief Determine the kind of specialization that this
+  /// declaration represents.
+  TemplateSpecializationKind getSpecializationKind() const {
+    return static_cast<TemplateSpecializationKind>(SpecializationKind);
+  }
+
+  bool isExplicitSpecialization() const {
+    return getSpecializationKind() == TSK_ExplicitSpecialization;
+  }
+
+  /// \brief True if this declaration is an explicit specialization,
+  /// explicit instantiation declaration, or explicit instantiation
+  /// definition.
+  bool isExplicitInstantiationOrSpecialization() const {
+    switch (getTemplateSpecializationKind()) {
+    case TSK_ExplicitSpecialization:
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+      return true;
+
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      return false;
+    }
+    llvm_unreachable("bad template specialization kind");
+  }
+
+  void setSpecializationKind(TemplateSpecializationKind TSK) {
+    SpecializationKind = TSK;
+  }
+
+  /// \brief Get the point of instantiation (if any), or null if none.
+  SourceLocation getPointOfInstantiation() const {
+    return PointOfInstantiation;
+  }
+
+  void setPointOfInstantiation(SourceLocation Loc) {
+    assert(Loc.isValid() && "point of instantiation must be valid!");
+    PointOfInstantiation = Loc;
+  }
+
+  /// \brief If this class template specialization is an instantiation of
+  /// a template (rather than an explicit specialization), return the
+  /// class template or class template partial specialization from which it
+  /// was instantiated.
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *>
+  getInstantiatedFrom() const {
+    if (!isTemplateInstantiation(getSpecializationKind()))
+      return llvm::PointerUnion<ClassTemplateDecl *,
+                                ClassTemplatePartialSpecializationDecl *>();
+
+    return getSpecializedTemplateOrPartial();
+  }
+
+  /// \brief Retrieve the class template or class template partial
+  /// specialization which was specialized by this.
+  llvm::PointerUnion<ClassTemplateDecl *,
+                     ClassTemplatePartialSpecializationDecl *>
+  getSpecializedTemplateOrPartial() const {
+    if (SpecializedPartialSpecialization *PartialSpec
+          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+      return PartialSpec->PartialSpecialization;
+
+    return SpecializedTemplate.get<ClassTemplateDecl*>();
+  }
+
+  /// \brief Retrieve the set of template arguments that should be used
+  /// to instantiate members of the class template or class template partial
+  /// specialization from which this class template specialization was
+  /// instantiated.
+  ///
+  /// \returns For a class template specialization instantiated from the primary
+  /// template, this function will return the same template arguments as
+  /// getTemplateArgs(). For a class template specialization instantiated from
+  /// a class template partial specialization, this function will return the
+  /// deduced template arguments for the class template partial specialization
+  /// itself.
+  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+    if (SpecializedPartialSpecialization *PartialSpec
+        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
+      return *PartialSpec->TemplateArgs;
+
+    return getTemplateArgs();
+  }
+
+  /// \brief Note that this class template specialization is actually an
+  /// instantiation of the given class template partial specialization whose
+  /// template arguments have been deduced.
+  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
+                          const TemplateArgumentList *TemplateArgs) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+           "Already set to a class template partial specialization!");
+    SpecializedPartialSpecialization *PS
+      = new (getASTContext()) SpecializedPartialSpecialization();
+    PS->PartialSpecialization = PartialSpec;
+    PS->TemplateArgs = TemplateArgs;
+    SpecializedTemplate = PS;
+  }
+
+  /// \brief Note that this class template specialization is an instantiation
+  /// of the given class template.
+  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+           "Previously set to a class template partial specialization!");
+    SpecializedTemplate = TemplDecl;
+  }
+
+  /// \brief Sets the type of this specialization as it was written by
+  /// the user. This will be a class template specialization type.
+  void setTypeAsWritten(TypeSourceInfo *T) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->TypeAsWritten = T;
+  }
+  /// \brief Gets the type of this specialization as it was written by
+  /// the user, if it was so written.
+  TypeSourceInfo *getTypeAsWritten() const {
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
+  }
+
+  /// \brief Gets the location of the extern keyword, if present.
+  SourceLocation getExternLoc() const {
+    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+  }
+  /// \brief Sets the location of the extern keyword.
+  void setExternLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->ExternLoc = Loc;
+  }
+
+  /// \brief Sets the location of the template keyword.
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->TemplateKeywordLoc = Loc;
+  }
+  /// \brief Gets the location of the template keyword, if present.
+  SourceLocation getTemplateKeywordLoc() const {
+    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
+  }
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
+  }
+
+  static void
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
+      TemplateArgs[Arg].Profile(ID, Context);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstClassTemplateSpecialization &&
+           K <= lastClassTemplateSpecialization;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+class ClassTemplatePartialSpecializationDecl
+  : public ClassTemplateSpecializationDecl {
+  void anchor() override;
+
+  /// \brief The list of template parameters
+  TemplateParameterList* TemplateParams;
+
+  /// \brief The source info for the template arguments as written.
+  /// FIXME: redundant with TypeAsWritten?
+  const ASTTemplateArgumentListInfo *ArgsAsWritten;
+
+  /// \brief The class template partial specialization from which this
+  /// class template partial specialization was instantiated.
+  ///
+  /// The boolean value will be true to indicate that this class template
+  /// partial specialization was specialized at this level.
+  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
+      InstantiatedFromMember;
+
+  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
+                                         DeclContext *DC,
+                                         SourceLocation StartLoc,
+                                         SourceLocation IdLoc,
+                                         TemplateParameterList *Params,
+                                         ClassTemplateDecl *SpecializedTemplate,
+                                         const TemplateArgument *Args,
+                                         unsigned NumArgs,
+                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
+                               ClassTemplatePartialSpecializationDecl *PrevDecl);
+
+  ClassTemplatePartialSpecializationDecl(ASTContext &C)
+    : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
+      TemplateParams(nullptr), ArgsAsWritten(nullptr),
+      InstantiatedFromMember(nullptr, false) {}
+
+public:
+  static ClassTemplatePartialSpecializationDecl *
+  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
+         SourceLocation StartLoc, SourceLocation IdLoc,
+         TemplateParameterList *Params,
+         ClassTemplateDecl *SpecializedTemplate,
+         const TemplateArgument *Args,
+         unsigned NumArgs,
+         const TemplateArgumentListInfo &ArgInfos,
+         QualType CanonInjectedType,
+         ClassTemplatePartialSpecializationDecl *PrevDecl);
+
+  static ClassTemplatePartialSpecializationDecl *
+  CreateDeserialized(ASTContext &C, unsigned ID);
+
+  ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
+    return cast<ClassTemplatePartialSpecializationDecl>(
+             static_cast<ClassTemplateSpecializationDecl *>(
+               this)->getMostRecentDecl());
+  }
+
+  /// Get the list of template parameters
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  /// Get the template arguments as written.
+  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+    return ArgsAsWritten;
+  }
+
+  /// \brief Retrieve the member class template partial specialization from
+  /// which this particular class template partial specialization was
+  /// instantiated.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct Outer {
+  ///   template<typename U> struct Inner;
+  ///   template<typename U> struct Inner<U*> { }; // #1
+  /// };
+  ///
+  /// Outer<float>::Inner<int*> ii;
+  /// \endcode
+  ///
+  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
+  /// end up instantiating the partial specialization
+  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
+  /// template partial specialization \c Outer<T>::Inner<U*>. Given
+  /// \c Outer<float>::Inner<U*>, this function would return
+  /// \c Outer<T>::Inner<U*>.
+  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
+    ClassTemplatePartialSpecializationDecl *First =
+        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+    return First->InstantiatedFromMember.getPointer();
+  }
+
+  void setInstantiatedFromMember(
+                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
+    ClassTemplatePartialSpecializationDecl *First =
+        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+    First->InstantiatedFromMember.setPointer(PartialSpec);
+  }
+
+  /// \brief Determines whether this class template partial specialization
+  /// template was a specialization of a member partial specialization.
+  ///
+  /// In the following example, the member template partial specialization
+  /// \c X<int>::Inner<T*> is a member specialization.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> struct Inner;
+  ///   template<typename U> struct Inner<U*>;
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// struct X<int>::Inner<T*> { /* ... */ };
+  /// \endcode
+  bool isMemberSpecialization() {
+    ClassTemplatePartialSpecializationDecl *First =
+        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+    return First->InstantiatedFromMember.getInt();
+  }
+
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    ClassTemplatePartialSpecializationDecl *First =
+        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
+    assert(First->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    return First->InstantiatedFromMember.setInt(true);
+  }
+
+  /// Retrieves the injected specialization type for this partial
+  /// specialization.  This is not the same as the type-decl-type for
+  /// this partial specialization, which is an InjectedClassNameType.
+  QualType getInjectedSpecializationType() const {
+    assert(getTypeForDecl() && "partial specialization has no type set!");
+    return cast<InjectedClassNameType>(getTypeForDecl())
+             ->getInjectedSpecializationType();
+  }
+
+  // FIXME: Add Profile support!
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == ClassTemplatePartialSpecialization;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// Declaration of a class template.
+class ClassTemplateDecl : public RedeclarableTemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+
+protected:
+  /// \brief Data that is common to all of the declarations of a given
+  /// class template.
+  struct Common : CommonBase {
+    Common() : LazySpecializations() { }
+
+    /// \brief The class template specializations for this class
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
+
+    /// \brief The class template partial specializations for this class
+    /// template.
+    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
+      PartialSpecializations;
+
+    /// \brief The injected-class-name type for this class template.
+    QualType InjectedClassNameType;
+
+    /// \brief If non-null, points to an array of specializations (including
+    /// partial specializations) known only by their external declaration IDs.
+    ///
+    /// The first value in the array is the number of of specializations/
+    /// partial specializations that follow.
+    uint32_t *LazySpecializations;
+  };
+
+  /// \brief Load any lazily-loaded specializations from the external source.
+  void LoadLazySpecializations() const;
+
+  /// \brief Retrieve the set of specializations of this class template.
+  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
+  getSpecializations() const;
+
+  /// \brief Retrieve the set of partial specializations of this class
+  /// template.
+  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
+  getPartialSpecializations();
+
+  ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                    DeclarationName Name, TemplateParameterList *Params,
+                    NamedDecl *Decl)
+      : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
+
+  CommonBase *newCommon(ASTContext &C) const override;
+
+  Common *getCommonPtr() const {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
+
+public:
+  /// \brief Get the underlying class declarations of the template.
+  CXXRecordDecl *getTemplatedDecl() const {
+    return static_cast<CXXRecordDecl *>(TemplatedDecl);
+  }
+
+  /// \brief Returns whether this template declaration defines the primary
+  /// class pattern.
+  bool isThisDeclarationADefinition() const {
+    return getTemplatedDecl()->isThisDeclarationADefinition();
+  }
+
+  /// \brief Create a class template node.
+  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                   SourceLocation L,
+                                   DeclarationName Name,
+                                   TemplateParameterList *Params,
+                                   NamedDecl *Decl,
+                                   ClassTemplateDecl *PrevDecl);
+
+  /// \brief Create an empty class template node.
+  static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  ClassTemplateSpecializationDecl *
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
+
+  /// \brief Insert the specified specialization knowing that it is not already
+  /// in. InsertPos must be obtained from findSpecialization.
+  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
+
+  ClassTemplateDecl *getCanonicalDecl() override {
+    return cast<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+  const ClassTemplateDecl *getCanonicalDecl() const {
+    return cast<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this class template, or
+  /// NULL if no such declaration exists.
+  ClassTemplateDecl *getPreviousDecl() {
+    return cast_or_null<ClassTemplateDecl>(
+             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this class template, or
+  /// NULL if no such declaration exists.
+  const ClassTemplateDecl *getPreviousDecl() const {
+    return cast_or_null<ClassTemplateDecl>(
+             static_cast<const RedeclarableTemplateDecl *>(
+               this)->getPreviousDecl());
+  }
+
+  ClassTemplateDecl *getMostRecentDecl() {
+    return cast<ClassTemplateDecl>(
+        static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
+  }
+  const ClassTemplateDecl *getMostRecentDecl() const {
+    return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
+  }
+
+  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return cast_or_null<ClassTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
+  }
+
+  /// \brief Return the partial specialization with the provided arguments if it
+  /// exists, otherwise return the insertion point.
+  ClassTemplatePartialSpecializationDecl *
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
+
+  /// \brief Insert the specified partial specialization knowing that it is not
+  /// already in. InsertPos must be obtained from findPartialSpecialization.
+  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
+                                void *InsertPos);
+
+  /// \brief Retrieve the partial specializations as an ordered list.
+  void getPartialSpecializations(
+          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+
+  /// \brief Find a class template partial specialization with the given
+  /// type T.
+  ///
+  /// \param T a dependent type that names a specialization of this class
+  /// template.
+  ///
+  /// \returns the class template partial specialization that exactly matches
+  /// the type \p T, or NULL if no such partial specialization exists.
+  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
+
+  /// \brief Find a class template partial specialization which was instantiated
+  /// from the given member partial specialization.
+  ///
+  /// \param D a member class template partial specialization.
+  ///
+  /// \returns the class template partial specialization which was instantiated
+  /// from the given member partial specialization, or NULL if no such partial
+  /// specialization exists.
+  ClassTemplatePartialSpecializationDecl *
+  findPartialSpecInstantiatedFromMember(
+                                     ClassTemplatePartialSpecializationDecl *D);
+
+  /// \brief Retrieve the template specialization type of the
+  /// injected-class-name for this class template.
+  ///
+  /// The injected-class-name for a class template \c X is \c
+  /// X<template-args>, where \c template-args is formed from the
+  /// template arguments that correspond to the template parameters of
+  /// \c X. For example:
+  ///
+  /// \code
+  /// template<typename T, int N>
+  /// struct array {
+  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
+  /// };
+  /// \endcode
+  QualType getInjectedClassNameSpecialization();
+
+  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
+
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
+
+  spec_iterator spec_begin() const {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() const {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == ClassTemplate; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Declaration of a friend template.
+///
+/// For example:
+/// \code
+/// template \<typename T> class A {
+///   friend class MyVector<T>; // not a friend template
+///   template \<typename U> friend class B; // not a friend template
+///   template \<typename U> friend class Foo<T>::Nested; // friend template
+/// };
+/// \endcode
+///
+/// \note This class is not currently in use.  All of the above
+/// will yield a FriendDecl, not a FriendTemplateDecl.
+class FriendTemplateDecl : public Decl {
+  virtual void anchor();
+public:
+  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
+
+private:
+  // The number of template parameters;  always non-zero.
+  unsigned NumParams;
+
+  // The parameter list.
+  TemplateParameterList **Params;
+
+  // The declaration that's a friend of this class.
+  FriendUnion Friend;
+
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
+
+
+  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
+                     unsigned NParams,
+                     TemplateParameterList **Params,
+                     FriendUnion Friend,
+                     SourceLocation FriendLoc)
+    : Decl(Decl::FriendTemplate, DC, Loc),
+      NumParams(NParams),
+      Params(Params),
+      Friend(Friend),
+      FriendLoc(FriendLoc)
+  {}
+
+  FriendTemplateDecl(EmptyShell Empty)
+    : Decl(Decl::FriendTemplate, Empty),
+      NumParams(0),
+      Params(nullptr)
+  {}
+
+public:
+  static FriendTemplateDecl *Create(ASTContext &Context,
+                                    DeclContext *DC, SourceLocation Loc,
+                                    unsigned NParams,
+                                    TemplateParameterList **Params,
+                                    FriendUnion Friend,
+                                    SourceLocation FriendLoc);
+
+  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// If this friend declaration names a templated type (or
+  /// a dependent member type of a templated type), return that
+  /// type;  otherwise return null.
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
+  }
+
+  /// If this friend declaration names a templated function (or
+  /// a member function of a templated type), return that type;
+  /// otherwise return null.
+  NamedDecl *getFriendDecl() const {
+    return Friend.dyn_cast<NamedDecl*>();
+  }
+
+  /// \brief Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
+  }
+
+  TemplateParameterList *getTemplateParameterList(unsigned i) const {
+    assert(i <= NumParams);
+    return Params[i];
+  }
+
+  unsigned getNumTemplateParameters() const {
+    return NumParams;
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
+
+  friend class ASTDeclReader;
+};
+
+/// \brief Declaration of an alias template.
+///
+/// For example:
+/// \code
+/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
+/// \endcode
+class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+
+protected:
+  typedef CommonBase Common;
+
+  TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                        DeclarationName Name, TemplateParameterList *Params,
+                        NamedDecl *Decl)
+      : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
+
+  CommonBase *newCommon(ASTContext &C) const override;
+
+  Common *getCommonPtr() {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
+
+public:
+  /// Get the underlying function declaration of the template.
+  TypeAliasDecl *getTemplatedDecl() const {
+    return static_cast<TypeAliasDecl*>(TemplatedDecl);
+  }
+
+
+  TypeAliasTemplateDecl *getCanonicalDecl() override {
+    return cast<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+  const TypeAliasTemplateDecl *getCanonicalDecl() const {
+    return cast<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  TypeAliasTemplateDecl *getPreviousDecl() {
+    return cast_or_null<TypeAliasTemplateDecl>(
+             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this function template, or
+  /// NULL if no such declaration exists.
+  const TypeAliasTemplateDecl *getPreviousDecl() const {
+    return cast_or_null<TypeAliasTemplateDecl>(
+             static_cast<const RedeclarableTemplateDecl *>(
+               this)->getPreviousDecl());
+  }
+
+  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return cast_or_null<TypeAliasTemplateDecl>(
+             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
+  }
+
+
+  /// \brief Create a function template node.
+  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                       SourceLocation L,
+                                       DeclarationName Name,
+                                       TemplateParameterList *Params,
+                                       NamedDecl *Decl);
+
+  /// \brief Create an empty alias template node.
+  static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Declaration of a function specialization at template class scope.
+///
+/// This is a non-standard extension needed to support MSVC.
+///
+/// For example:
+/// \code
+/// template <class T>
+/// class A {
+///    template <class U> void foo(U a) { }
+///    template<> void foo(int a) { }
+/// }
+/// \endcode
+///
+/// "template<> foo(int a)" will be saved in Specialization as a normal
+/// CXXMethodDecl. Then during an instantiation of class A, it will be
+/// transformed into an actual function specialization.
+class ClassScopeFunctionSpecializationDecl : public Decl {
+  virtual void anchor();
+
+  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
+                                       CXXMethodDecl *FD, bool Args,
+                                       TemplateArgumentListInfo TemplArgs)
+    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
+      Specialization(FD), HasExplicitTemplateArgs(Args),
+      TemplateArgs(TemplArgs) {}
+
+  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
+    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
+
+  CXXMethodDecl *Specialization;
+  bool HasExplicitTemplateArgs;
+  TemplateArgumentListInfo TemplateArgs;
+
+public:
+  CXXMethodDecl *getSpecialization() const { return Specialization; }
+  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
+
+  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
+                                                      DeclContext *DC,
+                                                      SourceLocation Loc,
+                                                      CXXMethodDecl *FD,
+                                                   bool HasExplicitTemplateArgs,
+                                        TemplateArgumentListInfo TemplateArgs) {
+    return new (C, DC) ClassScopeFunctionSpecializationDecl(
+        DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
+  }
+
+  static ClassScopeFunctionSpecializationDecl *
+  CreateDeserialized(ASTContext &Context, unsigned ID);
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == Decl::ClassScopeFunctionSpecialization;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// Implementation of inline functions that require the template declarations
+inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
+  : Function(FTD) { }
+
+/// \brief Represents a variable template specialization, which refers to
+/// a variable template with a given set of template arguments.
+///
+/// Variable template specializations represent both explicit
+/// specializations of variable templates, as in the example below, and
+/// implicit instantiations of variable templates.
+///
+/// \code
+/// template<typename T> constexpr T pi = T(3.1415926535897932385);
+///
+/// template<>
+/// constexpr float pi<float>; // variable template specialization pi<float>
+/// \endcode
+class VarTemplateSpecializationDecl : public VarDecl,
+                                      public llvm::FoldingSetNode {
+
+  /// \brief Structure that stores information about a variable template
+  /// specialization that was instantiated from a variable template partial
+  /// specialization.
+  struct SpecializedPartialSpecialization {
+    /// \brief The variable template partial specialization from which this
+    /// variable template specialization was instantiated.
+    VarTemplatePartialSpecializationDecl *PartialSpecialization;
+
+    /// \brief The template argument list deduced for the variable template
+    /// partial specialization itself.
+    const TemplateArgumentList *TemplateArgs;
+  };
+
+  /// \brief The template that this specialization specializes.
+  llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
+  SpecializedTemplate;
+
+  /// \brief Further info for explicit template specialization/instantiation.
+  struct ExplicitSpecializationInfo {
+    /// \brief The type-as-written.
+    TypeSourceInfo *TypeAsWritten;
+    /// \brief The location of the extern keyword.
+    SourceLocation ExternLoc;
+    /// \brief The location of the template keyword.
+    SourceLocation TemplateKeywordLoc;
+
+    ExplicitSpecializationInfo()
+        : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
+  };
+
+  /// \brief Further info for explicit template specialization/instantiation.
+  /// Does not apply to implicit specializations.
+  ExplicitSpecializationInfo *ExplicitInfo;
+
+  /// \brief The template arguments used to describe this specialization.
+  const TemplateArgumentList *TemplateArgs;
+  TemplateArgumentListInfo TemplateArgsInfo;
+
+  /// \brief The point where this template was instantiated (if any).
+  SourceLocation PointOfInstantiation;
+
+  /// \brief The kind of specialization this declaration refers to.
+  /// Really a value of type TemplateSpecializationKind.
+  unsigned SpecializationKind : 3;
+
+protected:
+  VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
+                                SourceLocation StartLoc, SourceLocation IdLoc,
+                                VarTemplateDecl *SpecializedTemplate,
+                                QualType T, TypeSourceInfo *TInfo,
+                                StorageClass S, const TemplateArgument *Args,
+                                unsigned NumArgs);
+
+  explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
+
+public:
+  static VarTemplateSpecializationDecl *
+  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+         SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
+         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
+         unsigned NumArgs);
+  static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
+                                                           unsigned ID);
+
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
+
+  VarTemplateSpecializationDecl *getMostRecentDecl() {
+    VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
+    return cast<VarTemplateSpecializationDecl>(Recent);
+  }
+
+  /// \brief Retrieve the template that this specialization specializes.
+  VarTemplateDecl *getSpecializedTemplate() const;
+
+  /// \brief Retrieve the template arguments of the variable template
+  /// specialization.
+  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
+
+  // TODO: Always set this when creating the new specialization?
+  void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
+
+  const TemplateArgumentListInfo &getTemplateArgsInfo() const {
+    return TemplateArgsInfo;
+  }
+
+  /// \brief Determine the kind of specialization that this
+  /// declaration represents.
+  TemplateSpecializationKind getSpecializationKind() const {
+    return static_cast<TemplateSpecializationKind>(SpecializationKind);
+  }
+
+  bool isExplicitSpecialization() const {
+    return getSpecializationKind() == TSK_ExplicitSpecialization;
+  }
+
+  /// \brief True if this declaration is an explicit specialization,
+  /// explicit instantiation declaration, or explicit instantiation
+  /// definition.
+  bool isExplicitInstantiationOrSpecialization() const {
+    switch (getTemplateSpecializationKind()) {
+    case TSK_ExplicitSpecialization:
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+      return true;
+
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      return false;
+    }
+    llvm_unreachable("bad template specialization kind");
+  }
+
+  void setSpecializationKind(TemplateSpecializationKind TSK) {
+    SpecializationKind = TSK;
+  }
+
+  /// \brief Get the point of instantiation (if any), or null if none.
+  SourceLocation getPointOfInstantiation() const {
+    return PointOfInstantiation;
+  }
+
+  void setPointOfInstantiation(SourceLocation Loc) {
+    assert(Loc.isValid() && "point of instantiation must be valid!");
+    PointOfInstantiation = Loc;
+  }
+
+  /// \brief If this variable template specialization is an instantiation of
+  /// a template (rather than an explicit specialization), return the
+  /// variable template or variable template partial specialization from which
+  /// it was instantiated.
+  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
+  getInstantiatedFrom() const {
+    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
+        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
+        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+      return llvm::PointerUnion<VarTemplateDecl *,
+                                VarTemplatePartialSpecializationDecl *>();
+
+    if (SpecializedPartialSpecialization *PartialSpec =
+            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+      return PartialSpec->PartialSpecialization;
+
+    return SpecializedTemplate.get<VarTemplateDecl *>();
+  }
+
+  /// \brief Retrieve the variable template or variable template partial
+  /// specialization which was specialized by this.
+  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
+  getSpecializedTemplateOrPartial() const {
+    if (SpecializedPartialSpecialization *PartialSpec =
+            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+      return PartialSpec->PartialSpecialization;
+
+    return SpecializedTemplate.get<VarTemplateDecl *>();
+  }
+
+  /// \brief Retrieve the set of template arguments that should be used
+  /// to instantiate the initializer of the variable template or variable
+  /// template partial specialization from which this variable template
+  /// specialization was instantiated.
+  ///
+  /// \returns For a variable template specialization instantiated from the
+  /// primary template, this function will return the same template arguments
+  /// as getTemplateArgs(). For a variable template specialization instantiated
+  /// from a variable template partial specialization, this function will the
+  /// return deduced template arguments for the variable template partial
+  /// specialization itself.
+  const TemplateArgumentList &getTemplateInstantiationArgs() const {
+    if (SpecializedPartialSpecialization *PartialSpec =
+            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+      return *PartialSpec->TemplateArgs;
+
+    return getTemplateArgs();
+  }
+
+  /// \brief Note that this variable template specialization is actually an
+  /// instantiation of the given variable template partial specialization whose
+  /// template arguments have been deduced.
+  void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
+                          const TemplateArgumentList *TemplateArgs) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+           "Already set to a variable template partial specialization!");
+    SpecializedPartialSpecialization *PS =
+        new (getASTContext()) SpecializedPartialSpecialization();
+    PS->PartialSpecialization = PartialSpec;
+    PS->TemplateArgs = TemplateArgs;
+    SpecializedTemplate = PS;
+  }
+
+  /// \brief Note that this variable template specialization is an instantiation
+  /// of the given variable template.
+  void setInstantiationOf(VarTemplateDecl *TemplDecl) {
+    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+           "Previously set to a variable template partial specialization!");
+    SpecializedTemplate = TemplDecl;
+  }
+
+  /// \brief Sets the type of this specialization as it was written by
+  /// the user.
+  void setTypeAsWritten(TypeSourceInfo *T) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->TypeAsWritten = T;
+  }
+  /// \brief Gets the type of this specialization as it was written by
+  /// the user, if it was so written.
+  TypeSourceInfo *getTypeAsWritten() const {
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
+  }
+
+  /// \brief Gets the location of the extern keyword, if present.
+  SourceLocation getExternLoc() const {
+    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+  }
+  /// \brief Sets the location of the extern keyword.
+  void setExternLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->ExternLoc = Loc;
+  }
+
+  /// \brief Sets the location of the template keyword.
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    if (!ExplicitInfo)
+      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+    ExplicitInfo->TemplateKeywordLoc = Loc;
+  }
+  /// \brief Gets the location of the template keyword, if present.
+  SourceLocation getTemplateKeywordLoc() const {
+    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      ArrayRef<TemplateArgument> TemplateArgs,
+                      ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
+      TemplateArgs[Arg].Profile(ID, Context);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K >= firstVarTemplateSpecialization &&
+           K <= lastVarTemplateSpecialization;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+class VarTemplatePartialSpecializationDecl
+    : public VarTemplateSpecializationDecl {
+  void anchor() override;
+
+  /// \brief The list of template parameters
+  TemplateParameterList *TemplateParams;
+
+  /// \brief The source info for the template arguments as written.
+  /// FIXME: redundant with TypeAsWritten?
+  const ASTTemplateArgumentListInfo *ArgsAsWritten;
+
+  /// \brief The variable template partial specialization from which this
+  /// variable template partial specialization was instantiated.
+  ///
+  /// The boolean value will be true to indicate that this variable template
+  /// partial specialization was specialized at this level.
+  llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
+  InstantiatedFromMember;
+
+  VarTemplatePartialSpecializationDecl(
+      ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+      SourceLocation IdLoc, TemplateParameterList *Params,
+      VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
+      StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
+      const ASTTemplateArgumentListInfo *ArgInfos);
+
+  VarTemplatePartialSpecializationDecl(ASTContext &Context)
+    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
+      TemplateParams(nullptr), ArgsAsWritten(nullptr),
+      InstantiatedFromMember(nullptr, false) {}
+
+public:
+  static VarTemplatePartialSpecializationDecl *
+  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+         SourceLocation IdLoc, TemplateParameterList *Params,
+         VarTemplateDecl *SpecializedTemplate, QualType T,
+         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
+         unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
+
+  static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
+                                                                  unsigned ID);
+
+  VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
+    return cast<VarTemplatePartialSpecializationDecl>(
+             static_cast<VarTemplateSpecializationDecl *>(
+               this)->getMostRecentDecl());
+  }
+
+  /// Get the list of template parameters
+  TemplateParameterList *getTemplateParameters() const {
+    return TemplateParams;
+  }
+
+  /// Get the template arguments as written.
+  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+    return ArgsAsWritten;
+  }
+
+  /// \brief Retrieve the member variable template partial specialization from
+  /// which this particular variable template partial specialization was
+  /// instantiated.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct Outer {
+  ///   template<typename U> U Inner;
+  ///   template<typename U> U* Inner<U*> = (U*)(0); // #1
+  /// };
+  ///
+  /// template int* Outer<float>::Inner<int*>;
+  /// \endcode
+  ///
+  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
+  /// end up instantiating the partial specialization
+  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
+  /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
+  /// \c Outer<float>::Inner<U*>, this function would return
+  /// \c Outer<T>::Inner<U*>.
+  VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
+    VarTemplatePartialSpecializationDecl *First =
+        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+    return First->InstantiatedFromMember.getPointer();
+  }
+
+  void
+  setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
+    VarTemplatePartialSpecializationDecl *First =
+        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+    First->InstantiatedFromMember.setPointer(PartialSpec);
+  }
+
+  /// \brief Determines whether this variable template partial specialization
+  /// was a specialization of a member partial specialization.
+  ///
+  /// In the following example, the member template partial specialization
+  /// \c X<int>::Inner<T*> is a member specialization.
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<typename U> U Inner;
+  ///   template<typename U> U* Inner<U*> = (U*)(0);
+  /// };
+  ///
+  /// template<> template<typename T>
+  /// U* X<int>::Inner<T*> = (T*)(0) + 1;
+  /// \endcode
+  bool isMemberSpecialization() {
+    VarTemplatePartialSpecializationDecl *First =
+        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+    return First->InstantiatedFromMember.getInt();
+  }
+
+  /// \brief Note that this member template is a specialization.
+  void setMemberSpecialization() {
+    VarTemplatePartialSpecializationDecl *First =
+        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+    assert(First->InstantiatedFromMember.getPointer() &&
+           "Only member templates can be member template specializations");
+    return First->InstantiatedFromMember.setInt(true);
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == VarTemplatePartialSpecialization;
+  }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// Declaration of a variable template.
+class VarTemplateDecl : public RedeclarableTemplateDecl {
+  static void DeallocateCommon(void *Ptr);
+
+protected:
+  /// \brief Data that is common to all of the declarations of a given
+  /// variable template.
+  struct Common : CommonBase {
+    Common() : LazySpecializations() {}
+
+    /// \brief The variable template specializations for this variable
+    /// template, including explicit specializations and instantiations.
+    llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
+
+    /// \brief The variable template partial specializations for this variable
+    /// template.
+    llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
+    PartialSpecializations;
+
+    /// \brief If non-null, points to an array of specializations (including
+    /// partial specializations) known ownly by their external declaration IDs.
+    ///
+    /// The first value in the array is the number of of specializations/
+    /// partial specializations that follow.
+    uint32_t *LazySpecializations;
+  };
+
+  /// \brief Load any lazily-loaded specializations from the external source.
+  void LoadLazySpecializations() const;
+
+  /// \brief Retrieve the set of specializations of this variable template.
+  llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
+  getSpecializations() const;
+
+  /// \brief Retrieve the set of partial specializations of this class
+  /// template.
+  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
+  getPartialSpecializations();
+
+  VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                  DeclarationName Name, TemplateParameterList *Params,
+                  NamedDecl *Decl)
+      : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
+
+  CommonBase *newCommon(ASTContext &C) const override;
+
+  Common *getCommonPtr() const {
+    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+  }
+
+public:
+  /// \brief Get the underlying variable declarations of the template.
+  VarDecl *getTemplatedDecl() const {
+    return static_cast<VarDecl *>(TemplatedDecl);
+  }
+
+  /// \brief Returns whether this template declaration defines the primary
+  /// variable pattern.
+  bool isThisDeclarationADefinition() const {
+    return getTemplatedDecl()->isThisDeclarationADefinition();
+  }
+
+  VarTemplateDecl *getDefinition();
+
+  /// \brief Create a variable template node.
+  static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+                                 SourceLocation L, DeclarationName Name,
+                                 TemplateParameterList *Params,
+                                 VarDecl *Decl);
+
+  /// \brief Create an empty variable template node.
+  static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  /// \brief Return the specialization with the provided arguments if it exists,
+  /// otherwise return the insertion point.
+  VarTemplateSpecializationDecl *
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
+
+  /// \brief Insert the specified specialization knowing that it is not already
+  /// in. InsertPos must be obtained from findSpecialization.
+  void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
+
+  VarTemplateDecl *getCanonicalDecl() override {
+    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+  const VarTemplateDecl *getCanonicalDecl() const {
+    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this variable template, or
+  /// NULL if no such declaration exists.
+  VarTemplateDecl *getPreviousDecl() {
+    return cast_or_null<VarTemplateDecl>(
+        static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+  }
+
+  /// \brief Retrieve the previous declaration of this variable template, or
+  /// NULL if no such declaration exists.
+  const VarTemplateDecl *getPreviousDecl() const {
+    return cast_or_null<VarTemplateDecl>(
+            static_cast<const RedeclarableTemplateDecl *>(
+              this)->getPreviousDecl());
+  }
+
+  VarTemplateDecl *getInstantiatedFromMemberTemplate() {
+    return cast_or_null<VarTemplateDecl>(
+        RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
+  }
+
+  /// \brief Return the partial specialization with the provided arguments if it
+  /// exists, otherwise return the insertion point.
+  VarTemplatePartialSpecializationDecl *
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
+
+  /// \brief Insert the specified partial specialization knowing that it is not
+  /// already in. InsertPos must be obtained from findPartialSpecialization.
+  void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
+                                void *InsertPos);
+
+  /// \brief Retrieve the partial specializations as an ordered list.
+  void getPartialSpecializations(
+      SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
+
+  /// \brief Find a variable template partial specialization which was
+  /// instantiated
+  /// from the given member partial specialization.
+  ///
+  /// \param D a member variable template partial specialization.
+  ///
+  /// \returns the variable template partial specialization which was
+  /// instantiated
+  /// from the given member partial specialization, or NULL if no such partial
+  /// specialization exists.
+  VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
+      VarTemplatePartialSpecializationDecl *D);
+
+  typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
+
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
+
+  spec_iterator spec_begin() const {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() const {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
+  // Implement isa/cast/dyncast support
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == VarTemplate; }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+} /* end of namespace clang */
+
+#endif
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
new file mode 100644
index 0000000..4eaae35
--- /dev/null
+++ b/include/clang/AST/DeclVisitor.h
@@ -0,0 +1,79 @@
+//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- 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 DeclVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLVISITOR_H
+#define LLVM_CLANG_AST_DECLVISITOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+namespace declvisitor {
+
+template <typename T> struct make_ptr       { typedef       T *type; };
+template <typename T> struct make_const_ptr { typedef const T *type; };
+
+/// \brief A simple visitor class that helps create declaration visitors.
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+class Base {
+public:
+
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME, CLASS) \
+  return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D))
+
+  RetTy Visit(PTR(Decl) D) {
+    switch (D->getKind()) {
+#define DECL(DERIVED, BASE) \
+      case Decl::DERIVED: DISPATCH(DERIVED##Decl, DERIVED##Decl);
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
+    }
+    llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
+  }
+
+  // If the implementation chooses not to implement a certain visit
+  // method, fall back to the parent.
+#define DECL(DERIVED, BASE) \
+  RetTy Visit##DERIVED##Decl(PTR(DERIVED##Decl) D) { DISPATCH(BASE, BASE); }
+#include "clang/AST/DeclNodes.inc"
+
+  RetTy VisitDecl(PTR(Decl) D) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+} // end namespace declvisitor
+
+/// \brief A simple visitor class that helps create declaration visitors.
+///
+/// This class does not preserve constness of Decl pointers (see also
+/// ConstDeclVisitor).
+template<typename ImplClass, typename RetTy=void>
+class DeclVisitor
+ : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
+
+/// \brief A simple visitor class that helps create declaration visitors.
+///
+/// This class preserves constness of Decl pointers (see also DeclVisitor).
+template<typename ImplClass, typename RetTy=void>
+class ConstDeclVisitor
+ : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {};
+
+}  // end namespace clang
+
+#endif // LLVM_CLANG_AST_DECLVISITOR_H
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
new file mode 100644
index 0000000..3076b30
--- /dev/null
+++ b/include/clang/AST/DeclarationName.h
@@ -0,0 +1,597 @@
+//===-- DeclarationName.h - Representation of declaration names -*- 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 DeclarationName and DeclarationNameTable classes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
+#define LLVM_CLANG_AST_DECLARATIONNAME_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+  class ASTContext;
+  class CXXLiteralOperatorIdName;
+  class CXXOperatorIdName;
+  class CXXSpecialName;
+  class DeclarationNameExtra;
+  class IdentifierInfo;
+  class MultiKeywordSelector;
+  enum OverloadedOperatorKind : int;
+  class QualType;
+  class Type;
+  class TypeSourceInfo;
+  class UsingDirectiveDecl;
+
+  template <typename> class CanQual;
+  typedef CanQual<Type> CanQualType;
+
+/// DeclarationName - The name of a declaration. In the common case,
+/// this just stores an IdentifierInfo pointer to a normal
+/// name. However, it also provides encodings for Objective-C
+/// selectors (optimizing zero- and one-argument selectors, which make
+/// up 78% percent of all selectors in Cocoa.h) and special C++ names
+/// for constructors, destructors, and conversion functions.
+class DeclarationName {
+public:
+  /// NameKind - The kind of name this object contains.
+  enum NameKind {
+    Identifier,
+    ObjCZeroArgSelector,
+    ObjCOneArgSelector,
+    ObjCMultiArgSelector,
+    CXXConstructorName,
+    CXXDestructorName,
+    CXXConversionFunctionName,
+    CXXOperatorName,
+    CXXLiteralOperatorName,
+    CXXUsingDirective
+  };
+
+private:
+  /// StoredNameKind - The kind of name that is actually stored in the
+  /// upper bits of the Ptr field. This is only used internally.
+  ///
+  /// Note: The entries here are synchronized with the entries in Selector,
+  /// for efficient translation between the two.
+  enum StoredNameKind {
+    StoredIdentifier = 0,
+    StoredObjCZeroArgSelector = 0x01,
+    StoredObjCOneArgSelector = 0x02,
+    StoredDeclarationNameExtra = 0x03,
+    PtrMask = 0x03
+  };
+
+  /// Ptr - The lowest two bits are used to express what kind of name
+  /// we're actually storing, using the values of NameKind. Depending
+  /// on the kind of name this is, the upper bits of Ptr may have one
+  /// of several different meanings:
+  ///
+  ///   StoredIdentifier - The name is a normal identifier, and Ptr is
+  ///   a normal IdentifierInfo pointer.
+  ///
+  ///   StoredObjCZeroArgSelector - The name is an Objective-C
+  ///   selector with zero arguments, and Ptr is an IdentifierInfo
+  ///   pointer pointing to the selector name.
+  ///
+  ///   StoredObjCOneArgSelector - The name is an Objective-C selector
+  ///   with one argument, and Ptr is an IdentifierInfo pointer
+  ///   pointing to the selector name.
+  ///
+  ///   StoredDeclarationNameExtra - Ptr is actually a pointer to a
+  ///   DeclarationNameExtra structure, whose first value will tell us
+  ///   whether this is an Objective-C selector, C++ operator-id name,
+  ///   or special C++ name.
+  uintptr_t Ptr;
+
+  /// getStoredNameKind - Return the kind of object that is stored in
+  /// Ptr.
+  StoredNameKind getStoredNameKind() const {
+    return static_cast<StoredNameKind>(Ptr & PtrMask);
+  }
+
+  /// getExtra - Get the "extra" information associated with this
+  /// multi-argument selector or C++ special name.
+  DeclarationNameExtra *getExtra() const {
+    assert(getStoredNameKind() == StoredDeclarationNameExtra &&
+           "Declaration name does not store an Extra structure");
+    return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
+  }
+
+  /// getAsCXXSpecialName - If the stored pointer is actually a
+  /// CXXSpecialName, returns a pointer to it. Otherwise, returns
+  /// a NULL pointer.
+  CXXSpecialName *getAsCXXSpecialName() const {
+    NameKind Kind = getNameKind();
+    if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
+      return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
+    return nullptr;
+  }
+
+  /// getAsCXXOperatorIdName
+  CXXOperatorIdName *getAsCXXOperatorIdName() const {
+    if (getNameKind() == CXXOperatorName)
+      return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
+    return nullptr;
+  }
+
+  CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+    if (getNameKind() == CXXLiteralOperatorName)
+      return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+    return nullptr;
+  }
+
+  // Construct a declaration name from the name of a C++ constructor,
+  // destructor, or conversion function.
+  DeclarationName(CXXSpecialName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  // Construct a declaration name from the name of a C++ overloaded
+  // operator.
+  DeclarationName(CXXOperatorIdName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  DeclarationName(CXXLiteralOperatorIdName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
+  /// Construct a declaration name from a raw pointer.
+  DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
+
+  friend class DeclarationNameTable;
+  friend class NamedDecl;
+
+  /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer
+  /// for this name as a void pointer if it's not an identifier.
+  void *getFETokenInfoAsVoidSlow() const;
+
+public:
+  /// DeclarationName - Used to create an empty selector.
+  DeclarationName() : Ptr(0) { }
+
+  // Construct a declaration name from an IdentifierInfo *.
+  DeclarationName(const IdentifierInfo *II)
+    : Ptr(reinterpret_cast<uintptr_t>(II)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+  }
+
+  // Construct a declaration name from an Objective-C selector.
+  DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
+
+  /// getUsingDirectiveName - Return name for all using-directives.
+  static DeclarationName getUsingDirectiveName();
+
+  // operator bool() - Evaluates true when this declaration name is
+  // non-empty.
+  LLVM_EXPLICIT operator bool() const {
+    return ((Ptr & PtrMask) != 0) ||
+           (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
+  }
+
+  /// \brief Evaluates true when this declaration name is empty.
+  bool isEmpty() const {
+    return !*this;
+  }
+
+  /// Predicate functions for querying what type of name this is.
+  bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
+  bool isObjCZeroArgSelector() const {
+    return getStoredNameKind() == StoredObjCZeroArgSelector;
+  }
+  bool isObjCOneArgSelector() const {
+    return getStoredNameKind() == StoredObjCOneArgSelector;
+  }
+
+  /// getNameKind - Determine what kind of name this is.
+  NameKind getNameKind() const;
+
+  /// \brief Determines whether the name itself is dependent, e.g., because it 
+  /// involves a C++ type that is itself dependent.
+  ///
+  /// Note that this does not capture all of the notions of "dependent name",
+  /// because an identifier can be a dependent name if it is used as the 
+  /// callee in a call expression with dependent arguments.
+  bool isDependentName() const;
+  
+  /// getNameAsString - Retrieve the human-readable string for this name.
+  std::string getAsString() const;
+
+  /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
+  /// this declaration name, or NULL if this declaration name isn't a
+  /// simple identifier.
+  IdentifierInfo *getAsIdentifierInfo() const {
+    if (isIdentifier())
+      return reinterpret_cast<IdentifierInfo *>(Ptr);
+    return nullptr;
+  }
+
+  /// getAsOpaqueInteger - Get the representation of this declaration
+  /// name as an opaque integer.
+  uintptr_t getAsOpaqueInteger() const { return Ptr; }
+
+  /// getAsOpaquePtr - Get the representation of this declaration name as
+  /// an opaque pointer.
+  void *getAsOpaquePtr() const { return reinterpret_cast<void*>(Ptr); }
+
+  static DeclarationName getFromOpaquePtr(void *P) {
+    DeclarationName N;
+    N.Ptr = reinterpret_cast<uintptr_t> (P);
+    return N;
+  }
+
+  static DeclarationName getFromOpaqueInteger(uintptr_t P) {
+    DeclarationName N;
+    N.Ptr = P;
+    return N;
+  }
+
+  /// getCXXNameType - If this name is one of the C++ names (of a
+  /// constructor, destructor, or conversion function), return the
+  /// type associated with that name.
+  QualType getCXXNameType() const;
+
+  /// getCXXOverloadedOperator - If this name is the name of an
+  /// overloadable operator in C++ (e.g., @c operator+), retrieve the
+  /// kind of overloaded operator.
+  OverloadedOperatorKind getCXXOverloadedOperator() const;
+
+  /// getCXXLiteralIdentifier - If this name is the name of a literal
+  /// operator, retrieve the identifier associated with it.
+  IdentifierInfo *getCXXLiteralIdentifier() const;
+
+  /// getObjCSelector - Get the Objective-C selector stored in this
+  /// declaration name.
+  Selector getObjCSelector() const {
+    assert((getNameKind() == ObjCZeroArgSelector ||
+            getNameKind() == ObjCOneArgSelector ||
+            getNameKind() == ObjCMultiArgSelector ||
+            Ptr == 0) && "Not a selector!");
+    return Selector(Ptr);
+  }
+
+  /// getFETokenInfo/setFETokenInfo - The language front-end is
+  /// allowed to associate arbitrary metadata with some kinds of
+  /// declaration names, including normal identifiers and C++
+  /// constructors, destructors, and conversion functions.
+  template<typename T>
+  T *getFETokenInfo() const {
+    if (const IdentifierInfo *Info = getAsIdentifierInfo())
+      return Info->getFETokenInfo<T>();
+    return static_cast<T*>(getFETokenInfoAsVoidSlow());
+  }
+
+  void setFETokenInfo(void *T);
+
+  /// operator== - Determine whether the specified names are identical..
+  friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
+    return LHS.Ptr == RHS.Ptr;
+  }
+
+  /// operator!= - Determine whether the specified names are different.
+  friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
+    return LHS.Ptr != RHS.Ptr;
+  }
+
+  static DeclarationName getEmptyMarker() {
+    return DeclarationName(uintptr_t(-1));
+  }
+
+  static DeclarationName getTombstoneMarker() {
+    return DeclarationName(uintptr_t(-2));
+  }
+
+  static int compare(DeclarationName LHS, DeclarationName RHS);
+  
+  void dump() const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) < 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) > 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) <= 0;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
+  return DeclarationName::compare(LHS, RHS) >= 0;
+}
+
+/// DeclarationNameTable - Used to store and retrieve DeclarationName
+/// instances for the various kinds of declaration names, e.g., normal
+/// identifiers, C++ constructor names, etc. This class contains
+/// uniqued versions of each of the C++ special names, which can be
+/// retrieved using its member functions (e.g.,
+/// getCXXConstructorName).
+class DeclarationNameTable {
+  const ASTContext &Ctx;
+  void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
+  CXXOperatorIdName *CXXOperatorNames; // Operator names
+  void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
+
+  DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
+  void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION;
+
+public:
+  DeclarationNameTable(const ASTContext &C);
+  ~DeclarationNameTable();
+
+  /// getIdentifier - Create a declaration name that is a simple
+  /// identifier.
+  DeclarationName getIdentifier(const IdentifierInfo *ID) {
+    return DeclarationName(ID);
+  }
+
+  /// getCXXConstructorName - Returns the name of a C++ constructor
+  /// for the given Type.
+  DeclarationName getCXXConstructorName(CanQualType Ty);
+
+  /// getCXXDestructorName - Returns the name of a C++ destructor
+  /// for the given Type.
+  DeclarationName getCXXDestructorName(CanQualType Ty);
+
+  /// getCXXConversionFunctionName - Returns the name of a C++
+  /// conversion function for the given Type.
+  DeclarationName getCXXConversionFunctionName(CanQualType Ty);
+
+  /// getCXXSpecialName - Returns a declaration name for special kind
+  /// of C++ name, e.g., for a constructor, destructor, or conversion
+  /// function.
+  DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
+                                    CanQualType Ty);
+
+  /// getCXXOperatorName - Get the name of the overloadable C++
+  /// operator corresponding to Op.
+  DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+
+  /// getCXXLiteralOperatorName - Get the name of the literal operator function
+  /// with II as the identifier.
+  DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
+};
+
+/// DeclarationNameLoc - Additional source/type location info
+/// for a declaration name. Needs a DeclarationName in order
+/// to be interpreted correctly.
+struct DeclarationNameLoc {
+  // The source location for identifier stored elsewhere.
+  // struct {} Identifier;
+
+  // Type info for constructors, destructors and conversion functions.
+  // Locations (if any) for the tilde (destructor) or operator keyword
+  // (conversion) are stored elsewhere.
+  struct NT {
+    TypeSourceInfo* TInfo;
+  };
+
+  // The location (if any) of the operator keyword is stored elsewhere.
+  struct CXXOpName {
+    unsigned BeginOpNameLoc;
+    unsigned EndOpNameLoc;
+  };
+
+  // The location (if any) of the operator keyword is stored elsewhere.
+  struct CXXLitOpName {
+    unsigned OpNameLoc;
+  };
+
+  // struct {} CXXUsingDirective;
+  // struct {} ObjCZeroArgSelector;
+  // struct {} ObjCOneArgSelector;
+  // struct {} ObjCMultiArgSelector;
+  union {
+    struct NT NamedType;
+    struct CXXOpName CXXOperatorName;
+    struct CXXLitOpName CXXLiteralOperatorName;
+  };
+
+  DeclarationNameLoc(DeclarationName Name);
+  // FIXME: this should go away once all DNLocs are properly initialized.
+  DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); }
+}; // struct DeclarationNameLoc
+
+
+/// DeclarationNameInfo - A collector data type for bundling together
+/// a DeclarationName and the correspnding source/type location info.
+struct DeclarationNameInfo {
+private:
+  /// Name - The declaration name, also encoding name kind.
+  DeclarationName Name;
+  /// Loc - The main source location for the declaration name.
+  SourceLocation NameLoc;
+  /// Info - Further source/type location info for special kinds of names.
+  DeclarationNameLoc LocInfo;
+
+public:
+  // FIXME: remove it.
+  DeclarationNameInfo() {}
+
+  DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc)
+    : Name(Name), NameLoc(NameLoc), LocInfo(Name) {}
+
+  DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc,
+                      DeclarationNameLoc LocInfo)
+    : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {}
+
+  /// getName - Returns the embedded declaration name.
+  DeclarationName getName() const { return Name; }
+  /// setName - Sets the embedded declaration name.
+  void setName(DeclarationName N) { Name = N; }
+
+  /// getLoc - Returns the main location of the declaration name.
+  SourceLocation getLoc() const { return NameLoc; }
+  /// setLoc - Sets the main location of the declaration name.
+  void setLoc(SourceLocation L) { NameLoc = L; }
+
+  const DeclarationNameLoc &getInfo() const { return LocInfo; }
+  DeclarationNameLoc &getInfo() { return LocInfo; }
+  void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
+
+  /// getNamedTypeInfo - Returns the source type info associated to
+  /// the name. Assumes it is a constructor, destructor or conversion.
+  TypeSourceInfo *getNamedTypeInfo() const {
+    assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+           Name.getNameKind() == DeclarationName::CXXDestructorName ||
+           Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+    return LocInfo.NamedType.TInfo;
+  }
+  /// setNamedTypeInfo - Sets the source type info associated to
+  /// the name. Assumes it is a constructor, destructor or conversion.
+  void setNamedTypeInfo(TypeSourceInfo *TInfo) {
+    assert(Name.getNameKind() == DeclarationName::CXXConstructorName ||
+           Name.getNameKind() == DeclarationName::CXXDestructorName ||
+           Name.getNameKind() == DeclarationName::CXXConversionFunctionName);
+    LocInfo.NamedType.TInfo = TInfo;
+  }
+
+  /// getCXXOperatorNameRange - Gets the range of the operator name
+  /// (without the operator keyword). Assumes it is a (non-literal) operator.
+  SourceRange getCXXOperatorNameRange() const {
+    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    return SourceRange(
+     SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.BeginOpNameLoc),
+     SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc)
+                       );
+  }
+  /// setCXXOperatorNameRange - Sets the range of the operator name
+  /// (without the operator keyword). Assumes it is a C++ operator.
+  void setCXXOperatorNameRange(SourceRange R) {
+    assert(Name.getNameKind() == DeclarationName::CXXOperatorName);
+    LocInfo.CXXOperatorName.BeginOpNameLoc = R.getBegin().getRawEncoding();
+    LocInfo.CXXOperatorName.EndOpNameLoc = R.getEnd().getRawEncoding();
+  }
+
+  /// getCXXLiteralOperatorNameLoc - Returns the location of the literal
+  /// operator name (not the operator keyword).
+  /// Assumes it is a literal operator.
+  SourceLocation getCXXLiteralOperatorNameLoc() const {
+    assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+    return SourceLocation::
+      getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc);
+  }
+  /// setCXXLiteralOperatorNameLoc - Sets the location of the literal
+  /// operator name (not the operator keyword).
+  /// Assumes it is a literal operator.
+  void setCXXLiteralOperatorNameLoc(SourceLocation Loc) {
+    assert(Name.getNameKind() == DeclarationName::CXXLiteralOperatorName);
+    LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
+  }
+
+  /// \brief Determine whether this name involves a template parameter.
+  bool isInstantiationDependent() const;
+  
+  /// \brief Determine whether this name contains an unexpanded
+  /// parameter pack.
+  bool containsUnexpandedParameterPack() const;
+
+  /// getAsString - Retrieve the human-readable string for this name.
+  std::string getAsString() const;
+
+  /// printName - Print the human-readable name to a stream.
+  void printName(raw_ostream &OS) const;
+
+  /// getBeginLoc - Retrieve the location of the first token.
+  SourceLocation getBeginLoc() const { return NameLoc; }
+  /// getEndLoc - Retrieve the location of the last token.
+  SourceLocation getEndLoc() const;
+  /// getSourceRange - The range of the declaration name.
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(getLocStart(), getLocEnd());
+  }
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getBeginLoc();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    SourceLocation EndLoc = getEndLoc();
+    return EndLoc.isValid() ? EndLoc : getLocStart();
+  }
+};
+
+/// Insertion operator for diagnostics.  This allows sending DeclarationName's
+/// into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           DeclarationName N) {
+  DB.AddTaggedVal(N.getAsOpaqueInteger(),
+                  DiagnosticsEngine::ak_declarationname);
+  return DB;
+}
+
+/// Insertion operator for partial diagnostics.  This allows binding
+/// DeclarationName's into a partial diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           DeclarationName N) {
+  PD.AddTaggedVal(N.getAsOpaqueInteger(),
+                  DiagnosticsEngine::ak_declarationname);
+  return PD;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+                                     DeclarationNameInfo DNInfo) {
+  DNInfo.printName(OS);
+  return OS;
+}
+
+}  // end namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that DeclarationNames can be used as keys
+/// in DenseMap and DenseSets.
+template<>
+struct DenseMapInfo<clang::DeclarationName> {
+  static inline clang::DeclarationName getEmptyKey() {
+    return clang::DeclarationName::getEmptyMarker();
+  }
+
+  static inline clang::DeclarationName getTombstoneKey() {
+    return clang::DeclarationName::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::DeclarationName Name) {
+    return DenseMapInfo<void*>::getHashValue(Name.getAsOpaquePtr());
+  }
+
+  static inline bool
+  isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
+    return LHS == RHS;
+  }
+};
+
+template <>
+struct isPodLike<clang::DeclarationName> { static const bool value = true; };
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
new file mode 100644
index 0000000..63047ec
--- /dev/null
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -0,0 +1,188 @@
+//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- 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 interfaces for diagnostics which may or may
+//  fire based on how a template is instantiated.
+//
+//  At the moment, the only consumer of this interface is access
+//  control.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+class ASTContext;
+class CXXRecordDecl;
+class NamedDecl;
+
+/// A dependently-generated diagnostic.
+class DependentDiagnostic {
+public:
+  enum AccessNonce { Access = 0 };
+
+  static DependentDiagnostic *Create(ASTContext &Context,
+                                     DeclContext *Parent,
+                                     AccessNonce _,
+                                     SourceLocation Loc,
+                                     bool IsMemberAccess,
+                                     AccessSpecifier AS,
+                                     NamedDecl *TargetDecl,
+                                     CXXRecordDecl *NamingClass,
+                                     QualType BaseObjectType,
+                                     const PartialDiagnostic &PDiag) {
+    DependentDiagnostic *DD = Create(Context, Parent, PDiag);
+    DD->AccessData.Loc = Loc.getRawEncoding();
+    DD->AccessData.IsMember = IsMemberAccess;
+    DD->AccessData.Access = AS;
+    DD->AccessData.TargetDecl = TargetDecl;
+    DD->AccessData.NamingClass = NamingClass;
+    DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
+    return DD;
+  }
+
+  unsigned getKind() const {
+    return Access;
+  }
+
+  bool isAccessToMember() const {
+    assert(getKind() == Access);
+    return AccessData.IsMember;
+  }
+
+  AccessSpecifier getAccess() const {
+    assert(getKind() == Access);
+    return AccessSpecifier(AccessData.Access);
+  }
+
+  SourceLocation getAccessLoc() const {
+    assert(getKind() == Access);
+    return SourceLocation::getFromRawEncoding(AccessData.Loc);
+  }
+
+  NamedDecl *getAccessTarget() const {
+    assert(getKind() == Access);
+    return AccessData.TargetDecl;
+  }
+
+  NamedDecl *getAccessNamingClass() const {
+    assert(getKind() == Access);
+    return AccessData.NamingClass;
+  }
+
+  QualType getAccessBaseObjectType() const {
+    assert(getKind() == Access);
+    return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
+  }
+
+  const PartialDiagnostic &getDiagnostic() const {
+    return Diag;
+  }
+
+private:
+  DependentDiagnostic(const PartialDiagnostic &PDiag,
+                      PartialDiagnostic::Storage *Storage) 
+    : Diag(PDiag, Storage) {}
+  
+  static DependentDiagnostic *Create(ASTContext &Context,
+                                     DeclContext *Parent,
+                                     const PartialDiagnostic &PDiag);
+
+  friend class DependentStoredDeclsMap;
+  friend class DeclContext::ddiag_iterator;
+  DependentDiagnostic *NextDiagnostic;
+
+  PartialDiagnostic Diag;
+
+  struct {
+    unsigned Loc;
+    unsigned Access : 2;
+    unsigned IsMember : 1;
+    NamedDecl *TargetDecl;
+    CXXRecordDecl *NamingClass;
+    void *BaseObjectType;
+  } AccessData;
+};
+
+/// 
+
+/// An iterator over the dependent diagnostics in a dependent context.
+class DeclContext::ddiag_iterator {
+public:
+  ddiag_iterator() : Ptr(nullptr) {}
+  explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
+
+  typedef DependentDiagnostic *value_type;
+  typedef DependentDiagnostic *reference;
+  typedef DependentDiagnostic *pointer;
+  typedef int difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+
+  reference operator*() const { return Ptr; }
+
+  ddiag_iterator &operator++() {
+    assert(Ptr && "attempt to increment past end of diag list");
+    Ptr = Ptr->NextDiagnostic;
+    return *this;
+  }
+
+  ddiag_iterator operator++(int) {
+    ddiag_iterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  bool operator==(ddiag_iterator Other) const {
+    return Ptr == Other.Ptr;
+  }
+
+  bool operator!=(ddiag_iterator Other) const {
+    return Ptr != Other.Ptr;
+  }
+
+  ddiag_iterator &operator+=(difference_type N) {
+    assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
+    while (N--)
+      ++*this;
+    return *this;
+  }
+
+  ddiag_iterator operator+(difference_type N) const {
+    ddiag_iterator tmp = *this;
+    tmp += N;
+    return tmp;
+  }
+
+private:
+  DependentDiagnostic *Ptr;
+};
+
+inline DeclContext::ddiag_range DeclContext::ddiags() const {
+  assert(isDependentContext()
+         && "cannot iterate dependent diagnostics of non-dependent context");
+  const DependentStoredDeclsMap *Map
+    = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
+
+  if (!Map)
+    return ddiag_range();
+
+  return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
+}
+
+}
+
+#endif
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
new file mode 100644
index 0000000..12c4fcc
--- /dev/null
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -0,0 +1,95 @@
+//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- 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 EvaluatedExprVisitor class template, which visits
+//  the potentially-evaluated subexpressions of a potentially-evaluated
+//  expression.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
+#define LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtVisitor.h"
+
+namespace clang {
+  
+class ASTContext;
+  
+/// \brief Given a potentially-evaluated expression, this visitor visits all
+/// of its potentially-evaluated subexpressions, recursively.
+template<typename ImplClass>
+class EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
+  ASTContext &Context;
+  
+public:
+  explicit EvaluatedExprVisitor(ASTContext &Context) : Context(Context) { }
+  
+  // Expressions that have no potentially-evaluated subexpressions (but may have
+  // other sub-expressions).
+  void VisitDeclRefExpr(DeclRefExpr *E) { }
+  void VisitOffsetOfExpr(OffsetOfExpr *E) { }
+  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
+  void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
+  void VisitBlockExpr(BlockExpr *E) { }
+  void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }  
+  void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }
+  
+  void VisitMemberExpr(MemberExpr *E) {
+    // Only the base matters.
+    return this->Visit(E->getBase());
+  }
+  
+  void VisitChooseExpr(ChooseExpr *E) {
+    // Don't visit either child expression if the condition is dependent.
+    if (E->getCond()->isValueDependent())
+      return;
+    // Only the selected subexpression matters; the other one is not evaluated.
+    return this->Visit(E->getChosenSubExpr());
+  }
+
+  void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+    // Only the actual initializer matters; the designators are all constant
+    // expressions.
+    return this->Visit(E->getInit());
+  }
+
+  void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+    if (E->isPotentiallyEvaluated())
+      return this->Visit(E->getExprOperand());
+  }
+
+  void VisitCallExpr(CallExpr *CE) {
+    if (!CE->isUnevaluatedBuiltinCall(Context))
+      return static_cast<ImplClass*>(this)->VisitExpr(CE);
+  }
+
+  void VisitLambdaExpr(LambdaExpr *LE) {
+    // Only visit the capture initializers, and not the body.
+    for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(),
+                                           E = LE->capture_init_end();
+         I != E; ++I)
+      if (*I)
+        this->Visit(*I);
+  }
+
+  /// \brief The basis case walks all of the children of the statement or
+  /// expression, assuming they are all potentially evaluated.
+  void VisitStmt(Stmt *S) {
+    for (Stmt::child_range C = S->children(); C; ++C)
+      if (*C)
+        this->Visit(*C);
+  }
+};
+
+}
+
+#endif // LLVM_CLANG_AST_EVALUATEDEXPRVISITOR_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
new file mode 100644
index 0000000..b4bb0b6
--- /dev/null
+++ b/include/clang/AST/Expr.h
@@ -0,0 +1,4846 @@
+//===--- Expr.h - Classes for representing expressions ----------*- 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 Expr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPR_H
+#define LLVM_CLANG_AST_EXPR_H
+
+#include "clang/AST/APValue.h"
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+  class APValue;
+  class ASTContext;
+  class BlockDecl;
+  class CXXBaseSpecifier;
+  class CXXMemberCallExpr;
+  class CXXOperatorCallExpr;
+  class CastExpr;
+  class Decl;
+  class IdentifierInfo;
+  class MaterializeTemporaryExpr;
+  class NamedDecl;
+  class ObjCPropertyRefExpr;
+  class OpaqueValueExpr;
+  class ParmVarDecl;
+  class TargetInfo;
+  class ValueDecl;
+
+/// \brief A simple array of base specifiers.
+typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
+
+/// \brief An adjustment to be made to the temporary created when emitting a
+/// reference binding, which accesses a particular subobject of that temporary.
+struct SubobjectAdjustment {
+  enum {
+    DerivedToBaseAdjustment,
+    FieldAdjustment,
+    MemberPointerAdjustment
+  } Kind;
+
+
+  struct DTB {
+    const CastExpr *BasePath;
+    const CXXRecordDecl *DerivedClass;
+  };
+
+  struct P {
+    const MemberPointerType *MPT;
+    Expr *RHS;
+  };
+
+  union {
+    struct DTB DerivedToBase;
+    FieldDecl *Field;
+    struct P Ptr;
+  };
+
+  SubobjectAdjustment(const CastExpr *BasePath,
+                      const CXXRecordDecl *DerivedClass)
+    : Kind(DerivedToBaseAdjustment) {
+    DerivedToBase.BasePath = BasePath;
+    DerivedToBase.DerivedClass = DerivedClass;
+  }
+
+  SubobjectAdjustment(FieldDecl *Field)
+    : Kind(FieldAdjustment) {
+    this->Field = Field;
+  }
+
+  SubobjectAdjustment(const MemberPointerType *MPT, Expr *RHS)
+    : Kind(MemberPointerAdjustment) {
+    this->Ptr.MPT = MPT;
+    this->Ptr.RHS = RHS;
+  }
+};
+
+/// Expr - This represents one expression.  Note that Expr's are subclasses of
+/// Stmt.  This allows an expression to be transparently used any place a Stmt
+/// is required.
+///
+class Expr : public Stmt {
+  QualType TR;
+
+protected:
+  Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
+       bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
+    : Stmt(SC)
+  {
+    ExprBits.TypeDependent = TD;
+    ExprBits.ValueDependent = VD;
+    ExprBits.InstantiationDependent = ID;
+    ExprBits.ValueKind = VK;
+    ExprBits.ObjectKind = OK;
+    ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+    setType(T);
+  }
+
+  /// \brief Construct an empty expression.
+  explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
+
+public:
+  QualType getType() const { return TR; }
+  void setType(QualType t) {
+    // In C++, the type of an expression is always adjusted so that it
+    // will not have reference type an expression will never have
+    // reference type (C++ [expr]p6). Use
+    // QualType::getNonReferenceType() to retrieve the non-reference
+    // type. Additionally, inspect Expr::isLvalue to determine whether
+    // an expression that is adjusted in this manner should be
+    // considered an lvalue.
+    assert((t.isNull() || !t->isReferenceType()) &&
+           "Expressions can't have reference type");
+
+    TR = t;
+  }
+
+  /// isValueDependent - Determines whether this expression is
+  /// value-dependent (C++ [temp.dep.constexpr]). For example, the
+  /// array bound of "Chars" in the following example is
+  /// value-dependent.
+  /// @code
+  /// template<int Size, char (&Chars)[Size]> struct meta_string;
+  /// @endcode
+  bool isValueDependent() const { return ExprBits.ValueDependent; }
+
+  /// \brief Set whether this expression is value-dependent or not.
+  void setValueDependent(bool VD) {
+    ExprBits.ValueDependent = VD;
+    if (VD)
+      ExprBits.InstantiationDependent = true;
+  }
+
+  /// isTypeDependent - Determines whether this expression is
+  /// type-dependent (C++ [temp.dep.expr]), which means that its type
+  /// could change from one template instantiation to the next. For
+  /// example, the expressions "x" and "x + y" are type-dependent in
+  /// the following code, but "y" is not type-dependent:
+  /// @code
+  /// template<typename T>
+  /// void add(T x, int y) {
+  ///   x + y;
+  /// }
+  /// @endcode
+  bool isTypeDependent() const { return ExprBits.TypeDependent; }
+
+  /// \brief Set whether this expression is type-dependent or not.
+  void setTypeDependent(bool TD) {
+    ExprBits.TypeDependent = TD;
+    if (TD)
+      ExprBits.InstantiationDependent = true;
+  }
+
+  /// \brief Whether this expression is instantiation-dependent, meaning that
+  /// it depends in some way on a template parameter, even if neither its type
+  /// nor (constant) value can change due to the template instantiation.
+  ///
+  /// In the following example, the expression \c sizeof(sizeof(T() + T())) is
+  /// instantiation-dependent (since it involves a template parameter \c T), but
+  /// is neither type- nor value-dependent, since the type of the inner
+  /// \c sizeof is known (\c std::size_t) and therefore the size of the outer
+  /// \c sizeof is known.
+  ///
+  /// \code
+  /// template<typename T>
+  /// void f(T x, T y) {
+  ///   sizeof(sizeof(T() + T());
+  /// }
+  /// \endcode
+  ///
+  bool isInstantiationDependent() const {
+    return ExprBits.InstantiationDependent;
+  }
+
+  /// \brief Set whether this expression is instantiation-dependent or not.
+  void setInstantiationDependent(bool ID) {
+    ExprBits.InstantiationDependent = ID;
+  }
+
+  /// \brief Whether this expression contains an unexpanded parameter
+  /// pack (for C++11 variadic templates).
+  ///
+  /// Given the following function template:
+  ///
+  /// \code
+  /// template<typename F, typename ...Types>
+  /// void forward(const F &f, Types &&...args) {
+  ///   f(static_cast<Types&&>(args)...);
+  /// }
+  /// \endcode
+  ///
+  /// The expressions \c args and \c static_cast<Types&&>(args) both
+  /// contain parameter packs.
+  bool containsUnexpandedParameterPack() const {
+    return ExprBits.ContainsUnexpandedParameterPack;
+  }
+
+  /// \brief Set the bit that describes whether this expression
+  /// contains an unexpanded parameter pack.
+  void setContainsUnexpandedParameterPack(bool PP = true) {
+    ExprBits.ContainsUnexpandedParameterPack = PP;
+  }
+
+  /// getExprLoc - Return the preferred location for the arrow when diagnosing
+  /// a problem with a generic expression.
+  SourceLocation getExprLoc() const LLVM_READONLY;
+
+  /// isUnusedResultAWarning - Return true if this immediate expression should
+  /// be warned about if the result is unused.  If so, fill in expr, location,
+  /// and ranges with expr to warn on and source locations/ranges appropriate
+  /// for a warning.
+  bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc,
+                              SourceRange &R1, SourceRange &R2,
+                              ASTContext &Ctx) const;
+
+  /// isLValue - True if this expression is an "l-value" according to
+  /// the rules of the current language.  C and C++ give somewhat
+  /// different rules for this concept, but in general, the result of
+  /// an l-value expression identifies a specific object whereas the
+  /// result of an r-value expression is a value detached from any
+  /// specific storage.
+  ///
+  /// C++11 divides the concept of "r-value" into pure r-values
+  /// ("pr-values") and so-called expiring values ("x-values"), which
+  /// identify specific objects that can be safely cannibalized for
+  /// their resources.  This is an unfortunate abuse of terminology on
+  /// the part of the C++ committee.  In Clang, when we say "r-value",
+  /// we generally mean a pr-value.
+  bool isLValue() const { return getValueKind() == VK_LValue; }
+  bool isRValue() const { return getValueKind() == VK_RValue; }
+  bool isXValue() const { return getValueKind() == VK_XValue; }
+  bool isGLValue() const { return getValueKind() != VK_RValue; }
+
+  enum LValueClassification {
+    LV_Valid,
+    LV_NotObjectType,
+    LV_IncompleteVoidType,
+    LV_DuplicateVectorComponents,
+    LV_InvalidExpression,
+    LV_InvalidMessageExpression,
+    LV_MemberFunction,
+    LV_SubObjCPropertySetting,
+    LV_ClassTemporary,
+    LV_ArrayTemporary
+  };
+  /// Reasons why an expression might not be an l-value.
+  LValueClassification ClassifyLValue(ASTContext &Ctx) const;
+
+  enum isModifiableLvalueResult {
+    MLV_Valid,
+    MLV_NotObjectType,
+    MLV_IncompleteVoidType,
+    MLV_DuplicateVectorComponents,
+    MLV_InvalidExpression,
+    MLV_LValueCast,           // Specialized form of MLV_InvalidExpression.
+    MLV_IncompleteType,
+    MLV_ConstQualified,
+    MLV_ArrayType,
+    MLV_NoSetterProperty,
+    MLV_MemberFunction,
+    MLV_SubObjCPropertySetting,
+    MLV_InvalidMessageExpression,
+    MLV_ClassTemporary,
+    MLV_ArrayTemporary
+  };
+  /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
+  /// does not have an incomplete type, does not have a const-qualified type,
+  /// and if it is a structure or union, does not have any member (including,
+  /// recursively, any member or element of all contained aggregates or unions)
+  /// with a const-qualified type.
+  ///
+  /// \param Loc [in,out] - A source location which *may* be filled
+  /// in with the location of the expression making this a
+  /// non-modifiable lvalue, if specified.
+  isModifiableLvalueResult
+  isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
+
+  /// \brief The return type of classify(). Represents the C++11 expression
+  ///        taxonomy.
+  class Classification {
+  public:
+    /// \brief The various classification results. Most of these mean prvalue.
+    enum Kinds {
+      CL_LValue,
+      CL_XValue,
+      CL_Function, // Functions cannot be lvalues in C.
+      CL_Void, // Void cannot be an lvalue in C.
+      CL_AddressableVoid, // Void expression whose address can be taken in C.
+      CL_DuplicateVectorComponents, // A vector shuffle with dupes.
+      CL_MemberFunction, // An expression referring to a member function
+      CL_SubObjCPropertySetting,
+      CL_ClassTemporary, // A temporary of class type, or subobject thereof.
+      CL_ArrayTemporary, // A temporary of array type.
+      CL_ObjCMessageRValue, // ObjC message is an rvalue
+      CL_PRValue // A prvalue for any other reason, of any other type
+    };
+    /// \brief The results of modification testing.
+    enum ModifiableType {
+      CM_Untested, // testModifiable was false.
+      CM_Modifiable,
+      CM_RValue, // Not modifiable because it's an rvalue
+      CM_Function, // Not modifiable because it's a function; C++ only
+      CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
+      CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
+      CM_ConstQualified,
+      CM_ArrayType,
+      CM_IncompleteType
+    };
+
+  private:
+    friend class Expr;
+
+    unsigned short Kind;
+    unsigned short Modifiable;
+
+    explicit Classification(Kinds k, ModifiableType m)
+      : Kind(k), Modifiable(m)
+    {}
+
+  public:
+    Classification() {}
+
+    Kinds getKind() const { return static_cast<Kinds>(Kind); }
+    ModifiableType getModifiable() const {
+      assert(Modifiable != CM_Untested && "Did not test for modifiability.");
+      return static_cast<ModifiableType>(Modifiable);
+    }
+    bool isLValue() const { return Kind == CL_LValue; }
+    bool isXValue() const { return Kind == CL_XValue; }
+    bool isGLValue() const { return Kind <= CL_XValue; }
+    bool isPRValue() const { return Kind >= CL_Function; }
+    bool isRValue() const { return Kind >= CL_XValue; }
+    bool isModifiable() const { return getModifiable() == CM_Modifiable; }
+
+    /// \brief Create a simple, modifiably lvalue
+    static Classification makeSimpleLValue() {
+      return Classification(CL_LValue, CM_Modifiable);
+    }
+
+  };
+  /// \brief Classify - Classify this expression according to the C++11
+  ///        expression taxonomy.
+  ///
+  /// C++11 defines ([basic.lval]) a new taxonomy of expressions to replace the
+  /// old lvalue vs rvalue. This function determines the type of expression this
+  /// is. There are three expression types:
+  /// - lvalues are classical lvalues as in C++03.
+  /// - prvalues are equivalent to rvalues in C++03.
+  /// - xvalues are expressions yielding unnamed rvalue references, e.g. a
+  ///   function returning an rvalue reference.
+  /// lvalues and xvalues are collectively referred to as glvalues, while
+  /// prvalues and xvalues together form rvalues.
+  Classification Classify(ASTContext &Ctx) const {
+    return ClassifyImpl(Ctx, nullptr);
+  }
+
+  /// \brief ClassifyModifiable - Classify this expression according to the
+  ///        C++11 expression taxonomy, and see if it is valid on the left side
+  ///        of an assignment.
+  ///
+  /// This function extends classify in that it also tests whether the
+  /// expression is modifiable (C99 6.3.2.1p1).
+  /// \param Loc A source location that might be filled with a relevant location
+  ///            if the expression is not modifiable.
+  Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{
+    return ClassifyImpl(Ctx, &Loc);
+  }
+
+  /// getValueKindForType - Given a formal return or parameter type,
+  /// give its value kind.
+  static ExprValueKind getValueKindForType(QualType T) {
+    if (const ReferenceType *RT = T->getAs<ReferenceType>())
+      return (isa<LValueReferenceType>(RT)
+                ? VK_LValue
+                : (RT->getPointeeType()->isFunctionType()
+                     ? VK_LValue : VK_XValue));
+    return VK_RValue;
+  }
+
+  /// getValueKind - The value kind that this expression produces.
+  ExprValueKind getValueKind() const {
+    return static_cast<ExprValueKind>(ExprBits.ValueKind);
+  }
+
+  /// getObjectKind - The object kind that this expression produces.
+  /// Object kinds are meaningful only for expressions that yield an
+  /// l-value or x-value.
+  ExprObjectKind getObjectKind() const {
+    return static_cast<ExprObjectKind>(ExprBits.ObjectKind);
+  }
+
+  bool isOrdinaryOrBitFieldObject() const {
+    ExprObjectKind OK = getObjectKind();
+    return (OK == OK_Ordinary || OK == OK_BitField);
+  }
+
+  /// setValueKind - Set the value kind produced by this expression.
+  void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }
+
+  /// setObjectKind - Set the object kind produced by this expression.
+  void setObjectKind(ExprObjectKind Cat) { ExprBits.ObjectKind = Cat; }
+
+private:
+  Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const;
+
+public:
+
+  /// \brief Returns true if this expression is a gl-value that
+  /// potentially refers to a bit-field.
+  ///
+  /// In C++, whether a gl-value refers to a bitfield is essentially
+  /// an aspect of the value-kind type system.
+  bool refersToBitField() const { return getObjectKind() == OK_BitField; }
+
+  /// \brief If this expression refers to a bit-field, retrieve the
+  /// declaration of that bit-field.
+  ///
+  /// Note that this returns a non-null pointer in subtly different
+  /// places than refersToBitField returns true.  In particular, this can
+  /// return a non-null pointer even for r-values loaded from
+  /// bit-fields, but it will return null for a conditional bit-field.
+  FieldDecl *getSourceBitField();
+
+  const FieldDecl *getSourceBitField() const {
+    return const_cast<Expr*>(this)->getSourceBitField();
+  }
+
+  /// \brief If this expression is an l-value for an Objective C
+  /// property, find the underlying property reference expression.
+  const ObjCPropertyRefExpr *getObjCProperty() const;
+
+  /// \brief Check if this expression is the ObjC 'self' implicit parameter.
+  bool isObjCSelfExpr() const;
+
+  /// \brief Returns whether this expression refers to a vector element.
+  bool refersToVectorElement() const;
+
+  /// \brief Returns whether this expression has a placeholder type.
+  bool hasPlaceholderType() const {
+    return getType()->isPlaceholderType();
+  }
+
+  /// \brief Returns whether this expression has a specific placeholder type.
+  bool hasPlaceholderType(BuiltinType::Kind K) const {
+    assert(BuiltinType::isPlaceholderTypeKind(K));
+    if (const BuiltinType *BT = dyn_cast<BuiltinType>(getType()))
+      return BT->getKind() == K;
+    return false;
+  }
+
+  /// isKnownToHaveBooleanValue - Return true if this is an integer expression
+  /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
+  /// but also int expressions which are produced by things like comparisons in
+  /// C.
+  bool isKnownToHaveBooleanValue() const;
+
+  /// isIntegerConstantExpr - Return true if this expression is a valid integer
+  /// constant expression, and, if so, return its value in Result.  If not a
+  /// valid i-c-e, return false and fill in Loc (if specified) with the location
+  /// of the invalid expression.
+  ///
+  /// Note: This does not perform the implicit conversions required by C++11
+  /// [expr.const]p5.
+  bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
+                             SourceLocation *Loc = nullptr,
+                             bool isEvaluated = true) const;
+  bool isIntegerConstantExpr(const ASTContext &Ctx,
+                             SourceLocation *Loc = nullptr) const;
+
+  /// isCXX98IntegralConstantExpr - Return true if this expression is an
+  /// integral constant expression in C++98. Can only be used in C++.
+  bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const;
+
+  /// isCXX11ConstantExpr - Return true if this expression is a constant
+  /// expression in C++11. Can only be used in C++.
+  ///
+  /// Note: This does not perform the implicit conversions required by C++11
+  /// [expr.const]p5.
+  bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
+                           SourceLocation *Loc = nullptr) const;
+
+  /// isPotentialConstantExpr - Return true if this function's definition
+  /// might be usable in a constant expression in C++11, if it were marked
+  /// constexpr. Return false if the function can never produce a constant
+  /// expression, along with diagnostics describing why not.
+  static bool isPotentialConstantExpr(const FunctionDecl *FD,
+                                      SmallVectorImpl<
+                                        PartialDiagnosticAt> &Diags);
+
+  /// isPotentialConstantExprUnevaluted - Return true if this expression might
+  /// be usable in a constant expression in C++11 in an unevaluated context, if
+  /// it were in function FD marked constexpr. Return false if the function can
+  /// never produce a constant expression, along with diagnostics describing
+  /// why not.
+  static bool isPotentialConstantExprUnevaluated(Expr *E,
+                                                 const FunctionDecl *FD,
+                                                 SmallVectorImpl<
+                                                   PartialDiagnosticAt> &Diags);
+
+  /// isConstantInitializer - Returns true if this expression can be emitted to
+  /// IR as a constant, and thus can be used as a constant initializer in C.
+  /// If this expression is not constant and Culprit is non-null,
+  /// it is used to store the address of first non constant expr.
+  bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
+                             const Expr **Culprit = nullptr) const;
+
+  /// EvalStatus is a struct with detailed info about an evaluation in progress.
+  struct EvalStatus {
+    /// HasSideEffects - Whether the evaluated expression has side effects.
+    /// For example, (f() && 0) can be folded, but it still has side effects.
+    bool HasSideEffects;
+
+    /// Diag - If this is non-null, it will be filled in with a stack of notes
+    /// indicating why evaluation failed (or why it failed to produce a constant
+    /// expression).
+    /// If the expression is unfoldable, the notes will indicate why it's not
+    /// foldable. If the expression is foldable, but not a constant expression,
+    /// the notes will describes why it isn't a constant expression. If the
+    /// expression *is* a constant expression, no notes will be produced.
+    SmallVectorImpl<PartialDiagnosticAt> *Diag;
+
+    EvalStatus() : HasSideEffects(false), Diag(nullptr) {}
+
+    // hasSideEffects - Return true if the evaluated expression has
+    // side effects.
+    bool hasSideEffects() const {
+      return HasSideEffects;
+    }
+  };
+
+  /// EvalResult is a struct with detailed info about an evaluated expression.
+  struct EvalResult : EvalStatus {
+    /// Val - This is the value the expression can be folded to.
+    APValue Val;
+
+    // isGlobalLValue - Return true if the evaluated lvalue expression
+    // is global.
+    bool isGlobalLValue() const;
+  };
+
+  /// EvaluateAsRValue - Return true if this is a constant which we can fold to
+  /// an rvalue using any crazy technique (that has nothing to do with language
+  /// standards) that we want to, even if the expression has side-effects. If
+  /// this function returns true, it returns the folded constant in Result. If
+  /// the expression is a glvalue, an lvalue-to-rvalue conversion will be
+  /// applied.
+  bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
+
+  /// EvaluateAsBooleanCondition - Return true if this is a constant
+  /// which we we can fold and convert to a boolean condition using
+  /// any crazy technique that we want to, even if the expression has
+  /// side-effects.
+  bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
+
+  enum SideEffectsKind { SE_NoSideEffects, SE_AllowSideEffects };
+
+  /// EvaluateAsInt - Return true if this is a constant which we can fold and
+  /// convert to an integer, using any crazy technique that we want to.
+  bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx,
+                     SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
+
+  /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
+  /// constant folded without side-effects, but discard the result.
+  bool isEvaluatable(const ASTContext &Ctx) const;
+
+  /// HasSideEffects - This routine returns true for all those expressions
+  /// which have any effect other than producing a value. Example is a function
+  /// call, volatile variable read, or throwing an exception.
+  bool HasSideEffects(const ASTContext &Ctx) const;
+
+  /// \brief Determine whether this expression involves a call to any function
+  /// that is not trivial.
+  bool hasNonTrivialCall(ASTContext &Ctx);
+
+  /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
+  /// integer. This must be called on an expression that constant folds to an
+  /// integer.
+  llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
+                    SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
+
+  void EvaluateForOverflow(const ASTContext &Ctx) const;
+
+  /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
+  /// lvalue with link time known address, with no side-effects.
+  bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const;
+
+  /// EvaluateAsInitializer - Evaluate an expression as if it were the
+  /// initializer of the given declaration. Returns true if the initializer
+  /// can be folded to a constant, and produces any relevant notes. In C++11,
+  /// notes will be produced if the expression is not a constant expression.
+  bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
+                             const VarDecl *VD,
+                             SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+
+  /// EvaluateWithSubstitution - Evaluate an expression as if from the context
+  /// of a call to the given function with the given arguments, inside an
+  /// unevaluated context. Returns true if the expression could be folded to a
+  /// constant.
+  bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+                                const FunctionDecl *Callee,
+                                ArrayRef<const Expr*> Args) const;
+
+  /// \brief Enumeration used to describe the kind of Null pointer constant
+  /// returned from \c isNullPointerConstant().
+  enum NullPointerConstantKind {
+    /// \brief Expression is not a Null pointer constant.
+    NPCK_NotNull = 0,
+
+    /// \brief Expression is a Null pointer constant built from a zero integer
+    /// expression that is not a simple, possibly parenthesized, zero literal.
+    /// C++ Core Issue 903 will classify these expressions as "not pointers"
+    /// once it is adopted.
+    /// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
+    NPCK_ZeroExpression,
+
+    /// \brief Expression is a Null pointer constant built from a literal zero.
+    NPCK_ZeroLiteral,
+
+    /// \brief Expression is a C++11 nullptr.
+    NPCK_CXX11_nullptr,
+
+    /// \brief Expression is a GNU-style __null constant.
+    NPCK_GNUNull
+  };
+
+  /// \brief Enumeration used to describe how \c isNullPointerConstant()
+  /// should cope with value-dependent expressions.
+  enum NullPointerConstantValueDependence {
+    /// \brief Specifies that the expression should never be value-dependent.
+    NPC_NeverValueDependent = 0,
+
+    /// \brief Specifies that a value-dependent expression of integral or
+    /// dependent type should be considered a null pointer constant.
+    NPC_ValueDependentIsNull,
+
+    /// \brief Specifies that a value-dependent expression should be considered
+    /// to never be a null pointer constant.
+    NPC_ValueDependentIsNotNull
+  };
+
+  /// isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to
+  /// a Null pointer constant. The return value can further distinguish the
+  /// kind of NULL pointer constant that was detected.
+  NullPointerConstantKind isNullPointerConstant(
+      ASTContext &Ctx,
+      NullPointerConstantValueDependence NPC) const;
+
+  /// isOBJCGCCandidate - Return true if this expression may be used in a read/
+  /// write barrier.
+  bool isOBJCGCCandidate(ASTContext &Ctx) const;
+
+  /// \brief Returns true if this expression is a bound member function.
+  bool isBoundMemberFunction(ASTContext &Ctx) const;
+
+  /// \brief Given an expression of bound-member type, find the type
+  /// of the member.  Returns null if this is an *overloaded* bound
+  /// member expression.
+  static QualType findBoundMemberType(const Expr *expr);
+
+  /// IgnoreImpCasts - Skip past any implicit casts which might
+  /// surround this expression.  Only skips ImplicitCastExprs.
+  Expr *IgnoreImpCasts() LLVM_READONLY;
+
+  /// IgnoreImplicit - Skip past any implicit AST nodes which might
+  /// surround this expression.
+  Expr *IgnoreImplicit() LLVM_READONLY {
+    return cast<Expr>(Stmt::IgnoreImplicit());
+  }
+
+  const Expr *IgnoreImplicit() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreImplicit();
+  }
+
+  /// IgnoreParens - Ignore parentheses.  If this Expr is a ParenExpr, return
+  ///  its subexpression.  If that subexpression is also a ParenExpr,
+  ///  then this method recursively returns its subexpression, and so forth.
+  ///  Otherwise, the method returns the current Expr.
+  Expr *IgnoreParens() LLVM_READONLY;
+
+  /// IgnoreParenCasts - Ignore parentheses and casts.  Strip off any ParenExpr
+  /// or CastExprs, returning their operand.
+  Expr *IgnoreParenCasts() LLVM_READONLY;
+
+  /// Ignore casts.  Strip off any CastExprs, returning their operand.
+  Expr *IgnoreCasts() LLVM_READONLY;
+
+  /// IgnoreParenImpCasts - Ignore parentheses and implicit casts.  Strip off
+  /// any ParenExpr or ImplicitCastExprs, returning their operand.
+  Expr *IgnoreParenImpCasts() LLVM_READONLY;
+
+  /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
+  /// call to a conversion operator, return the argument.
+  Expr *IgnoreConversionOperator() LLVM_READONLY;
+
+  const Expr *IgnoreConversionOperator() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreConversionOperator();
+  }
+
+  const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreParenImpCasts();
+  }
+
+  /// Ignore parentheses and lvalue casts.  Strip off any ParenExpr and
+  /// CastExprs that represent lvalue casts, returning their operand.
+  Expr *IgnoreParenLValueCasts() LLVM_READONLY;
+
+  const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
+  }
+
+  /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
+  /// value (including ptr->int casts of the same size).  Strip off any
+  /// ParenExpr or CastExprs, returning their operand.
+  Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
+
+  /// Ignore parentheses and derived-to-base casts.
+  Expr *ignoreParenBaseCasts() LLVM_READONLY;
+
+  const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->ignoreParenBaseCasts();
+  }
+
+  /// \brief Determine whether this expression is a default function argument.
+  ///
+  /// Default arguments are implicitly generated in the abstract syntax tree
+  /// by semantic analysis for function calls, object constructions, etc. in
+  /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
+  /// this routine also looks through any implicit casts to determine whether
+  /// the expression is a default argument.
+  bool isDefaultArgument() const;
+
+  /// \brief Determine whether the result of this expression is a
+  /// temporary object of the given class type.
+  bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
+
+  /// \brief Whether this expression is an implicit reference to 'this' in C++.
+  bool isImplicitCXXThis() const;
+
+  const Expr *IgnoreImpCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreImpCasts();
+  }
+  const Expr *IgnoreParens() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreParens();
+  }
+  const Expr *IgnoreParenCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreParenCasts();
+  }
+  /// Strip off casts, but keep parentheses.
+  const Expr *IgnoreCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreCasts();
+  }
+
+  const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
+  }
+
+  static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
+
+  /// \brief For an expression of class type or pointer to class type,
+  /// return the most derived class decl the expression is known to refer to.
+  ///
+  /// If this expression is a cast, this method looks through it to find the
+  /// most derived decl that can be inferred from the expression.
+  /// This is valid because derived-to-base conversions have undefined
+  /// behavior if the object isn't dynamically of the derived type.
+  const CXXRecordDecl *getBestDynamicClassType() const;
+
+  /// Walk outwards from an expression we want to bind a reference to and
+  /// find the expression whose lifetime needs to be extended. Record
+  /// the LHSs of comma expressions and adjustments needed along the path.
+  const Expr *skipRValueSubobjectAdjustments(
+      SmallVectorImpl<const Expr *> &CommaLHS,
+      SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() >= firstExprConstant &&
+           T->getStmtClass() <= lastExprConstant;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Primary Expressions.
+//===----------------------------------------------------------------------===//
+
+/// OpaqueValueExpr - An expression referring to an opaque object of a
+/// fixed type and value class.  These don't correspond to concrete
+/// syntax; instead they're used to express operations (usually copy
+/// operations) on values whose source is generally obvious from
+/// context.
+class OpaqueValueExpr : public Expr {
+  friend class ASTStmtReader;
+  Expr *SourceExpr;
+  SourceLocation Loc;
+
+public:
+  OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
+                  ExprObjectKind OK = OK_Ordinary,
+                  Expr *SourceExpr = nullptr)
+    : Expr(OpaqueValueExprClass, T, VK, OK,
+           T->isDependentType(), 
+           T->isDependentType() || 
+           (SourceExpr && SourceExpr->isValueDependent()),
+           T->isInstantiationDependentType(),
+           false),
+      SourceExpr(SourceExpr), Loc(Loc) {
+  }
+
+  /// Given an expression which invokes a copy constructor --- i.e.  a
+  /// CXXConstructExpr, possibly wrapped in an ExprWithCleanups ---
+  /// find the OpaqueValueExpr that's the source of the construction.
+  static const OpaqueValueExpr *findInCopyConstruct(const Expr *expr);
+
+  explicit OpaqueValueExpr(EmptyShell Empty)
+    : Expr(OpaqueValueExprClass, Empty) { }
+
+  /// \brief Retrieve the location of this expression.
+  SourceLocation getLocation() const { return Loc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return SourceExpr ? SourceExpr->getLocStart() : Loc;
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SourceExpr ? SourceExpr->getLocEnd() : Loc;
+  }
+  SourceLocation getExprLoc() const LLVM_READONLY {
+    if (SourceExpr) return SourceExpr->getExprLoc();
+    return Loc;
+  }
+
+  child_range children() { return child_range(); }
+
+  /// The source expression of an opaque value expression is the
+  /// expression which originally generated the value.  This is
+  /// provided as a convenience for analyses that don't wish to
+  /// precisely model the execution behavior of the program.
+  ///
+  /// The source expression is typically set when building the
+  /// expression which binds the opaque value expression in the first
+  /// place.
+  Expr *getSourceExpr() const { return SourceExpr; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OpaqueValueExprClass;
+  }
+};
+
+/// \brief A reference to a declared variable, function, enum, etc.
+/// [C99 6.5.1p2]
+///
+/// This encodes all the information about how a declaration is referenced
+/// within an expression.
+///
+/// There are several optional constructs attached to DeclRefExprs only when
+/// they apply in order to conserve memory. These are laid out past the end of
+/// the object, and flags in the DeclRefExprBitfield track whether they exist:
+///
+///   DeclRefExprBits.HasQualifier:
+///       Specifies when this declaration reference expression has a C++
+///       nested-name-specifier.
+///   DeclRefExprBits.HasFoundDecl:
+///       Specifies when this declaration reference expression has a record of
+///       a NamedDecl (different from the referenced ValueDecl) which was found
+///       during name lookup and/or overload resolution.
+///   DeclRefExprBits.HasTemplateKWAndArgsInfo:
+///       Specifies when this declaration reference expression has an explicit
+///       C++ template keyword and/or template argument list.
+///   DeclRefExprBits.RefersToEnclosingLocal
+///       Specifies when this declaration reference expression (validly)
+///       refers to a local variable from a different function.
+class DeclRefExpr : public Expr {
+  /// \brief The declaration that we are referencing.
+  ValueDecl *D;
+
+  /// \brief The location of the declaration name itself.
+  SourceLocation Loc;
+
+  /// \brief Provides source/type location info for the declaration name
+  /// embedded in D.
+  DeclarationNameLoc DNLoc;
+
+  /// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
+  NestedNameSpecifierLoc &getInternalQualifierLoc() {
+    assert(hasQualifier());
+    return *reinterpret_cast<NestedNameSpecifierLoc *>(this + 1);
+  }
+
+  /// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
+  const NestedNameSpecifierLoc &getInternalQualifierLoc() const {
+    return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc();
+  }
+
+  /// \brief Test whether there is a distinct FoundDecl attached to the end of
+  /// this DRE.
+  bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
+
+  /// \brief Helper to retrieve the optional NamedDecl through which this
+  /// reference occurred.
+  NamedDecl *&getInternalFoundDecl() {
+    assert(hasFoundDecl());
+    if (hasQualifier())
+      return *reinterpret_cast<NamedDecl **>(&getInternalQualifierLoc() + 1);
+    return *reinterpret_cast<NamedDecl **>(this + 1);
+  }
+
+  /// \brief Helper to retrieve the optional NamedDecl through which this
+  /// reference occurred.
+  NamedDecl *getInternalFoundDecl() const {
+    return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
+  }
+
+  DeclRefExpr(const ASTContext &Ctx,
+              NestedNameSpecifierLoc QualifierLoc,
+              SourceLocation TemplateKWLoc,
+              ValueDecl *D, bool refersToEnclosingLocal,
+              const DeclarationNameInfo &NameInfo,
+              NamedDecl *FoundD,
+              const TemplateArgumentListInfo *TemplateArgs,
+              QualType T, ExprValueKind VK);
+
+  /// \brief Construct an empty declaration reference expression.
+  explicit DeclRefExpr(EmptyShell Empty)
+    : Expr(DeclRefExprClass, Empty) { }
+
+  /// \brief Computes the type- and value-dependence flags for this
+  /// declaration reference expression.
+  void computeDependence(const ASTContext &C);
+
+public:
+  DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T,
+              ExprValueKind VK, SourceLocation L,
+              const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
+    : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
+      D(D), Loc(L), DNLoc(LocInfo) {
+    DeclRefExprBits.HasQualifier = 0;
+    DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
+    DeclRefExprBits.HasFoundDecl = 0;
+    DeclRefExprBits.HadMultipleCandidates = 0;
+    DeclRefExprBits.RefersToEnclosingLocal = refersToEnclosingLocal;
+    computeDependence(D->getASTContext());
+  }
+
+  static DeclRefExpr *
+  Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+         SourceLocation NameLoc, QualType T, ExprValueKind VK,
+         NamedDecl *FoundD = nullptr,
+         const TemplateArgumentListInfo *TemplateArgs = nullptr);
+
+  static DeclRefExpr *
+  Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+         const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+         NamedDecl *FoundD = nullptr,
+         const TemplateArgumentListInfo *TemplateArgs = nullptr);
+
+  /// \brief Construct an empty declaration reference expression.
+  static DeclRefExpr *CreateEmpty(const ASTContext &Context,
+                                  bool HasQualifier,
+                                  bool HasFoundDecl,
+                                  bool HasTemplateKWAndArgsInfo,
+                                  unsigned NumTemplateArgs);
+
+  ValueDecl *getDecl() { return D; }
+  const ValueDecl *getDecl() const { return D; }
+  void setDecl(ValueDecl *NewD) { D = NewD; }
+
+  DeclarationNameInfo getNameInfo() const {
+    return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
+  }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  /// \brief Determine whether this declaration reference was preceded by a
+  /// C++ nested-name-specifier, e.g., \c N::foo.
+  bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
+
+  /// \brief If the name was qualified, retrieves the nested-name-specifier
+  /// that precedes the name. Otherwise, returns NULL.
+  NestedNameSpecifier *getQualifier() const {
+    if (!hasQualifier())
+      return nullptr;
+
+    return getInternalQualifierLoc().getNestedNameSpecifier();
+  }
+
+  /// \brief If the name was qualified, retrieves the nested-name-specifier
+  /// that precedes the name, with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    if (!hasQualifier())
+      return NestedNameSpecifierLoc();
+
+    return getInternalQualifierLoc();
+  }
+
+  /// \brief Get the NamedDecl through which this reference occurred.
+  ///
+  /// This Decl may be different from the ValueDecl actually referred to in the
+  /// presence of using declarations, etc. It always returns non-NULL, and may
+  /// simple return the ValueDecl when appropriate.
+  NamedDecl *getFoundDecl() {
+    return hasFoundDecl() ? getInternalFoundDecl() : D;
+  }
+
+  /// \brief Get the NamedDecl through which this reference occurred.
+  /// See non-const variant.
+  const NamedDecl *getFoundDecl() const {
+    return hasFoundDecl() ? getInternalFoundDecl() : D;
+  }
+
+  bool hasTemplateKWAndArgsInfo() const {
+    return DeclRefExprBits.HasTemplateKWAndArgsInfo;
+  }
+
+  /// \brief Return the optional template keyword and arguments info.
+  ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
+    if (!hasTemplateKWAndArgsInfo())
+      return nullptr;
+
+    if (hasFoundDecl())
+      return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
+        &getInternalFoundDecl() + 1);
+
+    if (hasQualifier())
+      return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
+        &getInternalQualifierLoc() + 1);
+
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
+  }
+
+  /// \brief Return the optional template keyword and arguments info.
+  const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
+    return const_cast<DeclRefExpr*>(this)->getTemplateKWAndArgsInfo();
+  }
+
+  /// \brief Retrieve the location of the template keyword preceding
+  /// this name, if any.
+  SourceLocation getTemplateKeywordLoc() const {
+    if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc();
+  }
+
+  /// \brief Retrieve the location of the left angle bracket starting the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getLAngleLoc() const {
+    if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket ending the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getRAngleLoc() const {
+    if (!hasTemplateKWAndArgsInfo()) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->RAngleLoc;
+  }
+
+  /// \brief Determines whether the name in this declaration reference
+  /// was preceded by the template keyword.
+  bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+
+  /// \brief Determines whether this declaration reference was followed by an
+  /// explicit template argument list.
+  bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name.
+  ASTTemplateArgumentListInfo &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *getTemplateKWAndArgsInfo();
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name.
+  const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const {
+    return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return nullptr;
+    return &getExplicitTemplateArgs();
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    if (hasExplicitTemplateArgs())
+      getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    if (!hasExplicitTemplateArgs())
+      return nullptr;
+
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    if (!hasExplicitTemplateArgs())
+      return 0;
+
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  /// \brief Returns true if this expression refers to a function that
+  /// was resolved from an overloaded set having size greater than 1.
+  bool hadMultipleCandidates() const {
+    return DeclRefExprBits.HadMultipleCandidates;
+  }
+  /// \brief Sets the flag telling whether this expression refers to
+  /// a function that was resolved from an overloaded set having size
+  /// greater than 1.
+  void setHadMultipleCandidates(bool V = true) {
+    DeclRefExprBits.HadMultipleCandidates = V;
+  }
+
+  /// Does this DeclRefExpr refer to a local declaration from an
+  /// enclosing function scope?
+  bool refersToEnclosingLocal() const {
+    return DeclRefExprBits.RefersToEnclosingLocal;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DeclRefExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
+class PredefinedExpr : public Expr {
+public:
+  enum IdentType {
+    Func,
+    Function,
+    LFunction,  // Same as Function, but as wide string.
+    FuncDName,
+    FuncSig,
+    PrettyFunction,
+    /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+    /// 'virtual' keyword is omitted for virtual member functions.
+    PrettyFunctionNoVirtual
+  };
+
+private:
+  SourceLocation Loc;
+  IdentType Type;
+public:
+  PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
+    : Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
+           type->isDependentType(), type->isDependentType(),
+           type->isInstantiationDependentType(),
+           /*ContainsUnexpandedParameterPack=*/false),
+      Loc(l), Type(IT) {}
+
+  /// \brief Construct an empty predefined expression.
+  explicit PredefinedExpr(EmptyShell Empty)
+    : Expr(PredefinedExprClass, Empty) { }
+
+  IdentType getIdentType() const { return Type; }
+  void setIdentType(IdentType IT) { Type = IT; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == PredefinedExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief Used by IntegerLiteral/FloatingLiteral to store the numeric without
+/// leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers.  Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+  union {
+    uint64_t VAL;    ///< Used to store the <= 64 bits integer value.
+    uint64_t *pVal;  ///< Used to store the >64 bits integer value.
+  };
+  unsigned BitWidth;
+
+  bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+  APNumericStorage(const APNumericStorage &) LLVM_DELETED_FUNCTION;
+  void operator=(const APNumericStorage &) LLVM_DELETED_FUNCTION;
+
+protected:
+  APNumericStorage() : VAL(0), BitWidth(0) { }
+
+  llvm::APInt getIntValue() const {
+    unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+    if (NumWords > 1)
+      return llvm::APInt(BitWidth, NumWords, pVal);
+    else
+      return llvm::APInt(BitWidth, VAL);
+  }
+  void setIntValue(const ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : private APNumericStorage {
+public:
+  llvm::APInt getValue() const { return getIntValue(); }
+  void setValue(const ASTContext &C, const llvm::APInt &Val) {
+    setIntValue(C, Val);
+  }
+};
+
+class APFloatStorage : private APNumericStorage {
+public:
+  llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
+    return llvm::APFloat(Semantics, getIntValue());
+  }
+  void setValue(const ASTContext &C, const llvm::APFloat &Val) {
+    setIntValue(C, Val.bitcastToAPInt());
+  }
+};
+
+class IntegerLiteral : public Expr, public APIntStorage {
+  SourceLocation Loc;
+
+  /// \brief Construct an empty integer literal.
+  explicit IntegerLiteral(EmptyShell Empty)
+    : Expr(IntegerLiteralClass, Empty) { }
+
+public:
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+  // or UnsignedLongLongTy
+  IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
+                 SourceLocation l);
+
+  /// \brief Returns a new integer literal with value 'V' and type 'type'.
+  /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
+  /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
+  /// \param V - the value that the returned integer literal contains.
+  static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V,
+                                QualType type, SourceLocation l);
+  /// \brief Returns a new empty integer literal.
+  static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  /// \brief Retrieve the location of the literal.
+  SourceLocation getLocation() const { return Loc; }
+
+  void setLocation(SourceLocation Location) { Loc = Location; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IntegerLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+class CharacterLiteral : public Expr {
+public:
+  enum CharacterKind {
+    Ascii,
+    Wide,
+    UTF16,
+    UTF32
+  };
+
+private:
+  unsigned Value;
+  SourceLocation Loc;
+public:
+  // type should be IntTy
+  CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
+                   SourceLocation l)
+    : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
+           false, false),
+      Value(value), Loc(l) {
+    CharacterLiteralBits.Kind = kind;
+  }
+
+  /// \brief Construct an empty character literal.
+  CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
+
+  SourceLocation getLocation() const { return Loc; }
+  CharacterKind getKind() const {
+    return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  unsigned getValue() const { return Value; }
+
+  void setLocation(SourceLocation Location) { Loc = Location; }
+  void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; }
+  void setValue(unsigned Val) { Value = Val; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CharacterLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+class FloatingLiteral : public Expr, private APFloatStorage {
+  SourceLocation Loc;
+
+  FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
+                  QualType Type, SourceLocation L);
+
+  /// \brief Construct an empty floating-point literal.
+  explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
+
+public:
+  static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V,
+                                 bool isexact, QualType Type, SourceLocation L);
+  static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty);
+
+  llvm::APFloat getValue() const {
+    return APFloatStorage::getValue(getSemantics());
+  }
+  void setValue(const ASTContext &C, const llvm::APFloat &Val) {
+    assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
+    APFloatStorage::setValue(C, Val);
+  }
+
+  /// Get a raw enumeration value representing the floating-point semantics of
+  /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
+  APFloatSemantics getRawSemantics() const {
+    return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics);
+  }
+
+  /// Set the raw enumeration value representing the floating-point semantics of
+  /// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
+  void setRawSemantics(APFloatSemantics Sem) {
+    FloatingLiteralBits.Semantics = Sem;
+  }
+
+  /// Return the APFloat semantics this literal uses.
+  const llvm::fltSemantics &getSemantics() const;
+
+  /// Set the APFloat semantics this literal uses.
+  void setSemantics(const llvm::fltSemantics &Sem);
+
+  bool isExact() const { return FloatingLiteralBits.IsExact; }
+  void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
+
+  /// getValueAsApproximateDouble - This returns the value as an inaccurate
+  /// double.  Note that this may cause loss of precision, but is useful for
+  /// debugging dumps, etc.
+  double getValueAsApproximateDouble() const;
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == FloatingLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// ImaginaryLiteral - We support imaginary integer and floating point literals,
+/// like "1.0i".  We represent these as a wrapper around FloatingLiteral and
+/// IntegerLiteral classes.  Instances of this class always have a Complex type
+/// whose element type matches the subexpression.
+///
+class ImaginaryLiteral : public Expr {
+  Stmt *Val;
+public:
+  ImaginaryLiteral(Expr *val, QualType Ty)
+    : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
+           false, false),
+      Val(val) {}
+
+  /// \brief Build an empty imaginary literal.
+  explicit ImaginaryLiteral(EmptyShell Empty)
+    : Expr(ImaginaryLiteralClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Val->getLocStart(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Val->getLocEnd(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImaginaryLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Val, &Val+1); }
+};
+
+/// StringLiteral - This represents a string literal expression, e.g. "foo"
+/// or L"bar" (wide strings).  The actual string is returned by getBytes()
+/// is NOT null-terminated, and the length of the string is determined by
+/// calling getByteLength().  The C type for a string is always a
+/// ConstantArrayType.  In C++, the char type is const qualified, in C it is
+/// not.
+///
+/// Note that strings in C can be formed by concatenation of multiple string
+/// literal pptokens in translation phase #6.  This keeps track of the locations
+/// of each of these pieces.
+///
+/// Strings in C can also be truncated and extended by assigning into arrays,
+/// e.g. with constructs like:
+///   char X[2] = "foobar";
+/// In this case, getByteLength() will return 6, but the string literal will
+/// have type "char[2]".
+class StringLiteral : public Expr {
+public:
+  enum StringKind {
+    Ascii,
+    Wide,
+    UTF8,
+    UTF16,
+    UTF32
+  };
+
+private:
+  friend class ASTStmtReader;
+
+  union {
+    const char *asChar;
+    const uint16_t *asUInt16;
+    const uint32_t *asUInt32;
+  } StrData;
+  unsigned Length;
+  unsigned CharByteWidth : 4;
+  unsigned Kind : 3;
+  unsigned IsPascal : 1;
+  unsigned NumConcatenated;
+  SourceLocation TokLocs[1];
+
+  StringLiteral(QualType Ty) :
+    Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
+         false) {}
+
+  static int mapCharByteWidth(TargetInfo const &target,StringKind k);
+
+public:
+  /// This is the "fully general" constructor that allows representation of
+  /// strings formed from multiple concatenated tokens.
+  static StringLiteral *Create(const ASTContext &C, StringRef Str,
+                               StringKind Kind, bool Pascal, QualType Ty,
+                               const SourceLocation *Loc, unsigned NumStrs);
+
+  /// Simple constructor for string literals made from one token.
+  static StringLiteral *Create(const ASTContext &C, StringRef Str,
+                               StringKind Kind, bool Pascal, QualType Ty,
+                               SourceLocation Loc) {
+    return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
+  }
+
+  /// \brief Construct an empty string literal.
+  static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
+
+  StringRef getString() const {
+    assert(CharByteWidth==1
+           && "This function is used in places that assume strings use char");
+    return StringRef(StrData.asChar, getByteLength());
+  }
+
+  /// Allow access to clients that need the byte representation, such as
+  /// ASTWriterStmt::VisitStringLiteral().
+  StringRef getBytes() const {
+    // FIXME: StringRef may not be the right type to use as a result for this.
+    if (CharByteWidth == 1)
+      return StringRef(StrData.asChar, getByteLength());
+    if (CharByteWidth == 4)
+      return StringRef(reinterpret_cast<const char*>(StrData.asUInt32),
+                       getByteLength());
+    assert(CharByteWidth == 2 && "unsupported CharByteWidth");
+    return StringRef(reinterpret_cast<const char*>(StrData.asUInt16),
+                     getByteLength());
+  }
+
+  void outputString(raw_ostream &OS) const;
+
+  uint32_t getCodeUnit(size_t i) const {
+    assert(i < Length && "out of bounds access");
+    if (CharByteWidth == 1)
+      return static_cast<unsigned char>(StrData.asChar[i]);
+    if (CharByteWidth == 4)
+      return StrData.asUInt32[i];
+    assert(CharByteWidth == 2 && "unsupported CharByteWidth");
+    return StrData.asUInt16[i];
+  }
+
+  unsigned getByteLength() const { return CharByteWidth*Length; }
+  unsigned getLength() const { return Length; }
+  unsigned getCharByteWidth() const { return CharByteWidth; }
+
+  /// \brief Sets the string data to the given string data.
+  void setString(const ASTContext &C, StringRef Str,
+                 StringKind Kind, bool IsPascal);
+
+  StringKind getKind() const { return static_cast<StringKind>(Kind); }
+
+
+  bool isAscii() const { return Kind == Ascii; }
+  bool isWide() const { return Kind == Wide; }
+  bool isUTF8() const { return Kind == UTF8; }
+  bool isUTF16() const { return Kind == UTF16; }
+  bool isUTF32() const { return Kind == UTF32; }
+  bool isPascal() const { return IsPascal; }
+
+  bool containsNonAsciiOrNull() const {
+    StringRef Str = getString();
+    for (unsigned i = 0, e = Str.size(); i != e; ++i)
+      if (!isASCII(Str[i]) || !Str[i])
+        return true;
+    return false;
+  }
+
+  /// getNumConcatenated - Get the number of string literal tokens that were
+  /// concatenated in translation phase #6 to form this string literal.
+  unsigned getNumConcatenated() const { return NumConcatenated; }
+
+  SourceLocation getStrTokenLoc(unsigned TokNum) const {
+    assert(TokNum < NumConcatenated && "Invalid tok number");
+    return TokLocs[TokNum];
+  }
+  void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
+    assert(TokNum < NumConcatenated && "Invalid tok number");
+    TokLocs[TokNum] = L;
+  }
+
+  /// getLocationOfByte - Return a source location that points to the specified
+  /// byte of this string literal.
+  ///
+  /// Strings are amazingly complex.  They can be formed from multiple tokens
+  /// and can have escape sequences in them in addition to the usual trigraph
+  /// and escaped newline business.  This routine handles this complexity.
+  ///
+  SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM,
+                                   const LangOptions &Features,
+                                   const TargetInfo &Target) const;
+
+  typedef const SourceLocation *tokloc_iterator;
+  tokloc_iterator tokloc_begin() const { return TokLocs; }
+  tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return TokLocs[NumConcatenated - 1];
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == StringLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// ParenExpr - This represents a parethesized expression, e.g. "(1)".  This
+/// AST node is only formed if full location information is requested.
+class ParenExpr : public Expr {
+  SourceLocation L, R;
+  Stmt *Val;
+public:
+  ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
+    : Expr(ParenExprClass, val->getType(),
+           val->getValueKind(), val->getObjectKind(),
+           val->isTypeDependent(), val->isValueDependent(),
+           val->isInstantiationDependent(),
+           val->containsUnexpandedParameterPack()),
+      L(l), R(r), Val(val) {}
+
+  /// \brief Construct an empty parenthesized expression.
+  explicit ParenExpr(EmptyShell Empty)
+    : Expr(ParenExprClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return L; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return R; }
+
+  /// \brief Get the location of the left parentheses '('.
+  SourceLocation getLParen() const { return L; }
+  void setLParen(SourceLocation Loc) { L = Loc; }
+
+  /// \brief Get the location of the right parentheses ')'.
+  SourceLocation getRParen() const { return R; }
+  void setRParen(SourceLocation Loc) { R = Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ParenExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Val, &Val+1); }
+};
+
+
+/// UnaryOperator - This represents the unary-expression's (except sizeof and
+/// alignof), the postinc/postdec operators from postfix-expression, and various
+/// extensions.
+///
+/// Notes on various nodes:
+///
+/// Real/Imag - These return the real/imag part of a complex operand.  If
+///   applied to a non-complex value, the former returns its operand and the
+///   later returns zero in the type of the operand.
+///
+class UnaryOperator : public Expr {
+public:
+  typedef UnaryOperatorKind Opcode;
+
+private:
+  unsigned Opc : 5;
+  SourceLocation Loc;
+  Stmt *Val;
+public:
+
+  UnaryOperator(Expr *input, Opcode opc, QualType type,
+                ExprValueKind VK, ExprObjectKind OK, SourceLocation l)
+    : Expr(UnaryOperatorClass, type, VK, OK,
+           input->isTypeDependent() || type->isDependentType(),
+           input->isValueDependent(),
+           (input->isInstantiationDependent() ||
+            type->isInstantiationDependentType()),
+           input->containsUnexpandedParameterPack()),
+      Opc(opc), Loc(l), Val(input) {}
+
+  /// \brief Build an empty unary operator.
+  explicit UnaryOperator(EmptyShell Empty)
+    : Expr(UnaryOperatorClass, Empty), Opc(UO_AddrOf) { }
+
+  Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
+  void setOpcode(Opcode O) { Opc = O; }
+
+  Expr *getSubExpr() const { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  /// getOperatorLoc - Return the location of the operator.
+  SourceLocation getOperatorLoc() const { return Loc; }
+  void setOperatorLoc(SourceLocation L) { Loc = L; }
+
+  /// isPostfix - Return true if this is a postfix operation, like x++.
+  static bool isPostfix(Opcode Op) {
+    return Op == UO_PostInc || Op == UO_PostDec;
+  }
+
+  /// isPrefix - Return true if this is a prefix operation, like --x.
+  static bool isPrefix(Opcode Op) {
+    return Op == UO_PreInc || Op == UO_PreDec;
+  }
+
+  bool isPrefix() const { return isPrefix(getOpcode()); }
+  bool isPostfix() const { return isPostfix(getOpcode()); }
+
+  static bool isIncrementOp(Opcode Op) {
+    return Op == UO_PreInc || Op == UO_PostInc;
+  }
+  bool isIncrementOp() const {
+    return isIncrementOp(getOpcode());
+  }
+
+  static bool isDecrementOp(Opcode Op) {
+    return Op == UO_PreDec || Op == UO_PostDec;
+  }
+  bool isDecrementOp() const {
+    return isDecrementOp(getOpcode());
+  }
+
+  static bool isIncrementDecrementOp(Opcode Op) { return Op <= UO_PreDec; }
+  bool isIncrementDecrementOp() const {
+    return isIncrementDecrementOp(getOpcode());
+  }
+
+  static bool isArithmeticOp(Opcode Op) {
+    return Op >= UO_Plus && Op <= UO_LNot;
+  }
+  bool isArithmeticOp() const { return isArithmeticOp(getOpcode()); }
+
+  /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+  /// corresponds to, e.g. "sizeof" or "[pre]++"
+  static StringRef getOpcodeStr(Opcode Op);
+
+  /// \brief Retrieve the unary opcode that corresponds to the given
+  /// overloaded operator.
+  static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix);
+
+  /// \brief Retrieve the overloaded operator kind that corresponds to
+  /// the given unary opcode.
+  static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return isPostfix() ? Val->getLocStart() : Loc;
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return isPostfix() ? Loc : Val->getLocEnd();
+  }
+  SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnaryOperatorClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Val, &Val+1); }
+};
+
+/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
+/// offsetof(record-type, member-designator). For example, given:
+/// @code
+/// struct S {
+///   float f;
+///   double d;
+/// };
+/// struct T {
+///   int i;
+///   struct S s[10];
+/// };
+/// @endcode
+/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
+
+class OffsetOfExpr : public Expr {
+public:
+  // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+  class OffsetOfNode {
+  public:
+    /// \brief The kind of offsetof node we have.
+    enum Kind {
+      /// \brief An index into an array.
+      Array = 0x00,
+      /// \brief A field.
+      Field = 0x01,
+      /// \brief A field in a dependent type, known only by its name.
+      Identifier = 0x02,
+      /// \brief An implicit indirection through a C++ base class, when the
+      /// field found is in a base class.
+      Base = 0x03
+    };
+
+  private:
+    enum { MaskBits = 2, Mask = 0x03 };
+
+    /// \brief The source range that covers this part of the designator.
+    SourceRange Range;
+
+    /// \brief The data describing the designator, which comes in three
+    /// different forms, depending on the lower two bits.
+    ///   - An unsigned index into the array of Expr*'s stored after this node
+    ///     in memory, for [constant-expression] designators.
+    ///   - A FieldDecl*, for references to a known field.
+    ///   - An IdentifierInfo*, for references to a field with a given name
+    ///     when the class type is dependent.
+    ///   - A CXXBaseSpecifier*, for references that look at a field in a
+    ///     base class.
+    uintptr_t Data;
+
+  public:
+    /// \brief Create an offsetof node that refers to an array element.
+    OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
+                 SourceLocation RBracketLoc)
+      : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { }
+
+    /// \brief Create an offsetof node that refers to a field.
+    OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field,
+                 SourceLocation NameLoc)
+      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
+        Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { }
+
+    /// \brief Create an offsetof node that refers to an identifier.
+    OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
+                 SourceLocation NameLoc)
+      : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
+        Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { }
+
+    /// \brief Create an offsetof node that refers into a C++ base class.
+    explicit OffsetOfNode(const CXXBaseSpecifier *Base)
+      : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
+
+    /// \brief Determine what kind of offsetof node this is.
+    Kind getKind() const {
+      return static_cast<Kind>(Data & Mask);
+    }
+
+    /// \brief For an array element node, returns the index into the array
+    /// of expressions.
+    unsigned getArrayExprIndex() const {
+      assert(getKind() == Array);
+      return Data >> 2;
+    }
+
+    /// \brief For a field offsetof node, returns the field.
+    FieldDecl *getField() const {
+      assert(getKind() == Field);
+      return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
+    }
+
+    /// \brief For a field or identifier offsetof node, returns the name of
+    /// the field.
+    IdentifierInfo *getFieldName() const;
+
+    /// \brief For a base class node, returns the base specifier.
+    CXXBaseSpecifier *getBase() const {
+      assert(getKind() == Base);
+      return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
+    }
+
+    /// \brief Retrieve the source range that covers this offsetof node.
+    ///
+    /// For an array element node, the source range contains the locations of
+    /// the square brackets. For a field or identifier node, the source range
+    /// contains the location of the period (if there is one) and the
+    /// identifier.
+    SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+    SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+    SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  };
+
+private:
+
+  SourceLocation OperatorLoc, RParenLoc;
+  // Base type;
+  TypeSourceInfo *TSInfo;
+  // Number of sub-components (i.e. instances of OffsetOfNode).
+  unsigned NumComps;
+  // Number of sub-expressions (i.e. array subscript expressions).
+  unsigned NumExprs;
+
+  OffsetOfExpr(const ASTContext &C, QualType type,
+               SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+               ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
+               SourceLocation RParenLoc);
+
+  explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
+    : Expr(OffsetOfExprClass, EmptyShell()),
+      TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
+
+public:
+
+  static OffsetOfExpr *Create(const ASTContext &C, QualType type,
+                              SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+                              ArrayRef<OffsetOfNode> comps,
+                              ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
+
+  static OffsetOfExpr *CreateEmpty(const ASTContext &C,
+                                   unsigned NumComps, unsigned NumExprs);
+
+  /// getOperatorLoc - Return the location of the operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+  void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+  /// \brief Return the location of the right parentheses.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation R) { RParenLoc = R; }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TSInfo;
+  }
+  void setTypeSourceInfo(TypeSourceInfo *tsi) {
+    TSInfo = tsi;
+  }
+
+  const OffsetOfNode &getComponent(unsigned Idx) const {
+    assert(Idx < NumComps && "Subscript out of range");
+    return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx];
+  }
+
+  void setComponent(unsigned Idx, OffsetOfNode ON) {
+    assert(Idx < NumComps && "Subscript out of range");
+    reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
+  }
+
+  unsigned getNumComponents() const {
+    return NumComps;
+  }
+
+  Expr* getIndexExpr(unsigned Idx) {
+    assert(Idx < NumExprs && "Subscript out of range");
+    return reinterpret_cast<Expr **>(
+                    reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
+  }
+  const Expr *getIndexExpr(unsigned Idx) const {
+    return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx);
+  }
+
+  void setIndexExpr(unsigned Idx, Expr* E) {
+    assert(Idx < NumComps && "Subscript out of range");
+    reinterpret_cast<Expr **>(
+                reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
+  }
+
+  unsigned getNumExpressions() const {
+    return NumExprs;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OffsetOfExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    Stmt **begin =
+      reinterpret_cast<Stmt**>(reinterpret_cast<OffsetOfNode*>(this + 1)
+                               + NumComps);
+    return child_range(begin, begin + NumExprs);
+  }
+};
+
+/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
+/// expression operand.  Used for sizeof/alignof (C99 6.5.3.4) and
+/// vec_step (OpenCL 1.1 6.11.12).
+class UnaryExprOrTypeTraitExpr : public Expr {
+  union {
+    TypeSourceInfo *Ty;
+    Stmt *Ex;
+  } Argument;
+  SourceLocation OpLoc, RParenLoc;
+
+public:
+  UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
+                           QualType resultType, SourceLocation op,
+                           SourceLocation rp) :
+      Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+           false, // Never type-dependent (C++ [temp.dep.expr]p3).
+           // Value-dependent if the argument is type-dependent.
+           TInfo->getType()->isDependentType(),
+           TInfo->getType()->isInstantiationDependentType(),
+           TInfo->getType()->containsUnexpandedParameterPack()),
+      OpLoc(op), RParenLoc(rp) {
+    UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
+    UnaryExprOrTypeTraitExprBits.IsType = true;
+    Argument.Ty = TInfo;
+  }
+
+  UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
+                           QualType resultType, SourceLocation op,
+                           SourceLocation rp) :
+      Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+           false, // Never type-dependent (C++ [temp.dep.expr]p3).
+           // Value-dependent if the argument is type-dependent.
+           E->isTypeDependent(),
+           E->isInstantiationDependent(),
+           E->containsUnexpandedParameterPack()),
+      OpLoc(op), RParenLoc(rp) {
+    UnaryExprOrTypeTraitExprBits.Kind = ExprKind;
+    UnaryExprOrTypeTraitExprBits.IsType = false;
+    Argument.Ex = E;
+  }
+
+  /// \brief Construct an empty sizeof/alignof expression.
+  explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
+    : Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
+
+  UnaryExprOrTypeTrait getKind() const {
+    return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind);
+  }
+  void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;}
+
+  bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; }
+  QualType getArgumentType() const {
+    return getArgumentTypeInfo()->getType();
+  }
+  TypeSourceInfo *getArgumentTypeInfo() const {
+    assert(isArgumentType() && "calling getArgumentType() when arg is expr");
+    return Argument.Ty;
+  }
+  Expr *getArgumentExpr() {
+    assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
+    return static_cast<Expr*>(Argument.Ex);
+  }
+  const Expr *getArgumentExpr() const {
+    return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
+  }
+
+  void setArgument(Expr *E) {
+    Argument.Ex = E;
+    UnaryExprOrTypeTraitExprBits.IsType = false;
+  }
+  void setArgument(TypeSourceInfo *TInfo) {
+    Argument.Ty = TInfo;
+    UnaryExprOrTypeTraitExprBits.IsType = true;
+  }
+
+  /// Gets the argument type, or the type of the argument expression, whichever
+  /// is appropriate.
+  QualType getTypeOfArgument() const {
+    return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType();
+  }
+
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return OpLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
+  }
+
+  // Iterators
+  child_range children();
+};
+
+//===----------------------------------------------------------------------===//
+// Postfix Operators.
+//===----------------------------------------------------------------------===//
+
+/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
+class ArraySubscriptExpr : public Expr {
+  enum { LHS, RHS, END_EXPR=2 };
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation RBracketLoc;
+public:
+  ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
+                     ExprValueKind VK, ExprObjectKind OK,
+                     SourceLocation rbracketloc)
+  : Expr(ArraySubscriptExprClass, t, VK, OK,
+         lhs->isTypeDependent() || rhs->isTypeDependent(),
+         lhs->isValueDependent() || rhs->isValueDependent(),
+         (lhs->isInstantiationDependent() ||
+          rhs->isInstantiationDependent()),
+         (lhs->containsUnexpandedParameterPack() ||
+          rhs->containsUnexpandedParameterPack())),
+    RBracketLoc(rbracketloc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  /// \brief Create an empty array subscript expression.
+  explicit ArraySubscriptExpr(EmptyShell Shell)
+    : Expr(ArraySubscriptExprClass, Shell) { }
+
+  /// An array access can be written A[4] or 4[A] (both are equivalent).
+  /// - getBase() and getIdx() always present the normalized view: A[4].
+  ///    In this case getBase() returns "A" and getIdx() returns "4".
+  /// - getLHS() and getRHS() present the syntactic view. e.g. for
+  ///    4[A] getLHS() returns "4".
+  /// Note: Because vector element access is also written A[4] we must
+  /// predicate the format conversion in getBase and getIdx only on the
+  /// the type of the RHS, as it is possible for the LHS to be a vector of
+  /// integer type
+  Expr *getLHS() { return cast<Expr>(SubExprs[LHS]); }
+  const Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+
+  Expr *getRHS() { return cast<Expr>(SubExprs[RHS]); }
+  const Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  Expr *getBase() {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+  }
+
+  const Expr *getBase() const {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getLHS():getRHS());
+  }
+
+  Expr *getIdx() {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+  }
+
+  const Expr *getIdx() const {
+    return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getLHS()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; }
+
+  SourceLocation getRBracketLoc() const { return RBracketLoc; }
+  void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
+
+  SourceLocation getExprLoc() const LLVM_READONLY {
+    return getBase()->getExprLoc();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ArraySubscriptExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+
+/// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
+/// CallExpr itself represents a normal function call, e.g., "f(x, 2)",
+/// while its subclasses may represent alternative syntax that (semantically)
+/// results in a function call. For example, CXXOperatorCallExpr is
+/// a subclass for overloaded operator calls that use operator syntax, e.g.,
+/// "str1 + str2" to resolve to a function call.
+class CallExpr : public Expr {
+  enum { FN=0, PREARGS_START=1 };
+  Stmt **SubExprs;
+  unsigned NumArgs;
+  SourceLocation RParenLoc;
+
+protected:
+  // These versions of the constructor are for derived classes.
+  CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
+           ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
+           SourceLocation rparenloc);
+  CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
+           EmptyShell Empty);
+
+  Stmt *getPreArg(unsigned i) {
+    assert(i < getNumPreArgs() && "Prearg access out of range!");
+    return SubExprs[PREARGS_START+i];
+  }
+  const Stmt *getPreArg(unsigned i) const {
+    assert(i < getNumPreArgs() && "Prearg access out of range!");
+    return SubExprs[PREARGS_START+i];
+  }
+  void setPreArg(unsigned i, Stmt *PreArg) {
+    assert(i < getNumPreArgs() && "Prearg access out of range!");
+    SubExprs[PREARGS_START+i] = PreArg;
+  }
+
+  unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
+
+public:
+  CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
+           ExprValueKind VK, SourceLocation rparenloc);
+
+  /// \brief Build an empty call expression.
+  CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
+
+  const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
+  Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
+  void setCallee(Expr *F) { SubExprs[FN] = F; }
+
+  Decl *getCalleeDecl();
+  const Decl *getCalleeDecl() const {
+    return const_cast<CallExpr*>(this)->getCalleeDecl();
+  }
+
+  /// \brief If the callee is a FunctionDecl, return it. Otherwise return 0.
+  FunctionDecl *getDirectCallee();
+  const FunctionDecl *getDirectCallee() const {
+    return const_cast<CallExpr*>(this)->getDirectCallee();
+  }
+
+  /// getNumArgs - Return the number of actual arguments to this call.
+  ///
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Retrieve the call arguments.
+  Expr **getArgs() {
+    return reinterpret_cast<Expr **>(SubExprs+getNumPreArgs()+PREARGS_START);
+  }
+  const Expr *const *getArgs() const {
+    return const_cast<CallExpr*>(this)->getArgs();
+  }
+
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Arg+getNumPreArgs()+PREARGS_START]);
+  }
+
+  /// setArg - Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    SubExprs[Arg+getNumPreArgs()+PREARGS_START] = ArgExpr;
+  }
+
+  /// setNumArgs - This changes the number of arguments present in this call.
+  /// Any orphaned expressions are deleted by this, and any new operands are set
+  /// to null.
+  void setNumArgs(const ASTContext& C, unsigned NumArgs);
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+  typedef llvm::iterator_range<arg_iterator> arg_range;
+  typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+  arg_const_range arguments() const {
+    return arg_const_range(arg_begin(), arg_end());
+  }
+
+  arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
+  arg_iterator arg_end() {
+    return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+  }
+  const_arg_iterator arg_begin() const {
+    return SubExprs+PREARGS_START+getNumPreArgs();
+  }
+  const_arg_iterator arg_end() const {
+    return SubExprs+PREARGS_START+getNumPreArgs()+getNumArgs();
+  }
+
+  /// This method provides fast access to all the subexpressions of
+  /// a CallExpr without going through the slower virtual child_iterator
+  /// interface.  This provides efficient reverse iteration of the
+  /// subexpressions.  This is currently used for CFG construction.
+  ArrayRef<Stmt*> getRawSubExprs() {
+    return ArrayRef<Stmt*>(SubExprs,
+                           getNumPreArgs() + PREARGS_START + getNumArgs());
+  }
+
+  /// getNumCommas - Return the number of commas that must have been present in
+  /// this function call.
+  unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+
+  /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
+  /// of the callee. If not, return 0.
+  unsigned getBuiltinCallee() const;
+
+  /// \brief Returns \c true if this is a call to a builtin which does not
+  /// evaluate side-effects within its arguments.
+  bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
+
+  /// getCallReturnType - Get the return type of the call expr. This is not
+  /// always the type of the expr itself, if the return type is a reference
+  /// type.
+  QualType getCallReturnType() const;
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() >= firstCallExprConstant &&
+           T->getStmtClass() <= lastCallExprConstant;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0],
+                       &SubExprs[0]+NumArgs+getNumPreArgs()+PREARGS_START);
+  }
+};
+
+/// MemberExpr - [C99 6.5.2.3] Structure and Union Members.  X->F and X.F.
+///
+class MemberExpr : public Expr {
+  /// Extra data stored in some member expressions.
+  struct MemberNameQualifier {
+    /// \brief The nested-name-specifier that qualifies the name, including
+    /// source-location information.
+    NestedNameSpecifierLoc QualifierLoc;
+
+    /// \brief The DeclAccessPair through which the MemberDecl was found due to
+    /// name qualifiers.
+    DeclAccessPair FoundDecl;
+  };
+
+  /// Base - the expression for the base pointer or structure references.  In
+  /// X.F, this is "X".
+  Stmt *Base;
+
+  /// MemberDecl - This is the decl being referenced by the field/member name.
+  /// In X.F, this is the decl referenced by F.
+  ValueDecl *MemberDecl;
+
+  /// MemberDNLoc - Provides source/type location info for the
+  /// declaration name embedded in MemberDecl.
+  DeclarationNameLoc MemberDNLoc;
+
+  /// MemberLoc - This is the location of the member name.
+  SourceLocation MemberLoc;
+
+  /// IsArrow - True if this is "X->F", false if this is "X.F".
+  bool IsArrow : 1;
+
+  /// \brief True if this member expression used a nested-name-specifier to
+  /// refer to the member, e.g., "x->Base::f", or found its member via a using
+  /// declaration.  When true, a MemberNameQualifier
+  /// structure is allocated immediately after the MemberExpr.
+  bool HasQualifierOrFoundDecl : 1;
+
+  /// \brief True if this member expression specified a template keyword
+  /// and/or a template argument list explicitly, e.g., x->f<int>,
+  /// x->template f, x->template f<int>.
+  /// When true, an ASTTemplateKWAndArgsInfo structure and its
+  /// TemplateArguments (if any) are allocated immediately after
+  /// the MemberExpr or, if the member expression also has a qualifier,
+  /// after the MemberNameQualifier structure.
+  bool HasTemplateKWAndArgsInfo : 1;
+
+  /// \brief True if this member expression refers to a method that
+  /// was resolved from an overloaded set having size greater than 1.
+  bool HadMultipleCandidates : 1;
+
+  /// \brief Retrieve the qualifier that preceded the member name, if any.
+  MemberNameQualifier *getMemberQualifier() {
+    assert(HasQualifierOrFoundDecl);
+    return reinterpret_cast<MemberNameQualifier *> (this + 1);
+  }
+
+  /// \brief Retrieve the qualifier that preceded the member name, if any.
+  const MemberNameQualifier *getMemberQualifier() const {
+    return const_cast<MemberExpr *>(this)->getMemberQualifier();
+  }
+
+public:
+  MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+             const DeclarationNameInfo &NameInfo, QualType ty,
+             ExprValueKind VK, ExprObjectKind OK)
+    : Expr(MemberExprClass, ty, VK, OK,
+           base->isTypeDependent(),
+           base->isValueDependent(),
+           base->isInstantiationDependent(),
+           base->containsUnexpandedParameterPack()),
+      Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()),
+      MemberLoc(NameInfo.getLoc()), IsArrow(isarrow),
+      HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
+      HadMultipleCandidates(false) {
+    assert(memberdecl->getDeclName() == NameInfo.getName());
+  }
+
+  // NOTE: this constructor should be used only when it is known that
+  // the member name can not provide additional syntactic info
+  // (i.e., source locations for C++ operator names or type source info
+  // for constructors, destructors and conversion operators).
+  MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+             SourceLocation l, QualType ty,
+             ExprValueKind VK, ExprObjectKind OK)
+    : Expr(MemberExprClass, ty, VK, OK,
+           base->isTypeDependent(), base->isValueDependent(),
+           base->isInstantiationDependent(),
+           base->containsUnexpandedParameterPack()),
+      Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l),
+      IsArrow(isarrow),
+      HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
+      HadMultipleCandidates(false) {}
+
+  static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
+                            NestedNameSpecifierLoc QualifierLoc,
+                            SourceLocation TemplateKWLoc,
+                            ValueDecl *memberdecl, DeclAccessPair founddecl,
+                            DeclarationNameInfo MemberNameInfo,
+                            const TemplateArgumentListInfo *targs,
+                            QualType ty, ExprValueKind VK, ExprObjectKind OK);
+
+  void setBase(Expr *E) { Base = E; }
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  /// \brief Retrieve the member declaration to which this expression refers.
+  ///
+  /// The returned declaration will either be a FieldDecl or (in C++)
+  /// a CXXMethodDecl.
+  ValueDecl *getMemberDecl() const { return MemberDecl; }
+  void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
+
+  /// \brief Retrieves the declaration found by lookup.
+  DeclAccessPair getFoundDecl() const {
+    if (!HasQualifierOrFoundDecl)
+      return DeclAccessPair::make(getMemberDecl(),
+                                  getMemberDecl()->getAccess());
+    return getMemberQualifier()->FoundDecl;
+  }
+
+  /// \brief Determines whether this member expression actually had
+  /// a C++ nested-name-specifier prior to the name of the member, e.g.,
+  /// x->Base::foo.
+  bool hasQualifier() const { return getQualifier() != nullptr; }
+
+  /// \brief If the member name was qualified, retrieves the
+  /// nested-name-specifier that precedes the member name. Otherwise, returns
+  /// NULL.
+  NestedNameSpecifier *getQualifier() const {
+    if (!HasQualifierOrFoundDecl)
+      return nullptr;
+
+    return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief If the member name was qualified, retrieves the
+  /// nested-name-specifier that precedes the member name, with source-location
+  /// information.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    if (!hasQualifier())
+      return NestedNameSpecifierLoc();
+
+    return getMemberQualifier()->QualifierLoc;
+  }
+
+  /// \brief Return the optional template keyword and arguments info.
+  ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
+    if (!HasTemplateKWAndArgsInfo)
+      return nullptr;
+
+    if (!HasQualifierOrFoundDecl)
+      return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
+
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
+                                                      getMemberQualifier() + 1);
+  }
+
+  /// \brief Return the optional template keyword and arguments info.
+  const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
+    return const_cast<MemberExpr*>(this)->getTemplateKWAndArgsInfo();
+  }
+
+  /// \brief Retrieve the location of the template keyword preceding
+  /// the member name, if any.
+  SourceLocation getTemplateKeywordLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc();
+  }
+
+  /// \brief Retrieve the location of the left angle bracket starting the
+  /// explicit template argument list following the member name, if any.
+  SourceLocation getLAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket ending the
+  /// explicit template argument list following the member name, if any.
+  SourceLocation getRAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->RAngleLoc;
+  }
+
+  /// Determines whether the member name was preceded by the template keyword.
+  bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+
+  /// \brief Determines whether the member name was followed by an
+  /// explicit template argument list.
+  bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    if (hasExplicitTemplateArgs())
+      getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Retrieve the explicit template argument list that
+  /// follow the member template name.  This must only be called on an
+  /// expression with explicit template arguments.
+  ASTTemplateArgumentListInfo &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *getTemplateKWAndArgsInfo();
+  }
+
+  /// \brief Retrieve the explicit template argument list that
+  /// followed the member template name.  This must only be called on
+  /// an expression with explicit template arguments.
+  const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const {
+    return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return nullptr;
+    return &getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    if (!hasExplicitTemplateArgs())
+      return nullptr;
+
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    if (!hasExplicitTemplateArgs())
+      return 0;
+
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  /// \brief Retrieve the member declaration name info.
+  DeclarationNameInfo getMemberNameInfo() const {
+    return DeclarationNameInfo(MemberDecl->getDeclName(),
+                               MemberLoc, MemberDNLoc);
+  }
+
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// getMemberLoc - Return the location of the "member", in X->F, it is the
+  /// location of 'F'.
+  SourceLocation getMemberLoc() const { return MemberLoc; }
+  void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
+
+  /// \brief Determine whether the base of this explicit is implicit.
+  bool isImplicitAccess() const {
+    return getBase() && getBase()->isImplicitCXXThis();
+  }
+
+  /// \brief Returns true if this member expression refers to a method that
+  /// was resolved from an overloaded set having size greater than 1.
+  bool hadMultipleCandidates() const {
+    return HadMultipleCandidates;
+  }
+  /// \brief Sets the flag telling whether this expression refers to
+  /// a method that was resolved from an overloaded set having size
+  /// greater than 1.
+  void setHadMultipleCandidates(bool V = true) {
+    HadMultipleCandidates = V;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MemberExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Base, &Base+1); }
+
+  friend class ASTReader;
+  friend class ASTStmtWriter;
+};
+
+/// CompoundLiteralExpr - [C99 6.5.2.5]
+///
+class CompoundLiteralExpr : public Expr {
+  /// LParenLoc - If non-null, this is the location of the left paren in a
+  /// compound literal like "(int){4}".  This can be null if this is a
+  /// synthesized compound expression.
+  SourceLocation LParenLoc;
+
+  /// The type as written.  This can be an incomplete array type, in
+  /// which case the actual expression type will be different.
+  /// The int part of the pair stores whether this expr is file scope.
+  llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfoAndScope;
+  Stmt *Init;
+public:
+  CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
+                      QualType T, ExprValueKind VK, Expr *init, bool fileScope)
+    : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
+           tinfo->getType()->isDependentType(),
+           init->isValueDependent(),
+           (init->isInstantiationDependent() ||
+            tinfo->getType()->isInstantiationDependentType()),
+           init->containsUnexpandedParameterPack()),
+      LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {}
+
+  /// \brief Construct an empty compound literal.
+  explicit CompoundLiteralExpr(EmptyShell Empty)
+    : Expr(CompoundLiteralExprClass, Empty) { }
+
+  const Expr *getInitializer() const { return cast<Expr>(Init); }
+  Expr *getInitializer() { return cast<Expr>(Init); }
+  void setInitializer(Expr *E) { Init = E; }
+
+  bool isFileScope() const { return TInfoAndScope.getInt(); }
+  void setFileScope(bool FS) { TInfoAndScope.setInt(FS); }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TInfoAndScope.getPointer();
+  }
+  void setTypeSourceInfo(TypeSourceInfo *tinfo) {
+    TInfoAndScope.setPointer(tinfo);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    // FIXME: Init should never be null.
+    if (!Init)
+      return SourceLocation();
+    if (LParenLoc.isInvalid())
+      return Init->getLocStart();
+    return LParenLoc;
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    // FIXME: Init should never be null.
+    if (!Init)
+      return SourceLocation();
+    return Init->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CompoundLiteralExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Init, &Init+1); }
+};
+
+/// CastExpr - Base class for type casts, including both implicit
+/// casts (ImplicitCastExpr) and explicit casts that have some
+/// representation in the source code (ExplicitCastExpr's derived
+/// classes).
+class CastExpr : public Expr {
+public:
+  typedef clang::CastKind CastKind;
+
+private:
+  Stmt *Op;
+
+  bool CastConsistency() const;
+
+  const CXXBaseSpecifier * const *path_buffer() const {
+    return const_cast<CastExpr*>(this)->path_buffer();
+  }
+  CXXBaseSpecifier **path_buffer();
+
+  void setBasePathSize(unsigned basePathSize) {
+    CastExprBits.BasePathSize = basePathSize;
+    assert(CastExprBits.BasePathSize == basePathSize &&
+           "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
+  }
+
+protected:
+  CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
+           const CastKind kind, Expr *op, unsigned BasePathSize) :
+    Expr(SC, ty, VK, OK_Ordinary,
+         // Cast expressions are type-dependent if the type is
+         // dependent (C++ [temp.dep.expr]p3).
+         ty->isDependentType(),
+         // Cast expressions are value-dependent if the type is
+         // dependent or if the subexpression is value-dependent.
+         ty->isDependentType() || (op && op->isValueDependent()),
+         (ty->isInstantiationDependentType() ||
+          (op && op->isInstantiationDependent())),
+         (ty->containsUnexpandedParameterPack() ||
+          (op && op->containsUnexpandedParameterPack()))),
+    Op(op) {
+    assert(kind != CK_Invalid && "creating cast with invalid cast kind");
+    CastExprBits.Kind = kind;
+    setBasePathSize(BasePathSize);
+    assert(CastConsistency());
+  }
+
+  /// \brief Construct an empty cast.
+  CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
+    : Expr(SC, Empty) {
+    setBasePathSize(BasePathSize);
+  }
+
+public:
+  CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
+  void setCastKind(CastKind K) { CastExprBits.Kind = K; }
+  const char *getCastKindName() const;
+
+  Expr *getSubExpr() { return cast<Expr>(Op); }
+  const Expr *getSubExpr() const { return cast<Expr>(Op); }
+  void setSubExpr(Expr *E) { Op = E; }
+
+  /// \brief Retrieve the cast subexpression as it was written in the source
+  /// code, looking through any implicit casts or other intermediate nodes
+  /// introduced by semantic analysis.
+  Expr *getSubExprAsWritten();
+  const Expr *getSubExprAsWritten() const {
+    return const_cast<CastExpr *>(this)->getSubExprAsWritten();
+  }
+
+  typedef CXXBaseSpecifier **path_iterator;
+  typedef const CXXBaseSpecifier * const *path_const_iterator;
+  bool path_empty() const { return CastExprBits.BasePathSize == 0; }
+  unsigned path_size() const { return CastExprBits.BasePathSize; }
+  path_iterator path_begin() { return path_buffer(); }
+  path_iterator path_end() { return path_buffer() + path_size(); }
+  path_const_iterator path_begin() const { return path_buffer(); }
+  path_const_iterator path_end() const { return path_buffer() + path_size(); }
+
+  void setCastPath(const CXXCastPath &Path);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() >= firstCastExprConstant &&
+           T->getStmtClass() <= lastCastExprConstant;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Op, &Op+1); }
+};
+
+/// ImplicitCastExpr - Allows us to explicitly represent implicit type
+/// conversions, which have no direct representation in the original
+/// source code. For example: converting T[]->T*, void f()->void
+/// (*f)(), float->double, short->int, etc.
+///
+/// In C, implicit casts always produce rvalues. However, in C++, an
+/// implicit cast whose result is being bound to a reference will be
+/// an lvalue or xvalue. For example:
+///
+/// @code
+/// class Base { };
+/// class Derived : public Base { };
+/// Derived &&ref();
+/// void f(Derived d) {
+///   Base& b = d; // initializer is an ImplicitCastExpr
+///                // to an lvalue of type Base
+///   Base&& r = ref(); // initializer is an ImplicitCastExpr
+///                     // to an xvalue of type Base
+/// }
+/// @endcode
+class ImplicitCastExpr : public CastExpr {
+private:
+  ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+                   unsigned BasePathLength, ExprValueKind VK)
+    : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) {
+  }
+
+  /// \brief Construct an empty implicit cast.
+  explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
+    : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
+
+public:
+  enum OnStack_t { OnStack };
+  ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
+                   ExprValueKind VK)
+    : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
+  }
+
+  static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
+                                  CastKind Kind, Expr *Operand,
+                                  const CXXCastPath *BasePath,
+                                  ExprValueKind Cat);
+
+  static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
+                                       unsigned PathSize);
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getSubExpr()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSubExpr()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImplicitCastExprClass;
+  }
+};
+
+inline Expr *Expr::IgnoreImpCasts() {
+  Expr *e = this;
+  while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+    e = ice->getSubExpr();
+  return e;
+}
+
+/// ExplicitCastExpr - An explicit cast written in the source
+/// code.
+///
+/// This class is effectively an abstract class, because it provides
+/// the basic representation of an explicitly-written cast without
+/// specifying which kind of cast (C cast, functional cast, static
+/// cast, etc.) was written; specific derived classes represent the
+/// particular style of cast and its location information.
+///
+/// Unlike implicit casts, explicit cast nodes have two different
+/// types: the type that was written into the source code, and the
+/// actual type of the expression as determined by semantic
+/// analysis. These types may differ slightly. For example, in C++ one
+/// can cast to a reference type, which indicates that the resulting
+/// expression will be an lvalue or xvalue. The reference type, however,
+/// will not be used as the type of the expression.
+class ExplicitCastExpr : public CastExpr {
+  /// TInfo - Source type info for the (written) type
+  /// this expression is casting to.
+  TypeSourceInfo *TInfo;
+
+protected:
+  ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
+                   CastKind kind, Expr *op, unsigned PathSize,
+                   TypeSourceInfo *writtenTy)
+    : CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
+
+  /// \brief Construct an empty explicit cast.
+  ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : CastExpr(SC, Shell, PathSize) { }
+
+public:
+  /// getTypeInfoAsWritten - Returns the type source info for the type
+  /// that this expression is casting to.
+  TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; }
+  void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; }
+
+  /// getTypeAsWritten - Returns the type that this expression is
+  /// casting to, as written in the source code.
+  QualType getTypeAsWritten() const { return TInfo->getType(); }
+
+  static bool classof(const Stmt *T) {
+     return T->getStmtClass() >= firstExplicitCastExprConstant &&
+            T->getStmtClass() <= lastExplicitCastExprConstant;
+  }
+};
+
+/// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style
+/// cast in C++ (C++ [expr.cast]), which uses the syntax
+/// (Type)expr. For example: @c (int)f.
+class CStyleCastExpr : public ExplicitCastExpr {
+  SourceLocation LPLoc; // the location of the left paren
+  SourceLocation RPLoc; // the location of the right paren
+
+  CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
+                 unsigned PathSize, TypeSourceInfo *writtenTy,
+                 SourceLocation l, SourceLocation r)
+    : ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
+                       writtenTy), LPLoc(l), RPLoc(r) {}
+
+  /// \brief Construct an empty C-style explicit cast.
+  explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
+
+public:
+  static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
+                                ExprValueKind VK, CastKind K,
+                                Expr *Op, const CXXCastPath *BasePath,
+                                TypeSourceInfo *WrittenTy, SourceLocation L,
+                                SourceLocation R);
+
+  static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
+                                     unsigned PathSize);
+
+  SourceLocation getLParenLoc() const { return LPLoc; }
+  void setLParenLoc(SourceLocation L) { LPLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RPLoc; }
+  void setRParenLoc(SourceLocation L) { RPLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LPLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSubExpr()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CStyleCastExprClass;
+  }
+};
+
+/// \brief A builtin binary operation expression such as "x + y" or "x <= y".
+///
+/// This expression node kind describes a builtin binary operation,
+/// such as "x + y" for integer values "x" and "y". The operands will
+/// already have been converted to appropriate types (e.g., by
+/// performing promotions or conversions).
+///
+/// In C++, where operators may be overloaded, a different kind of
+/// expression node (CXXOperatorCallExpr) is used to express the
+/// invocation of an overloaded operator with operator syntax. Within
+/// a C++ template, whether BinaryOperator or CXXOperatorCallExpr is
+/// used to store an expression "x + y" depends on the subexpressions
+/// for x and y. If neither x or y is type-dependent, and the "+"
+/// operator resolves to a built-in operation, BinaryOperator will be
+/// used to express the computation (x and y may still be
+/// value-dependent). If either x or y is type-dependent, or if the
+/// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
+/// be used to express the computation.
+class BinaryOperator : public Expr {
+public:
+  typedef BinaryOperatorKind Opcode;
+
+private:
+  unsigned Opc : 6;
+
+  // Records the FP_CONTRACT pragma status at the point that this binary
+  // operator was parsed. This bit is only meaningful for operations on
+  // floating point types. For all other types it should default to
+  // false.
+  unsigned FPContractable : 1;
+  SourceLocation OpLoc;
+
+  enum { LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+public:
+
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+                 ExprValueKind VK, ExprObjectKind OK,
+                 SourceLocation opLoc, bool fpContractable)
+    : Expr(BinaryOperatorClass, ResTy, VK, OK,
+           lhs->isTypeDependent() || rhs->isTypeDependent(),
+           lhs->isValueDependent() || rhs->isValueDependent(),
+           (lhs->isInstantiationDependent() ||
+            rhs->isInstantiationDependent()),
+           (lhs->containsUnexpandedParameterPack() ||
+            rhs->containsUnexpandedParameterPack())),
+      Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+    assert(!isCompoundAssignmentOp() &&
+           "Use CompoundAssignOperator for compound assignments");
+  }
+
+  /// \brief Construct an empty binary operator.
+  explicit BinaryOperator(EmptyShell Empty)
+    : Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
+
+  SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+  Opcode getOpcode() const { return static_cast<Opcode>(Opc); }
+  void setOpcode(Opcode O) { Opc = O; }
+
+  Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getLHS()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getRHS()->getLocEnd();
+  }
+
+  /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+  /// corresponds to, e.g. "<<=".
+  static StringRef getOpcodeStr(Opcode Op);
+
+  StringRef getOpcodeStr() const { return getOpcodeStr(getOpcode()); }
+
+  /// \brief Retrieve the binary opcode that corresponds to the given
+  /// overloaded operator.
+  static Opcode getOverloadedOpcode(OverloadedOperatorKind OO);
+
+  /// \brief Retrieve the overloaded operator kind that corresponds to
+  /// the given binary opcode.
+  static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
+
+  /// predicates to categorize the respective opcodes.
+  bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; }
+  bool isMultiplicativeOp() const { return Opc >= BO_Mul && Opc <= BO_Rem; }
+  static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; }
+  bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); }
+  static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; }
+  bool isShiftOp() const { return isShiftOp(getOpcode()); }
+
+  static bool isBitwiseOp(Opcode Opc) { return Opc >= BO_And && Opc <= BO_Or; }
+  bool isBitwiseOp() const { return isBitwiseOp(getOpcode()); }
+
+  static bool isRelationalOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_GE; }
+  bool isRelationalOp() const { return isRelationalOp(getOpcode()); }
+
+  static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; }
+  bool isEqualityOp() const { return isEqualityOp(getOpcode()); }
+
+  static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; }
+  bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
+
+  static Opcode negateComparisonOp(Opcode Opc) {
+    switch (Opc) {
+    default:
+      llvm_unreachable("Not a comparsion operator.");
+    case BO_LT: return BO_GE;
+    case BO_GT: return BO_LE;
+    case BO_LE: return BO_GT;
+    case BO_GE: return BO_LT;
+    case BO_EQ: return BO_NE;
+    case BO_NE: return BO_EQ;
+    }
+  }
+
+  static Opcode reverseComparisonOp(Opcode Opc) {
+    switch (Opc) {
+    default:
+      llvm_unreachable("Not a comparsion operator.");
+    case BO_LT: return BO_GT;
+    case BO_GT: return BO_LT;
+    case BO_LE: return BO_GE;
+    case BO_GE: return BO_LE;
+    case BO_EQ:
+    case BO_NE:
+      return Opc;
+    }
+  }
+
+  static bool isLogicalOp(Opcode Opc) { return Opc == BO_LAnd || Opc==BO_LOr; }
+  bool isLogicalOp() const { return isLogicalOp(getOpcode()); }
+
+  static bool isAssignmentOp(Opcode Opc) {
+    return Opc >= BO_Assign && Opc <= BO_OrAssign;
+  }
+  bool isAssignmentOp() const { return isAssignmentOp(getOpcode()); }
+
+  static bool isCompoundAssignmentOp(Opcode Opc) {
+    return Opc > BO_Assign && Opc <= BO_OrAssign;
+  }
+  bool isCompoundAssignmentOp() const {
+    return isCompoundAssignmentOp(getOpcode());
+  }
+  static Opcode getOpForCompoundAssignment(Opcode Opc) {
+    assert(isCompoundAssignmentOp(Opc));
+    if (Opc >= BO_AndAssign)
+      return Opcode(unsigned(Opc) - BO_AndAssign + BO_And);
+    else
+      return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul);
+  }
+
+  static bool isShiftAssignOp(Opcode Opc) {
+    return Opc == BO_ShlAssign || Opc == BO_ShrAssign;
+  }
+  bool isShiftAssignOp() const {
+    return isShiftAssignOp(getOpcode());
+  }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() >= firstBinaryOperatorConstant &&
+           S->getStmtClass() <= lastBinaryOperatorConstant;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+
+  // Set the FP contractability status of this operator. Only meaningful for
+  // operations on floating point types.
+  void setFPContractable(bool FPC) { FPContractable = FPC; }
+
+  // Get the FP contractability status of this operator. Only meaningful for
+  // operations on floating point types.
+  bool isFPContractable() const { return FPContractable; }
+
+protected:
+  BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+                 ExprValueKind VK, ExprObjectKind OK,
+                 SourceLocation opLoc, bool fpContractable, bool dead2)
+    : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
+           lhs->isTypeDependent() || rhs->isTypeDependent(),
+           lhs->isValueDependent() || rhs->isValueDependent(),
+           (lhs->isInstantiationDependent() ||
+            rhs->isInstantiationDependent()),
+           (lhs->containsUnexpandedParameterPack() ||
+            rhs->containsUnexpandedParameterPack())),
+      Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  BinaryOperator(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty), Opc(BO_MulAssign) { }
+};
+
+/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
+/// track of the type the operation is performed in.  Due to the semantics of
+/// these operators, the operands are promoted, the arithmetic performed, an
+/// implicit conversion back to the result type done, then the assignment takes
+/// place.  This captures the intermediate type which the computation is done
+/// in.
+class CompoundAssignOperator : public BinaryOperator {
+  QualType ComputationLHSType;
+  QualType ComputationResultType;
+public:
+  CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
+                         ExprValueKind VK, ExprObjectKind OK,
+                         QualType CompLHSType, QualType CompResultType,
+                         SourceLocation OpLoc, bool fpContractable)
+    : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
+                     true),
+      ComputationLHSType(CompLHSType),
+      ComputationResultType(CompResultType) {
+    assert(isCompoundAssignmentOp() &&
+           "Only should be used for compound assignments");
+  }
+
+  /// \brief Build an empty compound assignment operator expression.
+  explicit CompoundAssignOperator(EmptyShell Empty)
+    : BinaryOperator(CompoundAssignOperatorClass, Empty) { }
+
+  // The two computation types are the type the LHS is converted
+  // to for the computation and the type of the result; the two are
+  // distinct in a few cases (specifically, int+=ptr and ptr-=ptr).
+  QualType getComputationLHSType() const { return ComputationLHSType; }
+  void setComputationLHSType(QualType T) { ComputationLHSType = T; }
+
+  QualType getComputationResultType() const { return ComputationResultType; }
+  void setComputationResultType(QualType T) { ComputationResultType = T; }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == CompoundAssignOperatorClass;
+  }
+};
+
+/// AbstractConditionalOperator - An abstract base class for
+/// ConditionalOperator and BinaryConditionalOperator.
+class AbstractConditionalOperator : public Expr {
+  SourceLocation QuestionLoc, ColonLoc;
+  friend class ASTStmtReader;
+
+protected:
+  AbstractConditionalOperator(StmtClass SC, QualType T,
+                              ExprValueKind VK, ExprObjectKind OK,
+                              bool TD, bool VD, bool ID,
+                              bool ContainsUnexpandedParameterPack,
+                              SourceLocation qloc,
+                              SourceLocation cloc)
+    : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
+      QuestionLoc(qloc), ColonLoc(cloc) {}
+
+  AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty) { }
+
+public:
+  // getCond - Return the expression representing the condition for
+  //   the ?: operator.
+  Expr *getCond() const;
+
+  // getTrueExpr - Return the subexpression representing the value of
+  //   the expression if the condition evaluates to true.
+  Expr *getTrueExpr() const;
+
+  // getFalseExpr - Return the subexpression representing the value of
+  //   the expression if the condition evaluates to false.  This is
+  //   the same as getRHS.
+  Expr *getFalseExpr() const;
+
+  SourceLocation getQuestionLoc() const { return QuestionLoc; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConditionalOperatorClass ||
+           T->getStmtClass() == BinaryConditionalOperatorClass;
+  }
+};
+
+/// ConditionalOperator - The ?: ternary operator.  The GNU "missing
+/// middle" extension is a BinaryConditionalOperator.
+class ConditionalOperator : public AbstractConditionalOperator {
+  enum { COND, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+
+  friend class ASTStmtReader;
+public:
+  ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs,
+                      SourceLocation CLoc, Expr *rhs,
+                      QualType t, ExprValueKind VK, ExprObjectKind OK)
+    : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK,
+           // FIXME: the type of the conditional operator doesn't
+           // depend on the type of the conditional, but the standard
+           // seems to imply that it could. File a bug!
+           (lhs->isTypeDependent() || rhs->isTypeDependent()),
+           (cond->isValueDependent() || lhs->isValueDependent() ||
+            rhs->isValueDependent()),
+           (cond->isInstantiationDependent() ||
+            lhs->isInstantiationDependent() ||
+            rhs->isInstantiationDependent()),
+           (cond->containsUnexpandedParameterPack() ||
+            lhs->containsUnexpandedParameterPack() ||
+            rhs->containsUnexpandedParameterPack()),
+                                  QLoc, CLoc) {
+    SubExprs[COND] = cond;
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+  }
+
+  /// \brief Build an empty conditional operator.
+  explicit ConditionalOperator(EmptyShell Empty)
+    : AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
+
+  // getCond - Return the expression representing the condition for
+  //   the ?: operator.
+  Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+
+  // getTrueExpr - Return the subexpression representing the value of
+  //   the expression if the condition evaluates to true.
+  Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
+
+  // getFalseExpr - Return the subexpression representing the value of
+  //   the expression if the condition evaluates to false.  This is
+  //   the same as getRHS.
+  Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
+
+  Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getCond()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getRHS()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConditionalOperatorClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+/// BinaryConditionalOperator - The GNU extension to the conditional
+/// operator which allows the middle operand to be omitted.
+///
+/// This is a different expression kind on the assumption that almost
+/// every client ends up needing to know that these are different.
+class BinaryConditionalOperator : public AbstractConditionalOperator {
+  enum { COMMON, COND, LHS, RHS, NUM_SUBEXPRS };
+
+  /// - the common condition/left-hand-side expression, which will be
+  ///   evaluated as the opaque value
+  /// - the condition, expressed in terms of the opaque value
+  /// - the left-hand-side, expressed in terms of the opaque value
+  /// - the right-hand-side
+  Stmt *SubExprs[NUM_SUBEXPRS];
+  OpaqueValueExpr *OpaqueValue;
+
+  friend class ASTStmtReader;
+public:
+  BinaryConditionalOperator(Expr *common, OpaqueValueExpr *opaqueValue,
+                            Expr *cond, Expr *lhs, Expr *rhs,
+                            SourceLocation qloc, SourceLocation cloc,
+                            QualType t, ExprValueKind VK, ExprObjectKind OK)
+    : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
+           (common->isTypeDependent() || rhs->isTypeDependent()),
+           (common->isValueDependent() || rhs->isValueDependent()),
+           (common->isInstantiationDependent() ||
+            rhs->isInstantiationDependent()),
+           (common->containsUnexpandedParameterPack() ||
+            rhs->containsUnexpandedParameterPack()),
+                                  qloc, cloc),
+      OpaqueValue(opaqueValue) {
+    SubExprs[COMMON] = common;
+    SubExprs[COND] = cond;
+    SubExprs[LHS] = lhs;
+    SubExprs[RHS] = rhs;
+    assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value");
+  }
+
+  /// \brief Build an empty conditional operator.
+  explicit BinaryConditionalOperator(EmptyShell Empty)
+    : AbstractConditionalOperator(BinaryConditionalOperatorClass, Empty) { }
+
+  /// \brief getCommon - Return the common expression, written to the
+  ///   left of the condition.  The opaque value will be bound to the
+  ///   result of this expression.
+  Expr *getCommon() const { return cast<Expr>(SubExprs[COMMON]); }
+
+  /// \brief getOpaqueValue - Return the opaque value placeholder.
+  OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
+
+  /// \brief getCond - Return the condition expression; this is defined
+  ///   in terms of the opaque value.
+  Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+
+  /// \brief getTrueExpr - Return the subexpression which will be
+  ///   evaluated if the condition evaluates to true;  this is defined
+  ///   in terms of the opaque value.
+  Expr *getTrueExpr() const {
+    return cast<Expr>(SubExprs[LHS]);
+  }
+
+  /// \brief getFalseExpr - Return the subexpression which will be
+  ///   evaluated if the condnition evaluates to false; this is
+  ///   defined in terms of the opaque value.
+  Expr *getFalseExpr() const {
+    return cast<Expr>(SubExprs[RHS]);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getCommon()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getFalseExpr()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BinaryConditionalOperatorClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(SubExprs, SubExprs + NUM_SUBEXPRS);
+  }
+};
+
+inline Expr *AbstractConditionalOperator::getCond() const {
+  if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
+    return co->getCond();
+  return cast<BinaryConditionalOperator>(this)->getCond();
+}
+
+inline Expr *AbstractConditionalOperator::getTrueExpr() const {
+  if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
+    return co->getTrueExpr();
+  return cast<BinaryConditionalOperator>(this)->getTrueExpr();
+}
+
+inline Expr *AbstractConditionalOperator::getFalseExpr() const {
+  if (const ConditionalOperator *co = dyn_cast<ConditionalOperator>(this))
+    return co->getFalseExpr();
+  return cast<BinaryConditionalOperator>(this)->getFalseExpr();
+}
+
+/// AddrLabelExpr - The GNU address of label extension, representing &&label.
+class AddrLabelExpr : public Expr {
+  SourceLocation AmpAmpLoc, LabelLoc;
+  LabelDecl *Label;
+public:
+  AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
+                QualType t)
+    : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
+           false),
+      AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
+
+  /// \brief Build an empty address of a label expression.
+  explicit AddrLabelExpr(EmptyShell Empty)
+    : Expr(AddrLabelExprClass, Empty) { }
+
+  SourceLocation getAmpAmpLoc() const { return AmpAmpLoc; }
+  void setAmpAmpLoc(SourceLocation L) { AmpAmpLoc = L; }
+  SourceLocation getLabelLoc() const { return LabelLoc; }
+  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AmpAmpLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+
+  LabelDecl *getLabel() const { return Label; }
+  void setLabel(LabelDecl *L) { Label = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == AddrLabelExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
+/// The StmtExpr contains a single CompoundStmt node, which it evaluates and
+/// takes the value of the last subexpression.
+///
+/// A StmtExpr is always an r-value; values "returned" out of a
+/// StmtExpr will be copied.
+class StmtExpr : public Expr {
+  Stmt *SubStmt;
+  SourceLocation LParenLoc, RParenLoc;
+public:
+  // FIXME: Does type-dependence need to be computed differently?
+  // FIXME: Do we need to compute instantiation instantiation-dependence for
+  // statements? (ugh!)
+  StmtExpr(CompoundStmt *substmt, QualType T,
+           SourceLocation lp, SourceLocation rp) :
+    Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
+         T->isDependentType(), false, false, false),
+    SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
+
+  /// \brief Build an empty statement expression.
+  explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
+
+  CompoundStmt *getSubStmt() { return cast<CompoundStmt>(SubStmt); }
+  const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
+  void setSubStmt(CompoundStmt *S) { SubStmt = S; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == StmtExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
+};
+
+
+/// ShuffleVectorExpr - clang-specific builtin-in function
+/// __builtin_shufflevector.
+/// This AST node represents a operator that does a constant
+/// shuffle, similar to LLVM's shufflevector instruction. It takes
+/// two vectors and a variable number of constant indices,
+/// and returns the appropriately shuffled vector.
+class ShuffleVectorExpr : public Expr {
+  SourceLocation BuiltinLoc, RParenLoc;
+
+  // SubExprs - the list of values passed to the __builtin_shufflevector
+  // function. The first two are vectors, and the rest are constant
+  // indices.  The number of values in this list is always
+  // 2+the number of indices in the vector type.
+  Stmt **SubExprs;
+  unsigned NumExprs;
+
+public:
+  ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
+                    SourceLocation BLoc, SourceLocation RP);
+
+  /// \brief Build an empty vector-shuffle expression.
+  explicit ShuffleVectorExpr(EmptyShell Empty)
+    : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ShuffleVectorExprClass;
+  }
+
+  /// getNumSubExprs - Return the size of the SubExprs array.  This includes the
+  /// constant expression, the actual arguments passed in, and the function
+  /// pointers.
+  unsigned getNumSubExprs() const { return NumExprs; }
+
+  /// \brief Retrieve the array of expressions.
+  Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
+
+  /// getExpr - Return the Expr at the specified index.
+  Expr *getExpr(unsigned Index) {
+    assert((Index < NumExprs) && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Index]);
+  }
+  const Expr *getExpr(unsigned Index) const {
+    assert((Index < NumExprs) && "Arg access out of range!");
+    return cast<Expr>(SubExprs[Index]);
+  }
+
+  void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
+
+  llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
+    assert((N < NumExprs - 2) && "Shuffle idx out of range!");
+    return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+NumExprs);
+  }
+};
+
+/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
+/// This AST node provides support for converting a vector type to another
+/// vector type of the same arity.
+class ConvertVectorExpr : public Expr {
+private:
+  Stmt *SrcExpr;
+  TypeSourceInfo *TInfo;
+  SourceLocation BuiltinLoc, RParenLoc;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
+
+public:
+  ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType,
+             ExprValueKind VK, ExprObjectKind OK,
+             SourceLocation BuiltinLoc, SourceLocation RParenLoc)
+    : Expr(ConvertVectorExprClass, DstType, VK, OK,
+           DstType->isDependentType(),
+           DstType->isDependentType() || SrcExpr->isValueDependent(),
+           (DstType->isInstantiationDependentType() ||
+            SrcExpr->isInstantiationDependent()),
+           (DstType->containsUnexpandedParameterPack() ||
+            SrcExpr->containsUnexpandedParameterPack())),
+  SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
+
+  /// getSrcExpr - Return the Expr to be converted.
+  Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
+
+  /// getTypeSourceInfo - Return the destination type.
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TInfo;
+  }
+  void setTypeSourceInfo(TypeSourceInfo *ti) {
+    TInfo = ti;
+  }
+
+  /// getBuiltinLoc - Return the location of the __builtin_convertvector token.
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+
+  /// getRParenLoc - Return the location of final right parenthesis.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConvertVectorExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
+};
+
+/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
+/// This AST node is similar to the conditional operator (?:) in C, with
+/// the following exceptions:
+/// - the test expression must be a integer constant expression.
+/// - the expression returned acts like the chosen subexpression in every
+///   visible way: the type is the same as that of the chosen subexpression,
+///   and all predicates (whether it's an l-value, whether it's an integer
+///   constant expression, etc.) return the same result as for the chosen
+///   sub-expression.
+class ChooseExpr : public Expr {
+  enum { COND, LHS, RHS, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // Left/Middle/Right hand sides.
+  SourceLocation BuiltinLoc, RParenLoc;
+  bool CondIsTrue;
+public:
+  ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs,
+             QualType t, ExprValueKind VK, ExprObjectKind OK,
+             SourceLocation RP, bool condIsTrue,
+             bool TypeDependent, bool ValueDependent)
+    : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
+           (cond->isInstantiationDependent() ||
+            lhs->isInstantiationDependent() ||
+            rhs->isInstantiationDependent()),
+           (cond->containsUnexpandedParameterPack() ||
+            lhs->containsUnexpandedParameterPack() ||
+            rhs->containsUnexpandedParameterPack())),
+      BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) {
+      SubExprs[COND] = cond;
+      SubExprs[LHS] = lhs;
+      SubExprs[RHS] = rhs;
+    }
+
+  /// \brief Build an empty __builtin_choose_expr.
+  explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { }
+
+  /// isConditionTrue - Return whether the condition is true (i.e. not
+  /// equal to zero).
+  bool isConditionTrue() const {
+    assert(!isConditionDependent() &&
+           "Dependent condition isn't true or false");
+    return CondIsTrue;
+  }
+  void setIsConditionTrue(bool isTrue) { CondIsTrue = isTrue; }
+
+  bool isConditionDependent() const {
+    return getCond()->isTypeDependent() || getCond()->isValueDependent();
+  }
+
+  /// getChosenSubExpr - Return the subexpression chosen according to the
+  /// condition.
+  Expr *getChosenSubExpr() const {
+    return isConditionTrue() ? getLHS() : getRHS();
+  }
+
+  Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
+  void setCond(Expr *E) { SubExprs[COND] = E; }
+  Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
+  void setLHS(Expr *E) { SubExprs[LHS] = E; }
+  Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
+  void setRHS(Expr *E) { SubExprs[RHS] = E; }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ChooseExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+/// GNUNullExpr - Implements the GNU __null extension, which is a name
+/// for a null pointer constant that has integral type (e.g., int or
+/// long) and is the same size and alignment as a pointer. The __null
+/// extension is typically only used by system headers, which define
+/// NULL as __null in C++ rather than using 0 (which is an integer
+/// that may not match the size of a pointer).
+class GNUNullExpr : public Expr {
+  /// TokenLoc - The location of the __null keyword.
+  SourceLocation TokenLoc;
+
+public:
+  GNUNullExpr(QualType Ty, SourceLocation Loc)
+    : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
+           false),
+      TokenLoc(Loc) { }
+
+  /// \brief Build an empty GNU __null expression.
+  explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { }
+
+  /// getTokenLocation - The location of the __null token.
+  SourceLocation getTokenLocation() const { return TokenLoc; }
+  void setTokenLocation(SourceLocation L) { TokenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return TokenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return TokenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GNUNullExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// VAArgExpr, used for the builtin function __builtin_va_arg.
+class VAArgExpr : public Expr {
+  Stmt *Val;
+  TypeSourceInfo *TInfo;
+  SourceLocation BuiltinLoc, RParenLoc;
+public:
+  VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo,
+            SourceLocation RPLoc, QualType t)
+    : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary,
+           t->isDependentType(), false,
+           (TInfo->getType()->isInstantiationDependentType() ||
+            e->isInstantiationDependent()),
+           (TInfo->getType()->containsUnexpandedParameterPack() ||
+            e->containsUnexpandedParameterPack())),
+      Val(e), TInfo(TInfo),
+      BuiltinLoc(BLoc),
+      RParenLoc(RPLoc) { }
+
+  /// \brief Create an empty __builtin_va_arg expression.
+  explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { }
+
+  const Expr *getSubExpr() const { return cast<Expr>(Val); }
+  Expr *getSubExpr() { return cast<Expr>(Val); }
+  void setSubExpr(Expr *E) { Val = E; }
+
+  TypeSourceInfo *getWrittenTypeInfo() const { return TInfo; }
+  void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo = TI; }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == VAArgExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Val, &Val+1); }
+};
+
+/// @brief Describes an C or C++ initializer list.
+///
+/// InitListExpr describes an initializer list, which can be used to
+/// initialize objects of different types, including
+/// struct/class/union types, arrays, and vectors. For example:
+///
+/// @code
+/// struct foo x = { 1, { 2, 3 } };
+/// @endcode
+///
+/// Prior to semantic analysis, an initializer list will represent the
+/// initializer list as written by the user, but will have the
+/// placeholder type "void". This initializer list is called the
+/// syntactic form of the initializer, and may contain C99 designated
+/// initializers (represented as DesignatedInitExprs), initializations
+/// of subobject members without explicit braces, and so on. Clients
+/// interested in the original syntax of the initializer list should
+/// use the syntactic form of the initializer list.
+///
+/// After semantic analysis, the initializer list will represent the
+/// semantic form of the initializer, where the initializations of all
+/// subobjects are made explicit with nested InitListExpr nodes and
+/// C99 designators have been eliminated by placing the designated
+/// initializations into the subobject they initialize. Additionally,
+/// any "holes" in the initialization, where no initializer has been
+/// specified for a particular subobject, will be replaced with
+/// implicitly-generated ImplicitValueInitExpr expressions that
+/// value-initialize the subobjects. Note, however, that the
+/// initializer lists may still have fewer initializers than there are
+/// elements to initialize within the object.
+///
+/// After semantic analysis has completed, given an initializer list,
+/// method isSemanticForm() returns true if and only if this is the
+/// semantic form of the initializer list (note: the same AST node
+/// may at the same time be the syntactic form).
+/// Given the semantic form of the initializer list, one can retrieve
+/// the syntactic form of that initializer list (when different)
+/// using method getSyntacticForm(); the method returns null if applied
+/// to a initializer list which is already in syntactic form.
+/// Similarly, given the syntactic form (i.e., an initializer list such
+/// that isSemanticForm() returns false), one can retrieve the semantic
+/// form using method getSemanticForm().
+/// Since many initializer lists have the same syntactic and semantic forms,
+/// getSyntacticForm() may return NULL, indicating that the current
+/// semantic initializer list also serves as its syntactic form.
+class InitListExpr : public Expr {
+  // FIXME: Eliminate this vector in favor of ASTContext allocation
+  typedef ASTVector<Stmt *> InitExprsTy;
+  InitExprsTy InitExprs;
+  SourceLocation LBraceLoc, RBraceLoc;
+
+  /// The alternative form of the initializer list (if it exists).
+  /// The int part of the pair stores whether this initializer list is
+  /// in semantic form. If not null, the pointer points to:
+  ///   - the syntactic form, if this is in semantic form;
+  ///   - the semantic form, if this is in syntactic form.
+  llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
+
+  /// \brief Either:
+  ///  If this initializer list initializes an array with more elements than
+  ///  there are initializers in the list, specifies an expression to be used
+  ///  for value initialization of the rest of the elements.
+  /// Or
+  ///  If this initializer list initializes a union, specifies which
+  ///  field within the union will be initialized.
+  llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
+
+public:
+  InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
+               ArrayRef<Expr*> initExprs, SourceLocation rbraceloc);
+
+  /// \brief Build an empty initializer list.
+  explicit InitListExpr(EmptyShell Empty)
+    : Expr(InitListExprClass, Empty) { }
+
+  unsigned getNumInits() const { return InitExprs.size(); }
+
+  /// \brief Retrieve the set of initializers.
+  Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
+
+  const Expr *getInit(unsigned Init) const {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    return cast_or_null<Expr>(InitExprs[Init]);
+  }
+
+  Expr *getInit(unsigned Init) {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    return cast_or_null<Expr>(InitExprs[Init]);
+  }
+
+  void setInit(unsigned Init, Expr *expr) {
+    assert(Init < getNumInits() && "Initializer access out of range!");
+    InitExprs[Init] = expr;
+
+    if (expr) {
+      ExprBits.TypeDependent |= expr->isTypeDependent();
+      ExprBits.ValueDependent |= expr->isValueDependent();
+      ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
+      ExprBits.ContainsUnexpandedParameterPack |=
+          expr->containsUnexpandedParameterPack();
+    }
+  }
+
+  /// \brief Reserve space for some number of initializers.
+  void reserveInits(const ASTContext &C, unsigned NumInits);
+
+  /// @brief Specify the number of initializers
+  ///
+  /// If there are more than @p NumInits initializers, the remaining
+  /// initializers will be destroyed. If there are fewer than @p
+  /// NumInits initializers, NULL expressions will be added for the
+  /// unknown initializers.
+  void resizeInits(const ASTContext &Context, unsigned NumInits);
+
+  /// @brief Updates the initializer at index @p Init with the new
+  /// expression @p expr, and returns the old expression at that
+  /// location.
+  ///
+  /// When @p Init is out of range for this initializer list, the
+  /// initializer list will be extended with NULL expressions to
+  /// accommodate the new entry.
+  Expr *updateInit(const ASTContext &C, unsigned Init, Expr *expr);
+
+  /// \brief If this initializer list initializes an array with more elements
+  /// than there are initializers in the list, specifies an expression to be
+  /// used for value initialization of the rest of the elements.
+  Expr *getArrayFiller() {
+    return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+  }
+  const Expr *getArrayFiller() const {
+    return const_cast<InitListExpr *>(this)->getArrayFiller();
+  }
+  void setArrayFiller(Expr *filler);
+
+  /// \brief Return true if this is an array initializer and its array "filler"
+  /// has been set.
+  bool hasArrayFiller() const { return getArrayFiller(); }
+
+  /// \brief If this initializes a union, specifies which field in the
+  /// union to initialize.
+  ///
+  /// Typically, this field is the first named field within the
+  /// union. However, a designated initializer can specify the
+  /// initialization of a different field within the union.
+  FieldDecl *getInitializedFieldInUnion() {
+    return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+  }
+  const FieldDecl *getInitializedFieldInUnion() const {
+    return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
+  }
+  void setInitializedFieldInUnion(FieldDecl *FD) {
+    assert((FD == nullptr
+            || getInitializedFieldInUnion() == nullptr
+            || getInitializedFieldInUnion() == FD)
+           && "Only one field of a union may be initialized at a time!");
+    ArrayFillerOrUnionFieldInit = FD;
+  }
+
+  // Explicit InitListExpr's originate from source code (and have valid source
+  // locations). Implicit InitListExpr's are created by the semantic analyzer.
+  bool isExplicit() {
+    return LBraceLoc.isValid() && RBraceLoc.isValid();
+  }
+
+  // Is this an initializer for an array of characters, initialized by a string
+  // literal or an @encode?
+  bool isStringLiteralInit() const;
+
+  SourceLocation getLBraceLoc() const { return LBraceLoc; }
+  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+  void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
+
+  bool isSemanticForm() const { return AltForm.getInt(); }
+  InitListExpr *getSemanticForm() const {
+    return isSemanticForm() ? nullptr : AltForm.getPointer();
+  }
+  InitListExpr *getSyntacticForm() const {
+    return isSemanticForm() ? AltForm.getPointer() : nullptr;
+  }
+
+  void setSyntacticForm(InitListExpr *Init) {
+    AltForm.setPointer(Init);
+    AltForm.setInt(true);
+    Init->AltForm.setPointer(this);
+    Init->AltForm.setInt(false);
+  }
+
+  bool hadArrayRangeDesignator() const {
+    return InitListExprBits.HadArrayRangeDesignator != 0;
+  }
+  void sawArrayRangeDesignator(bool ARD = true) {
+    InitListExprBits.HadArrayRangeDesignator = ARD;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == InitListExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    // FIXME: This does not include the array filler expression.
+    if (InitExprs.empty()) return child_range();
+    return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
+  }
+
+  typedef InitExprsTy::iterator iterator;
+  typedef InitExprsTy::const_iterator const_iterator;
+  typedef InitExprsTy::reverse_iterator reverse_iterator;
+  typedef InitExprsTy::const_reverse_iterator const_reverse_iterator;
+
+  iterator begin() { return InitExprs.begin(); }
+  const_iterator begin() const { return InitExprs.begin(); }
+  iterator end() { return InitExprs.end(); }
+  const_iterator end() const { return InitExprs.end(); }
+  reverse_iterator rbegin() { return InitExprs.rbegin(); }
+  const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
+  reverse_iterator rend() { return InitExprs.rend(); }
+  const_reverse_iterator rend() const { return InitExprs.rend(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// @brief Represents a C99 designated initializer expression.
+///
+/// A designated initializer expression (C99 6.7.8) contains one or
+/// more designators (which can be field designators, array
+/// designators, or GNU array-range designators) followed by an
+/// expression that initializes the field or element(s) that the
+/// designators refer to. For example, given:
+///
+/// @code
+/// struct point {
+///   double x;
+///   double y;
+/// };
+/// struct point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
+/// @endcode
+///
+/// The InitListExpr contains three DesignatedInitExprs, the first of
+/// which covers @c [2].y=1.0. This DesignatedInitExpr will have two
+/// designators, one array designator for @c [2] followed by one field
+/// designator for @c .y. The initialization expression will be 1.0.
+class DesignatedInitExpr : public Expr {
+public:
+  /// \brief Forward declaration of the Designator class.
+  class Designator;
+
+private:
+  /// The location of the '=' or ':' prior to the actual initializer
+  /// expression.
+  SourceLocation EqualOrColonLoc;
+
+  /// Whether this designated initializer used the GNU deprecated
+  /// syntax rather than the C99 '=' syntax.
+  bool GNUSyntax : 1;
+
+  /// The number of designators in this initializer expression.
+  unsigned NumDesignators : 15;
+
+  /// The number of subexpressions of this initializer expression,
+  /// which contains both the initializer and any additional
+  /// expressions used by array and array-range designators.
+  unsigned NumSubExprs : 16;
+
+  /// \brief The designators in this designated initialization
+  /// expression.
+  Designator *Designators;
+
+
+  DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators,
+                     const Designator *Designators,
+                     SourceLocation EqualOrColonLoc, bool GNUSyntax,
+                     ArrayRef<Expr*> IndexExprs, Expr *Init);
+
+  explicit DesignatedInitExpr(unsigned NumSubExprs)
+    : Expr(DesignatedInitExprClass, EmptyShell()),
+      NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
+
+public:
+  /// A field designator, e.g., ".x".
+  struct FieldDesignator {
+    /// Refers to the field that is being initialized. The low bit
+    /// of this field determines whether this is actually a pointer
+    /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
+    /// initially constructed, a field designator will store an
+    /// IdentifierInfo*. After semantic analysis has resolved that
+    /// name, the field designator will instead store a FieldDecl*.
+    uintptr_t NameOrField;
+
+    /// The location of the '.' in the designated initializer.
+    unsigned DotLoc;
+
+    /// The location of the field name in the designated initializer.
+    unsigned FieldLoc;
+  };
+
+  /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
+  struct ArrayOrRangeDesignator {
+    /// Location of the first index expression within the designated
+    /// initializer expression's list of subexpressions.
+    unsigned Index;
+    /// The location of the '[' starting the array range designator.
+    unsigned LBracketLoc;
+    /// The location of the ellipsis separating the start and end
+    /// indices. Only valid for GNU array-range designators.
+    unsigned EllipsisLoc;
+    /// The location of the ']' terminating the array range designator.
+    unsigned RBracketLoc;
+  };
+
+  /// @brief Represents a single C99 designator.
+  ///
+  /// @todo This class is infuriatingly similar to clang::Designator,
+  /// but minor differences (storing indices vs. storing pointers)
+  /// keep us from reusing it. Try harder, later, to rectify these
+  /// differences.
+  class Designator {
+    /// @brief The kind of designator this describes.
+    enum {
+      FieldDesignator,
+      ArrayDesignator,
+      ArrayRangeDesignator
+    } Kind;
+
+    union {
+      /// A field designator, e.g., ".x".
+      struct FieldDesignator Field;
+      /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
+      struct ArrayOrRangeDesignator ArrayOrRange;
+    };
+    friend class DesignatedInitExpr;
+
+  public:
+    Designator() {}
+
+    /// @brief Initializes a field designator.
+    Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
+               SourceLocation FieldLoc)
+      : Kind(FieldDesignator) {
+      Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
+      Field.DotLoc = DotLoc.getRawEncoding();
+      Field.FieldLoc = FieldLoc.getRawEncoding();
+    }
+
+    /// @brief Initializes an array designator.
+    Designator(unsigned Index, SourceLocation LBracketLoc,
+               SourceLocation RBracketLoc)
+      : Kind(ArrayDesignator) {
+      ArrayOrRange.Index = Index;
+      ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
+      ArrayOrRange.EllipsisLoc = SourceLocation().getRawEncoding();
+      ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
+    }
+
+    /// @brief Initializes a GNU array-range designator.
+    Designator(unsigned Index, SourceLocation LBracketLoc,
+               SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
+      : Kind(ArrayRangeDesignator) {
+      ArrayOrRange.Index = Index;
+      ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
+      ArrayOrRange.EllipsisLoc = EllipsisLoc.getRawEncoding();
+      ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
+    }
+
+    bool isFieldDesignator() const { return Kind == FieldDesignator; }
+    bool isArrayDesignator() const { return Kind == ArrayDesignator; }
+    bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
+
+    IdentifierInfo *getFieldName() const;
+
+    FieldDecl *getField() const {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      if (Field.NameOrField & 0x01)
+        return nullptr;
+      else
+        return reinterpret_cast<FieldDecl *>(Field.NameOrField);
+    }
+
+    void setField(FieldDecl *FD) {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
+    }
+
+    SourceLocation getDotLoc() const {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      return SourceLocation::getFromRawEncoding(Field.DotLoc);
+    }
+
+    SourceLocation getFieldLoc() const {
+      assert(Kind == FieldDesignator && "Only valid on a field designator");
+      return SourceLocation::getFromRawEncoding(Field.FieldLoc);
+    }
+
+    SourceLocation getLBracketLoc() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.LBracketLoc);
+    }
+
+    SourceLocation getRBracketLoc() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.RBracketLoc);
+    }
+
+    SourceLocation getEllipsisLoc() const {
+      assert(Kind == ArrayRangeDesignator &&
+             "Only valid on an array-range designator");
+      return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
+    }
+
+    unsigned getFirstExprIndex() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return ArrayOrRange.Index;
+    }
+
+    SourceLocation getLocStart() const LLVM_READONLY {
+      if (Kind == FieldDesignator)
+        return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
+      else
+        return getLBracketLoc();
+    }
+    SourceLocation getLocEnd() const LLVM_READONLY {
+      return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
+    }
+    SourceRange getSourceRange() const LLVM_READONLY {
+      return SourceRange(getLocStart(), getLocEnd());
+    }
+  };
+
+  static DesignatedInitExpr *Create(const ASTContext &C,
+                                    Designator *Designators,
+                                    unsigned NumDesignators,
+                                    ArrayRef<Expr*> IndexExprs,
+                                    SourceLocation EqualOrColonLoc,
+                                    bool GNUSyntax, Expr *Init);
+
+  static DesignatedInitExpr *CreateEmpty(const ASTContext &C,
+                                         unsigned NumIndexExprs);
+
+  /// @brief Returns the number of designators in this initializer.
+  unsigned size() const { return NumDesignators; }
+
+  // Iterator access to the designators.
+  typedef Designator *designators_iterator;
+  designators_iterator designators_begin() { return Designators; }
+  designators_iterator designators_end() {
+    return Designators + NumDesignators;
+  }
+
+  typedef const Designator *const_designators_iterator;
+  const_designators_iterator designators_begin() const { return Designators; }
+  const_designators_iterator designators_end() const {
+    return Designators + NumDesignators;
+  }
+
+  typedef llvm::iterator_range<designators_iterator> designators_range;
+  designators_range designators() {
+    return designators_range(designators_begin(), designators_end());
+  }
+
+  typedef llvm::iterator_range<const_designators_iterator>
+          designators_const_range;
+  designators_const_range designators() const {
+    return designators_const_range(designators_begin(), designators_end());
+  }
+
+  typedef std::reverse_iterator<designators_iterator>
+          reverse_designators_iterator;
+  reverse_designators_iterator designators_rbegin() {
+    return reverse_designators_iterator(designators_end());
+  }
+  reverse_designators_iterator designators_rend() {
+    return reverse_designators_iterator(designators_begin());
+  }
+
+  typedef std::reverse_iterator<const_designators_iterator>
+          const_reverse_designators_iterator;
+  const_reverse_designators_iterator designators_rbegin() const {
+    return const_reverse_designators_iterator(designators_end());
+  }
+  const_reverse_designators_iterator designators_rend() const {
+    return const_reverse_designators_iterator(designators_begin());
+  }
+
+  Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
+
+  void setDesignators(const ASTContext &C, const Designator *Desigs,
+                      unsigned NumDesigs);
+
+  Expr *getArrayIndex(const Designator &D) const;
+  Expr *getArrayRangeStart(const Designator &D) const;
+  Expr *getArrayRangeEnd(const Designator &D) const;
+
+  /// @brief Retrieve the location of the '=' that precedes the
+  /// initializer value itself, if present.
+  SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
+  void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
+
+  /// @brief Determines whether this designated initializer used the
+  /// deprecated GNU syntax for designated initializers.
+  bool usesGNUSyntax() const { return GNUSyntax; }
+  void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
+
+  /// @brief Retrieve the initializer value.
+  Expr *getInit() const {
+    return cast<Expr>(*const_cast<DesignatedInitExpr*>(this)->child_begin());
+  }
+
+  void setInit(Expr *init) {
+    *child_begin() = init;
+  }
+
+  /// \brief Retrieve the total number of subexpressions in this
+  /// designated initializer expression, including the actual
+  /// initialized value and any expressions that occur within array
+  /// and array-range designators.
+  unsigned getNumSubExprs() const { return NumSubExprs; }
+
+  Expr *getSubExpr(unsigned Idx) const {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
+  }
+
+  void setSubExpr(unsigned Idx, Expr *E) {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
+  }
+
+  /// \brief Replaces the designator at index @p Idx with the series
+  /// of designators in [First, Last).
+  void ExpandDesignator(const ASTContext &C, unsigned Idx,
+                        const Designator *First, const Designator *Last);
+
+  SourceRange getDesignatorsSourceRange() const;
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DesignatedInitExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    Stmt **begin = reinterpret_cast<Stmt**>(this + 1);
+    return child_range(begin, begin + NumSubExprs);
+  }
+};
+
+/// \brief Represents an implicitly-generated value initialization of
+/// an object of a given type.
+///
+/// Implicit value initializations occur within semantic initializer
+/// list expressions (InitListExpr) as placeholders for subobject
+/// initializations not explicitly specified by the user.
+///
+/// \see InitListExpr
+class ImplicitValueInitExpr : public Expr {
+public:
+  explicit ImplicitValueInitExpr(QualType ty)
+    : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
+           false, false, ty->isInstantiationDependentType(), false) { }
+
+  /// \brief Construct an empty implicit value initialization.
+  explicit ImplicitValueInitExpr(EmptyShell Empty)
+    : Expr(ImplicitValueInitExprClass, Empty) { }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ImplicitValueInitExprClass;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+
+class ParenListExpr : public Expr {
+  Stmt **Exprs;
+  unsigned NumExprs;
+  SourceLocation LParenLoc, RParenLoc;
+
+public:
+  ParenListExpr(const ASTContext& C, SourceLocation lparenloc,
+                ArrayRef<Expr*> exprs, SourceLocation rparenloc);
+
+  /// \brief Build an empty paren list.
+  explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
+
+  unsigned getNumExprs() const { return NumExprs; }
+
+  const Expr* getExpr(unsigned Init) const {
+    assert(Init < getNumExprs() && "Initializer access out of range!");
+    return cast_or_null<Expr>(Exprs[Init]);
+  }
+
+  Expr* getExpr(unsigned Init) {
+    assert(Init < getNumExprs() && "Initializer access out of range!");
+    return cast_or_null<Expr>(Exprs[Init]);
+  }
+
+  Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ParenListExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&Exprs[0], &Exprs[0]+NumExprs);
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+
+/// \brief Represents a C11 generic selection.
+///
+/// A generic selection (C11 6.5.1.1) contains an unevaluated controlling
+/// expression, followed by one or more generic associations.  Each generic
+/// association specifies a type name and an expression, or "default" and an
+/// expression (in which case it is known as a default generic association).
+/// The type and value of the generic selection are identical to those of its
+/// result expression, which is defined as the expression in the generic
+/// association with a type name that is compatible with the type of the
+/// controlling expression, or the expression in the default generic association
+/// if no types are compatible.  For example:
+///
+/// @code
+/// _Generic(X, double: 1, float: 2, default: 3)
+/// @endcode
+///
+/// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
+/// or 3 if "hello".
+///
+/// As an extension, generic selections are allowed in C++, where the following
+/// additional semantics apply:
+///
+/// Any generic selection whose controlling expression is type-dependent or
+/// which names a dependent type in its association list is result-dependent,
+/// which means that the choice of result expression is dependent.
+/// Result-dependent generic associations are both type- and value-dependent.
+class GenericSelectionExpr : public Expr {
+  enum { CONTROLLING, END_EXPR };
+  TypeSourceInfo **AssocTypes;
+  Stmt **SubExprs;
+  unsigned NumAssocs, ResultIndex;
+  SourceLocation GenericLoc, DefaultLoc, RParenLoc;
+
+public:
+  GenericSelectionExpr(const ASTContext &Context,
+                       SourceLocation GenericLoc, Expr *ControllingExpr,
+                       ArrayRef<TypeSourceInfo*> AssocTypes,
+                       ArrayRef<Expr*> AssocExprs,
+                       SourceLocation DefaultLoc, SourceLocation RParenLoc,
+                       bool ContainsUnexpandedParameterPack,
+                       unsigned ResultIndex);
+
+  /// This constructor is used in the result-dependent case.
+  GenericSelectionExpr(const ASTContext &Context,
+                       SourceLocation GenericLoc, Expr *ControllingExpr,
+                       ArrayRef<TypeSourceInfo*> AssocTypes,
+                       ArrayRef<Expr*> AssocExprs,
+                       SourceLocation DefaultLoc, SourceLocation RParenLoc,
+                       bool ContainsUnexpandedParameterPack);
+
+  explicit GenericSelectionExpr(EmptyShell Empty)
+    : Expr(GenericSelectionExprClass, Empty) { }
+
+  unsigned getNumAssocs() const { return NumAssocs; }
+
+  SourceLocation getGenericLoc() const { return GenericLoc; }
+  SourceLocation getDefaultLoc() const { return DefaultLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  const Expr *getAssocExpr(unsigned i) const {
+    return cast<Expr>(SubExprs[END_EXPR+i]);
+  }
+  Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
+
+  const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
+    return AssocTypes[i];
+  }
+  TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
+
+  QualType getAssocType(unsigned i) const {
+    if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
+      return TS->getType();
+    else
+      return QualType();
+  }
+
+  const Expr *getControllingExpr() const {
+    return cast<Expr>(SubExprs[CONTROLLING]);
+  }
+  Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
+
+  /// Whether this generic selection is result-dependent.
+  bool isResultDependent() const { return ResultIndex == -1U; }
+
+  /// The zero-based index of the result expression's generic association in
+  /// the generic selection's association list.  Defined only if the
+  /// generic selection is not result-dependent.
+  unsigned getResultIndex() const {
+    assert(!isResultDependent() && "Generic selection is result-dependent");
+    return ResultIndex;
+  }
+
+  /// The generic selection's result expression.  Defined only if the
+  /// generic selection is not result-dependent.
+  const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
+  Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return GenericLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GenericSelectionExprClass;
+  }
+
+  child_range children() {
+    return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
+  }
+
+  friend class ASTStmtReader;
+};
+
+//===----------------------------------------------------------------------===//
+// Clang Extensions
+//===----------------------------------------------------------------------===//
+
+
+/// ExtVectorElementExpr - This represents access to specific elements of a
+/// vector, and may occur on the left hand side or right hand side.  For example
+/// the following is legal:  "V.xy = V.zw" if V is a 4 element extended vector.
+///
+/// Note that the base may have either vector or pointer to vector type, just
+/// like a struct field reference.
+///
+class ExtVectorElementExpr : public Expr {
+  Stmt *Base;
+  IdentifierInfo *Accessor;
+  SourceLocation AccessorLoc;
+public:
+  ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base,
+                       IdentifierInfo &accessor, SourceLocation loc)
+    : Expr(ExtVectorElementExprClass, ty, VK,
+           (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
+           base->isTypeDependent(), base->isValueDependent(),
+           base->isInstantiationDependent(),
+           base->containsUnexpandedParameterPack()),
+      Base(base), Accessor(&accessor), AccessorLoc(loc) {}
+
+  /// \brief Build an empty vector element expression.
+  explicit ExtVectorElementExpr(EmptyShell Empty)
+    : Expr(ExtVectorElementExprClass, Empty) { }
+
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr *E) { Base = E; }
+
+  IdentifierInfo &getAccessor() const { return *Accessor; }
+  void setAccessor(IdentifierInfo *II) { Accessor = II; }
+
+  SourceLocation getAccessorLoc() const { return AccessorLoc; }
+  void setAccessorLoc(SourceLocation L) { AccessorLoc = L; }
+
+  /// getNumElements - Get the number of components being selected.
+  unsigned getNumElements() const;
+
+  /// containsDuplicateElements - Return true if any element access is
+  /// repeated.
+  bool containsDuplicateElements() const;
+
+  /// getEncodedElementAccess - Encode the elements accessed into an llvm
+  /// aggregate Constant of ConstantInt(s).
+  void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const;
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getBase()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return AccessorLoc; }
+
+  /// isArrow - Return true if the base expression is a pointer to vector,
+  /// return false if the base expression is a vector.
+  bool isArrow() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ExtVectorElementExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Base, &Base+1); }
+};
+
+
+/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
+/// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
+class BlockExpr : public Expr {
+protected:
+  BlockDecl *TheBlock;
+public:
+  BlockExpr(BlockDecl *BD, QualType ty)
+    : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
+           ty->isDependentType(), ty->isDependentType(),
+           ty->isInstantiationDependentType() || BD->isDependentContext(),
+           false),
+      TheBlock(BD) {}
+
+  /// \brief Build an empty block expression.
+  explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { }
+
+  const BlockDecl *getBlockDecl() const { return TheBlock; }
+  BlockDecl *getBlockDecl() { return TheBlock; }
+  void setBlockDecl(BlockDecl *BD) { TheBlock = BD; }
+
+  // Convenience functions for probing the underlying BlockDecl.
+  SourceLocation getCaretLocation() const;
+  const Stmt *getBody() const;
+  Stmt *getBody();
+
+  SourceLocation getLocStart() const LLVM_READONLY { return getCaretLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getBody()->getLocEnd(); }
+
+  /// getFunctionType - Return the underlying function type for this block.
+  const FunctionProtoType *getFunctionType() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BlockExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
+/// This AST node provides support for reinterpreting a type to another
+/// type of the same size.
+class AsTypeExpr : public Expr {
+private:
+  Stmt *SrcExpr;
+  SourceLocation BuiltinLoc, RParenLoc;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
+
+public:
+  AsTypeExpr(Expr* SrcExpr, QualType DstType,
+             ExprValueKind VK, ExprObjectKind OK,
+             SourceLocation BuiltinLoc, SourceLocation RParenLoc)
+    : Expr(AsTypeExprClass, DstType, VK, OK,
+           DstType->isDependentType(),
+           DstType->isDependentType() || SrcExpr->isValueDependent(),
+           (DstType->isInstantiationDependentType() ||
+            SrcExpr->isInstantiationDependent()),
+           (DstType->containsUnexpandedParameterPack() ||
+            SrcExpr->containsUnexpandedParameterPack())),
+  SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
+
+  /// getSrcExpr - Return the Expr to be converted.
+  Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
+
+  /// getBuiltinLoc - Return the location of the __builtin_astype token.
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+
+  /// getRParenLoc - Return the location of final right parenthesis.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == AsTypeExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
+};
+
+/// PseudoObjectExpr - An expression which accesses a pseudo-object
+/// l-value.  A pseudo-object is an abstract object, accesses to which
+/// are translated to calls.  The pseudo-object expression has a
+/// syntactic form, which shows how the expression was actually
+/// written in the source code, and a semantic form, which is a series
+/// of expressions to be executed in order which detail how the
+/// operation is actually evaluated.  Optionally, one of the semantic
+/// forms may also provide a result value for the expression.
+///
+/// If any of the semantic-form expressions is an OpaqueValueExpr,
+/// that OVE is required to have a source expression, and it is bound
+/// to the result of that source expression.  Such OVEs may appear
+/// only in subsequent semantic-form expressions and as
+/// sub-expressions of the syntactic form.
+///
+/// PseudoObjectExpr should be used only when an operation can be
+/// usefully described in terms of fairly simple rewrite rules on
+/// objects and functions that are meant to be used by end-developers.
+/// For example, under the Itanium ABI, dynamic casts are implemented
+/// as a call to a runtime function called __dynamic_cast; using this
+/// class to describe that would be inappropriate because that call is
+/// not really part of the user-visible semantics, and instead the
+/// cast is properly reflected in the AST and IR-generation has been
+/// taught to generate the call as necessary.  In contrast, an
+/// Objective-C property access is semantically defined to be
+/// equivalent to a particular message send, and this is very much
+/// part of the user model.  The name of this class encourages this
+/// modelling design.
+class PseudoObjectExpr : public Expr {
+  // PseudoObjectExprBits.NumSubExprs - The number of sub-expressions.
+  // Always at least two, because the first sub-expression is the
+  // syntactic form.
+
+  // PseudoObjectExprBits.ResultIndex - The index of the
+  // sub-expression holding the result.  0 means the result is void,
+  // which is unambiguous because it's the index of the syntactic
+  // form.  Note that this is therefore 1 higher than the value passed
+  // in to Create, which is an index within the semantic forms.
+  // Note also that ASTStmtWriter assumes this encoding.
+
+  Expr **getSubExprsBuffer() { return reinterpret_cast<Expr**>(this + 1); }
+  const Expr * const *getSubExprsBuffer() const {
+    return reinterpret_cast<const Expr * const *>(this + 1);
+  }
+
+  friend class ASTStmtReader;
+
+  PseudoObjectExpr(QualType type, ExprValueKind VK,
+                   Expr *syntactic, ArrayRef<Expr*> semantic,
+                   unsigned resultIndex);
+
+  PseudoObjectExpr(EmptyShell shell, unsigned numSemanticExprs);
+
+  unsigned getNumSubExprs() const {
+    return PseudoObjectExprBits.NumSubExprs;
+  }
+
+public:
+  /// NoResult - A value for the result index indicating that there is
+  /// no semantic result.
+  enum : unsigned { NoResult = ~0U };
+
+  static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
+                                  ArrayRef<Expr*> semantic,
+                                  unsigned resultIndex);
+
+  static PseudoObjectExpr *Create(const ASTContext &Context, EmptyShell shell,
+                                  unsigned numSemanticExprs);
+
+  /// Return the syntactic form of this expression, i.e. the
+  /// expression it actually looks like.  Likely to be expressed in
+  /// terms of OpaqueValueExprs bound in the semantic form.
+  Expr *getSyntacticForm() { return getSubExprsBuffer()[0]; }
+  const Expr *getSyntacticForm() const { return getSubExprsBuffer()[0]; }
+
+  /// Return the index of the result-bearing expression into the semantics
+  /// expressions, or PseudoObjectExpr::NoResult if there is none.
+  unsigned getResultExprIndex() const {
+    if (PseudoObjectExprBits.ResultIndex == 0) return NoResult;
+    return PseudoObjectExprBits.ResultIndex - 1;
+  }
+
+  /// Return the result-bearing expression, or null if there is none.
+  Expr *getResultExpr() {
+    if (PseudoObjectExprBits.ResultIndex == 0)
+      return nullptr;
+    return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
+  }
+  const Expr *getResultExpr() const {
+    return const_cast<PseudoObjectExpr*>(this)->getResultExpr();
+  }
+
+  unsigned getNumSemanticExprs() const { return getNumSubExprs() - 1; }
+
+  typedef Expr * const *semantics_iterator;
+  typedef const Expr * const *const_semantics_iterator;
+  semantics_iterator semantics_begin() {
+    return getSubExprsBuffer() + 1;
+  }
+  const_semantics_iterator semantics_begin() const {
+    return getSubExprsBuffer() + 1;
+  }
+  semantics_iterator semantics_end() {
+    return getSubExprsBuffer() + getNumSubExprs();
+  }
+  const_semantics_iterator semantics_end() const {
+    return getSubExprsBuffer() + getNumSubExprs();
+  }
+  Expr *getSemanticExpr(unsigned index) {
+    assert(index + 1 < getNumSubExprs());
+    return getSubExprsBuffer()[index + 1];
+  }
+  const Expr *getSemanticExpr(unsigned index) const {
+    return const_cast<PseudoObjectExpr*>(this)->getSemanticExpr(index);
+  }
+
+  SourceLocation getExprLoc() const LLVM_READONLY {
+    return getSyntacticForm()->getExprLoc();
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getSyntacticForm()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSyntacticForm()->getLocEnd();
+  }
+
+  child_range children() {
+    Stmt **cs = reinterpret_cast<Stmt**>(getSubExprsBuffer());
+    return child_range(cs, cs + getNumSubExprs());
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == PseudoObjectExprClass;
+  }
+};
+
+/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
+/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
+/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
+/// All of these instructions take one primary pointer and at least one memory
+/// order.
+class AtomicExpr : public Expr {
+public:
+  enum AtomicOp {
+#define BUILTIN(ID, TYPE, ATTRS)
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID,
+#include "clang/Basic/Builtins.def"
+    // Avoid trailing comma
+    BI_First = 0
+  };
+
+  // The ABI values for various atomic memory orderings.
+  enum AtomicOrderingKind {
+    AO_ABI_memory_order_relaxed = 0,
+    AO_ABI_memory_order_consume = 1,
+    AO_ABI_memory_order_acquire = 2,
+    AO_ABI_memory_order_release = 3,
+    AO_ABI_memory_order_acq_rel = 4,
+    AO_ABI_memory_order_seq_cst = 5
+  };
+
+private:
+  enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  unsigned NumSubExprs;
+  SourceLocation BuiltinLoc, RParenLoc;
+  AtomicOp Op;
+
+  friend class ASTStmtReader;
+
+public:
+  AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t,
+             AtomicOp op, SourceLocation RP);
+
+  /// \brief Determine the number of arguments the specified atomic builtin
+  /// should have.
+  static unsigned getNumSubExprs(AtomicOp Op);
+
+  /// \brief Build an empty AtomicExpr.
+  explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
+
+  Expr *getPtr() const {
+    return cast<Expr>(SubExprs[PTR]);
+  }
+  Expr *getOrder() const {
+    return cast<Expr>(SubExprs[ORDER]);
+  }
+  Expr *getVal1() const {
+    if (Op == AO__c11_atomic_init)
+      return cast<Expr>(SubExprs[ORDER]);
+    assert(NumSubExprs > VAL1);
+    return cast<Expr>(SubExprs[VAL1]);
+  }
+  Expr *getOrderFail() const {
+    assert(NumSubExprs > ORDER_FAIL);
+    return cast<Expr>(SubExprs[ORDER_FAIL]);
+  }
+  Expr *getVal2() const {
+    if (Op == AO__atomic_exchange)
+      return cast<Expr>(SubExprs[ORDER_FAIL]);
+    assert(NumSubExprs > VAL2);
+    return cast<Expr>(SubExprs[VAL2]);
+  }
+  Expr *getWeak() const {
+    assert(NumSubExprs > WEAK);
+    return cast<Expr>(SubExprs[WEAK]);
+  }
+
+  AtomicOp getOp() const { return Op; }
+  unsigned getNumSubExprs() { return NumSubExprs; }
+
+  Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
+
+  bool isVolatile() const {
+    return getPtr()->getType()->getPointeeType().isVolatileQualified();
+  }
+
+  bool isCmpXChg() const {
+    return getOp() == AO__c11_atomic_compare_exchange_strong ||
+           getOp() == AO__c11_atomic_compare_exchange_weak ||
+           getOp() == AO__atomic_compare_exchange ||
+           getOp() == AO__atomic_compare_exchange_n;
+  }
+
+  SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BuiltinLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == AtomicExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(SubExprs, SubExprs+NumSubExprs);
+  }
+};
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
new file mode 100644
index 0000000..3a43d6d
--- /dev/null
+++ b/include/clang/AST/ExprCXX.h
@@ -0,0 +1,3816 @@
+//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::Expr interface and subclasses for C++ expressions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCXX_H
+#define LLVM_CLANG_AST_EXPRCXX_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/ExpressionTraits.h"
+#include "clang/AST/LambdaCapture.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+class CXXConstructorDecl;
+class CXXDestructorDecl;
+class CXXMethodDecl;
+class CXXTemporary;
+class MSPropertyDecl;
+class TemplateArgumentListInfo;
+class UuidAttr;
+
+//===--------------------------------------------------------------------===//
+// C++ Expressions.
+//===--------------------------------------------------------------------===//
+
+/// \brief A call to an overloaded operator written using operator
+/// syntax.
+///
+/// Represents a call to an overloaded operator written using operator
+/// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
+/// normal call, this AST node provides better information about the
+/// syntactic representation of the call.
+///
+/// In a C++ template, this expression node kind will be used whenever
+/// any of the arguments are type-dependent. In this case, the
+/// function itself will be a (possibly empty) set of functions and
+/// function templates that were found by name lookup at template
+/// definition time.
+class CXXOperatorCallExpr : public CallExpr {
+  /// \brief The overloaded operator.
+  OverloadedOperatorKind Operator;
+  SourceRange Range;
+
+  // Record the FP_CONTRACT state that applies to this operator call. Only
+  // meaningful for floating point types. For other types this value can be
+  // set to false.
+  unsigned FPContractable : 1;
+
+  SourceRange getSourceRangeImpl() const LLVM_READONLY;
+public:
+  CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
+                      ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
+                      SourceLocation operatorloc, bool fpContractable)
+    : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
+               operatorloc),
+      Operator(Op), FPContractable(fpContractable) {
+    Range = getSourceRangeImpl();
+  }
+  explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
+    CallExpr(C, CXXOperatorCallExprClass, Empty) { }
+
+
+  /// \brief Returns the kind of overloaded operator that this
+  /// expression refers to.
+  OverloadedOperatorKind getOperator() const { return Operator; }
+
+  /// \brief Returns the location of the operator symbol in the expression.
+  ///
+  /// When \c getOperator()==OO_Call, this is the location of the right
+  /// parentheses; when \c getOperator()==OO_Subscript, this is the location
+  /// of the right bracket.
+  SourceLocation getOperatorLoc() const { return getRParenLoc(); }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const { return Range; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXOperatorCallExprClass;
+  }
+
+  // Set the FP contractability status of this operator. Only meaningful for
+  // operations on floating point types.
+  void setFPContractable(bool FPC) { FPContractable = FPC; }
+
+  // Get the FP contractability status of this operator. Only meaningful for
+  // operations on floating point types.
+  bool isFPContractable() const { return FPContractable; }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// Represents a call to a member function that
+/// may be written either with member call syntax (e.g., "obj.func()"
+/// or "objptr->func()") or with normal function-call syntax
+/// ("func()") within a member function that ends up calling a member
+/// function. The callee in either case is a MemberExpr that contains
+/// both the object argument and the member function, while the
+/// arguments are the arguments within the parentheses (not including
+/// the object argument).
+class CXXMemberCallExpr : public CallExpr {
+public:
+  CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args,
+                    QualType t, ExprValueKind VK, SourceLocation RP)
+    : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {}
+
+  CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
+    : CallExpr(C, CXXMemberCallExprClass, Empty) { }
+
+  /// \brief Retrieves the implicit object argument for the member call.
+  ///
+  /// For example, in "x.f(5)", this returns the sub-expression "x".
+  Expr *getImplicitObjectArgument() const;
+
+  /// \brief Retrieves the declaration of the called method.
+  CXXMethodDecl *getMethodDecl() const;
+
+  /// \brief Retrieves the CXXRecordDecl for the underlying type of
+  /// the implicit object argument.
+  ///
+  /// Note that this is may not be the same declaration as that of the class
+  /// context of the CXXMethodDecl which this function is calling.
+  /// FIXME: Returns 0 for member pointer call exprs.
+  CXXRecordDecl *getRecordDecl() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXMemberCallExprClass;
+  }
+};
+
+/// \brief Represents a call to a CUDA kernel function.
+class CUDAKernelCallExpr : public CallExpr {
+private:
+  enum { CONFIG, END_PREARG };
+
+public:
+  CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
+                     ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
+                     SourceLocation RP)
+    : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) {
+    setConfig(Config);
+  }
+
+  CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty)
+    : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { }
+
+  const CallExpr *getConfig() const {
+    return cast_or_null<CallExpr>(getPreArg(CONFIG));
+  }
+  CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
+  void setConfig(CallExpr *E) { setPreArg(CONFIG, E); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CUDAKernelCallExprClass;
+  }
+};
+
+/// \brief Abstract class common to all of the C++ "named"/"keyword" casts.
+///
+/// This abstract class is inherited by all of the classes
+/// representing "named" casts: CXXStaticCastExpr for \c static_cast,
+/// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
+/// reinterpret_cast, and CXXConstCastExpr for \c const_cast.
+class CXXNamedCastExpr : public ExplicitCastExpr {
+private:
+  SourceLocation Loc; // the location of the casting op
+  SourceLocation RParenLoc; // the location of the right parenthesis
+  SourceRange AngleBrackets; // range for '<' '>'
+
+protected:
+  CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
+                   CastKind kind, Expr *op, unsigned PathSize,
+                   TypeSourceInfo *writtenTy, SourceLocation l,
+                   SourceLocation RParenLoc,
+                   SourceRange AngleBrackets)
+    : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
+      RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
+
+  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(SC, Shell, PathSize) { }
+
+  friend class ASTStmtReader;
+
+public:
+  const char *getCastName() const;
+
+  /// \brief Retrieve the location of the cast operator keyword, e.g.,
+  /// \c static_cast.
+  SourceLocation getOperatorLoc() const { return Loc; }
+
+  /// \brief Retrieve the location of the closing parenthesis.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+  SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
+
+  static bool classof(const Stmt *T) {
+    switch (T->getStmtClass()) {
+    case CXXStaticCastExprClass:
+    case CXXDynamicCastExprClass:
+    case CXXReinterpretCastExprClass:
+    case CXXConstCastExprClass:
+      return true;
+    default:
+      return false;
+    }
+  }
+};
+
+/// \brief A C++ \c static_cast expression (C++ [expr.static.cast]).
+///
+/// This expression node represents a C++ static cast, e.g.,
+/// \c static_cast<int>(1.0).
+class CXXStaticCastExpr : public CXXNamedCastExpr {
+  CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
+                    unsigned pathSize, TypeSourceInfo *writtenTy,
+                    SourceLocation l, SourceLocation RParenLoc,
+                    SourceRange AngleBrackets)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
+                       writtenTy, l, RParenLoc, AngleBrackets) {}
+
+  explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
+
+public:
+  static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
+                                   ExprValueKind VK, CastKind K, Expr *Op,
+                                   const CXXCastPath *Path,
+                                   TypeSourceInfo *Written, SourceLocation L,
+                                   SourceLocation RParenLoc,
+                                   SourceRange AngleBrackets);
+  static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
+                                        unsigned PathSize);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXStaticCastExprClass;
+  }
+};
+
+/// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
+///
+/// This expression node represents a dynamic cast, e.g.,
+/// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
+/// check to determine how to perform the type conversion.
+class CXXDynamicCastExpr : public CXXNamedCastExpr {
+  CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
+                     Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
+                     SourceLocation l, SourceLocation RParenLoc,
+                     SourceRange AngleBrackets)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
+                       writtenTy, l, RParenLoc, AngleBrackets) {}
+
+  explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
+                                    ExprValueKind VK, CastKind Kind, Expr *Op,
+                                    const CXXCastPath *Path,
+                                    TypeSourceInfo *Written, SourceLocation L,
+                                    SourceLocation RParenLoc,
+                                    SourceRange AngleBrackets);
+
+  static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
+                                         unsigned pathSize);
+
+  bool isAlwaysNull() const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDynamicCastExprClass;
+  }
+};
+
+/// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
+///
+/// This expression node represents a reinterpret cast, e.g.,
+/// @c reinterpret_cast<int>(VoidPtr).
+///
+/// A reinterpret_cast provides a differently-typed view of a value but
+/// (in Clang, as in most C++ implementations) performs no actual work at
+/// run time.
+class CXXReinterpretCastExpr : public CXXNamedCastExpr {
+  CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
+                         Expr *op, unsigned pathSize,
+                         TypeSourceInfo *writtenTy, SourceLocation l,
+                         SourceLocation RParenLoc,
+                         SourceRange AngleBrackets)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
+                       pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
+
+  CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
+                                        ExprValueKind VK, CastKind Kind,
+                                        Expr *Op, const CXXCastPath *Path,
+                                 TypeSourceInfo *WrittenTy, SourceLocation L,
+                                        SourceLocation RParenLoc,
+                                        SourceRange AngleBrackets);
+  static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
+                                             unsigned pathSize);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXReinterpretCastExprClass;
+  }
+};
+
+/// \brief A C++ \c const_cast expression (C++ [expr.const.cast]).
+///
+/// This expression node represents a const cast, e.g.,
+/// \c const_cast<char*>(PtrToConstChar).
+///
+/// A const_cast can remove type qualifiers but does not change the underlying
+/// value.
+class CXXConstCastExpr : public CXXNamedCastExpr {
+  CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
+                   TypeSourceInfo *writtenTy, SourceLocation l,
+                   SourceLocation RParenLoc, SourceRange AngleBrackets)
+    : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
+                       0, writtenTy, l, RParenLoc, AngleBrackets) {}
+
+  explicit CXXConstCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
+
+public:
+  static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
+                                  ExprValueKind VK, Expr *Op,
+                                  TypeSourceInfo *WrittenTy, SourceLocation L,
+                                  SourceLocation RParenLoc,
+                                  SourceRange AngleBrackets);
+  static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXConstCastExprClass;
+  }
+};
+
+/// \brief A call to a literal operator (C++11 [over.literal])
+/// written as a user-defined literal (C++11 [lit.ext]).
+///
+/// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
+/// is semantically equivalent to a normal call, this AST node provides better
+/// information about the syntactic representation of the literal.
+///
+/// Since literal operators are never found by ADL and can only be declared at
+/// namespace scope, a user-defined literal is never dependent.
+class UserDefinedLiteral : public CallExpr {
+  /// \brief The location of a ud-suffix within the literal.
+  SourceLocation UDSuffixLoc;
+
+public:
+  UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args,
+                     QualType T, ExprValueKind VK, SourceLocation LitEndLoc,
+                     SourceLocation SuffixLoc)
+    : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc),
+      UDSuffixLoc(SuffixLoc) {}
+  explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty)
+    : CallExpr(C, UserDefinedLiteralClass, Empty) {}
+
+  /// The kind of literal operator which is invoked.
+  enum LiteralOperatorKind {
+    LOK_Raw,      ///< Raw form: operator "" X (const char *)
+    LOK_Template, ///< Raw form: operator "" X<cs...> ()
+    LOK_Integer,  ///< operator "" X (unsigned long long)
+    LOK_Floating, ///< operator "" X (long double)
+    LOK_String,   ///< operator "" X (const CharT *, size_t)
+    LOK_Character ///< operator "" X (CharT)
+  };
+
+  /// \brief Returns the kind of literal operator invocation
+  /// which this expression represents.
+  LiteralOperatorKind getLiteralOperatorKind() const;
+
+  /// \brief If this is not a raw user-defined literal, get the
+  /// underlying cooked literal (representing the literal with the suffix
+  /// removed).
+  Expr *getCookedLiteral();
+  const Expr *getCookedLiteral() const {
+    return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
+  }
+
+  SourceLocation getLocStart() const {
+    if (getLiteralOperatorKind() == LOK_Template)
+      return getRParenLoc();
+    return getArg(0)->getLocStart();
+  }
+  SourceLocation getLocEnd() const { return getRParenLoc(); }
+
+
+  /// \brief Returns the location of a ud-suffix in the expression.
+  ///
+  /// For a string literal, there may be multiple identical suffixes. This
+  /// returns the first.
+  SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
+
+  /// \brief Returns the ud-suffix specified for this literal.
+  const IdentifierInfo *getUDSuffix() const;
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == UserDefinedLiteralClass;
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// \brief A boolean literal, per ([C++ lex.bool] Boolean literals).
+///
+class CXXBoolLiteralExpr : public Expr {
+  bool Value;
+  SourceLocation Loc;
+public:
+  CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
+    Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+         false, false),
+    Value(val), Loc(l) {}
+
+  explicit CXXBoolLiteralExpr(EmptyShell Empty)
+    : Expr(CXXBoolLiteralExprClass, Empty) { }
+
+  bool getValue() const { return Value; }
+  void setValue(bool V) { Value = V; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXBoolLiteralExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief The null pointer literal (C++11 [lex.nullptr])
+///
+/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
+class CXXNullPtrLiteralExpr : public Expr {
+  SourceLocation Loc;
+public:
+  CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
+    Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+         false, false),
+    Loc(l) {}
+
+  explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
+    : Expr(CXXNullPtrLiteralExprClass, Empty) { }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNullPtrLiteralExprClass;
+  }
+
+  child_range children() { return child_range(); }
+};
+
+/// \brief Implicit construction of a std::initializer_list<T> object from an
+/// array temporary within list-initialization (C++11 [dcl.init.list]p5).
+class CXXStdInitializerListExpr : public Expr {
+  Stmt *SubExpr;
+
+  CXXStdInitializerListExpr(EmptyShell Empty)
+    : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
+
+public:
+  CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
+    : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
+           Ty->isDependentType(), SubExpr->isValueDependent(),
+           SubExpr->isInstantiationDependent(),
+           SubExpr->containsUnexpandedParameterPack()),
+      SubExpr(SubExpr) {}
+
+  Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
+  const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return SubExpr->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExpr->getLocEnd();
+  }
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SubExpr->getSourceRange();
+  }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() == CXXStdInitializerListExprClass;
+  }
+
+  child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+};
+
+/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
+/// the \c type_info that corresponds to the supplied type, or the (possibly
+/// dynamic) type of the supplied expression.
+///
+/// This represents code like \c typeid(int) or \c typeid(*objPtr)
+class CXXTypeidExpr : public Expr {
+private:
+  llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
+  SourceRange Range;
+
+public:
+  CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
+    : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
+           // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+           false,
+           // typeid is value-dependent if the type or expression are dependent
+           Operand->getType()->isDependentType(),
+           Operand->getType()->isInstantiationDependentType(),
+           Operand->getType()->containsUnexpandedParameterPack()),
+      Operand(Operand), Range(R) { }
+
+  CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
+    : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary,
+        // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+           false,
+        // typeid is value-dependent if the type or expression are dependent
+           Operand->isTypeDependent() || Operand->isValueDependent(),
+           Operand->isInstantiationDependent(),
+           Operand->containsUnexpandedParameterPack()),
+      Operand(Operand), Range(R) { }
+
+  CXXTypeidExpr(EmptyShell Empty, bool isExpr)
+    : Expr(CXXTypeidExprClass, Empty) {
+    if (isExpr)
+      Operand = (Expr*)nullptr;
+    else
+      Operand = (TypeSourceInfo*)nullptr;
+  }
+
+  /// Determine whether this typeid has a type operand which is potentially
+  /// evaluated, per C++11 [expr.typeid]p3.
+  bool isPotentiallyEvaluated() const;
+
+  bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+
+  /// \brief Retrieves the type operand of this typeid() expression after
+  /// various required adjustments (removing reference types, cv-qualifiers).
+  QualType getTypeOperand(ASTContext &Context) const;
+
+  /// \brief Retrieve source information for the type operand.
+  TypeSourceInfo *getTypeOperandSourceInfo() const {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+    return Operand.get<TypeSourceInfo *>();
+  }
+
+  void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+    Operand = TSI;
+  }
+
+  Expr *getExprOperand() const {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+    return static_cast<Expr*>(Operand.get<Stmt *>());
+  }
+
+  void setExprOperand(Expr *E) {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+    Operand = E;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  void setSourceRange(SourceRange R) { Range = R; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTypeidExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (isTypeOperand()) return child_range();
+    Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
+    return child_range(begin, begin + 1);
+  }
+};
+
+/// \brief A member reference to an MSPropertyDecl. 
+///
+/// This expression always has pseudo-object type, and therefore it is
+/// typically not encountered in a fully-typechecked expression except
+/// within the syntactic form of a PseudoObjectExpr.
+class MSPropertyRefExpr : public Expr {
+  Expr *BaseExpr;
+  MSPropertyDecl *TheDecl;
+  SourceLocation MemberLoc;
+  bool IsArrow;
+  NestedNameSpecifierLoc QualifierLoc;
+
+public:
+  MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
+                    QualType ty, ExprValueKind VK,
+                    NestedNameSpecifierLoc qualifierLoc,
+                    SourceLocation nameLoc)
+  : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary,
+         /*type-dependent*/ false, baseExpr->isValueDependent(),
+         baseExpr->isInstantiationDependent(),
+         baseExpr->containsUnexpandedParameterPack()),
+    BaseExpr(baseExpr), TheDecl(decl),
+    MemberLoc(nameLoc), IsArrow(isArrow),
+    QualifierLoc(qualifierLoc) {}
+
+  MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
+
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(getLocStart(), getLocEnd());
+  }
+  bool isImplicitAccess() const {
+    return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
+  }
+  SourceLocation getLocStart() const {
+    if (!isImplicitAccess())
+      return BaseExpr->getLocStart();
+    else if (QualifierLoc)
+      return QualifierLoc.getBeginLoc();
+    else
+        return MemberLoc;
+  }
+  SourceLocation getLocEnd() const { return getMemberLoc(); }
+
+  child_range children() {
+    return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
+  }
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MSPropertyRefExprClass;
+  }
+
+  Expr *getBaseExpr() const { return BaseExpr; }
+  MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
+  bool isArrow() const { return IsArrow; }
+  SourceLocation getMemberLoc() const { return MemberLoc; }
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  friend class ASTStmtReader;
+};
+
+/// A Microsoft C++ @c __uuidof expression, which gets
+/// the _GUID that corresponds to the supplied type or expression.
+///
+/// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
+class CXXUuidofExpr : public Expr {
+private:
+  llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
+  SourceRange Range;
+
+public:
+  CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
+    : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
+           false, Operand->getType()->isDependentType(),
+           Operand->getType()->isInstantiationDependentType(),
+           Operand->getType()->containsUnexpandedParameterPack()),
+      Operand(Operand), Range(R) { }
+
+  CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
+    : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
+           false, Operand->isTypeDependent(),
+           Operand->isInstantiationDependent(),
+           Operand->containsUnexpandedParameterPack()),
+      Operand(Operand), Range(R) { }
+
+  CXXUuidofExpr(EmptyShell Empty, bool isExpr)
+    : Expr(CXXUuidofExprClass, Empty) {
+    if (isExpr)
+      Operand = (Expr*)nullptr;
+    else
+      Operand = (TypeSourceInfo*)nullptr;
+  }
+
+  bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+
+  /// \brief Retrieves the type operand of this __uuidof() expression after
+  /// various required adjustments (removing reference types, cv-qualifiers).
+  QualType getTypeOperand(ASTContext &Context) const;
+
+  /// \brief Retrieve source information for the type operand.
+  TypeSourceInfo *getTypeOperandSourceInfo() const {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
+    return Operand.get<TypeSourceInfo *>();
+  }
+
+  void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
+    assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
+    Operand = TSI;
+  }
+
+  Expr *getExprOperand() const {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
+    return static_cast<Expr*>(Operand.get<Stmt *>());
+  }
+
+  void setExprOperand(Expr *E) {
+    assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
+    Operand = E;
+  }
+
+  StringRef getUuidAsStringRef(ASTContext &Context) const;
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  void setSourceRange(SourceRange R) { Range = R; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXUuidofExprClass;
+  }
+
+  /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
+  /// a single GUID.
+  static const UuidAttr *GetUuidAttrOfType(QualType QT,
+                                           bool *HasMultipleGUIDsPtr = nullptr);
+
+  // Iterators
+  child_range children() {
+    if (isTypeOperand()) return child_range();
+    Stmt **begin = reinterpret_cast<Stmt**>(&Operand);
+    return child_range(begin, begin + 1);
+  }
+};
+
+/// \brief Represents the \c this expression in C++.
+///
+/// This is a pointer to the object on which the current member function is
+/// executing (C++ [expr.prim]p3). Example:
+///
+/// \code
+/// class Foo {
+/// public:
+///   void bar();
+///   void test() { this->bar(); }
+/// };
+/// \endcode
+class CXXThisExpr : public Expr {
+  SourceLocation Loc;
+  bool Implicit : 1;
+
+public:
+  CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit)
+    : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary,
+           // 'this' is type-dependent if the class type of the enclosing
+           // member function is dependent (C++ [temp.dep.expr]p2)
+           Type->isDependentType(), Type->isDependentType(),
+           Type->isInstantiationDependentType(),
+           /*ContainsUnexpandedParameterPack=*/false),
+      Loc(L), Implicit(isImplicit) { }
+
+  CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXThisExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief A C++ throw-expression (C++ [except.throw]).
+///
+/// This handles 'throw' (for re-throwing the current exception) and
+/// 'throw' assignment-expression.  When assignment-expression isn't
+/// present, Op will be null.
+class CXXThrowExpr : public Expr {
+  Stmt *Op;
+  SourceLocation ThrowLoc;
+  /// \brief Whether the thrown variable (if any) is in scope.
+  unsigned IsThrownVariableInScope : 1;
+
+  friend class ASTStmtReader;
+
+public:
+  // \p Ty is the void type which is used as the result type of the
+  // expression.  The \p l is the location of the throw keyword.  \p expr
+  // can by null, if the optional expression to throw isn't present.
+  CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
+               bool IsThrownVariableInScope) :
+    Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+         expr && expr->isInstantiationDependent(),
+         expr && expr->containsUnexpandedParameterPack()),
+    Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
+  CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
+
+  const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
+  Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
+
+  SourceLocation getThrowLoc() const { return ThrowLoc; }
+
+  /// \brief Determines whether the variable thrown by this expression (if any!)
+  /// is within the innermost try block.
+  ///
+  /// This information is required to determine whether the NRVO can apply to
+  /// this variable.
+  bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (!getSubExpr())
+      return ThrowLoc;
+    return getSubExpr()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXThrowExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&Op, Op ? &Op+1 : &Op);
+  }
+};
+
+/// \brief A default argument (C++ [dcl.fct.default]).
+///
+/// This wraps up a function call argument that was created from the
+/// corresponding parameter's default argument, when the call did not
+/// explicitly supply arguments for all of the parameters.
+class CXXDefaultArgExpr : public Expr {
+  /// \brief The parameter whose default is being used.
+  ///
+  /// When the bit is set, the subexpression is stored after the
+  /// CXXDefaultArgExpr itself. When the bit is clear, the parameter's
+  /// actual default expression is the subexpression.
+  llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
+
+  /// \brief The location where the default argument expression was used.
+  SourceLocation Loc;
+
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
+    : Expr(SC,
+           param->hasUnparsedDefaultArg()
+             ? param->getType().getNonReferenceType()
+             : param->getDefaultArg()->getType(),
+           param->getDefaultArg()->getValueKind(),
+           param->getDefaultArg()->getObjectKind(), false, false, false, false),
+      Param(param, false), Loc(Loc) { }
+
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
+                    Expr *SubExpr)
+    : Expr(SC, SubExpr->getType(),
+           SubExpr->getValueKind(), SubExpr->getObjectKind(),
+           false, false, false, false),
+      Param(param, true), Loc(Loc) {
+    *reinterpret_cast<Expr **>(this + 1) = SubExpr;
+  }
+
+public:
+  CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+
+  // \p Param is the parameter whose default argument is used by this
+  // expression.
+  static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
+                                   ParmVarDecl *Param) {
+    return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
+  }
+
+  // \p Param is the parameter whose default argument is used by this
+  // expression, and \p SubExpr is the expression that will actually be used.
+  static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
+                                   ParmVarDecl *Param, Expr *SubExpr);
+
+  // Retrieve the parameter that the argument was created from.
+  const ParmVarDecl *getParam() const { return Param.getPointer(); }
+  ParmVarDecl *getParam() { return Param.getPointer(); }
+
+  // Retrieve the actual argument to the function call.
+  const Expr *getExpr() const {
+    if (Param.getInt())
+      return *reinterpret_cast<Expr const * const*> (this + 1);
+    return getParam()->getDefaultArg();
+  }
+  Expr *getExpr() {
+    if (Param.getInt())
+      return *reinterpret_cast<Expr **> (this + 1);
+    return getParam()->getDefaultArg();
+  }
+
+  /// \brief Retrieve the location where this default argument was actually
+  /// used.
+  SourceLocation getUsedLocation() const { return Loc; }
+
+  /// Default argument expressions have no representation in the
+  /// source, so they have an empty source range.
+  SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+  SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDefaultArgExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// \brief A use of a default initializer in a constructor or in aggregate
+/// initialization.
+///
+/// This wraps a use of a C++ default initializer (technically,
+/// a brace-or-equal-initializer for a non-static data member) when it
+/// is implicitly used in a mem-initializer-list in a constructor
+/// (C++11 [class.base.init]p8) or in aggregate initialization
+/// (C++1y [dcl.init.aggr]p7).
+class CXXDefaultInitExpr : public Expr {
+  /// \brief The field whose default is being used.
+  FieldDecl *Field;
+
+  /// \brief The location where the default initializer expression was used.
+  SourceLocation Loc;
+
+  CXXDefaultInitExpr(const ASTContext &C, SourceLocation Loc, FieldDecl *Field,
+                     QualType T);
+
+  CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
+
+public:
+  /// \p Field is the non-static data member whose default initializer is used
+  /// by this expression.
+  static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc,
+                                    FieldDecl *Field) {
+    return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType());
+  }
+
+  /// \brief Get the field whose initializer will be used.
+  FieldDecl *getField() { return Field; }
+  const FieldDecl *getField() const { return Field; }
+
+  /// \brief Get the initialization expression that will be used.
+  const Expr *getExpr() const { return Field->getInClassInitializer(); }
+  Expr *getExpr() { return Field->getInClassInitializer(); }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDefaultInitExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+};
+
+/// \brief Represents a C++ temporary.
+class CXXTemporary {
+  /// \brief The destructor that needs to be called.
+  const CXXDestructorDecl *Destructor;
+
+  explicit CXXTemporary(const CXXDestructorDecl *destructor)
+    : Destructor(destructor) { }
+
+public:
+  static CXXTemporary *Create(const ASTContext &C,
+                              const CXXDestructorDecl *Destructor);
+
+  const CXXDestructorDecl *getDestructor() const { return Destructor; }
+  void setDestructor(const CXXDestructorDecl *Dtor) {
+    Destructor = Dtor;
+  }
+};
+
+/// \brief Represents binding an expression to a temporary.
+///
+/// This ensures the destructor is called for the temporary. It should only be
+/// needed for non-POD, non-trivially destructable class types. For example:
+///
+/// \code
+///   struct S {
+///     S() { }  // User defined constructor makes S non-POD.
+///     ~S() { } // User defined destructor makes it non-trivial.
+///   };
+///   void test() {
+///     const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
+///   }
+/// \endcode
+class CXXBindTemporaryExpr : public Expr {
+  CXXTemporary *Temp;
+
+  Stmt *SubExpr;
+
+  CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr)
+   : Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
+          VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
+          SubExpr->isValueDependent(),
+          SubExpr->isInstantiationDependent(),
+          SubExpr->containsUnexpandedParameterPack()),
+     Temp(temp), SubExpr(SubExpr) { }
+
+public:
+  CXXBindTemporaryExpr(EmptyShell Empty)
+    : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
+
+  static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
+                                      Expr* SubExpr);
+
+  CXXTemporary *getTemporary() { return Temp; }
+  const CXXTemporary *getTemporary() const { return Temp; }
+  void setTemporary(CXXTemporary *T) { Temp = T; }
+
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  void setSubExpr(Expr *E) { SubExpr = E; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return SubExpr->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXBindTemporaryExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+};
+
+/// \brief Represents a call to a C++ constructor.
+class CXXConstructExpr : public Expr {
+public:
+  enum ConstructionKind {
+    CK_Complete,
+    CK_NonVirtualBase,
+    CK_VirtualBase,
+    CK_Delegating
+  };
+
+private:
+  CXXConstructorDecl *Constructor;
+
+  SourceLocation Loc;
+  SourceRange ParenOrBraceRange;
+  unsigned NumArgs : 16;
+  bool Elidable : 1;
+  bool HadMultipleCandidates : 1;
+  bool ListInitialization : 1;
+  bool StdInitListInitialization : 1;
+  bool ZeroInitialization : 1;
+  unsigned ConstructKind : 2;
+  Stmt **Args;
+
+protected:
+  CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
+                   SourceLocation Loc,
+                   CXXConstructorDecl *d, bool elidable,
+                   ArrayRef<Expr *> Args,
+                   bool HadMultipleCandidates,
+                   bool ListInitialization,
+                   bool StdInitListInitialization,
+                   bool ZeroInitialization,
+                   ConstructionKind ConstructKind,
+                   SourceRange ParenOrBraceRange);
+
+  /// \brief Construct an empty C++ construction expression.
+  CXXConstructExpr(StmtClass SC, EmptyShell Empty)
+    : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
+      HadMultipleCandidates(false), ListInitialization(false),
+      ZeroInitialization(false), ConstructKind(0), Args(nullptr)
+  { }
+
+public:
+  /// \brief Construct an empty C++ construction expression.
+  explicit CXXConstructExpr(EmptyShell Empty)
+    : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
+      NumArgs(0), Elidable(false), HadMultipleCandidates(false),
+      ListInitialization(false), ZeroInitialization(false),
+      ConstructKind(0), Args(nullptr)
+  { }
+
+  static CXXConstructExpr *Create(const ASTContext &C, QualType T,
+                                  SourceLocation Loc,
+                                  CXXConstructorDecl *D, bool Elidable,
+                                  ArrayRef<Expr *> Args,
+                                  bool HadMultipleCandidates,
+                                  bool ListInitialization,
+                                  bool StdInitListInitialization,
+                                  bool ZeroInitialization,
+                                  ConstructionKind ConstructKind,
+                                  SourceRange ParenOrBraceRange);
+
+  CXXConstructorDecl* getConstructor() const { return Constructor; }
+  void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+
+  /// \brief Whether this construction is elidable.
+  bool isElidable() const { return Elidable; }
+  void setElidable(bool E) { Elidable = E; }
+
+  /// \brief Whether the referred constructor was resolved from
+  /// an overloaded set having size greater than 1.
+  bool hadMultipleCandidates() const { return HadMultipleCandidates; }
+  void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+
+  /// \brief Whether this constructor call was written as list-initialization.
+  bool isListInitialization() const { return ListInitialization; }
+  void setListInitialization(bool V) { ListInitialization = V; }
+
+  /// \brief Whether this constructor call was written as list-initialization,
+  /// but was interpreted as forming a std::initializer_list<T> from the list
+  /// and passing that as a single constructor argument.
+  /// See C++11 [over.match.list]p1 bullet 1.
+  bool isStdInitListInitialization() const { return StdInitListInitialization; }
+  void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
+  /// \brief Whether this construction first requires
+  /// zero-initialization before the initializer is called.
+  bool requiresZeroInitialization() const { return ZeroInitialization; }
+  void setRequiresZeroInitialization(bool ZeroInit) {
+    ZeroInitialization = ZeroInit;
+  }
+
+  /// \brief Determine whether this constructor is actually constructing
+  /// a base class (rather than a complete object).
+  ConstructionKind getConstructionKind() const {
+    return (ConstructionKind)ConstructKind;
+  }
+  void setConstructionKind(ConstructionKind CK) {
+    ConstructKind = CK;
+  }
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator arg_begin() { return Args; }
+  arg_iterator arg_end() { return Args + NumArgs; }
+  const_arg_iterator arg_begin() const { return Args; }
+  const_arg_iterator arg_end() const { return Args + NumArgs; }
+
+  Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+  const Expr *const *getArgs() const {
+    return const_cast<CXXConstructExpr *>(this)->getArgs();
+  }
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(Args[Arg]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(Args[Arg]);
+  }
+
+  /// \brief Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    Args[Arg] = ArgExpr;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+  SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
+  void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXConstructExprClass ||
+      T->getStmtClass() == CXXTemporaryObjectExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&Args[0], &Args[0]+NumArgs);
+  }
+
+  friend class ASTStmtReader;
+};
+
+/// \brief Represents an explicit C++ type conversion that uses "functional"
+/// notation (C++ [expr.type.conv]).
+///
+/// Example:
+/// \code
+///   x = int(0.5);
+/// \endcode
+class CXXFunctionalCastExpr : public ExplicitCastExpr {
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+
+  CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
+                        TypeSourceInfo *writtenTy,
+                        CastKind kind, Expr *castExpr, unsigned pathSize,
+                        SourceLocation lParenLoc, SourceLocation rParenLoc)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
+                       castExpr, pathSize, writtenTy),
+      LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
+
+  explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
+
+public:
+  static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
+                                       ExprValueKind VK,
+                                       TypeSourceInfo *Written,
+                                       CastKind Kind, Expr *Op,
+                                       const CXXCastPath *Path,
+                                       SourceLocation LPLoc,
+                                       SourceLocation RPLoc);
+  static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
+                                            unsigned PathSize);
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXFunctionalCastExprClass;
+  }
+};
+
+/// @brief Represents a C++ functional cast expression that builds a
+/// temporary object.
+///
+/// This expression type represents a C++ "functional" cast
+/// (C++[expr.type.conv]) with N != 1 arguments that invokes a
+/// constructor to build a temporary object. With N == 1 arguments the
+/// functional cast expression will be represented by CXXFunctionalCastExpr.
+/// Example:
+/// \code
+/// struct X { X(int, float); }
+///
+/// X create_X() {
+///   return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
+/// };
+/// \endcode
+class CXXTemporaryObjectExpr : public CXXConstructExpr {
+  TypeSourceInfo *Type;
+
+public:
+  CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
+                         TypeSourceInfo *Type,
+                         ArrayRef<Expr *> Args,
+                         SourceRange ParenOrBraceRange,
+                         bool HadMultipleCandidates,
+                         bool ListInitialization,
+                         bool StdInitListInitialization,
+                         bool ZeroInitialization);
+  explicit CXXTemporaryObjectExpr(EmptyShell Empty)
+    : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
+
+  TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTemporaryObjectExprClass;
+  }
+
+  friend class ASTStmtReader;
+};
+
+/// \brief A C++ lambda expression, which produces a function object
+/// (of unspecified type) that can be invoked later.
+///
+/// Example:
+/// \code
+/// void low_pass_filter(std::vector<double> &values, double cutoff) {
+///   values.erase(std::remove_if(values.begin(), values.end(),
+///                               [=](double value) { return value > cutoff; });
+/// }
+/// \endcode
+///
+/// C++11 lambda expressions can capture local variables, either by copying
+/// the values of those local variables at the time the function
+/// object is constructed (not when it is called!) or by holding a
+/// reference to the local variable. These captures can occur either
+/// implicitly or can be written explicitly between the square
+/// brackets ([...]) that start the lambda expression.
+///
+/// C++1y introduces a new form of "capture" called an init-capture that
+/// includes an initializing expression (rather than capturing a variable),
+/// and which can never occur implicitly.
+class LambdaExpr : public Expr {
+  /// \brief The source range that covers the lambda introducer ([...]).
+  SourceRange IntroducerRange;
+
+  /// \brief The source location of this lambda's capture-default ('=' or '&').
+  SourceLocation CaptureDefaultLoc;
+
+  /// \brief The number of captures.
+  unsigned NumCaptures : 16;
+  
+  /// \brief The default capture kind, which is a value of type
+  /// LambdaCaptureDefault.
+  unsigned CaptureDefault : 2;
+
+  /// \brief Whether this lambda had an explicit parameter list vs. an
+  /// implicit (and empty) parameter list.
+  unsigned ExplicitParams : 1;
+
+  /// \brief Whether this lambda had the result type explicitly specified.
+  unsigned ExplicitResultType : 1;
+  
+  /// \brief Whether there are any array index variables stored at the end of
+  /// this lambda expression.
+  unsigned HasArrayIndexVars : 1;
+  
+  /// \brief The location of the closing brace ('}') that completes
+  /// the lambda.
+  /// 
+  /// The location of the brace is also available by looking up the
+  /// function call operator in the lambda class. However, it is
+  /// stored here to improve the performance of getSourceRange(), and
+  /// to avoid having to deserialize the function call operator from a
+  /// module file just to determine the source range.
+  SourceLocation ClosingBrace;
+
+  // Note: The capture initializers are stored directly after the lambda
+  // expression, along with the index variables used to initialize by-copy
+  // array captures.
+
+  typedef LambdaCapture Capture;
+
+  /// \brief Construct a lambda expression.
+  LambdaExpr(QualType T, SourceRange IntroducerRange,
+             LambdaCaptureDefault CaptureDefault,
+             SourceLocation CaptureDefaultLoc,
+             ArrayRef<Capture> Captures,
+             bool ExplicitParams,
+             bool ExplicitResultType,
+             ArrayRef<Expr *> CaptureInits,
+             ArrayRef<VarDecl *> ArrayIndexVars,
+             ArrayRef<unsigned> ArrayIndexStarts,
+             SourceLocation ClosingBrace,
+             bool ContainsUnexpandedParameterPack);
+
+  /// \brief Construct an empty lambda expression.
+  LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
+    : Expr(LambdaExprClass, Empty),
+      NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
+      ExplicitResultType(false), HasArrayIndexVars(true) { 
+    getStoredStmts()[NumCaptures] = nullptr;
+  }
+  
+  Stmt **getStoredStmts() const {
+    return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1);
+  }
+  
+  /// \brief Retrieve the mapping from captures to the first array index
+  /// variable.
+  unsigned *getArrayIndexStarts() const {
+    return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1);
+  }
+  
+  /// \brief Retrieve the complete set of array-index variables.
+  VarDecl **getArrayIndexVars() const {
+    unsigned ArrayIndexSize =
+        llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1),
+                                 llvm::alignOf<VarDecl*>());
+    return reinterpret_cast<VarDecl **>(
+        reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize);
+  }
+
+public:
+  /// \brief Construct a new lambda expression.
+  static LambdaExpr *Create(const ASTContext &C,
+                            CXXRecordDecl *Class,
+                            SourceRange IntroducerRange,
+                            LambdaCaptureDefault CaptureDefault,
+                            SourceLocation CaptureDefaultLoc,
+                            ArrayRef<Capture> Captures,
+                            bool ExplicitParams,
+                            bool ExplicitResultType,
+                            ArrayRef<Expr *> CaptureInits,
+                            ArrayRef<VarDecl *> ArrayIndexVars,
+                            ArrayRef<unsigned> ArrayIndexStarts,
+                            SourceLocation ClosingBrace,
+                            bool ContainsUnexpandedParameterPack);
+
+  /// \brief Construct a new lambda expression that will be deserialized from
+  /// an external source.
+  static LambdaExpr *CreateDeserialized(const ASTContext &C,
+                                        unsigned NumCaptures,
+                                        unsigned NumArrayIndexVars);
+
+  /// \brief Determine the default capture kind for this lambda.
+  LambdaCaptureDefault getCaptureDefault() const {
+    return static_cast<LambdaCaptureDefault>(CaptureDefault);
+  }
+
+  /// \brief Retrieve the location of this lambda's capture-default, if any.
+  SourceLocation getCaptureDefaultLoc() const {
+    return CaptureDefaultLoc;
+  }
+
+  /// \brief An iterator that walks over the captures of the lambda,
+  /// both implicit and explicit.
+  typedef const Capture *capture_iterator;
+
+  /// \brief An iterator over a range of lambda captures.
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+
+  /// \brief Retrieve this lambda's captures.
+  capture_range captures() const;
+  
+  /// \brief Retrieve an iterator pointing to the first lambda capture.
+  capture_iterator capture_begin() const;
+
+  /// \brief Retrieve an iterator pointing past the end of the
+  /// sequence of lambda captures.
+  capture_iterator capture_end() const;
+
+  /// \brief Determine the number of captures in this lambda.
+  unsigned capture_size() const { return NumCaptures; }
+
+  /// \brief Retrieve this lambda's explicit captures.
+  capture_range explicit_captures() const;
+  
+  /// \brief Retrieve an iterator pointing to the first explicit
+  /// lambda capture.
+  capture_iterator explicit_capture_begin() const;
+
+  /// \brief Retrieve an iterator pointing past the end of the sequence of
+  /// explicit lambda captures.
+  capture_iterator explicit_capture_end() const;
+
+  /// \brief Retrieve this lambda's implicit captures.
+  capture_range implicit_captures() const;
+
+  /// \brief Retrieve an iterator pointing to the first implicit
+  /// lambda capture.
+  capture_iterator implicit_capture_begin() const;
+
+  /// \brief Retrieve an iterator pointing past the end of the sequence of
+  /// implicit lambda captures.
+  capture_iterator implicit_capture_end() const;
+
+  /// \brief Iterator that walks over the capture initialization
+  /// arguments.
+  typedef Expr **capture_init_iterator;
+
+  /// \brief Retrieve the initialization expressions for this lambda's captures.
+  llvm::iterator_range<capture_init_iterator> capture_inits() const {
+    return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+                                                       capture_init_end());
+  }
+
+  /// \brief Retrieve the first initialization argument for this
+  /// lambda expression (which initializes the first capture field).
+  capture_init_iterator capture_init_begin() const {
+    return reinterpret_cast<Expr **>(getStoredStmts());
+  }
+
+  /// \brief Retrieve the iterator pointing one past the last
+  /// initialization argument for this lambda expression.
+  capture_init_iterator capture_init_end() const {
+    return capture_init_begin() + NumCaptures;    
+  }
+
+  /// \brief Retrieve the set of index variables used in the capture 
+  /// initializer of an array captured by copy.
+  ///
+  /// \param Iter The iterator that points at the capture initializer for 
+  /// which we are extracting the corresponding index variables.
+  ArrayRef<VarDecl *> getCaptureInitIndexVars(capture_init_iterator Iter) const;
+  
+  /// \brief Retrieve the source range covering the lambda introducer,
+  /// which contains the explicit capture list surrounded by square
+  /// brackets ([...]).
+  SourceRange getIntroducerRange() const { return IntroducerRange; }
+
+  /// \brief Retrieve the class that corresponds to the lambda.
+  /// 
+  /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
+  /// captures in its fields and provides the various operations permitted
+  /// on a lambda (copying, calling).
+  CXXRecordDecl *getLambdaClass() const;
+
+  /// \brief Retrieve the function call operator associated with this
+  /// lambda expression. 
+  CXXMethodDecl *getCallOperator() const;
+
+  /// \brief If this is a generic lambda expression, retrieve the template 
+  /// parameter list associated with it, or else return null. 
+  TemplateParameterList *getTemplateParameterList() const;
+
+  /// \brief Whether this is a generic lambda.
+  bool isGenericLambda() const { return getTemplateParameterList(); }
+
+  /// \brief Retrieve the body of the lambda.
+  CompoundStmt *getBody() const;
+
+  /// \brief Determine whether the lambda is mutable, meaning that any
+  /// captures values can be modified.
+  bool isMutable() const;
+
+  /// \brief Determine whether this lambda has an explicit parameter
+  /// list vs. an implicit (empty) parameter list.
+  bool hasExplicitParameters() const { return ExplicitParams; }
+
+  /// \brief Whether this lambda had its result type explicitly specified.
+  bool hasExplicitResultType() const { return ExplicitResultType; }
+    
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == LambdaExprClass;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return IntroducerRange.getBegin();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; }
+
+  child_range children() {
+    return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// An expression "T()" which creates a value-initialized rvalue of type
+/// T, which is a non-class type.  See (C++98 [5.2.3p2]).
+class CXXScalarValueInitExpr : public Expr {
+  SourceLocation RParenLoc;
+  TypeSourceInfo *TypeInfo;
+
+  friend class ASTStmtReader;
+
+public:
+  /// \brief Create an explicitly-written scalar-value initialization
+  /// expression.
+  CXXScalarValueInitExpr(QualType Type,
+                         TypeSourceInfo *TypeInfo,
+                         SourceLocation rParenLoc ) :
+    Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
+         false, false, Type->isInstantiationDependentType(), false),
+    RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
+
+  explicit CXXScalarValueInitExpr(EmptyShell Shell)
+    : Expr(CXXScalarValueInitExprClass, Shell) { }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return TypeInfo;
+  }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXScalarValueInitExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief Represents a new-expression for memory allocation and constructor
+/// calls, e.g: "new CXXNewExpr(foo)".
+class CXXNewExpr : public Expr {
+  /// Contains an optional array size expression, an optional initialization
+  /// expression, and any number of optional placement arguments, in that order.
+  Stmt **SubExprs;
+  /// \brief Points to the allocation function used.
+  FunctionDecl *OperatorNew;
+  /// \brief Points to the deallocation function used in case of error. May be
+  /// null.
+  FunctionDecl *OperatorDelete;
+
+  /// \brief The allocated type-source information, as written in the source.
+  TypeSourceInfo *AllocatedTypeInfo;
+
+  /// \brief If the allocated type was expressed as a parenthesized type-id,
+  /// the source range covering the parenthesized type-id.
+  SourceRange TypeIdParens;
+
+  /// \brief Range of the entire new expression.
+  SourceRange Range;
+
+  /// \brief Source-range of a paren-delimited initializer.
+  SourceRange DirectInitRange;
+
+  /// Was the usage ::new, i.e. is the global new to be used?
+  bool GlobalNew : 1;
+  /// Do we allocate an array? If so, the first SubExpr is the size expression.
+  bool Array : 1;
+  /// If this is an array allocation, does the usual deallocation
+  /// function for the allocated type want to know the allocated size?
+  bool UsualArrayDeleteWantsSize : 1;
+  /// The number of placement new arguments.
+  unsigned NumPlacementArgs : 13;
+  /// What kind of initializer do we have? Could be none, parens, or braces.
+  /// In storage, we distinguish between "none, and no initializer expr", and
+  /// "none, but an implicit initializer expr".
+  unsigned StoredInitializationStyle : 2;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+public:
+  enum InitializationStyle {
+    NoInit,   ///< New-expression has no initializer as written.
+    CallInit, ///< New-expression has a C++98 paren-delimited initializer.
+    ListInit  ///< New-expression has a C++11 list-initializer.
+  };
+
+  CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
+             FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
+             ArrayRef<Expr*> placementArgs,
+             SourceRange typeIdParens, Expr *arraySize,
+             InitializationStyle initializationStyle, Expr *initializer,
+             QualType ty, TypeSourceInfo *AllocatedTypeInfo,
+             SourceRange Range, SourceRange directInitRange);
+  explicit CXXNewExpr(EmptyShell Shell)
+    : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
+
+  void AllocateArgsArray(const ASTContext &C, bool isArray,
+                         unsigned numPlaceArgs, bool hasInitializer);
+
+  QualType getAllocatedType() const {
+    assert(getType()->isPointerType());
+    return getType()->getAs<PointerType>()->getPointeeType();
+  }
+
+  TypeSourceInfo *getAllocatedTypeSourceInfo() const {
+    return AllocatedTypeInfo;
+  }
+
+  /// \brief True if the allocation result needs to be null-checked.
+  ///
+  /// C++11 [expr.new]p13:
+  ///   If the allocation function returns null, initialization shall
+  ///   not be done, the deallocation function shall not be called,
+  ///   and the value of the new-expression shall be null.
+  ///
+  /// An allocation function is not allowed to return null unless it
+  /// has a non-throwing exception-specification.  The '03 rule is
+  /// identical except that the definition of a non-throwing
+  /// exception specification is just "is it throw()?".
+  bool shouldNullCheckAllocation(const ASTContext &Ctx) const;
+
+  FunctionDecl *getOperatorNew() const { return OperatorNew; }
+  void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
+  FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+  void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
+
+  bool isArray() const { return Array; }
+  Expr *getArraySize() {
+    return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+  }
+  const Expr *getArraySize() const {
+    return Array ? cast<Expr>(SubExprs[0]) : nullptr;
+  }
+
+  unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
+  Expr **getPlacementArgs() {
+    return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
+  }
+
+  Expr *getPlacementArg(unsigned i) {
+    assert(i < NumPlacementArgs && "Index out of range");
+    return getPlacementArgs()[i];
+  }
+  const Expr *getPlacementArg(unsigned i) const {
+    assert(i < NumPlacementArgs && "Index out of range");
+    return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
+  }
+
+  bool isParenTypeId() const { return TypeIdParens.isValid(); }
+  SourceRange getTypeIdParens() const { return TypeIdParens; }
+
+  bool isGlobalNew() const { return GlobalNew; }
+
+  /// \brief Whether this new-expression has any initializer at all.
+  bool hasInitializer() const { return StoredInitializationStyle > 0; }
+
+  /// \brief The kind of initializer this new-expression has.
+  InitializationStyle getInitializationStyle() const {
+    if (StoredInitializationStyle == 0)
+      return NoInit;
+    return static_cast<InitializationStyle>(StoredInitializationStyle-1);
+  }
+
+  /// \brief The initializer of this new-expression.
+  Expr *getInitializer() {
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+  }
+  const Expr *getInitializer() const {
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
+  }
+
+  /// \brief Returns the CXXConstructExpr from this new-expression, or null.
+  const CXXConstructExpr* getConstructExpr() const {
+    return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
+  }
+
+  /// Answers whether the usual array deallocation function for the
+  /// allocated type expects the size of the allocation as a
+  /// parameter.
+  bool doesUsualArrayDeleteWantSize() const {
+    return UsualArrayDeleteWantsSize;
+  }
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator placement_arg_begin() {
+    return SubExprs + Array + hasInitializer();
+  }
+  arg_iterator placement_arg_end() {
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+  }
+  const_arg_iterator placement_arg_begin() const {
+    return SubExprs + Array + hasInitializer();
+  }
+  const_arg_iterator placement_arg_end() const {
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+  }
+
+  typedef Stmt **raw_arg_iterator;
+  raw_arg_iterator raw_arg_begin() { return SubExprs; }
+  raw_arg_iterator raw_arg_end() {
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+  }
+  const_arg_iterator raw_arg_begin() const { return SubExprs; }
+  const_arg_iterator raw_arg_end() const {
+    return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
+  }
+
+  SourceLocation getStartLoc() const { return Range.getBegin(); }
+  SourceLocation getEndLoc() const { return Range.getEnd(); }
+
+  SourceRange getDirectInitRange() const { return DirectInitRange; }
+
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return Range;
+  }
+  SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNewExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(raw_arg_begin(), raw_arg_end());
+  }
+};
+
+/// \brief Represents a \c delete expression for memory deallocation and
+/// destructor calls, e.g. "delete[] pArray".
+class CXXDeleteExpr : public Expr {
+  /// Points to the operator delete overload that is used. Could be a member.
+  FunctionDecl *OperatorDelete;
+  /// The pointer expression to be deleted.
+  Stmt *Argument;
+  /// Location of the expression.
+  SourceLocation Loc;
+  /// Is this a forced global delete, i.e. "::delete"?
+  bool GlobalDelete : 1;
+  /// Is this the array form of delete, i.e. "delete[]"?
+  bool ArrayForm : 1;
+  /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied
+  /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm
+  /// will be true).
+  bool ArrayFormAsWritten : 1;
+  /// Does the usual deallocation function for the element type require
+  /// a size_t argument?
+  bool UsualArrayDeleteWantsSize : 1;
+public:
+  CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm,
+                bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
+                FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
+    : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
+           arg->isInstantiationDependent(),
+           arg->containsUnexpandedParameterPack()),
+      OperatorDelete(operatorDelete), Argument(arg), Loc(loc),
+      GlobalDelete(globalDelete),
+      ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
+      UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
+  explicit CXXDeleteExpr(EmptyShell Shell)
+    : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
+      Argument(nullptr) {}
+
+  bool isGlobalDelete() const { return GlobalDelete; }
+  bool isArrayForm() const { return ArrayForm; }
+  bool isArrayFormAsWritten() const { return ArrayFormAsWritten; }
+
+  /// Answers whether the usual array deallocation function for the
+  /// allocated type expects the size of the allocation as a
+  /// parameter.  This can be true even if the actual deallocation
+  /// function that we're using doesn't want a size.
+  bool doesUsualArrayDeleteWantSize() const {
+    return UsualArrayDeleteWantsSize;
+  }
+
+  FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+
+  Expr *getArgument() { return cast<Expr>(Argument); }
+  const Expr *getArgument() const { return cast<Expr>(Argument); }
+
+  /// \brief Retrieve the type being destroyed. 
+  ///
+  /// If the type being destroyed is a dependent type which may or may not
+  /// be a pointer, return an invalid type.
+  QualType getDestroyedType() const;
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {return Argument->getLocEnd();}
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDeleteExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Argument, &Argument+1); }
+
+  friend class ASTStmtReader;
+};
+
+/// \brief Stores the type being destroyed by a pseudo-destructor expression.
+class PseudoDestructorTypeStorage {
+  /// \brief Either the type source information or the name of the type, if
+  /// it couldn't be resolved due to type-dependence.
+  llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
+
+  /// \brief The starting source location of the pseudo-destructor type.
+  SourceLocation Location;
+
+public:
+  PseudoDestructorTypeStorage() { }
+
+  PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
+    : Type(II), Location(Loc) { }
+
+  PseudoDestructorTypeStorage(TypeSourceInfo *Info);
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    return Type.dyn_cast<TypeSourceInfo *>();
+  }
+
+  IdentifierInfo *getIdentifier() const {
+    return Type.dyn_cast<IdentifierInfo *>();
+  }
+
+  SourceLocation getLocation() const { return Location; }
+};
+
+/// \brief Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
+///
+/// A pseudo-destructor is an expression that looks like a member access to a
+/// destructor of a scalar type, except that scalar types don't have
+/// destructors. For example:
+///
+/// \code
+/// typedef int T;
+/// void f(int *p) {
+///   p->T::~T();
+/// }
+/// \endcode
+///
+/// Pseudo-destructors typically occur when instantiating templates such as:
+///
+/// \code
+/// template<typename T>
+/// void destroy(T* ptr) {
+///   ptr->T::~T();
+/// }
+/// \endcode
+///
+/// for scalar types. A pseudo-destructor expression has no run-time semantics
+/// beyond evaluating the base expression.
+class CXXPseudoDestructorExpr : public Expr {
+  /// \brief The base expression (that is being destroyed).
+  Stmt *Base;
+
+  /// \brief Whether the operator was an arrow ('->'); otherwise, it was a
+  /// period ('.').
+  bool IsArrow : 1;
+
+  /// \brief The location of the '.' or '->' operator.
+  SourceLocation OperatorLoc;
+
+  /// \brief The nested-name-specifier that follows the operator, if present.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief The type that precedes the '::' in a qualified pseudo-destructor
+  /// expression.
+  TypeSourceInfo *ScopeType;
+
+  /// \brief The location of the '::' in a qualified pseudo-destructor
+  /// expression.
+  SourceLocation ColonColonLoc;
+
+  /// \brief The location of the '~'.
+  SourceLocation TildeLoc;
+
+  /// \brief The type being destroyed, or its name if we were unable to
+  /// resolve the name.
+  PseudoDestructorTypeStorage DestroyedType;
+
+  friend class ASTStmtReader;
+
+public:
+  CXXPseudoDestructorExpr(const ASTContext &Context,
+                          Expr *Base, bool isArrow, SourceLocation OperatorLoc,
+                          NestedNameSpecifierLoc QualifierLoc,
+                          TypeSourceInfo *ScopeType,
+                          SourceLocation ColonColonLoc,
+                          SourceLocation TildeLoc,
+                          PseudoDestructorTypeStorage DestroyedType);
+
+  explicit CXXPseudoDestructorExpr(EmptyShell Shell)
+    : Expr(CXXPseudoDestructorExprClass, Shell),
+      Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
+
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  /// \brief Determines whether this member expression actually had
+  /// a C++ nested-name-specifier prior to the name of the member, e.g.,
+  /// x->Base::foo.
+  bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
+
+  /// \brief Retrieves the nested-name-specifier that qualifies the type name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief If the member name was qualified, retrieves the
+  /// nested-name-specifier that precedes the member name. Otherwise, returns
+  /// null.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief Determine whether this pseudo-destructor expression was written
+  /// using an '->' (otherwise, it used a '.').
+  bool isArrow() const { return IsArrow; }
+
+  /// \brief Retrieve the location of the '.' or '->' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+
+  /// \brief Retrieve the scope type in a qualified pseudo-destructor
+  /// expression.
+  ///
+  /// Pseudo-destructor expressions can have extra qualification within them
+  /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
+  /// Here, if the object type of the expression is (or may be) a scalar type,
+  /// \p T may also be a scalar type and, therefore, cannot be part of a
+  /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
+  /// destructor expression.
+  TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
+
+  /// \brief Retrieve the location of the '::' in a qualified pseudo-destructor
+  /// expression.
+  SourceLocation getColonColonLoc() const { return ColonColonLoc; }
+
+  /// \brief Retrieve the location of the '~'.
+  SourceLocation getTildeLoc() const { return TildeLoc; }
+
+  /// \brief Retrieve the source location information for the type
+  /// being destroyed.
+  ///
+  /// This type-source information is available for non-dependent
+  /// pseudo-destructor expressions and some dependent pseudo-destructor
+  /// expressions. Returns null if we only have the identifier for a
+  /// dependent pseudo-destructor expression.
+  TypeSourceInfo *getDestroyedTypeInfo() const {
+    return DestroyedType.getTypeSourceInfo();
+  }
+
+  /// \brief In a dependent pseudo-destructor expression for which we do not
+  /// have full type information on the destroyed type, provides the name
+  /// of the destroyed type.
+  IdentifierInfo *getDestroyedTypeIdentifier() const {
+    return DestroyedType.getIdentifier();
+  }
+
+  /// \brief Retrieve the type being destroyed.
+  QualType getDestroyedType() const;
+
+  /// \brief Retrieve the starting location of the type being destroyed.
+  SourceLocation getDestroyedTypeLoc() const {
+    return DestroyedType.getLocation();
+  }
+
+  /// \brief Set the name of destroyed type for a dependent pseudo-destructor
+  /// expression.
+  void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
+    DestroyedType = PseudoDestructorTypeStorage(II, Loc);
+  }
+
+  /// \brief Set the destroyed type.
+  void setDestroyedType(TypeSourceInfo *Info) {
+    DestroyedType = PseudoDestructorTypeStorage(Info);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {return Base->getLocStart();}
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXPseudoDestructorExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Base, &Base + 1); }
+};
+
+/// \brief A type trait used in the implementation of various C++11 and
+/// Library TR1 trait templates.
+///
+/// \code
+///   __is_pod(int) == true
+///   __is_enum(std::string) == false
+///   __is_trivially_constructible(vector<int>, int*, int*)
+/// \endcode
+class TypeTraitExpr : public Expr {
+  /// \brief The location of the type trait keyword.
+  SourceLocation Loc;
+  
+  /// \brief  The location of the closing parenthesis.
+  SourceLocation RParenLoc;
+  
+  // Note: The TypeSourceInfos for the arguments are allocated after the
+  // TypeTraitExpr.
+  
+  TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
+                ArrayRef<TypeSourceInfo *> Args,
+                SourceLocation RParenLoc,
+                bool Value);
+
+  TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
+
+  /// \brief Retrieve the argument types.
+  TypeSourceInfo **getTypeSourceInfos() {
+    return reinterpret_cast<TypeSourceInfo **>(this+1);
+  }
+  
+  /// \brief Retrieve the argument types.
+  TypeSourceInfo * const *getTypeSourceInfos() const {
+    return reinterpret_cast<TypeSourceInfo * const*>(this+1);
+  }
+  
+public:
+  /// \brief Create a new type trait expression.
+  static TypeTraitExpr *Create(const ASTContext &C, QualType T,
+                               SourceLocation Loc, TypeTrait Kind,
+                               ArrayRef<TypeSourceInfo *> Args,
+                               SourceLocation RParenLoc,
+                               bool Value);
+
+  static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
+                                           unsigned NumArgs);
+  
+  /// \brief Determine which type trait this expression uses.
+  TypeTrait getTrait() const {
+    return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
+  }
+
+  bool getValue() const { 
+    assert(!isValueDependent()); 
+    return TypeTraitExprBits.Value; 
+  }
+  
+  /// \brief Determine the number of arguments to this type trait.
+  unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
+  
+  /// \brief Retrieve the Ith argument.
+  TypeSourceInfo *getArg(unsigned I) const {
+    assert(I < getNumArgs() && "Argument out-of-range");
+    return getArgs()[I];
+  }
+  
+  /// \brief Retrieve the argument types.
+  ArrayRef<TypeSourceInfo *> getArgs() const { 
+    return ArrayRef<TypeSourceInfo *>(getTypeSourceInfos(), getNumArgs());
+  }
+  
+  typedef TypeSourceInfo **arg_iterator;
+  arg_iterator arg_begin() { 
+    return getTypeSourceInfos(); 
+  }
+  arg_iterator arg_end() { 
+    return getTypeSourceInfos() + getNumArgs(); 
+  }
+
+  typedef TypeSourceInfo const * const *arg_const_iterator;
+  arg_const_iterator arg_begin() const { return getTypeSourceInfos(); }
+  arg_const_iterator arg_end() const { 
+    return getTypeSourceInfos() + getNumArgs(); 
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == TypeTraitExprClass;
+  }
+  
+  // Iterators
+  child_range children() { return child_range(); }
+  
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+};
+
+/// \brief An Embarcadero array type trait, as used in the implementation of
+/// __array_rank and __array_extent.
+///
+/// Example:
+/// \code
+///   __array_rank(int[10][20]) == 2
+///   __array_extent(int, 1)    == 20
+/// \endcode
+class ArrayTypeTraitExpr : public Expr {
+  virtual void anchor();
+
+  /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+  unsigned ATT : 2;
+
+  /// \brief The value of the type trait. Unspecified if dependent.
+  uint64_t Value;
+
+  /// \brief The array dimension being queried, or -1 if not used.
+  Expr *Dimension;
+
+  /// \brief The location of the type trait keyword.
+  SourceLocation Loc;
+
+  /// \brief The location of the closing paren.
+  SourceLocation RParen;
+
+  /// \brief The type being queried.
+  TypeSourceInfo *QueriedType;
+
+public:
+  ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
+                     TypeSourceInfo *queried, uint64_t value,
+                     Expr *dimension, SourceLocation rparen, QualType ty)
+    : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
+           false, queried->getType()->isDependentType(),
+           (queried->getType()->isInstantiationDependentType() ||
+            (dimension && dimension->isInstantiationDependent())),
+           queried->getType()->containsUnexpandedParameterPack()),
+      ATT(att), Value(value), Dimension(dimension),
+      Loc(loc), RParen(rparen), QueriedType(queried) { }
+
+
+  explicit ArrayTypeTraitExpr(EmptyShell Empty)
+    : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
+      QueriedType() { }
+
+  virtual ~ArrayTypeTraitExpr() { }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
+
+  ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
+
+  QualType getQueriedType() const { return QueriedType->getType(); }
+
+  TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
+
+  uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
+
+  Expr *getDimensionExpression() const { return Dimension; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ArrayTypeTraitExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+};
+
+/// \brief An expression trait intrinsic.
+///
+/// Example:
+/// \code
+///   __is_lvalue_expr(std::cout) == true
+///   __is_lvalue_expr(1) == false
+/// \endcode
+class ExpressionTraitExpr : public Expr {
+  /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned.
+  unsigned ET : 31;
+  /// \brief The value of the type trait. Unspecified if dependent.
+  bool Value : 1;
+
+  /// \brief The location of the type trait keyword.
+  SourceLocation Loc;
+
+  /// \brief The location of the closing paren.
+  SourceLocation RParen;
+
+  /// \brief The expression being queried.
+  Expr* QueriedExpression;
+public:
+  ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
+                     Expr *queried, bool value,
+                     SourceLocation rparen, QualType resultType)
+    : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
+           false, // Not type-dependent
+           // Value-dependent if the argument is type-dependent.
+           queried->isTypeDependent(),
+           queried->isInstantiationDependent(),
+           queried->containsUnexpandedParameterPack()),
+      ET(et), Value(value), Loc(loc), RParen(rparen),
+      QueriedExpression(queried) { }
+
+  explicit ExpressionTraitExpr(EmptyShell Empty)
+    : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
+      QueriedExpression() { }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
+
+  ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
+
+  Expr *getQueriedExpression() const { return QueriedExpression; }
+
+  bool getValue() const { return Value; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ExpressionTraitExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+};
+
+
+/// \brief A reference to an overloaded function set, either an
+/// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
+class OverloadExpr : public Expr {
+  /// \brief The common name of these declarations.
+  DeclarationNameInfo NameInfo;
+
+  /// \brief The nested-name-specifier that qualifies the name, if any.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// The results.  These are undesugared, which is to say, they may
+  /// include UsingShadowDecls.  Access is relative to the naming
+  /// class.
+  // FIXME: Allocate this data after the OverloadExpr subclass.
+  DeclAccessPair *Results;
+  unsigned NumResults;
+
+protected:
+  /// \brief Whether the name includes info for explicit template
+  /// keyword and arguments.
+  bool HasTemplateKWAndArgsInfo;
+
+  /// \brief Return the optional template keyword and arguments info.
+  ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo(); // defined far below.
+
+  /// \brief Return the optional template keyword and arguments info.
+  const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
+    return const_cast<OverloadExpr*>(this)->getTemplateKWAndArgsInfo();
+  }
+
+  OverloadExpr(StmtClass K, const ASTContext &C,
+               NestedNameSpecifierLoc QualifierLoc,
+               SourceLocation TemplateKWLoc,
+               const DeclarationNameInfo &NameInfo,
+               const TemplateArgumentListInfo *TemplateArgs,
+               UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+               bool KnownDependent,
+               bool KnownInstantiationDependent,
+               bool KnownContainsUnexpandedParameterPack);
+
+  OverloadExpr(StmtClass K, EmptyShell Empty)
+    : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
+      HasTemplateKWAndArgsInfo(false) { }
+
+  void initializeResults(const ASTContext &C,
+                         UnresolvedSetIterator Begin,
+                         UnresolvedSetIterator End);
+
+public:
+  struct FindResult {
+    OverloadExpr *Expression;
+    bool IsAddressOfOperand;
+    bool HasFormOfMemberPointer;
+  };
+
+  /// \brief Finds the overloaded expression in the given expression \p E of
+  /// OverloadTy.
+  ///
+  /// \return the expression (which must be there) and true if it has
+  /// the particular form of a member pointer expression
+  static FindResult find(Expr *E) {
+    assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
+
+    FindResult Result;
+
+    E = E->IgnoreParens();
+    if (isa<UnaryOperator>(E)) {
+      assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
+      E = cast<UnaryOperator>(E)->getSubExpr();
+      OverloadExpr *Ovl = cast<OverloadExpr>(E->IgnoreParens());
+
+      Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
+      Result.IsAddressOfOperand = true;
+      Result.Expression = Ovl;
+    } else {
+      Result.HasFormOfMemberPointer = false;
+      Result.IsAddressOfOperand = false;
+      Result.Expression = cast<OverloadExpr>(E);
+    }
+
+    return Result;
+  }
+
+  /// \brief Gets the naming class of this lookup, if any.
+  CXXRecordDecl *getNamingClass() const;
+
+  typedef UnresolvedSetImpl::iterator decls_iterator;
+  decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
+  decls_iterator decls_end() const {
+    return UnresolvedSetIterator(Results + NumResults);
+  }
+  llvm::iterator_range<decls_iterator> decls() const {
+    return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+  }
+
+  /// \brief Gets the number of declarations in the unresolved set.
+  unsigned getNumDecls() const { return NumResults; }
+
+  /// \brief Gets the full name info.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+
+  /// \brief Gets the name looked up.
+  DeclarationName getName() const { return NameInfo.getName(); }
+
+  /// \brief Gets the location of the name.
+  SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
+
+  /// \brief Fetches the nested-name qualifier, if one was given.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief Fetches the nested-name qualifier with source-location
+  /// information, if one was given.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the location of the template keyword preceding
+  /// this name, if any.
+  SourceLocation getTemplateKeywordLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc();
+  }
+
+  /// \brief Retrieve the location of the left angle bracket starting the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getLAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket ending the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getRAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->RAngleLoc;
+  }
+
+  /// \brief Determines whether the name was preceded by the template keyword.
+  bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+
+  /// \brief Determines whether this expression had explicit template arguments.
+  bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
+
+  // Note that, inconsistently with the explicit-template-argument AST
+  // nodes, users are *forbidden* from calling these methods on objects
+  // without explicit template arguments.
+
+  ASTTemplateArgumentListInfo &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *getTemplateKWAndArgsInfo();
+  }
+
+  const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const {
+    return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
+  }
+
+  TemplateArgumentLoc const *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  /// \brief Copies the template arguments into the given structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  ///
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return nullptr;
+    return &getExplicitTemplateArgs();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedLookupExprClass ||
+           T->getStmtClass() == UnresolvedMemberExprClass;
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration.
+///
+/// This arises in several ways:
+///   * we might be waiting for argument-dependent lookup;
+///   * the name might resolve to an overloaded function;
+/// and eventually:
+///   * the lookup might have included a function template.
+///
+/// These never include UnresolvedUsingValueDecls, which are always class
+/// members and therefore appear only in UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public OverloadExpr {
+  /// True if these lookup results should be extended by
+  /// argument-dependent lookup if this is the operand of a function
+  /// call.
+  bool RequiresADL;
+
+  /// True if these lookup results are overloaded.  This is pretty
+  /// trivially rederivable if we urgently need to kill this field.
+  bool Overloaded;
+
+  /// The naming class (C++ [class.access.base]p5) of the lookup, if
+  /// any.  This can generally be recalculated from the context chain,
+  /// but that can be fairly expensive for unqualified lookups.  If we
+  /// want to improve memory use here, this could go in a union
+  /// against the qualified-lookup bits.
+  CXXRecordDecl *NamingClass;
+
+  UnresolvedLookupExpr(const ASTContext &C,
+                       CXXRecordDecl *NamingClass,
+                       NestedNameSpecifierLoc QualifierLoc,
+                       SourceLocation TemplateKWLoc,
+                       const DeclarationNameInfo &NameInfo,
+                       bool RequiresADL, bool Overloaded,
+                       const TemplateArgumentListInfo *TemplateArgs,
+                       UnresolvedSetIterator Begin, UnresolvedSetIterator End)
+    : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc,
+                   NameInfo, TemplateArgs, Begin, End, false, false, false),
+      RequiresADL(RequiresADL),
+      Overloaded(Overloaded), NamingClass(NamingClass)
+  {}
+
+  UnresolvedLookupExpr(EmptyShell Empty)
+    : OverloadExpr(UnresolvedLookupExprClass, Empty),
+      RequiresADL(false), Overloaded(false), NamingClass(nullptr)
+  {}
+
+  friend class ASTStmtReader;
+
+public:
+  static UnresolvedLookupExpr *Create(const ASTContext &C,
+                                      CXXRecordDecl *NamingClass,
+                                      NestedNameSpecifierLoc QualifierLoc,
+                                      const DeclarationNameInfo &NameInfo,
+                                      bool ADL, bool Overloaded,
+                                      UnresolvedSetIterator Begin,
+                                      UnresolvedSetIterator End) {
+    return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
+                                       SourceLocation(), NameInfo,
+                                       ADL, Overloaded, nullptr, Begin, End);
+  }
+
+  static UnresolvedLookupExpr *Create(const ASTContext &C,
+                                      CXXRecordDecl *NamingClass,
+                                      NestedNameSpecifierLoc QualifierLoc,
+                                      SourceLocation TemplateKWLoc,
+                                      const DeclarationNameInfo &NameInfo,
+                                      bool ADL,
+                                      const TemplateArgumentListInfo *Args,
+                                      UnresolvedSetIterator Begin,
+                                      UnresolvedSetIterator End);
+
+  static UnresolvedLookupExpr *CreateEmpty(const ASTContext &C,
+                                           bool HasTemplateKWAndArgsInfo,
+                                           unsigned NumTemplateArgs);
+
+  /// True if this declaration should be extended by
+  /// argument-dependent lookup.
+  bool requiresADL() const { return RequiresADL; }
+
+  /// True if this lookup is overloaded.
+  bool isOverloaded() const { return Overloaded; }
+
+  /// Gets the 'naming class' (in the sense of C++0x
+  /// [class.access.base]p5) of the lookup.  This is the scope
+  /// that was looked in to find these results.
+  CXXRecordDecl *getNamingClass() const { return NamingClass; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    if (NestedNameSpecifierLoc l = getQualifierLoc())
+      return l.getBeginLoc();
+    return getNameInfo().getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (hasExplicitTemplateArgs())
+      return getRAngleLoc();
+    return getNameInfo().getLocEnd();
+  }
+
+  child_range children() { return child_range(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedLookupExprClass;
+  }
+};
+
+/// \brief A qualified reference to a name whose declaration cannot
+/// yet be resolved.
+///
+/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
+/// it expresses a reference to a declaration such as
+/// X<T>::value. The difference, however, is that an
+/// DependentScopeDeclRefExpr node is used only within C++ templates when
+/// the qualification (e.g., X<T>::) refers to a dependent type. In
+/// this case, X<T>::value cannot resolve to a declaration because the
+/// declaration will differ from one instantiation of X<T> to the
+/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
+/// qualifier (X<T>::) and the name of the entity being referenced
+/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
+/// declaration can be found.
+class DependentScopeDeclRefExpr : public Expr {
+  /// \brief The nested-name-specifier that qualifies this unresolved
+  /// declaration name.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief The name of the entity we will be referencing.
+  DeclarationNameInfo NameInfo;
+
+  /// \brief Whether the name includes info for explicit template
+  /// keyword and arguments.
+  bool HasTemplateKWAndArgsInfo;
+
+  /// \brief Return the optional template keyword and arguments info.
+  ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
+    if (!HasTemplateKWAndArgsInfo) return nullptr;
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
+  }
+  /// \brief Return the optional template keyword and arguments info.
+  const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
+    return const_cast<DependentScopeDeclRefExpr*>(this)
+      ->getTemplateKWAndArgsInfo();
+  }
+
+  DependentScopeDeclRefExpr(QualType T,
+                            NestedNameSpecifierLoc QualifierLoc,
+                            SourceLocation TemplateKWLoc,
+                            const DeclarationNameInfo &NameInfo,
+                            const TemplateArgumentListInfo *Args);
+
+public:
+  static DependentScopeDeclRefExpr *Create(const ASTContext &C,
+                                           NestedNameSpecifierLoc QualifierLoc,
+                                           SourceLocation TemplateKWLoc,
+                                           const DeclarationNameInfo &NameInfo,
+                              const TemplateArgumentListInfo *TemplateArgs);
+
+  static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &C,
+                                                bool HasTemplateKWAndArgsInfo,
+                                                unsigned NumTemplateArgs);
+
+  /// \brief Retrieve the name that this expression refers to.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+
+  /// \brief Retrieve the name that this expression refers to.
+  DeclarationName getDeclName() const { return NameInfo.getName(); }
+
+  /// \brief Retrieve the location of the name within the expression.
+  ///
+  /// For example, in "X<T>::value" this is the location of "value".
+  SourceLocation getLocation() const { return NameInfo.getLoc(); }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name, with source location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies this
+  /// declaration.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief Retrieve the location of the template keyword preceding
+  /// this name, if any.
+  SourceLocation getTemplateKeywordLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc();
+  }
+
+  /// \brief Retrieve the location of the left angle bracket starting the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getLAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket ending the
+  /// explicit template argument list following the name, if any.
+  SourceLocation getRAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->RAngleLoc;
+  }
+
+  /// Determines whether the name was preceded by the template keyword.
+  bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+
+  /// Determines whether this lookup had explicit template arguments.
+  bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
+
+  // Note that, inconsistently with the explicit-template-argument AST
+  // nodes, users are *forbidden* from calling these methods on objects
+  // without explicit template arguments.
+
+  ASTTemplateArgumentListInfo &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ASTTemplateArgumentListInfo*>(this + 1);
+  }
+
+  /// Gets a reference to the explicit template argument list.
+  const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<const ASTTemplateArgumentListInfo*>(this + 1);
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  ///
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return nullptr;
+    return &getExplicitTemplateArgs();
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+
+  TemplateArgumentLoc const *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr,
+  /// and differs from getLocation().getStart().
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return QualifierLoc.getBeginLoc();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (hasExplicitTemplateArgs())
+      return getRAngleLoc();
+    return getLocation();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DependentScopeDeclRefExprClass;
+  }
+
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// Represents an expression -- generally a full-expression -- that
+/// introduces cleanups to be run at the end of the sub-expression's
+/// evaluation.  The most common source of expression-introduced
+/// cleanups is temporary objects in C++, but several other kinds of
+/// expressions can create cleanups, including basically every
+/// call in ARC that returns an Objective-C pointer.
+///
+/// This expression also tracks whether the sub-expression contains a
+/// potentially-evaluated block literal.  The lifetime of a block
+/// literal is the extent of the enclosing scope.
+class ExprWithCleanups : public Expr {
+public:
+  /// The type of objects that are kept in the cleanup.
+  /// It's useful to remember the set of blocks;  we could also
+  /// remember the set of temporaries, but there's currently
+  /// no need.
+  typedef BlockDecl *CleanupObject;
+
+private:
+  Stmt *SubExpr;
+
+  ExprWithCleanups(EmptyShell, unsigned NumObjects);
+  ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects);
+
+  CleanupObject *getObjectsBuffer() {
+    return reinterpret_cast<CleanupObject*>(this + 1);
+  }
+  const CleanupObject *getObjectsBuffer() const {
+    return reinterpret_cast<const CleanupObject*>(this + 1);
+  }
+  friend class ASTStmtReader;
+
+public:
+  static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
+                                  unsigned numObjects);
+
+  static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
+                                  ArrayRef<CleanupObject> objects);
+
+  ArrayRef<CleanupObject> getObjects() const {
+    return ArrayRef<CleanupObject>(getObjectsBuffer(), getNumObjects());
+  }
+
+  unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
+
+  CleanupObject getObject(unsigned i) const {
+    assert(i < getNumObjects() && "Index out of range");
+    return getObjects()[i];
+  }
+
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+
+  /// As with any mutator of the AST, be very careful
+  /// when modifying an existing AST to preserve its invariants.
+  void setSubExpr(Expr *E) { SubExpr = E; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return SubExpr->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();}
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ExprWithCleanupsClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+};
+
+/// \brief Describes an explicit type conversion that uses functional
+/// notion but could not be resolved because one or more arguments are
+/// type-dependent.
+///
+/// The explicit type conversions expressed by
+/// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
+/// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
+/// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
+/// type-dependent. For example, this would occur in a template such
+/// as:
+///
+/// \code
+///   template<typename T, typename A1>
+///   inline T make_a(const A1& a1) {
+///     return T(a1);
+///   }
+/// \endcode
+///
+/// When the returned expression is instantiated, it may resolve to a
+/// constructor call, conversion function call, or some kind of type
+/// conversion.
+class CXXUnresolvedConstructExpr : public Expr {
+  /// \brief The type being constructed.
+  TypeSourceInfo *Type;
+
+  /// \brief The location of the left parentheses ('(').
+  SourceLocation LParenLoc;
+
+  /// \brief The location of the right parentheses (')').
+  SourceLocation RParenLoc;
+
+  /// \brief The number of arguments used to construct the type.
+  unsigned NumArgs;
+
+  CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
+                             SourceLocation LParenLoc,
+                             ArrayRef<Expr*> Args,
+                             SourceLocation RParenLoc);
+
+  CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
+    : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { }
+
+  friend class ASTStmtReader;
+
+public:
+  static CXXUnresolvedConstructExpr *Create(const ASTContext &C,
+                                            TypeSourceInfo *Type,
+                                            SourceLocation LParenLoc,
+                                            ArrayRef<Expr*> Args,
+                                            SourceLocation RParenLoc);
+
+  static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &C,
+                                                 unsigned NumArgs);
+
+  /// \brief Retrieve the type that is being constructed, as specified
+  /// in the source code.
+  QualType getTypeAsWritten() const { return Type->getType(); }
+
+  /// \brief Retrieve the type source information for the type being
+  /// constructed.
+  TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+
+  /// \brief Retrieve the location of the left parentheses ('(') that
+  /// precedes the argument list.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+
+  /// \brief Retrieve the location of the right parentheses (')') that
+  /// follows the argument list.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  /// \brief Retrieve the number of arguments.
+  unsigned arg_size() const { return NumArgs; }
+
+  typedef Expr** arg_iterator;
+  arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
+  arg_iterator arg_end() { return arg_begin() + NumArgs; }
+
+  typedef const Expr* const * const_arg_iterator;
+  const_arg_iterator arg_begin() const {
+    return reinterpret_cast<const Expr* const *>(this + 1);
+  }
+  const_arg_iterator arg_end() const {
+    return arg_begin() + NumArgs;
+  }
+
+  Expr *getArg(unsigned I) {
+    assert(I < NumArgs && "Argument index out-of-range");
+    return *(arg_begin() + I);
+  }
+
+  const Expr *getArg(unsigned I) const {
+    assert(I < NumArgs && "Argument index out-of-range");
+    return *(arg_begin() + I);
+  }
+
+  void setArg(unsigned I, Expr *E) {
+    assert(I < NumArgs && "Argument index out-of-range");
+    *(arg_begin() + I) = E;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    assert(RParenLoc.isValid() || NumArgs == 1);
+    return RParenLoc.isValid() ? RParenLoc : getArg(0)->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXUnresolvedConstructExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    Stmt **begin = reinterpret_cast<Stmt**>(this+1);
+    return child_range(begin, begin + NumArgs);
+  }
+};
+
+/// \brief Represents a C++ member access expression where the actual
+/// member referenced could not be resolved because the base
+/// expression or the member name was dependent.
+///
+/// Like UnresolvedMemberExprs, these can be either implicit or
+/// explicit accesses.  It is only possible to get one of these with
+/// an implicit access if a qualifier is provided.
+class CXXDependentScopeMemberExpr : public Expr {
+  /// \brief The expression for the base pointer or class reference,
+  /// e.g., the \c x in x.f.  Can be null in implicit accesses.
+  Stmt *Base;
+
+  /// \brief The type of the base expression.  Never null, even for
+  /// implicit accesses.
+  QualType BaseType;
+
+  /// \brief Whether this member expression used the '->' operator or
+  /// the '.' operator.
+  bool IsArrow : 1;
+
+  /// \brief Whether this member expression has info for explicit template
+  /// keyword and arguments.
+  bool HasTemplateKWAndArgsInfo : 1;
+
+  /// \brief The location of the '->' or '.' operator.
+  SourceLocation OperatorLoc;
+
+  /// \brief The nested-name-specifier that precedes the member name, if any.
+  NestedNameSpecifierLoc QualifierLoc;
+
+  /// \brief In a qualified member access expression such as t->Base::f, this
+  /// member stores the resolves of name lookup in the context of the member
+  /// access expression, to be used at instantiation time.
+  ///
+  /// FIXME: This member, along with the QualifierLoc, could
+  /// be stuck into a structure that is optionally allocated at the end of
+  /// the CXXDependentScopeMemberExpr, to save space in the common case.
+  NamedDecl *FirstQualifierFoundInScope;
+
+  /// \brief The member to which this member expression refers, which
+  /// can be name, overloaded operator, or destructor.
+  ///
+  /// FIXME: could also be a template-id
+  DeclarationNameInfo MemberNameInfo;
+
+  /// \brief Return the optional template keyword and arguments info.
+  ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
+    if (!HasTemplateKWAndArgsInfo) return nullptr;
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
+  }
+  /// \brief Return the optional template keyword and arguments info.
+  const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const {
+    return const_cast<CXXDependentScopeMemberExpr*>(this)
+      ->getTemplateKWAndArgsInfo();
+  }
+
+  CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
+                              QualType BaseType, bool IsArrow,
+                              SourceLocation OperatorLoc,
+                              NestedNameSpecifierLoc QualifierLoc,
+                              SourceLocation TemplateKWLoc,
+                              NamedDecl *FirstQualifierFoundInScope,
+                              DeclarationNameInfo MemberNameInfo,
+                              const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+  CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base,
+                              QualType BaseType, bool IsArrow,
+                              SourceLocation OperatorLoc,
+                              NestedNameSpecifierLoc QualifierLoc,
+                              NamedDecl *FirstQualifierFoundInScope,
+                              DeclarationNameInfo MemberNameInfo);
+
+  static CXXDependentScopeMemberExpr *
+  Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow,
+         SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
+         DeclarationNameInfo MemberNameInfo,
+         const TemplateArgumentListInfo *TemplateArgs);
+
+  static CXXDependentScopeMemberExpr *
+  CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
+              unsigned NumTemplateArgs);
+
+  /// \brief True if this is an implicit access, i.e. one in which the
+  /// member being accessed was not written in the source.  The source
+  /// location of the operator is invalid in this case.
+  bool isImplicitAccess() const;
+
+  /// \brief Retrieve the base object of this member expressions,
+  /// e.g., the \c x in \c x.m.
+  Expr *getBase() const {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+
+  QualType getBaseType() const { return BaseType; }
+
+  /// \brief Determine whether this member expression used the '->'
+  /// operator; otherwise, it used the '.' operator.
+  bool isArrow() const { return IsArrow; }
+
+  /// \brief Retrieve the location of the '->' or '.' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the member
+  /// name.
+  NestedNameSpecifier *getQualifier() const {
+    return QualifierLoc.getNestedNameSpecifier();
+  }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the member
+  /// name, with source location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+
+  /// \brief Retrieve the first part of the nested-name-specifier that was
+  /// found in the scope of the member access expression when the member access
+  /// was initially parsed.
+  ///
+  /// This function only returns a useful result when member access expression
+  /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
+  /// returned by this function describes what was found by unqualified name
+  /// lookup for the identifier "Base" within the scope of the member access
+  /// expression itself. At template instantiation time, this information is
+  /// combined with the results of name lookup into the type of the object
+  /// expression itself (the class type of x).
+  NamedDecl *getFirstQualifierFoundInScope() const {
+    return FirstQualifierFoundInScope;
+  }
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  const DeclarationNameInfo &getMemberNameInfo() const {
+    return MemberNameInfo;
+  }
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  DeclarationName getMember() const { return MemberNameInfo.getName(); }
+
+  // \brief Retrieve the location of the name of the member that this
+  // expression refers to.
+  SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
+
+  /// \brief Retrieve the location of the template keyword preceding the
+  /// member name, if any.
+  SourceLocation getTemplateKeywordLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc();
+  }
+
+  /// \brief Retrieve the location of the left angle bracket starting the
+  /// explicit template argument list following the member name, if any.
+  SourceLocation getLAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->LAngleLoc;
+  }
+
+  /// \brief Retrieve the location of the right angle bracket ending the
+  /// explicit template argument list following the member name, if any.
+  SourceLocation getRAngleLoc() const {
+    if (!HasTemplateKWAndArgsInfo) return SourceLocation();
+    return getTemplateKWAndArgsInfo()->RAngleLoc;
+  }
+
+  /// Determines whether the member name was preceded by the template keyword.
+  bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
+
+  /// \brief Determines whether this member expression actually had a C++
+  /// template argument list explicitly specified, e.g., x.f<int>.
+  bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  ASTTemplateArgumentListInfo &getExplicitTemplateArgs() {
+    assert(hasExplicitTemplateArgs());
+    return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1);
+  }
+
+  /// \brief Retrieve the explicit template argument list that followed the
+  /// member template name, if any.
+  const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const {
+    return const_cast<CXXDependentScopeMemberExpr *>(this)
+             ->getExplicitTemplateArgs();
+  }
+
+  /// \brief Retrieves the optional explicit template arguments.
+  ///
+  /// This points to the same data as getExplicitTemplateArgs(), but
+  /// returns null if there are no explicit template arguments.
+  const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
+    if (!hasExplicitTemplateArgs()) return nullptr;
+    return &getExplicitTemplateArgs();
+  }
+
+  /// \brief Copies the template arguments (if present) into the given
+  /// structure.
+  void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+    getExplicitTemplateArgs().copyInto(List);
+  }
+
+  /// \brief Initializes the template arguments using the given structure.
+  void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) {
+    getExplicitTemplateArgs().initializeFrom(List);
+  }
+
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return getExplicitTemplateArgs().getTemplateArgs();
+  }
+
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const {
+    return getExplicitTemplateArgs().NumTemplateArgs;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    if (!isImplicitAccess())
+      return Base->getLocStart();
+    if (getQualifier())
+      return getQualifierLoc().getBeginLoc();
+    return MemberNameInfo.getBeginLoc();
+
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (hasExplicitTemplateArgs())
+      return getRAngleLoc();
+    return MemberNameInfo.getEndLoc();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXDependentScopeMemberExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (isImplicitAccess()) return child_range();
+    return child_range(&Base, &Base + 1);
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// \brief Represents a C++ member access expression for which lookup
+/// produced a set of overloaded functions.
+///
+/// The member access may be explicit or implicit:
+/// \code
+///    struct A {
+///      int a, b;
+///      int explicitAccess() { return this->a + this->A::b; }
+///      int implicitAccess() { return a + A::b; }
+///    };
+/// \endcode
+///
+/// In the final AST, an explicit access always becomes a MemberExpr.
+/// An implicit access may become either a MemberExpr or a
+/// DeclRefExpr, depending on whether the member is static.
+class UnresolvedMemberExpr : public OverloadExpr {
+  /// \brief Whether this member expression used the '->' operator or
+  /// the '.' operator.
+  bool IsArrow : 1;
+
+  /// \brief Whether the lookup results contain an unresolved using
+  /// declaration.
+  bool HasUnresolvedUsing : 1;
+
+  /// \brief The expression for the base pointer or class reference,
+  /// e.g., the \c x in x.f.
+  ///
+  /// This can be null if this is an 'unbased' member expression.
+  Stmt *Base;
+
+  /// \brief The type of the base expression; never null.
+  QualType BaseType;
+
+  /// \brief The location of the '->' or '.' operator.
+  SourceLocation OperatorLoc;
+
+  UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing,
+                       Expr *Base, QualType BaseType, bool IsArrow,
+                       SourceLocation OperatorLoc,
+                       NestedNameSpecifierLoc QualifierLoc,
+                       SourceLocation TemplateKWLoc,
+                       const DeclarationNameInfo &MemberNameInfo,
+                       const TemplateArgumentListInfo *TemplateArgs,
+                       UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+  UnresolvedMemberExpr(EmptyShell Empty)
+    : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
+      HasUnresolvedUsing(false), Base(nullptr) { }
+
+  friend class ASTStmtReader;
+
+public:
+  static UnresolvedMemberExpr *
+  Create(const ASTContext &C, bool HasUnresolvedUsing,
+         Expr *Base, QualType BaseType, bool IsArrow,
+         SourceLocation OperatorLoc,
+         NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc,
+         const DeclarationNameInfo &MemberNameInfo,
+         const TemplateArgumentListInfo *TemplateArgs,
+         UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+
+  static UnresolvedMemberExpr *
+  CreateEmpty(const ASTContext &C, bool HasTemplateKWAndArgsInfo,
+              unsigned NumTemplateArgs);
+
+  /// \brief True if this is an implicit access, i.e., one in which the
+  /// member being accessed was not written in the source.
+  ///
+  /// The source location of the operator is invalid in this case.
+  bool isImplicitAccess() const;
+
+  /// \brief Retrieve the base object of this member expressions,
+  /// e.g., the \c x in \c x.m.
+  Expr *getBase() {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+  const Expr *getBase() const {
+    assert(!isImplicitAccess());
+    return cast<Expr>(Base);
+  }
+
+  QualType getBaseType() const { return BaseType; }
+
+  /// \brief Determine whether the lookup results contain an unresolved using
+  /// declaration.
+  bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
+
+  /// \brief Determine whether this member expression used the '->'
+  /// operator; otherwise, it used the '.' operator.
+  bool isArrow() const { return IsArrow; }
+
+  /// \brief Retrieve the location of the '->' or '.' operator.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+
+  /// \brief Retrieve the naming class of this lookup.
+  CXXRecordDecl *getNamingClass() const;
+
+  /// \brief Retrieve the full name info for the member that this expression
+  /// refers to.
+  const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
+
+  /// \brief Retrieve the name of the member that this expression
+  /// refers to.
+  DeclarationName getMemberName() const { return getName(); }
+
+  // \brief Retrieve the location of the name of the member that this
+  // expression refers to.
+  SourceLocation getMemberLoc() const { return getNameLoc(); }
+
+  // \brief Return the preferred location (the member name) for the arrow when
+  // diagnosing a problem with this expression.
+  SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    if (!isImplicitAccess())
+      return Base->getLocStart();
+    if (NestedNameSpecifierLoc l = getQualifierLoc())
+      return l.getBeginLoc();
+    return getMemberNameInfo().getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (hasExplicitTemplateArgs())
+      return getRAngleLoc();
+    return getMemberNameInfo().getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == UnresolvedMemberExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (isImplicitAccess()) return child_range();
+    return child_range(&Base, &Base + 1);
+  }
+};
+
+/// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
+///
+/// The noexcept expression tests whether a given expression might throw. Its
+/// result is a boolean constant.
+class CXXNoexceptExpr : public Expr {
+  bool Value : 1;
+  Stmt *Operand;
+  SourceRange Range;
+
+  friend class ASTStmtReader;
+
+public:
+  CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
+                  SourceLocation Keyword, SourceLocation RParen)
+    : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
+           /*TypeDependent*/false,
+           /*ValueDependent*/Val == CT_Dependent,
+           Val == CT_Dependent || Operand->isInstantiationDependent(),
+           Operand->containsUnexpandedParameterPack()),
+      Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
+  { }
+
+  CXXNoexceptExpr(EmptyShell Empty)
+    : Expr(CXXNoexceptExprClass, Empty)
+  { }
+
+  Expr *getOperand() const { return static_cast<Expr*>(Operand); }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+  bool getValue() const { return Value; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXNoexceptExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Operand, &Operand + 1); }
+};
+
+/// \brief Represents a C++11 pack expansion that produces a sequence of
+/// expressions.
+///
+/// A pack expansion expression contains a pattern (which itself is an
+/// expression) followed by an ellipsis. For example:
+///
+/// \code
+/// template<typename F, typename ...Types>
+/// void forward(F f, Types &&...args) {
+///   f(static_cast<Types&&>(args)...);
+/// }
+/// \endcode
+///
+/// Here, the argument to the function object \c f is a pack expansion whose
+/// pattern is \c static_cast<Types&&>(args). When the \c forward function
+/// template is instantiated, the pack expansion will instantiate to zero or
+/// or more function arguments to the function object \c f.
+class PackExpansionExpr : public Expr {
+  SourceLocation EllipsisLoc;
+
+  /// \brief The number of expansions that will be produced by this pack
+  /// expansion expression, if known.
+  ///
+  /// When zero, the number of expansions is not known. Otherwise, this value
+  /// is the number of expansions + 1.
+  unsigned NumExpansions;
+
+  Stmt *Pattern;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+public:
+  PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
+                    Optional<unsigned> NumExpansions)
+    : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
+           Pattern->getObjectKind(), /*TypeDependent=*/true,
+           /*ValueDependent=*/true, /*InstantiationDependent=*/true,
+           /*ContainsUnexpandedParameterPack=*/false),
+      EllipsisLoc(EllipsisLoc),
+      NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
+      Pattern(Pattern) { }
+
+  PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { }
+
+  /// \brief Retrieve the pattern of the pack expansion.
+  Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
+
+  /// \brief Retrieve the pattern of the pack expansion.
+  const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
+
+  /// \brief Retrieve the location of the ellipsis that describes this pack
+  /// expansion.
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
+  /// \brief Determine the number of expansions that will be produced when
+  /// this pack expansion is instantiated, if already known.
+  Optional<unsigned> getNumExpansions() const {
+    if (NumExpansions)
+      return NumExpansions - 1;
+
+    return None;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return Pattern->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == PackExpansionExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&Pattern, &Pattern + 1);
+  }
+};
+
+inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() {
+  if (!HasTemplateKWAndArgsInfo) return nullptr;
+  if (isa<UnresolvedLookupExpr>(this))
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
+      (cast<UnresolvedLookupExpr>(this) + 1);
+  else
+    return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
+      (cast<UnresolvedMemberExpr>(this) + 1);
+}
+
+/// \brief Represents an expression that computes the length of a parameter
+/// pack.
+///
+/// \code
+/// template<typename ...Types>
+/// struct count {
+///   static const unsigned value = sizeof...(Types);
+/// };
+/// \endcode
+class SizeOfPackExpr : public Expr {
+  /// \brief The location of the \c sizeof keyword.
+  SourceLocation OperatorLoc;
+
+  /// \brief The location of the name of the parameter pack.
+  SourceLocation PackLoc;
+
+  /// \brief The location of the closing parenthesis.
+  SourceLocation RParenLoc;
+
+  /// \brief The length of the parameter pack, if known.
+  ///
+  /// When this expression is value-dependent, the length of the parameter pack
+  /// is unknown. When this expression is not value-dependent, the length is
+  /// known.
+  unsigned Length;
+
+  /// \brief The parameter pack itself.
+  NamedDecl *Pack;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+public:
+  /// \brief Create a value-dependent expression that computes the length of
+  /// the given parameter pack.
+  SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
+                 SourceLocation PackLoc, SourceLocation RParenLoc)
+    : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
+           /*TypeDependent=*/false, /*ValueDependent=*/true,
+           /*InstantiationDependent=*/true,
+           /*ContainsUnexpandedParameterPack=*/false),
+      OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
+      Length(0), Pack(Pack) { }
+
+  /// \brief Create an expression that computes the length of
+  /// the given parameter pack, which is already known.
+  SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
+                 SourceLocation PackLoc, SourceLocation RParenLoc,
+                 unsigned Length)
+  : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
+         /*TypeDependent=*/false, /*ValueDependent=*/false,
+         /*InstantiationDependent=*/false,
+         /*ContainsUnexpandedParameterPack=*/false),
+    OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
+    Length(Length), Pack(Pack) { }
+
+  /// \brief Create an empty expression.
+  SizeOfPackExpr(EmptyShell Empty) : Expr(SizeOfPackExprClass, Empty) { }
+
+  /// \brief Determine the location of the 'sizeof' keyword.
+  SourceLocation getOperatorLoc() const { return OperatorLoc; }
+
+  /// \brief Determine the location of the parameter pack.
+  SourceLocation getPackLoc() const { return PackLoc; }
+
+  /// \brief Determine the location of the right parenthesis.
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+
+  /// \brief Retrieve the parameter pack.
+  NamedDecl *getPack() const { return Pack; }
+
+  /// \brief Retrieve the length of the parameter pack.
+  ///
+  /// This routine may only be invoked when the expression is not
+  /// value-dependent.
+  unsigned getPackLength() const {
+    assert(!isValueDependent() &&
+           "Cannot get the length of a value-dependent pack size expression");
+    return Length;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SizeOfPackExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief Represents a reference to a non-type template parameter
+/// that has been substituted with a template argument.
+class SubstNonTypeTemplateParmExpr : public Expr {
+  /// \brief The replaced parameter.
+  NonTypeTemplateParmDecl *Param;
+
+  /// \brief The replacement expression.
+  Stmt *Replacement;
+
+  /// \brief The location of the non-type template parameter reference.
+  SourceLocation NameLoc;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
+    : Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
+
+public:
+  SubstNonTypeTemplateParmExpr(QualType type,
+                               ExprValueKind valueKind,
+                               SourceLocation loc,
+                               NonTypeTemplateParmDecl *param,
+                               Expr *replacement)
+    : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
+           replacement->isTypeDependent(), replacement->isValueDependent(),
+           replacement->isInstantiationDependent(),
+           replacement->containsUnexpandedParameterPack()),
+      Param(param), Replacement(replacement), NameLoc(loc) {}
+
+  SourceLocation getNameLoc() const { return NameLoc; }
+  SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+
+  Expr *getReplacement() const { return cast<Expr>(Replacement); }
+
+  NonTypeTemplateParmDecl *getParameter() const { return Param; }
+
+  static bool classof(const Stmt *s) {
+    return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Replacement, &Replacement+1); }
+};
+
+/// \brief Represents a reference to a non-type template parameter pack that
+/// has been substituted with a non-template argument pack.
+///
+/// When a pack expansion in the source code contains multiple parameter packs
+/// and those parameter packs correspond to different levels of template
+/// parameter lists, this node is used to represent a non-type template
+/// parameter pack from an outer level, which has already had its argument pack
+/// substituted but that still lives within a pack expansion that itself
+/// could not be instantiated. When actually performing a substitution into
+/// that pack expansion (e.g., when all template parameters have corresponding
+/// arguments), this type will be replaced with the appropriate underlying
+/// expression at the current pack substitution index.
+class SubstNonTypeTemplateParmPackExpr : public Expr {
+  /// \brief The non-type template parameter pack itself.
+  NonTypeTemplateParmDecl *Param;
+
+  /// \brief A pointer to the set of template arguments that this
+  /// parameter pack is instantiated with.
+  const TemplateArgument *Arguments;
+
+  /// \brief The number of template arguments in \c Arguments.
+  unsigned NumArguments;
+
+  /// \brief The location of the non-type template parameter pack reference.
+  SourceLocation NameLoc;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
+    : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
+
+public:
+  SubstNonTypeTemplateParmPackExpr(QualType T,
+                                   NonTypeTemplateParmDecl *Param,
+                                   SourceLocation NameLoc,
+                                   const TemplateArgument &ArgPack);
+
+  /// \brief Retrieve the non-type template parameter pack being substituted.
+  NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
+
+  /// \brief Retrieve the location of the parameter pack name.
+  SourceLocation getParameterPackLocation() const { return NameLoc; }
+
+  /// \brief Retrieve the template argument pack containing the substituted
+  /// template arguments.
+  TemplateArgument getArgumentPack() const;
+
+  SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief Represents a reference to a function parameter pack that has been
+/// substituted but not yet expanded.
+///
+/// When a pack expansion contains multiple parameter packs at different levels,
+/// this node is used to represent a function parameter pack at an outer level
+/// which we have already substituted to refer to expanded parameters, but where
+/// the containing pack expansion cannot yet be expanded.
+///
+/// \code
+/// template<typename...Ts> struct S {
+///   template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
+/// };
+/// template struct S<int, int>;
+/// \endcode
+class FunctionParmPackExpr : public Expr {
+  /// \brief The function parameter pack which was referenced.
+  ParmVarDecl *ParamPack;
+
+  /// \brief The location of the function parameter pack reference.
+  SourceLocation NameLoc;
+
+  /// \brief The number of expansions of this pack.
+  unsigned NumParameters;
+
+  FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack,
+                       SourceLocation NameLoc, unsigned NumParams,
+                       Decl * const *Params);
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+
+public:
+  static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
+                                      ParmVarDecl *ParamPack,
+                                      SourceLocation NameLoc,
+                                      ArrayRef<Decl *> Params);
+  static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
+                                           unsigned NumParams);
+
+  /// \brief Get the parameter pack which this expression refers to.
+  ParmVarDecl *getParameterPack() const { return ParamPack; }
+
+  /// \brief Get the location of the parameter pack.
+  SourceLocation getParameterPackLocation() const { return NameLoc; }
+
+  /// \brief Iterators over the parameters which the parameter pack expanded
+  /// into.
+  typedef ParmVarDecl * const *iterator;
+  iterator begin() const { return reinterpret_cast<iterator>(this+1); }
+  iterator end() const { return begin() + NumParameters; }
+
+  /// \brief Get the number of parameters in this parameter pack.
+  unsigned getNumExpansions() const { return NumParameters; }
+
+  /// \brief Get an expansion of the parameter pack by index.
+  ParmVarDecl *getExpansion(unsigned I) const { return begin()[I]; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return NameLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == FunctionParmPackExprClass;
+  }
+
+  child_range children() { return child_range(); }
+};
+
+/// \brief Represents a prvalue temporary that is written into memory so that
+/// a reference can bind to it.
+///
+/// Prvalue expressions are materialized when they need to have an address
+/// in memory for a reference to bind to. This happens when binding a
+/// reference to the result of a conversion, e.g.,
+///
+/// \code
+/// const int &r = 1.0;
+/// \endcode
+///
+/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
+/// then materialized via a \c MaterializeTemporaryExpr, and the reference
+/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
+/// (either an lvalue or an xvalue, depending on the kind of reference binding
+/// to it), maintaining the invariant that references always bind to glvalues.
+///
+/// Reference binding and copy-elision can both extend the lifetime of a
+/// temporary. When either happens, the expression will also track the
+/// declaration which is responsible for the lifetime extension.
+class MaterializeTemporaryExpr : public Expr {
+private:
+  struct ExtraState {
+    /// \brief The temporary-generating expression whose value will be
+    /// materialized.
+    Stmt *Temporary;
+
+    /// \brief The declaration which lifetime-extended this reference, if any.
+    /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
+    const ValueDecl *ExtendingDecl;
+
+    unsigned ManglingNumber;
+  };
+  llvm::PointerUnion<Stmt *, ExtraState *> State;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+  void initializeExtraState(const ValueDecl *ExtendedBy,
+                            unsigned ManglingNumber);
+
+public:
+  MaterializeTemporaryExpr(QualType T, Expr *Temporary,
+                           bool BoundToLvalueReference)
+    : Expr(MaterializeTemporaryExprClass, T,
+           BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
+           Temporary->isTypeDependent(), Temporary->isValueDependent(),
+           Temporary->isInstantiationDependent(),
+           Temporary->containsUnexpandedParameterPack()),
+        State(Temporary) {}
+
+  MaterializeTemporaryExpr(EmptyShell Empty)
+    : Expr(MaterializeTemporaryExprClass, Empty) { }
+
+  Stmt *getTemporary() const {
+    return State.is<Stmt *>() ? State.get<Stmt *>()
+                              : State.get<ExtraState *>()->Temporary;
+  }
+
+  /// \brief Retrieve the temporary-generating subexpression whose value will
+  /// be materialized into a glvalue.
+  Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
+
+  /// \brief Retrieve the storage duration for the materialized temporary.
+  StorageDuration getStorageDuration() const {
+    const ValueDecl *ExtendingDecl = getExtendingDecl();
+    if (!ExtendingDecl)
+      return SD_FullExpression;
+    // FIXME: This is not necessarily correct for a temporary materialized
+    // within a default initializer.
+    if (isa<FieldDecl>(ExtendingDecl))
+      return SD_Automatic;
+    return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
+  }
+
+  /// \brief Get the declaration which triggered the lifetime-extension of this
+  /// temporary, if any.
+  const ValueDecl *getExtendingDecl() const {
+    return State.is<Stmt *>() ? nullptr
+                              : State.get<ExtraState *>()->ExtendingDecl;
+  }
+
+  void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
+
+  unsigned getManglingNumber() const {
+    return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
+  }
+
+  /// \brief Determine whether this materialized temporary is bound to an
+  /// lvalue reference; otherwise, it's bound to an rvalue reference.
+  bool isBoundToLvalueReference() const {
+    return getValueKind() == VK_LValue;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getTemporary()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getTemporary()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MaterializeTemporaryExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (State.is<Stmt *>())
+      return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
+
+    auto ES = State.get<ExtraState *>();
+    return child_range(&ES->Temporary, &ES->Temporary + 1);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
new file mode 100644
index 0000000..817c0cc
--- /dev/null
+++ b/include/clang/AST/ExprObjC.h
@@ -0,0 +1,1572 @@
+//===--- ExprObjC.h - Classes for representing ObjC expressions -*- 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 ExprObjC interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPROBJC_H
+#define LLVM_CLANG_AST_EXPROBJC_H
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/SelectorLocationsKind.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+  class IdentifierInfo;
+  class ASTContext;
+
+/// ObjCStringLiteral, used for Objective-C string literals
+/// i.e. @"foo".
+class ObjCStringLiteral : public Expr {
+  Stmt *String;
+  SourceLocation AtLoc;
+public:
+  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
+    : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
+           false, false),
+      String(SL), AtLoc(L) {}
+  explicit ObjCStringLiteral(EmptyShell Empty)
+    : Expr(ObjCStringLiteralClass, Empty) {}
+
+  StringLiteral *getString() { return cast<StringLiteral>(String); }
+  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
+  void setString(StringLiteral *S) { String = S; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCStringLiteralClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&String, &String+1); }
+};
+
+/// ObjCBoolLiteralExpr - Objective-C Boolean Literal.
+///
+class ObjCBoolLiteralExpr : public Expr {
+  bool Value;
+  SourceLocation Loc;
+public:
+  ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
+  Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
+       false, false), Value(val), Loc(l) {}
+    
+  explicit ObjCBoolLiteralExpr(EmptyShell Empty)
+  : Expr(ObjCBoolLiteralExprClass, Empty) { }
+    
+  bool getValue() const { return Value; }
+  void setValue(bool V) { Value = V; }
+    
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+    
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCBoolLiteralExprClass;
+  }
+    
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// ObjCBoxedExpr - used for generalized expression boxing.
+/// as in: @(strdup("hello world")) or @(random())
+/// Also used for boxing non-parenthesized numeric literals;
+/// as in: @42 or \@true (c++/objc++) or \@__yes (c/objc).
+class ObjCBoxedExpr : public Expr {
+  Stmt *SubExpr;
+  ObjCMethodDecl *BoxingMethod;
+  SourceRange Range;
+public:
+  ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
+                     SourceRange R)
+  : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, 
+         E->isTypeDependent(), E->isValueDependent(), 
+         E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), 
+         SubExpr(E), BoxingMethod(method), Range(R) {}
+  explicit ObjCBoxedExpr(EmptyShell Empty)
+  : Expr(ObjCBoxedExprClass, Empty) {}
+  
+  Expr *getSubExpr() { return cast<Expr>(SubExpr); }
+  const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
+  
+  ObjCMethodDecl *getBoxingMethod() const {
+    return BoxingMethod; 
+  }
+  
+  SourceLocation getAtLoc() const { return Range.getBegin(); }
+  
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return Range;
+  }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCBoxedExprClass;
+  }
+  
+  // Iterators
+  child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+  
+  friend class ASTStmtReader;
+};
+
+/// ObjCArrayLiteral - used for objective-c array containers; as in:
+/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]];
+class ObjCArrayLiteral : public Expr {
+  unsigned NumElements;
+  SourceRange Range;
+  ObjCMethodDecl *ArrayWithObjectsMethod;
+  
+  ObjCArrayLiteral(ArrayRef<Expr *> Elements,
+                   QualType T, ObjCMethodDecl * Method,
+                   SourceRange SR);
+  
+  explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements)
+    : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {}
+
+public:
+  static ObjCArrayLiteral *Create(const ASTContext &C,
+                                  ArrayRef<Expr *> Elements,
+                                  QualType T, ObjCMethodDecl * Method,
+                                  SourceRange SR);
+
+  static ObjCArrayLiteral *CreateEmpty(const ASTContext &C,
+                                       unsigned NumElements);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+  static bool classof(const Stmt *T) {
+      return T->getStmtClass() == ObjCArrayLiteralClass;
+  }
+
+  /// \brief Retrieve elements of array of literals.
+  Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); }
+
+  /// \brief Retrieve elements of array of literals.
+  const Expr * const *getElements() const { 
+    return reinterpret_cast<const Expr * const*>(this + 1); 
+  }
+
+  /// getNumElements - Return number of elements of objective-c array literal.
+  unsigned getNumElements() const { return NumElements; }
+    
+    /// getExpr - Return the Expr at the specified index.
+  Expr *getElement(unsigned Index) {
+    assert((Index < NumElements) && "Arg access out of range!");
+    return cast<Expr>(getElements()[Index]);
+  }
+  const Expr *getElement(unsigned Index) const {
+    assert((Index < NumElements) && "Arg access out of range!");
+    return cast<Expr>(getElements()[Index]);
+  }
+    
+  ObjCMethodDecl *getArrayWithObjectsMethod() const {
+    return ArrayWithObjectsMethod; 
+  }
+    
+  // Iterators
+  child_range children() { 
+    return child_range((Stmt **)getElements(), 
+                       (Stmt **)getElements() + NumElements);
+  }
+    
+  friend class ASTStmtReader;
+};
+
+/// \brief An element in an Objective-C dictionary literal.
+///
+struct ObjCDictionaryElement {
+  /// \brief The key for the dictionary element.
+  Expr *Key;
+  
+  /// \brief The value of the dictionary element.
+  Expr *Value;
+  
+  /// \brief The location of the ellipsis, if this is a pack expansion.
+  SourceLocation EllipsisLoc;
+  
+  /// \brief The number of elements this pack expansion will expand to, if
+  /// this is a pack expansion and is known.
+  Optional<unsigned> NumExpansions;
+
+  /// \brief Determines whether this dictionary element is a pack expansion.
+  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+};
+} // end namespace clang
+
+namespace llvm {
+template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
+}
+
+namespace clang {
+/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary 
+/// literals; as in:  @{@"name" : NSUserName(), @"date" : [NSDate date] };
+class ObjCDictionaryLiteral : public Expr {
+  /// \brief Key/value pair used to store the key and value of a given element.
+  ///
+  /// Objects of this type are stored directly after the expression.
+  struct KeyValuePair {
+    Expr *Key;
+    Expr *Value;
+  };
+  
+  /// \brief Data that describes an element that is a pack expansion, used if any
+  /// of the elements in the dictionary literal are pack expansions.
+  struct ExpansionData {
+    /// \brief The location of the ellipsis, if this element is a pack
+    /// expansion.
+    SourceLocation EllipsisLoc;
+
+    /// \brief If non-zero, the number of elements that this pack
+    /// expansion will expand to (+1).
+    unsigned NumExpansionsPlusOne;
+  };
+
+  /// \brief The number of elements in this dictionary literal.
+  unsigned NumElements : 31;
+  
+  /// \brief Determine whether this dictionary literal has any pack expansions.
+  ///
+  /// If the dictionary literal has pack expansions, then there will
+  /// be an array of pack expansion data following the array of
+  /// key/value pairs, which provide the locations of the ellipses (if
+  /// any) and number of elements in the expansion (if known). If
+  /// there are no pack expansions, we optimize away this storage.
+  unsigned HasPackExpansions : 1;
+  
+  SourceRange Range;
+  ObjCMethodDecl *DictWithObjectsMethod;
+    
+  ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, 
+                        bool HasPackExpansions,
+                        QualType T, ObjCMethodDecl *method,
+                        SourceRange SR);
+
+  explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements,
+                                 bool HasPackExpansions)
+    : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements),
+      HasPackExpansions(HasPackExpansions) {}
+
+  KeyValuePair *getKeyValues() {
+    return reinterpret_cast<KeyValuePair *>(this + 1);
+  }
+  
+  const KeyValuePair *getKeyValues() const {
+    return reinterpret_cast<const KeyValuePair *>(this + 1);
+  }
+
+  ExpansionData *getExpansionData() {
+    if (!HasPackExpansions)
+      return nullptr;
+    
+    return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
+  }
+
+  const ExpansionData *getExpansionData() const {
+    if (!HasPackExpansions)
+      return nullptr;
+    
+    return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
+  }
+
+public:
+  static ObjCDictionaryLiteral *Create(const ASTContext &C,
+                                       ArrayRef<ObjCDictionaryElement> VK, 
+                                       bool HasPackExpansions,
+                                       QualType T, ObjCMethodDecl *method,
+                                       SourceRange SR);
+  
+  static ObjCDictionaryLiteral *CreateEmpty(const ASTContext &C,
+                                            unsigned NumElements,
+                                            bool HasPackExpansions);
+  
+  /// getNumElements - Return number of elements of objective-c dictionary 
+  /// literal.
+  unsigned getNumElements() const { return NumElements; }
+
+  ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
+    assert((Index < NumElements) && "Arg access out of range!");
+    const KeyValuePair &KV = getKeyValues()[Index];
+    ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
+    if (HasPackExpansions) {
+      const ExpansionData &Expansion = getExpansionData()[Index];
+      Result.EllipsisLoc = Expansion.EllipsisLoc;
+      if (Expansion.NumExpansionsPlusOne > 0)
+        Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1;
+    }
+    return Result;
+  }
+    
+  ObjCMethodDecl *getDictWithObjectsMethod() const
+    { return DictWithObjectsMethod; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  
+  static bool classof(const Stmt *T) {
+      return T->getStmtClass() == ObjCDictionaryLiteralClass;
+  }
+    
+  // Iterators
+  child_range children() { 
+    // Note: we're taking advantage of the layout of the KeyValuePair struct
+    // here. If that struct changes, this code will need to change as well.
+    return child_range(reinterpret_cast<Stmt **>(this + 1),
+                       reinterpret_cast<Stmt **>(this + 1) + NumElements * 2);
+  }
+    
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+
+/// ObjCEncodeExpr, used for \@encode in Objective-C.  \@encode has the same
+/// type and behavior as StringLiteral except that the string initializer is
+/// obtained from ASTContext with the encoding type as an argument.
+class ObjCEncodeExpr : public Expr {
+  TypeSourceInfo *EncodedType;
+  SourceLocation AtLoc, RParenLoc;
+public:
+  ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
+                 SourceLocation at, SourceLocation rp)
+    : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
+           EncodedType->getType()->isDependentType(),
+           EncodedType->getType()->isDependentType(),
+           EncodedType->getType()->isInstantiationDependentType(),
+           EncodedType->getType()->containsUnexpandedParameterPack()), 
+      EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
+
+  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
+
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  QualType getEncodedType() const { return EncodedType->getType(); }
+
+  TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
+  void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 
+    EncodedType = EncType; 
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCEncodeExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// ObjCSelectorExpr used for \@selector in Objective-C.
+class ObjCSelectorExpr : public Expr {
+  Selector SelName;
+  SourceLocation AtLoc, RParenLoc;
+public:
+  ObjCSelectorExpr(QualType T, Selector selInfo,
+                   SourceLocation at, SourceLocation rp)
+    : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 
+           false, false),
+    SelName(selInfo), AtLoc(at), RParenLoc(rp){}
+  explicit ObjCSelectorExpr(EmptyShell Empty)
+   : Expr(ObjCSelectorExprClass, Empty) {}
+
+  Selector getSelector() const { return SelName; }
+  void setSelector(Selector S) { SelName = S; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  /// getNumArgs - Return the number of actual arguments to this call.
+  unsigned getNumArgs() const { return SelName.getNumArgs(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCSelectorExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// ObjCProtocolExpr used for protocol expression in Objective-C.
+///
+/// This is used as: \@protocol(foo), as in:
+/// \code
+///   [obj conformsToProtocol:@protocol(foo)]
+/// \endcode
+///
+/// The return type is "Protocol*".
+class ObjCProtocolExpr : public Expr {
+  ObjCProtocolDecl *TheProtocol;
+  SourceLocation AtLoc, ProtoLoc, RParenLoc;
+public:
+  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
+                 SourceLocation at, SourceLocation protoLoc, SourceLocation rp)
+    : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
+           false, false),
+      TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {}
+  explicit ObjCProtocolExpr(EmptyShell Empty)
+    : Expr(ObjCProtocolExprClass, Empty) {}
+
+  ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
+  void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
+
+  SourceLocation getProtocolIdLoc() const { return ProtoLoc; }
+  SourceLocation getAtLoc() const { return AtLoc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setAtLoc(SourceLocation L) { AtLoc = L; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCProtocolExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
+class ObjCIvarRefExpr : public Expr {
+  ObjCIvarDecl *D;
+  Stmt *Base;
+  SourceLocation Loc;
+  /// OpLoc - This is the location of '.' or '->'
+  SourceLocation OpLoc;
+  
+  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
+  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
+
+public:
+  ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
+                  SourceLocation l, SourceLocation oploc,
+                  Expr *base,
+                  bool arrow = false, bool freeIvar = false) :
+    Expr(ObjCIvarRefExprClass, t, VK_LValue,
+         d->isBitField() ? OK_BitField : OK_Ordinary,
+         /*TypeDependent=*/false, base->isValueDependent(), 
+         base->isInstantiationDependent(),
+         base->containsUnexpandedParameterPack()), 
+    D(d), Base(base), Loc(l), OpLoc(oploc),
+    IsArrow(arrow), IsFreeIvar(freeIvar) {}
+
+  explicit ObjCIvarRefExpr(EmptyShell Empty)
+    : Expr(ObjCIvarRefExprClass, Empty) {}
+
+  ObjCIvarDecl *getDecl() { return D; }
+  const ObjCIvarDecl *getDecl() const { return D; }
+  void setDecl(ObjCIvarDecl *d) { D = d; }
+
+  const Expr *getBase() const { return cast<Expr>(Base); }
+  Expr *getBase() { return cast<Expr>(Base); }
+  void setBase(Expr * base) { Base = base; }
+
+  bool isArrow() const { return IsArrow; }
+  bool isFreeIvar() const { return IsFreeIvar; }
+  void setIsArrow(bool A) { IsArrow = A; }
+  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return isFreeIvar() ? Loc : getBase()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+  
+  SourceLocation getOpLoc() const { return OpLoc; }
+  void setOpLoc(SourceLocation L) { OpLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCIvarRefExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Base, &Base+1); }
+};
+
+/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
+/// property.
+class ObjCPropertyRefExpr : public Expr {
+private:
+  /// If the bool is true, this is an implicit property reference; the
+  /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
+  /// if the bool is false, this is an explicit property reference;
+  /// the pointer is an ObjCPropertyDecl and Setter is always null.
+  llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
+
+  /// \brief Indicates whether the property reference will result in a message
+  /// to the getter, the setter, or both.
+  /// This applies to both implicit and explicit property references.
+  enum MethodRefFlags {
+    MethodRef_None = 0,
+    MethodRef_Getter = 0x1,
+    MethodRef_Setter = 0x2
+  };
+
+  /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
+  llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
+
+  // FIXME: Maybe we should store the property identifier here,
+  // because it's not rederivable from the other data when there's an
+  // implicit property with no getter (because the 'foo' -> 'setFoo:'
+  // transformation is lossy on the first character).
+
+  SourceLocation IdLoc;
+  
+  /// \brief When the receiver in property access is 'super', this is
+  /// the location of the 'super' keyword.  When it's an interface,
+  /// this is that interface.
+  SourceLocation ReceiverLoc;
+  llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
+  
+public:
+  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
+                      ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation l, Expr *base)
+    : Expr(ObjCPropertyRefExprClass, t, VK, OK,
+           /*TypeDependent=*/false, base->isValueDependent(),
+           base->isInstantiationDependent(),
+           base->containsUnexpandedParameterPack()),
+      PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
+      IdLoc(l), ReceiverLoc(), Receiver(base) {
+    assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+  }
+  
+  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
+                      ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation l, SourceLocation sl, QualType st)
+    : Expr(ObjCPropertyRefExprClass, t, VK, OK,
+           /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
+           st->containsUnexpandedParameterPack()),
+      PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
+      IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
+    assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+  }
+
+  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                      QualType T, ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation IdLoc, Expr *Base)
+    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
+           Base->isValueDependent(), Base->isInstantiationDependent(),
+           Base->containsUnexpandedParameterPack()),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+      IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
+    assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+  }
+
+  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                      QualType T, ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation IdLoc,
+                      SourceLocation SuperLoc, QualType SuperTy)
+    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+      IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
+    assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+  }
+
+  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                      QualType T, ExprValueKind VK, ExprObjectKind OK,
+                      SourceLocation IdLoc,
+                      SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
+    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
+      IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
+    assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
+  }
+
+  explicit ObjCPropertyRefExpr(EmptyShell Empty)
+    : Expr(ObjCPropertyRefExprClass, Empty) {}
+
+  bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
+  bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
+
+  ObjCPropertyDecl *getExplicitProperty() const {
+    assert(!isImplicitProperty());
+    return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
+  }
+
+  ObjCMethodDecl *getImplicitPropertyGetter() const {
+    assert(isImplicitProperty());
+    return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
+  }
+
+  ObjCMethodDecl *getImplicitPropertySetter() const {
+    assert(isImplicitProperty());
+    return SetterAndMethodRefFlags.getPointer();
+  }
+
+  Selector getGetterSelector() const {
+    if (isImplicitProperty())
+      return getImplicitPropertyGetter()->getSelector();
+    return getExplicitProperty()->getGetterName();
+  }
+
+  Selector getSetterSelector() const {
+    if (isImplicitProperty())
+      return getImplicitPropertySetter()->getSelector();
+    return getExplicitProperty()->getSetterName();
+  }
+
+  /// \brief True if the property reference will result in a message to the
+  /// getter.
+  /// This applies to both implicit and explicit property references.
+  bool isMessagingGetter() const {
+    return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
+  }
+
+  /// \brief True if the property reference will result in a message to the
+  /// setter.
+  /// This applies to both implicit and explicit property references.
+  bool isMessagingSetter() const {
+    return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
+  }
+
+  void setIsMessagingGetter(bool val = true) {
+    setMethodRefFlag(MethodRef_Getter, val);
+  }
+
+  void setIsMessagingSetter(bool val = true) {
+    setMethodRefFlag(MethodRef_Setter, val);
+  }
+
+  const Expr *getBase() const { 
+    return cast<Expr>(Receiver.get<Stmt*>()); 
+  }
+  Expr *getBase() { 
+    return cast<Expr>(Receiver.get<Stmt*>()); 
+  }
+
+  SourceLocation getLocation() const { return IdLoc; }
+  
+  SourceLocation getReceiverLocation() const { return ReceiverLoc; }
+  QualType getSuperReceiverType() const { 
+    return QualType(Receiver.get<const Type*>(), 0); 
+  }
+  QualType getGetterResultType() const {
+    QualType ResultType;
+    if (isExplicitProperty()) {
+      const ObjCPropertyDecl *PDecl = getExplicitProperty();
+      if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
+        ResultType = Getter->getReturnType();
+      else
+        ResultType = PDecl->getType();
+    } else {
+      const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
+      if (Getter)
+        ResultType = Getter->getReturnType(); // with reference!
+    }
+    return ResultType;
+  }
+
+  QualType getSetterArgType() const {
+    QualType ArgType;
+    if (isImplicitProperty()) {
+      const ObjCMethodDecl *Setter = getImplicitPropertySetter();
+      ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
+      ArgType = (*P)->getType();
+    } else {
+      if (ObjCPropertyDecl *PDecl = getExplicitProperty())
+        if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
+          ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); 
+          ArgType = (*P)->getType();
+        }
+      if (ArgType.isNull())
+        ArgType = getType();
+    }
+    return ArgType;
+  }
+  
+  ObjCInterfaceDecl *getClassReceiver() const {
+    return Receiver.get<ObjCInterfaceDecl*>();
+  }
+  bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
+  bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
+  bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCPropertyRefExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (Receiver.is<Stmt*>()) {
+      Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
+      return child_range(begin, begin+1);
+    }
+    return child_range();
+  }
+
+private:
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+  void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
+    PropertyOrGetter.setPointer(D);
+    PropertyOrGetter.setInt(false);
+    SetterAndMethodRefFlags.setPointer(nullptr);
+    SetterAndMethodRefFlags.setInt(methRefFlags);
+  }
+  void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                           unsigned methRefFlags) {
+    PropertyOrGetter.setPointer(Getter);
+    PropertyOrGetter.setInt(true);
+    SetterAndMethodRefFlags.setPointer(Setter);
+    SetterAndMethodRefFlags.setInt(methRefFlags);
+  }
+  void setBase(Expr *Base) { Receiver = Base; }
+  void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
+  void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
+
+  void setLocation(SourceLocation L) { IdLoc = L; }
+  void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
+
+  void setMethodRefFlag(MethodRefFlags flag, bool val) {
+    unsigned f = SetterAndMethodRefFlags.getInt();
+    if (val)
+      f |= flag;
+    else
+      f &= ~flag;
+    SetterAndMethodRefFlags.setInt(f);
+  }
+};
+  
+/// ObjCSubscriptRefExpr - used for array and dictionary subscripting.
+/// array[4] = array[3]; dictionary[key] = dictionary[alt_key];
+///
+class ObjCSubscriptRefExpr : public Expr {
+  // Location of ']' in an indexing expression.
+  SourceLocation RBracket;
+  // array/dictionary base expression.
+  // for arrays, this is a numeric expression. For dictionaries, this is
+  // an objective-c object pointer expression.
+  enum { BASE, KEY, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  
+  ObjCMethodDecl *GetAtIndexMethodDecl;
+  
+  // For immutable objects this is null. When ObjCSubscriptRefExpr is to read
+  // an indexed object this is null too.
+  ObjCMethodDecl *SetAtIndexMethodDecl;
+  
+public:
+  
+  ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T,
+                       ExprValueKind VK, ExprObjectKind OK,
+                       ObjCMethodDecl *getMethod,
+                       ObjCMethodDecl *setMethod, SourceLocation RB)
+    : Expr(ObjCSubscriptRefExprClass, T, VK, OK, 
+           base->isTypeDependent() || key->isTypeDependent(), 
+           base->isValueDependent() || key->isValueDependent(),
+           base->isInstantiationDependent() || key->isInstantiationDependent(),
+           (base->containsUnexpandedParameterPack() ||
+            key->containsUnexpandedParameterPack())),
+      RBracket(RB), 
+  GetAtIndexMethodDecl(getMethod), 
+  SetAtIndexMethodDecl(setMethod) 
+    {SubExprs[BASE] = base; SubExprs[KEY] = key;}
+
+  explicit ObjCSubscriptRefExpr(EmptyShell Empty)
+    : Expr(ObjCSubscriptRefExprClass, Empty) {}
+  
+  static ObjCSubscriptRefExpr *Create(const ASTContext &C,
+                                      Expr *base,
+                                      Expr *key, QualType T, 
+                                      ObjCMethodDecl *getMethod,
+                                      ObjCMethodDecl *setMethod, 
+                                      SourceLocation RB);
+  
+  SourceLocation getRBracket() const { return RBracket; }
+  void setRBracket(SourceLocation RB) { RBracket = RB; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return SubExprs[BASE]->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCSubscriptRefExprClass;
+  }
+  
+  Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); }
+  void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; }
+  
+  Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); }
+  void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; }
+  
+  ObjCMethodDecl *getAtIndexMethodDecl() const {
+    return GetAtIndexMethodDecl;
+  }
+ 
+  ObjCMethodDecl *setAtIndexMethodDecl() const {
+    return SetAtIndexMethodDecl;
+  }
+  
+  bool isArraySubscriptRefExpr() const {
+    return getKeyExpr()->getType()->isIntegralOrEnumerationType();
+  }
+  
+  child_range children() {
+    return child_range(SubExprs, SubExprs+END_EXPR);
+  }
+private:
+  friend class ASTStmtReader;
+};
+  
+
+/// \brief An expression that sends a message to the given Objective-C
+/// object or class.
+///
+/// The following contains two message send expressions:
+///
+/// \code
+///   [[NSString alloc] initWithString:@"Hello"]
+/// \endcode
+///
+/// The innermost message send invokes the "alloc" class method on the
+/// NSString class, while the outermost message send invokes the
+/// "initWithString" instance method on the object returned from
+/// NSString's "alloc". In all, an Objective-C message send can take
+/// on four different (although related) forms:
+///
+///   1. Send to an object instance.
+///   2. Send to a class.
+///   3. Send to the superclass instance of the current class.
+///   4. Send to the superclass of the current class.
+///
+/// All four kinds of message sends are modeled by the ObjCMessageExpr
+/// class, and can be distinguished via \c getReceiverKind(). Example:
+///
+class ObjCMessageExpr : public Expr {
+  /// \brief Stores either the selector that this message is sending
+  /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
+  /// referring to the method that we type-checked against.
+  uintptr_t SelectorOrMethod;
+
+  enum { NumArgsBitWidth = 16 };
+
+  /// \brief The number of arguments in the message send, not
+  /// including the receiver.
+  unsigned NumArgs : NumArgsBitWidth;
+  
+  void setNumArgs(unsigned Num) {
+    assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
+    NumArgs = Num;
+  }
+
+  /// \brief The kind of message send this is, which is one of the
+  /// ReceiverKind values.
+  ///
+  /// We pad this out to a byte to avoid excessive masking and shifting.
+  unsigned Kind : 8;
+
+  /// \brief Whether we have an actual method prototype in \c
+  /// SelectorOrMethod.
+  ///
+  /// When non-zero, we have a method declaration; otherwise, we just
+  /// have a selector.
+  unsigned HasMethod : 1;
+
+  /// \brief Whether this message send is a "delegate init call",
+  /// i.e. a call of an init method on self from within an init method.
+  unsigned IsDelegateInitCall : 1;
+
+  /// \brief Whether this message send was implicitly generated by
+  /// the implementation rather than explicitly written by the user.
+  unsigned IsImplicit : 1;
+
+  /// \brief Whether the locations of the selector identifiers are in a
+  /// "standard" position, a enum SelectorLocationsKind.
+  unsigned SelLocsKind : 2;
+
+  /// \brief When the message expression is a send to 'super', this is
+  /// the location of the 'super' keyword.
+  SourceLocation SuperLoc;
+
+  /// \brief The source locations of the open and close square
+  /// brackets ('[' and ']', respectively).
+  SourceLocation LBracLoc, RBracLoc;
+
+  ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+    : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), 
+      HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) {
+    setNumArgs(NumArgs);
+  }
+
+  ObjCMessageExpr(QualType T, ExprValueKind VK,
+                  SourceLocation LBracLoc,
+                  SourceLocation SuperLoc,
+                  bool IsInstanceSuper,
+                  QualType SuperType,
+                  Selector Sel, 
+                  ArrayRef<SourceLocation> SelLocs,
+                  SelectorLocationsKind SelLocsK,
+                  ObjCMethodDecl *Method,
+                  ArrayRef<Expr *> Args,
+                  SourceLocation RBracLoc,
+                  bool isImplicit);
+  ObjCMessageExpr(QualType T, ExprValueKind VK,
+                  SourceLocation LBracLoc,
+                  TypeSourceInfo *Receiver,
+                  Selector Sel, 
+                  ArrayRef<SourceLocation> SelLocs,
+                  SelectorLocationsKind SelLocsK,
+                  ObjCMethodDecl *Method,
+                  ArrayRef<Expr *> Args,
+                  SourceLocation RBracLoc,
+                  bool isImplicit);
+  ObjCMessageExpr(QualType T, ExprValueKind VK,
+                  SourceLocation LBracLoc,
+                  Expr *Receiver,
+                  Selector Sel, 
+                  ArrayRef<SourceLocation> SelLocs,
+                  SelectorLocationsKind SelLocsK,
+                  ObjCMethodDecl *Method,
+                  ArrayRef<Expr *> Args,
+                  SourceLocation RBracLoc,
+                  bool isImplicit);
+
+  void initArgsAndSelLocs(ArrayRef<Expr *> Args,
+                          ArrayRef<SourceLocation> SelLocs,
+                          SelectorLocationsKind SelLocsK);
+
+  /// \brief Retrieve the pointer value of the message receiver.
+  void *getReceiverPointer() const {
+    return *const_cast<void **>(
+                             reinterpret_cast<const void * const*>(this + 1));
+  }
+
+  /// \brief Set the pointer value of the message receiver.
+  void setReceiverPointer(void *Value) {
+    *reinterpret_cast<void **>(this + 1) = Value;
+  }
+
+  SelectorLocationsKind getSelLocsKind() const {
+    return (SelectorLocationsKind)SelLocsKind;
+  }
+  bool hasStandardSelLocs() const {
+    return getSelLocsKind() != SelLoc_NonStandard;
+  }
+
+  /// \brief Get a pointer to the stored selector identifiers locations array.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  SourceLocation *getStoredSelLocs() {
+    return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
+  }
+  const SourceLocation *getStoredSelLocs() const {
+    return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
+  }
+
+  /// \brief Get the number of stored selector identifiers locations.
+  /// No locations will be stored if HasStandardSelLocs is true.
+  unsigned getNumStoredSelLocs() const {
+    if (hasStandardSelLocs())
+      return 0;
+    return getNumSelectorLocs();
+  }
+
+  static ObjCMessageExpr *alloc(const ASTContext &C,
+                                ArrayRef<Expr *> Args,
+                                SourceLocation RBraceLoc,
+                                ArrayRef<SourceLocation> SelLocs,
+                                Selector Sel,
+                                SelectorLocationsKind &SelLocsK);
+  static ObjCMessageExpr *alloc(const ASTContext &C,
+                                unsigned NumArgs,
+                                unsigned NumStoredSelLocs);
+
+public:
+  /// \brief The kind of receiver this message is sending to.
+  enum ReceiverKind {
+    /// \brief The receiver is a class.
+    Class = 0,
+    /// \brief The receiver is an object instance.
+    Instance,
+    /// \brief The receiver is a superclass.
+    SuperClass,
+    /// \brief The receiver is the instance of the superclass object.
+    SuperInstance
+  };
+
+  /// \brief Create a message send to super.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param VK The value kind of this message.  A message returning
+  /// a l-value or r-value reference will be an l-value or x-value,
+  /// respectively.
+  ///
+  /// \param LBracLoc The location of the open square bracket '['.
+  ///
+  /// \param SuperLoc The location of the "super" keyword.
+  ///
+  /// \param IsInstanceSuper Whether this is an instance "super"
+  /// message (otherwise, it's a class "super" message).
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+                                 ExprValueKind VK,
+                                 SourceLocation LBracLoc,
+                                 SourceLocation SuperLoc,
+                                 bool IsInstanceSuper,
+                                 QualType SuperType,
+                                 Selector Sel, 
+                                 ArrayRef<SourceLocation> SelLocs,
+                                 ObjCMethodDecl *Method,
+                                 ArrayRef<Expr *> Args,
+                                 SourceLocation RBracLoc,
+                                 bool isImplicit);
+
+  /// \brief Create a class message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param VK The value kind of this message.  A message returning
+  /// a l-value or r-value reference will be an l-value or x-value,
+  /// respectively.
+  ///
+  /// \param LBracLoc The location of the open square bracket '['.
+  ///
+  /// \param Receiver The type of the receiver, including
+  /// source-location information.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+                                 ExprValueKind VK,
+                                 SourceLocation LBracLoc,
+                                 TypeSourceInfo *Receiver,
+                                 Selector Sel, 
+                                 ArrayRef<SourceLocation> SelLocs,
+                                 ObjCMethodDecl *Method,
+                                 ArrayRef<Expr *> Args,
+                                 SourceLocation RBracLoc,
+                                 bool isImplicit);
+
+  /// \brief Create an instance message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param VK The value kind of this message.  A message returning
+  /// a l-value or r-value reference will be an l-value or x-value,
+  /// respectively.
+  ///
+  /// \param LBracLoc The location of the open square bracket '['.
+  ///
+  /// \param Receiver The expression used to produce the object that
+  /// will receive this message.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(const ASTContext &Context, QualType T,
+                                 ExprValueKind VK,
+                                 SourceLocation LBracLoc,
+                                 Expr *Receiver,
+                                 Selector Sel, 
+                                 ArrayRef<SourceLocation> SeLocs,
+                                 ObjCMethodDecl *Method,
+                                 ArrayRef<Expr *> Args,
+                                 SourceLocation RBracLoc,
+                                 bool isImplicit);
+
+  /// \brief Create an empty Objective-C message expression, to be
+  /// filled in by subsequent calls.
+  ///
+  /// \param Context The context in which the message send will be created.
+  ///
+  /// \param NumArgs The number of message arguments, not including
+  /// the receiver.
+  static ObjCMessageExpr *CreateEmpty(const ASTContext &Context,
+                                      unsigned NumArgs,
+                                      unsigned NumStoredSelLocs);
+
+  /// \brief Indicates whether the message send was implicitly
+  /// generated by the implementation. If false, it was written explicitly
+  /// in the source code.
+  bool isImplicit() const { return IsImplicit; }
+
+  /// \brief Determine the kind of receiver that this message is being
+  /// sent to.
+  ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+  /// \brief Source range of the receiver.
+  SourceRange getReceiverRange() const;
+
+  /// \brief Determine whether this is an instance message to either a
+  /// computed object or to super.
+  bool isInstanceMessage() const {
+    return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
+  }
+
+  /// \brief Determine whether this is an class message to either a
+  /// specified class or to super.
+  bool isClassMessage() const {
+    return getReceiverKind() == Class || getReceiverKind() == SuperClass;
+  }
+
+  /// \brief Returns the object expression (receiver) for an instance message,
+  /// or null for a message that is not an instance message.
+  Expr *getInstanceReceiver() {
+    if (getReceiverKind() == Instance)
+      return static_cast<Expr *>(getReceiverPointer());
+
+    return nullptr;
+  }
+  const Expr *getInstanceReceiver() const {
+    return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
+  }
+
+  /// \brief Turn this message send into an instance message that
+  /// computes the receiver object with the given expression.
+  void setInstanceReceiver(Expr *rec) { 
+    Kind = Instance;
+    setReceiverPointer(rec);
+  }
+  
+  /// \brief Returns the type of a class message send, or NULL if the
+  /// message is not a class message.
+  QualType getClassReceiver() const { 
+    if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
+      return TSInfo->getType();
+
+    return QualType();
+  }
+
+  /// \brief Returns a type-source information of a class message
+  /// send, or NULL if the message is not a class message.
+  TypeSourceInfo *getClassReceiverTypeInfo() const {
+    if (getReceiverKind() == Class)
+      return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
+    return nullptr;
+  }
+
+  void setClassReceiver(TypeSourceInfo *TSInfo) {
+    Kind = Class;
+    setReceiverPointer(TSInfo);
+  }
+
+  /// \brief Retrieve the location of the 'super' keyword for a class
+  /// or instance message to 'super', otherwise an invalid source location.
+  SourceLocation getSuperLoc() const { 
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return SuperLoc;
+
+    return SourceLocation();
+  }
+
+  /// \brief Retrieve the receiver type to which this message is being directed.
+  ///
+  /// This routine cross-cuts all of the different kinds of message
+  /// sends to determine what the underlying (statically known) type
+  /// of the receiver will be; use \c getReceiverKind() to determine
+  /// whether the message is a class or an instance method, whether it
+  /// is a send to super or not, etc.
+  ///
+  /// \returns The type of the receiver.
+  QualType getReceiverType() const;
+
+  /// \brief Retrieve the Objective-C interface to which this message
+  /// is being directed, if known.
+  ///
+  /// This routine cross-cuts all of the different kinds of message
+  /// sends to determine what the underlying (statically known) type
+  /// of the receiver will be; use \c getReceiverKind() to determine
+  /// whether the message is a class or an instance method, whether it
+  /// is a send to super or not, etc.
+  ///
+  /// \returns The Objective-C interface if known, otherwise NULL.
+  ObjCInterfaceDecl *getReceiverInterface() const;
+
+  /// \brief Retrieve the type referred to by 'super'. 
+  ///
+  /// The returned type will either be an ObjCInterfaceType (for an
+  /// class message to super) or an ObjCObjectPointerType that refers
+  /// to a class (for an instance message to super);
+  QualType getSuperType() const {
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return QualType::getFromOpaquePtr(getReceiverPointer());
+
+    return QualType();
+  }
+
+  void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
+    Kind = IsInstanceSuper? SuperInstance : SuperClass;
+    SuperLoc = Loc;
+    setReceiverPointer(T.getAsOpaquePtr());
+  }
+
+  Selector getSelector() const;
+
+  void setSelector(Selector S) { 
+    HasMethod = false;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
+  }
+
+  const ObjCMethodDecl *getMethodDecl() const { 
+    if (HasMethod)
+      return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
+
+    return nullptr;
+  }
+
+  ObjCMethodDecl *getMethodDecl() { 
+    if (HasMethod)
+      return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+    return nullptr;
+  }
+
+  void setMethodDecl(ObjCMethodDecl *MD) { 
+    HasMethod = true;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
+  }
+
+  ObjCMethodFamily getMethodFamily() const {
+    if (HasMethod) return getMethodDecl()->getMethodFamily();
+    return getSelector().getMethodFamily();
+  }
+
+  /// \brief Return the number of actual arguments in this message,
+  /// not counting the receiver.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Retrieve the arguments to this message, not including the
+  /// receiver.
+  Expr **getArgs() {
+    return reinterpret_cast<Expr **>(this + 1) + 1;
+  }
+  const Expr * const *getArgs() const {
+    return reinterpret_cast<const Expr * const *>(this + 1) + 1;
+  }
+
+  /// getArg - Return the specified argument.
+  Expr *getArg(unsigned Arg) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(getArgs()[Arg]);
+  }
+  const Expr *getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return cast<Expr>(getArgs()[Arg]);
+  }
+  /// setArg - Set the specified argument.
+  void setArg(unsigned Arg, Expr *ArgExpr) {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    getArgs()[Arg] = ArgExpr;
+  }
+
+  /// isDelegateInitCall - Answers whether this message send has been
+  /// tagged as a "delegate init call", i.e. a call to a method in the
+  /// -init family on self from within an -init method implementation.
+  bool isDelegateInitCall() const { return IsDelegateInitCall; }
+  void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
+
+  SourceLocation getLeftLoc() const { return LBracLoc; }
+  SourceLocation getRightLoc() const { return RBracLoc; }
+
+  SourceLocation getSelectorStartLoc() const {
+    if (isImplicit())
+      return getLocStart();
+    return getSelectorLoc(0);
+  }
+  SourceLocation getSelectorLoc(unsigned Index) const {
+    assert(Index < getNumSelectorLocs() && "Index out of range!");
+    if (hasStandardSelLocs())
+      return getStandardSelectorLoc(Index, getSelector(),
+                                   getSelLocsKind() == SelLoc_StandardWithSpace,
+                               llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
+                                                  getNumArgs()),
+                                   RBracLoc);
+    return getStoredSelLocs()[Index];
+  }
+
+  void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
+
+  unsigned getNumSelectorLocs() const {
+    if (isImplicit())
+      return 0;
+    Selector Sel = getSelector();
+    if (Sel.isUnarySelector())
+      return 1;
+    return Sel.getNumArgs();
+  }
+
+  void setSourceRange(SourceRange R) {
+    LBracLoc = R.getBegin();
+    RBracLoc = R.getEnd();
+  }
+  SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCMessageExprClass;
+  }
+
+  // Iterators
+  child_range children();
+
+  typedef ExprIterator arg_iterator;
+  typedef ConstExprIterator const_arg_iterator;
+
+  arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
+  arg_iterator arg_end()   { 
+    return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 
+  }
+  const_arg_iterator arg_begin() const { 
+    return reinterpret_cast<Stmt const * const*>(getArgs()); 
+  }
+  const_arg_iterator arg_end() const { 
+    return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 
+  }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
+/// (similar in spirit to MemberExpr).
+class ObjCIsaExpr : public Expr {
+  /// Base - the expression for the base object pointer.
+  Stmt *Base;
+
+  /// IsaMemberLoc - This is the location of the 'isa'.
+  SourceLocation IsaMemberLoc;
+  
+  /// OpLoc - This is the location of '.' or '->'
+  SourceLocation OpLoc;
+
+  /// IsArrow - True if this is "X->F", false if this is "X.F".
+  bool IsArrow;
+public:
+  ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc,
+              QualType ty)
+    : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
+           /*TypeDependent=*/false, base->isValueDependent(),
+           base->isInstantiationDependent(),
+           /*ContainsUnexpandedParameterPack=*/false),
+      Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {}
+
+  /// \brief Build an empty expression.
+  explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
+
+  void setBase(Expr *E) { Base = E; }
+  Expr *getBase() const { return cast<Expr>(Base); }
+
+  bool isArrow() const { return IsArrow; }
+  void setArrow(bool A) { IsArrow = A; }
+
+  /// getMemberLoc - Return the location of the "member", in X->F, it is the
+  /// location of 'F'.
+  SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
+  void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
+  
+  SourceLocation getOpLoc() const { return OpLoc; }
+  void setOpLoc(SourceLocation L) { OpLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getBase()->getLocStart();
+  }
+  
+  SourceLocation getBaseLocEnd() const LLVM_READONLY {
+    return getBase()->getLocEnd();
+  }
+  
+  SourceLocation getLocEnd() const LLVM_READONLY { return IsaMemberLoc; }
+
+  SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCIsaExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Base, &Base+1); }
+};
+
+
+/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
+/// argument by indirect copy-restore in ARC.  This is used to support
+/// passing indirect arguments with the wrong lifetime, e.g. when
+/// passing the address of a __strong local variable to an 'out'
+/// parameter.  This expression kind is only valid in an "argument"
+/// position to some sort of call expression.
+///
+/// The parameter must have type 'pointer to T', and the argument must
+/// have type 'pointer to U', where T and U agree except possibly in
+/// qualification.  If the argument value is null, then a null pointer
+/// is passed;  otherwise it points to an object A, and:
+/// 1. A temporary object B of type T is initialized, either by
+///    zero-initialization (used when initializing an 'out' parameter)
+///    or copy-initialization (used when initializing an 'inout'
+///    parameter).
+/// 2. The address of the temporary is passed to the function.
+/// 3. If the call completes normally, A is move-assigned from B.
+/// 4. Finally, A is destroyed immediately.
+///
+/// Currently 'T' must be a retainable object lifetime and must be
+/// __autoreleasing;  this qualifier is ignored when initializing
+/// the value.
+class ObjCIndirectCopyRestoreExpr : public Expr {
+  Stmt *Operand;
+
+  // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+
+  void setShouldCopy(bool shouldCopy) {
+    ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
+  }
+
+  explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
+    : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
+
+public:
+  ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
+    : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
+           operand->isTypeDependent(), operand->isValueDependent(),
+           operand->isInstantiationDependent(),
+           operand->containsUnexpandedParameterPack()),
+      Operand(operand) {
+    setShouldCopy(shouldCopy);
+  }
+
+  Expr *getSubExpr() { return cast<Expr>(Operand); }
+  const Expr *getSubExpr() const { return cast<Expr>(Operand); }
+
+  /// shouldCopy - True if we should do the 'copy' part of the
+  /// copy-restore.  If false, the temporary will be zero-initialized.
+  bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
+
+  child_range children() { return child_range(&Operand, &Operand+1); }  
+
+  // Source locations are determined by the subexpression.
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return Operand->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Operand->getLocEnd();}
+
+  SourceLocation getExprLoc() const LLVM_READONLY {
+    return getSubExpr()->getExprLoc();
+  }
+
+  static bool classof(const Stmt *s) {
+    return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
+  }
+};
+
+/// \brief An Objective-C "bridged" cast expression, which casts between
+/// Objective-C pointers and C pointers, transferring ownership in the process.
+///
+/// \code
+/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
+/// \endcode
+class ObjCBridgedCastExpr : public ExplicitCastExpr {
+  SourceLocation LParenLoc;
+  SourceLocation BridgeKeywordLoc;
+  unsigned Kind : 2;
+  
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+  
+public:
+  ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
+                      CastKind CK, SourceLocation BridgeKeywordLoc,
+                      TypeSourceInfo *TSInfo, Expr *Operand)
+    : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
+                       CK, Operand, 0, TSInfo),
+      LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
+  
+  /// \brief Construct an empty Objective-C bridged cast.
+  explicit ObjCBridgedCastExpr(EmptyShell Shell)
+    : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
+
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Determine which kind of bridge is being performed via this cast.
+  ObjCBridgeCastKind getBridgeKind() const { 
+    return static_cast<ObjCBridgeCastKind>(Kind); 
+  }
+  
+  /// \brief Retrieve the kind of bridge being performed as a string.
+  StringRef getBridgeKindName() const;
+  
+  /// \brief The location of the bridge keyword.
+  SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
+  
+  SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSubExpr()->getLocEnd();
+  }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCBridgedCastExprClass;
+  }
+};
+  
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
new file mode 100644
index 0000000..1e8eff3
--- /dev/null
+++ b/include/clang/AST/ExternalASTSource.h
@@ -0,0 +1,653 @@
+//===--- ExternalASTSource.h - Abstract External AST Interface --*- 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 ExternalASTSource interface, which enables
+//  construction of AST nodes from some external source.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+#define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
+
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclBase.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+class ASTConsumer;
+class CXXBaseSpecifier;
+class DeclarationName;
+class ExternalSemaSource; // layering violation required for downcasting
+class FieldDecl;
+class Module;
+class NamedDecl;
+class RecordDecl;
+class Selector;
+class Stmt;
+class TagDecl;
+
+/// \brief Enumeration describing the result of loading information from
+/// an external source.
+enum ExternalLoadResult {
+  /// \brief Loading the external information has succeeded.
+  ELR_Success,
+  
+  /// \brief Loading the external information has failed.
+  ELR_Failure,
+  
+  /// \brief The external information has already been loaded, and therefore
+  /// no additional processing is required.
+  ELR_AlreadyLoaded
+};
+
+/// \brief Abstract interface for external sources of AST nodes.
+///
+/// External AST sources provide AST nodes constructed from some
+/// external source, such as a precompiled header. External AST
+/// sources can resolve types and declarations from abstract IDs into
+/// actual type and declaration nodes, and read parts of declaration
+/// contexts.
+class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+  /// Generation number for this external AST source. Must be increased
+  /// whenever we might have added new redeclarations for existing decls.
+  uint32_t CurrentGeneration;
+
+  /// \brief Whether this AST source also provides information for
+  /// semantic analysis.
+  bool SemaSource;
+
+  friend class ExternalSemaSource;
+
+public:
+  ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
+
+  virtual ~ExternalASTSource();
+
+  /// \brief RAII class for safely pairing a StartedDeserializing call
+  /// with FinishedDeserializing.
+  class Deserializing {
+    ExternalASTSource *Source;
+  public:
+    explicit Deserializing(ExternalASTSource *source) : Source(source) {
+      assert(Source);
+      Source->StartedDeserializing();
+    }
+    ~Deserializing() {
+      Source->FinishedDeserializing();
+    }
+  };
+
+  /// \brief Get the current generation of this AST source. This number
+  /// is incremented each time the AST source lazily extends an existing
+  /// entity.
+  uint32_t getGeneration() const { return CurrentGeneration; }
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  ///
+  /// This method only needs to be implemented if the AST source ever
+  /// passes back decl sets as VisibleDeclaration objects.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual Decl *GetExternalDecl(uint32_t ID);
+
+  /// \brief Resolve a selector ID into a selector.
+  ///
+  /// This operation only needs to be implemented if the AST source
+  /// returns non-zero for GetNumKnownSelectors().
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual Selector GetExternalSelector(uint32_t ID);
+
+  /// \brief Returns the number of selectors known to the external AST
+  /// source.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual uint32_t GetNumExternalSelectors();
+
+  /// \brief Resolve the offset of a statement in the decl stream into
+  /// a statement.
+  ///
+  /// This operation is meant to be used via a LazyOffsetPtr.  It only
+  /// needs to be implemented if the AST source uses methods like
+  /// FunctionDecl::setLazyBody when building decls.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
+
+  /// \brief Resolve the offset of a set of C++ base specifiers in the decl
+  /// stream into an array of specifiers.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+
+  /// \brief Update an out-of-date identifier.
+  virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { }
+
+  /// \brief Find all declarations with the given name in the given context,
+  /// and add them to the context by calling SetExternalVisibleDeclsForName
+  /// or SetNoExternalVisibleDeclsForName.
+  /// \return \c true if any declarations might have been found, \c false if
+  /// we definitely have no declarations with tbis name.
+  ///
+  /// The default implementation of this method is a no-op returning \c false.
+  virtual bool
+  FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
+
+  /// \brief Ensures that the table of all visible declarations inside this
+  /// context is up to date.
+  ///
+  /// The default implementation of this function is a no-op.
+  virtual void completeVisibleDeclsMap(const DeclContext *DC);
+
+  /// \brief Retrieve the module that corresponds to the given module ID.
+  virtual Module *getModule(unsigned ID) { return nullptr; }
+
+  /// \brief Finds all declarations lexically contained within the given
+  /// DeclContext, after applying an optional filter predicate.
+  ///
+  /// \param isKindWeWant a predicate function that returns true if the passed
+  /// declaration kind is one we are looking for. If NULL, all declarations
+  /// are returned.
+  ///
+  /// \return an indication of whether the load succeeded or failed.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                        bool (*isKindWeWant)(Decl::Kind),
+                                        SmallVectorImpl<Decl*> &Result);
+
+  /// \brief Finds all declarations lexically contained within the given
+  /// DeclContext.
+  ///
+  /// \return true if an error occurred
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                SmallVectorImpl<Decl*> &Result) {
+    return FindExternalLexicalDecls(DC, nullptr, Result);
+  }
+
+  template <typename DeclTy>
+  ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
+                                  SmallVectorImpl<Decl*> &Result) {
+    return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
+  }
+
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \p Length can be 0 to indicate a point at \p Offset instead of
+  /// a range.
+  virtual void FindFileRegionDecls(FileID File, unsigned Offset,
+                                   unsigned Length,
+                                   SmallVectorImpl<Decl *> &Decls);
+
+  /// \brief Gives the external AST source an opportunity to complete
+  /// the redeclaration chain for a declaration. Called each time we
+  /// need the most recent declaration of a declaration after the
+  /// generation count is incremented.
+  virtual void CompleteRedeclChain(const Decl *D);
+
+  /// \brief Gives the external AST source an opportunity to complete
+  /// an incomplete type.
+  virtual void CompleteType(TagDecl *Tag);
+
+  /// \brief Gives the external AST source an opportunity to complete an
+  /// incomplete Objective-C class.
+  ///
+  /// This routine will only be invoked if the "externally completed" bit is
+  /// set on the ObjCInterfaceDecl via the function
+  /// \c ObjCInterfaceDecl::setExternallyCompleted().
+  virtual void CompleteType(ObjCInterfaceDecl *Class);
+
+  /// \brief Loads comment ranges.
+  virtual void ReadComments();
+
+  /// \brief Notify ExternalASTSource that we started deserialization of
+  /// a decl or type so until FinishedDeserializing is called there may be
+  /// decls that are initializing. Must be paired with FinishedDeserializing.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual void StartedDeserializing();
+
+  /// \brief Notify ExternalASTSource that we finished the deserialization of
+  /// a decl or type. Must be paired with StartedDeserializing.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual void FinishedDeserializing();
+
+  /// \brief Function that will be invoked when we begin parsing a new
+  /// translation unit involving this external AST source.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual void StartTranslationUnit(ASTConsumer *Consumer);
+
+  /// \brief Print any statistics that have been gathered regarding
+  /// the external AST source.
+  ///
+  /// The default implementation of this method is a no-op.
+  virtual void PrintStats();
+  
+  
+  /// \brief Perform layout on the given record.
+  ///
+  /// This routine allows the external AST source to provide an specific 
+  /// layout for a record, overriding the layout that would normally be
+  /// constructed. It is intended for clients who receive specific layout
+  /// details rather than source code (such as LLDB). The client is expected
+  /// to fill in the field offsets, base offsets, virtual base offsets, and
+  /// complete object size.
+  ///
+  /// \param Record The record whose layout is being requested.
+  ///
+  /// \param Size The final size of the record, in bits.
+  ///
+  /// \param Alignment The final alignment of the record, in bits.
+  ///
+  /// \param FieldOffsets The offset of each of the fields within the record,
+  /// expressed in bits. All of the fields must be provided with offsets.
+  ///
+  /// \param BaseOffsets The offset of each of the direct, non-virtual base
+  /// classes. If any bases are not given offsets, the bases will be laid 
+  /// out according to the ABI.
+  ///
+  /// \param VirtualBaseOffsets The offset of each of the virtual base classes
+  /// (either direct or not). If any bases are not given offsets, the bases will be laid 
+  /// out according to the ABI.
+  /// 
+  /// \returns true if the record layout was provided, false otherwise.
+  virtual bool layoutRecordType(
+      const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+      llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+      llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+      llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+
+  //===--------------------------------------------------------------------===//
+  // Queries for performance analysis.
+  //===--------------------------------------------------------------------===//
+  
+  struct MemoryBufferSizes {
+    size_t malloc_bytes;
+    size_t mmap_bytes;
+    
+    MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
+    : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
+  };
+  
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  MemoryBufferSizes getMemoryBufferSizes() const {
+    MemoryBufferSizes sizes(0, 0);
+    getMemoryBufferSizes(sizes);
+    return sizes;
+  }
+
+  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+
+protected:
+  static DeclContextLookupResult
+  SetExternalVisibleDeclsForName(const DeclContext *DC,
+                                 DeclarationName Name,
+                                 ArrayRef<NamedDecl*> Decls);
+
+  static DeclContextLookupResult
+  SetNoExternalVisibleDeclsForName(const DeclContext *DC,
+                                   DeclarationName Name);
+
+  /// \brief Increment the current generation.
+  uint32_t incrementGeneration(ASTContext &C);
+};
+
+/// \brief A lazy pointer to an AST node (of base type T) that resides
+/// within an external AST source.
+///
+/// The AST node is identified within the external AST source by a
+/// 63-bit offset, and can be retrieved via an operation on the
+/// external AST source itself.
+template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
+struct LazyOffsetPtr {
+  /// \brief Either a pointer to an AST node or the offset within the
+  /// external AST source where the AST node can be found.
+  ///
+  /// If the low bit is clear, a pointer to the AST node. If the low
+  /// bit is set, the upper 63 bits are the offset.
+  mutable uint64_t Ptr;
+
+public:
+  LazyOffsetPtr() : Ptr(0) { }
+
+  explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
+  explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
+    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+    if (Offset == 0)
+      Ptr = 0;
+  }
+
+  LazyOffsetPtr &operator=(T *Ptr) {
+    this->Ptr = reinterpret_cast<uint64_t>(Ptr);
+    return *this;
+  }
+
+  LazyOffsetPtr &operator=(uint64_t Offset) {
+    assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
+    if (Offset == 0)
+      Ptr = 0;
+    else
+      Ptr = (Offset << 1) | 0x01;
+
+    return *this;
+  }
+
+  /// \brief Whether this pointer is non-NULL.
+  ///
+  /// This operation does not require the AST node to be deserialized.
+  LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
+
+  /// \brief Whether this pointer is non-NULL.
+  ///
+  /// This operation does not require the AST node to be deserialized.
+  bool isValid() const { return Ptr != 0; }
+
+  /// \brief Whether this pointer is currently stored as an offset.
+  bool isOffset() const { return Ptr & 0x01; }
+
+  /// \brief Retrieve the pointer to the AST node that this lazy pointer
+  ///
+  /// \param Source the external AST source.
+  ///
+  /// \returns a pointer to the AST node.
+  T* get(ExternalASTSource *Source) const {
+    if (isOffset()) {
+      assert(Source &&
+             "Cannot deserialize a lazy pointer without an AST source");
+      Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
+    }
+    return reinterpret_cast<T*>(Ptr);
+  }
+};
+
+/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// where the value might change in later generations of the external AST
+/// source.
+template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
+struct LazyGenerationalUpdatePtr {
+  /// A cache of the value of this pointer, in the most recent generation in
+  /// which we queried it.
+  struct LazyData {
+    LazyData(ExternalASTSource *Source, T Value)
+        : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
+    ExternalASTSource *ExternalSource;
+    uint32_t LastGeneration;
+    T LastValue;
+  };
+
+  // Our value is represented as simply T if there is no external AST source.
+  typedef llvm::PointerUnion<T, LazyData*> ValueType;
+  ValueType Value;
+
+  LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+
+  // Defined in ASTContext.h
+  static ValueType makeValue(const ASTContext &Ctx, T Value);
+
+public:
+  explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+      : Value(makeValue(Ctx, Value)) {}
+
+  /// Create a pointer that is not potentially updated by later generations of
+  /// the external AST source.
+  enum NotUpdatedTag { NotUpdated };
+  LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
+      : Value(Value) {}
+
+  /// Forcibly set this pointer (which must be lazy) as needing updates.
+  void markIncomplete() {
+    Value.template get<LazyData *>()->LastGeneration = 0;
+  }
+
+  /// Set the value of this pointer, in the current generation.
+  void set(T NewValue) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      LazyVal->LastValue = NewValue;
+      return;
+    }
+    Value = NewValue;
+  }
+
+  /// Set the value of this pointer, for this and all future generations.
+  void setNotUpdated(T NewValue) { Value = NewValue; }
+
+  /// Get the value of this pointer, updating its owner if necessary.
+  T get(Owner O) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
+        LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+        (LazyVal->ExternalSource->*Update)(O);
+      }
+      return LazyVal->LastValue;
+    }
+    return Value.template get<T>();
+  }
+
+  /// Get the most recently computed value of this pointer without updating it.
+  T getNotUpdated() const {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+      return LazyVal->LastValue;
+    return Value.template get<T>();
+  }
+
+  void *getOpaqueValue() { return Value.getOpaqueValue(); }
+  static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
+    return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+  }
+};
+} // end namespace clang
+
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// placed into a PointerUnion.
+namespace llvm {
+template<typename Owner, typename T,
+         void (clang::ExternalASTSource::*Update)(Owner)>
+struct PointerLikeTypeTraits<
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
+  typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+  static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
+  static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+  enum {
+    NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
+  };
+};
+}
+
+namespace clang {
+/// \brief Represents a lazily-loaded vector of data.
+///
+/// The lazily-loaded vector of data contains data that is partially loaded
+/// from an external source and partially added by local translation. The 
+/// items loaded from the external source are loaded lazily, when needed for
+/// iteration over the complete vector.
+template<typename T, typename Source, 
+         void (Source::*Loader)(SmallVectorImpl<T>&),
+         unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
+class LazyVector {
+  SmallVector<T, LoadedStorage> Loaded;
+  SmallVector<T, LocalStorage> Local;
+
+public:
+  // Iteration over the elements in the vector.
+  class iterator {
+    LazyVector *Self;
+    
+    /// \brief Position within the vector..
+    ///
+    /// In a complete iteration, the Position field walks the range [-M, N),
+    /// where negative values are used to indicate elements
+    /// loaded from the external source while non-negative values are used to
+    /// indicate elements added via \c push_back().
+    /// However, to provide iteration in source order (for, e.g., chained
+    /// precompiled headers), dereferencing the iterator flips the negative
+    /// values (corresponding to loaded entities), so that position -M 
+    /// corresponds to element 0 in the loaded entities vector, position -M+1
+    /// corresponds to element 1 in the loaded entities vector, etc. This
+    /// gives us a reasonably efficient, source-order walk.
+    int Position;
+    
+    friend class LazyVector;
+    
+  public:
+    typedef T                   value_type;
+    typedef value_type&         reference;
+    typedef value_type*         pointer;
+    typedef std::random_access_iterator_tag iterator_category;
+    typedef int                 difference_type;
+    
+    iterator() : Self(0), Position(0) { }
+    
+    iterator(LazyVector *Self, int Position) 
+      : Self(Self), Position(Position) { }
+    
+    reference operator*() const {
+      if (Position < 0)
+        return Self->Loaded.end()[Position];
+      return Self->Local[Position];
+    }
+    
+    pointer operator->() const {
+      if (Position < 0)
+        return &Self->Loaded.end()[Position];
+      
+      return &Self->Local[Position];        
+    }
+    
+    reference operator[](difference_type D) {
+      return *(*this + D);
+    }
+    
+    iterator &operator++() {
+      ++Position;
+      return *this;
+    }
+    
+    iterator operator++(int) {
+      iterator Prev(*this);
+      ++Position;
+      return Prev;
+    }
+    
+    iterator &operator--() {
+      --Position;
+      return *this;
+    }
+    
+    iterator operator--(int) {
+      iterator Prev(*this);
+      --Position;
+      return Prev;
+    }
+    
+    friend bool operator==(const iterator &X, const iterator &Y) {
+      return X.Position == Y.Position;
+    }
+    
+    friend bool operator!=(const iterator &X, const iterator &Y) {
+      return X.Position != Y.Position;
+    }
+    
+    friend bool operator<(const iterator &X, const iterator &Y) {
+      return X.Position < Y.Position;
+    }
+    
+    friend bool operator>(const iterator &X, const iterator &Y) {
+      return X.Position > Y.Position;
+    }
+    
+    friend bool operator<=(const iterator &X, const iterator &Y) {
+      return X.Position < Y.Position;
+    }
+    
+    friend bool operator>=(const iterator &X, const iterator &Y) {
+      return X.Position > Y.Position;
+    }
+    
+    friend iterator& operator+=(iterator &X, difference_type D) {
+      X.Position += D;
+      return X;
+    }
+    
+    friend iterator& operator-=(iterator &X, difference_type D) {
+      X.Position -= D;
+      return X;
+    }
+    
+    friend iterator operator+(iterator X, difference_type D) {
+      X.Position += D;
+      return X;
+    }
+    
+    friend iterator operator+(difference_type D, iterator X) {
+      X.Position += D;
+      return X;
+    }
+    
+    friend difference_type operator-(const iterator &X, const iterator &Y) {
+      return X.Position - Y.Position;
+    }
+    
+    friend iterator operator-(iterator X, difference_type D) {
+      X.Position -= D;
+      return X;
+    }
+  };
+  friend class iterator;
+  
+  iterator begin(Source *source, bool LocalOnly = false) {
+    if (LocalOnly)
+      return iterator(this, 0);
+    
+    if (source)
+      (source->*Loader)(Loaded);
+    return iterator(this, -(int)Loaded.size());
+  }
+  
+  iterator end() {
+    return iterator(this, Local.size());
+  }
+  
+  void push_back(const T& LocalValue) {
+    Local.push_back(LocalValue);
+  }
+  
+  void erase(iterator From, iterator To) {
+    if (From.Position < 0 && To.Position < 0) {
+      Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position);
+      return;
+    }
+    
+    if (From.Position < 0) {
+      Loaded.erase(Loaded.end() + From.Position, Loaded.end());
+      From = begin(nullptr, true);
+    }
+    
+    Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
+  }
+};
+
+/// \brief A lazy pointer to a statement.
+typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
+  LazyDeclStmtPtr;
+
+/// \brief A lazy pointer to a declaration.
+typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
+  LazyDeclPtr;
+
+/// \brief A lazy pointer to a set of CXXBaseSpecifiers.
+typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, 
+                      &ExternalASTSource::GetExternalCXXBaseSpecifiers>
+  LazyCXXBaseSpecifiersPtr;
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
new file mode 100644
index 0000000..54c9d88
--- /dev/null
+++ b/include/clang/AST/GlobalDecl.h
@@ -0,0 +1,125 @@
+//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
+// together with its type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_GLOBALDECL_H
+#define LLVM_CLANG_AST_GLOBALDECL_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/ABI.h"
+
+namespace clang {
+
+/// GlobalDecl - represents a global declaration. This can either be a
+/// CXXConstructorDecl and the constructor type (Base, Complete).
+/// a CXXDestructorDecl and the destructor type (Base, Complete) or
+/// a VarDecl, a FunctionDecl or a BlockDecl.
+class GlobalDecl {
+  llvm::PointerIntPair<const Decl*, 2> Value;
+
+  void Init(const Decl *D) {
+    assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
+    assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
+
+    Value.setPointer(D);
+  }
+
+public:
+  GlobalDecl() {}
+
+  GlobalDecl(const VarDecl *D) { Init(D);}
+  GlobalDecl(const FunctionDecl *D) { Init(D); }
+  GlobalDecl(const BlockDecl *D) { Init(D); }
+  GlobalDecl(const CapturedDecl *D) { Init(D); }
+  GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
+
+  GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
+  : Value(D, Type) {}
+  GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
+  : Value(D, Type) {}
+
+  GlobalDecl getCanonicalDecl() const {
+    GlobalDecl CanonGD;
+    CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
+    CanonGD.Value.setInt(Value.getInt());
+    
+    return CanonGD;
+  }
+
+  const Decl *getDecl() const { return Value.getPointer(); }
+
+  CXXCtorType getCtorType() const {
+    assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
+    return static_cast<CXXCtorType>(Value.getInt());
+  }
+
+  CXXDtorType getDtorType() const {
+    assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
+    return static_cast<CXXDtorType>(Value.getInt());
+  }
+  
+  friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
+    return LHS.Value == RHS.Value;
+  }
+  
+  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+
+  static GlobalDecl getFromOpaquePtr(void *P) {
+    GlobalDecl GD;
+    GD.Value.setFromOpaqueValue(P);
+    return GD;
+  }
+  
+  GlobalDecl getWithDecl(const Decl *D) {
+    GlobalDecl Result(*this);
+    Result.Value.setPointer(D);
+    return Result;
+  }
+};
+
+} // end namespace clang
+
+namespace llvm {
+  template<class> struct DenseMapInfo;
+
+  template<> struct DenseMapInfo<clang::GlobalDecl> {
+    static inline clang::GlobalDecl getEmptyKey() {
+      return clang::GlobalDecl();
+    }
+  
+    static inline clang::GlobalDecl getTombstoneKey() {
+      return clang::GlobalDecl::
+        getFromOpaquePtr(reinterpret_cast<void*>(-1));
+    }
+
+    static unsigned getHashValue(clang::GlobalDecl GD) {
+      return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
+    }
+    
+    static bool isEqual(clang::GlobalDecl LHS, 
+                        clang::GlobalDecl RHS) {
+      return LHS == RHS;
+    }
+      
+  };
+  
+  // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
+  // copy assignment operator, and destructor are all trivial.
+  template <>
+  struct isPodLike<clang::GlobalDecl> {
+    static const bool value = true;
+  };
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
new file mode 100644
index 0000000..8633c97
--- /dev/null
+++ b/include/clang/AST/LambdaCapture.h
@@ -0,0 +1,123 @@
+//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the LambdaCapture class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
+#define LLVM_CLANG_AST_LAMBDACAPTURE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Lambda.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+/// \brief Describes the capture of a variable or of \c this, or of a
+/// C++1y init-capture.
+class LambdaCapture {
+  enum {
+    /// \brief Flag used by the Capture class to indicate that the given
+    /// capture was implicit.
+    Capture_Implicit = 0x01,
+
+    /// \brief Flag used by the Capture class to indicate that the
+    /// given capture was by-copy.
+    ///
+    /// This includes the case of a non-reference init-capture.
+    Capture_ByCopy = 0x02
+  };
+
+  llvm::PointerIntPair<Decl *, 2> DeclAndBits;
+  SourceLocation Loc;
+  SourceLocation EllipsisLoc;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+public:
+  /// \brief Create a new capture of a variable or of \c this.
+  ///
+  /// \param Loc The source location associated with this capture.
+  ///
+  /// \param Kind The kind of capture (this, byref, bycopy), which must
+  /// not be init-capture.
+  ///
+  /// \param Implicit Whether the capture was implicit or explicit.
+  ///
+  /// \param Var The local variable being captured, or null if capturing
+  /// \c this.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis (...) for a
+  /// capture that is a pack expansion, or an invalid source
+  /// location to indicate that this is not a pack expansion.
+  LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
+                VarDecl *Var = nullptr,
+                SourceLocation EllipsisLoc = SourceLocation());
+
+  /// \brief Determine the kind of capture.
+  LambdaCaptureKind getCaptureKind() const;
+
+  /// \brief Determine whether this capture handles the C++ \c this
+  /// pointer.
+  bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+
+  /// \brief Determine whether this capture handles a variable.
+  bool capturesVariable() const {
+    return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+  }
+
+  /// \brief Determine whether this is an init-capture.
+  bool isInitCapture() const {
+    return capturesVariable() && getCapturedVar()->isInitCapture();
+  }
+
+  /// \brief Retrieve the declaration of the local variable being
+  /// captured.
+  ///
+  /// This operation is only valid if this capture is a variable capture
+  /// (other than a capture of \c this).
+  VarDecl *getCapturedVar() const {
+    assert(capturesVariable() && "No variable available for 'this' capture");
+    return cast<VarDecl>(DeclAndBits.getPointer());
+  }
+
+  /// \brief Determine whether this was an implicit capture (not
+  /// written between the square brackets introducing the lambda).
+  bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
+
+  /// \brief Determine whether this was an explicit capture (written
+  /// between the square brackets introducing the lambda).
+  bool isExplicit() const { return !isImplicit(); }
+
+  /// \brief Retrieve the source location of the capture.
+  ///
+  /// For an explicit capture, this returns the location of the
+  /// explicit capture in the source. For an implicit capture, this
+  /// returns the location at which the variable or \c this was first
+  /// used.
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Determine whether this capture is a pack expansion,
+  /// which captures a function parameter pack.
+  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+  /// \brief Retrieve the location of the ellipsis for a capture
+  /// that is a pack expansion.
+  SourceLocation getEllipsisLoc() const {
+    assert(isPackExpansion() && "No ellipsis location for a non-expansion");
+    return EllipsisLoc;
+  }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
new file mode 100644
index 0000000..a8d1199
--- /dev/null
+++ b/include/clang/AST/Mangle.h
@@ -0,0 +1,213 @@
+//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the C++ name mangling interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MANGLE_H
+#define LLVM_CLANG_AST_MANGLE_H
+
+#include "clang/AST/Type.h"
+#include "clang/Basic/ABI.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+  class ASTContext;
+  class BlockDecl;
+  class CXXConstructorDecl;
+  class CXXDestructorDecl;
+  class CXXMethodDecl;
+  class FunctionDecl;
+  class NamedDecl;
+  class ObjCMethodDecl;
+  class StringLiteral;
+  struct ThisAdjustment;
+  struct ThunkInfo;
+  class VarDecl;
+
+/// MangleContext - Context for tracking state which persists across multiple
+/// calls to the C++ name mangler.
+class MangleContext {
+public:
+  enum ManglerKind {
+    MK_Itanium,
+    MK_Microsoft
+  };
+
+private:
+  virtual void anchor();
+
+  ASTContext &Context;
+  DiagnosticsEngine &Diags;
+  const ManglerKind Kind;
+
+  llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
+  llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
+  llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
+
+public:
+  ManglerKind getKind() const { return Kind; }
+
+  explicit MangleContext(ASTContext &Context,
+                         DiagnosticsEngine &Diags,
+                         ManglerKind Kind)
+      : Context(Context), Diags(Diags), Kind(Kind) {}
+
+  virtual ~MangleContext() { }
+
+  ASTContext &getASTContext() const { return Context; }
+
+  DiagnosticsEngine &getDiags() const { return Diags; }
+
+  virtual void startNewFunction() { LocalBlockIds.clear(); }
+  
+  unsigned getBlockId(const BlockDecl *BD, bool Local) {
+    llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
+      = Local? LocalBlockIds : GlobalBlockIds;
+    std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
+      Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
+    return Result.first->second;
+  }
+
+  uint64_t getAnonymousStructId(const TagDecl *TD) {
+    std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
+        Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+    return Result.first->second;
+  }
+
+  /// @name Mangler Entry Points
+  /// @{
+
+  bool shouldMangleDeclName(const NamedDecl *D);
+  virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
+  virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
+
+  // FIXME: consider replacing raw_ostream & with something like SmallString &.
+  void mangleName(const NamedDecl *D, raw_ostream &);
+  virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
+  virtual void mangleThunk(const CXXMethodDecl *MD,
+                          const ThunkInfo &Thunk,
+                          raw_ostream &) = 0;
+  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                                  const ThisAdjustment &ThisAdjustment,
+                                  raw_ostream &) = 0;
+  virtual void mangleReferenceTemporary(const VarDecl *D,
+                                        unsigned ManglingNumber,
+                                        raw_ostream &) = 0;
+  virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
+  virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
+  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                             raw_ostream &) = 0;
+  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                             raw_ostream &) = 0;
+  virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
+
+  void mangleGlobalBlock(const BlockDecl *BD,
+                         const NamedDecl *ID,
+                         raw_ostream &Out);
+  void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
+                       const BlockDecl *BD, raw_ostream &Out);
+  void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
+                       const BlockDecl *BD, raw_ostream &Out);
+  void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
+                   raw_ostream &Out);
+
+  void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
+
+  virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
+
+  virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
+
+  virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                             raw_ostream &) = 0;
+
+  /// Generates a unique string for an externally visible type for use with TBAA
+  /// or type uniquing.
+  /// TODO: Extend this to internal types by generating names that are unique
+  /// across translation units so it can be used with LTO.
+  virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
+
+  /// @}
+};
+
+class ItaniumMangleContext : public MangleContext {
+public:
+  explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
+      : MangleContext(C, D, MK_Itanium) {}
+
+  virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
+  virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
+  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+                                   const CXXRecordDecl *Type,
+                                   raw_ostream &) = 0;
+  virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
+                                            raw_ostream &) = 0;
+  virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
+                                               raw_ostream &) = 0;
+
+  static bool classof(const MangleContext *C) {
+    return C->getKind() == MK_Itanium;
+  }
+
+  static ItaniumMangleContext *create(ASTContext &Context,
+                                      DiagnosticsEngine &Diags);
+};
+
+class MicrosoftMangleContext : public MangleContext {
+public:
+  explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
+      : MangleContext(C, D, MK_Microsoft) {}
+
+  /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
+  /// to the vftable are included in the name.  It's up to the caller to pick
+  /// them correctly.
+  virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
+                                ArrayRef<const CXXRecordDecl *> BasePath,
+                                raw_ostream &Out) = 0;
+
+  /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
+  /// to the vbtable are included in the name.  It's up to the caller to pick
+  /// them correctly.
+  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
+                                ArrayRef<const CXXRecordDecl *> BasePath,
+                                raw_ostream &Out) = 0;
+
+  virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
+                                        raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTIBaseClassDescriptor(
+      const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+      uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
+
+  virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+                                           raw_ostream &Out) = 0;
+  virtual void
+  mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+                                        raw_ostream &Out) = 0;
+
+  virtual void
+  mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+                                     ArrayRef<const CXXRecordDecl *> BasePath,
+                                     raw_ostream &Out) = 0;
+
+  static bool classof(const MangleContext *C) {
+    return C->getKind() == MK_Microsoft;
+  }
+
+  static MicrosoftMangleContext *create(ASTContext &Context,
+                                        DiagnosticsEngine &Diags);
+};
+}
+
+#endif
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
new file mode 100644
index 0000000..56c9952
--- /dev/null
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -0,0 +1,63 @@
+//=== MangleNumberingContext.h - Context for mangling numbers ---*- 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 LambdaBlockMangleContext interface, which keeps track
+//  of the Itanium C++ ABI mangling numbers for lambda expressions and block
+//  literals.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
+#define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+namespace clang {
+
+class BlockDecl;
+class CXXMethodDecl;
+class IdentifierInfo;
+class TagDecl;
+class Type;
+class VarDecl;
+
+/// \brief Keeps track of the mangled names of lambda expressions and block
+/// literals within a particular context.
+class MangleNumberingContext 
+    : public RefCountedBase<MangleNumberingContext> {
+  llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
+
+public:
+  virtual ~MangleNumberingContext() {}
+
+  /// \brief Retrieve the mangling number of a new lambda expression with the
+  /// given call operator within this context.
+  unsigned getManglingNumber(const CXXMethodDecl *CallOperator);
+
+  /// \brief Retrieve the mangling number of a new block literal within this
+  /// context.
+  unsigned getManglingNumber(const BlockDecl *BD);
+
+  /// Static locals are numbered by source order.
+  unsigned getStaticLocalNumber(const VarDecl *VD);
+
+  /// \brief Retrieve the mangling number of a static local variable within
+  /// this context.
+  virtual unsigned getManglingNumber(const VarDecl *VD,
+                                     unsigned MSLocalManglingNumber) = 0;
+
+  /// \brief Retrieve the mangling number of a static local variable within
+  /// this context.
+  virtual unsigned getManglingNumber(const TagDecl *TD,
+                                     unsigned MSLocalManglingNumber) = 0;
+};
+  
+} // end namespace clang
+#endif
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
new file mode 100644
index 0000000..0b21b03
--- /dev/null
+++ b/include/clang/AST/NSAPI.h
@@ -0,0 +1,220 @@
+//===--- NSAPI.h - NSFoundation APIs ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_NSAPI_H
+#define LLVM_CLANG_AST_NSAPI_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+  class ASTContext;
+  class QualType;
+  class Expr;
+
+// \brief Provides info and caches identifiers/selectors for NSFoundation API.
+class NSAPI {
+public:
+  explicit NSAPI(ASTContext &Ctx);
+
+  ASTContext &getASTContext() const { return Ctx; }
+
+  enum NSClassIdKindKind {
+    ClassId_NSObject,
+    ClassId_NSString,
+    ClassId_NSArray,
+    ClassId_NSMutableArray,
+    ClassId_NSDictionary,
+    ClassId_NSMutableDictionary,
+    ClassId_NSNumber
+  };
+  static const unsigned NumClassIds = 7;
+
+  enum NSStringMethodKind {
+    NSStr_stringWithString,
+    NSStr_stringWithUTF8String,
+    NSStr_stringWithCStringEncoding,
+    NSStr_stringWithCString,
+    NSStr_initWithString
+  };
+  static const unsigned NumNSStringMethods = 5;
+
+  IdentifierInfo *getNSClassId(NSClassIdKindKind K) const;
+
+  /// \brief The Objective-C NSString selectors.
+  Selector getNSStringSelector(NSStringMethodKind MK) const;
+
+  /// \brief Return NSStringMethodKind if \param Sel is such a selector.
+  Optional<NSStringMethodKind> getNSStringMethodKind(Selector Sel) const;
+
+  /// \brief Returns true if the expression \param E is a reference of
+  /// "NSUTF8StringEncoding" enum constant.
+  bool isNSUTF8StringEncodingConstant(const Expr *E) const {
+    return isObjCEnumerator(E, "NSUTF8StringEncoding", NSUTF8StringEncodingId);
+  }
+
+  /// \brief Returns true if the expression \param E is a reference of
+  /// "NSASCIIStringEncoding" enum constant.
+  bool isNSASCIIStringEncodingConstant(const Expr *E) const {
+    return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId);
+  }
+
+  /// \brief Enumerates the NSArray methods used to generate literals.
+  enum NSArrayMethodKind {
+    NSArr_array,
+    NSArr_arrayWithArray,
+    NSArr_arrayWithObject,
+    NSArr_arrayWithObjects,
+    NSArr_arrayWithObjectsCount,
+    NSArr_initWithArray,
+    NSArr_initWithObjects,
+    NSArr_objectAtIndex,
+    NSMutableArr_replaceObjectAtIndex
+  };
+  static const unsigned NumNSArrayMethods = 9;
+
+  /// \brief The Objective-C NSArray selectors.
+  Selector getNSArraySelector(NSArrayMethodKind MK) const;
+
+  /// \brief Return NSArrayMethodKind if \p Sel is such a selector.
+  Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
+
+  /// \brief Enumerates the NSDictionary methods used to generate literals.
+  enum NSDictionaryMethodKind {
+    NSDict_dictionary,
+    NSDict_dictionaryWithDictionary,
+    NSDict_dictionaryWithObjectForKey,
+    NSDict_dictionaryWithObjectsForKeys,
+    NSDict_dictionaryWithObjectsForKeysCount,
+    NSDict_dictionaryWithObjectsAndKeys,
+    NSDict_initWithDictionary,
+    NSDict_initWithObjectsAndKeys,
+    NSDict_initWithObjectsForKeys,
+    NSDict_objectForKey,
+    NSMutableDict_setObjectForKey
+  };
+  static const unsigned NumNSDictionaryMethods = 11;
+
+  /// \brief The Objective-C NSDictionary selectors.
+  Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
+
+  /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector.
+  Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
+
+  /// \brief Returns selector for "objectForKeyedSubscript:".
+  Selector getObjectForKeyedSubscriptSelector() const {
+    return getOrInitSelector(StringRef("objectForKeyedSubscript"),
+                             objectForKeyedSubscriptSel);
+  }
+
+  /// \brief Returns selector for "objectAtIndexedSubscript:".
+  Selector getObjectAtIndexedSubscriptSelector() const {
+    return getOrInitSelector(StringRef("objectAtIndexedSubscript"),
+                             objectAtIndexedSubscriptSel);
+  }
+
+  /// \brief Returns selector for "setObject:forKeyedSubscript".
+  Selector getSetObjectForKeyedSubscriptSelector() const {
+    StringRef Ids[] = { "setObject", "forKeyedSubscript" };
+    return getOrInitSelector(Ids, setObjectForKeyedSubscriptSel);
+  }
+
+  /// \brief Returns selector for "setObject:atIndexedSubscript".
+  Selector getSetObjectAtIndexedSubscriptSelector() const {
+    StringRef Ids[] = { "setObject", "atIndexedSubscript" };
+    return getOrInitSelector(Ids, setObjectAtIndexedSubscriptSel);
+  }
+
+  /// \brief Returns selector for "isEqual:".
+  Selector getIsEqualSelector() const {
+    return getOrInitSelector(StringRef("isEqual"), isEqualSel);
+  }
+
+  /// \brief Enumerates the NSNumber methods used to generate literals.
+  enum NSNumberLiteralMethodKind {
+    NSNumberWithChar,
+    NSNumberWithUnsignedChar,
+    NSNumberWithShort,
+    NSNumberWithUnsignedShort,
+    NSNumberWithInt,
+    NSNumberWithUnsignedInt,
+    NSNumberWithLong,
+    NSNumberWithUnsignedLong,
+    NSNumberWithLongLong,
+    NSNumberWithUnsignedLongLong,
+    NSNumberWithFloat,
+    NSNumberWithDouble,
+    NSNumberWithBool,
+    NSNumberWithInteger,
+    NSNumberWithUnsignedInteger
+  };
+  static const unsigned NumNSNumberLiteralMethods = 15;
+
+  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
+  /// \param Instance if true it will return the selector for the init* method
+  /// otherwise it will return the selector for the number* method.
+  Selector getNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
+                                      bool Instance) const;
+
+  bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK,
+                                 Selector Sel) const {
+    return Sel == getNSNumberLiteralSelector(MK, false) ||
+           Sel == getNSNumberLiteralSelector(MK, true);
+  }
+
+  /// \brief Return NSNumberLiteralMethodKind if \p Sel is such a selector.
+  Optional<NSNumberLiteralMethodKind>
+      getNSNumberLiteralMethodKind(Selector Sel) const;
+
+  /// \brief Determine the appropriate NSNumber factory method kind for a
+  /// literal of the given type.
+  Optional<NSNumberLiteralMethodKind>
+      getNSNumberFactoryMethodKind(QualType T) const;
+
+  /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
+  bool isObjCBOOLType(QualType T) const;
+  /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
+  bool isObjCNSIntegerType(QualType T) const;
+  /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
+  bool isObjCNSUIntegerType(QualType T) const;
+
+private:
+  bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
+  bool isObjCEnumerator(const Expr *E,
+                        StringRef name, IdentifierInfo *&II) const;
+  Selector getOrInitSelector(ArrayRef<StringRef> Ids, Selector &Sel) const;
+
+  ASTContext &Ctx;
+
+  mutable IdentifierInfo *ClassIds[NumClassIds];
+
+  mutable Selector NSStringSelectors[NumNSStringMethods];
+
+  /// \brief The selectors for Objective-C NSArray methods.
+  mutable Selector NSArraySelectors[NumNSArrayMethods];
+
+  /// \brief The selectors for Objective-C NSDictionary methods.
+  mutable Selector NSDictionarySelectors[NumNSDictionaryMethods];
+
+  /// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
+  mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
+  mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
+
+  mutable Selector objectForKeyedSubscriptSel, objectAtIndexedSubscriptSel,
+                   setObjectForKeyedSubscriptSel,setObjectAtIndexedSubscriptSel,
+                   isEqualSel;
+
+  mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
+  mutable IdentifierInfo *NSASCIIStringEncodingId, *NSUTF8StringEncodingId;
+};
+
+}  // end namespace clang
+
+#endif // LLVM_CLANG_AST_NSAPI_H
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
new file mode 100644
index 0000000..fc719bd
--- /dev/null
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -0,0 +1,487 @@
+//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- 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 NestedNameSpecifier class, which represents
+//  a C++ nested-name-specifier.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+class ASTContext;
+class NamespaceAliasDecl;
+class NamespaceDecl;
+class IdentifierInfo;
+struct PrintingPolicy;
+class Type;
+class TypeLoc;
+class LangOptions;
+
+/// \brief Represents a C++ nested name specifier, such as
+/// "\::std::vector<int>::".
+///
+/// C++ nested name specifiers are the prefixes to qualified
+/// namespaces. For example, "foo::" in "foo::x" is a nested name
+/// specifier. Nested name specifiers are made up of a sequence of
+/// specifiers, each of which can be a namespace, type, identifier
+/// (for dependent names), decltype specifier, or the global specifier ('::').
+/// The last two specifiers can only appear at the start of a 
+/// nested-namespace-specifier.
+class NestedNameSpecifier : public llvm::FoldingSetNode {
+
+  /// \brief Enumeration describing
+  enum StoredSpecifierKind {
+    StoredIdentifier = 0,
+    StoredNamespaceOrAlias = 1,
+    StoredTypeSpec = 2,
+    StoredTypeSpecWithTemplate = 3
+  };
+
+  /// \brief The nested name specifier that precedes this nested name
+  /// specifier.
+  ///
+  /// The pointer is the nested-name-specifier that precedes this
+  /// one. The integer stores one of the first four values of type
+  /// SpecifierKind.
+  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
+
+  /// \brief The last component in the nested name specifier, which
+  /// can be an identifier, a declaration, or a type.
+  ///
+  /// When the pointer is NULL, this specifier represents the global
+  /// specifier '::'. Otherwise, the pointer is one of
+  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
+  /// specifier as encoded within the prefix.
+  void* Specifier;
+
+public:
+  /// \brief The kind of specifier that completes this nested name
+  /// specifier.
+  enum SpecifierKind {
+    /// \brief An identifier, stored as an IdentifierInfo*.
+    Identifier,
+    /// \brief A namespace, stored as a NamespaceDecl*.
+    Namespace,
+    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
+    NamespaceAlias,
+    /// \brief A type, stored as a Type*.
+    TypeSpec,
+    /// \brief A type that was preceded by the 'template' keyword,
+    /// stored as a Type*.
+    TypeSpecWithTemplate,
+    /// \brief The global specifier '::'. There is no stored value.
+    Global
+  };
+
+private:
+  /// \brief Builds the global specifier.
+  NestedNameSpecifier()
+    : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
+
+  /// \brief Copy constructor used internally to clone nested name
+  /// specifiers.
+  NestedNameSpecifier(const NestedNameSpecifier &Other)
+    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
+      Specifier(Other.Specifier) {
+  }
+
+  void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION;
+
+  /// \brief Either find or insert the given nested name specifier
+  /// mockup in the given context.
+  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
+                                           const NestedNameSpecifier &Mockup);
+
+public:
+  /// \brief Builds a specifier combining a prefix and an identifier.
+  ///
+  /// The prefix must be dependent, since nested name specifiers
+  /// referencing an identifier are only permitted when the identifier
+  /// cannot be resolved.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     IdentifierInfo *II);
+
+  /// \brief Builds a nested name specifier that names a namespace.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     const NamespaceDecl *NS);
+
+  /// \brief Builds a nested name specifier that names a namespace alias.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     NamespaceAliasDecl *Alias);
+
+  /// \brief Builds a nested name specifier that names a type.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     bool Template, const Type *T);
+
+  /// \brief Builds a specifier that consists of just an identifier.
+  ///
+  /// The nested-name-specifier is assumed to be dependent, but has no
+  /// prefix because the prefix is implied by something outside of the
+  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
+  /// type.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     IdentifierInfo *II);
+
+  /// \brief Returns the nested name specifier representing the global
+  /// scope.
+  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
+
+  /// \brief Return the prefix of this nested name specifier.
+  ///
+  /// The prefix contains all of the parts of the nested name
+  /// specifier that preced this current specifier. For example, for a
+  /// nested name specifier that represents "foo::bar::", the current
+  /// specifier will contain "bar::" and the prefix will contain
+  /// "foo::".
+  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
+
+  /// \brief Determine what kind of nested name specifier is stored.
+  SpecifierKind getKind() const;
+
+  /// \brief Retrieve the identifier stored in this nested name
+  /// specifier.
+  IdentifierInfo *getAsIdentifier() const {
+    if (Prefix.getInt() == StoredIdentifier)
+      return (IdentifierInfo *)Specifier;
+
+    return nullptr;
+  }
+
+  /// \brief Retrieve the namespace stored in this nested name
+  /// specifier.
+  NamespaceDecl *getAsNamespace() const;
+
+  /// \brief Retrieve the namespace alias stored in this nested name
+  /// specifier.
+  NamespaceAliasDecl *getAsNamespaceAlias() const;
+
+  /// \brief Retrieve the type stored in this nested name specifier.
+  const Type *getAsType() const {
+    if (Prefix.getInt() == StoredTypeSpec ||
+        Prefix.getInt() == StoredTypeSpecWithTemplate)
+      return (const Type *)Specifier;
+
+    return nullptr;
+  }
+
+  /// \brief Whether this nested name specifier refers to a dependent
+  /// type or not.
+  bool isDependent() const;
+
+  /// \brief Whether this nested name specifier involves a template
+  /// parameter.
+  bool isInstantiationDependent() const;
+
+  /// \brief Whether this nested-name-specifier contains an unexpanded
+  /// parameter pack (for C++11 variadic templates).
+  bool containsUnexpandedParameterPack() const;
+
+  /// \brief Print this nested name specifier to the given output
+  /// stream.
+  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(Prefix.getOpaqueValue());
+    ID.AddPointer(Specifier);
+  }
+
+  /// \brief Dump the nested name specifier to standard output to aid
+  /// in debugging.
+  void dump(const LangOptions &LO);
+};
+
+/// \brief A C++ nested-name-specifier augmented with source location
+/// information.
+class NestedNameSpecifierLoc {
+  NestedNameSpecifier *Qualifier;
+  void *Data;
+
+  /// \brief Determines the data length for the last component in the
+  /// given nested-name-specifier.
+  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
+
+  /// \brief Determines the data length for the entire
+  /// nested-name-specifier.
+  static unsigned getDataLength(NestedNameSpecifier *Qualifier);
+
+public:
+  /// \brief Construct an empty nested-name-specifier.
+  NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
+
+  /// \brief Construct a nested-name-specifier with source location information
+  /// from
+  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
+    : Qualifier(Qualifier), Data(Data) { }
+
+  /// \brief Evalutes true when this nested-name-specifier location is
+  /// non-empty.
+  LLVM_EXPLICIT operator bool() const { return Qualifier; }
+
+  /// \brief Evalutes true when this nested-name-specifier location is
+  /// empty.
+  bool hasQualifier() const { return Qualifier; }
+
+  /// \brief Retrieve the nested-name-specifier to which this instance
+  /// refers.
+  NestedNameSpecifier *getNestedNameSpecifier() const {
+    return Qualifier;
+  }
+
+  /// \brief Retrieve the opaque pointer that refers to source-location data.
+  void *getOpaqueData() const { return Data; }
+
+  /// \brief Retrieve the source range covering the entirety of this
+  /// nested-name-specifier.
+  ///
+  /// For example, if this instance refers to a nested-name-specifier
+  /// \c \::std::vector<int>::, the returned source range would cover
+  /// from the initial '::' to the last '::'.
+  SourceRange getSourceRange() const LLVM_READONLY;
+
+  /// \brief Retrieve the source range covering just the last part of
+  /// this nested-name-specifier, not including the prefix.
+  ///
+  /// For example, if this instance refers to a nested-name-specifier
+  /// \c \::std::vector<int>::, the returned source range would cover
+  /// from "vector" to the last '::'.
+  SourceRange getLocalSourceRange() const;
+
+  /// \brief Retrieve the location of the beginning of this
+  /// nested-name-specifier.
+  SourceLocation getBeginLoc() const {
+    return getSourceRange().getBegin();
+  }
+
+  /// \brief Retrieve the location of the end of this
+  /// nested-name-specifier.
+  SourceLocation getEndLoc() const {
+    return getSourceRange().getEnd();
+  }
+
+  /// \brief Retrieve the location of the beginning of this
+  /// component of the nested-name-specifier.
+  SourceLocation getLocalBeginLoc() const {
+    return getLocalSourceRange().getBegin();
+  }
+
+  /// \brief Retrieve the location of the end of this component of the
+  /// nested-name-specifier.
+  SourceLocation getLocalEndLoc() const {
+    return getLocalSourceRange().getEnd();
+  }
+
+  /// \brief Return the prefix of this nested-name-specifier.
+  ///
+  /// For example, if this instance refers to a nested-name-specifier
+  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
+  /// returned prefix may be empty, if this is the first component of
+  /// the nested-name-specifier.
+  NestedNameSpecifierLoc getPrefix() const {
+    if (!Qualifier)
+      return *this;
+
+    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
+  }
+
+  /// \brief For a nested-name-specifier that refers to a type,
+  /// retrieve the type with source-location information.
+  TypeLoc getTypeLoc() const;
+
+  /// \brief Determines the data length for the entire
+  /// nested-name-specifier.
+  unsigned getDataLength() const { return getDataLength(Qualifier); }
+
+  friend bool operator==(NestedNameSpecifierLoc X,
+                         NestedNameSpecifierLoc Y) {
+    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
+  }
+
+  friend bool operator!=(NestedNameSpecifierLoc X,
+                         NestedNameSpecifierLoc Y) {
+    return !(X == Y);
+  }
+};
+
+/// \brief Class that aids in the construction of nested-name-specifiers along
+/// with source-location information for all of the components of the
+/// nested-name-specifier.
+class NestedNameSpecifierLocBuilder {
+  /// \brief The current representation of the nested-name-specifier we're
+  /// building.
+  NestedNameSpecifier *Representation;
+
+  /// \brief Buffer used to store source-location information for the
+  /// nested-name-specifier.
+  ///
+  /// Note that we explicitly manage the buffer (rather than using a
+  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
+  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
+  char *Buffer;
+
+  /// \brief The size of the buffer used to store source-location information
+  /// for the nested-name-specifier.
+  unsigned BufferSize;
+
+  /// \brief The capacity of the buffer used to store source-location
+  /// information for the nested-name-specifier.
+  unsigned BufferCapacity;
+
+public:
+  NestedNameSpecifierLocBuilder()
+    : Representation(nullptr), Buffer(nullptr), BufferSize(0),
+      BufferCapacity(0) {}
+
+  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
+
+  NestedNameSpecifierLocBuilder &
+  operator=(const NestedNameSpecifierLocBuilder &Other);
+
+  ~NestedNameSpecifierLocBuilder() {
+    if (BufferCapacity)
+      free(Buffer);
+  }
+
+  /// \brief Retrieve the representation of the nested-name-specifier.
+  NestedNameSpecifier *getRepresentation() const { return Representation; }
+
+  /// \brief Extend the current nested-name-specifier by another
+  /// nested-name-specifier component of the form 'type::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
+  ///
+  /// \param TL The TypeLoc that describes the type preceding the '::'.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
+              SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another
+  /// nested-name-specifier component of the form 'identifier::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Identifier The identifier.
+  ///
+  /// \param IdentifierLoc The location of the identifier.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
+              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another
+  /// nested-name-specifier component of the form 'namespace::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Namespace The namespace.
+  ///
+  /// \param NamespaceLoc The location of the namespace name.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another
+  /// nested-name-specifier component of the form 'namespace-alias::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Alias The namespace alias.
+  ///
+  /// \param AliasLoc The location of the namespace alias
+  /// name.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Turn this (empty) nested-name-specifier into the global
+  /// nested-name-specifier '::'.
+  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+
+  /// \brief Make a new nested-name-specifier from incomplete source-location
+  /// information.
+  ///
+  /// This routine should be used very, very rarely, in cases where we
+  /// need to synthesize a nested-name-specifier. Most code should instead use
+  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
+  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
+                   SourceRange R);
+
+  /// \brief Adopt an existing nested-name-specifier (with source-range
+  /// information).
+  void Adopt(NestedNameSpecifierLoc Other);
+
+  /// \brief Retrieve the source range covered by this nested-name-specifier.
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
+  }
+
+  /// \brief Retrieve a nested-name-specifier with location information,
+  /// copied into the given AST context.
+  ///
+  /// \param Context The context into which this nested-name-specifier will be
+  /// copied.
+  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+
+  /// \brief Retrieve a nested-name-specifier with location
+  /// information based on the information in this builder.
+  ///
+  /// This loc will contain references to the builder's internal data and may
+  /// be invalidated by any change to the builder.
+  NestedNameSpecifierLoc getTemporary() const {
+    return NestedNameSpecifierLoc(Representation, Buffer);
+  }
+
+  /// \brief Clear out this builder, and prepare it to build another
+  /// nested-name-specifier with source-location information.
+  void Clear() {
+    Representation = nullptr;
+    BufferSize = 0;
+  }
+
+  /// \brief Retrieve the underlying buffer.
+  ///
+  /// \returns A pair containing a pointer to the buffer of source-location
+  /// data and the size of the source-location data that resides in that
+  /// buffer.
+  std::pair<char *, unsigned> getBuffer() const {
+    return std::make_pair(Buffer, BufferSize);
+  }
+};
+
+/// Insertion operator for diagnostics.  This allows sending
+/// NestedNameSpecifiers into a diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           NestedNameSpecifier *NNS) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
+                  DiagnosticsEngine::ak_nestednamespec);
+  return DB;
+}
+
+}
+
+#endif
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
new file mode 100644
index 0000000..3345959
--- /dev/null
+++ b/include/clang/AST/OpenMPClause.h
@@ -0,0 +1,1455 @@
+//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines OpenMP AST classes for clauses.
+/// There are clauses for executable directives, clauses for declarative
+/// directives and clauses which can be used in both kinds of directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
+#define LLVM_CLANG_AST_OPENMPCLAUSE_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST classes for clauses.
+//===----------------------------------------------------------------------===//
+
+/// \brief This is a basic class for representing single OpenMP clause.
+///
+class OMPClause {
+  /// \brief Starting location of the clause (the clause keyword).
+  SourceLocation StartLoc;
+  /// \brief Ending location of the clause.
+  SourceLocation EndLoc;
+  /// \brief Kind of the clause.
+  OpenMPClauseKind Kind;
+
+protected:
+  OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
+      : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
+
+public:
+  /// \brief Returns the starting location of the clause.
+  SourceLocation getLocStart() const { return StartLoc; }
+  /// \brief Returns the ending location of the clause.
+  SourceLocation getLocEnd() const { return EndLoc; }
+
+  /// \brief Sets the starting location of the clause.
+  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+  /// \brief Sets the ending location of the clause.
+  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
+
+  /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
+  OpenMPClauseKind getClauseKind() const { return Kind; }
+
+  bool isImplicit() const { return StartLoc.isInvalid(); }
+
+  StmtRange children();
+  ConstStmtRange children() const {
+    return const_cast<OMPClause *>(this)->children();
+  }
+  static bool classof(const OMPClause *T) { return true; }
+};
+
+/// \brief This represents clauses with the list of variables like 'private',
+/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
+/// '#pragma omp ...' directives.
+template <class T> class OMPVarListClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Number of variables in the list.
+  unsigned NumVars;
+
+protected:
+  /// \brief Fetches list of variables associated with this clause.
+  MutableArrayRef<Expr *> getVarRefs() {
+    return MutableArrayRef<Expr *>(
+        reinterpret_cast<Expr **>(
+            reinterpret_cast<char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+        NumVars);
+  }
+
+  /// \brief Sets the list of variables for this clause.
+  void setVarRefs(ArrayRef<Expr *> VL) {
+    assert(VL.size() == NumVars &&
+           "Number of variables is not the same as the preallocated buffer");
+    std::copy(
+        VL.begin(), VL.end(),
+        reinterpret_cast<Expr **>(
+            reinterpret_cast<char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
+  }
+
+  /// \brief Build a clause with \a N variables
+  ///
+  /// \param K Kind of the clause.
+  /// \param StartLoc Starting location of the clause (the clause keyword).
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+                   SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
+      : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
+
+public:
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+  typedef llvm::iterator_range<varlist_iterator> varlist_range;
+  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+
+  unsigned varlist_size() const { return NumVars; }
+  bool varlist_empty() const { return NumVars == 0; }
+
+  varlist_range varlists() {
+    return varlist_range(varlist_begin(), varlist_end());
+  }
+  varlist_const_range varlists() const {
+    return varlist_const_range(varlist_begin(), varlist_end());
+  }
+
+  varlist_iterator varlist_begin() { return getVarRefs().begin(); }
+  varlist_iterator varlist_end() { return getVarRefs().end(); }
+  varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
+  varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Fetches list of all variables in the clause.
+  ArrayRef<const Expr *> getVarRefs() const {
+    return ArrayRef<const Expr *>(
+        reinterpret_cast<const Expr *const *>(
+            reinterpret_cast<const char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+        NumVars);
+  }
+};
+
+/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel if(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'if'
+/// clause with condition 'a > 5'.
+///
+class OMPIfClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'if' clause.
+  Stmt *Condition;
+
+  /// \brief Set condition.
+  ///
+  void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+  /// \brief Build 'if' clause with condition \a Cond.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param Cond Condition of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+              SourceLocation EndLoc)
+      : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Condition(Cond) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPIfClause()
+      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns condition.
+  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_if;
+  }
+
+  StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task final(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp task' has simple 'final'
+/// clause with condition 'a > 5'.
+///
+class OMPFinalClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'if' clause.
+  Stmt *Condition;
+
+  /// \brief Set condition.
+  ///
+  void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+  /// \brief Build 'final' clause with condition \a Cond.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param Cond Condition of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+                 SourceLocation EndLoc)
+      : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Condition(Cond) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPFinalClause()
+      : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns condition.
+  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_final;
+  }
+
+  StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel num_threads(6)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'num_threads'
+/// clause with number of threads '6'.
+///
+class OMPNumThreadsClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'num_threads' clause.
+  Stmt *NumThreads;
+
+  /// \brief Set condition.
+  ///
+  void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+
+public:
+  /// \brief Build 'num_threads' clause with condition \a NumThreads.
+  ///
+  /// \param NumThreads Number of threads for the construct.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
+                      SourceLocation LParenLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        NumThreads(NumThreads) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPNumThreadsClause()
+      : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), NumThreads(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns number of threads.
+  Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_num_threads;
+  }
+
+  StmtRange children() { return StmtRange(&NumThreads, &NumThreads + 1); }
+};
+
+/// \brief This represents 'safelen' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd safelen(4)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'safelen'
+/// with single expression '4'.
+/// If the safelen clause is used then no two iterations executed
+/// concurrently with SIMD instructions can have a greater distance
+/// in the logical iteration space than its value. The parameter of
+/// the safelen clause must be a constant positive integer expression.
+///
+class OMPSafelenClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Safe iteration space distance.
+  Stmt *Safelen;
+
+  /// \brief Set safelen.
+  void setSafelen(Expr *Len) { Safelen = Len; }
+
+public:
+  /// \brief Build 'safelen' clause.
+  ///
+  /// \param Len Expression associated with this clause.
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc)
+      : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Safelen(Len) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPSafelenClause()
+      : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Safelen(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Return safe iteration space distance.
+  Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_safelen;
+  }
+
+  StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); }
+};
+
+/// \brief This represents 'collapse' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd collapse(3)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'collapse'
+/// with single expression '3'.
+/// The parameter must be a constant positive integer expression, it specifies
+/// the number of nested loops that should be collapsed into a single iteration
+/// space.
+///
+class OMPCollapseClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Number of for-loops.
+  Stmt *NumForLoops;
+
+  /// \brief Set the number of associated for-loops.
+  void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+
+public:
+  /// \brief Build 'collapse' clause.
+  ///
+  /// \param Num Expression associated with this clause.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+                    SourceLocation LParenLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        NumForLoops(Num) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPCollapseClause()
+      : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Return the number of associated for-loops.
+  Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_collapse;
+  }
+
+  StmtRange children() { return StmtRange(&NumForLoops, &NumForLoops + 1); }
+};
+
+/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel default(shared)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'default'
+/// clause with kind 'shared'.
+///
+class OMPDefaultClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'default' clause.
+  OpenMPDefaultClauseKind Kind;
+  /// \brief Start location of the kind in source code.
+  SourceLocation KindKwLoc;
+
+  /// \brief Set kind of the clauses.
+  ///
+  /// \param K Argument of clause.
+  ///
+  void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
+
+  /// \brief Set argument location.
+  ///
+  /// \param KLoc Argument location.
+  ///
+  void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+  /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
+  ///
+  /// \param A Argument of the clause ('none' or 'shared').
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
+                   SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc)
+      : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(A), KindKwLoc(ALoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPDefaultClause()
+      : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
+        KindKwLoc(SourceLocation()) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns kind of the clause.
+  OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
+
+  /// \brief Returns location of clause kind.
+  SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_default;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel proc_bind(master)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
+/// clause with kind 'master'.
+///
+class OMPProcBindClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'proc_bind' clause.
+  OpenMPProcBindClauseKind Kind;
+  /// \brief Start location of the kind in source code.
+  SourceLocation KindKwLoc;
+
+  /// \brief Set kind of the clause.
+  ///
+  /// \param K Kind of clause.
+  ///
+  void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
+
+  /// \brief Set clause kind location.
+  ///
+  /// \param KLoc Kind location.
+  ///
+  void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+  /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
+  ///        'spread').
+  ///
+  /// \param A Argument of the clause ('master', 'close' or 'spread').
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
+                    SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation EndLoc)
+      : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(A), KindKwLoc(ALoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPProcBindClause()
+      : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
+        KindKwLoc(SourceLocation()) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns kind of the clause.
+  OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
+
+  /// \brief Returns location of clause kind.
+  SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_proc_bind;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for schedule(static, 3)
+/// \endcode
+/// In this example directive '#pragma omp for' has 'schedule' clause with
+/// arguments 'static' and '3'.
+///
+class OMPScheduleClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'schedule' clause.
+  OpenMPScheduleClauseKind Kind;
+  /// \brief Start location of the schedule ind in source code.
+  SourceLocation KindLoc;
+  /// \brief Location of ',' (if any).
+  SourceLocation CommaLoc;
+  /// \brief Chunk size.
+  Stmt *ChunkSize;
+
+  /// \brief Set schedule kind.
+  ///
+  /// \param K Schedule kind.
+  ///
+  void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
+  /// \brief Sets the location of '('.
+  ///
+  /// \param Loc Location of '('.
+  ///
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Set schedule kind start location.
+  ///
+  /// \param KLoc Schedule kind location.
+  ///
+  void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+  /// \brief Set location of ','.
+  ///
+  /// \param Loc Location of ','.
+  ///
+  void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+  /// \brief Set chunk size.
+  ///
+  /// \param E Chunk size.
+  ///
+  void setChunkSize(Expr *E) { ChunkSize = E; }
+
+public:
+  /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
+  /// expression \a ChunkSize.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param KLoc Starting location of the argument.
+  /// \param CommaLoc Location of ','.
+  /// \param EndLoc Ending location of the clause.
+  /// \param Kind Schedule kind.
+  /// \param ChunkSize Chunk size.
+  ///
+  OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation KLoc, SourceLocation CommaLoc,
+                    SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
+                    Expr *ChunkSize)
+      : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPScheduleClause()
+      : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
+        Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {}
+
+  /// \brief Get kind of the clause.
+  ///
+  OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
+  /// \brief Get location of '('.
+  ///
+  SourceLocation getLParenLoc() { return LParenLoc; }
+  /// \brief Get kind location.
+  ///
+  SourceLocation getScheduleKindLoc() { return KindLoc; }
+  /// \brief Get location of ','.
+  ///
+  SourceLocation getCommaLoc() { return CommaLoc; }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_schedule;
+  }
+
+  StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); }
+};
+
+/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for ordered
+/// \endcode
+/// In this example directive '#pragma omp for' has 'ordered' clause.
+///
+class OMPOrderedClause : public OMPClause {
+public:
+  /// \brief Build 'ordered' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_ordered, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPOrderedClause()
+      : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_ordered;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for nowait
+/// \endcode
+/// In this example directive '#pragma omp for' has 'nowait' clause.
+///
+class OMPNowaitClause : public OMPClause {
+public:
+  /// \brief Build 'nowait' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPNowaitClause()
+      : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_nowait;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task untied
+/// \endcode
+/// In this example directive '#pragma omp task' has 'untied' clause.
+///
+class OMPUntiedClause : public OMPClause {
+public:
+  /// \brief Build 'untied' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPUntiedClause()
+      : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_untied;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task mergeable
+/// \endcode
+/// In this example directive '#pragma omp task' has 'mergeable' clause.
+///
+class OMPMergeableClause : public OMPClause {
+public:
+  /// \brief Build 'mergeable' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPMergeableClause()
+      : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_mergeable;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'private'
+/// with the variables 'a' and 'b'.
+///
+class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
+                                           EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPPrivateClause(unsigned N)
+      : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_private;
+  }
+};
+
+/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel firstprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                        SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
+                                                LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPFirstprivateClause(unsigned N)
+      : OMPVarListClause<OMPFirstprivateClause>(
+            OMPC_firstprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPFirstprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_firstprivate;
+  }
+};
+
+/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd lastprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'lastprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPLastprivateClause(unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(
+            OMPC_lastprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPLastprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_lastprivate;
+  }
+};
+
+/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel shared(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'shared'
+/// with the variables 'a' and 'b'.
+///
+class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
+                                          EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPSharedClause(unsigned N)
+      : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_shared;
+  }
+};
+
+/// \brief This represents clause 'reduction' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'reduction'
+/// with operator '+' and the variables 'a' and 'b'.
+///
+class OMPReductionClause : public OMPVarListClause<OMPReductionClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+  /// \brief Nested name specifier for C++.
+  NestedNameSpecifierLoc QualifierLoc;
+  /// \brief Name of custom operator.
+  DeclarationNameInfo NameInfo;
+
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param ColonLoc Location of ':'.
+  /// \param N Number of the variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                     SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
+                     NestedNameSpecifierLoc QualifierLoc,
+                     const DeclarationNameInfo &NameInfo)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
+                                             LParenLoc, EndLoc, N),
+        ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPReductionClause(unsigned N)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
+                                             SourceLocation(), SourceLocation(),
+                                             N),
+        ColonLoc(), QualifierLoc(), NameInfo() {}
+
+  /// \brief Sets location of ':' symbol in clause.
+  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+  /// \brief Sets the name info for specified reduction identifier.
+  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+  /// \brief Sets the nested name specifier.
+  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL The variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  static OMPReductionClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+         NestedNameSpecifierLoc QualifierLoc,
+         const DeclarationNameInfo &NameInfo);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  /// \brief Gets location of ':' symbol in clause.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  /// \brief Gets the name info for specified reduction identifier.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+  /// \brief Gets the nested name specifier.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_reduction;
+  }
+};
+
+/// \brief This represents clause 'linear' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd linear(a,b : 2)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'linear'
+/// with variables 'a', 'b' and linear step '2'.
+///
+class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the linear step for clause.
+  void setStep(Expr *Step) { *varlist_end() = Step; }
+
+  /// \brief Build 'linear' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation ColonLoc, SourceLocation EndLoc,
+                  unsigned NumVars)
+      : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
+                                          EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPLinearClause(unsigned NumVars)
+      : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and a linear step
+  /// \a Step.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param Step Linear step.
+  static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation ColonLoc, SourceLocation EndLoc,
+                                 ArrayRef<Expr *> VL, Expr *Step);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns linear step.
+  Expr *getStep() { return *varlist_end(); }
+  /// \brief Returns linear step.
+  const Expr *getStep() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_linear;
+  }
+};
+
+/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd aligned(a,b : 8)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'aligned'
+/// with variables 'a', 'b' and alignment '8'.
+///
+class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the alignment for clause.
+  void setAlignment(Expr *A) { *varlist_end() = A; }
+
+  /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation ColonLoc, SourceLocation EndLoc,
+                   unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
+                                           EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPAlignedClause(unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param A Alignment.
+  static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation ColonLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
+                                  Expr *A);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of ':'.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns alignment.
+  Expr *getAlignment() { return *varlist_end(); }
+  /// \brief Returns alignment.
+  const Expr *getAlignment() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_aligned;
+  }
+};
+
+/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel copyin(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'copyin'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
+                                          EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPCopyinClause(unsigned N)
+      : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_copyin;
+  }
+};
+
+/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp single copyprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp single' has clause 'copyprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPCopyprivateClause(unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(
+            OMPC_copyprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPCopyprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_copyprivate;
+  }
+};
+
+/// \brief This represents pseudo clause 'flush' for the '#pragma omp flush'
+/// directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has pseudo clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                 SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+                                         EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPFlushClause(unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+                                         SourceLocation(), SourceLocation(),
+                                         N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                SourceLocation LParenLoc, SourceLocation EndLoc,
+                                ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_flush;
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
new file mode 100644
index 0000000..aba88d6
--- /dev/null
+++ b/include/clang/AST/OperationKinds.h
@@ -0,0 +1,355 @@
+//===- OperationKinds.h - Operation enums -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates the different kinds of operations that can be
+// performed by various expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPERATION_KINDS_H
+#define LLVM_CLANG_AST_OPERATION_KINDS_H
+
+namespace clang {
+  
+/// CastKind - The kind of operation required for a conversion.
+enum CastKind {
+  /// CK_Dependent - A conversion which cannot yet be analyzed because
+  /// either the expression or target type is dependent.  These are
+  /// created only for explicit casts; dependent ASTs aren't required
+  /// to even approximately type-check.
+  ///   (T*) malloc(sizeof(T))
+  ///   reinterpret_cast<intptr_t>(A<T>::alloc());
+  CK_Dependent,
+
+  /// CK_BitCast - A conversion which causes a bit pattern of one type
+  /// to be reinterpreted as a bit pattern of another type.  Generally
+  /// the operands must have equivalent size and unrelated types.
+  ///
+  /// The pointer conversion char* -> int* is a bitcast.  A conversion
+  /// from any pointer type to a C pointer type is a bitcast unless
+  /// it's actually BaseToDerived or DerivedToBase.  A conversion to a
+  /// block pointer or ObjC pointer type is a bitcast only if the
+  /// operand has the same type kind; otherwise, it's one of the
+  /// specialized casts below.
+  ///
+  /// Vector coercions are bitcasts.
+  CK_BitCast,
+
+  /// CK_LValueBitCast - A conversion which reinterprets the address of
+  /// an l-value as an l-value of a different kind.  Used for
+  /// reinterpret_casts of l-value expressions to reference types.
+  ///    bool b; reinterpret_cast<char&>(b) = 'a';
+  CK_LValueBitCast,
+  
+  /// CK_LValueToRValue - A conversion which causes the extraction of
+  /// an r-value from the operand gl-value.  The result of an r-value
+  /// conversion is always unqualified.
+  CK_LValueToRValue,
+
+  /// CK_NoOp - A conversion which does not affect the type other than
+  /// (possibly) adding qualifiers.
+  ///   int    -> int
+  ///   char** -> const char * const *
+  CK_NoOp,
+
+  /// CK_BaseToDerived - A conversion from a C++ class pointer/reference
+  /// to a derived class pointer/reference.
+  ///   B *b = static_cast<B*>(a);
+  CK_BaseToDerived,
+
+  /// CK_DerivedToBase - A conversion from a C++ class pointer
+  /// to a base class pointer.
+  ///   A *a = new B();
+  CK_DerivedToBase,
+
+  /// CK_UncheckedDerivedToBase - A conversion from a C++ class
+  /// pointer/reference to a base class that can assume that the
+  /// derived pointer is not null.
+  ///   const A &a = B();
+  ///   b->method_from_a();
+  CK_UncheckedDerivedToBase,
+
+  /// CK_Dynamic - A C++ dynamic_cast.
+  CK_Dynamic,
+
+  /// CK_ToUnion - The GCC cast-to-union extension.
+  ///   int   -> union { int x; float y; }
+  ///   float -> union { int x; float y; }
+  CK_ToUnion,
+
+  /// CK_ArrayToPointerDecay - Array to pointer decay.
+  ///   int[10] -> int*
+  ///   char[5][6] -> char(*)[6]
+  CK_ArrayToPointerDecay,
+
+  /// CK_FunctionToPointerDecay - Function to pointer decay.
+  ///   void(int) -> void(*)(int)
+  CK_FunctionToPointerDecay,
+
+  /// CK_NullToPointer - Null pointer constant to pointer, ObjC
+  /// pointer, or block pointer.
+  ///   (void*) 0
+  ///   void (^block)() = 0;
+  CK_NullToPointer,
+
+  /// CK_NullToMemberPointer - Null pointer constant to member pointer.
+  ///   int A::*mptr = 0;
+  ///   int (A::*fptr)(int) = nullptr;
+  CK_NullToMemberPointer,
+
+  /// CK_BaseToDerivedMemberPointer - Member pointer in base class to
+  /// member pointer in derived class.
+  ///   int B::*mptr = &A::member;
+  CK_BaseToDerivedMemberPointer,
+
+  /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to
+  /// member pointer in base class.
+  ///   int A::*mptr = static_cast<int A::*>(&B::member);
+  CK_DerivedToBaseMemberPointer,
+    
+  /// CK_MemberPointerToBoolean - Member pointer to boolean.  A check
+  /// against the null member pointer.
+  CK_MemberPointerToBoolean,
+
+  /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a
+  /// different kind of member pointer.  C++ forbids this from
+  /// crossing between function and object types, but otherwise does
+  /// not restrict it.  However, the only operation that is permitted
+  /// on a "punned" member pointer is casting it back to the original
+  /// type, which is required to be a lossless operation (although
+  /// many ABIs do not guarantee this on all possible intermediate types).
+  CK_ReinterpretMemberPointer,
+
+  /// CK_UserDefinedConversion - Conversion using a user defined type
+  /// conversion function.
+  ///    struct A { operator int(); }; int i = int(A());
+  CK_UserDefinedConversion,
+
+  /// CK_ConstructorConversion - Conversion by constructor.
+  ///    struct A { A(int); }; A a = A(10);
+  CK_ConstructorConversion,
+    
+  /// CK_IntegralToPointer - Integral to pointer.  A special kind of
+  /// reinterpreting conversion.  Applies to normal, ObjC, and block
+  /// pointers.
+  ///    (char*) 0x1001aab0
+  ///    reinterpret_cast<int*>(0)
+  CK_IntegralToPointer,
+    
+  /// CK_PointerToIntegral - Pointer to integral.  A special kind of
+  /// reinterpreting conversion.  Applies to normal, ObjC, and block
+  /// pointers.
+  ///    (intptr_t) "help!"
+  CK_PointerToIntegral,
+
+  /// CK_PointerToBoolean - Pointer to boolean conversion.  A check
+  /// against null.  Applies to normal, ObjC, and block pointers.
+  CK_PointerToBoolean,
+    
+  /// CK_ToVoid - Cast to void, discarding the computed value.
+  ///    (void) malloc(2048)
+  CK_ToVoid,
+    
+  /// CK_VectorSplat - A conversion from an arithmetic type to a
+  /// vector of that element type.  Fills all elements ("splats") with
+  /// the source value.
+  ///    __attribute__((ext_vector_type(4))) int v = 5;
+  CK_VectorSplat,
+    
+  /// CK_IntegralCast - A cast between integral types (other than to
+  /// boolean).  Variously a bitcast, a truncation, a sign-extension,
+  /// or a zero-extension.
+  ///    long l = 5;
+  ///    (unsigned) i
+  CK_IntegralCast,
+
+  /// CK_IntegralToBoolean - Integral to boolean.  A check against zero.
+  ///    (bool) i
+  CK_IntegralToBoolean,
+
+  /// CK_IntegralToFloating - Integral to floating point.
+  ///    float f = i;
+  CK_IntegralToFloating,
+    
+  /// CK_FloatingToIntegral - Floating point to integral.  Rounds
+  /// towards zero, discarding any fractional component.
+  ///    (int) f
+  CK_FloatingToIntegral,
+
+  /// CK_FloatingToBoolean - Floating point to boolean.
+  ///    (bool) f
+  CK_FloatingToBoolean,
+    
+  /// CK_FloatingCast - Casting between floating types of different size.
+  ///    (double) f
+  ///    (float) ld
+  CK_FloatingCast,
+    
+  /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an
+  /// Objective-C pointer.
+  CK_CPointerToObjCPointerCast,
+
+  /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an
+  /// ObjC pointer.
+  CK_BlockPointerToObjCPointerCast,
+
+  /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer
+  /// to a block pointer.  Block-to-block casts are bitcasts.
+  CK_AnyPointerToBlockPointerCast,
+
+  /// \brief Converting between two Objective-C object types, which
+  /// can occur when performing reference binding to an Objective-C
+  /// object.
+  CK_ObjCObjectLValueCast,
+
+  /// \brief A conversion of a floating point real to a floating point
+  /// complex of the original type.  Injects the value as the real
+  /// component with a zero imaginary component.
+  ///   float -> _Complex float
+  CK_FloatingRealToComplex,
+
+  /// \brief Converts a floating point complex to floating point real
+  /// of the source's element type.  Just discards the imaginary
+  /// component.
+  ///   _Complex long double -> long double
+  CK_FloatingComplexToReal,
+
+  /// \brief Converts a floating point complex to bool by comparing
+  /// against 0+0i.
+  CK_FloatingComplexToBoolean,
+
+  /// \brief Converts between different floating point complex types.
+  ///   _Complex float -> _Complex double
+  CK_FloatingComplexCast,
+
+  /// \brief Converts from a floating complex to an integral complex.
+  ///   _Complex float -> _Complex int
+  CK_FloatingComplexToIntegralComplex,
+
+  /// \brief Converts from an integral real to an integral complex
+  /// whose element type matches the source.  Injects the value as
+  /// the real component with a zero imaginary component.
+  ///   long -> _Complex long
+  CK_IntegralRealToComplex,
+
+  /// \brief Converts an integral complex to an integral real of the
+  /// source's element type by discarding the imaginary component.
+  ///   _Complex short -> short
+  CK_IntegralComplexToReal,
+
+  /// \brief Converts an integral complex to bool by comparing against
+  /// 0+0i.
+  CK_IntegralComplexToBoolean,
+
+  /// \brief Converts between different integral complex types.
+  ///   _Complex char -> _Complex long long
+  ///   _Complex unsigned int -> _Complex signed int
+  CK_IntegralComplexCast,
+
+  /// \brief Converts from an integral complex to a floating complex.
+  ///   _Complex unsigned -> _Complex float
+  CK_IntegralComplexToFloatingComplex,
+
+  /// \brief [ARC] Produces a retainable object pointer so that it may
+  /// be consumed, e.g. by being passed to a consuming parameter.
+  /// Calls objc_retain.
+  CK_ARCProduceObject,
+
+  /// \brief [ARC] Consumes a retainable object pointer that has just
+  /// been produced, e.g. as the return value of a retaining call.
+  /// Enters a cleanup to call objc_release at some indefinite time.
+  CK_ARCConsumeObject,
+
+  /// \brief [ARC] Reclaim a retainable object pointer object that may
+  /// have been produced and autoreleased as part of a function return
+  /// sequence.
+  CK_ARCReclaimReturnedObject,
+
+  /// \brief [ARC] Causes a value of block type to be copied to the
+  /// heap, if it is not already there.  A number of other operations
+  /// in ARC cause blocks to be copied; this is for cases where that
+  /// would not otherwise be guaranteed, such as when casting to a
+  /// non-block pointer type.
+  CK_ARCExtendBlockObject,
+
+  /// \brief Converts from _Atomic(T) to T.
+  CK_AtomicToNonAtomic,
+  /// \brief Converts from T to _Atomic(T).
+  CK_NonAtomicToAtomic,
+  
+  /// \brief Causes a block literal to by copied to the heap and then 
+  /// autoreleased.
+  ///
+  /// This particular cast kind is used for the conversion from a C++11
+  /// lambda expression to a block pointer.
+  CK_CopyAndAutoreleaseBlockObject,
+
+  // Convert a builtin function to a function pointer; only allowed in the
+  // callee of a call expression.
+  CK_BuiltinFnToFnPtr,
+
+  // Convert a zero value for OpenCL event_t initialization.
+  CK_ZeroToOCLEvent,
+
+  // Convert a pointer to a different address space.
+  CK_AddressSpaceConversion
+};
+
+static const CastKind CK_Invalid = static_cast<CastKind>(-1);
+
+enum BinaryOperatorKind {
+  // Operators listed in order of precedence.
+  // Note that additions to this should also update the StmtVisitor class.
+  BO_PtrMemD, BO_PtrMemI,       // [C++ 5.5] Pointer-to-member operators.
+  BO_Mul, BO_Div, BO_Rem,       // [C99 6.5.5] Multiplicative operators.
+  BO_Add, BO_Sub,               // [C99 6.5.6] Additive operators.
+  BO_Shl, BO_Shr,               // [C99 6.5.7] Bitwise shift operators.
+  BO_LT, BO_GT, BO_LE, BO_GE,   // [C99 6.5.8] Relational operators.
+  BO_EQ, BO_NE,                 // [C99 6.5.9] Equality operators.
+  BO_And,                       // [C99 6.5.10] Bitwise AND operator.
+  BO_Xor,                       // [C99 6.5.11] Bitwise XOR operator.
+  BO_Or,                        // [C99 6.5.12] Bitwise OR operator.
+  BO_LAnd,                      // [C99 6.5.13] Logical AND operator.
+  BO_LOr,                       // [C99 6.5.14] Logical OR operator.
+  BO_Assign, BO_MulAssign,      // [C99 6.5.16] Assignment operators.
+  BO_DivAssign, BO_RemAssign,
+  BO_AddAssign, BO_SubAssign,
+  BO_ShlAssign, BO_ShrAssign,
+  BO_AndAssign, BO_XorAssign,
+  BO_OrAssign,
+  BO_Comma                      // [C99 6.5.17] Comma operator.
+};
+
+enum UnaryOperatorKind {
+  // Note that additions to this should also update the StmtVisitor class.
+  UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
+  UO_PreInc, UO_PreDec,   // [C99 6.5.3.1] Prefix increment and decrement
+  UO_AddrOf, UO_Deref,    // [C99 6.5.3.2] Address and indirection
+  UO_Plus, UO_Minus,      // [C99 6.5.3.3] Unary arithmetic
+  UO_Not, UO_LNot,        // [C99 6.5.3.3] Unary arithmetic
+  UO_Real, UO_Imag,       // "__real expr"/"__imag expr" Extension.
+  UO_Extension            // __extension__ marker.
+};
+
+/// \brief The kind of bridging performed by the Objective-C bridge cast.
+enum ObjCBridgeCastKind {
+  /// \brief Bridging via __bridge, which does nothing but reinterpret
+  /// the bits.
+  OBC_Bridge,
+  /// \brief Bridging via __bridge_transfer, which transfers ownership of an
+  /// Objective-C pointer into ARC.
+  OBC_BridgeTransfer,
+  /// \brief Bridging via __bridge_retain, which makes an ARC object available
+  /// as a +1 C pointer.
+  OBC_BridgeRetained
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
new file mode 100644
index 0000000..eece851
--- /dev/null
+++ b/include/clang/AST/ParentMap.h
@@ -0,0 +1,67 @@
+//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- 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 ParentMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARENTMAP_H
+#define LLVM_CLANG_PARENTMAP_H
+
+namespace clang {
+class Stmt;
+class Expr;
+
+class ParentMap {
+  void* Impl;
+public:
+  ParentMap(Stmt* ASTRoot);
+  ~ParentMap();
+
+  /// \brief Adds and/or updates the parent/child-relations of the complete
+  /// stmt tree of S. All children of S including indirect descendants are
+  /// visited and updated or inserted but not the parents of S.
+  void addStmt(Stmt* S);
+
+  /// Manually sets the parent of \p S to \p Parent.
+  ///
+  /// If \p S is already in the map, this method will update the mapping.
+  void setParent(const Stmt *S, const Stmt *Parent);
+
+  Stmt *getParent(Stmt*) const;
+  Stmt *getParentIgnoreParens(Stmt *) const;
+  Stmt *getParentIgnoreParenCasts(Stmt *) const;
+  Stmt *getParentIgnoreParenImpCasts(Stmt *) const;
+  Stmt *getOuterParenParent(Stmt *) const;
+
+  const Stmt *getParent(const Stmt* S) const {
+    return getParent(const_cast<Stmt*>(S));
+  }
+
+  const Stmt *getParentIgnoreParens(const Stmt *S) const {
+    return getParentIgnoreParens(const_cast<Stmt*>(S));
+  }
+
+  const Stmt *getParentIgnoreParenCasts(const Stmt *S) const {
+    return getParentIgnoreParenCasts(const_cast<Stmt*>(S));
+  }
+
+  bool hasParent(Stmt* S) const {
+    return getParent(S) != nullptr;
+  }
+
+  bool isConsumedExpr(Expr *E) const;
+
+  bool isConsumedExpr(const Expr *E) const {
+    return isConsumedExpr(const_cast<Expr*>(E));
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
new file mode 100644
index 0000000..349f4c4
--- /dev/null
+++ b/include/clang/AST/PrettyPrinter.h
@@ -0,0 +1,170 @@
+//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- 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 PrinterHelper interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H
+#define LLVM_CLANG_AST_PRETTY_PRINTER_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class LangOptions;
+class SourceManager;
+class Stmt;
+class TagDecl;
+
+class PrinterHelper {
+public:
+  virtual ~PrinterHelper();
+  virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0;
+};
+
+/// \brief Describes how types, statements, expressions, and
+/// declarations should be printed.
+struct PrintingPolicy {
+  /// \brief Create a default printing policy for C.
+  PrintingPolicy(const LangOptions &LO)
+    : LangOpts(LO), Indentation(2), SuppressSpecifiers(false),
+      SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
+      SuppressUnwrittenScope(false), SuppressInitializers(false),
+      ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
+      SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
+      Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
+      Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
+      IncludeNewlines(true) { }
+
+  /// \brief What language we're printing.
+  LangOptions LangOpts;
+
+  /// \brief The number of spaces to use to indent each line.
+  unsigned Indentation : 8;
+
+  /// \brief Whether we should suppress printing of the actual specifiers for
+  /// the given type or declaration.
+  ///
+  /// This flag is only used when we are printing declarators beyond
+  /// the first declarator within a declaration group. For example, given:
+  ///
+  /// \code
+  /// const int *x, *y;
+  /// \endcode
+  ///
+  /// SuppressSpecifiers will be false when printing the
+  /// declaration for "x", so that we will print "int *x"; it will be
+  /// \c true when we print "y", so that we suppress printing the
+  /// "const int" type specifier and instead only print the "*y".
+  bool SuppressSpecifiers : 1;
+
+  /// \brief Whether type printing should skip printing the tag keyword.
+  ///
+  /// This is used when printing the inner type of elaborated types,
+  /// (as the tag keyword is part of the elaborated type):
+  ///
+  /// \code
+  /// struct Geometry::Point;
+  /// \endcode
+  bool SuppressTagKeyword : 1;
+
+  /// \brief Whether type printing should skip printing the actual tag type.
+  ///
+  /// This is used when the caller needs to print a tag definition in front
+  /// of the type, as in constructs like the following:
+  ///
+  /// \code
+  /// typedef struct { int x, y; } Point;
+  /// \endcode
+  bool SuppressTag : 1;
+
+  /// \brief Suppresses printing of scope specifiers.
+  bool SuppressScope : 1;
+
+  /// \brief Suppress printing parts of scope specifiers that don't need
+  /// to be written, e.g., for inline or anonymous namespaces.
+  bool SuppressUnwrittenScope : 1;
+  
+  /// \brief Suppress printing of variable initializers.
+  ///
+  /// This flag is used when printing the loop variable in a for-range
+  /// statement. For example, given:
+  ///
+  /// \code
+  /// for (auto x : coll)
+  /// \endcode
+  ///
+  /// SuppressInitializers will be true when printing "auto x", so that the
+  /// internal initializer constructed for x will not be printed.
+  bool SuppressInitializers : 1;
+
+  /// \brief Whether we should print the sizes of constant array expressions
+  /// as written in the sources.
+  ///
+  /// This flag is determines whether arrays types declared as
+  ///
+  /// \code
+  /// int a[4+10*10];
+  /// char a[] = "A string";
+  /// \endcode
+  ///
+  /// will be printed as written or as follows:
+  ///
+  /// \code
+  /// int a[104];
+  /// char a[9] = "A string";
+  /// \endcode
+  bool ConstantArraySizeAsWritten : 1;
+  
+  /// \brief When printing an anonymous tag name, also print the location of
+  /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just 
+  /// prints "(anonymous)" for the name.
+  bool AnonymousTagLocations : 1;
+  
+  /// \brief When true, suppress printing of the __strong lifetime qualifier in
+  /// ARC.
+  unsigned SuppressStrongLifetime : 1;
+  
+  /// \brief When true, suppress printing of lifetime qualifier in
+  /// ARC.
+  unsigned SuppressLifetimeQualifiers : 1;
+  
+  /// \brief Whether we can use 'bool' rather than '_Bool', even if the language
+  /// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
+  unsigned Bool : 1;
+
+  /// \brief Provide a 'terse' output.
+  ///
+  /// For example, in this mode we don't print function bodies, class members,
+  /// declarations inside namespaces etc.  Effectively, this should print
+  /// only the requested declaration.
+  unsigned TerseOutput : 1;
+  
+  /// \brief When true, do certain refinement needed for producing proper
+  /// declaration tag; such as, do not print attributes attached to the declaration.
+  ///
+  unsigned PolishForDeclaration : 1;
+
+  /// \brief When true, print the half-precision floating-point type as 'half'
+  /// instead of '__fp16'
+  unsigned Half : 1;
+
+  /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
+  /// Microsoft mode when wchar_t is not available.
+  unsigned MSWChar : 1;
+
+  /// \brief When true, include newlines after statements like "break", etc.
+  unsigned IncludeNewlines : 1;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
new file mode 100644
index 0000000..8ba85c4
--- /dev/null
+++ b/include/clang/AST/RawCommentList.h
@@ -0,0 +1,203 @@
+//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
+#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
+
+#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+
+class ASTContext;
+class ASTReader;
+class Decl;
+class Preprocessor;
+
+namespace comments {
+  class FullComment;
+} // end namespace comments
+
+class RawComment {
+public:
+  enum CommentKind {
+    RCK_Invalid,      ///< Invalid comment
+    RCK_OrdinaryBCPL, ///< Any normal BCPL comments
+    RCK_OrdinaryC,    ///< Any normal C comment
+    RCK_BCPLSlash,    ///< \code /// stuff \endcode
+    RCK_BCPLExcl,     ///< \code //! stuff \endcode
+    RCK_JavaDoc,      ///< \code /** stuff */ \endcode
+    RCK_Qt,           ///< \code /*! stuff */ \endcode, also used by HeaderDoc
+    RCK_Merged        ///< Two or more documentation comments merged together
+  };
+
+  RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
+
+  RawComment(const SourceManager &SourceMgr, SourceRange SR,
+             bool Merged, bool ParseAllComments);
+
+  CommentKind getKind() const LLVM_READONLY {
+    return (CommentKind) Kind;
+  }
+
+  bool isInvalid() const LLVM_READONLY {
+    return Kind == RCK_Invalid;
+  }
+
+  bool isMerged() const LLVM_READONLY {
+    return Kind == RCK_Merged;
+  }
+
+  /// Is this comment attached to any declaration?
+  bool isAttached() const LLVM_READONLY {
+    return IsAttached;
+  }
+
+  void setAttached() {
+    IsAttached = true;
+  }
+
+  /// Returns true if it is a comment that should be put after a member:
+  /// \code ///< stuff \endcode
+  /// \code //!< stuff \endcode
+  /// \code /**< stuff */ \endcode
+  /// \code /*!< stuff */ \endcode
+  bool isTrailingComment() const LLVM_READONLY {
+    assert(isDocumentation());
+    return IsTrailingComment;
+  }
+
+  /// Returns true if it is a probable typo:
+  /// \code //< stuff \endcode
+  /// \code /*< stuff */ \endcode
+  bool isAlmostTrailingComment() const LLVM_READONLY {
+    return IsAlmostTrailingComment;
+  }
+
+  /// Returns true if this comment is not a documentation comment.
+  bool isOrdinary() const LLVM_READONLY {
+    return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
+        !ParseAllComments;
+  }
+
+  /// Returns true if this comment any kind of a documentation comment.
+  bool isDocumentation() const LLVM_READONLY {
+    return !isInvalid() && !isOrdinary();
+  }
+
+  /// Returns whether we are parsing all comments.
+  bool isParseAllComments() const LLVM_READONLY {
+    return ParseAllComments;
+  }
+
+  /// Returns raw comment text with comment markers.
+  StringRef getRawText(const SourceManager &SourceMgr) const {
+    if (RawTextValid)
+      return RawText;
+
+    RawText = getRawTextSlow(SourceMgr);
+    RawTextValid = true;
+    return RawText;
+  }
+
+  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
+  const char *getBriefText(const ASTContext &Context) const {
+    if (BriefTextValid)
+      return BriefText;
+
+    return extractBriefText(Context);
+  }
+
+  /// Parse the comment, assuming it is attached to decl \c D.
+  comments::FullComment *parse(const ASTContext &Context,
+                               const Preprocessor *PP, const Decl *D) const;
+
+private:
+  SourceRange Range;
+
+  mutable StringRef RawText;
+  mutable const char *BriefText;
+
+  mutable bool RawTextValid : 1;   ///< True if RawText is valid
+  mutable bool BriefTextValid : 1; ///< True if BriefText is valid
+
+  unsigned Kind : 3;
+
+  /// True if comment is attached to a declaration in ASTContext.
+  bool IsAttached : 1;
+
+  bool IsTrailingComment : 1;
+  bool IsAlmostTrailingComment : 1;
+
+  /// When true, ordinary comments starting with "//" and "/*" will be
+  /// considered as documentation comments.
+  bool ParseAllComments : 1;
+
+  /// \brief Constructor for AST deserialization.
+  RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
+             bool IsAlmostTrailingComment,
+             bool ParseAllComments) :
+    Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
+    IsAttached(false), IsTrailingComment(IsTrailingComment),
+    IsAlmostTrailingComment(IsAlmostTrailingComment),
+    ParseAllComments(ParseAllComments)
+  { }
+
+  StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
+
+  const char *extractBriefText(const ASTContext &Context) const;
+
+  friend class ASTReader;
+};
+
+/// \brief Compare comments' source locations.
+template<>
+class BeforeThanCompare<RawComment> {
+  const SourceManager &SM;
+
+public:
+  explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
+
+  bool operator()(const RawComment &LHS, const RawComment &RHS) {
+    return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
+  }
+
+  bool operator()(const RawComment *LHS, const RawComment *RHS) {
+    return operator()(*LHS, *RHS);
+  }
+};
+
+/// \brief This class represents all comments included in the translation unit,
+/// sorted in order of appearance in the translation unit.
+class RawCommentList {
+public:
+  RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
+
+  void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
+
+  ArrayRef<RawComment *> getComments() const {
+    return Comments;
+  }
+
+private:
+  SourceManager &SourceMgr;
+  std::vector<RawComment *> Comments;
+
+  void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
+
+  friend class ASTReader;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
new file mode 100644
index 0000000..4befb45
--- /dev/null
+++ b/include/clang/AST/RecordLayout.h
@@ -0,0 +1,315 @@
+//===--- RecordLayout.h - Layout information for a struct/union -*- 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 RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
+#define LLVM_CLANG_AST_LAYOUTINFO_H
+
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+  class ASTContext;
+  class FieldDecl;
+  class RecordDecl;
+  class CXXRecordDecl;
+
+/// ASTRecordLayout -
+/// This class contains layout information for one RecordDecl,
+/// which is a struct/union/class.  The decl represented must be a definition,
+/// not a forward declaration.
+/// This class is also used to contain layout information for one
+/// ObjCInterfaceDecl. FIXME - Find appropriate name.
+/// These objects are managed by ASTContext.
+class ASTRecordLayout {
+public:
+  struct VBaseInfo {
+    /// The offset to this virtual base in the complete-object layout
+    /// of this class.
+    CharUnits VBaseOffset;
+
+  private:
+    /// Whether this virtual base requires a vtordisp field in the
+    /// Microsoft ABI.  These fields are required for certain operations
+    /// in constructors and destructors.
+    bool HasVtorDisp;
+
+  public:
+    bool hasVtorDisp() const { return HasVtorDisp; }
+
+    VBaseInfo() : HasVtorDisp(false) {}
+
+    VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
+     VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
+  };
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
+    VBaseOffsetsMapTy;
+
+private:
+  /// Size - Size of record in characters.
+  CharUnits Size;
+
+  /// DataSize - Size of record in characters without tail padding.
+  CharUnits DataSize;
+
+  // Alignment - Alignment of record in characters.
+  CharUnits Alignment;
+
+  /// RequiredAlignment - The required alignment of the object.  In the MS-ABI
+  /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
+  CharUnits RequiredAlignment;
+
+  /// FieldOffsets - Array of field offsets in bits.
+  uint64_t *FieldOffsets;
+
+  // FieldCount - Number of fields.
+  unsigned FieldCount;
+
+  /// CXXRecordLayoutInfo - Contains C++ specific layout information.
+  struct CXXRecordLayoutInfo {
+    /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
+    /// the size of the object without virtual bases.
+    CharUnits NonVirtualSize;
+
+    /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
+    /// which is the alignment of the object without virtual bases.
+    CharUnits NonVirtualAlignment;
+
+    /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
+    /// (either a base or a member). Will be zero if the class doesn't contain
+    /// any empty subobjects.
+    CharUnits SizeOfLargestEmptySubobject;
+
+    /// VBPtrOffset - Virtual base table offset (Microsoft-only).
+    CharUnits VBPtrOffset;
+
+    /// HasOwnVFPtr - Does this class provide a virtual function table
+    /// (vtable in Itanium, vftbl in Microsoft) that is independent from
+    /// its base classes?
+    bool HasOwnVFPtr : 1;
+
+    /// HasVFPtr - Does this class have a vftable that could be extended by
+    /// a derived class.  The class may have inherited this pointer from
+    /// a primary base class.
+    bool HasExtendableVFPtr : 1;
+
+    /// HasZeroSizedSubObject - True if this class contains a zero sized member
+    /// or base or a base with a zero sized member or base.  Only used for
+    /// MS-ABI.
+    bool HasZeroSizedSubObject : 1;
+
+    /// \brief True if this class is zero sized or first base is zero sized or
+    /// has this property.  Only used for MS-ABI.
+    bool LeadsWithZeroSizedBase : 1;
+
+    /// PrimaryBase - The primary base info for this record.
+    llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
+
+    /// BaseSharingVBPtr - The base we share vbptr with.
+    const CXXRecordDecl *BaseSharingVBPtr;
+    
+    /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+    typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
+    
+    /// BaseOffsets - Contains a map from base classes to their offset.
+    BaseOffsetsMapTy BaseOffsets;
+
+    /// VBaseOffsets - Contains a map from vbase classes to their offset.
+    VBaseOffsetsMapTy VBaseOffsets;
+  };
+
+  /// CXXInfo - If the record layout is for a C++ record, this will have
+  /// C++ specific information about the record.
+  CXXRecordLayoutInfo *CXXInfo;
+
+  friend class ASTContext;
+
+  ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
+                  CharUnits requiredAlignment,
+                  CharUnits datasize, const uint64_t *fieldoffsets,
+                  unsigned fieldcount);
+
+  // Constructor for C++ records.
+  typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
+  ASTRecordLayout(const ASTContext &Ctx,
+                  CharUnits size, CharUnits alignment,
+                  CharUnits requiredAlignment,
+                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
+                  CharUnits vbptroffset,
+                  CharUnits datasize,
+                  const uint64_t *fieldoffsets, unsigned fieldcount,
+                  CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
+                  CharUnits SizeOfLargestEmptySubobject,
+                  const CXXRecordDecl *PrimaryBase,
+                  bool IsPrimaryBaseVirtual,
+                  const CXXRecordDecl *BaseSharingVBPtr,
+                  bool HasZeroSizedSubObject,
+                  bool LeadsWithZeroSizedBase,
+                  const BaseOffsetsMapTy& BaseOffsets,
+                  const VBaseOffsetsMapTy& VBaseOffsets);
+
+  ~ASTRecordLayout() {}
+
+  void Destroy(ASTContext &Ctx);
+  
+  ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
+  void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
+public:
+
+  /// getAlignment - Get the record alignment in characters.
+  CharUnits getAlignment() const { return Alignment; }
+
+  /// getSize - Get the record size in characters.
+  CharUnits getSize() const { return Size; }
+
+  /// getFieldCount - Get the number of fields in the layout.
+  unsigned getFieldCount() const { return FieldCount; }
+
+  /// getFieldOffset - Get the offset of the given field index, in
+  /// bits.
+  uint64_t getFieldOffset(unsigned FieldNo) const {
+    assert (FieldNo < FieldCount && "Invalid Field No");
+    return FieldOffsets[FieldNo];
+  }
+
+  /// getDataSize() - Get the record data size, which is the record size
+  /// without tail padding, in characters.
+  CharUnits getDataSize() const {
+    return DataSize;
+  }
+
+  /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
+  /// which is the size of the object without virtual bases.
+  CharUnits getNonVirtualSize() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->NonVirtualSize;
+  }
+
+  /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
+  /// which is the alignment of the object without virtual bases.
+  CharUnits getNonVirtualAlignment() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->NonVirtualAlignment;
+  }
+
+  /// getPrimaryBase - Get the primary base for this record.
+  const CXXRecordDecl *getPrimaryBase() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->PrimaryBase.getPointer();
+  }
+
+  /// isPrimaryBaseVirtual - Get whether the primary base for this record
+  /// is virtual or not.
+  bool isPrimaryBaseVirtual() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+    return CXXInfo->PrimaryBase.getInt();
+  }
+
+  /// getBaseClassOffset - Get the offset, in chars, for the given base class.
+  CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
+
+    return CXXInfo->BaseOffsets[Base];
+  }
+
+  /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
+  CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
+
+    return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
+  }
+
+  CharUnits getSizeOfLargestEmptySubobject() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->SizeOfLargestEmptySubobject;
+  }
+
+  /// hasOwnVFPtr - Does this class provide its own virtual-function
+  /// table pointer, rather than inheriting one from a primary base
+  /// class?  If so, it is at offset zero.
+  ///
+  /// This implies that the ABI has no primary base class, meaning
+  /// that it has no base classes that are suitable under the conditions
+  /// of the ABI.
+  bool hasOwnVFPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->HasOwnVFPtr;
+  }
+
+  /// hasVFPtr - Does this class have a virtual function table pointer
+  /// that can be extended by a derived class?  This is synonymous with
+  /// this class having a VFPtr at offset zero.
+  bool hasExtendableVFPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->HasExtendableVFPtr;
+  }
+  
+  /// hasOwnVBPtr - Does this class provide its own virtual-base
+  /// table pointer, rather than inheriting one from a primary base
+  /// class?
+  ///
+  /// This implies that the ABI has no primary base class, meaning
+  /// that it has no base classes that are suitable under the conditions
+  /// of the ABI.
+  bool hasOwnVBPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return hasVBPtr() && !CXXInfo->BaseSharingVBPtr;
+  }
+
+  /// hasVBPtr - Does this class have a virtual function table pointer.
+  bool hasVBPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return !CXXInfo->VBPtrOffset.isNegative();
+  }
+
+  CharUnits getRequiredAlignment() const {
+    return RequiredAlignment;
+  }
+
+  bool hasZeroSizedSubObject() const {
+    return CXXInfo && CXXInfo->HasZeroSizedSubObject;
+  }
+
+  bool leadsWithZeroSizedBase() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->LeadsWithZeroSizedBase;
+  }
+
+  /// getVBPtrOffset - Get the offset for virtual base table pointer.
+  /// This is only meaningful with the Microsoft ABI.
+  CharUnits getVBPtrOffset() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->VBPtrOffset;
+  }
+
+  const CXXRecordDecl *getBaseSharingVBPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->BaseSharingVBPtr;
+  }
+
+  const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->VBaseOffsets;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
new file mode 100644
index 0000000..ff46ffb
--- /dev/null
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -0,0 +1,2539 @@
+//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- 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 RecursiveASTVisitor interface, which recursively
+//  traverses the entire AST.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming.  The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST()                                                         \
+  OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
+      OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
+      OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
+      OPERATOR(Extension)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST()                                                           \
+  OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
+      OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
+      OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
+      OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd)     \
+      OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST()                                                             \
+  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
+      OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+
+namespace clang {
+
+// A helper macro to implement short-circuiting when recursing.  It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR)                                                      \
+  do {                                                                         \
+    if (!getDerived().CALL_EXPR)                                               \
+      return false;                                                            \
+  } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+///   1. traverse the AST (i.e. go to each node);
+///   2. at a given node, walk up the class hierarchy, starting from
+///      the node's dynamic type, until the top-most class (e.g. Stmt,
+///      Decl, or Type) is reached.
+///   3. given a (node, class) combination, where 'class' is some base
+///      class of the dynamic type of 'node', call a user-overridable
+///      function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
+///      for traversing an AST rooted at x.  This method simply
+///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+///      then recursively visits the child nodes of x.
+///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+///      similarly.
+///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
+///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
+///      where Bar is the direct parent class of Foo (unless Foo has
+///      no parent), and then calls VisitFoo(x) (see the next list item).
+///   3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*).  A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamespaceDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together.  In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior.  Most users only need to override Visit*.  Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies.  Returning false from one of these overridden
+/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once.  The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations.  Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately.  This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// to return true, in which case all known implicit and explicit
+/// instantiations will be visited at the same time as the pattern
+/// from which they were produced.
+template <typename Derived> class RecursiveASTVisitor {
+public:
+  /// \brief Return a reference to the derived class.
+  Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+  /// \brief Return whether this visitor should recurse into
+  /// template instantiations.
+  bool shouldVisitTemplateInstantiations() const { return false; }
+
+  /// \brief Return whether this visitor should recurse into the types of
+  /// TypeLocs.
+  bool shouldWalkTypesOfTypeLocs() const { return true; }
+
+  /// \brief Return whether this visitor should recurse into implicit
+  /// code, e.g., implicit constructors and destructors.
+  bool shouldVisitImplicitCode() const { return false; }
+
+  /// \brief Return whether \param S should be traversed using data recursion
+  /// to avoid a stack overflow with extreme cases.
+  bool shouldUseDataRecursionFor(Stmt *S) const {
+    return isa<BinaryOperator>(S) || isa<UnaryOperator>(S) ||
+           isa<CaseStmt>(S) || isa<CXXOperatorCallExpr>(S);
+  }
+
+  /// \brief Recursively visit a statement or expression, by
+  /// dispatching to Traverse*() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseStmt(Stmt *S);
+
+  /// \brief Recursively visit a type, by dispatching to
+  /// Traverse*Type() based on the argument's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type).
+  bool TraverseType(QualType T);
+
+  /// \brief Recursively visit a type with location, by dispatching to
+  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseTypeLoc(TypeLoc TL);
+
+  /// \brief Recursively visit an attribute, by dispatching to
+  /// Traverse*Attr() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseAttr(Attr *At);
+
+  /// \brief Recursively visit a declaration, by dispatching to
+  /// Traverse*Decl() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseDecl(Decl *D);
+
+  /// \brief Recursively visit a C++ nested-name-specifier.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// \brief Recursively visit a C++ nested-name-specifier with location
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+  /// \brief Recursively visit a name with its location information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+  /// \brief Recursively visit a template name and dispatch to the
+  /// appropriate method.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateName(TemplateName Template);
+
+  /// \brief Recursively visit a template argument and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: migrate callers to TemplateArgumentLoc instead.
+  bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+  /// \brief Recursively visit a template argument location and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Recursively visit a set of template arguments.
+  /// This can be overridden by a subclass, but it's not expected that
+  /// will be needed -- this visitor always dispatches to another.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+  bool TraverseTemplateArguments(const TemplateArgument *Args,
+                                 unsigned NumArgs);
+
+  /// \brief Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the name.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+  /// \brief Recursively visit a lambda capture.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+
+  /// \brief Recursively visit the body of a lambda expression.
+  ///
+  /// This provides a hook for visitors that need more context when visiting
+  /// \c LE->getBody().
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaBody(LambdaExpr *LE);
+
+  // ---- Methods on Attrs ----
+
+  // \brief Visit an attribute.
+  bool VisitAttr(Attr *A) { return true; }
+
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+  // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+  bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+  bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT)                                                    \
+  bool WalkUpFrom##CLASS(CLASS *S) {                                           \
+    TRY_TO(WalkUpFrom##PARENT(S));                                             \
+    TRY_TO(Visit##CLASS(S));                                                   \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods.  Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  bool TraverseUnary##NAME(UnaryOperator *S) {                                 \
+    TRY_TO(WalkUpFromUnary##NAME(S));                                          \
+    TRY_TO(TraverseStmt(S->getSubExpr()));                                     \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
+    TRY_TO(WalkUpFromUnaryOperator(S));                                        \
+    TRY_TO(VisitUnary##NAME(S));                                               \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+  UNARYOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods.  Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
+  bool TraverseBin##NAME(BINOP_TYPE *S) {                                      \
+    TRY_TO(WalkUpFromBin##NAME(S));                                            \
+    TRY_TO(TraverseStmt(S->getLHS()));                                         \
+    TRY_TO(TraverseStmt(S->getRHS()));                                         \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
+    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
+    TRY_TO(VisitBin##NAME(S));                                                 \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+  BINOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods.  Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+  CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
+
+// Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+  // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+  bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+  bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
+    TRY_TO(WalkUpFrom##BASE(T));                                               \
+    TRY_TO(Visit##CLASS##Type(T));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
+
+// Declare Traverse*() for all concrete TypeLoc classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+  // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+  bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+  // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+  // TypeNodes.def and thus need to be handled specially.
+  bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+  bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
+    TRY_TO(WalkUpFrom##BASE##Loc(TL));                                         \
+    TRY_TO(Visit##CLASS##TypeLoc(TL));                                         \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on Decls ----
+
+// Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+  // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+  bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+  bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
+    TRY_TO(WalkUpFrom##BASE(D));                                               \
+    TRY_TO(Visit##CLASS##Decl(D));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+  // These are helper methods used by more than one Traverse* method.
+  bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND)                                   \
+  bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
+  DEF_TRAVERSE_TMPL_INST(Class)
+  DEF_TRAVERSE_TMPL_INST(Var)
+  DEF_TRAVERSE_TMPL_INST(Function)
+#undef DEF_TRAVERSE_TMPL_INST
+  bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+                                          unsigned Count);
+  bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+  bool TraverseRecordHelper(RecordDecl *D);
+  bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+  bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+  bool TraverseDeclContextHelper(DeclContext *DC);
+  bool TraverseFunctionHelper(FunctionDecl *D);
+  bool TraverseVarHelper(VarDecl *D);
+  bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+  bool TraverseOMPClause(OMPClause *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+  /// \brief Process clauses with list of variables.
+  template <typename T> bool VisitOMPClauseList(T *Node);
+
+  struct EnqueueJob {
+    Stmt *S;
+    Stmt::child_iterator StmtIt;
+
+    EnqueueJob(Stmt *S) : S(S), StmtIt() {}
+  };
+  bool dataTraverse(Stmt *S);
+  bool dataTraverseNode(Stmt *S, bool &EnqueueChildren);
+};
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
+
+  SmallVector<EnqueueJob, 16> Queue;
+  Queue.push_back(S);
+
+  while (!Queue.empty()) {
+    EnqueueJob &job = Queue.back();
+    Stmt *CurrS = job.S;
+    if (!CurrS) {
+      Queue.pop_back();
+      continue;
+    }
+
+    if (getDerived().shouldUseDataRecursionFor(CurrS)) {
+      if (job.StmtIt == Stmt::child_iterator()) {
+        bool EnqueueChildren = true;
+        if (!dataTraverseNode(CurrS, EnqueueChildren))
+          return false;
+        if (!EnqueueChildren) {
+          Queue.pop_back();
+          continue;
+        }
+        job.StmtIt = CurrS->child_begin();
+      } else {
+        ++job.StmtIt;
+      }
+
+      if (job.StmtIt != CurrS->child_end())
+        Queue.push_back(*job.StmtIt);
+      else
+        Queue.pop_back();
+      continue;
+    }
+
+    Queue.pop_back();
+    TRY_TO(TraverseStmt(CurrS));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
+                                                    bool &EnqueueChildren) {
+
+// Dispatch to the corresponding WalkUpFrom* function only if the derived
+// class didn't override Traverse* (and thus the traversal is trivial).
+#define DISPATCH_WALK(NAME, CLASS, VAR)                                        \
+  {                                                                            \
+    bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME;            \
+    bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME;   \
+    if (DerivedFn == BaseFn)                                                   \
+      return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR));         \
+  }                                                                            \
+  EnqueueChildren = false;                                                     \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR));
+
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+    switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
+
+      BINOP_LIST()
+#undef OPERATOR
+
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
+    DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+      CAO_LIST()
+#undef OPERATOR
+    }
+  } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+    switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
+
+      UNARYOP_LIST()
+#undef OPERATOR
+    }
+  }
+
+  // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+  switch (S->getStmtClass()) {
+  case Stmt::NoStmtClass:
+    break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_WALK(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+  }
+
+#undef DISPATCH_WALK
+
+  return true;
+}
+
+#define DISPATCH(NAME, CLASS, VAR)                                             \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+  if (!S)
+    return true;
+
+#define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR)
+
+  if (getDerived().shouldUseDataRecursionFor(S))
+    return dataTraverse(S);
+
+  // If we have a binary expr, dispatch to the subcode of the binop.  A smart
+  // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+  // below.
+  if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+    switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
+
+      BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
+    DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+      CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
+    }
+  } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+    switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
+
+      UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
+    }
+  }
+
+  // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+  switch (S->getStmtClass()) {
+  case Stmt::NoStmtClass:
+    break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_STMT(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+  }
+
+  return true;
+}
+
+#undef DISPATCH_STMT
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+  if (T.isNull())
+    return true;
+
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  case Type::CLASS:                                                            \
+    DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
+#include "clang/AST/TypeNodes.def"
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+  if (TL.isNull())
+    return true;
+
+  switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  case TypeLoc::CLASS:                                                         \
+    return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+#include "clang/AST/TypeLocNodes.def"
+  }
+
+  return true;
+}
+
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+  if (!D)
+    return true;
+
+  // As a syntax visitor, by default we want to ignore declarations for
+  // implicit declarations (ones not typed explicitly by the user).
+  if (!getDerived().shouldVisitImplicitCode() && D->isImplicit())
+    return true;
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  case Decl::CLASS:                                                            \
+    if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D)))    \
+      return false;                                                            \
+    break;
+#include "clang/AST/DeclNodes.inc"
+  }
+
+  // Visit any attributes attached to this declaration.
+  for (auto *I : D->attrs()) {
+    if (!getDerived().TraverseAttr(I))
+      return false;
+  }
+  return true;
+}
+
+#undef DISPATCH
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+    NestedNameSpecifier *NNS) {
+  if (!NNS)
+    return true;
+
+  if (NNS->getPrefix())
+    TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+    NestedNameSpecifierLoc NNS) {
+  if (!NNS)
+    return true;
+
+  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+    TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+
+  switch (NNS.getNestedNameSpecifier()->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+    DeclarationNameInfo NameInfo) {
+  switch (NameInfo.getName().getNameKind()) {
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
+      TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
+
+    break;
+
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+    const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type:
+    return getDerived().TraverseType(Arg.getAsType());
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(Arg.getAsExpr());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+    const TemplateArgumentLoc &ArgLoc) {
+  const TemplateArgument &Arg = ArgLoc.getArgument();
+
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type: {
+    // FIXME: how can TSI ever be NULL?
+    if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+      return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+    else
+      return getDerived().TraverseType(Arg.getAsType());
+  }
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    if (ArgLoc.getTemplateQualifierLoc())
+      TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+          ArgLoc.getTemplateQualifierLoc()));
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+    const TemplateArgument *Args, unsigned NumArgs) {
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    TRY_TO(TraverseTemplateArgument(Args[I]));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+    CXXCtorInitializer *Init) {
+  if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
+  if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
+    TRY_TO(TraverseStmt(Init->getInit()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+                                                    const LambdaCapture *C) {
+  if (C->isInitCapture())
+    TRY_TO(TraverseDecl(C->getCapturedVar()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
+  TRY_TO(TraverseStmt(LE->getBody()));
+  return true;
+}
+
+// ----------------- Type traversal -----------------
+
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) {                 \
+    TRY_TO(WalkUpFrom##TYPE(T));                                               \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_TYPE(BuiltinType, {})
+
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(BlockPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+  TRY_TO(TraverseType(T->getPointeeType()));
+})
+
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+  TRY_TO(TraverseType(T->getElementType()));
+})
+
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+                  { TRY_TO(TraverseType(T->getReturnType())); })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+  TRY_TO(TraverseType(T->getReturnType()));
+
+  for (const auto &A : T->param_types()) {
+    TRY_TO(TraverseType(A));
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
+
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+
+DEF_TRAVERSE_TYPE(DecltypeType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(UnaryTransformType, {
+  TRY_TO(TraverseType(T->getBaseType()));
+  TRY_TO(TraverseType(T->getUnderlyingType()));
+})
+
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
+
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(T->getTemplateName()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPE(AttributedType,
+                  { TRY_TO(TraverseType(T->getModifiedType())); })
+
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+  if (T->getQualifier()) {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  }
+  TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+                  { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+  TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (T->getBaseType().getTypePtr() != T)
+    TRY_TO(TraverseType(T->getBaseType()));
+})
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
+// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
+// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                       \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) {       \
+    if (getDerived().shouldWalkTypesOfTypeLocs())                              \
+      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr())));           \
+    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                         \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // Move this over to the 'main' typeloc tree.  Note that this is a
+  // move -- we pretend that we were really looking at the unqualified
+  // typeloc all along -- rather than a recursion, so we don't follow
+  // the normal CRTP plan of going through
+  // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
+  // twice for the same type (once as a QualifiedTypeLoc version of
+  // the type, once as an UnqualifiedTypeLoc version of the type),
+  // which in effect means we'd call VisitTypeLoc twice with the
+  // 'same' type.  This solves that problem, at the cost of never
+  // seeing the qualified version of the type (unless the client
+  // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
+  // perfect solution.  A perfect solution probably requires making
+  // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+  // wrapper around Type* -- rather than being its own class in the
+  // type hierarchy.
+  return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(PointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+  TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+DEF_TRAVERSE_TYPELOC(DecayedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+  // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
+  return true;
+}
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+  if (TL.getTypePtr()->getSizeExpr())
+    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+                     { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
+
+// FIXME: location of exception specifications (attributes?)
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+  TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+
+  const FunctionProtoType *T = TL.getTypePtr();
+
+  for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+    if (TL.getParam(I)) {
+      TRY_TO(TraverseDecl(TL.getParam(I)));
+    } else if (I < T->getNumParams()) {
+      TRY_TO(TraverseType(T->getParamType(I)));
+    }
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+                     { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+  TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
+
+DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AutoType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
+
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AttributedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+  TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+  if (!DC)
+    return true;
+
+  for (auto *Child : DC->decls()) {
+    // BlockDecls and CapturedDecls are traversed through BlockExprs and
+    // CapturedStmts respectively.
+    if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+      TRY_TO(TraverseDecl(Child));
+  }
+
+  return true;
+}
+
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) {                 \
+    TRY_TO(WalkUpFrom##DECL(D));                                               \
+    { CODE; }                                                                  \
+    TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));               \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
+
+DEF_TRAVERSE_DECL(BlockDecl, {
+  if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+  TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(CapturedDecl, {
+  TRY_TO(TraverseStmt(D->getBody()));
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(EmptyDecl, {})
+
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+                  { TRY_TO(TraverseStmt(D->getAsmString())); })
+
+DEF_TRAVERSE_DECL(ImportDecl, {})
+
+DEF_TRAVERSE_DECL(FriendDecl, {
+  // Friend is either decl or a type.
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
+
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+  for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(I);
+    for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+         ITPL != ETPL; ++ITPL) {
+      TRY_TO(TraverseDecl(*ITPL));
+    }
+  }
+})
+
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
+  TRY_TO(TraverseDecl(D->getSpecialization()));
+
+  if (D->hasExplicitTemplateArgs()) {
+    const TemplateArgumentListInfo &args = D->templateArgs();
+    TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
+                                              args.size()));
+  }
+})
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+                                        })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+  TRY_TO(TraverseStmt(D->getAssertExpr()));
+  TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+    TranslationUnitDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+  // We shouldn't traverse an aliased namespace, since it will be
+  // defined (and, therefore, traversed) somewhere else.
+  //
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+                             })
+
+DEF_TRAVERSE_DECL(
+    NamespaceDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+                                           })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+                                        })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+                                          })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+                                     })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+  if (D->getReturnTypeSourceInfo()) {
+    TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+  }
+  for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    TRY_TO(TraverseDecl(*I));
+  }
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody()));
+  }
+  return true;
+})
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
+
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+  for (auto *I : D->varlists()) {
+    TRY_TO(TraverseStmt(I));
+  }
+})
+
+// A helper method for TemplateDecl's children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+    TemplateParameterList *TPL) {
+  if (TPL) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+    ClassTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      // We don't want to visit injected-class-names in this traversal.
+      if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+        continue;
+
+      switch (
+          cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+    VarTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      switch (
+          cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+    FunctionTemplateDecl *D) {
+  for (auto *FD : D->specializations()) {
+    for (auto *RD : FD->redecls()) {
+      switch (RD->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        // We don't know what kind of FunctionDecl this is.
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // FIXME: For now traverse explicit instantiations here. Change that
+      // once they are represented as dedicated nodes in the AST.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+// This macro unifies the traversal of class, variable and function
+// template declarations.
+#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)                                   \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, {                              \
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));                               \
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));   \
+                                                                               \
+    /* By default, we do not traverse the instantiations of                    \
+       class templates since they do not appear in the user code. The          \
+       following code optionally traverses them.                               \
+                                                                               \
+       We only traverse the class instantiations when we see the canonical     \
+       declaration of the template, to ensure we only visit them once. */      \
+    if (getDerived().shouldVisitTemplateInstantiations() &&                    \
+        D == D->getCanonicalDecl())                                            \
+      TRY_TO(TraverseTemplateInstantiations(D));                               \
+                                                                               \
+    /* Note that getInstantiatedFromMemberTemplate() is just a link            \
+       from a template instantiation back to the template from which           \
+       it was instantiated, and thus should not be traversed. */               \
+  })
+
+DEF_TRAVERSE_TMPL_DECL(Class)
+DEF_TRAVERSE_TMPL_DECL(Var)
+DEF_TRAVERSE_TMPL_DECL(Function)
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+  // D is the "T" in something like
+  //   template <template <typename> class T> class container { };
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
+    TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+  }
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+  // D is the "T" in something like "template<typename T> class vector;"
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the typedef, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type alias, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+  // A dependent using declaration which was marked with 'typename'.
+  //   template<class T> class A : public B<T> { using typename B<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // The enumerators are already traversed by
+  // decls_begin()/decls_end().
+})
+
+// Helper methods for RecordDecl and its children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the source.
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
+  if (!TraverseRecordHelper(D))
+    return false;
+  if (D->isCompleteDefinition()) {
+    for (const auto &I : D->bases()) {
+      TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+    }
+    // We don't traverse the friends or the conversions, as they are
+    // already in decls_begin()/decls_end().
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
+
+#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND)                              \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, {                \
+    /* For implicit instantiations ("set<int> x;"), we don't want to           \
+       recurse at all, since the instatiated template isn't written in         \
+       the source code anywhere.  (Note the instatiated *type* --              \
+       set<int> -- is written, and will still get a callback of                \
+       TemplateSpecializationType).  For explicit instantiations               \
+       ("template set<int>;"), we do need a callback, since this               \
+       is the only callback that's made for this instantiation.                \
+       We use getTypeAsWritten() to distinguish. */                            \
+    if (TypeSourceInfo *TSI = D->getTypeAsWritten())                           \
+      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));                              \
+                                                                               \
+    if (!getDerived().shouldVisitTemplateInstantiations() &&                   \
+        D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)      \
+      /* Returning from here skips traversing the                              \
+         declaration context of the *TemplateSpecializationDecl                \
+         (embedded in the DEF_TRAVERSE_DECL() macro)                           \
+         which contains the instantiated members of the template. */           \
+      return true;                                                             \
+  })
+
+DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
+DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+    const TemplateArgumentLoc *TAL, unsigned Count) {
+  for (unsigned I = 0; I < Count; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+  }
+  return true;
+}
+
+#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)               \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, {         \
+    /* The partial specialization. */                                          \
+    if (TemplateParameterList *TPL = D->getTemplateParameters()) {             \
+      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();   \
+           I != E; ++I) {                                                      \
+        TRY_TO(TraverseDecl(*I));                                              \
+      }                                                                        \
+    }                                                                          \
+    /* The args that remains unspecialized. */                                 \
+    TRY_TO(TraverseTemplateArgumentLocsHelper(                                 \
+        D->getTemplateArgsAsWritten()->getTemplateArgs(),                      \
+        D->getTemplateArgsAsWritten()->NumTemplateArgs));                      \
+                                                                               \
+    /* Don't need the *TemplatePartialSpecializationHelper, even               \
+       though that's our parent class -- we already visit all the              \
+       template args here. */                                                  \
+    TRY_TO(Traverse##DECLKIND##Helper(D));                                     \
+                                                                               \
+    /* Instantiations will have been visited with the primary template. */     \
+  })
+
+DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
+DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+  // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+  //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
+
+DEF_TRAVERSE_DECL(FieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  else if (D->hasInClassInitializer())
+    TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
+
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+
+  // If we're an explicit template specialization, iterate over the
+  // template args that were explicitly specified.  If we were doing
+  // this in typing order, we'd do it between the return type and
+  // the function args, but both are handled by the FunctionTypeLoc
+  // above, so we have to choose one side.  I've decided to do before.
+  if (const FunctionTemplateSpecializationInfo *FTSI =
+          D->getTemplateSpecializationInfo()) {
+    if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+        FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+      // A specialization might not have explicit template arguments if it has
+      // a templated return type and concrete arguments.
+      if (const ASTTemplateArgumentListInfo *TALI =
+              FTSI->TemplateArgumentsAsWritten) {
+        TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+                                                  TALI->NumTemplateArgs));
+      }
+    }
+  }
+
+  // Visit the function type itself, which can be either
+  // FunctionNoProtoType or FunctionProtoType, or a typedef.  This
+  // also covers the return type and the function parameters,
+  // including exception specifications.
+  if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
+    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+  } else if (getDerived().shouldVisitImplicitCode()) {
+    // Visit parameter variable declarations of the implicit function
+    // if the traverser is visiting implicit code. Parameter variable
+    // declarations do not have valid TypeSourceInfo, so to visit them
+    // we need to traverse the declarations explicitly.
+    for (FunctionDecl::param_const_iterator I = D->param_begin(),
+                                            E = D->param_end();
+         I != E; ++I)
+      TRY_TO(TraverseDecl(*I));
+  }
+
+  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+    // Constructor initializers.
+    for (auto *I : Ctor->inits()) {
+      TRY_TO(TraverseConstructorInitializer(I));
+    }
+  }
+
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody())); // Function body.
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  // Default params are taken care of when we traverse the ParmVarDecl.
+  if (!isa<ParmVarDecl>(D) &&
+      (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
+    TRY_TO(TraverseStmt(D->getInit()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+  // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+  TRY_TO(TraverseVarHelper(D));
+
+  if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+
+  if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in children() (every stmt defines these,
+// though sometimes the range is empty).  Each individual Traverse*
+// method only needs to worry about children other than those.  To see
+// what children() does for a given class, see, e.g.,
+//   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) {                 \
+    TRY_TO(WalkUpFrom##STMT(S));                                               \
+    { CODE; }                                                                  \
+    for (Stmt::child_range range = S->children(); range; ++range) {            \
+      TRY_TO(TraverseStmt(*range));                                            \
+    }                                                                          \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_STMT(GCCAsmStmt, {
+  TRY_TO(TraverseStmt(S->getAsmString()));
+  for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
+  }
+  for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
+  }
+  for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
+  }
+  // children() iterates over inputExpr and outputExpr.
+})
+
+DEF_TRAVERSE_STMT(
+    MSAsmStmt,
+    {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
+     // added this needs to be implemented.
+    })
+
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+  TRY_TO(TraverseDecl(S->getExceptionDecl()));
+  // children() iterates over the handler block.
+})
+
+DEF_TRAVERSE_STMT(DeclStmt, {
+  for (auto *I : S->decls()) {
+    TRY_TO(TraverseDecl(I));
+  }
+  // Suppress the default iteration over children() by
+  // returning.  Here's why: A DeclStmt looks like 'type var [=
+  // initializer]'.  The decls above already traverse over the
+  // initializers, so we don't have to do it again (which
+  // children() would do).
+  return true;
+})
+
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {
+  if (!getDerived().shouldVisitImplicitCode()) {
+    TRY_TO(TraverseStmt(S->getLoopVarStmt()));
+    TRY_TO(TraverseStmt(S->getRangeInit()));
+    TRY_TO(TraverseStmt(S->getBody()));
+    // Visit everything else only if shouldVisitImplicitCode().
+    return true;
+  }
+})
+DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+})
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getExplicitTemplateArgs().getTemplateArgs(),
+        S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(
+    ImplicitCastExpr,
+    {// We don't traverse the cast type, as it's not written in the
+     // source code.
+    })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+  if (InitListExpr *Syn = S->getSyntacticForm())
+    S = Syn;
+  TRY_TO(WalkUpFromInitListExpr(S));
+  // All we need are the default actions.  FIXME: use a helper function.
+  for (Stmt::child_range range = S->children(); range; ++range) {
+    TRY_TO(TraverseStmt(*range));
+  }
+  return true;
+}
+
+// GenericSelectionExpr is a special case because the types and expressions
+// are interleaved.  We also need to watch out for null types (default
+// generic associations).
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+    GenericSelectionExpr *S) {
+  TRY_TO(WalkUpFromGenericSelectionExpr(S));
+  TRY_TO(TraverseStmt(S->getControllingExpr()));
+  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+    if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+      TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+    TRY_TO(TraverseStmt(S->getAssocExpr(i)));
+  }
+  return true;
+}
+
+// PseudoObjectExpr is a special case because of the wierdness with
+// syntactic expressions and opaque values.
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+  TRY_TO(WalkUpFromPseudoObjectExpr(S));
+  TRY_TO(TraverseStmt(S->getSyntacticForm()));
+  for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+                                            e = S->semantics_end();
+       i != e; ++i) {
+    Expr *sub = *i;
+    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
+      sub = OVE->getSourceExpr();
+    TRY_TO(TraverseStmt(sub));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+  // This is called for code like 'return T()' where T is a built-in
+  // (i.e. non-class) type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+  // The child-iterator will pick up the other arguments.
+  TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+  // The child-iterator will pick up the expression representing
+  // the field.
+  // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+  // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isArgumentType())
+    TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXUuidofExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+    TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+  TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+                  { TRY_TO(TraverseStmt(S->getQueriedExpression())); })
+
+DEF_TRAVERSE_STMT(VAArgExpr, {
+  // The child-iterator will pick up the expression argument.
+  TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+  // This is called for code like 'return T()' where T is a class type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+  TRY_TO(WalkUpFromLambdaExpr(S));
+
+  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+                                    CEnd = S->explicit_capture_end();
+       C != CEnd; ++C) {
+    TRY_TO(TraverseLambdaCapture(S, C));
+  }
+
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+      }
+    }
+  }
+
+  TRY_TO(TraverseLambdaBody(S));
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
+  // This is called for code like 'T()', where T is a template argument.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// These expressions all might take explicit template arguments.
+// We traverse those if so.  FIXME: implement these.
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
+DEF_TRAVERSE_STMT(BlockExpr, {
+  TRY_TO(TraverseDecl(S->getBlockDecl()));
+  return true; // no child statements to loop through.
+})
+DEF_TRAVERSE_STMT(ChooseExpr, {})
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
+    TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
+  if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
+    TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
+  if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+  if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
+DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(SEHTryStmt, {})
+DEF_TRAVERSE_STMT(SEHExceptStmt, {})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
+
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
+// Traverse OpenCL: AsType, Convert.
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
+
+// OpenMP directives.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+    OMPExecutableDirective *S) {
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+// OpenMP clauses.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+  if (!C)
+    return true;
+  switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
+#include "clang/Basic/OpenMPKinds.def"
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    break;
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  TRY_TO(TraverseStmt(C->getNumThreads()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  TRY_TO(TraverseStmt(C->getSafelen()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+  return true;
+}
+
+template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+    OMPFirstprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything.  These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+//    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+//    Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
new file mode 100644
index 0000000..7aa11d4
--- /dev/null
+++ b/include/clang/AST/Redeclarable.h
@@ -0,0 +1,279 @@
+//===-- Redeclarable.h - Base for Decls that can be redeclared -*- 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 Redeclarable interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_REDECLARABLE_H
+#define LLVM_CLANG_AST_REDECLARABLE_H
+
+#include "clang/AST/ExternalASTSource.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
+#include <iterator>
+
+namespace clang {
+
+/// \brief Provides common interface for the Decls that can be redeclared.
+template<typename decl_type>
+class Redeclarable {
+protected:
+  class DeclLink {
+    /// A pointer to a known latest declaration, either statically known or
+    /// generationally updated as decls are added by an external source.
+    typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
+                                      &ExternalASTSource::CompleteRedeclChain>
+                                          KnownLatest;
+
+    typedef const ASTContext *UninitializedLatest;
+    typedef Decl *Previous;
+
+    /// A pointer to either an uninitialized latest declaration (where either
+    /// we've not yet set the previous decl or there isn't one), or to a known
+    /// previous declaration.
+    typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
+
+    mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
+
+  public:
+    enum PreviousTag { PreviousLink };
+    enum LatestTag { LatestLink };
+
+    DeclLink(LatestTag, const ASTContext &Ctx)
+        : Next(NotKnownLatest(&Ctx)) {}
+    DeclLink(PreviousTag, decl_type *D)
+        : Next(NotKnownLatest(Previous(D))) {}
+
+    bool NextIsPrevious() const {
+      return Next.is<NotKnownLatest>() &&
+             // FIXME: 'template' is required on the next line due to an
+             // apparent clang bug.
+             Next.get<NotKnownLatest>().template is<Previous>();
+    }
+
+    bool NextIsLatest() const { return !NextIsPrevious(); }
+
+    decl_type *getNext(const decl_type *D) const {
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        if (NKL.is<Previous>())
+          return static_cast<decl_type*>(NKL.get<Previous>());
+
+        // Allocate the generational 'most recent' cache now, if needed.
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(),
+                           const_cast<decl_type *>(D));
+      }
+
+      return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
+    }
+
+    void setPrevious(decl_type *D) {
+      assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
+      Next = Previous(D);
+    }
+
+    void setLatest(decl_type *D) {
+      assert(NextIsLatest() && "decl became canonical unexpectedly");
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
+      } else {
+        auto Latest = Next.get<KnownLatest>();
+        Latest.set(D);
+        Next = Latest;
+      }
+    }
+
+    void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
+  };
+
+  static DeclLink PreviousDeclLink(decl_type *D) {
+    return DeclLink(DeclLink::PreviousLink, D);
+  }
+
+  static DeclLink LatestDeclLink(const ASTContext &Ctx) {
+    return DeclLink(DeclLink::LatestLink, Ctx);
+  }
+
+  /// \brief Points to the next redeclaration in the chain.
+  ///
+  /// If NextIsPrevious() is true, this is a link to the previous declaration
+  /// of this same Decl. If NextIsLatest() is true, this is the first
+  /// declaration and Link points to the latest declaration. For example:
+  ///
+  ///  #1 int f(int x, int y = 1); // <pointer to #3, true>
+  ///  #2 int f(int x = 0, int y); // <pointer to #1, false>
+  ///  #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
+  ///
+  /// If there is only one declaration, it is <pointer to self, true>
+  DeclLink RedeclLink;
+
+  decl_type *getNextRedeclaration() const {
+    return RedeclLink.getNext(static_cast<const decl_type *>(this));
+  }
+
+public:
+  Redeclarable(const ASTContext &Ctx)
+      : RedeclLink(LatestDeclLink(Ctx)) {}
+
+  /// \brief Return the previous declaration of this declaration or NULL if this
+  /// is the first declaration.
+  decl_type *getPreviousDecl() {
+    if (RedeclLink.NextIsPrevious())
+      return getNextRedeclaration();
+    return nullptr;
+  }
+  const decl_type *getPreviousDecl() const {
+    return const_cast<decl_type *>(
+                 static_cast<const decl_type*>(this))->getPreviousDecl();
+  }
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  decl_type *getFirstDecl() {
+    decl_type *D = static_cast<decl_type*>(this);
+    while (D->getPreviousDecl())
+      D = D->getPreviousDecl();
+    return D;
+  }
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  const decl_type *getFirstDecl() const {
+    const decl_type *D = static_cast<const decl_type*>(this);
+    while (D->getPreviousDecl())
+      D = D->getPreviousDecl();
+    return D;
+  }
+
+  /// \brief True if this is the first declaration in its redeclaration chain.
+  bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
+
+  /// \brief Returns the most recent (re)declaration of this declaration.
+  decl_type *getMostRecentDecl() {
+    return getFirstDecl()->getNextRedeclaration();
+  }
+
+  /// \brief Returns the most recent (re)declaration of this declaration.
+  const decl_type *getMostRecentDecl() const {
+    return getFirstDecl()->getNextRedeclaration();
+  }
+
+  /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
+  /// first and only declaration.
+  void setPreviousDecl(decl_type *PrevDecl);
+
+  /// \brief Iterates through all the redeclarations of the same decl.
+  class redecl_iterator {
+    /// Current - The current declaration.
+    decl_type *Current;
+    decl_type *Starter;
+    bool PassedFirst;
+
+  public:
+    typedef decl_type*                value_type;
+    typedef decl_type*                reference;
+    typedef decl_type*                pointer;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef std::ptrdiff_t            difference_type;
+
+    redecl_iterator() : Current(nullptr) { }
+    explicit redecl_iterator(decl_type *C)
+      : Current(C), Starter(C), PassedFirst(false) { }
+
+    reference operator*() const { return Current; }
+    pointer operator->() const { return Current; }
+
+    redecl_iterator& operator++() {
+      assert(Current && "Advancing while iterator has reached end");
+      // Sanity check to avoid infinite loop on invalid redecl chain.
+      if (Current->isFirstDecl()) {
+        if (PassedFirst) {
+          assert(0 && "Passed first decl twice, invalid redecl chain!");
+          Current = nullptr;
+          return *this;
+        }
+        PassedFirst = true;
+      }
+
+      // Get either previous decl or latest decl.
+      decl_type *Next = Current->getNextRedeclaration();
+      Current = (Next != Starter) ? Next : nullptr;
+      return *this;
+    }
+
+    redecl_iterator operator++(int) {
+      redecl_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool operator==(redecl_iterator x, redecl_iterator y) {
+      return x.Current == y.Current;
+    }
+    friend bool operator!=(redecl_iterator x, redecl_iterator y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+  /// \brief Returns an iterator range for all the redeclarations of the same
+  /// decl. It will iterate at least once (when this decl is the only one).
+  redecl_range redecls() const {
+    return redecl_range(redecl_iterator(const_cast<decl_type *>(
+                            static_cast<const decl_type *>(this))),
+                        redecl_iterator());
+  }
+
+  redecl_iterator redecls_begin() const { return redecls().begin(); }
+  redecl_iterator redecls_end() const { return redecls().end(); }
+
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+};
+
+/// \brief Get the primary declaration for a declaration from an AST file. That
+/// will be the first-loaded declaration.
+Decl *getPrimaryMergedDecl(Decl *D);
+
+/// \brief Provides common interface for the Decls that cannot be redeclared,
+/// but can be merged if the same declaration is brought in from multiple
+/// modules.
+template<typename decl_type>
+class Mergeable {
+public:
+  Mergeable() {}
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  decl_type *getFirstDecl() {
+    decl_type *D = static_cast<decl_type*>(this);
+    if (!D->isFromASTFile())
+      return D;
+    return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
+  }
+
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  const decl_type *getFirstDecl() const {
+    const decl_type *D = static_cast<const decl_type*>(this);
+    if (!D->isFromASTFile())
+      return D;
+    return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
+  }
+
+  /// \brief Returns true if this is the first declaration.
+  bool isFirstDecl() const { return getFirstDecl() == this; }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
new file mode 100644
index 0000000..6d903f8
--- /dev/null
+++ b/include/clang/AST/SelectorLocationsKind.h
@@ -0,0 +1,83 @@
+//===--- SelectorLocationsKind.h - Kind of selector locations ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Describes whether the identifier locations for a selector are "standard"
+// or not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
+#define LLVM_CLANG_AST_SELECTORLOCATIONSKIND_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+  class Selector;
+  class SourceLocation;
+  class Expr;
+  class ParmVarDecl;
+
+/// \brief Whether all locations of the selector identifiers are in a
+/// "standard" position.
+enum SelectorLocationsKind {
+  /// \brief Non-standard.
+  SelLoc_NonStandard = 0,
+
+  /// \brief For nullary selectors, immediately before the end:
+  ///    "[foo release]" / "-(void)release;"
+  /// Or immediately before the arguments:
+  ///    "[foo first:1 second:2]" / "-(id)first:(int)x second:(int)y;
+  SelLoc_StandardNoSpace = 1,
+
+  /// \brief For nullary selectors, immediately before the end:
+  ///    "[foo release]" / "-(void)release;"
+  /// Or with a space between the arguments:
+  ///    "[foo first: 1 second: 2]" / "-(id)first: (int)x second: (int)y;
+  SelLoc_StandardWithSpace = 2
+};
+
+/// \brief Returns true if all \p SelLocs are in a "standard" location.
+SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
+                                              ArrayRef<SourceLocation> SelLocs,
+                                              ArrayRef<Expr *> Args,
+                                              SourceLocation EndLoc);
+
+/// \brief Get the "standard" location of a selector identifier, e.g:
+/// For nullary selectors, immediately before ']': "[foo release]"
+///
+/// \param WithArgSpace if true the standard location is with a space apart
+/// before arguments: "[foo first: 1 second: 2]"
+/// If false: "[foo first:1 second:2]"
+SourceLocation getStandardSelectorLoc(unsigned Index,
+                                      Selector Sel,
+                                      bool WithArgSpace,
+                                      ArrayRef<Expr *> Args,
+                                      SourceLocation EndLoc);
+
+/// \brief Returns true if all \p SelLocs are in a "standard" location.
+SelectorLocationsKind hasStandardSelectorLocs(Selector Sel,
+                                              ArrayRef<SourceLocation> SelLocs,
+                                              ArrayRef<ParmVarDecl *> Args,
+                                              SourceLocation EndLoc);
+
+/// \brief Get the "standard" location of a selector identifier, e.g:
+/// For nullary selectors, immediately before ']': "[foo release]"
+///
+/// \param WithArgSpace if true the standard location is with a space apart
+/// before arguments: "-(id)first: (int)x second: (int)y;"
+/// If false: "-(id)first:(int)x second:(int)y;"
+SourceLocation getStandardSelectorLoc(unsigned Index,
+                                      Selector Sel,
+                                      bool WithArgSpace,
+                                      ArrayRef<ParmVarDecl *> Args,
+                                      SourceLocation EndLoc);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
new file mode 100644
index 0000000..fb94097
--- /dev/null
+++ b/include/clang/AST/Stmt.h
@@ -0,0 +1,2178 @@
+//===--- Stmt.h - Classes for representing statements -----------*- 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 Stmt interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_H
+#define LLVM_CLANG_AST_STMT_H
+
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/StmtIterator.h"
+#include "clang/Basic/CapturedStmt.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <string>
+
+namespace llvm {
+  class FoldingSetNodeID;
+}
+
+namespace clang {
+  class ASTContext;
+  class Attr;
+  class CapturedDecl;
+  class Decl;
+  class Expr;
+  class IdentifierInfo;
+  class LabelDecl;
+  class ParmVarDecl;
+  class PrinterHelper;
+  struct PrintingPolicy;
+  class QualType;
+  class RecordDecl;
+  class SourceManager;
+  class StringLiteral;
+  class SwitchStmt;
+  class Token;
+  class VarDecl;
+
+  //===--------------------------------------------------------------------===//
+  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
+  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
+  //  references to children (to be compatible with StmtIterator).
+  //===--------------------------------------------------------------------===//
+
+  class Stmt;
+  class Expr;
+
+  class ExprIterator {
+    Stmt** I;
+  public:
+    ExprIterator(Stmt** i) : I(i) {}
+    ExprIterator() : I(nullptr) {}
+    ExprIterator& operator++() { ++I; return *this; }
+    ExprIterator operator-(size_t i) { return I-i; }
+    ExprIterator operator+(size_t i) { return I+i; }
+    Expr* operator[](size_t idx);
+    // FIXME: Verify that this will correctly return a signed distance.
+    signed operator-(const ExprIterator& R) const { return I - R.I; }
+    Expr* operator*() const;
+    Expr* operator->() const;
+    bool operator==(const ExprIterator& R) const { return I == R.I; }
+    bool operator!=(const ExprIterator& R) const { return I != R.I; }
+    bool operator>(const ExprIterator& R) const { return I > R.I; }
+    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
+  };
+
+  class ConstExprIterator {
+    const Stmt * const *I;
+  public:
+    ConstExprIterator(const Stmt * const *i) : I(i) {}
+    ConstExprIterator() : I(nullptr) {}
+    ConstExprIterator& operator++() { ++I; return *this; }
+    ConstExprIterator operator+(size_t i) const { return I+i; }
+    ConstExprIterator operator-(size_t i) const { return I-i; }
+    const Expr * operator[](size_t idx) const;
+    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
+    const Expr * operator*() const;
+    const Expr * operator->() const;
+    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
+    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
+    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
+    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
+  };
+
+//===----------------------------------------------------------------------===//
+// AST classes for statements.
+//===----------------------------------------------------------------------===//
+
+/// Stmt - This represents one statement.
+///
+class Stmt {
+public:
+  enum StmtClass {
+    NoStmtClass = 0,
+#define STMT(CLASS, PARENT) CLASS##Class,
+#define STMT_RANGE(BASE, FIRST, LAST) \
+        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
+#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
+        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
+#define ABSTRACT_STMT(STMT)
+#include "clang/AST/StmtNodes.inc"
+  };
+
+  // Make vanilla 'new' and 'delete' illegal for Stmts.
+protected:
+  void* operator new(size_t bytes) throw() {
+    llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
+  }
+  void operator delete(void* data) throw() {
+    llvm_unreachable("Stmts cannot be released with regular 'delete'.");
+  }
+
+  class StmtBitfields {
+    friend class Stmt;
+
+    /// \brief The statement class.
+    unsigned sClass : 8;
+  };
+  enum { NumStmtBits = 8 };
+
+  class CompoundStmtBitfields {
+    friend class CompoundStmt;
+    unsigned : NumStmtBits;
+
+    unsigned NumStmts : 32 - NumStmtBits;
+  };
+
+  class ExprBitfields {
+    friend class Expr;
+    friend class DeclRefExpr; // computeDependence
+    friend class InitListExpr; // ctor
+    friend class DesignatedInitExpr; // ctor
+    friend class BlockDeclRefExpr; // ctor
+    friend class ASTStmtReader; // deserialization
+    friend class CXXNewExpr; // ctor
+    friend class DependentScopeDeclRefExpr; // ctor
+    friend class CXXConstructExpr; // ctor
+    friend class CallExpr; // ctor
+    friend class OffsetOfExpr; // ctor
+    friend class ObjCMessageExpr; // ctor
+    friend class ObjCArrayLiteral; // ctor
+    friend class ObjCDictionaryLiteral; // ctor
+    friend class ShuffleVectorExpr; // ctor
+    friend class ParenListExpr; // ctor
+    friend class CXXUnresolvedConstructExpr; // ctor
+    friend class CXXDependentScopeMemberExpr; // ctor
+    friend class OverloadExpr; // ctor
+    friend class PseudoObjectExpr; // ctor
+    friend class AtomicExpr; // ctor
+    unsigned : NumStmtBits;
+
+    unsigned ValueKind : 2;
+    unsigned ObjectKind : 2;
+    unsigned TypeDependent : 1;
+    unsigned ValueDependent : 1;
+    unsigned InstantiationDependent : 1;
+    unsigned ContainsUnexpandedParameterPack : 1;
+  };
+  enum { NumExprBits = 16 };
+
+  class CharacterLiteralBitfields {
+    friend class CharacterLiteral;
+    unsigned : NumExprBits;
+
+    unsigned Kind : 2;
+  };
+
+  enum APFloatSemantics {
+    IEEEhalf,
+    IEEEsingle,
+    IEEEdouble,
+    x87DoubleExtended,
+    IEEEquad,
+    PPCDoubleDouble
+  };
+
+  class FloatingLiteralBitfields {
+    friend class FloatingLiteral;
+    unsigned : NumExprBits;
+
+    unsigned Semantics : 3; // Provides semantics for APFloat construction
+    unsigned IsExact : 1;
+  };
+
+  class UnaryExprOrTypeTraitExprBitfields {
+    friend class UnaryExprOrTypeTraitExpr;
+    unsigned : NumExprBits;
+
+    unsigned Kind : 2;
+    unsigned IsType : 1; // true if operand is a type, false if an expression.
+  };
+
+  class DeclRefExprBitfields {
+    friend class DeclRefExpr;
+    friend class ASTStmtReader; // deserialization
+    unsigned : NumExprBits;
+
+    unsigned HasQualifier : 1;
+    unsigned HasTemplateKWAndArgsInfo : 1;
+    unsigned HasFoundDecl : 1;
+    unsigned HadMultipleCandidates : 1;
+    unsigned RefersToEnclosingLocal : 1;
+  };
+
+  class CastExprBitfields {
+    friend class CastExpr;
+    unsigned : NumExprBits;
+
+    unsigned Kind : 6;
+    unsigned BasePathSize : 32 - 6 - NumExprBits;
+  };
+
+  class CallExprBitfields {
+    friend class CallExpr;
+    unsigned : NumExprBits;
+
+    unsigned NumPreArgs : 1;
+  };
+
+  class ExprWithCleanupsBitfields {
+    friend class ExprWithCleanups;
+    friend class ASTStmtReader; // deserialization
+
+    unsigned : NumExprBits;
+
+    unsigned NumObjects : 32 - NumExprBits;
+  };
+
+  class PseudoObjectExprBitfields {
+    friend class PseudoObjectExpr;
+    friend class ASTStmtReader; // deserialization
+
+    unsigned : NumExprBits;
+
+    // These don't need to be particularly wide, because they're
+    // strictly limited by the forms of expressions we permit.
+    unsigned NumSubExprs : 8;
+    unsigned ResultIndex : 32 - 8 - NumExprBits;
+  };
+
+  class ObjCIndirectCopyRestoreExprBitfields {
+    friend class ObjCIndirectCopyRestoreExpr;
+    unsigned : NumExprBits;
+
+    unsigned ShouldCopy : 1;
+  };
+
+  class InitListExprBitfields {
+    friend class InitListExpr;
+
+    unsigned : NumExprBits;
+
+    /// Whether this initializer list originally had a GNU array-range
+    /// designator in it. This is a temporary marker used by CodeGen.
+    unsigned HadArrayRangeDesignator : 1;
+  };
+
+  class TypeTraitExprBitfields {
+    friend class TypeTraitExpr;
+    friend class ASTStmtReader;
+    friend class ASTStmtWriter;
+    
+    unsigned : NumExprBits;
+    
+    /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
+    unsigned Kind : 8;
+    
+    /// \brief If this expression is not value-dependent, this indicates whether
+    /// the trait evaluated true or false.
+    unsigned Value : 1;
+
+    /// \brief The number of arguments to this type trait.
+    unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
+  };
+
+  union {
+    // FIXME: this is wasteful on 64-bit platforms.
+    void *Aligner;
+
+    StmtBitfields StmtBits;
+    CompoundStmtBitfields CompoundStmtBits;
+    ExprBitfields ExprBits;
+    CharacterLiteralBitfields CharacterLiteralBits;
+    FloatingLiteralBitfields FloatingLiteralBits;
+    UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
+    DeclRefExprBitfields DeclRefExprBits;
+    CastExprBitfields CastExprBits;
+    CallExprBitfields CallExprBits;
+    ExprWithCleanupsBitfields ExprWithCleanupsBits;
+    PseudoObjectExprBitfields PseudoObjectExprBits;
+    ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
+    InitListExprBitfields InitListExprBits;
+    TypeTraitExprBitfields TypeTraitExprBits;
+  };
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+public:
+  // Only allow allocation of Stmts using the allocator in ASTContext
+  // or by doing a placement new.
+  void* operator new(size_t bytes, const ASTContext& C,
+                     unsigned alignment = 8);
+
+  void* operator new(size_t bytes, const ASTContext* C,
+                     unsigned alignment = 8) {
+    return operator new(bytes, *C, alignment);
+  }
+
+  void* operator new(size_t bytes, void* mem) throw() {
+    return mem;
+  }
+
+  void operator delete(void*, const ASTContext&, unsigned) throw() { }
+  void operator delete(void*, const ASTContext*, unsigned) throw() { }
+  void operator delete(void*, size_t) throw() { }
+  void operator delete(void*, void*) throw() { }
+
+public:
+  /// \brief A placeholder type used to construct an empty shell of a
+  /// type, that will be filled in later (e.g., by some
+  /// de-serialization).
+  struct EmptyShell { };
+
+private:
+  /// \brief Whether statistic collection is enabled.
+  static bool StatisticsEnabled;
+
+protected:
+  /// \brief Construct an empty statement.
+  explicit Stmt(StmtClass SC, EmptyShell) {
+    StmtBits.sClass = SC;
+    if (StatisticsEnabled) Stmt::addStmtClass(SC);
+  }
+
+public:
+  Stmt(StmtClass SC) {
+    StmtBits.sClass = SC;
+    if (StatisticsEnabled) Stmt::addStmtClass(SC);
+  }
+
+  StmtClass getStmtClass() const {
+    return static_cast<StmtClass>(StmtBits.sClass);
+  }
+  const char *getStmtClassName() const;
+
+  /// SourceLocation tokens are not useful in isolation - they are low level
+  /// value objects created/interpreted by SourceManager. We assume AST
+  /// clients will have a pointer to the respective SourceManager.
+  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceLocation getLocStart() const LLVM_READONLY;
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  // global temp stats (until we have a per-module visitor)
+  static void addStmtClass(const StmtClass s);
+  static void EnableStatistics();
+  static void PrintStats();
+
+  /// \brief Dumps the specified AST fragment and all subtrees to
+  /// \c llvm::errs().
+  void dump() const;
+  void dump(SourceManager &SM) const;
+  void dump(raw_ostream &OS, SourceManager &SM) const;
+
+  /// dumpColor - same as dump(), but forces color highlighting.
+  void dumpColor() const;
+
+  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
+  /// back to its original source language syntax.
+  void dumpPretty(const ASTContext &Context) const;
+  void printPretty(raw_ostream &OS, PrinterHelper *Helper,
+                   const PrintingPolicy &Policy,
+                   unsigned Indentation = 0) const;
+
+  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
+  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
+  void viewAST() const;
+
+  /// Skip past any implicit AST nodes which might surround this
+  /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
+  Stmt *IgnoreImplicit();
+
+  const Stmt *stripLabelLikeStatements() const;
+  Stmt *stripLabelLikeStatements() {
+    return const_cast<Stmt*>(
+      const_cast<const Stmt*>(this)->stripLabelLikeStatements());
+  }
+
+  /// Child Iterators: All subclasses must implement 'children'
+  /// to permit easy iteration over the substatements/subexpessions of an
+  /// AST node.  This permits easy iteration over all nodes in the AST.
+  typedef StmtIterator       child_iterator;
+  typedef ConstStmtIterator  const_child_iterator;
+
+  typedef StmtRange          child_range;
+  typedef ConstStmtRange     const_child_range;
+
+  child_range children();
+  const_child_range children() const {
+    return const_cast<Stmt*>(this)->children();
+  }
+
+  child_iterator child_begin() { return children().first; }
+  child_iterator child_end() { return children().second; }
+
+  const_child_iterator child_begin() const { return children().first; }
+  const_child_iterator child_end() const { return children().second; }
+
+  /// \brief Produce a unique representation of the given statement.
+  ///
+  /// \param ID once the profiling operation is complete, will contain
+  /// the unique representation of the given statement.
+  ///
+  /// \param Context the AST context in which the statement resides
+  ///
+  /// \param Canonical whether the profile should be based on the canonical
+  /// representation of this statement (e.g., where non-type template
+  /// parameters are identified by index/level rather than their
+  /// declaration pointers) or the exact representation of the statement as
+  /// written in the source.
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+               bool Canonical) const;
+};
+
+/// DeclStmt - Adaptor class for mixing declarations with statements and
+/// expressions. For example, CompoundStmt mixes statements, expressions
+/// and declarations (variables, types). Another example is ForStmt, where
+/// the first statement can be an expression or a declaration.
+///
+class DeclStmt : public Stmt {
+  DeclGroupRef DG;
+  SourceLocation StartLoc, EndLoc;
+
+public:
+  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
+           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
+                                    StartLoc(startLoc), EndLoc(endLoc) {}
+
+  /// \brief Build an empty declaration statement.
+  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
+
+  /// isSingleDecl - This method returns true if this DeclStmt refers
+  /// to a single Decl.
+  bool isSingleDecl() const {
+    return DG.isSingleDecl();
+  }
+
+  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
+  Decl *getSingleDecl() { return DG.getSingleDecl(); }
+
+  const DeclGroupRef getDeclGroup() const { return DG; }
+  DeclGroupRef getDeclGroup() { return DG; }
+  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
+
+  SourceLocation getStartLoc() const { return StartLoc; }
+  void setStartLoc(SourceLocation L) { StartLoc = L; }
+  SourceLocation getEndLoc() const { return EndLoc; }
+  void setEndLoc(SourceLocation L) { EndLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DeclStmtClass;
+  }
+
+  // Iterators over subexpressions.
+  child_range children() {
+    return child_range(child_iterator(DG.begin(), DG.end()),
+                       child_iterator(DG.end(), DG.end()));
+  }
+
+  typedef DeclGroupRef::iterator decl_iterator;
+  typedef DeclGroupRef::const_iterator const_decl_iterator;
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+  typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
+
+  decl_range decls() { return decl_range(decl_begin(), decl_end()); }
+  decl_const_range decls() const {
+    return decl_const_range(decl_begin(), decl_end());
+  }
+  decl_iterator decl_begin() { return DG.begin(); }
+  decl_iterator decl_end() { return DG.end(); }
+  const_decl_iterator decl_begin() const { return DG.begin(); }
+  const_decl_iterator decl_end() const { return DG.end(); }
+
+  typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
+  reverse_decl_iterator decl_rbegin() {
+    return reverse_decl_iterator(decl_end());
+  }
+  reverse_decl_iterator decl_rend() {
+    return reverse_decl_iterator(decl_begin());
+  }
+};
+
+/// NullStmt - This is the null statement ";": C99 6.8.3p3.
+///
+class NullStmt : public Stmt {
+  SourceLocation SemiLoc;
+
+  /// \brief True if the null statement was preceded by an empty macro, e.g:
+  /// @code
+  ///   #define CALL(x)
+  ///   CALL(0);
+  /// @endcode
+  bool HasLeadingEmptyMacro;
+public:
+  NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
+    : Stmt(NullStmtClass), SemiLoc(L),
+      HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
+
+  /// \brief Build an empty null statement.
+  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
+      HasLeadingEmptyMacro(false) { }
+
+  SourceLocation getSemiLoc() const { return SemiLoc; }
+  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
+
+  bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == NullStmtClass;
+  }
+
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+};
+
+/// CompoundStmt - This represents a group of statements like { stmt stmt }.
+///
+class CompoundStmt : public Stmt {
+  Stmt** Body;
+  SourceLocation LBracLoc, RBracLoc;
+public:
+  CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
+               SourceLocation LB, SourceLocation RB);
+
+  // \brief Build an empty compound statement with a location.
+  explicit CompoundStmt(SourceLocation Loc)
+    : Stmt(CompoundStmtClass), Body(nullptr), LBracLoc(Loc), RBracLoc(Loc) {
+    CompoundStmtBits.NumStmts = 0;
+  }
+
+  // \brief Build an empty compound statement.
+  explicit CompoundStmt(EmptyShell Empty)
+    : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
+    CompoundStmtBits.NumStmts = 0;
+  }
+
+  void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts);
+
+  bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
+  unsigned size() const { return CompoundStmtBits.NumStmts; }
+
+  typedef Stmt** body_iterator;
+  typedef llvm::iterator_range<body_iterator> body_range;
+
+  body_range body() { return body_range(body_begin(), body_end()); }
+  body_iterator body_begin() { return Body; }
+  body_iterator body_end() { return Body + size(); }
+  Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
+
+  void setLastStmt(Stmt *S) {
+    assert(!body_empty() && "setLastStmt");
+    Body[size()-1] = S;
+  }
+
+  typedef Stmt* const * const_body_iterator;
+  typedef llvm::iterator_range<const_body_iterator> body_const_range;
+
+  body_const_range body() const {
+    return body_const_range(body_begin(), body_end());
+  }
+  const_body_iterator body_begin() const { return Body; }
+  const_body_iterator body_end() const { return Body + size(); }
+  const Stmt *body_back() const {
+    return !body_empty() ? Body[size() - 1] : nullptr;
+  }
+
+  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
+  reverse_body_iterator body_rbegin() {
+    return reverse_body_iterator(body_end());
+  }
+  reverse_body_iterator body_rend() {
+    return reverse_body_iterator(body_begin());
+  }
+
+  typedef std::reverse_iterator<const_body_iterator>
+          const_reverse_body_iterator;
+
+  const_reverse_body_iterator body_rbegin() const {
+    return const_reverse_body_iterator(body_end());
+  }
+
+  const_reverse_body_iterator body_rend() const {
+    return const_reverse_body_iterator(body_begin());
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
+
+  SourceLocation getLBracLoc() const { return LBracLoc; }
+  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
+  SourceLocation getRBracLoc() const { return RBracLoc; }
+  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CompoundStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(Body, Body + CompoundStmtBits.NumStmts);
+  }
+
+  const_child_range children() const {
+    return child_range(Body, Body + CompoundStmtBits.NumStmts);
+  }
+};
+
+// SwitchCase is the base class for CaseStmt and DefaultStmt,
+class SwitchCase : public Stmt {
+protected:
+  // A pointer to the following CaseStmt or DefaultStmt class,
+  // used by SwitchStmt.
+  SwitchCase *NextSwitchCase;
+  SourceLocation KeywordLoc;
+  SourceLocation ColonLoc;
+
+  SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
+    : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
+  }
+
+  SwitchCase(StmtClass SC, EmptyShell)
+    : Stmt(SC), NextSwitchCase(nullptr) {}
+
+public:
+  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
+
+  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
+
+  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
+
+  SourceLocation getKeywordLoc() const { return KeywordLoc; }
+  void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  Stmt *getSubStmt();
+  const Stmt *getSubStmt() const {
+    return const_cast<SwitchCase*>(this)->getSubStmt();
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CaseStmtClass ||
+           T->getStmtClass() == DefaultStmtClass;
+  }
+};
+
+class CaseStmt : public SwitchCase {
+  enum { LHS, RHS, SUBSTMT, END_EXPR };
+  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
+                             // GNU "case 1 ... 4" extension
+  SourceLocation EllipsisLoc;
+public:
+  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
+           SourceLocation ellipsisLoc, SourceLocation colonLoc)
+    : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
+    SubExprs[SUBSTMT] = nullptr;
+    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
+    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
+    EllipsisLoc = ellipsisLoc;
+  }
+
+  /// \brief Build an empty switch case statement.
+  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
+
+  SourceLocation getCaseLoc() const { return KeywordLoc; }
+  void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
+  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
+  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
+
+  const Expr *getLHS() const {
+    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
+  }
+  const Expr *getRHS() const {
+    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
+  }
+  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
+
+  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
+  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
+  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    // Handle deeply nested case statements with iteration instead of recursion.
+    const CaseStmt *CS = this;
+    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
+      CS = CS2;
+
+    return CS->getSubStmt()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CaseStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
+  }
+};
+
+class DefaultStmt : public SwitchCase {
+  Stmt* SubStmt;
+public:
+  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
+    SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
+
+  /// \brief Build an empty default statement.
+  explicit DefaultStmt(EmptyShell Empty)
+    : SwitchCase(DefaultStmtClass, Empty) { }
+
+  Stmt *getSubStmt() { return SubStmt; }
+  const Stmt *getSubStmt() const { return SubStmt; }
+  void setSubStmt(Stmt *S) { SubStmt = S; }
+
+  SourceLocation getDefaultLoc() const { return KeywordLoc; }
+  void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DefaultStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
+};
+
+inline SourceLocation SwitchCase::getLocEnd() const {
+  if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
+    return CS->getLocEnd();
+  return cast<DefaultStmt>(this)->getLocEnd();
+}
+
+/// LabelStmt - Represents a label, which has a substatement.  For example:
+///    foo: return;
+///
+class LabelStmt : public Stmt {
+  LabelDecl *TheDecl;
+  Stmt *SubStmt;
+  SourceLocation IdentLoc;
+public:
+  LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
+    : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) {
+  }
+
+  // \brief Build an empty label statement.
+  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
+
+  SourceLocation getIdentLoc() const { return IdentLoc; }
+  LabelDecl *getDecl() const { return TheDecl; }
+  void setDecl(LabelDecl *D) { TheDecl = D; }
+  const char *getName() const;
+  Stmt *getSubStmt() { return SubStmt; }
+  const Stmt *getSubStmt() const { return SubStmt; }
+  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
+  void setSubStmt(Stmt *SS) { SubStmt = SS; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
+  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == LabelStmtClass;
+  }
+};
+
+
+/// \brief Represents an attribute applied to a statement.
+///
+/// Represents an attribute applied to a statement. For example:
+///   [[omp::for(...)]] for (...) { ... }
+///
+class AttributedStmt : public Stmt {
+  Stmt *SubStmt;
+  SourceLocation AttrLoc;
+  unsigned NumAttrs;
+
+  friend class ASTStmtReader;
+
+  AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
+    : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
+      NumAttrs(Attrs.size()) {
+    memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *));
+  }
+
+  explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
+    : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
+    memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *));
+  }
+
+  Attr *const *getAttrArrayPtr() const {
+    return reinterpret_cast<Attr *const *>(this + 1);
+  }
+  Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); }
+
+public:
+  static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
+                                ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
+  // \brief Build an empty attributed statement.
+  static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
+
+  SourceLocation getAttrLoc() const { return AttrLoc; }
+  ArrayRef<const Attr*> getAttrs() const {
+    return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs);
+  }
+  Stmt *getSubStmt() { return SubStmt; }
+  const Stmt *getSubStmt() const { return SubStmt; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
+  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == AttributedStmtClass;
+  }
+};
+
+
+/// IfStmt - This represents an if/then/else.
+///
+class IfStmt : public Stmt {
+  enum { VAR, COND, THEN, ELSE, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+
+  SourceLocation IfLoc;
+  SourceLocation ElseLoc;
+
+public:
+  IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
+         Stmt *then, SourceLocation EL = SourceLocation(),
+         Stmt *elsev = nullptr);
+
+  /// \brief Build an empty if/then/else statement
+  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "if" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// if (int x = foo()) {
+  ///   printf("x is %d", x);
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(const ASTContext &C, VarDecl *V);
+
+  /// If this IfStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
+
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
+  const Stmt *getThen() const { return SubExprs[THEN]; }
+  void setThen(Stmt *S) { SubExprs[THEN] = S; }
+  const Stmt *getElse() const { return SubExprs[ELSE]; }
+  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  Stmt *getThen() { return SubExprs[THEN]; }
+  Stmt *getElse() { return SubExprs[ELSE]; }
+
+  SourceLocation getIfLoc() const { return IfLoc; }
+  void setIfLoc(SourceLocation L) { IfLoc = L; }
+  SourceLocation getElseLoc() const { return ElseLoc; }
+  void setElseLoc(SourceLocation L) { ElseLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    if (SubExprs[ELSE])
+      return SubExprs[ELSE]->getLocEnd();
+    else
+      return SubExprs[THEN]->getLocEnd();
+  }
+
+  // Iterators over subexpressions.  The iterators will include iterating
+  // over the initialization expression referenced by the condition variable.
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IfStmtClass;
+  }
+};
+
+/// SwitchStmt - This represents a 'switch' stmt.
+///
+class SwitchStmt : public Stmt {
+  enum { VAR, COND, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  // This points to a linked list of case and default statements.
+  SwitchCase *FirstCase;
+  SourceLocation SwitchLoc;
+
+  /// If the SwitchStmt is a switch on an enum value, this records whether
+  /// all the enum values were covered by CaseStmts.  This value is meant to
+  /// be a hint for possible clients.
+  unsigned AllEnumCasesCovered : 1;
+
+public:
+  SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
+
+  /// \brief Build a empty switch statement.
+  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "switch" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// switch (int x = foo()) {
+  ///   case 0: break;
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(const ASTContext &C, VarDecl *V);
+
+  /// If this SwitchStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
+
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+  SwitchCase *getSwitchCaseList() { return FirstCase; }
+
+  /// \brief Set the case list for this switch statement.
+  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
+
+  SourceLocation getSwitchLoc() const { return SwitchLoc; }
+  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
+
+  void setBody(Stmt *S, SourceLocation SL) {
+    SubExprs[BODY] = S;
+    SwitchLoc = SL;
+  }
+  void addSwitchCase(SwitchCase *SC) {
+    assert(!SC->getNextSwitchCase()
+           && "case/default already added to a switch");
+    SC->setNextSwitchCase(FirstCase);
+    FirstCase = SC;
+  }
+
+  /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
+  /// switch over an enum value then all cases have been explicitly covered.
+  void setAllEnumCasesCovered() {
+    AllEnumCasesCovered = 1;
+  }
+
+  /// Returns true if the SwitchStmt is a switch of an enum value and all cases
+  /// have been explicitly covered.
+  bool isAllEnumCasesCovered() const {
+    return (bool) AllEnumCasesCovered;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExprs[BODY]->getLocEnd();
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SwitchStmtClass;
+  }
+};
+
+
+/// WhileStmt - This represents a 'while' stmt.
+///
+class WhileStmt : public Stmt {
+  enum { VAR, COND, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation WhileLoc;
+public:
+  WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
+            SourceLocation WL);
+
+  /// \brief Build an empty while statement.
+  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
+
+  /// \brief Retrieve the variable declared in this "while" statement, if any.
+  ///
+  /// In the following example, "x" is the condition variable.
+  /// \code
+  /// while (int x = random()) {
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(const ASTContext &C, VarDecl *V);
+
+  /// If this WhileStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
+  }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getWhileLoc() const { return WhileLoc; }
+  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExprs[BODY]->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == WhileStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+/// DoStmt - This represents a 'do/while' stmt.
+///
+class DoStmt : public Stmt {
+  enum { BODY, COND, END_EXPR };
+  Stmt* SubExprs[END_EXPR];
+  SourceLocation DoLoc;
+  SourceLocation WhileLoc;
+  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
+
+public:
+  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
+         SourceLocation RP)
+    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
+    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+    SubExprs[BODY] = body;
+  }
+
+  /// \brief Build an empty do-while statement.
+  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getDoLoc() const { return DoLoc; }
+  void setDoLoc(SourceLocation L) { DoLoc = L; }
+  SourceLocation getWhileLoc() const { return WhileLoc; }
+  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == DoStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+
+/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
+/// the init/cond/inc parts of the ForStmt will be null if they were not
+/// specified in the source.
+///
+class ForStmt : public Stmt {
+  enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
+  SourceLocation ForLoc;
+  SourceLocation LParenLoc, RParenLoc;
+
+public:
+  ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
+          Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
+          SourceLocation RP);
+
+  /// \brief Build an empty for statement.
+  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
+
+  Stmt *getInit() { return SubExprs[INIT]; }
+
+  /// \brief Retrieve the variable declared in this "for" statement, if any.
+  ///
+  /// In the following example, "y" is the condition variable.
+  /// \code
+  /// for (int x = random(); int y = mangle(x); ++x) {
+  ///   // ...
+  /// }
+  /// \endcode
+  VarDecl *getConditionVariable() const;
+  void setConditionVariable(const ASTContext &C, VarDecl *V);
+
+  /// If this ForStmt has a condition variable, return the faux DeclStmt
+  /// associated with the creation of that condition variable.
+  const DeclStmt *getConditionVariableDeclStmt() const {
+    return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+  }
+
+  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
+  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+
+  const Stmt *getInit() const { return SubExprs[INIT]; }
+  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
+  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+
+  void setInit(Stmt *S) { SubExprs[INIT] = S; }
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation L) { ForLoc = L; }
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExprs[BODY]->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ForStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
+  }
+};
+
+/// GotoStmt - This represents a direct goto.
+///
+class GotoStmt : public Stmt {
+  LabelDecl *Label;
+  SourceLocation GotoLoc;
+  SourceLocation LabelLoc;
+public:
+  GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
+    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
+
+  /// \brief Build an empty goto statement.
+  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
+
+  LabelDecl *getLabel() const { return Label; }
+  void setLabel(LabelDecl *D) { Label = D; }
+
+  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getLabelLoc() const { return LabelLoc; }
+  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GotoStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// IndirectGotoStmt - This represents an indirect goto.
+///
+class IndirectGotoStmt : public Stmt {
+  SourceLocation GotoLoc;
+  SourceLocation StarLoc;
+  Stmt *Target;
+public:
+  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
+                   Expr *target)
+    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
+      Target((Stmt*)target) {}
+
+  /// \brief Build an empty indirect goto statement.
+  explicit IndirectGotoStmt(EmptyShell Empty)
+    : Stmt(IndirectGotoStmtClass, Empty) { }
+
+  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
+  SourceLocation getGotoLoc() const { return GotoLoc; }
+  void setStarLoc(SourceLocation L) { StarLoc = L; }
+  SourceLocation getStarLoc() const { return StarLoc; }
+
+  Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
+  const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
+  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
+
+  /// getConstantTarget - Returns the fixed target of this indirect
+  /// goto, if one exists.
+  LabelDecl *getConstantTarget();
+  const LabelDecl *getConstantTarget() const {
+    return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == IndirectGotoStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Target, &Target+1); }
+};
+
+
+/// ContinueStmt - This represents a continue.
+///
+class ContinueStmt : public Stmt {
+  SourceLocation ContinueLoc;
+public:
+  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
+
+  /// \brief Build an empty continue statement.
+  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
+
+  SourceLocation getContinueLoc() const { return ContinueLoc; }
+  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ContinueStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// BreakStmt - This represents a break.
+///
+class BreakStmt : public Stmt {
+  SourceLocation BreakLoc;
+public:
+  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
+
+  /// \brief Build an empty break statement.
+  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
+
+  SourceLocation getBreakLoc() const { return BreakLoc; }
+  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == BreakStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+
+/// ReturnStmt - This represents a return, optionally of an expression:
+///   return;
+///   return 4;
+///
+/// Note that GCC allows return with no argument in a function declared to
+/// return a value, and it allows returning a value in functions declared to
+/// return void.  We explicitly model this in the AST, which means you can't
+/// depend on the return type of the function and the presence of an argument.
+///
+class ReturnStmt : public Stmt {
+  Stmt *RetExpr;
+  SourceLocation RetLoc;
+  const VarDecl *NRVOCandidate;
+
+public:
+  ReturnStmt(SourceLocation RL)
+    : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL),
+      NRVOCandidate(nullptr) {}
+
+  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
+    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
+      NRVOCandidate(NRVOCandidate) {}
+
+  /// \brief Build an empty return expression.
+  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
+
+  const Expr *getRetValue() const;
+  Expr *getRetValue();
+  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
+
+  SourceLocation getReturnLoc() const { return RetLoc; }
+  void setReturnLoc(SourceLocation L) { RetLoc = L; }
+
+  /// \brief Retrieve the variable that might be used for the named return
+  /// value optimization.
+  ///
+  /// The optimization itself can only be performed if the variable is
+  /// also marked as an NRVO object.
+  const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
+  void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return RetExpr ? RetExpr->getLocEnd() : RetLoc;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ReturnStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
+    return child_range();
+  }
+};
+
+/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
+///
+class AsmStmt : public Stmt {
+protected:
+  SourceLocation AsmLoc;
+  /// \brief True if the assembly statement does not have any input or output
+  /// operands.
+  bool IsSimple;
+
+  /// \brief If true, treat this inline assembly as having side effects.
+  /// This assembly statement should not be optimized, deleted or moved.
+  bool IsVolatile;
+
+  unsigned NumOutputs;
+  unsigned NumInputs;
+  unsigned NumClobbers;
+
+  Stmt **Exprs;
+
+  AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
+          unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
+    Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
+    NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
+
+  friend class ASTStmtReader;
+
+public:
+  /// \brief Build an empty inline-assembly statement.
+  explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
+    Stmt(SC, Empty), Exprs(nullptr) { }
+
+  SourceLocation getAsmLoc() const { return AsmLoc; }
+  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
+
+  bool isSimple() const { return IsSimple; }
+  void setSimple(bool V) { IsSimple = V; }
+
+  bool isVolatile() const { return IsVolatile; }
+  void setVolatile(bool V) { IsVolatile = V; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+  //===--- Asm String Analysis ---===//
+
+  /// Assemble final IR asm string.
+  std::string generateAsmString(const ASTContext &C) const;
+
+  //===--- Output operands ---===//
+
+  unsigned getNumOutputs() const { return NumOutputs; }
+
+  /// getOutputConstraint - Return the constraint string for the specified
+  /// output operand.  All output constraints are known to be non-empty (either
+  /// '=' or '+').
+  StringRef getOutputConstraint(unsigned i) const;
+
+  /// isOutputPlusConstraint - Return true if the specified output constraint
+  /// is a "+" constraint (which is both an input and an output) or false if it
+  /// is an "=" constraint (just an output).
+  bool isOutputPlusConstraint(unsigned i) const {
+    return getOutputConstraint(i)[0] == '+';
+  }
+
+  const Expr *getOutputExpr(unsigned i) const;
+
+  /// getNumPlusOperands - Return the number of output operands that have a "+"
+  /// constraint.
+  unsigned getNumPlusOperands() const;
+
+  //===--- Input operands ---===//
+
+  unsigned getNumInputs() const { return NumInputs; }
+
+  /// getInputConstraint - Return the specified input constraint.  Unlike output
+  /// constraints, these can be empty.
+  StringRef getInputConstraint(unsigned i) const;
+  
+  const Expr *getInputExpr(unsigned i) const;
+
+  //===--- Other ---===//
+
+  unsigned getNumClobbers() const { return NumClobbers; }
+  StringRef getClobber(unsigned i) const;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GCCAsmStmtClass ||
+      T->getStmtClass() == MSAsmStmtClass;
+  }
+
+  // Input expr iterators.
+
+  typedef ExprIterator inputs_iterator;
+  typedef ConstExprIterator const_inputs_iterator;
+  typedef llvm::iterator_range<inputs_iterator> inputs_range;
+  typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
+
+  inputs_iterator begin_inputs() {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  inputs_iterator end_inputs() {
+    return &Exprs[0] + NumOutputs + NumInputs;
+  }
+
+  inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
+
+  const_inputs_iterator begin_inputs() const {
+    return &Exprs[0] + NumOutputs;
+  }
+
+  const_inputs_iterator end_inputs() const {
+    return &Exprs[0] + NumOutputs + NumInputs;
+  }
+
+  inputs_const_range inputs() const {
+    return inputs_const_range(begin_inputs(), end_inputs());
+  }
+
+  // Output expr iterators.
+
+  typedef ExprIterator outputs_iterator;
+  typedef ConstExprIterator const_outputs_iterator;
+  typedef llvm::iterator_range<outputs_iterator> outputs_range;
+  typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
+
+  outputs_iterator begin_outputs() {
+    return &Exprs[0];
+  }
+  outputs_iterator end_outputs() {
+    return &Exprs[0] + NumOutputs;
+  }
+  outputs_range outputs() {
+    return outputs_range(begin_outputs(), end_outputs());
+  }
+
+  const_outputs_iterator begin_outputs() const {
+    return &Exprs[0];
+  }
+  const_outputs_iterator end_outputs() const {
+    return &Exprs[0] + NumOutputs;
+  }
+  outputs_const_range outputs() const {
+    return outputs_const_range(begin_outputs(), end_outputs());
+  }
+
+  child_range children() {
+    return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
+  }
+};
+
+/// This represents a GCC inline-assembly statement extension.
+///
+class GCCAsmStmt : public AsmStmt {
+  SourceLocation RParenLoc;
+  StringLiteral *AsmStr;
+
+  // FIXME: If we wanted to, we could allocate all of these in one big array.
+  StringLiteral **Constraints;
+  StringLiteral **Clobbers;
+  IdentifierInfo **Names;
+
+  friend class ASTStmtReader;
+
+public:
+  GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
+             bool isvolatile, unsigned numoutputs, unsigned numinputs,
+             IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
+             StringLiteral *asmstr, unsigned numclobbers,
+             StringLiteral **clobbers, SourceLocation rparenloc);
+
+  /// \brief Build an empty inline-assembly statement.
+  explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
+    Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
+
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+  //===--- Asm String Analysis ---===//
+
+  const StringLiteral *getAsmString() const { return AsmStr; }
+  StringLiteral *getAsmString() { return AsmStr; }
+  void setAsmString(StringLiteral *E) { AsmStr = E; }
+
+  /// AsmStringPiece - this is part of a decomposed asm string specification
+  /// (for use with the AnalyzeAsmString function below).  An asm string is
+  /// considered to be a concatenation of these parts.
+  class AsmStringPiece {
+  public:
+    enum Kind {
+      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
+      Operand  // Operand reference, with optional modifier %c4.
+    };
+  private:
+    Kind MyKind;
+    std::string Str;
+    unsigned OperandNo;
+  public:
+    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
+    AsmStringPiece(unsigned OpNo, char Modifier)
+      : MyKind(Operand), Str(), OperandNo(OpNo) {
+      Str += Modifier;
+    }
+
+    bool isString() const { return MyKind == String; }
+    bool isOperand() const { return MyKind == Operand; }
+
+    const std::string &getString() const {
+      assert(isString());
+      return Str;
+    }
+
+    unsigned getOperandNo() const {
+      assert(isOperand());
+      return OperandNo;
+    }
+
+    /// getModifier - Get the modifier for this operand, if present.  This
+    /// returns '\0' if there was no modifier.
+    char getModifier() const {
+      assert(isOperand());
+      return Str[0];
+    }
+  };
+
+  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
+  /// it into pieces.  If the asm string is erroneous, emit errors and return
+  /// true, otherwise return false.  This handles canonicalization and
+  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
+  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
+  unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
+                            const ASTContext &C, unsigned &DiagOffs) const;
+
+  /// Assemble final IR asm string.
+  std::string generateAsmString(const ASTContext &C) const;
+
+  //===--- Output operands ---===//
+
+  IdentifierInfo *getOutputIdentifier(unsigned i) const {
+    return Names[i];
+  }
+
+  StringRef getOutputName(unsigned i) const {
+    if (IdentifierInfo *II = getOutputIdentifier(i))
+      return II->getName();
+
+    return StringRef();
+  }
+
+  StringRef getOutputConstraint(unsigned i) const;
+
+  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
+    return Constraints[i];
+  }
+  StringLiteral *getOutputConstraintLiteral(unsigned i) {
+    return Constraints[i];
+  }
+
+  Expr *getOutputExpr(unsigned i);
+
+  const Expr *getOutputExpr(unsigned i) const {
+    return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
+  }
+
+  //===--- Input operands ---===//
+
+  IdentifierInfo *getInputIdentifier(unsigned i) const {
+    return Names[i + NumOutputs];
+  }
+
+  StringRef getInputName(unsigned i) const {
+    if (IdentifierInfo *II = getInputIdentifier(i))
+      return II->getName();
+
+    return StringRef();
+  }
+
+  StringRef getInputConstraint(unsigned i) const;
+
+  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
+    return Constraints[i + NumOutputs];
+  }
+  StringLiteral *getInputConstraintLiteral(unsigned i) {
+    return Constraints[i + NumOutputs];
+  }
+
+  Expr *getInputExpr(unsigned i);
+  void setInputExpr(unsigned i, Expr *E);
+
+  const Expr *getInputExpr(unsigned i) const {
+    return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
+  }
+
+private:
+  void setOutputsAndInputsAndClobbers(const ASTContext &C,
+                                      IdentifierInfo **Names,
+                                      StringLiteral **Constraints,
+                                      Stmt **Exprs,
+                                      unsigned NumOutputs,
+                                      unsigned NumInputs,
+                                      StringLiteral **Clobbers,
+                                      unsigned NumClobbers);
+public:
+
+  //===--- Other ---===//
+
+  /// getNamedOperand - Given a symbolic operand reference like %[foo],
+  /// translate this into a numeric value needed to reference the same operand.
+  /// This returns -1 if the operand name is invalid.
+  int getNamedOperand(StringRef SymbolicName) const;
+
+  StringRef getClobber(unsigned i) const;
+  StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
+  const StringLiteral *getClobberStringLiteral(unsigned i) const {
+    return Clobbers[i];
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == GCCAsmStmtClass;
+  }
+};
+
+/// This represents a Microsoft inline-assembly statement extension.
+///
+class MSAsmStmt : public AsmStmt {
+  SourceLocation LBraceLoc, EndLoc;
+  StringRef AsmStr;
+
+  unsigned NumAsmToks;
+
+  Token *AsmToks;
+  StringRef *Constraints;
+  StringRef *Clobbers;
+
+  friend class ASTStmtReader;
+
+public:
+  MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
+            SourceLocation lbraceloc, bool issimple, bool isvolatile,
+            ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
+            ArrayRef<StringRef> constraints,
+            ArrayRef<Expr*> exprs, StringRef asmstr,
+            ArrayRef<StringRef> clobbers, SourceLocation endloc);
+
+  /// \brief Build an empty MS-style inline-assembly statement.
+  explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
+    NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
+
+  SourceLocation getLBraceLoc() const { return LBraceLoc; }
+  void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
+  SourceLocation getEndLoc() const { return EndLoc; }
+  void setEndLoc(SourceLocation L) { EndLoc = L; }
+
+  bool hasBraces() const { return LBraceLoc.isValid(); }
+
+  unsigned getNumAsmToks() { return NumAsmToks; }
+  Token *getAsmToks() { return AsmToks; }
+
+  //===--- Asm String Analysis ---===//
+  StringRef getAsmString() const { return AsmStr; }
+
+  /// Assemble final IR asm string.
+  std::string generateAsmString(const ASTContext &C) const;
+
+  //===--- Output operands ---===//
+
+  StringRef getOutputConstraint(unsigned i) const {
+    assert(i < NumOutputs);
+    return Constraints[i];
+  }
+
+  Expr *getOutputExpr(unsigned i);
+
+  const Expr *getOutputExpr(unsigned i) const {
+    return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
+  }
+
+  //===--- Input operands ---===//
+
+  StringRef getInputConstraint(unsigned i) const {
+    assert(i < NumInputs);
+    return Constraints[i + NumOutputs];
+  }
+
+  Expr *getInputExpr(unsigned i);
+  void setInputExpr(unsigned i, Expr *E);
+
+  const Expr *getInputExpr(unsigned i) const {
+    return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
+  }
+
+  //===--- Other ---===//
+
+  ArrayRef<StringRef> getAllConstraints() const {
+    return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs);
+  }
+  ArrayRef<StringRef> getClobbers() const {
+    return ArrayRef<StringRef>(Clobbers, NumClobbers);
+  }
+  ArrayRef<Expr*> getAllExprs() const {
+    return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs),
+                           NumInputs + NumOutputs);
+  }
+
+  StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
+
+private:
+  void initialize(const ASTContext &C, StringRef AsmString,
+                  ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
+                  ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
+public:
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MSAsmStmtClass;
+  }
+
+  child_range children() {
+    return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
+  }
+};
+
+class SEHExceptStmt : public Stmt {
+  SourceLocation  Loc;
+  Stmt           *Children[2];
+
+  enum { FILTER_EXPR, BLOCK };
+
+  SEHExceptStmt(SourceLocation Loc,
+                Expr *FilterExpr,
+                Stmt *Block);
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
+
+public:
+  static SEHExceptStmt* Create(const ASTContext &C,
+                               SourceLocation ExceptLoc,
+                               Expr *FilterExpr,
+                               Stmt *Block);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  SourceLocation getExceptLoc() const { return Loc; }
+  SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
+
+  Expr *getFilterExpr() const {
+    return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
+  }
+
+  CompoundStmt *getBlock() const {
+    return cast<CompoundStmt>(Children[BLOCK]);
+  }
+
+  child_range children() {
+    return child_range(Children,Children+2);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHExceptStmtClass;
+  }
+
+};
+
+class SEHFinallyStmt : public Stmt {
+  SourceLocation  Loc;
+  Stmt           *Block;
+
+  SEHFinallyStmt(SourceLocation Loc,
+                 Stmt *Block);
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
+
+public:
+  static SEHFinallyStmt* Create(const ASTContext &C,
+                                SourceLocation FinallyLoc,
+                                Stmt *Block);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  SourceLocation getFinallyLoc() const { return Loc; }
+  SourceLocation getEndLoc() const { return Block->getLocEnd(); }
+
+  CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
+
+  child_range children() {
+    return child_range(&Block,&Block+1);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHFinallyStmtClass;
+  }
+
+};
+
+class SEHTryStmt : public Stmt {
+  bool            IsCXXTry;
+  SourceLocation  TryLoc;
+  Stmt           *Children[2];
+  int             HandlerIndex;
+  int             HandlerParentIndex;
+
+  enum { TRY = 0, HANDLER = 1 };
+
+  SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
+             SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler,
+             int HandlerIndex, int HandlerParentIndex);
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+  explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
+
+public:
+  static SEHTryStmt *Create(const ASTContext &C, bool isCXXTry,
+                            SourceLocation TryLoc, Stmt *TryBlock,
+                            Stmt *Handler, int HandlerIndex,
+                            int HandlerParentIndex);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  SourceLocation getTryLoc() const { return TryLoc; }
+  SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
+
+  bool getIsCXXTry() const { return IsCXXTry; }
+
+  CompoundStmt* getTryBlock() const {
+    return cast<CompoundStmt>(Children[TRY]);
+  }
+
+  Stmt *getHandler() const { return Children[HANDLER]; }
+
+  /// Returns 0 if not defined
+  SEHExceptStmt  *getExceptHandler() const;
+  SEHFinallyStmt *getFinallyHandler() const;
+
+  child_range children() {
+    return child_range(Children,Children+2);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHTryStmtClass;
+  }
+
+  int getHandlerIndex() const { return HandlerIndex; }
+  int getHandlerParentIndex() const { return HandlerParentIndex; }
+};
+
+/// Represents a __leave statement.
+///
+class SEHLeaveStmt : public Stmt {
+  SourceLocation LeaveLoc;
+public:
+  explicit SEHLeaveStmt(SourceLocation LL)
+      : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
+
+  /// \brief Build an empty __leave statement.
+  explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
+
+  SourceLocation getLeaveLoc() const { return LeaveLoc; }
+  void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHLeaveStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
+};
+
+/// \brief This captures a statement into a function. For example, the following
+/// pragma annotated compound statement can be represented as a CapturedStmt,
+/// and this compound statement is the body of an anonymous outlined function.
+/// @code
+/// #pragma omp parallel
+/// {
+///   compute();
+/// }
+/// @endcode
+class CapturedStmt : public Stmt {
+public:
+  /// \brief The different capture forms: by 'this' or by reference, etc.
+  enum VariableCaptureKind {
+    VCK_This,
+    VCK_ByRef
+  };
+
+  /// \brief Describes the capture of either a variable or 'this'.
+  class Capture {
+    llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind;
+    SourceLocation Loc;
+
+  public:
+    /// \brief Create a new capture.
+    ///
+    /// \param Loc The source location associated with this capture.
+    ///
+    /// \param Kind The kind of capture (this, ByRef, ...).
+    ///
+    /// \param Var The variable being captured, or null if capturing this.
+    ///
+    Capture(SourceLocation Loc, VariableCaptureKind Kind,
+            VarDecl *Var = nullptr)
+      : VarAndKind(Var, Kind), Loc(Loc) {
+      switch (Kind) {
+      case VCK_This:
+        assert(!Var && "'this' capture cannot have a variable!");
+        break;
+      case VCK_ByRef:
+        assert(Var && "capturing by reference must have a variable!");
+        break;
+      }
+    }
+
+    /// \brief Determine the kind of capture.
+    VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); }
+
+    /// \brief Retrieve the source location at which the variable or 'this' was
+    /// first used.
+    SourceLocation getLocation() const { return Loc; }
+
+    /// \brief Determine whether this capture handles the C++ 'this' pointer.
+    bool capturesThis() const { return getCaptureKind() == VCK_This; }
+
+    /// \brief Determine whether this capture handles a variable.
+    bool capturesVariable() const { return getCaptureKind() != VCK_This; }
+
+    /// \brief Retrieve the declaration of the variable being captured.
+    ///
+    /// This operation is only valid if this capture does not capture 'this'.
+    VarDecl *getCapturedVar() const {
+      assert(!capturesThis() && "No variable available for 'this' capture");
+      return VarAndKind.getPointer();
+    }
+    friend class ASTStmtReader;
+  };
+
+private:
+  /// \brief The number of variable captured, including 'this'.
+  unsigned NumCaptures;
+
+  /// \brief The pointer part is the implicit the outlined function and the 
+  /// int part is the captured region kind, 'CR_Default' etc.
+  llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
+
+  /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
+  RecordDecl *TheRecordDecl;
+
+  /// \brief Construct a captured statement.
+  CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
+               ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
+
+  /// \brief Construct an empty captured statement.
+  CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
+
+  Stmt **getStoredStmts() const {
+    return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1);
+  }
+
+  Capture *getStoredCaptures() const;
+
+  void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
+
+public:
+  static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
+                              CapturedRegionKind Kind,
+                              ArrayRef<Capture> Captures,
+                              ArrayRef<Expr *> CaptureInits,
+                              CapturedDecl *CD, RecordDecl *RD);
+
+  static CapturedStmt *CreateDeserialized(const ASTContext &Context,
+                                          unsigned NumCaptures);
+
+  /// \brief Retrieve the statement being captured.
+  Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
+  const Stmt *getCapturedStmt() const {
+    return const_cast<CapturedStmt *>(this)->getCapturedStmt();
+  }
+
+  /// \brief Retrieve the outlined function declaration.
+  CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); }
+  const CapturedDecl *getCapturedDecl() const {
+    return const_cast<CapturedStmt *>(this)->getCapturedDecl();
+  }
+
+  /// \brief Set the outlined function declaration.
+  void setCapturedDecl(CapturedDecl *D) {
+    assert(D && "null CapturedDecl");
+    CapDeclAndKind.setPointer(D);
+  }
+
+  /// \brief Retrieve the captured region kind.
+  CapturedRegionKind getCapturedRegionKind() const {
+    return CapDeclAndKind.getInt();
+  }
+
+  /// \brief Set the captured region kind.
+  void setCapturedRegionKind(CapturedRegionKind Kind) {
+    CapDeclAndKind.setInt(Kind);
+  }
+
+  /// \brief Retrieve the record declaration for captured variables.
+  const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
+
+  /// \brief Set the record declaration for captured variables.
+  void setCapturedRecordDecl(RecordDecl *D) {
+    assert(D && "null RecordDecl");
+    TheRecordDecl = D;
+  }
+
+  /// \brief True if this variable has been captured.
+  bool capturesVariable(const VarDecl *Var) const;
+
+  /// \brief An iterator that walks over the captures.
+  typedef Capture *capture_iterator;
+  typedef const Capture *const_capture_iterator;
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+  typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
+
+  capture_range captures() {
+    return capture_range(capture_begin(), capture_end());
+  }
+  capture_const_range captures() const {
+    return capture_const_range(capture_begin(), capture_end());
+  }
+
+  /// \brief Retrieve an iterator pointing to the first capture.
+  capture_iterator capture_begin() { return getStoredCaptures(); }
+  const_capture_iterator capture_begin() const { return getStoredCaptures(); }
+
+  /// \brief Retrieve an iterator pointing past the end of the sequence of
+  /// captures.
+  capture_iterator capture_end() const {
+    return getStoredCaptures() + NumCaptures;
+  }
+
+  /// \brief Retrieve the number of captures, including 'this'.
+  unsigned capture_size() const { return NumCaptures; }
+
+  /// \brief Iterator that walks over the capture initialization arguments.
+  typedef Expr **capture_init_iterator;
+  typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
+
+  capture_init_range capture_inits() const {
+    return capture_init_range(capture_init_begin(), capture_init_end());
+  }
+
+  /// \brief Retrieve the first initialization argument.
+  capture_init_iterator capture_init_begin() const {
+    return reinterpret_cast<Expr **>(getStoredStmts());
+  }
+
+  /// \brief Retrieve the iterator pointing one past the last initialization
+  /// argument.
+  capture_init_iterator capture_init_end() const {
+    return capture_init_begin() + NumCaptures;
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY {
+    return getCapturedStmt()->getLocStart();
+  }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getCapturedStmt()->getLocEnd();
+  }
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return getCapturedStmt()->getSourceRange();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CapturedStmtClass;
+  }
+
+  child_range children();
+
+  friend class ASTStmtReader;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
new file mode 100644
index 0000000..837dc45
--- /dev/null
+++ b/include/clang/AST/StmtCXX.h
@@ -0,0 +1,292 @@
+//===--- StmtCXX.h - Classes for representing C++ statements ----*- 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 C++ statement AST node classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTCXX_H
+#define LLVM_CLANG_AST_STMTCXX_H
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+class VarDecl;
+
+/// CXXCatchStmt - This represents a C++ catch block.
+///
+class CXXCatchStmt : public Stmt {
+  SourceLocation CatchLoc;
+  /// The exception-declaration of the type.
+  VarDecl *ExceptionDecl;
+  /// The handler block.
+  Stmt *HandlerBlock;
+
+public:
+  CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
+  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
+    HandlerBlock(handlerBlock) {}
+
+  CXXCatchStmt(EmptyShell Empty)
+  : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
+
+  SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return HandlerBlock->getLocEnd();
+  }
+
+  SourceLocation getCatchLoc() const { return CatchLoc; }
+  VarDecl *getExceptionDecl() const { return ExceptionDecl; }
+  QualType getCaughtType() const;
+  Stmt *getHandlerBlock() const { return HandlerBlock; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXCatchStmtClass;
+  }
+
+  child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
+
+  friend class ASTStmtReader;
+};
+
+/// CXXTryStmt - A C++ try block, including all handlers.
+///
+class CXXTryStmt : public Stmt {
+  SourceLocation TryLoc;
+  unsigned NumHandlers;
+
+  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+
+  CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
+    : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
+
+  Stmt const * const *getStmts() const {
+    return reinterpret_cast<Stmt const * const*>(this + 1);
+  }
+  Stmt **getStmts() {
+    return reinterpret_cast<Stmt **>(this + 1);
+  }
+
+public:
+  static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
+                            Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+
+  static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
+                            unsigned numHandlers);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  SourceLocation getTryLoc() const { return TryLoc; }
+  SourceLocation getEndLoc() const {
+    return getStmts()[NumHandlers]->getLocEnd();
+  }
+
+  CompoundStmt *getTryBlock() {
+    return cast<CompoundStmt>(getStmts()[0]);
+  }
+  const CompoundStmt *getTryBlock() const {
+    return cast<CompoundStmt>(getStmts()[0]);
+  }
+
+  unsigned getNumHandlers() const { return NumHandlers; }
+  CXXCatchStmt *getHandler(unsigned i) {
+    return cast<CXXCatchStmt>(getStmts()[i + 1]);
+  }
+  const CXXCatchStmt *getHandler(unsigned i) const {
+    return cast<CXXCatchStmt>(getStmts()[i + 1]);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXTryStmtClass;
+  }
+
+  child_range children() {
+    return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
+  }
+
+  friend class ASTStmtReader;
+};
+
+/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
+/// statement, represented as 'for (range-declarator : range-expression)'.
+///
+/// This is stored in a partially-desugared form to allow full semantic
+/// analysis of the constituent components. The original syntactic components
+/// can be extracted using getLoopVariable and getRangeInit.
+class CXXForRangeStmt : public Stmt {
+  enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
+  // SubExprs[RANGE] is an expression or declstmt.
+  // SubExprs[COND] and SubExprs[INC] are expressions.
+  Stmt *SubExprs[END];
+  SourceLocation ForLoc;
+  SourceLocation ColonLoc;
+  SourceLocation RParenLoc;
+public:
+  CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
+                  Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
+                  SourceLocation FL, SourceLocation CL, SourceLocation RPL);
+  CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
+
+
+  VarDecl *getLoopVariable();
+  Expr *getRangeInit();
+
+  const VarDecl *getLoopVariable() const;
+  const Expr *getRangeInit() const;
+
+
+  DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
+  DeclStmt *getBeginEndStmt() {
+    return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
+  }
+  Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
+  Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
+  DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
+  Stmt *getBody() { return SubExprs[BODY]; }
+
+  const DeclStmt *getRangeStmt() const {
+    return cast<DeclStmt>(SubExprs[RANGE]);
+  }
+  const DeclStmt *getBeginEndStmt() const {
+    return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
+  }
+  const Expr *getCond() const {
+    return cast_or_null<Expr>(SubExprs[COND]);
+  }
+  const Expr *getInc() const {
+    return cast_or_null<Expr>(SubExprs[INC]);
+  }
+  const DeclStmt *getLoopVarStmt() const {
+    return cast<DeclStmt>(SubExprs[LOOPVAR]);
+  }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+
+  void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
+  void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
+  void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
+  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
+  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
+  void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExprs[BODY]->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == CXXForRangeStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[END]);
+  }
+};
+
+/// \brief Representation of a Microsoft __if_exists or __if_not_exists
+/// statement with a dependent name.
+///
+/// The __if_exists statement can be used to include a sequence of statements
+/// in the program only when a particular dependent name does not exist. For
+/// example:
+///
+/// \code
+/// template<typename T>
+/// void call_foo(T &t) {
+///   __if_exists (T::foo) {
+///     t.foo(); // okay: only called when T::foo exists.
+///   }
+/// }
+/// \endcode
+///
+/// Similarly, the __if_not_exists statement can be used to include the
+/// statements when a particular name does not exist.
+///
+/// Note that this statement only captures __if_exists and __if_not_exists
+/// statements whose name is dependent. All non-dependent cases are handled
+/// directly in the parser, so that they don't introduce a new scope. Clang
+/// introduces scopes in the dependent case to keep names inside the compound
+/// statement from leaking out into the surround statements, which would
+/// compromise the template instantiation model. This behavior differs from
+/// Visual C++ (which never introduces a scope), but is a fairly reasonable
+/// approximation of the VC++ behavior.
+class MSDependentExistsStmt : public Stmt {
+  SourceLocation KeywordLoc;
+  bool IsIfExists;
+  NestedNameSpecifierLoc QualifierLoc;
+  DeclarationNameInfo NameInfo;
+  Stmt *SubStmt;
+
+  friend class ASTReader;
+  friend class ASTStmtReader;
+
+public:
+  MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
+                        NestedNameSpecifierLoc QualifierLoc,
+                        DeclarationNameInfo NameInfo,
+                        CompoundStmt *SubStmt)
+  : Stmt(MSDependentExistsStmtClass),
+    KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
+    QualifierLoc(QualifierLoc), NameInfo(NameInfo),
+    SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
+
+  /// \brief Retrieve the location of the __if_exists or __if_not_exists
+  /// keyword.
+  SourceLocation getKeywordLoc() const { return KeywordLoc; }
+
+  /// \brief Determine whether this is an __if_exists statement.
+  bool isIfExists() const { return IsIfExists; }
+
+  /// \brief Determine whether this is an __if_exists statement.
+  bool isIfNotExists() const { return !IsIfExists; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies this name, if
+  /// any.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the name of the entity we're testing for, along with
+  /// location information
+  DeclarationNameInfo getNameInfo() const { return NameInfo; }
+
+  /// \brief Retrieve the compound statement that will be included in the
+  /// program only if the existence of the symbol matches the initial keyword.
+  CompoundStmt *getSubStmt() const {
+    return reinterpret_cast<CompoundStmt *>(SubStmt);
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
+  child_range children() {
+    return child_range(&SubStmt, &SubStmt+1);
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == MSDependentExistsStmtClass;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
new file mode 100644
index 0000000..a3e9e1e
--- /dev/null
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -0,0 +1,83 @@
+//===--- StmtGraphTraits.h - Graph Traits for the class Stmt ----*- 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 template specialization of llvm::GraphTraits to
+//  treat ASTs (Stmt*) as graphs
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+#define LLVM_CLANG_AST_STMT_GRAPHTRAITS_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
+
+namespace llvm {
+
+//template <typename T> struct GraphTraits;
+
+
+template <> struct GraphTraits<clang::Stmt*> {
+  typedef clang::Stmt                       NodeType;
+  typedef clang::Stmt::child_iterator       ChildIteratorType;
+  typedef llvm::df_iterator<clang::Stmt*>   nodes_iterator;
+
+  static NodeType* getEntryNode(clang::Stmt* S) { return S; }
+
+  static inline ChildIteratorType child_begin(NodeType* N) {
+    if (N) return N->child_begin();
+    else return ChildIteratorType();
+  }
+
+  static inline ChildIteratorType child_end(NodeType* N) {
+    if (N) return N->child_end();
+    else return ChildIteratorType();
+  }
+
+  static nodes_iterator nodes_begin(clang::Stmt* S) {
+    return df_begin(S);
+  }
+
+  static nodes_iterator nodes_end(clang::Stmt* S) {
+    return df_end(S);
+  }
+};
+
+
+template <> struct GraphTraits<const clang::Stmt*> {
+  typedef const clang::Stmt                       NodeType;
+  typedef clang::Stmt::const_child_iterator       ChildIteratorType;
+  typedef llvm::df_iterator<const clang::Stmt*>   nodes_iterator;
+
+  static NodeType* getEntryNode(const clang::Stmt* S) { return S; }
+
+  static inline ChildIteratorType child_begin(NodeType* N) {
+    if (N) return N->child_begin();
+    else return ChildIteratorType();
+  }
+
+  static inline ChildIteratorType child_end(NodeType* N) {
+    if (N) return N->child_end();
+    else return ChildIteratorType();
+  }
+
+  static nodes_iterator nodes_begin(const clang::Stmt* S) {
+    return df_begin(S);
+  }
+
+  static nodes_iterator nodes_end(const clang::Stmt* S) {
+    return df_end(S);
+  }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
new file mode 100644
index 0000000..18c5516
--- /dev/null
+++ b/include/clang/AST/StmtIterator.h
@@ -0,0 +1,222 @@
+//===--- StmtIterator.h - Iterators for Statements --------------*- 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 StmtIterator and ConstStmtIterator classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_ITR_H
+#define LLVM_CLANG_AST_STMT_ITR_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+
+namespace clang {
+
+class Stmt;
+class Decl;
+class VariableArrayType;
+
+class StmtIteratorBase {
+protected:
+  enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
+         Flags = 0x3 };
+  
+  Stmt **stmt;
+  Decl **DGI;
+  uintptr_t RawVAPtr;
+  Decl **DGE;
+  
+  bool inDeclGroup() const {
+    return (RawVAPtr & Flags) == DeclGroupMode;
+  }
+
+  bool inSizeOfTypeVA() const {
+    return (RawVAPtr & Flags) == SizeOfTypeVAMode;
+  }
+
+  bool inStmt() const {
+    return (RawVAPtr & Flags) == StmtMode;
+  }
+
+  const VariableArrayType *getVAPtr() const {
+    return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
+  }
+
+  void setVAPtr(const VariableArrayType *P) {
+    assert (inDeclGroup() || inSizeOfTypeVA());
+    RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
+  }
+
+  void NextDecl(bool ImmediateAdvance = true);
+  bool HandleDecl(Decl* D);
+  void NextVA();
+
+  Stmt*& GetDeclExpr() const;
+
+  StmtIteratorBase(Stmt **s) : stmt(s), DGI(nullptr), RawVAPtr(0) {}
+  StmtIteratorBase(const VariableArrayType *t);
+  StmtIteratorBase(Decl **dgi, Decl **dge);
+  StmtIteratorBase() : stmt(nullptr), DGI(nullptr), RawVAPtr(0) {}
+};
+
+
+template <typename DERIVED, typename REFERENCE>
+class StmtIteratorImpl : public StmtIteratorBase,
+                         public std::iterator<std::forward_iterator_tag,
+                                              REFERENCE, ptrdiff_t,
+                                              REFERENCE, REFERENCE> {
+protected:
+  StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
+public:
+  StmtIteratorImpl() {}
+  StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
+  StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
+  StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
+
+  DERIVED& operator++() {
+    if (inStmt())
+      ++stmt;
+    else if (getVAPtr())
+      NextVA();
+    else
+      NextDecl();
+
+    return static_cast<DERIVED&>(*this);
+  }
+
+  DERIVED operator++(int) {
+    DERIVED tmp = static_cast<DERIVED&>(*this);
+    operator++();
+    return tmp;
+  }
+
+  bool operator==(const DERIVED& RHS) const {
+    return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
+  }
+
+  bool operator!=(const DERIVED& RHS) const {
+    return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
+  }
+
+  REFERENCE operator*() const {
+    return inStmt() ? *stmt : GetDeclExpr();
+  }
+
+  REFERENCE operator->() const { return operator*(); }
+};
+
+struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
+  explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
+
+  StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
+
+  StmtIterator(Decl** dgi, Decl** dge)
+   : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
+
+  StmtIterator(const VariableArrayType *t)
+    : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
+};
+
+struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
+                                                   const Stmt*> {
+  explicit ConstStmtIterator() :
+    StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
+
+  ConstStmtIterator(const StmtIterator& RHS) :
+    StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
+};
+
+/// A range of statement iterators.
+///
+/// This class provides some extra functionality beyond std::pair
+/// in order to allow the following idiom:
+///   for (StmtRange range = stmt->children(); range; ++range)
+struct StmtRange : std::pair<StmtIterator,StmtIterator> {
+  StmtRange() {}
+  StmtRange(const StmtIterator &begin, const StmtIterator &end)
+    : std::pair<StmtIterator,StmtIterator>(begin, end) {}
+
+  bool empty() const { return first == second; }
+  LLVM_EXPLICIT operator bool() const { return !empty(); }
+
+  Stmt *operator->() const { return first.operator->(); }
+  Stmt *&operator*() const { return first.operator*(); }
+
+  StmtRange &operator++() {
+    assert(!empty() && "incrementing on empty range");
+    ++first;
+    return *this;
+  }
+
+  StmtRange operator++(int) {
+    assert(!empty() && "incrementing on empty range");
+    StmtRange copy = *this;
+    ++first;
+    return copy;
+  }
+
+  friend const StmtIterator &begin(const StmtRange &range) {
+    return range.first;
+  }
+  friend const StmtIterator &end(const StmtRange &range) {
+    return range.second;
+  }
+};
+
+/// A range of const statement iterators.
+///
+/// This class provides some extra functionality beyond std::pair
+/// in order to allow the following idiom:
+///   for (ConstStmtRange range = stmt->children(); range; ++range)
+struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
+  ConstStmtRange() {}
+  ConstStmtRange(const ConstStmtIterator &begin,
+                 const ConstStmtIterator &end)
+    : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
+  ConstStmtRange(const StmtRange &range)
+    : std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second)
+  {}
+  ConstStmtRange(const StmtIterator &begin, const StmtIterator &end)
+    : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
+
+  bool empty() const { return first == second; }
+  LLVM_EXPLICIT operator bool() const { return !empty(); }
+
+  const Stmt *operator->() const { return first.operator->(); }
+  const Stmt *operator*() const { return first.operator*(); }
+
+  ConstStmtRange &operator++() {
+    assert(!empty() && "incrementing on empty range");
+    ++first;
+    return *this;
+  }
+
+  ConstStmtRange operator++(int) {
+    assert(!empty() && "incrementing on empty range");
+    ConstStmtRange copy = *this;
+    ++first;
+    return copy;
+  }
+
+  friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
+    return range.first;
+  }
+  friend const ConstStmtIterator &end(const ConstStmtRange &range) {
+    return range.second;
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtNodes.inc b/include/clang/AST/StmtNodes.inc
new file mode 100644
index 0000000..73ba22d
--- /dev/null
+++ b/include/clang/AST/StmtNodes.inc
@@ -0,0 +1,985 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of AST nodes of a particular kind                                      *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef ABSTRACT_STMT
+#  define ABSTRACT_STMT(Type) Type
+#endif
+#ifndef STMT_RANGE
+#  define STMT_RANGE(Base, First, Last)
+#endif
+
+#ifndef LAST_STMT_RANGE
+#  define LAST_STMT_RANGE(Base, First, Last) STMT_RANGE(Base, First, Last)
+#endif
+
+#ifndef ASMSTMT
+#  define ASMSTMT(Type, Base) STMT(Type, Base)
+#endif
+ABSTRACT_STMT(ASMSTMT(AsmStmt, Stmt))
+#ifndef GCCASMSTMT
+#  define GCCASMSTMT(Type, Base) ASMSTMT(Type, Base)
+#endif
+GCCASMSTMT(GCCAsmStmt, AsmStmt)
+#undef GCCASMSTMT
+
+#ifndef MSASMSTMT
+#  define MSASMSTMT(Type, Base) ASMSTMT(Type, Base)
+#endif
+MSASMSTMT(MSAsmStmt, AsmStmt)
+#undef MSASMSTMT
+
+STMT_RANGE(AsmStmt, GCCAsmStmt, MSAsmStmt)
+
+#undef ASMSTMT
+
+#ifndef ATTRIBUTEDSTMT
+#  define ATTRIBUTEDSTMT(Type, Base) STMT(Type, Base)
+#endif
+ATTRIBUTEDSTMT(AttributedStmt, Stmt)
+#undef ATTRIBUTEDSTMT
+
+#ifndef BREAKSTMT
+#  define BREAKSTMT(Type, Base) STMT(Type, Base)
+#endif
+BREAKSTMT(BreakStmt, Stmt)
+#undef BREAKSTMT
+
+#ifndef CXXCATCHSTMT
+#  define CXXCATCHSTMT(Type, Base) STMT(Type, Base)
+#endif
+CXXCATCHSTMT(CXXCatchStmt, Stmt)
+#undef CXXCATCHSTMT
+
+#ifndef CXXFORRANGESTMT
+#  define CXXFORRANGESTMT(Type, Base) STMT(Type, Base)
+#endif
+CXXFORRANGESTMT(CXXForRangeStmt, Stmt)
+#undef CXXFORRANGESTMT
+
+#ifndef CXXTRYSTMT
+#  define CXXTRYSTMT(Type, Base) STMT(Type, Base)
+#endif
+CXXTRYSTMT(CXXTryStmt, Stmt)
+#undef CXXTRYSTMT
+
+#ifndef CAPTUREDSTMT
+#  define CAPTUREDSTMT(Type, Base) STMT(Type, Base)
+#endif
+CAPTUREDSTMT(CapturedStmt, Stmt)
+#undef CAPTUREDSTMT
+
+#ifndef COMPOUNDSTMT
+#  define COMPOUNDSTMT(Type, Base) STMT(Type, Base)
+#endif
+COMPOUNDSTMT(CompoundStmt, Stmt)
+#undef COMPOUNDSTMT
+
+#ifndef CONTINUESTMT
+#  define CONTINUESTMT(Type, Base) STMT(Type, Base)
+#endif
+CONTINUESTMT(ContinueStmt, Stmt)
+#undef CONTINUESTMT
+
+#ifndef DECLSTMT
+#  define DECLSTMT(Type, Base) STMT(Type, Base)
+#endif
+DECLSTMT(DeclStmt, Stmt)
+#undef DECLSTMT
+
+#ifndef DOSTMT
+#  define DOSTMT(Type, Base) STMT(Type, Base)
+#endif
+DOSTMT(DoStmt, Stmt)
+#undef DOSTMT
+
+#ifndef EXPR
+#  define EXPR(Type, Base) STMT(Type, Base)
+#endif
+ABSTRACT_STMT(EXPR(Expr, Stmt))
+#ifndef ABSTRACTCONDITIONALOPERATOR
+#  define ABSTRACTCONDITIONALOPERATOR(Type, Base) EXPR(Type, Base)
+#endif
+ABSTRACT_STMT(ABSTRACTCONDITIONALOPERATOR(AbstractConditionalOperator, Expr))
+#ifndef BINARYCONDITIONALOPERATOR
+#  define BINARYCONDITIONALOPERATOR(Type, Base) ABSTRACTCONDITIONALOPERATOR(Type, Base)
+#endif
+BINARYCONDITIONALOPERATOR(BinaryConditionalOperator, AbstractConditionalOperator)
+#undef BINARYCONDITIONALOPERATOR
+
+#ifndef CONDITIONALOPERATOR
+#  define CONDITIONALOPERATOR(Type, Base) ABSTRACTCONDITIONALOPERATOR(Type, Base)
+#endif
+CONDITIONALOPERATOR(ConditionalOperator, AbstractConditionalOperator)
+#undef CONDITIONALOPERATOR
+
+STMT_RANGE(AbstractConditionalOperator, BinaryConditionalOperator, ConditionalOperator)
+
+#undef ABSTRACTCONDITIONALOPERATOR
+
+#ifndef ADDRLABELEXPR
+#  define ADDRLABELEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ADDRLABELEXPR(AddrLabelExpr, Expr)
+#undef ADDRLABELEXPR
+
+#ifndef ARRAYSUBSCRIPTEXPR
+#  define ARRAYSUBSCRIPTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ARRAYSUBSCRIPTEXPR(ArraySubscriptExpr, Expr)
+#undef ARRAYSUBSCRIPTEXPR
+
+#ifndef ARRAYTYPETRAITEXPR
+#  define ARRAYTYPETRAITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ARRAYTYPETRAITEXPR(ArrayTypeTraitExpr, Expr)
+#undef ARRAYTYPETRAITEXPR
+
+#ifndef ASTYPEEXPR
+#  define ASTYPEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ASTYPEEXPR(AsTypeExpr, Expr)
+#undef ASTYPEEXPR
+
+#ifndef ATOMICEXPR
+#  define ATOMICEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ATOMICEXPR(AtomicExpr, Expr)
+#undef ATOMICEXPR
+
+#ifndef BINARYOPERATOR
+#  define BINARYOPERATOR(Type, Base) EXPR(Type, Base)
+#endif
+BINARYOPERATOR(BinaryOperator, Expr)
+#ifndef COMPOUNDASSIGNOPERATOR
+#  define COMPOUNDASSIGNOPERATOR(Type, Base) BINARYOPERATOR(Type, Base)
+#endif
+COMPOUNDASSIGNOPERATOR(CompoundAssignOperator, BinaryOperator)
+#undef COMPOUNDASSIGNOPERATOR
+
+STMT_RANGE(BinaryOperator, BinaryOperator, CompoundAssignOperator)
+
+#undef BINARYOPERATOR
+
+#ifndef BLOCKEXPR
+#  define BLOCKEXPR(Type, Base) EXPR(Type, Base)
+#endif
+BLOCKEXPR(BlockExpr, Expr)
+#undef BLOCKEXPR
+
+#ifndef CXXBINDTEMPORARYEXPR
+#  define CXXBINDTEMPORARYEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXBINDTEMPORARYEXPR(CXXBindTemporaryExpr, Expr)
+#undef CXXBINDTEMPORARYEXPR
+
+#ifndef CXXBOOLLITERALEXPR
+#  define CXXBOOLLITERALEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXBOOLLITERALEXPR(CXXBoolLiteralExpr, Expr)
+#undef CXXBOOLLITERALEXPR
+
+#ifndef CXXCONSTRUCTEXPR
+#  define CXXCONSTRUCTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXCONSTRUCTEXPR(CXXConstructExpr, Expr)
+#ifndef CXXTEMPORARYOBJECTEXPR
+#  define CXXTEMPORARYOBJECTEXPR(Type, Base) CXXCONSTRUCTEXPR(Type, Base)
+#endif
+CXXTEMPORARYOBJECTEXPR(CXXTemporaryObjectExpr, CXXConstructExpr)
+#undef CXXTEMPORARYOBJECTEXPR
+
+STMT_RANGE(CXXConstructExpr, CXXConstructExpr, CXXTemporaryObjectExpr)
+
+#undef CXXCONSTRUCTEXPR
+
+#ifndef CXXDEFAULTARGEXPR
+#  define CXXDEFAULTARGEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXDEFAULTARGEXPR(CXXDefaultArgExpr, Expr)
+#undef CXXDEFAULTARGEXPR
+
+#ifndef CXXDEFAULTINITEXPR
+#  define CXXDEFAULTINITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXDEFAULTINITEXPR(CXXDefaultInitExpr, Expr)
+#undef CXXDEFAULTINITEXPR
+
+#ifndef CXXDELETEEXPR
+#  define CXXDELETEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXDELETEEXPR(CXXDeleteExpr, Expr)
+#undef CXXDELETEEXPR
+
+#ifndef CXXDEPENDENTSCOPEMEMBEREXPR
+#  define CXXDEPENDENTSCOPEMEMBEREXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXDEPENDENTSCOPEMEMBEREXPR(CXXDependentScopeMemberExpr, Expr)
+#undef CXXDEPENDENTSCOPEMEMBEREXPR
+
+#ifndef CXXNEWEXPR
+#  define CXXNEWEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXNEWEXPR(CXXNewExpr, Expr)
+#undef CXXNEWEXPR
+
+#ifndef CXXNOEXCEPTEXPR
+#  define CXXNOEXCEPTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXNOEXCEPTEXPR(CXXNoexceptExpr, Expr)
+#undef CXXNOEXCEPTEXPR
+
+#ifndef CXXNULLPTRLITERALEXPR
+#  define CXXNULLPTRLITERALEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXNULLPTRLITERALEXPR(CXXNullPtrLiteralExpr, Expr)
+#undef CXXNULLPTRLITERALEXPR
+
+#ifndef CXXPSEUDODESTRUCTOREXPR
+#  define CXXPSEUDODESTRUCTOREXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXPSEUDODESTRUCTOREXPR(CXXPseudoDestructorExpr, Expr)
+#undef CXXPSEUDODESTRUCTOREXPR
+
+#ifndef CXXSCALARVALUEINITEXPR
+#  define CXXSCALARVALUEINITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXSCALARVALUEINITEXPR(CXXScalarValueInitExpr, Expr)
+#undef CXXSCALARVALUEINITEXPR
+
+#ifndef CXXSTDINITIALIZERLISTEXPR
+#  define CXXSTDINITIALIZERLISTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXSTDINITIALIZERLISTEXPR(CXXStdInitializerListExpr, Expr)
+#undef CXXSTDINITIALIZERLISTEXPR
+
+#ifndef CXXTHISEXPR
+#  define CXXTHISEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXTHISEXPR(CXXThisExpr, Expr)
+#undef CXXTHISEXPR
+
+#ifndef CXXTHROWEXPR
+#  define CXXTHROWEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXTHROWEXPR(CXXThrowExpr, Expr)
+#undef CXXTHROWEXPR
+
+#ifndef CXXTYPEIDEXPR
+#  define CXXTYPEIDEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXTYPEIDEXPR(CXXTypeidExpr, Expr)
+#undef CXXTYPEIDEXPR
+
+#ifndef CXXUNRESOLVEDCONSTRUCTEXPR
+#  define CXXUNRESOLVEDCONSTRUCTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXUNRESOLVEDCONSTRUCTEXPR(CXXUnresolvedConstructExpr, Expr)
+#undef CXXUNRESOLVEDCONSTRUCTEXPR
+
+#ifndef CXXUUIDOFEXPR
+#  define CXXUUIDOFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CXXUUIDOFEXPR(CXXUuidofExpr, Expr)
+#undef CXXUUIDOFEXPR
+
+#ifndef CALLEXPR
+#  define CALLEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CALLEXPR(CallExpr, Expr)
+#ifndef CUDAKERNELCALLEXPR
+#  define CUDAKERNELCALLEXPR(Type, Base) CALLEXPR(Type, Base)
+#endif
+CUDAKERNELCALLEXPR(CUDAKernelCallExpr, CallExpr)
+#undef CUDAKERNELCALLEXPR
+
+#ifndef CXXMEMBERCALLEXPR
+#  define CXXMEMBERCALLEXPR(Type, Base) CALLEXPR(Type, Base)
+#endif
+CXXMEMBERCALLEXPR(CXXMemberCallExpr, CallExpr)
+#undef CXXMEMBERCALLEXPR
+
+#ifndef CXXOPERATORCALLEXPR
+#  define CXXOPERATORCALLEXPR(Type, Base) CALLEXPR(Type, Base)
+#endif
+CXXOPERATORCALLEXPR(CXXOperatorCallExpr, CallExpr)
+#undef CXXOPERATORCALLEXPR
+
+#ifndef USERDEFINEDLITERAL
+#  define USERDEFINEDLITERAL(Type, Base) CALLEXPR(Type, Base)
+#endif
+USERDEFINEDLITERAL(UserDefinedLiteral, CallExpr)
+#undef USERDEFINEDLITERAL
+
+STMT_RANGE(CallExpr, CallExpr, UserDefinedLiteral)
+
+#undef CALLEXPR
+
+#ifndef CASTEXPR
+#  define CASTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ABSTRACT_STMT(CASTEXPR(CastExpr, Expr))
+#ifndef EXPLICITCASTEXPR
+#  define EXPLICITCASTEXPR(Type, Base) CASTEXPR(Type, Base)
+#endif
+ABSTRACT_STMT(EXPLICITCASTEXPR(ExplicitCastExpr, CastExpr))
+#ifndef CSTYLECASTEXPR
+#  define CSTYLECASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base)
+#endif
+CSTYLECASTEXPR(CStyleCastExpr, ExplicitCastExpr)
+#undef CSTYLECASTEXPR
+
+#ifndef CXXFUNCTIONALCASTEXPR
+#  define CXXFUNCTIONALCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base)
+#endif
+CXXFUNCTIONALCASTEXPR(CXXFunctionalCastExpr, ExplicitCastExpr)
+#undef CXXFUNCTIONALCASTEXPR
+
+#ifndef CXXNAMEDCASTEXPR
+#  define CXXNAMEDCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base)
+#endif
+ABSTRACT_STMT(CXXNAMEDCASTEXPR(CXXNamedCastExpr, ExplicitCastExpr))
+#ifndef CXXCONSTCASTEXPR
+#  define CXXCONSTCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base)
+#endif
+CXXCONSTCASTEXPR(CXXConstCastExpr, CXXNamedCastExpr)
+#undef CXXCONSTCASTEXPR
+
+#ifndef CXXDYNAMICCASTEXPR
+#  define CXXDYNAMICCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base)
+#endif
+CXXDYNAMICCASTEXPR(CXXDynamicCastExpr, CXXNamedCastExpr)
+#undef CXXDYNAMICCASTEXPR
+
+#ifndef CXXREINTERPRETCASTEXPR
+#  define CXXREINTERPRETCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base)
+#endif
+CXXREINTERPRETCASTEXPR(CXXReinterpretCastExpr, CXXNamedCastExpr)
+#undef CXXREINTERPRETCASTEXPR
+
+#ifndef CXXSTATICCASTEXPR
+#  define CXXSTATICCASTEXPR(Type, Base) CXXNAMEDCASTEXPR(Type, Base)
+#endif
+CXXSTATICCASTEXPR(CXXStaticCastExpr, CXXNamedCastExpr)
+#undef CXXSTATICCASTEXPR
+
+STMT_RANGE(CXXNamedCastExpr, CXXConstCastExpr, CXXStaticCastExpr)
+
+#undef CXXNAMEDCASTEXPR
+
+#ifndef OBJCBRIDGEDCASTEXPR
+#  define OBJCBRIDGEDCASTEXPR(Type, Base) EXPLICITCASTEXPR(Type, Base)
+#endif
+OBJCBRIDGEDCASTEXPR(ObjCBridgedCastExpr, ExplicitCastExpr)
+#undef OBJCBRIDGEDCASTEXPR
+
+STMT_RANGE(ExplicitCastExpr, CStyleCastExpr, ObjCBridgedCastExpr)
+
+#undef EXPLICITCASTEXPR
+
+#ifndef IMPLICITCASTEXPR
+#  define IMPLICITCASTEXPR(Type, Base) CASTEXPR(Type, Base)
+#endif
+IMPLICITCASTEXPR(ImplicitCastExpr, CastExpr)
+#undef IMPLICITCASTEXPR
+
+STMT_RANGE(CastExpr, CStyleCastExpr, ImplicitCastExpr)
+
+#undef CASTEXPR
+
+#ifndef CHARACTERLITERAL
+#  define CHARACTERLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+CHARACTERLITERAL(CharacterLiteral, Expr)
+#undef CHARACTERLITERAL
+
+#ifndef CHOOSEEXPR
+#  define CHOOSEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+CHOOSEEXPR(ChooseExpr, Expr)
+#undef CHOOSEEXPR
+
+#ifndef COMPOUNDLITERALEXPR
+#  define COMPOUNDLITERALEXPR(Type, Base) EXPR(Type, Base)
+#endif
+COMPOUNDLITERALEXPR(CompoundLiteralExpr, Expr)
+#undef COMPOUNDLITERALEXPR
+
+#ifndef CONVERTVECTOREXPR
+#  define CONVERTVECTOREXPR(Type, Base) EXPR(Type, Base)
+#endif
+CONVERTVECTOREXPR(ConvertVectorExpr, Expr)
+#undef CONVERTVECTOREXPR
+
+#ifndef DECLREFEXPR
+#  define DECLREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+DECLREFEXPR(DeclRefExpr, Expr)
+#undef DECLREFEXPR
+
+#ifndef DEPENDENTSCOPEDECLREFEXPR
+#  define DEPENDENTSCOPEDECLREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+DEPENDENTSCOPEDECLREFEXPR(DependentScopeDeclRefExpr, Expr)
+#undef DEPENDENTSCOPEDECLREFEXPR
+
+#ifndef DESIGNATEDINITEXPR
+#  define DESIGNATEDINITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+DESIGNATEDINITEXPR(DesignatedInitExpr, Expr)
+#undef DESIGNATEDINITEXPR
+
+#ifndef EXPRWITHCLEANUPS
+#  define EXPRWITHCLEANUPS(Type, Base) EXPR(Type, Base)
+#endif
+EXPRWITHCLEANUPS(ExprWithCleanups, Expr)
+#undef EXPRWITHCLEANUPS
+
+#ifndef EXPRESSIONTRAITEXPR
+#  define EXPRESSIONTRAITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+EXPRESSIONTRAITEXPR(ExpressionTraitExpr, Expr)
+#undef EXPRESSIONTRAITEXPR
+
+#ifndef EXTVECTORELEMENTEXPR
+#  define EXTVECTORELEMENTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+EXTVECTORELEMENTEXPR(ExtVectorElementExpr, Expr)
+#undef EXTVECTORELEMENTEXPR
+
+#ifndef FLOATINGLITERAL
+#  define FLOATINGLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+FLOATINGLITERAL(FloatingLiteral, Expr)
+#undef FLOATINGLITERAL
+
+#ifndef FUNCTIONPARMPACKEXPR
+#  define FUNCTIONPARMPACKEXPR(Type, Base) EXPR(Type, Base)
+#endif
+FUNCTIONPARMPACKEXPR(FunctionParmPackExpr, Expr)
+#undef FUNCTIONPARMPACKEXPR
+
+#ifndef GNUNULLEXPR
+#  define GNUNULLEXPR(Type, Base) EXPR(Type, Base)
+#endif
+GNUNULLEXPR(GNUNullExpr, Expr)
+#undef GNUNULLEXPR
+
+#ifndef GENERICSELECTIONEXPR
+#  define GENERICSELECTIONEXPR(Type, Base) EXPR(Type, Base)
+#endif
+GENERICSELECTIONEXPR(GenericSelectionExpr, Expr)
+#undef GENERICSELECTIONEXPR
+
+#ifndef IMAGINARYLITERAL
+#  define IMAGINARYLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+IMAGINARYLITERAL(ImaginaryLiteral, Expr)
+#undef IMAGINARYLITERAL
+
+#ifndef IMPLICITVALUEINITEXPR
+#  define IMPLICITVALUEINITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+IMPLICITVALUEINITEXPR(ImplicitValueInitExpr, Expr)
+#undef IMPLICITVALUEINITEXPR
+
+#ifndef INITLISTEXPR
+#  define INITLISTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+INITLISTEXPR(InitListExpr, Expr)
+#undef INITLISTEXPR
+
+#ifndef INTEGERLITERAL
+#  define INTEGERLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+INTEGERLITERAL(IntegerLiteral, Expr)
+#undef INTEGERLITERAL
+
+#ifndef LAMBDAEXPR
+#  define LAMBDAEXPR(Type, Base) EXPR(Type, Base)
+#endif
+LAMBDAEXPR(LambdaExpr, Expr)
+#undef LAMBDAEXPR
+
+#ifndef MSPROPERTYREFEXPR
+#  define MSPROPERTYREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+MSPROPERTYREFEXPR(MSPropertyRefExpr, Expr)
+#undef MSPROPERTYREFEXPR
+
+#ifndef MATERIALIZETEMPORARYEXPR
+#  define MATERIALIZETEMPORARYEXPR(Type, Base) EXPR(Type, Base)
+#endif
+MATERIALIZETEMPORARYEXPR(MaterializeTemporaryExpr, Expr)
+#undef MATERIALIZETEMPORARYEXPR
+
+#ifndef MEMBEREXPR
+#  define MEMBEREXPR(Type, Base) EXPR(Type, Base)
+#endif
+MEMBEREXPR(MemberExpr, Expr)
+#undef MEMBEREXPR
+
+#ifndef OBJCARRAYLITERAL
+#  define OBJCARRAYLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+OBJCARRAYLITERAL(ObjCArrayLiteral, Expr)
+#undef OBJCARRAYLITERAL
+
+#ifndef OBJCBOOLLITERALEXPR
+#  define OBJCBOOLLITERALEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCBOOLLITERALEXPR(ObjCBoolLiteralExpr, Expr)
+#undef OBJCBOOLLITERALEXPR
+
+#ifndef OBJCBOXEDEXPR
+#  define OBJCBOXEDEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCBOXEDEXPR(ObjCBoxedExpr, Expr)
+#undef OBJCBOXEDEXPR
+
+#ifndef OBJCDICTIONARYLITERAL
+#  define OBJCDICTIONARYLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+OBJCDICTIONARYLITERAL(ObjCDictionaryLiteral, Expr)
+#undef OBJCDICTIONARYLITERAL
+
+#ifndef OBJCENCODEEXPR
+#  define OBJCENCODEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCENCODEEXPR(ObjCEncodeExpr, Expr)
+#undef OBJCENCODEEXPR
+
+#ifndef OBJCINDIRECTCOPYRESTOREEXPR
+#  define OBJCINDIRECTCOPYRESTOREEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCINDIRECTCOPYRESTOREEXPR(ObjCIndirectCopyRestoreExpr, Expr)
+#undef OBJCINDIRECTCOPYRESTOREEXPR
+
+#ifndef OBJCISAEXPR
+#  define OBJCISAEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCISAEXPR(ObjCIsaExpr, Expr)
+#undef OBJCISAEXPR
+
+#ifndef OBJCIVARREFEXPR
+#  define OBJCIVARREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCIVARREFEXPR(ObjCIvarRefExpr, Expr)
+#undef OBJCIVARREFEXPR
+
+#ifndef OBJCMESSAGEEXPR
+#  define OBJCMESSAGEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCMESSAGEEXPR(ObjCMessageExpr, Expr)
+#undef OBJCMESSAGEEXPR
+
+#ifndef OBJCPROPERTYREFEXPR
+#  define OBJCPROPERTYREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCPROPERTYREFEXPR(ObjCPropertyRefExpr, Expr)
+#undef OBJCPROPERTYREFEXPR
+
+#ifndef OBJCPROTOCOLEXPR
+#  define OBJCPROTOCOLEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCPROTOCOLEXPR(ObjCProtocolExpr, Expr)
+#undef OBJCPROTOCOLEXPR
+
+#ifndef OBJCSELECTOREXPR
+#  define OBJCSELECTOREXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCSELECTOREXPR(ObjCSelectorExpr, Expr)
+#undef OBJCSELECTOREXPR
+
+#ifndef OBJCSTRINGLITERAL
+#  define OBJCSTRINGLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+OBJCSTRINGLITERAL(ObjCStringLiteral, Expr)
+#undef OBJCSTRINGLITERAL
+
+#ifndef OBJCSUBSCRIPTREFEXPR
+#  define OBJCSUBSCRIPTREFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OBJCSUBSCRIPTREFEXPR(ObjCSubscriptRefExpr, Expr)
+#undef OBJCSUBSCRIPTREFEXPR
+
+#ifndef OFFSETOFEXPR
+#  define OFFSETOFEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OFFSETOFEXPR(OffsetOfExpr, Expr)
+#undef OFFSETOFEXPR
+
+#ifndef OPAQUEVALUEEXPR
+#  define OPAQUEVALUEEXPR(Type, Base) EXPR(Type, Base)
+#endif
+OPAQUEVALUEEXPR(OpaqueValueExpr, Expr)
+#undef OPAQUEVALUEEXPR
+
+#ifndef OVERLOADEXPR
+#  define OVERLOADEXPR(Type, Base) EXPR(Type, Base)
+#endif
+ABSTRACT_STMT(OVERLOADEXPR(OverloadExpr, Expr))
+#ifndef UNRESOLVEDLOOKUPEXPR
+#  define UNRESOLVEDLOOKUPEXPR(Type, Base) OVERLOADEXPR(Type, Base)
+#endif
+UNRESOLVEDLOOKUPEXPR(UnresolvedLookupExpr, OverloadExpr)
+#undef UNRESOLVEDLOOKUPEXPR
+
+#ifndef UNRESOLVEDMEMBEREXPR
+#  define UNRESOLVEDMEMBEREXPR(Type, Base) OVERLOADEXPR(Type, Base)
+#endif
+UNRESOLVEDMEMBEREXPR(UnresolvedMemberExpr, OverloadExpr)
+#undef UNRESOLVEDMEMBEREXPR
+
+STMT_RANGE(OverloadExpr, UnresolvedLookupExpr, UnresolvedMemberExpr)
+
+#undef OVERLOADEXPR
+
+#ifndef PACKEXPANSIONEXPR
+#  define PACKEXPANSIONEXPR(Type, Base) EXPR(Type, Base)
+#endif
+PACKEXPANSIONEXPR(PackExpansionExpr, Expr)
+#undef PACKEXPANSIONEXPR
+
+#ifndef PARENEXPR
+#  define PARENEXPR(Type, Base) EXPR(Type, Base)
+#endif
+PARENEXPR(ParenExpr, Expr)
+#undef PARENEXPR
+
+#ifndef PARENLISTEXPR
+#  define PARENLISTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+PARENLISTEXPR(ParenListExpr, Expr)
+#undef PARENLISTEXPR
+
+#ifndef PREDEFINEDEXPR
+#  define PREDEFINEDEXPR(Type, Base) EXPR(Type, Base)
+#endif
+PREDEFINEDEXPR(PredefinedExpr, Expr)
+#undef PREDEFINEDEXPR
+
+#ifndef PSEUDOOBJECTEXPR
+#  define PSEUDOOBJECTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+PSEUDOOBJECTEXPR(PseudoObjectExpr, Expr)
+#undef PSEUDOOBJECTEXPR
+
+#ifndef SHUFFLEVECTOREXPR
+#  define SHUFFLEVECTOREXPR(Type, Base) EXPR(Type, Base)
+#endif
+SHUFFLEVECTOREXPR(ShuffleVectorExpr, Expr)
+#undef SHUFFLEVECTOREXPR
+
+#ifndef SIZEOFPACKEXPR
+#  define SIZEOFPACKEXPR(Type, Base) EXPR(Type, Base)
+#endif
+SIZEOFPACKEXPR(SizeOfPackExpr, Expr)
+#undef SIZEOFPACKEXPR
+
+#ifndef STMTEXPR
+#  define STMTEXPR(Type, Base) EXPR(Type, Base)
+#endif
+STMTEXPR(StmtExpr, Expr)
+#undef STMTEXPR
+
+#ifndef STRINGLITERAL
+#  define STRINGLITERAL(Type, Base) EXPR(Type, Base)
+#endif
+STRINGLITERAL(StringLiteral, Expr)
+#undef STRINGLITERAL
+
+#ifndef SUBSTNONTYPETEMPLATEPARMEXPR
+#  define SUBSTNONTYPETEMPLATEPARMEXPR(Type, Base) EXPR(Type, Base)
+#endif
+SUBSTNONTYPETEMPLATEPARMEXPR(SubstNonTypeTemplateParmExpr, Expr)
+#undef SUBSTNONTYPETEMPLATEPARMEXPR
+
+#ifndef SUBSTNONTYPETEMPLATEPARMPACKEXPR
+#  define SUBSTNONTYPETEMPLATEPARMPACKEXPR(Type, Base) EXPR(Type, Base)
+#endif
+SUBSTNONTYPETEMPLATEPARMPACKEXPR(SubstNonTypeTemplateParmPackExpr, Expr)
+#undef SUBSTNONTYPETEMPLATEPARMPACKEXPR
+
+#ifndef TYPETRAITEXPR
+#  define TYPETRAITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+TYPETRAITEXPR(TypeTraitExpr, Expr)
+#undef TYPETRAITEXPR
+
+#ifndef UNARYEXPRORTYPETRAITEXPR
+#  define UNARYEXPRORTYPETRAITEXPR(Type, Base) EXPR(Type, Base)
+#endif
+UNARYEXPRORTYPETRAITEXPR(UnaryExprOrTypeTraitExpr, Expr)
+#undef UNARYEXPRORTYPETRAITEXPR
+
+#ifndef UNARYOPERATOR
+#  define UNARYOPERATOR(Type, Base) EXPR(Type, Base)
+#endif
+UNARYOPERATOR(UnaryOperator, Expr)
+#undef UNARYOPERATOR
+
+#ifndef VAARGEXPR
+#  define VAARGEXPR(Type, Base) EXPR(Type, Base)
+#endif
+VAARGEXPR(VAArgExpr, Expr)
+#undef VAARGEXPR
+
+STMT_RANGE(Expr, BinaryConditionalOperator, VAArgExpr)
+
+#undef EXPR
+
+#ifndef FORSTMT
+#  define FORSTMT(Type, Base) STMT(Type, Base)
+#endif
+FORSTMT(ForStmt, Stmt)
+#undef FORSTMT
+
+#ifndef GOTOSTMT
+#  define GOTOSTMT(Type, Base) STMT(Type, Base)
+#endif
+GOTOSTMT(GotoStmt, Stmt)
+#undef GOTOSTMT
+
+#ifndef IFSTMT
+#  define IFSTMT(Type, Base) STMT(Type, Base)
+#endif
+IFSTMT(IfStmt, Stmt)
+#undef IFSTMT
+
+#ifndef INDIRECTGOTOSTMT
+#  define INDIRECTGOTOSTMT(Type, Base) STMT(Type, Base)
+#endif
+INDIRECTGOTOSTMT(IndirectGotoStmt, Stmt)
+#undef INDIRECTGOTOSTMT
+
+#ifndef LABELSTMT
+#  define LABELSTMT(Type, Base) STMT(Type, Base)
+#endif
+LABELSTMT(LabelStmt, Stmt)
+#undef LABELSTMT
+
+#ifndef MSDEPENDENTEXISTSSTMT
+#  define MSDEPENDENTEXISTSSTMT(Type, Base) STMT(Type, Base)
+#endif
+MSDEPENDENTEXISTSSTMT(MSDependentExistsStmt, Stmt)
+#undef MSDEPENDENTEXISTSSTMT
+
+#ifndef NULLSTMT
+#  define NULLSTMT(Type, Base) STMT(Type, Base)
+#endif
+NULLSTMT(NullStmt, Stmt)
+#undef NULLSTMT
+
+#ifndef OMPEXECUTABLEDIRECTIVE
+#  define OMPEXECUTABLEDIRECTIVE(Type, Base) STMT(Type, Base)
+#endif
+ABSTRACT_STMT(OMPEXECUTABLEDIRECTIVE(OMPExecutableDirective, Stmt))
+#ifndef OMPBARRIERDIRECTIVE
+#  define OMPBARRIERDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPBARRIERDIRECTIVE(OMPBarrierDirective, OMPExecutableDirective)
+#undef OMPBARRIERDIRECTIVE
+
+#ifndef OMPCRITICALDIRECTIVE
+#  define OMPCRITICALDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPCRITICALDIRECTIVE(OMPCriticalDirective, OMPExecutableDirective)
+#undef OMPCRITICALDIRECTIVE
+
+#ifndef OMPFLUSHDIRECTIVE
+#  define OMPFLUSHDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPFLUSHDIRECTIVE(OMPFlushDirective, OMPExecutableDirective)
+#undef OMPFLUSHDIRECTIVE
+
+#ifndef OMPFORDIRECTIVE
+#  define OMPFORDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPFORDIRECTIVE(OMPForDirective, OMPExecutableDirective)
+#undef OMPFORDIRECTIVE
+
+#ifndef OMPMASTERDIRECTIVE
+#  define OMPMASTERDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPMASTERDIRECTIVE(OMPMasterDirective, OMPExecutableDirective)
+#undef OMPMASTERDIRECTIVE
+
+#ifndef OMPPARALLELDIRECTIVE
+#  define OMPPARALLELDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPPARALLELDIRECTIVE(OMPParallelDirective, OMPExecutableDirective)
+#undef OMPPARALLELDIRECTIVE
+
+#ifndef OMPPARALLELFORDIRECTIVE
+#  define OMPPARALLELFORDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPPARALLELFORDIRECTIVE(OMPParallelForDirective, OMPExecutableDirective)
+#undef OMPPARALLELFORDIRECTIVE
+
+#ifndef OMPPARALLELSECTIONSDIRECTIVE
+#  define OMPPARALLELSECTIONSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPPARALLELSECTIONSDIRECTIVE(OMPParallelSectionsDirective, OMPExecutableDirective)
+#undef OMPPARALLELSECTIONSDIRECTIVE
+
+#ifndef OMPSECTIONDIRECTIVE
+#  define OMPSECTIONDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPSECTIONDIRECTIVE(OMPSectionDirective, OMPExecutableDirective)
+#undef OMPSECTIONDIRECTIVE
+
+#ifndef OMPSECTIONSDIRECTIVE
+#  define OMPSECTIONSDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPSECTIONSDIRECTIVE(OMPSectionsDirective, OMPExecutableDirective)
+#undef OMPSECTIONSDIRECTIVE
+
+#ifndef OMPSIMDDIRECTIVE
+#  define OMPSIMDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPSIMDDIRECTIVE(OMPSimdDirective, OMPExecutableDirective)
+#undef OMPSIMDDIRECTIVE
+
+#ifndef OMPSINGLEDIRECTIVE
+#  define OMPSINGLEDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPSINGLEDIRECTIVE(OMPSingleDirective, OMPExecutableDirective)
+#undef OMPSINGLEDIRECTIVE
+
+#ifndef OMPTASKDIRECTIVE
+#  define OMPTASKDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPTASKDIRECTIVE(OMPTaskDirective, OMPExecutableDirective)
+#undef OMPTASKDIRECTIVE
+
+#ifndef OMPTASKWAITDIRECTIVE
+#  define OMPTASKWAITDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPTASKWAITDIRECTIVE(OMPTaskwaitDirective, OMPExecutableDirective)
+#undef OMPTASKWAITDIRECTIVE
+
+#ifndef OMPTASKYIELDDIRECTIVE
+#  define OMPTASKYIELDDIRECTIVE(Type, Base) OMPEXECUTABLEDIRECTIVE(Type, Base)
+#endif
+OMPTASKYIELDDIRECTIVE(OMPTaskyieldDirective, OMPExecutableDirective)
+#undef OMPTASKYIELDDIRECTIVE
+
+STMT_RANGE(OMPExecutableDirective, OMPBarrierDirective, OMPTaskyieldDirective)
+
+#undef OMPEXECUTABLEDIRECTIVE
+
+#ifndef OBJCATCATCHSTMT
+#  define OBJCATCATCHSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCATCATCHSTMT(ObjCAtCatchStmt, Stmt)
+#undef OBJCATCATCHSTMT
+
+#ifndef OBJCATFINALLYSTMT
+#  define OBJCATFINALLYSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCATFINALLYSTMT(ObjCAtFinallyStmt, Stmt)
+#undef OBJCATFINALLYSTMT
+
+#ifndef OBJCATSYNCHRONIZEDSTMT
+#  define OBJCATSYNCHRONIZEDSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCATSYNCHRONIZEDSTMT(ObjCAtSynchronizedStmt, Stmt)
+#undef OBJCATSYNCHRONIZEDSTMT
+
+#ifndef OBJCATTHROWSTMT
+#  define OBJCATTHROWSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCATTHROWSTMT(ObjCAtThrowStmt, Stmt)
+#undef OBJCATTHROWSTMT
+
+#ifndef OBJCATTRYSTMT
+#  define OBJCATTRYSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCATTRYSTMT(ObjCAtTryStmt, Stmt)
+#undef OBJCATTRYSTMT
+
+#ifndef OBJCAUTORELEASEPOOLSTMT
+#  define OBJCAUTORELEASEPOOLSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCAUTORELEASEPOOLSTMT(ObjCAutoreleasePoolStmt, Stmt)
+#undef OBJCAUTORELEASEPOOLSTMT
+
+#ifndef OBJCFORCOLLECTIONSTMT
+#  define OBJCFORCOLLECTIONSTMT(Type, Base) STMT(Type, Base)
+#endif
+OBJCFORCOLLECTIONSTMT(ObjCForCollectionStmt, Stmt)
+#undef OBJCFORCOLLECTIONSTMT
+
+#ifndef RETURNSTMT
+#  define RETURNSTMT(Type, Base) STMT(Type, Base)
+#endif
+RETURNSTMT(ReturnStmt, Stmt)
+#undef RETURNSTMT
+
+#ifndef SEHEXCEPTSTMT
+#  define SEHEXCEPTSTMT(Type, Base) STMT(Type, Base)
+#endif
+SEHEXCEPTSTMT(SEHExceptStmt, Stmt)
+#undef SEHEXCEPTSTMT
+
+#ifndef SEHFINALLYSTMT
+#  define SEHFINALLYSTMT(Type, Base) STMT(Type, Base)
+#endif
+SEHFINALLYSTMT(SEHFinallyStmt, Stmt)
+#undef SEHFINALLYSTMT
+
+#ifndef SEHLEAVESTMT
+#  define SEHLEAVESTMT(Type, Base) STMT(Type, Base)
+#endif
+SEHLEAVESTMT(SEHLeaveStmt, Stmt)
+#undef SEHLEAVESTMT
+
+#ifndef SEHTRYSTMT
+#  define SEHTRYSTMT(Type, Base) STMT(Type, Base)
+#endif
+SEHTRYSTMT(SEHTryStmt, Stmt)
+#undef SEHTRYSTMT
+
+#ifndef SWITCHCASE
+#  define SWITCHCASE(Type, Base) STMT(Type, Base)
+#endif
+ABSTRACT_STMT(SWITCHCASE(SwitchCase, Stmt))
+#ifndef CASESTMT
+#  define CASESTMT(Type, Base) SWITCHCASE(Type, Base)
+#endif
+CASESTMT(CaseStmt, SwitchCase)
+#undef CASESTMT
+
+#ifndef DEFAULTSTMT
+#  define DEFAULTSTMT(Type, Base) SWITCHCASE(Type, Base)
+#endif
+DEFAULTSTMT(DefaultStmt, SwitchCase)
+#undef DEFAULTSTMT
+
+STMT_RANGE(SwitchCase, CaseStmt, DefaultStmt)
+
+#undef SWITCHCASE
+
+#ifndef SWITCHSTMT
+#  define SWITCHSTMT(Type, Base) STMT(Type, Base)
+#endif
+SWITCHSTMT(SwitchStmt, Stmt)
+#undef SWITCHSTMT
+
+#ifndef WHILESTMT
+#  define WHILESTMT(Type, Base) STMT(Type, Base)
+#endif
+WHILESTMT(WhileStmt, Stmt)
+#undef WHILESTMT
+
+LAST_STMT_RANGE(Stmt, GCCAsmStmt, WhileStmt)
+
+#undef STMT
+#undef STMT_RANGE
+#undef LAST_STMT_RANGE
+#undef ABSTRACT_STMT
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
new file mode 100644
index 0000000..d0527e2
--- /dev/null
+++ b/include/clang/AST/StmtObjC.h
@@ -0,0 +1,374 @@
+//===--- StmtObjC.h - Classes for representing ObjC statements --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+/// \file
+/// \brief Defines the Objective-C statement AST node classes.
+
+#ifndef LLVM_CLANG_AST_STMTOBJC_H
+#define LLVM_CLANG_AST_STMTOBJC_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+/// \brief Represents Objective-C's collection statement.
+///
+/// This is represented as 'for (element 'in' collection-expression)' stmt.
+class ObjCForCollectionStmt : public Stmt {
+  enum { ELEM, COLLECTION, BODY, END_EXPR };
+  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
+  SourceLocation ForLoc;
+  SourceLocation RParenLoc;
+public:
+  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
+                        SourceLocation FCL, SourceLocation RPL);
+  explicit ObjCForCollectionStmt(EmptyShell Empty) :
+    Stmt(ObjCForCollectionStmtClass, Empty) { }
+
+  Stmt *getElement() { return SubExprs[ELEM]; }
+  Expr *getCollection() {
+    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+  }
+  Stmt *getBody() { return SubExprs[BODY]; }
+
+  const Stmt *getElement() const { return SubExprs[ELEM]; }
+  const Expr *getCollection() const {
+    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
+  }
+  const Stmt *getBody() const { return SubExprs[BODY]; }
+
+  void setElement(Stmt *S) { SubExprs[ELEM] = S; }
+  void setCollection(Expr *E) {
+    SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(E);
+  }
+  void setBody(Stmt *S) { SubExprs[BODY] = S; }
+
+  SourceLocation getForLoc() const { return ForLoc; }
+  void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return SubExprs[BODY]->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCForCollectionStmtClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
+  }
+};
+
+/// \brief Represents Objective-C's \@catch statement.
+class ObjCAtCatchStmt : public Stmt {
+private:
+  VarDecl *ExceptionDecl;
+  Stmt *Body;
+  SourceLocation AtCatchLoc, RParenLoc;
+
+public:
+  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
+                  VarDecl *catchVarDecl,
+                  Stmt *atCatchStmt)
+    : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl), 
+    Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
+
+  explicit ObjCAtCatchStmt(EmptyShell Empty) :
+    Stmt(ObjCAtCatchStmtClass, Empty) { }
+
+  const Stmt *getCatchBody() const { return Body; }
+  Stmt *getCatchBody() { return Body; }
+  void setCatchBody(Stmt *S) { Body = S; }
+
+  const VarDecl *getCatchParamDecl() const {
+    return ExceptionDecl;
+  }
+  VarDecl *getCatchParamDecl() {
+    return ExceptionDecl;
+  }
+  void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
+
+  SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
+  void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
+  SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
+
+  bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtCatchStmtClass;
+  }
+
+  child_range children() { return child_range(&Body, &Body + 1); }
+};
+
+/// \brief Represents Objective-C's \@finally statement
+class ObjCAtFinallyStmt : public Stmt {
+  Stmt *AtFinallyStmt;
+  SourceLocation AtFinallyLoc;
+public:
+  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
+  : Stmt(ObjCAtFinallyStmtClass),
+    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
+
+  explicit ObjCAtFinallyStmt(EmptyShell Empty) :
+    Stmt(ObjCAtFinallyStmtClass, Empty) { }
+
+  const Stmt *getFinallyBody() const { return AtFinallyStmt; }
+  Stmt *getFinallyBody() { return AtFinallyStmt; }
+  void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtFinallyLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return AtFinallyStmt->getLocEnd();
+  }
+
+  SourceLocation getAtFinallyLoc() const { return AtFinallyLoc; }
+  void setAtFinallyLoc(SourceLocation Loc) { AtFinallyLoc = Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtFinallyStmtClass;
+  }
+
+  child_range children() {
+    return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
+  }
+};
+
+/// \brief Represents Objective-C's \@try ... \@catch ... \@finally statement.
+class ObjCAtTryStmt : public Stmt {
+private:
+  // The location of the @ in the \@try.
+  SourceLocation AtTryLoc;
+  
+  // The number of catch blocks in this statement.
+  unsigned NumCatchStmts : 16;
+  
+  // Whether this statement has a \@finally statement.
+  bool HasFinally : 1;
+  
+  /// \brief Retrieve the statements that are stored after this \@try statement.
+  ///
+  /// The order of the statements in memory follows the order in the source,
+  /// with the \@try body first, followed by the \@catch statements (if any)
+  /// and, finally, the \@finally (if it exists).
+  Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
+  const Stmt* const *getStmts() const { 
+    return reinterpret_cast<const Stmt * const*> (this + 1); 
+  }
+  
+  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
+                Stmt **CatchStmts, unsigned NumCatchStmts,
+                Stmt *atFinallyStmt);
+  
+  explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
+                         bool HasFinally)
+    : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
+      HasFinally(HasFinally) { }
+
+public:
+  static ObjCAtTryStmt *Create(const ASTContext &Context,
+                               SourceLocation atTryLoc, Stmt *atTryStmt,
+                               Stmt **CatchStmts, unsigned NumCatchStmts,
+                               Stmt *atFinallyStmt);
+  static ObjCAtTryStmt *CreateEmpty(const ASTContext &Context,
+                                    unsigned NumCatchStmts, bool HasFinally);
+  
+  /// \brief Retrieve the location of the @ in the \@try.
+  SourceLocation getAtTryLoc() const { return AtTryLoc; }
+  void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
+
+  /// \brief Retrieve the \@try body.
+  const Stmt *getTryBody() const { return getStmts()[0]; }
+  Stmt *getTryBody() { return getStmts()[0]; }
+  void setTryBody(Stmt *S) { getStmts()[0] = S; }
+
+  /// \brief Retrieve the number of \@catch statements in this try-catch-finally
+  /// block.
+  unsigned getNumCatchStmts() const { return NumCatchStmts; }
+  
+  /// \brief Retrieve a \@catch statement.
+  const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
+  }
+  
+  /// \brief Retrieve a \@catch statement.
+  ObjCAtCatchStmt *getCatchStmt(unsigned I) {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
+  }
+  
+  /// \brief Set a particular catch statement.
+  void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
+    assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+    getStmts()[I + 1] = S;
+  }
+  
+  /// \brief Retrieve the \@finally statement, if any.
+  const ObjCAtFinallyStmt *getFinallyStmt() const {
+    if (!HasFinally)
+      return nullptr;
+    
+    return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
+  }
+  ObjCAtFinallyStmt *getFinallyStmt() {
+    if (!HasFinally)
+      return nullptr;
+    
+    return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
+  }
+  void setFinallyStmt(Stmt *S) { 
+    assert(HasFinally && "@try does not have a @finally slot!");
+    getStmts()[1 + NumCatchStmts] = S; 
+  }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtTryLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY;
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtTryStmtClass;
+  }
+
+  child_range children() {
+    return child_range(getStmts(),
+                       getStmts() + 1 + NumCatchStmts + HasFinally);
+  }
+};
+
+/// \brief Represents Objective-C's \@synchronized statement.
+///
+/// Example:
+/// \code
+///   @synchronized (sem) {
+///     do-something;
+///   }
+/// \endcode
+class ObjCAtSynchronizedStmt : public Stmt {
+private:
+  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
+  Stmt* SubStmts[END_EXPR];
+  SourceLocation AtSynchronizedLoc;
+
+public:
+  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
+                         Stmt *synchBody)
+  : Stmt(ObjCAtSynchronizedStmtClass) {
+    SubStmts[SYNC_EXPR] = synchExpr;
+    SubStmts[SYNC_BODY] = synchBody;
+    AtSynchronizedLoc = atSynchronizedLoc;
+  }
+  explicit ObjCAtSynchronizedStmt(EmptyShell Empty) :
+    Stmt(ObjCAtSynchronizedStmtClass, Empty) { }
+
+  SourceLocation getAtSynchronizedLoc() const { return AtSynchronizedLoc; }
+  void setAtSynchronizedLoc(SourceLocation Loc) { AtSynchronizedLoc = Loc; }
+
+  const CompoundStmt *getSynchBody() const {
+    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
+  }
+  CompoundStmt *getSynchBody() {
+    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
+  }
+  void setSynchBody(Stmt *S) { SubStmts[SYNC_BODY] = S; }
+
+  const Expr *getSynchExpr() const {
+    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+  }
+  Expr *getSynchExpr() {
+    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
+  }
+  void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtSynchronizedLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return getSynchBody()->getLocEnd();
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
+  }
+
+  child_range children() {
+    return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
+  }
+};
+
+/// \brief Represents Objective-C's \@throw statement.
+class ObjCAtThrowStmt : public Stmt {
+  Stmt *Throw;
+  SourceLocation AtThrowLoc;
+public:
+  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
+  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
+    AtThrowLoc = atThrowLoc;
+  }
+  explicit ObjCAtThrowStmt(EmptyShell Empty) :
+    Stmt(ObjCAtThrowStmtClass, Empty) { }
+
+  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
+  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
+  void setThrowExpr(Stmt *S) { Throw = S; }
+
+  SourceLocation getThrowLoc() { return AtThrowLoc; }
+  void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY {
+    return Throw ? Throw->getLocEnd() : AtThrowLoc;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAtThrowStmtClass;
+  }
+
+  child_range children() { return child_range(&Throw, &Throw+1); }
+};
+
+/// \brief Represents Objective-C's \@autoreleasepool Statement
+class ObjCAutoreleasePoolStmt : public Stmt {
+  Stmt *SubStmt;
+  SourceLocation AtLoc;
+public:
+  ObjCAutoreleasePoolStmt(SourceLocation atLoc, 
+                            Stmt *subStmt)
+  : Stmt(ObjCAutoreleasePoolStmtClass),
+    SubStmt(subStmt), AtLoc(atLoc) {}
+
+  explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
+    Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
+
+  const Stmt *getSubStmt() const { return SubStmt; }
+  Stmt *getSubStmt() { return SubStmt; }
+  void setSubStmt(Stmt *S) { SubStmt = S; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
+  }
+
+  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
new file mode 100644
index 0000000..db02afe
--- /dev/null
+++ b/include/clang/AST/StmtOpenMP.h
@@ -0,0 +1,1033 @@
+//===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines OpenMP AST classes for executable directives and
+/// clauses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTOPENMP_H
+#define LLVM_CLANG_AST_STMTOPENMP_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST classes for directives.
+//===----------------------------------------------------------------------===//
+
+/// \brief This is a basic class for representing single OpenMP executable
+/// directive.
+///
+class OMPExecutableDirective : public Stmt {
+  friend class ASTStmtReader;
+  /// \brief Kind of the directive.
+  OpenMPDirectiveKind Kind;
+  /// \brief Starting location of the directive (directive keyword).
+  SourceLocation StartLoc;
+  /// \brief Ending location of the directive.
+  SourceLocation EndLoc;
+  /// \brief Numbers of clauses.
+  const unsigned NumClauses;
+  /// \brief Number of child expressions/stmts.
+  const unsigned NumChildren;
+  /// \brief Offset from this to the start of clauses.
+  /// There are NumClauses pointers to clauses, they are followed by
+  /// NumChildren pointers to child stmts/exprs (if the directive type
+  /// requires an associated stmt, then it has to be the first of them).
+  const unsigned ClausesOffset;
+
+  /// \brief Get the clauses storage.
+  MutableArrayRef<OMPClause *> getClauses() {
+    OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
+        reinterpret_cast<char *>(this) + ClausesOffset);
+    return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+  }
+
+protected:
+  /// \brief Build instance of directive of class \a K.
+  ///
+  /// \param SC Statement class.
+  /// \param K Kind of OpenMP directive.
+  /// \param StartLoc Starting location of the directive (directive keyword).
+  /// \param EndLoc Ending location of the directive.
+  ///
+  template <typename T>
+  OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
+                         SourceLocation StartLoc, SourceLocation EndLoc,
+                         unsigned NumClauses, unsigned NumChildren)
+      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
+        EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
+        NumChildren(NumChildren),
+        ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
+                                               llvm::alignOf<OMPClause *>())) {}
+
+  /// \brief Sets the list of variables for this clause.
+  ///
+  /// \param Clauses The list of clauses for the directive.
+  ///
+  void setClauses(ArrayRef<OMPClause *> Clauses);
+
+  /// \brief Set the associated statement for the directive.
+  ///
+  /// /param S Associated statement.
+  ///
+  void setAssociatedStmt(Stmt *S) {
+    assert(hasAssociatedStmt() && "no associated statement.");
+    *child_begin() = S;
+  }
+
+public:
+  /// \brief Iterates over a filtered subrange of clauses applied to a
+  /// directive.
+  ///
+  /// This iterator visits only those declarations that meet some run-time
+  /// criteria.
+  template <class FilterPredicate> class filtered_clause_iterator {
+    ArrayRef<OMPClause *>::const_iterator Current;
+    ArrayRef<OMPClause *>::const_iterator End;
+    FilterPredicate Pred;
+    void SkipToNextClause() {
+      while (Current != End && !Pred(*Current))
+        ++Current;
+    }
+
+  public:
+    typedef const OMPClause *value_type;
+    filtered_clause_iterator() : Current(), End() {}
+    filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
+        : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
+      SkipToNextClause();
+    }
+    value_type operator*() const { return *Current; }
+    value_type operator->() const { return *Current; }
+    filtered_clause_iterator &operator++() {
+      ++Current;
+      SkipToNextClause();
+      return *this;
+    }
+
+    filtered_clause_iterator operator++(int) {
+      filtered_clause_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator!() { return Current == End; }
+    operator bool() { return Current != End; }
+  };
+
+  /// \brief Returns starting location of directive kind.
+  SourceLocation getLocStart() const { return StartLoc; }
+  /// \brief Returns ending location of directive.
+  SourceLocation getLocEnd() const { return EndLoc; }
+
+  /// \brief Set starting location of directive kind.
+  ///
+  /// \param Loc New starting location of directive.
+  ///
+  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+  /// \brief Set ending location of directive.
+  ///
+  /// \param Loc New ending location of directive.
+  ///
+  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
+
+  /// \brief Get number of clauses.
+  unsigned getNumClauses() const { return NumClauses; }
+
+  /// \brief Returns specified clause.
+  ///
+  /// \param i Number of clause.
+  ///
+  OMPClause *getClause(unsigned i) const { return clauses()[i]; }
+
+  /// \brief Returns true if directive has associated statement.
+  bool hasAssociatedStmt() const { return NumChildren > 0; }
+
+  /// \brief Returns statement associated with the directive.
+  Stmt *getAssociatedStmt() const {
+    assert(hasAssociatedStmt() && "no associated statement.");
+    return const_cast<Stmt *>(*child_begin());
+  }
+
+  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
+
+  static bool classof(const Stmt *S) {
+    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
+           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
+  }
+
+  child_range children() {
+    if (!hasAssociatedStmt())
+      return child_range();
+    Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
+    return child_range(ChildStorage, ChildStorage + NumChildren);
+  }
+
+  ArrayRef<OMPClause *> clauses() { return getClauses(); }
+
+  ArrayRef<OMPClause *> clauses() const {
+    return const_cast<OMPExecutableDirective *>(this)->getClauses();
+  }
+};
+
+/// \brief This represents '#pragma omp parallel' directive.
+///
+/// \code
+/// #pragma omp parallel private(a,b) reduction(+: c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clauses 'private'
+/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
+/// variables 'c' and 'd'.
+///
+class OMPParallelDirective : public OMPExecutableDirective {
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive (directive keyword).
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                       unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement associated with the directive.
+  ///
+  static OMPParallelDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a N clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
+                                           unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp simd' directive.
+///
+/// \code
+/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clauses 'private'
+/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
+/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
+///
+class OMPSimdDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                   unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
+                               EndLoc, NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation EndLoc, unsigned CollapsedNum,
+                                  ArrayRef<OMPClause *> Clauses,
+                                  Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                       unsigned CollapsedNum, EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSimdDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp for' directive.
+///
+/// \code
+/// #pragma omp for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp for' has clauses 'private' with the
+/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
+/// and 'd'.
+///
+class OMPForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                  unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
+                               EndLoc, NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation EndLoc, unsigned CollapsedNum,
+                                 ArrayRef<OMPClause *> Clauses,
+                                 Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                      unsigned CollapsedNum, EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp sections' directive.
+///
+/// \code
+/// #pragma omp sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp sections' has clauses 'private' with
+/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
+/// 'c' and 'd'.
+///
+class OMPSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                       unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
+                                           unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionsDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp section' directive.
+///
+/// \code
+/// #pragma omp section
+/// \endcode
+///
+class OMPSectionDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPSectionDirective()
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionDirective *Create(const ASTContext &C,
+                                     SourceLocation StartLoc,
+                                     SourceLocation EndLoc,
+                                     Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp single' directive.
+///
+/// \code
+/// #pragma omp single private(a,b) copyprivate(c,d)
+/// \endcode
+/// In this example directive '#pragma omp single' has clauses 'private' with
+/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
+///
+class OMPSingleDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                     unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSingleDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSingleDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
+                                         unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSingleDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp master' directive.
+///
+/// \code
+/// #pragma omp master
+/// \endcode
+///
+class OMPMasterDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPMasterDirective()
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPMasterDirective *Create(const ASTContext &C,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc,
+                                    Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPMasterDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp critical' directive.
+///
+/// \code
+/// #pragma omp critical
+/// \endcode
+///
+class OMPCriticalDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Name of the directive.
+  DeclarationNameInfo DirName;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
+                       SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               StartLoc, EndLoc, 0, 1),
+        DirName(Name) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPCriticalDirective()
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               SourceLocation(), SourceLocation(), 0, 1),
+        DirName() {}
+
+  /// \brief Set name of the directive.
+  ///
+  /// \param Name Name of the directive.
+  ///
+  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPCriticalDirective *
+  Create(const ASTContext &C, const DeclarationNameInfo &Name,
+         SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  /// \brief Return name of the directive.
+  ///
+  DeclarationNameInfo getDirectiveName() const { return DirName; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPCriticalDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel for' directive.
+///
+/// \code
+/// #pragma omp parallel for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel for' has clauses 'private'
+/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
+/// variables 'c' and 'd'.
+///
+class OMPParallelForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                          unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, SourceLocation(),
+                               SourceLocation(), NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelForDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses,
+                                              unsigned CollapsedNum,
+                                              EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel sections' directive.
+///
+/// \code
+/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel sections' has clauses
+/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
+/// and variables 'c' and 'd'.
+///
+class OMPParallelSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                               unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, StartLoc, EndLoc,
+                               NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, SourceLocation(),
+                               SourceLocation(), NumClauses, 1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelSectionsDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp task' directive.
+///
+/// \code
+/// #pragma omp task private(a,b) final(d)
+/// \endcode
+/// In this example directive '#pragma omp task' has clauses 'private' with the
+/// variables 'a' and 'b' and 'final' with condition 'd'.
+///
+class OMPTaskDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                   unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
+                               EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTaskDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation EndLoc,
+                                  ArrayRef<OMPClause *> Clauses,
+                                  Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                       EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp taskyield' directive.
+///
+/// \code
+/// #pragma omp taskyield
+/// \endcode
+///
+class OMPTaskyieldDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPTaskyieldDirective()
+      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPTaskyieldDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskyieldDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp barrier' directive.
+///
+/// \code
+/// #pragma omp barrier
+/// \endcode
+///
+class OMPBarrierDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPBarrierDirective()
+      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPBarrierDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPBarrierDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp taskwait' directive.
+///
+/// \code
+/// #pragma omp taskwait
+/// \endcode
+///
+class OMPTaskwaitDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPTaskwaitDirective()
+      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPTaskwaitDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskwaitDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp flush' directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
+/// and 'b'.
+/// 'omp flush' directive does not have clauses but have an optional list of
+/// variables to flush. This list of variables is stored within some fake clause
+/// FlushClause.
+class OMPFlushDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                    unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               StartLoc, EndLoc, NumClauses, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPFlushDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               0) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses (only single OMPFlushClause clause is
+  /// allowed).
+  ///
+  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                   SourceLocation EndLoc,
+                                   ArrayRef<OMPClause *> Clauses);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
+                                        unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPFlushDirectiveClass;
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
new file mode 100644
index 0000000..c71af38
--- /dev/null
+++ b/include/clang/AST/StmtVisitor.h
@@ -0,0 +1,225 @@
+//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- 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 StmtVisitor and ConstStmtVisitor interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTVISITOR_H
+#define LLVM_CLANG_AST_STMTVISITOR_H
+
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+
+namespace clang {
+
+template <typename T> struct make_ptr       { typedef       T *type; };
+template <typename T> struct make_const_ptr { typedef const T *type; };
+
+/// StmtVisitorBase - This class implements a simple visitor for Stmt
+/// subclasses. Since Expr derives from Stmt, this also includes support for
+/// visiting Exprs.
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+class StmtVisitorBase {
+public:
+
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME, CLASS) \
+ return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
+
+  RetTy Visit(PTR(Stmt) S) {
+
+    // If we have a binary expr, dispatch to the subcode of the binop.  A smart
+    // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+    // below.
+    if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
+      switch (BinOp->getOpcode()) {
+      case BO_PtrMemD:   DISPATCH(BinPtrMemD,   BinaryOperator);
+      case BO_PtrMemI:   DISPATCH(BinPtrMemI,   BinaryOperator);
+      case BO_Mul:       DISPATCH(BinMul,       BinaryOperator);
+      case BO_Div:       DISPATCH(BinDiv,       BinaryOperator);
+      case BO_Rem:       DISPATCH(BinRem,       BinaryOperator);
+      case BO_Add:       DISPATCH(BinAdd,       BinaryOperator);
+      case BO_Sub:       DISPATCH(BinSub,       BinaryOperator);
+      case BO_Shl:       DISPATCH(BinShl,       BinaryOperator);
+      case BO_Shr:       DISPATCH(BinShr,       BinaryOperator);
+
+      case BO_LT:        DISPATCH(BinLT,        BinaryOperator);
+      case BO_GT:        DISPATCH(BinGT,        BinaryOperator);
+      case BO_LE:        DISPATCH(BinLE,        BinaryOperator);
+      case BO_GE:        DISPATCH(BinGE,        BinaryOperator);
+      case BO_EQ:        DISPATCH(BinEQ,        BinaryOperator);
+      case BO_NE:        DISPATCH(BinNE,        BinaryOperator);
+
+      case BO_And:       DISPATCH(BinAnd,       BinaryOperator);
+      case BO_Xor:       DISPATCH(BinXor,       BinaryOperator);
+      case BO_Or :       DISPATCH(BinOr,        BinaryOperator);
+      case BO_LAnd:      DISPATCH(BinLAnd,      BinaryOperator);
+      case BO_LOr :      DISPATCH(BinLOr,       BinaryOperator);
+      case BO_Assign:    DISPATCH(BinAssign,    BinaryOperator);
+      case BO_MulAssign: DISPATCH(BinMulAssign, CompoundAssignOperator);
+      case BO_DivAssign: DISPATCH(BinDivAssign, CompoundAssignOperator);
+      case BO_RemAssign: DISPATCH(BinRemAssign, CompoundAssignOperator);
+      case BO_AddAssign: DISPATCH(BinAddAssign, CompoundAssignOperator);
+      case BO_SubAssign: DISPATCH(BinSubAssign, CompoundAssignOperator);
+      case BO_ShlAssign: DISPATCH(BinShlAssign, CompoundAssignOperator);
+      case BO_ShrAssign: DISPATCH(BinShrAssign, CompoundAssignOperator);
+      case BO_AndAssign: DISPATCH(BinAndAssign, CompoundAssignOperator);
+      case BO_OrAssign:  DISPATCH(BinOrAssign,  CompoundAssignOperator);
+      case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
+      case BO_Comma:     DISPATCH(BinComma,     BinaryOperator);
+      }
+    } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
+      switch (UnOp->getOpcode()) {
+      case UO_PostInc:   DISPATCH(UnaryPostInc,   UnaryOperator);
+      case UO_PostDec:   DISPATCH(UnaryPostDec,   UnaryOperator);
+      case UO_PreInc:    DISPATCH(UnaryPreInc,    UnaryOperator);
+      case UO_PreDec:    DISPATCH(UnaryPreDec,    UnaryOperator);
+      case UO_AddrOf:    DISPATCH(UnaryAddrOf,    UnaryOperator);
+      case UO_Deref:     DISPATCH(UnaryDeref,     UnaryOperator);
+      case UO_Plus:      DISPATCH(UnaryPlus,      UnaryOperator);
+      case UO_Minus:     DISPATCH(UnaryMinus,     UnaryOperator);
+      case UO_Not:       DISPATCH(UnaryNot,       UnaryOperator);
+      case UO_LNot:      DISPATCH(UnaryLNot,      UnaryOperator);
+      case UO_Real:      DISPATCH(UnaryReal,      UnaryOperator);
+      case UO_Imag:      DISPATCH(UnaryImag,      UnaryOperator);
+      case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator);
+      }
+    }
+
+    // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+    switch (S->getStmtClass()) {
+    default: llvm_unreachable("Unknown stmt kind!");
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                              \
+    case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
+#include "clang/AST/StmtNodes.inc"
+    }
+  }
+
+  // If the implementation chooses not to implement a certain visit method, fall
+  // back on VisitExpr or whatever else is the superclass.
+#define STMT(CLASS, PARENT)                                   \
+  RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
+#include "clang/AST/StmtNodes.inc"
+
+  // If the implementation doesn't implement binary operator methods, fall back
+  // on VisitBinaryOperator.
+#define BINOP_FALLBACK(NAME) \
+  RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
+    DISPATCH(BinaryOperator, BinaryOperator); \
+  }
+  BINOP_FALLBACK(PtrMemD)                    BINOP_FALLBACK(PtrMemI)
+  BINOP_FALLBACK(Mul)   BINOP_FALLBACK(Div)  BINOP_FALLBACK(Rem)
+  BINOP_FALLBACK(Add)   BINOP_FALLBACK(Sub)  BINOP_FALLBACK(Shl)
+  BINOP_FALLBACK(Shr)
+
+  BINOP_FALLBACK(LT)    BINOP_FALLBACK(GT)   BINOP_FALLBACK(LE)
+  BINOP_FALLBACK(GE)    BINOP_FALLBACK(EQ)   BINOP_FALLBACK(NE)
+  BINOP_FALLBACK(And)   BINOP_FALLBACK(Xor)  BINOP_FALLBACK(Or)
+  BINOP_FALLBACK(LAnd)  BINOP_FALLBACK(LOr)
+
+  BINOP_FALLBACK(Assign)
+  BINOP_FALLBACK(Comma)
+#undef BINOP_FALLBACK
+
+  // If the implementation doesn't implement compound assignment operator
+  // methods, fall back on VisitCompoundAssignOperator.
+#define CAO_FALLBACK(NAME) \
+  RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
+    DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
+  }
+  CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
+  CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
+  CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
+  CAO_FALLBACK(XorAssign)
+#undef CAO_FALLBACK
+
+  // If the implementation doesn't implement unary operator methods, fall back
+  // on VisitUnaryOperator.
+#define UNARYOP_FALLBACK(NAME) \
+  RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
+    DISPATCH(UnaryOperator, UnaryOperator);    \
+  }
+  UNARYOP_FALLBACK(PostInc)   UNARYOP_FALLBACK(PostDec)
+  UNARYOP_FALLBACK(PreInc)    UNARYOP_FALLBACK(PreDec)
+  UNARYOP_FALLBACK(AddrOf)    UNARYOP_FALLBACK(Deref)
+
+  UNARYOP_FALLBACK(Plus)      UNARYOP_FALLBACK(Minus)
+  UNARYOP_FALLBACK(Not)       UNARYOP_FALLBACK(LNot)
+  UNARYOP_FALLBACK(Real)      UNARYOP_FALLBACK(Imag)
+  UNARYOP_FALLBACK(Extension)
+#undef UNARYOP_FALLBACK
+
+  // Base case, ignore it. :)
+  RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+///
+/// This class does not preserve constness of Stmt pointers (see also
+/// ConstStmtVisitor).
+template<typename ImplClass, typename RetTy=void>
+class StmtVisitor
+ : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
+
+/// ConstStmtVisitor - This class implements a simple visitor for Stmt
+/// subclasses. Since Expr derives from Stmt, this also includes support for
+/// visiting Exprs.
+///
+/// This class preserves constness of Stmt pointers (see also StmtVisitor).
+template<typename ImplClass, typename RetTy=void>
+class ConstStmtVisitor
+ : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
+
+/// \brief This class implements a simple visitor for OMPClause
+/// subclasses.
+template<class ImplClass, template <typename> class Ptr, typename RetTy>
+class OMPClauseVisitorBase {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(CLASS) \
+  return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
+
+#define OPENMP_CLAUSE(Name, Class)                              \
+  RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
+#include "clang/Basic/OpenMPKinds.def"
+
+  RetTy Visit(PTR(OMPClause) S) {
+    // Top switch clause: visit each OMPClause.
+    switch (S->getClauseKind()) {
+    default: llvm_unreachable("Unknown clause kind!");
+#define OPENMP_CLAUSE(Name, Class)                              \
+    case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S));
+#include "clang/Basic/OpenMPKinds.def"
+    }
+  }
+  // Base case, ignore it. :)
+  RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
+#undef PTR
+#undef DISPATCH
+};
+
+template<class ImplClass, typename RetTy = void>
+class OMPClauseVisitor :
+      public OMPClauseVisitorBase <ImplClass, make_ptr, RetTy> {};
+template<class ImplClass, typename RetTy = void>
+class ConstOMPClauseVisitor :
+      public OMPClauseVisitorBase <ImplClass, make_const_ptr, RetTy> {};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
new file mode 100644
index 0000000..1026a78
--- /dev/null
+++ b/include/clang/AST/TemplateBase.h
@@ -0,0 +1,673 @@
+//===-- TemplateBase.h - Core classes for C++ templates ---------*- 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 definitions which are common for all kinds of
+//  template representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
+#define LLVM_CLANG_AST_TEMPLATEBASE_H
+
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+  class FoldingSetNodeID;
+}
+
+namespace clang {
+
+class DiagnosticBuilder;
+class Expr;
+struct PrintingPolicy;
+class TypeSourceInfo;
+class ValueDecl;
+
+/// \brief Represents a template argument.
+class TemplateArgument {
+public:
+  /// \brief The kind of template argument we're storing.
+  enum ArgKind {
+    /// \brief Represents an empty template argument, e.g., one that has not
+    /// been deduced.
+    Null = 0,
+    /// The template argument is a type.
+    Type,
+    /// The template argument is a declaration that was provided for a pointer,
+    /// reference, or pointer to member non-type template parameter.
+    Declaration,
+    /// The template argument is a null pointer or null pointer to member that
+    /// was provided for a non-type template parameter.
+    NullPtr,
+    /// The template argument is an integral value stored in an llvm::APSInt
+    /// that was provided for an integral non-type template parameter.
+    Integral,
+    /// The template argument is a template name that was provided for a
+    /// template template parameter.
+    Template,
+    /// The template argument is a pack expansion of a template name that was
+    /// provided for a template template parameter.
+    TemplateExpansion,
+    /// The template argument is an expression, and we've not resolved it to one
+    /// of the other forms yet, either because it's dependent or because we're
+    /// representing a non-canonical template argument (for instance, in a
+    /// TemplateSpecializationType). Also used to represent a non-dependent
+    /// __uuidof expression (a Microsoft extension).
+    Expression,
+    /// The template argument is actually a parameter pack. Arguments are stored
+    /// in the Args struct.
+    Pack
+  };
+
+private:
+  /// \brief The kind of template argument we're storing.
+
+  struct DA {
+    unsigned Kind;
+    bool ForRefParam;
+    ValueDecl *D;
+  };
+  struct I {
+    unsigned Kind;
+    // We store a decomposed APSInt with the data allocated by ASTContext if
+    // BitWidth > 64. The memory may be shared between multiple
+    // TemplateArgument instances.
+    unsigned BitWidth : 31;
+    unsigned IsUnsigned : 1;
+    union {
+      uint64_t VAL;          ///< Used to store the <= 64 bits integer value.
+      const uint64_t *pVal;  ///< Used to store the >64 bits integer value.
+    };
+    void *Type;
+  };
+  struct A {
+    unsigned Kind;
+    unsigned NumArgs;
+    const TemplateArgument *Args;
+  };
+  struct TA {
+    unsigned Kind;
+    unsigned NumExpansions;
+    void *Name;
+  };
+  struct TV {
+    unsigned Kind;
+    uintptr_t V;
+  };
+  union {
+    struct DA DeclArg;
+    struct I Integer;
+    struct A Args;
+    struct TA TemplateArg;
+    struct TV TypeOrValue;
+  };
+
+  TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
+  
+public:
+  /// \brief Construct an empty, invalid template argument.
+  TemplateArgument() {
+    TypeOrValue.Kind = Null;
+    TypeOrValue.V = 0;
+  }
+
+  /// \brief Construct a template type argument.
+  TemplateArgument(QualType T, bool isNullPtr = false) {
+    TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
+    TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+  }
+
+  /// \brief Construct a template argument that refers to a
+  /// declaration, which is either an external declaration or a
+  /// template declaration.
+  TemplateArgument(ValueDecl *D, bool ForRefParam) {
+    assert(D && "Expected decl");
+    DeclArg.Kind = Declaration;
+    DeclArg.D = D;
+    DeclArg.ForRefParam = ForRefParam;
+  }
+
+  /// \brief Construct an integral constant template argument. The memory to
+  /// store the value is allocated with Ctx.
+  TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
+
+  /// \brief Construct an integral constant template argument with the same
+  /// value as Other but a different type.
+  TemplateArgument(const TemplateArgument &Other, QualType Type) {
+    Integer = Other.Integer;
+    Integer.Type = Type.getAsOpaquePtr();
+  }
+
+  /// \brief Construct a template argument that is a template.
+  ///
+  /// This form of template argument is generally used for template template
+  /// parameters. However, the template name could be a dependent template
+  /// name that ends up being instantiated to a function template whose address
+  /// is taken.
+  ///
+  /// \param Name The template name.
+  TemplateArgument(TemplateName Name) {
+    TemplateArg.Kind = Template;
+    TemplateArg.Name = Name.getAsVoidPointer();
+    TemplateArg.NumExpansions = 0;
+  }
+
+  /// \brief Construct a template argument that is a template pack expansion.
+  ///
+  /// This form of template argument is generally used for template template
+  /// parameters. However, the template name could be a dependent template
+  /// name that ends up being instantiated to a function template whose address
+  /// is taken.
+  ///
+  /// \param Name The template name.
+  ///
+  /// \param NumExpansions The number of expansions that will be generated by
+  /// instantiating
+  TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
+    TemplateArg.Kind = TemplateExpansion;
+    TemplateArg.Name = Name.getAsVoidPointer();
+    if (NumExpansions)
+      TemplateArg.NumExpansions = *NumExpansions + 1;
+    else
+      TemplateArg.NumExpansions = 0;
+  }
+
+  /// \brief Construct a template argument that is an expression.
+  ///
+  /// This form of template argument only occurs in template argument
+  /// lists used for dependent types and for expression; it will not
+  /// occur in a non-dependent, canonical template argument list.
+  TemplateArgument(Expr *E) {
+    TypeOrValue.Kind = Expression;
+    TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
+  }
+
+  /// \brief Construct a template argument that is a template argument pack.
+  ///
+  /// We assume that storage for the template arguments provided
+  /// outlives the TemplateArgument itself.
+  TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
+    this->Args.Kind = Pack;
+    this->Args.Args = Args;
+    this->Args.NumArgs = NumArgs;
+  }
+
+  static TemplateArgument getEmptyPack() {
+    return TemplateArgument((TemplateArgument*)nullptr, 0);
+  }
+
+  /// \brief Create a new template argument pack by copying the given set of
+  /// template arguments.
+  static TemplateArgument CreatePackCopy(ASTContext &Context,
+                                         const TemplateArgument *Args,
+                                         unsigned NumArgs);
+  
+  /// \brief Return the kind of stored template argument.
+  ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
+
+  /// \brief Determine whether this template argument has no value.
+  bool isNull() const { return getKind() == Null; }
+
+  /// \brief Whether this template argument is dependent on a template
+  /// parameter such that its result can change from one instantiation to
+  /// another.
+  bool isDependent() const;
+
+  /// \brief Whether this template argument is dependent on a template
+  /// parameter.
+  bool isInstantiationDependent() const;
+
+  /// \brief Whether this template argument contains an unexpanded
+  /// parameter pack.
+  bool containsUnexpandedParameterPack() const;
+
+  /// \brief Determine whether this template argument is a pack expansion.
+  bool isPackExpansion() const;
+  
+  /// \brief Retrieve the type for a type template argument.
+  QualType getAsType() const {
+    assert(getKind() == Type && "Unexpected kind");
+    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+  }
+
+  /// \brief Retrieve the declaration for a declaration non-type
+  /// template argument.
+  ValueDecl *getAsDecl() const {
+    assert(getKind() == Declaration && "Unexpected kind");
+    return DeclArg.D;
+  }
+
+  /// \brief Retrieve whether a declaration is binding to a
+  /// reference parameter in a declaration non-type template argument.
+  bool isDeclForReferenceParam() const {
+    assert(getKind() == Declaration && "Unexpected kind");
+    return DeclArg.ForRefParam;
+  }
+
+  /// \brief Retrieve the type for null non-type template argument.
+  QualType getNullPtrType() const {
+    assert(getKind() == NullPtr && "Unexpected kind");
+    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+  }
+
+  /// \brief Retrieve the template name for a template name argument.
+  TemplateName getAsTemplate() const {
+    assert(getKind() == Template && "Unexpected kind");
+    return TemplateName::getFromVoidPointer(TemplateArg.Name);
+  }
+
+  /// \brief Retrieve the template argument as a template name; if the argument
+  /// is a pack expansion, return the pattern as a template name.
+  TemplateName getAsTemplateOrTemplatePattern() const {
+    assert((getKind() == Template || getKind() == TemplateExpansion) &&
+           "Unexpected kind");
+    
+    return TemplateName::getFromVoidPointer(TemplateArg.Name);
+  }
+
+  /// \brief Retrieve the number of expansions that a template template argument
+  /// expansion will produce, if known.
+  Optional<unsigned> getNumTemplateExpansions() const;
+  
+  /// \brief Retrieve the template argument as an integral value.
+  // FIXME: Provide a way to read the integral data without copying the value.
+  llvm::APSInt getAsIntegral() const {
+    assert(getKind() == Integral && "Unexpected kind");
+    using namespace llvm;
+    if (Integer.BitWidth <= 64)
+      return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
+
+    unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
+    return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
+                  Integer.IsUnsigned);
+  }
+
+  /// \brief Retrieve the type of the integral value.
+  QualType getIntegralType() const {
+    assert(getKind() == Integral && "Unexpected kind");
+    return QualType::getFromOpaquePtr(Integer.Type);
+  }
+
+  void setIntegralType(QualType T) {
+    assert(getKind() == Integral && "Unexpected kind");
+    Integer.Type = T.getAsOpaquePtr();
+  }
+
+  /// \brief Retrieve the template argument as an expression.
+  Expr *getAsExpr() const {
+    assert(getKind() == Expression && "Unexpected kind");
+    return reinterpret_cast<Expr *>(TypeOrValue.V);
+  }
+
+  /// \brief Iterator that traverses the elements of a template argument pack.
+  typedef const TemplateArgument * pack_iterator;
+
+  /// \brief Iterator referencing the first argument of a template argument
+  /// pack.
+  pack_iterator pack_begin() const {
+    assert(getKind() == Pack);
+    return Args.Args;
+  }
+
+  /// \brief Iterator referencing one past the last argument of a template
+  /// argument pack.
+  pack_iterator pack_end() const {
+    assert(getKind() == Pack);
+    return Args.Args + Args.NumArgs;
+  }
+
+  /// \brief Iterator range referencing all of the elements of a template
+  /// argument pack.
+  llvm::iterator_range<pack_iterator> pack_elements() const {
+    return llvm::make_range(pack_begin(), pack_end());
+  }
+
+  /// \brief The number of template arguments in the given template argument
+  /// pack.
+  unsigned pack_size() const {
+    assert(getKind() == Pack);
+    return Args.NumArgs;
+  }
+
+  /// \brief Return the array of arguments in this template argument pack.
+  ArrayRef<TemplateArgument> getPackAsArray() const {
+    assert(getKind() == Pack);
+    return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+  }
+
+  /// \brief Determines whether two template arguments are superficially the
+  /// same.
+  bool structurallyEquals(const TemplateArgument &Other) const;
+
+  /// \brief When the template argument is a pack expansion, returns
+  /// the pattern of the pack expansion.
+  TemplateArgument getPackExpansionPattern() const;
+
+  /// \brief Print this template argument to the given output stream.
+  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
+             
+  /// \brief Used to insert TemplateArguments into FoldingSets.
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
+};
+
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+
+  struct T {
+    // FIXME: We'd like to just use the qualifier in the TemplateName,
+    // but template arguments get canonicalized too quickly.
+    NestedNameSpecifier *Qualifier;
+    void *QualifierLocData;
+    unsigned TemplateNameLoc;
+    unsigned EllipsisLoc;
+  };
+
+  union {
+    struct T Template;
+    Expr *Expression;
+    TypeSourceInfo *Declarator;
+  };
+
+public:
+  TemplateArgumentLocInfo();
+  
+  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
+  
+  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
+  
+  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
+                          SourceLocation TemplateNameLoc,
+                          SourceLocation EllipsisLoc)
+  {
+    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
+    Template.QualifierLocData = QualifierLoc.getOpaqueData();
+    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
+  }
+
+  TypeSourceInfo *getAsTypeSourceInfo() const {
+    return Declarator;
+  }
+
+  Expr *getAsExpr() const {
+    return Expression;
+  }
+
+  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
+    return NestedNameSpecifierLoc(Template.Qualifier, 
+                                  Template.QualifierLocData);
+  }
+  
+  SourceLocation getTemplateNameLoc() const {
+    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
+  }
+  
+  SourceLocation getTemplateEllipsisLoc() const {
+    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
+  }
+};
+
+/// Location wrapper for a TemplateArgument.  TemplateArgument is to
+/// TemplateArgumentLoc as Type is to TypeLoc.
+class TemplateArgumentLoc {
+  TemplateArgument Argument;
+  TemplateArgumentLocInfo LocInfo;
+
+public:
+  TemplateArgumentLoc() {}
+
+  TemplateArgumentLoc(const TemplateArgument &Argument,
+                      TemplateArgumentLocInfo Opaque)
+    : Argument(Argument), LocInfo(Opaque) {
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
+    : Argument(Argument), LocInfo(TInfo) {
+    assert(Argument.getKind() == TemplateArgument::Type);
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
+    : Argument(Argument), LocInfo(E) {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+  }
+
+  TemplateArgumentLoc(const TemplateArgument &Argument, 
+                      NestedNameSpecifierLoc QualifierLoc,
+                      SourceLocation TemplateNameLoc,
+                      SourceLocation EllipsisLoc = SourceLocation())
+    : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
+  }
+  
+  /// \brief - Fetches the primary location of the argument.
+  SourceLocation getLocation() const {
+    if (Argument.getKind() == TemplateArgument::Template ||
+        Argument.getKind() == TemplateArgument::TemplateExpansion)
+      return getTemplateNameLoc();
+    
+    return getSourceRange().getBegin();
+  }
+
+  /// \brief - Fetches the full source range of the argument.
+  SourceRange getSourceRange() const LLVM_READONLY;
+
+  const TemplateArgument &getArgument() const {
+    return Argument;
+  }
+
+  TemplateArgumentLocInfo getLocInfo() const {
+    return LocInfo;
+  }
+
+  TypeSourceInfo *getTypeSourceInfo() const {
+    assert(Argument.getKind() == TemplateArgument::Type);
+    return LocInfo.getAsTypeSourceInfo();
+  }
+
+  Expr *getSourceExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Expression);
+    return LocInfo.getAsExpr();
+  }
+
+  Expr *getSourceDeclExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Declaration);
+    return LocInfo.getAsExpr();
+  }
+
+  Expr *getSourceNullPtrExpression() const {
+    assert(Argument.getKind() == TemplateArgument::NullPtr);
+    return LocInfo.getAsExpr();
+  }
+
+  Expr *getSourceIntegralExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Integral);
+    return LocInfo.getAsExpr();
+  }
+
+  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
+    return LocInfo.getTemplateQualifierLoc();
+  }
+  
+  SourceLocation getTemplateNameLoc() const {
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
+    return LocInfo.getTemplateNameLoc();
+  }  
+  
+  SourceLocation getTemplateEllipsisLoc() const {
+    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
+    return LocInfo.getTemplateEllipsisLoc();
+  }
+};
+
+/// A convenient class for passing around template argument
+/// information.  Designed to be passed by reference.
+class TemplateArgumentListInfo {
+  SmallVector<TemplateArgumentLoc, 8> Arguments;
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+
+  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
+  // instead.
+  void* operator new(size_t bytes, ASTContext& C);
+
+public:
+  TemplateArgumentListInfo() {}
+
+  TemplateArgumentListInfo(SourceLocation LAngleLoc,
+                           SourceLocation RAngleLoc)
+    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
+  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
+
+  unsigned size() const { return Arguments.size(); }
+
+  const TemplateArgumentLoc *getArgumentArray() const {
+    return Arguments.data();
+  }
+
+  const TemplateArgumentLoc &operator[](unsigned I) const {
+    return Arguments[I];
+  }
+
+  TemplateArgumentLoc &operator[](unsigned I) {
+    return Arguments[I];
+  }
+
+  void addArgument(const TemplateArgumentLoc &Loc) {
+    Arguments.push_back(Loc);
+  }
+};
+
+/// \brief Represents an explicit template argument list in C++, e.g.,
+/// the "<int>" in "sort<int>".
+/// This is safe to be used inside an AST node, in contrast with
+/// TemplateArgumentListInfo.
+struct ASTTemplateArgumentListInfo {
+  /// \brief The source location of the left angle bracket ('<').
+  SourceLocation LAngleLoc;
+  
+  /// \brief The source location of the right angle bracket ('>').
+  SourceLocation RAngleLoc;
+  
+  union {
+    /// \brief The number of template arguments in TemplateArgs.
+    /// The actual template arguments (if any) are stored after the
+    /// ExplicitTemplateArgumentList structure.
+    unsigned NumTemplateArgs;
+
+    /// Force ASTTemplateArgumentListInfo to the right alignment
+    /// for the following array of TemplateArgumentLocs.
+    llvm::AlignedCharArray<
+        llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
+  };
+
+  /// \brief Retrieve the template arguments
+  TemplateArgumentLoc *getTemplateArgs() {
+    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
+  }
+  
+  /// \brief Retrieve the template arguments
+  const TemplateArgumentLoc *getTemplateArgs() const {
+    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
+  }
+
+  const TemplateArgumentLoc &operator[](unsigned I) const {
+    return getTemplateArgs()[I];
+  }
+
+  static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
+                                          const TemplateArgumentListInfo &List);
+
+  void initializeFrom(const TemplateArgumentListInfo &List);
+  void initializeFrom(const TemplateArgumentListInfo &List,
+                      bool &Dependent, bool &InstantiationDependent,
+                      bool &ContainsUnexpandedParameterPack);
+  void copyInto(TemplateArgumentListInfo &List) const;
+  static std::size_t sizeFor(unsigned NumTemplateArgs);
+};
+
+/// \brief Extends ASTTemplateArgumentListInfo with the source location
+/// information for the template keyword; this is used as part of the
+/// representation of qualified identifiers, such as S<T>::template apply<T>.
+struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
+  typedef ASTTemplateArgumentListInfo Base;
+
+  // NOTE: the source location of the (optional) template keyword is
+  // stored after all template arguments.
+
+  /// \brief Get the source location of the template keyword.
+  SourceLocation getTemplateKeywordLoc() const {
+    return *reinterpret_cast<const SourceLocation*>
+      (getTemplateArgs() + NumTemplateArgs);
+  }
+
+  /// \brief Sets the source location of the template keyword.
+  void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
+    *reinterpret_cast<SourceLocation*>
+      (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
+  }
+
+  static const ASTTemplateKWAndArgsInfo*
+  Create(ASTContext &C, SourceLocation TemplateKWLoc,
+         const TemplateArgumentListInfo &List);
+
+  void initializeFrom(SourceLocation TemplateKWLoc,
+                      const TemplateArgumentListInfo &List);
+  void initializeFrom(SourceLocation TemplateKWLoc,
+                      const TemplateArgumentListInfo &List,
+                      bool &Dependent, bool &InstantiationDependent,
+                      bool &ContainsUnexpandedParameterPack);
+  void initializeFrom(SourceLocation TemplateKWLoc);
+
+  static std::size_t sizeFor(unsigned NumTemplateArgs);
+};
+
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    const TemplateArgument &Arg);
+
+inline TemplateSpecializationType::iterator
+    TemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
+}
+
+inline DependentTemplateSpecializationType::iterator
+    DependentTemplateSpecializationType::end() const {
+  return getArgs() + getNumArgs();
+}
+
+inline const TemplateArgument &
+    TemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+
+inline const TemplateArgument &
+    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
+  assert(Idx < getNumArgs() && "Template argument out of range");
+  return getArgs()[Idx];
+}
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
new file mode 100644
index 0000000..f3d23b9
--- /dev/null
+++ b/include/clang/AST/TemplateName.h
@@ -0,0 +1,562 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- 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 TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
+#define LLVM_CLANG_AST_TEMPLATENAME_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+  
+class ASTContext;
+class DependentTemplateName;
+class DiagnosticBuilder;
+class IdentifierInfo;
+class NamedDecl;
+class NestedNameSpecifier;
+enum OverloadedOperatorKind : int;
+class OverloadedTemplateStorage;
+struct PrintingPolicy;
+class QualifiedTemplateName;
+class SubstTemplateTemplateParmPackStorage;
+class SubstTemplateTemplateParmStorage;
+class TemplateArgument;
+class TemplateDecl;
+class TemplateTemplateParmDecl;
+  
+/// \brief Implementation class used to describe either a set of overloaded
+/// template names or an already-substituted template template parameter pack.
+class UncommonTemplateNameStorage {
+protected:
+  enum Kind {
+    Overloaded,
+    SubstTemplateTemplateParm,
+    SubstTemplateTemplateParmPack
+  };
+
+  struct BitsTag {
+    /// \brief A Kind.
+    unsigned Kind : 2;
+    
+    /// \brief The number of stored templates or template arguments,
+    /// depending on which subclass we have.
+    unsigned Size : 30;
+  };
+
+  union {
+    struct BitsTag Bits;
+    void *PointerAlignment;
+  };
+  
+  UncommonTemplateNameStorage(Kind kind, unsigned size) {
+    Bits.Kind = kind;
+    Bits.Size = size;
+  }
+  
+public:
+  unsigned size() const { return Bits.Size; }
+  
+  OverloadedTemplateStorage *getAsOverloadedStorage()  {
+    return Bits.Kind == Overloaded
+             ? reinterpret_cast<OverloadedTemplateStorage *>(this) 
+             : nullptr;
+  }
+  
+  SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
+    return Bits.Kind == SubstTemplateTemplateParm
+             ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
+             : nullptr;
+  }
+
+  SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
+    return Bits.Kind == SubstTemplateTemplateParmPack
+             ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
+             : nullptr;
+  }
+};
+  
+/// \brief A structure for storing the information associated with an
+/// overloaded template name.
+class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
+  friend class ASTContext;
+
+  OverloadedTemplateStorage(unsigned size) 
+    : UncommonTemplateNameStorage(Overloaded, size) { }
+
+  NamedDecl **getStorage() {
+    return reinterpret_cast<NamedDecl **>(this + 1);
+  }
+  NamedDecl * const *getStorage() const {
+    return reinterpret_cast<NamedDecl *const *>(this + 1);
+  }
+
+public:
+  typedef NamedDecl *const *iterator;
+
+  iterator begin() const { return getStorage(); }
+  iterator end() const { return getStorage() + size(); }
+};
+
+/// \brief A structure for storing an already-substituted template template
+/// parameter pack.
+///
+/// This kind of template names occurs when the parameter pack has been 
+/// provided with a template template argument pack in a context where its
+/// enclosing pack expansion could not be fully expanded.
+class SubstTemplateTemplateParmPackStorage
+  : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
+{
+  TemplateTemplateParmDecl *Parameter;
+  const TemplateArgument *Arguments;
+  
+public:
+  SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
+                                       unsigned Size, 
+                                       const TemplateArgument *Arguments)
+    : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
+      Parameter(Parameter), Arguments(Arguments) { }
+  
+  /// \brief Retrieve the template template parameter pack being substituted.
+  TemplateTemplateParmDecl *getParameterPack() const {
+    return Parameter;
+  }
+  
+  /// \brief Retrieve the template template argument pack with which this
+  /// parameter was substituted.
+  TemplateArgument getArgumentPack() const;
+  
+  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
+  
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      ASTContext &Context,
+                      TemplateTemplateParmDecl *Parameter,
+                      const TemplateArgument &ArgPack);
+};
+
+/// \brief Represents a C++ template name within the type system.
+///
+/// A C++ template name refers to a template within the C++ type
+/// system. In most cases, a template name is simply a reference to a
+/// class template, e.g.
+///
+/// \code
+/// template<typename T> class X { };
+///
+/// X<int> xi;
+/// \endcode
+///
+/// Here, the 'X' in \c X<int> is a template name that refers to the
+/// declaration of the class template X, above. Template names can
+/// also refer to function templates, C++0x template aliases, etc.
+///
+/// Some template names are dependent. For example, consider:
+///
+/// \code
+/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
+///   typedef typename MetaFun::template apply<T1, T2>::type type;
+/// };
+/// \endcode
+///
+/// Here, "apply" is treated as a template name within the typename
+/// specifier in the typedef. "apply" is a nested template, and can
+/// only be understood in the context of
+class TemplateName {
+  typedef llvm::PointerUnion4<TemplateDecl *,
+                              UncommonTemplateNameStorage *,
+                              QualifiedTemplateName *,
+                              DependentTemplateName *> StorageType;
+
+  StorageType Storage;
+
+  explicit TemplateName(void *Ptr) {
+    Storage = StorageType::getFromOpaqueValue(Ptr);
+  }
+
+public:
+  // \brief Kind of name that is actually stored.
+  enum NameKind {
+    /// \brief A single template declaration.
+    Template,
+    /// \brief A set of overloaded template declarations.
+    OverloadedTemplate,
+    /// \brief A qualified template name, where the qualification is kept 
+    /// to describe the source code as written.
+    QualifiedTemplate,
+    /// \brief A dependent template name that has not been resolved to a 
+    /// template (or set of templates).
+    DependentTemplate,
+    /// \brief A template template parameter that has been substituted
+    /// for some other template name.
+    SubstTemplateTemplateParm,
+    /// \brief A template template parameter pack that has been substituted for 
+    /// a template template argument pack, but has not yet been expanded into
+    /// individual arguments.
+    SubstTemplateTemplateParmPack
+  };
+
+  TemplateName() : Storage() { }
+  explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
+  explicit TemplateName(OverloadedTemplateStorage *Storage)
+    : Storage(Storage) { }
+  explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
+  explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
+    : Storage(Storage) { }
+  explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
+  explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
+
+  /// \brief Determine whether this template name is NULL.
+  bool isNull() const { return Storage.isNull(); }
+  
+  // \brief Get the kind of name that is actually stored.
+  NameKind getKind() const;
+
+  /// \brief Retrieve the underlying template declaration that
+  /// this template name refers to, if known.
+  ///
+  /// \returns The template declaration that this template name refers
+  /// to, if any. If the template name does not refer to a specific
+  /// declaration because it is a dependent name, or if it refers to a
+  /// set of function templates, returns NULL.
+  TemplateDecl *getAsTemplateDecl() const;
+
+  /// \brief Retrieve the underlying, overloaded function template
+  // declarations that this template name refers to, if known.
+  ///
+  /// \returns The set of overloaded function templates that this template
+  /// name refers to, if known. If the template name does not refer to a
+  /// specific set of function templates because it is a dependent name or
+  /// refers to a single template, returns NULL.
+  OverloadedTemplateStorage *getAsOverloadedTemplate() const {
+    if (UncommonTemplateNameStorage *Uncommon = 
+                              Storage.dyn_cast<UncommonTemplateNameStorage *>())
+      return Uncommon->getAsOverloadedStorage();
+    
+    return nullptr;
+  }
+
+  /// \brief Retrieve the substituted template template parameter, if 
+  /// known.
+  ///
+  /// \returns The storage for the substituted template template parameter,
+  /// if known. Otherwise, returns NULL.
+  SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
+    if (UncommonTemplateNameStorage *uncommon = 
+          Storage.dyn_cast<UncommonTemplateNameStorage *>())
+      return uncommon->getAsSubstTemplateTemplateParm();
+    
+    return nullptr;
+  }
+
+  /// \brief Retrieve the substituted template template parameter pack, if 
+  /// known.
+  ///
+  /// \returns The storage for the substituted template template parameter pack,
+  /// if known. Otherwise, returns NULL.
+  SubstTemplateTemplateParmPackStorage *
+  getAsSubstTemplateTemplateParmPack() const {
+    if (UncommonTemplateNameStorage *Uncommon = 
+        Storage.dyn_cast<UncommonTemplateNameStorage *>())
+      return Uncommon->getAsSubstTemplateTemplateParmPack();
+    
+    return nullptr;
+  }
+
+  /// \brief Retrieve the underlying qualified template name
+  /// structure, if any.
+  QualifiedTemplateName *getAsQualifiedTemplateName() const {
+    return Storage.dyn_cast<QualifiedTemplateName *>();
+  }
+
+  /// \brief Retrieve the underlying dependent template name
+  /// structure, if any.
+  DependentTemplateName *getAsDependentTemplateName() const {
+    return Storage.dyn_cast<DependentTemplateName *>();
+  }
+
+  TemplateName getUnderlying() const;
+
+  /// \brief Determines whether this is a dependent template name.
+  bool isDependent() const;
+
+  /// \brief Determines whether this is a template name that somehow
+  /// depends on a template parameter.
+  bool isInstantiationDependent() const;
+
+  /// \brief Determines whether this template name contains an
+  /// unexpanded parameter pack (for C++0x variadic templates).
+  bool containsUnexpandedParameterPack() const;
+
+  /// \brief Print the template name.
+  ///
+  /// \param OS the output stream to which the template name will be
+  /// printed.
+  ///
+  /// \param SuppressNNS if true, don't print the
+  /// nested-name-specifier that precedes the template name (if it has
+  /// one).
+  void print(raw_ostream &OS, const PrintingPolicy &Policy,
+             bool SuppressNNS = false) const;
+
+  /// \brief Debugging aid that dumps the template name.
+  void dump(raw_ostream &OS) const;
+
+  /// \brief Debugging aid that dumps the template name to standard
+  /// error.
+  void dump() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddPointer(Storage.getOpaqueValue());
+  }
+
+  /// \brief Retrieve the template name as a void pointer.
+  void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
+
+  /// \brief Build a template name from a void pointer.
+  static TemplateName getFromVoidPointer(void *Ptr) {
+    return TemplateName(Ptr);
+  }
+};
+
+/// Insertion operator for diagnostics.  This allows sending TemplateName's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    TemplateName N);
+
+/// \brief A structure for storing the information associated with a
+/// substituted template template parameter.
+class SubstTemplateTemplateParmStorage
+  : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
+  friend class ASTContext;
+
+  TemplateTemplateParmDecl *Parameter;
+  TemplateName Replacement;
+
+  SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
+                                   TemplateName replacement)
+    : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
+      Parameter(parameter), Replacement(replacement) {}
+
+public:
+  TemplateTemplateParmDecl *getParameter() const { return Parameter; }
+  TemplateName getReplacement() const { return Replacement; }
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      TemplateTemplateParmDecl *parameter,
+                      TemplateName replacement);
+};
+
+inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
+  : Storage(Storage) { }
+
+inline TemplateName TemplateName::getUnderlying() const {
+  if (SubstTemplateTemplateParmStorage *subst
+        = getAsSubstTemplateTemplateParm())
+    return subst->getReplacement().getUnderlying();
+  return *this;
+}
+
+/// \brief Represents a template name that was expressed as a
+/// qualified name.
+///
+/// This kind of template name refers to a template name that was
+/// preceded by a nested name specifier, e.g., \c std::vector. Here,
+/// the nested name specifier is "std::" and the template name is the
+/// declaration for "vector". The QualifiedTemplateName class is only
+/// used to provide "sugar" for template names that were expressed
+/// with a qualified name, and has no semantic meaning. In this
+/// manner, it is to TemplateName what ElaboratedType is to Type,
+/// providing extra syntactic sugar for downstream clients.
+class QualifiedTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template name.
+  ///
+  /// The bit is used to indicate whether the "template" keyword was
+  /// present before the template name itself. Note that the
+  /// "template" keyword is always redundant in this case (otherwise,
+  /// the template name would be a dependent name and we would express
+  /// this name with DependentTemplateName).
+  llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
+
+  /// \brief The template declaration or set of overloaded function templates
+  /// that this qualified name refers to.
+  TemplateDecl *Template;
+
+  friend class ASTContext;
+
+  QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
+                        TemplateDecl *Template)
+    : Qualifier(NNS, TemplateKeyword? 1 : 0),
+      Template(Template) { }
+
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+  /// \brief Whether the template name was prefixed by the "template"
+  /// keyword.
+  bool hasTemplateKeyword() const { return Qualifier.getInt(); }
+
+  /// \brief The template declaration that this qualified name refers
+  /// to.
+  TemplateDecl *getDecl() const { return Template; }
+
+  /// \brief The template declaration to which this qualified name
+  /// refers.
+  TemplateDecl *getTemplateDecl() const { return Template; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      bool TemplateKeyword, TemplateDecl *Template) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(TemplateKeyword);
+    ID.AddPointer(Template);
+  }
+};
+
+/// \brief Represents a dependent template name that cannot be
+/// resolved prior to template instantiation.
+///
+/// This kind of template name refers to a dependent template name,
+/// including its nested name specifier (if any). For example,
+/// DependentTemplateName can refer to "MetaFun::template apply",
+/// where "MetaFun::" is the nested name specifier and "apply" is the
+/// template name referenced. The "template" keyword is implied.
+class DependentTemplateName : public llvm::FoldingSetNode {
+  /// \brief The nested name specifier that qualifies the template
+  /// name.
+  ///
+  /// The bit stored in this qualifier describes whether the \c Name field
+  /// is interpreted as an IdentifierInfo pointer (when clear) or as an
+  /// overloaded operator kind (when set).
+  llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
+
+  /// \brief The dependent template name.
+  union {
+    /// \brief The identifier template name.
+    ///
+    /// Only valid when the bit on \c Qualifier is clear.
+    const IdentifierInfo *Identifier;
+    
+    /// \brief The overloaded operator name.
+    ///
+    /// Only valid when the bit on \c Qualifier is set.
+    OverloadedOperatorKind Operator;
+  };
+
+  /// \brief The canonical template name to which this dependent
+  /// template name refers.
+  ///
+  /// The canonical template name for a dependent template name is
+  /// another dependent template name whose nested name specifier is
+  /// canonical.
+  TemplateName CanonicalTemplateName;
+
+  friend class ASTContext;
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        const IdentifierInfo *Identifier)
+    : Qualifier(Qualifier, false), Identifier(Identifier), 
+      CanonicalTemplateName(this) { }
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        const IdentifierInfo *Identifier,
+                        TemplateName Canon)
+    : Qualifier(Qualifier, false), Identifier(Identifier), 
+      CanonicalTemplateName(Canon) { }
+
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        OverloadedOperatorKind Operator)
+  : Qualifier(Qualifier, true), Operator(Operator), 
+    CanonicalTemplateName(this) { }
+  
+  DependentTemplateName(NestedNameSpecifier *Qualifier,
+                        OverloadedOperatorKind Operator,
+                        TemplateName Canon)
+  : Qualifier(Qualifier, true), Operator(Operator), 
+    CanonicalTemplateName(Canon) { }
+  
+public:
+  /// \brief Return the nested name specifier that qualifies this name.
+  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+  /// \brief Determine whether this template name refers to an identifier.
+  bool isIdentifier() const { return !Qualifier.getInt(); }
+
+  /// \brief Returns the identifier to which this template name refers.
+  const IdentifierInfo *getIdentifier() const { 
+    assert(isIdentifier() && "Template name isn't an identifier?");
+    return Identifier;
+  }
+  
+  /// \brief Determine whether this template name refers to an overloaded
+  /// operator.
+  bool isOverloadedOperator() const { return Qualifier.getInt(); }
+  
+  /// \brief Return the overloaded operator to which this template name refers.
+  OverloadedOperatorKind getOperator() const { 
+    assert(isOverloadedOperator() &&
+           "Template name isn't an overloaded operator?");
+    return Operator; 
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    if (isIdentifier())
+      Profile(ID, getQualifier(), getIdentifier());
+    else
+      Profile(ID, getQualifier(), getOperator());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      const IdentifierInfo *Identifier) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(false);
+    ID.AddPointer(Identifier);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+                      OverloadedOperatorKind Operator) {
+    ID.AddPointer(NNS);
+    ID.AddBoolean(true);
+    ID.AddInteger(Operator);
+  }
+};
+
+} // end namespace clang.
+
+namespace llvm {
+
+/// \brief The clang::TemplateName class is effectively a pointer.
+template<>
+class PointerLikeTypeTraits<clang::TemplateName> {
+public:
+  static inline void *getAsVoidPointer(clang::TemplateName TN) {
+    return TN.getAsVoidPointer();
+  }
+
+  static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
+    return clang::TemplateName::getFromVoidPointer(Ptr);
+  }
+
+  // No bits are available!
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm.
+
+#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
new file mode 100644
index 0000000..09862e4
--- /dev/null
+++ b/include/clang/AST/Type.h
@@ -0,0 +1,5247 @@
+//===--- Type.h - C Language Family Type Representation ---------*- 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 Type interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPE_H
+#define LLVM_CLANG_AST_TYPE_H
+
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+  enum {
+    TypeAlignmentInBits = 4,
+    TypeAlignment = 1 << TypeAlignmentInBits
+  };
+  class Type;
+  class ExtQuals;
+  class QualType;
+}
+
+namespace llvm {
+  template <typename T>
+  class PointerLikeTypeTraits;
+  template<>
+  class PointerLikeTypeTraits< ::clang::Type*> {
+  public:
+    static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
+    static inline ::clang::Type *getFromVoidPointer(void *P) {
+      return static_cast< ::clang::Type*>(P);
+    }
+    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+  };
+  template<>
+  class PointerLikeTypeTraits< ::clang::ExtQuals*> {
+  public:
+    static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
+    static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
+      return static_cast< ::clang::ExtQuals*>(P);
+    }
+    enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
+  };
+
+  template <>
+  struct isPodLike<clang::QualType> { static const bool value = true; };
+}
+
+namespace clang {
+  class ASTContext;
+  class TypedefNameDecl;
+  class TemplateDecl;
+  class TemplateTypeParmDecl;
+  class NonTypeTemplateParmDecl;
+  class TemplateTemplateParmDecl;
+  class TagDecl;
+  class RecordDecl;
+  class CXXRecordDecl;
+  class EnumDecl;
+  class FieldDecl;
+  class FunctionDecl;
+  class ObjCInterfaceDecl;
+  class ObjCProtocolDecl;
+  class ObjCMethodDecl;
+  class UnresolvedUsingTypenameDecl;
+  class Expr;
+  class Stmt;
+  class SourceLocation;
+  class StmtIteratorBase;
+  class TemplateArgument;
+  class TemplateArgumentLoc;
+  class TemplateArgumentListInfo;
+  class ElaboratedType;
+  class ExtQuals;
+  class ExtQualsTypeCommonBase;
+  struct PrintingPolicy;
+
+  template <typename> class CanQual;
+  typedef CanQual<Type> CanQualType;
+
+  // Provide forward declarations for all of the *Type classes
+#define TYPE(Class, Base) class Class##Type;
+#include "clang/AST/TypeNodes.def"
+
+/// Qualifiers - The collection of all-type qualifiers we support.
+/// Clang supports five independent qualifiers:
+/// * C99: const, volatile, and restrict
+/// * Embedded C (TR18037): address spaces
+/// * Objective C: the GC attributes (none, weak, or strong)
+class Qualifiers {
+public:
+  enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
+    Const    = 0x1,
+    Restrict = 0x2,
+    Volatile = 0x4,
+    CVRMask = Const | Volatile | Restrict
+  };
+
+  enum GC {
+    GCNone = 0,
+    Weak,
+    Strong
+  };
+
+  enum ObjCLifetime {
+    /// There is no lifetime qualification on this type.
+    OCL_None,
+
+    /// This object can be modified without requiring retains or
+    /// releases.
+    OCL_ExplicitNone,
+
+    /// Assigning into this object requires the old value to be
+    /// released and the new value to be retained.  The timing of the
+    /// release of the old value is inexact: it may be moved to
+    /// immediately after the last known point where the value is
+    /// live.
+    OCL_Strong,
+
+    /// Reading or writing from this object requires a barrier call.
+    OCL_Weak,
+
+    /// Assigning into this object requires a lifetime extension.
+    OCL_Autoreleasing
+  };
+
+  enum {
+    /// The maximum supported address space number.
+    /// 24 bits should be enough for anyone.
+    MaxAddressSpace = 0xffffffu,
+
+    /// The width of the "fast" qualifier mask.
+    FastWidth = 3,
+
+    /// The fast qualifier mask.
+    FastMask = (1 << FastWidth) - 1
+  };
+
+  Qualifiers() : Mask(0) {}
+
+  /// \brief Returns the common set of qualifiers while removing them from
+  /// the given sets.
+  static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
+    // If both are only CVR-qualified, bit operations are sufficient.
+    if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
+      Qualifiers Q;
+      Q.Mask = L.Mask & R.Mask;
+      L.Mask &= ~Q.Mask;
+      R.Mask &= ~Q.Mask;
+      return Q;
+    }
+
+    Qualifiers Q;
+    unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
+    Q.addCVRQualifiers(CommonCRV);
+    L.removeCVRQualifiers(CommonCRV);
+    R.removeCVRQualifiers(CommonCRV);
+
+    if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
+      Q.setObjCGCAttr(L.getObjCGCAttr());
+      L.removeObjCGCAttr();
+      R.removeObjCGCAttr();
+    }
+
+    if (L.getObjCLifetime() == R.getObjCLifetime()) {
+      Q.setObjCLifetime(L.getObjCLifetime());
+      L.removeObjCLifetime();
+      R.removeObjCLifetime();
+    }
+
+    if (L.getAddressSpace() == R.getAddressSpace()) {
+      Q.setAddressSpace(L.getAddressSpace());
+      L.removeAddressSpace();
+      R.removeAddressSpace();
+    }
+    return Q;
+  }
+
+  static Qualifiers fromFastMask(unsigned Mask) {
+    Qualifiers Qs;
+    Qs.addFastQualifiers(Mask);
+    return Qs;
+  }
+
+  static Qualifiers fromCVRMask(unsigned CVR) {
+    Qualifiers Qs;
+    Qs.addCVRQualifiers(CVR);
+    return Qs;
+  }
+
+  // Deserialize qualifiers from an opaque representation.
+  static Qualifiers fromOpaqueValue(unsigned opaque) {
+    Qualifiers Qs;
+    Qs.Mask = opaque;
+    return Qs;
+  }
+
+  // Serialize these qualifiers into an opaque representation.
+  unsigned getAsOpaqueValue() const {
+    return Mask;
+  }
+
+  bool hasConst() const { return Mask & Const; }
+  void setConst(bool flag) {
+    Mask = (Mask & ~Const) | (flag ? Const : 0);
+  }
+  void removeConst() { Mask &= ~Const; }
+  void addConst() { Mask |= Const; }
+
+  bool hasVolatile() const { return Mask & Volatile; }
+  void setVolatile(bool flag) {
+    Mask = (Mask & ~Volatile) | (flag ? Volatile : 0);
+  }
+  void removeVolatile() { Mask &= ~Volatile; }
+  void addVolatile() { Mask |= Volatile; }
+
+  bool hasRestrict() const { return Mask & Restrict; }
+  void setRestrict(bool flag) {
+    Mask = (Mask & ~Restrict) | (flag ? Restrict : 0);
+  }
+  void removeRestrict() { Mask &= ~Restrict; }
+  void addRestrict() { Mask |= Restrict; }
+
+  bool hasCVRQualifiers() const { return getCVRQualifiers(); }
+  unsigned getCVRQualifiers() const { return Mask & CVRMask; }
+  void setCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask = (Mask & ~CVRMask) | mask;
+  }
+  void removeCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask &= ~mask;
+  }
+  void removeCVRQualifiers() {
+    removeCVRQualifiers(CVRMask);
+  }
+  void addCVRQualifiers(unsigned mask) {
+    assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits");
+    Mask |= mask;
+  }
+
+  bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
+  GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
+  void setObjCGCAttr(GC type) {
+    Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
+  }
+  void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
+  void addObjCGCAttr(GC type) {
+    assert(type);
+    setObjCGCAttr(type);
+  }
+  Qualifiers withoutObjCGCAttr() const {
+    Qualifiers qs = *this;
+    qs.removeObjCGCAttr();
+    return qs;
+  }
+  Qualifiers withoutObjCLifetime() const {
+    Qualifiers qs = *this;
+    qs.removeObjCLifetime();
+    return qs;
+  }
+
+  bool hasObjCLifetime() const { return Mask & LifetimeMask; }
+  ObjCLifetime getObjCLifetime() const {
+    return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
+  }
+  void setObjCLifetime(ObjCLifetime type) {
+    Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
+  }
+  void removeObjCLifetime() { setObjCLifetime(OCL_None); }
+  void addObjCLifetime(ObjCLifetime type) {
+    assert(type);
+    assert(!hasObjCLifetime());
+    Mask |= (type << LifetimeShift);
+  }
+
+  /// True if the lifetime is neither None or ExplicitNone.
+  bool hasNonTrivialObjCLifetime() const {
+    ObjCLifetime lifetime = getObjCLifetime();
+    return (lifetime > OCL_ExplicitNone);
+  }
+
+  /// True if the lifetime is either strong or weak.
+  bool hasStrongOrWeakObjCLifetime() const {
+    ObjCLifetime lifetime = getObjCLifetime();
+    return (lifetime == OCL_Strong || lifetime == OCL_Weak);
+  }
+
+  bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
+  unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
+  void setAddressSpace(unsigned space) {
+    assert(space <= MaxAddressSpace);
+    Mask = (Mask & ~AddressSpaceMask)
+         | (((uint32_t) space) << AddressSpaceShift);
+  }
+  void removeAddressSpace() { setAddressSpace(0); }
+  void addAddressSpace(unsigned space) {
+    assert(space);
+    setAddressSpace(space);
+  }
+
+  // Fast qualifiers are those that can be allocated directly
+  // on a QualType object.
+  bool hasFastQualifiers() const { return getFastQualifiers(); }
+  unsigned getFastQualifiers() const { return Mask & FastMask; }
+  void setFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask = (Mask & ~FastMask) | mask;
+  }
+  void removeFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask &= ~mask;
+  }
+  void removeFastQualifiers() {
+    removeFastQualifiers(FastMask);
+  }
+  void addFastQualifiers(unsigned mask) {
+    assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits");
+    Mask |= mask;
+  }
+
+  /// hasNonFastQualifiers - Return true if the set contains any
+  /// qualifiers which require an ExtQuals node to be allocated.
+  bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
+  Qualifiers getNonFastQualifiers() const {
+    Qualifiers Quals = *this;
+    Quals.setFastQualifiers(0);
+    return Quals;
+  }
+
+  /// hasQualifiers - Return true if the set contains any qualifiers.
+  bool hasQualifiers() const { return Mask; }
+  bool empty() const { return !Mask; }
+
+  /// \brief Add the qualifiers from the given set to this set.
+  void addQualifiers(Qualifiers Q) {
+    // If the other set doesn't have any non-boolean qualifiers, just
+    // bit-or it in.
+    if (!(Q.Mask & ~CVRMask))
+      Mask |= Q.Mask;
+    else {
+      Mask |= (Q.Mask & CVRMask);
+      if (Q.hasAddressSpace())
+        addAddressSpace(Q.getAddressSpace());
+      if (Q.hasObjCGCAttr())
+        addObjCGCAttr(Q.getObjCGCAttr());
+      if (Q.hasObjCLifetime())
+        addObjCLifetime(Q.getObjCLifetime());
+    }
+  }
+
+  /// \brief Remove the qualifiers from the given set from this set.
+  void removeQualifiers(Qualifiers Q) {
+    // If the other set doesn't have any non-boolean qualifiers, just
+    // bit-and the inverse in.
+    if (!(Q.Mask & ~CVRMask))
+      Mask &= ~Q.Mask;
+    else {
+      Mask &= ~(Q.Mask & CVRMask);
+      if (getObjCGCAttr() == Q.getObjCGCAttr())
+        removeObjCGCAttr();
+      if (getObjCLifetime() == Q.getObjCLifetime())
+        removeObjCLifetime();
+      if (getAddressSpace() == Q.getAddressSpace())
+        removeAddressSpace();
+    }
+  }
+
+  /// \brief Add the qualifiers from the given set to this set, given that
+  /// they don't conflict.
+  void addConsistentQualifiers(Qualifiers qs) {
+    assert(getAddressSpace() == qs.getAddressSpace() ||
+           !hasAddressSpace() || !qs.hasAddressSpace());
+    assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
+           !hasObjCGCAttr() || !qs.hasObjCGCAttr());
+    assert(getObjCLifetime() == qs.getObjCLifetime() ||
+           !hasObjCLifetime() || !qs.hasObjCLifetime());
+    Mask |= qs.Mask;
+  }
+
+  /// \brief Determines if these qualifiers compatibly include another set.
+  /// Generally this answers the question of whether an object with the other
+  /// qualifiers can be safely used as an object with these qualifiers.
+  bool compatiblyIncludes(Qualifiers other) const {
+    return
+      // Address spaces must match exactly.
+      getAddressSpace() == other.getAddressSpace() &&
+      // ObjC GC qualifiers can match, be added, or be removed, but can't be
+      // changed.
+      (getObjCGCAttr() == other.getObjCGCAttr() ||
+       !hasObjCGCAttr() || !other.hasObjCGCAttr()) &&
+      // ObjC lifetime qualifiers must match exactly.
+      getObjCLifetime() == other.getObjCLifetime() &&
+      // CVR qualifiers may subset.
+      (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
+  }
+
+  /// \brief Determines if these qualifiers compatibly include another set of
+  /// qualifiers from the narrow perspective of Objective-C ARC lifetime.
+  ///
+  /// One set of Objective-C lifetime qualifiers compatibly includes the other
+  /// if the lifetime qualifiers match, or if both are non-__weak and the
+  /// including set also contains the 'const' qualifier.
+  bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
+    if (getObjCLifetime() == other.getObjCLifetime())
+      return true;
+
+    if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
+      return false;
+
+    return hasConst();
+  }
+
+  /// \brief Determine whether this set of qualifiers is a strict superset of
+  /// another set of qualifiers, not considering qualifier compatibility.
+  bool isStrictSupersetOf(Qualifiers Other) const;
+
+  bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
+  bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
+
+  LLVM_EXPLICIT operator bool() const { return hasQualifiers(); }
+
+  Qualifiers &operator+=(Qualifiers R) {
+    addQualifiers(R);
+    return *this;
+  }
+
+  // Union two qualifier sets.  If an enumerated qualifier appears
+  // in both sets, use the one from the right.
+  friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
+    L += R;
+    return L;
+  }
+
+  Qualifiers &operator-=(Qualifiers R) {
+    removeQualifiers(R);
+    return *this;
+  }
+
+  /// \brief Compute the difference between two qualifier sets.
+  friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
+    L -= R;
+    return L;
+  }
+
+  std::string getAsString() const;
+  std::string getAsString(const PrintingPolicy &Policy) const;
+
+  bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
+  void print(raw_ostream &OS, const PrintingPolicy &Policy,
+             bool appendSpaceIfNonEmpty = false) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(Mask);
+  }
+
+private:
+
+  // bits:     |0 1 2|3 .. 4|5  ..  7|8   ...   31|
+  //           |C R V|GCAttr|Lifetime|AddressSpace|
+  uint32_t Mask;
+
+  static const uint32_t GCAttrMask = 0x18;
+  static const uint32_t GCAttrShift = 3;
+  static const uint32_t LifetimeMask = 0xE0;
+  static const uint32_t LifetimeShift = 5;
+  static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
+  static const uint32_t AddressSpaceShift = 8;
+};
+
+/// A std::pair-like structure for storing a qualified type split
+/// into its local qualifiers and its locally-unqualified type.
+struct SplitQualType {
+  /// The locally-unqualified type.
+  const Type *Ty;
+
+  /// The local qualifiers.
+  Qualifiers Quals;
+
+  SplitQualType() : Ty(nullptr), Quals() {}
+  SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
+
+  SplitQualType getSingleStepDesugaredType() const; // end of this file
+
+  // Make std::tie work.
+  std::pair<const Type *,Qualifiers> asPair() const {
+    return std::pair<const Type *, Qualifiers>(Ty, Quals);
+  }
+
+  friend bool operator==(SplitQualType a, SplitQualType b) {
+    return a.Ty == b.Ty && a.Quals == b.Quals;
+  }
+  friend bool operator!=(SplitQualType a, SplitQualType b) {
+    return a.Ty != b.Ty || a.Quals != b.Quals;
+  }
+};
+
+/// QualType - For efficiency, we don't store CV-qualified types as nodes on
+/// their own: instead each reference to a type stores the qualifiers.  This
+/// greatly reduces the number of nodes we need to allocate for types (for
+/// example we only need one for 'int', 'const int', 'volatile int',
+/// 'const volatile int', etc).
+///
+/// As an added efficiency bonus, instead of making this a pair, we
+/// just store the two bits we care about in the low bits of the
+/// pointer.  To handle the packing/unpacking, we make QualType be a
+/// simple wrapper class that acts like a smart pointer.  A third bit
+/// indicates whether there are extended qualifiers present, in which
+/// case the pointer points to a special structure.
+class QualType {
+  // Thankfully, these are efficiently composable.
+  llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
+                       Qualifiers::FastWidth> Value;
+
+  const ExtQuals *getExtQualsUnsafe() const {
+    return Value.getPointer().get<const ExtQuals*>();
+  }
+
+  const Type *getTypePtrUnsafe() const {
+    return Value.getPointer().get<const Type*>();
+  }
+
+  const ExtQualsTypeCommonBase *getCommonPtr() const {
+    assert(!isNull() && "Cannot retrieve a NULL type pointer");
+    uintptr_t CommonPtrVal
+      = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
+    CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
+    return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
+  }
+
+  friend class QualifierCollector;
+public:
+  QualType() {}
+
+  QualType(const Type *Ptr, unsigned Quals)
+    : Value(Ptr, Quals) {}
+  QualType(const ExtQuals *Ptr, unsigned Quals)
+    : Value(Ptr, Quals) {}
+
+  unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+  void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+
+  /// Retrieves a pointer to the underlying (unqualified) type.
+  ///
+  /// This function requires that the type not be NULL. If the type might be
+  /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
+  const Type *getTypePtr() const;
+
+  const Type *getTypePtrOrNull() const;
+
+  /// Retrieves a pointer to the name of the base type.
+  const IdentifierInfo *getBaseTypeIdentifier() const;
+
+  /// Divides a QualType into its unqualified type and a set of local
+  /// qualifiers.
+  SplitQualType split() const;
+
+  void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
+  static QualType getFromOpaquePtr(const void *Ptr) {
+    QualType T;
+    T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
+    return T;
+  }
+
+  const Type &operator*() const {
+    return *getTypePtr();
+  }
+
+  const Type *operator->() const {
+    return getTypePtr();
+  }
+
+  bool isCanonical() const;
+  bool isCanonicalAsParam() const;
+
+  /// isNull - Return true if this QualType doesn't point to a type yet.
+  bool isNull() const {
+    return Value.getPointer().isNull();
+  }
+
+  /// \brief Determine whether this particular QualType instance has the
+  /// "const" qualifier set, without looking through typedefs that may have
+  /// added "const" at a different level.
+  bool isLocalConstQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Const);
+  }
+
+  /// \brief Determine whether this type is const-qualified.
+  bool isConstQualified() const;
+
+  /// \brief Determine whether this particular QualType instance has the
+  /// "restrict" qualifier set, without looking through typedefs that may have
+  /// added "restrict" at a different level.
+  bool isLocalRestrictQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Restrict);
+  }
+
+  /// \brief Determine whether this type is restrict-qualified.
+  bool isRestrictQualified() const;
+
+  /// \brief Determine whether this particular QualType instance has the
+  /// "volatile" qualifier set, without looking through typedefs that may have
+  /// added "volatile" at a different level.
+  bool isLocalVolatileQualified() const {
+    return (getLocalFastQualifiers() & Qualifiers::Volatile);
+  }
+
+  /// \brief Determine whether this type is volatile-qualified.
+  bool isVolatileQualified() const;
+
+  /// \brief Determine whether this particular QualType instance has any
+  /// qualifiers, without looking through any typedefs that might add
+  /// qualifiers at a different level.
+  bool hasLocalQualifiers() const {
+    return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
+  }
+
+  /// \brief Determine whether this type has any qualifiers.
+  bool hasQualifiers() const;
+
+  /// \brief Determine whether this particular QualType instance has any
+  /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+  /// instance.
+  bool hasLocalNonFastQualifiers() const {
+    return Value.getPointer().is<const ExtQuals*>();
+  }
+
+  /// \brief Retrieve the set of qualifiers local to this particular QualType
+  /// instance, not including any qualifiers acquired through typedefs or
+  /// other sugar.
+  Qualifiers getLocalQualifiers() const;
+
+  /// \brief Retrieve the set of qualifiers applied to this type.
+  Qualifiers getQualifiers() const;
+
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+  /// local to this particular QualType instance, not including any qualifiers
+  /// acquired through typedefs or other sugar.
+  unsigned getLocalCVRQualifiers() const {
+    return getLocalFastQualifiers();
+  }
+
+  /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+  /// applied to this type.
+  unsigned getCVRQualifiers() const;
+
+  bool isConstant(ASTContext& Ctx) const {
+    return QualType::isConstant(*this, Ctx);
+  }
+
+  /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
+  bool isPODType(ASTContext &Context) const;
+
+  /// isCXX98PODType() - Return true if this is a POD type according to the
+  /// rules of the C++98 standard, regardless of the current compilation's
+  /// language.
+  bool isCXX98PODType(ASTContext &Context) const;
+
+  /// isCXX11PODType() - Return true if this is a POD type according to the
+  /// more relaxed rules of the C++11 standard, regardless of the current
+  /// compilation's language.
+  /// (C++0x [basic.types]p9)
+  bool isCXX11PODType(ASTContext &Context) const;
+
+  /// isTrivialType - Return true if this is a trivial type
+  /// (C++0x [basic.types]p9)
+  bool isTrivialType(ASTContext &Context) const;
+
+  /// isTriviallyCopyableType - Return true if this is a trivially
+  /// copyable type (C++0x [basic.types]p9)
+  bool isTriviallyCopyableType(ASTContext &Context) const;
+
+  // Don't promise in the API that anything besides 'const' can be
+  // easily added.
+
+  /// addConst - add the specified type qualifier to this QualType.
+  void addConst() {
+    addFastQualifiers(Qualifiers::Const);
+  }
+  QualType withConst() const {
+    return withFastQualifiers(Qualifiers::Const);
+  }
+
+  /// addVolatile - add the specified type qualifier to this QualType.
+  void addVolatile() {
+    addFastQualifiers(Qualifiers::Volatile);
+  }
+  QualType withVolatile() const {
+    return withFastQualifiers(Qualifiers::Volatile);
+  }
+  
+  /// Add the restrict qualifier to this QualType.
+  void addRestrict() {
+    addFastQualifiers(Qualifiers::Restrict);
+  }
+  QualType withRestrict() const {
+    return withFastQualifiers(Qualifiers::Restrict);
+  }
+
+  QualType withCVRQualifiers(unsigned CVR) const {
+    return withFastQualifiers(CVR);
+  }
+
+  void addFastQualifiers(unsigned TQs) {
+    assert(!(TQs & ~Qualifiers::FastMask)
+           && "non-fast qualifier bits set in mask!");
+    Value.setInt(Value.getInt() | TQs);
+  }
+
+  void removeLocalConst();
+  void removeLocalVolatile();
+  void removeLocalRestrict();
+  void removeLocalCVRQualifiers(unsigned Mask);
+
+  void removeLocalFastQualifiers() { Value.setInt(0); }
+  void removeLocalFastQualifiers(unsigned Mask) {
+    assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers");
+    Value.setInt(Value.getInt() & ~Mask);
+  }
+
+  // Creates a type with the given qualifiers in addition to any
+  // qualifiers already on this type.
+  QualType withFastQualifiers(unsigned TQs) const {
+    QualType T = *this;
+    T.addFastQualifiers(TQs);
+    return T;
+  }
+
+  // Creates a type with exactly the given fast qualifiers, removing
+  // any existing fast qualifiers.
+  QualType withExactLocalFastQualifiers(unsigned TQs) const {
+    return withoutLocalFastQualifiers().withFastQualifiers(TQs);
+  }
+
+  // Removes fast qualifiers, but leaves any extended qualifiers in place.
+  QualType withoutLocalFastQualifiers() const {
+    QualType T = *this;
+    T.removeLocalFastQualifiers();
+    return T;
+  }
+
+  QualType getCanonicalType() const;
+
+  /// \brief Return this type with all of the instance-specific qualifiers
+  /// removed, but without removing any qualifiers that may have been applied
+  /// through typedefs.
+  QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+
+  /// \brief Retrieve the unqualified variant of the given type,
+  /// removing as little sugar as possible.
+  ///
+  /// This routine looks through various kinds of sugar to find the
+  /// least-desugared type that is unqualified. For example, given:
+  ///
+  /// \code
+  /// typedef int Integer;
+  /// typedef const Integer CInteger;
+  /// typedef CInteger DifferenceType;
+  /// \endcode
+  ///
+  /// Executing \c getUnqualifiedType() on the type \c DifferenceType will
+  /// desugar until we hit the type \c Integer, which has no qualifiers on it.
+  ///
+  /// The resulting type might still be qualified if it's sugar for an array
+  /// type.  To strip qualifiers even from within a sugared array type, use
+  /// ASTContext::getUnqualifiedArrayType.
+  inline QualType getUnqualifiedType() const;
+
+  /// getSplitUnqualifiedType - Retrieve the unqualified variant of the
+  /// given type, removing as little sugar as possible.
+  ///
+  /// Like getUnqualifiedType(), but also returns the set of
+  /// qualifiers that were built up.
+  ///
+  /// The resulting type might still be qualified if it's sugar for an array
+  /// type.  To strip qualifiers even from within a sugared array type, use
+  /// ASTContext::getUnqualifiedArrayType.
+  inline SplitQualType getSplitUnqualifiedType() const;
+
+  /// \brief Determine whether this type is more qualified than the other
+  /// given type, requiring exact equality for non-CVR qualifiers.
+  bool isMoreQualifiedThan(QualType Other) const;
+
+  /// \brief Determine whether this type is at least as qualified as the other
+  /// given type, requiring exact equality for non-CVR qualifiers.
+  bool isAtLeastAsQualifiedAs(QualType Other) const;
+
+  QualType getNonReferenceType() const;
+
+  /// \brief Determine the type of a (typically non-lvalue) expression with the
+  /// specified result type.
+  ///
+  /// This routine should be used for expressions for which the return type is
+  /// explicitly specified (e.g., in a cast or call) and isn't necessarily
+  /// an lvalue. It removes a top-level reference (since there are no
+  /// expressions of reference type) and deletes top-level cvr-qualifiers
+  /// from non-class types (in C++) or all types (in C).
+  QualType getNonLValueExprType(const ASTContext &Context) const;
+
+  /// getDesugaredType - Return the specified type with any "sugar" removed from
+  /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
+  /// the type is already concrete, it returns it unmodified.  This is similar
+  /// to getting the canonical type, but it doesn't remove *all* typedefs.  For
+  /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
+  /// concrete.
+  ///
+  /// Qualifiers are left in place.
+  QualType getDesugaredType(const ASTContext &Context) const {
+    return getDesugaredType(*this, Context);
+  }
+
+  SplitQualType getSplitDesugaredType() const {
+    return getSplitDesugaredType(*this);
+  }
+
+  /// \brief Return the specified type with one level of "sugar" removed from
+  /// the type.
+  ///
+  /// This routine takes off the first typedef, typeof, etc. If the outer level
+  /// of the type is already concrete, it returns it unmodified.
+  QualType getSingleStepDesugaredType(const ASTContext &Context) const {
+    return getSingleStepDesugaredTypeImpl(*this, Context);
+  }
+
+  /// IgnoreParens - Returns the specified type after dropping any
+  /// outer-level parentheses.
+  QualType IgnoreParens() const {
+    if (isa<ParenType>(*this))
+      return QualType::IgnoreParens(*this);
+    return *this;
+  }
+
+  /// operator==/!= - Indicate whether the specified types and qualifiers are
+  /// identical.
+  friend bool operator==(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value == RHS.Value;
+  }
+  friend bool operator!=(const QualType &LHS, const QualType &RHS) {
+    return LHS.Value != RHS.Value;
+  }
+  std::string getAsString() const {
+    return getAsString(split());
+  }
+  static std::string getAsString(SplitQualType split) {
+    return getAsString(split.Ty, split.Quals);
+  }
+  static std::string getAsString(const Type *ty, Qualifiers qs);
+
+  std::string getAsString(const PrintingPolicy &Policy) const;
+
+  void print(raw_ostream &OS, const PrintingPolicy &Policy,
+             const Twine &PlaceHolder = Twine()) const {
+    print(split(), OS, Policy, PlaceHolder);
+  }
+  static void print(SplitQualType split, raw_ostream &OS,
+                    const PrintingPolicy &policy, const Twine &PlaceHolder) {
+    return print(split.Ty, split.Quals, OS, policy, PlaceHolder);
+  }
+  static void print(const Type *ty, Qualifiers qs,
+                    raw_ostream &OS, const PrintingPolicy &policy,
+                    const Twine &PlaceHolder);
+
+  void getAsStringInternal(std::string &Str,
+                           const PrintingPolicy &Policy) const {
+    return getAsStringInternal(split(), Str, Policy);
+  }
+  static void getAsStringInternal(SplitQualType split, std::string &out,
+                                  const PrintingPolicy &policy) {
+    return getAsStringInternal(split.Ty, split.Quals, out, policy);
+  }
+  static void getAsStringInternal(const Type *ty, Qualifiers qs,
+                                  std::string &out,
+                                  const PrintingPolicy &policy);
+
+  class StreamedQualTypeHelper {
+    const QualType &T;
+    const PrintingPolicy &Policy;
+    const Twine &PlaceHolder;
+  public:
+    StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
+                           const Twine &PlaceHolder)
+      : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { }
+
+    friend raw_ostream &operator<<(raw_ostream &OS,
+                                   const StreamedQualTypeHelper &SQT) {
+      SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder);
+      return OS;
+    }
+  };
+
+  StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
+                                const Twine &PlaceHolder = Twine()) const {
+    return StreamedQualTypeHelper(*this, Policy, PlaceHolder);
+  }
+
+  void dump(const char *s) const;
+  void dump() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddPointer(getAsOpaquePtr());
+  }
+
+  /// getAddressSpace - Return the address space of this type.
+  inline unsigned getAddressSpace() const;
+
+  /// getObjCGCAttr - Returns gc attribute of this type.
+  inline Qualifiers::GC getObjCGCAttr() const;
+
+  /// isObjCGCWeak true when Type is objc's weak.
+  bool isObjCGCWeak() const {
+    return getObjCGCAttr() == Qualifiers::Weak;
+  }
+
+  /// isObjCGCStrong true when Type is objc's strong.
+  bool isObjCGCStrong() const {
+    return getObjCGCAttr() == Qualifiers::Strong;
+  }
+
+  /// getObjCLifetime - Returns lifetime attribute of this type.
+  Qualifiers::ObjCLifetime getObjCLifetime() const {
+    return getQualifiers().getObjCLifetime();
+  }
+
+  bool hasNonTrivialObjCLifetime() const {
+    return getQualifiers().hasNonTrivialObjCLifetime();
+  }
+
+  bool hasStrongOrWeakObjCLifetime() const {
+    return getQualifiers().hasStrongOrWeakObjCLifetime();
+  }
+
+  enum DestructionKind {
+    DK_none,
+    DK_cxx_destructor,
+    DK_objc_strong_lifetime,
+    DK_objc_weak_lifetime
+  };
+
+  /// isDestructedType - nonzero if objects of this type require
+  /// non-trivial work to clean up after.  Non-zero because it's
+  /// conceivable that qualifiers (objc_gc(weak)?) could make
+  /// something require destruction.
+  DestructionKind isDestructedType() const {
+    return isDestructedTypeImpl(*this);
+  }
+
+  /// \brief Determine whether expressions of the given type are forbidden
+  /// from being lvalues in C.
+  ///
+  /// The expression types that are forbidden to be lvalues are:
+  ///   - 'void', but not qualified void
+  ///   - function types
+  ///
+  /// The exact rule here is C99 6.3.2.1:
+  ///   An lvalue is an expression with an object type or an incomplete
+  ///   type other than void.
+  bool isCForbiddenLValueType() const;
+
+private:
+  // These methods are implemented in a separate translation unit;
+  // "static"-ize them to avoid creating temporary QualTypes in the
+  // caller.
+  static bool isConstant(QualType T, ASTContext& Ctx);
+  static QualType getDesugaredType(QualType T, const ASTContext &Context);
+  static SplitQualType getSplitDesugaredType(QualType T);
+  static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
+  static QualType getSingleStepDesugaredTypeImpl(QualType type,
+                                                 const ASTContext &C);
+  static QualType IgnoreParens(QualType T);
+  static DestructionKind isDestructedTypeImpl(QualType type);
+};
+
+} // end clang.
+
+namespace llvm {
+/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
+/// to a specific Type class.
+template<> struct simplify_type< ::clang::QualType> {
+  typedef const ::clang::Type *SimpleType;
+  static SimpleType getSimplifiedValue(::clang::QualType Val) {
+    return Val.getTypePtr();
+  }
+};
+
+// Teach SmallPtrSet that QualType is "basically a pointer".
+template<>
+class PointerLikeTypeTraits<clang::QualType> {
+public:
+  static inline void *getAsVoidPointer(clang::QualType P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::QualType getFromVoidPointer(void *P) {
+    return clang::QualType::getFromOpaquePtr(P);
+  }
+  // Various qualifiers go in low bits.
+  enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+namespace clang {
+
+/// \brief Base class that is common to both the \c ExtQuals and \c Type
+/// classes, which allows \c QualType to access the common fields between the
+/// two.
+///
+class ExtQualsTypeCommonBase {
+  ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
+    : BaseType(baseType), CanonicalType(canon) {}
+
+  /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or
+  /// a self-referential pointer (for \c Type).
+  ///
+  /// This pointer allows an efficient mapping from a QualType to its
+  /// underlying type pointer.
+  const Type *const BaseType;
+
+  /// \brief The canonical type of this type.  A QualType.
+  QualType CanonicalType;
+
+  friend class QualType;
+  friend class Type;
+  friend class ExtQuals;
+};
+
+/// ExtQuals - We can encode up to four bits in the low bits of a
+/// type pointer, but there are many more type qualifiers that we want
+/// to be able to apply to an arbitrary type.  Therefore we have this
+/// struct, intended to be heap-allocated and used by QualType to
+/// store qualifiers.
+///
+/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers
+/// in three low bits on the QualType pointer; a fourth bit records whether
+/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
+/// Objective-C GC attributes) are much more rare.
+class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
+  // NOTE: changing the fast qualifiers should be straightforward as
+  // long as you don't make 'const' non-fast.
+  // 1. Qualifiers:
+  //    a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
+  //       Fast qualifiers must occupy the low-order bits.
+  //    b) Update Qualifiers::FastWidth and FastMask.
+  // 2. QualType:
+  //    a) Update is{Volatile,Restrict}Qualified(), defined inline.
+  //    b) Update remove{Volatile,Restrict}, defined near the end of
+  //       this header.
+  // 3. ASTContext:
+  //    a) Update get{Volatile,Restrict}Type.
+
+  /// Quals - the immutable set of qualifiers applied by this
+  /// node;  always contains extended qualifiers.
+  Qualifiers Quals;
+
+  ExtQuals *this_() { return this; }
+
+public:
+  ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
+    : ExtQualsTypeCommonBase(baseType,
+                             canon.isNull() ? QualType(this_(), 0) : canon),
+      Quals(quals)
+  {
+    assert(Quals.hasNonFastQualifiers()
+           && "ExtQuals created with no fast qualifiers");
+    assert(!Quals.hasFastQualifiers()
+           && "ExtQuals created with fast qualifiers");
+  }
+
+  Qualifiers getQualifiers() const { return Quals; }
+
+  bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
+  Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
+
+  bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
+  Qualifiers::ObjCLifetime getObjCLifetime() const {
+    return Quals.getObjCLifetime();
+  }
+
+  bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
+  unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
+
+  const Type *getBaseType() const { return BaseType; }
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, getBaseType(), Quals);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const Type *BaseType,
+                      Qualifiers Quals) {
+    assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!");
+    ID.AddPointer(BaseType);
+    Quals.Profile(ID);
+  }
+};
+
+/// \brief The kind of C++0x ref-qualifier associated with a function type,
+/// which determines whether a member function's "this" object can be an
+/// lvalue, rvalue, or neither.
+enum RefQualifierKind {
+  /// \brief No ref-qualifier was provided.
+  RQ_None = 0,
+  /// \brief An lvalue ref-qualifier was provided (\c &).
+  RQ_LValue,
+  /// \brief An rvalue ref-qualifier was provided (\c &&).
+  RQ_RValue
+};
+
+/// Type - This is the base class of the type hierarchy.  A central concept
+/// with types is that each type always has a canonical type.  A canonical type
+/// is the type with any typedef names stripped out of it or the types it
+/// references.  For example, consider:
+///
+///  typedef int  foo;
+///  typedef foo* bar;
+///    'int *'    'foo *'    'bar'
+///
+/// There will be a Type object created for 'int'.  Since int is canonical, its
+/// canonicaltype pointer points to itself.  There is also a Type for 'foo' (a
+/// TypedefType).  Its CanonicalType pointer points to the 'int' Type.  Next
+/// there is a PointerType that represents 'int*', which, like 'int', is
+/// canonical.  Finally, there is a PointerType type for 'foo*' whose canonical
+/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
+/// is also 'int*'.
+///
+/// Non-canonical types are useful for emitting diagnostics, without losing
+/// information about typedefs being used.  Canonical types are useful for type
+/// comparisons (they allow by-pointer equality tests) and useful for reasoning
+/// about whether something has a particular form (e.g. is a function type),
+/// because they implicitly, recursively, strip all typedefs out of a type.
+///
+/// Types, once created, are immutable.
+///
+class Type : public ExtQualsTypeCommonBase {
+public:
+  enum TypeClass {
+#define TYPE(Class, Base) Class,
+#define LAST_TYPE(Class) TypeLast = Class,
+#define ABSTRACT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+    TagFirst = Record, TagLast = Enum
+  };
+
+private:
+  Type(const Type &) LLVM_DELETED_FUNCTION;
+  void operator=(const Type &) LLVM_DELETED_FUNCTION;
+
+  /// Bitfields required by the Type class.
+  class TypeBitfields {
+    friend class Type;
+    template <class T> friend class TypePropertyCache;
+
+    /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+    unsigned TC : 8;
+
+    /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
+    unsigned Dependent : 1;
+
+    /// \brief Whether this type somehow involves a template parameter, even
+    /// if the resolution of the type does not depend on a template parameter.
+    unsigned InstantiationDependent : 1;
+
+    /// \brief Whether this type is a variably-modified type (C99 6.7.5).
+    unsigned VariablyModified : 1;
+
+    /// \brief Whether this type contains an unexpanded parameter pack
+    /// (for C++0x variadic templates).
+    unsigned ContainsUnexpandedParameterPack : 1;
+
+    /// \brief True if the cache (i.e. the bitfields here starting with
+    /// 'Cache') is valid.
+    mutable unsigned CacheValid : 1;
+
+    /// \brief Linkage of this type.
+    mutable unsigned CachedLinkage : 3;
+
+    /// \brief Whether this type involves and local or unnamed types.
+    mutable unsigned CachedLocalOrUnnamed : 1;
+
+    /// \brief FromAST - Whether this type comes from an AST file.
+    mutable unsigned FromAST : 1;
+
+    bool isCacheValid() const {
+      return CacheValid;
+    }
+    Linkage getLinkage() const {
+      assert(isCacheValid() && "getting linkage from invalid cache");
+      return static_cast<Linkage>(CachedLinkage);
+    }
+    bool hasLocalOrUnnamedType() const {
+      assert(isCacheValid() && "getting linkage from invalid cache");
+      return CachedLocalOrUnnamed;
+    }
+  };
+  enum { NumTypeBits = 18 };
+
+protected:
+  // These classes allow subclasses to somewhat cleanly pack bitfields
+  // into Type.
+
+  class ArrayTypeBitfields {
+    friend class ArrayType;
+
+    unsigned : NumTypeBits;
+
+    /// IndexTypeQuals - CVR qualifiers from declarations like
+    /// 'int X[static restrict 4]'. For function parameters only.
+    unsigned IndexTypeQuals : 3;
+
+    /// SizeModifier - storage class qualifiers from declarations like
+    /// 'int X[static restrict 4]'. For function parameters only.
+    /// Actually an ArrayType::ArraySizeModifier.
+    unsigned SizeModifier : 3;
+  };
+
+  class BuiltinTypeBitfields {
+    friend class BuiltinType;
+
+    unsigned : NumTypeBits;
+
+    /// The kind (BuiltinType::Kind) of builtin type this is.
+    unsigned Kind : 8;
+  };
+
+  class FunctionTypeBitfields {
+    friend class FunctionType;
+
+    unsigned : NumTypeBits;
+
+    /// Extra information which affects how the function is called, like
+    /// regparm and the calling convention.
+    unsigned ExtInfo : 9;
+
+    /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
+    /// other bitfields.
+    /// The qualifiers are part of FunctionProtoType because...
+    ///
+    /// C++ 8.3.5p4: The return type, the parameter type list and the
+    /// cv-qualifier-seq, [...], are part of the function type.
+    unsigned TypeQuals : 3;
+  };
+
+  class ObjCObjectTypeBitfields {
+    friend class ObjCObjectType;
+
+    unsigned : NumTypeBits;
+
+    /// NumProtocols - The number of protocols stored directly on this
+    /// object type.
+    unsigned NumProtocols : 32 - NumTypeBits;
+  };
+
+  class ReferenceTypeBitfields {
+    friend class ReferenceType;
+
+    unsigned : NumTypeBits;
+
+    /// True if the type was originally spelled with an lvalue sigil.
+    /// This is never true of rvalue references but can also be false
+    /// on lvalue references because of C++0x [dcl.typedef]p9,
+    /// as follows:
+    ///
+    ///   typedef int &ref;    // lvalue, spelled lvalue
+    ///   typedef int &&rvref; // rvalue
+    ///   ref &a;              // lvalue, inner ref, spelled lvalue
+    ///   ref &&a;             // lvalue, inner ref
+    ///   rvref &a;            // lvalue, inner ref, spelled lvalue
+    ///   rvref &&a;           // rvalue, inner ref
+    unsigned SpelledAsLValue : 1;
+
+    /// True if the inner type is a reference type.  This only happens
+    /// in non-canonical forms.
+    unsigned InnerRef : 1;
+  };
+
+  class TypeWithKeywordBitfields {
+    friend class TypeWithKeyword;
+
+    unsigned : NumTypeBits;
+
+    /// An ElaboratedTypeKeyword.  8 bits for efficient access.
+    unsigned Keyword : 8;
+  };
+
+  class VectorTypeBitfields {
+    friend class VectorType;
+
+    unsigned : NumTypeBits;
+
+    /// VecKind - The kind of vector, either a generic vector type or some
+    /// target-specific vector type such as for AltiVec or Neon.
+    unsigned VecKind : 3;
+
+    /// NumElements - The number of elements in the vector.
+    unsigned NumElements : 29 - NumTypeBits;
+
+    enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
+  };
+
+  class AttributedTypeBitfields {
+    friend class AttributedType;
+
+    unsigned : NumTypeBits;
+
+    /// AttrKind - an AttributedType::Kind
+    unsigned AttrKind : 32 - NumTypeBits;
+  };
+
+  class AutoTypeBitfields {
+    friend class AutoType;
+
+    unsigned : NumTypeBits;
+
+    /// Was this placeholder type spelled as 'decltype(auto)'?
+    unsigned IsDecltypeAuto : 1;
+  };
+
+  union {
+    TypeBitfields TypeBits;
+    ArrayTypeBitfields ArrayTypeBits;
+    AttributedTypeBitfields AttributedTypeBits;
+    AutoTypeBitfields AutoTypeBits;
+    BuiltinTypeBitfields BuiltinTypeBits;
+    FunctionTypeBitfields FunctionTypeBits;
+    ObjCObjectTypeBitfields ObjCObjectTypeBits;
+    ReferenceTypeBitfields ReferenceTypeBits;
+    TypeWithKeywordBitfields TypeWithKeywordBits;
+    VectorTypeBitfields VectorTypeBits;
+  };
+
+private:
+  /// \brief Set whether this type comes from an AST file.
+  void setFromAST(bool V = true) const {
+    TypeBits.FromAST = V;
+  }
+
+  template <class T> friend class TypePropertyCache;
+
+protected:
+  // silence VC++ warning C4355: 'this' : used in base member initializer list
+  Type *this_() { return this; }
+  Type(TypeClass tc, QualType canon, bool Dependent,
+       bool InstantiationDependent, bool VariablyModified,
+       bool ContainsUnexpandedParameterPack)
+    : ExtQualsTypeCommonBase(this,
+                             canon.isNull() ? QualType(this_(), 0) : canon) {
+    TypeBits.TC = tc;
+    TypeBits.Dependent = Dependent;
+    TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
+    TypeBits.VariablyModified = VariablyModified;
+    TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+    TypeBits.CacheValid = false;
+    TypeBits.CachedLocalOrUnnamed = false;
+    TypeBits.CachedLinkage = NoLinkage;
+    TypeBits.FromAST = false;
+  }
+  friend class ASTContext;
+
+  void setDependent(bool D = true) {
+    TypeBits.Dependent = D;
+    if (D)
+      TypeBits.InstantiationDependent = true;
+  }
+  void setInstantiationDependent(bool D = true) {
+    TypeBits.InstantiationDependent = D; }
+  void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
+  }
+  void setContainsUnexpandedParameterPack(bool PP = true) {
+    TypeBits.ContainsUnexpandedParameterPack = PP;
+  }
+
+public:
+  TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
+
+  /// \brief Whether this type comes from an AST file.
+  bool isFromAST() const { return TypeBits.FromAST; }
+
+  /// \brief Whether this type is or contains an unexpanded parameter
+  /// pack, used to support C++0x variadic templates.
+  ///
+  /// A type that contains a parameter pack shall be expanded by the
+  /// ellipsis operator at some point. For example, the typedef in the
+  /// following example contains an unexpanded parameter pack 'T':
+  ///
+  /// \code
+  /// template<typename ...T>
+  /// struct X {
+  ///   typedef T* pointer_types; // ill-formed; T is a parameter pack.
+  /// };
+  /// \endcode
+  ///
+  /// Note that this routine does not specify which
+  bool containsUnexpandedParameterPack() const {
+    return TypeBits.ContainsUnexpandedParameterPack;
+  }
+
+  /// Determines if this type would be canonical if it had no further
+  /// qualification.
+  bool isCanonicalUnqualified() const {
+    return CanonicalType == QualType(this, 0);
+  }
+
+  /// Pull a single level of sugar off of this locally-unqualified type.
+  /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
+  /// or QualType::getSingleStepDesugaredType(const ASTContext&).
+  QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
+
+  /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
+  /// object types, function types, and incomplete types.
+
+  /// isIncompleteType - Return true if this is an incomplete type.
+  /// A type that can describe objects, but which lacks information needed to
+  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
+  /// routine will need to determine if the size is actually required.
+  ///
+  /// \brief Def If non-NULL, and the type refers to some kind of declaration
+  /// that can be completed (such as a C struct, C++ class, or Objective-C
+  /// class), will be set to the declaration.
+  bool isIncompleteType(NamedDecl **Def = nullptr) const;
+
+  /// isIncompleteOrObjectType - Return true if this is an incomplete or object
+  /// type, in other words, not a function type.
+  bool isIncompleteOrObjectType() const {
+    return !isFunctionType();
+  }
+
+  /// \brief Determine whether this type is an object type.
+  bool isObjectType() const {
+    // C++ [basic.types]p8:
+    //   An object type is a (possibly cv-qualified) type that is not a
+    //   function type, not a reference type, and not a void type.
+    return !isReferenceType() && !isFunctionType() && !isVoidType();
+  }
+
+  /// isLiteralType - Return true if this is a literal type
+  /// (C++11 [basic.types]p10)
+  bool isLiteralType(const ASTContext &Ctx) const;
+
+  /// \brief Test if this type is a standard-layout type.
+  /// (C++0x [basic.type]p9)
+  bool isStandardLayoutType() const;
+
+  /// Helper methods to distinguish type categories. All type predicates
+  /// operate on the canonical type, ignoring typedefs and qualifiers.
+
+  /// isBuiltinType - returns true if the type is a builtin type.
+  bool isBuiltinType() const;
+
+  /// isSpecificBuiltinType - Test for a particular builtin type.
+  bool isSpecificBuiltinType(unsigned K) const;
+
+  /// isPlaceholderType - Test for a type which does not represent an
+  /// actual type-system type but is instead used as a placeholder for
+  /// various convenient purposes within Clang.  All such types are
+  /// BuiltinTypes.
+  bool isPlaceholderType() const;
+  const BuiltinType *getAsPlaceholderType() const;
+
+  /// isSpecificPlaceholderType - Test for a specific placeholder type.
+  bool isSpecificPlaceholderType(unsigned K) const;
+
+  /// isNonOverloadPlaceholderType - Test for a placeholder type
+  /// other than Overload;  see BuiltinType::isNonOverloadPlaceholderType.
+  bool isNonOverloadPlaceholderType() const;
+
+  /// isIntegerType() does *not* include complex integers (a GCC extension).
+  /// isComplexIntegerType() can be used to test for complex integers.
+  bool isIntegerType() const;     // C99 6.2.5p17 (int, char, bool, enum)
+  bool isEnumeralType() const;
+  bool isBooleanType() const;
+  bool isCharType() const;
+  bool isWideCharType() const;
+  bool isChar16Type() const;
+  bool isChar32Type() const;
+  bool isAnyCharacterType() const;
+  bool isIntegralType(ASTContext &Ctx) const;
+
+  /// \brief Determine whether this type is an integral or enumeration type.
+  bool isIntegralOrEnumerationType() const;
+  /// \brief Determine whether this type is an integral or unscoped enumeration
+  /// type.
+  bool isIntegralOrUnscopedEnumerationType() const;
+
+  /// Floating point categories.
+  bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
+  /// isComplexType() does *not* include complex integers (a GCC extension).
+  /// isComplexIntegerType() can be used to test for complex integers.
+  bool isComplexType() const;      // C99 6.2.5p11 (complex)
+  bool isAnyComplexType() const;   // C99 6.2.5p11 (complex) + Complex Int.
+  bool isFloatingType() const;     // C99 6.2.5p11 (real floating + complex)
+  bool isHalfType() const;         // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
+  bool isRealType() const;         // C99 6.2.5p17 (real floating + integer)
+  bool isArithmeticType() const;   // C99 6.2.5p18 (integer + floating)
+  bool isVoidType() const;         // C99 6.2.5p19
+  bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
+  bool isAggregateType() const;
+  bool isFundamentalType() const;
+  bool isCompoundType() const;
+
+  // Type Predicates: Check to see if this type is structurally the specified
+  // type, ignoring typedefs and qualifiers.
+  bool isFunctionType() const;
+  bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
+  bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
+  bool isPointerType() const;
+  bool isAnyPointerType() const;   // Any C pointer or ObjC object pointer
+  bool isBlockPointerType() const;
+  bool isVoidPointerType() const;
+  bool isReferenceType() const;
+  bool isLValueReferenceType() const;
+  bool isRValueReferenceType() const;
+  bool isFunctionPointerType() const;
+  bool isMemberPointerType() const;
+  bool isMemberFunctionPointerType() const;
+  bool isMemberDataPointerType() const;
+  bool isArrayType() const;
+  bool isConstantArrayType() const;
+  bool isIncompleteArrayType() const;
+  bool isVariableArrayType() const;
+  bool isDependentSizedArrayType() const;
+  bool isRecordType() const;
+  bool isClassType() const;
+  bool isStructureType() const;
+  bool isInterfaceType() const;
+  bool isStructureOrClassType() const;
+  bool isUnionType() const;
+  bool isComplexIntegerType() const;            // GCC _Complex integer type.
+  bool isVectorType() const;                    // GCC vector type.
+  bool isExtVectorType() const;                 // Extended vector type.
+  bool isObjCObjectPointerType() const;         // pointer to ObjC object
+  bool isObjCRetainableType() const;            // ObjC object or block pointer
+  bool isObjCLifetimeType() const;              // (array of)* retainable type
+  bool isObjCIndirectLifetimeType() const;      // (pointer to)* lifetime type
+  bool isObjCNSObjectType() const;              // __attribute__((NSObject))
+  // FIXME: change this to 'raw' interface type, so we can used 'interface' type
+  // for the common case.
+  bool isObjCObjectType() const;                // NSString or typeof(*(id)0)
+  bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
+  bool isObjCQualifiedIdType() const;           // id<foo>
+  bool isObjCQualifiedClassType() const;        // Class<foo>
+  bool isObjCObjectOrInterfaceType() const;
+  bool isObjCIdType() const;                    // id
+  bool isObjCClassType() const;                 // Class
+  bool isObjCSelType() const;                 // Class
+  bool isObjCBuiltinType() const;               // 'id' or 'Class'
+  bool isObjCARCBridgableType() const;
+  bool isCARCBridgableType() const;
+  bool isTemplateTypeParmType() const;          // C++ template type parameter
+  bool isNullPtrType() const;                   // C++0x nullptr_t
+  bool isAtomicType() const;                    // C11 _Atomic()
+
+  bool isImage1dT() const;                      // OpenCL image1d_t
+  bool isImage1dArrayT() const;                 // OpenCL image1d_array_t
+  bool isImage1dBufferT() const;                // OpenCL image1d_buffer_t
+  bool isImage2dT() const;                      // OpenCL image2d_t
+  bool isImage2dArrayT() const;                 // OpenCL image2d_array_t
+  bool isImage3dT() const;                      // OpenCL image3d_t
+
+  bool isImageType() const;                     // Any OpenCL image type
+
+  bool isSamplerT() const;                      // OpenCL sampler_t
+  bool isEventT() const;                        // OpenCL event_t
+
+  bool isOpenCLSpecificType() const;            // Any OpenCL specific type
+
+  /// Determines if this type, which must satisfy
+  /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
+  /// than implicitly __strong.
+  bool isObjCARCImplicitlyUnretainedType() const;
+
+  /// Return the implicit lifetime for this type, which must not be dependent.
+  Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
+
+  enum ScalarTypeKind {
+    STK_CPointer,
+    STK_BlockPointer,
+    STK_ObjCObjectPointer,
+    STK_MemberPointer,
+    STK_Bool,
+    STK_Integral,
+    STK_Floating,
+    STK_IntegralComplex,
+    STK_FloatingComplex
+  };
+  /// getScalarTypeKind - Given that this is a scalar type, classify it.
+  ScalarTypeKind getScalarTypeKind() const;
+
+  /// isDependentType - Whether this type is a dependent type, meaning
+  /// that its definition somehow depends on a template parameter
+  /// (C++ [temp.dep.type]).
+  bool isDependentType() const { return TypeBits.Dependent; }
+
+  /// \brief Determine whether this type is an instantiation-dependent type,
+  /// meaning that the type involves a template parameter (even if the
+  /// definition does not actually depend on the type substituted for that
+  /// template parameter).
+  bool isInstantiationDependentType() const {
+    return TypeBits.InstantiationDependent;
+  }
+
+  /// \brief Determine whether this type is an undeduced type, meaning that
+  /// it somehow involves a C++11 'auto' type which has not yet been deduced.
+  bool isUndeducedType() const;
+
+  /// \brief Whether this type is a variably-modified type (C99 6.7.5).
+  bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
+
+  /// \brief Whether this type involves a variable-length array type
+  /// with a definite size.
+  bool hasSizedVLAType() const;
+
+  /// \brief Whether this type is or contains a local or unnamed type.
+  bool hasUnnamedOrLocalType() const;
+
+  bool isOverloadableType() const;
+
+  /// \brief Determine wither this type is a C++ elaborated-type-specifier.
+  bool isElaboratedTypeSpecifier() const;
+
+  bool canDecayToPointerType() const;
+
+  /// hasPointerRepresentation - Whether this type is represented
+  /// natively as a pointer; this includes pointers, references, block
+  /// pointers, and Objective-C interface, qualified id, and qualified
+  /// interface types, as well as nullptr_t.
+  bool hasPointerRepresentation() const;
+
+  /// hasObjCPointerRepresentation - Whether this type can represent
+  /// an objective pointer type for the purpose of GC'ability
+  bool hasObjCPointerRepresentation() const;
+
+  /// \brief Determine whether this type has an integer representation
+  /// of some sort, e.g., it is an integer type or a vector.
+  bool hasIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an signed integer representation
+  /// of some sort, e.g., it is an signed integer type or a vector.
+  bool hasSignedIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has an unsigned integer representation
+  /// of some sort, e.g., it is an unsigned integer type or a vector.
+  bool hasUnsignedIntegerRepresentation() const;
+
+  /// \brief Determine whether this type has a floating-point representation
+  /// of some sort, e.g., it is a floating-point type or a vector thereof.
+  bool hasFloatingRepresentation() const;
+
+  // Type Checking Functions: Check to see if this type is structurally the
+  // specified type, ignoring typedefs and qualifiers, and return a pointer to
+  // the best type we can.
+  const RecordType *getAsStructureType() const;
+  /// NOTE: getAs*ArrayType are methods on ASTContext.
+  const RecordType *getAsUnionType() const;
+  const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
+  // The following is a convenience method that returns an ObjCObjectPointerType
+  // for object declared using an interface.
+  const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
+  const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
+  const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
+  const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
+
+  /// \brief Retrieves the CXXRecordDecl that this type refers to, either
+  /// because the type is a RecordType or because it is the injected-class-name
+  /// type of a class template or class template partial specialization.
+  CXXRecordDecl *getAsCXXRecordDecl() const;
+
+  /// If this is a pointer or reference to a RecordType, return the
+  /// CXXRecordDecl that that type refers to.
+  ///
+  /// If this is not a pointer or reference, or the type being pointed to does
+  /// not refer to a CXXRecordDecl, returns NULL.
+  const CXXRecordDecl *getPointeeCXXRecordDecl() const;
+
+  /// \brief Get the AutoType whose type will be deduced for a variable with
+  /// an initializer of this type. This looks through declarators like pointer
+  /// types, but not through decltype or typedefs.
+  AutoType *getContainedAutoType() const;
+
+  /// Member-template getAs<specific type>'.  Look through sugar for
+  /// an instance of \<specific type>.   This scheme will eventually
+  /// replace the specific getAsXXXX methods above.
+  ///
+  /// There are some specializations of this member template listed
+  /// immediately following this class.
+  template <typename T> const T *getAs() const;
+
+  /// A variant of getAs<> for array types which silently discards
+  /// qualifiers from the outermost type.
+  const ArrayType *getAsArrayTypeUnsafe() const;
+
+  /// Member-template castAs<specific type>.  Look through sugar for
+  /// the underlying instance of \<specific type>.
+  ///
+  /// This method has the same relationship to getAs<T> as cast<T> has
+  /// to dyn_cast<T>; which is to say, the underlying type *must*
+  /// have the intended type, and this method will never return null.
+  template <typename T> const T *castAs() const;
+
+  /// A variant of castAs<> for array type which silently discards
+  /// qualifiers from the outermost type.
+  const ArrayType *castAsArrayTypeUnsafe() const;
+
+  /// getBaseElementTypeUnsafe - Get the base element type of this
+  /// type, potentially discarding type qualifiers.  This method
+  /// should never be used when type qualifiers are meaningful.
+  const Type *getBaseElementTypeUnsafe() const;
+
+  /// getArrayElementTypeNoTypeQual - If this is an array type, return the
+  /// element type of the array, potentially with type qualifiers missing.
+  /// This method should never be used when type qualifiers are meaningful.
+  const Type *getArrayElementTypeNoTypeQual() const;
+
+  /// getPointeeType - If this is a pointer, ObjC object pointer, or block
+  /// pointer, this returns the respective pointee.
+  QualType getPointeeType() const;
+
+  /// getUnqualifiedDesugaredType() - Return the specified type with
+  /// any "sugar" removed from the type, removing any typedefs,
+  /// typeofs, etc., as well as any qualifiers.
+  const Type *getUnqualifiedDesugaredType() const;
+
+  /// More type predicates useful for type checking/promotion
+  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
+
+  /// isSignedIntegerType - Return true if this is an integer type that is
+  /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
+  /// or an enum decl which has a signed representation.
+  bool isSignedIntegerType() const;
+
+  /// isUnsignedIntegerType - Return true if this is an integer type that is
+  /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
+  /// or an enum decl which has an unsigned representation.
+  bool isUnsignedIntegerType() const;
+
+  /// Determines whether this is an integer type that is signed or an
+  /// enumeration types whose underlying type is a signed integer type.
+  bool isSignedIntegerOrEnumerationType() const;
+
+  /// Determines whether this is an integer type that is unsigned or an
+  /// enumeration types whose underlying type is a unsigned integer type.
+  bool isUnsignedIntegerOrEnumerationType() const;
+
+  /// isConstantSizeType - Return true if this is not a variable sized type,
+  /// according to the rules of C99 6.7.5p3.  It is not legal to call this on
+  /// incomplete types.
+  bool isConstantSizeType() const;
+
+  /// isSpecifierType - Returns true if this type can be represented by some
+  /// set of type specifiers.
+  bool isSpecifierType() const;
+
+  /// \brief Determine the linkage of this type.
+  Linkage getLinkage() const;
+
+  /// \brief Determine the visibility of this type.
+  Visibility getVisibility() const {
+    return getLinkageAndVisibility().getVisibility();
+  }
+
+  /// \brief Return true if the visibility was explicitly set is the code.
+  bool isVisibilityExplicit() const {
+    return getLinkageAndVisibility().isVisibilityExplicit();
+  }
+
+  /// \brief Determine the linkage and visibility of this type.
+  LinkageInfo getLinkageAndVisibility() const;
+
+  /// \brief True if the computed linkage is valid. Used for consistency
+  /// checking. Should always return true.
+  bool isLinkageValid() const;
+
+  const char *getTypeClassName() const;
+
+  QualType getCanonicalTypeInternal() const {
+    return CanonicalType;
+  }
+  CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
+  void dump() const;
+
+  friend class ASTReader;
+  friend class ASTWriter;
+};
+
+/// \brief This will check for a TypedefType by removing any existing sugar
+/// until it reaches a TypedefType or a non-sugared type.
+template <> const TypedefType *Type::getAs() const;
+
+/// \brief This will check for a TemplateSpecializationType by removing any
+/// existing sugar until it reaches a TemplateSpecializationType or a
+/// non-sugared type.
+template <> const TemplateSpecializationType *Type::getAs() const;
+
+/// \brief This will check for an AttributedType by removing any existing sugar
+/// until it reaches an AttributedType or a non-sugared type.
+template <> const AttributedType *Type::getAs() const;
+
+// We can do canonical leaf types faster, because we don't have to
+// worry about preserving child type decoration.
+#define TYPE(Class, Base)
+#define LEAF_TYPE(Class) \
+template <> inline const Class##Type *Type::getAs() const { \
+  return dyn_cast<Class##Type>(CanonicalType); \
+} \
+template <> inline const Class##Type *Type::castAs() const { \
+  return cast<Class##Type>(CanonicalType); \
+}
+#include "clang/AST/TypeNodes.def"
+
+
+/// BuiltinType - This class is used for builtin types like 'int'.  Builtin
+/// types are always canonical and have a literal name field.
+class BuiltinType : public Type {
+public:
+  enum Kind {
+#define BUILTIN_TYPE(Id, SingletonId) Id,
+#define LAST_BUILTIN_TYPE(Id) LastKind = Id
+#include "clang/AST/BuiltinTypes.def"
+  };
+
+public:
+  BuiltinType(Kind K)
+    : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
+           /*InstantiationDependent=*/(K == Dependent),
+           /*VariablyModified=*/false,
+           /*Unexpanded paramter pack=*/false) {
+    BuiltinTypeBits.Kind = K;
+  }
+
+  Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
+  StringRef getName(const PrintingPolicy &Policy) const;
+  const char *getNameAsCString(const PrintingPolicy &Policy) const {
+    // The StringRef is null-terminated.
+    StringRef str = getName(Policy);
+    assert(!str.empty() && str.data()[str.size()] == '\0');
+    return str.data();
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  bool isInteger() const {
+    return getKind() >= Bool && getKind() <= Int128;
+  }
+
+  bool isSignedInteger() const {
+    return getKind() >= Char_S && getKind() <= Int128;
+  }
+
+  bool isUnsignedInteger() const {
+    return getKind() >= Bool && getKind() <= UInt128;
+  }
+
+  bool isFloatingPoint() const {
+    return getKind() >= Half && getKind() <= LongDouble;
+  }
+
+  /// Determines whether the given kind corresponds to a placeholder type.
+  static bool isPlaceholderTypeKind(Kind K) {
+    return K >= Overload;
+  }
+
+  /// Determines whether this type is a placeholder type, i.e. a type
+  /// which cannot appear in arbitrary positions in a fully-formed
+  /// expression.
+  bool isPlaceholderType() const {
+    return isPlaceholderTypeKind(getKind());
+  }
+
+  /// Determines whether this type is a placeholder type other than
+  /// Overload.  Most placeholder types require only syntactic
+  /// information about their context in order to be resolved (e.g.
+  /// whether it is a call expression), which means they can (and
+  /// should) be resolved in an earlier "phase" of analysis.
+  /// Overload expressions sometimes pick up further information
+  /// from their context, like whether the context expects a
+  /// specific function-pointer type, and so frequently need
+  /// special treatment.
+  bool isNonOverloadPlaceholderType() const {
+    return getKind() > Overload;
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
+};
+
+/// ComplexType - C99 6.2.5p11 - Complex values.  This supports the C99 complex
+/// types (_Complex float etc) as well as the GCC integer complex extensions.
+///
+class ComplexType : public Type, public llvm::FoldingSetNode {
+  QualType ElementType;
+  ComplexType(QualType Element, QualType CanonicalPtr) :
+    Type(Complex, CanonicalPtr, Element->isDependentType(),
+         Element->isInstantiationDependentType(),
+         Element->isVariablyModifiedType(),
+         Element->containsUnexpandedParameterPack()),
+    ElementType(Element) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getElementType() const { return ElementType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
+    ID.AddPointer(Element.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
+};
+
+/// ParenType - Sugar for parentheses used when specifying types.
+///
+class ParenType : public Type, public llvm::FoldingSetNode {
+  QualType Inner;
+
+  ParenType(QualType InnerType, QualType CanonType) :
+    Type(Paren, CanonType, InnerType->isDependentType(),
+         InnerType->isInstantiationDependentType(),
+         InnerType->isVariablyModifiedType(),
+         InnerType->containsUnexpandedParameterPack()),
+    Inner(InnerType) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+
+  QualType getInnerType() const { return Inner; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return getInnerType(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getInnerType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
+    Inner.Profile(ID);
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
+};
+
+/// PointerType - C99 6.7.5.1 - Pointer Declarators.
+///
+class PointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+
+  PointerType(QualType Pointee, QualType CanonicalPtr) :
+    Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
+         Pointee->isInstantiationDependentType(),
+         Pointee->isVariablyModifiedType(),
+         Pointee->containsUnexpandedParameterPack()),
+    PointeeType(Pointee) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+
+  QualType getPointeeType() const { return PointeeType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
+    ID.AddPointer(Pointee.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
+};
+
+/// \brief Represents a type which was implicitly adjusted by the semantic
+/// engine for arbitrary reasons.  For example, array and function types can
+/// decay, and function types can have their calling conventions adjusted.
+class AdjustedType : public Type, public llvm::FoldingSetNode {
+  QualType OriginalTy;
+  QualType AdjustedTy;
+
+protected:
+  AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
+               QualType CanonicalPtr)
+      : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
+             OriginalTy->isInstantiationDependentType(),
+             OriginalTy->isVariablyModifiedType(),
+             OriginalTy->containsUnexpandedParameterPack()),
+        OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getOriginalType() const { return OriginalTy; }
+  QualType getAdjustedType() const { return AdjustedTy; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return AdjustedTy; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, OriginalTy, AdjustedTy);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
+    ID.AddPointer(Orig.getAsOpaquePtr());
+    ID.AddPointer(New.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
+  }
+};
+
+/// \brief Represents a pointer type decayed from an array or function type.
+class DecayedType : public AdjustedType {
+
+  DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
+      : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
+    assert(isa<PointerType>(getAdjustedType()));
+  }
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getDecayedType() const { return getAdjustedType(); }
+
+  QualType getPointeeType() const {
+    return cast<PointerType>(getDecayedType())->getPointeeType();
+  }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
+};
+
+/// BlockPointerType - pointer to a block type.
+/// This type is to represent types syntactically represented as
+/// "void (^)(int)", etc. Pointee is required to always be a function type.
+///
+class BlockPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;  // Block is some kind of pointer type
+  BlockPointerType(QualType Pointee, QualType CanonicalCls) :
+    Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
+         Pointee->isInstantiationDependentType(),
+         Pointee->isVariablyModifiedType(),
+         Pointee->containsUnexpandedParameterPack()),
+    PointeeType(Pointee) {
+  }
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+
+  // Get the pointee type. Pointee is required to always be a function type.
+  QualType getPointeeType() const { return PointeeType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+      Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
+      ID.AddPointer(Pointee.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == BlockPointer;
+  }
+};
+
+/// ReferenceType - Base for LValueReferenceType and RValueReferenceType
+///
+class ReferenceType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+
+protected:
+  ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
+                bool SpelledAsLValue) :
+    Type(tc, CanonicalRef, Referencee->isDependentType(),
+         Referencee->isInstantiationDependentType(),
+         Referencee->isVariablyModifiedType(),
+         Referencee->containsUnexpandedParameterPack()),
+    PointeeType(Referencee)
+  {
+    ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
+    ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
+  }
+
+public:
+  bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
+  bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
+
+  QualType getPointeeTypeAsWritten() const { return PointeeType; }
+  QualType getPointeeType() const {
+    // FIXME: this might strip inner qualifiers; okay?
+    const ReferenceType *T = this;
+    while (T->isInnerRef())
+      T = T->PointeeType->castAs<ReferenceType>();
+    return T->PointeeType;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, PointeeType, isSpelledAsLValue());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      QualType Referencee,
+                      bool SpelledAsLValue) {
+    ID.AddPointer(Referencee.getAsOpaquePtr());
+    ID.AddBoolean(SpelledAsLValue);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == LValueReference ||
+           T->getTypeClass() == RValueReference;
+  }
+};
+
+/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
+///
+class LValueReferenceType : public ReferenceType {
+  LValueReferenceType(QualType Referencee, QualType CanonicalRef,
+                      bool SpelledAsLValue) :
+    ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
+  {}
+  friend class ASTContext; // ASTContext creates these
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == LValueReference;
+  }
+};
+
+/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference
+///
+class RValueReferenceType : public ReferenceType {
+  RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
+    ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
+  }
+  friend class ASTContext; // ASTContext creates these
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == RValueReference;
+  }
+};
+
+/// MemberPointerType - C++ 8.3.3 - Pointers to members
+///
+class MemberPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+  /// The class of which the pointee is a member. Must ultimately be a
+  /// RecordType, but could be a typedef or a template parameter too.
+  const Type *Class;
+
+  MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
+    Type(MemberPointer, CanonicalPtr,
+         Cls->isDependentType() || Pointee->isDependentType(),
+         (Cls->isInstantiationDependentType() ||
+          Pointee->isInstantiationDependentType()),
+         Pointee->isVariablyModifiedType(),
+         (Cls->containsUnexpandedParameterPack() ||
+          Pointee->containsUnexpandedParameterPack())),
+    PointeeType(Pointee), Class(Cls) {
+  }
+  friend class ASTContext; // ASTContext creates these.
+
+public:
+  QualType getPointeeType() const { return PointeeType; }
+
+  /// Returns true if the member type (i.e. the pointee type) is a
+  /// function type rather than a data-member type.
+  bool isMemberFunctionPointer() const {
+    return PointeeType->isFunctionProtoType();
+  }
+
+  /// Returns true if the member type (i.e. the pointee type) is a
+  /// data type rather than a function type.
+  bool isMemberDataPointer() const {
+    return !PointeeType->isFunctionProtoType();
+  }
+
+  const Type *getClass() const { return Class; }
+  CXXRecordDecl *getMostRecentCXXRecordDecl() const;
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType(), getClass());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
+                      const Type *Class) {
+    ID.AddPointer(Pointee.getAsOpaquePtr());
+    ID.AddPointer(Class);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == MemberPointer;
+  }
+};
+
+/// ArrayType - C99 6.7.5.2 - Array Declarators.
+///
+class ArrayType : public Type, public llvm::FoldingSetNode {
+public:
+  /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
+  /// an array with a static size (e.g. int X[static 4]), or an array
+  /// with a star size (e.g. int X[*]).
+  /// 'static' is only allowed on function parameters.
+  enum ArraySizeModifier {
+    Normal, Static, Star
+  };
+private:
+  /// ElementType - The element type of the array.
+  QualType ElementType;
+
+protected:
+  // C++ [temp.dep.type]p1:
+  //   A type is dependent if it is...
+  //     - an array type constructed from any dependent type or whose
+  //       size is specified by a constant expression that is
+  //       value-dependent,
+  ArrayType(TypeClass tc, QualType et, QualType can,
+            ArraySizeModifier sm, unsigned tq,
+            bool ContainsUnexpandedParameterPack)
+    : Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
+           et->isInstantiationDependentType() || tc == DependentSizedArray,
+           (tc == VariableArray || et->isVariablyModifiedType()),
+           ContainsUnexpandedParameterPack),
+      ElementType(et) {
+    ArrayTypeBits.IndexTypeQuals = tq;
+    ArrayTypeBits.SizeModifier = sm;
+  }
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getElementType() const { return ElementType; }
+  ArraySizeModifier getSizeModifier() const {
+    return ArraySizeModifier(ArrayTypeBits.SizeModifier);
+  }
+  Qualifiers getIndexTypeQualifiers() const {
+    return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
+  }
+  unsigned getIndexTypeCVRQualifiers() const {
+    return ArrayTypeBits.IndexTypeQuals;
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArray ||
+           T->getTypeClass() == VariableArray ||
+           T->getTypeClass() == IncompleteArray ||
+           T->getTypeClass() == DependentSizedArray;
+  }
+};
+
+/// ConstantArrayType - This class represents the canonical version of
+/// C arrays with a specified constant size.  For example, the canonical
+/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element
+/// type is 'int' and the size is 404.
+class ConstantArrayType : public ArrayType {
+  llvm::APInt Size; // Allows us to unique the type.
+
+  ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
+                    ArraySizeModifier sm, unsigned tq)
+    : ArrayType(ConstantArray, et, can, sm, tq,
+                et->containsUnexpandedParameterPack()),
+      Size(size) {}
+protected:
+  ConstantArrayType(TypeClass tc, QualType et, QualType can,
+                    const llvm::APInt &size, ArraySizeModifier sm, unsigned tq)
+    : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()),
+      Size(size) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  const llvm::APInt &getSize() const { return Size; }
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+
+  /// \brief Determine the number of bits required to address a member of
+  // an array with the given element type and number of elements.
+  static unsigned getNumAddressingBits(ASTContext &Context,
+                                       QualType ElementType,
+                                       const llvm::APInt &NumElements);
+
+  /// \brief Determine the maximum number of active bits that an array's size
+  /// can require, which limits the maximum size of the array.
+  static unsigned getMaxSizeBits(ASTContext &Context);
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getSize(),
+            getSizeModifier(), getIndexTypeCVRQualifiers());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
+                      const llvm::APInt &ArraySize, ArraySizeModifier SizeMod,
+                      unsigned TypeQuals) {
+    ID.AddPointer(ET.getAsOpaquePtr());
+    ID.AddInteger(ArraySize.getZExtValue());
+    ID.AddInteger(SizeMod);
+    ID.AddInteger(TypeQuals);
+  }
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ConstantArray;
+  }
+};
+
+/// IncompleteArrayType - This class represents C arrays with an unspecified
+/// size.  For example 'int A[]' has an IncompleteArrayType where the element
+/// type is 'int' and the size is unspecified.
+class IncompleteArrayType : public ArrayType {
+
+  IncompleteArrayType(QualType et, QualType can,
+                      ArraySizeModifier sm, unsigned tq)
+    : ArrayType(IncompleteArray, et, can, sm, tq,
+                et->containsUnexpandedParameterPack()) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == IncompleteArray;
+  }
+
+  friend class StmtIteratorBase;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getSizeModifier(),
+            getIndexTypeCVRQualifiers());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
+                      ArraySizeModifier SizeMod, unsigned TypeQuals) {
+    ID.AddPointer(ET.getAsOpaquePtr());
+    ID.AddInteger(SizeMod);
+    ID.AddInteger(TypeQuals);
+  }
+};
+
+/// VariableArrayType - This class represents C arrays with a specified size
+/// which is not an integer-constant-expression.  For example, 'int s[x+foo()]'.
+/// Since the size expression is an arbitrary expression, we store it as such.
+///
+/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
+/// should not be: two lexically equivalent variable array types could mean
+/// different things, for example, these variables do not have the same type
+/// dynamically:
+///
+/// void foo(int x) {
+///   int Y[x];
+///   ++x;
+///   int Z[x];
+/// }
+///
+class VariableArrayType : public ArrayType {
+  /// SizeExpr - An assignment expression. VLA's are only permitted within
+  /// a function block.
+  Stmt *SizeExpr;
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
+  VariableArrayType(QualType et, QualType can, Expr *e,
+                    ArraySizeModifier sm, unsigned tq,
+                    SourceRange brackets)
+    : ArrayType(VariableArray, et, can, sm, tq,
+                et->containsUnexpandedParameterPack()),
+      SizeExpr((Stmt*) e), Brackets(brackets) {}
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  Expr *getSizeExpr() const {
+    // We use C-style casts instead of cast<> here because we do not wish
+    // to have a dependency of Type.h on Stmt.h/Expr.h.
+    return (Expr*) SizeExpr;
+  }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == VariableArray;
+  }
+
+  friend class StmtIteratorBase;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    llvm_unreachable("Cannot unique VariableArrayTypes.");
+  }
+};
+
+/// DependentSizedArrayType - This type represents an array type in
+/// C++ whose size is a value-dependent expression. For example:
+///
+/// \code
+/// template<typename T, int Size>
+/// class array {
+///   T data[Size];
+/// };
+/// \endcode
+///
+/// For these types, we won't actually know what the array bound is
+/// until template instantiation occurs, at which point this will
+/// become either a ConstantArrayType or a VariableArrayType.
+class DependentSizedArrayType : public ArrayType {
+  const ASTContext &Context;
+
+  /// \brief An assignment expression that will instantiate to the
+  /// size of the array.
+  ///
+  /// The expression itself might be NULL, in which case the array
+  /// type will have its size deduced from an initializer.
+  Stmt *SizeExpr;
+
+  /// Brackets - The left and right array brackets.
+  SourceRange Brackets;
+
+  DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
+                          Expr *e, ArraySizeModifier sm, unsigned tq,
+                          SourceRange brackets);
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  Expr *getSizeExpr() const {
+    // We use C-style casts instead of cast<> here because we do not wish
+    // to have a dependency of Type.h on Stmt.h/Expr.h.
+    return (Expr*) SizeExpr;
+  }
+  SourceRange getBracketsRange() const { return Brackets; }
+  SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
+  SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentSizedArray;
+  }
+
+  friend class StmtIteratorBase;
+
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getElementType(),
+            getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+                      QualType ET, ArraySizeModifier SizeMod,
+                      unsigned TypeQuals, Expr *E);
+};
+
+/// DependentSizedExtVectorType - This type represent an extended vector type
+/// where either the type or size is dependent. For example:
+/// @code
+/// template<typename T, int Size>
+/// class vector {
+///   typedef T __attribute__((ext_vector_type(Size))) type;
+/// }
+/// @endcode
+class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
+  const ASTContext &Context;
+  Expr *SizeExpr;
+  /// ElementType - The element type of the array.
+  QualType ElementType;
+  SourceLocation loc;
+
+  DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
+                              QualType can, Expr *SizeExpr, SourceLocation loc);
+
+  friend class ASTContext;
+
+public:
+  Expr *getSizeExpr() const { return SizeExpr; }
+  QualType getElementType() const { return ElementType; }
+  SourceLocation getAttributeLoc() const { return loc; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentSizedExtVector;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getElementType(), getSizeExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+                      QualType ElementType, Expr *SizeExpr);
+};
+
+
+/// VectorType - GCC generic vector type. This type is created using
+/// __attribute__((vector_size(n)), where "n" specifies the vector size in
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
+/// client is responsible for converting the size into the number of elements.
+class VectorType : public Type, public llvm::FoldingSetNode {
+public:
+  enum VectorKind {
+    GenericVector,  // not a target-specific vector type
+    AltiVecVector,  // is AltiVec vector
+    AltiVecPixel,   // is AltiVec 'vector Pixel'
+    AltiVecBool,    // is AltiVec 'vector bool ...'
+    NeonVector,     // is ARM Neon vector
+    NeonPolyVector  // is ARM Neon polynomial vector
+  };
+protected:
+  /// ElementType - The element type of the vector.
+  QualType ElementType;
+
+  VectorType(QualType vecType, unsigned nElements, QualType canonType,
+             VectorKind vecKind);
+
+  VectorType(TypeClass tc, QualType vecType, unsigned nElements,
+             QualType canonType, VectorKind vecKind);
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+
+  QualType getElementType() const { return ElementType; }
+  unsigned getNumElements() const { return VectorTypeBits.NumElements; }
+  static bool isVectorSizeTooLarge(unsigned NumElements) {
+    return NumElements > VectorTypeBitfields::MaxNumElements;
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  VectorKind getVectorKind() const {
+    return VectorKind(VectorTypeBits.VecKind);
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getElementType(), getNumElements(),
+            getTypeClass(), getVectorKind());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
+                      unsigned NumElements, TypeClass TypeClass,
+                      VectorKind VecKind) {
+    ID.AddPointer(ElementType.getAsOpaquePtr());
+    ID.AddInteger(NumElements);
+    ID.AddInteger(TypeClass);
+    ID.AddInteger(VecKind);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
+  }
+};
+
+/// ExtVectorType - Extended vector type. This type is created using
+/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
+/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
+/// class enables syntactic extensions, like Vector Components for accessing
+/// points, colors, and textures (modeled after OpenGL Shading Language).
+class ExtVectorType : public VectorType {
+  ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
+    VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  static int getPointAccessorIdx(char c) {
+    switch (c) {
+    default: return -1;
+    case 'x': return 0;
+    case 'y': return 1;
+    case 'z': return 2;
+    case 'w': return 3;
+    }
+  }
+  static int getNumericAccessorIdx(char c) {
+    switch (c) {
+      default: return -1;
+      case '0': return 0;
+      case '1': return 1;
+      case '2': return 2;
+      case '3': return 3;
+      case '4': return 4;
+      case '5': return 5;
+      case '6': return 6;
+      case '7': return 7;
+      case '8': return 8;
+      case '9': return 9;
+      case 'A':
+      case 'a': return 10;
+      case 'B':
+      case 'b': return 11;
+      case 'C':
+      case 'c': return 12;
+      case 'D':
+      case 'd': return 13;
+      case 'E':
+      case 'e': return 14;
+      case 'F':
+      case 'f': return 15;
+    }
+  }
+
+  static int getAccessorIdx(char c) {
+    if (int idx = getPointAccessorIdx(c)+1) return idx-1;
+    return getNumericAccessorIdx(c);
+  }
+
+  bool isAccessorWithinNumElements(char c) const {
+    if (int idx = getAccessorIdx(c)+1)
+      return unsigned(idx-1) < getNumElements();
+    return false;
+  }
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ExtVector;
+  }
+};
+
+/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
+/// class of FunctionNoProtoType and FunctionProtoType.
+///
+class FunctionType : public Type {
+  // The type returned by the function.
+  QualType ResultType;
+
+ public:
+  /// ExtInfo - A class which abstracts out some details necessary for
+  /// making a call.
+  ///
+  /// It is not actually used directly for storing this information in
+  /// a FunctionType, although FunctionType does currently use the
+  /// same bit-pattern.
+  ///
+  // If you add a field (say Foo), other than the obvious places (both,
+  // constructors, compile failures), what you need to update is
+  // * Operator==
+  // * getFoo
+  // * withFoo
+  // * functionType. Add Foo, getFoo.
+  // * ASTContext::getFooType
+  // * ASTContext::mergeFunctionTypes
+  // * FunctionNoProtoType::Profile
+  // * FunctionProtoType::Profile
+  // * TypePrinter::PrintFunctionProto
+  // * AST read and write
+  // * Codegen
+  class ExtInfo {
+    // Feel free to rearrange or add bits, but if you go over 9,
+    // you'll need to adjust both the Bits field below and
+    // Type::FunctionTypeBitfields.
+
+    //   |  CC  |noreturn|produces|regparm|
+    //   |0 .. 3|   4    |    5   | 6 .. 8|
+    //
+    // regparm is either 0 (no regparm attribute) or the regparm value+1.
+    enum { CallConvMask = 0xF };
+    enum { NoReturnMask = 0x10 };
+    enum { ProducesResultMask = 0x20 };
+    enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
+           RegParmOffset = 6 }; // Assumed to be the last field
+
+    uint16_t Bits;
+
+    ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
+
+    friend class FunctionType;
+
+   public:
+    // Constructor with no defaults. Use this when you know that you
+    // have all the elements (when reading an AST file for example).
+    ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
+            bool producesResult) {
+      assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
+      Bits = ((unsigned) cc) |
+             (noReturn ? NoReturnMask : 0) |
+             (producesResult ? ProducesResultMask : 0) |
+             (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
+    }
+
+    // Constructor with all defaults. Use when for example creating a
+    // function know to use defaults.
+    ExtInfo() : Bits(CC_C) { }
+
+    // Constructor with just the calling convention, which is an important part
+    // of the canonical type.
+    ExtInfo(CallingConv CC) : Bits(CC) { }
+
+    bool getNoReturn() const { return Bits & NoReturnMask; }
+    bool getProducesResult() const { return Bits & ProducesResultMask; }
+    bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
+    unsigned getRegParm() const {
+      unsigned RegParm = Bits >> RegParmOffset;
+      if (RegParm > 0)
+        --RegParm;
+      return RegParm;
+    }
+    CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
+
+    bool operator==(ExtInfo Other) const {
+      return Bits == Other.Bits;
+    }
+    bool operator!=(ExtInfo Other) const {
+      return Bits != Other.Bits;
+    }
+
+    // Note that we don't have setters. That is by design, use
+    // the following with methods instead of mutating these objects.
+
+    ExtInfo withNoReturn(bool noReturn) const {
+      if (noReturn)
+        return ExtInfo(Bits | NoReturnMask);
+      else
+        return ExtInfo(Bits & ~NoReturnMask);
+    }
+
+    ExtInfo withProducesResult(bool producesResult) const {
+      if (producesResult)
+        return ExtInfo(Bits | ProducesResultMask);
+      else
+        return ExtInfo(Bits & ~ProducesResultMask);
+    }
+
+    ExtInfo withRegParm(unsigned RegParm) const {
+      assert(RegParm < 7 && "Invalid regparm value");
+      return ExtInfo((Bits & ~RegParmMask) |
+                     ((RegParm + 1) << RegParmOffset));
+    }
+
+    ExtInfo withCallingConv(CallingConv cc) const {
+      return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
+    }
+
+    void Profile(llvm::FoldingSetNodeID &ID) const {
+      ID.AddInteger(Bits);
+    }
+  };
+
+protected:
+  FunctionType(TypeClass tc, QualType res,
+               unsigned typeQuals, QualType Canonical, bool Dependent,
+               bool InstantiationDependent,
+               bool VariablyModified, bool ContainsUnexpandedParameterPack,
+               ExtInfo Info)
+    : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
+           ContainsUnexpandedParameterPack),
+      ResultType(res) {
+    FunctionTypeBits.ExtInfo = Info.Bits;
+    FunctionTypeBits.TypeQuals = typeQuals;
+  }
+  unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
+
+public:
+  QualType getReturnType() const { return ResultType; }
+
+  bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
+  unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
+  /// \brief Determine whether this function type includes the GNU noreturn
+  /// attribute. The C++11 [[noreturn]] attribute does not affect the function
+  /// type.
+  bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
+  CallingConv getCallConv() const { return getExtInfo().getCC(); }
+  ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
+  bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
+  bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
+  bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
+
+  /// \brief Determine the type of an expression that calls a function of
+  /// this type.
+  QualType getCallResultType(ASTContext &Context) const {
+    return getReturnType().getNonLValueExprType(Context);
+  }
+
+  static StringRef getNameForCallConv(CallingConv CC);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionNoProto ||
+           T->getTypeClass() == FunctionProto;
+  }
+};
+
+/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
+/// no information available about its arguments.
+class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
+  FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
+    : FunctionType(FunctionNoProto, Result, 0, Canonical,
+                   /*Dependent=*/false, /*InstantiationDependent=*/false,
+                   Result->isVariablyModifiedType(),
+                   /*ContainsUnexpandedParameterPack=*/false, Info) {}
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  // No additional state past what FunctionType provides.
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getReturnType(), getExtInfo());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
+                      ExtInfo Info) {
+    Info.Profile(ID);
+    ID.AddPointer(ResultType.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionNoProto;
+  }
+};
+
+/// FunctionProtoType - Represents a prototype with parameter type info, e.g.
+/// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
+/// parameters, not as having a single void parameter. Such a type can have an
+/// exception specification, but this specification is not part of the canonical
+/// type.
+class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
+public:
+  /// ExtProtoInfo - Extra information about a function prototype.
+  struct ExtProtoInfo {
+    ExtProtoInfo()
+        : Variadic(false), HasTrailingReturn(false), TypeQuals(0),
+          ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
+          Exceptions(nullptr), NoexceptExpr(nullptr),
+          ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+          ConsumedParameters(nullptr) {}
+
+    ExtProtoInfo(CallingConv CC)
+        : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
+          ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
+          Exceptions(nullptr), NoexceptExpr(nullptr),
+          ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+          ConsumedParameters(nullptr) {}
+
+    FunctionType::ExtInfo ExtInfo;
+    bool Variadic : 1;
+    bool HasTrailingReturn : 1;
+    unsigned char TypeQuals;
+    ExceptionSpecificationType ExceptionSpecType;
+    RefQualifierKind RefQualifier;
+    unsigned NumExceptions;
+    const QualType *Exceptions;
+    Expr *NoexceptExpr;
+    FunctionDecl *ExceptionSpecDecl;
+    FunctionDecl *ExceptionSpecTemplate;
+    const bool *ConsumedParameters;
+  };
+
+private:
+  /// \brief Determine whether there are any argument types that
+  /// contain an unexpanded parameter pack.
+  static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
+                                                 unsigned numArgs) {
+    for (unsigned Idx = 0; Idx < numArgs; ++Idx)
+      if (ArgArray[Idx]->containsUnexpandedParameterPack())
+        return true;
+
+    return false;
+  }
+
+  FunctionProtoType(QualType result, ArrayRef<QualType> params,
+                    QualType canonical, const ExtProtoInfo &epi);
+
+  /// The number of parameters this function has, not counting '...'.
+  unsigned NumParams : 15;
+
+  /// NumExceptions - The number of types in the exception spec, if any.
+  unsigned NumExceptions : 9;
+
+  /// ExceptionSpecType - The type of exception specification this function has.
+  unsigned ExceptionSpecType : 3;
+
+  /// HasAnyConsumedParams - Whether this function has any consumed parameters.
+  unsigned HasAnyConsumedParams : 1;
+
+  /// Variadic - Whether the function is variadic.
+  unsigned Variadic : 1;
+
+  /// HasTrailingReturn - Whether this function has a trailing return type.
+  unsigned HasTrailingReturn : 1;
+
+  /// \brief The ref-qualifier associated with a \c FunctionProtoType.
+  ///
+  /// This is a value of type \c RefQualifierKind.
+  unsigned RefQualifier : 2;
+
+  // ParamInfo - There is an variable size array after the class in memory that
+  // holds the parameter types.
+
+  // Exceptions - There is another variable size array after ArgInfo that
+  // holds the exception types.
+
+  // NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
+  // to the expression in the noexcept() specifier.
+
+  // ExceptionSpecDecl, ExceptionSpecTemplate - Instead of Exceptions, there may
+  // be a pair of FunctionDecl* pointing to the function which should be used to
+  // instantiate this function type's exception specification, and the function
+  // from which it should be instantiated.
+
+  // ConsumedParameters - A variable size array, following Exceptions
+  // and of length NumParams, holding flags indicating which parameters
+  // are consumed.  This only appears if HasAnyConsumedParams is true.
+
+  friend class ASTContext;  // ASTContext creates these.
+
+  const bool *getConsumedParamsBuffer() const {
+    assert(hasAnyConsumedParams());
+
+    // Find the end of the exceptions.
+    Expr *const *eh_end = reinterpret_cast<Expr *const *>(param_type_end());
+    if (getExceptionSpecType() != EST_ComputedNoexcept)
+      eh_end += NumExceptions;
+    else
+      eh_end += 1; // NoexceptExpr
+
+    return reinterpret_cast<const bool*>(eh_end);
+  }
+
+public:
+  unsigned getNumParams() const { return NumParams; }
+  QualType getParamType(unsigned i) const {
+    assert(i < NumParams && "invalid parameter index");
+    return param_type_begin()[i];
+  }
+  ArrayRef<QualType> getParamTypes() const {
+    return ArrayRef<QualType>(param_type_begin(), param_type_end());
+  }
+
+  ExtProtoInfo getExtProtoInfo() const {
+    ExtProtoInfo EPI;
+    EPI.ExtInfo = getExtInfo();
+    EPI.Variadic = isVariadic();
+    EPI.HasTrailingReturn = hasTrailingReturn();
+    EPI.ExceptionSpecType = getExceptionSpecType();
+    EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
+    EPI.RefQualifier = getRefQualifier();
+    if (EPI.ExceptionSpecType == EST_Dynamic) {
+      EPI.NumExceptions = NumExceptions;
+      EPI.Exceptions = exception_begin();
+    } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
+      EPI.NoexceptExpr = getNoexceptExpr();
+    } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
+      EPI.ExceptionSpecDecl = getExceptionSpecDecl();
+      EPI.ExceptionSpecTemplate = getExceptionSpecTemplate();
+    } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
+      EPI.ExceptionSpecDecl = getExceptionSpecDecl();
+    }
+    if (hasAnyConsumedParams())
+      EPI.ConsumedParameters = getConsumedParamsBuffer();
+    return EPI;
+  }
+
+  /// \brief Get the kind of exception specification on this function.
+  ExceptionSpecificationType getExceptionSpecType() const {
+    return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+  }
+  /// \brief Return whether this function has any kind of exception spec.
+  bool hasExceptionSpec() const {
+    return getExceptionSpecType() != EST_None;
+  }
+  /// \brief Return whether this function has a dynamic (throw) exception spec.
+  bool hasDynamicExceptionSpec() const {
+    return isDynamicExceptionSpec(getExceptionSpecType());
+  }
+  /// \brief Return whether this function has a noexcept exception spec.
+  bool hasNoexceptExceptionSpec() const {
+    return isNoexceptExceptionSpec(getExceptionSpecType());
+  }
+  /// \brief Result type of getNoexceptSpec().
+  enum NoexceptResult {
+    NR_NoNoexcept,  ///< There is no noexcept specifier.
+    NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
+    NR_Dependent,   ///< The noexcept specifier is dependent.
+    NR_Throw,       ///< The noexcept specifier evaluates to false.
+    NR_Nothrow      ///< The noexcept specifier evaluates to true.
+  };
+  /// \brief Get the meaning of the noexcept spec on this function, if any.
+  NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const;
+  unsigned getNumExceptions() const { return NumExceptions; }
+  QualType getExceptionType(unsigned i) const {
+    assert(i < NumExceptions && "Invalid exception number!");
+    return exception_begin()[i];
+  }
+  Expr *getNoexceptExpr() const {
+    if (getExceptionSpecType() != EST_ComputedNoexcept)
+      return nullptr;
+    // NoexceptExpr sits where the arguments end.
+    return *reinterpret_cast<Expr *const *>(param_type_end());
+  }
+  /// \brief If this function type has an exception specification which hasn't
+  /// been determined yet (either because it has not been evaluated or because
+  /// it has not been instantiated), this is the function whose exception
+  /// specification is represented by this type.
+  FunctionDecl *getExceptionSpecDecl() const {
+    if (getExceptionSpecType() != EST_Uninstantiated &&
+        getExceptionSpecType() != EST_Unevaluated)
+      return nullptr;
+    return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
+  }
+  /// \brief If this function type has an uninstantiated exception
+  /// specification, this is the function whose exception specification
+  /// should be instantiated to find the exception specification for
+  /// this type.
+  FunctionDecl *getExceptionSpecTemplate() const {
+    if (getExceptionSpecType() != EST_Uninstantiated)
+      return nullptr;
+    return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
+  }
+  /// \brief Determine whether this function type has a non-throwing exception
+  /// specification. If this depends on template arguments, returns
+  /// \c ResultIfDependent.
+  bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
+
+  bool isVariadic() const { return Variadic; }
+
+  /// \brief Determines whether this function prototype contains a
+  /// parameter pack at the end.
+  ///
+  /// A function template whose last parameter is a parameter pack can be
+  /// called with an arbitrary number of arguments, much like a variadic
+  /// function.
+  bool isTemplateVariadic() const;
+
+  bool hasTrailingReturn() const { return HasTrailingReturn; }
+
+  unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
+
+
+  /// \brief Retrieve the ref-qualifier associated with this function type.
+  RefQualifierKind getRefQualifier() const {
+    return static_cast<RefQualifierKind>(RefQualifier);
+  }
+
+  typedef const QualType *param_type_iterator;
+  typedef llvm::iterator_range<param_type_iterator> param_type_range;
+
+  param_type_range param_types() const {
+    return param_type_range(param_type_begin(), param_type_end());
+  }
+  param_type_iterator param_type_begin() const {
+    return reinterpret_cast<const QualType *>(this+1);
+  }
+  param_type_iterator param_type_end() const {
+    return param_type_begin() + NumParams;
+  }
+
+  typedef const QualType *exception_iterator;
+  typedef llvm::iterator_range<exception_iterator> exception_range;
+
+  exception_range exceptions() const {
+    return exception_range(exception_begin(), exception_end());
+  }
+  exception_iterator exception_begin() const {
+    // exceptions begin where arguments end
+    return param_type_end();
+  }
+  exception_iterator exception_end() const {
+    if (getExceptionSpecType() != EST_Dynamic)
+      return exception_begin();
+    return exception_begin() + NumExceptions;
+  }
+
+  bool hasAnyConsumedParams() const { return HasAnyConsumedParams; }
+  bool isParamConsumed(unsigned I) const {
+    assert(I < getNumParams() && "parameter index out of range");
+    if (hasAnyConsumedParams())
+      return getConsumedParamsBuffer()[I];
+    return false;
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void printExceptionSpecification(raw_ostream &OS, 
+                                   const PrintingPolicy &Policy) const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == FunctionProto;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+                      param_type_iterator ArgTys, unsigned NumArgs,
+                      const ExtProtoInfo &EPI, const ASTContext &Context);
+};
+
+
+/// \brief Represents the dependent type named by a dependently-scoped
+/// typename using declaration, e.g.
+///   using typename Base<T>::foo;
+/// Template instantiation turns these into the underlying type.
+class UnresolvedUsingType : public Type {
+  UnresolvedUsingTypenameDecl *Decl;
+
+  UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
+    : Type(UnresolvedUsing, QualType(), true, true, false,
+           /*ContainsUnexpandedParameterPack=*/false),
+      Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
+  friend class ASTContext; // ASTContext creates these.
+public:
+
+  UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == UnresolvedUsing;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    return Profile(ID, Decl);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      UnresolvedUsingTypenameDecl *D) {
+    ID.AddPointer(D);
+  }
+};
+
+
+class TypedefType : public Type {
+  TypedefNameDecl *Decl;
+protected:
+  TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
+    : Type(tc, can, can->isDependentType(),
+           can->isInstantiationDependentType(),
+           can->isVariablyModifiedType(),
+           /*ContainsUnexpandedParameterPack=*/false),
+      Decl(const_cast<TypedefNameDecl*>(D)) {
+    assert(!isa<TypedefType>(can) && "Invalid canonical type");
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+
+  TypedefNameDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
+};
+
+/// TypeOfExprType (GCC extension).
+class TypeOfExprType : public Type {
+  Expr *TOExpr;
+
+protected:
+  TypeOfExprType(Expr *E, QualType can = QualType());
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  Expr *getUnderlyingExpr() const { return TOExpr; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const;
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
+};
+
+/// \brief Internal representation of canonical, dependent
+/// typeof(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via TypeOfExprType nodes.
+class DependentTypeOfExprType
+  : public TypeOfExprType, public llvm::FoldingSetNode {
+  const ASTContext &Context;
+
+public:
+  DependentTypeOfExprType(const ASTContext &Context, Expr *E)
+    : TypeOfExprType(E), Context(Context) { }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getUnderlyingExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+                      Expr *E);
+};
+
+/// TypeOfType (GCC extension).
+class TypeOfType : public Type {
+  QualType TOType;
+  TypeOfType(QualType T, QualType can)
+    : Type(TypeOf, can, T->isDependentType(),
+           T->isInstantiationDependentType(),
+           T->isVariablyModifiedType(),
+           T->containsUnexpandedParameterPack()),
+      TOType(T) {
+    assert(!isa<TypedefType>(can) && "Invalid canonical type");
+  }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  QualType getUnderlyingType() const { return TOType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getUnderlyingType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
+};
+
+/// DecltypeType (C++0x)
+class DecltypeType : public Type {
+  Expr *E;
+  QualType UnderlyingType;
+
+protected:
+  DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  Expr *getUnderlyingExpr() const { return E; }
+  QualType getUnderlyingType() const { return UnderlyingType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const;
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const;
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
+};
+
+/// \brief Internal representation of canonical, dependent
+/// decltype(expr) types.
+///
+/// This class is used internally by the ASTContext to manage
+/// canonical, dependent types, only. Clients will only see instances
+/// of this class via DecltypeType nodes.
+class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
+  const ASTContext &Context;
+
+public:
+  DependentDecltypeType(const ASTContext &Context, Expr *E);
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, Context, getUnderlyingExpr());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
+                      Expr *E);
+};
+
+/// \brief A unary type transform, which is a type constructed from another
+class UnaryTransformType : public Type {
+public:
+  enum UTTKind {
+    EnumUnderlyingType
+  };
+
+private:
+  /// The untransformed type.
+  QualType BaseType;
+  /// The transformed type if not dependent, otherwise the same as BaseType.
+  QualType UnderlyingType;
+
+  UTTKind UKind;
+protected:
+  UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
+                     QualType CanonicalTy);
+  friend class ASTContext;
+public:
+  bool isSugared() const { return !isDependentType(); }
+  QualType desugar() const { return UnderlyingType; }
+
+  QualType getUnderlyingType() const { return UnderlyingType; }
+  QualType getBaseType() const { return BaseType; }
+
+  UTTKind getUTTKind() const { return UKind; }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == UnaryTransform;
+  }
+};
+
+class TagType : public Type {
+  /// Stores the TagDecl associated with this type. The decl may point to any
+  /// TagDecl that declares the entity.
+  TagDecl * decl;
+
+  friend class ASTReader;
+  
+protected:
+  TagType(TypeClass TC, const TagDecl *D, QualType can);
+
+public:
+  TagDecl *getDecl() const;
+
+  /// @brief Determines whether this type is in the process of being
+  /// defined.
+  bool isBeingDefined() const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
+  }
+};
+
+/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
+/// to detect TagType objects of structs/unions/classes.
+class RecordType : public TagType {
+protected:
+  explicit RecordType(const RecordDecl *D)
+    : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  explicit RecordType(TypeClass TC, RecordDecl *D)
+    : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  friend class ASTContext;   // ASTContext creates these.
+public:
+
+  RecordDecl *getDecl() const {
+    return reinterpret_cast<RecordDecl*>(TagType::getDecl());
+  }
+
+  // FIXME: This predicate is a helper to QualType/Type. It needs to
+  // recursively check all fields for const-ness. If any field is declared
+  // const, it needs to return false.
+  bool hasConstFields() const { return false; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Record; }
+};
+
+/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
+/// to detect TagType objects of enums.
+class EnumType : public TagType {
+  explicit EnumType(const EnumDecl *D)
+    : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
+  friend class ASTContext;   // ASTContext creates these.
+public:
+
+  EnumDecl *getDecl() const {
+    return reinterpret_cast<EnumDecl*>(TagType::getDecl());
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
+};
+
+/// AttributedType - An attributed type is a type to which a type
+/// attribute has been applied.  The "modified type" is the
+/// fully-sugared type to which the attributed type was applied;
+/// generally it is not canonically equivalent to the attributed type.
+/// The "equivalent type" is the minimally-desugared type which the
+/// type is canonically equivalent to.
+///
+/// For example, in the following attributed type:
+///     int32_t __attribute__((vector_size(16)))
+///   - the modified type is the TypedefType for int32_t
+///   - the equivalent type is VectorType(16, int32_t)
+///   - the canonical type is VectorType(16, int)
+class AttributedType : public Type, public llvm::FoldingSetNode {
+public:
+  // It is really silly to have yet another attribute-kind enum, but
+  // clang::attr::Kind doesn't currently cover the pure type attrs.
+  enum Kind {
+    // Expression operand.
+    attr_address_space,
+    attr_regparm,
+    attr_vector_size,
+    attr_neon_vector_type,
+    attr_neon_polyvector_type,
+
+    FirstExprOperandKind = attr_address_space,
+    LastExprOperandKind = attr_neon_polyvector_type,
+
+    // Enumerated operand (string or keyword).
+    attr_objc_gc,
+    attr_objc_ownership,
+    attr_pcs,
+    attr_pcs_vfp,
+
+    FirstEnumOperandKind = attr_objc_gc,
+    LastEnumOperandKind = attr_pcs_vfp,
+
+    // No operand.
+    attr_noreturn,
+    attr_cdecl,
+    attr_fastcall,
+    attr_stdcall,
+    attr_thiscall,
+    attr_pascal,
+    attr_pnaclcall,
+    attr_inteloclbicc,
+    attr_ms_abi,
+    attr_sysv_abi,
+    attr_ptr32,
+    attr_ptr64,
+    attr_sptr,
+    attr_uptr
+  };
+
+private:
+  QualType ModifiedType;
+  QualType EquivalentType;
+
+  friend class ASTContext; // creates these
+
+  AttributedType(QualType canon, Kind attrKind,
+                 QualType modified, QualType equivalent)
+    : Type(Attributed, canon, canon->isDependentType(),
+           canon->isInstantiationDependentType(),
+           canon->isVariablyModifiedType(),
+           canon->containsUnexpandedParameterPack()),
+      ModifiedType(modified), EquivalentType(equivalent) {
+    AttributedTypeBits.AttrKind = attrKind;
+  }
+
+public:
+  Kind getAttrKind() const {
+    return static_cast<Kind>(AttributedTypeBits.AttrKind);
+  }
+
+  QualType getModifiedType() const { return ModifiedType; }
+  QualType getEquivalentType() const { return EquivalentType; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return getEquivalentType(); }
+
+  bool isMSTypeSpec() const;
+
+  bool isCallingConv() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
+                      QualType modified, QualType equivalent) {
+    ID.AddInteger(attrKind);
+    ID.AddPointer(modified.getAsOpaquePtr());
+    ID.AddPointer(equivalent.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Attributed;
+  }
+};
+
+class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+  // Helper data collector for canonical types.
+  struct CanonicalTTPTInfo {
+    unsigned Depth : 15;
+    unsigned ParameterPack : 1;
+    unsigned Index : 16;
+  };
+
+  union {
+    // Info for the canonical type.
+    CanonicalTTPTInfo CanTTPTInfo;
+    // Info for the non-canonical type.
+    TemplateTypeParmDecl *TTPDecl;
+  };
+
+  /// Build a non-canonical type.
+  TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
+    : Type(TemplateTypeParm, Canon, /*Dependent=*/true,
+           /*InstantiationDependent=*/true,
+           /*VariablyModified=*/false,
+           Canon->containsUnexpandedParameterPack()),
+      TTPDecl(TTPDecl) { }
+
+  /// Build the canonical type.
+  TemplateTypeParmType(unsigned D, unsigned I, bool PP)
+    : Type(TemplateTypeParm, QualType(this, 0),
+           /*Dependent=*/true,
+           /*InstantiationDependent=*/true,
+           /*VariablyModified=*/false, PP) {
+    CanTTPTInfo.Depth = D;
+    CanTTPTInfo.Index = I;
+    CanTTPTInfo.ParameterPack = PP;
+  }
+
+  friend class ASTContext;  // ASTContext creates these
+
+  const CanonicalTTPTInfo& getCanTTPTInfo() const {
+    QualType Can = getCanonicalTypeInternal();
+    return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
+  }
+
+public:
+  unsigned getDepth() const { return getCanTTPTInfo().Depth; }
+  unsigned getIndex() const { return getCanTTPTInfo().Index; }
+  bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
+
+  TemplateTypeParmDecl *getDecl() const {
+    return isCanonicalUnqualified() ? nullptr : TTPDecl;
+  }
+
+  IdentifierInfo *getIdentifier() const;
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
+                      unsigned Index, bool ParameterPack,
+                      TemplateTypeParmDecl *TTPDecl) {
+    ID.AddInteger(Depth);
+    ID.AddInteger(Index);
+    ID.AddBoolean(ParameterPack);
+    ID.AddPointer(TTPDecl);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == TemplateTypeParm;
+  }
+};
+
+/// \brief Represents the result of substituting a type for a template
+/// type parameter.
+///
+/// Within an instantiated template, all template type parameters have
+/// been replaced with these.  They are used solely to record that a
+/// type was originally written as a template type parameter;
+/// therefore they are never canonical.
+class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+  // The original type parameter.
+  const TemplateTypeParmType *Replaced;
+
+  SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
+    : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
+           Canon->isInstantiationDependentType(),
+           Canon->isVariablyModifiedType(),
+           Canon->containsUnexpandedParameterPack()),
+      Replaced(Param) { }
+
+  friend class ASTContext;
+
+public:
+  /// Gets the template parameter that was substituted for.
+  const TemplateTypeParmType *getReplacedParameter() const {
+    return Replaced;
+  }
+
+  /// Gets the type that was substituted for the template
+  /// parameter.
+  QualType getReplacementType() const {
+    return getCanonicalTypeInternal();
+  }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return getReplacementType(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getReplacedParameter(), getReplacementType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const TemplateTypeParmType *Replaced,
+                      QualType Replacement) {
+    ID.AddPointer(Replaced);
+    ID.AddPointer(Replacement.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == SubstTemplateTypeParm;
+  }
+};
+
+/// \brief Represents the result of substituting a set of types for a template
+/// type parameter pack.
+///
+/// When a pack expansion in the source code contains multiple parameter packs
+/// and those parameter packs correspond to different levels of template
+/// parameter lists, this type node is used to represent a template type
+/// parameter pack from an outer level, which has already had its argument pack
+/// substituted but that still lives within a pack expansion that itself
+/// could not be instantiated. When actually performing a substitution into
+/// that pack expansion (e.g., when all template parameters have corresponding
+/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
+/// at the current pack substitution index.
+class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
+  /// \brief The original type parameter.
+  const TemplateTypeParmType *Replaced;
+
+  /// \brief A pointer to the set of template arguments that this
+  /// parameter pack is instantiated with.
+  const TemplateArgument *Arguments;
+
+  /// \brief The number of template arguments in \c Arguments.
+  unsigned NumArguments;
+
+  SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
+                                QualType Canon,
+                                const TemplateArgument &ArgPack);
+
+  friend class ASTContext;
+
+public:
+  IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
+
+  /// Gets the template parameter that was substituted for.
+  const TemplateTypeParmType *getReplacedParameter() const {
+    return Replaced;
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  TemplateArgument getArgumentPack() const;
+
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const TemplateTypeParmType *Replaced,
+                      const TemplateArgument &ArgPack);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == SubstTemplateTypeParmPack;
+  }
+};
+
+/// \brief Represents a C++11 auto or C++1y decltype(auto) type.
+///
+/// These types are usually a placeholder for a deduced type. However, before
+/// the initializer is attached, or if the initializer is type-dependent, there
+/// is no deduced type and an auto type is canonical. In the latter case, it is
+/// also a dependent type.
+class AutoType : public Type, public llvm::FoldingSetNode {
+  AutoType(QualType DeducedType, bool IsDecltypeAuto, 
+           bool IsDependent)
+    : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
+           /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent,
+           /*VariablyModified=*/false, 
+           /*ContainsParameterPack=*/DeducedType.isNull() 
+               ? false : DeducedType->containsUnexpandedParameterPack()) {
+    assert((DeducedType.isNull() || !IsDependent) &&
+           "auto deduced to dependent type");
+    AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto;
+  }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; }
+
+  bool isSugared() const { return !isCanonicalUnqualified(); }
+  QualType desugar() const { return getCanonicalTypeInternal(); }
+
+  /// \brief Get the type deduced for this auto type, or null if it's either
+  /// not been deduced or was deduced to a dependent type.
+  QualType getDeducedType() const {
+    return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
+  }
+  bool isDeduced() const {
+    return !isCanonicalUnqualified() || isDependentType();
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getDeducedType(), isDecltypeAuto(), 
+		    isDependentType());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced,
+                      bool IsDecltypeAuto, bool IsDependent) {
+    ID.AddPointer(Deduced.getAsOpaquePtr());
+    ID.AddBoolean(IsDecltypeAuto);
+    ID.AddBoolean(IsDependent);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Auto;
+  }
+};
+
+/// \brief Represents a type template specialization; the template
+/// must be a class template, a type alias template, or a template
+/// template parameter.  A template which cannot be resolved to one of
+/// these, e.g. because it is written with a dependent scope
+/// specifier, is instead represented as a
+/// @c DependentTemplateSpecializationType.
+///
+/// A non-dependent template specialization type is always "sugar",
+/// typically for a @c RecordType.  For example, a class template
+/// specialization type of @c vector<int> will refer to a tag type for
+/// the instantiation @c std::vector<int, std::allocator<int>>
+///
+/// Template specializations are dependent if either the template or
+/// any of the template arguments are dependent, in which case the
+/// type may also be canonical.
+///
+/// Instances of this type are allocated with a trailing array of
+/// TemplateArguments, followed by a QualType representing the
+/// non-canonical aliased type when the template is a type alias
+/// template.
+class TemplateSpecializationType
+  : public Type, public llvm::FoldingSetNode {
+  /// \brief The name of the template being specialized.  This is
+  /// either a TemplateName::Template (in which case it is a
+  /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
+  /// TypeAliasTemplateDecl*), a
+  /// TemplateName::SubstTemplateTemplateParmPack, or a
+  /// TemplateName::SubstTemplateTemplateParm (in which case the
+  /// replacement must, recursively, be one of these).
+  TemplateName Template;
+
+  /// \brief - The number of template arguments named in this class
+  /// template specialization.
+  unsigned NumArgs : 31;
+
+  /// \brief Whether this template specialization type is a substituted
+  /// type alias.
+  bool TypeAlias : 1;
+    
+  TemplateSpecializationType(TemplateName T,
+                             const TemplateArgument *Args,
+                             unsigned NumArgs, QualType Canon,
+                             QualType Aliased);
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Determine whether any of the given template arguments are
+  /// dependent.
+  static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+                                            unsigned NumArgs,
+                                            bool &InstantiationDependent);
+
+  static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
+                                            bool &InstantiationDependent);
+
+  /// \brief Print a template argument list, including the '<' and '>'
+  /// enclosing the template arguments.
+  static void PrintTemplateArgumentList(raw_ostream &OS,
+                                        const TemplateArgument *Args,
+                                        unsigned NumArgs,
+                                        const PrintingPolicy &Policy,
+                                        bool SkipBrackets = false);
+
+  static void PrintTemplateArgumentList(raw_ostream &OS,
+                                        const TemplateArgumentLoc *Args,
+                                        unsigned NumArgs,
+                                        const PrintingPolicy &Policy);
+
+  static void PrintTemplateArgumentList(raw_ostream &OS,
+                                        const TemplateArgumentListInfo &,
+                                        const PrintingPolicy &Policy);
+
+  /// True if this template specialization type matches a current
+  /// instantiation in the context in which it is found.
+  bool isCurrentInstantiation() const {
+    return isa<InjectedClassNameType>(getCanonicalTypeInternal());
+  }
+
+  /// \brief Determine if this template specialization type is for a type alias
+  /// template that has been substituted.
+  ///
+  /// Nearly every template specialization type whose template is an alias
+  /// template will be substituted. However, this is not the case when
+  /// the specialization contains a pack expansion but the template alias
+  /// does not have a corresponding parameter pack, e.g.,
+  ///
+  /// \code
+  /// template<typename T, typename U, typename V> struct S;
+  /// template<typename T, typename U> using A = S<T, int, U>;
+  /// template<typename... Ts> struct X {
+  ///   typedef A<Ts...> type; // not a type alias
+  /// };
+  /// \endcode
+  bool isTypeAlias() const { return TypeAlias; }
+    
+  /// Get the aliased type, if this is a specialization of a type alias
+  /// template.
+  QualType getAliasedType() const {
+    assert(isTypeAlias() && "not a type alias template specialization");
+    return *reinterpret_cast<const QualType*>(end());
+  }
+
+  typedef const TemplateArgument * iterator;
+
+  iterator begin() const { return getArgs(); }
+  iterator end() const; // defined inline in TemplateBase.h
+
+  /// \brief Retrieve the name of the template that we are specializing.
+  TemplateName getTemplateName() const { return Template; }
+
+  /// \brief Retrieve the template arguments.
+  const TemplateArgument *getArgs() const {
+    return reinterpret_cast<const TemplateArgument *>(this + 1);
+  }
+
+  /// \brief Retrieve the number of template arguments.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// \brief Retrieve a specific template argument as a type.
+  /// \pre @c isArgType(Arg)
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+  bool isSugared() const {
+    return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
+  }
+  QualType desugar() const { return getCanonicalTypeInternal(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
+    Profile(ID, Template, getArgs(), NumArgs, Ctx);
+    if (isTypeAlias())
+      getAliasedType().Profile(ID);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
+                      const TemplateArgument *Args,
+                      unsigned NumArgs,
+                      const ASTContext &Context);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == TemplateSpecialization;
+  }
+};
+
+/// \brief The injected class name of a C++ class template or class
+/// template partial specialization.  Used to record that a type was
+/// spelled with a bare identifier rather than as a template-id; the
+/// equivalent for non-templated classes is just RecordType.
+///
+/// Injected class name types are always dependent.  Template
+/// instantiation turns these into RecordTypes.
+///
+/// Injected class name types are always canonical.  This works
+/// because it is impossible to compare an injected class name type
+/// with the corresponding non-injected template type, for the same
+/// reason that it is impossible to directly compare template
+/// parameters from different dependent contexts: injected class name
+/// types can only occur within the scope of a particular templated
+/// declaration, and within that scope every template specialization
+/// will canonicalize to the injected class name (when appropriate
+/// according to the rules of the language).
+class InjectedClassNameType : public Type {
+  CXXRecordDecl *Decl;
+
+  /// The template specialization which this type represents.
+  /// For example, in
+  ///   template <class T> class A { ... };
+  /// this is A<T>, whereas in
+  ///   template <class X, class Y> class A<B<X,Y> > { ... };
+  /// this is A<B<X,Y> >.
+  ///
+  /// It is always unqualified, always a template specialization type,
+  /// and always dependent.
+  QualType InjectedType;
+
+  friend class ASTContext; // ASTContext creates these.
+  friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
+                          // currently suitable for AST reading, too much
+                          // interdependencies.
+  InjectedClassNameType(CXXRecordDecl *D, QualType TST)
+    : Type(InjectedClassName, QualType(), /*Dependent=*/true,
+           /*InstantiationDependent=*/true,
+           /*VariablyModified=*/false,
+           /*ContainsUnexpandedParameterPack=*/false),
+      Decl(D), InjectedType(TST) {
+    assert(isa<TemplateSpecializationType>(TST));
+    assert(!TST.hasQualifiers());
+    assert(TST->isDependentType());
+  }
+
+public:
+  QualType getInjectedSpecializationType() const { return InjectedType; }
+  const TemplateSpecializationType *getInjectedTST() const {
+    return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
+  }
+
+  CXXRecordDecl *getDecl() const;
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == InjectedClassName;
+  }
+};
+
+/// \brief The kind of a tag type.
+enum TagTypeKind {
+  /// \brief The "struct" keyword.
+  TTK_Struct,
+  /// \brief The "__interface" keyword.
+  TTK_Interface,
+  /// \brief The "union" keyword.
+  TTK_Union,
+  /// \brief The "class" keyword.
+  TTK_Class,
+  /// \brief The "enum" keyword.
+  TTK_Enum
+};
+
+/// \brief The elaboration keyword that precedes a qualified type name or
+/// introduces an elaborated-type-specifier.
+enum ElaboratedTypeKeyword {
+  /// \brief The "struct" keyword introduces the elaborated-type-specifier.
+  ETK_Struct,
+  /// \brief The "__interface" keyword introduces the elaborated-type-specifier.
+  ETK_Interface,
+  /// \brief The "union" keyword introduces the elaborated-type-specifier.
+  ETK_Union,
+  /// \brief The "class" keyword introduces the elaborated-type-specifier.
+  ETK_Class,
+  /// \brief The "enum" keyword introduces the elaborated-type-specifier.
+  ETK_Enum,
+  /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+  /// \c typename T::type.
+  ETK_Typename,
+  /// \brief No keyword precedes the qualified type name.
+  ETK_None
+};
+
+/// A helper class for Type nodes having an ElaboratedTypeKeyword.
+/// The keyword in stored in the free bits of the base class.
+/// Also provides a few static helpers for converting and printing
+/// elaborated type keyword and tag type kind enumerations.
+class TypeWithKeyword : public Type {
+protected:
+  TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+                  QualType Canonical, bool Dependent,
+                  bool InstantiationDependent, bool VariablyModified,
+                  bool ContainsUnexpandedParameterPack)
+  : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
+         ContainsUnexpandedParameterPack) {
+    TypeWithKeywordBits.Keyword = Keyword;
+  }
+
+public:
+  ElaboratedTypeKeyword getKeyword() const {
+    return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
+  }
+
+  /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into an elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+  /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
+  /// into a tag type kind.  It is an error to provide a type specifier
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+
+  /// getKeywordForTagDeclKind - Converts a TagTypeKind into an
+  /// elaborated type keyword.
+  static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+  /// getTagTypeKindForKeyword - Converts an elaborated type keyword into
+  // a TagTypeKind. It is an error to provide an elaborated type keyword
+  /// which *isn't* a tag kind here.
+  static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
+
+  static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
+
+  static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
+
+  static StringRef getTagTypeKindName(TagTypeKind Kind) {
+    return getKeywordName(getKeywordForTagTypeKind(Kind));
+  }
+
+  class CannotCastToThisType {};
+  static CannotCastToThisType classof(const Type *);
+};
+
+/// \brief Represents a type that was referred to using an elaborated type
+/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
+/// or both.
+///
+/// This type is used to keep track of a type name as written in the
+/// source code, including tag keywords and any nested-name-specifiers.
+/// The type itself is always "sugar", used to express what was written
+/// in the source code but containing no additional semantic information.
+class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The type that this qualified name refers to.
+  QualType NamedType;
+
+  ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+                 QualType NamedType, QualType CanonType)
+    : TypeWithKeyword(Keyword, Elaborated, CanonType,
+                      NamedType->isDependentType(),
+                      NamedType->isInstantiationDependentType(),
+                      NamedType->isVariablyModifiedType(),
+                      NamedType->containsUnexpandedParameterPack()),
+      NNS(NNS), NamedType(NamedType) {
+    assert(!(Keyword == ETK_None && NNS == nullptr) &&
+           "ElaboratedType cannot have elaborated type keyword "
+           "and name qualifier both null.");
+  }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  ~ElaboratedType();
+
+  /// \brief Retrieve the qualification on this type.
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+
+  /// \brief Retrieve the type named by the qualified-id.
+  QualType getNamedType() const { return NamedType; }
+
+  /// \brief Remove a single level of sugar.
+  QualType desugar() const { return getNamedType(); }
+
+  /// \brief Returns whether this type directly provides sugar.
+  bool isSugared() const { return true; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getKeyword(), NNS, NamedType);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *NNS, QualType NamedType) {
+    ID.AddInteger(Keyword);
+    ID.AddPointer(NNS);
+    NamedType.Profile(ID);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Elaborated;
+  }
+};
+
+/// \brief Represents a qualified type name for which the type name is
+/// dependent.
+///
+/// DependentNameType represents a class of dependent types that involve a
+/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
+/// name of a type. The DependentNameType may start with a "typename" (for a
+/// typename-specifier), "class", "struct", "union", or "enum" (for a
+/// dependent elaborated-type-specifier), or nothing (in contexts where we
+/// know that we must be referring to a type, e.g., in a base class specifier).
+/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
+/// mode, this type is used with non-dependent names to delay name lookup until
+/// instantiation.
+class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
+
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The type that this typename specifier refers to.
+  const IdentifierInfo *Name;
+
+  DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+                    const IdentifierInfo *Name, QualType CanonType)
+    : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
+                      /*InstantiationDependent=*/true,
+                      /*VariablyModified=*/false,
+                      NNS->containsUnexpandedParameterPack()),
+      NNS(NNS), Name(Name) {}
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Retrieve the qualification on this type.
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+
+  /// \brief Retrieve the type named by the typename specifier as an
+  /// identifier.
+  ///
+  /// This routine will return a non-NULL identifier pointer when the
+  /// form of the original typename was terminated by an identifier,
+  /// e.g., "typename T::type".
+  const IdentifierInfo *getIdentifier() const {
+    return Name;
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getKeyword(), NNS, Name);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
+    ID.AddInteger(Keyword);
+    ID.AddPointer(NNS);
+    ID.AddPointer(Name);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentName;
+  }
+};
+
+/// DependentTemplateSpecializationType - Represents a template
+/// specialization type whose template cannot be resolved, e.g.
+///   A<T>::template B<T>
+class DependentTemplateSpecializationType :
+  public TypeWithKeyword, public llvm::FoldingSetNode {
+
+  /// \brief The nested name specifier containing the qualifier.
+  NestedNameSpecifier *NNS;
+
+  /// \brief The identifier of the template.
+  const IdentifierInfo *Name;
+
+  /// \brief - The number of template arguments named in this class
+  /// template specialization.
+  unsigned NumArgs;
+
+  const TemplateArgument *getArgBuffer() const {
+    return reinterpret_cast<const TemplateArgument*>(this+1);
+  }
+  TemplateArgument *getArgBuffer() {
+    return reinterpret_cast<TemplateArgument*>(this+1);
+  }
+
+  DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+                                      NestedNameSpecifier *NNS,
+                                      const IdentifierInfo *Name,
+                                      unsigned NumArgs,
+                                      const TemplateArgument *Args,
+                                      QualType Canon);
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  NestedNameSpecifier *getQualifier() const { return NNS; }
+  const IdentifierInfo *getIdentifier() const { return Name; }
+
+  /// \brief Retrieve the template arguments.
+  const TemplateArgument *getArgs() const {
+    return getArgBuffer();
+  }
+
+  /// \brief Retrieve the number of template arguments.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+  typedef const TemplateArgument * iterator;
+  iterator begin() const { return getArgs(); }
+  iterator end() const; // inline in TemplateBase.h
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
+    Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const ASTContext &Context,
+                      ElaboratedTypeKeyword Keyword,
+                      NestedNameSpecifier *Qualifier,
+                      const IdentifierInfo *Name,
+                      unsigned NumArgs,
+                      const TemplateArgument *Args);
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == DependentTemplateSpecialization;
+  }
+};
+
+/// \brief Represents a pack expansion of types.
+///
+/// Pack expansions are part of C++0x variadic templates. A pack
+/// expansion contains a pattern, which itself contains one or more
+/// "unexpanded" parameter packs. When instantiated, a pack expansion
+/// produces a series of types, each instantiated from the pattern of
+/// the expansion, where the Ith instantiation of the pattern uses the
+/// Ith arguments bound to each of the unexpanded parameter packs. The
+/// pack expansion is considered to "expand" these unexpanded
+/// parameter packs.
+///
+/// \code
+/// template<typename ...Types> struct tuple;
+///
+/// template<typename ...Types>
+/// struct tuple_of_references {
+///   typedef tuple<Types&...> type;
+/// };
+/// \endcode
+///
+/// Here, the pack expansion \c Types&... is represented via a
+/// PackExpansionType whose pattern is Types&.
+class PackExpansionType : public Type, public llvm::FoldingSetNode {
+  /// \brief The pattern of the pack expansion.
+  QualType Pattern;
+
+  /// \brief The number of expansions that this pack expansion will
+  /// generate when substituted (+1), or indicates that
+  ///
+  /// This field will only have a non-zero value when some of the parameter
+  /// packs that occur within the pattern have been substituted but others have
+  /// not.
+  unsigned NumExpansions;
+
+  PackExpansionType(QualType Pattern, QualType Canon,
+                    Optional<unsigned> NumExpansions)
+    : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
+           /*InstantiationDependent=*/true,
+           /*VariablyModified=*/Pattern->isVariablyModifiedType(),
+           /*ContainsUnexpandedParameterPack=*/false),
+      Pattern(Pattern),
+      NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
+
+  friend class ASTContext;  // ASTContext creates these
+
+public:
+  /// \brief Retrieve the pattern of this pack expansion, which is the
+  /// type that will be repeatedly instantiated when instantiating the
+  /// pack expansion itself.
+  QualType getPattern() const { return Pattern; }
+
+  /// \brief Retrieve the number of expansions that this pack expansion will
+  /// generate, if known.
+  Optional<unsigned> getNumExpansions() const {
+    if (NumExpansions)
+      return NumExpansions - 1;
+
+    return None;
+  }
+
+  bool isSugared() const { return !Pattern->isDependentType(); }
+  QualType desugar() const { return isSugared() ? Pattern : QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPattern(), getNumExpansions());
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
+                      Optional<unsigned> NumExpansions) {
+    ID.AddPointer(Pattern.getAsOpaquePtr());
+    ID.AddBoolean(NumExpansions.hasValue());
+    if (NumExpansions)
+      ID.AddInteger(*NumExpansions);
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == PackExpansion;
+  }
+};
+
+/// ObjCObjectType - Represents a class type in Objective C.
+/// Every Objective C type is a combination of a base type and a
+/// list of protocols.
+///
+/// Given the following declarations:
+/// \code
+///   \@class C;
+///   \@protocol P;
+/// \endcode
+///
+/// 'C' is an ObjCInterfaceType C.  It is sugar for an ObjCObjectType
+/// with base C and no protocols.
+///
+/// 'C<P>' is an ObjCObjectType with base C and protocol list [P].
+///
+/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose
+/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
+/// and no protocols.
+///
+/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
+/// with base BuiltinType::ObjCIdType and protocol list [P].  Eventually
+/// this should get its own sugar class to better represent the source.
+class ObjCObjectType : public Type {
+  // ObjCObjectType.NumProtocols - the number of protocols stored
+  // after the ObjCObjectPointerType node.
+  //
+  // These protocols are those written directly on the type.  If
+  // protocol qualifiers ever become additive, the iterators will need
+  // to get kindof complicated.
+  //
+  // In the canonical object type, these are sorted alphabetically
+  // and uniqued.
+
+  /// Either a BuiltinType or an InterfaceType or sugar for either.
+  QualType BaseType;
+
+  ObjCProtocolDecl * const *getProtocolStorage() const {
+    return const_cast<ObjCObjectType*>(this)->getProtocolStorage();
+  }
+
+  ObjCProtocolDecl **getProtocolStorage();
+
+protected:
+  ObjCObjectType(QualType Canonical, QualType Base,
+                 ObjCProtocolDecl * const *Protocols, unsigned NumProtocols);
+
+  enum Nonce_ObjCInterface { Nonce_ObjCInterface };
+  ObjCObjectType(enum Nonce_ObjCInterface)
+        : Type(ObjCInterface, QualType(), false, false, false, false),
+      BaseType(QualType(this_(), 0)) {
+    ObjCObjectTypeBits.NumProtocols = 0;
+  }
+
+public:
+  /// getBaseType - Gets the base type of this object type.  This is
+  /// always (possibly sugar for) one of:
+  ///  - the 'id' builtin type (as opposed to the 'id' type visible to the
+  ///    user, which is a typedef for an ObjCObjectPointerType)
+  ///  - the 'Class' builtin type (same caveat)
+  ///  - an ObjCObjectType (currently always an ObjCInterfaceType)
+  QualType getBaseType() const { return BaseType; }
+
+  bool isObjCId() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
+  }
+  bool isObjCClass() const {
+    return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
+  }
+  bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
+  bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
+  bool isObjCUnqualifiedIdOrClass() const {
+    if (!qual_empty()) return false;
+    if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
+      return T->getKind() == BuiltinType::ObjCId ||
+             T->getKind() == BuiltinType::ObjCClass;
+    return false;
+  }
+  bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
+  bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
+
+  /// Gets the interface declaration for this object type, if the base type
+  /// really is an interface.
+  ObjCInterfaceDecl *getInterface() const;
+
+  typedef ObjCProtocolDecl * const *qual_iterator;
+  typedef llvm::iterator_range<qual_iterator> qual_range;
+
+  qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
+  qual_iterator qual_begin() const { return getProtocolStorage(); }
+  qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
+
+  bool qual_empty() const { return getNumProtocols() == 0; }
+
+  /// getNumProtocols - Return the number of qualifying protocols in this
+  /// interface type, or 0 if there are none.
+  unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; }
+
+  /// \brief Fetch a protocol by index.
+  ObjCProtocolDecl *getProtocol(unsigned I) const {
+    assert(I < getNumProtocols() && "Out-of-range protocol access");
+    return qual_begin()[I];
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCObject ||
+           T->getTypeClass() == ObjCInterface;
+  }
+};
+
+/// ObjCObjectTypeImpl - A class providing a concrete implementation
+/// of ObjCObjectType, so as to not increase the footprint of
+/// ObjCInterfaceType.  Code outside of ASTContext and the core type
+/// system should not reference this type.
+class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
+  friend class ASTContext;
+
+  // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
+  // will need to be modified.
+
+  ObjCObjectTypeImpl(QualType Canonical, QualType Base,
+                     ObjCProtocolDecl * const *Protocols,
+                     unsigned NumProtocols)
+    : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {}
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID);
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      QualType Base,
+                      ObjCProtocolDecl *const *protocols,
+                      unsigned NumProtocols);
+};
+
+inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() {
+  return reinterpret_cast<ObjCProtocolDecl**>(
+            static_cast<ObjCObjectTypeImpl*>(this) + 1);
+}
+
+/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
+/// object oriented design.  They basically correspond to C++ classes.  There
+/// are two kinds of interface types, normal interfaces like "NSString" and
+/// qualified interfaces, which are qualified with a protocol list like
+/// "NSString<NSCopyable, NSAmazing>".
+///
+/// ObjCInterfaceType guarantees the following properties when considered
+/// as a subtype of its superclass, ObjCObjectType:
+///   - There are no protocol qualifiers.  To reinforce this, code which
+///     tries to invoke the protocol methods via an ObjCInterfaceType will
+///     fail to compile.
+///   - It is its own base type.  That is, if T is an ObjCInterfaceType*,
+///     T->getBaseType() == QualType(T, 0).
+class ObjCInterfaceType : public ObjCObjectType {
+  mutable ObjCInterfaceDecl *Decl;
+
+  ObjCInterfaceType(const ObjCInterfaceDecl *D)
+    : ObjCObjectType(Nonce_ObjCInterface),
+      Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
+  friend class ASTContext;  // ASTContext creates these.
+  friend class ASTReader;
+  friend class ObjCInterfaceDecl;
+
+public:
+  /// getDecl - Get the declaration of this interface.
+  ObjCInterfaceDecl *getDecl() const { return Decl; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCInterface;
+  }
+
+  // Nonsense to "hide" certain members of ObjCObjectType within this
+  // class.  People asking for protocols on an ObjCInterfaceType are
+  // not going to get what they want: ObjCInterfaceTypes are
+  // guaranteed to have no protocols.
+  enum {
+    qual_iterator,
+    qual_begin,
+    qual_end,
+    getNumProtocols,
+    getProtocol
+  };
+};
+
+inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
+  if (const ObjCInterfaceType *T =
+        getBaseType()->getAs<ObjCInterfaceType>())
+    return T->getDecl();
+  return nullptr;
+}
+
+/// ObjCObjectPointerType - Used to represent a pointer to an
+/// Objective C object.  These are constructed from pointer
+/// declarators when the pointee type is an ObjCObjectType (or sugar
+/// for one).  In addition, the 'id' and 'Class' types are typedefs
+/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>'
+/// are translated into these.
+///
+/// Pointers to pointers to Objective C objects are still PointerTypes;
+/// only the first level of pointer gets it own type implementation.
+class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
+  QualType PointeeType;
+
+  ObjCObjectPointerType(QualType Canonical, QualType Pointee)
+    : Type(ObjCObjectPointer, Canonical, false, false, false, false),
+      PointeeType(Pointee) {}
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  /// getPointeeType - Gets the type pointed to by this ObjC pointer.
+  /// The result will always be an ObjCObjectType or sugar thereof.
+  QualType getPointeeType() const { return PointeeType; }
+
+  /// getObjCObjectType - Gets the type pointed to by this ObjC
+  /// pointer.  This method always returns non-null.
+  ///
+  /// This method is equivalent to getPointeeType() except that
+  /// it discards any typedefs (or other sugar) between this
+  /// type and the "outermost" object type.  So for:
+  /// \code
+  ///   \@class A; \@protocol P; \@protocol Q;
+  ///   typedef A<P> AP;
+  ///   typedef A A1;
+  ///   typedef A1<P> A1P;
+  ///   typedef A1P<Q> A1PQ;
+  /// \endcode
+  /// For 'A*', getObjectType() will return 'A'.
+  /// For 'A<P>*', getObjectType() will return 'A<P>'.
+  /// For 'AP*', getObjectType() will return 'A<P>'.
+  /// For 'A1*', getObjectType() will return 'A'.
+  /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
+  /// For 'A1P*', getObjectType() will return 'A1<P>'.
+  /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
+  ///   adding protocols to a protocol-qualified base discards the
+  ///   old qualifiers (for now).  But if it didn't, getObjectType()
+  ///   would return 'A1P<Q>' (and we'd have to make iterating over
+  ///   qualifiers more complicated).
+  const ObjCObjectType *getObjectType() const {
+    return PointeeType->castAs<ObjCObjectType>();
+  }
+
+  /// getInterfaceType - If this pointer points to an Objective C
+  /// \@interface type, gets the type for that interface.  Any protocol
+  /// qualifiers on the interface are ignored.
+  ///
+  /// \return null if the base type for this pointer is 'id' or 'Class'
+  const ObjCInterfaceType *getInterfaceType() const {
+    return getObjectType()->getBaseType()->getAs<ObjCInterfaceType>();
+  }
+
+  /// getInterfaceDecl - If this pointer points to an Objective \@interface
+  /// type, gets the declaration for that interface.
+  ///
+  /// \return null if the base type for this pointer is 'id' or 'Class'
+  ObjCInterfaceDecl *getInterfaceDecl() const {
+    return getObjectType()->getInterface();
+  }
+
+  /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if
+  /// its object type is the primitive 'id' type with no protocols.
+  bool isObjCIdType() const {
+    return getObjectType()->isObjCUnqualifiedId();
+  }
+
+  /// isObjCClassType - True if this is equivalent to the 'Class' type,
+  /// i.e. if its object tive is the primitive 'Class' type with no protocols.
+  bool isObjCClassType() const {
+    return getObjectType()->isObjCUnqualifiedClass();
+  }
+
+  /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
+  /// non-empty set of protocols.
+  bool isObjCQualifiedIdType() const {
+    return getObjectType()->isObjCQualifiedId();
+  }
+
+  /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for
+  /// some non-empty set of protocols.
+  bool isObjCQualifiedClassType() const {
+    return getObjectType()->isObjCQualifiedClass();
+  }
+
+  /// An iterator over the qualifiers on the object type.  Provided
+  /// for convenience.  This will always iterate over the full set of
+  /// protocols on a type, not just those provided directly.
+  typedef ObjCObjectType::qual_iterator qual_iterator;
+  typedef llvm::iterator_range<qual_iterator> qual_range;
+
+  qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
+  qual_iterator qual_begin() const {
+    return getObjectType()->qual_begin();
+  }
+  qual_iterator qual_end() const {
+    return getObjectType()->qual_end();
+  }
+  bool qual_empty() const { return getObjectType()->qual_empty(); }
+
+  /// getNumProtocols - Return the number of qualifying protocols on
+  /// the object type.
+  unsigned getNumProtocols() const {
+    return getObjectType()->getNumProtocols();
+  }
+
+  /// \brief Retrieve a qualifying protocol by index on the object
+  /// type.
+  ObjCProtocolDecl *getProtocol(unsigned I) const {
+    return getObjectType()->getProtocol(I);
+  }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getPointeeType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+    ID.AddPointer(T.getAsOpaquePtr());
+  }
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == ObjCObjectPointer;
+  }
+};
+
+class AtomicType : public Type, public llvm::FoldingSetNode {
+  QualType ValueType;
+
+  AtomicType(QualType ValTy, QualType Canonical)
+    : Type(Atomic, Canonical, ValTy->isDependentType(),
+           ValTy->isInstantiationDependentType(),
+           ValTy->isVariablyModifiedType(),
+           ValTy->containsUnexpandedParameterPack()),
+      ValueType(ValTy) {}
+  friend class ASTContext;  // ASTContext creates these.
+
+  public:
+  /// getValueType - Gets the type contained by this atomic type, i.e.
+  /// the type returned by performing an atomic load of this atomic type.
+  QualType getValueType() const { return ValueType; }
+
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, getValueType());
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
+    ID.AddPointer(T.getAsOpaquePtr());
+  }
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Atomic;
+  }
+};
+
+/// A qualifier set is used to build a set of qualifiers.
+class QualifierCollector : public Qualifiers {
+public:
+  QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
+
+  /// Collect any qualifiers on the given type and return an
+  /// unqualified type.  The qualifiers are assumed to be consistent
+  /// with those already in the type.
+  const Type *strip(QualType type) {
+    addFastQualifiers(type.getLocalFastQualifiers());
+    if (!type.hasLocalNonFastQualifiers())
+      return type.getTypePtrUnsafe();
+
+    const ExtQuals *extQuals = type.getExtQualsUnsafe();
+    addConsistentQualifiers(extQuals->getQualifiers());
+    return extQuals->getBaseType();
+  }
+
+  /// Apply the collected qualifiers to the given type.
+  QualType apply(const ASTContext &Context, QualType QT) const;
+
+  /// Apply the collected qualifiers to the given type.
+  QualType apply(const ASTContext &Context, const Type* T) const;
+};
+
+
+// Inline function definitions.
+
+inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
+  SplitQualType desugar =
+    Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
+  desugar.Quals.addConsistentQualifiers(Quals);
+  return desugar;
+}
+
+inline const Type *QualType::getTypePtr() const {
+  return getCommonPtr()->BaseType;
+}
+
+inline const Type *QualType::getTypePtrOrNull() const {
+  return (isNull() ? nullptr : getCommonPtr()->BaseType);
+}
+
+inline SplitQualType QualType::split() const {
+  if (!hasLocalNonFastQualifiers())
+    return SplitQualType(getTypePtrUnsafe(),
+                         Qualifiers::fromFastMask(getLocalFastQualifiers()));
+
+  const ExtQuals *eq = getExtQualsUnsafe();
+  Qualifiers qs = eq->getQualifiers();
+  qs.addFastQualifiers(getLocalFastQualifiers());
+  return SplitQualType(eq->getBaseType(), qs);
+}
+
+inline Qualifiers QualType::getLocalQualifiers() const {
+  Qualifiers Quals;
+  if (hasLocalNonFastQualifiers())
+    Quals = getExtQualsUnsafe()->getQualifiers();
+  Quals.addFastQualifiers(getLocalFastQualifiers());
+  return Quals;
+}
+
+inline Qualifiers QualType::getQualifiers() const {
+  Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
+  quals.addFastQualifiers(getLocalFastQualifiers());
+  return quals;
+}
+
+inline unsigned QualType::getCVRQualifiers() const {
+  unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
+  cvr |= getLocalCVRQualifiers();
+  return cvr;
+}
+
+inline QualType QualType::getCanonicalType() const {
+  QualType canon = getCommonPtr()->CanonicalType;
+  return canon.withFastQualifiers(getLocalFastQualifiers());
+}
+
+inline bool QualType::isCanonical() const {
+  return getTypePtr()->isCanonicalUnqualified();
+}
+
+inline bool QualType::isCanonicalAsParam() const {
+  if (!isCanonical()) return false;
+  if (hasLocalQualifiers()) return false;
+
+  const Type *T = getTypePtr();
+  if (T->isVariablyModifiedType() && T->hasSizedVLAType())
+    return false;
+
+  return !isa<FunctionType>(T) && !isa<ArrayType>(T);
+}
+
+inline bool QualType::isConstQualified() const {
+  return isLocalConstQualified() ||
+         getCommonPtr()->CanonicalType.isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+  return isLocalRestrictQualified() ||
+         getCommonPtr()->CanonicalType.isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+  return isLocalVolatileQualified() ||
+         getCommonPtr()->CanonicalType.isLocalVolatileQualified();
+}
+
+inline bool QualType::hasQualifiers() const {
+  return hasLocalQualifiers() ||
+         getCommonPtr()->CanonicalType.hasLocalQualifiers();
+}
+
+inline QualType QualType::getUnqualifiedType() const {
+  if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
+    return QualType(getTypePtr(), 0);
+
+  return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
+}
+  
+inline SplitQualType QualType::getSplitUnqualifiedType() const {
+  if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
+    return split();
+
+  return getSplitUnqualifiedTypeImpl(*this);
+}
+
+inline void QualType::removeLocalConst() {
+  removeLocalFastQualifiers(Qualifiers::Const);
+}
+
+inline void QualType::removeLocalRestrict() {
+  removeLocalFastQualifiers(Qualifiers::Restrict);
+}
+
+inline void QualType::removeLocalVolatile() {
+  removeLocalFastQualifiers(Qualifiers::Volatile);
+}
+
+inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
+  assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
+  assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask);
+
+  // Fast path: we don't need to touch the slow qualifiers.
+  removeLocalFastQualifiers(Mask);
+}
+
+/// getAddressSpace - Return the address space of this type.
+inline unsigned QualType::getAddressSpace() const {
+  return getQualifiers().getAddressSpace();
+}
+  
+/// getObjCGCAttr - Return the gc attribute of this type.
+inline Qualifiers::GC QualType::getObjCGCAttr() const {
+  return getQualifiers().getObjCGCAttr();
+}
+
+inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
+  if (const PointerType *PT = t.getAs<PointerType>()) {
+    if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
+      return FT->getExtInfo();
+  } else if (const FunctionType *FT = t.getAs<FunctionType>())
+    return FT->getExtInfo();
+
+  return FunctionType::ExtInfo();
+}
+
+inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
+  return getFunctionExtInfo(*t);
+}
+
+/// isMoreQualifiedThan - Determine whether this type is more
+/// qualified than the Other type. For example, "const volatile int"
+/// is more qualified than "const int", "volatile int", and
+/// "int". However, it is not more qualified than "const volatile
+/// int".
+inline bool QualType::isMoreQualifiedThan(QualType other) const {
+  Qualifiers myQuals = getQualifiers();
+  Qualifiers otherQuals = other.getQualifiers();
+  return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals));
+}
+
+/// isAtLeastAsQualifiedAs - Determine whether this type is at last
+/// as qualified as the Other type. For example, "const volatile
+/// int" is at least as qualified as "const int", "volatile int",
+/// "int", and "const volatile int".
+inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
+  return getQualifiers().compatiblyIncludes(other.getQualifiers());
+}
+
+/// getNonReferenceType - If Type is a reference type (e.g., const
+/// int&), returns the type that the reference refers to ("const
+/// int"). Otherwise, returns the type itself. This routine is used
+/// throughout Sema to implement C++ 5p6:
+///
+///   If an expression initially has the type "reference to T" (8.3.2,
+///   8.5.3), the type is adjusted to "T" prior to any further
+///   analysis, the expression designates the object or function
+///   denoted by the reference, and the expression is an lvalue.
+inline QualType QualType::getNonReferenceType() const {
+  if (const ReferenceType *RefType = (*this)->getAs<ReferenceType>())
+    return RefType->getPointeeType();
+  else
+    return *this;
+}
+
+inline bool QualType::isCForbiddenLValueType() const {
+  return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
+          getTypePtr()->isFunctionType());
+}
+
+/// \brief Tests whether the type is categorized as a fundamental type.
+///
+/// \returns True for types specified in C++0x [basic.fundamental].
+inline bool Type::isFundamentalType() const {
+  return isVoidType() ||
+         // FIXME: It's really annoying that we don't have an
+         // 'isArithmeticType()' which agrees with the standard definition.
+         (isArithmeticType() && !isEnumeralType());
+}
+
+/// \brief Tests whether the type is categorized as a compound type.
+///
+/// \returns True for types specified in C++0x [basic.compound].
+inline bool Type::isCompoundType() const {
+  // C++0x [basic.compound]p1:
+  //   Compound types can be constructed in the following ways:
+  //    -- arrays of objects of a given type [...];
+  return isArrayType() ||
+  //    -- functions, which have parameters of given types [...];
+         isFunctionType() ||
+  //    -- pointers to void or objects or functions [...];
+         isPointerType() ||
+  //    -- references to objects or functions of a given type. [...]
+         isReferenceType() ||
+  //    -- classes containing a sequence of objects of various types, [...];
+         isRecordType() ||
+  //    -- unions, which are classes capable of containing objects of different
+  //               types at different times;
+         isUnionType() ||
+  //    -- enumerations, which comprise a set of named constant values. [...];
+         isEnumeralType() ||
+  //    -- pointers to non-static class members, [...].
+         isMemberPointerType();
+}
+
+inline bool Type::isFunctionType() const {
+  return isa<FunctionType>(CanonicalType);
+}
+inline bool Type::isPointerType() const {
+  return isa<PointerType>(CanonicalType);
+}
+inline bool Type::isAnyPointerType() const {
+  return isPointerType() || isObjCObjectPointerType();
+}
+inline bool Type::isBlockPointerType() const {
+  return isa<BlockPointerType>(CanonicalType);
+}
+inline bool Type::isReferenceType() const {
+  return isa<ReferenceType>(CanonicalType);
+}
+inline bool Type::isLValueReferenceType() const {
+  return isa<LValueReferenceType>(CanonicalType);
+}
+inline bool Type::isRValueReferenceType() const {
+  return isa<RValueReferenceType>(CanonicalType);
+}
+inline bool Type::isFunctionPointerType() const {
+  if (const PointerType *T = getAs<PointerType>())
+    return T->getPointeeType()->isFunctionType();
+  else
+    return false;
+}
+inline bool Type::isMemberPointerType() const {
+  return isa<MemberPointerType>(CanonicalType);
+}
+inline bool Type::isMemberFunctionPointerType() const {
+  if (const MemberPointerType* T = getAs<MemberPointerType>())
+    return T->isMemberFunctionPointer();
+  else
+    return false;
+}
+inline bool Type::isMemberDataPointerType() const {
+  if (const MemberPointerType* T = getAs<MemberPointerType>())
+    return T->isMemberDataPointer();
+  else
+    return false;
+}
+inline bool Type::isArrayType() const {
+  return isa<ArrayType>(CanonicalType);
+}
+inline bool Type::isConstantArrayType() const {
+  return isa<ConstantArrayType>(CanonicalType);
+}
+inline bool Type::isIncompleteArrayType() const {
+  return isa<IncompleteArrayType>(CanonicalType);
+}
+inline bool Type::isVariableArrayType() const {
+  return isa<VariableArrayType>(CanonicalType);
+}
+inline bool Type::isDependentSizedArrayType() const {
+  return isa<DependentSizedArrayType>(CanonicalType);
+}
+inline bool Type::isBuiltinType() const {
+  return isa<BuiltinType>(CanonicalType);
+}
+inline bool Type::isRecordType() const {
+  return isa<RecordType>(CanonicalType);
+}
+inline bool Type::isEnumeralType() const {
+  return isa<EnumType>(CanonicalType);
+}
+inline bool Type::isAnyComplexType() const {
+  return isa<ComplexType>(CanonicalType);
+}
+inline bool Type::isVectorType() const {
+  return isa<VectorType>(CanonicalType);
+}
+inline bool Type::isExtVectorType() const {
+  return isa<ExtVectorType>(CanonicalType);
+}
+inline bool Type::isObjCObjectPointerType() const {
+  return isa<ObjCObjectPointerType>(CanonicalType);
+}
+inline bool Type::isObjCObjectType() const {
+  return isa<ObjCObjectType>(CanonicalType);
+}
+inline bool Type::isObjCObjectOrInterfaceType() const {
+  return isa<ObjCInterfaceType>(CanonicalType) ||
+    isa<ObjCObjectType>(CanonicalType);
+}
+inline bool Type::isAtomicType() const {
+  return isa<AtomicType>(CanonicalType);
+}
+
+inline bool Type::isObjCQualifiedIdType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCQualifiedIdType();
+  return false;
+}
+inline bool Type::isObjCQualifiedClassType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCQualifiedClassType();
+  return false;
+}
+inline bool Type::isObjCIdType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCIdType();
+  return false;
+}
+inline bool Type::isObjCClassType() const {
+  if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
+    return OPT->isObjCClassType();
+  return false;
+}
+inline bool Type::isObjCSelType() const {
+  if (const PointerType *OPT = getAs<PointerType>())
+    return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
+  return false;
+}
+inline bool Type::isObjCBuiltinType() const {
+  return isObjCIdType() || isObjCClassType() || isObjCSelType();
+}
+
+inline bool Type::isImage1dT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage1d);
+}
+
+inline bool Type::isImage1dArrayT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage1dArray);
+}
+
+inline bool Type::isImage1dBufferT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer);
+}
+
+inline bool Type::isImage2dT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage2d);
+}
+
+inline bool Type::isImage2dArrayT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage2dArray);
+}
+
+inline bool Type::isImage3dT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLImage3d);
+}
+
+inline bool Type::isSamplerT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLSampler);
+}
+
+inline bool Type::isEventT() const {
+  return isSpecificBuiltinType(BuiltinType::OCLEvent);
+}
+
+inline bool Type::isImageType() const {
+  return isImage3dT() ||
+         isImage2dT() || isImage2dArrayT() ||
+         isImage1dT() || isImage1dArrayT() || isImage1dBufferT();
+}
+
+inline bool Type::isOpenCLSpecificType() const {
+  return isSamplerT() || isEventT() || isImageType();
+}
+
+inline bool Type::isTemplateTypeParmType() const {
+  return isa<TemplateTypeParmType>(CanonicalType);
+}
+
+inline bool Type::isSpecificBuiltinType(unsigned K) const {
+  if (const BuiltinType *BT = getAs<BuiltinType>())
+    if (BT->getKind() == (BuiltinType::Kind) K)
+      return true;
+  return false;
+}
+
+inline bool Type::isPlaceholderType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    return BT->isPlaceholderType();
+  return false;
+}
+
+inline const BuiltinType *Type::getAsPlaceholderType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    if (BT->isPlaceholderType())
+      return BT;
+  return nullptr;
+}
+
+inline bool Type::isSpecificPlaceholderType(unsigned K) const {
+  assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K));
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    return (BT->getKind() == (BuiltinType::Kind) K);
+  return false;
+}
+
+inline bool Type::isNonOverloadPlaceholderType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    return BT->isNonOverloadPlaceholderType();
+  return false;
+}
+
+inline bool Type::isVoidType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Void;
+  return false;
+}
+
+inline bool Type::isHalfType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Half;
+  // FIXME: Should we allow complex __fp16? Probably not.
+  return false;
+}
+
+inline bool Type::isNullPtrType() const {
+  if (const BuiltinType *BT = getAs<BuiltinType>())
+    return BT->getKind() == BuiltinType::NullPtr;
+  return false;
+}
+
+extern bool IsEnumDeclComplete(EnumDecl *);
+extern bool IsEnumDeclScoped(EnumDecl *);
+
+inline bool Type::isIntegerType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::Int128;
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
+    // Incomplete enum types are not treated as integer types.
+    // FIXME: In C++, enum types are never integer types.
+    return IsEnumDeclComplete(ET->getDecl()) &&
+      !IsEnumDeclScoped(ET->getDecl());
+  }
+  return false;
+}
+
+inline bool Type::isScalarType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() > BuiltinType::Void &&
+           BT->getKind() <= BuiltinType::NullPtr;
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+    // Enums are scalar types, but only if they are defined.  Incomplete enums
+    // are not treated as scalar types.
+    return IsEnumDeclComplete(ET->getDecl());
+  return isa<PointerType>(CanonicalType) ||
+         isa<BlockPointerType>(CanonicalType) ||
+         isa<MemberPointerType>(CanonicalType) ||
+         isa<ComplexType>(CanonicalType) ||
+         isa<ObjCObjectPointerType>(CanonicalType);
+}
+
+inline bool Type::isIntegralOrEnumerationType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::Int128;
+
+  // Check for a complete enum type; incomplete enum types are not properly an
+  // enumeration type in the sense required here.
+  if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
+    return IsEnumDeclComplete(ET->getDecl());
+
+  return false;  
+}
+
+inline bool Type::isBooleanType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return BT->getKind() == BuiltinType::Bool;
+  return false;
+}
+
+inline bool Type::isUndeducedType() const {
+  const AutoType *AT = getContainedAutoType();
+  return AT && !AT->isDeduced();
+}
+
+/// \brief Determines whether this is a type for which one can define
+/// an overloaded operator.
+inline bool Type::isOverloadableType() const {
+  return isDependentType() || isRecordType() || isEnumeralType();
+}
+
+/// \brief Determines whether this type can decay to a pointer type.
+inline bool Type::canDecayToPointerType() const {
+  return isFunctionType() || isArrayType();
+}
+
+inline bool Type::hasPointerRepresentation() const {
+  return (isPointerType() || isReferenceType() || isBlockPointerType() ||
+          isObjCObjectPointerType() || isNullPtrType());
+}
+
+inline bool Type::hasObjCPointerRepresentation() const {
+  return isObjCObjectPointerType();
+}
+
+inline const Type *Type::getBaseElementTypeUnsafe() const {
+  const Type *type = this;
+  while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
+    type = arrayType->getElementType().getTypePtr();
+  return type;
+}
+
+/// Insertion operator for diagnostics.  This allows sending QualType's into a
+/// diagnostic with <<.
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           QualType T) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+                  DiagnosticsEngine::ak_qualtype);
+  return DB;
+}
+
+/// Insertion operator for partial diagnostics.  This allows sending QualType's
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           QualType T) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+                  DiagnosticsEngine::ak_qualtype);
+  return PD;
+}
+
+// Helper class template that is used by Type::getAs to ensure that one does
+// not try to look through a qualified type to get to an array type.
+template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
+                                          std::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs {};
+
+template<typename T>
+struct ArrayType_cannot_be_used_with_getAs<T, true>;
+
+// Member-template getAs<specific type>'.
+template <typename T> const T *Type::getAs() const {
+  ArrayType_cannot_be_used_with_getAs<T> at;
+  (void)at;
+
+  // If this is directly a T type, return it.
+  if (const T *Ty = dyn_cast<T>(this))
+    return Ty;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<T>(CanonicalType))
+    return nullptr;
+
+  // If this is a typedef for the type, strip the typedef off without
+  // losing all typedef information.
+  return cast<T>(getUnqualifiedDesugaredType());
+}
+
+inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
+  // If this is directly an array type, return it.
+  if (const ArrayType *arr = dyn_cast<ArrayType>(this))
+    return arr;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<ArrayType>(CanonicalType))
+    return nullptr;
+
+  // If this is a typedef for the type, strip the typedef off without
+  // losing all typedef information.
+  return cast<ArrayType>(getUnqualifiedDesugaredType());
+}
+
+template <typename T> const T *Type::castAs() const {
+  ArrayType_cannot_be_used_with_getAs<T> at;
+  (void) at;
+
+  assert(isa<T>(CanonicalType));
+  if (const T *ty = dyn_cast<T>(this)) return ty;
+  return cast<T>(getUnqualifiedDesugaredType());
+}
+
+inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
+  assert(isa<ArrayType>(CanonicalType));
+  if (const ArrayType *arr = dyn_cast<ArrayType>(this)) return arr;
+  return cast<ArrayType>(getUnqualifiedDesugaredType());
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
new file mode 100644
index 0000000..3648d2a
--- /dev/null
+++ b/include/clang/AST/TypeLoc.h
@@ -0,0 +1,1955 @@
+//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TypeLoc interface and its subclasses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOC_H
+#define LLVM_CLANG_AST_TYPELOC_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+  class ASTContext;
+  class ParmVarDecl;
+  class TypeSourceInfo;
+  class UnqualTypeLoc;
+
+// Predeclare all the type nodes.
+#define ABSTRACT_TYPELOC(Class, Base)
+#define TYPELOC(Class, Base) \
+  class Class##TypeLoc;
+#include "clang/AST/TypeLocNodes.def"
+
+/// \brief Base wrapper for a particular "section" of type source info.
+///
+/// A client should use the TypeLoc subclasses through castAs()/getAs()
+/// in order to get at the actual information.
+class TypeLoc {
+protected:
+  // The correctness of this relies on the property that, for Type *Ty,
+  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
+  const void *Ty;
+  void *Data;
+
+public:
+  /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
+  /// is of the desired type.
+  ///
+  /// \pre T::isKind(*this)
+  template<typename T>
+  T castAs() const {
+    assert(T::isKind(*this));
+    T t;
+    TypeLoc& tl = t;
+    tl = *this;
+    return t;
+  }
+
+  /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+  /// this TypeLoc is not of the desired type.
+  template<typename T>
+  T getAs() const {
+    if (!T::isKind(*this))
+      return T();
+    T t;
+    TypeLoc& tl = t;
+    tl = *this;
+    return t;
+  }
+
+  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
+  /// except it also defines a Qualified enum that corresponds to the
+  /// QualifiedLoc class.
+  enum TypeLocClass {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+    Class = Type::Class,
+#include "clang/AST/TypeNodes.def"
+    Qualified
+  };
+
+  TypeLoc() : Ty(nullptr), Data(nullptr) { }
+  TypeLoc(QualType ty, void *opaqueData)
+    : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
+  TypeLoc(const Type *ty, void *opaqueData)
+    : Ty(ty), Data(opaqueData) { }
+
+  TypeLocClass getTypeLocClass() const {
+    if (getType().hasLocalQualifiers()) return Qualified;
+    return (TypeLocClass) getType()->getTypeClass();
+  }
+
+  bool isNull() const { return !Ty; }
+  LLVM_EXPLICIT operator bool() const { return Ty; }
+
+  /// \brief Returns the size of type source info data block for the given type.
+  static unsigned getFullDataSizeForType(QualType Ty);
+
+  /// \brief Returns the alignment of type source info data block for
+  /// the given type.
+  static unsigned getLocalAlignmentForType(QualType Ty);
+
+  /// \brief Get the type for which this source info wrapper provides
+  /// information.
+  QualType getType() const {
+    return QualType::getFromOpaquePtr(Ty);
+  }
+
+  const Type *getTypePtr() const {
+    return QualType::getFromOpaquePtr(Ty).getTypePtr();
+  }
+
+  /// \brief Get the pointer where source information is stored.
+  void *getOpaqueData() const {
+    return Data;
+  }
+
+  /// \brief Get the begin source location.
+  SourceLocation getBeginLoc() const;
+
+  /// \brief Get the end source location.
+  SourceLocation getEndLoc() const;
+
+  /// \brief Get the full source range.
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(getBeginLoc(), getEndLoc());
+  }
+  SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
+
+  /// \brief Get the local source range.
+  SourceRange getLocalSourceRange() const {
+    return getLocalSourceRangeImpl(*this);
+  }
+
+  /// \brief Returns the size of the type source info data block.
+  unsigned getFullDataSize() const {
+    return getFullDataSizeForType(getType());
+  }
+
+  /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
+  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
+  TypeLoc getNextTypeLoc() const {
+    return getNextTypeLocImpl(*this);
+  }
+
+  /// \brief Skips past any qualifiers, if this is qualified.
+  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
+
+  TypeLoc IgnoreParens() const;
+
+  /// \brief Initializes this to state that every location in this
+  /// type is the given location.
+  ///
+  /// This method exists to provide a simple transition for code that
+  /// relies on location-less types.
+  void initialize(ASTContext &Context, SourceLocation Loc) const {
+    initializeImpl(Context, *this, Loc);
+  }
+
+  /// \brief Initializes this by copying its information from another
+  /// TypeLoc of the same type.
+  void initializeFullCopy(TypeLoc Other) const {
+    assert(getType() == Other.getType());
+    size_t Size = getFullDataSize();
+    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
+  }
+
+  /// \brief Initializes this by copying its information from another
+  /// TypeLoc of the same type.  The given size must be the full data
+  /// size.
+  void initializeFullCopy(TypeLoc Other, unsigned Size) const {
+    assert(getType() == Other.getType());
+    assert(getFullDataSize() == Size);
+    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
+  }
+
+  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
+    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
+  }
+
+  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
+    return !(LHS == RHS);
+  }
+
+private:
+  static bool isKind(const TypeLoc&) {
+    return true;
+  }
+
+  static void initializeImpl(ASTContext &Context, TypeLoc TL,
+                             SourceLocation Loc);
+  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
+  static TypeLoc IgnoreParensImpl(TypeLoc TL);
+  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
+};
+
+/// \brief Return the TypeLoc for a type source info.
+inline TypeLoc TypeSourceInfo::getTypeLoc() const {
+  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
+}
+
+/// \brief Wrapper of type source information for a type with
+/// no direct qualifiers.
+class UnqualTypeLoc : public TypeLoc {
+public:
+  UnqualTypeLoc() {}
+  UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
+
+  const Type *getTypePtr() const {
+    return reinterpret_cast<const Type*>(Ty);
+  }
+
+  TypeLocClass getTypeLocClass() const {
+    return (TypeLocClass) getTypePtr()->getTypeClass();
+  }
+
+private:
+  friend class TypeLoc;
+  static bool isKind(const TypeLoc &TL) {
+    return !TL.getType().hasLocalQualifiers();
+  }
+};
+
+/// \brief Wrapper of type source information for a type with
+/// non-trivial direct qualifiers.
+///
+/// Currently, we intentionally do not provide source location for
+/// type qualifiers.
+class QualifiedTypeLoc : public TypeLoc {
+public:
+  SourceRange getLocalSourceRange() const {
+    return SourceRange();
+  }
+
+  UnqualTypeLoc getUnqualifiedLoc() const {
+    unsigned align =
+        TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
+    uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
+    dataInt = llvm::RoundUpToAlignment(dataInt, align);
+    return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
+  }
+
+  /// Initializes the local data of this type source info block to
+  /// provide no information.
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    // do nothing
+  }
+
+  TypeLoc getNextTypeLoc() const {
+    return getUnqualifiedLoc();
+  }
+
+  /// \brief Returns the size of the type source info data block that is
+  /// specific to this type.
+  unsigned getLocalDataSize() const {
+    // In fact, we don't currently preserve any location information
+    // for qualifiers.
+    return 0;
+  }
+
+  /// \brief Returns the alignment of the type source info data block that is
+  /// specific to this type.
+  unsigned getLocalDataAlignment() const {
+    // We don't preserve any location information.
+    return 1;
+  }
+
+private:
+  friend class TypeLoc;
+  static bool isKind(const TypeLoc &TL) {
+    return TL.getType().hasLocalQualifiers();
+  }
+};
+
+inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
+  if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
+    return Loc.getUnqualifiedLoc();
+  return castAs<UnqualTypeLoc>();
+}
+
+/// A metaprogramming base class for TypeLoc classes which correspond
+/// to a particular Type subclass.  It is accepted for a single
+/// TypeLoc class to correspond to multiple Type classes.
+///
+/// \tparam Base a class from which to derive
+/// \tparam Derived the class deriving from this one
+/// \tparam TypeClass the concrete Type subclass associated with this
+///   location type
+/// \tparam LocalData the structure type of local location data for
+///   this type
+///
+/// TypeLocs with non-constant amounts of local data should override
+/// getExtraLocalDataSize(); getExtraLocalData() will then point to
+/// this extra memory.
+///
+/// TypeLocs with an inner type should define
+///   QualType getInnerType() const
+/// and getInnerTypeLoc() will then point to this inner type's
+/// location data.
+///
+/// A word about hierarchies: this template is not designed to be
+/// derived from multiple times in a hierarchy.  It is also not
+/// designed to be used for classes where subtypes might provide
+/// different amounts of source information.  It should be subclassed
+/// only at the deepest portion of the hierarchy where all children
+/// have identical source information; if that's an abstract type,
+/// then further descendents should inherit from
+/// InheritingConcreteTypeLoc instead.
+template <class Base, class Derived, class TypeClass, class LocalData>
+class ConcreteTypeLoc : public Base {
+
+  const Derived *asDerived() const {
+    return static_cast<const Derived*>(this);
+  }
+
+  friend class TypeLoc;
+  static bool isKind(const TypeLoc &TL) {
+    return !TL.getType().hasLocalQualifiers() &&
+           Derived::classofType(TL.getTypePtr());
+  }
+
+  static bool classofType(const Type *Ty) {
+    return TypeClass::classof(Ty);
+  }
+
+public:
+  unsigned getLocalDataAlignment() const {
+    return std::max(llvm::alignOf<LocalData>(),
+                    asDerived()->getExtraLocalDataAlignment());
+  }
+  unsigned getLocalDataSize() const {
+    unsigned size = sizeof(LocalData);
+    unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
+    size = llvm::RoundUpToAlignment(size, extraAlign);
+    size += asDerived()->getExtraLocalDataSize();
+    return size;
+  }
+
+  TypeLoc getNextTypeLoc() const {
+    return getNextTypeLoc(asDerived()->getInnerType());
+  }
+
+  const TypeClass *getTypePtr() const {
+    return cast<TypeClass>(Base::getTypePtr());
+  }
+
+protected:
+  unsigned getExtraLocalDataSize() const {
+    return 0;
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return 1;
+  }
+
+  LocalData *getLocalData() const {
+    return static_cast<LocalData*>(Base::Data);
+  }
+
+  /// Gets a pointer past the Info structure; useful for classes with
+  /// local data that can't be captured in the Info (e.g. because it's
+  /// of variable size).
+  void *getExtraLocalData() const {
+    unsigned size = sizeof(LocalData);
+    unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
+    size = llvm::RoundUpToAlignment(size, extraAlign);
+    return reinterpret_cast<char*>(Base::Data) + size;
+  }
+
+  void *getNonLocalData() const {
+    uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
+    data += asDerived()->getLocalDataSize();
+    data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
+    return reinterpret_cast<void*>(data);
+  }
+
+  struct HasNoInnerType {};
+  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
+
+  TypeLoc getInnerTypeLoc() const {
+    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
+  }
+
+private:
+  unsigned getInnerTypeSize() const {
+    return getInnerTypeSize(asDerived()->getInnerType());
+  }
+
+  unsigned getInnerTypeSize(HasNoInnerType _) const {
+    return 0;
+  }
+
+  unsigned getInnerTypeSize(QualType _) const {
+    return getInnerTypeLoc().getFullDataSize();
+  }
+
+  unsigned getNextTypeAlign() const {
+    return getNextTypeAlign(asDerived()->getInnerType());
+  }
+
+  unsigned getNextTypeAlign(HasNoInnerType _) const {
+    return 1;
+  }
+
+  unsigned getNextTypeAlign(QualType T) const {
+    return TypeLoc::getLocalAlignmentForType(T);
+  }
+
+  TypeLoc getNextTypeLoc(HasNoInnerType _) const {
+    return TypeLoc();
+  }
+
+  TypeLoc getNextTypeLoc(QualType T) const {
+    return TypeLoc(T, getNonLocalData());
+  }
+};
+
+/// A metaprogramming class designed for concrete subtypes of abstract
+/// types where all subtypes share equivalently-structured source
+/// information.  See the note on ConcreteTypeLoc.
+template <class Base, class Derived, class TypeClass>
+class InheritingConcreteTypeLoc : public Base {
+  friend class TypeLoc;
+  static bool classofType(const Type *Ty) {
+    return TypeClass::classof(Ty);
+  }
+
+  static bool isKind(const TypeLoc &TL) {
+    return !TL.getType().hasLocalQualifiers() &&
+           Derived::classofType(TL.getTypePtr());
+  }
+  static bool isKind(const UnqualTypeLoc &TL) {
+    return Derived::classofType(TL.getTypePtr());
+  }
+
+public:
+  const TypeClass *getTypePtr() const {
+    return cast<TypeClass>(Base::getTypePtr());
+  }
+};
+
+
+struct TypeSpecLocInfo {
+  SourceLocation NameLoc;
+};
+
+/// \brief A reasonable base class for TypeLocs that correspond to
+/// types that are written as a type-specifier.
+class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                               TypeSpecTypeLoc,
+                                               Type,
+                                               TypeSpecLocInfo> {
+public:
+  enum { LocalDataSize = sizeof(TypeSpecLocInfo),
+         LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getNameLoc(), getNameLoc());
+  }
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setNameLoc(Loc);
+  }
+
+private:
+  friend class TypeLoc;
+  static bool isKind(const TypeLoc &TL);
+};
+
+
+struct BuiltinLocInfo {
+  SourceLocation BuiltinLoc;
+};
+
+/// \brief Wrapper for source info for builtin types.
+class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                              BuiltinTypeLoc,
+                                              BuiltinType,
+                                              BuiltinLocInfo> {
+public:
+  SourceLocation getBuiltinLoc() const {
+    return getLocalData()->BuiltinLoc;
+  }
+  void setBuiltinLoc(SourceLocation Loc) {
+    getLocalData()->BuiltinLoc = Loc;
+  }
+
+  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
+
+  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
+    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
+  }
+  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
+    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
+  }
+
+  bool needsExtraLocalData() const {
+    BuiltinType::Kind bk = getTypePtr()->getKind();
+    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
+      || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
+      || bk == BuiltinType::UChar
+      || bk == BuiltinType::SChar;
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
+  }
+
+  TypeSpecifierSign getWrittenSignSpec() const {
+    if (needsExtraLocalData())
+      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
+    else
+      return TSS_unspecified;
+  }
+  bool hasWrittenSignSpec() const {
+    return getWrittenSignSpec() != TSS_unspecified;
+  }
+  void setWrittenSignSpec(TypeSpecifierSign written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Sign = written;
+  }
+
+  TypeSpecifierWidth getWrittenWidthSpec() const {
+    if (needsExtraLocalData())
+      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
+    else
+      return TSW_unspecified;
+  }
+  bool hasWrittenWidthSpec() const {
+    return getWrittenWidthSpec() != TSW_unspecified;
+  }
+  void setWrittenWidthSpec(TypeSpecifierWidth written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Width = written;
+  }
+
+  TypeSpecifierType getWrittenTypeSpec() const;
+  bool hasWrittenTypeSpec() const {
+    return getWrittenTypeSpec() != TST_unspecified;
+  }
+  void setWrittenTypeSpec(TypeSpecifierType written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().Type = written;
+  }
+
+  bool hasModeAttr() const {
+    if (needsExtraLocalData())
+      return getWrittenBuiltinSpecs().ModeAttr;
+    else
+      return false;
+  }
+  void setModeAttr(bool written) {
+    if (needsExtraLocalData())
+      getWrittenBuiltinSpecs().ModeAttr = written;
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setBuiltinLoc(Loc);
+    if (needsExtraLocalData()) {
+      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
+      wbs.Sign = TSS_unspecified;
+      wbs.Width = TSW_unspecified;
+      wbs.Type = TST_unspecified;
+      wbs.ModeAttr = false;
+    }
+  }
+};
+
+
+/// \brief Wrapper for source info for typedefs.
+class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                        TypedefTypeLoc,
+                                                        TypedefType> {
+public:
+  TypedefNameDecl *getTypedefNameDecl() const {
+    return getTypePtr()->getDecl();
+  }
+};
+
+/// \brief Wrapper for source info for injected class names of class
+/// templates.
+class InjectedClassNameTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     InjectedClassNameTypeLoc,
+                                     InjectedClassNameType> {
+public:
+  CXXRecordDecl *getDecl() const {
+    return getTypePtr()->getDecl();
+  }
+};
+
+/// \brief Wrapper for source info for unresolved typename using decls.
+class UnresolvedUsingTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     UnresolvedUsingTypeLoc,
+                                     UnresolvedUsingType> {
+public:
+  UnresolvedUsingTypenameDecl *getDecl() const {
+    return getTypePtr()->getDecl();
+  }
+};
+
+/// \brief Wrapper for source info for tag types.  Note that this only
+/// records source info for the name itself; a type written 'struct foo'
+/// should be represented as an ElaboratedTypeLoc.  We currently
+/// only do that when C++ is enabled because of the expense of
+/// creating an ElaboratedType node for so many type references in C.
+class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                    TagTypeLoc,
+                                                    TagType> {
+public:
+  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
+
+  /// \brief True if the tag was defined in this type specifier.
+  bool isDefinition() const {
+    TagDecl *D = getDecl();
+    return D->isCompleteDefinition() &&
+           (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
+  }
+};
+
+/// \brief Wrapper for source info for record types.
+class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+                                                       RecordTypeLoc,
+                                                       RecordType> {
+public:
+  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for source info for enum types.
+class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+                                                     EnumTypeLoc,
+                                                     EnumType> {
+public:
+  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for template type parameters.
+class TemplateTypeParmTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     TemplateTypeParmTypeLoc,
+                                     TemplateTypeParmType> {
+public:
+  TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     SubstTemplateTypeParmTypeLoc,
+                                     SubstTemplateTypeParmType> {
+};
+
+  /// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmPackTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     SubstTemplateTypeParmPackTypeLoc,
+                                     SubstTemplateTypeParmPackType> {
+};
+
+struct AttributedLocInfo {
+  union {
+    Expr *ExprOperand;
+
+    /// A raw SourceLocation.
+    unsigned EnumOperandLoc;
+  };
+
+  SourceRange OperandParens;
+
+  SourceLocation AttrLoc;
+};
+
+/// \brief Type source information for an attributed type.
+class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 AttributedTypeLoc,
+                                                 AttributedType,
+                                                 AttributedLocInfo> {
+public:
+  AttributedType::Kind getAttrKind() const {
+    return getTypePtr()->getAttrKind();
+  }
+
+  bool hasAttrExprOperand() const {
+    return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
+            getAttrKind() <= AttributedType::LastExprOperandKind);
+  }
+
+  bool hasAttrEnumOperand() const {
+    return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
+            getAttrKind() <= AttributedType::LastEnumOperandKind);
+  }
+
+  bool hasAttrOperand() const {
+    return hasAttrExprOperand() || hasAttrEnumOperand();
+  }
+
+  /// The modified type, which is generally canonically different from
+  /// the attribute type.
+  ///    int main(int, char**) __attribute__((noreturn))
+  ///    ~~~     ~~~~~~~~~~~~~
+  TypeLoc getModifiedLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  /// The location of the attribute name, i.e.
+  ///    __attribute__((regparm(1000)))
+  ///                   ^~~~~~~
+  SourceLocation getAttrNameLoc() const {
+    return getLocalData()->AttrLoc;
+  }
+  void setAttrNameLoc(SourceLocation loc) {
+    getLocalData()->AttrLoc = loc;
+  }
+
+  /// The attribute's expression operand, if it has one.
+  ///    void *cur_thread __attribute__((address_space(21)))
+  ///                                                  ^~
+  Expr *getAttrExprOperand() const {
+    assert(hasAttrExprOperand());
+    return getLocalData()->ExprOperand;
+  }
+  void setAttrExprOperand(Expr *e) {
+    assert(hasAttrExprOperand());
+    getLocalData()->ExprOperand = e;
+  }
+
+  /// The location of the attribute's enumerated operand, if it has one.
+  ///    void * __attribute__((objc_gc(weak)))
+  ///                                  ^~~~
+  SourceLocation getAttrEnumOperandLoc() const {
+    assert(hasAttrEnumOperand());
+    return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
+  }
+  void setAttrEnumOperandLoc(SourceLocation loc) {
+    assert(hasAttrEnumOperand());
+    getLocalData()->EnumOperandLoc = loc.getRawEncoding();
+  }
+
+  /// The location of the parentheses around the operand, if there is
+  /// an operand.
+  ///    void * __attribute__((objc_gc(weak)))
+  ///                                 ^    ^
+  SourceRange getAttrOperandParensRange() const {
+    assert(hasAttrOperand());
+    return getLocalData()->OperandParens;
+  }
+  void setAttrOperandParensRange(SourceRange range) {
+    assert(hasAttrOperand());
+    getLocalData()->OperandParens = range;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    // Note that this does *not* include the range of the attribute
+    // enclosure, e.g.:
+    //    __attribute__((foo(bar)))
+    //    ^~~~~~~~~~~~~~~        ~~
+    // or
+    //    [[foo(bar)]]
+    //    ^~        ~~
+    // That enclosure doesn't necessarily belong to a single attribute
+    // anyway.
+    SourceRange range(getAttrNameLoc());
+    if (hasAttrOperand())
+      range.setEnd(getAttrOperandParensRange().getEnd());
+    return range;
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation loc) {
+    setAttrNameLoc(loc);
+    if (hasAttrExprOperand()) {
+      setAttrOperandParensRange(SourceRange(loc));
+      setAttrExprOperand(nullptr);
+    } else if (hasAttrEnumOperand()) {
+      setAttrOperandParensRange(SourceRange(loc));
+      setAttrEnumOperandLoc(loc);
+    }
+  }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getModifiedType();
+  }
+};
+
+
+struct ObjCProtocolListLocInfo {
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+  bool HasBaseTypeAsWritten;
+};
+
+// A helper class for defining ObjC TypeLocs that can qualified with
+// protocols.
+//
+// TypeClass basically has to be either ObjCInterfaceType or
+// ObjCObjectPointerType.
+class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 ObjCObjectTypeLoc,
+                                                 ObjCObjectType,
+                                                 ObjCProtocolListLocInfo> {
+  // SourceLocations are stored after Info, one for each Protocol.
+  SourceLocation *getProtocolLocArray() const {
+    return (SourceLocation*) this->getExtraLocalData();
+  }
+
+public:
+  SourceLocation getLAngleLoc() const {
+    return this->getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return this->getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumProtocols() const {
+    return this->getTypePtr()->getNumProtocols();
+  }
+
+  SourceLocation getProtocolLoc(unsigned i) const {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    return getProtocolLocArray()[i];
+  }
+  void setProtocolLoc(unsigned i, SourceLocation Loc) {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    getProtocolLocArray()[i] = Loc;
+  }
+
+  ObjCProtocolDecl *getProtocol(unsigned i) const {
+    assert(i < getNumProtocols() && "Index is out of bounds!");
+    return *(this->getTypePtr()->qual_begin() + i);
+  }
+
+  bool hasBaseTypeAsWritten() const {
+    return getLocalData()->HasBaseTypeAsWritten;
+  }
+
+  void setHasBaseTypeAsWritten(bool HasBaseType) {
+    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
+  }
+
+  TypeLoc getBaseLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getLAngleLoc(), getRAngleLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setHasBaseTypeAsWritten(true);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+      setProtocolLoc(i, Loc);
+  }
+
+  unsigned getExtraLocalDataSize() const {
+    return this->getNumProtocols() * sizeof(SourceLocation);
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return llvm::alignOf<SourceLocation>();
+  }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getBaseType();
+  }
+};
+
+
+struct ObjCInterfaceLocInfo {
+  SourceLocation NameLoc;
+  SourceLocation NameEndLoc;
+};
+
+/// \brief Wrapper for source info for ObjC interfaces.
+class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
+                                                    ObjCInterfaceTypeLoc,
+                                                    ObjCInterfaceType,
+                                                    ObjCInterfaceLocInfo> {
+public:
+  ObjCInterfaceDecl *getIFaceDecl() const {
+    return getTypePtr()->getDecl();
+  }
+
+  SourceLocation getNameLoc() const {
+    return getLocalData()->NameLoc;
+  }
+
+  void setNameLoc(SourceLocation Loc) {
+    getLocalData()->NameLoc = Loc;
+  }
+                                                    
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getNameLoc(), getNameEndLoc());
+  }
+  
+  SourceLocation getNameEndLoc() const {
+    return getLocalData()->NameEndLoc;
+  }
+
+  void setNameEndLoc(SourceLocation Loc) {
+    getLocalData()->NameEndLoc = Loc;
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setNameLoc(Loc);
+    setNameEndLoc(Loc);
+  }
+};
+
+struct ParenLocInfo {
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+};
+
+class ParenTypeLoc
+  : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
+                           ParenLocInfo> {
+public:
+  SourceLocation getLParenLoc() const {
+    return this->getLocalData()->LParenLoc;
+  }
+  SourceLocation getRParenLoc() const {
+    return this->getLocalData()->RParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    this->getLocalData()->LParenLoc = Loc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    this->getLocalData()->RParenLoc = Loc;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+  }
+
+  TypeLoc getInnerLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  QualType getInnerType() const {
+    return this->getTypePtr()->getInnerType();
+  }
+};
+
+inline TypeLoc TypeLoc::IgnoreParens() const {
+  if (ParenTypeLoc::isKind(*this))
+    return IgnoreParensImpl(*this);
+  return *this;
+}
+
+
+struct AdjustedLocInfo { }; // Nothing.
+
+class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
+                                               AdjustedType, AdjustedLocInfo> {
+public:
+  TypeLoc getOriginalLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    // do nothing
+  }
+
+  QualType getInnerType() const {
+    // The inner type is the undecayed type, since that's what we have source
+    // location information for.
+    return getTypePtr()->getOriginalType();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange();
+  }
+
+  unsigned getLocalDataSize() const {
+    // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
+    // anyway.  TypeLocBuilder can't handle data sizes of 1.
+    return 0;  // No data.
+  }
+};
+
+/// \brief Wrapper for source info for pointers decayed from arrays and
+/// functions.
+class DecayedTypeLoc : public InheritingConcreteTypeLoc<
+                           AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
+};
+
+struct PointerLikeLocInfo {
+  SourceLocation StarLoc;
+};
+
+/// A base class for
+template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
+class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
+                                                  TypeClass, LocalData> {
+public:
+  SourceLocation getSigilLoc() const {
+    return this->getLocalData()->StarLoc;
+  }
+  void setSigilLoc(SourceLocation Loc) {
+    this->getLocalData()->StarLoc = Loc;
+  }
+
+  TypeLoc getPointeeLoc() const {
+    return this->getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getSigilLoc(), getSigilLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+
+  QualType getInnerType() const {
+    return this->getTypePtr()->getPointeeType();
+  }
+};
+
+
+/// \brief Wrapper for source info for pointers.
+class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
+                                                 PointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+/// \brief Wrapper for source info for block pointers.
+class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
+                                                      BlockPointerType> {
+public:
+  SourceLocation getCaretLoc() const {
+    return getSigilLoc();
+  }
+  void setCaretLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+struct MemberPointerLocInfo : public PointerLikeLocInfo {
+  TypeSourceInfo *ClassTInfo;
+};
+
+/// \brief Wrapper for source info for member pointers.
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+                                                       MemberPointerType,
+                                                       MemberPointerLocInfo> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+
+  const Type *getClass() const {
+    return getTypePtr()->getClass();
+  }
+  TypeSourceInfo *getClassTInfo() const {
+    return getLocalData()->ClassTInfo;
+  }
+  void setClassTInfo(TypeSourceInfo* TI) {
+    getLocalData()->ClassTInfo = TI;
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setSigilLoc(Loc);
+    setClassTInfo(nullptr);
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (TypeSourceInfo *TI = getClassTInfo())
+      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
+    else
+      return SourceRange(getStarLoc());
+  }
+};
+
+/// Wraps an ObjCPointerType with source location information.
+class ObjCObjectPointerTypeLoc :
+    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
+                              ObjCObjectPointerType> {
+public:
+  SourceLocation getStarLoc() const {
+    return getSigilLoc();
+  }
+
+  void setStarLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
+                                                   ReferenceType> {
+public:
+  QualType getInnerType() const {
+    return getTypePtr()->getPointeeTypeAsWritten();
+  }
+};
+
+class LValueReferenceTypeLoc :
+    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+                                     LValueReferenceTypeLoc,
+                                     LValueReferenceType> {
+public:
+  SourceLocation getAmpLoc() const {
+    return getSigilLoc();
+  }
+  void setAmpLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+class RValueReferenceTypeLoc :
+    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+                                     RValueReferenceTypeLoc,
+                                     RValueReferenceType> {
+public:
+  SourceLocation getAmpAmpLoc() const {
+    return getSigilLoc();
+  }
+  void setAmpAmpLoc(SourceLocation Loc) {
+    setSigilLoc(Loc);
+  }
+};
+
+
+struct FunctionLocInfo {
+  SourceLocation LocalRangeBegin;
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+  SourceLocation LocalRangeEnd;
+};
+
+/// \brief Wrapper for source info for functions.
+class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                               FunctionTypeLoc,
+                                               FunctionType,
+                                               FunctionLocInfo> {
+public:
+  SourceLocation getLocalRangeBegin() const {
+    return getLocalData()->LocalRangeBegin;
+  }
+  void setLocalRangeBegin(SourceLocation L) {
+    getLocalData()->LocalRangeBegin = L;
+  }
+
+  SourceLocation getLocalRangeEnd() const {
+    return getLocalData()->LocalRangeEnd;
+  }
+  void setLocalRangeEnd(SourceLocation L) {
+    getLocalData()->LocalRangeEnd = L;
+  }
+
+  SourceLocation getLParenLoc() const {
+    return this->getLocalData()->LParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    this->getLocalData()->LParenLoc = Loc;
+  }
+
+  SourceLocation getRParenLoc() const {
+    return this->getLocalData()->RParenLoc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    this->getLocalData()->RParenLoc = Loc;
+  }
+
+  SourceRange getParensRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+
+  ArrayRef<ParmVarDecl *> getParams() const {
+    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumParams());
+  }
+
+  // ParmVarDecls* are stored after Info, one for each parameter.
+  ParmVarDecl **getParmArray() const {
+    return (ParmVarDecl**) getExtraLocalData();
+  }
+
+  unsigned getNumParams() const {
+    if (isa<FunctionNoProtoType>(getTypePtr()))
+      return 0;
+    return cast<FunctionProtoType>(getTypePtr())->getNumParams();
+  }
+  ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
+  void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
+
+  TypeLoc getReturnLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setLocalRangeBegin(Loc);
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+    setLocalRangeEnd(Loc);
+    for (unsigned i = 0, e = getNumParams(); i != e; ++i)
+      setParam(i, nullptr);
+  }
+
+  /// \brief Returns the size of the type source info data block that is
+  /// specific to this type.
+  unsigned getExtraLocalDataSize() const {
+    return getNumParams() * sizeof(ParmVarDecl *);
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return llvm::alignOf<ParmVarDecl*>();
+  }
+
+  QualType getInnerType() const { return getTypePtr()->getReturnType(); }
+};
+
+class FunctionProtoTypeLoc :
+    public InheritingConcreteTypeLoc<FunctionTypeLoc,
+                                     FunctionProtoTypeLoc,
+                                     FunctionProtoType> {
+};
+
+class FunctionNoProtoTypeLoc :
+    public InheritingConcreteTypeLoc<FunctionTypeLoc,
+                                     FunctionNoProtoTypeLoc,
+                                     FunctionNoProtoType> {
+};
+
+
+struct ArrayLocInfo {
+  SourceLocation LBracketLoc, RBracketLoc;
+  Expr *Size;
+};
+
+/// \brief Wrapper for source info for arrays.
+class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                            ArrayTypeLoc,
+                                            ArrayType,
+                                            ArrayLocInfo> {
+public:
+  SourceLocation getLBracketLoc() const {
+    return getLocalData()->LBracketLoc;
+  }
+  void setLBracketLoc(SourceLocation Loc) {
+    getLocalData()->LBracketLoc = Loc;
+  }
+
+  SourceLocation getRBracketLoc() const {
+    return getLocalData()->RBracketLoc;
+  }
+  void setRBracketLoc(SourceLocation Loc) {
+    getLocalData()->RBracketLoc = Loc;
+  }
+
+  SourceRange getBracketsRange() const {
+    return SourceRange(getLBracketLoc(), getRBracketLoc());
+  }
+
+  Expr *getSizeExpr() const {
+    return getLocalData()->Size;
+  }
+  void setSizeExpr(Expr *Size) {
+    getLocalData()->Size = Size;
+  }
+
+  TypeLoc getElementLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getLBracketLoc(), getRBracketLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setLBracketLoc(Loc);
+    setRBracketLoc(Loc);
+    setSizeExpr(nullptr);
+  }
+
+  QualType getInnerType() const { return getTypePtr()->getElementType(); }
+};
+
+class ConstantArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     ConstantArrayTypeLoc,
+                                     ConstantArrayType> {
+};
+
+class IncompleteArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     IncompleteArrayTypeLoc,
+                                     IncompleteArrayType> {
+};
+
+class DependentSizedArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     DependentSizedArrayTypeLoc,
+                                     DependentSizedArrayType> {
+
+};
+
+class VariableArrayTypeLoc :
+    public InheritingConcreteTypeLoc<ArrayTypeLoc,
+                                     VariableArrayTypeLoc,
+                                     VariableArrayType> {
+};
+
+
+// Location information for a TemplateName.  Rudimentary for now.
+struct TemplateNameLocInfo {
+  SourceLocation NameLoc;
+};
+
+struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+  SourceLocation TemplateKWLoc;
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           TemplateSpecializationTypeLoc,
+                           TemplateSpecializationType,
+                           TemplateSpecializationLocInfo> {
+public:
+  SourceLocation getTemplateKeywordLoc() const {
+    return getLocalData()->TemplateKWLoc;
+  }
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    getLocalData()->TemplateKWLoc = Loc;
+  }
+
+  SourceLocation getLAngleLoc() const {
+    return getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumArgs() const {
+    return getTypePtr()->getNumArgs();
+  }
+  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+    getArgInfos()[i] = AI;
+  }
+  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+    return getArgInfos()[i];
+  }
+
+  TemplateArgumentLoc getArgLoc(unsigned i) const {
+    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+  }
+
+  SourceLocation getTemplateNameLoc() const {
+    return getLocalData()->NameLoc;
+  }
+  void setTemplateNameLoc(SourceLocation Loc) {
+    getLocalData()->NameLoc = Loc;
+  }
+
+  /// \brief - Copy the location information from the given info.
+  void copy(TemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+
+    // We're potentially copying Expr references here.  We don't
+    // bother retaining them because TypeSourceInfos live forever, so
+    // as long as the Expr was retained when originally written into
+    // the TypeLoc, we're okay.
+    memcpy(Data, Loc.Data, size);
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getTemplateKeywordLoc().isValid())
+      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
+    else
+      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setTemplateKeywordLoc(Loc);
+    setTemplateNameLoc(Loc);
+    setLAngleLoc(Loc);
+    setRAngleLoc(Loc);
+    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
+                      getArgInfos(), Loc);
+  }
+
+  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
+                                const TemplateArgument *Args,
+                                TemplateArgumentLocInfo *ArgInfos,
+                                SourceLocation Loc);
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return llvm::alignOf<TemplateArgumentLocInfo>();
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//
+//  All of these need proper implementations.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: size expression and attribute locations (or keyword if we
+// ever fully support altivec syntax).
+class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                       VectorTypeLoc,
+                                                       VectorType> {
+};
+
+// FIXME: size expression and attribute locations.
+class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
+                                                          ExtVectorTypeLoc,
+                                                          ExtVectorType> {
+};
+
+// FIXME: attribute locations.
+// For some reason, this isn't a subtype of VectorType.
+class DependentSizedExtVectorTypeLoc :
+    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                     DependentSizedExtVectorTypeLoc,
+                                     DependentSizedExtVectorType> {
+};
+
+// FIXME: location of the '_Complex' keyword.
+class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                        ComplexTypeLoc,
+                                                        ComplexType> {
+};
+
+struct TypeofLocInfo {
+  SourceLocation TypeofLoc;
+  SourceLocation LParenLoc;
+  SourceLocation RParenLoc;
+};
+
+struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
+};
+
+struct TypeOfTypeLocInfo : public TypeofLocInfo {
+  TypeSourceInfo* UnderlyingTInfo;
+};
+
+template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
+class TypeofLikeTypeLoc
+  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
+public:
+  SourceLocation getTypeofLoc() const {
+    return this->getLocalData()->TypeofLoc;
+  }
+  void setTypeofLoc(SourceLocation Loc) {
+    this->getLocalData()->TypeofLoc = Loc;
+  }
+
+  SourceLocation getLParenLoc() const {
+    return this->getLocalData()->LParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    this->getLocalData()->LParenLoc = Loc;
+  }
+
+  SourceLocation getRParenLoc() const {
+    return this->getLocalData()->RParenLoc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    this->getLocalData()->RParenLoc = Loc;
+  }
+
+  SourceRange getParensRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+  void setParensRange(SourceRange range) {
+      setLParenLoc(range.getBegin());
+      setRParenLoc(range.getEnd());
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getTypeofLoc(), getRParenLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setTypeofLoc(Loc);
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+  }
+};
+
+class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
+                                                   TypeOfExprType,
+                                                   TypeOfExprTypeLocInfo> {
+public:
+  Expr* getUnderlyingExpr() const {
+    return getTypePtr()->getUnderlyingExpr();
+  }
+  // Reimplemented to account for GNU/C++ extension
+  //     typeof unary-expression
+  // where there are no parentheses.
+  SourceRange getLocalSourceRange() const;
+};
+
+class TypeOfTypeLoc
+  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
+public:
+  QualType getUnderlyingType() const {
+    return this->getTypePtr()->getUnderlyingType();
+  }
+  TypeSourceInfo* getUnderlyingTInfo() const {
+    return this->getLocalData()->UnderlyingTInfo;
+  }
+  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
+    this->getLocalData()->UnderlyingTInfo = TI;
+  }
+};
+
+// FIXME: location of the 'decltype' and parens.
+class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                         DecltypeTypeLoc,
+                                                         DecltypeType> {
+public:
+  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
+};
+
+struct UnaryTransformTypeLocInfo {
+  // FIXME: While there's only one unary transform right now, future ones may
+  // need different representations
+  SourceLocation KWLoc, LParenLoc, RParenLoc;
+  TypeSourceInfo *UnderlyingTInfo;
+};
+
+class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                    UnaryTransformTypeLoc,
+                                                    UnaryTransformType,
+                                                    UnaryTransformTypeLocInfo> {
+public:
+  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
+  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
+
+  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
+  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
+
+  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
+  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
+
+  TypeSourceInfo* getUnderlyingTInfo() const {
+    return getLocalData()->UnderlyingTInfo;
+  }
+  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
+    getLocalData()->UnderlyingTInfo = TInfo;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getKWLoc(), getRParenLoc());
+  }
+
+  SourceRange getParensRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+  void setParensRange(SourceRange Range) {
+    setLParenLoc(Range.getBegin());
+    setRParenLoc(Range.getEnd());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setKWLoc(Loc);
+    setRParenLoc(Loc);
+    setLParenLoc(Loc);
+  }
+};
+
+class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+                                                        AutoTypeLoc,
+                                                        AutoType> {
+};
+
+struct ElaboratedLocInfo {
+  SourceLocation ElaboratedKWLoc;
+  /// \brief Data associated with the nested-name-specifier location.
+  void *QualifierData;
+};
+
+class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                 ElaboratedTypeLoc,
+                                                 ElaboratedType,
+                                                 ElaboratedLocInfo> {
+public:
+  SourceLocation getElaboratedKeywordLoc() const {
+    return this->getLocalData()->ElaboratedKWLoc;
+  }
+  void setElaboratedKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->ElaboratedKWLoc = Loc;
+  }
+
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+                                  getLocalData()->QualifierData);
+  }
+
+  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+    assert(QualifierLoc.getNestedNameSpecifier()
+                                            == getTypePtr()->getQualifier() &&
+           "Inconsistent nested-name-specifier pointer");
+    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getElaboratedKeywordLoc().isValid())
+      if (getQualifierLoc())
+        return SourceRange(getElaboratedKeywordLoc(),
+                           getQualifierLoc().getEndLoc());
+      else
+        return SourceRange(getElaboratedKeywordLoc());
+    else
+      return getQualifierLoc().getSourceRange();
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc);
+
+  TypeLoc getNamedTypeLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  QualType getInnerType() const {
+    return getTypePtr()->getNamedType();
+  }
+
+  void copy(ElaboratedTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+};
+
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TypeDeclTypeLoc.
+struct DependentNameLocInfo : ElaboratedLocInfo {
+  SourceLocation NameLoc;
+};
+
+class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+                                                    DependentNameTypeLoc,
+                                                    DependentNameType,
+                                                    DependentNameLocInfo> {
+public:
+  SourceLocation getElaboratedKeywordLoc() const {
+    return this->getLocalData()->ElaboratedKWLoc;
+  }
+  void setElaboratedKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->ElaboratedKWLoc = Loc;
+  }
+
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+                                  getLocalData()->QualifierData);
+  }
+
+  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+    assert(QualifierLoc.getNestedNameSpecifier()
+                                            == getTypePtr()->getQualifier() &&
+           "Inconsistent nested-name-specifier pointer");
+    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+  }
+
+  SourceLocation getNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getElaboratedKeywordLoc().isValid())
+      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
+    else
+      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
+  }
+
+  void copy(DependentNameTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc);
+};
+
+struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+  SourceLocation TemplateKWLoc;
+  SourceLocation LAngleLoc;
+  SourceLocation RAngleLoc;
+  // followed by a TemplateArgumentLocInfo[]
+};
+
+class DependentTemplateSpecializationTypeLoc :
+    public ConcreteTypeLoc<UnqualTypeLoc,
+                           DependentTemplateSpecializationTypeLoc,
+                           DependentTemplateSpecializationType,
+                           DependentTemplateSpecializationLocInfo> {
+public:
+  SourceLocation getElaboratedKeywordLoc() const {
+    return this->getLocalData()->ElaboratedKWLoc;
+  }
+  void setElaboratedKeywordLoc(SourceLocation Loc) {
+    this->getLocalData()->ElaboratedKWLoc = Loc;
+  }
+
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    if (!getLocalData()->QualifierData)
+      return NestedNameSpecifierLoc();
+
+    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+                                  getLocalData()->QualifierData);
+  }
+
+  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+    if (!QualifierLoc) {
+      // Even if we have a nested-name-specifier in the dependent
+      // template specialization type, we won't record the nested-name-specifier
+      // location information when this type-source location information is
+      // part of a nested-name-specifier.
+      getLocalData()->QualifierData = nullptr;
+      return;
+    }
+
+    assert(QualifierLoc.getNestedNameSpecifier()
+                                        == getTypePtr()->getQualifier() &&
+           "Inconsistent nested-name-specifier pointer");
+    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+  }
+
+  SourceLocation getTemplateKeywordLoc() const {
+    return getLocalData()->TemplateKWLoc;
+  }
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    getLocalData()->TemplateKWLoc = Loc;
+  }
+
+  SourceLocation getTemplateNameLoc() const {
+    return this->getLocalData()->NameLoc;
+  }
+  void setTemplateNameLoc(SourceLocation Loc) {
+    this->getLocalData()->NameLoc = Loc;
+  }
+
+  SourceLocation getLAngleLoc() const {
+    return this->getLocalData()->LAngleLoc;
+  }
+  void setLAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->LAngleLoc = Loc;
+  }
+
+  SourceLocation getRAngleLoc() const {
+    return this->getLocalData()->RAngleLoc;
+  }
+  void setRAngleLoc(SourceLocation Loc) {
+    this->getLocalData()->RAngleLoc = Loc;
+  }
+
+  unsigned getNumArgs() const {
+    return getTypePtr()->getNumArgs();
+  }
+
+  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+    getArgInfos()[i] = AI;
+  }
+  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+    return getArgInfos()[i];
+  }
+
+  TemplateArgumentLoc getArgLoc(unsigned i) const {
+    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+  }
+
+  SourceRange getLocalSourceRange() const {
+    if (getElaboratedKeywordLoc().isValid())
+      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
+    else if (getQualifierLoc())
+      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
+    else if (getTemplateKeywordLoc().isValid())
+      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
+    else
+      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+  }
+
+  void copy(DependentTemplateSpecializationTypeLoc Loc) {
+    unsigned size = getFullDataSize();
+    assert(size == Loc.getFullDataSize());
+    memcpy(Data, Loc.Data, size);
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc);
+
+  unsigned getExtraLocalDataSize() const {
+    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+  }
+
+  unsigned getExtraLocalDataAlignment() const {
+    return llvm::alignOf<TemplateArgumentLocInfo>();
+  }
+
+private:
+  TemplateArgumentLocInfo *getArgInfos() const {
+    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+  }
+};
+
+
+struct PackExpansionTypeLocInfo {
+  SourceLocation EllipsisLoc;
+};
+
+class PackExpansionTypeLoc
+  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
+                           PackExpansionType, PackExpansionTypeLocInfo> {
+public:
+  SourceLocation getEllipsisLoc() const {
+    return this->getLocalData()->EllipsisLoc;
+  }
+
+  void setEllipsisLoc(SourceLocation Loc) {
+    this->getLocalData()->EllipsisLoc = Loc;
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setEllipsisLoc(Loc);
+  }
+
+  TypeLoc getPatternLoc() const {
+    return getInnerTypeLoc();
+  }
+
+  QualType getInnerType() const {
+    return this->getTypePtr()->getPattern();
+  }
+};
+
+struct AtomicTypeLocInfo {
+  SourceLocation KWLoc, LParenLoc, RParenLoc;
+};
+
+class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
+                                             AtomicType, AtomicTypeLocInfo> {
+public:
+  TypeLoc getValueLoc() const {
+    return this->getInnerTypeLoc();
+  }
+
+  SourceRange getLocalSourceRange() const {
+    return SourceRange(getKWLoc(), getRParenLoc());
+  }
+
+  SourceLocation getKWLoc() const {
+    return this->getLocalData()->KWLoc;
+  }
+  void setKWLoc(SourceLocation Loc) {
+    this->getLocalData()->KWLoc = Loc;
+  }
+
+  SourceLocation getLParenLoc() const {
+    return this->getLocalData()->LParenLoc;
+  }
+  void setLParenLoc(SourceLocation Loc) {
+    this->getLocalData()->LParenLoc = Loc;
+  }
+
+  SourceLocation getRParenLoc() const {
+    return this->getLocalData()->RParenLoc;
+  }
+  void setRParenLoc(SourceLocation Loc) {
+    this->getLocalData()->RParenLoc = Loc;
+  }
+
+  SourceRange getParensRange() const {
+    return SourceRange(getLParenLoc(), getRParenLoc());
+  }
+  void setParensRange(SourceRange Range) {
+    setLParenLoc(Range.getBegin());
+    setRParenLoc(Range.getEnd());
+  }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    setKWLoc(Loc);
+    setLParenLoc(Loc);
+    setRParenLoc(Loc);
+  }
+
+  QualType getInnerType() const {
+    return this->getTypePtr()->getValueType();
+  }
+};
+
+
+}
+
+#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
new file mode 100644
index 0000000..4590e48
--- /dev/null
+++ b/include/clang/AST/TypeLocNodes.def
@@ -0,0 +1,41 @@
+//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- 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 TypeLoc info database.  Each node is
+//  enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
+//  and base class (e.g., "DeclaratorLoc").  All nodes except QualifiedTypeLoc
+//  are associated
+//
+//    TYPELOC(Class, Base) - A TypeLoc subclass.  If UNQUAL_TYPELOC is
+//      provided, there will be exactly one of these, Qualified.
+//
+//    UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
+//
+//    ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef UNQUAL_TYPELOC
+#  define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
+#endif
+
+#ifndef ABSTRACT_TYPELOC
+#  define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
+#endif
+
+TYPELOC(Qualified, TypeLoc)
+#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
+#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
+#include "clang/AST/TypeNodes.def"
+
+#undef DECLARATOR_TYPELOC
+#undef TYPESPEC_TYPELOC
+#undef ABSTRACT_TYPELOC
+#undef UNQUAL_TYPELOC
+#undef TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
new file mode 100644
index 0000000..db5775a
--- /dev/null
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -0,0 +1,62 @@
+//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- 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 TypeLocVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_TYPELOCVISITOR_H
+#define LLVM_CLANG_AST_TYPELOCVISITOR_H
+
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeVisitor.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+#define DISPATCH(CLASSNAME) \
+  return static_cast<ImplClass*>(this)-> \
+    Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>())
+
+template<typename ImplClass, typename RetTy=void>
+class TypeLocVisitor {
+public:
+  RetTy Visit(TypeLoc TyLoc) {
+    switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+    }
+    llvm_unreachable("unexpected type loc class!");
+  }
+
+  RetTy Visit(UnqualTypeLoc TyLoc) {
+    switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+    }
+    llvm_unreachable("unexpected type loc class!");
+  }
+
+#define TYPELOC(CLASS, PARENT)      \
+  RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+    DISPATCH(PARENT);               \
+  }
+#include "clang/AST/TypeLocNodes.def"
+
+  RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif // LLVM_CLANG_AST_TYPELOCVISITOR_H
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
new file mode 100644
index 0000000..3b2665b
--- /dev/null
+++ b/include/clang/AST/TypeNodes.def
@@ -0,0 +1,129 @@
+//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- 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 AST type info database. Each type node is
+//  enumerated by providing its name (e.g., "Builtin" or "Enum") and
+//  base class (e.g., "Type" or "TagType"). Depending on where in the
+//  abstract syntax tree the type will show up, the enumeration uses
+//  one of four different macros:
+//
+//    TYPE(Class, Base) - A type that can show up anywhere in the AST,
+//    and might be dependent, canonical, or non-canonical. All clients
+//    will need to understand these types.
+//
+//    ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
+//    the type hierarchy but has no concrete instances.
+//
+//    NON_CANONICAL_TYPE(Class, Base) - A type that can show up
+//    anywhere in the AST but will never be a part of a canonical
+//    type. Clients that only need to deal with canonical types
+//    (ignoring, e.g., typedefs and other type alises used for
+//    pretty-printing) can ignore these types.
+//
+//    DEPENDENT_TYPE(Class, Base) - A type that will only show up
+//    within a C++ template that has not been instantiated, e.g., a
+//    type that is always dependent. Clients that do not need to deal
+//    with uninstantiated C++ templates can ignore these types.
+//
+//    NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) - A type that
+//    is non-canonical unless it is dependent.  Defaults to TYPE because
+//    it is neither reliably dependent nor reliably non-canonical.
+//
+//  There is a sixth macro, independent of the others.  Most clients
+//  will not need to use it.
+//
+//    LEAF_TYPE(Class) - A type that never has inner types.  Clients
+//    which can operate on such types more efficiently may wish to do so.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ABSTRACT_TYPE
+#  define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef NON_CANONICAL_TYPE
+#  define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef DEPENDENT_TYPE
+#  define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+#  define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+TYPE(Builtin, Type)
+TYPE(Complex, Type)
+TYPE(Pointer, Type)
+TYPE(BlockPointer, Type)
+ABSTRACT_TYPE(Reference, Type)
+TYPE(LValueReference, ReferenceType)
+TYPE(RValueReference, ReferenceType)
+TYPE(MemberPointer, Type)
+ABSTRACT_TYPE(Array, Type)
+TYPE(ConstantArray, ArrayType)
+TYPE(IncompleteArray, ArrayType)
+TYPE(VariableArray, ArrayType)
+DEPENDENT_TYPE(DependentSizedArray, ArrayType)
+DEPENDENT_TYPE(DependentSizedExtVector, Type)
+TYPE(Vector, Type)
+TYPE(ExtVector, VectorType)
+ABSTRACT_TYPE(Function, Type)
+TYPE(FunctionProto, FunctionType)
+TYPE(FunctionNoProto, FunctionType)
+DEPENDENT_TYPE(UnresolvedUsing, Type)
+NON_CANONICAL_TYPE(Paren, Type)
+NON_CANONICAL_TYPE(Typedef, Type)
+NON_CANONICAL_TYPE(Adjusted, Type)
+NON_CANONICAL_TYPE(Decayed, AdjustedType)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)
+ABSTRACT_TYPE(Tag, Type)
+TYPE(Record, TagType)
+TYPE(Enum, TagType)
+NON_CANONICAL_TYPE(Elaborated, Type)
+NON_CANONICAL_TYPE(Attributed, Type)
+DEPENDENT_TYPE(TemplateTypeParm, Type)
+NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
+DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
+TYPE(Auto, Type)
+DEPENDENT_TYPE(InjectedClassName, Type)
+DEPENDENT_TYPE(DependentName, Type)
+DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
+NON_CANONICAL_UNLESS_DEPENDENT_TYPE(PackExpansion, Type)
+TYPE(ObjCObject, Type)
+TYPE(ObjCInterface, ObjCObjectType)
+TYPE(ObjCObjectPointer, Type)
+TYPE(Atomic, Type)
+
+#ifdef LAST_TYPE
+LAST_TYPE(Atomic)
+#undef LAST_TYPE
+#endif
+
+// These types are always leaves in the type hierarchy.
+#ifdef LEAF_TYPE
+LEAF_TYPE(Enum)
+LEAF_TYPE(Builtin)
+LEAF_TYPE(Record)
+LEAF_TYPE(InjectedClassName)
+LEAF_TYPE(ObjCInterface)
+LEAF_TYPE(TemplateTypeParm)
+#undef LEAF_TYPE
+#endif
+
+#undef NON_CANONICAL_UNLESS_DEPENDENT_TYPE
+#undef DEPENDENT_TYPE
+#undef NON_CANONICAL_TYPE
+#undef ABSTRACT_TYPE
+#undef TYPE
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
new file mode 100644
index 0000000..9c9f15e
--- /dev/null
+++ b/include/clang/AST/TypeOrdering.h
@@ -0,0 +1,79 @@
+//===-------------- TypeOrdering.h - Total ordering for types -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Allows QualTypes to be sorted and hence used in maps and sets.
+///
+/// Defines clang::QualTypeOrdering, a total ordering on clang::QualType,
+/// and hence enables QualType values to be sorted and to be used in
+/// std::maps, std::sets, llvm::DenseMaps, and llvm::DenseSets.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPE_ORDERING_H
+#define LLVM_CLANG_TYPE_ORDERING_H
+
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
+#include <functional>
+
+namespace clang {
+
+/// \brief Function object that provides a total ordering on QualType values.
+struct QualTypeOrdering : std::binary_function<QualType, QualType, bool> {
+  bool operator()(QualType T1, QualType T2) const {
+    return std::less<void*>()(T1.getAsOpaquePtr(), T2.getAsOpaquePtr());
+  }
+};
+
+}
+
+namespace llvm {
+  template<class> struct DenseMapInfo;
+
+  template<> struct DenseMapInfo<clang::QualType> {
+    static inline clang::QualType getEmptyKey() { return clang::QualType(); }
+
+    static inline clang::QualType getTombstoneKey() {
+      using clang::QualType;
+      return QualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
+    }
+
+    static unsigned getHashValue(clang::QualType Val) {
+      return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
+            ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
+    }
+
+    static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
+      return LHS == RHS;
+    }
+  };
+
+  template<> struct DenseMapInfo<clang::CanQualType> {
+    static inline clang::CanQualType getEmptyKey() { 
+      return clang::CanQualType(); 
+    }
+    
+    static inline clang::CanQualType getTombstoneKey() {
+      using clang::CanQualType;
+      return CanQualType::getFromOpaquePtr(reinterpret_cast<clang::Type *>(-1));
+    }
+    
+    static unsigned getHashValue(clang::CanQualType Val) {
+      return (unsigned)((uintptr_t)Val.getAsOpaquePtr()) ^
+      ((unsigned)((uintptr_t)Val.getAsOpaquePtr() >> 9));
+    }
+    
+    static bool isEqual(clang::CanQualType LHS, clang::CanQualType RHS) {
+      return LHS == RHS;
+    }
+  };
+}
+
+#endif
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
new file mode 100644
index 0000000..11e5a47
--- /dev/null
+++ b/include/clang/AST/TypeVisitor.h
@@ -0,0 +1,95 @@
+//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- 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 TypeVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
+#define LLVM_CLANG_AST_TYPEVISITOR_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+#define DISPATCH(CLASS) \
+  return static_cast<ImplClass*>(this)-> \
+           Visit##CLASS(static_cast<const CLASS*>(T))
+
+/// \brief An operation on a type.
+///
+/// \tparam ImplClass Class implementing the operation. Must be inherited from
+///         TypeVisitor.
+/// \tparam RetTy %Type of result produced by the operation.
+///
+/// The class implements polymorphic operation on an object of type derived
+/// from Type. The operation is performed by calling method Visit. It then
+/// dispatches the call to function \c VisitFooType, if actual argument type
+/// is \c FooType.
+///
+/// The class implements static polymorphism using Curiously Recurring
+/// Template Pattern. It is designed to be a base class for some concrete
+/// class:
+///
+/// \code
+///     class SomeVisitor : public TypeVisitor<SomeVisitor,sometype> { ... };
+///     ...
+///     Type *atype = ...
+///     ...
+///     SomeVisitor avisitor;
+///     sometype result = avisitor.Visit(atype);
+/// \endcode
+///
+/// Actual treatment is made by methods of the derived class, TypeVisitor only
+/// dispatches call to the appropriate method. If the implementation class
+/// \c ImplClass provides specific action for some type, say
+/// \c ConstantArrayType, it should define method
+/// <tt>VisitConstantArrayType(const ConstantArrayType*)</tt>. Otherwise
+/// \c TypeVisitor dispatches call to the method that handles parent type. In
+/// this example handlers are tried in the sequence:
+///
+/// \li <tt>ImplClass::VisitConstantArrayType(const ConstantArrayType*)</tt>
+/// \li <tt>ImplClass::VisitArrayType(const ArrayType*)</tt>
+/// \li <tt>ImplClass::VisitType(const Type*)</tt>
+/// \li <tt>TypeVisitor::VisitType(const Type*)</tt>
+///
+/// The first function of this sequence that is defined will handle object of
+/// type \c ConstantArrayType.
+template<typename ImplClass, typename RetTy=void>
+class TypeVisitor {
+public:
+
+  /// \brief Performs the operation associated with this visitor object.
+  RetTy Visit(const Type *T) {
+    // Top switch stmt: dispatch to VisitFooType for each FooType.
+    switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, PARENT)
+#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
+#include "clang/AST/TypeNodes.def"
+    }
+    llvm_unreachable("Unknown type class!");
+  }
+
+  // If the implementation chooses not to implement a certain visit method, fall
+  // back on superclass.
+#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(const CLASS##Type *T) { \
+  DISPATCH(PARENT);                                                          \
+}
+#include "clang/AST/TypeNodes.def"
+
+  /// \brief Method called if \c ImpClass doesn't provide specific handler
+  /// for some type class.
+  RetTy VisitType(const Type*) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
new file mode 100644
index 0000000..2ef5800
--- /dev/null
+++ b/include/clang/AST/UnresolvedSet.h
@@ -0,0 +1,184 @@
+//===-- UnresolvedSet.h - Unresolved sets of declarations  ------*- 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 UnresolvedSet class, which is used to store
+//  collections of declarations in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H
+#define LLVM_CLANG_AST_UNRESOLVEDSET_H
+
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include <iterator>
+
+namespace clang {
+
+/// The iterator over UnresolvedSets.  Serves as both the const and
+/// non-const iterator.
+class UnresolvedSetIterator {
+private:
+  typedef MutableArrayRef<DeclAccessPair> DeclsTy;
+  typedef DeclsTy::iterator IteratorTy;
+
+  IteratorTy ir;
+
+  friend class UnresolvedSetImpl;
+  friend class ASTUnresolvedSet;
+  friend class OverloadExpr;
+  explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
+  explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
+    ir(const_cast<DeclsTy::iterator>(ir)) {}
+  
+  IteratorTy getIterator() const { return ir; }
+  
+public:
+  UnresolvedSetIterator() {}
+
+  typedef std::iterator_traits<IteratorTy>::difference_type difference_type;
+  typedef NamedDecl *value_type;
+  typedef NamedDecl **pointer;
+  typedef NamedDecl *reference;
+  typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
+
+  NamedDecl *getDecl() const { return ir->getDecl(); }
+  void setDecl(NamedDecl *ND) const { return ir->setDecl(ND); }
+  AccessSpecifier getAccess() const { return ir->getAccess(); }
+  void setAccess(AccessSpecifier AS) { ir->setAccess(AS); }
+  DeclAccessPair getPair() const { return *ir; }
+
+  NamedDecl *operator*() const { return getDecl(); }
+  
+  UnresolvedSetIterator &operator++() { ++ir; return *this; }
+  UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); }
+  UnresolvedSetIterator &operator--() { --ir; return *this; }
+  UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); }
+
+  UnresolvedSetIterator &operator+=(difference_type d) {
+    ir += d; return *this;
+  }
+  UnresolvedSetIterator operator+(difference_type d) const {
+    return UnresolvedSetIterator(ir + d);
+  }
+  UnresolvedSetIterator &operator-=(difference_type d) {
+    ir -= d; return *this;
+  }
+  UnresolvedSetIterator operator-(difference_type d) const {
+    return UnresolvedSetIterator(ir - d);
+  }
+  value_type operator[](difference_type d) const { return *(*this + d); }
+
+  difference_type operator-(const UnresolvedSetIterator &o) const {
+    return ir - o.ir;
+  }
+
+  bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; }
+  bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; }
+  bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; }
+  bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; }
+  bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; }
+  bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
+};
+
+/// \brief A set of unresolved declarations.
+class UnresolvedSetImpl {
+  typedef SmallVectorImpl<DeclAccessPair> DeclsTy;
+
+  // Don't allow direct construction, and only permit subclassing by
+  // UnresolvedSet.
+private:
+  template <unsigned N> friend class UnresolvedSet;
+  UnresolvedSetImpl() {}
+  UnresolvedSetImpl(const UnresolvedSetImpl &) LLVM_DELETED_FUNCTION;
+
+public:
+  // We don't currently support assignment through this iterator, so we might
+  // as well use the same implementation twice.
+  typedef UnresolvedSetIterator iterator;
+  typedef UnresolvedSetIterator const_iterator;
+
+  iterator begin() { return iterator(decls().begin()); }
+  iterator end() { return iterator(decls().end()); }
+
+  const_iterator begin() const { return const_iterator(decls().begin()); }
+  const_iterator end() const { return const_iterator(decls().end()); }
+
+  void addDecl(NamedDecl *D) {
+    addDecl(D, AS_none);
+  }
+
+  void addDecl(NamedDecl *D, AccessSpecifier AS) {
+    decls().push_back(DeclAccessPair::make(D, AS));
+  }
+
+  /// Replaces the given declaration with the new one, once.
+  ///
+  /// \return true if the set changed
+  bool replace(const NamedDecl* Old, NamedDecl *New) {
+    for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
+      if (I->getDecl() == Old)
+        return (I->setDecl(New), true);
+    return false;
+  }
+
+  /// Replaces the declaration at the given iterator with the new one,
+  /// preserving the original access bits.
+  void replace(iterator I, NamedDecl *New) {
+    I.ir->setDecl(New);
+  }
+
+  void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
+    I.ir->set(New, AS);
+  }
+
+  void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
+
+  void erase(iterator I) { *I.ir = decls().pop_back_val(); }
+
+  void setAccess(iterator I, AccessSpecifier AS) {
+    I.ir->setAccess(AS);
+  }
+
+  void clear() { decls().clear(); }
+  void set_size(unsigned N) { decls().set_size(N); }
+
+  bool empty() const { return decls().empty(); }
+  unsigned size() const { return decls().size(); }
+
+  void append(iterator I, iterator E) {
+    decls().append(I.ir, E.ir);
+  }
+
+  DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
+  const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
+
+private:
+  // These work because the only permitted subclass is UnresolvedSetImpl
+
+  DeclsTy &decls() {
+    return *reinterpret_cast<DeclsTy*>(this);
+  }
+  const DeclsTy &decls() const {
+    return *reinterpret_cast<const DeclsTy*>(this);
+  }
+};
+
+/// \brief A set of unresolved declarations.
+template <unsigned InlineCapacity> class UnresolvedSet :
+    public UnresolvedSetImpl {
+  SmallVector<DeclAccessPair, InlineCapacity> Decls;
+};
+
+  
+} // namespace clang
+
+#endif
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
new file mode 100644
index 0000000..727bf51
--- /dev/null
+++ b/include/clang/AST/VTTBuilder.h
@@ -0,0 +1,162 @@
+//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with generation of the layout of virtual table
+// tables (VTT).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_VTTBUILDER_H
+#define LLVM_CLANG_AST_VTTBUILDER_H
+
+#include "clang/AST/BaseSubobject.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/GlobalDecl.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/ABI.h"
+#include "llvm/ADT/SetVector.h"
+#include <utility>
+
+namespace clang {
+
+class VTTVTable {
+  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
+  CharUnits BaseOffset;
+
+public:
+  VTTVTable() {}
+  VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
+    : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
+  VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
+    : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
+      BaseOffset(Base.getBaseOffset()) {}
+
+  const CXXRecordDecl *getBase() const {
+    return BaseAndIsVirtual.getPointer();
+  }
+
+  CharUnits getBaseOffset() const {
+    return BaseOffset;
+  }
+
+  bool isVirtual() const {
+    return BaseAndIsVirtual.getInt();
+  }
+
+  BaseSubobject getBaseSubobject() const {
+    return BaseSubobject(getBase(), getBaseOffset());
+  }
+};
+
+struct VTTComponent {
+  uint64_t VTableIndex;
+  BaseSubobject VTableBase;
+
+  VTTComponent() {}
+  VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
+    : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
+};
+
+/// \brief Class for building VTT layout information.
+class VTTBuilder {
+  
+  ASTContext &Ctx;
+
+  /// \brief The most derived class for which we're building this vtable.
+  const CXXRecordDecl *MostDerivedClass;
+
+  typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy;
+  
+  /// \brief The VTT vtables.
+  VTTVTablesVectorTy VTTVTables;
+  
+  typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy;
+  
+  /// \brief The VTT components.
+  VTTComponentsVectorTy VTTComponents;
+  
+  /// \brief The AST record layout of the most derived class.
+  const ASTRecordLayout &MostDerivedClassLayout;
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
+
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+
+  /// \brief The sub-VTT indices for the bases of the most derived class.
+  llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
+
+  /// \brief The secondary virtual pointer indices of all subobjects of
+  /// the most derived class.
+  llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
+
+  /// \brief Whether the VTT builder should generate LLVM IR for the VTT.
+  bool GenerateDefinition;
+
+  /// \brief Add a vtable pointer to the VTT currently being built.
+  void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
+                        const CXXRecordDecl *VTableClass);
+                        
+  /// \brief Lay out the secondary VTTs of the given base subobject.
+  void LayoutSecondaryVTTs(BaseSubobject Base);
+  
+  /// \brief Lay out the secondary virtual pointers for the given base
+  /// subobject.
+  ///
+  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                      bool BaseIsMorallyVirtual,
+                                      uint64_t VTableIndex,
+                                      const CXXRecordDecl *VTableClass,
+                                      VisitedVirtualBasesSetTy &VBases);
+  
+  /// \brief Lay out the secondary virtual pointers for the given base
+  /// subobject.
+  void LayoutSecondaryVirtualPointers(BaseSubobject Base, 
+                                      uint64_t VTableIndex);
+
+  /// \brief Lay out the VTTs for the virtual base classes of the given
+  /// record declaration.
+  void LayoutVirtualVTTs(const CXXRecordDecl *RD,
+                         VisitedVirtualBasesSetTy &VBases);
+  
+  /// \brief Lay out the VTT for the given subobject, including any
+  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
+  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
+  
+public:
+  VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
+             bool GenerateDefinition);
+
+  // \brief Returns a reference to the VTT components.
+  const VTTComponentsVectorTy &getVTTComponents() const {
+    return VTTComponents;
+  }
+  
+  // \brief Returns a reference to the VTT vtables.
+  const VTTVTablesVectorTy &getVTTVTables() const {
+    return VTTVTables;
+  }
+  
+  /// \brief Returns a reference to the sub-VTT indices.
+  const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
+    return SubVTTIndicies;
+  }
+  
+  /// \brief Returns a reference to the secondary virtual pointer indices.
+  const llvm::DenseMap<BaseSubobject, uint64_t> &
+  getSecondaryVirtualPointerIndices() const {
+    return SecondaryVirtualPointerIndices;
+  }
+
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
new file mode 100644
index 0000000..4e24bdd
--- /dev/null
+++ b/include/clang/AST/VTableBuilder.h
@@ -0,0 +1,545 @@
+//===--- VTableBuilder.h - C++ vtable layout builder --------------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with generation of the layout of virtual tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_VTABLEBUILDER_H
+#define LLVM_CLANG_AST_VTABLEBUILDER_H
+
+#include "clang/AST/BaseSubobject.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/GlobalDecl.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/Basic/ABI.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+#include <memory>
+#include <utility>
+
+namespace clang {
+  class CXXRecordDecl;
+
+/// \brief Represents a single component in a vtable.
+class VTableComponent {
+public:
+  enum Kind {
+    CK_VCallOffset,
+    CK_VBaseOffset,
+    CK_OffsetToTop,
+    CK_RTTI,
+    CK_FunctionPointer,
+
+    /// \brief A pointer to the complete destructor.
+    CK_CompleteDtorPointer,
+
+    /// \brief A pointer to the deleting destructor.
+    CK_DeletingDtorPointer,
+
+    /// \brief An entry that is never used.
+    ///
+    /// In some cases, a vtable function pointer will end up never being
+    /// called. Such vtable function pointers are represented as a
+    /// CK_UnusedFunctionPointer.
+    CK_UnusedFunctionPointer
+  };
+
+  VTableComponent() { }
+
+  static VTableComponent MakeVCallOffset(CharUnits Offset) {
+    return VTableComponent(CK_VCallOffset, Offset);
+  }
+
+  static VTableComponent MakeVBaseOffset(CharUnits Offset) {
+    return VTableComponent(CK_VBaseOffset, Offset);
+  }
+
+  static VTableComponent MakeOffsetToTop(CharUnits Offset) {
+    return VTableComponent(CK_OffsetToTop, Offset);
+  }
+
+  static VTableComponent MakeRTTI(const CXXRecordDecl *RD) {
+    return VTableComponent(CK_RTTI, reinterpret_cast<uintptr_t>(RD));
+  }
+
+  static VTableComponent MakeFunction(const CXXMethodDecl *MD) {
+    assert(!isa<CXXDestructorDecl>(MD) &&
+           "Don't use MakeFunction with destructors!");
+
+    return VTableComponent(CK_FunctionPointer,
+                           reinterpret_cast<uintptr_t>(MD));
+  }
+
+  static VTableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) {
+    return VTableComponent(CK_CompleteDtorPointer,
+                           reinterpret_cast<uintptr_t>(DD));
+  }
+
+  static VTableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) {
+    return VTableComponent(CK_DeletingDtorPointer,
+                           reinterpret_cast<uintptr_t>(DD));
+  }
+
+  static VTableComponent MakeUnusedFunction(const CXXMethodDecl *MD) {
+    assert(!isa<CXXDestructorDecl>(MD) &&
+           "Don't use MakeUnusedFunction with destructors!");
+    return VTableComponent(CK_UnusedFunctionPointer,
+                           reinterpret_cast<uintptr_t>(MD));
+  }
+
+  static VTableComponent getFromOpaqueInteger(uint64_t I) {
+    return VTableComponent(I);
+  }
+
+  /// \brief Get the kind of this vtable component.
+  Kind getKind() const {
+    return (Kind)(Value & 0x7);
+  }
+
+  CharUnits getVCallOffset() const {
+    assert(getKind() == CK_VCallOffset && "Invalid component kind!");
+
+    return getOffset();
+  }
+
+  CharUnits getVBaseOffset() const {
+    assert(getKind() == CK_VBaseOffset && "Invalid component kind!");
+
+    return getOffset();
+  }
+
+  CharUnits getOffsetToTop() const {
+    assert(getKind() == CK_OffsetToTop && "Invalid component kind!");
+
+    return getOffset();
+  }
+
+  const CXXRecordDecl *getRTTIDecl() const {
+    assert(getKind() == CK_RTTI && "Invalid component kind!");
+
+    return reinterpret_cast<CXXRecordDecl *>(getPointer());
+  }
+
+  const CXXMethodDecl *getFunctionDecl() const {
+    assert(getKind() == CK_FunctionPointer);
+
+    return reinterpret_cast<CXXMethodDecl *>(getPointer());
+  }
+
+  const CXXDestructorDecl *getDestructorDecl() const {
+    assert((getKind() == CK_CompleteDtorPointer ||
+            getKind() == CK_DeletingDtorPointer) && "Invalid component kind!");
+
+    return reinterpret_cast<CXXDestructorDecl *>(getPointer());
+  }
+
+  const CXXMethodDecl *getUnusedFunctionDecl() const {
+    assert(getKind() == CK_UnusedFunctionPointer);
+
+    return reinterpret_cast<CXXMethodDecl *>(getPointer());
+  }
+
+private:
+  VTableComponent(Kind ComponentKind, CharUnits Offset) {
+    assert((ComponentKind == CK_VCallOffset ||
+            ComponentKind == CK_VBaseOffset ||
+            ComponentKind == CK_OffsetToTop) && "Invalid component kind!");
+    assert(Offset.getQuantity() < (1LL << 56) && "Offset is too big!");
+    assert(Offset.getQuantity() >= -(1LL << 56) && "Offset is too small!");
+
+    Value = (uint64_t(Offset.getQuantity()) << 3) | ComponentKind;
+  }
+
+  VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
+    assert((ComponentKind == CK_RTTI ||
+            ComponentKind == CK_FunctionPointer ||
+            ComponentKind == CK_CompleteDtorPointer ||
+            ComponentKind == CK_DeletingDtorPointer ||
+            ComponentKind == CK_UnusedFunctionPointer) &&
+            "Invalid component kind!");
+
+    assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
+
+    Value = Ptr | ComponentKind;
+  }
+
+  CharUnits getOffset() const {
+    assert((getKind() == CK_VCallOffset || getKind() == CK_VBaseOffset ||
+            getKind() == CK_OffsetToTop) && "Invalid component kind!");
+
+    return CharUnits::fromQuantity(Value >> 3);
+  }
+
+  uintptr_t getPointer() const {
+    assert((getKind() == CK_RTTI ||
+            getKind() == CK_FunctionPointer ||
+            getKind() == CK_CompleteDtorPointer ||
+            getKind() == CK_DeletingDtorPointer ||
+            getKind() == CK_UnusedFunctionPointer) &&
+           "Invalid component kind!");
+
+    return static_cast<uintptr_t>(Value & ~7ULL);
+  }
+
+  explicit VTableComponent(uint64_t Value)
+    : Value(Value) { }
+
+  /// The kind is stored in the lower 3 bits of the value. For offsets, we
+  /// make use of the facts that classes can't be larger than 2^55 bytes,
+  /// so we store the offset in the lower part of the 61 bits that remain.
+  /// (The reason that we're not simply using a PointerIntPair here is that we
+  /// need the offsets to be 64-bit, even when on a 32-bit machine).
+  int64_t Value;
+};
+
+class VTableLayout {
+public:
+  typedef std::pair<uint64_t, ThunkInfo> VTableThunkTy;
+
+  typedef const VTableComponent *vtable_component_iterator;
+  typedef const VTableThunkTy *vtable_thunk_iterator;
+
+  typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+private:
+  uint64_t NumVTableComponents;
+  std::unique_ptr<VTableComponent[]> VTableComponents;
+
+  /// \brief Contains thunks needed by vtables, sorted by indices.
+  uint64_t NumVTableThunks;
+  std::unique_ptr<VTableThunkTy[]> VTableThunks;
+
+  /// \brief Address points for all vtables.
+  AddressPointsMapTy AddressPoints;
+
+  bool IsMicrosoftABI;
+
+public:
+  VTableLayout(uint64_t NumVTableComponents,
+               const VTableComponent *VTableComponents,
+               uint64_t NumVTableThunks,
+               const VTableThunkTy *VTableThunks,
+               const AddressPointsMapTy &AddressPoints,
+               bool IsMicrosoftABI);
+  ~VTableLayout();
+
+  uint64_t getNumVTableComponents() const {
+    return NumVTableComponents;
+  }
+
+  vtable_component_iterator vtable_component_begin() const {
+    return VTableComponents.get();
+  }
+
+  vtable_component_iterator vtable_component_end() const {
+    return VTableComponents.get() + NumVTableComponents;
+  }
+
+  uint64_t getNumVTableThunks() const { return NumVTableThunks; }
+
+  vtable_thunk_iterator vtable_thunk_begin() const {
+    return VTableThunks.get();
+  }
+
+  vtable_thunk_iterator vtable_thunk_end() const {
+    return VTableThunks.get() + NumVTableThunks;
+  }
+
+  uint64_t getAddressPoint(BaseSubobject Base) const {
+    assert(AddressPoints.count(Base) &&
+           "Did not find address point!");
+
+    uint64_t AddressPoint = AddressPoints.lookup(Base);
+    assert(AddressPoint != 0 || IsMicrosoftABI);
+    (void)IsMicrosoftABI;
+
+    return AddressPoint;
+  }
+
+  const AddressPointsMapTy &getAddressPoints() const {
+    return AddressPoints;
+  }
+};
+
+class VTableContextBase {
+public:
+  typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
+
+  bool isMicrosoft() const { return IsMicrosoftABI; }
+
+  virtual ~VTableContextBase() {}
+
+protected:
+  typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
+
+  /// \brief Contains all thunks that a given method decl will need.
+  ThunksMapTy Thunks;
+
+  /// Compute and store all vtable related information (vtable layout, vbase
+  /// offset offsets, thunks etc) for the given record decl.
+  virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0;
+
+  VTableContextBase(bool MS) : IsMicrosoftABI(MS) {}
+
+public:
+  virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
+    const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()->getCanonicalDecl());
+    computeVTableRelatedInformation(MD->getParent());
+
+    // This assumes that all the destructors present in the vtable
+    // use exactly the same set of thunks.
+    ThunksMapTy::const_iterator I = Thunks.find(MD);
+    if (I == Thunks.end()) {
+      // We did not find a thunk for this method.
+      return nullptr;
+    }
+
+    return &I->second;
+  }
+
+  bool IsMicrosoftABI;
+};
+
+class ItaniumVTableContext : public VTableContextBase {
+private:
+
+  /// \brief Contains the index (relative to the vtable address point)
+  /// where the function pointer for a virtual function is stored.
+  typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy;
+  MethodVTableIndicesTy MethodVTableIndices;
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, const VTableLayout *>
+    VTableLayoutMapTy;
+  VTableLayoutMapTy VTableLayouts;
+
+  typedef std::pair<const CXXRecordDecl *,
+                    const CXXRecordDecl *> ClassPairTy;
+
+  /// \brief vtable offsets for offsets of virtual bases of a class.
+  ///
+  /// Contains the vtable offset (relative to the address point) in chars
+  /// where the offsets for virtual bases of a class are stored.
+  typedef llvm::DenseMap<ClassPairTy, CharUnits>
+    VirtualBaseClassOffsetOffsetsMapTy;
+  VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
+
+  void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
+
+public:
+  ItaniumVTableContext(ASTContext &Context);
+  ~ItaniumVTableContext();
+
+  const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {
+    computeVTableRelatedInformation(RD);
+    assert(VTableLayouts.count(RD) && "No layout for this record decl!");
+
+    return *VTableLayouts[RD];
+  }
+
+  VTableLayout *
+  createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
+                                 CharUnits MostDerivedClassOffset,
+                                 bool MostDerivedClassIsVirtual,
+                                 const CXXRecordDecl *LayoutClass);
+
+  /// \brief Locate a virtual function in the vtable.
+  ///
+  /// Return the index (relative to the vtable address point) where the
+  /// function pointer for the given virtual function is stored.
+  uint64_t getMethodVTableIndex(GlobalDecl GD);
+
+  /// Return the offset in chars (relative to the vtable address point) where
+  /// the offset of the virtual base that contains the given base is stored,
+  /// otherwise, if no virtual base contains the given class, return 0. 
+  ///
+  /// Base must be a virtual base class or an unambiguous base.
+  CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
+                                       const CXXRecordDecl *VBase);
+
+  static bool classof(const VTableContextBase *VT) {
+    return !VT->isMicrosoft();
+  }
+};
+
+/// Holds information about the inheritance path to a virtual base or function
+/// table pointer.  A record may contain as many vfptrs or vbptrs as there are
+/// base subobjects.
+struct VPtrInfo {
+  typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
+
+  VPtrInfo(const CXXRecordDecl *RD)
+      : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
+
+  // Copy constructor.
+  // FIXME: Uncomment when we've moved to C++11.
+  // VPtrInfo(const VPtrInfo &) = default;
+
+  /// The vtable will hold all of the virtual bases or virtual methods of
+  /// ReusingBase.  This may or may not be the same class as VPtrSubobject.Base.
+  /// A derived class will reuse the vptr of the first non-virtual base
+  /// subobject that has one.
+  const CXXRecordDecl *ReusingBase;
+
+  /// BaseWithVPtr is at this offset from its containing complete object or
+  /// virtual base.
+  CharUnits NonVirtualOffset;
+
+  /// The vptr is stored inside this subobject.
+  const CXXRecordDecl *BaseWithVPtr;
+
+  /// The bases from the inheritance path that got used to mangle the vbtable
+  /// name.  This is not really a full path like a CXXBasePath.  It holds the
+  /// subset of records that need to be mangled into the vbtable symbol name in
+  /// order to get a unique name.
+  BasePath MangledPath;
+
+  /// The next base to push onto the mangled path if this path is ambiguous in a
+  /// derived class.  If it's null, then it's already been pushed onto the path.
+  const CXXRecordDecl *NextBaseToMangle;
+
+  /// The set of possibly indirect vbases that contain this vbtable.  When a
+  /// derived class indirectly inherits from the same vbase twice, we only keep
+  /// vtables and their paths from the first instance.
+  BasePath ContainingVBases;
+
+  /// This holds the base classes path from the complete type to the first base
+  /// with the given vfptr offset, in the base-to-derived order.  Only used for
+  /// vftables.
+  BasePath PathToBaseWithVPtr;
+
+  /// Static offset from the top of the most derived class to this vfptr,
+  /// including any virtual base offset.  Only used for vftables.
+  CharUnits FullOffsetInMDC;
+
+  /// The vptr is stored inside the non-virtual component of this virtual base.
+  const CXXRecordDecl *getVBaseWithVPtr() const {
+    return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
+  }
+};
+
+typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
+
+/// All virtual base related information about a given record decl.  Includes
+/// information on all virtual base tables and the path components that are used
+/// to mangle them.
+struct VirtualBaseInfo {
+  ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
+
+  /// A map from virtual base to vbtable index for doing a conversion from the
+  /// the derived class to the a base.
+  llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
+
+  /// Information on all virtual base tables used when this record is the most
+  /// derived class.
+  VPtrInfoVector VBPtrPaths;
+};
+
+class MicrosoftVTableContext : public VTableContextBase {
+public:
+  struct MethodVFTableLocation {
+    /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
+    uint64_t VBTableIndex;
+
+    /// If nonnull, holds the last vbase which contains the vfptr that the
+    /// method definition is adjusted to.
+    const CXXRecordDecl *VBase;
+
+    /// This is the offset of the vfptr from the start of the last vbase, or the
+    /// complete type if there are no virtual bases.
+    CharUnits VFPtrOffset;
+
+    /// Method's index in the vftable.
+    uint64_t Index;
+
+    MethodVFTableLocation()
+        : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
+          Index(0) {}
+
+    MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
+                          CharUnits VFPtrOffset, uint64_t Index)
+        : VBTableIndex(VBTableIndex), VBase(VBase),
+          VFPtrOffset(VFPtrOffset), Index(Index) {}
+
+    bool operator<(const MethodVFTableLocation &other) const {
+      if (VBTableIndex != other.VBTableIndex) {
+        assert(VBase != other.VBase);
+        return VBTableIndex < other.VBTableIndex;
+      }
+      return std::tie(VFPtrOffset, Index) <
+             std::tie(other.VFPtrOffset, other.Index);
+    }
+  };
+
+private:
+  ASTContext &Context;
+
+  typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
+    MethodVFTableLocationsTy;
+  MethodVFTableLocationsTy MethodVFTableLocations;
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
+    VFPtrLocationsMapTy;
+  VFPtrLocationsMapTy VFPtrLocations;
+
+  typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
+  typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
+  VFTableLayoutMapTy VFTableLayouts;
+
+  llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
+
+  void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
+
+  void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
+
+  void dumpMethodLocations(const CXXRecordDecl *RD,
+                           const MethodVFTableLocationsTy &NewMethods,
+                           raw_ostream &);
+
+  const VirtualBaseInfo *
+  computeVBTableRelatedInformation(const CXXRecordDecl *RD);
+
+  void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
+                          VPtrInfoVector &Paths);
+
+public:
+  MicrosoftVTableContext(ASTContext &Context)
+      : VTableContextBase(/*MS=*/true), Context(Context) {}
+
+  ~MicrosoftVTableContext();
+
+  const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD);
+
+  const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
+                                       CharUnits VFPtrOffset);
+
+  const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
+
+  const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
+    // Complete destructors don't have a slot in a vftable, so no thunks needed.
+    if (isa<CXXDestructorDecl>(GD.getDecl()) &&
+        GD.getDtorType() == Dtor_Complete)
+      return nullptr;
+    return VTableContextBase::getThunkInfo(GD);
+  }
+
+  /// \brief Returns the index of VBase in the vbtable of Derived.
+  /// VBase must be a morally virtual base of Derived.
+  /// The vbtable is an array of i32 offsets.  The first entry is a self entry,
+  /// and the rest are offsets from the vbptr to virtual bases.
+  unsigned getVBTableIndex(const CXXRecordDecl *Derived,
+                           const CXXRecordDecl *VBase);
+
+  const VPtrInfoVector &enumerateVBTables(const CXXRecordDecl *RD);
+
+  static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
new file mode 100644
index 0000000..8af0546
--- /dev/null
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -0,0 +1,258 @@
+//===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Provides a way to construct an ASTConsumer that runs given matchers
+//  over the AST and invokes a given callback on every match.
+//
+//  The general idea is to construct a matcher expression that describes a
+//  subtree match on the AST. Next, a callback that is executed every time the
+//  expression matches is registered, and the matcher is run over the AST of
+//  some code. Matched subexpressions can be bound to string IDs and easily
+//  be accessed from the registered callback. The callback can than use the
+//  AST nodes that the subexpressions matched on to output information about
+//  the match or construct changes that can be applied to the code.
+//
+//  Example:
+//  class HandleMatch : public MatchFinder::MatchCallback {
+//  public:
+//    virtual void Run(const MatchFinder::MatchResult &Result) {
+//      const CXXRecordDecl *Class =
+//          Result.Nodes.GetDeclAs<CXXRecordDecl>("id");
+//      ...
+//    }
+//  };
+//
+//  int main(int argc, char **argv) {
+//    ClangTool Tool(argc, argv);
+//    MatchFinder finder;
+//    finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))),
+//                      new HandleMatch);
+//    return Tool.Run(newFrontendActionFactory(&finder));
+//  }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
+#define LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+namespace clang {
+
+namespace ast_matchers {
+
+/// \brief A class to allow finding matches over the Clang AST.
+///
+/// After creation, you can add multiple matchers to the MatchFinder via
+/// calls to addMatcher(...).
+///
+/// Once all matchers are added, newASTConsumer() returns an ASTConsumer
+/// that will trigger the callbacks specified via addMatcher(...) when a match
+/// is found.
+///
+/// The order of matches is guaranteed to be equivalent to doing a pre-order
+/// traversal on the AST, and applying the matchers in the order in which they
+/// were added to the MatchFinder.
+///
+/// See ASTMatchers.h for more information about how to create matchers.
+///
+/// Not intended to be subclassed.
+class MatchFinder {
+public:
+  /// \brief Contains all information for a given match.
+  ///
+  /// Every time a match is found, the MatchFinder will invoke the registered
+  /// MatchCallback with a MatchResult containing information about the match.
+  struct MatchResult {
+    MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context);
+
+    /// \brief Contains the nodes bound on the current match.
+    ///
+    /// This allows user code to easily extract matched AST nodes.
+    const BoundNodes Nodes;
+
+    /// \brief Utilities for interpreting the matched AST structures.
+    /// @{
+    clang::ASTContext * const Context;
+    clang::SourceManager * const SourceManager;
+    /// @}
+  };
+
+  /// \brief Called when the Match registered for it was successfully found
+  /// in the AST.
+  class MatchCallback {
+  public:
+    virtual ~MatchCallback();
+
+    /// \brief Called on every match by the \c MatchFinder.
+    virtual void run(const MatchResult &Result) = 0;
+
+    /// \brief Called at the start of each translation unit.
+    ///
+    /// Optionally override to do per translation unit tasks.
+    virtual void onStartOfTranslationUnit() {}
+
+    /// \brief Called at the end of each translation unit.
+    ///
+    /// Optionally override to do per translation unit tasks.
+    virtual void onEndOfTranslationUnit() {}
+  };
+
+  /// \brief Called when parsing is finished. Intended for testing only.
+  class ParsingDoneTestCallback {
+  public:
+    virtual ~ParsingDoneTestCallback();
+    virtual void run() = 0;
+  };
+
+  MatchFinder();
+  ~MatchFinder();
+
+  /// \brief Adds a matcher to execute when running over the AST.
+  ///
+  /// Calls 'Action' with the BoundNodes on every match.
+  /// Adding more than one 'NodeMatch' allows finding different matches in a
+  /// single pass over the AST.
+  ///
+  /// Does not take ownership of 'Action'.
+  /// @{
+  void addMatcher(const DeclarationMatcher &NodeMatch,
+                  MatchCallback *Action);
+  void addMatcher(const TypeMatcher &NodeMatch,
+                  MatchCallback *Action);
+  void addMatcher(const StatementMatcher &NodeMatch,
+                  MatchCallback *Action);
+  void addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
+                  MatchCallback *Action);
+  void addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
+                  MatchCallback *Action);
+  void addMatcher(const TypeLocMatcher &NodeMatch,
+                  MatchCallback *Action);
+  /// @}
+
+  /// \brief Adds a matcher to execute when running over the AST.
+  ///
+  /// This is similar to \c addMatcher(), but it uses the dynamic interface. It
+  /// is more flexible, but the lost type information enables a caller to pass
+  /// a matcher that cannot match anything.
+  ///
+  /// \returns \c true if the matcher is a valid top-level matcher, \c false
+  ///   otherwise.
+  bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
+                         MatchCallback *Action);
+
+  /// \brief Creates a clang ASTConsumer that finds all matches.
+  clang::ASTConsumer *newASTConsumer();
+
+  /// \brief Calls the registered callbacks on all matches on the given \p Node.
+  ///
+  /// Note that there can be multiple matches on a single node, for
+  /// example when using decl(forEachDescendant(stmt())).
+  ///
+  /// @{
+  template <typename T> void match(const T &Node, ASTContext &Context) {
+    match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
+  }
+  void match(const clang::ast_type_traits::DynTypedNode &Node,
+             ASTContext &Context);
+  /// @}
+
+  /// \brief Finds all matches in the given AST.
+  void matchAST(ASTContext &Context);
+
+  /// \brief Registers a callback to notify the end of parsing.
+  ///
+  /// The provided closure is called after parsing is done, before the AST is
+  /// traversed. Useful for benchmarking.
+  /// Each call to FindAll(...) will call the closure once.
+  void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone);
+
+private:
+  /// \brief For each \c DynTypedMatcher a \c MatchCallback that will be called
+  /// when it matches.
+  std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> >
+    MatcherCallbackPairs;
+
+  /// \brief Called when parsing is done.
+  ParsingDoneTestCallback *ParsingDone;
+};
+
+/// \brief Returns the results of matching \p Matcher on \p Node.
+///
+/// Collects the \c BoundNodes of all callback invocations when matching
+/// \p Matcher on \p Node and returns the collected results.
+///
+/// Multiple results occur when using matchers like \c forEachDescendant,
+/// which generate a result for each sub-match.
+///
+/// \see selectFirst
+/// @{
+template <typename MatcherT, typename NodeT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
+
+template <typename MatcherT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+      ASTContext &Context);
+/// @}
+
+/// \brief Returns the first result of type \c NodeT bound to \p BoundTo.
+///
+/// Returns \c NULL if there is no match, or if the matching node cannot be
+/// casted to \c NodeT.
+///
+/// This is useful in combanation with \c match():
+/// \code
+///   Decl *D = selectFirst<Decl>("id", match(Matcher.bind("id"),
+///                                           Node, Context));
+/// \endcode
+template <typename NodeT>
+NodeT *
+selectFirst(StringRef BoundTo, const SmallVectorImpl<BoundNodes> &Results) {
+  for (SmallVectorImpl<BoundNodes>::const_iterator I = Results.begin(),
+                                                   E = Results.end();
+       I != E; ++I) {
+    if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
+      return Node;
+  }
+  return nullptr;
+}
+
+namespace internal {
+class CollectMatchesCallback : public MatchFinder::MatchCallback {
+public:
+  void run(const MatchFinder::MatchResult &Result) override {
+    Nodes.push_back(Result.Nodes);
+  }
+  SmallVector<BoundNodes, 1> Nodes;
+};
+}
+
+template <typename MatcherT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
+      ASTContext &Context) {
+  internal::CollectMatchesCallback Callback;
+  MatchFinder Finder;
+  Finder.addMatcher(Matcher, &Callback);
+  Finder.match(Node, Context);
+  return Callback.Nodes;
+}
+
+template <typename MatcherT, typename NodeT>
+SmallVector<BoundNodes, 1>
+match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
+  return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
+}
+
+} // end namespace ast_matchers
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
new file mode 100644
index 0000000..1ff4ab3
--- /dev/null
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -0,0 +1,3649 @@
+//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements matchers to be used together with the MatchFinder to
+//  match AST nodes.
+//
+//  Matchers are created by generator functions, which can be combined in
+//  a functional in-language DSL to express queries over the C++ AST.
+//
+//  For example, to match a class with a certain name, one would call:
+//    recordDecl(hasName("MyClass"))
+//  which returns a matcher that can be used to find all AST nodes that declare
+//  a class named 'MyClass'.
+//
+//  For more complicated match expressions we're often interested in accessing
+//  multiple parts of the matched AST nodes once a match is found. In that case,
+//  use the id(...) matcher around the match expressions that match the nodes
+//  you want to access.
+//
+//  For example, when we're interested in child classes of a certain class, we
+//  would write:
+//    recordDecl(hasName("MyClass"), hasChild(id("child", recordDecl())))
+//  When the match is found via the MatchFinder, a user provided callback will
+//  be called with a BoundNodes instance that contains a mapping from the
+//  strings that we provided for the id(...) calls to the nodes that were
+//  matched.
+//  In the given example, each time our matcher finds a match we get a callback
+//  where "child" is bound to the CXXRecordDecl node of the matching child
+//  class declaration.
+//
+//  See ASTMatchersInternal.h for a more in-depth explanation of the
+//  implementation details of the matcher framework.
+//
+//  See ASTMatchFinder.h for how to use the generated matchers to run over
+//  an AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
+#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
+
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Regex.h"
+#include <iterator>
+
+namespace clang {
+namespace ast_matchers {
+
+/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
+///
+/// The bound nodes are generated by calling \c bind("id") on the node matchers
+/// of the nodes we want to access later.
+///
+/// The instances of BoundNodes are created by \c MatchFinder when the user's
+/// callbacks are executed every time a match is found.
+class BoundNodes {
+public:
+  /// \brief Returns the AST node bound to \c ID.
+  ///
+  /// Returns NULL if there was no node bound to \c ID or if there is a node but
+  /// it cannot be converted to the specified type.
+  template <typename T>
+  const T *getNodeAs(StringRef ID) const {
+    return MyBoundNodes.getNodeAs<T>(ID);
+  }
+
+  /// \brief Deprecated. Please use \c getNodeAs instead.
+  /// @{
+  template <typename T>
+  const T *getDeclAs(StringRef ID) const {
+    return getNodeAs<T>(ID);
+  }
+  template <typename T>
+  const T *getStmtAs(StringRef ID) const {
+    return getNodeAs<T>(ID);
+  }
+  /// @}
+
+  /// \brief Type of mapping from binding identifiers to bound nodes. This type
+  /// is an associative container with a key type of \c std::string and a value
+  /// type of \c clang::ast_type_traits::DynTypedNode
+  typedef internal::BoundNodesMap::IDToNodeMap IDToNodeMap;
+
+  /// \brief Retrieve mapping from binding identifiers to bound nodes.
+  const IDToNodeMap &getMap() const {
+    return MyBoundNodes.getMap();
+  }
+
+private:
+  /// \brief Create BoundNodes from a pre-filled map of bindings.
+  BoundNodes(internal::BoundNodesMap &MyBoundNodes)
+      : MyBoundNodes(MyBoundNodes) {}
+
+  internal::BoundNodesMap MyBoundNodes;
+
+  friend class internal::BoundNodesTreeBuilder;
+};
+
+/// \brief If the provided matcher matches a node, binds the node to \c ID.
+///
+/// FIXME: Do we want to support this now that we have bind()?
+template <typename T>
+internal::Matcher<T> id(const std::string &ID,
+                        const internal::BindableMatcher<T> &InnerMatcher) {
+  return InnerMatcher.bind(ID);
+}
+
+/// \brief Types of matchers for the top-level classes in the AST class
+/// hierarchy.
+/// @{
+typedef internal::Matcher<Decl> DeclarationMatcher;
+typedef internal::Matcher<Stmt> StatementMatcher;
+typedef internal::Matcher<QualType> TypeMatcher;
+typedef internal::Matcher<TypeLoc> TypeLocMatcher;
+typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
+typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
+/// @}
+
+/// \brief Matches any node.
+///
+/// Useful when another matcher requires a child matcher, but there's no
+/// additional constraint. This will often be used with an explicit conversion
+/// to an \c internal::Matcher<> type such as \c TypeMatcher.
+///
+/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// \code
+/// "int* p" and "void f()" in
+///   int* p;
+///   void f();
+/// \endcode
+///
+/// Usable as: Any Matcher
+inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>
+anything() {
+  return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
+}
+
+/// \brief Matches declarations.
+///
+/// Examples matches \c X, \c C, and the friend declaration inside \c C;
+/// \code
+///   void X();
+///   class C {
+///     friend X;
+///   };
+/// \endcode
+const internal::VariadicAllOfMatcher<Decl> decl;
+
+/// \brief Matches a declaration of anything that could have a name.
+///
+/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
+/// \code
+///   typedef int X;
+///   struct S {
+///     union {
+///       int i;
+///     } U;
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
+
+/// \brief Matches a declaration of a namespace.
+///
+/// Given
+/// \code
+///   namespace {}
+///   namespace test {}
+/// \endcode
+/// namespaceDecl()
+///   matches "namespace {}" and "namespace test {}"
+const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
+
+/// \brief Matches C++ class declarations.
+///
+/// Example matches \c X, \c Z
+/// \code
+///   class X;
+///   template<class T> class Z {};
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  CXXRecordDecl> recordDecl;
+
+/// \brief Matches C++ class template declarations.
+///
+/// Example matches \c Z
+/// \code
+///   template<class T> class Z {};
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  ClassTemplateDecl> classTemplateDecl;
+
+/// \brief Matches C++ class template specializations.
+///
+/// Given
+/// \code
+///   template<typename T> class A {};
+///   template<> class A<double> {};
+///   A<int> a;
+/// \endcode
+/// classTemplateSpecializationDecl()
+///   matches the specializations \c A<int> and \c A<double>
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  ClassTemplateSpecializationDecl> classTemplateSpecializationDecl;
+
+/// \brief Matches declarator declarations (field, variable, function
+/// and non-type template parameter declarations).
+///
+/// Given
+/// \code
+///   class X { int y; };
+/// \endcode
+/// declaratorDecl()
+///   matches \c int y.
+const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
+    declaratorDecl;
+
+/// \brief Matches parameter variable declarations.
+///
+/// Given
+/// \code
+///   void f(int x);
+/// \endcode
+/// parmVarDecl()
+///   matches \c int x.
+const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
+
+/// \brief Matches C++ access specifier declarations.
+///
+/// Given
+/// \code
+///   class C {
+///   public:
+///     int a;
+///   };
+/// \endcode
+/// accessSpecDecl()
+///   matches 'public:'
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  AccessSpecDecl> accessSpecDecl;
+
+/// \brief Matches constructor initializers.
+///
+/// Examples matches \c i(42).
+/// \code
+///   class C {
+///     C() : i(42) {}
+///     int i;
+///   };
+/// \endcode
+const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer;
+
+/// \brief Matches public C++ declarations.
+///
+/// Given
+/// \code
+///   class C {
+///   public:    int a;
+///   protected: int b;
+///   private:   int c;
+///   };
+/// \endcode
+/// fieldDecl(isPublic())
+///   matches 'int a;' 
+AST_MATCHER(Decl, isPublic) {
+  return Node.getAccess() == AS_public;
+}
+
+/// \brief Matches protected C++ declarations.
+///
+/// Given
+/// \code
+///   class C {
+///   public:    int a;
+///   protected: int b;
+///   private:   int c;
+///   };
+/// \endcode
+/// fieldDecl(isProtected())
+///   matches 'int b;' 
+AST_MATCHER(Decl, isProtected) {
+  return Node.getAccess() == AS_protected;
+}
+
+/// \brief Matches private C++ declarations.
+///
+/// Given
+/// \code
+///   class C {
+///   public:    int a;
+///   protected: int b;
+///   private:   int c;
+///   };
+/// \endcode
+/// fieldDecl(isPrivate())
+///   matches 'int c;' 
+AST_MATCHER(Decl, isPrivate) {
+  return Node.getAccess() == AS_private;
+}
+
+/// \brief Matches a declaration that has been implicitly added
+/// by the compiler (eg. implicit default/copy constructors).
+AST_MATCHER(Decl, isImplicit) {
+  return Node.isImplicit();
+}
+
+/// \brief Matches classTemplateSpecializations that have at least one
+/// TemplateArgument matching the given InnerMatcher.
+///
+/// Given
+/// \code
+///   template<typename T> class A {};
+///   template<> class A<double> {};
+///   A<int> a;
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+///     refersToType(asString("int"))))
+///   matches the specialization \c A<int>
+AST_POLYMORPHIC_MATCHER_P(
+    hasAnyTemplateArgument,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+                                      TemplateSpecializationType),
+    internal::Matcher<TemplateArgument>, InnerMatcher) {
+  ArrayRef<TemplateArgument> List =
+      internal::getTemplateSpecializationArgs(Node);
+  return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
+                             Builder);
+}
+
+/// \brief Matches expressions that match InnerMatcher after any implicit casts
+/// are stripped off.
+///
+/// Parentheses and explicit casts are not discarded.
+/// Given
+/// \code
+///   int arr[5];
+///   int a = 0;
+///   char b = 0;
+///   const int c = a;
+///   int *d = arr;
+///   long e = (long) 0l;
+/// \endcode
+/// The matchers
+/// \code
+///    varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
+///    varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
+/// \endcode
+/// would match the declarations for a, b, c, and d, but not e.
+/// While
+/// \code
+///    varDecl(hasInitializer(integerLiteral()))
+///    varDecl(hasInitializer(declRefExpr()))
+/// \endcode
+/// only match the declarations for b, c, and d.
+AST_MATCHER_P(Expr, ignoringImpCasts,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
+}
+
+/// \brief Matches expressions that match InnerMatcher after parentheses and
+/// casts are stripped off.
+///
+/// Implicit and non-C Style casts are also discarded.
+/// Given
+/// \code
+///   int a = 0;
+///   char b = (0);
+///   void* c = reinterpret_cast<char*>(0);
+///   char d = char(0);
+/// \endcode
+/// The matcher
+///    varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
+/// would match the declarations for a, b, c, and d.
+/// while
+///    varDecl(hasInitializer(integerLiteral()))
+/// only match the declaration for a.
+AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
+}
+
+/// \brief Matches expressions that match InnerMatcher after implicit casts and
+/// parentheses are stripped off.
+///
+/// Explicit casts are not discarded.
+/// Given
+/// \code
+///   int arr[5];
+///   int a = 0;
+///   char b = (0);
+///   const int c = a;
+///   int *d = (arr);
+///   long e = ((long) 0l);
+/// \endcode
+/// The matchers
+///    varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
+///    varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
+/// would match the declarations for a, b, c, and d, but not e.
+/// while
+///    varDecl(hasInitializer(integerLiteral()))
+///    varDecl(hasInitializer(declRefExpr()))
+/// would only match the declaration for a.
+AST_MATCHER_P(Expr, ignoringParenImpCasts,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
+}
+
+/// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
+/// matches the given InnerMatcher.
+///
+/// Given
+/// \code
+///   template<typename T, typename U> class A {};
+///   A<bool, int> b;
+///   A<int, bool> c;
+/// \endcode
+/// classTemplateSpecializationDecl(hasTemplateArgument(
+///     1, refersToType(asString("int"))))
+///   matches the specialization \c A<bool, int>
+AST_POLYMORPHIC_MATCHER_P2(
+    hasTemplateArgument,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+                                      TemplateSpecializationType),
+    unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
+  ArrayRef<TemplateArgument> List =
+      internal::getTemplateSpecializationArgs(Node);
+  if (List.size() <= N)
+    return false;
+  return InnerMatcher.matches(List[N], Finder, Builder);
+}
+
+/// \brief Matches a TemplateArgument that refers to a certain type.
+///
+/// Given
+/// \code
+///   struct X {};
+///   template<typename T> struct A {};
+///   A<X> a;
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+///     refersToType(class(hasName("X")))))
+///   matches the specialization \c A<X>
+AST_MATCHER_P(TemplateArgument, refersToType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  if (Node.getKind() != TemplateArgument::Type)
+    return false;
+  return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
+}
+
+/// \brief Matches a canonical TemplateArgument that refers to a certain
+/// declaration.
+///
+/// Given
+/// \code
+///   template<typename T> struct A {};
+///   struct B { B* next; };
+///   A<&B::next> a;
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+///     refersToDeclaration(fieldDecl(hasName("next"))))
+///   matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+///     \c B::next
+AST_MATCHER_P(TemplateArgument, refersToDeclaration,
+              internal::Matcher<Decl>, InnerMatcher) {
+  if (Node.getKind() == TemplateArgument::Declaration)
+    return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder);
+  return false;
+}
+
+/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
+///
+/// Given
+/// \code
+///   template<typename T> struct A {};
+///   struct B { B* next; };
+///   A<&B::next> a;
+/// \endcode
+/// templateSpecializationType(hasAnyTemplateArgument(
+///   isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
+///   matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+///     \c B::next
+AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
+  if (Node.getKind() == TemplateArgument::Expression)
+    return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
+  return false;
+}
+
+/// \brief Matches C++ constructor declarations.
+///
+/// Example matches Foo::Foo() and Foo::Foo(int)
+/// \code
+///   class Foo {
+///    public:
+///     Foo();
+///     Foo(int);
+///     int DoSomething();
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  CXXConstructorDecl> constructorDecl;
+
+/// \brief Matches explicit C++ destructor declarations.
+///
+/// Example matches Foo::~Foo()
+/// \code
+///   class Foo {
+///    public:
+///     virtual ~Foo();
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  CXXDestructorDecl> destructorDecl;
+
+/// \brief Matches enum declarations.
+///
+/// Example matches X
+/// \code
+///   enum X {
+///     A, B, C
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
+
+/// \brief Matches enum constants.
+///
+/// Example matches A, B, C
+/// \code
+///   enum X {
+///     A, B, C
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  EnumConstantDecl> enumConstantDecl;
+
+/// \brief Matches method declarations.
+///
+/// Example matches y
+/// \code
+///   class X { void y(); };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl;
+
+/// \brief Matches variable declarations.
+///
+/// Note: this does not match declarations of member variables, which are
+/// "field" declarations in Clang parlance.
+///
+/// Example matches a
+/// \code
+///   int a;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
+
+/// \brief Matches field declarations.
+///
+/// Given
+/// \code
+///   class X { int m; };
+/// \endcode
+/// fieldDecl()
+///   matches 'm'.
+const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
+
+/// \brief Matches function declarations.
+///
+/// Example matches f
+/// \code
+///   void f();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
+
+/// \brief Matches C++ function template declarations.
+///
+/// Example matches f
+/// \code
+///   template<class T> void f(T t) {}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  FunctionTemplateDecl> functionTemplateDecl;
+
+/// \brief Matches friend declarations.
+///
+/// Given
+/// \code
+///   class X { friend void foo(); };
+/// \endcode
+/// friendDecl()
+///   matches 'friend void foo()'.
+const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
+
+/// \brief Matches statements.
+///
+/// Given
+/// \code
+///   { ++a; }
+/// \endcode
+/// stmt()
+///   matches both the compound statement '{ ++a; }' and '++a'.
+const internal::VariadicAllOfMatcher<Stmt> stmt;
+
+/// \brief Matches declaration statements.
+///
+/// Given
+/// \code
+///   int a;
+/// \endcode
+/// declStmt()
+///   matches 'int a'.
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  DeclStmt> declStmt;
+
+/// \brief Matches member expressions.
+///
+/// Given
+/// \code
+///   class Y {
+///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
+///     int a; static int b;
+///   };
+/// \endcode
+/// memberExpr()
+///   matches this->x, x, y.x, a, this->b
+const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
+
+/// \brief Matches call expressions.
+///
+/// Example matches x.y() and y()
+/// \code
+///   X x;
+///   x.y();
+///   y();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
+
+/// \brief Matches lambda expressions.
+///
+/// Example matches [&](){return 5;}
+/// \code
+///   [&](){return 5;}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
+
+/// \brief Matches member call expressions.
+///
+/// Example matches x.y()
+/// \code
+///   X x;
+///   x.y();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXMemberCallExpr> memberCallExpr;
+
+/// \brief Matches expressions that introduce cleanups to be run at the end
+/// of the sub-expression's evaluation.
+///
+/// Example matches std::string()
+/// \code
+///   const std::string str = std::string();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
+exprWithCleanups;
+
+/// \brief Matches init list expressions.
+///
+/// Given
+/// \code
+///   int a[] = { 1, 2 };
+///   struct B { int x, y; };
+///   B b = { 5, 6 };
+/// \endcode
+/// initListExpr()
+///   matches "{ 1, 2 }" and "{ 5, 6 }"
+const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
+
+/// \brief Matches substitutions of non-type template parameters.
+///
+/// Given
+/// \code
+///   template <int N>
+///   struct A { static const int n = N; };
+///   struct B : public A<42> {};
+/// \endcode
+/// substNonTypeTemplateParmExpr()
+///   matches "N" in the right-hand side of "static const int n = N;"
+const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
+substNonTypeTemplateParmExpr;
+
+/// \brief Matches using declarations.
+///
+/// Given
+/// \code
+///   namespace X { int x; }
+///   using X::x;
+/// \endcode
+/// usingDecl()
+///   matches \code using X::x \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
+
+/// \brief Matches using namespace declarations.
+///
+/// Given
+/// \code
+///   namespace X { int x; }
+///   using namespace X;
+/// \endcode
+/// usingDirectiveDecl()
+///   matches \code using namespace X \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
+    usingDirectiveDecl;
+
+/// \brief Matches unresolved using value declarations.
+///
+/// Given
+/// \code
+///   template<typename X>
+///   class C : private X {
+///     using X::x;
+///   };
+/// \endcode
+/// unresolvedUsingValueDecl()
+///   matches \code using X::x \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  UnresolvedUsingValueDecl> unresolvedUsingValueDecl;
+
+/// \brief Matches constructor call expressions (including implicit ones).
+///
+/// Example matches string(ptr, n) and ptr within arguments of f
+///     (matcher = constructExpr())
+/// \code
+///   void f(const string &a, const string &b);
+///   char *ptr;
+///   int n;
+///   f(string(ptr, n), ptr);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXConstructExpr> constructExpr;
+
+/// \brief Matches unresolved constructor call expressions.
+///
+/// Example matches T(t) in return statement of f
+///     (matcher = unresolvedConstructExpr())
+/// \code
+///   template <typename T>
+///   void f(const T& t) { return T(t); }
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXUnresolvedConstructExpr> unresolvedConstructExpr;
+
+/// \brief Matches implicit and explicit this expressions.
+///
+/// Example matches the implicit this expression in "return i".
+///     (matcher = thisExpr())
+/// \code
+/// struct foo {
+///   int i;
+///   int f() { return i; }
+/// };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> thisExpr;
+
+/// \brief Matches nodes where temporaries are created.
+///
+/// Example matches FunctionTakesString(GetStringByValue())
+///     (matcher = bindTemporaryExpr())
+/// \code
+///   FunctionTakesString(GetStringByValue());
+///   FunctionTakesStringByPointer(GetStringPointer());
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXBindTemporaryExpr> bindTemporaryExpr;
+
+/// \brief Matches nodes where temporaries are materialized.
+///
+/// Example: Given
+/// \code
+///   struct T {void func()};
+///   T f();
+///   void g(T);
+/// \endcode
+/// materializeTemporaryExpr() matches 'f()' in these statements
+/// \code
+///   T u(f());
+///   g(f());
+/// \endcode
+/// but does not match
+/// \code
+///   f();
+///   f().func();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  MaterializeTemporaryExpr> materializeTemporaryExpr;
+
+/// \brief Matches new expressions.
+///
+/// Given
+/// \code
+///   new X;
+/// \endcode
+/// newExpr()
+///   matches 'new X'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> newExpr;
+
+/// \brief Matches delete expressions.
+///
+/// Given
+/// \code
+///   delete X;
+/// \endcode
+/// deleteExpr()
+///   matches 'delete X'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> deleteExpr;
+
+/// \brief Matches array subscript expressions.
+///
+/// Given
+/// \code
+///   int i = a[1];
+/// \endcode
+/// arraySubscriptExpr()
+///   matches "a[1]"
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  ArraySubscriptExpr> arraySubscriptExpr;
+
+/// \brief Matches the value of a default argument at the call site.
+///
+/// Example matches the CXXDefaultArgExpr placeholder inserted for the
+///     default value of the second parameter in the call expression f(42)
+///     (matcher = defaultArgExpr())
+/// \code
+///   void f(int x, int y = 0);
+///   f(42);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXDefaultArgExpr> defaultArgExpr;
+
+/// \brief Matches overloaded operator calls.
+///
+/// Note that if an operator isn't overloaded, it won't match. Instead, use
+/// binaryOperator matcher.
+/// Currently it does not match operators such as new delete.
+/// FIXME: figure out why these do not match?
+///
+/// Example matches both operator<<((o << b), c) and operator<<(o, b)
+///     (matcher = operatorCallExpr())
+/// \code
+///   ostream &operator<< (ostream &out, int i) { };
+///   ostream &o; int b = 1, c = 1;
+///   o << b << c;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXOperatorCallExpr> operatorCallExpr;
+
+/// \brief Matches expressions.
+///
+/// Example matches x()
+/// \code
+///   void f() { x(); }
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
+
+/// \brief Matches expressions that refer to declarations.
+///
+/// Example matches x in if (x)
+/// \code
+///   bool x;
+///   if (x) {}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
+
+/// \brief Matches if statements.
+///
+/// Example matches 'if (x) {}'
+/// \code
+///   if (x) {}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
+
+/// \brief Matches for statements.
+///
+/// Example matches 'for (;;) {}'
+/// \code
+///   for (;;) {}
+///   int i[] =  {1, 2, 3}; for (auto a : i);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
+
+/// \brief Matches the increment statement of a for loop.
+///
+/// Example:
+///     forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
+/// matches '++x' in
+/// \code
+///     for (x; x < N; ++x) { }
+/// \endcode
+AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
+              InnerMatcher) {
+  const Stmt *const Increment = Node.getInc();
+  return (Increment != nullptr &&
+          InnerMatcher.matches(*Increment, Finder, Builder));
+}
+
+/// \brief Matches the initialization statement of a for loop.
+///
+/// Example:
+///     forStmt(hasLoopInit(declStmt()))
+/// matches 'int x = 0' in
+/// \code
+///     for (int x = 0; x < N; ++x) { }
+/// \endcode
+AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
+              InnerMatcher) {
+  const Stmt *const Init = Node.getInit();
+  return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
+}
+
+/// \brief Matches range-based for statements.
+///
+/// forRangeStmt() matches 'for (auto a : i)'
+/// \code
+///   int i[] =  {1, 2, 3}; for (auto a : i);
+///   for(int j = 0; j < 5; ++j);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
+
+/// \brief Matches the initialization statement of a for loop.
+///
+/// Example:
+///     forStmt(hasLoopVariable(anything()))
+/// matches 'int x' in
+/// \code
+///     for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
+              InnerMatcher) {
+  const VarDecl *const Var = Node.getLoopVariable();
+  return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
+}
+
+/// \brief Matches the range initialization statement of a for loop.
+///
+/// Example:
+///     forStmt(hasRangeInit(anything()))
+/// matches 'a' in
+/// \code
+///     for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
+              InnerMatcher) {
+  const Expr *const Init = Node.getRangeInit();
+  return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
+}
+
+/// \brief Matches while statements.
+///
+/// Given
+/// \code
+///   while (true) {}
+/// \endcode
+/// whileStmt()
+///   matches 'while (true) {}'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
+
+/// \brief Matches do statements.
+///
+/// Given
+/// \code
+///   do {} while (true);
+/// \endcode
+/// doStmt()
+///   matches 'do {} while(true)'
+const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
+
+/// \brief Matches break statements.
+///
+/// Given
+/// \code
+///   while (true) { break; }
+/// \endcode
+/// breakStmt()
+///   matches 'break'
+const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
+
+/// \brief Matches continue statements.
+///
+/// Given
+/// \code
+///   while (true) { continue; }
+/// \endcode
+/// continueStmt()
+///   matches 'continue'
+const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
+
+/// \brief Matches return statements.
+///
+/// Given
+/// \code
+///   return 1;
+/// \endcode
+/// returnStmt()
+///   matches 'return 1'
+const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
+
+/// \brief Matches goto statements.
+///
+/// Given
+/// \code
+///   goto FOO;
+///   FOO: bar();
+/// \endcode
+/// gotoStmt()
+///   matches 'goto FOO'
+const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
+
+/// \brief Matches label statements.
+///
+/// Given
+/// \code
+///   goto FOO;
+///   FOO: bar();
+/// \endcode
+/// labelStmt()
+///   matches 'FOO:'
+const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
+
+/// \brief Matches switch statements.
+///
+/// Given
+/// \code
+///   switch(a) { case 42: break; default: break; }
+/// \endcode
+/// switchStmt()
+///   matches 'switch(a)'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
+
+/// \brief Matches case and default statements inside switch statements.
+///
+/// Given
+/// \code
+///   switch(a) { case 42: break; default: break; }
+/// \endcode
+/// switchCase()
+///   matches 'case 42: break;' and 'default: break;'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
+
+/// \brief Matches case statements inside switch statements.
+///
+/// Given
+/// \code
+///   switch(a) { case 42: break; default: break; }
+/// \endcode
+/// caseStmt()
+///   matches 'case 42: break;'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
+
+/// \brief Matches default statements inside switch statements.
+///
+/// Given
+/// \code
+///   switch(a) { case 42: break; default: break; }
+/// \endcode
+/// defaultStmt()
+///   matches 'default: break;'.
+const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
+
+/// \brief Matches compound statements.
+///
+/// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
+/// \code
+///   for (;;) {{}}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
+
+/// \brief Matches catch statements.
+///
+/// \code
+///   try {} catch(int i) {}
+/// \endcode
+/// catchStmt()
+///   matches 'catch(int i)'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> catchStmt;
+
+/// \brief Matches try statements.
+///
+/// \code
+///   try {} catch(int i) {}
+/// \endcode
+/// tryStmt()
+///   matches 'try {}'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> tryStmt;
+
+/// \brief Matches throw expressions.
+///
+/// \code
+///   try { throw 5; } catch(int i) {}
+/// \endcode
+/// throwExpr()
+///   matches 'throw 5'
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> throwExpr;
+
+/// \brief Matches null statements.
+///
+/// \code
+///   foo();;
+/// \endcode
+/// nullStmt()
+///   matches the second ';'
+const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
+
+/// \brief Matches asm statements.
+///
+/// \code
+///  int i = 100;
+///   __asm("mov al, 2");
+/// \endcode
+/// asmStmt()
+///   matches '__asm("mov al, 2")'
+const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
+
+/// \brief Matches bool literals.
+///
+/// Example matches true
+/// \code
+///   true
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXBoolLiteralExpr> boolLiteral;
+
+/// \brief Matches string literals (also matches wide string literals).
+///
+/// Example matches "abcd", L"abcd"
+/// \code
+///   char *s = "abcd"; wchar_t *ws = L"abcd"
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  StringLiteral> stringLiteral;
+
+/// \brief Matches character literals (also matches wchar_t).
+///
+/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
+/// though.
+///
+/// Example matches 'a', L'a'
+/// \code
+///   char ch = 'a'; wchar_t chw = L'a';
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CharacterLiteral> characterLiteral;
+
+/// \brief Matches integer literals of all sizes / encodings, e.g.
+/// 1, 1L, 0x1 and 1U.
+///
+/// Does not match character-encoded integers such as L'a'.
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  IntegerLiteral> integerLiteral;
+
+/// \brief Matches float literals of all sizes / encodings, e.g.
+/// 1.0, 1.0f, 1.0L and 1e10.
+///
+/// Does not match implicit conversions such as
+/// \code
+///   float a = 10;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  FloatingLiteral> floatLiteral;
+
+/// \brief Matches user defined literal operator call.
+///
+/// Example match: "foo"_suffix
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  UserDefinedLiteral> userDefinedLiteral;
+
+/// \brief Matches compound (i.e. non-scalar) literals
+///
+/// Example match: {1}, (1, 2)
+/// \code
+///   int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CompoundLiteralExpr> compoundLiteralExpr;
+
+/// \brief Matches nullptr literal.
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXNullPtrLiteralExpr> nullPtrLiteralExpr;
+
+/// \brief Matches binary operator expressions.
+///
+/// Example matches a || b
+/// \code
+///   !(a || b)
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  BinaryOperator> binaryOperator;
+
+/// \brief Matches unary operator expressions.
+///
+/// Example matches !a
+/// \code
+///   !a || b
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  UnaryOperator> unaryOperator;
+
+/// \brief Matches conditional operator expressions.
+///
+/// Example matches a ? b : c
+/// \code
+///   (a ? b : c) + 42
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  ConditionalOperator> conditionalOperator;
+
+/// \brief Matches a reinterpret_cast expression.
+///
+/// Either the source expression or the destination type can be matched
+/// using has(), but hasDestinationType() is more specific and can be
+/// more readable.
+///
+/// Example matches reinterpret_cast<char*>(&p) in
+/// \code
+///   void* p = reinterpret_cast<char*>(&p);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXReinterpretCastExpr> reinterpretCastExpr;
+
+/// \brief Matches a C++ static_cast expression.
+///
+/// \see hasDestinationType
+/// \see reinterpretCast
+///
+/// Example:
+///   staticCastExpr()
+/// matches
+///   static_cast<long>(8)
+/// in
+/// \code
+///   long eight(static_cast<long>(8));
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXStaticCastExpr> staticCastExpr;
+
+/// \brief Matches a dynamic_cast expression.
+///
+/// Example:
+///   dynamicCastExpr()
+/// matches
+///   dynamic_cast<D*>(&b);
+/// in
+/// \code
+///   struct B { virtual ~B() {} }; struct D : B {};
+///   B b;
+///   D* p = dynamic_cast<D*>(&b);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXDynamicCastExpr> dynamicCastExpr;
+
+/// \brief Matches a const_cast expression.
+///
+/// Example: Matches const_cast<int*>(&r) in
+/// \code
+///   int n = 42;
+///   const int &r(n);
+///   int* p = const_cast<int*>(&r);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXConstCastExpr> constCastExpr;
+
+/// \brief Matches a C-style cast expression.
+///
+/// Example: Matches (int*) 2.2f in
+/// \code
+///   int i = (int) 2.2f;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CStyleCastExpr> cStyleCastExpr;
+
+/// \brief Matches explicit cast expressions.
+///
+/// Matches any cast expression written in user code, whether it be a
+/// C-style cast, a functional-style cast, or a keyword cast.
+///
+/// Does not match implicit conversions.
+///
+/// Note: the name "explicitCast" is chosen to match Clang's terminology, as
+/// Clang uses the term "cast" to apply to implicit conversions as well as to
+/// actual cast expressions.
+///
+/// \see hasDestinationType.
+///
+/// Example: matches all five of the casts in
+/// \code
+///   int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
+/// \endcode
+/// but does not match the implicit conversion in
+/// \code
+///   long ell = 42;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  ExplicitCastExpr> explicitCastExpr;
+
+/// \brief Matches the implicit cast nodes of Clang's AST.
+///
+/// This matches many different places, including function call return value
+/// eliding, as well as any type conversions.
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  ImplicitCastExpr> implicitCastExpr;
+
+/// \brief Matches any cast nodes of Clang's AST.
+///
+/// Example: castExpr() matches each of the following:
+/// \code
+///   (int) 3;
+///   const_cast<Expr *>(SubExpr);
+///   char c = 0;
+/// \endcode
+/// but does not match
+/// \code
+///   int i = (0);
+///   int k = 0;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
+
+/// \brief Matches functional cast expressions
+///
+/// Example: Matches Foo(bar);
+/// \code
+///   Foo f = bar;
+///   Foo g = (Foo) bar;
+///   Foo h = Foo(bar);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXFunctionalCastExpr> functionalCastExpr;
+
+/// \brief Matches functional cast expressions having N != 1 arguments
+///
+/// Example: Matches Foo(bar, bar)
+/// \code
+///   Foo h = Foo(bar, bar);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  CXXTemporaryObjectExpr> temporaryObjectExpr;
+
+/// \brief Matches \c QualTypes in the clang AST.
+const internal::VariadicAllOfMatcher<QualType> qualType;
+
+/// \brief Matches \c Types in the clang AST.
+const internal::VariadicAllOfMatcher<Type> type;
+
+/// \brief Matches \c TypeLocs in the clang AST.
+const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
+
+/// \brief Matches if any of the given matchers matches.
+///
+/// Unlike \c anyOf, \c eachOf will generate a match result for each
+/// matching submatcher.
+///
+/// For example, in:
+/// \code
+///   class A { int a; int b; };
+/// \endcode
+/// The matcher:
+/// \code
+///   recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
+///                     has(fieldDecl(hasName("b")).bind("v"))))
+/// \endcode
+/// will generate two results binding "v", the first of which binds
+/// the field declaration of \c a, the second the field declaration of
+/// \c b.
+///
+/// Usable as: Any Matcher
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
+  internal::EachOfVariadicOperator
+};
+
+/// \brief Matches if any of the given matchers matches.
+///
+/// Usable as: Any Matcher
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
+  internal::AnyOfVariadicOperator
+};
+
+/// \brief Matches if all given matchers match.
+///
+/// Usable as: Any Matcher
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
+  internal::AllOfVariadicOperator
+};
+
+/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
+///
+/// Given
+/// \code
+///   Foo x = bar;
+///   int y = sizeof(x) + alignof(x);
+/// \endcode
+/// unaryExprOrTypeTraitExpr()
+///   matches \c sizeof(x) and \c alignof(x)
+const internal::VariadicDynCastAllOfMatcher<
+  Stmt,
+  UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr;
+
+/// \brief Matches unary expressions that have a specific type of argument.
+///
+/// Given
+/// \code
+///   int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
+/// \endcode
+/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
+///   matches \c sizeof(a) and \c alignof(c)
+AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  const QualType ArgumentType = Node.getTypeOfArgument();
+  return InnerMatcher.matches(ArgumentType, Finder, Builder);
+}
+
+/// \brief Matches unary expressions of a certain kind.
+///
+/// Given
+/// \code
+///   int x;
+///   int s = sizeof(x) + alignof(x)
+/// \endcode
+/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
+///   matches \c sizeof(x)
+AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
+  return Node.getKind() == Kind;
+}
+
+/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// alignof.
+inline internal::Matcher<Stmt> alignOfExpr(
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
+  return stmt(unaryExprOrTypeTraitExpr(allOf(
+      ofKind(UETT_AlignOf), InnerMatcher)));
+}
+
+/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
+/// sizeof.
+inline internal::Matcher<Stmt> sizeOfExpr(
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
+  return stmt(unaryExprOrTypeTraitExpr(
+      allOf(ofKind(UETT_SizeOf), InnerMatcher)));
+}
+
+/// \brief Matches NamedDecl nodes that have the specified name.
+///
+/// Supports specifying enclosing namespaces or classes by prefixing the name
+/// with '<enclosing>::'.
+/// Does not match typedefs of an underlying type with the given name.
+///
+/// Example matches X (Name == "X")
+/// \code
+///   class X;
+/// \endcode
+///
+/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
+/// \code
+///   namespace a { namespace b { class X; } }
+/// \endcode
+AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
+  assert(!Name.empty());
+  const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
+  const StringRef FullName = FullNameString;
+  const StringRef Pattern = Name;
+  if (Pattern.startswith("::")) {
+    return FullName == Pattern;
+  } else {
+    return FullName.endswith(("::" + Pattern).str());
+  }
+}
+
+/// \brief Matches NamedDecl nodes whose fully qualified names contain
+/// a substring matched by the given RegExp.
+///
+/// Supports specifying enclosing namespaces or classes by
+/// prefixing the name with '<enclosing>::'.  Does not match typedefs
+/// of an underlying type with the given name.
+///
+/// Example matches X (regexp == "::X")
+/// \code
+///   class X;
+/// \endcode
+///
+/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
+/// \code
+///   namespace foo { namespace bar { class X; } }
+/// \endcode
+AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
+  assert(!RegExp.empty());
+  std::string FullNameString = "::" + Node.getQualifiedNameAsString();
+  llvm::Regex RE(RegExp);
+  return RE.match(FullNameString);
+}
+
+/// \brief Matches overloaded operator names.
+///
+/// Matches overloaded operator names specified in strings without the
+/// "operator" prefix: e.g. "<<".
+///
+/// Given:
+/// \code
+///   class A { int operator*(); };
+///   const A &operator<<(const A &a, const A &b);
+///   A a;
+///   a << a;   // <-- This matches
+/// \endcode
+///
+/// \c operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified
+/// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
+/// the declaration of \c A.
+///
+/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
+inline internal::PolymorphicMatcherWithParam1<
+    internal::HasOverloadedOperatorNameMatcher, StringRef,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
+hasOverloadedOperatorName(const StringRef Name) {
+  return internal::PolymorphicMatcherWithParam1<
+      internal::HasOverloadedOperatorNameMatcher, StringRef,
+      AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
+      Name);
+}
+
+/// \brief Matches C++ classes that are directly or indirectly derived from
+/// a class matching \c Base.
+///
+/// Note that a class is not considered to be derived from itself.
+///
+/// Example matches Y, Z, C (Base == hasName("X"))
+/// \code
+///   class X;
+///   class Y : public X {};  // directly derived
+///   class Z : public Y {};  // indirectly derived
+///   typedef X A;
+///   typedef A B;
+///   class C : public B {};  // derived from a typedef of X
+/// \endcode
+///
+/// In the following example, Bar matches isDerivedFrom(hasName("X")):
+/// \code
+///   class Foo;
+///   typedef Foo X;
+///   class Bar : public Foo {};  // derived from a type that X is a typedef of
+/// \endcode
+AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
+              internal::Matcher<NamedDecl>, Base) {
+  return Finder->classIsDerivedFrom(&Node, Base, Builder);
+}
+
+/// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
+AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, StringRef, BaseName, 1) {
+  assert(!BaseName.empty());
+  return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
+}
+
+/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly
+/// match \c Base.
+AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom,
+                       internal::Matcher<NamedDecl>, Base, 0) {
+  return Matcher<CXXRecordDecl>(anyOf(Base, isDerivedFrom(Base)))
+      .matches(Node, Finder, Builder);
+}
+
+/// \brief Overloaded method as shortcut for
+/// \c isSameOrDerivedFrom(hasName(...)).
+AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, StringRef, BaseName,
+                       1) {
+  assert(!BaseName.empty());
+  return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
+}
+
+/// \brief Matches the first method of a class or struct that satisfies \c
+/// InnerMatcher.
+///
+/// Given:
+/// \code
+///   class A { void func(); };
+///   class B { void member(); };
+/// \code
+///
+/// \c recordDecl(hasMethod(hasName("func"))) matches the declaration of \c A
+/// but not \c B.
+AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
+              InnerMatcher) {
+  return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
+                                    Node.method_end(), Finder, Builder);
+}
+
+/// \brief Matches AST nodes that have child AST nodes that match the
+/// provided matcher.
+///
+/// Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
+/// \code
+///   class X {};  // Matches X, because X::X is a class of name X inside X.
+///   class Y { class X {}; };
+///   class Z { class Y { class X {}; }; };  // Does not match Z.
+/// \endcode
+///
+/// ChildT must be an AST base type.
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher>
+LLVM_ATTRIBUTE_UNUSED has = {};
+
+/// \brief Matches AST nodes that have descendant AST nodes that match the
+/// provided matcher.
+///
+/// Example matches X, Y, Z
+///     (matcher = recordDecl(hasDescendant(recordDecl(hasName("X")))))
+/// \code
+///   class X {};  // Matches X, because X::X is a class of name X inside X.
+///   class Y { class X {}; };
+///   class Z { class Y { class X {}; }; };
+/// \endcode
+///
+/// DescendantT must be an AST base type.
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
+LLVM_ATTRIBUTE_UNUSED hasDescendant = {};
+
+/// \brief Matches AST nodes that have child AST nodes that match the
+/// provided matcher.
+///
+/// Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X")))
+/// \code
+///   class X {};  // Matches X, because X::X is a class of name X inside X.
+///   class Y { class X {}; };
+///   class Z { class Y { class X {}; }; };  // Does not match Z.
+/// \endcode
+///
+/// ChildT must be an AST base type.
+///
+/// As opposed to 'has', 'forEach' will cause a match for each result that
+/// matches instead of only on the first one.
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
+LLVM_ATTRIBUTE_UNUSED forEach = {};
+
+/// \brief Matches AST nodes that have descendant AST nodes that match the
+/// provided matcher.
+///
+/// Example matches X, A, B, C
+///     (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X")))))
+/// \code
+///   class X {};  // Matches X, because X::X is a class of name X inside X.
+///   class A { class X {}; };
+///   class B { class C { class X {}; }; };
+/// \endcode
+///
+/// DescendantT must be an AST base type.
+///
+/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
+/// each result that matches instead of only on the first one.
+///
+/// Note: Recursively combined ForEachDescendant can cause many matches:
+///   recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl()))))
+/// will match 10 times (plus injected class name matches) on:
+/// \code
+///   class A { class B { class C { class D { class E {}; }; }; }; };
+/// \endcode
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
+LLVM_ATTRIBUTE_UNUSED forEachDescendant = {};
+
+/// \brief Matches if the node or any descendant matches.
+///
+/// Generates results for each match.
+///
+/// For example, in:
+/// \code
+///   class A { class B {}; class C {}; };
+/// \endcode
+/// The matcher:
+/// \code
+///   recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m")))
+/// \endcode
+/// will generate results for \c A, \c B and \c C.
+///
+/// Usable as: Any Matcher
+template <typename T>
+internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
+  return eachOf(Matcher, forEachDescendant(Matcher));
+}
+
+/// \brief Matches AST nodes that have a parent that matches the provided
+/// matcher.
+///
+/// Given
+/// \code
+/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
+/// \endcode
+/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<
+    internal::HasParentMatcher, internal::TypeList<Decl, Stmt>,
+    internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasParent = {};
+
+/// \brief Matches AST nodes that have an ancestor that matches the provided
+/// matcher.
+///
+/// Given
+/// \code
+/// void f() { if (true) { int x = 42; } }
+/// void g() { for (;;) { int x = 43; } }
+/// \endcode
+/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
+///
+/// Usable as: Any Matcher
+const internal::ArgumentAdaptingMatcherFunc<
+    internal::HasAncestorMatcher, internal::TypeList<Decl, Stmt>,
+    internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasAncestor = {};
+
+/// \brief Matches if the provided matcher does not match.
+///
+/// Example matches Y (matcher = recordDecl(unless(hasName("X"))))
+/// \code
+///   class X {};
+///   class Y {};
+/// \endcode
+///
+/// Usable as: Any Matcher
+const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
+  internal::NotUnaryOperator
+};
+
+/// \brief Matches a node if the declaration associated with that node
+/// matches the given matcher.
+///
+/// The associated declaration is:
+/// - for type nodes, the declaration of the underlying type
+/// - for CallExpr, the declaration of the callee
+/// - for MemberExpr, the declaration of the referenced member
+/// - for CXXConstructExpr, the declaration of the constructor
+///
+/// Also usable as Matcher<T> for any T supporting the getDecl() member
+/// function. e.g. various subtypes of clang::Type and various expressions.
+///
+/// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
+///   Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
+///   Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
+///   Matcher<RecordType>, Matcher<TagType>,
+///   Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
+///   Matcher<TypedefType>, Matcher<UnresolvedUsingType>
+inline internal::PolymorphicMatcherWithParam1<
+    internal::HasDeclarationMatcher, internal::Matcher<Decl>,
+    void(internal::HasDeclarationSupportedTypes)>
+hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
+  return internal::PolymorphicMatcherWithParam1<
+      internal::HasDeclarationMatcher, internal::Matcher<Decl>,
+      void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
+}
+
+/// \brief Matches on the implicit object argument of a member call expression.
+///
+/// Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y"))))))
+/// \code
+///   class Y { public: void x(); };
+///   void z() { Y y; y.x(); }",
+/// \endcode
+///
+/// FIXME: Overload to allow directly matching types?
+AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
+              InnerMatcher) {
+  const Expr *ExprNode = Node.getImplicitObjectArgument()
+                            ->IgnoreParenImpCasts();
+  return (ExprNode != nullptr &&
+          InnerMatcher.matches(*ExprNode, Finder, Builder));
+}
+
+/// \brief Matches if the call expression's callee expression matches.
+///
+/// Given
+/// \code
+///   class Y { void x() { this->x(); x(); Y y; y.x(); } };
+///   void f() { f(); }
+/// \endcode
+/// callExpr(callee(expr()))
+///   matches this->x(), x(), y.x(), f()
+/// with callee(...)
+///   matching this->x, x, y.x, f respectively
+///
+/// Note: Callee cannot take the more general internal::Matcher<Expr>
+/// because this introduces ambiguous overloads with calls to Callee taking a
+/// internal::Matcher<Decl>, as the matcher hierarchy is purely
+/// implemented in terms of implicit casts.
+AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
+              InnerMatcher) {
+  const Expr *ExprNode = Node.getCallee();
+  return (ExprNode != nullptr &&
+          InnerMatcher.matches(*ExprNode, Finder, Builder));
+}
+
+/// \brief Matches if the call expression's callee's declaration matches the
+/// given matcher.
+///
+/// Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x")))))
+/// \code
+///   class Y { public: void x(); };
+///   void z() { Y y; y.x();
+/// \endcode
+AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
+                       1) {
+  return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
+}
+
+/// \brief Matches if the expression's or declaration's type matches a type
+/// matcher.
+///
+/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+///             and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+/// \code
+///  class X {};
+///  void y(X &x) { x; X z; }
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
+    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
+    internal::Matcher<QualType>, InnerMatcher, 0) {
+  return InnerMatcher.matches(Node.getType(), Finder, Builder);
+}
+
+/// \brief Overloaded to match the declaration of the expression's or value
+/// declaration's type.
+///
+/// In case of a value declaration (for example a variable declaration),
+/// this resolves one layer of indirection. For example, in the value
+/// declaration "X x;", recordDecl(hasName("X")) matches the declaration of X,
+/// while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration
+/// of x."
+///
+/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+///             and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+/// \code
+///  class X {};
+///  void y(X &x) { x; X z; }
+/// \endcode
+///
+/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
+    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
+    internal::Matcher<Decl>, InnerMatcher, 1) {
+  return qualType(hasDeclaration(InnerMatcher))
+      .matches(Node.getType(), Finder, Builder);
+}
+
+/// \brief Matches if the type location of the declarator decl's type matches
+/// the inner matcher.
+///
+/// Given
+/// \code
+///   int x;
+/// \endcode
+/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
+///   matches int x
+AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) {
+  if (!Node.getTypeSourceInfo())
+    // This happens for example for implicit destructors.
+    return false;
+  return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder);
+}
+
+/// \brief Matches if the matched type is represented by the given string.
+///
+/// Given
+/// \code
+///   class Y { public: void x(); };
+///   void z() { Y* y; y->x(); }
+/// \endcode
+/// callExpr(on(hasType(asString("class Y *"))))
+///   matches y->x()
+AST_MATCHER_P(QualType, asString, std::string, Name) {
+  return Name == Node.getAsString();
+}
+
+/// \brief Matches if the matched type is a pointer type and the pointee type
+/// matches the specified matcher.
+///
+/// Example matches y->x()
+///     (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))))
+/// \code
+///   class Y { public: void x(); };
+///   void z() { Y *y; y->x(); }
+/// \endcode
+AST_MATCHER_P(
+    QualType, pointsTo, internal::Matcher<QualType>,
+    InnerMatcher) {
+  return (!Node.isNull() && Node->isPointerType() &&
+          InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
+}
+
+/// \brief Overloaded to match the pointee type's declaration.
+AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,
+                       InnerMatcher, 1) {
+  return pointsTo(qualType(hasDeclaration(InnerMatcher)))
+      .matches(Node, Finder, Builder);
+}
+
+/// \brief Matches if the matched type is a reference type and the referenced
+/// type matches the specified matcher.
+///
+/// Example matches X &x and const X &y
+///     (matcher = varDecl(hasType(references(recordDecl(hasName("X"))))))
+/// \code
+///   class X {
+///     void a(X b) {
+///       X &x = b;
+///       const X &y = b;
+///   };
+/// \endcode
+AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
+              InnerMatcher) {
+  return (!Node.isNull() && Node->isReferenceType() &&
+          InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
+}
+
+/// \brief Matches QualTypes whose canonical type matches InnerMatcher.
+///
+/// Given:
+/// \code
+///   typedef int &int_ref;
+///   int a;
+///   int_ref b = a;
+/// \code
+///
+/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
+/// declaration of b but \c
+/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
+AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,
+              InnerMatcher) {
+  if (Node.isNull())
+    return false;
+  return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
+}
+
+/// \brief Overloaded to match the referenced type's declaration.
+AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
+                       InnerMatcher, 1) {
+  return references(qualType(hasDeclaration(InnerMatcher)))
+      .matches(Node, Finder, Builder);
+}
+
+AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr *ExprNode = Node.getImplicitObjectArgument();
+  return (ExprNode != nullptr &&
+          InnerMatcher.matches(*ExprNode, Finder, Builder));
+}
+
+/// \brief Matches if the expression's type either matches the specified
+/// matcher, or is a pointer to a type that matches the InnerMatcher.
+AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
+                       internal::Matcher<QualType>, InnerMatcher, 0) {
+  return onImplicitObjectArgument(
+      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
+      .matches(Node, Finder, Builder);
+}
+
+/// \brief Overloaded to match the type's declaration.
+AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
+                       internal::Matcher<Decl>, InnerMatcher, 1) {
+  return onImplicitObjectArgument(
+      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
+      .matches(Node, Finder, Builder);
+}
+
+/// \brief Matches a DeclRefExpr that refers to a declaration that matches the
+/// specified matcher.
+///
+/// Example matches x in if(x)
+///     (matcher = declRefExpr(to(varDecl(hasName("x")))))
+/// \code
+///   bool x;
+///   if (x) {}
+/// \endcode
+AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
+              InnerMatcher) {
+  const Decl *DeclNode = Node.getDecl();
+  return (DeclNode != nullptr &&
+          InnerMatcher.matches(*DeclNode, Finder, Builder));
+}
+
+/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
+/// specific using shadow declaration.
+///
+/// FIXME: This currently only works for functions. Fix.
+///
+/// Given
+/// \code
+///   namespace a { void f() {} }
+///   using a::f;
+///   void g() {
+///     f();     // Matches this ..
+///     a::f();  // .. but not this.
+///   }
+/// \endcode
+/// declRefExpr(throughUsingDeclaration(anything()))
+///   matches \c f()
+AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
+              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
+  const NamedDecl *FoundDecl = Node.getFoundDecl();
+  if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
+    return InnerMatcher.matches(*UsingDecl, Finder, Builder);
+  return false;
+}
+
+/// \brief Matches the Decl of a DeclStmt which has a single declaration.
+///
+/// Given
+/// \code
+///   int a, b;
+///   int c;
+/// \endcode
+/// declStmt(hasSingleDecl(anything()))
+///   matches 'int c;' but not 'int a, b;'.
+AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
+  if (Node.isSingleDecl()) {
+    const Decl *FoundDecl = Node.getSingleDecl();
+    return InnerMatcher.matches(*FoundDecl, Finder, Builder);
+  }
+  return false;
+}
+
+/// \brief Matches a variable declaration that has an initializer expression
+/// that matches the given matcher.
+///
+/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
+/// \code
+///   bool y() { return true; }
+///   bool x = y();
+/// \endcode
+AST_MATCHER_P(
+    VarDecl, hasInitializer, internal::Matcher<Expr>,
+    InnerMatcher) {
+  const Expr *Initializer = Node.getAnyInitializer();
+  return (Initializer != nullptr &&
+          InnerMatcher.matches(*Initializer, Finder, Builder));
+}
+
+/// \brief Matches a variable declaration that has function scope and is a
+/// non-static local variable.
+///
+/// Example matches x (matcher = varDecl(hasLocalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasLocalStorage) {
+  return Node.hasLocalStorage();
+}
+
+/// \brief Matches a variable declaration that does not have local storage.
+///
+/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasGlobalStorage) {
+  return Node.hasGlobalStorage();
+}
+
+/// \brief Checks that a call expression or a constructor call expression has
+/// a specific number of arguments (including absent default arguments).
+///
+/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+/// \code
+///   void f(int x, int y);
+///   f(0, 0);
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
+                                               CallExpr, CXXConstructExpr),
+                          unsigned, N) {
+  return Node.getNumArgs() == N;
+}
+
+/// \brief Matches the n'th argument of a call expression or a constructor
+/// call expression.
+///
+/// Example matches y in x(y)
+///     (matcher = callExpr(hasArgument(0, declRefExpr())))
+/// \code
+///   void x(int) { int y; x(y); }
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P2(
+    hasArgument,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr),
+    unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
+  return (N < Node.getNumArgs() &&
+          InnerMatcher.matches(
+              *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
+}
+
+/// \brief Matches declaration statements that contain a specific number of
+/// declarations.
+///
+/// Example: Given
+/// \code
+///   int a, b;
+///   int c;
+///   int d = 2, e;
+/// \endcode
+/// declCountIs(2)
+///   matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
+AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
+  return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
+}
+
+/// \brief Matches the n'th declaration of a declaration statement.
+///
+/// Note that this does not work for global declarations because the AST
+/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
+/// DeclStmt's.
+/// Example: Given non-global declarations
+/// \code
+///   int a, b = 0;
+///   int c;
+///   int d = 2, e;
+/// \endcode
+/// declStmt(containsDeclaration(
+///       0, varDecl(hasInitializer(anything()))))
+///   matches only 'int d = 2, e;', and
+/// declStmt(containsDeclaration(1, varDecl()))
+/// \code
+///   matches 'int a, b = 0' as well as 'int d = 2, e;'
+///   but 'int c;' is not matched.
+/// \endcode
+AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
+               internal::Matcher<Decl>, InnerMatcher) {
+  const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
+  if (N >= NumDecls)
+    return false;
+  DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
+  std::advance(Iterator, N);
+  return InnerMatcher.matches(**Iterator, Finder, Builder);
+}
+
+/// \brief Matches a constructor initializer.
+///
+/// Given
+/// \code
+///   struct Foo {
+///     Foo() : foo_(1) { }
+///     int foo_;
+///   };
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything()))))
+///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
+AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
+              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
+  return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
+                                    Node.init_end(), Finder, Builder);
+}
+
+/// \brief Matches the field declaration of a constructor initializer.
+///
+/// Given
+/// \code
+///   struct Foo {
+///     Foo() : foo_(1) { }
+///     int foo_;
+///   };
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(
+///     forField(hasName("foo_"))))))
+///   matches Foo
+/// with forField matching foo_
+AST_MATCHER_P(CXXCtorInitializer, forField,
+              internal::Matcher<FieldDecl>, InnerMatcher) {
+  const FieldDecl *NodeAsDecl = Node.getMember();
+  return (NodeAsDecl != nullptr &&
+      InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
+}
+
+/// \brief Matches the initializer expression of a constructor initializer.
+///
+/// Given
+/// \code
+///   struct Foo {
+///     Foo() : foo_(1) { }
+///     int foo_;
+///   };
+/// \endcode
+/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(
+///     withInitializer(integerLiteral(equals(1)))))))
+///   matches Foo
+/// with withInitializer matching (1)
+AST_MATCHER_P(CXXCtorInitializer, withInitializer,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr* NodeAsExpr = Node.getInit();
+  return (NodeAsExpr != nullptr &&
+      InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
+}
+
+/// \brief Matches a constructor initializer if it is explicitly written in
+/// code (as opposed to implicitly added by the compiler).
+///
+/// Given
+/// \code
+///   struct Foo {
+///     Foo() { }
+///     Foo(int) : foo_("A") { }
+///     string foo_;
+///   };
+/// \endcode
+/// constructorDecl(hasAnyConstructorInitializer(isWritten()))
+///   will match Foo(int), but not Foo()
+AST_MATCHER(CXXCtorInitializer, isWritten) {
+  return Node.isWritten();
+}
+
+/// \brief Matches any argument of a call expression or a constructor call
+/// expression.
+///
+/// Given
+/// \code
+///   void x(int, int, int) { int y; x(1, y, 42); }
+/// \endcode
+/// callExpr(hasAnyArgument(declRefExpr()))
+///   matches x(1, y, 42)
+/// with hasAnyArgument(...)
+///   matching y
+///
+/// FIXME: Currently this will ignore parentheses and implicit casts on
+/// the argument before applying the inner matcher. We'll want to remove
+/// this to allow for greater control by the user once \c ignoreImplicit()
+/// has been implemented.
+AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
+                                              CallExpr, CXXConstructExpr),
+                          internal::Matcher<Expr>, InnerMatcher) {
+  for (unsigned I = 0; I < Node.getNumArgs(); ++I) {
+    BoundNodesTreeBuilder Result(*Builder);
+    if (InnerMatcher.matches(*Node.getArg(I)->IgnoreParenImpCasts(), Finder,
+                             &Result)) {
+      *Builder = Result;
+      return true;
+    }
+  }
+  return false;
+}
+
+/// \brief Matches a constructor call expression which uses list initialization.
+AST_MATCHER(CXXConstructExpr, isListInitialization) {
+  return Node.isListInitialization();
+}
+
+/// \brief Matches the n'th parameter of a function declaration.
+///
+/// Given
+/// \code
+///   class X { void f(int x) {} };
+/// \endcode
+/// methodDecl(hasParameter(0, hasType(varDecl())))
+///   matches f(int x) {}
+/// with hasParameter(...)
+///   matching int x
+AST_MATCHER_P2(FunctionDecl, hasParameter,
+               unsigned, N, internal::Matcher<ParmVarDecl>,
+               InnerMatcher) {
+  return (N < Node.getNumParams() &&
+          InnerMatcher.matches(
+              *Node.getParamDecl(N), Finder, Builder));
+}
+
+/// \brief Matches any parameter of a function declaration.
+///
+/// Does not match the 'this' parameter of a method.
+///
+/// Given
+/// \code
+///   class X { void f(int x, int y, int z) {} };
+/// \endcode
+/// methodDecl(hasAnyParameter(hasName("y")))
+///   matches f(int x, int y, int z) {}
+/// with hasAnyParameter(...)
+///   matching int y
+AST_MATCHER_P(FunctionDecl, hasAnyParameter,
+              internal::Matcher<ParmVarDecl>, InnerMatcher) {
+  return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
+                                    Node.param_end(), Finder, Builder);
+}
+
+/// \brief Matches \c FunctionDecls that have a specific parameter count.
+///
+/// Given
+/// \code
+///   void f(int i) {}
+///   void g(int i, int j) {}
+/// \endcode
+/// functionDecl(parameterCountIs(2))
+///   matches g(int i, int j) {}
+AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) {
+  return Node.getNumParams() == N;
+}
+
+/// \brief Matches the return type of a function declaration.
+///
+/// Given:
+/// \code
+///   class X { int f() { return 1; } };
+/// \endcode
+/// methodDecl(returns(asString("int")))
+///   matches int f() { return 1; }
+AST_MATCHER_P(FunctionDecl, returns,
+              internal::Matcher<QualType>, InnerMatcher) {
+  return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
+}
+
+/// \brief Matches extern "C" function declarations.
+///
+/// Given:
+/// \code
+///   extern "C" void f() {}
+///   extern "C" { void g() {} }
+///   void h() {}
+/// \endcode
+/// functionDecl(isExternC())
+///   matches the declaration of f and g, but not the declaration h
+AST_MATCHER(FunctionDecl, isExternC) {
+  return Node.isExternC();
+}
+
+/// \brief Matches the condition expression of an if statement, for loop,
+/// or conditional operator.
+///
+/// Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+/// \code
+///   if (true) {}
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P(
+    hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5(
+                      IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator),
+    internal::Matcher<Expr>, InnerMatcher) {
+  const Expr *const Condition = Node.getCond();
+  return (Condition != nullptr &&
+          InnerMatcher.matches(*Condition, Finder, Builder));
+}
+
+/// \brief Matches the then-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+/// \code
+///   if (false) true; else false;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
+  const Stmt *const Then = Node.getThen();
+  return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
+}
+
+/// \brief Matches the else-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+/// \code
+///   if (false) false; else true;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
+  const Stmt *const Else = Node.getElse();
+  return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
+}
+
+/// \brief Matches if a node equals a previously bound node.
+///
+/// Matches a node if it equals the node previously bound to \p ID.
+///
+/// Given
+/// \code
+///   class X { int a; int b; };
+/// \endcode
+/// recordDecl(
+///     has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
+///     has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
+///   matches the class \c X, as \c a and \c b have the same type.
+///
+/// Note that when multiple matches are involved via \c forEach* matchers,
+/// \c equalsBoundNodes acts as a filter.
+/// For example:
+/// compoundStmt(
+///     forEachDescendant(varDecl().bind("d")),
+///     forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
+/// will trigger a match for each combination of variable declaration
+/// and reference to that variable declaration within a compound statement.
+AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4(
+                                               Stmt, Decl, Type, QualType),
+                          std::string, ID) {
+  // FIXME: Figure out whether it makes sense to allow this
+  // on any other node types.
+  // For *Loc it probably does not make sense, as those seem
+  // unique. For NestedNameSepcifier it might make sense, as
+  // those also have pointer identity, but I'm not sure whether
+  // they're ever reused.
+  internal::NotEqualsBoundNodePredicate Predicate;
+  Predicate.ID = ID;
+  Predicate.Node = ast_type_traits::DynTypedNode::create(Node);
+  return Builder->removeBindings(Predicate);
+}
+
+/// \brief Matches the condition variable statement in an if statement.
+///
+/// Given
+/// \code
+///   if (A* a = GetAPointer()) {}
+/// \endcode
+/// hasConditionVariableStatement(...)
+///   matches 'A* a = GetAPointer()'.
+AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
+              internal::Matcher<DeclStmt>, InnerMatcher) {
+  const DeclStmt* const DeclarationStatement =
+    Node.getConditionVariableDeclStmt();
+  return DeclarationStatement != nullptr &&
+         InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
+}
+
+/// \brief Matches the index expression of an array subscript expression.
+///
+/// Given
+/// \code
+///   int i[5];
+///   void f() { i[1] = 42; }
+/// \endcode
+/// arraySubscriptExpression(hasIndex(integerLiteral()))
+///   matches \c i[1] with the \c integerLiteral() matching \c 1
+AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
+              internal::Matcher<Expr>, InnerMatcher) {
+  if (const Expr* Expression = Node.getIdx())
+    return InnerMatcher.matches(*Expression, Finder, Builder);
+  return false;
+}
+
+/// \brief Matches the base expression of an array subscript expression.
+///
+/// Given
+/// \code
+///   int i[5];
+///   void f() { i[1] = 42; }
+/// \endcode
+/// arraySubscriptExpression(hasBase(implicitCastExpr(
+///     hasSourceExpression(declRefExpr()))))
+///   matches \c i[1] with the \c declRefExpr() matching \c i
+AST_MATCHER_P(ArraySubscriptExpr, hasBase,
+              internal::Matcher<Expr>, InnerMatcher) {
+  if (const Expr* Expression = Node.getBase())
+    return InnerMatcher.matches(*Expression, Finder, Builder);
+  return false;
+}
+
+/// \brief Matches a 'for', 'while', or 'do while' statement that has
+/// a given body.
+///
+/// Given
+/// \code
+///   for (;;) {}
+/// \endcode
+/// hasBody(compoundStmt())
+///   matches 'for (;;) {}'
+/// with compoundStmt()
+///   matching '{}'
+AST_POLYMORPHIC_MATCHER_P(hasBody,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt,
+                                                            WhileStmt,
+                                                            CXXForRangeStmt),
+                          internal::Matcher<Stmt>, InnerMatcher) {
+  const Stmt *const Statement = Node.getBody();
+  return (Statement != nullptr &&
+          InnerMatcher.matches(*Statement, Finder, Builder));
+}
+
+/// \brief Matches compound statements where at least one substatement matches
+/// a given matcher.
+///
+/// Given
+/// \code
+///   { {}; 1+2; }
+/// \endcode
+/// hasAnySubstatement(compoundStmt())
+///   matches '{ {}; 1+2; }'
+/// with compoundStmt()
+///   matching '{}'
+AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
+              internal::Matcher<Stmt>, InnerMatcher) {
+  return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(),
+                                    Node.body_end(), Finder, Builder);
+}
+
+/// \brief Checks that a compound statement contains a specific number of
+/// child statements.
+///
+/// Example: Given
+/// \code
+///   { for (;;) {} }
+/// \endcode
+/// compoundStmt(statementCountIs(0)))
+///   matches '{}'
+///   but does not match the outer compound statement.
+AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) {
+  return Node.size() == N;
+}
+
+/// \brief Matches literals that are equal to the given value.
+///
+/// Example matches true (matcher = boolLiteral(equals(true)))
+/// \code
+///   true
+/// \endcode
+///
+/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+///            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
+template <typename ValueT>
+internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
+equals(const ValueT &Value) {
+  return internal::PolymorphicMatcherWithParam1<
+    internal::ValueEqualsMatcher,
+    ValueT>(Value);
+}
+
+/// \brief Matches the operator Name of operator expressions (binary or
+/// unary).
+///
+/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+/// \code
+///   !(a || b)
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
+                                               BinaryOperator, UnaryOperator),
+                          std::string, Name) {
+  return Name == Node.getOpcodeStr(Node.getOpcode());
+}
+
+/// \brief Matches the left hand side of binary operator expressions.
+///
+/// Example matches a (matcher = binaryOperator(hasLHS()))
+/// \code
+///   a || b
+/// \endcode
+AST_MATCHER_P(BinaryOperator, hasLHS,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *LeftHandSide = Node.getLHS();
+  return (LeftHandSide != nullptr &&
+          InnerMatcher.matches(*LeftHandSide, Finder, Builder));
+}
+
+/// \brief Matches the right hand side of binary operator expressions.
+///
+/// Example matches b (matcher = binaryOperator(hasRHS()))
+/// \code
+///   a || b
+/// \endcode
+AST_MATCHER_P(BinaryOperator, hasRHS,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *RightHandSide = Node.getRHS();
+  return (RightHandSide != nullptr &&
+          InnerMatcher.matches(*RightHandSide, Finder, Builder));
+}
+
+/// \brief Matches if either the left hand side or the right hand side of a
+/// binary operator matches.
+inline internal::Matcher<BinaryOperator> hasEitherOperand(
+    const internal::Matcher<Expr> &InnerMatcher) {
+  return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher));
+}
+
+/// \brief Matches if the operand of a unary operator matches.
+///
+/// Example matches true (matcher = hasUnaryOperand(boolLiteral(equals(true))))
+/// \code
+///   !true
+/// \endcode
+AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr * const Operand = Node.getSubExpr();
+  return (Operand != nullptr &&
+          InnerMatcher.matches(*Operand, Finder, Builder));
+}
+
+/// \brief Matches if the cast's source expression matches the given matcher.
+///
+/// Example: matches "a string" (matcher =
+///                                  hasSourceExpression(constructExpr()))
+/// \code
+/// class URL { URL(string); };
+/// URL url = "a string";
+AST_MATCHER_P(CastExpr, hasSourceExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  const Expr* const SubExpression = Node.getSubExpr();
+  return (SubExpression != nullptr &&
+          InnerMatcher.matches(*SubExpression, Finder, Builder));
+}
+
+/// \brief Matches casts whose destination type matches a given matcher.
+///
+/// (Note: Clang's AST refers to other conversions as "casts" too, and calls
+/// actual casts "explicit" casts.)
+AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  const QualType NodeType = Node.getTypeAsWritten();
+  return InnerMatcher.matches(NodeType, Finder, Builder);
+}
+
+/// \brief Matches implicit casts whose destination type matches a given
+/// matcher.
+///
+/// FIXME: Unit test this matcher
+AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  return InnerMatcher.matches(Node.getType(), Finder, Builder);
+}
+
+/// \brief Matches the true branch expression of a conditional operator.
+///
+/// Example matches a
+/// \code
+///   condition ? a : b
+/// \endcode
+AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *Expression = Node.getTrueExpr();
+  return (Expression != nullptr &&
+          InnerMatcher.matches(*Expression, Finder, Builder));
+}
+
+/// \brief Matches the false branch expression of a conditional operator.
+///
+/// Example matches b
+/// \code
+///   condition ? a : b
+/// \endcode
+AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  Expr *Expression = Node.getFalseExpr();
+  return (Expression != nullptr &&
+          InnerMatcher.matches(*Expression, Finder, Builder));
+}
+
+/// \brief Matches if a declaration has a body attached.
+///
+/// Example matches A, va, fa
+/// \code
+///   class A {};
+///   class B;  // Doesn't match, as it has no body.
+///   int va;
+///   extern int vb;  // Doesn't match, as it doesn't define the variable.
+///   void fa() {}
+///   void fb();  // Doesn't match, as it has no body.
+/// \endcode
+///
+/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3(
+                                          TagDecl, VarDecl, FunctionDecl)) {
+  return Node.isThisDeclarationADefinition();
+}
+
+/// \brief Matches the class declaration that the given method declaration
+/// belongs to.
+///
+/// FIXME: Generalize this for other kinds of declarations.
+/// FIXME: What other kind of declarations would we need to generalize
+/// this to?
+///
+/// Example matches A() in the last line
+///     (matcher = constructExpr(hasDeclaration(methodDecl(
+///         ofClass(hasName("A"))))))
+/// \code
+///   class A {
+///    public:
+///     A();
+///   };
+///   A a = A();
+/// \endcode
+AST_MATCHER_P(CXXMethodDecl, ofClass,
+              internal::Matcher<CXXRecordDecl>, InnerMatcher) {
+  const CXXRecordDecl *Parent = Node.getParent();
+  return (Parent != nullptr &&
+          InnerMatcher.matches(*Parent, Finder, Builder));
+}
+
+/// \brief Matches if the given method declaration is virtual.
+///
+/// Given
+/// \code
+///   class A {
+///    public:
+///     virtual void x();
+///   };
+/// \endcode
+///   matches A::x
+AST_MATCHER(CXXMethodDecl, isVirtual) {
+  return Node.isVirtual();
+}
+
+/// \brief Matches if the given method declaration is pure.
+///
+/// Given
+/// \code
+///   class A {
+///    public:
+///     virtual void x() = 0;
+///   };
+/// \endcode
+///   matches A::x
+AST_MATCHER(CXXMethodDecl, isPure) {
+  return Node.isPure();
+}
+
+/// \brief Matches if the given method declaration is const.
+///
+/// Given
+/// \code
+/// struct A {
+///   void foo() const;
+///   void bar();
+/// };
+/// \endcode
+///
+/// methodDecl(isConst()) matches A::foo() but not A::bar()
+AST_MATCHER(CXXMethodDecl, isConst) {
+  return Node.isConst();
+}
+
+/// \brief Matches if the given method declaration overrides another method.
+///
+/// Given
+/// \code
+///   class A {
+///    public:
+///     virtual void x();
+///   };
+///   class B : public A {
+///    public:
+///     virtual void x();
+///   };
+/// \endcode
+///   matches B::x
+AST_MATCHER(CXXMethodDecl, isOverride) {
+  return Node.size_overridden_methods() > 0;
+}
+
+/// \brief Matches member expressions that are called with '->' as opposed
+/// to '.'.
+///
+/// Member calls on the implicit this pointer match as called with '->'.
+///
+/// Given
+/// \code
+///   class Y {
+///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
+///     int a;
+///     static int b;
+///   };
+/// \endcode
+/// memberExpr(isArrow())
+///   matches this->x, x, y.x, a, this->b
+AST_MATCHER(MemberExpr, isArrow) {
+  return Node.isArrow();
+}
+
+/// \brief Matches QualType nodes that are of integer type.
+///
+/// Given
+/// \code
+///   void a(int);
+///   void b(long);
+///   void c(double);
+/// \endcode
+/// functionDecl(hasAnyParameter(hasType(isInteger())))
+/// matches "a(int)", "b(long)", but not "c(double)".
+AST_MATCHER(QualType, isInteger) {
+    return Node->isIntegerType();
+}
+
+/// \brief Matches QualType nodes that are const-qualified, i.e., that
+/// include "top-level" const.
+///
+/// Given
+/// \code
+///   void a(int);
+///   void b(int const);
+///   void c(const int);
+///   void d(const int*);
+///   void e(int const) {};
+/// \endcode
+/// functionDecl(hasAnyParameter(hasType(isConstQualified())))
+///   matches "void b(int const)", "void c(const int)" and
+///   "void e(int const) {}". It does not match d as there
+///   is no top-level const on the parameter type "const int *".
+AST_MATCHER(QualType, isConstQualified) {
+  return Node.isConstQualified();
+}
+
+/// \brief Matches QualType nodes that have local CV-qualifiers attached to
+/// the node, not hidden within a typedef.
+///
+/// Given
+/// \code
+///   typedef const int const_int;
+///   const_int i;
+///   int *const j;
+///   int *volatile k;
+///   int m;
+/// \endcode
+/// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k.
+/// \c i is const-qualified but the qualifier is not local.
+AST_MATCHER(QualType, hasLocalQualifiers) {
+  return Node.hasLocalQualifiers();
+}
+
+/// \brief Matches a member expression where the member is matched by a
+/// given matcher.
+///
+/// Given
+/// \code
+///   struct { int first, second; } first, second;
+///   int i(second.first);
+///   int j(first.second);
+/// \endcode
+/// memberExpr(member(hasName("first")))
+///   matches second.first
+///   but not first.second (because the member name there is "second").
+AST_MATCHER_P(MemberExpr, member,
+              internal::Matcher<ValueDecl>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
+}
+
+/// \brief Matches a member expression where the object expression is
+/// matched by a given matcher.
+///
+/// Given
+/// \code
+///   struct X { int m; };
+///   void f(X x) { x.m; m; }
+/// \endcode
+/// memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))))
+///   matches "x.m" and "m"
+/// with hasObjectExpression(...)
+///   matching "x" and the implicit object expression of "m" which has type X*.
+AST_MATCHER_P(MemberExpr, hasObjectExpression,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
+}
+
+/// \brief Matches any using shadow declaration.
+///
+/// Given
+/// \code
+///   namespace X { void b(); }
+///   using X::b;
+/// \endcode
+/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
+///   matches \code using X::b \endcode
+AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
+              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
+  return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
+                                    Node.shadow_end(), Finder, Builder);
+}
+
+/// \brief Matches a using shadow declaration where the target declaration is
+/// matched by the given matcher.
+///
+/// Given
+/// \code
+///   namespace X { int a; void b(); }
+///   using X::a;
+///   using X::b;
+/// \endcode
+/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl())))
+///   matches \code using X::b \endcode
+///   but not \code using X::a \endcode
+AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
+              internal::Matcher<NamedDecl>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
+}
+
+/// \brief Matches template instantiations of function, class, or static
+/// member variable template instantiations.
+///
+/// Given
+/// \code
+///   template <typename T> class X {}; class A {}; X<A> x;
+/// \endcode
+/// or
+/// \code
+///   template <typename T> class X {}; class A {}; template class X<A>;
+/// \endcode
+/// recordDecl(hasName("::X"), isTemplateInstantiation())
+///   matches the template instantiation of X<A>.
+///
+/// But given
+/// \code
+///   template <typename T>  class X {}; class A {};
+///   template <> class X<A> {}; X<A> x;
+/// \endcode
+/// recordDecl(hasName("::X"), isTemplateInstantiation())
+///   does not match, as X<A> is an explicit template specialization.
+///
+/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
+AST_POLYMORPHIC_MATCHER(
+    isTemplateInstantiation,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
+  return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
+          Node.getTemplateSpecializationKind() ==
+          TSK_ExplicitInstantiationDefinition);
+}
+
+/// \brief Matches explicit template specializations of function, class, or
+/// static member variable template instantiations.
+///
+/// Given
+/// \code
+///   template<typename T> void A(T t) { }
+///   template<> void A(int N) { }
+/// \endcode
+/// functionDecl(isExplicitTemplateSpecialization())
+///   matches the specialization A<int>().
+///
+/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
+AST_POLYMORPHIC_MATCHER(
+    isExplicitTemplateSpecialization,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
+  return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
+}
+
+/// \brief Matches \c TypeLocs for which the given inner
+/// QualType-matcher matches.
+AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
+                                internal::Matcher<QualType>, InnerMatcher, 0) {
+  return internal::BindableMatcher<TypeLoc>(
+      new internal::TypeLocTypeMatcher(InnerMatcher));
+}
+
+/// \brief Matches builtin Types.
+///
+/// Given
+/// \code
+///   struct A {};
+///   A a;
+///   int b;
+///   float c;
+///   bool d;
+/// \endcode
+/// builtinType()
+///   matches "int b", "float c" and "bool d"
+AST_TYPE_MATCHER(BuiltinType, builtinType);
+
+/// \brief Matches all kinds of arrays.
+///
+/// Given
+/// \code
+///   int a[] = { 2, 3 };
+///   int b[4];
+///   void f() { int c[a[0]]; }
+/// \endcode
+/// arrayType()
+///   matches "int a[]", "int b[4]" and "int c[a[0]]";
+AST_TYPE_MATCHER(ArrayType, arrayType);
+
+/// \brief Matches C99 complex types.
+///
+/// Given
+/// \code
+///   _Complex float f;
+/// \endcode
+/// complexType()
+///   matches "_Complex float f"
+AST_TYPE_MATCHER(ComplexType, complexType);
+
+/// \brief Matches arrays and C99 complex types that have a specific element
+/// type.
+///
+/// Given
+/// \code
+///   struct A {};
+///   A a[7];
+///   int b[7];
+/// \endcode
+/// arrayType(hasElementType(builtinType()))
+///   matches "int b[7]"
+///
+/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
+AST_TYPELOC_TRAVERSE_MATCHER(
+    hasElementType, getElement,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType));
+
+/// \brief Matches C arrays with a specified constant size.
+///
+/// Given
+/// \code
+///   void() {
+///     int a[2];
+///     int b[] = { 2, 3 };
+///     int c[b[0]];
+///   }
+/// \endcode
+/// constantArrayType()
+///   matches "int a[2]"
+AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
+
+/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+///
+/// Given
+/// \code
+///   int a[42];
+///   int b[2 * 21];
+///   int c[41], d[43];
+/// \endcode
+/// constantArrayType(hasSize(42))
+///   matches "int a[42]" and "int b[2 * 21]"
+AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
+  return Node.getSize() == N;
+}
+
+/// \brief Matches C++ arrays whose size is a value-dependent expression.
+///
+/// Given
+/// \code
+///   template<typename T, int Size>
+///   class array {
+///     T data[Size];
+///   };
+/// \endcode
+/// dependentSizedArrayType
+///   matches "T data[Size]"
+AST_TYPE_MATCHER(DependentSizedArrayType, dependentSizedArrayType);
+
+/// \brief Matches C arrays with unspecified size.
+///
+/// Given
+/// \code
+///   int a[] = { 2, 3 };
+///   int b[42];
+///   void f(int c[]) { int d[a[0]]; };
+/// \endcode
+/// incompleteArrayType()
+///   matches "int a[]" and "int c[]"
+AST_TYPE_MATCHER(IncompleteArrayType, incompleteArrayType);
+
+/// \brief Matches C arrays with a specified size that is not an
+/// integer-constant-expression.
+///
+/// Given
+/// \code
+///   void f() {
+///     int a[] = { 2, 3 }
+///     int b[42];
+///     int c[a[0]];
+/// \endcode
+/// variableArrayType()
+///   matches "int c[a[0]]"
+AST_TYPE_MATCHER(VariableArrayType, variableArrayType);
+
+/// \brief Matches \c VariableArrayType nodes that have a specific size
+/// expression.
+///
+/// Given
+/// \code
+///   void f(int b) {
+///     int a[b];
+///   }
+/// \endcode
+/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
+///   varDecl(hasName("b")))))))
+///   matches "int a[b]"
+AST_MATCHER_P(VariableArrayType, hasSizeExpr,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
+}
+
+/// \brief Matches atomic types.
+///
+/// Given
+/// \code
+///   _Atomic(int) i;
+/// \endcode
+/// atomicType()
+///   matches "_Atomic(int) i"
+AST_TYPE_MATCHER(AtomicType, atomicType);
+
+/// \brief Matches atomic types with a specific value type.
+///
+/// Given
+/// \code
+///   _Atomic(int) i;
+///   _Atomic(float) f;
+/// \endcode
+/// atomicType(hasValueType(isInteger()))
+///  matches "_Atomic(int) i"
+///
+/// Usable as: Matcher<AtomicType>
+AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
+                             AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType));
+
+/// \brief Matches types nodes representing C++11 auto types.
+///
+/// Given:
+/// \code
+///   auto n = 4;
+///   int v[] = { 2, 3 }
+///   for (auto i : v) { }
+/// \endcode
+/// autoType()
+///   matches "auto n" and "auto i"
+AST_TYPE_MATCHER(AutoType, autoType);
+
+/// \brief Matches \c AutoType nodes where the deduced type is a specific type.
+///
+/// Note: There is no \c TypeLoc for the deduced type and thus no
+/// \c getDeducedLoc() matcher.
+///
+/// Given
+/// \code
+///   auto a = 1;
+///   auto b = 2.0;
+/// \endcode
+/// autoType(hasDeducedType(isInteger()))
+///   matches "auto a"
+///
+/// Usable as: Matcher<AutoType>
+AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType));
+
+/// \brief Matches \c FunctionType nodes.
+///
+/// Given
+/// \code
+///   int (*f)(int);
+///   void g();
+/// \endcode
+/// functionType()
+///   matches "int (*f)(int)" and the type of "g".
+AST_TYPE_MATCHER(FunctionType, functionType);
+
+/// \brief Matches \c ParenType nodes.
+///
+/// Given
+/// \code
+///   int (*ptr_to_array)[4];
+///   int *array_of_ptrs[4];
+/// \endcode
+///
+/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
+/// \c array_of_ptrs.
+AST_TYPE_MATCHER(ParenType, parenType);
+
+/// \brief Matches \c ParenType nodes where the inner type is a specific type.
+///
+/// Given
+/// \code
+///   int (*ptr_to_array)[4];
+///   int (*ptr_to_func)(int);
+/// \endcode
+///
+/// \c varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches
+/// \c ptr_to_func but not \c ptr_to_array.
+///
+/// Usable as: Matcher<ParenType>
+AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType));
+
+/// \brief Matches block pointer types, i.e. types syntactically represented as
+/// "void (^)(int)".
+///
+/// The \c pointee is always required to be a \c FunctionType.
+AST_TYPE_MATCHER(BlockPointerType, blockPointerType);
+
+/// \brief Matches member pointer types.
+/// Given
+/// \code
+///   struct A { int i; }
+///   A::* ptr = A::i;
+/// \endcode
+/// memberPointerType()
+///   matches "A::* ptr"
+AST_TYPE_MATCHER(MemberPointerType, memberPointerType);
+
+/// \brief Matches pointer types.
+///
+/// Given
+/// \code
+///   int *a;
+///   int &b = *a;
+///   int c = 5;
+/// \endcode
+/// pointerType()
+///   matches "int *a"
+AST_TYPE_MATCHER(PointerType, pointerType);
+
+/// \brief Matches both lvalue and rvalue reference types.
+///
+/// Given
+/// \code
+///   int *a;
+///   int &b = *a;
+///   int &&c = 1;
+///   auto &d = b;
+///   auto &&e = c;
+///   auto &&f = 2;
+///   int g = 5;
+/// \endcode
+///
+/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
+AST_TYPE_MATCHER(ReferenceType, referenceType);
+
+/// \brief Matches lvalue reference types.
+///
+/// Given:
+/// \code
+///   int *a;
+///   int &b = *a;
+///   int &&c = 1;
+///   auto &d = b;
+///   auto &&e = c;
+///   auto &&f = 2;
+///   int g = 5;
+/// \endcode
+///
+/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
+/// matched since the type is deduced as int& by reference collapsing rules.
+AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType);
+
+/// \brief Matches rvalue reference types.
+///
+/// Given:
+/// \code
+///   int *a;
+///   int &b = *a;
+///   int &&c = 1;
+///   auto &d = b;
+///   auto &&e = c;
+///   auto &&f = 2;
+///   int g = 5;
+/// \endcode
+///
+/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
+/// matched as it is deduced to int& by reference collapsing rules.
+AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType);
+
+/// \brief Narrows PointerType (and similar) matchers to those where the
+/// \c pointee matches a given matcher.
+///
+/// Given
+/// \code
+///   int *a;
+///   int const *b;
+///   float const *f;
+/// \endcode
+/// pointerType(pointee(isConstQualified(), isInteger()))
+///   matches "int const *b"
+///
+/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
+///   Matcher<PointerType>, Matcher<ReferenceType>
+AST_TYPELOC_TRAVERSE_MATCHER(
+    pointee, getPointee,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType,
+                                      PointerType, ReferenceType));
+
+/// \brief Matches typedef types.
+///
+/// Given
+/// \code
+///   typedef int X;
+/// \endcode
+/// typedefType()
+///   matches "typedef int X"
+AST_TYPE_MATCHER(TypedefType, typedefType);
+
+/// \brief Matches template specialization types.
+///
+/// Given
+/// \code
+///   template <typename T>
+///   class C { };
+///
+///   template class C<int>;  // A
+///   C<char> var;            // B
+/// \code
+///
+/// \c templateSpecializationType() matches the type of the explicit
+/// instantiation in \c A and the type of the variable declaration in \c B.
+AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType);
+
+/// \brief Matches types nodes representing unary type transformations.
+///
+/// Given:
+/// \code
+///   typedef __underlying_type(T) type;
+/// \endcode
+/// unaryTransformType()
+///   matches "__underlying_type(T)"
+AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType);
+
+/// \brief Matches record types (e.g. structs, classes).
+///
+/// Given
+/// \code
+///   class C {};
+///   struct S {};
+///
+///   C c;
+///   S s;
+/// \code
+///
+/// \c recordType() matches the type of the variable declarations of both \c c
+/// and \c s.
+AST_TYPE_MATCHER(RecordType, recordType);
+
+/// \brief Matches types specified with an elaborated type keyword or with a
+/// qualified name.
+///
+/// Given
+/// \code
+///   namespace N {
+///     namespace M {
+///       class D {};
+///     }
+///   }
+///   class C {};
+///
+///   class C c;
+///   N::M::D d;
+/// \code
+///
+/// \c elaboratedType() matches the type of the variable declarations of both
+/// \c c and \c d.
+AST_TYPE_MATCHER(ElaboratedType, elaboratedType);
+
+/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
+/// matches \c InnerMatcher if the qualifier exists.
+///
+/// Given
+/// \code
+///   namespace N {
+///     namespace M {
+///       class D {};
+///     }
+///   }
+///   N::M::D d;
+/// \code
+///
+/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
+/// matches the type of the variable declaration of \c d.
+AST_MATCHER_P(ElaboratedType, hasQualifier,
+              internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
+  if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
+    return InnerMatcher.matches(*Qualifier, Finder, Builder);
+
+  return false;
+}
+
+/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher.
+///
+/// Given
+/// \code
+///   namespace N {
+///     namespace M {
+///       class D {};
+///     }
+///   }
+///   N::M::D d;
+/// \code
+///
+/// \c elaboratedType(namesType(recordType(
+/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
+/// declaration of \c d.
+AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
+              InnerMatcher) {
+  return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
+}
+
+/// \brief Matches declarations whose declaration context, interpreted as a
+/// Decl, matches \c InnerMatcher.
+///
+/// Given
+/// \code
+///   namespace N {
+///     namespace M {
+///       class D {};
+///     }
+///   }
+/// \code
+///
+/// \c recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
+/// declaration of \c class \c D.
+AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) {
+  return InnerMatcher.matches(*Decl::castFromDeclContext(Node.getDeclContext()),
+                              Finder, Builder);
+}
+
+/// \brief Matches nested name specifiers.
+///
+/// Given
+/// \code
+///   namespace ns {
+///     struct A { static void f(); };
+///     void A::f() {}
+///     void g() { A::f(); }
+///   }
+///   ns::A a;
+/// \endcode
+/// nestedNameSpecifier()
+///   matches "ns::" and both "A::"
+const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+
+/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
+const internal::VariadicAllOfMatcher<
+  NestedNameSpecifierLoc> nestedNameSpecifierLoc;
+
+/// \brief Matches \c NestedNameSpecifierLocs for which the given inner
+/// NestedNameSpecifier-matcher matches.
+AST_MATCHER_FUNCTION_P_OVERLOAD(
+    internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
+    internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1) {
+  return internal::BindableMatcher<NestedNameSpecifierLoc>(
+      new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
+          InnerMatcher));
+}
+
+/// \brief Matches nested name specifiers that specify a type matching the
+/// given \c QualType matcher without qualifiers.
+///
+/// Given
+/// \code
+///   struct A { struct B { struct C {}; }; };
+///   A::B::C c;
+/// \endcode
+/// nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A")))))
+///   matches "A::"
+AST_MATCHER_P(NestedNameSpecifier, specifiesType,
+              internal::Matcher<QualType>, InnerMatcher) {
+  if (!Node.getAsType())
+    return false;
+  return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
+}
+
+/// \brief Matches nested name specifier locs that specify a type matching the
+/// given \c TypeLoc.
+///
+/// Given
+/// \code
+///   struct A { struct B { struct C {}; }; };
+///   A::B::C c;
+/// \endcode
+/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type(
+///   hasDeclaration(recordDecl(hasName("A")))))))
+///   matches "A::"
+AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
+              internal::Matcher<TypeLoc>, InnerMatcher) {
+  return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+}
+
+/// \brief Matches on the prefix of a \c NestedNameSpecifier.
+///
+/// Given
+/// \code
+///   struct A { struct B { struct C {}; }; };
+///   A::B::C c;
+/// \endcode
+/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and
+///   matches "A::"
+AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
+                       internal::Matcher<NestedNameSpecifier>, InnerMatcher,
+                       0) {
+  NestedNameSpecifier *NextNode = Node.getPrefix();
+  if (!NextNode)
+    return false;
+  return InnerMatcher.matches(*NextNode, Finder, Builder);
+}
+
+/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc.
+///
+/// Given
+/// \code
+///   struct A { struct B { struct C {}; }; };
+///   A::B::C c;
+/// \endcode
+/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
+///   matches "A::"
+AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
+                       internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
+                       1) {
+  NestedNameSpecifierLoc NextNode = Node.getPrefix();
+  if (!NextNode)
+    return false;
+  return InnerMatcher.matches(NextNode, Finder, Builder);
+}
+
+/// \brief Matches nested name specifiers that specify a namespace matching the
+/// given namespace matcher.
+///
+/// Given
+/// \code
+///   namespace ns { struct A {}; }
+///   ns::A a;
+/// \endcode
+/// nestedNameSpecifier(specifiesNamespace(hasName("ns")))
+///   matches "ns::"
+AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
+              internal::Matcher<NamespaceDecl>, InnerMatcher) {
+  if (!Node.getAsNamespace())
+    return false;
+  return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
+}
+
+/// \brief Overloads for the \c equalsNode matcher.
+/// FIXME: Implement for other node types.
+/// @{
+
+/// \brief Matches if a node equals another node.
+///
+/// \c Decl has pointer identity in the AST.
+AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
+  return &Node == Other;
+}
+/// \brief Matches if a node equals another node.
+///
+/// \c Stmt has pointer identity in the AST.
+///
+AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
+  return &Node == Other;
+}
+
+/// @}
+
+/// \brief Matches each case or default statement belonging to the given switch
+/// statement. This matcher may produce multiple matches.
+///
+/// Given
+/// \code
+///   switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } }
+/// \endcode
+/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
+///   matches four times, with "c" binding each of "case 1:", "case 2:",
+/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)",
+/// "switch (1)", "switch (2)" and "switch (2)".
+AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,
+              InnerMatcher) {
+  BoundNodesTreeBuilder Result;
+  // FIXME: getSwitchCaseList() does not necessarily guarantee a stable
+  // iteration order. We should use the more general iterating matchers once
+  // they are capable of expressing this matcher (for example, it should ignore
+  // case statements belonging to nested switch statements).
+  bool Matched = false;
+  for (const SwitchCase *SC = Node.getSwitchCaseList(); SC;
+       SC = SC->getNextSwitchCase()) {
+    BoundNodesTreeBuilder CaseBuilder(*Builder);
+    bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder);
+    if (CaseMatched) {
+      Matched = true;
+      Result.addMatch(CaseBuilder);
+    }
+  }
+  *Builder = Result;
+  return Matched;
+}
+
+/// \brief Matches each constructor initializer in a constructor definition.
+///
+/// Given
+/// \code
+///   class A { A() : i(42), j(42) {} int i; int j; };
+/// \endcode
+/// constructorDecl(forEachConstructorInitializer(forField(decl().bind("x"))))
+///   will trigger two matches, binding for 'i' and 'j' respectively.
+AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
+              internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
+  BoundNodesTreeBuilder Result;
+  bool Matched = false;
+  for (const auto *I : Node.inits()) {
+    BoundNodesTreeBuilder InitBuilder(*Builder);
+    if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
+      Matched = true;
+      Result.addMatch(InitBuilder);
+    }
+  }
+  *Builder = Result;
+  return Matched;
+}
+
+/// \brief If the given case statement does not use the GNU case range
+/// extension, matches the constant given in the statement.
+///
+/// Given
+/// \code
+///   switch (1) { case 1: case 1+1: case 3 ... 4: ; }
+/// \endcode
+/// caseStmt(hasCaseConstant(integerLiteral()))
+///   matches "case 1:"
+AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
+              InnerMatcher) {
+  if (Node.getRHS())
+    return false;
+
+  return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
+}
+
+} // end namespace ast_matchers
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
new file mode 100644
index 0000000..94435fd
--- /dev/null
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -0,0 +1,1645 @@
+//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Implements the base layer of the matcher framework.
+//
+//  Matchers are methods that return a Matcher<T> which provides a method
+//  Matches(...) which is a predicate on an AST node. The Matches method's
+//  parameters define the context of the match, which allows matchers to recurse
+//  or store the current node as bound to a specific string, so that it can be
+//  retrieved later.
+//
+//  In general, matchers have two parts:
+//  1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T>
+//     based on the arguments and optionally on template type deduction based
+//     on the arguments. Matcher<T>s form an implicit reverse hierarchy
+//     to clang's AST class hierarchy, meaning that you can use a Matcher<Base>
+//     everywhere a Matcher<Derived> is required.
+//  2. An implementation of a class derived from MatcherInterface<T>.
+//
+//  The matcher functions are defined in ASTMatchers.h. To make it possible
+//  to implement both the matcher function and the implementation of the matcher
+//  interface in one place, ASTMatcherMacros.h defines macros that allow
+//  implementing a matcher in a single place.
+//
+//  This file contains the base classes needed to construct the actual matchers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
+#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/VariadicFunction.h"
+#include <map>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace ast_matchers {
+
+class BoundNodes;
+
+namespace internal {
+
+/// \brief Internal version of BoundNodes. Holds all the bound nodes.
+class BoundNodesMap {
+public:
+  /// \brief Adds \c Node to the map with key \c ID.
+  ///
+  /// The node's base type should be in NodeBaseType or it will be unaccessible.
+  template <typename T>
+  void addNode(StringRef ID, const T* Node) {
+    NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node);
+  }
+
+  /// \brief Returns the AST node bound to \c ID.
+  ///
+  /// Returns NULL if there was no node bound to \c ID or if there is a node but
+  /// it cannot be converted to the specified type.
+  template <typename T>
+  const T *getNodeAs(StringRef ID) const {
+    IDToNodeMap::const_iterator It = NodeMap.find(ID);
+    if (It == NodeMap.end()) {
+      return nullptr;
+    }
+    return It->second.get<T>();
+  }
+
+  ast_type_traits::DynTypedNode getNode(StringRef ID) const {
+    IDToNodeMap::const_iterator It = NodeMap.find(ID);
+    if (It == NodeMap.end()) {
+      return ast_type_traits::DynTypedNode();
+    }
+    return It->second;
+  }
+
+  /// \brief Imposes an order on BoundNodesMaps.
+  bool operator<(const BoundNodesMap &Other) const {
+    return NodeMap < Other.NodeMap;
+  }
+
+  /// \brief A map from IDs to the bound nodes.
+  ///
+  /// Note that we're using std::map here, as for memoization:
+  /// - we need a comparison operator
+  /// - we need an assignment operator
+  typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap;
+
+  const IDToNodeMap &getMap() const {
+    return NodeMap;
+  }
+
+private:
+  IDToNodeMap NodeMap;
+};
+
+/// \brief Creates BoundNodesTree objects.
+///
+/// The tree builder is used during the matching process to insert the bound
+/// nodes from the Id matcher.
+class BoundNodesTreeBuilder {
+public:
+  /// \brief A visitor interface to visit all BoundNodes results for a
+  /// BoundNodesTree.
+  class Visitor {
+  public:
+    virtual ~Visitor() {}
+
+    /// \brief Called multiple times during a single call to VisitMatches(...).
+    ///
+    /// 'BoundNodesView' contains the bound nodes for a single match.
+    virtual void visitMatch(const BoundNodes& BoundNodesView) = 0;
+  };
+
+  /// \brief Add a binding from an id to a node.
+  template <typename T> void setBinding(const std::string &Id, const T *Node) {
+    if (Bindings.empty())
+      Bindings.push_back(BoundNodesMap());
+    for (unsigned i = 0, e = Bindings.size(); i != e; ++i)
+      Bindings[i].addNode(Id, Node);
+  }
+
+  /// \brief Adds a branch in the tree.
+  void addMatch(const BoundNodesTreeBuilder &Bindings);
+
+  /// \brief Visits all matches that this BoundNodesTree represents.
+  ///
+  /// The ownership of 'ResultVisitor' remains at the caller.
+  void visitMatches(Visitor* ResultVisitor);
+
+  template <typename ExcludePredicate>
+  bool removeBindings(const ExcludePredicate &Predicate) {
+    Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
+                   Bindings.end());
+    return !Bindings.empty();
+  }
+
+  /// \brief Imposes an order on BoundNodesTreeBuilders.
+  bool operator<(const BoundNodesTreeBuilder &Other) const {
+    return Bindings < Other.Bindings;
+  }
+
+private:
+  SmallVector<BoundNodesMap, 16> Bindings;
+};
+
+class ASTMatchFinder;
+
+/// \brief Generic interface for matchers on an AST node of type T.
+///
+/// Implement this if your matcher may need to inspect the children or
+/// descendants of the node or bind matched nodes to names. If you are
+/// writing a simple matcher that only inspects properties of the
+/// current node and doesn't care about its children or descendants,
+/// implement SingleNodeMatcherInterface instead.
+template <typename T>
+class MatcherInterface : public RefCountedBaseVPTR {
+public:
+  virtual ~MatcherInterface() {}
+
+  /// \brief Returns true if 'Node' can be matched.
+  ///
+  /// May bind 'Node' to an ID via 'Builder', or recurse into
+  /// the AST via 'Finder'.
+  virtual bool matches(const T &Node,
+                       ASTMatchFinder *Finder,
+                       BoundNodesTreeBuilder *Builder) const = 0;
+};
+
+/// \brief Interface for matchers that only evaluate properties on a single
+/// node.
+template <typename T>
+class SingleNodeMatcherInterface : public MatcherInterface<T> {
+public:
+  /// \brief Returns true if the matcher matches the provided node.
+  ///
+  /// A subclass must implement this instead of Matches().
+  virtual bool matchesNode(const T &Node) const = 0;
+
+private:
+  /// Implements MatcherInterface::Matches.
+  bool matches(const T &Node,
+               ASTMatchFinder * /* Finder */,
+               BoundNodesTreeBuilder * /*  Builder */) const override {
+    return matchesNode(Node);
+  }
+};
+
+/// \brief Wrapper of a MatcherInterface<T> *that allows copying.
+///
+/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
+/// required. This establishes an is-a relationship which is reverse
+/// to the AST hierarchy. In other words, Matcher<T> is contravariant
+/// with respect to T. The relationship is built via a type conversion
+/// operator rather than a type hierarchy to be able to templatize the
+/// type hierarchy instead of spelling it out.
+template <typename T>
+class Matcher {
+public:
+  /// \brief Takes ownership of the provided implementation pointer.
+  explicit Matcher(MatcherInterface<T> *Implementation)
+      : Implementation(Implementation) {}
+
+  /// \brief Implicitly converts \c Other to a Matcher<T>.
+  ///
+  /// Requires \c T to be derived from \c From.
+  template <typename From>
+  Matcher(const Matcher<From> &Other,
+          typename std::enable_if<std::is_base_of<From, T>::value &&
+                                  !std::is_same<From, T>::value>::type * = 0)
+      : Implementation(new ImplicitCastMatcher<From>(Other)) {}
+
+  /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
+  ///
+  /// The resulting matcher is not strict, i.e. ignores qualifiers.
+  template <typename TypeT>
+  Matcher(const Matcher<TypeT> &Other,
+          typename std::enable_if<
+            std::is_same<T, QualType>::value &&
+            std::is_same<TypeT, Type>::value>::type* = 0)
+      : Implementation(new TypeToQualType<TypeT>(Other)) {}
+
+  /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
+  bool matches(const T &Node,
+               ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const {
+    if (Implementation->matches(Node, Finder, Builder))
+      return true;
+    // Delete all bindings when a matcher does not match.
+    // This prevents unexpected exposure of bound nodes in unmatches
+    // branches of the match tree.
+    *Builder = BoundNodesTreeBuilder();
+    return false;
+  }
+
+  /// \brief Returns an ID that uniquely identifies the matcher.
+  uint64_t getID() const {
+    /// FIXME: Document the requirements this imposes on matcher
+    /// implementations (no new() implementation_ during a Matches()).
+    return reinterpret_cast<uint64_t>(Implementation.get());
+  }
+
+  /// \brief Allows the conversion of a \c Matcher<Type> to a \c
+  /// Matcher<QualType>.
+  ///
+  /// Depending on the constructor argument, the matcher is either strict, i.e.
+  /// does only matches in the absence of qualifiers, or not, i.e. simply
+  /// ignores any qualifiers.
+  template <typename TypeT>
+  class TypeToQualType : public MatcherInterface<QualType> {
+   public:
+    TypeToQualType(const Matcher<TypeT> &InnerMatcher)
+        : InnerMatcher(InnerMatcher) {}
+
+    bool matches(const QualType &Node, ASTMatchFinder *Finder,
+                 BoundNodesTreeBuilder *Builder) const override {
+      if (Node.isNull())
+        return false;
+      return InnerMatcher.matches(*Node, Finder, Builder);
+    }
+   private:
+    const Matcher<TypeT> InnerMatcher;
+  };
+
+private:
+  /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T
+  /// is derived from Base.
+  template <typename Base>
+  class ImplicitCastMatcher : public MatcherInterface<T> {
+  public:
+    explicit ImplicitCastMatcher(const Matcher<Base> &From)
+        : From(From) {}
+
+    bool matches(const T &Node, ASTMatchFinder *Finder,
+                 BoundNodesTreeBuilder *Builder) const override {
+      return From.matches(Node, Finder, Builder);
+    }
+
+  private:
+    const Matcher<Base> From;
+  };
+
+  IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
+};  // class Matcher
+
+/// \brief A convenient helper for creating a Matcher<T> without specifying
+/// the template type argument.
+template <typename T>
+inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
+  return Matcher<T>(Implementation);
+}
+
+template <typename T> class BindableMatcher;
+
+/// \brief Matcher that works on a \c DynTypedNode.
+///
+/// It is constructed from a \c Matcher<T> object and redirects most calls to
+/// underlying matcher.
+/// It checks whether the \c DynTypedNode is convertible into the type of the
+/// underlying matcher and then do the actual match on the actual node, or
+/// return false if it is not convertible.
+class DynTypedMatcher {
+public:
+  /// \brief Construct from a \c Matcher<T>. Copies the matcher.
+  template <typename T> inline DynTypedMatcher(const Matcher<T> &M);
+
+  /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher.
+  ///
+  /// This version enables \c tryBind() on the \c DynTypedMatcher.
+  template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M);
+
+  /// \brief Returns true if the matcher matches the given \c DynNode.
+  bool matches(const ast_type_traits::DynTypedNode DynNode,
+               ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const {
+    return Storage->matches(DynNode, Finder, Builder);
+  }
+
+  /// \brief Bind the specified \p ID to the matcher.
+  /// \return A new matcher with the \p ID bound to it if this matcher supports
+  ///   binding. Otherwise, returns an empty \c Optional<>.
+  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const {
+    return Storage->tryBind(ID);
+  }
+
+  /// \brief Returns a unique \p ID for the matcher.
+  uint64_t getID() const { return Storage->getID(); }
+
+  /// \brief Returns the type this matcher works on.
+  ///
+  /// \c matches() will always return false unless the node passed is of this
+  /// or a derived type.
+  ast_type_traits::ASTNodeKind getSupportedKind() const {
+    return Storage->getSupportedKind();
+  }
+
+  /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted
+  ///   to a \c Matcher<T>.
+  ///
+  /// This method verifies that the underlying matcher in \c Other can process
+  /// nodes of types T.
+  template <typename T> bool canConvertTo() const {
+    return getSupportedKind().isBaseOf(
+        ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+  }
+
+  /// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
+  ///
+  /// This method asserts that \c canConvertTo() is \c true. Callers
+  /// should call \c canConvertTo() first to make sure that \c this is
+  /// compatible with T.
+  template <typename T> Matcher<T> convertTo() const {
+    assert(canConvertTo<T>());
+    return unconditionalConvertTo<T>();
+  }
+
+  /// \brief Same as \c convertTo(), but does not check that the underlying
+  ///   matcher can handle a value of T.
+  ///
+  /// If it is not compatible, then this matcher will never match anything.
+  template <typename T> Matcher<T> unconditionalConvertTo() const;
+
+private:
+  class MatcherStorage : public RefCountedBaseVPTR {
+  public:
+    MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID)
+        : SupportedKind(SupportedKind), ID(ID) {}
+    virtual ~MatcherStorage();
+
+    virtual bool matches(const ast_type_traits::DynTypedNode DynNode,
+                         ASTMatchFinder *Finder,
+                         BoundNodesTreeBuilder *Builder) const = 0;
+
+    virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0;
+
+    ast_type_traits::ASTNodeKind getSupportedKind() const {
+      return SupportedKind;
+    }
+
+    uint64_t getID() const { return ID; }
+
+  private:
+    const ast_type_traits::ASTNodeKind SupportedKind;
+    const uint64_t ID;
+  };
+
+  /// \brief Typed implementation of \c MatcherStorage.
+  template <typename T> class TypedMatcherStorage;
+
+  IntrusiveRefCntPtr<const MatcherStorage> Storage;
+};
+
+template <typename T>
+class DynTypedMatcher::TypedMatcherStorage : public MatcherStorage {
+public:
+  TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind)
+      : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
+                       Other.getID()),
+        InnerMatcher(Other), AllowBind(AllowBind) {}
+
+  bool matches(const ast_type_traits::DynTypedNode DynNode,
+               ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    if (const T *Node = DynNode.get<T>()) {
+      return InnerMatcher.matches(*Node, Finder, Builder);
+    }
+    return false;
+  }
+
+  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override {
+    if (!AllowBind)
+      return llvm::Optional<DynTypedMatcher>();
+    return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
+  }
+
+private:
+  const Matcher<T> InnerMatcher;
+  const bool AllowBind;
+};
+
+template <typename T>
+inline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M)
+    : Storage(new TypedMatcherStorage<T>(M, false)) {}
+
+template <typename T>
+inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
+    : Storage(new TypedMatcherStorage<T>(M, true)) {}
+
+/// \brief Specialization of the conversion functions for QualType.
+///
+/// These specializations provide the Matcher<Type>->Matcher<QualType>
+/// conversion that the static API does.
+template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const {
+  const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
+  return SourceKind.isSame(
+             ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||
+         SourceKind.isSame(
+             ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>());
+}
+
+template <>
+inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
+  assert(canConvertTo<QualType>());
+  const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
+  if (SourceKind.isSame(
+          ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
+    // We support implicit conversion from Matcher<Type> to Matcher<QualType>
+    return unconditionalConvertTo<Type>();
+  }
+  return unconditionalConvertTo<QualType>();
+}
+
+/// \brief Finds the first node in a range that matches the given matcher.
+template <typename MatcherT, typename IteratorT>
+bool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
+                         IteratorT End, ASTMatchFinder *Finder,
+                         BoundNodesTreeBuilder *Builder) {
+  for (IteratorT I = Start; I != End; ++I) {
+    BoundNodesTreeBuilder Result(*Builder);
+    if (Matcher.matches(*I, Finder, &Result)) {
+      *Builder = Result;
+      return true;
+    }
+  }
+  return false;
+}
+
+/// \brief Finds the first node in a pointer range that matches the given
+/// matcher.
+template <typename MatcherT, typename IteratorT>
+bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
+                                IteratorT End, ASTMatchFinder *Finder,
+                                BoundNodesTreeBuilder *Builder) {
+  for (IteratorT I = Start; I != End; ++I) {
+    BoundNodesTreeBuilder Result(*Builder);
+    if (Matcher.matches(**I, Finder, &Result)) {
+      *Builder = Result;
+      return true;
+    }
+  }
+  return false;
+}
+
+/// \brief Metafunction to determine if type T has a member called getDecl.
+template <typename T> struct has_getDecl {
+  struct Default { int getDecl; };
+  struct Derived : T, Default { };
+
+  template<typename C, C> struct CheckT;
+
+  // If T::getDecl exists, an ambiguity arises and CheckT will
+  // not be instantiable. This makes f(...) the only available
+  // overload.
+  template<typename C>
+  static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
+  template<typename C> static char (&f(...))[2];
+
+  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
+};
+
+/// \brief Matches overloaded operators with a specific name.
+///
+/// The type argument ArgT is not used by this matcher but is used by
+/// PolymorphicMatcherWithParam1 and should be StringRef.
+template <typename T, typename ArgT>
+class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
+  static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
+                std::is_base_of<FunctionDecl, T>::value,
+                "unsupported class for matcher");
+  static_assert(std::is_same<ArgT, StringRef>::value,
+                "argument type must be StringRef");
+
+public:
+  explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
+      : SingleNodeMatcherInterface<T>(), Name(Name) {}
+
+  bool matchesNode(const T &Node) const override {
+    return matchesSpecialized(Node);
+  }
+
+private:
+
+  /// \brief CXXOperatorCallExpr exist only for calls to overloaded operators
+  /// so this function returns true if the call is to an operator of the given
+  /// name.
+  bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
+    return getOperatorSpelling(Node.getOperator()) == Name;
+  }
+
+  /// \brief Returns true only if CXXMethodDecl represents an overloaded
+  /// operator and has the given operator name.
+  bool matchesSpecialized(const FunctionDecl &Node) const {
+    return Node.isOverloadedOperator() &&
+           getOperatorSpelling(Node.getOverloadedOperator()) == Name;
+  }
+
+  std::string Name;
+};
+
+/// \brief Matches declarations for QualType and CallExpr.
+///
+/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
+/// not actually used.
+template <typename T, typename DeclMatcherT>
+class HasDeclarationMatcher : public MatcherInterface<T> {
+  static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
+                "instantiated with wrong types");
+
+public:
+  explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
+      : InnerMatcher(InnerMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return matchesSpecialized(Node, Finder, Builder);
+  }
+
+private:
+  /// \brief If getDecl exists as a member of U, returns whether the inner
+  /// matcher matches Node.getDecl().
+  template <typename U>
+  bool matchesSpecialized(
+      const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+      typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
+    return matchesDecl(Node.getDecl(), Finder, Builder);
+  }
+
+  /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns
+  /// whether the inner matcher matches on it.
+  bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    /// FIXME: Add other ways to convert...
+    if (Node.isNull())
+      return false;
+    if (const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr()))
+      return matchesDecl(AsEnum->getDecl(), Finder, Builder);
+    return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
+  }
+
+  /// \brief Gets the TemplateDecl from a TemplateSpecializationType
+  /// and returns whether the inner matches on it.
+  bool matchesSpecialized(const TemplateSpecializationType &Node,
+                          ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    return matchesDecl(Node.getTemplateName().getAsTemplateDecl(),
+                       Finder, Builder);
+  }
+
+  /// \brief Extracts the Decl of the callee of a CallExpr and returns whether
+  /// the inner matcher matches on it.
+  bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
+  }
+
+  /// \brief Extracts the Decl of the constructor call and returns whether the
+  /// inner matcher matches on it.
+  bool matchesSpecialized(const CXXConstructExpr &Node,
+                          ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    return matchesDecl(Node.getConstructor(), Finder, Builder);
+  }
+
+  /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
+  /// whether the inner matcher matches on it.
+  bool matchesSpecialized(const MemberExpr &Node,
+                          ASTMatchFinder *Finder,
+                          BoundNodesTreeBuilder *Builder) const {
+    return matchesDecl(Node.getMemberDecl(), Finder, Builder);
+  }
+
+  /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
+  /// is \c NULL.
+  bool matchesDecl(const Decl *Node,
+                   ASTMatchFinder *Finder,
+                   BoundNodesTreeBuilder *Builder) const {
+    return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder);
+  }
+
+  const Matcher<Decl> InnerMatcher;
+};
+
+/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST
+/// node class hierarchies.
+template <typename T>
+struct IsBaseType {
+  static const bool value =
+      std::is_same<T, Decl>::value ||
+      std::is_same<T, Stmt>::value ||
+      std::is_same<T, QualType>::value ||
+      std::is_same<T, Type>::value ||
+      std::is_same<T, TypeLoc>::value ||
+      std::is_same<T, NestedNameSpecifier>::value ||
+      std::is_same<T, NestedNameSpecifierLoc>::value ||
+      std::is_same<T, CXXCtorInitializer>::value;
+};
+template <typename T>
+const bool IsBaseType<T>::value;
+
+/// \brief Interface that allows matchers to traverse the AST.
+/// FIXME: Find a better name.
+///
+/// This provides three entry methods for each base node type in the AST:
+/// - \c matchesChildOf:
+///   Matches a matcher on every child node of the given node. Returns true
+///   if at least one child node could be matched.
+/// - \c matchesDescendantOf:
+///   Matches a matcher on all descendant nodes of the given node. Returns true
+///   if at least one descendant matched.
+/// - \c matchesAncestorOf:
+///   Matches a matcher on all ancestors of the given node. Returns true if
+///   at least one ancestor matched.
+///
+/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
+/// In the future, we wan to implement this for all nodes for which it makes
+/// sense. In the case of matchesAncestorOf, we'll want to implement it for
+/// all nodes, as all nodes have ancestors.
+class ASTMatchFinder {
+public:
+  /// \brief Defines how we descend a level in the AST when we pass
+  /// through expressions.
+  enum TraversalKind {
+    /// Will traverse any child nodes.
+    TK_AsIs,
+    /// Will not traverse implicit casts and parentheses.
+    TK_IgnoreImplicitCastsAndParentheses
+  };
+
+  /// \brief Defines how bindings are processed on recursive matches.
+  enum BindKind {
+    /// Stop at the first match and only bind the first match.
+    BK_First,
+    /// Create results for all combinations of bindings that match.
+    BK_All
+  };
+
+  /// \brief Defines which ancestors are considered for a match.
+  enum AncestorMatchMode {
+    /// All ancestors.
+    AMM_All,
+    /// Direct parent only.
+    AMM_ParentOnly
+  };
+
+  virtual ~ASTMatchFinder() {}
+
+  /// \brief Returns true if the given class is directly or indirectly derived
+  /// from a base type matching \c base.
+  ///
+  /// A class is considered to be also derived from itself.
+  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
+                                  const Matcher<NamedDecl> &Base,
+                                  BoundNodesTreeBuilder *Builder) = 0;
+
+  template <typename T>
+  bool matchesChildOf(const T &Node,
+                      const DynTypedMatcher &Matcher,
+                      BoundNodesTreeBuilder *Builder,
+                      TraversalKind Traverse,
+                      BindKind Bind) {
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value ||
+                  std::is_base_of<NestedNameSpecifier, T>::value ||
+                  std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+                  std::is_base_of<TypeLoc, T>::value ||
+                  std::is_base_of<QualType, T>::value,
+                  "unsupported type for recursive matching");
+   return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
+                          Matcher, Builder, Traverse, Bind);
+  }
+
+  template <typename T>
+  bool matchesDescendantOf(const T &Node,
+                           const DynTypedMatcher &Matcher,
+                           BoundNodesTreeBuilder *Builder,
+                           BindKind Bind) {
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value ||
+                  std::is_base_of<NestedNameSpecifier, T>::value ||
+                  std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+                  std::is_base_of<TypeLoc, T>::value ||
+                  std::is_base_of<QualType, T>::value,
+                  "unsupported type for recursive matching");
+    return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
+                               Matcher, Builder, Bind);
+  }
+
+  // FIXME: Implement support for BindKind.
+  template <typename T>
+  bool matchesAncestorOf(const T &Node,
+                         const DynTypedMatcher &Matcher,
+                         BoundNodesTreeBuilder *Builder,
+                         AncestorMatchMode MatchMode) {
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value,
+                  "only Decl or Stmt allowed for recursive matching");
+    return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
+                             Matcher, Builder, MatchMode);
+  }
+
+  virtual ASTContext &getASTContext() const = 0;
+
+protected:
+  virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
+                              const DynTypedMatcher &Matcher,
+                              BoundNodesTreeBuilder *Builder,
+                              TraversalKind Traverse,
+                              BindKind Bind) = 0;
+
+  virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
+                                   const DynTypedMatcher &Matcher,
+                                   BoundNodesTreeBuilder *Builder,
+                                   BindKind Bind) = 0;
+
+  virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
+                                 const DynTypedMatcher &Matcher,
+                                 BoundNodesTreeBuilder *Builder,
+                                 AncestorMatchMode MatchMode) = 0;
+};
+
+/// \brief A type-list implementation.
+///
+/// A list is declared as a tree of type list nodes, where the leafs are the
+/// types.
+/// However, it is used as a "linked list" of types, by using the ::head and
+/// ::tail typedefs.
+/// Each node supports up to 4 children (instead of just 2) to reduce the
+/// nesting required by large lists.
+template <typename T1 = void, typename T2 = void, typename T3 = void,
+          typename T4 = void>
+struct TypeList {
+  /// \brief Implementation detail. Combined with the specializations below,
+  ///   this typedef allows for flattening of nested structures.
+  typedef TypeList<T1, T2, T3, T4> self;
+
+  /// \brief The first type on the list.
+  typedef T1 head;
+
+  /// \brief A sublist with the tail. ie everything but the head.
+  ///
+  /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
+  /// end of the list.
+  typedef typename TypeList<T2, T3, T4>::self tail;
+};
+
+/// \brief Template specialization to allow nested lists.
+///
+/// First element is a typelist. Pop its first element.
+template <typename Sub1, typename Sub2, typename Sub3, typename Sub4,
+          typename T2, typename T3, typename T4>
+struct TypeList<TypeList<Sub1, Sub2, Sub3, Sub4>, T2, T3,
+                T4> : public TypeList<Sub1,
+                                      typename TypeList<Sub2, Sub3, Sub4>::self,
+                                      typename TypeList<T2, T3, T4>::self> {};
+
+/// \brief Template specialization to allow nested lists.
+///
+/// First element is an empty typelist. Skip it.
+template <typename T2, typename T3, typename T4>
+struct TypeList<TypeList<>, T2, T3, T4> : public TypeList<T2, T3, T4> {
+};
+
+/// \brief The empty type list.
+typedef TypeList<> EmptyTypeList;
+
+/// \brief Helper meta-function to determine if some type \c T is present or
+///   a parent type in the list.
+template <typename AnyTypeList, typename T>
+struct TypeListContainsSuperOf {
+  static const bool value =
+      std::is_base_of<typename AnyTypeList::head, T>::value ||
+      TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
+};
+template <typename T>
+struct TypeListContainsSuperOf<EmptyTypeList, T> {
+  static const bool value = false;
+};
+
+/// \brief A "type list" that contains all types.
+///
+/// Useful for matchers like \c anything and \c unless.
+typedef TypeList<
+    TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc>,
+    TypeList<QualType, Type, TypeLoc, CXXCtorInitializer> > AllNodeBaseTypes;
+
+/// \brief Helper meta-function to extract the argument out of a function of
+///   type void(Arg).
+///
+/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details.
+template <class T> struct ExtractFunctionArgMeta;
+template <class T> struct ExtractFunctionArgMeta<void(T)> {
+  typedef T type;
+};
+
+/// \brief Default type lists for ArgumentAdaptingMatcher matchers.
+typedef AllNodeBaseTypes AdaptativeDefaultFromTypes;
+typedef TypeList<TypeList<Decl, Stmt, NestedNameSpecifier>,
+                 TypeList<NestedNameSpecifierLoc, TypeLoc, QualType> >
+AdaptativeDefaultToTypes;
+
+/// \brief All types that are supported by HasDeclarationMatcher above.
+typedef TypeList<TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType>,
+                 TypeList<InjectedClassNameType, LabelStmt, MemberExpr>,
+                 TypeList<QualType, RecordType, TagType>,
+                 TypeList<TemplateSpecializationType, TemplateTypeParmType,
+                          TypedefType, UnresolvedUsingType> >
+HasDeclarationSupportedTypes;
+
+/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by
+/// "adapting" a \c To into a \c T.
+///
+/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
+///
+/// For example:
+///   \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
+/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
+/// that is convertible into any matcher of type \c To by constructing
+/// \c HasMatcher<To, T>(InnerMatcher).
+///
+/// If a matcher does not need knowledge about the inner type, prefer to use
+/// PolymorphicMatcherWithParam1.
+template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
+          typename FromTypes = AdaptativeDefaultFromTypes,
+          typename ToTypes = AdaptativeDefaultToTypes>
+struct ArgumentAdaptingMatcherFunc {
+  template <typename T> class Adaptor {
+  public:
+    explicit Adaptor(const Matcher<T> &InnerMatcher)
+        : InnerMatcher(InnerMatcher) {}
+
+    typedef ToTypes ReturnTypes;
+
+    template <typename To> operator Matcher<To>() const {
+      return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
+    }
+
+  private:
+    const Matcher<T> InnerMatcher;
+  };
+
+  template <typename T>
+  static Adaptor<T> create(const Matcher<T> &InnerMatcher) {
+    return Adaptor<T>(InnerMatcher);
+  }
+
+  template <typename T>
+  Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const {
+    return create(InnerMatcher);
+  }
+};
+
+/// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be
+/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
+/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
+/// can be constructed.
+///
+/// For example:
+/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>()
+///   creates an object that can be used as a Matcher<T> for any type T
+///   where an IsDefinitionMatcher<T>() can be constructed.
+/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42)
+///   creates an object that can be used as a Matcher<T> for any type T
+///   where a ValueEqualsMatcher<T, int>(42) can be constructed.
+template <template <typename T> class MatcherT,
+          typename ReturnTypesF = void(AllNodeBaseTypes)>
+class PolymorphicMatcherWithParam0 {
+public:
+  typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+  template <typename T>
+  operator Matcher<T>() const {
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
+    return Matcher<T>(new MatcherT<T>());
+  }
+};
+
+template <template <typename T, typename P1> class MatcherT,
+          typename P1,
+          typename ReturnTypesF = void(AllNodeBaseTypes)>
+class PolymorphicMatcherWithParam1 {
+public:
+  explicit PolymorphicMatcherWithParam1(const P1 &Param1)
+      : Param1(Param1) {}
+
+  typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+
+  template <typename T>
+  operator Matcher<T>() const {
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
+    return Matcher<T>(new MatcherT<T, P1>(Param1));
+  }
+
+private:
+  const P1 Param1;
+};
+
+template <template <typename T, typename P1, typename P2> class MatcherT,
+          typename P1, typename P2,
+          typename ReturnTypesF = void(AllNodeBaseTypes)>
+class PolymorphicMatcherWithParam2 {
+public:
+  PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2)
+      : Param1(Param1), Param2(Param2) {}
+
+  typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+
+  template <typename T>
+  operator Matcher<T>() const {
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
+    return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
+  }
+
+private:
+  const P1 Param1;
+  const P2 Param2;
+};
+
+/// \brief Matches any instance of the given NodeType.
+///
+/// This is useful when a matcher syntactically requires a child matcher,
+/// but the context doesn't care. See for example: anything().
+///
+/// FIXME: Alternatively we could also create a IsAMatcher or something
+/// that checks that a dyn_cast is possible. This is purely needed for the
+/// difference between calling for example:
+///   record()
+/// and
+///   record(SomeMatcher)
+/// In the second case we need the correct type we were dyn_cast'ed to in order
+/// to get the right type for the inner matcher. In the first case we don't need
+/// that, but we use the type conversion anyway and insert a TrueMatcher.
+template <typename T>
+class TrueMatcher : public SingleNodeMatcherInterface<T>  {
+public:
+  bool matchesNode(const T &Node) const override {
+    return true;
+  }
+};
+
+/// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node
+/// to an ID if the inner matcher matches on the node.
+template <typename T>
+class IdMatcher : public MatcherInterface<T> {
+public:
+  /// \brief Creates an IdMatcher that binds to 'ID' if 'InnerMatcher' matches
+  /// the node.
+  IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher)
+      : ID(ID), InnerMatcher(InnerMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    bool Result = InnerMatcher.matches(Node, Finder, Builder);
+    if (Result) {
+      Builder->setBinding(ID, &Node);
+    }
+    return Result;
+  }
+
+private:
+  const std::string ID;
+  const Matcher<T> InnerMatcher;
+};
+
+/// \brief A Matcher that allows binding the node it matches to an id.
+///
+/// BindableMatcher provides a \a bind() method that allows binding the
+/// matched node to an id if the match was successful.
+template <typename T>
+class BindableMatcher : public Matcher<T> {
+public:
+  explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
+  explicit BindableMatcher(MatcherInterface<T> *Implementation)
+    : Matcher<T>(Implementation) {}
+
+  /// \brief Returns a matcher that will bind the matched node on a match.
+  ///
+  /// The returned matcher is equivalent to this matcher, but will
+  /// bind the matched node on a match.
+  Matcher<T> bind(StringRef ID) const {
+    return Matcher<T>(new IdMatcher<T>(ID, *this));
+  }
+};
+
+/// \brief Matches nodes of type T that have child nodes of type ChildT for
+/// which a specified child matcher matches.
+///
+/// ChildT must be an AST base type.
+template <typename T, typename ChildT>
+class HasMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<ChildT>::value,
+                "has only accepts base type matcher");
+
+public:
+  explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
+      : ChildMatcher(ChildMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Finder->matchesChildOf(
+        Node, ChildMatcher, Builder,
+        ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
+        ASTMatchFinder::BK_First);
+  }
+
+ private:
+  const Matcher<ChildT> ChildMatcher;
+};
+
+/// \brief Matches nodes of type T that have child nodes of type ChildT for
+/// which a specified child matcher matches. ChildT must be an AST base
+/// type.
+/// As opposed to the HasMatcher, the ForEachMatcher will produce a match
+/// for each child that matches.
+template <typename T, typename ChildT>
+class ForEachMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<ChildT>::value,
+                "for each only accepts base type matcher");
+
+ public:
+  explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
+      : ChildMatcher(ChildMatcher) {}
+
+  bool matches(const T& Node, ASTMatchFinder* Finder,
+               BoundNodesTreeBuilder* Builder) const override {
+    return Finder->matchesChildOf(
+      Node, ChildMatcher, Builder,
+      ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
+      ASTMatchFinder::BK_All);
+  }
+
+private:
+  const Matcher<ChildT> ChildMatcher;
+};
+
+/// \brief VariadicOperatorMatcher related types.
+/// @{
+
+/// \brief Function signature for any variadic operator. It takes the inner
+///   matchers as an array of DynTypedMatcher.
+typedef bool (*VariadicOperatorFunction)(
+    const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder,
+    BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
+
+/// \brief \c MatcherInterface<T> implementation for an variadic operator.
+template <typename T>
+class VariadicOperatorMatcherInterface : public MatcherInterface<T> {
+public:
+  VariadicOperatorMatcherInterface(VariadicOperatorFunction Func,
+                                   std::vector<DynTypedMatcher> InnerMatchers)
+      : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
+                InnerMatchers);
+  }
+
+private:
+  const VariadicOperatorFunction Func;
+  const std::vector<DynTypedMatcher> InnerMatchers;
+};
+
+/// \brief "No argument" placeholder to use as template paratemers.
+struct VariadicOperatorNoArg {};
+
+/// \brief Polymorphic matcher object that uses a \c VariadicOperatorFunction
+///   operator.
+///
+/// Input matchers can have any type (including other polymorphic matcher
+/// types), and the actual Matcher<T> is generated on demand with an implicit
+/// coversion operator.
+template <typename P1, typename P2 = VariadicOperatorNoArg,
+          typename P3 = VariadicOperatorNoArg,
+          typename P4 = VariadicOperatorNoArg,
+          typename P5 = VariadicOperatorNoArg,
+          typename P6 = VariadicOperatorNoArg,
+          typename P7 = VariadicOperatorNoArg,
+          typename P8 = VariadicOperatorNoArg,
+          typename P9 = VariadicOperatorNoArg>
+class VariadicOperatorMatcher {
+public:
+  VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
+                          const P2 &Param2 = VariadicOperatorNoArg(),
+                          const P3 &Param3 = VariadicOperatorNoArg(),
+                          const P4 &Param4 = VariadicOperatorNoArg(),
+                          const P5 &Param5 = VariadicOperatorNoArg(),
+                          const P6 &Param6 = VariadicOperatorNoArg(),
+                          const P7 &Param7 = VariadicOperatorNoArg(),
+                          const P8 &Param8 = VariadicOperatorNoArg(),
+                          const P9 &Param9 = VariadicOperatorNoArg())
+      : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
+        Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
+        Param8(Param8), Param9(Param9) {}
+
+  template <typename T> operator Matcher<T>() const {
+    std::vector<DynTypedMatcher> Matchers;
+    addMatcher<T>(Param1, Matchers);
+    addMatcher<T>(Param2, Matchers);
+    addMatcher<T>(Param3, Matchers);
+    addMatcher<T>(Param4, Matchers);
+    addMatcher<T>(Param5, Matchers);
+    addMatcher<T>(Param6, Matchers);
+    addMatcher<T>(Param7, Matchers);
+    addMatcher<T>(Param8, Matchers);
+    addMatcher<T>(Param9, Matchers);
+    return Matcher<T>(
+        new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
+  }
+
+private:
+  template <typename T>
+  static void addMatcher(const Matcher<T> &M,
+                         std::vector<DynTypedMatcher> &Matchers) {
+    Matchers.push_back(M);
+  }
+
+  /// \brief Overload to ignore \c VariadicOperatorNoArg arguments.
+  template <typename T>
+  static void addMatcher(VariadicOperatorNoArg,
+                         std::vector<DynTypedMatcher> &Matchers) {}
+
+  const VariadicOperatorFunction Func;
+  const P1 Param1;
+  const P2 Param2;
+  const P3 Param3;
+  const P4 Param4;
+  const P5 Param5;
+  const P6 Param6;
+  const P7 Param7;
+  const P8 Param8;
+  const P9 Param9;
+};
+
+/// \brief Overloaded function object to generate VariadicOperatorMatcher
+///   objects from arbitrary matchers.
+///
+/// It supports 1-9 argument overloaded operator(). More can be added if needed.
+template <unsigned MinCount, unsigned MaxCount>
+struct VariadicOperatorMatcherFunc {
+  VariadicOperatorFunction Func;
+
+  template <unsigned Count, typename T>
+  struct EnableIfValidArity
+      : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {};
+
+  template <typename M1>
+  typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
+  operator()(const M1 &P1) const {
+    return VariadicOperatorMatcher<M1>(Func, P1);
+  }
+  template <typename M1, typename M2>
+  typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
+  operator()(const M1 &P1, const M2 &P2) const {
+    return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
+  }
+  template <typename M1, typename M2, typename M3>
+  typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
+    return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
+  }
+  template <typename M1, typename M2, typename M3, typename M4>
+  typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5>
+  typename EnableIfValidArity<
+      5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
+                                                       P5);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6>
+  typename EnableIfValidArity<
+      6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
+        Func, P1, P2, P3, P4, P5, P6);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7>
+  typename EnableIfValidArity<
+      7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
+        Func, P1, P2, P3, P4, P5, P6, P7);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8>
+  typename EnableIfValidArity<
+      8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8, typename M9>
+  typename EnableIfValidArity<
+      9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
+             const M9 &P9) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+  }
+};
+
+/// @}
+
+/// \brief Matches nodes that do not match the provided matcher.
+///
+/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+                      ArrayRef<DynTypedMatcher> InnerMatchers);
+
+/// \brief Matches nodes for which all provided matchers match.
+bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
+
+/// \brief Matches nodes for which at least one of the provided matchers
+/// matches, but doesn't stop at the first match.
+bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                            ASTMatchFinder *Finder,
+                            BoundNodesTreeBuilder *Builder,
+                            ArrayRef<DynTypedMatcher> InnerMatchers);
+
+/// \brief Matches nodes for which at least one of the provided matchers
+/// matches.
+bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
+                           ASTMatchFinder *Finder,
+                           BoundNodesTreeBuilder *Builder,
+                           ArrayRef<DynTypedMatcher> InnerMatchers);
+
+template <typename T>
+inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
+  return Matcher<T>(new VariadicOperatorMatcherInterface<T>(
+      AllOfVariadicOperator, llvm::makeArrayRef(*this)));
+}
+
+/// \brief Creates a Matcher<T> that matches if all inner matchers match.
+template<typename T>
+BindableMatcher<T> makeAllOfComposite(
+    ArrayRef<const Matcher<T> *> InnerMatchers) {
+  std::vector<DynTypedMatcher> DynMatchers;
+  for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
+    DynMatchers.push_back(*InnerMatchers[i]);
+  }
+  return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>(
+      AllOfVariadicOperator, std::move(DynMatchers)));
+}
+
+/// \brief Creates a Matcher<T> that matches if
+/// T is dyn_cast'able into InnerT and all inner matchers match.
+///
+/// Returns BindableMatcher, as matchers that use dyn_cast have
+/// the same object both to match on and to run submatchers on,
+/// so there is no ambiguity with what gets bound.
+template<typename T, typename InnerT>
+BindableMatcher<T> makeDynCastAllOfComposite(
+    ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
+  return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers))
+                                .unconditionalConvertTo<T>());
+}
+
+/// \brief Matches nodes of type T that have at least one descendant node of
+/// type DescendantT for which the given inner matcher matches.
+///
+/// DescendantT must be an AST base type.
+template <typename T, typename DescendantT>
+class HasDescendantMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<DescendantT>::value,
+                "has descendant only accepts base type matcher");
+
+public:
+  explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
+      : DescendantMatcher(DescendantMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Finder->matchesDescendantOf(
+        Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First);
+  }
+
+ private:
+  const Matcher<DescendantT> DescendantMatcher;
+};
+
+/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT
+/// for which the given inner matcher matches.
+///
+/// \c ParentT must be an AST base type.
+template <typename T, typename ParentT>
+class HasParentMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<ParentT>::value,
+                "has parent only accepts base type matcher");
+
+public:
+  explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
+      : ParentMatcher(ParentMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Finder->matchesAncestorOf(
+        Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
+  }
+
+ private:
+  const Matcher<ParentT> ParentMatcher;
+};
+
+/// \brief Matches nodes of type \c T that have at least one ancestor node of
+/// type \c AncestorT for which the given inner matcher matches.
+///
+/// \c AncestorT must be an AST base type.
+template <typename T, typename AncestorT>
+class HasAncestorMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<AncestorT>::value,
+                "has ancestor only accepts base type matcher");
+
+public:
+  explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
+      : AncestorMatcher(AncestorMatcher) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    return Finder->matchesAncestorOf(
+        Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
+  }
+
+ private:
+  const Matcher<AncestorT> AncestorMatcher;
+};
+
+/// \brief Matches nodes of type T that have at least one descendant node of
+/// type DescendantT for which the given inner matcher matches.
+///
+/// DescendantT must be an AST base type.
+/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
+/// for each descendant node that matches instead of only for the first.
+template <typename T, typename DescendantT>
+class ForEachDescendantMatcher : public MatcherInterface<T> {
+  static_assert(IsBaseType<DescendantT>::value,
+                "for each descendant only accepts base type matcher");
+
+ public:
+  explicit ForEachDescendantMatcher(
+      const Matcher<DescendantT>& DescendantMatcher)
+      : DescendantMatcher(DescendantMatcher) {}
+
+  bool matches(const T& Node, ASTMatchFinder* Finder,
+               BoundNodesTreeBuilder* Builder) const override {
+    return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder,
+                                       ASTMatchFinder::BK_All);
+  }
+
+private:
+  const Matcher<DescendantT> DescendantMatcher;
+};
+
+/// \brief Matches on nodes that have a getValue() method if getValue() equals
+/// the value the ValueEqualsMatcher was constructed with.
+template <typename T, typename ValueT>
+class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
+  static_assert(std::is_base_of<CharacterLiteral, T>::value ||
+                std::is_base_of<CXXBoolLiteralExpr, T>::value ||
+                std::is_base_of<FloatingLiteral, T>::value ||
+                std::is_base_of<IntegerLiteral, T>::value,
+                "the node must have a getValue method");
+
+public:
+  explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
+      : ExpectedValue(ExpectedValue) {}
+
+  bool matchesNode(const T &Node) const override {
+    return Node.getValue() == ExpectedValue;
+  }
+
+private:
+  const ValueT ExpectedValue;
+};
+
+/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
+/// variadic functor that takes a number of Matcher<TargetT> and returns a
+/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
+/// given matchers, if SourceT can be dynamically casted into TargetT.
+///
+/// For example:
+///   const VariadicDynCastAllOfMatcher<
+///       Decl, CXXRecordDecl> record;
+/// Creates a functor record(...) that creates a Matcher<Decl> given
+/// a variable number of arguments of type Matcher<CXXRecordDecl>.
+/// The returned matcher matches if the given Decl can by dynamically
+/// casted to CXXRecordDecl and all given matchers match.
+template <typename SourceT, typename TargetT>
+class VariadicDynCastAllOfMatcher
+    : public llvm::VariadicFunction<
+        BindableMatcher<SourceT>, Matcher<TargetT>,
+        makeDynCastAllOfComposite<SourceT, TargetT> > {
+public:
+  VariadicDynCastAllOfMatcher() {}
+};
+
+/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
+/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
+/// nodes that are matched by all of the given matchers.
+///
+/// For example:
+///   const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+/// Creates a functor nestedNameSpecifier(...) that creates a
+/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
+/// \c Matcher<NestedNameSpecifier>.
+/// The returned matcher matches if all given matchers match.
+template <typename T>
+class VariadicAllOfMatcher : public llvm::VariadicFunction<
+                               BindableMatcher<T>, Matcher<T>,
+                               makeAllOfComposite<T> > {
+public:
+  VariadicAllOfMatcher() {}
+};
+
+/// \brief Matches nodes of type \c TLoc for which the inner
+/// \c Matcher<T> matches.
+template <typename TLoc, typename T>
+class LocMatcher : public MatcherInterface<TLoc> {
+public:
+  explicit LocMatcher(const Matcher<T> &InnerMatcher)
+    : InnerMatcher(InnerMatcher) {}
+
+  bool matches(const TLoc &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    if (!Node)
+      return false;
+    return InnerMatcher.matches(*extract(Node), Finder, Builder);
+  }
+
+private:
+  const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const {
+    return Loc.getNestedNameSpecifier();
+  }
+
+  const Matcher<T> InnerMatcher;
+};
+
+/// \brief Matches \c TypeLocs based on an inner matcher matching a certain
+/// \c QualType.
+///
+/// Used to implement the \c loc() matcher.
+class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
+public:
+  explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
+      : InnerMatcher(InnerMatcher) {}
+
+  bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    if (!Node)
+      return false;
+    return InnerMatcher.matches(Node.getType(), Finder, Builder);
+  }
+
+private:
+  const Matcher<QualType> InnerMatcher;
+};
+
+/// \brief Matches nodes of type \c T for which the inner matcher matches on a
+/// another node of type \c T that can be reached using a given traverse
+/// function.
+template <typename T>
+class TypeTraverseMatcher : public MatcherInterface<T> {
+public:
+  explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
+                               QualType (T::*TraverseFunction)() const)
+      : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    QualType NextNode = (Node.*TraverseFunction)();
+    if (NextNode.isNull())
+      return false;
+    return InnerMatcher.matches(NextNode, Finder, Builder);
+  }
+
+private:
+  const Matcher<QualType> InnerMatcher;
+  QualType (T::*TraverseFunction)() const;
+};
+
+/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
+/// matcher matches on a another node of type \c T that can be reached using a
+/// given traverse function.
+template <typename T>
+class TypeLocTraverseMatcher : public MatcherInterface<T> {
+public:
+  explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
+                                  TypeLoc (T::*TraverseFunction)() const)
+      : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
+
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
+    TypeLoc NextNode = (Node.*TraverseFunction)();
+    if (!NextNode)
+      return false;
+    return InnerMatcher.matches(NextNode, Finder, Builder);
+  }
+
+private:
+  const Matcher<TypeLoc> InnerMatcher;
+  TypeLoc (T::*TraverseFunction)() const;
+};
+
+/// \brief Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
+/// \c OuterT is any type that is supported by \c Getter.
+///
+/// \code Getter<OuterT>::value() \endcode returns a
+/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
+/// object into a \c InnerT
+template <typename InnerTBase,
+          template <typename OuterT> class Getter,
+          template <typename OuterT> class MatcherImpl,
+          typename ReturnTypesF>
+class TypeTraversePolymorphicMatcher {
+private:
+  typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
+                                         ReturnTypesF> Self;
+  static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
+
+public:
+  typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
+
+  explicit TypeTraversePolymorphicMatcher(
+      ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
+      : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
+
+  template <typename OuterT> operator Matcher<OuterT>() const {
+    return Matcher<OuterT>(
+        new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
+  }
+
+  struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>,
+                                              &Self::create> {
+    Func() {}
+  };
+
+private:
+  const Matcher<InnerTBase> InnerMatcher;
+};
+
+// Define the create() method out of line to silence a GCC warning about
+// the struct "Func" having greater visibility than its base, which comes from
+// using the flag -fvisibility-inlines-hidden.
+template <typename InnerTBase, template <typename OuterT> class Getter,
+          template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
+TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
+TypeTraversePolymorphicMatcher<
+    InnerTBase, Getter, MatcherImpl,
+    ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
+  return Self(InnerMatchers);
+}
+
+// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
+// APIs for accessing the template argument list.
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
+  return D.getTemplateArgs().asArray();
+}
+
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
+  return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+}
+
+struct NotEqualsBoundNodePredicate {
+  bool operator()(const internal::BoundNodesMap &Nodes) const {
+    return Nodes.getNode(ID) != Node;
+  }
+  std::string ID;
+  ast_type_traits::DynTypedNode Node;
+};
+
+} // end namespace internal
+} // end namespace ast_matchers
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
new file mode 100644
index 0000000..563372a
--- /dev/null
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -0,0 +1,355 @@
+//===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Defines macros that enable us to define new matchers in a single place.
+//  Since a matcher is a function which returns a Matcher<T> object, where
+//  T is the type of the actual implementation of the matcher, the macros allow
+//  us to write matchers like functions and take care of the definition of the
+//  class boilerplate.
+//
+//  Note that when you define a matcher with an AST_MATCHER* macro, only the
+//  function which creates the matcher goes into the current namespace - the
+//  class that implements the actual matcher, which gets returned by the
+//  generator function, is put into the 'internal' namespace. This allows us
+//  to only have the functions (which is all the user cares about) in the
+//  'ast_matchers' namespace and hide the boilerplate.
+//
+//  To define a matcher in user code, always put it into the clang::ast_matchers
+//  namespace and refer to the internal types via the 'internal::':
+//
+//  namespace clang {
+//  namespace ast_matchers {
+//  AST_MATCHER_P(MemberExpr, Member,
+//                internal::Matcher<ValueDecl>, InnerMatcher) {
+//    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
+//  }
+//  } // end namespace ast_matchers
+//  } // end namespace clang
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
+#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
+
+/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
+/// defines a single-parameter function named DefineMatcher() that returns a
+/// ReturnType object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Param:                 the parameter passed to the function; its type
+///                          is ParamType.
+///
+/// The code should return an instance of ReturnType.
+#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
+  AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
+                                  0)
+#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
+                                        Param, OverloadId)                     \
+  inline ReturnType DefineMatcher(ParamType const &Param);                     \
+  typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
+  inline ReturnType DefineMatcher(ParamType const &Param)
+
+/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
+/// defines a zero parameter function named DefineMatcher() that returns a
+/// Matcher<Type> object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Node:                  the AST node being matched; its type is Type.
+///   Finder:                an ASTMatchFinder*.
+///   Builder:               a BoundNodesTreeBuilder*.
+///
+/// The code should return true if 'Node' matches.
+#define AST_MATCHER(Type, DefineMatcher)                                       \
+  namespace internal {                                                         \
+  class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
+  public:                                                                      \
+    explicit matcher_##DefineMatcher##Matcher() {}                             \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
+  };                                                                           \
+  }                                                                            \
+  inline internal::Matcher<Type> DefineMatcher() {                             \
+    return internal::makeMatcher(                                              \
+        new internal::matcher_##DefineMatcher##Matcher());                     \
+  }                                                                            \
+  inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
+      const Type &Node, ASTMatchFinder *Finder,                                \
+      BoundNodesTreeBuilder *Builder) const
+
+/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
+/// defines a single-parameter function named DefineMatcher() that returns a
+/// Matcher<Type> object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Node:                  the AST node being matched; its type is Type.
+///   Param:                 the parameter passed to the function; its type
+///                          is ParamType.
+///   Finder:                an ASTMatchFinder*.
+///   Builder:               a BoundNodesTreeBuilder*.
+///
+/// The code should return true if 'Node' matches.
+#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
+  AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
+
+#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
+                               OverloadId)                                     \
+  namespace internal {                                                         \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public MatcherInterface<Type> {                                        \
+  public:                                                                      \
+    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
+        ParamType const &A##Param)                                             \
+        : Param(A##Param) {}                                                   \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
+                                                                               \
+  private:                                                                     \
+    ParamType const Param;                                                     \
+  };                                                                           \
+  }                                                                            \
+  inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
+    return internal::makeMatcher(                                              \
+        new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
+  }                                                                            \
+  typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
+      ParamType const &Param);                                                 \
+  inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
+      const Type &Node, ASTMatchFinder *Finder,                                \
+      BoundNodesTreeBuilder *Builder) const
+
+/// \brief AST_MATCHER_P2(
+///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
+/// defines a two-parameter function named DefineMatcher() that returns a
+/// Matcher<Type> object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Node:                  the AST node being matched; its type is Type.
+///   Param1, Param2:        the parameters passed to the function; their types
+///                          are ParamType1 and ParamType2.
+///   Finder:                an ASTMatchFinder*.
+///   Builder:               a BoundNodesTreeBuilder*.
+///
+/// The code should return true if 'Node' matches.
+#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
+                       Param2)                                                 \
+  AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
+                          Param2, 0)
+
+#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
+                                ParamType2, Param2, OverloadId)                \
+  namespace internal {                                                         \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public MatcherInterface<Type> {                                        \
+  public:                                                                      \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
+        : Param1(A##Param1), Param2(A##Param2) {}                              \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
+                                                                               \
+  private:                                                                     \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
+  };                                                                           \
+  }                                                                            \
+  inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
+                                               ParamType2 const &Param2) {     \
+    return internal::makeMatcher(                                              \
+        new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
+                                                                   Param2));   \
+  }                                                                            \
+  typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
+  inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
+      const Type &Node, ASTMatchFinder *Finder,                                \
+      BoundNodesTreeBuilder *Builder) const
+
+/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
+///   macros.
+///
+/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
+/// will look at that as two arguments. However, you can pass
+/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
+/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
+/// extract the TypeList object.
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
+  void(internal::TypeList<t1, t2>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
+  void(internal::TypeList<t1, t2, t3>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
+  void(internal::TypeList<t1, t2, t3, t4>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
+  void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
+
+/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
+/// defines a single-parameter function named DefineMatcher() that is
+/// polymorphic in the return type.
+///
+/// The variables are the same as for AST_MATCHER, but NodeType will be deduced
+/// from the calling context.
+#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
+  namespace internal {                                                         \
+  template <typename NodeType>                                                 \
+  class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
+  public:                                                                      \
+    bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
+                 BoundNodesTreeBuilder *Builder) const override;               \
+  };                                                                           \
+  }                                                                            \
+  inline internal::PolymorphicMatcherWithParam0<                               \
+      internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
+  DefineMatcher() {                                                            \
+    return internal::PolymorphicMatcherWithParam0<                             \
+        internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
+  }                                                                            \
+  template <typename NodeType>                                                 \
+  bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
+      const NodeType &Node, ASTMatchFinder *Finder,                            \
+      BoundNodesTreeBuilder *Builder) const
+
+/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
+/// defines a single-parameter function named DefineMatcher() that is
+/// polymorphic in the return type.
+///
+/// The variables are the same as for
+/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
+/// of the matcher Matcher<NodeType> returned by the function matcher().
+///
+/// FIXME: Pull out common code with above macro?
+#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
+                                  Param)                                       \
+  AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
+                                     Param, 0)
+
+#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
+                                           ParamType, Param, OverloadId)       \
+  namespace internal {                                                         \
+  template <typename NodeType, typename ParamT>                                \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public MatcherInterface<NodeType> {                                    \
+  public:                                                                      \
+    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
+        ParamType const &A##Param)                                             \
+        : Param(A##Param) {}                                                   \
+    bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
+                 BoundNodesTreeBuilder *Builder) const override;               \
+                                                                               \
+  private:                                                                     \
+    ParamType const Param;                                                     \
+  };                                                                           \
+  }                                                                            \
+  inline internal::PolymorphicMatcherWithParam1<                               \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
+      ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
+    return internal::PolymorphicMatcherWithParam1<                             \
+        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
+        ReturnTypesF>(Param);                                                  \
+  }                                                                            \
+  typedef internal::PolymorphicMatcherWithParam1<                              \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
+      ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
+      ParamType const &Param);                                                 \
+  template <typename NodeType, typename ParamT>                                \
+  bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
+      NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
+                                 BoundNodesTreeBuilder *Builder) const
+
+/// \brief AST_POLYMORPHIC_MATCHER_P2(
+///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
+/// defines a two-parameter function named matcher() that is polymorphic in
+/// the return type.
+///
+/// The variables are the same as for AST_MATCHER_P2, with the
+/// addition of NodeType, which specifies the node type of the matcher
+/// Matcher<NodeType> returned by the function DefineMatcher().
+#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
+                                   Param1, ParamType2, Param2)                 \
+  AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
+                                      Param1, ParamType2, Param2, 0)
+
+#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
+                                            ParamType1, Param1, ParamType2,    \
+                                            Param2, OverloadId)                \
+  namespace internal {                                                         \
+  template <typename NodeType, typename ParamT1, typename ParamT2>             \
+  class matcher_##DefineMatcher##OverloadId##Matcher                           \
+      : public MatcherInterface<NodeType> {                                    \
+  public:                                                                      \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
+        : Param1(A##Param1), Param2(A##Param2) {}                              \
+     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
+                  BoundNodesTreeBuilder *Builder) const override;              \
+                                                                               \
+  private:                                                                     \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
+  };                                                                           \
+  }                                                                            \
+  inline internal::PolymorphicMatcherWithParam2<                               \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
+      ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
+                                              ParamType2 const &Param2) {      \
+    return internal::PolymorphicMatcherWithParam2<                             \
+        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
+        ParamType2, ReturnTypesF>(Param1, Param2);                             \
+  }                                                                            \
+  typedef internal::PolymorphicMatcherWithParam2<                              \
+      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
+      ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
+  template <typename NodeType, typename ParamT1, typename ParamT2>             \
+  bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
+      NodeType, ParamT1, ParamT2>::matches(                                    \
+      const NodeType &Node, ASTMatchFinder *Finder,                            \
+      BoundNodesTreeBuilder *Builder) const
+
+/// \brief Creates a variadic matcher for both a specific \c Type as well as
+/// the corresponding \c TypeLoc.
+#define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
+  const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
+// FIXME: add a matcher for TypeLoc derived classes using its custom casting
+// API (no longer dyn_cast) if/when we need such matching
+
+/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
+/// the matcher \c MatcherName that can be used to traverse from one \c Type
+/// to another.
+///
+/// For a specific \c SpecificType, the traversal is done using 
+/// \c SpecificType::FunctionName. The existence of such a function determines
+/// whether a corresponding matcher can be used on \c SpecificType.
+#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
+  namespace internal {                                                         \
+  template <typename T> struct TypeMatcher##MatcherName##Getter {              \
+    static QualType (T::*value())() const { return &T::FunctionName; }         \
+  };                                                                           \
+  }                                                                            \
+  const internal::TypeTraversePolymorphicMatcher<                              \
+      QualType, internal::TypeMatcher##MatcherName##Getter,                    \
+      internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
+
+/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
+/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
+#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
+  namespace internal {                                                         \
+  template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
+    static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
+  };                                                                           \
+  }                                                                            \
+  const internal::TypeTraversePolymorphicMatcher<                              \
+      TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
+      internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
+  AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
+
+#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
new file mode 100644
index 0000000..82a14f1
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -0,0 +1,185 @@
+//===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Diagnostics class to manage error messages.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
+
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+struct SourceLocation {
+  SourceLocation() : Line(), Column() {}
+  unsigned Line;
+  unsigned Column;
+};
+
+struct SourceRange {
+  SourceLocation Start;
+  SourceLocation End;
+};
+
+/// \brief A VariantValue instance annotated with its parser context.
+struct ParserValue {
+  ParserValue() : Text(), Range(), Value() {}
+  StringRef Text;
+  SourceRange Range;
+  VariantValue Value;
+};
+
+/// \brief Helper class to manage error messages.
+class Diagnostics {
+public:
+  /// \brief Parser context types.
+  enum ContextType {
+    CT_MatcherArg = 0,
+    CT_MatcherConstruct = 1
+  };
+
+  /// \brief All errors from the system.
+  enum ErrorType {
+    ET_None = 0,
+
+    ET_RegistryMatcherNotFound = 1,
+    ET_RegistryWrongArgCount = 2,
+    ET_RegistryWrongArgType = 3,
+    ET_RegistryNotBindable = 4,
+    ET_RegistryAmbiguousOverload = 5,
+    ET_RegistryValueNotFound = 6,
+
+    ET_ParserStringError = 100,
+    ET_ParserNoOpenParen = 101,
+    ET_ParserNoCloseParen = 102,
+    ET_ParserNoComma = 103,
+    ET_ParserNoCode = 104,
+    ET_ParserNotAMatcher = 105,
+    ET_ParserInvalidToken = 106,
+    ET_ParserMalformedBindExpr = 107,
+    ET_ParserTrailingCode = 108,
+    ET_ParserUnsignedError = 109,
+    ET_ParserOverloadedType = 110
+  };
+
+  /// \brief Helper stream class.
+  class ArgStream {
+  public:
+    ArgStream(std::vector<std::string> *Out) : Out(Out) {}
+    template <class T> ArgStream &operator<<(const T &Arg) {
+      return operator<<(Twine(Arg));
+    }
+    ArgStream &operator<<(const Twine &Arg);
+
+  private:
+    std::vector<std::string> *Out;
+  };
+
+  /// \brief Class defining a parser context.
+  ///
+  /// Used by the parser to specify (possibly recursive) contexts where the
+  /// parsing/construction can fail. Any error triggered within a context will
+  /// keep information about the context chain.
+  /// This class should be used as a RAII instance in the stack.
+  struct Context {
+  public:
+    /// \brief About to call the constructor for a matcher.
+    enum ConstructMatcherEnum { ConstructMatcher };
+    Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName,
+            const SourceRange &MatcherRange);
+    /// \brief About to recurse into parsing one argument for a matcher.
+    enum MatcherArgEnum { MatcherArg };
+    Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
+            const SourceRange &MatcherRange, unsigned ArgNumber);
+    ~Context();
+
+  private:
+    Diagnostics *const Error;
+  };
+
+  /// \brief Context for overloaded matcher construction.
+  ///
+  /// This context will take care of merging all errors that happen within it
+  /// as "candidate" overloads for the same matcher.
+  struct OverloadContext {
+  public:
+   OverloadContext(Diagnostics* Error);
+   ~OverloadContext();
+
+   /// \brief Revert all errors that happened within this context.
+   void revertErrors();
+
+  private:
+    Diagnostics *const Error;
+    unsigned BeginIndex;
+  };
+
+  /// \brief Add an error to the diagnostics.
+  ///
+  /// All the context information will be kept on the error message.
+  /// \return a helper class to allow the caller to pass the arguments for the
+  /// error message, using the << operator.
+  ArgStream addError(const SourceRange &Range, ErrorType Error);
+
+  /// \brief Information stored for one frame of the context.
+  struct ContextFrame {
+    ContextType Type;
+    SourceRange Range;
+    std::vector<std::string> Args;
+  };
+
+  /// \brief Information stored for each error found.
+  struct ErrorContent {
+    std::vector<ContextFrame> ContextStack;
+    struct Message {
+      SourceRange Range;
+      ErrorType Type;
+      std::vector<std::string> Args;
+    };
+    std::vector<Message> Messages;
+  };
+  ArrayRef<ErrorContent> errors() const { return Errors; }
+
+  /// \brief Returns a simple string representation of each error.
+  ///
+  /// Each error only shows the error message without any context.
+  void printToStream(llvm::raw_ostream &OS) const;
+  std::string toString() const;
+
+  /// \brief Returns the full string representation of each error.
+  ///
+  /// Each error message contains the full context.
+  void printToStreamFull(llvm::raw_ostream &OS) const;
+  std::string toStringFull() const;
+
+private:
+  /// \brief Helper function used by the constructors of ContextFrame.
+  ArgStream pushContextFrame(ContextType Type, SourceRange Range);
+
+  std::vector<ContextFrame> ContextStack;
+  std::vector<ErrorContent> Errors;
+};
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
+
+#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
new file mode 100644
index 0000000..4045f57
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -0,0 +1,207 @@
+//===--- Parser.h - Matcher expression parser -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Simple matcher expression parser.
+///
+/// The parser understands matcher expressions of the form:
+///   MatcherName(Arg0, Arg1, ..., ArgN)
+/// as well as simple types like strings.
+/// The parser does not know how to process the matchers. It delegates this task
+/// to a Sema object received as an argument.
+///
+/// \code
+/// Grammar for the expressions supported:
+/// <Expression>        := <Literal> | <NamedValue> | <MatcherExpression>
+/// <Literal>           := <StringLiteral> | <Unsigned>
+/// <StringLiteral>     := "quoted string"
+/// <Unsigned>          := [0-9]+
+/// <NamedValue>        := <Identifier>
+/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
+///                        <Identifier>(<ArgumentList>).bind(<StringLiteral>)
+/// <Identifier>        := [a-zA-Z]+
+/// <ArgumentList>      := <Expression> | <Expression>,<ArgumentList>
+/// \endcode
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
+
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+/// \brief Matcher expression parser.
+class Parser {
+public:
+  /// \brief Interface to connect the parser with the registry and more.
+  ///
+  /// The parser uses the Sema instance passed into
+  /// parseMatcherExpression() to handle all matcher tokens. The simplest
+  /// processor implementation would simply call into the registry to create
+  /// the matchers.
+  /// However, a more complex processor might decide to intercept the matcher
+  /// creation and do some extra work. For example, it could apply some
+  /// transformation to the matcher by adding some id() nodes, or could detect
+  /// specific matcher nodes for more efficient lookup.
+  class Sema {
+  public:
+    virtual ~Sema();
+
+    /// \brief Lookup a value by name.
+    ///
+    /// This can be used in the Sema layer to declare known constants or to
+    /// allow to split an expression in pieces.
+    ///
+    /// \param Name The name of the value to lookup.
+    ///
+    /// \return The named value. It could be any type that VariantValue
+    ///   supports. An empty value means that the name is not recognized.
+    virtual VariantValue getNamedValue(StringRef Name);
+
+    /// \brief Process a matcher expression.
+    ///
+    /// All the arguments passed here have already been processed.
+    ///
+    /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
+    ///
+    /// \param NameRange The location of the name in the matcher source.
+    ///   Useful for error reporting.
+    ///
+    /// \param BindID The ID to use to bind the matcher, or a null \c StringRef
+    ///   if no ID is specified.
+    ///
+    /// \param Args The argument list for the matcher.
+    ///
+    /// \return The matcher objects constructed by the processor, or a null
+    ///   matcher if an error occurred. In that case, \c Error will contain a
+    ///   description of the error.
+    virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
+                                                  const SourceRange &NameRange,
+                                                  StringRef BindID,
+                                                  ArrayRef<ParserValue> Args,
+                                                  Diagnostics *Error) = 0;
+
+    /// \brief Look up a matcher by name.
+    ///
+    /// \param MatcherName The matcher name found by the parser.
+    ///
+    /// \return The matcher constructor, or Optional<MatcherCtor>() if not
+    /// found.
+    virtual llvm::Optional<MatcherCtor>
+    lookupMatcherCtor(StringRef MatcherName) = 0;
+  };
+
+  /// \brief Sema implementation that uses the matcher registry to process the
+  ///   tokens.
+  class RegistrySema : public Parser::Sema {
+   public:
+    virtual ~RegistrySema();
+
+    llvm::Optional<MatcherCtor>
+    lookupMatcherCtor(StringRef MatcherName) override;
+
+    VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
+                                          const SourceRange &NameRange,
+                                          StringRef BindID,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) override;
+  };
+
+  /// \brief Parse a matcher expression, creating matchers from the registry.
+  ///
+  /// This overload creates matchers calling directly into the registry. If the
+  /// caller needs more control over how the matchers are created, then it can
+  /// use the overload below that takes a Sema.
+  ///
+  /// \param MatcherCode The matcher expression to parse.
+  ///
+  /// \return The matcher object constructed, or an empty Optional if an error
+  ///   occurred.
+  ///   In that case, \c Error will contain a description of the error.
+  ///   The caller takes ownership of the DynTypedMatcher object returned.
+  static llvm::Optional<DynTypedMatcher>
+  parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error);
+
+  /// \brief Parse a matcher expression.
+  ///
+  /// \param MatcherCode The matcher expression to parse.
+  ///
+  /// \param S The Sema instance that will help the parser
+  ///   construct the matchers.
+  /// \return The matcher object constructed by the processor, or an empty
+  ///   Optional if an error occurred. In that case, \c Error will contain a
+  ///   description of the error.
+  ///   The caller takes ownership of the DynTypedMatcher object returned.
+  static llvm::Optional<DynTypedMatcher>
+  parseMatcherExpression(StringRef MatcherCode, Sema *S, Diagnostics *Error);
+
+  /// \brief Parse an expression, creating matchers from the registry.
+  ///
+  /// Parses any expression supported by this parser. In general, the
+  /// \c parseMatcherExpression function is a better approach to get a matcher
+  /// object.
+  static bool parseExpression(StringRef Code, VariantValue *Value,
+                              Diagnostics *Error);
+
+  /// \brief Parse an expression.
+  ///
+  /// Parses any expression supported by this parser. In general, the
+  /// \c parseMatcherExpression function is a better approach to get a matcher
+  /// object.
+  static bool parseExpression(StringRef Code, Sema *S,
+                              VariantValue *Value, Diagnostics *Error);
+
+  /// \brief Complete an expression at the given offset.
+  ///
+  /// \return The list of completions, which may be empty if there are no
+  /// available completions or if an error occurred.
+  static std::vector<MatcherCompletion>
+  completeExpression(StringRef Code, unsigned CompletionOffset);
+
+private:
+  class CodeTokenizer;
+  struct ScopedContextEntry;
+  struct TokenInfo;
+
+  Parser(CodeTokenizer *Tokenizer, Sema *S,
+         Diagnostics *Error);
+
+  bool parseExpressionImpl(VariantValue *Value);
+  bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
+                                  VariantValue *Value);
+  bool parseIdentifierPrefixImpl(VariantValue *Value);
+
+  void addCompletion(const TokenInfo &CompToken, StringRef TypedText,
+                     StringRef Decl);
+  void addExpressionCompletions();
+
+  CodeTokenizer *const Tokenizer;
+  Sema *const S;
+  Diagnostics *const Error;
+
+  typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
+  ContextStackTy ContextStack;
+  std::vector<MatcherCompletion> Completions;
+};
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
+
+#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
new file mode 100644
index 0000000..faa9254
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -0,0 +1,124 @@
+//===--- Registry.h - Matcher registry -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Registry of all known matchers.
+///
+/// The registry provides a generic interface to construct any matcher by name.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
+
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+namespace internal {
+class MatcherDescriptor;
+}
+
+typedef const internal::MatcherDescriptor *MatcherCtor;
+
+struct MatcherCompletion {
+  MatcherCompletion() {}
+  MatcherCompletion(StringRef TypedText, StringRef MatcherDecl)
+      : TypedText(TypedText), MatcherDecl(MatcherDecl) {}
+
+  /// \brief The text to type to select this matcher.
+  std::string TypedText;
+
+  /// \brief The "declaration" of the matcher, with type information.
+  std::string MatcherDecl;
+
+  bool operator==(const MatcherCompletion &Other) const {
+    return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
+  }
+};
+
+class Registry {
+public:
+  /// \brief Look up a matcher in the registry by name,
+  ///
+  /// \return An opaque value which may be used to refer to the matcher
+  /// constructor, or Optional<MatcherCtor>() if not found.
+  static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
+
+  /// \brief Compute the list of completions for \p Context.
+  ///
+  /// Each element of \p Context represents a matcher invocation, going from
+  /// outermost to innermost. Elements are pairs consisting of a reference to the
+  /// matcher constructor and the index of the next element in the argument list
+  /// of that matcher (or for the last element, the index of the completion
+  /// point in the argument list). An empty list requests completion for the
+  /// root matcher.
+  ///
+  /// The completions are ordered first by decreasing relevance, then
+  /// alphabetically.  Relevance is determined by how closely the matcher's
+  /// type matches that of the context. For example, if the innermost matcher
+  /// takes a FunctionDecl matcher, the FunctionDecl matchers are returned
+  /// first, followed by the ValueDecl matchers, then NamedDecl, then Decl, then
+  /// polymorphic matchers.
+  ///
+  /// Matchers which are technically convertible to the innermost context but
+  /// which would match either all or no nodes are excluded. For example,
+  /// namedDecl and varDecl are excluded in a FunctionDecl context, because
+  /// those matchers would match respectively all or no nodes in such a context.
+  static std::vector<MatcherCompletion>
+  getCompletions(ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
+
+  /// \brief Construct a matcher from the registry.
+  ///
+  /// \param Ctor The matcher constructor to instantiate.
+  ///
+  /// \param NameRange The location of the name in the matcher source.
+  ///   Useful for error reporting.
+  ///
+  /// \param Args The argument list for the matcher. The number and types of the
+  ///   values must be valid for the matcher requested. Otherwise, the function
+  ///   will return an error.
+  ///
+  /// \return The matcher object constructed if no error was found.
+  ///   A null matcher if the number of arguments or argument types do not match
+  ///   the signature.  In that case \c Error will contain the description of
+  ///   the error.
+  static VariantMatcher constructMatcher(MatcherCtor Ctor,
+                                         const SourceRange &NameRange,
+                                         ArrayRef<ParserValue> Args,
+                                         Diagnostics *Error);
+
+  /// \brief Construct a matcher from the registry and bind it.
+  ///
+  /// Similar the \c constructMatcher() above, but it then tries to bind the
+  /// matcher to the specified \c BindID.
+  /// If the matcher is not bindable, it sets an error in \c Error and returns
+  /// a null matcher.
+  static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
+                                              const SourceRange &NameRange,
+                                              StringRef BindID,
+                                              ArrayRef<ParserValue> Args,
+                                              Diagnostics *Error);
+
+private:
+  Registry() LLVM_DELETED_FUNCTION;
+};
+
+}  // namespace dynamic
+}  // namespace ast_matchers
+}  // namespace clang
+
+#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
new file mode 100644
index 0000000..b25267b
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -0,0 +1,260 @@
+//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Polymorphic value type.
+///
+/// Supports all the types required for dynamic Matcher construction.
+///  Used by the registry to construct matchers in a generic way.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Twine.h"
+#include <memory>
+#include <vector>
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+using ast_matchers::internal::DynTypedMatcher;
+
+/// \brief A variant matcher object.
+///
+/// The purpose of this object is to abstract simple and polymorphic matchers
+/// into a single object type.
+/// Polymorphic matchers might be implemented as a list of all the possible
+/// overloads of the matcher. \c VariantMatcher knows how to select the
+/// appropriate overload when needed.
+/// To get a real matcher object out of a \c VariantMatcher you can do:
+///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
+///    to decide which matcher to return. Eg. it contains only a single
+///    matcher, or a polymorphic one with only one overload.
+///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
+///    the underlying matcher(s) can unambiguously return a Matcher<T>.
+class VariantMatcher {
+  /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
+  class MatcherOps {
+  public:
+    virtual ~MatcherOps();
+    virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+                                  bool &IsExactMatch) const = 0;
+    virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
+    virtual void constructVariadicOperator(
+        ast_matchers::internal::VariadicOperatorFunction Func,
+        ArrayRef<VariantMatcher> InnerMatchers) = 0;
+  };
+
+  /// \brief Payload interface to be specialized by each matcher type.
+  ///
+  /// It follows a similar interface as VariantMatcher itself.
+  class Payload : public RefCountedBaseVPTR {
+  public:
+    virtual ~Payload();
+    virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
+    virtual std::string getTypeAsString() const = 0;
+    virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
+  };
+
+public:
+  /// \brief A null matcher.
+  VariantMatcher();
+
+  /// \brief Clones the provided matcher.
+  static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
+
+  /// \brief Clones the provided matchers.
+  ///
+  /// They should be the result of a polymorphic matcher.
+  static VariantMatcher
+  PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
+
+  /// \brief Creates a 'variadic' operator matcher.
+  ///
+  /// It will bind to the appropriate type on getTypedMatcher<T>().
+  static VariantMatcher VariadicOperatorMatcher(
+      ast_matchers::internal::VariadicOperatorFunction Func,
+      std::vector<VariantMatcher> Args);
+
+  /// \brief Makes the matcher the "null" matcher.
+  void reset();
+
+  /// \brief Whether the matcher is null.
+  bool isNull() const { return !Value; }
+
+  /// \brief Return a single matcher, if there is no ambiguity.
+  ///
+  /// \returns the matcher, if there is only one matcher. An empty Optional, if
+  /// the underlying matcher is a polymorphic matcher with more than one
+  /// representation.
+  llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
+
+  /// \brief Determines if the contained matcher can be converted to
+  ///   \c Matcher<T>.
+  ///
+  /// For the Single case, it returns true if it can be converted to
+  /// \c Matcher<T>.
+  /// For the Polymorphic case, it returns true if one, and only one, of the
+  /// overloads can be converted to \c Matcher<T>. If there are more than one
+  /// that can, the result would be ambiguous and false is returned.
+  template <class T>
+  bool hasTypedMatcher() const {
+    TypedMatcherOps<T> Ops;
+    if (Value) Value->makeTypedMatcher(Ops);
+    return Ops.hasMatcher();
+  }
+
+  /// \brief Return this matcher as a \c Matcher<T>.
+  ///
+  /// Handles the different types (Single, Polymorphic) accordingly.
+  /// Asserts that \c hasTypedMatcher<T>() is true.
+  template <class T>
+  ast_matchers::internal::Matcher<T> getTypedMatcher() const {
+    TypedMatcherOps<T> Ops;
+    Value->makeTypedMatcher(Ops);
+    assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
+    return Ops.matcher();
+  }
+
+  /// \brief String representation of the type of the value.
+  ///
+  /// If the underlying matcher is a polymorphic one, the string will show all
+  /// the types.
+  std::string getTypeAsString() const;
+
+private:
+  explicit VariantMatcher(Payload *Value) : Value(Value) {}
+
+  class SinglePayload;
+  class PolymorphicPayload;
+  class VariadicOpPayload;
+
+  template <typename T>
+  class TypedMatcherOps : public MatcherOps {
+  public:
+    typedef ast_matchers::internal::Matcher<T> MatcherT;
+
+    virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+                                  bool &IsExactMatch) const {
+      IsExactMatch = Matcher.getSupportedKind().isSame(
+          ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+      return Matcher.canConvertTo<T>();
+    }
+
+    virtual void constructFrom(const DynTypedMatcher& Matcher) {
+      Out.reset(new MatcherT(Matcher.convertTo<T>()));
+    }
+
+    virtual void constructVariadicOperator(
+        ast_matchers::internal::VariadicOperatorFunction Func,
+        ArrayRef<VariantMatcher> InnerMatchers) {
+      std::vector<DynTypedMatcher> DynMatchers;
+      for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
+        // Abort if any of the inner matchers can't be converted to
+        // Matcher<T>.
+        if (!InnerMatchers[i].hasTypedMatcher<T>()) {
+          return;
+        }
+        DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
+      }
+      Out.reset(new MatcherT(
+          new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
+              Func, DynMatchers)));
+    }
+
+    bool hasMatcher() const { return Out.get() != nullptr; }
+    const MatcherT &matcher() const { return *Out; }
+
+  private:
+    std::unique_ptr<MatcherT> Out;
+  };
+
+  IntrusiveRefCntPtr<const Payload> Value;
+};
+
+/// \brief Variant value class.
+///
+/// Basically, a tagged union with value type semantics.
+/// It is used by the registry as the return value and argument type for the
+/// matcher factory methods.
+/// It can be constructed from any of the supported types. It supports
+/// copy/assignment.
+///
+/// Supported types:
+///  - \c unsigned
+///  - \c std::string
+///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
+class VariantValue {
+public:
+  VariantValue() : Type(VT_Nothing) {}
+
+  VariantValue(const VariantValue &Other);
+  ~VariantValue();
+  VariantValue &operator=(const VariantValue &Other);
+
+  /// \brief Specific constructors for each supported type.
+  VariantValue(unsigned Unsigned);
+  VariantValue(const std::string &String);
+  VariantValue(const VariantMatcher &Matchers);
+
+  /// \brief Returns true iff this is not an empty value.
+  LLVM_EXPLICIT operator bool() const { return hasValue(); }
+  bool hasValue() const { return Type != VT_Nothing; }
+
+  /// \brief Unsigned value functions.
+  bool isUnsigned() const;
+  unsigned getUnsigned() const;
+  void setUnsigned(unsigned Unsigned);
+
+  /// \brief String value functions.
+  bool isString() const;
+  const std::string &getString() const;
+  void setString(const std::string &String);
+
+  /// \brief Matcher value functions.
+  bool isMatcher() const;
+  const VariantMatcher &getMatcher() const;
+  void setMatcher(const VariantMatcher &Matcher);
+
+  /// \brief String representation of the type of the value.
+  std::string getTypeAsString() const;
+
+private:
+  void reset();
+
+  /// \brief All supported value types.
+  enum ValueType {
+    VT_Nothing,
+    VT_Unsigned,
+    VT_String,
+    VT_Matcher
+  };
+
+  /// \brief All supported value types.
+  union AllValues {
+    unsigned Unsigned;
+    std::string *String;
+    VariantMatcher *Matcher;
+  };
+
+  ValueType Type;
+  AllValues Value;
+};
+
+} // end namespace dynamic
+} // end namespace ast_matchers
+} // end namespace clang
+
+#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
new file mode 100644
index 0000000..a61d9e4
--- /dev/null
+++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
@@ -0,0 +1,49 @@
+//==- CFGReachabilityAnalysis.h - Basic reachability analysis ----*- 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 flow-sensitive, (mostly) path-insensitive reachability
+// analysis based on Clang's CFGs.  Clients can query if a given basic block
+// is reachable within the CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_ANALYSIS_CFG_REACHABILITY
+#define CLANG_ANALYSIS_CFG_REACHABILITY
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+class CFG;
+class CFGBlock;
+  
+// A class that performs reachability queries for CFGBlocks. Several internal
+// checks in this checker require reachability information. The requests all
+// tend to have a common destination, so we lazily do a predecessor search
+// from the destination node and cache the results to prevent work
+// duplication.
+class CFGReverseBlockReachabilityAnalysis {
+  typedef llvm::BitVector ReachableSet;
+  typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
+  ReachableSet analyzed;
+  ReachableMap reachable;
+public:
+  CFGReverseBlockReachabilityAnalysis(const CFG &cfg);
+
+  /// Returns true if the block 'Dst' can be reached from block 'Src'.
+  bool isReachable(const CFGBlock *Src, const CFGBlock *Dst);
+
+private:
+  void mapReachability(const CFGBlock *Dst);
+};
+  
+}
+
+#endif
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
new file mode 100644
index 0000000..36e07c2
--- /dev/null
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -0,0 +1,265 @@
+//===- Consumed.h ----------------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A intra-procedural analysis for checking consumed properties.  This is based,
+// in part, on research on linear types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CONSUMED_H
+#define LLVM_CLANG_CONSUMED_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+namespace consumed {
+  
+  enum ConsumedState {
+    // No state information for the given variable.
+    CS_None,
+    
+    CS_Unknown,
+    CS_Unconsumed,
+    CS_Consumed
+  };
+  
+  class ConsumedStmtVisitor;
+  
+  typedef SmallVector<PartialDiagnosticAt, 1> OptionalNotes;
+  typedef std::pair<PartialDiagnosticAt, OptionalNotes> DelayedDiag;
+  typedef std::list<DelayedDiag> DiagList;
+
+  class ConsumedWarningsHandlerBase {
+
+  public:
+
+    virtual ~ConsumedWarningsHandlerBase();
+
+    /// \brief Emit the warnings and notes left by the analysis.
+    virtual void emitDiagnostics() {}
+    
+    /// \brief Warn that a variable's state doesn't match at the entry and exit
+    /// of a loop.
+    ///
+    /// \param Loc -- The location of the end of the loop.
+    ///
+    /// \param VariableName -- The name of the variable that has a mismatched
+    /// state.
+    virtual void warnLoopStateMismatch(SourceLocation Loc,
+                                       StringRef VariableName) {}
+    
+    /// \brief Warn about parameter typestate mismatches upon return.
+    ///
+    /// \param Loc -- The SourceLocation of the return statement.
+    ///
+    /// \param ExpectedState -- The state the return value was expected to be
+    /// in.
+    ///
+    /// \param ObservedState -- The state the return value was observed to be
+    /// in.
+    virtual void warnParamReturnTypestateMismatch(SourceLocation Loc,
+                                                  StringRef VariableName,
+                                                  StringRef ExpectedState,
+                                                  StringRef ObservedState) {};
+    
+    // FIXME: Add documentation.
+    virtual void warnParamTypestateMismatch(SourceLocation LOC,
+                                            StringRef ExpectedState,
+                                            StringRef ObservedState) {}
+    
+    // FIXME: This can be removed when the attr propagation fix for templated
+    //        classes lands.
+    /// \brief Warn about return typestates set for unconsumable types.
+    /// 
+    /// \param Loc -- The location of the attributes.
+    ///
+    /// \param TypeName -- The name of the unconsumable type.
+    virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
+                                                        StringRef TypeName) {}
+    
+    /// \brief Warn about return typestate mismatches.
+    ///
+    /// \param Loc -- The SourceLocation of the return statement.
+    ///
+    /// \param ExpectedState -- The state the return value was expected to be
+    /// in.
+    ///
+    /// \param ObservedState -- The state the return value was observed to be
+    /// in.
+    virtual void warnReturnTypestateMismatch(SourceLocation Loc,
+                                             StringRef ExpectedState,
+                                             StringRef ObservedState) {}
+
+    /// \brief Warn about use-while-consumed errors.
+    /// \param MethodName -- The name of the method that was incorrectly
+    /// invoked.
+    ///
+    /// \param State -- The state the object was used in.
+    ///
+    /// \param Loc -- The SourceLocation of the method invocation.
+    virtual void warnUseOfTempInInvalidState(StringRef MethodName,
+                                             StringRef State,
+                                             SourceLocation Loc) {}
+
+    /// \brief Warn about use-while-consumed errors.
+    /// \param MethodName -- The name of the method that was incorrectly
+    /// invoked.
+    ///
+    /// \param State -- The state the object was used in.
+    ///
+    /// \param VariableName -- The name of the variable that holds the unique
+    /// value.
+    ///
+    /// \param Loc -- The SourceLocation of the method invocation.
+    virtual void warnUseInInvalidState(StringRef MethodName,
+                                       StringRef VariableName,
+                                       StringRef State,
+                                       SourceLocation Loc) {}
+  };
+
+  class ConsumedStateMap {
+    
+    typedef llvm::DenseMap<const VarDecl *, ConsumedState> VarMapType;
+    typedef llvm::DenseMap<const CXXBindTemporaryExpr *, ConsumedState>
+            TmpMapType;
+    
+  protected:
+    
+    bool Reachable;
+    const Stmt *From;
+    VarMapType VarMap;
+    TmpMapType TmpMap;
+    
+  public:
+    ConsumedStateMap() : Reachable(true), From(nullptr) {}
+    ConsumedStateMap(const ConsumedStateMap &Other)
+      : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
+        TmpMap() {}
+    
+    /// \brief Warn if any of the parameters being tracked are not in the state
+    /// they were declared to be in upon return from a function.
+    void checkParamsForReturnTypestate(SourceLocation BlameLoc,
+      ConsumedWarningsHandlerBase &WarningsHandler) const;
+    
+    /// \brief Clear the TmpMap.
+    void clearTemporaries();
+    
+    /// \brief Get the consumed state of a given variable.
+    ConsumedState getState(const VarDecl *Var) const;
+    
+    /// \brief Get the consumed state of a given temporary value.
+    ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const;
+    
+    /// \brief Merge this state map with another map.
+    void intersect(const ConsumedStateMap *Other);
+    
+    void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack,
+      const ConsumedStateMap *LoopBackStates,
+      ConsumedWarningsHandlerBase &WarningsHandler);
+    
+    /// \brief Return true if this block is reachable.
+    bool isReachable() const { return Reachable; }
+    
+    /// \brief Mark the block as unreachable.
+    void markUnreachable();
+    
+    /// \brief Set the source for a decision about the branching of states.
+    /// \param Source -- The statement that was the origin of a branching
+    /// decision.
+    void setSource(const Stmt *Source) { this->From = Source; }
+    
+    /// \brief Set the consumed state of a given variable.
+    void setState(const VarDecl *Var, ConsumedState State);
+    
+    /// \brief Set the consumed state of a given temporary value.
+    void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
+    
+    /// \brief Remove the temporary value from our state map.
+    void remove(const CXXBindTemporaryExpr *Tmp);
+    
+    /// \brief Tests to see if there is a mismatch in the states stored in two
+    /// maps.
+    ///
+    /// \param Other -- The second map to compare against.
+    bool operator!=(const ConsumedStateMap *Other) const;
+  };
+  
+  class ConsumedBlockInfo {
+    std::vector<ConsumedStateMap*> StateMapsArray;
+    std::vector<unsigned int> VisitOrder;
+    
+  public:
+    ConsumedBlockInfo() { }
+    ~ConsumedBlockInfo() { llvm::DeleteContainerPointers(StateMapsArray); }
+
+    ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
+        : StateMapsArray(NumBlocks, nullptr), VisitOrder(NumBlocks, 0) {
+      unsigned int VisitOrderCounter = 0;
+      for (PostOrderCFGView::iterator BI = SortedGraph->begin(),
+           BE = SortedGraph->end(); BI != BE; ++BI) {
+        VisitOrder[(*BI)->getBlockID()] = VisitOrderCounter++;
+      }
+    }
+    
+    bool allBackEdgesVisited(const CFGBlock *CurrBlock,
+                             const CFGBlock *TargetBlock);
+    
+    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap,
+                 bool &AlreadyOwned);
+    void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap);
+    
+    ConsumedStateMap* borrowInfo(const CFGBlock *Block);
+    
+    void discardInfo(const CFGBlock *Block);
+    
+    ConsumedStateMap* getInfo(const CFGBlock *Block);
+    
+    bool isBackEdge(const CFGBlock *From, const CFGBlock *To);
+    bool isBackEdgeTarget(const CFGBlock *Block);
+  };
+
+  /// A class that handles the analysis of uniqueness violations.
+  class ConsumedAnalyzer {
+    
+    ConsumedBlockInfo BlockInfo;
+    ConsumedStateMap *CurrStates;
+    
+    ConsumedState ExpectedReturnState;
+    
+    void determineExpectedReturnState(AnalysisDeclContext &AC,
+                                      const FunctionDecl *D);
+    bool hasConsumableAttributes(const CXXRecordDecl *RD);
+    bool splitState(const CFGBlock *CurrBlock,
+                    const ConsumedStmtVisitor &Visitor);
+    
+  public:
+    
+    ConsumedWarningsHandlerBase &WarningsHandler;
+
+    ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler)
+        : WarningsHandler(WarningsHandler) {}
+
+    ConsumedState getExpectedReturnState() const { return ExpectedReturnState; }
+    
+    /// \brief Check a function's CFG for consumed violations.
+    ///
+    /// We traverse the blocks in the CFG, keeping track of the state of each
+    /// value who's type has uniquness annotations.  If methods are invoked in
+    /// the wrong state a warning is issued.  Each block in the CFG is traversed
+    /// exactly once.
+    void run(AnalysisDeclContext &AC);
+  };
+}} // end namespace clang::consumed
+
+#endif
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
new file mode 100644
index 0000000..6c6d923
--- /dev/null
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -0,0 +1,212 @@
+//==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
+//
+//                     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 dominators tree functionality for Clang CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DOMINATORS_H
+#define LLVM_CLANG_DOMINATORS_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+
+// FIXME: There is no good reason for the domtree to require a print method
+// which accepts an LLVM Module, so remove this (and the method's argument that
+// needs it) when that is fixed.
+namespace llvm {
+class Module;
+}
+
+namespace clang {
+
+class CFGBlock;
+typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
+
+/// \brief Concrete subclass of DominatorTreeBase for Clang
+/// This class implements the dominators tree functionality given a Clang CFG.
+///
+class DominatorTree : public ManagedAnalysis {
+  virtual void anchor();
+public:
+  llvm::DominatorTreeBase<CFGBlock>* DT;
+
+  DominatorTree() {
+    DT = new llvm::DominatorTreeBase<CFGBlock>(false);
+  }
+
+  ~DominatorTree() {
+    delete DT;
+  }
+
+  llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
+
+  /// \brief This method returns the root CFGBlock of the dominators tree.
+  ///
+  inline CFGBlock *getRoot() const {
+    return DT->getRoot();
+  }
+
+  /// \brief This method returns the root DomTreeNode, which is the wrapper
+  /// for CFGBlock.
+  inline DomTreeNode *getRootNode() const {
+    return DT->getRootNode();
+  }
+
+  /// \brief This method compares two dominator trees.
+  /// The method returns false if the other dominator tree matches this
+  /// dominator tree, otherwise returns true.
+  ///
+  inline bool compare(DominatorTree &Other) const {
+    DomTreeNode *R = getRootNode();
+    DomTreeNode *OtherR = Other.getRootNode();
+
+    if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
+      return true;
+
+    if (DT->compare(Other.getBase()))
+      return true;
+
+    return false;
+  }
+
+  /// \brief This method builds the dominator tree for a given CFG
+  /// The CFG information is passed via AnalysisDeclContext
+  ///
+  void buildDominatorTree(AnalysisDeclContext &AC) {
+    cfg = AC.getCFG();
+    DT->recalculate(*cfg);
+  }
+
+  /// \brief This method dumps immediate dominators for each block,
+  /// mainly used for debug purposes.
+  ///
+  void dump() {
+    llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
+    for (CFG::const_iterator I = cfg->begin(),
+        E = cfg->end(); I != E; ++I) {
+      if(DT->getNode(*I)->getIDom())
+        llvm::errs() << "(" << (*I)->getBlockID()
+                     << ","
+                     << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
+                     << ")\n";
+      else llvm::errs() << "(" << (*I)->getBlockID()
+                        << "," << (*I)->getBlockID() << ")\n";
+    }
+  }
+
+  /// \brief This method tests if one CFGBlock dominates the other.
+  /// The method return true if A dominates B, false otherwise.
+  /// Note a block always dominates itself.
+  ///
+  inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
+    return DT->dominates(A, B);
+  }
+
+  /// \brief This method tests if one CFGBlock properly dominates the other.
+  /// The method return true if A properly dominates B, false otherwise.
+  ///
+  bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  /// \brief This method finds the nearest common dominator CFG block
+  /// for CFG block A and B. If there is no such block then return NULL.
+  ///
+  inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
+                                                      const CFGBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  /// \brief This method is used to update the dominator
+  /// tree information when a node's immediate dominator changes.
+  ///
+  inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
+    DT->changeImmediateDominator(N, NewIDom);
+  }
+
+  /// \brief This method tests if the given CFGBlock can be reachable from root.
+  /// Returns true if reachable, false otherwise.
+  ///
+  bool isReachableFromEntry(const CFGBlock *A) {
+    return DT->isReachableFromEntry(A);
+  }
+
+  /// \brief This method releases the memory held by the dominator tree.
+  ///
+  virtual void releaseMemory() {
+    DT->releaseMemory();
+  }
+
+  /// \brief This method converts the dominator tree to human readable form.
+  ///
+  virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
+    DT->print(OS);
+  }
+
+private:
+  CFG *cfg;
+};
+
+} // end namespace clang
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+namespace llvm {
+template <> struct GraphTraits< ::clang::DomTreeNode* > {
+  typedef ::clang::DomTreeNode NodeType;
+  typedef NodeType::iterator  ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) {
+    return N;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+
+  typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
+
+  static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+
+template <> struct GraphTraits< ::clang::DominatorTree* >
+  : public GraphTraits< ::clang::DomTreeNode* > {
+  static NodeType *getEntryNode(::clang::DominatorTree *DT) {
+    return DT->getRootNode();
+  }
+
+  static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(::clang::DominatorTree *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
new file mode 100644
index 0000000..76fe9dd
--- /dev/null
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -0,0 +1,654 @@
+//= FormatString.h - Analysis of printf/fprintf format strings --*- 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 APIs for analyzing the format strings of printf, fscanf,
+// and friends.
+//
+// The structure of format strings for fprintf are described in C99 7.19.6.1.
+//
+// The structure of format strings for fscanf are described in C99 7.19.6.2.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_H
+#define LLVM_CLANG_FORMAT_H
+
+#include "clang/AST/CanonicalType.h"
+
+namespace clang {
+
+class TargetInfo;
+
+//===----------------------------------------------------------------------===//
+/// Common components of both fprintf and fscanf format strings.
+namespace analyze_format_string {
+
+/// Class representing optional flags with location and representation
+/// information.
+class OptionalFlag {
+public:
+  OptionalFlag(const char *Representation)
+      : representation(Representation), flag(false) {}
+  bool isSet() { return flag; }
+  void set() { flag = true; }
+  void clear() { flag = false; }
+  void setPosition(const char *position) {
+    assert(position);
+    this->position = position;
+  }
+  const char *getPosition() const {
+    assert(position);
+    return position;
+  }
+  const char *toString() const { return representation; }
+
+  // Overloaded operators for bool like qualities
+  LLVM_EXPLICIT operator bool() const { return flag; }
+  OptionalFlag& operator=(const bool &rhs) {
+    flag = rhs;
+    return *this;  // Return a reference to myself.
+  }
+private:
+  const char *representation;
+  const char *position;
+  bool flag;
+};
+
+/// Represents the length modifier in a format string in scanf/printf.
+class LengthModifier {
+public:
+  enum Kind {
+    None,
+    AsChar,       // 'hh'
+    AsShort,      // 'h'
+    AsLong,       // 'l'
+    AsLongLong,   // 'll'
+    AsQuad,       // 'q' (BSD, deprecated, for 64-bit integer types)
+    AsIntMax,     // 'j'
+    AsSizeT,      // 'z'
+    AsPtrDiff,    // 't'
+    AsInt32,      // 'I32' (MSVCRT, like __int32)
+    AsInt3264,    // 'I'   (MSVCRT, like __int3264 from MIDL)
+    AsInt64,      // 'I64' (MSVCRT, like __int64)
+    AsLongDouble, // 'L'
+    AsAllocate,   // for '%as', GNU extension to C90 scanf
+    AsMAllocate,  // for '%ms', GNU extension to scanf
+    AsWideChar = AsLong // for '%ls', only makes sense for printf
+  };
+
+  LengthModifier()
+    : Position(nullptr), kind(None) {}
+  LengthModifier(const char *pos, Kind k)
+    : Position(pos), kind(k) {}
+
+  const char *getStart() const {
+    return Position;
+  }
+
+  unsigned getLength() const {
+    switch (kind) {
+      default:
+        return 1;
+      case AsLongLong:
+      case AsChar:
+        return 2;
+      case AsInt32:
+      case AsInt64:
+        return 3;
+      case None:
+        return 0;
+    }
+  }
+
+  Kind getKind() const { return kind; }
+  void setKind(Kind k) { kind = k; }
+
+  const char *toString() const;
+
+private:
+  const char *Position;
+  Kind kind;
+};
+
+class ConversionSpecifier {
+public:
+  enum Kind {
+    InvalidSpecifier = 0,
+      // C99 conversion specifiers.
+    cArg,
+    dArg,
+    DArg, // Apple extension
+    iArg,
+    IntArgBeg = dArg, IntArgEnd = iArg,
+
+    oArg,
+    OArg, // Apple extension
+    uArg,
+    UArg, // Apple extension
+    xArg,
+    XArg,
+    UIntArgBeg = oArg, UIntArgEnd = XArg,
+
+    fArg,
+    FArg,
+    eArg,
+    EArg,
+    gArg,
+    GArg,
+    aArg,
+    AArg,
+    DoubleArgBeg = fArg, DoubleArgEnd = AArg,
+
+    sArg,
+    pArg,
+    nArg,
+    PercentArg,
+    CArg,
+    SArg,
+
+    // ** Printf-specific **
+
+    // Objective-C specific specifiers.
+    ObjCObjArg,  // '@'
+    ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
+
+    // GlibC specific specifiers.
+    PrintErrno,   // 'm'
+
+    PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno,
+
+    // ** Scanf-specific **
+    ScanListArg, // '['
+    ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg
+  };
+
+  ConversionSpecifier(bool isPrintf = true)
+    : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
+      kind(InvalidSpecifier) {}
+
+  ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
+    : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
+
+  const char *getStart() const {
+    return Position;
+  }
+
+  StringRef getCharacters() const {
+    return StringRef(getStart(), getLength());
+  }
+
+  bool consumesDataArgument() const {
+    switch (kind) {
+      case PrintErrno:
+        assert(IsPrintf);
+        return false;
+      case PercentArg:
+        return false;
+      default:
+        return true;
+    }
+  }
+
+  Kind getKind() const { return kind; }
+  void setKind(Kind k) { kind = k; }
+  unsigned getLength() const {
+    return EndScanList ? EndScanList - Position : 1;
+  }
+
+  bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; }
+  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
+  bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
+  const char *toString() const;
+
+  bool isPrintfKind() const { return IsPrintf; }
+  
+  Optional<ConversionSpecifier> getStandardSpecifier() const;
+
+protected:
+  bool IsPrintf;
+  const char *Position;
+  const char *EndScanList;
+  Kind kind;
+};
+
+class ArgType {
+public:
+  enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
+              AnyCharTy, CStrTy, WCStrTy, WIntTy };
+private:
+  const Kind K;
+  QualType T;
+  const char *Name;
+  bool Ptr;
+public:
+  ArgType(Kind k = UnknownTy, const char *n = nullptr)
+      : K(k), Name(n), Ptr(false) {}
+  ArgType(QualType t, const char *n = nullptr)
+      : K(SpecificTy), T(t), Name(n), Ptr(false) {}
+  ArgType(CanQualType t) : K(SpecificTy), T(t), Name(nullptr), Ptr(false) {}
+
+  static ArgType Invalid() { return ArgType(InvalidTy); }
+  bool isValid() const { return K != InvalidTy; }
+
+  /// Create an ArgType which corresponds to the type pointer to A.
+  static ArgType PtrTo(const ArgType& A) {
+    assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
+    ArgType Res = A;
+    Res.Ptr = true;
+    return Res;
+  }
+
+  bool matchesType(ASTContext &C, QualType argTy) const;
+
+  QualType getRepresentativeType(ASTContext &C) const;
+
+  std::string getRepresentativeTypeName(ASTContext &C) const;
+};
+
+class OptionalAmount {
+public:
+  enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
+
+  OptionalAmount(HowSpecified howSpecified,
+                 unsigned amount,
+                 const char *amountStart,
+                 unsigned amountLength,
+                 bool usesPositionalArg)
+  : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
+  UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
+
+  OptionalAmount(bool valid = true)
+  : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
+  UsesPositionalArg(0), UsesDotPrefix(0) {}
+
+  bool isInvalid() const {
+    return hs == Invalid;
+  }
+
+  HowSpecified getHowSpecified() const { return hs; }
+  void setHowSpecified(HowSpecified h) { hs = h; }
+
+  bool hasDataArgument() const { return hs == Arg; }
+
+  unsigned getArgIndex() const {
+    assert(hasDataArgument());
+    return amt;
+  }
+
+  unsigned getConstantAmount() const {
+    assert(hs == Constant);
+    return amt;
+  }
+
+  const char *getStart() const {
+      // We include the . character if it is given.
+    return start - UsesDotPrefix;
+  }
+
+  unsigned getConstantLength() const {
+    assert(hs == Constant);
+    return length + UsesDotPrefix;
+  }
+
+  ArgType getArgType(ASTContext &Ctx) const;
+
+  void toString(raw_ostream &os) const;
+
+  bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
+  unsigned getPositionalArgIndex() const {
+    assert(hasDataArgument());
+    return amt + 1;
+  }
+
+  bool usesDotPrefix() const { return UsesDotPrefix; }
+  void setUsesDotPrefix() { UsesDotPrefix = true; }
+
+private:
+  const char *start;
+  unsigned length;
+  HowSpecified hs;
+  unsigned amt;
+  bool UsesPositionalArg : 1;
+  bool UsesDotPrefix;
+};
+
+
+class FormatSpecifier {
+protected:
+  LengthModifier LM;
+  OptionalAmount FieldWidth;
+  ConversionSpecifier CS;
+  /// Positional arguments, an IEEE extension:
+  ///  IEEE Std 1003.1, 2004 Edition
+  ///  http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+  bool UsesPositionalArg;
+  unsigned argIndex;
+public:
+  FormatSpecifier(bool isPrintf)
+    : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
+
+  void setLengthModifier(LengthModifier lm) {
+    LM = lm;
+  }
+
+  void setUsesPositionalArg() { UsesPositionalArg = true; }
+
+  void setArgIndex(unsigned i) {
+    argIndex = i;
+  }
+
+  unsigned getArgIndex() const {
+    return argIndex;
+  }
+
+  unsigned getPositionalArgIndex() const {
+    return argIndex + 1;
+  }
+
+  const LengthModifier &getLengthModifier() const {
+    return LM;
+  }
+
+  const OptionalAmount &getFieldWidth() const {
+    return FieldWidth;
+  }
+
+  void setFieldWidth(const OptionalAmount &Amt) {
+    FieldWidth = Amt;
+  }
+
+  bool usesPositionalArg() const { return UsesPositionalArg; }
+
+  bool hasValidLengthModifier(const TargetInfo &Target) const;
+
+  bool hasStandardLengthModifier() const;
+
+  Optional<LengthModifier> getCorrectedLengthModifier() const;
+
+  bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
+
+  bool hasStandardLengthConversionCombination() const;
+
+  /// For a TypedefType QT, if it is a named integer type such as size_t,
+  /// assign the appropriate value to LM and return true.
+  static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
+};
+
+} // end analyze_format_string namespace
+
+//===----------------------------------------------------------------------===//
+/// Pieces specific to fprintf format strings.
+
+namespace analyze_printf {
+
+class PrintfConversionSpecifier :
+  public analyze_format_string::ConversionSpecifier  {
+public:
+  PrintfConversionSpecifier()
+    : ConversionSpecifier(true, nullptr, InvalidSpecifier) {}
+
+  PrintfConversionSpecifier(const char *pos, Kind k)
+    : ConversionSpecifier(true, pos, k) {}
+
+  bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
+  bool isDoubleArg() const { return kind >= DoubleArgBeg &&
+                                    kind <= DoubleArgEnd; }
+  unsigned getLength() const {
+      // Conversion specifiers currently only are represented by
+      // single characters, but we be flexible.
+    return 1;
+  }
+
+  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
+    return CS->isPrintfKind();
+  }
+};
+
+using analyze_format_string::ArgType;
+using analyze_format_string::LengthModifier;
+using analyze_format_string::OptionalAmount;
+using analyze_format_string::OptionalFlag;
+
+class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
+  OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
+  OptionalFlag IsLeftJustified; // '-'
+  OptionalFlag HasPlusPrefix; // '+'
+  OptionalFlag HasSpacePrefix; // ' '
+  OptionalFlag HasAlternativeForm; // '#'
+  OptionalFlag HasLeadingZeroes; // '0'
+  OptionalAmount Precision;
+public:
+  PrintfSpecifier() :
+    FormatSpecifier(/* isPrintf = */ true),
+    HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
+    HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0") {}
+
+  static PrintfSpecifier Parse(const char *beg, const char *end);
+
+    // Methods for incrementally constructing the PrintfSpecifier.
+  void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
+    CS = cs;
+  }
+  void setHasThousandsGrouping(const char *position) {
+    HasThousandsGrouping = true;
+    HasThousandsGrouping.setPosition(position);
+  }
+  void setIsLeftJustified(const char *position) {
+    IsLeftJustified = true;
+    IsLeftJustified.setPosition(position);
+  }
+  void setHasPlusPrefix(const char *position) {
+    HasPlusPrefix = true;
+    HasPlusPrefix.setPosition(position);
+  }
+  void setHasSpacePrefix(const char *position) {
+    HasSpacePrefix = true;
+    HasSpacePrefix.setPosition(position);
+  }
+  void setHasAlternativeForm(const char *position) {
+    HasAlternativeForm = true;
+    HasAlternativeForm.setPosition(position);
+  }
+  void setHasLeadingZeros(const char *position) {
+    HasLeadingZeroes = true;
+    HasLeadingZeroes.setPosition(position);
+  }
+  void setUsesPositionalArg() { UsesPositionalArg = true; }
+
+    // Methods for querying the format specifier.
+
+  const PrintfConversionSpecifier &getConversionSpecifier() const {
+    return cast<PrintfConversionSpecifier>(CS);
+  }
+
+  void setPrecision(const OptionalAmount &Amt) {
+    Precision = Amt;
+    Precision.setUsesDotPrefix();
+  }
+
+  const OptionalAmount &getPrecision() const {
+    return Precision;
+  }
+
+  bool consumesDataArgument() const {
+    return getConversionSpecifier().consumesDataArgument();
+  }
+
+  /// \brief Returns the builtin type that a data argument
+  /// paired with this format specifier should have.  This method
+  /// will return null if the format specifier does not have
+  /// a matching data argument or the matching argument matches
+  /// more than one type.
+  ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
+
+  const OptionalFlag &hasThousandsGrouping() const {
+      return HasThousandsGrouping;
+  }
+  const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
+  const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
+  const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
+  const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
+  const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
+  bool usesPositionalArg() const { return UsesPositionalArg; }
+
+  /// Changes the specifier and length according to a QualType, retaining any
+  /// flags or options. Returns true on success, or false when a conversion
+  /// was not successful.
+  bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
+               bool IsObjCLiteral);
+
+  void toString(raw_ostream &os) const;
+
+  // Validation methods - to check if any element results in undefined behavior
+  bool hasValidPlusPrefix() const;
+  bool hasValidAlternativeForm() const;
+  bool hasValidLeadingZeros() const;
+  bool hasValidSpacePrefix() const;
+  bool hasValidLeftJustified() const;
+  bool hasValidThousandsGroupingPrefix() const;
+
+  bool hasValidPrecision() const;
+  bool hasValidFieldWidth() const;
+};
+}  // end analyze_printf namespace
+
+//===----------------------------------------------------------------------===//
+/// Pieces specific to fscanf format strings.
+
+namespace analyze_scanf {
+
+class ScanfConversionSpecifier :
+    public analyze_format_string::ConversionSpecifier  {
+public:
+  ScanfConversionSpecifier()
+    : ConversionSpecifier(false, nullptr, InvalidSpecifier) {}
+
+  ScanfConversionSpecifier(const char *pos, Kind k)
+    : ConversionSpecifier(false, pos, k) {}
+
+  void setEndScanList(const char *pos) { EndScanList = pos; }
+
+  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
+    return !CS->isPrintfKind();
+  }
+};
+
+using analyze_format_string::ArgType;
+using analyze_format_string::LengthModifier;
+using analyze_format_string::OptionalAmount;
+using analyze_format_string::OptionalFlag;
+
+class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
+  OptionalFlag SuppressAssignment; // '*'
+public:
+  ScanfSpecifier() :
+    FormatSpecifier(/* isPrintf = */ false),
+    SuppressAssignment("*") {}
+
+  void setSuppressAssignment(const char *position) {
+    SuppressAssignment = true;
+    SuppressAssignment.setPosition(position);
+  }
+
+  const OptionalFlag &getSuppressAssignment() const {
+    return SuppressAssignment;
+  }
+
+  void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
+    CS = cs;
+  }
+
+  const ScanfConversionSpecifier &getConversionSpecifier() const {
+    return cast<ScanfConversionSpecifier>(CS);
+  }
+
+  bool consumesDataArgument() const {
+    return CS.consumesDataArgument() && !SuppressAssignment;
+  }
+
+  ArgType getArgType(ASTContext &Ctx) const;
+
+  bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
+               ASTContext &Ctx);
+
+  void toString(raw_ostream &os) const;
+
+  static ScanfSpecifier Parse(const char *beg, const char *end);
+};
+
+} // end analyze_scanf namespace
+
+//===----------------------------------------------------------------------===//
+// Parsing and processing of format strings (both fprintf and fscanf).
+
+namespace analyze_format_string {
+
+enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
+
+class FormatStringHandler {
+public:
+  FormatStringHandler() {}
+  virtual ~FormatStringHandler();
+
+  virtual void HandleNullChar(const char *nullCharacter) {}
+
+  virtual void HandlePosition(const char *startPos, unsigned posLen) {}
+
+  virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
+                                     PositionContext p) {}
+
+  virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
+
+  virtual void HandleIncompleteSpecifier(const char *startSpecifier,
+                                         unsigned specifierLen) {}
+
+  // Printf-specific handlers.
+
+  virtual bool HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen) {
+    return true;
+  }
+
+  virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
+                                     const char *startSpecifier,
+                                     unsigned specifierLen) {
+    return true;
+  }
+
+    // Scanf-specific handlers.
+
+  virtual bool HandleInvalidScanfConversionSpecifier(
+                                        const analyze_scanf::ScanfSpecifier &FS,
+                                        const char *startSpecifier,
+                                        unsigned specifierLen) {
+    return true;
+  }
+
+  virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
+                                    const char *startSpecifier,
+                                    unsigned specifierLen) {
+    return true;
+  }
+
+  virtual void HandleIncompleteScanList(const char *start, const char *end) {}
+};
+
+bool ParsePrintfString(FormatStringHandler &H,
+                       const char *beg, const char *end, const LangOptions &LO,
+                       const TargetInfo &Target);
+
+bool ParseScanfString(FormatStringHandler &H,
+                      const char *beg, const char *end, const LangOptions &LO,
+                      const TargetInfo &Target);
+
+} // end analyze_format_string namespace
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
new file mode 100644
index 0000000..7842271
--- /dev/null
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -0,0 +1,120 @@
+//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Live Variables analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIVEVARIABLES_H
+#define LLVM_CLANG_LIVEVARIABLES_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ImmutableSet.h"
+
+namespace clang {
+
+class CFG;
+class CFGBlock;
+class Stmt;
+class DeclRefExpr;
+class SourceManager;
+  
+class LiveVariables : public ManagedAnalysis {
+public:
+  class LivenessValues {
+  public:
+
+    llvm::ImmutableSet<const Stmt *> liveStmts;
+    llvm::ImmutableSet<const VarDecl *> liveDecls;
+    
+    bool equals(const LivenessValues &V) const;
+
+    LivenessValues()
+      : liveStmts(nullptr), liveDecls(nullptr) {}
+
+    LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
+                   llvm::ImmutableSet<const VarDecl *> LiveDecls)
+      : liveStmts(LiveStmts), liveDecls(LiveDecls) {}
+
+    ~LivenessValues() {}
+    
+    bool isLive(const Stmt *S) const;
+    bool isLive(const VarDecl *D) const;
+    
+    friend class LiveVariables;    
+  };
+  
+  class Observer {
+    virtual void anchor();
+  public:
+    virtual ~Observer() {}
+    
+    /// A callback invoked right before invoking the
+    ///  liveness transfer function on the given statement.
+    virtual void observeStmt(const Stmt *S,
+                             const CFGBlock *currentBlock,
+                             const LivenessValues& V) {}
+    
+    /// Called when the live variables analysis registers
+    /// that a variable is killed.
+    virtual void observerKill(const DeclRefExpr *DR) {}
+  };    
+
+
+  virtual ~LiveVariables();
+  
+  /// Compute the liveness information for a given CFG.
+  static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext,
+                                        bool killAtAssign);
+  
+  /// Return true if a variable is live at the end of a
+  /// specified block.
+  bool isLive(const CFGBlock *B, const VarDecl *D);
+  
+  /// Returns true if a variable is live at the beginning of the
+  ///  the statement.  This query only works if liveness information
+  ///  has been recorded at the statement level (see runOnAllBlocks), and
+  ///  only returns liveness information for block-level expressions.
+  bool isLive(const Stmt *S, const VarDecl *D);
+  
+  /// Returns true the block-level expression "value" is live
+  ///  before the given block-level expression (see runOnAllBlocks).
+  bool isLive(const Stmt *Loc, const Stmt *StmtVal);
+    
+  /// Print to stderr the liveness information associated with
+  /// each basic block.
+  void dumpBlockLiveness(const SourceManager& M);
+
+  void runOnAllBlocks(Observer &obs);
+  
+  static LiveVariables *create(AnalysisDeclContext &analysisContext) {
+    return computeLiveness(analysisContext, true);
+  }
+  
+  static const void *getTag();
+  
+private:
+  LiveVariables(void *impl);
+  void *impl;
+};
+  
+class RelaxedLiveVariables : public LiveVariables {
+public:
+  static LiveVariables *create(AnalysisDeclContext &analysisContext) {
+    return computeLiveness(analysisContext, false);
+  }
+  
+  static const void *getTag();
+};
+  
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
new file mode 100644
index 0000000..91bf51c
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -0,0 +1,115 @@
+//===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- C++ --*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements post order view of the blocks in a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_POSTORDER_CFGVIEW
+#define LLVM_CLANG_POSTORDER_CFGVIEW
+
+#include <vector>
+//#include <algorithm>
+
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/BitVector.h"
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+class PostOrderCFGView : public ManagedAnalysis {
+  virtual void anchor();
+public:
+  /// \brief Implements a set of CFGBlocks using a BitVector.
+  ///
+  /// This class contains a minimal interface, primarily dictated by the SetType
+  /// template parameter of the llvm::po_iterator template, as used with
+  /// external storage. We also use this set to keep track of which CFGBlocks we
+  /// visit during the analysis.
+  class CFGBlockSet {
+    llvm::BitVector VisitedBlockIDs;
+  public:
+    // po_iterator requires this iterator, but the only interface needed is the
+    // value_type typedef.
+    struct iterator { typedef const CFGBlock *value_type; };
+
+    CFGBlockSet() {}
+    CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
+
+    /// \brief Set the bit associated with a particular CFGBlock.
+    /// This is the important method for the SetType template parameter.
+    bool insert(const CFGBlock *Block) {
+      // Note that insert() is called by po_iterator, which doesn't check to
+      // make sure that Block is non-null.  Moreover, the CFGBlock iterator will
+      // occasionally hand out null pointers for pruned edges, so we catch those
+      // here.
+      if (!Block)
+        return false;  // if an edge is trivially false.
+      if (VisitedBlockIDs.test(Block->getBlockID()))
+        return false;
+      VisitedBlockIDs.set(Block->getBlockID());
+      return true;
+    }
+
+    /// \brief Check if the bit for a CFGBlock has been already set.
+    /// This method is for tracking visited blocks in the main threadsafety
+    /// loop. Block must not be null.
+    bool alreadySet(const CFGBlock *Block) {
+      return VisitedBlockIDs.test(Block->getBlockID());
+    }
+  };
+
+private:
+  typedef llvm::po_iterator<const CFG*, CFGBlockSet, true>  po_iterator;
+  std::vector<const CFGBlock*> Blocks;
+
+  typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
+  BlockOrderTy BlockOrder;
+
+public:
+  typedef std::vector<const CFGBlock *>::reverse_iterator iterator;
+  typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator;
+
+  PostOrderCFGView(const CFG *cfg);
+
+  iterator begin() { return Blocks.rbegin(); }
+  iterator end()   { return Blocks.rend(); }
+
+  const_iterator begin() const { return Blocks.rbegin(); }
+  const_iterator end() const { return Blocks.rend(); }
+
+  bool empty() const { return begin() == end(); }
+
+  struct BlockOrderCompare;
+  friend struct BlockOrderCompare;
+
+  struct BlockOrderCompare {
+    const PostOrderCFGView &POV;
+  public:
+    BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {}
+    bool operator()(const CFGBlock *b1, const CFGBlock *b2) const;
+  };
+
+  BlockOrderCompare getComparator() const {
+    return BlockOrderCompare(*this);
+  }
+
+  // Used by AnalyisContext to construct this object.
+  static const void *getTag();
+
+  static PostOrderCFGView *create(AnalysisDeclContext &analysisContext);
+};
+
+} // end clang namespace
+
+#endif
+
diff --git a/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
new file mode 100644
index 0000000..cb73850
--- /dev/null
+++ b/include/clang/Analysis/Analyses/PseudoConstantAnalysis.h
@@ -0,0 +1,45 @@
+//== PseudoConstantAnalysis.h - Find Pseudo-constants in the AST -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tracks the usage of variables in a Decl body to see if they are
+// never written to, implying that they constant. This is useful in static
+// analysis to see if a developer might have intended a variable to be const.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
+#define LLVM_CLANG_ANALYSIS_PSEUDOCONSTANTANALYSIS
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+class PseudoConstantAnalysis {
+public:
+  PseudoConstantAnalysis(const Stmt *DeclBody);
+  ~PseudoConstantAnalysis();
+
+  bool isPseudoConstant(const VarDecl *VD);
+  bool wasReferenced(const VarDecl *VD);
+
+private:
+  void RunAnalysis();
+  inline static const Decl *getDecl(const Expr *E);
+
+  // for storing the result of analyzed ValueDecls
+  void *NonConstantsImpl;
+  void *UsedVarsImpl;
+
+  const Stmt *DeclBody;
+  bool Analyzed;
+};
+
+}
+
+#endif
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
new file mode 100644
index 0000000..90a6d01
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -0,0 +1,69 @@
+//===- ReachableCode.h -----------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A flow-sensitive, path-insensitive analysis of unreachable code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REACHABLECODE_H
+#define LLVM_CLANG_REACHABLECODE_H
+
+#include "clang/Basic/SourceLocation.h"
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+  class BitVector;
+}
+
+namespace clang {
+  class AnalysisDeclContext;
+  class CFGBlock;
+  class Preprocessor;
+}
+
+//===----------------------------------------------------------------------===//
+// API.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace reachable_code {
+
+/// Classifications of unreachable code.
+enum UnreachableKind {
+  UK_Return,
+  UK_Break,
+  UK_Loop_Increment,
+  UK_Other
+};
+
+class Callback {
+  virtual void anchor();
+public:
+  virtual ~Callback() {}
+  virtual void HandleUnreachable(UnreachableKind UK,
+                                 SourceLocation L,
+                                 SourceRange ConditionVal,
+                                 SourceRange R1,
+                                 SourceRange R2) = 0;
+};
+
+/// ScanReachableFromBlock - Mark all blocks reachable from Start.
+/// Returns the total number of blocks that were marked reachable.  
+unsigned ScanReachableFromBlock(const CFGBlock *Start,
+                                llvm::BitVector &Reachable);
+
+void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
+                         Callback &CB);
+
+}} // end namespace clang::reachable_code
+
+#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
new file mode 100644
index 0000000..b533c1d
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -0,0 +1,194 @@
+//===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+// A intra-procedural analysis for thread safety (e.g. deadlocks and race
+// conditions), based off of an annotation system.
+//
+// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
+// for more information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREADSAFETY_H
+#define LLVM_CLANG_THREADSAFETY_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace thread_safety {
+
+/// This enum distinguishes between different kinds of operations that may
+/// need to be protected by locks. We use this enum in error handling.
+enum ProtectedOperationKind {
+  POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
+  POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
+  POK_FunctionCall ///< Making a function call (e.g. fool())
+};
+
+/// This enum distinguishes between different kinds of lock actions. For
+/// example, it is an error to write a variable protected by shared version of a
+/// mutex.
+enum LockKind {
+  LK_Shared, ///< Shared/reader lock of a mutex.
+  LK_Exclusive, ///< Exclusive/writer lock of a mutex.
+  LK_Generic  ///<  Can be either Shared or Exclusive
+};
+
+/// This enum distinguishes between different ways to access (read or write) a
+/// variable.
+enum AccessKind {
+  AK_Read, ///< Reading a variable.
+  AK_Written ///< Writing a variable.
+};
+
+/// This enum distinguishes between different situations where we warn due to
+/// inconsistent locking.
+/// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
+/// loop iterations.
+/// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
+/// predecessors of a CFGBlock.
+/// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
+/// function.
+enum LockErrorKind {
+  LEK_LockedSomeLoopIterations,
+  LEK_LockedSomePredecessors,
+  LEK_LockedAtEndOfFunction,
+  LEK_NotLockedAtEndOfFunction
+};
+
+/// Handler class for thread safety warnings.
+class ThreadSafetyHandler {
+public:
+  typedef StringRef Name;
+  ThreadSafetyHandler() : IssueBetaWarnings(false) { }
+  virtual ~ThreadSafetyHandler();
+
+  /// Warn about lock expressions which fail to resolve to lockable objects.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param Loc -- the SourceLocation of the unresolved expression.
+  virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
+
+  /// Warn about unlock function calls that do not have a prior matching lock
+  /// expression.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Loc -- The SourceLocation of the Unlock
+  virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
+                                     SourceLocation Loc) {}
+
+  /// Warn about an unlock function call that attempts to unlock a lock with
+  /// the incorrect lock kind. For instance, a shared lock being unlocked
+  /// exclusively, or vice versa.
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param Expected -- the kind of lock expected.
+  /// \param Received -- the kind of lock received.
+  /// \param Loc -- The SourceLocation of the Unlock.
+  virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
+                                         LockKind Expected, LockKind Received,
+                                         SourceLocation Loc) {}
+
+  /// Warn about lock function calls for locks which are already held.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Loc -- The location of the second lock expression.
+  virtual void handleDoubleLock(StringRef Kind, Name LockName,
+                                SourceLocation Loc) {}
+
+  /// Warn about situations where a mutex is sometimes held and sometimes not.
+  /// The three situations are:
+  /// 1. a mutex is locked on an "if" branch but not the "else" branch,
+  /// 2, or a mutex is only held at the start of some loop iterations,
+  /// 3. or when a mutex is locked but not unlocked inside a function.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param LocLocked -- The location of the lock expression where the mutex is
+  ///               locked
+  /// \param LocEndOfScope -- The location of the end of the scope where the
+  ///               mutex is no longer held
+  /// \param LEK -- which of the three above cases we should warn for
+  virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
+                                         SourceLocation LocLocked,
+                                         SourceLocation LocEndOfScope,
+                                         LockErrorKind LEK) {}
+
+  /// Warn when a mutex is held exclusively and shared at the same point. For
+  /// example, if a mutex is locked exclusively during an if branch and shared
+  /// during the else branch.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Loc1 -- The location of the first lock expression.
+  /// \param Loc2 -- The location of the second lock expression.
+  virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
+                                        SourceLocation Loc1,
+                                        SourceLocation Loc2) {}
+
+  /// Warn when a protected operation occurs while no locks are held.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param D -- The decl for the protected variable or function
+  /// \param POK -- The kind of protected operation (e.g. variable access)
+  /// \param AK -- The kind of access (i.e. read or write) that occurred
+  /// \param Loc -- The location of the protected operation.
+  virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
+                                 ProtectedOperationKind POK, AccessKind AK,
+                                 SourceLocation Loc) {}
+
+  /// Warn when a protected operation occurs while the specific mutex protecting
+  /// the operation is not locked.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param D -- The decl for the protected variable or function
+  /// \param POK -- The kind of protected operation (e.g. variable access)
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param LK -- The kind of access (i.e. read or write) that occurred
+  /// \param Loc -- The location of the protected operation.
+  virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
+                                  ProtectedOperationKind POK, Name LockName,
+                                  LockKind LK, SourceLocation Loc,
+                                  Name *PossibleMatch = nullptr) {}
+
+  /// Warn when a function is called while an excluded mutex is locked. For
+  /// example, the mutex may be locked inside the function.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param FunName -- The name of the function
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Loc -- The location of the function call.
+  virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
+                                     Name LockName, SourceLocation Loc) {}
+
+  bool issueBetaWarnings() { return IssueBetaWarnings; }
+  void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
+
+private:
+  bool IssueBetaWarnings;
+};
+
+/// \brief Check a function's CFG for thread-safety violations.
+///
+/// We traverse the blocks in the CFG, compute the set of mutexes that are held
+/// at the end of each block, and issue warnings for thread safety violations.
+/// Each block in the CFG is traversed exactly once.
+void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
+                             ThreadSafetyHandler &Handler);
+
+/// \brief Helper function that returns a LockKind required for the given level
+/// of access.
+LockKind getLockKindFromAccessKind(AccessKind AK);
+
+}} // end namespace clang::thread_safety
+#endif
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
new file mode 100644
index 0000000..09c614c
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -0,0 +1,393 @@
+//===- ThreadSafetyCommon.h ------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Parts of thread safety analysis that are not specific to thread safety
+// itself have been factored into classes here, where they can be potentially
+// used by other analyses.  Currently these include:
+//
+// * Generalize clang CFG visitors.
+// * Conversion of the clang CFG to SSA form.
+// * Translation of clang Exprs to TIL SExprs
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_COMMON_H
+#define LLVM_CLANG_THREAD_SAFETY_COMMON_H
+
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/OperatorKinds.h"
+
+#include <memory>
+#include <vector>
+
+
+namespace clang {
+namespace threadSafety {
+
+// This class defines the interface of a clang CFG Visitor.
+// CFGWalker will invoke the following methods.
+// Note that methods are not virtual; the visitor is templatized.
+class CFGVisitor {
+  // Enter the CFG for Decl D, and perform any initial setup operations.
+  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
+
+  // Enter a CFGBlock.
+  void enterCFGBlock(const CFGBlock *B) {}
+
+  // Returns true if this visitor implements handlePredecessor
+  bool visitPredecessors() { return true; }
+
+  // Process a predecessor edge.
+  void handlePredecessor(const CFGBlock *Pred) {}
+
+  // Process a successor back edge to a previously visited block.
+  void handlePredecessorBackEdge(const CFGBlock *Pred) {}
+
+  // Called just before processing statements.
+  void enterCFGBlockBody(const CFGBlock *B) {}
+
+  // Process an ordinary statement.
+  void handleStatement(const Stmt *S) {}
+
+  // Process a destructor call
+  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
+
+  // Called after all statements have been handled.
+  void exitCFGBlockBody(const CFGBlock *B) {}
+
+  // Return true
+  bool visitSuccessors() { return true; }
+
+  // Process a successor edge.
+  void handleSuccessor(const CFGBlock *Succ) {}
+
+  // Process a successor back edge to a previously visited block.
+  void handleSuccessorBackEdge(const CFGBlock *Succ) {}
+
+  // Leave a CFGBlock.
+  void exitCFGBlock(const CFGBlock *B) {}
+
+  // Leave the CFG, and perform any final cleanup operations.
+  void exitCFG(const CFGBlock *Last) {}
+};
+
+
+// Walks the clang CFG, and invokes methods on a given CFGVisitor.
+class CFGWalker {
+public:
+  CFGWalker() : CFGraph(nullptr), ACtx(nullptr), SortedGraph(nullptr) {}
+
+  // Initialize the CFGWalker.  This setup only needs to be done once, even
+  // if there are multiple passes over the CFG.
+  bool init(AnalysisDeclContext &AC) {
+    ACtx = &AC;
+    CFGraph = AC.getCFG();
+    if (!CFGraph)
+      return false;
+
+    // Ignore anonymous functions.
+    if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
+      return false;
+
+    SortedGraph = AC.getAnalysis<PostOrderCFGView>();
+    if (!SortedGraph)
+      return false;
+
+    return true;
+  }
+
+  // Traverse the CFG, calling methods on V as appropriate.
+  template <class Visitor>
+  void walk(Visitor &V) {
+    PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
+
+    V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry());
+
+    for (const auto *CurrBlock : *SortedGraph) {
+      VisitedBlocks.insert(CurrBlock);
+
+      V.enterCFGBlock(CurrBlock);
+
+      // Process predecessors, handling back edges last
+      if (V.visitPredecessors()) {
+        SmallVector<CFGBlock*, 4> BackEdges;
+        // Process successors
+        for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(),
+                                           SE = CurrBlock->pred_end();
+             SI != SE; ++SI) {
+          if (*SI == nullptr)
+            continue;
+
+          if (!VisitedBlocks.alreadySet(*SI)) {
+            BackEdges.push_back(*SI);
+            continue;
+          }
+          V.handlePredecessor(*SI);
+        }
+
+        for (auto *Blk : BackEdges)
+          V.handlePredecessorBackEdge(Blk);
+      }
+
+      V.enterCFGBlockBody(CurrBlock);
+
+      // Process statements
+      for (const auto &BI : *CurrBlock) {
+        switch (BI.getKind()) {
+        case CFGElement::Statement: {
+          V.handleStatement(BI.castAs<CFGStmt>().getStmt());
+          break;
+        }
+        case CFGElement::AutomaticObjectDtor: {
+          CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
+          CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
+              AD.getDestructorDecl(ACtx->getASTContext()));
+          VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
+          V.handleDestructorCall(VD, DD);
+          break;
+        }
+        default:
+          break;
+        }
+      }
+
+      V.exitCFGBlockBody(CurrBlock);
+
+      // Process successors, handling back edges first.
+      if (V.visitSuccessors()) {
+        SmallVector<CFGBlock*, 8> ForwardEdges;
+
+        // Process successors
+        for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
+                                           SE = CurrBlock->succ_end();
+             SI != SE; ++SI) {
+          if (*SI == nullptr)
+            continue;
+
+          if (!VisitedBlocks.alreadySet(*SI)) {
+            ForwardEdges.push_back(*SI);
+            continue;
+          }
+          V.handleSuccessorBackEdge(*SI);
+        }
+
+        for (auto *Blk : ForwardEdges)
+          V.handleSuccessor(Blk);
+      }
+
+      V.exitCFGBlock(CurrBlock);
+    }
+    V.exitCFG(&CFGraph->getExit());
+  }
+
+  const CFG *getGraph() const { return CFGraph; }
+  CFG *getGraph() { return CFGraph; }
+
+  const NamedDecl *getDecl() const {
+    return dyn_cast<NamedDecl>(ACtx->getDecl());
+  }
+
+  const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
+
+private:
+  CFG *CFGraph;
+  AnalysisDeclContext *ACtx;
+  PostOrderCFGView *SortedGraph;
+};
+
+
+// Translate clang::Expr to til::SExpr.
+class SExprBuilder {
+public:
+  /// \brief Encapsulates the lexical context of a function call.  The lexical
+  /// context includes the arguments to the call, including the implicit object
+  /// argument.  When an attribute containing a mutex expression is attached to
+  /// a method, the expression may refer to formal parameters of the method.
+  /// Actual arguments must be substituted for formal parameters to derive
+  /// the appropriate mutex expression in the lexical context where the function
+  /// is called.  PrevCtx holds the context in which the arguments themselves
+  /// should be evaluated; multiple calling contexts can be chained together
+  /// by the lock_returned attribute.
+  struct CallingContext {
+    const NamedDecl *AttrDecl;  // The decl to which the attr is attached.
+    const Expr *SelfArg;        // Implicit object argument -- e.g. 'this'
+    unsigned NumArgs;           // Number of funArgs
+    const Expr *const *FunArgs; // Function arguments
+    CallingContext *Prev;       // The previous context; or 0 if none.
+    bool SelfArrow;             // is Self referred to with -> or .?
+
+    CallingContext(const NamedDecl *D = nullptr, const Expr *S = nullptr,
+                   unsigned N = 0, const Expr *const *A = nullptr,
+                   CallingContext *P = nullptr)
+        : AttrDecl(D), SelfArg(S), NumArgs(N), FunArgs(A), Prev(P),
+          SelfArrow(false)
+    {}
+  };
+
+  SExprBuilder(til::MemRegionRef A)
+      : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
+        CurrentBlockInfo(nullptr) {
+    // FIXME: we don't always have a self-variable.
+    SelfVar = new (Arena) til::Variable(nullptr);
+    SelfVar->setKind(til::Variable::VK_SFun);
+  }
+
+  // Translate a clang statement or expression to a TIL expression.
+  // Also performs substitution of variables; Ctx provides the context.
+  // Dispatches on the type of S.
+  til::SExpr *translate(const Stmt *S, CallingContext *Ctx);
+  til::SCFG  *buildCFG(CFGWalker &Walker);
+
+  til::SExpr *lookupStmt(const Stmt *S);
+
+  til::BasicBlock *lookupBlock(const CFGBlock *B) {
+    return BlockMap[B->getBlockID()];
+  }
+
+  const til::SCFG *getCFG() const { return Scfg; }
+  til::SCFG *getCFG() { return Scfg; }
+
+private:
+  til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
+                                   CallingContext *Ctx) ;
+  til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
+  til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
+  til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx);
+  til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
+                                         CallingContext *Ctx);
+  til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
+                                           CallingContext *Ctx);
+  til::SExpr *translateUnaryOperator(const UnaryOperator *UO,
+                                     CallingContext *Ctx);
+  til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op,
+                             const BinaryOperator *BO,
+                             CallingContext *Ctx, bool Reverse = false);
+  til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op,
+                                 const BinaryOperator *BO,
+                                 CallingContext *Ctx, bool Assign = false);
+  til::SExpr *translateBinaryOperator(const BinaryOperator *BO,
+                                      CallingContext *Ctx);
+  til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
+  til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
+                                          CallingContext *Ctx);
+  til::SExpr *translateConditionalOperator(const ConditionalOperator *C,
+                                           CallingContext *Ctx);
+  til::SExpr *translateBinaryConditionalOperator(
+      const BinaryConditionalOperator *C, CallingContext *Ctx);
+
+  til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);
+
+  // Map from statements in the clang CFG to SExprs in the til::SCFG.
+  typedef llvm::DenseMap<const Stmt*, til::SExpr*> StatementMap;
+
+  // Map from clang local variables to indices in a LVarDefinitionMap.
+  typedef llvm::DenseMap<const ValueDecl *, unsigned> LVarIndexMap;
+
+  // Map from local variable indices to SSA variables (or constants).
+  typedef std::pair<const ValueDecl *, til::SExpr *> NameVarPair;
+  typedef CopyOnWriteVector<NameVarPair> LVarDefinitionMap;
+
+  struct BlockInfo {
+    LVarDefinitionMap ExitMap;
+    bool HasBackEdges;
+    unsigned UnprocessedSuccessors;   // Successors yet to be processed
+    unsigned ProcessedPredecessors;   // Predecessors already processed
+
+    BlockInfo()
+        : HasBackEdges(false), UnprocessedSuccessors(0),
+          ProcessedPredecessors(0) {}
+    BlockInfo(BlockInfo &&RHS)
+        : ExitMap(std::move(RHS.ExitMap)),
+          HasBackEdges(RHS.HasBackEdges),
+          UnprocessedSuccessors(RHS.UnprocessedSuccessors),
+          ProcessedPredecessors(RHS.ProcessedPredecessors) {}
+
+    BlockInfo &operator=(BlockInfo &&RHS) {
+      if (this != &RHS) {
+        ExitMap = std::move(RHS.ExitMap);
+        HasBackEdges = RHS.HasBackEdges;
+        UnprocessedSuccessors = RHS.UnprocessedSuccessors;
+        ProcessedPredecessors = RHS.ProcessedPredecessors;
+      }
+      return *this;
+    }
+
+  private:
+    BlockInfo(const BlockInfo &) LLVM_DELETED_FUNCTION;
+    void operator=(const BlockInfo &) LLVM_DELETED_FUNCTION;
+  };
+
+  // We implement the CFGVisitor API
+  friend class CFGWalker;
+
+  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
+  void enterCFGBlock(const CFGBlock *B);
+  bool visitPredecessors() { return true; }
+  void handlePredecessor(const CFGBlock *Pred);
+  void handlePredecessorBackEdge(const CFGBlock *Pred);
+  void enterCFGBlockBody(const CFGBlock *B);
+  void handleStatement(const Stmt *S);
+  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD);
+  void exitCFGBlockBody(const CFGBlock *B);
+  bool visitSuccessors() { return true; }
+  void handleSuccessor(const CFGBlock *Succ);
+  void handleSuccessorBackEdge(const CFGBlock *Succ);
+  void exitCFGBlock(const CFGBlock *B);
+  void exitCFG(const CFGBlock *Last);
+
+  void insertStmt(const Stmt *S, til::SExpr *E) {
+    SMap.insert(std::make_pair(S, E));
+  }
+  til::SExpr *getCurrentLVarDefinition(const ValueDecl *VD);
+
+  til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
+                           const ValueDecl *VD = nullptr);
+  til::SExpr *lookupVarDecl(const ValueDecl *VD);
+  til::SExpr *addVarDecl(const ValueDecl *VD, til::SExpr *E);
+  til::SExpr *updateVarDecl(const ValueDecl *VD, til::SExpr *E);
+
+  void makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E);
+  void mergeEntryMap(LVarDefinitionMap Map);
+  void mergeEntryMapBackEdge();
+  void mergePhiNodesBackEdge(const CFGBlock *Blk);
+
+private:
+  til::MemRegionRef Arena;
+  til::Variable *SelfVar;       // Variable to use for 'this'.  May be null.
+  til::SCFG *Scfg;
+
+  StatementMap SMap;                       // Map from Stmt to TIL Variables
+  LVarIndexMap LVarIdxMap;                 // Indices of clang local vars.
+  std::vector<til::BasicBlock *> BlockMap; // Map from clang to til BBs.
+  std::vector<BlockInfo> BBInfo;           // Extra information per BB.
+                                           // Indexed by clang BlockID.
+  std::unique_ptr<SExprBuilder::CallingContext> CallCtx; // Root calling context
+
+  LVarDefinitionMap CurrentLVarMap;
+  std::vector<til::Variable*> CurrentArguments;
+  std::vector<til::Variable*> CurrentInstructions;
+  std::vector<til::Variable*> IncompleteArgs;
+  til::BasicBlock *CurrentBB;
+  BlockInfo *CurrentBlockInfo;
+};
+
+
+// Dump an SCFG to llvm::errs().
+void printSCFG(CFGWalker &Walker);
+
+
+} // end namespace threadSafety
+
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_COMMON_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
new file mode 100644
index 0000000..c4f4b21
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -0,0 +1,108 @@
+//===- ThreadSafetyLogical.h -----------------------------------*- 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 representation for logical expressions with SExpr leaves
+// that are used as part of fact-checking capability expressions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+#define LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace lexpr {
+
+class LExpr {
+public:
+  enum Opcode {
+    Terminal,
+    And,
+    Or,
+    Not
+  };
+  Opcode kind() const { return Kind; }
+
+  /// \brief Logical implication. Returns true if the LExpr implies RHS, i.e. if
+  /// the LExpr holds, then RHS must hold. For example, (A & B) implies A.
+  inline bool implies(const LExpr *RHS) const;
+
+protected:
+  LExpr(Opcode Kind) : Kind(Kind) {}
+
+private:
+  Opcode Kind;
+};
+
+class Terminal : public LExpr {
+  til::SExprRef Expr;
+
+public:
+  Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {}
+
+  const til::SExpr *expr() const { return Expr.get(); }
+  til::SExpr *expr() { return Expr.get(); }
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; }
+};
+
+class BinOp : public LExpr {
+  LExpr *LHS, *RHS;
+
+protected:
+  BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {}
+
+public:
+  const LExpr *left() const { return LHS; }
+  LExpr *left() { return LHS; }
+
+  const LExpr *right() const { return RHS; }
+  LExpr *right() { return RHS; }
+};
+
+class And : public BinOp {
+public:
+  And(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::And) {}
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::And; }
+};
+
+class Or : public BinOp {
+public:
+  Or(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::Or) {}
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Or; }
+};
+
+class Not : public LExpr {
+  LExpr *Exp;
+
+public:
+  Not(LExpr *Exp) : LExpr(LExpr::Not), Exp(Exp) {}
+
+  const LExpr *exp() const { return Exp; }
+  LExpr *exp() { return Exp; }
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; }
+};
+
+/// \brief Logical implication. Returns true if LHS implies RHS, i.e. if LHS
+/// holds, then RHS must hold. For example, (A & B) implies A.
+bool implies(const LExpr *LHS, const LExpr *RHS);
+
+bool LExpr::implies(const LExpr *RHS) const {
+  return lexpr::implies(this, RHS);
+}
+
+}
+}
+}
+
+#endif // LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
new file mode 100644
index 0000000..6ebc95d
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -0,0 +1,54 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- 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 list of core opcodes for the Thread Safety
+// Typed Intermediate language.  Please see ThreadSafetyTIL.h for more
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+
+TIL_OPCODE_DEF(Future)
+TIL_OPCODE_DEF(Undefined)
+TIL_OPCODE_DEF(Wildcard)
+
+TIL_OPCODE_DEF(Literal)
+TIL_OPCODE_DEF(LiteralPtr)
+TIL_OPCODE_DEF(Variable)
+TIL_OPCODE_DEF(Function)
+TIL_OPCODE_DEF(SFunction)
+TIL_OPCODE_DEF(Code)
+TIL_OPCODE_DEF(Field)
+
+TIL_OPCODE_DEF(Apply)
+TIL_OPCODE_DEF(SApply)
+TIL_OPCODE_DEF(Project)
+
+TIL_OPCODE_DEF(Call)
+TIL_OPCODE_DEF(Alloc)
+TIL_OPCODE_DEF(Load)
+TIL_OPCODE_DEF(Store)
+TIL_OPCODE_DEF(ArrayIndex)
+TIL_OPCODE_DEF(ArrayAdd)
+
+TIL_OPCODE_DEF(UnaryOp)
+TIL_OPCODE_DEF(BinaryOp)
+TIL_OPCODE_DEF(Cast)
+
+TIL_OPCODE_DEF(SCFG)
+TIL_OPCODE_DEF(BasicBlock)
+TIL_OPCODE_DEF(Phi)
+TIL_OPCODE_DEF(Goto)
+TIL_OPCODE_DEF(Branch)
+
+// pseudo-terms
+TIL_OPCODE_DEF(Identifier)
+TIL_OPCODE_DEF(IfThenElse)
+TIL_OPCODE_DEF(Let)
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
new file mode 100644
index 0000000..8e4299e
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -0,0 +1,1813 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT in the llvm repository for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple Typed Intermediate Language, or TIL, that is used
+// by the thread safety analysis (See ThreadSafety.cpp).  The TIL is intended
+// to be largely independent of clang, in the hope that the analysis can be
+// reused for other non-C++ languages.  All dependencies on clang/llvm should
+// go in ThreadSafetyUtil.h.
+//
+// Thread safety analysis works by comparing mutex expressions, e.g.
+//
+// class A { Mutex mu; int dat GUARDED_BY(this->mu); }
+// class B { A a; }
+//
+// void foo(B* b) {
+//   (*b).a.mu.lock();     // locks (*b).a.mu
+//   b->a.dat = 0;         // substitute &b->a for 'this';
+//                         // requires lock on (&b->a)->mu
+//   (b->a.mu).unlock();   // unlocks (b->a.mu)
+// }
+//
+// As illustrated by the above example, clang Exprs are not well-suited to
+// represent mutex expressions directly, since there is no easy way to compare
+// Exprs for equivalence.  The thread safety analysis thus lowers clang Exprs
+// into a simple intermediate language (IL).  The IL supports:
+//
+// (1) comparisons for semantic equality of expressions
+// (2) SSA renaming of variables
+// (3) wildcards and pattern matching over expressions
+// (4) hash-based expression lookup
+//
+// The TIL is currently very experimental, is intended only for use within
+// the thread safety analysis, and is subject to change without notice.
+// After the API stabilizes and matures, it may be appropriate to make this
+// more generally available to other analyses.
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
+#define LLVM_CLANG_THREAD_SAFETY_TIL_H
+
+// All clang include dependencies for this file must be put in
+// ThreadSafetyUtil.h.
+#include "ThreadSafetyUtil.h"
+
+#include <stdint.h>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+
+enum TIL_Opcode {
+#define TIL_OPCODE_DEF(X) COP_##X,
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+enum TIL_UnaryOpcode : unsigned char {
+  UOP_Minus,        //  -
+  UOP_BitNot,       //  ~
+  UOP_LogicNot      //  !
+};
+
+enum TIL_BinaryOpcode : unsigned char {
+  BOP_Mul,          //  *
+  BOP_Div,          //  /
+  BOP_Rem,          //  %
+  BOP_Add,          //  +
+  BOP_Sub,          //  -
+  BOP_Shl,          //  <<
+  BOP_Shr,          //  >>
+  BOP_BitAnd,       //  &
+  BOP_BitXor,       //  ^
+  BOP_BitOr,        //  |
+  BOP_Eq,           //  ==
+  BOP_Neq,          //  !=
+  BOP_Lt,           //  <
+  BOP_Leq,          //  <=
+  BOP_LogicAnd,     //  &&
+  BOP_LogicOr       //  ||
+};
+
+enum TIL_CastOpcode : unsigned char {
+  CAST_none = 0,
+  CAST_extendNum,   // extend precision of numeric type
+  CAST_truncNum,    // truncate precision of numeric type
+  CAST_toFloat,     // convert to floating point type
+  CAST_toInt,       // convert to integer type
+};
+
+const TIL_Opcode       COP_Min  = COP_Future;
+const TIL_Opcode       COP_Max  = COP_Branch;
+const TIL_UnaryOpcode  UOP_Min  = UOP_Minus;
+const TIL_UnaryOpcode  UOP_Max  = UOP_LogicNot;
+const TIL_BinaryOpcode BOP_Min  = BOP_Mul;
+const TIL_BinaryOpcode BOP_Max  = BOP_LogicOr;
+const TIL_CastOpcode   CAST_Min = CAST_none;
+const TIL_CastOpcode   CAST_Max = CAST_toInt;
+
+StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
+StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
+
+
+// ValueTypes are data types that can actually be held in registers.
+// All variables and expressions must have a vBNF_Nonealue type.
+// Pointer types are further subdivided into the various heap-allocated
+// types, such as functions, records, etc.
+// Structured types that are passed by value (e.g. complex numbers)
+// require special handling; they use BT_ValueRef, and size ST_0.
+struct ValueType {
+  enum BaseType : unsigned char {
+    BT_Void = 0,
+    BT_Bool,
+    BT_Int,
+    BT_Float,
+    BT_String,    // String literals
+    BT_Pointer,
+    BT_ValueRef
+  };
+
+  enum SizeType : unsigned char {
+    ST_0 = 0,
+    ST_1,
+    ST_8,
+    ST_16,
+    ST_32,
+    ST_64,
+    ST_128
+  };
+
+  inline static SizeType getSizeType(unsigned nbytes);
+
+  template <class T>
+  inline static ValueType getValueType();
+
+  ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
+      : Base(B), Size(Sz), Signed(S), VectSize(VS)
+  { }
+
+  BaseType      Base;
+  SizeType      Size;
+  bool          Signed;
+  unsigned char VectSize;  // 0 for scalar, otherwise num elements in vector
+};
+
+
+inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
+  switch (nbytes) {
+    case 1: return ST_8;
+    case 2: return ST_16;
+    case 4: return ST_32;
+    case 8: return ST_64;
+    case 16: return ST_128;
+    default: return ST_0;
+  }
+}
+
+
+template<>
+inline ValueType ValueType::getValueType<void>() {
+  return ValueType(BT_Void, ST_0, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<bool>() {
+  return ValueType(BT_Bool, ST_1, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int8_t>() {
+  return ValueType(BT_Int, ST_8, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint8_t>() {
+  return ValueType(BT_Int, ST_8, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int16_t>() {
+  return ValueType(BT_Int, ST_16, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint16_t>() {
+  return ValueType(BT_Int, ST_16, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int32_t>() {
+  return ValueType(BT_Int, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint32_t>() {
+  return ValueType(BT_Int, ST_32, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int64_t>() {
+  return ValueType(BT_Int, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint64_t>() {
+  return ValueType(BT_Int, ST_64, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<float>() {
+  return ValueType(BT_Float, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<double>() {
+  return ValueType(BT_Float, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<long double>() {
+  return ValueType(BT_Float, ST_128, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<StringRef>() {
+  return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<void*>() {
+  return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0);
+}
+
+
+
+// Base class for AST nodes in the typed intermediate language.
+class SExpr {
+public:
+  TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
+
+  // Subclasses of SExpr must define the following:
+  //
+  // This(const This& E, ...) {
+  //   copy constructor: construct copy of E, with some additional arguments.
+  // }
+  //
+  // template <class V>
+  // typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+  //   traverse all subexpressions, following the traversal/rewriter interface.
+  // }
+  //
+  // template <class C> typename C::CType compare(CType* E, C& Cmp) {
+  //   compare all subexpressions, following the comparator interface
+  // }
+
+  void *operator new(size_t S, MemRegionRef &R) {
+    return ::operator new(S, R);
+  }
+
+  // SExpr objects cannot be deleted.
+  // This declaration is public to workaround a gcc bug that breaks building
+  // with REQUIRES_EH=1.
+  void operator delete(void *) LLVM_DELETED_FUNCTION;
+
+protected:
+  SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
+  SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
+
+  const unsigned char Opcode;
+  unsigned char Reserved;
+  unsigned short Flags;
+
+private:
+  SExpr() LLVM_DELETED_FUNCTION;
+
+  // SExpr objects must be created in an arena.
+  void *operator new(size_t) LLVM_DELETED_FUNCTION;
+};
+
+
+// Class for owning references to SExprs.
+// Includes attach/detach logic for counting variable references and lazy
+// rewriting strategies.
+class SExprRef {
+public:
+  SExprRef() : Ptr(nullptr) { }
+  SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
+  SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
+
+  // Defined after Variable and Future, below.
+  inline SExprRef(SExpr *P);
+  inline ~SExprRef();
+
+  SExpr       *get()       { return Ptr; }
+  const SExpr *get() const { return Ptr; }
+
+  SExpr       *operator->()       { return get(); }
+  const SExpr *operator->() const { return get(); }
+
+  SExpr       &operator*()        { return *Ptr; }
+  const SExpr &operator*() const  { return *Ptr; }
+
+  bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
+  bool operator!=(const SExprRef &R) const { return !operator==(R); }
+  bool operator==(const SExpr *P)    const { return Ptr == P; }
+  bool operator!=(const SExpr *P)    const { return !operator==(P); }
+  bool operator==(std::nullptr_t)    const { return Ptr == nullptr; }
+  bool operator!=(std::nullptr_t)    const { return Ptr != nullptr; }
+
+  inline void reset(SExpr *E);
+
+private:
+  inline void attach();
+  inline void detach();
+
+  SExpr *Ptr;
+};
+
+
+// Contains various helper functions for SExprs.
+namespace ThreadSafetyTIL {
+  inline bool isTrivial(const SExpr *E) {
+    unsigned Op = E->opcode();
+    return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
+  }
+}
+
+// Nodes which declare variables
+class Function;
+class SFunction;
+class BasicBlock;
+class Let;
+
+
+// A named variable, e.g. "x".
+//
+// There are two distinct places in which a Variable can appear in the AST.
+// A variable declaration introduces a new variable, and can occur in 3 places:
+//   Let-expressions:           (Let (x = t) u)
+//   Functions:                 (Function (x : t) u)
+//   Self-applicable functions  (SFunction (x) t)
+//
+// If a variable occurs in any other location, it is a reference to an existing
+// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
+// allocate a separate AST node for variable references; a reference is just a
+// pointer to the original declaration.
+class Variable : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
+
+  // Let-variable, function parameter, or self-variable
+  enum VariableKind {
+    VK_Let,
+    VK_LetBB,
+    VK_Fun,
+    VK_SFun
+  };
+
+  // These are defined after SExprRef contructor, below
+  inline Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr);
+  inline Variable(StringRef s, SExpr *D = nullptr);
+  inline Variable(const Variable &Vd, SExpr *D);
+
+  VariableKind kind() const { return static_cast<VariableKind>(Flags); }
+
+  const StringRef name() const { return Name; }
+  const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+  // Returns the definition (for let vars) or type (for parameter & self vars)
+  SExpr *definition() { return Definition.get(); }
+  const SExpr *definition() const { return Definition.get(); }
+
+  void attachVar() const { ++NumUses; }
+  void detachVar() const { assert(NumUses > 0); --NumUses; }
+
+  unsigned getID() const { return Id; }
+  unsigned getBlockID() const { return BlockID; }
+
+  void setName(StringRef S) { Name = S; }
+  void setID(unsigned Bid, unsigned I) {
+    BlockID = static_cast<unsigned short>(Bid);
+    Id = static_cast<unsigned short>(I);
+  }
+  void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
+  void setDefinition(SExpr *E);
+  void setKind(VariableKind K) { Flags = K; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This routine is only called for variable references.
+    return Vs.reduceVariableRef(this);
+  }
+
+  template <class C> typename C::CType compare(Variable* E, C& Cmp) {
+    return Cmp.compareVariableRefs(this, E);
+  }
+
+private:
+  friend class Function;
+  friend class SFunction;
+  friend class BasicBlock;
+  friend class Let;
+
+  StringRef Name;                  // The name of the variable.
+  SExprRef  Definition;            // The TIL type or definition
+  const clang::ValueDecl *Cvdecl;  // The clang declaration for this variable.
+
+  unsigned short BlockID;
+  unsigned short Id;
+  mutable unsigned NumUses;
+};
+
+
+// Placeholder for an expression that has not yet been created.
+// Used to implement lazy copy and rewriting strategies.
+class Future : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
+
+  enum FutureStatus {
+    FS_pending,
+    FS_evaluating,
+    FS_done
+  };
+
+  Future() :
+    SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
+  {}
+private:
+  virtual ~Future() LLVM_DELETED_FUNCTION;
+public:
+
+  // Registers the location in the AST where this future is stored.
+  // Forcing the future will automatically update the AST.
+  static inline void registerLocation(SExprRef *Member) {
+    if (Future *F = dyn_cast_or_null<Future>(Member->get()))
+      F->Location = Member;
+  }
+
+  // A lazy rewriting strategy should subclass Future and override this method.
+  virtual SExpr *create() { return nullptr; }
+
+  // Return the result of this future if it exists, otherwise return null.
+  SExpr *maybeGetResult() {
+    return Result;
+  }
+
+  // Return the result of this future; forcing it if necessary.
+  SExpr *result() {
+    switch (Status) {
+    case FS_pending:
+      force();
+      return Result;
+    case FS_evaluating:
+      return nullptr; // infinite loop; illegal recursion.
+    case FS_done:
+      return Result;
+    }
+  }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    assert(Result && "Cannot traverse Future that has not been forced.");
+    return Vs.traverse(Result, Ctx);
+  }
+
+  template <class C> typename C::CType compare(Future* E, C& Cmp) {
+    if (!Result || !E->Result)
+      return Cmp.comparePointers(this, E);
+    return Cmp.compare(Result, E->Result);
+  }
+
+private:
+  // Force the future.
+  inline void force();
+
+  FutureStatus Status;
+  SExpr *Result;
+  SExprRef *Location;
+};
+
+
+inline void SExprRef::attach() {
+  if (!Ptr)
+    return;
+
+  TIL_Opcode Op = Ptr->opcode();
+  if (Op == COP_Variable) {
+    cast<Variable>(Ptr)->attachVar();
+  } else if (Op == COP_Future) {
+    cast<Future>(Ptr)->registerLocation(this);
+  }
+}
+
+inline void SExprRef::detach() {
+  if (Ptr && Ptr->opcode() == COP_Variable) {
+    cast<Variable>(Ptr)->detachVar();
+  }
+}
+
+inline SExprRef::SExprRef(SExpr *P) : Ptr(P) {
+  attach();
+}
+
+inline SExprRef::~SExprRef() {
+  detach();
+}
+
+inline void SExprRef::reset(SExpr *P) {
+  detach();
+  Ptr = P;
+  attach();
+}
+
+
+inline Variable::Variable(StringRef s, SExpr *D)
+    : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr),
+      BlockID(0), Id(0), NumUses(0) {
+  Flags = VK_Let;
+}
+
+inline Variable::Variable(SExpr *D, const clang::ValueDecl *Cvd)
+    : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
+      Definition(D), Cvdecl(Cvd), BlockID(0), Id(0), NumUses(0) {
+  Flags = VK_Let;
+}
+
+inline Variable::Variable(const Variable &Vd, SExpr *D) // rewrite constructor
+    : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl),
+      BlockID(0), Id(0), NumUses(0) {
+  Flags = Vd.kind();
+}
+
+inline void Variable::setDefinition(SExpr *E) {
+  Definition.reset(E);
+}
+
+void Future::force() {
+  Status = FS_evaluating;
+  SExpr *R = create();
+  Result = R;
+  if (Location)
+    Location->reset(R);
+  Status = FS_done;
+}
+
+
+// Placeholder for C++ expressions that cannot be represented in the TIL.
+class Undefined : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
+
+  Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
+  Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceUndefined(*this);
+  }
+
+  template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
+    return Cmp.comparePointers(Cstmt, E->Cstmt);
+  }
+
+private:
+  const clang::Stmt *Cstmt;
+};
+
+
+// Placeholder for a wildcard that matches any other expression.
+class Wildcard : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
+
+  Wildcard() : SExpr(COP_Wildcard) {}
+  Wildcard(const Wildcard &W) : SExpr(W) {}
+
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceWildcard(*this);
+  }
+
+  template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
+    return Cmp.trueResult();
+  }
+};
+
+
+template <class T> class LiteralT;
+
+// Base class for literal values.
+class Literal : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
+
+  Literal(const clang::Expr *C)
+     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C)
+  { }
+  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT), Cexpr(nullptr) {}
+  Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
+
+  // The clang expression for this literal.
+  const clang::Expr *clangExpr() const { return Cexpr; }
+
+  ValueType valueType() const { return ValType; }
+
+  template<class T> const LiteralT<T>& as() const {
+    return *static_cast<const LiteralT<T>*>(this);
+  }
+  template<class T> LiteralT<T>& as() {
+    return *static_cast<LiteralT<T>*>(this);
+  }
+
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
+
+  template <class C> typename C::CType compare(Literal* E, C& Cmp) {
+    // TODO -- use value, not pointer equality
+    return Cmp.comparePointers(Cexpr, E->Cexpr);
+  }
+
+private:
+  const ValueType ValType;
+  const clang::Expr *Cexpr;
+};
+
+
+// Derived class for literal values, which stores the actual value.
+template<class T>
+class LiteralT : public Literal {
+public:
+  LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) { }
+  LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) { }
+
+  T  value() const { return Val;}
+  T& value() { return Val; }
+
+private:
+  T Val;
+};
+
+
+
+template <class V>
+typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
+  if (Cexpr)
+    return Vs.reduceLiteral(*this);
+
+  switch (ValType.Base) {
+  case ValueType::BT_Void:
+    break;
+  case ValueType::BT_Bool:
+    return Vs.reduceLiteralT(as<bool>());
+  case ValueType::BT_Int: {
+    switch (ValType.Size) {
+    case ValueType::ST_8:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int8_t>());
+      else
+        return Vs.reduceLiteralT(as<uint8_t>());
+    case ValueType::ST_16:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int16_t>());
+      else
+        return Vs.reduceLiteralT(as<uint16_t>());
+    case ValueType::ST_32:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int32_t>());
+      else
+        return Vs.reduceLiteralT(as<uint32_t>());
+    case ValueType::ST_64:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int64_t>());
+      else
+        return Vs.reduceLiteralT(as<uint64_t>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_Float: {
+    switch (ValType.Size) {
+    case ValueType::ST_32:
+      return Vs.reduceLiteralT(as<float>());
+    case ValueType::ST_64:
+      return Vs.reduceLiteralT(as<double>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_String:
+    return Vs.reduceLiteralT(as<StringRef>());
+  case ValueType::BT_Pointer:
+    return Vs.reduceLiteralT(as<void*>());
+  case ValueType::BT_ValueRef:
+    break;
+  }
+  return Vs.reduceLiteral(*this);
+}
+
+
+// Literal pointer to an object allocated in memory.
+// At compile time, pointer literals are represented by symbolic names.
+class LiteralPtr : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
+
+  LiteralPtr(const clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
+  LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
+
+  // The clang declaration for the value that this pointer points to.
+  const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceLiteralPtr(*this);
+  }
+
+  template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
+    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+  }
+
+private:
+  const clang::ValueDecl *Cvdecl;
+};
+
+
+// A function -- a.k.a. lambda abstraction.
+// Functions with multiple arguments are created by currying,
+// e.g. (function (x: Int) (function (y: Int) (add x y)))
+class Function : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
+
+  Function(Variable *Vd, SExpr *Bd)
+      : SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Fun);
+  }
+  Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
+      : SExpr(F), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Fun);
+  }
+
+  Variable *variableDecl()  { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This is a variable declaration, so traverse the definition.
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.typeCtx(Ctx));
+    // Tell the rewriter to enter the scope of the function.
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceFunction(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(Function* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+// A self-applicable function.
+// A self-applicable function can be applied to itself.  It's useful for
+// implementing objects and late binding
+class SFunction : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
+
+  SFunction(Variable *Vd, SExpr *B)
+      : SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
+    assert(Vd->Definition == nullptr);
+    Vd->setKind(Variable::VK_SFun);
+    Vd->Definition.reset(this);
+  }
+  SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
+      : SExpr(F), VarDecl(Vd), Body(B) {
+    assert(Vd->Definition == nullptr);
+    Vd->setKind(Variable::VK_SFun);
+    Vd->Definition.reset(this);
+  }
+
+  Variable *variableDecl() { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // A self-variable points to the SFunction itself.
+    // A rewrite must introduce the variable with a null definition, and update
+    // it after 'this' has been rewritten.
+    Variable *Nvd = Vs.enterScope(*VarDecl, nullptr);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
+    // A rewrite operation will call SFun constructor to set Vvd->Definition.
+    return Vs.reduceSFunction(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    typename C::CType Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+// A block of code -- e.g. the body of a function.
+class Code : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
+
+  Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
+  Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
+      : SExpr(C), ReturnType(T), Body(B) {}
+
+  SExpr *returnType() { return ReturnType.get(); }
+  const SExpr *returnType() const { return ReturnType.get(); }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,       Vs.lazyCtx(Ctx));
+    return Vs.reduceCode(*this, Nt, Nb);
+  }
+
+  template <class C> typename C::CType compare(Code* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(body(), E->body());
+  }
+
+private:
+  SExprRef ReturnType;
+  SExprRef Body;
+};
+
+
+// A typed, writable location in memory
+class Field : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
+
+  Field(SExpr *R, SExpr *B) : SExpr(COP_Field), Range(R), Body(B) {}
+  Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
+      : SExpr(C), Range(R), Body(B) {}
+
+  SExpr *range() { return Range.get(); }
+  const SExpr *range() const { return Range.get(); }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,  Vs.lazyCtx(Ctx));
+    return Vs.reduceField(*this, Nr, Nb);
+  }
+
+  template <class C> typename C::CType compare(Field* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(range(), E->range());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(body(), E->body());
+  }
+
+private:
+  SExprRef Range;
+  SExprRef Body;
+};
+
+
+// Apply an argument to a function
+class Apply : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
+
+  Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
+  Apply(const Apply &A, SExpr *F, SExpr *Ar)  // rewrite constructor
+      : SExpr(A), Fun(F), Arg(Ar)
+  {}
+
+  SExpr *fun() { return Fun.get(); }
+  const SExpr *fun() const { return Fun.get(); }
+
+  SExpr *arg() { return Arg.get(); }
+  const SExpr *arg() const { return Arg.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Fun, Vs.subExprCtx(Ctx));
+    auto Na = Vs.traverse(Arg, Vs.subExprCtx(Ctx));
+    return Vs.reduceApply(*this, Nf, Na);
+  }
+
+  template <class C> typename C::CType compare(Apply* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(fun(), E->fun());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(arg(), E->arg());
+  }
+
+private:
+  SExprRef Fun;
+  SExprRef Arg;
+};
+
+
+// Apply a self-argument to a self-applicable function
+class SApply : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
+
+  SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
+  SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
+      : SExpr(A), Sfun(Sf), Arg(Ar) {}
+
+  SExpr *sfun() { return Sfun.get(); }
+  const SExpr *sfun() const { return Sfun.get(); }
+
+  SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
+  const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
+
+  bool isDelegation() const { return Arg == nullptr; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
+    typename V::R_SExpr Na = Arg.get() ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
+                                       : nullptr;
+    return Vs.reduceSApply(*this, Nf, Na);
+  }
+
+  template <class C> typename C::CType compare(SApply* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
+    if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
+      return Ct;
+    return Cmp.compare(arg(), E->arg());
+  }
+
+private:
+  SExprRef Sfun;
+  SExprRef Arg;
+};
+
+
+// Project a named slot from a C++ struct or class.
+class Project : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
+
+  Project(SExpr *R, StringRef SName)
+      : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
+  { }
+  Project(SExpr *R, clang::ValueDecl *Cvd)
+      : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
+  { }
+  Project(const Project &P, SExpr *R)
+      : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
+  { }
+
+  SExpr *record() { return Rec.get(); }
+  const SExpr *record() const { return Rec.get(); }
+
+  const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
+
+  StringRef slotName() const {
+    if (Cvdecl)
+      return Cvdecl->getName();
+    else
+      return SlotName;
+  }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Rec, Vs.subExprCtx(Ctx));
+    return Vs.reduceProject(*this, Nr);
+  }
+
+  template <class C> typename C::CType compare(Project* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(record(), E->record());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+  }
+
+private:
+  SExprRef Rec;
+  StringRef SlotName;
+  clang::ValueDecl *Cvdecl;
+};
+
+
+// Call a function (after all arguments have been applied).
+class Call : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+  Call(SExpr *T, const clang::CallExpr *Ce = nullptr)
+      : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
+  Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
+
+  SExpr *target() { return Target.get(); }
+  const SExpr *target() const { return Target.get(); }
+
+  const clang::CallExpr *clangCallExpr() const { return Cexpr; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(Target, Vs.subExprCtx(Ctx));
+    return Vs.reduceCall(*this, Nt);
+  }
+
+  template <class C> typename C::CType compare(Call* E, C& Cmp) {
+    return Cmp.compare(target(), E->target());
+  }
+
+private:
+  SExprRef Target;
+  const clang::CallExpr *Cexpr;
+};
+
+
+// Allocate memory for a new value on the heap or stack.
+class Alloc : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+  enum AllocKind {
+    AK_Stack,
+    AK_Heap
+  };
+
+  Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
+  Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
+
+  AllocKind kind() const { return static_cast<AllocKind>(Flags); }
+
+  SExpr *dataType() { return Dtype.get(); }
+  const SExpr *dataType() const { return Dtype.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nd = Vs.traverse(Dtype, Vs.declCtx(Ctx));
+    return Vs.reduceAlloc(*this, Nd);
+  }
+
+  template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(dataType(), E->dataType());
+  }
+
+private:
+  SExprRef Dtype;
+};
+
+
+// Load a value from memory.
+class Load : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
+
+  Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
+  Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
+
+  SExpr *pointer() { return Ptr.get(); }
+  const SExpr *pointer() const { return Ptr.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Ptr, Vs.subExprCtx(Ctx));
+    return Vs.reduceLoad(*this, Np);
+  }
+
+  template <class C> typename C::CType compare(Load* E, C& Cmp) {
+    return Cmp.compare(pointer(), E->pointer());
+  }
+
+private:
+  SExprRef Ptr;
+};
+
+
+// Store a value to memory.
+// Source is a pointer, destination is the value to store.
+class Store : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
+
+  Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
+  Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
+
+  SExpr *destination() { return Dest.get(); }  // Address to store to
+  const SExpr *destination() const { return Dest.get(); }
+
+  SExpr *source() { return Source.get(); }     // Value to store
+  const SExpr *source() const { return Source.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Dest,   Vs.subExprCtx(Ctx));
+    auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx));
+    return Vs.reduceStore(*this, Np, Nv);
+  }
+
+  template <class C> typename C::CType compare(Store* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(destination(), E->destination());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(source(), E->source());
+  }
+
+private:
+  SExprRef Dest;
+  SExprRef Source;
+};
+
+
+// If p is a reference to an array, then first(p) is a reference to the first
+// element.  The usual array notation p[i]  becomes first(p + i).
+class ArrayIndex : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
+
+  ArrayIndex(SExpr *A, SExpr *N) : SExpr(COP_ArrayIndex), Array(A), Index(N) {}
+  ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
+    : SExpr(E), Array(A), Index(N) {}
+
+  SExpr *array() { return Array.get(); }
+  const SExpr *array() const { return Array.get(); }
+
+  SExpr *index() { return Index.get(); }
+  const SExpr *index() const { return Index.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayIndex(*this, Na, Ni);
+  }
+
+  template <class C> typename C::CType compare(ArrayIndex* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(array(), E->array());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(index(), E->index());
+  }
+
+private:
+  SExprRef Array;
+  SExprRef Index;
+};
+
+
+// Pointer arithmetic, restricted to arrays only.
+// If p is a reference to an array, then p + n, where n is an integer, is
+// a reference to a subarray.
+class ArrayAdd : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
+
+  ArrayAdd(SExpr *A, SExpr *N) : SExpr(COP_ArrayAdd), Array(A), Index(N) {}
+  ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
+    : SExpr(E), Array(A), Index(N) {}
+
+  SExpr *array() { return Array.get(); }
+  const SExpr *array() const { return Array.get(); }
+
+  SExpr *index() { return Index.get(); }
+  const SExpr *index() const { return Index.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayAdd(*this, Na, Ni);
+  }
+
+  template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(array(), E->array());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(index(), E->index());
+  }
+
+private:
+  SExprRef Array;
+  SExprRef Index;
+};
+
+
+// Simple unary operation -- e.g. !, ~, etc.
+class UnaryOp : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
+
+  UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
+    Flags = Op;
+  }
+  UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U), Expr0(E) { Flags = U.Flags; }
+
+  TIL_UnaryOpcode unaryOpcode() const {
+    return static_cast<TIL_UnaryOpcode>(Flags);
+  }
+
+  SExpr *expr() { return Expr0.get(); }
+  const SExpr *expr() const { return Expr0.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceUnaryOp(*this, Ne);
+  }
+
+  template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr(), E->expr());
+  }
+
+private:
+  SExprRef Expr0;
+};
+
+
+// Simple binary operation -- e.g. +, -, etc.
+class BinaryOp : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
+
+  BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
+      : SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
+    Flags = Op;
+  }
+  BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
+      : SExpr(B), Expr0(E0), Expr1(E1) {
+    Flags = B.Flags;
+  }
+
+  TIL_BinaryOpcode binaryOpcode() const {
+    return static_cast<TIL_BinaryOpcode>(Flags);
+  }
+
+  SExpr *expr0() { return Expr0.get(); }
+  const SExpr *expr0() const { return Expr0.get(); }
+
+  SExpr *expr1() { return Expr1.get(); }
+  const SExpr *expr1() const { return Expr1.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne0 = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    auto Ne1 = Vs.traverse(Expr1, Vs.subExprCtx(Ctx));
+    return Vs.reduceBinaryOp(*this, Ne0, Ne1);
+  }
+
+  template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Ct = Cmp.compare(expr0(), E->expr0());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr1(), E->expr1());
+  }
+
+private:
+  SExprRef Expr0;
+  SExprRef Expr1;
+};
+
+
+// Cast expression
+class Cast : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
+
+  Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
+  Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
+
+  TIL_CastOpcode castOpcode() const {
+    return static_cast<TIL_CastOpcode>(Flags);
+  }
+
+  SExpr *expr() { return Expr0.get(); }
+  const SExpr *expr() const { return Expr0.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceCast(*this, Ne);
+  }
+
+  template <class C> typename C::CType compare(Cast* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(castOpcode(), E->castOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr(), E->expr());
+  }
+
+private:
+  SExprRef Expr0;
+};
+
+
+class SCFG;
+
+
+class Phi : public SExpr {
+public:
+  // TODO: change to SExprRef
+  typedef SimpleArray<SExpr *> ValArray;
+
+  // In minimal SSA form, all Phi nodes are MultiVal.
+  // During conversion to SSA, incomplete Phi nodes may be introduced, which
+  // are later determined to be SingleVal, and are thus redundant.
+  enum Status {
+    PH_MultiVal = 0, // Phi node has multiple distinct values.  (Normal)
+    PH_SingleVal,    // Phi node has one distinct value, and can be eliminated
+    PH_Incomplete    // Phi node is incomplete
+  };
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
+
+  Phi() : SExpr(COP_Phi) {}
+  Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
+  Phi(const Phi &P, ValArray &&Vs)    : SExpr(P), Values(std::move(Vs)) {}
+
+  const ValArray &values() const { return Values; }
+  ValArray &values() { return Values; }
+
+  Status status() const { return static_cast<Status>(Flags); }
+  void setStatus(Status s) { Flags = s; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<typename V::R_SExpr>
+      Nvs(Vs, Values.size());
+
+    for (auto *Val : Values) {
+      Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
+    }
+    return Vs.reducePhi(*this, Nvs);
+  }
+
+  template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  ValArray Values;
+};
+
+
+// A basic block is part of an SCFG, and can be treated as a function in
+// continuation passing style.  It consists of a sequence of phi nodes, which
+// are "arguments" to the function, followed by a sequence of instructions.
+// Both arguments and instructions define new variables.  It ends with a
+// branch or goto to another basic block in the same SCFG.
+class BasicBlock : public SExpr {
+public:
+  typedef SimpleArray<Variable*>   VarArray;
+  typedef SimpleArray<BasicBlock*> BlockArray;
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
+
+  explicit BasicBlock(MemRegionRef A, BasicBlock* P = nullptr)
+      : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),
+        Parent(P), Terminator(nullptr)
+  { }
+  BasicBlock(BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
+      : SExpr(COP_BasicBlock), Arena(B.Arena), CFGPtr(nullptr), BlockID(0),
+        Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
+        Terminator(T)
+  { }
+
+  unsigned blockID() const { return BlockID; }
+  unsigned numPredecessors() const { return Predecessors.size(); }
+
+  const SCFG* cfg() const { return CFGPtr; }
+  SCFG* cfg() { return CFGPtr; }
+
+  const BasicBlock *parent() const { return Parent; }
+  BasicBlock *parent() { return Parent; }
+
+  const VarArray &arguments() const { return Args; }
+  VarArray &arguments() { return Args; }
+
+  const VarArray &instructions() const { return Instrs; }
+  VarArray &instructions() { return Instrs; }
+
+  const BlockArray &predecessors() const { return Predecessors; }
+  BlockArray &predecessors() { return Predecessors; }
+
+  const SExpr *terminator() const { return Terminator.get(); }
+  SExpr *terminator() { return Terminator.get(); }
+
+  void setBlockID(unsigned i)   { BlockID = i; }
+  void setParent(BasicBlock *P) { Parent = P;  }
+  void setTerminator(SExpr *E)  { Terminator.reset(E); }
+
+  // Add a new argument.  V must define a phi-node.
+  void addArgument(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Args.reserveCheck(1, Arena);
+    Args.push_back(V);
+  }
+  // Add a new instruction.
+  void addInstruction(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Instrs.reserveCheck(1, Arena);
+    Instrs.push_back(V);
+  }
+  // Add a new predecessor, and return the phi-node index for it.
+  // Will add an argument to all phi-nodes, initialized to nullptr.
+  unsigned addPredecessor(BasicBlock *Pred);
+
+  // Reserve space for Nargs arguments.
+  void reserveArguments(unsigned Nargs)   { Args.reserve(Nargs, Arena); }
+
+  // Reserve space for Nins instructions.
+  void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); }
+
+  // Reserve space for NumPreds predecessors, including space in phi nodes.
+  void reservePredecessors(unsigned NumPreds);
+
+  // Return the index of BB, or Predecessors.size if BB is not a predecessor.
+  unsigned findPredecessorIndex(const BasicBlock *BB) const {
+    auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
+    return std::distance(Predecessors.cbegin(), I);
+  }
+
+  // Set id numbers for variables.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<Variable*> Nas(Vs, Args.size());
+    typename V::template Container<Variable*> Nis(Vs, Instrs.size());
+
+    // Entering the basic block should do any scope initialization.
+    Vs.enterBasicBlock(*this);
+
+    for (auto *A : Args) {
+      auto Ne = Vs.traverse(A->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*A, Ne);
+      Nas.push_back(Nvd);
+    }
+    for (auto *I : Instrs) {
+      auto Ne = Vs.traverse(I->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*I, Ne);
+      Nis.push_back(Nvd);
+    }
+    auto Nt = Vs.traverse(Terminator, Ctx);
+
+    // Exiting the basic block should handle any scope cleanup.
+    Vs.exitBasicBlock(*this);
+
+    return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
+  }
+
+  template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  friend class SCFG;
+
+  MemRegionRef Arena;
+
+  SCFG       *CFGPtr;       // The CFG that contains this block.
+  unsigned   BlockID;       // unique id for this BB in the containing CFG
+  BasicBlock *Parent;       // The parent block is the enclosing lexical scope.
+                            // The parent dominates this block.
+  BlockArray Predecessors;  // Predecessor blocks in the CFG.
+  VarArray   Args;          // Phi nodes.  One argument per predecessor.
+  VarArray   Instrs;        // Instructions.
+  SExprRef   Terminator;    // Branch or Goto
+};
+
+
+// An SCFG is a control-flow graph.  It consists of a set of basic blocks, each
+// of which terminates in a branch to another basic block.  There is one
+// entry point, and one exit point.
+class SCFG : public SExpr {
+public:
+  typedef SimpleArray<BasicBlock *> BlockArray;
+  typedef BlockArray::iterator iterator;
+  typedef BlockArray::const_iterator const_iterator;
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
+
+  SCFG(MemRegionRef A, unsigned Nblocks)
+    : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
+      Entry(nullptr), Exit(nullptr) {
+    Entry = new (A) BasicBlock(A, nullptr);
+    Exit  = new (A) BasicBlock(A, Entry);
+    auto *V = new (A) Variable(new (A) Phi());
+    Exit->addArgument(V);
+    add(Entry);
+    add(Exit);
+  }
+  SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
+      : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)),
+        Entry(nullptr), Exit(nullptr) {
+    // TODO: set entry and exit!
+  }
+
+  iterator begin() { return Blocks.begin(); }
+  iterator end() { return Blocks.end(); }
+
+  const_iterator begin() const { return cbegin(); }
+  const_iterator end() const { return cend(); }
+
+  const_iterator cbegin() const { return Blocks.cbegin(); }
+  const_iterator cend() const { return Blocks.cend(); }
+
+  const BasicBlock *entry() const { return Entry; }
+  BasicBlock *entry() { return Entry; }
+  const BasicBlock *exit() const { return Exit; }
+  BasicBlock *exit() { return Exit; }
+
+  inline void add(BasicBlock *BB) {
+    assert(BB->CFGPtr == nullptr || BB->CFGPtr == this);
+    BB->setBlockID(Blocks.size());
+    BB->CFGPtr = this;
+    Blocks.reserveCheck(1, Arena);
+    Blocks.push_back(BB);
+  }
+
+  void setEntry(BasicBlock *BB) { Entry = BB; }
+  void setExit(BasicBlock *BB)  { Exit = BB;  }
+
+  // Set varable ids in all blocks.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    Vs.enterCFG(*this);
+    typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
+    for (auto *B : Blocks) {
+      Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
+    }
+    Vs.exitCFG(*this);
+    return Vs.reduceSCFG(*this, Bbs);
+  }
+
+  template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  MemRegionRef Arena;
+  BlockArray   Blocks;
+  BasicBlock   *Entry;
+  BasicBlock   *Exit;
+};
+
+
+class Goto : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
+
+  Goto(BasicBlock *B, unsigned I)
+      : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
+  Goto(const Goto &G, BasicBlock *B, unsigned I)
+      : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
+
+  const BasicBlock *targetBlock() const { return TargetBlock; }
+  BasicBlock *targetBlock() { return TargetBlock; }
+
+  unsigned index() const { return Index; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
+    return Vs.reduceGoto(*this, Ntb);
+  }
+
+  template <class C> typename C::CType compare(Goto *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  BasicBlock *TargetBlock;
+  unsigned Index;   // Index into Phi nodes of target block.
+};
+
+
+class Branch : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
+
+  Branch(SExpr *C, BasicBlock *T, BasicBlock *E, unsigned TI, unsigned EI)
+      : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+        ThenIndex(TI), ElseIndex(EI)
+  {}
+  Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E,
+         unsigned TI, unsigned EI)
+      : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+        ThenIndex(TI), ElseIndex(EI)
+  {}
+
+  const SExpr *condition() const { return Condition; }
+  SExpr *condition() { return Condition; }
+
+  const BasicBlock *thenBlock() const { return ThenBlock; }
+  BasicBlock *thenBlock() { return ThenBlock; }
+
+  const BasicBlock *elseBlock() const { return ElseBlock; }
+  BasicBlock *elseBlock() { return ElseBlock; }
+
+  unsigned thenIndex() const { return ThenIndex; }
+  unsigned elseIndex() const { return ElseIndex; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(ThenBlock);
+    BasicBlock *Nte = Vs.reduceBasicBlockRef(ElseBlock);
+    return Vs.reduceBranch(*this, Nc, Ntb, Nte);
+  }
+
+  template <class C> typename C::CType compare(Branch *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  SExpr *Condition;
+  BasicBlock *ThenBlock;
+  BasicBlock *ElseBlock;
+  unsigned ThenIndex;
+  unsigned ElseIndex;
+};
+
+
+// An identifier, e.g. 'foo' or 'x'.
+// This is a pseduo-term; it will be lowered to a variable or projection.
+class Identifier : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
+
+  Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) { }
+  Identifier(const Identifier& I) : SExpr(I), Name(I.Name)  { }
+
+  StringRef name() const { return Name; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceIdentifier(*this);
+  }
+
+  template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
+    return Cmp.compareStrings(name(), E->name());
+  }
+
+private:
+  StringRef Name;
+};
+
+
+// An if-then-else expression.
+// This is a pseduo-term; it will be lowered to a branch in a CFG.
+class IfThenElse : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
+
+  IfThenElse(SExpr *C, SExpr *T, SExpr *E)
+    : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E)
+  { }
+  IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
+    : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
+  { }
+
+  SExpr *condition() { return Condition.get(); }   // Address to store to
+  const SExpr *condition() const { return Condition.get(); }
+
+  SExpr *thenExpr() { return ThenExpr.get(); }     // Value to store
+  const SExpr *thenExpr() const { return ThenExpr.get(); }
+
+  SExpr *elseExpr() { return ElseExpr.get(); }     // Value to store
+  const SExpr *elseExpr() const { return ElseExpr.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    auto Nt = Vs.traverse(ThenExpr,  Vs.subExprCtx(Ctx));
+    auto Ne = Vs.traverse(ElseExpr,  Vs.subExprCtx(Ctx));
+    return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
+  }
+
+  template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(condition(), E->condition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Ct = Cmp.compare(thenExpr(), E->thenExpr());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(elseExpr(), E->elseExpr());
+  }
+
+private:
+  SExprRef Condition;
+  SExprRef ThenExpr;
+  SExprRef ElseExpr;
+};
+
+
+// A let-expression,  e.g.  let x=t; u.
+// This is a pseduo-term; it will be lowered to instructions in a CFG.
+class Let : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
+
+  Let(Variable *Vd, SExpr *Bd) : SExpr(COP_Let), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Let);
+  }
+  Let(const Let &L, Variable *Vd, SExpr *Bd) : SExpr(L), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Let);
+  }
+
+  Variable *variableDecl()  { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This is a variable declaration, so traverse the definition.
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.subExprCtx(Ctx));
+    // Tell the rewriter to enter the scope of the let variable.
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Ctx);
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceLet(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(Let* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+
+SExpr *getCanonicalVal(SExpr *E);
+void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
new file mode 100644
index 0000000..bc1490b
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -0,0 +1,936 @@
+//===- ThreadSafetyTraverse.h ----------------------------------*- 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 framework for doing generic traversals and rewriting
+// operations over the Thread Safety TIL.
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+#define LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+
+#include "ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Defines an interface used to traverse SExprs.  Traversals have been made as
+// generic as possible, and are intended to handle any kind of pass over the
+// AST, e.g. visiters, copying, non-destructive rewriting, destructive
+// (in-place) rewriting, hashing, typing, etc.
+//
+// Traversals implement the functional notion of a "fold" operation on SExprs.
+// Each SExpr class provides a traverse method, which does the following:
+//   * e->traverse(v):
+//       // compute a result r_i for each subexpression e_i
+//       for (i = 1..n)  r_i = v.traverse(e_i);
+//       // combine results into a result for e,  where X is the class of e
+//       return v.reduceX(*e, r_1, .. r_n).
+//
+// A visitor can control the traversal by overriding the following methods:
+//   * v.traverse(e):
+//       return v.traverseByCase(e), which returns v.traverseX(e)
+//   * v.traverseX(e):   (X is the class of e)
+//       return e->traverse(v).
+//   * v.reduceX(*e, r_1, .. r_n):
+//       compute a result for a node of type X
+//
+// The reduceX methods control the kind of traversal (visitor, copy, etc.).
+// They are defined in derived classes.
+//
+// Class R defines the basic interface types (R_SExpr).
+template <class Self, class R>
+class Traversal {
+public:
+  Self *self() { return static_cast<Self *>(this); }
+
+  // Traverse an expression -- returning a result of type R_SExpr.
+  // Override this method to do something for every expression, regardless
+  // of which kind it is.
+  typename R::R_SExpr traverse(SExprRef &E, typename R::R_Ctx Ctx) {
+    return traverse(E.get(), Ctx);
+  }
+
+  typename R::R_SExpr traverse(SExpr *E, typename R::R_Ctx Ctx) {
+    return traverseByCase(E, Ctx);
+  }
+
+  // Helper method to call traverseX(e) on the appropriate type.
+  typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) {
+    switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                   \
+    case COP_##X:                                                           \
+      return self()->traverse##X(cast<X>(E), Ctx);
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+
+// Traverse e, by static dispatch on the type "X" of e.
+// Override these methods to do something for a particular kind of term.
+#define TIL_OPCODE_DEF(X)                                                   \
+  typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) {            \
+    return e->traverse(*self(), Ctx);                                       \
+  }
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+
+// Base class for simple reducers that don't much care about the context.
+class SimpleReducerBase {
+public:
+  enum TraversalKind {
+    TRV_Normal,
+    TRV_Decl,
+    TRV_Lazy,
+    TRV_Type
+  };
+
+  // R_Ctx defines a "context" for the traversal, which encodes information
+  // about where a term appears.  This can be used to encoding the
+  // "current continuation" for CPS transforms, or other information.
+  typedef TraversalKind R_Ctx;
+
+  // Create context for an ordinary subexpression.
+  R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; }
+
+  // Create context for a subexpression that occurs in a declaration position
+  // (e.g. function body).
+  R_Ctx declCtx(R_Ctx Ctx) { return TRV_Decl; }
+
+  // Create context for a subexpression that occurs in a position that
+  // should be reduced lazily.  (e.g. code body).
+  R_Ctx lazyCtx(R_Ctx Ctx) { return TRV_Lazy; }
+
+  // Create context for a subexpression that occurs in a type position.
+  R_Ctx typeCtx(R_Ctx Ctx) { return TRV_Type; }
+};
+
+
+// Base class for traversals that rewrite an SExpr to another SExpr.
+class CopyReducerBase : public SimpleReducerBase {
+public:
+  // R_SExpr is the result type for a traversal.
+  // A copy or non-destructive rewrite returns a newly allocated term.
+  typedef SExpr *R_SExpr;
+  typedef BasicBlock *R_BasicBlock;
+
+  // Container is a minimal interface used to store results when traversing
+  // SExprs of variable arity, such as Phi, Goto, and SCFG.
+  template <class T> class Container {
+  public:
+    // Allocate a new container with a capacity for n elements.
+    Container(CopyReducerBase &S, unsigned N) : Elems(S.Arena, N) {}
+
+    // Push a new element onto the container.
+    void push_back(T E) { Elems.push_back(E); }
+
+    SimpleArray<T> Elems;
+  };
+
+  CopyReducerBase(MemRegionRef A) : Arena(A) {}
+
+protected:
+  MemRegionRef Arena;
+};
+
+
+// Implements a traversal that makes a deep copy of an SExpr.
+// The default behavior of reduce##X(...) is to create a copy of the original.
+// Subclasses can override reduce##X to implement non-destructive rewriting
+// passes.
+template<class Self>
+class CopyReducer : public Traversal<Self, CopyReducerBase>,
+                    public CopyReducerBase {
+public:
+  CopyReducer(MemRegionRef A) : CopyReducerBase(A) {}
+
+public:
+  R_SExpr reduceNull() {
+    return nullptr;
+  }
+  // R_SExpr reduceFuture(...)  is never used.
+
+  R_SExpr reduceUndefined(Undefined &Orig) {
+    return new (Arena) Undefined(Orig);
+  }
+  R_SExpr reduceWildcard(Wildcard &Orig) {
+    return new (Arena) Wildcard(Orig);
+  }
+
+  R_SExpr reduceLiteral(Literal &Orig) {
+    return new (Arena) Literal(Orig);
+  }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) {
+    return new (Arena) LiteralT<T>(Orig);
+  }
+  R_SExpr reduceLiteralPtr(LiteralPtr &Orig) {
+    return new (Arena) LiteralPtr(Orig);
+  }
+
+  R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+    return new (Arena) Function(Orig, Nvd, E0);
+  }
+  R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+    return new (Arena) SFunction(Orig, Nvd, E0);
+  }
+  R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Code(Orig, E0, E1);
+  }
+  R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Field(Orig, E0, E1);
+  }
+
+  R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Apply(Orig, E0, E1);
+  }
+  R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) SApply(Orig, E0, E1);
+  }
+  R_SExpr reduceProject(Project &Orig, R_SExpr E0) {
+    return new (Arena) Project(Orig, E0);
+  }
+  R_SExpr reduceCall(Call &Orig, R_SExpr E0) {
+    return new (Arena) Call(Orig, E0);
+  }
+
+  R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) {
+    return new (Arena) Alloc(Orig, E0);
+  }
+  R_SExpr reduceLoad(Load &Orig, R_SExpr E0) {
+    return new (Arena) Load(Orig, E0);
+  }
+  R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Store(Orig, E0, E1);
+  }
+  R_SExpr reduceArrayIndex(ArrayIndex &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) ArrayIndex(Orig, E0, E1);
+  }
+  R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) ArrayAdd(Orig, E0, E1);
+  }
+  R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) {
+    return new (Arena) UnaryOp(Orig, E0);
+  }
+  R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) BinaryOp(Orig, E0, E1);
+  }
+  R_SExpr reduceCast(Cast &Orig, R_SExpr E0) {
+    return new (Arena) Cast(Orig, E0);
+  }
+
+  R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) {
+    return nullptr;  // FIXME: implement CFG rewriting
+  }
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return nullptr;  // FIXME: implement CFG rewriting
+  }
+  R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+    return new (Arena) Phi(Orig, std::move(As.Elems));
+  }
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
+    return new (Arena) Goto(Orig, B, 0);  // FIXME: set index
+  }
+  R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+    return new (Arena) Branch(O, C, B0, B1, 0, 0);  // FIXME: set indices
+  }
+
+  R_SExpr reduceIdentifier(Identifier &Orig) {
+    return new (Arena) Identifier(Orig);
+  }
+  R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+    return new (Arena) IfThenElse(Orig, C, T, E);
+  }
+  R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+    return new (Arena) Let(Orig, Nvd, B);
+  }
+
+  // Create a new variable from orig, and push it onto the lexical scope.
+  Variable *enterScope(Variable &Orig, R_SExpr E0) {
+    return new (Arena) Variable(Orig, E0);
+  }
+  // Exit the lexical scope of orig.
+  void exitScope(const Variable &Orig) {}
+
+  void enterCFG(SCFG &Cfg) {}
+  void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
+
+  // Map Variable references to their rewritten definitions.
+  Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
+
+  // Map BasicBlock references to their rewritten definitions.
+  BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+};
+
+
+class SExprCopier : public CopyReducer<SExprCopier> {
+public:
+  typedef SExpr *R_SExpr;
+
+  SExprCopier(MemRegionRef A) : CopyReducer(A) { }
+
+  // Create a copy of e in region a.
+  static SExpr *copy(SExpr *E, MemRegionRef A) {
+    SExprCopier Copier(A);
+    return Copier.traverse(E, TRV_Normal);
+  }
+};
+
+
+
+// Base class for visit traversals.
+class VisitReducerBase : public SimpleReducerBase {
+public:
+  // A visitor returns a bool, representing success or failure.
+  typedef bool R_SExpr;
+  typedef bool R_BasicBlock;
+
+  // A visitor "container" is a single bool, which accumulates success.
+  template <class T> class Container {
+  public:
+    Container(VisitReducerBase &S, unsigned N) : Success(true) {}
+    void push_back(bool E) { Success = Success && E; }
+
+    bool Success;
+  };
+};
+
+
+// Implements a traversal that visits each subexpression, and returns either
+// true or false.
+template <class Self>
+class VisitReducer : public Traversal<Self, VisitReducerBase>,
+                     public VisitReducerBase {
+public:
+  VisitReducer() {}
+
+public:
+  R_SExpr reduceNull() { return true; }
+  R_SExpr reduceUndefined(Undefined &Orig) { return true; }
+  R_SExpr reduceWildcard(Wildcard &Orig) { return true; }
+
+  R_SExpr reduceLiteral(Literal &Orig) { return true; }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) { return true; }
+  R_SExpr reduceLiteralPtr(Literal &Orig) { return true; }
+
+  R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+    return Nvd && E0;
+  }
+  R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+    return Nvd && E0;
+  }
+  R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceProject(Project &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceCall(Call &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; }
+  R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { return E0; }
+
+  R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
+    return Bbs.Success;
+  }
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return (As.Success && Is.Success && T);
+  }
+  R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+    return As.Success;
+  }
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
+    return true;
+  }
+  R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+    return C;
+  }
+
+  R_SExpr reduceIdentifier(Identifier &Orig) {
+    return true;
+  }
+  R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+    return C && T && E;
+  }
+  R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+    return Nvd && B;
+  }
+
+  Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; }
+  void exitScope(const Variable &Orig) {}
+  void enterCFG(SCFG &Cfg) {}
+  void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
+
+  Variable   *reduceVariableRef  (Variable *Ovd)   { return Ovd; }
+  BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+
+public:
+  bool traverse(SExpr *E, TraversalKind K = TRV_Normal) {
+    Success = Success && this->traverseByCase(E);
+    return Success;
+  }
+
+  static bool visit(SExpr *E) {
+    Self Visitor;
+    return Visitor.traverse(E, TRV_Normal);
+  }
+
+private:
+  bool Success;
+};
+
+
+// Basic class for comparison operations over expressions.
+template <typename Self>
+class Comparator {
+protected:
+  Self *self() { return reinterpret_cast<Self *>(this); }
+
+public:
+  bool compareByCase(SExpr *E1, SExpr* E2) {
+    switch (E1->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                     \
+    case COP_##X:                                                             \
+      return cast<X>(E1)->compare(cast<X>(E2), *self());
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+};
+
+
+class EqualsComparator : public Comparator<EqualsComparator> {
+public:
+  // Result type for the comparison, e.g. bool for simple equality,
+  // or int for lexigraphic comparison (-1, 0, 1).  Must have one value which
+  // denotes "true".
+  typedef bool CType;
+
+  CType trueResult() { return true; }
+  bool notTrue(CType ct) { return !ct; }
+
+  bool compareIntegers(unsigned i, unsigned j)       { return i == j; }
+  bool compareStrings (StringRef s, StringRef r)     { return s == r; }
+  bool comparePointers(const void* P, const void* Q) { return P == Q; }
+
+  bool compare(SExpr *E1, SExpr* E2) {
+    if (E1->opcode() != E2->opcode())
+      return false;
+    return compareByCase(E1, E2);
+  }
+
+  // TODO -- handle alpha-renaming of variables
+  void enterScope(Variable* V1, Variable* V2) { }
+  void leaveScope() { }
+
+  bool compareVariableRefs(Variable* V1, Variable* V2) {
+    return V1 == V2;
+  }
+
+  static bool compareExprs(SExpr *E1, SExpr* E2) {
+    EqualsComparator Eq;
+    return Eq.compare(E1, E2);
+  }
+};
+
+
+// Pretty printer for TIL expressions
+template <typename Self, typename StreamType>
+class PrettyPrinter {
+private:
+  bool Verbose;  // Print out additional information
+  bool Cleanup;  // Omit redundant decls.
+
+public:
+  PrettyPrinter(bool V = false, bool C = true) : Verbose(V), Cleanup(C) { }
+
+  static void print(SExpr *E, StreamType &SS) {
+    Self printer;
+    printer.printSExpr(E, SS, Prec_MAX);
+  }
+
+protected:
+  Self *self() { return reinterpret_cast<Self *>(this); }
+
+  void newline(StreamType &SS) {
+    SS << "\n";
+  }
+
+  // TODO: further distinguish between binary operations.
+  static const unsigned Prec_Atom = 0;
+  static const unsigned Prec_Postfix = 1;
+  static const unsigned Prec_Unary = 2;
+  static const unsigned Prec_Binary = 3;
+  static const unsigned Prec_Other = 4;
+  static const unsigned Prec_Decl = 5;
+  static const unsigned Prec_MAX = 6;
+
+  // Return the precedence of a given node, for use in pretty printing.
+  unsigned precedence(SExpr *E) {
+    switch (E->opcode()) {
+      case COP_Future:     return Prec_Atom;
+      case COP_Undefined:  return Prec_Atom;
+      case COP_Wildcard:   return Prec_Atom;
+
+      case COP_Literal:    return Prec_Atom;
+      case COP_LiteralPtr: return Prec_Atom;
+      case COP_Variable:   return Prec_Atom;
+      case COP_Function:   return Prec_Decl;
+      case COP_SFunction:  return Prec_Decl;
+      case COP_Code:       return Prec_Decl;
+      case COP_Field:      return Prec_Decl;
+
+      case COP_Apply:      return Prec_Postfix;
+      case COP_SApply:     return Prec_Postfix;
+      case COP_Project:    return Prec_Postfix;
+
+      case COP_Call:       return Prec_Postfix;
+      case COP_Alloc:      return Prec_Other;
+      case COP_Load:       return Prec_Postfix;
+      case COP_Store:      return Prec_Other;
+      case COP_ArrayIndex: return Prec_Postfix;
+      case COP_ArrayAdd:   return Prec_Postfix;
+
+      case COP_UnaryOp:    return Prec_Unary;
+      case COP_BinaryOp:   return Prec_Binary;
+      case COP_Cast:       return Prec_Unary;
+
+      case COP_SCFG:       return Prec_Decl;
+      case COP_BasicBlock: return Prec_MAX;
+      case COP_Phi:        return Prec_Atom;
+      case COP_Goto:       return Prec_Atom;
+      case COP_Branch:     return Prec_Atom;
+
+      case COP_Identifier: return Prec_Atom;
+      case COP_IfThenElse: return Prec_Other;
+      case COP_Let:        return Prec_Decl;
+    }
+    return Prec_MAX;
+  }
+
+  void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
+    if (!BB) {
+      SS << "BB_null";
+      return;
+    }
+    SS << "BB_";
+    SS << BB->blockID();
+    SS << ":";
+    SS << index;
+  }
+
+  void printSExpr(SExpr *E, StreamType &SS, unsigned P) {
+    if (!E) {
+      self()->printNull(SS);
+      return;
+    }
+    if (self()->precedence(E) > P) {
+      // Wrap expr in () if necessary.
+      SS << "(";
+      self()->printSExpr(E, SS, Prec_MAX);
+      SS << ")";
+      return;
+    }
+
+    switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                  \
+    case COP_##X:                                                          \
+      self()->print##X(cast<X>(E), SS);                                    \
+      return;
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+
+  void printNull(StreamType &SS) {
+    SS << "#null";
+  }
+
+  void printFuture(Future *E, StreamType &SS) {
+    self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom);
+  }
+
+  void printUndefined(Undefined *E, StreamType &SS) {
+    SS << "#undefined";
+  }
+
+  void printWildcard(Wildcard *E, StreamType &SS) {
+    SS << "_";
+  }
+
+  template<class T>
+  void printLiteralT(LiteralT<T> *E, StreamType &SS) {
+    SS << E->value();
+  }
+
+  void printLiteralT(LiteralT<uint8_t> *E, StreamType &SS) {
+    SS << "'" << E->value() << "'";
+  }
+
+  void printLiteral(Literal *E, StreamType &SS) {
+    if (E->clangExpr()) {
+      SS << getSourceLiteralString(E->clangExpr());
+      return;
+    }
+    else {
+      ValueType VT = E->valueType();
+      switch (VT.Base) {
+      case ValueType::BT_Void: {
+        SS << "void";
+        return;
+      }
+      case ValueType::BT_Bool: {
+        if (E->as<bool>().value())
+          SS << "true";
+        else
+          SS << "false";
+        return;
+      }
+      case ValueType::BT_Int: {
+        switch (VT.Size) {
+        case ValueType::ST_8:
+          if (VT.Signed)
+            printLiteralT(&E->as<int8_t>(), SS);
+          else
+            printLiteralT(&E->as<uint8_t>(), SS);
+          return;
+        case ValueType::ST_16:
+          if (VT.Signed)
+            printLiteralT(&E->as<int16_t>(), SS);
+          else
+            printLiteralT(&E->as<uint16_t>(), SS);
+          return;
+        case ValueType::ST_32:
+          if (VT.Signed)
+            printLiteralT(&E->as<int32_t>(), SS);
+          else
+            printLiteralT(&E->as<uint32_t>(), SS);
+          return;
+        case ValueType::ST_64:
+          if (VT.Signed)
+            printLiteralT(&E->as<int64_t>(), SS);
+          else
+            printLiteralT(&E->as<uint64_t>(), SS);
+          return;
+        default:
+          break;
+        }
+        break;
+      }
+      case ValueType::BT_Float: {
+        switch (VT.Size) {
+        case ValueType::ST_32:
+          printLiteralT(&E->as<float>(), SS);
+          return;
+        case ValueType::ST_64:
+          printLiteralT(&E->as<double>(), SS);
+          return;
+        default:
+          break;
+        }
+        break;
+      }
+      case ValueType::BT_String: {
+        SS << "\"";
+        printLiteralT(&E->as<StringRef>(), SS);
+        SS << "\"";
+        return;
+      }
+      case ValueType::BT_Pointer: {
+        SS << "#ptr";
+        return;
+      }
+      case ValueType::BT_ValueRef: {
+        SS << "#vref";
+        return;
+      }
+      }
+    }
+    SS << "#lit";
+  }
+
+  void printLiteralPtr(LiteralPtr *E, StreamType &SS) {
+    SS << E->clangDecl()->getNameAsString();
+  }
+
+  void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) {
+    if (!IsVarDecl && Cleanup) {
+      SExpr* E = getCanonicalVal(V);
+      if (E != V) {
+        printSExpr(E, SS, Prec_Atom);
+        return;
+      }
+    }
+    if (V->kind() == Variable::VK_LetBB)
+      SS << V->name() << V->getBlockID() << "_" << V->getID();
+    else
+      SS << V->name() << V->getID();
+  }
+
+  void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) {
+    switch (sugared) {
+      default:
+        SS << "\\(";   // Lambda
+        break;
+      case 1:
+        SS << "(";     // Slot declarations
+        break;
+      case 2:
+        SS << ", ";    // Curried functions
+        break;
+    }
+    self()->printVariable(E->variableDecl(), SS, true);
+    SS << ": ";
+    self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX);
+
+    SExpr *B = E->body();
+    if (B && B->opcode() == COP_Function)
+      self()->printFunction(cast<Function>(B), SS, 2);
+    else {
+      SS << ")";
+      self()->printSExpr(B, SS, Prec_Decl);
+    }
+  }
+
+  void printSFunction(SFunction *E, StreamType &SS) {
+    SS << "@";
+    self()->printVariable(E->variableDecl(), SS, true);
+    SS << " ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printCode(Code *E, StreamType &SS) {
+    SS << ": ";
+    self()->printSExpr(E->returnType(), SS, Prec_Decl-1);
+    SS << " -> ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printField(Field *E, StreamType &SS) {
+    SS << ": ";
+    self()->printSExpr(E->range(), SS, Prec_Decl-1);
+    SS << " = ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printApply(Apply *E, StreamType &SS, bool sugared = false) {
+    SExpr *F = E->fun();
+    if (F->opcode() == COP_Apply) {
+      printApply(cast<Apply>(F), SS, true);
+      SS << ", ";
+    } else {
+      self()->printSExpr(F, SS, Prec_Postfix);
+      SS << "(";
+    }
+    self()->printSExpr(E->arg(), SS, Prec_MAX);
+    if (!sugared)
+      SS << ")$";
+  }
+
+  void printSApply(SApply *E, StreamType &SS) {
+    self()->printSExpr(E->sfun(), SS, Prec_Postfix);
+    if (E->isDelegation()) {
+      SS << "@(";
+      self()->printSExpr(E->arg(), SS, Prec_MAX);
+      SS << ")";
+    }
+  }
+
+  void printProject(Project *E, StreamType &SS) {
+    self()->printSExpr(E->record(), SS, Prec_Postfix);
+    SS << ".";
+    SS << E->slotName();
+  }
+
+  void printCall(Call *E, StreamType &SS) {
+    SExpr *T = E->target();
+    if (T->opcode() == COP_Apply) {
+      self()->printApply(cast<Apply>(T), SS, true);
+      SS << ")";
+    }
+    else {
+      self()->printSExpr(T, SS, Prec_Postfix);
+      SS << "()";
+    }
+  }
+
+  void printAlloc(Alloc *E, StreamType &SS) {
+    SS << "new ";
+    self()->printSExpr(E->dataType(), SS, Prec_Other-1);
+  }
+
+  void printLoad(Load *E, StreamType &SS) {
+    self()->printSExpr(E->pointer(), SS, Prec_Postfix);
+    SS << "^";
+  }
+
+  void printStore(Store *E, StreamType &SS) {
+    self()->printSExpr(E->destination(), SS, Prec_Other-1);
+    SS << " := ";
+    self()->printSExpr(E->source(), SS, Prec_Other-1);
+  }
+
+  void printArrayIndex(ArrayIndex *E, StreamType &SS) {
+    self()->printSExpr(E->array(), SS, Prec_Postfix);
+    SS << "[";
+    self()->printSExpr(E->index(), SS, Prec_MAX);
+    SS << "]";
+  }
+
+  void printArrayAdd(ArrayAdd *E, StreamType &SS) {
+    self()->printSExpr(E->array(), SS, Prec_Postfix);
+    SS << " + ";
+    self()->printSExpr(E->index(), SS, Prec_Atom);
+  }
+
+  void printUnaryOp(UnaryOp *E, StreamType &SS) {
+    SS << getUnaryOpcodeString(E->unaryOpcode());
+    self()->printSExpr(E->expr(), SS, Prec_Unary);
+  }
+
+  void printBinaryOp(BinaryOp *E, StreamType &SS) {
+    self()->printSExpr(E->expr0(), SS, Prec_Binary-1);
+    SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " ";
+    self()->printSExpr(E->expr1(), SS, Prec_Binary-1);
+  }
+
+  void printCast(Cast *E, StreamType &SS) {
+    SS << "%";
+    self()->printSExpr(E->expr(), SS, Prec_Unary);
+  }
+
+  void printSCFG(SCFG *E, StreamType &SS) {
+    SS << "CFG {\n";
+    for (auto BBI : *E) {
+      printBasicBlock(BBI, SS);
+    }
+    SS << "}";
+    newline(SS);
+  }
+
+  void printBasicBlock(BasicBlock *E, StreamType &SS) {
+    SS << "BB_" << E->blockID() << ":";
+    if (E->parent())
+      SS << " BB_" << E->parent()->blockID();
+    newline(SS);
+    for (auto *A : E->arguments()) {
+      SS << "let ";
+      self()->printVariable(A, SS, true);
+      SS << " = ";
+      self()->printSExpr(A->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    for (auto *I : E->instructions()) {
+      if (I->definition()->opcode() != COP_Store) {
+        SS << "let ";
+        self()->printVariable(I, SS, true);
+        SS << " = ";
+      }
+      self()->printSExpr(I->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    SExpr *T = E->terminator();
+    if (T) {
+      self()->printSExpr(T, SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    newline(SS);
+  }
+
+  void printPhi(Phi *E, StreamType &SS) {
+    SS << "phi(";
+    if (E->status() == Phi::PH_SingleVal)
+      self()->printSExpr(E->values()[0], SS, Prec_MAX);
+    else {
+      unsigned i = 0;
+      for (auto V : E->values()) {
+        if (i++ > 0)
+          SS << ", ";
+        self()->printSExpr(V, SS, Prec_MAX);
+      }
+    }
+    SS << ")";
+  }
+
+  void printGoto(Goto *E, StreamType &SS) {
+    SS << "goto ";
+    printBlockLabel(SS, E->targetBlock(), E->index());
+  }
+
+  void printBranch(Branch *E, StreamType &SS) {
+    SS << "branch (";
+    self()->printSExpr(E->condition(), SS, Prec_MAX);
+    SS << ") ";
+    printBlockLabel(SS, E->thenBlock(), E->thenIndex());
+    SS << " ";
+    printBlockLabel(SS, E->elseBlock(), E->elseIndex());
+  }
+
+  void printIdentifier(Identifier *E, StreamType &SS) {
+    SS << E->name();
+  }
+
+  void printIfThenElse(IfThenElse *E, StreamType &SS) {
+    SS << "if (";
+    printSExpr(E->condition(), SS, Prec_MAX);
+    SS << ") then ";
+    printSExpr(E->thenExpr(), SS, Prec_Other);
+    SS << " else ";
+    printSExpr(E->elseExpr(), SS, Prec_Other);
+  }
+
+  void printLet(Let *E, StreamType &SS) {
+    SS << "let ";
+    printVariable(E->variableDecl(), SS, true);
+    SS << " = ";
+    printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1);
+    SS << "; ";
+    printSExpr(E->body(), SS, Prec_Decl-1);
+  }
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
new file mode 100644
index 0000000..31200a3
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -0,0 +1,316 @@
+//===- ThreadSafetyUtil.h --------------------------------------*- 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 some basic utility classes for use by ThreadSafetyTIL.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_UTIL_H
+#define LLVM_CLANG_THREAD_SAFETY_UTIL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "clang/AST/ExprCXX.h"
+
+#include <cassert>
+#include <cstddef>
+#include <vector>
+#include <utility>
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Simple wrapper class to abstract away from the details of memory management.
+// SExprs are allocated in pools, and deallocated all at once.
+class MemRegionRef {
+private:
+  union AlignmentType {
+    double d;
+    void *p;
+    long double dd;
+    long long ii;
+  };
+
+public:
+  MemRegionRef() : Allocator(nullptr) {}
+  MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
+
+  void *allocate(size_t Sz) {
+    return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
+  }
+
+  template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }
+
+  template <typename T> T *allocateT(size_t NumElems) {
+    return Allocator->Allocate<T>(NumElems);
+  }
+
+private:
+  llvm::BumpPtrAllocator *Allocator;
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+
+inline void *operator new(size_t Sz,
+                          clang::threadSafety::til::MemRegionRef &R) {
+  return R.allocate(Sz);
+}
+
+
+namespace clang {
+namespace threadSafety {
+
+std::string getSourceLiteralString(const clang::Expr *CE);
+
+using llvm::StringRef;
+using clang::SourceLocation;
+
+namespace til {
+
+
+// A simple fixed size array class that does not manage its own memory,
+// suitable for use with bump pointer allocation.
+template <class T> class SimpleArray {
+public:
+  SimpleArray() : Data(nullptr), Size(0), Capacity(0) {}
+  SimpleArray(T *Dat, size_t Cp, size_t Sz = 0)
+      : Data(Dat), Size(Sz), Capacity(Cp) {}
+  SimpleArray(MemRegionRef A, size_t Cp)
+      : Data(Cp == 0 ? nullptr : A.allocateT<T>(Cp)), Size(0), Capacity(Cp) {}
+  SimpleArray(SimpleArray<T> &&A)
+      : Data(A.Data), Size(A.Size), Capacity(A.Capacity) {
+    A.Data = nullptr;
+    A.Size = 0;
+    A.Capacity = 0;
+  }
+
+  SimpleArray &operator=(SimpleArray &&RHS) {
+    if (this != &RHS) {
+      Data = RHS.Data;
+      Size = RHS.Size;
+      Capacity = RHS.Capacity;
+
+      RHS.Data = nullptr;
+      RHS.Size = RHS.Capacity = 0;
+    }
+    return *this;
+  }
+
+  // Reserve space for at least Ncp items, reallocating if necessary.
+  void reserve(size_t Ncp, MemRegionRef A) {
+    if (Ncp <= Capacity)
+      return;
+    T *Odata = Data;
+    Data = A.allocateT<T>(Ncp);
+    Capacity = Ncp;
+    memcpy(Data, Odata, sizeof(T) * Size);
+    return;
+  }
+
+  // Reserve space for at least N more items.
+  void reserveCheck(size_t N, MemRegionRef A) {
+    if (Capacity == 0)
+      reserve(u_max(InitialCapacity, N), A);
+    else if (Size + N < Capacity)
+      reserve(u_max(Size + N, Capacity * 2), A);
+  }
+
+  typedef T *iterator;
+  typedef const T *const_iterator;
+
+  size_t size() const { return Size; }
+  size_t capacity() const { return Capacity; }
+
+  T &operator[](unsigned i) {
+    assert(i < Size && "Array index out of bounds.");
+    return Data[i];
+  }
+  const T &operator[](unsigned i) const {
+    assert(i < Size && "Array index out of bounds.");
+    return Data[i];
+  }
+
+  iterator begin() { return Data; }
+  iterator end() { return Data + Size; }
+
+  const_iterator cbegin() const { return Data; }
+  const_iterator cend() const { return Data + Size; }
+
+  void push_back(const T &Elem) {
+    assert(Size < Capacity);
+    Data[Size++] = Elem;
+  }
+
+  void setValues(unsigned Sz, const T& C) {
+    assert(Sz <= Capacity);
+    Size = Sz;
+    for (unsigned i = 0; i < Sz; ++i) {
+      Data[i] = C;
+    }
+  }
+
+  template <class Iter> unsigned append(Iter I, Iter E) {
+    size_t Osz = Size;
+    size_t J = Osz;
+    for (; J < Capacity && I != E; ++J, ++I)
+      Data[J] = *I;
+    Size = J;
+    return J - Osz;
+  }
+
+private:
+  // std::max is annoying here, because it requires a reference,
+  // thus forcing InitialCapacity to be initialized outside the .h file.
+  size_t u_max(size_t i, size_t j) { return (i < j) ? j : i; }
+
+  static const size_t InitialCapacity = 4;
+
+  SimpleArray(const SimpleArray<T> &A) LLVM_DELETED_FUNCTION;
+
+  T *Data;
+  size_t Size;
+  size_t Capacity;
+};
+
+}  // end namespace til
+
+
+// A copy on write vector.
+// The vector can be in one of three states:
+// * invalid -- no operations are permitted.
+// * read-only -- read operations are permitted.
+// * writable -- read and write operations are permitted.
+// The init(), destroy(), and makeWritable() methods will change state.
+template<typename T>
+class CopyOnWriteVector {
+  class VectorData {
+  public:
+    VectorData() : NumRefs(1) { }
+    VectorData(const VectorData &VD) : NumRefs(1), Vect(VD.Vect) { }
+
+    unsigned NumRefs;
+    std::vector<T> Vect;
+  };
+
+  // No copy constructor or copy assignment.  Use clone() with move assignment.
+  CopyOnWriteVector(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+  void operator=(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+
+public:
+  CopyOnWriteVector() : Data(nullptr) {}
+  CopyOnWriteVector(CopyOnWriteVector &&V) : Data(V.Data) { V.Data = nullptr; }
+  ~CopyOnWriteVector() { destroy(); }
+
+  // Returns true if this holds a valid vector.
+  bool valid() const  { return Data; }
+
+  // Returns true if this vector is writable.
+  bool writable() const { return Data && Data->NumRefs == 1; }
+
+  // If this vector is not valid, initialize it to a valid vector.
+  void init() {
+    if (!Data) {
+      Data = new VectorData();
+    }
+  }
+
+  // Destroy this vector; thus making it invalid.
+  void destroy() {
+    if (!Data)
+      return;
+    if (Data->NumRefs <= 1)
+      delete Data;
+    else
+      --Data->NumRefs;
+    Data = nullptr;
+  }
+
+  // Make this vector writable, creating a copy if needed.
+  void makeWritable() {
+    if (!Data) {
+      Data = new VectorData();
+      return;
+    }
+    if (Data->NumRefs == 1)
+      return;   // already writeable.
+    --Data->NumRefs;
+    Data = new VectorData(*Data);
+  }
+
+  // Create a lazy copy of this vector.
+  CopyOnWriteVector clone() { return CopyOnWriteVector(Data); }
+
+  CopyOnWriteVector &operator=(CopyOnWriteVector &&V) {
+    destroy();
+    Data = V.Data;
+    V.Data = nullptr;
+    return *this;
+  }
+
+  typedef typename std::vector<T>::const_iterator const_iterator;
+
+  const std::vector<T> &elements() const { return Data->Vect; }
+
+  const_iterator begin() const { return elements().cbegin(); }
+  const_iterator end() const { return elements().cend(); }
+
+  const T& operator[](unsigned i) const { return elements()[i]; }
+
+  unsigned size() const { return Data ? elements().size() : 0; }
+
+  // Return true if V and this vector refer to the same data.
+  bool sameAs(const CopyOnWriteVector &V) const { return Data == V.Data; }
+
+  // Clear vector.  The vector must be writable.
+  void clear() {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.clear();
+  }
+
+  // Push a new element onto the end.  The vector must be writable.
+  void push_back(const T &Elem) {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.push_back(Elem);
+  }
+
+  // Gets a mutable reference to the element at index(i).
+  // The vector must be writable.
+  T& elem(unsigned i) {
+    assert(writable() && "Vector is not writable!");
+    return Data->Vect[i];
+  }
+
+  // Drops elements from the back until the vector has size i.
+  void downsize(unsigned i) {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.erase(Data->Vect.begin() + i, Data->Vect.end());
+  }
+
+private:
+  CopyOnWriteVector(VectorData *D) : Data(D) {
+    if (!Data)
+      return;
+    ++Data->NumRefs;
+  }
+
+  VectorData *Data;
+};
+
+
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_UTIL_H
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
new file mode 100644
index 0000000..188722d
--- /dev/null
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -0,0 +1,126 @@
+//= UninitializedValues.h - Finding uses of uninitialized values -*- 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 APIs for invoking and reported uninitialized values
+// warnings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNINIT_VALS_H
+#define LLVM_CLANG_UNINIT_VALS_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class AnalysisDeclContext;
+class CFG;
+class DeclContext;
+class Expr;
+class VarDecl;
+
+/// A use of a variable, which might be uninitialized.
+class UninitUse {
+public:
+  struct Branch {
+    const Stmt *Terminator;
+    unsigned Output;
+  };
+
+private:
+  /// The expression which uses this variable.
+  const Expr *User;
+
+  /// Is this use uninitialized whenever the function is called?
+  bool UninitAfterCall;
+
+  /// Is this use uninitialized whenever the variable declaration is reached?
+  bool UninitAfterDecl;
+
+  /// Does this use always see an uninitialized value?
+  bool AlwaysUninit;
+
+  /// This use is always uninitialized if it occurs after any of these branches
+  /// is taken.
+  SmallVector<Branch, 2> UninitBranches;
+
+public:
+  UninitUse(const Expr *User, bool AlwaysUninit)
+      : User(User), UninitAfterCall(false), UninitAfterDecl(false),
+        AlwaysUninit(AlwaysUninit) {}
+
+  void addUninitBranch(Branch B) {
+    UninitBranches.push_back(B);
+  }
+
+  void setUninitAfterCall() { UninitAfterCall = true; }
+  void setUninitAfterDecl() { UninitAfterDecl = true; }
+
+  /// Get the expression containing the uninitialized use.
+  const Expr *getUser() const { return User; }
+
+  /// The kind of uninitialized use.
+  enum Kind {
+    /// The use might be uninitialized.
+    Maybe,
+    /// The use is uninitialized whenever a certain branch is taken.
+    Sometimes,
+    /// The use is uninitialized the first time it is reached after we reach
+    /// the variable's declaration.
+    AfterDecl,
+    /// The use is uninitialized the first time it is reached after the function
+    /// is called.
+    AfterCall,
+    /// The use is always uninitialized.
+    Always
+  };
+
+  /// Get the kind of uninitialized use.
+  Kind getKind() const {
+    return AlwaysUninit ? Always :
+           UninitAfterCall ? AfterCall :
+           UninitAfterDecl ? AfterDecl :
+           !branch_empty() ? Sometimes : Maybe;
+  }
+
+  typedef SmallVectorImpl<Branch>::const_iterator branch_iterator;
+  /// Branches which inevitably result in the variable being used uninitialized.
+  branch_iterator branch_begin() const { return UninitBranches.begin(); }
+  branch_iterator branch_end() const { return UninitBranches.end(); }
+  bool branch_empty() const { return UninitBranches.empty(); }
+};
+
+class UninitVariablesHandler {
+public:
+  UninitVariablesHandler() {}
+  virtual ~UninitVariablesHandler();
+
+  /// Called when the uninitialized variable is used at the given expression.
+  virtual void handleUseOfUninitVariable(const VarDecl *vd,
+                                         const UninitUse &use) {}
+
+  /// Called when the uninitialized variable analysis detects the
+  /// idiom 'int x = x'.  All other uses of 'x' within the initializer
+  /// are handled by handleUseOfUninitVariable.
+  virtual void handleSelfInit(const VarDecl *vd) {}
+};
+
+struct UninitVariablesAnalysisStats {
+  unsigned NumVariablesAnalyzed;
+  unsigned NumBlockVisits;
+};
+
+void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
+                                       AnalysisDeclContext &ac,
+                                       UninitVariablesHandler &handler,
+                                       UninitVariablesAnalysisStats &stats);
+
+}
+#endif
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
new file mode 100644
index 0000000..08e3354
--- /dev/null
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -0,0 +1,466 @@
+//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisDeclContext, a class that manages the analysis
+// context data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+
+namespace clang {
+
+class Stmt;
+class CFGReverseBlockReachabilityAnalysis;
+class CFGStmtMap;
+class LiveVariables;
+class ManagedAnalysis;
+class ParentMap;
+class PseudoConstantAnalysis;
+class LocationContextManager;
+class StackFrameContext;
+class BlockInvocationContext;
+class AnalysisDeclContextManager;
+class LocationContext;
+
+namespace idx { class TranslationUnit; }
+
+/// The base class of a hierarchy of objects representing analyses tied
+/// to AnalysisDeclContext.
+class ManagedAnalysis {
+protected:
+  ManagedAnalysis() {}
+public:
+  virtual ~ManagedAnalysis();
+
+  // Subclasses need to implement:
+  //
+  //  static const void *getTag();
+  //
+  // Which returns a fixed pointer address to distinguish classes of
+  // analysis objects.  They also need to implement:
+  //
+  //  static [Derived*] create(AnalysisDeclContext &Ctx);
+  //
+  // which creates the analysis object given an AnalysisDeclContext.
+};
+
+
+/// AnalysisDeclContext contains the context data for the function or method
+/// under analysis.
+class AnalysisDeclContext {
+  /// Backpoint to the AnalysisManager object that created this
+  /// AnalysisDeclContext. This may be null.
+  AnalysisDeclContextManager *Manager;
+
+  const Decl * const D;
+
+  std::unique_ptr<CFG> cfg, completeCFG;
+  std::unique_ptr<CFGStmtMap> cfgStmtMap;
+
+  CFG::BuildOptions cfgBuildOptions;
+  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
+
+  bool builtCFG, builtCompleteCFG;
+  std::unique_ptr<ParentMap> PM;
+  std::unique_ptr<PseudoConstantAnalysis> PCA;
+  std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
+
+  llvm::BumpPtrAllocator A;
+
+  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+
+  void *ManagedAnalyses;
+
+public:
+  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
+                  const Decl *D);
+
+  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
+                  const Decl *D,
+                  const CFG::BuildOptions &BuildOptions);
+
+  ~AnalysisDeclContext();
+
+  ASTContext &getASTContext() const { return D->getASTContext(); }
+  const Decl *getDecl() const { return D; }
+
+  /// Return the AnalysisDeclContextManager (if any) that created
+  /// this AnalysisDeclContext.
+  AnalysisDeclContextManager *getManager() const {
+    return Manager;
+  }
+  
+  /// Return the build options used to construct the CFG.
+  CFG::BuildOptions &getCFGBuildOptions() {
+    return cfgBuildOptions;
+  }
+
+  const CFG::BuildOptions &getCFGBuildOptions() const {
+    return cfgBuildOptions;
+  }
+
+  /// getAddEHEdges - Return true iff we are adding exceptional edges from
+  /// callExprs.  If this is false, then try/catch statements and blocks
+  /// reachable from them can appear to be dead in the CFG, analysis passes must
+  /// cope with that.
+  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
+  bool getUseUnoptimizedCFG() const {
+      return !cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
+  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
+
+  void registerForcedBlockExpression(const Stmt *stmt);
+  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
+
+  /// \brief Get the body of the Declaration.
+  Stmt *getBody() const;
+
+  /// \brief Get the body of the Declaration.
+  /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
+  ///             by the BodyFarm.
+  Stmt *getBody(bool &IsAutosynthesized) const;
+
+  /// \brief Checks if the body of the Decl is generated by the BodyFarm.
+  ///
+  /// Note, the lookup is not free. We are going to call getBody behind
+  /// the scenes.
+  /// \sa getBody
+  bool isBodyAutosynthesized() const;
+
+  CFG *getCFG();
+
+  CFGStmtMap *getCFGStmtMap();
+
+  CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
+
+  /// Return a version of the CFG without any edges pruned.
+  CFG *getUnoptimizedCFG();
+
+  void dumpCFG(bool ShowColors);
+
+  /// \brief Returns true if we have built a CFG for this analysis context.
+  /// Note that this doesn't correspond to whether or not a valid CFG exists, it
+  /// corresponds to whether we *attempted* to build one.
+  bool isCFGBuilt() const { return builtCFG; }
+
+  ParentMap &getParentMap();
+  PseudoConstantAnalysis *getPseudoConstantAnalysis();
+
+  typedef const VarDecl * const * referenced_decls_iterator;
+
+  std::pair<referenced_decls_iterator, referenced_decls_iterator>
+    getReferencedBlockVars(const BlockDecl *BD);
+
+  /// Return the ImplicitParamDecl* associated with 'self' if this
+  /// AnalysisDeclContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
+  const ImplicitParamDecl *getSelfDecl() const;
+
+  const StackFrameContext *getStackFrame(LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx);
+  
+  const BlockInvocationContext *
+  getBlockInvocationContext(const LocationContext *parent,
+                            const BlockDecl *BD,
+                            const void *ContextData);
+
+  /// Return the specified analysis object, lazily running the analysis if
+  /// necessary.  Return NULL if the analysis could not run.
+  template <typename T>
+  T *getAnalysis() {
+    const void *tag = T::getTag();
+    ManagedAnalysis *&data = getAnalysisImpl(tag);
+    if (!data) {
+      data = T::create(*this);
+    }
+    return static_cast<T*>(data);
+  }
+private:
+  ManagedAnalysis *&getAnalysisImpl(const void* tag);
+
+  LocationContextManager &getLocationContextManager();
+};
+
+class LocationContext : public llvm::FoldingSetNode {
+public:
+  enum ContextKind { StackFrame, Scope, Block };
+
+private:
+  ContextKind Kind;
+
+  // AnalysisDeclContext can't be const since some methods may modify its
+  // member.
+  AnalysisDeclContext *Ctx;
+
+  const LocationContext *Parent;
+
+protected:
+  LocationContext(ContextKind k, AnalysisDeclContext *ctx,
+                  const LocationContext *parent)
+    : Kind(k), Ctx(ctx), Parent(parent) {}
+
+public:
+  virtual ~LocationContext();
+
+  ContextKind getKind() const { return Kind; }
+
+  AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
+
+  const LocationContext *getParent() const { return Parent; }
+
+  bool isParentOf(const LocationContext *LC) const;
+
+  const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
+
+  CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
+
+  template <typename T>
+  T *getAnalysis() const {
+    return getAnalysisDeclContext()->getAnalysis<T>();
+  }
+
+  ParentMap &getParentMap() const {
+    return getAnalysisDeclContext()->getParentMap();
+  }
+
+  const ImplicitParamDecl *getSelfDecl() const {
+    return Ctx->getSelfDecl();
+  }
+
+  const StackFrameContext *getCurrentStackFrame() const;
+
+  /// Return true if the current LocationContext has no caller context.
+  virtual bool inTopFrame() const;
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+
+  void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
+  void dumpStack() const;
+
+public:
+  static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+                            ContextKind ck,
+                            AnalysisDeclContext *ctx,
+                            const LocationContext *parent,
+                            const void *data);
+};
+
+class StackFrameContext : public LocationContext {
+  // The callsite where this stack frame is established.
+  const Stmt *CallSite;
+
+  // The parent block of the callsite.
+  const CFGBlock *Block;
+
+  // The index of the callsite in the CFGBlock.
+  unsigned Index;
+
+  friend class LocationContextManager;
+  StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
+                    const Stmt *s, const CFGBlock *blk,
+                    unsigned idx)
+    : LocationContext(StackFrame, ctx, parent), CallSite(s),
+      Block(blk), Index(idx) {}
+
+public:
+  ~StackFrameContext() {}
+
+  const Stmt *getCallSite() const { return CallSite; }
+
+  const CFGBlock *getCallSiteBlock() const { return Block; }
+
+  /// Return true if the current LocationContext has no caller context.
+  bool inTopFrame() const override { return getParent() == nullptr;  }
+
+  unsigned getIndex() const { return Index; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const Stmt *s,
+                      const CFGBlock *blk, unsigned idx) {
+    ProfileCommon(ID, StackFrame, ctx, parent, s);
+    ID.AddPointer(blk);
+    ID.AddInteger(idx);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == StackFrame;
+  }
+};
+
+class ScopeContext : public LocationContext {
+  const Stmt *Enter;
+
+  friend class LocationContextManager;
+  ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
+               const Stmt *s)
+    : LocationContext(Scope, ctx, parent), Enter(s) {}
+
+public:
+  ~ScopeContext() {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const Stmt *s) {
+    ProfileCommon(ID, Scope, ctx, parent, s);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == Scope;
+  }
+};
+
+class BlockInvocationContext : public LocationContext {
+  const BlockDecl *BD;
+  
+  // FIXME: Come up with a more type-safe way to model context-sensitivity.
+  const void *ContextData;
+
+  friend class LocationContextManager;
+
+  BlockInvocationContext(AnalysisDeclContext *ctx,
+                         const LocationContext *parent,
+                         const BlockDecl *bd, const void *contextData)
+    : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
+
+public:
+  ~BlockInvocationContext() {}
+
+  const BlockDecl *getBlockDecl() const { return BD; }
+  
+  const void *getContextData() const { return ContextData; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const BlockDecl *bd,
+                      const void *contextData) {
+    ProfileCommon(ID, Block, ctx, parent, bd);
+    ID.AddPointer(contextData);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == Block;
+  }
+};
+
+class LocationContextManager {
+  llvm::FoldingSet<LocationContext> Contexts;
+public:
+  ~LocationContextManager();
+
+  const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
+                                         const LocationContext *parent,
+                                         const Stmt *s,
+                                         const CFGBlock *blk, unsigned idx);
+
+  const ScopeContext *getScope(AnalysisDeclContext *ctx,
+                               const LocationContext *parent,
+                               const Stmt *s);
+  
+  const BlockInvocationContext *
+  getBlockInvocationContext(AnalysisDeclContext *ctx,
+                            const LocationContext *parent,
+                            const BlockDecl *BD,
+                            const void *ContextData);
+
+  /// Discard all previously created LocationContext objects.
+  void clear();
+private:
+  template <typename LOC, typename DATA>
+  const LOC *getLocationContext(AnalysisDeclContext *ctx,
+                                const LocationContext *parent,
+                                const DATA *d);
+};
+
+class AnalysisDeclContextManager {
+  typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
+
+  ContextMap Contexts;
+  LocationContextManager LocContexts;
+  CFG::BuildOptions cfgBuildOptions;
+  
+  /// Flag to indicate whether or not bodies should be synthesized
+  /// for well-known functions.
+  bool SynthesizeBodies;
+
+public:
+  AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
+                             bool addImplicitDtors = false,
+                             bool addInitializers = false,
+                             bool addTemporaryDtors = false,
+                             bool synthesizeBodies = false,
+                             bool addStaticInitBranches = false,
+                             bool addCXXNewAllocator = true);
+
+  ~AnalysisDeclContextManager();
+
+  AnalysisDeclContext *getContext(const Decl *D);
+
+  bool getUseUnoptimizedCFG() const {
+    return !cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+
+  CFG::BuildOptions &getCFGBuildOptions() {
+    return cfgBuildOptions;
+  }
+  
+  /// Return true if faux bodies should be synthesized for well-known
+  /// functions.
+  bool synthesizeBodies() const { return SynthesizeBodies; }
+
+  const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
+  }
+
+  // Get the top level stack frame.
+  const StackFrameContext *getStackFrame(const Decl *D) {
+    return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
+                                     0);
+  }
+
+  // Get a stack frame with parent.
+  StackFrameContext const *getStackFrame(const Decl *D,
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
+  }
+
+  /// Discard all previously created AnalysisDeclContexts.
+  void clear();
+
+private:
+  friend class AnalysisDeclContext;
+
+  LocationContextManager &getLocationContextManager() {
+    return LocContexts;
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
new file mode 100644
index 0000000..33c940e
--- /dev/null
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICANALYSIS_H
+#define LLVM_CLANG_DIAGNOSTICANALYSIS_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define ANALYSISSTART
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
new file mode 100644
index 0000000..891fb90
--- /dev/null
+++ b/include/clang/Analysis/CFG.h
@@ -0,0 +1,1114 @@
+//===--- CFG.h - Classes for representing and building CFGs------*- 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 CFG and CFGBuilder classes for representing and
+//  building Control-Flow Graphs (CFGs) from ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CFG_H
+#define LLVM_CLANG_CFG_H
+
+#include "clang/AST/Stmt.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+#include <bitset>
+#include <cassert>
+#include <iterator>
+#include <memory>
+
+namespace clang {
+  class CXXDestructorDecl;
+  class Decl;
+  class Stmt;
+  class Expr;
+  class FieldDecl;
+  class VarDecl;
+  class CXXCtorInitializer;
+  class CXXBaseSpecifier;
+  class CXXBindTemporaryExpr;
+  class CFG;
+  class PrinterHelper;
+  class LangOptions;
+  class ASTContext;
+  class CXXRecordDecl;
+  class CXXDeleteExpr;
+  class CXXNewExpr;
+  class BinaryOperator;
+
+/// CFGElement - Represents a top-level expression in a basic block.
+class CFGElement {
+public:
+  enum Kind {
+    // main kind
+    Statement,
+    Initializer,
+    NewAllocator,
+    // dtor kind
+    AutomaticObjectDtor,
+    DeleteDtor,
+    BaseDtor,
+    MemberDtor,
+    TemporaryDtor,
+    DTOR_BEGIN = AutomaticObjectDtor,
+    DTOR_END = TemporaryDtor
+  };
+
+protected:
+  // The int bits are used to mark the kind.
+  llvm::PointerIntPair<void *, 2> Data1;
+  llvm::PointerIntPair<void *, 2> Data2;
+
+  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
+    : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
+      Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
+    assert(getKind() == kind);
+  }
+
+  CFGElement() {}
+public:
+
+  /// \brief Convert to the specified CFGElement type, asserting that this
+  /// CFGElement is of the desired type.
+  template<typename T>
+  T castAs() const {
+    assert(T::isKind(*this));
+    T t;
+    CFGElement& e = t;
+    e = *this;
+    return t;
+  }
+
+  /// \brief Convert to the specified CFGElement type, returning None if this
+  /// CFGElement is not of the desired type.
+  template<typename T>
+  Optional<T> getAs() const {
+    if (!T::isKind(*this))
+      return None;
+    T t;
+    CFGElement& e = t;
+    e = *this;
+    return t;
+  }
+
+  Kind getKind() const {
+    unsigned x = Data2.getInt();
+    x <<= 2;
+    x |= Data1.getInt();
+    return (Kind) x;
+  }
+};
+
+class CFGStmt : public CFGElement {
+public:
+  CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
+
+  const Stmt *getStmt() const {
+    return static_cast<const Stmt *>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGStmt() {}
+  static bool isKind(const CFGElement &E) {
+    return E.getKind() == Statement;
+  }
+};
+
+/// CFGInitializer - Represents C++ base or member initializer from
+/// constructor's initialization list.
+class CFGInitializer : public CFGElement {
+public:
+  CFGInitializer(CXXCtorInitializer *initializer)
+      : CFGElement(Initializer, initializer) {}
+
+  CXXCtorInitializer* getInitializer() const {
+    return static_cast<CXXCtorInitializer*>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGInitializer() {}
+  static bool isKind(const CFGElement &E) {
+    return E.getKind() == Initializer;
+  }
+};
+
+/// CFGNewAllocator - Represents C++ allocator call.
+class CFGNewAllocator : public CFGElement {
+public:
+  explicit CFGNewAllocator(const CXXNewExpr *S)
+    : CFGElement(NewAllocator, S) {}
+
+  // Get the new expression.
+  const CXXNewExpr *getAllocatorExpr() const {
+    return static_cast<CXXNewExpr *>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGNewAllocator() {}
+  static bool isKind(const CFGElement &elem) {
+    return elem.getKind() == NewAllocator;
+  }
+};
+
+/// CFGImplicitDtor - Represents C++ object destructor implicitly generated
+/// by compiler on various occasions.
+class CFGImplicitDtor : public CFGElement {
+protected:
+  CFGImplicitDtor() {}
+  CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
+    : CFGElement(kind, data1, data2) {
+    assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
+  }
+
+public:
+  const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
+  bool isNoReturn(ASTContext &astContext) const;
+
+private:
+  friend class CFGElement;
+  static bool isKind(const CFGElement &E) {
+    Kind kind = E.getKind();
+    return kind >= DTOR_BEGIN && kind <= DTOR_END;
+  }
+};
+
+/// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated
+/// for automatic object or temporary bound to const reference at the point
+/// of leaving its local scope.
+class CFGAutomaticObjDtor: public CFGImplicitDtor {
+public:
+  CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
+      : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {}
+
+  const VarDecl *getVarDecl() const {
+    return static_cast<VarDecl*>(Data1.getPointer());
+  }
+
+  // Get statement end of which triggered the destructor call.
+  const Stmt *getTriggerStmt() const {
+    return static_cast<Stmt*>(Data2.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGAutomaticObjDtor() {}
+  static bool isKind(const CFGElement &elem) {
+    return elem.getKind() == AutomaticObjectDtor;
+  }
+};
+
+/// CFGDeleteDtor - Represents C++ object destructor generated
+/// from a call to delete.
+class CFGDeleteDtor : public CFGImplicitDtor {
+public:
+  CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
+      : CFGImplicitDtor(DeleteDtor, RD, DE) {}
+
+  const CXXRecordDecl *getCXXRecordDecl() const {
+    return static_cast<CXXRecordDecl*>(Data1.getPointer());
+  }
+
+  // Get Delete expression which triggered the destructor call.
+  const CXXDeleteExpr *getDeleteExpr() const {
+    return static_cast<CXXDeleteExpr *>(Data2.getPointer());
+  }
+
+
+private:
+  friend class CFGElement;
+  CFGDeleteDtor() {}
+  static bool isKind(const CFGElement &elem) {
+    return elem.getKind() == DeleteDtor;
+  }
+};
+
+/// CFGBaseDtor - Represents C++ object destructor implicitly generated for
+/// base object in destructor.
+class CFGBaseDtor : public CFGImplicitDtor {
+public:
+  CFGBaseDtor(const CXXBaseSpecifier *base)
+      : CFGImplicitDtor(BaseDtor, base) {}
+
+  const CXXBaseSpecifier *getBaseSpecifier() const {
+    return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGBaseDtor() {}
+  static bool isKind(const CFGElement &E) {
+    return E.getKind() == BaseDtor;
+  }
+};
+
+/// CFGMemberDtor - Represents C++ object destructor implicitly generated for
+/// member object in destructor.
+class CFGMemberDtor : public CFGImplicitDtor {
+public:
+  CFGMemberDtor(const FieldDecl *field)
+      : CFGImplicitDtor(MemberDtor, field, nullptr) {}
+
+  const FieldDecl *getFieldDecl() const {
+    return static_cast<const FieldDecl*>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGMemberDtor() {}
+  static bool isKind(const CFGElement &E) {
+    return E.getKind() == MemberDtor;
+  }
+};
+
+/// CFGTemporaryDtor - Represents C++ object destructor implicitly generated
+/// at the end of full expression for temporary object.
+class CFGTemporaryDtor : public CFGImplicitDtor {
+public:
+  CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
+      : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
+
+  const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
+    return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGTemporaryDtor() {}
+  static bool isKind(const CFGElement &E) {
+    return E.getKind() == TemporaryDtor;
+  }
+};
+
+/// CFGTerminator - Represents CFGBlock terminator statement.
+///
+/// TemporaryDtorsBranch bit is set to true if the terminator marks a branch
+/// in control flow of destructors of temporaries. In this case terminator
+/// statement is the same statement that branches control flow in evaluation
+/// of matching full expression.
+class CFGTerminator {
+  llvm::PointerIntPair<Stmt *, 1> Data;
+public:
+  CFGTerminator() {}
+  CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
+      : Data(S, TemporaryDtorsBranch) {}
+
+  Stmt *getStmt() { return Data.getPointer(); }
+  const Stmt *getStmt() const { return Data.getPointer(); }
+
+  bool isTemporaryDtorsBranch() const { return Data.getInt(); }
+
+  operator Stmt *() { return getStmt(); }
+  operator const Stmt *() const { return getStmt(); }
+
+  Stmt *operator->() { return getStmt(); }
+  const Stmt *operator->() const { return getStmt(); }
+
+  Stmt &operator*() { return *getStmt(); }
+  const Stmt &operator*() const { return *getStmt(); }
+
+  LLVM_EXPLICIT operator bool() const { return getStmt(); }
+};
+
+/// CFGBlock - Represents a single basic block in a source-level CFG.
+///  It consists of:
+///
+///  (1) A set of statements/expressions (which may contain subexpressions).
+///  (2) A "terminator" statement (not in the set of statements).
+///  (3) A list of successors and predecessors.
+///
+/// Terminator: The terminator represents the type of control-flow that occurs
+/// at the end of the basic block.  The terminator is a Stmt* referring to an
+/// AST node that has control-flow: if-statements, breaks, loops, etc.
+/// If the control-flow is conditional, the condition expression will appear
+/// within the set of statements in the block (usually the last statement).
+///
+/// Predecessors: the order in the set of predecessors is arbitrary.
+///
+/// Successors: the order in the set of successors is NOT arbitrary.  We
+///  currently have the following orderings based on the terminator:
+///
+///     Terminator       Successor Ordering
+///  -----------------------------------------------------
+///       if            Then Block;  Else Block
+///     ? operator      LHS expression;  RHS expression
+///     &&, ||          expression that uses result of && or ||, RHS
+///
+/// But note that any of that may be NULL in case of optimized-out edges.
+///
+class CFGBlock {
+  class ElementList {
+    typedef BumpVector<CFGElement> ImplTy;
+    ImplTy Impl;
+  public:
+    ElementList(BumpVectorContext &C) : Impl(C, 4) {}
+
+    typedef std::reverse_iterator<ImplTy::iterator>       iterator;
+    typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
+    typedef ImplTy::iterator                              reverse_iterator;
+    typedef ImplTy::const_iterator                       const_reverse_iterator;
+    typedef ImplTy::const_reference                       const_reference;
+
+    void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
+    reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
+        BumpVectorContext &C) {
+      return Impl.insert(I, Cnt, E, C);
+    }
+
+    const_reference front() const { return Impl.back(); }
+    const_reference back() const { return Impl.front(); }
+
+    iterator begin() { return Impl.rbegin(); }
+    iterator end() { return Impl.rend(); }
+    const_iterator begin() const { return Impl.rbegin(); }
+    const_iterator end() const { return Impl.rend(); }
+    reverse_iterator rbegin() { return Impl.begin(); }
+    reverse_iterator rend() { return Impl.end(); }
+    const_reverse_iterator rbegin() const { return Impl.begin(); }
+    const_reverse_iterator rend() const { return Impl.end(); }
+
+   CFGElement operator[](size_t i) const  {
+     assert(i < Impl.size());
+     return Impl[Impl.size() - 1 - i];
+   }
+
+    size_t size() const { return Impl.size(); }
+    bool empty() const { return Impl.empty(); }
+  };
+
+  /// Stmts - The set of statements in the basic block.
+  ElementList Elements;
+
+  /// Label - An (optional) label that prefixes the executable
+  ///  statements in the block.  When this variable is non-NULL, it is
+  ///  either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
+  Stmt *Label;
+
+  /// Terminator - The terminator for a basic block that
+  ///  indicates the type of control-flow that occurs between a block
+  ///  and its successors.
+  CFGTerminator Terminator;
+
+  /// LoopTarget - Some blocks are used to represent the "loop edge" to
+  ///  the start of a loop from within the loop body.  This Stmt* will be
+  ///  refer to the loop statement for such blocks (and be null otherwise).
+  const Stmt *LoopTarget;
+
+  /// BlockID - A numerical ID assigned to a CFGBlock during construction
+  ///   of the CFG.
+  unsigned BlockID;
+
+public:
+  /// This class represents a potential adjacent block in the CFG.  It encodes
+  /// whether or not the block is actually reachable, or can be proved to be
+  /// trivially unreachable.  For some cases it allows one to encode scenarios
+  /// where a block was substituted because the original (now alternate) block
+  /// is unreachable.
+  class AdjacentBlock {
+    enum Kind {
+      AB_Normal,
+      AB_Unreachable,
+      AB_Alternate
+    };
+
+    CFGBlock *ReachableBlock;
+    llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
+
+  public:
+    /// Construct an AdjacentBlock with a possibly unreachable block.
+    AdjacentBlock(CFGBlock *B, bool IsReachable);
+    
+    /// Construct an AdjacentBlock with a reachable block and an alternate
+    /// unreachable block.
+    AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
+
+    /// Get the reachable block, if one exists.
+    CFGBlock *getReachableBlock() const {
+      return ReachableBlock;
+    }
+
+    /// Get the potentially unreachable block.
+    CFGBlock *getPossiblyUnreachableBlock() const {
+      return UnreachableBlock.getPointer();
+    }
+
+    /// Provide an implicit conversion to CFGBlock* so that
+    /// AdjacentBlock can be substituted for CFGBlock*.
+    operator CFGBlock*() const {
+      return getReachableBlock();
+    }
+
+    CFGBlock& operator *() const {
+      return *getReachableBlock();
+    }
+
+    CFGBlock* operator ->() const {
+      return getReachableBlock();
+    }
+
+    bool isReachable() const {
+      Kind K = (Kind) UnreachableBlock.getInt();
+      return K == AB_Normal || K == AB_Alternate;
+    }
+  };
+
+private:
+  /// Predecessors/Successors - Keep track of the predecessor / successor
+  /// CFG blocks.
+  typedef BumpVector<AdjacentBlock> AdjacentBlocks;
+  AdjacentBlocks Preds;
+  AdjacentBlocks Succs;
+
+  /// NoReturn - This bit is set when the basic block contains a function call
+  /// or implicit destructor that is attributed as 'noreturn'. In that case,
+  /// control cannot technically ever proceed past this block. All such blocks
+  /// will have a single immediate successor: the exit block. This allows them
+  /// to be easily reached from the exit block and using this bit quickly
+  /// recognized without scanning the contents of the block.
+  ///
+  /// Optimization Note: This bit could be profitably folded with Terminator's
+  /// storage if the memory usage of CFGBlock becomes an issue.
+  unsigned HasNoReturnElement : 1;
+
+  /// Parent - The parent CFG that owns this CFGBlock.
+  CFG *Parent;
+
+public:
+  explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
+    : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), 
+      BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
+      Parent(parent) {}
+  ~CFGBlock() {}
+
+  // Statement iterators
+  typedef ElementList::iterator                      iterator;
+  typedef ElementList::const_iterator                const_iterator;
+  typedef ElementList::reverse_iterator              reverse_iterator;
+  typedef ElementList::const_reverse_iterator        const_reverse_iterator;
+
+  CFGElement                 front()       const { return Elements.front();   }
+  CFGElement                 back()        const { return Elements.back();    }
+
+  iterator                   begin()             { return Elements.begin();   }
+  iterator                   end()               { return Elements.end();     }
+  const_iterator             begin()       const { return Elements.begin();   }
+  const_iterator             end()         const { return Elements.end();     }
+
+  reverse_iterator           rbegin()            { return Elements.rbegin();  }
+  reverse_iterator           rend()              { return Elements.rend();    }
+  const_reverse_iterator     rbegin()      const { return Elements.rbegin();  }
+  const_reverse_iterator     rend()        const { return Elements.rend();    }
+
+  unsigned                   size()        const { return Elements.size();    }
+  bool                       empty()       const { return Elements.empty();   }
+
+  CFGElement operator[](size_t i) const  { return Elements[i]; }
+
+  // CFG iterators
+  typedef AdjacentBlocks::iterator                              pred_iterator;
+  typedef AdjacentBlocks::const_iterator                  const_pred_iterator;
+  typedef AdjacentBlocks::reverse_iterator              pred_reverse_iterator;
+  typedef AdjacentBlocks::const_reverse_iterator  const_pred_reverse_iterator;
+
+  typedef AdjacentBlocks::iterator                              succ_iterator;
+  typedef AdjacentBlocks::const_iterator                  const_succ_iterator;
+  typedef AdjacentBlocks::reverse_iterator              succ_reverse_iterator;
+  typedef AdjacentBlocks::const_reverse_iterator  const_succ_reverse_iterator;
+
+  pred_iterator                pred_begin()        { return Preds.begin();   }
+  pred_iterator                pred_end()          { return Preds.end();     }
+  const_pred_iterator          pred_begin()  const { return Preds.begin();   }
+  const_pred_iterator          pred_end()    const { return Preds.end();     }
+
+  pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
+  pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
+  const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
+  const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
+
+  succ_iterator                succ_begin()        { return Succs.begin();   }
+  succ_iterator                succ_end()          { return Succs.end();     }
+  const_succ_iterator          succ_begin()  const { return Succs.begin();   }
+  const_succ_iterator          succ_end()    const { return Succs.end();     }
+
+  succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
+  succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
+  const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
+  const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
+
+  unsigned                     succ_size()   const { return Succs.size();    }
+  bool                         succ_empty()  const { return Succs.empty();   }
+
+  unsigned                     pred_size()   const { return Preds.size();    }
+  bool                         pred_empty()  const { return Preds.empty();   }
+
+
+  class FilterOptions {
+  public:
+    FilterOptions() {
+      IgnoreNullPredecessors = 1;
+      IgnoreDefaultsWithCoveredEnums = 0;
+    }
+
+    unsigned IgnoreNullPredecessors : 1;
+    unsigned IgnoreDefaultsWithCoveredEnums : 1;
+  };
+
+  static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
+       const CFGBlock *Dst);
+
+  template <typename IMPL, bool IsPred>
+  class FilteredCFGBlockIterator {
+  private:
+    IMPL I, E;
+    const FilterOptions F;
+    const CFGBlock *From;
+  public:
+    explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
+                                      const CFGBlock *from,
+                                      const FilterOptions &f)
+        : I(i), E(e), F(f), From(from) {
+      while (hasMore() && Filter(*I))
+        ++I;
+    }
+
+    bool hasMore() const { return I != E; }
+
+    FilteredCFGBlockIterator &operator++() {
+      do { ++I; } while (hasMore() && Filter(*I));
+      return *this;
+    }
+
+    const CFGBlock *operator*() const { return *I; }
+  private:
+    bool Filter(const CFGBlock *To) {
+      return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
+    }
+  };
+
+  typedef FilteredCFGBlockIterator<const_pred_iterator, true>
+          filtered_pred_iterator;
+
+  typedef FilteredCFGBlockIterator<const_succ_iterator, false>
+          filtered_succ_iterator;
+
+  filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
+    return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
+  }
+
+  filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const {
+    return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
+  }
+
+  // Manipulation of block contents
+
+  void setTerminator(CFGTerminator Term) { Terminator = Term; }
+  void setLabel(Stmt *Statement) { Label = Statement; }
+  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
+  void setHasNoReturnElement() { HasNoReturnElement = true; }
+
+  CFGTerminator getTerminator() { return Terminator; }
+  const CFGTerminator getTerminator() const { return Terminator; }
+
+  Stmt *getTerminatorCondition(bool StripParens = true);
+
+  const Stmt *getTerminatorCondition(bool StripParens = true) const {
+    return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
+  }
+
+  const Stmt *getLoopTarget() const { return LoopTarget; }
+
+  Stmt *getLabel() { return Label; }
+  const Stmt *getLabel() const { return Label; }
+
+  bool hasNoReturnElement() const { return HasNoReturnElement; }
+
+  unsigned getBlockID() const { return BlockID; }
+
+  CFG *getParent() const { return Parent; }
+
+  void dump() const;
+
+  void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
+  void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
+             bool ShowColors) const;
+  void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
+  void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
+    OS << "BB#" << getBlockID();
+  }
+
+  /// Adds a (potentially unreachable) successor block to the current block.
+  void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
+
+  void appendStmt(Stmt *statement, BumpVectorContext &C) {
+    Elements.push_back(CFGStmt(statement), C);
+  }
+
+  void appendInitializer(CXXCtorInitializer *initializer,
+                        BumpVectorContext &C) {
+    Elements.push_back(CFGInitializer(initializer), C);
+  }
+
+  void appendNewAllocator(CXXNewExpr *NE,
+                          BumpVectorContext &C) {
+    Elements.push_back(CFGNewAllocator(NE), C);
+  }
+
+  void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
+    Elements.push_back(CFGBaseDtor(BS), C);
+  }
+
+  void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) {
+    Elements.push_back(CFGMemberDtor(FD), C);
+  }
+
+  void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) {
+    Elements.push_back(CFGTemporaryDtor(E), C);
+  }
+
+  void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
+    Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
+  }
+
+  void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
+    Elements.push_back(CFGDeleteDtor(RD, DE), C);
+  }
+
+  // Destructors must be inserted in reversed order. So insertion is in two
+  // steps. First we prepare space for some number of elements, then we insert
+  // the elements beginning at the last position in prepared space.
+  iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
+      BumpVectorContext &C) {
+    return iterator(Elements.insert(I.base(), Cnt,
+                                    CFGAutomaticObjDtor(nullptr, 0), C));
+  }
+  iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
+    *I = CFGAutomaticObjDtor(VD, S);
+    return ++I;
+  }
+};
+
+/// \brief CFGCallback defines methods that should be called when a logical
+/// operator error is found when building the CFG.
+class CFGCallback {
+public:
+  CFGCallback() {}
+  virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
+  virtual void compareBitwiseEquality(const BinaryOperator *B,
+                                      bool isAlwaysTrue) {}
+  virtual ~CFGCallback() {}
+};
+
+/// CFG - Represents a source-level, intra-procedural CFG that represents the
+///  control-flow of a Stmt.  The Stmt can represent an entire function body,
+///  or a single expression.  A CFG will always contain one empty block that
+///  represents the Exit point of the CFG.  A CFG will also contain a designated
+///  Entry block.  The CFG solely represents control-flow; it consists of
+///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
+///  was constructed from.
+class CFG {
+public:
+  //===--------------------------------------------------------------------===//
+  // CFG Construction & Manipulation.
+  //===--------------------------------------------------------------------===//
+
+  class BuildOptions {
+    std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
+  public:
+    typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
+    ForcedBlkExprs **forcedBlkExprs;
+    CFGCallback *Observer;
+    bool PruneTriviallyFalseEdges;
+    bool AddEHEdges;
+    bool AddInitializers;
+    bool AddImplicitDtors;
+    bool AddTemporaryDtors;
+    bool AddStaticInitBranches;
+    bool AddCXXNewAllocator;
+
+    bool alwaysAdd(const Stmt *stmt) const {
+      return alwaysAddMask[stmt->getStmtClass()];
+    }
+
+    BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
+      alwaysAddMask[stmtClass] = val;
+      return *this;
+    }
+
+    BuildOptions &setAllAlwaysAdd() {
+      alwaysAddMask.set();
+      return *this;
+    }
+
+    BuildOptions()
+      : forcedBlkExprs(nullptr), Observer(nullptr),
+        PruneTriviallyFalseEdges(true), AddEHEdges(false),
+        AddInitializers(false), AddImplicitDtors(false),
+        AddTemporaryDtors(false), AddStaticInitBranches(false),
+        AddCXXNewAllocator(false) {}
+  };
+
+  /// \brief Provides a custom implementation of the iterator class to have the
+  /// same interface as Function::iterator - iterator returns CFGBlock
+  /// (not a pointer to CFGBlock).
+  class graph_iterator {
+  public:
+    typedef const CFGBlock                  value_type;
+    typedef value_type&                     reference;
+    typedef value_type*                     pointer;
+    typedef BumpVector<CFGBlock*>::iterator ImplTy;
+
+    graph_iterator(const ImplTy &i) : I(i) {}
+
+    bool operator==(const graph_iterator &X) const { return I == X.I; }
+    bool operator!=(const graph_iterator &X) const { return I != X.I; }
+
+    reference operator*()    const { return **I; }
+    pointer operator->()     const { return  *I; }
+    operator CFGBlock* ()          { return  *I; }
+
+    graph_iterator &operator++() { ++I; return *this; }
+    graph_iterator &operator--() { --I; return *this; }
+
+  private:
+    ImplTy I;
+  };
+
+  class const_graph_iterator {
+  public:
+    typedef const CFGBlock                  value_type;
+    typedef value_type&                     reference;
+    typedef value_type*                     pointer;
+    typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
+
+    const_graph_iterator(const ImplTy &i) : I(i) {}
+
+    bool operator==(const const_graph_iterator &X) const { return I == X.I; }
+    bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
+
+    reference operator*() const { return **I; }
+    pointer operator->()  const { return  *I; }
+    operator CFGBlock* () const { return  *I; }
+
+    const_graph_iterator &operator++() { ++I; return *this; }
+    const_graph_iterator &operator--() { --I; return *this; }
+
+  private:
+    ImplTy I;
+  };
+
+  /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
+  ///   constructed CFG belongs to the caller.
+  static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
+                       const BuildOptions &BO);
+
+  /// createBlock - Create a new block in the CFG.  The CFG owns the block;
+  ///  the caller should not directly free it.
+  CFGBlock *createBlock();
+
+  /// setEntry - Set the entry block of the CFG.  This is typically used
+  ///  only during CFG construction.  Most CFG clients expect that the
+  ///  entry block has no predecessors and contains no statements.
+  void setEntry(CFGBlock *B) { Entry = B; }
+
+  /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
+  ///  This is typically used only during CFG construction.
+  void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
+
+  //===--------------------------------------------------------------------===//
+  // Block Iterators
+  //===--------------------------------------------------------------------===//
+
+  typedef BumpVector<CFGBlock*>                    CFGBlockListTy;
+  typedef CFGBlockListTy::iterator                 iterator;
+  typedef CFGBlockListTy::const_iterator           const_iterator;
+  typedef std::reverse_iterator<iterator>          reverse_iterator;
+  typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
+
+  CFGBlock &                front()                { return *Blocks.front(); }
+  CFGBlock &                back()                 { return *Blocks.back(); }
+
+  iterator                  begin()                { return Blocks.begin(); }
+  iterator                  end()                  { return Blocks.end(); }
+  const_iterator            begin()       const    { return Blocks.begin(); }
+  const_iterator            end()         const    { return Blocks.end(); }
+
+  graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
+  graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
+  const_graph_iterator nodes_begin() const {
+    return const_graph_iterator(Blocks.begin());
+  }
+  const_graph_iterator nodes_end() const {
+    return const_graph_iterator(Blocks.end());
+  }
+
+  reverse_iterator          rbegin()               { return Blocks.rbegin(); }
+  reverse_iterator          rend()                 { return Blocks.rend(); }
+  const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
+  const_reverse_iterator    rend()        const    { return Blocks.rend(); }
+
+  CFGBlock &                getEntry()             { return *Entry; }
+  const CFGBlock &          getEntry()    const    { return *Entry; }
+  CFGBlock &                getExit()              { return *Exit; }
+  const CFGBlock &          getExit()     const    { return *Exit; }
+
+  CFGBlock *       getIndirectGotoBlock() { return IndirectGotoBlock; }
+  const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
+
+  typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
+  try_block_iterator try_blocks_begin() const {
+    return TryDispatchBlocks.begin();
+  }
+  try_block_iterator try_blocks_end() const {
+    return TryDispatchBlocks.end();
+  }
+
+  void addTryDispatchBlock(const CFGBlock *block) {
+    TryDispatchBlocks.push_back(block);
+  }
+
+  /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
+  ///
+  /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
+  /// multiple decls.
+  void addSyntheticDeclStmt(const DeclStmt *Synthetic,
+                            const DeclStmt *Source) {
+    assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
+    assert(Synthetic != Source && "Don't include original DeclStmts in map");
+    assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
+    SyntheticDeclStmts[Synthetic] = Source;
+  }
+
+  typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
+    synthetic_stmt_iterator;
+
+  /// Iterates over synthetic DeclStmts in the CFG.
+  ///
+  /// Each element is a (synthetic statement, source statement) pair.
+  ///
+  /// \sa addSyntheticDeclStmt
+  synthetic_stmt_iterator synthetic_stmt_begin() const {
+    return SyntheticDeclStmts.begin();
+  }
+
+  /// \sa synthetic_stmt_begin
+  synthetic_stmt_iterator synthetic_stmt_end() const {
+    return SyntheticDeclStmts.end();
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Member templates useful for various batch operations over CFGs.
+  //===--------------------------------------------------------------------===//
+
+  template <typename CALLBACK>
+  void VisitBlockStmts(CALLBACK& O) const {
+    for (const_iterator I=begin(), E=end(); I != E; ++I)
+      for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
+           BI != BE; ++BI) {
+        if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
+          O(const_cast<Stmt*>(stmt->getStmt()));
+      }
+  }
+
+  //===--------------------------------------------------------------------===//
+  // CFG Introspection.
+  //===--------------------------------------------------------------------===//
+
+  /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
+  /// start at 0).
+  unsigned getNumBlockIDs() const { return NumBlockIDs; }
+
+  /// size - Return the total number of CFGBlocks within the CFG
+  /// This is simply a renaming of the getNumBlockIDs(). This is necessary 
+  /// because the dominator implementation needs such an interface.
+  unsigned size() const { return NumBlockIDs; }
+
+  //===--------------------------------------------------------------------===//
+  // CFG Debugging: Pretty-Printing and Visualization.
+  //===--------------------------------------------------------------------===//
+
+  void viewCFG(const LangOptions &LO) const;
+  void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
+  void dump(const LangOptions &LO, bool ShowColors) const;
+
+  //===--------------------------------------------------------------------===//
+  // Internal: constructors and data.
+  //===--------------------------------------------------------------------===//
+
+  CFG()
+    : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
+      Blocks(BlkBVC, 10) {}
+
+  llvm::BumpPtrAllocator& getAllocator() {
+    return BlkBVC.getAllocator();
+  }
+
+  BumpVectorContext &getBumpVectorContext() {
+    return BlkBVC;
+  }
+
+private:
+  CFGBlock *Entry;
+  CFGBlock *Exit;
+  CFGBlock* IndirectGotoBlock;  // Special block to contain collective dispatch
+                                // for indirect gotos
+  unsigned  NumBlockIDs;
+
+  BumpVectorContext BlkBVC;
+
+  CFGBlockListTy Blocks;
+
+  /// C++ 'try' statements are modeled with an indirect dispatch block.
+  /// This is the collection of such blocks present in the CFG.
+  std::vector<const CFGBlock *> TryDispatchBlocks;
+
+  /// Collects DeclStmts synthesized for this CFG and maps each one back to its
+  /// source DeclStmt.
+  llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
+};
+} // end namespace clang
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
+/// CFGTerminator to a specific Stmt class.
+template <> struct simplify_type< ::clang::CFGTerminator> {
+  typedef ::clang::Stmt *SimpleType;
+  static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
+    return Val.getStmt();
+  }
+};
+
+// Traits for: CFGBlock
+
+template <> struct GraphTraits< ::clang::CFGBlock *> {
+  typedef ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
+
+  static NodeType* getEntryNode(::clang::CFGBlock *BB)
+  { return BB; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->succ_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->succ_end(); }
+};
+
+template <> struct GraphTraits< const ::clang::CFGBlock *> {
+  typedef const ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
+
+  static NodeType* getEntryNode(const clang::CFGBlock *BB)
+  { return BB; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->succ_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->succ_end(); }
+};
+
+template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
+  typedef ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
+  { return G.Graph; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->pred_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->pred_end(); }
+};
+
+template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
+  typedef const ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
+  { return G.Graph; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->pred_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->pred_end(); }
+};
+
+// Traits for: CFG
+
+template <> struct GraphTraits< ::clang::CFG* >
+    : public GraphTraits< ::clang::CFGBlock *>  {
+
+  typedef ::clang::CFG::graph_iterator nodes_iterator;
+
+  static NodeType     *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
+  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
+  static nodes_iterator   nodes_end(::clang::CFG* F) { return F->nodes_end(); }
+  static unsigned              size(::clang::CFG* F) { return F->size(); }
+};
+
+template <> struct GraphTraits<const ::clang::CFG* >
+    : public GraphTraits<const ::clang::CFGBlock *>  {
+
+  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
+
+  static NodeType *getEntryNode( const ::clang::CFG* F) {
+    return &F->getEntry();
+  }
+  static nodes_iterator nodes_begin( const ::clang::CFG* F) {
+    return F->nodes_begin();
+  }
+  static nodes_iterator nodes_end( const ::clang::CFG* F) {
+    return F->nodes_end();
+  }
+  static unsigned size(const ::clang::CFG* F) {
+    return F->size();
+  }
+};
+
+template <> struct GraphTraits<Inverse< ::clang::CFG*> >
+  : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
+
+  typedef ::clang::CFG::graph_iterator nodes_iterator;
+
+  static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
+  static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
+  static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
+};
+
+template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
+  : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
+
+  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
+
+  static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
+  static nodes_iterator nodes_begin(const ::clang::CFG* F) {
+    return F->nodes_begin();
+  }
+  static nodes_iterator nodes_end(const ::clang::CFG* F) {
+    return F->nodes_end();
+  }
+};
+} // end llvm namespace
+#endif
diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h
new file mode 100644
index 0000000..6e8e140
--- /dev/null
+++ b/include/clang/Analysis/CFGStmtMap.h
@@ -0,0 +1,52 @@
+//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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 CFGStmtMap class, which defines a mapping from
+//  Stmt* to CFGBlock*
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CFGSTMTMAP_H
+#define LLVM_CLANG_CFGSTMTMAP_H
+
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+
+class CFG;
+class CFGBlock;
+class ParentMap;
+class Stmt;
+
+class CFGStmtMap {
+  ParentMap *PM;
+  void *M;
+  
+  CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}
+  
+public:
+  ~CFGStmtMap();
+  
+  /// Returns a new CFGMap for the given CFG.  It is the caller's
+  /// responsibility to 'delete' this object when done using it.
+  static CFGStmtMap *Build(CFG* C, ParentMap *PM);
+
+  /// Returns the CFGBlock the specified Stmt* appears in.  For Stmt* that
+  /// are terminators, the CFGBlock is the block they appear as a terminator,
+  /// and not the block they appear as a block-level expression (e.g, '&&').
+  /// CaseStmts and LabelStmts map to the CFGBlock they label.
+  CFGBlock *getBlock(Stmt * S);
+
+  const CFGBlock *getBlock(const Stmt * S) const {
+    return const_cast<CFGStmtMap*>(this)->getBlock(const_cast<Stmt*>(S));
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
new file mode 100644
index 0000000..593ba57
--- /dev/null
+++ b/include/clang/Analysis/CallGraph.h
@@ -0,0 +1,253 @@
+//== CallGraph.h - AST-based Call graph  ------------------------*- 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 AST-based CallGraph.
+//
+//  A call graph for functions whose definitions/bodies are available in the
+//  current translation unit. The graph has a "virtual" root node that contains
+//  edges to all externally available functions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CALLGRAPH
+#define LLVM_CLANG_ANALYSIS_CALLGRAPH
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+class CallGraphNode;
+
+/// \brief The AST-based call graph.
+///
+/// The call graph extends itself with the given declarations by implementing
+/// the recursive AST visitor, which constructs the graph by visiting the given
+/// declarations.
+class CallGraph : public RecursiveASTVisitor<CallGraph> {
+  friend class CallGraphNode;
+
+  typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
+
+  /// FunctionMap owns all CallGraphNodes.
+  FunctionMapTy FunctionMap;
+
+  /// This is a virtual root node that has edges to all the functions.
+  CallGraphNode *Root;
+
+public:
+  CallGraph();
+  ~CallGraph();
+
+  /// \brief Populate the call graph with the functions in the given
+  /// declaration.
+  ///
+  /// Recursively walks the declaration to find all the dependent Decls as well.
+  void addToCallGraph(Decl *D) {
+    TraverseDecl(D);
+  }
+
+  /// \brief Determine if a declaration should be included in the graph.
+  static bool includeInGraph(const Decl *D);
+
+  /// \brief Lookup the node for the given declaration.
+  CallGraphNode *getNode(const Decl *) const;
+
+  /// \brief Lookup the node for the given declaration. If none found, insert
+  /// one into the graph.
+  CallGraphNode *getOrInsertNode(Decl *);
+
+  /// Iterators through all the elements in the graph. Note, this gives
+  /// non-deterministic order.
+  typedef FunctionMapTy::iterator iterator;
+  typedef FunctionMapTy::const_iterator const_iterator;
+  iterator begin() { return FunctionMap.begin(); }
+  iterator end()   { return FunctionMap.end();   }
+  const_iterator begin() const { return FunctionMap.begin(); }
+  const_iterator end()   const { return FunctionMap.end();   }
+
+  /// \brief Get the number of nodes in the graph.
+  unsigned size() const { return FunctionMap.size(); }
+
+  /// \ brief Get the virtual root of the graph, all the functions available
+  /// externally are represented as callees of the node.
+  CallGraphNode *getRoot() const { return Root; }
+
+  /// Iterators through all the nodes of the graph that have no parent. These
+  /// are the unreachable nodes, which are either unused or are due to us
+  /// failing to add a call edge due to the analysis imprecision.
+  typedef llvm::SetVector<CallGraphNode *>::iterator nodes_iterator;
+  typedef llvm::SetVector<CallGraphNode *>::const_iterator const_nodes_iterator;
+
+  void print(raw_ostream &os) const;
+  void dump() const;
+  void viewGraph() const;
+
+  void addNodesForBlocks(DeclContext *D);
+
+  /// Part of recursive declaration visitation. We recursively visit all the
+  /// declarations to collect the root functions.
+  bool VisitFunctionDecl(FunctionDecl *FD) {
+    // We skip function template definitions, as their semantics is
+    // only determined when they are instantiated.
+    if (includeInGraph(FD)) {
+      // Add all blocks declared inside this function to the graph.
+      addNodesForBlocks(FD);
+      // If this function has external linkage, anything could call it.
+      // Note, we are not precise here. For example, the function could have
+      // its address taken.
+      addNodeForDecl(FD, FD->isGlobal());
+    }
+    return true;
+  }
+
+  /// Part of recursive declaration visitation.
+  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+    if (includeInGraph(MD)) {
+      addNodesForBlocks(MD);
+      addNodeForDecl(MD, true);
+    }
+    return true;
+  }
+
+  // We are only collecting the declarations, so do not step into the bodies.
+  bool TraverseStmt(Stmt *S) { return true; }
+
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+private:
+  /// \brief Add the given declaration to the call graph.
+  void addNodeForDecl(Decl *D, bool IsGlobal);
+
+  /// \brief Allocate a new node in the graph.
+  CallGraphNode *allocateNewNode(Decl *);
+};
+
+class CallGraphNode {
+public:
+  typedef CallGraphNode* CallRecord;
+
+private:
+  /// \brief The function/method declaration.
+  Decl *FD;
+
+  /// \brief The list of functions called from this node.
+  SmallVector<CallRecord, 5> CalledFunctions;
+
+public:
+  CallGraphNode(Decl *D) : FD(D) {}
+
+  typedef SmallVectorImpl<CallRecord>::iterator iterator;
+  typedef SmallVectorImpl<CallRecord>::const_iterator const_iterator;
+
+  /// Iterators through all the callees/children of the node.
+  inline iterator begin() { return CalledFunctions.begin(); }
+  inline iterator end()   { return CalledFunctions.end(); }
+  inline const_iterator begin() const { return CalledFunctions.begin(); }
+  inline const_iterator end()   const { return CalledFunctions.end();   }
+
+  inline bool empty() const {return CalledFunctions.empty(); }
+  inline unsigned size() const {return CalledFunctions.size(); }
+
+  void addCallee(CallGraphNode *N, CallGraph *CG) {
+    CalledFunctions.push_back(N);
+  }
+
+  Decl *getDecl() const { return FD; }
+
+  void print(raw_ostream &os) const;
+  void dump() const;
+};
+
+} // end clang namespace
+
+// Graph traits for iteration, viewing.
+namespace llvm {
+template <> struct GraphTraits<clang::CallGraphNode*> {
+  typedef clang::CallGraphNode NodeType;
+  typedef clang::CallGraphNode::CallRecord CallRecordTy;
+  typedef std::pointer_to_unary_function<CallRecordTy,
+                                         clang::CallGraphNode*> CGNDerefFun;
+  static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; }
+  typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+  }
+  static inline ChildIteratorType child_end  (NodeType *N) {
+    return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+  }
+  static clang::CallGraphNode *CGNDeref(CallRecordTy P) {
+    return P;
+  }
+};
+
+template <> struct GraphTraits<const clang::CallGraphNode*> {
+  typedef const clang::CallGraphNode NodeType;
+  typedef NodeType::const_iterator ChildIteratorType;
+  static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; }
+  static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+  static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+
+template <> struct GraphTraits<clang::CallGraph*>
+  : public GraphTraits<clang::CallGraphNode*> {
+
+  static NodeType *getEntryNode(clang::CallGraph *CGN) {
+    return CGN->getRoot();  // Start at the external node!
+  }
+  typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
+  typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
+
+  static nodes_iterator nodes_begin(clang::CallGraph *CG) {
+    return map_iterator(CG->begin(), DerefFun(CGdereference));
+  }
+  static nodes_iterator nodes_end  (clang::CallGraph *CG) {
+    return map_iterator(CG->end(), DerefFun(CGdereference));
+  }
+  static clang::CallGraphNode &CGdereference(PairTy P) {
+    return *(P.second);
+  }
+
+  static unsigned size(clang::CallGraph *CG) {
+    return CG->size();
+  }
+};
+
+template <> struct GraphTraits<const clang::CallGraph*> :
+  public GraphTraits<const clang::CallGraphNode*> {
+  static NodeType *getEntryNode(const clang::CallGraph *CGN) {
+    return CGN->getRoot();
+  }
+  typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
+  typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef mapped_iterator<clang::CallGraph::const_iterator,
+                          DerefFun> nodes_iterator;
+
+  static nodes_iterator nodes_begin(const clang::CallGraph *CG) {
+    return map_iterator(CG->begin(), DerefFun(CGdereference));
+  }
+  static nodes_iterator nodes_end(const clang::CallGraph *CG) {
+    return map_iterator(CG->end(), DerefFun(CGdereference));
+  }
+  static clang::CallGraphNode &CGdereference(PairTy P) {
+    return *(P.second);
+  }
+
+  static unsigned size(const clang::CallGraph *CG) {
+    return CG->size();
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
new file mode 100644
index 0000000..e6a2f13
--- /dev/null
+++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
@@ -0,0 +1,42 @@
+//===- CocoaConventions.h - Special handling of Cocoa conventions -*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements cocoa naming convention analysis. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_DS_COCOA
+#define LLVM_CLANG_ANALYSIS_DS_COCOA
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+class FunctionDecl;
+class QualType;
+  
+namespace ento {
+namespace cocoa {
+  
+  bool isRefType(QualType RetTy, StringRef Prefix,
+                 StringRef Name = StringRef());
+    
+  bool isCocoaObjectRef(QualType T);
+
+}
+
+namespace coreFoundation {
+  bool isCFObjectRef(QualType T);
+  
+  bool followsCreateRule(const FunctionDecl *FD);
+}
+
+}} // end: "clang:ento"
+
+#endif
diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
new file mode 100644
index 0000000..930c2bd
--- /dev/null
+++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
@@ -0,0 +1,46 @@
+//= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- C++ -*---//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements special handling of recognizing ObjC API hooks that
+// do not return but aren't marked as such in API headers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
+#define LLVM_CLANG_ANALYSIS_DS_OBJCNORETURN
+
+#include "clang/Basic/IdentifierTable.h"
+
+namespace clang {
+
+class ASTContext;
+class ObjCMessageExpr;
+  
+class ObjCNoReturn {
+  /// Cached "raise" selector.
+  Selector RaiseSel;
+
+  /// Cached identifier for "NSException".
+  IdentifierInfo *NSExceptionII;
+
+  enum { NUM_RAISE_SELECTORS = 2 };
+
+  /// Cached set of selectors in NSException that are 'noreturn'.
+  Selector NSExceptionInstanceRaiseSelectors[NUM_RAISE_SELECTORS];
+
+public:
+  ObjCNoReturn(ASTContext &C);
+  
+  /// Return true if the given message expression is known to never
+  /// return.
+  bool isImplicitNoReturn(const ObjCMessageExpr *ME);
+};
+}
+
+#endif
diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h
new file mode 100644
index 0000000..f86b2b0
--- /dev/null
+++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -0,0 +1,172 @@
+//===--- DataflowValues.h - Data structure for dataflow values --*- 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 skeleton data structure for encapsulating the dataflow
+// values for a CFG.  Typically this is subclassed to provide methods for
+// computing these values from a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
+#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
+
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "llvm/ADT/DenseMap.h"
+
+//===----------------------------------------------------------------------===//
+/// Dataflow Directional Tag Classes.  These are used for tag dispatching
+///  within the dataflow solver/transfer functions to determine what direction
+///  a dataflow analysis flows.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+namespace dataflow {
+  struct forward_analysis_tag {};
+  struct backward_analysis_tag {};
+} // end namespace dataflow
+
+//===----------------------------------------------------------------------===//
+/// DataflowValues.  Container class to store dataflow values for a CFG.
+//===----------------------------------------------------------------------===//
+
+template <typename ValueTypes,
+          typename _AnalysisDirTag = dataflow::forward_analysis_tag >
+class DataflowValues {
+
+  //===--------------------------------------------------------------------===//
+  // Type declarations.
+  //===--------------------------------------------------------------------===//
+
+public:
+  typedef typename ValueTypes::ValTy               ValTy;
+  typedef typename ValueTypes::AnalysisDataTy      AnalysisDataTy;
+  typedef _AnalysisDirTag                          AnalysisDirTag;
+  typedef llvm::DenseMap<ProgramPoint, ValTy>      EdgeDataMapTy;
+  typedef llvm::DenseMap<const CFGBlock*, ValTy>   BlockDataMapTy;
+  typedef llvm::DenseMap<const Stmt*, ValTy>       StmtDataMapTy;
+
+  //===--------------------------------------------------------------------===//
+  // Predicates.
+  //===--------------------------------------------------------------------===//
+
+public:
+  /// isForwardAnalysis - Returns true if the dataflow values are computed
+  ///  from a forward analysis.
+  bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); }
+
+  /// isBackwardAnalysis - Returns true if the dataflow values are computed
+  ///  from a backward analysis.
+  bool isBackwardAnalysis() { return !isForwardAnalysis(); }
+
+private:
+  bool isForwardAnalysis(dataflow::forward_analysis_tag)  { return true; }
+  bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; }
+
+  //===--------------------------------------------------------------------===//
+  // Initialization and accessors methods.
+  //===--------------------------------------------------------------------===//
+
+public:
+  DataflowValues() : StmtDataMap(NULL) {}
+  ~DataflowValues() { delete StmtDataMap; }
+
+  /// InitializeValues - Invoked by the solver to initialize state needed for
+  ///  dataflow analysis.  This method is usually specialized by subclasses.
+  void InitializeValues(const CFG& cfg) {}
+
+
+  /// getEdgeData - Retrieves the dataflow values associated with a
+  ///  CFG edge.
+  ValTy& getEdgeData(const BlockEdge &E) {
+    typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
+    assert (I != EdgeDataMap.end() && "No data associated with Edge.");
+    return I->second;
+  }
+
+  const ValTy& getEdgeData(const BlockEdge &E) const {
+    return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
+  }
+
+  /// getBlockData - Retrieves the dataflow values associated with a
+  ///  specified CFGBlock.  If the dataflow analysis is a forward analysis,
+  ///  this data is associated with the END of the block.  If the analysis
+  ///  is a backwards analysis, it is associated with the ENTRY of the block.
+  ValTy& getBlockData(const CFGBlock *B) {
+    typename BlockDataMapTy::iterator I = BlockDataMap.find(B);
+    assert (I != BlockDataMap.end() && "No data associated with block.");
+    return I->second;
+  }
+
+  const ValTy& getBlockData(const CFGBlock *B) const {
+    return const_cast<DataflowValues*>(this)->getBlockData(B);
+  }
+
+  /// getStmtData - Retrieves the dataflow values associated with a
+  ///  specified Stmt.  If the dataflow analysis is a forward analysis,
+  ///  this data corresponds to the point immediately before a Stmt.
+  ///  If the analysis is a backwards analysis, it is associated with
+  ///  the point after a Stmt.  This data is only computed for block-level
+  ///  expressions, and only when requested when the analysis is executed.
+  ValTy& getStmtData(const Stmt *S) {
+    assert (StmtDataMap && "Dataflow values were not computed for statements.");
+    typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
+    assert (I != StmtDataMap->end() && "No data associated with statement.");
+    return I->second;
+  }
+
+  const ValTy& getStmtData(const Stmt *S) const {
+    return const_cast<DataflowValues*>(this)->getStmtData(S);
+  }
+
+  /// getEdgeDataMap - Retrieves the internal map between CFG edges and
+  ///  dataflow values.  Usually used by a dataflow solver to compute
+  ///  values for blocks.
+  EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; }
+  const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; }
+
+  /// getBlockDataMap - Retrieves the internal map between CFGBlocks and
+  /// dataflow values.  If the dataflow analysis operates in the forward
+  /// direction, the values correspond to the dataflow values at the start
+  /// of the block.  Otherwise, for a backward analysis, the values correpsond
+  /// to the dataflow values at the end of the block.
+  BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
+  const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
+
+  /// getStmtDataMap - Retrieves the internal map between Stmts and
+  /// dataflow values.
+  StmtDataMapTy& getStmtDataMap() {
+    if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
+    return *StmtDataMap;
+  }
+
+  const StmtDataMapTy& getStmtDataMap() const {
+    return const_cast<DataflowValues*>(this)->getStmtDataMap();
+  }
+
+  /// getAnalysisData - Retrieves the meta data associated with a
+  ///  dataflow analysis for analyzing a particular CFG.
+  ///  This is typically consumed by transfer function code (via the solver).
+  ///  This can also be used by subclasses to interpret the dataflow values.
+  AnalysisDataTy& getAnalysisData() { return AnalysisData; }
+  const AnalysisDataTy& getAnalysisData() const { return AnalysisData; }
+
+  //===--------------------------------------------------------------------===//
+  // Internal data.
+  //===--------------------------------------------------------------------===//
+
+protected:
+  EdgeDataMapTy      EdgeDataMap;
+  BlockDataMapTy     BlockDataMap;
+  StmtDataMapTy*     StmtDataMap;
+  AnalysisDataTy     AnalysisData;
+};
+
+} // end namespace clang
+#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
new file mode 100644
index 0000000..57324d0
--- /dev/null
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -0,0 +1,705 @@
+//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- 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 interface ProgramPoint, which identifies a
+//  distinct location in a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+#define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <string>
+#include <utility>
+
+namespace clang {
+
+class AnalysisDeclContext;
+class FunctionDecl;
+class LocationContext;
+class ProgramPointTag;
+  
+class ProgramPoint {
+public:
+  enum Kind { BlockEdgeKind,
+              BlockEntranceKind,
+              BlockExitKind,
+              PreStmtKind,
+              PreStmtPurgeDeadSymbolsKind,
+              PostStmtPurgeDeadSymbolsKind,
+              PostStmtKind,
+              PreLoadKind,
+              PostLoadKind,
+              PreStoreKind,
+              PostStoreKind,
+              PostConditionKind,
+              PostLValueKind,
+              MinPostStmtKind = PostStmtKind,
+              MaxPostStmtKind = PostLValueKind,
+              PostInitializerKind,
+              CallEnterKind,
+              CallExitBeginKind,
+              CallExitEndKind,
+              PreImplicitCallKind,
+              PostImplicitCallKind,
+              MinImplicitCallKind = PreImplicitCallKind,
+              MaxImplicitCallKind = PostImplicitCallKind,
+              EpsilonKind};
+
+private:
+  const void *Data1;
+  llvm::PointerIntPair<const void *, 2, unsigned> Data2;
+
+  // The LocationContext could be NULL to allow ProgramPoint to be used in
+  // context insensitive analysis.
+  llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
+
+  llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
+
+protected:
+  ProgramPoint() {}
+  ProgramPoint(const void *P,
+               Kind k,
+               const LocationContext *l,
+               const ProgramPointTag *tag = nullptr)
+    : Data1(P),
+      Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
+      L(l, (((unsigned) k) >> 2) & 0x3),
+      Tag(tag, (((unsigned) k) >> 4) & 0x3) {
+        assert(getKind() == k);
+        assert(getLocationContext() == l);
+        assert(getData1() == P);
+      }
+        
+  ProgramPoint(const void *P1,
+               const void *P2,
+               Kind k,
+               const LocationContext *l,
+               const ProgramPointTag *tag = nullptr)
+    : Data1(P1),
+      Data2(P2, (((unsigned) k) >> 0) & 0x3),
+      L(l, (((unsigned) k) >> 2) & 0x3),
+      Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
+
+protected:
+  const void *getData1() const { return Data1; }
+  const void *getData2() const { return Data2.getPointer(); }
+  void setData2(const void *d) { Data2.setPointer(d); }
+
+public:
+  /// Create a new ProgramPoint object that is the same as the original
+  /// except for using the specified tag value.
+  ProgramPoint withTag(const ProgramPointTag *tag) const {
+    return ProgramPoint(getData1(), getData2(), getKind(),
+                        getLocationContext(), tag);
+  }
+
+  /// \brief Convert to the specified ProgramPoint type, asserting that this
+  /// ProgramPoint is of the desired type.
+  template<typename T>
+  T castAs() const {
+    assert(T::isKind(*this));
+    T t;
+    ProgramPoint& PP = t;
+    PP = *this;
+    return t;
+  }
+
+  /// \brief Convert to the specified ProgramPoint type, returning None if this
+  /// ProgramPoint is not of the desired type.
+  template<typename T>
+  Optional<T> getAs() const {
+    if (!T::isKind(*this))
+      return None;
+    T t;
+    ProgramPoint& PP = t;
+    PP = *this;
+    return t;
+  }
+
+  Kind getKind() const {
+    unsigned x = Tag.getInt();
+    x <<= 2;
+    x |= L.getInt();
+    x <<= 2;
+    x |= Data2.getInt();
+    return (Kind) x;
+  }
+
+  /// \brief Is this a program point corresponding to purge/removal of dead
+  /// symbols and bindings.
+  bool isPurgeKind() {
+    Kind K = getKind();
+    return (K == PostStmtPurgeDeadSymbolsKind ||
+            K == PreStmtPurgeDeadSymbolsKind);
+  }
+
+  const ProgramPointTag *getTag() const { return Tag.getPointer(); }
+
+  const LocationContext *getLocationContext() const {
+    return L.getPointer();
+  }
+
+  // For use with DenseMap.  This hash is probably slow.
+  unsigned getHashValue() const {
+    llvm::FoldingSetNodeID ID;
+    Profile(ID);
+    return ID.ComputeHash();
+  }
+
+  bool operator==(const ProgramPoint & RHS) const {
+    return Data1 == RHS.Data1 &&
+           Data2 == RHS.Data2 &&
+           L == RHS.L &&
+           Tag == RHS.Tag;
+  }
+
+  bool operator!=(const ProgramPoint &RHS) const {
+    return Data1 != RHS.Data1 ||
+           Data2 != RHS.Data2 ||
+           L != RHS.L ||
+           Tag != RHS.Tag;
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) getKind());
+    ID.AddPointer(getData1());
+    ID.AddPointer(getData2());
+    ID.AddPointer(getLocationContext());
+    ID.AddPointer(getTag());
+  }
+
+  static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
+                                      const LocationContext *LC,
+                                      const ProgramPointTag *tag);
+};
+
+class BlockEntrance : public ProgramPoint {
+public:
+  BlockEntrance(const CFGBlock *B, const LocationContext *L,
+                const ProgramPointTag *tag = nullptr)
+    : ProgramPoint(B, BlockEntranceKind, L, tag) {    
+    assert(B && "BlockEntrance requires non-null block");
+  }
+
+  const CFGBlock *getBlock() const {
+    return reinterpret_cast<const CFGBlock*>(getData1());
+  }
+
+  Optional<CFGElement> getFirstElement() const {
+    const CFGBlock *B = getBlock();
+    return B->empty() ? Optional<CFGElement>() : B->front();
+  }
+  
+private:
+  friend class ProgramPoint;
+  BlockEntrance() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockEntranceKind;
+  }
+};
+
+class BlockExit : public ProgramPoint {
+public:
+  BlockExit(const CFGBlock *B, const LocationContext *L)
+    : ProgramPoint(B, BlockExitKind, L) {}
+
+  const CFGBlock *getBlock() const {
+    return reinterpret_cast<const CFGBlock*>(getData1());
+  }
+
+  const Stmt *getTerminator() const {
+    return getBlock()->getTerminator();
+  }
+
+private:
+  friend class ProgramPoint;
+  BlockExit() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockExitKind;
+  }
+};
+
+class StmtPoint : public ProgramPoint {
+public:
+  StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
+            const ProgramPointTag *tag)
+    : ProgramPoint(S, p2, k, L, tag) {
+    assert(S);
+  }
+
+  const Stmt *getStmt() const { return (const Stmt*) getData1(); }
+
+  template <typename T>
+  const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
+
+protected:
+  StmtPoint() {}
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    unsigned k = Location.getKind();
+    return k >= PreStmtKind && k <= MaxPostStmtKind;
+  }
+};
+
+
+class PreStmt : public StmtPoint {
+public:
+  PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
+          const Stmt *SubStmt = nullptr)
+    : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
+
+  const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
+
+private:
+  friend class ProgramPoint;
+  PreStmt() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreStmtKind;
+  }
+};
+
+class PostStmt : public StmtPoint {
+protected:
+  PostStmt() {}
+  PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
+           const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, data, k, L, tag) {}
+
+public:
+  explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L,
+                    const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, k, L, tag) {}
+
+  explicit PostStmt(const Stmt *S, const LocationContext *L,
+                    const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
+
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    unsigned k = Location.getKind();
+    return k >= MinPostStmtKind && k <= MaxPostStmtKind;
+  }
+};
+
+// PostCondition represents the post program point of a branch condition.
+class PostCondition : public PostStmt {
+public:
+  PostCondition(const Stmt *S, const LocationContext *L,
+                const ProgramPointTag *tag = nullptr)
+    : PostStmt(S, PostConditionKind, L, tag) {}
+
+private:
+  friend class ProgramPoint;
+  PostCondition() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostConditionKind;
+  }
+};
+
+class LocationCheck : public StmtPoint {
+protected:
+  LocationCheck() {}
+  LocationCheck(const Stmt *S, const LocationContext *L,
+                ProgramPoint::Kind K, const ProgramPointTag *tag)
+    : StmtPoint(S, nullptr, K, L, tag) {}
+    
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &location) {
+    unsigned k = location.getKind();
+    return k == PreLoadKind || k == PreStoreKind;
+  }
+};
+  
+class PreLoad : public LocationCheck {
+public:
+  PreLoad(const Stmt *S, const LocationContext *L,
+          const ProgramPointTag *tag = nullptr)
+    : LocationCheck(S, L, PreLoadKind, tag) {}
+  
+private:
+  friend class ProgramPoint;
+  PreLoad() {}
+  static bool isKind(const ProgramPoint &location) {
+    return location.getKind() == PreLoadKind;
+  }
+};
+
+class PreStore : public LocationCheck {
+public:
+  PreStore(const Stmt *S, const LocationContext *L,
+           const ProgramPointTag *tag = nullptr)
+  : LocationCheck(S, L, PreStoreKind, tag) {}
+  
+private:
+  friend class ProgramPoint;
+  PreStore() {}
+  static bool isKind(const ProgramPoint &location) {
+    return location.getKind() == PreStoreKind;
+  }
+};
+
+class PostLoad : public PostStmt {
+public:
+  PostLoad(const Stmt *S, const LocationContext *L,
+           const ProgramPointTag *tag = nullptr)
+    : PostStmt(S, PostLoadKind, L, tag) {}
+
+private:
+  friend class ProgramPoint;
+  PostLoad() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostLoadKind;
+  }
+};
+
+/// \brief Represents a program point after a store evaluation.
+class PostStore : public PostStmt {
+public:
+  /// Construct the post store point.
+  /// \param Loc can be used to store the information about the location 
+  /// used in the form it was uttered in the code.
+  PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
+            const ProgramPointTag *tag = nullptr)
+    : PostStmt(S, PostStoreKind, L, tag) {
+    assert(getData2() == nullptr);
+    setData2(Loc);
+  }
+
+  /// \brief Returns the information about the location used in the store,
+  /// how it was uttered in the code.
+  const void *getLocationValue() const {
+    return getData2();
+  }
+
+private:
+  friend class ProgramPoint;
+  PostStore() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostStoreKind;
+  }
+};
+
+class PostLValue : public PostStmt {
+public:
+  PostLValue(const Stmt *S, const LocationContext *L,
+             const ProgramPointTag *tag = nullptr)
+    : PostStmt(S, PostLValueKind, L, tag) {}
+
+private:
+  friend class ProgramPoint;
+  PostLValue() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostLValueKind;
+  }
+};
+
+/// Represents a point after we ran remove dead bindings BEFORE
+/// processing the given statement.
+class PreStmtPurgeDeadSymbols : public StmtPoint {
+public:
+  PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
+                       const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
+
+private:
+  friend class ProgramPoint;
+  PreStmtPurgeDeadSymbols() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
+  }
+};
+
+/// Represents a point after we ran remove dead bindings AFTER
+/// processing the  given statement.
+class PostStmtPurgeDeadSymbols : public StmtPoint {
+public:
+  PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
+                       const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
+
+private:
+  friend class ProgramPoint;
+  PostStmtPurgeDeadSymbols() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
+  }
+};
+
+class BlockEdge : public ProgramPoint {
+public:
+  BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L)
+    : ProgramPoint(B1, B2, BlockEdgeKind, L) {
+    assert(B1 && "BlockEdge: source block must be non-null");
+    assert(B2 && "BlockEdge: destination block must be non-null");    
+  }
+
+  const CFGBlock *getSrc() const {
+    return static_cast<const CFGBlock*>(getData1());
+  }
+
+  const CFGBlock *getDst() const {
+    return static_cast<const CFGBlock*>(getData2());
+  }
+
+private:
+  friend class ProgramPoint;
+  BlockEdge() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockEdgeKind;
+  }
+};
+
+class PostInitializer : public ProgramPoint {
+public:
+  /// \brief Construct a PostInitializer point that represents a location after
+  ///   CXXCtorInitializer expression evaluation.
+  ///
+  /// \param I The initializer.
+  /// \param Loc The location of the field being initialized.
+  PostInitializer(const CXXCtorInitializer *I,
+                  const void *Loc,
+                  const LocationContext *L)
+    : ProgramPoint(I, Loc, PostInitializerKind, L) {}
+
+  const CXXCtorInitializer *getInitializer() const {
+    return static_cast<const CXXCtorInitializer *>(getData1());
+  }
+
+  /// \brief Returns the location of the field.
+  const void *getLocationValue() const {
+    return getData2();
+  }
+
+private:
+  friend class ProgramPoint;
+  PostInitializer() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostInitializerKind;
+  }
+};
+
+/// Represents an implicit call event.
+///
+/// The nearest statement is provided for diagnostic purposes.
+class ImplicitCallPoint : public ProgramPoint {
+public:
+  ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
+                    const LocationContext *L, const ProgramPointTag *Tag)
+    : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
+
+  const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
+  SourceLocation getLocation() const {
+    return SourceLocation::getFromPtrEncoding(getData1());
+  }
+
+protected:
+  ImplicitCallPoint() {}
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() >= MinImplicitCallKind &&
+           Location.getKind() <= MaxImplicitCallKind;
+  }
+};
+
+/// Represents a program point just before an implicit call event.
+///
+/// Explicit calls will appear as PreStmt program points.
+class PreImplicitCall : public ImplicitCallPoint {
+public:
+  PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+                  const ProgramPointTag *Tag = nullptr)
+    : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
+
+private:
+  friend class ProgramPoint;
+  PreImplicitCall() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreImplicitCallKind;
+  }
+};
+
+/// Represents a program point just after an implicit call event.
+///
+/// Explicit calls will appear as PostStmt program points.
+class PostImplicitCall : public ImplicitCallPoint {
+public:
+  PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+                   const ProgramPointTag *Tag = nullptr)
+    : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
+
+private:
+  friend class ProgramPoint;
+  PostImplicitCall() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostImplicitCallKind;
+  }
+};
+
+/// Represents a point when we begin processing an inlined call.
+/// CallEnter uses the caller's location context.
+class CallEnter : public ProgramPoint {
+public:
+  CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 
+            const LocationContext *callerCtx)
+    : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
+
+  const Stmt *getCallExpr() const {
+    return static_cast<const Stmt *>(getData1());
+  }
+
+  const StackFrameContext *getCalleeContext() const {
+    return static_cast<const StackFrameContext *>(getData2());
+  }
+
+private:
+  friend class ProgramPoint;
+  CallEnter() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallEnterKind;
+  }
+};
+
+/// Represents a point when we start the call exit sequence (for inlined call).
+///
+/// The call exit is simulated with a sequence of nodes, which occur between
+/// CallExitBegin and CallExitEnd. The following operations occur between the
+/// two program points:
+/// - CallExitBegin
+/// - Bind the return value
+/// - Run Remove dead bindings (to clean up the dead symbols from the callee).
+/// - CallExitEnd
+class CallExitBegin : public ProgramPoint {
+public:
+  // CallExitBegin uses the callee's location context.
+  CallExitBegin(const StackFrameContext *L)
+    : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
+
+private:
+  friend class ProgramPoint;
+  CallExitBegin() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallExitBeginKind;
+  }
+};
+
+/// Represents a point when we finish the call exit sequence (for inlined call).
+/// \sa CallExitBegin
+class CallExitEnd : public ProgramPoint {
+public:
+  // CallExitEnd uses the caller's location context.
+  CallExitEnd(const StackFrameContext *CalleeCtx,
+              const LocationContext *CallerCtx)
+    : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
+
+  const StackFrameContext *getCalleeContext() const {
+    return static_cast<const StackFrameContext *>(getData1());
+  }
+
+private:
+  friend class ProgramPoint;
+  CallExitEnd() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallExitEndKind;
+  }
+};
+
+/// This is a meta program point, which should be skipped by all the diagnostic
+/// reasoning etc.
+class EpsilonPoint : public ProgramPoint {
+public:
+  EpsilonPoint(const LocationContext *L, const void *Data1,
+               const void *Data2 = nullptr,
+               const ProgramPointTag *tag = nullptr)
+    : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
+
+  const void *getData() const { return getData1(); }
+
+private:
+  friend class ProgramPoint;
+  EpsilonPoint() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == EpsilonKind;
+  }
+};
+
+/// ProgramPoints can be "tagged" as representing points specific to a given
+/// analysis entity.  Tags are abstract annotations, with an associated
+/// description and potentially other information.
+class ProgramPointTag {
+public:
+  ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
+  virtual ~ProgramPointTag();
+  virtual StringRef getTagDescription() const = 0;    
+
+protected:
+  /// Used to implement 'isKind' in subclasses.
+  const void *getTagKind() { return TagKind; }
+  
+private:
+  const void *TagKind;
+};
+
+class SimpleProgramPointTag : public ProgramPointTag {
+  std::string Desc;
+public:
+  SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
+  StringRef getTagDescription() const override;
+};
+
+} // end namespace clang
+
+
+namespace llvm { // Traits specialization for DenseMap
+
+template <> struct DenseMapInfo<clang::ProgramPoint> {
+
+static inline clang::ProgramPoint getEmptyKey() {
+  uintptr_t x =
+   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
+}
+
+static inline clang::ProgramPoint getTombstoneKey() {
+  uintptr_t x =
+   reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
+}
+
+static unsigned getHashValue(const clang::ProgramPoint &Loc) {
+  return Loc.getHashValue();
+}
+
+static bool isEqual(const clang::ProgramPoint &L,
+                    const clang::ProgramPoint &R) {
+  return L == R;
+}
+
+};
+  
+template <>
+struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
new file mode 100644
index 0000000..6d0427b
--- /dev/null
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -0,0 +1,244 @@
+//===-- BumpVector.h - Vector-like ADT that uses bump allocation --*- 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 BumpVector, a vector-like ADT whose contents are
+//  allocated from a BumpPtrAllocator.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Most of this is copy-and-paste from SmallVector.h.  We can
+// refactor this core logic into something common that is shared between
+// the two.  The main thing that is different is the allocation strategy.
+
+#ifndef LLVM_CLANG_BUMP_VECTOR
+#define LLVM_CLANG_BUMP_VECTOR
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cstring>
+#include <iterator>
+#include <memory>
+
+namespace clang {
+  
+class BumpVectorContext {
+  llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
+public:
+  /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
+  /// and destroys it when the BumpVectorContext object is destroyed.
+  BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {}
+  
+  /// Construct a new BumpVectorContext that reuses an existing
+  /// BumpPtrAllocator.  This BumpPtrAllocator is not destroyed when the
+  /// BumpVectorContext object is destroyed.
+  BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {}
+  
+  ~BumpVectorContext() {
+    if (Alloc.getInt())
+      delete Alloc.getPointer();
+  }
+  
+  llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); }
+};
+  
+template<typename T>
+class BumpVector {
+  T *Begin, *End, *Capacity;
+public:
+  // Default ctor - Initialize to empty.
+  explicit BumpVector(BumpVectorContext &C, unsigned N)
+  : Begin(nullptr), End(nullptr), Capacity(nullptr) {
+    reserve(C, N);
+  }
+  
+  ~BumpVector() {
+    if (std::is_class<T>::value) {
+      // Destroy the constructed elements in the vector.
+      destroy_range(Begin, End);
+    }
+  }
+  
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T* iterator;
+  typedef const T* const_iterator;
+  
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+  
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef T* pointer;
+  typedef const T* const_pointer;
+  
+  // forward iterator creation methods.
+  iterator begin() { return Begin; }
+  const_iterator begin() const { return Begin; }
+  iterator end() { return End; }
+  const_iterator end() const { return End; }
+  
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+    
+  bool empty() const { return Begin == End; }
+  size_type size() const { return End-Begin; }
+
+  reference operator[](unsigned idx) {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  const_reference operator[](unsigned idx) const {
+    assert(Begin + idx < End);
+    return Begin[idx];
+  }
+  
+  reference front() {
+    return begin()[0];
+  }
+  const_reference front() const {
+    return begin()[0];
+  }
+  
+  reference back() {
+    return end()[-1];
+  }
+  const_reference back() const {
+    return end()[-1];
+  }
+  
+  void pop_back() {
+    --End;
+    End->~T();
+  }
+  
+  T pop_back_val() {
+    T Result = back();
+    pop_back();
+    return Result;
+  }
+  
+  void clear() {
+    if (std::is_class<T>::value) {
+      destroy_range(Begin, End);
+    }
+    End = Begin;
+  }
+  
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  pointer data() {
+    return pointer(Begin);
+  }
+  
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  const_pointer data() const {
+    return const_pointer(Begin);
+  }
+  
+  void push_back(const_reference Elt, BumpVectorContext &C) {
+    if (End < Capacity) {
+    Retry:
+      new (End) T(Elt);
+      ++End;
+      return;
+    }
+    grow(C);
+    goto Retry;    
+  }
+
+  /// insert - Insert some number of copies of element into a position. Return
+  /// iterator to position after last inserted copy.
+  iterator insert(iterator I, size_t Cnt, const_reference E,
+      BumpVectorContext &C) {
+    assert (I >= Begin && I <= End && "Iterator out of bounds.");
+    if (End + Cnt <= Capacity) {
+    Retry:
+      move_range_right(I, End, Cnt);
+      construct_range(I, I + Cnt, E);
+      End += Cnt;
+      return I + Cnt;
+    }
+    ptrdiff_t D = I - Begin;
+    grow(C, size() + Cnt);
+    I = Begin + D;
+    goto Retry;
+  }
+
+  void reserve(BumpVectorContext &C, unsigned N) {
+    if (unsigned(Capacity-Begin) < N)
+      grow(C, N);
+  }
+
+  /// capacity - Return the total number of elements in the currently allocated
+  /// buffer.
+  size_t capacity() const { return Capacity - Begin; }  
+    
+private:
+  /// grow - double the size of the allocated memory, guaranteeing space for at
+  /// least one more element or MinSize if specified.
+  void grow(BumpVectorContext &C, size_type MinSize = 1);
+  
+  void construct_range(T *S, T *E, const T &Elt) {
+    for (; S != E; ++S)
+      new (S) T(Elt);
+  }
+  
+  void destroy_range(T *S, T *E) {
+    while (S != E) {
+      --E;
+      E->~T();
+    }
+  }
+
+  void move_range_right(T *S, T *E, size_t D) {
+    for (T *I = E + D - 1, *IL = S + D - 1; I != IL; --I) {
+      --E;
+      new (I) T(*E);
+      E->~T();
+    }
+  }
+};
+  
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
+  size_t CurCapacity = Capacity-Begin;
+  size_t CurSize = size();
+  size_t NewCapacity = 2*CurCapacity;
+  if (NewCapacity < MinSize)
+    NewCapacity = MinSize;
+
+  // Allocate the memory from the BumpPtrAllocator.
+  T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
+  
+  // Copy the elements over.
+  if (std::is_class<T>::value) {
+    std::uninitialized_copy(Begin, End, NewElts);
+    // Destroy the original elements.
+    destroy_range(Begin, End);
+  }
+  else {
+    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  }
+
+  // For now, leak 'Begin'.  We can add it back to a freelist in
+  // BumpVectorContext.
+  Begin = NewElts;
+  End = NewElts+CurSize;
+  Capacity = Begin+NewCapacity;
+}
+
+} // end: clang namespace
+#endif // end: LLVM_CLANG_BUMP_VECTOR
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
new file mode 100644
index 0000000..9e8ef2e
--- /dev/null
+++ b/include/clang/Basic/ABI.h
@@ -0,0 +1,207 @@
+//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Enums/classes describing ABI related information about constructors,
+/// destructors and thunks.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_ABI_H
+#define CLANG_BASIC_ABI_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+
+/// \brief C++ constructor types.
+enum CXXCtorType {
+    Ctor_Complete,          ///< Complete object ctor
+    Ctor_Base,              ///< Base object ctor
+    Ctor_CompleteAllocating ///< Complete object allocating ctor
+};
+
+/// \brief C++ destructor types.
+enum CXXDtorType {
+    Dtor_Deleting, ///< Deleting dtor
+    Dtor_Complete, ///< Complete object dtor
+    Dtor_Base      ///< Base object dtor
+};
+
+/// \brief A return adjustment.
+struct ReturnAdjustment {
+  /// \brief The non-virtual adjustment from the derived object to its
+  /// nearest virtual base.
+  int64_t NonVirtual;
+
+  /// \brief Holds the ABI-specific information about the virtual return
+  /// adjustment, if needed.
+  union VirtualAdjustment {
+    // Itanium ABI
+    struct {
+      /// \brief The offset (in bytes), relative to the address point
+      /// of the virtual base class offset.
+      int64_t VBaseOffsetOffset;
+    } Itanium;
+
+    // Microsoft ABI
+    struct {
+      /// \brief The offset (in bytes) of the vbptr, relative to the beginning
+      /// of the derived class.
+      uint32_t VBPtrOffset;
+
+      /// \brief Index of the virtual base in the vbtable.
+      uint32_t VBIndex;
+    } Microsoft;
+
+    VirtualAdjustment() {
+      memset(this, 0, sizeof(*this));
+    }
+
+    bool Equals(const VirtualAdjustment &Other) const {
+      return memcmp(this, &Other, sizeof(Other)) == 0;
+    }
+
+    bool isEmpty() const {
+      VirtualAdjustment Zero;
+      return Equals(Zero);
+    }
+
+    bool Less(const VirtualAdjustment &RHS) const {
+      return memcmp(this, &RHS, sizeof(RHS)) < 0;
+    }
+  } Virtual;
+  
+  ReturnAdjustment() : NonVirtual(0) {}
+  
+  bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
+
+  friend bool operator==(const ReturnAdjustment &LHS, 
+                         const ReturnAdjustment &RHS) {
+    return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
+  }
+
+  friend bool operator!=(const ReturnAdjustment &LHS, const ReturnAdjustment &RHS) {
+    return !(LHS == RHS);
+  }
+
+  friend bool operator<(const ReturnAdjustment &LHS,
+                        const ReturnAdjustment &RHS) {
+    if (LHS.NonVirtual < RHS.NonVirtual)
+      return true;
+
+    return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
+  }
+};
+  
+/// \brief A \c this pointer adjustment.
+struct ThisAdjustment {
+  /// \brief The non-virtual adjustment from the derived object to its
+  /// nearest virtual base.
+  int64_t NonVirtual;
+
+  /// \brief Holds the ABI-specific information about the virtual this
+  /// adjustment, if needed.
+  union VirtualAdjustment {
+    // Itanium ABI
+    struct {
+      /// \brief The offset (in bytes), relative to the address point,
+      /// of the virtual call offset.
+      int64_t VCallOffsetOffset;
+    } Itanium;
+
+    struct {
+      /// \brief The offset of the vtordisp (in bytes), relative to the ECX.
+      int32_t VtordispOffset;
+
+      /// \brief The offset of the vbptr of the derived class (in bytes),
+      /// relative to the ECX after vtordisp adjustment.
+      int32_t VBPtrOffset;
+
+      /// \brief The offset (in bytes) of the vbase offset in the vbtable.
+      int32_t VBOffsetOffset;
+    } Microsoft;
+
+    VirtualAdjustment() {
+      memset(this, 0, sizeof(*this));
+    }
+
+    bool Equals(const VirtualAdjustment &Other) const {
+      return memcmp(this, &Other, sizeof(Other)) == 0;
+    }
+
+    bool isEmpty() const {
+      VirtualAdjustment Zero;
+      return Equals(Zero);
+    }
+
+    bool Less(const VirtualAdjustment &RHS) const {
+      return memcmp(this, &RHS, sizeof(RHS)) < 0;
+    }
+  } Virtual;
+  
+  ThisAdjustment() : NonVirtual(0) { }
+
+  bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
+
+  friend bool operator==(const ThisAdjustment &LHS, 
+                         const ThisAdjustment &RHS) {
+    return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Equals(RHS.Virtual);
+  }
+
+  friend bool operator!=(const ThisAdjustment &LHS, const ThisAdjustment &RHS) {
+    return !(LHS == RHS);
+  }
+  
+  friend bool operator<(const ThisAdjustment &LHS,
+                        const ThisAdjustment &RHS) {
+    if (LHS.NonVirtual < RHS.NonVirtual)
+      return true;
+    
+    return LHS.NonVirtual == RHS.NonVirtual && LHS.Virtual.Less(RHS.Virtual);
+  }
+};
+
+class CXXMethodDecl;
+
+/// \brief The \c this pointer adjustment as well as an optional return
+/// adjustment for a thunk.
+struct ThunkInfo {
+  /// \brief The \c this pointer adjustment.
+  ThisAdjustment This;
+    
+  /// \brief The return adjustment.
+  ReturnAdjustment Return;
+
+  /// \brief Holds a pointer to the overridden method this thunk is for,
+  /// if needed by the ABI to distinguish different thunks with equal
+  /// adjustments. Otherwise, null.
+  /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using
+  /// an ABI-specific comparator.
+  const CXXMethodDecl *Method;
+
+  ThunkInfo() : Method(nullptr) { }
+
+  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
+            const CXXMethodDecl *Method = nullptr)
+      : This(This), Return(Return), Method(Method) {}
+
+  friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
+    return LHS.This == RHS.This && LHS.Return == RHS.Return &&
+           LHS.Method == RHS.Method;
+  }
+
+  bool isEmpty() const {
+    return This.isEmpty() && Return.isEmpty() && Method == nullptr;
+  }
+};  
+
+} // end namespace clang
+
+#endif // CLANG_BASIC_ABI_H
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
new file mode 100644
index 0000000..4b1cea5
--- /dev/null
+++ b/include/clang/Basic/AddressSpaces.h
@@ -0,0 +1,50 @@
+//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides definitions for the various language-specific address
+/// spaces.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
+#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
+
+namespace clang {
+
+namespace LangAS {
+
+/// \brief Defines the set of possible language-specific address spaces.
+///
+/// This uses a high starting offset so as not to conflict with any address
+/// space used by a target.
+enum ID {
+  Offset = 0xFFFF00,
+
+  opencl_global = Offset,
+  opencl_local,
+  opencl_constant,
+
+  cuda_device,
+  cuda_constant,
+  cuda_shared,
+
+  Last,
+  Count = Last-Offset
+};
+
+/// The type of a lookup table which maps from language-specific address spaces
+/// to target-specific ones.
+typedef unsigned Map[Count];
+
+}
+
+}
+
+#endif
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
new file mode 100644
index 0000000..7304c8f
--- /dev/null
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -0,0 +1,40 @@
+//===--- AllDiagnostics.h - Aggregate Diagnostic headers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Includes all the separate Diagnostic headers & some related helpers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ALL_DIAGNOSTICS_H
+#define LLVM_CLANG_ALL_DIAGNOSTICS_H
+
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/CommentDiagnostic.h"
+#include "clang/Analysis/AnalysisDiagnostic.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Serialization/SerializationDiagnostic.h"
+
+namespace clang {
+template <size_t SizeOfStr, typename FieldType>
+class StringSizerHelper {
+  char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
+public:
+  enum { Size = SizeOfStr };
+};
+} // end namespace clang 
+
+#define STR_SIZE(str, fieldTy) clang::StringSizerHelper<sizeof(str)-1, \
+                                                        fieldTy>::Size 
+
+#endif
diff --git a/include/clang/Basic/AttrHasAttributeImpl.inc b/include/clang/Basic/AttrHasAttributeImpl.inc
new file mode 100644
index 0000000..f876b98
--- /dev/null
+++ b/include/clang/Basic/AttrHasAttributeImpl.inc
@@ -0,0 +1,690 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Code to implement the __has_attribute logic                                 *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+switch (Syntax) {
+case AttrSyntax::Generic:
+  return llvm::StringSwitch<bool>(Name)
+    .Case("interrupt", (T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb))
+    .Case("acquire_capability", true)
+    .Case("acquire_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("exclusive_lock_function", true)
+    .Case("shared_lock_function", true)
+    .Case("acquired_after", true)
+    .Case("acquired_before", true)
+    .Case("address_space", true)
+    .Case("alias", true)
+    .Case("alias", true)
+    .Case("aligned", true)
+    .Case("aligned", true)
+    .Case("align", true)
+    .Case("alignas", true)
+    .Case("_Alignas", true)
+    .Case("always_inline", true)
+    .Case("always_inline", true)
+    .Case("__forceinline", true)
+    .Case("analyzer_noreturn", true)
+    .Case("annotate", true)
+    .Case("objc_arc_weak_reference_unavailable", true)
+    .Case("argument_with_type_tag", true)
+    .Case("pointer_with_type_tag", true)
+    .Case("asm", true)
+    .Case("__asm__", true)
+    .Case("assert_capability", true)
+    .Case("assert_capability", true)
+    .Case("assert_shared_capability", true)
+    .Case("assert_shared_capability", true)
+    .Case("assert_exclusive_lock", true)
+    .Case("assert_shared_lock", true)
+    .Case("availability", true)
+    .Case("blocks", true)
+    .Case("bounded", true)
+    .Case("_Noreturn", true)
+    .Case("cdecl", true)
+    .Case("cdecl", true)
+    .Case("__cdecl", true)
+    .Case("_cdecl", true)
+    .Case("cf_audited_transfer", true)
+    .Case("cf_consumed", true)
+    .Case("cf_returns_not_retained", true)
+    .Case("cf_returns_retained", true)
+    .Case("cf_unknown_transfer", true)
+    .Case("constant", true)
+    .Case("device", true)
+    .Case("global", true)
+    .Case("host", true)
+    .Case("launch_bounds", true)
+    .Case("shared", true)
+    .Case("noreturn", true)
+    .Case("callable_when", true)
+    .Case("capability", true)
+    .Case("capability", true)
+    .Case("shared_capability", true)
+    .Case("shared_capability", true)
+    .Case("carries_dependency", true)
+    .Case("carries_dependency", true)
+    .Case("cleanup", true)
+    .Case("cleanup", true)
+    .Case("cold", true)
+    .Case("cold", true)
+    .Case("common", true)
+    .Case("common", true)
+    .Case("const", true)
+    .Case("const", true)
+    .Case("__const", true)
+    .Case("__const", true)
+    .Case("constructor", true)
+    .Case("constructor", true)
+    .Case("consumable", true)
+    .Case("consumable_auto_cast_state", true)
+    .Case("consumable_set_state_on_read", true)
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("deprecated", true)
+    .Case("deprecated", true)
+    .Case("deprecated", true)
+    .Case("deprecated", true)
+    .Case("destructor", true)
+    .Case("destructor", true)
+    .Case("enable_if", true)
+    .Case("exclusive_trylock_function", true)
+    .Case("ext_vector_type", true)
+    .Case("fallthrough", true)
+    .Case("fastcall", true)
+    .Case("fastcall", true)
+    .Case("__fastcall", true)
+    .Case("_fastcall", true)
+    .Case("final", true)
+    .Case("sealed", true)
+    .Case("flatten", true)
+    .Case("flatten", true)
+    .Case("format", true)
+    .Case("format", true)
+    .Case("format_arg", true)
+    .Case("format_arg", true)
+    .Case("gnu_inline", true)
+    .Case("gnu_inline", true)
+    .Case("guarded_by", true)
+    .Case("guarded_var", true)
+    .Case("hot", true)
+    .Case("hot", true)
+    .Case("ibaction", true)
+    .Case("iboutlet", true)
+    .Case("iboutletcollection", true)
+    .Case("init_priority", true)
+    .Case("init_seg", true)
+    .Case("intel_ocl_bicc", true)
+    .Case("lock_returned", true)
+    .Case("lockable", true)
+    .Case("locks_excluded", true)
+    .Case("loop", true)
+    .Case("unroll", true)
+    .Case("ms_abi", true)
+    .Case("ms_abi", true)
+    .Case("__single_inheritance", true)
+    .Case("__multiple_inheritance", true)
+    .Case("__virtual_inheritance", true)
+    .Case("__unspecified_inheritance", true)
+    .Case("interrupt", (T.getArch() == llvm::Triple::msp430))
+    .Case("malloc", true)
+    .Case("malloc", true)
+    .Case("may_alias", true)
+    .Case("may_alias", true)
+    .Case("minsize", true)
+    .Case("mips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("mips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("mode", true)
+    .Case("mode", true)
+    .Case("property", true)
+    .Case("ms_struct", true)
+    .Case("ms_struct", true)
+    .Case("ns_consumed", true)
+    .Case("ns_consumes_self", true)
+    .Case("ns_returns_autoreleased", true)
+    .Case("ns_returns_not_retained", true)
+    .Case("ns_returns_retained", true)
+    .Case("naked", true)
+    .Case("naked", true)
+    .Case("naked", true)
+    .Case("neon_polyvector_type", true)
+    .Case("neon_vector_type", true)
+    .Case("nocommon", true)
+    .Case("nocommon", true)
+    .Case("nodebug", true)
+    .Case("noduplicate", true)
+    .Case("noduplicate", true)
+    .Case("noinline", true)
+    .Case("noinline", true)
+    .Case("noinline", true)
+    .Case("no_instrument_function", true)
+    .Case("no_instrument_function", true)
+    .Case("nomips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("nomips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("noreturn", true)
+    .Case("noreturn", true)
+    .Case("noreturn", true)
+    .Case("no_address_safety_analysis", true)
+    .Case("no_address_safety_analysis", true)
+    .Case("no_sanitize_address", true)
+    .Case("no_sanitize_address", true)
+    .Case("no_sanitize_memory", true)
+    .Case("no_sanitize_thread", true)
+    .Case("no_split_stack", true)
+    .Case("no_split_stack", true)
+    .Case("no_thread_safety_analysis", true)
+    .Case("nothrow", true)
+    .Case("nothrow", true)
+    .Case("nothrow", true)
+    .Case("nonnull", true)
+    .Case("nonnull", true)
+    .Case("objc_bridge", true)
+    .Case("objc_bridge_mutable", true)
+    .Case("objc_bridge_related", true)
+    .Case("objc_designated_initializer", true)
+    .Case("objc_exception", true)
+    .Case("objc_protocol_requires_explicit_implementation", true)
+    .Case("objc_gc", true)
+    .Case("objc_method_family", true)
+    .Case("NSObject", true)
+    .Case("objc_ownership", true)
+    .Case("objc_precise_lifetime", true)
+    .Case("objc_requires_property_definitions", true)
+    .Case("objc_requires_super", true)
+    .Case("objc_returns_inner_pointer", true)
+    .Case("objc_root_class", true)
+    .Case("objc_runtime_name", true)
+    .Case("__constant", true)
+    .Case("constant", true)
+    .Case("__global", true)
+    .Case("global", true)
+    .Case("__read_only", true)
+    .Case("read_only", true)
+    .Case("__write_only", true)
+    .Case("write_only", true)
+    .Case("__read_write", true)
+    .Case("read_write", true)
+    .Case("__kernel", true)
+    .Case("kernel", true)
+    .Case("__local", true)
+    .Case("local", true)
+    .Case("__private", true)
+    .Case("private", true)
+    .Case("optnone", true)
+    .Case("optnone", true)
+    .Case("overloadable", true)
+    .Case("override", true)
+    .Case("ownership_holds", true)
+    .Case("ownership_returns", true)
+    .Case("ownership_takes", true)
+    .Case("packed", true)
+    .Case("packed", true)
+    .Case("param_typestate", true)
+    .Case("pascal", true)
+    .Case("__pascal", true)
+    .Case("_pascal", true)
+    .Case("pcs", true)
+    .Case("pcs", true)
+    .Case("pnaclcall", true)
+    .Case("pt_guarded_by", true)
+    .Case("pt_guarded_var", true)
+    .Case("__ptr32", true)
+    .Case("__ptr64", true)
+    .Case("pure", true)
+    .Case("pure", true)
+    .Case("regparm", true)
+    .Case("regparm", true)
+    .Case("release_capability", true)
+    .Case("release_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("unlock_function", true)
+    .Case("reqd_work_group_size", true)
+    .Case("requires_capability", true)
+    .Case("requires_capability", true)
+    .Case("exclusive_locks_required", true)
+    .Case("requires_shared_capability", true)
+    .Case("requires_shared_capability", true)
+    .Case("shared_locks_required", true)
+    .Case("return_typestate", true)
+    .Case("returns_nonnull", true)
+    .Case("returns_nonnull", true)
+    .Case("returns_twice", true)
+    .Case("returns_twice", true)
+    .Case("__sptr", true)
+    .Case("scoped_lockable", true)
+    .Case("section", true)
+    .Case("section", true)
+    .Case("allocate", true)
+    .Case("selectany", true)
+    .Case("sentinel", true)
+    .Case("sentinel", true)
+    .Case("set_typestate", true)
+    .Case("shared_trylock_function", true)
+    .Case("stdcall", true)
+    .Case("stdcall", true)
+    .Case("__stdcall", true)
+    .Case("_stdcall", true)
+    .Case("sysv_abi", true)
+    .Case("sysv_abi", true)
+    .Case("tls_model", true)
+    .Case("tls_model", true)
+    .Case("test_typestate", true)
+    .Case("thiscall", true)
+    .Case("thiscall", true)
+    .Case("__thiscall", true)
+    .Case("_thiscall", true)
+    .Case("thread", true)
+    .Case("transparent_union", true)
+    .Case("transparent_union", true)
+    .Case("try_acquire_capability", true)
+    .Case("try_acquire_capability", true)
+    .Case("try_acquire_shared_capability", true)
+    .Case("try_acquire_shared_capability", true)
+    .Case("type_tag_for_datatype", true)
+    .Case("type_visibility", true)
+    .Case("type_visibility", true)
+    .Case("__uptr", true)
+    .Case("__unaligned", true)
+    .Case("unavailable", true)
+    .Case("unused", true)
+    .Case("unused", true)
+    .Case("used", true)
+    .Case("used", true)
+    .Case("uuid", true)
+    .Case("vecreturn", true)
+    .Case("vec_type_hint", true)
+    .Case("vector_size", true)
+    .Case("vector_size", true)
+    .Case("visibility", true)
+    .Case("visibility", true)
+    .Case("warn_unused", true)
+    .Case("warn_unused_result", true)
+    .Case("warn_unused_result", true)
+    .Case("warn_unused_result", true)
+    .Case("weak", true)
+    .Case("weak", true)
+    .Case("weak_import", true)
+    .Case("weakref", true)
+    .Case("weakref", true)
+    .Case("__w64", true)
+    .Case("work_group_size_hint", true)
+    .Case("force_align_arg_pointer", (T.getArch() == llvm::Triple::x86))
+    .Default(false);
+case AttrSyntax::GNU:
+  return llvm::StringSwitch<bool>(Name)
+    .Case("interrupt", (T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb))
+    .Case("acquire_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("exclusive_lock_function", true)
+    .Case("shared_lock_function", true)
+    .Case("acquire_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("exclusive_lock_function", true)
+    .Case("shared_lock_function", true)
+    .Case("acquire_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("exclusive_lock_function", true)
+    .Case("shared_lock_function", true)
+    .Case("acquire_capability", true)
+    .Case("acquire_shared_capability", true)
+    .Case("exclusive_lock_function", true)
+    .Case("shared_lock_function", true)
+    .Case("acquired_after", true)
+    .Case("acquired_before", true)
+    .Case("address_space", true)
+    .Case("alias", true)
+    .Case("aligned", true)
+    .Case("always_inline", true)
+    .Case("analyzer_noreturn", true)
+    .Case("annotate", true)
+    .Case("objc_arc_weak_reference_unavailable", true)
+    .Case("argument_with_type_tag", true)
+    .Case("pointer_with_type_tag", true)
+    .Case("argument_with_type_tag", true)
+    .Case("pointer_with_type_tag", true)
+    .Case("assert_capability", true)
+    .Case("assert_shared_capability", true)
+    .Case("assert_capability", true)
+    .Case("assert_shared_capability", true)
+    .Case("assert_exclusive_lock", true)
+    .Case("assert_shared_lock", true)
+    .Case("availability", true)
+    .Case("blocks", true)
+    .Case("bounded", true)
+    .Case("cdecl", true)
+    .Case("cf_audited_transfer", true)
+    .Case("cf_consumed", true)
+    .Case("cf_returns_not_retained", true)
+    .Case("cf_returns_retained", true)
+    .Case("cf_unknown_transfer", true)
+    .Case("constant", true)
+    .Case("device", true)
+    .Case("global", true)
+    .Case("host", true)
+    .Case("launch_bounds", true)
+    .Case("shared", true)
+    .Case("callable_when", true)
+    .Case("capability", true)
+    .Case("shared_capability", true)
+    .Case("capability", true)
+    .Case("shared_capability", true)
+    .Case("carries_dependency", true)
+    .Case("cleanup", true)
+    .Case("cold", true)
+    .Case("common", true)
+    .Case("const", true)
+    .Case("__const", true)
+    .Case("const", true)
+    .Case("__const", true)
+    .Case("constructor", true)
+    .Case("consumable", true)
+    .Case("consumable_auto_cast_state", true)
+    .Case("consumable_set_state_on_read", true)
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("deprecated", true)
+    .Case("destructor", true)
+    .Case("enable_if", true)
+    .Case("exclusive_trylock_function", true)
+    .Case("ext_vector_type", true)
+    .Case("fastcall", true)
+    .Case("flatten", true)
+    .Case("format", true)
+    .Case("format_arg", true)
+    .Case("gnu_inline", true)
+    .Case("guarded_by", true)
+    .Case("guarded_var", true)
+    .Case("hot", true)
+    .Case("ibaction", true)
+    .Case("iboutlet", true)
+    .Case("iboutletcollection", true)
+    .Case("init_priority", true)
+    .Case("intel_ocl_bicc", true)
+    .Case("lock_returned", true)
+    .Case("lockable", true)
+    .Case("locks_excluded", true)
+    .Case("ms_abi", true)
+    .Case("interrupt", (T.getArch() == llvm::Triple::msp430))
+    .Case("malloc", true)
+    .Case("may_alias", true)
+    .Case("minsize", true)
+    .Case("mips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("mode", true)
+    .Case("ms_struct", true)
+    .Case("ns_consumed", true)
+    .Case("ns_consumes_self", true)
+    .Case("ns_returns_autoreleased", true)
+    .Case("ns_returns_not_retained", true)
+    .Case("ns_returns_retained", true)
+    .Case("naked", true)
+    .Case("neon_polyvector_type", true)
+    .Case("neon_vector_type", true)
+    .Case("nocommon", true)
+    .Case("nodebug", true)
+    .Case("noduplicate", true)
+    .Case("noinline", true)
+    .Case("no_instrument_function", true)
+    .Case("nomips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel))
+    .Case("noreturn", true)
+    .Case("no_address_safety_analysis", true)
+    .Case("no_sanitize_address", true)
+    .Case("no_address_safety_analysis", true)
+    .Case("no_sanitize_address", true)
+    .Case("no_sanitize_memory", true)
+    .Case("no_sanitize_thread", true)
+    .Case("no_split_stack", true)
+    .Case("no_thread_safety_analysis", true)
+    .Case("nothrow", true)
+    .Case("nonnull", true)
+    .Case("objc_bridge", true)
+    .Case("objc_bridge_mutable", true)
+    .Case("objc_bridge_related", true)
+    .Case("objc_designated_initializer", true)
+    .Case("objc_exception", true)
+    .Case("objc_protocol_requires_explicit_implementation", true)
+    .Case("objc_gc", true)
+    .Case("objc_method_family", true)
+    .Case("NSObject", true)
+    .Case("objc_ownership", true)
+    .Case("objc_precise_lifetime", true)
+    .Case("objc_requires_property_definitions", true)
+    .Case("objc_requires_super", true)
+    .Case("objc_returns_inner_pointer", true)
+    .Case("objc_root_class", true)
+    .Case("objc_runtime_name", true)
+    .Case("optnone", true)
+    .Case("overloadable", true)
+    .Case("ownership_holds", true)
+    .Case("ownership_returns", true)
+    .Case("ownership_takes", true)
+    .Case("ownership_holds", true)
+    .Case("ownership_returns", true)
+    .Case("ownership_takes", true)
+    .Case("ownership_holds", true)
+    .Case("ownership_returns", true)
+    .Case("ownership_takes", true)
+    .Case("packed", true)
+    .Case("param_typestate", true)
+    .Case("pascal", true)
+    .Case("pcs", true)
+    .Case("pnaclcall", true)
+    .Case("pt_guarded_by", true)
+    .Case("pt_guarded_var", true)
+    .Case("pure", true)
+    .Case("regparm", true)
+    .Case("release_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("unlock_function", true)
+    .Case("release_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("unlock_function", true)
+    .Case("release_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("unlock_function", true)
+    .Case("release_capability", true)
+    .Case("release_shared_capability", true)
+    .Case("release_generic_capability", true)
+    .Case("unlock_function", true)
+    .Case("reqd_work_group_size", true)
+    .Case("requires_capability", true)
+    .Case("exclusive_locks_required", true)
+    .Case("requires_shared_capability", true)
+    .Case("shared_locks_required", true)
+    .Case("requires_capability", true)
+    .Case("exclusive_locks_required", true)
+    .Case("requires_shared_capability", true)
+    .Case("shared_locks_required", true)
+    .Case("requires_capability", true)
+    .Case("exclusive_locks_required", true)
+    .Case("requires_shared_capability", true)
+    .Case("shared_locks_required", true)
+    .Case("requires_capability", true)
+    .Case("exclusive_locks_required", true)
+    .Case("requires_shared_capability", true)
+    .Case("shared_locks_required", true)
+    .Case("return_typestate", true)
+    .Case("returns_nonnull", true)
+    .Case("returns_twice", true)
+    .Case("scoped_lockable", true)
+    .Case("section", true)
+    .Case("sentinel", true)
+    .Case("set_typestate", true)
+    .Case("shared_trylock_function", true)
+    .Case("stdcall", true)
+    .Case("sysv_abi", true)
+    .Case("tls_model", true)
+    .Case("test_typestate", true)
+    .Case("thiscall", true)
+    .Case("transparent_union", true)
+    .Case("try_acquire_capability", true)
+    .Case("try_acquire_shared_capability", true)
+    .Case("try_acquire_capability", true)
+    .Case("try_acquire_shared_capability", true)
+    .Case("type_tag_for_datatype", true)
+    .Case("type_visibility", true)
+    .Case("unavailable", true)
+    .Case("unused", true)
+    .Case("used", true)
+    .Case("vecreturn", true)
+    .Case("vec_type_hint", true)
+    .Case("vector_size", true)
+    .Case("visibility", true)
+    .Case("warn_unused", true)
+    .Case("warn_unused_result", true)
+    .Case("weak", true)
+    .Case("weak_import", true)
+    .Case("weakref", true)
+    .Case("work_group_size_hint", true)
+    .Case("force_align_arg_pointer", (T.getArch() == llvm::Triple::x86))
+    .Default(false);
+case AttrSyntax::Declspec:
+  return llvm::StringSwitch<bool>(Name)
+    .Case("align", true)
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32))
+    .Case("deprecated", true)
+    .Case("property", true)
+    .Case("naked", true)
+    .Case("noinline", true)
+    .Case("noreturn", true)
+    .Case("nothrow", true)
+    .Case("allocate", true)
+    .Case("selectany", true)
+    .Case("thread", true)
+    .Case("uuid", true)
+    .Default(false);
+case AttrSyntax::Pragma:
+  return llvm::StringSwitch<bool>(Name)
+    .Case("init_seg", true)
+    .Case("loop", true)
+    .Case("unroll", true)
+    .Case("loop", true)
+    .Case("unroll", true)
+    .Default(false);
+case AttrSyntax::CXX: {
+if (!Scope || Scope->getName() == "") {
+  return llvm::StringSwitch<bool>(Name)
+    .Case("noreturn", LangOpts.CPlusPlus11)
+    .Case("carries_dependency", LangOpts.CPlusPlus11)
+    .Case("deprecated", LangOpts.CPlusPlus11)
+    .Case("deprecated", LangOpts.CPlusPlus11)
+    .Default(false);
+} else if (Scope->getName() == "clang") {
+  return llvm::StringSwitch<bool>(Name)
+    .Case("acquire_capability", LangOpts.CPlusPlus11)
+    .Case("acquire_shared_capability", LangOpts.CPlusPlus11)
+    .Case("acquire_capability", LangOpts.CPlusPlus11)
+    .Case("acquire_shared_capability", LangOpts.CPlusPlus11)
+    .Case("assert_capability", LangOpts.CPlusPlus11)
+    .Case("assert_shared_capability", LangOpts.CPlusPlus11)
+    .Case("assert_capability", LangOpts.CPlusPlus11)
+    .Case("assert_shared_capability", LangOpts.CPlusPlus11)
+    .Case("capability", LangOpts.CPlusPlus11)
+    .Case("shared_capability", LangOpts.CPlusPlus11)
+    .Case("capability", LangOpts.CPlusPlus11)
+    .Case("shared_capability", LangOpts.CPlusPlus11)
+    .Case("fallthrough", LangOpts.CPlusPlus11)
+    .Case("noduplicate", LangOpts.CPlusPlus11)
+    .Case("optnone", LangOpts.CPlusPlus11)
+    .Case("release_capability", LangOpts.CPlusPlus11)
+    .Case("release_shared_capability", LangOpts.CPlusPlus11)
+    .Case("release_generic_capability", LangOpts.CPlusPlus11)
+    .Case("release_capability", LangOpts.CPlusPlus11)
+    .Case("release_shared_capability", LangOpts.CPlusPlus11)
+    .Case("release_generic_capability", LangOpts.CPlusPlus11)
+    .Case("release_capability", LangOpts.CPlusPlus11)
+    .Case("release_shared_capability", LangOpts.CPlusPlus11)
+    .Case("release_generic_capability", LangOpts.CPlusPlus11)
+    .Case("requires_capability", LangOpts.CPlusPlus11)
+    .Case("requires_shared_capability", LangOpts.CPlusPlus11)
+    .Case("requires_capability", LangOpts.CPlusPlus11)
+    .Case("requires_shared_capability", LangOpts.CPlusPlus11)
+    .Case("try_acquire_capability", LangOpts.CPlusPlus11)
+    .Case("try_acquire_shared_capability", LangOpts.CPlusPlus11)
+    .Case("try_acquire_capability", LangOpts.CPlusPlus11)
+    .Case("try_acquire_shared_capability", LangOpts.CPlusPlus11)
+    .Case("type_visibility", LangOpts.CPlusPlus11)
+    .Case("warn_unused_result", LangOpts.CPlusPlus11)
+    .Default(false);
+} else if (Scope->getName() == "gnu") {
+  return llvm::StringSwitch<bool>(Name)
+    .Case("alias", LangOpts.CPlusPlus11)
+    .Case("aligned", LangOpts.CPlusPlus11)
+    .Case("always_inline", LangOpts.CPlusPlus11)
+    .Case("cdecl", LangOpts.CPlusPlus11)
+    .Case("cleanup", LangOpts.CPlusPlus11)
+    .Case("cold", LangOpts.CPlusPlus11)
+    .Case("common", LangOpts.CPlusPlus11)
+    .Case("const", LangOpts.CPlusPlus11)
+    .Case("__const", LangOpts.CPlusPlus11)
+    .Case("const", LangOpts.CPlusPlus11)
+    .Case("__const", LangOpts.CPlusPlus11)
+    .Case("constructor", LangOpts.CPlusPlus11)
+    .Case("dllexport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32) && LangOpts.CPlusPlus11)
+    .Case("dllimport", (T.getArch() == llvm::Triple::x86 || T.getArch() == llvm::Triple::x86_64 || T.getArch() == llvm::Triple::arm || T.getArch() == llvm::Triple::thumb) && (T.getOS() == llvm::Triple::Win32) && LangOpts.CPlusPlus11)
+    .Case("deprecated", LangOpts.CPlusPlus11)
+    .Case("destructor", LangOpts.CPlusPlus11)
+    .Case("fastcall", LangOpts.CPlusPlus11)
+    .Case("flatten", LangOpts.CPlusPlus11)
+    .Case("format", LangOpts.CPlusPlus11)
+    .Case("format_arg", LangOpts.CPlusPlus11)
+    .Case("gnu_inline", LangOpts.CPlusPlus11)
+    .Case("hot", LangOpts.CPlusPlus11)
+    .Case("ms_abi", LangOpts.CPlusPlus11)
+    .Case("malloc", LangOpts.CPlusPlus11)
+    .Case("may_alias", LangOpts.CPlusPlus11)
+    .Case("mips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel) && LangOpts.CPlusPlus11)
+    .Case("mode", LangOpts.CPlusPlus11)
+    .Case("ms_struct", LangOpts.CPlusPlus11)
+    .Case("naked", LangOpts.CPlusPlus11)
+    .Case("nocommon", LangOpts.CPlusPlus11)
+    .Case("noinline", LangOpts.CPlusPlus11)
+    .Case("no_instrument_function", LangOpts.CPlusPlus11)
+    .Case("nomips16", (T.getArch() == llvm::Triple::mips || T.getArch() == llvm::Triple::mipsel) && LangOpts.CPlusPlus11)
+    .Case("noreturn", LangOpts.CPlusPlus11)
+    .Case("no_address_safety_analysis", LangOpts.CPlusPlus11)
+    .Case("no_sanitize_address", LangOpts.CPlusPlus11)
+    .Case("no_address_safety_analysis", LangOpts.CPlusPlus11)
+    .Case("no_sanitize_address", LangOpts.CPlusPlus11)
+    .Case("no_split_stack", LangOpts.CPlusPlus11)
+    .Case("nothrow", LangOpts.CPlusPlus11)
+    .Case("nonnull", LangOpts.CPlusPlus11)
+    .Case("packed", LangOpts.CPlusPlus11)
+    .Case("pcs", LangOpts.CPlusPlus11)
+    .Case("pure", LangOpts.CPlusPlus11)
+    .Case("regparm", LangOpts.CPlusPlus11)
+    .Case("returns_nonnull", LangOpts.CPlusPlus11)
+    .Case("returns_twice", LangOpts.CPlusPlus11)
+    .Case("section", LangOpts.CPlusPlus11)
+    .Case("sentinel", LangOpts.CPlusPlus11)
+    .Case("stdcall", LangOpts.CPlusPlus11)
+    .Case("sysv_abi", LangOpts.CPlusPlus11)
+    .Case("tls_model", LangOpts.CPlusPlus11)
+    .Case("thiscall", LangOpts.CPlusPlus11)
+    .Case("transparent_union", LangOpts.CPlusPlus11)
+    .Case("unused", LangOpts.CPlusPlus11)
+    .Case("used", LangOpts.CPlusPlus11)
+    .Case("vector_size", LangOpts.CPlusPlus11)
+    .Case("visibility", LangOpts.CPlusPlus11)
+    .Case("warn_unused_result", LangOpts.CPlusPlus11)
+    .Case("weak", LangOpts.CPlusPlus11)
+    .Case("weakref", LangOpts.CPlusPlus11)
+    .Default(false);
+}
+}
+}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
new file mode 100644
index 0000000..150a30e
--- /dev/null
+++ b/include/clang/Basic/AttrKinds.h
@@ -0,0 +1,34 @@
+//===----- Attr.h - Enum values for C Attribute Kinds ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::attr::Kind enum.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRKINDS_H
+#define LLVM_CLANG_ATTRKINDS_H
+
+namespace clang {
+
+namespace attr {
+
+// \brief A list of all the recognized kinds of attributes.
+enum Kind {
+#define ATTR(X) X,
+#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
+#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
+#include "clang/Basic/AttrList.inc"
+  NUM_ATTRS
+};
+
+} // end namespace attr
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/AttrList.inc b/include/clang/Basic/AttrList.inc
new file mode 100644
index 0000000..e37d14d
--- /dev/null
+++ b/include/clang/Basic/AttrList.inc
@@ -0,0 +1,199 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of all attributes that Clang recognizes                                *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LAST_ATTR
+#define LAST_ATTR(NAME) ATTR(NAME)
+#endif
+
+#ifndef INHERITABLE_ATTR
+#define INHERITABLE_ATTR(NAME) ATTR(NAME)
+#endif
+
+#ifndef LAST_INHERITABLE_ATTR
+#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)
+#endif
+
+#ifndef INHERITABLE_PARAM_ATTR
+#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)
+#endif
+
+#ifndef LAST_INHERITABLE_PARAM_ATTR
+#define LAST_INHERITABLE_PARAM_ATTR(NAME) INHERITABLE_PARAM_ATTR(NAME)
+#endif
+
+INHERITABLE_PARAM_ATTR(Annotate)
+INHERITABLE_PARAM_ATTR(CFConsumed)
+INHERITABLE_PARAM_ATTR(CarriesDependency)
+LAST_INHERITABLE_PARAM_ATTR(NSConsumed)
+
+INHERITABLE_ATTR(ARMInterrupt)
+INHERITABLE_ATTR(AcquireCapability)
+INHERITABLE_ATTR(AcquiredAfter)
+INHERITABLE_ATTR(AcquiredBefore)
+INHERITABLE_ATTR(AlignMac68k)
+INHERITABLE_ATTR(Aligned)
+INHERITABLE_ATTR(AlwaysInline)
+INHERITABLE_ATTR(AnalyzerNoReturn)
+INHERITABLE_ATTR(ArcWeakrefUnavailable)
+INHERITABLE_ATTR(ArgumentWithTypeTag)
+INHERITABLE_ATTR(AsmLabel)
+INHERITABLE_ATTR(AssertCapability)
+INHERITABLE_ATTR(AssertExclusiveLock)
+INHERITABLE_ATTR(AssertSharedLock)
+INHERITABLE_ATTR(Availability)
+INHERITABLE_ATTR(Blocks)
+INHERITABLE_ATTR(C11NoReturn)
+INHERITABLE_ATTR(CDecl)
+INHERITABLE_ATTR(CFAuditedTransfer)
+INHERITABLE_ATTR(CFReturnsNotRetained)
+INHERITABLE_ATTR(CFReturnsRetained)
+INHERITABLE_ATTR(CFUnknownTransfer)
+INHERITABLE_ATTR(CUDAConstant)
+INHERITABLE_ATTR(CUDADevice)
+INHERITABLE_ATTR(CUDAGlobal)
+INHERITABLE_ATTR(CUDAHost)
+INHERITABLE_ATTR(CUDALaunchBounds)
+INHERITABLE_ATTR(CUDAShared)
+INHERITABLE_ATTR(CXX11NoReturn)
+INHERITABLE_ATTR(CallableWhen)
+INHERITABLE_ATTR(Capability)
+INHERITABLE_ATTR(Cleanup)
+INHERITABLE_ATTR(Cold)
+INHERITABLE_ATTR(Common)
+INHERITABLE_ATTR(Const)
+INHERITABLE_ATTR(Constructor)
+INHERITABLE_ATTR(Consumable)
+INHERITABLE_ATTR(ConsumableAutoCast)
+INHERITABLE_ATTR(ConsumableSetOnRead)
+INHERITABLE_ATTR(DLLExport)
+INHERITABLE_ATTR(DLLImport)
+INHERITABLE_ATTR(Deprecated)
+INHERITABLE_ATTR(Destructor)
+INHERITABLE_ATTR(EnableIf)
+INHERITABLE_ATTR(ExclusiveTrylockFunction)
+INHERITABLE_ATTR(FastCall)
+INHERITABLE_ATTR(Final)
+INHERITABLE_ATTR(Flatten)
+INHERITABLE_ATTR(Format)
+INHERITABLE_ATTR(FormatArg)
+INHERITABLE_ATTR(GNUInline)
+INHERITABLE_ATTR(GuardedBy)
+INHERITABLE_ATTR(GuardedVar)
+INHERITABLE_ATTR(Hot)
+INHERITABLE_ATTR(IBAction)
+INHERITABLE_ATTR(IBOutlet)
+INHERITABLE_ATTR(IBOutletCollection)
+INHERITABLE_ATTR(InitPriority)
+INHERITABLE_ATTR(IntelOclBicc)
+INHERITABLE_ATTR(LockReturned)
+INHERITABLE_ATTR(LocksExcluded)
+INHERITABLE_ATTR(MSABI)
+INHERITABLE_ATTR(MSInheritance)
+INHERITABLE_ATTR(MSP430Interrupt)
+INHERITABLE_ATTR(MSVtorDisp)
+INHERITABLE_ATTR(Malloc)
+INHERITABLE_ATTR(MaxFieldAlignment)
+INHERITABLE_ATTR(MayAlias)
+INHERITABLE_ATTR(MinSize)
+INHERITABLE_ATTR(Mips16)
+INHERITABLE_ATTR(MsStruct)
+INHERITABLE_ATTR(NSConsumesSelf)
+INHERITABLE_ATTR(NSReturnsAutoreleased)
+INHERITABLE_ATTR(NSReturnsNotRetained)
+INHERITABLE_ATTR(NSReturnsRetained)
+INHERITABLE_ATTR(Naked)
+INHERITABLE_ATTR(NoCommon)
+INHERITABLE_ATTR(NoDebug)
+INHERITABLE_ATTR(NoDuplicate)
+INHERITABLE_ATTR(NoInline)
+INHERITABLE_ATTR(NoInstrumentFunction)
+INHERITABLE_ATTR(NoMips16)
+INHERITABLE_ATTR(NoReturn)
+INHERITABLE_ATTR(NoSanitizeAddress)
+INHERITABLE_ATTR(NoSanitizeMemory)
+INHERITABLE_ATTR(NoSanitizeThread)
+INHERITABLE_ATTR(NoSplitStack)
+INHERITABLE_ATTR(NoThreadSafetyAnalysis)
+INHERITABLE_ATTR(NoThrow)
+INHERITABLE_ATTR(NonNull)
+INHERITABLE_ATTR(ObjCBridge)
+INHERITABLE_ATTR(ObjCBridgeMutable)
+INHERITABLE_ATTR(ObjCBridgeRelated)
+INHERITABLE_ATTR(ObjCException)
+INHERITABLE_ATTR(ObjCExplicitProtocolImpl)
+INHERITABLE_ATTR(ObjCMethodFamily)
+INHERITABLE_ATTR(ObjCNSObject)
+INHERITABLE_ATTR(ObjCPreciseLifetime)
+INHERITABLE_ATTR(ObjCRequiresPropertyDefs)
+INHERITABLE_ATTR(ObjCRequiresSuper)
+INHERITABLE_ATTR(ObjCReturnsInnerPointer)
+INHERITABLE_ATTR(ObjCRootClass)
+INHERITABLE_ATTR(OpenCLKernel)
+INHERITABLE_ATTR(OptimizeNone)
+INHERITABLE_ATTR(Override)
+INHERITABLE_ATTR(Ownership)
+INHERITABLE_ATTR(Packed)
+INHERITABLE_ATTR(ParamTypestate)
+INHERITABLE_ATTR(Pascal)
+INHERITABLE_ATTR(Pcs)
+INHERITABLE_ATTR(PnaclCall)
+INHERITABLE_ATTR(PtGuardedBy)
+INHERITABLE_ATTR(PtGuardedVar)
+INHERITABLE_ATTR(Pure)
+INHERITABLE_ATTR(ReleaseCapability)
+INHERITABLE_ATTR(ReqdWorkGroupSize)
+INHERITABLE_ATTR(RequiresCapability)
+INHERITABLE_ATTR(ReturnTypestate)
+INHERITABLE_ATTR(ReturnsNonNull)
+INHERITABLE_ATTR(ReturnsTwice)
+INHERITABLE_ATTR(ScopedLockable)
+INHERITABLE_ATTR(Section)
+INHERITABLE_ATTR(SelectAny)
+INHERITABLE_ATTR(Sentinel)
+INHERITABLE_ATTR(SetTypestate)
+INHERITABLE_ATTR(SharedTrylockFunction)
+INHERITABLE_ATTR(StdCall)
+INHERITABLE_ATTR(SysVABI)
+INHERITABLE_ATTR(TLSModel)
+INHERITABLE_ATTR(TestTypestate)
+INHERITABLE_ATTR(ThisCall)
+INHERITABLE_ATTR(TransparentUnion)
+INHERITABLE_ATTR(TryAcquireCapability)
+INHERITABLE_ATTR(TypeTagForDatatype)
+INHERITABLE_ATTR(TypeVisibility)
+INHERITABLE_ATTR(Unavailable)
+INHERITABLE_ATTR(Unused)
+INHERITABLE_ATTR(Used)
+INHERITABLE_ATTR(Uuid)
+INHERITABLE_ATTR(VecReturn)
+INHERITABLE_ATTR(VecTypeHint)
+INHERITABLE_ATTR(Visibility)
+INHERITABLE_ATTR(WarnUnused)
+INHERITABLE_ATTR(WarnUnusedResult)
+INHERITABLE_ATTR(Weak)
+INHERITABLE_ATTR(WeakImport)
+INHERITABLE_ATTR(WeakRef)
+INHERITABLE_ATTR(WorkGroupSizeHint)
+LAST_INHERITABLE_ATTR(X86ForceAlignArgPointer)
+
+ATTR(Alias)
+ATTR(FallThrough)
+ATTR(InitSeg)
+ATTR(LoopHint)
+ATTR(Mode)
+ATTR(ObjCDesignatedInitializer)
+ATTR(ObjCRuntimeName)
+ATTR(OpenCLImageAccess)
+ATTR(Overloadable)
+LAST_ATTR(Thread)
+
+#undef LAST_ATTR
+#undef INHERITABLE_ATTR
+#undef LAST_INHERITABLE_ATTR
+#undef LAST_INHERITABLE_PARAM_ATTR
+#undef ATTR
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
new file mode 100644
index 0000000..5783b3b
--- /dev/null
+++ b/include/clang/Basic/Attributes.h
@@ -0,0 +1,41 @@
+//===--- Attributes.h - Attributes header -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ATTRIBUTES_H
+#define LLVM_CLANG_BASIC_ATTRIBUTES_H
+
+#include "llvm/ADT/Triple.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+enum class AttrSyntax {
+  /// Is the attribute identifier generally known for any syntax?
+  Generic,
+  /// Is the identifier known as a GNU-style attribute?
+  GNU,
+  /// Is the identifier known as a __declspec-style attribute?
+  Declspec,
+  // Is the identifier known as a C++-style attribute?
+  CXX,
+  // Is the identifier known as a pragma attribute?
+  Pragma
+};
+
+/// \brief Return true if we recognize and implement the attribute specified by
+/// the given information.
+bool hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+                  const IdentifierInfo *Attr, const llvm::Triple &T,
+                  const LangOptions &LangOpts);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
new file mode 100644
index 0000000..e705382
--- /dev/null
+++ b/include/clang/Basic/Builtins.def
@@ -0,0 +1,1215 @@
+//===--- Builtins.def - Builtin function info database ----------*- 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 standard builtin function database.  Users of this file
+// must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: This should really be a .td file, but that requires modifying tblgen.
+// Perhaps tblgen should have plugins.
+
+// The first value provided to the macro specifies the function name of the
+// builtin, and results in a clang::builtin::BIXX enum value for XX.
+
+// The second value provided to the macro specifies the type of the function
+// (result value, then each argument) as follows:
+//  v -> void
+//  b -> boolean
+//  c -> char
+//  s -> short
+//  i -> int
+//  h -> half
+//  f -> float
+//  d -> double
+//  z -> size_t
+//  F -> constant CFString
+//  G -> id
+//  H -> SEL
+//  M -> struct objc_super
+//  a -> __builtin_va_list
+//  A -> "reference" to __builtin_va_list
+//  V -> Vector, followed by the number of elements and the base type.
+//  E -> ext_vector, followed by the number of elements and the base type.
+//  X -> _Complex, followed by the base type.
+//  Y -> ptrdiff_t
+//  P -> FILE
+//  J -> jmp_buf
+//  SJ -> sigjmp_buf
+//  K -> ucontext_t
+//  p -> pid_t
+//  . -> "...".  This may only occur at the end of the function list.
+//
+// Types may be prefixed with the following modifiers:
+//  L   -> long (e.g. Li for 'long int')
+//  LL  -> long long
+//  LLL -> __int128_t (e.g. LLLi)
+//  W   -> int64_t
+//  S   -> signed
+//  U   -> unsigned
+//  I   -> Required to constant fold to an integer constant expression.
+//
+// Types may be postfixed with the following modifiers:
+// * -> pointer (optionally followed by an address space number)
+// & -> reference (optionally followed by an address space number)
+// C -> const
+// D -> volatile
+
+// The third value provided to the macro specifies information about attributes
+// of the function.  These must be kept in sync with the predicates in the
+// Builtin::Context class.  Currently we have:
+//  n -> nothrow
+//  r -> noreturn
+//  c -> const
+//  t -> signature is meaningless, use custom typechecking
+//  F -> this is a libc/libm function with a '__builtin_' prefix added.
+//  f -> this is a libc/libm function without the '__builtin_' prefix. It can
+//       be followed by ':headername:' to state which header this function
+//       comes from.
+//  i -> this is a runtime library implemented function without the
+//       '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
+//  p:N: -> this is a printf-like function whose Nth argument is the format
+//          string.
+//  P:N: -> similar to the p:N: attribute, but the function is like vprintf
+//          in that it accepts its arguments as a va_list rather than
+//          through an ellipsis
+//  s:N: -> this is a scanf-like function whose Nth argument is the format
+//          string.
+//  S:N: -> similar to the s:N: attribute, but the function is like vscanf
+//          in that it accepts its arguments as a va_list rather than
+//          through an ellipsis
+//  e -> const, but only when -fmath-errno=0
+//  j -> returns_twice (like setjmp)
+//  u -> arguments are not evaluated for their side-effects
+//  FIXME: gcc has nonnull
+
+#if defined(BUILTIN) && !defined(LIBBUILTIN)
+#  define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+#  define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// Standard libc/libm functions:
+BUILTIN(__builtin_atan2 , "ddd"  , "Fnc")
+BUILTIN(__builtin_atan2f, "fff"  , "Fnc")
+BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc")
+BUILTIN(__builtin_abs  , "ii"  , "ncF")
+BUILTIN(__builtin_copysign, "ddd", "ncF")
+BUILTIN(__builtin_copysignf, "fff", "ncF")
+BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
+BUILTIN(__builtin_fabs , "dd"  , "ncF")
+BUILTIN(__builtin_fabsf, "ff"  , "ncF")
+BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_fmod , "ddd"  , "Fnc")
+BUILTIN(__builtin_fmodf, "fff"  , "Fnc")
+BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_frexp , "ddi*"  , "Fn")
+BUILTIN(__builtin_frexpf, "ffi*"  , "Fn")
+BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
+BUILTIN(__builtin_huge_val, "d", "nc")
+BUILTIN(__builtin_huge_valf, "f", "nc")
+BUILTIN(__builtin_huge_vall, "Ld", "nc")
+BUILTIN(__builtin_inf  , "d"   , "nc")
+BUILTIN(__builtin_inff , "f"   , "nc")
+BUILTIN(__builtin_infl , "Ld"  , "nc")
+BUILTIN(__builtin_labs , "LiLi"  , "Fnc")
+BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
+BUILTIN(__builtin_ldexp , "ddi"  , "Fnc")
+BUILTIN(__builtin_ldexpf, "ffi"  , "Fnc")
+BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc")
+BUILTIN(__builtin_modf , "ddd*"  , "Fn")
+BUILTIN(__builtin_modff, "fff*"  , "Fn")
+BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
+BUILTIN(__builtin_nan,  "dcC*" , "ncF")
+BUILTIN(__builtin_nanf, "fcC*" , "ncF")
+BUILTIN(__builtin_nanl, "LdcC*", "ncF")
+BUILTIN(__builtin_nans,  "dcC*" , "ncF")
+BUILTIN(__builtin_nansf, "fcC*" , "ncF")
+BUILTIN(__builtin_nansl, "LdcC*", "ncF")
+BUILTIN(__builtin_powi , "ddi"  , "Fnc")
+BUILTIN(__builtin_powif, "ffi"  , "Fnc")
+BUILTIN(__builtin_powil, "LdLdi", "Fnc")
+BUILTIN(__builtin_pow , "ddd"  , "Fnc")
+BUILTIN(__builtin_powf, "fff"  , "Fnc")
+BUILTIN(__builtin_powl, "LdLdLd", "Fnc")
+
+// Standard unary libc/libm functions with double/float/long double variants:
+BUILTIN(__builtin_acos , "dd"  , "Fnc")
+BUILTIN(__builtin_acosf, "ff"  , "Fnc")
+BUILTIN(__builtin_acosl, "LdLd", "Fnc")
+BUILTIN(__builtin_acosh , "dd"  , "Fnc")
+BUILTIN(__builtin_acoshf, "ff"  , "Fnc")
+BUILTIN(__builtin_acoshl, "LdLd", "Fnc")
+BUILTIN(__builtin_asin , "dd"  , "Fnc")
+BUILTIN(__builtin_asinf, "ff"  , "Fnc")
+BUILTIN(__builtin_asinl, "LdLd", "Fnc")
+BUILTIN(__builtin_asinh , "dd"  , "Fnc")
+BUILTIN(__builtin_asinhf, "ff"  , "Fnc")
+BUILTIN(__builtin_asinhl, "LdLd", "Fnc")
+BUILTIN(__builtin_atan , "dd"  , "Fnc")
+BUILTIN(__builtin_atanf, "ff"  , "Fnc")
+BUILTIN(__builtin_atanl, "LdLd", "Fnc")
+BUILTIN(__builtin_atanh , "dd", "Fnc")
+BUILTIN(__builtin_atanhf, "ff", "Fnc")
+BUILTIN(__builtin_atanhl, "LdLd", "Fnc")
+BUILTIN(__builtin_cbrt , "dd", "Fnc")
+BUILTIN(__builtin_cbrtf, "ff", "Fnc")
+BUILTIN(__builtin_cbrtl, "LdLd", "Fnc")
+BUILTIN(__builtin_ceil , "dd"  , "Fnc")
+BUILTIN(__builtin_ceilf, "ff"  , "Fnc")
+BUILTIN(__builtin_ceill, "LdLd", "Fnc")
+BUILTIN(__builtin_cos , "dd"  , "Fnc")
+BUILTIN(__builtin_cosf, "ff"  , "Fnc")
+BUILTIN(__builtin_cosh , "dd"  , "Fnc")
+BUILTIN(__builtin_coshf, "ff"  , "Fnc")
+BUILTIN(__builtin_coshl, "LdLd", "Fnc")
+BUILTIN(__builtin_cosl, "LdLd", "Fnc")
+BUILTIN(__builtin_erf , "dd", "Fnc")
+BUILTIN(__builtin_erff, "ff", "Fnc")
+BUILTIN(__builtin_erfl, "LdLd", "Fnc")
+BUILTIN(__builtin_erfc , "dd", "Fnc")
+BUILTIN(__builtin_erfcf, "ff", "Fnc")
+BUILTIN(__builtin_erfcl, "LdLd", "Fnc")
+BUILTIN(__builtin_exp , "dd"  , "Fnc")
+BUILTIN(__builtin_expf, "ff"  , "Fnc")
+BUILTIN(__builtin_expl, "LdLd", "Fnc")
+BUILTIN(__builtin_exp2 , "dd"  , "Fnc")
+BUILTIN(__builtin_exp2f, "ff"  , "Fnc")
+BUILTIN(__builtin_exp2l, "LdLd", "Fnc")
+BUILTIN(__builtin_expm1 , "dd", "Fnc")
+BUILTIN(__builtin_expm1f, "ff", "Fnc")
+BUILTIN(__builtin_expm1l, "LdLd", "Fnc")
+BUILTIN(__builtin_fdim, "ddd", "Fnc")
+BUILTIN(__builtin_fdimf, "fff", "Fnc")
+BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc")
+BUILTIN(__builtin_floor , "dd"  , "Fnc")
+BUILTIN(__builtin_floorf, "ff"  , "Fnc")
+BUILTIN(__builtin_floorl, "LdLd", "Fnc")
+BUILTIN(__builtin_fma, "dddd", "Fnc")
+BUILTIN(__builtin_fmaf, "ffff", "Fnc")
+BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc")
+BUILTIN(__builtin_fmax, "ddd", "Fnc")
+BUILTIN(__builtin_fmaxf, "fff", "Fnc")
+BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_fmin, "ddd", "Fnc")
+BUILTIN(__builtin_fminf, "fff", "Fnc")
+BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_hypot , "ddd"  , "Fnc")
+BUILTIN(__builtin_hypotf, "fff"  , "Fnc")
+BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_ilogb , "id", "Fnc")
+BUILTIN(__builtin_ilogbf, "if", "Fnc")
+BUILTIN(__builtin_ilogbl, "iLd", "Fnc")
+BUILTIN(__builtin_lgamma , "dd", "Fnc")
+BUILTIN(__builtin_lgammaf, "ff", "Fnc")
+BUILTIN(__builtin_lgammal, "LdLd", "Fnc")
+BUILTIN(__builtin_llrint, "LLid", "Fnc")
+BUILTIN(__builtin_llrintf, "LLif", "Fnc")
+BUILTIN(__builtin_llrintl, "LLiLd", "Fnc")
+BUILTIN(__builtin_llround , "LLid", "Fnc")
+BUILTIN(__builtin_llroundf, "LLif", "Fnc")
+BUILTIN(__builtin_llroundl, "LLiLd", "Fnc")
+BUILTIN(__builtin_log , "dd"  , "Fnc")
+BUILTIN(__builtin_log10 , "dd"  , "Fnc")
+BUILTIN(__builtin_log10f, "ff"  , "Fnc")
+BUILTIN(__builtin_log10l, "LdLd", "Fnc")
+BUILTIN(__builtin_log1p , "dd"  , "Fnc")
+BUILTIN(__builtin_log1pf, "ff"  , "Fnc")
+BUILTIN(__builtin_log1pl, "LdLd", "Fnc")
+BUILTIN(__builtin_log2, "dd"  , "Fnc")
+BUILTIN(__builtin_log2f, "ff"  , "Fnc")
+BUILTIN(__builtin_log2l, "LdLd"  , "Fnc")
+BUILTIN(__builtin_logb , "dd", "Fnc")
+BUILTIN(__builtin_logbf, "ff", "Fnc")
+BUILTIN(__builtin_logbl, "LdLd", "Fnc")
+BUILTIN(__builtin_logf, "ff"  , "Fnc")
+BUILTIN(__builtin_logl, "LdLd", "Fnc")
+BUILTIN(__builtin_lrint , "Lid", "Fnc")
+BUILTIN(__builtin_lrintf, "Lif", "Fnc")
+BUILTIN(__builtin_lrintl, "LiLd", "Fnc")
+BUILTIN(__builtin_lround , "Lid", "Fnc")
+BUILTIN(__builtin_lroundf, "Lif", "Fnc")
+BUILTIN(__builtin_lroundl, "LiLd", "Fnc")
+BUILTIN(__builtin_nearbyint , "dd", "Fnc")
+BUILTIN(__builtin_nearbyintf, "ff", "Fnc")
+BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc")
+BUILTIN(__builtin_nextafter , "ddd", "Fnc")
+BUILTIN(__builtin_nextafterf, "fff", "Fnc")
+BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_nexttoward , "ddLd", "Fnc")
+BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc")
+BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_remainder , "ddd", "Fnc")
+BUILTIN(__builtin_remainderf, "fff", "Fnc")
+BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc")
+BUILTIN(__builtin_remquo , "dddi*", "Fn")
+BUILTIN(__builtin_remquof, "fffi*", "Fn")
+BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn")
+BUILTIN(__builtin_rint , "dd", "Fnc")
+BUILTIN(__builtin_rintf, "ff", "Fnc")
+BUILTIN(__builtin_rintl, "LdLd", "Fnc")
+BUILTIN(__builtin_round, "dd"  , "Fnc")
+BUILTIN(__builtin_roundf, "ff"  , "Fnc")
+BUILTIN(__builtin_roundl, "LdLd"  , "Fnc")
+BUILTIN(__builtin_scalbln , "ddLi", "Fnc")
+BUILTIN(__builtin_scalblnf, "ffLi", "Fnc")
+BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc")
+BUILTIN(__builtin_scalbn , "ddi", "Fnc")
+BUILTIN(__builtin_scalbnf, "ffi", "Fnc")
+BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc")
+BUILTIN(__builtin_sin , "dd"  , "Fnc")
+BUILTIN(__builtin_sinf, "ff"  , "Fnc")
+BUILTIN(__builtin_sinh , "dd"  , "Fnc")
+BUILTIN(__builtin_sinhf, "ff"  , "Fnc")
+BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
+BUILTIN(__builtin_sinl, "LdLd", "Fnc")
+BUILTIN(__builtin_sqrt , "dd"  , "Fnc")
+BUILTIN(__builtin_sqrtf, "ff"  , "Fnc")
+BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
+BUILTIN(__builtin_tan , "dd"  , "Fnc")
+BUILTIN(__builtin_tanf, "ff"  , "Fnc")
+BUILTIN(__builtin_tanh , "dd"  , "Fnc")
+BUILTIN(__builtin_tanhf, "ff"  , "Fnc")
+BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
+BUILTIN(__builtin_tanl, "LdLd", "Fnc")
+BUILTIN(__builtin_tgamma , "dd", "Fnc")
+BUILTIN(__builtin_tgammaf, "ff", "Fnc")
+BUILTIN(__builtin_tgammal, "LdLd", "Fnc")
+BUILTIN(__builtin_trunc , "dd", "Fnc")
+BUILTIN(__builtin_truncf, "ff", "Fnc")
+BUILTIN(__builtin_truncl, "LdLd", "Fnc")
+
+// C99 complex builtins
+BUILTIN(__builtin_cabs, "dXd", "Fnc")
+BUILTIN(__builtin_cabsf, "fXf", "Fnc")
+BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
+BUILTIN(__builtin_cacos, "XdXd", "Fnc")
+BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
+BUILTIN(__builtin_cacosh, "XdXd", "Fnc")
+BUILTIN(__builtin_cacoshf, "XfXf", "Fnc")
+BUILTIN(__builtin_cacoshl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_carg, "dXd", "Fnc")
+BUILTIN(__builtin_cargf, "fXf", "Fnc")
+BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
+BUILTIN(__builtin_casin, "XdXd", "Fnc")
+BUILTIN(__builtin_casinf, "XfXf", "Fnc")
+BUILTIN(__builtin_casinh, "XdXd", "Fnc")
+BUILTIN(__builtin_casinhf, "XfXf", "Fnc")
+BUILTIN(__builtin_casinhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_catan, "XdXd", "Fnc")
+BUILTIN(__builtin_catanf, "XfXf", "Fnc")
+BUILTIN(__builtin_catanh, "XdXd", "Fnc")
+BUILTIN(__builtin_catanhf, "XfXf", "Fnc")
+BUILTIN(__builtin_catanhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccos, "XdXd", "Fnc")
+BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
+BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cexp, "XdXd", "Fnc")
+BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
+BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cimag, "dXd", "Fnc")
+BUILTIN(__builtin_cimagf, "fXf", "Fnc")
+BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
+BUILTIN(__builtin_conj, "XdXd", "Fnc")
+BUILTIN(__builtin_conjf, "XfXf", "Fnc")
+BUILTIN(__builtin_conjl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_clog, "XdXd", "Fnc")
+BUILTIN(__builtin_clogf, "XfXf", "Fnc")
+BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cproj, "XdXd", "Fnc")
+BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
+BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
+BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
+BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
+BUILTIN(__builtin_creal, "dXd", "Fnc")
+BUILTIN(__builtin_crealf, "fXf", "Fnc")
+BUILTIN(__builtin_creall, "LdXLd", "Fnc")
+BUILTIN(__builtin_csin, "XdXd", "Fnc")
+BUILTIN(__builtin_csinf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csinh, "XdXd", "Fnc")
+BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
+BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
+BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctan, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
+
+// FP Comparisons.
+BUILTIN(__builtin_isgreater     , "i.", "nc")
+BUILTIN(__builtin_isgreaterequal, "i.", "nc")
+BUILTIN(__builtin_isless        , "i.", "nc")
+BUILTIN(__builtin_islessequal   , "i.", "nc")
+BUILTIN(__builtin_islessgreater , "i.", "nc")
+BUILTIN(__builtin_isunordered   , "i.", "nc")
+
+// Unary FP classification
+BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_isfinite,   "i.", "nc")
+BUILTIN(__builtin_isinf,      "i.", "nc")
+BUILTIN(__builtin_isinf_sign, "i.", "nc")
+BUILTIN(__builtin_isnan,      "i.", "nc")
+BUILTIN(__builtin_isnormal,   "i.", "nc")
+
+// FP signbit builtins
+BUILTIN(__builtin_signbit, "id", "nc")
+BUILTIN(__builtin_signbitf, "if", "nc")
+BUILTIN(__builtin_signbitl, "iLd", "nc")
+
+// Builtins for arithmetic.
+BUILTIN(__builtin_clzs , "iUs"  , "nc")
+BUILTIN(__builtin_clz  , "iUi"  , "nc")
+BUILTIN(__builtin_clzl , "iULi" , "nc")
+BUILTIN(__builtin_clzll, "iULLi", "nc")
+// TODO: int clzimax(uintmax_t)
+BUILTIN(__builtin_ctzs , "iUs"  , "nc")
+BUILTIN(__builtin_ctz  , "iUi"  , "nc")
+BUILTIN(__builtin_ctzl , "iULi" , "nc")
+BUILTIN(__builtin_ctzll, "iULLi", "nc")
+// TODO: int ctzimax(uintmax_t)
+BUILTIN(__builtin_ffs  , "ii"  , "nc")
+BUILTIN(__builtin_ffsl , "iLi" , "nc")
+BUILTIN(__builtin_ffsll, "iLLi", "nc")
+BUILTIN(__builtin_parity  , "iUi"  , "nc")
+BUILTIN(__builtin_parityl , "iULi" , "nc")
+BUILTIN(__builtin_parityll, "iULLi", "nc")
+BUILTIN(__builtin_popcount  , "iUi"  , "nc")
+BUILTIN(__builtin_popcountl , "iULi" , "nc")
+BUILTIN(__builtin_popcountll, "iULLi", "nc")
+
+// FIXME: These type signatures are not correct for targets with int != 32-bits
+// or with ULL != 64-bits.
+BUILTIN(__builtin_bswap16, "UsUs", "nc")
+BUILTIN(__builtin_bswap32, "UiUi", "nc")
+BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
+
+// Random GCC builtins
+BUILTIN(__builtin_constant_p, "i.", "nctu")
+BUILTIN(__builtin_classify_type, "i.", "nctu")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin_va_start, "vA.", "nt")
+BUILTIN(__builtin_va_end, "vA", "n")
+BUILTIN(__builtin_va_copy, "vAA", "n")
+BUILTIN(__builtin_stdarg_start, "vA.", "n")
+BUILTIN(__builtin_bcmp, "iv*v*z", "n")
+BUILTIN(__builtin_bcopy, "vv*v*z", "n")
+BUILTIN(__builtin_bzero, "vv*z", "nF")
+BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
+BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
+BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
+BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
+BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
+BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
+BUILTIN(__builtin_memset, "v*v*iz", "nF")
+BUILTIN(__builtin_printf, "icC*.", "Fp:0:")
+BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
+BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
+BUILTIN(__builtin_strcat, "c*c*cC*", "nF")
+BUILTIN(__builtin_strchr, "c*cC*i", "nF")
+BUILTIN(__builtin_strcmp, "icC*cC*", "nF")
+BUILTIN(__builtin_strcpy, "c*c*cC*", "nF")
+BUILTIN(__builtin_strcspn, "zcC*cC*", "nF")
+BUILTIN(__builtin_strdup, "c*cC*", "nF")
+BUILTIN(__builtin_strlen, "zcC*", "nF")
+BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF")
+BUILTIN(__builtin_strncat, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strncmp, "icC*cC*z", "nF")
+BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF")
+BUILTIN(__builtin_strndup, "c*cC*z", "nF")
+BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
+BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
+BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
+BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
+BUILTIN(__builtin_return_address, "v*IUi", "n")
+BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
+BUILTIN(__builtin_frame_address, "v*IUi", "n")
+BUILTIN(__builtin___clear_cache, "vc*c*", "n")
+BUILTIN(__builtin_flt_rounds, "i", "nc")
+BUILTIN(__builtin_setjmp, "iv**", "j")
+BUILTIN(__builtin_longjmp, "vv**i", "r")
+BUILTIN(__builtin_unwind_init, "v", "")
+BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc")
+BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
+BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
+BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
+
+// GCC exception builtins
+BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
+BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
+BUILTIN(__builtin_dwarf_cfa, "v*", "n")
+BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
+BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
+BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
+
+// GCC Object size checking builtins
+BUILTIN(__builtin_object_size, "zvC*i", "nu")
+BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
+BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
+BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strlcat_chk, "zc*cC*zz", "nF")
+BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF")
+BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
+BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
+BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
+BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
+BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
+BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
+BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
+BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
+
+BUILTIN(__builtin_expect, "LiLiLi"   , "nc")
+BUILTIN(__builtin_prefetch, "vvC*.", "nc")
+BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
+BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_debugtrap, "v", "n")
+BUILTIN(__builtin_unreachable, "v", "nr")
+BUILTIN(__builtin_shufflevector, "v."   , "nc")
+BUILTIN(__builtin_convertvector, "v."   , "nct")
+BUILTIN(__builtin_alloca, "v*z"   , "n")
+
+// "Overloaded" Atomic operator builtins.  These are overloaded to support data
+// types of i8, i16, i32, i64, and i128.  The front-end sees calls to the
+// non-suffixed version of these (which has a bogus type) and transforms them to
+// the right overloaded version in Sema (plus casts).
+
+// FIXME: These assume that char -> i8, short -> i16, int -> i32,
+// long long -> i64.
+
+BUILTIN(__sync_fetch_and_add, "v.", "t")
+BUILTIN(__sync_fetch_and_add_1, "ccD*c.", "nt")
+BUILTIN(__sync_fetch_and_add_2, "ssD*s.", "nt")
+BUILTIN(__sync_fetch_and_add_4, "iiD*i.", "nt")
+BUILTIN(__sync_fetch_and_add_8, "LLiLLiD*LLi.", "nt")
+BUILTIN(__sync_fetch_and_add_16, "LLLiLLLiD*LLLi.", "nt")
+
+BUILTIN(__sync_fetch_and_sub, "v.", "t")
+BUILTIN(__sync_fetch_and_sub_1, "ccD*c.", "nt")
+BUILTIN(__sync_fetch_and_sub_2, "ssD*s.", "nt")
+BUILTIN(__sync_fetch_and_sub_4, "iiD*i.", "nt")
+BUILTIN(__sync_fetch_and_sub_8, "LLiLLiD*LLi.", "nt")
+BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLiD*LLLi.", "nt")
+
+BUILTIN(__sync_fetch_and_or, "v.", "t")
+BUILTIN(__sync_fetch_and_or_1, "ccD*c.", "nt")
+BUILTIN(__sync_fetch_and_or_2, "ssD*s.", "nt")
+BUILTIN(__sync_fetch_and_or_4, "iiD*i.", "nt")
+BUILTIN(__sync_fetch_and_or_8, "LLiLLiD*LLi.", "nt")
+BUILTIN(__sync_fetch_and_or_16, "LLLiLLLiD*LLLi.", "nt")
+
+BUILTIN(__sync_fetch_and_and, "v.", "t")
+BUILTIN(__sync_fetch_and_and_1, "ccD*c.", "tn")
+BUILTIN(__sync_fetch_and_and_2, "ssD*s.", "tn")
+BUILTIN(__sync_fetch_and_and_4, "iiD*i.", "tn")
+BUILTIN(__sync_fetch_and_and_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_fetch_and_and_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_fetch_and_xor, "v.", "t")
+BUILTIN(__sync_fetch_and_xor_1, "ccD*c.", "tn")
+BUILTIN(__sync_fetch_and_xor_2, "ssD*s.", "tn")
+BUILTIN(__sync_fetch_and_xor_4, "iiD*i.", "tn")
+BUILTIN(__sync_fetch_and_xor_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLiD*LLLi.", "tn")
+
+
+BUILTIN(__sync_add_and_fetch, "v.", "t")
+BUILTIN(__sync_add_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_add_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_add_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_add_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_add_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_sub_and_fetch, "v.", "t")
+BUILTIN(__sync_sub_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_sub_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_sub_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_sub_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_or_and_fetch, "v.", "t")
+BUILTIN(__sync_or_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_or_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_or_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_or_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_or_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_and_and_fetch, "v.", "t")
+BUILTIN(__sync_and_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_and_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_and_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_and_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_and_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_xor_and_fetch, "v.", "t")
+BUILTIN(__sync_xor_and_fetch_1, "ccD*c.", "tn")
+BUILTIN(__sync_xor_and_fetch_2, "ssD*s.", "tn")
+BUILTIN(__sync_xor_and_fetch_4, "iiD*i.", "tn")
+BUILTIN(__sync_xor_and_fetch_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_bool_compare_and_swap, "v.", "t")
+BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "tn")
+BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "tn")
+BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "tn")
+BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "tn")
+BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "tn")
+
+BUILTIN(__sync_val_compare_and_swap, "v.", "t")
+BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "tn")
+BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "tn")
+BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "tn")
+BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "tn")
+BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "tn")
+
+BUILTIN(__sync_lock_test_and_set, "v.", "t")
+BUILTIN(__sync_lock_test_and_set_1, "ccD*c.", "tn")
+BUILTIN(__sync_lock_test_and_set_2, "ssD*s.", "tn")
+BUILTIN(__sync_lock_test_and_set_4, "iiD*i.", "tn")
+BUILTIN(__sync_lock_test_and_set_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLiD*LLLi.", "tn")
+
+BUILTIN(__sync_lock_release, "v.", "t")
+BUILTIN(__sync_lock_release_1, "vcD*.", "tn")
+BUILTIN(__sync_lock_release_2, "vsD*.", "tn")
+BUILTIN(__sync_lock_release_4, "viD*.", "tn")
+BUILTIN(__sync_lock_release_8, "vLLiD*.", "tn")
+BUILTIN(__sync_lock_release_16, "vLLLiD*.", "tn")
+
+BUILTIN(__sync_swap, "v.", "t")
+BUILTIN(__sync_swap_1, "ccD*c.", "tn")
+BUILTIN(__sync_swap_2, "ssD*s.", "tn")
+BUILTIN(__sync_swap_4, "iiD*i.", "tn")
+BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "tn")
+BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "tn")
+
+// Some of our atomics builtins are handled by AtomicExpr rather than
+// as normal builtin CallExprs. This macro is used for such builtins.
+#ifndef ATOMIC_BUILTIN
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// C11 _Atomic operations for <stdatomic.h>.
+ATOMIC_BUILTIN(__c11_atomic_init, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_compare_exchange_strong, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_compare_exchange_weak, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t")
+BUILTIN(__c11_atomic_thread_fence, "vi", "n")
+BUILTIN(__c11_atomic_signal_fence, "vi", "n")
+BUILTIN(__c11_atomic_is_lock_free, "iz", "n")
+
+// GNU atomic builtins.
+ATOMIC_BUILTIN(__atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__atomic_load_n, "v.", "t")
+ATOMIC_BUILTIN(__atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__atomic_store_n, "v.", "t")
+ATOMIC_BUILTIN(__atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__atomic_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__atomic_compare_exchange, "v.", "t")
+ATOMIC_BUILTIN(__atomic_compare_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__atomic_fetch_nand, "v.", "t")
+ATOMIC_BUILTIN(__atomic_add_fetch, "v.", "t")
+ATOMIC_BUILTIN(__atomic_sub_fetch, "v.", "t")
+ATOMIC_BUILTIN(__atomic_and_fetch, "v.", "t")
+ATOMIC_BUILTIN(__atomic_or_fetch, "v.", "t")
+ATOMIC_BUILTIN(__atomic_xor_fetch, "v.", "t")
+ATOMIC_BUILTIN(__atomic_nand_fetch, "v.", "t")
+BUILTIN(__atomic_test_and_set, "bvD*i", "n")
+BUILTIN(__atomic_clear, "vvD*i", "n")
+BUILTIN(__atomic_thread_fence, "vi", "n")
+BUILTIN(__atomic_signal_fence, "vi", "n")
+BUILTIN(__atomic_always_lock_free, "izvCD*", "n")
+BUILTIN(__atomic_is_lock_free, "izvCD*", "n")
+
+#undef ATOMIC_BUILTIN
+
+// Non-overloaded atomic builtins.
+BUILTIN(__sync_synchronize, "v.", "n")
+// GCC does not support these, they are a Clang extension.
+BUILTIN(__sync_fetch_and_min, "iiD*i", "n")
+BUILTIN(__sync_fetch_and_max, "iiD*i", "n")
+BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n")
+BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n")
+
+// Random libc builtins.
+BUILTIN(__builtin_abort, "v", "Fnr")
+BUILTIN(__builtin_index, "c*cC*i", "Fn")
+BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
+
+// Microsoft builtins.  These are only active with -fms-extensions.
+LANGBUILTIN(_alloca,      "v*z", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__assume,     "vb",  "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__noop,       "i.",  "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__debugbreak, "v",   "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__va_start,   "vc**.", "nt", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+
+// C99 library functions
+// C99 stdlib.h
+LIBBUILTIN(abort, "v",            "fr",    "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(calloc, "v*zz",        "f",     "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(exit, "vi",            "fr",    "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(_Exit, "vi",           "fr",    "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(malloc, "v*z",         "f",     "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(realloc, "v*v*z",      "f",     "stdlib.h", ALL_LANGUAGES)
+// C99 string.h
+LIBBUILTIN(memcpy, "v*v*vC*z",    "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(memcmp, "ivC*vC*z",    "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(memmove, "v*v*vC*z",   "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strcpy, "c*c*cC*",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strncpy, "c*c*cC*z",   "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strcmp, "icC*cC*",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strncmp, "icC*cC*z",   "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strcat, "c*c*cC*",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strncat, "c*c*cC*z",   "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strxfrm, "zc*cC*z",    "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(memchr, "v*vC*iz",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strchr, "c*cC*i",      "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strcspn, "zcC*cC*",    "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strpbrk, "c*cC*cC*",   "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strrchr, "c*cC*i",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strspn, "zcC*cC*",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strstr, "c*cC*cC*",    "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strtok, "c*c*cC*",     "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(memset, "v*v*iz",      "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strerror, "c*i",       "f",     "string.h", ALL_LANGUAGES)
+LIBBUILTIN(strlen, "zcC*",        "f",     "string.h", ALL_LANGUAGES)
+// C99 stdio.h
+LIBBUILTIN(printf, "icC*.",       "fp:0:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(fprintf, "iP*cC*.",    "fp:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(snprintf, "ic*zcC*.",  "fp:2:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(sprintf, "ic*cC*.",    "fp:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vprintf, "icC*a",      "fP:0:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vfprintf, "i.",        "fP:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vsprintf, "ic*cC*a",   "fP:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(scanf, "icC*R.",       "fs:0:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(fscanf, "iP*RcC*R.",   "fs:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(sscanf, "icC*RcC*R.",  "fs:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vscanf, "icC*Ra",      "fS:0:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vfscanf, "iP*RcC*Ra",  "fS:1:", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
+// C99
+// In some systems setjmp is a macro that expands to _setjmp. We undefine
+// it here to avoid having two identical LIBBUILTIN entries.
+#undef setjmp
+LIBBUILTIN(setjmp, "iJ",          "fj",    "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(longjmp, "vJi",        "fr",    "setjmp.h", ALL_LANGUAGES)
+
+// Non-C library functions, active in GNU mode only.
+// Functions with (returns_twice) attribute (marked as "j") are still active in
+// all languages, because losing this attribute would result in miscompilation
+// when these functions are used in non-GNU mode. PR16138.
+LIBBUILTIN(alloca, "v*z",         "f",     "stdlib.h", ALL_GNU_LANGUAGES)
+// POSIX string.h
+LIBBUILTIN(stpcpy, "c*c*cC*",     "f",     "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(stpncpy, "c*c*cC*z",   "f",     "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strdup, "c*cC*",       "f",     "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strndup, "c*cC*z",     "f",     "string.h", ALL_GNU_LANGUAGES)
+// POSIX strings.h
+LIBBUILTIN(index, "c*cC*i",       "f",     "strings.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(rindex, "c*cC*i",      "f",     "strings.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(bzero, "vv*z",         "f",     "strings.h", ALL_GNU_LANGUAGES)
+// In some systems str[n]casejmp is a macro that expands to _str[n]icmp.
+// We undefine then here to avoid wrong name.
+#undef strcasecmp
+#undef strncasecmp
+LIBBUILTIN(strcasecmp, "icC*cC*", "f",     "strings.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strncasecmp, "icC*cC*z", "f",   "strings.h", ALL_GNU_LANGUAGES)
+// POSIX unistd.h
+LIBBUILTIN(_exit, "vi",           "fr",    "unistd.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(vfork, "p",            "fj",    "unistd.h", ALL_LANGUAGES)
+// POSIX setjmp.h
+
+LIBBUILTIN(_setjmp, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(__sigsetjmp, "iSJi",   "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(sigsetjmp, "iSJi",     "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(setjmp_syscall, "iJ",  "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(savectx, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(qsetjmp, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(getcontext, "iK*",     "fj",   "setjmp.h", ALL_LANGUAGES)
+
+LIBBUILTIN(_longjmp, "vJi",       "fr",    "setjmp.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(siglongjmp, "vSJi",    "fr",    "setjmp.h", ALL_GNU_LANGUAGES)
+// non-standard but very common
+LIBBUILTIN(strlcpy, "zc*cC*z",    "f",     "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strlcat, "zc*cC*z",    "f",     "string.h", ALL_GNU_LANGUAGES)
+//   id objc_msgSend(id, SEL, ...)
+LIBBUILTIN(objc_msgSend, "GGH.",   "f",     "objc/message.h", OBJC_LANG)
+// long double objc_msgSend_fpret(id self, SEL op, ...) 
+LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", "objc/message.h", OBJC_LANG)
+// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
+LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", "objc/message.h", OBJC_LANG)
+// void objc_msgSend_stret (id, SEL, ...)
+LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", "objc/message.h", OBJC_LANG)
+// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
+LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", "objc/message.h", OBJC_LANG)
+// void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...)
+LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", "objc/message.h", OBJC_LANG)
+//   id objc_getClass(const char *name)
+LIBBUILTIN(objc_getClass, "GcC*",   "f",     "objc/runtime.h", OBJC_LANG)
+//   id objc_getMetaClass(const char *name)
+LIBBUILTIN(objc_getMetaClass, "GcC*",   "f", "objc/runtime.h", OBJC_LANG)
+// void objc_enumerationMutation(id)
+LIBBUILTIN(objc_enumerationMutation, "vG", "f", "objc/runtime.h", OBJC_LANG)
+
+// id objc_read_weak(id *location)
+LIBBUILTIN(objc_read_weak, "GG*", "f", "objc/objc-auto.h", OBJC_LANG)
+// id objc_assign_weak(id value, id *location)
+LIBBUILTIN(objc_assign_weak, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+// id objc_assign_ivar(id value, id dest, ptrdiff_t offset)
+LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "objc/objc-auto.h", OBJC_LANG)
+// id objc_assign_global(id val, id *dest)
+LIBBUILTIN(objc_assign_global, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+// id objc_assign_strongCast(id val, id *dest
+LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+
+// id objc_exception_extract(void *localExceptionData)
+LIBBUILTIN(objc_exception_extract, "Gv*", "f", "objc/objc-exception.h", OBJC_LANG)
+// void objc_exception_try_enter(void *localExceptionData)
+LIBBUILTIN(objc_exception_try_enter, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
+// void objc_exception_try_exit(void *localExceptionData)
+LIBBUILTIN(objc_exception_try_exit, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
+// int objc_exception_match(Class exceptionClass, id exception)
+LIBBUILTIN(objc_exception_match, "iGG", "f", "objc/objc-exception.h", OBJC_LANG)
+// void objc_exception_throw(id exception)
+LIBBUILTIN(objc_exception_throw, "vG", "f", "objc/objc-exception.h", OBJC_LANG)
+
+// int objc_sync_enter(id obj)
+LIBBUILTIN(objc_sync_enter, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
+// int objc_sync_exit(id obj)
+LIBBUILTIN(objc_sync_exit, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
+
+BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF")
+
+// void NSLog(NSString *fmt, ...)
+LIBBUILTIN(NSLog, "vG.", "fp:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
+// void NSLogv(NSString *fmt, va_list args)
+LIBBUILTIN(NSLogv, "vGa", "fP:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
+
+// Builtin math library functions
+LIBBUILTIN(atan2, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atan2f, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atan2l, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(abs, "ii", "fnc", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(labs, "LiLi", "fnc", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(llabs, "LLiLLi", "fnc", "stdlib.h", ALL_LANGUAGES)
+
+LIBBUILTIN(copysign, "ddd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(copysignf, "fff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(copysignl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fabsl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(frexp, "ddi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(frexpf, "ffi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(frexpl, "LdLdi*", "fn", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ldexp, "ddi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ldexpf, "ffi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ldexpl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(nan,  "dcC*", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nanf, "fcC*", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nanl, "LdcC*", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(powl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(acos, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acosf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(acosh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acoshf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acoshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(asin, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asinf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(asinh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(atan, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atanf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cbrt, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceill, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cos, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cosf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cosh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(coshf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(coshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(erf, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erff, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erfl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(erfc, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erfcf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erfcl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(exp, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(expf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(expl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(exp2, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2f, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(expm1, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(expm1f, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(expm1l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fdim, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fdimf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fdiml, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(floor, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floorf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floorl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fma, "dddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaf, "ffff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmal, "LdLdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fmax, "ddd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaxf, "fff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaxl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(fmin, "ddd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fminf, "fff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fminl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(hypot, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(hypotf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(hypotl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(lgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(llrintl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(llround, "LLid", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(llroundf, "LLif", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(llroundl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(log, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(logf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(logl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(log10, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log10f, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log10l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(log1p, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log1pf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log1pl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(log2, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2f, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(logb, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(logbf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(logbl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(lrint, "Lid", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lrintf, "Lif", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lrintl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(lround, "Lid", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lroundf, "Lif", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lroundl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(nearbyint, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nearbyintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nearbyintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(nextafter, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nextafterf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nextafterl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(nexttoward, "ddLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nexttowardf, "ffLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nexttowardl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(round, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(scalbln, "ddLi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalblnf, "ffLi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalblnl, "LdLdLi", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(scalbn, "ddi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalbnf, "ffi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalbnl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(sin, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sinf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(sinh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(sqrt, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sqrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sqrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(tan, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tanf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(tanh, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(tgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cabs, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabsf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabsl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cacos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cacosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(carg, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cargf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cargl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(casin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(casinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(catan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(catanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ccos, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ccosh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccoshf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccoshl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cexp, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexpf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexpl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(clog, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clogf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clogl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(cpow, "XdXdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpowf, "XfXfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpowl, "XLdXLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(csin, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(csinh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(csqrt, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrtf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrtl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ctan, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+LIBBUILTIN(ctanh, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+
+// __sinpi and friends are OS X specific library functions, but otherwise much
+// like the standard (non-complex) sin (etc).
+LIBBUILTIN(__sinpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__sinpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__cospi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__cospif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__tanpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__tanpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+// Similarly, __exp10 is OS X only
+LIBBUILTIN(__exp10, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__exp10f, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+// Blocks runtime Builtin math library functions
+LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
+LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
+// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+
+// Annotation function
+BUILTIN(__builtin_annotation, "v.", "tn")
+
+// Multiprecision Arithmetic Builtins.
+BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
+BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
+BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n")
+BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n")
+BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_subcb, "UcUcCUcCUcCUc*", "n")
+BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n")
+BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n")
+BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
+BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
+
+// Checked Arithmetic Builtins for Security.
+BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n")
+BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n")
+BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "n")
+BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "n")
+BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "n")
+BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "n")
+BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "n")
+BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "n")
+BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "n")
+BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "n")
+BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "n")
+BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "n")
+BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "n")
+BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "n")
+BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
+
+// Clang builtins (not available in GCC).
+BUILTIN(__builtin_addressof, "v*v&", "nct")
+BUILTIN(__builtin_operator_new, "v*z", "c")
+BUILTIN(__builtin_operator_delete, "vv*", "n")
+
+#undef BUILTIN
+#undef LIBBUILTIN
+#undef LANGBUILTIN
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
new file mode 100644
index 0000000..f9d30e4
--- /dev/null
+++ b/include/clang/Basic/Builtins.h
@@ -0,0 +1,188 @@
+//===--- Builtins.h - Builtin function header -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines enum values for all the target-independent builtin
+/// functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_BUILTINS_H
+#define LLVM_CLANG_BASIC_BUILTINS_H
+
+#include "clang/Basic/LLVM.h"
+#include <cstring>
+
+// VC++ defines 'alloca' as an object-like macro, which interferes with our
+// builtins.
+#undef alloca
+
+namespace clang {
+  class TargetInfo;
+  class IdentifierTable;
+  class ASTContext;
+  class QualType;
+  class LangOptions;
+  
+  enum LanguageID {
+    GNU_LANG = 0x1,  // builtin requires GNU mode.
+    C_LANG = 0x2,    // builtin for c only.
+    CXX_LANG = 0x4,  // builtin for cplusplus only.
+    OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
+    MS_LANG = 0x10,  // builtin requires MS mode.
+    ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
+    ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG,  // builtin requires GNU mode.
+    ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG     // builtin requires MS mode.
+  };
+  
+namespace Builtin {
+enum ID {
+  NotBuiltin  = 0,      // This is not a builtin function.
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/Builtins.def"
+  FirstTSBuiltin
+};
+
+struct Info {
+  const char *Name, *Type, *Attributes, *HeaderName;
+  LanguageID builtin_lang;
+
+  bool operator==(const Info &RHS) const {
+    return !strcmp(Name, RHS.Name) &&
+           !strcmp(Type, RHS.Type) &&
+           !strcmp(Attributes, RHS.Attributes);
+  }
+  bool operator!=(const Info &RHS) const { return !(*this == RHS); }
+};
+
+/// \brief Holds information about both target-independent and
+/// target-specific builtins, allowing easy queries by clients.
+class Context {
+  const Info *TSRecords;
+  unsigned NumTSRecords;
+public:
+  Context();
+
+  /// \brief Perform target-specific initialization
+  void InitializeTarget(const TargetInfo &Target);
+  
+  /// \brief Mark the identifiers for all the builtins with their
+  /// appropriate builtin ID # and mark any non-portable builtin identifiers as
+  /// such.
+  void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts);
+
+  /// \brief Populate the vector with the names of all of the builtins.
+  void GetBuiltinNames(SmallVectorImpl<const char *> &Names);
+
+  /// \brief Return the identifier name for the specified builtin,
+  /// e.g. "__builtin_abs".
+  const char *GetName(unsigned ID) const {
+    return GetRecord(ID).Name;
+  }
+
+  /// \brief Get the type descriptor string for the specified builtin.
+  const char *GetTypeString(unsigned ID) const {
+    return GetRecord(ID).Type;
+  }
+
+  /// \brief Return true if this function has no side effects and doesn't
+  /// read memory.
+  bool isConst(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'c') != nullptr;
+  }
+
+  /// \brief Return true if we know this builtin never throws an exception.
+  bool isNoThrow(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'n') != nullptr;
+  }
+
+  /// \brief Return true if we know this builtin never returns.
+  bool isNoReturn(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'r') != nullptr;
+  }
+
+  /// \brief Return true if we know this builtin can return twice.
+  bool isReturnsTwice(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'j') != nullptr;
+  }
+
+  /// \brief Returns true if this builtin does not perform the side-effects
+  /// of its arguments.
+  bool isUnevaluated(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'u') != nullptr;
+  }
+
+  /// \brief Return true if this is a builtin for a libc/libm function,
+  /// with a "__builtin_" prefix (e.g. __builtin_abs).
+  bool isLibFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'F') != nullptr;
+  }
+
+  /// \brief Determines whether this builtin is a predefined libc/libm
+  /// function, such as "malloc", where we know the signature a
+  /// priori.
+  bool isPredefinedLibFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'f') != nullptr;
+  }
+
+  /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
+  /// function, such as "__clear_cache", where we know the signature a
+  /// priori.
+  bool isPredefinedRuntimeFunction(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'i') != nullptr;
+  }
+
+  /// \brief Determines whether this builtin has custom typechecking.
+  bool hasCustomTypechecking(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 't') != nullptr;
+  }
+
+  /// \brief Completely forget that the given ID was ever considered a builtin,
+  /// e.g., because the user provided a conflicting signature.
+  void ForgetBuiltin(unsigned ID, IdentifierTable &Table);
+  
+  /// \brief If this is a library function that comes from a specific
+  /// header, retrieve that header name.
+  const char *getHeaderName(unsigned ID) const {
+    return GetRecord(ID).HeaderName;
+  }
+
+  /// \brief Determine whether this builtin is like printf in its
+  /// formatting rules and, if so, set the index to the format string
+  /// argument and whether this function as a va_list argument.
+  bool isPrintfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+
+  /// \brief Determine whether this builtin is like scanf in its
+  /// formatting rules and, if so, set the index to the format string
+  /// argument and whether this function as a va_list argument.
+  bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+
+  /// \brief Return true if this function has no side effects and doesn't
+  /// read memory, except for possibly errno.
+  ///
+  /// Such functions can be const when the MathErrno lang option is disabled.
+  bool isConstWithoutErrno(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'e') != nullptr;
+  }
+
+private:
+  const Info &GetRecord(unsigned ID) const;
+
+  /// \brief Is this builtin supported according to the given language options?
+  bool BuiltinIsSupported(const Builtin::Info &BuiltinInfo,
+                          const LangOptions &LangOpts);
+
+  /// \brief Helper function for isPrintfLike and isScanfLike.
+  bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
+              const char *Fmt) const;
+};
+
+}
+} // end namespace clang
+#endif
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
new file mode 100644
index 0000000..695ecf9
--- /dev/null
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -0,0 +1,53 @@
+//==- BuiltinsAArch64.def - AArch64 Builtin function database ----*- 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 AArch64-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// In libgcc
+BUILTIN(__clear_cache, "vv*v*", "i")
+
+BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
+BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
+BUILTIN(__builtin_arm_clrex, "v", "")
+
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
+
+// HINT
+BUILTIN(__builtin_arm_nop, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
+BUILTIN(__builtin_arm_sevl, "v", "")
+
+// CRC32
+BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
+BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
+
+// Memory barrier
+BUILTIN(__builtin_arm_dmb, "vUi", "nc")
+BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
new file mode 100644
index 0000000..2e5eac6
--- /dev/null
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -0,0 +1,100 @@
+//===--- BuiltinsARM.def - ARM Builtin function database ----*- 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 ARM-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+#   define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// In libgcc
+BUILTIN(__clear_cache, "vv*v*", "i")
+BUILTIN(__builtin_thread_pointer, "v*", "")
+
+// Saturating arithmetic
+BUILTIN(__builtin_arm_qadd, "iii", "nc")
+BUILTIN(__builtin_arm_qsub, "iii", "nc")
+BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
+BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
+
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+
+// Store and load exclusive
+BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
+BUILTIN(__builtin_arm_strexd, "iLLUiv*", "")
+
+BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
+BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
+BUILTIN(__builtin_arm_clrex, "v", "")
+
+// VFP
+BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc")
+BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc")
+BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc")
+BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc")
+
+// Coprocessor
+BUILTIN(__builtin_arm_mcr, "vUiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_mcr2, "vUiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_mrc, "UiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_mrc2, "UiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_cdp, "vUiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_mcrr, "vUiUiUiUiUi", "")
+BUILTIN(__builtin_arm_mcrr2, "vUiUiUiUiUi", "")
+
+// CRC32
+BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
+BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
+
+// HINT
+BUILTIN(__builtin_arm_nop, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
+BUILTIN(__builtin_arm_sevl, "v", "")
+
+// Data barrier
+BUILTIN(__builtin_arm_dmb, "vUi", "nc")
+BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
+
+// MSVC
+LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
+
+LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__ldrexd, "WiCDWi*", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor2, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor2, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+
+#undef BUILTIN
+#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
new file mode 100644
index 0000000..c071a46
--- /dev/null
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -0,0 +1,878 @@
+//===-- BuiltinsHexagon.def - Hexagon Builtin function database --*- 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 Hexagon-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// The builtins below are not autogenerated from iset.py.
+// Make sure you do not overwrite these.
+
+BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "")
+BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*ii", "")
+
+// The builtins above are not autogenerated from iset.py.
+// Make sure you do not overwrite these.
+
+BUILTIN(__builtin_HEXAGON_C2_cmpeq,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgt,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_bitsset,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_bitsclr,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsset,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgti,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgei,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmplt,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_cmpltu,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_bitsclri,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmpltei,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmplteui,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmpneq,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmplte,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_cmplteu,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_and,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_or,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_xor,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_andn,"bii","")
+BUILTIN(__builtin_HEXAGON_C2_not,"bi","")
+BUILTIN(__builtin_HEXAGON_C2_orn,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_and_and,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_and_or,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_or_and,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_or_or,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_and_andn,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_and_orn,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_or_andn,"biii","")
+BUILTIN(__builtin_HEXAGON_C4_or_orn,"biii","")
+BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"bi","")
+BUILTIN(__builtin_HEXAGON_C2_any8,"bi","")
+BUILTIN(__builtin_HEXAGON_C2_all8,"bi","")
+BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","")
+BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_muxii,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_muxir,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_muxri,"iiii","")
+BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"bii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpheq,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgt,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgti,"bii","")
+BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"bii","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"bLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"bLLii","")
+BUILTIN(__builtin_HEXAGON_A4_boundscheck,"biLLi","")
+BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"bLLii","")
+BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","")
+BUILTIN(__builtin_HEXAGON_C2_tfrrp,"bi","")
+BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"bii","")
+BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"bii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpysmi,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_macsip,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_macsin,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0,"ULLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_up,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyu_up,"Uiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpysu_up,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyi,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mpyui,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_maci,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_acci,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_accii,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_nacci,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_naccii,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_subacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addr,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyri_addi,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi,"iiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vmac2es,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrmac_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vrmpybuu,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vrmacbuu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vrmpybsu,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vrmacbsu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vmpybuu,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M5_vmpybsu,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M5_vmacbuu,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M5_vmacbsu,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M5_vdmpybsu,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M5_vdmacbsu,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacs_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacs_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpys_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpys_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacs_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacs_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1,"iii","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmaci_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmacr_s0,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc,"iLLii","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vcrotate,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc,"LLiLLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S4_vrcrotate,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_vcnegh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vrcnegh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_M4_pmpyw,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M4_vpmpyh,"LLiii","")
+BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_A2_add,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_sub,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addsat,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subsat,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addi,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_aslh,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_asrh,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_addp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_addpsat,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_addsp,"LLiiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_subp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_neg,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_negsat,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_abs,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_abssat,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_vconj,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_negp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_absp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_max,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_maxu,"Uiii","")
+BUILTIN(__builtin_HEXAGON_A2_min,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_minu,"Uiii","")
+BUILTIN(__builtin_HEXAGON_A2_maxp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_maxup,"ULLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_minp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_minup,"ULLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_tfr,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrsi,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_tfrpi,"LLii","")
+BUILTIN(__builtin_HEXAGON_A2_zxtb,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_sxtb,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_zxth,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_sxth,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_combinew,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_combineri,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_combineir,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_combineii,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_combine_hh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_combine_hl,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_combine_lh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_combine_ll,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_tfril,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_tfrih,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_and,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_or,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_xor,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_not,"ii","")
+BUILTIN(__builtin_HEXAGON_M2_xor_xacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_xor_xacc,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_andn,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_orn,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_andnp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_ornp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_addaddi,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_subaddi,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_and_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_and_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_and_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_and_xor,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_or_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_or_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_or_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_or_xor,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_or_andix,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_or_andi,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_or_ori,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_xor_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_xor_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_M4_xor_andn,"iiii","")
+BUILTIN(__builtin_HEXAGON_A2_subri,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_andir,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_orir,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_andp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_orp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_xorp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_notp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_sxtw,"LLii","")
+BUILTIN(__builtin_HEXAGON_A2_sat,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_roundsat,"iLLi","")
+BUILTIN(__builtin_HEXAGON_A2_sath,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_satuh,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_satub,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_satb,"ii","")
+BUILTIN(__builtin_HEXAGON_A2_vaddub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddb_map,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddubs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vadduhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A5_vaddhubs,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vaddws,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxaddsubw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxaddsubh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_svavgh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svavghs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svnavgh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svaddh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svaddhs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svadduhs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svsubh,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svsubhs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_svsubuhs,"iii","")
+BUILTIN(__builtin_HEXAGON_A2_vraddub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vraddub_acc,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vraddh,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vradduh,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubb_map,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsububs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubuhs,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vsubws,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabsh,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabshsat,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabsw,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vabswsat,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vabsdiffw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_M2_vabsdiffh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vrsadub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgwcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavgwcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavghcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavghcr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguwr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavgubr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavguhr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vavghr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vnavghr,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_round_ri,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_round_rr,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_round_ri_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_round_rr_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_cround_ri,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_cround_rr,"iii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminuh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxuh,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrminuw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A4_vrmaxuw,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_A2_vminb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxub,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminuh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxuh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vminuw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A2_vmaxuw,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_A4_modwrapu,"iii","")
+BUILTIN(__builtin_HEXAGON_F2_sfadd,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sfsub,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sfmpy,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sffma,"ffff","")
+BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","")
+BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","")
+BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","")
+BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"bff","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"bff","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"bff","")
+BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"bff","")
+BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sfclass,"bfi","")
+BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fi","")
+BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fi","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","")
+BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","")
+BUILTIN(__builtin_HEXAGON_F2_dfadd,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dfsub,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dfmpy,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffma,"dddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffms,"dddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffma_lib,"dddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffms_lib,"dddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffma_sc,"ddddi","")
+BUILTIN(__builtin_HEXAGON_F2_dfmax,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dfmin,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"bdd","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"bdd","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"bdd","")
+BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"bdd","")
+BUILTIN(__builtin_HEXAGON_F2_dfclass,"bdi","")
+BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"di","")
+BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"di","")
+BUILTIN(__builtin_HEXAGON_F2_dffixupn,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffixupd,"ddd","")
+BUILTIN(__builtin_HEXAGON_F2_dffixupr,"dd","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","")
+BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_uw2df,"di","")
+BUILTIN(__builtin_HEXAGON_F2_conv_w2sf,"fi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_w2df,"di","")
+BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf,"fLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_ud2df,"dLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_d2sf,"fLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_d2df,"dLLi","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw,"if","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2w,"if","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud,"LLif","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2d,"LLif","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2uw,"id","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2w,"id","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2ud,"LLid","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2d,"LLid","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop,"if","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop,"if","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop,"LLif","")
+BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop,"LLif","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop,"id","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop,"id","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop,"LLid","")
+BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop,"LLid","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S4_lsli,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_addasl_rrri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_valignib,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_valignrb,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vspliceib,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsplicerb,"LLiLLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsplatrh,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsplatrb,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_insert,"iiiii","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax,"iiiii","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax,"iiiii","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax,"iiiii","")
+BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax,"iiiii","")
+BUILTIN(__builtin_HEXAGON_A4_bitspliti,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A4_bitsplit,"LLiii","")
+BUILTIN(__builtin_HEXAGON_S4_extract,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_extractu,"iiii","")
+BUILTIN(__builtin_HEXAGON_S2_insertp,"LLiLLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S4_extractp,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_extractup,"LLiLLiii","")
+BUILTIN(__builtin_HEXAGON_S2_insert_rp,"iiiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_extract_rp,"iiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"bii","")
+BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"bii","")
+BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"bii","")
+BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"bii","")
+BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S5_asrhub_sat,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_i_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asr_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_asl_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw,"LLiLLii","")
+BUILTIN(__builtin_HEXAGON_S2_vrndpackwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsxtbh,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_vzxtbh,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsathub,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_svsathub,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_svsathb,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_vsathb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunohb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunewh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunowh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vtrunehb,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsxthw,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_vzxthw,"LLii","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwuh,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_packhl,"LLiii","")
+BUILTIN(__builtin_HEXAGON_A2_swiz,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_shuffob,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_shuffeb,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_shuffoh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_shuffeh,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S5_popcountp,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S4_parity,"iii","")
+BUILTIN(__builtin_HEXAGON_S2_parityp,"iLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_lfsp,"LLiLLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_clbnorm,"ii","")
+BUILTIN(__builtin_HEXAGON_S4_clbaddi,"iii","")
+BUILTIN(__builtin_HEXAGON_S4_clbpnorm,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S4_clbpaddi,"iLLii","")
+BUILTIN(__builtin_HEXAGON_S2_clb,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_cl0,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_cl1,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_clbp,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_cl0p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_cl1p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_brev,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_brevp,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_ct0,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_ct1,"ii","")
+BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
+BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
new file mode 100644
index 0000000..2d217f7
--- /dev/null
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -0,0 +1,900 @@
+//===-- BuiltinsMips.def - Mips Builtin function database --------*- 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 MIPS-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// MIPS DSP Rev 1
+
+// Add/subtract with optional saturation
+BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_subu_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_subu_s_qb, "V4ScV4ScV4Sc", "n")
+
+BUILTIN(__builtin_mips_addq_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_addq_s_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subq_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subq_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_madd, "LLiLLiii", "nc")
+BUILTIN(__builtin_mips_maddu, "LLiLLiUiUi", "nc")
+BUILTIN(__builtin_mips_msub, "LLiLLiii", "nc")
+BUILTIN(__builtin_mips_msubu, "LLiLLiUiUi", "nc")
+
+BUILTIN(__builtin_mips_addq_s_w, "iii", "n")
+BUILTIN(__builtin_mips_subq_s_w, "iii", "n")
+
+BUILTIN(__builtin_mips_addsc, "iii", "n")
+BUILTIN(__builtin_mips_addwc, "iii", "n")
+
+BUILTIN(__builtin_mips_modsub, "iii", "nc")
+
+BUILTIN(__builtin_mips_raddu_w_qb, "iV4Sc", "nc")
+
+BUILTIN(__builtin_mips_absq_s_ph, "V2sV2s", "n")
+BUILTIN(__builtin_mips_absq_s_w, "ii", "n")
+
+BUILTIN(__builtin_mips_precrq_qb_ph, "V4ScV2sV2s", "nc")
+BUILTIN(__builtin_mips_precrqu_s_qb_ph, "V4ScV2sV2s", "n")
+BUILTIN(__builtin_mips_precrq_ph_w, "V2sii", "nc")
+BUILTIN(__builtin_mips_precrq_rs_ph_w, "V2sii", "n")
+BUILTIN(__builtin_mips_preceq_w_phl, "iV2s", "nc")
+BUILTIN(__builtin_mips_preceq_w_phr, "iV2s", "nc")
+BUILTIN(__builtin_mips_precequ_ph_qbl, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_precequ_ph_qbr, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_precequ_ph_qbla, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_precequ_ph_qbra, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_preceu_ph_qbl, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_preceu_ph_qbr, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_preceu_ph_qbla, "V2sV4Sc", "nc")
+BUILTIN(__builtin_mips_preceu_ph_qbra, "V2sV4Sc", "nc")
+
+BUILTIN(__builtin_mips_shll_qb, "V4ScV4Sci", "n")
+BUILTIN(__builtin_mips_shrl_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shll_ph, "V2sV2si", "n")
+BUILTIN(__builtin_mips_shll_s_ph, "V2sV2si", "n")
+BUILTIN(__builtin_mips_shra_ph, "V2sV2si", "nc")
+BUILTIN(__builtin_mips_shra_r_ph, "V2sV2si", "nc")
+BUILTIN(__builtin_mips_shll_s_w, "iii", "n")
+BUILTIN(__builtin_mips_shra_r_w, "iii", "nc")
+BUILTIN(__builtin_mips_shilo, "LLiLLii", "nc")
+
+BUILTIN(__builtin_mips_muleu_s_ph_qbl, "V2sV4ScV2s", "n")
+BUILTIN(__builtin_mips_muleu_s_ph_qbr, "V2sV4ScV2s", "n")
+BUILTIN(__builtin_mips_mulq_rs_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_muleq_s_w_phl, "iV2sV2s", "n")
+BUILTIN(__builtin_mips_muleq_s_w_phr, "iV2sV2s", "n")
+BUILTIN(__builtin_mips_mulsaq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_s_w_phl, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_s_w_phr, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_sa_w_phl, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_sa_w_phr, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_mult, "LLiii", "nc")
+BUILTIN(__builtin_mips_multu, "LLiUiUi", "nc")
+
+BUILTIN(__builtin_mips_dpau_h_qbl, "LLiLLiV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_dpau_h_qbr, "LLiLLiV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_dpsu_h_qbl, "LLiLLiV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_dpsu_h_qbr, "LLiLLiV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_dpaq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpsq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpaq_sa_l_w, "LLiLLiii", "n")
+BUILTIN(__builtin_mips_dpsq_sa_l_w, "LLiLLiii", "n")
+
+BUILTIN(__builtin_mips_cmpu_eq_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpu_lt_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpu_le_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_eq_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_lt_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_le_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmp_eq_ph, "vV2sV2s", "n")
+BUILTIN(__builtin_mips_cmp_lt_ph, "vV2sV2s", "n")
+BUILTIN(__builtin_mips_cmp_le_ph, "vV2sV2s", "n")
+
+BUILTIN(__builtin_mips_extr_s_h, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_rs_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_r_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extp, "iLLii", "n")
+BUILTIN(__builtin_mips_extpdp, "iLLii", "n")
+
+BUILTIN(__builtin_mips_wrdsp, "viIi", "n")
+BUILTIN(__builtin_mips_rddsp, "iIi", "n")
+BUILTIN(__builtin_mips_insv, "iii", "n")
+BUILTIN(__builtin_mips_bitrev, "ii", "nc")
+BUILTIN(__builtin_mips_packrl_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_repl_qb, "V4Sci", "nc")
+BUILTIN(__builtin_mips_repl_ph, "V2si", "nc")
+BUILTIN(__builtin_mips_pick_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_pick_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mthlip, "LLiLLii", "n")
+BUILTIN(__builtin_mips_bposge32, "i", "n")
+BUILTIN(__builtin_mips_lbux, "iv*i", "n")
+BUILTIN(__builtin_mips_lhx, "iv*i", "n")
+BUILTIN(__builtin_mips_lwx, "iv*i", "n")
+
+// MIPS DSP Rev 2
+
+BUILTIN(__builtin_mips_absq_s_qb, "V4ScV4Sc", "n")
+
+BUILTIN(__builtin_mips_addqh_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_addqh_r_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_addqh_w, "iii", "nc")
+BUILTIN(__builtin_mips_addqh_r_w, "iii", "nc")
+
+BUILTIN(__builtin_mips_addu_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_addu_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_adduh_qb, "V4ScV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_adduh_r_qb, "V4ScV4ScV4Sc", "nc")
+
+BUILTIN(__builtin_mips_append, "iiiIi", "nc")
+BUILTIN(__builtin_mips_balign, "iiiIi", "nc")
+
+BUILTIN(__builtin_mips_cmpgdu_eq_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgdu_lt_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgdu_le_qb, "iV4ScV4Sc", "n")
+
+BUILTIN(__builtin_mips_dpa_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dps_w_ph, "LLiLLiV2sV2s", "nc")
+
+BUILTIN(__builtin_mips_dpaqx_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpaqx_sa_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpax_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dpsx_w_ph, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_dpsqx_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpsqx_sa_w_ph, "LLiLLiV2sV2s", "n")
+
+BUILTIN(__builtin_mips_mul_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mul_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_mulq_rs_w, "iii", "n")
+BUILTIN(__builtin_mips_mulq_s_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mulq_s_w, "iii", "n")
+BUILTIN(__builtin_mips_mulsa_w_ph, "LLiLLiV2sV2s", "nc")
+
+BUILTIN(__builtin_mips_precr_qb_ph, "V4ScV2sV2s", "n")
+BUILTIN(__builtin_mips_precr_sra_ph_w, "V2siiIi", "nc")
+BUILTIN(__builtin_mips_precr_sra_r_ph_w, "V2siiIi", "nc")
+
+BUILTIN(__builtin_mips_prepend, "iiiIi", "nc")
+
+BUILTIN(__builtin_mips_shra_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shra_r_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shrl_ph, "V2sV2si", "nc")
+
+BUILTIN(__builtin_mips_subqh_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_subqh_r_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_subqh_w, "iii", "nc")
+BUILTIN(__builtin_mips_subqh_r_w, "iii", "nc")
+
+BUILTIN(__builtin_mips_subu_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subu_s_ph, "V2sV2sV2s", "n")
+
+BUILTIN(__builtin_mips_subuh_qb, "V4ScV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_subuh_r_qb, "V4ScV4ScV4Sc", "nc")
+
+// MIPS MSA
+
+BUILTIN(__builtin_msa_add_a_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_add_a_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_add_a_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_add_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_adds_a_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_adds_a_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_adds_a_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_adds_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_adds_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_adds_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_adds_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_adds_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_adds_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_adds_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_adds_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_adds_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_addv_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_addv_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_addv_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_addv_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_addvi_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_addvi_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_addvi_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_addvi_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_and_v, "V16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_andi_b, "V16UcV16UcIUi", "nc")
+
+BUILTIN(__builtin_msa_asub_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_asub_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_asub_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_asub_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_asub_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_asub_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_asub_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_asub_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_ave_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_ave_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_ave_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_ave_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_ave_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_ave_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_ave_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_ave_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_aver_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_aver_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_aver_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_aver_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_aver_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_aver_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_aver_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_aver_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bclr_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_bclr_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_bclr_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_bclr_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bclri_b, "V16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_bclri_h, "V8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_bclri_w, "V4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_bclri_d, "V2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_binsl_b, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_binsl_h, "V8UsV8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_binsl_w, "V4UiV4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_binsl_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_binsli_b, "V16UcV16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_binsli_h, "V8UsV8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_binsli_w, "V4UiV4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_binsli_d, "V2ULLiV2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_binsr_b, "V16UcV16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_binsr_h, "V8UsV8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_binsr_w, "V4UiV4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_binsr_d, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_binsri_b, "V16UcV16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_binsri_h, "V8UsV8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_binsri_w, "V4UiV4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_binsri_d, "V2ULLiV2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_bmnz_v, "V16UcV16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_bmnzi_b, "V16UcV16UcV16UcIUi", "nc")
+
+BUILTIN(__builtin_msa_bmz_v, "V16UcV16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_bmzi_b, "V16UcV16UcV16UcIUi", "nc")
+
+BUILTIN(__builtin_msa_bneg_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_bneg_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_bneg_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_bneg_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bnegi_b, "V16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_bnegi_h, "V8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_bnegi_w, "V4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_bnegi_d, "V2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_bnz_b, "iV16Uc", "nc")
+BUILTIN(__builtin_msa_bnz_h, "iV8Us", "nc")
+BUILTIN(__builtin_msa_bnz_w, "iV4Ui", "nc")
+BUILTIN(__builtin_msa_bnz_d, "iV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bnz_v, "iV16Uc", "nc")
+
+BUILTIN(__builtin_msa_bsel_v, "V16UcV16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_bseli_b, "V16UcV16UcV16UcIUi", "nc")
+
+BUILTIN(__builtin_msa_bset_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_bset_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_bset_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_bset_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bseti_b, "V16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_bseti_h, "V8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_bseti_w, "V4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_bseti_d, "V2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_bz_b, "iV16Uc", "nc")
+BUILTIN(__builtin_msa_bz_h, "iV8Us", "nc")
+BUILTIN(__builtin_msa_bz_w, "iV4Ui", "nc")
+BUILTIN(__builtin_msa_bz_d, "iV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_bz_v, "iV16Uc", "nc")
+
+BUILTIN(__builtin_msa_ceq_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_ceq_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_ceq_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_ceq_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_ceqi_b, "V16ScV16ScISi", "nc")
+BUILTIN(__builtin_msa_ceqi_h, "V8SsV8SsISi", "nc")
+BUILTIN(__builtin_msa_ceqi_w, "V4SiV4SiISi", "nc")
+BUILTIN(__builtin_msa_ceqi_d, "V2SLLiV2SLLiISi", "nc")
+
+BUILTIN(__builtin_msa_cfcmsa, "iIi", "n")
+
+BUILTIN(__builtin_msa_cle_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_cle_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_cle_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_cle_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_cle_u_b, "V16ScV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_cle_u_h, "V8SsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_cle_u_w, "V4SiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_cle_u_d, "V2SLLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_clei_s_b, "V16ScV16ScISi", "nc")
+BUILTIN(__builtin_msa_clei_s_h, "V8SsV8SsISi", "nc")
+BUILTIN(__builtin_msa_clei_s_w, "V4SiV4SiISi", "nc")
+BUILTIN(__builtin_msa_clei_s_d, "V2SLLiV2SLLiISi", "nc")
+
+BUILTIN(__builtin_msa_clei_u_b, "V16ScV16UcIUi", "nc")
+BUILTIN(__builtin_msa_clei_u_h, "V8SsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_clei_u_w, "V4SiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_clei_u_d, "V2SLLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_clt_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_clt_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_clt_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_clt_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_clt_u_b, "V16ScV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_clt_u_h, "V8SsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_clt_u_w, "V4SiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_clt_u_d, "V2SLLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_clti_s_b, "V16ScV16ScISi", "nc")
+BUILTIN(__builtin_msa_clti_s_h, "V8SsV8SsISi", "nc")
+BUILTIN(__builtin_msa_clti_s_w, "V4SiV4SiISi", "nc")
+BUILTIN(__builtin_msa_clti_s_d, "V2SLLiV2SLLiISi", "nc")
+
+BUILTIN(__builtin_msa_clti_u_b, "V16ScV16UcIUi", "nc")
+BUILTIN(__builtin_msa_clti_u_h, "V8SsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_clti_u_w, "V4SiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_clti_u_d, "V2SLLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_copy_s_b, "iV16ScIUi", "nc")
+BUILTIN(__builtin_msa_copy_s_h, "iV8SsIUi", "nc")
+BUILTIN(__builtin_msa_copy_s_w, "iV4SiIUi", "nc")
+BUILTIN(__builtin_msa_copy_s_d, "LLiV2SLLiIUi", "nc")
+
+BUILTIN(__builtin_msa_copy_u_b, "iV16UcIUi", "nc")
+BUILTIN(__builtin_msa_copy_u_h, "iV8UsIUi", "nc")
+BUILTIN(__builtin_msa_copy_u_w, "iV4UiIUi", "nc")
+BUILTIN(__builtin_msa_copy_u_d, "LLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_ctcmsa, "vIii", "n")
+
+BUILTIN(__builtin_msa_div_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_div_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_div_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_div_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_div_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_div_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_div_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_div_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_dotp_s_h, "V8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_dotp_s_w, "V4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_dotp_s_d, "V2SLLiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_dotp_u_h, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_dotp_u_w, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_dotp_u_d, "V2ULLiV4UiV4Ui", "nc")
+
+BUILTIN(__builtin_msa_dpadd_s_h, "V8SsV8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_dpadd_s_w, "V4SiV4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_dpadd_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_dpadd_u_h, "V8UsV8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_dpadd_u_w, "V4UiV4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_dpadd_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc")
+
+BUILTIN(__builtin_msa_dpsub_s_h, "V8SsV8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_dpsub_s_w, "V4SiV4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_dpsub_s_d, "V2SLLiV2SLLiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_dpsub_u_h, "V8UsV8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_dpsub_u_w, "V4UiV4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_dpsub_u_d, "V2ULLiV2ULLiV4UiV4Ui", "nc")
+
+BUILTIN(__builtin_msa_fadd_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fadd_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcaf_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcaf_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fceq_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fceq_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fclass_w, "V4iV4f", "nc")
+BUILTIN(__builtin_msa_fclass_d, "V2LLiV2d", "nc")
+
+BUILTIN(__builtin_msa_fcle_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcle_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fclt_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fclt_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcne_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcne_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcor_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcor_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcueq_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcueq_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcule_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcule_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcult_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcult_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcun_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcun_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fcune_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fcune_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fdiv_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fdiv_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fexdo_h, "V8hV4fV4f", "nc")
+BUILTIN(__builtin_msa_fexdo_w, "V4fV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fexp2_w, "V4fV4fV4i", "nc")
+BUILTIN(__builtin_msa_fexp2_d, "V2dV2dV2LLi", "nc")
+
+BUILTIN(__builtin_msa_fexupl_w, "V4fV8h", "nc")
+BUILTIN(__builtin_msa_fexupl_d, "V2dV4f", "nc")
+
+BUILTIN(__builtin_msa_fexupr_w, "V4fV8h", "nc")
+BUILTIN(__builtin_msa_fexupr_d, "V2dV4f", "nc")
+
+BUILTIN(__builtin_msa_ffint_s_w, "V4fV4Si", "nc")
+BUILTIN(__builtin_msa_ffint_s_d, "V2dV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_ffint_u_w, "V4fV4Ui", "nc")
+BUILTIN(__builtin_msa_ffint_u_d, "V2dV2ULLi", "nc")
+
+// ffql uses integers since long _Fract is not implemented
+BUILTIN(__builtin_msa_ffql_w, "V4fV8Ss", "nc")
+BUILTIN(__builtin_msa_ffql_d, "V2dV4Si", "nc")
+
+// ffqr uses integers since long _Fract is not implemented
+BUILTIN(__builtin_msa_ffqr_w, "V4fV8Ss", "nc")
+BUILTIN(__builtin_msa_ffqr_d, "V2dV4Si", "nc")
+
+BUILTIN(__builtin_msa_fill_b, "V16Sci", "nc")
+BUILTIN(__builtin_msa_fill_h, "V8Ssi", "nc")
+BUILTIN(__builtin_msa_fill_w, "V4Sii", "nc")
+BUILTIN(__builtin_msa_fill_d, "V2SLLiLLi", "nc")
+
+BUILTIN(__builtin_msa_flog2_w, "V4fV4f", "nc")
+BUILTIN(__builtin_msa_flog2_d, "V2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmadd_w, "V4fV4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmadd_d, "V2dV2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmax_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmax_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmax_a_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmax_a_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmin_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmin_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmin_a_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmin_a_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmsub_w, "V4fV4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmsub_d, "V2dV2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fmul_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fmul_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_frint_w, "V4fV4f", "nc")
+BUILTIN(__builtin_msa_frint_d, "V2dV2d", "nc")
+
+BUILTIN(__builtin_msa_frcp_w, "V4fV4f", "nc")
+BUILTIN(__builtin_msa_frcp_d, "V2dV2d", "nc")
+
+BUILTIN(__builtin_msa_frsqrt_w, "V4fV4f", "nc")
+BUILTIN(__builtin_msa_frsqrt_d, "V2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsaf_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsaf_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fseq_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fseq_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsle_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsle_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fslt_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fslt_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsne_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsne_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsor_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsor_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsqrt_w, "V4fV4f", "nc")
+BUILTIN(__builtin_msa_fsqrt_d, "V2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsub_w, "V4fV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsub_d, "V2dV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsueq_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsueq_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsule_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsule_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsult_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsult_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsun_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsun_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_fsune_w, "V4iV4fV4f", "nc")
+BUILTIN(__builtin_msa_fsune_d, "V2LLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_ftint_s_w, "V4SiV4f", "nc")
+BUILTIN(__builtin_msa_ftint_s_d, "V2SLLiV2d", "nc")
+
+BUILTIN(__builtin_msa_ftint_u_w, "V4UiV4f", "nc")
+BUILTIN(__builtin_msa_ftint_u_d, "V2ULLiV2d", "nc")
+
+BUILTIN(__builtin_msa_ftq_h, "V4UiV4fV4f", "nc")
+BUILTIN(__builtin_msa_ftq_w, "V2ULLiV2dV2d", "nc")
+
+BUILTIN(__builtin_msa_ftrunc_s_w, "V4SiV4f", "nc")
+BUILTIN(__builtin_msa_ftrunc_s_d, "V2SLLiV2d", "nc")
+
+BUILTIN(__builtin_msa_ftrunc_u_w, "V4UiV4f", "nc")
+BUILTIN(__builtin_msa_ftrunc_u_d, "V2ULLiV2d", "nc")
+
+BUILTIN(__builtin_msa_hadd_s_h, "V8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_hadd_s_w, "V4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_hadd_s_d, "V2SLLiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_hadd_u_h, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_hadd_u_w, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_hadd_u_d, "V2ULLiV4UiV4Ui", "nc")
+
+BUILTIN(__builtin_msa_hsub_s_h, "V8SsV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_hsub_s_w, "V4SiV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_hsub_s_d, "V2SLLiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_hsub_u_h, "V8UsV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_hsub_u_w, "V4UiV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_hsub_u_d, "V2ULLiV4UiV4Ui", "nc")
+
+BUILTIN(__builtin_msa_ilvev_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_ilvev_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_ilvev_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_ilvev_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_ilvl_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_ilvl_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_ilvl_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_ilvl_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_ilvod_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_ilvod_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_ilvod_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_ilvod_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_ilvr_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_ilvr_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_ilvr_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_ilvr_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_insert_b, "V16ScV16ScIUii", "nc")
+BUILTIN(__builtin_msa_insert_h, "V8SsV8SsIUii", "nc")
+BUILTIN(__builtin_msa_insert_w, "V4SiV4SiIUii", "nc")
+BUILTIN(__builtin_msa_insert_d, "V2SLLiV2SLLiIUiLLi", "nc")
+
+BUILTIN(__builtin_msa_insve_b, "V16ScV16ScIUiV16Sc", "nc")
+BUILTIN(__builtin_msa_insve_h, "V8SsV8SsIUiV8Ss", "nc")
+BUILTIN(__builtin_msa_insve_w, "V4SiV4SiIUiV4Si", "nc")
+BUILTIN(__builtin_msa_insve_d, "V2SLLiV2SLLiIUiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_ld_b, "V16Scv*Ii", "nc")
+BUILTIN(__builtin_msa_ld_h, "V8Ssv*Ii", "nc")
+BUILTIN(__builtin_msa_ld_w, "V4Siv*Ii", "nc")
+BUILTIN(__builtin_msa_ld_d, "V2SLLiv*Ii", "nc")
+
+BUILTIN(__builtin_msa_ldi_b, "V16cIi", "nc")
+BUILTIN(__builtin_msa_ldi_h, "V8sIi", "nc")
+BUILTIN(__builtin_msa_ldi_w, "V4iIi", "nc")
+BUILTIN(__builtin_msa_ldi_d, "V2LLiIi", "nc")
+
+BUILTIN(__builtin_msa_madd_q_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_madd_q_w, "V4SiV4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_maddr_q_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_maddr_q_w, "V4SiV4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_maddv_b, "V16ScV16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_maddv_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_maddv_w, "V4SiV4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_maddv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_max_a_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_max_a_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_max_a_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_max_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_max_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_max_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_max_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_max_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_max_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_max_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_max_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_max_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_maxi_s_b, "V16ScV16ScIi", "nc")
+BUILTIN(__builtin_msa_maxi_s_h, "V8SsV8SsIi", "nc")
+BUILTIN(__builtin_msa_maxi_s_w, "V4SiV4SiIi", "nc")
+BUILTIN(__builtin_msa_maxi_s_d, "V2SLLiV2SLLiIi", "nc")
+
+BUILTIN(__builtin_msa_maxi_u_b, "V16UcV16UcIi", "nc")
+BUILTIN(__builtin_msa_maxi_u_h, "V8UsV8UsIi", "nc")
+BUILTIN(__builtin_msa_maxi_u_w, "V4UiV4UiIi", "nc")
+BUILTIN(__builtin_msa_maxi_u_d, "V2ULLiV2ULLiIi", "nc")
+
+BUILTIN(__builtin_msa_min_a_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_min_a_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_min_a_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_min_a_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_min_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_min_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_min_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_min_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_min_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_min_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_min_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_min_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_mini_s_b, "V16ScV16ScIi", "nc")
+BUILTIN(__builtin_msa_mini_s_h, "V8SsV8SsIi", "nc")
+BUILTIN(__builtin_msa_mini_s_w, "V4SiV4SiIi", "nc")
+BUILTIN(__builtin_msa_mini_s_d, "V2SLLiV2SLLiIi", "nc")
+
+BUILTIN(__builtin_msa_mini_u_b, "V16UcV16UcIi", "nc")
+BUILTIN(__builtin_msa_mini_u_h, "V8UsV8UsIi", "nc")
+BUILTIN(__builtin_msa_mini_u_w, "V4UiV4UiIi", "nc")
+BUILTIN(__builtin_msa_mini_u_d, "V2ULLiV2ULLiIi", "nc")
+
+BUILTIN(__builtin_msa_mod_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_mod_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_mod_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_mod_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_mod_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_mod_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_mod_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_mod_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_move_v, "V16ScV16Sc", "nc")
+
+BUILTIN(__builtin_msa_msub_q_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_msub_q_w, "V4SiV4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_msubr_q_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_msubr_q_w, "V4SiV4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_msubv_b, "V16ScV16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_msubv_h, "V8SsV8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_msubv_w, "V4SiV4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_msubv_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_mul_q_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_mul_q_w, "V4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_mulr_q_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_mulr_q_w, "V4SiV4SiV4Si", "nc")
+
+BUILTIN(__builtin_msa_mulv_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_mulv_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_mulv_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_mulv_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_nloc_b, "V16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_nloc_h, "V8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_nloc_w, "V4SiV4Si", "nc")
+BUILTIN(__builtin_msa_nloc_d, "V2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_nlzc_b, "V16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_nlzc_h, "V8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_nlzc_w, "V4SiV4Si", "nc")
+BUILTIN(__builtin_msa_nlzc_d, "V2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_nor_v, "V16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_nori_b, "V16UcV16cIUi", "nc")
+
+BUILTIN(__builtin_msa_or_v, "V16UcV16UcV16Uc", "nc")
+
+BUILTIN(__builtin_msa_ori_b, "V16UcV16UcIUi", "nc")
+
+BUILTIN(__builtin_msa_pckev_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_pckev_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_pckev_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_pckev_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_pckod_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_pckod_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_pckod_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_pckod_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_pcnt_b, "V16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_pcnt_h, "V8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_pcnt_w, "V4SiV4Si", "nc")
+BUILTIN(__builtin_msa_pcnt_d, "V2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_sat_s_b, "V16ScV16ScIUi", "nc")
+BUILTIN(__builtin_msa_sat_s_h, "V8SsV8SsIUi", "nc")
+BUILTIN(__builtin_msa_sat_s_w, "V4SiV4SiIUi", "nc")
+BUILTIN(__builtin_msa_sat_s_d, "V2SLLiV2SLLiIUi", "nc")
+
+BUILTIN(__builtin_msa_sat_u_b, "V16UcV16UcIUi", "nc")
+BUILTIN(__builtin_msa_sat_u_h, "V8UsV8UsIUi", "nc")
+BUILTIN(__builtin_msa_sat_u_w, "V4UiV4UiIUi", "nc")
+BUILTIN(__builtin_msa_sat_u_d, "V2ULLiV2ULLiIUi", "nc")
+
+BUILTIN(__builtin_msa_shf_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_shf_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_shf_w, "V4iV4iIUi", "nc")
+
+BUILTIN(__builtin_msa_sld_b, "V16cV16cV16cUi", "nc")
+BUILTIN(__builtin_msa_sld_h, "V8sV8sV8sUi", "nc")
+BUILTIN(__builtin_msa_sld_w, "V4iV4iV4iUi", "nc")
+BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiV2LLiUi", "nc")
+
+BUILTIN(__builtin_msa_sldi_b, "V16cV16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_sldi_h, "V8sV8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_sldi_w, "V4iV4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_sll_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_sll_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_sll_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_sll_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_slli_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_slli_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_slli_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_slli_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_splat_b, "V16cV16cUi", "nc")
+BUILTIN(__builtin_msa_splat_h, "V8sV8sUi", "nc")
+BUILTIN(__builtin_msa_splat_w, "V4iV4iUi", "nc")
+BUILTIN(__builtin_msa_splat_d, "V2LLiV2LLiUi", "nc")
+
+BUILTIN(__builtin_msa_splati_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_splati_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_splati_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_splati_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_sra_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_sra_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_sra_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_sra_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_srai_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_srai_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_srai_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_srai_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_srar_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_srar_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_srar_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_srar_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_srari_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_srari_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_srari_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_srari_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_srl_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_srl_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_srl_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_srl_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_srli_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_srli_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_srli_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_srli_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_srlr_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_srlr_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_srlr_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_srlr_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_srlri_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_srlri_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_srlri_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_srlri_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_st_b, "vV16Scv*Ii", "nc")
+BUILTIN(__builtin_msa_st_h, "vV8Ssv*Ii", "nc")
+BUILTIN(__builtin_msa_st_w, "vV4Siv*Ii", "nc")
+BUILTIN(__builtin_msa_st_d, "vV2SLLiv*Ii", "nc")
+
+BUILTIN(__builtin_msa_subs_s_b, "V16ScV16ScV16Sc", "nc")
+BUILTIN(__builtin_msa_subs_s_h, "V8SsV8SsV8Ss", "nc")
+BUILTIN(__builtin_msa_subs_s_w, "V4SiV4SiV4Si", "nc")
+BUILTIN(__builtin_msa_subs_s_d, "V2SLLiV2SLLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_subs_u_b, "V16UcV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_subs_u_h, "V8UsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_subs_u_w, "V4UiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_subs_u_d, "V2ULLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_subsus_u_b, "V16UcV16UcV16Sc", "nc")
+BUILTIN(__builtin_msa_subsus_u_h, "V8UsV8UsV8Ss", "nc")
+BUILTIN(__builtin_msa_subsus_u_w, "V4UiV4UiV4Si", "nc")
+BUILTIN(__builtin_msa_subsus_u_d, "V2ULLiV2ULLiV2SLLi", "nc")
+
+BUILTIN(__builtin_msa_subsuu_s_b, "V16ScV16UcV16Uc", "nc")
+BUILTIN(__builtin_msa_subsuu_s_h, "V8SsV8UsV8Us", "nc")
+BUILTIN(__builtin_msa_subsuu_s_w, "V4SiV4UiV4Ui", "nc")
+BUILTIN(__builtin_msa_subsuu_s_d, "V2SLLiV2ULLiV2ULLi", "nc")
+
+BUILTIN(__builtin_msa_subv_b, "V16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_subv_h, "V8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_subv_w, "V4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_subv_d, "V2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_subvi_b, "V16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_subvi_h, "V8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_subvi_w, "V4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_subvi_d, "V2LLiV2LLiIUi", "nc")
+
+BUILTIN(__builtin_msa_vshf_b, "V16cV16cV16cV16c", "nc")
+BUILTIN(__builtin_msa_vshf_h, "V8sV8sV8sV8s", "nc")
+BUILTIN(__builtin_msa_vshf_w, "V4iV4iV4iV4i", "nc")
+BUILTIN(__builtin_msa_vshf_d, "V2LLiV2LLiV2LLiV2LLi", "nc")
+
+BUILTIN(__builtin_msa_xor_v, "V16cV16cV16c", "nc")
+
+BUILTIN(__builtin_msa_xori_b, "V16cV16cIUi", "nc")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
new file mode 100644
index 0000000..7800ae6
--- /dev/null
+++ b/include/clang/Basic/BuiltinsNEON.def
@@ -0,0 +1,21 @@
+//===--- BuiltinsNEON.def - NEON Builtin function database ------*- 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 NEON-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+#define GET_NEON_BUILTINS
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_BUILTINS
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
new file mode 100644
index 0000000..7e9b5ee
--- /dev/null
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -0,0 +1,566 @@
+//===--- BuiltinsPTX.def - PTX Builtin function database ----*- 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 PTX-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// Builtins retained from previous PTX back-end
+BUILTIN(__builtin_ptx_read_tid_x, "i", "nc")
+BUILTIN(__builtin_ptx_read_tid_y, "i", "nc")
+BUILTIN(__builtin_ptx_read_tid_z, "i", "nc")
+BUILTIN(__builtin_ptx_read_tid_w, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_ntid_x, "i", "nc")
+BUILTIN(__builtin_ptx_read_ntid_y, "i", "nc")
+BUILTIN(__builtin_ptx_read_ntid_z, "i", "nc")
+BUILTIN(__builtin_ptx_read_ntid_w, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_ctaid_x, "i", "nc")
+BUILTIN(__builtin_ptx_read_ctaid_y, "i", "nc")
+BUILTIN(__builtin_ptx_read_ctaid_z, "i", "nc")
+BUILTIN(__builtin_ptx_read_ctaid_w, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_nctaid_x, "i", "nc")
+BUILTIN(__builtin_ptx_read_nctaid_y, "i", "nc")
+BUILTIN(__builtin_ptx_read_nctaid_z, "i", "nc")
+BUILTIN(__builtin_ptx_read_nctaid_w, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_laneid, "i", "nc")
+BUILTIN(__builtin_ptx_read_warpid, "i", "nc")
+BUILTIN(__builtin_ptx_read_nwarpid, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_smid, "i", "nc")
+BUILTIN(__builtin_ptx_read_nsmid, "i", "nc")
+BUILTIN(__builtin_ptx_read_gridid, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_lanemask_eq, "i", "nc")
+BUILTIN(__builtin_ptx_read_lanemask_le, "i", "nc")
+BUILTIN(__builtin_ptx_read_lanemask_lt, "i", "nc")
+BUILTIN(__builtin_ptx_read_lanemask_ge, "i", "nc")
+BUILTIN(__builtin_ptx_read_lanemask_gt, "i", "nc")
+
+BUILTIN(__builtin_ptx_read_clock, "i", "n")
+BUILTIN(__builtin_ptx_read_clock64, "Li", "n")
+
+BUILTIN(__builtin_ptx_read_pm0, "i", "n")
+BUILTIN(__builtin_ptx_read_pm1, "i", "n")
+BUILTIN(__builtin_ptx_read_pm2, "i", "n")
+BUILTIN(__builtin_ptx_read_pm3, "i", "n")
+
+BUILTIN(__builtin_ptx_bar_sync, "vi", "n")
+
+
+// Builtins exposed as part of NVVM
+// MISC
+
+BUILTIN(__nvvm_clz_i, "ii", "")
+BUILTIN(__nvvm_clz_ll, "iLLi", "")
+BUILTIN(__nvvm_popc_i, "ii", "")
+BUILTIN(__nvvm_popc_ll, "iLLi", "")
+BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
+
+// Min Max
+
+BUILTIN(__nvvm_min_i, "iii", "")
+BUILTIN(__nvvm_min_ui, "UiUiUi", "")
+BUILTIN(__nvvm_min_ll, "LLiLLiLLi", "")
+BUILTIN(__nvvm_min_ull, "ULLiULLiULLi", "")
+
+BUILTIN(__nvvm_max_i, "iii", "")
+BUILTIN(__nvvm_max_ui, "UiUiUi", "")
+BUILTIN(__nvvm_max_ll, "LLiLLiLLi", "")
+BUILTIN(__nvvm_max_ull, "ULLiULLiULLi", "")
+
+BUILTIN(__nvvm_fmax_ftz_f, "fff",  "")
+BUILTIN(__nvvm_fmax_f, "fff",  "")
+BUILTIN(__nvvm_fmin_ftz_f, "fff",  "")
+BUILTIN(__nvvm_fmin_f, "fff",  "")
+
+BUILTIN(__nvvm_fmax_d, "ddd", "")
+BUILTIN(__nvvm_fmin_d, "ddd", "")
+
+// Multiplication
+
+BUILTIN(__nvvm_mulhi_i, "iii", "")
+BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "")
+BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "")
+BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "")
+
+BUILTIN(__nvvm_mul_rn_ftz_f,  "fff", "")
+BUILTIN(__nvvm_mul_rn_f,  "fff", "")
+BUILTIN(__nvvm_mul_rz_ftz_f,  "fff", "")
+BUILTIN(__nvvm_mul_rz_f,  "fff", "")
+BUILTIN(__nvvm_mul_rm_ftz_f,  "fff", "")
+BUILTIN(__nvvm_mul_rm_f,  "fff", "")
+BUILTIN(__nvvm_mul_rp_ftz_f,  "fff", "")
+BUILTIN(__nvvm_mul_rp_f,  "fff", "")
+
+BUILTIN(__nvvm_mul_rn_d,  "ddd", "")
+BUILTIN(__nvvm_mul_rz_d,  "ddd", "")
+BUILTIN(__nvvm_mul_rm_d,  "ddd", "")
+BUILTIN(__nvvm_mul_rp_d,  "ddd", "")
+
+BUILTIN(__nvvm_mul24_i,  "iii", "")
+BUILTIN(__nvvm_mul24_ui,  "UiUiUi", "")
+
+// Div
+
+BUILTIN(__nvvm_div_approx_ftz_f,  "fff", "")
+BUILTIN(__nvvm_div_approx_f,  "fff", "")
+
+BUILTIN(__nvvm_div_rn_ftz_f,  "fff", "")
+BUILTIN(__nvvm_div_rn_f,  "fff", "")
+BUILTIN(__nvvm_div_rz_ftz_f,  "fff", "")
+BUILTIN(__nvvm_div_rz_f,  "fff", "")
+BUILTIN(__nvvm_div_rm_ftz_f,  "fff", "")
+BUILTIN(__nvvm_div_rm_f,  "fff", "")
+BUILTIN(__nvvm_div_rp_ftz_f,  "fff", "")
+BUILTIN(__nvvm_div_rp_f,  "fff", "")
+
+BUILTIN(__nvvm_div_rn_d,  "ddd", "")
+BUILTIN(__nvvm_div_rz_d,  "ddd", "")
+BUILTIN(__nvvm_div_rm_d,  "ddd", "")
+BUILTIN(__nvvm_div_rp_d,  "ddd", "")
+
+// Brev
+
+BUILTIN(__nvvm_brev32, "UiUi", "")
+BUILTIN(__nvvm_brev64, "ULLiULLi", "")
+
+// Sad
+
+BUILTIN(__nvvm_sad_i, "iii", "")
+BUILTIN(__nvvm_sad_ui, "UiUiUi", "")
+
+// Floor, Ceil
+
+BUILTIN(__nvvm_floor_ftz_f, "ff", "")
+BUILTIN(__nvvm_floor_f, "ff", "")
+BUILTIN(__nvvm_floor_d, "dd", "")
+
+BUILTIN(__nvvm_ceil_ftz_f, "ff", "")
+BUILTIN(__nvvm_ceil_f, "ff", "")
+BUILTIN(__nvvm_ceil_d, "dd", "")
+
+// Abs
+
+BUILTIN(__nvvm_abs_i, "ii", "")
+BUILTIN(__nvvm_abs_ll, "LLiLLi", "")
+
+BUILTIN(__nvvm_fabs_ftz_f, "ff", "")
+BUILTIN(__nvvm_fabs_f, "ff", "")
+BUILTIN(__nvvm_fabs_d, "dd", "")
+
+// Round
+
+BUILTIN(__nvvm_round_ftz_f, "ff", "")
+BUILTIN(__nvvm_round_f, "ff", "")
+BUILTIN(__nvvm_round_d, "dd", "")
+
+// Trunc
+
+BUILTIN(__nvvm_trunc_ftz_f, "ff", "")
+BUILTIN(__nvvm_trunc_f, "ff", "")
+BUILTIN(__nvvm_trunc_d, "dd", "")
+
+// Saturate
+
+BUILTIN(__nvvm_saturate_ftz_f, "ff", "")
+BUILTIN(__nvvm_saturate_f, "ff", "")
+BUILTIN(__nvvm_saturate_d, "dd", "")
+
+// Exp2, Log2
+
+BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_ex2_approx_f, "ff", "")
+BUILTIN(__nvvm_ex2_approx_d, "dd", "")
+
+BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_lg2_approx_f, "ff", "")
+BUILTIN(__nvvm_lg2_approx_d, "dd", "")
+
+// Sin, Cos
+
+BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_sin_approx_f, "ff", "")
+
+BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_cos_approx_f, "ff", "")
+
+// Fma
+
+BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "")
+BUILTIN(__nvvm_fma_rn_f, "ffff", "")
+BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "")
+BUILTIN(__nvvm_fma_rz_f, "ffff", "")
+BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "")
+BUILTIN(__nvvm_fma_rm_f, "ffff", "")
+BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "")
+BUILTIN(__nvvm_fma_rp_f, "ffff", "")
+BUILTIN(__nvvm_fma_rn_d, "dddd", "")
+BUILTIN(__nvvm_fma_rz_d, "dddd", "")
+BUILTIN(__nvvm_fma_rm_d, "dddd", "")
+BUILTIN(__nvvm_fma_rp_d, "dddd", "")
+
+// Rcp
+
+BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "")
+BUILTIN(__nvvm_rcp_rn_f, "ff", "")
+BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "")
+BUILTIN(__nvvm_rcp_rz_f, "ff", "")
+BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "")
+BUILTIN(__nvvm_rcp_rm_f, "ff", "")
+BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "")
+BUILTIN(__nvvm_rcp_rp_f, "ff", "")
+
+BUILTIN(__nvvm_rcp_rn_d, "dd", "")
+BUILTIN(__nvvm_rcp_rz_d, "dd", "")
+BUILTIN(__nvvm_rcp_rm_d, "dd", "")
+BUILTIN(__nvvm_rcp_rp_d, "dd", "")
+BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "")
+
+// Sqrt
+
+BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rn_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rm_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_rp_f, "ff", "")
+BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_sqrt_approx_f, "ff", "")
+
+BUILTIN(__nvvm_sqrt_rn_d, "dd", "")
+BUILTIN(__nvvm_sqrt_rz_d, "dd", "")
+BUILTIN(__nvvm_sqrt_rm_d, "dd", "")
+BUILTIN(__nvvm_sqrt_rp_d, "dd", "")
+
+// Rsqrt
+
+BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "")
+BUILTIN(__nvvm_rsqrt_approx_f, "ff", "")
+BUILTIN(__nvvm_rsqrt_approx_d, "dd", "")
+
+// Add
+
+BUILTIN(__nvvm_add_rn_ftz_f, "ff", "")
+BUILTIN(__nvvm_add_rn_f, "ff", "")
+BUILTIN(__nvvm_add_rz_ftz_f, "ff", "")
+BUILTIN(__nvvm_add_rz_f, "ff", "")
+BUILTIN(__nvvm_add_rm_ftz_f, "ff", "")
+BUILTIN(__nvvm_add_rm_f, "ff", "")
+BUILTIN(__nvvm_add_rp_ftz_f, "ff", "")
+BUILTIN(__nvvm_add_rp_f, "ff", "")
+
+BUILTIN(__nvvm_add_rn_d, "dd", "")
+BUILTIN(__nvvm_add_rz_d, "dd", "")
+BUILTIN(__nvvm_add_rm_d, "dd", "")
+BUILTIN(__nvvm_add_rp_d, "dd", "")
+
+// Convert
+
+BUILTIN(__nvvm_d2f_rn_ftz, "fd", "")
+BUILTIN(__nvvm_d2f_rn, "fd", "")
+BUILTIN(__nvvm_d2f_rz_ftz, "fd", "")
+BUILTIN(__nvvm_d2f_rz, "fd", "")
+BUILTIN(__nvvm_d2f_rm_ftz, "fd", "")
+BUILTIN(__nvvm_d2f_rm, "fd", "")
+BUILTIN(__nvvm_d2f_rp_ftz, "fd", "")
+BUILTIN(__nvvm_d2f_rp, "fd", "")
+
+BUILTIN(__nvvm_d2i_rn, "id", "")
+BUILTIN(__nvvm_d2i_rz, "id", "")
+BUILTIN(__nvvm_d2i_rm, "id", "")
+BUILTIN(__nvvm_d2i_rp, "id", "")
+
+BUILTIN(__nvvm_d2ui_rn, "Uid", "")
+BUILTIN(__nvvm_d2ui_rz, "Uid", "")
+BUILTIN(__nvvm_d2ui_rm, "Uid", "")
+BUILTIN(__nvvm_d2ui_rp, "Uid", "")
+
+BUILTIN(__nvvm_i2d_rn, "di", "")
+BUILTIN(__nvvm_i2d_rz, "di", "")
+BUILTIN(__nvvm_i2d_rm, "di", "")
+BUILTIN(__nvvm_i2d_rp, "di", "")
+
+BUILTIN(__nvvm_ui2d_rn, "dUi", "")
+BUILTIN(__nvvm_ui2d_rz, "dUi", "")
+BUILTIN(__nvvm_ui2d_rm, "dUi", "")
+BUILTIN(__nvvm_ui2d_rp, "dUi", "")
+
+BUILTIN(__nvvm_f2i_rn_ftz, "if", "")
+BUILTIN(__nvvm_f2i_rn, "if", "")
+BUILTIN(__nvvm_f2i_rz_ftz, "if", "")
+BUILTIN(__nvvm_f2i_rz, "if", "")
+BUILTIN(__nvvm_f2i_rm_ftz, "if", "")
+BUILTIN(__nvvm_f2i_rm, "if", "")
+BUILTIN(__nvvm_f2i_rp_ftz, "if", "")
+BUILTIN(__nvvm_f2i_rp, "if", "")
+
+BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "")
+BUILTIN(__nvvm_f2ui_rn, "Uif", "")
+BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "")
+BUILTIN(__nvvm_f2ui_rz, "Uif", "")
+BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "")
+BUILTIN(__nvvm_f2ui_rm, "Uif", "")
+BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "")
+BUILTIN(__nvvm_f2ui_rp, "Uif", "")
+
+BUILTIN(__nvvm_i2f_rn, "fi", "")
+BUILTIN(__nvvm_i2f_rz, "fi", "")
+BUILTIN(__nvvm_i2f_rm, "fi", "")
+BUILTIN(__nvvm_i2f_rp, "fi", "")
+
+BUILTIN(__nvvm_ui2f_rn, "fUi", "")
+BUILTIN(__nvvm_ui2f_rz, "fUi", "")
+BUILTIN(__nvvm_ui2f_rm, "fUi", "")
+BUILTIN(__nvvm_ui2f_rp, "fUi", "")
+
+BUILTIN(__nvvm_lohi_i2d, "dii", "")
+
+BUILTIN(__nvvm_d2i_lo, "id", "")
+BUILTIN(__nvvm_d2i_hi, "id", "")
+
+BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "")
+BUILTIN(__nvvm_f2ll_rn, "LLif", "")
+BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "")
+BUILTIN(__nvvm_f2ll_rz, "LLif", "")
+BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "")
+BUILTIN(__nvvm_f2ll_rm, "LLif", "")
+BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "")
+BUILTIN(__nvvm_f2ll_rp, "LLif", "")
+
+BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rn, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rz, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rm, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "")
+BUILTIN(__nvvm_f2ull_rp, "ULLif", "")
+
+BUILTIN(__nvvm_d2ll_rn, "LLid", "")
+BUILTIN(__nvvm_d2ll_rz, "LLid", "")
+BUILTIN(__nvvm_d2ll_rm, "LLid", "")
+BUILTIN(__nvvm_d2ll_rp, "LLid", "")
+
+BUILTIN(__nvvm_d2ull_rn, "ULLid", "")
+BUILTIN(__nvvm_d2ull_rz, "ULLid", "")
+BUILTIN(__nvvm_d2ull_rm, "ULLid", "")
+BUILTIN(__nvvm_d2ull_rp, "ULLid", "")
+
+BUILTIN(__nvvm_ll2f_rn, "fLLi", "")
+BUILTIN(__nvvm_ll2f_rz, "fLLi", "")
+BUILTIN(__nvvm_ll2f_rm, "fLLi", "")
+BUILTIN(__nvvm_ll2f_rp, "fLLi", "")
+
+BUILTIN(__nvvm_ull2f_rn, "fULLi", "")
+BUILTIN(__nvvm_ull2f_rz, "fULLi", "")
+BUILTIN(__nvvm_ull2f_rm, "fULLi", "")
+BUILTIN(__nvvm_ull2f_rp, "fULLi", "")
+
+BUILTIN(__nvvm_ll2d_rn, "dLLi", "")
+BUILTIN(__nvvm_ll2d_rz, "dLLi", "")
+BUILTIN(__nvvm_ll2d_rm, "dLLi", "")
+BUILTIN(__nvvm_ll2d_rp, "dLLi", "")
+
+BUILTIN(__nvvm_ull2d_rn, "dULLi", "")
+BUILTIN(__nvvm_ull2d_rz, "dULLi", "")
+BUILTIN(__nvvm_ull2d_rm, "dULLi", "")
+BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
+
+BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
+BUILTIN(__nvvm_f2h_rn, "Usf", "")
+
+BUILTIN(__nvvm_h2f, "fUs", "")
+
+// Bitcast
+
+BUILTIN(__nvvm_bitcast_f2i, "if", "")
+BUILTIN(__nvvm_bitcast_i2f, "fi", "")
+
+BUILTIN(__nvvm_bitcast_ll2d, "dLLi", "")
+BUILTIN(__nvvm_bitcast_d2ll, "LLid", "")
+
+// Sync
+
+BUILTIN(__syncthreads, "v", "")
+BUILTIN(__nvvm_bar0, "v", "")
+BUILTIN(__nvvm_bar0_popc, "ii", "")
+BUILTIN(__nvvm_bar0_and, "ii", "")
+BUILTIN(__nvvm_bar0_or, "ii", "")
+
+// Membar
+
+BUILTIN(__nvvm_membar_cta, "v", "")
+BUILTIN(__nvvm_membar_gl, "v", "")
+BUILTIN(__nvvm_membar_sys, "v", "")
+
+// Memcpy, Memset
+
+BUILTIN(__nvvm_memcpy, "vUc*Uc*zi","")
+BUILTIN(__nvvm_memset, "vUc*Uczi","")
+
+// Image
+
+BUILTIN(__builtin_ptx_read_image2Dfi_, "V4fiiii", "")
+BUILTIN(__builtin_ptx_read_image2Dff_, "V4fiiff", "")
+BUILTIN(__builtin_ptx_read_image2Dii_, "V4iiiii", "")
+BUILTIN(__builtin_ptx_read_image2Dif_, "V4iiiff", "")
+
+BUILTIN(__builtin_ptx_read_image3Dfi_, "V4fiiiiii", "")
+BUILTIN(__builtin_ptx_read_image3Dff_, "V4fiiffff", "")
+BUILTIN(__builtin_ptx_read_image3Dii_, "V4iiiiiii", "")
+BUILTIN(__builtin_ptx_read_image3Dif_, "V4iiiffff", "")
+
+BUILTIN(__builtin_ptx_write_image2Df_, "viiiffff", "")
+BUILTIN(__builtin_ptx_write_image2Di_, "viiiiiii", "")
+BUILTIN(__builtin_ptx_write_image2Dui_, "viiiUiUiUiUi", "")
+BUILTIN(__builtin_ptx_get_image_depthi_, "ii", "")
+BUILTIN(__builtin_ptx_get_image_heighti_, "ii", "")
+BUILTIN(__builtin_ptx_get_image_widthi_, "ii", "")
+BUILTIN(__builtin_ptx_get_image_channel_data_typei_, "ii", "")
+BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "")
+
+// Atomic
+//
+// We need the atom intrinsics because
+// - they are used in converging analysis
+// - they are used in address space analysis and optimization
+// So it does not hurt to expose them as builtins.
+//
+BUILTIN(__nvvm_atom_add_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_add_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_add_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_add_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_add_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_add_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n")
+BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n")
+BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n")
+BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n")
+
+BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_sub_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_sub_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_sub_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_sub_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_sub_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_sub_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n")
+
+BUILTIN(__nvvm_atom_xchg_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_xchg_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_xchg_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_xchg_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_xchg_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_xchg_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n")
+
+BUILTIN(__nvvm_atom_max_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_max_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_max_g_ui, "UiUiD*1Ui", "n")
+BUILTIN(__nvvm_atom_max_s_ui, "UiUiD*3Ui", "n")
+BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n")
+BUILTIN(__nvvm_atom_max_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_max_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_max_g_ul, "ULiULiD*1ULi", "n")
+BUILTIN(__nvvm_atom_max_s_ul, "ULiULiD*3ULi", "n")
+BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n")
+BUILTIN(__nvvm_atom_max_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_max_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n")
+BUILTIN(__nvvm_atom_max_g_ull, "ULLiULLiD*1ULLi", "n")
+BUILTIN(__nvvm_atom_max_s_ull, "ULLiULLiD*3ULLi", "n")
+BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n")
+
+BUILTIN(__nvvm_atom_min_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_min_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_min_g_ui, "UiUiD*1Ui", "n")
+BUILTIN(__nvvm_atom_min_s_ui, "UiUiD*3Ui", "n")
+BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n")
+BUILTIN(__nvvm_atom_min_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_min_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_min_gen_l, "LiLi10D*Li", "n")
+BUILTIN(__nvvm_atom_min_g_ul, "ULiULiD*1ULi", "n")
+BUILTIN(__nvvm_atom_min_s_ul, "ULiULiD*3ULi", "n")
+BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n")
+BUILTIN(__nvvm_atom_min_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_min_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n")
+BUILTIN(__nvvm_atom_min_g_ull, "ULLiULLiD*1ULLi", "n")
+BUILTIN(__nvvm_atom_min_s_ull, "ULLiULLiD*3ULLi", "n")
+BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n")
+
+BUILTIN(__nvvm_atom_inc_g_ui, "UiUiD*1Ui", "n")
+BUILTIN(__nvvm_atom_inc_s_ui, "UiUiD*3Ui", "n")
+BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n")
+BUILTIN(__nvvm_atom_dec_g_ui, "UiUiD*1Ui", "n")
+BUILTIN(__nvvm_atom_dec_s_ui, "UiUiD*3Ui", "n")
+BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n")
+
+BUILTIN(__nvvm_atom_and_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_and_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_and_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_and_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_and_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_and_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n")
+
+BUILTIN(__nvvm_atom_or_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_or_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_or_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_or_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_or_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_or_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n")
+
+BUILTIN(__nvvm_atom_xor_g_i, "iiD*1i", "n")
+BUILTIN(__nvvm_atom_xor_s_i, "iiD*3i", "n")
+BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n")
+BUILTIN(__nvvm_atom_xor_g_l, "LiLiD*1Li", "n")
+BUILTIN(__nvvm_atom_xor_s_l, "LiLiD*3Li", "n")
+BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n")
+BUILTIN(__nvvm_atom_xor_g_ll, "LLiLLiD*1LLi", "n")
+BUILTIN(__nvvm_atom_xor_s_ll, "LLiLLiD*3LLi", "n")
+BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n")
+
+BUILTIN(__nvvm_atom_cas_g_i, "iiD*1ii", "n")
+BUILTIN(__nvvm_atom_cas_s_i, "iiD*3ii", "n")
+BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n")
+BUILTIN(__nvvm_atom_cas_g_l, "LiLiD*1LiLi", "n")
+BUILTIN(__nvvm_atom_cas_s_l, "LiLiD*3LiLi", "n")
+BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n")
+BUILTIN(__nvvm_atom_cas_g_ll, "LLiLLiD*1LLiLLi", "n")
+BUILTIN(__nvvm_atom_cas_s_ll, "LLiLLiD*3LLiLLi", "n")
+BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n")
+
+// Compiler Error Warn
+BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
+BUILTIN(__nvvm_compiler_warn, "vcC*4", "n")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
new file mode 100644
index 0000000..8a751e4
--- /dev/null
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -0,0 +1,209 @@
+//===--- BuiltinsPPC.def - PowerPC Builtin function database ----*- 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 PowerPC-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: this needs to be the full list supported by GCC.  Right now, I'm just
+// adding stuff on demand.
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// This is just a placeholder, the types and attributes are wrong.
+BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcfsx, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vcfux, "V4fV4ii", "")
+BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fi", "")
+BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fi", "")
+
+BUILTIN(__builtin_altivec_dss, "vUi", "")
+BUILTIN(__builtin_altivec_dssall, "v", "")
+BUILTIN(__builtin_altivec_dst, "vvC*iUi", "") 
+BUILTIN(__builtin_altivec_dstt, "vvC*iUi", "")
+BUILTIN(__builtin_altivec_dstst, "vvC*iUi", "")
+BUILTIN(__builtin_altivec_dststt, "vvC*iUi", "")
+
+BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvx, "V4iivC*", "")
+BUILTIN(__builtin_altivec_lvxl, "V4iivC*", "")
+BUILTIN(__builtin_altivec_lvebx, "V16civC*", "")
+BUILTIN(__builtin_altivec_lvehx, "V8sivC*", "")
+BUILTIN(__builtin_altivec_lvewx, "V4iivC*", "")
+
+BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_lvsl, "V16cUcvC*", "")
+BUILTIN(__builtin_altivec_lvsr, "V16cUcvC*", "")
+
+BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "")
+
+BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "")
+BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "")
+BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
+
+BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
+
+BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
+BUILTIN(__builtin_altivec_stvehx, "vV8siv*", "")
+BUILTIN(__builtin_altivec_stvewx, "vV4iiv*", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mfvscr, "V8Us", "")
+
+BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
+
+BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "")
+BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "")
+BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "")
+
+BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "")
+BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "")
+BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "")
+
+BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "")
+
+BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
+
+BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
+
+BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
+BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
+BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
+
+// FIXME: Obviously incomplete.
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsR600.def b/include/clang/Basic/BuiltinsR600.def
new file mode 100644
index 0000000..49135cc
--- /dev/null
+++ b/include/clang/Basic/BuiltinsR600.def
@@ -0,0 +1,32 @@
+//==- BuiltinsR600.def - R600 Builtin function database ----------*- 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 R600-specific builtin function database. Users of this
+// file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n")
+BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n")
+BUILTIN(__builtin_amdgpu_div_fmas, "dddd", "nc")
+BUILTIN(__builtin_amdgpu_div_fmasf, "ffff", "nc")
+BUILTIN(__builtin_amdgpu_div_fixup, "dddd", "nc")
+BUILTIN(__builtin_amdgpu_div_fixupf, "ffff", "nc")
+BUILTIN(__builtin_amdgpu_trig_preop, "ddi", "nc")
+BUILTIN(__builtin_amdgpu_trig_preopf, "ffi", "nc")
+BUILTIN(__builtin_amdgpu_rcp, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rcpf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsqf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clamped, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clampedf, "ff", "nc")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
new file mode 100644
index 0000000..1f377a8
--- /dev/null
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -0,0 +1,764 @@
+//===--- BuiltinsX86.def - X86 Builtin function database --------*- 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 X86-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+// FIXME: In GCC, these builtins are defined depending on whether support for
+// MMX/SSE/etc is turned on. We should do this too.
+
+// FIXME: Ideally we would be able to pull this information from what
+// LLVM already knows about X86 builtins. We need to match the LLVM
+// definition anyway, since code generation will lower to the
+// intrinsic if one exists.
+
+// FIXME: Are these nothrow/const?
+
+// 3DNow!
+//
+BUILTIN(__builtin_ia32_femms, "v", "")
+BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc")
+BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc")
+BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc")
+BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc")
+// 3DNow! Extensions (3dnowa).
+BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc")
+BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc")
+BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "nc")
+BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "nc")
+BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc")
+
+// MMX
+//
+// All MMX instructions will be generated via builtins. Any MMX vector
+// types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
+// expanded by the back-end.
+BUILTIN(_mm_prefetch, "vcC*i", "nc")
+BUILTIN(__builtin_ia32_emms, "v", "")
+BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "")
+BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "")
+BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "")
+BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "")
+BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "")
+BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "")
+BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "")
+BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "")
+BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "")
+BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "")
+BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "")
+BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "")
+BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "")
+BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "")
+
+// MMX2 (MMX+SSE) intrinsics
+BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
+BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
+BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
+BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
+BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "")
+
+// MMX+SSE2
+BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
+BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
+BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "")
+BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
+BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "")
+
+// MMX+SSSE3
+BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
+BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
+BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
+BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "")
+BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
+BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
+BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
+BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
+
+// SSE intrinsics.
+BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "")
+BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "")
+BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "")
+BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "")
+BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "")
+BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "")
+BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "")
+BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "")
+BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "")
+BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "")
+BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "")
+BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "")
+BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "")
+BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "")
+BUILTIN(__builtin_ia32_stmxcsr, "Ui", "")
+BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
+BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
+BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
+BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
+BUILTIN(__builtin_ia32_movmskps, "iV4f", "")
+BUILTIN(__builtin_ia32_movntps, "vf*V4f", "")
+BUILTIN(__builtin_ia32_sfence, "v", "")
+BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "")
+BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movmskpd, "iV2d", "")
+BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "")
+BUILTIN(__builtin_ia32_movnti, "vi*i", "")
+BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "")
+BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "")
+BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "")
+BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "")
+BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "")
+BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "")
+BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "")
+BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "")
+BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "")
+BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "")
+BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "")
+BUILTIN(__builtin_ia32_clflush, "vvC*", "")
+BUILTIN(__builtin_ia32_lfence, "v", "")
+BUILTIN(__builtin_ia32_mfence, "v", "")
+BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "")
+BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pslldqi128, "V2LLiV2LLiIi", "")
+BUILTIN(__builtin_ia32_psrldqi128, "V2LLiV2LLiIi", "")
+BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "")
+BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "")
+BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "")
+BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "")
+BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
+BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
+BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
+BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIc", "")
+BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
+
+BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8sIi", "")
+BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2dIi", "")
+BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fIi", "")
+BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "")
+
+BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_pmovsxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovsxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovsxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovsxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "")
+BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "")
+BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "")
+BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
+BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
+BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "")
+BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "")
+BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "")
+
+// SSE 4.2
+BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "")
+BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cIc", "")
+BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "")
+BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","")
+
+BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","")
+
+BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "")
+BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "")
+BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "")
+BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "")
+
+// SSE4a
+BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "")
+BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "")
+BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "")
+BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "")
+BUILTIN(__builtin_ia32_movntss, "vf*V4f", "")
+
+// AES
+BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "")
+
+// CLMUL
+BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "")
+
+// AVX
+BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "")
+BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "")
+BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "")
+BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "")
+BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "")
+BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIi", "")
+BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIi", "")
+BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIi", "")
+BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dc", "")
+BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fc", "")
+BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIc", "")
+BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIc", "")
+BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIc", "")
+BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "")
+BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "")
+BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "")
+BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "")
+BUILTIN(__builtin_ia32_cvtps2pd256, "V4dV4f", "")
+BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "")
+BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "")
+BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "")
+BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "")
+BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "")
+BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIc", "")
+BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "")
+BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "")
+BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "")
+BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "")
+BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "")
+BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "")
+BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "")
+BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "")
+BUILTIN(__builtin_ia32_movmskps256, "iV8f", "")
+BUILTIN(__builtin_ia32_vzeroall, "v", "")
+BUILTIN(__builtin_ia32_vzeroupper, "v", "")
+BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "")
+BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "")
+BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "")
+BUILTIN(__builtin_ia32_storeups256, "vf*V8f", "")
+BUILTIN(__builtin_ia32_storedqu256, "vc*V32c", "")
+BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "")
+BUILTIN(__builtin_ia32_movntdq256, "vV4LLi*V4LLi", "")
+BUILTIN(__builtin_ia32_movntpd256, "vd*V4d", "")
+BUILTIN(__builtin_ia32_movntps256, "vf*V8f", "")
+BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2d", "")
+BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4f", "")
+BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4d", "")
+BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8f", "")
+BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2dV2d", "")
+BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4fV4f", "")
+BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4dV4d", "")
+BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8fV8f", "")
+
+// AVX2
+BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32ci", "")
+BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "")
+BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "")
+BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "")
+BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "")
+BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "")
+BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "")
+BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "")
+BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIc", "")
+BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "")
+BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_phsubw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "")
+BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "")
+BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "")
+BUILTIN(__builtin_ia32_pmovsxbw256, "V16sV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbd256, "V8iV16c", "")
+BUILTIN(__builtin_ia32_pmovsxbq256, "V4LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovsxwd256, "V8iV8s", "")
+BUILTIN(__builtin_ia32_pmovsxwq256, "V4LLiV8s", "")
+BUILTIN(__builtin_ia32_pmovsxdq256, "V4LLiV4i", "")
+BUILTIN(__builtin_ia32_pmovzxbw256, "V16sV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbd256, "V8iV16c", "")
+BUILTIN(__builtin_ia32_pmovzxbq256, "V4LLiV16c", "")
+BUILTIN(__builtin_ia32_pmovzxwd256, "V8iV8s", "")
+BUILTIN(__builtin_ia32_pmovzxwq256, "V4LLiV8s", "")
+BUILTIN(__builtin_ia32_pmovzxdq256, "V4LLiV4i", "")
+BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "")
+BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "")
+BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "")
+BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_psignb256, "V32cV32cV32c", "")
+BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "")
+BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_pslldqi256, "V4LLiV4LLiIi", "")
+BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "")
+BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "")
+BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "")
+BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "")
+BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "")
+BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "")
+BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "")
+BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "")
+BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "")
+BUILTIN(__builtin_ia32_psrldqi256, "V4LLiV4LLiIi", "")
+BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "")
+BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "")
+BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "")
+BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "")
+BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "")
+BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "")
+BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLi*", "")
+BUILTIN(__builtin_ia32_vbroadcastss_ps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_vbroadcastss_ps256, "V8fV4f", "")
+BUILTIN(__builtin_ia32_vbroadcastsd_pd256, "V4dV2d", "")
+BUILTIN(__builtin_ia32_vbroadcastsi256, "V4LLiV2LLi", "")
+BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIi", "")
+BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIi", "")
+BUILTIN(__builtin_ia32_pbroadcastb256, "V32cV16c", "")
+BUILTIN(__builtin_ia32_pbroadcastw256, "V16sV8s", "")
+BUILTIN(__builtin_ia32_pbroadcastd256, "V8iV4i", "")
+BUILTIN(__builtin_ia32_pbroadcastq256, "V4LLiV2LLi", "")
+BUILTIN(__builtin_ia32_pbroadcastb128, "V16cV16c", "")
+BUILTIN(__builtin_ia32_pbroadcastw128, "V8sV8s", "")
+BUILTIN(__builtin_ia32_pbroadcastd128, "V4iV4i", "")
+BUILTIN(__builtin_ia32_pbroadcastq128, "V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8f", "")
+BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "")
+BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIc", "")
+BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIc", "")
+BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "")
+BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "")
+BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "")
+BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "")
+BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "")
+BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "")
+BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "")
+BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "")
+
+// GATHER
+BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2dV2dC*V4iV2dIc", "")
+BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4dV4dC*V4iV4dIc", "")
+BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2dV2dC*V2LLiV2dIc", "")
+BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4dV4dC*V4LLiV4dIc", "")
+BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4fV4fC*V4iV4fIc", "")
+BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8fV8fC*V8iV8fIc", "")
+BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4fV4fC*V2LLiV4fIc", "")
+BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4fV4fC*V4LLiV4fIc", "")
+
+BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiV2LLiC*V4iV2LLiIc", "")
+BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiV4LLiC*V4iV4LLiIc", "")
+BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiV2LLiC*V2LLiV2LLiIc", "")
+BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiV4LLiC*V4LLiV4LLiIc", "")
+BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iV4iC*V4iV4iIc", "")
+BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iV8iC*V8iV8iIc", "")
+BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iV4iC*V2LLiV4iIc", "")
+BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iV4iC*V4LLiV4iIc", "")
+
+// F16C
+BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "")
+BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "")
+BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "")
+BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "")
+
+// RDRAND
+BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "")
+BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "")
+BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "")
+
+// RDSEED
+BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "")
+BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "")
+BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "")
+
+// BMI
+BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "")
+BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "")
+
+// BMI2
+BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "")
+BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "")
+BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "")
+BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "")
+BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "")
+BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "")
+
+// TBM
+BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "")
+BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "")
+
+// SHA
+BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "")
+BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "")
+BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "")
+
+// FMA4
+BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "")
+BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "")
+BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "")
+BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "")
+BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "")
+
+// XOP
+BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "")
+BUILTIN(__builtin_ia32_vpmacsww, "V8sV8sV8sV8s", "")
+BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "")
+BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "")
+BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "")
+BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "")
+BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "")
+BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "")
+BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "")
+BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "")
+BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "")
+BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "")
+
+BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "")
+BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "")
+BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "")
+BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "")
+BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "")
+BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "")
+BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "")
+BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "")
+BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "")
+BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "")
+BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "")
+BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "")
+BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "")
+BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "")
+BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "")
+BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "")
+BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "")
+BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "")
+BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "")
+BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "")
+BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "")
+BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "")
+BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "")
+BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "")
+BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "")
+BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "")
+BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "")
+BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "")
+BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "")
+BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "")
+BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "")
+BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "")
+BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "")
+BUILTIN(__builtin_ia32_vfrczsd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "")
+BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "")
+BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "")
+BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "")
+BUILTIN(__builtin_ia32_xbegin, "i", "")
+BUILTIN(__builtin_ia32_xend, "v", "")
+BUILTIN(__builtin_ia32_xabort, "vIc", "")
+BUILTIN(__builtin_ia32_xtest, "i", "")
+BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
+BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
+BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsXCore.def b/include/clang/Basic/BuiltinsXCore.def
new file mode 100644
index 0000000..672d205
--- /dev/null
+++ b/include/clang/Basic/BuiltinsXCore.def
@@ -0,0 +1,22 @@
+//===--- BuiltinsXCore.def - XCore Builtin function database ----*- 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 XCore-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+BUILTIN(__builtin_bitrev, "UiUi", "nc")
+BUILTIN(__builtin_getid, "Si", "nc")
+BUILTIN(__builtin_getps, "UiUi", "n")
+BUILTIN(__builtin_setps, "vUiUi", "n")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h
new file mode 100644
index 0000000..c4a289b
--- /dev/null
+++ b/include/clang/Basic/CapturedStmt.h
@@ -0,0 +1,24 @@
+//===--- CapturedStmt.h - Types for CapturedStmts ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_BASIC_CAPTUREDSTMT_H
+#define LLVM_CLANG_BASIC_CAPTUREDSTMT_H
+
+namespace clang {
+
+/// \brief The different kinds of captured statement.
+enum CapturedRegionKind {
+  CR_Default,
+  CR_OpenMP
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_CAPTUREDSTMT_H
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
new file mode 100644
index 0000000..d0afda4
--- /dev/null
+++ b/include/clang/Basic/CharInfo.h
@@ -0,0 +1,198 @@
+//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_CHARINFO_H
+#define CLANG_BASIC_CHARINFO_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+namespace charinfo {
+  extern const uint16_t InfoTable[256];
+
+  enum {
+    CHAR_HORZ_WS  = 0x0001,  // '\t', '\f', '\v'.  Note, no '\0'
+    CHAR_VERT_WS  = 0x0002,  // '\r', '\n'
+    CHAR_SPACE    = 0x0004,  // ' '
+    CHAR_DIGIT    = 0x0008,  // 0-9
+    CHAR_XLETTER  = 0x0010,  // a-f,A-F
+    CHAR_UPPER    = 0x0020,  // A-Z
+    CHAR_LOWER    = 0x0040,  // a-z
+    CHAR_UNDER    = 0x0080,  // _
+    CHAR_PERIOD   = 0x0100,  // .
+    CHAR_RAWDEL   = 0x0200,  // {}[]#<>%:;?*+-/^&|~!=,"'
+    CHAR_PUNCT    = 0x0400   // `$@()
+  };
+
+  enum {
+    CHAR_XUPPER = CHAR_XLETTER | CHAR_UPPER,
+    CHAR_XLOWER = CHAR_XLETTER | CHAR_LOWER
+  };
+} // end namespace charinfo
+
+/// Returns true if this is an ASCII character.
+LLVM_READNONE static inline bool isASCII(char c) {
+  return static_cast<unsigned char>(c) <= 127;
+}
+
+/// Returns true if this is a valid first character of a C identifier,
+/// which is [a-zA-Z_].
+LLVM_READONLY static inline bool isIdentifierHead(unsigned char c,
+                                                  bool AllowDollar = false) {
+  using namespace charinfo;
+  if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
+    return true;
+  return AllowDollar && c == '$';
+}
+
+/// Returns true if this is a body character of a C identifier,
+/// which is [a-zA-Z0-9_].
+LLVM_READONLY static inline bool isIdentifierBody(unsigned char c,
+                                                  bool AllowDollar = false) {
+  using namespace charinfo;
+  if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
+    return true;
+  return AllowDollar && c == '$';
+}
+
+/// Returns true if this character is horizontal ASCII whitespace:
+/// ' ', '\\t', '\\f', '\\v'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isHorizontalWhitespace(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_SPACE)) != 0;
+}
+
+/// Returns true if this character is vertical ASCII whitespace: '\\n', '\\r'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isVerticalWhitespace(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & CHAR_VERT_WS) != 0;
+}
+
+/// Return true if this character is horizontal or vertical ASCII whitespace:
+/// ' ', '\\t', '\\f', '\\v', '\\n', '\\r'.
+///
+/// Note that this returns false for '\\0'.
+LLVM_READONLY static inline bool isWhitespace(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_HORZ_WS|CHAR_VERT_WS|CHAR_SPACE)) != 0;
+}
+
+/// Return true if this character is an ASCII digit: [0-9]
+LLVM_READONLY static inline bool isDigit(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & CHAR_DIGIT) != 0;
+}
+
+/// Return true if this character is a lowercase ASCII letter: [a-z]
+LLVM_READONLY static inline bool isLowercase(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & CHAR_LOWER) != 0;
+}
+
+/// Return true if this character is an uppercase ASCII letter: [A-Z]
+LLVM_READONLY static inline bool isUppercase(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & CHAR_UPPER) != 0;
+}
+
+/// Return true if this character is an ASCII letter: [a-zA-Z]
+LLVM_READONLY static inline bool isLetter(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER)) != 0;
+}
+
+/// Return true if this character is an ASCII letter or digit: [a-zA-Z0-9]
+LLVM_READONLY static inline bool isAlphanumeric(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_DIGIT|CHAR_UPPER|CHAR_LOWER)) != 0;
+}
+
+/// Return true if this character is an ASCII hex digit: [0-9a-fA-F]
+LLVM_READONLY static inline bool isHexDigit(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_DIGIT|CHAR_XLETTER)) != 0;
+}
+
+/// Return true if this character is an ASCII punctuation character.
+///
+/// Note that '_' is both a punctuation character and an identifier character!
+LLVM_READONLY static inline bool isPunctuation(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0;
+}
+
+/// Return true if this character is an ASCII printable character; that is, a
+/// character that should take exactly one column to print in a fixed-width
+/// terminal.
+LLVM_READONLY static inline bool isPrintable(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT|
+                          CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0;
+}
+
+/// Return true if this is the body character of a C preprocessing number,
+/// which is [a-zA-Z0-9_.].
+LLVM_READONLY static inline bool isPreprocessingNumberBody(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] &
+          (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER|CHAR_PERIOD)) != 0;
+}
+
+/// Return true if this is the body character of a C++ raw string delimiter.
+LLVM_READONLY static inline bool isRawStringDelimBody(unsigned char c) {
+  using namespace charinfo;
+  return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|
+                          CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
+}
+
+
+/// Converts the given ASCII character to its lowercase equivalent.
+///
+/// If the character is not an uppercase character, it is returned as is.
+LLVM_READONLY static inline char toLowercase(char c) {
+  if (isUppercase(c))
+    return c + 'a' - 'A';
+  return c;
+}
+
+/// Converts the given ASCII character to its uppercase equivalent.
+///
+/// If the character is not a lowercase character, it is returned as is.
+LLVM_READONLY static inline char toUppercase(char c) {
+  if (isLowercase(c))
+    return c + 'A' - 'a';
+  return c;
+}
+
+
+/// Return true if this is a valid ASCII identifier.
+///
+/// Note that this is a very simple check; it does not accept '$' or UCNs as
+/// valid identifier characters.
+LLVM_READONLY static inline bool isValidIdentifier(StringRef S) {
+  if (S.empty() || !isIdentifierHead(S[0]))
+    return false;
+
+  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I)
+    if (!isIdentifierBody(*I))
+      return false;
+
+  return true;
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
new file mode 100644
index 0000000..7991875
--- /dev/null
+++ b/include/clang/Basic/CommentOptions.h
@@ -0,0 +1,39 @@
+//===--- CommentOptions.h - Options for parsing comments -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::CommentOptions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_COMMENTOPTIONS_H
+#define LLVM_CLANG_COMMENTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Options for controlling comment parsing.
+struct CommentOptions {
+  typedef std::vector<std::string> BlockCommandNamesTy;
+
+  /// \brief Command names to treat as block commands in comments.
+  /// Should not include the leading backslash.
+  BlockCommandNamesTy BlockCommandNames;
+
+  /// \brief Treat ordinary comments as documentation comments.
+  bool ParseAllComments;
+
+  CommentOptions() : ParseAllComments(false) { }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
new file mode 100644
index 0000000..a7b2ba2
--- /dev/null
+++ b/include/clang/Basic/Diagnostic.h
@@ -0,0 +1,1405 @@
+//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the Diagnostic-related interfaces.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTIC_H
+#define LLVM_CLANG_DIAGNOSTIC_H
+
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/iterator_range.h"
+#include <list>
+#include <vector>
+
+namespace clang {
+  class DeclContext;
+  class DiagnosticBuilder;
+  class DiagnosticConsumer;
+  class DiagnosticErrorTrap;
+  class DiagnosticOptions;
+  class IdentifierInfo;
+  class LangOptions;
+  class Preprocessor;
+  class StoredDiagnostic;
+  namespace tok {
+  enum TokenKind : unsigned short;
+  }
+
+/// \brief Annotates a diagnostic with some code that should be
+/// inserted, removed, or replaced to fix the problem.
+///
+/// This kind of hint should be used when we are certain that the
+/// introduction, removal, or modification of a particular (small!)
+/// amount of code will correct a compilation error. The compiler
+/// should also provide full recovery from such errors, such that
+/// suppressing the diagnostic output can still result in successful
+/// compilation.
+class FixItHint {
+public:
+  /// \brief Code that should be replaced to correct the error. Empty for an
+  /// insertion hint.
+  CharSourceRange RemoveRange;
+
+  /// \brief Code in the specific range that should be inserted in the insertion
+  /// location.
+  CharSourceRange InsertFromRange;
+
+  /// \brief The actual code to insert at the insertion location, as a
+  /// string.
+  std::string CodeToInsert;
+
+  bool BeforePreviousInsertions;
+
+  /// \brief Empty code modification hint, indicating that no code
+  /// modification is known.
+  FixItHint() : BeforePreviousInsertions(false) { }
+
+  bool isNull() const {
+    return !RemoveRange.isValid();
+  }
+  
+  /// \brief Create a code modification hint that inserts the given
+  /// code string at a specific location.
+  static FixItHint CreateInsertion(SourceLocation InsertionLoc,
+                                   StringRef Code,
+                                   bool BeforePreviousInsertions = false) {
+    FixItHint Hint;
+    Hint.RemoveRange =
+      CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
+    Hint.CodeToInsert = Code;
+    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
+    return Hint;
+  }
+  
+  /// \brief Create a code modification hint that inserts the given
+  /// code from \p FromRange at a specific location.
+  static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
+                                            CharSourceRange FromRange,
+                                        bool BeforePreviousInsertions = false) {
+    FixItHint Hint;
+    Hint.RemoveRange =
+      CharSourceRange::getCharRange(InsertionLoc, InsertionLoc);
+    Hint.InsertFromRange = FromRange;
+    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
+    return Hint;
+  }
+
+  /// \brief Create a code modification hint that removes the given
+  /// source range.
+  static FixItHint CreateRemoval(CharSourceRange RemoveRange) {
+    FixItHint Hint;
+    Hint.RemoveRange = RemoveRange;
+    return Hint;
+  }
+  static FixItHint CreateRemoval(SourceRange RemoveRange) {
+    return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange));
+  }
+  
+  /// \brief Create a code modification hint that replaces the given
+  /// source range with the given code string.
+  static FixItHint CreateReplacement(CharSourceRange RemoveRange,
+                                     StringRef Code) {
+    FixItHint Hint;
+    Hint.RemoveRange = RemoveRange;
+    Hint.CodeToInsert = Code;
+    return Hint;
+  }
+  
+  static FixItHint CreateReplacement(SourceRange RemoveRange,
+                                     StringRef Code) {
+    return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code);
+  }
+};
+
+/// \brief Concrete class used by the front-end to report problems and issues.
+///
+/// This massages the diagnostics (e.g. handling things like "report warnings
+/// as errors" and passes them off to the DiagnosticConsumer for reporting to
+/// the user. DiagnosticsEngine is tied to one translation unit and one
+/// SourceManager.
+class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
+  DiagnosticsEngine(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+  void operator=(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+
+public:
+  /// \brief The level of the diagnostic, after it has been through mapping.
+  enum Level {
+    Ignored = DiagnosticIDs::Ignored,
+    Note = DiagnosticIDs::Note,
+    Remark = DiagnosticIDs::Remark,
+    Warning = DiagnosticIDs::Warning,
+    Error = DiagnosticIDs::Error,
+    Fatal = DiagnosticIDs::Fatal
+  };
+
+  enum ArgumentKind {
+    ak_std_string,      ///< std::string
+    ak_c_string,        ///< const char *
+    ak_sint,            ///< int
+    ak_uint,            ///< unsigned
+    ak_tokenkind,       ///< enum TokenKind : unsigned
+    ak_identifierinfo,  ///< IdentifierInfo
+    ak_qualtype,        ///< QualType
+    ak_declarationname, ///< DeclarationName
+    ak_nameddecl,       ///< NamedDecl *
+    ak_nestednamespec,  ///< NestedNameSpecifier *
+    ak_declcontext,     ///< DeclContext *
+    ak_qualtype_pair,   ///< pair<QualType, QualType>
+    ak_attr             ///< Attr *
+  };
+
+  /// \brief Represents on argument value, which is a union discriminated
+  /// by ArgumentKind, with a value.
+  typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
+
+private:
+  unsigned char AllExtensionsSilenced; // Used by __extension__
+  bool IgnoreAllWarnings;        // Ignore all warnings: -w
+  bool WarningsAsErrors;         // Treat warnings like errors.
+  bool EnableAllWarnings;        // Enable all warnings.
+  bool ErrorsAsFatal;            // Treat errors like fatal errors.
+  bool SuppressSystemWarnings;   // Suppress warnings in system headers.
+  bool SuppressAllDiagnostics;   // Suppress all diagnostics.
+  bool ElideType;                // Elide common types of templates.
+  bool PrintTemplateTree;        // Print a tree when comparing templates.
+  bool ShowColors;               // Color printing is enabled.
+  OverloadsShown ShowOverloads;  // Which overload candidates to show.
+  unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
+  unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
+                                   // 0 -> no limit.
+  unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
+                                    // backtrace stack, 0 -> no limit.
+  diag::Severity ExtBehavior;       // Map extensions to warnings or errors?
+  IntrusiveRefCntPtr<DiagnosticIDs> Diags;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  DiagnosticConsumer *Client;
+  bool OwnsDiagClient;
+  SourceManager *SourceMgr;
+
+  /// \brief Mapping information for diagnostics.
+  ///
+  /// Mapping info is packed into four bits per diagnostic.  The low three
+  /// bits are the mapping (an instance of diag::Severity), or zero if unset.
+  /// The high bit is set when the mapping was established as a user mapping.
+  /// If the high bit is clear, then the low bits are set to the default
+  /// value, and should be mapped with -pedantic, -Werror, etc.
+  ///
+  /// A new DiagState is created and kept around when diagnostic pragmas modify
+  /// the state so that we know what is the diagnostic state at any given
+  /// source location.
+  class DiagState {
+    llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
+
+  public:
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
+    const_iterator;
+
+    void setMapping(diag::kind Diag, DiagnosticMapping Info) {
+      DiagMap[Diag] = Info;
+    }
+
+    DiagnosticMapping &getOrAddMapping(diag::kind Diag);
+
+    const_iterator begin() const { return DiagMap.begin(); }
+    const_iterator end() const { return DiagMap.end(); }
+  };
+
+  /// \brief Keeps and automatically disposes all DiagStates that we create.
+  std::list<DiagState> DiagStates;
+
+  /// \brief Represents a point in source where the diagnostic state was
+  /// modified because of a pragma.
+  ///
+  /// 'Loc' can be null if the point represents the diagnostic state
+  /// modifications done through the command-line.
+  struct DiagStatePoint {
+    DiagState *State;
+    FullSourceLoc Loc;
+    DiagStatePoint(DiagState *State, FullSourceLoc Loc)
+      : State(State), Loc(Loc) { } 
+    
+    bool operator<(const DiagStatePoint &RHS) const {
+      // If Loc is invalid it means it came from <command-line>, in which case
+      // we regard it as coming before any valid source location.
+      if (RHS.Loc.isInvalid())
+        return false;
+      if (Loc.isInvalid())
+        return true;
+      return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
+    }
+  };
+
+  /// \brief A sorted vector of all DiagStatePoints representing changes in
+  /// diagnostic state due to diagnostic pragmas.
+  ///
+  /// The vector is always sorted according to the SourceLocation of the
+  /// DiagStatePoint.
+  typedef std::vector<DiagStatePoint> DiagStatePointsTy;
+  mutable DiagStatePointsTy DiagStatePoints;
+
+  /// \brief Keeps the DiagState that was active during each diagnostic 'push'
+  /// so we can get back at it when we 'pop'.
+  std::vector<DiagState *> DiagStateOnPushStack;
+
+  DiagState *GetCurDiagState() const {
+    assert(!DiagStatePoints.empty());
+    return DiagStatePoints.back().State;
+  }
+
+  void PushDiagStatePoint(DiagState *State, SourceLocation L) {
+    FullSourceLoc Loc(L, getSourceManager());
+    // Make sure that DiagStatePoints is always sorted according to Loc.
+    assert(Loc.isValid() && "Adding invalid loc point");
+    assert(!DiagStatePoints.empty() &&
+           (DiagStatePoints.back().Loc.isInvalid() ||
+            DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
+           "Previous point loc comes after or is the same as new one");
+    DiagStatePoints.push_back(DiagStatePoint(State, Loc));
+  }
+
+  /// \brief Finds the DiagStatePoint that contains the diagnostic state of
+  /// the given source location.
+  DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
+
+  /// \brief Sticky flag set to \c true when an error is emitted.
+  bool ErrorOccurred;
+
+  /// \brief Sticky flag set to \c true when an "uncompilable error" occurs.
+  /// I.e. an error that was not upgraded from a warning by -Werror.
+  bool UncompilableErrorOccurred;
+
+  /// \brief Sticky flag set to \c true when a fatal error is emitted.
+  bool FatalErrorOccurred;
+
+  /// \brief Indicates that an unrecoverable error has occurred.
+  bool UnrecoverableErrorOccurred;
+  
+  /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
+  /// during a parsing section, e.g. during parsing a function.
+  unsigned TrapNumErrorsOccurred;
+  unsigned TrapNumUnrecoverableErrorsOccurred;
+
+  /// \brief The level of the last diagnostic emitted.
+  ///
+  /// This is used to emit continuation diagnostics with the same level as the
+  /// diagnostic that they follow.
+  DiagnosticIDs::Level LastDiagLevel;
+
+  unsigned NumWarnings;         ///< Number of warnings reported
+  unsigned NumErrors;           ///< Number of errors reported
+  unsigned NumErrorsSuppressed; ///< Number of errors suppressed
+
+  /// \brief A function pointer that converts an opaque diagnostic
+  /// argument to a strings.
+  ///
+  /// This takes the modifiers and argument that was present in the diagnostic.
+  ///
+  /// The PrevArgs array indicates the previous arguments formatted for this
+  /// diagnostic.  Implementations of this function can use this information to
+  /// avoid redundancy across arguments.
+  ///
+  /// This is a hack to avoid a layering violation between libbasic and libsema.
+  typedef void (*ArgToStringFnTy)(
+      ArgumentKind Kind, intptr_t Val,
+      StringRef Modifier, StringRef Argument,
+      ArrayRef<ArgumentValue> PrevArgs,
+      SmallVectorImpl<char> &Output,
+      void *Cookie,
+      ArrayRef<intptr_t> QualTypeVals);
+  void *ArgToStringCookie;
+  ArgToStringFnTy ArgToStringFn;
+
+  /// \brief ID of the "delayed" diagnostic, which is a (typically
+  /// fatal) diagnostic that had to be delayed because it was found
+  /// while emitting another diagnostic.
+  unsigned DelayedDiagID;
+
+  /// \brief First string argument for the delayed diagnostic.
+  std::string DelayedDiagArg1;
+
+  /// \brief Second string argument for the delayed diagnostic.
+  std::string DelayedDiagArg2;
+
+  /// \brief Optional flag value.
+  ///
+  /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
+  /// -Rpass=<value>. The content of this string is emitted after the flag name
+  /// and '='.
+  std::string FlagValue;
+
+public:
+  explicit DiagnosticsEngine(
+                      const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
+                      DiagnosticOptions *DiagOpts,
+                      DiagnosticConsumer *client = nullptr,
+                      bool ShouldOwnClient = true);
+  ~DiagnosticsEngine();
+
+  const IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const {
+    return Diags;
+  }
+
+  /// \brief Retrieve the diagnostic options.
+  DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
+
+  typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
+
+  /// \brief Get the current set of diagnostic mappings.
+  diag_mapping_range getDiagnosticMappings() const {
+    const DiagState &DS = *GetCurDiagState();
+    return diag_mapping_range(DS.begin(), DS.end());
+  }
+
+  DiagnosticConsumer *getClient() { return Client; }
+  const DiagnosticConsumer *getClient() const { return Client; }
+
+  /// \brief Determine whether this \c DiagnosticsEngine object own its client.
+  bool ownsClient() const { return OwnsDiagClient; }
+  
+  /// \brief Return the current diagnostic client along with ownership of that
+  /// client.
+  DiagnosticConsumer *takeClient() {
+    OwnsDiagClient = false;
+    return Client;
+  }
+
+  bool hasSourceManager() const { return SourceMgr != nullptr; }
+  SourceManager &getSourceManager() const {
+    assert(SourceMgr && "SourceManager not set!");
+    return *SourceMgr;
+  }
+  void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
+
+  //===--------------------------------------------------------------------===//
+  //  DiagnosticsEngine characterization methods, used by a client to customize
+  //  how diagnostics are emitted.
+  //
+
+  /// \brief Copies the current DiagMappings and pushes the new copy
+  /// onto the top of the stack.
+  void pushMappings(SourceLocation Loc);
+
+  /// \brief Pops the current DiagMappings off the top of the stack,
+  /// causing the new top of the stack to be the active mappings.
+  ///
+  /// \returns \c true if the pop happens, \c false if there is only one
+  /// DiagMapping on the stack.
+  bool popMappings(SourceLocation Loc);
+
+  /// \brief Set the diagnostic client associated with this diagnostic object.
+  ///
+  /// \param ShouldOwnClient true if the diagnostic object should take
+  /// ownership of \c client.
+  void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true);
+
+  /// \brief Specify a limit for the number of errors we should
+  /// emit before giving up.
+  ///
+  /// Zero disables the limit.
+  void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
+  
+  /// \brief Specify the maximum number of template instantiation
+  /// notes to emit along with a given diagnostic.
+  void setTemplateBacktraceLimit(unsigned Limit) {
+    TemplateBacktraceLimit = Limit;
+  }
+
+  /// \brief Retrieve the maximum number of template instantiation
+  /// notes to emit along with a given diagnostic.
+  unsigned getTemplateBacktraceLimit() const {
+    return TemplateBacktraceLimit;
+  }
+
+  /// \brief Specify the maximum number of constexpr evaluation
+  /// notes to emit along with a given diagnostic.
+  void setConstexprBacktraceLimit(unsigned Limit) {
+    ConstexprBacktraceLimit = Limit;
+  }
+
+  /// \brief Retrieve the maximum number of constexpr evaluation
+  /// notes to emit along with a given diagnostic.
+  unsigned getConstexprBacktraceLimit() const {
+    return ConstexprBacktraceLimit;
+  }
+
+  /// \brief When set to true, any unmapped warnings are ignored.
+  ///
+  /// If this and WarningsAsErrors are both set, then this one wins.
+  void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
+  bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
+
+  /// \brief When set to true, any unmapped ignored warnings are no longer
+  /// ignored.
+  ///
+  /// If this and IgnoreAllWarnings are both set, then that one wins.
+  void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; }
+  bool getEnableAllWarnings() const { return EnableAllWarnings; }
+
+  /// \brief When set to true, any warnings reported are issued as errors.
+  void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
+  bool getWarningsAsErrors() const { return WarningsAsErrors; }
+
+  /// \brief When set to true, any error reported is made a fatal error.
+  void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; }
+  bool getErrorsAsFatal() const { return ErrorsAsFatal; }
+
+  /// \brief When set to true mask warnings that come from system headers.
+  void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
+  bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
+
+  /// \brief Suppress all diagnostics, to silence the front end when we 
+  /// know that we don't want any more diagnostics to be passed along to the
+  /// client
+  void setSuppressAllDiagnostics(bool Val = true) { 
+    SuppressAllDiagnostics = Val; 
+  }
+  bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
+
+  /// \brief Set type eliding, to skip outputting same types occurring in
+  /// template types.
+  void setElideType(bool Val = true) { ElideType = Val; }
+  bool getElideType() { return ElideType; }
+ 
+  /// \brief Set tree printing, to outputting the template difference in a
+  /// tree format.
+  void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; }
+  bool getPrintTemplateTree() { return PrintTemplateTree; }
+ 
+  /// \brief Set color printing, so the type diffing will inject color markers
+  /// into the output.
+  void setShowColors(bool Val = false) { ShowColors = Val; }
+  bool getShowColors() { return ShowColors; }
+
+  /// \brief Specify which overload candidates to show when overload resolution
+  /// fails.
+  ///
+  /// By default, we show all candidates.
+  void setShowOverloads(OverloadsShown Val) {
+    ShowOverloads = Val;
+  }
+  OverloadsShown getShowOverloads() const { return ShowOverloads; }
+  
+  /// \brief Pretend that the last diagnostic issued was ignored, so any
+  /// subsequent notes will be suppressed.
+  ///
+  /// This can be used by clients who suppress diagnostics themselves.
+  void setLastDiagnosticIgnored() {
+    if (LastDiagLevel == DiagnosticIDs::Fatal)
+      FatalErrorOccurred = true;
+    LastDiagLevel = DiagnosticIDs::Ignored;
+  }
+
+  /// \brief Determine whether the previous diagnostic was ignored. This can
+  /// be used by clients that want to determine whether notes attached to a
+  /// diagnostic will be suppressed.
+  bool isLastDiagnosticIgnored() const {
+    return LastDiagLevel == DiagnosticIDs::Ignored;
+  }
+
+  /// \brief Controls whether otherwise-unmapped extension diagnostics are
+  /// mapped onto ignore/warning/error. 
+  ///
+  /// This corresponds to the GCC -pedantic and -pedantic-errors option.
+  void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; }
+  diag::Severity getExtensionHandlingBehavior() const { return ExtBehavior; }
+
+  /// \brief Counter bumped when an __extension__  block is/ encountered.
+  ///
+  /// When non-zero, all extension diagnostics are entirely silenced, no
+  /// matter how they are mapped.
+  void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
+  void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
+  bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
+
+  /// \brief This allows the client to specify that certain warnings are
+  /// ignored.
+  ///
+  /// Notes can never be mapped, errors can only be mapped to fatal, and
+  /// WARNINGs and EXTENSIONs can be mapped arbitrarily.
+  ///
+  /// \param Loc The source location that this change of diagnostic state should
+  /// take affect. It can be null if we are setting the latest state.
+  void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
+
+  /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
+  /// have the specified mapping.
+  ///
+  /// \returns true (and ignores the request) if "Group" was unknown, false
+  /// otherwise.
+  ///
+  /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
+  /// state of the -Wfoo group and vice versa.
+  ///
+  /// \param Loc The source location that this change of diagnostic state should
+  /// take affect. It can be null if we are setting the state from command-line.
+  bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
+                           diag::Severity Map,
+                           SourceLocation Loc = SourceLocation());
+
+  /// \brief Set the warning-as-error flag for the given diagnostic group.
+  ///
+  /// This function always only operates on the current diagnostic state.
+  ///
+  /// \returns True if the given group is unknown, false otherwise.
+  bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
+
+  /// \brief Set the error-as-fatal flag for the given diagnostic group.
+  ///
+  /// This function always only operates on the current diagnostic state.
+  ///
+  /// \returns True if the given group is unknown, false otherwise.
+  bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
+
+  /// \brief Add the specified mapping to all diagnostics of the specified
+  /// flavor.
+  ///
+  /// Mainly to be used by -Wno-everything to disable all warnings but allow
+  /// subsequent -W options to enable specific warnings.
+  void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
+                         SourceLocation Loc = SourceLocation());
+
+  bool hasErrorOccurred() const { return ErrorOccurred; }
+
+  /// \brief Errors that actually prevent compilation, not those that are
+  /// upgraded from a warning by -Werror.
+  bool hasUncompilableErrorOccurred() const {
+    return UncompilableErrorOccurred;
+  }
+  bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
+  
+  /// \brief Determine whether any kind of unrecoverable error has occurred.
+  bool hasUnrecoverableErrorOccurred() const {
+    return FatalErrorOccurred || UnrecoverableErrorOccurred;
+  }
+  
+  unsigned getNumWarnings() const { return NumWarnings; }
+
+  void setNumWarnings(unsigned NumWarnings) {
+    this->NumWarnings = NumWarnings;
+  }
+
+  /// \brief Return an ID for a diagnostic with the specified format string and
+  /// level.
+  ///
+  /// If this is the first request for this diagnostic, it is registered and
+  /// created, otherwise the existing ID is returned.
+  ///
+  /// \param FormatString A fixed diagnostic format string that will be hashed
+  /// and mapped to a unique DiagID.
+  template <unsigned N>
+  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
+    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
+                                  StringRef(FormatString, N - 1));
+  }
+
+  /// \brief Converts a diagnostic argument (as an intptr_t) into the string
+  /// that represents it.
+  void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
+                          StringRef Modifier, StringRef Argument,
+                          ArrayRef<ArgumentValue> PrevArgs,
+                          SmallVectorImpl<char> &Output,
+                          ArrayRef<intptr_t> QualTypeVals) const {
+    ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
+                  ArgToStringCookie, QualTypeVals);
+  }
+
+  void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
+    ArgToStringFn = Fn;
+    ArgToStringCookie = Cookie;
+  }
+
+  /// \brief Note that the prior diagnostic was emitted by some other
+  /// \c DiagnosticsEngine, and we may be attaching a note to that diagnostic.
+  void notePriorDiagnosticFrom(const DiagnosticsEngine &Other) {
+    LastDiagLevel = Other.LastDiagLevel;
+  }
+
+  /// \brief Reset the state of the diagnostic object to its initial 
+  /// configuration.
+  void Reset();
+  
+  //===--------------------------------------------------------------------===//
+  // DiagnosticsEngine classification and reporting interfaces.
+  //
+
+  /// \brief Determine whether the diagnostic is known to be ignored.
+  ///
+  /// This can be used to opportunistically avoid expensive checks when it's
+  /// known for certain that the diagnostic has been suppressed at the
+  /// specified location \p Loc.
+  ///
+  /// \param Loc The source location we are interested in finding out the
+  /// diagnostic state. Can be null in order to query the latest state.
+  bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
+    return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
+           diag::Severity::Ignored;
+  }
+
+  /// \brief Based on the way the client configured the DiagnosticsEngine
+  /// object, classify the specified diagnostic ID into a Level, consumable by
+  /// the DiagnosticConsumer.
+  ///
+  /// To preserve invariant assumptions, this function should not be used to
+  /// influence parse or semantic analysis actions. Instead consider using
+  /// \c isIgnored().
+  ///
+  /// \param Loc The source location we are interested in finding out the
+  /// diagnostic state. Can be null in order to query the latest state.
+  Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
+    return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this);
+  }
+
+  /// \brief Issue the message to the client.
+  ///
+  /// This actually returns an instance of DiagnosticBuilder which emits the
+  /// diagnostics (through @c ProcessDiag) when it is destroyed.
+  ///
+  /// \param DiagID A member of the @c diag::kind enum.
+  /// \param Loc Represents the source location associated with the diagnostic,
+  /// which can be an invalid location if no position information is available.
+  inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID);
+  inline DiagnosticBuilder Report(unsigned DiagID);
+
+  void Report(const StoredDiagnostic &storedDiag);
+
+  /// \brief Determine whethere there is already a diagnostic in flight.
+  bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
+
+  /// \brief Set the "delayed" diagnostic that will be emitted once
+  /// the current diagnostic completes.
+  ///
+  ///  If a diagnostic is already in-flight but the front end must
+  ///  report a problem (e.g., with an inconsistent file system
+  ///  state), this routine sets a "delayed" diagnostic that will be
+  ///  emitted after the current diagnostic completes. This should
+  ///  only be used for fatal errors detected at inconvenient
+  ///  times. If emitting a delayed diagnostic causes a second delayed
+  ///  diagnostic to be introduced, that second delayed diagnostic
+  ///  will be ignored.
+  ///
+  /// \param DiagID The ID of the diagnostic being delayed.
+  ///
+  /// \param Arg1 A string argument that will be provided to the
+  /// diagnostic. A copy of this string will be stored in the
+  /// DiagnosticsEngine object itself.
+  ///
+  /// \param Arg2 A string argument that will be provided to the
+  /// diagnostic. A copy of this string will be stored in the
+  /// DiagnosticsEngine object itself.
+  void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "",
+                            StringRef Arg2 = "");
+  
+  /// \brief Clear out the current diagnostic.
+  void Clear() { CurDiagID = ~0U; }
+
+  /// \brief Return the value associated with this diagnostic flag.
+  StringRef getFlagValue() const { return FlagValue; }
+
+private:
+  /// \brief Report the delayed diagnostic.
+  void ReportDelayed();
+
+  // This is private state used by DiagnosticBuilder.  We put it here instead of
+  // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
+  // object.  This implementation choice means that we can only have one
+  // diagnostic "in flight" at a time, but this seems to be a reasonable
+  // tradeoff to keep these objects small.  Assertions verify that only one
+  // diagnostic is in flight at a time.
+  friend class DiagnosticIDs;
+  friend class DiagnosticBuilder;
+  friend class Diagnostic;
+  friend class PartialDiagnostic;
+  friend class DiagnosticErrorTrap;
+  
+  /// \brief The location of the current diagnostic that is in flight.
+  SourceLocation CurDiagLoc;
+
+  /// \brief The ID of the current diagnostic that is in flight.
+  ///
+  /// This is set to ~0U when there is no diagnostic in flight.
+  unsigned CurDiagID;
+
+  enum {
+    /// \brief The maximum number of arguments we can hold.
+    ///
+    /// We currently only support up to 10 arguments (%0-%9).  A single
+    /// diagnostic with more than that almost certainly has to be simplified
+    /// anyway.
+    MaxArguments = 10,
+  };
+
+  /// \brief The number of entries in Arguments.
+  signed char NumDiagArgs;
+
+  /// \brief Specifies whether an argument is in DiagArgumentsStr or
+  /// in DiagArguments.
+  ///
+  /// This is an array of ArgumentKind::ArgumentKind enum values, one for each
+  /// argument.
+  unsigned char DiagArgumentsKind[MaxArguments];
+
+  /// \brief Holds the values of each string argument for the current
+  /// diagnostic.
+  ///
+  /// This is only used when the corresponding ArgumentKind is ak_std_string.
+  std::string DiagArgumentsStr[MaxArguments];
+
+  /// \brief The values for the various substitution positions.
+  ///
+  /// This is used when the argument is not an std::string.  The specific
+  /// value is mangled into an intptr_t and the interpretation depends on
+  /// exactly what sort of argument kind it is.
+  intptr_t DiagArgumentsVal[MaxArguments];
+
+  /// \brief The list of ranges added to this diagnostic.
+  SmallVector<CharSourceRange, 8> DiagRanges;
+
+  /// \brief If valid, provides a hint with some code to insert, remove,
+  /// or modify at a particular position.
+  SmallVector<FixItHint, 8> DiagFixItHints;
+
+  DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
+    bool isPragma = L.isValid();
+    DiagnosticMapping Mapping =
+        DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
+
+    // If this is a pragma mapping, then set the diagnostic mapping flags so
+    // that we override command line options.
+    if (isPragma) {
+      Mapping.setNoWarningAsError(true);
+      Mapping.setNoErrorAsFatal(true);
+    }
+
+    return Mapping;
+  }
+
+  /// \brief Used to report a diagnostic that is finally fully formed.
+  ///
+  /// \returns true if the diagnostic was emitted, false if it was suppressed.
+  bool ProcessDiag() {
+    return Diags->ProcessDiag(*this);
+  }
+
+  /// @name Diagnostic Emission
+  /// @{
+protected:
+  // Sema requires access to the following functions because the current design
+  // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
+  // access us directly to ensure we minimize the emitted code for the common
+  // Sema::Diag() patterns.
+  friend class Sema;
+
+  /// \brief Emit the current diagnostic and clear the diagnostic state.
+  ///
+  /// \param Force Emit the diagnostic regardless of suppression settings.
+  bool EmitCurrentDiagnostic(bool Force = false);
+
+  unsigned getCurrentDiagID() const { return CurDiagID; }
+
+  SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
+
+  /// @}
+
+  friend class ASTReader;
+  friend class ASTWriter;
+};
+
+/// \brief RAII class that determines when any errors have occurred
+/// between the time the instance was created and the time it was
+/// queried.
+class DiagnosticErrorTrap {
+  DiagnosticsEngine &Diag;
+  unsigned NumErrors;
+  unsigned NumUnrecoverableErrors;
+
+public:
+  explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag)
+    : Diag(Diag) { reset(); }
+
+  /// \brief Determine whether any errors have occurred since this
+  /// object instance was created.
+  bool hasErrorOccurred() const {
+    return Diag.TrapNumErrorsOccurred > NumErrors;
+  }
+
+  /// \brief Determine whether any unrecoverable errors have occurred since this
+  /// object instance was created.
+  bool hasUnrecoverableErrorOccurred() const {
+    return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
+  }
+
+  /// \brief Set to initial state of "no errors occurred".
+  void reset() {
+    NumErrors = Diag.TrapNumErrorsOccurred;
+    NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// DiagnosticBuilder
+//===----------------------------------------------------------------------===//
+
+/// \brief A little helper class used to produce diagnostics.
+///
+/// This is constructed by the DiagnosticsEngine::Report method, and
+/// allows insertion of extra information (arguments and source ranges) into
+/// the currently "in flight" diagnostic.  When the temporary for the builder
+/// is destroyed, the diagnostic is issued.
+///
+/// Note that many of these will be created as temporary objects (many call
+/// sites), so we want them to be small and we never want their address taken.
+/// This ensures that compilers with somewhat reasonable optimizers will promote
+/// the common fields to registers, eliminating increments of the NumArgs field,
+/// for example.
+class DiagnosticBuilder {
+  mutable DiagnosticsEngine *DiagObj;
+  mutable unsigned NumArgs;
+
+  /// \brief Status variable indicating if this diagnostic is still active.
+  ///
+  // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
+  // but LLVM is not currently smart enough to eliminate the null check that
+  // Emit() would end up with if we used that as our status variable.
+  mutable bool IsActive;
+
+  /// \brief Flag indicating that this diagnostic is being emitted via a
+  /// call to ForceEmit.
+  mutable bool IsForceEmit;
+
+  void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION;
+  friend class DiagnosticsEngine;
+
+  DiagnosticBuilder()
+      : DiagObj(nullptr), NumArgs(0), IsActive(false), IsForceEmit(false) {}
+
+  explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
+      : DiagObj(diagObj), NumArgs(0), IsActive(true), IsForceEmit(false) {
+    assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
+    diagObj->DiagRanges.clear();
+    diagObj->DiagFixItHints.clear();
+  }
+
+  friend class PartialDiagnostic;
+  
+protected:
+  void FlushCounts() {
+    DiagObj->NumDiagArgs = NumArgs;
+  }
+
+  /// \brief Clear out the current diagnostic.
+  void Clear() const {
+    DiagObj = nullptr;
+    IsActive = false;
+    IsForceEmit = false;
+  }
+
+  /// \brief Determine whether this diagnostic is still active.
+  bool isActive() const { return IsActive; }
+
+  /// \brief Force the diagnostic builder to emit the diagnostic now.
+  ///
+  /// Once this function has been called, the DiagnosticBuilder object
+  /// should not be used again before it is destroyed.
+  ///
+  /// \returns true if a diagnostic was emitted, false if the
+  /// diagnostic was suppressed.
+  bool Emit() {
+    // If this diagnostic is inactive, then its soul was stolen by the copy ctor
+    // (or by a subclass, as in SemaDiagnosticBuilder).
+    if (!isActive()) return false;
+
+    // When emitting diagnostics, we set the final argument count into
+    // the DiagnosticsEngine object.
+    FlushCounts();
+
+    // Process the diagnostic.
+    bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
+
+    // This diagnostic is dead.
+    Clear();
+
+    return Result;
+  }
+  
+public:
+  /// Copy constructor.  When copied, this "takes" the diagnostic info from the
+  /// input and neuters it.
+  DiagnosticBuilder(const DiagnosticBuilder &D) {
+    DiagObj = D.DiagObj;
+    IsActive = D.IsActive;
+    IsForceEmit = D.IsForceEmit;
+    D.Clear();
+    NumArgs = D.NumArgs;
+  }
+
+  /// \brief Retrieve an empty diagnostic builder.
+  static DiagnosticBuilder getEmpty() {
+    return DiagnosticBuilder();
+  }
+
+  /// \brief Emits the diagnostic.
+  ~DiagnosticBuilder() {
+    Emit();
+  }
+  
+  /// \brief Forces the diagnostic to be emitted.
+  const DiagnosticBuilder &setForceEmit() const {
+    IsForceEmit = true;
+    return *this;
+  }
+
+  /// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
+  ///
+  /// This allows is to be used in boolean error contexts (where \c true is
+  /// used to indicate that an error has occurred), like:
+  /// \code
+  /// return Diag(...);
+  /// \endcode
+  operator bool() const { return true; }
+
+  void AddString(StringRef S) const {
+    assert(isActive() && "Clients must not add to cleared diagnostic!");
+    assert(NumArgs < DiagnosticsEngine::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
+    DiagObj->DiagArgumentsStr[NumArgs++] = S;
+  }
+
+  void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
+    assert(isActive() && "Clients must not add to cleared diagnostic!");
+    assert(NumArgs < DiagnosticsEngine::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagObj->DiagArgumentsKind[NumArgs] = Kind;
+    DiagObj->DiagArgumentsVal[NumArgs++] = V;
+  }
+
+  void AddSourceRange(const CharSourceRange &R) const {
+    assert(isActive() && "Clients must not add to cleared diagnostic!");
+    DiagObj->DiagRanges.push_back(R);
+  }
+
+  void AddFixItHint(const FixItHint &Hint) const {
+    assert(isActive() && "Clients must not add to cleared diagnostic!");
+    DiagObj->DiagFixItHints.push_back(Hint);
+  }
+
+  void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
+};
+
+struct AddFlagValue {
+  explicit AddFlagValue(StringRef V) : Val(V) {}
+  StringRef Val;
+};
+
+/// \brief Register a value for the flag in the current diagnostic. This
+/// value will be shown as the suffix "=value" after the flag name. It is
+/// useful in cases where the diagnostic flag accepts values (e.g.,
+/// -Rpass or -Wframe-larger-than).
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const AddFlagValue V) {
+  DB.addFlagValue(V.Val);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           StringRef S) {
+  DB.AddString(S);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const char *Str) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
+                  DiagnosticsEngine::ak_c_string);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
+  DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
+  return DB;
+}
+
+// We use enable_if here to prevent that this overload is selected for
+// pointers or other arguments that are implicitly convertible to bool.
+template <typename T>
+inline
+typename std::enable_if<std::is_same<T, bool>::value,
+                        const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T I) {
+  DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           unsigned I) {
+  DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           tok::TokenKind I) {
+  DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const IdentifierInfo *II) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
+                  DiagnosticsEngine::ak_identifierinfo);
+  return DB;
+}
+
+// Adds a DeclContext to the diagnostic. The enable_if template magic is here
+// so that we only match those arguments that are (statically) DeclContexts;
+// other arguments that derive from DeclContext (e.g., RecordDecls) will not
+// match.
+template<typename T>
+inline
+typename std::enable_if<std::is_same<T, DeclContext>::value,
+                        const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T *DC) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+                  DiagnosticsEngine::ak_declcontext);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const SourceRange &R) {
+  DB.AddSourceRange(CharSourceRange::getTokenRange(R));
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           ArrayRef<SourceRange> Ranges) {
+  for (const SourceRange &R: Ranges)
+    DB.AddSourceRange(CharSourceRange::getTokenRange(R));
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const CharSourceRange &R) {
+  DB.AddSourceRange(R);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const FixItHint &Hint) {
+  if (!Hint.isNull())
+    DB.AddFixItHint(Hint);
+  return DB;
+}
+
+inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
+                                                   unsigned DiagID) {
+  assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
+  CurDiagLoc = Loc;
+  CurDiagID = DiagID;
+  FlagValue.clear();
+  return DiagnosticBuilder(this);
+}
+
+inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
+  return Report(SourceLocation(), DiagID);
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnostic
+//===----------------------------------------------------------------------===//
+
+/// A little helper class (which is basically a smart pointer that forwards
+/// info from DiagnosticsEngine) that allows clients to enquire about the
+/// currently in-flight diagnostic.
+class Diagnostic {
+  const DiagnosticsEngine *DiagObj;
+  StringRef StoredDiagMessage;
+public:
+  explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
+  Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage)
+    : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
+
+  const DiagnosticsEngine *getDiags() const { return DiagObj; }
+  unsigned getID() const { return DiagObj->CurDiagID; }
+  const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; }
+  bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
+  SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
+
+  unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
+
+  /// \brief Return the kind of the specified index.
+  ///
+  /// Based on the kind of argument, the accessors below can be used to get
+  /// the value.
+  ///
+  /// \pre Idx < getNumArgs()
+  DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
+    assert(Idx < getNumArgs() && "Argument index out of range!");
+    return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
+  }
+
+  /// \brief Return the provided argument string specified by \p Idx.
+  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
+  const std::string &getArgStdStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
+           "invalid argument accessor!");
+    return DiagObj->DiagArgumentsStr[Idx];
+  }
+
+  /// \brief Return the specified C string argument.
+  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
+  const char *getArgCStr(unsigned Idx) const {
+    assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
+           "invalid argument accessor!");
+    return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
+  }
+
+  /// \brief Return the specified signed integer argument.
+  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
+  int getArgSInt(unsigned Idx) const {
+    assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
+           "invalid argument accessor!");
+    return (int)DiagObj->DiagArgumentsVal[Idx];
+  }
+
+  /// \brief Return the specified unsigned integer argument.
+  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
+  unsigned getArgUInt(unsigned Idx) const {
+    assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
+           "invalid argument accessor!");
+    return (unsigned)DiagObj->DiagArgumentsVal[Idx];
+  }
+
+  /// \brief Return the specified IdentifierInfo argument.
+  /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
+  const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
+    assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
+           "invalid argument accessor!");
+    return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
+  }
+
+  /// \brief Return the specified non-string argument in an opaque form.
+  /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
+  intptr_t getRawArg(unsigned Idx) const {
+    assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
+           "invalid argument accessor!");
+    return DiagObj->DiagArgumentsVal[Idx];
+  }
+
+  /// \brief Return the number of source ranges associated with this diagnostic.
+  unsigned getNumRanges() const {
+    return DiagObj->DiagRanges.size();
+  }
+
+  /// \pre Idx < getNumRanges()
+  const CharSourceRange &getRange(unsigned Idx) const {
+    assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
+    return DiagObj->DiagRanges[Idx];
+  }
+
+  /// \brief Return an array reference for this diagnostic's ranges.
+  ArrayRef<CharSourceRange> getRanges() const {
+    return DiagObj->DiagRanges;
+  }
+
+  unsigned getNumFixItHints() const {
+    return DiagObj->DiagFixItHints.size();
+  }
+
+  const FixItHint &getFixItHint(unsigned Idx) const {
+    assert(Idx < getNumFixItHints() && "Invalid index!");
+    return DiagObj->DiagFixItHints[Idx];
+  }
+
+  ArrayRef<FixItHint> getFixItHints() const {
+    return DiagObj->DiagFixItHints;
+  }
+
+  /// \brief Format this diagnostic into a string, substituting the
+  /// formal arguments into the %0 slots.
+  ///
+  /// The result is appended onto the \p OutStr array.
+  void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const;
+
+  /// \brief Format the given format-string into the output buffer using the
+  /// arguments stored in this diagnostic.
+  void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
+                        SmallVectorImpl<char> &OutStr) const;
+};
+
+/**
+ * \brief Represents a diagnostic in a form that can be retained until its 
+ * corresponding source manager is destroyed. 
+ */
+class StoredDiagnostic {
+  unsigned ID;
+  DiagnosticsEngine::Level Level;
+  FullSourceLoc Loc;
+  std::string Message;
+  std::vector<CharSourceRange> Ranges;
+  std::vector<FixItHint> FixIts;
+
+public:
+  StoredDiagnostic();
+  StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
+  StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
+                   StringRef Message);
+  StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 
+                   StringRef Message, FullSourceLoc Loc,
+                   ArrayRef<CharSourceRange> Ranges,
+                   ArrayRef<FixItHint> Fixits);
+  ~StoredDiagnostic();
+
+  /// \brief Evaluates true when this object stores a diagnostic.
+  LLVM_EXPLICIT operator bool() const { return Message.size() > 0; }
+
+  unsigned getID() const { return ID; }
+  DiagnosticsEngine::Level getLevel() const { return Level; }
+  const FullSourceLoc &getLocation() const { return Loc; }
+  StringRef getMessage() const { return Message; }
+
+  void setLocation(FullSourceLoc Loc) { this->Loc = Loc; }
+
+  typedef std::vector<CharSourceRange>::const_iterator range_iterator;
+  range_iterator range_begin() const { return Ranges.begin(); }
+  range_iterator range_end() const { return Ranges.end(); }
+  unsigned range_size() const { return Ranges.size(); }
+  
+  ArrayRef<CharSourceRange> getRanges() const {
+    return llvm::makeArrayRef(Ranges);
+  }
+
+
+  typedef std::vector<FixItHint>::const_iterator fixit_iterator;
+  fixit_iterator fixit_begin() const { return FixIts.begin(); }
+  fixit_iterator fixit_end() const { return FixIts.end(); }
+  unsigned fixit_size() const { return FixIts.size(); }
+  
+  ArrayRef<FixItHint> getFixIts() const {
+    return llvm::makeArrayRef(FixIts);
+  }
+};
+
+/// \brief Abstract interface, implemented by clients of the front-end, which
+/// formats and prints fully processed diagnostics.
+class DiagnosticConsumer {
+protected:
+  unsigned NumWarnings;       ///< Number of warnings reported
+  unsigned NumErrors;         ///< Number of errors reported
+  
+public:
+  DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
+
+  unsigned getNumErrors() const { return NumErrors; }
+  unsigned getNumWarnings() const { return NumWarnings; }
+  virtual void clear() { NumWarnings = NumErrors = 0; }
+
+  virtual ~DiagnosticConsumer();
+
+  /// \brief Callback to inform the diagnostic client that processing
+  /// of a source file is beginning.
+  ///
+  /// Note that diagnostics may be emitted outside the processing of a source
+  /// file, for example during the parsing of command line options. However,
+  /// diagnostics with source range information are required to only be emitted
+  /// in between BeginSourceFile() and EndSourceFile().
+  ///
+  /// \param LangOpts The language options for the source file being processed.
+  /// \param PP The preprocessor object being used for the source; this is 
+  /// optional, e.g., it may not be present when processing AST source files.
+  virtual void BeginSourceFile(const LangOptions &LangOpts,
+                               const Preprocessor *PP = nullptr) {}
+
+  /// \brief Callback to inform the diagnostic client that processing
+  /// of a source file has ended.
+  ///
+  /// The diagnostic client should assume that any objects made available via
+  /// BeginSourceFile() are inaccessible.
+  virtual void EndSourceFile() {}
+
+  /// \brief Callback to inform the diagnostic client that processing of all
+  /// source files has ended.
+  virtual void finish() {}
+
+  /// \brief Indicates whether the diagnostics handled by this
+  /// DiagnosticConsumer should be included in the number of diagnostics
+  /// reported by DiagnosticsEngine.
+  ///
+  /// The default implementation returns true.
+  virtual bool IncludeInDiagnosticCounts() const;
+
+  /// \brief Handle this diagnostic, reporting it to the user or
+  /// capturing it to a log as needed.
+  ///
+  /// The default implementation just keeps track of the total number of
+  /// warnings and errors.
+  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                                const Diagnostic &Info);
+};
+
+/// \brief A diagnostic client that ignores all diagnostics.
+class IgnoringDiagConsumer : public DiagnosticConsumer {
+  virtual void anchor();
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override {
+    // Just ignore it.
+  }
+};
+
+/// \brief Diagnostic consumer that forwards diagnostics along to an
+/// existing, already-initialized diagnostic consumer.
+///
+class ForwardingDiagnosticConsumer : public DiagnosticConsumer {
+  DiagnosticConsumer &Target;
+
+public:
+  ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {}
+
+  virtual ~ForwardingDiagnosticConsumer();
+
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+  void clear() override;
+
+  bool IncludeInDiagnosticCounts() const override;
+};
+
+// Struct used for sending info about how a type should be printed.
+struct TemplateDiffTypes {
+  intptr_t FromType;
+  intptr_t ToType;
+  unsigned PrintTree : 1;
+  unsigned PrintFromType : 1;
+  unsigned ElideType : 1;
+  unsigned ShowColors : 1;
+  // The printer sets this variable to true if the template diff was used.
+  unsigned TemplateDiffUsed : 1;
+};
+
+/// Special character that the diagnostic printer will use to toggle the bold
+/// attribute.  The character itself will be not be printed.
+const char ToggleHighlight = 127;
+
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(DiagnosticsEngine &Diags,
+                           const DiagnosticOptions &Opts,
+                           bool ReportDiags = true);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticASTKinds.inc b/include/clang/Basic/DiagnosticASTKinds.inc
new file mode 100644
index 0000000..2305eb5
--- /dev/null
+++ b/include/clang/Basic/DiagnosticASTKinds.inc
@@ -0,0 +1,103 @@
+#ifdef ASTSTART
+__ASTSTART = DIAG_START_AST,
+#undef ASTSTART
+#endif
+
+DIAG(err_asm_empty_symbolic_operand_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "empty symbolic operand name in inline assembly string", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_escape, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid %% escape in inline assembly string", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_operand_number, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid operand number in inline asm string", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_unknown_symbolic_operand_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown symbolic operand name in inline assembly string", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_unterminated_symbolic_operand_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "unterminated symbolic operand name in inline assembly string", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_odr_different_num_template_parameters, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter lists have a different number of parameters (%0 vs %1)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_different_template_parameter_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter has different kinds in different translation units", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_field_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "field %0 declared with incompatible types in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_function_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "external function %0 declared with incompatible types in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_ivar_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 declared with incompatible types in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_non_type_parameter_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template parameter declared with incompatible types in different translation units (%0 vs. %1)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_method_num_params_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|instance}0 method %1 has a different number of parameters in different translation units (%2 vs. %3)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_method_param_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|instance}0 method %1 has a parameter with a different types in different translation units (%2 vs. %3)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_method_result_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|instance}0 method %1 has incompatible result types in different translation units (%2 vs. %3)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_method_variadic_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|instance}0 method %1 is variadic in one translation unit and not variadic in another", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_property_impl_kind_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 is implemented with %select{@synthesize|@dynamic}1 in one translation but %select{@dynamic|@synthesize}1 in another translation unit", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_property_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 declared with incompatible types in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_superclass_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "class %0 has incompatible superclasses", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_objc_synthesize_ivar_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 is synthesized to different ivars in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_parameter_pack_non_pack, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_variable_multiple_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "external variable %0 defined in multiple translation units", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_odr_variable_type_inconsistent, CLASS_ERROR, (unsigned)diag::Severity::Error, "external variable %0 declared with incompatible types in different translation units (%1 vs. %2)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_unsupported_ast_node, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot import unsupported AST node %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(note_constexpr_access_inactive_union_member, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 member %1 of union with %select{active member %3|no active member}2 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_null, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 dereferenced null pointer is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_past_end, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 dereferenced one-past-the-end pointer is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_static_temporary, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 temporary is not allowed in a constant expression outside the expression that created the temporary", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_uninit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 object outside its lifetime is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_volatile_obj, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 volatile %select{temporary|object %2|member %2}1 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_access_volatile_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 volatile-qualified type %1 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_array_index, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot refer to element %0 of %select{array of %2 elements|non-array object}1 in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_call_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in call to '%0'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_call_limit_exceeded, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constexpr evaluation hit maximum call limit", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_calls_suppressed, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to see all)", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_compare_virtual_mem_ptr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comparison of pointer to virtual member function %0 has unspecified value", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_conditional_never_const, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "both arms of conditional operator are unable to produce a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_depth_limit_exceeded, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constexpr evaluation exceeded maximum depth of %0 calls", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_float_arithmetic, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "floating point arithmetic produces %select{an infinity|a NaN}0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_invalid_cast, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of a reinterpret_cast|cast from %1}0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_invalid_downcast, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot cast object of dynamic type %0 to type %1", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_invalid_function, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot be used in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_large_shift, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "shift count %0 >= width of type %1 (%2 bit%s2)", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_lifetime_ended, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{read of|assignment to|increment of|decrement of}0 %select{temporary|variable}1 whose lifetime has ended", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_lshift_discards, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "signed left shift discards bits", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_lshift_of_negative, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "left shift of negative value %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_ltor_mutable, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "read of mutable member %0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_ltor_non_const_int, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "read of non-const variable %0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_ltor_non_constexpr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "read of non-constexpr variable %0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_modify_const_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "modification of object of const-qualified type %0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_modify_global, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "a constant expression cannot modify an object that is visible outside that expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_negative_shift, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "negative shift count %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_no_return, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "control reached end of constexpr function", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_non_global, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{pointer|reference}0 to %select{|subobject of }1%select{temporary|%3}2 is not a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_nonliteral, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "non-literal type %0 cannot be used in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_null_subobject, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot %select{access base class of|access derived class of|access field of|access array element of|perform pointer arithmetic on|call member function on|access real component of|access imaginary component of}0 null pointer", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_overflow, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "value %0 is outside the range of representable values of type %1", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_past_end, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "dereferenced pointer past the end of %select{|subobject of }0%select{temporary|%2}1 is not a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_past_end_subobject, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot %select{access base class of|access derived class of|access field of|access array element of|ERROR|call member function on|access real component of|access imaginary component of}0 pointer past the end of object", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_pointer_comparison_base_classes, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comparison of addresses of subobjects of different base classes has unspecified value", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_pointer_comparison_base_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comparison of address of base class subobject %0 of class %1 to field %2 has unspecified value", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_pointer_comparison_differing_access, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comparison of address of fields %0 and %2 of %4 with differing access specifiers (%1 vs %3) has unspecified value", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_pointer_subtraction_not_same_array, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "subtracted pointers are not elements of the same array", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_pointer_subtraction_zero_size, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "subtraction of pointers to type %0 of zero size", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_step_limit_exceeded, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constexpr evaluation hit maximum step limit; possible infinite loop?", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_stmt_expr_unsupported, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "this use of statement expressions is not supported in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_temporary_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "temporary created here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_this, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{|implicit }0use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_typeid_polymorphic, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "typeid applied to expression of polymorphic type %0 is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_uninitialized, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{|sub}0object of type %1 is not initialized", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_use_uninit_reference, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use of reference outside its lifetime is not allowed in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_var_init_non_constant, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "initializer of %0 is not a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_virtual_base, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot construct object of type %0 with virtual base class in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_virtual_call, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot evaluate virtual function call in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_constexpr_void_comparison, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comparison between unequal pointers to void has unspecified result", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_expr_divide_by_zero, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "division by zero", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_base, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class has base type %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_bit_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "bit-field %0 with type %1 and length %2 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_defined_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "also defined here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_enumerator, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "enumerator %0 with value %1 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "field %0 has type %1 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_missing_base, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "no corresponding base class here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_missing_enumerator, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "no corresponding enumerator here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_missing_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "no corresponding field here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_not_bit_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "field %0 is not a bit-field", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_number_of_bases, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class has %0 base %plural{1:class|:classes}0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_objc_method_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{class|instance}0 method %1 also declared here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_objc_missing_superclass, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "no corresponding superclass here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_objc_property_impl_kind, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property %0 is implemented with %select{@synthesize|@dynamic}1 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_objc_superclass, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "inherits from superclass %0 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_objc_synthesize_ivar_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property is synthesized to ivar %0 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_parameter_pack_non_pack, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{parameter|parameter pack}0 declared here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_tag_kind_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is a %select{struct|interface|union|class|enum}1 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_template_parameter_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template parameter declared here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_template_parameter_list, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template parameter list also declared here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_value_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declared here with type %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_odr_virtual_base, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{non-virtual|virtual}0 derivation here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_integer_constant_overflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overflow in expression; result is %0 with type %1", 239, SFINAE_Suppress, false, false, 0)
+DIAG(warn_odr_tag_type_inconsistent, CLASS_WARNING, (unsigned)diag::Severity::Warning, "type %0 has incompatible definitions in different translation units", 332, SFINAE_Suppress, false, false, 0)
diff --git a/include/clang/Basic/DiagnosticAnalysisKinds.inc b/include/clang/Basic/DiagnosticAnalysisKinds.inc
new file mode 100644
index 0000000..a6ff0e2
--- /dev/null
+++ b/include/clang/Basic/DiagnosticAnalysisKinds.inc
@@ -0,0 +1,5 @@
+#ifdef ANALYSISSTART
+__ANALYSISSTART = DIAG_START_ANALYSIS,
+#undef ANALYSISSTART
+#endif
+
diff --git a/include/clang/Basic/DiagnosticCategories.h b/include/clang/Basic/DiagnosticCategories.h
new file mode 100644
index 0000000..4dd067b
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCategories.h
@@ -0,0 +1,26 @@
+//===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- C++ -*===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H
+
+namespace clang {
+  namespace diag {
+    enum {
+#define GET_CATEGORY_TABLE
+#define CATEGORY(X, ENUM) ENUM,
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef CATEGORY
+#undef GET_CATEGORY_TABLE
+      DiagCat_NUM_CATEGORIES
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticCommentKinds.inc b/include/clang/Basic/DiagnosticCommentKinds.inc
new file mode 100644
index 0000000..563ae10
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCommentKinds.inc
@@ -0,0 +1,39 @@
+#ifdef COMMENTSTART
+__COMMENTSTART = DIAG_START_COMMENT,
+#undef COMMENTSTART
+#endif
+
+DIAG(note_add_deprecation_attr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add a deprecation attribute to the declaration to silence this warning", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_block_command_previous, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous command '%select{\\|@}0%1' here", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_block_command_previous_alias, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous command '%select{\\|@}0%1' (an alias of '\\%2') here", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_html_end_tag, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "end tag", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_html_tag_started_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "HTML tag started here", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_param_name_suggestion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean '%0'?", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_param_previous, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous documentation", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_tparam_name_suggestion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean '%0'?", 0, SFINAE_Suppress, false, false, 18)
+DIAG(note_doc_tparam_previous, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous documentation", 0, SFINAE_Suppress, false, false, 18)
+DIAG(warn_correct_comment_command_name, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unknown command tag name '%0'; did you mean '%1'?", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_api_container_decl_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%select{class|interface|protocol|struct|union}1' command should not be used in a comment attached to a non-%select{class|interface|protocol|struct|union}2 declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_block_command_duplicate, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "duplicated command '%select{\\|@}0%1'", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_block_command_empty_paragraph, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "empty paragraph passed to '%select{\\|@}0%1' command", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_container_decl_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%select{classdesign|coclass|dependency|helper|helperclass|helps|instancesize|ownership|performance|security|superclass}1' command should not be used in a comment attached to a non-container declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_deprecated_not_sync, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration is marked with '\\deprecated' command but does not have a deprecation attribute", 133, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_function_method_decl_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%select{function|functiongroup|method|methodgroup|callback}1' command should be used in a comment attached to %select{a function|a function|an Objective-C method|an Objective-C method|a pointer to function}2 declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_end_forbidden, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "HTML end tag '%0' is forbidden", 134, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_end_unbalanced, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "HTML end tag does not match any start tag", 134, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_missing_end_tag, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "HTML tag '%0' requires an end tag", 134, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_start_end_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "HTML start tag '%0' closed by '%1'", 134, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_start_tag_expected_ident_or_greater, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "HTML start tag prematurely ended, expected attribute name or '>'", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_html_start_tag_expected_quoted_string, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "expected quoted string after equals sign", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_param_duplicate, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "parameter '%0' is already documented", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_param_invalid_direction, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unrecognized parameter passing direction, valid directions are '[in]', '[out]' and '[in,out]'", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_param_not_attached_to_a_function_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0param' command used in a comment that is not attached to a function declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_param_not_found, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "parameter '%0' not found in the function declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_param_spaces_in_direction, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "whitespace is not allowed in parameter passing direction", 135, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_returns_attached_to_a_void_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%1' command used in a comment that is attached to a %select{function returning void|constructor|destructor|method returning void}2", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_returns_not_attached_to_a_function_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%1' command used in a comment that is not attached to a function or method declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_tparam_duplicate, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "template parameter '%0' is already documented", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_tparam_not_attached_to_a_template_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0tparam' command used in a comment that is not attached to a template declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_doc_tparam_not_found, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "template parameter '%0' not found in the template declaration", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_unknown_comment_command_name, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unknown command tag name", 136, SFINAE_Suppress, false, false, 18)
+DIAG(warn_verbatim_block_end_without_start, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%select{\\|@}0%1' command does not terminate a verbatim text block", 132, SFINAE_Suppress, false, false, 18)
diff --git a/include/clang/Basic/DiagnosticCommonKinds.inc b/include/clang/Basic/DiagnosticCommonKinds.inc
new file mode 100644
index 0000000..8aae9f5
--- /dev/null
+++ b/include/clang/Basic/DiagnosticCommonKinds.inc
@@ -0,0 +1,64 @@
+#ifdef COMMONSTART
+__COMMONSTART = DIAG_START_COMMON,
+#undef COMMONSTART
+#endif
+
+DIAG(err_arcmt_nsinvocation_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_attribute_not_type_attr, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be applied to types", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_cannot_open_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "cannot open file '%0': %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_default_special_members, CLASS_ERROR, (unsigned)diag::Severity::Error, "only special member functions may be defaulted", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_deleted_non_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "only functions can have deleted definitions", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_enum_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumeration cannot be a template", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_after, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %1 after %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_colon_after_setter_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "method name referenced in property setter attribute must end with ':'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_expected_either, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %0 or %1", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_namespace_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected namespace name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_string_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected string literal %select{in %1|for diagnostic message in static_assert|for optional message in 'availability' attribute}0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_file_modified, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "file '%0' modified since it was first processed", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_integer_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "integer constant is larger than the largest unsigned integer type", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_invalid_character_udl, CLASS_ERROR, (unsigned)diag::Severity::Error, "character literal with user-defined suffix cannot be used here", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_numeric_udl, CLASS_ERROR, (unsigned)diag::Severity::Error, "numeric literal with user-defined suffix cannot be used here", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_storage_class_in_func_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid storage class specifier in function declarator", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_string_udl, CLASS_ERROR, (unsigned)diag::Severity::Error, "string literal with user-defined suffix cannot be used here", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_module_cycle, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "cyclic dependency in module '%0': %1", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_module_file_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "module '%0' found in both '%1' and '%2'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_module_not_built, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "could not build module '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_module_not_found, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "module '%0' not found", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_mt_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "[rewriter] %0", 0, SFINAE_SubstitutionFailure, false, false, 0)
+DIAG(err_param_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of parameter %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_target_unknown_abi, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown target ABI '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_target_unknown_cpu, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown target CPU '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_target_unknown_fpmath, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown FP unit '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_target_unknown_triple, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown target triple '%0', please use -triple or -arch", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_target_unsupported_fpmath, CLASS_ERROR, (unsigned)diag::Severity::Error, "the '%0' unit is not supported with this instruction set", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_unable_to_make_temp, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to make temporary file: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_unable_to_rename_temp, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to rename temporary '%0' to output file '%1': '%2'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_unsupported_bom, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "%0 byte order mark detected in '%1', but encoding is not supported", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(ext_c99_longlong, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "'long long' is an extension when C99 mode is not enabled", 259, SFINAE_Suppress, false, false, 0)
+DIAG(ext_cxx11_longlong, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "'long long' is a C++11 extension", 63, SFINAE_Suppress, false, false, 0)
+DIAG(ext_integer_too_large_for_signed, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "integer constant is larger than the largest signed integer type", 218, SFINAE_Suppress, false, false, 0)
+DIAG(ext_variadic_templates, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "variadic templates are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(fatal_too_many_errors, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "too many errors emitted, stopping now", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(note_also_found, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "also found", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_decl_hiding_tag_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%1 %0 is hidden by a non-type declaration of %0 here", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_declared_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declared here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_duplicate_case_prev, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous case defined here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_forward_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "forward declaration of %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_invalid_subexpr_in_const_expr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "subexpression not valid in a constant expression", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_matching, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "to match this %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_mt_message, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "[rewriter] %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_possibility, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "one possibility", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_pragma_entered_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "#pragma entered here", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_previous_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous declaration is here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_previous_definition, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous definition is here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_previous_implicit_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous implicit declaration is here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_previous_use, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous use is here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_type_being_defined, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "definition of %0 is not complete until the closing '}'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_using, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "using", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_arcmt_nsalloc_realloc, CLASS_WARNING, (unsigned)diag::Severity::Warning, "[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_cxx98_compat_longlong, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'long long' is incompatible with C++98", 76, SFINAE_Suppress, false, false, 0)
+DIAG(warn_cxx98_compat_variadic_templates, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variadic templates are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_method_param_declaration, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "redeclaration of method parameter %0", 140, SFINAE_Suppress, false, false, 4)
+DIAG(warn_method_param_redefinition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "redefinition of method parameter %0", 0, SFINAE_Suppress, false, false, 4)
+DIAG(warn_mt_message, CLASS_WARNING, (unsigned)diag::Severity::Warning, "[rewriter] %0", 0, SFINAE_Suppress, false, false, 0)
diff --git a/include/clang/Basic/DiagnosticDriverKinds.inc b/include/clang/Basic/DiagnosticDriverKinds.inc
new file mode 100644
index 0000000..ff32784
--- /dev/null
+++ b/include/clang/Basic/DiagnosticDriverKinds.inc
@@ -0,0 +1,87 @@
+#ifdef DRIVERSTART
+__DRIVERSTART = DIAG_START_DRIVER,
+#undef DRIVERSTART
+#endif
+
+DIAG(err_analyzer_config_multiple_values, CLASS_ERROR, (unsigned)diag::Severity::Error, "analyzer-config option '%0' should contain only one '='", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_analyzer_config_no_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "analyzer-config option '%0' has a key but no value", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_arc_unsupported_on_runtime, CLASS_ERROR, (unsigned)diag::Severity::Error, "-fobjc-arc is not supported on platforms using the legacy runtime", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_arc_unsupported_on_toolchain, CLASS_ERROR, (unsigned)diag::Severity::Error, "-fobjc-arc is not supported on versions of OS X prior to 10.6", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_I_dash_not_supported, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' not supported, please use -iquote instead", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_argument_not_allowed_with, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument '%0' not allowed with '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_argument_only_allowed_with, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument '%0' only allowed with '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_cc_print_options_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to open CC_PRINT_OPTIONS file: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_clang_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "the clang compiler does not support '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_clang_unsupported_opt_cxx_darwin_i386, CLASS_ERROR, (unsigned)diag::Severity::Error, "the clang compiler does not support '%0' for C++ on Darwin/i386", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_clang_unsupported_per_platform, CLASS_ERROR, (unsigned)diag::Severity::Error, "the clang compiler does not support '%0' on this platform", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_command_failed, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 command failed with exit code %1 (use -v to see invocation)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_command_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to execute command: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_command_signalled, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 command failed due to signal (use -v to see invocation)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_conflicting_deployment_targets, CLASS_ERROR, (unsigned)diag::Severity::Error, "conflicting deployment targets, both '%0' and '%1' are present in environment", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_emit_llvm_link, CLASS_ERROR, (unsigned)diag::Severity::Error, "-emit-llvm cannot be used when linking", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_force_crash, CLASS_ERROR, (unsigned)diag::Severity::Error, "failing because environment variable '%0' is set", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_Xarch_argument_isdriver, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_Xarch_argument_with_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid Xarch argument: '%0', options requiring arguments are unsupported", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_arch_for_deployment_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid architecture '%0' for deployment target '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_arch_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid arch name '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_darwin_version, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid Darwin version number: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_gcc_output_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid output type '%0' for use with gcc tool", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_int_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid integral value '%1' in '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_libcxx_deployment, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid deployment target for -stdlib=libc++ (requires %0 or later)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_linker_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid linker name in argument '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_mfloat_abi, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid float ABI '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_output_with_multiple_archs, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use '%0' output with multiple -arch options", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_remap_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid option '%0' not of the form <from-file>;<to-file>", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_rtlib_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid runtime library name in argument '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_stdlib_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid library name in argument '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid value '%1' in '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_invalid_version_number, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid version number in '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_malformed_sanitizer_blacklist, CLASS_ERROR, (unsigned)diag::Severity::Error, "malformed sanitizer blacklist: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_mg_requires_m_or_mm, CLASS_ERROR, (unsigned)diag::Severity::Error, "option '-MG' requires '-M' or '-MM'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_missing_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to '%0' is missing (expected %1 value%s1)", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_modules_validate_once_requires_timestamp, CLASS_ERROR, (unsigned)diag::Severity::Error, "option '-fmodules-validate-once-per-build-session' requires '-fbuild-session-timestamp=<seconds since Epoch>'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_ast_support, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0': unable to use AST files with this tool", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_input_files, CLASS_ERROR, (unsigned)diag::Severity::Error, "no input files", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_linker_llvm_support, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0': unable to pass LLVM bit-code files to linker", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_module_support, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0': unable to use module files with this tool", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_neon_modifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "[no]neon is not accepted as modifier, please use [no]simd instead", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_no_such_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "no such file or directory: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_objc_gc_arr, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specify both '-fobjc-arc' and '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_optimization_remark_pattern, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 in '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_out_file_argument_with_multiple_sources, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specify '%0%1' when compiling multiple source files", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_output_argument_with_multiple_files, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specify -o when generating multiple output files", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_preamble_format, CLASS_ERROR, (unsigned)diag::Severity::Error, "incorrect format for -preamble-bytes=N,END", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unable_to_remove_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to remove file: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unknown_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown argument: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unknown_language, CLASS_ERROR, (unsigned)diag::Severity::Error, "language not recognized: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unknown_objc_runtime, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown or ill-formed Objective-C runtime '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unknown_stdin_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "-E or -x required when input is from standard input", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unknown_stdin_type_clang_cl, CLASS_ERROR, (unsigned)diag::Severity::Error, "use /Tc or /Tp to set input type for standard input", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unsupported_opt, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported option '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unsupported_opt_for_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported option '%0' for target '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unsupported_option_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported argument '%1' to option '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_unsupported_rtlib_for_platform, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported runtime library '%0' for platform '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_drv_use_of_Z_option, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported use of internal gcc -Z option '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_no_external_assembler, CLASS_ERROR, (unsigned)diag::Severity::Error, "there is no external assembler that can be used on this platform", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_target_unsupported_arch, CLASS_ERROR, (unsigned)diag::Severity::Error, "the target architecture '%0' is not supported by the target '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(note_drv_command_failed_diag_msg, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "diagnostic msg: %0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_drv_t_option_is_global, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "The last /TC or /TP option takes precedence over earlier instances", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_O4_is_O3, CLASS_WARNING, (unsigned)diag::Severity::Warning, "-O4 is equivalent to -O3", 114, SFINAE_Suppress, false, false, 21)
+DIAG(warn_c_kext, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignoring -fapple-kext which is valid for C++ and Objective-C++ only", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_debug_compression_unavailable, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot compress debug sections (zlib not installed)", 109, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_assuming_mfloat_abi_is, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown platform, assuming -mfloat-abi=%0", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_clang_unsupported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "the clang compiler does not support '%0'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_empty_joined_argument, CLASS_WARNING, (unsigned)diag::Severity::Warning, "joined argument expects additional value: '%0'", 481, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_input_file_unused, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0: '%1' input unused%select{ when '%3' is present|}2", 481, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_input_file_unused_by_cpp, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0: '%1' input unused in cpp mode", 481, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_invoking_fallback, CLASS_WARNING, (unsigned)diag::Severity::Warning, "falling back to %0", 160, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_objc_gc_unsupported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "Objective-C garbage collection is not supported on this platform, ignoring '%0'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_optimization_value, CLASS_WARNING, (unsigned)diag::Severity::Warning, "optimization level '%0' is not supported; using '%1%2' instead", 240, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_overriding_flag_option, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overriding '%0' option with '%1'", 344, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_pch_not_first_include, CLASS_WARNING, (unsigned)diag::Severity::Warning, "precompiled header '%0' was ignored because '%1' is not first '-include'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_preprocessed_input_file_unused, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0: previously preprocessed input%select{ unused when '%2' is present|}1", 481, SFINAE_Suppress, false, false, 0)
+DIAG(warn_drv_treating_input_as_cxx, CLASS_WARNING, (unsigned)diag::Severity::Warning, "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated", 114, SFINAE_Suppress, false, false, 21)
+DIAG(warn_drv_unused_argument, CLASS_WARNING, (unsigned)diag::Severity::Warning, "argument unused during compilation: '%0'", 481, SFINAE_Suppress, false, false, 0)
+DIAG(warn_ignored_gcc_optimization, CLASS_WARNING, (unsigned)diag::Severity::Warning, "optimization flag '%0' is not supported", 240, SFINAE_Suppress, false, false, 0)
+DIAG(warn_ignoring_ftabstop_value, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignoring invalid -ftabstop value '%0', using default value %1", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_missing_sysroot, CLASS_WARNING, (unsigned)diag::Severity::Warning, "no such sysroot directory: '%0'", 281, SFINAE_Suppress, false, false, 0)
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.inc b/include/clang/Basic/DiagnosticFrontendKinds.inc
new file mode 100644
index 0000000..87da9b8
--- /dev/null
+++ b/include/clang/Basic/DiagnosticFrontendKinds.inc
@@ -0,0 +1,82 @@
+#ifdef FRONTENDSTART
+__FRONTENDSTART = DIAG_START_FRONTEND,
+#undef FRONTENDSTART
+#endif
+
+DIAG(err_fe_action_not_available, CLASS_ERROR, (unsigned)diag::Severity::Error, "action %0 not compiled in", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_backend_frame_larger_than, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 12)
+DIAG(err_fe_backend_plugin, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 12)
+DIAG(err_fe_cannot_link_module, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "cannot link module '%0': %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_dependency_file_requires_MT, CLASS_ERROR, (unsigned)diag::Severity::Error, "-dependency-file requires at least one -MT or -MQ option", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_error_backend, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "error in backend: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_error_opening, CLASS_ERROR, (unsigned)diag::Severity::Error, "error opening '%0': %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_error_reading, CLASS_ERROR, (unsigned)diag::Severity::Error, "error reading '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_error_reading_stdin, CLASS_ERROR, (unsigned)diag::Severity::Error, "error reading stdin: %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_expected_clang_command, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a clang compiler command", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_expected_compiler_job, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to handle compilation, expected exactly one compiler job in '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_inline_asm, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_fe_invalid_code_complete_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "cannot locate code-completion file %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_invalid_plugin_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to find plugin '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_no_pch_in_dir, CLASS_ERROR, (unsigned)diag::Severity::Error, "no suitable precompiled header file found in directory '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_pth_file_has_no_source_header, CLASS_ERROR, (unsigned)diag::Severity::Error, "PTH file '%0' does not designate an original source header file for -include-pth", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_remap_missing_from_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "could not remap from missing file '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_remap_missing_to_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "could not remap file '%0' to the contents of file '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_stdout_binary, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "unable to change standard output to binary", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_unable_to_create_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to create target: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_unable_to_interface_with_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to interface with target machine", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_unable_to_load_pch, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to load PCH file", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_unable_to_load_plugin, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to load plugin '%0': '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_fe_unable_to_open_output, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to open output file '%0': '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_invalid_vfs_overlay, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "invalid virtual filesystem overlay file '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_missing_module, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "no module named '%0' declared in module map file '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_missing_module_name, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "no module name provided; specify one with -fmodule-name=", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_missing_vfs_overlay_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "virtual filesystem overlay file '%0' not found", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_module_cannot_create_includes, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot create includes file for module %0: %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_module_header_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|umbrella }0header '%1' not found", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_module_map_not_found, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "module map file '%0' not found", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_module_unavailable, CLASS_ERROR, (unsigned)diag::Severity::Error, "module '%0' %select{is incompatible with|requires}1 feature '%2'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_no_submodule, CLASS_ERROR, (unsigned)diag::Severity::Error, "no submodule named %0 in module '%1'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_no_submodule_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no submodule named %0 in module '%1'; did you mean '%2'?", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_relocatable_without_isysroot, CLASS_ERROR, (unsigned)diag::Severity::Error, "must specify system root with -isysroot when building a relocatable PCH file", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_unknown_analyzer_checker, CLASS_ERROR, (unsigned)diag::Severity::Error, "no analyzer checkers are associated with '%0'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_inconsistent_diags, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_invalid_content, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid expected %0: %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_invalid_no_diags, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{expected|'expected-no-diagnostics'}0 directive cannot follow %select{'expected-no-diagnostics' directive|other expected directives}0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_invalid_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid range following '-' in expected %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_missing_end, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find end ('}}') of expected %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_missing_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "file '%0' could not be located in expected %1", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_missing_line, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing or invalid line number following '@' in expected %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_missing_regex, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find start of regex ('{{') in %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_missing_start, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find start ('{{') of expected %0", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(err_verify_no_directives, CLASS_ERROR, (unsigned)diag::Severity::Error, "no expected directives found: consider use of 'expected-no-diagnostics'", 0, SFINAE_SubstitutionFailure, false, true, 0)
+DIAG(note_fe_backend_frame_larger_than, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0", 0, SFINAE_Suppress, false, true, 12)
+DIAG(note_fe_backend_optimization_remark_invalid_loc, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "could not determine the original source location for %0:%1:%2", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_fe_backend_plugin, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0", 0, SFINAE_Suppress, false, true, 12)
+DIAG(note_fe_inline_asm, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0", 0, SFINAE_Suppress, false, false, 11)
+DIAG(note_fe_inline_asm_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "instantiated into assembly here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_fixit_applied, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "FIX-IT applied suggested code changes", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_fixit_failed, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "FIX-IT unable to apply suggested code changes", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_fixit_in_macro, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "FIX-IT unable to apply suggested code changes in a macro", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_fixit_unfixed_error, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "FIX-IT detected an error it cannot fix", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_incompatible_analyzer_plugin_api, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "current API version is '%0', but plugin was compiled with version '%1'", 0, SFINAE_Suppress, false, false, 0)
+DIAG(note_module_def_undef_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "macro was %select{defined|#undef'd}0 here", 0, SFINAE_Suppress, false, false, 0)
+DIAG(remark_fe_backend_optimization_remark, CLASS_REMARK, (unsigned)diag::Severity::Ignored, "%0", 349, SFINAE_Suppress, false, true, 12)
+DIAG(remark_fe_backend_optimization_remark_analysis, CLASS_REMARK, (unsigned)diag::Severity::Ignored, "%0", 350, SFINAE_Suppress, false, true, 12)
+DIAG(remark_fe_backend_optimization_remark_missed, CLASS_REMARK, (unsigned)diag::Severity::Ignored, "%0", 352, SFINAE_Suppress, false, true, 12)
+DIAG(remark_fe_backend_plugin, CLASS_REMARK, (unsigned)diag::Severity::Ignored, "%0", 373, SFINAE_Suppress, false, true, 12)
+DIAG(remark_module_build, CLASS_REMARK, (unsigned)diag::Severity::Ignored, "building module '%0' as '%1'", 283, SFINAE_Suppress, false, false, 0)
+DIAG(warn_fe_backend_frame_larger_than, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 174, SFINAE_Suppress, false, true, 12)
+DIAG(warn_fe_backend_optimization_failure, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 351, SFINAE_Suppress, false, true, 12)
+DIAG(warn_fe_backend_plugin, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 41, SFINAE_Suppress, false, true, 12)
+DIAG(warn_fe_cc_log_diagnostics_failure, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_fe_cc_print_header_failure, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unable to open CC_PRINT_HEADERS file: %0 (using stderr)", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_fe_frame_larger_than, CLASS_WARNING, (unsigned)diag::Severity::Warning, "stack frame size of %0 bytes in %q1", 174, SFINAE_Suppress, false, true, 12)
+DIAG(warn_fe_inline_asm, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 233, SFINAE_Suppress, false, false, 11)
+DIAG(warn_fe_macro_contains_embedded_newline, CLASS_WARNING, (unsigned)diag::Severity::Warning, "macro '%0' contains embedded newline; text after the newline is ignored", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_fe_serialized_diag_failure, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unable to open file %0 for serializing diagnostics (%1)", 389, SFINAE_Suppress, false, false, 0)
+DIAG(warn_fixit_no_changes, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "FIX-IT detected errors it could not fix; no output will be generated", 0, SFINAE_Suppress, false, false, 0)
+DIAG(warn_incompatible_analyzer_plugin_api, CLASS_WARNING, (unsigned)diag::Severity::Warning, "checker plugin '%0' is not compatible with this version of the analyzer", 16, SFINAE_Suppress, false, false, 0)
+DIAG(warn_missing_submodule, CLASS_WARNING, (unsigned)diag::Severity::Warning, "missing submodule '%0'", 227, SFINAE_Suppress, false, false, 0)
+DIAG(warn_module_config_macro_undef, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{definition|#undef}0 of configuration macro '%1' has no effect on the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line to configure the module", 93, SFINAE_Suppress, false, false, 0)
+DIAG(warn_unknown_diag_option, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown %select{warning|remark}0 option '%1'%select{|; did you mean '%3'?}2", 466, SFINAE_Suppress, false, false, 0)
+DIAG(warn_unknown_warning_specifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown %0 warning specifier: '%1'", 466, SFINAE_Suppress, false, false, 0)
diff --git a/include/clang/Basic/DiagnosticGroups.inc b/include/clang/Basic/DiagnosticGroups.inc
new file mode 100644
index 0000000..5490e68
--- /dev/null
+++ b/include/clang/Basic/DiagnosticGroups.inc
@@ -0,0 +1,1237 @@
+
+#ifdef GET_DIAG_ARRAYS
+static const int16_t DiagArrays[] = {
+  /* Empty */ -1,
+  /* DiagArray1 */ diag::warn_pragma_message, -1,
+  /* DiagArray2 */ diag::pp_hash_warning, -1,
+  /* DiagArray3 */ diag::warn_cfstring_truncated, -1,
+  /* DiagArray4 */ diag::warn_nsobject_attribute, -1,
+  /* DiagArray6 */ diag::warn_abs_too_small, diag::warn_unsigned_abs, diag::warn_wrong_absolute_value_type, -1,
+  /* DiagArray7 */ diag::warn_abstract_final_class, -1,
+  /* DiagArray8 */ diag::warn_abstract_vbase_init_ignored, -1,
+  /* DiagArray10 */ diag::warn_temporary_array_to_pointer_decay, -1,
+  /* DiagArray11 */ diag::ext_typecheck_addrof_temporary, -1,
+  /* DiagArray14 */ diag::warn_pp_ambiguous_macro, -1,
+  /* DiagArray15 */ diag::ext_nested_name_member_ref_lookup_ambiguous, -1,
+  /* DiagArray16 */ diag::warn_incompatible_analyzer_plugin_api, -1,
+  /* DiagArray17 */ diag::ext_abstract_pack_declarator_parens, -1,
+  /* DiagArray20 */ diag::warn_arc_bridge_cast_nonarc, -1,
+  /* DiagArray21 */ diag::warn_arc_possible_repeated_use_of_weak, -1,
+  /* DiagArray22 */ diag::warn_arc_object_memaccess, -1,
+  /* DiagArray23 */ diag::warn_arc_perform_selector_leaks, -1,
+  /* DiagArray24 */ diag::warn_arc_repeated_use_of_weak, -1,
+  /* DiagArray25 */ diag::warn_arc_retain_cycle, -1,
+  /* DiagArray26 */ diag::warn_arc_literal_assign, diag::warn_arc_retained_assign, diag::warn_arc_retained_property_assign, -1,
+  /* DiagArray27 */ diag::warn_array_index_exceeds_bounds, diag::warn_array_index_precedes_bounds, diag::warn_static_array_too_small, diag::warn_typecheck_zero_static_array_size, -1,
+  /* DiagArray28 */ diag::warn_ptr_arith_exceeds_bounds, diag::warn_ptr_arith_precedes_bounds, -1,
+  /* DiagArray30 */ diag::warn_asm_mismatched_size_modifier, -1,
+  /* DiagArray31 */ diag::warn_not_in_enum_assignment, -1,
+  /* DiagArray32 */ diag::warn_assume_side_effects, -1,
+  /* DiagArray33 */ diag::warn_atomic_op_has_invalid_memory_order, -1,
+  /* DiagArray35 */ diag::warn_atomic_property_rule, -1,
+  /* DiagArray37 */ diag::warn_auto_module_import, -1,
+  /* DiagArray38 */ diag::ext_auto_storage_class, -1,
+  /* DiagArray39 */ diag::warn_auto_var_is_id, -1,
+  /* DiagArray40 */ diag::warn_availability_and_unavailable, diag::warn_availability_unknown_platform, diag::warn_availability_version_ordering, diag::warn_mismatched_availability, diag::warn_mismatched_availability_override, diag::warn_mismatched_availability_override_unavail, -1,
+  /* DiagArray41 */ diag::warn_fe_backend_plugin, -1,
+  /* DiagArray42 */ diag::backslash_newline_space, -1,
+  /* DiagArray43 */ diag::warn_array_new_too_large, diag::warn_typecheck_negative_array_new_size, -1,
+  /* DiagArray44 */ diag::warn_bad_function_cast, -1,
+  /* DiagArray45 */ diag::ext_rvalue_to_reference_access_ctor, diag::ext_rvalue_to_reference_temp_copy_no_viable, -1,
+  /* DiagArray46 */ diag::warn_impcast_bitfield_precision_constant, -1,
+  /* DiagArray47 */ diag::warn_bitwise_and_in_bitwise_or, -1,
+  /* DiagArray48 */ diag::warn_impcast_bool_to_null_pointer, -1,
+  /* DiagArray50 */ diag::warn_objc_invalid_bridge, diag::warn_objc_invalid_bridge_to_cf, -1,
+  /* DiagArray51 */ diag::ext_pp_redef_builtin_macro, diag::ext_pp_undef_builtin_macro, -1,
+  /* DiagArray52 */ diag::warn_implicit_decl_requires_sysheader, -1,
+  /* DiagArray53 */ diag::warn_zero_size_struct_union_compat, -1,
+  /* DiagArray57 */ diag::warn_auto_storage_class, diag::warn_cxx11_compat_user_defined_literal, diag::warn_cxx11_keyword, diag::warn_cxx11_right_shift_in_template_arg, diag::warn_explicit_instantiation_inline_0x, diag::warn_explicit_instantiation_must_be_global_0x, diag::warn_explicit_instantiation_out_of_scope_0x, diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x, -1,
+  /* DiagArray58 */ diag::warn_deprecated_string_literal_conversion, -1,
+  /* DiagArray60 */ diag::warn_cxx11_compat_reserved_user_defined_literal, -1,
+  /* DiagArray61 */ diag::ext_alias_declaration, diag::ext_array_size_conversion, diag::ext_auto_type_specifier, diag::ext_cxx11_enum_fixed_underlying_type, diag::ext_defaulted_function, diag::ext_deleted_function, diag::ext_enum_friend, diag::ext_enumerator_list_comma_cxx, diag::ext_explicit_conversion_functions, diag::ext_explicit_instantiation_after_specialization, diag::ext_extern_template, diag::ext_for_range, diag::ext_generalized_initializer_lists, diag::ext_inline_namespace, diag::ext_nonclass_type_friend, diag::ext_nonstatic_member_init, diag::ext_override_control_keyword, diag::ext_ref_qualifier, diag::ext_rvalue_reference, diag::ext_scoped_enum, diag::ext_static_data_member_in_union, diag::ext_template_arg_object_internal, diag::ext_template_outside_of_template, diag::ext_template_parameter_default_in_function_template, diag::ext_template_spec_decl_out_of_scope, diag::ext_typename_outside_of_template, diag::ext_unelaborated_friend_type, diag::ext_variadic_templates, -1,
+  /* DiagArray62 */ diag::ext_extra_semi_cxx11, -1,
+  /* DiagArray63 */ diag::ext_cxx11_longlong, -1,
+  /* DiagArray64 */ diag::ext_cce_narrowing, diag::ext_init_list_constant_narrowing, diag::ext_init_list_type_narrowing, diag::ext_init_list_variable_narrowing, diag::warn_init_list_constant_narrowing, diag::warn_init_list_type_narrowing, diag::warn_init_list_variable_narrowing, -1,
+  /* DiagArray67 */ diag::ext_binary_literal_cxx1y, diag::ext_constexpr_body_invalid_stmt, diag::ext_constexpr_body_multiple_return, diag::ext_constexpr_local_var, diag::ext_constexpr_type_definition, diag::ext_decltype_auto_type_specifier, diag::ext_init_capture, diag::ext_variable_template, -1,
+  /* DiagArray68 */ diag::ext_for_range_identifier, diag::ext_static_assert_no_message, diag::ext_template_template_param_typename, -1,
+  /* DiagArray69 */ diag::warn_cxx1y_compat_for_range_identifier, diag::warn_cxx1y_compat_static_assert_no_message, diag::warn_cxx1y_compat_template_template_param_typename, -1,
+  /* DiagArray71 */ diag::warn_cxx11_compat_constexpr_body_invalid_stmt, diag::warn_cxx11_compat_constexpr_body_multiple_return, diag::warn_cxx11_compat_constexpr_body_no_return, diag::warn_cxx11_compat_constexpr_local_var, diag::warn_cxx11_compat_constexpr_type_definition, diag::warn_cxx11_compat_decltype_auto_type_specifier, diag::warn_cxx11_compat_digit_separator, diag::warn_cxx11_compat_init_capture, diag::warn_cxx11_compat_variable_template, -1,
+  /* DiagArray72 */ diag::warn_cxx11_compat_binary_literal, -1,
+  /* DiagArray73 */ diag::warn_cxx98_compat_alias_declaration, diag::warn_cxx98_compat_alignas, diag::warn_cxx98_compat_alignof, diag::warn_cxx98_compat_attribute, diag::warn_cxx98_compat_auto_type_specifier, diag::warn_cxx98_compat_constexpr, diag::warn_cxx98_compat_ctor_list_init, diag::warn_cxx98_compat_decltype, diag::warn_cxx98_compat_defaulted_function, diag::warn_cxx98_compat_delegating_ctor, diag::warn_cxx98_compat_deleted_function, diag::warn_cxx98_compat_empty_scalar_initializer, diag::warn_cxx98_compat_enum_fixed_underlying_type, diag::warn_cxx98_compat_enum_friend, diag::warn_cxx98_compat_enum_nested_name_spec, diag::warn_cxx98_compat_explicit_conversion_functions, diag::warn_cxx98_compat_for_range, diag::warn_cxx98_compat_friend_is_member, diag::warn_cxx98_compat_generalized_initializer_lists, diag::warn_cxx98_compat_goto_into_protected_scope, diag::warn_cxx98_compat_indirect_goto_in_protected_scope, diag::warn_cxx98_compat_initializer_list_init, diag::warn_cxx98_compat_inline_namespace, diag::warn_cxx98_compat_lambda, diag::warn_cxx98_compat_less_colon_colon, diag::warn_cxx98_compat_literal_operator, diag::warn_cxx98_compat_literal_ucn_control_character, diag::warn_cxx98_compat_literal_ucn_escape_basic_scs, diag::warn_cxx98_compat_noexcept_decl, diag::warn_cxx98_compat_noexcept_expr, diag::warn_cxx98_compat_non_static_member_use, diag::warn_cxx98_compat_nonclass_type_friend, diag::warn_cxx98_compat_nonstatic_member_init, diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member, diag::warn_cxx98_compat_nullptr, diag::warn_cxx98_compat_override_control_keyword, diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg, diag::warn_cxx98_compat_raw_string_literal, diag::warn_cxx98_compat_ref_qualifier, diag::warn_cxx98_compat_reference_list_init, diag::warn_cxx98_compat_rvalue_reference, diag::warn_cxx98_compat_scoped_enum, diag::warn_cxx98_compat_sfinae_access_control, diag::warn_cxx98_compat_static_assert, diag::warn_cxx98_compat_static_data_member_in_union, diag::warn_cxx98_compat_switch_into_protected_scope, diag::warn_cxx98_compat_template_arg_extra_parens, diag::warn_cxx98_compat_template_arg_null, diag::warn_cxx98_compat_template_arg_object_internal, diag::warn_cxx98_compat_template_outside_of_template, diag::warn_cxx98_compat_template_parameter_default_in_function_template, diag::warn_cxx98_compat_template_spec_decl_out_of_scope, diag::warn_cxx98_compat_trailing_return_type, diag::warn_cxx98_compat_two_right_angle_brackets, diag::warn_cxx98_compat_typename_outside_of_template, diag::warn_cxx98_compat_unelaborated_friend_type, diag::warn_cxx98_compat_unicode_id, diag::warn_cxx98_compat_unicode_literal, diag::warn_cxx98_compat_unicode_type, diag::warn_cxx98_compat_using_decl_constructor, diag::warn_cxx98_compat_variadic_templates, -1,
+  /* DiagArray74 */ diag::warn_cxx98_compat_temp_copy, -1,
+  /* DiagArray75 */ diag::warn_cxx98_compat_template_arg_local_type, -1,
+  /* DiagArray76 */ diag::warn_cxx98_compat_array_size_conversion, diag::warn_cxx98_compat_cast_fn_obj, diag::warn_cxx98_compat_empty_fnmacro_arg, diag::warn_cxx98_compat_enumerator_list_comma, diag::warn_cxx98_compat_explicit_instantiation_after_specialization, diag::warn_cxx98_compat_extern_template, diag::warn_cxx98_compat_longlong, diag::warn_cxx98_compat_no_newline_eof, diag::warn_cxx98_compat_pp_line_too_big, diag::warn_cxx98_compat_top_level_semi, diag::warn_cxx98_compat_variadic_macro, -1,
+  /* DiagArray77 */ diag::warn_cxx98_compat_template_arg_unnamed_type, -1,
+  /* DiagArray78 */ diag::ext_anonymous_union, diag::ext_c11_alignment, diag::ext_c11_anonymous_struct, diag::ext_c11_generic_selection, diag::ext_c11_noreturn, diag::ext_c11_static_assert, -1,
+  /* DiagArray79 */ diag::warn_c99_compat_unicode_id, diag::warn_c99_compat_unicode_literal, -1,
+  /* DiagArray80 */ diag::ext_aggregate_init_not_constant, diag::ext_c99_array_usage, diag::ext_c99_compound_literal, diag::ext_c99_flexible_array_member, diag::ext_c99_variable_decl_in_for_loop, diag::ext_c99_whitespace_required_after_macro_name, diag::ext_designated_init, diag::ext_empty_fnmacro_arg, diag::ext_enumerator_list_comma_c, diag::ext_hexconstant_invalid, -1,
+  /* DiagArray81 */ diag::warn_cast_align, -1,
+  /* DiagArray82 */ diag::warn_cast_pointer_from_sel, -1,
+  /* DiagArray85 */ diag::warn_subscript_is_char, -1,
+  /* DiagArray86 */ diag::warn_pass_class_arg_to_vararg, -1,
+  /* DiagArray87 */ diag::escaped_newline_block_comment_end, diag::ext_line_comment, diag::ext_multi_line_line_comment, diag::warn_nested_block_comment, -1,
+  /* DiagArray89 */ diag::ext_typecheck_comparison_of_distinct_pointers, diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard, -1,
+  /* DiagArray90 */ diag::ext_complex_component_init, -1,
+  /* DiagArray91 */ diag::ext_typecheck_cond_pointer_integer_mismatch, -1,
+  /* DiagArray92 */ diag::warn_maybe_uninit_var, -1,
+  /* DiagArray93 */ diag::warn_module_config_macro_undef, -1,
+  /* DiagArray94 */ diag::warn_impcast_integer_precision_constant, -1,
+  /* DiagArray95 */ diag::warn_logical_instead_of_bitwise, -1,
+  /* DiagArray96 */ diag::warn_cxx1y_compat_constexpr_not_const, -1,
+  /* DiagArray97 */ diag::warn_attr_on_unconsumable_class, diag::warn_loop_state_mismatch, diag::warn_param_return_typestate_mismatch, diag::warn_param_typestate_mismatch, diag::warn_return_typestate_for_unconsumable_type, diag::warn_return_typestate_mismatch, diag::warn_use_in_invalid_state, diag::warn_use_of_temp_in_invalid_state, -1,
+  /* DiagArray98 */ diag::warn_impcast_complex_scalar, diag::warn_impcast_float_precision, diag::warn_impcast_integer_precision, diag::warn_impcast_vector_scalar, diag::warn_template_arg_negative, diag::warn_template_arg_too_large, -1,
+  /* DiagArray100 */ diag::warn_unreachable_default, -1,
+  /* DiagArray102 */ diag::warn_pragma_unroll_cuda_value_in_parens, -1,
+  /* DiagArray103 */ diag::warn_default_atomic_custom_getter_setter, -1,
+  /* DiagArray104 */ diag::warn_dangling_else, -1,
+  /* DiagArray105 */ diag::warn_bind_ref_member_to_parameter, diag::warn_bind_ref_member_to_temporary, diag::warn_init_ptr_member_to_parameter_addr, -1,
+  /* DiagArray106 */ diag::warn_dangling_std_initializer_list, -1,
+  /* DiagArray107 */ diag::warn_pp_date_time, -1,
+  /* DiagArray108 */ diag::warn_dealloc_in_category, -1,
+  /* DiagArray109 */ diag::warn_debug_compression_unavailable, -1,
+  /* DiagArray110 */ diag::ext_mixed_decls_code, -1,
+  /* DiagArray111 */ diag::warn_delegating_ctor_cycle, -1,
+  /* DiagArray112 */ diag::warn_delete_incomplete, -1,
+  /* DiagArray113 */ diag::warn_delete_abstract_non_virtual_dtor, diag::warn_delete_non_virtual_dtor, -1,
+  /* DiagArray114 */ diag::warn_O4_is_O3, diag::warn_access_decl_deprecated, diag::warn_deprecated_copy_operation, diag::warn_drv_treating_input_as_cxx, diag::warn_exception_spec_deprecated, diag::warn_vector_long_decl_spec_combination, -1,
+  /* DiagArray115 */ diag::warn_cstyle_param, diag::warn_deprecated, diag::warn_deprecated_fwdclass_message, diag::warn_deprecated_message, diag::warn_property_method_deprecated, -1,
+  /* DiagArray116 */ diag::warn_deprecated_def, -1,
+  /* DiagArray117 */ diag::warn_increment_bool, -1,
+  /* DiagArray118 */ diag::warn_objc_isa_assign, diag::warn_objc_isa_use, -1,
+  /* DiagArray119 */ diag::warn_objc_pointer_masking, -1,
+  /* DiagArray120 */ diag::warn_objc_pointer_masking_performSelector, -1,
+  /* DiagArray121 */ diag::warn_deprecated_register, -1,
+  /* DiagArray123 */ diag::warn_direct_ivar_access, -1,
+  /* DiagArray124 */ diag::pp_disabled_macro_expansion, -1,
+  /* DiagArray127 */ diag::warn_conflicting_param_modifiers, diag::warn_conflicting_ret_type_modifiers, -1,
+  /* DiagArray129 */ diag::warn_division_by_zero, diag::warn_remainder_by_zero, -1,
+  /* DiagArray130 */ diag::warn_attribute_dll_redeclaration, -1,
+  /* DiagArray131 */ diag::warn_attribute_dllimport_static_field_definition, -1,
+  /* DiagArray132 */ diag::warn_correct_comment_command_name, diag::warn_doc_api_container_decl_mismatch, diag::warn_doc_block_command_duplicate, diag::warn_doc_block_command_empty_paragraph, diag::warn_doc_container_decl_mismatch, diag::warn_doc_function_method_decl_mismatch, diag::warn_doc_html_start_tag_expected_ident_or_greater, diag::warn_doc_html_start_tag_expected_quoted_string, diag::warn_doc_param_duplicate, diag::warn_doc_param_invalid_direction, diag::warn_doc_param_not_attached_to_a_function_decl, diag::warn_doc_param_not_found, diag::warn_doc_returns_attached_to_a_void_function, diag::warn_doc_returns_not_attached_to_a_function_decl, diag::warn_doc_tparam_duplicate, diag::warn_doc_tparam_not_attached_to_a_template_decl, diag::warn_doc_tparam_not_found, diag::warn_not_a_doxygen_trailing_member_comment, diag::warn_verbatim_block_end_without_start, -1,
+  /* DiagArray133 */ diag::warn_doc_deprecated_not_sync, -1,
+  /* DiagArray134 */ diag::warn_doc_html_end_forbidden, diag::warn_doc_html_end_unbalanced, diag::warn_doc_html_missing_end_tag, diag::warn_doc_html_start_end_mismatch, -1,
+  /* DiagArray135 */ diag::warn_doc_param_spaces_in_direction, -1,
+  /* DiagArray136 */ diag::warn_unknown_comment_command_name, -1,
+  /* DiagArray137 */ diag::ext_dollar_in_identifier, -1,
+  /* DiagArray138 */ diag::ext_duplicate_declspec, diag::warn_duplicate_declspec, -1,
+  /* DiagArray139 */ diag::warn_duplicate_enum_values, -1,
+  /* DiagArray140 */ diag::warn_method_param_declaration, -1,
+  /* DiagArray141 */ diag::warn_duplicate_method_decl, -1,
+  /* DiagArray142 */ diag::warn_dyn_class_memaccess, -1,
+  /* DiagArray144 */ diag::ext_embedded_directive, -1,
+  /* DiagArray145 */ diag::warn_empty_for_body, diag::warn_empty_if_body, diag::warn_empty_range_based_for_body, diag::warn_empty_switch_body, diag::warn_empty_while_body, -1,
+  /* DiagArray146 */ diag::ext_empty_translation_unit, -1,
+  /* DiagArray148 */ diag::warn_comparison_of_mixed_enum_types, -1,
+  /* DiagArray149 */ diag::warn_impcast_different_enum_types, -1,
+  /* DiagArray150 */ diag::ext_enum_too_large, diag::ext_enumerator_increment_too_large, -1,
+  /* DiagArray151 */ diag::warn_exit_time_destructor, -1,
+  /* DiagArray152 */ diag::warn_arc_strong_pointer_objc_pointer, -1,
+  /* DiagArray153 */ diag::ext_offsetof_extended_field_designator, -1,
+  /* DiagArray154 */ diag::warn_zero_size_struct_union_in_extern_c, -1,
+  /* DiagArray155 */ diag::warn_extern_init, -1,
+  /* DiagArray157 */ diag::warn_namespace_member_extra_qualification, -1,
+  /* DiagArray158 */ diag::ext_extra_semi, diag::warn_extra_semi_after_mem_fn_def, -1,
+  /* DiagArray159 */ diag::ext_pp_extra_tokens_at_eol, diag::warn_omp_extra_tokens_at_eol, -1,
+  /* DiagArray160 */ diag::warn_drv_invoking_fallback, -1,
+  /* DiagArray161 */ diag::ext_flexible_array_in_array, diag::ext_flexible_array_in_struct, -1,
+  /* DiagArray162 */ diag::warn_impcast_float_integer, -1,
+  /* DiagArray163 */ diag::warn_floatingpoint_eq, -1,
+  /* DiagArray164 */ diag::warn_format_argument_needs_cast, diag::warn_format_conversion_argument_type_mismatch, diag::warn_format_invalid_positional_specifier, diag::warn_format_mix_positional_nonpositional_args, diag::warn_format_nonsensical_length, diag::warn_format_string_is_wide_literal, diag::warn_format_zero_positional_specifier, diag::warn_missing_format_string, diag::warn_printf_asterisk_missing_arg, diag::warn_printf_asterisk_wrong_type, diag::warn_printf_format_string_contains_null_char, diag::warn_printf_format_string_not_null_terminated, diag::warn_printf_ignored_flag, diag::warn_printf_incomplete_specifier, diag::warn_printf_insufficient_data_args, diag::warn_printf_nonsensical_flag, diag::warn_printf_nonsensical_optional_amount, diag::warn_printf_positional_arg_exceeds_data_args, diag::warn_scanf_nonzero_width, diag::warn_scanf_scanlist_incomplete, -1,
+  /* DiagArray165 */ diag::warn_printf_data_arg_not_used, -1,
+  /* DiagArray166 */ diag::warn_format_invalid_conversion, -1,
+  /* DiagArray167 */ diag::warn_format_non_standard, diag::warn_format_non_standard_conversion_spec, diag::warn_format_non_standard_positional_arg, -1,
+  /* DiagArray168 */ diag::warn_format_nonliteral, -1,
+  /* DiagArray169 */ diag::warn_format_nonliteral_noargs, -1,
+  /* DiagArray171 */ diag::warn_empty_format_string, -1,
+  /* DiagArray173 */ diag::ext_four_char_character_literal, -1,
+  /* DiagArray174 */ diag::warn_fe_backend_frame_larger_than, diag::warn_fe_frame_larger_than, -1,
+  /* DiagArray175 */ diag::warn_function_def_in_objc_container, -1,
+  /* DiagArray176 */ diag::warn_attribute_on_function_definition, diag::warn_break_binds_to_switch, diag::warn_cleanup_ext, diag::warn_loop_ctrl_binds_to_inner, -1,
+  /* DiagArray177 */ diag::warn_global_constructor, diag::warn_global_destructor, -1,
+  /* DiagArray179 */ diag::ext_alignof_expr, -1,
+  /* DiagArray180 */ diag::ext_gnu_anonymous_struct, -1,
+  /* DiagArray181 */ diag::ext_array_init_parens, -1,
+  /* DiagArray182 */ diag::ext_binary_literal, -1,
+  /* DiagArray183 */ diag::ext_gnu_case_range, -1,
+  /* DiagArray184 */ diag::ext_integer_complex, -1,
+  /* DiagArray185 */ diag::ext_array_init_copy, -1,
+  /* DiagArray186 */ diag::ext_gnu_conditional_expr, -1,
+  /* DiagArray187 */ diag::ext_gnu_array_range, diag::ext_gnu_missing_equal_designator, diag::ext_gnu_old_style_field_designator, -1,
+  /* DiagArray188 */ diag::ext_gnu_empty_initializer, -1,
+  /* DiagArray189 */ diag::ext_empty_struct_union, diag::ext_flexible_array_empty_aggregate_gnu, diag::ext_no_named_members_in_struct_union, -1,
+  /* DiagArray190 */ diag::ext_flexible_array_init, -1,
+  /* DiagArray191 */ diag::ext_flexible_array_union_gnu, -1,
+  /* DiagArray192 */ diag::ext_expr_not_ice, diag::ext_in_class_initializer_non_constant, diag::ext_vla_folded_to_constant, -1,
+  /* DiagArray193 */ diag::ext_imaginary_constant, -1,
+  /* DiagArray194 */ diag::ext_gnu_address_of_label, diag::ext_gnu_indirect_goto, -1,
+  /* DiagArray195 */ diag::ext_forward_ref_enum_def, -1,
+  /* DiagArray196 */ diag::ext_gnu_statement_expr, -1,
+  /* DiagArray197 */ diag::ext_in_class_initializer_float_type, -1,
+  /* DiagArray198 */ diag::ext_string_literal_operator_template, -1,
+  /* DiagArray199 */ diag::ext_typecheck_cast_to_union, -1,
+  /* DiagArray200 */ diag::ext_variable_sized_type_in_struct, -1,
+  /* DiagArray201 */ diag::ext_pp_line_zero, -1,
+  /* DiagArray202 */ diag::ext_missing_varargs_arg, diag::ext_paste_comma, -1,
+  /* DiagArray203 */ diag::warn_header_guard, -1,
+  /* DiagArray204 */ diag::warn_using_directive_in_header, -1,
+  /* DiagArray205 */ diag::warn_condition_is_idiomatic_assignment, -1,
+  /* DiagArray206 */ diag::warn_alias_to_weak_alias, diag::warn_alias_with_section, diag::warn_attribute_after_definition_ignored, diag::warn_attribute_iboutlet, diag::warn_attribute_ignored, diag::warn_attribute_ignored_for_field_of_type, diag::warn_attribute_invalid_on_definition, diag::warn_attribute_malloc_pointer_only, diag::warn_attribute_no_decl, diag::warn_attribute_nonnull_no_pointers, diag::warn_attribute_nonnull_parm_no_args, diag::warn_attribute_not_on_decl, diag::warn_attribute_pointers_only, diag::warn_attribute_precede_definition, diag::warn_attribute_requires_functions_or_static_globals, diag::warn_attribute_return_pointers_only, diag::warn_attribute_sentinel_named_arguments, diag::warn_attribute_sentinel_not_variadic, diag::warn_attribute_type_not_supported, diag::warn_attribute_unknown_visibility, diag::warn_attribute_void_function_method, diag::warn_attribute_weak_on_field, diag::warn_attribute_weak_on_local, diag::warn_attribute_wrong_decl_type, diag::warn_cconv_ignored, diag::warn_cconv_varargs, diag::warn_cxx11_gnu_attribute_on_type, diag::warn_declspec_attribute_ignored, diag::warn_duplicate_attribute, diag::warn_duplicate_attribute_exact, diag::warn_gc_attribute_weak_on_local, diag::warn_gnu_inline_attribute_requires_inline, diag::warn_ignored_ms_inheritance, diag::warn_mmap_unknown_attribute, diag::warn_ns_attribute_wrong_parameter_type, diag::warn_ns_attribute_wrong_return_type, diag::warn_transparent_union_attribute_field_size_align, diag::warn_transparent_union_attribute_floating, diag::warn_transparent_union_attribute_not_definition, diag::warn_transparent_union_attribute_zero_fields, diag::warn_type_attribute_wrong_type, diag::warn_unhandled_ms_attribute_ignored, -1,
+  /* DiagArray207 */ diag::warn_pragma_align_expected_equal, diag::warn_pragma_align_invalid_option, diag::warn_pragma_debug_unexpected_command, diag::warn_pragma_expected_action_or_r_paren, diag::warn_pragma_expected_colon, diag::warn_pragma_expected_enable_disable, diag::warn_pragma_expected_identifier, diag::warn_pragma_expected_init_seg, diag::warn_pragma_expected_integer, diag::warn_pragma_expected_lparen, diag::warn_pragma_expected_non_wide_string, diag::warn_pragma_expected_punc, diag::warn_pragma_expected_rparen, diag::warn_pragma_expected_section_label_or_name, diag::warn_pragma_expected_section_name, diag::warn_pragma_expected_section_push_pop_or_name, diag::warn_pragma_extra_tokens_at_eol, diag::warn_pragma_init_seg_unsupported_target, diag::warn_pragma_invalid_action, diag::warn_pragma_invalid_specific_action, diag::warn_pragma_ms_struct, diag::warn_pragma_options_align_reset_failed, diag::warn_pragma_options_expected_align, diag::warn_pragma_pack_invalid_alignment, diag::warn_pragma_pack_malformed, diag::warn_pragma_pop_failed, diag::warn_pragma_pop_macro_no_push, diag::warn_pragma_unknown_extension, diag::warn_pragma_unsupported_action, diag::warn_pragma_unused_expected_var, diag::warn_pragma_unused_expected_var_arg, diag::warn_pragma_unused_undeclared_var, -1,
+  /* DiagArray208 */ diag::warn_arc_lifetime_result_type, diag::warn_qual_return_type, diag::warn_typecheck_reference_qualifiers, -1,
+  /* DiagArray210 */ diag::warn_auto_implicit_atomic_property, diag::warn_implicit_atomic_property, -1,
+  /* DiagArray211 */ diag::warn_impcast_floating_point_to_bool, -1,
+  /* DiagArray212 */ diag::ext_implicit_exception_spec_mismatch, -1,
+  /* DiagArray213 */ diag::warn_fallthrough_attr_invalid_placement, diag::warn_fallthrough_attr_unreachable, diag::warn_unannotated_fallthrough, -1,
+  /* DiagArray214 */ diag::warn_unannotated_fallthrough_per_function, -1,
+  /* DiagArray215 */ diag::ext_implicit_function_decl, diag::warn_builtin_unknown, diag::warn_implicit_function_decl, -1,
+  /* DiagArray216 */ diag::ext_missing_type_specifier, -1,
+  /* DiagArray217 */ diag::warn_implicitly_retains_self, -1,
+  /* DiagArray218 */ diag::ext_integer_too_large_for_signed, -1,
+  /* DiagArray220 */ diag::ext_pp_import_directive, -1,
+  /* DiagArray221 */ diag::warn_redecl_library_builtin, -1,
+  /* DiagArray222 */ diag::warn_cxx_ms_struct, -1,
+  /* DiagArray223 */ diag::ext_typecheck_convert_incompatible_pointer, -1,
+  /* DiagArray224 */ diag::ext_nested_pointer_qualifier_mismatch, diag::ext_typecheck_convert_discards_qualifiers, -1,
+  /* DiagArray225 */ diag::warn_undef_method_impl, -1,
+  /* DiagArray226 */ diag::warn_forgotten_module_header, -1,
+  /* DiagArray227 */ diag::warn_missing_submodule, diag::warn_uncovered_module_header, -1,
+  /* DiagArray228 */ diag::warn_infinite_recursive_function, -1,
+  /* DiagArray229 */ diag::warn_using_decl_constructor_ellipsis, -1,
+  /* DiagArray231 */ diag::warn_initializer_overrides, diag::warn_subobject_initializer_overrides, -1,
+  /* DiagArray233 */ diag::warn_fe_inline_asm, -1,
+  /* DiagArray234 */ diag::ext_operator_new_delete_declared_inline, -1,
+  /* DiagArray235 */ diag::ext_typecheck_convert_int_pointer, diag::ext_typecheck_convert_pointer_int, -1,
+  /* DiagArray237 */ diag::warn_int_to_pointer_cast, -1,
+  /* DiagArray238 */ diag::warn_int_to_void_pointer_cast, -1,
+  /* DiagArray239 */ diag::warn_integer_constant_overflow, -1,
+  /* DiagArray240 */ diag::warn_drv_optimization_value, diag::warn_ignored_gcc_optimization, -1,
+  /* DiagArray241 */ diag::ext_constexpr_function_never_constant_expr, -1,
+  /* DiagArray242 */ diag::warn_iboutlet_object_type, diag::warn_iboutletcollection_property_assign, -1,
+  /* DiagArray243 */ diag::warn_invalid_initializer_from_system_header, -1,
+  /* DiagArray244 */ diag::warn_falloff_noreturn_function, diag::warn_noreturn_function_has_return_expr, -1,
+  /* DiagArray245 */ diag::ext_offsetof_non_pod_type, diag::ext_offsetof_non_standardlayout_type, -1,
+  /* DiagArray247 */ diag::ext_empty_character, diag::ext_unterminated_char, diag::ext_unterminated_string, -1,
+  /* DiagArray248 */ diag::warn_bad_character_encoding, diag::warn_bad_string_encoding, -1,
+  /* DiagArray249 */ diag::ext_pp_bad_paste_ms, -1,
+  /* DiagArray250 */ diag::ext_keyword_as_ident, -1,
+  /* DiagArray251 */ diag::ext_param_promoted_not_compatible_with_prototype, -1,
+  /* DiagArray252 */ diag::ext_token_used, -1,
+  /* DiagArray253 */ diag::warn_parameter_size, diag::warn_return_value_size, -1,
+  /* DiagArray254 */ diag::warn_impcast_literal_float_to_integer, -1,
+  /* DiagArray255 */ diag::warn_float_overflow, diag::warn_float_underflow, -1,
+  /* DiagArray256 */ diag::ext_template_arg_local_type, -1,
+  /* DiagArray257 */ diag::warn_logical_not_on_lhs_of_comparison, -1,
+  /* DiagArray258 */ diag::warn_logical_and_in_logical_or, -1,
+  /* DiagArray259 */ diag::ext_c99_longlong, -1,
+  /* DiagArray260 */ diag::warn_redundant_loop_iteration, diag::warn_variables_not_in_loop_body, -1,
+  /* DiagArray261 */ diag::ext_pp_macro_redef, -1,
+  /* DiagArray262 */ diag::ext_main_used, diag::ext_noreturn_main, diag::warn_main_one_arg, diag::warn_static_main, -1,
+  /* DiagArray263 */ diag::ext_main_returns_nonint, -1,
+  /* DiagArray264 */ diag::warn_has_warning_invalid_option, -1,
+  /* DiagArray265 */ diag::warn_memsize_comparison, -1,
+  /* DiagArray266 */ diag::warn_non_contravariant_param_types, diag::warn_non_covariant_ret_types, -1,
+  /* DiagArray267 */ diag::ext_anonymous_record_with_type, diag::ext_c_enum_fixed_underlying_type, diag::ext_charize_microsoft, diag::ext_ellipsis_exception_spec, diag::ext_enumerator_too_large, diag::ext_explicit_instantiation_duplicate, diag::ext_flexible_array_empty_aggregate_ms, diag::ext_flexible_array_union_ms, diag::ext_found_via_dependent_bases_lookup, diag::ext_friend_tag_redecl_outside_namespace, diag::ext_function_specialization_in_class, diag::ext_goto_into_protected_scope, diag::ext_mismatched_exception_spec, diag::ext_ms_anonymous_struct, diag::ext_ms_delayed_template_argument, diag::ext_ms_deref_template_argument, diag::ext_ms_explicit_constructor_call, diag::ext_ms_forward_ref_enum, diag::ext_ms_sealed_keyword, diag::ext_ms_template_type_arg_missing_typename, diag::ext_ms_using_declaration_inaccessible, diag::ext_override_exception_spec, diag::ext_param_default_argument_redefinition, diag::ext_pp_operator_used_as_macro_name, diag::ext_pseudo_dtor_on_void, diag::ext_pure_function_definition, diag::ext_static_non_static, diag::ext_undeclared_unqual_id_with_dependent_base, diag::ext_union_member_of_reference_type, diag::warn_member_extra_qualification, -1,
+  /* DiagArray268 */ diag::warn_microsoft_dependent_exists, -1,
+  /* DiagArray269 */ diag::warn_conflicting_param_types, -1,
+  /* DiagArray270 */ diag::warn_conflicting_ret_types, -1,
+  /* DiagArray271 */ diag::warn_struct_class_previous_tag_mismatch, diag::warn_struct_class_tag_mismatch, -1,
+  /* DiagArray272 */ diag::warn_missing_braces, -1,
+  /* DiagArray273 */ diag::ext_no_declarators, diag::ext_standalone_specifier, diag::ext_typedef_without_a_name, diag::warn_standalone_specifier, -1,
+  /* DiagArray274 */ diag::warn_missing_field_initializers, -1,
+  /* DiagArray277 */ diag::warn_missing_method_return_type, -1,
+  /* DiagArray278 */ diag::warn_suggest_noreturn_block, diag::warn_suggest_noreturn_function, -1,
+  /* DiagArray279 */ diag::warn_missing_prototype, -1,
+  /* DiagArray280 */ diag::warn_missing_selector_name, -1,
+  /* DiagArray281 */ diag::warn_missing_sysroot, -1,
+  /* DiagArray282 */ diag::warn_missing_variable_declarations, -1,
+  /* DiagArray283 */ diag::remark_module_build, -1,
+  /* DiagArray284 */ diag::warn_module_conflict, -1,
+  /* DiagArray286 */ diag::ext_pp_include_search_ms, -1,
+  /* DiagArray287 */ diag::ext_multichar_character_literal, -1,
+  /* DiagArray288 */ diag::warn_vbase_moved_multiple_times, -1,
+  /* DiagArray290 */ diag::ext_anonymous_record_with_anonymous_type, -1,
+  /* DiagArray292 */ diag::warn_operator_new_returns_null, -1,
+  /* DiagArray293 */ diag::ext_no_newline_eof, diag::warn_no_newline_eof, -1,
+  /* DiagArray295 */ diag::warn_non_literal_null_pointer, -1,
+  /* DiagArray296 */ diag::warn_non_modular_include_in_framework_module, -1,
+  /* DiagArray297 */ diag::warn_non_modular_include_in_module, -1,
+  /* DiagArray298 */ diag::warn_cannot_pass_non_pod_arg_to_vararg, diag::warn_non_pod_vararg_with_format_string, diag::warn_second_parameter_to_va_arg_not_pod, diag::warn_second_parameter_to_va_arg_ownership_qualified, -1,
+  /* DiagArray299 */ diag::warn_non_virtual_dtor, -1,
+  /* DiagArray300 */ diag::warn_null_arg, diag::warn_null_ret, -1,
+  /* DiagArray302 */ diag::warn_neon_vector_initializer_non_portable, -1,
+  /* DiagArray303 */ diag::warn_null_in_arithmetic_operation, diag::warn_null_in_comparison_operation, -1,
+  /* DiagArray304 */ diag::null_in_char, diag::null_in_file, diag::null_in_string, -1,
+  /* DiagArray305 */ diag::warn_impcast_null_pointer_to_integer, -1,
+  /* DiagArray306 */ diag::warn_indirection_through_null, -1,
+  /* DiagArray307 */ diag::warn_autosynthesis_property_ivar_match, -1,
+  /* DiagArray309 */ diag::warn_objc_designated_init_missing_super_call, diag::warn_objc_designated_init_non_designated_init_call, diag::warn_objc_designated_init_non_super_designated_init_call, diag::warn_objc_implementation_missing_designated_init_override, diag::warn_objc_secondary_init_missing_init_call, diag::warn_objc_secondary_init_super_init_call, -1,
+  /* DiagArray310 */ diag::warn_forward_class_redefinition, -1,
+  /* DiagArray311 */ diag::warn_ivars_in_interface, -1,
+  /* DiagArray312 */ diag::warn_objc_literal_comparison, -1,
+  /* DiagArray313 */ diag::warn_impcast_objective_c_literal_to_bool, -1,
+  /* DiagArray314 */ diag::warn_class_method_not_found, diag::warn_class_method_not_found_with_typo, diag::warn_inst_method_not_found, diag::warn_instance_method_not_found_with_typo, diag::warn_instance_method_on_class_found, diag::warn_root_inst_method_not_found, -1,
+  /* DiagArray315 */ diag::warn_missing_explicit_synthesis, -1,
+  /* DiagArray316 */ diag::warn_objc_missing_super_call, -1,
+  /* DiagArray317 */ diag::warn_objc_property_retain_of_block, -1,
+  /* DiagArray318 */ diag::warn_objc_pointer_cxx_catch_fragile, -1,
+  /* DiagArray319 */ diag::warn_setter_getter_impl_required, diag::warn_setter_getter_impl_required_in_category, -1,
+  /* DiagArray320 */ diag::warn_property_implicitly_mismatched, -1,
+  /* DiagArray321 */ diag::warn_cocoa_naming_owned_rule, -1,
+  /* DiagArray322 */ diag::warn_objc_property_default_assign_on_object, diag::warn_objc_property_no_assignment_attribute, -1,
+  /* DiagArray323 */ diag::warn_no_autosynthesis_property, diag::warn_no_autosynthesis_shared_ivar_property, -1,
+  /* DiagArray324 */ diag::warn_category_method_impl_match, -1,
+  /* DiagArray325 */ diag::warn_auto_synthesizing_protocol_property, -1,
+  /* DiagArray326 */ diag::warn_objc_readonly_property_has_setter, -1,
+  /* DiagArray328 */ diag::warn_objc_redundant_literal_use, -1,
+  /* DiagArray329 */ diag::warn_objc_root_class_missing, -1,
+  /* DiagArray330 */ diag::warn_objc_string_literal_comparison, -1,
+  /* DiagArray331 */ diag::warn_concatenated_nsarray_literal, -1,
+  /* DiagArray332 */ diag::warn_odr_tag_type_inconsistent, -1,
+  /* DiagArray333 */ diag::warn_old_style_cast, -1,
+  /* DiagArray335 */ diag::warn_omp_linear_step_zero, -1,
+  /* DiagArray336 */ diag::ext_omp_loop_not_canonical_init, -1,
+  /* DiagArray337 */ diag::ext_out_of_line_declaration, -1,
+  /* DiagArray338 */ diag::warn_overaligned_type, -1,
+  /* DiagArray340 */ diag::ext_string_too_long, -1,
+  /* DiagArray341 */ diag::warn_overloaded_shift_in_comparison, -1,
+  /* DiagArray342 */ diag::warn_overloaded_virtual, -1,
+  /* DiagArray343 */ diag::warn_conflicting_overriding_param_modifiers, diag::warn_conflicting_overriding_param_types, diag::warn_conflicting_overriding_ret_type_modifiers, diag::warn_conflicting_overriding_ret_types, diag::warn_conflicting_overriding_variadic, diag::warn_non_contravariant_overriding_param_types, diag::warn_non_covariant_overriding_ret_types, -1,
+  /* DiagArray344 */ diag::warn_drv_overriding_flag_option, -1,
+  /* DiagArray345 */ diag::warn_unnecessary_packed, -1,
+  /* DiagArray346 */ diag::warn_padded_struct_anon_field, diag::warn_padded_struct_field, diag::warn_padded_struct_size, -1,
+  /* DiagArray347 */ diag::warn_condition_is_assignment, diag::warn_precedence_bitwise_rel, diag::warn_precedence_conditional, -1,
+  /* DiagArray348 */ diag::warn_equality_with_extra_parens, -1,
+  /* DiagArray349 */ diag::remark_fe_backend_optimization_remark, -1,
+  /* DiagArray350 */ diag::remark_fe_backend_optimization_remark_analysis, -1,
+  /* DiagArray351 */ diag::warn_fe_backend_optimization_failure, -1,
+  /* DiagArray352 */ diag::remark_fe_backend_optimization_remark_missed, -1,
+  /* DiagArray353 */ diag::ext_aggregate_init_not_constant, diag::ext_anonymous_record_with_type, diag::ext_anonymous_struct_union_qualified, diag::ext_array_size_conversion, diag::ext_binary_literal_cxx1y, diag::ext_c99_array_usage, diag::ext_c99_compound_literal, diag::ext_c99_flexible_array_member, diag::ext_c99_variable_decl_in_for_loop, diag::ext_c_enum_fixed_underlying_type, diag::ext_cast_fn_obj, diag::ext_charize_microsoft, diag::ext_cxx11_enum_fixed_underlying_type, diag::ext_designated_init, diag::ext_ellipsis_exception_spec, diag::ext_empty_fnmacro_arg, diag::ext_enum_value_not_int, diag::ext_enumerator_list_comma_c, diag::ext_enumerator_list_comma_cxx, diag::ext_explicit_instantiation_after_specialization, diag::ext_explicit_instantiation_without_qualified_id, diag::ext_extern_template, diag::ext_extra_semi, diag::ext_flexible_array_empty_aggregate_ms, diag::ext_flexible_array_union_ms, diag::ext_forward_ref_enum, diag::ext_freestanding_complex, diag::ext_gnu_array_range, diag::ext_gnu_ptr_func_arith, diag::ext_gnu_subscript_void_type, diag::ext_gnu_void_ptr, diag::ext_hexconstant_invalid, diag::ext_ident_list_in_param, diag::ext_integer_complement_complex, diag::ext_integer_increment_complex, diag::ext_internal_in_extern_inline_quiet, diag::ext_invalid_sign_spec, diag::ext_line_comment, diag::ext_main_used, diag::ext_ms_forward_ref_enum, diag::ext_multi_line_line_comment, diag::ext_no_newline_eof, diag::ext_nonstandard_escape, diag::ext_param_not_declared, diag::ext_pp_bad_vaargs_use, diag::ext_pp_comma_expr, diag::ext_pp_ident_directive, diag::ext_pp_include_next_directive, diag::ext_pp_line_too_big, diag::ext_pp_operator_used_as_macro_name, diag::ext_pp_warning_directive, diag::ext_return_has_void_expr, diag::ext_sizeof_alignof_function_type, diag::ext_sizeof_alignof_void_type, diag::ext_static_non_static, diag::ext_subscript_non_lvalue, diag::ext_thread_before, diag::ext_typecheck_addrof_void, diag::ext_typecheck_cast_nonscalar, diag::ext_typecheck_comparison_of_fptr_to_void, diag::ext_typecheck_cond_one_void, diag::ext_typecheck_convert_pointer_void_func, diag::ext_typecheck_ordered_comparison_of_pointer_and_zero, diag::warn_illegal_constant_array_size, -1,
+  /* DiagArray354 */ diag::ext_gnu_ptr_func_arith, diag::ext_gnu_subscript_void_type, diag::ext_gnu_void_ptr, diag::ext_sizeof_alignof_function_type, diag::ext_sizeof_alignof_void_type, diag::warn_sub_ptr_zero_size_types, -1,
+  /* DiagArray355 */ diag::warn_impcast_pointer_to_bool, -1,
+  /* DiagArray356 */ diag::ext_typecheck_convert_incompatible_pointer_sign, -1,
+  /* DiagArray358 */ diag::ext_typecheck_cond_incompatible_pointers, -1,
+  /* DiagArray360 */ diag::ext_predef_outside_function, -1,
+  /* DiagArray361 */ diag::warn_private_extern, -1,
+  /* DiagArray362 */ diag::warn_profile_data_out_of_date, -1,
+  /* DiagArray363 */ diag::warn_profile_data_unprofiled, -1,
+  /* DiagArray364 */ diag::warn_unimplemented_protocol_method, -1,
+  /* DiagArray365 */ diag::warn_protocol_property_mismatch, -1,
+  /* DiagArray366 */ diag::warn_auto_readonly_iboutlet_property, -1,
+  /* DiagArray367 */ diag::warn_bad_receiver_type, -1,
+  /* DiagArray368 */ diag::warn_receiver_forward_class, diag::warn_receiver_forward_instance, -1,
+  /* DiagArray369 */ diag::warn_receiver_is_weak, -1,
+  /* DiagArray370 */ diag::ext_member_redeclared, -1,
+  /* DiagArray372 */ diag::warn_reinterpret_different_from_static, -1,
+  /* DiagArray373 */ diag::remark_fe_backend_plugin, -1,
+  /* DiagArray374 */ diag::warn_initializer_out_of_order, -1,
+  /* DiagArray375 */ diag::warn_objc_requires_super_protocol, -1,
+  /* DiagArray376 */ diag::ext_ms_reserved_user_defined_literal, diag::ext_reserved_user_defined_literal, -1,
+  /* DiagArray377 */ diag::ext_retained_language_linkage, -1,
+  /* DiagArray378 */ diag::warn_ret_addr_label, diag::warn_ret_local_temp_addr, diag::warn_ret_local_temp_ref, diag::warn_ret_stack_addr, diag::warn_ret_stack_ref, -1,
+  /* DiagArray379 */ diag::ext_return_has_expr, diag::ext_return_missing_expr, diag::warn_falloff_nonvoid_function, diag::warn_falloff_nonvoid_lambda, diag::warn_maybe_falloff_nonvoid_function, diag::warn_maybe_falloff_nonvoid_lambda, diag::warn_return_missing_expr, -1,
+  /* DiagArray380 */ diag::warn_return_value_udt, diag::warn_return_value_udt_incomplete, -1,
+  /* DiagArray381 */ diag::warn_mismatched_section, -1,
+  /* DiagArray382 */ diag::warn_unimplemented_selector, -1,
+  /* DiagArray383 */ diag::warning_multiple_selectors, -1,
+  /* DiagArray384 */ diag::warn_self_assignment, -1,
+  /* DiagArray385 */ diag::warn_identity_field_assign, -1,
+  /* DiagArray386 */ diag::warn_semicolon_before_method_body, -1,
+  /* DiagArray387 */ diag::warn_missing_sentinel, diag::warn_not_enough_argument, -1,
+  /* DiagArray389 */ diag::warn_fe_serialized_diag_failure, -1,
+  /* DiagArray390 */ diag::warn_decl_shadow, -1,
+  /* DiagArray391 */ diag::warn_ivar_use_hidden, -1,
+  /* DiagArray392 */ diag::warn_shift_negative, -1,
+  /* DiagArray393 */ diag::warn_shift_gt_typewidth, -1,
+  /* DiagArray394 */ diag::warn_addition_in_bitshift, -1,
+  /* DiagArray395 */ diag::warn_shift_result_gt_typewidth, -1,
+  /* DiagArray396 */ diag::warn_shift_result_sets_sign_bit, -1,
+  /* DiagArray397 */ diag::warn_impcast_integer_64_32, -1,
+  /* DiagArray398 */ diag::warn_mixed_sign_comparison, -1,
+  /* DiagArray399 */ diag::warn_impcast_integer_sign, diag::warn_impcast_integer_sign_conditional, -1,
+  /* DiagArray401 */ diag::warn_sizeof_array_param, -1,
+  /* DiagArray402 */ diag::warn_sizeof_array_decay, -1,
+  /* DiagArray403 */ diag::warn_sizeof_pointer_expr_memaccess, diag::warn_sizeof_pointer_type_memaccess, -1,
+  /* DiagArray404 */ diag::warn_sometimes_uninit_var, -1,
+  /* DiagArray405 */ diag::warn_pragma_omp_ignored, -1,
+  /* DiagArray407 */ diag::ext_in_class_initializer_float_type_cxx11, -1,
+  /* DiagArray408 */ diag::ext_internal_in_extern_inline, diag::ext_internal_in_extern_inline_quiet, -1,
+  /* DiagArray409 */ diag::warn_static_inline_explicit_inst_ignored, -1,
+  /* DiagArray410 */ diag::warn_static_local_in_extern_inline, -1,
+  /* DiagArray411 */ diag::warn_static_self_reference_in_init, -1,
+  /* DiagArray424 */ diag::warn_strict_multiple_method_decl, -1,
+  /* DiagArray425 */ diag::warn_stringcompare, -1,
+  /* DiagArray426 */ diag::warn_impcast_string_literal_to_bool, -1,
+  /* DiagArray427 */ diag::warn_string_plus_char, -1,
+  /* DiagArray428 */ diag::warn_string_plus_int, -1,
+  /* DiagArray429 */ diag::warn_strlcpycat_wrong_size, -1,
+  /* DiagArray430 */ diag::warn_strncat_large_size, diag::warn_strncat_src_size, diag::warn_strncat_wrong_size, -1,
+  /* DiagArray431 */ diag::ext_typecheck_base_super, -1,
+  /* DiagArray432 */ diag::warn_case_value_overflow, diag::warn_missing_case1, diag::warn_missing_case2, diag::warn_missing_case3, diag::warn_missing_cases, diag::warn_not_in_enum, -1,
+  /* DiagArray433 */ diag::warn_bool_switch_condition, -1,
+  /* DiagArray435 */ diag::warn_def_missing_case1, diag::warn_def_missing_case2, diag::warn_def_missing_case3, diag::warn_def_missing_cases, -1,
+  /* DiagArray437 */ diag::warn_comparison_always, diag::warn_comparison_bitwise_always, diag::warn_lunsigned_always_true_comparison, diag::warn_runsigned_always_true_comparison, -1,
+  /* DiagArray438 */ diag::warn_out_of_range_compare, -1,
+  /* DiagArray439 */ diag::warn_tautological_overlap_comparison, -1,
+  /* DiagArray440 */ diag::warn_null_pointer_compare, -1,
+  /* DiagArray441 */ diag::warn_address_of_reference_null_compare, diag::warn_this_null_compare, -1,
+  /* DiagArray442 */ diag::ext_typecheck_decl_incomplete_type, -1,
+  /* DiagArray444 */ diag::warn_cannot_resolve_lock, diag::warn_double_lock, diag::warn_expecting_lock_held_on_loop, diag::warn_expecting_locked, diag::warn_fun_excludes_mutex, diag::warn_fun_requires_lock, diag::warn_lock_exclusive_and_shared, diag::warn_lock_some_predecessors, diag::warn_no_unlock, diag::warn_unlock_but_no_lock, diag::warn_unlock_kind_mismatch, diag::warn_var_deref_requires_any_lock, diag::warn_var_deref_requires_lock, diag::warn_variable_requires_any_lock, diag::warn_variable_requires_lock, -1,
+  /* DiagArray445 */ diag::warn_invalid_capability_name, diag::warn_thread_attribute_argument_not_lockable, diag::warn_thread_attribute_decl_not_lockable, diag::warn_thread_attribute_decl_not_pointer, diag::warn_thread_attribute_ignored, -1,
+  /* DiagArray446 */ diag::warn_thread_safety_beta, -1,
+  /* DiagArray447 */ diag::warn_fun_requires_lock_precise, diag::warn_var_deref_requires_lock_precise, diag::warn_variable_requires_lock_precise, -1,
+  /* DiagArray448 */ diag::trigraph_converted, diag::trigraph_ends_block_comment, diag::trigraph_ignored, diag::trigraph_ignored_block_comment, -1,
+  /* DiagArray450 */ diag::warn_type_safety_null_pointer_required, diag::warn_type_safety_type_mismatch, diag::warn_type_tag_for_datatype_wrong_kind, -1,
+  /* DiagArray451 */ diag::ext_redefinition_of_typedef, -1,
+  /* DiagArray452 */ diag::ext_typename_missing, -1,
+  /* DiagArray453 */ diag::warn_unavailable_fwdclass_message, -1,
+  /* DiagArray454 */ diag::warn_undeclared_selector, diag::warn_undeclared_selector_with_typo, -1,
+  /* DiagArray455 */ diag::warn_pp_undef_identifier, -1,
+  /* DiagArray456 */ diag::warn_address_of_reference_bool_conversion, diag::warn_this_bool_conversion, -1,
+  /* DiagArray457 */ diag::warn_undefined_inline, -1,
+  /* DiagArray458 */ diag::warn_undefined_internal, -1,
+  /* DiagArray459 */ diag::warn_pointer_indirection_from_incompatible_type, diag::warn_undefined_reinterpret_cast, -1,
+  /* DiagArray460 */ diag::warn_ucn_escape_incomplete, diag::warn_ucn_escape_no_digits, diag::warn_ucn_escape_surrogate, diag::warn_ucn_not_valid_in_c89, diag::warn_ucn_not_valid_in_c89_literal, -1,
+  /* DiagArray461 */ diag::ext_unicode_whitespace, -1,
+  /* DiagArray462 */ diag::warn_field_is_uninit, diag::warn_reference_field_is_uninit, diag::warn_uninit_byref_blockvar_captured_by_block, diag::warn_uninit_self_reference_in_init, diag::warn_uninit_self_reference_in_reference_init, diag::warn_uninit_var, -1,
+  /* DiagArray463 */ diag::warn_unknown_attribute_ignored, -1,
+  /* DiagArray464 */ diag::ext_unknown_escape, -1,
+  /* DiagArray465 */ diag::ext_on_off_switch_syntax, diag::ext_pragma_syntax_eod, diag::ext_stdc_pragma_ignored, diag::warn_pragma_diagnostic_cannot_pop, diag::warn_pragma_diagnostic_invalid, diag::warn_pragma_diagnostic_invalid_option, diag::warn_pragma_diagnostic_invalid_token, diag::warn_pragma_diagnostic_unknown_warning, diag::warn_pragma_ignored, diag::warn_pragma_include_alias_expected, diag::warn_pragma_include_alias_expected_filename, diag::warn_pragma_include_alias_mismatch_angle, diag::warn_pragma_include_alias_mismatch_quote, diag::warn_pragma_warning_expected, diag::warn_pragma_warning_expected_number, diag::warn_pragma_warning_push_level, diag::warn_pragma_warning_spec_invalid, diag::warn_stdc_fenv_access_not_supported, -1,
+  /* DiagArray466 */ diag::warn_unknown_diag_option, diag::warn_unknown_warning_specifier, -1,
+  /* DiagArray467 */ diag::ext_template_arg_unnamed_type, -1,
+  /* DiagArray468 */ diag::warn_unneeded_internal_decl, diag::warn_unneeded_static_internal_decl, -1,
+  /* DiagArray469 */ diag::warn_unneeded_member_function, -1,
+  /* DiagArray470 */ diag::warn_unreachable, -1,
+  /* DiagArray472 */ diag::warn_unreachable_break, -1,
+  /* DiagArray473 */ diag::warn_unreachable_loop_increment, -1,
+  /* DiagArray474 */ diag::warn_unreachable_return, -1,
+  /* DiagArray475 */ diag::warn_unsequenced_mod_mod, diag::warn_unsequenced_mod_use, -1,
+  /* DiagArray476 */ diag::warn_attribute_dll_instantiated_base_class, -1,
+  /* DiagArray477 */ diag::warn_template_qualified_friend_ignored, diag::warn_template_qualified_friend_unsupported, -1,
+  /* DiagArray478 */ diag::warn_attribute_protected_visibility, -1,
+  /* DiagArray481 */ diag::warn_drv_empty_joined_argument, diag::warn_drv_input_file_unused, diag::warn_drv_input_file_unused_by_cpp, diag::warn_drv_preprocessed_input_file_unused, diag::warn_drv_unused_argument, -1,
+  /* DiagArray482 */ diag::warn_unused_comparison, -1,
+  /* DiagArray483 */ diag::warn_unused_const_variable, -1,
+  /* DiagArray484 */ diag::warn_unused_exception_param, -1,
+  /* DiagArray485 */ diag::warn_unused_function, -1,
+  /* DiagArray486 */ diag::warn_unused_label, -1,
+  /* DiagArray487 */ diag::pp_macro_not_used, -1,
+  /* DiagArray488 */ diag::warn_unused_member_function, -1,
+  /* DiagArray489 */ diag::warn_unused_parameter, -1,
+  /* DiagArray490 */ diag::warn_unused_private_field, -1,
+  /* DiagArray491 */ diag::warn_unused_property_backing_ivar, -1,
+  /* DiagArray492 */ diag::warn_unused_result, -1,
+  /* DiagArray493 */ diag::warn_unused_call, diag::warn_unused_container_subscript_expr, diag::warn_unused_expr, diag::warn_unused_property_expr, diag::warn_unused_voidptr, -1,
+  /* DiagArray494 */ diag::warn_unused_variable, -1,
+  /* DiagArray495 */ diag::warn_unused_volatile, -1,
+  /* DiagArray496 */ diag::warn_used_but_marked_unused, -1,
+  /* DiagArray497 */ diag::warn_user_literal_reserved, -1,
+  /* DiagArray498 */ diag::warn_second_parameter_of_va_start_not_last_named_argument, diag::warn_second_parameter_to_va_arg_never_compatible, diag::warn_va_start_of_reference_type_is_undefined, -1,
+  /* DiagArray499 */ diag::ext_named_variadic_macro, diag::ext_variadic_macro, -1,
+  /* DiagArray500 */ diag::warn_incompatible_vectors, -1,
+  /* DiagArray502 */ diag::warn_empty_parens_are_function_decl, diag::warn_parens_disambiguated_as_function_declaration, -1,
+  /* DiagArray503 */ diag::warn_decl_in_param_list, diag::warn_redefinition_in_param_list, -1,
+  /* DiagArray504 */ diag::warn_vla_used, -1,
+  /* DiagArray505 */ diag::ext_vla, -1,
+  /* DiagArray506 */ diag::ext_typecheck_indirection_through_void_pointer, -1,
+  /* DiagArray508 */ diag::warn_weak_template_vtable, -1,
+  /* DiagArray509 */ diag::warn_weak_vtable, -1,
+  /* DiagArray510 */ diag::ext_deprecated_string_literal_conversion, -1,
+  /* DiagArray512 */ diag::ext_typecheck_zero_array_size, -1,
+};
+
+static const int16_t DiagSubGroups[] = {
+  /* Empty */ -1,
+  /* DiagSubGroup0 */ 156, -1,
+  /* DiagSubGroup9 */ 355, 425, 440, -1,
+  /* DiagSubGroup13 */ 285, 347, 432, 433, -1,
+  /* DiagSubGroup18 */ 26, 25, 22, -1,
+  /* DiagSubGroup24 */ 21, -1,
+  /* DiagSubGroup29 */ 30, -1,
+  /* DiagSubGroup34 */ 210, 103, -1,
+  /* DiagSubGroup36 */ 463, 206, -1,
+  /* DiagSubGroup45 */ 74, -1,
+  /* DiagSubGroup48 */ 355, 456, -1,
+  /* DiagSubGroup49 */ 48, -1,
+  /* DiagSubGroup54 */ 57, -1,
+  /* DiagSubGroup55 */ 61, -1,
+  /* DiagSubGroup56 */ 64, -1,
+  /* DiagSubGroup57 */ 64, 60, 58, 71, 69, -1,
+  /* DiagSubGroup59 */ 72, 70, -1,
+  /* DiagSubGroup61 */ 62, 63, -1,
+  /* DiagSubGroup65 */ 69, -1,
+  /* DiagSubGroup66 */ 70, -1,
+  /* DiagSubGroup70 */ 69, -1,
+  /* DiagSubGroup72 */ 71, -1,
+  /* DiagSubGroup73 */ 74, 75, 77, 71, 69, -1,
+  /* DiagSubGroup76 */ 73, 72, 70, -1,
+  /* DiagSubGroup86 */ 298, -1,
+  /* DiagSubGroup88 */ 87, -1,
+  /* DiagSubGroup94 */ 46, -1,
+  /* DiagSubGroup98 */ 48, 94, 149, 162, 397, 235, 254, 295, 305, 313, 399, 426, -1,
+  /* DiagSubGroup99 */ 305, -1,
+  /* DiagSubGroup114 */ 115, 117, 121, 122, -1,
+  /* DiagSubGroup119 */ 120, -1,
+  /* DiagSubGroup122 */ 58, -1,
+  /* DiagSubGroup132 */ 134, 133, -1,
+  /* DiagSubGroup135 */ 136, -1,
+  /* DiagSubGroup147 */ 159, -1,
+  /* DiagSubGroup156 */ 274, 208, 231, 386, 277, 398, 489, -1,
+  /* DiagSubGroup158 */ 62, -1,
+  /* DiagSubGroup164 */ 165, 171, 300, 169, 170, 166, -1,
+  /* DiagSubGroup172 */ 168, 169, 170, -1,
+  /* DiagSubGroup178 */ 179, 180, 182, 183, 184, 185, 186, 187, 188, 189, 505, 190, 191, 192, 193, 194, 370, 195, 196, 197, 198, 199, 200, 512, 201, 202, -1,
+  /* DiagSubGroup209 */ 215, 216, -1,
+  /* DiagSubGroup213 */ 214, -1,
+  /* DiagSubGroup223 */ 224, -1,
+  /* DiagSubGroup226 */ 227, -1,
+  /* DiagSubGroup236 */ 235, -1,
+  /* DiagSubGroup237 */ 238, -1,
+  /* DiagSubGroup256 */ 75, -1,
+  /* DiagSubGroup259 */ 63, -1,
+  /* DiagSubGroup285 */ 85, 87, 113, 164, 209, 271, 272, 287, 374, 379, 384, 401, 402, 428, 448, 462, 465, 479, 507, 316, 309, 342, 361, 82, 154, -1,
+  /* DiagSubGroup289 */ 64, -1,
+  /* DiagSubGroup294 */ 398, 98, 255, -1,
+  /* DiagSubGroup297 */ 296, -1,
+  /* DiagSubGroup308 */ 327, -1,
+  /* DiagSubGroup312 */ 330, -1,
+  /* DiagSubGroup327 */ 328, -1,
+  /* DiagSubGroup347 */ 258, 257, 47, 394, 341, 348, 104, -1,
+  /* DiagSubGroup353 */ 78, 62, 63, 161, 173, 180, 182, 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 199, 201, 202, 259, 340, 505, 499, 512, 377, 90, 153, 506, 290, 110, 137, 252, 220, 144, 146, -1,
+  /* DiagSubGroup359 */ 465, 207, -1,
+  /* DiagSubGroup376 */ 60, -1,
+  /* DiagSubGroup379 */ 380, -1,
+  /* DiagSubGroup382 */ 383, -1,
+  /* DiagSubGroup384 */ 385, -1,
+  /* DiagSubGroup388 */ 475, -1,
+  /* DiagSubGroup407 */ 197, -1,
+  /* DiagSubGroup437 */ 438, 440, 439, 441, -1,
+  /* DiagSubGroup443 */ 445, 444, 447, -1,
+  /* DiagSubGroup462 */ 404, 411, -1,
+  /* DiagSubGroup467 */ 77, -1,
+  /* DiagSubGroup470 */ 473, -1,
+  /* DiagSubGroup471 */ 470, 472, 474, -1,
+  /* DiagSubGroup479 */ 480, 485, 486, 490, 493, 494, 491, -1,
+  /* DiagSubGroup485 */ 468, -1,
+  /* DiagSubGroup488 */ 469, -1,
+  /* DiagSubGroup493 */ 482, 492, -1,
+  /* DiagSubGroup494 */ 483, -1,
+  /* DiagSubGroup501 */ 500, -1,
+  /* DiagSubGroup510 */ 122, -1,
+  /* DiagSubGroup511 */ 510, -1,
+};
+
+static const char DiagGroupNames[] = {
+    "\000\020#pragma-messages\t#warnings\020CFString-literal\022NSObject-att"
+    "ribute\003abi\016absolute-value\024abstract-final-class\023abstract-vba"
+    "se-init\007address\032address-of-array-temporary\024address-of-temporar"
+    "y\020aggregate-return\003all\017ambiguous-macro\031ambiguous-member-tem"
+    "plate\034analyzer-incompatible-plugin\025anonymous-pack-parens\003arc\007"
+    "arc-abi%arc-bridge-casts-disallowed-in-nonarc\036arc-maybe-repeated-use"
+    "-of-weak\025arc-non-pod-memaccess\031arc-performSelector-leaks\030arc-r"
+    "epeated-use-of-weak\021arc-retain-cycles\032arc-unsafe-retained-assign\014"
+    "array-bounds\037array-bounds-pointer-arithmetic\003asm\022asm-operand-w"
+    "idths\013assign-enum\006assume\026atomic-memory-ordering\021atomic-prop"
+    "erties*atomic-property-with-user-defined-accessor\nattributes\013auto-i"
+    "mport\022auto-storage-class\013auto-var-id\014availability\016backend-p"
+    "lugin\030backslash-newline-escape\024bad-array-new-length\021bad-functi"
+    "on-cast\026bind-to-temporary-copy\034bitfield-constant-conversion\026bi"
+    "twise-op-parentheses\017bool-conversion\020bool-conversions\013bridge-c"
+    "ast\027builtin-macro-redefined\027builtin-requires-header\nc++-compat\014"
+    "c++0x-compat\020c++0x-extensions\017c++0x-narrowing\014c++11-compat(c++"
+    "11-compat-deprecated-writable-strings\025c++11-compat-pedantic*c++11-co"
+    "mpat-reserved-user-defined-literal\020c++11-extensions\020c++11-extra-s"
+    "emi\017c++11-long-long\017c++11-narrowing\014c++14-compat\025c++14-comp"
+    "at-pedantic\020c++1y-extensions\020c++1z-extensions\030c++98-c++11-c++1"
+    "4-compat!c++98-c++11-c++14-compat-pedantic\022c++98-c++11-compat\033c++"
+    "98-c++11-compat-pedantic\014c++98-compat#c++98-compat-bind-to-temporary"
+    "-copy%c++98-compat-local-type-template-args\025c++98-compat-pedantic'c+"
+    "+98-compat-unnamed-type-template-args\016c11-extensions\nc99-compat\016"
+    "c99-extensions\ncast-align\020cast-of-sel-type\tcast-qual\nchar-align\017"
+    "char-subscripts\015class-varargs\007comment\010comments\036compare-dist"
+    "inct-pointer-types\026complex-component-init\031conditional-type-mismat"
+    "ch\031conditional-uninitialized\015config-macros\023constant-conversion"
+    "\030constant-logical-operand\023constexpr-not-const\010consumed\nconver"
+    "sion\017conversion-null\026covered-switch-default\021ctor-dtor-privacy\013"
+    "cuda-compat\030custom-atomic-properties\015dangling-else\016dangling-fi"
+    "eld\031dangling-initializer-list\tdate-time\023dealloc-in-category\035d"
+    "ebug-compression-unavailable\033declaration-after-statement\026delegati"
+    "ng-ctor-cycles\021delete-incomplete\027delete-non-virtual-dtor\ndepreca"
+    "ted\027deprecated-declarations\032deprecated-implementations\031depreca"
+    "ted-increment-bool\031deprecated-objc-isa-usage%deprecated-objc-pointer"
+    "-introspection5deprecated-objc-pointer-introspection-performSelector\023"
+    "deprecated-register\033deprecated-writable-strings\022direct-ivar-acces"
+    "s\030disabled-macro-expansion\025disabled-optimization\014discard-qual\034"
+    "distributed-object-modifiers\013div-by-zero\020division-by-zero\036dll-"
+    "attribute-on-redeclaration\032dllimport-static-field-def\015documentati"
+    "on\035documentation-deprecated-sync\022documentation-html\026documentat"
+    "ion-pedantic\035documentation-unknown-command\036dollar-in-identifier-e"
+    "xtension\030duplicate-decl-specifier\016duplicate-enum\024duplicate-met"
+    "hod-arg\026duplicate-method-match\027dynamic-class-memaccess\006effc++\022"
+    "embedded-directive\nempty-body\026empty-translation-unit\014endif-label"
+    "s\014enum-compare\017enum-conversion\016enum-too-large\025exit-time-des"
+    "tructors\027explicit-ownership-type\021extended-offsetof\017extern-c-co"
+    "mpat\022extern-initializer\005extra\023extra-qualification\nextra-semi\014"
+    "extra-tokens\010fallback\031flexible-array-extensions\020float-conversi"
+    "on\013float-equal\006format\021format-extra-args\030format-invalid-spec"
+    "ifier\016format-non-iso\021format-nonliteral\017format-security\nformat"
+    "-y2k\022format-zero-length\010format=2\023four-char-constants\022frame-"
+    "larger-than=\036function-def-in-objc-container\ngcc-compat\023global-co"
+    "nstructors\003gnu\026gnu-alignof-expression\024gnu-anonymous-struct\033"
+    "gnu-array-member-paren-init\022gnu-binary-literal\016gnu-case-range\023"
+    "gnu-complex-integer gnu-compound-literal-initializer\037gnu-conditional"
+    "-omitted-operand\016gnu-designator\025gnu-empty-initializer\020gnu-empt"
+    "y-struct\036gnu-flexible-array-initializer\037gnu-flexible-array-union-"
+    "member\024gnu-folding-constant\026gnu-imaginary-constant\022gnu-label-a"
+    "s-value\023gnu-redeclared-enum\030gnu-statement-expression\025gnu-stati"
+    "c-float-init$gnu-string-literal-operator-template\016gnu-union-cast\"gn"
+    "u-variable-sized-type-not-at-end\027gnu-zero-line-directive!gnu-zero-va"
+    "riadic-macro-arguments\014header-guard\016header-hygiene\025idiomatic-p"
+    "arentheses\022ignored-attributes\017ignored-pragmas\022ignored-qualifie"
+    "rs\010implicit\032implicit-atomic-properties*implicit-conversion-floati"
+    "ng-point-to-bool implicit-exception-spec-mismatch\024implicit-fallthrou"
+    "gh!implicit-fallthrough-per-function\035implicit-function-declaration\014"
+    "implicit-int\024implicit-retain-self\033implicitly-unsigned-literal\006"
+    "import&import-preprocessor-directive-pedantic\"incompatible-library-red"
+    "eclaration\026incompatible-ms-struct\032incompatible-pointer-types.inco"
+    "mpatible-pointer-types-discards-qualifiers\031incomplete-implementation"
+    "\021incomplete-module\023incomplete-umbrella\022infinite-recursion\027i"
+    "nherited-variadic-ctor\tinit-self\025initializer-overrides\006inline\ni"
+    "nline-asm\021inline-new-delete\016int-conversion\017int-conversions\023"
+    "int-to-pointer-cast\030int-to-void-pointer-cast\020integer-overflow\035"
+    "invalid-command-line-argument\021invalid-constexpr\020invalid-iboutlet&"
+    "invalid-initializer-from-system-header\020invalid-noreturn\020invalid-o"
+    "ffsetof\013invalid-pch\020invalid-pp-token\027invalid-source-encoding\023"
+    "invalid-token-paste\016keyword-compat\026knr-promoted-parameter\030lang"
+    "uage-extension-token\023large-by-value-copy\022literal-conversion\015li"
+    "teral-range\030local-type-template-args\027logical-not-parentheses\026l"
+    "ogical-op-parentheses\tlong-long\015loop-analysis\017macro-redefined\004"
+    "main\020main-return-type\027malformed-warning-check\022memsize-comparis"
+    "on\021method-signatures\tmicrosoft\020microsoft-exists\032mismatched-pa"
+    "rameter-types\027mismatched-return-types\017mismatched-tags\016missing-"
+    "braces\024missing-declarations\032missing-field-initializers\030missing"
+    "-format-attribute\024missing-include-dirs\032missing-method-return-type"
+    "\020missing-noreturn\022missing-prototypes\025missing-selector-name\017"
+    "missing-sysroot\035missing-variable-declarations\014module-build\017mod"
+    "ule-conflict\004most\014msvc-include\tmultichar\023multiple-move-vbase\t"
+    "narrowing\021nested-anon-types\016nested-externs\020new-returns-null\013"
+    "newline-eof\007non-gcc\033non-literal-null-conversion'non-modular-inclu"
+    "de-in-framework-module\035non-modular-include-in-module\017non-pod-vara"
+    "rgs\020non-virtual-dtor\007nonnull\025nonportable-cfstrings!nonportable"
+    "-vector-initialization\017null-arithmetic\016null-character\017null-con"
+    "version\020null-dereference+objc-autosynthesis-property-ivar-name-match"
+    "\016objc-cocoa-api\034objc-designated-initializers\037objc-forward-clas"
+    "s-redefinition\024objc-interface-ivars\024objc-literal-compare\027objc-"
+    "literal-conversion\022objc-method-access\037objc-missing-property-synth"
+    "esis\030objc-missing-super-calls\"objc-noncopy-retain-block-property\032"
+    "objc-nonunified-exceptions\034objc-property-implementation\037objc-prop"
+    "erty-implicit-mismatch*objc-property-matches-cocoa-ownership-rule\032ob"
+    "jc-property-no-attribute\027objc-property-synthesis#objc-protocol-metho"
+    "d-implementation objc-protocol-property-synthesis\"objc-readonly-with-s"
+    "etter-property\026objc-redundant-api-use\032objc-redundant-literal-use\017"
+    "objc-root-class\023objc-string-compare\031objc-string-concatenation\003"
+    "odr\016old-style-cast\024old-style-definition\016openmp-clauses\020open"
+    "mp-loop-form\027out-of-line-declaration\014over-aligned\010overflow\022"
+    "overlength-strings\037overloaded-shift-op-parentheses\022overloaded-vir"
+    "tual\032overriding-method-mismatch\023overriding-t-option\006packed\006"
+    "padded\013parentheses\024parentheses-equality\004pass\015pass-analysis\013"
+    "pass-failed\013pass-missed\010pedantic\015pointer-arith\027pointer-bool"
+    "-conversion\014pointer-sign\023pointer-to-int-cast\025pointer-type-mism"
+    "atch\007pragmas&predefined-identifier-outside-function\016private-exter"
+    "n\031profile-instr-out-of-date\030profile-instr-unprofiled\010protocol%"
+    "protocol-property-synthesis-ambiguity\032readonly-iboutlet-property\015"
+    "receiver-expr\026receiver-forward-class\020receiver-is-weak\027redeclar"
+    "ed-class-member\017redundant-decls\026reinterpret-base-class\025remark-"
+    "backend-plugin\007reorder\030requires-super-attribute\035reserved-user-"
+    "defined-literal\031retained-language-linkage\024return-stack-address\013"
+    "return-type\025return-type-c-linkage\007section\010selector\026selector"
+    "-type-mismatch\013self-assign\021self-assign-field\034semicolon-before-"
+    "method-body\010sentinel\016sequence-point\026serialized-diagnostics\006"
+    "shadow\013shadow-ivar\024shift-count-negative\024shift-count-overflow\024"
+    "shift-op-parentheses\016shift-overflow\023shift-sign-overflow\020shorte"
+    "n-64-to-32\014sign-compare\017sign-conversion\nsign-promo\025sizeof-arr"
+    "ay-argument\022sizeof-array-decay\030sizeof-pointer-memaccess\027someti"
+    "mes-uninitialized\022source-uses-openmp\017stack-protector\021static-fl"
+    "oat-init\020static-in-inline$static-inline-explicit-instantiation\026st"
+    "atic-local-in-inline\020static-self-init\017strict-aliasing\021strict-a"
+    "liasing=0\021strict-aliasing=1\021strict-aliasing=2\017strict-overflow\021"
+    "strict-overflow=0\021strict-overflow=1\021strict-overflow=2\021strict-o"
+    "verflow=3\021strict-overflow=4\021strict-overflow=5\021strict-prototype"
+    "s\025strict-selector-match\016string-compare\021string-conversion\020st"
+    "ring-plus-char\017string-plus-int\024strlcpy-strlcat-size\014strncat-si"
+    "ze\033super-class-method-mismatch\006switch\013switch-bool\016switch-de"
+    "fault\013switch-enum\005synth\024tautological-compare*tautological-cons"
+    "tant-out-of-range-compare\034tautological-overlap-compare\034tautologic"
+    "al-pointer-compare\036tautological-undefined-compare$tentative-definiti"
+    "on-incomplete-type\015thread-safety\026thread-safety-analysis\030thread"
+    "-safety-attributes\022thread-safety-beta\025thread-safety-precise\ttrig"
+    "raphs\013type-limits\013type-safety\024typedef-redefinition\020typename"
+    "-missing\030unavailable-declarations\023undeclared-selector\005undef\031"
+    "undefined-bool-conversion\020undefined-inline\022undefined-internal\032"
+    "undefined-reinterpret-cast\007unicode\022unicode-whitespace\015uninitia"
+    "lized\022unknown-attributes\027unknown-escape-sequence\017unknown-pragm"
+    "as\026unknown-warning-option\032unnamed-type-template-args\035unneeded-"
+    "internal-declaration\030unneeded-member-function\020unreachable-code\033"
+    "unreachable-code-aggressive\026unreachable-code-break\037unreachable-co"
+    "de-loop-increment\027unreachable-code-return\013unsequenced#unsupported"
+    "-dll-base-class-template\022unsupported-friend\026unsupported-visibilit"
+    "y\006unused\017unused-argument\034unused-command-line-argument\021unuse"
+    "d-comparison\025unused-const-variable\032unused-exception-parameter\017"
+    "unused-function\014unused-label\015unused-macros\026unused-member-funct"
+    "ion\020unused-parameter\024unused-private-field\024unused-property-ivar"
+    "\015unused-result\014unused-value\017unused-variable\026unused-volatile"
+    "-lvalue\026used-but-marked-unused\025user-defined-literals\007varargs\017"
+    "variadic-macros\021vector-conversion\022vector-conversions\014vexing-pa"
+    "rse\nvisibility\003vla\015vla-extension\024void-ptr-dereference\025vola"
+    "tile-register-var\025weak-template-vtables\014weak-vtables\020writable-"
+    "strings\015write-strings\021zero-length-array"};
+
+#endif // GET_DIAG_ARRAYS
+
+
+#ifdef GET_DIAG_TABLE
+  { /*  */                                                      0, /* Empty */     0, /* DiagSubGroup0 */ 1 },
+  { /* #pragma-messages */                                      1, /* DiagArray1 */ 1, /* Empty */         0 },
+  { /* #warnings */                                             18, /* DiagArray2 */ 3, /* Empty */         0 },
+  { /* CFString-literal */                                      28, /* DiagArray3 */ 5, /* Empty */         0 },
+  { /* NSObject-attribute */                                    45, /* DiagArray4 */ 7, /* Empty */         0 },
+  { /* abi */                                                   64, /* Empty */     0, /* Empty */         0 },
+  { /* absolute-value */                                        68, /* DiagArray6 */ 9, /* Empty */         0 },
+  { /* abstract-final-class */                                  83, /* DiagArray7 */ 13, /* Empty */         0 },
+  { /* abstract-vbase-init */                                   104, /* DiagArray8 */ 15, /* Empty */         0 },
+  { /* address */                                               124, /* Empty */     0, /* DiagSubGroup9 */ 3 },
+  { /* address-of-array-temporary */                            132, /* DiagArray10 */ 17, /* Empty */         0 },
+  { /* address-of-temporary */                                  159, /* DiagArray11 */ 19, /* Empty */         0 },
+  { /* aggregate-return */                                      180, /* Empty */     0, /* Empty */         0 },
+  { /* all */                                                   197, /* Empty */     0, /* DiagSubGroup13 */ 7 },
+  { /* ambiguous-macro */                                       201, /* DiagArray14 */ 21, /* Empty */         0 },
+  { /* ambiguous-member-template */                             217, /* DiagArray15 */ 23, /* Empty */         0 },
+  { /* analyzer-incompatible-plugin */                          243, /* DiagArray16 */ 25, /* Empty */         0 },
+  { /* anonymous-pack-parens */                                 272, /* DiagArray17 */ 27, /* Empty */         0 },
+  { /* arc */                                                   294, /* Empty */     0, /* DiagSubGroup18 */ 12 },
+  { /* arc-abi */                                               298, /* Empty */     0, /* Empty */         0 },
+  { /* arc-bridge-casts-disallowed-in-nonarc */                 306, /* DiagArray20 */ 29, /* Empty */         0 },
+  { /* arc-maybe-repeated-use-of-weak */                        344, /* DiagArray21 */ 31, /* Empty */         0 },
+  { /* arc-non-pod-memaccess */                                 375, /* DiagArray22 */ 33, /* Empty */         0 },
+  { /* arc-performSelector-leaks */                             397, /* DiagArray23 */ 35, /* Empty */         0 },
+  { /* arc-repeated-use-of-weak */                              423, /* DiagArray24 */ 37, /* DiagSubGroup24 */ 16 },
+  { /* arc-retain-cycles */                                     448, /* DiagArray25 */ 39, /* Empty */         0 },
+  { /* arc-unsafe-retained-assign */                            466, /* DiagArray26 */ 41, /* Empty */         0 },
+  { /* array-bounds */                                          493, /* DiagArray27 */ 45, /* Empty */         0 },
+  { /* array-bounds-pointer-arithmetic */                       506, /* DiagArray28 */ 50, /* Empty */         0 },
+  { /* asm */                                                   538, /* Empty */     0, /* DiagSubGroup29 */ 18 },
+  { /* asm-operand-widths */                                    542, /* DiagArray30 */ 53, /* Empty */         0 },
+  { /* assign-enum */                                           561, /* DiagArray31 */ 55, /* Empty */         0 },
+  { /* assume */                                                573, /* DiagArray32 */ 57, /* Empty */         0 },
+  { /* atomic-memory-ordering */                                580, /* DiagArray33 */ 59, /* Empty */         0 },
+  { /* atomic-properties */                                     603, /* Empty */     0, /* DiagSubGroup34 */ 20 },
+  { /* atomic-property-with-user-defined-accessor */            621, /* DiagArray35 */ 61, /* Empty */         0 },
+  { /* attributes */                                            664, /* Empty */     0, /* DiagSubGroup36 */ 23 },
+  { /* auto-import */                                           675, /* DiagArray37 */ 63, /* Empty */         0 },
+  { /* auto-storage-class */                                    687, /* DiagArray38 */ 65, /* Empty */         0 },
+  { /* auto-var-id */                                           706, /* DiagArray39 */ 67, /* Empty */         0 },
+  { /* availability */                                          718, /* DiagArray40 */ 69, /* Empty */         0 },
+  { /* backend-plugin */                                        731, /* DiagArray41 */ 76, /* Empty */         0 },
+  { /* backslash-newline-escape */                              746, /* DiagArray42 */ 78, /* Empty */         0 },
+  { /* bad-array-new-length */                                  771, /* DiagArray43 */ 80, /* Empty */         0 },
+  { /* bad-function-cast */                                     792, /* DiagArray44 */ 83, /* Empty */         0 },
+  { /* bind-to-temporary-copy */                                810, /* DiagArray45 */ 85, /* DiagSubGroup45 */ 26 },
+  { /* bitfield-constant-conversion */                          833, /* DiagArray46 */ 88, /* Empty */         0 },
+  { /* bitwise-op-parentheses */                                862, /* DiagArray47 */ 90, /* Empty */         0 },
+  { /* bool-conversion */                                       885, /* DiagArray48 */ 92, /* DiagSubGroup48 */ 28 },
+  { /* bool-conversions */                                      901, /* Empty */     0, /* DiagSubGroup49 */ 31 },
+  { /* bridge-cast */                                           918, /* DiagArray50 */ 94, /* Empty */         0 },
+  { /* builtin-macro-redefined */                               930, /* DiagArray51 */ 97, /* Empty */         0 },
+  { /* builtin-requires-header */                               954, /* DiagArray52 */ 100, /* Empty */         0 },
+  { /* c++-compat */                                            978, /* DiagArray53 */ 102, /* Empty */         0 },
+  { /* c++0x-compat */                                          989, /* Empty */     0, /* DiagSubGroup54 */ 33 },
+  { /* c++0x-extensions */                                      1002, /* Empty */     0, /* DiagSubGroup55 */ 35 },
+  { /* c++0x-narrowing */                                       1019, /* Empty */     0, /* DiagSubGroup56 */ 37 },
+  { /* c++11-compat */                                          1035, /* DiagArray57 */ 104, /* DiagSubGroup57 */ 39 },
+  { /* c++11-compat-deprecated-writable-strings */              1048, /* DiagArray58 */ 113, /* Empty */         0 },
+  { /* c++11-compat-pedantic */                                 1089, /* Empty */     0, /* DiagSubGroup59 */ 45 },
+  { /* c++11-compat-reserved-user-defined-literal */            1111, /* DiagArray60 */ 115, /* Empty */         0 },
+  { /* c++11-extensions */                                      1154, /* DiagArray61 */ 117, /* DiagSubGroup61 */ 48 },
+  { /* c++11-extra-semi */                                      1171, /* DiagArray62 */ 146, /* Empty */         0 },
+  { /* c++11-long-long */                                       1188, /* DiagArray63 */ 148, /* Empty */         0 },
+  { /* c++11-narrowing */                                       1204, /* DiagArray64 */ 150, /* Empty */         0 },
+  { /* c++14-compat */                                          1220, /* Empty */     0, /* DiagSubGroup65 */ 51 },
+  { /* c++14-compat-pedantic */                                 1233, /* Empty */     0, /* DiagSubGroup66 */ 53 },
+  { /* c++1y-extensions */                                      1255, /* DiagArray67 */ 158, /* Empty */         0 },
+  { /* c++1z-extensions */                                      1272, /* DiagArray68 */ 167, /* Empty */         0 },
+  { /* c++98-c++11-c++14-compat */                              1289, /* DiagArray69 */ 171, /* Empty */         0 },
+  { /* c++98-c++11-c++14-compat-pedantic */                     1314, /* Empty */     0, /* DiagSubGroup70 */ 55 },
+  { /* c++98-c++11-compat */                                    1348, /* DiagArray71 */ 175, /* Empty */         0 },
+  { /* c++98-c++11-compat-pedantic */                           1367, /* DiagArray72 */ 185, /* DiagSubGroup72 */ 57 },
+  { /* c++98-compat */                                          1395, /* DiagArray73 */ 187, /* DiagSubGroup73 */ 59 },
+  { /* c++98-compat-bind-to-temporary-copy */                   1408, /* DiagArray74 */ 249, /* Empty */         0 },
+  { /* c++98-compat-local-type-template-args */                 1444, /* DiagArray75 */ 251, /* Empty */         0 },
+  { /* c++98-compat-pedantic */                                 1482, /* DiagArray76 */ 253, /* DiagSubGroup76 */ 65 },
+  { /* c++98-compat-unnamed-type-template-args */               1504, /* DiagArray77 */ 265, /* Empty */         0 },
+  { /* c11-extensions */                                        1544, /* DiagArray78 */ 267, /* Empty */         0 },
+  { /* c99-compat */                                            1559, /* DiagArray79 */ 274, /* Empty */         0 },
+  { /* c99-extensions */                                        1570, /* DiagArray80 */ 277, /* Empty */         0 },
+  { /* cast-align */                                            1585, /* DiagArray81 */ 288, /* Empty */         0 },
+  { /* cast-of-sel-type */                                      1596, /* DiagArray82 */ 290, /* Empty */         0 },
+  { /* cast-qual */                                             1613, /* Empty */     0, /* Empty */         0 },
+  { /* char-align */                                            1623, /* Empty */     0, /* Empty */         0 },
+  { /* char-subscripts */                                       1634, /* DiagArray85 */ 292, /* Empty */         0 },
+  { /* class-varargs */                                         1650, /* DiagArray86 */ 294, /* DiagSubGroup86 */ 69 },
+  { /* comment */                                               1664, /* DiagArray87 */ 296, /* Empty */         0 },
+  { /* comments */                                              1672, /* Empty */     0, /* DiagSubGroup88 */ 71 },
+  { /* compare-distinct-pointer-types */                        1681, /* DiagArray89 */ 301, /* Empty */         0 },
+  { /* complex-component-init */                                1712, /* DiagArray90 */ 304, /* Empty */         0 },
+  { /* conditional-type-mismatch */                             1735, /* DiagArray91 */ 306, /* Empty */         0 },
+  { /* conditional-uninitialized */                             1761, /* DiagArray92 */ 308, /* Empty */         0 },
+  { /* config-macros */                                         1787, /* DiagArray93 */ 310, /* Empty */         0 },
+  { /* constant-conversion */                                   1801, /* DiagArray94 */ 312, /* DiagSubGroup94 */ 73 },
+  { /* constant-logical-operand */                              1821, /* DiagArray95 */ 314, /* Empty */         0 },
+  { /* constexpr-not-const */                                   1846, /* DiagArray96 */ 316, /* Empty */         0 },
+  { /* consumed */                                              1866, /* DiagArray97 */ 318, /* Empty */         0 },
+  { /* conversion */                                            1875, /* DiagArray98 */ 327, /* DiagSubGroup98 */ 75 },
+  { /* conversion-null */                                       1886, /* Empty */     0, /* DiagSubGroup99 */ 88 },
+  { /* covered-switch-default */                                1902, /* DiagArray100 */ 334, /* Empty */         0 },
+  { /* ctor-dtor-privacy */                                     1925, /* Empty */     0, /* Empty */         0 },
+  { /* cuda-compat */                                           1943, /* DiagArray102 */ 336, /* Empty */         0 },
+  { /* custom-atomic-properties */                              1955, /* DiagArray103 */ 338, /* Empty */         0 },
+  { /* dangling-else */                                         1980, /* DiagArray104 */ 340, /* Empty */         0 },
+  { /* dangling-field */                                        1994, /* DiagArray105 */ 342, /* Empty */         0 },
+  { /* dangling-initializer-list */                             2009, /* DiagArray106 */ 346, /* Empty */         0 },
+  { /* date-time */                                             2035, /* DiagArray107 */ 348, /* Empty */         0 },
+  { /* dealloc-in-category */                                   2045, /* DiagArray108 */ 350, /* Empty */         0 },
+  { /* debug-compression-unavailable */                         2065, /* DiagArray109 */ 352, /* Empty */         0 },
+  { /* declaration-after-statement */                           2095, /* DiagArray110 */ 354, /* Empty */         0 },
+  { /* delegating-ctor-cycles */                                2123, /* DiagArray111 */ 356, /* Empty */         0 },
+  { /* delete-incomplete */                                     2146, /* DiagArray112 */ 358, /* Empty */         0 },
+  { /* delete-non-virtual-dtor */                               2164, /* DiagArray113 */ 360, /* Empty */         0 },
+  { /* deprecated */                                            2188, /* DiagArray114 */ 363, /* DiagSubGroup114 */ 90 },
+  { /* deprecated-declarations */                               2199, /* DiagArray115 */ 370, /* Empty */         0 },
+  { /* deprecated-implementations */                            2223, /* DiagArray116 */ 376, /* Empty */         0 },
+  { /* deprecated-increment-bool */                             2250, /* DiagArray117 */ 378, /* Empty */         0 },
+  { /* deprecated-objc-isa-usage */                             2276, /* DiagArray118 */ 380, /* Empty */         0 },
+  { /* deprecated-objc-pointer-introspection */                 2302, /* DiagArray119 */ 383, /* DiagSubGroup119 */ 95 },
+  { /* deprecated-objc-pointer-introspection-performSelector */ 2340, /* DiagArray120 */ 385, /* Empty */         0 },
+  { /* deprecated-register */                                   2394, /* DiagArray121 */ 387, /* Empty */         0 },
+  { /* deprecated-writable-strings */                           2414, /* Empty */     0, /* DiagSubGroup122 */ 97 },
+  { /* direct-ivar-access */                                    2442, /* DiagArray123 */ 389, /* Empty */         0 },
+  { /* disabled-macro-expansion */                              2461, /* DiagArray124 */ 391, /* Empty */         0 },
+  { /* disabled-optimization */                                 2486, /* Empty */     0, /* Empty */         0 },
+  { /* discard-qual */                                          2508, /* Empty */     0, /* Empty */         0 },
+  { /* distributed-object-modifiers */                          2521, /* DiagArray127 */ 393, /* Empty */         0 },
+  { /* div-by-zero */                                           2550, /* Empty */     0, /* Empty */         0 },
+  { /* division-by-zero */                                      2562, /* DiagArray129 */ 396, /* Empty */         0 },
+  { /* dll-attribute-on-redeclaration */                        2579, /* DiagArray130 */ 399, /* Empty */         0 },
+  { /* dllimport-static-field-def */                            2610, /* DiagArray131 */ 401, /* Empty */         0 },
+  { /* documentation */                                         2637, /* DiagArray132 */ 403, /* DiagSubGroup132 */ 99 },
+  { /* documentation-deprecated-sync */                         2651, /* DiagArray133 */ 423, /* Empty */         0 },
+  { /* documentation-html */                                    2681, /* DiagArray134 */ 425, /* Empty */         0 },
+  { /* documentation-pedantic */                                2700, /* DiagArray135 */ 430, /* DiagSubGroup135 */ 102 },
+  { /* documentation-unknown-command */                         2723, /* DiagArray136 */ 432, /* Empty */         0 },
+  { /* dollar-in-identifier-extension */                        2753, /* DiagArray137 */ 434, /* Empty */         0 },
+  { /* duplicate-decl-specifier */                              2784, /* DiagArray138 */ 436, /* Empty */         0 },
+  { /* duplicate-enum */                                        2809, /* DiagArray139 */ 439, /* Empty */         0 },
+  { /* duplicate-method-arg */                                  2824, /* DiagArray140 */ 441, /* Empty */         0 },
+  { /* duplicate-method-match */                                2845, /* DiagArray141 */ 443, /* Empty */         0 },
+  { /* dynamic-class-memaccess */                               2868, /* DiagArray142 */ 445, /* Empty */         0 },
+  { /* effc++ */                                                2892, /* Empty */     0, /* Empty */         0 },
+  { /* embedded-directive */                                    2899, /* DiagArray144 */ 447, /* Empty */         0 },
+  { /* empty-body */                                            2918, /* DiagArray145 */ 449, /* Empty */         0 },
+  { /* empty-translation-unit */                                2929, /* DiagArray146 */ 455, /* Empty */         0 },
+  { /* endif-labels */                                          2952, /* Empty */     0, /* DiagSubGroup147 */ 104 },
+  { /* enum-compare */                                          2965, /* DiagArray148 */ 457, /* Empty */         0 },
+  { /* enum-conversion */                                       2978, /* DiagArray149 */ 459, /* Empty */         0 },
+  { /* enum-too-large */                                        2994, /* DiagArray150 */ 461, /* Empty */         0 },
+  { /* exit-time-destructors */                                 3009, /* DiagArray151 */ 464, /* Empty */         0 },
+  { /* explicit-ownership-type */                               3031, /* DiagArray152 */ 466, /* Empty */         0 },
+  { /* extended-offsetof */                                     3055, /* DiagArray153 */ 468, /* Empty */         0 },
+  { /* extern-c-compat */                                       3073, /* DiagArray154 */ 470, /* Empty */         0 },
+  { /* extern-initializer */                                    3089, /* DiagArray155 */ 472, /* Empty */         0 },
+  { /* extra */                                                 3108, /* Empty */     0, /* DiagSubGroup156 */ 106 },
+  { /* extra-qualification */                                   3114, /* DiagArray157 */ 474, /* Empty */         0 },
+  { /* extra-semi */                                            3134, /* DiagArray158 */ 476, /* DiagSubGroup158 */ 114 },
+  { /* extra-tokens */                                          3145, /* DiagArray159 */ 479, /* Empty */         0 },
+  { /* fallback */                                              3158, /* DiagArray160 */ 482, /* Empty */         0 },
+  { /* flexible-array-extensions */                             3167, /* DiagArray161 */ 484, /* Empty */         0 },
+  { /* float-conversion */                                      3193, /* DiagArray162 */ 487, /* Empty */         0 },
+  { /* float-equal */                                           3210, /* DiagArray163 */ 489, /* Empty */         0 },
+  { /* format */                                                3222, /* DiagArray164 */ 491, /* DiagSubGroup164 */ 116 },
+  { /* format-extra-args */                                     3229, /* DiagArray165 */ 512, /* Empty */         0 },
+  { /* format-invalid-specifier */                              3247, /* DiagArray166 */ 514, /* Empty */         0 },
+  { /* format-non-iso */                                        3272, /* DiagArray167 */ 516, /* Empty */         0 },
+  { /* format-nonliteral */                                     3287, /* DiagArray168 */ 520, /* Empty */         0 },
+  { /* format-security */                                       3305, /* DiagArray169 */ 522, /* Empty */         0 },
+  { /* format-y2k */                                            3321, /* Empty */     0, /* Empty */         0 },
+  { /* format-zero-length */                                    3332, /* DiagArray171 */ 524, /* Empty */         0 },
+  { /* format=2 */                                              3351, /* Empty */     0, /* DiagSubGroup172 */ 123 },
+  { /* four-char-constants */                                   3360, /* DiagArray173 */ 526, /* Empty */         0 },
+  { /* frame-larger-than= */                                    3380, /* DiagArray174 */ 528, /* Empty */         0 },
+  { /* function-def-in-objc-container */                        3399, /* DiagArray175 */ 531, /* Empty */         0 },
+  { /* gcc-compat */                                            3430, /* DiagArray176 */ 533, /* Empty */         0 },
+  { /* global-constructors */                                   3441, /* DiagArray177 */ 538, /* Empty */         0 },
+  { /* gnu */                                                   3461, /* Empty */     0, /* DiagSubGroup178 */ 127 },
+  { /* gnu-alignof-expression */                                3465, /* DiagArray179 */ 541, /* Empty */         0 },
+  { /* gnu-anonymous-struct */                                  3488, /* DiagArray180 */ 543, /* Empty */         0 },
+  { /* gnu-array-member-paren-init */                           3509, /* DiagArray181 */ 545, /* Empty */         0 },
+  { /* gnu-binary-literal */                                    3537, /* DiagArray182 */ 547, /* Empty */         0 },
+  { /* gnu-case-range */                                        3556, /* DiagArray183 */ 549, /* Empty */         0 },
+  { /* gnu-complex-integer */                                   3571, /* DiagArray184 */ 551, /* Empty */         0 },
+  { /* gnu-compound-literal-initializer */                      3591, /* DiagArray185 */ 553, /* Empty */         0 },
+  { /* gnu-conditional-omitted-operand */                       3624, /* DiagArray186 */ 555, /* Empty */         0 },
+  { /* gnu-designator */                                        3656, /* DiagArray187 */ 557, /* Empty */         0 },
+  { /* gnu-empty-initializer */                                 3671, /* DiagArray188 */ 561, /* Empty */         0 },
+  { /* gnu-empty-struct */                                      3693, /* DiagArray189 */ 563, /* Empty */         0 },
+  { /* gnu-flexible-array-initializer */                        3710, /* DiagArray190 */ 567, /* Empty */         0 },
+  { /* gnu-flexible-array-union-member */                       3741, /* DiagArray191 */ 569, /* Empty */         0 },
+  { /* gnu-folding-constant */                                  3773, /* DiagArray192 */ 571, /* Empty */         0 },
+  { /* gnu-imaginary-constant */                                3794, /* DiagArray193 */ 575, /* Empty */         0 },
+  { /* gnu-label-as-value */                                    3817, /* DiagArray194 */ 577, /* Empty */         0 },
+  { /* gnu-redeclared-enum */                                   3836, /* DiagArray195 */ 580, /* Empty */         0 },
+  { /* gnu-statement-expression */                              3856, /* DiagArray196 */ 582, /* Empty */         0 },
+  { /* gnu-static-float-init */                                 3881, /* DiagArray197 */ 584, /* Empty */         0 },
+  { /* gnu-string-literal-operator-template */                  3903, /* DiagArray198 */ 586, /* Empty */         0 },
+  { /* gnu-union-cast */                                        3940, /* DiagArray199 */ 588, /* Empty */         0 },
+  { /* gnu-variable-sized-type-not-at-end */                    3955, /* DiagArray200 */ 590, /* Empty */         0 },
+  { /* gnu-zero-line-directive */                               3990, /* DiagArray201 */ 592, /* Empty */         0 },
+  { /* gnu-zero-variadic-macro-arguments */                     4014, /* DiagArray202 */ 594, /* Empty */         0 },
+  { /* header-guard */                                          4048, /* DiagArray203 */ 597, /* Empty */         0 },
+  { /* header-hygiene */                                        4061, /* DiagArray204 */ 599, /* Empty */         0 },
+  { /* idiomatic-parentheses */                                 4076, /* DiagArray205 */ 601, /* Empty */         0 },
+  { /* ignored-attributes */                                    4098, /* DiagArray206 */ 603, /* Empty */         0 },
+  { /* ignored-pragmas */                                       4117, /* DiagArray207 */ 646, /* Empty */         0 },
+  { /* ignored-qualifiers */                                    4133, /* DiagArray208 */ 679, /* Empty */         0 },
+  { /* implicit */                                              4152, /* Empty */     0, /* DiagSubGroup209 */ 154 },
+  { /* implicit-atomic-properties */                            4161, /* DiagArray210 */ 683, /* Empty */         0 },
+  { /* implicit-conversion-floating-point-to-bool */            4188, /* DiagArray211 */ 686, /* Empty */         0 },
+  { /* implicit-exception-spec-mismatch */                      4231, /* DiagArray212 */ 688, /* Empty */         0 },
+  { /* implicit-fallthrough */                                  4264, /* DiagArray213 */ 690, /* DiagSubGroup213 */ 157 },
+  { /* implicit-fallthrough-per-function */                     4285, /* DiagArray214 */ 694, /* Empty */         0 },
+  { /* implicit-function-declaration */                         4319, /* DiagArray215 */ 696, /* Empty */         0 },
+  { /* implicit-int */                                          4349, /* DiagArray216 */ 700, /* Empty */         0 },
+  { /* implicit-retain-self */                                  4362, /* DiagArray217 */ 702, /* Empty */         0 },
+  { /* implicitly-unsigned-literal */                           4383, /* DiagArray218 */ 704, /* Empty */         0 },
+  { /* import */                                                4411, /* Empty */     0, /* Empty */         0 },
+  { /* import-preprocessor-directive-pedantic */                4418, /* DiagArray220 */ 706, /* Empty */         0 },
+  { /* incompatible-library-redeclaration */                    4457, /* DiagArray221 */ 708, /* Empty */         0 },
+  { /* incompatible-ms-struct */                                4492, /* DiagArray222 */ 710, /* Empty */         0 },
+  { /* incompatible-pointer-types */                            4515, /* DiagArray223 */ 712, /* DiagSubGroup223 */ 159 },
+  { /* incompatible-pointer-types-discards-qualifiers */        4542, /* DiagArray224 */ 714, /* Empty */         0 },
+  { /* incomplete-implementation */                             4589, /* DiagArray225 */ 717, /* Empty */         0 },
+  { /* incomplete-module */                                     4615, /* DiagArray226 */ 719, /* DiagSubGroup226 */ 161 },
+  { /* incomplete-umbrella */                                   4633, /* DiagArray227 */ 721, /* Empty */         0 },
+  { /* infinite-recursion */                                    4653, /* DiagArray228 */ 724, /* Empty */         0 },
+  { /* inherited-variadic-ctor */                               4672, /* DiagArray229 */ 726, /* Empty */         0 },
+  { /* init-self */                                             4696, /* Empty */     0, /* Empty */         0 },
+  { /* initializer-overrides */                                 4706, /* DiagArray231 */ 728, /* Empty */         0 },
+  { /* inline */                                                4728, /* Empty */     0, /* Empty */         0 },
+  { /* inline-asm */                                            4735, /* DiagArray233 */ 731, /* Empty */         0 },
+  { /* inline-new-delete */                                     4746, /* DiagArray234 */ 733, /* Empty */         0 },
+  { /* int-conversion */                                        4764, /* DiagArray235 */ 735, /* Empty */         0 },
+  { /* int-conversions */                                       4779, /* Empty */     0, /* DiagSubGroup236 */ 163 },
+  { /* int-to-pointer-cast */                                   4795, /* DiagArray237 */ 738, /* DiagSubGroup237 */ 165 },
+  { /* int-to-void-pointer-cast */                              4815, /* DiagArray238 */ 740, /* Empty */         0 },
+  { /* integer-overflow */                                      4840, /* DiagArray239 */ 742, /* Empty */         0 },
+  { /* invalid-command-line-argument */                         4857, /* DiagArray240 */ 744, /* Empty */         0 },
+  { /* invalid-constexpr */                                     4887, /* DiagArray241 */ 747, /* Empty */         0 },
+  { /* invalid-iboutlet */                                      4905, /* DiagArray242 */ 749, /* Empty */         0 },
+  { /* invalid-initializer-from-system-header */                4922, /* DiagArray243 */ 752, /* Empty */         0 },
+  { /* invalid-noreturn */                                      4961, /* DiagArray244 */ 754, /* Empty */         0 },
+  { /* invalid-offsetof */                                      4978, /* DiagArray245 */ 757, /* Empty */         0 },
+  { /* invalid-pch */                                           4995, /* Empty */     0, /* Empty */         0 },
+  { /* invalid-pp-token */                                      5007, /* DiagArray247 */ 760, /* Empty */         0 },
+  { /* invalid-source-encoding */                               5024, /* DiagArray248 */ 764, /* Empty */         0 },
+  { /* invalid-token-paste */                                   5048, /* DiagArray249 */ 767, /* Empty */         0 },
+  { /* keyword-compat */                                        5068, /* DiagArray250 */ 769, /* Empty */         0 },
+  { /* knr-promoted-parameter */                                5083, /* DiagArray251 */ 771, /* Empty */         0 },
+  { /* language-extension-token */                              5106, /* DiagArray252 */ 773, /* Empty */         0 },
+  { /* large-by-value-copy */                                   5131, /* DiagArray253 */ 775, /* Empty */         0 },
+  { /* literal-conversion */                                    5151, /* DiagArray254 */ 778, /* Empty */         0 },
+  { /* literal-range */                                         5170, /* DiagArray255 */ 780, /* Empty */         0 },
+  { /* local-type-template-args */                              5184, /* DiagArray256 */ 783, /* DiagSubGroup256 */ 167 },
+  { /* logical-not-parentheses */                               5209, /* DiagArray257 */ 785, /* Empty */         0 },
+  { /* logical-op-parentheses */                                5233, /* DiagArray258 */ 787, /* Empty */         0 },
+  { /* long-long */                                             5256, /* DiagArray259 */ 789, /* DiagSubGroup259 */ 169 },
+  { /* loop-analysis */                                         5266, /* DiagArray260 */ 791, /* Empty */         0 },
+  { /* macro-redefined */                                       5280, /* DiagArray261 */ 794, /* Empty */         0 },
+  { /* main */                                                  5296, /* DiagArray262 */ 796, /* Empty */         0 },
+  { /* main-return-type */                                      5301, /* DiagArray263 */ 801, /* Empty */         0 },
+  { /* malformed-warning-check */                               5318, /* DiagArray264 */ 803, /* Empty */         0 },
+  { /* memsize-comparison */                                    5342, /* DiagArray265 */ 805, /* Empty */         0 },
+  { /* method-signatures */                                     5361, /* DiagArray266 */ 807, /* Empty */         0 },
+  { /* microsoft */                                             5379, /* DiagArray267 */ 810, /* Empty */         0 },
+  { /* microsoft-exists */                                      5389, /* DiagArray268 */ 841, /* Empty */         0 },
+  { /* mismatched-parameter-types */                            5406, /* DiagArray269 */ 843, /* Empty */         0 },
+  { /* mismatched-return-types */                               5433, /* DiagArray270 */ 845, /* Empty */         0 },
+  { /* mismatched-tags */                                       5457, /* DiagArray271 */ 847, /* Empty */         0 },
+  { /* missing-braces */                                        5473, /* DiagArray272 */ 850, /* Empty */         0 },
+  { /* missing-declarations */                                  5488, /* DiagArray273 */ 852, /* Empty */         0 },
+  { /* missing-field-initializers */                            5509, /* DiagArray274 */ 857, /* Empty */         0 },
+  { /* missing-format-attribute */                              5536, /* Empty */     0, /* Empty */         0 },
+  { /* missing-include-dirs */                                  5561, /* Empty */     0, /* Empty */         0 },
+  { /* missing-method-return-type */                            5582, /* DiagArray277 */ 859, /* Empty */         0 },
+  { /* missing-noreturn */                                      5609, /* DiagArray278 */ 861, /* Empty */         0 },
+  { /* missing-prototypes */                                    5626, /* DiagArray279 */ 864, /* Empty */         0 },
+  { /* missing-selector-name */                                 5645, /* DiagArray280 */ 866, /* Empty */         0 },
+  { /* missing-sysroot */                                       5667, /* DiagArray281 */ 868, /* Empty */         0 },
+  { /* missing-variable-declarations */                         5683, /* DiagArray282 */ 870, /* Empty */         0 },
+  { /* module-build */                                          5713, /* DiagArray283 */ 872, /* Empty */         0 },
+  { /* module-conflict */                                       5726, /* DiagArray284 */ 874, /* Empty */         0 },
+  { /* most */                                                  5742, /* Empty */     0, /* DiagSubGroup285 */ 171 },
+  { /* msvc-include */                                          5747, /* DiagArray286 */ 876, /* Empty */         0 },
+  { /* multichar */                                             5760, /* DiagArray287 */ 878, /* Empty */         0 },
+  { /* multiple-move-vbase */                                   5770, /* DiagArray288 */ 880, /* Empty */         0 },
+  { /* narrowing */                                             5790, /* Empty */     0, /* DiagSubGroup289 */ 197 },
+  { /* nested-anon-types */                                     5800, /* DiagArray290 */ 882, /* Empty */         0 },
+  { /* nested-externs */                                        5818, /* Empty */     0, /* Empty */         0 },
+  { /* new-returns-null */                                      5833, /* DiagArray292 */ 884, /* Empty */         0 },
+  { /* newline-eof */                                           5850, /* DiagArray293 */ 886, /* Empty */         0 },
+  { /* non-gcc */                                               5862, /* Empty */     0, /* DiagSubGroup294 */ 199 },
+  { /* non-literal-null-conversion */                           5870, /* DiagArray295 */ 889, /* Empty */         0 },
+  { /* non-modular-include-in-framework-module */               5898, /* DiagArray296 */ 891, /* Empty */         0 },
+  { /* non-modular-include-in-module */                         5938, /* DiagArray297 */ 893, /* DiagSubGroup297 */ 203 },
+  { /* non-pod-varargs */                                       5968, /* DiagArray298 */ 895, /* Empty */         0 },
+  { /* non-virtual-dtor */                                      5984, /* DiagArray299 */ 900, /* Empty */         0 },
+  { /* nonnull */                                               6001, /* DiagArray300 */ 902, /* Empty */         0 },
+  { /* nonportable-cfstrings */                                 6009, /* Empty */     0, /* Empty */         0 },
+  { /* nonportable-vector-initialization */                     6031, /* DiagArray302 */ 905, /* Empty */         0 },
+  { /* null-arithmetic */                                       6065, /* DiagArray303 */ 907, /* Empty */         0 },
+  { /* null-character */                                        6081, /* DiagArray304 */ 910, /* Empty */         0 },
+  { /* null-conversion */                                       6096, /* DiagArray305 */ 914, /* Empty */         0 },
+  { /* null-dereference */                                      6112, /* DiagArray306 */ 916, /* Empty */         0 },
+  { /* objc-autosynthesis-property-ivar-name-match */           6129, /* DiagArray307 */ 918, /* Empty */         0 },
+  { /* objc-cocoa-api */                                        6173, /* Empty */     0, /* DiagSubGroup308 */ 205 },
+  { /* objc-designated-initializers */                          6188, /* DiagArray309 */ 920, /* Empty */         0 },
+  { /* objc-forward-class-redefinition */                       6217, /* DiagArray310 */ 927, /* Empty */         0 },
+  { /* objc-interface-ivars */                                  6249, /* DiagArray311 */ 929, /* Empty */         0 },
+  { /* objc-literal-compare */                                  6270, /* DiagArray312 */ 931, /* DiagSubGroup312 */ 207 },
+  { /* objc-literal-conversion */                               6291, /* DiagArray313 */ 933, /* Empty */         0 },
+  { /* objc-method-access */                                    6315, /* DiagArray314 */ 935, /* Empty */         0 },
+  { /* objc-missing-property-synthesis */                       6334, /* DiagArray315 */ 942, /* Empty */         0 },
+  { /* objc-missing-super-calls */                              6366, /* DiagArray316 */ 944, /* Empty */         0 },
+  { /* objc-noncopy-retain-block-property */                    6391, /* DiagArray317 */ 946, /* Empty */         0 },
+  { /* objc-nonunified-exceptions */                            6426, /* DiagArray318 */ 948, /* Empty */         0 },
+  { /* objc-property-implementation */                          6453, /* DiagArray319 */ 950, /* Empty */         0 },
+  { /* objc-property-implicit-mismatch */                       6482, /* DiagArray320 */ 953, /* Empty */         0 },
+  { /* objc-property-matches-cocoa-ownership-rule */            6514, /* DiagArray321 */ 955, /* Empty */         0 },
+  { /* objc-property-no-attribute */                            6557, /* DiagArray322 */ 957, /* Empty */         0 },
+  { /* objc-property-synthesis */                               6584, /* DiagArray323 */ 960, /* Empty */         0 },
+  { /* objc-protocol-method-implementation */                   6608, /* DiagArray324 */ 963, /* Empty */         0 },
+  { /* objc-protocol-property-synthesis */                      6644, /* DiagArray325 */ 965, /* Empty */         0 },
+  { /* objc-readonly-with-setter-property */                    6677, /* DiagArray326 */ 967, /* Empty */         0 },
+  { /* objc-redundant-api-use */                                6712, /* Empty */     0, /* DiagSubGroup327 */ 209 },
+  { /* objc-redundant-literal-use */                            6735, /* DiagArray328 */ 969, /* Empty */         0 },
+  { /* objc-root-class */                                       6762, /* DiagArray329 */ 971, /* Empty */         0 },
+  { /* objc-string-compare */                                   6778, /* DiagArray330 */ 973, /* Empty */         0 },
+  { /* objc-string-concatenation */                             6798, /* DiagArray331 */ 975, /* Empty */         0 },
+  { /* odr */                                                   6824, /* DiagArray332 */ 977, /* Empty */         0 },
+  { /* old-style-cast */                                        6828, /* DiagArray333 */ 979, /* Empty */         0 },
+  { /* old-style-definition */                                  6843, /* Empty */     0, /* Empty */         0 },
+  { /* openmp-clauses */                                        6864, /* DiagArray335 */ 981, /* Empty */         0 },
+  { /* openmp-loop-form */                                      6879, /* DiagArray336 */ 983, /* Empty */         0 },
+  { /* out-of-line-declaration */                               6896, /* DiagArray337 */ 985, /* Empty */         0 },
+  { /* over-aligned */                                          6920, /* DiagArray338 */ 987, /* Empty */         0 },
+  { /* overflow */                                              6933, /* Empty */     0, /* Empty */         0 },
+  { /* overlength-strings */                                    6942, /* DiagArray340 */ 989, /* Empty */         0 },
+  { /* overloaded-shift-op-parentheses */                       6961, /* DiagArray341 */ 991, /* Empty */         0 },
+  { /* overloaded-virtual */                                    6993, /* DiagArray342 */ 993, /* Empty */         0 },
+  { /* overriding-method-mismatch */                            7012, /* DiagArray343 */ 995, /* Empty */         0 },
+  { /* overriding-t-option */                                   7039, /* DiagArray344 */ 1003, /* Empty */         0 },
+  { /* packed */                                                7059, /* DiagArray345 */ 1005, /* Empty */         0 },
+  { /* padded */                                                7066, /* DiagArray346 */ 1007, /* Empty */         0 },
+  { /* parentheses */                                           7073, /* DiagArray347 */ 1011, /* DiagSubGroup347 */ 211 },
+  { /* parentheses-equality */                                  7085, /* DiagArray348 */ 1015, /* Empty */         0 },
+  { /* pass */                                                  7106, /* DiagArray349 */ 1017, /* Empty */         0 },
+  { /* pass-analysis */                                         7111, /* DiagArray350 */ 1019, /* Empty */         0 },
+  { /* pass-failed */                                           7125, /* DiagArray351 */ 1021, /* Empty */         0 },
+  { /* pass-missed */                                           7137, /* DiagArray352 */ 1023, /* Empty */         0 },
+  { /* pedantic */                                              7149, /* DiagArray353 */ 1025, /* DiagSubGroup353 */ 219 },
+  { /* pointer-arith */                                         7158, /* DiagArray354 */ 1090, /* Empty */         0 },
+  { /* pointer-bool-conversion */                               7172, /* DiagArray355 */ 1097, /* Empty */         0 },
+  { /* pointer-sign */                                          7196, /* DiagArray356 */ 1099, /* Empty */         0 },
+  { /* pointer-to-int-cast */                                   7209, /* Empty */     0, /* Empty */         0 },
+  { /* pointer-type-mismatch */                                 7229, /* DiagArray358 */ 1101, /* Empty */         0 },
+  { /* pragmas */                                               7251, /* Empty */     0, /* DiagSubGroup359 */ 259 },
+  { /* predefined-identifier-outside-function */                7259, /* DiagArray360 */ 1103, /* Empty */         0 },
+  { /* private-extern */                                        7298, /* DiagArray361 */ 1105, /* Empty */         0 },
+  { /* profile-instr-out-of-date */                             7313, /* DiagArray362 */ 1107, /* Empty */         0 },
+  { /* profile-instr-unprofiled */                              7339, /* DiagArray363 */ 1109, /* Empty */         0 },
+  { /* protocol */                                              7364, /* DiagArray364 */ 1111, /* Empty */         0 },
+  { /* protocol-property-synthesis-ambiguity */                 7373, /* DiagArray365 */ 1113, /* Empty */         0 },
+  { /* readonly-iboutlet-property */                            7411, /* DiagArray366 */ 1115, /* Empty */         0 },
+  { /* receiver-expr */                                         7438, /* DiagArray367 */ 1117, /* Empty */         0 },
+  { /* receiver-forward-class */                                7452, /* DiagArray368 */ 1119, /* Empty */         0 },
+  { /* receiver-is-weak */                                      7475, /* DiagArray369 */ 1122, /* Empty */         0 },
+  { /* redeclared-class-member */                               7492, /* DiagArray370 */ 1124, /* Empty */         0 },
+  { /* redundant-decls */                                       7516, /* Empty */     0, /* Empty */         0 },
+  { /* reinterpret-base-class */                                7532, /* DiagArray372 */ 1126, /* Empty */         0 },
+  { /* remark-backend-plugin */                                 7555, /* DiagArray373 */ 1128, /* Empty */         0 },
+  { /* reorder */                                               7577, /* DiagArray374 */ 1130, /* Empty */         0 },
+  { /* requires-super-attribute */                              7585, /* DiagArray375 */ 1132, /* Empty */         0 },
+  { /* reserved-user-defined-literal */                         7610, /* DiagArray376 */ 1134, /* DiagSubGroup376 */ 262 },
+  { /* retained-language-linkage */                             7640, /* DiagArray377 */ 1137, /* Empty */         0 },
+  { /* return-stack-address */                                  7666, /* DiagArray378 */ 1139, /* Empty */         0 },
+  { /* return-type */                                           7687, /* DiagArray379 */ 1145, /* DiagSubGroup379 */ 264 },
+  { /* return-type-c-linkage */                                 7699, /* DiagArray380 */ 1153, /* Empty */         0 },
+  { /* section */                                               7721, /* DiagArray381 */ 1156, /* Empty */         0 },
+  { /* selector */                                              7729, /* DiagArray382 */ 1158, /* DiagSubGroup382 */ 266 },
+  { /* selector-type-mismatch */                                7738, /* DiagArray383 */ 1160, /* Empty */         0 },
+  { /* self-assign */                                           7761, /* DiagArray384 */ 1162, /* DiagSubGroup384 */ 268 },
+  { /* self-assign-field */                                     7773, /* DiagArray385 */ 1164, /* Empty */         0 },
+  { /* semicolon-before-method-body */                          7791, /* DiagArray386 */ 1166, /* Empty */         0 },
+  { /* sentinel */                                              7820, /* DiagArray387 */ 1168, /* Empty */         0 },
+  { /* sequence-point */                                        7829, /* Empty */     0, /* DiagSubGroup388 */ 270 },
+  { /* serialized-diagnostics */                                7844, /* DiagArray389 */ 1171, /* Empty */         0 },
+  { /* shadow */                                                7867, /* DiagArray390 */ 1173, /* Empty */         0 },
+  { /* shadow-ivar */                                           7874, /* DiagArray391 */ 1175, /* Empty */         0 },
+  { /* shift-count-negative */                                  7886, /* DiagArray392 */ 1177, /* Empty */         0 },
+  { /* shift-count-overflow */                                  7907, /* DiagArray393 */ 1179, /* Empty */         0 },
+  { /* shift-op-parentheses */                                  7928, /* DiagArray394 */ 1181, /* Empty */         0 },
+  { /* shift-overflow */                                        7949, /* DiagArray395 */ 1183, /* Empty */         0 },
+  { /* shift-sign-overflow */                                   7964, /* DiagArray396 */ 1185, /* Empty */         0 },
+  { /* shorten-64-to-32 */                                      7984, /* DiagArray397 */ 1187, /* Empty */         0 },
+  { /* sign-compare */                                          8001, /* DiagArray398 */ 1189, /* Empty */         0 },
+  { /* sign-conversion */                                       8014, /* DiagArray399 */ 1191, /* Empty */         0 },
+  { /* sign-promo */                                            8030, /* Empty */     0, /* Empty */         0 },
+  { /* sizeof-array-argument */                                 8041, /* DiagArray401 */ 1194, /* Empty */         0 },
+  { /* sizeof-array-decay */                                    8063, /* DiagArray402 */ 1196, /* Empty */         0 },
+  { /* sizeof-pointer-memaccess */                              8082, /* DiagArray403 */ 1198, /* Empty */         0 },
+  { /* sometimes-uninitialized */                               8107, /* DiagArray404 */ 1201, /* Empty */         0 },
+  { /* source-uses-openmp */                                    8131, /* DiagArray405 */ 1203, /* Empty */         0 },
+  { /* stack-protector */                                       8150, /* Empty */     0, /* Empty */         0 },
+  { /* static-float-init */                                     8166, /* DiagArray407 */ 1205, /* DiagSubGroup407 */ 272 },
+  { /* static-in-inline */                                      8184, /* DiagArray408 */ 1207, /* Empty */         0 },
+  { /* static-inline-explicit-instantiation */                  8201, /* DiagArray409 */ 1210, /* Empty */         0 },
+  { /* static-local-in-inline */                                8238, /* DiagArray410 */ 1212, /* Empty */         0 },
+  { /* static-self-init */                                      8261, /* DiagArray411 */ 1214, /* Empty */         0 },
+  { /* strict-aliasing */                                       8278, /* Empty */     0, /* Empty */         0 },
+  { /* strict-aliasing=0 */                                     8294, /* Empty */     0, /* Empty */         0 },
+  { /* strict-aliasing=1 */                                     8312, /* Empty */     0, /* Empty */         0 },
+  { /* strict-aliasing=2 */                                     8330, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow */                                       8348, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=0 */                                     8364, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=1 */                                     8382, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=2 */                                     8400, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=3 */                                     8418, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=4 */                                     8436, /* Empty */     0, /* Empty */         0 },
+  { /* strict-overflow=5 */                                     8454, /* Empty */     0, /* Empty */         0 },
+  { /* strict-prototypes */                                     8472, /* Empty */     0, /* Empty */         0 },
+  { /* strict-selector-match */                                 8490, /* DiagArray424 */ 1216, /* Empty */         0 },
+  { /* string-compare */                                        8512, /* DiagArray425 */ 1218, /* Empty */         0 },
+  { /* string-conversion */                                     8527, /* DiagArray426 */ 1220, /* Empty */         0 },
+  { /* string-plus-char */                                      8545, /* DiagArray427 */ 1222, /* Empty */         0 },
+  { /* string-plus-int */                                       8562, /* DiagArray428 */ 1224, /* Empty */         0 },
+  { /* strlcpy-strlcat-size */                                  8578, /* DiagArray429 */ 1226, /* Empty */         0 },
+  { /* strncat-size */                                          8599, /* DiagArray430 */ 1228, /* Empty */         0 },
+  { /* super-class-method-mismatch */                           8612, /* DiagArray431 */ 1232, /* Empty */         0 },
+  { /* switch */                                                8640, /* DiagArray432 */ 1234, /* Empty */         0 },
+  { /* switch-bool */                                           8647, /* DiagArray433 */ 1241, /* Empty */         0 },
+  { /* switch-default */                                        8659, /* Empty */     0, /* Empty */         0 },
+  { /* switch-enum */                                           8674, /* DiagArray435 */ 1243, /* Empty */         0 },
+  { /* synth */                                                 8686, /* Empty */     0, /* Empty */         0 },
+  { /* tautological-compare */                                  8692, /* DiagArray437 */ 1248, /* DiagSubGroup437 */ 274 },
+  { /* tautological-constant-out-of-range-compare */            8713, /* DiagArray438 */ 1253, /* Empty */         0 },
+  { /* tautological-overlap-compare */                          8756, /* DiagArray439 */ 1255, /* Empty */         0 },
+  { /* tautological-pointer-compare */                          8785, /* DiagArray440 */ 1257, /* Empty */         0 },
+  { /* tautological-undefined-compare */                        8814, /* DiagArray441 */ 1259, /* Empty */         0 },
+  { /* tentative-definition-incomplete-type */                  8845, /* DiagArray442 */ 1262, /* Empty */         0 },
+  { /* thread-safety */                                         8882, /* Empty */     0, /* DiagSubGroup443 */ 279 },
+  { /* thread-safety-analysis */                                8896, /* DiagArray444 */ 1264, /* Empty */         0 },
+  { /* thread-safety-attributes */                              8919, /* DiagArray445 */ 1280, /* Empty */         0 },
+  { /* thread-safety-beta */                                    8944, /* DiagArray446 */ 1286, /* Empty */         0 },
+  { /* thread-safety-precise */                                 8963, /* DiagArray447 */ 1288, /* Empty */         0 },
+  { /* trigraphs */                                             8985, /* DiagArray448 */ 1292, /* Empty */         0 },
+  { /* type-limits */                                           8995, /* Empty */     0, /* Empty */         0 },
+  { /* type-safety */                                           9007, /* DiagArray450 */ 1297, /* Empty */         0 },
+  { /* typedef-redefinition */                                  9019, /* DiagArray451 */ 1301, /* Empty */         0 },
+  { /* typename-missing */                                      9040, /* DiagArray452 */ 1303, /* Empty */         0 },
+  { /* unavailable-declarations */                              9057, /* DiagArray453 */ 1305, /* Empty */         0 },
+  { /* undeclared-selector */                                   9082, /* DiagArray454 */ 1307, /* Empty */         0 },
+  { /* undef */                                                 9102, /* DiagArray455 */ 1310, /* Empty */         0 },
+  { /* undefined-bool-conversion */                             9108, /* DiagArray456 */ 1312, /* Empty */         0 },
+  { /* undefined-inline */                                      9134, /* DiagArray457 */ 1315, /* Empty */         0 },
+  { /* undefined-internal */                                    9151, /* DiagArray458 */ 1317, /* Empty */         0 },
+  { /* undefined-reinterpret-cast */                            9170, /* DiagArray459 */ 1319, /* Empty */         0 },
+  { /* unicode */                                               9197, /* DiagArray460 */ 1322, /* Empty */         0 },
+  { /* unicode-whitespace */                                    9205, /* DiagArray461 */ 1328, /* Empty */         0 },
+  { /* uninitialized */                                         9224, /* DiagArray462 */ 1330, /* DiagSubGroup462 */ 283 },
+  { /* unknown-attributes */                                    9238, /* DiagArray463 */ 1337, /* Empty */         0 },
+  { /* unknown-escape-sequence */                               9257, /* DiagArray464 */ 1339, /* Empty */         0 },
+  { /* unknown-pragmas */                                       9281, /* DiagArray465 */ 1341, /* Empty */         0 },
+  { /* unknown-warning-option */                                9297, /* DiagArray466 */ 1360, /* Empty */         0 },
+  { /* unnamed-type-template-args */                            9320, /* DiagArray467 */ 1363, /* DiagSubGroup467 */ 286 },
+  { /* unneeded-internal-declaration */                         9347, /* DiagArray468 */ 1365, /* Empty */         0 },
+  { /* unneeded-member-function */                              9377, /* DiagArray469 */ 1368, /* Empty */         0 },
+  { /* unreachable-code */                                      9402, /* DiagArray470 */ 1370, /* DiagSubGroup470 */ 288 },
+  { /* unreachable-code-aggressive */                           9419, /* Empty */     0, /* DiagSubGroup471 */ 290 },
+  { /* unreachable-code-break */                                9447, /* DiagArray472 */ 1372, /* Empty */         0 },
+  { /* unreachable-code-loop-increment */                       9470, /* DiagArray473 */ 1374, /* Empty */         0 },
+  { /* unreachable-code-return */                               9502, /* DiagArray474 */ 1376, /* Empty */         0 },
+  { /* unsequenced */                                           9526, /* DiagArray475 */ 1378, /* Empty */         0 },
+  { /* unsupported-dll-base-class-template */                   9538, /* DiagArray476 */ 1381, /* Empty */         0 },
+  { /* unsupported-friend */                                    9574, /* DiagArray477 */ 1383, /* Empty */         0 },
+  { /* unsupported-visibility */                                9593, /* DiagArray478 */ 1386, /* Empty */         0 },
+  { /* unused */                                                9616, /* Empty */     0, /* DiagSubGroup479 */ 294 },
+  { /* unused-argument */                                       9623, /* Empty */     0, /* Empty */         0 },
+  { /* unused-command-line-argument */                          9639, /* DiagArray481 */ 1388, /* Empty */         0 },
+  { /* unused-comparison */                                     9668, /* DiagArray482 */ 1394, /* Empty */         0 },
+  { /* unused-const-variable */                                 9686, /* DiagArray483 */ 1396, /* Empty */         0 },
+  { /* unused-exception-parameter */                            9708, /* DiagArray484 */ 1398, /* Empty */         0 },
+  { /* unused-function */                                       9735, /* DiagArray485 */ 1400, /* DiagSubGroup485 */ 302 },
+  { /* unused-label */                                          9751, /* DiagArray486 */ 1402, /* Empty */         0 },
+  { /* unused-macros */                                         9764, /* DiagArray487 */ 1404, /* Empty */         0 },
+  { /* unused-member-function */                                9778, /* DiagArray488 */ 1406, /* DiagSubGroup488 */ 304 },
+  { /* unused-parameter */                                      9801, /* DiagArray489 */ 1408, /* Empty */         0 },
+  { /* unused-private-field */                                  9818, /* DiagArray490 */ 1410, /* Empty */         0 },
+  { /* unused-property-ivar */                                  9839, /* DiagArray491 */ 1412, /* Empty */         0 },
+  { /* unused-result */                                         9860, /* DiagArray492 */ 1414, /* Empty */         0 },
+  { /* unused-value */                                          9874, /* DiagArray493 */ 1416, /* DiagSubGroup493 */ 306 },
+  { /* unused-variable */                                       9887, /* DiagArray494 */ 1422, /* DiagSubGroup494 */ 309 },
+  { /* unused-volatile-lvalue */                                9903, /* DiagArray495 */ 1424, /* Empty */         0 },
+  { /* used-but-marked-unused */                                9926, /* DiagArray496 */ 1426, /* Empty */         0 },
+  { /* user-defined-literals */                                 9949, /* DiagArray497 */ 1428, /* Empty */         0 },
+  { /* varargs */                                               9971, /* DiagArray498 */ 1430, /* Empty */         0 },
+  { /* variadic-macros */                                       9979, /* DiagArray499 */ 1434, /* Empty */         0 },
+  { /* vector-conversion */                                     9995, /* DiagArray500 */ 1437, /* Empty */         0 },
+  { /* vector-conversions */                                    10013, /* Empty */     0, /* DiagSubGroup501 */ 311 },
+  { /* vexing-parse */                                          10032, /* DiagArray502 */ 1439, /* Empty */         0 },
+  { /* visibility */                                            10045, /* DiagArray503 */ 1442, /* Empty */         0 },
+  { /* vla */                                                   10056, /* DiagArray504 */ 1445, /* Empty */         0 },
+  { /* vla-extension */                                         10060, /* DiagArray505 */ 1447, /* Empty */         0 },
+  { /* void-ptr-dereference */                                  10074, /* DiagArray506 */ 1449, /* Empty */         0 },
+  { /* volatile-register-var */                                 10095, /* Empty */     0, /* Empty */         0 },
+  { /* weak-template-vtables */                                 10117, /* DiagArray508 */ 1451, /* Empty */         0 },
+  { /* weak-vtables */                                          10139, /* DiagArray509 */ 1453, /* Empty */         0 },
+  { /* writable-strings */                                      10152, /* DiagArray510 */ 1455, /* DiagSubGroup510 */ 313 },
+  { /* write-strings */                                         10169, /* Empty */     0, /* DiagSubGroup511 */ 315 },
+  { /* zero-length-array */                                     10183, /* DiagArray512 */ 1457, /* Empty */         0 },
+#endif // GET_DIAG_TABLE
+
+
+#ifdef GET_CATEGORY_TABLE
+CATEGORY("", DiagCat_None)
+CATEGORY("Lexical or Preprocessor Issue", DiagCat_Lexical_or_Preprocessor_Issue)
+CATEGORY("Semantic Issue", DiagCat_Semantic_Issue)
+CATEGORY("Lambda Issue", DiagCat_Lambda_Issue)
+CATEGORY("Parse Issue", DiagCat_Parse_Issue)
+CATEGORY("ARC Semantic Issue", DiagCat_ARC_Semantic_Issue)
+CATEGORY("ARC and @properties", DiagCat_ARC_and__properties)
+CATEGORY("ARC Casting Rules", DiagCat_ARC_Casting_Rules)
+CATEGORY("ARC Parse Issue", DiagCat_ARC_Parse_Issue)
+CATEGORY("ARC Weak References", DiagCat_ARC_Weak_References)
+CATEGORY("ARC Restrictions", DiagCat_ARC_Restrictions)
+CATEGORY("Inline Assembly Issue", DiagCat_Inline_Assembly_Issue)
+CATEGORY("Backend Issue", DiagCat_Backend_Issue)
+CATEGORY("AST Deserialization Issue", DiagCat_AST_Deserialization_Issue)
+CATEGORY("Modules Issue", DiagCat_Modules_Issue)
+CATEGORY("OpenMP Issue", DiagCat_OpenMP_Issue)
+CATEGORY("User-Defined Issue", DiagCat_User_Defined_Issue)
+CATEGORY("Value Conversion Issue", DiagCat_Value_Conversion_Issue)
+CATEGORY("Documentation Issue", DiagCat_Documentation_Issue)
+CATEGORY("ARC Retain Cycle", DiagCat_ARC_Retain_Cycle)
+CATEGORY("Related Result Type Issue", DiagCat_Related_Result_Type_Issue)
+CATEGORY("Deprecations", DiagCat_Deprecations)
+CATEGORY("Format String Issue", DiagCat_Format_String_Issue)
+CATEGORY("Cocoa API Issue", DiagCat_Cocoa_API_Issue)
+CATEGORY("#pragma message Directive", DiagCat__pragma_message_Directive)
+CATEGORY("Instrumentation Issue", DiagCat_Instrumentation_Issue)
+CATEGORY("Unused Entity Issue", DiagCat_Unused_Entity_Issue)
+#endif // GET_CATEGORY_TABLE
+
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
new file mode 100644
index 0000000..bfb0f0d
--- /dev/null
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -0,0 +1,287 @@
+//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the Diagnostic IDs-related interfaces.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICIDS_H
+#define LLVM_CLANG_DIAGNOSTICIDS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+  class DiagnosticsEngine;
+  class SourceLocation;
+
+  // Import the diagnostic enums themselves.
+  namespace diag {
+    // Start position for diagnostics.
+    enum {
+      DIAG_START_COMMON        =                                 0,
+      DIAG_START_DRIVER        = DIAG_START_COMMON          +  300,
+      DIAG_START_FRONTEND      = DIAG_START_DRIVER          +  100,
+      DIAG_START_SERIALIZATION = DIAG_START_FRONTEND        +  100,
+      DIAG_START_LEX           = DIAG_START_SERIALIZATION   +  120,
+      DIAG_START_PARSE         = DIAG_START_LEX             +  300,
+      DIAG_START_AST           = DIAG_START_PARSE           +  400,
+      DIAG_START_COMMENT       = DIAG_START_AST             +  100,
+      DIAG_START_SEMA          = DIAG_START_COMMENT         +  100,
+      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 3000,
+      DIAG_UPPER_LIMIT         = DIAG_START_ANALYSIS        +  100
+    };
+
+    class CustomDiagInfo;
+
+    /// \brief All of the diagnostics that can be emitted by the frontend.
+    typedef unsigned kind;
+
+    // Get typedefs for common diagnostics.
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,CATEGORY,NOWERROR,SHOWINSYSHEADER) ENUM,
+#define COMMONSTART
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+      NUM_BUILTIN_COMMON_DIAGNOSTICS
+#undef DIAG
+    };
+
+    /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
+    /// to either Ignore (nothing), Remark (emit a remark), Warning
+    /// (emit a warning) or Error (emit as an error).  It allows clients to
+    /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
+    enum class Severity {
+      // NOTE: 0 means "uncomputed".
+      Ignored = 1, ///< Do not present this diagnostic, ignore it.
+      Remark = 2,  ///< Present this diagnostic as a remark.
+      Warning = 3, ///< Present this diagnostic as a warning.
+      Error = 4,   ///< Present this diagnostic as an error.
+      Fatal = 5    ///< Present this diagnostic as a fatal error.
+    };
+
+    /// Flavors of diagnostics we can emit. Used to filter for a particular
+    /// kind of diagnostic (for instance, for -W/-R flags).
+    enum class Flavor {
+      WarningOrError, ///< A diagnostic that indicates a problem or potential
+                      ///< problem. Can be made fatal by -Werror.
+      Remark          ///< A diagnostic that indicates normal progress through
+                      ///< compilation.
+    };
+  }
+
+class DiagnosticMapping {
+  unsigned Severity : 3;
+  unsigned IsUser : 1;
+  unsigned IsPragma : 1;
+  unsigned HasNoWarningAsError : 1;
+  unsigned HasNoErrorAsFatal : 1;
+
+public:
+  static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
+                                bool IsPragma) {
+    DiagnosticMapping Result;
+    Result.Severity = (unsigned)Severity;
+    Result.IsUser = IsUser;
+    Result.IsPragma = IsPragma;
+    Result.HasNoWarningAsError = 0;
+    Result.HasNoErrorAsFatal = 0;
+    return Result;
+  }
+
+  diag::Severity getSeverity() const { return (diag::Severity)Severity; }
+  void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; }
+
+  bool isUser() const { return IsUser; }
+  bool isPragma() const { return IsPragma; }
+
+  bool hasNoWarningAsError() const { return HasNoWarningAsError; }
+  void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
+
+  bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; }
+  void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; }
+};
+
+/// \brief Used for handling and querying diagnostic IDs.
+///
+/// Can be used and shared by multiple Diagnostics for multiple translation units.
+class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
+public:
+  /// \brief The level of the diagnostic, after it has been through mapping.
+  enum Level {
+    Ignored, Note, Remark, Warning, Error, Fatal
+  };
+
+private:
+  /// \brief Information for uniquing and looking up custom diags.
+  diag::CustomDiagInfo *CustomDiagInfo;
+
+public:
+  DiagnosticIDs();
+  ~DiagnosticIDs();
+
+  /// \brief Return an ID for a diagnostic with the specified format string and
+  /// level.
+  ///
+  /// If this is the first request for this diagnostic, it is registered and
+  /// created, otherwise the existing ID is returned.
+
+  // FIXME: Replace this function with a create-only facilty like
+  // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
+  // writing, nearly all callers of this function were invalid.
+  unsigned getCustomDiagID(Level L, StringRef FormatString);
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic classification and reporting interfaces.
+  //
+
+  /// \brief Given a diagnostic ID, return a description of the issue.
+  StringRef getDescription(unsigned DiagID) const;
+
+  /// \brief Return true if the unmapped diagnostic levelof the specified
+  /// diagnostic ID is a Warning or Extension.
+  ///
+  /// This only works on builtin diagnostics, not custom ones, and is not
+  /// legal to call on NOTEs.
+  static bool isBuiltinWarningOrExtension(unsigned DiagID);
+
+  /// \brief Return true if the specified diagnostic is mapped to errors by
+  /// default.
+  static bool isDefaultMappingAsError(unsigned DiagID);
+
+  /// \brief Determine whether the given built-in diagnostic ID is a Note.
+  static bool isBuiltinNote(unsigned DiagID);
+
+  /// \brief Determine whether the given built-in diagnostic ID is for an
+  /// extension of some sort.
+  static bool isBuiltinExtensionDiag(unsigned DiagID) {
+    bool ignored;
+    return isBuiltinExtensionDiag(DiagID, ignored);
+  }
+  
+  /// \brief Determine whether the given built-in diagnostic ID is for an
+  /// extension of some sort, and whether it is enabled by default.
+  ///
+  /// This also returns EnabledByDefault, which is set to indicate whether the
+  /// diagnostic is ignored by default (in which case -pedantic enables it) or
+  /// treated as a warning/error by default.
+  ///
+  static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+  
+
+  /// \brief Return the lowest-level warning option that enables the specified
+  /// diagnostic.
+  ///
+  /// If there is no -Wfoo flag that controls the diagnostic, this returns null.
+  static StringRef getWarningOptionForDiag(unsigned DiagID);
+  
+  /// \brief Return the category number that a specified \p DiagID belongs to,
+  /// or 0 if no category.
+  static unsigned getCategoryNumberForDiag(unsigned DiagID);
+
+  /// \brief Return the number of diagnostic categories.
+  static unsigned getNumberOfCategories();
+
+  /// \brief Given a category ID, return the name of the category.
+  static StringRef getCategoryNameFromID(unsigned CategoryID);
+  
+  /// \brief Return true if a given diagnostic falls into an ARC diagnostic
+  /// category.
+  static bool isARCDiagnostic(unsigned DiagID);
+
+  /// \brief Enumeration describing how the emission of a diagnostic should
+  /// be treated when it occurs during C++ template argument deduction.
+  enum SFINAEResponse {
+    /// \brief The diagnostic should not be reported, but it should cause
+    /// template argument deduction to fail.
+    ///
+    /// The vast majority of errors that occur during template argument 
+    /// deduction fall into this category.
+    SFINAE_SubstitutionFailure,
+    
+    /// \brief The diagnostic should be suppressed entirely.
+    ///
+    /// Warnings generally fall into this category.
+    SFINAE_Suppress,
+    
+    /// \brief The diagnostic should be reported.
+    ///
+    /// The diagnostic should be reported. Various fatal errors (e.g., 
+    /// template instantiation depth exceeded) fall into this category.
+    SFINAE_Report,
+    
+    /// \brief The diagnostic is an access-control diagnostic, which will be
+    /// substitution failures in some contexts and reported in others.
+    SFINAE_AccessControl
+  };
+  
+  /// \brief Determines whether the given built-in diagnostic ID is
+  /// for an error that is suppressed if it occurs during C++ template
+  /// argument deduction.
+  ///
+  /// When an error is suppressed due to SFINAE, the template argument
+  /// deduction fails but no diagnostic is emitted. Certain classes of
+  /// errors, such as those errors that involve C++ access control,
+  /// are not SFINAE errors.
+  static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
+
+  /// \brief Get the set of all diagnostic IDs in the group with the given name.
+  ///
+  /// \param[out] Diags - On return, the diagnostics in the group.
+  /// \returns \c true if the given group is unknown, \c false otherwise.
+  bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
+                             SmallVectorImpl<diag::kind> &Diags) const;
+
+  /// \brief Get the set of all diagnostic IDs.
+  void getAllDiagnostics(diag::Flavor Flavor,
+                         SmallVectorImpl<diag::kind> &Diags) const;
+
+  /// \brief Get the diagnostic option with the closest edit distance to the
+  /// given group name.
+  static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group);
+
+private:
+  /// \brief Classify the specified diagnostic ID into a Level, consumable by
+  /// the DiagnosticClient.
+  /// 
+  /// The classification is based on the way the client configured the
+  /// DiagnosticsEngine object.
+  ///
+  /// \param Loc The source location for which we are interested in finding out
+  /// the diagnostic state. Can be null in order to query the latest state.
+  DiagnosticIDs::Level
+  getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
+                     const DiagnosticsEngine &Diag) const LLVM_READONLY;
+
+  diag::Severity
+  getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+                        const DiagnosticsEngine &Diag) const LLVM_READONLY;
+
+  /// \brief Used to report a diagnostic that is finally fully formed.
+  ///
+  /// \returns \c true if the diagnostic was emitted, \c false if it was
+  /// suppressed.
+  bool ProcessDiag(DiagnosticsEngine &Diag) const;
+
+  /// \brief Used to emit a diagnostic that is finally fully formed,
+  /// ignoring suppression.
+  void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const;
+
+  /// \brief Whether the diagnostic may leave the AST in a state where some
+  /// invariants can break.
+  bool isUnrecoverable(unsigned DiagID) const;
+
+  friend class DiagnosticsEngine;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticIndexName.inc b/include/clang/Basic/DiagnosticIndexName.inc
new file mode 100644
index 0000000..efb409b
--- /dev/null
+++ b/include/clang/Basic/DiagnosticIndexName.inc
@@ -0,0 +1,3631 @@
+DIAG_NAME_INDEX(backslash_newline_space)
+DIAG_NAME_INDEX(err__Pragma_malformed)
+DIAG_NAME_INDEX(err_abstract_type_in_decl)
+DIAG_NAME_INDEX(err_access)
+DIAG_NAME_INDEX(err_access_base_ctor)
+DIAG_NAME_INDEX(err_access_ctor)
+DIAG_NAME_INDEX(err_access_decl)
+DIAG_NAME_INDEX(err_access_dtor)
+DIAG_NAME_INDEX(err_access_dtor_base)
+DIAG_NAME_INDEX(err_access_dtor_exception)
+DIAG_NAME_INDEX(err_access_dtor_field)
+DIAG_NAME_INDEX(err_access_dtor_ivar)
+DIAG_NAME_INDEX(err_access_dtor_temp)
+DIAG_NAME_INDEX(err_access_dtor_var)
+DIAG_NAME_INDEX(err_access_dtor_vbase)
+DIAG_NAME_INDEX(err_access_field_ctor)
+DIAG_NAME_INDEX(err_access_friend_function)
+DIAG_NAME_INDEX(err_access_lambda_capture)
+DIAG_NAME_INDEX(err_access_specifier_interface)
+DIAG_NAME_INDEX(err_addr_ovl_ambiguous)
+DIAG_NAME_INDEX(err_addr_ovl_no_qualifier)
+DIAG_NAME_INDEX(err_addr_ovl_no_viable)
+DIAG_NAME_INDEX(err_addr_ovl_not_func_ptrref)
+DIAG_NAME_INDEX(err_address_of_label_outside_fn)
+DIAG_NAME_INDEX(err_address_space_qualified_delete)
+DIAG_NAME_INDEX(err_address_space_qualified_new)
+DIAG_NAME_INDEX(err_alias_after_tentative)
+DIAG_NAME_INDEX(err_alias_declaration_not_identifier)
+DIAG_NAME_INDEX(err_alias_declaration_specialization)
+DIAG_NAME_INDEX(err_alias_not_supported_on_darwin)
+DIAG_NAME_INDEX(err_alias_template_expansion_into_fixed_list)
+DIAG_NAME_INDEX(err_alias_template_extra_headers)
+DIAG_NAME_INDEX(err_alias_to_undefined)
+DIAG_NAME_INDEX(err_alignas_attribute_wrong_decl_type)
+DIAG_NAME_INDEX(err_alignas_mismatch)
+DIAG_NAME_INDEX(err_alignas_missing_on_definition)
+DIAG_NAME_INDEX(err_alignas_underaligned)
+DIAG_NAME_INDEX(err_aligned_attribute_argument_not_int)
+DIAG_NAME_INDEX(err_alignof_member_of_incomplete_type)
+DIAG_NAME_INDEX(err_allocation_of_abstract_type)
+DIAG_NAME_INDEX(err_altivec_empty_initializer)
+DIAG_NAME_INDEX(err_ambiguous_base_to_derived_cast)
+DIAG_NAME_INDEX(err_ambiguous_delete_operand)
+DIAG_NAME_INDEX(err_ambiguous_derived_to_base_conv)
+DIAG_NAME_INDEX(err_ambiguous_member_multiple_subobject_types)
+DIAG_NAME_INDEX(err_ambiguous_member_multiple_subobjects)
+DIAG_NAME_INDEX(err_ambiguous_memptr_conv)
+DIAG_NAME_INDEX(err_ambiguous_reference)
+DIAG_NAME_INDEX(err_ambiguous_suitable_delete_member_function_found)
+DIAG_NAME_INDEX(err_ambiguous_tag_hiding)
+DIAG_NAME_INDEX(err_analyzer_config_multiple_values)
+DIAG_NAME_INDEX(err_analyzer_config_no_value)
+DIAG_NAME_INDEX(err_anon_bitfield_has_negative_width)
+DIAG_NAME_INDEX(err_anon_bitfield_width_exceeds_type_size)
+DIAG_NAME_INDEX(err_anon_type_definition)
+DIAG_NAME_INDEX(err_anonymous_property)
+DIAG_NAME_INDEX(err_anonymous_record_bad_member)
+DIAG_NAME_INDEX(err_anonymous_record_nonpublic_member)
+DIAG_NAME_INDEX(err_anonymous_record_with_function)
+DIAG_NAME_INDEX(err_anonymous_record_with_static)
+DIAG_NAME_INDEX(err_anonymous_record_with_type)
+DIAG_NAME_INDEX(err_anonymous_struct_member_redecl)
+DIAG_NAME_INDEX(err_anonymous_struct_not_member)
+DIAG_NAME_INDEX(err_anonymous_union_member_redecl)
+DIAG_NAME_INDEX(err_anonymous_union_not_static)
+DIAG_NAME_INDEX(err_anonymous_union_with_storage_spec)
+DIAG_NAME_INDEX(err_arc_array_param_no_ownership)
+DIAG_NAME_INDEX(err_arc_assign_property_ownership)
+DIAG_NAME_INDEX(err_arc_atomic_ownership)
+DIAG_NAME_INDEX(err_arc_autoreleasing_capture)
+DIAG_NAME_INDEX(err_arc_autoreleasing_var)
+DIAG_NAME_INDEX(err_arc_bridge_cast_incompatible)
+DIAG_NAME_INDEX(err_arc_bridge_cast_wrong_kind)
+DIAG_NAME_INDEX(err_arc_bridge_retain)
+DIAG_NAME_INDEX(err_arc_cast_requires_bridge)
+DIAG_NAME_INDEX(err_arc_collection_forward)
+DIAG_NAME_INDEX(err_arc_convesion_of_weak_unavailable)
+DIAG_NAME_INDEX(err_arc_gained_method_convention)
+DIAG_NAME_INDEX(err_arc_illegal_explicit_message)
+DIAG_NAME_INDEX(err_arc_illegal_method_def)
+DIAG_NAME_INDEX(err_arc_illegal_selector)
+DIAG_NAME_INDEX(err_arc_inconsistent_property_ownership)
+DIAG_NAME_INDEX(err_arc_indirect_no_ownership)
+DIAG_NAME_INDEX(err_arc_init_method_unrelated_result_type)
+DIAG_NAME_INDEX(err_arc_lost_method_convention)
+DIAG_NAME_INDEX(err_arc_may_not_respond)
+DIAG_NAME_INDEX(err_arc_method_not_found)
+DIAG_NAME_INDEX(err_arc_mismatched_cast)
+DIAG_NAME_INDEX(err_arc_multiple_method_decl)
+DIAG_NAME_INDEX(err_arc_new_array_without_ownership)
+DIAG_NAME_INDEX(err_arc_nolifetime_behavior)
+DIAG_NAME_INDEX(err_arc_nonlocal_writeback)
+DIAG_NAME_INDEX(err_arc_objc_object_in_tag)
+DIAG_NAME_INDEX(err_arc_objc_property_default_assign_on_object)
+DIAG_NAME_INDEX(err_arc_perform_selector_retains)
+DIAG_NAME_INDEX(err_arc_pseudo_dtor_inconstant_quals)
+DIAG_NAME_INDEX(err_arc_receiver_forward_class)
+DIAG_NAME_INDEX(err_arc_receiver_forward_instance)
+DIAG_NAME_INDEX(err_arc_strong_property_ownership)
+DIAG_NAME_INDEX(err_arc_thread_ownership)
+DIAG_NAME_INDEX(err_arc_typecheck_convert_incompatible_pointer)
+DIAG_NAME_INDEX(err_arc_unsupported_on_runtime)
+DIAG_NAME_INDEX(err_arc_unsupported_on_toolchain)
+DIAG_NAME_INDEX(err_arc_unsupported_weak_class)
+DIAG_NAME_INDEX(err_arc_unused_init_message)
+DIAG_NAME_INDEX(err_arc_weak_no_runtime)
+DIAG_NAME_INDEX(err_arc_weak_unavailable_assign)
+DIAG_NAME_INDEX(err_arc_weak_unavailable_property)
+DIAG_NAME_INDEX(err_arcmt_nsinvocation_ownership)
+DIAG_NAME_INDEX(err_arg_with_address_space)
+DIAG_NAME_INDEX(err_argument_invalid_range)
+DIAG_NAME_INDEX(err_argument_required_after_attribute)
+DIAG_NAME_INDEX(err_arithmetic_nonfragile_interface)
+DIAG_NAME_INDEX(err_array_designator_empty_range)
+DIAG_NAME_INDEX(err_array_designator_negative)
+DIAG_NAME_INDEX(err_array_designator_non_array)
+DIAG_NAME_INDEX(err_array_designator_too_large)
+DIAG_NAME_INDEX(err_array_init_different_type)
+DIAG_NAME_INDEX(err_array_init_incompat_wide_string_into_wchar)
+DIAG_NAME_INDEX(err_array_init_narrow_string_into_wchar)
+DIAG_NAME_INDEX(err_array_init_non_constant_array)
+DIAG_NAME_INDEX(err_array_init_not_init_list)
+DIAG_NAME_INDEX(err_array_init_wide_string_into_char)
+DIAG_NAME_INDEX(err_array_new_needs_size)
+DIAG_NAME_INDEX(err_array_of_abstract_type)
+DIAG_NAME_INDEX(err_array_size_ambiguous_conversion)
+DIAG_NAME_INDEX(err_array_size_explicit_conversion)
+DIAG_NAME_INDEX(err_array_size_incomplete_type)
+DIAG_NAME_INDEX(err_array_size_non_int)
+DIAG_NAME_INDEX(err_array_size_not_integral)
+DIAG_NAME_INDEX(err_array_star_in_function_definition)
+DIAG_NAME_INDEX(err_array_star_outside_prototype)
+DIAG_NAME_INDEX(err_array_static_not_outermost)
+DIAG_NAME_INDEX(err_array_static_outside_prototype)
+DIAG_NAME_INDEX(err_array_too_large)
+DIAG_NAME_INDEX(err_as_qualified_auto_decl)
+DIAG_NAME_INDEX(err_asm_bad_register_type)
+DIAG_NAME_INDEX(err_asm_empty)
+DIAG_NAME_INDEX(err_asm_empty_symbolic_operand_name)
+DIAG_NAME_INDEX(err_asm_incomplete_type)
+DIAG_NAME_INDEX(err_asm_invalid_escape)
+DIAG_NAME_INDEX(err_asm_invalid_input_constraint)
+DIAG_NAME_INDEX(err_asm_invalid_input_size)
+DIAG_NAME_INDEX(err_asm_invalid_lvalue_in_input)
+DIAG_NAME_INDEX(err_asm_invalid_lvalue_in_output)
+DIAG_NAME_INDEX(err_asm_invalid_operand_number)
+DIAG_NAME_INDEX(err_asm_invalid_output_constraint)
+DIAG_NAME_INDEX(err_asm_invalid_type_in_input)
+DIAG_NAME_INDEX(err_asm_operand_wide_string_literal)
+DIAG_NAME_INDEX(err_asm_tying_incompatible_types)
+DIAG_NAME_INDEX(err_asm_unknown_register_name)
+DIAG_NAME_INDEX(err_asm_unknown_symbolic_operand_name)
+DIAG_NAME_INDEX(err_asm_unterminated_symbolic_operand_name)
+DIAG_NAME_INDEX(err_asm_wide_character)
+DIAG_NAME_INDEX(err_assoc_compatible_types)
+DIAG_NAME_INDEX(err_assoc_type_incomplete)
+DIAG_NAME_INDEX(err_assoc_type_nonobject)
+DIAG_NAME_INDEX(err_assoc_type_variably_modified)
+DIAG_NAME_INDEX(err_at_defs_cxx)
+DIAG_NAME_INDEX(err_at_in_class)
+DIAG_NAME_INDEX(err_atdef_nonfragile_interface)
+DIAG_NAME_INDEX(err_atimport)
+DIAG_NAME_INDEX(err_atomic_builtin_must_be_pointer)
+DIAG_NAME_INDEX(err_atomic_builtin_must_be_pointer_intfltptr)
+DIAG_NAME_INDEX(err_atomic_builtin_must_be_pointer_intptr)
+DIAG_NAME_INDEX(err_atomic_builtin_pointer_size)
+DIAG_NAME_INDEX(err_atomic_exclusive_builtin_pointer_size)
+DIAG_NAME_INDEX(err_atomic_load_store_uses_lib)
+DIAG_NAME_INDEX(err_atomic_op_bitwise_needs_atomic_int)
+DIAG_NAME_INDEX(err_atomic_op_needs_atomic)
+DIAG_NAME_INDEX(err_atomic_op_needs_atomic_int_or_ptr)
+DIAG_NAME_INDEX(err_atomic_op_needs_non_const_atomic)
+DIAG_NAME_INDEX(err_atomic_op_needs_trivial_copy)
+DIAG_NAME_INDEX(err_atomic_property_nontrivial_assign_op)
+DIAG_NAME_INDEX(err_atomic_specifier_bad_type)
+DIAG_NAME_INDEX(err_attr_objc_ownership_redundant)
+DIAG_NAME_INDEX(err_attr_tlsmodel_arg)
+DIAG_NAME_INDEX(err_attr_wrong_decl)
+DIAG_NAME_INDEX(err_attribute_address_function_type)
+DIAG_NAME_INDEX(err_attribute_address_multiple_qualifiers)
+DIAG_NAME_INDEX(err_attribute_address_space_negative)
+DIAG_NAME_INDEX(err_attribute_address_space_too_high)
+DIAG_NAME_INDEX(err_attribute_aligned_not_power_of_two)
+DIAG_NAME_INDEX(err_attribute_aligned_too_great)
+DIAG_NAME_INDEX(err_attribute_argument_is_zero)
+DIAG_NAME_INDEX(err_attribute_argument_n_type)
+DIAG_NAME_INDEX(err_attribute_argument_out_of_bounds)
+DIAG_NAME_INDEX(err_attribute_argument_out_of_range)
+DIAG_NAME_INDEX(err_attribute_argument_outof_range)
+DIAG_NAME_INDEX(err_attribute_argument_type)
+DIAG_NAME_INDEX(err_attribute_argument_vec_type_hint)
+DIAG_NAME_INDEX(err_attribute_bad_neon_vector_size)
+DIAG_NAME_INDEX(err_attribute_cleanup_arg_not_function)
+DIAG_NAME_INDEX(err_attribute_cleanup_func_arg_incompatible_type)
+DIAG_NAME_INDEX(err_attribute_cleanup_func_must_take_one_arg)
+DIAG_NAME_INDEX(err_attribute_dll_deleted)
+DIAG_NAME_INDEX(err_attribute_dll_member_of_dll_class)
+DIAG_NAME_INDEX(err_attribute_dll_not_extern)
+DIAG_NAME_INDEX(err_attribute_dll_redeclaration)
+DIAG_NAME_INDEX(err_attribute_dllimport_data_definition)
+DIAG_NAME_INDEX(err_attribute_dllimport_function_definition)
+DIAG_NAME_INDEX(err_attribute_dllimport_static_field_definition)
+DIAG_NAME_INDEX(err_attribute_invalid_implicit_this_argument)
+DIAG_NAME_INDEX(err_attribute_invalid_on_stmt)
+DIAG_NAME_INDEX(err_attribute_invalid_size)
+DIAG_NAME_INDEX(err_attribute_invalid_vector_type)
+DIAG_NAME_INDEX(err_attribute_multiple_objc_gc)
+DIAG_NAME_INDEX(err_attribute_no_member_pointers)
+DIAG_NAME_INDEX(err_attribute_not_supported_in_lang)
+DIAG_NAME_INDEX(err_attribute_not_type_attr)
+DIAG_NAME_INDEX(err_attribute_overloadable_missing)
+DIAG_NAME_INDEX(err_attribute_overloadable_no_prototype)
+DIAG_NAME_INDEX(err_attribute_pointers_only)
+DIAG_NAME_INDEX(err_attribute_regparm_invalid_number)
+DIAG_NAME_INDEX(err_attribute_regparm_wrong_platform)
+DIAG_NAME_INDEX(err_attribute_requires_arguments)
+DIAG_NAME_INDEX(err_attribute_section_invalid_for_target)
+DIAG_NAME_INDEX(err_attribute_selectany_non_extern_data)
+DIAG_NAME_INDEX(err_attribute_sentinel_less_than_zero)
+DIAG_NAME_INDEX(err_attribute_sentinel_not_zero_or_one)
+DIAG_NAME_INDEX(err_attribute_size_too_large)
+DIAG_NAME_INDEX(err_attribute_too_few_arguments)
+DIAG_NAME_INDEX(err_attribute_too_many_arguments)
+DIAG_NAME_INDEX(err_attribute_unsupported)
+DIAG_NAME_INDEX(err_attribute_uuid_malformed_guid)
+DIAG_NAME_INDEX(err_attribute_vecreturn_only_pod_record)
+DIAG_NAME_INDEX(err_attribute_vecreturn_only_vector_member)
+DIAG_NAME_INDEX(err_attribute_weak_static)
+DIAG_NAME_INDEX(err_attribute_weakref_not_global_context)
+DIAG_NAME_INDEX(err_attribute_weakref_not_static)
+DIAG_NAME_INDEX(err_attribute_weakref_without_alias)
+DIAG_NAME_INDEX(err_attribute_wrong_decl_type)
+DIAG_NAME_INDEX(err_attribute_wrong_number_arguments)
+DIAG_NAME_INDEX(err_attribute_zero_size)
+DIAG_NAME_INDEX(err_attributes_are_not_compatible)
+DIAG_NAME_INDEX(err_attributes_not_allowed)
+DIAG_NAME_INDEX(err_auto_different_deductions)
+DIAG_NAME_INDEX(err_auto_fn_deduction_failure)
+DIAG_NAME_INDEX(err_auto_fn_different_deductions)
+DIAG_NAME_INDEX(err_auto_fn_no_return_but_not_auto)
+DIAG_NAME_INDEX(err_auto_fn_return_init_list)
+DIAG_NAME_INDEX(err_auto_fn_return_void_but_not_auto)
+DIAG_NAME_INDEX(err_auto_fn_used_before_defined)
+DIAG_NAME_INDEX(err_auto_fn_virtual)
+DIAG_NAME_INDEX(err_auto_missing_trailing_return)
+DIAG_NAME_INDEX(err_auto_new_ctor_multiple_expressions)
+DIAG_NAME_INDEX(err_auto_new_deduction_failure)
+DIAG_NAME_INDEX(err_auto_new_list_init)
+DIAG_NAME_INDEX(err_auto_new_requires_ctor_arg)
+DIAG_NAME_INDEX(err_auto_not_allowed)
+DIAG_NAME_INDEX(err_auto_not_allowed_var_inst)
+DIAG_NAME_INDEX(err_auto_var_deduction_failure)
+DIAG_NAME_INDEX(err_auto_var_deduction_failure_from_init_list)
+DIAG_NAME_INDEX(err_auto_var_init_multiple_expressions)
+DIAG_NAME_INDEX(err_auto_var_init_no_expression)
+DIAG_NAME_INDEX(err_auto_var_init_paren_braces)
+DIAG_NAME_INDEX(err_auto_var_requires_init)
+DIAG_NAME_INDEX(err_auto_variable_cannot_appear_in_own_initializer)
+DIAG_NAME_INDEX(err_availability_expected_change)
+DIAG_NAME_INDEX(err_availability_expected_platform)
+DIAG_NAME_INDEX(err_availability_redundant)
+DIAG_NAME_INDEX(err_availability_unknown_change)
+DIAG_NAME_INDEX(err_bad_character_encoding)
+DIAG_NAME_INDEX(err_bad_const_cast_dest)
+DIAG_NAME_INDEX(err_bad_cstyle_cast_overload)
+DIAG_NAME_INDEX(err_bad_cxx_cast_bitfield)
+DIAG_NAME_INDEX(err_bad_cxx_cast_generic)
+DIAG_NAME_INDEX(err_bad_cxx_cast_member_pointer_size)
+DIAG_NAME_INDEX(err_bad_cxx_cast_qualifiers_away)
+DIAG_NAME_INDEX(err_bad_cxx_cast_rvalue)
+DIAG_NAME_INDEX(err_bad_cxx_cast_scalar_to_vector_different_size)
+DIAG_NAME_INDEX(err_bad_cxx_cast_vector_to_scalar_different_size)
+DIAG_NAME_INDEX(err_bad_cxx_cast_vector_to_vector_different_size)
+DIAG_NAME_INDEX(err_bad_dynamic_cast_incomplete)
+DIAG_NAME_INDEX(err_bad_dynamic_cast_not_class)
+DIAG_NAME_INDEX(err_bad_dynamic_cast_not_polymorphic)
+DIAG_NAME_INDEX(err_bad_dynamic_cast_not_ptr)
+DIAG_NAME_INDEX(err_bad_dynamic_cast_not_ref_or_ptr)
+DIAG_NAME_INDEX(err_bad_kernel_param_type)
+DIAG_NAME_INDEX(err_bad_lvalue_to_rvalue_cast)
+DIAG_NAME_INDEX(err_bad_memptr_lhs)
+DIAG_NAME_INDEX(err_bad_memptr_rhs)
+DIAG_NAME_INDEX(err_bad_new_type)
+DIAG_NAME_INDEX(err_bad_parameter_name)
+DIAG_NAME_INDEX(err_bad_receiver_type)
+DIAG_NAME_INDEX(err_bad_reinterpret_cast_overload)
+DIAG_NAME_INDEX(err_bad_reinterpret_cast_reference)
+DIAG_NAME_INDEX(err_bad_reinterpret_cast_small_int)
+DIAG_NAME_INDEX(err_bad_static_cast_member_pointer_nonmp)
+DIAG_NAME_INDEX(err_bad_static_cast_overload)
+DIAG_NAME_INDEX(err_bad_static_cast_pointer_nonpointer)
+DIAG_NAME_INDEX(err_bad_string_encoding)
+DIAG_NAME_INDEX(err_bad_variable_name)
+DIAG_NAME_INDEX(err_base_class_has_flexible_array_member)
+DIAG_NAME_INDEX(err_base_clause_on_union)
+DIAG_NAME_INDEX(err_base_init_direct_and_virtual)
+DIAG_NAME_INDEX(err_base_init_does_not_name_class)
+DIAG_NAME_INDEX(err_base_must_be_class)
+DIAG_NAME_INDEX(err_base_specifier_attribute)
+DIAG_NAME_INDEX(err_bitfield_has_negative_width)
+DIAG_NAME_INDEX(err_bitfield_has_zero_width)
+DIAG_NAME_INDEX(err_bitfield_member_init)
+DIAG_NAME_INDEX(err_bitfield_width_exceeds_type_size)
+DIAG_NAME_INDEX(err_block_decl_ref_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_block_extern_cant_init)
+DIAG_NAME_INDEX(err_block_on_nonlocal)
+DIAG_NAME_INDEX(err_block_on_vm)
+DIAG_NAME_INDEX(err_block_return_missing_expr)
+DIAG_NAME_INDEX(err_block_returning_array_function)
+DIAG_NAME_INDEX(err_blocks_disable)
+DIAG_NAME_INDEX(err_bool_redeclaration)
+DIAG_NAME_INDEX(err_bound_member_function)
+DIAG_NAME_INDEX(err_box_literal_collection)
+DIAG_NAME_INDEX(err_bracket_depth_exceeded)
+DIAG_NAME_INDEX(err_brackets_go_after_unqualified_id)
+DIAG_NAME_INDEX(err_break_not_in_loop_or_switch)
+DIAG_NAME_INDEX(err_builtin_annotation_first_arg)
+DIAG_NAME_INDEX(err_builtin_annotation_second_arg)
+DIAG_NAME_INDEX(err_builtin_definition)
+DIAG_NAME_INDEX(err_builtin_fn_use)
+DIAG_NAME_INDEX(err_builtin_func_cast_more_than_one_arg)
+DIAG_NAME_INDEX(err_builtin_longjmp_invalid_val)
+DIAG_NAME_INDEX(err_builtin_requires_language)
+DIAG_NAME_INDEX(err_c99_array_usage_cxx)
+DIAG_NAME_INDEX(err_call_function_incomplete_return)
+DIAG_NAME_INDEX(err_call_incomplete_argument)
+DIAG_NAME_INDEX(err_call_incomplete_return)
+DIAG_NAME_INDEX(err_cannot_form_pointer_to_member_of_reference_type)
+DIAG_NAME_INDEX(err_cannot_open_file)
+DIAG_NAME_INDEX(err_cannot_pass_objc_interface_to_vararg)
+DIAG_NAME_INDEX(err_cannot_pass_objc_interface_to_vararg_format)
+DIAG_NAME_INDEX(err_cannot_pass_to_vararg)
+DIAG_NAME_INDEX(err_cannot_pass_to_vararg_format)
+DIAG_NAME_INDEX(err_capture_block_variable)
+DIAG_NAME_INDEX(err_capture_default_non_local)
+DIAG_NAME_INDEX(err_capture_does_not_name_variable)
+DIAG_NAME_INDEX(err_capture_more_than_once)
+DIAG_NAME_INDEX(err_capture_non_automatic_variable)
+DIAG_NAME_INDEX(err_capture_of_abstract_type)
+DIAG_NAME_INDEX(err_capture_of_incomplete_type)
+DIAG_NAME_INDEX(err_carries_dependency_missing_on_first_decl)
+DIAG_NAME_INDEX(err_carries_dependency_param_not_function_decl)
+DIAG_NAME_INDEX(err_case_not_in_switch)
+DIAG_NAME_INDEX(err_cast_pointer_from_non_pointer_int)
+DIAG_NAME_INDEX(err_cast_pointer_to_non_pointer_int)
+DIAG_NAME_INDEX(err_cast_selector_expr)
+DIAG_NAME_INDEX(err_catch_incomplete)
+DIAG_NAME_INDEX(err_catch_incomplete_ptr)
+DIAG_NAME_INDEX(err_catch_incomplete_ref)
+DIAG_NAME_INDEX(err_catch_param_not_objc_type)
+DIAG_NAME_INDEX(err_catch_rvalue_ref)
+DIAG_NAME_INDEX(err_category_forward_interface)
+DIAG_NAME_INDEX(err_cconv_change)
+DIAG_NAME_INDEX(err_cconv_knr)
+DIAG_NAME_INDEX(err_cconv_varargs)
+DIAG_NAME_INDEX(err_cfstring_literal_not_string_constant)
+DIAG_NAME_INDEX(err_character_too_large)
+DIAG_NAME_INDEX(err_circular_inheritance)
+DIAG_NAME_INDEX(err_class_extension_after_impl)
+DIAG_NAME_INDEX(err_class_marked_final_used_as_base)
+DIAG_NAME_INDEX(err_class_on_template_template_param)
+DIAG_NAME_INDEX(err_class_redeclared_with_different_access)
+DIAG_NAME_INDEX(err_cocoa_naming_owned_rule)
+DIAG_NAME_INDEX(err_collection_expr_type)
+DIAG_NAME_INDEX(err_compound_qualified_function_type)
+DIAG_NAME_INDEX(err_cond_voidptr_arc)
+DIAG_NAME_INDEX(err_conditional_ambiguous)
+DIAG_NAME_INDEX(err_conditional_ambiguous_ovl)
+DIAG_NAME_INDEX(err_conditional_void_nonvoid)
+DIAG_NAME_INDEX(err_config_scalar_return)
+DIAG_NAME_INDEX(err_conflict_marker)
+DIAG_NAME_INDEX(err_conflicting_aliasing_type)
+DIAG_NAME_INDEX(err_conflicting_ivar_bitwidth)
+DIAG_NAME_INDEX(err_conflicting_ivar_name)
+DIAG_NAME_INDEX(err_conflicting_ivar_type)
+DIAG_NAME_INDEX(err_conflicting_overriding_cc_attributes)
+DIAG_NAME_INDEX(err_conflicting_super_class)
+DIAG_NAME_INDEX(err_conflicting_types)
+DIAG_NAME_INDEX(err_constant_integer_arg_type)
+DIAG_NAME_INDEX(err_constexpr_body_invalid_stmt)
+DIAG_NAME_INDEX(err_constexpr_body_no_return)
+DIAG_NAME_INDEX(err_constexpr_ctor_missing_init)
+DIAG_NAME_INDEX(err_constexpr_dtor)
+DIAG_NAME_INDEX(err_constexpr_function_try_block)
+DIAG_NAME_INDEX(err_constexpr_local_var_no_init)
+DIAG_NAME_INDEX(err_constexpr_local_var_non_literal_type)
+DIAG_NAME_INDEX(err_constexpr_local_var_static)
+DIAG_NAME_INDEX(err_constexpr_main)
+DIAG_NAME_INDEX(err_constexpr_method_non_literal)
+DIAG_NAME_INDEX(err_constexpr_no_declarators)
+DIAG_NAME_INDEX(err_constexpr_non_literal_param)
+DIAG_NAME_INDEX(err_constexpr_non_literal_return)
+DIAG_NAME_INDEX(err_constexpr_redecl_mismatch)
+DIAG_NAME_INDEX(err_constexpr_static_mem_var_requires_init)
+DIAG_NAME_INDEX(err_constexpr_tag)
+DIAG_NAME_INDEX(err_constexpr_union_ctor_no_init)
+DIAG_NAME_INDEX(err_constexpr_var_non_literal)
+DIAG_NAME_INDEX(err_constexpr_var_requires_const_init)
+DIAG_NAME_INDEX(err_constexpr_virtual)
+DIAG_NAME_INDEX(err_constexpr_virtual_base)
+DIAG_NAME_INDEX(err_constexpr_vla)
+DIAG_NAME_INDEX(err_constructor_bad_name)
+DIAG_NAME_INDEX(err_constructor_byvalue_arg)
+DIAG_NAME_INDEX(err_constructor_cannot_be)
+DIAG_NAME_INDEX(err_constructor_redeclared)
+DIAG_NAME_INDEX(err_constructor_return_type)
+DIAG_NAME_INDEX(err_continuation_class)
+DIAG_NAME_INDEX(err_continue_not_in_loop)
+DIAG_NAME_INDEX(err_conv_function_not_member)
+DIAG_NAME_INDEX(err_conv_function_redeclared)
+DIAG_NAME_INDEX(err_conv_function_return_type)
+DIAG_NAME_INDEX(err_conv_function_to_array)
+DIAG_NAME_INDEX(err_conv_function_to_function)
+DIAG_NAME_INDEX(err_conv_function_variadic)
+DIAG_NAME_INDEX(err_conv_function_with_complex_decl)
+DIAG_NAME_INDEX(err_conv_function_with_params)
+DIAG_NAME_INDEX(err_convertvector_incompatible_vector)
+DIAG_NAME_INDEX(err_convertvector_non_vector)
+DIAG_NAME_INDEX(err_convertvector_non_vector_type)
+DIAG_NAME_INDEX(err_copy_capture_with_copy_default)
+DIAG_NAME_INDEX(err_covariant_return_ambiguous_derived_to_base_conv)
+DIAG_NAME_INDEX(err_covariant_return_inaccessible_base)
+DIAG_NAME_INDEX(err_covariant_return_incomplete)
+DIAG_NAME_INDEX(err_covariant_return_not_derived)
+DIAG_NAME_INDEX(err_covariant_return_type_class_type_more_qualified)
+DIAG_NAME_INDEX(err_covariant_return_type_different_qualifications)
+DIAG_NAME_INDEX(err_ctor_dtor_returns_void)
+DIAG_NAME_INDEX(err_ctor_init_missing_comma)
+DIAG_NAME_INDEX(err_cxx11_attribute_forbids_arguments)
+DIAG_NAME_INDEX(err_cxx11_attribute_forbids_ellipsis)
+DIAG_NAME_INDEX(err_cxx11_attribute_repeated)
+DIAG_NAME_INDEX(err_cyclic_alias)
+DIAG_NAME_INDEX(err_decimal_unsupported)
+DIAG_NAME_INDEX(err_decl_negative_array_size)
+DIAG_NAME_INDEX(err_declaration_does_not_declare_param)
+DIAG_NAME_INDEX(err_declarator_need_ident)
+DIAG_NAME_INDEX(err_declspec_thread_on_thread_variable)
+DIAG_NAME_INDEX(err_decltype_auto_cannot_be_combined)
+DIAG_NAME_INDEX(err_decltype_auto_compound_type)
+DIAG_NAME_INDEX(err_decltype_auto_function_declarator_not_declaration)
+DIAG_NAME_INDEX(err_decltype_auto_initializer_list)
+DIAG_NAME_INDEX(err_decltype_in_declarator)
+DIAG_NAME_INDEX(err_decrement_bool)
+DIAG_NAME_INDEX(err_deduced_non_type_template_arg_type_mismatch)
+DIAG_NAME_INDEX(err_deduced_return_type)
+DIAG_NAME_INDEX(err_deep_exception_specs_differ)
+DIAG_NAME_INDEX(err_default_arg_in_partial_spec)
+DIAG_NAME_INDEX(err_default_arg_makes_ctor_special)
+DIAG_NAME_INDEX(err_default_arg_unparsed)
+DIAG_NAME_INDEX(err_default_delete_in_multiple_declaration)
+DIAG_NAME_INDEX(err_default_init_const)
+DIAG_NAME_INDEX(err_default_not_in_switch)
+DIAG_NAME_INDEX(err_default_special_members)
+DIAG_NAME_INDEX(err_default_template_template_parameter_not_template)
+DIAG_NAME_INDEX(err_defaulted_copy_assign_not_ref)
+DIAG_NAME_INDEX(err_defaulted_special_member_copy_const_param)
+DIAG_NAME_INDEX(err_defaulted_special_member_move_const_param)
+DIAG_NAME_INDEX(err_defaulted_special_member_params)
+DIAG_NAME_INDEX(err_defaulted_special_member_quals)
+DIAG_NAME_INDEX(err_defaulted_special_member_return_type)
+DIAG_NAME_INDEX(err_defaulted_special_member_variadic)
+DIAG_NAME_INDEX(err_defaulted_special_member_volatile_param)
+DIAG_NAME_INDEX(err_defined_macro_name)
+DIAG_NAME_INDEX(err_definition_of_explicitly_defaulted_member)
+DIAG_NAME_INDEX(err_definition_of_implicitly_declared_member)
+DIAG_NAME_INDEX(err_delegating_ctor)
+DIAG_NAME_INDEX(err_delegating_initializer_alone)
+DIAG_NAME_INDEX(err_delete_explicit_conversion)
+DIAG_NAME_INDEX(err_delete_incomplete_class_type)
+DIAG_NAME_INDEX(err_delete_operand)
+DIAG_NAME_INDEX(err_deleted_decl_not_first)
+DIAG_NAME_INDEX(err_deleted_function_use)
+DIAG_NAME_INDEX(err_deleted_main)
+DIAG_NAME_INDEX(err_deleted_non_function)
+DIAG_NAME_INDEX(err_deleted_override)
+DIAG_NAME_INDEX(err_dependent_nested_name_spec)
+DIAG_NAME_INDEX(err_dependent_non_type_arg_in_partial_spec)
+DIAG_NAME_INDEX(err_dependent_tag_decl)
+DIAG_NAME_INDEX(err_dependent_typed_non_type_arg_in_partial_spec)
+DIAG_NAME_INDEX(err_dereference_incomplete_type)
+DIAG_NAME_INDEX(err_designator_for_scalar_init)
+DIAG_NAME_INDEX(err_designator_into_flexible_array_member)
+DIAG_NAME_INDEX(err_destructor_cannot_be)
+DIAG_NAME_INDEX(err_destructor_class_name)
+DIAG_NAME_INDEX(err_destructor_expr_type_mismatch)
+DIAG_NAME_INDEX(err_destructor_name)
+DIAG_NAME_INDEX(err_destructor_not_member)
+DIAG_NAME_INDEX(err_destructor_redeclared)
+DIAG_NAME_INDEX(err_destructor_return_type)
+DIAG_NAME_INDEX(err_destructor_template)
+DIAG_NAME_INDEX(err_destructor_template_id)
+DIAG_NAME_INDEX(err_destructor_tilde_identifier)
+DIAG_NAME_INDEX(err_destructor_typedef_name)
+DIAG_NAME_INDEX(err_destructor_variadic)
+DIAG_NAME_INDEX(err_destructor_with_params)
+DIAG_NAME_INDEX(err_different_language_linkage)
+DIAG_NAME_INDEX(err_different_return_type_for_overriding_virtual_function)
+DIAG_NAME_INDEX(err_digit_separator_not_between_digits)
+DIAG_NAME_INDEX(err_dimension_expr_not_constant_integer)
+DIAG_NAME_INDEX(err_distant_exception_spec)
+DIAG_NAME_INDEX(err_double_requires_fp64)
+DIAG_NAME_INDEX(err_downcast_from_inaccessible_base)
+DIAG_NAME_INDEX(err_drv_I_dash_not_supported)
+DIAG_NAME_INDEX(err_drv_argument_not_allowed_with)
+DIAG_NAME_INDEX(err_drv_argument_only_allowed_with)
+DIAG_NAME_INDEX(err_drv_cc_print_options_failure)
+DIAG_NAME_INDEX(err_drv_clang_unsupported)
+DIAG_NAME_INDEX(err_drv_clang_unsupported_opt_cxx_darwin_i386)
+DIAG_NAME_INDEX(err_drv_clang_unsupported_per_platform)
+DIAG_NAME_INDEX(err_drv_command_failed)
+DIAG_NAME_INDEX(err_drv_command_failure)
+DIAG_NAME_INDEX(err_drv_command_signalled)
+DIAG_NAME_INDEX(err_drv_conflicting_deployment_targets)
+DIAG_NAME_INDEX(err_drv_emit_llvm_link)
+DIAG_NAME_INDEX(err_drv_force_crash)
+DIAG_NAME_INDEX(err_drv_invalid_Xarch_argument_isdriver)
+DIAG_NAME_INDEX(err_drv_invalid_Xarch_argument_with_args)
+DIAG_NAME_INDEX(err_drv_invalid_arch_for_deployment_target)
+DIAG_NAME_INDEX(err_drv_invalid_arch_name)
+DIAG_NAME_INDEX(err_drv_invalid_darwin_version)
+DIAG_NAME_INDEX(err_drv_invalid_gcc_output_type)
+DIAG_NAME_INDEX(err_drv_invalid_int_value)
+DIAG_NAME_INDEX(err_drv_invalid_libcxx_deployment)
+DIAG_NAME_INDEX(err_drv_invalid_linker_name)
+DIAG_NAME_INDEX(err_drv_invalid_mfloat_abi)
+DIAG_NAME_INDEX(err_drv_invalid_output_with_multiple_archs)
+DIAG_NAME_INDEX(err_drv_invalid_remap_file)
+DIAG_NAME_INDEX(err_drv_invalid_rtlib_name)
+DIAG_NAME_INDEX(err_drv_invalid_stdlib_name)
+DIAG_NAME_INDEX(err_drv_invalid_value)
+DIAG_NAME_INDEX(err_drv_invalid_version_number)
+DIAG_NAME_INDEX(err_drv_malformed_sanitizer_blacklist)
+DIAG_NAME_INDEX(err_drv_mg_requires_m_or_mm)
+DIAG_NAME_INDEX(err_drv_missing_argument)
+DIAG_NAME_INDEX(err_drv_modules_validate_once_requires_timestamp)
+DIAG_NAME_INDEX(err_drv_no_ast_support)
+DIAG_NAME_INDEX(err_drv_no_input_files)
+DIAG_NAME_INDEX(err_drv_no_linker_llvm_support)
+DIAG_NAME_INDEX(err_drv_no_module_support)
+DIAG_NAME_INDEX(err_drv_no_neon_modifier)
+DIAG_NAME_INDEX(err_drv_no_such_file)
+DIAG_NAME_INDEX(err_drv_objc_gc_arr)
+DIAG_NAME_INDEX(err_drv_optimization_remark_pattern)
+DIAG_NAME_INDEX(err_drv_out_file_argument_with_multiple_sources)
+DIAG_NAME_INDEX(err_drv_output_argument_with_multiple_files)
+DIAG_NAME_INDEX(err_drv_preamble_format)
+DIAG_NAME_INDEX(err_drv_unable_to_remove_file)
+DIAG_NAME_INDEX(err_drv_unknown_argument)
+DIAG_NAME_INDEX(err_drv_unknown_language)
+DIAG_NAME_INDEX(err_drv_unknown_objc_runtime)
+DIAG_NAME_INDEX(err_drv_unknown_stdin_type)
+DIAG_NAME_INDEX(err_drv_unknown_stdin_type_clang_cl)
+DIAG_NAME_INDEX(err_drv_unsupported_opt)
+DIAG_NAME_INDEX(err_drv_unsupported_opt_for_target)
+DIAG_NAME_INDEX(err_drv_unsupported_option_argument)
+DIAG_NAME_INDEX(err_drv_unsupported_rtlib_for_platform)
+DIAG_NAME_INDEX(err_drv_use_of_Z_option)
+DIAG_NAME_INDEX(err_dtor_expr_without_call)
+DIAG_NAME_INDEX(err_dup_implementation_category)
+DIAG_NAME_INDEX(err_dup_implementation_class)
+DIAG_NAME_INDEX(err_dup_virtual)
+DIAG_NAME_INDEX(err_duplicate_base_class)
+DIAG_NAME_INDEX(err_duplicate_case)
+DIAG_NAME_INDEX(err_duplicate_case_differing_expr)
+DIAG_NAME_INDEX(err_duplicate_class_def)
+DIAG_NAME_INDEX(err_duplicate_default_assoc)
+DIAG_NAME_INDEX(err_duplicate_ivar_declaration)
+DIAG_NAME_INDEX(err_duplicate_mangled_name)
+DIAG_NAME_INDEX(err_duplicate_member)
+DIAG_NAME_INDEX(err_duplicate_method_decl)
+DIAG_NAME_INDEX(err_duplicate_property)
+DIAG_NAME_INDEX(err_duplicate_virt_specifier)
+DIAG_NAME_INDEX(err_dynamic_and_noexcept_specification)
+DIAG_NAME_INDEX(err_early_catch_all)
+DIAG_NAME_INDEX(err_ellipsis_first_param)
+DIAG_NAME_INDEX(err_ellipsis_in_declarator_not_parameter)
+DIAG_NAME_INDEX(err_embedded_include)
+DIAG_NAME_INDEX(err_empty_scalar_initializer)
+DIAG_NAME_INDEX(err_enable_if_never_constant_expr)
+DIAG_NAME_INDEX(err_enum_class_reference)
+DIAG_NAME_INDEX(err_enum_invalid_underlying)
+DIAG_NAME_INDEX(err_enum_redeclare_fixed_mismatch)
+DIAG_NAME_INDEX(err_enum_redeclare_scoped_mismatch)
+DIAG_NAME_INDEX(err_enum_redeclare_type_mismatch)
+DIAG_NAME_INDEX(err_enum_template)
+DIAG_NAME_INDEX(err_enumerator_does_not_exist)
+DIAG_NAME_INDEX(err_enumerator_list_missing_comma)
+DIAG_NAME_INDEX(err_enumerator_too_large)
+DIAG_NAME_INDEX(err_enumerator_unnamed_no_def)
+DIAG_NAME_INDEX(err_enumerator_wrapped)
+DIAG_NAME_INDEX(err_event_t_addr_space_qual)
+DIAG_NAME_INDEX(err_event_t_global_var)
+DIAG_NAME_INDEX(err_event_t_struct_field)
+DIAG_NAME_INDEX(err_exception_spec_in_typedef)
+DIAG_NAME_INDEX(err_exceptions_disabled)
+DIAG_NAME_INDEX(err_excess_initializers)
+DIAG_NAME_INDEX(err_excess_initializers_in_char_array_initializer)
+DIAG_NAME_INDEX(err_expected)
+DIAG_NAME_INDEX(err_expected_after)
+DIAG_NAME_INDEX(err_expected_capture)
+DIAG_NAME_INDEX(err_expected_case_before_expression)
+DIAG_NAME_INDEX(err_expected_catch)
+DIAG_NAME_INDEX(err_expected_class_name)
+DIAG_NAME_INDEX(err_expected_class_name_not_template)
+DIAG_NAME_INDEX(err_expected_class_or_namespace)
+DIAG_NAME_INDEX(err_expected_colon_after_setter_name)
+DIAG_NAME_INDEX(err_expected_comma_greater)
+DIAG_NAME_INDEX(err_expected_comma_or_rsquare)
+DIAG_NAME_INDEX(err_expected_either)
+DIAG_NAME_INDEX(err_expected_end_of_enumerator)
+DIAG_NAME_INDEX(err_expected_equal_designator)
+DIAG_NAME_INDEX(err_expected_expression)
+DIAG_NAME_INDEX(err_expected_external_declaration)
+DIAG_NAME_INDEX(err_expected_field_designator)
+DIAG_NAME_INDEX(err_expected_fn_body)
+DIAG_NAME_INDEX(err_expected_id_building_module)
+DIAG_NAME_INDEX(err_expected_init_in_condition)
+DIAG_NAME_INDEX(err_expected_init_in_condition_lparen)
+DIAG_NAME_INDEX(err_expected_kernel_void_return_type)
+DIAG_NAME_INDEX(err_expected_lambda_body)
+DIAG_NAME_INDEX(err_expected_lbrace_after_base_specifiers)
+DIAG_NAME_INDEX(err_expected_lbrace_in_compound_literal)
+DIAG_NAME_INDEX(err_expected_less_after)
+DIAG_NAME_INDEX(err_expected_lparen_after)
+DIAG_NAME_INDEX(err_expected_lparen_after_type)
+DIAG_NAME_INDEX(err_expected_member_name_or_semi)
+DIAG_NAME_INDEX(err_expected_member_or_base_name)
+DIAG_NAME_INDEX(err_expected_method_body)
+DIAG_NAME_INDEX(err_expected_minus_or_plus)
+DIAG_NAME_INDEX(err_expected_namespace_name)
+DIAG_NAME_INDEX(err_expected_objc_container)
+DIAG_NAME_INDEX(err_expected_parameter_pack)
+DIAG_NAME_INDEX(err_expected_parentheses_around_typename)
+DIAG_NAME_INDEX(err_expected_property_name)
+DIAG_NAME_INDEX(err_expected_punc)
+DIAG_NAME_INDEX(err_expected_qualified_after_typename)
+DIAG_NAME_INDEX(err_expected_rparen_after)
+DIAG_NAME_INDEX(err_expected_selector_for_method)
+DIAG_NAME_INDEX(err_expected_semi_after_attribute_list)
+DIAG_NAME_INDEX(err_expected_semi_after_expr)
+DIAG_NAME_INDEX(err_expected_semi_after_method_proto)
+DIAG_NAME_INDEX(err_expected_semi_after_namespace_name)
+DIAG_NAME_INDEX(err_expected_semi_after_static_assert)
+DIAG_NAME_INDEX(err_expected_semi_after_stmt)
+DIAG_NAME_INDEX(err_expected_semi_decl_list)
+DIAG_NAME_INDEX(err_expected_semi_declaration)
+DIAG_NAME_INDEX(err_expected_semi_for)
+DIAG_NAME_INDEX(err_expected_statement)
+DIAG_NAME_INDEX(err_expected_string_literal)
+DIAG_NAME_INDEX(err_expected_template)
+DIAG_NAME_INDEX(err_expected_template_parameter)
+DIAG_NAME_INDEX(err_expected_type)
+DIAG_NAME_INDEX(err_expected_type_name_after_typename)
+DIAG_NAME_INDEX(err_expected_unqualified_id)
+DIAG_NAME_INDEX(err_expected_version)
+DIAG_NAME_INDEX(err_expected_while)
+DIAG_NAME_INDEX(err_explicit_instantiation_ambiguous)
+DIAG_NAME_INDEX(err_explicit_instantiation_constexpr)
+DIAG_NAME_INDEX(err_explicit_instantiation_data_member_not_instantiated)
+DIAG_NAME_INDEX(err_explicit_instantiation_declaration_after_definition)
+DIAG_NAME_INDEX(err_explicit_instantiation_duplicate)
+DIAG_NAME_INDEX(err_explicit_instantiation_enum)
+DIAG_NAME_INDEX(err_explicit_instantiation_in_class)
+DIAG_NAME_INDEX(err_explicit_instantiation_inline)
+DIAG_NAME_INDEX(err_explicit_instantiation_member_function_not_instantiated)
+DIAG_NAME_INDEX(err_explicit_instantiation_must_be_global)
+DIAG_NAME_INDEX(err_explicit_instantiation_nontemplate_type)
+DIAG_NAME_INDEX(err_explicit_instantiation_not_known)
+DIAG_NAME_INDEX(err_explicit_instantiation_of_typedef)
+DIAG_NAME_INDEX(err_explicit_instantiation_out_of_scope)
+DIAG_NAME_INDEX(err_explicit_instantiation_requires_name)
+DIAG_NAME_INDEX(err_explicit_instantiation_storage_class)
+DIAG_NAME_INDEX(err_explicit_instantiation_undefined_func_template)
+DIAG_NAME_INDEX(err_explicit_instantiation_undefined_member)
+DIAG_NAME_INDEX(err_explicit_instantiation_undefined_var_template)
+DIAG_NAME_INDEX(err_explicit_instantiation_unqualified_wrong_namespace)
+DIAG_NAME_INDEX(err_explicit_instantiation_with_definition)
+DIAG_NAME_INDEX(err_explicit_instantiation_without_template_id)
+DIAG_NAME_INDEX(err_explicit_non_ctor_or_conv_function)
+DIAG_NAME_INDEX(err_explicit_non_function)
+DIAG_NAME_INDEX(err_explicit_out_of_class)
+DIAG_NAME_INDEX(err_explicit_spec_non_template)
+DIAG_NAME_INDEX(err_explicit_specialization_inconsistent_storage_class)
+DIAG_NAME_INDEX(err_exponent_has_no_digits)
+DIAG_NAME_INDEX(err_expr_not_cce)
+DIAG_NAME_INDEX(err_expr_not_ice)
+DIAG_NAME_INDEX(err_ext_vector_component_exceeds_length)
+DIAG_NAME_INDEX(err_ext_vector_component_name_illegal)
+DIAG_NAME_INDEX(err_extern_c_global_conflict)
+DIAG_NAME_INDEX(err_extern_non_extern)
+DIAG_NAME_INDEX(err_extraneous_closing_brace)
+DIAG_NAME_INDEX(err_extraneous_rparen_in_condition)
+DIAG_NAME_INDEX(err_extraneous_token_before_semi)
+DIAG_NAME_INDEX(err_falloff_nonvoid_block)
+DIAG_NAME_INDEX(err_fallthrough_attr_outside_switch)
+DIAG_NAME_INDEX(err_fallthrough_attr_wrong_target)
+DIAG_NAME_INDEX(err_fe_action_not_available)
+DIAG_NAME_INDEX(err_fe_backend_frame_larger_than)
+DIAG_NAME_INDEX(err_fe_backend_plugin)
+DIAG_NAME_INDEX(err_fe_cannot_link_module)
+DIAG_NAME_INDEX(err_fe_dependency_file_requires_MT)
+DIAG_NAME_INDEX(err_fe_error_backend)
+DIAG_NAME_INDEX(err_fe_error_opening)
+DIAG_NAME_INDEX(err_fe_error_reading)
+DIAG_NAME_INDEX(err_fe_error_reading_stdin)
+DIAG_NAME_INDEX(err_fe_expected_clang_command)
+DIAG_NAME_INDEX(err_fe_expected_compiler_job)
+DIAG_NAME_INDEX(err_fe_inline_asm)
+DIAG_NAME_INDEX(err_fe_invalid_code_complete_file)
+DIAG_NAME_INDEX(err_fe_invalid_plugin_name)
+DIAG_NAME_INDEX(err_fe_no_pch_in_dir)
+DIAG_NAME_INDEX(err_fe_not_a_pch_file)
+DIAG_NAME_INDEX(err_fe_pch_file_modified)
+DIAG_NAME_INDEX(err_fe_pch_file_overridden)
+DIAG_NAME_INDEX(err_fe_pch_malformed)
+DIAG_NAME_INDEX(err_fe_pch_malformed_block)
+DIAG_NAME_INDEX(err_fe_pth_file_has_no_source_header)
+DIAG_NAME_INDEX(err_fe_remap_missing_from_file)
+DIAG_NAME_INDEX(err_fe_remap_missing_to_file)
+DIAG_NAME_INDEX(err_fe_stdout_binary)
+DIAG_NAME_INDEX(err_fe_unable_to_create_target)
+DIAG_NAME_INDEX(err_fe_unable_to_interface_with_target)
+DIAG_NAME_INDEX(err_fe_unable_to_load_pch)
+DIAG_NAME_INDEX(err_fe_unable_to_load_plugin)
+DIAG_NAME_INDEX(err_fe_unable_to_open_output)
+DIAG_NAME_INDEX(err_fe_unable_to_read_pch_file)
+DIAG_NAME_INDEX(err_feature_check_malformed)
+DIAG_NAME_INDEX(err_field_declared_as_function)
+DIAG_NAME_INDEX(err_field_designator_non_aggr)
+DIAG_NAME_INDEX(err_field_designator_nonfield)
+DIAG_NAME_INDEX(err_field_designator_unknown)
+DIAG_NAME_INDEX(err_field_designator_unknown_suggest)
+DIAG_NAME_INDEX(err_field_incomplete)
+DIAG_NAME_INDEX(err_field_instantiates_to_function)
+DIAG_NAME_INDEX(err_field_with_address_space)
+DIAG_NAME_INDEX(err_file_modified)
+DIAG_NAME_INDEX(err_filter_expression_integral)
+DIAG_NAME_INDEX(err_final_function_overridden)
+DIAG_NAME_INDEX(err_first_argument_to_va_arg_not_of_type_va_list)
+DIAG_NAME_INDEX(err_flexible_array_empty_aggregate)
+DIAG_NAME_INDEX(err_flexible_array_has_nontrivial_dtor)
+DIAG_NAME_INDEX(err_flexible_array_init)
+DIAG_NAME_INDEX(err_flexible_array_init_needs_braces)
+DIAG_NAME_INDEX(err_flexible_array_union)
+DIAG_NAME_INDEX(err_flexible_array_virtual_base)
+DIAG_NAME_INDEX(err_for_range_begin_end_types_differ)
+DIAG_NAME_INDEX(err_for_range_decl_must_be_var)
+DIAG_NAME_INDEX(err_for_range_deduction_failure)
+DIAG_NAME_INDEX(err_for_range_dereference)
+DIAG_NAME_INDEX(err_for_range_expected_decl)
+DIAG_NAME_INDEX(err_for_range_incomplete_type)
+DIAG_NAME_INDEX(err_for_range_invalid)
+DIAG_NAME_INDEX(err_for_range_iter_deduction_failure)
+DIAG_NAME_INDEX(err_for_range_member_begin_end_mismatch)
+DIAG_NAME_INDEX(err_for_range_storage_class)
+DIAG_NAME_INDEX(err_format_attribute_implicit_this_format_string)
+DIAG_NAME_INDEX(err_format_attribute_not)
+DIAG_NAME_INDEX(err_format_attribute_requires_variadic)
+DIAG_NAME_INDEX(err_format_attribute_result_not)
+DIAG_NAME_INDEX(err_format_strftime_third_parameter)
+DIAG_NAME_INDEX(err_forward_ref_enum)
+DIAG_NAME_INDEX(err_forward_superclass)
+DIAG_NAME_INDEX(err_friend_decl_defines_type)
+DIAG_NAME_INDEX(err_friend_decl_does_not_match)
+DIAG_NAME_INDEX(err_friend_decl_spec)
+DIAG_NAME_INDEX(err_friend_decl_with_def_arg_must_be_def)
+DIAG_NAME_INDEX(err_friend_decl_with_def_arg_redeclared)
+DIAG_NAME_INDEX(err_friend_def_in_local_class)
+DIAG_NAME_INDEX(err_friend_explicit_instantiation)
+DIAG_NAME_INDEX(err_friend_invalid_in_context)
+DIAG_NAME_INDEX(err_friend_is_member)
+DIAG_NAME_INDEX(err_friend_not_first_in_declaration)
+DIAG_NAME_INDEX(err_func_def_incomplete_result)
+DIAG_NAME_INDEX(err_func_def_no_params)
+DIAG_NAME_INDEX(err_func_returning_array_function)
+DIAG_NAME_INDEX(err_function_declared_typedef)
+DIAG_NAME_INDEX(err_function_definition_not_allowed)
+DIAG_NAME_INDEX(err_function_is_not_record)
+DIAG_NAME_INDEX(err_function_marked_override_not_overriding)
+DIAG_NAME_INDEX(err_function_parameter_pack_without_parameter_packs)
+DIAG_NAME_INDEX(err_function_specialization_in_class)
+DIAG_NAME_INDEX(err_function_template_partial_spec)
+DIAG_NAME_INDEX(err_function_template_spec_ambiguous)
+DIAG_NAME_INDEX(err_function_template_spec_no_match)
+DIAG_NAME_INDEX(err_gc_weak_property_strong_type)
+DIAG_NAME_INDEX(err_generic_sel_multi_match)
+DIAG_NAME_INDEX(err_generic_sel_no_match)
+DIAG_NAME_INDEX(err_getter_not_found)
+DIAG_NAME_INDEX(err_global_call_not_config)
+DIAG_NAME_INDEX(err_goto_into_protected_scope)
+DIAG_NAME_INDEX(err_hex_escape_no_digits)
+DIAG_NAME_INDEX(err_hex_escape_too_large)
+DIAG_NAME_INDEX(err_hexconstant_requires_digits)
+DIAG_NAME_INDEX(err_hexconstant_requires_exponent)
+DIAG_NAME_INDEX(err_iboutletcollection_builtintype)
+DIAG_NAME_INDEX(err_iboutletcollection_type)
+DIAG_NAME_INDEX(err_ice_ambiguous_conversion)
+DIAG_NAME_INDEX(err_ice_explicit_conversion)
+DIAG_NAME_INDEX(err_ice_incomplete_type)
+DIAG_NAME_INDEX(err_ice_not_integral)
+DIAG_NAME_INDEX(err_id_after_template_in_nested_name_spec)
+DIAG_NAME_INDEX(err_ident_in_dtor_not_a_type)
+DIAG_NAME_INDEX(err_ident_list_in_fn_declaration)
+DIAG_NAME_INDEX(err_illegal_container_subscripting_op)
+DIAG_NAME_INDEX(err_illegal_decl_array_incomplete_type)
+DIAG_NAME_INDEX(err_illegal_decl_array_of_auto)
+DIAG_NAME_INDEX(err_illegal_decl_array_of_functions)
+DIAG_NAME_INDEX(err_illegal_decl_array_of_references)
+DIAG_NAME_INDEX(err_illegal_decl_mempointer_in_nonclass)
+DIAG_NAME_INDEX(err_illegal_decl_mempointer_to_reference)
+DIAG_NAME_INDEX(err_illegal_decl_mempointer_to_void)
+DIAG_NAME_INDEX(err_illegal_decl_pointer_to_reference)
+DIAG_NAME_INDEX(err_illegal_decl_reference_to_reference)
+DIAG_NAME_INDEX(err_illegal_initializer)
+DIAG_NAME_INDEX(err_illegal_initializer_type)
+DIAG_NAME_INDEX(err_illegal_message_expr_incomplete_type)
+DIAG_NAME_INDEX(err_illegal_qualifiers_on_catch_parm)
+DIAG_NAME_INDEX(err_illegal_super_cast)
+DIAG_NAME_INDEX(err_illegal_union_or_anon_struct_member)
+DIAG_NAME_INDEX(err_imaginary_not_supported)
+DIAG_NAME_INDEX(err_implicit_empty_initializer)
+DIAG_NAME_INDEX(err_implicit_instantiate_member_undefined)
+DIAG_NAME_INDEX(err_implicit_object_parameter_init)
+DIAG_NAME_INDEX(err_implied_std_initializer_list_not_found)
+DIAG_NAME_INDEX(err_imported_module_modmap_changed)
+DIAG_NAME_INDEX(err_imported_module_not_found)
+DIAG_NAME_INDEX(err_in_class_initializer_bad_type)
+DIAG_NAME_INDEX(err_in_class_initializer_literal_type)
+DIAG_NAME_INDEX(err_in_class_initializer_non_const)
+DIAG_NAME_INDEX(err_in_class_initializer_non_constant)
+DIAG_NAME_INDEX(err_in_class_initializer_references_def_ctor)
+DIAG_NAME_INDEX(err_in_class_initializer_volatile)
+DIAG_NAME_INDEX(err_incompatible_exception_specs)
+DIAG_NAME_INDEX(err_incomplete_array_member_init)
+DIAG_NAME_INDEX(err_incomplete_base_class)
+DIAG_NAME_INDEX(err_incomplete_in_exception_spec)
+DIAG_NAME_INDEX(err_incomplete_member_access)
+DIAG_NAME_INDEX(err_incomplete_nested_name_spec)
+DIAG_NAME_INDEX(err_incomplete_object_call)
+DIAG_NAME_INDEX(err_incomplete_receiver_type)
+DIAG_NAME_INDEX(err_incomplete_synthesized_property)
+DIAG_NAME_INDEX(err_incomplete_type)
+DIAG_NAME_INDEX(err_incomplete_type_objc_at_encode)
+DIAG_NAME_INDEX(err_incomplete_type_used_in_type_trait_expr)
+DIAG_NAME_INDEX(err_incomplete_typeid)
+DIAG_NAME_INDEX(err_inconsistent_ivar_count)
+DIAG_NAME_INDEX(err_incorrect_defaulted_constexpr)
+DIAG_NAME_INDEX(err_incorrect_defaulted_exception_spec)
+DIAG_NAME_INDEX(err_incorrect_number_of_vector_initializers)
+DIAG_NAME_INDEX(err_increment_decrement_enum)
+DIAG_NAME_INDEX(err_indirect_goto_in_protected_scope)
+DIAG_NAME_INDEX(err_indirect_goto_without_addrlabel)
+DIAG_NAME_INDEX(err_init_capture_deduction_failure)
+DIAG_NAME_INDEX(err_init_capture_deduction_failure_from_init_list)
+DIAG_NAME_INDEX(err_init_capture_multiple_expressions)
+DIAG_NAME_INDEX(err_init_capture_no_expression)
+DIAG_NAME_INDEX(err_init_capture_paren_braces)
+DIAG_NAME_INDEX(err_init_conversion_failed)
+DIAG_NAME_INDEX(err_init_element_not_constant)
+DIAG_NAME_INDEX(err_init_incomplete_type)
+DIAG_NAME_INDEX(err_init_list_bad_dest_type)
+DIAG_NAME_INDEX(err_init_list_bin_op)
+DIAG_NAME_INDEX(err_init_method_bad_return_type)
+DIAG_NAME_INDEX(err_init_non_aggr_init_list)
+DIAG_NAME_INDEX(err_init_objc_class)
+DIAG_NAME_INDEX(err_init_priority_object_attr)
+DIAG_NAME_INDEX(err_init_reference_member_uninitialized)
+DIAG_NAME_INDEX(err_initializer_string_for_char_array_too_long)
+DIAG_NAME_INDEX(err_inline_decl_follows_def)
+DIAG_NAME_INDEX(err_inline_declaration_block_scope)
+DIAG_NAME_INDEX(err_inline_main)
+DIAG_NAME_INDEX(err_inline_ms_asm_parsing)
+DIAG_NAME_INDEX(err_inline_namespace_alias)
+DIAG_NAME_INDEX(err_inline_namespace_mismatch)
+DIAG_NAME_INDEX(err_inline_non_function)
+DIAG_NAME_INDEX(err_int128_unsupported)
+DIAG_NAME_INDEX(err_int_to_block_pointer)
+DIAG_NAME_INDEX(err_integer_too_large)
+DIAG_NAME_INDEX(err_introducing_special_friend)
+DIAG_NAME_INDEX(err_invalid_asm_cast_lvalue)
+DIAG_NAME_INDEX(err_invalid_astype_of_different_size)
+DIAG_NAME_INDEX(err_invalid_base_in_interface)
+DIAG_NAME_INDEX(err_invalid_binary_digit)
+DIAG_NAME_INDEX(err_invalid_char_raw_delim)
+DIAG_NAME_INDEX(err_invalid_character_to_charify)
+DIAG_NAME_INDEX(err_invalid_character_udl)
+DIAG_NAME_INDEX(err_invalid_collection_element)
+DIAG_NAME_INDEX(err_invalid_complex_spec)
+DIAG_NAME_INDEX(err_invalid_constexpr)
+DIAG_NAME_INDEX(err_invalid_constexpr_member)
+DIAG_NAME_INDEX(err_invalid_constexpr_var_decl)
+DIAG_NAME_INDEX(err_invalid_conversion_between_ext_vectors)
+DIAG_NAME_INDEX(err_invalid_conversion_between_vector_and_integer)
+DIAG_NAME_INDEX(err_invalid_conversion_between_vector_and_scalar)
+DIAG_NAME_INDEX(err_invalid_conversion_between_vectors)
+DIAG_NAME_INDEX(err_invalid_decimal_digit)
+DIAG_NAME_INDEX(err_invalid_decl_spec_combination)
+DIAG_NAME_INDEX(err_invalid_declarator_global_scope)
+DIAG_NAME_INDEX(err_invalid_declarator_in_block)
+DIAG_NAME_INDEX(err_invalid_declarator_in_function)
+DIAG_NAME_INDEX(err_invalid_declarator_scope)
+DIAG_NAME_INDEX(err_invalid_form_pointer_member_function)
+DIAG_NAME_INDEX(err_invalid_incomplete_type_use)
+DIAG_NAME_INDEX(err_invalid_long_spec)
+DIAG_NAME_INDEX(err_invalid_longlong_spec)
+DIAG_NAME_INDEX(err_invalid_member_in_interface)
+DIAG_NAME_INDEX(err_invalid_member_use_in_static_method)
+DIAG_NAME_INDEX(err_invalid_neon_type_code)
+DIAG_NAME_INDEX(err_invalid_non_static_member_use)
+DIAG_NAME_INDEX(err_invalid_nsnumber_type)
+DIAG_NAME_INDEX(err_invalid_numeric_udl)
+DIAG_NAME_INDEX(err_invalid_octal_digit)
+DIAG_NAME_INDEX(err_invalid_operator_on_type)
+DIAG_NAME_INDEX(err_invalid_pcs)
+DIAG_NAME_INDEX(err_invalid_pixel_decl_spec_combination)
+DIAG_NAME_INDEX(err_invalid_property_name)
+DIAG_NAME_INDEX(err_invalid_protocol_qualifiers)
+DIAG_NAME_INDEX(err_invalid_pth_file)
+DIAG_NAME_INDEX(err_invalid_qualified_constructor)
+DIAG_NAME_INDEX(err_invalid_qualified_destructor)
+DIAG_NAME_INDEX(err_invalid_qualified_function_type)
+DIAG_NAME_INDEX(err_invalid_receiver_class_message)
+DIAG_NAME_INDEX(err_invalid_receiver_to_message_super)
+DIAG_NAME_INDEX(err_invalid_reference_qualifier_application)
+DIAG_NAME_INDEX(err_invalid_short_spec)
+DIAG_NAME_INDEX(err_invalid_sign_spec)
+DIAG_NAME_INDEX(err_invalid_storage_class_in_func_decl)
+DIAG_NAME_INDEX(err_invalid_string_udl)
+DIAG_NAME_INDEX(err_invalid_suffix_float_constant)
+DIAG_NAME_INDEX(err_invalid_suffix_integer_constant)
+DIAG_NAME_INDEX(err_invalid_this_use)
+DIAG_NAME_INDEX(err_invalid_thread)
+DIAG_NAME_INDEX(err_invalid_token_after_declarator_suggest_equal)
+DIAG_NAME_INDEX(err_invalid_token_after_toplevel_declarator)
+DIAG_NAME_INDEX(err_invalid_use_of_array_type)
+DIAG_NAME_INDEX(err_invalid_use_of_function_type)
+DIAG_NAME_INDEX(err_invalid_utf8)
+DIAG_NAME_INDEX(err_invalid_var_template_spec_type)
+DIAG_NAME_INDEX(err_invalid_vector_bool_decl_spec)
+DIAG_NAME_INDEX(err_invalid_vector_decl_spec)
+DIAG_NAME_INDEX(err_invalid_vector_decl_spec_combination)
+DIAG_NAME_INDEX(err_invalid_vfs_overlay)
+DIAG_NAME_INDEX(err_ivar_access_using_property_syntax_suggest)
+DIAG_NAME_INDEX(err_ivar_reference_type)
+DIAG_NAME_INDEX(err_kern_call_not_global_function)
+DIAG_NAME_INDEX(err_kern_type_not_void_return)
+DIAG_NAME_INDEX(err_l_square_l_square_not_attribute)
+DIAG_NAME_INDEX(err_label_end_of_compound_statement)
+DIAG_NAME_INDEX(err_lambda_capture_anonymous_var)
+DIAG_NAME_INDEX(err_lambda_capture_default_arg)
+DIAG_NAME_INDEX(err_lambda_capture_flexarray_type)
+DIAG_NAME_INDEX(err_lambda_capture_vm_type)
+DIAG_NAME_INDEX(err_lambda_decl_ref_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_lambda_impcap)
+DIAG_NAME_INDEX(err_lambda_in_constant_expression)
+DIAG_NAME_INDEX(err_lambda_incomplete_result)
+DIAG_NAME_INDEX(err_lambda_missing_parens)
+DIAG_NAME_INDEX(err_lambda_return_init_list)
+DIAG_NAME_INDEX(err_lambda_unevaluated_operand)
+DIAG_NAME_INDEX(err_language_linkage_spec_not_ascii)
+DIAG_NAME_INDEX(err_language_linkage_spec_unknown)
+DIAG_NAME_INDEX(err_lexing_string)
+DIAG_NAME_INDEX(err_literal_operator_default_argument)
+DIAG_NAME_INDEX(err_literal_operator_extern_c)
+DIAG_NAME_INDEX(err_literal_operator_id_outside_namespace)
+DIAG_NAME_INDEX(err_literal_operator_outside_namespace)
+DIAG_NAME_INDEX(err_literal_operator_params)
+DIAG_NAME_INDEX(err_literal_operator_string_not_empty)
+DIAG_NAME_INDEX(err_literal_operator_string_prefix)
+DIAG_NAME_INDEX(err_local_cant_init)
+DIAG_NAME_INDEX(err_lvalue_reference_bind_to_initlist)
+DIAG_NAME_INDEX(err_lvalue_reference_bind_to_temporary)
+DIAG_NAME_INDEX(err_lvalue_reference_bind_to_unrelated)
+DIAG_NAME_INDEX(err_lvalue_to_rvalue_ref)
+DIAG_NAME_INDEX(err_machine_mode)
+DIAG_NAME_INDEX(err_main_arg_wrong)
+DIAG_NAME_INDEX(err_main_returns_nonint)
+DIAG_NAME_INDEX(err_main_surplus_args)
+DIAG_NAME_INDEX(err_mainlike_template_decl)
+DIAG_NAME_INDEX(err_malformed_std_initializer_list)
+DIAG_NAME_INDEX(err_maybe_falloff_nonvoid_block)
+DIAG_NAME_INDEX(err_mem_init_not_member_or_class)
+DIAG_NAME_INDEX(err_mem_init_not_member_or_class_suggest)
+DIAG_NAME_INDEX(err_member_call_without_object)
+DIAG_NAME_INDEX(err_member_decl_does_not_match)
+DIAG_NAME_INDEX(err_member_decl_does_not_match_suggest)
+DIAG_NAME_INDEX(err_member_def_does_not_match_ret_type)
+DIAG_NAME_INDEX(err_member_def_undefined_record)
+DIAG_NAME_INDEX(err_member_extra_qualification)
+DIAG_NAME_INDEX(err_member_function_call_bad_cvr)
+DIAG_NAME_INDEX(err_member_function_initialization)
+DIAG_NAME_INDEX(err_member_name_of_class)
+DIAG_NAME_INDEX(err_member_not_yet_instantiated)
+DIAG_NAME_INDEX(err_member_qualification)
+DIAG_NAME_INDEX(err_member_redeclared)
+DIAG_NAME_INDEX(err_member_redeclared_in_instantiation)
+DIAG_NAME_INDEX(err_member_reference_needs_call)
+DIAG_NAME_INDEX(err_mempointer_in_nonclass_type)
+DIAG_NAME_INDEX(err_memptr_conv_via_virtual)
+DIAG_NAME_INDEX(err_mismatched_exception_spec)
+DIAG_NAME_INDEX(err_mismatched_ms_inheritance)
+DIAG_NAME_INDEX(err_mismatched_visibility)
+DIAG_NAME_INDEX(err_misplaced_ellipsis_in_declaration)
+DIAG_NAME_INDEX(err_misplaced_ivar)
+DIAG_NAME_INDEX(err_missing_atsign_prefix)
+DIAG_NAME_INDEX(err_missing_catch_finally)
+DIAG_NAME_INDEX(err_missing_comma_before_ellipsis)
+DIAG_NAME_INDEX(err_missing_default_ctor)
+DIAG_NAME_INDEX(err_missing_dependent_template_keyword)
+DIAG_NAME_INDEX(err_missing_end_of_definition)
+DIAG_NAME_INDEX(err_missing_module)
+DIAG_NAME_INDEX(err_missing_module_name)
+DIAG_NAME_INDEX(err_missing_open_square_message_send)
+DIAG_NAME_INDEX(err_missing_param)
+DIAG_NAME_INDEX(err_missing_type_specifier)
+DIAG_NAME_INDEX(err_missing_vfs_overlay_file)
+DIAG_NAME_INDEX(err_missing_whitespace_digraph)
+DIAG_NAME_INDEX(err_mmap_config_macro_submodule)
+DIAG_NAME_INDEX(err_mmap_expected_attribute)
+DIAG_NAME_INDEX(err_mmap_expected_config_macro)
+DIAG_NAME_INDEX(err_mmap_expected_conflicts_comma)
+DIAG_NAME_INDEX(err_mmap_expected_conflicts_message)
+DIAG_NAME_INDEX(err_mmap_expected_export_wildcard)
+DIAG_NAME_INDEX(err_mmap_expected_feature)
+DIAG_NAME_INDEX(err_mmap_expected_header)
+DIAG_NAME_INDEX(err_mmap_expected_inferred_member)
+DIAG_NAME_INDEX(err_mmap_expected_lbrace)
+DIAG_NAME_INDEX(err_mmap_expected_lbrace_wildcard)
+DIAG_NAME_INDEX(err_mmap_expected_library_name)
+DIAG_NAME_INDEX(err_mmap_expected_member)
+DIAG_NAME_INDEX(err_mmap_expected_mmap_file)
+DIAG_NAME_INDEX(err_mmap_expected_module)
+DIAG_NAME_INDEX(err_mmap_expected_module_name)
+DIAG_NAME_INDEX(err_mmap_expected_rbrace)
+DIAG_NAME_INDEX(err_mmap_expected_rsquare)
+DIAG_NAME_INDEX(err_mmap_explicit_inferred_framework)
+DIAG_NAME_INDEX(err_mmap_explicit_top_level)
+DIAG_NAME_INDEX(err_mmap_inferred_framework_submodule)
+DIAG_NAME_INDEX(err_mmap_inferred_no_umbrella)
+DIAG_NAME_INDEX(err_mmap_inferred_redef)
+DIAG_NAME_INDEX(err_mmap_missing_exclude_name)
+DIAG_NAME_INDEX(err_mmap_missing_module_qualified)
+DIAG_NAME_INDEX(err_mmap_missing_module_unqualified)
+DIAG_NAME_INDEX(err_mmap_module_id)
+DIAG_NAME_INDEX(err_mmap_module_redefinition)
+DIAG_NAME_INDEX(err_mmap_nested_submodule_id)
+DIAG_NAME_INDEX(err_mmap_top_level_inferred_submodule)
+DIAG_NAME_INDEX(err_mmap_umbrella_clash)
+DIAG_NAME_INDEX(err_mmap_umbrella_dir_not_found)
+DIAG_NAME_INDEX(err_mmap_unknown_token)
+DIAG_NAME_INDEX(err_mode_not_primitive)
+DIAG_NAME_INDEX(err_mode_wrong_type)
+DIAG_NAME_INDEX(err_module_cannot_create_includes)
+DIAG_NAME_INDEX(err_module_cycle)
+DIAG_NAME_INDEX(err_module_expected_ident)
+DIAG_NAME_INDEX(err_module_expected_semi)
+DIAG_NAME_INDEX(err_module_file_conflict)
+DIAG_NAME_INDEX(err_module_header_missing)
+DIAG_NAME_INDEX(err_module_import_in_extern_c)
+DIAG_NAME_INDEX(err_module_import_not_at_top_level)
+DIAG_NAME_INDEX(err_module_map_not_found)
+DIAG_NAME_INDEX(err_module_not_built)
+DIAG_NAME_INDEX(err_module_not_found)
+DIAG_NAME_INDEX(err_module_odr_violation_different_definitions)
+DIAG_NAME_INDEX(err_module_odr_violation_different_instantiations)
+DIAG_NAME_INDEX(err_module_odr_violation_missing_decl)
+DIAG_NAME_INDEX(err_module_private_declaration)
+DIAG_NAME_INDEX(err_module_private_definition)
+DIAG_NAME_INDEX(err_module_private_local)
+DIAG_NAME_INDEX(err_module_private_local_class)
+DIAG_NAME_INDEX(err_module_private_specialization)
+DIAG_NAME_INDEX(err_module_self_import)
+DIAG_NAME_INDEX(err_module_unavailable)
+DIAG_NAME_INDEX(err_ms___leave_not_in___try)
+DIAG_NAME_INDEX(err_ms_declspec_type)
+DIAG_NAME_INDEX(err_ms_property_duplicate_accessor)
+DIAG_NAME_INDEX(err_ms_property_expected_accessor_name)
+DIAG_NAME_INDEX(err_ms_property_expected_comma_or_rparen)
+DIAG_NAME_INDEX(err_ms_property_expected_equal)
+DIAG_NAME_INDEX(err_ms_property_has_set_accessor)
+DIAG_NAME_INDEX(err_ms_property_missing_accessor_kind)
+DIAG_NAME_INDEX(err_ms_property_no_getter_or_putter)
+DIAG_NAME_INDEX(err_ms_property_unknown_accessor)
+DIAG_NAME_INDEX(err_msasm_unable_to_create_target)
+DIAG_NAME_INDEX(err_msasm_unsupported_arch)
+DIAG_NAME_INDEX(err_mt_message)
+DIAG_NAME_INDEX(err_multichar_utf_character_literal)
+DIAG_NAME_INDEX(err_multiple_base_initialization)
+DIAG_NAME_INDEX(err_multiple_default_labels_defined)
+DIAG_NAME_INDEX(err_multiple_final_overriders)
+DIAG_NAME_INDEX(err_multiple_mem_initialization)
+DIAG_NAME_INDEX(err_multiple_mem_union_initialization)
+DIAG_NAME_INDEX(err_multiple_template_declarators)
+DIAG_NAME_INDEX(err_mutable_const)
+DIAG_NAME_INDEX(err_mutable_function)
+DIAG_NAME_INDEX(err_mutable_nonmember)
+DIAG_NAME_INDEX(err_mutable_reference)
+DIAG_NAME_INDEX(err_namespace_nonnamespace_scope)
+DIAG_NAME_INDEX(err_need_header_before_ms_uuidof)
+DIAG_NAME_INDEX(err_need_header_before_typeid)
+DIAG_NAME_INDEX(err_nested_name_member_ref_lookup_ambiguous)
+DIAG_NAME_INDEX(err_nested_name_spec_is_not_class)
+DIAG_NAME_INDEX(err_nested_name_spec_non_tag)
+DIAG_NAME_INDEX(err_nested_namespaces_with_double_colon)
+DIAG_NAME_INDEX(err_nested_non_static_member_use)
+DIAG_NAME_INDEX(err_nested_redefinition)
+DIAG_NAME_INDEX(err_new_array_init_args)
+DIAG_NAME_INDEX(err_new_array_nonconst)
+DIAG_NAME_INDEX(err_new_array_of_auto)
+DIAG_NAME_INDEX(err_new_incomplete_type)
+DIAG_NAME_INDEX(err_no_accessor_for_property)
+DIAG_NAME_INDEX(err_no_dynamic_cast_with_fno_rtti)
+DIAG_NAME_INDEX(err_no_external_assembler)
+DIAG_NAME_INDEX(err_no_matching_local_friend)
+DIAG_NAME_INDEX(err_no_matching_local_friend_suggest)
+DIAG_NAME_INDEX(err_no_matching_param)
+DIAG_NAME_INDEX(err_no_member)
+DIAG_NAME_INDEX(err_no_member_overloaded_arrow)
+DIAG_NAME_INDEX(err_no_member_suggest)
+DIAG_NAME_INDEX(err_no_member_template_suggest)
+DIAG_NAME_INDEX(err_no_nsconstant_string_class)
+DIAG_NAME_INDEX(err_no_submodule)
+DIAG_NAME_INDEX(err_no_submodule_suggest)
+DIAG_NAME_INDEX(err_no_suitable_delete_member_function_found)
+DIAG_NAME_INDEX(err_no_template_suggest)
+DIAG_NAME_INDEX(err_no_typeid_with_fno_rtti)
+DIAG_NAME_INDEX(err_noexcept_needs_constant_expression)
+DIAG_NAME_INDEX(err_nogetter_property_compound_assignment)
+DIAG_NAME_INDEX(err_nogetter_property_incdec)
+DIAG_NAME_INDEX(err_non_ascii)
+DIAG_NAME_INDEX(err_non_deleted_override)
+DIAG_NAME_INDEX(err_non_extern_extern)
+DIAG_NAME_INDEX(err_non_local_variable_decl_in_for)
+DIAG_NAME_INDEX(err_non_static_static)
+DIAG_NAME_INDEX(err_non_thread_thread)
+DIAG_NAME_INDEX(err_non_type_template_in_nested_name_specifier)
+DIAG_NAME_INDEX(err_non_variable_decl_in_for)
+DIAG_NAME_INDEX(err_non_virtual_pure)
+DIAG_NAME_INDEX(err_nonfunction_block_type)
+DIAG_NAME_INDEX(err_nonstatic_member_out_of_line)
+DIAG_NAME_INDEX(err_noreturn_block_has_return_expr)
+DIAG_NAME_INDEX(err_noreturn_lambda_has_return_expr)
+DIAG_NAME_INDEX(err_noreturn_missing_on_first_decl)
+DIAG_NAME_INDEX(err_noreturn_non_function)
+DIAG_NAME_INDEX(err_nosetter_property_assignment)
+DIAG_NAME_INDEX(err_nosetter_property_incdec)
+DIAG_NAME_INDEX(err_not_a_pch_file)
+DIAG_NAME_INDEX(err_not_class_template_specialization)
+DIAG_NAME_INDEX(err_not_direct_base_or_virtual)
+DIAG_NAME_INDEX(err_not_found_by_two_phase_lookup)
+DIAG_NAME_INDEX(err_not_integral_type_anon_bitfield)
+DIAG_NAME_INDEX(err_not_integral_type_bitfield)
+DIAG_NAME_INDEX(err_not_opencl_storage_class_specifier)
+DIAG_NAME_INDEX(err_not_tag_in_scope)
+DIAG_NAME_INDEX(err_nsconsumed_attribute_mismatch)
+DIAG_NAME_INDEX(err_nsnumber_nonliteral_unary)
+DIAG_NAME_INDEX(err_nsobject_attribute)
+DIAG_NAME_INDEX(err_nsreturns_retained_attribute_mismatch)
+DIAG_NAME_INDEX(err_objc_array_of_interfaces)
+DIAG_NAME_INDEX(err_objc_attr_not_id)
+DIAG_NAME_INDEX(err_objc_attr_protocol_requires_definition)
+DIAG_NAME_INDEX(err_objc_bridged_related_invalid_class)
+DIAG_NAME_INDEX(err_objc_bridged_related_invalid_class_name)
+DIAG_NAME_INDEX(err_objc_bridged_related_known_method)
+DIAG_NAME_INDEX(err_objc_cf_bridged_not_interface)
+DIAG_NAME_INDEX(err_objc_concat_string)
+DIAG_NAME_INDEX(err_objc_decls_may_only_appear_in_global_scope)
+DIAG_NAME_INDEX(err_objc_directive_only_in_protocol)
+DIAG_NAME_INDEX(err_objc_exceptions_disabled)
+DIAG_NAME_INDEX(err_objc_expected_equal_for_getter)
+DIAG_NAME_INDEX(err_objc_expected_equal_for_setter)
+DIAG_NAME_INDEX(err_objc_expected_property_attr)
+DIAG_NAME_INDEX(err_objc_expected_selector_for_getter_setter)
+DIAG_NAME_INDEX(err_objc_illegal_boxed_expression_type)
+DIAG_NAME_INDEX(err_objc_illegal_interface_qual)
+DIAG_NAME_INDEX(err_objc_illegal_visibility_spec)
+DIAG_NAME_INDEX(err_objc_incomplete_boxed_expression_type)
+DIAG_NAME_INDEX(err_objc_index_incomplete_class_type)
+DIAG_NAME_INDEX(err_objc_indexing_method_result_type)
+DIAG_NAME_INDEX(err_objc_literal_method_sig)
+DIAG_NAME_INDEX(err_objc_missing_end)
+DIAG_NAME_INDEX(err_objc_multiple_subscript_type_conversion)
+DIAG_NAME_INDEX(err_objc_no_attributes_on_category)
+DIAG_NAME_INDEX(err_objc_ns_bridged_invalid_cfobject)
+DIAG_NAME_INDEX(err_objc_object_assignment)
+DIAG_NAME_INDEX(err_objc_object_catch)
+DIAG_NAME_INDEX(err_objc_postfix_attribute)
+DIAG_NAME_INDEX(err_objc_postfix_attribute_hint)
+DIAG_NAME_INDEX(err_objc_precise_lifetime_bad_type)
+DIAG_NAME_INDEX(err_objc_properties_require_objc2)
+DIAG_NAME_INDEX(err_objc_property_attr_mutually_exclusive)
+DIAG_NAME_INDEX(err_objc_property_bitfield)
+DIAG_NAME_INDEX(err_objc_property_requires_field_name)
+DIAG_NAME_INDEX(err_objc_property_requires_object)
+DIAG_NAME_INDEX(err_objc_root_class_subclass)
+DIAG_NAME_INDEX(err_objc_subscript_base_type)
+DIAG_NAME_INDEX(err_objc_subscript_dic_object_type)
+DIAG_NAME_INDEX(err_objc_subscript_index_type)
+DIAG_NAME_INDEX(err_objc_subscript_key_type)
+DIAG_NAME_INDEX(err_objc_subscript_method_not_found)
+DIAG_NAME_INDEX(err_objc_subscript_object_type)
+DIAG_NAME_INDEX(err_objc_subscript_pointer)
+DIAG_NAME_INDEX(err_objc_subscript_type_conversion)
+DIAG_NAME_INDEX(err_objc_unexpected_atend)
+DIAG_NAME_INDEX(err_objc_unexpected_attr)
+DIAG_NAME_INDEX(err_objc_unknown_at)
+DIAG_NAME_INDEX(err_objc_var_decl_inclass)
+DIAG_NAME_INDEX(err_objcbridge_related_expected_related_class)
+DIAG_NAME_INDEX(err_objcbridge_related_selector_name)
+DIAG_NAME_INDEX(err_object_cannot_be_passed_returned_by_value)
+DIAG_NAME_INDEX(err_octal_escape_too_large)
+DIAG_NAME_INDEX(err_odr_different_num_template_parameters)
+DIAG_NAME_INDEX(err_odr_different_template_parameter_kind)
+DIAG_NAME_INDEX(err_odr_field_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_function_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_ivar_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_non_type_parameter_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_method_num_params_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_method_param_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_method_result_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_method_variadic_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_property_impl_kind_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_property_type_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_superclass_inconsistent)
+DIAG_NAME_INDEX(err_odr_objc_synthesize_ivar_inconsistent)
+DIAG_NAME_INDEX(err_odr_parameter_pack_non_pack)
+DIAG_NAME_INDEX(err_odr_variable_multiple_def)
+DIAG_NAME_INDEX(err_odr_variable_type_inconsistent)
+DIAG_NAME_INDEX(err_offsetof_array_type)
+DIAG_NAME_INDEX(err_offsetof_bitfield)
+DIAG_NAME_INDEX(err_offsetof_field_of_virtual_base)
+DIAG_NAME_INDEX(err_offsetof_incomplete_type)
+DIAG_NAME_INDEX(err_offsetof_record_type)
+DIAG_NAME_INDEX(err_omp_aligned_expected_array_or_ptr)
+DIAG_NAME_INDEX(err_omp_aligned_twice)
+DIAG_NAME_INDEX(err_omp_ambiguous_conversion)
+DIAG_NAME_INDEX(err_omp_clause_floating_type_arg)
+DIAG_NAME_INDEX(err_omp_clause_not_arithmetic_type_arg)
+DIAG_NAME_INDEX(err_omp_clause_ref_type_arg)
+DIAG_NAME_INDEX(err_omp_const_variable)
+DIAG_NAME_INDEX(err_omp_expected_identifier_for_critical)
+DIAG_NAME_INDEX(err_omp_expected_punc)
+DIAG_NAME_INDEX(err_omp_expected_var_arg)
+DIAG_NAME_INDEX(err_omp_expected_var_arg_suggest)
+DIAG_NAME_INDEX(err_omp_expected_var_name)
+DIAG_NAME_INDEX(err_omp_explicit_conversion)
+DIAG_NAME_INDEX(err_omp_firstprivate_incomplete_type)
+DIAG_NAME_INDEX(err_omp_global_var_arg)
+DIAG_NAME_INDEX(err_omp_immediate_directive)
+DIAG_NAME_INDEX(err_omp_incomplete_type)
+DIAG_NAME_INDEX(err_omp_lastprivate_incomplete_type)
+DIAG_NAME_INDEX(err_omp_linear_expected_int_or_ptr)
+DIAG_NAME_INDEX(err_omp_linear_incomplete_type)
+DIAG_NAME_INDEX(err_omp_local_var_in_threadprivate_init)
+DIAG_NAME_INDEX(err_omp_loop_cannot_use_stmt)
+DIAG_NAME_INDEX(err_omp_loop_incr_not_compatible)
+DIAG_NAME_INDEX(err_omp_loop_not_canonical_cond)
+DIAG_NAME_INDEX(err_omp_loop_not_canonical_incr)
+DIAG_NAME_INDEX(err_omp_loop_not_canonical_init)
+DIAG_NAME_INDEX(err_omp_loop_var_dsa)
+DIAG_NAME_INDEX(err_omp_loop_variable_type)
+DIAG_NAME_INDEX(err_omp_more_one_clause)
+DIAG_NAME_INDEX(err_omp_negative_expression_in_clause)
+DIAG_NAME_INDEX(err_omp_no_dsa_for_variable)
+DIAG_NAME_INDEX(err_omp_not_for)
+DIAG_NAME_INDEX(err_omp_not_integral)
+DIAG_NAME_INDEX(err_omp_once_referenced)
+DIAG_NAME_INDEX(err_omp_orphaned_section_directive)
+DIAG_NAME_INDEX(err_omp_parallel_reduction_in_task_firstprivate)
+DIAG_NAME_INDEX(err_omp_parallel_sections_not_compound_stmt)
+DIAG_NAME_INDEX(err_omp_parallel_sections_substmt_not_section)
+DIAG_NAME_INDEX(err_omp_private_incomplete_type)
+DIAG_NAME_INDEX(err_omp_prohibited_region)
+DIAG_NAME_INDEX(err_omp_prohibited_region_critical_same_name)
+DIAG_NAME_INDEX(err_omp_prohibited_region_simd)
+DIAG_NAME_INDEX(err_omp_reduction_id_not_compatible)
+DIAG_NAME_INDEX(err_omp_reduction_in_task)
+DIAG_NAME_INDEX(err_omp_reduction_incomplete_type)
+DIAG_NAME_INDEX(err_omp_reduction_ref_type_arg)
+DIAG_NAME_INDEX(err_omp_reduction_type_array)
+DIAG_NAME_INDEX(err_omp_ref_type_arg)
+DIAG_NAME_INDEX(err_omp_required_access)
+DIAG_NAME_INDEX(err_omp_required_method)
+DIAG_NAME_INDEX(err_omp_sections_not_compound_stmt)
+DIAG_NAME_INDEX(err_omp_sections_substmt_not_section)
+DIAG_NAME_INDEX(err_omp_simd_region_cannot_use_stmt)
+DIAG_NAME_INDEX(err_omp_task_predetermined_firstprivate_ref_type_arg)
+DIAG_NAME_INDEX(err_omp_task_predetermined_firstprivate_required_method)
+DIAG_NAME_INDEX(err_omp_threadprivate_incomplete_type)
+DIAG_NAME_INDEX(err_omp_unexpected_clause)
+DIAG_NAME_INDEX(err_omp_unexpected_clause_value)
+DIAG_NAME_INDEX(err_omp_unexpected_directive)
+DIAG_NAME_INDEX(err_omp_unknown_directive)
+DIAG_NAME_INDEX(err_omp_unknown_reduction_identifier)
+DIAG_NAME_INDEX(err_omp_var_scope)
+DIAG_NAME_INDEX(err_omp_var_thread_local)
+DIAG_NAME_INDEX(err_omp_var_used)
+DIAG_NAME_INDEX(err_omp_wrong_dsa)
+DIAG_NAME_INDEX(err_only_annotate_after_access_spec)
+DIAG_NAME_INDEX(err_only_constructors_take_base_inits)
+DIAG_NAME_INDEX(err_only_enums_have_underlying_types)
+DIAG_NAME_INDEX(err_opencl_bitfields)
+DIAG_NAME_INDEX(err_opencl_cast_to_half)
+DIAG_NAME_INDEX(err_opencl_constant_no_init)
+DIAG_NAME_INDEX(err_opencl_function_pointer_variable)
+DIAG_NAME_INDEX(err_opencl_global_invalid_addr_space)
+DIAG_NAME_INDEX(err_opencl_half_declaration)
+DIAG_NAME_INDEX(err_opencl_half_load_store)
+DIAG_NAME_INDEX(err_opencl_half_param)
+DIAG_NAME_INDEX(err_opencl_half_return)
+DIAG_NAME_INDEX(err_opencl_kernel_attr)
+DIAG_NAME_INDEX(err_opencl_no_main)
+DIAG_NAME_INDEX(err_opencl_private_ptr_kernel_param)
+DIAG_NAME_INDEX(err_opencl_ptrptr_kernel_param)
+DIAG_NAME_INDEX(err_opencl_return_value_with_address_space)
+DIAG_NAME_INDEX(err_opencl_sizeof_alignof_type)
+DIAG_NAME_INDEX(err_opencl_taking_function_address)
+DIAG_NAME_INDEX(err_opencl_vla)
+DIAG_NAME_INDEX(err_operator_arrow_circular)
+DIAG_NAME_INDEX(err_operator_arrow_depth_exceeded)
+DIAG_NAME_INDEX(err_operator_delete_dependent_param_type)
+DIAG_NAME_INDEX(err_operator_delete_param_type)
+DIAG_NAME_INDEX(err_operator_new_default_arg)
+DIAG_NAME_INDEX(err_operator_new_delete_declared_in_namespace)
+DIAG_NAME_INDEX(err_operator_new_delete_declared_static)
+DIAG_NAME_INDEX(err_operator_new_delete_dependent_result_type)
+DIAG_NAME_INDEX(err_operator_new_delete_invalid_result_type)
+DIAG_NAME_INDEX(err_operator_new_delete_template_too_few_parameters)
+DIAG_NAME_INDEX(err_operator_new_delete_too_few_parameters)
+DIAG_NAME_INDEX(err_operator_new_dependent_param_type)
+DIAG_NAME_INDEX(err_operator_new_param_type)
+DIAG_NAME_INDEX(err_operator_overload_default_arg)
+DIAG_NAME_INDEX(err_operator_overload_must_be)
+DIAG_NAME_INDEX(err_operator_overload_must_be_member)
+DIAG_NAME_INDEX(err_operator_overload_needs_class_or_enum)
+DIAG_NAME_INDEX(err_operator_overload_post_incdec_must_be_int)
+DIAG_NAME_INDEX(err_operator_overload_static)
+DIAG_NAME_INDEX(err_operator_overload_variadic)
+DIAG_NAME_INDEX(err_out_of_line_constructor_template_id)
+DIAG_NAME_INDEX(err_out_of_line_default_deletes)
+DIAG_NAME_INDEX(err_out_of_line_template_id_names_constructor)
+DIAG_NAME_INDEX(err_out_of_line_type_names_constructor)
+DIAG_NAME_INDEX(err_override_control_interface)
+DIAG_NAME_INDEX(err_override_exception_spec)
+DIAG_NAME_INDEX(err_ovl_ambiguous_call)
+DIAG_NAME_INDEX(err_ovl_ambiguous_conversion_in_cast)
+DIAG_NAME_INDEX(err_ovl_ambiguous_init)
+DIAG_NAME_INDEX(err_ovl_ambiguous_member_call)
+DIAG_NAME_INDEX(err_ovl_ambiguous_object_call)
+DIAG_NAME_INDEX(err_ovl_ambiguous_oper_binary)
+DIAG_NAME_INDEX(err_ovl_ambiguous_oper_unary)
+DIAG_NAME_INDEX(err_ovl_deleted_call)
+DIAG_NAME_INDEX(err_ovl_deleted_conversion_in_cast)
+DIAG_NAME_INDEX(err_ovl_deleted_init)
+DIAG_NAME_INDEX(err_ovl_deleted_member_call)
+DIAG_NAME_INDEX(err_ovl_deleted_object_call)
+DIAG_NAME_INDEX(err_ovl_deleted_oper)
+DIAG_NAME_INDEX(err_ovl_deleted_special_init)
+DIAG_NAME_INDEX(err_ovl_deleted_special_oper)
+DIAG_NAME_INDEX(err_ovl_diff_return_type)
+DIAG_NAME_INDEX(err_ovl_no_conversion_in_cast)
+DIAG_NAME_INDEX(err_ovl_no_oper)
+DIAG_NAME_INDEX(err_ovl_no_viable_conversion_in_cast)
+DIAG_NAME_INDEX(err_ovl_no_viable_function_in_call)
+DIAG_NAME_INDEX(err_ovl_no_viable_function_in_init)
+DIAG_NAME_INDEX(err_ovl_no_viable_literal_operator)
+DIAG_NAME_INDEX(err_ovl_no_viable_member_function_in_call)
+DIAG_NAME_INDEX(err_ovl_no_viable_object_call)
+DIAG_NAME_INDEX(err_ovl_no_viable_oper)
+DIAG_NAME_INDEX(err_ovl_no_viable_subscript)
+DIAG_NAME_INDEX(err_ovl_static_nonstatic_member)
+DIAG_NAME_INDEX(err_ovl_unresolvable)
+DIAG_NAME_INDEX(err_ownership_type)
+DIAG_NAME_INDEX(err_pack_expansion_length_conflict)
+DIAG_NAME_INDEX(err_pack_expansion_length_conflict_multilevel)
+DIAG_NAME_INDEX(err_pack_expansion_member_init)
+DIAG_NAME_INDEX(err_pack_expansion_without_parameter_packs)
+DIAG_NAME_INDEX(err_param_default_argument)
+DIAG_NAME_INDEX(err_param_default_argument_member_template_redecl)
+DIAG_NAME_INDEX(err_param_default_argument_missing)
+DIAG_NAME_INDEX(err_param_default_argument_missing_name)
+DIAG_NAME_INDEX(err_param_default_argument_nonfunc)
+DIAG_NAME_INDEX(err_param_default_argument_redefinition)
+DIAG_NAME_INDEX(err_param_default_argument_references_local)
+DIAG_NAME_INDEX(err_param_default_argument_references_param)
+DIAG_NAME_INDEX(err_param_default_argument_references_this)
+DIAG_NAME_INDEX(err_param_default_argument_template_redecl)
+DIAG_NAME_INDEX(err_param_redefinition)
+DIAG_NAME_INDEX(err_param_with_void_type)
+DIAG_NAME_INDEX(err_parameter_name_omitted)
+DIAG_NAME_INDEX(err_parameters_retval_cannot_have_fp16_type)
+DIAG_NAME_INDEX(err_paren_after_colon_colon)
+DIAG_NAME_INDEX(err_paren_sizeof_parameter_pack)
+DIAG_NAME_INDEX(err_parens_pointer_member_function)
+DIAG_NAME_INDEX(err_partial_spec_args_match_primary_template)
+DIAG_NAME_INDEX(err_partial_spec_fully_specialized)
+DIAG_NAME_INDEX(err_partial_spec_ordering_ambiguous)
+DIAG_NAME_INDEX(err_partial_spec_redeclared)
+DIAG_NAME_INDEX(err_partial_specialization_friend)
+DIAG_NAME_INDEX(err_pascal_string_too_long)
+DIAG_NAME_INDEX(err_paste_at_end)
+DIAG_NAME_INDEX(err_paste_at_start)
+DIAG_NAME_INDEX(err_pch_diagopt_mismatch)
+DIAG_NAME_INDEX(err_pch_different_branch)
+DIAG_NAME_INDEX(err_pch_langopt_mismatch)
+DIAG_NAME_INDEX(err_pch_langopt_value_mismatch)
+DIAG_NAME_INDEX(err_pch_macro_def_conflict)
+DIAG_NAME_INDEX(err_pch_macro_def_undef)
+DIAG_NAME_INDEX(err_pch_pp_detailed_record)
+DIAG_NAME_INDEX(err_pch_targetopt_feature_mismatch)
+DIAG_NAME_INDEX(err_pch_targetopt_mismatch)
+DIAG_NAME_INDEX(err_pch_undef)
+DIAG_NAME_INDEX(err_pch_version_too_new)
+DIAG_NAME_INDEX(err_pch_version_too_old)
+DIAG_NAME_INDEX(err_pch_with_compiler_errors)
+DIAG_NAME_INDEX(err_placement_new_non_placement_delete)
+DIAG_NAME_INDEX(err_pointer_to_member_call_drops_quals)
+DIAG_NAME_INDEX(err_pointer_to_member_oper_value_classify)
+DIAG_NAME_INDEX(err_pointer_to_member_type)
+DIAG_NAME_INDEX(err_pp_arc_cf_code_audited_syntax)
+DIAG_NAME_INDEX(err_pp_bad_paste)
+DIAG_NAME_INDEX(err_pp_colon_without_question)
+DIAG_NAME_INDEX(err_pp_directive_required)
+DIAG_NAME_INDEX(err_pp_division_by_zero)
+DIAG_NAME_INDEX(err_pp_double_begin_of_arc_cf_code_audited)
+DIAG_NAME_INDEX(err_pp_duplicate_name_in_arg_list)
+DIAG_NAME_INDEX(err_pp_empty_filename)
+DIAG_NAME_INDEX(err_pp_endif_without_if)
+DIAG_NAME_INDEX(err_pp_eof_in_arc_cf_code_audited)
+DIAG_NAME_INDEX(err_pp_error_opening_file)
+DIAG_NAME_INDEX(err_pp_expected_after)
+DIAG_NAME_INDEX(err_pp_expected_comma_in_arg_list)
+DIAG_NAME_INDEX(err_pp_expected_eol)
+DIAG_NAME_INDEX(err_pp_expected_ident_in_arg_list)
+DIAG_NAME_INDEX(err_pp_expected_rparen)
+DIAG_NAME_INDEX(err_pp_expected_value_in_expr)
+DIAG_NAME_INDEX(err_pp_expects_filename)
+DIAG_NAME_INDEX(err_pp_expr_bad_token_binop)
+DIAG_NAME_INDEX(err_pp_expr_bad_token_start_expr)
+DIAG_NAME_INDEX(err_pp_file_not_found)
+DIAG_NAME_INDEX(err_pp_file_not_found_not_fatal)
+DIAG_NAME_INDEX(err_pp_hash_error)
+DIAG_NAME_INDEX(err_pp_identifier_arg_not_identifier)
+DIAG_NAME_INDEX(err_pp_illegal_floating_literal)
+DIAG_NAME_INDEX(err_pp_import_directive_ms)
+DIAG_NAME_INDEX(err_pp_include_in_arc_cf_code_audited)
+DIAG_NAME_INDEX(err_pp_include_too_deep)
+DIAG_NAME_INDEX(err_pp_invalid_directive)
+DIAG_NAME_INDEX(err_pp_invalid_poison)
+DIAG_NAME_INDEX(err_pp_invalid_tok_in_arg_list)
+DIAG_NAME_INDEX(err_pp_invalid_udl)
+DIAG_NAME_INDEX(err_pp_line_digit_sequence)
+DIAG_NAME_INDEX(err_pp_line_invalid_filename)
+DIAG_NAME_INDEX(err_pp_line_requires_integer)
+DIAG_NAME_INDEX(err_pp_linemarker_invalid_filename)
+DIAG_NAME_INDEX(err_pp_linemarker_invalid_flag)
+DIAG_NAME_INDEX(err_pp_linemarker_invalid_pop)
+DIAG_NAME_INDEX(err_pp_linemarker_requires_integer)
+DIAG_NAME_INDEX(err_pp_macro_not_identifier)
+DIAG_NAME_INDEX(err_pp_malformed_ident)
+DIAG_NAME_INDEX(err_pp_missing_macro_name)
+DIAG_NAME_INDEX(err_pp_missing_rparen_in_macro_def)
+DIAG_NAME_INDEX(err_pp_opencl_variadic_macros)
+DIAG_NAME_INDEX(err_pp_operator_used_as_macro_name)
+DIAG_NAME_INDEX(err_pp_remainder_by_zero)
+DIAG_NAME_INDEX(err_pp_stringize_not_parameter)
+DIAG_NAME_INDEX(err_pp_unmatched_end_of_arc_cf_code_audited)
+DIAG_NAME_INDEX(err_pp_unterminated_conditional)
+DIAG_NAME_INDEX(err_pp_used_poisoned_id)
+DIAG_NAME_INDEX(err_pp_visibility_non_macro)
+DIAG_NAME_INDEX(err_pragma_comment_malformed)
+DIAG_NAME_INDEX(err_pragma_comment_unknown_kind)
+DIAG_NAME_INDEX(err_pragma_detect_mismatch_malformed)
+DIAG_NAME_INDEX(err_pragma_fp_contract_scope)
+DIAG_NAME_INDEX(err_pragma_loop_compatibility)
+DIAG_NAME_INDEX(err_pragma_loop_invalid_keyword)
+DIAG_NAME_INDEX(err_pragma_loop_invalid_option)
+DIAG_NAME_INDEX(err_pragma_loop_invalid_value)
+DIAG_NAME_INDEX(err_pragma_loop_precedes_nonloop)
+DIAG_NAME_INDEX(err_pragma_message)
+DIAG_NAME_INDEX(err_pragma_message_malformed)
+DIAG_NAME_INDEX(err_pragma_missing_argument)
+DIAG_NAME_INDEX(err_pragma_optimize_extra_argument)
+DIAG_NAME_INDEX(err_pragma_optimize_invalid_argument)
+DIAG_NAME_INDEX(err_pragma_options_align_mac68k_target_unsupported)
+DIAG_NAME_INDEX(err_pragma_pointers_to_members_unknown_kind)
+DIAG_NAME_INDEX(err_pragma_pop_visibility_mismatch)
+DIAG_NAME_INDEX(err_pragma_push_pop_macro_malformed)
+DIAG_NAME_INDEX(err_pragma_push_visibility_mismatch)
+DIAG_NAME_INDEX(err_property_found_suggest)
+DIAG_NAME_INDEX(err_property_function_in_objc_container)
+DIAG_NAME_INDEX(err_property_is_variably_modified)
+DIAG_NAME_INDEX(err_property_method_unavailable)
+DIAG_NAME_INDEX(err_property_not_as_forward_class)
+DIAG_NAME_INDEX(err_property_not_found)
+DIAG_NAME_INDEX(err_property_not_found_forward_class)
+DIAG_NAME_INDEX(err_property_not_found_suggest)
+DIAG_NAME_INDEX(err_property_type)
+DIAG_NAME_INDEX(err_protocol_has_circular_dependency)
+DIAG_NAME_INDEX(err_pseudo_dtor_base_not_scalar)
+DIAG_NAME_INDEX(err_pseudo_dtor_call_with_args)
+DIAG_NAME_INDEX(err_pseudo_dtor_destructor_non_type)
+DIAG_NAME_INDEX(err_pseudo_dtor_type_mismatch)
+DIAG_NAME_INDEX(err_qualified_catch_declarator)
+DIAG_NAME_INDEX(err_qualified_friend_def)
+DIAG_NAME_INDEX(err_qualified_friend_not_found)
+DIAG_NAME_INDEX(err_qualified_member_nonclass)
+DIAG_NAME_INDEX(err_qualified_member_of_unrelated)
+DIAG_NAME_INDEX(err_qualified_objc_access)
+DIAG_NAME_INDEX(err_qualified_objc_catch_parm)
+DIAG_NAME_INDEX(err_qualified_param_declarator)
+DIAG_NAME_INDEX(err_qualified_typedef_declarator)
+DIAG_NAME_INDEX(err_range_on_array_parameter)
+DIAG_NAME_INDEX(err_raw_delim_too_long)
+DIAG_NAME_INDEX(err_realimag_invalid_type)
+DIAG_NAME_INDEX(err_record_with_pointers_kernel_param)
+DIAG_NAME_INDEX(err_recursive_superclass)
+DIAG_NAME_INDEX(err_redefinition)
+DIAG_NAME_INDEX(err_redefinition_different_kind)
+DIAG_NAME_INDEX(err_redefinition_different_type)
+DIAG_NAME_INDEX(err_redefinition_different_typedef)
+DIAG_NAME_INDEX(err_redefinition_extern_inline)
+DIAG_NAME_INDEX(err_redefinition_of_enumerator)
+DIAG_NAME_INDEX(err_redefinition_of_label)
+DIAG_NAME_INDEX(err_redefinition_variably_modified_typedef)
+DIAG_NAME_INDEX(err_ref_array_type)
+DIAG_NAME_INDEX(err_ref_bad_target)
+DIAG_NAME_INDEX(err_ref_flexarray_type)
+DIAG_NAME_INDEX(err_ref_init_ambiguous)
+DIAG_NAME_INDEX(err_ref_non_value)
+DIAG_NAME_INDEX(err_ref_qualifier_constructor)
+DIAG_NAME_INDEX(err_ref_qualifier_destructor)
+DIAG_NAME_INDEX(err_ref_qualifier_overload)
+DIAG_NAME_INDEX(err_ref_vm_type)
+DIAG_NAME_INDEX(err_reference_bind_drops_quals)
+DIAG_NAME_INDEX(err_reference_bind_failed)
+DIAG_NAME_INDEX(err_reference_bind_init_list)
+DIAG_NAME_INDEX(err_reference_bind_to_bitfield)
+DIAG_NAME_INDEX(err_reference_bind_to_vector_element)
+DIAG_NAME_INDEX(err_reference_capture_with_reference_default)
+DIAG_NAME_INDEX(err_reference_has_multiple_inits)
+DIAG_NAME_INDEX(err_reference_to_local_var_in_enclosing_block)
+DIAG_NAME_INDEX(err_reference_to_local_var_in_enclosing_context)
+DIAG_NAME_INDEX(err_reference_to_local_var_in_enclosing_function)
+DIAG_NAME_INDEX(err_reference_to_local_var_in_enclosing_lambda)
+DIAG_NAME_INDEX(err_reference_to_void)
+DIAG_NAME_INDEX(err_reference_var_requires_init)
+DIAG_NAME_INDEX(err_reference_without_init)
+DIAG_NAME_INDEX(err_regparm_mismatch)
+DIAG_NAME_INDEX(err_relocatable_without_isysroot)
+DIAG_NAME_INDEX(err_repeat_attribute)
+DIAG_NAME_INDEX(err_ret_local_block)
+DIAG_NAME_INDEX(err_return_block_has_expr)
+DIAG_NAME_INDEX(err_return_in_captured_stmt)
+DIAG_NAME_INDEX(err_return_in_constructor_handler)
+DIAG_NAME_INDEX(err_return_init_list)
+DIAG_NAME_INDEX(err_returns_retained_mismatch)
+DIAG_NAME_INDEX(err_right_angle_bracket_equal_needs_space)
+DIAG_NAME_INDEX(err_rref_in_exception_spec)
+DIAG_NAME_INDEX(err_sampler_argument_required)
+DIAG_NAME_INDEX(err_scoped_enum_missing_identifier)
+DIAG_NAME_INDEX(err_second_parameter_to_va_arg_abstract)
+DIAG_NAME_INDEX(err_second_parameter_to_va_arg_incomplete)
+DIAG_NAME_INDEX(err_section_conflict)
+DIAG_NAME_INDEX(err_seh___except_block)
+DIAG_NAME_INDEX(err_seh___except_filter)
+DIAG_NAME_INDEX(err_seh___finally_block)
+DIAG_NAME_INDEX(err_seh_expected_handler)
+DIAG_NAME_INDEX(err_selected_explicit_constructor)
+DIAG_NAME_INDEX(err_selector_element_const_type)
+DIAG_NAME_INDEX(err_selector_element_not_lvalue)
+DIAG_NAME_INDEX(err_selector_element_type)
+DIAG_NAME_INDEX(err_setter_type_void)
+DIAG_NAME_INDEX(err_shufflevector_argument_too_large)
+DIAG_NAME_INDEX(err_shufflevector_incompatible_vector)
+DIAG_NAME_INDEX(err_shufflevector_non_vector)
+DIAG_NAME_INDEX(err_shufflevector_nonconstant_argument)
+DIAG_NAME_INDEX(err_single_decl_assign_in_for_range)
+DIAG_NAME_INDEX(err_sizeof_alignof_bitfield)
+DIAG_NAME_INDEX(err_sizeof_alignof_function_type)
+DIAG_NAME_INDEX(err_sizeof_alignof_incomplete_type)
+DIAG_NAME_INDEX(err_sizeof_nonfragile_interface)
+DIAG_NAME_INDEX(err_sizeof_pack_no_pack_name)
+DIAG_NAME_INDEX(err_sizeof_pack_no_pack_name_suggest)
+DIAG_NAME_INDEX(err_sizeof_parameter_pack)
+DIAG_NAME_INDEX(err_spec_member_not_instantiated)
+DIAG_NAME_INDEX(err_specialization_after_instantiation)
+DIAG_NAME_INDEX(err_specialize_member_of_template)
+DIAG_NAME_INDEX(err_standalone_class_nested_name_specifier)
+DIAG_NAME_INDEX(err_static_assert_expression_is_not_constant)
+DIAG_NAME_INDEX(err_static_assert_failed)
+DIAG_NAME_INDEX(err_static_block_func)
+DIAG_NAME_INDEX(err_static_data_member_not_allowed_in_anon_struct)
+DIAG_NAME_INDEX(err_static_data_member_not_allowed_in_local_class)
+DIAG_NAME_INDEX(err_static_data_member_reinitialization)
+DIAG_NAME_INDEX(err_static_downcast_via_virtual)
+DIAG_NAME_INDEX(err_static_function_scope)
+DIAG_NAME_INDEX(err_static_illegal_in_new)
+DIAG_NAME_INDEX(err_static_kernel)
+DIAG_NAME_INDEX(err_static_main)
+DIAG_NAME_INDEX(err_static_non_static)
+DIAG_NAME_INDEX(err_static_not_bitfield)
+DIAG_NAME_INDEX(err_static_out_of_line)
+DIAG_NAME_INDEX(err_static_overrides_virtual)
+DIAG_NAME_INDEX(err_statically_allocated_object)
+DIAG_NAME_INDEX(err_stmtexpr_file_scope)
+DIAG_NAME_INDEX(err_storage_class_for_static_member)
+DIAG_NAME_INDEX(err_storage_spec_on_catch_parm)
+DIAG_NAME_INDEX(err_storageclass_invalid_for_member)
+DIAG_NAME_INDEX(err_string_concat_mixed_suffix)
+DIAG_NAME_INDEX(err_subscript_function_type)
+DIAG_NAME_INDEX(err_subscript_incomplete_type)
+DIAG_NAME_INDEX(err_subscript_nonfragile_interface)
+DIAG_NAME_INDEX(err_switch_explicit_conversion)
+DIAG_NAME_INDEX(err_switch_incomplete_class_type)
+DIAG_NAME_INDEX(err_switch_into_protected_scope)
+DIAG_NAME_INDEX(err_switch_multiple_conversions)
+DIAG_NAME_INDEX(err_synthesized_property_name)
+DIAG_NAME_INDEX(err_tag_definition_of_typedef)
+DIAG_NAME_INDEX(err_tag_reference_conflict)
+DIAG_NAME_INDEX(err_tag_reference_non_tag)
+DIAG_NAME_INDEX(err_tagless_friend_type_template)
+DIAG_NAME_INDEX(err_target_unknown_abi)
+DIAG_NAME_INDEX(err_target_unknown_cpu)
+DIAG_NAME_INDEX(err_target_unknown_fpmath)
+DIAG_NAME_INDEX(err_target_unknown_triple)
+DIAG_NAME_INDEX(err_target_unsupported_arch)
+DIAG_NAME_INDEX(err_target_unsupported_fpmath)
+DIAG_NAME_INDEX(err_temp_copy_ambiguous)
+DIAG_NAME_INDEX(err_temp_copy_deleted)
+DIAG_NAME_INDEX(err_temp_copy_incomplete)
+DIAG_NAME_INDEX(err_temp_copy_no_viable)
+DIAG_NAME_INDEX(err_template_arg_address_of_non_pointer)
+DIAG_NAME_INDEX(err_template_arg_field)
+DIAG_NAME_INDEX(err_template_arg_list_different_arity)
+DIAG_NAME_INDEX(err_template_arg_method)
+DIAG_NAME_INDEX(err_template_arg_must_be_expr)
+DIAG_NAME_INDEX(err_template_arg_must_be_template)
+DIAG_NAME_INDEX(err_template_arg_must_be_type)
+DIAG_NAME_INDEX(err_template_arg_must_be_type_suggest)
+DIAG_NAME_INDEX(err_template_arg_no_ref_bind)
+DIAG_NAME_INDEX(err_template_arg_nontype_ambig)
+DIAG_NAME_INDEX(err_template_arg_not_address_constant)
+DIAG_NAME_INDEX(err_template_arg_not_address_of)
+DIAG_NAME_INDEX(err_template_arg_not_class_template)
+DIAG_NAME_INDEX(err_template_arg_not_convertible)
+DIAG_NAME_INDEX(err_template_arg_not_decl_ref)
+DIAG_NAME_INDEX(err_template_arg_not_ice)
+DIAG_NAME_INDEX(err_template_arg_not_integral_or_enumeral)
+DIAG_NAME_INDEX(err_template_arg_not_object_or_func)
+DIAG_NAME_INDEX(err_template_arg_not_pointer_to_member_form)
+DIAG_NAME_INDEX(err_template_arg_object_no_linkage)
+DIAG_NAME_INDEX(err_template_arg_overload_type)
+DIAG_NAME_INDEX(err_template_arg_ref_bind_ignores_quals)
+DIAG_NAME_INDEX(err_template_arg_reference_var)
+DIAG_NAME_INDEX(err_template_arg_template_params_mismatch)
+DIAG_NAME_INDEX(err_template_arg_thread_local)
+DIAG_NAME_INDEX(err_template_arg_untyped_null_constant)
+DIAG_NAME_INDEX(err_template_arg_wrongtype_null_constant)
+DIAG_NAME_INDEX(err_template_decl_ref)
+DIAG_NAME_INDEX(err_template_defn_explicit_instantiation)
+DIAG_NAME_INDEX(err_template_id_not_a_type)
+DIAG_NAME_INDEX(err_template_inside_local_class)
+DIAG_NAME_INDEX(err_template_instantiate_undefined)
+DIAG_NAME_INDEX(err_template_instantiate_within_definition)
+DIAG_NAME_INDEX(err_template_kw_missing)
+DIAG_NAME_INDEX(err_template_kw_refers_to_class_template)
+DIAG_NAME_INDEX(err_template_kw_refers_to_non_template)
+DIAG_NAME_INDEX(err_template_linkage)
+DIAG_NAME_INDEX(err_template_member)
+DIAG_NAME_INDEX(err_template_member_noparams)
+DIAG_NAME_INDEX(err_template_missing_args)
+DIAG_NAME_INDEX(err_template_nontype_parm_bad_type)
+DIAG_NAME_INDEX(err_template_nontype_parm_different_type)
+DIAG_NAME_INDEX(err_template_outside_namespace_or_class_scope)
+DIAG_NAME_INDEX(err_template_param_default_arg_missing)
+DIAG_NAME_INDEX(err_template_param_default_arg_redefinition)
+DIAG_NAME_INDEX(err_template_param_different_kind)
+DIAG_NAME_INDEX(err_template_param_list_different_arity)
+DIAG_NAME_INDEX(err_template_param_list_matches_nontemplate)
+DIAG_NAME_INDEX(err_template_param_pack_default_arg)
+DIAG_NAME_INDEX(err_template_param_pack_must_be_last_template_parameter)
+DIAG_NAME_INDEX(err_template_param_shadow)
+DIAG_NAME_INDEX(err_template_parameter_default_friend_template)
+DIAG_NAME_INDEX(err_template_parameter_default_template_member)
+DIAG_NAME_INDEX(err_template_parameter_pack_non_pack)
+DIAG_NAME_INDEX(err_template_qualified_declarator_no_match)
+DIAG_NAME_INDEX(err_template_recursion_depth_exceeded)
+DIAG_NAME_INDEX(err_template_spec_decl_class_scope)
+DIAG_NAME_INDEX(err_template_spec_decl_friend)
+DIAG_NAME_INDEX(err_template_spec_decl_function_scope)
+DIAG_NAME_INDEX(err_template_spec_decl_out_of_scope)
+DIAG_NAME_INDEX(err_template_spec_decl_out_of_scope_global)
+DIAG_NAME_INDEX(err_template_spec_default_arg)
+DIAG_NAME_INDEX(err_template_spec_extra_headers)
+DIAG_NAME_INDEX(err_template_spec_friend)
+DIAG_NAME_INDEX(err_template_spec_needs_header)
+DIAG_NAME_INDEX(err_template_spec_needs_template_parameters)
+DIAG_NAME_INDEX(err_template_spec_redecl_global_scope)
+DIAG_NAME_INDEX(err_template_spec_redecl_out_of_scope)
+DIAG_NAME_INDEX(err_template_spec_syntax_non_template)
+DIAG_NAME_INDEX(err_template_spec_unknown_kind)
+DIAG_NAME_INDEX(err_template_tag_noparams)
+DIAG_NAME_INDEX(err_template_template_parm_no_parms)
+DIAG_NAME_INDEX(err_template_typedef)
+DIAG_NAME_INDEX(err_template_unnamed_class)
+DIAG_NAME_INDEX(err_template_variable_noparams)
+DIAG_NAME_INDEX(err_templated_using_declaration)
+DIAG_NAME_INDEX(err_templated_using_directive)
+DIAG_NAME_INDEX(err_tentative_after_alias)
+DIAG_NAME_INDEX(err_tentative_def_incomplete_type)
+DIAG_NAME_INDEX(err_this_capture)
+DIAG_NAME_INDEX(err_this_capture_with_copy_default)
+DIAG_NAME_INDEX(err_this_captured_by_reference)
+DIAG_NAME_INDEX(err_this_static_member_func)
+DIAG_NAME_INDEX(err_thread_dynamic_init)
+DIAG_NAME_INDEX(err_thread_non_global)
+DIAG_NAME_INDEX(err_thread_non_thread)
+DIAG_NAME_INDEX(err_thread_nontrivial_dtor)
+DIAG_NAME_INDEX(err_thread_thread_different_kind)
+DIAG_NAME_INDEX(err_thread_unsupported)
+DIAG_NAME_INDEX(err_throw_abstract_type)
+DIAG_NAME_INDEX(err_throw_incomplete)
+DIAG_NAME_INDEX(err_throw_incomplete_ptr)
+DIAG_NAME_INDEX(err_too_few_args_in_macro_invoc)
+DIAG_NAME_INDEX(err_too_many_args_in_macro_invoc)
+DIAG_NAME_INDEX(err_toomany_element_decls)
+DIAG_NAME_INDEX(err_trailing_return_in_parens)
+DIAG_NAME_INDEX(err_trailing_return_without_auto)
+DIAG_NAME_INDEX(err_two_right_angle_brackets_need_space)
+DIAG_NAME_INDEX(err_type_defined_in_alias_template)
+DIAG_NAME_INDEX(err_type_defined_in_condition)
+DIAG_NAME_INDEX(err_type_defined_in_for_range)
+DIAG_NAME_INDEX(err_type_defined_in_param_type)
+DIAG_NAME_INDEX(err_type_defined_in_result_type)
+DIAG_NAME_INDEX(err_type_defined_in_type_specifier)
+DIAG_NAME_INDEX(err_type_mismatch_continuation_class)
+DIAG_NAME_INDEX(err_type_safety_unknown_flag)
+DIAG_NAME_INDEX(err_type_tag_for_datatype_not_ice)
+DIAG_NAME_INDEX(err_type_tag_for_datatype_too_large)
+DIAG_NAME_INDEX(err_type_trait_arity)
+DIAG_NAME_INDEX(err_typecheck_address_of)
+DIAG_NAME_INDEX(err_typecheck_addrof_dtor)
+DIAG_NAME_INDEX(err_typecheck_addrof_temporary)
+DIAG_NAME_INDEX(err_typecheck_ambiguous_condition)
+DIAG_NAME_INDEX(err_typecheck_arc_assign_self)
+DIAG_NAME_INDEX(err_typecheck_arc_assign_self_class_method)
+DIAG_NAME_INDEX(err_typecheck_arithmetic_incomplete_type)
+DIAG_NAME_INDEX(err_typecheck_arr_assign_enumeration)
+DIAG_NAME_INDEX(err_typecheck_array_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_typecheck_assign_const)
+DIAG_NAME_INDEX(err_typecheck_bool_condition)
+DIAG_NAME_INDEX(err_typecheck_call_invalid_ordered_compare)
+DIAG_NAME_INDEX(err_typecheck_call_invalid_unary_fp)
+DIAG_NAME_INDEX(err_typecheck_call_not_function)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args_at_least)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args_at_least_one)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args_at_least_suggest)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args_one)
+DIAG_NAME_INDEX(err_typecheck_call_too_few_args_suggest)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args_at_most)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args_at_most_one)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args_at_most_suggest)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args_one)
+DIAG_NAME_INDEX(err_typecheck_call_too_many_args_suggest)
+DIAG_NAME_INDEX(err_typecheck_cast_to_incomplete)
+DIAG_NAME_INDEX(err_typecheck_cast_to_union_no_type)
+DIAG_NAME_INDEX(err_typecheck_choose_expr_requires_constant)
+DIAG_NAME_INDEX(err_typecheck_comparison_of_distinct_blocks)
+DIAG_NAME_INDEX(err_typecheck_comparison_of_distinct_pointers)
+DIAG_NAME_INDEX(err_typecheck_comparison_of_fptr_to_void)
+DIAG_NAME_INDEX(err_typecheck_comparison_of_pointer_integer)
+DIAG_NAME_INDEX(err_typecheck_cond_expect_scalar)
+DIAG_NAME_INDEX(err_typecheck_cond_expect_scalar_or_vector)
+DIAG_NAME_INDEX(err_typecheck_cond_incompatible_operands)
+DIAG_NAME_INDEX(err_typecheck_cond_incompatible_operands_null)
+DIAG_NAME_INDEX(err_typecheck_convert_incompatible)
+DIAG_NAME_INDEX(err_typecheck_convert_incompatible_block_pointer)
+DIAG_NAME_INDEX(err_typecheck_converted_constant_expression)
+DIAG_NAME_INDEX(err_typecheck_converted_constant_expression_disallowed)
+DIAG_NAME_INDEX(err_typecheck_decl_incomplete_type)
+DIAG_NAME_INDEX(err_typecheck_decl_incomplete_type___float128)
+DIAG_NAME_INDEX(err_typecheck_deleted_function)
+DIAG_NAME_INDEX(err_typecheck_duplicate_vector_components_not_mlvalue)
+DIAG_NAME_INDEX(err_typecheck_expect_scalar_operand)
+DIAG_NAME_INDEX(err_typecheck_expression_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_typecheck_field_variable_size)
+DIAG_NAME_INDEX(err_typecheck_illegal_increment_decrement)
+DIAG_NAME_INDEX(err_typecheck_incompatible_address_space)
+DIAG_NAME_INDEX(err_typecheck_incompatible_ownership)
+DIAG_NAME_INDEX(err_typecheck_incomplete_array_needs_initializer)
+DIAG_NAME_INDEX(err_typecheck_incomplete_tag)
+DIAG_NAME_INDEX(err_typecheck_incomplete_type_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_typecheck_indirection_requires_pointer)
+DIAG_NAME_INDEX(err_typecheck_invalid_lvalue_addrof)
+DIAG_NAME_INDEX(err_typecheck_invalid_lvalue_addrof_addrof_function)
+DIAG_NAME_INDEX(err_typecheck_invalid_operands)
+DIAG_NAME_INDEX(err_typecheck_invalid_restrict_invalid_pointee)
+DIAG_NAME_INDEX(err_typecheck_invalid_restrict_not_pointer)
+DIAG_NAME_INDEX(err_typecheck_invalid_restrict_not_pointer_noarg)
+DIAG_NAME_INDEX(err_typecheck_ivar_variable_size)
+DIAG_NAME_INDEX(err_typecheck_lvalue_casts_not_supported)
+DIAG_NAME_INDEX(err_typecheck_member_reference_arrow)
+DIAG_NAME_INDEX(err_typecheck_member_reference_ivar)
+DIAG_NAME_INDEX(err_typecheck_member_reference_ivar_suggest)
+DIAG_NAME_INDEX(err_typecheck_member_reference_struct_union)
+DIAG_NAME_INDEX(err_typecheck_member_reference_suggestion)
+DIAG_NAME_INDEX(err_typecheck_member_reference_type)
+DIAG_NAME_INDEX(err_typecheck_member_reference_unknown)
+DIAG_NAME_INDEX(err_typecheck_missing_return_type_incompatible)
+DIAG_NAME_INDEX(err_typecheck_negative_array_size)
+DIAG_NAME_INDEX(err_typecheck_non_object_not_modifiable_lvalue)
+DIAG_NAME_INDEX(err_typecheck_nonviable_condition)
+DIAG_NAME_INDEX(err_typecheck_nonviable_condition_incomplete)
+DIAG_NAME_INDEX(err_typecheck_pointer_arith_function_type)
+DIAG_NAME_INDEX(err_typecheck_pointer_arith_void_type)
+DIAG_NAME_INDEX(err_typecheck_sclass_fscope)
+DIAG_NAME_INDEX(err_typecheck_sclass_func)
+DIAG_NAME_INDEX(err_typecheck_statement_requires_integer)
+DIAG_NAME_INDEX(err_typecheck_statement_requires_scalar)
+DIAG_NAME_INDEX(err_typecheck_sub_ptr_compatible)
+DIAG_NAME_INDEX(err_typecheck_subscript_not_integer)
+DIAG_NAME_INDEX(err_typecheck_subscript_value)
+DIAG_NAME_INDEX(err_typecheck_unary_expr)
+DIAG_NAME_INDEX(err_typecheck_vector_not_convertable)
+DIAG_NAME_INDEX(err_typecheck_vector_not_convertable_non_scalar)
+DIAG_NAME_INDEX(err_typecheck_zero_array_size)
+DIAG_NAME_INDEX(err_typedef_changes_linkage)
+DIAG_NAME_INDEX(err_typedef_not_bitfield)
+DIAG_NAME_INDEX(err_typedef_not_identifier)
+DIAG_NAME_INDEX(err_typename_identifiers_only)
+DIAG_NAME_INDEX(err_typename_invalid_constexpr)
+DIAG_NAME_INDEX(err_typename_invalid_functionspec)
+DIAG_NAME_INDEX(err_typename_invalid_storageclass)
+DIAG_NAME_INDEX(err_typename_missing)
+DIAG_NAME_INDEX(err_typename_nested_not_found)
+DIAG_NAME_INDEX(err_typename_nested_not_found_enable_if)
+DIAG_NAME_INDEX(err_typename_nested_not_type)
+DIAG_NAME_INDEX(err_typename_refers_to_non_type_template)
+DIAG_NAME_INDEX(err_typename_refers_to_using_value_decl)
+DIAG_NAME_INDEX(err_typename_requires_specqual)
+DIAG_NAME_INDEX(err_ucn_control_character)
+DIAG_NAME_INDEX(err_ucn_escape_basic_scs)
+DIAG_NAME_INDEX(err_ucn_escape_incomplete)
+DIAG_NAME_INDEX(err_ucn_escape_invalid)
+DIAG_NAME_INDEX(err_unable_to_make_temp)
+DIAG_NAME_INDEX(err_unable_to_rename_temp)
+DIAG_NAME_INDEX(err_unavailable)
+DIAG_NAME_INDEX(err_unavailable_message)
+DIAG_NAME_INDEX(err_uncasted_call_of_unknown_any)
+DIAG_NAME_INDEX(err_uncasted_send_to_unknown_any_method)
+DIAG_NAME_INDEX(err_uncasted_use_of_unknown_any)
+DIAG_NAME_INDEX(err_undeclared_boxing_method)
+DIAG_NAME_INDEX(err_undeclared_label_use)
+DIAG_NAME_INDEX(err_undeclared_nsarray)
+DIAG_NAME_INDEX(err_undeclared_nsdictionary)
+DIAG_NAME_INDEX(err_undeclared_nsnumber)
+DIAG_NAME_INDEX(err_undeclared_nsstring)
+DIAG_NAME_INDEX(err_undeclared_protocol)
+DIAG_NAME_INDEX(err_undeclared_protocol_suggest)
+DIAG_NAME_INDEX(err_undeclared_use)
+DIAG_NAME_INDEX(err_undeclared_use_suggest)
+DIAG_NAME_INDEX(err_undeclared_var_use)
+DIAG_NAME_INDEX(err_undeclared_var_use_suggest)
+DIAG_NAME_INDEX(err_undef_interface)
+DIAG_NAME_INDEX(err_undef_interface_suggest)
+DIAG_NAME_INDEX(err_undef_superclass)
+DIAG_NAME_INDEX(err_undef_superclass_suggest)
+DIAG_NAME_INDEX(err_underlying_type_of_incomplete_enum)
+DIAG_NAME_INDEX(err_unexpanded_parameter_pack_0)
+DIAG_NAME_INDEX(err_unexpanded_parameter_pack_1)
+DIAG_NAME_INDEX(err_unexpanded_parameter_pack_2)
+DIAG_NAME_INDEX(err_unexpanded_parameter_pack_3_or_more)
+DIAG_NAME_INDEX(err_unexpected_at)
+DIAG_NAME_INDEX(err_unexpected_colon_in_nested_name_spec)
+DIAG_NAME_INDEX(err_unexpected_friend)
+DIAG_NAME_INDEX(err_unexpected_interface)
+DIAG_NAME_INDEX(err_unexpected_namespace)
+DIAG_NAME_INDEX(err_unexpected_namespace_attributes_alias)
+DIAG_NAME_INDEX(err_unexpected_protocol_qualifier)
+DIAG_NAME_INDEX(err_unexpected_scope_on_base_decltype)
+DIAG_NAME_INDEX(err_unexpected_token_in_nested_name_spec)
+DIAG_NAME_INDEX(err_unexpected_typedef)
+DIAG_NAME_INDEX(err_unexpected_typedef_ident)
+DIAG_NAME_INDEX(err_unexpected_unqualified_id)
+DIAG_NAME_INDEX(err_uninitialized_member_for_assign)
+DIAG_NAME_INDEX(err_uninitialized_member_in_ctor)
+DIAG_NAME_INDEX(err_union_as_base_class)
+DIAG_NAME_INDEX(err_union_member_of_reference_type)
+DIAG_NAME_INDEX(err_unknown_analyzer_checker)
+DIAG_NAME_INDEX(err_unknown_any_addrof)
+DIAG_NAME_INDEX(err_unknown_any_function)
+DIAG_NAME_INDEX(err_unknown_any_var_function_type)
+DIAG_NAME_INDEX(err_unknown_nested_typename_suggest)
+DIAG_NAME_INDEX(err_unknown_receiver_suggest)
+DIAG_NAME_INDEX(err_unknown_template_name)
+DIAG_NAME_INDEX(err_unknown_type_or_class_name_suggest)
+DIAG_NAME_INDEX(err_unknown_typename)
+DIAG_NAME_INDEX(err_unknown_typename_suggest)
+DIAG_NAME_INDEX(err_unqualified_pointer_member_function)
+DIAG_NAME_INDEX(err_unspecified_vla_size_with_static)
+DIAG_NAME_INDEX(err_unsupported_ast_node)
+DIAG_NAME_INDEX(err_unsupported_bom)
+DIAG_NAME_INDEX(err_unsupported_string_concat)
+DIAG_NAME_INDEX(err_unsupported_unknown_any_call)
+DIAG_NAME_INDEX(err_unsupported_unknown_any_decl)
+DIAG_NAME_INDEX(err_unsupported_unknown_any_expr)
+DIAG_NAME_INDEX(err_unterm_macro_invoc)
+DIAG_NAME_INDEX(err_unterminated___pragma)
+DIAG_NAME_INDEX(err_unterminated_block_comment)
+DIAG_NAME_INDEX(err_unterminated_raw_string)
+DIAG_NAME_INDEX(err_upcast_to_inaccessible_base)
+DIAG_NAME_INDEX(err_use_continuation_class)
+DIAG_NAME_INDEX(err_use_continuation_class_redeclaration_readwrite)
+DIAG_NAME_INDEX(err_use_of_default_argument_to_function_declared_later)
+DIAG_NAME_INDEX(err_use_of_tag_name_without_tag)
+DIAG_NAME_INDEX(err_use_with_wrong_tag)
+DIAG_NAME_INDEX(err_using_decl_can_not_refer_to_class_member)
+DIAG_NAME_INDEX(err_using_decl_can_not_refer_to_namespace)
+DIAG_NAME_INDEX(err_using_decl_conflict)
+DIAG_NAME_INDEX(err_using_decl_conflict_reverse)
+DIAG_NAME_INDEX(err_using_decl_constructor)
+DIAG_NAME_INDEX(err_using_decl_constructor_conflict)
+DIAG_NAME_INDEX(err_using_decl_constructor_not_in_direct_base)
+DIAG_NAME_INDEX(err_using_decl_destructor)
+DIAG_NAME_INDEX(err_using_decl_friend)
+DIAG_NAME_INDEX(err_using_decl_nested_name_specifier_is_current_class)
+DIAG_NAME_INDEX(err_using_decl_nested_name_specifier_is_not_base_class)
+DIAG_NAME_INDEX(err_using_decl_nested_name_specifier_is_not_class)
+DIAG_NAME_INDEX(err_using_decl_redeclaration)
+DIAG_NAME_INDEX(err_using_decl_template_id)
+DIAG_NAME_INDEX(err_using_dependent_value_is_type)
+DIAG_NAME_INDEX(err_using_directive_member_suggest)
+DIAG_NAME_INDEX(err_using_directive_suggest)
+DIAG_NAME_INDEX(err_using_namespace_in_class)
+DIAG_NAME_INDEX(err_using_requires_qualname)
+DIAG_NAME_INDEX(err_using_typename_non_type)
+DIAG_NAME_INDEX(err_uuidof_with_multiple_guids)
+DIAG_NAME_INDEX(err_uuidof_without_guid)
+DIAG_NAME_INDEX(err_va_start_used_in_non_variadic_function)
+DIAG_NAME_INDEX(err_value_init_for_array_type)
+DIAG_NAME_INDEX(err_var_partial_spec_redeclared)
+DIAG_NAME_INDEX(err_var_spec_no_template)
+DIAG_NAME_INDEX(err_var_spec_no_template_but_method)
+DIAG_NAME_INDEX(err_variable_instantiates_to_function)
+DIAG_NAME_INDEX(err_variable_object_no_init)
+DIAG_NAME_INDEX(err_variably_modified_new_type)
+DIAG_NAME_INDEX(err_variably_modified_nontype_template_param)
+DIAG_NAME_INDEX(err_variably_modified_template_arg)
+DIAG_NAME_INDEX(err_vecstep_non_scalar_vector_type)
+DIAG_NAME_INDEX(err_vector_incorrect_num_initializers)
+DIAG_NAME_INDEX(err_verify_inconsistent_diags)
+DIAG_NAME_INDEX(err_verify_invalid_content)
+DIAG_NAME_INDEX(err_verify_invalid_no_diags)
+DIAG_NAME_INDEX(err_verify_invalid_range)
+DIAG_NAME_INDEX(err_verify_missing_end)
+DIAG_NAME_INDEX(err_verify_missing_file)
+DIAG_NAME_INDEX(err_verify_missing_line)
+DIAG_NAME_INDEX(err_verify_missing_regex)
+DIAG_NAME_INDEX(err_verify_missing_start)
+DIAG_NAME_INDEX(err_verify_no_directives)
+DIAG_NAME_INDEX(err_virtual_member_function_template)
+DIAG_NAME_INDEX(err_virtual_non_function)
+DIAG_NAME_INDEX(err_virtual_out_of_class)
+DIAG_NAME_INDEX(err_vla_decl_has_extern_linkage)
+DIAG_NAME_INDEX(err_vla_decl_has_static_storage)
+DIAG_NAME_INDEX(err_vla_decl_in_file_scope)
+DIAG_NAME_INDEX(err_vla_in_sfinae)
+DIAG_NAME_INDEX(err_vla_non_pod)
+DIAG_NAME_INDEX(err_vm_decl_has_extern_linkage)
+DIAG_NAME_INDEX(err_vm_decl_in_file_scope)
+DIAG_NAME_INDEX(err_vm_func_decl)
+DIAG_NAME_INDEX(err_void_only_param)
+DIAG_NAME_INDEX(err_void_param_qualified)
+DIAG_NAME_INDEX(err_warning_check_malformed)
+DIAG_NAME_INDEX(err_wrong_sampler_addressspace)
+DIAG_NAME_INDEX(err_zero_version)
+DIAG_NAME_INDEX(error_arc_weak_ivar_access)
+DIAG_NAME_INDEX(error_bad_category_property_decl)
+DIAG_NAME_INDEX(error_bad_property_context)
+DIAG_NAME_INDEX(error_bad_property_decl)
+DIAG_NAME_INDEX(error_cannot_find_suitable_accessor)
+DIAG_NAME_INDEX(error_category_property)
+DIAG_NAME_INDEX(error_dealloc_bad_result_type)
+DIAG_NAME_INDEX(error_duplicate_ivar_use)
+DIAG_NAME_INDEX(error_dynamic_property_ivar_decl)
+DIAG_NAME_INDEX(error_empty_enum)
+DIAG_NAME_INDEX(error_implicit_ivar_access)
+DIAG_NAME_INDEX(error_ivar_in_superclass_use)
+DIAG_NAME_INDEX(error_ivar_use_in_class_method)
+DIAG_NAME_INDEX(error_method_not_found_with_typo)
+DIAG_NAME_INDEX(error_missing_method_context)
+DIAG_NAME_INDEX(error_missing_property_context)
+DIAG_NAME_INDEX(error_missing_property_interface)
+DIAG_NAME_INDEX(error_missing_property_ivar_decl)
+DIAG_NAME_INDEX(error_no_subobject_property_setting)
+DIAG_NAME_INDEX(error_no_super_class_message)
+DIAG_NAME_INDEX(error_objc_synchronized_expects_object)
+DIAG_NAME_INDEX(error_objc_throw_expects_object)
+DIAG_NAME_INDEX(error_private_ivar_access)
+DIAG_NAME_INDEX(error_property_accessor_type)
+DIAG_NAME_INDEX(error_property_implemented)
+DIAG_NAME_INDEX(error_property_ivar_decl)
+DIAG_NAME_INDEX(error_property_ivar_type)
+DIAG_NAME_INDEX(error_property_setter_ambiguous_use)
+DIAG_NAME_INDEX(error_protected_ivar_access)
+DIAG_NAME_INDEX(error_readonly_message_assignment)
+DIAG_NAME_INDEX(error_reference_property)
+DIAG_NAME_INDEX(error_rethrow_used_outside_catch)
+DIAG_NAME_INDEX(error_root_class_cannot_use_super)
+DIAG_NAME_INDEX(error_strong_property)
+DIAG_NAME_INDEX(error_synthesize_category_decl)
+DIAG_NAME_INDEX(error_synthesize_weak_non_arc_or_gc)
+DIAG_NAME_INDEX(error_undeclared_use_of_module)
+DIAG_NAME_INDEX(error_use_of_private_header_outside_module)
+DIAG_NAME_INDEX(error_weak_property)
+DIAG_NAME_INDEX(escaped_newline_block_comment_end)
+DIAG_NAME_INDEX(ext_abstract_pack_declarator_parens)
+DIAG_NAME_INDEX(ext_aggregate_init_not_constant)
+DIAG_NAME_INDEX(ext_alias_declaration)
+DIAG_NAME_INDEX(ext_alignof_expr)
+DIAG_NAME_INDEX(ext_anonymous_record_with_anonymous_type)
+DIAG_NAME_INDEX(ext_anonymous_record_with_type)
+DIAG_NAME_INDEX(ext_anonymous_struct_union_qualified)
+DIAG_NAME_INDEX(ext_anonymous_union)
+DIAG_NAME_INDEX(ext_array_init_copy)
+DIAG_NAME_INDEX(ext_array_init_parens)
+DIAG_NAME_INDEX(ext_array_size_conversion)
+DIAG_NAME_INDEX(ext_auto_storage_class)
+DIAG_NAME_INDEX(ext_auto_type_specifier)
+DIAG_NAME_INDEX(ext_binary_literal)
+DIAG_NAME_INDEX(ext_binary_literal_cxx1y)
+DIAG_NAME_INDEX(ext_c11_alignment)
+DIAG_NAME_INDEX(ext_c11_anonymous_struct)
+DIAG_NAME_INDEX(ext_c11_generic_selection)
+DIAG_NAME_INDEX(ext_c11_noreturn)
+DIAG_NAME_INDEX(ext_c11_static_assert)
+DIAG_NAME_INDEX(ext_c99_array_usage)
+DIAG_NAME_INDEX(ext_c99_compound_literal)
+DIAG_NAME_INDEX(ext_c99_flexible_array_member)
+DIAG_NAME_INDEX(ext_c99_longlong)
+DIAG_NAME_INDEX(ext_c99_variable_decl_in_for_loop)
+DIAG_NAME_INDEX(ext_c99_whitespace_required_after_macro_name)
+DIAG_NAME_INDEX(ext_c_enum_fixed_underlying_type)
+DIAG_NAME_INDEX(ext_cast_fn_obj)
+DIAG_NAME_INDEX(ext_cce_narrowing)
+DIAG_NAME_INDEX(ext_charize_microsoft)
+DIAG_NAME_INDEX(ext_complex_component_init)
+DIAG_NAME_INDEX(ext_constexpr_body_invalid_stmt)
+DIAG_NAME_INDEX(ext_constexpr_body_multiple_return)
+DIAG_NAME_INDEX(ext_constexpr_function_never_constant_expr)
+DIAG_NAME_INDEX(ext_constexpr_local_var)
+DIAG_NAME_INDEX(ext_constexpr_type_definition)
+DIAG_NAME_INDEX(ext_cxx11_enum_fixed_underlying_type)
+DIAG_NAME_INDEX(ext_cxx11_longlong)
+DIAG_NAME_INDEX(ext_decltype_auto_type_specifier)
+DIAG_NAME_INDEX(ext_defaulted_function)
+DIAG_NAME_INDEX(ext_delete_void_ptr_operand)
+DIAG_NAME_INDEX(ext_deleted_function)
+DIAG_NAME_INDEX(ext_deprecated_string_literal_conversion)
+DIAG_NAME_INDEX(ext_designated_init)
+DIAG_NAME_INDEX(ext_dollar_in_identifier)
+DIAG_NAME_INDEX(ext_duplicate_declspec)
+DIAG_NAME_INDEX(ext_ellipsis_exception_spec)
+DIAG_NAME_INDEX(ext_embedded_directive)
+DIAG_NAME_INDEX(ext_empty_character)
+DIAG_NAME_INDEX(ext_empty_fnmacro_arg)
+DIAG_NAME_INDEX(ext_empty_struct_union)
+DIAG_NAME_INDEX(ext_empty_translation_unit)
+DIAG_NAME_INDEX(ext_enum_friend)
+DIAG_NAME_INDEX(ext_enum_too_large)
+DIAG_NAME_INDEX(ext_enum_value_not_int)
+DIAG_NAME_INDEX(ext_enumerator_increment_too_large)
+DIAG_NAME_INDEX(ext_enumerator_list_comma_c)
+DIAG_NAME_INDEX(ext_enumerator_list_comma_cxx)
+DIAG_NAME_INDEX(ext_enumerator_too_large)
+DIAG_NAME_INDEX(ext_excess_initializers)
+DIAG_NAME_INDEX(ext_excess_initializers_in_char_array_initializer)
+DIAG_NAME_INDEX(ext_expected_semi_decl_list)
+DIAG_NAME_INDEX(ext_explicit_conversion_functions)
+DIAG_NAME_INDEX(ext_explicit_instantiation_after_specialization)
+DIAG_NAME_INDEX(ext_explicit_instantiation_duplicate)
+DIAG_NAME_INDEX(ext_explicit_instantiation_without_qualified_id)
+DIAG_NAME_INDEX(ext_explicit_specialization_storage_class)
+DIAG_NAME_INDEX(ext_expr_not_ice)
+DIAG_NAME_INDEX(ext_extern_template)
+DIAG_NAME_INDEX(ext_extra_semi)
+DIAG_NAME_INDEX(ext_extra_semi_cxx11)
+DIAG_NAME_INDEX(ext_flexible_array_empty_aggregate_gnu)
+DIAG_NAME_INDEX(ext_flexible_array_empty_aggregate_ms)
+DIAG_NAME_INDEX(ext_flexible_array_in_array)
+DIAG_NAME_INDEX(ext_flexible_array_in_struct)
+DIAG_NAME_INDEX(ext_flexible_array_init)
+DIAG_NAME_INDEX(ext_flexible_array_union_gnu)
+DIAG_NAME_INDEX(ext_flexible_array_union_ms)
+DIAG_NAME_INDEX(ext_for_range)
+DIAG_NAME_INDEX(ext_for_range_identifier)
+DIAG_NAME_INDEX(ext_forward_ref_enum)
+DIAG_NAME_INDEX(ext_forward_ref_enum_def)
+DIAG_NAME_INDEX(ext_found_via_dependent_bases_lookup)
+DIAG_NAME_INDEX(ext_four_char_character_literal)
+DIAG_NAME_INDEX(ext_freestanding_complex)
+DIAG_NAME_INDEX(ext_friend_tag_redecl_outside_namespace)
+DIAG_NAME_INDEX(ext_function_specialization_in_class)
+DIAG_NAME_INDEX(ext_generalized_initializer_lists)
+DIAG_NAME_INDEX(ext_gnu_address_of_label)
+DIAG_NAME_INDEX(ext_gnu_anonymous_struct)
+DIAG_NAME_INDEX(ext_gnu_array_range)
+DIAG_NAME_INDEX(ext_gnu_case_range)
+DIAG_NAME_INDEX(ext_gnu_conditional_expr)
+DIAG_NAME_INDEX(ext_gnu_empty_initializer)
+DIAG_NAME_INDEX(ext_gnu_indirect_goto)
+DIAG_NAME_INDEX(ext_gnu_missing_equal_designator)
+DIAG_NAME_INDEX(ext_gnu_old_style_field_designator)
+DIAG_NAME_INDEX(ext_gnu_ptr_func_arith)
+DIAG_NAME_INDEX(ext_gnu_statement_expr)
+DIAG_NAME_INDEX(ext_gnu_subscript_void_type)
+DIAG_NAME_INDEX(ext_gnu_void_ptr)
+DIAG_NAME_INDEX(ext_goto_into_protected_scope)
+DIAG_NAME_INDEX(ext_hexconstant_invalid)
+DIAG_NAME_INDEX(ext_ident_list_in_param)
+DIAG_NAME_INDEX(ext_imaginary_constant)
+DIAG_NAME_INDEX(ext_implicit_exception_spec_mismatch)
+DIAG_NAME_INDEX(ext_implicit_function_decl)
+DIAG_NAME_INDEX(ext_implicit_lib_function_decl)
+DIAG_NAME_INDEX(ext_in_class_initializer_float_type)
+DIAG_NAME_INDEX(ext_in_class_initializer_float_type_cxx11)
+DIAG_NAME_INDEX(ext_in_class_initializer_non_constant)
+DIAG_NAME_INDEX(ext_init_capture)
+DIAG_NAME_INDEX(ext_init_list_constant_narrowing)
+DIAG_NAME_INDEX(ext_init_list_type_narrowing)
+DIAG_NAME_INDEX(ext_init_list_variable_narrowing)
+DIAG_NAME_INDEX(ext_initializer_string_for_char_array_too_long)
+DIAG_NAME_INDEX(ext_inline_namespace)
+DIAG_NAME_INDEX(ext_integer_complement_complex)
+DIAG_NAME_INDEX(ext_integer_complex)
+DIAG_NAME_INDEX(ext_integer_increment_complex)
+DIAG_NAME_INDEX(ext_integer_too_large_for_signed)
+DIAG_NAME_INDEX(ext_internal_in_extern_inline)
+DIAG_NAME_INDEX(ext_internal_in_extern_inline_quiet)
+DIAG_NAME_INDEX(ext_invalid_sign_spec)
+DIAG_NAME_INDEX(ext_keyword_as_ident)
+DIAG_NAME_INDEX(ext_line_comment)
+DIAG_NAME_INDEX(ext_main_returns_nonint)
+DIAG_NAME_INDEX(ext_main_used)
+DIAG_NAME_INDEX(ext_many_braces_around_scalar_init)
+DIAG_NAME_INDEX(ext_member_redeclared)
+DIAG_NAME_INDEX(ext_mismatched_exception_spec)
+DIAG_NAME_INDEX(ext_missing_declspec)
+DIAG_NAME_INDEX(ext_missing_type_specifier)
+DIAG_NAME_INDEX(ext_missing_varargs_arg)
+DIAG_NAME_INDEX(ext_missing_whitespace_after_macro_name)
+DIAG_NAME_INDEX(ext_mixed_decls_code)
+DIAG_NAME_INDEX(ext_ms_anonymous_struct)
+DIAG_NAME_INDEX(ext_ms_delayed_template_argument)
+DIAG_NAME_INDEX(ext_ms_deref_template_argument)
+DIAG_NAME_INDEX(ext_ms_explicit_constructor_call)
+DIAG_NAME_INDEX(ext_ms_forward_ref_enum)
+DIAG_NAME_INDEX(ext_ms_reserved_user_defined_literal)
+DIAG_NAME_INDEX(ext_ms_sealed_keyword)
+DIAG_NAME_INDEX(ext_ms_template_type_arg_missing_typename)
+DIAG_NAME_INDEX(ext_ms_using_declaration_inaccessible)
+DIAG_NAME_INDEX(ext_multi_line_line_comment)
+DIAG_NAME_INDEX(ext_multichar_character_literal)
+DIAG_NAME_INDEX(ext_named_variadic_macro)
+DIAG_NAME_INDEX(ext_nested_name_member_ref_lookup_ambiguous)
+DIAG_NAME_INDEX(ext_nested_pointer_qualifier_mismatch)
+DIAG_NAME_INDEX(ext_new_paren_array_nonconst)
+DIAG_NAME_INDEX(ext_no_declarators)
+DIAG_NAME_INDEX(ext_no_named_members_in_struct_union)
+DIAG_NAME_INDEX(ext_no_newline_eof)
+DIAG_NAME_INDEX(ext_nonclass_type_friend)
+DIAG_NAME_INDEX(ext_nonstandard_escape)
+DIAG_NAME_INDEX(ext_nonstatic_member_init)
+DIAG_NAME_INDEX(ext_noreturn_main)
+DIAG_NAME_INDEX(ext_offsetof_extended_field_designator)
+DIAG_NAME_INDEX(ext_offsetof_non_pod_type)
+DIAG_NAME_INDEX(ext_offsetof_non_standardlayout_type)
+DIAG_NAME_INDEX(ext_omp_loop_not_canonical_init)
+DIAG_NAME_INDEX(ext_on_off_switch_syntax)
+DIAG_NAME_INDEX(ext_operator_new_delete_declared_inline)
+DIAG_NAME_INDEX(ext_out_of_line_declaration)
+DIAG_NAME_INDEX(ext_override_control_keyword)
+DIAG_NAME_INDEX(ext_override_exception_spec)
+DIAG_NAME_INDEX(ext_param_default_argument_redefinition)
+DIAG_NAME_INDEX(ext_param_not_declared)
+DIAG_NAME_INDEX(ext_param_promoted_not_compatible_with_prototype)
+DIAG_NAME_INDEX(ext_paste_comma)
+DIAG_NAME_INDEX(ext_plain_complex)
+DIAG_NAME_INDEX(ext_pp_bad_paste_ms)
+DIAG_NAME_INDEX(ext_pp_bad_vaargs_use)
+DIAG_NAME_INDEX(ext_pp_comma_expr)
+DIAG_NAME_INDEX(ext_pp_extra_tokens_at_eol)
+DIAG_NAME_INDEX(ext_pp_ident_directive)
+DIAG_NAME_INDEX(ext_pp_import_directive)
+DIAG_NAME_INDEX(ext_pp_include_next_directive)
+DIAG_NAME_INDEX(ext_pp_include_search_ms)
+DIAG_NAME_INDEX(ext_pp_line_too_big)
+DIAG_NAME_INDEX(ext_pp_line_zero)
+DIAG_NAME_INDEX(ext_pp_macro_redef)
+DIAG_NAME_INDEX(ext_pp_operator_used_as_macro_name)
+DIAG_NAME_INDEX(ext_pp_redef_builtin_macro)
+DIAG_NAME_INDEX(ext_pp_undef_builtin_macro)
+DIAG_NAME_INDEX(ext_pp_warning_directive)
+DIAG_NAME_INDEX(ext_pragma_syntax_eod)
+DIAG_NAME_INDEX(ext_predef_outside_function)
+DIAG_NAME_INDEX(ext_pseudo_dtor_on_void)
+DIAG_NAME_INDEX(ext_pure_function_definition)
+DIAG_NAME_INDEX(ext_redefinition_of_typedef)
+DIAG_NAME_INDEX(ext_ref_qualifier)
+DIAG_NAME_INDEX(ext_reserved_user_defined_literal)
+DIAG_NAME_INDEX(ext_retained_language_linkage)
+DIAG_NAME_INDEX(ext_return_has_expr)
+DIAG_NAME_INDEX(ext_return_has_void_expr)
+DIAG_NAME_INDEX(ext_return_missing_expr)
+DIAG_NAME_INDEX(ext_rvalue_reference)
+DIAG_NAME_INDEX(ext_rvalue_to_reference_access_ctor)
+DIAG_NAME_INDEX(ext_rvalue_to_reference_temp_copy_no_viable)
+DIAG_NAME_INDEX(ext_scoped_enum)
+DIAG_NAME_INDEX(ext_sizeof_alignof_function_type)
+DIAG_NAME_INDEX(ext_sizeof_alignof_void_type)
+DIAG_NAME_INDEX(ext_standalone_specifier)
+DIAG_NAME_INDEX(ext_static_assert_no_message)
+DIAG_NAME_INDEX(ext_static_data_member_in_union)
+DIAG_NAME_INDEX(ext_static_non_static)
+DIAG_NAME_INDEX(ext_stdc_pragma_ignored)
+DIAG_NAME_INDEX(ext_string_literal_operator_template)
+DIAG_NAME_INDEX(ext_string_too_long)
+DIAG_NAME_INDEX(ext_subscript_non_lvalue)
+DIAG_NAME_INDEX(ext_template_arg_extra_parens)
+DIAG_NAME_INDEX(ext_template_arg_local_type)
+DIAG_NAME_INDEX(ext_template_arg_object_internal)
+DIAG_NAME_INDEX(ext_template_arg_unnamed_type)
+DIAG_NAME_INDEX(ext_template_outside_of_template)
+DIAG_NAME_INDEX(ext_template_parameter_default_in_function_template)
+DIAG_NAME_INDEX(ext_template_spec_decl_out_of_scope)
+DIAG_NAME_INDEX(ext_template_template_param_typename)
+DIAG_NAME_INDEX(ext_thread_before)
+DIAG_NAME_INDEX(ext_token_used)
+DIAG_NAME_INDEX(ext_typecheck_addrof_temporary)
+DIAG_NAME_INDEX(ext_typecheck_addrof_void)
+DIAG_NAME_INDEX(ext_typecheck_base_super)
+DIAG_NAME_INDEX(ext_typecheck_cast_nonscalar)
+DIAG_NAME_INDEX(ext_typecheck_cast_to_union)
+DIAG_NAME_INDEX(ext_typecheck_comparison_of_distinct_pointers)
+DIAG_NAME_INDEX(ext_typecheck_comparison_of_distinct_pointers_nonstandard)
+DIAG_NAME_INDEX(ext_typecheck_comparison_of_fptr_to_void)
+DIAG_NAME_INDEX(ext_typecheck_comparison_of_pointer_integer)
+DIAG_NAME_INDEX(ext_typecheck_cond_incompatible_operands)
+DIAG_NAME_INDEX(ext_typecheck_cond_incompatible_operands_nonstandard)
+DIAG_NAME_INDEX(ext_typecheck_cond_incompatible_pointers)
+DIAG_NAME_INDEX(ext_typecheck_cond_one_void)
+DIAG_NAME_INDEX(ext_typecheck_cond_pointer_integer_mismatch)
+DIAG_NAME_INDEX(ext_typecheck_convert_discards_qualifiers)
+DIAG_NAME_INDEX(ext_typecheck_convert_incompatible_pointer)
+DIAG_NAME_INDEX(ext_typecheck_convert_incompatible_pointer_sign)
+DIAG_NAME_INDEX(ext_typecheck_convert_int_pointer)
+DIAG_NAME_INDEX(ext_typecheck_convert_pointer_int)
+DIAG_NAME_INDEX(ext_typecheck_convert_pointer_void_func)
+DIAG_NAME_INDEX(ext_typecheck_decl_incomplete_type)
+DIAG_NAME_INDEX(ext_typecheck_indirection_through_void_pointer)
+DIAG_NAME_INDEX(ext_typecheck_ordered_comparison_of_function_pointers)
+DIAG_NAME_INDEX(ext_typecheck_ordered_comparison_of_pointer_and_zero)
+DIAG_NAME_INDEX(ext_typecheck_ordered_comparison_of_pointer_integer)
+DIAG_NAME_INDEX(ext_typecheck_zero_array_size)
+DIAG_NAME_INDEX(ext_typedef_without_a_name)
+DIAG_NAME_INDEX(ext_typename_missing)
+DIAG_NAME_INDEX(ext_typename_outside_of_template)
+DIAG_NAME_INDEX(ext_undeclared_unqual_id_with_dependent_base)
+DIAG_NAME_INDEX(ext_unelaborated_friend_type)
+DIAG_NAME_INDEX(ext_unicode_whitespace)
+DIAG_NAME_INDEX(ext_union_member_of_reference_type)
+DIAG_NAME_INDEX(ext_unknown_escape)
+DIAG_NAME_INDEX(ext_unterminated_char)
+DIAG_NAME_INDEX(ext_unterminated_string)
+DIAG_NAME_INDEX(ext_using_undefined_std)
+DIAG_NAME_INDEX(ext_variable_sized_type_in_struct)
+DIAG_NAME_INDEX(ext_variable_template)
+DIAG_NAME_INDEX(ext_variadic_macro)
+DIAG_NAME_INDEX(ext_variadic_templates)
+DIAG_NAME_INDEX(ext_vla)
+DIAG_NAME_INDEX(ext_vla_folded_to_constant)
+DIAG_NAME_INDEX(fatal_too_many_errors)
+DIAG_NAME_INDEX(not_conv_function_declared_at)
+DIAG_NAME_INDEX(not_incomplete_class_and_qualified_id)
+DIAG_NAME_INDEX(note_access_constrained_by_path)
+DIAG_NAME_INDEX(note_access_natural)
+DIAG_NAME_INDEX(note_access_protected_restricted_ctordtor)
+DIAG_NAME_INDEX(note_access_protected_restricted_noobject)
+DIAG_NAME_INDEX(note_access_protected_restricted_object)
+DIAG_NAME_INDEX(note_add_deprecation_attr)
+DIAG_NAME_INDEX(note_additional_parens_for_variable_declaration)
+DIAG_NAME_INDEX(note_alignas_on_declaration)
+DIAG_NAME_INDEX(note_also_found)
+DIAG_NAME_INDEX(note_ambig_member_ref_object_type)
+DIAG_NAME_INDEX(note_ambig_member_ref_scope)
+DIAG_NAME_INDEX(note_ambiguous_candidate)
+DIAG_NAME_INDEX(note_ambiguous_member_found)
+DIAG_NAME_INDEX(note_ambiguous_type_conversion)
+DIAG_NAME_INDEX(note_arc_assign_to_strong)
+DIAG_NAME_INDEX(note_arc_bridge)
+DIAG_NAME_INDEX(note_arc_bridge_retained)
+DIAG_NAME_INDEX(note_arc_bridge_transfer)
+DIAG_NAME_INDEX(note_arc_cstyle_bridge)
+DIAG_NAME_INDEX(note_arc_cstyle_bridge_retained)
+DIAG_NAME_INDEX(note_arc_cstyle_bridge_transfer)
+DIAG_NAME_INDEX(note_arc_gained_method_convention)
+DIAG_NAME_INDEX(note_arc_lost_method_convention)
+DIAG_NAME_INDEX(note_arc_retain_cycle_owner)
+DIAG_NAME_INDEX(note_arc_weak_also_accessed_here)
+DIAG_NAME_INDEX(note_array_index_out_of_bounds)
+DIAG_NAME_INDEX(note_array_size_conversion)
+DIAG_NAME_INDEX(note_assign_lhs_incomplete)
+DIAG_NAME_INDEX(note_atomic_property_fixup_suggest)
+DIAG_NAME_INDEX(note_attribute)
+DIAG_NAME_INDEX(note_attribute_overloadable_prev_overload)
+DIAG_NAME_INDEX(note_auto_readonly_iboutlet_fixup_suggest)
+DIAG_NAME_INDEX(note_availability_specified_here)
+DIAG_NAME_INDEX(note_bad_memaccess_silence)
+DIAG_NAME_INDEX(note_base_class_specified_here)
+DIAG_NAME_INDEX(note_bitfield_decl)
+DIAG_NAME_INDEX(note_block_var_fixit_add_initialization)
+DIAG_NAME_INDEX(note_bracket_depth)
+DIAG_NAME_INDEX(note_callee_decl)
+DIAG_NAME_INDEX(note_callee_static_array)
+DIAG_NAME_INDEX(note_cannot_inherit)
+DIAG_NAME_INDEX(note_carries_dependency_missing_first_decl)
+DIAG_NAME_INDEX(note_class_declared)
+DIAG_NAME_INDEX(note_compat_assoc)
+DIAG_NAME_INDEX(note_condition_assign_silence)
+DIAG_NAME_INDEX(note_condition_assign_to_comparison)
+DIAG_NAME_INDEX(note_condition_or_assign_to_comparison)
+DIAG_NAME_INDEX(note_constexpr_access_inactive_union_member)
+DIAG_NAME_INDEX(note_constexpr_access_null)
+DIAG_NAME_INDEX(note_constexpr_access_past_end)
+DIAG_NAME_INDEX(note_constexpr_access_static_temporary)
+DIAG_NAME_INDEX(note_constexpr_access_uninit)
+DIAG_NAME_INDEX(note_constexpr_access_volatile_obj)
+DIAG_NAME_INDEX(note_constexpr_access_volatile_type)
+DIAG_NAME_INDEX(note_constexpr_array_index)
+DIAG_NAME_INDEX(note_constexpr_body_previous_return)
+DIAG_NAME_INDEX(note_constexpr_call_here)
+DIAG_NAME_INDEX(note_constexpr_call_limit_exceeded)
+DIAG_NAME_INDEX(note_constexpr_calls_suppressed)
+DIAG_NAME_INDEX(note_constexpr_compare_virtual_mem_ptr)
+DIAG_NAME_INDEX(note_constexpr_conditional_never_const)
+DIAG_NAME_INDEX(note_constexpr_ctor_missing_init)
+DIAG_NAME_INDEX(note_constexpr_depth_limit_exceeded)
+DIAG_NAME_INDEX(note_constexpr_float_arithmetic)
+DIAG_NAME_INDEX(note_constexpr_invalid_cast)
+DIAG_NAME_INDEX(note_constexpr_invalid_downcast)
+DIAG_NAME_INDEX(note_constexpr_invalid_function)
+DIAG_NAME_INDEX(note_constexpr_large_shift)
+DIAG_NAME_INDEX(note_constexpr_lifetime_ended)
+DIAG_NAME_INDEX(note_constexpr_lshift_discards)
+DIAG_NAME_INDEX(note_constexpr_lshift_of_negative)
+DIAG_NAME_INDEX(note_constexpr_ltor_mutable)
+DIAG_NAME_INDEX(note_constexpr_ltor_non_const_int)
+DIAG_NAME_INDEX(note_constexpr_ltor_non_constexpr)
+DIAG_NAME_INDEX(note_constexpr_modify_const_type)
+DIAG_NAME_INDEX(note_constexpr_modify_global)
+DIAG_NAME_INDEX(note_constexpr_negative_shift)
+DIAG_NAME_INDEX(note_constexpr_no_return)
+DIAG_NAME_INDEX(note_constexpr_non_global)
+DIAG_NAME_INDEX(note_constexpr_nonliteral)
+DIAG_NAME_INDEX(note_constexpr_null_subobject)
+DIAG_NAME_INDEX(note_constexpr_overflow)
+DIAG_NAME_INDEX(note_constexpr_past_end)
+DIAG_NAME_INDEX(note_constexpr_past_end_subobject)
+DIAG_NAME_INDEX(note_constexpr_pointer_comparison_base_classes)
+DIAG_NAME_INDEX(note_constexpr_pointer_comparison_base_field)
+DIAG_NAME_INDEX(note_constexpr_pointer_comparison_differing_access)
+DIAG_NAME_INDEX(note_constexpr_pointer_subtraction_not_same_array)
+DIAG_NAME_INDEX(note_constexpr_pointer_subtraction_zero_size)
+DIAG_NAME_INDEX(note_constexpr_step_limit_exceeded)
+DIAG_NAME_INDEX(note_constexpr_stmt_expr_unsupported)
+DIAG_NAME_INDEX(note_constexpr_temporary_here)
+DIAG_NAME_INDEX(note_constexpr_this)
+DIAG_NAME_INDEX(note_constexpr_typeid_polymorphic)
+DIAG_NAME_INDEX(note_constexpr_uninitialized)
+DIAG_NAME_INDEX(note_constexpr_use_uninit_reference)
+DIAG_NAME_INDEX(note_constexpr_var_init_non_constant)
+DIAG_NAME_INDEX(note_constexpr_virtual_base)
+DIAG_NAME_INDEX(note_constexpr_virtual_base_here)
+DIAG_NAME_INDEX(note_constexpr_virtual_call)
+DIAG_NAME_INDEX(note_constexpr_void_comparison)
+DIAG_NAME_INDEX(note_constructor_declared_here)
+DIAG_NAME_INDEX(note_convert_inline_to_static)
+DIAG_NAME_INDEX(note_decl_hiding_tag_type)
+DIAG_NAME_INDEX(note_declaration_not_a_prototype)
+DIAG_NAME_INDEX(note_declared_at)
+DIAG_NAME_INDEX(note_default_arg_instantiation_here)
+DIAG_NAME_INDEX(note_default_argument_declared_here)
+DIAG_NAME_INDEX(note_default_function_arg_instantiation_here)
+DIAG_NAME_INDEX(note_defined_here)
+DIAG_NAME_INDEX(note_delete_conversion)
+DIAG_NAME_INDEX(note_deleted_assign_field)
+DIAG_NAME_INDEX(note_deleted_copy_ctor_rvalue_reference)
+DIAG_NAME_INDEX(note_deleted_copy_user_declared_move)
+DIAG_NAME_INDEX(note_deleted_default_ctor_all_const)
+DIAG_NAME_INDEX(note_deleted_default_ctor_uninit_field)
+DIAG_NAME_INDEX(note_deleted_dtor_no_operator_delete)
+DIAG_NAME_INDEX(note_deleted_special_member_class_subobject)
+DIAG_NAME_INDEX(note_dependent_non_type_default_arg_in_partial_spec)
+DIAG_NAME_INDEX(note_dependent_var_use)
+DIAG_NAME_INDEX(note_destructor_type_here)
+DIAG_NAME_INDEX(note_doc_block_command_previous)
+DIAG_NAME_INDEX(note_doc_block_command_previous_alias)
+DIAG_NAME_INDEX(note_doc_html_end_tag)
+DIAG_NAME_INDEX(note_doc_html_tag_started_here)
+DIAG_NAME_INDEX(note_doc_param_name_suggestion)
+DIAG_NAME_INDEX(note_doc_param_previous)
+DIAG_NAME_INDEX(note_doc_tparam_name_suggestion)
+DIAG_NAME_INDEX(note_doc_tparam_previous)
+DIAG_NAME_INDEX(note_drv_command_failed_diag_msg)
+DIAG_NAME_INDEX(note_drv_t_option_is_global)
+DIAG_NAME_INDEX(note_duplicate_case_prev)
+DIAG_NAME_INDEX(note_duplicate_element)
+DIAG_NAME_INDEX(note_empty_body_on_separate_line)
+DIAG_NAME_INDEX(note_empty_parens_default_ctor)
+DIAG_NAME_INDEX(note_empty_parens_function_call)
+DIAG_NAME_INDEX(note_empty_parens_zero_initialize)
+DIAG_NAME_INDEX(note_enters_block_captures_cxx_obj)
+DIAG_NAME_INDEX(note_enters_block_captures_strong)
+DIAG_NAME_INDEX(note_enters_block_captures_weak)
+DIAG_NAME_INDEX(note_entity_declared_at)
+DIAG_NAME_INDEX(note_enum_specialized_here)
+DIAG_NAME_INDEX(note_equality_comparison_silence)
+DIAG_NAME_INDEX(note_equality_comparison_to_assign)
+DIAG_NAME_INDEX(note_evaluate_comparison_first)
+DIAG_NAME_INDEX(note_exception_spec_deprecated)
+DIAG_NAME_INDEX(note_exits___block)
+DIAG_NAME_INDEX(note_exits_block_captures_cxx_obj)
+DIAG_NAME_INDEX(note_exits_block_captures_strong)
+DIAG_NAME_INDEX(note_exits_block_captures_weak)
+DIAG_NAME_INDEX(note_exits_cleanup)
+DIAG_NAME_INDEX(note_exits_cxx_catch)
+DIAG_NAME_INDEX(note_exits_cxx_try)
+DIAG_NAME_INDEX(note_exits_dtor)
+DIAG_NAME_INDEX(note_exits_objc_autoreleasepool)
+DIAG_NAME_INDEX(note_exits_objc_catch)
+DIAG_NAME_INDEX(note_exits_objc_finally)
+DIAG_NAME_INDEX(note_exits_objc_ownership)
+DIAG_NAME_INDEX(note_exits_objc_synchronized)
+DIAG_NAME_INDEX(note_exits_objc_try)
+DIAG_NAME_INDEX(note_exits_temporary_dtor)
+DIAG_NAME_INDEX(note_explicit_instantiation_candidate)
+DIAG_NAME_INDEX(note_explicit_instantiation_definition_here)
+DIAG_NAME_INDEX(note_explicit_instantiation_here)
+DIAG_NAME_INDEX(note_explicit_template_arg_substitution_here)
+DIAG_NAME_INDEX(note_explicit_template_spec_does_not_need_header)
+DIAG_NAME_INDEX(note_expr_divide_by_zero)
+DIAG_NAME_INDEX(note_extern_c_global_conflict)
+DIAG_NAME_INDEX(note_extra_comma_message_arg)
+DIAG_NAME_INDEX(note_fallthrough_insert_semi_fixit)
+DIAG_NAME_INDEX(note_fe_backend_frame_larger_than)
+DIAG_NAME_INDEX(note_fe_backend_optimization_remark_invalid_loc)
+DIAG_NAME_INDEX(note_fe_backend_plugin)
+DIAG_NAME_INDEX(note_fe_inline_asm)
+DIAG_NAME_INDEX(note_fe_inline_asm_here)
+DIAG_NAME_INDEX(note_field_designator_found)
+DIAG_NAME_INDEX(note_final_overrider)
+DIAG_NAME_INDEX(note_fixit_applied)
+DIAG_NAME_INDEX(note_fixit_failed)
+DIAG_NAME_INDEX(note_fixit_in_macro)
+DIAG_NAME_INDEX(note_fixit_unfixed_error)
+DIAG_NAME_INDEX(note_flexible_array_member)
+DIAG_NAME_INDEX(note_for_range_begin_end)
+DIAG_NAME_INDEX(note_for_range_invalid_iterator)
+DIAG_NAME_INDEX(note_force_empty_selector_name)
+DIAG_NAME_INDEX(note_format_fix_specifier)
+DIAG_NAME_INDEX(note_format_string_defined)
+DIAG_NAME_INDEX(note_forward_class)
+DIAG_NAME_INDEX(note_forward_declaration)
+DIAG_NAME_INDEX(note_found_mutex_near_match)
+DIAG_NAME_INDEX(note_function_suggestion)
+DIAG_NAME_INDEX(note_function_template_deduction_instantiation_here)
+DIAG_NAME_INDEX(note_function_template_spec_here)
+DIAG_NAME_INDEX(note_function_template_spec_matched)
+DIAG_NAME_INDEX(note_function_to_function_call)
+DIAG_NAME_INDEX(note_function_warning_silence)
+DIAG_NAME_INDEX(note_getter_unavailable)
+DIAG_NAME_INDEX(note_header_guard)
+DIAG_NAME_INDEX(note_hidden_overloaded_virtual_declared_here)
+DIAG_NAME_INDEX(note_hidden_tag)
+DIAG_NAME_INDEX(note_hiding_object)
+DIAG_NAME_INDEX(note_ice_conversion_here)
+DIAG_NAME_INDEX(note_illegal_field_declared_here)
+DIAG_NAME_INDEX(note_implementation_declared)
+DIAG_NAME_INDEX(note_implemented_by_class)
+DIAG_NAME_INDEX(note_implicit_param_decl)
+DIAG_NAME_INDEX(note_implicitly_deleted)
+DIAG_NAME_INDEX(note_in_class_initializer_float_type_cxx11)
+DIAG_NAME_INDEX(note_in_for_range)
+DIAG_NAME_INDEX(note_in_omitted_aggregate_initializer)
+DIAG_NAME_INDEX(note_include_header_or_declare)
+DIAG_NAME_INDEX(note_incompatible_analyzer_plugin_api)
+DIAG_NAME_INDEX(note_indirect_goto_target)
+DIAG_NAME_INDEX(note_indirection_through_null)
+DIAG_NAME_INDEX(note_inequality_comparison_to_or_assign)
+DIAG_NAME_INDEX(note_inhctor_synthesized_at)
+DIAG_NAME_INDEX(note_inherited_deleted_here)
+DIAG_NAME_INDEX(note_init_list_at_beginning_of_macro_argument)
+DIAG_NAME_INDEX(note_init_list_narrowing_silence)
+DIAG_NAME_INDEX(note_insert_break_fixit)
+DIAG_NAME_INDEX(note_insert_fallthrough_fixit)
+DIAG_NAME_INDEX(note_instantiation_contexts_suppressed)
+DIAG_NAME_INDEX(note_instantiation_required_here)
+DIAG_NAME_INDEX(note_invalid_subexpr_in_const_expr)
+DIAG_NAME_INDEX(note_it_delegates_to)
+DIAG_NAME_INDEX(note_ivar_decl)
+DIAG_NAME_INDEX(note_lambda_decl)
+DIAG_NAME_INDEX(note_lambda_to_block_conv)
+DIAG_NAME_INDEX(note_local_decl_close_match)
+DIAG_NAME_INDEX(note_local_decl_close_param_match)
+DIAG_NAME_INDEX(note_lock_exclusive_and_shared)
+DIAG_NAME_INDEX(note_locked_here)
+DIAG_NAME_INDEX(note_logical_instead_of_bitwise_change_operator)
+DIAG_NAME_INDEX(note_logical_instead_of_bitwise_remove_constant)
+DIAG_NAME_INDEX(note_logical_not_fix)
+DIAG_NAME_INDEX(note_logical_not_silence_with_parens)
+DIAG_NAME_INDEX(note_loop_iteration_here)
+DIAG_NAME_INDEX(note_macro_here)
+DIAG_NAME_INDEX(note_main_change_return_type)
+DIAG_NAME_INDEX(note_main_remove_noreturn)
+DIAG_NAME_INDEX(note_matching)
+DIAG_NAME_INDEX(note_member_declared_at)
+DIAG_NAME_INDEX(note_member_declared_here)
+DIAG_NAME_INDEX(note_member_def_close_const_match)
+DIAG_NAME_INDEX(note_member_def_close_match)
+DIAG_NAME_INDEX(note_member_def_close_param_match)
+DIAG_NAME_INDEX(note_member_reference_arrow_from_operator_arrow)
+DIAG_NAME_INDEX(note_member_synthesized_at)
+DIAG_NAME_INDEX(note_memsize_comparison_cast_silence)
+DIAG_NAME_INDEX(note_memsize_comparison_paren)
+DIAG_NAME_INDEX(note_method_declared_at)
+DIAG_NAME_INDEX(note_method_return_type_change)
+DIAG_NAME_INDEX(note_method_sent_forward_class)
+DIAG_NAME_INDEX(note_missing_end_of_definition_before)
+DIAG_NAME_INDEX(note_missing_selector_name)
+DIAG_NAME_INDEX(note_mmap_lbrace_match)
+DIAG_NAME_INDEX(note_mmap_lsquare_match)
+DIAG_NAME_INDEX(note_mmap_prev_definition)
+DIAG_NAME_INDEX(note_module_cache_path)
+DIAG_NAME_INDEX(note_module_def_undef_here)
+DIAG_NAME_INDEX(note_module_import_in_extern_c)
+DIAG_NAME_INDEX(note_module_import_not_at_top_level)
+DIAG_NAME_INDEX(note_module_odr_violation_different_definitions)
+DIAG_NAME_INDEX(note_module_odr_violation_no_possible_decls)
+DIAG_NAME_INDEX(note_module_odr_violation_possible_decl)
+DIAG_NAME_INDEX(note_mt_message)
+DIAG_NAME_INDEX(note_namespace_defined_here)
+DIAG_NAME_INDEX(note_neon_vector_initializer_non_portable)
+DIAG_NAME_INDEX(note_neon_vector_initializer_non_portable_q)
+DIAG_NAME_INDEX(note_non_instantiated_member_here)
+DIAG_NAME_INDEX(note_non_literal_base_class)
+DIAG_NAME_INDEX(note_non_literal_field)
+DIAG_NAME_INDEX(note_non_literal_incomplete)
+DIAG_NAME_INDEX(note_non_literal_no_constexpr_ctors)
+DIAG_NAME_INDEX(note_non_literal_nontrivial_dtor)
+DIAG_NAME_INDEX(note_non_literal_user_provided_dtor)
+DIAG_NAME_INDEX(note_non_literal_virtual_base)
+DIAG_NAME_INDEX(note_nontemplate_decl_here)
+DIAG_NAME_INDEX(note_nontrivial_default_arg)
+DIAG_NAME_INDEX(note_nontrivial_has_virtual)
+DIAG_NAME_INDEX(note_nontrivial_in_class_init)
+DIAG_NAME_INDEX(note_nontrivial_no_copy)
+DIAG_NAME_INDEX(note_nontrivial_no_def_ctor)
+DIAG_NAME_INDEX(note_nontrivial_objc_ownership)
+DIAG_NAME_INDEX(note_nontrivial_param_type)
+DIAG_NAME_INDEX(note_nontrivial_subobject)
+DIAG_NAME_INDEX(note_nontrivial_user_provided)
+DIAG_NAME_INDEX(note_nontrivial_variadic)
+DIAG_NAME_INDEX(note_nontrivial_virtual_dtor)
+DIAG_NAME_INDEX(note_noreturn_missing_first_decl)
+DIAG_NAME_INDEX(note_not_found_by_two_phase_lookup)
+DIAG_NAME_INDEX(note_objc_container_start)
+DIAG_NAME_INDEX(note_objc_designated_init_marked_here)
+DIAG_NAME_INDEX(note_objc_literal_comparison_isequal)
+DIAG_NAME_INDEX(note_objc_literal_method_param)
+DIAG_NAME_INDEX(note_objc_literal_method_return)
+DIAG_NAME_INDEX(note_objc_needs_superclass)
+DIAG_NAME_INDEX(note_odr_base)
+DIAG_NAME_INDEX(note_odr_bit_field)
+DIAG_NAME_INDEX(note_odr_defined_here)
+DIAG_NAME_INDEX(note_odr_enumerator)
+DIAG_NAME_INDEX(note_odr_field)
+DIAG_NAME_INDEX(note_odr_missing_base)
+DIAG_NAME_INDEX(note_odr_missing_enumerator)
+DIAG_NAME_INDEX(note_odr_missing_field)
+DIAG_NAME_INDEX(note_odr_not_bit_field)
+DIAG_NAME_INDEX(note_odr_number_of_bases)
+DIAG_NAME_INDEX(note_odr_objc_method_here)
+DIAG_NAME_INDEX(note_odr_objc_missing_superclass)
+DIAG_NAME_INDEX(note_odr_objc_property_impl_kind)
+DIAG_NAME_INDEX(note_odr_objc_superclass)
+DIAG_NAME_INDEX(note_odr_objc_synthesize_ivar_here)
+DIAG_NAME_INDEX(note_odr_parameter_pack_non_pack)
+DIAG_NAME_INDEX(note_odr_tag_kind_here)
+DIAG_NAME_INDEX(note_odr_template_parameter_here)
+DIAG_NAME_INDEX(note_odr_template_parameter_list)
+DIAG_NAME_INDEX(note_odr_value_here)
+DIAG_NAME_INDEX(note_odr_virtual_base)
+DIAG_NAME_INDEX(note_omp_collapse_expr)
+DIAG_NAME_INDEX(note_omp_conversion_here)
+DIAG_NAME_INDEX(note_omp_explicit_dsa)
+DIAG_NAME_INDEX(note_omp_implicit_dsa)
+DIAG_NAME_INDEX(note_omp_loop_cond_requres_compatible_incr)
+DIAG_NAME_INDEX(note_omp_predetermined_dsa)
+DIAG_NAME_INDEX(note_omp_previous_critical_region)
+DIAG_NAME_INDEX(note_omp_referenced)
+DIAG_NAME_INDEX(note_operator_arrow_depth)
+DIAG_NAME_INDEX(note_operator_arrow_here)
+DIAG_NAME_INDEX(note_operator_arrows_suppressed)
+DIAG_NAME_INDEX(note_overridden_method)
+DIAG_NAME_INDEX(note_overridden_virtual_function)
+DIAG_NAME_INDEX(note_ovl_builtin_binary_candidate)
+DIAG_NAME_INDEX(note_ovl_builtin_unary_candidate)
+DIAG_NAME_INDEX(note_ovl_candidate)
+DIAG_NAME_INDEX(note_ovl_candidate_arity)
+DIAG_NAME_INDEX(note_ovl_candidate_arity_one)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_addrspace)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_arc_conv)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_base_to_derived_conv)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_conv)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_conv_incomplete)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_cvr)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_cvr_this)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_deduction)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_gc)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_list_argument)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_lvalue)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_overload)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_ownership)
+DIAG_NAME_INDEX(note_ovl_candidate_bad_target)
+DIAG_NAME_INDEX(note_ovl_candidate_deleted)
+DIAG_NAME_INDEX(note_ovl_candidate_disabled_by_enable_if)
+DIAG_NAME_INDEX(note_ovl_candidate_disabled_by_enable_if_attr)
+DIAG_NAME_INDEX(note_ovl_candidate_explicit_arg_mismatch_named)
+DIAG_NAME_INDEX(note_ovl_candidate_explicit_arg_mismatch_unnamed)
+DIAG_NAME_INDEX(note_ovl_candidate_failed_overload_resolution)
+DIAG_NAME_INDEX(note_ovl_candidate_incomplete_deduction)
+DIAG_NAME_INDEX(note_ovl_candidate_inconsistent_deduction)
+DIAG_NAME_INDEX(note_ovl_candidate_inherited_constructor)
+DIAG_NAME_INDEX(note_ovl_candidate_instantiation_depth)
+DIAG_NAME_INDEX(note_ovl_candidate_non_deduced_mismatch)
+DIAG_NAME_INDEX(note_ovl_candidate_non_deduced_mismatch_qualified)
+DIAG_NAME_INDEX(note_ovl_candidate_substitution_failure)
+DIAG_NAME_INDEX(note_ovl_candidate_underqualified)
+DIAG_NAME_INDEX(note_ovl_surrogate_cand)
+DIAG_NAME_INDEX(note_ovl_too_many_candidates)
+DIAG_NAME_INDEX(note_parameter_here)
+DIAG_NAME_INDEX(note_parameter_named_here)
+DIAG_NAME_INDEX(note_parameter_pack_here)
+DIAG_NAME_INDEX(note_parameter_type)
+DIAG_NAME_INDEX(note_partial_spec_deduct_instantiation_here)
+DIAG_NAME_INDEX(note_partial_spec_match)
+DIAG_NAME_INDEX(note_partial_spec_unused_parameter)
+DIAG_NAME_INDEX(note_pch_rebuild_required)
+DIAG_NAME_INDEX(note_pch_required_by)
+DIAG_NAME_INDEX(note_possibility)
+DIAG_NAME_INDEX(note_possible_target_of_call)
+DIAG_NAME_INDEX(note_pp_ambiguous_macro_chosen)
+DIAG_NAME_INDEX(note_pp_ambiguous_macro_other)
+DIAG_NAME_INDEX(note_pragma_entered_here)
+DIAG_NAME_INDEX(note_precedence_bitwise_first)
+DIAG_NAME_INDEX(note_precedence_conditional_first)
+DIAG_NAME_INDEX(note_precedence_silence)
+DIAG_NAME_INDEX(note_prev_partial_spec_here)
+DIAG_NAME_INDEX(note_previous_access_declaration)
+DIAG_NAME_INDEX(note_previous_attribute)
+DIAG_NAME_INDEX(note_previous_builtin_declaration)
+DIAG_NAME_INDEX(note_previous_decl)
+DIAG_NAME_INDEX(note_previous_declaration)
+DIAG_NAME_INDEX(note_previous_default_assoc)
+DIAG_NAME_INDEX(note_previous_definition)
+DIAG_NAME_INDEX(note_previous_exception_handler)
+DIAG_NAME_INDEX(note_previous_explicit_instantiation)
+DIAG_NAME_INDEX(note_previous_implicit_declaration)
+DIAG_NAME_INDEX(note_previous_initializer)
+DIAG_NAME_INDEX(note_previous_ms_inheritance)
+DIAG_NAME_INDEX(note_previous_template_specialization)
+DIAG_NAME_INDEX(note_previous_use)
+DIAG_NAME_INDEX(note_printf_c_str)
+DIAG_NAME_INDEX(note_prior_template_arg_substitution)
+DIAG_NAME_INDEX(note_private_extern)
+DIAG_NAME_INDEX(note_property_attribute)
+DIAG_NAME_INDEX(note_property_declare)
+DIAG_NAME_INDEX(note_property_synthesize)
+DIAG_NAME_INDEX(note_protected_by___block)
+DIAG_NAME_INDEX(note_protected_by_cleanup)
+DIAG_NAME_INDEX(note_protected_by_cxx_catch)
+DIAG_NAME_INDEX(note_protected_by_cxx_try)
+DIAG_NAME_INDEX(note_protected_by_objc_autoreleasepool)
+DIAG_NAME_INDEX(note_protected_by_objc_catch)
+DIAG_NAME_INDEX(note_protected_by_objc_finally)
+DIAG_NAME_INDEX(note_protected_by_objc_ownership)
+DIAG_NAME_INDEX(note_protected_by_objc_synchronized)
+DIAG_NAME_INDEX(note_protected_by_objc_try)
+DIAG_NAME_INDEX(note_protected_by_variable_init)
+DIAG_NAME_INDEX(note_protected_by_variable_non_pod)
+DIAG_NAME_INDEX(note_protected_by_variable_nontriv_destructor)
+DIAG_NAME_INDEX(note_protected_by_vla)
+DIAG_NAME_INDEX(note_protected_by_vla_type_alias)
+DIAG_NAME_INDEX(note_protected_by_vla_typedef)
+DIAG_NAME_INDEX(note_protocol_decl)
+DIAG_NAME_INDEX(note_protocol_decl_undefined)
+DIAG_NAME_INDEX(note_protocol_property_declare)
+DIAG_NAME_INDEX(note_pure_virtual_function)
+DIAG_NAME_INDEX(note_receiver_class_declared)
+DIAG_NAME_INDEX(note_receiver_is_id)
+DIAG_NAME_INDEX(note_ref_or_ptr_member_declared_here)
+DIAG_NAME_INDEX(note_ref_subobject_of_member_declared_here)
+DIAG_NAME_INDEX(note_ref_var_local_bind)
+DIAG_NAME_INDEX(note_refconst_member_not_initialized)
+DIAG_NAME_INDEX(note_reference_is_return_value)
+DIAG_NAME_INDEX(note_referenced_class_template)
+DIAG_NAME_INDEX(note_reinterpret_updowncast_use_static)
+DIAG_NAME_INDEX(note_related_result_type_explicit)
+DIAG_NAME_INDEX(note_related_result_type_family)
+DIAG_NAME_INDEX(note_related_result_type_inferred)
+DIAG_NAME_INDEX(note_related_result_type_overridden)
+DIAG_NAME_INDEX(note_remove_abs)
+DIAG_NAME_INDEX(note_replace_abs_function)
+DIAG_NAME_INDEX(note_sentinel_here)
+DIAG_NAME_INDEX(note_specialized_decl)
+DIAG_NAME_INDEX(note_specialized_entity)
+DIAG_NAME_INDEX(note_string_plus_scalar_silence)
+DIAG_NAME_INDEX(note_strlcpycat_wrong_size)
+DIAG_NAME_INDEX(note_strncat_wrong_size)
+DIAG_NAME_INDEX(note_struct_class_suggestion)
+DIAG_NAME_INDEX(note_suggest_parens_for_macro)
+DIAG_NAME_INDEX(note_suppressed_class_declare)
+DIAG_NAME_INDEX(note_surrounding_namespace_ends_here)
+DIAG_NAME_INDEX(note_surrounding_namespace_starts_here)
+DIAG_NAME_INDEX(note_switch_conversion)
+DIAG_NAME_INDEX(note_template_arg_internal_object)
+DIAG_NAME_INDEX(note_template_arg_refers_here)
+DIAG_NAME_INDEX(note_template_arg_refers_here_func)
+DIAG_NAME_INDEX(note_template_class_explicit_specialization_was_here)
+DIAG_NAME_INDEX(note_template_class_instantiation_here)
+DIAG_NAME_INDEX(note_template_class_instantiation_was_here)
+DIAG_NAME_INDEX(note_template_decl_here)
+DIAG_NAME_INDEX(note_template_declared_here)
+DIAG_NAME_INDEX(note_template_default_arg_checking)
+DIAG_NAME_INDEX(note_template_enum_def_here)
+DIAG_NAME_INDEX(note_template_exception_spec_instantiation_here)
+DIAG_NAME_INDEX(note_template_member_class_here)
+DIAG_NAME_INDEX(note_template_member_function_here)
+DIAG_NAME_INDEX(note_template_nontype_parm_different_type)
+DIAG_NAME_INDEX(note_template_nontype_parm_prev_declaration)
+DIAG_NAME_INDEX(note_template_param_different_kind)
+DIAG_NAME_INDEX(note_template_param_here)
+DIAG_NAME_INDEX(note_template_param_list_different_arity)
+DIAG_NAME_INDEX(note_template_param_prev_default_arg)
+DIAG_NAME_INDEX(note_template_parameter_pack_here)
+DIAG_NAME_INDEX(note_template_parameter_pack_non_pack)
+DIAG_NAME_INDEX(note_template_prev_declaration)
+DIAG_NAME_INDEX(note_template_recursion_depth)
+DIAG_NAME_INDEX(note_template_static_data_member_def_here)
+DIAG_NAME_INDEX(note_template_type_alias_instantiation_here)
+DIAG_NAME_INDEX(note_template_unnamed_type_here)
+DIAG_NAME_INDEX(note_template_variable_def_here)
+DIAG_NAME_INDEX(note_transparent_union_first_field_size_align)
+DIAG_NAME_INDEX(note_type_being_defined)
+DIAG_NAME_INDEX(note_typecheck_member_reference_suggestion)
+DIAG_NAME_INDEX(note_typedef_changes_linkage)
+DIAG_NAME_INDEX(note_typename_refers_here)
+DIAG_NAME_INDEX(note_ucn_four_not_eight)
+DIAG_NAME_INDEX(note_uninit_fixit_remove_cond)
+DIAG_NAME_INDEX(note_uninit_in_this_constructor)
+DIAG_NAME_INDEX(note_uninit_reference_member)
+DIAG_NAME_INDEX(note_uninit_var_def)
+DIAG_NAME_INDEX(note_uninit_var_use)
+DIAG_NAME_INDEX(note_unreachable_silence)
+DIAG_NAME_INDEX(note_use_thread_local)
+DIAG_NAME_INDEX(note_used_here)
+DIAG_NAME_INDEX(note_used_in_initialization_here)
+DIAG_NAME_INDEX(note_user_declared_ctor)
+DIAG_NAME_INDEX(note_using)
+DIAG_NAME_INDEX(note_using_decl)
+DIAG_NAME_INDEX(note_using_decl_class_member_workaround)
+DIAG_NAME_INDEX(note_using_decl_conflict)
+DIAG_NAME_INDEX(note_using_decl_constructor_conflict_current_ctor)
+DIAG_NAME_INDEX(note_using_decl_constructor_conflict_previous_ctor)
+DIAG_NAME_INDEX(note_using_decl_constructor_conflict_previous_using)
+DIAG_NAME_INDEX(note_using_decl_constructor_ellipsis)
+DIAG_NAME_INDEX(note_using_decl_target)
+DIAG_NAME_INDEX(note_using_value_decl_missing_typename)
+DIAG_NAME_INDEX(note_value_initialization_here)
+DIAG_NAME_INDEX(note_var_fixit_add_initialization)
+DIAG_NAME_INDEX(note_var_prev_partial_spec_here)
+DIAG_NAME_INDEX(note_vbase_moved_here)
+DIAG_NAME_INDEX(note_which_delegates_to)
+DIAG_NAME_INDEX(note_while_in_implementation)
+DIAG_NAME_INDEX(note_within_field_of_type)
+DIAG_NAME_INDEX(null_in_char)
+DIAG_NAME_INDEX(null_in_file)
+DIAG_NAME_INDEX(null_in_string)
+DIAG_NAME_INDEX(override_keyword_hides_virtual_member_function)
+DIAG_NAME_INDEX(override_keyword_only_allowed_on_virtual_member_functions)
+DIAG_NAME_INDEX(pp_disabled_macro_expansion)
+DIAG_NAME_INDEX(pp_err_elif_after_else)
+DIAG_NAME_INDEX(pp_err_elif_without_if)
+DIAG_NAME_INDEX(pp_err_else_after_else)
+DIAG_NAME_INDEX(pp_err_else_without_if)
+DIAG_NAME_INDEX(pp_hash_warning)
+DIAG_NAME_INDEX(pp_include_macros_out_of_predefines)
+DIAG_NAME_INDEX(pp_include_next_absolute_path)
+DIAG_NAME_INDEX(pp_include_next_in_primary)
+DIAG_NAME_INDEX(pp_invalid_string_literal)
+DIAG_NAME_INDEX(pp_macro_not_used)
+DIAG_NAME_INDEX(pp_out_of_date_dependency)
+DIAG_NAME_INDEX(pp_poisoning_existing_macro)
+DIAG_NAME_INDEX(pp_pragma_once_in_main_file)
+DIAG_NAME_INDEX(pp_pragma_sysheader_in_main_file)
+DIAG_NAME_INDEX(remark_fe_backend_optimization_remark)
+DIAG_NAME_INDEX(remark_fe_backend_optimization_remark_analysis)
+DIAG_NAME_INDEX(remark_fe_backend_optimization_remark_missed)
+DIAG_NAME_INDEX(remark_fe_backend_plugin)
+DIAG_NAME_INDEX(remark_module_build)
+DIAG_NAME_INDEX(trigraph_converted)
+DIAG_NAME_INDEX(trigraph_ends_block_comment)
+DIAG_NAME_INDEX(trigraph_ignored)
+DIAG_NAME_INDEX(trigraph_ignored_block_comment)
+DIAG_NAME_INDEX(w_asm_qualifier_ignored)
+DIAG_NAME_INDEX(warn_O4_is_O3)
+DIAG_NAME_INDEX(warn_abs_too_small)
+DIAG_NAME_INDEX(warn_abstract_final_class)
+DIAG_NAME_INDEX(warn_abstract_vbase_init_ignored)
+DIAG_NAME_INDEX(warn_access_decl_deprecated)
+DIAG_NAME_INDEX(warn_accessor_property_type_mismatch)
+DIAG_NAME_INDEX(warn_addition_in_bitshift)
+DIAG_NAME_INDEX(warn_address_of_reference_bool_conversion)
+DIAG_NAME_INDEX(warn_address_of_reference_null_compare)
+DIAG_NAME_INDEX(warn_alias_to_weak_alias)
+DIAG_NAME_INDEX(warn_alias_with_section)
+DIAG_NAME_INDEX(warn_anon_bitfield_width_exceeds_type_size)
+DIAG_NAME_INDEX(warn_arc_bridge_cast_nonarc)
+DIAG_NAME_INDEX(warn_arc_lifetime_result_type)
+DIAG_NAME_INDEX(warn_arc_literal_assign)
+DIAG_NAME_INDEX(warn_arc_object_memaccess)
+DIAG_NAME_INDEX(warn_arc_perform_selector_leaks)
+DIAG_NAME_INDEX(warn_arc_possible_repeated_use_of_weak)
+DIAG_NAME_INDEX(warn_arc_repeated_use_of_weak)
+DIAG_NAME_INDEX(warn_arc_retain_cycle)
+DIAG_NAME_INDEX(warn_arc_retained_assign)
+DIAG_NAME_INDEX(warn_arc_retained_property_assign)
+DIAG_NAME_INDEX(warn_arc_strong_pointer_objc_pointer)
+DIAG_NAME_INDEX(warn_arcmt_nsalloc_realloc)
+DIAG_NAME_INDEX(warn_array_index_exceeds_bounds)
+DIAG_NAME_INDEX(warn_array_index_precedes_bounds)
+DIAG_NAME_INDEX(warn_array_new_too_large)
+DIAG_NAME_INDEX(warn_asm_label_on_auto_decl)
+DIAG_NAME_INDEX(warn_asm_mismatched_size_modifier)
+DIAG_NAME_INDEX(warn_assume_side_effects)
+DIAG_NAME_INDEX(warn_atomic_op_has_invalid_memory_order)
+DIAG_NAME_INDEX(warn_atomic_property_rule)
+DIAG_NAME_INDEX(warn_attr_on_unconsumable_class)
+DIAG_NAME_INDEX(warn_attribute_after_definition_ignored)
+DIAG_NAME_INDEX(warn_attribute_dll_instantiated_base_class)
+DIAG_NAME_INDEX(warn_attribute_dll_redeclaration)
+DIAG_NAME_INDEX(warn_attribute_dllimport_static_field_definition)
+DIAG_NAME_INDEX(warn_attribute_iboutlet)
+DIAG_NAME_INDEX(warn_attribute_ignored)
+DIAG_NAME_INDEX(warn_attribute_ignored_for_field_of_type)
+DIAG_NAME_INDEX(warn_attribute_invalid_on_definition)
+DIAG_NAME_INDEX(warn_attribute_malloc_pointer_only)
+DIAG_NAME_INDEX(warn_attribute_no_decl)
+DIAG_NAME_INDEX(warn_attribute_nonnull_no_pointers)
+DIAG_NAME_INDEX(warn_attribute_nonnull_parm_no_args)
+DIAG_NAME_INDEX(warn_attribute_not_on_decl)
+DIAG_NAME_INDEX(warn_attribute_on_function_definition)
+DIAG_NAME_INDEX(warn_attribute_pointers_only)
+DIAG_NAME_INDEX(warn_attribute_precede_definition)
+DIAG_NAME_INDEX(warn_attribute_protected_visibility)
+DIAG_NAME_INDEX(warn_attribute_requires_functions_or_static_globals)
+DIAG_NAME_INDEX(warn_attribute_return_pointers_only)
+DIAG_NAME_INDEX(warn_attribute_sentinel_named_arguments)
+DIAG_NAME_INDEX(warn_attribute_sentinel_not_variadic)
+DIAG_NAME_INDEX(warn_attribute_type_not_supported)
+DIAG_NAME_INDEX(warn_attribute_unknown_visibility)
+DIAG_NAME_INDEX(warn_attribute_void_function_method)
+DIAG_NAME_INDEX(warn_attribute_weak_on_field)
+DIAG_NAME_INDEX(warn_attribute_weak_on_local)
+DIAG_NAME_INDEX(warn_attribute_wrong_decl_type)
+DIAG_NAME_INDEX(warn_auto_implicit_atomic_property)
+DIAG_NAME_INDEX(warn_auto_module_import)
+DIAG_NAME_INDEX(warn_auto_readonly_iboutlet_property)
+DIAG_NAME_INDEX(warn_auto_storage_class)
+DIAG_NAME_INDEX(warn_auto_synthesizing_protocol_property)
+DIAG_NAME_INDEX(warn_auto_var_is_id)
+DIAG_NAME_INDEX(warn_autosynthesis_property_ivar_match)
+DIAG_NAME_INDEX(warn_availability_and_unavailable)
+DIAG_NAME_INDEX(warn_availability_unknown_platform)
+DIAG_NAME_INDEX(warn_availability_version_ordering)
+DIAG_NAME_INDEX(warn_bad_character_encoding)
+DIAG_NAME_INDEX(warn_bad_function_cast)
+DIAG_NAME_INDEX(warn_bad_receiver_type)
+DIAG_NAME_INDEX(warn_bad_string_encoding)
+DIAG_NAME_INDEX(warn_bind_ref_member_to_parameter)
+DIAG_NAME_INDEX(warn_bind_ref_member_to_temporary)
+DIAG_NAME_INDEX(warn_bitfield_width_exceeds_type_size)
+DIAG_NAME_INDEX(warn_bitwise_and_in_bitwise_or)
+DIAG_NAME_INDEX(warn_bool_switch_condition)
+DIAG_NAME_INDEX(warn_braces_around_scalar_init)
+DIAG_NAME_INDEX(warn_break_binds_to_switch)
+DIAG_NAME_INDEX(warn_builtin_unknown)
+DIAG_NAME_INDEX(warn_c99_compat_unicode_id)
+DIAG_NAME_INDEX(warn_c99_compat_unicode_literal)
+DIAG_NAME_INDEX(warn_c_kext)
+DIAG_NAME_INDEX(warn_call_to_pure_virtual_member_function_from_ctor_dtor)
+DIAG_NAME_INDEX(warn_call_wrong_number_of_arguments)
+DIAG_NAME_INDEX(warn_cannot_pass_non_pod_arg_to_vararg)
+DIAG_NAME_INDEX(warn_cannot_resolve_lock)
+DIAG_NAME_INDEX(warn_case_empty_range)
+DIAG_NAME_INDEX(warn_case_value_overflow)
+DIAG_NAME_INDEX(warn_cast_align)
+DIAG_NAME_INDEX(warn_cast_pointer_from_sel)
+DIAG_NAME_INDEX(warn_category_method_impl_match)
+DIAG_NAME_INDEX(warn_cconv_ignored)
+DIAG_NAME_INDEX(warn_cconv_varargs)
+DIAG_NAME_INDEX(warn_cfstring_truncated)
+DIAG_NAME_INDEX(warn_char_constant_too_large)
+DIAG_NAME_INDEX(warn_class_method_not_found)
+DIAG_NAME_INDEX(warn_class_method_not_found_with_typo)
+DIAG_NAME_INDEX(warn_cleanup_ext)
+DIAG_NAME_INDEX(warn_cocoa_naming_owned_rule)
+DIAG_NAME_INDEX(warn_collection_expr_type)
+DIAG_NAME_INDEX(warn_comparison_always)
+DIAG_NAME_INDEX(warn_comparison_bitwise_always)
+DIAG_NAME_INDEX(warn_comparison_of_mixed_enum_types)
+DIAG_NAME_INDEX(warn_concatenated_nsarray_literal)
+DIAG_NAME_INDEX(warn_condition_is_assignment)
+DIAG_NAME_INDEX(warn_condition_is_idiomatic_assignment)
+DIAG_NAME_INDEX(warn_conflicting_overriding_param_modifiers)
+DIAG_NAME_INDEX(warn_conflicting_overriding_param_types)
+DIAG_NAME_INDEX(warn_conflicting_overriding_ret_type_modifiers)
+DIAG_NAME_INDEX(warn_conflicting_overriding_ret_types)
+DIAG_NAME_INDEX(warn_conflicting_overriding_variadic)
+DIAG_NAME_INDEX(warn_conflicting_param_modifiers)
+DIAG_NAME_INDEX(warn_conflicting_param_types)
+DIAG_NAME_INDEX(warn_conflicting_ret_type_modifiers)
+DIAG_NAME_INDEX(warn_conflicting_ret_types)
+DIAG_NAME_INDEX(warn_conflicting_variadic)
+DIAG_NAME_INDEX(warn_conv_to_base_not_used)
+DIAG_NAME_INDEX(warn_conv_to_self_not_used)
+DIAG_NAME_INDEX(warn_conv_to_void_not_used)
+DIAG_NAME_INDEX(warn_correct_comment_command_name)
+DIAG_NAME_INDEX(warn_cstyle_param)
+DIAG_NAME_INDEX(warn_cxx11_compat_binary_literal)
+DIAG_NAME_INDEX(warn_cxx11_compat_constexpr_body_invalid_stmt)
+DIAG_NAME_INDEX(warn_cxx11_compat_constexpr_body_multiple_return)
+DIAG_NAME_INDEX(warn_cxx11_compat_constexpr_body_no_return)
+DIAG_NAME_INDEX(warn_cxx11_compat_constexpr_local_var)
+DIAG_NAME_INDEX(warn_cxx11_compat_constexpr_type_definition)
+DIAG_NAME_INDEX(warn_cxx11_compat_decltype_auto_type_specifier)
+DIAG_NAME_INDEX(warn_cxx11_compat_digit_separator)
+DIAG_NAME_INDEX(warn_cxx11_compat_init_capture)
+DIAG_NAME_INDEX(warn_cxx11_compat_reserved_user_defined_literal)
+DIAG_NAME_INDEX(warn_cxx11_compat_user_defined_literal)
+DIAG_NAME_INDEX(warn_cxx11_compat_variable_template)
+DIAG_NAME_INDEX(warn_cxx11_gnu_attribute_on_type)
+DIAG_NAME_INDEX(warn_cxx11_keyword)
+DIAG_NAME_INDEX(warn_cxx11_right_shift_in_template_arg)
+DIAG_NAME_INDEX(warn_cxx1y_compat_constexpr_not_const)
+DIAG_NAME_INDEX(warn_cxx1y_compat_for_range_identifier)
+DIAG_NAME_INDEX(warn_cxx1y_compat_static_assert_no_message)
+DIAG_NAME_INDEX(warn_cxx1y_compat_template_template_param_typename)
+DIAG_NAME_INDEX(warn_cxx98_compat_alias_declaration)
+DIAG_NAME_INDEX(warn_cxx98_compat_alignas)
+DIAG_NAME_INDEX(warn_cxx98_compat_alignof)
+DIAG_NAME_INDEX(warn_cxx98_compat_array_size_conversion)
+DIAG_NAME_INDEX(warn_cxx98_compat_attribute)
+DIAG_NAME_INDEX(warn_cxx98_compat_auto_type_specifier)
+DIAG_NAME_INDEX(warn_cxx98_compat_cast_fn_obj)
+DIAG_NAME_INDEX(warn_cxx98_compat_constexpr)
+DIAG_NAME_INDEX(warn_cxx98_compat_ctor_list_init)
+DIAG_NAME_INDEX(warn_cxx98_compat_decltype)
+DIAG_NAME_INDEX(warn_cxx98_compat_defaulted_function)
+DIAG_NAME_INDEX(warn_cxx98_compat_delegating_ctor)
+DIAG_NAME_INDEX(warn_cxx98_compat_deleted_function)
+DIAG_NAME_INDEX(warn_cxx98_compat_empty_fnmacro_arg)
+DIAG_NAME_INDEX(warn_cxx98_compat_empty_scalar_initializer)
+DIAG_NAME_INDEX(warn_cxx98_compat_enum_fixed_underlying_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_enum_friend)
+DIAG_NAME_INDEX(warn_cxx98_compat_enum_nested_name_spec)
+DIAG_NAME_INDEX(warn_cxx98_compat_enumerator_list_comma)
+DIAG_NAME_INDEX(warn_cxx98_compat_explicit_conversion_functions)
+DIAG_NAME_INDEX(warn_cxx98_compat_explicit_instantiation_after_specialization)
+DIAG_NAME_INDEX(warn_cxx98_compat_extern_template)
+DIAG_NAME_INDEX(warn_cxx98_compat_for_range)
+DIAG_NAME_INDEX(warn_cxx98_compat_friend_is_member)
+DIAG_NAME_INDEX(warn_cxx98_compat_generalized_initializer_lists)
+DIAG_NAME_INDEX(warn_cxx98_compat_goto_into_protected_scope)
+DIAG_NAME_INDEX(warn_cxx98_compat_indirect_goto_in_protected_scope)
+DIAG_NAME_INDEX(warn_cxx98_compat_initializer_list_init)
+DIAG_NAME_INDEX(warn_cxx98_compat_inline_namespace)
+DIAG_NAME_INDEX(warn_cxx98_compat_lambda)
+DIAG_NAME_INDEX(warn_cxx98_compat_less_colon_colon)
+DIAG_NAME_INDEX(warn_cxx98_compat_literal_operator)
+DIAG_NAME_INDEX(warn_cxx98_compat_literal_ucn_control_character)
+DIAG_NAME_INDEX(warn_cxx98_compat_literal_ucn_escape_basic_scs)
+DIAG_NAME_INDEX(warn_cxx98_compat_longlong)
+DIAG_NAME_INDEX(warn_cxx98_compat_no_newline_eof)
+DIAG_NAME_INDEX(warn_cxx98_compat_noexcept_decl)
+DIAG_NAME_INDEX(warn_cxx98_compat_noexcept_expr)
+DIAG_NAME_INDEX(warn_cxx98_compat_non_static_member_use)
+DIAG_NAME_INDEX(warn_cxx98_compat_nonclass_type_friend)
+DIAG_NAME_INDEX(warn_cxx98_compat_nonstatic_member_init)
+DIAG_NAME_INDEX(warn_cxx98_compat_nontrivial_union_or_anon_struct_member)
+DIAG_NAME_INDEX(warn_cxx98_compat_nullptr)
+DIAG_NAME_INDEX(warn_cxx98_compat_override_control_keyword)
+DIAG_NAME_INDEX(warn_cxx98_compat_pass_non_pod_arg_to_vararg)
+DIAG_NAME_INDEX(warn_cxx98_compat_pp_line_too_big)
+DIAG_NAME_INDEX(warn_cxx98_compat_raw_string_literal)
+DIAG_NAME_INDEX(warn_cxx98_compat_ref_qualifier)
+DIAG_NAME_INDEX(warn_cxx98_compat_reference_list_init)
+DIAG_NAME_INDEX(warn_cxx98_compat_rvalue_reference)
+DIAG_NAME_INDEX(warn_cxx98_compat_scoped_enum)
+DIAG_NAME_INDEX(warn_cxx98_compat_sfinae_access_control)
+DIAG_NAME_INDEX(warn_cxx98_compat_static_assert)
+DIAG_NAME_INDEX(warn_cxx98_compat_static_data_member_in_union)
+DIAG_NAME_INDEX(warn_cxx98_compat_switch_into_protected_scope)
+DIAG_NAME_INDEX(warn_cxx98_compat_temp_copy)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_arg_extra_parens)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_arg_local_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_arg_null)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_arg_object_internal)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_arg_unnamed_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_outside_of_template)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_parameter_default_in_function_template)
+DIAG_NAME_INDEX(warn_cxx98_compat_template_spec_decl_out_of_scope)
+DIAG_NAME_INDEX(warn_cxx98_compat_top_level_semi)
+DIAG_NAME_INDEX(warn_cxx98_compat_trailing_return_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_two_right_angle_brackets)
+DIAG_NAME_INDEX(warn_cxx98_compat_typename_outside_of_template)
+DIAG_NAME_INDEX(warn_cxx98_compat_unelaborated_friend_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_unicode_id)
+DIAG_NAME_INDEX(warn_cxx98_compat_unicode_literal)
+DIAG_NAME_INDEX(warn_cxx98_compat_unicode_type)
+DIAG_NAME_INDEX(warn_cxx98_compat_using_decl_constructor)
+DIAG_NAME_INDEX(warn_cxx98_compat_variadic_macro)
+DIAG_NAME_INDEX(warn_cxx98_compat_variadic_templates)
+DIAG_NAME_INDEX(warn_cxx_ms_struct)
+DIAG_NAME_INDEX(warn_dangling_else)
+DIAG_NAME_INDEX(warn_dangling_std_initializer_list)
+DIAG_NAME_INDEX(warn_dealloc_in_category)
+DIAG_NAME_INDEX(warn_debug_compression_unavailable)
+DIAG_NAME_INDEX(warn_decl_in_param_list)
+DIAG_NAME_INDEX(warn_decl_shadow)
+DIAG_NAME_INDEX(warn_declspec_attribute_ignored)
+DIAG_NAME_INDEX(warn_def_missing_case1)
+DIAG_NAME_INDEX(warn_def_missing_case2)
+DIAG_NAME_INDEX(warn_def_missing_case3)
+DIAG_NAME_INDEX(warn_def_missing_cases)
+DIAG_NAME_INDEX(warn_default_atomic_custom_getter_setter)
+DIAG_NAME_INDEX(warn_delegating_ctor_cycle)
+DIAG_NAME_INDEX(warn_delete_abstract_non_virtual_dtor)
+DIAG_NAME_INDEX(warn_delete_array_type)
+DIAG_NAME_INDEX(warn_delete_incomplete)
+DIAG_NAME_INDEX(warn_delete_non_virtual_dtor)
+DIAG_NAME_INDEX(warn_deprecated)
+DIAG_NAME_INDEX(warn_deprecated_copy_operation)
+DIAG_NAME_INDEX(warn_deprecated_def)
+DIAG_NAME_INDEX(warn_deprecated_fwdclass_message)
+DIAG_NAME_INDEX(warn_deprecated_message)
+DIAG_NAME_INDEX(warn_deprecated_register)
+DIAG_NAME_INDEX(warn_deprecated_string_literal_conversion)
+DIAG_NAME_INDEX(warn_direct_ivar_access)
+DIAG_NAME_INDEX(warn_division_by_zero)
+DIAG_NAME_INDEX(warn_doc_api_container_decl_mismatch)
+DIAG_NAME_INDEX(warn_doc_block_command_duplicate)
+DIAG_NAME_INDEX(warn_doc_block_command_empty_paragraph)
+DIAG_NAME_INDEX(warn_doc_container_decl_mismatch)
+DIAG_NAME_INDEX(warn_doc_deprecated_not_sync)
+DIAG_NAME_INDEX(warn_doc_function_method_decl_mismatch)
+DIAG_NAME_INDEX(warn_doc_html_end_forbidden)
+DIAG_NAME_INDEX(warn_doc_html_end_unbalanced)
+DIAG_NAME_INDEX(warn_doc_html_missing_end_tag)
+DIAG_NAME_INDEX(warn_doc_html_start_end_mismatch)
+DIAG_NAME_INDEX(warn_doc_html_start_tag_expected_ident_or_greater)
+DIAG_NAME_INDEX(warn_doc_html_start_tag_expected_quoted_string)
+DIAG_NAME_INDEX(warn_doc_param_duplicate)
+DIAG_NAME_INDEX(warn_doc_param_invalid_direction)
+DIAG_NAME_INDEX(warn_doc_param_not_attached_to_a_function_decl)
+DIAG_NAME_INDEX(warn_doc_param_not_found)
+DIAG_NAME_INDEX(warn_doc_param_spaces_in_direction)
+DIAG_NAME_INDEX(warn_doc_returns_attached_to_a_void_function)
+DIAG_NAME_INDEX(warn_doc_returns_not_attached_to_a_function_decl)
+DIAG_NAME_INDEX(warn_doc_tparam_duplicate)
+DIAG_NAME_INDEX(warn_doc_tparam_not_attached_to_a_template_decl)
+DIAG_NAME_INDEX(warn_doc_tparam_not_found)
+DIAG_NAME_INDEX(warn_double_const_requires_fp64)
+DIAG_NAME_INDEX(warn_double_lock)
+DIAG_NAME_INDEX(warn_drv_assuming_mfloat_abi_is)
+DIAG_NAME_INDEX(warn_drv_clang_unsupported)
+DIAG_NAME_INDEX(warn_drv_empty_joined_argument)
+DIAG_NAME_INDEX(warn_drv_input_file_unused)
+DIAG_NAME_INDEX(warn_drv_input_file_unused_by_cpp)
+DIAG_NAME_INDEX(warn_drv_invoking_fallback)
+DIAG_NAME_INDEX(warn_drv_objc_gc_unsupported)
+DIAG_NAME_INDEX(warn_drv_optimization_value)
+DIAG_NAME_INDEX(warn_drv_overriding_flag_option)
+DIAG_NAME_INDEX(warn_drv_pch_not_first_include)
+DIAG_NAME_INDEX(warn_drv_preprocessed_input_file_unused)
+DIAG_NAME_INDEX(warn_drv_treating_input_as_cxx)
+DIAG_NAME_INDEX(warn_drv_unused_argument)
+DIAG_NAME_INDEX(warn_dup_category_def)
+DIAG_NAME_INDEX(warn_duplicate_attribute)
+DIAG_NAME_INDEX(warn_duplicate_attribute_exact)
+DIAG_NAME_INDEX(warn_duplicate_declspec)
+DIAG_NAME_INDEX(warn_duplicate_enum_values)
+DIAG_NAME_INDEX(warn_duplicate_method_decl)
+DIAG_NAME_INDEX(warn_duplicate_protocol_def)
+DIAG_NAME_INDEX(warn_dyn_class_memaccess)
+DIAG_NAME_INDEX(warn_empty_for_body)
+DIAG_NAME_INDEX(warn_empty_format_string)
+DIAG_NAME_INDEX(warn_empty_if_body)
+DIAG_NAME_INDEX(warn_empty_parens_are_function_decl)
+DIAG_NAME_INDEX(warn_empty_range_based_for_body)
+DIAG_NAME_INDEX(warn_empty_switch_body)
+DIAG_NAME_INDEX(warn_empty_while_body)
+DIAG_NAME_INDEX(warn_enum_value_overflow)
+DIAG_NAME_INDEX(warn_equality_with_extra_parens)
+DIAG_NAME_INDEX(warn_exception_caught_by_earlier_handler)
+DIAG_NAME_INDEX(warn_exception_spec_deprecated)
+DIAG_NAME_INDEX(warn_exit_time_destructor)
+DIAG_NAME_INDEX(warn_expected_qualified_after_typename)
+DIAG_NAME_INDEX(warn_expecting_lock_held_on_loop)
+DIAG_NAME_INDEX(warn_expecting_locked)
+DIAG_NAME_INDEX(warn_explicit_instantiation_inline_0x)
+DIAG_NAME_INDEX(warn_explicit_instantiation_must_be_global_0x)
+DIAG_NAME_INDEX(warn_explicit_instantiation_out_of_scope_0x)
+DIAG_NAME_INDEX(warn_explicit_instantiation_unqualified_wrong_namespace_0x)
+DIAG_NAME_INDEX(warn_extern_init)
+DIAG_NAME_INDEX(warn_extra_semi_after_mem_fn_def)
+DIAG_NAME_INDEX(warn_extraneous_char_constant)
+DIAG_NAME_INDEX(warn_falloff_nonvoid_function)
+DIAG_NAME_INDEX(warn_falloff_nonvoid_lambda)
+DIAG_NAME_INDEX(warn_falloff_noreturn_function)
+DIAG_NAME_INDEX(warn_fallthrough_attr_invalid_placement)
+DIAG_NAME_INDEX(warn_fallthrough_attr_unreachable)
+DIAG_NAME_INDEX(warn_fe_backend_frame_larger_than)
+DIAG_NAME_INDEX(warn_fe_backend_optimization_failure)
+DIAG_NAME_INDEX(warn_fe_backend_plugin)
+DIAG_NAME_INDEX(warn_fe_cc_log_diagnostics_failure)
+DIAG_NAME_INDEX(warn_fe_cc_print_header_failure)
+DIAG_NAME_INDEX(warn_fe_frame_larger_than)
+DIAG_NAME_INDEX(warn_fe_inline_asm)
+DIAG_NAME_INDEX(warn_fe_macro_contains_embedded_newline)
+DIAG_NAME_INDEX(warn_fe_serialized_diag_failure)
+DIAG_NAME_INDEX(warn_field_is_uninit)
+DIAG_NAME_INDEX(warn_file_asm_volatile)
+DIAG_NAME_INDEX(warn_fixit_no_changes)
+DIAG_NAME_INDEX(warn_float_overflow)
+DIAG_NAME_INDEX(warn_float_underflow)
+DIAG_NAME_INDEX(warn_floatingpoint_eq)
+DIAG_NAME_INDEX(warn_forgotten_module_header)
+DIAG_NAME_INDEX(warn_format_argument_needs_cast)
+DIAG_NAME_INDEX(warn_format_conversion_argument_type_mismatch)
+DIAG_NAME_INDEX(warn_format_invalid_conversion)
+DIAG_NAME_INDEX(warn_format_invalid_positional_specifier)
+DIAG_NAME_INDEX(warn_format_mix_positional_nonpositional_args)
+DIAG_NAME_INDEX(warn_format_non_standard)
+DIAG_NAME_INDEX(warn_format_non_standard_conversion_spec)
+DIAG_NAME_INDEX(warn_format_non_standard_positional_arg)
+DIAG_NAME_INDEX(warn_format_nonliteral)
+DIAG_NAME_INDEX(warn_format_nonliteral_noargs)
+DIAG_NAME_INDEX(warn_format_nonsensical_length)
+DIAG_NAME_INDEX(warn_format_string_is_wide_literal)
+DIAG_NAME_INDEX(warn_format_zero_positional_specifier)
+DIAG_NAME_INDEX(warn_forward_class_redefinition)
+DIAG_NAME_INDEX(warn_fun_excludes_mutex)
+DIAG_NAME_INDEX(warn_fun_requires_lock)
+DIAG_NAME_INDEX(warn_fun_requires_lock_precise)
+DIAG_NAME_INDEX(warn_function_def_in_objc_container)
+DIAG_NAME_INDEX(warn_gc_attribute_weak_on_local)
+DIAG_NAME_INDEX(warn_global_constructor)
+DIAG_NAME_INDEX(warn_global_destructor)
+DIAG_NAME_INDEX(warn_gnu_inline_attribute_requires_inline)
+DIAG_NAME_INDEX(warn_has_warning_invalid_option)
+DIAG_NAME_INDEX(warn_header_guard)
+DIAG_NAME_INDEX(warn_iboutlet_object_type)
+DIAG_NAME_INDEX(warn_iboutletcollection_property_assign)
+DIAG_NAME_INDEX(warn_identity_field_assign)
+DIAG_NAME_INDEX(warn_ignored_gcc_optimization)
+DIAG_NAME_INDEX(warn_ignored_ms_inheritance)
+DIAG_NAME_INDEX(warn_ignoring_ftabstop_value)
+DIAG_NAME_INDEX(warn_illegal_constant_array_size)
+DIAG_NAME_INDEX(warn_impcast_bitfield_precision_constant)
+DIAG_NAME_INDEX(warn_impcast_bool_to_null_pointer)
+DIAG_NAME_INDEX(warn_impcast_complex_scalar)
+DIAG_NAME_INDEX(warn_impcast_different_enum_types)
+DIAG_NAME_INDEX(warn_impcast_float_integer)
+DIAG_NAME_INDEX(warn_impcast_float_precision)
+DIAG_NAME_INDEX(warn_impcast_floating_point_to_bool)
+DIAG_NAME_INDEX(warn_impcast_integer_64_32)
+DIAG_NAME_INDEX(warn_impcast_integer_precision)
+DIAG_NAME_INDEX(warn_impcast_integer_precision_constant)
+DIAG_NAME_INDEX(warn_impcast_integer_sign)
+DIAG_NAME_INDEX(warn_impcast_integer_sign_conditional)
+DIAG_NAME_INDEX(warn_impcast_literal_float_to_integer)
+DIAG_NAME_INDEX(warn_impcast_null_pointer_to_integer)
+DIAG_NAME_INDEX(warn_impcast_objective_c_literal_to_bool)
+DIAG_NAME_INDEX(warn_impcast_pointer_to_bool)
+DIAG_NAME_INDEX(warn_impcast_string_literal_to_bool)
+DIAG_NAME_INDEX(warn_impcast_vector_scalar)
+DIAG_NAME_INDEX(warn_implements_nscopying)
+DIAG_NAME_INDEX(warn_implicit_atomic_property)
+DIAG_NAME_INDEX(warn_implicit_decl_requires_sysheader)
+DIAG_NAME_INDEX(warn_implicit_function_decl)
+DIAG_NAME_INDEX(warn_implicitly_retains_self)
+DIAG_NAME_INDEX(warn_incompatible_analyzer_plugin_api)
+DIAG_NAME_INDEX(warn_incompatible_qualified_id)
+DIAG_NAME_INDEX(warn_incompatible_vectors)
+DIAG_NAME_INDEX(warn_increment_bool)
+DIAG_NAME_INDEX(warn_indirection_through_null)
+DIAG_NAME_INDEX(warn_infinite_recursive_function)
+DIAG_NAME_INDEX(warn_init_list_constant_narrowing)
+DIAG_NAME_INDEX(warn_init_list_type_narrowing)
+DIAG_NAME_INDEX(warn_init_list_variable_narrowing)
+DIAG_NAME_INDEX(warn_init_ptr_member_to_parameter_addr)
+DIAG_NAME_INDEX(warn_initializer_out_of_order)
+DIAG_NAME_INDEX(warn_initializer_overrides)
+DIAG_NAME_INDEX(warn_inline_namespace_reopened_noninline)
+DIAG_NAME_INDEX(warn_inst_method_not_found)
+DIAG_NAME_INDEX(warn_instance_method_not_found_with_typo)
+DIAG_NAME_INDEX(warn_instance_method_on_class_found)
+DIAG_NAME_INDEX(warn_int_to_pointer_cast)
+DIAG_NAME_INDEX(warn_int_to_void_pointer_cast)
+DIAG_NAME_INDEX(warn_integer_constant_overflow)
+DIAG_NAME_INDEX(warn_invalid_asm_cast_lvalue)
+DIAG_NAME_INDEX(warn_invalid_capability_name)
+DIAG_NAME_INDEX(warn_invalid_initializer_from_system_header)
+DIAG_NAME_INDEX(warn_ivar_use_hidden)
+DIAG_NAME_INDEX(warn_ivars_in_interface)
+DIAG_NAME_INDEX(warn_lock_exclusive_and_shared)
+DIAG_NAME_INDEX(warn_lock_some_predecessors)
+DIAG_NAME_INDEX(warn_logical_and_in_logical_or)
+DIAG_NAME_INDEX(warn_logical_instead_of_bitwise)
+DIAG_NAME_INDEX(warn_logical_not_on_lhs_of_comparison)
+DIAG_NAME_INDEX(warn_loop_ctrl_binds_to_inner)
+DIAG_NAME_INDEX(warn_loop_state_mismatch)
+DIAG_NAME_INDEX(warn_lunsigned_always_true_comparison)
+DIAG_NAME_INDEX(warn_main_one_arg)
+DIAG_NAME_INDEX(warn_maybe_falloff_nonvoid_function)
+DIAG_NAME_INDEX(warn_maybe_falloff_nonvoid_lambda)
+DIAG_NAME_INDEX(warn_maybe_uninit_var)
+DIAG_NAME_INDEX(warn_maynot_respond)
+DIAG_NAME_INDEX(warn_member_extra_qualification)
+DIAG_NAME_INDEX(warn_memsize_comparison)
+DIAG_NAME_INDEX(warn_method_param_declaration)
+DIAG_NAME_INDEX(warn_method_param_redefinition)
+DIAG_NAME_INDEX(warn_microsoft_dependent_exists)
+DIAG_NAME_INDEX(warn_mismatched_availability)
+DIAG_NAME_INDEX(warn_mismatched_availability_override)
+DIAG_NAME_INDEX(warn_mismatched_availability_override_unavail)
+DIAG_NAME_INDEX(warn_mismatched_section)
+DIAG_NAME_INDEX(warn_missing_braces)
+DIAG_NAME_INDEX(warn_missing_case1)
+DIAG_NAME_INDEX(warn_missing_case2)
+DIAG_NAME_INDEX(warn_missing_case3)
+DIAG_NAME_INDEX(warn_missing_case_for_condition)
+DIAG_NAME_INDEX(warn_missing_cases)
+DIAG_NAME_INDEX(warn_missing_dependent_template_keyword)
+DIAG_NAME_INDEX(warn_missing_exception_specification)
+DIAG_NAME_INDEX(warn_missing_explicit_synthesis)
+DIAG_NAME_INDEX(warn_missing_field_initializers)
+DIAG_NAME_INDEX(warn_missing_format_string)
+DIAG_NAME_INDEX(warn_missing_method_return_type)
+DIAG_NAME_INDEX(warn_missing_prototype)
+DIAG_NAME_INDEX(warn_missing_selector_name)
+DIAG_NAME_INDEX(warn_missing_sentinel)
+DIAG_NAME_INDEX(warn_missing_submodule)
+DIAG_NAME_INDEX(warn_missing_sysroot)
+DIAG_NAME_INDEX(warn_missing_variable_declarations)
+DIAG_NAME_INDEX(warn_missing_whitespace_after_macro_name)
+DIAG_NAME_INDEX(warn_mixed_sign_comparison)
+DIAG_NAME_INDEX(warn_mmap_unknown_attribute)
+DIAG_NAME_INDEX(warn_module_config_macro_undef)
+DIAG_NAME_INDEX(warn_module_conflict)
+DIAG_NAME_INDEX(warn_mt_message)
+DIAG_NAME_INDEX(warn_multiple_method_decl)
+DIAG_NAME_INDEX(warn_namespace_member_extra_qualification)
+DIAG_NAME_INDEX(warn_neon_vector_initializer_non_portable)
+DIAG_NAME_INDEX(warn_nested_block_comment)
+DIAG_NAME_INDEX(warn_no_autosynthesis_property)
+DIAG_NAME_INDEX(warn_no_autosynthesis_shared_ivar_property)
+DIAG_NAME_INDEX(warn_no_constructor_for_refconst)
+DIAG_NAME_INDEX(warn_no_newline_eof)
+DIAG_NAME_INDEX(warn_no_unlock)
+DIAG_NAME_INDEX(warn_non_contravariant_overriding_param_types)
+DIAG_NAME_INDEX(warn_non_contravariant_param_types)
+DIAG_NAME_INDEX(warn_non_covariant_overriding_ret_types)
+DIAG_NAME_INDEX(warn_non_covariant_ret_types)
+DIAG_NAME_INDEX(warn_non_literal_null_pointer)
+DIAG_NAME_INDEX(warn_non_modular_include_in_framework_module)
+DIAG_NAME_INDEX(warn_non_modular_include_in_module)
+DIAG_NAME_INDEX(warn_non_pod_vararg_with_format_string)
+DIAG_NAME_INDEX(warn_non_virtual_dtor)
+DIAG_NAME_INDEX(warn_noreturn_function_has_return_expr)
+DIAG_NAME_INDEX(warn_not_a_doxygen_trailing_member_comment)
+DIAG_NAME_INDEX(warn_not_compound_assign)
+DIAG_NAME_INDEX(warn_not_enough_argument)
+DIAG_NAME_INDEX(warn_not_in_enum)
+DIAG_NAME_INDEX(warn_not_in_enum_assignment)
+DIAG_NAME_INDEX(warn_ns_attribute_wrong_parameter_type)
+DIAG_NAME_INDEX(warn_ns_attribute_wrong_return_type)
+DIAG_NAME_INDEX(warn_nsobject_attribute)
+DIAG_NAME_INDEX(warn_null_arg)
+DIAG_NAME_INDEX(warn_null_in_arithmetic_operation)
+DIAG_NAME_INDEX(warn_null_in_comparison_operation)
+DIAG_NAME_INDEX(warn_null_pointer_compare)
+DIAG_NAME_INDEX(warn_null_ret)
+DIAG_NAME_INDEX(warn_objc_designated_init_missing_super_call)
+DIAG_NAME_INDEX(warn_objc_designated_init_non_designated_init_call)
+DIAG_NAME_INDEX(warn_objc_designated_init_non_super_designated_init_call)
+DIAG_NAME_INDEX(warn_objc_implementation_missing_designated_init_override)
+DIAG_NAME_INDEX(warn_objc_invalid_bridge)
+DIAG_NAME_INDEX(warn_objc_invalid_bridge_to_cf)
+DIAG_NAME_INDEX(warn_objc_isa_assign)
+DIAG_NAME_INDEX(warn_objc_isa_use)
+DIAG_NAME_INDEX(warn_objc_literal_comparison)
+DIAG_NAME_INDEX(warn_objc_missing_super_call)
+DIAG_NAME_INDEX(warn_objc_pointer_cxx_catch_fragile)
+DIAG_NAME_INDEX(warn_objc_pointer_masking)
+DIAG_NAME_INDEX(warn_objc_pointer_masking_performSelector)
+DIAG_NAME_INDEX(warn_objc_precise_lifetime_meaningless)
+DIAG_NAME_INDEX(warn_objc_property_copy_missing_on_block)
+DIAG_NAME_INDEX(warn_objc_property_default_assign_on_object)
+DIAG_NAME_INDEX(warn_objc_property_no_assignment_attribute)
+DIAG_NAME_INDEX(warn_objc_property_retain_of_block)
+DIAG_NAME_INDEX(warn_objc_protocol_qualifier_missing_id)
+DIAG_NAME_INDEX(warn_objc_readonly_property_has_setter)
+DIAG_NAME_INDEX(warn_objc_redundant_literal_use)
+DIAG_NAME_INDEX(warn_objc_requires_super_protocol)
+DIAG_NAME_INDEX(warn_objc_root_class_missing)
+DIAG_NAME_INDEX(warn_objc_secondary_init_missing_init_call)
+DIAG_NAME_INDEX(warn_objc_secondary_init_super_init_call)
+DIAG_NAME_INDEX(warn_objc_string_literal_comparison)
+DIAG_NAME_INDEX(warn_odr_tag_type_inconsistent)
+DIAG_NAME_INDEX(warn_old_style_cast)
+DIAG_NAME_INDEX(warn_omp_extra_tokens_at_eol)
+DIAG_NAME_INDEX(warn_omp_linear_step_zero)
+DIAG_NAME_INDEX(warn_on_superclass_use)
+DIAG_NAME_INDEX(warn_operator_new_returns_null)
+DIAG_NAME_INDEX(warn_out_of_range_compare)
+DIAG_NAME_INDEX(warn_overaligned_type)
+DIAG_NAME_INDEX(warn_overloaded_shift_in_comparison)
+DIAG_NAME_INDEX(warn_overloaded_virtual)
+DIAG_NAME_INDEX(warn_padded_struct_anon_field)
+DIAG_NAME_INDEX(warn_padded_struct_field)
+DIAG_NAME_INDEX(warn_padded_struct_size)
+DIAG_NAME_INDEX(warn_param_return_typestate_mismatch)
+DIAG_NAME_INDEX(warn_param_typestate_mismatch)
+DIAG_NAME_INDEX(warn_parameter_size)
+DIAG_NAME_INDEX(warn_parens_disambiguated_as_function_declaration)
+DIAG_NAME_INDEX(warn_partial_specs_not_deducible)
+DIAG_NAME_INDEX(warn_pass_class_arg_to_vararg)
+DIAG_NAME_INDEX(warn_pointer_indirection_from_incompatible_type)
+DIAG_NAME_INDEX(warn_pp_ambiguous_macro)
+DIAG_NAME_INDEX(warn_pp_convert_lhs_to_positive)
+DIAG_NAME_INDEX(warn_pp_convert_rhs_to_positive)
+DIAG_NAME_INDEX(warn_pp_date_time)
+DIAG_NAME_INDEX(warn_pp_expr_overflow)
+DIAG_NAME_INDEX(warn_pp_line_decimal)
+DIAG_NAME_INDEX(warn_pp_undef_identifier)
+DIAG_NAME_INDEX(warn_pragma_align_expected_equal)
+DIAG_NAME_INDEX(warn_pragma_align_invalid_option)
+DIAG_NAME_INDEX(warn_pragma_debug_unexpected_command)
+DIAG_NAME_INDEX(warn_pragma_diagnostic_cannot_pop)
+DIAG_NAME_INDEX(warn_pragma_diagnostic_invalid)
+DIAG_NAME_INDEX(warn_pragma_diagnostic_invalid_option)
+DIAG_NAME_INDEX(warn_pragma_diagnostic_invalid_token)
+DIAG_NAME_INDEX(warn_pragma_diagnostic_unknown_warning)
+DIAG_NAME_INDEX(warn_pragma_expected_action_or_r_paren)
+DIAG_NAME_INDEX(warn_pragma_expected_colon)
+DIAG_NAME_INDEX(warn_pragma_expected_enable_disable)
+DIAG_NAME_INDEX(warn_pragma_expected_identifier)
+DIAG_NAME_INDEX(warn_pragma_expected_init_seg)
+DIAG_NAME_INDEX(warn_pragma_expected_integer)
+DIAG_NAME_INDEX(warn_pragma_expected_lparen)
+DIAG_NAME_INDEX(warn_pragma_expected_non_wide_string)
+DIAG_NAME_INDEX(warn_pragma_expected_punc)
+DIAG_NAME_INDEX(warn_pragma_expected_rparen)
+DIAG_NAME_INDEX(warn_pragma_expected_section_label_or_name)
+DIAG_NAME_INDEX(warn_pragma_expected_section_name)
+DIAG_NAME_INDEX(warn_pragma_expected_section_push_pop_or_name)
+DIAG_NAME_INDEX(warn_pragma_extra_tokens_at_eol)
+DIAG_NAME_INDEX(warn_pragma_ignored)
+DIAG_NAME_INDEX(warn_pragma_include_alias_expected)
+DIAG_NAME_INDEX(warn_pragma_include_alias_expected_filename)
+DIAG_NAME_INDEX(warn_pragma_include_alias_mismatch_angle)
+DIAG_NAME_INDEX(warn_pragma_include_alias_mismatch_quote)
+DIAG_NAME_INDEX(warn_pragma_init_seg_unsupported_target)
+DIAG_NAME_INDEX(warn_pragma_invalid_action)
+DIAG_NAME_INDEX(warn_pragma_invalid_specific_action)
+DIAG_NAME_INDEX(warn_pragma_message)
+DIAG_NAME_INDEX(warn_pragma_ms_struct)
+DIAG_NAME_INDEX(warn_pragma_omp_ignored)
+DIAG_NAME_INDEX(warn_pragma_options_align_reset_failed)
+DIAG_NAME_INDEX(warn_pragma_options_expected_align)
+DIAG_NAME_INDEX(warn_pragma_pack_invalid_alignment)
+DIAG_NAME_INDEX(warn_pragma_pack_malformed)
+DIAG_NAME_INDEX(warn_pragma_pack_pop_identifer_and_alignment)
+DIAG_NAME_INDEX(warn_pragma_pack_show)
+DIAG_NAME_INDEX(warn_pragma_pop_failed)
+DIAG_NAME_INDEX(warn_pragma_pop_macro_no_push)
+DIAG_NAME_INDEX(warn_pragma_unknown_extension)
+DIAG_NAME_INDEX(warn_pragma_unroll_cuda_value_in_parens)
+DIAG_NAME_INDEX(warn_pragma_unsupported_action)
+DIAG_NAME_INDEX(warn_pragma_unused_expected_var)
+DIAG_NAME_INDEX(warn_pragma_unused_expected_var_arg)
+DIAG_NAME_INDEX(warn_pragma_unused_undeclared_var)
+DIAG_NAME_INDEX(warn_pragma_warning_expected)
+DIAG_NAME_INDEX(warn_pragma_warning_expected_number)
+DIAG_NAME_INDEX(warn_pragma_warning_push_level)
+DIAG_NAME_INDEX(warn_pragma_warning_spec_invalid)
+DIAG_NAME_INDEX(warn_precedence_bitwise_rel)
+DIAG_NAME_INDEX(warn_precedence_conditional)
+DIAG_NAME_INDEX(warn_printf_asterisk_missing_arg)
+DIAG_NAME_INDEX(warn_printf_asterisk_wrong_type)
+DIAG_NAME_INDEX(warn_printf_data_arg_not_used)
+DIAG_NAME_INDEX(warn_printf_format_string_contains_null_char)
+DIAG_NAME_INDEX(warn_printf_format_string_not_null_terminated)
+DIAG_NAME_INDEX(warn_printf_ignored_flag)
+DIAG_NAME_INDEX(warn_printf_incomplete_specifier)
+DIAG_NAME_INDEX(warn_printf_insufficient_data_args)
+DIAG_NAME_INDEX(warn_printf_nonsensical_flag)
+DIAG_NAME_INDEX(warn_printf_nonsensical_optional_amount)
+DIAG_NAME_INDEX(warn_printf_positional_arg_exceeds_data_args)
+DIAG_NAME_INDEX(warn_private_extern)
+DIAG_NAME_INDEX(warn_profile_data_out_of_date)
+DIAG_NAME_INDEX(warn_profile_data_unprofiled)
+DIAG_NAME_INDEX(warn_property_attr_mismatch)
+DIAG_NAME_INDEX(warn_property_attribute)
+DIAG_NAME_INDEX(warn_property_getter_owning_mismatch)
+DIAG_NAME_INDEX(warn_property_implicitly_mismatched)
+DIAG_NAME_INDEX(warn_property_method_deprecated)
+DIAG_NAME_INDEX(warn_property_types_are_incompatible)
+DIAG_NAME_INDEX(warn_protocol_property_mismatch)
+DIAG_NAME_INDEX(warn_ptr_arith_exceeds_bounds)
+DIAG_NAME_INDEX(warn_ptr_arith_precedes_bounds)
+DIAG_NAME_INDEX(warn_qual_return_type)
+DIAG_NAME_INDEX(warn_readonly_property)
+DIAG_NAME_INDEX(warn_receiver_forward_class)
+DIAG_NAME_INDEX(warn_receiver_forward_instance)
+DIAG_NAME_INDEX(warn_receiver_is_weak)
+DIAG_NAME_INDEX(warn_redecl_library_builtin)
+DIAG_NAME_INDEX(warn_redeclaration_without_attribute_prev_attribute_ignored)
+DIAG_NAME_INDEX(warn_redefinition_in_param_list)
+DIAG_NAME_INDEX(warn_redundant_loop_iteration)
+DIAG_NAME_INDEX(warn_reference_field_is_uninit)
+DIAG_NAME_INDEX(warn_register_objc_catch_parm)
+DIAG_NAME_INDEX(warn_reinterpret_different_from_static)
+DIAG_NAME_INDEX(warn_related_result_type_compatibility_class)
+DIAG_NAME_INDEX(warn_related_result_type_compatibility_protocol)
+DIAG_NAME_INDEX(warn_remainder_by_zero)
+DIAG_NAME_INDEX(warn_ret_addr_label)
+DIAG_NAME_INDEX(warn_ret_local_temp_addr)
+DIAG_NAME_INDEX(warn_ret_local_temp_ref)
+DIAG_NAME_INDEX(warn_ret_stack_addr)
+DIAG_NAME_INDEX(warn_ret_stack_ref)
+DIAG_NAME_INDEX(warn_return_missing_expr)
+DIAG_NAME_INDEX(warn_return_typestate_for_unconsumable_type)
+DIAG_NAME_INDEX(warn_return_typestate_mismatch)
+DIAG_NAME_INDEX(warn_return_value_size)
+DIAG_NAME_INDEX(warn_return_value_udt)
+DIAG_NAME_INDEX(warn_return_value_udt_incomplete)
+DIAG_NAME_INDEX(warn_root_inst_method_not_found)
+DIAG_NAME_INDEX(warn_runsigned_always_true_comparison)
+DIAG_NAME_INDEX(warn_scanf_nonzero_width)
+DIAG_NAME_INDEX(warn_scanf_scanlist_incomplete)
+DIAG_NAME_INDEX(warn_second_parameter_of_va_start_not_last_named_argument)
+DIAG_NAME_INDEX(warn_second_parameter_to_va_arg_never_compatible)
+DIAG_NAME_INDEX(warn_second_parameter_to_va_arg_not_pod)
+DIAG_NAME_INDEX(warn_second_parameter_to_va_arg_ownership_qualified)
+DIAG_NAME_INDEX(warn_self_assignment)
+DIAG_NAME_INDEX(warn_semicolon_before_method_body)
+DIAG_NAME_INDEX(warn_setter_getter_impl_required)
+DIAG_NAME_INDEX(warn_setter_getter_impl_required_in_category)
+DIAG_NAME_INDEX(warn_shift_gt_typewidth)
+DIAG_NAME_INDEX(warn_shift_negative)
+DIAG_NAME_INDEX(warn_shift_result_gt_typewidth)
+DIAG_NAME_INDEX(warn_shift_result_sets_sign_bit)
+DIAG_NAME_INDEX(warn_sizeof_array_decay)
+DIAG_NAME_INDEX(warn_sizeof_array_param)
+DIAG_NAME_INDEX(warn_sizeof_pointer_expr_memaccess)
+DIAG_NAME_INDEX(warn_sizeof_pointer_expr_memaccess_note)
+DIAG_NAME_INDEX(warn_sizeof_pointer_type_memaccess)
+DIAG_NAME_INDEX(warn_sometimes_uninit_var)
+DIAG_NAME_INDEX(warn_standalone_specifier)
+DIAG_NAME_INDEX(warn_static_array_too_small)
+DIAG_NAME_INDEX(warn_static_inline_explicit_inst_ignored)
+DIAG_NAME_INDEX(warn_static_local_in_extern_inline)
+DIAG_NAME_INDEX(warn_static_main)
+DIAG_NAME_INDEX(warn_static_self_reference_in_init)
+DIAG_NAME_INDEX(warn_stdc_fenv_access_not_supported)
+DIAG_NAME_INDEX(warn_strict_multiple_method_decl)
+DIAG_NAME_INDEX(warn_string_plus_char)
+DIAG_NAME_INDEX(warn_string_plus_int)
+DIAG_NAME_INDEX(warn_stringcompare)
+DIAG_NAME_INDEX(warn_strlcpycat_wrong_size)
+DIAG_NAME_INDEX(warn_strncat_large_size)
+DIAG_NAME_INDEX(warn_strncat_src_size)
+DIAG_NAME_INDEX(warn_strncat_wrong_size)
+DIAG_NAME_INDEX(warn_struct_class_previous_tag_mismatch)
+DIAG_NAME_INDEX(warn_struct_class_tag_mismatch)
+DIAG_NAME_INDEX(warn_sub_ptr_zero_size_types)
+DIAG_NAME_INDEX(warn_subobject_initializer_overrides)
+DIAG_NAME_INDEX(warn_subscript_is_char)
+DIAG_NAME_INDEX(warn_suggest_noreturn_block)
+DIAG_NAME_INDEX(warn_suggest_noreturn_function)
+DIAG_NAME_INDEX(warn_tautological_overlap_comparison)
+DIAG_NAME_INDEX(warn_template_arg_negative)
+DIAG_NAME_INDEX(warn_template_arg_too_large)
+DIAG_NAME_INDEX(warn_template_export_unsupported)
+DIAG_NAME_INDEX(warn_template_qualified_friend_ignored)
+DIAG_NAME_INDEX(warn_template_qualified_friend_unsupported)
+DIAG_NAME_INDEX(warn_template_spec_extra_headers)
+DIAG_NAME_INDEX(warn_temporary_array_to_pointer_decay)
+DIAG_NAME_INDEX(warn_tentative_incomplete_array)
+DIAG_NAME_INDEX(warn_this_bool_conversion)
+DIAG_NAME_INDEX(warn_this_null_compare)
+DIAG_NAME_INDEX(warn_thread_attribute_argument_not_lockable)
+DIAG_NAME_INDEX(warn_thread_attribute_decl_not_lockable)
+DIAG_NAME_INDEX(warn_thread_attribute_decl_not_pointer)
+DIAG_NAME_INDEX(warn_thread_attribute_ignored)
+DIAG_NAME_INDEX(warn_thread_safety_beta)
+DIAG_NAME_INDEX(warn_transparent_union_attribute_field_size_align)
+DIAG_NAME_INDEX(warn_transparent_union_attribute_floating)
+DIAG_NAME_INDEX(warn_transparent_union_attribute_not_definition)
+DIAG_NAME_INDEX(warn_transparent_union_attribute_zero_fields)
+DIAG_NAME_INDEX(warn_type_attribute_wrong_type)
+DIAG_NAME_INDEX(warn_type_safety_null_pointer_required)
+DIAG_NAME_INDEX(warn_type_safety_type_mismatch)
+DIAG_NAME_INDEX(warn_type_tag_for_datatype_wrong_kind)
+DIAG_NAME_INDEX(warn_typecheck_function_qualifiers)
+DIAG_NAME_INDEX(warn_typecheck_negative_array_new_size)
+DIAG_NAME_INDEX(warn_typecheck_reference_qualifiers)
+DIAG_NAME_INDEX(warn_typecheck_zero_static_array_size)
+DIAG_NAME_INDEX(warn_ucn_escape_incomplete)
+DIAG_NAME_INDEX(warn_ucn_escape_no_digits)
+DIAG_NAME_INDEX(warn_ucn_escape_surrogate)
+DIAG_NAME_INDEX(warn_ucn_not_valid_in_c89)
+DIAG_NAME_INDEX(warn_ucn_not_valid_in_c89_literal)
+DIAG_NAME_INDEX(warn_unannotated_fallthrough)
+DIAG_NAME_INDEX(warn_unannotated_fallthrough_per_function)
+DIAG_NAME_INDEX(warn_unavailable_fwdclass_message)
+DIAG_NAME_INDEX(warn_uncovered_module_header)
+DIAG_NAME_INDEX(warn_undeclared_selector)
+DIAG_NAME_INDEX(warn_undeclared_selector_with_typo)
+DIAG_NAME_INDEX(warn_undef_interface)
+DIAG_NAME_INDEX(warn_undef_interface_suggest)
+DIAG_NAME_INDEX(warn_undef_method_impl)
+DIAG_NAME_INDEX(warn_undef_protocolref)
+DIAG_NAME_INDEX(warn_undefined_inline)
+DIAG_NAME_INDEX(warn_undefined_internal)
+DIAG_NAME_INDEX(warn_undefined_reinterpret_cast)
+DIAG_NAME_INDEX(warn_unhandled_ms_attribute_ignored)
+DIAG_NAME_INDEX(warn_unimplemented_protocol_method)
+DIAG_NAME_INDEX(warn_unimplemented_selector)
+DIAG_NAME_INDEX(warn_uninit_byref_blockvar_captured_by_block)
+DIAG_NAME_INDEX(warn_uninit_self_reference_in_init)
+DIAG_NAME_INDEX(warn_uninit_self_reference_in_reference_init)
+DIAG_NAME_INDEX(warn_uninit_var)
+DIAG_NAME_INDEX(warn_unknown_attribute_ignored)
+DIAG_NAME_INDEX(warn_unknown_comment_command_name)
+DIAG_NAME_INDEX(warn_unknown_diag_option)
+DIAG_NAME_INDEX(warn_unknown_warning_specifier)
+DIAG_NAME_INDEX(warn_unlock_but_no_lock)
+DIAG_NAME_INDEX(warn_unlock_kind_mismatch)
+DIAG_NAME_INDEX(warn_unnecessary_packed)
+DIAG_NAME_INDEX(warn_unneeded_internal_decl)
+DIAG_NAME_INDEX(warn_unneeded_member_function)
+DIAG_NAME_INDEX(warn_unneeded_static_internal_decl)
+DIAG_NAME_INDEX(warn_unreachable)
+DIAG_NAME_INDEX(warn_unreachable_break)
+DIAG_NAME_INDEX(warn_unreachable_default)
+DIAG_NAME_INDEX(warn_unreachable_loop_increment)
+DIAG_NAME_INDEX(warn_unreachable_return)
+DIAG_NAME_INDEX(warn_unsequenced_mod_mod)
+DIAG_NAME_INDEX(warn_unsequenced_mod_use)
+DIAG_NAME_INDEX(warn_unsigned_abs)
+DIAG_NAME_INDEX(warn_unused_call)
+DIAG_NAME_INDEX(warn_unused_comparison)
+DIAG_NAME_INDEX(warn_unused_const_variable)
+DIAG_NAME_INDEX(warn_unused_container_subscript_expr)
+DIAG_NAME_INDEX(warn_unused_exception_param)
+DIAG_NAME_INDEX(warn_unused_expr)
+DIAG_NAME_INDEX(warn_unused_function)
+DIAG_NAME_INDEX(warn_unused_label)
+DIAG_NAME_INDEX(warn_unused_member_function)
+DIAG_NAME_INDEX(warn_unused_parameter)
+DIAG_NAME_INDEX(warn_unused_private_field)
+DIAG_NAME_INDEX(warn_unused_property_backing_ivar)
+DIAG_NAME_INDEX(warn_unused_property_expr)
+DIAG_NAME_INDEX(warn_unused_result)
+DIAG_NAME_INDEX(warn_unused_variable)
+DIAG_NAME_INDEX(warn_unused_voidptr)
+DIAG_NAME_INDEX(warn_unused_volatile)
+DIAG_NAME_INDEX(warn_use_in_invalid_state)
+DIAG_NAME_INDEX(warn_use_of_temp_in_invalid_state)
+DIAG_NAME_INDEX(warn_use_out_of_scope_declaration)
+DIAG_NAME_INDEX(warn_used_but_marked_unused)
+DIAG_NAME_INDEX(warn_user_literal_reserved)
+DIAG_NAME_INDEX(warn_using_decl_constructor_ellipsis)
+DIAG_NAME_INDEX(warn_using_directive_in_header)
+DIAG_NAME_INDEX(warn_va_start_of_reference_type_is_undefined)
+DIAG_NAME_INDEX(warn_var_deref_requires_any_lock)
+DIAG_NAME_INDEX(warn_var_deref_requires_lock)
+DIAG_NAME_INDEX(warn_var_deref_requires_lock_precise)
+DIAG_NAME_INDEX(warn_variable_requires_any_lock)
+DIAG_NAME_INDEX(warn_variable_requires_lock)
+DIAG_NAME_INDEX(warn_variable_requires_lock_precise)
+DIAG_NAME_INDEX(warn_variables_not_in_loop_body)
+DIAG_NAME_INDEX(warn_vbase_moved_multiple_times)
+DIAG_NAME_INDEX(warn_vector_long_decl_spec_combination)
+DIAG_NAME_INDEX(warn_verbatim_block_end_without_start)
+DIAG_NAME_INDEX(warn_vla_used)
+DIAG_NAME_INDEX(warn_weak_identifier_undeclared)
+DIAG_NAME_INDEX(warn_weak_import)
+DIAG_NAME_INDEX(warn_weak_template_vtable)
+DIAG_NAME_INDEX(warn_weak_vtable)
+DIAG_NAME_INDEX(warn_wrong_absolute_value_type)
+DIAG_NAME_INDEX(warn_zero_size_struct_union_compat)
+DIAG_NAME_INDEX(warn_zero_size_struct_union_in_extern_c)
+DIAG_NAME_INDEX(warning_multiple_selectors)
diff --git a/include/clang/Basic/DiagnosticLexKinds.inc b/include/clang/Basic/DiagnosticLexKinds.inc
new file mode 100644
index 0000000..a911c00
--- /dev/null
+++ b/include/clang/Basic/DiagnosticLexKinds.inc
@@ -0,0 +1,282 @@
+#ifdef LEXSTART
+__LEXSTART = DIAG_START_LEX,
+#undef LEXSTART
+#endif
+
+DIAG(backslash_newline_space, CLASS_WARNING, (unsigned)diag::Severity::Warning, "backslash and newline separated by space", 42, SFINAE_Suppress, false, false, 1)
+DIAG(err__Pragma_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "_Pragma takes a parenthesized string literal", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_bad_character_encoding, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal character encoding in character literal", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_bad_string_encoding, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal character encoding in string literal", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_character_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "character too large for enclosing character literal type", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_conflict_marker, CLASS_ERROR, (unsigned)diag::Severity::Error, "version control conflict marker in file", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_defined_macro_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "'defined' cannot be used as a macro name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_digit_separator_not_between_digits, CLASS_ERROR, (unsigned)diag::Severity::Error, "digit separator cannot appear at %select{start|end}0 of digit sequence", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_embedded_include, CLASS_ERROR, (unsigned)diag::Severity::Error, "embedding a #%0 directive within macro arguments is not supported", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_expected_id_building_module, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a module name in '__building_module' expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_exponent_has_no_digits, CLASS_ERROR, (unsigned)diag::Severity::Error, "exponent has no digits", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_feature_check_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "builtin feature check macro requires a parenthesized identifier", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_hex_escape_no_digits, CLASS_ERROR, (unsigned)diag::Severity::Error, "\\%0 used with no following hex digits", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_hex_escape_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "hex escape sequence out of range", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_hexconstant_requires_digits, CLASS_ERROR, (unsigned)diag::Severity::Error, "hexadecimal floating constants require a significand", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_hexconstant_requires_exponent, CLASS_ERROR, (unsigned)diag::Severity::Error, "hexadecimal floating constants require an exponent", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_binary_digit, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid digit '%0' in binary constant", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_char_raw_delim, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid character '%0' character in raw string delimiter; use PREFIX( )PREFIX to delimit raw string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_character_to_charify, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument to convert to character", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_decimal_digit, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid digit '%0' in decimal constant", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_octal_digit, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid digit '%0' in octal constant", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_pth_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid or corrupt PTH file '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_suffix_float_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid suffix '%0' on floating constant", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_suffix_integer_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid suffix '%0' on integer constant", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_invalid_utf8, CLASS_ERROR, (unsigned)diag::Severity::Error, "source file is not valid UTF-8", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_lexing_string, CLASS_ERROR, (unsigned)diag::Severity::Error, "failure when lexing a string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_config_macro_submodule, CLASS_ERROR, (unsigned)diag::Severity::Error, "configuration macros are only allowed on top-level modules", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected an attribute name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_config_macro, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected configuration macro name after ','", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_conflicts_comma, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ',' after conflicting module name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_conflicts_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a message describing the conflict with '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_export_wildcard, CLASS_ERROR, (unsigned)diag::Severity::Error, "only '*' can be exported from an inferred submodule", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_feature, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a feature name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_header, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a header name after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_inferred_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %select{module exclusion with 'exclude'|'export *'}0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_lbrace, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '{' to start module '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_lbrace_wildcard, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '{' to start inferred submodule", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_library_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %select{library|framework}0 name as a string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected umbrella, header, submodule, or module export", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_mmap_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a module map file name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_module, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected module declaration", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_module_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected module name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_rbrace, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '}'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_expected_rsquare, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ']' to close attribute", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_explicit_inferred_framework, CLASS_ERROR, (unsigned)diag::Severity::Error, "inferred framework modules cannot be 'explicit'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_explicit_top_level, CLASS_ERROR, (unsigned)diag::Severity::Error, "'explicit' is not permitted on top-level modules", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_inferred_framework_submodule, CLASS_ERROR, (unsigned)diag::Severity::Error, "inferred submodule cannot be a framework submodule", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_inferred_no_umbrella, CLASS_ERROR, (unsigned)diag::Severity::Error, "inferred submodules require a module with an umbrella", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_inferred_redef, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of inferred submodule", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_missing_exclude_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected excluded module name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_missing_module_qualified, CLASS_ERROR, (unsigned)diag::Severity::Error, "no module named '%0' in '%1'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_missing_module_unqualified, CLASS_ERROR, (unsigned)diag::Severity::Error, "no module named '%0' visible from '%1'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_module_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a module name or '*'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_module_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of module '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_nested_submodule_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "qualified module name can only be used to define modules at the top level", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_top_level_inferred_submodule, CLASS_ERROR, (unsigned)diag::Severity::Error, "only submodules and framework modules may be inferred with wildcard syntax", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_umbrella_clash, CLASS_ERROR, (unsigned)diag::Severity::Error, "umbrella for module '%0' already covers this directory", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_umbrella_dir_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "umbrella directory '%0' not found", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_mmap_unknown_token, CLASS_ERROR, (unsigned)diag::Severity::Error, "skipping stray token", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_multichar_utf_character_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "Unicode character literals may not contain multiple characters", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_non_ascii, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-ASCII characters are not allowed outside of literals and identifiers", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_octal_escape_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "octal escape sequence out of range", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pascal_string_too_long, CLASS_ERROR, (unsigned)diag::Severity::Error, "Pascal string is too long", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_paste_at_end, CLASS_ERROR, (unsigned)diag::Severity::Error, "'##' cannot appear at end of macro expansion", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_paste_at_start, CLASS_ERROR, (unsigned)diag::Severity::Error, "'##' cannot appear at start of macro expansion", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_arc_cf_code_audited_syntax, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected 'begin' or 'end'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_bad_paste, CLASS_ERROR, (unsigned)diag::Severity::Error, "pasting formed '%0', an invalid preprocessing token", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_colon_without_question, CLASS_ERROR, (unsigned)diag::Severity::Error, "':' without preceding '?'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_directive_required, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must be used within a preprocessing directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_division_by_zero, CLASS_ERROR, (unsigned)diag::Severity::Error, "division by zero in preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_double_begin_of_arc_cf_code_audited, CLASS_ERROR, (unsigned)diag::Severity::Error, "already inside '#pragma clang arc_cf_code_audited'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_duplicate_name_in_arg_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate macro parameter name %0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_empty_filename, CLASS_ERROR, (unsigned)diag::Severity::Error, "empty filename", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_endif_without_if, CLASS_ERROR, (unsigned)diag::Severity::Error, "#endif without #if", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_eof_in_arc_cf_code_audited, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#pragma clang arc_cf_code_audited' was not ended within this file", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_error_opening_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "error opening file '%0': %1", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_after, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing %1 after %0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_comma_in_arg_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected comma in macro parameter list", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_eol, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected end of line in preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_ident_in_arg_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected identifier in macro parameter list", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_rparen, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ')' in preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expected_value_in_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected value in expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expects_filename, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected \"FILENAME\" or <FILENAME>", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expr_bad_token_binop, CLASS_ERROR, (unsigned)diag::Severity::Error, "token is not a valid binary operator in a preprocessor subexpression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_expr_bad_token_start_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid token at start of a preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_file_not_found, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "'%0' file not found", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_file_not_found_not_fatal, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' file not found with <angled> include; use \"quotes\" instead", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_hash_error, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 16)
+DIAG(err_pp_identifier_arg_not_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot convert %0 token to an identifier", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_illegal_floating_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "floating point literal in preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_import_directive_ms, CLASS_ERROR, (unsigned)diag::Severity::Error, "#import of type library is an unsupported Microsoft feature", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_include_in_arc_cf_code_audited, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot #include files inside '#pragma clang arc_cf_code_audited'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_include_too_deep, CLASS_ERROR, (unsigned)diag::Severity::Error, "#include nested too deeply", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_invalid_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid preprocessing directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_invalid_poison, CLASS_ERROR, (unsigned)diag::Severity::Error, "can only poison identifier tokens", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_invalid_tok_in_arg_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid token in macro parameter list", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_invalid_udl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{character|integer}0 literal with user-defined suffix cannot be used in preprocessor constant expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_line_digit_sequence, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{#line|GNU line marker}0 directive requires a simple digit sequence", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_line_invalid_filename, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid filename for #line directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_line_requires_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "#line directive requires a positive integer argument", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_linemarker_invalid_filename, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid filename for line marker directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_linemarker_invalid_flag, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid flag line marker directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_linemarker_invalid_pop, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid line marker flag '2': cannot pop empty include stack", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_linemarker_requires_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "line marker directive requires a positive integer argument", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_macro_not_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "macro name must be an identifier", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_malformed_ident, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid #ident directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_missing_macro_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "macro name missing", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_missing_rparen_in_macro_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing ')' in macro parameter list", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_opencl_variadic_macros, CLASS_ERROR, (unsigned)diag::Severity::Error, "variadic macros not supported in OpenCL", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_operator_used_as_macro_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "C++ operator %0 (aka %1) used as a macro name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_remainder_by_zero, CLASS_ERROR, (unsigned)diag::Severity::Error, "remainder by zero in preprocessor expression", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_stringize_not_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#' is not followed by a macro parameter", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_unmatched_end_of_arc_cf_code_audited, CLASS_ERROR, (unsigned)diag::Severity::Error, "not currently inside '#pragma clang arc_cf_code_audited'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_unterminated_conditional, CLASS_ERROR, (unsigned)diag::Severity::Error, "unterminated conditional directive", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_used_poisoned_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "attempt to use a poisoned identifier", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pp_visibility_non_macro, CLASS_ERROR, (unsigned)diag::Severity::Error, "no macro named %0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pragma_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pragma_message_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "pragma %select{message|warning|error}0 requires parenthesized string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_pragma_push_pop_macro_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "pragma %0 requires a parenthesized string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_raw_delim_too_long, CLASS_ERROR, (unsigned)diag::Severity::Error, "raw string delimiter longer than 16 characters; use PREFIX( )PREFIX to delimit raw string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_string_concat_mixed_suffix, CLASS_ERROR, (unsigned)diag::Severity::Error, "differing user-defined suffixes ('%0' and '%1') in string literal concatenation", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_too_few_args_in_macro_invoc, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few arguments provided to function-like macro invocation", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_too_many_args_in_macro_invoc, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many arguments provided to function-like macro invocation", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_ucn_control_character, CLASS_ERROR, (unsigned)diag::Severity::Error, "universal character name refers to a control character", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_ucn_escape_basic_scs, CLASS_ERROR, (unsigned)diag::Severity::Error, "character '%0' cannot be specified by a universal character name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_ucn_escape_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete universal character name", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_ucn_escape_invalid, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid universal character", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_unsupported_string_concat, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported non-standard concatenation of string literals", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_unterm_macro_invoc, CLASS_ERROR, (unsigned)diag::Severity::Error, "unterminated function-like macro invocation", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_unterminated___pragma, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing terminating ')' character", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_unterminated_block_comment, CLASS_ERROR, (unsigned)diag::Severity::Error, "unterminated /* comment", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_unterminated_raw_string, CLASS_ERROR, (unsigned)diag::Severity::Error, "raw string missing terminating delimiter )%0\"", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(err_warning_check_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "builtin warning check macro requires a parenthesized string", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(error_undeclared_use_of_module, CLASS_ERROR, (unsigned)diag::Severity::Error, "module %0 does not depend on a module exporting '%1'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(error_use_of_private_header_outside_module, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of private header from outside its module: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(escaped_newline_block_comment_end, CLASS_WARNING, (unsigned)diag::Severity::Warning, "escaped newline between */ characters at block comment end", 87, SFINAE_Suppress, false, false, 1)
+DIAG(ext_binary_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "binary integer literals are a GNU extension", 182, SFINAE_Suppress, false, false, 1)
+DIAG(ext_binary_literal_cxx1y, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "binary integer literals are a C++1y extension", 67, SFINAE_Suppress, false, false, 1)
+DIAG(ext_c99_whitespace_required_after_macro_name, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "ISO C99 requires whitespace after the macro name", 80, SFINAE_Suppress, false, false, 1)
+DIAG(ext_charize_microsoft, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "charizing operator #@ is a Microsoft extension", 267, SFINAE_Suppress, false, false, 1)
+DIAG(ext_dollar_in_identifier, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "'$' in identifier", 137, SFINAE_Suppress, false, false, 1)
+DIAG(ext_embedded_directive, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "embedding a directive within macro arguments has undefined behavior", 144, SFINAE_Suppress, false, false, 1)
+DIAG(ext_empty_character, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "empty character constant", 247, SFINAE_Suppress, false, false, 1)
+DIAG(ext_empty_fnmacro_arg, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "empty macro arguments are a C99 feature", 80, SFINAE_Suppress, false, false, 1)
+DIAG(ext_four_char_character_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "multi-character character constant", 173, SFINAE_Suppress, false, false, 1)
+DIAG(ext_hexconstant_invalid, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "hexadecimal floating constants are a C99 feature", 80, SFINAE_Suppress, false, false, 1)
+DIAG(ext_imaginary_constant, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "imaginary constants are a GNU extension", 193, SFINAE_Suppress, false, false, 1)
+DIAG(ext_line_comment, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "// comments are not allowed in this language", 87, SFINAE_Suppress, false, false, 1)
+DIAG(ext_missing_varargs_arg, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "must specify at least one argument for '...' parameter of variadic macro", 202, SFINAE_Suppress, false, false, 1)
+DIAG(ext_missing_whitespace_after_macro_name, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "whitespace required after macro name", 0, SFINAE_Suppress, false, false, 1)
+DIAG(ext_ms_reserved_user_defined_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "invalid suffix on literal; C++11 requires a space between literal and identifier", 376, SFINAE_Suppress, false, false, 1)
+DIAG(ext_multi_line_line_comment, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "multi-line // comment", 87, SFINAE_Suppress, false, false, 1)
+DIAG(ext_multichar_character_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "multi-character character constant", 287, SFINAE_Suppress, false, false, 1)
+DIAG(ext_named_variadic_macro, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "named variadic macros are a GNU extension", 499, SFINAE_Suppress, false, false, 1)
+DIAG(ext_no_newline_eof, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "no newline at end of file", 293, SFINAE_Suppress, false, false, 1)
+DIAG(ext_nonstandard_escape, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of non-standard escape character '\\%0'", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_on_off_switch_syntax, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "expected 'ON' or 'OFF' or 'DEFAULT' in pragma", 465, SFINAE_Suppress, false, false, 1)
+DIAG(ext_paste_comma, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "token pasting of ',' and __VA_ARGS__ is a GNU extension", 202, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_bad_paste_ms, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "pasting formed '%0', an invalid preprocessing token", 249, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_bad_vaargs_use, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_comma_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "comma operator in operand of #if", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_extra_tokens_at_eol, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "extra tokens at end of #%0 directive", 159, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_ident_directive, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "#ident is a language extension", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_import_directive, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "#import is a language extension", 220, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_include_next_directive, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "#include_next is a language extension", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_include_search_ms, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "#include resolved using non-portable MSVC search rules as: %0", 286, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_line_too_big, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "C requires #line number to be less than %0, allowed as extension", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_line_zero, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "#line directive with zero argument is a GNU extension", 201, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_macro_redef, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%0 macro redefined", 261, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_operator_used_as_macro_name, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "C++ operator %0 (aka %1) used as a macro name", 267, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_redef_builtin_macro, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "redefining builtin macro", 51, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_undef_builtin_macro, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "undefining builtin macro", 51, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pp_warning_directive, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "#warning is a language extension", 353, SFINAE_Suppress, false, false, 1)
+DIAG(ext_pragma_syntax_eod, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "expected end of directive in pragma", 465, SFINAE_Suppress, false, false, 1)
+DIAG(ext_reserved_user_defined_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "invalid suffix on literal; C++11 requires a space between literal and identifier", 376, SFINAE_Suppress, false, false, 1)
+DIAG(ext_stdc_pragma_ignored, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unknown pragma in STDC namespace", 465, SFINAE_Suppress, false, false, 1)
+DIAG(ext_string_too_long, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "string literal of length %0 exceeds maximum length %1 that %select{C90|ISO C99|C++}2 compilers are required to support", 340, SFINAE_Suppress, false, false, 1)
+DIAG(ext_token_used, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "extension used", 252, SFINAE_Suppress, false, false, 1)
+DIAG(ext_unicode_whitespace, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "treating Unicode character as whitespace", 461, SFINAE_Suppress, false, false, 1)
+DIAG(ext_unknown_escape, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unknown escape sequence '\\%0'", 464, SFINAE_Suppress, false, false, 1)
+DIAG(ext_unterminated_char, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "missing terminating ' character", 247, SFINAE_Suppress, false, false, 1)
+DIAG(ext_unterminated_string, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "missing terminating '\"' character", 247, SFINAE_Suppress, false, false, 1)
+DIAG(ext_variadic_macro, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "variadic macros are a C99 feature", 499, SFINAE_Suppress, false, false, 1)
+DIAG(note_header_guard, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is defined here; did you mean %1?", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_init_list_at_beginning_of_macro_argument, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "cannot use initializer list at the beginning of a macro argument", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_macro_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "macro %0 defined here", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_mmap_lbrace_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "to match this '{'", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_mmap_lsquare_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "to match this ']'", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_mmap_prev_definition, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previously defined here", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_pp_ambiguous_macro_chosen, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "expanding this definition of %0", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_pp_ambiguous_macro_other, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "other definition of %0", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_suggest_parens_for_macro, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "parentheses are required around macro argument containing braced initializer list", 0, SFINAE_Suppress, false, false, 1)
+DIAG(note_ucn_four_not_eight, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to use '\\u'?", 0, SFINAE_Suppress, false, false, 1)
+DIAG(null_in_char, CLASS_WARNING, (unsigned)diag::Severity::Warning, "null character(s) preserved in character literal", 304, SFINAE_Suppress, false, false, 1)
+DIAG(null_in_file, CLASS_WARNING, (unsigned)diag::Severity::Warning, "null character ignored", 304, SFINAE_Suppress, false, false, 1)
+DIAG(null_in_string, CLASS_WARNING, (unsigned)diag::Severity::Warning, "null character(s) preserved in string literal", 304, SFINAE_Suppress, false, false, 1)
+DIAG(pp_disabled_macro_expansion, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "disabled expansion of recursive macro", 124, SFINAE_Suppress, false, false, 1)
+DIAG(pp_err_elif_after_else, CLASS_ERROR, (unsigned)diag::Severity::Error, "#elif after #else", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(pp_err_elif_without_if, CLASS_ERROR, (unsigned)diag::Severity::Error, "#elif without #if", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(pp_err_else_after_else, CLASS_ERROR, (unsigned)diag::Severity::Error, "#else after #else", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(pp_err_else_without_if, CLASS_ERROR, (unsigned)diag::Severity::Error, "#else without #if", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(pp_hash_warning, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 2, SFINAE_Suppress, false, true, 16)
+DIAG(pp_include_macros_out_of_predefines, CLASS_ERROR, (unsigned)diag::Severity::Error, "the #__include_macros directive is only for internal use by -imacros", 0, SFINAE_SubstitutionFailure, false, true, 1)
+DIAG(pp_include_next_absolute_path, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#include_next with absolute path", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_include_next_in_primary, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#include_next in primary source file", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_invalid_string_literal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid string literal, ignoring final '\\'", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_macro_not_used, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "macro is not used", 487, SFINAE_Suppress, false, false, 1)
+DIAG(pp_out_of_date_dependency, CLASS_WARNING, (unsigned)diag::Severity::Warning, "current file is older than dependency %0", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_poisoning_existing_macro, CLASS_WARNING, (unsigned)diag::Severity::Warning, "poisoning existing macro", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_pragma_once_in_main_file, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#pragma once in main file", 0, SFINAE_Suppress, false, false, 1)
+DIAG(pp_pragma_sysheader_in_main_file, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#pragma system_header ignored in main file", 0, SFINAE_Suppress, false, false, 1)
+DIAG(trigraph_converted, CLASS_WARNING, (unsigned)diag::Severity::Warning, "trigraph converted to '%0' character", 448, SFINAE_Suppress, false, false, 1)
+DIAG(trigraph_ends_block_comment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "trigraph ends block comment", 448, SFINAE_Suppress, false, false, 1)
+DIAG(trigraph_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "trigraph ignored", 448, SFINAE_Suppress, false, false, 1)
+DIAG(trigraph_ignored_block_comment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignored trigraph would end block comment", 448, SFINAE_Suppress, false, false, 1)
+DIAG(warn_auto_module_import, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "treating #%select{include|import|include_next|__include_macros}0 as an import of module '%1'", 37, SFINAE_Suppress, false, false, 1)
+DIAG(warn_bad_character_encoding, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "illegal character encoding in character literal", 248, SFINAE_Suppress, false, false, 1)
+DIAG(warn_bad_string_encoding, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "illegal character encoding in string literal", 248, SFINAE_Suppress, false, false, 1)
+DIAG(warn_c99_compat_unicode_id, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{using this character in an identifier|starting an identifier with this character}0 is incompatible with C99", 79, SFINAE_Suppress, false, false, 1)
+DIAG(warn_c99_compat_unicode_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unicode literals are incompatible with C99", 79, SFINAE_Suppress, false, false, 1)
+DIAG(warn_char_constant_too_large, CLASS_WARNING, (unsigned)diag::Severity::Warning, "character constant too long for its type", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx11_compat_binary_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "binary integer literals are incompatible with C++ standards before C++1y", 72, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx11_compat_digit_separator, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "digit separators are incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx11_compat_reserved_user_defined_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "identifier after literal will be treated as a reserved user-defined literal suffix in C++11", 60, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx11_compat_user_defined_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "identifier after literal will be treated as a user-defined literal suffix in C++11", 57, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx11_keyword, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%0' is a keyword in C++11", 57, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_empty_fnmacro_arg, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "empty macro arguments are incompatible with C++98", 76, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_less_colon_colon, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_literal_ucn_control_character, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "universal character name referring to a control character is incompatible with C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_literal_ucn_escape_basic_scs, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "specifying character '%0' with a universal character name is incompatible with C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_no_newline_eof, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "C++98 requires newline at end of file", 76, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_pp_line_too_big, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "#line number greater than 32767 is incompatible with C++98", 76, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_raw_string_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "raw string literals are incompatible with C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_unicode_id, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "using this character in an identifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_unicode_literal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unicode literals are incompatible with C++98", 73, SFINAE_Suppress, false, false, 1)
+DIAG(warn_cxx98_compat_variadic_macro, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variadic macros are incompatible with C++98", 76, SFINAE_Suppress, false, false, 1)
+DIAG(warn_extraneous_char_constant, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extraneous characters in character constant ignored", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_forgotten_module_header, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "header '%0' is included in module '%1' but not listed in module map", 226, SFINAE_Suppress, false, false, 1)
+DIAG(warn_has_warning_invalid_option, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "__has_warning expected option name (e.g. \"-Wundef\")", 264, SFINAE_Suppress, false, false, 1)
+DIAG(warn_header_guard, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 is used as a header guard here, followed by #define of a different macro", 203, SFINAE_Suppress, false, false, 1)
+DIAG(warn_missing_whitespace_after_macro_name, CLASS_WARNING, (unsigned)diag::Severity::Warning, "whitespace recommended after macro name", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_mmap_unknown_attribute, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown attribute '%0'", 206, SFINAE_Suppress, false, false, 1)
+DIAG(warn_nested_block_comment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'/*' within block comment", 87, SFINAE_Suppress, false, false, 1)
+DIAG(warn_no_newline_eof, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "no newline at end of file", 293, SFINAE_Suppress, false, false, 1)
+DIAG(warn_non_modular_include_in_framework_module, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "include of non-modular header inside framework module '%0'", 296, SFINAE_Suppress, false, false, 1)
+DIAG(warn_non_modular_include_in_module, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "include of non-modular header inside module '%0'", 297, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_ambiguous_macro, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ambiguous expansion of macro %0", 14, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_convert_lhs_to_positive, CLASS_WARNING, (unsigned)diag::Severity::Warning, "left side of operator converted from negative value to unsigned: %0", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_convert_rhs_to_positive, CLASS_WARNING, (unsigned)diag::Severity::Warning, "right side of operator converted from negative value to unsigned: %0", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_date_time, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "expansion of date or time macro is not reproducible", 107, SFINAE_Suppress, false, true, 1)
+DIAG(warn_pp_expr_overflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "integer overflow in preprocessor expression", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_line_decimal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{#line|GNU line marker}0 directive interprets number as decimal, not octal", 0, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pp_undef_identifier, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 is not defined, evaluates to 0", 455, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_debug_unexpected_command, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unexpected debug command '%0'", 207, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_diagnostic_cannot_pop, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pragma diagnostic pop could not pop, no matching push", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_diagnostic_invalid, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_diagnostic_invalid_option, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pragma diagnostic expected option name (e.g. \"-Wundef\")", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_diagnostic_invalid_token, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unexpected token in pragma diagnostic", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_diagnostic_unknown_warning, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unknown warning group '%0', ignored", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_ignored, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unknown pragma ignored", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_include_alias_expected, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pragma include_alias expected '%0'", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_include_alias_expected_filename, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pragma include_alias expected include filename", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_include_alias_mismatch_angle, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "angle-bracketed include <%0> cannot be aliased to double-quoted include \"%1\"", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_include_alias_mismatch_quote, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "double-quoted include \"%0\" cannot be aliased to angle-bracketed include <%1>", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_message, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0", 1, SFINAE_Suppress, true, false, 24)
+DIAG(warn_pragma_pop_macro_no_push, CLASS_WARNING, (unsigned)diag::Severity::Warning, "pragma pop_macro could not pop '%0', no matching push_macro", 207, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_warning_expected, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "#pragma warning expected '%0'", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_warning_expected_number, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "#pragma warning expected a warning number", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_warning_push_level, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "#pragma warning(push, level) requires a level between 0 and 4", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_pragma_warning_spec_invalid, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "#pragma warning expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_stdc_fenv_access_not_supported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "pragma STDC FENV_ACCESS ON is not supported, ignoring pragma", 465, SFINAE_Suppress, false, false, 1)
+DIAG(warn_ucn_escape_incomplete, CLASS_WARNING, (unsigned)diag::Severity::Warning, "incomplete universal character name; treating as '\\' followed by identifier", 460, SFINAE_Suppress, false, false, 1)
+DIAG(warn_ucn_escape_no_digits, CLASS_WARNING, (unsigned)diag::Severity::Warning, "\\%0 used with no following hex digits; treating as '\\' followed by identifier", 460, SFINAE_Suppress, false, false, 1)
+DIAG(warn_ucn_escape_surrogate, CLASS_WARNING, (unsigned)diag::Severity::Warning, "universal character name refers to a surrogate character", 460, SFINAE_Suppress, false, false, 1)
+DIAG(warn_ucn_not_valid_in_c89, CLASS_WARNING, (unsigned)diag::Severity::Warning, "universal character names are only valid in C99 or C++; treating as '\\' followed by identifier", 460, SFINAE_Suppress, false, false, 1)
+DIAG(warn_ucn_not_valid_in_c89_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "universal character names are only valid in C99 or C++", 460, SFINAE_Suppress, false, false, 1)
+DIAG(warn_uncovered_module_header, CLASS_WARNING, (unsigned)diag::Severity::Warning, "umbrella header for module '%0' does not include header '%1'", 227, SFINAE_Suppress, false, false, 1)
diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def
new file mode 100644
index 0000000..a360a5a
--- /dev/null
+++ b/include/clang/Basic/DiagnosticOptions.def
@@ -0,0 +1,95 @@
+//===--- DiagOptions.def - Diagnostic option database ------------- 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 diagnostic options. Users of this file
+// must define the DIAGOPT macro to make use of this information.
+// Optionally, the user may also define ENUM_DIAGOPT (for options
+// that have enumeration type and VALUE_DIAGOPT (for options that
+// describe a value rather than a flag). The SEMANTIC_* variants of these macros
+// indicate options that affect the processing of the program, rather than
+// simply the output.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DIAGOPT
+#  error Define the DIAGOPT macro to handle language options
+#endif
+
+#ifndef VALUE_DIAGOPT
+#  define VALUE_DIAGOPT(Name, Bits, Default) \
+DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef ENUM_DIAGOPT
+#  define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_DIAGOPT
+#  define SEMANTIC_DIAGOPT(Name, Bits, Default) DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_VALUE_DIAGOPT
+#  define SEMANTIC_VALUE_DIAGOPT(Name, Bits, Default) \
+     VALUE_DIAGOPT(Name, Bits, Default)
+#endif
+
+#ifndef SEMANTIC_ENUM_DIAGOPT
+#  define SEMANTIC_ENUM_DIAGOPT(Name, Type, Bits, Default) \
+     ENUM_DIAGOPT(Name, Type, Bits, Default)
+#endif
+
+SEMANTIC_DIAGOPT(IgnoreWarnings, 1, 0)   /// -w
+DIAGOPT(NoRewriteMacros, 1, 0)  /// -Wno-rewrite-macros
+DIAGOPT(Pedantic, 1, 0)         /// -pedantic
+DIAGOPT(PedanticErrors, 1, 0)   /// -pedantic-errors
+DIAGOPT(ShowColumn, 1, 1)       /// Show column number on diagnostics.
+DIAGOPT(ShowLocation, 1, 1)     /// Show source location information.
+DIAGOPT(ShowCarets, 1, 1)       /// Show carets in diagnostics.
+DIAGOPT(ShowFixits, 1, 1)       /// Show fixit information.
+DIAGOPT(ShowSourceRanges, 1, 0) /// Show source ranges in numeric form.
+DIAGOPT(ShowParseableFixits, 1, 0) /// Show machine parseable fix-its.
+DIAGOPT(ShowPresumedLoc, 1, 0)  /// Show presumed location for diagnostics.
+DIAGOPT(ShowOptionNames, 1, 0)  /// Show the option name for mappable
+                                /// diagnostics.
+DIAGOPT(ShowNoteIncludeStack, 1, 0) /// Show include stacks for notes.
+VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number,
+                                    /// 2 -> Full Name.
+                                 
+ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics: 
+  
+DIAGOPT(ShowColors, 1, 0)       /// Show diagnostics with ANSI color sequences.
+ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1,
+             Ovl_All)    /// Overload candidates to show.
+DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected
+                                 /// diagnostics, indicated by markers in the
+                                 /// input source file.
+
+DIAGOPT(ElideType, 1, 0)         /// Elide identical types in template diffing
+DIAGOPT(ShowTemplateTree, 1, 0)  /// Print a template tree when diffing
+DIAGOPT(CLFallbackMode, 1, 0)    /// Format for clang-cl fallback mode
+
+VALUE_DIAGOPT(ErrorLimit, 32, 0)           /// Limit # errors emitted.
+/// Limit depth of macro expansion backtrace.
+VALUE_DIAGOPT(MacroBacktraceLimit, 32, DefaultMacroBacktraceLimit)
+/// Limit depth of instantiation backtrace.
+VALUE_DIAGOPT(TemplateBacktraceLimit, 32, DefaultTemplateBacktraceLimit)
+/// Limit depth of constexpr backtrace.
+VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit)
+
+VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops.
+/// Column limit for formatting message diagnostics, or 0 if unused.
+VALUE_DIAGOPT(MessageLength, 32, 0)
+
+#undef DIAGOPT
+#undef ENUM_DIAGOPT
+#undef VALUE_DIAGOPT
+#undef SEMANTIC_DIAGOPT
+#undef SEMANTIC_ENUM_DIAGOPT
+#undef SEMANTIC_VALUE_DIAGOPT
+
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
new file mode 100644
index 0000000..3e4d0ee
--- /dev/null
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -0,0 +1,84 @@
+//===--- DiagnosticOptions.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICOPTIONS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Specifies which overload candidates to display when overload
+/// resolution fails.
+enum OverloadsShown : unsigned {
+  Ovl_All,  ///< Show all overloads.
+  Ovl_Best  ///< Show just the "best" overload candidates.
+};
+
+/// \brief Options for controlling the compiler diagnostics engine.
+class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
+public:
+  enum TextDiagnosticFormat { Clang, Msvc, Vi };
+
+  // Default values.
+  enum { DefaultTabStop = 8, MaxTabStop = 100,
+    DefaultMacroBacktraceLimit = 6,
+    DefaultTemplateBacktraceLimit = 10,
+    DefaultConstexprBacktraceLimit = 10 };
+
+  // Define simple diagnostic options (with no accessors).
+#define DIAGOPT(Name, Bits, Default) unsigned Name : Bits;
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)
+#include "clang/Basic/DiagnosticOptions.def"
+
+protected:
+  // Define diagnostic options of enumeration type. These are private, and will
+  // have accessors (below).
+#define DIAGOPT(Name, Bits, Default)
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) unsigned Name : Bits;
+#include "clang/Basic/DiagnosticOptions.def"
+
+public:
+  /// \brief The file to log diagnostic output to.
+  std::string DiagnosticLogFile;
+  
+  /// \brief The file to serialize diagnostics to (non-appending).
+  std::string DiagnosticSerializationFile;
+
+  /// The list of -W... options used to alter the diagnostic mappings, with the
+  /// prefixes removed.
+  std::vector<std::string> Warnings;
+
+  /// The list of -R... options used to alter the diagnostic mappings, with the
+  /// prefixes removed.
+  std::vector<std::string> Remarks;
+
+public:
+  // Define accessors/mutators for diagnostic options of enumeration type.
+#define DIAGOPT(Name, Bits, Default)
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+  Type get##Name() const { return static_cast<Type>(Name); } \
+  void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
+#include "clang/Basic/DiagnosticOptions.def"
+
+  DiagnosticOptions() {
+#define DIAGOPT(Name, Bits, Default) Name = Default;
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) set##Name(Default);
+#include "clang/Basic/DiagnosticOptions.def"
+  }
+};
+
+typedef DiagnosticOptions::TextDiagnosticFormat TextDiagnosticFormat;
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticParseKinds.inc b/include/clang/Basic/DiagnosticParseKinds.inc
new file mode 100644
index 0000000..e1e965d
--- /dev/null
+++ b/include/clang/Basic/DiagnosticParseKinds.inc
@@ -0,0 +1,378 @@
+#ifdef PARSESTART
+__PARSESTART = DIAG_START_PARSE,
+#undef PARSESTART
+#endif
+
+DIAG(err_access_specifier_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "interface types cannot specify '%select{private|protected}0' access", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_address_of_label_outside_fn, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of address-of-label extension outside of a function body", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_alias_declaration_not_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "name defined in alias declaration must be an identifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_alias_declaration_specialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_anon_type_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of anonymous %0 must be a definition", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_arc_bridge_retain, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown cast annotation __bridge_retain; did you mean __bridge_retained?", 0, SFINAE_SubstitutionFailure, false, true, 8)
+DIAG(err_argument_required_after_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument required after attribute", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_asm_empty, CLASS_ERROR, (unsigned)diag::Severity::Error, "__asm used with no assembly instructions", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_operand_wide_string_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use %select{unicode|wide}0 string literal in 'asm'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_at_defs_cxx, CLASS_ERROR, (unsigned)diag::Severity::Error, "@defs is not supported in Objective-C++", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_at_in_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected '@' in member specification", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_atimport, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of '@import' when modules are disabled", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_attribute_requires_arguments, CLASS_ERROR, (unsigned)diag::Severity::Error, "parentheses must be omitted if %0 attribute's argument list is empty", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_attributes_not_allowed, CLASS_ERROR, (unsigned)diag::Severity::Error, "an attribute list cannot appear here", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_availability_expected_change, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected 'introduced', 'deprecated', or 'obsoleted'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_availability_expected_platform, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a platform name, e.g., 'macosx'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_availability_redundant, CLASS_ERROR, (unsigned)diag::Severity::Error, "redundant %0 availability change; only the last specified change will be used", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_availability_unknown_change, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not an availability stage; use 'introduced', 'deprecated', or 'obsoleted'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_bitfield_member_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "bitfield member cannot have an in-class initializer", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_bool_redeclaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "redeclaration of C++ built-in type 'bool'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_bracket_depth_exceeded, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "bracket nesting level exceeded maximum of %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_brackets_go_after_unqualified_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "brackets go after the %select{identifier|unqualified-id}0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_class_on_template_template_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "template template parameter requires 'class' after the parameter list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_constructor_bad_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing return type for function %0; did you mean the constructor name %1?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ctor_init_missing_comma, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing ',' between base or member initializers", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_cxx11_attribute_forbids_arguments, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %0 cannot have an argument list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_cxx11_attribute_forbids_ellipsis, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute '%0' cannot be used as an attribute pack", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_cxx11_attribute_repeated, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %0 cannot appear multiple times in an attribute specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_declaration_does_not_declare_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration does not declare a parameter", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_default_arg_unparsed, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected end of default argument expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_default_delete_in_multiple_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "'= %select{default|delete}0' is a function definition and must occur in a standalone declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_default_template_template_parameter_not_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "default template argument for a template template parameter must be a class template", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_destructor_template_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor name %0 does not refer to a template", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_destructor_tilde_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a class name after '~' to name a destructor", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_dup_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate 'virtual' in base specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_duplicate_default_assoc, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate default generic association", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_duplicate_virt_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "class member already marked '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_dynamic_and_noexcept_specification, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot have both throw() and noexcept() clause on the same function", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_enumerator_list_missing_comma, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing ',' between enumerators", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_enumerator_unnamed_no_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "unnamed enumeration must be a definition", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_capture, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected variable name or 'this' in lambda capture list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_case_before_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected 'case' keyword before expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_catch, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected catch", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_class_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected class name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_class_name_not_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "'typename' is redundant; base classes are implicitly types", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_comma_greater, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ',' or '>' in template-parameter-list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_comma_or_rsquare, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ',' or ']' in lambda capture list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_end_of_enumerator, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '= constant-expression' or end of enumerator definition", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_equal_designator, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '=' or another designator", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_external_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected external declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_field_designator, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a field designator, such as '.field = 4'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_fn_body, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected function body after function declarator", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_init_in_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable declaration in condition must have an initializer", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_init_in_condition_lparen, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable declaration in condition cannot have a parenthesized initializer", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_lambda_body, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected body of lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_lbrace_after_base_specifiers, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '{' after base class list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_lbrace_in_compound_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '{' in compound literal", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_less_after, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '<' after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_lparen_after, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '(' after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_lparen_after_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '(' for function-style cast or type construction", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_member_name_or_semi, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected member name or ';' after declaration specifiers", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_member_or_base_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected class member or base class name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_method_body, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected method body", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_minus_or_plus, CLASS_ERROR, (unsigned)diag::Severity::Error, "method type specifier must start with '-' or '+'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_objc_container, CLASS_ERROR, (unsigned)diag::Severity::Error, "'@end' must appear in an Objective-C context", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_parameter_pack, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected the name of a parameter pack", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_parentheses_around_typename, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected parentheses around type name in %0 expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_property_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected property name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_punc, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ')' or ',' after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_qualified_after_typename, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a qualified name after 'typename'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_rparen_after, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ')' after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_selector_for_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected selector for Objective-C method", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_attribute_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after attribute list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_method_proto, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after method prototype", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_namespace_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after namespace name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_static_assert, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after static_assert", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_after_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after %0 statement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_decl_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' at end of declaration list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' at end of declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_semi_for, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' in 'for' statement specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_statement, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected statement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected template", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_template_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected template parameter", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a type", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_type_name_after_typename, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected an identifier or template-id after '::'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_unqualified_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %select{identifier|unqualified-id}0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_version, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a version of the form 'major[.minor[.subminor]]'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_expected_while, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected 'while' in do/while loop", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_explicit_instantiation_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumerations cannot be explicitly instantiated", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_explicit_instantiation_with_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_explicit_spec_non_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit %select{specialization|instantiation}0 of non-template %1 %2", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_extraneous_closing_brace, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous closing brace ('}')", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_extraneous_rparen_in_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous ')' after condition, expected a statement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_extraneous_token_before_semi, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous '%0' before ';'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_for_range_expected_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "for range declaration must declare a variable", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_friend_decl_defines_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot define a type in a friend declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_friend_decl_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' is invalid in friend declarations", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_friend_explicit_instantiation, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend cannot be declared in an explicit instantiation; if this declaration is meant to be a friend declaration, remove the 'template' keyword", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_friend_invalid_in_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "'friend' used outside of class", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_func_def_no_params, CLASS_ERROR, (unsigned)diag::Severity::Error, "function definition does not declare parameters", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_function_declared_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "function definition declared 'typedef'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_function_definition_not_allowed, CLASS_ERROR, (unsigned)diag::Severity::Error, "function definition is not allowed here", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_function_is_not_record, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected %0 in function call; perhaps remove the %0?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_id_after_template_in_nested_name_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected template name after 'template' keyword in nested name specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_illegal_decl_reference_to_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 declared as a reference to a reference", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_illegal_super_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast 'super' (it isn't an expression)", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_incomplete_array_member_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "array bound cannot be deduced from an in-class initializer", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_init_list_bin_op, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer list cannot be used on the %select{left|right}0 hand side of operator '%1'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_inline_ms_asm_parsing, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_inline_namespace_alias, CLASS_ERROR, (unsigned)diag::Severity::Error, "namespace alias cannot be inline", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_complex_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'_Complex %0' is invalid", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_decl_spec_combination, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot combine with previous '%0' declaration specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_long_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'long %0' is invalid", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_longlong_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'long long %0' is invalid", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_operator_on_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use %select{dot|arrow}0 operator on a type", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_pixel_decl_spec_combination, CLASS_ERROR, (unsigned)diag::Severity::Error, "'__pixel' must be preceded by '__vector'.  '%0' declaration specifier not allowed here", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_reference_qualifier_application, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' qualifier may not be applied to a reference", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_short_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'short %0' is invalid", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_sign_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' cannot be signed or unsigned", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_token_after_declarator_suggest_equal, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid %0 at end of declaration; did you mean '='?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_token_after_toplevel_declarator, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after top level declarator", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_vector_bool_decl_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use '%0' with '__vector bool'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_vector_decl_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use '%0' with '__vector'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_invalid_vector_decl_spec_combination, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot combine with previous '%0' declaration specifier. '__vector' must be first", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_l_square_l_square_not_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "C++11 only allows consecutive left square brackets when introducing an attribute", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_label_end_of_compound_statement, CLASS_ERROR, (unsigned)diag::Severity::Error, "label at end of compound statement: expected statement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_lambda_missing_parens, CLASS_ERROR, (unsigned)diag::Severity::Error, "lambda requires '()' before %select{'mutable'|return type|attribute specifier}0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_literal_operator_string_not_empty, CLASS_ERROR, (unsigned)diag::Severity::Error, "string literal after 'operator' must be '\"\"'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_literal_operator_string_prefix, CLASS_ERROR, (unsigned)diag::Severity::Error, "string literal after 'operator' cannot have an encoding prefix", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_misplaced_ellipsis_in_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "'...' must %select{immediately precede declared identifier|be innermost component of anonymous pack declaration}0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_catch_finally, CLASS_ERROR, (unsigned)diag::Severity::Error, "@try statement without a @catch and @finally clause", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_comma_before_ellipsis, CLASS_ERROR, (unsigned)diag::Severity::Error, "C requires a comma prior to the ellipsis in a variadic function type", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_dependent_template_keyword, CLASS_ERROR, (unsigned)diag::Severity::Error, "use 'template' keyword to treat '%0' as a dependent template name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_end_of_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing '}' at end of definition of %q0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected parameter declarator", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_missing_whitespace_digraph, CLASS_ERROR, (unsigned)diag::Severity::Error, "found '<::' after a %select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0 which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_module_expected_ident, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a module name after module import", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_expected_semi, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ';' after module name", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_ms_declspec_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "__declspec attributes must be an identifier or string literal", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_duplicate_accessor, CLASS_ERROR, (unsigned)diag::Severity::Error, "property declaration specifies '%0' accessor twice", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_expected_accessor_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected name of accessor method", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_expected_comma_or_rparen, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ',' or ')' at end of property accessor list", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_expected_equal, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '=' after '%0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_has_set_accessor, CLASS_ERROR, (unsigned)diag::Severity::Error, "putter for property must be specified as 'put', not 'set'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_missing_accessor_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing 'get=' or 'put='", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_no_getter_or_putter, CLASS_ERROR, (unsigned)diag::Severity::Error, "property does not specify a getter or a putter", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_ms_property_unknown_accessor, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected 'get' or 'put' in property declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_msasm_unable_to_create_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "MS-style inline assembly is not available: %0", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_msasm_unsupported_arch, CLASS_ERROR, (unsigned)diag::Severity::Error, "Unsupported architecture '%0' for MS-style inline assembly", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_multiple_template_declarators, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|a template declaration|an explicit template specialization|an explicit template instantiation}0 can only %select{|declare|declare|instantiate}0 a single entity", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_namespace_nonnamespace_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "namespaces can only be defined in global or namespace scope", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_nested_namespaces_with_double_colon, CLASS_ERROR, (unsigned)diag::Severity::Error, "nested namespace definition must define each namespace separately", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_no_matching_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter named %0 is missing", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_not_opencl_storage_class_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "OpenCL does not support the '%0' storage class specifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_nsnumber_nonliteral_unary, CLASS_ERROR, (unsigned)diag::Severity::Error, "@%0 must be followed by a number to form an NSNumber object", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_concat_string, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected token after Objective-C string", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_directive_only_in_protocol, CLASS_ERROR, (unsigned)diag::Severity::Error, "directive may only be specified in protocols only", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_expected_equal_for_getter, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '=' for Objective-C getter", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_expected_equal_for_setter, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '=' for Objective-C setter", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_expected_property_attr, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown property attribute %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_expected_selector_for_getter_setter, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected selector for Objective-C %select{setter|getter}0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_illegal_interface_qual, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal interface qualifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_illegal_visibility_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal visibility specification", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_missing_end, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing '@end'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_no_attributes_on_category, CLASS_ERROR, (unsigned)diag::Severity::Error, "attributes may not be specified on a category", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_postfix_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "postfix attributes are not allowed on Objective-C directives", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_postfix_attribute_hint, CLASS_ERROR, (unsigned)diag::Severity::Error, "postfix attributes are not allowed on Objective-C directives, place them in front of '%select{@interface|@protocol}0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_properties_require_objc2, CLASS_ERROR, (unsigned)diag::Severity::Error, "properties are an Objective-C 2 feature", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_property_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "property name cannot be a bitfield", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_property_requires_field_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "property requires fields to be named", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_unexpected_atend, CLASS_ERROR, (unsigned)diag::Severity::Error, "'@end' appears where closing brace '}' is expected", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_unexpected_attr, CLASS_ERROR, (unsigned)diag::Severity::Error, "prefix attribute must be followed by an interface or protocol", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objc_unknown_at, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected an Objective-C directive after '@'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objcbridge_related_expected_related_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a related ObjectiveC class name, e.g., 'NSColor'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_objcbridge_related_selector_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a class method selector with single argument, e.g., 'colorWithCGColor:'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_expected_identifier_for_critical, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected identifier specifying the name of the 'omp critical' directive", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_expected_punc, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected ',' or ')' in '%0' %select{clause|directive}1", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_immediate_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#pragma omp %0' cannot be an immediate substatement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_more_one_clause, CLASS_ERROR, (unsigned)diag::Severity::Error, "directive '#pragma omp %0' cannot contain more than one '%1' clause", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_unexpected_clause, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected OpenMP clause '%0' in directive '#pragma omp %1'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_unexpected_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected OpenMP directive '#pragma omp %0'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_omp_unknown_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected an OpenMP directive", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_out_of_line_constructor_template_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "out-of-line constructor for %0 cannot have template arguments", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_out_of_line_template_id_names_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "qualified reference to %0 is a constructor name rather than a template name wherever a constructor can be declared", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_out_of_line_type_names_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "qualified reference to %0 is a constructor name rather than a type wherever a constructor can be declared", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_override_control_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' keyword not permitted with interface types", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_paren_after_colon_colon, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected parenthesis after '::'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_paren_sizeof_parameter_pack, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing parentheses around the size of parameter pack %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_comment_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "pragma comment requires parenthesized identifier and optional string", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_comment_unknown_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown kind of pragma comment", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_detect_mismatch_malformed, CLASS_ERROR, (unsigned)diag::Severity::Error, "pragma detect_mismatch is malformed; it requires two comma-separated string literals", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_fp_contract_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#pragma fp_contract' can only appear at file scope or at the start of a compound statement", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_loop_invalid_option, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, vectorize_width, interleave, interleave_count, unroll, or unroll_count", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_missing_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing argument to '#pragma %0'; expected %1", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_optimize_extra_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected extra argument '%0' to '#pragma clang optimize'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_optimize_invalid_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected argument '%0' to '#pragma clang optimize'; expected 'on' or 'off'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_pragma_pointers_to_members_unknown_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_right_angle_bracket_equal_needs_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "a space is required between a right angle bracket and an equals sign (use '> =')", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_scoped_enum_missing_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "scoped enumeration requires a name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_seh___except_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 only allowed in __except block", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_seh___except_filter, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 only allowed in __except filter expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_seh___finally_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 only allowed in __finally block", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_seh_expected_handler, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected '__except' or '__finally' block", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_single_decl_assign_in_for_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "range-based 'for' statement uses ':', not '='", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_sizeof_parameter_pack, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected parenthesized parameter pack name in 'sizeof...' expression", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_synthesized_property_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a property name in @synthesize", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_template_defn_explicit_instantiation, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{function|class|variable}0 cannot be defined in an explicit instantiation; if this declaration is meant to be a %select{function|class|variable}0 definition, remove the 'template' keyword", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_template_spec_syntax_non_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "identifier followed by '<' indicates a class template specialization but %0 %select{does not refer to a template|refers to a function template|<unused>|refers to a variable template|<unused>}1", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_templated_using_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot template a using declaration", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_templated_using_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot template a using directive", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_this_captured_by_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "'this' cannot be captured by reference", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_two_right_angle_brackets_need_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "a space is required between consecutive right angle brackets (use '> >')", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_type_safety_unknown_flag, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_type_trait_arity, CLASS_ERROR, (unsigned)diag::Severity::Error, "type trait requires %0%select{| or more}1 argument%select{|s}2; have %3 argument%s3", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_identifiers_only, CLASS_ERROR, (unsigned)diag::Severity::Error, "typename is allowed for identifiers only", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_invalid_constexpr, CLASS_ERROR, (unsigned)diag::Severity::Error, "type name does not allow constexpr specifier to be specified", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_invalid_functionspec, CLASS_ERROR, (unsigned)diag::Severity::Error, "type name does not allow function specifier to be specified", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_invalid_storageclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "type name does not allow storage class to be specified", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_refers_to_non_type_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "typename specifier refers to a non-type template", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_typename_requires_specqual, CLASS_ERROR, (unsigned)diag::Severity::Error, "type name requires a specifier or qualifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_at, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected '@' in program", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_colon_in_nested_name_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected ':' in nested name specifier; did you mean '::'?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_namespace_attributes_alias, CLASS_ERROR, (unsigned)diag::Severity::Error, "attributes cannot be specified on namespace alias", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_protocol_qualifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "@implementation declaration cannot be protocol qualified", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_scope_on_base_decltype, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected namespace scope prior to decltype", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_token_in_nested_name_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' cannot be a part of nested name specifier; did you mean ':'?", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_typedef_ident, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected type name %0: expected identifier", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unexpected_unqualified_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "type-id cannot have a name", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unknown_template_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown template name %0", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_unspecified_vla_size_with_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "'static' may not be used with an unspecified variable length array size", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_use_of_tag_name_without_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "must use '%1' tag to refer to type %0%select{| in this scope}2", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_using_namespace_in_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "'using namespace' is not allowed in classes", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(err_zero_version, CLASS_ERROR, (unsigned)diag::Severity::Error, "version number must have non-zero major, minor, or sub-minor version", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(error_empty_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of empty enum", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(error_property_ivar_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "property synthesize requires specification of an ivar", 0, SFINAE_SubstitutionFailure, false, true, 4)
+DIAG(ext_abstract_pack_declarator_parens, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "ISO C++11 requires a parenthesized pack declaration to have a name", 17, SFINAE_Suppress, false, false, 4)
+DIAG(ext_alias_declaration, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "alias declarations are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_alignof_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%0 applied to an expression is a GNU extension", 179, SFINAE_Suppress, false, false, 4)
+DIAG(ext_auto_storage_class, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases", 38, SFINAE_Suppress, false, false, 4)
+DIAG(ext_auto_type_specifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'auto' type specifier is a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c11_alignment, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%0 is a C11-specific feature", 78, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c11_generic_selection, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "generic selections are a C11-specific feature", 78, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c11_noreturn, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "_Noreturn functions are a C11-specific feature", 78, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c11_static_assert, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "_Static_assert is a C11-specific feature", 78, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c99_compound_literal, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "compound literals are a C99-specific feature", 80, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c99_variable_decl_in_for_loop, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "variable declaration in for loop is a C99-specific feature", 80, SFINAE_Suppress, false, false, 4)
+DIAG(ext_c_enum_fixed_underlying_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "enumeration types with a fixed underlying type are a Microsoft extension", 267, SFINAE_Suppress, false, false, 4)
+DIAG(ext_cxx11_enum_fixed_underlying_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "enumeration types with a fixed underlying type are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_decltype_auto_type_specifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'decltype(auto)' type specifier is a C++1y extension", 67, SFINAE_Suppress, false, false, 4)
+DIAG(ext_defaulted_function, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "defaulted function definitions are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_deleted_function, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "deleted function definitions are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_duplicate_declspec, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "duplicate '%0' declaration specifier", 138, SFINAE_Suppress, false, false, 4)
+DIAG(ext_ellipsis_exception_spec, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "exception specification of '...' is a Microsoft extension", 267, SFINAE_Suppress, false, false, 4)
+DIAG(ext_empty_translation_unit, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C requires a translation unit to contain at least one declaration", 146, SFINAE_Suppress, false, false, 4)
+DIAG(ext_enumerator_list_comma_c, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "commas at the end of enumerator lists are a C99-specific feature", 80, SFINAE_Suppress, false, false, 4)
+DIAG(ext_enumerator_list_comma_cxx, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "commas at the end of enumerator lists are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_expected_semi_decl_list, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "expected ';' at end of declaration list", 0, SFINAE_Suppress, false, false, 4)
+DIAG(ext_extern_template, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "extern templates are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_extra_semi, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "extra ';' %select{outside of a function|inside a %1|inside instance variable list|after member function definition}0", 158, SFINAE_Suppress, false, false, 4)
+DIAG(ext_extra_semi_cxx11, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "extra ';' outside of a function is a C++11 extension", 62, SFINAE_Suppress, false, false, 4)
+DIAG(ext_for_range, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "range-based for loop is a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_for_range_identifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "range-based for loop with implicit deduced type is a C++1z extension", 68, SFINAE_Suppress, false, false, 4)
+DIAG(ext_generalized_initializer_lists, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "generalized initializer lists are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_address_of_label, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU address-of-label extension", 194, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_array_range, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU array range extension", 187, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_case_range, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU case range extension", 183, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_conditional_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU ?: conditional expression extension, omitting middle operand", 186, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_empty_initializer, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU empty initializer extension", 188, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_indirect_goto, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU indirect-goto extension", 194, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_missing_equal_designator, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use of GNU 'missing =' extension in designator", 187, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_old_style_field_designator, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use of GNU old-style field designator extension", 187, SFINAE_Suppress, false, false, 4)
+DIAG(ext_gnu_statement_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "use of GNU statement expression extension", 196, SFINAE_Suppress, false, false, 4)
+DIAG(ext_ident_list_in_param, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "type-less parameter names in function declaration", 353, SFINAE_Suppress, false, false, 4)
+DIAG(ext_inline_namespace, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "inline namespaces are a C++11 feature", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_integer_complex, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "complex integer types are a GNU extension", 184, SFINAE_Suppress, false, false, 4)
+DIAG(ext_keyword_as_ident, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "keyword '%0' will be made available as an identifier %select{here|for the remainder of the translation unit}1", 250, SFINAE_Suppress, false, false, 4)
+DIAG(ext_ms_sealed_keyword, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'sealed' keyword is a Microsoft extension", 267, SFINAE_Suppress, false, false, 4)
+DIAG(ext_nonstatic_member_init, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "in-class initialization of non-static data member is a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_override_control_keyword, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'%0' keyword is a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_plain_complex, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "plain '_Complex' requires a type specifier; assuming '_Complex double'", 0, SFINAE_Suppress, false, false, 4)
+DIAG(ext_ref_qualifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "reference qualifiers on functions are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_rvalue_reference, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "rvalue references are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_scoped_enum, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "scoped enumerations are a C++11 extension", 61, SFINAE_Suppress, false, false, 4)
+DIAG(ext_template_template_param_typename, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "template template parameter using 'typename' is a C++1z extension", 68, SFINAE_Suppress, false, false, 4)
+DIAG(ext_thread_before, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "'__thread' before '%0'", 353, SFINAE_Suppress, false, false, 4)
+DIAG(note_bracket_depth, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use -fbracket-depth=N to increase maximum nesting level", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_extra_comma_message_arg, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "comma separating Objective-C messaging arguments", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_force_empty_selector_name, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "or insert whitespace before ':' to use %0 as parameter name and have an empty entry in the selector", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_missing_end_of_definition_before, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "still within definition of %q0 here", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_missing_selector_name, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "introduce a parameter name to make %0 part of the selector", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_objc_container_start, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{class|protocol|category|class extension|implementation|category implementation}0 started here", 0, SFINAE_Suppress, false, false, 4)
+DIAG(note_previous_default_assoc, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous default generic association is here", 0, SFINAE_Suppress, false, false, 4)
+DIAG(w_asm_qualifier_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignored %0 qualifier on asm", 0, SFINAE_Suppress, false, false, 11)
+DIAG(warn_arc_bridge_cast_nonarc, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' casts have no effect when not using ARC", 20, SFINAE_Suppress, false, false, 8)
+DIAG(warn_attribute_no_decl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 ignored, because it is not attached to a declaration", 206, SFINAE_Suppress, false, false, 4)
+DIAG(warn_attribute_on_function_definition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "GCC does not allow %0 attribute in this position on a function definition", 176, SFINAE_Suppress, false, false, 4)
+DIAG(warn_auto_storage_class, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'auto' storage class specifier is redundant and incompatible with C++11", 57, SFINAE_Suppress, false, false, 4)
+DIAG(warn_availability_and_unavailable, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'unavailable' availability overrides all other availability information", 40, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cstyle_param, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of C-style parameters in Objective-C method declarations is deprecated", 115, SFINAE_Suppress, false, false, 21)
+DIAG(warn_cxx11_compat_decltype_auto_type_specifier, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'decltype(auto)' type specifier is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx11_right_shift_in_template_arg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of right-shift operator ('>>') in template argument will require parentheses in C++11", 57, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx1y_compat_for_range_identifier, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "range-based for loop with implicit deduced type is incompatible with C++ standards before C++1z", 69, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx1y_compat_template_template_param_typename, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "template template parameter using 'typename' is incompatible with C++ standards before C++1z", 69, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_alias_declaration, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "alias declarations are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_alignas, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'alignas' is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_alignof, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "alignof expressions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_attribute, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "C++11 attribute syntax is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_decltype, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'decltype' type specifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_defaulted_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "defaulted function definitions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_deleted_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "deleted function definitions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_enum_fixed_underlying_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "enumeration types with a fixed underlying type are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_enumerator_list_comma, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "commas at the end of enumerator lists are incompatible with C++98", 76, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_extern_template, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "extern templates are incompatible with C++98", 76, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_for_range, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "range-based for loop is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_generalized_initializer_lists, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "generalized initializer lists are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_inline_namespace, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "inline namespaces are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_lambda, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "lambda expressions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_literal_operator, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "literal operators are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_noexcept_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "noexcept specifications are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_noexcept_expr, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "noexcept expressions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_nonstatic_member_init, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "in-class initialization of non-static data members is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_nullptr, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'nullptr' is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_override_control_keyword, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%0' keyword is incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_ref_qualifier, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "reference qualifiers on functions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_rvalue_reference, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "rvalue references are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_scoped_enum, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "scoped enumerations are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_static_assert, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "static_assert declarations are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_top_level_semi, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "extra ';' outside of a function is incompatible with C++98", 76, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_trailing_return_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "trailing return types are incompatible with C++98", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_cxx98_compat_two_right_angle_brackets, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "consecutive right angle brackets are incompatible with C++98 (use '> >')", 73, SFINAE_Suppress, false, false, 4)
+DIAG(warn_dangling_else, CLASS_WARNING, (unsigned)diag::Severity::Warning, "add explicit braces to avoid dangling else", 104, SFINAE_Suppress, false, false, 4)
+DIAG(warn_deprecated_register, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'register' storage class specifier is deprecated", 121, SFINAE_Suppress, false, false, 21)
+DIAG(warn_duplicate_declspec, CLASS_WARNING, (unsigned)diag::Severity::Warning, "duplicate '%0' declaration specifier", 138, SFINAE_Suppress, false, false, 4)
+DIAG(warn_expected_qualified_after_typename, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "expected a qualified name after 'typename'", 0, SFINAE_Suppress, false, false, 4)
+DIAG(warn_extra_semi_after_mem_fn_def, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "extra ';' after member function definition", 158, SFINAE_Suppress, false, false, 4)
+DIAG(warn_file_asm_volatile, CLASS_WARNING, (unsigned)diag::Severity::Warning, "meaningless 'volatile' on asm outside function", 0, SFINAE_Suppress, false, false, 11)
+DIAG(warn_microsoft_dependent_exists, CLASS_WARNING, (unsigned)diag::Severity::Warning, "dependent %select{__if_not_exists|__if_exists}0 declarations are ignored", 268, SFINAE_Suppress, false, false, 4)
+DIAG(warn_missing_dependent_template_keyword, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use 'template' keyword to treat '%0' as a dependent template name", 0, SFINAE_Suppress, false, false, 4)
+DIAG(warn_missing_selector_name, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 used as the name of the previous parameter rather than as part of the selector", 280, SFINAE_Suppress, false, false, 4)
+DIAG(warn_objc_protocol_qualifier_missing_id, CLASS_WARNING, (unsigned)diag::Severity::Warning, "protocol has no object type specified; defaults to qualified 'id'", 0, SFINAE_Suppress, false, false, 4)
+DIAG(warn_omp_extra_tokens_at_eol, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extra tokens at the end of '#pragma omp %0' are ignored", 159, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_align_expected_equal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected '=' following '#pragma %select{align|options align}0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_align_invalid_option, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid alignment option in '#pragma %select{align|options align}0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_action_or_r_paren, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected action or ')' in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_colon, CLASS_WARNING, (unsigned)diag::Severity::Warning, "missing ':' after %0 - ignoring", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_enable_disable, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected 'enable' or 'disable' - ignoring", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_identifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected identifier in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_init_seg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_integer, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected integer between %0 and %1 inclusive in '#pragma %2' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_lparen, CLASS_WARNING, (unsigned)diag::Severity::Warning, "missing '(' after '#pragma %0' - ignoring", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_non_wide_string, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected non-wide string literal in '#pragma %0'", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_punc, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected ')' or ',' in '#pragma %0'", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_rparen, CLASS_WARNING, (unsigned)diag::Severity::Warning, "missing ')' after '#pragma %0' - ignoring", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_section_label_or_name, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected a stack label or a string literal for the section name in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_section_name, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected a string literal for the section name in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_expected_section_push_pop_or_name, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected push, pop or a string literal for the section name in '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_extra_tokens_at_eol, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extra tokens at end of '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_init_seg_unsupported_target, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'#pragma init_seg' is only supported when targeting a Microsoft environment", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_invalid_action, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown action for '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_invalid_specific_action, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown action '%1' for '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_ms_struct, CLASS_WARNING, (unsigned)diag::Severity::Warning, "incorrect use of '#pragma ms_struct on|off' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_omp_ignored, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unexpected '#pragma omp ...' in program", 405, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_options_expected_align, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected 'align' following '#pragma options' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_pack_malformed, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected integer or identifier in '#pragma pack' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_unknown_extension, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown OpenCL extension %0 - ignoring", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_unroll_cuda_value_in_parens, CLASS_WARNING, (unsigned)diag::Severity::Warning, "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++", 102, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_unsupported_action, CLASS_WARNING, (unsigned)diag::Severity::Warning, "known but unsupported action '%1' for '#pragma %0' - ignored", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_pragma_unused_expected_var, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected '#pragma unused' argument to be a variable name", 207, SFINAE_Suppress, false, false, 4)
+DIAG(warn_semicolon_before_method_body, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "semicolon before method body is ignored", 386, SFINAE_Suppress, false, false, 4)
+DIAG(warn_static_inline_explicit_inst_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignoring '%select{static|inline}0' keyword on explicit template instantiation", 409, SFINAE_Suppress, false, false, 4)
+DIAG(warn_vector_long_decl_spec_combination, CLASS_WARNING, (unsigned)diag::Severity::Warning, "Use of 'long' with '__vector' is deprecated", 114, SFINAE_Suppress, false, false, 21)
diff --git a/include/clang/Basic/DiagnosticSemaKinds.inc b/include/clang/Basic/DiagnosticSemaKinds.inc
new file mode 100644
index 0000000..a656976
--- /dev/null
+++ b/include/clang/Basic/DiagnosticSemaKinds.inc
@@ -0,0 +1,2604 @@
+#ifdef SEMASTART
+__SEMASTART = DIAG_START_SEMA,
+#undef SEMASTART
+#endif
+
+DIAG(err_abstract_type_in_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{return|parameter|variable|field|instance variable|synthesized instance variable}0 type %1 is an abstract class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "%1 is a %select{private|protected}0 member of %3", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_base_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{base class|inherited virtual base class}0 %1 has %select{private|protected}3 %select{default |copy |move |*ERROR* |*ERROR* |*ERROR*|}2constructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "calling a %select{private|protected}0 constructor of class %2", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "ISO C++11 does not allow access declarations; use using declarations instead", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_access_dtor, CLASS_ERROR, (unsigned)diag::Severity::Error, "calling a %select{private|protected}1 destructor of class %0", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "base class %0 has %select{private|protected}1 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_exception, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception object of type %0 has %select{private|protected}1 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_field, CLASS_ERROR, (unsigned)diag::Severity::Error, "field of type %1 has %select{private|protected}2 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_ivar, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable of type %0 has %select{private|protected}1 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_temp, CLASS_ERROR, (unsigned)diag::Severity::Error, "temporary of type %0 has %select{private|protected}1 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable of type %1 has %select{private|protected}2 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_dtor_vbase, CLASS_ERROR, (unsigned)diag::Severity::Error, "inherited virtual base class %1 has %select{private|protected}2 destructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_field_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "field of type %0 has %select{private|protected}2 %select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_friend_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend function %1 is a %select{private|protected}0 member of %3", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_access_lambda_capture, CLASS_ERROR, (unsigned)diag::Severity::Error, "capture of variable '%0' as type %1 calls %select{private|protected}3 %select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}2constructor", 0, SFINAE_AccessControl, false, true, 3)
+DIAG(err_addr_ovl_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of overloaded function %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_addr_ovl_no_qualifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "can't form member pointer of type %0 without '&' and class name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_addr_ovl_no_viable, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of overloaded function %0 does not match required type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_addr_ovl_not_func_ptrref, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of overloaded function %0 cannot be converted to type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_address_space_qualified_delete, CLASS_ERROR, (unsigned)diag::Severity::Error, "'delete' cannot delete objects of type %0 in address space '%1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_address_space_qualified_new, CLASS_ERROR, (unsigned)diag::Severity::Error, "'new' cannot allocate objects of type %0 in address space '%1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alias_after_tentative, CLASS_ERROR, (unsigned)diag::Severity::Error, "alias definition of %0 after tentative definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alias_not_supported_on_darwin, CLASS_ERROR, (unsigned)diag::Severity::Error, "only weak aliases are supported on darwin", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alias_template_expansion_into_fixed_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "pack expansion used as argument for non-pack parameter of alias template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alias_template_extra_headers, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous template parameter list in alias template declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alias_to_undefined, CLASS_ERROR, (unsigned)diag::Severity::Error, "alias must point to a defined variable or function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alignas_attribute_wrong_decl_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be applied to a %select{function parameter|variable with 'register' storage class|'catch' variable|bit-field}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alignas_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "redeclaration has different alignment requirement (%1 vs %0)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alignas_missing_on_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must be specified on definition if it is specified on any declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alignas_underaligned, CLASS_ERROR, (unsigned)diag::Severity::Error, "requested alignment is less than minimum alignment of %1 for type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_aligned_attribute_argument_not_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "'aligned' attribute requires integer constant", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_alignof_member_of_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of 'alignof' to a field of a class still being defined", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_allocation_of_abstract_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "allocating an object of abstract class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_altivec_empty_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_base_to_derived_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous cast from base %0 to derived %1:%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_delete_operand, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion of delete expression of type %0 to a pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_derived_to_base_conv, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion from derived class %0 to base class %1:%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_member_multiple_subobject_types, CLASS_ERROR, (unsigned)diag::Severity::Error, "member %0 found in multiple base classes of different types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_member_multiple_subobjects, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-static member %0 found in multiple base-class subobjects of type %1:%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_memptr_conv, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion from pointer to member of %select{base|derived}0 class %1 to pointer to member of %select{derived|base}0 class %2:%3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_suitable_delete_member_function_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple suitable %0 functions in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ambiguous_tag_hiding, CLASS_ERROR, (unsigned)diag::Severity::Error, "a type named %0 is hidden by a declaration in a different namespace", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anon_bitfield_has_negative_width, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous bit-field has negative width (%0)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anon_bitfield_width_exceeds_type_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous property is not supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_record_bad_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous %select{struct|union}0 can only contain non-static data members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_record_nonpublic_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous %select{struct|union}0 cannot contain a %select{private|protected}1 data member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_record_with_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "functions cannot be declared in an anonymous %select{struct|union}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_record_with_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "static members cannot be declared in an anonymous %select{struct|union}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_record_with_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "types cannot be declared in an anonymous %select{struct|union}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_struct_member_redecl, CLASS_ERROR, (unsigned)diag::Severity::Error, "member of anonymous struct redeclares %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_struct_not_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous %select{structs|structs and classes}0 must be %select{struct or union|class}0 members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_union_member_redecl, CLASS_ERROR, (unsigned)diag::Severity::Error, "member of anonymous union redeclares %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_union_not_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous unions at namespace or global scope must be declared 'static'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_anonymous_union_with_storage_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous union at class scope must not have a storage specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_arc_array_param_no_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "must explicitly describe intended ownership of an object array parameter", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_assign_property_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "existing instance variable %1 for property %0 with %select{unsafe_unretained| assign}2 attribute must be __unsafe_unretained", 0, SFINAE_SubstitutionFailure, false, true, 6)
+DIAG(err_arc_atomic_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot perform atomic operation on a pointer to type %0: type has non-trivial ownership", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_autoreleasing_capture, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot capture __autoreleasing variable in a %select{block|lambda by copy}0", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_autoreleasing_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{__block variables|global variables|fields|instance variables}0 cannot have __autoreleasing ownership", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_bridge_cast_incompatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "incompatible types casting %0 to %1 with a %select{__bridge|__bridge_transfer|__bridge_retained}2 cast", 0, SFINAE_SubstitutionFailure, false, true, 7)
+DIAG(err_arc_bridge_cast_wrong_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "cast of %select{Objective-C|block|C}0 pointer type %1 to %select{Objective-C|block|C}2 pointer type %3 cannot use %select{__bridge|__bridge_transfer|__bridge_retained}4", 0, SFINAE_SubstitutionFailure, false, true, 7)
+DIAG(err_arc_cast_requires_bridge, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{cast|implicit conversion}0 of %select{Objective-C|block|C}1 pointer type %2 to %select{Objective-C|block|C}3 pointer type %4 requires a bridged cast", 0, SFINAE_SubstitutionFailure, false, true, 7)
+DIAG(err_arc_collection_forward, CLASS_ERROR, (unsigned)diag::Severity::Error, "collection expression type %0 is a forward declaration", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_convesion_of_weak_unavailable, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to a __weak object of type %2", 0, SFINAE_SubstitutionFailure, false, true, 9)
+DIAG(err_arc_gained_method_convention, CLASS_ERROR, (unsigned)diag::Severity::Error, "method implementation does not match its declaration", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_illegal_explicit_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "ARC forbids explicit message send of %0", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_illegal_method_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "ARC forbids %select{implementation|synthesis}0 of %1", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_illegal_selector, CLASS_ERROR, (unsigned)diag::Severity::Error, "ARC forbids use of %0 in a @selector", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_inconsistent_property_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2", 0, SFINAE_SubstitutionFailure, false, true, 6)
+DIAG(err_arc_indirect_no_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{pointer|reference}1 to non-const type %0 with no explicit ownership", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_init_method_unrelated_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "init methods must return a type related to the receiver type", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_lost_method_convention, CLASS_ERROR, (unsigned)diag::Severity::Error, "method was declared as %select{an 'alloc'|a 'copy'|an 'init'|a 'new'}0 method, but its implementation doesn't match because %select{its result type is not an object pointer|its result type is unrelated to its receiver type}1", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_may_not_respond, CLASS_ERROR, (unsigned)diag::Severity::Error, "no visible @interface for %0 declares the selector %1", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_method_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "no known %select{instance|class}1 method for selector %0", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_mismatched_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{implicit conversion|cast}0 of %select{%2|a non-Objective-C pointer type %2|a block pointer|an Objective-C pointer|an indirect pointer to an Objective-C pointer}1 to %3 is disallowed with ARC", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_multiple_method_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple methods named %0 found with mismatched result, parameter type or attributes", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_new_array_without_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "'new' cannot allocate an array of %0 with no explicit ownership", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_nolifetime_behavior, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit ownership qualifier on cast result has no effect", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_nonlocal_writeback, CLASS_ERROR, (unsigned)diag::Severity::Error, "passing address of %select{non-local|non-scalar}0 object to __autoreleasing parameter for write-back", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_objc_object_in_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "ARC forbids %select{Objective-C objects|blocks}0 in %select{struct|interface|union|<<ERROR>>|enum}1", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_objc_property_default_assign_on_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "ARC forbids synthesizing a property of an Objective-C object with unspecified ownership or storage attribute", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_perform_selector_retains, CLASS_ERROR, (unsigned)diag::Severity::Error, "performSelector names a selector which retains the object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_arc_pseudo_dtor_inconstant_quals, CLASS_ERROR, (unsigned)diag::Severity::Error, "pseudo-destructor destroys object of type %0 with inconsistently-qualified type %1", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_receiver_forward_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "receiver %0 for class message is a forward declaration", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_receiver_forward_instance, CLASS_ERROR, (unsigned)diag::Severity::Error, "receiver type %0 for instance message is a forward declaration", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_strong_property_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "existing instance variable %1 for strong property %0 may not be %select{|__unsafe_unretained||__weak}2", 0, SFINAE_SubstitutionFailure, false, true, 6)
+DIAG(err_arc_thread_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "thread-local variable has non-trivial ownership: type is %0", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_arc_typecheck_convert_incompatible_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "incompatible pointer types passing retainable parameter of type %0to a CF function expecting %1 type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_arc_unsupported_weak_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "class is incompatible with __weak references", 0, SFINAE_SubstitutionFailure, false, true, 9)
+DIAG(err_arc_unused_init_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "the result of a delegate init call must be immediately returned or assigned to 'self'", 0, SFINAE_SubstitutionFailure, false, true, 10)
+DIAG(err_arc_weak_no_runtime, CLASS_ERROR, (unsigned)diag::Severity::Error, "the current deployment target does not support automated __weak references", 0, SFINAE_SubstitutionFailure, false, true, 9)
+DIAG(err_arc_weak_unavailable_assign, CLASS_ERROR, (unsigned)diag::Severity::Error, "assignment of a weak-unavailable object to a __weak object", 0, SFINAE_SubstitutionFailure, false, true, 9)
+DIAG(err_arc_weak_unavailable_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "synthesizing __weak instance variable of type %0, which does not support weak references", 0, SFINAE_SubstitutionFailure, false, true, 9)
+DIAG(err_arg_with_address_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter may not be qualified with an address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_argument_invalid_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument should be a value from %0 to %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_arithmetic_nonfragile_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "arithmetic on pointer to interface %0, which is not a constant size for this architecture and platform", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_designator_empty_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "array designator range [%0, %1] is empty", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_designator_negative, CLASS_ERROR, (unsigned)diag::Severity::Error, "array designator value '%0' is negative", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_designator_non_array, CLASS_ERROR, (unsigned)diag::Severity::Error, "array designator cannot initialize non-array type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_designator_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "array designator index (%0) exceeds array bounds (%1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_different_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot initialize array %diff{of type $ with array of type $|with different type of array}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_incompat_wide_string_into_wchar, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializing wide char array with incompatible wide string literal", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_narrow_string_into_wchar, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializing wide char array with non-wide string literal", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_non_constant_array, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot initialize array %diff{of type $ with non-constant array of type $|with different type of array}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_not_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "array initializer must be an initializer list%select{| or string literal| or wide string literal}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_init_wide_string_into_char, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializing char array with wide string literal", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_new_needs_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "array size must be specified in new expressions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_of_abstract_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "array of abstract class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_size_ambiguous_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion of array size expression of type %0 to an integral or enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_size_explicit_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "array size expression of type %0 requires explicit conversion to type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_size_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "array size expression has incomplete class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_size_non_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "size of array has non-integer type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_size_not_integral, CLASS_ERROR, (unsigned)diag::Severity::Error, "array size expression must have integral or %select{|unscoped }0enumeration type, not %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_star_in_function_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array must be bound in function definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_star_outside_prototype, CLASS_ERROR, (unsigned)diag::Severity::Error, "star modifier used outside of function prototype", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_static_not_outermost, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 used in non-outermost array type derivation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_static_outside_prototype, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 used in array declarator outside of function prototype", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_array_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "array is too large (%0 elements)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_as_qualified_auto_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "automatic variable qualified with an address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_asm_bad_register_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "bad type for named register variable", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "asm operand has incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_input_constraint, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid input constraint '%0' in asm", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_input_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid input size for constraint '%0'", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_lvalue_in_input, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid lvalue in asm input for constraint '%0'", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_lvalue_in_output, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid lvalue in asm output", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_output_constraint, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid output constraint '%0' in asm", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_invalid_type_in_input, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid type %0 in asm input for constraint '%1'", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_tying_incompatible_types, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported inline asm: input with type %diff{$ matching output with type $|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_unknown_register_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown register name '%0' in asm", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_asm_wide_character, CLASS_ERROR, (unsigned)diag::Severity::Error, "wide string is invalid in 'asm'", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_assoc_compatible_types, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 in generic association compatible with previously specified type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_assoc_type_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 in generic association incomplete", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_assoc_type_nonobject, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 in generic association not an object type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_assoc_type_variably_modified, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 in generic association is a variably modified type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atdef_nonfragile_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of @defs is not supported on this architecture and platform", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_builtin_must_be_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic builtin must be a pointer (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_builtin_must_be_pointer_intfltptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic builtin must be a pointer to integer, floating-point or pointer (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_builtin_must_be_pointer_intptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic builtin must be a pointer to integer or pointer (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_builtin_pointer_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_exclusive_builtin_pointer_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_load_store_uses_lib, CLASS_ERROR, (unsigned)diag::Severity::Error, "atomic %select{load|store}0 requires runtime support that is not available for this target", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_op_bitwise_needs_atomic_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to bitwise atomic operation must be a pointer to %select{|atomic }0integer (%1 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_op_needs_atomic, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic operation must be a pointer to _Atomic type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_op_needs_atomic_int_or_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic operation must be a pointer to %select{|atomic }0integer or pointer (%1 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_op_needs_non_const_atomic, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic operation must be a pointer to non-const _Atomic type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_op_needs_trivial_copy, CLASS_ERROR, (unsigned)diag::Severity::Error, "address argument to atomic operation must be a pointer to a trivially-copyable type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_property_nontrivial_assign_op, CLASS_ERROR, (unsigned)diag::Severity::Error, "atomic property of reference type %0 cannot have non-trivial assignment operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_atomic_specifier_bad_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "_Atomic cannot be applied to %select{incomplete |array |function |reference |atomic |qualified |}0type %1 %select{||||||which is not trivially copyable}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attr_objc_ownership_redundant, CLASS_ERROR, (unsigned)diag::Severity::Error, "the type %0 is already explicitly ownership-qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attr_tlsmodel_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "tls_model must be \"global-dynamic\", \"local-dynamic\", \"initial-exec\" or \"local-exec\"", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attr_wrong_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute invalid on this declaration, requires typedef or value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_address_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "function type may not be qualified with an address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_address_multiple_qualifiers, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple address spaces specified for type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_address_space_negative, CLASS_ERROR, (unsigned)diag::Severity::Error, "address space is negative", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_address_space_too_high, CLASS_ERROR, (unsigned)diag::Severity::Error, "address space is larger than the maximum supported (%0)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_aligned_not_power_of_two, CLASS_ERROR, (unsigned)diag::Severity::Error, "requested alignment is not a power of 2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_aligned_too_great, CLASS_ERROR, (unsigned)diag::Severity::Error, "requested alignment must be %0 bytes or smaller", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_is_zero, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute must be greater than 0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_n_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute requires parameter %1 to be %select{int or bool|an integer constant|a string|an identifier}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_out_of_bounds, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute parameter %1 is out of bounds", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_out_of_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute parameter %1 is out of bounds: %plural{0:no parameters to index into|1:can only be 1, since there is one parameter|:must be between 1 and %2}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_outof_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "init_priority attribute requires integer constant between 101 and 65535 inclusive", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute requires %select{int or bool|an integer constant|a string|an identifier}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_argument_vec_type_hint, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid attribute argument %0 - expecting a vector or vectorizable scalar type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_bad_neon_vector_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "Neon vector size must be 64 or 128 bits", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_cleanup_arg_not_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'cleanup' argument %select{|%1 |%1 }0is not a %select{||single }0function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_cleanup_func_arg_incompatible_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "'cleanup' function %0 parameter has %diff{type $ which is incompatible with type $|incompatible type}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_cleanup_func_must_take_one_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "'cleanup' function %0 must take 1 parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dll_deleted, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %q0 cannot be applied to a deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dll_member_of_dll_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %q0 cannot be applied to member of %q1 class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dll_not_extern, CLASS_ERROR, (unsigned)diag::Severity::Error, "%q0 must have external linkage when declared %q1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dll_redeclaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "redeclaration of %q0 cannot add %q1 attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dllimport_data_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of dllimport data", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dllimport_function_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "dllimport cannot be applied to non-inline function definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_dllimport_static_field_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of dllimport static field not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_invalid_implicit_this_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute is invalid for the implicit this argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_invalid_on_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be applied to a statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_invalid_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "vector size not an integral multiple of component size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_invalid_vector_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid vector element type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_multiple_objc_gc, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple garbage collection attributes specified for type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_no_member_pointers, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be used with pointers to members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_not_supported_in_lang, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute is not supported in %select{C|C++|Objective-C}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_overloadable_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{overloaded function|redeclaration of}0 %1 must have the 'overloadable' attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_overloadable_no_prototype, CLASS_ERROR, (unsigned)diag::Severity::Error, "'overloadable' function %0 must have a prototype", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_pointers_only, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute only applies to pointer arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_regparm_invalid_number, CLASS_ERROR, (unsigned)diag::Severity::Error, "'regparm' parameter must be between 0 and %0 inclusive", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_regparm_wrong_platform, CLASS_ERROR, (unsigned)diag::Severity::Error, "'regparm' is not valid on this platform", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_section_invalid_for_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to 'section' attribute is not valid for this target: %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_selectany_non_extern_data, CLASS_ERROR, (unsigned)diag::Severity::Error, "'selectany' can only be applied to data items with external linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_sentinel_less_than_zero, CLASS_ERROR, (unsigned)diag::Severity::Error, "'sentinel' parameter 1 less than zero", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_sentinel_not_zero_or_one, CLASS_ERROR, (unsigned)diag::Severity::Error, "'sentinel' parameter 2 not 0 or 1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_size_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "vector size too large", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_too_few_arguments, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute takes at least %1 argument%s1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_too_many_arguments, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute takes no more than %1 argument%s1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute is not supported for this target", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_uuid_malformed_guid, CLASS_ERROR, (unsigned)diag::Severity::Error, "uuid attribute contains a malformed GUID", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_vecreturn_only_pod_record, CLASS_ERROR, (unsigned)diag::Severity::Error, "the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_vecreturn_only_vector_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "the vecreturn attribute can only be used on a class or structure with one member, which must be a vector", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_weak_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "weak declaration cannot have internal linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_weakref_not_global_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "weakref declaration of %0 must be in a global context", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_weakref_not_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "weakref declaration must have internal linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_weakref_without_alias, CLASS_ERROR, (unsigned)diag::Severity::Error, "weakref declaration of %0 must also have an alias attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_wrong_decl_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute only applies to %select{functions|unions|variables and functions|functions and methods|parameters|functions, methods and blocks|functions, methods, and classes|functions, methods, and parameters|classes|variables|methods|variables, functions and labels|fields and global variables|structs|variables, functions and tag types|thread-local variables|variables and fields|variables, data members and tag types|types and namespaces|Objective-C interfaces|methods and properties|struct or union|struct, union or class|types|Objective-C instance methods|init methods of interface or class extension declarations|variables, functions and classes|Objective-C protocols|functions and global variables|structs or typedefs|interface or protocol declarations}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_wrong_number_arguments, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute %plural{0:takes no arguments|1:takes one argument|:requires exactly %1 arguments}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attribute_zero_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "zero vector size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_attributes_are_not_compatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 and %1 attributes are not compatible", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_different_deductions, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%select{auto|decltype(auto)}0' deduced as %1 in declaration of %2 and deduced as %3 in declaration of %4", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce return type %0 from returned value of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_different_deductions, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%select{auto|decltype(auto)}0' in return type deduced as %1 here but deduced as %2 in earlier return statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_no_return_but_not_auto, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce return type %0 for function with no return statements", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_return_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce return type from initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_return_void_but_not_auto, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce return type %0 from omitted return expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_used_before_defined, CLASS_ERROR, (unsigned)diag::Severity::Error, "function %0 with deduced return type cannot be used before it is defined", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_fn_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "function with deduced return type cannot be virtual", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_missing_trailing_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "'auto' return without trailing return type; deduced return types are a C++1y extension", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_new_ctor_multiple_expressions, CLASS_ERROR, (unsigned)diag::Severity::Error, "new expression for type %0 contains multiple constructor arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_new_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "new expression for type %0 has incompatible constructor argument of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_new_list_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "new expression for type %0 cannot use list-initialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_new_requires_ctor_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "new expression for type %0 requires a constructor argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_not_allowed, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{'auto'|'decltype(auto)'}0 not allowed %select{in function prototype|in non-static struct member|in non-static union member|in non-static class member|in interface member|in exception declaration|in template parameter|in block literal|in template argument|in typedef|in type alias|in function return type|in conversion function type|here|in lambda parameter}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_not_allowed_var_inst, CLASS_ERROR, (unsigned)diag::Severity::Error, "'auto' variable template instantiation is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 with type %1 has incompatible initializer of type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_deduction_failure_from_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce actual type for variable %0 with type %1 from initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_init_multiple_expressions, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer for variable %0 with type %1 contains multiple expressions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_init_no_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer for variable %0 with type %1 is empty", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_init_paren_braces, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce type for variable %0 with type %1 from parenthesized initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_var_requires_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of variable %0 with type %1 requires an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_auto_variable_cannot_appear_in_own_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 declared with 'auto' type cannot appear in its own initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_const_cast_dest, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{const_cast||||C-style cast|functional-style cast}0 to %2, which is not a reference, pointer-to-object, or pointer-to-data-member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cstyle_cast_overload, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of overloaded function %0 cannot be cast to type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from bit-field lvalue to reference type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_generic, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2 is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_member_pointer_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer type %1 to member pointer type %2 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_qualifiers_away, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2 casts away qualifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_rvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from rvalue to reference type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_scalar_to_vector_different_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{||reinterpret_cast||C-style cast|}0 from scalar %1 to vector %2 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_vector_to_scalar_different_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{||reinterpret_cast||C-style cast|}0 from vector %1 to scalar %2 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_cxx_cast_vector_to_vector_different_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{||reinterpret_cast||C-style cast|}0 from vector %1 to vector %2 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_dynamic_cast_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is an incomplete type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_dynamic_cast_not_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_dynamic_cast_not_polymorphic, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not polymorphic", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_dynamic_cast_not_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_dynamic_cast_not_ref_or_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a reference or pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_kernel_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be used as the type of a kernel parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_lvalue_to_rvalue_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast from lvalue of type %1 to rvalue reference type %2; types are not compatible", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_memptr_lhs, CLASS_ERROR, (unsigned)diag::Severity::Error, "left hand operand to %0 must be a %select{|pointer to }1class compatible with the right hand operand, but is %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_memptr_rhs, CLASS_ERROR, (unsigned)diag::Severity::Error, "right hand operand to %0 has non-pointer-to-member type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_new_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot allocate %select{function|reference}1 type %0 with new", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_parameter_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be the name of a parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_receiver_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "bad receiver type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_reinterpret_cast_overload, CLASS_ERROR, (unsigned)diag::Severity::Error, "reinterpret_cast cannot resolve overloaded function %0 to type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_reinterpret_cast_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "reinterpret_cast of a %0 to %1 needs its address which is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_reinterpret_cast_small_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "cast from pointer to smaller type %2 loses information", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_static_cast_member_pointer_nonmp, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast from type %1 to member pointer type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_static_cast_overload, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of overloaded function %0 cannot be static_cast to type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_static_cast_pointer_nonpointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast from type %1 to pointer type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bad_variable_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be the name of a variable or data member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_class_has_flexible_array_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "base class %0 has a flexible array member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_clause_on_union, CLASS_ERROR, (unsigned)diag::Severity::Error, "unions cannot have base classes", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_init_direct_and_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "base class initializer %0 names both a direct base class and an inherited virtual base class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_init_does_not_name_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "constructor initializer %0 does not name a class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_must_be_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "base specifier must name a class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_base_specifier_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be applied to a base specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bitfield_has_negative_width, CLASS_ERROR, (unsigned)diag::Severity::Error, "bit-field %0 has negative width (%1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bitfield_has_zero_width, CLASS_ERROR, (unsigned)diag::Severity::Error, "named bit-field %0 has zero width", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bitfield_width_exceeds_type_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_decl_ref_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable is not assignable (missing __block type specifier)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_extern_cant_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "'extern' variable cannot have an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_on_nonlocal, CLASS_ERROR, (unsigned)diag::Severity::Error, "__block attribute not allowed, only allowed on local variables", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_on_vm, CLASS_ERROR, (unsigned)diag::Severity::Error, "__block attribute not allowed on declaration with a variably modified type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_return_missing_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-void block should return a value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_block_returning_array_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "block cannot return %select{array|function}0 type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_blocks_disable, CLASS_ERROR, (unsigned)diag::Severity::Error, "blocks support disabled - compile with -fblocks or pick a deployment target that supports them", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_bound_member_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to non-static member function must be called%select{|; did you mean to call it with no arguments?}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_box_literal_collection, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{string|character|boolean|numeric}0 literal must be prefixed by '@' in a collection", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_break_not_in_loop_or_switch, CLASS_ERROR, (unsigned)diag::Severity::Error, "'break' statement not in loop or switch statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_annotation_first_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "first argument to __builtin_annotation must be an integer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_annotation_second_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "second argument to __builtin_annotation must be a non-wide string constant", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of builtin function %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_fn_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "builtin functions must be directly called", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_func_cast_more_than_one_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "function-style cast to a builtin type can only take one argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_longjmp_invalid_val, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to __builtin_longjmp must be a constant 1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_builtin_requires_language, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' is only available in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_c99_array_usage_cxx, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 feature, not permitted in C++", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_call_function_incomplete_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "calling %0 with incomplete return type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_call_incomplete_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument type %0 is incomplete", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_call_incomplete_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "calling function with incomplete return type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cannot_form_pointer_to_member_of_reference_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot form a pointer-to-member to member %0 of reference type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cannot_pass_objc_interface_to_vararg, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot pass object with interface type %0 by value through variadic %select{function|block|method|constructor}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cannot_pass_objc_interface_to_vararg_format, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot pass object with interface type %1 by value to variadic %select{function|block|method|constructor}2; expected type from format string was %3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cannot_pass_to_vararg, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot pass %select{expression of type %1|initializer list}0 to variadic %select{function|block|method|constructor}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cannot_pass_to_vararg_format, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot pass %select{expression of type %1|initializer list}0 to variadic %select{function|block|method|constructor}2; expected type from format string was %3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_capture_block_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "__block variable %0 cannot be captured in a %select{lambda expression|captured statement}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_capture_default_non_local, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-local lambda expression cannot have a capture-default", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_capture_does_not_name_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 in capture list does not name a variable", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_capture_more_than_once, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 can appear only once in a capture list", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_capture_non_automatic_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be captured because it does not have automatic storage duration", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_capture_of_abstract_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "by-copy capture of value of abstract type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_capture_of_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "by-copy capture of variable %0 with incomplete type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_carries_dependency_missing_on_first_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{function|parameter}0 declared '[[carries_dependency]]' after its first declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_carries_dependency_param_not_function_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "'[[carries_dependency]]' attribute only allowed on parameter in a function declaration or lambda", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_case_not_in_switch, CLASS_ERROR, (unsigned)diag::Severity::Error, "'case' statement not in switch statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cast_pointer_from_non_pointer_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "operand of type %0 cannot be cast to a pointer type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cast_pointer_to_non_pointer_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "pointer cannot be cast to type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cast_selector_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot type cast @selector expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_catch_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot catch incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_catch_incomplete_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot catch pointer to incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_catch_incomplete_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot catch reference to incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_catch_param_not_objc_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "@catch parameter is not a pointer to an interface type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_catch_rvalue_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot catch exceptions by rvalue reference", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_category_forward_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot define %select{category|class extension}0 for undefined class %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cconv_change, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declared '%0' here was previously declared %select{'%2'|without calling convention}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cconv_knr, CLASS_ERROR, (unsigned)diag::Severity::Error, "function with no prototype cannot use %0 calling convention", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cconv_varargs, CLASS_ERROR, (unsigned)diag::Severity::Error, "variadic function cannot use %0 calling convention", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cfstring_literal_not_string_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "CFString literal is not a string constant", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_circular_inheritance, CLASS_ERROR, (unsigned)diag::Severity::Error, "circular inheritance between %0 and %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_class_extension_after_impl, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot declare class extension for %0 after class implementation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_class_marked_final_used_as_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "base %0 is marked '%select{final|sealed}1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_class_redeclared_with_different_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 redeclared with '%1' access", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cocoa_naming_owned_rule, CLASS_ERROR, (unsigned)diag::Severity::Error, "property follows Cocoa naming convention for returning 'owned' objects", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_collection_expr_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "the type %0 is not a pointer to a fast-enumerable object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_compound_qualified_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{block pointer|pointer|reference}0 to function type %select{%2 |}1cannot have '%3' qualifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cond_voidptr_arc, CLASS_ERROR, (unsigned)diag::Severity::Error, "operands to conditional of types%diff{ $ and $|}0,1 are incompatible in ARC mode", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conditional_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "conditional expression is ambiguous; %diff{$ can be converted to $ and vice versa|types can be convert to each other}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conditional_ambiguous_ovl, CLASS_ERROR, (unsigned)diag::Severity::Error, "conditional expression is ambiguous; %diff{$ and $|types}0,1 can be converted to several common types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conditional_void_nonvoid, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{left|right}1 operand to ? is void, but %select{right|left}1 operand is of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_config_scalar_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "CUDA special function 'cudaConfigureCall' must have scalar return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_aliasing_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "conflicting types for alias %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_ivar_bitwidth, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 has conflicting bit-field width", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_ivar_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "conflicting instance variable names: %0 vs %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_ivar_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 has conflicting type%diff{: $ vs $|}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_overriding_cc_attributes, CLASS_ERROR, (unsigned)diag::Severity::Error, "virtual function %0 has different calling convention attributes %diff{($) than the function it overrides (which has calling convention $)|than the function it overrides}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_super_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "conflicting super class name %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conflicting_types, CLASS_ERROR, (unsigned)diag::Severity::Error, "conflicting types for %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constant_integer_arg_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to %0 must be a constant integer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_body_invalid_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement not allowed in constexpr %select{function|constructor}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_body_no_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "no return statement in constexpr function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_ctor_missing_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr constructor must initialize all members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_dtor, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be marked constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_function_try_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "function try block not allowed in constexpr %select{function|constructor}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_local_var_no_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "variables defined in a constexpr %select{function|constructor}0 must be initialized", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_local_var_non_literal_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable of non-literal type %1 cannot be defined in a constexpr %select{function|constructor}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_local_var_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{static|thread_local}1 variable not permitted in a constexpr %select{function|constructor}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_main, CLASS_ERROR, (unsigned)diag::Severity::Error, "'main' is not allowed to be declared constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_method_non_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-literal type %0 cannot have constexpr members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_no_declarators, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr can only be used in variable and function declarations", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_non_literal_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is not a literal type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_non_literal_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr function's return type %0 is not a literal type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_redecl_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-constexpr declaration of %0 follows constexpr declaration|constexpr declaration of %0 follows non-constexpr declaration}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_static_mem_var_requires_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of constexpr static data member %0 requires an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|struct|interface|union|enum}0 cannot be marked constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_union_ctor_no_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr union constructor does not initialize any member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_var_non_literal, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr variable cannot have non-literal type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_var_requires_const_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr variable %0 must be initialized by a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "virtual function cannot be constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_virtual_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr %select{member function|constructor}0 not allowed in %select{struct|interface|class}1 with virtual base %plural{1:class|:classes}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constexpr_vla, CLASS_ERROR, (unsigned)diag::Severity::Error, "variably-modified type %0 cannot be used in a constexpr %select{function|constructor}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constructor_byvalue_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "copy constructor must pass its first argument by reference", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constructor_cannot_be, CLASS_ERROR, (unsigned)diag::Severity::Error, "constructor cannot be declared '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constructor_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "constructor cannot be redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_constructor_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "constructor cannot have a return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_continuation_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "class extension has no primary class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_continue_not_in_loop, CLASS_ERROR, (unsigned)diag::Severity::Error, "'continue' statement not in loop statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_not_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function must be a non-static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot be redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot have a return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_to_array, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot convert to an array type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_to_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot convert to a function type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_variadic, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot be variadic", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_with_complex_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "must use a typedef to declare a conversion to %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_conv_function_with_params, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function cannot have any parameters", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_convertvector_incompatible_vector, CLASS_ERROR, (unsigned)diag::Severity::Error, "first two arguments to __builtin_convertvector must have the same number of elements", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_convertvector_non_vector, CLASS_ERROR, (unsigned)diag::Severity::Error, "first argument to __builtin_convertvector must be a vector", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_convertvector_non_vector_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "second argument to __builtin_convertvector must be a vector type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_copy_capture_with_copy_default, CLASS_ERROR, (unsigned)diag::Severity::Error, "'&' must precede a capture when the capture default is '='", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_covariant_return_ambiguous_derived_to_base_conv, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of virtual function %3 is not covariant with the return type of the function it overrides (ambiguous conversion from derived class %0 to base class %1:%2)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_covariant_return_inaccessible_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid covariant return for virtual function: %1 is a %select{private|protected}2 base class of %0", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(err_covariant_return_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of virtual function %0 is not covariant with the return type of the function it overrides (%1 is incomplete)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_covariant_return_not_derived, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of virtual function %0 is not covariant with the return type of the function it overrides (%1 is not derived from %2)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_covariant_return_type_class_type_more_qualified, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of virtual function %0 is not covariant with the return type of the function it overrides (class type %1 is more qualified than class type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_covariant_return_type_different_qualifications, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of virtual function %0 is not covariant with the return type of the function it overrides (%1 has different qualifiers than %2)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ctor_dtor_returns_void, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{constructor|destructor}1 %0 must not return void expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_cyclic_alias, CLASS_ERROR, (unsigned)diag::Severity::Error, "alias definition is part of a cycle", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decimal_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "GNU decimal type extension not supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decl_negative_array_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as an array with a negative size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_declarator_need_ident, CLASS_ERROR, (unsigned)diag::Severity::Error, "declarator requires an identifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_declspec_thread_on_thread_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "'__declspec(thread)' applied to variable that already has a thread-local storage specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decltype_auto_cannot_be_combined, CLASS_ERROR, (unsigned)diag::Severity::Error, "'decltype(auto)' cannot be combined with other type specifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decltype_auto_compound_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot form %select{pointer to|reference to|array of}0 'decltype(auto)'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decltype_auto_function_declarator_not_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "'decltype(auto)' can only be used as a return type in a function declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decltype_auto_initializer_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce 'decltype(auto)' from initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decltype_in_declarator, CLASS_ERROR, (unsigned)diag::Severity::Error, "'decltype' cannot be used to name a declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_decrement_bool, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot decrement expression of type bool", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deduced_non_type_template_arg_type_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "deduced non-type template argument does not have the same type as the its corresponding template parameter%diff{ ($ vs $)|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deduced_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "deduced return types are a C++1y extension", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deep_exception_specs_differ, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specifications of %select{return|argument}0 types differ", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_default_arg_in_partial_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "default template argument in a class template partial specialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_default_arg_makes_ctor_special, CLASS_ERROR, (unsigned)diag::Severity::Error, "addition of default argument on redeclaration makes this constructor a %select{default|copy|move}0 constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_default_init_const, CLASS_ERROR, (unsigned)diag::Severity::Error, "default initialization of an object of const type %0%select{| requires a user-provided default constructor}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_default_not_in_switch, CLASS_ERROR, (unsigned)diag::Severity::Error, "'default' statement not in switch statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_copy_assign_not_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "the parameter for an explicitly-defaulted copy assignment operator must be an lvalue reference type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_copy_const_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "the parameter for this explicitly-defaulted copy %select{constructor|assignment operator}0 is const, but a member or base requires it to be non-const", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_move_const_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "the parameter for an explicitly-defaulted move %select{constructor|assignment operator}0 may not be const", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_params, CLASS_ERROR, (unsigned)diag::Severity::Error, "an explicitly-defaulted %select{|copy |move }0constructor cannot have default arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_quals, CLASS_ERROR, (unsigned)diag::Severity::Error, "an explicitly-defaulted %select{copy|move}0 assignment operator may not have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicitly-defaulted %select{copy|move}0 assignment operator must return %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_variadic, CLASS_ERROR, (unsigned)diag::Severity::Error, "an explicitly-defaulted %select{|copy |move }0constructor cannot be variadic", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_defaulted_special_member_volatile_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "the parameter for an explicitly-defaulted %select{<<ERROR>>|copy constructor|move constructor|copy assignment operator|move assignment operator|<<ERROR>>}0 may not be volatile", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_definition_of_explicitly_defaulted_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of explicitly defaulted %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_definition_of_implicitly_declared_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of implicitly declared %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor|function}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_delegating_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "delegating constructors are permitted only in C++11", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_delegating_initializer_alone, CLASS_ERROR, (unsigned)diag::Severity::Error, "an initializer for a delegating constructor must appear alone", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_delete_explicit_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "converting delete expression from type %0 to type %1 invokes an explicit conversion function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_delete_incomplete_class_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "deleting incomplete class type %0; no conversions to pointer type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_delete_operand, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot delete expression of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deleted_decl_not_first, CLASS_ERROR, (unsigned)diag::Severity::Error, "deleted definition must be first declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deleted_function_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "attempt to use a deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deleted_main, CLASS_ERROR, (unsigned)diag::Severity::Error, "'main' is not allowed to be deleted", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_deleted_override, CLASS_ERROR, (unsigned)diag::Severity::Error, "deleted function %0 cannot override a non-deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dependent_nested_name_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "nested name specifier for a declaration cannot depend on a template parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dependent_non_type_arg_in_partial_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument depends on a template parameter of the partial specialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dependent_tag_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{declaration|definition}0 of %select{struct|interface|union|class|enum}1 in a dependent scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dependent_typed_non_type_arg_in_partial_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument specializes a template parameter with dependent type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dereference_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "dereference of pointer to incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_designator_for_scalar_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "designator in initializer for scalar type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_designator_into_flexible_array_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "designator into flexible array member subobject", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_cannot_be, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be declared '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_class_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected the class name after '~' to name a destructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_expr_type_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor type %0 in object destruction expression does not match the type %1 of the object being destroyed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected the class name after '~' to name the enclosing class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_not_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor must be a non-static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot have a return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be declared as a template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_typedef_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be declared using a %select{typedef|type alias}1 %0 of the class name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_variadic, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot be variadic", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_destructor_with_params, CLASS_ERROR, (unsigned)diag::Severity::Error, "destructor cannot have any parameters", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_different_language_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %0 has a different language linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_different_return_type_for_overriding_virtual_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "virtual function %0 has a different return type %diff{($) than the function it overrides (which has return type $)|than the function it overrides}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dimension_expr_not_constant_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "dimension expression does not evaluate to a constant unsigned int", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_distant_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specifications are not allowed beyond a single level of indirection", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_double_requires_fp64, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of type 'double' requires cl_khr_fp64 extension to be enabled", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_downcast_from_inaccessible_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast %select{private|protected}2 base class %1 to %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dtor_expr_without_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{destructor reference|pseudo-destructor expression}0 must be called immediately with '()'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dup_implementation_category, CLASS_ERROR, (unsigned)diag::Severity::Error, "reimplementation of category %1 for class %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_dup_implementation_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "reimplementation of class %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_base_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "base class %0 specified more than once as a direct base class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_case, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate case value '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_case_differing_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate case value: '%0' and '%1' both equal '%2'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_class_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate interface definition for class %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_ivar_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable is already declared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_mangled_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition with same mangled name as another definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_method_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate declaration of method %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_duplicate_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "property has a previous declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_early_catch_all, CLASS_ERROR, (unsigned)diag::Severity::Error, "catch-all handler must come last", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ellipsis_first_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "ISO C requires a named parameter before '...'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ellipsis_in_declarator_not_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "only function and template parameters can be parameter packs", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_empty_scalar_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "scalar initializer cannot be empty", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enable_if_never_constant_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "'enable_if' attribute expression never produces a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enum_class_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to %select{|scoped }0enumeration must use 'enum' not 'enum class'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enum_invalid_underlying, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-integral type %0 is an invalid underlying type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enum_redeclare_fixed_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumeration previously declared with %select{non|}0fixed underlying type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enum_redeclare_scoped_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumeration previously declared as %select{un|}0scoped", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enum_redeclare_type_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumeration redeclared with different underlying type %0 (was %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enumerator_does_not_exist, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumerator %0 does not exist in instantiation of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enumerator_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumerator value is not representable in the underlying type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_enumerator_wrapped, CLASS_ERROR, (unsigned)diag::Severity::Error, "enumerator value %0 is not representable in the underlying type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_event_t_addr_space_qual, CLASS_ERROR, (unsigned)diag::Severity::Error, "the event_t type can only be used with __private address space qualifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_event_t_global_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "the event_t type cannot be used to declare a program scope variable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_event_t_struct_field, CLASS_ERROR, (unsigned)diag::Severity::Error, "the event_t type cannot be used to declare a structure or union field", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_exception_spec_in_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specifications are not allowed in %select{typedefs|type aliases}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_exceptions_disabled, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use '%0' with exceptions disabled", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_excess_initializers, CLASS_ERROR, (unsigned)diag::Severity::Error, "excess elements in %select{array|vector|scalar|union|struct}0 initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_excess_initializers_in_char_array_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "excess elements in char array initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_expected_class_or_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a class%select{ or namespace|, namespace, or scoped enumeration}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_expected_kernel_void_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel must have void return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "partial ordering for explicit instantiation of %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_constexpr, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation cannot be 'constexpr'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_data_member_not_instantiated, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation refers to static data member %q0 that is not an instantiation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_declaration_after_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_duplicate, CLASS_ERROR, (unsigned)diag::Severity::Error, "duplicate explicit instantiation of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_in_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %0 in class scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_inline, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation cannot be 'inline'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_member_function_not_instantiated, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation refers to member function %q0 that is not an instantiation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_must_be_global, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %0 must occur at global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_nontemplate_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of non-templated type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_not_known, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %0 does not refer to a function template, variable template, member function, member class, or static data member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_of_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of typedef %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_out_of_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %0 not in a namespace enclosing %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_requires_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation declaration requires a name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_storage_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation cannot have a storage class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_undefined_func_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of undefined function template %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_undefined_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of undefined %select{member class|member function|static data member}0 %1 of class template %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_undefined_var_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of undefined variable template %q0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_unqualified_wrong_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %q0 must occur in namespace %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_instantiation_without_template_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit instantiation of %q0 must specify a template argument list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_non_ctor_or_conv_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'explicit' can only be applied to a constructor or conversion function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_non_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'explicit' can only appear on non-static member functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_out_of_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "'explicit' can only be specified inside the class definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_explicit_specialization_inconsistent_storage_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit specialization has extraneous, inconsistent storage class '%select{none|extern|static|__private_extern__|auto|register}0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_expr_not_cce, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{case value|enumerator value|non-type template argument|array size}0 is not a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_expr_not_ice, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression is not an %select{integer|integral}0 constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ext_vector_component_exceeds_length, CLASS_ERROR, (unsigned)diag::Severity::Error, "vector component access exceeds type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ext_vector_component_name_illegal, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal vector component name '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_extern_c_global_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %1 %select{with C language linkage|in global scope}0 conflicts with declaration %select{in global scope|with C language linkage}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_extern_non_extern, CLASS_ERROR, (unsigned)diag::Severity::Error, "extern declaration of %0 follows non-extern declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_falloff_nonvoid_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "control reaches end of non-void block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_fallthrough_attr_outside_switch, CLASS_ERROR, (unsigned)diag::Severity::Error, "fallthrough annotation is outside switch statement", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_fallthrough_attr_wrong_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "clang::fallthrough attribute is only allowed on empty statements", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_declared_as_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "field %0 declared as a function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_designator_non_aggr, CLASS_ERROR, (unsigned)diag::Severity::Error, "field designator cannot initialize a %select{non-struct, non-union|non-class}0 type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_designator_nonfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "field designator %0 does not refer to a non-static data member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_designator_unknown, CLASS_ERROR, (unsigned)diag::Severity::Error, "field designator %0 does not refer to any field in type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_designator_unknown_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "field designator %0 does not refer to any field in type %1; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "field has incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_instantiates_to_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "data member instantiated with function type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_field_with_address_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "field may not be qualified with an address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_filter_expression_integral, CLASS_ERROR, (unsigned)diag::Severity::Error, "filter expression type should be an integral value not %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_final_function_overridden, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %0 overrides a '%select{final|sealed}1' function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_first_argument_to_va_arg_not_of_type_va_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "first argument to 'va_arg' is of type %0 and not 'va_list'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_empty_aggregate, CLASS_ERROR, (unsigned)diag::Severity::Error, "flexible array member %0 not allowed in otherwise empty %select{struct|interface|union|class|enum}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_has_nontrivial_dtor, CLASS_ERROR, (unsigned)diag::Severity::Error, "flexible array member %0 of type %1 with non-trivial destruction", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "initialization of flexible array member is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_init_needs_braces, CLASS_ERROR, (unsigned)diag::Severity::Error, "flexible array requires brace-enclosed initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_union, CLASS_ERROR, (unsigned)diag::Severity::Error, "flexible array member %0 in a union is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_flexible_array_virtual_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "flexible array member %0 not allowed in %select{struct|interface|union|class|enum}1 which has a virtual base class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_begin_end_types_differ, CLASS_ERROR, (unsigned)diag::Severity::Error, "'begin' and 'end' must return the same type (got %0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_decl_must_be_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "for range declaration must declare a variable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use type %0 as a range", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_dereference, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid range expression of type %0; did you mean to dereference it with '*'?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use incomplete type %0 as a range", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_invalid, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid range expression of type %0; no viable '%select{begin|end}1' function available", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_iter_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use type %0 as an iterator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_member_begin_end_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_for_range_storage_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "loop variable %0 may not be declared %select{'extern'|'static'|'__private_extern__'|'auto'|'register'|'constexpr'}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_format_attribute_implicit_this_format_string, CLASS_ERROR, (unsigned)diag::Severity::Error, "format attribute cannot specify the implicit this argument as the format string", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_format_attribute_not, CLASS_ERROR, (unsigned)diag::Severity::Error, "format argument not %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_format_attribute_requires_variadic, CLASS_ERROR, (unsigned)diag::Severity::Error, "format attribute requires variadic function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_format_attribute_result_not, CLASS_ERROR, (unsigned)diag::Severity::Error, "function does not return %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_format_strftime_third_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "strftime format attribute requires 3rd parameter to be 0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_forward_ref_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "ISO C++ forbids forward references to 'enum' types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_forward_superclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "attempting to use the forward class %0 as superclass of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_decl_does_not_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend declaration of %0 does not match any declaration in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_decl_with_def_arg_must_be_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend declaration specifying a default argument must be a definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_decl_with_def_arg_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend declaration specifying a default argument must be the only declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_def_in_local_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend function cannot be defined in a local class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_is_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "friends cannot be members of the declaring class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_friend_not_first_in_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "'friend' must appear first in a non-function declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_func_def_incomplete_result, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete result type %0 in function definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_func_returning_array_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "function cannot return %select{array|function}0 type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_marked_override_not_overriding, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 marked 'override' but does not override any member functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_parameter_pack_without_parameter_packs, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 of function parameter pack does not contain any unexpanded parameter packs", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_specialization_in_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specialize a function %0 within class scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_template_partial_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "function template partial specialization is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_template_spec_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "function template specialization %0 ambiguously refers to more than one function template; explicitly specify%select{| additional}1 template arguments to identify a particular function template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_function_template_spec_no_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "no function template matches function template specialization %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_gc_weak_property_strong_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "weak attribute declared on a __strong type property in GC mode", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_generic_sel_multi_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "controlling expression type %0 compatible with %1 generic association types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_generic_sel_no_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "controlling expression type %0 not compatible with any generic association type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_getter_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "no getter method for read from property", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_global_call_not_config, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to global function %0 not configured", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_goto_into_protected_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "goto into protected scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_iboutletcollection_builtintype, CLASS_ERROR, (unsigned)diag::Severity::Error, "type argument of iboutletcollection attribute cannot be a builtin type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_iboutletcollection_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid type %0 as argument of iboutletcollection attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ice_ambiguous_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion from type %0 to an integral or unscoped enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ice_explicit_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "integral constant expression requires explicit conversion from %0 to %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ice_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "integral constant expression has incomplete class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ice_not_integral, CLASS_ERROR, (unsigned)diag::Severity::Error, "integral constant expression must have integral or unscoped enumeration type, not %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ident_in_dtor_not_a_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "identifier %0 in object destruction expression does not name a type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ident_list_in_fn_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "a parameter list without types is only allowed in a function definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_container_subscripting_op, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal operation on Objective-C container subscripting", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_array_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "array has incomplete element type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_array_of_auto, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as array of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_array_of_functions, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as array of functions of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_array_of_references, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as array of references of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_mempointer_in_nonclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' does not point into a class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_mempointer_to_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as a member pointer to a reference of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_mempointer_to_void, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as a member pointer to void", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_decl_pointer_to_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' declared as a pointer to a reference of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal initializer (only variables can be initialized)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_initializer_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal initializer type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_message_expr_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "Objective-C message has incomplete result type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_qualifiers_on_catch_parm, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal qualifiers on @catch parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_illegal_union_or_anon_struct_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{anonymous struct|union}0 member %1 has a non-trivial %select{constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_imaginary_not_supported, CLASS_ERROR, (unsigned)diag::Severity::Error, "imaginary types are not supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_implicit_empty_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer for aggregate with no elements requires explicit braces", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_implicit_instantiate_member_undefined, CLASS_ERROR, (unsigned)diag::Severity::Error, "implicit instantiation of undefined member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_implicit_object_parameter_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot initialize object parameter of type %0 with an expression of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_implied_std_initializer_list_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce type of initializer list because std::initializer_list was not found; include <initializer_list>", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_bad_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "static data member of type %0 must be initialized out of line", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_literal_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "in-class initializer for static data member of type %0 requires 'constexpr' specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_non_const, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-const static data member must be initialized out of line", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_non_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "in-class initializer for static data member is not a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_references_def_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "defaulted default constructor of %0 cannot be used by non-static data member initializer which appears before end of class definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_in_class_initializer_volatile, CLASS_ERROR, (unsigned)diag::Severity::Error, "static const volatile data member must be initialized out of line", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incompatible_exception_specs, CLASS_ERROR, (unsigned)diag::Severity::Error, "target exception specification is not superset of source", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_base_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "base class has incomplete type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_in_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|pointer to |reference to }0incomplete type %1 is not allowed in exception specification", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_member_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "member access into incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_nested_name_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type %0 named in nested name specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_object_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type in call to object of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_receiver_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete receiver type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_synthesized_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot synthesize property %0 with incomplete type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type %0 where a complete type is required", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_type_objc_at_encode, CLASS_ERROR, (unsigned)diag::Severity::Error, "'@encode' of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_type_used_in_type_trait_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type %0 used in type trait expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incomplete_typeid, CLASS_ERROR, (unsigned)diag::Severity::Error, "'typeid' of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inconsistent_ivar_count, CLASS_ERROR, (unsigned)diag::Severity::Error, "inconsistent number of instance variables specified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incorrect_defaulted_constexpr, CLASS_ERROR, (unsigned)diag::Severity::Error, "defaulted definition of %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator}0 is not constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incorrect_defaulted_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specification of explicitly defaulted %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0 does not match the calculated one", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_incorrect_number_of_vector_initializers, CLASS_ERROR, (unsigned)diag::Severity::Error, "number of elements must be either one or match the size of the vector", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_increment_decrement_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot %select{decrement|increment}0 expression of enum type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_indirect_goto_in_protected_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "indirect goto might cross protected scopes", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_indirect_goto_without_addrlabel, CLASS_ERROR, (unsigned)diag::Severity::Error, "indirect goto in function with no address-of-label expressions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_capture_deduction_failure, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce type for lambda capture %0 from initializer of type %2", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_init_capture_deduction_failure_from_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce type for lambda capture %0 from initializer list", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_init_capture_multiple_expressions, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer for lambda capture %0 contains multiple expressions", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_init_capture_no_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer missing for lambda capture %0", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_init_capture_paren_braces, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce type for lambda capture %0 from parenthesized initializer list", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_init_conversion_failed, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot initialize %select{a variable|a parameter|return object|an exception object|a member subobject|an array element|a new value|a value|a base class|a constructor delegation|a vector element|a block element|a complex element|a lambda capture|a compound literal initializer|a related result|a parameter of CF audited function}0 %diff{of type $ with an %select{rvalue|lvalue}2 of type $|with an %select{rvalue|lvalue}2 of incompatible type}1,3%select{|: different classes%diff{ ($ vs $)|}5,6|: different number of parameters (%5 vs %6)|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7|: different return type%diff{ ($ vs $)|}5,6|: different qualifiers (%select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}5 vs %select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}6)}4", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_element_not_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer element is not a compile-time constant", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "initialization of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_list_bad_dest_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|non-aggregate }0type %1 cannot be initialized with an initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_method_bad_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "init methods must return an object pointer type, not %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_non_aggr_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "initialization of non-aggregate type %0 with an initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_objc_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot initialize Objective-C class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_priority_object_attr, CLASS_ERROR, (unsigned)diag::Severity::Error, "can only use 'init_priority' attribute on file-scope definitions of objects of class type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_init_reference_member_uninitialized, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference member of type %0 uninitialized", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_initializer_string_for_char_array_too_long, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer-string for char array is too long", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inline_decl_follows_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "inline declaration of %0 follows non-inline definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inline_declaration_block_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "inline declaration of %0 not allowed in block scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inline_main, CLASS_ERROR, (unsigned)diag::Severity::Error, "'main' is not allowed to be declared inline", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inline_namespace_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|non-}0inline namespace cannot be reopened as %select{non-|}0inline", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_inline_non_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'inline' can only appear on functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_int128_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "__int128 is not supported on this target", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_int_to_block_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid block pointer conversion %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_introducing_special_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "must use a qualified name when declaring a %select{constructor|destructor|conversion operator}0 as a friend", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_asm_cast_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of a cast in a inline asm context requiring an l-value: remove the cast or build with -fheinous-gnu-extensions", 0, SFINAE_SubstitutionFailure, false, true, 11)
+DIAG(err_invalid_astype_of_different_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid reinterpretation: sizes of %0 and %1 must match", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_base_in_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "interface type cannot inherit from %select{'struct|non-public 'interface|'class}0 %1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_collection_element, CLASS_ERROR, (unsigned)diag::Severity::Error, "collection element of type %0 is not an Objective-C object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_constexpr, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{function parameter|typedef|non-static data member}0 cannot be constexpr", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_constexpr_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-static data member cannot be constexpr%select{; did you intend to make it %select{const|static}0?|}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_constexpr_var_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "constexpr variable declaration must be a definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_conversion_between_ext_vectors, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid conversion between ext-vector type %0 and %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_conversion_between_vector_and_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid conversion between vector type %0 and integer type %1 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_conversion_between_vector_and_scalar, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid conversion between vector type %0 and scalar type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_conversion_between_vectors, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid conversion between vector type%diff{ $ and $|}0,1 of different size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_declarator_global_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition or redeclaration of %0 cannot name the global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_declarator_in_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition or redeclaration of %0 not allowed inside a block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_declarator_in_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition or redeclaration of %0 not allowed inside a function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_declarator_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot define or redeclare %0 here because namespace %1 does not enclose namespace %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_form_pointer_member_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot create a non-constant pointer to member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_incomplete_type_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_member_in_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{data member |non-public member function |static member function |user-declared constructor|user-declared destructor|operator |nested class }0%1 is not permitted within an interface type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_member_use_in_static_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of member %0 in static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_neon_type_code, CLASS_ERROR, (unsigned)diag::Severity::Error, "incompatible constant for this __builtin_neon function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_non_static_member_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of non-static data member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_nsnumber_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a valid literal type for NSNumber", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_pcs, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid PCS type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_property_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a valid property name (accessing an object of type %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_protocol_qualifiers, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid protocol qualifiers on non-ObjC type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_qualified_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' qualifier is not allowed on a constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_qualified_destructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' qualifier is not allowed on a destructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_qualified_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{static |non-}0member function %select{of type %2 |}1cannot have '%3' qualifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_receiver_class_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "receiver type %0 is not an Objective-C class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_receiver_to_message_super, CLASS_ERROR, (unsigned)diag::Severity::Error, "'super' is only valid in a method body", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_this_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of 'this' outside of a non-static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_thread, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' is only allowed on variable declarations", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_use_of_array_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "an array type is not allowed here", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_use_of_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a function type is not allowed here", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_invalid_var_template_spec_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %2 of %select{explicit instantiation|explicit specialization|partial specialization|redeclaration}0 of %1 does not match expected type %3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ivar_access_using_property_syntax_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 not found on object of type %1; did you mean to access instance variable %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ivar_reference_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variables cannot be of reference type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_kern_call_not_global_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel call to non-global function %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_kern_type_not_void_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel function type %0 must have void return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lambda_capture_anonymous_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "unnamed variable cannot be implicitly captured in a lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_capture_default_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "lambda expression in default argument cannot capture any entity", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_capture_flexarray_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 with flexible array member cannot be captured in a lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_capture_vm_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 with variably modified type cannot be captured in a lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_decl_ref_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot assign to a variable captured by copy in a non-mutable lambda", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lambda_impcap, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 cannot be implicitly captured in a lambda with no capture-default specified", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_in_constant_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "a lambda expression may not appear inside of a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_incomplete_result, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete result type %0 in lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_return_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot deduce lambda return type from initializer list", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_lambda_unevaluated_operand, CLASS_ERROR, (unsigned)diag::Severity::Error, "lambda expression in an unevaluated operand", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_language_linkage_spec_not_ascii, CLASS_ERROR, (unsigned)diag::Severity::Error, "string literal in language linkage specifier cannot have an encoding-prefix", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_language_linkage_spec_unknown, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown linkage language", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_literal_operator_default_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "literal operator cannot have a default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_literal_operator_extern_c, CLASS_ERROR, (unsigned)diag::Severity::Error, "literal operator must have C++ linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_literal_operator_id_outside_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-namespace scope '%0' cannot have a literal operator member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_literal_operator_outside_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "literal operator %0 must be in a namespace or global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_literal_operator_params, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter declaration for literal operator %0 is not valid", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_local_cant_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "'__local' variable cannot have an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lvalue_reference_bind_to_initlist, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to an initializer list temporary", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lvalue_reference_bind_to_temporary, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-const|volatile}0 lvalue reference %diff{to type $ cannot bind to a temporary of type $|cannot bind to incompatible temporary}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lvalue_reference_bind_to_unrelated, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-const|volatile}0 lvalue reference %diff{to type $ cannot bind to a value of unrelated type $|cannot bind to a value of unrelated type}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_lvalue_to_rvalue_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "rvalue reference %diff{to type $ cannot bind to lvalue of type $|cannot bind to incompatible lvalue}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_machine_mode, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{unknown|unsupported}0 machine mode %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_main_arg_wrong, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{first|second|third|fourth}0 parameter of 'main' (%select{argument count|argument array|environment|platform-specific data}0) must be of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_main_returns_nonint, CLASS_ERROR, (unsigned)diag::Severity::Error, "'main' must return 'int'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_main_surplus_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many parameters (%0) for 'main': must be 0, 2, or 3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mainlike_template_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be a template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_malformed_std_initializer_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "std::initializer_list must be a class template with a single type parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_maybe_falloff_nonvoid_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "control may reach end of non-void block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mem_init_not_member_or_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "member initializer %0 does not name a non-static data member or base class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mem_init_not_member_or_class_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer %0 does not name a non-static data member or base class; did you mean the %select{base class|member}1 %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_call_without_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to non-static member function without an object argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_decl_does_not_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "out-of-line %select{declaration|definition}2 of %0 does not match any declaration in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_decl_does_not_match_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "out-of-line %select{declaration|definition}2 of %0 does not match any declaration in %1; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_def_does_not_match_ret_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "return type of out-of-line definition of %q0 differs from that in the declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_def_undefined_record, CLASS_ERROR, (unsigned)diag::Severity::Error, "out-of-line definition of %0 from class %1 without definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_extra_qualification, CLASS_ERROR, (unsigned)diag::Severity::Error, "extra qualification on member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_function_call_bad_cvr, CLASS_ERROR, (unsigned)diag::Severity::Error, "member function %0 not viable: 'this' argument has type %1, but function is not marked %select{const|restrict|const or restrict|volatile|const or volatile|volatile or restrict|const, volatile, or restrict}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_function_initialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer on function does not look like a pure-specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_name_of_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "member %0 has the same name as its class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_not_yet_instantiated, CLASS_ERROR, (unsigned)diag::Severity::Error, "no member %0 in %1; it has not yet been instantiated", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_qualification, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-friend class member %0 cannot have a qualified name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "class member cannot be redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_redeclared_in_instantiation, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple overloads of %0 instantiate to the same signature %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_member_reference_needs_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "base of member reference is a function; perhaps you meant to call it%select{| with no arguments}0?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mempointer_in_nonclass_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "member pointer refers into non-class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_memptr_conv_via_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion from pointer to member of class %0 to pointer to member of class %1 via virtual base %2 is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mismatched_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specification in declaration does not match previous declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mismatched_ms_inheritance, CLASS_ERROR, (unsigned)diag::Severity::Error, "inheritance model does not match %select{definition|previous declaration}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mismatched_visibility, CLASS_ERROR, (unsigned)diag::Severity::Error, "visibility does not match previous declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_misplaced_ivar, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variables may not be placed in %select{categories|class extension}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_missing_atsign_prefix, CLASS_ERROR, (unsigned)diag::Severity::Error, "string literal must be prefixed by '@' ", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_missing_default_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|implicit default |inheriting }0constructor for %1 must explicitly initialize the %select{base class|member}2 %3 which does not have a default constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_missing_open_square_message_send, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing '[' at start of message send expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_missing_type_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "C++ requires a type specifier for all declarations", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mode_not_primitive, CLASS_ERROR, (unsigned)diag::Severity::Error, "mode attribute only supported for integer and floating-point types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mode_wrong_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of machine mode does not match type of base type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_module_import_in_extern_c, CLASS_ERROR, (unsigned)diag::Severity::Error, "import of C++ module '%0' appears within extern \"C\" language linkage specification", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_import_not_at_top_level, CLASS_ERROR, (unsigned)diag::Severity::Error, "import of module '%0' appears within %1", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_private_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %0 must be imported from module '%1' before it is required", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_private_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of %0 must be imported from module '%1' before it is required", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_private_local, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{local variable|parameter|typedef}0 %1 cannot be declared __module_private__", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_private_local_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "local %select{struct|interface|union|class|enum}0 cannot be declared __module_private__", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_private_specialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{template|partial|member}0 specialization cannot be declared __module_private__", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_module_self_import, CLASS_ERROR, (unsigned)diag::Severity::Error, "import of module '%0' appears within same top-level module '%1'", 0, SFINAE_SubstitutionFailure, false, true, 14)
+DIAG(err_ms___leave_not_in___try, CLASS_ERROR, (unsigned)diag::Severity::Error, "'__leave' statement not in __try block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_multiple_base_initialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple initializations given for base %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_multiple_default_labels_defined, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple default labels in one switch", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_multiple_final_overriders, CLASS_ERROR, (unsigned)diag::Severity::Error, "virtual function %q0 has more than one final overrider in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_multiple_mem_initialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple initializations given for non-static member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_multiple_mem_union_initialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializing multiple members of union", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mutable_const, CLASS_ERROR, (unsigned)diag::Severity::Error, "'mutable' and 'const' cannot be mixed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mutable_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'mutable' cannot be applied to functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mutable_nonmember, CLASS_ERROR, (unsigned)diag::Severity::Error, "'mutable' can only be applied to member variables", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_mutable_reference, CLASS_ERROR, (unsigned)diag::Severity::Error, "'mutable' cannot be applied to references", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_need_header_before_ms_uuidof, CLASS_ERROR, (unsigned)diag::Severity::Error, "you need to include <guiddef.h> before using the '__uuidof' operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_need_header_before_typeid, CLASS_ERROR, (unsigned)diag::Severity::Error, "you need to include <typeinfo> before using the 'typeid' operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nested_name_member_ref_lookup_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "lookup of %0 in member access expression is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nested_name_spec_is_not_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot appear before '::' because it is not a class%select{ or namespace|, namespace, or scoped enumeration}1; did you mean ':'?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nested_name_spec_non_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 cannot be used prior to '::' because it has no members", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nested_non_static_member_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{call to non-static member function|use of non-static data member}0 %2 of %1 from nested type %3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nested_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "nested redefinition of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_new_array_init_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "array 'new' cannot have initialization arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_new_array_nonconst, CLASS_ERROR, (unsigned)diag::Severity::Error, "only the first dimension of an allocated array may have dynamic size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_new_array_of_auto, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot allocate array of 'auto'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_new_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "allocation of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_accessor_for_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "no %select{getter|setter}0 defined for property %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_dynamic_cast_with_fno_rtti, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use dynamic_cast with -fno-rtti", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_matching_local_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching function found in local scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_matching_local_friend_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching function %0 found in local scope; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "no member named %0 in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_member_overloaded_arrow, CLASS_ERROR, (unsigned)diag::Severity::Error, "no member named %0 in %1; did you mean to use '->' instead of '.'?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_member_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no member named %0 in %1; did you mean %select{|simply }2%3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_member_template_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no template named %0 in %1; did you mean %select{|simply }2%3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_nsconstant_string_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find interface declaration for %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_suitable_delete_member_function_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "no suitable member %0 in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_template_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no template named %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_no_typeid_with_fno_rtti, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use typeid with -fno-rtti", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_noexcept_needs_constant_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to noexcept specifier must be a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nogetter_property_compound_assignment, CLASS_ERROR, (unsigned)diag::Severity::Error, "a getter method is needed to perform a compound assignment on a property", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nogetter_property_incdec, CLASS_ERROR, (unsigned)diag::Severity::Error, "no getter method %1 for %select{increment|decrement}0 of property", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_deleted_override, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-deleted function %0 cannot override a deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_extern_extern, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-extern declaration of %0 follows extern declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_local_variable_decl_in_for, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of non-local variable in 'for' loop", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_static_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-static declaration of %0 follows static declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_thread_thread, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-thread-local declaration of %0 follows thread-local declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_type_template_in_nested_name_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "qualified name refers into a specialization of %select{function|variable}0 template %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_variable_decl_in_for, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-variable declaration in 'for' loop", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_non_virtual_pure, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not virtual and cannot be declared pure", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nonfunction_block_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "block pointer to non-function type is invalid", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nonstatic_member_out_of_line, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-static data member defined out-of-line", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_noreturn_block_has_return_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "block declared 'noreturn' should not return", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_noreturn_lambda_has_return_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "lambda declared 'noreturn' should not return", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_noreturn_missing_on_first_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declared '[[noreturn]]' after its first declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_noreturn_non_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'_Noreturn' can only appear on functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nosetter_property_assignment, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{assignment to readonly property|no setter method %1 for assignment to property}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nosetter_property_incdec, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{%select{increment|decrement}1 of readonly property|no setter method %2 for %select{increment|decrement}1 of property}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_class_template_specialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specialize a %select{dependent template|template template parameter}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_direct_base_or_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 is not a direct or virtual base of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_found_by_two_phase_lookup, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to function %0 that is neither visible in the template definition nor found by argument-dependent lookup", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_integral_type_anon_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "anonymous bit-field has non-integral type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_integral_type_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "bit-field %0 has non-integral type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_not_tag_in_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "no %select{struct|interface|union|class|enum}0 named %1 in %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nsconsumed_attribute_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "overriding method has mismatched ns_consumed attribute on its parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nsobject_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "'NSObject' attribute is for pointer types only", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_nsreturns_retained_attribute_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "overriding method has mismatched ns_returns_%select{not_retained|retained}0 attributes", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_array_of_interfaces, CLASS_ERROR, (unsigned)diag::Severity::Error, "array of interface %0 is invalid (probably should be an array of pointers)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_attr_not_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_attr_protocol_requires_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %0 can only be applied to @protocol definitions, not forward declarations", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_bridged_related_invalid_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "could not find Objective-C class %0 to convert %1 to %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_bridged_related_invalid_class_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must be name of an Objective-C class to be able to convert %1 to %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_bridged_related_known_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 method for this conversion", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_cf_bridged_not_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "CF object of type %0 is bridged to %1, which is not an Objective-C class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_decls_may_only_appear_in_global_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "Objective-C declarations may only appear in global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_exceptions_disabled, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot use '%0' with Objective-C exceptions disabled", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_illegal_boxed_expression_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal type %0 used in a boxed expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_incomplete_boxed_expression_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type %0 used in a boxed expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_index_incomplete_class_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "Objective-C index expression has incomplete class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_indexing_method_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "method for accessing %select{dictionary|array}1 element must have Objective-C object return type instead of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_literal_method_sig, CLASS_ERROR, (unsigned)diag::Severity::Error, "literal construction method %0 has incompatible signature", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_multiple_subscript_type_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "indexing expression is invalid because subscript type %0 has multiple type conversion functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_ns_bridged_invalid_cfobject, CLASS_ERROR, (unsigned)diag::Severity::Error, "ObjectiveC object of type %0 is bridged to %1, which is not valid CF object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_object_assignment, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot assign to class object (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_object_catch, CLASS_ERROR, (unsigned)diag::Severity::Error, "can't catch an Objective-C object by value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_precise_lifetime_bad_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "objc_precise_lifetime only applies to retainable types; type here is %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_property_attr_mutually_exclusive, CLASS_ERROR, (unsigned)diag::Severity::Error, "property attributes '%0' and '%1' are mutually exclusive", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_property_requires_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "property with '%0' attribute must be of object type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_root_class_subclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "objc_root_class attribute may only be specified on a root class declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_base_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{dictionary|array}1 subscript base type %0 is not an Objective-C object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_dic_object_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "method object parameter type %0 is not object type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_index_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "method index parameter type %0 is not integral type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_key_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "method key parameter type %0 is not object type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_method_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected method to %select{read|write}1 %select{dictionary|array}2 element not found on object of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_object_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot assign to this %select{dictionary|array}1 because assigning method's 2nd parameter of type %0 is not an Objective-C pointer type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "indexing expression is invalid because subscript type %0 is not an Objective-C pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_subscript_type_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "indexing expression is invalid because subscript type %0 is not an integral or Objective-C pointer type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_objc_var_decl_inclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot declare variable inside @interface or @protocol", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_object_cannot_be_passed_returned_by_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "interface type %1 cannot be %select{returned|passed}0 by value; did you forget * in %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_offsetof_array_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "offsetof requires array type, %0 invalid", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_offsetof_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot compute offset of bit-field %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_offsetof_field_of_virtual_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of 'offsetof' to a field of a virtual base", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_offsetof_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "offsetof of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_offsetof_record_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "offsetof requires struct, union, or class type, %0 invalid", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_omp_aligned_expected_array_or_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument of aligned clause should be array%select{ or pointer|, pointer, reference to array or reference to pointer}1, not %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_aligned_twice, CLASS_ERROR, (unsigned)diag::Severity::Error, "a variable cannot appear in more than one aligned clause", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_ambiguous_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion from type %0 to an integral or unscoped enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_clause_floating_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_clause_not_arithmetic_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of %select{scalar|arithmetic}0 type", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_clause_ref_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "arguments of OpenMP clause '%0' cannot be of reference type %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_const_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "const-qualified variable cannot be %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_expected_var_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a global variable, static local variable or static data member", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_expected_var_arg_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a global variable, static local variable or static data member; did you mean %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_expected_var_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected variable name", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_explicit_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression requires explicit conversion from %0 to %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_firstprivate_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a firstprivate variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_global_var_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression has incomplete class type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_lastprivate_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a lastprivate variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_linear_expected_int_or_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument of a linear clause should be of integral or pointer type, not %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_linear_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a linear variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_local_var_in_threadprivate_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable with local storage in initial value of threadprivate variable", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_cannot_use_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' statement cannot be used in OpenMP for loop", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_incr_not_compatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "increment expression must cause %0 to %select{decrease|increase}1 on each iteration of OpenMP for loop", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_not_canonical_cond, CLASS_ERROR, (unsigned)diag::Severity::Error, "condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_not_canonical_incr, CLASS_ERROR, (unsigned)diag::Severity::Error, "increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_not_canonical_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_var_dsa, CLASS_ERROR, (unsigned)diag::Severity::Error, "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_loop_variable_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable must be of integer or %select{pointer|random access iterator}0 type", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_negative_expression_in_clause, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument to '%0' clause must be a positive integer value", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_no_dsa_for_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 must have explicitly specified data sharing attributes", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_not_for, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{statement after '#pragma omp %1' must be a for loop|expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_not_integral, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression must have integral or unscoped enumeration type, not %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_once_referenced, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable can appear only once in OpenMP '%0' clause", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_orphaned_section_directive, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{orphaned 'omp section' directives are prohibited, it|'omp section' directive}0 must be closely nested to a sections region%select{|, not a %1 region}0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_parallel_reduction_in_task_firstprivate, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument of a reduction clause of a %0 construct must not appear in a firstprivate clause on a task construct", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_parallel_sections_not_compound_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "the statement for '#pragma omp parallel sections' must be a compound statement", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_parallel_sections_substmt_not_section, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement in 'omp parallel sections' directive must be enclosed into a section region", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_private_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a private variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_prohibited_region, CLASS_ERROR, (unsigned)diag::Severity::Error, "region cannot be%select{| closely}0 nested inside '%1' region%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_prohibited_region_critical_same_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot nest 'critical' regions having the same name %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_prohibited_region_simd, CLASS_ERROR, (unsigned)diag::Severity::Error, "OpenMP constructs may not be nested inside a simd region", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_reduction_id_not_compatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable of type %0 is not valid for specified reduction operation", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_reduction_in_task, CLASS_ERROR, (unsigned)diag::Severity::Error, "reduction variables may not be accessed in an explicit task", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_reduction_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a reduction variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_reduction_ref_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument of OpenMP clause 'reduction' must reference the same object in all threads", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_reduction_type_array, CLASS_ERROR, (unsigned)diag::Severity::Error, "a reduction variable with array type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_ref_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "arguments of '#pragma omp %0' cannot be of reference type %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_required_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 variable must be %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_required_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_sections_not_compound_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "the statement for '#pragma omp sections' must be a compound statement", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_sections_substmt_not_section, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement in 'omp sections' directive must be enclosed into a section region", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_simd_region_cannot_use_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' statement cannot be used in OpenMP simd region", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_task_predetermined_firstprivate_ref_type_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "predetermined as a firstprivate in a task construct variable cannot be of reference type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_task_predetermined_firstprivate_required_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous %select{copy constructor|destructor}0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_threadprivate_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "threadprivate variable with incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_unexpected_clause_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected %0 in OpenMP clause '%1'", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_unknown_reduction_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_var_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#pragma omp %0' must appear in the scope of the %q1 variable declaration", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_var_thread_local, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 cannot be threadprivate because it is thread-local", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_var_used, CLASS_ERROR, (unsigned)diag::Severity::Error, "'#pragma omp %0' must precede all references to variable %q1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_omp_wrong_dsa, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 variable cannot be %1", 0, SFINAE_SubstitutionFailure, false, true, 15)
+DIAG(err_only_annotate_after_access_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "access specifier can only have annotation attributes", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_only_constructors_take_base_inits, CLASS_ERROR, (unsigned)diag::Severity::Error, "only constructors take base initializers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_only_enums_have_underlying_types, CLASS_ERROR, (unsigned)diag::Severity::Error, "only enumeration types have underlying types", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_bitfields, CLASS_ERROR, (unsigned)diag::Severity::Error, "bitfields are not supported in OpenCL", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_cast_to_half, CLASS_ERROR, (unsigned)diag::Severity::Error, "casting to type %0 is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_constant_no_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable in constant address space must be initialized", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_function_pointer_variable, CLASS_ERROR, (unsigned)diag::Severity::Error, "pointers to functions are not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_global_invalid_addr_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "global variables must have a constant address space qualifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_half_declaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaring variable of type %0 is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_half_load_store, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{loading directly from|assigning directly to}0 pointer to type %1 is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_half_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaring function parameter of type %0 is not allowed; did you forget * ?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_half_return, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaring function return value of type %0 is not allowed; did you forget * ?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_kernel_attr, CLASS_ERROR, (unsigned)diag::Severity::Error, "attribute %0 can only be applied to a kernel function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_no_main, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{function|kernel}0 cannot be called 'main'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_private_ptr_kernel_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel parameter cannot be declared as a pointer to the __private address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_ptrptr_kernel_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel parameter cannot be declared as a pointer to a pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_return_value_with_address_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "return value cannot be qualified with address space", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_sizeof_alignof_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of '%select{sizeof|alignof|vec_step}0' to a void type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_taking_function_address, CLASS_ERROR, (unsigned)diag::Severity::Error, "taking address of function is not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_opencl_vla, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length arrays are not supported in OpenCL", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_arrow_circular, CLASS_ERROR, (unsigned)diag::Severity::Error, "circular pointer delegation detected", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_arrow_depth_exceeded, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of 'operator->' on type %0 would invoke a sequence of more than %1 'operator->' calls", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_delete_dependent_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot take a dependent type as first parameter; use %1 instead", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_delete_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "first parameter of %0 must have type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_default_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter of %0 cannot have a default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_declared_in_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be declared inside a namespace", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_declared_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be declared static in global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_dependent_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot have a dependent return type; use %1 instead", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_invalid_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must return type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_template_too_few_parameters, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 template must have at least two parameters", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_delete_too_few_parameters, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 must have at least one parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_dependent_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot take a dependent type as first parameter; use size_t (%1) instead", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_new_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 takes type size_t (%1) as first parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_default_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter of overloaded %0 cannot have a default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_must_be, CLASS_ERROR, (unsigned)diag::Severity::Error, "overloaded %0 must be a %select{unary|binary|unary or binary}2 operator (has %1 parameter%s1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_must_be_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "overloaded %0 must be a non-static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_needs_class_or_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "overloaded %0 must have at least one parameter of class or enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_post_incdec_must_be_int, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter of overloaded post-%select{increment|decrement}1 operator must have type 'int' (not %0)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "overloaded %0 cannot be a static member function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_operator_overload_variadic, CLASS_ERROR, (unsigned)diag::Severity::Error, "overloaded %0 cannot be variadic", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_out_of_line_default_deletes, CLASS_ERROR, (unsigned)diag::Severity::Error, "defaulting this %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0 would delete it after its first declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_override_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception specification of overriding function is more lax than base version", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_conversion_in_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous conversion for %select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to constructor of %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_member_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to member function %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_object_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to object of type %0 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_oper_binary, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of overloaded operator '%0' is ambiguous (with operand types %1 and %2)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_ambiguous_oper_unary, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of overloaded operator '%0' is ambiguous (operand type %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to %select{unavailable|deleted}0 function %1%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_conversion_in_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2 uses deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to %select{unavailable|deleted}0 constructor of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_member_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to %select{unavailable|deleted}0 member function %1%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_object_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to %select{unavailable|deleted}0 function call operator in type %1%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_oper, CLASS_ERROR, (unsigned)diag::Severity::Error, "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_special_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to implicitly-deleted %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor|function}0 of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_deleted_special_oper, CLASS_ERROR, (unsigned)diag::Severity::Error, "object of type %0 cannot be %select{constructed|copied|moved|assigned|assigned|destroyed}1 because its %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}1 is implicitly deleted", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_diff_return_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "functions that differ only in their return type cannot be overloaded", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_conversion_in_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot convert %1 to %2 without a conversion operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_oper, CLASS_ERROR, (unsigned)diag::Severity::Error, "type %0 does not provide a %select{subscript|call}1 operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_conversion_in_cast, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching conversion for %select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_function_in_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching function for call to %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_function_in_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching constructor for initialization of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_literal_operator, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching literal operator for call to %0%select{| with argument of type %2| with arguments of types %2 and %3}1%select{| or 'const char *'}4%select{|, and no matching literal operator template}5", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_member_function_in_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching member function for call to %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_object_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "no matching function for call to object of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_oper, CLASS_ERROR, (unsigned)diag::Severity::Error, "no viable overloaded '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_no_viable_subscript, CLASS_ERROR, (unsigned)diag::Severity::Error, "no viable overloaded operator[] for type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_static_nonstatic_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "static and non-static member functions with the same parameter types cannot be overloaded", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ovl_unresolvable, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to overloaded function could not be resolved; did you mean to call it%select{| with no arguments}0?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ownership_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute only applies to %select{pointer|integer}1 arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pack_expansion_length_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "pack expansion contains parameter packs %0 and %1 that have different lengths (%2 vs. %3)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pack_expansion_length_conflict_multilevel, CLASS_ERROR, (unsigned)diag::Severity::Error, "pack expansion contains parameter pack %0 that has a different length (%1 vs. %2) from outer parameter packs", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pack_expansion_member_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "pack expansion for initialization of member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pack_expansion_without_parameter_packs, CLASS_ERROR, (unsigned)diag::Severity::Error, "pack expansion does not contain any unexpanded parameter packs", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "C does not support default arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_member_template_redecl, CLASS_ERROR, (unsigned)diag::Severity::Error, "default arguments cannot be added to an out-of-line definition of a member of a %select{class template|class template partial specialization|nested class in a template}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing default argument on parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_missing_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing default argument on parameter %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_nonfunc, CLASS_ERROR, (unsigned)diag::Severity::Error, "default arguments can only be specified for parameters in a function declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_references_local, CLASS_ERROR, (unsigned)diag::Severity::Error, "default argument references local variable %0 of enclosing function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_references_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "default argument references parameter %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_references_this, CLASS_ERROR, (unsigned)diag::Severity::Error, "default argument references 'this'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_default_argument_template_redecl, CLASS_ERROR, (unsigned)diag::Severity::Error, "default arguments cannot be added to a function template that has already been declared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_param_with_void_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "argument may not have 'void' type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_parameter_name_omitted, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter name omitted", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_parameters_retval_cannot_have_fp16_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_parens_pointer_member_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot parenthesize the name of a method when forming a member pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_partial_spec_args_match_primary_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class|variable}0 template partial specialization does not specialize any template argument; to %select{declare|define}1 the primary template, remove the template argument list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_partial_spec_fully_specialized, CLASS_ERROR, (unsigned)diag::Severity::Error, "partial specialization of %0 does not use any of its template parameters", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_partial_spec_ordering_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous partial specializations of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_partial_spec_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "class template partial specialization %0 cannot be redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_partial_specialization_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "partial specialization cannot be declared as a friend", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_placement_new_non_placement_delete, CLASS_ERROR, (unsigned)diag::Severity::Error, "'new' expression with placement arguments refers to non-placement 'operator delete'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pointer_to_member_call_drops_quals, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to pointer to member function of type %0 drops '%1' qualifier%s2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pointer_to_member_oper_value_classify, CLASS_ERROR, (unsigned)diag::Severity::Error, "pointer-to-member function type %0 can only be called on an %select{rvalue|lvalue}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pointer_to_member_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid use of pointer to member type after %select{.*|->*}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_loop_compatibility, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{incompatible|duplicate}0 directives '%1' and '%2'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_loop_invalid_keyword, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument; expected 'enable' or 'disable'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_loop_invalid_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument; expected a positive integer value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_loop_precedes_nonloop, CLASS_ERROR, (unsigned)diag::Severity::Error, "expected a for, while, or do-while loop to follow '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_options_align_mac68k_target_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "mac68k alignment pragma is not supported on this target", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_pop_visibility_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "#pragma visibility pop with no matching #pragma visibility push", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pragma_push_visibility_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "#pragma visibility push with no matching #pragma visibility pop", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_found_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 found on object of type %1; did you mean to access it with the \".\" operator?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_function_in_objc_container, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of Objective-C property in function nested in Objective-C container not supported, move function outside its container", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_is_variably_modified, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 has a variably modified type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_method_unavailable, CLASS_ERROR, (unsigned)diag::Severity::Error, "property access is using %0 method which is unavailable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_not_as_forward_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 refers to an incomplete Objective-C class %1 (with no @interface available)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 not found on object of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_not_found_forward_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 cannot be found in forward class object %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_not_found_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 not found on object of type %1; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_property_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "property cannot have array or function type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_protocol_has_circular_dependency, CLASS_ERROR, (unsigned)diag::Severity::Error, "protocol has circular dependency", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pseudo_dtor_base_not_scalar, CLASS_ERROR, (unsigned)diag::Severity::Error, "object expression of non-scalar type %0 cannot be used in a pseudo-destructor expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pseudo_dtor_call_with_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to pseudo-destructor cannot have any arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pseudo_dtor_destructor_non_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not refer to a type name in pseudo-destructor expression; expected the name of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_pseudo_dtor_type_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "the type of object expression %diff{($) does not match the type being destroyed ($)|does not match the type being destroyed}0,1 in pseudo-destructor expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_catch_declarator, CLASS_ERROR, (unsigned)diag::Severity::Error, "exception declarator cannot be qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_friend_def, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend function definition cannot be qualified with '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_friend_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "no function named %0 with type %1 was found in the specified scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_member_nonclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "qualified member access refers to a member in %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_member_of_unrelated, CLASS_ERROR, (unsigned)diag::Severity::Error, "%q0 is not a member of class %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_objc_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{property|instance variable}0 access cannot be qualified with '%1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_objc_catch_parm, CLASS_ERROR, (unsigned)diag::Severity::Error, "@catch parameter declarator cannot be qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_param_declarator, CLASS_ERROR, (unsigned)diag::Severity::Error, "parameter declarator cannot be qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_qualified_typedef_declarator, CLASS_ERROR, (unsigned)diag::Severity::Error, "typedef declarator cannot be qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_range_on_array_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot build range expression with array function parameter %0 since parameter with array type %1 is treated as pointer type %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_realimag_invalid_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid type %0 to %1 operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_record_with_pointers_kernel_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{struct|union}0 kernel parameters may not contain pointers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_recursive_superclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "trying to recursively use %0 as superclass of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_different_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of %0 as different kind of symbol", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_different_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of %0 with a different type%diff{: $ vs $|}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_different_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{typedef|type alias|type alias template}0 redefinition with different types%diff{ ($ vs $)|}1,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_extern_inline, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of a 'extern inline' function %0 is not supported in %select{C99 mode|C++}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_of_enumerator, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of enumerator %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_of_label, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of label %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_redefinition_variably_modified_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "redefinition of %select{typedef|type alias}0 for variably-modified type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_array_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to declaration with an array type inside block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_bad_target, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to %select{__device__|__global__|__host__|__host__ __device__}0 function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_flexarray_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to declaration of structure variable with flexible array member inside block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_init_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference initialization of type %0 with initializer of type %1 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_non_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not refer to a value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_qualifier_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "ref-qualifier '%select{&&|&}0' is not allowed on a constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_qualifier_destructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "ref-qualifier '%select{&&|&}0' is not allowed on a destructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_qualifier_overload, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot overload a member function %select{without a ref-qualifier|with ref-qualifier '&'|with ref-qualifier '&&'}0 with a member function %select{without a ref-qualifier|with ref-qualifier '&'|with ref-qualifier '&&'}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ref_vm_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to declaration with a variably modified type inside block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_bind_drops_quals, CLASS_ERROR, (unsigned)diag::Severity::Error, "binding of reference %diff{to type $ to a value of type $ drops qualifiers|drops qualifiers}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_bind_failed, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_bind_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to type %0 cannot bind to an initializer list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_bind_to_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-const|volatile}0 reference cannot bind to bit-field%select{| %1}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_bind_to_vector_element, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{non-const|volatile}0 reference cannot bind to vector element", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_capture_with_reference_default, CLASS_ERROR, (unsigned)diag::Severity::Error, "'&' cannot precede a capture when the capture default is '&'", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_reference_has_multiple_inits, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference cannot be initialized with multiple values", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_to_local_var_in_enclosing_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to local variable %0 declared in enclosing block literal", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_to_local_var_in_enclosing_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to local variable %0 declared in enclosing context", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_to_local_var_in_enclosing_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to local variable %0 declared in enclosing function %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_to_local_var_in_enclosing_lambda, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to local variable %0 declared in enclosing lambda expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_to_void, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot form a reference to 'void'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_var_requires_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of reference variable %0 requires an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_reference_without_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference to type %0 requires an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_regparm_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declared with regparm(%0) attribute was previously declared %plural{0:without the regparm|:with the regparm(%1)}1 attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_repeat_attribute, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 attribute cannot be repeated", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_ret_local_block, CLASS_ERROR, (unsigned)diag::Severity::Error, "returning block that lives on the local stack", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_return_block_has_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "void block should not return a value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_return_in_captured_stmt, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot return from %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_return_in_constructor_handler, CLASS_ERROR, (unsigned)diag::Severity::Error, "return in the catch of a function try block of a constructor is illegal", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_return_init_list, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{void function|void method|constructor|destructor}1 %0 must not return a value", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_returns_retained_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declared with the ns_returns_retained attribute was previously declared without the ns_returns_retained attribute", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_rref_in_exception_spec, CLASS_ERROR, (unsigned)diag::Severity::Error, "rvalue reference type %0 is not allowed in exception specification", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sampler_argument_required, CLASS_ERROR, (unsigned)diag::Severity::Error, "sampler_t variable required - got %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_second_parameter_to_va_arg_abstract, CLASS_ERROR, (unsigned)diag::Severity::Error, "second argument to 'va_arg' is of abstract type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_second_parameter_to_va_arg_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "second argument to 'va_arg' is of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_section_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 causes a section type conflict with %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_selected_explicit_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "chosen constructor is explicit in copy-initialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_selector_element_const_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "selector element of type %0 cannot be a constant l-value expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_selector_element_not_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "selector element is not a valid lvalue", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_selector_element_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "selector element type %0 is not a valid object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_setter_type_void, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of setter must be void", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_shufflevector_argument_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "index for __builtin_shufflevector must be less than the total number of vector elements", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_shufflevector_incompatible_vector, CLASS_ERROR, (unsigned)diag::Severity::Error, "first two arguments to __builtin_shufflevector must have the same type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_shufflevector_non_vector, CLASS_ERROR, (unsigned)diag::Severity::Error, "first two arguments to __builtin_shufflevector must be vectors", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_shufflevector_nonconstant_argument, CLASS_ERROR, (unsigned)diag::Severity::Error, "index for __builtin_shufflevector must be a constant integer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_alignof_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of '%select{sizeof|alignof}0' to bit-field", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_alignof_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of '%select{sizeof|alignof|vec_step}0' to a function type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_alignof_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid application of '%select{sizeof|alignof|vec_step}0' to an incomplete type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_nonfragile_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "application of '%select{alignof|sizeof}1' to interface %0 is not supported on this architecture and platform", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_pack_no_pack_name, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not refer to the name of a parameter pack", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_sizeof_pack_no_pack_name_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not refer to the name of a parameter pack; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_spec_member_not_instantiated, CLASS_ERROR, (unsigned)diag::Severity::Error, "specialization of member %q0 does not specialize an instantiated member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_specialization_after_instantiation, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit specialization of %0 after instantiation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_specialize_member_of_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot specialize %select{|(with 'template<>') }0a member of an unspecialized template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_standalone_class_nested_name_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "forward declaration of %select{class|struct|interface|union|enum}0 cannot have a nested name specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_assert_expression_is_not_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "static_assert expression is not an integral constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_assert_failed, CLASS_ERROR, (unsigned)diag::Severity::Error, "static_assert failed%select{ %1|}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_block_func, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declared in block scope cannot have 'static' storage class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_data_member_not_allowed_in_anon_struct, CLASS_ERROR, (unsigned)diag::Severity::Error, "static data member %0 not allowed in anonymous struct", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_data_member_not_allowed_in_local_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "static data member %0 not allowed in local class %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_data_member_reinitialization, CLASS_ERROR, (unsigned)diag::Severity::Error, "static data member %0 already has an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_downcast_via_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast %0 to %1 via virtual base %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_function_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "variables in function scope cannot be declared static", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_illegal_in_new, CLASS_ERROR, (unsigned)diag::Severity::Error, "the 'static' modifier for the array size is not legal in new expressions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_kernel, CLASS_ERROR, (unsigned)diag::Severity::Error, "kernel functions cannot be declared static", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_main, CLASS_ERROR, (unsigned)diag::Severity::Error, "'main' is not allowed to be declared static", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_non_static, CLASS_ERROR, (unsigned)diag::Severity::Error, "static declaration of %0 follows non-static declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_not_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "static member %0 cannot be a bit-field", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_out_of_line, CLASS_ERROR, (unsigned)diag::Severity::Error, "'static' can only be specified inside the class definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_static_overrides_virtual, CLASS_ERROR, (unsigned)diag::Severity::Error, "'static' member function %0 overrides a virtual function in a base class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_statically_allocated_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "interface type cannot be statically allocated", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_stmtexpr_file_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement expression not allowed at file scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_storage_class_for_static_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "static data member definition cannot specify a storage class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_storage_spec_on_catch_parm, CLASS_ERROR, (unsigned)diag::Severity::Error, "@catch parameter cannot have storage specifier '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_storageclass_invalid_for_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "storage class specified for a member declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_subscript_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "subscript of pointer to function type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_subscript_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "subscript of pointer to incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_subscript_nonfragile_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "subscript requires size of interface %0, which is not constant for this architecture and platform", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_switch_explicit_conversion, CLASS_ERROR, (unsigned)diag::Severity::Error, "switch condition type %0 requires explicit conversion to %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_switch_incomplete_class_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "switch condition has incomplete class type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_switch_into_protected_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "switch case is in protected scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_switch_multiple_conversions, CLASS_ERROR, (unsigned)diag::Severity::Error, "multiple conversions from switch condition type %0 to an integral or enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tag_definition_of_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tag_reference_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "implicit declaration introduced by elaborated type conflicts with %select{a declaration|a typedef|a type alias|a template}0 of the same name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tag_reference_non_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tagless_friend_type_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "friend type templates must use an elaborated type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_temp_copy_ambiguous, CLASS_ERROR, (unsigned)diag::Severity::Error, "ambiguous constructor call when %select{copying variable|copying parameter|returning object|throwing object|copying member subobject|copying array element|allocating object|copying temporary|initializing base subobject|initializing vector element|capturing value}0 of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_temp_copy_deleted, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{copying variable|copying parameter|returning object|throwing object|copying member subobject|copying array element|allocating object|copying temporary|initializing base subobject|initializing vector element|capturing value}0 of type %1 invokes deleted constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_temp_copy_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "copying a temporary object of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_temp_copy_no_viable, CLASS_ERROR, (unsigned)diag::Severity::Error, "no viable constructor %select{copying variable|copying parameter|returning object|throwing object|copying member subobject|copying array element|allocating object|copying temporary|initializing base subobject|initializing vector element|capturing value}0 of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_address_of_non_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "address taken in non-type template argument for template parameter of reference type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_field, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument refers to non-static data member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_list_different_arity, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{too few|too many}0 template arguments for %select{class template|function template|template template parameter|template}1 %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument refers to non-static member function %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_must_be_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument for non-type template parameter must be an expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_must_be_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument for template template parameter must be a class template%select{| or type alias template}0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_must_be_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument for template type parameter must be a type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_must_be_type_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument for template type parameter must be a type; did you forget 'typename'?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_no_ref_bind, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template parameter of reference type %diff{$ cannot bind to template argument of type $|cannot bind to template of incompatible argument type}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_nontype_ambig, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument for non-type template parameter is treated as function type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_address_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument of type %0 is not a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_address_of, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument for template parameter of pointer type %0 must have its address taken", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_class_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument does not refer to a class template or template template parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_convertible, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument of type %0 cannot be converted to a value of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_decl_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument does not refer to any declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_ice, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument of type %0 is not an integral constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_integral_or_enumeral, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument of type %0 must have an integral or enumeration type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_object_or_func, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument does not refer to an object or function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_not_pointer_to_member_form, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument is not a pointer to member constant", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_object_no_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument refers to %select{function|object}0 %1 that does not have linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_overload_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "template argument is the type of an unresolved overloaded function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_ref_bind_ignores_quals, CLASS_ERROR, (unsigned)diag::Severity::Error, "reference binding of non-type template parameter %diff{of type $ to template argument of type $|to template argument}0,1 ignores qualifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_reference_var, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument of reference type %0 is not an object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_template_params_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "template template argument has different template parameters than its corresponding template template parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_thread_local, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template argument refers to thread-local object", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_untyped_null_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "null non-type template argument must be cast to template parameter type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_arg_wrongtype_null_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "null non-type template argument of type %0 does not match template parameter of type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_decl_ref, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to %select{class|variable}0 template %1 without a template argument list", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_id_not_a_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "template name refers to non-type template %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_inside_local_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "templates cannot be declared inside of a local class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_instantiate_undefined, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{implicit|explicit}0 instantiation of undefined template %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_instantiate_within_definition, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{implicit|explicit}0 instantiation of template %1 within its own definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_kw_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing 'template' keyword prior to dependent template name '%0%1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_kw_refers_to_class_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0%1' instantiated to a class template, not a function template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_kw_refers_to_non_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 following the 'template' keyword does not refer to a template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "templates must have C++ linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "member %0 declared as a template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_member_noparams, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous 'template<>' in declaration of member %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_missing_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of class template %0 requires template arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_nontype_parm_bad_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "a non-type template parameter cannot have type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_nontype_parm_different_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "template non-type parameter has a different type %0 in template %select{|template parameter }1redeclaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_outside_namespace_or_class_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "templates can only be declared in namespace or class scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_default_arg_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter missing a default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_default_arg_redefinition, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter redefines default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_different_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter has a different kind in template %select{|template parameter }0redeclaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_list_different_arity, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{too few|too many}0 template parameters in template %select{|template parameter }1redeclaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_list_matches_nontemplate, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter list matching the non-templated nested type %0 should be empty ('template<>')", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_pack_default_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter pack cannot have a default argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_pack_must_be_last_template_parameter, CLASS_ERROR, (unsigned)diag::Severity::Error, "template parameter pack must be the last template parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_param_shadow, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %0 shadows template parameter", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_parameter_default_friend_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "default template argument not permitted on a friend template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_parameter_default_template_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot add a default template argument to the definition of a member of a class template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_parameter_pack_non_pack, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{template type|non-type template|template template}0 parameter%select{| pack}1 conflicts with previous %select{template type|non-type template|template template}0 parameter%select{ pack|}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_qualified_declarator_no_match, CLASS_ERROR, (unsigned)diag::Severity::Error, "nested name specifier '%0' for declaration does not refer into a class, class template or class template partial specialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_recursion_depth_exceeded, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "recursive template instantiation exceeded maximum depth of %0", 0, SFINAE_Report, false, true, 2)
+DIAG(err_template_spec_decl_class_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit specialization of %0 in class scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_decl_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot declare an explicit specialization in a friend", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_decl_function_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "explicit specialization of %0 in function scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_decl_out_of_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 must originally be declared in namespace %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_decl_out_of_scope_global, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 must originally be declared in the global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_default_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "default argument not permitted on an explicit %select{instantiation|specialization}0 of function %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_extra_headers, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous template parameter list in template specialization or out-of-line template definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "template specialization declaration cannot be a friend", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_needs_header, CLASS_ERROR, (unsigned)diag::Severity::Error, "template specialization requires 'template<>'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_needs_template_parameters, CLASS_ERROR, (unsigned)diag::Severity::Error, "template specialization or definition requires a template parameter list corresponding to the nested type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_redecl_global_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 must occur at global scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_redecl_out_of_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 not in a namespace enclosing %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_spec_unknown_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "can only provide an explicit specialization for a class template, function template, variable template, or a member function, static data member, %select{or member class|member class, or member enumeration}0 of a class template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_tag_noparams, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous 'template<>' in declaration of %0 %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_template_parm_no_parms, CLASS_ERROR, (unsigned)diag::Severity::Error, "template template parameter must have its own template parameters", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "a typedef cannot be a template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_unnamed_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot declare a class template with no name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_template_variable_noparams, CLASS_ERROR, (unsigned)diag::Severity::Error, "extraneous 'template<>' in declaration of variable %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tentative_after_alias, CLASS_ERROR, (unsigned)diag::Severity::Error, "tentative definition of %0 after alias definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_tentative_def_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "tentative definition has type %0 that is never completed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_this_capture, CLASS_ERROR, (unsigned)diag::Severity::Error, "'this' cannot be %select{implicitly |}0captured in this context", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_this_capture_with_copy_default, CLASS_ERROR, (unsigned)diag::Severity::Error, "'this' cannot be explicitly captured when the capture default is '='", 0, SFINAE_SubstitutionFailure, false, true, 3)
+DIAG(err_this_static_member_func, CLASS_ERROR, (unsigned)diag::Severity::Error, "'this' cannot be%select{| implicitly}0 used in a static member function declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_dynamic_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "initializer for thread-local variable must be a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_non_global, CLASS_ERROR, (unsigned)diag::Severity::Error, "'%0' variables must have global storage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_non_thread, CLASS_ERROR, (unsigned)diag::Severity::Error, "thread-local declaration of %0 follows non-thread-local declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_nontrivial_dtor, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of thread-local variable has non-trivial destruction", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_thread_different_kind, CLASS_ERROR, (unsigned)diag::Severity::Error, "thread-local declaration of %0 with %select{static|dynamic}1 initialization follows declaration with %select{dynamic|static}1 initialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_thread_unsupported, CLASS_ERROR, (unsigned)diag::Severity::Error, "thread-local storage is not supported for the current target", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_throw_abstract_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot throw an object of abstract type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_throw_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot throw object of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_throw_incomplete_ptr, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot throw pointer to object of incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_toomany_element_decls, CLASS_ERROR, (unsigned)diag::Severity::Error, "only one element declaration is allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_trailing_return_in_parens, CLASS_ERROR, (unsigned)diag::Severity::Error, "trailing return type may not be nested within parentheses", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_trailing_return_without_auto, CLASS_ERROR, (unsigned)diag::Severity::Error, "function with trailing return type must specify return type 'auto', not %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_alias_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be defined in a type alias template", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "types may not be defined in conditions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_for_range, CLASS_ERROR, (unsigned)diag::Severity::Error, "types may not be defined in a for range declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_param_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be defined in a parameter type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be defined in the result type of a function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_defined_in_type_specifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot be defined in a type specifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_mismatch_continuation_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of property %0 in class extension does not match property type in primary class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_tag_for_datatype_not_ice, CLASS_ERROR, (unsigned)diag::Severity::Error, "'type_tag_for_datatype' attribute requires the initializer to be an %select{integer|integral}0 constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_type_tag_for_datatype_too_large, CLASS_ERROR, (unsigned)diag::Severity::Error, "'type_tag_for_datatype' attribute requires the initializer to be an %select{integer|integral}0 constant expression that can be represented by a 64 bit integer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_address_of, CLASS_ERROR, (unsigned)diag::Severity::Error, "address of %select{bit-field|vector element|property expression|register variable}0 requested", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_addrof_dtor, CLASS_ERROR, (unsigned)diag::Severity::Error, "taking the address of a destructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_addrof_temporary, CLASS_ERROR, (unsigned)diag::Severity::Error, "taking the address of a temporary object of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_ambiguous_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion %diff{from $ to $|between types}0,1 is ambiguous", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_arc_assign_self, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot assign to 'self' outside of a method in the init family", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_typecheck_arc_assign_self_class_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot assign to 'self' in a class method", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_typecheck_arithmetic_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "arithmetic on a pointer to an incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_arr_assign_enumeration, CLASS_ERROR, (unsigned)diag::Severity::Error, "fast enumeration variables can't be modified in ARC by default; declare the variable __strong to allow this", 0, SFINAE_SubstitutionFailure, false, true, 5)
+DIAG(err_typecheck_array_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "array type %0 is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_assign_const, CLASS_ERROR, (unsigned)diag::Severity::Error, "read-only variable is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_bool_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "value of type %0 is not contextually convertible to 'bool'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_invalid_ordered_compare, CLASS_ERROR, (unsigned)diag::Severity::Error, "ordered compare requires two args of floating point type%diff{ ($ and $)|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_invalid_unary_fp, CLASS_ERROR, (unsigned)diag::Severity::Error, "floating point classification requires argument of floating point type (passed in %0)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_not_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "called object type %0 is not a function or function pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected %1, have %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args_at_least, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected at least %1, have %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args_at_least_one, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, at least argument %1 must be specified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args_at_least_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected at least %1, have %2; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args_one, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, single argument %1 was not specified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_few_args_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "too few %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected %1, have %2; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected %1, have %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args_at_most, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected at most %1, have %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args_at_most_one, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected at most single argument %1, have %2 arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args_at_most_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected at most %1, have %2; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args_one, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected single argument %1, have %2 arguments", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_call_too_many_args_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "too many %select{|||execution configuration }0arguments to %select{function|block|method|kernel function}0 call, expected %1, have %2; did you mean %3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cast_to_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "cast to incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cast_to_union_no_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cast to union type from type %0 not present in union", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_choose_expr_requires_constant, CLASS_ERROR, (unsigned)diag::Severity::Error, "'__builtin_choose_expr' requires a constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_comparison_of_distinct_blocks, CLASS_ERROR, (unsigned)diag::Severity::Error, "comparison of distinct block types%diff{ ($ and $)|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_comparison_of_distinct_pointers, CLASS_ERROR, (unsigned)diag::Severity::Error, "comparison of distinct pointer types%diff{ ($ and $)|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_comparison_of_fptr_to_void, CLASS_ERROR, (unsigned)diag::Severity::Error, "equality comparison between function pointer and void pointer (%0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_comparison_of_pointer_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "comparison between pointer and integer (%0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cond_expect_scalar, CLASS_ERROR, (unsigned)diag::Severity::Error, "used type %0 where arithmetic or pointer type is required", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cond_expect_scalar_or_vector, CLASS_ERROR, (unsigned)diag::Severity::Error, "used type %0 where arithmetic, pointer, or vector type is required", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cond_incompatible_operands, CLASS_ERROR, (unsigned)diag::Severity::Error, "incompatible operand types%diff{ ($ and $)|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_cond_incompatible_operands_null, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-pointer operand type %0 incompatible with %select{NULL|nullptr}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_convert_incompatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{%diff{assigning to $ from incompatible type $|assigning to type from incompatible type}0,1|%diff{passing $ to parameter of incompatible type $|passing type to parameter of incompatible type}0,1|%diff{returning $ from a function with incompatible result type $|returning type from a function with incompatible result type}0,1|%diff{converting $ to incompatible type $|converting type to incompatible type}0,1|%diff{initializing $ with an expression of incompatible type $|initializing type with an expression of incompatible type}0,1|%diff{sending $ to parameter of incompatible type $|sending type to parameter of incompatible type}0,1|%diff{casting $ to incompatible type $|casting type to incompatible type}0,1}2%select{|; dereference with *|; take the address with &|; remove *|; remove &}3%select{|: different classes%diff{ ($ vs $)|}5,6|: different number of parameters (%5 vs %6)|: type mismatch at %ordinal5 parameter%diff{ ($ vs $)|}6,7|: different return type%diff{ ($ vs $)|}5,6|: different qualifiers (%select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}5 vs %select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}6)}4", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_convert_incompatible_block_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "incompatible block pointer types %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_converted_constant_expression, CLASS_ERROR, (unsigned)diag::Severity::Error, "value of type %0 is not implicitly convertible to %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_converted_constant_expression_disallowed, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion from %0 to %1 is not allowed in a converted constant expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_decl_incomplete_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable has incomplete type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_decl_incomplete_type___float128, CLASS_ERROR, (unsigned)diag::Severity::Error, "support for type '__float128' is not yet implemented", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_deleted_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "conversion function %diff{from $ to $|between types}0,1 invokes a deleted function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_duplicate_vector_components_not_mlvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "vector is not assignable (contains duplicate components)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_expect_scalar_operand, CLASS_ERROR, (unsigned)diag::Severity::Error, "operand of type %0 where arithmetic or pointer type is required", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_expression_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_field_variable_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "fields must have a constant size: 'variable length array in structure' extension will never be supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_illegal_increment_decrement, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot %select{decrement|increment}1 value of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_incompatible_address_space, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{%diff{assigning $ to $|assigning to different types}1,0|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 changes address space of pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_incompatible_ownership, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{%diff{assigning $ to $|assigning to different types}1,0|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 changes retain/release properties of pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_incomplete_array_needs_initializer, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of variable with array type needs an explicit size or an initializer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_incomplete_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete definition of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "incomplete type %0 is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_indirection_requires_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "indirection requires pointer operand (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_lvalue_addrof, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot take the address of an rvalue of type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_lvalue_addrof_addrof_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "extra '&' taking address of overloaded function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_operands, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid operands to binary expression (%0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_restrict_invalid_pointee, CLASS_ERROR, (unsigned)diag::Severity::Error, "pointer to function type %0 may not be 'restrict' qualified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_restrict_not_pointer, CLASS_ERROR, (unsigned)diag::Severity::Error, "restrict requires a pointer or reference (%0 is invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_invalid_restrict_not_pointer_noarg, CLASS_ERROR, (unsigned)diag::Severity::Error, "restrict requires a pointer or reference", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_ivar_variable_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variables must have a constant size", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_lvalue_casts_not_supported, CLASS_ERROR, (unsigned)diag::Severity::Error, "assignment to cast is illegal, lvalue casts are not supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_arrow, CLASS_ERROR, (unsigned)diag::Severity::Error, "member reference type %0 is not a pointer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_ivar, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not have a member named %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_ivar_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 does not have a member named %1; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_struct_union, CLASS_ERROR, (unsigned)diag::Severity::Error, "member reference base type %0 is not a structure or union", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_suggestion, CLASS_ERROR, (unsigned)diag::Severity::Error, "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to type member %0 in %1 with '%select{.|->}2'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_member_reference_unknown, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot refer to member %0 in %1 with '%select{.|->}2'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_missing_return_type_incompatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "%diff{return type $ must match previous return type $|return type must match previous return type}0,1 when %select{block literal|lambda expression}2 has unspecified explicit return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_negative_array_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "array size is negative", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_non_object_not_modifiable_lvalue, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-object type %0 is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_nonviable_condition, CLASS_ERROR, (unsigned)diag::Severity::Error, "no viable conversion%diff{ from $ to $|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_nonviable_condition_incomplete, CLASS_ERROR, (unsigned)diag::Severity::Error, "no viable conversion%diff{ from $ to incomplete type $|}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_pointer_arith_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function type%select{|s}2 %1%select{| and %3}2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_pointer_arith_void_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "arithmetic on%select{ a|}0 pointer%select{|s}0 to void", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_sclass_fscope, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal storage class on file-scoped variable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_sclass_func, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal storage class on function", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_statement_requires_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement requires expression of integer type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_statement_requires_scalar, CLASS_ERROR, (unsigned)diag::Severity::Error, "statement requires expression of scalar type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_sub_ptr_compatible, CLASS_ERROR, (unsigned)diag::Severity::Error, "%diff{$ and $ are not pointers to compatible types|pointers to incompatible types}0,1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_subscript_not_integer, CLASS_ERROR, (unsigned)diag::Severity::Error, "array subscript is not an integer", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_subscript_value, CLASS_ERROR, (unsigned)diag::Severity::Error, "subscripted value is not an array, pointer, or vector", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_unary_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "invalid argument type %0 to unary expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_vector_not_convertable, CLASS_ERROR, (unsigned)diag::Severity::Error, "can't convert between vector values of different size (%0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_vector_not_convertable_non_scalar, CLASS_ERROR, (unsigned)diag::Severity::Error, "can't convert between vector and non-scalar values (%0 and %1)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typecheck_zero_array_size, CLASS_ERROR, (unsigned)diag::Severity::Error, "zero-length arrays are not permitted in C++", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typedef_changes_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported: typedef changes linkage of anonymous type, but linkage was already computed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typedef_not_bitfield, CLASS_ERROR, (unsigned)diag::Severity::Error, "typedef member %0 cannot be a bit-field", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typedef_not_identifier, CLASS_ERROR, (unsigned)diag::Severity::Error, "typedef name must be an identifier", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typename_missing, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing 'typename' prior to dependent type name '%0%1'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typename_nested_not_found, CLASS_ERROR, (unsigned)diag::Severity::Error, "no type named %0 in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typename_nested_not_found_enable_if, CLASS_ERROR, (unsigned)diag::Severity::Error, "no type named 'type' in %0; 'enable_if' cannot be used to disable this declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typename_nested_not_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "typename specifier refers to non-type member %0 in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_typename_refers_to_using_value_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "typename specifier refers to a dependent using declaration for a value %0 in %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unavailable, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is unavailable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unavailable_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is unavailable: %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uncasted_call_of_unknown_any, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 has unknown return type; cast the call to its declared return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uncasted_send_to_unknown_any_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "no known method %select{%objcinstance1|%objcclass1}0; cast the message send to the method's return type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uncasted_use_of_unknown_any, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 has unknown type; cast it to its declared type to use it", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_boxing_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration of %0 is missing in %1 class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_label_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of undeclared label %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_nsarray, CLASS_ERROR, (unsigned)diag::Severity::Error, "NSArray must be available to use Objective-C array literals", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_nsdictionary, CLASS_ERROR, (unsigned)diag::Severity::Error, "NSDictionary must be available to use Objective-C dictionary literals", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_nsnumber, CLASS_ERROR, (unsigned)diag::Severity::Error, "NSNumber must be available to use Objective-C literals", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_nsstring, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot box a string value because NSString has not been declared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_protocol, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find protocol declaration for %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_protocol_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find protocol declaration for %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of undeclared %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_use_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of undeclared %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_var_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of undeclared identifier %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undeclared_var_use_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of undeclared identifier %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undef_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find interface declaration for %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undef_interface_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find interface declaration for %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undef_superclass, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find interface declaration for %0, superclass of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_undef_superclass_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find interface declaration for %0, superclass of %1; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_underlying_type_of_incomplete_enum, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot determine underlying type of incomplete enumeration type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpanded_parameter_pack_0, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{expression|base type|declaration type|data member type|bit-field size|static assertion|fixed underlying type|enumerator value|using declaration|friend declaration|qualifier|initializer|default argument|non-type template parameter type|exception type|partial specialization|__if_exists name|__if_not_exists name|lambda|block}0 contains an unexpanded parameter pack", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpanded_parameter_pack_1, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{expression|base type|declaration type|data member type|bit-field size|static assertion|fixed underlying type|enumerator value|using declaration|friend declaration|qualifier|initializer|default argument|non-type template parameter type|exception type|partial specialization|__if_exists name|__if_not_exists name|lambda|block}0 contains unexpanded parameter pack %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpanded_parameter_pack_2, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{expression|base type|declaration type|data member type|bit-field size|static assertion|fixed underlying type|enumerator value|using declaration|friend declaration|qualifier|initializer|default argument|non-type template parameter type|exception type|partial specialization|__if_exists name|__if_not_exists name|lambda|block}0 contains unexpanded parameter packs %1 and %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpanded_parameter_pack_3_or_more, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{expression|base type|declaration type|data member type|bit-field size|static assertion|fixed underlying type|enumerator value|using declaration|friend declaration|qualifier|initializer|default argument|non-type template parameter type|exception type|partial specialization|__if_exists name|__if_not_exists name|lambda|block}0 contains unexpanded parameter packs %1, %2, ...", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpected_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "friends can only be classes or functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpected_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected interface name %0: expected expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpected_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected namespace name %0: expected expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unexpected_typedef, CLASS_ERROR, (unsigned)diag::Severity::Error, "unexpected type name %0: expected expression", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uninitialized_member_for_assign, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot define the implicit copy assignment operator for %0, because non-static %select{reference|const}1 member %2 can't use copy assignment operator", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uninitialized_member_in_ctor, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{|implicit default |inheriting }0constructor for %1 must explicitly initialize the %select{reference|const}2 member %3", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_union_as_base_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "unions cannot be base classes", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_union_member_of_reference_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "union member %0 has reference type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_any_addrof, CLASS_ERROR, (unsigned)diag::Severity::Error, "the address of a declaration with unknown type can only be cast to a pointer type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_any_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "function %0 with unknown type must be given a function type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_any_var_function_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable %0 with unknown type cannot be given a function type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_nested_typename_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no type named %0 in %1; did you mean %select{|simply }2%3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_receiver_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown receiver %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_type_or_class_name_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown %select{type|class}1 name %0; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_typename, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown type name %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unknown_typename_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "unknown type name %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unqualified_pointer_member_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "must explicitly qualify name of member function when taking its address", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unsupported_unknown_any_call, CLASS_ERROR, (unsigned)diag::Severity::Error, "call to unsupported expression with unknown type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unsupported_unknown_any_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 has unknown type, which is not supported for this kind of declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_unsupported_unknown_any_expr, CLASS_ERROR, (unsigned)diag::Severity::Error, "unsupported expression with unknown type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_upcast_to_inaccessible_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot cast %0 to its %select{private|protected}2 base class %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_use_continuation_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal redeclaration of property in class extension %0 (attribute must be 'readwrite', while its primary must be 'readonly')", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_use_continuation_class_redeclaration_readwrite, CLASS_ERROR, (unsigned)diag::Severity::Error, "illegal redeclaration of 'readwrite' property in class extension %0 (perhaps you intended this to be a 'readwrite' redeclaration of a 'readonly' public property?)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_use_of_default_argument_to_function_declared_later, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of default argument to function %0 that is declared later in class %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_use_with_wrong_tag, CLASS_ERROR, (unsigned)diag::Severity::Error, "use of %0 with tag type that does not match previous declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_can_not_refer_to_class_member, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration cannot refer to class member", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_can_not_refer_to_namespace, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration cannot refer to namespace", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "target of using declaration conflicts with declaration already in scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_conflict_reverse, CLASS_ERROR, (unsigned)diag::Severity::Error, "declaration conflicts with target of using declaration already in scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_constructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration cannot refer to a constructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_constructor_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot inherit constructor, already inherited constructor with the same signature", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_constructor_not_in_direct_base, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is not a direct base of %1, cannot inherit constructors", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_destructor, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration cannot refer to a destructor", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_friend, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot befriend target of using declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_nested_name_specifier_is_current_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration refers to its own class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_nested_name_specifier_is_not_base_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration refers into '%0', which is not a base class of %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_nested_name_specifier_is_not_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration in class refers into '%0', which is not a class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_redeclaration, CLASS_ERROR, (unsigned)diag::Severity::Error, "redeclaration of using decl", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_decl_template_id, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration cannot refer to a template specialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_dependent_value_is_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "dependent using declaration resolved to type without 'typename'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_directive_member_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no namespace named %0 in %1; did you mean %select{|simply }2%3?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_directive_suggest, CLASS_ERROR, (unsigned)diag::Severity::Error, "no namespace named %0; did you mean %1?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_requires_qualname, CLASS_ERROR, (unsigned)diag::Severity::Error, "using declaration requires a qualified name", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_using_typename_non_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "'typename' keyword used on a non-type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uuidof_with_multiple_guids, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot call operator __uuidof on a type with multiple GUIDs", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_uuidof_without_guid, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot call operator __uuidof on a type with no GUID", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_va_start_used_in_non_variadic_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'va_start' used in function with fixed args", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_value_init_for_array_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "array types cannot be value-initialized", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_var_partial_spec_redeclared, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable template partial specialization %0 cannot be redefined", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_var_spec_no_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "no variable template matches%select{| partial}0 specialization", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_var_spec_no_template_but_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "no variable template matches specialization; did you mean to use %0 as function template instead?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_variable_instantiates_to_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{variable|static data member}0 instantiated with function type %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_variable_object_no_init, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable-sized object may not be initialized", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_variably_modified_new_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "'new' cannot allocate object of variably modified type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_variably_modified_nontype_template_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-type template parameter of variably modified type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_variably_modified_template_arg, CLASS_ERROR, (unsigned)diag::Severity::Error, "variably modified type %0 cannot be used as a template argument", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vecstep_non_scalar_vector_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "'vec_step' requires built-in scalar or vector type, %0 invalid", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vector_incorrect_num_initializers, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_virtual_member_function_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "'virtual' cannot be specified on member function templates", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_virtual_non_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "'virtual' can only appear on non-static member functions", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_virtual_out_of_class, CLASS_ERROR, (unsigned)diag::Severity::Error, "'virtual' can only be specified inside the class definition", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vla_decl_has_extern_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array declaration cannot have 'extern' linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vla_decl_has_static_storage, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array declaration cannot have 'static' storage duration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vla_decl_in_file_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array declaration not allowed at file scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vla_in_sfinae, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array cannot be formed during template argument deduction", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vla_non_pod, CLASS_ERROR, (unsigned)diag::Severity::Error, "variable length array of non-POD element type %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vm_decl_has_extern_linkage, CLASS_ERROR, (unsigned)diag::Severity::Error, "variably modified type declaration cannot have 'extern' linkage", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vm_decl_in_file_scope, CLASS_ERROR, (unsigned)diag::Severity::Error, "variably modified type declaration not allowed at file scope", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_vm_func_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "function declaration cannot have variably modified type", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_void_only_param, CLASS_ERROR, (unsigned)diag::Severity::Error, "'void' must be the first and only parameter if specified", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_void_param_qualified, CLASS_ERROR, (unsigned)diag::Severity::Error, "'void' as parameter must not have type qualifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(err_wrong_sampler_addressspace, CLASS_ERROR, (unsigned)diag::Severity::Error, "sampler type cannot be used with the __local and __global address space qualifiers", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_arc_weak_ivar_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to strong variable first", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_bad_category_property_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "property implementation must have its declaration in the category %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_bad_property_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "property implementation must be in a class or category implementation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_bad_property_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "property implementation must have its declaration in interface %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_cannot_find_suitable_accessor, CLASS_ERROR, (unsigned)diag::Severity::Error, "cannot find suitable %select{getter|setter}0 for property %1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_category_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "property declared in category %0 cannot be implemented in class implementation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_dealloc_bad_result_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "dealloc return type must be correctly specified as 'void' under ARC, instead of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_duplicate_ivar_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "synthesized properties %0 and %1 both claim instance variable %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_dynamic_property_ivar_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "dynamic property cannot have instance variable specification", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_implicit_ivar_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 cannot be accessed because 'self' has been redeclared", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_ivar_in_superclass_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 attempting to use instance variable %1 declared in super class %2", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_ivar_use_in_class_method, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 accessed in class method", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_method_not_found_with_typo, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{instance|class}1 method %0 not found ; did you mean %2?", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_missing_method_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing context for method declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_missing_property_context, CLASS_ERROR, (unsigned)diag::Severity::Error, "missing context for property implementation declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_missing_property_interface, CLASS_ERROR, (unsigned)diag::Severity::Error, "property implementation in a category with no category declaration", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_missing_property_ivar_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "synthesized property %0 must either be named the same as a compatible instance variable or must explicitly name an instance variable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_no_subobject_property_setting, CLASS_ERROR, (unsigned)diag::Severity::Error, "expression is not assignable", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_no_super_class_message, CLASS_ERROR, (unsigned)diag::Severity::Error, "no @interface declaration found in class messaging of %0", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_objc_synchronized_expects_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "@synchronized requires an Objective-C object type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_objc_throw_expects_object, CLASS_ERROR, (unsigned)diag::Severity::Error, "@throw requires an Objective-C object type (%0 invalid)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_private_ivar_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 is private", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(error_property_accessor_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of property %0 (%1) does not match type of accessor %2 (%3)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_property_implemented, CLASS_ERROR, (unsigned)diag::Severity::Error, "property %0 is already implemented", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_property_ivar_type, CLASS_ERROR, (unsigned)diag::Severity::Error, "type of property %0 (%1) does not match type of instance variable %2 (%3)", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_property_setter_ambiguous_use, CLASS_ERROR, (unsigned)diag::Severity::Error, "synthesized properties %0 and %1 both claim setter %2 - use of this setter will cause unexpected behavior", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_protected_ivar_access, CLASS_ERROR, (unsigned)diag::Severity::Error, "instance variable %0 is protected", 0, SFINAE_AccessControl, false, true, 2)
+DIAG(error_readonly_message_assignment, CLASS_ERROR, (unsigned)diag::Severity::Error, "assigning to 'readonly' return result of an Objective-C message not allowed", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_reference_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "property of reference type is not supported", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_rethrow_used_outside_catch, CLASS_ERROR, (unsigned)diag::Severity::Error, "@throw (rethrow) used outside of a @catch block", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_root_class_cannot_use_super, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 cannot use 'super' because it is a root class", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_strong_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "existing instance variable %1 for strong property %0 may not be __weak", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_synthesize_category_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "@synthesize not allowed in a category's implementation", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_synthesize_weak_non_arc_or_gc, CLASS_ERROR, (unsigned)diag::Severity::Error, "@synthesize of 'weak' property is only allowed in ARC or GC mode", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(error_weak_property, CLASS_ERROR, (unsigned)diag::Severity::Error, "existing instance variable %1 for __weak property %0 must be __weak", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(ext_aggregate_init_not_constant, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "initializer for aggregate is not a compile-time constant", 80, SFINAE_Suppress, false, false, 2)
+DIAG(ext_anonymous_record_with_anonymous_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "anonymous types declared in an anonymous %select{struct|union}0 are an extension", 290, SFINAE_Suppress, false, false, 2)
+DIAG(ext_anonymous_record_with_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "types declared in an anonymous %select{struct|union}0 are a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_anonymous_struct_union_qualified, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "anonymous %select{struct|union}0 cannot be '%1'", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_anonymous_union, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "anonymous unions are a C11 extension", 78, SFINAE_Suppress, false, false, 2)
+DIAG(ext_array_init_copy, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "initialization of an array %diff{of type $ from a compound literal of type $|from a compound literal}0,1 is a GNU extension", 185, SFINAE_Suppress, false, false, 2)
+DIAG(ext_array_init_parens, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "parenthesized initialization of a member array is a GNU extension", 181, SFINAE_Suppress, false, false, 2)
+DIAG(ext_array_size_conversion, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "implicit conversion from array size expression of type %0 to %select{integral|enumeration}1 type %2 is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_c11_anonymous_struct, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "anonymous structs are a C11 extension", 78, SFINAE_Suppress, false, false, 2)
+DIAG(ext_c99_array_usage, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 feature", 80, SFINAE_Suppress, false, false, 2)
+DIAG(ext_c99_flexible_array_member, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array members are a C99 feature", 80, SFINAE_Suppress, false, false, 2)
+DIAG(ext_cast_fn_obj, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "cast between pointer-to-function and pointer-to-object is an extension", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_cce_narrowing, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "%select{case value|enumerator value|non-type template argument|array size}0 %select{cannot be narrowed from type %2 to %3|evaluates to %2, which cannot be narrowed to type %3}1", 64, SFINAE_SubstitutionFailure, false, false, 2)
+DIAG(ext_complex_component_init, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "complex initialization specifying real and imaginary components is an extension", 90, SFINAE_Suppress, false, false, 2)
+DIAG(ext_constexpr_body_invalid_stmt, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use of this statement in a constexpr %select{function|constructor}0 is a C++1y extension", 67, SFINAE_Suppress, false, false, 2)
+DIAG(ext_constexpr_body_multiple_return, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "multiple return statements in constexpr function is a C++1y extension", 67, SFINAE_Suppress, false, false, 2)
+DIAG(ext_constexpr_function_never_constant_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "constexpr %select{function|constructor}0 never produces a constant expression", 241, SFINAE_Suppress, false, false, 2)
+DIAG(ext_constexpr_local_var, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "variable declaration in a constexpr %select{function|constructor}0 is a C++1y extension", 67, SFINAE_Suppress, false, false, 2)
+DIAG(ext_constexpr_type_definition, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "type definition in a constexpr %select{function|constructor}0 is a C++1y extension", 67, SFINAE_Suppress, false, false, 2)
+DIAG(ext_delete_void_ptr_operand, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "cannot delete expression with pointer-to-'void' type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_deprecated_string_literal_conversion, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "ISO C++11 does not allow conversion from string literal to %0", 510, SFINAE_SubstitutionFailure, false, false, 2)
+DIAG(ext_designated_init, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "designated initializers are a C99 feature", 80, SFINAE_Suppress, false, false, 2)
+DIAG(ext_empty_struct_union, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "empty %select{struct|union}0 is a GNU extension", 189, SFINAE_Suppress, false, false, 2)
+DIAG(ext_enum_friend, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "befriending enumeration type %0 is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_enum_too_large, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "enumeration values exceed range of largest integer", 150, SFINAE_Suppress, false, false, 2)
+DIAG(ext_enum_value_not_int, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C restricts enumerator values to range of 'int' (%0 is too %select{small|large}1)", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_enumerator_increment_too_large, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incremented enumerator value %0 is not representable in the largest integer type", 150, SFINAE_Suppress, false, false, 2)
+DIAG(ext_enumerator_too_large, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "enumerator value is not representable in the underlying type %0", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_excess_initializers, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "excess elements in %select{array|vector|scalar|union|struct}0 initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_excess_initializers_in_char_array_initializer, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "excess elements in char array initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_explicit_conversion_functions, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "explicit conversion functions are a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_explicit_instantiation_after_specialization, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "explicit instantiation of %0 that occurs after an explicit specialization will be ignored (C++11 extension)", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_explicit_instantiation_duplicate, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "duplicate explicit instantiation of %0 ignored as a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_explicit_instantiation_without_qualified_id, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "qualifier in explicit instantiation of %q0 requires a template-id (a typedef is not permitted)", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_explicit_specialization_storage_class, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "explicit specialization cannot have a storage class", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_expr_not_ice, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "expression is not an %select{integer|integral}0 constant expression; folding it to a constant is a GNU extension", 192, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_empty_aggregate_gnu, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array member %0 in otherwise empty %select{struct|interface|union|class|enum}1 is a GNU extension", 189, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_empty_aggregate_ms, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array member %0 in otherwise empty %select{struct|interface|union|class|enum}1 is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_in_array, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%0 may not be used as an array element due to flexible array member", 161, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_in_struct, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%0 may not be nested in a struct due to flexible array member", 161, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_init, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array initialization is a GNU extension", 190, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_union_gnu, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array member %0 in a union is a GNU extension", 191, SFINAE_Suppress, false, false, 2)
+DIAG(ext_flexible_array_union_ms, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "flexible array member %0 in a union is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_forward_ref_enum, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C forbids forward references to 'enum' types", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_forward_ref_enum_def, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "redeclaration of already-defined enum %0 is a GNU extension", 195, SFINAE_Suppress, false, false, 2)
+DIAG(ext_found_via_dependent_bases_lookup, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use of identifier %0 found via unqualified lookup into dependent bases of class templates is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_freestanding_complex, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "complex numbers are an extension in a freestanding C99 implementation", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_friend_tag_redecl_outside_namespace, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unqualified friend declaration referring to type outside of the nearest enclosing namespace is a Microsoft extension; add a nested name specifier", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_function_specialization_in_class, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "explicit specialization of %0 within class scope is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_gnu_anonymous_struct, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "anonymous structs are a GNU extension", 180, SFINAE_Suppress, false, false, 2)
+DIAG(ext_gnu_ptr_func_arith, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function type%select{|s}2 %1%select{| and %3}2 is a GNU extension", 354, SFINAE_Suppress, false, false, 2)
+DIAG(ext_gnu_subscript_void_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "subscript of a pointer to void is a GNU extension", 354, SFINAE_Suppress, false, false, 2)
+DIAG(ext_gnu_void_ptr, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension", 354, SFINAE_Suppress, false, false, 2)
+DIAG(ext_goto_into_protected_scope, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "goto into protected scope", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_implicit_exception_spec_mismatch, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "function previously declared with an %select{explicit|implicit}0 exception specification redeclared with an %select{implicit|explicit}0 exception specification", 212, SFINAE_Suppress, false, false, 2)
+DIAG(ext_implicit_function_decl, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "implicit declaration of function %0 is invalid in C99", 215, SFINAE_Suppress, false, false, 2)
+DIAG(ext_implicit_lib_function_decl, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "implicitly declaring library function '%0' with type %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_in_class_initializer_float_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "in-class initializer for static data member of type %0 is a GNU extension", 197, SFINAE_Suppress, false, false, 2)
+DIAG(ext_in_class_initializer_float_type_cxx11, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "in-class initializer for static data member of type %0 requires 'constexpr' specifier", 407, SFINAE_Suppress, false, false, 2)
+DIAG(ext_in_class_initializer_non_constant, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "in-class initializer for static data member is not a constant expression; folding it to a constant is a GNU extension", 192, SFINAE_Suppress, false, false, 2)
+DIAG(ext_init_capture, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "initialized lambda captures are a C++1y extension", 67, SFINAE_Suppress, false, false, 3)
+DIAG(ext_init_list_constant_narrowing, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "constant expression evaluates to %0 which cannot be narrowed to type %1", 64, SFINAE_SubstitutionFailure, false, false, 2)
+DIAG(ext_init_list_type_narrowing, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "type %0 cannot be narrowed to %1 in initializer list", 64, SFINAE_SubstitutionFailure, false, false, 2)
+DIAG(ext_init_list_variable_narrowing, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "non-constant-expression cannot be narrowed from type %0 to %1 in initializer list", 64, SFINAE_SubstitutionFailure, false, false, 2)
+DIAG(ext_initializer_string_for_char_array_too_long, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "initializer-string for char array is too long", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_integer_complement_complex, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C does not support '~' for complex conjugation of %0", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_integer_increment_complex, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C does not support '++'/'--' on complex integer type %0", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_internal_in_extern_inline, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "static %select{function|variable}0 %1 is used in an inline function with external linkage", 408, SFINAE_Suppress, false, false, 2)
+DIAG(ext_internal_in_extern_inline_quiet, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "static %select{function|variable}0 %1 is used in an inline function with external linkage", 408, SFINAE_Suppress, false, false, 2)
+DIAG(ext_invalid_sign_spec, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "'%0' cannot be signed or unsigned", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_main_returns_nonint, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "return type of 'main' is not 'int'", 263, SFINAE_Suppress, false, false, 2)
+DIAG(ext_main_used, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C++ does not allow 'main' to be used by a program", 262, SFINAE_Suppress, false, false, 2)
+DIAG(ext_many_braces_around_scalar_init, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "too many braces around scalar initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_member_redeclared, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "class member cannot be redeclared", 370, SFINAE_Suppress, false, false, 2)
+DIAG(ext_mismatched_exception_spec, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "exception specification in declaration does not match previous declaration", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_missing_declspec, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "declaration specifier missing, defaulting to 'int'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_missing_type_specifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "type specifier missing, defaults to 'int'", 216, SFINAE_Suppress, false, false, 2)
+DIAG(ext_mixed_decls_code, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C90 forbids mixing declarations and code", 110, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_anonymous_struct, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "anonymous structs are a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_delayed_template_argument, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "using the undeclared type %0 as a default template argument is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_deref_template_argument, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "non-type template argument containing a dereference operation is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_explicit_constructor_call, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "explicit constructor calls are a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_forward_ref_enum, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "forward references to 'enum' types are a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_template_type_arg_missing_typename, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "template argument for template type parameter must be a type; omitted 'typename' is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_ms_using_declaration_inaccessible, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "using declaration referring to inaccessible member '%0' (which refers to accessible member '%1') is a Microsoft compatibility extension", 267, SFINAE_AccessControl, false, false, 2)
+DIAG(ext_nested_name_member_ref_lookup_ambiguous, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "lookup of %0 in member access expression is ambiguous; using member of %1", 15, SFINAE_Suppress, false, false, 2)
+DIAG(ext_nested_pointer_qualifier_mismatch, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 discards qualifiers in nested pointer types", 224, SFINAE_Suppress, false, false, 2)
+DIAG(ext_new_paren_array_nonconst, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "when type is in parentheses, array cannot have dynamic size", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_no_declarators, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "declaration does not declare anything", 273, SFINAE_Suppress, false, false, 2)
+DIAG(ext_no_named_members_in_struct_union, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%select{struct|union}0 without named members is a GNU extension", 189, SFINAE_Suppress, false, false, 2)
+DIAG(ext_nonclass_type_friend, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "non-class friend type %0 is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_noreturn_main, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'main' is not allowed to be declared _Noreturn", 262, SFINAE_Suppress, false, false, 2)
+DIAG(ext_offsetof_extended_field_designator, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "using extended field designator is an extension", 153, SFINAE_Suppress, false, false, 2)
+DIAG(ext_offsetof_non_pod_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "offset of on non-POD type %0", 245, SFINAE_Suppress, false, false, 2)
+DIAG(ext_offsetof_non_standardlayout_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "offset of on non-standard-layout type %0", 245, SFINAE_Suppress, false, false, 2)
+DIAG(ext_omp_loop_not_canonical_init, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')", 336, SFINAE_Suppress, false, false, 15)
+DIAG(ext_operator_new_delete_declared_inline, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "replacement function %0 cannot be declared 'inline'", 234, SFINAE_Suppress, false, false, 2)
+DIAG(ext_out_of_line_declaration, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "out-of-line declaration of a member must be a definition", 337, SFINAE_Suppress, false, false, 2)
+DIAG(ext_override_exception_spec, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "exception specification of overriding function is more lax than base version", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_param_default_argument_redefinition, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "redefinition of default argument", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_param_not_declared, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "parameter %0 was not declared, defaulting to type 'int'", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_param_promoted_not_compatible_with_prototype, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%diff{promoted type $ of K&R function parameter is not compatible with the parameter type $|promoted type of K&R function parameter is not compatible with parameter type}0,1 declared in a previous prototype", 251, SFINAE_Suppress, false, false, 2)
+DIAG(ext_predef_outside_function, CLASS_WARNING, (unsigned)diag::Severity::Warning, "predefined identifier is only valid inside function", 360, SFINAE_Suppress, false, false, 2)
+DIAG(ext_pseudo_dtor_on_void, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pseudo-destructors on type void are a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_pure_function_definition, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "function definition with pure-specifier is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_redefinition_of_typedef, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "redefinition of typedef %0 is a C11 feature", 451, SFINAE_Suppress, false, false, 2)
+DIAG(ext_retained_language_linkage, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "friend function %0 retaining previous language linkage is an extension", 377, SFINAE_Suppress, false, false, 2)
+DIAG(ext_return_has_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "%select{void function|void method|constructor|destructor}1 %0 should not return a value", 379, SFINAE_Suppress, false, false, 2)
+DIAG(ext_return_has_void_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "void %select{function|method|block}1 %0 should not return void expression", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_return_missing_expr, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "non-void %select{function|method}1 %0 should return a value", 379, SFINAE_Suppress, false, false, 2)
+DIAG(ext_rvalue_to_reference_access_ctor, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "C++98 requires an accessible copy constructor for class %2 when binding a reference to a temporary; was %select{private|protected}0", 45, SFINAE_AccessControl, false, false, 2)
+DIAG(ext_rvalue_to_reference_temp_copy_no_viable, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "no viable constructor %select{copying variable|copying parameter|returning object|throwing object|copying member subobject|copying array element|allocating object|copying temporary|initializing base subobject|initializing vector element|capturing value}0 of type %1; C++98 requires a copy constructor when binding a reference to a temporary", 45, SFINAE_Suppress, false, false, 2)
+DIAG(ext_sizeof_alignof_function_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "invalid application of '%select{sizeof|alignof|vec_step}0' to a function type", 354, SFINAE_Suppress, false, false, 2)
+DIAG(ext_sizeof_alignof_void_type, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "invalid application of '%select{sizeof|alignof|vec_step}0' to a void type", 354, SFINAE_Suppress, false, false, 2)
+DIAG(ext_standalone_specifier, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'%0' is not permitted on a declaration of a type", 273, SFINAE_Suppress, false, false, 2)
+DIAG(ext_static_assert_no_message, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "static_assert with no message is a C++1z extension", 68, SFINAE_Suppress, false, false, 2)
+DIAG(ext_static_data_member_in_union, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "static data member %0 in union is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_static_non_static, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "redeclaring non-static %0 as static is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_string_literal_operator_template, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "string literal operator templates are a GNU extension", 198, SFINAE_Suppress, false, false, 2)
+DIAG(ext_subscript_non_lvalue, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C90 does not allow subscripting non-lvalue array", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_arg_extra_parens, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "address non-type template argument cannot be surrounded by parentheses", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_arg_local_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "template argument uses local type %0", 256, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_arg_object_internal, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "non-type template argument referring to %select{function|object}0 %1 with internal linkage is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_arg_unnamed_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "template argument uses unnamed type", 467, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_outside_of_template, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'template' keyword outside of a template", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_parameter_default_in_function_template, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "default template arguments for a function template are a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_template_spec_decl_out_of_scope, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "first declaration of %select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 outside namespace %2 is a C++11 extension", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_addrof_temporary, CLASS_EXTENSION, (unsigned)diag::Severity::Error, "taking the address of a temporary object of type %0", 11, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_addrof_void, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C forbids taking the address of an expression of type 'void'", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_base_super, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "method parameter type %diff{$ does not match super class method parameter type $|does not match super class method parameter type}0,1", 431, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cast_nonscalar, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "C99 forbids casting nonscalar type %0 to the same type", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cast_to_union, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "cast to union type is a GNU extension", 199, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_comparison_of_distinct_pointers, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "comparison of distinct pointer types%diff{ ($ and $)|}0,1", 89, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_comparison_of_distinct_pointers_nonstandard, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "comparison of distinct pointer types (%0 and %1) uses non-standard composite pointer type %2", 89, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_comparison_of_fptr_to_void, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "equality comparison between function pointer and void pointer (%0 and %1)", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_comparison_of_pointer_integer, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "comparison between pointer and integer (%0 and %1)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cond_incompatible_operands, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incompatible operand types (%0 and %1)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cond_incompatible_operands_nonstandard, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incompatible operand types%diff{ ($ and $)|}0,1 use non-standard composite pointer type %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cond_incompatible_pointers, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pointer type mismatch%diff{ ($ and $)|}0,1", 358, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cond_one_void, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "C99 forbids conditional expressions with only one void side", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_cond_pointer_integer_mismatch, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "pointer/integer type mismatch in conditional expression%diff{ ($ and $)|}0,1", 91, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_convert_discards_qualifiers, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 discards qualifiers", 224, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_convert_incompatible_pointer, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incompatible pointer types %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2%select{|; dereference with *|; take the address with &|; remove *|; remove &}3", 223, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_convert_incompatible_pointer_sign, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "%select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 converts between pointers to integer types with different sign", 356, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_convert_int_pointer, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incompatible integer to pointer conversion %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2%select{|; dereference with *|; take the address with &|; remove *|; remove &}3", 235, SFINAE_Suppress, false, false, 17)
+DIAG(ext_typecheck_convert_pointer_int, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "incompatible pointer to integer conversion %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2%select{|; dereference with *|; take the address with &|; remove *|; remove &}3", 235, SFINAE_Suppress, false, false, 17)
+DIAG(ext_typecheck_convert_pointer_void_func, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "%select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2 converts between void pointer and function pointer", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_decl_incomplete_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "tentative definition of variable with internal linkage has incomplete non-array type %0", 442, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_indirection_through_void_pointer, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ISO C++ does not allow indirection on operand of type %0", 506, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_ordered_comparison_of_function_pointers, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "ordered comparison of function pointers (%0 and %1)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_ordered_comparison_of_pointer_and_zero, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "ordered comparison between pointer and zero (%0 and %1) is an extension", 353, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_ordered_comparison_of_pointer_integer, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "ordered comparison between pointer and integer (%0 and %1)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typecheck_zero_array_size, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "zero size arrays are an extension", 512, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typedef_without_a_name, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "typedef requires a name", 273, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typename_missing, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "missing 'typename' prior to dependent type name '%0%1'", 452, SFINAE_Suppress, false, false, 2)
+DIAG(ext_typename_outside_of_template, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "'typename' occurs outside of a template", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_undeclared_unqual_id_with_dependent_base, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "use of undeclared identifier %0; unqualified lookup into dependent bases of class template %1 is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_unelaborated_friend_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "unelaborated friend declaration is a C++11 extension; specify '%select{struct|interface|union|class|enum}0' to befriend %1", 61, SFINAE_Suppress, false, false, 2)
+DIAG(ext_union_member_of_reference_type, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "union member %0 has reference type %1, which is a Microsoft extension", 267, SFINAE_Suppress, false, false, 2)
+DIAG(ext_using_undefined_std, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "using directive refers to implicitly-defined namespace 'std'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(ext_variable_sized_type_in_struct, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "field %0 with variable sized type %1 not at the end of a struct or class is a GNU extension", 200, SFINAE_Suppress, false, false, 2)
+DIAG(ext_variable_template, CLASS_EXTENSION, (unsigned)diag::Severity::Warning, "variable templates are a C++1y extension", 67, SFINAE_Suppress, false, false, 2)
+DIAG(ext_vla, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "variable length arrays are a C99 feature", 505, SFINAE_Suppress, false, false, 2)
+DIAG(ext_vla_folded_to_constant, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "variable length array folded to constant array as an extension", 192, SFINAE_Suppress, false, false, 2)
+DIAG(not_conv_function_declared_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type conversion function declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(not_incomplete_class_and_qualified_id, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conformance of forward class %0 to protocol %1 can not be confirmed", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_access_constrained_by_path, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constrained by %select{|implicitly }1%select{private|protected}0 inheritance here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_access_natural, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{|implicitly }1declared %select{private|protected}0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_access_protected_restricted_ctordtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "protected %select{constructor|destructor}0 can only be used to %select{construct|destroy}0 a base class subobject", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_access_protected_restricted_noobject, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "must name member using the type of the current context %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_access_protected_restricted_object, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "can only access this member on an object of type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_additional_parens_for_variable_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add a pair of parentheses to declare a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_alignas_on_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declared with %0 attribute here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ambig_member_ref_object_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "lookup in the object type %0 refers here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ambig_member_ref_scope, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "lookup from the current scope refers here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ambiguous_candidate, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate found by name lookup is %q0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ambiguous_member_found, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member found by ambiguous name lookup", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ambiguous_type_conversion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because of ambiguity in conversion %diff{of $ to $|between types}0,1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_arc_assign_to_strong, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "assign the value to a strong variable to keep the object alive during use", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_arc_bridge, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use __bridge to convert directly (no change in ownership)", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_bridge_retained, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use %select{__bridge_retained|CFBridgingRetain call}1 to make an ARC object available as a +1 %0", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_bridge_transfer, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use %select{__bridge_transfer|CFBridgingRelease call}1 to transfer ownership of a +1 %0 into ARC", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_cstyle_bridge, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use __bridge with C-style cast to convert directly (no change in ownership)", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_cstyle_bridge_retained, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use __bridge_retained with C-style cast to make an ARC object available as a +1 %0", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_cstyle_bridge_transfer, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use __bridge_transfer with C-style cast to transfer ownership of a +1 %0 into ARC", 0, SFINAE_Suppress, false, false, 7)
+DIAG(note_arc_gained_method_convention, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration in interface is not in the '%select{alloc|copy|init|new}0' family because %select{its result type is not an object pointer|its result type is unrelated to its receiver type}1", 0, SFINAE_Suppress, false, false, 5)
+DIAG(note_arc_lost_method_convention, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration in interface", 0, SFINAE_Suppress, false, false, 5)
+DIAG(note_arc_retain_cycle_owner, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "block will be retained by %select{the captured object|an object strongly retained by the captured object}0", 0, SFINAE_Suppress, false, false, 19)
+DIAG(note_arc_weak_also_accessed_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "also accessed here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_array_index_out_of_bounds, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "array %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_array_size_conversion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion to %select{integral|enumeration}0 type %1 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_assign_lhs_incomplete, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type %0 is incomplete", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_atomic_property_fixup_suggest, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "setter and getter must both be synthesized, or both be user defined,or the property must be nonatomic", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_attribute, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "attribute is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_attribute_overloadable_prev_overload, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous overload of function is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_auto_readonly_iboutlet_fixup_suggest, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property should be changed to be readwrite", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_availability_specified_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 has been explicitly marked %select{unavailable|deleted|deprecated}1 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_bad_memaccess_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicitly cast the pointer to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_base_class_specified_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "base class %0 specified here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_bitfield_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "bit-field is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_block_var_fixit_add_initialization, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "maybe you meant to use __block %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_callee_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_callee_static_array, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "callee declares array parameter as static here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_cannot_inherit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constructor cannot be inherited", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_carries_dependency_missing_first_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration missing '[[carries_dependency]]' attribute is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_class_declared, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_compat_assoc, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "compatible type %0 specified here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_condition_assign_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "place parentheses around the assignment to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_condition_assign_to_comparison, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '==' to turn this assignment into an equality comparison", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_condition_or_assign_to_comparison, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '!=' to turn this compound assignment into an inequality comparison", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_constexpr_body_previous_return, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous return statement is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_constexpr_ctor_missing_init, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member not initialized by constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_constexpr_virtual_base_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "virtual base class declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_constructor_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constructor declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_convert_inline_to_static, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use 'static' to give inline function %0 internal linkage", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_declaration_not_a_prototype, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_default_arg_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of default argument for '%0' required here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_default_argument_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "default argument declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_default_function_arg_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of default function argument expression for '%0' required here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_defined_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 defined here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_delete_conversion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion to pointer type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_assign_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{copy|move}0 assignment operator of %1 is implicitly deleted because field %2 is of %select{reference|const-qualified}4 type %3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_copy_ctor_rvalue_reference, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "copy constructor of %0 is implicitly deleted because field %1 is of rvalue reference type %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_copy_user_declared_move, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "copy %select{constructor|assignment operator}0 is implicitly deleted because %1 has a user-declared move %select{constructor|assignment operator}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_default_ctor_all_const, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "default constructor of %0 is implicitly deleted because all %select{data members|data members of an anonymous union member}1 are const-qualified", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_default_ctor_uninit_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "default constructor of %0 is implicitly deleted because field %1 of %select{reference|const-qualified}3 type %2 would not be initialized", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_dtor_no_operator_delete, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "virtual destructor requires an unambiguous, accessible 'operator delete'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_deleted_special_member_class_subobject, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0 of %1 is implicitly deleted because %select{base class %3|%select{||||variant }4field %3}2 has %select{no|a deleted|multiple|an inaccessible|a non-trivial}4 %select{%select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0|destructor}5%select{||s||}4", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_dependent_non_type_default_arg_in_partial_spec, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template parameter is used in default argument declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_dependent_var_use, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "must qualify identifier to find this declaration in dependent base class", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_destructor_type_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type %0 is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_duplicate_element, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "element %0 also has value %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_empty_body_on_separate_line, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "put the semicolon on a separate line to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_empty_parens_default_ctor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove parentheses to declare a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_empty_parens_function_call, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "change this ',' to a ';' to call %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_empty_parens_zero_initialize, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "replace parentheses with an initializer to declare a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_enters_block_captures_cxx_obj, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump enters lifetime of block which captures a destructible C++ object", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_enters_block_captures_strong, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump enters lifetime of block which strongly captures a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_enters_block_captures_weak, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump enters lifetime of block which weakly captures a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_entity_declared_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_enum_specialized_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "enum %0 was explicitly specialized here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_equality_comparison_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove extraneous parentheses around the comparison to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_equality_comparison_to_assign, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '=' to turn this equality comparison into an assignment", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_evaluate_comparison_first, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "place parentheses around comparison expression to evaluate it first", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exception_spec_deprecated, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '%0' instead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits___block, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits scope of __block variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_block_captures_cxx_obj, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits lifetime of block which captures a destructible C++ object", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_block_captures_strong, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits lifetime of block which strongly captures a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_block_captures_weak, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits lifetime of block which weakly captures a variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_cleanup, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits scope of variable with __attribute__((cleanup))", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_cxx_catch, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits catch block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_cxx_try, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits try block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_dtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits scope of variable with non-trivial destructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_autoreleasepool, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits autoreleasepool block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_catch, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits @catch block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_finally, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits @finally block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_ownership, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits scope of retaining variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_synchronized, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits @synchronized block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_objc_try, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits @try block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_exits_temporary_dtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump exits scope of lifetime-extended temporary with non-trivial destructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_explicit_instantiation_candidate, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicit instantiation candidate function template here %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_explicit_instantiation_definition_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicit instantiation definition is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_explicit_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicit instantiation refers here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_explicit_template_arg_substitution_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "while substituting explicitly-specified template arguments into function template %0 %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_explicit_template_spec_does_not_need_header, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "'template<>' header not required for explicitly-specialized class %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_extern_c_global_conflict, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declared %select{in global scope|with C language linkage}0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_fallthrough_insert_semi_fixit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you forget ';'?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_field_designator_found, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "field designator refers here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_final_overrider, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "final overrider of %q0 in %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_flexible_array_member, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "initialized flexible array member %0 is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_for_range_begin_end, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_for_range_invalid_iterator, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_format_fix_specifier, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to use '%0'?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_format_string_defined, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "format string is defined here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_forward_class, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "forward declaration of class here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_found_mutex_near_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "found near match '%0'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_suggestion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean %0?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_template_deduction_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "while substituting deduced template arguments into function template %0 %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_template_spec_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of function template specialization %q0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_template_spec_matched, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "function template matches specialization %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_to_function_call, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "suffix with parentheses to turn this into a function call", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_function_warning_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "prefix with the address-of operator to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_getter_unavailable, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "or because setter is declared here, but no getter method %0 is found", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_hidden_overloaded_virtual_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "hidden overloaded virtual function %q0 declared here%select{|: different classes%diff{ ($ vs $)|}2,3|: different number of parameters (%2 vs %3)|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4|: different return type%diff{ ($ vs $)|}2,3|: different qualifiers (%select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}2 vs %select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}3)}1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_hidden_tag, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type declaration hidden", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_hiding_object, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration hides type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ice_conversion_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion to %select{integral|enumeration}0 type %1 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_illegal_field_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "field of illegal %select{type|pointer type}0 %1 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_implementation_declared, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class implementation is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_implemented_by_class, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "when implemented by class %0", 0, SFINAE_Suppress, false, false, 9)
+DIAG(note_implicit_param_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is an implicit parameter", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_implicitly_deleted, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicitly defaulted function was implicitly deleted here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_in_class_initializer_float_type_cxx11, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add 'constexpr'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_in_for_range, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "when looking up '%select{begin|end}0' function for range expression of type %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_in_omitted_aggregate_initializer, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in implicit initialization of %select{array element %1|field %1}0 with omitted initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_include_header_or_declare, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "include the header <%0> or explicitly provide a declaration for '%1'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_indirect_goto_target, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "possible target of indirect goto", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_indirection_through_null, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "consider using __builtin_trap() or qualifying pointer with 'volatile'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_inequality_comparison_to_or_assign, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '|=' to turn this inequality comparison into an or-assignment", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_inhctor_synthesized_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "inheriting constructor for %0 first required here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_inherited_deleted_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "deleted constructor was inherited here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_init_list_narrowing_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "insert an explicit cast to silence this issue", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_insert_break_fixit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "insert 'break;' to avoid fall-through", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_insert_fallthrough_fixit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "insert '%0;' to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_instantiation_contexts_suppressed, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to see all)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_instantiation_required_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{implicit|explicit}0 instantiation first required here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_it_delegates_to, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "it delegates to", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ivar_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "instance variable is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_lambda_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "lambda expression begins here", 0, SFINAE_Suppress, false, false, 3)
+DIAG(note_lambda_to_block_conv, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "implicit capture of lambda object due to conversion to block pointer here", 0, SFINAE_Suppress, false, false, 3)
+DIAG(note_local_decl_close_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "local declaration nearly matches", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_local_decl_close_param_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type of %ordinal0 parameter of local declaration does not match definition%diff{ ($ vs $)|}1,2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_lock_exclusive_and_shared, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "the other acquisition of %0 '%1' is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_locked_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 acquired here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_logical_instead_of_bitwise_change_operator, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use '%0' for a bitwise operation", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_logical_instead_of_bitwise_remove_constant, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove constant to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_logical_not_fix, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add parentheses after the '!' to evaluate the comparison first", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_logical_not_silence_with_parens, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add parentheses around left hand side expression to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_loop_iteration_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{decremented|incremented}0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_main_change_return_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "change return type to 'int'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_main_remove_noreturn, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove '_Noreturn'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_declared_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_def_close_const_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member declaration does not match because it %select{is|is not}0 const qualified", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_def_close_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member declaration nearly matches", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_def_close_param_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "type of %ordinal0 parameter of member declaration does not match definition%diff{ ($ vs $)|}1,2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_reference_arrow_from_operator_arrow, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "'->' applied to return value of the operator->() declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_member_synthesized_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "implicit %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}0 for %1 first required here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_memsize_comparison_cast_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicitly cast the argument to size_t to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_memsize_comparison_paren, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to compare the result of %0 instead?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_method_declared_at, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "method %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_method_return_type_change, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "compiler has implicitly changed method %0 return type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_method_sent_forward_class, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "method %0 is used for the forward class", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_module_import_in_extern_c, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "extern \"C\" language linkage specification begins here", 0, SFINAE_Suppress, false, false, 14)
+DIAG(note_module_import_not_at_top_level, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 begins here", 0, SFINAE_Suppress, false, false, 14)
+DIAG(note_namespace_defined_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "namespace %0 defined here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_neon_vector_initializer_non_portable, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "consider using vld1_%0%1() to initialize a vector from memory, or vcreate_%0%1() to initialize from an integer constant", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_neon_vector_initializer_non_portable_q, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "consider using vld1q_%0%1() to initialize a vector from memory, or vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer constants", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_instantiated_member_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "not-yet-instantiated member is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_base_class, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is not literal because it has base class %1 of non-literal type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_field, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is not literal because it has data member %1 of %select{non-literal|volatile}3 type %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_incomplete, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "incomplete type %0 is not a literal type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_no_constexpr_ctors, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_nontrivial_dtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is not literal because it has a non-trivial destructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_user_provided_dtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is not literal because it has a user-provided destructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_non_literal_virtual_base, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{struct|interface|class}0 with virtual base %plural{1:class|:classes}1 is not a literal type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontemplate_decl_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "non-templated declaration is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_default_arg, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because it has a default argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_has_virtual, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because type %0 has a virtual %select{member function|base class}1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_in_class_init, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because field %0 has an initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_no_copy, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because no %select{<<ERROR>>|constructor|constructor|assignment operator|assignment operator|<<ERROR>>}2 can be used to %select{<<ERROR>>|copy|move|copy|move|<<ERROR>>}2 %select{base class|field|an object}0 of type %3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_no_def_ctor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because %select{base class of |field of |}0type %1 has no default constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_objc_ownership, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because type %0 has a member with %select{no|no|__strong|__weak|__autoreleasing}1 ownership", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_param_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because its parameter is %diff{of type $, not $|of the wrong type}2,3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_subobject, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because the function selected to %select{construct|copy|move|copy|move|destroy}2 %select{base class|field}0 of type %1 is not trivial", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_user_provided, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because %select{base class of |field of |}0type %1 has a user-provided %select{default constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_variadic, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "because it is a variadic function", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_nontrivial_virtual_dtor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "destructor for %0 is not trivial because it is virtual", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_noreturn_missing_first_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration missing '[[noreturn]]' attribute is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_not_found_by_two_phase_lookup, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 should be declared prior to the call site%select{| or in %2| or in an associated namespace of one of its arguments}1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_objc_designated_init_marked_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "method marked as designated initializer of the class here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_objc_literal_comparison_isequal, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use 'isEqual:' instead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_objc_literal_method_param, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{first|second|third}0 parameter has unexpected type %1 (should be %2)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_objc_literal_method_return, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "method returns unexpected type %0 (should be an object type)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_objc_needs_superclass, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add a super class to fix this problem", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_omp_collapse_expr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "as specified in 'collapse' clause", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_conversion_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion to %select{integral|enumeration}0 type %1 declared here", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_explicit_dsa, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "defined as %0", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_implicit_dsa, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "implicitly determined as %0", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_loop_cond_requres_compatible_incr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "loop step is expected to be %select{negative|positive}0 due to this condition", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_predetermined_dsa, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{static data member is predetermined as shared|variable with static storage duration is predetermined as shared|loop iteration variable is predetermined as private|loop iteration variable is predetermined as linear|loop iteration variable is predetermined as lastprivate|constant variable is predetermined as shared|global variable is predetermined as shared|non-shared variable in a task construct is predetermined as firstprivate|variable with automatic storage duration is predetermined as private}0%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_previous_critical_region, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous 'critical' region starts here", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_omp_referenced, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previously referenced here", 0, SFINAE_Suppress, false, false, 15)
+DIAG(note_operator_arrow_depth, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use -foperator-arrow-depth=N to increase 'operator->' limit", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_operator_arrow_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "'operator->' declared here produces an object of type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_operator_arrows_suppressed, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "(skipping %0 'operator->'%s0 in backtrace)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_overridden_method, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "overridden method is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_overridden_virtual_function, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "overridden virtual function is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_builtin_binary_candidate, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "built-in candidate %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_builtin_unary_candidate, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "built-in candidate %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |is the implicit default constructor|is the implicit copy constructor|is the implicit move constructor|is the implicit copy assignment operator|is the implicit move assignment operator|is an inherited constructor}0%1%select{| has different class%diff{ (expected $ but has $)|}3,4| has different number of parameters (expected %3 but has %4)| has type mismatch at %ordinal3 parameter%diff{ (expected $ but has $)|}4,5| has different return type%diff{ ($ expected but has $)|}3,4| has different qualifiers (expected %select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}3 but found %select{none|const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}4)}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_arity, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function|function|constructor|constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0 %select{|template }1not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 provided", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_arity_one, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function|function|constructor|constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0 %select{|template }1not viable: %select{requires at least|allows at most single|requires single}2 argument %3, but %plural{0:no|:%4}4 arguments were provided", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_addrspace, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: %select{%ordinal6|'this'}5 argument (%2) is in address space %3, but parameter must be in address space %4", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_arc_conv, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: cannot implicitly convert argument %diff{of type $ to $|type to parameter type}2,3 for %select{%ordinal5 argument|object argument}4 under ARC", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_base_to_derived_conv, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: cannot %select{convert from|convert from|bind}2 %select{base class pointer|superclass|base class object of type}2 %3 to %select{derived class pointer|subclass|derived class reference}2 %4 for %ordinal5 argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_conv, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: no known conversion %diff{from $ to $|from argument type to parameter type}2,3 for %select{%ordinal5 argument|object argument}4%select{|; dereference the argument with *|; take the address of the argument with &|; remove *|; remove &}6", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_conv_incomplete, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: cannot convert argument of incomplete type %diff{$ to $|to parameter type}2,3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_cvr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: %ordinal4 argument (%2) would lose %select{const|restrict|const and restrict|volatile|const and volatile|volatile and restrict|const, volatile, and restrict}3 qualifier%select{||s||s|s|s}3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_cvr_this, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{|function|||function|||||function (the implicit copy assignment operator)|function (the implicit move assignment operator)|}0 not viable: 'this' argument has type %2, but method is not marked %select{const|restrict|const or restrict|volatile|const or volatile|volatile or restrict|const, volatile, or restrict}3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_deduction, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: failed template argument deduction", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_gc, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: %select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 ownership, but parameter has %select{no|__weak|__strong}4 ownership", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_list_argument, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: cannot convert initializer list argument to %3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_lvalue, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: expects an l-value for %select{%ordinal3 argument|object argument}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_overload, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: no overload of %3 matching %2 for %ordinal4 argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_ownership, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 not viable: %select{%ordinal6|'this'}5 argument (%2) has %select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership, but parameter has %select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}4 ownership", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_bad_target, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0 not viable: call to %select{__device__|__global__|__host__|__host__ __device__}1 function from %select{__device__|__global__|__host__|__host__ __device__}2 function", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_deleted, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate %select{function|function|constructor|function |function |constructor |constructor (the implicit default constructor)|constructor (the implicit copy constructor)|constructor (the implicit move constructor)|function (the implicit copy assignment operator)|function (the implicit move assignment operator)|constructor (inherited)}0%1 has been %select{explicitly made unavailable|explicitly deleted|implicitly deleted}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_disabled_by_enable_if, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: disabled by %0%1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_disabled_by_enable_if_attr, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate disabled: %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_explicit_arg_mismatch_named, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: invalid explicitly-specified argument for template parameter %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_explicit_arg_mismatch_unnamed, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: invalid explicitly-specified argument for %ordinal0 template parameter", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_failed_overload_resolution, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: couldn't resolve reference to overloaded function %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_incomplete_deduction, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: couldn't infer template argument %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_inconsistent_deduction, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: deduced conflicting %select{types|values|templates}0 for parameter %1%diff{ ($ vs. $)|}2,3", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_inherited_constructor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "inherited from here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_instantiation_depth, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: substitution exceeded maximum template instantiation depth", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_non_deduced_mismatch, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: could not match %diff{$ against $|types}0,1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_non_deduced_mismatch_qualified, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: could not match %q0 against %q1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_substitution_failure, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: substitution failure%0%1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_candidate_underqualified, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "candidate template ignored: can't deduce a type for %0 which would make %2 equal %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_surrogate_cand, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion candidate of type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ovl_too_many_candidates, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remaining %0 candidate%s0 omitted; pass -fshow-overloads=all to show them", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_parameter_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "passing argument to parameter here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_parameter_named_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "passing argument to parameter %0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_parameter_pack_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "parameter pack %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_parameter_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "parameter of type %0 is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_partial_spec_deduct_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "during template argument deduction for class template partial specialization %0 %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_partial_spec_match, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "partial specialization matches %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_partial_spec_unused_parameter, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "non-deducible template parameter %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_possible_target_of_call, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "possible target for call", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_precedence_bitwise_first, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "place parentheses around the %0 expression to evaluate it first", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_precedence_conditional_first, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "place parentheses around the '?:' expression to evaluate it first", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_precedence_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "place parentheses around the '%0' expression to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_prev_partial_spec_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous declaration of class template partial specialization %0 is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_access_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previously declared '%1' here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_attribute, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous attribute is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_builtin_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 is a builtin with type %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_exception_handler, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "for type %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_explicit_instantiation, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous explicit instantiation is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_initializer, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous initialization %select{|with side effects }0is here%select{| (side effects may not occur at run time)}0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_ms_inheritance, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous inheritance model specified here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_previous_template_specialization, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous template specialization is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_printf_c_str, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to call the %0 method?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_prior_template_arg_substitution, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "while substituting prior template arguments into %select{non-type|template}0 template parameter%1 %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_private_extern, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use __attribute__((visibility(\"hidden\"))) attribute instead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_property_attribute, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property %0 is declared %select{deprecated|unavailable}1 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_property_declare, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_property_synthesize, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "property synthesized here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by___block, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses setup of __block variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_cleanup, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of variable with __attribute__((cleanup))", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_cxx_catch, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of catch block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_cxx_try, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of try block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_autoreleasepool, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses auto release push of @autoreleasepool block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_catch, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of @catch block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_finally, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of @finally block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_ownership, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of retaining variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_synchronized, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of @synchronized block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_objc_try, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of @try block", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_variable_init, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses variable initialization", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_variable_non_pod, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of non-POD variable", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_variable_nontriv_destructor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses variable with a non-trivial destructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_vla, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of variable length array", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_vla_type_alias, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of VLA type alias", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protected_by_vla_typedef, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "jump bypasses initialization of VLA typedef", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protocol_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "protocol is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protocol_decl_undefined, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "protocol %0 has no definition", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_protocol_property_declare, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "it could also be property of type %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_pure_virtual_function, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "unimplemented pure virtual method %0 in %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_receiver_class_declared, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "receiver is instance of class declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_receiver_is_id, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "receiver is treated with 'id' type for purpose of method lookup", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ref_or_ptr_member_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{reference|pointer}0 member declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ref_subobject_of_member_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "member with reference subobject declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_ref_var_local_bind, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "binding reference variable %0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_refconst_member_not_initialized, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{const|reference}0 member %1 will never be initialized", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_reference_is_return_value, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%0 returns a reference", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_referenced_class_template, CLASS_ERROR, (unsigned)diag::Severity::Error, "class template declared here", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(note_reinterpret_updowncast_use_static, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use 'static_cast' to adjust the pointer correctly while %select{upcasting|downcasting}0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_related_result_type_explicit, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{overridden|current}0 method is explicitly declared 'instancetype'%select{| and is expected to return an instance of its class type}0", 0, SFINAE_Suppress, false, false, 20)
+DIAG(note_related_result_type_family, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{overridden|current}0 method is part of the '%select{|alloc|copy|init|mutableCopy|new|autorelease|dealloc|finalize|release|retain|retainCount|self}1' method family%select{| and is expected to return an instance of its class type}0", 0, SFINAE_Suppress, false, false, 20)
+DIAG(note_related_result_type_inferred, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{class|instance}0 method %1 is assumed to return an instance of its receiver type (%2)", 0, SFINAE_Suppress, false, false, 20)
+DIAG(note_related_result_type_overridden, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "overridden method returns an instance of its class type", 0, SFINAE_Suppress, false, false, 20)
+DIAG(note_remove_abs, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove the call to '%0' since unsigned values cannot be negative", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_replace_abs_function, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use function '%0' instead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_sentinel_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{function|method|block}0 has been explicitly marked sentinel here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_specialized_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "attempt to specialize declaration here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_specialized_entity, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "explicitly specialized declaration is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_string_plus_scalar_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use array indexing to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_strlcpycat_wrong_size, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "change size argument to be the size of the destination", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_strncat_wrong_size, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "change the argument to be the free space in the destination buffer minus the terminating null byte", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_struct_class_suggestion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean %select{struct|interface|class}0 here?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_suppressed_class_declare, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class with specified objc_requires_property_definitions attribute is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_surrounding_namespace_ends_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "surrounding namespace with visibility attribute ends here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_surrounding_namespace_starts_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "surrounding namespace with visibility attribute starts here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_switch_conversion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conversion to %select{integral|enumeration}0 type %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_arg_internal_object, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "non-type template argument refers to %select{function|object}0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_arg_refers_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "non-type template argument refers here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_arg_refers_here_func, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template argument refers to function template %0, here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_class_explicit_specialization_was_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class template %0 was explicitly specialized here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_class_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of template class %0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_class_instantiation_was_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "class template %0 was instantiated here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_decl_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_declared_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{function template|class template|variable template|type alias template|template template parameter}0 %1 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_default_arg_checking, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "while checking a default template argument used here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_enum_def_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of enumeration %q0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_exception_spec_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of exception specification for %0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_member_class_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of member class %0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_member_function_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of member function %q0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_nontype_parm_different_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template non-type parameter has a different type %0 in template argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_nontype_parm_prev_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous non-type template parameter with type %0 is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_param_different_kind, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template parameter has a different kind in template argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_param_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "template parameter is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_param_list_different_arity, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{too few|too many}0 template parameters in template template argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_param_prev_default_arg, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous default template argument defined here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_parameter_pack_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous %select{template type|non-type template|template template}0 parameter%select{| pack}1 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_parameter_pack_non_pack, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{template type|non-type template|template template}0 parameter%select{| pack}1 does not match %select{template type|non-type template|template template}0 parameter%select{ pack|}1 in template argument", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_prev_declaration, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous template %select{declaration|template parameter}0 is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_recursion_depth, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use -ftemplate-depth=N to increase recursive template instantiation depth", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_static_data_member_def_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of static data member %q0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_type_alias_instantiation_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of template type alias %0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_unnamed_type_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "unnamed type used in template argument was declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_template_variable_def_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in instantiation of variable template specialization %q0 requested here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_transparent_union_first_field_size_align, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{alignment|size}0 of first field is %1 bits", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_typecheck_member_reference_suggestion, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to use '.' instead?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_typedef_changes_linkage, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use a tag name here to establish linkage prior to definition", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_typename_refers_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "referenced member %0 is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_uninit_fixit_remove_cond, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "remove the %select{'%1' if its condition|condition if it}0 is always %select{false|true}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_uninit_in_this_constructor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "during field initialization in %select{this|the implicit default}0 constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_uninit_reference_member, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "uninitialized reference member is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_uninit_var_def, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "variable %0 is declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_uninit_var_use, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{uninitialized use occurs|variable is captured by block}0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_unreachable_silence, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "silence by adding parentheses to mark code as explicitly dead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_use_thread_local, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use 'thread_local' to allow this", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_used_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "used here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_used_in_initialization_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "used in initialization here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_user_declared_ctor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "implicit default constructor suppressed by user-declared constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{|previous }0using declaration", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_class_member_workaround, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "use %select{an alias declaration|a typedef declaration|a reference}0 instead", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_conflict, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conflicting declaration", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_constructor_conflict_current_ctor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "conflicting constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_constructor_conflict_previous_ctor, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous constructor", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_constructor_conflict_previous_using, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previously inherited here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_constructor_ellipsis, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "constructor declared with ellipsis here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_decl_target, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "target of using declaration", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_using_value_decl_missing_typename, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "add 'typename' to treat this using declaration as a type", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_value_initialization_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "in value-initialization of type %0 here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_var_fixit_add_initialization, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "initialize the variable %0 to silence this warning", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_var_prev_partial_spec_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "previous declaration of variable template partial specialization is here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_vbase_moved_here, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "%select{%1 is a virtual base class of base class %2 declared here|virtual base class %1 declared here}0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_which_delegates_to, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "which delegates to", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_while_in_implementation, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "detected while default synthesizing properties in class implementation", 0, SFINAE_Suppress, false, false, 2)
+DIAG(note_within_field_of_type, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "within field of type %0 declared here", 0, SFINAE_Suppress, false, false, 2)
+DIAG(override_keyword_hides_virtual_member_function, CLASS_ERROR, (unsigned)diag::Severity::Error, "non-virtual member function marked '%0' hides virtual member %select{function|functions}1", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(override_keyword_only_allowed_on_virtual_member_functions, CLASS_ERROR, (unsigned)diag::Severity::Error, "only virtual member functions can be marked '%0'", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(warn_abs_too_small, CLASS_WARNING, (unsigned)diag::Severity::Warning, "absolute value function %0 given an argument of type %1 but has parameter of type %2 which may cause truncation of value", 6, SFINAE_Suppress, false, false, 2)
+DIAG(warn_abstract_final_class, CLASS_WARNING, (unsigned)diag::Severity::Warning, "abstract class is marked '%select{final|sealed}0'", 7, SFINAE_Suppress, false, false, 2)
+DIAG(warn_abstract_vbase_init_ignored, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "initializer for virtual base class %0 of abstract class %1 will never be used", 8, SFINAE_Suppress, false, false, 2)
+DIAG(warn_access_decl_deprecated, CLASS_WARNING, (unsigned)diag::Severity::Warning, "access declarations are deprecated; use using declarations instead", 114, SFINAE_Suppress, false, false, 21)
+DIAG(warn_accessor_property_type_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "type of property %0 does not match type of accessor %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_addition_in_bitshift, CLASS_WARNING, (unsigned)diag::Severity::Warning, "operator '%0' has lower precedence than '%1'; '%1' will be evaluated first", 394, SFINAE_Suppress, false, false, 2)
+DIAG(warn_address_of_reference_bool_conversion, CLASS_WARNING, (unsigned)diag::Severity::Warning, "reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true", 456, SFINAE_Suppress, false, false, 17)
+DIAG(warn_address_of_reference_null_compare, CLASS_WARNING, (unsigned)diag::Severity::Warning, "reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to %select{true|false}0", 441, SFINAE_Suppress, false, false, 2)
+DIAG(warn_alias_to_weak_alias, CLASS_WARNING, (unsigned)diag::Severity::Warning, "alias will always resolve to %0 even if weak definition of alias %1 is overridden", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_alias_with_section, CLASS_WARNING, (unsigned)diag::Severity::Warning, "alias will not be in section '%0' but in the same section as the aliasee", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_anon_bitfield_width_exceeds_type_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "size of anonymous bit-field (%0 bits) exceeds size of its type; value will be truncated to %1 bits", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_arc_lifetime_result_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ARC %select{unused|__unsafe_unretained|__strong|__weak|__autoreleasing}0 lifetime qualifier on return type is ignored", 208, SFINAE_Suppress, false, false, 5)
+DIAG(warn_arc_literal_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "assigning %select{array literal|dictionary literal|numeric literal|boxed expression|<should not happen>|block literal}0 to a weak %select{property|variable}1; object will be released after assignment", 26, SFINAE_Suppress, false, false, 5)
+DIAG(warn_arc_object_memaccess, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{destination for|source of}0 this %1 call is a pointer to ownership-qualified type %2", 22, SFINAE_Suppress, false, false, 5)
+DIAG(warn_arc_perform_selector_leaks, CLASS_WARNING, (unsigned)diag::Severity::Warning, "performSelector may cause a leak because its selector is unknown", 23, SFINAE_Suppress, false, false, 2)
+DIAG(warn_arc_possible_repeated_use_of_weak, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "weak %select{variable|property|implicit property|instance variable}0 %1 may be accessed multiple times in this %select{function|method|block|lambda}2 and may be unpredictably set to nil; assign to a strong variable to keep the object alive", 21, SFINAE_Suppress, false, false, 2)
+DIAG(warn_arc_repeated_use_of_weak, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "weak %select{variable|property|implicit property|instance variable}0 %1 is accessed multiple times in this %select{function|method|block|lambda}2 but may be unpredictably set to nil; assign to a strong variable to keep the object alive", 24, SFINAE_Suppress, false, false, 2)
+DIAG(warn_arc_retain_cycle, CLASS_WARNING, (unsigned)diag::Severity::Warning, "capturing %0 strongly in this block is likely to lead to a retain cycle", 25, SFINAE_Suppress, false, false, 19)
+DIAG(warn_arc_retained_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "assigning retained object to %select{weak|unsafe_unretained}0 %select{property|variable}1; object will be released after assignment", 26, SFINAE_Suppress, false, false, 5)
+DIAG(warn_arc_retained_property_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "assigning retained object to unsafe property; object will be released after assignment", 26, SFINAE_Suppress, false, false, 5)
+DIAG(warn_arc_strong_pointer_objc_pointer, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "method parameter of type %0 with no explicit ownership", 152, SFINAE_Suppress, false, false, 10)
+DIAG(warn_array_index_exceeds_bounds, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array index %0 is past the end of the array (which contains %1 element%s2)", 27, SFINAE_Suppress, false, false, 2)
+DIAG(warn_array_index_precedes_bounds, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array index %0 is before the beginning of the array", 27, SFINAE_Suppress, false, false, 2)
+DIAG(warn_array_new_too_large, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array is too large (%0 elements)", 43, SFINAE_Suppress, false, false, 2)
+DIAG(warn_asm_label_on_auto_decl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignored asm label '%0' on automatic variable", 0, SFINAE_Suppress, false, false, 11)
+DIAG(warn_asm_mismatched_size_modifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "value size does not match register size specified by the constraint and modifier", 30, SFINAE_Suppress, false, false, 11)
+DIAG(warn_assume_side_effects, CLASS_WARNING, (unsigned)diag::Severity::Warning, "the argument to __assume has side effects that will be discarded", 32, SFINAE_Suppress, false, false, 2)
+DIAG(warn_atomic_op_has_invalid_memory_order, CLASS_WARNING, (unsigned)diag::Severity::Warning, "memory order argument to atomic operation is invalid", 33, SFINAE_Suppress, false, false, 2)
+DIAG(warn_atomic_property_rule, CLASS_WARNING, (unsigned)diag::Severity::Warning, "writable atomic property %0 cannot pair a synthesized %select{getter|setter}1 with a user defined %select{getter|setter}2", 35, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attr_on_unconsumable_class, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "consumed analysis attribute is attached to member of class '%0' which isn't marked as consumable", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_after_definition_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 after definition is ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_dll_instantiated_base_class, CLASS_WARNING, (unsigned)diag::Severity::Warning, "propagating dll attribute to %select{already instantiated|explicitly specialized}0 base class template %select{without dll attribute|with different dll attribute}1 is not supported", 476, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_dll_redeclaration, CLASS_WARNING, (unsigned)diag::Severity::Warning, "redeclaration of %q0 should not add %q1 attribute", 130, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_dllimport_static_field_definition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "definition of dllimport static field", 131, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_iboutlet, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute can only be applied to instance variables or properties", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_ignored_for_field_of_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute ignored for field of type %1", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_invalid_on_definition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' attribute cannot be specified on a definition", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_malloc_pointer_only, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'malloc' attribute only applies to functions returning a pointer type", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_nonnull_no_pointers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'nonnull' attribute applied to function with no pointer arguments", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_nonnull_parm_no_args, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'nonnull' attribute when used on parameters takes no arguments", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_not_on_decl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute ignored when parsing type", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_pointers_only, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute only applies to pointer arguments", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_precede_definition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute declaration must precede definition", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_protected_visibility, CLASS_WARNING, (unsigned)diag::Severity::Warning, "target does not support 'protected' visibility; using 'default'", 478, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_requires_functions_or_static_globals, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 only applies to variables with static storage duration and functions", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_return_pointers_only, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute only applies to return values that are pointers", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_sentinel_named_arguments, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'sentinel' attribute requires named arguments", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_sentinel_not_variadic, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'sentinel' attribute only supported for variadic %select{functions|blocks}0", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_type_not_supported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute argument not supported: %1", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_unknown_visibility, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown visibility %0", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_void_function_method, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 cannot be applied to %select{functions|Objective-C method}1 without return value", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_weak_on_field, CLASS_WARNING, (unsigned)diag::Severity::Warning, "__weak attribute cannot be specified on a field declaration", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_weak_on_local, CLASS_WARNING, (unsigned)diag::Severity::Warning, "__weak attribute cannot be specified on an automatic variable when ARC is not enabled", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_attribute_wrong_decl_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute only applies to %select{functions|unions|variables and functions|functions and methods|parameters|functions, methods and blocks|functions, methods, and classes|functions, methods, and parameters|classes|variables|methods|variables, functions and labels|fields and global variables|structs|variables, functions and tag types|thread-local variables|variables and fields|variables, data members and tag types|types and namespaces|Objective-C interfaces|methods and properties|struct or union|struct, union or class|types|Objective-C instance methods|init methods of interface or class extension declarations|variables, functions and classes|Objective-C protocols|functions and global variables|structs or typedefs|interface or protocol declarations}1", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_auto_implicit_atomic_property, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "property is assumed atomic when auto-synthesizing the property", 210, SFINAE_Suppress, false, false, 2)
+DIAG(warn_auto_readonly_iboutlet_property, CLASS_WARNING, (unsigned)diag::Severity::Warning, "readonly IBOutlet property %0 when auto-synthesized may not work correctly with 'nib' loader", 366, SFINAE_Suppress, false, false, 2)
+DIAG(warn_auto_synthesizing_protocol_property, CLASS_WARNING, (unsigned)diag::Severity::Warning, "auto property synthesis will not synthesize property %0 declared in protocol %1", 325, SFINAE_Suppress, false, false, 2)
+DIAG(warn_auto_var_is_id, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'auto' deduced as 'id' in declaration of %0", 39, SFINAE_Suppress, false, false, 2)
+DIAG(warn_autosynthesis_property_ivar_match, CLASS_WARNING, (unsigned)diag::Severity::Warning, "autosynthesized property %0 will use %select{|synthesized}1 instance variable %2, not existing instance variable %3", 307, SFINAE_Suppress, false, false, 2)
+DIAG(warn_availability_unknown_platform, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown platform %0 in availability macro", 40, SFINAE_Suppress, false, false, 2)
+DIAG(warn_availability_version_ordering, CLASS_WARNING, (unsigned)diag::Severity::Warning, "feature cannot be %select{introduced|deprecated|obsoleted}0 in %1 version %2 before it was %select{introduced|deprecated|obsoleted}3 in version %4; attribute ignored", 40, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bad_function_cast, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "cast from function call of type %0 to non-matching type %1", 44, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bad_receiver_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "receiver type %0 is not 'id' or interface pointer, consider casting it to 'id'", 367, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bind_ref_member_to_parameter, CLASS_WARNING, (unsigned)diag::Severity::Warning, "binding reference member %0 to stack allocated parameter %1", 105, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bind_ref_member_to_temporary, CLASS_WARNING, (unsigned)diag::Severity::Warning, "binding reference %select{|subobject of }1member %0 to a temporary value", 105, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bitfield_width_exceeds_type_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be truncated to %2 bits", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bitwise_and_in_bitwise_or, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'&' within '|'", 47, SFINAE_Suppress, false, false, 2)
+DIAG(warn_bool_switch_condition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "switch condition has boolean value", 433, SFINAE_Suppress, false, false, 2)
+DIAG(warn_braces_around_scalar_init, CLASS_WARNING, (unsigned)diag::Severity::Warning, "braces around scalar initializer", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_break_binds_to_switch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'break' is bound to loop, GCC binds it to switch", 176, SFINAE_Suppress, false, false, 2)
+DIAG(warn_builtin_unknown, CLASS_WARNING, (unsigned)diag::Severity::Error, "use of unknown builtin %0", 215, SFINAE_Suppress, false, false, 2)
+DIAG(warn_call_to_pure_virtual_member_function_from_ctor_dtor, CLASS_WARNING, (unsigned)diag::Severity::Warning, "call to pure virtual member function %0; overrides of %0 in subclasses are not available in the %select{constructor|destructor}1 of %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_call_wrong_number_of_arguments, CLASS_WARNING, (unsigned)diag::Severity::Warning, "too %select{few|many}0 arguments in call to %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cannot_pass_non_pod_arg_to_vararg, CLASS_WARNING, (unsigned)diag::Severity::Error, "cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic %select{function|block|method|constructor}2; call will abort at runtime", 298, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cannot_resolve_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "cannot resolve lock expression", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_case_empty_range, CLASS_WARNING, (unsigned)diag::Severity::Warning, "empty case range specified", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_case_value_overflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overflow converting case value to switch condition type (%0 to %1)", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cast_align, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "cast from %0 to %1 increases required alignment from %2 to %3", 81, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cast_pointer_from_sel, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cast of type %0 to %1 is deprecated; use sel_getName instead", 82, SFINAE_Suppress, false, false, 2)
+DIAG(warn_category_method_impl_match, CLASS_WARNING, (unsigned)diag::Severity::Warning, "category is implementing a method which will also be implemented by its primary class", 324, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cconv_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "calling convention %0 ignored for this target", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cconv_varargs, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 calling convention ignored on variadic function", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cfstring_truncated, CLASS_WARNING, (unsigned)diag::Severity::Warning, "input conversion stopped due to an input byte that does not belong to the input codeset UTF-8", 3, SFINAE_Suppress, false, false, 2)
+DIAG(warn_class_method_not_found, CLASS_WARNING, (unsigned)diag::Severity::Warning, "class method %objcclass0 not found (return type defaults to 'id')", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_class_method_not_found_with_typo, CLASS_WARNING, (unsigned)diag::Severity::Warning, "class method %objcclass0 not found (return type defaults to 'id'); did you mean %objcclass2?", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cleanup_ext, CLASS_WARNING, (unsigned)diag::Severity::Warning, "GCC does not allow the 'cleanup' attribute argument to be anything other than a simple identifier", 176, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cocoa_naming_owned_rule, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property follows Cocoa naming convention for returning 'owned' objects", 321, SFINAE_Suppress, false, false, 2)
+DIAG(warn_collection_expr_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "collection expression type %0 may not respond to %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_comparison_always, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1", 437, SFINAE_Suppress, false, false, 2)
+DIAG(warn_comparison_bitwise_always, CLASS_WARNING, (unsigned)diag::Severity::Warning, "bitwise comparison always evaluates to %select{false|true}0", 437, SFINAE_Suppress, false, false, 2)
+DIAG(warn_comparison_of_mixed_enum_types, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison of two values with different enumeration types%diff{ ($ and $)|}0,1", 148, SFINAE_Suppress, false, false, 2)
+DIAG(warn_concatenated_nsarray_literal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "concatenated NSString literal for an NSArray expression - possibly missing a comma", 331, SFINAE_Suppress, false, false, 2)
+DIAG(warn_condition_is_assignment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "using the result of an assignment as a condition without parentheses", 347, SFINAE_Suppress, false, false, 2)
+DIAG(warn_condition_is_idiomatic_assignment, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "using the result of an assignment as a condition without parentheses", 205, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_overriding_param_modifiers, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting distributed object modifiers on parameter type in declaration of %0", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_overriding_param_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting parameter types in declaration of %0%diff{: $ vs $|}1,2", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_overriding_ret_type_modifiers, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting distributed object modifiers on return type in declaration of %0", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_overriding_ret_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting return type in declaration of %0%diff{: $ vs $|}1,2", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_overriding_variadic, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting variadic declaration of method and its implementation", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_param_modifiers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conflicting distributed object modifiers on parameter type in implementation of %0", 127, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_param_types, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conflicting parameter types in implementation of %0%diff{: $ vs $|}1,2", 269, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_ret_type_modifiers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conflicting distributed object modifiers on return type in implementation of %0", 127, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_ret_types, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conflicting return type in implementation of %0%diff{: $ vs $|}1,2", 270, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conflicting_variadic, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conflicting variadic declaration of method and its implementation", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conv_to_base_not_used, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conversion function converting %0 to its base class %1 will never be used", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conv_to_self_not_used, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conversion function converting %0 to itself will never be used", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_conv_to_void_not_used, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conversion function converting %0 to %1 will never be used", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_constexpr_body_invalid_stmt, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of this statement in a constexpr %select{function|constructor}0 is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_constexpr_body_multiple_return, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "multiple return statements in constexpr function is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_constexpr_body_no_return, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "constexpr function with no return statements is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_constexpr_local_var, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable declaration in a constexpr %select{function|constructor}0 is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_constexpr_type_definition, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "type definition in a constexpr %select{function|constructor}0 is incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_compat_init_capture, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "initialized lambda captures are incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 3)
+DIAG(warn_cxx11_compat_variable_template, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable templates are incompatible with C++ standards before C++1y", 71, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx11_gnu_attribute_on_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 ignored, because it cannot be applied to a type", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx1y_compat_constexpr_not_const, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'constexpr' non-static member function will not be implicitly 'const' in C++1y; add 'const' to avoid a change in behavior", 96, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx1y_compat_static_assert_no_message, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "static_assert with no message is incompatible with C++ standards before C++1z", 69, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_array_size_conversion, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion from array size expression of type %0 to %select{integral|enumeration}1 type %2 is incompatible with C++98", 76, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_auto_type_specifier, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'auto' type specifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_cast_fn_obj, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "cast between pointer-to-function and pointer-to-object is incompatible with C++98", 76, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_constexpr, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'constexpr' specifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_ctor_list_init, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "constructor call from initializer list is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_delegating_ctor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "delegating constructors are incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_empty_scalar_initializer, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "scalar initialized from empty initializer list is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_enum_friend, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "befriending enumeration type %0 is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_enum_nested_name_spec, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "enumeration type in nested name specifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_explicit_conversion_functions, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit conversion functions are incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_explicit_instantiation_after_specialization, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit instantiation of %0 that occurs after an explicit specialization is incompatible with C++98", 76, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_friend_is_member, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "friend declaration naming a member of the declaring class is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_goto_into_protected_scope, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "goto would jump into protected scope in C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_indirect_goto_in_protected_scope, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "indirect goto might cross protected scopes in C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_initializer_list_init, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "initialization of initializer_list object is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_non_static_member_use, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of non-static data member %0 in an unevaluated context is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_nonclass_type_friend, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "non-class friend type %0 is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_nontrivial_union_or_anon_struct_member, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{anonymous struct|union}0 member %1 with a non-trivial %select{constructor|copy constructor|move constructor|copy assignment operator|move assignment operator|destructor}2 is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_pass_non_pod_arg_to_vararg, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "passing object of trivial but non-POD type %0 through variadic %select{function|block|method|constructor}1 is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_reference_list_init, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "reference initialized from initializer list is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_sfinae_access_control, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "substitution failure due to access control is incompatible with C++98", 73, SFINAE_Report, false, false, 2)
+DIAG(warn_cxx98_compat_static_data_member_in_union, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "static data member %0 in union is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_switch_into_protected_scope, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "switch case would be in a protected scope in C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_temp_copy, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{copying variable|copying parameter|returning object|throwing object|copying member subobject|copying array element|allocating object|copying temporary|initializing base subobject|initializing vector element}1 of type %2 when binding a reference to a temporary would %select{invoke an inaccessible constructor|find no viable constructor|find ambiguous constructors|invoke a deleted constructor}0 in C++98", 74, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_arg_extra_parens, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "redundant parentheses surrounding address non-type template argument are incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_arg_local_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "local type %0 as template argument is incompatible with C++98", 75, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_arg_null, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of null pointer as non-type template argument is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_arg_object_internal, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "non-type template argument referring to %select{function|object}0 %1 with internal linkage is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_arg_unnamed_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unnamed type as template argument is incompatible with C++98", 77, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_outside_of_template, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of 'template' keyword outside of a template is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_parameter_default_in_function_template, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "default template arguments for a function template are incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_template_spec_decl_out_of_scope, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{class template|class template partial|variable template|variable template partial|function template|member function|static data member|member class|member enumeration}0 specialization of %1 outside namespace %2 is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_typename_outside_of_template, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of 'typename' outside of a template is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_unelaborated_friend_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "befriending %1 without '%select{struct|interface|union|class|enum}0' keyword is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_unicode_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%0' type specifier is incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx98_compat_using_decl_constructor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "inheriting constructors are incompatible with C++98", 73, SFINAE_Suppress, false, false, 2)
+DIAG(warn_cxx_ms_struct, CLASS_WARNING, (unsigned)diag::Severity::Error, "ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions", 222, SFINAE_Suppress, false, false, 2)
+DIAG(warn_dangling_std_initializer_list, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array backing the initializer list will be destroyed at the end of %select{the full-expression|the constructor}0", 106, SFINAE_Suppress, false, false, 2)
+DIAG(warn_dealloc_in_category, CLASS_WARNING, (unsigned)diag::Severity::Warning, "-dealloc is being overridden in a category", 108, SFINAE_Suppress, false, false, 2)
+DIAG(warn_decl_in_param_list, CLASS_WARNING, (unsigned)diag::Severity::Warning, "declaration of %0 will not be visible outside of this function", 503, SFINAE_Suppress, false, false, 2)
+DIAG(warn_decl_shadow, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration shadows a %select{local variable|variable in %2|static data member of %2|field of %2}1", 390, SFINAE_Suppress, false, false, 2)
+DIAG(warn_declspec_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 is ignored, place it after \"%select{class|struct|union|interface|enum}1\" to apply attribute to type declaration", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_def_missing_case1, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "enumeration value %0 not explicitly handled in switch", 435, SFINAE_Suppress, false, false, 2)
+DIAG(warn_def_missing_case2, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "enumeration values %0 and %1 not explicitly handled in switch", 435, SFINAE_Suppress, false, false, 2)
+DIAG(warn_def_missing_case3, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "enumeration values %0, %1, and %2 not explicitly handled in switch", 435, SFINAE_Suppress, false, false, 2)
+DIAG(warn_def_missing_cases, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 enumeration values not explicitly handled in switch: %1, %2, %3...", 435, SFINAE_Suppress, false, false, 2)
+DIAG(warn_default_atomic_custom_getter_setter, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "atomic by default property %0 has a user defined %select{getter|setter}1 (property should be marked 'atomic' if this is intended)", 103, SFINAE_Suppress, false, false, 2)
+DIAG(warn_delegating_ctor_cycle, CLASS_WARNING, (unsigned)diag::Severity::Error, "constructor for %0 creates a delegation cycle", 111, SFINAE_Suppress, false, false, 2)
+DIAG(warn_delete_abstract_non_virtual_dtor, CLASS_WARNING, (unsigned)diag::Severity::Warning, "delete called on %0 that is abstract but has non-virtual destructor", 113, SFINAE_Suppress, false, false, 2)
+DIAG(warn_delete_array_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'delete' applied to a pointer-to-array type %0 treated as delete[]", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_delete_incomplete, CLASS_WARNING, (unsigned)diag::Severity::Warning, "deleting pointer to incomplete type %0 may cause undefined behavior", 112, SFINAE_Suppress, false, false, 2)
+DIAG(warn_delete_non_virtual_dtor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "delete called on %0 that has virtual functions but non-virtual destructor", 113, SFINAE_Suppress, false, false, 2)
+DIAG(warn_deprecated, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 is deprecated", 115, SFINAE_Suppress, false, false, 21)
+DIAG(warn_deprecated_copy_operation, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "definition of implicit copy %select{constructor|assignment operator}1 for %0 is deprecated because it has a user-declared %select{copy %select{assignment operator|constructor}1|destructor}2", 114, SFINAE_Suppress, false, false, 21)
+DIAG(warn_deprecated_def, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "Implementing deprecated %select{method|class|category}0", 116, SFINAE_Suppress, false, false, 2)
+DIAG(warn_deprecated_fwdclass_message, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 may be deprecated because the receiver type is unknown", 115, SFINAE_Suppress, false, false, 21)
+DIAG(warn_deprecated_message, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 is deprecated: %1", 115, SFINAE_Suppress, false, false, 21)
+DIAG(warn_deprecated_string_literal_conversion, CLASS_WARNING, (unsigned)diag::Severity::Warning, "conversion from string literal to %0 is deprecated", 58, SFINAE_Suppress, false, false, 21)
+DIAG(warn_direct_ivar_access, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "instance variable %0 is being directly accessed", 123, SFINAE_Suppress, false, false, 2)
+DIAG(warn_division_by_zero, CLASS_WARNING, (unsigned)diag::Severity::Warning, "division by zero is undefined", 129, SFINAE_Suppress, false, false, 2)
+DIAG(warn_double_const_requires_fp64, CLASS_WARNING, (unsigned)diag::Severity::Warning, "double precision constant requires cl_khr_fp64, casting to single precision", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_double_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "acquiring %0 '%1' that is already held", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_dup_category_def, CLASS_WARNING, (unsigned)diag::Severity::Warning, "duplicate definition of category %1 on interface %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_duplicate_attribute, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 is already applied with different parameters", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_duplicate_attribute_exact, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute %0 is already applied", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_duplicate_enum_values, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "element %0 has been implicitly assigned %1 which another element has been assigned", 139, SFINAE_Suppress, false, false, 2)
+DIAG(warn_duplicate_method_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "multiple declarations of method %0 found and ignored", 141, SFINAE_Suppress, false, false, 2)
+DIAG(warn_duplicate_protocol_def, CLASS_WARNING, (unsigned)diag::Severity::Warning, "duplicate protocol definition of %0 is ignored", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_dyn_class_memaccess, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{destination for|source of|first operand of|second operand of}0 this %1 call is a pointer to %select{|class containing a }2dynamic class %3; vtable pointer will be %select{overwritten|copied|moved|compared}4", 142, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_for_body, CLASS_WARNING, (unsigned)diag::Severity::Warning, "for loop has empty body", 145, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_format_string, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string is empty", 171, SFINAE_Suppress, false, false, 22)
+DIAG(warn_empty_if_body, CLASS_WARNING, (unsigned)diag::Severity::Warning, "if statement has empty body", 145, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_parens_are_function_decl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "empty parentheses interpreted as a function declaration", 502, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_range_based_for_body, CLASS_WARNING, (unsigned)diag::Severity::Warning, "range-based for loop has empty body", 145, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_switch_body, CLASS_WARNING, (unsigned)diag::Severity::Warning, "switch statement has empty body", 145, SFINAE_Suppress, false, false, 2)
+DIAG(warn_empty_while_body, CLASS_WARNING, (unsigned)diag::Severity::Warning, "while loop has empty body", 145, SFINAE_Suppress, false, false, 2)
+DIAG(warn_enum_value_overflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overflow in enumeration value", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_equality_with_extra_parens, CLASS_WARNING, (unsigned)diag::Severity::Warning, "equality comparison with extraneous parentheses", 348, SFINAE_Suppress, false, false, 2)
+DIAG(warn_exception_caught_by_earlier_handler, CLASS_WARNING, (unsigned)diag::Severity::Warning, "exception of type %0 will be caught by earlier handler", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_exception_spec_deprecated, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "dynamic exception specifications are deprecated", 114, SFINAE_Suppress, false, false, 21)
+DIAG(warn_exit_time_destructor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration requires an exit-time destructor", 151, SFINAE_Suppress, false, false, 2)
+DIAG(warn_expecting_lock_held_on_loop, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "expecting %0 '%1' to be held at start of each loop", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_expecting_locked, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "expecting %0 '%1' to be held at the end of function", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_explicit_instantiation_inline_0x, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit instantiation cannot be 'inline'", 57, SFINAE_Suppress, false, false, 2)
+DIAG(warn_explicit_instantiation_must_be_global_0x, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit instantiation of %0 must occur at global scope", 57, SFINAE_Suppress, false, false, 2)
+DIAG(warn_explicit_instantiation_out_of_scope_0x, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit instantiation of %0 not in a namespace enclosing %1", 57, SFINAE_Suppress, false, false, 2)
+DIAG(warn_explicit_instantiation_unqualified_wrong_namespace_0x, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit instantiation of %q0 must occur in namespace %1", 57, SFINAE_Suppress, false, false, 2)
+DIAG(warn_extern_init, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'extern' variable has an initializer", 155, SFINAE_Suppress, false, false, 2)
+DIAG(warn_falloff_nonvoid_function, CLASS_WARNING, (unsigned)diag::Severity::Warning, "control reaches end of non-void function", 379, SFINAE_Suppress, false, false, 2)
+DIAG(warn_falloff_nonvoid_lambda, CLASS_WARNING, (unsigned)diag::Severity::Warning, "control reaches end of non-void lambda", 379, SFINAE_Suppress, false, false, 3)
+DIAG(warn_falloff_noreturn_function, CLASS_WARNING, (unsigned)diag::Severity::Warning, "function declared 'noreturn' should not return", 244, SFINAE_Suppress, false, false, 2)
+DIAG(warn_fallthrough_attr_invalid_placement, CLASS_WARNING, (unsigned)diag::Severity::Warning, "fallthrough annotation does not directly precede switch label", 213, SFINAE_Suppress, false, false, 2)
+DIAG(warn_fallthrough_attr_unreachable, CLASS_WARNING, (unsigned)diag::Severity::Warning, "fallthrough annotation in unreachable code", 213, SFINAE_Suppress, false, false, 2)
+DIAG(warn_field_is_uninit, CLASS_WARNING, (unsigned)diag::Severity::Warning, "field %0 is uninitialized when used here", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_float_overflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "magnitude of floating-point constant too large for type %0; maximum is %1", 255, SFINAE_Suppress, false, false, 2)
+DIAG(warn_float_underflow, CLASS_WARNING, (unsigned)diag::Severity::Warning, "magnitude of floating-point constant too small for type %0; minimum is %1", 255, SFINAE_Suppress, false, false, 2)
+DIAG(warn_floatingpoint_eq, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "comparing floating point with == or != is unsafe", 163, SFINAE_Suppress, false, false, 2)
+DIAG(warn_format_argument_needs_cast, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{values of type|enum values with underlying type}2 '%0' should not be used as format arguments; add an explicit cast to %1 instead", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_conversion_argument_type_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format specifies type %0 but the argument has %select{type|underlying type}2 %1", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_invalid_conversion, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid conversion specifier '%0'", 166, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_invalid_positional_specifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid position specified for %select{field width|field precision}0", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_mix_positional_nonpositional_args, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot mix positional and non-positional arguments in format string", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_non_standard, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%0' %select{length modifier|conversion specifier}1 is not supported by ISO C", 167, SFINAE_Suppress, false, false, 2)
+DIAG(warn_format_non_standard_conversion_spec, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "using length modifier '%0' with conversion specifier '%1' is not supported by ISO C", 167, SFINAE_Suppress, false, false, 2)
+DIAG(warn_format_non_standard_positional_arg, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "positional arguments are not supported by ISO C", 167, SFINAE_Suppress, false, false, 2)
+DIAG(warn_format_nonliteral, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "format string is not a string literal", 168, SFINAE_Suppress, false, false, 2)
+DIAG(warn_format_nonliteral_noargs, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string is not a string literal (potentially insecure)", 169, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_nonsensical_length, CLASS_WARNING, (unsigned)diag::Severity::Warning, "length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_string_is_wide_literal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string should not be a wide string", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_format_zero_positional_specifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "position arguments in format strings start counting at 1 (not 0)", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_forward_class_redefinition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "redefinition of forward class %0 of a typedef name of an object type is ignored", 310, SFINAE_Suppress, false, false, 2)
+DIAG(warn_fun_excludes_mutex, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "cannot call function '%1' while %0 '%2' is held", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_fun_requires_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "calling function '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_fun_requires_lock_precise, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "calling function '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 447, SFINAE_Suppress, false, false, 2)
+DIAG(warn_function_def_in_objc_container, CLASS_WARNING, (unsigned)diag::Severity::Warning, "function definition inside an Objective-C container is deprecated", 175, SFINAE_Suppress, false, false, 2)
+DIAG(warn_gc_attribute_weak_on_local, CLASS_WARNING, (unsigned)diag::Severity::Warning, "Objective-C GC does not allow weak variables on the stack", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_global_constructor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration requires a global constructor", 177, SFINAE_Suppress, false, false, 2)
+DIAG(warn_global_destructor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration requires a global destructor", 177, SFINAE_Suppress, false, false, 2)
+DIAG(warn_gnu_inline_attribute_requires_inline, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'gnu_inline' attribute requires function to be marked 'inline', attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_iboutlet_object_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{instance variable|property}2 with %0 attribute must be an object type (invalid %1)", 242, SFINAE_Suppress, false, false, 2)
+DIAG(warn_iboutletcollection_property_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "IBOutletCollection properties should be copy/strong and not assign", 242, SFINAE_Suppress, false, false, 2)
+DIAG(warn_identity_field_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "assigning %select{field|instance variable}0 to itself", 385, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ignored_ms_inheritance, CLASS_WARNING, (unsigned)diag::Severity::Warning, "inheritance model ignored on %select{primary template|partial specialization}0", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_illegal_constant_array_size, CLASS_EXTENSION, (unsigned)diag::Severity::Ignored, "size of static array must be an integer constant expression", 353, SFINAE_Suppress, false, false, 2)
+DIAG(warn_impcast_bitfield_precision_constant, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit truncation from %2 to bitfield changes value from %0 to %1", 46, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_bool_to_null_pointer, CLASS_WARNING, (unsigned)diag::Severity::Warning, "initialization of pointer of type %0 to null from a constant boolean expression", 48, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_complex_scalar, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion discards imaginary component: %0 to %1", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_different_enum_types, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit conversion from enumeration type %0 to different enumeration type %1", 149, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_float_integer, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion turns floating-point number into integer: %0 to %1", 162, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_float_precision, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion loses floating-point precision: %0 to %1", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_floating_point_to_bool, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit conversion turns floating-point number into bool: %0 to %1", 211, SFINAE_Suppress, false, false, 2)
+DIAG(warn_impcast_integer_64_32, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion loses integer precision: %0 to %1", 397, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_integer_precision, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion loses integer precision: %0 to %1", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_integer_precision_constant, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit conversion from %2 to %3 changes value from %0 to %1", 94, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_integer_sign, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion changes signedness: %0 to %1", 399, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_integer_sign_conditional, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "operand of ? changes signedness: %0 to %1", 399, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_literal_float_to_integer, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit conversion from %0 to %1 changes value from %2 to %3", 254, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_null_pointer_to_integer, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit conversion of NULL constant to %0", 305, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_objective_c_literal_to_bool, CLASS_WARNING, (unsigned)diag::Severity::Warning, "implicit boolean conversion of Objective-C object literal always evaluates to true", 313, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_pointer_to_bool, CLASS_WARNING, (unsigned)diag::Severity::Warning, "address of%select{| function| array}0 '%1' will always evaluate to 'true'", 355, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_string_literal_to_bool, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion turns string literal into bool: %0 to %1", 426, SFINAE_Suppress, false, false, 17)
+DIAG(warn_impcast_vector_scalar, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit conversion turns vector to scalar: %0 to %1", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_implements_nscopying, CLASS_WARNING, (unsigned)diag::Severity::Warning, "default assign attribute on property %0 which implements NSCopying protocol is not appropriate with -fobjc-gc[-only]", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_implicit_atomic_property, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "property is assumed atomic by default", 210, SFINAE_Suppress, false, false, 2)
+DIAG(warn_implicit_decl_requires_sysheader, CLASS_WARNING, (unsigned)diag::Severity::Warning, "declaration of built-in function '%1' requires inclusion of the header <%0>", 52, SFINAE_Suppress, false, false, 2)
+DIAG(warn_implicit_function_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "implicit declaration of function %0", 215, SFINAE_Suppress, false, false, 2)
+DIAG(warn_implicitly_retains_self, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior", 217, SFINAE_Suppress, false, false, 2)
+DIAG(warn_incompatible_qualified_id, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{%diff{assigning to $ from incompatible type $|assigning to type from incompatible type}0,1|%diff{passing $ to parameter of incompatible type $|passing type to parameter of incompatible type}0,1|%diff{returning $ from a function with incompatible result type $|returning type from a function with incompatible result type}0,1|%diff{converting $ to incompatible type $|converting type to incompatible type}0,1|%diff{initializing $ with an expression of incompatible type $|initializing type with an expression of incompatible type}0,1|%diff{sending $ to parameter of incompatible type $|sending type to parameter of incompatible type}0,1|%diff{casting $ to incompatible type $|casting type to incompatible type}0,1}2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_incompatible_vectors, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "incompatible vector types %select{%diff{assigning to $ from $|assigning to different types}0,1|%diff{passing $ to parameter of type $|passing to parameter of different type}0,1|%diff{returning $ from a function with result type $|returning from function with different return type}0,1|%diff{converting $ to type $|converting between types}0,1|%diff{initializing $ with an expression of type $|initializing with expression of different type}0,1|%diff{sending $ to parameter of type $|sending to parameter of different type}0,1|%diff{casting $ to type $|casting between types}0,1}2", 500, SFINAE_Suppress, false, false, 2)
+DIAG(warn_increment_bool, CLASS_WARNING, (unsigned)diag::Severity::Warning, "incrementing expression of type bool is deprecated", 117, SFINAE_Suppress, false, false, 21)
+DIAG(warn_indirection_through_null, CLASS_WARNING, (unsigned)diag::Severity::Warning, "indirection of non-volatile null pointer will be deleted, not trap", 306, SFINAE_Suppress, false, false, 2)
+DIAG(warn_infinite_recursive_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "all paths through this function will call itself", 228, SFINAE_Suppress, false, false, 2)
+DIAG(warn_init_list_constant_narrowing, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "constant expression evaluates to %0 which cannot be narrowed to type %1 in C++11", 64, SFINAE_Suppress, false, false, 2)
+DIAG(warn_init_list_type_narrowing, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "type %0 cannot be narrowed to %1 in initializer list in C++11", 64, SFINAE_Suppress, false, false, 2)
+DIAG(warn_init_list_variable_narrowing, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "non-constant-expression cannot be narrowed from type %0 to %1 in initializer list in C++11", 64, SFINAE_Suppress, false, false, 2)
+DIAG(warn_init_ptr_member_to_parameter_addr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "initializing pointer member %0 with the stack address of parameter %1", 105, SFINAE_Suppress, false, false, 2)
+DIAG(warn_initializer_out_of_order, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{field|base class}0 %1 will be initialized after %select{field|base}2 %3", 374, SFINAE_Suppress, false, false, 2)
+DIAG(warn_initializer_overrides, CLASS_WARNING, (unsigned)diag::Severity::Warning, "initializer overrides prior initialization of this subobject", 231, SFINAE_Suppress, false, false, 2)
+DIAG(warn_inline_namespace_reopened_noninline, CLASS_WARNING, (unsigned)diag::Severity::Warning, "inline namespace cannot be reopened as a non-inline namespace", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_inst_method_not_found, CLASS_WARNING, (unsigned)diag::Severity::Warning, "instance method %objcinstance0 not found (return type defaults to 'id')", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_instance_method_not_found_with_typo, CLASS_WARNING, (unsigned)diag::Severity::Warning, "instance method %objcinstance0 not found (return type defaults to 'id'); did you mean %objcinstance2?", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_instance_method_on_class_found, CLASS_WARNING, (unsigned)diag::Severity::Warning, "instance method %0 found instead of class method %1", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_int_to_pointer_cast, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cast to %1 from smaller integer type %0", 237, SFINAE_Suppress, false, false, 2)
+DIAG(warn_int_to_void_pointer_cast, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cast to %1 from smaller integer type %0", 238, SFINAE_Suppress, false, false, 2)
+DIAG(warn_invalid_asm_cast_lvalue, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid use of a cast in an inline asm context requiring an l-value: accepted due to -fheinous-gnu-extensions, but clang may remove support for this in the future", 0, SFINAE_Suppress, false, false, 11)
+DIAG(warn_invalid_capability_name, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "invalid capability name '%0'; capability name must be 'mutex' or 'role'", 445, SFINAE_Suppress, false, false, 2)
+DIAG(warn_invalid_initializer_from_system_header, CLASS_WARNING, (unsigned)diag::Severity::Warning, "invalid constructor form class in system header, should not be explicit", 243, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ivar_use_hidden, CLASS_WARNING, (unsigned)diag::Severity::Warning, "local declaration of %0 hides instance variable", 391, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ivars_in_interface, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "declaration of instance variables in the interface is deprecated", 311, SFINAE_Suppress, false, false, 2)
+DIAG(warn_lock_exclusive_and_shared, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 '%1' is acquired exclusively and shared in the same scope", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_lock_some_predecessors, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 '%1' is not held on every path through here", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_logical_and_in_logical_or, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'&&' within '||'", 258, SFINAE_Suppress, false, false, 2)
+DIAG(warn_logical_instead_of_bitwise, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of logical '%0' with constant operand", 95, SFINAE_Suppress, false, false, 2)
+DIAG(warn_logical_not_on_lhs_of_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "logical not is only applied to the left hand side of this comparison", 257, SFINAE_Suppress, false, false, 2)
+DIAG(warn_loop_ctrl_binds_to_inner, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' is bound to current loop, GCC binds it to the enclosing loop", 176, SFINAE_Suppress, false, false, 2)
+DIAG(warn_loop_state_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "state of variable '%0' must match at the entry and exit of loop", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_lunsigned_always_true_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison of unsigned%select{| enum}2 expression %0 is always %1", 437, SFINAE_Suppress, false, false, 2)
+DIAG(warn_main_one_arg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "only one parameter on 'main' declaration", 262, SFINAE_Suppress, false, false, 2)
+DIAG(warn_maybe_falloff_nonvoid_function, CLASS_WARNING, (unsigned)diag::Severity::Warning, "control may reach end of non-void function", 379, SFINAE_Suppress, false, false, 2)
+DIAG(warn_maybe_falloff_nonvoid_lambda, CLASS_WARNING, (unsigned)diag::Severity::Warning, "control may reach end of non-void lambda", 379, SFINAE_Suppress, false, false, 3)
+DIAG(warn_maybe_uninit_var, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable %0 may be uninitialized when %select{used here|captured by block}1", 92, SFINAE_Suppress, false, false, 2)
+DIAG(warn_maynot_respond, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 may not respond to %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_member_extra_qualification, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extra qualification on member %0", 267, SFINAE_Suppress, false, false, 2)
+DIAG(warn_memsize_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "size argument in %0 call is a comparison", 265, SFINAE_Suppress, false, false, 2)
+DIAG(warn_mismatched_availability, CLASS_WARNING, (unsigned)diag::Severity::Warning, "availability does not match previous declaration", 40, SFINAE_Suppress, false, false, 2)
+DIAG(warn_mismatched_availability_override, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overriding method %select{introduced after|deprecated before|obsoleted before}0 overridden method on %1 (%2 vs. %3)", 40, SFINAE_Suppress, false, false, 2)
+DIAG(warn_mismatched_availability_override_unavail, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overriding method cannot be unavailable on %0 when its overridden method is available", 40, SFINAE_Suppress, false, false, 2)
+DIAG(warn_mismatched_section, CLASS_WARNING, (unsigned)diag::Severity::Warning, "section does not match previous declaration", 381, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_braces, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "suggest braces around initialization of subobject", 272, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_case1, CLASS_WARNING, (unsigned)diag::Severity::Warning, "enumeration value %0 not handled in switch", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_case2, CLASS_WARNING, (unsigned)diag::Severity::Warning, "enumeration values %0 and %1 not handled in switch", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_case3, CLASS_WARNING, (unsigned)diag::Severity::Warning, "enumeration values %0, %1, and %2 not handled in switch", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_case_for_condition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "no case matching constant switch condition '%0'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_cases, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 enumeration values not handled in switch: %1, %2, %3...", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_exception_specification, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 is missing exception specification '%1'", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_explicit_synthesis, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "auto property synthesis is synthesizing property not explicitly synthesized", 315, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_field_initializers, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "missing field %0 initializer", 274, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_format_string, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string missing", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_missing_method_return_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "method has no return type specified; defaults to 'id'", 277, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_prototype, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "no previous prototype for function %0", 279, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_sentinel, CLASS_WARNING, (unsigned)diag::Severity::Warning, "missing sentinel in %select{function call|method dispatch|block call}0", 387, SFINAE_Suppress, false, false, 2)
+DIAG(warn_missing_variable_declarations, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "no previous extern declaration for non-static variable %0", 282, SFINAE_Suppress, false, false, 2)
+DIAG(warn_mixed_sign_comparison, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "comparison of integers of different signs: %0 and %1", 398, SFINAE_Suppress, false, false, 2)
+DIAG(warn_multiple_method_decl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "multiple methods named %0 found", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_namespace_member_extra_qualification, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extra qualification on member %0", 157, SFINAE_Suppress, false, false, 2)
+DIAG(warn_neon_vector_initializer_non_portable, CLASS_WARNING, (unsigned)diag::Severity::Warning, "vector initializers are not compatible with NEON intrinsics in big endian mode", 302, SFINAE_Suppress, false, false, 2)
+DIAG(warn_no_autosynthesis_property, CLASS_WARNING, (unsigned)diag::Severity::Warning, "auto property synthesis will not synthesize property %0 because it is 'readwrite' but it will be synthesized 'readonly' via another property", 323, SFINAE_Suppress, false, false, 2)
+DIAG(warn_no_autosynthesis_shared_ivar_property, CLASS_WARNING, (unsigned)diag::Severity::Warning, "auto property synthesis will not synthesize property %0 because it cannot share an ivar with another synthesized property", 323, SFINAE_Suppress, false, false, 2)
+DIAG(warn_no_constructor_for_refconst, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{struct|interface|union|class|enum}0 %1 does not declare any constructor to initialize its non-modifiable members", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_no_unlock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 '%1' is still held at the end of function", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_contravariant_overriding_param_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting parameter types in declaration of %0: %1 vs %2", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_contravariant_param_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting parameter types in implementation of %0: %1 vs %2", 266, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_covariant_overriding_ret_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting return type in declaration of %0: %1 vs %2", 343, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_covariant_ret_types, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "conflicting return type in implementation of %0: %1 vs %2", 266, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_literal_null_pointer, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expression which evaluates to zero treated as a null pointer constant of type %0", 295, SFINAE_Suppress, false, false, 17)
+DIAG(warn_non_pod_vararg_with_format_string, CLASS_WARNING, (unsigned)diag::Severity::Error, "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic %select{function|block|method|constructor}2; expected type from format string was %3", 298, SFINAE_Suppress, false, false, 2)
+DIAG(warn_non_virtual_dtor, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 has virtual functions but non-virtual destructor", 299, SFINAE_Suppress, false, false, 2)
+DIAG(warn_noreturn_function_has_return_expr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "function %0 declared 'noreturn' should not return", 244, SFINAE_Suppress, false, false, 2)
+DIAG(warn_not_a_doxygen_trailing_member_comment, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "not a Doxygen trailing comment", 132, SFINAE_Suppress, false, false, 18)
+DIAG(warn_not_compound_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of unary operator that may be intended as compound assignment (%0=)", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_not_enough_argument, CLASS_WARNING, (unsigned)diag::Severity::Warning, "not enough variable arguments in %0 declaration to fit a sentinel", 387, SFINAE_Suppress, false, false, 2)
+DIAG(warn_not_in_enum, CLASS_WARNING, (unsigned)diag::Severity::Warning, "case value not in enumerated type %0", 432, SFINAE_Suppress, false, false, 2)
+DIAG(warn_not_in_enum_assignment, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "integer constant not in range of enumerated type %0", 31, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ns_attribute_wrong_parameter_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute only applies to %select{Objective-C object|pointer}1 parameters", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ns_attribute_wrong_return_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute only applies to %select{functions|methods|properties}1 that return %select{an Objective-C object|a pointer|a non-retainable pointer}2", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_nsobject_attribute, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'NSObject' attribute may be put on a typedef only; attribute is ignored", 4, SFINAE_Suppress, false, false, 2)
+DIAG(warn_null_arg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "null passed to a callee which requires a non-null argument", 300, SFINAE_Suppress, false, false, 22)
+DIAG(warn_null_in_arithmetic_operation, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of NULL in arithmetic operation", 303, SFINAE_Suppress, false, false, 2)
+DIAG(warn_null_in_comparison_operation, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison between NULL and non-pointer %select{(%1 and NULL)|(NULL and %1)}0", 303, SFINAE_Suppress, false, false, 2)
+DIAG(warn_null_pointer_compare, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison of %select{address of|function|array}0 '%1' %select{not |}2equal to a null pointer is always %select{true|false}2", 440, SFINAE_Suppress, false, false, 2)
+DIAG(warn_null_ret, CLASS_WARNING, (unsigned)diag::Severity::Warning, "null returned from %select{function|method}0 that requires a non-null return value", 300, SFINAE_Suppress, false, false, 22)
+DIAG(warn_objc_designated_init_missing_super_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "designated initializer missing a 'super' call to a designated initializer of the super class", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_designated_init_non_designated_init_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "designated initializer invoked a non-designated initializer", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_designated_init_non_super_designated_init_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "designated initializer should only invoke a designated initializer on 'super'", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_implementation_missing_designated_init_override, CLASS_WARNING, (unsigned)diag::Severity::Warning, "method override for the designated initializer of the superclass %objcinstance0 not found", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_invalid_bridge, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 bridges to %1, not %2", 50, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_invalid_bridge_to_cf, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 cannot bridge to %1", 50, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_isa_assign, CLASS_WARNING, (unsigned)diag::Severity::Warning, "assignment to Objective-C's isa is deprecated in favor of object_setClass()", 118, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_isa_use, CLASS_WARNING, (unsigned)diag::Severity::Warning, "direct access to Objective-C's isa is deprecated in favor of object_getClass()", 118, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_literal_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "direct comparison of %select{an array literal|a dictionary literal|a numeric literal|a boxed expression|}0 has undefined behavior", 312, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_missing_super_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "method possibly missing a [super %0] call", 316, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_pointer_cxx_catch_fragile, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot catch an exception thrown with @throw in C++ in the non-unified exception model", 318, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_pointer_masking, CLASS_WARNING, (unsigned)diag::Severity::Warning, "bitmasking for introspection of Objective-C object pointers is strongly discouraged", 119, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_pointer_masking_performSelector, CLASS_WARNING, (unsigned)diag::Severity::Warning, "bitmasking for introspection of Objective-C object pointers is strongly discouraged", 120, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_precise_lifetime_meaningless, CLASS_ERROR, (unsigned)diag::Severity::Error, "objc_precise_lifetime is not meaningful for %select{__unsafe_unretained|__autoreleasing}0 objects", 0, SFINAE_SubstitutionFailure, false, true, 2)
+DIAG(warn_objc_property_copy_missing_on_block, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'copy' attribute must be specified for the block property when -fobjc-gc-only is specified", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_property_default_assign_on_object, CLASS_WARNING, (unsigned)diag::Severity::Warning, "default property attribute 'assign' not appropriate for non-GC object", 322, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_property_no_assignment_attribute, CLASS_WARNING, (unsigned)diag::Severity::Warning, "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed", 322, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_property_retain_of_block, CLASS_WARNING, (unsigned)diag::Severity::Warning, "retain'ed block property does not copy the block - use copy attribute instead", 317, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_readonly_property_has_setter, CLASS_WARNING, (unsigned)diag::Severity::Warning, "setter cannot be specified for a readonly property", 326, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_redundant_literal_use, CLASS_WARNING, (unsigned)diag::Severity::Warning, "using %0 with a literal is redundant", 328, SFINAE_Suppress, false, false, 23)
+DIAG(warn_objc_requires_super_protocol, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 attribute cannot be applied to %select{methods in protocols|dealloc}1", 375, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_root_class_missing, CLASS_WARNING, (unsigned)diag::Severity::Warning, "class %0 defined without specifying a base class", 329, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_secondary_init_missing_init_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "convenience initializer missing a 'self' call to another initializer", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_secondary_init_super_init_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "convenience initializer should not invoke an initializer on 'super'", 309, SFINAE_Suppress, false, false, 2)
+DIAG(warn_objc_string_literal_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "direct comparison of a string literal has undefined behavior", 330, SFINAE_Suppress, false, false, 2)
+DIAG(warn_old_style_cast, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "use of old-style cast", 333, SFINAE_Suppress, false, false, 2)
+DIAG(warn_omp_linear_step_zero, CLASS_WARNING, (unsigned)diag::Severity::Warning, "zero linear step (%0 %select{|and other variables in clause }1should probably be const)", 335, SFINAE_Suppress, false, false, 15)
+DIAG(warn_on_superclass_use, CLASS_WARNING, (unsigned)diag::Severity::Warning, "class implementation may not have super class", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_operator_new_returns_null, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 should not return a null pointer unless it is declared 'throw()'%select{| or 'noexcept'}1", 292, SFINAE_Suppress, false, false, 2)
+DIAG(warn_out_of_range_compare, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison of %select{constant %0|true|false}1 with %select{expression of type %2|boolean expression}3 is always %select{false|true}4", 438, SFINAE_Suppress, false, false, 2)
+DIAG(warn_overaligned_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "type %0 requires %1 bytes of alignment and the default allocator only guarantees %2 bytes", 338, SFINAE_Suppress, false, false, 2)
+DIAG(warn_overloaded_shift_in_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "overloaded operator %select{>>|<<}0 has lower precedence than comparison operator", 341, SFINAE_Suppress, false, false, 2)
+DIAG(warn_overloaded_virtual, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%q0 hides overloaded virtual %select{function|functions}1", 342, SFINAE_Suppress, false, false, 2)
+DIAG(warn_padded_struct_anon_field, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "padding %select{struct|interface|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 to align anonymous bit-field", 346, SFINAE_Suppress, false, false, 2)
+DIAG(warn_padded_struct_field, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "padding %select{struct|interface|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 to align %5", 346, SFINAE_Suppress, false, false, 2)
+DIAG(warn_padded_struct_size, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "padding size of %0 with %1 %select{byte|bit}2%select{|s}3 to alignment boundary", 346, SFINAE_Suppress, false, false, 2)
+DIAG(warn_param_return_typestate_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "parameter '%0' not in expected state when the function returns: expected '%1', observed '%2'", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_param_typestate_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "argument not in expected state; expected '%0', observed '%1'", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_parameter_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 is a large (%1 bytes) pass-by-value argument; pass it by reference instead ?", 253, SFINAE_Suppress, false, false, 2)
+DIAG(warn_parens_disambiguated_as_function_declaration, CLASS_WARNING, (unsigned)diag::Severity::Warning, "parentheses were disambiguated as a function declaration", 502, SFINAE_Suppress, false, false, 2)
+DIAG(warn_partial_specs_not_deducible, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{class|variable}0 template partial specialization contains %select{a template parameter|template parameters}1 that cannot be deduced; this partial specialization will never be used", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pass_class_arg_to_vararg, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "passing object of class type %0 through variadic %select{function|block|method|constructor}1%select{|; did you mean to call '%3'?}2", 86, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pointer_indirection_from_incompatible_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "dereference of type %1 that was reinterpret_cast from type %0 has undefined behavior", 459, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_options_align_reset_failed, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#pragma options align=reset failed: %0", 207, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_pack_invalid_alignment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'", 207, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_pack_pop_identifer_and_alignment, CLASS_WARNING, (unsigned)diag::Severity::Warning, "specifying both a name and alignment to 'pop' is undefined", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_pack_show, CLASS_WARNING, (unsigned)diag::Severity::Warning, "value of #pragma pack(show) == %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_pop_failed, CLASS_WARNING, (unsigned)diag::Severity::Warning, "#pragma %0(pop, ...) failed: %1", 207, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_unused_expected_var_arg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "only variables can be arguments to '#pragma unused'", 207, SFINAE_Suppress, false, false, 2)
+DIAG(warn_pragma_unused_undeclared_var, CLASS_WARNING, (unsigned)diag::Severity::Warning, "undeclared variable %0 used as an argument for '#pragma unused'", 207, SFINAE_Suppress, false, false, 2)
+DIAG(warn_precedence_bitwise_rel, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 has lower precedence than %1; %1 will be evaluated first", 347, SFINAE_Suppress, false, false, 2)
+DIAG(warn_precedence_conditional, CLASS_WARNING, (unsigned)diag::Severity::Warning, "operator '?:' has lower precedence than '%0'; '%0' will be evaluated first", 347, SFINAE_Suppress, false, false, 2)
+DIAG(warn_printf_asterisk_missing_arg, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_asterisk_wrong_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "field %select{width|precision}0 should have type %1, but argument has type %2", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_data_arg_not_used, CLASS_WARNING, (unsigned)diag::Severity::Warning, "data argument not used by format string", 165, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_format_string_contains_null_char, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string contains '\\0' within the string body", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_format_string_not_null_terminated, CLASS_WARNING, (unsigned)diag::Severity::Warning, "format string is not null-terminated", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_ignored_flag, CLASS_WARNING, (unsigned)diag::Severity::Warning, "flag '%0' is ignored when flag '%1' is present", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_incomplete_specifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "incomplete format specifier", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_insufficient_data_args, CLASS_WARNING, (unsigned)diag::Severity::Warning, "more '%%' conversions than data arguments", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_nonsensical_flag, CLASS_WARNING, (unsigned)diag::Severity::Warning, "flag '%0' results in undefined behavior with '%1' conversion specifier", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_nonsensical_optional_amount, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{field width|precision}0 used with '%1' conversion specifier, resulting in undefined behavior", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_printf_positional_arg_exceeds_data_args, CLASS_WARNING, (unsigned)diag::Severity::Warning, "data argument position '%0' exceeds the number of data arguments (%1)", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_private_extern, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of __private_extern__ on a declaration may not produce external symbol private to the linkage unit and is deprecated", 361, SFINAE_Suppress, false, false, 2)
+DIAG(warn_profile_data_out_of_date, CLASS_WARNING, (unsigned)diag::Severity::Warning, "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1 no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored", 362, SFINAE_Suppress, false, false, 25)
+DIAG(warn_profile_data_unprofiled, CLASS_WARNING, (unsigned)diag::Severity::Warning, "no profile data available for file \"%0\"", 363, SFINAE_Suppress, false, false, 25)
+DIAG(warn_property_attr_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property attribute in class extension does not match the primary class", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_property_attribute, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%1' attribute on property %0 does not match the property inherited from %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_property_getter_owning_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property declared as returning non-retained objects; getter returning retained objects", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_property_implicitly_mismatched, CLASS_WARNING, (unsigned)diag::Severity::Warning, "primary property declaration is implicitly strong while redeclaration in class extension is weak", 320, SFINAE_Suppress, false, false, 2)
+DIAG(warn_property_method_deprecated, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property access is using %0 method which is deprecated", 115, SFINAE_Suppress, false, false, 21)
+DIAG(warn_property_types_are_incompatible, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property type %0 is incompatible with type %1 inherited from %2", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_protocol_property_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property of type %0 was selected for synthesis", 365, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ptr_arith_exceeds_bounds, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "the pointer incremented by %0 refers past the end of the array (that contains %1 element%s2)", 28, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ptr_arith_precedes_bounds, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "the pointer decremented by %0 refers before the beginning of the array", 28, SFINAE_Suppress, false, false, 2)
+DIAG(warn_qual_return_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect", 208, SFINAE_Suppress, false, false, 2)
+DIAG(warn_readonly_property, CLASS_WARNING, (unsigned)diag::Severity::Warning, "attribute 'readonly' of property %0 restricts attribute 'readwrite' of property inherited from %1", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_receiver_forward_class, CLASS_WARNING, (unsigned)diag::Severity::Warning, "receiver %0 is a forward class and corresponding @interface may not exist", 368, SFINAE_Suppress, false, false, 2)
+DIAG(warn_receiver_forward_instance, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "receiver type %0 for instance message is a forward declaration", 368, SFINAE_Suppress, false, false, 5)
+DIAG(warn_receiver_is_weak, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "weak %select{receiver|property|implicit property}0 may be unpredictably set to nil", 369, SFINAE_Suppress, false, false, 2)
+DIAG(warn_redecl_library_builtin, CLASS_WARNING, (unsigned)diag::Severity::Warning, "incompatible redeclaration of library function %0", 221, SFINAE_Suppress, false, false, 2)
+DIAG(warn_redeclaration_without_attribute_prev_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%q0 redeclared without %1 attribute: previous %1 ignored", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_redefinition_in_param_list, CLASS_WARNING, (unsigned)diag::Severity::Warning, "redefinition of %0 will not be visible outside of this function", 503, SFINAE_Suppress, false, false, 2)
+DIAG(warn_redundant_loop_iteration, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable %0 is %select{decremented|incremented}1 both in the loop header and in the loop body", 260, SFINAE_Suppress, false, false, 2)
+DIAG(warn_reference_field_is_uninit, CLASS_WARNING, (unsigned)diag::Severity::Warning, "reference %0 is not yet bound to a value when used here", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_register_objc_catch_parm, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'register' storage specifier on @catch parameter will be ignored", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_reinterpret_different_from_static, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'reinterpret_cast' %select{from|to}3 class %0 %select{to|from}3 its %select{virtual base|base at non-zero offset}2 %1 behaves differently from 'static_cast'", 372, SFINAE_Suppress, false, false, 2)
+DIAG(warn_related_result_type_compatibility_class, CLASS_WARNING, (unsigned)diag::Severity::Warning, "method is expected to return an instance of its class type %diff{$, but is declared to return $|, but is declared to return different type}0,1", 0, SFINAE_Suppress, false, false, 20)
+DIAG(warn_related_result_type_compatibility_protocol, CLASS_WARNING, (unsigned)diag::Severity::Warning, "protocol method is expected to return an instance of the implementing class, but is declared to return %0", 0, SFINAE_Suppress, false, false, 20)
+DIAG(warn_remainder_by_zero, CLASS_WARNING, (unsigned)diag::Severity::Warning, "remainder by zero is undefined", 129, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ret_addr_label, CLASS_WARNING, (unsigned)diag::Severity::Warning, "returning address of label, which is local", 378, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ret_local_temp_addr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "returning address of local temporary object", 378, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ret_local_temp_ref, CLASS_WARNING, (unsigned)diag::Severity::Warning, "returning reference to local temporary object", 378, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ret_stack_addr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "address of stack memory associated with local variable %0 returned", 378, SFINAE_Suppress, false, false, 2)
+DIAG(warn_ret_stack_ref, CLASS_WARNING, (unsigned)diag::Severity::Warning, "reference to stack memory associated with local variable %0 returned", 378, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_missing_expr, CLASS_WARNING, (unsigned)diag::Severity::Error, "non-void %select{function|method}1 %0 should return a value", 379, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_typestate_for_unconsumable_type, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "return state set for an unconsumable type '%0'", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_typestate_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "return value not in expected state; expected '%0', observed '%1'", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_value_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "return value of %0 is a large (%1 bytes) pass-by-value object; pass it by reference instead ?", 253, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_value_udt, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 has C-linkage specified, but returns user-defined type %1 which is incompatible with C", 380, SFINAE_Suppress, false, false, 2)
+DIAG(warn_return_value_udt_incomplete, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 has C-linkage specified, but returns incomplete type %1 which could be incompatible with C", 380, SFINAE_Suppress, false, false, 2)
+DIAG(warn_root_inst_method_not_found, CLASS_WARNING, (unsigned)diag::Severity::Warning, "instance method %0 is being used on 'Class' which is not in the root class", 314, SFINAE_Suppress, false, false, 2)
+DIAG(warn_runsigned_always_true_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "comparison of %0 unsigned%select{| enum}2 expression is always %1", 437, SFINAE_Suppress, false, false, 2)
+DIAG(warn_scanf_nonzero_width, CLASS_WARNING, (unsigned)diag::Severity::Warning, "zero field width in scanf format string is unused", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_scanf_scanlist_incomplete, CLASS_WARNING, (unsigned)diag::Severity::Warning, "no closing ']' for '%%[' in scanf format string", 164, SFINAE_Suppress, false, false, 22)
+DIAG(warn_second_parameter_of_va_start_not_last_named_argument, CLASS_WARNING, (unsigned)diag::Severity::Warning, "second parameter of 'va_start' not last named argument", 498, SFINAE_Suppress, false, false, 2)
+DIAG(warn_second_parameter_to_va_arg_never_compatible, CLASS_WARNING, (unsigned)diag::Severity::Warning, "second argument to 'va_arg' is of promotable type %0; this va_arg has undefined behavior because arguments will be promoted to %1", 498, SFINAE_Suppress, false, false, 2)
+DIAG(warn_second_parameter_to_va_arg_not_pod, CLASS_WARNING, (unsigned)diag::Severity::Error, "second argument to 'va_arg' is of non-POD type %0", 298, SFINAE_Suppress, false, false, 2)
+DIAG(warn_second_parameter_to_va_arg_ownership_qualified, CLASS_WARNING, (unsigned)diag::Severity::Error, "second argument to 'va_arg' is of ARC ownership-qualified type %0", 298, SFINAE_Suppress, false, false, 2)
+DIAG(warn_self_assignment, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicitly assigning value of variable of type %0 to itself", 384, SFINAE_Suppress, false, false, 2)
+DIAG(warn_setter_getter_impl_required, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property %0 requires method %1 to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation", 319, SFINAE_Suppress, false, false, 2)
+DIAG(warn_setter_getter_impl_required_in_category, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property %0 requires method %1 to be defined - use @dynamic or provide a method implementation in this category", 319, SFINAE_Suppress, false, false, 2)
+DIAG(warn_shift_gt_typewidth, CLASS_WARNING, (unsigned)diag::Severity::Warning, "shift count >= width of type", 393, SFINAE_Suppress, false, false, 2)
+DIAG(warn_shift_negative, CLASS_WARNING, (unsigned)diag::Severity::Warning, "shift count is negative", 392, SFINAE_Suppress, false, false, 2)
+DIAG(warn_shift_result_gt_typewidth, CLASS_WARNING, (unsigned)diag::Severity::Warning, "signed shift result (%0) requires %1 bits to represent, but %2 only has %3 bits", 395, SFINAE_Suppress, false, false, 2)
+DIAG(warn_shift_result_sets_sign_bit, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "signed shift result (%0) sets the sign bit of the shift expression's type (%1) and becomes negative", 396, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sizeof_array_decay, CLASS_WARNING, (unsigned)diag::Severity::Warning, "sizeof on pointer operation will return size of %0 instead of %1", 402, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sizeof_array_param, CLASS_WARNING, (unsigned)diag::Severity::Warning, "sizeof on array function parameter will return size of %0 instead of %1", 401, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sizeof_pointer_expr_memaccess, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' call operates on objects of type %1 while the size is based on a different type %2", 403, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sizeof_pointer_expr_memaccess_note, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "did you mean to %select{dereference the argument to 'sizeof' (and multiply it by the number of elements)|remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)|provide an explicit length}0?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sizeof_pointer_type_memaccess, CLASS_WARNING, (unsigned)diag::Severity::Warning, "argument to 'sizeof' in %0 call is the same pointer type %1 as the %select{destination|source}2; expected %3 or an explicit length", 403, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sometimes_uninit_var, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable %0 is %select{used|captured}1 uninitialized whenever %select{'%3' condition is %select{true|false}4|'%3' loop %select{is entered|exits because its condition is false}4|'%3' loop %select{condition is true|exits because its condition is false}4|switch %3 is taken|its declaration is reached|%3 is called}2", 404, SFINAE_Suppress, false, false, 2)
+DIAG(warn_standalone_specifier, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' ignored on this declaration", 273, SFINAE_Suppress, false, false, 2)
+DIAG(warn_static_array_too_small, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array argument is too small; contains %0 elements, callee requires at least %1", 27, SFINAE_Suppress, false, false, 2)
+DIAG(warn_static_local_in_extern_inline, CLASS_WARNING, (unsigned)diag::Severity::Warning, "non-constant static local variable in inline function may be different in different files", 410, SFINAE_Suppress, false, false, 2)
+DIAG(warn_static_main, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'main' should not be declared static", 262, SFINAE_Suppress, false, false, 2)
+DIAG(warn_static_self_reference_in_init, CLASS_WARNING, (unsigned)diag::Severity::Warning, "static variable %0 is suspiciously used within its own initialization", 411, SFINAE_Suppress, false, false, 2)
+DIAG(warn_strict_multiple_method_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "multiple methods named %0 found", 424, SFINAE_Suppress, false, false, 2)
+DIAG(warn_string_plus_char, CLASS_WARNING, (unsigned)diag::Severity::Warning, "adding %0 to a string pointer does not append to the string", 427, SFINAE_Suppress, false, false, 2)
+DIAG(warn_string_plus_int, CLASS_WARNING, (unsigned)diag::Severity::Warning, "adding %0 to a string does not append to the string", 428, SFINAE_Suppress, false, false, 2)
+DIAG(warn_stringcompare, CLASS_WARNING, (unsigned)diag::Severity::Warning, "result of comparison against %select{a string literal|@encode}0 is unspecified (use strncmp instead)", 425, SFINAE_Suppress, false, false, 2)
+DIAG(warn_strlcpycat_wrong_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "size argument in %0 call appears to be size of the source; expected the size of the destination", 429, SFINAE_Suppress, false, false, 2)
+DIAG(warn_strncat_large_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "the value of the size argument in 'strncat' is too large, might lead to a buffer overflow", 430, SFINAE_Suppress, false, false, 2)
+DIAG(warn_strncat_src_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "size argument in 'strncat' call appears to be size of the source", 430, SFINAE_Suppress, false, false, 2)
+DIAG(warn_strncat_wrong_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "the value of the size argument to 'strncat' is wrong", 430, SFINAE_Suppress, false, false, 2)
+DIAG(warn_struct_class_previous_tag_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 here but previously declared as %select{a struct|an interface|a class}3%select{| template}1", 271, SFINAE_Suppress, false, false, 2)
+DIAG(warn_struct_class_tag_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{struct|interface|class}0%select{| template}1 %2 was previously declared as a %select{struct|interface|class}3%select{| template}1", 271, SFINAE_Suppress, false, false, 2)
+DIAG(warn_sub_ptr_zero_size_types, CLASS_WARNING, (unsigned)diag::Severity::Warning, "subtraction of pointers to type %0 of zero size has undefined behavior", 354, SFINAE_Suppress, false, false, 2)
+DIAG(warn_subobject_initializer_overrides, CLASS_WARNING, (unsigned)diag::Severity::Warning, "subobject initialization overrides initialization of other fields within its enclosing subobject", 231, SFINAE_Suppress, false, false, 2)
+DIAG(warn_subscript_is_char, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "array subscript is of type 'char'", 85, SFINAE_Suppress, false, false, 2)
+DIAG(warn_suggest_noreturn_block, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "block could be declared with attribute 'noreturn'", 278, SFINAE_Suppress, false, false, 2)
+DIAG(warn_suggest_noreturn_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{function|method}0 %1 could be declared with attribute 'noreturn'", 278, SFINAE_Suppress, false, false, 2)
+DIAG(warn_tautological_overlap_comparison, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "overlapping comparisons always evaluate to %select{false|true}0", 439, SFINAE_Suppress, false, false, 2)
+DIAG(warn_template_arg_negative, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "non-type template argument with value '%0' converted to '%1' for unsigned template parameter of type %2", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_template_arg_too_large, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "non-type template argument value '%0' truncated to '%1' for template parameter of type %2", 98, SFINAE_Suppress, false, false, 17)
+DIAG(warn_template_export_unsupported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "exported templates are unsupported", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_template_qualified_friend_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "dependent nested name specifier '%0' for friend template declaration is not supported; ignoring this friend declaration", 477, SFINAE_Suppress, false, false, 2)
+DIAG(warn_template_qualified_friend_unsupported, CLASS_WARNING, (unsigned)diag::Severity::Warning, "dependent nested name specifier '%0' for friend class declaration is not supported; turning off access control for %1", 477, SFINAE_Suppress, false, false, 2)
+DIAG(warn_template_spec_extra_headers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "extraneous template parameter list in template specialization", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_temporary_array_to_pointer_decay, CLASS_WARNING, (unsigned)diag::Severity::Warning, "pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression", 10, SFINAE_Suppress, false, false, 2)
+DIAG(warn_tentative_incomplete_array, CLASS_WARNING, (unsigned)diag::Severity::Warning, "tentative array definition assumed to have one element", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_this_bool_conversion, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true", 456, SFINAE_Suppress, false, false, 17)
+DIAG(warn_this_null_compare, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to %select{true|false}0", 441, SFINAE_Suppress, false, false, 2)
+DIAG(warn_thread_attribute_argument_not_lockable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 attribute requires arguments whose type is annotated with 'capability' attribute; type here is %1", 445, SFINAE_Suppress, false, false, 2)
+DIAG(warn_thread_attribute_decl_not_lockable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 attribute can only be applied in a context annotated with 'capability(\"mutex\")' attribute", 445, SFINAE_Suppress, false, false, 2)
+DIAG(warn_thread_attribute_decl_not_pointer, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 only applies to pointer types; type here is %1", 445, SFINAE_Suppress, false, false, 2)
+DIAG(warn_thread_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "ignoring %0 attribute because its argument is invalid", 445, SFINAE_Suppress, false, false, 2)
+DIAG(warn_thread_safety_beta, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "Thread safety beta warning.", 446, SFINAE_Suppress, false, false, 2)
+DIAG(warn_transparent_union_attribute_field_size_align, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{alignment|size}0 of field %1 (%2 bits) does not match the %select{alignment|size}0 of the first field in transparent union; transparent_union attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_transparent_union_attribute_floating, CLASS_WARNING, (unsigned)diag::Severity::Warning, "first field of a transparent union cannot have %select{floating point|vector}0 type %1; transparent_union attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_transparent_union_attribute_not_definition, CLASS_WARNING, (unsigned)diag::Severity::Warning, "transparent_union attribute can only be applied to a union definition; attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_transparent_union_attribute_zero_fields, CLASS_WARNING, (unsigned)diag::Severity::Warning, "transparent union definition must contain at least one field; transparent_union attribute ignored", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_type_attribute_wrong_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' only applies to %select{function|pointer|Objective-C object or block pointer}1 types; type here is %2", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_type_safety_null_pointer_required, CLASS_WARNING, (unsigned)diag::Severity::Warning, "specified %0 type tag requires a null pointer", 450, SFINAE_Suppress, false, false, 2)
+DIAG(warn_type_safety_type_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Warning, "argument type %0 doesn't match specified %1 type tag %select{that requires %3|}2", 450, SFINAE_Suppress, false, false, 2)
+DIAG(warn_type_tag_for_datatype_wrong_kind, CLASS_WARNING, (unsigned)diag::Severity::Warning, "this type tag was not designed to be used with this function", 450, SFINAE_Suppress, false, false, 2)
+DIAG(warn_typecheck_function_qualifiers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "qualifier on function type %0 has unspecified behavior", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_typecheck_negative_array_new_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "array size is negative", 43, SFINAE_Suppress, false, false, 2)
+DIAG(warn_typecheck_reference_qualifiers, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'%0' qualifier on reference type %1 has no effect", 208, SFINAE_Suppress, false, false, 2)
+DIAG(warn_typecheck_zero_static_array_size, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'static' has no effect on zero-length arrays", 27, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unannotated_fallthrough, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unannotated fall-through between switch labels", 213, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unannotated_fallthrough_per_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unannotated fall-through between switch labels in partly-annotated function", 214, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unavailable_fwdclass_message, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%0 may be unavailable because the receiver type is unknown", 453, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undeclared_selector, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "undeclared selector %0", 454, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undeclared_selector_with_typo, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "undeclared selector %0; did you mean %1?", 454, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undef_interface, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot find interface declaration for %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undef_interface_suggest, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot find interface declaration for %0; did you mean %1?", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undef_method_impl, CLASS_WARNING, (unsigned)diag::Severity::Warning, "method definition for %0 not found", 225, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undef_protocolref, CLASS_WARNING, (unsigned)diag::Severity::Warning, "cannot find protocol definition for %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undefined_inline, CLASS_WARNING, (unsigned)diag::Severity::Warning, "inline function %q0 is not defined", 457, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undefined_internal, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{function|variable}0 %q1 has internal linkage but is not defined", 458, SFINAE_Suppress, false, false, 2)
+DIAG(warn_undefined_reinterpret_cast, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "reinterpret_cast from %0 to %1 has undefined behavior", 459, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unhandled_ms_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "__declspec attribute %0 is not supported", 206, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unimplemented_protocol_method, CLASS_WARNING, (unsigned)diag::Severity::Warning, "method %0 in protocol %1 not implemented", 364, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unimplemented_selector, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "no method with selector %0 is implemented in this translation unit", 382, SFINAE_Suppress, false, false, 2)
+DIAG(warn_uninit_byref_blockvar_captured_by_block, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "block pointer variable %0 is uninitialized when captured by block", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_uninit_self_reference_in_init, CLASS_WARNING, (unsigned)diag::Severity::Warning, "variable %0 is uninitialized when used within its own initialization", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_uninit_self_reference_in_reference_init, CLASS_WARNING, (unsigned)diag::Severity::Warning, "reference %0 is not yet bound to a value when used within its own initialization", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_uninit_var, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable %0 is uninitialized when %select{used here|captured by block}1", 462, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unknown_attribute_ignored, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unknown attribute %0 ignored", 463, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unlock_but_no_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "releasing %0 '%1' that was not held", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unlock_kind_mismatch, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "releasing %0 '%1' using %select{shared|exclusive}2 access, expected %select{shared|exclusive}3 access", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unnecessary_packed, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "packed attribute is unnecessary for %0", 345, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unneeded_internal_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{function|variable}0 %1 is not needed and will not be emitted", 468, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unneeded_member_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "member function %0 is not needed and will not be emitted", 469, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unneeded_static_internal_decl, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'static' function %0 declared in header file should be declared 'static inline'", 468, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unreachable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "code will never be executed", 470, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unreachable_break, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'break' will never be executed", 472, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unreachable_default, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "default label in switch which covers all enumeration values", 100, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unreachable_loop_increment, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "loop will run at most once (loop increment never executed)", 473, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unreachable_return, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "'return' will never be executed", 474, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unsequenced_mod_mod, CLASS_WARNING, (unsigned)diag::Severity::Warning, "multiple unsequenced modifications to %0", 475, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unsequenced_mod_use, CLASS_WARNING, (unsigned)diag::Severity::Warning, "unsequenced modification and access to %0", 475, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unsigned_abs, CLASS_WARNING, (unsigned)diag::Severity::Warning, "taking the absolute value of unsigned type %0 has no effect", 6, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unused_call, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignoring return value of function declared with %0 attribute", 493, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_comparison, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{%select{|in}1equality|relational}0 comparison result unused", 482, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_const_variable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused variable %0", 483, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_container_subscript_expr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "container access result unused - container access should not be used for side effects", 493, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_exception_param, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused exception parameter %0", 484, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unused_expr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expression result unused", 493, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused function %0", 485, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_label, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused label %0", 486, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_member_function, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused member function %0", 488, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unused_parameter, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused parameter %0", 489, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unused_private_field, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "private field %0 is not used", 490, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_property_backing_ivar, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "ivar %0 which backs the property is not referenced in this property's accessor", 491, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_property_expr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "property access result unused - getters should not be used for side effects", 493, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_result, CLASS_WARNING, (unsigned)diag::Severity::Warning, "ignoring return value of function declared with warn_unused_result attribute", 492, SFINAE_Suppress, false, false, 2)
+DIAG(warn_unused_variable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "unused variable %0", 494, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_voidptr, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expression result unused; should this cast be to 'void'?", 493, SFINAE_Suppress, false, false, 26)
+DIAG(warn_unused_volatile, CLASS_WARNING, (unsigned)diag::Severity::Warning, "expression result unused; assign into a variable to force a volatile load", 495, SFINAE_Suppress, false, false, 2)
+DIAG(warn_use_in_invalid_state, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "invalid invocation of method '%0' on object '%1' while it is in the '%2' state", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_use_of_temp_in_invalid_state, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "invalid invocation of method '%0' on a temporary object while it is in the '%1' state", 97, SFINAE_Suppress, false, false, 2)
+DIAG(warn_use_out_of_scope_declaration, CLASS_WARNING, (unsigned)diag::Severity::Warning, "use of out-of-scope declaration of %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_used_but_marked_unused, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 was marked unused but was used", 496, SFINAE_Suppress, false, false, 2)
+DIAG(warn_user_literal_reserved, CLASS_WARNING, (unsigned)diag::Severity::Warning, "user-defined literal suffixes not starting with '_' are reserved%select{; no literal will invoke this operator|}0", 497, SFINAE_Suppress, false, false, 2)
+DIAG(warn_using_decl_constructor_ellipsis, CLASS_WARNING, (unsigned)diag::Severity::Warning, "inheriting constructor does not inherit ellipsis", 229, SFINAE_Suppress, false, false, 2)
+DIAG(warn_using_directive_in_header, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "using namespace directive in global context in header", 204, SFINAE_Suppress, false, false, 2)
+DIAG(warn_va_start_of_reference_type_is_undefined, CLASS_WARNING, (unsigned)diag::Severity::Warning, "'va_start' has undefined behavior with reference types", 498, SFINAE_Suppress, false, false, 2)
+DIAG(warn_var_deref_requires_any_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}1 the value pointed to by '%0' requires holding %select{any mutex|any mutex exclusively}1", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_var_deref_requires_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}3 the value pointed to by '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_var_deref_requires_lock_precise, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}3 the value pointed to by '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 447, SFINAE_Suppress, false, false, 2)
+DIAG(warn_variable_requires_any_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}1 variable '%0' requires holding %select{any mutex|any mutex exclusively}1", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_variable_requires_lock, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}3 variable '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 444, SFINAE_Suppress, false, false, 2)
+DIAG(warn_variable_requires_lock_precise, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{reading|writing}3 variable '%1' requires holding %0 %select{'%2'|'%2' exclusively}3", 447, SFINAE_Suppress, false, false, 2)
+DIAG(warn_variables_not_in_loop_body, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 used in loop condition not modified in loop body", 260, SFINAE_Suppress, false, false, 2)
+DIAG(warn_vbase_moved_multiple_times, CLASS_WARNING, (unsigned)diag::Severity::Warning, "defaulted move assignment operator of %0 will move assign virtual base class %1 multiple times", 288, SFINAE_Suppress, false, false, 2)
+DIAG(warn_vla_used, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "variable length array used", 504, SFINAE_Suppress, false, false, 2)
+DIAG(warn_weak_identifier_undeclared, CLASS_WARNING, (unsigned)diag::Severity::Warning, "weak identifier %0 never declared", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_weak_import, CLASS_WARNING, (unsigned)diag::Severity::Warning, "an already-declared variable is made a weak_import declaration %0", 0, SFINAE_Suppress, false, false, 2)
+DIAG(warn_weak_template_vtable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "explicit template instantiation %0 will emit a vtable in every translation unit", 508, SFINAE_Suppress, false, false, 2)
+DIAG(warn_weak_vtable, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%0 has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit", 509, SFINAE_Suppress, false, false, 2)
+DIAG(warn_wrong_absolute_value_type, CLASS_WARNING, (unsigned)diag::Severity::Warning, "using %select{integer|floating point|complex}1 absolute value function %0 when argument is of %select{integer|floating point|complex}2 type", 6, SFINAE_Suppress, false, false, 2)
+DIAG(warn_zero_size_struct_union_compat, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "%select{|empty }0%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++", 53, SFINAE_Suppress, false, false, 2)
+DIAG(warn_zero_size_struct_union_in_extern_c, CLASS_WARNING, (unsigned)diag::Severity::Warning, "%select{|empty }0%select{struct|union}1 has size 0 in C, %select{size 1|non-zero size}2 in C++", 154, SFINAE_Suppress, false, false, 2)
+DIAG(warning_multiple_selectors, CLASS_WARNING, (unsigned)diag::Severity::Ignored, "several methods with selector %0 of mismatched types are found for the @selector expression", 383, SFINAE_Suppress, false, false, 2)
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.inc b/include/clang/Basic/DiagnosticSerializationKinds.inc
new file mode 100644
index 0000000..069ba8a
--- /dev/null
+++ b/include/clang/Basic/DiagnosticSerializationKinds.inc
@@ -0,0 +1,37 @@
+#ifdef SERIALIZATIONSTART
+__SERIALIZATIONSTART = DIAG_START_SERIALIZATION,
+#undef SERIALIZATIONSTART
+#endif
+
+DIAG(err_fe_not_a_pch_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "input is not a PCH file: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_fe_pch_file_modified, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "file '%0' has been modified since the precompiled header '%1' was built", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_fe_pch_file_overridden, CLASS_ERROR, (unsigned)diag::Severity::Error, "file '%0' from the precompiled header has been overridden", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_fe_pch_malformed, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "malformed or corrupted AST file: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_fe_pch_malformed_block, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "malformed block record in PCH file: '%0'", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_fe_unable_to_read_pch_file, CLASS_ERROR, (unsigned)diag::Severity::Error, "unable to read PCH file %0: '%1'", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_imported_module_modmap_changed, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "module '%0' imported by AST file '%1' found in a different module map file (%2) than when the importing AST file was built (%3)", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_imported_module_not_found, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "module '%0' imported by AST file '%1' not found", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_module_odr_violation_different_definitions, CLASS_ERROR, (unsigned)diag::Severity::Error, "%q0 has different definitions in different modules; %select{definition in module '%2' is here|defined here}1", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_module_odr_violation_different_instantiations, CLASS_ERROR, (unsigned)diag::Severity::Error, "instantiation of %q0 is different in different modules", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_module_odr_violation_missing_decl, CLASS_ERROR, (unsigned)diag::Severity::Error, "%q0 from module '%1' is not present in definition of %q2%select{ in module '%4'| provided earlier}3", 0, SFINAE_Report, false, true, 13)
+DIAG(err_not_a_pch_file, CLASS_ERROR, (unsigned)diag::Severity::Fatal, "'%0' does not appear to be a precompiled header file", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_diagopt_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 is currently enabled, but was not in the PCH file", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_different_branch, CLASS_ERROR, (unsigned)diag::Severity::Error, "PCH file built from a different branch (%0) than the compiler (%1)", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_langopt_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 was %select{disabled|enabled}1 in PCH file but is currently %select{disabled|enabled}2", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_langopt_value_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%0 differs in PCH file vs. current file", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_macro_def_conflict, CLASS_ERROR, (unsigned)diag::Severity::Error, "definition of macro '%0' differs between the precompiled header ('%1') and the command line ('%2')", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_macro_def_undef, CLASS_ERROR, (unsigned)diag::Severity::Error, "macro '%0' was %select{defined|undef'd}1 in the precompiled header but %select{undef'd|defined}1 on the command line", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_pp_detailed_record, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{command line contains|precompiled header was built with}0 '-detailed-preprocessing-record' but %select{precompiled header was not built with it|it is not present on the command line}0", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_targetopt_feature_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{AST file|current translation unit}0 was compiled with the target feature'%1' but the %select{current translation unit is|AST file was}0 not", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_targetopt_mismatch, CLASS_ERROR, (unsigned)diag::Severity::Error, "PCH file was compiled for the %0 '%1' but the current translation unit is being compiled for target '%2'", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_undef, CLASS_ERROR, (unsigned)diag::Severity::Error, "%select{command line contains|precompiled header was built with}0 '-undef' but %select{precompiled header was not built with it|it is not present on the command line}0", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_version_too_new, CLASS_ERROR, (unsigned)diag::Severity::Error, "PCH file uses a newer PCH format that cannot be read", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_version_too_old, CLASS_ERROR, (unsigned)diag::Severity::Error, "PCH file uses an older PCH format that is no longer supported", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(err_pch_with_compiler_errors, CLASS_ERROR, (unsigned)diag::Severity::Error, "PCH file contains compiler errors", 0, SFINAE_SubstitutionFailure, false, true, 13)
+DIAG(note_module_cache_path, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "after modifying system headers, please delete the module cache at '%0'", 0, SFINAE_Suppress, false, false, 13)
+DIAG(note_module_odr_violation_different_definitions, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "definition in module '%0' is here", 0, SFINAE_Suppress, false, false, 13)
+DIAG(note_module_odr_violation_no_possible_decls, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "definition has no member %0", 0, SFINAE_Suppress, false, false, 13)
+DIAG(note_module_odr_violation_possible_decl, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "declaration of %0 does not match", 0, SFINAE_Suppress, false, false, 13)
+DIAG(note_pch_rebuild_required, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "please rebuild precompiled header '%0'", 0, SFINAE_Suppress, false, false, 13)
+DIAG(note_pch_required_by, CLASS_NOTE, (unsigned)diag::Severity::Fatal, "'%0' required by '%1'", 0, SFINAE_Suppress, false, false, 13)
+DIAG(warn_module_conflict, CLASS_WARNING, (unsigned)diag::Severity::Warning, "module '%0' conflicts with already-imported module '%1': %2", 284, SFINAE_Suppress, false, false, 13)
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
new file mode 100644
index 0000000..edd89ec
--- /dev/null
+++ b/include/clang/Basic/ExceptionSpecificationType.h
@@ -0,0 +1,59 @@
+//===--- ExceptionSpecificationType.h ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the ExceptionSpecificationType enumeration and various
+/// utility functions.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
+#define LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
+
+namespace clang {
+
+/// \brief The various types of exception specifications that exist in C++11.
+enum ExceptionSpecificationType {
+  EST_None,             ///< no exception specification
+  EST_DynamicNone,      ///< throw()
+  EST_Dynamic,          ///< throw(T1, T2)
+  EST_MSAny,            ///< Microsoft throw(...) extension
+  EST_BasicNoexcept,    ///< noexcept
+  EST_ComputedNoexcept, ///< noexcept(expression)
+  EST_Unevaluated,      ///< not evaluated yet, for special member function
+  EST_Uninstantiated    ///< not instantiated yet
+};
+
+inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {
+  return ESpecType >= EST_DynamicNone && ESpecType <= EST_MSAny;
+}
+
+inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) {
+  return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept;
+}
+
+inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) {
+  return ESpecType == EST_Unevaluated || ESpecType == EST_Uninstantiated;
+}
+
+/// \brief Possible results from evaluation of a noexcept expression.
+enum CanThrowResult {
+  CT_Cannot,
+  CT_Dependent,
+  CT_Can
+};
+
+inline CanThrowResult mergeCanThrow(CanThrowResult CT1, CanThrowResult CT2) {
+  // CanThrowResult constants are ordered so that the maximum is the correct
+  // merge result.
+  return CT1 > CT2 ? CT1 : CT2;
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h
new file mode 100644
index 0000000..e877715
--- /dev/null
+++ b/include/clang/Basic/ExpressionTraits.h
@@ -0,0 +1,26 @@
+//===- ExpressionTraits.h - C++ Expression Traits Support Enums -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines enumerations for expression traits intrinsics.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXPRESSIONTRAITS_H
+#define LLVM_CLANG_EXPRESSIONTRAITS_H
+
+namespace clang {
+
+  enum ExpressionTrait {
+    ET_IsLValueExpr,
+    ET_IsRValueExpr
+  };
+}
+
+#endif
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
new file mode 100644
index 0000000..0ad53c4
--- /dev/null
+++ b/include/clang/Basic/FileManager.h
@@ -0,0 +1,289 @@
+//===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::FileManager interface and associated types.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FILEMANAGER_H
+#define LLVM_CLANG_FILEMANAGER_H
+
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+// FIXME: Enhance libsystem to support inode and other fields in stat.
+#include <sys/types.h>
+#include <map>
+
+#ifdef _MSC_VER
+typedef unsigned short mode_t;
+#endif
+
+struct stat;
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+class FileManager;
+class FileSystemStatCache;
+
+/// \brief Cached information about one directory (either on disk or in
+/// the virtual file system).
+class DirectoryEntry {
+  const char *Name;   // Name of the directory.
+  friend class FileManager;
+public:
+  DirectoryEntry() : Name(nullptr) {}
+  const char *getName() const { return Name; }
+};
+
+/// \brief Cached information about one file (either on disk
+/// or in the virtual file system).
+///
+/// If the 'File' member is valid, then this FileEntry has an open file
+/// descriptor for the file.
+class FileEntry {
+  std::string Name;           // Name of the file.
+  off_t Size;                 // File size in bytes.
+  time_t ModTime;             // Modification time of file.
+  const DirectoryEntry *Dir;  // Directory file lives in.
+  unsigned UID;               // A unique (small) ID for the file.
+  llvm::sys::fs::UniqueID UniqueID;
+  bool IsNamedPipe;
+  bool InPCH;
+  bool IsValid;               // Is this \c FileEntry initialized and valid?
+
+  /// \brief The open file, if it is owned by the \p FileEntry.
+  mutable std::unique_ptr<vfs::File> File;
+  friend class FileManager;
+
+  void closeFile() const {
+    File.reset(); // rely on destructor to close File
+  }
+
+  void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
+
+public:
+  FileEntry()
+      : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
+  {}
+
+  // FIXME: this is here to allow putting FileEntry in std::map.  Once we have
+  // emplace, we shouldn't need a copy constructor anymore.
+  /// Intentionally does not copy fields that are not set in an uninitialized
+  /// \c FileEntry.
+  FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
+      IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
+    assert(!isValid() && "Cannot copy an initialized FileEntry");
+  }
+
+  const char *getName() const { return Name.c_str(); }
+  bool isValid() const { return IsValid; }
+  off_t getSize() const { return Size; }
+  unsigned getUID() const { return UID; }
+  const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
+  bool isInPCH() const { return InPCH; }
+  time_t getModificationTime() const { return ModTime; }
+
+  /// \brief Return the directory the file lives in.
+  const DirectoryEntry *getDir() const { return Dir; }
+
+  bool operator<(const FileEntry &RHS) const { return UniqueID < RHS.UniqueID; }
+
+  /// \brief Check whether the file is a named pipe (and thus can't be opened by
+  /// the native FileManager methods).
+  bool isNamedPipe() const { return IsNamedPipe; }
+};
+
+struct FileData;
+
+/// \brief Implements support for file system lookup, file system caching,
+/// and directory search management.
+///
+/// This also handles more advanced properties, such as uniquing files based
+/// on "inode", so that a file with two names (e.g. symlinked) will be treated
+/// as a single file.
+///
+class FileManager : public RefCountedBase<FileManager> {
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
+  FileSystemOptions FileSystemOpts;
+
+  /// \brief Cache for existing real directories.
+  std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
+
+  /// \brief Cache for existing real files.
+  std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
+
+  /// \brief The virtual directories that we have allocated.
+  ///
+  /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
+  /// directories (foo/ and foo/bar/) here.
+  SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries;
+  /// \brief The virtual files that we have allocated.
+  SmallVector<FileEntry*, 4> VirtualFileEntries;
+
+  /// \brief A cache that maps paths to directory entries (either real or
+  /// virtual) we have looked up
+  ///
+  /// The actual Entries for real directories/files are
+  /// owned by UniqueRealDirs/UniqueRealFiles above, while the Entries
+  /// for virtual directories/files are owned by
+  /// VirtualDirectoryEntries/VirtualFileEntries above.
+  ///
+  llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> SeenDirEntries;
+
+  /// \brief A cache that maps paths to file entries (either real or
+  /// virtual) we have looked up.
+  ///
+  /// \see SeenDirEntries
+  llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> SeenFileEntries;
+
+  /// \brief The canonical names of directories.
+  llvm::DenseMap<const DirectoryEntry *, llvm::StringRef> CanonicalDirNames;
+
+  /// \brief Storage for canonical names that we have computed.
+  llvm::BumpPtrAllocator CanonicalNameStorage;
+
+  /// \brief Each FileEntry we create is assigned a unique ID #.
+  ///
+  unsigned NextFileUID;
+
+  // Statistics.
+  unsigned NumDirLookups, NumFileLookups;
+  unsigned NumDirCacheMisses, NumFileCacheMisses;
+
+  // Caching.
+  std::unique_ptr<FileSystemStatCache> StatCache;
+
+  bool getStatValue(const char *Path, FileData &Data, bool isFile,
+                    std::unique_ptr<vfs::File> *F);
+
+  /// Add all ancestors of the given path (pointing to either a file
+  /// or a directory) as virtual directories.
+  void addAncestorsAsVirtualDirs(StringRef Path);
+
+public:
+  FileManager(const FileSystemOptions &FileSystemOpts,
+              IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
+  ~FileManager();
+
+  /// \brief Installs the provided FileSystemStatCache object within
+  /// the FileManager.
+  ///
+  /// Ownership of this object is transferred to the FileManager.
+  ///
+  /// \param statCache the new stat cache to install. Ownership of this
+  /// object is transferred to the FileManager.
+  ///
+  /// \param AtBeginning whether this new stat cache must be installed at the
+  /// beginning of the chain of stat caches. Otherwise, it will be added to
+  /// the end of the chain.
+  void addStatCache(FileSystemStatCache *statCache, bool AtBeginning = false);
+
+  /// \brief Removes the specified FileSystemStatCache object from the manager.
+  void removeStatCache(FileSystemStatCache *statCache);
+
+  /// \brief Removes all FileSystemStatCache objects from the manager.
+  void clearStatCaches();
+
+  /// \brief Lookup, cache, and verify the specified directory (real or
+  /// virtual).
+  ///
+  /// This returns NULL if the directory doesn't exist.
+  ///
+  /// \param CacheFailure If true and the file does not exist, we'll cache
+  /// the failure to find this file.
+  const DirectoryEntry *getDirectory(StringRef DirName,
+                                     bool CacheFailure = true);
+
+  /// \brief Lookup, cache, and verify the specified file (real or
+  /// virtual).
+  ///
+  /// This returns NULL if the file doesn't exist.
+  ///
+  /// \param OpenFile if true and the file exists, it will be opened.
+  ///
+  /// \param CacheFailure If true and the file does not exist, we'll cache
+  /// the failure to find this file.
+  const FileEntry *getFile(StringRef Filename, bool OpenFile = false,
+                           bool CacheFailure = true);
+
+  /// \brief Returns the current file system options
+  const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; }
+
+  IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
+    return FS;
+  }
+
+  /// \brief Retrieve a file entry for a "virtual" file that acts as
+  /// if there were a file with the given name on disk.
+  ///
+  /// The file itself is not accessed.
+  const FileEntry *getVirtualFile(StringRef Filename, off_t Size,
+                                  time_t ModificationTime);
+
+  /// \brief Open the specified file as a MemoryBuffer, returning a new
+  /// MemoryBuffer if successful, otherwise returning null.
+  llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
+                                       std::string *ErrorStr = nullptr,
+                                       bool isVolatile = false,
+                                       bool ShouldCloseOpenFile = true);
+  llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
+                                       std::string *ErrorStr = nullptr);
+
+  /// \brief Get the 'stat' information for the given \p Path.
+  ///
+  /// If the path is relative, it will be resolved against the WorkingDir of the
+  /// FileManager's FileSystemOptions.
+  ///
+  /// \returns false on success, true on error.
+  bool getNoncachedStatValue(StringRef Path,
+                             vfs::Status &Result);
+
+  /// \brief Remove the real file \p Entry from the cache.
+  void invalidateCache(const FileEntry *Entry);
+
+  /// \brief If path is not absolute and FileSystemOptions set the working
+  /// directory, the path is modified to be relative to the given
+  /// working directory.
+  void FixupRelativePath(SmallVectorImpl<char> &path) const;
+
+  /// \brief Produce an array mapping from the unique IDs assigned to each
+  /// file to the corresponding FileEntry pointer.
+  void GetUniqueIDMapping(
+                    SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
+
+  /// \brief Modifies the size and modification time of a previously created
+  /// FileEntry. Use with caution.
+  static void modifyFileEntry(FileEntry *File, off_t Size,
+                              time_t ModificationTime);
+
+  /// \brief Retrieve the canonical name for a given directory.
+  ///
+  /// This is a very expensive operation, despite its results being cached,
+  /// and should only be used when the physical layout of the file system is
+  /// required, which is (almost) never.
+  StringRef getCanonicalName(const DirectoryEntry *Dir);
+
+  void PrintStats() const;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
new file mode 100644
index 0000000..38f1346
--- /dev/null
+++ b/include/clang/Basic/FileSystemOptions.h
@@ -0,0 +1,32 @@
+//===--- FileSystemOptions.h - File System Options --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::FileSystemOptions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_FILESYSTEMOPTIONS_H
+#define LLVM_CLANG_BASIC_FILESYSTEMOPTIONS_H
+
+#include <string>
+
+namespace clang {
+
+/// \brief Keeps track of options that affect how file operations are performed.
+class FileSystemOptions {
+public:
+  /// \brief If set, paths are resolved as if the working directory was
+  /// set to the value of WorkingDir.
+  std::string WorkingDir;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
new file mode 100644
index 0000000..9be8b10
--- /dev/null
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -0,0 +1,129 @@
+//===--- FileSystemStatCache.h - Caching for 'stat' calls -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the FileSystemStatCache interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FILESYSTEMSTATCACHE_H
+#define LLVM_CLANG_FILESYSTEMSTATCACHE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/FileSystem.h"
+#include <memory>
+
+namespace clang {
+
+namespace vfs {
+class File;
+class FileSystem;
+}
+
+// FIXME: should probably replace this with vfs::Status
+struct FileData {
+  std::string Name;
+  uint64_t Size;
+  time_t ModTime;
+  llvm::sys::fs::UniqueID UniqueID;
+  bool IsDirectory;
+  bool IsNamedPipe;
+  bool InPCH;
+  bool IsVFSMapped; // FIXME: remove this when files support multiple names
+  FileData()
+      : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
+        InPCH(false), IsVFSMapped(false) {}
+};
+
+/// \brief Abstract interface for introducing a FileManager cache for 'stat'
+/// system calls, which is used by precompiled and pretokenized headers to
+/// improve performance.
+class FileSystemStatCache {
+  virtual void anchor();
+protected:
+  std::unique_ptr<FileSystemStatCache> NextStatCache;
+
+public:
+  virtual ~FileSystemStatCache() {}
+  
+  enum LookupResult {
+    CacheExists,   ///< We know the file exists and its cached stat data.
+    CacheMissing   ///< We know that the file doesn't exist.
+  };
+
+  /// \brief Get the 'stat' information for the specified path, using the cache
+  /// to accelerate it if possible.
+  ///
+  /// \returns \c true if the path does not exist or \c false if it exists.
+  ///
+  /// If isFile is true, then this lookup should only return success for files
+  /// (not directories).  If it is false this lookup should only return
+  /// success for directories (not files).  On a successful file lookup, the
+  /// implementation can optionally fill in \p F with a valid \p File object and
+  /// the client guarantees that it will close it.
+  static bool get(const char *Path, FileData &Data, bool isFile,
+                  std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
+                  vfs::FileSystem &FS);
+
+  /// \brief Sets the next stat call cache in the chain of stat caches.
+  /// Takes ownership of the given stat cache.
+  void setNextStatCache(FileSystemStatCache *Cache) {
+    NextStatCache.reset(Cache);
+  }
+  
+  /// \brief Retrieve the next stat call cache in the chain.
+  FileSystemStatCache *getNextStatCache() { return NextStatCache.get(); }
+  
+  /// \brief Retrieve the next stat call cache in the chain, transferring
+  /// ownership of this cache (and, transitively, all of the remaining caches)
+  /// to the caller.
+  FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
+
+protected:
+  // FIXME: The pointer here is a non-owning/optional reference to the
+  // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
+  // Optional needs some work to support references so this isn't possible yet.
+  virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+                               std::unique_ptr<vfs::File> *F,
+                               vfs::FileSystem &FS) = 0;
+
+  LookupResult statChained(const char *Path, FileData &Data, bool isFile,
+                           std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
+    if (FileSystemStatCache *Next = getNextStatCache())
+      return Next->getStat(Path, Data, isFile, F, FS);
+
+    // If we hit the end of the list of stat caches to try, just compute and
+    // return it without a cache.
+    return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
+  }
+};
+
+/// \brief A stat "cache" that can be used by FileManager to keep
+/// track of the results of stat() calls that occur throughout the
+/// execution of the front end.
+class MemorizeStatCalls : public FileSystemStatCache {
+public:
+  /// \brief The set of stat() calls that have been seen.
+  llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
+
+  typedef llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator
+  iterator;
+
+  iterator begin() const { return StatCalls.begin(); }
+  iterator end() const { return StatCalls.end(); }
+
+  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
new file mode 100644
index 0000000..0c278a1
--- /dev/null
+++ b/include/clang/Basic/IdentifierTable.h
@@ -0,0 +1,855 @@
+//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and
+/// clang::Selector interfaces.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+  template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+  class LangOptions;
+  class IdentifierInfo;
+  class IdentifierTable;
+  class SourceLocation;
+  class MultiKeywordSelector; // private class used by Selector
+  class DeclarationName;      // AST class that stores declaration names
+
+  /// \brief A simple pair of identifier info and location.
+  typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
+
+
+/// One of these records is kept for each identifier that
+/// is lexed.  This contains information about whether the token was \#define'd,
+/// is a language keyword, or if it is a front-end token of some sort (e.g. a
+/// variable or function name).  The preprocessor keeps this information in a
+/// set, and all tok::identifier tokens have a pointer to one of these.
+class IdentifierInfo {
+  unsigned TokenID            : 9; // Front-end token ID or tok::identifier.
+  // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
+  // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
+  // are for builtins.
+  unsigned ObjCOrBuiltinID    :11;
+  bool HasMacro               : 1; // True if there is a #define for this.
+  bool HadMacro               : 1; // True if there was a #define for this.
+  bool IsExtension            : 1; // True if identifier is a lang extension.
+  bool IsCXX11CompatKeyword   : 1; // True if identifier is a keyword in C++11.
+  bool IsPoisoned             : 1; // True if identifier is poisoned.
+  bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
+  bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
+  bool IsFromAST              : 1; // True if identifier was loaded (at least 
+                                   // partially) from an AST file.
+  bool ChangedAfterLoad       : 1; // True if identifier has changed from the
+                                   // definition loaded from an AST file.
+  bool RevertedTokenID        : 1; // True if RevertTokenIDToIdentifier was
+                                   // called.
+  bool OutOfDate              : 1; // True if there may be additional
+                                   // information about this identifier
+                                   // stored externally.
+  bool IsModulesImport        : 1; // True if this is the 'import' contextual
+                                   // keyword.
+  // 32-bit word is filled.
+
+  void *FETokenInfo;               // Managed by the language front-end.
+  llvm::StringMapEntry<IdentifierInfo*> *Entry;
+
+  IdentifierInfo(const IdentifierInfo&) LLVM_DELETED_FUNCTION;
+  void operator=(const IdentifierInfo&) LLVM_DELETED_FUNCTION;
+
+  friend class IdentifierTable;
+  
+public:
+  IdentifierInfo();
+
+
+  /// \brief Return true if this is the identifier for the specified string.
+  ///
+  /// This is intended to be used for string literals only: II->isStr("foo").
+  template <std::size_t StrLen>
+  bool isStr(const char (&Str)[StrLen]) const {
+    return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
+  }
+
+  /// \brief Return the beginning of the actual null-terminated string for this
+  /// identifier.
+  ///
+  const char *getNameStart() const {
+    if (Entry) return Entry->getKeyData();
+    // FIXME: This is gross. It would be best not to embed specific details
+    // of the PTH file format here.
+    // The 'this' pointer really points to a
+    // std::pair<IdentifierInfo, const char*>, where internal pointer
+    // points to the external string data.
+    typedef std::pair<IdentifierInfo, const char*> actualtype;
+    return ((const actualtype*) this)->second;
+  }
+
+  /// \brief Efficiently return the length of this identifier info.
+  ///
+  unsigned getLength() const {
+    if (Entry) return Entry->getKeyLength();
+    // FIXME: This is gross. It would be best not to embed specific details
+    // of the PTH file format here.
+    // The 'this' pointer really points to a
+    // std::pair<IdentifierInfo, const char*>, where internal pointer
+    // points to the external string data.
+    typedef std::pair<IdentifierInfo, const char*> actualtype;
+    const char* p = ((const actualtype*) this)->second - 2;
+    return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
+  }
+
+  /// \brief Return the actual identifier string.
+  StringRef getName() const {
+    return StringRef(getNameStart(), getLength());
+  }
+
+  /// \brief Return true if this identifier is \#defined to some other value.
+  bool hasMacroDefinition() const {
+    return HasMacro;
+  }
+  void setHasMacroDefinition(bool Val) {
+    if (HasMacro == Val) return;
+
+    HasMacro = Val;
+    if (Val) {
+      NeedsHandleIdentifier = 1;
+      HadMacro = true;
+    } else {
+      RecomputeNeedsHandleIdentifier();
+    }
+  }
+  /// \brief Returns true if this identifier was \#defined to some value at any
+  /// moment. In this case there should be an entry for the identifier in the
+  /// macro history table in Preprocessor.
+  bool hadMacroDefinition() const {
+    return HadMacro;
+  }
+
+  /// If this is a source-language token (e.g. 'for'), this API
+  /// can be used to cause the lexer to map identifiers to source-language
+  /// tokens.
+  tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
+
+  /// \brief True if RevertTokenIDToIdentifier() was called.
+  bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
+
+  /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
+  /// compatibility.
+  ///
+  /// TokenID is normally read-only but there are 2 instances where we revert it
+  /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
+  /// using this method so we can inform serialization about it.
+  void RevertTokenIDToIdentifier() {
+    assert(TokenID != tok::identifier && "Already at tok::identifier");
+    TokenID = tok::identifier;
+    RevertedTokenID = true;
+  }
+
+  /// \brief Return the preprocessor keyword ID for this identifier.
+  ///
+  /// For example, "define" will return tok::pp_define.
+  tok::PPKeywordKind getPPKeywordID() const;
+
+  /// \brief Return the Objective-C keyword ID for the this identifier.
+  ///
+  /// For example, 'class' will return tok::objc_class if ObjC is enabled.
+  tok::ObjCKeywordKind getObjCKeywordID() const {
+    if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
+      return tok::ObjCKeywordKind(ObjCOrBuiltinID);
+    else
+      return tok::objc_not_keyword;
+  }
+  void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
+
+  /// \brief Return a value indicating whether this is a builtin function.
+  ///
+  /// 0 is not-built-in.  1 is builtin-for-some-nonprimary-target.
+  /// 2+ are specific builtin functions.
+  unsigned getBuiltinID() const {
+    if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
+      return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
+    else
+      return 0;
+  }
+  void setBuiltinID(unsigned ID) {
+    ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
+    assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
+           && "ID too large for field!");
+  }
+
+  unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
+  void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
+
+  /// get/setExtension - Initialize information about whether or not this
+  /// language token is an extension.  This controls extension warnings, and is
+  /// only valid if a custom token ID is set.
+  bool isExtensionToken() const { return IsExtension; }
+  void setIsExtensionToken(bool Val) {
+    IsExtension = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// is/setIsCXX11CompatKeyword - Initialize information about whether or not
+  /// this language token is a keyword in C++11. This controls compatibility
+  /// warnings, and is only true when not parsing C++11. Once a compatibility
+  /// problem has been diagnosed with this keyword, the flag will be cleared.
+  bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; }
+  void setIsCXX11CompatKeyword(bool Val) {
+    IsCXX11CompatKeyword = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// setIsPoisoned - Mark this identifier as poisoned.  After poisoning, the
+  /// Preprocessor will emit an error every time this token is used.
+  void setIsPoisoned(bool Value = true) {
+    IsPoisoned = Value;
+    if (Value)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+
+  /// \brief Return true if this token has been poisoned.
+  bool isPoisoned() const { return IsPoisoned; }
+
+  /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
+  /// this identifier is a C++ alternate representation of an operator.
+  void setIsCPlusPlusOperatorKeyword(bool Val = true) {
+    IsCPPOperatorKeyword = Val;
+    if (Val)
+      NeedsHandleIdentifier = 1;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+  bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
+
+  /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
+  /// associate arbitrary metadata with this token.
+  template<typename T>
+  T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
+  void setFETokenInfo(void *T) { FETokenInfo = T; }
+
+  /// \brief Return true if the Preprocessor::HandleIdentifier must be called
+  /// on a token of this identifier.
+  ///
+  /// If this returns false, we know that HandleIdentifier will not affect
+  /// the token.
+  bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
+
+  /// \brief Return true if the identifier in its current state was loaded
+  /// from an AST file.
+  bool isFromAST() const { return IsFromAST; }
+
+  void setIsFromAST() { IsFromAST = true; }
+
+  /// \brief Determine whether this identifier has changed since it was loaded
+  /// from an AST file.
+  bool hasChangedSinceDeserialization() const {
+    return ChangedAfterLoad;
+  }
+  
+  /// \brief Note that this identifier has changed since it was loaded from
+  /// an AST file.
+  void setChangedSinceDeserialization() {
+    ChangedAfterLoad = true;
+  }
+
+  /// \brief Determine whether the information for this identifier is out of
+  /// date with respect to the external source.
+  bool isOutOfDate() const { return OutOfDate; }
+  
+  /// \brief Set whether the information for this identifier is out of
+  /// date with respect to the external source.
+  void setOutOfDate(bool OOD) {
+    OutOfDate = OOD;
+    if (OOD)
+      NeedsHandleIdentifier = true;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+  
+  /// \brief Determine whether this is the contextual keyword \c import.
+  bool isModulesImport() const { return IsModulesImport; }
+  
+  /// \brief Set whether this identifier is the contextual keyword \c import.
+  void setModulesImport(bool I) {
+    IsModulesImport = I;
+    if (I)
+      NeedsHandleIdentifier = true;
+    else
+      RecomputeNeedsHandleIdentifier();
+  }
+  
+private:
+  /// The Preprocessor::HandleIdentifier does several special (but rare)
+  /// things to identifiers of various sorts.  For example, it changes the
+  /// \c for keyword token from tok::identifier to tok::for.
+  ///
+  /// This method is very tied to the definition of HandleIdentifier.  Any
+  /// change to it should be reflected here.
+  void RecomputeNeedsHandleIdentifier() {
+    NeedsHandleIdentifier =
+      (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
+       isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() ||
+       isModulesImport());
+  }
+};
+
+/// \brief An RAII object for [un]poisoning an identifier within a scope.
+///
+/// \p II is allowed to be null, in which case objects of this type have
+/// no effect.
+class PoisonIdentifierRAIIObject {
+  IdentifierInfo *const II;
+  const bool OldValue;
+public:
+  PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
+    : II(II), OldValue(II ? II->isPoisoned() : false) {
+    if(II)
+      II->setIsPoisoned(NewValue);
+  }
+
+  ~PoisonIdentifierRAIIObject() {
+    if(II)
+      II->setIsPoisoned(OldValue);
+  }
+};
+
+/// \brief An iterator that walks over all of the known identifiers
+/// in the lookup table.
+///
+/// Since this iterator uses an abstract interface via virtual
+/// functions, it uses an object-oriented interface rather than the
+/// more standard C++ STL iterator interface. In this OO-style
+/// iteration, the single function \c Next() provides dereference,
+/// advance, and end-of-sequence checking in a single
+/// operation. Subclasses of this iterator type will provide the
+/// actual functionality.
+class IdentifierIterator {
+private:
+  IdentifierIterator(const IdentifierIterator &) LLVM_DELETED_FUNCTION;
+  void operator=(const IdentifierIterator &) LLVM_DELETED_FUNCTION;
+
+protected:
+  IdentifierIterator() { }
+  
+public:
+  virtual ~IdentifierIterator();
+
+  /// \brief Retrieve the next string in the identifier table and
+  /// advances the iterator for the following string.
+  ///
+  /// \returns The next string in the identifier table. If there is
+  /// no such string, returns an empty \c StringRef.
+  virtual StringRef Next() = 0;
+};
+
+/// \brief Provides lookups to, and iteration over, IdentiferInfo objects.
+class IdentifierInfoLookup {
+public:
+  virtual ~IdentifierInfoLookup();
+
+  /// \brief Return the IdentifierInfo for the specified named identifier.
+  ///
+  /// Unlike the version in IdentifierTable, this returns a pointer instead
+  /// of a reference.  If the pointer is null then the IdentifierInfo cannot
+  /// be found.
+  virtual IdentifierInfo* get(StringRef Name) = 0;
+
+  /// \brief Retrieve an iterator into the set of all identifiers
+  /// known to this identifier lookup source.
+  ///
+  /// This routine provides access to all of the identifiers known to
+  /// the identifier lookup, allowing access to the contents of the
+  /// identifiers without introducing the overhead of constructing
+  /// IdentifierInfo objects for each.
+  ///
+  /// \returns A new iterator into the set of known identifiers. The
+  /// caller is responsible for deleting this iterator.
+  virtual IdentifierIterator *getIdentifiers();
+};
+
+/// \brief An abstract class used to resolve numerical identifier
+/// references (meaningful only to some external source) into
+/// IdentifierInfo pointers.
+class ExternalIdentifierLookup {
+public:
+  virtual ~ExternalIdentifierLookup();
+
+  /// \brief Return the identifier associated with the given ID number.
+  ///
+  /// The ID 0 is associated with the NULL identifier.
+  virtual IdentifierInfo *GetIdentifier(unsigned ID) = 0;
+};
+
+/// \brief Implements an efficient mapping from strings to IdentifierInfo nodes.
+///
+/// This has no other purpose, but this is an extremely performance-critical
+/// piece of the code, as each occurrence of every identifier goes through
+/// here when lexed.
+class IdentifierTable {
+  // Shark shows that using MallocAllocator is *much* slower than using this
+  // BumpPtrAllocator!
+  typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
+  HashTableTy HashTable;
+
+  IdentifierInfoLookup* ExternalLookup;
+
+public:
+  /// \brief Create the identifier table, populating it with info about the
+  /// language keywords for the language specified by \p LangOpts.
+  IdentifierTable(const LangOptions &LangOpts,
+                  IdentifierInfoLookup* externalLookup = nullptr);
+
+  /// \brief Set the external identifier lookup mechanism.
+  void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
+    ExternalLookup = IILookup;
+  }
+
+  /// \brief Retrieve the external identifier lookup object, if any.
+  IdentifierInfoLookup *getExternalIdentifierLookup() const {
+    return ExternalLookup;
+  }
+  
+  llvm::BumpPtrAllocator& getAllocator() {
+    return HashTable.getAllocator();
+  }
+
+  /// \brief Return the identifier token info for the specified named
+  /// identifier.
+  IdentifierInfo &get(StringRef Name) {
+    llvm::StringMapEntry<IdentifierInfo*> &Entry =
+      HashTable.GetOrCreateValue(Name);
+
+    IdentifierInfo *II = Entry.getValue();
+    if (II) return *II;
+
+    // No entry; if we have an external lookup, look there first.
+    if (ExternalLookup) {
+      II = ExternalLookup->get(Name);
+      if (II) {
+        // Cache in the StringMap for subsequent lookups.
+        Entry.setValue(II);
+        return *II;
+      }
+    }
+
+    // Lookups failed, make a new IdentifierInfo.
+    void *Mem = getAllocator().Allocate<IdentifierInfo>();
+    II = new (Mem) IdentifierInfo();
+    Entry.setValue(II);
+
+    // Make sure getName() knows how to find the IdentifierInfo
+    // contents.
+    II->Entry = &Entry;
+
+    return *II;
+  }
+
+  IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) {
+    IdentifierInfo &II = get(Name);
+    II.TokenID = TokenCode;
+    assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large");
+    return II;
+  }
+
+  /// \brief Gets an IdentifierInfo for the given name without consulting
+  ///        external sources.
+  ///
+  /// This is a version of get() meant for external sources that want to
+  /// introduce or modify an identifier. If they called get(), they would
+  /// likely end up in a recursion.
+  IdentifierInfo &getOwn(StringRef Name) {
+    llvm::StringMapEntry<IdentifierInfo*> &Entry =
+      HashTable.GetOrCreateValue(Name);
+
+    IdentifierInfo *II = Entry.getValue();
+    if (!II) {
+
+      // Lookups failed, make a new IdentifierInfo.
+      void *Mem = getAllocator().Allocate<IdentifierInfo>();
+      II = new (Mem) IdentifierInfo();
+      Entry.setValue(II);
+
+      // Make sure getName() knows how to find the IdentifierInfo
+      // contents.
+      II->Entry = &Entry;
+      
+      // If this is the 'import' contextual keyword, mark it as such.
+      if (Name.equals("import"))
+        II->setModulesImport(true);
+    }
+
+    return *II;
+  }
+
+  typedef HashTableTy::const_iterator iterator;
+  typedef HashTableTy::const_iterator const_iterator;
+
+  iterator begin() const { return HashTable.begin(); }
+  iterator end() const   { return HashTable.end(); }
+  unsigned size() const { return HashTable.size(); }
+
+  /// \brief Print some statistics to stderr that indicate how well the
+  /// hashing is doing.
+  void PrintStats() const;
+
+  void AddKeywords(const LangOptions &LangOpts);
+};
+
+/// \brief A family of Objective-C methods. 
+///
+/// These families have no inherent meaning in the language, but are
+/// nonetheless central enough in the existing implementations to
+/// merit direct AST support.  While, in theory, arbitrary methods can
+/// be considered to form families, we focus here on the methods
+/// involving allocation and retain-count management, as these are the
+/// most "core" and the most likely to be useful to diverse clients
+/// without extra information.
+///
+/// Both selectors and actual method declarations may be classified
+/// into families.  Method families may impose additional restrictions
+/// beyond their selector name; for example, a method called '_init'
+/// that returns void is not considered to be in the 'init' family
+/// (but would be if it returned 'id').  It is also possible to
+/// explicitly change or remove a method's family.  Therefore the
+/// method's family should be considered the single source of truth.
+enum ObjCMethodFamily {
+  /// \brief No particular method family.
+  OMF_None,
+
+  // Selectors in these families may have arbitrary arity, may be
+  // written with arbitrary leading underscores, and may have
+  // additional CamelCase "words" in their first selector chunk
+  // following the family name.
+  OMF_alloc,
+  OMF_copy,
+  OMF_init,
+  OMF_mutableCopy,
+  OMF_new,
+
+  // These families are singletons consisting only of the nullary
+  // selector with the given name.
+  OMF_autorelease,
+  OMF_dealloc,
+  OMF_finalize,
+  OMF_release,
+  OMF_retain,
+  OMF_retainCount,
+  OMF_self,
+
+  // performSelector families
+  OMF_performSelector
+};
+
+/// Enough bits to store any enumerator in ObjCMethodFamily or
+/// InvalidObjCMethodFamily.
+enum { ObjCMethodFamilyBitWidth = 4 };
+
+/// \brief An invalid value of ObjCMethodFamily.
+enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
+
+/// \brief A family of Objective-C methods.
+///
+/// These are family of methods whose result type is initially 'id', but
+/// but are candidate for the result type to be changed to 'instancetype'.
+enum ObjCInstanceTypeFamily {
+  OIT_None,
+  OIT_Array,
+  OIT_Dictionary,
+  OIT_Singleton,
+  OIT_Init,
+  OIT_ReturnsSelf
+};
+
+/// \brief Smart pointer class that efficiently represents Objective-C method
+/// names.
+///
+/// This class will either point to an IdentifierInfo or a
+/// MultiKeywordSelector (which is private). This enables us to optimize
+/// selectors that take no arguments and selectors that take 1 argument, which
+/// accounts for 78% of all selectors in Cocoa.h.
+class Selector {
+  friend class Diagnostic;
+
+  enum IdentifierInfoFlag {
+    // Empty selector = 0.
+    ZeroArg  = 0x1,
+    OneArg   = 0x2,
+    MultiArg = 0x3,
+    ArgFlags = ZeroArg|OneArg
+  };
+  uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
+
+  Selector(IdentifierInfo *II, unsigned nArgs) {
+    InfoPtr = reinterpret_cast<uintptr_t>(II);
+    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
+    assert(nArgs < 2 && "nArgs not equal to 0/1");
+    InfoPtr |= nArgs+1;
+  }
+  Selector(MultiKeywordSelector *SI) {
+    InfoPtr = reinterpret_cast<uintptr_t>(SI);
+    assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
+    InfoPtr |= MultiArg;
+  }
+
+  IdentifierInfo *getAsIdentifierInfo() const {
+    if (getIdentifierInfoFlag() < MultiArg)
+      return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
+    return nullptr;
+  }
+  MultiKeywordSelector *getMultiKeywordSelector() const {
+    return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
+  }
+  
+  unsigned getIdentifierInfoFlag() const {
+    return InfoPtr & ArgFlags;
+  }
+
+  static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
+
+public:
+  friend class SelectorTable; // only the SelectorTable can create these
+  friend class DeclarationName; // and the AST's DeclarationName.
+
+  /// The default ctor should only be used when creating data structures that
+  ///  will contain selectors.
+  Selector() : InfoPtr(0) {}
+  Selector(uintptr_t V) : InfoPtr(V) {}
+
+  /// operator==/!= - Indicate whether the specified selectors are identical.
+  bool operator==(Selector RHS) const {
+    return InfoPtr == RHS.InfoPtr;
+  }
+  bool operator!=(Selector RHS) const {
+    return InfoPtr != RHS.InfoPtr;
+  }
+  void *getAsOpaquePtr() const {
+    return reinterpret_cast<void*>(InfoPtr);
+  }
+
+  /// \brief Determine whether this is the empty selector.
+  bool isNull() const { return InfoPtr == 0; }
+
+  // Predicates to identify the selector type.
+  bool isKeywordSelector() const {
+    return getIdentifierInfoFlag() != ZeroArg;
+  }
+  bool isUnarySelector() const {
+    return getIdentifierInfoFlag() == ZeroArg;
+  }
+  unsigned getNumArgs() const;
+  
+  
+  /// \brief Retrieve the identifier at a given position in the selector.
+  ///
+  /// Note that the identifier pointer returned may be NULL. Clients that only
+  /// care about the text of the identifier string, and not the specific, 
+  /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
+  /// an empty string when the identifier pointer would be NULL.
+  ///
+  /// \param argIndex The index for which we want to retrieve the identifier.
+  /// This index shall be less than \c getNumArgs() unless this is a keyword
+  /// selector, in which case 0 is the only permissible value.
+  ///
+  /// \returns the uniqued identifier for this slot, or NULL if this slot has
+  /// no corresponding identifier.
+  IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
+  
+  /// \brief Retrieve the name at a given position in the selector.
+  ///
+  /// \param argIndex The index for which we want to retrieve the name.
+  /// This index shall be less than \c getNumArgs() unless this is a keyword
+  /// selector, in which case 0 is the only permissible value.
+  ///
+  /// \returns the name for this slot, which may be the empty string if no
+  /// name was supplied.
+  StringRef getNameForSlot(unsigned argIndex) const;
+  
+  /// \brief Derive the full selector name (e.g. "foo:bar:") and return
+  /// it as an std::string.
+  std::string getAsString() const;
+
+  /// \brief Prints the full selector name (e.g. "foo:bar:").
+  void print(llvm::raw_ostream &OS) const;
+
+  /// \brief Derive the conventional family of this method.
+  ObjCMethodFamily getMethodFamily() const {
+    return getMethodFamilyImpl(*this);
+  }
+
+  static Selector getEmptyMarker() {
+    return Selector(uintptr_t(-1));
+  }
+  static Selector getTombstoneMarker() {
+    return Selector(uintptr_t(-2));
+  }
+  
+  static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
+};
+
+/// \brief This table allows us to fully hide how we implement
+/// multi-keyword caching.
+class SelectorTable {
+  void *Impl;  // Actually a SelectorTableImpl
+  SelectorTable(const SelectorTable &) LLVM_DELETED_FUNCTION;
+  void operator=(const SelectorTable &) LLVM_DELETED_FUNCTION;
+public:
+  SelectorTable();
+  ~SelectorTable();
+
+  /// \brief Can create any sort of selector.
+  ///
+  /// \p NumArgs indicates whether this is a no argument selector "foo", a
+  /// single argument selector "foo:" or multi-argument "foo:bar:".
+  Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
+
+  Selector getUnarySelector(IdentifierInfo *ID) {
+    return Selector(ID, 1);
+  }
+  Selector getNullarySelector(IdentifierInfo *ID) {
+    return Selector(ID, 0);
+  }
+
+  /// \brief Return the total amount of memory allocated for managing selectors.
+  size_t getTotalMemory() const;
+
+  /// \brief Return the default setter name for the given identifier.
+  ///
+  /// This is "set" + \p Name where the initial character of \p Name
+  /// has been capitalized.
+  static SmallString<64> constructSetterName(StringRef Name);
+
+  /// \brief Return the default setter selector for the given identifier.
+  ///
+  /// This is "set" + \p Name where the initial character of \p Name
+  /// has been capitalized.
+  static Selector constructSetterSelector(IdentifierTable &Idents,
+                                          SelectorTable &SelTable,
+                                          const IdentifierInfo *Name);
+};
+
+/// DeclarationNameExtra - Common base of the MultiKeywordSelector,
+/// CXXSpecialName, and CXXOperatorIdName classes, all of which are
+/// private classes that describe different kinds of names.
+class DeclarationNameExtra {
+public:
+  /// ExtraKind - The kind of "extra" information stored in the
+  /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
+  /// how these enumerator values are used.
+  enum ExtraKind {
+    CXXConstructor = 0,
+    CXXDestructor,
+    CXXConversionFunction,
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+    CXXOperator##Name,
+#include "clang/Basic/OperatorKinds.def"
+    CXXLiteralOperator,
+    CXXUsingDirective,
+    NUM_EXTRA_KINDS
+  };
+
+  /// ExtraKindOrNumArgs - Either the kind of C++ special name or
+  /// operator-id (if the value is one of the CXX* enumerators of
+  /// ExtraKind), in which case the DeclarationNameExtra is also a
+  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
+  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
+  /// it may be also name common to C++ using-directives (CXXUsingDirective),
+  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
+  /// arguments in the Objective-C selector, in which case the
+  /// DeclarationNameExtra is also a MultiKeywordSelector.
+  unsigned ExtraKindOrNumArgs;
+};
+
+}  // end namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
+/// DenseSets.
+template <>
+struct DenseMapInfo<clang::Selector> {
+  static inline clang::Selector getEmptyKey() {
+    return clang::Selector::getEmptyMarker();
+  }
+  static inline clang::Selector getTombstoneKey() {
+    return clang::Selector::getTombstoneMarker();
+  }
+
+  static unsigned getHashValue(clang::Selector S);
+
+  static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
+    return LHS == RHS;
+  }
+};
+
+template <>
+struct isPodLike<clang::Selector> { static const bool value = true; };
+
+template <typename T> class PointerLikeTypeTraits;
+
+template<>
+class PointerLikeTypeTraits<clang::Selector> {
+public:
+  static inline const void *getAsVoidPointer(clang::Selector P) {
+    return P.getAsOpaquePtr();
+  }
+  static inline clang::Selector getFromVoidPointer(const void *P) {
+    return clang::Selector(reinterpret_cast<uintptr_t>(P));
+  }
+  enum { NumLowBitsAvailable = 0 };  
+};
+
+// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
+// are not guaranteed to be 8-byte aligned.
+template<>
+class PointerLikeTypeTraits<clang::IdentifierInfo*> {
+public:
+  static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
+    return P;
+  }
+  static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
+    return static_cast<clang::IdentifierInfo*>(P);
+  }
+  enum { NumLowBitsAvailable = 1 };
+};
+
+template<>
+class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
+public:
+  static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
+    return P;
+  }
+  static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
+    return static_cast<const clang::IdentifierInfo*>(P);
+  }
+  enum { NumLowBitsAvailable = 1 };
+};
+
+}  // end namespace llvm
+#endif
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
new file mode 100644
index 0000000..5a71fa8
--- /dev/null
+++ b/include/clang/Basic/LLVM.h
@@ -0,0 +1,81 @@
+//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// \brief Forward-declares and imports various common LLVM datatypes that
+/// clang wants to use unqualified.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_LLVM_H
+#define CLANG_BASIC_LLVM_H
+
+// Do not proliferate #includes here, require clients to #include their
+// dependencies.
+// Casting.h has complex templates that cannot be easily forward declared.
+#include "llvm/Support/Casting.h"
+// None.h includes an enumerator that is desired & cannot be forward declared
+// without a definition of NoneType.
+#include "llvm/ADT/None.h"
+
+namespace llvm {
+  // ADT's.
+  class StringRef;
+  class Twine;
+  template<typename T> class ArrayRef;
+  template<typename T> class MutableArrayRef;
+  template<unsigned InternalLen> class SmallString;
+  template<typename T, unsigned N> class SmallVector;
+  template<typename T> class SmallVectorImpl;
+  template<typename T> class Optional;
+
+  template<typename T>
+  struct SaveAndRestore;
+
+  // Reference counting.
+  template <typename T> class IntrusiveRefCntPtr;
+  template <typename T> struct IntrusiveRefCntPtrInfo;
+  template <class Derived> class RefCountedBase;
+  class RefCountedBaseVPTR;
+
+  class raw_ostream;
+  // TODO: DenseMap, ...
+}
+
+
+namespace clang {
+  // Casting operators.
+  using llvm::isa;
+  using llvm::cast;
+  using llvm::dyn_cast;
+  using llvm::dyn_cast_or_null;
+  using llvm::cast_or_null;
+  
+  // ADT's.
+  using llvm::None;
+  using llvm::Optional;
+  using llvm::StringRef;
+  using llvm::Twine;
+  using llvm::ArrayRef;
+  using llvm::MutableArrayRef;
+  using llvm::SmallString;
+  using llvm::SmallVector;
+  using llvm::SmallVectorImpl;
+  using llvm::SaveAndRestore;
+
+  // Reference counting.
+  using llvm::IntrusiveRefCntPtr;
+  using llvm::IntrusiveRefCntPtrInfo;
+  using llvm::RefCountedBase;
+  using llvm::RefCountedBaseVPTR;
+
+  using llvm::raw_ostream;
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h
new file mode 100644
index 0000000..280ae94
--- /dev/null
+++ b/include/clang/Basic/Lambda.h
@@ -0,0 +1,42 @@
+//===--- Lambda.h - Types for C++ Lambdas -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines several types used to describe C++ lambda expressions
+/// that are shared between the parser and AST.
+///
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_BASIC_LAMBDA_H
+#define LLVM_CLANG_BASIC_LAMBDA_H
+
+namespace clang {
+
+/// \brief The default, if any, capture method for a lambda expression.
+enum LambdaCaptureDefault {
+  LCD_None,
+  LCD_ByCopy,
+  LCD_ByRef
+};
+
+/// \brief The different capture forms in a lambda introducer
+///
+/// C++11 allows capture of \c this, or of local variables by copy or
+/// by reference.  C++1y also allows "init-capture", where the initializer
+/// is an expression.
+enum LambdaCaptureKind {
+  LCK_This,   ///< Capturing the \c this pointer
+  LCK_ByCopy, ///< Capturing by copy (a.k.a., by value)
+  LCK_ByRef   ///< Capturing by reference
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_LAMBDA_H
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
new file mode 100644
index 0000000..a297a4c
--- /dev/null
+++ b/include/clang/Basic/LangOptions.def
@@ -0,0 +1,195 @@
+//===--- LangOptions.def - Language option database -------------*- 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 language options. Users of this file must
+// define the LANGOPT macro to make use of this information.
+// Optionally, the user may also define BENIGN_LANGOPT
+// (for options that don't affect the construction of the AST in an
+// incompatible way), ENUM_LANGOPT (for options that have enumeration,
+// rather than unsigned, type), BENIGN_ENUM_LANGOPT (for benign
+// options that have enumeration type), and VALUE_LANGOPT is a language option
+// that describes a value rather than a flag.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LANGOPT
+#  error Define the LANGOPT macro to handle language options
+#endif
+
+#ifndef VALUE_LANGOPT
+#  define VALUE_LANGOPT(Name, Bits, Default, Description) \
+     LANGOPT(Name, Bits, Default, Description)
+#endif
+
+#ifndef BENIGN_LANGOPT
+#  define BENIGN_LANGOPT(Name, Bits, Default, Description) \
+     LANGOPT(Name, Bits, Default, Description)
+#endif
+
+#ifndef ENUM_LANGOPT
+#  define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+     LANGOPT(Name, Bits, Default, Description)
+#endif
+
+#ifndef BENIGN_ENUM_LANGOPT
+#  define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+     ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#endif
+
+LANGOPT(C99               , 1, 0, "C99")
+LANGOPT(C11               , 1, 0, "C11")
+LANGOPT(MSVCCompat        , 1, 0, "Microsoft Visual C++ full compatibility mode")
+LANGOPT(MicrosoftExt      , 1, 0, "Microsoft C++ extensions")
+LANGOPT(AsmBlocks         , 1, 0, "Microsoft inline asm blocks")
+LANGOPT(Borland           , 1, 0, "Borland extensions")
+LANGOPT(CPlusPlus         , 1, 0, "C++")
+LANGOPT(CPlusPlus11       , 1, 0, "C++11")
+LANGOPT(CPlusPlus1y       , 1, 0, "C++1y")
+LANGOPT(CPlusPlus1z       , 1, 0, "C++1z")
+LANGOPT(ObjC1             , 1, 0, "Objective-C 1")
+LANGOPT(ObjC2             , 1, 0, "Objective-C 2")
+BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
+               "Objective-C auto-synthesized properties")
+BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0,
+               "Encoding extended block type signature")
+BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1,
+               "Objective-C related result type inference")
+LANGOPT(Trigraphs         , 1, 0,"trigraphs")
+LANGOPT(LineComment       , 1, 0, "'//' comments")
+LANGOPT(Bool              , 1, 0, "bool, true, and false keywords")
+LANGOPT(Half              , 1, 0, "half keyword")
+LANGOPT(WChar             , 1, CPlusPlus, "wchar_t keyword")
+BENIGN_LANGOPT(DollarIdents   , 1, 1, "'$' in identifiers")
+BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
+BENIGN_LANGOPT(GNUMode        , 1, 1, "GNU extensions")
+LANGOPT(GNUKeywords       , 1, 1, "GNU keywords")
+BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
+LANGOPT(Digraphs          , 1, 0, "digraphs")
+BENIGN_LANGOPT(HexFloats  , 1, C99, "C99 hexadecimal float constants")
+LANGOPT(CXXOperatorNames  , 1, 0, "C++ operator name keywords")
+LANGOPT(AppleKext         , 1, 0, "Apple kext support")
+BENIGN_LANGOPT(PascalStrings, 1, 0, "Pascal string support")
+LANGOPT(WritableStrings   , 1, 0, "writable string support")
+LANGOPT(ConstStrings      , 1, 0, "const-qualified string support")
+LANGOPT(LaxVectorConversions , 1, 1, "lax vector conversions")
+LANGOPT(AltiVec           , 1, 0, "AltiVec-style vector initializers")
+LANGOPT(Exceptions        , 1, 0, "exception handling")
+LANGOPT(ObjCExceptions    , 1, 0, "Objective-C exceptions")
+LANGOPT(CXXExceptions     , 1, 0, "C++ exceptions")
+LANGOPT(SjLjExceptions    , 1, 0, "setjmp-longjump exception handling")
+LANGOPT(TraditionalCPP    , 1, 0, "traditional CPP emulation")
+LANGOPT(RTTI              , 1, 1, "run-time type information")
+LANGOPT(RTTIData          , 1, 1, "emit run-time type information data")
+LANGOPT(MSBitfields       , 1, 0, "Microsoft-compatible structure layout")
+LANGOPT(Freestanding, 1, 0, "freestanding implementation")
+LANGOPT(NoBuiltin         , 1, 0, "disable builtin functions")
+LANGOPT(NoMathBuiltin     , 1, 0, "disable math builtin functions")
+
+BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers")
+LANGOPT(POSIXThreads      , 1, 0, "POSIX thread support")
+LANGOPT(Blocks            , 1, 0, "blocks extension to C")
+BENIGN_LANGOPT(EmitAllDecls      , 1, 0, "support for emitting all declarations")
+LANGOPT(MathErrno         , 1, 1, "errno support for math functions")
+BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time")
+LANGOPT(Modules           , 1, 0, "modules extension to C")
+LANGOPT(ModulesDeclUse    , 1, 0, "require declaration of module uses")
+LANGOPT(ModulesSearchAll  , 1, 1, "search even non-imported modules to find unresolved references")
+LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
+LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
+LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
+LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
+LANGOPT(Static            , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
+VALUE_LANGOPT(PackStruct  , 32, 0,
+              "default struct packing maximum alignment")
+VALUE_LANGOPT(PICLevel    , 2, 0, "__PIC__ level")
+VALUE_LANGOPT(PIELevel    , 2, 0, "__PIE__ level")
+LANGOPT(GNUInline         , 1, 0, "GNU inline semantics")
+LANGOPT(NoInlineDefine    , 1, 0, "__NO_INLINE__ predefined macro")
+LANGOPT(Deprecated        , 1, 0, "__DEPRECATED predefined macro")
+LANGOPT(FastMath          , 1, 0, "__FAST_MATH__ predefined macro")
+LANGOPT(FiniteMathOnly    , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
+
+BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
+
+BENIGN_LANGOPT(AccessControl     , 1, 1, "C++ access control")
+LANGOPT(CharIsSigned      , 1, 1, "signed char")
+LANGOPT(ShortWChar        , 1, 0, "unsigned short wchar_t")
+ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
+
+LANGOPT(ShortEnums        , 1, 0, "short enum types")
+
+LANGOPT(OpenCL            , 1, 0, "OpenCL")
+LANGOPT(OpenCLVersion     , 32, 0, "OpenCL version")
+LANGOPT(NativeHalfType    , 1, 0, "Native half type support")
+LANGOPT(CUDA              , 1, 0, "CUDA")
+LANGOPT(OpenMP            , 1, 0, "OpenMP support")
+
+LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators")
+LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions")
+BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
+BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records")
+BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form")
+BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
+LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings")
+BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
+BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
+BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
+BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
+BENIGN_LANGOPT(DebuggerObjCLiteral , 1, 0, "debugger Objective-C literals and subscripting support")
+
+BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
+LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
+LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
+LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
+LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
+LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
+LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
+LANGOPT(ObjCARCWeak         , 1, 0, "__weak support in the ARC runtime")
+LANGOPT(ObjCSubscriptingLegacyRuntime         , 1, 0, "Subscripting support in legacy ObjectiveC runtime")
+LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
+ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
+
+LANGOPT(MRTD , 1, 0, "-mrtd calling convention")
+BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing")
+LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime")
+
+ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
+ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
+             "value symbol visibility")
+ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
+             "type symbol visibility")
+ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
+             "stack protector mode")
+ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
+             "signed integer overflow handling")
+
+BENIGN_LANGOPT(ArrowDepth, 32, 256,
+               "maximum number of operator->s to follow")
+BENIGN_LANGOPT(InstantiationDepth, 32, 256,
+               "maximum template instantiation depth")
+BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
+               "maximum constexpr call depth")
+BENIGN_LANGOPT(ConstexprStepLimit, 32, 1048576,
+               "maximum constexpr evaluation steps")
+BENIGN_LANGOPT(BracketDepth, 32, 256,
+               "maximum bracket nesting depth")
+BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
+        "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
+VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
+VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
+
+LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
+
+LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+
+#undef LANGOPT
+#undef VALUE_LANGOPT
+#undef BENIGN_LANGOPT
+#undef ENUM_LANGOPT
+#undef BENIGN_ENUM_LANGOPT
+
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
new file mode 100644
index 0000000..9bffc7c
--- /dev/null
+++ b/include/clang/Basic/LangOptions.h
@@ -0,0 +1,153 @@
+//===--- LangOptions.h - C Language Family Language Options -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::LangOptions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LANGOPTIONS_H
+#define LLVM_CLANG_LANGOPTIONS_H
+
+#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Visibility.h"
+#include <string>
+
+namespace clang {
+
+struct SanitizerOptions {
+#define SANITIZER(NAME, ID) unsigned ID : 1;
+#include "clang/Basic/Sanitizers.def"
+
+  /// \brief Cached set of sanitizer options with all sanitizers disabled.
+  static const SanitizerOptions Disabled;
+};
+
+/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
+/// this large collection of bitfields is a trivial class type.
+class LangOptionsBase {
+public:
+  // Define simple language options (with no accessors).
+#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
+#include "clang/Basic/LangOptions.def"
+
+  SanitizerOptions Sanitize;
+protected:
+  // Define language options of enumeration type. These are private, and will
+  // have accessors (below).
+#define LANGOPT(Name, Bits, Default, Description)
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+  unsigned Name : Bits;
+#include "clang/Basic/LangOptions.def"
+};
+
+/// \brief Keeps track of the various options that can be
+/// enabled, which controls the dialect of C or C++ that is accepted.
+class LangOptions : public LangOptionsBase {
+public:
+  typedef clang::Visibility Visibility;
+  
+  enum GCMode { NonGC, GCOnly, HybridGC };
+  enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
+  
+  enum SignedOverflowBehaviorTy {
+    SOB_Undefined,  // Default C standard behavior.
+    SOB_Defined,    // -fwrapv
+    SOB_Trapping    // -ftrapv
+  };
+
+  enum PragmaMSPointersToMembersKind {
+    PPTMK_BestCase,
+    PPTMK_FullGeneralitySingleInheritance,
+    PPTMK_FullGeneralityMultipleInheritance,
+    PPTMK_FullGeneralityVirtualInheritance
+  };
+
+  enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
+
+public:
+  clang::ObjCRuntime ObjCRuntime;
+
+  std::string ObjCConstantStringClass;
+  
+  /// \brief The name of the handler function to be called when -ftrapv is
+  /// specified.
+  ///
+  /// If none is specified, abort (GCC-compatible behaviour).
+  std::string OverflowHandler;
+
+  /// \brief The name of the current module.
+  std::string CurrentModule;
+
+  /// \brief Options for parsing comments.
+  CommentOptions CommentOpts;
+  
+  LangOptions();
+
+  // Define accessors/mutators for language options of enumeration type.
+#define LANGOPT(Name, Bits, Default, Description) 
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+  Type get##Name() const { return static_cast<Type>(Name); } \
+  void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }  
+#include "clang/Basic/LangOptions.def"
+  
+  bool isSignedOverflowDefined() const {
+    return getSignedOverflowBehavior() == SOB_Defined;
+  }
+  
+  bool isSubscriptPointerArithmetic() const {
+    return ObjCRuntime.isSubscriptPointerArithmetic() &&
+           !ObjCSubscriptingLegacyRuntime;
+  }
+
+  /// \brief Reset all of the options that are not considered when building a
+  /// module.
+  void resetNonModularOptions();
+};
+
+/// \brief Floating point control options
+class FPOptions {
+public:
+  unsigned fp_contract : 1;
+
+  FPOptions() : fp_contract(0) {}
+
+  FPOptions(const LangOptions &LangOpts) :
+    fp_contract(LangOpts.DefaultFPContract) {}
+};
+
+/// \brief OpenCL volatile options
+class OpenCLOptions {
+public:
+#define OPENCLEXT(nm)  unsigned nm : 1;
+#include "clang/Basic/OpenCLExtensions.def"
+
+  OpenCLOptions() {
+#define OPENCLEXT(nm)   nm = 0;
+#include "clang/Basic/OpenCLExtensions.def"
+  }
+};
+
+/// \brief Describes the kind of translation unit being processed.
+enum TranslationUnitKind {
+  /// \brief The translation unit is a complete translation unit.
+  TU_Complete,
+  /// \brief The translation unit is a prefix to a translation unit, and is
+  /// not complete.
+  TU_Prefix,
+  /// \brief The translation unit is a module.
+  TU_Module
+};
+  
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
new file mode 100644
index 0000000..f3b4769
--- /dev/null
+++ b/include/clang/Basic/Linkage.h
@@ -0,0 +1,106 @@
+//===--- Linkage.h - Linkage enumeration and utilities ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the Linkage enumeration and various utility functions.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_LINKAGE_H
+#define LLVM_CLANG_BASIC_LINKAGE_H
+
+namespace clang {
+
+/// \brief Describes the different kinds of linkage 
+/// (C++ [basic.link], C99 6.2.2) that an entity may have.
+enum Linkage : unsigned char {
+  /// \brief No linkage, which means that the entity is unique and
+  /// can only be referred to from within its scope.
+  NoLinkage = 0,
+
+  /// \brief Internal linkage, which indicates that the entity can
+  /// be referred to from within the translation unit (but not other
+  /// translation units).
+  InternalLinkage,
+
+  /// \brief External linkage within a unique namespace. 
+  ///
+  /// From the language perspective, these entities have external
+  /// linkage. However, since they reside in an anonymous namespace,
+  /// their names are unique to this translation unit, which is
+  /// equivalent to having internal linkage from the code-generation
+  /// point of view.
+  UniqueExternalLinkage,
+
+  /// \brief No linkage according to the standard, but is visible from other
+  /// translation units because of types defined in a inline function.
+  VisibleNoLinkage,
+
+  /// \brief External linkage, which indicates that the entity can
+  /// be referred to from other translation units.
+  ExternalLinkage
+};
+
+/// \brief Describes the different kinds of language linkage
+/// (C++ [dcl.link]) that an entity may have.
+enum LanguageLinkage {
+  CLanguageLinkage,
+  CXXLanguageLinkage,
+  NoLanguageLinkage
+};
+
+/// \brief A more specific kind of linkage than enum Linkage.
+///
+/// This is relevant to CodeGen and AST file reading.
+enum GVALinkage {
+  GVA_Internal,
+  GVA_AvailableExternally,
+  GVA_DiscardableODR,
+  GVA_StrongExternal,
+  GVA_StrongODR
+};
+
+inline bool isExternallyVisible(Linkage L) {
+  return L == ExternalLinkage || L == VisibleNoLinkage;
+}
+
+inline Linkage getFormalLinkage(Linkage L) {
+  if (L == UniqueExternalLinkage)
+    return ExternalLinkage;
+  if (L == VisibleNoLinkage)
+    return NoLinkage;
+  return L;
+}
+
+inline bool isExternalFormalLinkage(Linkage L) {
+  return getFormalLinkage(L) == ExternalLinkage;
+}
+
+/// \brief Compute the minimum linkage given two linkages.
+///
+/// The linkage can be interpreted as a pair formed by the formal linkage and
+/// a boolean for external visibility. This is just what getFormalLinkage and
+/// isExternallyVisible return. We want the minimum of both components. The
+/// Linkage enum is defined in an order that makes this simple, we just need
+/// special cases for when VisibleNoLinkage would lose the visible bit and
+/// become NoLinkage.
+inline Linkage minLinkage(Linkage L1, Linkage L2) {
+  if (L2 == VisibleNoLinkage)
+    std::swap(L1, L2);
+  if (L1 == VisibleNoLinkage) {
+    if (L2 == InternalLinkage)
+      return NoLinkage;
+    if (L2 == UniqueExternalLinkage)
+      return NoLinkage;
+  }
+  return L1 < L2 ? L1 : L2;
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_LINKAGE_H
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
new file mode 100644
index 0000000..9a9eaa2
--- /dev/null
+++ b/include/clang/Basic/MacroBuilder.h
@@ -0,0 +1,48 @@
+//===--- MacroBuilder.h - CPP Macro building utility ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::MacroBuilder utility class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H
+#define LLVM_CLANG_BASIC_MACROBUILDER_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+class MacroBuilder {
+  raw_ostream &Out;
+public:
+  MacroBuilder(raw_ostream &Output) : Out(Output) {}
+
+  /// Append a \#define line for macro of the form "\#define Name Value\n".
+  void defineMacro(const Twine &Name, const Twine &Value = "1") {
+    Out << "#define " << Name << ' ' << Value << '\n';
+  }
+
+  /// Append a \#undef line for Name.  Name should be of the form XXX
+  /// and we emit "\#undef XXX".
+  void undefineMacro(const Twine &Name) {
+    Out << "#undef " << Name << '\n';
+  }
+
+  /// Directly append Str and a newline to the underlying buffer.
+  void append(const Twine &Str) {
+    Out << Str << '\n';
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
new file mode 100644
index 0000000..9b66840
--- /dev/null
+++ b/include/clang/Basic/Module.h
@@ -0,0 +1,470 @@
+//===--- Module.h - Describe a module ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::Module class, which describes a module in the
+/// source code.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_MODULE_H
+#define LLVM_CLANG_BASIC_MODULE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+  
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+class LangOptions;
+class TargetInfo;
+class IdentifierInfo;
+  
+/// \brief Describes the name of a module.
+typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
+  
+/// \brief Describes a module or submodule.
+class Module {
+public:
+  /// \brief The name of this module.
+  std::string Name;
+  
+  /// \brief The location of the module definition.
+  SourceLocation DefinitionLoc;
+
+  /// \brief The parent of this module. This will be NULL for the top-level
+  /// module.
+  Module *Parent;
+
+  /// \brief The module map file that (along with the module name) uniquely
+  /// identifies this module.
+  ///
+  /// The particular module that \c Name refers to may depend on how the module
+  /// was found in header search. However, the combination of \c Name and
+  /// \c ModuleMap will be globally unique for top-level modules. In the case of
+  /// inferred modules, \c ModuleMap will contain the module map that allowed
+  /// the inference (e.g. contained 'Module *') rather than the virtual
+  /// inferred module map file.
+  const FileEntry *ModuleMap;
+  
+  /// \brief The umbrella header or directory.
+  llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
+  
+private:
+  /// \brief The submodules of this module, indexed by name.
+  std::vector<Module *> SubModules;
+  
+  /// \brief A mapping from the submodule name to the index into the 
+  /// \c SubModules vector at which that submodule resides.
+  llvm::StringMap<unsigned> SubModuleIndex;
+
+  /// \brief The AST file if this is a top-level module which has a
+  /// corresponding serialized AST file, or null otherwise.
+  const FileEntry *ASTFile;
+
+  /// \brief The top-level headers associated with this module.
+  llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
+
+  /// \brief top-level header filenames that aren't resolved to FileEntries yet.
+  std::vector<std::string> TopHeaderNames;
+
+  /// \brief Cache of modules visible to lookup in this module.
+  mutable llvm::DenseSet<const Module*> VisibleModulesCache;
+
+public:
+  /// \brief The headers that are part of this module.
+  SmallVector<const FileEntry *, 2> NormalHeaders;
+
+  /// \brief The headers that are explicitly excluded from this module.
+  SmallVector<const FileEntry *, 2> ExcludedHeaders;
+
+  /// \brief The headers that are private to this module.
+  SmallVector<const FileEntry *, 2> PrivateHeaders;
+
+  /// \brief Information about a header directive as found in the module map
+  /// file.
+  struct HeaderDirective {
+    SourceLocation FileNameLoc;
+    std::string FileName;
+    bool IsUmbrella;
+  };
+
+  /// \brief Headers that are mentioned in the module map file but could not be
+  /// found on the file system.
+  SmallVector<HeaderDirective, 1> MissingHeaders;
+
+  /// \brief An individual requirement: a feature name and a flag indicating
+  /// the required state of that feature.
+  typedef std::pair<std::string, bool> Requirement;
+
+  /// \brief The set of language features required to use this module.
+  ///
+  /// If any of these requirements are not available, the \c IsAvailable bit
+  /// will be false to indicate that this (sub)module is not available.
+  SmallVector<Requirement, 2> Requirements;
+
+  /// \brief Whether this module is missing a feature from \c Requirements.
+  unsigned IsMissingRequirement : 1;
+
+  /// \brief Whether this module is available in the current translation unit.
+  ///
+  /// If the module is missing headers or does not meet all requirements then
+  /// this bit will be 0.
+  unsigned IsAvailable : 1;
+
+  /// \brief Whether this module was loaded from a module file.
+  unsigned IsFromModuleFile : 1;
+  
+  /// \brief Whether this is a framework module.
+  unsigned IsFramework : 1;
+  
+  /// \brief Whether this is an explicit submodule.
+  unsigned IsExplicit : 1;
+  
+  /// \brief Whether this is a "system" module (which assumes that all
+  /// headers in it are system headers).
+  unsigned IsSystem : 1;
+
+  /// \brief Whether this is an 'extern "C"' module (which implicitly puts all
+  /// headers in it within an 'extern "C"' block, and allows the module to be
+  /// imported within such a block).
+  unsigned IsExternC : 1;
+
+  /// \brief Whether this is an inferred submodule (module * { ... }).
+  unsigned IsInferred : 1;
+
+  /// \brief Whether we should infer submodules for this module based on 
+  /// the headers.
+  ///
+  /// Submodules can only be inferred for modules with an umbrella header.
+  unsigned InferSubmodules : 1;
+  
+  /// \brief Whether, when inferring submodules, the inferred submodules
+  /// should be explicit.
+  unsigned InferExplicitSubmodules : 1;
+  
+  /// \brief Whether, when inferring submodules, the inferr submodules should
+  /// export all modules they import (e.g., the equivalent of "export *").
+  unsigned InferExportWildcard : 1;
+
+  /// \brief Whether the set of configuration macros is exhaustive.
+  ///
+  /// When the set of configuration macros is exhaustive, meaning
+  /// that no identifier not in this list should affect how the module is
+  /// built.
+  unsigned ConfigMacrosExhaustive : 1;
+
+  /// \brief Describes the visibility of the various names within a
+  /// particular module.
+  enum NameVisibilityKind {
+    /// \brief All of the names in this module are hidden.
+    ///
+    Hidden,
+    /// \brief Only the macro names in this module are visible.
+    MacrosVisible,
+    /// \brief All of the names in this module are visible.
+    AllVisible
+  };
+
+  /// \brief The visibility of names within this particular module.
+  NameVisibilityKind NameVisibility;
+
+  /// \brief The location at which macros within this module became visible.
+  SourceLocation MacroVisibilityLoc;
+
+  /// \brief The location of the inferred submodule.
+  SourceLocation InferredSubmoduleLoc;
+
+  /// \brief The set of modules imported by this module, and on which this
+  /// module depends.
+  SmallVector<Module *, 2> Imports;
+  
+  /// \brief Describes an exported module.
+  ///
+  /// The pointer is the module being re-exported, while the bit will be true
+  /// to indicate that this is a wildcard export.
+  typedef llvm::PointerIntPair<Module *, 1, bool> ExportDecl;
+  
+  /// \brief The set of export declarations.
+  SmallVector<ExportDecl, 2> Exports;
+  
+  /// \brief Describes an exported module that has not yet been resolved
+  /// (perhaps because the module it refers to has not yet been loaded).
+  struct UnresolvedExportDecl {
+    /// \brief The location of the 'export' keyword in the module map file.
+    SourceLocation ExportLoc;
+    
+    /// \brief The name of the module.
+    ModuleId Id;
+    
+    /// \brief Whether this export declaration ends in a wildcard, indicating
+    /// that all of its submodules should be exported (rather than the named
+    /// module itself).
+    bool Wildcard;
+  };
+  
+  /// \brief The set of export declarations that have yet to be resolved.
+  SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
+
+  /// \brief The directly used modules.
+  SmallVector<Module *, 2> DirectUses;
+
+  /// \brief The set of use declarations that have yet to be resolved.
+  SmallVector<ModuleId, 2> UnresolvedDirectUses;
+
+  /// \brief A library or framework to link against when an entity from this
+  /// module is used.
+  struct LinkLibrary {
+    LinkLibrary() : IsFramework(false) { }
+    LinkLibrary(const std::string &Library, bool IsFramework)
+      : Library(Library), IsFramework(IsFramework) { }
+    
+    /// \brief The library to link against.
+    ///
+    /// This will typically be a library or framework name, but can also
+    /// be an absolute path to the library or framework.
+    std::string Library;
+
+    /// \brief Whether this is a framework rather than a library.
+    bool IsFramework;
+  };
+
+  /// \brief The set of libraries or frameworks to link against when
+  /// an entity from this module is used.
+  llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
+
+  /// \brief The set of "configuration macros", which are macros that
+  /// (intentionally) change how this module is built.
+  std::vector<std::string> ConfigMacros;
+
+  /// \brief An unresolved conflict with another module.
+  struct UnresolvedConflict {
+    /// \brief The (unresolved) module id.
+    ModuleId Id;
+
+    /// \brief The message provided to the user when there is a conflict.
+    std::string Message;
+  };
+
+  /// \brief The list of conflicts for which the module-id has not yet been
+  /// resolved.
+  std::vector<UnresolvedConflict> UnresolvedConflicts;
+
+  /// \brief A conflict between two modules.
+  struct Conflict {
+    /// \brief The module that this module conflicts with.
+    Module *Other;
+
+    /// \brief The message provided to the user when there is a conflict.
+    std::string Message;
+  };
+
+  /// \brief The list of conflicts.
+  std::vector<Conflict> Conflicts;
+
+  /// \brief Construct a new module or submodule.
+  ///
+  /// For an explanation of \p ModuleMap, see Module::ModuleMap.
+  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
+         const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
+  
+  ~Module();
+  
+  /// \brief Determine whether this module is available for use within the
+  /// current translation unit.
+  bool isAvailable() const { return IsAvailable; }
+
+  /// \brief Determine whether this module is available for use within the
+  /// current translation unit.
+  ///
+  /// \param LangOpts The language options used for the current
+  /// translation unit.
+  ///
+  /// \param Target The target options used for the current translation unit.
+  ///
+  /// \param Req If this module is unavailable, this parameter
+  /// will be set to one of the requirements that is not met for use of
+  /// this module.
+  bool isAvailable(const LangOptions &LangOpts, 
+                   const TargetInfo &Target,
+                   Requirement &Req,
+                   HeaderDirective &MissingHeader) const;
+
+  /// \brief Determine whether this module is a submodule.
+  bool isSubModule() const { return Parent != nullptr; }
+  
+  /// \brief Determine whether this module is a submodule of the given other
+  /// module.
+  bool isSubModuleOf(const Module *Other) const;
+  
+  /// \brief Determine whether this module is a part of a framework,
+  /// either because it is a framework module or because it is a submodule
+  /// of a framework module.
+  bool isPartOfFramework() const {
+    for (const Module *Mod = this; Mod; Mod = Mod->Parent) 
+      if (Mod->IsFramework)
+        return true;
+    
+    return false;
+  }
+
+  /// \brief Determine whether this module is a subframework of another
+  /// framework.
+  bool isSubFramework() const {
+    return IsFramework && Parent && Parent->isPartOfFramework();
+  }
+
+  /// \brief Retrieve the full name of this module, including the path from
+  /// its top-level module.
+  std::string getFullModuleName() const;
+
+  /// \brief Retrieve the top-level module for this (sub)module, which may
+  /// be this module.
+  Module *getTopLevelModule() {
+    return const_cast<Module *>(
+             const_cast<const Module *>(this)->getTopLevelModule());
+  }
+
+  /// \brief Retrieve the top-level module for this (sub)module, which may
+  /// be this module.
+  const Module *getTopLevelModule() const;
+  
+  /// \brief Retrieve the name of the top-level module.
+  ///
+  StringRef getTopLevelModuleName() const {
+    return getTopLevelModule()->Name;
+  }
+
+  /// \brief The serialized AST file for this module, if one was created.
+  const FileEntry *getASTFile() const {
+    return getTopLevelModule()->ASTFile;
+  }
+
+  /// \brief Set the serialized AST file for the top-level module of this module.
+  void setASTFile(const FileEntry *File) {
+    assert((File == nullptr || getASTFile() == nullptr ||
+            getASTFile() == File) && "file path changed");
+    getTopLevelModule()->ASTFile = File;
+  }
+
+  /// \brief Retrieve the directory for which this module serves as the
+  /// umbrella.
+  const DirectoryEntry *getUmbrellaDir() const;
+
+  /// \brief Retrieve the header that serves as the umbrella header for this
+  /// module.
+  const FileEntry *getUmbrellaHeader() const {
+    return Umbrella.dyn_cast<const FileEntry *>();
+  }
+
+  /// \brief Determine whether this module has an umbrella directory that is
+  /// not based on an umbrella header.
+  bool hasUmbrellaDir() const {
+    return Umbrella && Umbrella.is<const DirectoryEntry *>();
+  }
+
+  /// \brief Add a top-level header associated with this module.
+  void addTopHeader(const FileEntry *File) {
+    assert(File);
+    TopHeaders.insert(File);
+  }
+
+  /// \brief Add a top-level header filename associated with this module.
+  void addTopHeaderFilename(StringRef Filename) {
+    TopHeaderNames.push_back(Filename);
+  }
+
+  /// \brief The top-level headers associated with this module.
+  ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
+
+  /// \brief Add the given feature requirement to the list of features
+  /// required by this module.
+  ///
+  /// \param Feature The feature that is required by this module (and
+  /// its submodules).
+  ///
+  /// \param RequiredState The required state of this feature: \c true
+  /// if it must be present, \c false if it must be absent.
+  ///
+  /// \param LangOpts The set of language options that will be used to
+  /// evaluate the availability of this feature.
+  ///
+  /// \param Target The target options that will be used to evaluate the
+  /// availability of this feature.
+  void addRequirement(StringRef Feature, bool RequiredState,
+                      const LangOptions &LangOpts,
+                      const TargetInfo &Target);
+
+  /// \brief Mark this module and all of its submodules as unavailable.
+  void markUnavailable(bool MissingRequirement = false);
+
+  /// \brief Find the submodule with the given name.
+  ///
+  /// \returns The submodule if found, or NULL otherwise.
+  Module *findSubmodule(StringRef Name) const;
+
+  /// \brief Determine whether the specified module would be visible to
+  /// a lookup at the end of this module.
+  ///
+  /// FIXME: This may return incorrect results for (submodules of) the
+  /// module currently being built, if it's queried before we see all
+  /// of its imports.
+  bool isModuleVisible(const Module *M) const {
+    if (VisibleModulesCache.empty())
+      buildVisibleModulesCache();
+    return VisibleModulesCache.count(M);
+  }
+
+  typedef std::vector<Module *>::iterator submodule_iterator;
+  typedef std::vector<Module *>::const_iterator submodule_const_iterator;
+  
+  submodule_iterator submodule_begin() { return SubModules.begin(); }
+  submodule_const_iterator submodule_begin() const {return SubModules.begin();}
+  submodule_iterator submodule_end()   { return SubModules.end(); }
+  submodule_const_iterator submodule_end() const { return SubModules.end(); }
+
+  /// \brief Appends this module's list of exported modules to \p Exported.
+  ///
+  /// This provides a subset of immediately imported modules (the ones that are
+  /// directly exported), not the complete set of exported modules.
+  void getExportedModules(SmallVectorImpl<Module *> &Exported) const;
+
+  static StringRef getModuleInputBufferName() {
+    return "<module-includes>";
+  }
+
+  /// \brief Print the module map for this module to the given stream. 
+  ///
+  void print(raw_ostream &OS, unsigned Indent = 0) const;
+  
+  /// \brief Dump the contents of this module to the given output stream.
+  void dump() const;
+
+private:
+  void buildVisibleModulesCache() const;
+};
+
+} // end namespace clang
+
+
+#endif // LLVM_CLANG_BASIC_MODULE_H
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
new file mode 100644
index 0000000..fa375f4
--- /dev/null
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -0,0 +1,315 @@
+//===--- ObjCRuntime.h - Objective-C Runtime Configuration ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines types useful for describing an Objective-C runtime.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_OBJCRUNTIME_H
+#define LLVM_CLANG_OBJCRUNTIME_H
+
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+/// \brief The basic abstraction for the target Objective-C runtime.
+class ObjCRuntime {
+public:
+  /// \brief The basic Objective-C runtimes that we know about.
+  enum Kind {
+    /// 'macosx' is the Apple-provided NeXT-derived runtime on Mac OS
+    /// X platforms that use the non-fragile ABI; the version is a
+    /// release of that OS.
+    MacOSX,
+
+    /// 'macosx-fragile' is the Apple-provided NeXT-derived runtime on
+    /// Mac OS X platforms that use the fragile ABI; the version is a
+    /// release of that OS.
+    FragileMacOSX,
+
+    /// 'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS
+    /// simulator;  it is always non-fragile.  The version is a release
+    /// version of iOS.
+    iOS,
+
+    /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a
+    /// fragile Objective-C ABI
+    GCC,
+
+    /// 'gnustep' is the modern non-fragile GNUstep runtime.
+    GNUstep,
+
+    /// 'objfw' is the Objective-C runtime included in ObjFW
+    ObjFW
+  };
+
+private:
+  Kind TheKind;
+  VersionTuple Version;
+
+public:
+  /// A bogus initialization of the runtime.
+  ObjCRuntime() : TheKind(MacOSX) {}
+
+  ObjCRuntime(Kind kind, const VersionTuple &version)
+    : TheKind(kind), Version(version) {}
+
+  void set(Kind kind, VersionTuple version) {
+    TheKind = kind;
+    Version = version;
+  }
+
+  Kind getKind() const { return TheKind; }
+  const VersionTuple &getVersion() const { return Version; }
+
+  /// \brief Does this runtime follow the set of implied behaviors for a
+  /// "non-fragile" ABI?
+  bool isNonFragile() const {
+    switch (getKind()) {
+    case FragileMacOSX: return false;
+    case GCC: return false;
+    case MacOSX: return true;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    case iOS: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// The inverse of isNonFragile():  does this runtime follow the set of
+  /// implied behaviors for a "fragile" ABI?
+  bool isFragile() const { return !isNonFragile(); }
+
+  /// The default dispatch mechanism to use for the specified architecture
+  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
+    // The GNUstep runtime uses a newer dispatch method by default from
+    // version 1.6 onwards
+    if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
+      if (Arch == llvm::Triple::arm ||
+          Arch == llvm::Triple::x86 ||
+          Arch == llvm::Triple::x86_64)
+        return false;
+    }
+    else if ((getKind() ==  MacOSX) && isNonFragile() &&
+             (getVersion() >= VersionTuple(10, 0)) &&
+             (getVersion() < VersionTuple(10, 6)))
+        return Arch != llvm::Triple::x86_64;
+    // Except for deployment target of 10.5 or less,
+    // Mac runtimes use legacy dispatch everywhere now.
+    return true;
+  }
+
+  /// \brief Is this runtime basically of the GNU family of runtimes?
+  bool isGNUFamily() const {
+    switch (getKind()) {
+    case FragileMacOSX:
+    case MacOSX:
+    case iOS:
+      return false;
+    case GCC:
+    case GNUstep:
+    case ObjFW:
+      return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Is this runtime basically of the NeXT family of runtimes?
+  bool isNeXTFamily() const {
+    // For now, this is just the inverse of isGNUFamily(), but that's
+    // not inherently true.
+    return !isGNUFamily();
+  }
+
+  /// \brief Does this runtime allow ARC at all?
+  bool allowsARC() const {
+    switch (getKind()) {
+    case FragileMacOSX: return false;
+    case MacOSX: return true;
+    case iOS: return true;
+    case GCC: return false;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Does this runtime natively provide the ARC entrypoints? 
+  ///
+  /// ARC cannot be directly supported on a platform that does not provide
+  /// these entrypoints, although it may be supportable via a stub
+  /// library.
+  bool hasNativeARC() const {
+    switch (getKind()) {
+    case FragileMacOSX: return false;
+    case MacOSX: return getVersion() >= VersionTuple(10, 7);
+    case iOS: return getVersion() >= VersionTuple(5);
+
+    case GCC: return false;
+    case GNUstep: return getVersion() >= VersionTuple(1, 6);
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Does this runtime supports optimized setter entrypoints?
+  bool hasOptimizedSetter() const {
+    switch (getKind()) {
+      case MacOSX:
+        return getVersion() >= VersionTuple(10, 8);
+      case iOS:
+        return (getVersion() >= VersionTuple(6));
+      case GNUstep:
+        return getVersion() >= VersionTuple(1, 7);
+    
+      default:
+      return false;
+    }
+  }
+
+  /// Does this runtime allow the use of __weak?
+  bool allowsWeak() const {
+    return hasNativeWeak();
+  }
+
+  /// \brief Does this runtime natively provide ARC-compliant 'weak'
+  /// entrypoints?
+  bool hasNativeWeak() const {
+    // Right now, this is always equivalent to whether the runtime
+    // natively supports ARC decision.
+    return hasNativeARC();
+  }
+
+  /// \brief Does this runtime directly support the subscripting methods?
+  ///
+  /// This is really a property of the library, not the runtime.
+  bool hasSubscripting() const {
+    switch (getKind()) {
+    case FragileMacOSX: return false;
+    case MacOSX: return getVersion() >= VersionTuple(10, 8);
+    case iOS: return getVersion() >= VersionTuple(6);
+
+    // This is really a lie, because some implementations and versions
+    // of the runtime do not support ARC.  Probably -fgnu-runtime
+    // should imply a "maximal" runtime or something?
+    case GCC: return true;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Does this runtime allow sizeof or alignof on object types?
+  bool allowsSizeofAlignof() const {
+    return isFragile();
+  }
+
+  /// \brief Does this runtime allow pointer arithmetic on objects?
+  ///
+  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
+  /// yields true) [].
+  bool allowsPointerArithmetic() const {
+    switch (getKind()) {
+    case FragileMacOSX:
+    case GCC:
+      return true;
+    case MacOSX:
+    case iOS:
+    case GNUstep:
+    case ObjFW:
+      return false;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Is subscripting pointer arithmetic?
+  bool isSubscriptPointerArithmetic() const {
+    return allowsPointerArithmetic();
+  }
+
+  /// \brief Does this runtime provide an objc_terminate function?
+  ///
+  /// This is used in handlers for exceptions during the unwind process;
+  /// without it, abort() must be used in pure ObjC files.
+  bool hasTerminate() const {
+    switch (getKind()) {
+    case FragileMacOSX: return getVersion() >= VersionTuple(10, 8);
+    case MacOSX: return getVersion() >= VersionTuple(10, 8);
+    case iOS: return getVersion() >= VersionTuple(5);
+    case GCC: return false;
+    case GNUstep: return false;
+    case ObjFW: return false;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Does this runtime support weakly importing classes?
+  bool hasWeakClassImport() const {
+    switch (getKind()) {
+    case MacOSX: return true;
+    case iOS: return true;
+    case FragileMacOSX: return false;
+    case GCC: return true;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Does this runtime use zero-cost exceptions?
+  bool hasUnwindExceptions() const {
+    switch (getKind()) {
+    case MacOSX: return true;
+    case iOS: return true;
+    case FragileMacOSX: return false;
+    case GCC: return true;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  bool hasAtomicCopyHelper() const {
+    switch (getKind()) {
+    case FragileMacOSX:
+    case MacOSX:
+    case iOS:
+      return true;
+    case GNUstep:
+      return getVersion() >= VersionTuple(1, 7);
+    default: return false;
+    }
+  }
+
+  /// \brief Try to parse an Objective-C runtime specification from the given
+  /// string.
+  ///
+  /// \return true on error.
+  bool tryParse(StringRef input);
+
+  std::string getAsString() const;
+
+  friend bool operator==(const ObjCRuntime &left, const ObjCRuntime &right) {
+    return left.getKind() == right.getKind() &&
+           left.getVersion() == right.getVersion();
+  }
+
+  friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) {
+    return !(left == right);
+  }
+};
+
+raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
new file mode 100644
index 0000000..103fa83
--- /dev/null
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -0,0 +1,32 @@
+//===--- OpenCLExtensions.def - OpenCL extension list -----------*- 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 list of supported OpenCL extensions.
+//
+//===----------------------------------------------------------------------===//
+
+// OpenCL 1.1.
+OPENCLEXT(cl_khr_fp64)
+OPENCLEXT(cl_khr_int64_base_atomics)
+OPENCLEXT(cl_khr_int64_extended_atomics)
+OPENCLEXT(cl_khr_fp16)
+OPENCLEXT(cl_khr_gl_sharing)
+OPENCLEXT(cl_khr_gl_event)
+OPENCLEXT(cl_khr_d3d10_sharing)
+OPENCLEXT(cl_khr_global_int32_base_atomics)
+OPENCLEXT(cl_khr_global_int32_extended_atomics)
+OPENCLEXT(cl_khr_local_int32_base_atomics)
+OPENCLEXT(cl_khr_local_int32_extended_atomics)
+OPENCLEXT(cl_khr_byte_addressable_store)
+OPENCLEXT(cl_khr_3d_image_writes)
+
+// Clang Extensions.
+OPENCLEXT(cl_clang_storage_class_specifiers)
+
+#undef OPENCLEXT
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
new file mode 100644
index 0000000..6cfa5ea
--- /dev/null
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -0,0 +1,210 @@
+//===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines the list of supported OpenMP directives and
+/// clauses.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_DIRECTIVE
+#  define OPENMP_DIRECTIVE(Name)
+#endif
+#ifndef OPENMP_DIRECTIVE_EXT
+#define OPENMP_DIRECTIVE_EXT(Name, Str)
+#endif
+#ifndef OPENMP_CLAUSE
+#  define OPENMP_CLAUSE(Name, Class)
+#endif
+#ifndef OPENMP_PARALLEL_CLAUSE
+#  define OPENMP_PARALLEL_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SIMD_CLAUSE
+#  define OPENMP_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_FOR_CLAUSE
+#  define OPENMP_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SECTIONS_CLAUSE
+#  define OPENMP_SECTIONS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SINGLE_CLAUSE
+#  define OPENMP_SINGLE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_FOR_CLAUSE
+#  define OPENMP_PARALLEL_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#  define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TASK_CLAUSE
+#  define OPENMP_TASK_CLAUSE(Name)
+#endif
+#ifndef OPENMP_DEFAULT_KIND
+#  define OPENMP_DEFAULT_KIND(Name)
+#endif
+#ifndef OPENMP_PROC_BIND_KIND
+#  define OPENMP_PROC_BIND_KIND(Name)
+#endif
+#ifndef OPENMP_SCHEDULE_KIND
+#define OPENMP_SCHEDULE_KIND(Name)
+#endif
+
+// OpenMP directives.
+OPENMP_DIRECTIVE(threadprivate)
+OPENMP_DIRECTIVE(parallel)
+OPENMP_DIRECTIVE(task)
+OPENMP_DIRECTIVE(simd)
+OPENMP_DIRECTIVE(for)
+OPENMP_DIRECTIVE(sections)
+OPENMP_DIRECTIVE(section)
+OPENMP_DIRECTIVE(single)
+OPENMP_DIRECTIVE(master)
+OPENMP_DIRECTIVE(critical)
+OPENMP_DIRECTIVE(taskyield)
+OPENMP_DIRECTIVE(barrier)
+OPENMP_DIRECTIVE(taskwait)
+OPENMP_DIRECTIVE(flush)
+OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
+OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
+
+// OpenMP clauses.
+OPENMP_CLAUSE(if, OMPIfClause)
+OPENMP_CLAUSE(final, OMPFinalClause)
+OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
+OPENMP_CLAUSE(safelen, OMPSafelenClause)
+OPENMP_CLAUSE(collapse, OMPCollapseClause)
+OPENMP_CLAUSE(default, OMPDefaultClause)
+OPENMP_CLAUSE(private, OMPPrivateClause)
+OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
+OPENMP_CLAUSE(lastprivate, OMPLastprivateClause)
+OPENMP_CLAUSE(shared,  OMPSharedClause)
+OPENMP_CLAUSE(reduction,  OMPReductionClause)
+OPENMP_CLAUSE(linear,  OMPLinearClause)
+OPENMP_CLAUSE(aligned, OMPAlignedClause)
+OPENMP_CLAUSE(copyin,  OMPCopyinClause)
+OPENMP_CLAUSE(copyprivate,  OMPCopyprivateClause)
+OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
+OPENMP_CLAUSE(schedule, OMPScheduleClause)
+OPENMP_CLAUSE(ordered, OMPOrderedClause)
+OPENMP_CLAUSE(nowait, OMPNowaitClause)
+OPENMP_CLAUSE(untied, OMPUntiedClause)
+OPENMP_CLAUSE(mergeable, OMPMergeableClause)
+OPENMP_CLAUSE(flush, OMPFlushClause)
+
+// Clauses allowed for OpenMP directive 'parallel'.
+OPENMP_PARALLEL_CLAUSE(if)
+OPENMP_PARALLEL_CLAUSE(num_threads)
+OPENMP_PARALLEL_CLAUSE(default)
+OPENMP_PARALLEL_CLAUSE(proc_bind)
+OPENMP_PARALLEL_CLAUSE(private)
+OPENMP_PARALLEL_CLAUSE(firstprivate)
+OPENMP_PARALLEL_CLAUSE(shared)
+OPENMP_PARALLEL_CLAUSE(reduction)
+OPENMP_PARALLEL_CLAUSE(copyin)
+
+// Clauses allowed for directive 'omp simd'.
+OPENMP_SIMD_CLAUSE(private)
+OPENMP_SIMD_CLAUSE(lastprivate)
+OPENMP_SIMD_CLAUSE(linear)
+OPENMP_SIMD_CLAUSE(aligned)
+OPENMP_SIMD_CLAUSE(safelen)
+OPENMP_SIMD_CLAUSE(collapse)
+OPENMP_SIMD_CLAUSE(reduction)
+
+// Clauses allowed for directive 'omp for'.
+OPENMP_FOR_CLAUSE(private)
+OPENMP_FOR_CLAUSE(lastprivate)
+OPENMP_FOR_CLAUSE(firstprivate)
+OPENMP_FOR_CLAUSE(reduction)
+OPENMP_FOR_CLAUSE(collapse)
+OPENMP_FOR_CLAUSE(schedule)
+OPENMP_FOR_CLAUSE(ordered)
+OPENMP_FOR_CLAUSE(nowait)
+
+// Clauses allowed for OpenMP directive 'omp sections'.
+OPENMP_SECTIONS_CLAUSE(private)
+OPENMP_SECTIONS_CLAUSE(lastprivate)
+OPENMP_SECTIONS_CLAUSE(firstprivate)
+OPENMP_SECTIONS_CLAUSE(reduction)
+OPENMP_SECTIONS_CLAUSE(nowait)
+
+// Clauses allowed for directive 'omp single'.
+OPENMP_SINGLE_CLAUSE(private)
+OPENMP_SINGLE_CLAUSE(firstprivate)
+OPENMP_SINGLE_CLAUSE(copyprivate)
+OPENMP_SINGLE_CLAUSE(nowait)
+
+// Static attributes for 'default' clause.
+OPENMP_DEFAULT_KIND(none)
+OPENMP_DEFAULT_KIND(shared)
+
+// Static attributes for 'proc_bind' clause.
+OPENMP_PROC_BIND_KIND(master)
+OPENMP_PROC_BIND_KIND(close)
+OPENMP_PROC_BIND_KIND(spread)
+
+// Static attributes for 'schedule' clause.
+OPENMP_SCHEDULE_KIND(static)
+OPENMP_SCHEDULE_KIND(dynamic)
+OPENMP_SCHEDULE_KIND(guided)
+OPENMP_SCHEDULE_KIND(auto)
+OPENMP_SCHEDULE_KIND(runtime)
+
+// Clauses allowed for OpenMP directive 'parallel for'.
+OPENMP_PARALLEL_FOR_CLAUSE(if)
+OPENMP_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_PARALLEL_FOR_CLAUSE(default)
+OPENMP_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_PARALLEL_FOR_CLAUSE(private)
+OPENMP_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_PARALLEL_FOR_CLAUSE(copyin)
+OPENMP_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_PARALLEL_FOR_CLAUSE(ordered)
+
+// Clauses allowed for OpenMP directive 'parallel sections'.
+OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(default)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(private)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(shared)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
+
+// Clauses allowed for OpenMP directive 'task'.
+OPENMP_TASK_CLAUSE(if)
+OPENMP_TASK_CLAUSE(final)
+OPENMP_TASK_CLAUSE(default)
+OPENMP_TASK_CLAUSE(private)
+OPENMP_TASK_CLAUSE(firstprivate)
+OPENMP_TASK_CLAUSE(shared)
+OPENMP_TASK_CLAUSE(untied)
+OPENMP_TASK_CLAUSE(mergeable)
+
+#undef OPENMP_SCHEDULE_KIND
+#undef OPENMP_PROC_BIND_KIND
+#undef OPENMP_DEFAULT_KIND
+#undef OPENMP_DIRECTIVE
+#undef OPENMP_DIRECTIVE_EXT
+#undef OPENMP_CLAUSE
+#undef OPENMP_SINGLE_CLAUSE
+#undef OPENMP_SECTIONS_CLAUSE
+#undef OPENMP_PARALLEL_CLAUSE
+#undef OPENMP_PARALLEL_FOR_CLAUSE
+#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#undef OPENMP_TASK_CLAUSE
+#undef OPENMP_SIMD_CLAUSE
+#undef OPENMP_FOR_CLAUSE
+
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
new file mode 100644
index 0000000..526cbb2
--- /dev/null
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -0,0 +1,117 @@
+//===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines some OpenMP-specific enums and functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
+#define LLVM_CLANG_BASIC_OPENMPKINDS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+/// \brief OpenMP directives.
+enum OpenMPDirectiveKind {
+#define OPENMP_DIRECTIVE(Name) \
+  OMPD_##Name,
+#define OPENMP_DIRECTIVE_EXT(Name, Str) \
+  OMPD_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPD_unknown
+};
+
+/// \brief OpenMP clauses.
+enum OpenMPClauseKind {
+#define OPENMP_CLAUSE(Name, Class) \
+  OMPC_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_threadprivate,
+  OMPC_unknown
+};
+
+/// \brief OpenMP attributes for 'default' clause.
+enum OpenMPDefaultClauseKind {
+#define OPENMP_DEFAULT_KIND(Name) \
+  OMPC_DEFAULT_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_DEFAULT_unknown
+};
+
+/// \brief OpenMP attributes for 'proc_bind' clause.
+enum OpenMPProcBindClauseKind {
+#define OPENMP_PROC_BIND_KIND(Name) \
+  OMPC_PROC_BIND_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_PROC_BIND_unknown
+};
+
+/// \brief OpenMP attributes for 'schedule' clause.
+enum OpenMPScheduleClauseKind {
+#define OPENMP_SCHEDULE_KIND(Name) \
+  OMPC_SCHEDULE_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_SCHEDULE_unknown
+};
+
+OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
+const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind);
+
+OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str);
+const char *getOpenMPClauseName(OpenMPClauseKind Kind);
+
+unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str);
+const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
+
+bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
+                                 OpenMPClauseKind CKind);
+
+/// \brief Checks if the specified directive is a directive with an associated
+/// loop construct.
+/// \param DKind Specified directive.
+/// \return true - the directive is a loop-associated directive like 'omp simd'
+/// or 'omp for' directive, otherwise - false.
+bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a worksharing directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a worksharing directive like 'omp for',
+/// otherwise - false.
+bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a parallel-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a parallel-like directive like 'omp
+/// parallel', otherwise - false.
+bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a simd directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a simd directive like 'omp simd',
+/// otherwise - false.
+bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified clause is one of private clauses like
+/// 'private', 'firstprivate', 'reduction' etc..
+/// \param Kind Clause kind.
+/// \return true - the clause is a private clause, otherwise - false.
+bool isOpenMPPrivate(OpenMPClauseKind Kind);
+
+/// \brief Checks if the specified clause is one of threadprivate clauses like
+/// 'threadprivate', 'copyin' or 'copyprivate'.
+/// \param Kind Clause kind.
+/// \return true - the clause is a threadprivate clause, otherwise - false.
+bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
+
+}
+
+#endif
+
diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def
new file mode 100644
index 0000000..d011e9d
--- /dev/null
+++ b/include/clang/Basic/OperatorKinds.def
@@ -0,0 +1,106 @@
+//===--- OperatorKinds.def - C++ Overloaded Operator Database ---*- 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 OverloadedOperator database, which includes
+// all of the overloadable C++ operators.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file OperatorKinds.def
+///
+/// In this file, each of the overloadable C++ operators is enumerated
+/// with either the OVERLOADED_OPERATOR or OVERLOADED_OPERATOR_MULTI
+/// macro, each of which can be specified by the code including this
+/// file. OVERLOADED_OPERATOR is used for single-token operators
+/// (e.g., "+"), and has six arguments:
+///
+/// Name: The name of the token. OO_Name will be the name of the
+/// corresponding enumerator in OverloadedOperatorKind in
+/// OperatorKinds.h.
+///
+/// Spelling: A string that provides a canonical spelling for the
+/// operator, e.g., "operator+".
+///
+/// Token: The name of the token that specifies the operator, e.g.,
+/// "plus" for operator+ or "greatergreaterequal" for
+/// "operator>>=". With a "kw_" prefix, the token name can be used as
+/// an enumerator into the TokenKind enumeration.
+///
+/// Unary: True if the operator can be declared as a unary operator.
+///
+/// Binary: True if the operator can be declared as a binary
+/// operator. Note that some operators (e.g., "operator+" and
+/// "operator*") can be both unary and binary.
+///
+/// MemberOnly: True if this operator can only be declared as a
+/// non-static member function. False if the operator can be both a
+/// non-member function and a non-static member function.
+///
+/// OVERLOADED_OPERATOR_MULTI is used to enumerate the multi-token
+/// overloaded operator names, e.g., "operator delete []". The macro
+/// has all of the parameters of OVERLOADED_OPERATOR except Token,
+/// which is omitted.
+
+#ifndef OVERLOADED_OPERATOR
+#  define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)
+#endif
+
+#ifndef OVERLOADED_OPERATOR_MULTI
+#  define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) \
+    OVERLOADED_OPERATOR(Name,Spelling,unknown,Unary,Binary,MemberOnly)
+#endif
+
+OVERLOADED_OPERATOR_MULTI(New            , "new"                      , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Delete         , "delete"                   , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_New      , "new[]"                    , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_Delete   , "delete[]"                 , true , true , false)
+OVERLOADED_OPERATOR(Plus                 , "+"   , plus               , true , true , false)
+OVERLOADED_OPERATOR(Minus                , "-"   , minus              , true , true , false)
+OVERLOADED_OPERATOR(Star                 , "*"   , star               , true , true , false)
+OVERLOADED_OPERATOR(Slash                , "/"   , slash              , false, true , false)
+OVERLOADED_OPERATOR(Percent              , "%"   , percent            , false, true , false)
+OVERLOADED_OPERATOR(Caret                , "^"   , caret              , false, true , false)
+OVERLOADED_OPERATOR(Amp                  , "&"   , amp                , true , true , false)
+OVERLOADED_OPERATOR(Pipe                 , "|"   , pipe               , false, true , false)
+OVERLOADED_OPERATOR(Tilde                , "~"   , tilde              , true , false, false)
+OVERLOADED_OPERATOR(Exclaim              , "!"   , exclaim            , true , false, false)
+OVERLOADED_OPERATOR(Equal                , "="   , equal              , false, true , true)
+OVERLOADED_OPERATOR(Less                 , "<"   , less               , false, true , false)
+OVERLOADED_OPERATOR(Greater              , ">"   , greater            , false, true , false)
+OVERLOADED_OPERATOR(PlusEqual            , "+="  , plusequal          , false, true , false)
+OVERLOADED_OPERATOR(MinusEqual           , "-="  , minusequal         , false, true , false)
+OVERLOADED_OPERATOR(StarEqual            , "*="  , starequal          , false, true , false)
+OVERLOADED_OPERATOR(SlashEqual           , "/="  , slashequal         , false, true , false)
+OVERLOADED_OPERATOR(PercentEqual         , "%="  , percentequal       , false, true , false)
+OVERLOADED_OPERATOR(CaretEqual           , "^="  , caretequal         , false, true , false)
+OVERLOADED_OPERATOR(AmpEqual             , "&="  , ampequal           , false, true , false)
+OVERLOADED_OPERATOR(PipeEqual            , "|="  , pipeequal          , false, true , false)
+OVERLOADED_OPERATOR(LessLess             , "<<"  , lessless           , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreater       , ">>"  , greatergreater     , false, true , false)
+OVERLOADED_OPERATOR(LessLessEqual        , "<<=" , lesslessequal      , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreaterEqual  , ">>=" , greatergreaterequal, false, true , false)
+OVERLOADED_OPERATOR(EqualEqual           , "=="  , equalequal         , false, true , false)
+OVERLOADED_OPERATOR(ExclaimEqual         , "!="  , exclaimequal       , false, true , false)
+OVERLOADED_OPERATOR(LessEqual            , "<="  , lessequal          , false, true , false)
+OVERLOADED_OPERATOR(GreaterEqual         , ">="  , greaterequal       , false, true , false)
+OVERLOADED_OPERATOR(AmpAmp               , "&&"  , ampamp             , false, true , false)
+OVERLOADED_OPERATOR(PipePipe             , "||"  , pipepipe           , false, true , false)
+OVERLOADED_OPERATOR(PlusPlus             , "++"  , plusplus           , true , true , false)
+OVERLOADED_OPERATOR(MinusMinus           , "--"  , minusminus         , true , true , false)
+OVERLOADED_OPERATOR(Comma                , ","   , comma              , false, true , false)
+OVERLOADED_OPERATOR(ArrowStar            , "->*" , arrowstar          , false, true , false)
+OVERLOADED_OPERATOR(Arrow                , "->"  , arrow              , true , false, true)
+OVERLOADED_OPERATOR_MULTI(Call           , "()"                       , true , true , true)
+OVERLOADED_OPERATOR_MULTI(Subscript      , "[]"                       , false, true , true)
+// ?: can *not* be overloaded, but we need the overload
+// resolution machinery for it.
+OVERLOADED_OPERATOR_MULTI(Conditional    , "?"                        , false, true , false)
+
+#undef OVERLOADED_OPERATOR_MULTI
+#undef OVERLOADED_OPERATOR
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
new file mode 100644
index 0000000..d3b70c2
--- /dev/null
+++ b/include/clang/Basic/OperatorKinds.h
@@ -0,0 +1,36 @@
+//===--- OperatorKinds.h - C++ Overloaded Operators -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines an enumeration for C++ overloaded operators.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+#define LLVM_CLANG_BASIC_OPERATOR_KINDS_H
+
+namespace clang {
+
+/// \brief Enumeration specifying the different kinds of C++ overloaded
+/// operators.
+enum OverloadedOperatorKind : int {
+  OO_None,                ///< Not an overloaded operator
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+  OO_##Name,
+#include "clang/Basic/OperatorKinds.def"
+  NUM_OVERLOADED_OPERATORS
+};
+
+/// \brief Retrieve the spelling of the given overloaded operator, without 
+/// the preceding "operator" keyword.
+const char *getOperatorSpelling(OverloadedOperatorKind Operator);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
new file mode 100644
index 0000000..b68d577
--- /dev/null
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -0,0 +1,52 @@
+//===--- OperatorPrecedence.h - Operator precedence levels ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines and computes precedence levels for binary/ternary operators.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_OPERATOR_PRECEDENCE_H
+#define LLVM_CLANG_OPERATOR_PRECEDENCE_H
+
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+
+/// PrecedenceLevels - These are precedences for the binary/ternary
+/// operators in the C99 grammar.  These have been named to relate
+/// with the C99 grammar productions.  Low precedences numbers bind
+/// more weakly than high numbers.
+namespace prec {
+  enum Level {
+    Unknown         = 0,    // Not binary operator.
+    Comma           = 1,    // ,
+    Assignment      = 2,    // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
+    Conditional     = 3,    // ?
+    LogicalOr       = 4,    // ||
+    LogicalAnd      = 5,    // &&
+    InclusiveOr     = 6,    // |
+    ExclusiveOr     = 7,    // ^
+    And             = 8,    // &
+    Equality        = 9,    // ==, !=
+    Relational      = 10,   //  >=, <=, >, <
+    Shift           = 11,   // <<, >>
+    Additive        = 12,   // -, +
+    Multiplicative  = 13,   // *, /, %
+    PointerToMember = 14    // .*, ->*
+  };
+}
+
+/// \brief Return the precedence of the specified binary operator token.
+prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
+                               bool CPlusPlus11);
+
+}  // end namespace clang
+
+#endif  // LLVM_CLANG_OPERATOR_PRECEDENCE_H
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
new file mode 100644
index 0000000..8ae3b22
--- /dev/null
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -0,0 +1,410 @@
+//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Implements a partial diagnostic that can be emitted anwyhere
+/// in a DiagnosticBuilder stream.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
+#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace clang {
+
+class PartialDiagnostic {
+public:
+  enum {
+      // The MaxArguments and MaxFixItHints member enum values from
+      // DiagnosticsEngine are private but DiagnosticsEngine declares
+      // PartialDiagnostic a friend.  These enum values are redeclared
+      // here so that the nested Storage class below can access them.
+      MaxArguments = DiagnosticsEngine::MaxArguments
+  };
+
+  struct Storage {
+    Storage() : NumDiagArgs(0) { }
+
+    enum {
+        /// \brief The maximum number of arguments we can hold. We
+        /// currently only support up to 10 arguments (%0-%9).
+        ///
+        /// A single diagnostic with more than that almost certainly has to
+        /// be simplified anyway.
+        MaxArguments = PartialDiagnostic::MaxArguments
+    };
+
+    /// \brief The number of entries in Arguments.
+    unsigned char NumDiagArgs;
+
+    /// \brief Specifies for each argument whether it is in DiagArgumentsStr
+    /// or in DiagArguments.
+    unsigned char DiagArgumentsKind[MaxArguments];
+
+    /// \brief The values for the various substitution positions.
+    ///
+    /// This is used when the argument is not an std::string. The specific value
+    /// is mangled into an intptr_t and the interpretation depends on exactly
+    /// what sort of argument kind it is.
+    intptr_t DiagArgumentsVal[MaxArguments];
+
+    /// \brief The values for the various substitution positions that have
+    /// string arguments.
+    std::string DiagArgumentsStr[MaxArguments];
+
+    /// \brief The list of ranges added to this diagnostic.
+    SmallVector<CharSourceRange, 8> DiagRanges;
+
+    /// \brief If valid, provides a hint with some code to insert, remove, or
+    /// modify at a particular position.
+    SmallVector<FixItHint, 6>  FixItHints;
+  };
+
+  /// \brief An allocator for Storage objects, which uses a small cache to
+  /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
+  class StorageAllocator {
+    static const unsigned NumCached = 16;
+    Storage Cached[NumCached];
+    Storage *FreeList[NumCached];
+    unsigned NumFreeListEntries;
+
+  public:
+    StorageAllocator();
+    ~StorageAllocator();
+
+    /// \brief Allocate new storage.
+    Storage *Allocate() {
+      if (NumFreeListEntries == 0)
+        return new Storage;
+
+      Storage *Result = FreeList[--NumFreeListEntries];
+      Result->NumDiagArgs = 0;
+      Result->DiagRanges.clear();
+      Result->FixItHints.clear();
+      return Result;
+    }
+
+    /// \brief Free the given storage object.
+    void Deallocate(Storage *S) {
+      if (S >= Cached && S <= Cached + NumCached) {
+        FreeList[NumFreeListEntries++] = S;
+        return;
+      }
+
+      delete S;
+    }
+  };
+
+private:
+  // NOTE: Sema assumes that PartialDiagnostic is location-invariant
+  // in the sense that its bits can be safely memcpy'ed and destructed
+  // in the new location.
+
+  /// \brief The diagnostic ID.
+  mutable unsigned DiagID;
+
+  /// \brief Storage for args and ranges.
+  mutable Storage *DiagStorage;
+
+  /// \brief Allocator used to allocate storage for this diagnostic.
+  StorageAllocator *Allocator;
+
+  /// \brief Retrieve storage for this particular diagnostic.
+  Storage *getStorage() const {
+    if (DiagStorage)
+      return DiagStorage;
+
+    if (Allocator)
+      DiagStorage = Allocator->Allocate();
+    else {
+      assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)));
+      DiagStorage = new Storage;
+    }
+    return DiagStorage;
+  }
+
+  void freeStorage() {
+    if (!DiagStorage)
+      return;
+
+    // The hot path for PartialDiagnostic is when we just used it to wrap an ID
+    // (typically so we have the flexibility of passing a more complex
+    // diagnostic into the callee, but that does not commonly occur).
+    //
+    // Split this out into a slow function for silly compilers (*cough*) which
+    // can't do decent partial inlining.
+    freeStorageSlow();
+  }
+
+  void freeStorageSlow() {
+    if (Allocator)
+      Allocator->Deallocate(DiagStorage);
+    else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+      delete DiagStorage;
+    DiagStorage = nullptr;
+  }
+
+  void AddSourceRange(const CharSourceRange &R) const {
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    DiagStorage->DiagRanges.push_back(R);
+  }
+
+  void AddFixItHint(const FixItHint &Hint) const {
+    if (Hint.isNull())
+      return;
+
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    DiagStorage->FixItHints.push_back(Hint);
+  }
+
+public:
+  struct NullDiagnostic {};
+  /// \brief Create a null partial diagnostic, which cannot carry a payload,
+  /// and only exists to be swapped with a real partial diagnostic.
+  PartialDiagnostic(NullDiagnostic)
+    : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { }
+
+  PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
+    : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
+
+  PartialDiagnostic(const PartialDiagnostic &Other)
+    : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
+  {
+    if (Other.DiagStorage) {
+      DiagStorage = getStorage();
+      *DiagStorage = *Other.DiagStorage;
+    }
+  }
+
+  PartialDiagnostic(PartialDiagnostic &&Other)
+    : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
+      Allocator(Other.Allocator) {
+    Other.DiagStorage = nullptr;
+  }
+
+  PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
+    : DiagID(Other.DiagID), DiagStorage(DiagStorage),
+      Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+  {
+    if (Other.DiagStorage)
+      *this->DiagStorage = *Other.DiagStorage;
+  }
+
+  PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
+    : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
+  {
+    // Copy arguments.
+    for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
+      if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string)
+        AddString(Other.getArgStdStr(I));
+      else
+        AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I));
+    }
+
+    // Copy source ranges.
+    for (unsigned I = 0, N = Other.getNumRanges(); I != N; ++I)
+      AddSourceRange(Other.getRange(I));
+
+    // Copy fix-its.
+    for (unsigned I = 0, N = Other.getNumFixItHints(); I != N; ++I)
+      AddFixItHint(Other.getFixItHint(I));
+  }
+
+  PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
+    DiagID = Other.DiagID;
+    if (Other.DiagStorage) {
+      if (!DiagStorage)
+        DiagStorage = getStorage();
+
+      *DiagStorage = *Other.DiagStorage;
+    } else {
+      freeStorage();
+    }
+
+    return *this;
+  }
+
+  PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
+    freeStorage();
+
+    DiagID = Other.DiagID;
+    DiagStorage = Other.DiagStorage;
+    Allocator = Other.Allocator;
+
+    Other.DiagStorage = nullptr;
+    return *this;
+  }
+
+  ~PartialDiagnostic() {
+    freeStorage();
+  }
+
+  void swap(PartialDiagnostic &PD) {
+    std::swap(DiagID, PD.DiagID);
+    std::swap(DiagStorage, PD.DiagStorage);
+    std::swap(Allocator, PD.Allocator);
+  }
+
+  unsigned getDiagID() const { return DiagID; }
+
+  void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
+    DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
+  }
+
+  void AddString(StringRef V) const {
+    if (!DiagStorage)
+      DiagStorage = getStorage();
+
+    assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
+           "Too many arguments to diagnostic!");
+    DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs]
+      = DiagnosticsEngine::ak_std_string;
+    DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V;
+  }
+
+  void Emit(const DiagnosticBuilder &DB) const {
+    if (!DiagStorage)
+      return;
+
+    // Add all arguments.
+    for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
+      if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]
+            == DiagnosticsEngine::ak_std_string)
+        DB.AddString(DiagStorage->DiagArgumentsStr[i]);
+      else
+        DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
+            (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
+    }
+
+    // Add all ranges.
+    for (const CharSourceRange &Range : DiagStorage->DiagRanges)
+      DB.AddSourceRange(Range);
+
+    // Add all fix-its.
+    for (const FixItHint &Fix : DiagStorage->FixItHints)
+      DB.AddFixItHint(Fix);
+  }
+
+  void EmitToString(DiagnosticsEngine &Diags,
+                    SmallVectorImpl<char> &Buf) const {
+    // FIXME: It should be possible to render a diagnostic to a string without
+    //        messing with the state of the diagnostics engine.
+    DiagnosticBuilder DB(Diags.Report(getDiagID()));
+    Emit(DB);
+    DB.FlushCounts();
+    Diagnostic(&Diags).FormatDiagnostic(Buf);
+    DB.Clear();
+    Diags.Clear();
+  }
+
+  /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
+  /// and removing all of its arguments, ranges, and fix-it hints.
+  void Reset(unsigned DiagID = 0) {
+    this->DiagID = DiagID;
+    freeStorage();
+  }
+
+  bool hasStorage() const { return DiagStorage != nullptr; }
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             unsigned I) {
+    PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
+    return PD;
+  }
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             int I) {
+    PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const char *S) {
+    PD.AddTaggedVal(reinterpret_cast<intptr_t>(S),
+                    DiagnosticsEngine::ak_c_string);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    StringRef S) {
+
+    PD.AddString(S);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const IdentifierInfo *II) {
+    PD.AddTaggedVal(reinterpret_cast<intptr_t>(II),
+                    DiagnosticsEngine::ak_identifierinfo);
+    return PD;
+  }
+
+  // Adds a DeclContext to the diagnostic. The enable_if template magic is here
+  // so that we only match those arguments that are (statically) DeclContexts;
+  // other arguments that derive from DeclContext (e.g., RecordDecls) will not
+  // match.
+  template<typename T>
+  friend inline
+  typename std::enable_if<std::is_same<T, DeclContext>::value,
+                          const PartialDiagnostic &>::type
+  operator<<(const PartialDiagnostic &PD, T *DC) {
+    PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+                    DiagnosticsEngine::ak_declcontext);
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const SourceRange &R) {
+    PD.AddSourceRange(CharSourceRange::getTokenRange(R));
+    return PD;
+  }
+
+  friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                                    const CharSourceRange &R) {
+    PD.AddSourceRange(R);
+    return PD;
+  }
+
+  friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                             const FixItHint &Hint) {
+    PD.AddFixItHint(Hint);
+    return PD;
+  }
+
+};
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const PartialDiagnostic &PD) {
+  PD.Emit(DB);
+  return DB;
+}
+
+/// \brief A partial diagnostic along with the source location where this
+/// diagnostic occurs.
+typedef std::pair<SourceLocation, PartialDiagnostic> PartialDiagnosticAt;
+
+}  // end namespace clang
+#endif
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
new file mode 100644
index 0000000..b7a9382
--- /dev/null
+++ b/include/clang/Basic/PlistSupport.h
@@ -0,0 +1,122 @@
+//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PLISTSUPPORT_H
+#define LLVM_CLANG_PLISTSUPPORT_H
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace markup {
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+                   const SourceManager &SM, SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::iterator I = FIDs.find(FID);
+  if (I != FIDs.end())
+    return;
+  FIDs[FID] = V.size();
+  V.push_back(FID);
+}
+
+inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+                       SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::const_iterator I = FIDs.find(FID);
+  assert(I != FIDs.end());
+  return I->second;
+}
+
+inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
+  for (unsigned i = 0; i < indent; ++i)
+    o << ' ';
+  return o;
+}
+
+inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
+  static const char *PlistHeader =
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+      "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+      "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+      "<plist version=\"1.0\">\n";
+  return o << PlistHeader;
+}
+
+inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
+  o << "<integer>";
+  o << value;
+  o << "</integer>";
+  return o;
+}
+
+inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
+  o << "<string>";
+  for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
+    char c = *I;
+    switch (c) {
+    default:
+      o << c;
+      break;
+    case '&':
+      o << "&amp;";
+      break;
+    case '<':
+      o << "&lt;";
+      break;
+    case '>':
+      o << "&gt;";
+      break;
+    case '\'':
+      o << "&apos;";
+      break;
+    case '\"':
+      o << "&quot;";
+      break;
+    }
+  }
+  o << "</string>";
+  return o;
+}
+
+inline void EmitLocation(raw_ostream &o, const SourceManager &SM,
+                         const LangOptions &LangOpts, SourceLocation L,
+                         const FIDMap &FM, unsigned indent,
+                         bool extend = false) {
+  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
+
+  // Add in the length of the token, so that we cover multi-char tokens.
+  unsigned offset =
+      extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+  Indent(o, indent) << "<dict>\n";
+  Indent(o, indent) << " <key>line</key>";
+  EmitInteger(o, Loc.getExpansionLineNumber()) << '\n';
+  Indent(o, indent) << " <key>col</key>";
+  EmitInteger(o, Loc.getExpansionColumnNumber() + offset) << '\n';
+  Indent(o, indent) << " <key>file</key>";
+  EmitInteger(o, GetFID(FM, SM, Loc)) << '\n';
+  Indent(o, indent) << "</dict>\n";
+}
+
+inline void EmitRange(raw_ostream &o, const SourceManager &SM,
+                      const LangOptions &LangOpts, CharSourceRange R,
+                      const FIDMap &FM, unsigned indent) {
+  Indent(o, indent) << "<array>\n";
+  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
+  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
+  Indent(o, indent) << "</array>\n";
+}
+}
+}
+
+#endif
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
new file mode 100644
index 0000000..0e49295
--- /dev/null
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -0,0 +1,38 @@
+//===- clang/Basic/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the PrettyStackTraceEntry class, which is used to make
+/// crashes give more contextual information about what the program was doing
+/// when it crashed.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_PRETTYSTACKTRACE_H
+#define CLANG_BASIC_PRETTYSTACKTRACE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+
+  /// If a crash happens while one of these objects are live, the message
+  /// is printed out along with the specified source location.
+  class PrettyStackTraceLoc : public llvm::PrettyStackTraceEntry {
+    SourceManager &SM;
+    SourceLocation Loc;
+    const char *Message;
+  public:
+    PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
+      : SM(sm), Loc(L), Message(Msg) {}
+    void print(raw_ostream &OS) const override;
+  };
+}
+
+#endif
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
new file mode 100644
index 0000000..0ef39bc
--- /dev/null
+++ b/include/clang/Basic/Sanitizers.def
@@ -0,0 +1,103 @@
+//===--- Sanitizers.def - Runtime sanitizer options -------------*- 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 options for specifying which runtime sanitizers to
+// enable. Users of this file must define the SANITIZER macro to make use of
+// this information. Users of this file can also define the SANITIZER_GROUP
+// macro to get information on options which refer to sets of sanitizers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER
+#error "Define SANITIZER prior to including this file!"
+#endif
+
+// SANITIZER(NAME, ID)
+
+// The first value is the name of the sanitizer as a string. The sanitizer can
+// be enabled by specifying -fsanitize=NAME.
+
+// The second value is an identifier which can be used to refer to the
+// sanitizer.
+
+
+// SANITIZER_GROUP(NAME, ID, ALIAS)
+
+// The first two values have the same semantics as the corresponding SANITIZER
+// values. The third value is an expression ORing together the IDs of individual
+// sanitizers in this group.
+
+#ifndef SANITIZER_GROUP
+#define SANITIZER_GROUP(NAME, ID, ALIAS)
+#endif
+
+
+// AddressSanitizer
+SANITIZER("address", Address)
+
+// MemorySanitizer
+SANITIZER("memory", Memory)
+
+// ThreadSanitizer
+SANITIZER("thread", Thread)
+
+// LeakSanitizer
+SANITIZER("leak", Leak)
+
+// UndefinedBehaviorSanitizer
+SANITIZER("alignment", Alignment)
+SANITIZER("array-bounds", ArrayBounds)
+SANITIZER("bool", Bool)
+SANITIZER("enum", Enum)
+SANITIZER("float-cast-overflow", FloatCastOverflow)
+SANITIZER("float-divide-by-zero", FloatDivideByZero)
+SANITIZER("function", Function)
+SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
+SANITIZER("null", Null)
+SANITIZER("object-size", ObjectSize)
+SANITIZER("return", Return)
+SANITIZER("shift", Shift)
+SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
+SANITIZER("unreachable", Unreachable)
+SANITIZER("vla-bound", VLABound)
+SANITIZER("vptr", Vptr)
+
+// IntegerSanitizer
+SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow)
+
+// DataFlowSanitizer
+SANITIZER("dataflow", DataFlow)
+
+// -fsanitize=undefined includes all the sanitizers which have low overhead, no
+// ABI or address space layout implications, and only catch undefined behavior.
+SANITIZER_GROUP("undefined", Undefined,
+                Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
+                FloatDivideByZero | Function | IntegerDivideByZero | Null |
+                ObjectSize | Return | Shift | SignedIntegerOverflow |
+                Unreachable | VLABound | Vptr)
+
+// -fsanitize=undefined-trap includes
+// all sanitizers included by -fsanitize=undefined, except those that require
+// runtime support.  This group is generally used in conjunction with the
+// -fsanitize-undefined-trap-on-error flag.
+SANITIZER_GROUP("undefined-trap", UndefinedTrap,
+                Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
+                FloatDivideByZero | IntegerDivideByZero | Null | ObjectSize |
+                Return | Shift | SignedIntegerOverflow | Unreachable |
+                VLABound)
+
+SANITIZER_GROUP("integer", Integer,
+                SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
+                IntegerDivideByZero)
+
+SANITIZER("local-bounds", LocalBounds)
+SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
+
+#undef SANITIZER
+#undef SANITIZER_GROUP
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
new file mode 100644
index 0000000..7b637d7
--- /dev/null
+++ b/include/clang/Basic/SourceLocation.h
@@ -0,0 +1,438 @@
+//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::SourceLocation class and associated facilities.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCELOCATION_H
+#define LLVM_CLANG_SOURCELOCATION_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+#include <functional>
+#include <string>
+#include <utility>
+
+namespace llvm {
+  class MemoryBuffer;
+  template <typename T> struct DenseMapInfo;
+  template <typename T> struct isPodLike;
+}
+
+namespace clang {
+
+class SourceManager;
+
+/// \brief An opaque identifier used by SourceManager which refers to a
+/// source file (MemoryBuffer) along with its \#include path and \#line data.
+///
+class FileID {
+  /// \brief A mostly-opaque identifier, where 0 is "invalid", >0 is 
+  /// this module, and <-1 is something loaded from another module.
+  int ID;
+public:
+  FileID() : ID(0) {}
+
+  bool isInvalid() const { return ID == 0; }
+
+  bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
+  bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
+  bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
+  bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
+  bool operator>(const FileID &RHS) const { return RHS < *this; }
+  bool operator>=(const FileID &RHS) const { return RHS <= *this; }
+
+  static FileID getSentinel() { return get(-1); }
+  unsigned getHashValue() const { return static_cast<unsigned>(ID); }
+
+private:
+  friend class SourceManager;
+  friend class ASTWriter;
+  friend class ASTReader;
+  
+  static FileID get(int V) {
+    FileID F;
+    F.ID = V;
+    return F;
+  }
+  int getOpaqueValue() const { return ID; }
+};
+
+
+/// \brief Encodes a location in the source. The SourceManager can decode this
+/// to get at the full include stack, line and column information.
+///
+/// Technically, a source location is simply an offset into the manager's view
+/// of the input source, which is all input buffers (including macro
+/// expansions) concatenated in an effectively arbitrary order. The manager
+/// actually maintains two blocks of input buffers. One, starting at offset
+/// 0 and growing upwards, contains all buffers from this module. The other,
+/// starting at the highest possible offset and growing downwards, contains
+/// buffers of loaded modules.
+///
+/// In addition, one bit of SourceLocation is used for quick access to the
+/// information whether the location is in a file or a macro expansion.
+///
+/// It is important that this type remains small. It is currently 32 bits wide.
+class SourceLocation {
+  unsigned ID;
+  friend class SourceManager;
+  friend class ASTReader;
+  friend class ASTWriter;
+  enum : unsigned {
+    MacroIDBit = 1U << 31
+  };
+public:
+
+  SourceLocation() : ID(0) {}
+
+  bool isFileID() const  { return (ID & MacroIDBit) == 0; }
+  bool isMacroID() const { return (ID & MacroIDBit) != 0; }
+
+  /// \brief Return true if this is a valid SourceLocation object.
+  ///
+  /// Invalid SourceLocations are often used when events have no corresponding
+  /// location in the source (e.g. a diagnostic is required for a command line
+  /// option).
+  bool isValid() const { return ID != 0; }
+  bool isInvalid() const { return ID == 0; }
+
+private:
+  /// \brief Return the offset into the manager's global input view.
+  unsigned getOffset() const {
+    return ID & ~MacroIDBit;
+  }
+
+  static SourceLocation getFileLoc(unsigned ID) {
+    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
+    SourceLocation L;
+    L.ID = ID;
+    return L;
+  }
+
+  static SourceLocation getMacroLoc(unsigned ID) {
+    assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
+    SourceLocation L;
+    L.ID = MacroIDBit | ID;
+    return L;
+  }
+public:
+
+  /// \brief Return a source location with the specified offset from this
+  /// SourceLocation.
+  SourceLocation getLocWithOffset(int Offset) const {
+    assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow");
+    SourceLocation L;
+    L.ID = ID+Offset;
+    return L;
+  }
+
+  /// \brief When a SourceLocation itself cannot be used, this returns
+  /// an (opaque) 32-bit integer encoding for it.
+  ///
+  /// This should only be passed to SourceLocation::getFromRawEncoding, it
+  /// should not be inspected directly.
+  unsigned getRawEncoding() const { return ID; }
+
+  /// \brief Turn a raw encoding of a SourceLocation object into
+  /// a real SourceLocation.
+  ///
+  /// \see getRawEncoding.
+  static SourceLocation getFromRawEncoding(unsigned Encoding) {
+    SourceLocation X;
+    X.ID = Encoding;
+    return X;
+  }
+
+  /// \brief When a SourceLocation itself cannot be used, this returns
+  /// an (opaque) pointer encoding for it.
+  ///
+  /// This should only be passed to SourceLocation::getFromPtrEncoding, it
+  /// should not be inspected directly.
+  void* getPtrEncoding() const {
+    // Double cast to avoid a warning "cast to pointer from integer of different
+    // size".
+    return (void*)(uintptr_t)getRawEncoding();
+  }
+
+  /// \brief Turn a pointer encoding of a SourceLocation object back
+  /// into a real SourceLocation.
+  static SourceLocation getFromPtrEncoding(const void *Encoding) {
+    return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
+  }
+
+  void print(raw_ostream &OS, const SourceManager &SM) const;
+  std::string printToString(const SourceManager &SM) const;
+  void dump(const SourceManager &SM) const;
+};
+
+inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return LHS.getRawEncoding() == RHS.getRawEncoding();
+}
+
+inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return !(LHS == RHS);
+}
+
+inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
+  return LHS.getRawEncoding() < RHS.getRawEncoding();
+}
+
+/// \brief A trivial tuple used to represent a source range.
+class SourceRange {
+  SourceLocation B;
+  SourceLocation E;
+public:
+  SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
+  SourceRange(SourceLocation loc) : B(loc), E(loc) {}
+  SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
+
+  SourceLocation getBegin() const { return B; }
+  SourceLocation getEnd() const { return E; }
+
+  void setBegin(SourceLocation b) { B = b; }
+  void setEnd(SourceLocation e) { E = e; }
+
+  bool isValid() const { return B.isValid() && E.isValid(); }
+  bool isInvalid() const { return !isValid(); }
+
+  bool operator==(const SourceRange &X) const {
+    return B == X.B && E == X.E;
+  }
+
+  bool operator!=(const SourceRange &X) const {
+    return B != X.B || E != X.E;
+  }
+};
+  
+/// \brief Represents a character-granular source range.
+///
+/// The underlying SourceRange can either specify the starting/ending character
+/// of the range, or it can specify the start of the range and the start of the
+/// last token of the range (a "token range").  In the token range case, the
+/// size of the last token must be measured to determine the actual end of the
+/// range.
+class CharSourceRange { 
+  SourceRange Range;
+  bool IsTokenRange;
+public:
+  CharSourceRange() : IsTokenRange(false) {}
+  CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
+
+  static CharSourceRange getTokenRange(SourceRange R) {
+    return CharSourceRange(R, true);
+  }
+
+  static CharSourceRange getCharRange(SourceRange R) {
+    return CharSourceRange(R, false);
+  }
+    
+  static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
+    return getTokenRange(SourceRange(B, E));
+  }
+  static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
+    return getCharRange(SourceRange(B, E));
+  }
+  
+  /// \brief Return true if the end of this range specifies the start of
+  /// the last token.  Return false if the end of this range specifies the last
+  /// character in the range.
+  bool isTokenRange() const { return IsTokenRange; }
+  bool isCharRange() const { return !IsTokenRange; }
+  
+  SourceLocation getBegin() const { return Range.getBegin(); }
+  SourceLocation getEnd() const { return Range.getEnd(); }
+  const SourceRange &getAsRange() const { return Range; }
+ 
+  void setBegin(SourceLocation b) { Range.setBegin(b); }
+  void setEnd(SourceLocation e) { Range.setEnd(e); }
+  
+  bool isValid() const { return Range.isValid(); }
+  bool isInvalid() const { return !isValid(); }
+};
+
+/// \brief A SourceLocation and its associated SourceManager.
+///
+/// This is useful for argument passing to functions that expect both objects.
+class FullSourceLoc : public SourceLocation {
+  const SourceManager *SrcMgr;
+public:
+  /// \brief Creates a FullSourceLoc where isValid() returns \c false.
+  explicit FullSourceLoc() : SrcMgr(nullptr) {}
+
+  explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
+    : SourceLocation(Loc), SrcMgr(&SM) {}
+
+  /// \pre This FullSourceLoc has an associated SourceManager.
+  const SourceManager &getManager() const {
+    assert(SrcMgr && "SourceManager is NULL.");
+    return *SrcMgr;
+  }
+
+  FileID getFileID() const;
+
+  FullSourceLoc getExpansionLoc() const;
+  FullSourceLoc getSpellingLoc() const;
+
+  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
+  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
+
+  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
+  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
+
+  const char *getCharacterData(bool *Invalid = nullptr) const;
+
+  const llvm::MemoryBuffer* getBuffer(bool *Invalid = nullptr) const;
+
+  /// \brief Return a StringRef to the source buffer data for the
+  /// specified FileID.
+  StringRef getBufferData(bool *Invalid = nullptr) const;
+
+  /// \brief Decompose the specified location into a raw FileID + Offset pair.
+  ///
+  /// The first element is the FileID, the second is the offset from the
+  /// start of the buffer of the location.
+  std::pair<FileID, unsigned> getDecomposedLoc() const;
+
+  bool isInSystemHeader() const;
+
+  /// \brief Determines the order of 2 source locations in the translation unit.
+  ///
+  /// \returns true if this source location comes before 'Loc', false otherwise.
+  bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
+
+  /// \brief Determines the order of 2 source locations in the translation unit.
+  ///
+  /// \returns true if this source location comes before 'Loc', false otherwise.
+  bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
+    assert(Loc.isValid());
+    assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!");
+    return isBeforeInTranslationUnitThan((SourceLocation)Loc);
+  }
+
+  /// \brief Comparison function class, useful for sorting FullSourceLocs.
+  struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
+                                                         FullSourceLoc, bool> {
+    bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
+      return lhs.isBeforeInTranslationUnitThan(rhs);
+    }
+  };
+
+  /// \brief Prints information about this FullSourceLoc to stderr.
+  ///
+  /// This is useful for debugging.
+  void dump() const;
+
+  friend inline bool
+  operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
+    return LHS.getRawEncoding() == RHS.getRawEncoding() &&
+          LHS.SrcMgr == RHS.SrcMgr;
+  }
+
+  friend inline bool
+  operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
+    return !(LHS == RHS);
+  }
+
+};
+
+/// \brief Represents an unpacked "presumed" location which can be presented
+/// to the user.
+///
+/// A 'presumed' location can be modified by \#line and GNU line marker
+/// directives and is always the expansion point of a normal location.
+///
+/// You can get a PresumedLoc from a SourceLocation with SourceManager.
+class PresumedLoc {
+  const char *Filename;
+  unsigned Line, Col;
+  SourceLocation IncludeLoc;
+public:
+  PresumedLoc() : Filename(nullptr) {}
+  PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
+    : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
+  }
+
+  /// \brief Return true if this object is invalid or uninitialized.
+  ///
+  /// This occurs when created with invalid source locations or when walking
+  /// off the top of a \#include stack.
+  bool isInvalid() const { return Filename == nullptr; }
+  bool isValid() const { return Filename != nullptr; }
+
+  /// \brief Return the presumed filename of this location.
+  ///
+  /// This can be affected by \#line etc.
+  const char *getFilename() const { return Filename; }
+
+  /// \brief Return the presumed line number of this location.
+  ///
+  /// This can be affected by \#line etc.
+  unsigned getLine() const { return Line; }
+
+  /// \brief Return the presumed column number of this location.
+  ///
+  /// This cannot be affected by \#line, but is packaged here for convenience.
+  unsigned getColumn() const { return Col; }
+
+  /// \brief Return the presumed include location of this location.
+  ///
+  /// This can be affected by GNU linemarker directives.
+  SourceLocation getIncludeLoc() const { return IncludeLoc; }
+};
+
+
+}  // end namespace clang
+
+namespace llvm {
+  /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
+  /// DenseSets.
+  template <>
+  struct DenseMapInfo<clang::FileID> {
+    static inline clang::FileID getEmptyKey() {
+      return clang::FileID();
+    }
+    static inline clang::FileID getTombstoneKey() {
+      return clang::FileID::getSentinel();
+    }
+
+    static unsigned getHashValue(clang::FileID S) {
+      return S.getHashValue();
+    }
+
+    static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
+      return LHS == RHS;
+    }
+  };
+  
+  template <>
+  struct isPodLike<clang::SourceLocation> { static const bool value = true; };
+  template <>
+  struct isPodLike<clang::FileID> { static const bool value = true; };
+
+  // Teach SmallPtrSet how to handle SourceLocation.
+  template<>
+  class PointerLikeTypeTraits<clang::SourceLocation> {
+  public:
+    static inline void *getAsVoidPointer(clang::SourceLocation L) {
+      return L.getPtrEncoding();
+    }
+    static inline clang::SourceLocation getFromVoidPointer(void *P) {
+      return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
+    }
+    enum { NumLowBitsAvailable = 0 };
+  };
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
new file mode 100644
index 0000000..e567a7a
--- /dev/null
+++ b/include/clang/Basic/SourceManager.h
@@ -0,0 +1,1685 @@
+//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the SourceManager interface.
+///
+/// There are three different types of locations in a %file: a spelling
+/// location, an expansion location, and a presumed location.
+///
+/// Given an example of:
+/// \code
+/// #define min(x, y) x < y ? x : y
+/// \endcode
+///
+/// and then later on a use of min:
+/// \code
+/// #line 17
+/// return min(a, b);
+/// \endcode
+///
+/// The expansion location is the line in the source code where the macro
+/// was expanded (the return statement), the spelling location is the
+/// location in the source where the macro was originally defined,
+/// and the presumed location is where the line directive states that
+/// the line is 17, or any other line.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_H
+#define LLVM_CLANG_SOURCEMANAGER_H
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace clang {
+
+class DiagnosticsEngine;
+class SourceManager;
+class FileManager;
+class FileEntry;
+class LineTableInfo;
+class LangOptions;
+class ASTWriter;
+class ASTReader;
+
+/// \brief Public enums and private classes that are part of the
+/// SourceManager implementation.
+///
+namespace SrcMgr {
+  /// \brief Indicates whether a file or directory holds normal user code,
+  /// system code, or system code which is implicitly 'extern "C"' in C++ mode.
+  ///
+  /// Entire directories can be tagged with this (this is maintained by
+  /// DirectoryLookup and friends) as can specific FileInfos when a \#pragma
+  /// system_header is seen or in various other cases.
+  ///
+  enum CharacteristicKind {
+    C_User, C_System, C_ExternCSystem
+  };
+
+  /// \brief One instance of this struct is kept for every file loaded or used.
+  ///
+  /// This object owns the MemoryBuffer object.
+  class ContentCache {
+    enum CCFlags {
+      /// \brief Whether the buffer is invalid.
+      InvalidFlag = 0x01,
+      /// \brief Whether the buffer should not be freed on destruction.
+      DoNotFreeFlag = 0x02
+    };
+
+    // Note that the first member of this class is an aligned character buffer
+    // to ensure that this class has an alignment of 8 bytes. This wastes
+    // 8 bytes for every ContentCache object, but each of these corresponds to
+    // a file loaded into memory, so the 8 bytes doesn't seem terribly
+    // important. It is quite awkward to fit this aligner into any other part
+    // of the class due to the lack of portable ways to combine it with other
+    // members.
+    llvm::AlignedCharArray<8, 1> NonceAligner;
+
+    /// \brief The actual buffer containing the characters from the input
+    /// file.
+    ///
+    /// This is owned by the ContentCache object.  The bits indicate
+    /// whether the buffer is invalid.
+    mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
+
+  public:
+    /// \brief Reference to the file entry representing this ContentCache.
+    ///
+    /// This reference does not own the FileEntry object.
+    ///
+    /// It is possible for this to be NULL if the ContentCache encapsulates
+    /// an imaginary text buffer.
+    const FileEntry *OrigEntry;
+
+    /// \brief References the file which the contents were actually loaded from.
+    ///
+    /// Can be different from 'Entry' if we overridden the contents of one file
+    /// with the contents of another file.
+    const FileEntry *ContentsEntry;
+
+    /// \brief A bump pointer allocated array of offsets for each source line.
+    ///
+    /// This is lazily computed.  This is owned by the SourceManager
+    /// BumpPointerAllocator object.
+    unsigned *SourceLineCache;
+
+    /// \brief The number of lines in this ContentCache.
+    ///
+    /// This is only valid if SourceLineCache is non-null.
+    unsigned NumLines : 31;
+
+    /// \brief Indicates whether the buffer itself was provided to override
+    /// the actual file contents.
+    ///
+    /// When true, the original entry may be a virtual file that does not
+    /// exist.
+    unsigned BufferOverridden : 1;
+
+    /// \brief True if this content cache was initially created for a source
+    /// file considered as a system one.
+    unsigned IsSystemFile : 1;
+    
+    ContentCache(const FileEntry *Ent = nullptr)
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(Ent),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
+        IsSystemFile(false) {
+      (void)NonceAligner; // Silence warnings about unused member.
+    }
+    
+    ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
+        IsSystemFile(false) {}
+    
+    ~ContentCache();
+    
+    /// The copy ctor does not allow copies where source object has either
+    /// a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
+    /// is not transferred, so this is a logical error.
+    ContentCache(const ContentCache &RHS)
+      : Buffer(nullptr, false), SourceLineCache(nullptr),
+        BufferOverridden(false), IsSystemFile(false) {
+      OrigEntry = RHS.OrigEntry;
+      ContentsEntry = RHS.ContentsEntry;
+
+      assert(RHS.Buffer.getPointer() == nullptr &&
+             RHS.SourceLineCache == nullptr &&
+             "Passed ContentCache object cannot own a buffer.");
+
+      NumLines = RHS.NumLines;
+    }
+
+    /// \brief Returns the memory buffer for the associated content.
+    ///
+    /// \param Diag Object through which diagnostics will be emitted if the
+    ///   buffer cannot be retrieved.
+    ///
+    /// \param Loc If specified, is the location that invalid file diagnostics
+    ///   will be emitted at.
+    ///
+    /// \param Invalid If non-NULL, will be set \c true if an error occurred.
+    llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
+                                  const SourceManager &SM,
+                                  SourceLocation Loc = SourceLocation(),
+                                  bool *Invalid = nullptr) const;
+
+    /// \brief Returns the size of the content encapsulated by this
+    /// ContentCache.
+    ///
+    /// This can be the size of the source file or the size of an
+    /// arbitrary scratch buffer.  If the ContentCache encapsulates a source
+    /// file this size is retrieved from the file's FileEntry.
+    unsigned getSize() const;
+
+    /// \brief Returns the number of bytes actually mapped for this
+    /// ContentCache.
+    ///
+    /// This can be 0 if the MemBuffer was not actually expanded.
+    unsigned getSizeBytesMapped() const;
+
+    /// Returns the kind of memory used to back the memory buffer for
+    /// this content cache.  This is used for performance analysis.
+    llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
+
+    void setBuffer(llvm::MemoryBuffer *B) {
+      assert(!Buffer.getPointer() && "MemoryBuffer already set.");
+      Buffer.setPointer(B);
+      Buffer.setInt(false);
+    }
+
+    /// \brief Get the underlying buffer, returning NULL if the buffer is not
+    /// yet available.
+    llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
+
+    /// \brief Replace the existing buffer (which will be deleted)
+    /// with the given buffer.
+    void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
+
+    /// \brief Determine whether the buffer itself is invalid.
+    bool isBufferInvalid() const {
+      return Buffer.getInt() & InvalidFlag;
+    }
+
+    /// \brief Determine whether the buffer should be freed.
+    bool shouldFreeBuffer() const {
+      return (Buffer.getInt() & DoNotFreeFlag) == 0;
+    }
+
+  private:
+    // Disable assignments.
+    ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION;
+  };
+
+  // Assert that the \c ContentCache objects will always be 8-byte aligned so
+  // that we can pack 3 bits of integer into pointers to such objects.
+  static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
+                "ContentCache must be 8-byte aligned.");
+
+  /// \brief Information about a FileID, basically just the logical file
+  /// that it represents and include stack information.
+  ///
+  /// Each FileInfo has include stack information, indicating where it came
+  /// from. This information encodes the \#include chain that a token was
+  /// expanded from. The main include file has an invalid IncludeLoc.
+  ///
+  /// FileInfos contain a "ContentCache *", with the contents of the file.
+  ///
+  class FileInfo {
+    /// \brief The location of the \#include that brought in this file.
+    ///
+    /// This is an invalid SLOC for the main file (top of the \#include chain).
+    unsigned IncludeLoc;  // Really a SourceLocation
+
+    /// \brief Number of FileIDs (files and macros) that were created during
+    /// preprocessing of this \#include, including this SLocEntry.
+    ///
+    /// Zero means the preprocessor didn't provide such info for this SLocEntry.
+    unsigned NumCreatedFIDs;
+
+    /// \brief Contains the ContentCache* and the bits indicating the
+    /// characteristic of the file and whether it has \#line info, all
+    /// bitmangled together.
+    uintptr_t Data;
+
+    friend class clang::SourceManager;
+    friend class clang::ASTWriter;
+    friend class clang::ASTReader;
+  public:
+    /// \brief Return a FileInfo object.
+    static FileInfo get(SourceLocation IL, const ContentCache *Con,
+                        CharacteristicKind FileCharacter) {
+      FileInfo X;
+      X.IncludeLoc = IL.getRawEncoding();
+      X.NumCreatedFIDs = 0;
+      X.Data = (uintptr_t)Con;
+      assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned");
+      assert((unsigned)FileCharacter < 4 && "invalid file character");
+      X.Data |= (unsigned)FileCharacter;
+      return X;
+    }
+
+    SourceLocation getIncludeLoc() const {
+      return SourceLocation::getFromRawEncoding(IncludeLoc);
+    }
+    const ContentCache* getContentCache() const {
+      return reinterpret_cast<const ContentCache*>(Data & ~uintptr_t(7));
+    }
+
+    /// \brief Return whether this is a system header or not.
+    CharacteristicKind getFileCharacteristic() const {
+      return (CharacteristicKind)(Data & 3);
+    }
+
+    /// \brief Return true if this FileID has \#line directives in it.
+    bool hasLineDirectives() const { return (Data & 4) != 0; }
+
+    /// \brief Set the flag that indicates that this FileID has
+    /// line table entries associated with it.
+    void setHasLineDirectives() {
+      Data |= 4;
+    }
+  };
+
+  /// \brief Each ExpansionInfo encodes the expansion location - where
+  /// the token was ultimately expanded, and the SpellingLoc - where the actual
+  /// character data for the token came from.
+  class ExpansionInfo {
+    // Really these are all SourceLocations.
+
+    /// \brief Where the spelling for the token can be found.
+    unsigned SpellingLoc;
+
+    /// In a macro expansion, ExpansionLocStart and ExpansionLocEnd
+    /// indicate the start and end of the expansion. In object-like macros,
+    /// they will be the same. In a function-like macro expansion, the start
+    /// will be the identifier and the end will be the ')'. Finally, in
+    /// macro-argument instantiations, the end will be 'SourceLocation()', an
+    /// invalid location.
+    unsigned ExpansionLocStart, ExpansionLocEnd;
+
+  public:
+    SourceLocation getSpellingLoc() const {
+      return SourceLocation::getFromRawEncoding(SpellingLoc);
+    }
+    SourceLocation getExpansionLocStart() const {
+      return SourceLocation::getFromRawEncoding(ExpansionLocStart);
+    }
+    SourceLocation getExpansionLocEnd() const {
+      SourceLocation EndLoc =
+        SourceLocation::getFromRawEncoding(ExpansionLocEnd);
+      return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc;
+    }
+
+    std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const {
+      return std::make_pair(getExpansionLocStart(), getExpansionLocEnd());
+    }
+
+    bool isMacroArgExpansion() const {
+      // Note that this needs to return false for default constructed objects.
+      return getExpansionLocStart().isValid() &&
+        SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid();
+    }
+
+    bool isMacroBodyExpansion() const {
+      return getExpansionLocStart().isValid() &&
+        SourceLocation::getFromRawEncoding(ExpansionLocEnd).isValid();
+    }
+
+    bool isFunctionMacroExpansion() const {
+      return getExpansionLocStart().isValid() &&
+          getExpansionLocStart() != getExpansionLocEnd();
+    }
+
+    /// \brief Return a ExpansionInfo for an expansion.
+    ///
+    /// Start and End specify the expansion range (where the macro is
+    /// expanded), and SpellingLoc specifies the spelling location (where
+    /// the characters from the token come from). All three can refer to
+    /// normal File SLocs or expansion locations.
+    static ExpansionInfo create(SourceLocation SpellingLoc,
+                                SourceLocation Start, SourceLocation End) {
+      ExpansionInfo X;
+      X.SpellingLoc = SpellingLoc.getRawEncoding();
+      X.ExpansionLocStart = Start.getRawEncoding();
+      X.ExpansionLocEnd = End.getRawEncoding();
+      return X;
+    }
+
+    /// \brief Return a special ExpansionInfo for the expansion of
+    /// a macro argument into a function-like macro's body.
+    ///
+    /// ExpansionLoc specifies the expansion location (where the macro is
+    /// expanded). This doesn't need to be a range because a macro is always
+    /// expanded at a macro parameter reference, and macro parameters are
+    /// always exactly one token. SpellingLoc specifies the spelling location
+    /// (where the characters from the token come from). ExpansionLoc and
+    /// SpellingLoc can both refer to normal File SLocs or expansion locations.
+    ///
+    /// Given the code:
+    /// \code
+    ///   #define F(x) f(x)
+    ///   F(42);
+    /// \endcode
+    ///
+    /// When expanding '\c F(42)', the '\c x' would call this with an
+    /// SpellingLoc pointing at '\c 42' and an ExpansionLoc pointing at its
+    /// location in the definition of '\c F'.
+    static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc,
+                                           SourceLocation ExpansionLoc) {
+      // We store an intentionally invalid source location for the end of the
+      // expansion range to mark that this is a macro argument ion rather than
+      // a normal one.
+      return create(SpellingLoc, ExpansionLoc, SourceLocation());
+    }
+  };
+
+  /// \brief This is a discriminated union of FileInfo and ExpansionInfo.
+  ///
+  /// SourceManager keeps an array of these objects, and they are uniquely
+  /// identified by the FileID datatype.
+  class SLocEntry {
+    unsigned Offset;   // low bit is set for expansion info.
+    union {
+      FileInfo File;
+      ExpansionInfo Expansion;
+    };
+  public:
+    unsigned getOffset() const { return Offset >> 1; }
+
+    bool isExpansion() const { return Offset & 1; }
+    bool isFile() const { return !isExpansion(); }
+
+    const FileInfo &getFile() const {
+      assert(isFile() && "Not a file SLocEntry!");
+      return File;
+    }
+
+    const ExpansionInfo &getExpansion() const {
+      assert(isExpansion() && "Not a macro expansion SLocEntry!");
+      return Expansion;
+    }
+
+    static SLocEntry get(unsigned Offset, const FileInfo &FI) {
+      SLocEntry E;
+      E.Offset = Offset << 1;
+      E.File = FI;
+      return E;
+    }
+
+    static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) {
+      SLocEntry E;
+      E.Offset = (Offset << 1) | 1;
+      E.Expansion = Expansion;
+      return E;
+    }
+  };
+}  // end SrcMgr namespace.
+
+/// \brief External source of source location entries.
+class ExternalSLocEntrySource {
+public:
+  virtual ~ExternalSLocEntrySource();
+
+  /// \brief Read the source location entry with index ID, which will always be
+  /// less than -1.
+  ///
+  /// \returns true if an error occurred that prevented the source-location
+  /// entry from being loaded.
+  virtual bool ReadSLocEntry(int ID) = 0;
+
+  /// \brief Retrieve the module import location and name for the given ID, if
+  /// in fact it was loaded from a module (rather than, say, a precompiled
+  /// header).
+  virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0;
+};
+
+
+/// \brief Holds the cache used by isBeforeInTranslationUnit.
+///
+/// The cache structure is complex enough to be worth breaking out of
+/// SourceManager.
+class InBeforeInTUCacheEntry {
+  /// \brief The FileID's of the cached query.
+  ///
+  /// If these match up with a subsequent query, the result can be reused.
+  FileID LQueryFID, RQueryFID;
+
+  /// \brief True if LQueryFID was created before RQueryFID.
+  ///
+  /// This is used to compare macro expansion locations.
+  bool IsLQFIDBeforeRQFID;
+
+  /// \brief The file found in common between the two \#include traces, i.e.,
+  /// the nearest common ancestor of the \#include tree.
+  FileID CommonFID;
+
+  /// \brief The offset of the previous query in CommonFID.
+  ///
+  /// Usually, this represents the location of the \#include for QueryFID, but
+  /// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a
+  /// random token in the parent.
+  unsigned LCommonOffset, RCommonOffset;
+public:
+  /// \brief Return true if the currently cached values match up with
+  /// the specified LHS/RHS query.
+  ///
+  /// If not, we can't use the cache.
+  bool isCacheValid(FileID LHS, FileID RHS) const {
+    return LQueryFID == LHS && RQueryFID == RHS;
+  }
+
+  /// \brief If the cache is valid, compute the result given the
+  /// specified offsets in the LHS/RHS FileID's.
+  bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
+    // If one of the query files is the common file, use the offset.  Otherwise,
+    // use the #include loc in the common file.
+    if (LQueryFID != CommonFID) LOffset = LCommonOffset;
+    if (RQueryFID != CommonFID) ROffset = RCommonOffset;
+
+    // It is common for multiple macro expansions to be "included" from the same
+    // location (expansion location), in which case use the order of the FileIDs
+    // to determine which came first. This will also take care the case where
+    // one of the locations points at the inclusion/expansion point of the other
+    // in which case its FileID will come before the other.
+    if (LOffset == ROffset)
+      return IsLQFIDBeforeRQFID;
+
+    return LOffset < ROffset;
+  }
+
+  /// \brief Set up a new query.
+  void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
+    assert(LHS != RHS);
+    LQueryFID = LHS;
+    RQueryFID = RHS;
+    IsLQFIDBeforeRQFID = isLFIDBeforeRFID;
+  }
+
+  void clear() {
+    LQueryFID = RQueryFID = FileID();
+    IsLQFIDBeforeRQFID = false;
+  }
+
+  void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
+                    unsigned rCommonOffset) {
+    CommonFID = commonFID;
+    LCommonOffset = lCommonOffset;
+    RCommonOffset = rCommonOffset;
+  }
+
+};
+
+/// \brief The stack used when building modules on demand, which is used
+/// to provide a link between the source managers of the different compiler
+/// instances.
+typedef ArrayRef<std::pair<std::string, FullSourceLoc> > ModuleBuildStack;
+
+/// \brief This class handles loading and caching of source files into memory.
+///
+/// This object owns the MemoryBuffer objects for all of the loaded
+/// files and assigns unique FileID's for each unique \#include chain.
+///
+/// The SourceManager can be queried for information about SourceLocation
+/// objects, turning them into either spelling or expansion locations. Spelling
+/// locations represent where the bytes corresponding to a token came from and
+/// expansion locations represent where the location is in the user's view. In
+/// the case of a macro expansion, for example, the spelling location indicates
+/// where the expanded token came from and the expansion location specifies
+/// where it was expanded.
+class SourceManager : public RefCountedBase<SourceManager> {
+  /// \brief DiagnosticsEngine object.
+  DiagnosticsEngine &Diag;
+
+  FileManager &FileMgr;
+
+  mutable llvm::BumpPtrAllocator ContentCacheAlloc;
+
+  /// \brief Memoized information about all of the files tracked by this
+  /// SourceManager.
+  ///
+  /// This map allows us to merge ContentCache entries based
+  /// on their FileEntry*.  All ContentCache objects will thus have unique,
+  /// non-null, FileEntry pointers.
+  llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
+
+  /// \brief True if the ContentCache for files that are overridden by other
+  /// files, should report the original file name. Defaults to true.
+  bool OverridenFilesKeepOriginalName;
+
+  /// \brief True if non-system source files should be treated as volatile
+  /// (likely to change while trying to use them). Defaults to false.
+  bool UserFilesAreVolatile;
+
+  struct OverriddenFilesInfoTy {
+    /// \brief Files that have been overridden with the contents from another
+    /// file.
+    llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
+    /// \brief Files that were overridden with a memory buffer.
+    llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
+  };
+
+  /// \brief Lazily create the object keeping overridden files info, since
+  /// it is uncommonly used.
+  std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
+
+  OverriddenFilesInfoTy &getOverriddenFilesInfo() {
+    if (!OverriddenFilesInfo)
+      OverriddenFilesInfo.reset(new OverriddenFilesInfoTy);
+    return *OverriddenFilesInfo;
+  }
+
+  /// \brief Information about various memory buffers that we have read in.
+  ///
+  /// All FileEntry* within the stored ContentCache objects are NULL,
+  /// as they do not refer to a file.
+  std::vector<SrcMgr::ContentCache*> MemBufferInfos;
+
+  /// \brief The table of SLocEntries that are local to this module.
+  ///
+  /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid
+  /// expansion.
+  SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable;
+
+  /// \brief The table of SLocEntries that are loaded from other modules.
+  ///
+  /// Negative FileIDs are indexes into this table. To get from ID to an index,
+  /// use (-ID - 2).
+  mutable SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
+
+  /// \brief The starting offset of the next local SLocEntry.
+  ///
+  /// This is LocalSLocEntryTable.back().Offset + the size of that entry.
+  unsigned NextLocalOffset;
+
+  /// \brief The starting offset of the latest batch of loaded SLocEntries.
+  ///
+  /// This is LoadedSLocEntryTable.back().Offset, except that that entry might
+  /// not have been loaded, so that value would be unknown.
+  unsigned CurrentLoadedOffset;
+
+  /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset
+  /// starts at 2^31.
+  static const unsigned MaxLoadedOffset = 1U << 31U;
+
+  /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable
+  /// have already been loaded from the external source.
+  ///
+  /// Same indexing as LoadedSLocEntryTable.
+  std::vector<bool> SLocEntryLoaded;
+
+  /// \brief An external source for source location entries.
+  ExternalSLocEntrySource *ExternalSLocEntries;
+
+  /// \brief A one-entry cache to speed up getFileID.
+  ///
+  /// LastFileIDLookup records the last FileID looked up or created, because it
+  /// is very common to look up many tokens from the same file.
+  mutable FileID LastFileIDLookup;
+
+  /// \brief Holds information for \#line directives.
+  ///
+  /// This is referenced by indices from SLocEntryTable.
+  LineTableInfo *LineTable;
+
+  /// \brief These ivars serve as a cache used in the getLineNumber
+  /// method which is used to speedup getLineNumber calls to nearby locations.
+  mutable FileID LastLineNoFileIDQuery;
+  mutable SrcMgr::ContentCache *LastLineNoContentCache;
+  mutable unsigned LastLineNoFilePos;
+  mutable unsigned LastLineNoResult;
+
+  /// \brief The file ID for the main source file of the translation unit.
+  FileID MainFileID;
+
+  /// \brief The file ID for the precompiled preamble there is one.
+  FileID PreambleFileID;
+
+  // Statistics for -print-stats.
+  mutable unsigned NumLinearScans, NumBinaryProbes;
+
+  /// \brief Associates a FileID with its "included/expanded in" decomposed
+  /// location.
+  ///
+  /// Used to cache results from and speed-up \c getDecomposedIncludedLoc
+  /// function.
+  mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap;
+
+  /// The key value into the IsBeforeInTUCache table.
+  typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey;
+
+  /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs
+  /// to cache results.
+  typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>
+          InBeforeInTUCache;
+
+  /// Cache results for the isBeforeInTranslationUnit method.
+  mutable InBeforeInTUCache IBTUCache;
+  mutable InBeforeInTUCacheEntry IBTUCacheOverflow;
+
+  /// Return the cache entry for comparing the given file IDs
+  /// for isBeforeInTranslationUnit.
+  InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const;
+
+  // Cache for the "fake" buffer used for error-recovery purposes.
+  mutable llvm::MemoryBuffer *FakeBufferForRecovery;
+
+  mutable SrcMgr::ContentCache *FakeContentCacheForRecovery;
+
+  /// \brief Lazily computed map of macro argument chunks to their expanded
+  /// source location.
+  typedef std::map<unsigned, SourceLocation> MacroArgsMap;
+
+  mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap;
+
+  /// \brief The stack of modules being built, which is used to detect
+  /// cycles in the module dependency graph as modules are being built, as
+  /// well as to describe why we're rebuilding a particular module.
+  ///
+  /// There is no way to set this value from the command line. If we ever need
+  /// to do so (e.g., if on-demand module construction moves out-of-process),
+  /// we can add a cc1-level option to do so.
+  SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
+
+  // SourceManager doesn't support copy construction.
+  explicit SourceManager(const SourceManager&) LLVM_DELETED_FUNCTION;
+  void operator=(const SourceManager&) LLVM_DELETED_FUNCTION;
+public:
+  SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
+                bool UserFilesAreVolatile = false);
+  ~SourceManager();
+
+  void clearIDTables();
+
+  DiagnosticsEngine &getDiagnostics() const { return Diag; }
+
+  FileManager &getFileManager() const { return FileMgr; }
+
+  /// \brief Set true if the SourceManager should report the original file name
+  /// for contents of files that were overridden by other files. Defaults to
+  /// true.
+  void setOverridenFilesKeepOriginalName(bool value) {
+    OverridenFilesKeepOriginalName = value;
+  }
+
+  /// \brief True if non-system source files should be treated as volatile
+  /// (likely to change while trying to use them).
+  bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
+
+  /// \brief Retrieve the module build stack.
+  ModuleBuildStack getModuleBuildStack() const {
+    return StoredModuleBuildStack;
+  }
+
+  /// \brief Set the module build stack.
+  void setModuleBuildStack(ModuleBuildStack stack) {
+    StoredModuleBuildStack.clear();
+    StoredModuleBuildStack.append(stack.begin(), stack.end());
+  }
+
+  /// \brief Push an entry to the module build stack.
+  void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) {
+    StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // MainFileID creation and querying methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Returns the FileID of the main source file.
+  FileID getMainFileID() const { return MainFileID; }
+
+  /// \brief Set the file ID for the main source file.
+  void setMainFileID(FileID FID) {
+    assert(MainFileID.isInvalid() && "MainFileID already set!");
+    MainFileID = FID;
+  }
+
+  /// \brief Set the file ID for the precompiled preamble.
+  void setPreambleFileID(FileID Preamble) {
+    assert(PreambleFileID.isInvalid() && "PreambleFileID already set!");
+    PreambleFileID = Preamble;
+  }
+
+  /// \brief Get the file ID for the precompiled preamble if there is one.
+  FileID getPreambleFileID() const { return PreambleFileID; }
+
+  //===--------------------------------------------------------------------===//
+  // Methods to create new FileID's and macro expansions.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Create a new FileID that represents the specified file
+  /// being \#included from the specified IncludePosition.
+  ///
+  /// This translates NULL into standard input.
+  FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
+                      SrcMgr::CharacteristicKind FileCharacter,
+                      int LoadedID = 0, unsigned LoadedOffset = 0) {
+    const SrcMgr::ContentCache *
+      IR = getOrCreateContentCache(SourceFile,
+                              /*isSystemFile=*/FileCharacter != SrcMgr::C_User);
+    assert(IR && "getOrCreateContentCache() cannot return NULL");
+    return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset);
+  }
+
+  /// \brief Create a new FileID that represents the specified memory buffer.
+  ///
+  /// This does no caching of the buffer and takes ownership of the
+  /// MemoryBuffer, so only pass a MemoryBuffer to this once.
+  FileID createFileID(llvm::MemoryBuffer *Buffer,
+                      SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
+                      int LoadedID = 0, unsigned LoadedOffset = 0,
+                      SourceLocation IncludeLoc = SourceLocation()) {
+    return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
+                        FileCharacter, LoadedID, LoadedOffset);
+  }
+
+  /// \brief Return a new SourceLocation that encodes the
+  /// fact that a token from SpellingLoc should actually be referenced from
+  /// ExpansionLoc, and that it represents the expansion of a macro argument
+  /// into the function-like macro body.
+  SourceLocation createMacroArgExpansionLoc(SourceLocation Loc,
+                                            SourceLocation ExpansionLoc,
+                                            unsigned TokLength);
+
+  /// \brief Return a new SourceLocation that encodes the fact
+  /// that a token from SpellingLoc should actually be referenced from
+  /// ExpansionLoc.
+  SourceLocation createExpansionLoc(SourceLocation Loc,
+                                    SourceLocation ExpansionLocStart,
+                                    SourceLocation ExpansionLocEnd,
+                                    unsigned TokLength,
+                                    int LoadedID = 0,
+                                    unsigned LoadedOffset = 0);
+
+  /// \brief Retrieve the memory buffer associated with the given file.
+  ///
+  /// \param Invalid If non-NULL, will be set \c true if an error
+  /// occurs while retrieving the memory buffer.
+  llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+                                             bool *Invalid = nullptr);
+
+  /// \brief Override the contents of the given source file by providing an
+  /// already-allocated buffer.
+  ///
+  /// \param SourceFile the source file whose contents will be overridden.
+  ///
+  /// \param Buffer the memory buffer whose contents will be used as the
+  /// data in the given source file.
+  ///
+  /// \param DoNotFree If true, then the buffer will not be freed when the
+  /// source manager is destroyed.
+  void overrideFileContents(const FileEntry *SourceFile,
+                            llvm::MemoryBuffer *Buffer, bool DoNotFree = false);
+
+  /// \brief Override the given source file with another one.
+  ///
+  /// \param SourceFile the source file which will be overridden.
+  ///
+  /// \param NewFile the file whose contents will be used as the
+  /// data instead of the contents of the given source file.
+  void overrideFileContents(const FileEntry *SourceFile,
+                            const FileEntry *NewFile);
+
+  /// \brief Returns true if the file contents have been overridden.
+  bool isFileOverridden(const FileEntry *File) {
+    if (OverriddenFilesInfo) {
+      if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File))
+        return true;
+      if (OverriddenFilesInfo->OverriddenFiles.find(File) !=
+          OverriddenFilesInfo->OverriddenFiles.end())
+        return true;
+    }
+    return false;
+  }
+
+  /// \brief Disable overridding the contents of a file, previously enabled
+  /// with #overrideFileContents.
+  ///
+  /// This should be called before parsing has begun.
+  void disableFileContentsOverride(const FileEntry *File);
+
+  //===--------------------------------------------------------------------===//
+  // FileID manipulation methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the buffer for the specified FileID.
+  ///
+  /// If there is an error opening this buffer the first time, this
+  /// manufactures a temporary buffer and returns a non-empty error string.
+  llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                bool *Invalid = nullptr) const {
+    bool MyInvalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
+    if (MyInvalid || !Entry.isFile()) {
+      if (Invalid)
+        *Invalid = true;
+
+      return getFakeBufferForRecovery();
+    }
+
+    return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc,
+                                                        Invalid);
+  }
+
+  llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
+    bool MyInvalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
+    if (MyInvalid || !Entry.isFile()) {
+      if (Invalid)
+        *Invalid = true;
+
+      return getFakeBufferForRecovery();
+    }
+
+    return Entry.getFile().getContentCache()->getBuffer(Diag, *this,
+                                                        SourceLocation(),
+                                                        Invalid);
+  }
+
+  /// \brief Returns the FileEntry record for the provided FileID.
+  const FileEntry *getFileEntryForID(FileID FID) const {
+    bool MyInvalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
+    if (MyInvalid || !Entry.isFile())
+      return nullptr;
+
+    const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
+    if (!Content)
+      return nullptr;
+    return Content->OrigEntry;
+  }
+
+  /// \brief Returns the FileEntry record for the provided SLocEntry.
+  const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
+  {
+    const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
+    if (!Content)
+      return nullptr;
+    return Content->OrigEntry;
+  }
+
+  /// \brief Return a StringRef to the source buffer data for the
+  /// specified FileID.
+  ///
+  /// \param FID The file ID whose contents will be returned.
+  /// \param Invalid If non-NULL, will be set true if an error occurred.
+  StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
+
+  /// \brief Get the number of FileIDs (files and macros) that were created
+  /// during preprocessing of \p FID, including it.
+  unsigned getNumCreatedFIDsForFileID(FileID FID) const {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+    if (Invalid || !Entry.isFile())
+      return 0;
+
+    return Entry.getFile().NumCreatedFIDs;
+  }
+
+  /// \brief Set the number of FileIDs (files and macros) that were created
+  /// during preprocessing of \p FID, including it.
+  void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+    if (Invalid || !Entry.isFile())
+      return;
+
+    assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!");
+    const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // SourceLocation manipulation methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the FileID for a SourceLocation.
+  ///
+  /// This is a very hot method that is used for all SourceManager queries
+  /// that start with a SourceLocation object.  It is responsible for finding
+  /// the entry in SLocEntryTable which contains the specified location.
+  ///
+  FileID getFileID(SourceLocation SpellingLoc) const {
+    unsigned SLocOffset = SpellingLoc.getOffset();
+
+    // If our one-entry cache covers this offset, just return it.
+    if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
+      return LastFileIDLookup;
+
+    return getFileIDSlow(SLocOffset);
+  }
+
+  /// \brief Return the filename of the file containing a SourceLocation.
+  StringRef getFilename(SourceLocation SpellingLoc) const {
+    if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
+      return F->getName();
+    return StringRef();
+  }
+
+  /// \brief Return the source location corresponding to the first byte of
+  /// the specified file.
+  SourceLocation getLocForStartOfFile(FileID FID) const {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+    if (Invalid || !Entry.isFile())
+      return SourceLocation();
+
+    unsigned FileOffset = Entry.getOffset();
+    return SourceLocation::getFileLoc(FileOffset);
+  }
+  
+  /// \brief Return the source location corresponding to the last byte of the
+  /// specified file.
+  SourceLocation getLocForEndOfFile(FileID FID) const {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+    if (Invalid || !Entry.isFile())
+      return SourceLocation();
+    
+    unsigned FileOffset = Entry.getOffset();
+    return SourceLocation::getFileLoc(FileOffset + getFileIDSize(FID));
+  }
+
+  /// \brief Returns the include location if \p FID is a \#include'd file
+  /// otherwise it returns an invalid location.
+  SourceLocation getIncludeLoc(FileID FID) const {
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+    if (Invalid || !Entry.isFile())
+      return SourceLocation();
+
+    return Entry.getFile().getIncludeLoc();
+  }
+
+  // \brief Returns the import location if the given source location is
+  // located within a module, or an invalid location if the source location
+  // is within the current translation unit.
+  std::pair<SourceLocation, StringRef>
+  getModuleImportLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+
+    // Positive file IDs are in the current translation unit, and -1 is a
+    // placeholder.
+    if (FID.ID >= -1)
+      return std::make_pair(SourceLocation(), "");
+
+    return ExternalSLocEntries->getModuleImportLoc(FID.ID);
+  }
+
+  /// \brief Given a SourceLocation object \p Loc, return the expansion
+  /// location referenced by the ID.
+  SourceLocation getExpansionLoc(SourceLocation Loc) const {
+    // Handle the non-mapped case inline, defer to out of line code to handle
+    // expansions.
+    if (Loc.isFileID()) return Loc;
+    return getExpansionLocSlowCase(Loc);
+  }
+
+  /// \brief Given \p Loc, if it is a macro location return the expansion
+  /// location or the spelling location, depending on if it comes from a
+  /// macro argument or not.
+  SourceLocation getFileLoc(SourceLocation Loc) const {
+    if (Loc.isFileID()) return Loc;
+    return getFileLocSlowCase(Loc);
+  }
+
+  /// \brief Return the start/end of the expansion information for an
+  /// expansion location.
+  ///
+  /// \pre \p Loc is required to be an expansion location.
+  std::pair<SourceLocation,SourceLocation>
+  getImmediateExpansionRange(SourceLocation Loc) const;
+
+  /// \brief Given a SourceLocation object, return the range of
+  /// tokens covered by the expansion the ultimate file.
+  std::pair<SourceLocation,SourceLocation>
+  getExpansionRange(SourceLocation Loc) const;
+
+
+  /// \brief Given a SourceLocation object, return the spelling
+  /// location referenced by the ID.
+  ///
+  /// This is the place where the characters that make up the lexed token
+  /// can be found.
+  SourceLocation getSpellingLoc(SourceLocation Loc) const {
+    // Handle the non-mapped case inline, defer to out of line code to handle
+    // expansions.
+    if (Loc.isFileID()) return Loc;
+    return getSpellingLocSlowCase(Loc);
+  }
+
+  /// \brief Given a SourceLocation object, return the spelling location
+  /// referenced by the ID.
+  ///
+  /// This is the first level down towards the place where the characters
+  /// that make up the lexed token can be found.  This should not generally
+  /// be used by clients.
+  SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
+
+  /// \brief Decompose the specified location into a raw FileID + Offset pair.
+  ///
+  /// The first element is the FileID, the second is the offset from the
+  /// start of the buffer of the location.
+  std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    bool Invalid = false;
+    const SrcMgr::SLocEntry &E = getSLocEntry(FID, &Invalid);
+    if (Invalid)
+      return std::make_pair(FileID(), 0);
+    return std::make_pair(FID, Loc.getOffset()-E.getOffset());
+  }
+
+  /// \brief Decompose the specified location into a raw FileID + Offset pair.
+  ///
+  /// If the location is an expansion record, walk through it until we find
+  /// the final location expanded.
+  std::pair<FileID, unsigned>
+  getDecomposedExpansionLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    bool Invalid = false;
+    const SrcMgr::SLocEntry *E = &getSLocEntry(FID, &Invalid);
+    if (Invalid)
+      return std::make_pair(FileID(), 0);
+
+    unsigned Offset = Loc.getOffset()-E->getOffset();
+    if (Loc.isFileID())
+      return std::make_pair(FID, Offset);
+
+    return getDecomposedExpansionLocSlowCase(E);
+  }
+
+  /// \brief Decompose the specified location into a raw FileID + Offset pair.
+  ///
+  /// If the location is an expansion record, walk through it until we find
+  /// its spelling record.
+  std::pair<FileID, unsigned>
+  getDecomposedSpellingLoc(SourceLocation Loc) const {
+    FileID FID = getFileID(Loc);
+    bool Invalid = false;
+    const SrcMgr::SLocEntry *E = &getSLocEntry(FID, &Invalid);
+    if (Invalid)
+      return std::make_pair(FileID(), 0);
+
+    unsigned Offset = Loc.getOffset()-E->getOffset();
+    if (Loc.isFileID())
+      return std::make_pair(FID, Offset);
+    return getDecomposedSpellingLocSlowCase(E, Offset);
+  }
+
+  /// \brief Returns the "included/expanded in" decomposed location of the given
+  /// FileID.
+  std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const;
+
+  /// \brief Returns the offset from the start of the file that the
+  /// specified SourceLocation represents.
+  ///
+  /// This is not very meaningful for a macro ID.
+  unsigned getFileOffset(SourceLocation SpellingLoc) const {
+    return getDecomposedLoc(SpellingLoc).second;
+  }
+
+  /// \brief Tests whether the given source location represents a macro
+  /// argument's expansion into the function-like macro definition.
+  ///
+  /// Such source locations only appear inside of the expansion
+  /// locations representing where a particular function-like macro was
+  /// expanded.
+  bool isMacroArgExpansion(SourceLocation Loc) const;
+
+  /// \brief Tests whether the given source location represents the expansion of
+  /// a macro body.
+  ///
+  /// This is equivalent to testing whether the location is part of a macro
+  /// expansion but not the expansion of an argument to a function-like macro.
+  bool isMacroBodyExpansion(SourceLocation Loc) const;
+
+  /// \brief Returns true if the given MacroID location points at the beginning
+  /// of the immediate macro expansion.
+  ///
+  /// \param MacroBegin If non-null and function returns true, it is set to the
+  /// begin location of the immediate macro expansion.
+  bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
+                                    SourceLocation *MacroBegin = nullptr) const;
+
+  /// \brief Returns true if the given MacroID location points at the character
+  /// end of the immediate macro expansion.
+  ///
+  /// \param MacroEnd If non-null and function returns true, it is set to the
+  /// character end location of the immediate macro expansion.
+  bool
+  isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
+                                   SourceLocation *MacroEnd = nullptr) const;
+
+  /// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
+  /// chunk of the source location address space.
+  ///
+  /// If it's true and \p RelativeOffset is non-null, it will be set to the
+  /// relative offset of \p Loc inside the chunk.
+  bool isInSLocAddrSpace(SourceLocation Loc,
+                         SourceLocation Start, unsigned Length,
+                         unsigned *RelativeOffset = nullptr) const {
+    assert(((Start.getOffset() < NextLocalOffset &&
+               Start.getOffset()+Length <= NextLocalOffset) ||
+            (Start.getOffset() >= CurrentLoadedOffset &&
+                Start.getOffset()+Length < MaxLoadedOffset)) &&
+           "Chunk is not valid SLoc address space");
+    unsigned LocOffs = Loc.getOffset();
+    unsigned BeginOffs = Start.getOffset();
+    unsigned EndOffs = BeginOffs + Length;
+    if (LocOffs >= BeginOffs && LocOffs < EndOffs) {
+      if (RelativeOffset)
+        *RelativeOffset = LocOffs - BeginOffs;
+      return true;
+    }
+
+    return false;
+  }
+
+  /// \brief Return true if both \p LHS and \p RHS are in the local source
+  /// location address space or the loaded one.
+  ///
+  /// If it's true and \p RelativeOffset is non-null, it will be set to the
+  /// offset of \p RHS relative to \p LHS.
+  bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS,
+                             int *RelativeOffset) const {
+    unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset();
+    bool LHSLoaded = LHSOffs >= CurrentLoadedOffset;
+    bool RHSLoaded = RHSOffs >= CurrentLoadedOffset;
+
+    if (LHSLoaded == RHSLoaded) {
+      if (RelativeOffset)
+        *RelativeOffset = RHSOffs - LHSOffs;
+      return true;
+    }
+
+    return false;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Queries about the code at a SourceLocation.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return a pointer to the start of the specified location
+  /// in the appropriate spelling MemoryBuffer.
+  ///
+  /// \param Invalid If non-NULL, will be set \c true if an error occurs.
+  const char *getCharacterData(SourceLocation SL,
+                               bool *Invalid = nullptr) const;
+
+  /// \brief Return the column # for the specified file position.
+  ///
+  /// This is significantly cheaper to compute than the line number.  This
+  /// returns zero if the column number isn't known.  This may only be called
+  /// on a file sloc, so you must choose a spelling or expansion location
+  /// before calling this method.
+  unsigned getColumnNumber(FileID FID, unsigned FilePos,
+                           bool *Invalid = nullptr) const;
+  unsigned getSpellingColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
+  unsigned getExpansionColumnNumber(SourceLocation Loc,
+                                    bool *Invalid = nullptr) const;
+  unsigned getPresumedColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
+
+  /// \brief Given a SourceLocation, return the spelling line number
+  /// for the position indicated.
+  ///
+  /// This requires building and caching a table of line offsets for the
+  /// MemoryBuffer, so this is not cheap: use only when about to emit a
+  /// diagnostic.
+  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const;
+  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+
+  /// \brief Return the filename or buffer identifier of the buffer the
+  /// location is in.
+  ///
+  /// Note that this name does not respect \#line directives.  Use
+  /// getPresumedLoc for normal clients.
+  const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
+
+  /// \brief Return the file characteristic of the specified source
+  /// location, indicating whether this is a normal file, a system
+  /// header, or an "implicit extern C" system header.
+  ///
+  /// This state can be modified with flags on GNU linemarker directives like:
+  /// \code
+  ///   # 4 "foo.h" 3
+  /// \endcode
+  /// which changes all source locations in the current file after that to be
+  /// considered to be from a system header.
+  SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
+
+  /// \brief Returns the "presumed" location of a SourceLocation specifies.
+  ///
+  /// A "presumed location" can be modified by \#line or GNU line marker
+  /// directives.  This provides a view on the data that a user should see
+  /// in diagnostics, for example.
+  ///
+  /// Note that a presumed location is always given as the expansion point of
+  /// an expansion location, not at the spelling location.
+  ///
+  /// \returns The presumed location of the specified SourceLocation. If the
+  /// presumed location cannot be calculated (e.g., because \p Loc is invalid
+  /// or the file containing \p Loc has changed on disk), returns an invalid
+  /// presumed location.
+  PresumedLoc getPresumedLoc(SourceLocation Loc,
+                             bool UseLineDirectives = true) const;
+
+  /// \brief Returns whether the PresumedLoc for a given SourceLocation is 
+  /// in the main file.
+  ///
+  /// This computes the "presumed" location for a SourceLocation, then checks
+  /// whether it came from a file other than the main file. This is different
+  /// from isWrittenInMainFile() because it takes line marker directives into
+  /// account.
+  bool isInMainFile(SourceLocation Loc) const;
+
+  /// \brief Returns true if the spelling locations for both SourceLocations
+  /// are part of the same file buffer.
+  ///
+  /// This check ignores line marker directives.
+  bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
+    return getFileID(Loc1) == getFileID(Loc2);
+  }
+
+  /// \brief Returns true if the spelling location for the given location
+  /// is in the main file buffer.
+  ///
+  /// This check ignores line marker directives.
+  bool isWrittenInMainFile(SourceLocation Loc) const {
+    return getFileID(Loc) == getMainFileID();
+  }
+
+  /// \brief Returns if a SourceLocation is in a system header.
+  bool isInSystemHeader(SourceLocation Loc) const {
+    return getFileCharacteristic(Loc) != SrcMgr::C_User;
+  }
+
+  /// \brief Returns if a SourceLocation is in an "extern C" system header.
+  bool isInExternCSystemHeader(SourceLocation Loc) const {
+    return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
+  }
+
+  /// \brief Returns whether \p Loc is expanded from a macro in a system header.
+  bool isInSystemMacro(SourceLocation loc) {
+    return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
+  }
+
+  /// \brief The size of the SLocEntry that \p FID represents.
+  unsigned getFileIDSize(FileID FID) const;
+
+  /// \brief Given a specific FileID, returns true if \p Loc is inside that
+  /// FileID chunk and sets relative offset (offset of \p Loc from beginning
+  /// of FileID) to \p relativeOffset.
+  bool isInFileID(SourceLocation Loc, FileID FID,
+                  unsigned *RelativeOffset = nullptr) const {
+    unsigned Offs = Loc.getOffset();
+    if (isOffsetInFileID(FID, Offs)) {
+      if (RelativeOffset)
+        *RelativeOffset = Offs - getSLocEntry(FID).getOffset();
+      return true;
+    }
+
+    return false;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Line Table Manipulation Routines
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the uniqued ID for the specified filename.
+  ///
+  unsigned getLineTableFilenameID(StringRef Str);
+
+  /// \brief Add a line note to the line table for the FileID and offset
+  /// specified by Loc.
+  ///
+  /// If FilenameID is -1, it is considered to be unspecified.
+  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
+  void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
+                   bool IsFileEntry, bool IsFileExit,
+                   bool IsSystemHeader, bool IsExternCHeader);
+
+  /// \brief Determine if the source manager has a line table.
+  bool hasLineTable() const { return LineTable != nullptr; }
+
+  /// \brief Retrieve the stored line table.
+  LineTableInfo &getLineTable();
+
+  //===--------------------------------------------------------------------===//
+  // Queries for performance analysis.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return the total amount of physical memory allocated by the
+  /// ContentCache allocator.
+  size_t getContentCacheSize() const {
+    return ContentCacheAlloc.getTotalMemory();
+  }
+
+  struct MemoryBufferSizes {
+    const size_t malloc_bytes;
+    const size_t mmap_bytes;
+
+    MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
+      : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
+  };
+
+  /// \brief Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  MemoryBufferSizes getMemoryBufferSizes() const;
+
+  /// \brief Return the amount of memory used for various side tables and
+  /// data structures in the SourceManager.
+  size_t getDataStructureSizes() const;
+
+  //===--------------------------------------------------------------------===//
+  // Other miscellaneous methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Get the source location for the given file:line:col triplet.
+  ///
+  /// If the source file is included multiple times, the source location will
+  /// be based upon the first inclusion.
+  SourceLocation translateFileLineCol(const FileEntry *SourceFile,
+                                      unsigned Line, unsigned Col) const;
+
+  /// \brief Get the FileID for the given file.
+  ///
+  /// If the source file is included multiple times, the FileID will be the
+  /// first inclusion.
+  FileID translateFile(const FileEntry *SourceFile) const;
+
+  /// \brief Get the source location in \p FID for the given line:col.
+  /// Returns null location if \p FID is not a file SLocEntry.
+  SourceLocation translateLineCol(FileID FID,
+                                  unsigned Line, unsigned Col) const;
+
+  /// \brief If \p Loc points inside a function macro argument, the returned
+  /// location will be the macro location in which the argument was expanded.
+  /// If a macro argument is used multiple times, the expanded location will
+  /// be at the first expansion of the argument.
+  /// e.g.
+  ///   MY_MACRO(foo);
+  ///             ^
+  /// Passing a file location pointing at 'foo', will yield a macro location
+  /// where 'foo' was expanded into.
+  SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const;
+
+  /// \brief Determines the order of 2 source locations in the translation unit.
+  ///
+  /// \returns true if LHS source location comes before RHS, false otherwise.
+  bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
+
+  /// \brief Determines the order of 2 source locations in the "source location
+  /// address space".
+  bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {
+    return isBeforeInSLocAddrSpace(LHS, RHS.getOffset());
+  }
+
+  /// \brief Determines the order of a source location and a source location
+  /// offset in the "source location address space".
+  ///
+  /// Note that we always consider source locations loaded from
+  bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const {
+    unsigned LHSOffset = LHS.getOffset();
+    bool LHSLoaded = LHSOffset >= CurrentLoadedOffset;
+    bool RHSLoaded = RHS >= CurrentLoadedOffset;
+    if (LHSLoaded == RHSLoaded)
+      return LHSOffset < RHS;
+
+    return LHSLoaded;
+  }
+
+  // Iterators over FileInfos.
+  typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
+      ::const_iterator fileinfo_iterator;
+  fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
+  fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
+  bool hasFileInfo(const FileEntry *File) const {
+    return FileInfos.find(File) != FileInfos.end();
+  }
+
+  /// \brief Print statistics to stderr.
+  ///
+  void PrintStats() const;
+
+  /// \brief Get the number of local SLocEntries we have.
+  unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); }
+
+  /// \brief Get a local SLocEntry. This is exposed for indexing.
+  const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
+                                             bool *Invalid = nullptr) const {
+    assert(Index < LocalSLocEntryTable.size() && "Invalid index");
+    return LocalSLocEntryTable[Index];
+  }
+
+  /// \brief Get the number of loaded SLocEntries we have.
+  unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
+
+  /// \brief Get a loaded SLocEntry. This is exposed for indexing.
+  const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
+                                              bool *Invalid = nullptr) const {
+    assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
+    if (SLocEntryLoaded[Index])
+      return LoadedSLocEntryTable[Index];
+    return loadSLocEntry(Index, Invalid);
+  }
+
+  const SrcMgr::SLocEntry &getSLocEntry(FileID FID,
+                                        bool *Invalid = nullptr) const {
+    if (FID.ID == 0 || FID.ID == -1) {
+      if (Invalid) *Invalid = true;
+      return LocalSLocEntryTable[0];
+    }
+    return getSLocEntryByID(FID.ID, Invalid);
+  }
+
+  unsigned getNextLocalOffset() const { return NextLocalOffset; }
+
+  void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
+    assert(LoadedSLocEntryTable.empty() &&
+           "Invalidating existing loaded entries");
+    ExternalSLocEntries = Source;
+  }
+
+  /// \brief Allocate a number of loaded SLocEntries, which will be actually
+  /// loaded on demand from the external source.
+  ///
+  /// NumSLocEntries will be allocated, which occupy a total of TotalSize space
+  /// in the global source view. The lowest ID and the base offset of the
+  /// entries will be returned.
+  std::pair<int, unsigned>
+  AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize);
+
+  /// \brief Returns true if \p Loc came from a PCH/Module.
+  bool isLoadedSourceLocation(SourceLocation Loc) const {
+    return Loc.getOffset() >= CurrentLoadedOffset;
+  }
+
+  /// \brief Returns true if \p Loc did not come from a PCH/Module.
+  bool isLocalSourceLocation(SourceLocation Loc) const {
+    return Loc.getOffset() < NextLocalOffset;
+  }
+
+  /// \brief Returns true if \p FID came from a PCH/Module.
+  bool isLoadedFileID(FileID FID) const {
+    assert(FID.ID != -1 && "Using FileID sentinel value");
+    return FID.ID < 0;
+  }
+
+  /// \brief Returns true if \p FID did not come from a PCH/Module.
+  bool isLocalFileID(FileID FID) const {
+    return !isLoadedFileID(FID);
+  }
+
+  /// Gets the location of the immediate macro caller, one level up the stack
+  /// toward the initial macro typed into the source.
+  SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const {
+    if (!Loc.isMacroID()) return Loc;
+
+    // When we have the location of (part of) an expanded parameter, its
+    // spelling location points to the argument as expanded in the macro call,
+    // and therefore is used to locate the macro caller.
+    if (isMacroArgExpansion(Loc))
+      return getImmediateSpellingLoc(Loc);
+
+    // Otherwise, the caller of the macro is located where this macro is
+    // expanded (while the spelling is part of the macro definition).
+    return getImmediateExpansionRange(Loc).first;
+  }
+
+private:
+  llvm::MemoryBuffer *getFakeBufferForRecovery() const;
+  const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
+
+  const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
+
+  /// \brief Get the entry with the given unwrapped FileID.
+  const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
+                                            bool *Invalid = nullptr) const {
+    assert(ID != -1 && "Using FileID sentinel value");
+    if (ID < 0)
+      return getLoadedSLocEntryByID(ID, Invalid);
+    return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
+  }
+
+  const SrcMgr::SLocEntry &
+  getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const {
+    return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
+  }
+
+  /// Implements the common elements of storing an expansion info struct into
+  /// the SLocEntry table and producing a source location that refers to it.
+  SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion,
+                                        unsigned TokLength,
+                                        int LoadedID = 0,
+                                        unsigned LoadedOffset = 0);
+
+  /// \brief Return true if the specified FileID contains the
+  /// specified SourceLocation offset.  This is a very hot method.
+  inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
+    const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
+    // If the entry is after the offset, it can't contain it.
+    if (SLocOffset < Entry.getOffset()) return false;
+
+    // If this is the very last entry then it does.
+    if (FID.ID == -2)
+      return true;
+
+    // If it is the last local entry, then it does if the location is local.
+    if (FID.ID+1 == static_cast<int>(LocalSLocEntryTable.size()))
+      return SLocOffset < NextLocalOffset;
+
+    // Otherwise, the entry after it has to not include it. This works for both
+    // local and loaded entries.
+    return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset();
+  }
+
+  /// \brief Returns the previous in-order FileID or an invalid FileID if there
+  /// is no previous one.
+  FileID getPreviousFileID(FileID FID) const;
+
+  /// \brief Returns the next in-order FileID or an invalid FileID if there is
+  /// no next one.
+  FileID getNextFileID(FileID FID) const;
+
+  /// \brief Create a new fileID for the specified ContentCache and
+  /// include position.
+  ///
+  /// This works regardless of whether the ContentCache corresponds to a
+  /// file or some other input source.
+  FileID createFileID(const SrcMgr::ContentCache* File,
+                      SourceLocation IncludePos,
+                      SrcMgr::CharacteristicKind DirCharacter,
+                      int LoadedID, unsigned LoadedOffset);
+
+  const SrcMgr::ContentCache *
+    getOrCreateContentCache(const FileEntry *SourceFile,
+                            bool isSystemFile = false);
+
+  /// \brief Create a new ContentCache for the specified  memory buffer.
+  const SrcMgr::ContentCache *
+  createMemBufferContentCache(llvm::MemoryBuffer *Buf);
+
+  FileID getFileIDSlow(unsigned SLocOffset) const;
+  FileID getFileIDLocal(unsigned SLocOffset) const;
+  FileID getFileIDLoaded(unsigned SLocOffset) const;
+
+  SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const;
+  SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
+  SourceLocation getFileLocSlowCase(SourceLocation Loc) const;
+
+  std::pair<FileID, unsigned>
+  getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const;
+  std::pair<FileID, unsigned>
+  getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
+                                   unsigned Offset) const;
+  void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const;
+  void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache,
+                                         FileID FID,
+                                         SourceLocation SpellLoc,
+                                         SourceLocation ExpansionLoc,
+                                         unsigned ExpansionLength) const;
+  friend class ASTReader;
+  friend class ASTWriter;
+};
+
+/// \brief Comparison function object.
+template<typename T>
+class BeforeThanCompare;
+
+/// \brief Compare two source locations.
+template<>
+class BeforeThanCompare<SourceLocation> {
+  SourceManager &SM;
+
+public:
+  explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
+
+  bool operator()(SourceLocation LHS, SourceLocation RHS) const {
+    return SM.isBeforeInTranslationUnit(LHS, RHS);
+  }
+};
+
+/// \brief Compare two non-overlapping source ranges.
+template<>
+class BeforeThanCompare<SourceRange> {
+  SourceManager &SM;
+
+public:
+  explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { }
+
+  bool operator()(SourceRange LHS, SourceRange RHS) {
+    return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin());
+  }
+};
+
+}  // end namespace clang
+
+
+#endif
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
new file mode 100644
index 0000000..af95b78
--- /dev/null
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -0,0 +1,133 @@
+//===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines implementation details of the clang::SourceManager class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+#define LLVM_CLANG_SOURCEMANAGER_INTERNALS_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringMap.h"
+#include <map>
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// Line Table Implementation
+//===----------------------------------------------------------------------===//
+
+struct LineEntry {
+  /// \brief The offset in this file that the line entry occurs at.
+  unsigned FileOffset;
+
+  /// \brief The presumed line number of this line entry: \#line 4.
+  unsigned LineNo;
+
+  /// \brief The ID of the filename identified by this line entry:
+  /// \#line 4 "foo.c".  This is -1 if not specified.
+  int FilenameID;
+
+  /// \brief Set the 0 if no flags, 1 if a system header,
+  SrcMgr::CharacteristicKind FileKind;
+
+  /// \brief The offset of the virtual include stack location,
+  /// which is manipulated by GNU linemarker directives.
+  ///
+  /// If this is 0 then there is no virtual \#includer.
+  unsigned IncludeOffset;
+
+  static LineEntry get(unsigned Offs, unsigned Line, int Filename,
+                       SrcMgr::CharacteristicKind FileKind,
+                       unsigned IncludeOffset) {
+    LineEntry E;
+    E.FileOffset = Offs;
+    E.LineNo = Line;
+    E.FilenameID = Filename;
+    E.FileKind = FileKind;
+    E.IncludeOffset = IncludeOffset;
+    return E;
+  }
+};
+
+// needed for FindNearestLineEntry (upper_bound of LineEntry)
+inline bool operator<(const LineEntry &lhs, const LineEntry &rhs) {
+  // FIXME: should check the other field?
+  return lhs.FileOffset < rhs.FileOffset;
+}
+
+inline bool operator<(const LineEntry &E, unsigned Offset) {
+  return E.FileOffset < Offset;
+}
+
+inline bool operator<(unsigned Offset, const LineEntry &E) {
+  return Offset < E.FileOffset;
+}
+
+/// \brief Used to hold and unique data used to represent \#line information.
+class LineTableInfo {
+  /// \brief Map used to assign unique IDs to filenames in \#line directives. 
+  ///
+  /// This allows us to unique the filenames that
+  /// frequently reoccur and reference them with indices.  FilenameIDs holds
+  /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID
+  /// to string.
+  llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
+  std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
+
+  /// \brief Map from FileIDs to a list of line entries (sorted by the offset
+  /// at which they occur in the file).
+  std::map<FileID, std::vector<LineEntry> > LineEntries;
+public:
+  LineTableInfo() {
+  }
+
+  void clear() {
+    FilenameIDs.clear();
+    FilenamesByID.clear();
+    LineEntries.clear();
+  }
+
+  ~LineTableInfo() {}
+
+  unsigned getLineTableFilenameID(StringRef Str);
+  const char *getFilename(unsigned ID) const {
+    assert(ID < FilenamesByID.size() && "Invalid FilenameID");
+    return FilenamesByID[ID]->getKeyData();
+  }
+  unsigned getNumFilenames() const { return FilenamesByID.size(); }
+
+  void AddLineNote(FileID FID, unsigned Offset,
+                   unsigned LineNo, int FilenameID);
+  void AddLineNote(FileID FID, unsigned Offset,
+                   unsigned LineNo, int FilenameID,
+                   unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
+
+
+  /// \brief Find the line entry nearest to FID that is before it.
+  ///
+  /// If there is no line entry before \p Offset in \p FID, returns null.
+  const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset);
+
+  // Low-level access
+  typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator;
+  iterator begin() { return LineEntries.begin(); }
+  iterator end() { return LineEntries.end(); }
+
+  /// \brief Add a new line entry that has already been encoded into
+  /// the internal representation of the line table.
+  void AddEntry(FileID FID, const std::vector<LineEntry> &Entries);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
new file mode 100644
index 0000000..f895673
--- /dev/null
+++ b/include/clang/Basic/Specifiers.h
@@ -0,0 +1,238 @@
+//===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines various enumerations that describe declaration and
+/// type specifiers.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
+#define LLVM_CLANG_BASIC_SPECIFIERS_H
+
+namespace clang {
+  /// \brief Specifies the width of a type, e.g., short, long, or long long.
+  enum TypeSpecifierWidth {
+    TSW_unspecified,
+    TSW_short,
+    TSW_long,
+    TSW_longlong
+  };
+  
+  /// \brief Specifies the signedness of a type, e.g., signed or unsigned.
+  enum TypeSpecifierSign {
+    TSS_unspecified,
+    TSS_signed,
+    TSS_unsigned
+  };
+  
+  /// \brief Specifies the kind of type.
+  enum TypeSpecifierType {
+    TST_unspecified,
+    TST_void,
+    TST_char,
+    TST_wchar,        // C++ wchar_t
+    TST_char16,       // C++11 char16_t
+    TST_char32,       // C++11 char32_t
+    TST_int,
+    TST_int128,
+    TST_half,         // OpenCL half, ARM NEON __fp16
+    TST_float,
+    TST_double,
+    TST_bool,         // _Bool
+    TST_decimal32,    // _Decimal32
+    TST_decimal64,    // _Decimal64
+    TST_decimal128,   // _Decimal128
+    TST_enum,
+    TST_union,
+    TST_struct,
+    TST_class,        // C++ class type
+    TST_interface,    // C++ (Microsoft-specific) __interface type
+    TST_typename,     // Typedef, C++ class-name or enum name, etc.
+    TST_typeofType,
+    TST_typeofExpr,
+    TST_decltype,         // C++11 decltype
+    TST_underlyingType,   // __underlying_type for C++11
+    TST_auto,             // C++11 auto
+    TST_decltype_auto,    // C++1y decltype(auto)
+    TST_unknown_anytype,  // __unknown_anytype extension
+    TST_atomic,           // C11 _Atomic
+    TST_error         // erroneous type
+  };
+  
+  /// \brief Structure that packs information about the type specifiers that
+  /// were written in a particular type specifier sequence.
+  struct WrittenBuiltinSpecs {
+    /*DeclSpec::TST*/ unsigned Type  : 5;
+    /*DeclSpec::TSS*/ unsigned Sign  : 2;
+    /*DeclSpec::TSW*/ unsigned Width : 2;
+    bool ModeAttr : 1;
+  };  
+
+  /// \brief A C++ access specifier (public, private, protected), plus the
+  /// special value "none" which means different things in different contexts.
+  enum AccessSpecifier {
+    AS_public,
+    AS_protected,
+    AS_private,
+    AS_none
+  };
+
+  /// \brief The categorization of expression values, currently following the
+  /// C++11 scheme.
+  enum ExprValueKind {
+    /// \brief An r-value expression (a pr-value in the C++11 taxonomy)
+    /// produces a temporary value.
+    VK_RValue,
+
+    /// \brief An l-value expression is a reference to an object with
+    /// independent storage.
+    VK_LValue,
+
+    /// \brief An x-value expression is a reference to an object with
+    /// independent storage but which can be "moved", i.e.
+    /// efficiently cannibalized for its resources.
+    VK_XValue
+  };
+
+  /// \brief A further classification of the kind of object referenced by an
+  /// l-value or x-value.
+  enum ExprObjectKind {
+    /// An ordinary object is located at an address in memory.
+    OK_Ordinary,
+
+    /// A bitfield object is a bitfield on a C or C++ record.
+    OK_BitField,
+
+    /// A vector component is an element or range of elements on a vector.
+    OK_VectorComponent,
+
+    /// An Objective-C property is a logical field of an Objective-C
+    /// object which is read and written via Objective-C method calls.
+    OK_ObjCProperty,
+    
+    /// An Objective-C array/dictionary subscripting which reads an
+    /// object or writes at the subscripted array/dictionary element via
+    /// Objective-C method calls.
+    OK_ObjCSubscript
+  };
+
+  /// \brief Describes the kind of template specialization that a
+  /// particular template specialization declaration represents.
+  enum TemplateSpecializationKind {
+    /// This template specialization was formed from a template-id but
+    /// has not yet been declared, defined, or instantiated.
+    TSK_Undeclared = 0,
+    /// This template specialization was implicitly instantiated from a
+    /// template. (C++ [temp.inst]).
+    TSK_ImplicitInstantiation,
+    /// This template specialization was declared or defined by an
+    /// explicit specialization (C++ [temp.expl.spec]) or partial
+    /// specialization (C++ [temp.class.spec]).
+    TSK_ExplicitSpecialization,
+    /// This template specialization was instantiated from a template
+    /// due to an explicit instantiation declaration request
+    /// (C++11 [temp.explicit]).
+    TSK_ExplicitInstantiationDeclaration,
+    /// This template specialization was instantiated from a template
+    /// due to an explicit instantiation definition request
+    /// (C++ [temp.explicit]).
+    TSK_ExplicitInstantiationDefinition
+  };
+
+  /// \brief Determine whether this template specialization kind refers
+  /// to an instantiation of an entity (as opposed to a non-template or
+  /// an explicit specialization).
+  inline bool isTemplateInstantiation(TemplateSpecializationKind Kind) {
+    return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization;
+  }
+
+  /// \brief Thread storage-class-specifier.
+  enum ThreadStorageClassSpecifier {
+    TSCS_unspecified,
+    /// GNU __thread.
+    TSCS___thread,
+    /// C++11 thread_local. Implies 'static' at block scope, but not at
+    /// class scope.
+    TSCS_thread_local,
+    /// C11 _Thread_local. Must be combined with either 'static' or 'extern'
+    /// if used at block scope.
+    TSCS__Thread_local
+  };
+
+  /// \brief Storage classes.
+  enum StorageClass {
+    // These are legal on both functions and variables.
+    SC_None,
+    SC_Extern,
+    SC_Static,
+    SC_PrivateExtern,
+
+    // These are only legal on variables.
+    SC_OpenCLWorkGroupLocal,
+    SC_Auto,
+    SC_Register
+  };
+
+  /// \brief Checks whether the given storage class is legal for functions.
+  inline bool isLegalForFunction(StorageClass SC) {
+    return SC <= SC_PrivateExtern;
+  }
+
+  /// \brief Checks whether the given storage class is legal for variables.
+  inline bool isLegalForVariable(StorageClass SC) {
+    return true;
+  }
+
+  /// \brief In-class initialization styles for non-static data members.
+  enum InClassInitStyle {
+    ICIS_NoInit,   ///< No in-class initializer.
+    ICIS_CopyInit, ///< Copy initialization.
+    ICIS_ListInit  ///< Direct list-initialization.
+  };
+
+  /// \brief CallingConv - Specifies the calling convention that a function uses.
+  enum CallingConv {
+    CC_C,           // __attribute__((cdecl))
+    CC_X86StdCall,  // __attribute__((stdcall))
+    CC_X86FastCall, // __attribute__((fastcall))
+    CC_X86ThisCall, // __attribute__((thiscall))
+    CC_X86Pascal,   // __attribute__((pascal))
+    CC_X86_64Win64, // __attribute__((ms_abi))
+    CC_X86_64SysV,  // __attribute__((sysv_abi))
+    CC_AAPCS,       // __attribute__((pcs("aapcs")))
+    CC_AAPCS_VFP,   // __attribute__((pcs("aapcs-vfp")))
+    CC_PnaclCall,   // __attribute__((pnaclcall))
+    CC_IntelOclBicc // __attribute__((intel_ocl_bicc))
+  };
+
+  /// \brief Checks whether the given calling convention is callee-cleanup.
+  inline bool isCalleeCleanup(CallingConv CC) {
+    switch (CC) {
+    case CC_X86StdCall:
+    case CC_X86FastCall:
+    case CC_X86ThisCall:
+    case CC_X86Pascal:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  /// \brief The storage duration for an object (per C++ [basic.stc]).
+  enum StorageDuration {
+    SD_FullExpression, ///< Full-expression storage duration (for temporaries).
+    SD_Automatic,      ///< Automatic storage duration (most local variables).
+    SD_Thread,         ///< Thread storage duration.
+    SD_Static,         ///< Static storage duration.
+    SD_Dynamic         ///< Dynamic storage duration.
+  };
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_SPECIFIERS_H
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
new file mode 100644
index 0000000..b1652be
--- /dev/null
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -0,0 +1,169 @@
+//===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Enumerates target-specific builtins in their own namespaces within
+/// namespace ::clang.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+#define LLVM_CLANG_BASIC_TARGET_BUILTINS_H
+
+#include "clang/Basic/Builtins.h"
+#undef PPC
+
+namespace clang {
+
+  namespace NEON {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsNEON.def"
+    FirstTSBuiltin
+  };
+  }
+
+  /// \brief ARM builtins
+  namespace ARM {
+    enum {
+      LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+      LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsARM.def"
+      LastTSBuiltin
+    };
+  }
+
+  /// \brief AArch64 builtins
+  namespace AArch64 {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+    LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
+  #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+  #include "clang/Basic/BuiltinsAArch64.def"
+    LastTSBuiltin
+  };
+  }
+
+  /// \brief PPC builtins
+  namespace PPC {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsPPC.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// \brief NVPTX builtins
+  namespace NVPTX {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsNVPTX.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// \brief R600 builtins
+  namespace R600 {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+  #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+  #include "clang/Basic/BuiltinsR600.def"
+    LastTSBuiltin
+  };
+  }
+
+  /// \brief X86 builtins
+  namespace X86 {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsX86.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// \brief Flags to identify the types for overloaded Neon builtins.
+  ///
+  /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
+  class NeonTypeFlags {
+    enum {
+      EltTypeMask = 0xf,
+      UnsignedFlag = 0x10,
+      QuadFlag = 0x20
+    };
+    uint32_t Flags;
+
+  public:
+    enum EltType {
+      Int8,
+      Int16,
+      Int32,
+      Int64,
+      Poly8,
+      Poly16,
+      Poly64,
+      Poly128,
+      Float16,
+      Float32,
+      Float64
+    };
+
+    NeonTypeFlags(unsigned F) : Flags(F) {}
+    NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
+      if (IsUnsigned)
+        Flags |= UnsignedFlag;
+      if (IsQuad)
+        Flags |= QuadFlag;
+    }
+
+    EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
+    bool isPoly() const {
+      EltType ET = getEltType();
+      return ET == Poly8 || ET == Poly16;
+    }
+    bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
+    bool isQuad() const { return (Flags & QuadFlag) != 0; }
+  };
+
+  /// \brief Hexagon builtins
+  namespace Hexagon {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsHexagon.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// \brief MIPS builtins
+  namespace Mips {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsMips.def"
+        LastTSBuiltin
+    };
+  }
+
+  /// \brief XCore builtins
+  namespace XCore {
+    enum {
+        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsXCore.def"
+        LastTSBuiltin
+    };
+  }
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
new file mode 100644
index 0000000..f9e37c3
--- /dev/null
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -0,0 +1,289 @@
+//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the TargetCXXABI class, which abstracts details of the
+/// C++ ABI that we're targeting.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TARGETCXXABI_H
+#define LLVM_CLANG_TARGETCXXABI_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+/// \brief The basic abstraction for the target C++ ABI.
+class TargetCXXABI {
+public:
+  /// \brief The basic C++ ABI kind.
+  enum Kind {
+    /// The generic Itanium ABI is the standard ABI of most open-source
+    /// and Unix-like platforms.  It is the primary ABI targeted by
+    /// many compilers, including Clang and GCC.
+    ///
+    /// It is documented here:
+    ///   http://www.codesourcery.com/public/cxx-abi/
+    GenericItanium,
+
+    /// The generic ARM ABI is a modified version of the Itanium ABI
+    /// proposed by ARM for use on ARM-based platforms.
+    ///
+    /// These changes include:
+    ///   - the representation of member function pointers is adjusted
+    ///     to not conflict with the 'thumb' bit of ARM function pointers;
+    ///   - constructors and destructors return 'this';
+    ///   - guard variables are smaller;
+    ///   - inline functions are never key functions;
+    ///   - array cookies have a slightly different layout;
+    ///   - additional convenience functions are specified;
+    ///   - and more!
+    ///
+    /// It is documented here:
+    ///    http://infocenter.arm.com
+    ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
+    GenericARM,
+
+    /// The iOS ABI is a partial implementation of the ARM ABI.
+    /// Several of the features of the ARM ABI were not fully implemented
+    /// in the compilers that iOS was launched with.
+    ///
+    /// Essentially, the iOS ABI includes the ARM changes to:
+    ///   - member function pointers,
+    ///   - guard variables,
+    ///   - array cookies, and
+    ///   - constructor/destructor signatures.
+    iOS,
+
+    /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
+    /// closely, but we don't guarantee to follow it perfectly.
+    ///
+    /// It is documented here:
+    ///    http://infocenter.arm.com
+    ///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
+    iOS64,
+
+    /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
+    /// but it has fewer divergences than the 32-bit ARM ABI.
+    ///
+    /// The relevant changes from the generic ABI in this case are:
+    ///   - representation of member function pointers adjusted as in ARM.
+    ///   - guard variables  are smaller.
+    GenericAArch64,
+
+    /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
+    /// compatible compilers).
+    ///
+    /// FIXME: should this be split into Win32 and Win64 variants?
+    ///
+    /// Only scattered and incomplete official documentation exists.
+    Microsoft
+  };
+
+private:
+  // Right now, this class is passed around as a cheap value type.
+  // If you add more members, especially non-POD members, please
+  // audit the users to pass it by reference instead.
+  Kind TheKind;
+
+public:
+  /// A bogus initialization of the platform ABI.
+  TargetCXXABI() : TheKind(GenericItanium) {}
+
+  TargetCXXABI(Kind kind) : TheKind(kind) {}
+
+  void set(Kind kind) {
+    TheKind = kind;
+  }
+
+  Kind getKind() const { return TheKind; }
+
+  /// \brief Does this ABI generally fall into the Itanium family of ABIs?
+  bool isItaniumFamily() const {
+    switch (getKind()) {
+    case GenericAArch64:
+    case GenericItanium:
+    case GenericARM:
+    case iOS:
+    case iOS64:
+      return true;
+
+    case Microsoft:
+      return false;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// \brief Is this ABI an MSVC-compatible ABI?
+  bool isMicrosoft() const {
+    switch (getKind()) {
+    case GenericAArch64:
+    case GenericItanium:
+    case GenericARM:
+    case iOS:
+    case iOS64:
+      return false;
+
+    case Microsoft:
+      return true;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// \brief Is the default C++ member function calling convention
+  /// the same as the default calling convention?
+  bool isMemberFunctionCCDefault() const {
+    // Right now, this is always false for Microsoft.
+    return !isMicrosoft();
+  }
+
+  /// Are arguments to a call destroyed left to right in the callee?
+  /// This is a fundamental language change, since it implies that objects
+  /// passed by value do *not* live to the end of the full expression.
+  /// Temporaries passed to a function taking a const reference live to the end
+  /// of the full expression as usual.  Both the caller and the callee must
+  /// have access to the destructor, while only the caller needs the
+  /// destructor if this is false.
+  bool areArgsDestroyedLeftToRightInCallee() const {
+    return isMicrosoft();
+  }
+
+  /// \brief Does this ABI have different entrypoints for complete-object
+  /// and base-subobject constructors?
+  bool hasConstructorVariants() const {
+    return isItaniumFamily();
+  }
+
+  /// \brief Does this ABI allow virtual bases to be primary base classes?
+  bool hasPrimaryVBases() const {
+    return isItaniumFamily();
+  }
+
+  /// \brief Does this ABI use key functions?  If so, class data such as the
+  /// vtable is emitted with strong linkage by the TU containing the key
+  /// function.
+  bool hasKeyFunctions() const {
+    return isItaniumFamily();
+  }
+
+  /// \brief Can an out-of-line inline function serve as a key function?
+  ///
+  /// This flag is only useful in ABIs where type data (for example,
+  /// v-tables and type_info objects) are emitted only after processing
+  /// the definition of a special "key" virtual function.  (This is safe
+  /// because the ODR requires that every virtual function be defined
+  /// somewhere in a program.)  This usually permits such data to be
+  /// emitted in only a single object file, as opposed to redundantly
+  /// in every object file that requires it.
+  ///
+  /// One simple and common definition of "key function" is the first
+  /// virtual function in the class definition which is not defined there.
+  /// This rule works very well when that function has a non-inline
+  /// definition in some non-header file.  Unfortunately, when that
+  /// function is defined inline, this rule requires the type data
+  /// to be emitted weakly, as if there were no key function.
+  ///
+  /// The ARM ABI observes that the ODR provides an additional guarantee:
+  /// a virtual function is always ODR-used, so if it is defined inline,
+  /// that definition must appear in every translation unit that defines
+  /// the class.  Therefore, there is no reason to allow such functions
+  /// to serve as key functions.
+  ///
+  /// Because this changes the rules for emitting type data,
+  /// it can cause type data to be emitted with both weak and strong
+  /// linkage, which is not allowed on all platforms.  Therefore,
+  /// exploiting this observation requires an ABI break and cannot be
+  /// done on a generic Itanium platform.
+  bool canKeyFunctionBeInline() const {
+    switch (getKind()) {
+    case GenericARM:
+    case iOS64:
+      return false;
+
+    case GenericAArch64:
+    case GenericItanium:
+    case iOS:   // old iOS compilers did not follow this rule
+    case Microsoft:
+      return true;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// When is record layout allowed to allocate objects in the tail
+  /// padding of a base class?
+  ///
+  /// This decision cannot be changed without breaking platform ABI
+  /// compatibility, and yet it is tied to language guarantees which
+  /// the committee has so far seen fit to strengthen no less than
+  /// three separate times:
+  ///   - originally, there were no restrictions at all;
+  ///   - C++98 declared that objects could not be allocated in the
+  ///     tail padding of a POD type;
+  ///   - C++03 extended the definition of POD to include classes
+  ///     containing member pointers; and
+  ///   - C++11 greatly broadened the definition of POD to include
+  ///     all trivial standard-layout classes.
+  /// Each of these changes technically took several existing
+  /// platforms and made them permanently non-conformant.
+  enum TailPaddingUseRules {
+    /// The tail-padding of a base class is always theoretically
+    /// available, even if it's POD.  This is not strictly conforming
+    /// in any language mode.
+    AlwaysUseTailPadding,
+
+    /// Only allocate objects in the tail padding of a base class if
+    /// the base class is not POD according to the rules of C++ TR1.
+    /// This is non-strictly conforming in C++11 mode.
+    UseTailPaddingUnlessPOD03,
+
+    /// Only allocate objects in the tail padding of a base class if
+    /// the base class is not POD according to the rules of C++11.
+    UseTailPaddingUnlessPOD11
+  };
+  TailPaddingUseRules getTailPaddingUseRules() const {
+    switch (getKind()) {
+    // To preserve binary compatibility, the generic Itanium ABI has
+    // permanently locked the definition of POD to the rules of C++ TR1,
+    // and that trickles down to all the derived ABIs.
+    case GenericItanium:
+    case GenericAArch64:
+    case GenericARM:
+    case iOS:
+      return UseTailPaddingUnlessPOD03;
+
+    // iOS on ARM64 uses the C++11 POD rules.  It does not honor the
+    // Itanium exception about classes with over-large bitfields.
+    case iOS64:
+      return UseTailPaddingUnlessPOD11;
+
+    // MSVC always allocates fields in the tail-padding of a base class
+    // subobject, even if they're POD.
+    case Microsoft:
+      return AlwaysUseTailPadding;
+    }
+    llvm_unreachable("bad ABI kind");
+  }
+
+  /// Try to parse an ABI name, returning false on error.
+  bool tryParse(llvm::StringRef name);
+
+  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
+    return left.getKind() == right.getKind();
+  }
+
+  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
+    return !(left == right);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
new file mode 100644
index 0000000..edef7c0
--- /dev/null
+++ b/include/clang/Basic/TargetInfo.h
@@ -0,0 +1,842 @@
+//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TargetInfo interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
+#define LLVM_CLANG_BASIC_TARGETINFO_H
+
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <string>
+#include <vector>
+
+namespace llvm {
+struct fltSemantics;
+}
+
+namespace clang {
+class DiagnosticsEngine;
+class LangOptions;
+class MacroBuilder;
+class SourceLocation;
+class SourceManager;
+
+namespace Builtin { struct Info; }
+
+/// \brief Exposes information about the current target.
+///
+class TargetInfo : public RefCountedBase<TargetInfo> {
+  std::shared_ptr<TargetOptions> TargetOpts;
+  llvm::Triple Triple;
+protected:
+  // Target values set by the ctor of the actual target implementation.  Default
+  // values are specified by the TargetInfo constructor.
+  bool BigEndian;
+  bool TLSSupported;
+  bool NoAsmVariants;  // True if {|} are normal characters.
+  unsigned char PointerWidth, PointerAlign;
+  unsigned char BoolWidth, BoolAlign;
+  unsigned char IntWidth, IntAlign;
+  unsigned char HalfWidth, HalfAlign;
+  unsigned char FloatWidth, FloatAlign;
+  unsigned char DoubleWidth, DoubleAlign;
+  unsigned char LongDoubleWidth, LongDoubleAlign;
+  unsigned char LargeArrayMinWidth, LargeArrayAlign;
+  unsigned char LongWidth, LongAlign;
+  unsigned char LongLongWidth, LongLongAlign;
+  unsigned char SuitableAlign;
+  unsigned char MinGlobalAlign;
+  unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
+  unsigned short MaxVectorAlign;
+  const char *DescriptionString;
+  const char *UserLabelPrefix;
+  const char *MCountName;
+  const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
+    *LongDoubleFormat;
+  unsigned char RegParmMax, SSERegParmMax;
+  TargetCXXABI TheCXXABI;
+  const LangAS::Map *AddrSpaceMap;
+
+  mutable StringRef PlatformName;
+  mutable VersionTuple PlatformMinVersion;
+
+  unsigned HasAlignMac68kSupport : 1;
+  unsigned RealTypeUsesObjCFPRet : 3;
+  unsigned ComplexLongDoubleUsesFP2Ret : 1;
+
+  // TargetInfo Constructor.  Default initializes all fields.
+  TargetInfo(const llvm::Triple &T);
+
+public:
+  /// \brief Construct a target for the given options.
+  ///
+  /// \param Opts - The options to use to initialize the target. The target may
+  /// modify the options to canonicalize the target feature information to match
+  /// what the backend expects.
+  static TargetInfo *
+  CreateTargetInfo(DiagnosticsEngine &Diags,
+                   const std::shared_ptr<TargetOptions> &Opts);
+
+  virtual ~TargetInfo();
+
+  /// \brief Retrieve the target options.
+  TargetOptions &getTargetOpts() const { 
+    assert(TargetOpts && "Missing target options");
+    return *TargetOpts; 
+  }
+
+  ///===---- Target Data Type Query Methods -------------------------------===//
+  enum IntType {
+    NoInt = 0,
+    SignedChar,
+    UnsignedChar,
+    SignedShort,
+    UnsignedShort,
+    SignedInt,
+    UnsignedInt,
+    SignedLong,
+    UnsignedLong,
+    SignedLongLong,
+    UnsignedLongLong
+  };
+
+  enum RealType {
+    NoFloat = 255,
+    Float = 0,
+    Double,
+    LongDouble
+  };
+
+  /// \brief The different kinds of __builtin_va_list types defined by
+  /// the target implementation.
+  enum BuiltinVaListKind {
+    /// typedef char* __builtin_va_list;
+    CharPtrBuiltinVaList = 0,
+
+    /// typedef void* __builtin_va_list;
+    VoidPtrBuiltinVaList,
+
+    /// __builtin_va_list as defind by the AArch64 ABI
+    /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
+    AArch64ABIBuiltinVaList,
+
+    /// __builtin_va_list as defined by the PNaCl ABI:
+    /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
+    PNaClABIBuiltinVaList,
+
+    /// __builtin_va_list as defined by the Power ABI:
+    /// https://www.power.org
+    ///        /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
+    PowerABIBuiltinVaList,
+
+    /// __builtin_va_list as defined by the x86-64 ABI:
+    /// http://www.x86-64.org/documentation/abi.pdf
+    X86_64ABIBuiltinVaList,
+
+    /// __builtin_va_list as defined by ARM AAPCS ABI
+    /// http://infocenter.arm.com
+    //        /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
+    AAPCSABIBuiltinVaList,
+
+    // typedef struct __va_list_tag
+    //   {
+    //     long __gpr;
+    //     long __fpr;
+    //     void *__overflow_arg_area;
+    //     void *__reg_save_area;
+    //   } va_list[1];
+    SystemZBuiltinVaList
+  };
+
+protected:
+  IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
+          WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
+          ProcessIDType;
+
+  /// \brief Whether Objective-C's built-in boolean type should be signed char.
+  ///
+  /// Otherwise, when this flag is not set, the normal built-in boolean type is
+  /// used.
+  unsigned UseSignedCharForObjCBool : 1;
+
+  /// Control whether the alignment of bit-field types is respected when laying
+  /// out structures. If true, then the alignment of the bit-field type will be
+  /// used to (a) impact the alignment of the containing structure, and (b)
+  /// ensure that the individual bit-field will not straddle an alignment
+  /// boundary.
+  unsigned UseBitFieldTypeAlignment : 1;
+
+  /// \brief Whether zero length bitfields (e.g., int : 0;) force alignment of
+  /// the next bitfield.
+  ///
+  /// If the alignment of the zero length bitfield is greater than the member
+  /// that follows it, `bar', `bar' will be aligned as the type of the
+  /// zero-length bitfield.
+  unsigned UseZeroLengthBitfieldAlignment : 1;
+
+  /// If non-zero, specifies a fixed alignment value for bitfields that follow
+  /// zero length bitfield, regardless of the zero length bitfield type.
+  unsigned ZeroLengthBitfieldBoundary;
+
+  /// \brief Specify if mangling based on address space map should be used or
+  /// not for language specific address spaces
+  bool UseAddrSpaceMapMangling;
+
+public:
+  IntType getSizeType() const { return SizeType; }
+  IntType getIntMaxType() const { return IntMaxType; }
+  IntType getUIntMaxType() const {
+    return getCorrespondingUnsignedType(IntMaxType);
+  }
+  IntType getPtrDiffType(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
+  }
+  IntType getIntPtrType() const { return IntPtrType; }
+  IntType getUIntPtrType() const {
+    return getCorrespondingUnsignedType(IntPtrType);
+  }
+  IntType getWCharType() const { return WCharType; }
+  IntType getWIntType() const { return WIntType; }
+  IntType getChar16Type() const { return Char16Type; }
+  IntType getChar32Type() const { return Char32Type; }
+  IntType getInt64Type() const { return Int64Type; }
+  IntType getUInt64Type() const {
+    return getCorrespondingUnsignedType(Int64Type);
+  }
+  IntType getSigAtomicType() const { return SigAtomicType; }
+  IntType getProcessIDType() const { return ProcessIDType; }
+
+  static IntType getCorrespondingUnsignedType(IntType T) {
+    switch (T) {
+    case SignedChar:
+      return UnsignedChar;
+    case SignedShort:
+      return UnsignedShort;
+    case SignedInt:
+      return UnsignedInt;
+    case SignedLong:
+      return UnsignedLong;
+    case SignedLongLong:
+      return UnsignedLongLong;
+    default:
+      llvm_unreachable("Unexpected signed integer type");
+    }
+  }
+
+  /// \brief Return the width (in bits) of the specified integer type enum.
+  ///
+  /// For example, SignedInt -> getIntWidth().
+  unsigned getTypeWidth(IntType T) const;
+
+  /// \brief Return integer type with specified width.
+  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
+
+  /// \brief Return the smallest integer type with at least the specified width.
+  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
+
+  /// \brief Return floating point type with specified width.
+  RealType getRealTypeByWidth(unsigned BitWidth) const;
+
+  /// \brief Return the alignment (in bits) of the specified integer type enum.
+  ///
+  /// For example, SignedInt -> getIntAlign().
+  unsigned getTypeAlign(IntType T) const;
+
+  /// \brief Returns true if the type is signed; false otherwise.
+  static bool isTypeSigned(IntType T);
+
+  /// \brief Return the width of pointers on this target, for the
+  /// specified address space.
+  uint64_t getPointerWidth(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
+  }
+  uint64_t getPointerAlign(unsigned AddrSpace) const {
+    return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
+  }
+
+  /// \brief Return the size of '_Bool' and C++ 'bool' for this target, in bits.
+  unsigned getBoolWidth() const { return BoolWidth; }
+
+  /// \brief Return the alignment of '_Bool' and C++ 'bool' for this target.
+  unsigned getBoolAlign() const { return BoolAlign; }
+
+  unsigned getCharWidth() const { return 8; } // FIXME
+  unsigned getCharAlign() const { return 8; } // FIXME
+
+  /// \brief Return the size of 'signed short' and 'unsigned short' for this
+  /// target, in bits.
+  unsigned getShortWidth() const { return 16; } // FIXME
+
+  /// \brief Return the alignment of 'signed short' and 'unsigned short' for
+  /// this target.
+  unsigned getShortAlign() const { return 16; } // FIXME
+
+  /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
+  /// this target, in bits.
+  unsigned getIntWidth() const { return IntWidth; }
+  unsigned getIntAlign() const { return IntAlign; }
+
+  /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
+  /// for this target, in bits.
+  unsigned getLongWidth() const { return LongWidth; }
+  unsigned getLongAlign() const { return LongAlign; }
+
+  /// getLongLongWidth/Align - Return the size of 'signed long long' and
+  /// 'unsigned long long' for this target, in bits.
+  unsigned getLongLongWidth() const { return LongLongWidth; }
+  unsigned getLongLongAlign() const { return LongLongAlign; }
+
+  /// \brief Determine whether the __int128 type is supported on this target.
+  virtual bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
+
+  /// \brief Return the alignment that is suitable for storing any
+  /// object with a fundamental alignment requirement.
+  unsigned getSuitableAlign() const { return SuitableAlign; }
+
+  /// getMinGlobalAlign - Return the minimum alignment of a global variable,
+  /// unless its alignment is explicitly reduced via attributes.
+  unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
+
+  /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
+  /// bits.
+  unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
+  unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
+
+  /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
+  /// bits.
+  unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
+  unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
+
+  /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
+  /// bits.
+  unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
+  unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
+
+  /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
+  unsigned getHalfWidth() const { return HalfWidth; }
+  unsigned getHalfAlign() const { return HalfAlign; }
+  const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
+
+  /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
+  unsigned getFloatWidth() const { return FloatWidth; }
+  unsigned getFloatAlign() const { return FloatAlign; }
+  const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
+
+  /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
+  unsigned getDoubleWidth() const { return DoubleWidth; }
+  unsigned getDoubleAlign() const { return DoubleAlign; }
+  const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
+
+  /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
+  /// double'.
+  unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
+  unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
+  const llvm::fltSemantics &getLongDoubleFormat() const {
+    return *LongDoubleFormat;
+  }
+
+  /// \brief Return the value for the C99 FLT_EVAL_METHOD macro.
+  virtual unsigned getFloatEvalMethod() const { return 0; }
+
+  // getLargeArrayMinWidth/Align - Return the minimum array size that is
+  // 'large' and its alignment.
+  unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
+  unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
+
+  /// \brief Return the maximum width lock-free atomic operation which will
+  /// ever be supported for the given target
+  unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
+  /// \brief Return the maximum width lock-free atomic operation which can be
+  /// inlined given the supported features of the given target.
+  unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
+
+  /// \brief Return the maximum vector alignment supported for the given target.
+  unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
+
+  /// \brief Return the size of intmax_t and uintmax_t for this target, in bits.
+  unsigned getIntMaxTWidth() const {
+    return getTypeWidth(IntMaxType);
+  }
+
+  // Return the size of unwind_word for this target.
+  unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
+
+  /// \brief Return the "preferred" register width on this target.
+  unsigned getRegisterWidth() const {
+    // Currently we assume the register width on the target matches the pointer
+    // width, we can introduce a new variable for this if/when some target wants
+    // it.
+    return PointerWidth;
+  }
+
+  /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
+  /// which is the prefix given to user symbols by default.
+  ///
+  /// On most platforms this is "_", but it is "" on some, and "." on others.
+  const char *getUserLabelPrefix() const {
+    return UserLabelPrefix;
+  }
+
+  /// \brief Returns the name of the mcount instrumentation function.
+  const char *getMCountName() const {
+    return MCountName;
+  }
+
+  /// \brief Check if the Objective-C built-in boolean type should be signed
+  /// char.
+  ///
+  /// Otherwise, if this returns false, the normal built-in boolean type
+  /// should also be used for Objective-C.
+  bool useSignedCharForObjCBool() const {
+    return UseSignedCharForObjCBool;
+  }
+  void noSignedCharForObjCBool() {
+    UseSignedCharForObjCBool = false;
+  }
+
+  /// \brief Check whether the alignment of bit-field types is respected
+  /// when laying out structures.
+  bool useBitFieldTypeAlignment() const {
+    return UseBitFieldTypeAlignment;
+  }
+
+  /// \brief Check whether zero length bitfields should force alignment of
+  /// the next member.
+  bool useZeroLengthBitfieldAlignment() const {
+    return UseZeroLengthBitfieldAlignment;
+  }
+
+  /// \brief Get the fixed alignment value in bits for a member that follows
+  /// a zero length bitfield.
+  unsigned getZeroLengthBitfieldBoundary() const {
+    return ZeroLengthBitfieldBoundary;
+  }
+
+  /// \brief Check whether this target support '\#pragma options align=mac68k'.
+  bool hasAlignMac68kSupport() const {
+    return HasAlignMac68kSupport;
+  }
+
+  /// \brief Return the user string for the specified integer type enum.
+  ///
+  /// For example, SignedShort -> "short".
+  static const char *getTypeName(IntType T);
+
+  /// \brief Return the constant suffix for the specified integer type enum.
+  ///
+  /// For example, SignedLong -> "L".
+  const char *getTypeConstantSuffix(IntType T) const;
+
+  /// \brief Return the printf format modifier for the specified
+  /// integer type enum.
+  ///
+  /// For example, SignedLong -> "l".
+  static const char *getTypeFormatModifier(IntType T);
+
+  /// \brief Check whether the given real type should use the "fpret" flavor of
+  /// Objective-C message passing on this target.
+  bool useObjCFPRetForRealType(RealType T) const {
+    return RealTypeUsesObjCFPRet & (1 << T);
+  }
+
+  /// \brief Check whether _Complex long double should use the "fp2ret" flavor
+  /// of Objective-C message passing on this target.
+  bool useObjCFP2RetForComplexLongDouble() const {
+    return ComplexLongDoubleUsesFP2Ret;
+  }
+
+  /// \brief Specify if mangling based on address space map should be used or
+  /// not for language specific address spaces
+  bool useAddressSpaceMapMangling() const {
+    return UseAddrSpaceMapMangling;
+  }
+
+  ///===---- Other target property query methods --------------------------===//
+
+  /// \brief Appends the target-specific \#define values for this
+  /// target set to the specified buffer.
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const = 0;
+
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const = 0;
+
+  /// The __builtin_clz* and __builtin_ctz* built-in
+  /// functions are specified to have undefined results for zero inputs, but
+  /// on targets that support these operations in a way that provides
+  /// well-defined results for zero without loss of performance, it is a good
+  /// idea to avoid optimizing based on that undef behavior.
+  virtual bool isCLZForZeroUndef() const { return true; }
+
+  /// \brief Returns the kind of __builtin_va_list type that should be used
+  /// with this target.
+  virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
+
+  /// \brief Returns whether the passed in string is a valid clobber in an
+  /// inline asm statement.
+  ///
+  /// This is used by Sema.
+  bool isValidClobber(StringRef Name) const;
+
+  /// \brief Returns whether the passed in string is a valid register name
+  /// according to GCC.
+  ///
+  /// This is used by Sema for inline asm statements.
+  bool isValidGCCRegisterName(StringRef Name) const;
+
+  /// \brief Returns the "normalized" GCC register name.
+  ///
+  /// For example, on x86 it will return "ax" when "eax" is passed in.
+  StringRef getNormalizedGCCRegisterName(StringRef Name) const;
+
+  struct ConstraintInfo {
+    enum {
+      CI_None = 0x00,
+      CI_AllowsMemory = 0x01,
+      CI_AllowsRegister = 0x02,
+      CI_ReadWrite = 0x04,       // "+r" output constraint (read and write).
+      CI_HasMatchingInput = 0x08 // This output operand has a matching input.
+    };
+    unsigned Flags;
+    int TiedOperand;
+
+    std::string ConstraintStr;  // constraint: "=rm"
+    std::string Name;           // Operand name: [foo] with no []'s.
+  public:
+    ConstraintInfo(StringRef ConstraintStr, StringRef Name)
+      : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
+      Name(Name.str()) {}
+
+    const std::string &getConstraintStr() const { return ConstraintStr; }
+    const std::string &getName() const { return Name; }
+    bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
+    bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
+    bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
+
+    /// \brief Return true if this output operand has a matching
+    /// (tied) input operand.
+    bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
+
+    /// \brief Return true if this input operand is a matching
+    /// constraint that ties it to an output operand.
+    ///
+    /// If this returns true then getTiedOperand will indicate which output
+    /// operand this is tied to.
+    bool hasTiedOperand() const { return TiedOperand != -1; }
+    unsigned getTiedOperand() const {
+      assert(hasTiedOperand() && "Has no tied operand!");
+      return (unsigned)TiedOperand;
+    }
+
+    void setIsReadWrite() { Flags |= CI_ReadWrite; }
+    void setAllowsMemory() { Flags |= CI_AllowsMemory; }
+    void setAllowsRegister() { Flags |= CI_AllowsRegister; }
+    void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
+
+    /// \brief Indicate that this is an input operand that is tied to
+    /// the specified output operand. 
+    ///
+    /// Copy over the various constraint information from the output.
+    void setTiedOperand(unsigned N, ConstraintInfo &Output) {
+      Output.setHasMatchingInput();
+      Flags = Output.Flags;
+      TiedOperand = N;
+      // Don't copy Name or constraint string.
+    }
+  };
+
+  // validateOutputConstraint, validateInputConstraint - Checks that
+  // a constraint is valid and provides information about it.
+  // FIXME: These should return a real error instead of just true/false.
+  bool validateOutputConstraint(ConstraintInfo &Info) const;
+  bool validateInputConstraint(ConstraintInfo *OutputConstraints,
+                               unsigned NumOutputs,
+                               ConstraintInfo &info) const;
+  virtual bool validateInputSize(StringRef /*Constraint*/,
+                                 unsigned /*Size*/) const {
+    return true;
+  }
+  virtual bool validateConstraintModifier(StringRef /*Constraint*/,
+                                          const char /*Modifier*/,
+                                          unsigned /*Size*/) const {
+    return true;
+  }
+  bool resolveSymbolicName(const char *&Name,
+                           ConstraintInfo *OutputConstraints,
+                           unsigned NumOutputs, unsigned &Index) const;
+
+  // Constraint parm will be left pointing at the last character of
+  // the constraint.  In practice, it won't be changed unless the
+  // constraint is longer than one character.
+  virtual std::string convertConstraint(const char *&Constraint) const {
+    // 'p' defaults to 'r', but can be overridden by targets.
+    if (*Constraint == 'p')
+      return std::string("r");
+    return std::string(1, *Constraint);
+  }
+
+  /// \brief Returns a string of target-specific clobbers, in LLVM format.
+  virtual const char *getClobbers() const = 0;
+
+
+  /// \brief Returns the target triple of the primary target.
+  const llvm::Triple &getTriple() const {
+    return Triple;
+  }
+
+  const char *getTargetDescription() const {
+    assert(DescriptionString);
+    return DescriptionString;
+  }
+
+  struct GCCRegAlias {
+    const char * const Aliases[5];
+    const char * const Register;
+  };
+
+  struct AddlRegName {
+    const char * const Names[5];
+    const unsigned RegNum;
+  };
+
+  /// \brief Does this target support "protected" visibility?
+  ///
+  /// Any target which dynamic libraries will naturally support
+  /// something like "default" (meaning that the symbol is visible
+  /// outside this shared object) and "hidden" (meaning that it isn't)
+  /// visibilities, but "protected" is really an ELF-specific concept
+  /// with weird semantics designed around the convenience of dynamic
+  /// linker implementations.  Which is not to suggest that there's
+  /// consistent target-independent semantics for "default" visibility
+  /// either; the entire thing is pretty badly mangled.
+  virtual bool hasProtectedVisibility() const { return true; }
+
+  /// \brief An optional hook that targets can implement to perform semantic
+  /// checking on attribute((section("foo"))) specifiers.
+  ///
+  /// In this case, "foo" is passed in to be checked.  If the section
+  /// specifier is invalid, the backend should return a non-empty string
+  /// that indicates the problem.
+  ///
+  /// This hook is a simple quality of implementation feature to catch errors
+  /// and give good diagnostics in cases when the assembler or code generator
+  /// would otherwise reject the section specifier.
+  ///
+  virtual std::string isValidSectionSpecifier(StringRef SR) const {
+    return "";
+  }
+
+  /// \brief Set forced language options.
+  ///
+  /// Apply changes to the target information with respect to certain
+  /// language options which change the target configuration.
+  virtual void adjust(const LangOptions &Opts);
+
+  /// \brief Get the default set of target features for the CPU;
+  /// this should include all legal feature strings on the target.
+  virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
+  }
+
+  /// \brief Get the ABI currently in use.
+  virtual StringRef getABI() const { return StringRef(); }
+
+  /// \brief Get the C++ ABI currently in use.
+  TargetCXXABI getCXXABI() const {
+    return TheCXXABI;
+  }
+
+  /// \brief Target the specified CPU.
+  ///
+  /// \return  False on error (invalid CPU name).
+  virtual bool setCPU(const std::string &Name) {
+    return false;
+  }
+
+  /// \brief Use the specified ABI.
+  ///
+  /// \return False on error (invalid ABI name).
+  virtual bool setABI(const std::string &Name) {
+    return false;
+  }
+
+  /// \brief Use the specified unit for FP math.
+  ///
+  /// \return False on error (invalid unit name).
+  virtual bool setFPMath(StringRef Name) {
+    return false;
+  }
+
+  /// \brief Use this specified C++ ABI.
+  ///
+  /// \return False on error (invalid C++ ABI name).
+  bool setCXXABI(llvm::StringRef name) {
+    TargetCXXABI ABI;
+    if (!ABI.tryParse(name)) return false;
+    return setCXXABI(ABI);
+  }
+
+  /// \brief Set the C++ ABI to be used by this implementation.
+  ///
+  /// \return False on error (ABI not valid on this target)
+  virtual bool setCXXABI(TargetCXXABI ABI) {
+    TheCXXABI = ABI;
+    return true;
+  }
+
+  /// \brief Enable or disable a specific target feature;
+  /// the feature name must be valid.
+  virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
+                                 StringRef Name,
+                                 bool Enabled) const {
+    Features[Name] = Enabled;
+  }
+
+  /// \brief Perform initialization based on the user configured
+  /// set of features (e.g., +sse4).
+  ///
+  /// The list is guaranteed to have at most one entry per feature.
+  ///
+  /// The target may modify the features list, to change which options are
+  /// passed onwards to the backend.
+  ///
+  /// \return  False on error.
+  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+                                    DiagnosticsEngine &Diags) {
+    return true;
+  }
+
+  /// \brief Determine whether the given target has the given feature.
+  virtual bool hasFeature(StringRef Feature) const {
+    return false;
+  }
+  
+  // \brief Returns maximal number of args passed in registers.
+  unsigned getRegParmMax() const {
+    assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
+    return RegParmMax;
+  }
+
+  /// \brief Whether the target supports thread-local storage.
+  bool isTLSSupported() const {
+    return TLSSupported;
+  }
+
+  /// \brief Return true if {|} are normal characters in the asm string.
+  ///
+  /// If this returns false (the default), then {abc|xyz} is syntax
+  /// that says that when compiling for asm variant #0, "abc" should be
+  /// generated, but when compiling for asm variant #1, "xyz" should be
+  /// generated.
+  bool hasNoAsmVariants() const {
+    return NoAsmVariants;
+  }
+
+  /// \brief Return the register number that __builtin_eh_return_regno would
+  /// return with the specified argument.
+  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+    return -1;
+  }
+
+  /// \brief Return the section to use for C++ static initialization functions.
+  virtual const char *getStaticInitSectionSpecifier() const {
+    return nullptr;
+  }
+
+  const LangAS::Map &getAddressSpaceMap() const {
+    return *AddrSpaceMap;
+  }
+
+  /// \brief Retrieve the name of the platform as it is used in the
+  /// availability attribute.
+  StringRef getPlatformName() const { return PlatformName; }
+
+  /// \brief Retrieve the minimum desired version of the platform, to
+  /// which the program should be compiled.
+  VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
+
+  bool isBigEndian() const { return BigEndian; }
+
+  enum CallingConvMethodType {
+    CCMT_Unknown,
+    CCMT_Member,
+    CCMT_NonMember
+  };
+
+  /// \brief Gets the default calling convention for the given target and
+  /// declaration context.
+  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
+    // Not all targets will specify an explicit calling convention that we can
+    // express.  This will always do the right thing, even though it's not
+    // an explicit calling convention.
+    return CC_C;
+  }
+
+  enum CallingConvCheckResult {
+    CCCR_OK,
+    CCCR_Warning
+  };
+
+  /// \brief Determines whether a given calling convention is valid for the
+  /// target. A calling convention can either be accepted, produce a warning 
+  /// and be substituted with the default calling convention, or (someday)
+  /// produce an error (such as using thiscall on a non-instance function).
+  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
+    switch (CC) {
+      default:
+        return CCCR_Warning;
+      case CC_C:
+        return CCCR_OK;
+    }
+  }
+
+protected:
+  virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
+    return PointerWidth;
+  }
+  virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
+    return PointerAlign;
+  }
+  virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
+    return PtrDiffType;
+  }
+  virtual void getGCCRegNames(const char * const *&Names,
+                              unsigned &NumNames) const = 0;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const = 0;
+  virtual void getGCCAddlRegNames(const AddlRegName *&Addl,
+                                  unsigned &NumAddl) const {
+    Addl = nullptr;
+    NumAddl = 0;
+  }
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &info) const= 0;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
new file mode 100644
index 0000000..2c86c31
--- /dev/null
+++ b/include/clang/Basic/TargetOptions.h
@@ -0,0 +1,52 @@
+//===--- TargetOptions.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TargetOptions class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Options for controlling the target.
+class TargetOptions {
+public:
+  /// If given, the name of the target triple to compile for. If not given the
+  /// target will be selected to match the host.
+  std::string Triple;
+
+  /// If given, the name of the target CPU to generate code for.
+  std::string CPU;
+
+  /// If given, the unit to use for floating point math.
+  std::string FPMath;
+
+  /// If given, the name of the target ABI to use.
+  std::string ABI;
+
+  /// If given, the version string of the linker in use.
+  std::string LinkerVersion;
+
+  /// \brief The list of target specific features to enable or disable, as written on the command line.
+  std::vector<std::string> FeaturesAsWritten;
+
+  /// The list of target specific features to enable or disable -- this should
+  /// be a list of strings starting with by '+' or '-'.
+  std::vector<std::string> Features;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
new file mode 100644
index 0000000..b730143
--- /dev/null
+++ b/include/clang/Basic/TemplateKinds.h
@@ -0,0 +1,44 @@
+//===--- TemplateKinds.h - Enum values for C++ Template Kinds ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TemplateNameKind enum.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TEMPLATEKINDS_H
+#define LLVM_CLANG_TEMPLATEKINDS_H
+
+namespace clang {
+
+/// \brief Specifies the kind of template name that an identifier refers to.
+/// Be careful when changing this: this enumeration is used in diagnostics.
+enum TemplateNameKind {
+  /// The name does not refer to a template.
+  TNK_Non_template = 0,
+  /// The name refers to a function template or a set of overloaded
+  /// functions that includes at least one function template.
+  TNK_Function_template,
+  /// The name refers to a template whose specialization produces a
+  /// type. The template itself could be a class template, template
+  /// template parameter, or C++0x template alias.
+  TNK_Type_template,
+  /// The name refers to a variable template whose specialization produces a
+  /// variable.
+  TNK_Var_template,
+  /// The name refers to a dependent template name. Whether the
+  /// template name is assumed to refer to a type template or a
+  /// function template depends on the context in which the template
+  /// name occurs.
+  TNK_Dependent_template_name
+};
+
+}
+#endif
+
+
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
new file mode 100644
index 0000000..5d08833
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.def
@@ -0,0 +1,727 @@
+//===--- TokenKinds.def - C Family Token Kind Database ----------*- 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 TokenKind database.  This includes normal tokens like
+// tok::ampamp (corresponding to the && token) as well as keywords for various
+// languages.  Users of this file must optionally #define the TOK, KEYWORD,
+// ALIAS, or PPKEYWORD macros to make use of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TOK
+#define TOK(X)
+#endif
+#ifndef PUNCTUATOR
+#define PUNCTUATOR(X,Y) TOK(X)
+#endif
+#ifndef KEYWORD
+#define KEYWORD(X,Y) TOK(kw_ ## X)
+#endif
+#ifndef TYPE_TRAIT
+#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
+#endif
+#ifndef TYPE_TRAIT_1
+#define TYPE_TRAIT_1(I,E,K) TYPE_TRAIT(1,I,K)
+#endif
+#ifndef TYPE_TRAIT_2
+#define TYPE_TRAIT_2(I,E,K) TYPE_TRAIT(2,I,K)
+#endif
+#ifndef TYPE_TRAIT_N
+#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
+#endif
+#ifndef ALIAS
+#define ALIAS(X,Y,Z)
+#endif
+#ifndef PPKEYWORD
+#define PPKEYWORD(X)
+#endif
+#ifndef CXX_KEYWORD_OPERATOR
+#define CXX_KEYWORD_OPERATOR(X,Y)
+#endif
+#ifndef OBJC1_AT_KEYWORD
+#define OBJC1_AT_KEYWORD(X)
+#endif
+#ifndef OBJC2_AT_KEYWORD
+#define OBJC2_AT_KEYWORD(X)
+#endif
+#ifndef TESTING_KEYWORD
+#define TESTING_KEYWORD(X, L) KEYWORD(X, L)
+#endif
+#ifndef ANNOTATION
+#define ANNOTATION(X) TOK(annot_ ## X)
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after a '#' at the start of a line. These define enums in
+// the tok::pp_* namespace.  Note that IdentifierInfo::getPPKeywordID must be
+// manually updated if something is added here.
+PPKEYWORD(not_keyword)
+
+// C99 6.10.1 - Conditional Inclusion.
+PPKEYWORD(if)
+PPKEYWORD(ifdef)
+PPKEYWORD(ifndef)
+PPKEYWORD(elif)
+PPKEYWORD(else)
+PPKEYWORD(endif)
+PPKEYWORD(defined)
+
+// C99 6.10.2 - Source File Inclusion.
+PPKEYWORD(include)
+PPKEYWORD(__include_macros)
+
+// C99 6.10.3 - Macro Replacement.
+PPKEYWORD(define)
+PPKEYWORD(undef)
+
+// C99 6.10.4 - Line Control.
+PPKEYWORD(line)
+
+// C99 6.10.5 - Error Directive.
+PPKEYWORD(error)
+
+// C99 6.10.6 - Pragma Directive.
+PPKEYWORD(pragma)
+
+// GNU Extensions.
+PPKEYWORD(import)
+PPKEYWORD(include_next)
+PPKEYWORD(warning)
+PPKEYWORD(ident)
+PPKEYWORD(sccs)
+PPKEYWORD(assert)
+PPKEYWORD(unassert)
+
+// Clang extensions
+PPKEYWORD(__public_macro)
+PPKEYWORD(__private_macro)
+
+//===----------------------------------------------------------------------===//
+// Language keywords.
+//===----------------------------------------------------------------------===//
+
+// These define members of the tok::* namespace.
+
+TOK(unknown)             // Not a token.
+TOK(eof)                 // End of file.
+TOK(eod)                 // End of preprocessing directive (end of line inside a
+                         // directive).
+TOK(code_completion)     // Code completion marker
+TOK(cxx_defaultarg_end)  // C++ default argument end marker
+
+// C99 6.4.9: Comments.
+TOK(comment)             // Comment (only in -E -C[C] mode)
+
+// C99 6.4.2: Identifiers.
+TOK(identifier)          // abcde123
+TOK(raw_identifier)      // Used only in raw lexing mode.
+
+// C99 6.4.4.1: Integer Constants
+// C99 6.4.4.2: Floating Constants
+TOK(numeric_constant)    // 0x123
+
+// C99 6.4.4: Character Constants
+TOK(char_constant)       // 'a'
+TOK(wide_char_constant)  // L'b'
+
+// C++11 Character Constants
+TOK(utf16_char_constant) // u'a'
+TOK(utf32_char_constant) // U'a'
+
+// C99 6.4.5: String Literals.
+TOK(string_literal)      // "foo"
+TOK(wide_string_literal) // L"foo"
+TOK(angle_string_literal)// <foo>
+
+// C++11 String Literals.
+TOK(utf8_string_literal) // u8"foo"
+TOK(utf16_string_literal)// u"foo"
+TOK(utf32_string_literal)// U"foo"
+
+// C99 6.4.6: Punctuators.
+PUNCTUATOR(l_square,            "[")
+PUNCTUATOR(r_square,            "]")
+PUNCTUATOR(l_paren,             "(")
+PUNCTUATOR(r_paren,             ")")
+PUNCTUATOR(l_brace,             "{")
+PUNCTUATOR(r_brace,             "}")
+PUNCTUATOR(period,              ".")
+PUNCTUATOR(ellipsis,            "...")
+PUNCTUATOR(amp,                 "&")
+PUNCTUATOR(ampamp,              "&&")
+PUNCTUATOR(ampequal,            "&=")
+PUNCTUATOR(star,                "*")
+PUNCTUATOR(starequal,           "*=")
+PUNCTUATOR(plus,                "+")
+PUNCTUATOR(plusplus,            "++")
+PUNCTUATOR(plusequal,           "+=")
+PUNCTUATOR(minus,               "-")
+PUNCTUATOR(arrow,               "->")
+PUNCTUATOR(minusminus,          "--")
+PUNCTUATOR(minusequal,          "-=")
+PUNCTUATOR(tilde,               "~")
+PUNCTUATOR(exclaim,             "!")
+PUNCTUATOR(exclaimequal,        "!=")
+PUNCTUATOR(slash,               "/")
+PUNCTUATOR(slashequal,          "/=")
+PUNCTUATOR(percent,             "%")
+PUNCTUATOR(percentequal,        "%=")
+PUNCTUATOR(less,                "<")
+PUNCTUATOR(lessless,            "<<")
+PUNCTUATOR(lessequal,           "<=")
+PUNCTUATOR(lesslessequal,       "<<=")
+PUNCTUATOR(greater,             ">")
+PUNCTUATOR(greatergreater,      ">>")
+PUNCTUATOR(greaterequal,        ">=")
+PUNCTUATOR(greatergreaterequal, ">>=")
+PUNCTUATOR(caret,               "^")
+PUNCTUATOR(caretequal,          "^=")
+PUNCTUATOR(pipe,                "|")
+PUNCTUATOR(pipepipe,            "||")
+PUNCTUATOR(pipeequal,           "|=")
+PUNCTUATOR(question,            "?")
+PUNCTUATOR(colon,               ":")
+PUNCTUATOR(semi,                ";")
+PUNCTUATOR(equal,               "=")
+PUNCTUATOR(equalequal,          "==")
+PUNCTUATOR(comma,               ",")
+PUNCTUATOR(hash,                "#")
+PUNCTUATOR(hashhash,            "##")
+PUNCTUATOR(hashat,              "#@")
+
+// C++ Support
+PUNCTUATOR(periodstar,          ".*")
+PUNCTUATOR(arrowstar,           "->*")
+PUNCTUATOR(coloncolon,          "::")
+
+// Objective C support.
+PUNCTUATOR(at,                  "@")
+
+// CUDA support.
+PUNCTUATOR(lesslessless,          "<<<")
+PUNCTUATOR(greatergreatergreater, ">>>")
+
+// C99 6.4.1: Keywords.  These turn into kw_* tokens.
+// Flags allowed:
+//   KEYALL   - This is a keyword in all variants of C and C++, or it
+//              is a keyword in the implementation namespace that should
+//              always be treated as a keyword
+//   KEYC99   - This is a keyword introduced to C in C99
+//   KEYC11   - This is a keyword introduced to C in C11
+//   KEYCXX   - This is a C++ keyword, or a C++-specific keyword in the
+//              implementation namespace
+//   KEYNOCXX - This is a keyword in every non-C++ dialect.
+//   KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
+//   KEYGNU   - This is a keyword if GNU extensions are enabled
+//   KEYMS    - This is a keyword if Microsoft extensions are enabled
+//   KEYNOMS  - This is a keyword that must never be enabled under
+//              Microsoft mode
+//   KEYOPENCL  - This is a keyword in OpenCL
+//   KEYALTIVEC - This is a keyword in AltiVec
+//   KEYBORLAND - This is a keyword if Borland extensions are enabled
+//   BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
+//   HALFSUPPORT - This is a keyword if 'half' is a built-in type
+//   WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
+//
+KEYWORD(auto                        , KEYALL)
+KEYWORD(break                       , KEYALL)
+KEYWORD(case                        , KEYALL)
+KEYWORD(char                        , KEYALL)
+KEYWORD(const                       , KEYALL)
+KEYWORD(continue                    , KEYALL)
+KEYWORD(default                     , KEYALL)
+KEYWORD(do                          , KEYALL)
+KEYWORD(double                      , KEYALL)
+KEYWORD(else                        , KEYALL)
+KEYWORD(enum                        , KEYALL)
+KEYWORD(extern                      , KEYALL)
+KEYWORD(float                       , KEYALL)
+KEYWORD(for                         , KEYALL)
+KEYWORD(goto                        , KEYALL)
+KEYWORD(if                          , KEYALL)
+KEYWORD(inline                      , KEYC99|KEYCXX|KEYGNU)
+KEYWORD(int                         , KEYALL)
+KEYWORD(long                        , KEYALL)
+KEYWORD(register                    , KEYALL)
+KEYWORD(restrict                    , KEYC99)
+KEYWORD(return                      , KEYALL)
+KEYWORD(short                       , KEYALL)
+KEYWORD(signed                      , KEYALL)
+KEYWORD(sizeof                      , KEYALL)
+KEYWORD(static                      , KEYALL)
+KEYWORD(struct                      , KEYALL)
+KEYWORD(switch                      , KEYALL)
+KEYWORD(typedef                     , KEYALL)
+KEYWORD(union                       , KEYALL)
+KEYWORD(unsigned                    , KEYALL)
+KEYWORD(void                        , KEYALL)
+KEYWORD(volatile                    , KEYALL)
+KEYWORD(while                       , KEYALL)
+KEYWORD(_Alignas                    , KEYALL)
+KEYWORD(_Alignof                    , KEYALL)
+KEYWORD(_Atomic                     , KEYALL|KEYNOMS)
+KEYWORD(_Bool                       , KEYNOCXX)
+KEYWORD(_Complex                    , KEYALL)
+KEYWORD(_Generic                    , KEYALL)
+KEYWORD(_Imaginary                  , KEYALL)
+KEYWORD(_Noreturn                   , KEYALL)
+KEYWORD(_Static_assert              , KEYALL)
+KEYWORD(_Thread_local               , KEYALL)
+KEYWORD(__func__                    , KEYALL)
+KEYWORD(__objc_yes                  , KEYALL)
+KEYWORD(__objc_no                   , KEYALL)
+
+
+// C++ 2.11p1: Keywords.
+KEYWORD(asm                         , KEYCXX|KEYGNU)
+KEYWORD(bool                        , BOOLSUPPORT)
+KEYWORD(catch                       , KEYCXX)
+KEYWORD(class                       , KEYCXX)
+KEYWORD(const_cast                  , KEYCXX)
+KEYWORD(delete                      , KEYCXX)
+KEYWORD(dynamic_cast                , KEYCXX)
+KEYWORD(explicit                    , KEYCXX)
+KEYWORD(export                      , KEYCXX)
+KEYWORD(false                       , BOOLSUPPORT)
+KEYWORD(friend                      , KEYCXX)
+KEYWORD(mutable                     , KEYCXX)
+KEYWORD(namespace                   , KEYCXX)
+KEYWORD(new                         , KEYCXX)
+KEYWORD(operator                    , KEYCXX)
+KEYWORD(private                     , KEYCXX)
+KEYWORD(protected                   , KEYCXX)
+KEYWORD(public                      , KEYCXX)
+KEYWORD(reinterpret_cast            , KEYCXX)
+KEYWORD(static_cast                 , KEYCXX)
+KEYWORD(template                    , KEYCXX)
+KEYWORD(this                        , KEYCXX)
+KEYWORD(throw                       , KEYCXX)
+KEYWORD(true                        , BOOLSUPPORT)
+KEYWORD(try                         , KEYCXX)
+KEYWORD(typename                    , KEYCXX)
+KEYWORD(typeid                      , KEYCXX)
+KEYWORD(using                       , KEYCXX)
+KEYWORD(virtual                     , KEYCXX)
+KEYWORD(wchar_t                     , WCHARSUPPORT)
+
+// C++ 2.5p2: Alternative Representations.
+CXX_KEYWORD_OPERATOR(and     , ampamp)
+CXX_KEYWORD_OPERATOR(and_eq  , ampequal)
+CXX_KEYWORD_OPERATOR(bitand  , amp)
+CXX_KEYWORD_OPERATOR(bitor   , pipe)
+CXX_KEYWORD_OPERATOR(compl   , tilde)
+CXX_KEYWORD_OPERATOR(not     , exclaim)
+CXX_KEYWORD_OPERATOR(not_eq  , exclaimequal)
+CXX_KEYWORD_OPERATOR(or      , pipepipe)
+CXX_KEYWORD_OPERATOR(or_eq   , pipeequal)
+CXX_KEYWORD_OPERATOR(xor     , caret)
+CXX_KEYWORD_OPERATOR(xor_eq  , caretequal)
+
+// C++11 keywords
+KEYWORD(alignas                     , KEYCXX11)
+KEYWORD(alignof                     , KEYCXX11)
+KEYWORD(char16_t                    , KEYCXX11|KEYNOMS)
+KEYWORD(char32_t                    , KEYCXX11|KEYNOMS)
+KEYWORD(constexpr                   , KEYCXX11)
+KEYWORD(decltype                    , KEYCXX11)
+KEYWORD(noexcept                    , KEYCXX11)
+KEYWORD(nullptr                     , KEYCXX11)
+KEYWORD(static_assert               , KEYCXX11)
+KEYWORD(thread_local                , KEYCXX11)
+
+// GNU Extensions (in impl-reserved namespace)
+KEYWORD(_Decimal32                  , KEYALL)
+KEYWORD(_Decimal64                  , KEYALL)
+KEYWORD(_Decimal128                 , KEYALL)
+KEYWORD(__null                      , KEYCXX)
+KEYWORD(__alignof                   , KEYALL)
+KEYWORD(__attribute                 , KEYALL)
+KEYWORD(__builtin_choose_expr       , KEYALL)
+KEYWORD(__builtin_offsetof          , KEYALL)
+// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
+// type trait.
+TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
+KEYWORD(__builtin_va_arg            , KEYALL)
+KEYWORD(__extension__               , KEYALL)
+KEYWORD(__imag                      , KEYALL)
+KEYWORD(__int128                    , KEYALL)
+KEYWORD(__label__                   , KEYALL)
+KEYWORD(__real                      , KEYALL)
+KEYWORD(__thread                    , KEYALL)
+KEYWORD(__FUNCTION__                , KEYALL)
+KEYWORD(__PRETTY_FUNCTION__         , KEYALL)
+
+// GNU Extensions (outside impl-reserved namespace)
+KEYWORD(typeof                      , KEYGNU)
+
+// MS Extensions
+KEYWORD(__FUNCDNAME__               , KEYMS)
+KEYWORD(__FUNCSIG__                 , KEYMS)
+KEYWORD(L__FUNCTION__               , KEYMS)
+TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
+TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
+
+// MSVC12.0 / VS2013 Type Traits
+TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
+TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
+TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
+
+// GNU and MS Type Traits
+TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_assign, HasTrivialAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_copy, HasTrivialCopy, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_constructor, HasTrivialDefaultConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
+TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
+TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
+TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
+TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
+TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
+TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)
+TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)
+TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)
+// Tentative name - there's no implementation of std::is_literal_type yet.
+TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)
+// Name for GCC 4.6 compatibility - people have already written libraries using
+// this name unfortunately.
+ALIAS("__is_literal_type", __is_literal, KEYCXX)
+TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
+TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
+TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
+TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
+
+// Clang-only C++ Type Traits
+TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
+TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX)
+KEYWORD(__underlying_type           , KEYCXX)
+
+// Embarcadero Expression Traits
+KEYWORD(__is_lvalue_expr            , KEYCXX)
+KEYWORD(__is_rvalue_expr            , KEYCXX)
+
+// Embarcadero Unary Type Traits
+TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX)
+TYPE_TRAIT_1(__is_floating_point, IsFloatingPoint, KEYCXX)
+TYPE_TRAIT_1(__is_integral, IsIntegral, KEYCXX)
+TYPE_TRAIT_1(__is_complete_type, IsCompleteType, KEYCXX)
+TYPE_TRAIT_1(__is_void, IsVoid, KEYCXX)
+TYPE_TRAIT_1(__is_array, IsArray, KEYCXX)
+TYPE_TRAIT_1(__is_function, IsFunction, KEYCXX)
+TYPE_TRAIT_1(__is_reference, IsReference, KEYCXX)
+TYPE_TRAIT_1(__is_lvalue_reference, IsLvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_rvalue_reference, IsRvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_fundamental, IsFundamental, KEYCXX)
+TYPE_TRAIT_1(__is_object, IsObject, KEYCXX)
+TYPE_TRAIT_1(__is_scalar, IsScalar, KEYCXX)
+TYPE_TRAIT_1(__is_compound, IsCompound, KEYCXX)
+TYPE_TRAIT_1(__is_pointer, IsPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_object_pointer, IsMemberObjectPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_function_pointer, IsMemberFunctionPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_pointer, IsMemberPointer, KEYCXX)
+TYPE_TRAIT_1(__is_const, IsConst, KEYCXX)
+TYPE_TRAIT_1(__is_volatile, IsVolatile, KEYCXX)
+TYPE_TRAIT_1(__is_standard_layout, IsStandardLayout, KEYCXX)
+TYPE_TRAIT_1(__is_signed, IsSigned, KEYCXX)
+TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
+
+// Embarcadero Binary Type Traits
+TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
+TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
+KEYWORD(__array_rank                , KEYCXX)
+KEYWORD(__array_extent              , KEYCXX)
+
+// Apple Extension.
+KEYWORD(__private_extern__          , KEYALL)
+KEYWORD(__module_private__          , KEYALL)
+
+// Microsoft Extension.
+KEYWORD(__declspec                  , KEYALL)
+KEYWORD(__cdecl                     , KEYALL)
+KEYWORD(__stdcall                   , KEYALL)
+KEYWORD(__fastcall                  , KEYALL)
+KEYWORD(__thiscall                  , KEYALL)
+KEYWORD(__forceinline               , KEYMS)
+KEYWORD(__unaligned                 , KEYMS)
+
+// OpenCL address space qualifiers
+KEYWORD(__global                    , KEYOPENCL)
+KEYWORD(__local                     , KEYOPENCL)
+KEYWORD(__constant                  , KEYOPENCL)
+KEYWORD(__private                   , KEYOPENCL)
+ALIAS("global", __global            , KEYOPENCL)
+ALIAS("local", __local              , KEYOPENCL)
+ALIAS("constant", __constant        , KEYOPENCL)
+ALIAS("private", __private          , KEYOPENCL)
+// OpenCL function qualifiers
+KEYWORD(__kernel                    , KEYOPENCL)
+ALIAS("kernel", __kernel            , KEYOPENCL)
+// OpenCL access qualifiers
+KEYWORD(__read_only                 , KEYOPENCL)
+KEYWORD(__write_only                , KEYOPENCL)
+KEYWORD(__read_write                , KEYOPENCL)
+ALIAS("read_only", __read_only      , KEYOPENCL)
+ALIAS("write_only", __write_only    , KEYOPENCL)
+ALIAS("read_write", __read_write    , KEYOPENCL)
+// OpenCL builtins
+KEYWORD(__builtin_astype            , KEYOPENCL)
+KEYWORD(vec_step                    , KEYOPENCL|KEYALTIVEC)
+
+// Borland Extensions.
+KEYWORD(__pascal                    , KEYALL)
+
+// Altivec Extension.
+KEYWORD(__vector                    , KEYALTIVEC)
+KEYWORD(__pixel                     , KEYALTIVEC)
+
+// ARM NEON extensions.
+ALIAS("__fp16", half                , KEYALL)
+
+// OpenCL Extension.
+KEYWORD(half                        , HALFSUPPORT)
+
+// Objective-C ARC keywords.
+KEYWORD(__bridge                     , KEYARC)
+KEYWORD(__bridge_transfer            , KEYARC)
+KEYWORD(__bridge_retained            , KEYARC)
+KEYWORD(__bridge_retain              , KEYARC)
+
+// Alternate spelling for various tokens.  There are GCC extensions in all
+// languages, but should not be disabled in strict conformance mode.
+ALIAS("__alignof__"  , __alignof  , KEYALL)
+ALIAS("__asm"        , asm        , KEYALL)
+ALIAS("__asm__"      , asm        , KEYALL)
+ALIAS("__attribute__", __attribute, KEYALL)
+ALIAS("__complex"    , _Complex   , KEYALL)
+ALIAS("__complex__"  , _Complex   , KEYALL)
+ALIAS("__const"      , const      , KEYALL)
+ALIAS("__const__"    , const      , KEYALL)
+ALIAS("__decltype"   , decltype   , KEYCXX)
+ALIAS("__imag__"     , __imag     , KEYALL)
+ALIAS("__inline"     , inline     , KEYALL)
+ALIAS("__inline__"   , inline     , KEYALL)
+ALIAS("__nullptr"    , nullptr    , KEYCXX)
+ALIAS("__real__"     , __real     , KEYALL)
+ALIAS("__restrict"   , restrict   , KEYALL)
+ALIAS("__restrict__" , restrict   , KEYALL)
+ALIAS("__signed"     , signed     , KEYALL)
+ALIAS("__signed__"   , signed     , KEYALL)
+ALIAS("__typeof"     , typeof     , KEYALL)
+ALIAS("__typeof__"   , typeof     , KEYALL)
+ALIAS("__volatile"   , volatile   , KEYALL)
+ALIAS("__volatile__" , volatile   , KEYALL)
+
+// Microsoft extensions which should be disabled in strict conformance mode
+KEYWORD(__ptr64                       , KEYMS)
+KEYWORD(__ptr32                       , KEYMS)
+KEYWORD(__sptr                        , KEYMS)
+KEYWORD(__uptr                        , KEYMS)
+KEYWORD(__w64                         , KEYMS)
+KEYWORD(__uuidof                      , KEYMS | KEYBORLAND)
+KEYWORD(__try                         , KEYMS | KEYBORLAND)
+KEYWORD(__finally                     , KEYMS | KEYBORLAND)
+KEYWORD(__leave                       , KEYMS | KEYBORLAND)
+KEYWORD(__int64                       , KEYMS)
+KEYWORD(__if_exists                   , KEYMS)
+KEYWORD(__if_not_exists               , KEYMS)
+KEYWORD(__single_inheritance          , KEYMS)
+KEYWORD(__multiple_inheritance        , KEYMS)
+KEYWORD(__virtual_inheritance         , KEYMS)
+KEYWORD(__interface                   , KEYMS)
+ALIAS("__int8"           , char       , KEYMS)
+ALIAS("__int16"          , short      , KEYMS)
+ALIAS("__int32"          , int        , KEYMS)
+ALIAS("__wchar_t"        , wchar_t    , KEYMS)
+ALIAS("_asm"             , asm        , KEYMS)
+ALIAS("_alignof"         , __alignof  , KEYMS)
+ALIAS("__builtin_alignof", __alignof  , KEYMS)
+ALIAS("_cdecl"           , __cdecl    , KEYMS | KEYBORLAND)
+ALIAS("_fastcall"        , __fastcall , KEYMS | KEYBORLAND)
+ALIAS("_stdcall"         , __stdcall  , KEYMS | KEYBORLAND)
+ALIAS("_thiscall"        , __thiscall , KEYMS)
+ALIAS("_uuidof"          , __uuidof   , KEYMS | KEYBORLAND)
+ALIAS("_inline"          , inline     , KEYMS)
+ALIAS("_declspec"        , __declspec , KEYMS)
+
+// Borland Extensions which should be disabled in strict conformance mode.
+ALIAS("_pascal"      , __pascal   , KEYBORLAND)
+
+// Clang Extensions.
+KEYWORD(__builtin_convertvector   , KEYALL)
+ALIAS("__char16_t"   , char16_t   , KEYCXX)
+ALIAS("__char32_t"   , char32_t   , KEYCXX)
+
+// Clang-specific keywords enabled only in testing.
+TESTING_KEYWORD(__unknown_anytype , KEYALL)
+
+
+//===----------------------------------------------------------------------===//
+// Objective-C @-preceded keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after an '@' in Objective-C mode. These define enums in
+// the tok::objc_* namespace.
+
+OBJC1_AT_KEYWORD(not_keyword)
+OBJC1_AT_KEYWORD(class)
+OBJC1_AT_KEYWORD(compatibility_alias)
+OBJC1_AT_KEYWORD(defs)
+OBJC1_AT_KEYWORD(encode)
+OBJC1_AT_KEYWORD(end)
+OBJC1_AT_KEYWORD(implementation)
+OBJC1_AT_KEYWORD(interface)
+OBJC1_AT_KEYWORD(private)
+OBJC1_AT_KEYWORD(protected)
+OBJC1_AT_KEYWORD(protocol)
+OBJC1_AT_KEYWORD(public)
+OBJC1_AT_KEYWORD(selector)
+OBJC1_AT_KEYWORD(throw)
+OBJC1_AT_KEYWORD(try)
+OBJC1_AT_KEYWORD(catch)
+OBJC1_AT_KEYWORD(finally)
+OBJC1_AT_KEYWORD(synchronized)
+OBJC1_AT_KEYWORD(autoreleasepool)
+
+OBJC2_AT_KEYWORD(property)
+OBJC2_AT_KEYWORD(package)
+OBJC2_AT_KEYWORD(required)
+OBJC2_AT_KEYWORD(optional)
+OBJC2_AT_KEYWORD(synthesize)
+OBJC2_AT_KEYWORD(dynamic)
+OBJC2_AT_KEYWORD(import)
+
+// TODO: What to do about context-sensitive keywords like:
+//       bycopy/byref/in/inout/oneway/out?
+
+ANNOTATION(cxxscope)     // annotation for a C++ scope spec, e.g. "::foo::bar::"
+ANNOTATION(typename)     // annotation for a C typedef name, a C++ (possibly
+                         // qualified) typename, e.g. "foo::MyClass", or
+                         // template-id that names a type ("std::vector<int>")
+ANNOTATION(template_id)  // annotation for a C++ template-id that names a
+                         // function template specialization (not a type),
+                         // e.g., "std::swap<int>"
+ANNOTATION(primary_expr) // annotation for a primary expression
+ANNOTATION(decltype)     // annotation for a decltype expression,
+                         // e.g., "decltype(foo.bar())"
+
+// Annotation for #pragma unused(...)
+// For each argument inside the parentheses the pragma handler will produce
+// one 'pragma_unused' annotation token followed by the argument token.
+ANNOTATION(pragma_unused)
+
+// Annotation for #pragma GCC visibility...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_vis)
+
+// Annotation for #pragma pack...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_pack)
+
+// Annotation for #pragma clang __debug parser_crash...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_parser_crash)
+
+// Annotation for #pragma clang __debug captured...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_captured)
+
+// Annotation for #pragma ms_struct...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_msstruct)
+
+// Annotation for #pragma align...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_align)
+
+// Annotation for #pragma weak id
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_weak)
+
+// Annotation for #pragma weak id = id
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_weakalias)
+
+// Annotation for #pragma redefine_extname...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_redefine_extname)
+
+// Annotation for #pragma STDC FP_CONTRACT...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_fp_contract)
+
+// Annotation for #pragma pointers_to_members...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pointers_to_members)
+
+// Annotation for #pragma vtordisp...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_vtordisp)
+
+// Annotation for all microsoft #pragmas...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pragma)
+
+// Annotation for #pragma OPENCL EXTENSION...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_opencl_extension)
+
+// Annotations for OpenMP pragma directives - #pragma omp ...
+// The lexer produces these so that they only take effect when the parser
+// handles #pragma omp ... directives.
+ANNOTATION(pragma_openmp)
+ANNOTATION(pragma_openmp_end)
+
+// Annotations for loop pragma directives #pragma clang loop ...
+// The lexer produces these so that they only take effect when the parser
+// handles #pragma loop ... directives.
+ANNOTATION(pragma_loop_hint)
+
+// Annotations for module import translated from #include etc.
+ANNOTATION(module_include)
+ANNOTATION(module_begin)
+ANNOTATION(module_end)
+
+#undef ANNOTATION
+#undef TESTING_KEYWORD
+#undef OBJC2_AT_KEYWORD
+#undef OBJC1_AT_KEYWORD
+#undef CXX_KEYWORD_OPERATOR
+#undef PPKEYWORD
+#undef ALIAS
+#undef TYPE_TRAIT_N
+#undef TYPE_TRAIT_2
+#undef TYPE_TRAIT_1
+#undef TYPE_TRAIT
+#undef KEYWORD
+#undef PUNCTUATOR
+#undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
new file mode 100644
index 0000000..794625c
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.h
@@ -0,0 +1,106 @@
+//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::TokenKind enum and support functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENKINDS_H
+#define LLVM_CLANG_TOKENKINDS_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+namespace tok {
+
+/// \brief Provides a simple uniform namespace for tokens from all C languages.
+enum TokenKind : unsigned short {
+#define TOK(X) X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_TOKENS
+};
+
+/// \brief Provides a namespace for preprocessor keywords which start with a
+/// '#' at the beginning of the line.
+enum PPKeywordKind {
+#define PPKEYWORD(X) pp_##X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_PP_KEYWORDS
+};
+
+/// \brief Provides a namespace for Objective-C keywords which start with
+/// an '@'.
+enum ObjCKeywordKind {
+#define OBJC1_AT_KEYWORD(X) objc_##X,
+#define OBJC2_AT_KEYWORD(X) objc_##X,
+#include "clang/Basic/TokenKinds.def"
+  NUM_OBJC_KEYWORDS
+};
+
+/// \brief Defines the possible values of an on-off-switch (C99 6.10.6p2).
+enum OnOffSwitch {
+  OOS_ON, OOS_OFF, OOS_DEFAULT
+};
+
+/// \brief Determines the name of a token as used within the front end.
+///
+/// The name of a token will be an internal name (such as "l_square")
+/// and should not be used as part of diagnostic messages.
+const char *getTokenName(TokenKind Kind) LLVM_READNONE;
+
+/// \brief Determines the spelling of simple punctuation tokens like
+/// '!' or '%', and returns NULL for literal and annotation tokens.
+///
+/// This routine only retrieves the "simple" spelling of the token,
+/// and will not produce any alternative spellings (e.g., a
+/// digraph). For the actual spelling of a given Token, use
+/// Preprocessor::getSpelling().
+const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
+
+/// \brief Determines the spelling of simple keyword and contextual keyword
+/// tokens like 'int' and 'dynamic_cast'. Returns NULL for other token kinds.
+const char *getKeywordSpelling(TokenKind Kind) LLVM_READNONE;
+
+/// \brief Return true if this is a raw identifier or an identifier kind.
+inline bool isAnyIdentifier(TokenKind K) {
+  return (K == tok::identifier) || (K == tok::raw_identifier);
+}
+
+/// \brief Return true if this is a C or C++ string-literal (or
+/// C++11 user-defined-string-literal) token.
+inline bool isStringLiteral(TokenKind K) {
+  return K == tok::string_literal || K == tok::wide_string_literal ||
+         K == tok::utf8_string_literal || K == tok::utf16_string_literal ||
+         K == tok::utf32_string_literal;
+}
+
+/// \brief Return true if this is a "literal" kind, like a numeric
+/// constant, string, etc.
+inline bool isLiteral(TokenKind K) {
+  return K == tok::numeric_constant || K == tok::char_constant ||
+         K == tok::wide_char_constant || K == tok::utf16_char_constant ||
+         K == tok::utf32_char_constant || isStringLiteral(K) ||
+         K == tok::angle_string_literal;
+}
+
+/// \brief Return true if this is any of tok::annot_* kinds.
+inline bool isAnnotation(TokenKind K) {
+#define ANNOTATION(NAME) \
+  if (K == tok::annot_##NAME) \
+    return true;
+#include "clang/Basic/TokenKinds.def"
+  return false;
+}
+
+}  // end namespace tok
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
new file mode 100644
index 0000000..d7d2b18
--- /dev/null
+++ b/include/clang/Basic/TypeTraits.h
@@ -0,0 +1,99 @@
+//===--- TypeTraits.h - C++ Type Traits Support Enumerations ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines enumerations for the type traits support.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TYPETRAITS_H
+#define LLVM_CLANG_TYPETRAITS_H
+
+namespace clang {
+
+  /// \brief Names for traits that operate specifically on types.
+  enum TypeTrait {
+    UTT_HasNothrowAssign,
+    UTT_HasNothrowMoveAssign,
+    UTT_HasNothrowCopy,
+    UTT_HasNothrowConstructor,
+    UTT_HasTrivialAssign,
+    UTT_HasTrivialMoveAssign,
+    UTT_HasTrivialCopy,
+    UTT_HasTrivialDefaultConstructor,
+    UTT_HasTrivialMoveConstructor,
+    UTT_HasTrivialDestructor,
+    UTT_HasVirtualDestructor,
+    UTT_IsAbstract,
+    UTT_IsArithmetic,
+    UTT_IsArray,
+    UTT_IsClass,
+    UTT_IsCompleteType,
+    UTT_IsCompound,
+    UTT_IsConst,
+    UTT_IsDestructible,
+    UTT_IsEmpty,
+    UTT_IsEnum,
+    UTT_IsFinal,
+    UTT_IsFloatingPoint,
+    UTT_IsFunction,
+    UTT_IsFundamental,
+    UTT_IsIntegral,
+    UTT_IsInterfaceClass,
+    UTT_IsLiteral,
+    UTT_IsLvalueReference,
+    UTT_IsMemberFunctionPointer,
+    UTT_IsMemberObjectPointer,
+    UTT_IsMemberPointer,
+    UTT_IsNothrowDestructible,
+    UTT_IsObject,
+    UTT_IsPOD,
+    UTT_IsPointer,
+    UTT_IsPolymorphic,
+    UTT_IsReference,
+    UTT_IsRvalueReference,
+    UTT_IsScalar,
+    UTT_IsSealed,
+    UTT_IsSigned,
+    UTT_IsStandardLayout,
+    UTT_IsTrivial,
+    UTT_IsTriviallyCopyable,
+    UTT_IsUnion,
+    UTT_IsUnsigned,
+    UTT_IsVoid,
+    UTT_IsVolatile,
+    UTT_Last = UTT_IsVolatile,
+    BTT_IsBaseOf,
+    BTT_IsConvertible,
+    BTT_IsConvertibleTo,
+    BTT_IsSame,
+    BTT_TypeCompatible,
+    BTT_IsNothrowAssignable,
+    BTT_IsTriviallyAssignable,
+    BTT_Last = BTT_IsTriviallyAssignable,
+    TT_IsConstructible,
+    TT_IsNothrowConstructible,
+    TT_IsTriviallyConstructible
+  };
+
+  /// \brief Names for the array type traits.
+  enum ArrayTypeTrait {
+    ATT_ArrayRank,
+    ATT_ArrayExtent
+  };
+
+  /// \brief Names for the "expression or type" traits.
+  enum UnaryExprOrTypeTrait {
+    UETT_SizeOf,
+    UETT_AlignOf,
+    UETT_VecStep
+  };
+}
+
+#endif
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
new file mode 100644
index 0000000..02da432
--- /dev/null
+++ b/include/clang/Basic/Version.h
@@ -0,0 +1,82 @@
+//===- Version.h - Clang Version Number -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines version macros and version-related utility functions
+/// for Clang.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VERSION_H
+#define LLVM_CLANG_BASIC_VERSION_H
+
+#include "clang/Basic/Version.inc"
+#include "llvm/ADT/StringRef.h"
+
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING2(X) #X
+
+#ifdef CLANG_VERSION_PATCHLEVEL
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
+
+/// \brief A string that describes the Clang version number, e.g., "1.0".
+#define CLANG_VERSION_STRING \
+  CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR, \
+                            CLANG_VERSION_PATCHLEVEL)
+#else
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
+
+/// \brief A string that describes the Clang version number, e.g., "1.0".
+#define CLANG_VERSION_STRING \
+  CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
+#endif
+
+namespace clang {
+  /// \brief Retrieves the repository path (e.g., Subversion path) that
+  /// identifies the particular Clang branch, tag, or trunk from which this
+  /// Clang was built.
+  std::string getClangRepositoryPath();
+
+  /// \brief Retrieves the repository path from which LLVM was built.
+  ///
+  /// This supports LLVM residing in a separate repository from clang.
+  std::string getLLVMRepositoryPath();
+
+  /// \brief Retrieves the repository revision number (or identifer) from which
+  /// this Clang was built.
+  std::string getClangRevision();
+
+  /// \brief Retrieves the repository revision number (or identifer) from which
+  /// LLVM was built.
+  ///
+  /// If Clang and LLVM are in the same repository, this returns the same
+  /// string as getClangRevision.
+  std::string getLLVMRevision();
+
+  /// \brief Retrieves the full repository version that is an amalgamation of
+  /// the information in getClangRepositoryPath() and getClangRevision().
+  std::string getClangFullRepositoryVersion();
+
+  /// \brief Retrieves a string representing the complete clang version,
+  /// which includes the clang version number, the repository version,
+  /// and the vendor tag.
+  std::string getClangFullVersion();
+
+  /// \brief Like getClangFullVersion(), but with a custom tool name.
+  std::string getClangToolFullVersion(llvm::StringRef ToolName);
+
+  /// \brief Retrieves a string representing the complete clang version suitable
+  /// for use in the CPP __VERSION__ macro, which includes the clang version
+  /// number, the repository version, and the vendor tag.
+  std::string getClangFullCPPVersion();
+}
+
+#endif // LLVM_CLANG_BASIC_VERSION_H
diff --git a/include/clang/Basic/Version.inc b/include/clang/Basic/Version.inc
new file mode 100644
index 0000000..5d33695
--- /dev/null
+++ b/include/clang/Basic/Version.inc
@@ -0,0 +1,6 @@
+#define CLANG_VERSION 3.5.2
+#define CLANG_VERSION_MAJOR 3
+#define CLANG_VERSION_MINOR 5
+#if 1
+#define CLANG_VERSION_PATCHLEVEL 2
+#endif
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
new file mode 100644
index 0000000..54d06e0
--- /dev/null
+++ b/include/clang/Basic/VersionTuple.h
@@ -0,0 +1,134 @@
+//===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::VersionTuple class, which represents a version in
+/// the form major[.minor[.subminor]].
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
+#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Optional.h"
+#include <string>
+#include <tuple>
+
+namespace clang {
+
+/// \brief Represents a version number in the form major[.minor[.subminor]].
+class VersionTuple {
+  unsigned Major;
+  unsigned Minor : 31;
+  unsigned Subminor : 31;
+  unsigned HasMinor : 1;
+  unsigned HasSubminor : 1;
+
+public:
+  VersionTuple() 
+    : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { }
+
+  explicit VersionTuple(unsigned Major)
+    : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false)
+  { }
+
+  explicit VersionTuple(unsigned Major, unsigned Minor)
+    : Major(Major), Minor(Minor), Subminor(0), HasMinor(true), 
+      HasSubminor(false)
+  { }
+
+  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
+    : Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true), 
+      HasSubminor(true)
+  { }
+
+  /// \brief Determine whether this version information is empty
+  /// (e.g., all version components are zero).
+  bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; }
+
+  /// \brief Retrieve the major version number.
+  unsigned getMajor() const { return Major; }
+
+  /// \brief Retrieve the minor version number, if provided.
+  Optional<unsigned> getMinor() const {
+    if (!HasMinor)
+      return None;
+    return Minor;
+  }
+
+  /// \brief Retrieve the subminor version number, if provided.
+  Optional<unsigned> getSubminor() const {
+    if (!HasSubminor)
+      return None;
+    return Subminor;
+  }
+
+  /// \brief Determine if two version numbers are equivalent. If not
+  /// provided, minor and subminor version numbers are considered to be zero.
+  friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
+    return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor;
+  }
+
+  /// \brief Determine if two version numbers are not equivalent.
+  ///
+  /// If not provided, minor and subminor version numbers are considered to be 
+  /// zero.
+  friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
+    return !(X == Y);
+  }
+
+  /// \brief Determine whether one version number precedes another.
+  ///
+  /// If not provided, minor and subminor version numbers are considered to be
+  /// zero.
+  friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
+    return std::tie(X.Major, X.Minor, X.Subminor) <
+           std::tie(Y.Major, Y.Minor, Y.Subminor);
+  }
+
+  /// \brief Determine whether one version number follows another.
+  ///
+  /// If not provided, minor and subminor version numbers are considered to be
+  /// zero.
+  friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
+    return Y < X;
+  }
+
+  /// \brief Determine whether one version number precedes or is
+  /// equivalent to another. 
+  ///
+  /// If not provided, minor and subminor version numbers are considered to be
+  /// zero.
+  friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
+    return !(Y < X);
+  }
+
+  /// \brief Determine whether one version number follows or is
+  /// equivalent to another.
+  ///
+  /// If not provided, minor and subminor version numbers are considered to be
+  /// zero.
+  friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
+    return !(X < Y);
+  }
+
+  /// \brief Retrieve a string representation of the version number.
+  std::string getAsString() const;
+
+  /// \brief Try to parse the given string as a version number.
+  /// \returns \c true if the string does not match the regular expression
+  ///   [0-9]+(\.[0-9]+(\.[0-9]+))
+  bool tryParse(StringRef string);
+};
+
+/// \brief Print a version number.
+raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
+
+} // end namespace clang
+#endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
new file mode 100644
index 0000000..36f78fd
--- /dev/null
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -0,0 +1,283 @@
+//===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Defines the virtual file system interface vfs::FileSystem.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#define LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+namespace vfs {
+
+/// \brief The result of a \p status operation.
+class Status {
+  std::string Name;
+  llvm::sys::fs::UniqueID UID;
+  llvm::sys::TimeValue MTime;
+  uint32_t User;
+  uint32_t Group;
+  uint64_t Size;
+  llvm::sys::fs::file_type Type;
+  llvm::sys::fs::perms Perms;
+
+public:
+  bool IsVFSMapped; // FIXME: remove when files support multiple names
+
+public:
+  Status() : Type(llvm::sys::fs::file_type::status_error) {}
+  Status(const llvm::sys::fs::file_status &Status);
+  Status(StringRef Name, StringRef RealName, llvm::sys::fs::UniqueID UID,
+         llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
+         uint64_t Size, llvm::sys::fs::file_type Type,
+         llvm::sys::fs::perms Perms);
+
+  /// \brief Returns the name that should be used for this file or directory.
+  StringRef getName() const { return Name; }
+  void setName(StringRef N) { Name = N; }
+
+  /// @name Status interface from llvm::sys::fs
+  /// @{
+  llvm::sys::fs::file_type getType() const { return Type; }
+  llvm::sys::fs::perms getPermissions() const { return Perms; }
+  llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
+  llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
+  uint32_t getUser() const { return User; }
+  uint32_t getGroup() const { return Group; }
+  uint64_t getSize() const { return Size; }
+  void setType(llvm::sys::fs::file_type v) { Type = v; }
+  void setPermissions(llvm::sys::fs::perms p) { Perms = p; }
+  /// @}
+  /// @name Status queries
+  /// These are static queries in llvm::sys::fs.
+  /// @{
+  bool equivalent(const Status &Other) const;
+  bool isDirectory() const;
+  bool isRegularFile() const;
+  bool isOther() const;
+  bool isSymlink() const;
+  bool isStatusKnown() const;
+  bool exists() const;
+  /// @}
+};
+
+/// \brief Represents an open file.
+class File {
+public:
+  /// \brief Destroy the file after closing it (if open).
+  /// Sub-classes should generally call close() inside their destructors.  We
+  /// cannot do that from the base class, since close is virtual.
+  virtual ~File();
+  /// \brief Get the status of the file.
+  virtual llvm::ErrorOr<Status> status() = 0;
+  /// \brief Get the contents of the file as a \p MemoryBuffer.
+  virtual std::error_code getBuffer(const Twine &Name,
+                                    std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                    int64_t FileSize = -1,
+                                    bool RequiresNullTerminator = true,
+                                    bool IsVolatile = false) = 0;
+  /// \brief Closes the file.
+  virtual std::error_code close() = 0;
+  /// \brief Sets the name to use for this file.
+  virtual void setName(StringRef Name) = 0;
+};
+
+namespace detail {
+/// \brief An interface for virtual file systems to provide an iterator over the
+/// (non-recursive) contents of a directory.
+struct DirIterImpl {
+  virtual ~DirIterImpl();
+  /// \brief Sets \c CurrentEntry to the next entry in the directory on success,
+  /// or returns a system-defined \c error_code.
+  virtual std::error_code increment() = 0;
+  Status CurrentEntry;
+};
+} // end namespace detail
+
+/// \brief An input iterator over the entries in a virtual path, similar to
+/// llvm::sys::fs::directory_iterator.
+class directory_iterator {
+  std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
+
+public:
+  directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) {
+    assert(Impl.get() != nullptr && "requires non-null implementation");
+    if (!Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+  }
+
+  /// \brief Construct an 'end' iterator.
+  directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  directory_iterator &increment(std::error_code &EC) {
+    assert(Impl && "attempting to increment past end");
+    EC = Impl->increment();
+    if (EC || !Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+    return *this;
+  }
+
+  const Status &operator*() const { return Impl->CurrentEntry; }
+  const Status *operator->() const { return &Impl->CurrentEntry; }
+
+  bool operator==(const directory_iterator &RHS) const {
+    if (Impl && RHS.Impl)
+      return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
+    return !Impl && !RHS.Impl;
+  }
+  bool operator!=(const directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+class FileSystem;
+
+/// \brief An input iterator over the recursive contents of a virtual path,
+/// similar to llvm::sys::fs::recursive_directory_iterator.
+class recursive_directory_iterator {
+  typedef std::stack<directory_iterator, std::vector<directory_iterator>>
+      IterState;
+
+  FileSystem *FS;
+  std::shared_ptr<IterState> State; // Input iterator semantics on copy.
+
+public:
+  recursive_directory_iterator(FileSystem &FS, const Twine &Path,
+                               std::error_code &EC);
+  /// \brief Construct an 'end' iterator.
+  recursive_directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  recursive_directory_iterator &increment(std::error_code &EC);
+
+  const Status &operator*() const { return *State->top(); }
+  const Status *operator->() const { return &*State->top(); }
+
+  bool operator==(const recursive_directory_iterator &Other) const {
+    return State == Other.State; // identity
+  }
+  bool operator!=(const recursive_directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+/// \brief The virtual file system interface.
+class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
+public:
+  virtual ~FileSystem();
+
+  /// \brief Get the status of the entry at \p Path, if one exists.
+  virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
+  /// \brief Get a \p File object for the file at \p Path, if one exists.
+  virtual std::error_code openFileForRead(const Twine &Path,
+                                          std::unique_ptr<File> &Result) = 0;
+
+  /// This is a convenience method that opens a file, gets its content and then
+  /// closes the file.
+  std::error_code getBufferForFile(const Twine &Name,
+                                   std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                   int64_t FileSize = -1,
+                                   bool RequiresNullTerminator = true,
+                                   bool IsVolatile = false);
+
+  /// \brief Get a directory_iterator for \p Dir.
+  /// \note The 'end' iterator is directory_iterator().
+  virtual directory_iterator dir_begin(const Twine &Dir,
+                                       std::error_code &EC) = 0;
+};
+
+/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
+/// the operating system.
+IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
+
+/// \brief A file system that allows overlaying one \p AbstractFileSystem on top
+/// of another.
+///
+/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
+/// one merged file system. When there is a directory that exists in more than
+/// one file system, the \p OverlayFileSystem contains a directory containing
+/// the union of their contents.  The attributes (permissions, etc.) of the
+/// top-most (most recently added) directory are used.  When there is a file
+/// that exists in more than one file system, the file in the top-most file
+/// system overrides the other(s).
+class OverlayFileSystem : public FileSystem {
+  typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
+  /// \brief The stack of file systems, implemented as a list in order of
+  /// their addition.
+  FileSystemList FSList;
+
+public:
+  OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
+  /// \brief Pushes a file system on top of the stack.
+  void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
+
+  llvm::ErrorOr<Status> status(const Twine &Path) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
+
+  typedef FileSystemList::reverse_iterator iterator;
+  
+  /// \brief Get an iterator pointing to the most recently added file system.
+  iterator overlays_begin() { return FSList.rbegin(); }
+
+  /// \brief Get an iterator pointing one-past the least recently added file
+  /// system.
+  iterator overlays_end() { return FSList.rend(); }
+};
+
+/// \brief Get a globally unique ID for a virtual file or directory.
+llvm::sys::fs::UniqueID getNextVirtualUniqueID();
+
+/// \brief Gets a \p FileSystem for a virtual file system described in YAML
+/// format.
+///
+/// Takes ownership of \p Buffer.
+IntrusiveRefCntPtr<FileSystem>
+getVFSFromYAML(llvm::MemoryBuffer *Buffer,
+               llvm::SourceMgr::DiagHandlerTy DiagHandler,
+               void *DiagContext = nullptr,
+               IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+
+struct YAMLVFSEntry {
+  template <typename T1, typename T2> YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
+      : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
+  std::string VPath;
+  std::string RPath;
+};
+
+class YAMLVFSWriter {
+  std::vector<YAMLVFSEntry> Mappings;
+  Optional<bool> IsCaseSensitive;
+
+public:
+  YAMLVFSWriter() {}
+  void addFileMapping(StringRef VirtualPath, StringRef RealPath);
+  void setCaseSensitivity(bool CaseSensitive) {
+    IsCaseSensitive = CaseSensitive;
+  }
+  void write(llvm::raw_ostream &OS);
+};
+
+} // end namespace vfs
+} // end namespace clang
+#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h
new file mode 100644
index 0000000..6ac52ed
--- /dev/null
+++ b/include/clang/Basic/Visibility.h
@@ -0,0 +1,141 @@
+//===--- Visibility.h - Visibility enumeration and utilities ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::Visibility enumeration and various utility
+/// functions.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_VISIBILITY_H
+#define LLVM_CLANG_BASIC_VISIBILITY_H
+
+#include "clang/Basic/Linkage.h"
+
+namespace clang {
+
+/// \brief Describes the different kinds of visibility that a declaration
+/// may have.
+///
+/// Visibility determines how a declaration interacts with the dynamic
+/// linker.  It may also affect whether the symbol can be found by runtime
+/// symbol lookup APIs.
+///
+/// Visibility is not described in any language standard and
+/// (nonetheless) sometimes has odd behavior.  Not all platforms
+/// support all visibility kinds.
+enum Visibility {
+  /// Objects with "hidden" visibility are not seen by the dynamic
+  /// linker.
+  HiddenVisibility,
+
+  /// Objects with "protected" visibility are seen by the dynamic
+  /// linker but always dynamically resolve to an object within this
+  /// shared object.
+  ProtectedVisibility,
+
+  /// Objects with "default" visibility are seen by the dynamic linker
+  /// and act like normal objects.
+  DefaultVisibility
+};
+
+inline Visibility minVisibility(Visibility L, Visibility R) {
+  return L < R ? L : R;
+}
+
+class LinkageInfo {
+  uint8_t linkage_    : 3;
+  uint8_t visibility_ : 2;
+  uint8_t explicit_   : 1;
+
+  void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
+public:
+  LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
+                  explicit_(false) {}
+  LinkageInfo(Linkage L, Visibility V, bool E)
+    : linkage_(L), visibility_(V), explicit_(E) {
+    assert(getLinkage() == L && getVisibility() == V &&
+           isVisibilityExplicit() == E && "Enum truncated!");
+  }
+
+  static LinkageInfo external() {
+    return LinkageInfo();
+  }
+  static LinkageInfo internal() {
+    return LinkageInfo(InternalLinkage, DefaultVisibility, false);
+  }
+  static LinkageInfo uniqueExternal() {
+    return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
+  }
+  static LinkageInfo none() {
+    return LinkageInfo(NoLinkage, DefaultVisibility, false);
+  }
+
+  Linkage getLinkage() const { return (Linkage)linkage_; }
+  Visibility getVisibility() const { return (Visibility)visibility_; }
+  bool isVisibilityExplicit() const { return explicit_; }
+
+  void setLinkage(Linkage L) { linkage_ = L; }
+
+  void mergeLinkage(Linkage L) {
+    setLinkage(minLinkage(getLinkage(), L));
+  }
+  void mergeLinkage(LinkageInfo other) {
+    mergeLinkage(other.getLinkage());
+  }
+
+  void mergeExternalVisibility(Linkage L) {
+    Linkage ThisL = getLinkage();
+    if (!isExternallyVisible(L)) {
+      if (ThisL == VisibleNoLinkage)
+        ThisL = NoLinkage;
+      else if (ThisL == ExternalLinkage)
+        ThisL = UniqueExternalLinkage;
+    }
+    setLinkage(ThisL);
+  }
+  void mergeExternalVisibility(LinkageInfo Other) {
+    mergeExternalVisibility(Other.getLinkage());
+  }
+
+  /// Merge in the visibility 'newVis'.
+  void mergeVisibility(Visibility newVis, bool newExplicit) {
+    Visibility oldVis = getVisibility();
+
+    // Never increase visibility.
+    if (oldVis < newVis)
+      return;
+
+    // If the new visibility is the same as the old and the new
+    // visibility isn't explicit, we have nothing to add.
+    if (oldVis == newVis && !newExplicit)
+      return;
+
+    // Otherwise, we're either decreasing visibility or making our
+    // existing visibility explicit.
+    setVisibility(newVis, newExplicit);
+  }
+  void mergeVisibility(LinkageInfo other) {
+    mergeVisibility(other.getVisibility(), other.isVisibilityExplicit());
+  }
+
+  /// Merge both linkage and visibility.
+  void merge(LinkageInfo other) {
+    mergeLinkage(other);
+    mergeVisibility(other);
+  }
+
+  /// Merge linkage and conditionally merge visibility.
+  void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) {
+    mergeLinkage(other);
+    if (withVis) mergeVisibility(other);
+  }
+};
+}
+
+#endif // LLVM_CLANG_BASIC_VISIBILITY_H
diff --git a/include/clang/Basic/arm_neon.inc b/include/clang/Basic/arm_neon.inc
new file mode 100644
index 0000000..944a460
--- /dev/null
+++ b/include/clang/Basic/arm_neon.inc
@@ -0,0 +1,1149 @@
+#ifdef GET_NEON_BUILTINS
+BUILTIN(__builtin_neon_vabd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vabdd_f64, "ddd", "n")
+BUILTIN(__builtin_neon_vabdq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vabds_f32, "fff", "n")
+BUILTIN(__builtin_neon_vabs_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vabsd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vabsq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vaddd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vaddd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vaddhn_v, "V8ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vaddlv_s16, "iV4s", "n")
+BUILTIN(__builtin_neon_vaddlv_s32, "WiV2i", "n")
+BUILTIN(__builtin_neon_vaddlv_s8, "sV8Sc", "n")
+BUILTIN(__builtin_neon_vaddlv_u16, "UiV4Us", "n")
+BUILTIN(__builtin_neon_vaddlv_u32, "UWiV2Ui", "n")
+BUILTIN(__builtin_neon_vaddlv_u8, "UsV8Sc", "n")
+BUILTIN(__builtin_neon_vaddlvq_s16, "iV8s", "n")
+BUILTIN(__builtin_neon_vaddlvq_s32, "WiV4i", "n")
+BUILTIN(__builtin_neon_vaddlvq_s8, "sV16Sc", "n")
+BUILTIN(__builtin_neon_vaddlvq_u16, "UiV8Us", "n")
+BUILTIN(__builtin_neon_vaddlvq_u32, "UWiV4Ui", "n")
+BUILTIN(__builtin_neon_vaddlvq_u8, "UsV16Sc", "n")
+BUILTIN(__builtin_neon_vaddv_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vaddv_s16, "sV4s", "n")
+BUILTIN(__builtin_neon_vaddv_s32, "iV2i", "n")
+BUILTIN(__builtin_neon_vaddv_s8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vaddv_u16, "UsV4Us", "n")
+BUILTIN(__builtin_neon_vaddv_u32, "UiV2Ui", "n")
+BUILTIN(__builtin_neon_vaddv_u8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vaddvq_f32, "fV4f", "n")
+BUILTIN(__builtin_neon_vaddvq_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vaddvq_s16, "sV8s", "n")
+BUILTIN(__builtin_neon_vaddvq_s32, "iV4i", "n")
+BUILTIN(__builtin_neon_vaddvq_s64, "WiV2Wi", "n")
+BUILTIN(__builtin_neon_vaddvq_s8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vaddvq_u16, "UsV8Us", "n")
+BUILTIN(__builtin_neon_vaddvq_u32, "UiV4Ui", "n")
+BUILTIN(__builtin_neon_vaddvq_u64, "UWiV2UWi", "n")
+BUILTIN(__builtin_neon_vaddvq_u8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vaesdq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vaeseq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vaesimcq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vaesmcq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vbsl_v, "V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vbslq_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcage_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcaged_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcageq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcages_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcagt_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcagtd_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcagtq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcagts_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcale_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcaled_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcaleq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcales_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcalt_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcaltd_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcaltq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcalts_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vceqd_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vceqd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vceqd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vceqs_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vceqz_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vceqzd_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vceqzd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vceqzd_u64, "UWiUWi", "n")
+BUILTIN(__builtin_neon_vceqzq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vceqzs_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcged_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcged_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vcged_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vcges_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcgez_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcgezd_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcgezd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vcgezq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcgezs_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcgtd_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcgtd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vcgtd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vcgts_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcgtz_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcgtzd_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcgtzd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vcgtzq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcgtzs_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcled_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcled_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vcled_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vcles_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vclez_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vclezd_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vclezd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vclezq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vclezs_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcls_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vclsq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcltd_f64, "UWidd", "n")
+BUILTIN(__builtin_neon_vcltd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vcltd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vclts_f32, "Uiff", "n")
+BUILTIN(__builtin_neon_vcltz_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcltzd_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcltzd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vcltzq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcltzs_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vclz_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vclzq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcnt_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcntq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f16_v, "V8ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f32_f16, "V4fV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f32_f64, "V8ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f32_v, "V2fV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f64_f32, "V16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_f64_v, "V1dV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_n_f32_v, "V2fV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_n_f64_v, "V1dV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_n_s32_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_n_s64_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_n_u32_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_n_u64_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vcvt_s32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_s64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_u32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvt_u64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvta_s32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvta_s64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvta_u32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvta_u64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtad_s64_f64, "Wid", "n")
+BUILTIN(__builtin_neon_vcvtad_u64_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcvtaq_s32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtaq_s64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtaq_u32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtaq_u64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtas_s32_f32, "if", "n")
+BUILTIN(__builtin_neon_vcvtas_u32_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcvtd_f64_s64, "dWi", "n")
+BUILTIN(__builtin_neon_vcvtd_f64_u64, "dUWi", "n")
+BUILTIN(__builtin_neon_vcvtd_n_f64_s64, "dWii", "n")
+BUILTIN(__builtin_neon_vcvtd_n_f64_u64, "dUWii", "n")
+BUILTIN(__builtin_neon_vcvtd_n_s64_f64, "Widi", "n")
+BUILTIN(__builtin_neon_vcvtd_n_u64_f64, "UWidi", "n")
+BUILTIN(__builtin_neon_vcvtd_s64_f64, "Wid", "n")
+BUILTIN(__builtin_neon_vcvtd_u64_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcvtm_s32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtm_s64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtm_u32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtm_u64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtmd_s64_f64, "Wid", "n")
+BUILTIN(__builtin_neon_vcvtmd_u64_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcvtmq_s32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtmq_s64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtmq_u32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtmq_u64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtms_s32_f32, "if", "n")
+BUILTIN(__builtin_neon_vcvtms_u32_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcvtn_s32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtn_s64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtn_u32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtn_u64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtnd_s64_f64, "Wid", "n")
+BUILTIN(__builtin_neon_vcvtnd_u64_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcvtnq_s32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtnq_s64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtnq_u32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtnq_u64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtns_s32_f32, "if", "n")
+BUILTIN(__builtin_neon_vcvtns_u32_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcvtp_s32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtp_s64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtp_u32_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtp_u64_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vcvtpd_s64_f64, "Wid", "n")
+BUILTIN(__builtin_neon_vcvtpd_u64_f64, "UWid", "n")
+BUILTIN(__builtin_neon_vcvtpq_s32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtpq_s64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtpq_u32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtpq_u64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtps_s32_f32, "if", "n")
+BUILTIN(__builtin_neon_vcvtps_u32_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcvtq_f32_v, "V4fV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtq_f64_v, "V2dV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtq_n_f32_v, "V4fV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_n_f64_v, "V2dV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_n_s32_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_n_s64_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_n_u32_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_n_u64_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vcvtq_s32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtq_s64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtq_u32_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtq_u64_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vcvts_f32_s32, "fi", "n")
+BUILTIN(__builtin_neon_vcvts_f32_u32, "fUi", "n")
+BUILTIN(__builtin_neon_vcvts_n_f32_s32, "fii", "n")
+BUILTIN(__builtin_neon_vcvts_n_f32_u32, "fUii", "n")
+BUILTIN(__builtin_neon_vcvts_n_s32_f32, "ifi", "n")
+BUILTIN(__builtin_neon_vcvts_n_u32_f32, "Uifi", "n")
+BUILTIN(__builtin_neon_vcvts_s32_f32, "if", "n")
+BUILTIN(__builtin_neon_vcvts_u32_f32, "Uif", "n")
+BUILTIN(__builtin_neon_vcvtx_f32_v, "V2fV16Sci", "n")
+BUILTIN(__builtin_neon_vcvtxd_f32_f64, "fd", "n")
+BUILTIN(__builtin_neon_vdupb_lane_i8, "ScV8Sci", "n")
+BUILTIN(__builtin_neon_vdupb_laneq_i8, "ScV16Sci", "n")
+BUILTIN(__builtin_neon_vdupd_lane_f64, "dV1di", "n")
+BUILTIN(__builtin_neon_vdupd_lane_i64, "UWiV1Wii", "n")
+BUILTIN(__builtin_neon_vdupd_laneq_f64, "dV2di", "n")
+BUILTIN(__builtin_neon_vdupd_laneq_i64, "UWiV2Wii", "n")
+BUILTIN(__builtin_neon_vduph_lane_i16, "UsV4si", "n")
+BUILTIN(__builtin_neon_vduph_laneq_i16, "UsV8si", "n")
+BUILTIN(__builtin_neon_vdups_lane_f32, "fV2fi", "n")
+BUILTIN(__builtin_neon_vdups_lane_i32, "UiV2ii", "n")
+BUILTIN(__builtin_neon_vdups_laneq_f32, "fV4fi", "n")
+BUILTIN(__builtin_neon_vdups_laneq_i32, "UiV4ii", "n")
+BUILTIN(__builtin_neon_vext_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vextq_v, "V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vfma_lane_v, "V8ScV8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vfma_laneq_v, "V8ScV8ScV8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vfma_v, "V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vfmad_lane_f64, "dddV1di", "n")
+BUILTIN(__builtin_neon_vfmad_laneq_f64, "dddV2di", "n")
+BUILTIN(__builtin_neon_vfmaq_lane_v, "V16ScV16ScV16ScV8Scii", "n")
+BUILTIN(__builtin_neon_vfmaq_laneq_v, "V16ScV16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vfmaq_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vfmas_lane_f32, "fffV2fi", "n")
+BUILTIN(__builtin_neon_vfmas_laneq_f32, "fffV4fi", "n")
+BUILTIN(__builtin_neon_vfms_v, "V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vfmsq_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vget_lane_f32, "fV2fi", "n")
+BUILTIN(__builtin_neon_vget_lane_f64, "dV1di", "n")
+BUILTIN(__builtin_neon_vget_lane_i16, "UsV4si", "n")
+BUILTIN(__builtin_neon_vget_lane_i32, "UiV2ii", "n")
+BUILTIN(__builtin_neon_vget_lane_i64, "UWiV1Wii", "n")
+BUILTIN(__builtin_neon_vget_lane_i8, "ScV8Sci", "n")
+BUILTIN(__builtin_neon_vgetq_lane_f32, "fV4fi", "n")
+BUILTIN(__builtin_neon_vgetq_lane_f64, "dV2di", "n")
+BUILTIN(__builtin_neon_vgetq_lane_i16, "UsV8si", "n")
+BUILTIN(__builtin_neon_vgetq_lane_i32, "UiV4ii", "n")
+BUILTIN(__builtin_neon_vgetq_lane_i64, "UWiV2Wii", "n")
+BUILTIN(__builtin_neon_vgetq_lane_i8, "ScV16Sci", "n")
+BUILTIN(__builtin_neon_vhadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vhaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vhsub_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vhsubq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vld1_dup_v, "V8ScvC*i", "n")
+BUILTIN(__builtin_neon_vld1_lane_v, "V8ScvC*V8Scii", "n")
+BUILTIN(__builtin_neon_vld1_v, "V8ScvC*i", "n")
+BUILTIN(__builtin_neon_vld1_x2_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld1_x3_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld1_x4_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld1q_dup_v, "V16ScvC*i", "n")
+BUILTIN(__builtin_neon_vld1q_lane_v, "V16ScvC*V16Scii", "n")
+BUILTIN(__builtin_neon_vld1q_v, "V16ScvC*i", "n")
+BUILTIN(__builtin_neon_vld1q_x2_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld1q_x3_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld1q_x4_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld2_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld2_lane_v, "vv*vC*V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vld2_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld2q_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld2q_lane_v, "vv*vC*V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vld2q_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld3_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld3_lane_v, "vv*vC*V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vld3_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld3q_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld3q_lane_v, "vv*vC*V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vld3q_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld4_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld4_lane_v, "vv*vC*V8ScV8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vld4_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld4q_dup_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vld4q_lane_v, "vv*vC*V16ScV16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vld4q_v, "vv*vC*i", "n")
+BUILTIN(__builtin_neon_vldrq_p128, "ULLLivC*", "n")
+BUILTIN(__builtin_neon_vmax_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmaxnm_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmaxnmq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vmaxnmv_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vmaxnmvq_f32, "fV4f", "n")
+BUILTIN(__builtin_neon_vmaxnmvq_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vmaxq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vmaxv_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vmaxv_s16, "sV4s", "n")
+BUILTIN(__builtin_neon_vmaxv_s32, "iV2i", "n")
+BUILTIN(__builtin_neon_vmaxv_s8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vmaxv_u16, "UsV4Us", "n")
+BUILTIN(__builtin_neon_vmaxv_u32, "UiV2Ui", "n")
+BUILTIN(__builtin_neon_vmaxv_u8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vmaxvq_f32, "fV4f", "n")
+BUILTIN(__builtin_neon_vmaxvq_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vmaxvq_s16, "sV8s", "n")
+BUILTIN(__builtin_neon_vmaxvq_s32, "iV4i", "n")
+BUILTIN(__builtin_neon_vmaxvq_s8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vmaxvq_u16, "UsV8Us", "n")
+BUILTIN(__builtin_neon_vmaxvq_u32, "UiV4Ui", "n")
+BUILTIN(__builtin_neon_vmaxvq_u8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vmin_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vminnm_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vminnmq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vminnmv_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vminnmvq_f32, "fV4f", "n")
+BUILTIN(__builtin_neon_vminnmvq_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vminq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vminv_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vminv_s16, "sV4s", "n")
+BUILTIN(__builtin_neon_vminv_s32, "iV2i", "n")
+BUILTIN(__builtin_neon_vminv_s8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vminv_u16, "UsV4Us", "n")
+BUILTIN(__builtin_neon_vminv_u32, "UiV2Ui", "n")
+BUILTIN(__builtin_neon_vminv_u8, "ScV8Sc", "n")
+BUILTIN(__builtin_neon_vminvq_f32, "fV4f", "n")
+BUILTIN(__builtin_neon_vminvq_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vminvq_s16, "sV8s", "n")
+BUILTIN(__builtin_neon_vminvq_s32, "iV4i", "n")
+BUILTIN(__builtin_neon_vminvq_s8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vminvq_u16, "UsV8Us", "n")
+BUILTIN(__builtin_neon_vminvq_u32, "UiV4Ui", "n")
+BUILTIN(__builtin_neon_vminvq_u8, "ScV16Sc", "n")
+BUILTIN(__builtin_neon_vmovl_v, "V16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmovn_v, "V8ScV16Sci", "n")
+BUILTIN(__builtin_neon_vmul_lane_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vmul_laneq_v, "V8ScV8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vmul_n_f64, "V1dV1dd", "n")
+BUILTIN(__builtin_neon_vmul_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmull_p64, "ULLLiUWiUWi", "n")
+BUILTIN(__builtin_neon_vmull_v, "V16ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmulq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vmulx_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vmulxd_f64, "ddd", "n")
+BUILTIN(__builtin_neon_vmulxq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vmulxs_f32, "fff", "n")
+BUILTIN(__builtin_neon_vnegd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vpadal_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpadalq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpaddd_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vpaddd_s64, "WiV2Wi", "n")
+BUILTIN(__builtin_neon_vpaddd_u64, "UWiV2UWi", "n")
+BUILTIN(__builtin_neon_vpaddl_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpaddlq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpadds_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vpmax_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpmaxnm_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpmaxnmq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpmaxnmqd_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vpmaxnms_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vpmaxq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpmaxqd_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vpmaxs_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vpmin_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpminnm_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vpminnmq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpminnmqd_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vpminnms_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vpminq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vpminqd_f64, "dV2d", "n")
+BUILTIN(__builtin_neon_vpmins_f32, "fV2f", "n")
+BUILTIN(__builtin_neon_vqabs_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqabsb_s8, "ScSc", "n")
+BUILTIN(__builtin_neon_vqabsd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vqabsh_s16, "ss", "n")
+BUILTIN(__builtin_neon_vqabsq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqabss_s32, "ii", "n")
+BUILTIN(__builtin_neon_vqadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqaddb_s8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqaddb_u8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqaddd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vqaddd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vqaddh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqaddh_u16, "UsUsUs", "n")
+BUILTIN(__builtin_neon_vqaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqadds_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqadds_u32, "UiUiUi", "n")
+BUILTIN(__builtin_neon_vqdmlal_v, "V16ScV16ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqdmlalh_lane_s16, "iisV4si", "n")
+BUILTIN(__builtin_neon_vqdmlalh_laneq_s16, "iisV8si", "n")
+BUILTIN(__builtin_neon_vqdmlalh_s16, "iiss", "n")
+BUILTIN(__builtin_neon_vqdmlals_lane_s32, "WiWiiV2ii", "n")
+BUILTIN(__builtin_neon_vqdmlals_laneq_s32, "WiWiiV4ii", "n")
+BUILTIN(__builtin_neon_vqdmlals_s32, "WiWiii", "n")
+BUILTIN(__builtin_neon_vqdmlsl_v, "V16ScV16ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqdmlslh_lane_s16, "iisV4si", "n")
+BUILTIN(__builtin_neon_vqdmlslh_laneq_s16, "iisV8si", "n")
+BUILTIN(__builtin_neon_vqdmlslh_s16, "iiss", "n")
+BUILTIN(__builtin_neon_vqdmlsls_lane_s32, "WiWiiV2ii", "n")
+BUILTIN(__builtin_neon_vqdmlsls_laneq_s32, "WiWiiV4ii", "n")
+BUILTIN(__builtin_neon_vqdmlsls_s32, "WiWiii", "n")
+BUILTIN(__builtin_neon_vqdmulh_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqdmulhh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqdmulhq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqdmulhs_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqdmull_v, "V16ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqdmullh_s16, "iss", "n")
+BUILTIN(__builtin_neon_vqdmulls_s32, "Wiii", "n")
+BUILTIN(__builtin_neon_vqmovn_v, "V8ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqmovnd_s64, "iWi", "n")
+BUILTIN(__builtin_neon_vqmovnd_u64, "UiUWi", "n")
+BUILTIN(__builtin_neon_vqmovnh_s16, "Scs", "n")
+BUILTIN(__builtin_neon_vqmovnh_u16, "ScUs", "n")
+BUILTIN(__builtin_neon_vqmovns_s32, "si", "n")
+BUILTIN(__builtin_neon_vqmovns_u32, "UsUi", "n")
+BUILTIN(__builtin_neon_vqmovun_v, "V8ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqmovund_s64, "iWi", "n")
+BUILTIN(__builtin_neon_vqmovunh_s16, "Scs", "n")
+BUILTIN(__builtin_neon_vqmovuns_s32, "si", "n")
+BUILTIN(__builtin_neon_vqneg_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqnegb_s8, "ScSc", "n")
+BUILTIN(__builtin_neon_vqnegd_s64, "WiWi", "n")
+BUILTIN(__builtin_neon_vqnegh_s16, "ss", "n")
+BUILTIN(__builtin_neon_vqnegq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqnegs_s32, "ii", "n")
+BUILTIN(__builtin_neon_vqrdmulh_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqrdmulhh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqrdmulhq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqrdmulhs_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqrshl_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqrshlb_s8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqrshlb_u8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqrshld_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vqrshld_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vqrshlh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqrshlh_u16, "UsUsUs", "n")
+BUILTIN(__builtin_neon_vqrshlq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqrshls_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqrshls_u32, "UiUiUi", "n")
+BUILTIN(__builtin_neon_vqrshrn_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqrshrnd_n_s64, "iWii", "n")
+BUILTIN(__builtin_neon_vqrshrnd_n_u64, "UiUWii", "n")
+BUILTIN(__builtin_neon_vqrshrnh_n_s16, "Scsi", "n")
+BUILTIN(__builtin_neon_vqrshrnh_n_u16, "ScUsi", "n")
+BUILTIN(__builtin_neon_vqrshrns_n_s32, "sii", "n")
+BUILTIN(__builtin_neon_vqrshrns_n_u32, "UsUii", "n")
+BUILTIN(__builtin_neon_vqrshrun_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqrshrund_n_s64, "iWii", "n")
+BUILTIN(__builtin_neon_vqrshrunh_n_s16, "Scsi", "n")
+BUILTIN(__builtin_neon_vqrshruns_n_s32, "sii", "n")
+BUILTIN(__builtin_neon_vqshl_n_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vqshl_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqshlb_n_s8, "ScSci", "n")
+BUILTIN(__builtin_neon_vqshlb_n_u8, "ScSci", "n")
+BUILTIN(__builtin_neon_vqshlb_s8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqshlb_u8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqshld_n_s64, "WiWii", "n")
+BUILTIN(__builtin_neon_vqshld_n_u64, "UWiUWii", "n")
+BUILTIN(__builtin_neon_vqshld_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vqshld_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vqshlh_n_s16, "ssi", "n")
+BUILTIN(__builtin_neon_vqshlh_n_u16, "UsUsi", "n")
+BUILTIN(__builtin_neon_vqshlh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqshlh_u16, "UsUsUs", "n")
+BUILTIN(__builtin_neon_vqshlq_n_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqshlq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqshls_n_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqshls_n_u32, "UiUii", "n")
+BUILTIN(__builtin_neon_vqshls_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqshls_u32, "UiUiUi", "n")
+BUILTIN(__builtin_neon_vqshlu_n_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vqshlub_n_s8, "ScSci", "n")
+BUILTIN(__builtin_neon_vqshlud_n_s64, "WiWii", "n")
+BUILTIN(__builtin_neon_vqshluh_n_s16, "ssi", "n")
+BUILTIN(__builtin_neon_vqshluq_n_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqshlus_n_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqshrn_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqshrnd_n_s64, "iWii", "n")
+BUILTIN(__builtin_neon_vqshrnd_n_u64, "UiUWii", "n")
+BUILTIN(__builtin_neon_vqshrnh_n_s16, "Scsi", "n")
+BUILTIN(__builtin_neon_vqshrnh_n_u16, "ScUsi", "n")
+BUILTIN(__builtin_neon_vqshrns_n_s32, "sii", "n")
+BUILTIN(__builtin_neon_vqshrns_n_u32, "UsUii", "n")
+BUILTIN(__builtin_neon_vqshrun_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vqshrund_n_s64, "iWii", "n")
+BUILTIN(__builtin_neon_vqshrunh_n_s16, "Scsi", "n")
+BUILTIN(__builtin_neon_vqshruns_n_s32, "sii", "n")
+BUILTIN(__builtin_neon_vqsub_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqsubb_s8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqsubb_u8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vqsubd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vqsubd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vqsubh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vqsubh_u16, "UsUsUs", "n")
+BUILTIN(__builtin_neon_vqsubq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqsubs_s32, "iii", "n")
+BUILTIN(__builtin_neon_vqsubs_u32, "UiUiUi", "n")
+BUILTIN(__builtin_neon_vqtbl1_v, "V8ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbl1q_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbl2_v, "V8ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbl2q_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbl3_v, "V8ScV16ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbl3q_v, "V16ScV16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbl4_v, "V8ScV16ScV16ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbl4q_v, "V16ScV16ScV16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbx1_v, "V8ScV8ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbx1q_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbx2_v, "V8ScV8ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbx2q_v, "V16ScV16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbx3_v, "V8ScV8ScV16ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbx3q_v, "V16ScV16ScV16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vqtbx4_v, "V8ScV8ScV16ScV16ScV16ScV16ScV8Sci", "n")
+BUILTIN(__builtin_neon_vqtbx4q_v, "V16ScV16ScV16ScV16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vraddhn_v, "V8ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrbit_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrbitq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrecpe_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrecped_f64, "dd", "n")
+BUILTIN(__builtin_neon_vrecpeq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrecpes_f32, "ff", "n")
+BUILTIN(__builtin_neon_vrecps_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrecpsd_f64, "ddd", "n")
+BUILTIN(__builtin_neon_vrecpsq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrecpss_f32, "fff", "n")
+BUILTIN(__builtin_neon_vrecpxd_f64, "dd", "n")
+BUILTIN(__builtin_neon_vrecpxs_f32, "ff", "n")
+BUILTIN(__builtin_neon_vrhadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrhaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrnd_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrnda_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndaq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndi_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndiq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndm_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndmq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndn_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndnq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndp_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndpq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrndx_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrndxq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrshl_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrshld_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vrshld_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vrshlq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrshr_n_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vrshrd_n_s64, "WiWii", "n")
+BUILTIN(__builtin_neon_vrshrd_n_u64, "UWiUWii", "n")
+BUILTIN(__builtin_neon_vrshrn_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vrshrq_n_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vrsqrte_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrsqrted_f64, "dd", "n")
+BUILTIN(__builtin_neon_vrsqrteq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrsqrtes_f32, "ff", "n")
+BUILTIN(__builtin_neon_vrsqrts_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vrsqrtsd_f64, "ddd", "n")
+BUILTIN(__builtin_neon_vrsqrtsq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vrsqrtss_f32, "fff", "n")
+BUILTIN(__builtin_neon_vrsra_n_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vrsrad_n_s64, "WiWiWii", "n")
+BUILTIN(__builtin_neon_vrsrad_n_u64, "UWiUWiUWii", "n")
+BUILTIN(__builtin_neon_vrsraq_n_v, "V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vrsubhn_v, "V8ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vset_lane_f32, "V2ffV2fi", "n")
+BUILTIN(__builtin_neon_vset_lane_f64, "V1ddV1di", "n")
+BUILTIN(__builtin_neon_vset_lane_i16, "V4ssV4si", "n")
+BUILTIN(__builtin_neon_vset_lane_i32, "V2iiV2ii", "n")
+BUILTIN(__builtin_neon_vset_lane_i64, "V1WiWiV1Wii", "n")
+BUILTIN(__builtin_neon_vset_lane_i8, "V8ScScV8Sci", "n")
+BUILTIN(__builtin_neon_vsetq_lane_f32, "V4ffV4fi", "n")
+BUILTIN(__builtin_neon_vsetq_lane_f64, "V2ddV2di", "n")
+BUILTIN(__builtin_neon_vsetq_lane_i16, "V8ssV8si", "n")
+BUILTIN(__builtin_neon_vsetq_lane_i32, "V4iiV4ii", "n")
+BUILTIN(__builtin_neon_vsetq_lane_i64, "V2WiWiV2Wii", "n")
+BUILTIN(__builtin_neon_vsetq_lane_i8, "V16ScScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha1cq_u32, "V4iV4UiUiV4Ui", "n")
+BUILTIN(__builtin_neon_vsha1h_u32, "UiUi", "n")
+BUILTIN(__builtin_neon_vsha1mq_u32, "V4iV4UiUiV4Ui", "n")
+BUILTIN(__builtin_neon_vsha1pq_u32, "V4iV4UiUiV4Ui", "n")
+BUILTIN(__builtin_neon_vsha1su0q_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha1su1q_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha256h2q_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha256hq_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha256su0q_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsha256su1q_v, "V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vshl_n_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vshl_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vshld_n_s64, "WiWii", "n")
+BUILTIN(__builtin_neon_vshld_n_u64, "UWiUWii", "n")
+BUILTIN(__builtin_neon_vshld_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vshld_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vshll_n_v, "V16ScV8Scii", "n")
+BUILTIN(__builtin_neon_vshlq_n_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vshlq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vshr_n_v, "V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vshrd_n_s64, "WiWii", "n")
+BUILTIN(__builtin_neon_vshrd_n_u64, "UWiUWii", "n")
+BUILTIN(__builtin_neon_vshrn_n_v, "V8ScV16Scii", "n")
+BUILTIN(__builtin_neon_vshrq_n_v, "V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vsli_n_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vslid_n_s64, "WiWiWii", "n")
+BUILTIN(__builtin_neon_vslid_n_u64, "UWiUWiUWii", "n")
+BUILTIN(__builtin_neon_vsliq_n_v, "V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vsqadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vsqaddb_u8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vsqaddd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vsqaddh_u16, "UsUsUs", "n")
+BUILTIN(__builtin_neon_vsqaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsqadds_u32, "UiUiUi", "n")
+BUILTIN(__builtin_neon_vsqrt_v, "V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vsqrtq_v, "V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vsra_n_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vsrad_n_s64, "WiWiWii", "n")
+BUILTIN(__builtin_neon_vsrad_n_u64, "UWiUWiUWii", "n")
+BUILTIN(__builtin_neon_vsraq_n_v, "V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vsri_n_v, "V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vsrid_n_s64, "WiWiWii", "n")
+BUILTIN(__builtin_neon_vsrid_n_u64, "UWiUWiUWii", "n")
+BUILTIN(__builtin_neon_vsriq_n_v, "V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vst1_lane_v, "vv*V8Scii", "n")
+BUILTIN(__builtin_neon_vst1_v, "vv*V8Sci", "n")
+BUILTIN(__builtin_neon_vst1_x2_v, "vv*V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst1_x3_v, "vv*V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst1_x4_v, "vv*V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst1q_lane_v, "vv*V16Scii", "n")
+BUILTIN(__builtin_neon_vst1q_v, "vv*V16Sci", "n")
+BUILTIN(__builtin_neon_vst1q_x2_v, "vv*V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vst1q_x3_v, "vv*V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vst1q_x4_v, "vv*V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vst2_lane_v, "vv*V8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vst2_v, "vv*V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst2q_lane_v, "vv*V16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vst2q_v, "vv*V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vst3_lane_v, "vv*V8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vst3_v, "vv*V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst3q_lane_v, "vv*V16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vst3q_v, "vv*V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vst4_lane_v, "vv*V8ScV8ScV8ScV8Scii", "n")
+BUILTIN(__builtin_neon_vst4_v, "vv*V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vst4q_lane_v, "vv*V16ScV16ScV16ScV16Scii", "n")
+BUILTIN(__builtin_neon_vst4q_v, "vv*V16ScV16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vstrq_p128, "vv*ULLLi", "n")
+BUILTIN(__builtin_neon_vsubd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vsubd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vsubhn_v, "V8ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vtbl1_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbl2_v, "V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbl3_v, "V8ScV8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbl4_v, "V8ScV8ScV8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbx1_v, "V8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbx2_v, "V8ScV8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbx3_v, "V8ScV8ScV8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtbx4_v, "V8ScV8ScV8ScV8ScV8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtrn_v, "vv*V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtrnq_v, "vv*V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vtst_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vtstd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vtstd_u64, "UWiUWiUWi", "n")
+BUILTIN(__builtin_neon_vtstq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vuqadd_v, "V8ScV8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vuqaddb_s8, "ScScSc", "n")
+BUILTIN(__builtin_neon_vuqaddd_s64, "WiWiWi", "n")
+BUILTIN(__builtin_neon_vuqaddh_s16, "sss", "n")
+BUILTIN(__builtin_neon_vuqaddq_v, "V16ScV16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vuqadds_s32, "iii", "n")
+BUILTIN(__builtin_neon_vuzp_v, "vv*V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vuzpq_v, "vv*V16ScV16Sci", "n")
+BUILTIN(__builtin_neon_vzip_v, "vv*V8ScV8Sci", "n")
+BUILTIN(__builtin_neon_vzipq_v, "vv*V16ScV16Sci", "n")
+#endif
+
+#ifdef GET_NEON_OVERLOAD_CHECK
+case NEON::BI__builtin_neon_vabd_v: mask = 0x70607ULL; break;
+case NEON::BI__builtin_neon_vabdq_v: mask = 0x7060700000000ULL; break;
+case NEON::BI__builtin_neon_vabs_v: mask = 0x60FULL; break;
+case NEON::BI__builtin_neon_vabsq_v: mask = 0x60F00000000ULL; break;
+case NEON::BI__builtin_neon_vaddhn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vaesdq_v: mask = 0x1000000000000ULL; break;
+case NEON::BI__builtin_neon_vaeseq_v: mask = 0x1000000000000ULL; break;
+case NEON::BI__builtin_neon_vaesimcq_v: mask = 0x1000000000000ULL; break;
+case NEON::BI__builtin_neon_vaesmcq_v: mask = 0x1000000000000ULL; break;
+case NEON::BI__builtin_neon_vbsl_v: mask = 0xF067FULL; break;
+case NEON::BI__builtin_neon_vbslq_v: mask = 0xF067F00000000ULL; break;
+case NEON::BI__builtin_neon_vcage_v: mask = 0xC0000ULL; break;
+case NEON::BI__builtin_neon_vcageq_v: mask = 0xC000000000000ULL; break;
+case NEON::BI__builtin_neon_vcagt_v: mask = 0xC0000ULL; break;
+case NEON::BI__builtin_neon_vcagtq_v: mask = 0xC000000000000ULL; break;
+case NEON::BI__builtin_neon_vcale_v: mask = 0xC0000ULL; break;
+case NEON::BI__builtin_neon_vcaleq_v: mask = 0xC000000000000ULL; break;
+case NEON::BI__builtin_neon_vcalt_v: mask = 0xC0000ULL; break;
+case NEON::BI__builtin_neon_vcaltq_v: mask = 0xC000000000000ULL; break;
+case NEON::BI__builtin_neon_vceqz_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vceqzq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vcgez_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vcgezq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vcgtz_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vcgtzq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vclez_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vclezq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vcls_v: mask = 0x7ULL; break;
+case NEON::BI__builtin_neon_vclsq_v: mask = 0x700000000ULL; break;
+case NEON::BI__builtin_neon_vcltz_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vcltzq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vclz_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vclzq_v: mask = 0x7000700000000ULL; break;
+case NEON::BI__builtin_neon_vcnt_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vcntq_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vcvt_f16_v: mask = 0x100ULL; break;
+case NEON::BI__builtin_neon_vcvt_f32_f16: mask = 0x100ULL; break;
+case NEON::BI__builtin_neon_vcvt_f32_f64: mask = 0x200ULL; break;
+case NEON::BI__builtin_neon_vcvt_f32_v: mask = 0x40004ULL; break;
+case NEON::BI__builtin_neon_vcvt_f64_f32: mask = 0x40000000000ULL; break;
+case NEON::BI__builtin_neon_vcvt_f64_v: mask = 0x80008ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_f32_v: mask = 0x40004ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_f64_v: mask = 0x80008ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvt_n_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvt_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvt_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvt_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvt_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvta_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvta_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvta_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvta_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvtaq_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtaq_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtaq_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtaq_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtm_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvtm_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvtm_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvtm_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvtmq_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtmq_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtmq_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtmq_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtn_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvtn_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvtn_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvtn_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvtnq_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtnq_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtnq_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtnq_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtp_s32_v: mask = 0x4ULL; break;
+case NEON::BI__builtin_neon_vcvtp_s64_v: mask = 0x8ULL; break;
+case NEON::BI__builtin_neon_vcvtp_u32_v: mask = 0x40000ULL; break;
+case NEON::BI__builtin_neon_vcvtp_u64_v: mask = 0x80000ULL; break;
+case NEON::BI__builtin_neon_vcvtpq_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtpq_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtpq_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtpq_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_f32_v: mask = 0x4000400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_f64_v: mask = 0x8000800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_f32_v: mask = 0x4000400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_f64_v: mask = 0x8000800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_n_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_s32_v: mask = 0x400000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_s64_v: mask = 0x800000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_u32_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtq_u64_v: mask = 0x8000000000000ULL; break;
+case NEON::BI__builtin_neon_vcvtx_f32_v: mask = 0x40000000000ULL; break;
+case NEON::BI__builtin_neon_vext_v: mask = 0xF067FULL; break;
+case NEON::BI__builtin_neon_vextq_v: mask = 0xF067F00000000ULL; break;
+case NEON::BI__builtin_neon_vfma_lane_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vfma_laneq_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vfma_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vfmaq_lane_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vfmaq_laneq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vfmaq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vfms_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vfmsq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vhadd_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vhaddq_v: mask = 0x7000700000000ULL; break;
+case NEON::BI__builtin_neon_vhsub_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vhsubq_v: mask = 0x7000700000000ULL; break;
+case NEON::BI__builtin_neon_vld1_dup_v: mask = 0xF077FULL; break;
+case NEON::BI__builtin_neon_vld1_lane_v: mask = 0xF077FULL; break;
+case NEON::BI__builtin_neon_vld1_v: mask = 0xF077FULL; PtrArgNum = 0; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1_x2_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1_x3_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1_x4_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1q_dup_v: mask = 0xF077F00000000ULL; break;
+case NEON::BI__builtin_neon_vld1q_lane_v: mask = 0xF077F00000000ULL; break;
+case NEON::BI__builtin_neon_vld1q_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1q_x2_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1q_x3_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld1q_x4_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2_dup_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2_lane_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2q_dup_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld2q_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3_dup_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3_lane_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3q_dup_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld3q_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4_dup_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4_lane_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4_v: mask = 0xF077FULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4q_dup_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vld4q_v: mask = 0xF077F00000000ULL; PtrArgNum = 1; HasConstPtr = true; break;
+case NEON::BI__builtin_neon_vmax_v: mask = 0x70607ULL; break;
+case NEON::BI__builtin_neon_vmaxnm_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vmaxnmq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vmaxq_v: mask = 0x7060700000000ULL; break;
+case NEON::BI__builtin_neon_vmin_v: mask = 0x70607ULL; break;
+case NEON::BI__builtin_neon_vminnm_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vminnmq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vminq_v: mask = 0x7060700000000ULL; break;
+case NEON::BI__builtin_neon_vmovl_v: mask = 0xE000E00000000ULL; break;
+case NEON::BI__builtin_neon_vmovn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vmul_lane_v: mask = 0x400ULL; break;
+case NEON::BI__builtin_neon_vmul_laneq_v: mask = 0x400ULL; break;
+case NEON::BI__builtin_neon_vmul_v: mask = 0x10ULL; break;
+case NEON::BI__builtin_neon_vmull_v: mask = 0xE002E00000000ULL; break;
+case NEON::BI__builtin_neon_vmulq_v: mask = 0x1000000000ULL; break;
+case NEON::BI__builtin_neon_vmulx_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vmulxq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vpadal_v: mask = 0xE000EULL; break;
+case NEON::BI__builtin_neon_vpadalq_v: mask = 0xE000E00000000ULL; break;
+case NEON::BI__builtin_neon_vpadd_v: mask = 0x70207ULL; break;
+case NEON::BI__builtin_neon_vpaddl_v: mask = 0xE000EULL; break;
+case NEON::BI__builtin_neon_vpaddlq_v: mask = 0xE000E00000000ULL; break;
+case NEON::BI__builtin_neon_vpaddq_v: mask = 0xF060F00000000ULL; break;
+case NEON::BI__builtin_neon_vpmax_v: mask = 0x70207ULL; break;
+case NEON::BI__builtin_neon_vpmaxnm_v: mask = 0x200ULL; break;
+case NEON::BI__builtin_neon_vpmaxnmq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vpmaxq_v: mask = 0x7060700000000ULL; break;
+case NEON::BI__builtin_neon_vpmin_v: mask = 0x70207ULL; break;
+case NEON::BI__builtin_neon_vpminnm_v: mask = 0x200ULL; break;
+case NEON::BI__builtin_neon_vpminnmq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vpminq_v: mask = 0x7060700000000ULL; break;
+case NEON::BI__builtin_neon_vqabs_v: mask = 0xFULL; break;
+case NEON::BI__builtin_neon_vqabsq_v: mask = 0xF00000000ULL; break;
+case NEON::BI__builtin_neon_vqadd_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vqaddq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vqdmlal_v: mask = 0xC00000000ULL; break;
+case NEON::BI__builtin_neon_vqdmlsl_v: mask = 0xC00000000ULL; break;
+case NEON::BI__builtin_neon_vqdmulh_v: mask = 0x6ULL; break;
+case NEON::BI__builtin_neon_vqdmulhq_v: mask = 0x600000000ULL; break;
+case NEON::BI__builtin_neon_vqdmull_v: mask = 0xC00000000ULL; break;
+case NEON::BI__builtin_neon_vqmovn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vqmovun_v: mask = 0x70000ULL; break;
+case NEON::BI__builtin_neon_vqneg_v: mask = 0xFULL; break;
+case NEON::BI__builtin_neon_vqnegq_v: mask = 0xF00000000ULL; break;
+case NEON::BI__builtin_neon_vqrdmulh_v: mask = 0x6ULL; break;
+case NEON::BI__builtin_neon_vqrdmulhq_v: mask = 0x600000000ULL; break;
+case NEON::BI__builtin_neon_vqrshl_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vqrshlq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vqrshrn_n_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vqrshrun_n_v: mask = 0x70000ULL; break;
+case NEON::BI__builtin_neon_vqshl_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vqshl_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vqshlq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vqshlq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vqshlu_n_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vqshluq_n_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vqshrn_n_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vqshrun_n_v: mask = 0x70000ULL; break;
+case NEON::BI__builtin_neon_vqsub_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vqsubq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vqtbl1_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbl1q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbl2_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbl2q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbl3_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbl3q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbl4_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbl4q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbx1_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbx1q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbx2_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbx2q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbx3_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbx3q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vqtbx4_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vqtbx4q_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vraddhn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vrbit_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vrbitq_v: mask = 0x1001100000000ULL; break;
+case NEON::BI__builtin_neon_vrecpe_v: mask = 0x40600ULL; break;
+case NEON::BI__builtin_neon_vrecpeq_v: mask = 0x4060000000000ULL; break;
+case NEON::BI__builtin_neon_vrecps_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrecpsq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrhadd_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vrhaddq_v: mask = 0x7000700000000ULL; break;
+case NEON::BI__builtin_neon_vrnd_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrnda_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndaq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndi_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndiq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndm_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndmq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndn_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndnq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndp_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndpq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrndx_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrndxq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrshl_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vrshlq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vrshr_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vrshrn_n_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vrshrq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vrsqrte_v: mask = 0x40600ULL; break;
+case NEON::BI__builtin_neon_vrsqrteq_v: mask = 0x4060000000000ULL; break;
+case NEON::BI__builtin_neon_vrsqrts_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vrsqrtsq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vrsra_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vrsraq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vrsubhn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vsha1su0q_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vsha1su1q_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vsha256h2q_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vsha256hq_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vsha256su0q_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vsha256su1q_v: mask = 0x4000000000000ULL; break;
+case NEON::BI__builtin_neon_vshl_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vshl_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vshll_n_v: mask = 0xE000E00000000ULL; break;
+case NEON::BI__builtin_neon_vshlq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vshlq_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vshr_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vshrn_n_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vshrq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vsli_n_v: mask = 0xF007FULL; break;
+case NEON::BI__builtin_neon_vsliq_n_v: mask = 0xF007F00000000ULL; break;
+case NEON::BI__builtin_neon_vsqadd_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vsqaddq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vsqrt_v: mask = 0x600ULL; break;
+case NEON::BI__builtin_neon_vsqrtq_v: mask = 0x60000000000ULL; break;
+case NEON::BI__builtin_neon_vsra_n_v: mask = 0xF000FULL; break;
+case NEON::BI__builtin_neon_vsraq_n_v: mask = 0xF000F00000000ULL; break;
+case NEON::BI__builtin_neon_vsri_n_v: mask = 0xF007FULL; break;
+case NEON::BI__builtin_neon_vsriq_n_v: mask = 0xF007F00000000ULL; break;
+case NEON::BI__builtin_neon_vst1_lane_v: mask = 0xF077FULL; break;
+case NEON::BI__builtin_neon_vst1_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1_x2_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1_x3_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1_x4_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1q_lane_v: mask = 0xF077F00000000ULL; break;
+case NEON::BI__builtin_neon_vst1q_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1q_x2_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1q_x3_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst1q_x4_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst2_lane_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst2_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst2q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst2q_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst3_lane_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst3_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst3q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst3q_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst4_lane_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst4_v: mask = 0xF077FULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst4q_lane_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vst4q_v: mask = 0xF077F00000000ULL; PtrArgNum = 0; break;
+case NEON::BI__builtin_neon_vsubhn_v: mask = 0x70007ULL; break;
+case NEON::BI__builtin_neon_vtbl1_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbl2_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbl3_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbl4_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbx1_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbx2_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbx3_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtbx4_v: mask = 0x10011ULL; break;
+case NEON::BI__builtin_neon_vtrn_v: mask = 0x70237ULL; break;
+case NEON::BI__builtin_neon_vtrnq_v: mask = 0x7023700000000ULL; break;
+case NEON::BI__builtin_neon_vtst_v: mask = 0xF0000ULL; break;
+case NEON::BI__builtin_neon_vtstq_v: mask = 0xF000000000000ULL; break;
+case NEON::BI__builtin_neon_vuqadd_v: mask = 0xFULL; break;
+case NEON::BI__builtin_neon_vuqaddq_v: mask = 0xF00000000ULL; break;
+case NEON::BI__builtin_neon_vuzp_v: mask = 0x70237ULL; break;
+case NEON::BI__builtin_neon_vuzpq_v: mask = 0x7023700000000ULL; break;
+case NEON::BI__builtin_neon_vzip_v: mask = 0x70237ULL; break;
+case NEON::BI__builtin_neon_vzipq_v: mask = 0x7023700000000ULL; break;
+#endif
+
+#ifdef GET_NEON_IMMEDIATE_CHECK
+case NEON::BI__builtin_neon_vcvtq_n_f64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvt_n_f64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvtq_n_s64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvt_n_s64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvtq_n_u64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvt_n_u64_v: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vget_lane_i64: i = 1; u = 0; break;
+case NEON::BI__builtin_neon_vgetq_lane_i64: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vgetq_lane_f64: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vget_lane_f64: i = 1; u = 0; break;
+case NEON::BI__builtin_neon_vld1_lane_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld1q_lane_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld2_lane_v: i = 4; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld2q_lane_v: i = 4; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld3_lane_v: i = 5; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld3q_lane_v: i = 5; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld4_lane_v: i = 6; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vld4q_lane_v: i = 6; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vcvts_n_s32_f32: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvtd_n_s64_f64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvts_n_u32_f32: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvtd_n_u64_f64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vfmad_lane_f64: i = 3; u = 0; break;
+case NEON::BI__builtin_neon_vfmas_lane_f32: i = 3; u = 1; break;
+case NEON::BI__builtin_neon_vfmad_laneq_f64: i = 3; u = 1; break;
+case NEON::BI__builtin_neon_vfmas_laneq_f32: i = 3; u = 3; break;
+case NEON::BI__builtin_neon_vcvts_n_f32_u32: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvts_n_f32_s32: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvtd_n_f64_u64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vcvtd_n_f64_s64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vshld_n_u64: i = 1; u = 63; break;
+case NEON::BI__builtin_neon_vshld_n_s64: i = 1; u = 63; break;
+case NEON::BI__builtin_neon_vslid_n_u64: i = 2; u = 63; break;
+case NEON::BI__builtin_neon_vslid_n_s64: i = 2; u = 63; break;
+case NEON::BI__builtin_neon_vqdmlals_lane_s32: i = 3; u = 1; break;
+case NEON::BI__builtin_neon_vqdmlalh_lane_s16: i = 3; u = 3; break;
+case NEON::BI__builtin_neon_vqdmlals_laneq_s32: i = 3; u = 3; break;
+case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: i = 3; u = 7; break;
+case NEON::BI__builtin_neon_vqdmlsls_lane_s32: i = 3; u = 1; break;
+case NEON::BI__builtin_neon_vqdmlslh_lane_s16: i = 3; u = 3; break;
+case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: i = 3; u = 3; break;
+case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: i = 3; u = 7; break;
+case NEON::BI__builtin_neon_vqrshrns_n_u32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqrshrnd_n_u64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqrshrnh_n_u16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqrshrns_n_s32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqrshrnd_n_s64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqrshrnh_n_s16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqrshruns_n_s32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqrshrund_n_s64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqrshrunh_n_s16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshlub_n_s8: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshlus_n_s32: i = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshlud_n_s64: i = 1; u = 63; break;
+case NEON::BI__builtin_neon_vqshluh_n_s16: i = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshlb_n_u8: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshls_n_u32: i = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshld_n_u64: i = 1; u = 63; break;
+case NEON::BI__builtin_neon_vqshlh_n_u16: i = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshlb_n_s8: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshls_n_s32: i = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshld_n_s64: i = 1; u = 63; break;
+case NEON::BI__builtin_neon_vqshlh_n_s16: i = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshrns_n_u32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshrnd_n_u64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshrnh_n_u16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshrns_n_s32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshrnd_n_s64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshrnh_n_s16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vqshruns_n_s32: i = 1; l = 1; u = 15; break;
+case NEON::BI__builtin_neon_vqshrund_n_s64: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vqshrunh_n_s16: i = 1; l = 1; u = 7; break;
+case NEON::BI__builtin_neon_vsrid_n_u64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vsrid_n_s64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vrshrd_n_u64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vrshrd_n_s64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vrsrad_n_u64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vrsrad_n_s64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vshrd_n_u64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vshrd_n_s64: i = 1; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vsrad_n_u64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vsrad_n_s64: i = 2; l = 1; u = 63; break;
+case NEON::BI__builtin_neon_vdupb_lane_i8: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vduph_lane_i16: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vdups_lane_i32: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vdupd_lane_i64: i = 1; u = 0; break;
+case NEON::BI__builtin_neon_vdupd_lane_f64: i = 1; u = 0; break;
+case NEON::BI__builtin_neon_vdups_lane_f32: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vdupb_laneq_i8: i = 1; u = 15; break;
+case NEON::BI__builtin_neon_vduph_laneq_i16: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vdups_laneq_i32: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vdupd_laneq_i64: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vdupd_laneq_f64: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vdups_laneq_f32: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vmul_lane_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vmul_laneq_v: i = 2; u = RFT(TV, false, true); break;
+case NEON::BI__builtin_neon_vset_lane_i64: i = 2; u = 0; break;
+case NEON::BI__builtin_neon_vsetq_lane_i64: i = 2; u = 1; break;
+case NEON::BI__builtin_neon_vsetq_lane_f64: i = 2; u = 1; break;
+case NEON::BI__builtin_neon_vset_lane_f64: i = 2; u = 0; break;
+case NEON::BI__builtin_neon_vsli_n_v: i = 2; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vsliq_n_v: i = 2; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vsri_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vsriq_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vst1_lane_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst1q_lane_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst2_lane_v: i = 3; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst2q_lane_v: i = 3; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst3_lane_v: i = 4; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst3q_lane_v: i = 4; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst4_lane_v: i = 5; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vst4q_lane_v: i = 5; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vcvtq_n_f32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvt_n_f32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvtq_n_s32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvt_n_s32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvtq_n_u32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vcvt_n_u32_v: i = 1; l = 1; u = 31; break;
+case NEON::BI__builtin_neon_vext_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vextq_v: i = 2; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vfmaq_lane_v: i = 3; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vfma_lane_v: i = 3; u = RFT(TV, false, false); break;
+case NEON::BI__builtin_neon_vfmaq_laneq_v: i = 3; u = RFT(TV, false, true); break;
+case NEON::BI__builtin_neon_vfma_laneq_v: i = 3; u = RFT(TV, false, true); break;
+case NEON::BI__builtin_neon_vget_lane_i8: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vget_lane_i16: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vgetq_lane_i8: i = 1; u = 15; break;
+case NEON::BI__builtin_neon_vgetq_lane_i16: i = 1; u = 7; break;
+case NEON::BI__builtin_neon_vgetq_lane_i32: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vgetq_lane_f32: i = 1; u = 3; break;
+case NEON::BI__builtin_neon_vget_lane_i32: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vget_lane_f32: i = 1; u = 1; break;
+case NEON::BI__builtin_neon_vqrshrn_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqrshrun_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshluq_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshlu_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshlq_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshl_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshrn_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vqshrun_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vrshrn_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vrshrq_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vrshr_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vrsraq_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vrsra_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vset_lane_i8: i = 2; u = 7; break;
+case NEON::BI__builtin_neon_vset_lane_i16: i = 2; u = 3; break;
+case NEON::BI__builtin_neon_vsetq_lane_i8: i = 2; u = 15; break;
+case NEON::BI__builtin_neon_vsetq_lane_i16: i = 2; u = 7; break;
+case NEON::BI__builtin_neon_vsetq_lane_i32: i = 2; u = 3; break;
+case NEON::BI__builtin_neon_vsetq_lane_f32: i = 2; u = 3; break;
+case NEON::BI__builtin_neon_vset_lane_i32: i = 2; u = 1; break;
+case NEON::BI__builtin_neon_vset_lane_f32: i = 2; u = 1; break;
+case NEON::BI__builtin_neon_vshll_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vshlq_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vshl_n_v: i = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vshrn_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vshrq_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vshr_n_v: i = 1; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vsraq_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+case NEON::BI__builtin_neon_vsra_n_v: i = 2; l = 1; u = RFT(TV, true); break;
+#endif
+
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
new file mode 100644
index 0000000..f8b90b3
--- /dev/null
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -0,0 +1,40 @@
+//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+#define LLVM_CLANG_CODEGEN_BACKEND_UTIL_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace llvm {
+  class Module;
+}
+
+namespace clang {
+  class DiagnosticsEngine;
+  class CodeGenOptions;
+  class TargetOptions;
+  class LangOptions;
+
+  enum BackendAction {
+    Backend_EmitAssembly,  ///< Emit native assembly files
+    Backend_EmitBC,        ///< Emit LLVM bitcode files
+    Backend_EmitLL,        ///< Emit human-readable LLVM assembly
+    Backend_EmitNothing,   ///< Don't emit anything (benchmarking mode)
+    Backend_EmitMCNull,    ///< Run CodeGen, but don't emit anything
+    Backend_EmitObj        ///< Emit native object files
+  };
+
+  void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
+                         const TargetOptions &TOpts, const LangOptions &LOpts,
+                         StringRef TDesc, llvm::Module *M, BackendAction Action,
+                         raw_ostream *OS);
+}
+
+#endif
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
new file mode 100644
index 0000000..449827e
--- /dev/null
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -0,0 +1,482 @@
+//==-- CGFunctionInfo.h - Representation of function argument/return types -==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines CGFunctionInfo and associated types used in representing the
+// LLVM source types and ABI-coerced types for function arguments and
+// return values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
+#define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
+
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <cassert>
+
+namespace llvm {
+  class Type;
+  class StructType;
+}
+
+namespace clang {
+class Decl;
+
+namespace CodeGen {
+
+/// ABIArgInfo - Helper class to encapsulate information about how a
+/// specific C type should be passed to or returned from a function.
+class ABIArgInfo {
+public:
+  enum Kind : uint8_t {
+    /// Direct - Pass the argument directly using the normal converted LLVM
+    /// type, or by coercing to another specified type stored in
+    /// 'CoerceToType').  If an offset is specified (in UIntData), then the
+    /// argument passed is offset by some number of bytes in the memory
+    /// representation. A dummy argument is emitted before the real argument
+    /// if the specified type stored in "PaddingType" is not zero.
+    Direct,
+
+    /// Extend - Valid only for integer argument types. Same as 'direct'
+    /// but also emit a zero/sign extension attribute.
+    Extend,
+
+    /// Indirect - Pass the argument indirectly via a hidden pointer
+    /// with the specified alignment (0 indicates default alignment).
+    Indirect,
+
+    /// Ignore - Ignore the argument (treat as void). Useful for void and
+    /// empty structs.
+    Ignore,
+
+    /// Expand - Only valid for aggregate argument types. The structure should
+    /// be expanded into consecutive arguments for its constituent fields.
+    /// Currently expand is only allowed on structures whose fields
+    /// are all scalar types or are themselves expandable types.
+    Expand,
+
+    /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
+    /// This is similar to 'direct', except it only applies to arguments stored
+    /// in memory and forbids any implicit copies.  When applied to a return
+    /// type, it means the value is returned indirectly via an implicit sret
+    /// parameter stored in the argument struct.
+    InAlloca,
+    KindFirst = Direct,
+    KindLast = InAlloca
+  };
+
+private:
+  llvm::Type *TypeData; // isDirect() || isExtend()
+  llvm::Type *PaddingType;
+  union {
+    unsigned DirectOffset;     // isDirect() || isExtend()
+    unsigned IndirectAlign;    // isIndirect()
+    unsigned AllocaFieldIndex; // isInAlloca()
+  };
+  Kind TheKind;
+  bool PaddingInReg : 1;
+  bool InAllocaSRet : 1;    // isInAlloca()
+  bool IndirectByVal : 1;   // isIndirect()
+  bool IndirectRealign : 1; // isIndirect()
+  bool SRetAfterThis : 1;   // isIndirect()
+  bool InReg : 1;           // isDirect() || isExtend() || isIndirect()
+
+  ABIArgInfo(Kind K)
+      : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
+
+public:
+  ABIArgInfo()
+      : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
+        TheKind(Direct), PaddingInReg(false), InReg(false) {}
+
+  static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
+                              llvm::Type *Padding = nullptr) {
+    auto AI = ABIArgInfo(Direct);
+    AI.setCoerceToType(T);
+    AI.setDirectOffset(Offset);
+    AI.setPaddingType(Padding);
+    return AI;
+  }
+  static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
+    auto AI = getDirect(T);
+    AI.setInReg(true);
+    return AI;
+  }
+  static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
+    auto AI = ABIArgInfo(Extend);
+    AI.setCoerceToType(T);
+    AI.setDirectOffset(0);
+    return AI;
+  }
+  static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
+    auto AI = getExtend(T);
+    AI.setInReg(true);
+    return AI;
+  }
+  static ABIArgInfo getIgnore() {
+    return ABIArgInfo(Ignore);
+  }
+  static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true,
+                                bool Realign = false,
+                                llvm::Type *Padding = nullptr) {
+    auto AI = ABIArgInfo(Indirect);
+    AI.setIndirectAlign(Alignment);
+    AI.setIndirectByVal(ByVal);
+    AI.setIndirectRealign(Realign);
+    AI.setSRetAfterThis(false);
+    AI.setPaddingType(Padding);
+    return AI;
+  }
+  static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true,
+                                     bool Realign = false) {
+    auto AI = getIndirect(Alignment, ByVal, Realign);
+    AI.setInReg(true);
+    return AI;
+  }
+  static ABIArgInfo getInAlloca(unsigned FieldIndex) {
+    auto AI = ABIArgInfo(InAlloca);
+    AI.setInAllocaFieldIndex(FieldIndex);
+    return AI;
+  }
+  static ABIArgInfo getExpand() {
+    return ABIArgInfo(Expand);
+  }
+  static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
+                                         llvm::Type *Padding) {
+    auto AI = getExpand();
+    AI.setPaddingInReg(PaddingInReg);
+    AI.setPaddingType(Padding);
+    return AI;
+  }
+
+  Kind getKind() const { return TheKind; }
+  bool isDirect() const { return TheKind == Direct; }
+  bool isInAlloca() const { return TheKind == InAlloca; }
+  bool isExtend() const { return TheKind == Extend; }
+  bool isIgnore() const { return TheKind == Ignore; }
+  bool isIndirect() const { return TheKind == Indirect; }
+  bool isExpand() const { return TheKind == Expand; }
+
+  bool canHaveCoerceToType() const { return isDirect() || isExtend(); }
+
+  // Direct/Extend accessors
+  unsigned getDirectOffset() const {
+    assert((isDirect() || isExtend()) && "Not a direct or extend kind");
+    return DirectOffset;
+  }
+  void setDirectOffset(unsigned Offset) {
+    assert((isDirect() || isExtend()) && "Not a direct or extend kind");
+    DirectOffset = Offset;
+  }
+
+  llvm::Type *getPaddingType() const { return PaddingType; }
+
+  void setPaddingType(llvm::Type *T) { PaddingType = T; }
+
+  bool getPaddingInReg() const {
+    return PaddingInReg;
+  }
+  void setPaddingInReg(bool PIR) {
+    PaddingInReg = PIR;
+  }
+
+  llvm::Type *getCoerceToType() const {
+    assert(canHaveCoerceToType() && "Invalid kind!");
+    return TypeData;
+  }
+
+  void setCoerceToType(llvm::Type *T) {
+    assert(canHaveCoerceToType() && "Invalid kind!");
+    TypeData = T;
+  }
+
+  bool getInReg() const {
+    assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+    return InReg;
+  }
+
+  void setInReg(bool IR) {
+    assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+    InReg = IR;
+  }
+
+  // Indirect accessors
+  unsigned getIndirectAlign() const {
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectAlign;
+  }
+  void setIndirectAlign(unsigned IA) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectAlign = IA;
+  }
+
+  bool getIndirectByVal() const {
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectByVal;
+  }
+  void setIndirectByVal(unsigned IBV) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectByVal = IBV;
+  }
+
+  bool getIndirectRealign() const {
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectRealign;
+  }
+  void setIndirectRealign(bool IR) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectRealign = IR;
+  }
+
+  bool isSRetAfterThis() const {
+    assert(isIndirect() && "Invalid kind!");
+    return SRetAfterThis;
+  }
+  void setSRetAfterThis(bool AfterThis) {
+    assert(isIndirect() && "Invalid kind!");
+    SRetAfterThis = AfterThis;
+  }
+
+  unsigned getInAllocaFieldIndex() const {
+    assert(isInAlloca() && "Invalid kind!");
+    return AllocaFieldIndex;
+  }
+  void setInAllocaFieldIndex(unsigned FieldIndex) {
+    assert(isInAlloca() && "Invalid kind!");
+    AllocaFieldIndex = FieldIndex;
+  }
+
+  /// \brief Return true if this field of an inalloca struct should be returned
+  /// to implement a struct return calling convention.
+  bool getInAllocaSRet() const {
+    assert(isInAlloca() && "Invalid kind!");
+    return InAllocaSRet;
+  }
+
+  void setInAllocaSRet(bool SRet) {
+    assert(isInAlloca() && "Invalid kind!");
+    InAllocaSRet = SRet;
+  }
+
+  void dump() const;
+};
+
+/// A class for recording the number of arguments that a function
+/// signature requires.
+class RequiredArgs {
+  /// The number of required arguments, or ~0 if the signature does
+  /// not permit optional arguments.
+  unsigned NumRequired;
+public:
+  enum All_t { All };
+
+  RequiredArgs(All_t _) : NumRequired(~0U) {}
+  explicit RequiredArgs(unsigned n) : NumRequired(n) {
+    assert(n != ~0U);
+  }
+
+  /// Compute the arguments required by the given formal prototype,
+  /// given that there may be some additional, non-formal arguments
+  /// in play.
+  static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
+                                       unsigned additional) {
+    if (!prototype->isVariadic()) return All;
+    return RequiredArgs(prototype->getNumParams() + additional);
+  }
+
+  static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
+    return forPrototypePlus(prototype, 0);
+  }
+
+  static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
+    return forPrototype(prototype.getTypePtr());
+  }
+
+  static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
+                                       unsigned additional) {
+    return forPrototypePlus(prototype.getTypePtr(), additional);
+  }
+
+  bool allowsOptionalArgs() const { return NumRequired != ~0U; }
+  unsigned getNumRequiredArgs() const {
+    assert(allowsOptionalArgs());
+    return NumRequired;
+  }
+
+  unsigned getOpaqueData() const { return NumRequired; }
+  static RequiredArgs getFromOpaqueData(unsigned value) {
+    if (value == ~0U) return All;
+    return RequiredArgs(value);
+  }
+};
+
+/// CGFunctionInfo - Class to encapsulate the information about a
+/// function definition.
+class CGFunctionInfo : public llvm::FoldingSetNode {
+  struct ArgInfo {
+    CanQualType type;
+    ABIArgInfo info;
+  };
+
+  /// The LLVM::CallingConv to use for this function (as specified by the
+  /// user).
+  unsigned CallingConvention : 8;
+
+  /// The LLVM::CallingConv to actually use for this function, which may
+  /// depend on the ABI.
+  unsigned EffectiveCallingConvention : 8;
+
+  /// The clang::CallingConv that this was originally created with.
+  unsigned ASTCallingConvention : 8;
+
+  /// Whether this is an instance method.
+  unsigned InstanceMethod : 1;
+
+  /// Whether this function is noreturn.
+  unsigned NoReturn : 1;
+
+  /// Whether this function is returns-retained.
+  unsigned ReturnsRetained : 1;
+
+  /// How many arguments to pass inreg.
+  unsigned HasRegParm : 1;
+  unsigned RegParm : 4;
+
+  RequiredArgs Required;
+
+  /// The struct representing all arguments passed in memory.  Only used when
+  /// passing non-trivial types with inalloca.  Not part of the profile.
+  llvm::StructType *ArgStruct;
+
+  unsigned NumArgs;
+  ArgInfo *getArgsBuffer() {
+    return reinterpret_cast<ArgInfo*>(this+1);
+  }
+  const ArgInfo *getArgsBuffer() const {
+    return reinterpret_cast<const ArgInfo*>(this + 1);
+  }
+
+  CGFunctionInfo() : Required(RequiredArgs::All) {}
+
+public:
+  static CGFunctionInfo *create(unsigned llvmCC,
+                                bool InstanceMethod,
+                                const FunctionType::ExtInfo &extInfo,
+                                CanQualType resultType,
+                                ArrayRef<CanQualType> argTypes,
+                                RequiredArgs required);
+
+  typedef const ArgInfo *const_arg_iterator;
+  typedef ArgInfo *arg_iterator;
+
+  typedef llvm::iterator_range<arg_iterator> arg_range;
+  typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+  arg_const_range arguments() const {
+    return arg_const_range(arg_begin(), arg_end());
+  }
+
+  const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
+  const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
+  arg_iterator arg_begin() { return getArgsBuffer() + 1; }
+  arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
+
+  unsigned  arg_size() const { return NumArgs; }
+
+  bool isVariadic() const { return Required.allowsOptionalArgs(); }
+  RequiredArgs getRequiredArgs() const { return Required; }
+
+  bool isInstanceMethod() const { return InstanceMethod; }
+
+  bool isNoReturn() const { return NoReturn; }
+
+  /// In ARC, whether this function retains its return value.  This
+  /// is not always reliable for call sites.
+  bool isReturnsRetained() const { return ReturnsRetained; }
+
+  /// getASTCallingConvention() - Return the AST-specified calling
+  /// convention.
+  CallingConv getASTCallingConvention() const {
+    return CallingConv(ASTCallingConvention);
+  }
+
+  /// getCallingConvention - Return the user specified calling
+  /// convention, which has been translated into an LLVM CC.
+  unsigned getCallingConvention() const { return CallingConvention; }
+
+  /// getEffectiveCallingConvention - Return the actual calling convention to
+  /// use, which may depend on the ABI.
+  unsigned getEffectiveCallingConvention() const {
+    return EffectiveCallingConvention;
+  }
+  void setEffectiveCallingConvention(unsigned Value) {
+    EffectiveCallingConvention = Value;
+  }
+
+  bool getHasRegParm() const { return HasRegParm; }
+  unsigned getRegParm() const { return RegParm; }
+
+  FunctionType::ExtInfo getExtInfo() const {
+    return FunctionType::ExtInfo(isNoReturn(),
+                                 getHasRegParm(), getRegParm(),
+                                 getASTCallingConvention(),
+                                 isReturnsRetained());
+  }
+
+  CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
+
+  ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
+  const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
+
+  /// \brief Return true if this function uses inalloca arguments.
+  bool usesInAlloca() const { return ArgStruct; }
+
+  /// \brief Get the struct type used to represent all the arguments in memory.
+  llvm::StructType *getArgStruct() const { return ArgStruct; }
+  void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    ID.AddInteger(getASTCallingConvention());
+    ID.AddBoolean(InstanceMethod);
+    ID.AddBoolean(NoReturn);
+    ID.AddBoolean(ReturnsRetained);
+    ID.AddBoolean(HasRegParm);
+    ID.AddInteger(RegParm);
+    ID.AddInteger(Required.getOpaqueData());
+    getReturnType().Profile(ID);
+    for (const auto &I : arguments())
+      I.type.Profile(ID);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      bool InstanceMethod,
+                      const FunctionType::ExtInfo &info,
+                      RequiredArgs required,
+                      CanQualType resultType,
+                      ArrayRef<CanQualType> argTypes) {
+    ID.AddInteger(info.getCC());
+    ID.AddBoolean(InstanceMethod);
+    ID.AddBoolean(info.getNoReturn());
+    ID.AddBoolean(info.getProducesResult());
+    ID.AddBoolean(info.getHasRegParm());
+    ID.AddInteger(info.getRegParm());
+    ID.AddInteger(required.getOpaqueData());
+    resultType.Profile(ID);
+    for (ArrayRef<CanQualType>::iterator
+           i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
+      i->Profile(ID);
+    }
+  }
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
new file mode 100644
index 0000000..2502982
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -0,0 +1,83 @@
+//==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// CodeGenABITypes is a simple interface for getting LLVM types for
+// the parameters and the return value of a function given the Clang
+// types.
+//
+// The class is implemented as a public wrapper around the private
+// CodeGenTypes class in lib/CodeGen.
+//
+// It allows other clients, like LLDB, to determine the LLVM types that are
+// actually used in function calls, which makes it possible to then determine
+// the acutal ABI locations (e.g. registers, stack locations, etc.) that
+// these parameters are stored in.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_ABITYPES_H
+#define LLVM_CLANG_CODEGEN_ABITYPES_H
+
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
+#include "clang/CodeGen/CGFunctionInfo.h"
+
+namespace llvm {
+  class DataLayout;
+  class Module;
+}
+
+namespace clang {
+class ASTContext;
+class CXXRecordDecl;
+class CodeGenOptions;
+class DiagnosticsEngine;
+class ObjCMethodDecl;
+
+namespace CodeGen {
+class CGFunctionInfo;
+class CodeGenModule;
+
+class CodeGenABITypes
+{
+public:
+  CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD);
+  ~CodeGenABITypes();
+
+  /// These methods all forward to methods in the private implementation class
+  /// CodeGenTypes.
+
+  const CGFunctionInfo &arrangeObjCMessageSendSignature(
+                                                     const ObjCMethodDecl *MD,
+                                                     QualType receiverType);
+  const CGFunctionInfo &arrangeFreeFunctionType(
+                                               CanQual<FunctionProtoType> Ty);
+  const CGFunctionInfo &arrangeFreeFunctionType(
+                                             CanQual<FunctionNoProtoType> Ty);
+  const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
+                                             const FunctionProtoType *FTP);
+  const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
+                                                ArrayRef<CanQualType> argTypes,
+                                                FunctionType::ExtInfo info,
+                                                RequiredArgs args);
+
+private:
+  /// Default CodeGenOptions object used to initialize the
+  /// CodeGenModule and otherwise not used. More specifically, it is
+  /// not used in ABI type generation, so none of the options matter.
+  CodeGenOptions *CGO;
+
+  /// The CodeGenModule we use get to the CodeGenTypes object.
+  CodeGen::CodeGenModule *CGM;
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
new file mode 100644
index 0000000..37819c7
--- /dev/null
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -0,0 +1,103 @@
+//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+#define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <memory>
+
+namespace llvm {
+  class LLVMContext;
+  class Module;
+}
+
+namespace clang {
+class BackendConsumer;
+
+class CodeGenAction : public ASTFrontendAction {
+private:
+  unsigned Act;
+  std::unique_ptr<llvm::Module> TheModule;
+  llvm::Module *LinkModule;
+  llvm::LLVMContext *VMContext;
+  bool OwnsVMContext;
+
+protected:
+  /// Create a new code generation action.  If the optional \p _VMContext
+  /// parameter is supplied, the action uses it without taking ownership,
+  /// otherwise it creates a fresh LLVM context and takes ownership.
+  CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
+
+  bool hasIRSupport() const override;
+
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  void ExecuteAction() override;
+
+  void EndSourceFileAction() override;
+
+public:
+  ~CodeGenAction();
+
+  /// setLinkModule - Set the link module to be used by this action.  If a link
+  /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty,
+  /// the action will load it from the specified file.
+  void setLinkModule(llvm::Module *Mod) { LinkModule = Mod; }
+
+  /// takeModule - Take the generated LLVM module, for use after the action has
+  /// been run. The result may be null on failure.
+  llvm::Module *takeModule();
+
+  /// Take the LLVM context used by this action.
+  llvm::LLVMContext *takeLLVMContext();
+
+  BackendConsumer *BEConsumer;
+};
+
+class EmitAssemblyAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitBCAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitLLVMAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitLLVMOnlyAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitCodeGenOnlyAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+class EmitObjAction : public CodeGenAction {
+  virtual void anchor();
+public:
+  EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
+};
+
+}
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
new file mode 100644
index 0000000..4b7236b
--- /dev/null
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,50 @@
+//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- 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 ModuleBuilder interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include <string>
+
+namespace llvm {
+  class LLVMContext;
+  class Module;
+}
+
+namespace clang {
+  class DiagnosticsEngine;
+  class LangOptions;
+  class CodeGenOptions;
+  class TargetOptions;
+  class Decl;
+
+  class CodeGenerator : public ASTConsumer {
+    virtual void anchor();
+  public:
+    virtual llvm::Module* GetModule() = 0;
+    virtual llvm::Module* ReleaseModule() = 0;
+    virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0;
+  };
+
+  /// CreateLLVMCodeGen - Create a CodeGenerator instance.
+  /// It is the responsibility of the caller to call delete on
+  /// the allocated CodeGenerator instance.
+  CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
+                                   const std::string &ModuleName,
+                                   const CodeGenOptions &CGO,
+                                   const TargetOptions &TO,
+                                   llvm::LLVMContext& C);
+}
+
+#endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
new file mode 100644
index 0000000..2cdb581
--- /dev/null
+++ b/include/clang/Driver/Action.h
@@ -0,0 +1,266 @@
+//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ACTION_H_
+#define CLANG_DRIVER_ACTION_H_
+
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+namespace opt {
+  class Arg;
+}
+}
+
+namespace clang {
+namespace driver {
+
+/// Action - Represent an abstract compilation step to perform.
+///
+/// An action represents an edge in the compilation graph; typically
+/// it is a job to transform an input using some tool.
+///
+/// The current driver is hard wired to expect actions which produce a
+/// single primary output, at least in terms of controlling the
+/// compilation. Actions can produce auxiliary files, but can only
+/// produce a single output to feed into subsequent actions.
+class Action {
+public:
+  typedef ActionList::size_type size_type;
+  typedef ActionList::iterator iterator;
+  typedef ActionList::const_iterator const_iterator;
+
+  enum ActionClass {
+    InputClass = 0,
+    BindArchClass,
+    PreprocessJobClass,
+    PrecompileJobClass,
+    AnalyzeJobClass,
+    MigrateJobClass,
+    CompileJobClass,
+    AssembleJobClass,
+    LinkJobClass,
+    LipoJobClass,
+    DsymutilJobClass,
+    VerifyDebugInfoJobClass,
+    VerifyPCHJobClass,
+
+    JobClassFirst=PreprocessJobClass,
+    JobClassLast=VerifyPCHJobClass
+  };
+
+  static const char *getClassName(ActionClass AC);
+
+private:
+  ActionClass Kind;
+
+  /// The output type of this action.
+  types::ID Type;
+
+  ActionList Inputs;
+
+  unsigned OwnsInputs : 1;
+
+protected:
+  Action(ActionClass _Kind, types::ID _Type)
+    : Kind(_Kind), Type(_Type), OwnsInputs(true)  {}
+  Action(ActionClass _Kind, Action *Input, types::ID _Type)
+    : Kind(_Kind), Type(_Type), Inputs(&Input, &Input + 1), OwnsInputs(true) {}
+  Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type)
+    : Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {}
+public:
+  virtual ~Action();
+
+  const char *getClassName() const { return Action::getClassName(getKind()); }
+
+  bool getOwnsInputs() { return OwnsInputs; }
+  void setOwnsInputs(bool Value) { OwnsInputs = Value; }
+
+  ActionClass getKind() const { return Kind; }
+  types::ID getType() const { return Type; }
+
+  ActionList &getInputs() { return Inputs; }
+  const ActionList &getInputs() const { return Inputs; }
+
+  size_type size() const { return Inputs.size(); }
+
+  iterator begin() { return Inputs.begin(); }
+  iterator end() { return Inputs.end(); }
+  const_iterator begin() const { return Inputs.begin(); }
+  const_iterator end() const { return Inputs.end(); }
+};
+
+class InputAction : public Action {
+  virtual void anchor();
+  const llvm::opt::Arg &Input;
+
+public:
+  InputAction(const llvm::opt::Arg &_Input, types::ID _Type);
+
+  const llvm::opt::Arg &getInputArg() const { return Input; }
+
+  static bool classof(const Action *A) {
+    return A->getKind() == InputClass;
+  }
+};
+
+class BindArchAction : public Action {
+  virtual void anchor();
+  /// The architecture to bind, or 0 if the default architecture
+  /// should be bound.
+  const char *ArchName;
+
+public:
+  BindArchAction(Action *Input, const char *_ArchName);
+
+  const char *getArchName() const { return ArchName; }
+
+  static bool classof(const Action *A) {
+    return A->getKind() == BindArchClass;
+  }
+};
+
+class JobAction : public Action {
+  virtual void anchor();
+protected:
+  JobAction(ActionClass Kind, Action *Input, types::ID Type);
+  JobAction(ActionClass Kind, const ActionList &Inputs, types::ID Type);
+
+public:
+  static bool classof(const Action *A) {
+    return (A->getKind() >= JobClassFirst &&
+            A->getKind() <= JobClassLast);
+  }
+};
+
+class PreprocessJobAction : public JobAction {
+  void anchor() override;
+public:
+  PreprocessJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == PreprocessJobClass;
+  }
+};
+
+class PrecompileJobAction : public JobAction {
+  void anchor() override;
+public:
+  PrecompileJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == PrecompileJobClass;
+  }
+};
+
+class AnalyzeJobAction : public JobAction {
+  void anchor() override;
+public:
+  AnalyzeJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == AnalyzeJobClass;
+  }
+};
+
+class MigrateJobAction : public JobAction {
+  void anchor() override;
+public:
+  MigrateJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == MigrateJobClass;
+  }
+};
+
+class CompileJobAction : public JobAction {
+  void anchor() override;
+public:
+  CompileJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == CompileJobClass;
+  }
+};
+
+class AssembleJobAction : public JobAction {
+  void anchor() override;
+public:
+  AssembleJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == AssembleJobClass;
+  }
+};
+
+class LinkJobAction : public JobAction {
+  void anchor() override;
+public:
+  LinkJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == LinkJobClass;
+  }
+};
+
+class LipoJobAction : public JobAction {
+  void anchor() override;
+public:
+  LipoJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == LipoJobClass;
+  }
+};
+
+class DsymutilJobAction : public JobAction {
+  void anchor() override;
+public:
+  DsymutilJobAction(ActionList &Inputs, types::ID Type);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == DsymutilJobClass;
+  }
+};
+
+class VerifyJobAction : public JobAction {
+  void anchor() override;
+public:
+  VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
+  VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == VerifyDebugInfoJobClass ||
+           A->getKind() == VerifyPCHJobClass;
+  }
+};
+
+class VerifyDebugInfoJobAction : public VerifyJobAction {
+  void anchor() override;
+public:
+  VerifyDebugInfoJobAction(Action *Input, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == VerifyDebugInfoJobClass;
+  }
+};
+
+class VerifyPCHJobAction : public VerifyJobAction {
+  void anchor() override;
+public:
+  VerifyPCHJobAction(Action *Input, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == VerifyPCHJobClass;
+  }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
new file mode 100644
index 0000000..c1c0f43
--- /dev/null
+++ b/include/clang/Driver/Compilation.h
@@ -0,0 +1,187 @@
+//===--- Compilation.h - Compilation Task Data Structure --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_COMPILATION_H_
+#define CLANG_DRIVER_COMPILATION_H_
+
+#include "clang/Driver/Job.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace opt {
+  class DerivedArgList;
+  class InputArgList;
+}
+}
+
+namespace clang {
+namespace driver {
+  class Driver;
+  class JobAction;
+  class JobList;
+  class ToolChain;
+
+/// Compilation - A set of tasks to perform for a single driver
+/// invocation.
+class Compilation {
+  /// The driver we were created by.
+  const Driver &TheDriver;
+
+  /// The default tool chain.
+  const ToolChain &DefaultToolChain;
+
+  /// The original (untranslated) input argument list.
+  llvm::opt::InputArgList *Args;
+
+  /// The driver translated arguments. Note that toolchains may perform their
+  /// own argument translation.
+  llvm::opt::DerivedArgList *TranslatedArgs;
+
+  /// The list of actions.
+  ActionList Actions;
+
+  /// The root list of jobs.
+  JobList Jobs;
+
+  /// Cache of translated arguments for a particular tool chain and bound
+  /// architecture.
+  llvm::DenseMap<std::pair<const ToolChain *, const char *>,
+                 llvm::opt::DerivedArgList *> TCArgs;
+
+  /// Temporary files which should be removed on exit.
+  llvm::opt::ArgStringList TempFiles;
+
+  /// Result files which should be removed on failure.
+  ArgStringMap ResultFiles;
+
+  /// Result files which are generated correctly on failure, and which should
+  /// only be removed if we crash.
+  ArgStringMap FailureResultFiles;
+
+  /// Redirection for stdout, stderr, etc.
+  const StringRef **Redirects;
+
+  /// Whether we're compiling for diagnostic purposes.
+  bool ForDiagnostics;
+
+public:
+  Compilation(const Driver &D, const ToolChain &DefaultToolChain,
+              llvm::opt::InputArgList *Args,
+              llvm::opt::DerivedArgList *TranslatedArgs);
+  ~Compilation();
+
+  const Driver &getDriver() const { return TheDriver; }
+
+  const ToolChain &getDefaultToolChain() const { return DefaultToolChain; }
+
+  const llvm::opt::InputArgList &getInputArgs() const { return *Args; }
+
+  const llvm::opt::DerivedArgList &getArgs() const { return *TranslatedArgs; }
+
+  llvm::opt::DerivedArgList &getArgs() { return *TranslatedArgs; }
+
+  ActionList &getActions() { return Actions; }
+  const ActionList &getActions() const { return Actions; }
+
+  JobList &getJobs() { return Jobs; }
+  const JobList &getJobs() const { return Jobs; }
+
+  void addCommand(Command *C) { Jobs.addJob(C); }
+
+  const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
+
+  const ArgStringMap &getResultFiles() const { return ResultFiles; }
+
+  const ArgStringMap &getFailureResultFiles() const {
+    return FailureResultFiles;
+  }
+
+  /// Returns the sysroot path.
+  StringRef getSysRoot() const;
+
+  /// getArgsForToolChain - Return the derived argument list for the
+  /// tool chain \p TC (or the default tool chain, if TC is not specified).
+  ///
+  /// \param BoundArch - The bound architecture name, or 0.
+  const llvm::opt::DerivedArgList &getArgsForToolChain(const ToolChain *TC,
+                                                       const char *BoundArch);
+
+  /// addTempFile - Add a file to remove on exit, and returns its
+  /// argument.
+  const char *addTempFile(const char *Name) {
+    TempFiles.push_back(Name);
+    return Name;
+  }
+
+  /// addResultFile - Add a file to remove on failure, and returns its
+  /// argument.
+  const char *addResultFile(const char *Name, const JobAction *JA) {
+    ResultFiles[JA] = Name;
+    return Name;
+  }
+
+  /// addFailureResultFile - Add a file to remove if we crash, and returns its
+  /// argument.
+  const char *addFailureResultFile(const char *Name, const JobAction *JA) {
+    FailureResultFiles[JA] = Name;
+    return Name;
+  }
+
+  /// CleanupFile - Delete a given file.
+  ///
+  /// \param IssueErrors - Report failures as errors.
+  /// \return Whether the file was removed successfully.
+  bool CleanupFile(const char *File, bool IssueErrors = false) const;
+
+  /// CleanupFileList - Remove the files in the given list.
+  ///
+  /// \param IssueErrors - Report failures as errors.
+  /// \return Whether all files were removed successfully.
+  bool CleanupFileList(const llvm::opt::ArgStringList &Files,
+                       bool IssueErrors = false) const;
+
+  /// CleanupFileMap - Remove the files in the given map.
+  ///
+  /// \param JA - If specified, only delete the files associated with this
+  /// JobAction.  Otherwise, delete all files in the map.
+  /// \param IssueErrors - Report failures as errors.
+  /// \return Whether all files were removed successfully.
+  bool CleanupFileMap(const ArgStringMap &Files,
+                      const JobAction *JA,
+                      bool IssueErrors = false) const;
+
+  /// ExecuteCommand - Execute an actual command.
+  ///
+  /// \param FailingCommand - For non-zero results, this will be set to the
+  /// Command which failed, if any.
+  /// \return The result code of the subprocess.
+  int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
+
+  /// ExecuteJob - Execute a single job.
+  ///
+  /// \param FailingCommands - For non-zero results, this will be a vector of
+  /// failing commands and their associated result code.
+  void ExecuteJob(const Job &J,
+     SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
+
+  /// initCompilationForDiagnostics - Remove stale state and suppress output
+  /// so compilation can be reexecuted to generate additional diagnostic
+  /// information (e.g., preprocessed source(s)).
+  void initCompilationForDiagnostics();
+
+  /// Return true if we're compiling for diagnostics.
+  bool isForDiagnostics() { return ForDiagnostics; }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
new file mode 100644
index 0000000..df974ad
--- /dev/null
+++ b/include/clang/Driver/Driver.h
@@ -0,0 +1,424 @@
+//===--- Driver.h - Clang GCC Compatible Driver -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_DRIVER_H_
+#define CLANG_DRIVER_DRIVER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Driver/Phases.h"
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo
+#include <memory>
+                              // lands.
+#include <list>
+#include <set>
+#include <string>
+
+namespace llvm {
+namespace opt {
+  class Arg;
+  class ArgList;
+  class DerivedArgList;
+  class InputArgList;
+  class OptTable;
+}
+}
+
+namespace clang {
+namespace driver {
+
+  class Action;
+  class Command;
+  class Compilation;
+  class InputInfo;
+  class JobAction;
+  class SanitizerArgs;
+  class ToolChain;
+
+/// Driver - Encapsulate logic for constructing compilation processes
+/// from a set of gcc-driver-like command line arguments.
+class Driver {
+  llvm::opt::OptTable *Opts;
+
+  DiagnosticsEngine &Diags;
+
+  enum DriverMode {
+    GCCMode,
+    GXXMode,
+    CPPMode,
+    CLMode
+  } Mode;
+
+public:
+  // Diag - Forwarding function for diagnostics.
+  DiagnosticBuilder Diag(unsigned DiagID) const {
+    return Diags.Report(DiagID);
+  }
+
+  // FIXME: Privatize once interface is stable.
+public:
+  /// The name the driver was invoked as.
+  std::string Name;
+
+  /// The path the driver executable was in, as invoked from the
+  /// command line.
+  std::string Dir;
+
+  /// The original path to the clang executable.
+  std::string ClangExecutable;
+
+  /// The path to the installed clang directory, if any.
+  std::string InstalledDir;
+
+  /// The path to the compiler resource directory.
+  std::string ResourceDir;
+
+  /// A prefix directory used to emulated a limited subset of GCC's '-Bprefix'
+  /// functionality.
+  /// FIXME: This type of customization should be removed in favor of the
+  /// universal driver when it is ready.
+  typedef SmallVector<std::string, 4> prefix_list;
+  prefix_list PrefixDirs;
+
+  /// sysroot, if present
+  std::string SysRoot;
+
+  /// Dynamic loader prefix, if present
+  std::string DyldPrefix;
+
+  /// If the standard library is used
+  bool UseStdLib;
+
+  /// Default target triple.
+  std::string DefaultTargetTriple;
+
+  /// Default name for linked images (e.g., "a.out").
+  std::string DefaultImageName;
+
+  /// Driver title to use with help.
+  std::string DriverTitle;
+
+  /// Information about the host which can be overridden by the user.
+  std::string HostBits, HostMachine, HostSystem, HostRelease;
+
+  /// The file to log CC_PRINT_OPTIONS output to, if enabled.
+  const char *CCPrintOptionsFilename;
+
+  /// The file to log CC_PRINT_HEADERS output to, if enabled.
+  const char *CCPrintHeadersFilename;
+
+  /// The file to log CC_LOG_DIAGNOSTICS output to, if enabled.
+  const char *CCLogDiagnosticsFilename;
+
+  /// A list of inputs and their types for the given arguments.
+  typedef SmallVector<std::pair<types::ID, const llvm::opt::Arg *>, 16>
+      InputList;
+
+  /// Whether the driver should follow g++ like behavior.
+  bool CCCIsCXX() const { return Mode == GXXMode; }
+
+  /// Whether the driver is just the preprocessor.
+  bool CCCIsCPP() const { return Mode == CPPMode; }
+
+  /// Whether the driver should follow cl.exe like behavior.
+  bool IsCLMode() const { return Mode == CLMode; }
+
+  /// Only print tool bindings, don't build any jobs.
+  unsigned CCCPrintBindings : 1;
+
+  /// Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to
+  /// CCPrintOptionsFilename or to stderr.
+  unsigned CCPrintOptions : 1;
+
+  /// Set CC_PRINT_HEADERS mode, which causes the frontend to log header include
+  /// information to CCPrintHeadersFilename or to stderr.
+  unsigned CCPrintHeaders : 1;
+
+  /// Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics
+  /// to CCLogDiagnosticsFilename or to stderr, in a stable machine readable
+  /// format.
+  unsigned CCLogDiagnostics : 1;
+
+  /// Whether the driver is generating diagnostics for debugging purposes.
+  unsigned CCGenDiagnostics : 1;
+
+private:
+  /// Name to use when invoking gcc/g++.
+  std::string CCCGenericGCCName;
+
+  /// Whether to check that input files exist when constructing compilation
+  /// jobs.
+  unsigned CheckInputsExist : 1;
+
+public:
+  /// Use lazy precompiled headers for PCH support.
+  unsigned CCCUsePCH : 1;
+
+private:
+  /// Certain options suppress the 'no input files' warning.
+  bool SuppressMissingInputWarning : 1;
+
+  std::list<std::string> TempFiles;
+  std::list<std::string> ResultFiles;
+
+  /// \brief Cache of all the ToolChains in use by the driver.
+  ///
+  /// This maps from the string representation of a triple to a ToolChain
+  /// created targeting that triple. The driver owns all the ToolChain objects
+  /// stored in it, and will clean them up when torn down.
+  mutable llvm::StringMap<ToolChain *> ToolChains;
+
+private:
+  /// TranslateInputArgs - Create a new derived argument list from the input
+  /// arguments, after applying the standard argument translations.
+  llvm::opt::DerivedArgList *
+  TranslateInputArgs(const llvm::opt::InputArgList &Args) const;
+
+  // getFinalPhase - Determine which compilation mode we are in and record 
+  // which option we used to determine the final phase.
+  phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
+                           llvm::opt::Arg **FinalPhaseArg = nullptr) const;
+
+public:
+  Driver(StringRef _ClangExecutable,
+         StringRef _DefaultTargetTriple,
+         DiagnosticsEngine &_Diags);
+  ~Driver();
+
+  /// @name Accessors
+  /// @{
+
+  /// Name to use when invoking gcc/g++.
+  const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
+
+  const llvm::opt::OptTable &getOpts() const { return *Opts; }
+
+  const DiagnosticsEngine &getDiags() const { return Diags; }
+
+  bool getCheckInputsExist() const { return CheckInputsExist; }
+
+  void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+
+  const std::string &getTitle() { return DriverTitle; }
+  void setTitle(std::string Value) { DriverTitle = Value; }
+
+  /// \brief Get the path to the main clang executable.
+  const char *getClangProgramPath() const {
+    return ClangExecutable.c_str();
+  }
+
+  /// \brief Get the path to where the clang executable was installed.
+  const char *getInstalledDir() const {
+    if (!InstalledDir.empty())
+      return InstalledDir.c_str();
+    return Dir.c_str();
+  }
+  void setInstalledDir(StringRef Value) {
+    InstalledDir = Value;
+  }
+
+  /// @}
+  /// @name Primary Functionality
+  /// @{
+
+  /// BuildCompilation - Construct a compilation object for a command
+  /// line argument vector.
+  ///
+  /// \return A compilation, or 0 if none was built for the given
+  /// argument vector. A null return value does not necessarily
+  /// indicate an error condition, the diagnostics should be queried
+  /// to determine if an error occurred.
+  Compilation *BuildCompilation(ArrayRef<const char *> Args);
+
+  /// @name Driver Steps
+  /// @{
+
+  /// ParseDriverMode - Look for and handle the driver mode option in Args.
+  void ParseDriverMode(ArrayRef<const char *> Args);
+
+  /// ParseArgStrings - Parse the given list of strings into an
+  /// ArgList.
+  llvm::opt::InputArgList *ParseArgStrings(ArrayRef<const char *> Args);
+
+  /// BuildInputs - Construct the list of inputs and their types from 
+  /// the given arguments.
+  ///
+  /// \param TC - The default host tool chain.
+  /// \param Args - The input arguments.
+  /// \param Inputs - The list to store the resulting compilation 
+  /// inputs onto.
+  void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
+                   InputList &Inputs) const;
+
+  /// BuildActions - Construct the list of actions to perform for the
+  /// given arguments, which are only done for a single architecture.
+  ///
+  /// \param TC - The default host tool chain.
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildActions(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
+                    const InputList &Inputs, ActionList &Actions) const;
+
+  /// BuildUniversalActions - Construct the list of actions to perform
+  /// for the given arguments, which may require a universal build.
+  ///
+  /// \param TC - The default host tool chain.
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildUniversalActions(const ToolChain &TC,
+                             llvm::opt::DerivedArgList &Args,
+                             const InputList &BAInputs,
+                             ActionList &Actions) const;
+
+  /// BuildJobs - Bind actions to concrete tools and translate
+  /// arguments to form the list of jobs to run.
+  ///
+  /// \param C - The compilation that is being built.
+  void BuildJobs(Compilation &C) const;
+
+  /// ExecuteCompilation - Execute the compilation according to the command line
+  /// arguments and return an appropriate exit code.
+  ///
+  /// This routine handles additional processing that must be done in addition
+  /// to just running the subprocesses, for example reporting errors, removing
+  /// temporary files, etc.
+  int ExecuteCompilation(const Compilation &C,
+     SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const;
+  
+  /// generateCompilationDiagnostics - Generate diagnostics information 
+  /// including preprocessed source file(s).
+  /// 
+  void generateCompilationDiagnostics(Compilation &C,
+                                      const Command *FailingCommand);
+
+  /// @}
+  /// @name Helper Methods
+  /// @{
+
+  /// PrintActions - Print the list of actions.
+  void PrintActions(const Compilation &C) const;
+
+  /// PrintHelp - Print the help text.
+  ///
+  /// \param ShowHidden - Show hidden options.
+  void PrintHelp(bool ShowHidden) const;
+
+  /// PrintVersion - Print the driver version.
+  void PrintVersion(const Compilation &C, raw_ostream &OS) const;
+
+  /// GetFilePath - Lookup \p Name in the list of file search paths.
+  ///
+  /// \param TC - The tool chain for additional information on
+  /// directories to search.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetFilePath(const char *Name, const ToolChain &TC) const;
+
+  /// GetProgramPath - Lookup \p Name in the list of program search paths.
+  ///
+  /// \param TC - The provided tool chain for additional information on
+  /// directories to search.
+  //
+  // FIXME: This should be in CompilationInfo.
+  std::string GetProgramPath(const char *Name, const ToolChain &TC) const;
+
+  /// HandleImmediateArgs - Handle any arguments which should be
+  /// treated before building actions or binding tools.
+  ///
+  /// \return Whether any compilation should be built for this
+  /// invocation.
+  bool HandleImmediateArgs(const Compilation &C);
+
+  /// ConstructAction - Construct the appropriate action to do for
+  /// \p Phase on the \p Input, taking in to account arguments
+  /// like -fsyntax-only or --analyze.
+  Action *ConstructPhaseAction(const llvm::opt::ArgList &Args, phases::ID Phase,
+                               Action *Input) const;
+
+  /// BuildJobsForAction - Construct the jobs to perform for the
+  /// action \p A.
+  void BuildJobsForAction(Compilation &C,
+                          const Action *A,
+                          const ToolChain *TC,
+                          const char *BoundArch,
+                          bool AtTopLevel,
+                          bool MultipleArchs,
+                          const char *LinkingOutput,
+                          InputInfo &Result) const;
+
+  /// GetNamedOutputPath - Return the name to use for the output of
+  /// the action \p JA. The result is appended to the compilation's
+  /// list of temporary or result files, as appropriate.
+  ///
+  /// \param C - The compilation.
+  /// \param JA - The action of interest.
+  /// \param BaseInput - The original input file that this action was
+  /// triggered by.
+  /// \param BoundArch - The bound architecture. 
+  /// \param AtTopLevel - Whether this is a "top-level" action.
+  /// \param MultipleArchs - Whether multiple -arch options were supplied.
+  const char *GetNamedOutputPath(Compilation &C,
+                                 const JobAction &JA,
+                                 const char *BaseInput,
+                                 const char *BoundArch,
+                                 bool AtTopLevel,
+                                 bool MultipleArchs) const;
+
+  /// GetTemporaryPath - Return the pathname of a temporary file to use 
+  /// as part of compilation; the file will have the given prefix and suffix.
+  ///
+  /// GCC goes to extra lengths here to be a bit more robust.
+  std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
+
+  /// ShouldUseClangCompiler - Should the clang compiler be used to
+  /// handle this action.
+  bool ShouldUseClangCompiler(const JobAction &JA) const;
+
+  bool IsUsingLTO(const llvm::opt::ArgList &Args) const;
+
+private:
+  /// \brief Retrieves a ToolChain for a particular target triple.
+  ///
+  /// Will cache ToolChains for the life of the driver object, and create them
+  /// on-demand.
+  const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
+                                StringRef DarwinArchName = "") const;
+
+  /// @}
+
+  /// \brief Get bitmasks for which option flags to include and exclude based on
+  /// the driver mode.
+  std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const;
+
+public:
+  /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
+  /// return the grouped values as integers. Numbers which are not
+  /// provided are set to 0.
+  ///
+  /// \return True if the entire string was parsed (9.2), or all
+  /// groups were parsed (10.3.5extrastuff). HadExtra is true if all
+  /// groups were parsed but extra characters remain at the end.
+  static bool GetReleaseVersion(const char *Str, unsigned &Major,
+                                unsigned &Minor, unsigned &Micro,
+                                bool &HadExtra);
+};
+
+/// \return True if the last defined optimization level is -Ofast.
+/// And False otherwise.
+bool isOptimizationLevelFast(const llvm::opt::ArgList &Args);
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
new file mode 100644
index 0000000..f3c33ae
--- /dev/null
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVERDIAGNOSTIC_H
+#define LLVM_CLANG_DRIVERDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define DRIVERSTART
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_DRIVER_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
new file mode 100644
index 0000000..5b19efe
--- /dev/null
+++ b/include/clang/Driver/Job.h
@@ -0,0 +1,163 @@
+//===--- Job.h - Commands to Execute ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_JOB_H_
+#define CLANG_DRIVER_JOB_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Option/Option.h"
+#include <memory>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+namespace driver {
+class Action;
+class Command;
+class Tool;
+
+// Re-export this as clang::driver::ArgStringList.
+using llvm::opt::ArgStringList;
+
+class Job {
+public:
+  enum JobClass {
+    CommandClass,
+    FallbackCommandClass,
+    JobListClass
+  };
+
+private:
+  JobClass Kind;
+
+protected:
+  Job(JobClass _Kind) : Kind(_Kind) {}
+public:
+  virtual ~Job();
+
+  JobClass getKind() const { return Kind; }
+
+  /// Print - Print this Job in -### format.
+  ///
+  /// \param OS - The stream to print on.
+  /// \param Terminator - A string to print at the end of the line.
+  /// \param Quote - Should separate arguments be quoted.
+  /// \param CrashReport - Whether to print for inclusion in a crash report.
+  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
+                     bool Quote, bool CrashReport = false) const = 0;
+};
+
+/// Command - An executable path/name and argument vector to
+/// execute.
+class Command : public Job {
+  /// Source - The action which caused the creation of this job.
+  const Action &Source;
+
+  /// Tool - The tool which caused the creation of this job.
+  const Tool &Creator;
+
+  /// The executable to run.
+  const char *Executable;
+
+  /// The list of program arguments (not including the implicit first
+  /// argument, which will be the executable).
+  llvm::opt::ArgStringList Arguments;
+
+public:
+  Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
+          const llvm::opt::ArgStringList &_Arguments);
+
+  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+             bool CrashReport = false) const override;
+
+  virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
+                      bool *ExecutionFailed) const;
+
+  /// getSource - Return the Action which caused the creation of this job.
+  const Action &getSource() const { return Source; }
+
+  /// getCreator - Return the Tool which caused the creation of this job.
+  const Tool &getCreator() const { return Creator; }
+
+  const char *getExecutable() const { return Executable; }
+
+  const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
+
+  static bool classof(const Job *J) {
+    return J->getKind() == CommandClass ||
+           J->getKind() == FallbackCommandClass;
+  }
+};
+
+/// Like Command, but with a fallback which is executed in case
+/// the primary command crashes.
+class FallbackCommand : public Command {
+public:
+  FallbackCommand(const Action &Source_, const Tool &Creator_,
+                  const char *Executable_, const ArgStringList &Arguments_,
+                  Command *Fallback_);
+
+  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+             bool CrashReport = false) const override;
+
+  int Execute(const StringRef **Redirects, std::string *ErrMsg,
+              bool *ExecutionFailed) const override;
+
+  static bool classof(const Job *J) {
+    return J->getKind() == FallbackCommandClass;
+  }
+
+private:
+  std::unique_ptr<Command> Fallback;
+};
+
+/// JobList - A sequence of jobs to perform.
+class JobList : public Job {
+public:
+  typedef SmallVector<Job*, 4> list_type;
+  typedef list_type::size_type size_type;
+  typedef list_type::iterator iterator;
+  typedef list_type::const_iterator const_iterator;
+
+private:
+  list_type Jobs;
+
+public:
+  JobList();
+  virtual ~JobList();
+
+  void Print(llvm::raw_ostream &OS, const char *Terminator,
+             bool Quote, bool CrashReport = false) const override;
+
+  /// Add a job to the list (taking ownership).
+  void addJob(Job *J) { Jobs.push_back(J); }
+
+  /// Clear the job list.
+  void clear();
+
+  const list_type &getJobs() const { return Jobs; }
+
+  size_type size() const { return Jobs.size(); }
+  iterator begin() { return Jobs.begin(); }
+  const_iterator begin() const { return Jobs.begin(); }
+  iterator end() { return Jobs.end(); }
+  const_iterator end() const { return Jobs.end(); }
+
+  static bool classof(const Job *J) {
+    return J->getKind() == JobListClass;
+  }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
new file mode 100644
index 0000000..6c3738a
--- /dev/null
+++ b/include/clang/Driver/Multilib.h
@@ -0,0 +1,167 @@
+//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
+#define CLANG_LIB_DRIVER_MULTILIB_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+
+/// This corresponds to a single GCC Multilib, or a segment of one controlled
+/// by a command line flag
+class Multilib {
+public:
+  typedef std::vector<std::string> flags_list;
+
+private:
+  std::string GCCSuffix;
+  std::string OSSuffix;
+  std::string IncludeSuffix;
+  flags_list Flags;
+
+public:
+  Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
+           StringRef IncludeSuffix = "");
+
+  /// \brief Get the detected GCC installation path suffix for the multi-arch
+  /// target variant. Always starts with a '/', unless empty
+  const std::string &gccSuffix() const {
+    assert(GCCSuffix.empty() ||
+           (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
+    return GCCSuffix;
+  }
+  /// Set the GCC installation path suffix.
+  Multilib &gccSuffix(StringRef S);
+
+  /// \brief Get the detected os path suffix for the multi-arch
+  /// target variant. Always starts with a '/', unless empty
+  const std::string &osSuffix() const {
+    assert(OSSuffix.empty() ||
+           (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
+    return OSSuffix;
+  }
+  /// Set the os path suffix.
+  Multilib &osSuffix(StringRef S);
+
+  /// \brief Get the include directory suffix. Always starts with a '/', unless
+  /// empty
+  const std::string &includeSuffix() const {
+    assert(IncludeSuffix.empty() ||
+           (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
+    return IncludeSuffix;
+  }
+  /// Set the include directory suffix
+  Multilib &includeSuffix(StringRef S);
+
+  /// \brief Get the flags that indicate or contraindicate this multilib's use
+  /// All elements begin with either '+' or '-'
+  const flags_list &flags() const { return Flags; }
+  flags_list &flags() { return Flags; }
+  /// Add a flag to the flags list
+  Multilib &flag(StringRef F) {
+    assert(F.front() == '+' || F.front() == '-');
+    Flags.push_back(F);
+    return *this;
+  }
+
+  /// \brief print summary of the Multilib
+  void print(raw_ostream &OS) const;
+
+  /// Check whether any of the 'against' flags contradict the 'for' flags.
+  bool isValid() const;
+
+  /// Check whether the default is selected
+  bool isDefault() const
+  { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
+
+  bool operator==(const Multilib &Other) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
+
+class MultilibSet {
+public:
+  typedef std::vector<Multilib> multilib_list;
+  typedef multilib_list::iterator iterator;
+  typedef multilib_list::const_iterator const_iterator;
+
+  struct FilterCallback {
+    virtual ~FilterCallback() {};
+    /// \return true iff the filter should remove the Multilib from the set
+    virtual bool operator()(const Multilib &M) const = 0;
+  };
+
+private:
+  multilib_list Multilibs;
+
+public:
+  MultilibSet() {}
+
+  /// Add an optional Multilib segment
+  MultilibSet &Maybe(const Multilib &M);
+
+  /// Add a set of mutually incompatible Multilib segments
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3, const Multilib &M4);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3, const Multilib &M4,
+                      const Multilib &M5);
+  MultilibSet &Either(const std::vector<Multilib> &Ms);
+
+  /// Filter out some subset of the Multilibs using a user defined callback
+  MultilibSet &FilterOut(const FilterCallback &F);
+  /// Filter out those Multilibs whose gccSuffix matches the given expression
+  MultilibSet &FilterOut(std::string Regex);
+
+  /// Add a completed Multilib to the set
+  void push_back(const Multilib &M);
+
+  /// Union this set of multilibs with another
+  void combineWith(const MultilibSet &MS);
+
+  /// Remove all of thie multilibs from the set
+  void clear() { Multilibs.clear(); }
+
+  iterator begin() { return Multilibs.begin(); }
+  const_iterator begin() const { return Multilibs.begin(); }
+
+  iterator end() { return Multilibs.end(); }
+  const_iterator end() const { return Multilibs.end(); }
+
+  /// Pick the best multilib in the set, \returns false if none are compatible
+  bool select(const Multilib::flags_list &Flags, Multilib &M) const;
+
+  unsigned size() const { return Multilibs.size(); }
+
+  void print(raw_ostream &OS) const;
+
+private:
+  /// Apply the filter to Multilibs and return the subset that remains
+  static multilib_list filterCopy(const FilterCallback &F,
+                                  const multilib_list &Ms);
+
+  /// Apply the filter to the multilib_list, removing those that don't match
+  static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
+}
+}
+
+#endif
+
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
new file mode 100644
index 0000000..cee705d
--- /dev/null
+++ b/include/clang/Driver/Options.h
@@ -0,0 +1,51 @@
+//===--- Options.h - Option info & table ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTIONS_H
+#define CLANG_DRIVER_OPTIONS_H
+
+namespace llvm {
+namespace opt {
+class OptTable;
+}
+}
+
+namespace clang {
+namespace driver {
+
+namespace options {
+/// Flags specifically for clang options.  Must not overlap with
+/// llvm::opt::DriverFlag.
+enum ClangFlags {
+  DriverOption = (1 << 4),
+  LinkerInput = (1 << 5),
+  NoArgumentUnused = (1 << 6),
+  Unsupported = (1 << 7),
+  CoreOption = (1 << 8),
+  CLOption = (1 << 9),
+  CC1Option = (1 << 10),
+  CC1AsOption = (1 << 11),
+  NoDriverOption = (1 << 12)
+};
+
+enum ID {
+    OPT_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+               HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/Options.inc"
+    LastOption
+#undef OPTION
+  };
+}
+
+llvm::opt::OptTable *createDriverOptTable();
+}
+}
+
+#endif
diff --git a/include/clang/Driver/Options.inc b/include/clang/Driver/Options.inc
new file mode 100644
index 0000000..c0a4cf4
--- /dev/null
+++ b/include/clang/Driver/Options.inc
@@ -0,0 +1,2190 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Option Parsing Definitions                                                  *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+/////////
+// Prefixes
+
+#ifdef PREFIX
+#define COMMA ,
+PREFIX(prefix_0, {0})
+PREFIX(prefix_1, {"-" COMMA 0})
+PREFIX(prefix_4, {"-" COMMA "--" COMMA 0})
+PREFIX(prefix_3, {"--" COMMA 0})
+PREFIX(prefix_2, {"/" COMMA "-" COMMA 0})
+#undef COMMA
+#endif
+
+/////////
+// Groups
+
+#ifdef OPTION
+OPTION(0, "<action group>", Action_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<CompileOnly group>", CompileOnly_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<I group>", I_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<M group>", M_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<O group>", O_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<R group>", R_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<R (with value) group>", R_value_Group, Group, R_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<T group>", T_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<W group>", W_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<W (with value) group>", W_value_Group, Group, W_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "</M group>", _SLASH_M_Group, Group, cl_compile_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang-cl options>", cl_Group, Group, INVALID, INVALID, 0, 0, 0,
+       "CL.EXE COMPATIBILITY OPTIONS", 0)
+OPTION(0, "<clang-cl compile-only options>", cl_compile_Group, Group, cl_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang-cl ignored options>", cl_ignored_Group, Group, cl_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang i group>", clang_i_Group, Group, i_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang ignored f group>", clang_ignored_f_Group, Group, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang_ignored_gcc_optimization_f_Group>", clang_ignored_gcc_optimization_f_Group, Group, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang ignored m group>", clang_ignored_m_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<d group>", d_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<f group>", f_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<f (clang-only) group>", f_clang_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<g group>", g_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<g flags group>", g_flags_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "gfortran Group", gfortran_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<i group>", i_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang internal options>", internal_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<clang debug/development internal options>", internal_debug_Group, Group, internal_Group, INVALID, 0, 0, 0,
+       "DEBUG/DEVELOPMENT OPTIONS", 0)
+OPTION(0, "<clang driver internal options>", internal_driver_Group, Group, internal_Group, INVALID, 0, 0, 0,
+       "DRIVER OPTIONS", 0)
+OPTION(0, "<m group>", m_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<m aarch64 features group>", m_aarch64_Features_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<m arm features group>", m_arm_Features_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<m hexagon features group>", m_hexagon_Features_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<m ppc features group>", m_ppc_Features_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<m x86 features group>", m_x86_Features_Group, Group, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<pedantic group>", pedantic_Group, Group, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<reserved libs group>", reserved_lib_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(0, "<u group>", u_Group, Group, INVALID, INVALID, 0, 0, 0, 0, 0)
+
+//////////
+// Options
+
+OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "###", _HASH_HASH_HASH, Flag, INVALID, INVALID, 0, DriverOption | CoreOption, 0,
+       "Print (but do not run) the commands to run for this compilation", 0)
+OPTION(prefix_2, "?", _SLASH_QUESTION, Flag, cl_Group, help, 0, CLOption | DriverOption, 0,
+       "Display available options", 0)
+OPTION(prefix_1, "A-", A_DASH, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "add-plugin", add_plugin, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use the named plugin action in addition to the default action", "<name>")
+OPTION(prefix_2, "AI", _SLASH_AI, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "all-warnings", _all_warnings, Flag, INVALID, Wall, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "all_load", all__load, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "allowable_client", allowable__client, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "analyze-auto", _analyze_auto, Flag, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyze-function=", analyze_function_EQ, Joined, INVALID, analyze_function, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyze-function", analyze_function, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run analysis on specific function", 0)
+OPTION(prefix_2, "analyze-", _SLASH_analyze_, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "analyzer-checker-help", analyzer_checker_help, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Display the list of analyzer checkers that are available", 0)
+OPTION(prefix_1, "analyzer-checker=", analyzer_checker_EQ, Joined, INVALID, analyzer_checker, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-checker", analyzer_checker, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Choose analyzer checkers to enable", 0)
+OPTION(prefix_1, "analyzer-config", analyzer_config, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Choose analyzer options to enable", 0)
+OPTION(prefix_1, "analyzer-constraints=", analyzer_constraints_EQ, Joined, INVALID, analyzer_constraints, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-constraints", analyzer_constraints, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Source Code Analysis - Symbolic Constraint Engines", 0)
+OPTION(prefix_1, "analyzer-disable-checker=", analyzer_disable_checker_EQ, Joined, INVALID, analyzer_disable_checker, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-disable-checker", analyzer_disable_checker, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Choose analyzer checkers to disable", 0)
+OPTION(prefix_1, "analyzer-disable-retry-exhausted", analyzer_disable_retry_exhausted, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)", 0)
+OPTION(prefix_1, "analyzer-display-progress", analyzer_display_progress, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit verbose output about the analyzer's progress", 0)
+OPTION(prefix_1, "analyzer-eagerly-assume", analyzer_eagerly_assume, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Eagerly assume the truth/falseness of some symbolic constraints", 0)
+OPTION(prefix_1, "analyzer-inline-max-stack-depth=", analyzer_inline_max_stack_depth_EQ, Joined, INVALID, analyzer_inline_max_stack_depth, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-inline-max-stack-depth", analyzer_inline_max_stack_depth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Bound on stack depth while inlining (4 by default)", 0)
+OPTION(prefix_1, "analyzer-inlining-mode=", analyzer_inlining_mode_EQ, Joined, INVALID, analyzer_inlining_mode, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-inlining-mode", analyzer_inlining_mode, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Specify the function selection heuristic used during inlining", 0)
+OPTION(prefix_1, "analyzer-max-loop", analyzer_max_loop, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "The maximum number of times the analyzer will go through a loop", 0)
+OPTION(prefix_3, "analyzer-no-default-checks", _analyzer_no_default_checks, Flag, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-opt-analyze-headers", analyzer_opt_analyze_headers, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Force the static analyzer to analyze functions defined in header files", 0)
+OPTION(prefix_1, "analyzer-opt-analyze-nested-blocks", analyzer_opt_analyze_nested_blocks, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Analyze the definitions of blocks in addition to functions", 0)
+OPTION(prefix_1, "analyzer-output=", analyzer_output_EQ, Joined, INVALID, analyzer_output, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_3, "analyzer-output", _analyzer_output, JoinedOrSeparate, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-output", analyzer_output, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Source Code Analysis - Output Options", 0)
+OPTION(prefix_1, "analyzer-purge=", analyzer_purge_EQ, Joined, INVALID, analyzer_purge, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-purge", analyzer_purge, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Source Code Analysis - Dead Symbol Removal Frequency", 0)
+OPTION(prefix_1, "analyzer-stats", analyzer_stats, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print internal analyzer statistics.", 0)
+OPTION(prefix_1, "analyzer-store=", analyzer_store_EQ, Joined, INVALID, analyzer_store, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "analyzer-store", analyzer_store, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Source Code Analysis - Abstract Memory Store Models", 0)
+OPTION(prefix_1, "analyzer-viz-egraph-graphviz", analyzer_viz_egraph_graphviz, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Display exploded graph using GraphViz", 0)
+OPTION(prefix_1, "analyzer-viz-egraph-ubigraph", analyzer_viz_egraph_ubigraph, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Display exploded graph using Ubigraph", 0)
+OPTION(prefix_3, "analyze", _analyze, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Run the static analyzer", 0)
+OPTION(prefix_1, "analyze", analyze, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run static analysis engine", 0)
+OPTION(prefix_4, "ansi", ansi, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "arange_sections", arange_sections, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit DWARF .debug_arange sections", 0)
+OPTION(prefix_2, "arch:", _SLASH_arch, Joined, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set architecture for code generation", 0)
+OPTION(prefix_1, "arch_errors_fatal", arch__errors__fatal, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "arch_only", arch__only, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "arch", arch, Separate, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "arcmt-check", arcmt_check, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Check for ARC migration issues that need manual handling", 0)
+OPTION(prefix_1, "arcmt-migrate-emit-errors", arcmt_migrate_emit_arc_errors, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Emit ARC errors even if the migrator can fix them", 0)
+OPTION(prefix_1, "arcmt-migrate-report-output", arcmt_migrate_report_output, Separate, INVALID, INVALID, 0, CC1Option, 0,
+       "Output path for the plist report", 0)
+OPTION(prefix_1, "arcmt-migrate", arcmt_migrate, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply modifications and produces temporary files that conform to ARC", 0)
+OPTION(prefix_1, "arcmt-modify", arcmt_modify, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply modifications to files to conform to ARC", 0)
+OPTION(prefix_3, "assemble", _assemble, Flag, INVALID, S, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "assert=", _assert_EQ, Joined, INVALID, A, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "assert", _assert, Separate, INVALID, A, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ast-dump-filter", ast_dump_filter, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use with -ast-dump or -ast-print to dump/print only AST declaration nodes having a certain substring in a qualified name. Use -ast-list to list all filterable declaration node names.", "<dump_filter>")
+OPTION(prefix_1, "ast-dump-lookups", ast_dump_lookups, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include name lookup table dumps in AST dumps", 0)
+OPTION(prefix_1, "ast-dump", ast_dump, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs and then debug dump them", 0)
+OPTION(prefix_1, "ast-list", ast_list, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs and print the list of declaration node qualified names", 0)
+OPTION(prefix_1, "ast-merge", ast_merge, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Merge the given AST file into the translation unit being compiled.", "<ast file>")
+OPTION(prefix_1, "ast-print", ast_print, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs and then pretty-print them", 0)
+OPTION(prefix_1, "ast-view", ast_view, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs and view them with GraphViz", 0)
+OPTION(prefix_1, "A", A, JoinedOrSeparate, INVALID, INVALID, 0, RenderJoined, 0, 0, 0)
+OPTION(prefix_1, "a", a, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "backend-option", backend_option, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Additional arguments to forward to LLVM backend (during code gen)", 0)
+OPTION(prefix_2, "bigobj", _SLASH_bigobj, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "bind_at_load", bind__at__load, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "bootclasspath=", _bootclasspath_EQ, Joined, INVALID, fbootclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "bootclasspath", _bootclasspath, Separate, INVALID, fbootclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "bundle_loader", bundle__loader, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "bundle", bundle, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "B", B, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "b", b, JoinedOrSeparate, INVALID, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "c-isystem", c_isystem, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add directory to the C SYSTEM include search path", "<directory>")
+OPTION(prefix_1, "cc1as", cc1as, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "cc1", cc1, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "ccc-arcmt-check", ccc_arcmt_check, Flag, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Check for ARC migration issues that need manual handling", 0)
+OPTION(prefix_1, "ccc-arcmt-migrate", ccc_arcmt_migrate, Separate, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Apply modifications and produces temporary files that conform to ARC", 0)
+OPTION(prefix_1, "ccc-arcmt-modify", ccc_arcmt_modify, Flag, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Apply modifications to files to conform to ARC", 0)
+OPTION(prefix_1, "ccc-gcc-name", ccc_gcc_name, Separate, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Name for native GCC compiler", "<gcc-path>")
+OPTION(prefix_1, "ccc-install-dir", ccc_install_dir, Separate, internal_debug_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Simulate installation in the given directory", 0)
+OPTION(prefix_1, "ccc-objcmt-migrate", ccc_objcmt_migrate, Separate, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Apply modifications and produces temporary files to migrate to modern ObjC syntax", 0)
+OPTION(prefix_1, "ccc-pch-is-pch", ccc_pch_is_pch, Flag, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Use lazy PCH for precompiled headers", 0)
+OPTION(prefix_1, "ccc-pch-is-pth", ccc_pch_is_pth, Flag, internal_driver_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Use pretokenized headers for precompiled headers", 0)
+OPTION(prefix_1, "ccc-print-bindings", ccc_print_bindings, Flag, internal_debug_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Show bindings of tools to actions", 0)
+OPTION(prefix_1, "ccc-print-phases", ccc_print_phases, Flag, internal_debug_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Dump list of actions to perform", 0)
+OPTION(prefix_1, "ccc-", ccc_, Joined, internal_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "CC", CC, Flag, INVALID, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "cfg-add-implicit-dtors", analysis_CFGAddImplicitDtors, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add C++ implicit destructors to CFGs for all analyses", 0)
+OPTION(prefix_1, "chain-include", chain_include, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include and chain a header file after turning it into PCH", "<file>")
+OPTION(prefix_1, "cl-fast-relaxed-math", cl_fast_relaxed_math, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__", 0)
+OPTION(prefix_1, "cl-finite-math-only", cl_finite_math_only, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.", 0)
+OPTION(prefix_1, "cl-kernel-arg-info", cl_kernel_arg_info, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Generate kernel argument metadata.", 0)
+OPTION(prefix_1, "cl-mad-enable", cl_mad_enable, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Enable less precise MAD instructions to be generated.", 0)
+OPTION(prefix_1, "cl-opt-disable", cl_opt_disable, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. This option disables all optimizations. The default is optimizations are enabled.", 0)
+OPTION(prefix_1, "cl-single-precision-constant", cl_single_precision_constant, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Treat double precision floating-point constant as single precision constant.", 0)
+OPTION(prefix_1, "cl-std=", cl_std_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL language standard to compile for", 0)
+OPTION(prefix_1, "cl-unsafe-math-optimizations", cl_unsafe_math_optimizations, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "OpenCL only. Allow unsafe floating-point optimizations.  Also implies -cl-no-signed-zeros and -cl-mad-enable", 0)
+OPTION(prefix_3, "CLASSPATH=", _CLASSPATH_EQ, Joined, INVALID, fclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "classpath=", _classpath_EQ, Joined, INVALID, fclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "CLASSPATH", _CLASSPATH, Separate, INVALID, fclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "classpath", _classpath, Separate, INVALID, fclasspath_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "client_name", client__name, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "clr", _SLASH_clr, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "code-completion-at=", code_completion_at_EQ, Joined, INVALID, code_completion_at, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "code-completion-at", code_completion_at, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Dump code-completion information at a location", "<file>:<line>:<column>")
+OPTION(prefix_1, "code-completion-brief-comments", code_completion_brief_comments, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include brief documentation comments in code-completion results.", 0)
+OPTION(prefix_1, "code-completion-macros", code_completion_macros, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include macros in code-completion results", 0)
+OPTION(prefix_1, "code-completion-patterns", code_completion_patterns, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include code patterns in code-completion results", 0)
+OPTION(prefix_4, "combine", combine, Flag, INVALID, INVALID, 0, DriverOption | Unsupported, 0, 0, 0)
+OPTION(prefix_3, "comments-in-macros", _comments_in_macros, Flag, INVALID, CC, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "comments", _comments, Flag, INVALID, C, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "compatibility_version", compatibility__version, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "compile", _compile, Flag, INVALID, c, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "compress-debug-sections", compress_debug_sections, Flag, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Compress DWARF debug sections using zlib", 0)
+OPTION(prefix_3, "constant-cfstrings", _constant_cfstrings, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "coverage-cfg-checksum", coverage_cfg_checksum, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit CFG checksum for functions in .gcno files.", 0)
+OPTION(prefix_1, "coverage-file=", coverage_file_EQ, Joined, INVALID, coverage_file, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "coverage-file", coverage_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit coverage data to this filename. The extension will be replaced.", 0)
+OPTION(prefix_1, "coverage-no-function-names-in-data", coverage_no_function_names_in_data, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit function names in .gcda files.", 0)
+OPTION(prefix_1, "coverage-version=", coverage_version_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Four-byte version string for gcov files.", 0)
+OPTION(prefix_4, "coverage", coverage, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "cpp-precomp", cpp_precomp, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "cpp", cpp, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "current_version", current__version, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "cxx-isystem", cxx_isystem, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to the C++ SYSTEM include search path", "<directory>")
+OPTION(prefix_1, "C", C, Flag, INVALID, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "C", _SLASH_C, Flag, cl_Group, C, 0, CLOption | DriverOption, 0,
+       "Don't discard comments when preprocessing", 0)
+OPTION(prefix_1, "c", c, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Only run preprocess, compile, and assemble steps", 0)
+OPTION(prefix_2, "c", _SLASH_c, Flag, cl_Group, c, 0, CLOption | DriverOption, 0,
+       "Compile only", 0)
+OPTION(prefix_2, "d2Zi+", _SLASH_d2Zi_PLUS, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "dA", dA, Flag, d_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dD", dD, Flag, d_Group, INVALID, 0, CC1Option, 0,
+       "Print macro definitions in -E mode in addition to normal output", 0)
+OPTION(prefix_1, "dead_strip", dead__strip, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "debug=", _debug_EQ, Joined, INVALID, g_Flag, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "debug", _debug, Flag, INVALID, g_Flag, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "define-macro=", _define_macro_EQ, Joined, INVALID, D, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "define-macro", _define_macro, Separate, INVALID, D, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "dependencies", _dependencies, Flag, INVALID, M, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dependency-dot", dependency_dot, Separate, INVALID, INVALID, 0, CC1Option, 0,
+       "Filename to write DOT-formatted header dependencies to", 0)
+OPTION(prefix_1, "dependency-file", dependency_file, Separate, INVALID, INVALID, 0, CC1Option, 0,
+       "Filename (or -) to write dependency output to", 0)
+OPTION(prefix_3, "dependent-lib=", dependent_lib, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add dependent library", 0)
+OPTION(prefix_1, "detailed-preprocessing-record", detailed_preprocessing_record, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "include a detailed record of preprocessing actions", 0)
+OPTION(prefix_1, "diagnostic-log-file", diagnostic_log_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Filename (or -) to log diagnostics to", 0)
+OPTION(prefix_1, "disable-free", disable_free, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable freeing of memory on exit", 0)
+OPTION(prefix_1, "disable-llvm-optzns", disable_llvm_optzns, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Don't run LLVM optimization passes", 0)
+OPTION(prefix_1, "disable-llvm-verifier", disable_llvm_verifier, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Don't run the LLVM IR verifier pass", 0)
+OPTION(prefix_1, "disable-objc-default-synthesize-properties", disable_objc_default_synthesize_properties, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "disable the default synthesis of Objective-C properties", 0)
+OPTION(prefix_1, "disable-red-zone", disable_red_zone, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not emit code that uses the red zone.", 0)
+OPTION(prefix_1, "dM", dM, Flag, d_Group, INVALID, 0, CC1Option, 0,
+       "Print macro definitions in -E mode instead of normal output", 0)
+OPTION(prefix_2, "doc", _SLASH_doc, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "driver-mode=", driver_mode, Joined, internal_driver_Group, INVALID, 0, CoreOption | DriverOption | HelpHidden, 0,
+       "Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'", 0)
+OPTION(prefix_1, "dump-deserialized-decls", dump_deserialized_pch_decls, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Dump declarations that are deserialized from PCH, for testing", 0)
+OPTION(prefix_1, "dump-raw-tokens", dump_raw_tokens, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Lex file in raw mode and dump raw tokens", 0)
+OPTION(prefix_1, "dump-tokens", dump_tokens, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run preprocessor, dump internal rep of tokens", 0)
+OPTION(prefix_1, "dumpmachine", dumpmachine, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dumpspecs", dumpspecs, Flag, INVALID, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "dumpversion", dumpversion, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dwarf-column-info", dwarf_column_info, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Turn on column location information.", 0)
+OPTION(prefix_1, "dwarf-debug-flags", dwarf_debug_flags, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "The string to embed in the Dwarf debug flags record.", 0)
+OPTION(prefix_1, "dwarf-debug-producer", dwarf_debug_producer, Separate, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "The string to embed in the Dwarf debug AT_producer record.", 0)
+OPTION(prefix_3, "dyld-prefix=", _dyld_prefix_EQ, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "dyld-prefix", _dyld_prefix, Separate, INVALID, _dyld_prefix_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dylib_file", dylib__file, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dylinker_install_name", dylinker__install__name, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dylinker", dylinker, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dynamiclib", dynamiclib, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "dynamic", dynamic, Flag, INVALID, INVALID, 0, NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_1, "D", D, JoinedOrSeparate, CompileOnly_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "D", _SLASH_D, JoinedOrSeparate, cl_Group, D, 0, CLOption | DriverOption, 0,
+       "Define macro", "<macro[=value]>")
+OPTION(prefix_1, "d", d_Flag, Flag, d_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "d", d_Joined, Joined, d_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "EB", EB, Flag, INVALID, mbig_endian, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "EH", _SLASH_EH, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Exception handling model", 0)
+OPTION(prefix_1, "EL", EL, Flag, INVALID, mlittle_endian, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "emit-ast", emit_ast, Flag, INVALID, INVALID, 0, 0, 0,
+       "Emit Clang AST files for source inputs", 0)
+OPTION(prefix_1, "emit-codegen-only", emit_codegen_only, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate machine code, but discard output", 0)
+OPTION(prefix_1, "emit-html", emit_html, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Output input source as HTML", 0)
+OPTION(prefix_1, "emit-llvm-bc", emit_llvm_bc, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs then convert to LLVM, emit .bc file", 0)
+OPTION(prefix_1, "emit-llvm-only", emit_llvm_only, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Build ASTs and convert to LLVM, discarding output", 0)
+OPTION(prefix_1, "emit-llvm", emit_llvm, Flag, Action_Group, INVALID, 0, CC1Option, 0,
+       "Use the LLVM representation for assembler and object files", 0)
+OPTION(prefix_1, "emit-module", emit_module, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate pre-compiled module file from a module map", 0)
+OPTION(prefix_1, "emit-obj", emit_obj, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit native object files", 0)
+OPTION(prefix_1, "emit-pch", emit_pch, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate pre-compiled header file", 0)
+OPTION(prefix_1, "emit-pth", emit_pth, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate pre-tokenized header file", 0)
+OPTION(prefix_3, "encoding=", _encoding_EQ, Joined, INVALID, fencoding_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "encoding", _encoding, Separate, INVALID, fencoding_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "entry", _entry, Flag, INVALID, e, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Eonly", Eonly, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Just run preprocessor, no output (for timings)", 0)
+OPTION(prefix_2, "EP", _SLASH_EP, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Disable linemarker output and preprocess to stdout", 0)
+OPTION(prefix_1, "error-on-deserialized-decl=", error_on_deserialized_pch_decl_EQ, Joined, INVALID, error_on_deserialized_pch_decl, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "error-on-deserialized-decl", error_on_deserialized_pch_decl, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit error if a specific declaration is deserialized from PCH, for testing", 0)
+OPTION(prefix_2, "errorReport", _SLASH_errorReport, Joined, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "exported_symbols_list", exported__symbols__list, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "extdirs=", _extdirs_EQ, Joined, INVALID, fextdirs_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "extdirs", _extdirs, Separate, INVALID, fextdirs_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "extra-warnings", _extra_warnings, Flag, INVALID, W_Joined, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "E", E, Flag, Action_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Only run the preprocessor", 0)
+OPTION(prefix_2, "E", _SLASH_E, Flag, cl_Group, E, 0, CLOption | DriverOption, 0,
+       "Preprocess to stdout", 0)
+OPTION(prefix_1, "e", e, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "faccess-control", faccess_control, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "faddress-space-map-mangling=", faddress_space_map_mangling_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the mode for address space map based mangling; OpenCL testing purposes only", "<yes|no|target>")
+OPTION(prefix_1, "faggressive-function-elimination", aggressive_function_elimination_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "falign-commons", align_commons_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "falign-functions=", falign_functions_EQ, Joined, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "falign-functions", align_functions_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fall-intrinsics", all_intrinsics_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "fallback", _SLASH_fallback, Flag, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Fall back to cl.exe if clang-cl fails to compile", 0)
+OPTION(prefix_1, "fallow-unsupported", fallow_unsupported, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "faltivec", faltivec, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable AltiVec vector initializer syntax", 0)
+OPTION(prefix_1, "fansi-escape-codes", fansi_escape_codes, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use ANSI escape codes for diagnostics", 0)
+OPTION(prefix_1, "fapple-kext", fapple_kext, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use Apple's kernel extensions ABI", 0)
+OPTION(prefix_1, "fapple-pragma-pack", fapple_pragma_pack, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable Apple gcc-compatible #pragma pack handling", 0)
+OPTION(prefix_1, "fasm-blocks", fasm_blocks, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fasm", fasm, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fassociative-math", fassociative_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fassume-sane-operator-new", fassume_sane_operator_new, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fastcp", fastcp, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fastf", fastf, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fast", fast, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fasynchronous-unwind-tables", fasynchronous_unwind_tables, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fauto-profile=", fauto_profile_EQ, Joined, INVALID, fprofile_sample_use_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fautolink", fautolink, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fautomatic", automatic_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "favor", _SLASH_favor, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "FA", _SLASH_FA, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Output assembly code file during compilation", 0)
+OPTION(prefix_2, "FA", _SLASH_FA_joined, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Fa", _SLASH_Fa, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Output assembly code to this file during compilation", "<file or directory>")
+OPTION(prefix_1, "fbackslash", backslash_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fbacktrace", backtrace_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fblas-matmul-limit=", fblas_matmul_limit_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fblocks-runtime-optional", fblocks_runtime_optional, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Weakly link in the blocks runtime", 0)
+OPTION(prefix_1, "fblocks", fblocks, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable the 'blocks' language feature", 0)
+OPTION(prefix_1, "fbootclasspath=", fbootclasspath_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fborland-extensions", fborland_extensions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Accept non-standard constructs supported by the Borland compiler", 0)
+OPTION(prefix_1, "fbounds-check", bounds_check_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fbracket-depth=", fbracket_depth_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fbracket-depth", fbracket_depth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Maximum nesting level for parentheses, brackets, and braces", 0)
+OPTION(prefix_1, "fbuild-session-timestamp=", fbuild_session_timestamp, Joined, i_Group, INVALID, 0, CC1Option, 0,
+       "Time when the current build session started", "<time since Epoch in seconds>")
+OPTION(prefix_1, "fbuiltin", fbuiltin, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcaret-diagnostics", fcaret_diagnostics, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcheck-array-temporaries", check_array_temporaries_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcheck=", fcheck_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fclasspath=", fclasspath_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcoarray=", fcoarray_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcolor-diagnostics", fcolor_diagnostics, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use colors in diagnostics", 0)
+OPTION(prefix_1, "fcomment-block-commands=", fcomment_block_commands, CommaJoined, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Treat each comma separated argument in <arg> as a documentation comment block command", "<arg>")
+OPTION(prefix_1, "fcommon", fcommon, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcompile-resource=", fcompile_resource_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconst-strings", fconst_strings, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use a const qualified type for string literals in C and ObjC", 0)
+OPTION(prefix_1, "fconstant-cfstrings", fconstant_cfstrings, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconstant-string-class=", fconstant_string_class_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconstant-string-class", fconstant_string_class, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Specify the class to use for constant Objective-C string objects.", "<class name>")
+OPTION(prefix_1, "fconstexpr-backtrace-limit=", fconstexpr_backtrace_limit_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconstexpr-backtrace-limit", fconstexpr_backtrace_limit, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).", "<N>")
+OPTION(prefix_1, "fconstexpr-depth=", fconstexpr_depth_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconstexpr-depth", fconstexpr_depth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Maximum depth of recursive constexpr function calls", 0)
+OPTION(prefix_1, "fconstexpr-steps=", fconstexpr_steps_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fconstexpr-steps", fconstexpr_steps, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Maximum number of steps in constexpr function evaluation", 0)
+OPTION(prefix_1, "fconvert=", fconvert_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcray-pointer", cray_pointer_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcreate-profile", fcreate_profile, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fcuda-is-device", fcuda_is_device, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate code for CUDA device", 0)
+OPTION(prefix_1, "fcxx-exceptions", fcxx_exceptions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable C++ exceptions", 0)
+OPTION(prefix_1, "fcxx-modules", fcxx_modules, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_2, "FC", _SLASH_FC, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fd-lines-as-code", d_lines_as_code_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fd-lines-as-comments", d_lines_as_comments_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdata-sections", fdata_sections, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Place each data in its own section (ELF Only)", 0)
+OPTION(prefix_1, "fdebug-compilation-dir", fdebug_compilation_dir, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "The compilation directory to embed in the debug info.", 0)
+OPTION(prefix_1, "fdebug-pass-arguments", fdebug_pass_arguments, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdebug-pass-structure", fdebug_pass_structure, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdebug-types-section", fdebug_types_section, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Place debug types in their own section (ELF Only)", 0)
+OPTION(prefix_1, "fdebugger-cast-result-to-id", fdebugger_cast_result_to_id, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable casting unknown expression results to id", 0)
+OPTION(prefix_1, "fdebugger-objc-literal", fdebugger_objc_literal, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable special debugger support for Objective-C subscripting and literals", 0)
+OPTION(prefix_1, "fdebugger-support", fdebugger_support, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable special debugger support behavior", 0)
+OPTION(prefix_1, "fdefault-double-8", default_double_8_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdefault-integer-8", default_integer_8_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdefault-real-8", default_real_8_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdefer-pop", anonymous_3, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdelayed-template-parsing", fdelayed_template_parsing, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Parse templated function definitions at the end of the translation unit", 0)
+OPTION(prefix_1, "fdeprecated-macro", fdeprecated_macro, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Defines the __DEPRECATED macro", 0)
+OPTION(prefix_1, "fdiagnostics-color=", fdiagnostics_color_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-color", fdiagnostics_color, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-fixit-info", fdiagnostics_fixit_info, Flag, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-format=", fdiagnostics_format_EQ, Joined, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-format", fdiagnostics_format, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Change diagnostic formatting to match IDE and command line tools", 0)
+OPTION(prefix_1, "fdiagnostics-parseable-fixits", fdiagnostics_parseable_fixits, Flag, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Print fix-its in machine parseable form", 0)
+OPTION(prefix_1, "fdiagnostics-print-source-range-info", fdiagnostics_print_source_range_info, Flag, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Print source range spans in numeric form", 0)
+OPTION(prefix_1, "fdiagnostics-show-category=", fdiagnostics_show_category_EQ, Joined, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-show-category", fdiagnostics_show_category, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print diagnostic category", 0)
+OPTION(prefix_1, "fdiagnostics-show-location=", fdiagnostics_show_location_EQ, Joined, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdiagnostics-show-note-include-stack", fdiagnostics_show_note_include_stack, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Display include stacks for diagnostic notes", 0)
+OPTION(prefix_1, "fdiagnostics-show-option", fdiagnostics_show_option, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Print option name with mappable diagnostics", 0)
+OPTION(prefix_1, "fdiagnostics-show-template-tree", fdiagnostics_show_template_tree, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Print a template comparison tree for differing templates", 0)
+OPTION(prefix_1, "fdisable-module-hash", fdisable_module_hash, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable the module hash", 0)
+OPTION(prefix_1, "fdollar-ok", dollar_ok_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdollars-in-identifiers", fdollars_in_identifiers, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Allow '$' in identifiers", 0)
+OPTION(prefix_1, "fdump-fortran-optimized", dump_fortran_optimized_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdump-fortran-original", dump_fortran_original_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdump-parse-tree", dump_parse_tree_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdump-record-layouts-simple", fdump_record_layouts_simple, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Dump record layout information in a simple form used for testing", 0)
+OPTION(prefix_1, "fdump-record-layouts", fdump_record_layouts, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Dump record layout information", 0)
+OPTION(prefix_1, "fdump-vtable-layouts", fdump_vtable_layouts, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Dump the layouts of all vtables that will be emitted in a translation unit", 0)
+OPTION(prefix_1, "fdwarf-directory-asm", fdwarf_directory_asm, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fdwarf2-cfi-asm", fdwarf2_cfi_asm, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Fd", _SLASH_Fd, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "felide-constructors", felide_constructors, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "feliminate-unused-debug-symbols", feliminate_unused_debug_symbols, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "feliminate-unused-debug-types", eliminate_unused_debug_types_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "femit-all-decls", femit_all_decls, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Emit all declarations, even if unused", 0)
+OPTION(prefix_1, "femit-coverage-data", femit_coverage_data, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Instrument the program to emit gcov coverage data when run.", 0)
+OPTION(prefix_1, "femit-coverage-notes", femit_coverage_notes, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit a gcov coverage notes file when compiling.", 0)
+OPTION(prefix_1, "fencode-extended-block-signature", fencode_extended_block_signature, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "enable extended encoding of block type signature", 0)
+OPTION(prefix_1, "fencoding=", fencoding_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ferror-limit=", ferror_limit_EQ, Joined, f_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "ferror-limit", ferror_limit, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the maximum number of errors to emit before stopping (0 = no limit).", "<N>")
+OPTION(prefix_1, "fexceptions", fexceptions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable support for exception handling", 0)
+OPTION(prefix_1, "fexpensive-optimizations", anonymous_1, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fextdirs=", fextdirs_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fextended-identifiers", anonymous_5, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fexternal-blas", external_blas_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Fe", _SLASH_Fe, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set output executable file or directory (ends in / or \\)", "<file or directory>")
+OPTION(prefix_1, "ff2c", f2c_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffake-address-space-map", ffake_address_space_map, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use a fake address space map; OpenCL testing purposes only", 0)
+OPTION(prefix_1, "ffast-math", ffast_math, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable the *frontend*'s 'fast-math' mode. This has no effect on optimizations, but provides a preprocessor macro __FAST_MATH__ the same as GCC's -ffast-math flag", 0)
+OPTION(prefix_1, "ffinite-math-only", ffinite_math_only, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "ffixed-form", fixed_form_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffixed-line-length-", ffixed_line_length_VALUE, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffixed-r9", ffixed_r9, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Reserve the r9 register (ARM only)", 0)
+OPTION(prefix_1, "ffloat-store", float_store_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffor-scope", ffor_scope, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fforbid-guard-variables", fforbid_guard_variables, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit an error if a C++ static local initializer would need a guard variable", 0)
+OPTION(prefix_1, "ffp-contract=", ffp_contract, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Form fused FP ops (e.g. FMAs): fast (everywhere) | on (according to FP_CONTRACT pragma, default) | off (never fuse)", 0)
+OPTION(prefix_1, "ffpe-trap=", ffpe_trap_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffree-form", free_form_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffree-line-length-", ffree_line_length_VALUE, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffreestanding", ffreestanding, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Assert that the compilation takes place in a freestanding environment", 0)
+OPTION(prefix_1, "ffrontend-optimize", frontend_optimize_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffunction-attribute-list", function_attribute_list_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ffunction-sections", ffunction_sections, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Place each function in its own section (ELF Only)", 0)
+OPTION(prefix_1, "fgcse", gcse_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fgnu-keywords", fgnu_keywords, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Allow GNU-extension keywords regardless of language standard", 0)
+OPTION(prefix_1, "fgnu-runtime", fgnu_runtime, Flag, f_Group, INVALID, 0, 0, 0,
+       "Generate output compatible with the standard GNU Objective-C runtime", 0)
+OPTION(prefix_1, "fgnu89-inline", fgnu89_inline, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use the gnu89 inline semantics", 0)
+OPTION(prefix_1, "fgnu", gnu_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fheinous-gnu-extensions", fheinous_gnu_extensions, Flag, INVALID, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fhonor-infinites", anonymous_7, Flag, INVALID, fhonor_infinities, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fhonor-infinities", fhonor_infinities, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fhonor-nans", fhonor_nans, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fhosted", fhosted, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fident", ident_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "filelist", filelist, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "filetype", filetype, Separate, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "Specify the output file type ('asm', 'null', or 'obj')", 0)
+OPTION(prefix_1, "fimplicit-none", implicit_none_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fimplicit-templates", implicit_templates_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "findirect-virtual-calls", anonymous_9, Flag, INVALID, fapple_kext, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finit-character=", finit_character_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finit-integer=", finit_integer_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finit-local-zero", init_local_zero_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finit-logical=", finit_logical_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finit-real=", finit_real_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finline-functions", finline_functions, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finline-limit=", finline_limit_EQ, Joined, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finline-limit", finline_limit_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finline", finline, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finput-charset=", finput_charset_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "finstrument-functions", finstrument_functions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Generate calls to instrument function entry and exit", 0)
+OPTION(prefix_1, "finteger-4-integer-8", integer_4_integer_8_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fintegrated-as", fintegrated_as, Flag, f_Group, INVALID, 0, DriverOption, 0,
+       "Enable the integrated assembler", 0)
+OPTION(prefix_1, "fintrinsic-modules-path", intrinsic_modules_path_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fivopts", ivopts_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fix-only-warnings", fix_only_warnings, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it advice only for warnings, not errors", 0)
+OPTION(prefix_1, "fix-what-you-can", fix_what_you_can, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it advice even in the presence of unfixable errors", 0)
+OPTION(prefix_1, "fixit-recompile", fixit_recompile, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it changes and recompile", 0)
+OPTION(prefix_1, "fixit-to-temporary", fixit_to_temp, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it changes to temporary files", 0)
+OPTION(prefix_1, "fixit=", fixit_EQ, Joined, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it advice creating a file with the given suffix", 0)
+OPTION(prefix_1, "fixit", fixit, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Apply fix-it advice to the input source", 0)
+OPTION(prefix_2, "FI", _SLASH_FI, JoinedOrSeparate, cl_Group, include, 0, CLOption | DriverOption, 0,
+       "Include file before parsing", 0)
+OPTION(prefix_2, "Fi", _SLASH_Fi, Joined, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set preprocess output file name", "<file>")
+OPTION(prefix_1, "flat_namespace", flat__namespace, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "flax-vector-conversions", flax_vector_conversions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "flimit-debug-info", flimit_debug_info, Flag, INVALID, fno_standalone_debug, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "flimited-precision=", flimited_precision_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "flto", flto, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmacro-backtrace-limit=", fmacro_backtrace_limit_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmacro-backtrace-limit", fmacro_backtrace_limit, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).", "<N>")
+OPTION(prefix_1, "fmath-errno", fmath_errno, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Require math functions to indicate errors by setting errno", 0)
+OPTION(prefix_1, "fmax-array-constructor=", fmax_array_constructor_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmax-errors=", fmax_errors_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmax-identifier-length", max_identifier_length_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmax-stack-var-size=", fmax_stack_var_size_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmax-subrecord-length=", fmax_subrecord_length_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmerge-all-constants", fmerge_all_constants, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmessage-length=", fmessage_length_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmessage-length", fmessage_length, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Format message diagnostics so that they fit within N columns or fewer, when possible.", "<N>")
+OPTION(prefix_1, "fmodule-map-file=", fmodule_map_file, JoinedOrSeparate, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Load this module map file", "<file>")
+OPTION(prefix_1, "fmodule-maps", fmodule_maps, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Read module maps to understand the structure of library headers", 0)
+OPTION(prefix_1, "fmodule-name=", fmodule_name, JoinedOrSeparate, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Specify the name of the module to build", "<name>")
+OPTION(prefix_1, "fmodule-private", module_private_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmodules-cache-path=", fmodules_cache_path, Joined, i_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Specify the module cache path", "<directory>")
+OPTION(prefix_1, "fmodules-decluse", fmodules_decluse, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Require declaration of modules used within a module", 0)
+OPTION(prefix_1, "fmodules-ignore-macro=", fmodules_ignore_macro, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Ignore the definition of the given macro when building and loading modules", 0)
+OPTION(prefix_1, "fmodules-prune-after=", fmodules_prune_after, Joined, i_Group, INVALID, 0, CC1Option, 0,
+       "Specify the interval (in seconds) after which a module file will be considered unused", "<seconds>")
+OPTION(prefix_1, "fmodules-prune-interval=", fmodules_prune_interval, Joined, i_Group, INVALID, 0, CC1Option, 0,
+       "Specify the interval (in seconds) between attempts to prune the module cache", "<seconds>")
+OPTION(prefix_1, "fmodules-search-all", fmodules_search_all, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Search even non-imported modules to resolve references", 0)
+OPTION(prefix_1, "fmodules-strict-decluse", fmodules_strict_decluse, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Like -fmodules-decluse but requires all headers to be in modules", 0)
+OPTION(prefix_1, "fmodules-user-build-path", fmodules_user_build_path, Separate, i_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Specify the module user build path", "<directory>")
+OPTION(prefix_1, "fmodules-validate-once-per-build-session", fmodules_validate_once_per_build_session, Flag, i_Group, INVALID, 0, CC1Option, 0,
+       "Don't verify input files for the modules if the module has been successfully validate or loaded during this build session", 0)
+OPTION(prefix_1, "fmodules-validate-system-headers", fmodules_validate_system_headers, Flag, i_Group, INVALID, 0, CC1Option, 0,
+       "Validate the system headers that a module depends on when loading the module", 0)
+OPTION(prefix_1, "fmodules", fmodules, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Enable the 'modules' language feature", 0)
+OPTION(prefix_1, "fms-compatibility-version=", fms_compatibility_version, Joined, f_Group, INVALID, 0, CC1Option | CoreOption, 0,
+       "Dot-separated value representing the Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))", 0)
+OPTION(prefix_1, "fms-compatibility", fms_compatibility, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable full Microsoft Visual C++ compatibility", 0)
+OPTION(prefix_1, "fms-extensions", fms_extensions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Accept some non-standard constructs supported by the Microsoft compiler", 0)
+OPTION(prefix_1, "fms-memptr-rep=", fms_memptr_rep_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fmsc-version=", fmsc_version, Joined, f_Group, INVALID, 0, DriverOption | CoreOption, 0,
+       "Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))", 0)
+OPTION(prefix_1, "fmudflapth", fmudflapth, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fmudflap", fmudflap, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Fm", _SLASH_Fm, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fnested-functions", fnested_functions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fnext-runtime", fnext_runtime, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-access-control", fno_access_control, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable C++ access control", 0)
+OPTION(prefix_1, "fno-aggressive-function-elimination", aggressive_function_elimination_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-align-commons", align_commons_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-align-functions", align_functions_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-all-intrinsics", all_intrinsics_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-altivec", fno_altivec, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-apple-pragma-pack", fno_apple_pragma_pack, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-asm-blocks", fno_asm_blocks, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-asm", fno_asm, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-associative-math", fno_associative_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-assume-sane-operator-new", fno_assume_sane_operator_new, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Don't assume that C++'s global operator new can't alias any pointer", 0)
+OPTION(prefix_1, "fno-asynchronous-unwind-tables", fno_asynchronous_unwind_tables, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-autolink", fno_autolink, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Disable generation of linker directives for automatic library linking", 0)
+OPTION(prefix_1, "fno-automatic", automatic_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-backslash", backslash_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-backtrace", backtrace_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-bitfield-type-align", fno_bitfield_type_align, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Ignore bit-field types when aligning structures", 0)
+OPTION(prefix_1, "fno-blocks", fno_blocks, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-borland-extensions", fno_borland_extensions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-bounds-check", bounds_check_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-builtin-", fno_builtin_, Joined, clang_ignored_f_Group, INVALID, 0, 0, 0,
+       "Disable implicit builtin knowledge of a specific function", 0)
+OPTION(prefix_1, "fno-builtin", fno_builtin, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable implicit builtin knowledge of functions", 0)
+OPTION(prefix_1, "fno-caret-diagnostics", fno_caret_diagnostics, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-check-array-temporaries", check_array_temporaries_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-color-diagnostics", fno_color_diagnostics, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-common", fno_common, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Compile common globals like normal definitions", 0)
+OPTION(prefix_1, "fno-const-strings", fno_const_strings, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Don't use a const qualified type for string literals in C and ObjC", 0)
+OPTION(prefix_1, "fno-constant-cfstrings", fno_constant_cfstrings, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable creation of CodeFoundation-type constant strings", 0)
+OPTION(prefix_1, "fno-crash-diagnostics", fno_crash_diagnostics, Flag, f_clang_Group, INVALID, 0, NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_1, "fno-cray-pointer", cray_pointer_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-cxx-exceptions", fno_cxx_exceptions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-cxx-modules", fno_cxx_modules, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fno-d-lines-as-code", d_lines_as_code_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-d-lines-as-comments", d_lines_as_comments_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-data-sections", fno_data_sections, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-debug-types-section", fno_debug_types_section, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-default-double-8", default_double_8_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-default-integer-8", default_integer_8_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-default-real-8", default_real_8_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-defer-pop", anonymous_4, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-delayed-template-parsing", fno_delayed_template_parsing, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-deprecated-macro", fno_deprecated_macro, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Undefines the __DEPRECATED macro", 0)
+OPTION(prefix_1, "fno-diagnostics-color", fno_diagnostics_color, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-diagnostics-fixit-info", fno_diagnostics_fixit_info, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not include fixit information in diagnostics", 0)
+OPTION(prefix_1, "fno-diagnostics-show-note-include-stack", fno_diagnostics_show_note_include_stack, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-diagnostics-show-option", fno_diagnostics_show_option, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-diagnostics-use-presumed-location", fno_diagnostics_use_presumed_location, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Ignore #line directives when displaying diagnostic locations", 0)
+OPTION(prefix_1, "fno-dollar-ok", dollar_ok_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-dollars-in-identifiers", fno_dollars_in_identifiers, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disallow '$' in identifiers", 0)
+OPTION(prefix_1, "fno-dump-fortran-optimized", dump_fortran_optimized_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-dump-fortran-original", dump_fortran_original_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-dump-parse-tree", dump_parse_tree_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-dwarf-directory-asm", fno_dwarf_directory_asm, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-dwarf2-cfi-asm", fno_dwarf2_cfi_asm, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-elide-constructors", fno_elide_constructors, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable C++ copy constructor elision", 0)
+OPTION(prefix_1, "fno-elide-type", fno_elide_type, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not elide types when printing diagnostics", 0)
+OPTION(prefix_1, "fno-eliminate-unused-debug-symbols", fno_eliminate_unused_debug_symbols, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-eliminate-unused-debug-types", eliminate_unused_debug_types_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-exceptions", fno_exceptions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-expensive-optimizations", anonymous_2, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-extended-identifiers", anonymous_6, Flag, f_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "fno-external-blas", external_blas_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-f2c", f2c_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-fast-math", fno_fast_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-finite-math-only", fno_finite_math_only, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-fixed-form", fixed_form_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-float-store", float_store_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-for-scope", fno_for_scope, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-free-form", free_form_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-frontend-optimize", frontend_optimize_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-function-attribute-list", function_attribute_list_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-function-sections", fno_function_sections, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-gcse", gcse_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-gnu-keywords", fno_gnu_keywords, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-gnu89-inline", fno_gnu89_inline, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-gnu", gnu_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-honor-infinites", anonymous_8, Flag, INVALID, fno_honor_infinities, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-honor-infinities", fno_honor_infinities, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-honor-nans", fno_honor_nans, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-ident", ident_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-implicit-none", implicit_none_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-implicit-templates", implicit_templates_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-init-local-zero", init_local_zero_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-inline-functions", fno_inline_functions, Flag, f_clang_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-inline-limit", finline_limit_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-inline", fno_inline, Flag, f_clang_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-integer-4-integer-8", integer_4_integer_8_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-integrated-as", fno_integrated_as, Flag, f_Group, INVALID, 0, CC1Option | DriverOption, 0,
+       "Disable the integrated assembler", 0)
+OPTION(prefix_1, "fno-intrinsic-modules-path", intrinsic_modules_path_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-ivopts", ivopts_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-keep-inline-functions", anonymous_21_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-lax-vector-conversions", fno_lax_vector_conversions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disallow implicit conversions between vectors with a different number of elements or different element types", 0)
+OPTION(prefix_1, "fno-limit-debug-info", fno_limit_debug_info, Flag, INVALID, fstandalone_debug, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-lto", fno_lto, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-math-builtin", fno_math_builtin, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable implicit builtin knowledge of math functions", 0)
+OPTION(prefix_1, "fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-max-identifier-length", max_identifier_length_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-merge-all-constants", fno_merge_all_constants, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disallow merging of constants", 0)
+OPTION(prefix_1, "fno-module-maps", fno_module_maps, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fno-module-private", module_private_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-modules-decluse", fno_modules_decluse, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fno-modules-error-recovery", fno_modules_error_recovery, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not automatically import modules for error recovery", 0)
+OPTION(prefix_1, "fno-modules-global-index", fno_modules_global_index, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not automatically generate or update the global module index", 0)
+OPTION(prefix_1, "fno-modules-search-all", fno_modules_search_all, Flag, f_Group, INVALID, 0, DriverOption | CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fno-modules", fno_modules, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fno-ms-compatibility", fno_ms_compatibility, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-ms-extensions", fno_ms_extensions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-no-keep-inline-functions", anonymous_21_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-non-call-exceptions", non_call_exceptions_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-objc-arc-exceptions", fno_objc_arc_exceptions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-objc-arc", fno_objc_arc, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-objc-exceptions", fno_objc_exceptions, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-objc-infer-related-result-type", fno_objc_infer_related_result_type, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "do not infer Objective-C related result type based on method family", 0)
+OPTION(prefix_1, "fno-objc-legacy-dispatch", fno_objc_legacy_dispatch, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-objc-nonfragile-abi", fno_objc_nonfragile_abi, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-omit-frame-pointer", fno_omit_frame_pointer, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-operator-names", fno_operator_names, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not treat C++ operator name keywords as synonyms for operators", 0)
+OPTION(prefix_1, "fno-optimize-sibling-calls", fno_optimize_sibling_calls, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-pack-derived", pack_derived_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-pack-struct", fno_pack_struct, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-permissive", permissive_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-PIC", fno_PIC, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-pic", fno_pic, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-PIE", fno_PIE, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-pie", fno_pie, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-prefetch-loop-arrays", prefetch_loop_arrays_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-printf", printf_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile-correction", profile_correction_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile-generate-sampling", profile_generate_sampling_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile-reusedist", profile_reusedist_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile-use", profile_use_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile-values", profile_values_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-profile", profile_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-protect-parens", protect_parens_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-range-check", range_check_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-4-real-10", real_4_real_10_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-4-real-16", real_4_real_16_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-4-real-8", real_4_real_8_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-8-real-10", real_8_real_10_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-8-real-16", real_8_real_16_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-real-8-real-4", real_8_real_4_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-realloc-lhs", realloc_lhs_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-reciprocal-math", fno_reciprocal_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-recursive", recursive_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-regs-graph", regs_graph_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-repack-arrays", repack_arrays_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-reroll-loops", fno_reroll_loops, Flag, f_Group, INVALID, 0, 0, 0,
+       "Turn off loop reroller", 0)
+OPTION(prefix_1, "fno-rewrite-includes", fno_rewrite_includes, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-ripa", ripa_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-rounding-math", rounding_math_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-rtti-data", fno_rtti_data, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Control emission of RTTI data", 0)
+OPTION(prefix_1, "fno-rtti", fno_rtti, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable generation of rtti information", 0)
+OPTION(prefix_1, "fno-sanitize-blacklist", fno_sanitize_blacklist, Flag, f_clang_Group, INVALID, 0, 0, 0,
+       "Don't use blacklist file for sanitizers", 0)
+OPTION(prefix_1, "fno-sanitize-memory-track-origins", fno_sanitize_memory_track_origins, Flag, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Disable origins tracking in MemorySanitizer", 0)
+OPTION(prefix_1, "fno-sanitize-recover", fno_sanitize_recover, Flag, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Disable sanitizer check recovery", 0)
+OPTION(prefix_1, "fno-sanitize-undefined-trap-on-error", fno_sanitize_undefined_trap_on_error, Flag, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-sanitize=", fno_sanitize_EQ, CommaJoined, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-schedule-insns", schedule_insns_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-second-underscore", second_underscore_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-see", see_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-short-enums", fno_short_enums, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-short-wchar", fno_short_wchar, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Force wchar_t to be an unsigned int", 0)
+OPTION(prefix_1, "fno-show-column", fno_show_column, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not include column number on diagnostics", 0)
+OPTION(prefix_1, "fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not include source location information with diagnostics", 0)
+OPTION(prefix_1, "fno-sign-zero", sign_zero_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-signaling-math", fno_signaling_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-signaling-nans", signaling_nans_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-signed-char", fno_signed_char, Flag, clang_ignored_f_Group, INVALID, 0, CC1Option, 0,
+       "Char is unsigned", 0)
+OPTION(prefix_1, "fno-signed-zeros", fno_signed_zeros, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-slp-vectorize-aggressive", fno_slp_vectorize_aggressive, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-slp-vectorize", fno_slp_vectorize, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-spec-constr-count", spec_constr_count_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-spell-checking", fno_spell_checking, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Disable spell-checking", 0)
+OPTION(prefix_1, "fno-stack-arrays", stack_arrays_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, 0, 0, 0,
+       "Disable the use of stack protectors", 0)
+OPTION(prefix_1, "fno-standalone-debug", fno_standalone_debug, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Limit debug information produced to reduce size of debug binary", 0)
+OPTION(prefix_1, "fno-strength-reduce", strength_reduce_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-strict-aliasing", fno_strict_aliasing, Flag, f_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "fno-strict-enums", fno_strict_enums, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-strict-modules-decluse", fno_modules_strict_decluse, Flag, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fno-strict-overflow", fno_strict_overflow, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-struct-path-tbaa", fno_struct_path_tbaa, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-threadsafe-statics", fno_threadsafe_statics, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Do not emit code to make initialization of local statics thread safe", 0)
+OPTION(prefix_1, "fno-tls-model", tls_model_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-tracer", tracer_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-trapping-math", fno_trapping_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-tree-salias", tree_salias_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-tree-slp-vectorize", anonymous_15, Flag, INVALID, fno_slp_vectorize, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-tree-vectorizer-verbose", tree_vectorizer_verbose_fno, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-tree-vectorize", anonymous_13, Flag, INVALID, fno_vectorize, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-underscoring", underscoring_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unroll-all-loops", unroll_all_loops_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unroll-loops", fno_unroll_loops, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Turn off loop unroller", 0)
+OPTION(prefix_1, "fno-unsafe-math-optimizations", fno_unsafe_math_optimizations, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unsigned-char", fno_unsigned_char, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unswitch-loops", unswitch_loops_fno, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-use-cxa-atexit", fno_use_cxa_atexit, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Don't use __cxa_atexit for calling destructors", 0)
+OPTION(prefix_1, "fno-use-init-array", fno_use_init_array, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Don't use .init_array instead of .ctors", 0)
+OPTION(prefix_1, "fno-validate-pch", fno_validate_pch, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable validation of precompiled headers", 0)
+OPTION(prefix_1, "fno-var-tracking", fno_var_tracking, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-vectorize", fno_vectorize, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-verbose-asm", fno_verbose_asm, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-wchar", fno_wchar, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable C++ builtin type wchar_t", 0)
+OPTION(prefix_1, "fno-whole-file", whole_file_fno, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-working-directory", fno_working_directory, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-wrapv", fno_wrapv, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fno-zero-initialized-in-bss", fno_zero_initialized_in_bss, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fnon-call-exceptions", non_call_exceptions_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-abi-version=", fobjc_abi_version_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-arc-cxxlib=", fobjc_arc_cxxlib_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Objective-C++ Automatic Reference Counting standard library kind", 0)
+OPTION(prefix_1, "fobjc-arc-exceptions", fobjc_arc_exceptions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use EH-safe code when synthesizing retains and releases in -fobjc-arc", 0)
+OPTION(prefix_1, "fobjc-arc", fobjc_arc, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Synthesize retain and release calls for Objective-C pointers", 0)
+OPTION(prefix_1, "fobjc-atdefs", fobjc_atdefs, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-call-cxx-cdtors", fobjc_call_cxx_cdtors, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-dispatch-method=", fobjc_dispatch_method_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Objective-C dispatch method to use", 0)
+OPTION(prefix_1, "fobjc-exceptions", fobjc_exceptions, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable Objective-C exceptions", 0)
+OPTION(prefix_1, "fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use GC exclusively for Objective-C related memory management", 0)
+OPTION(prefix_1, "fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable Objective-C garbage collection", 0)
+OPTION(prefix_1, "fobjc-infer-related-result-type", fobjc_infer_related_result_type, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-legacy-dispatch", fobjc_legacy_dispatch, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-link-runtime", fobjc_link_runtime, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-nonfragile-abi-version=", fobjc_nonfragile_abi_version_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-runtime-has-weak", fobjc_runtime_has_weak, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "The target Objective-C runtime supports ARC weak operations", 0)
+OPTION(prefix_1, "fobjc-runtime=", fobjc_runtime_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Specify the target Objective-C runtime kind and version", 0)
+OPTION(prefix_1, "fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fobjc-subscripting-legacy-runtime", fobjc_subscripting_legacy_runtime, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Allow Objective-C array and dictionary subscripting in legacy runtime", 0)
+OPTION(prefix_1, "fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fopenmp=", fopenmp_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fopenmp", fopenmp, Flag, f_Group, INVALID, 0, CC1Option | NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_1, "foperator-arrow-depth=", foperator_arrow_depth_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "foperator-arrow-depth", foperator_arrow_depth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Maximum number of 'operator->'s to call for a member access", 0)
+OPTION(prefix_1, "foptimize-sibling-calls", foptimize_sibling_calls, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "for-linker=", _for_linker_EQ, Joined, INVALID, Xlinker, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "for-linker", _for_linker, Separate, INVALID, Xlinker, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "force-link=", _force_link_EQ, Joined, INVALID, u, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "force-link", _force_link, Separate, INVALID, u, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "force_cpusubtype_ALL", force__cpusubtype__ALL, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "force_flat_namespace", force__flat__namespace, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "force_load", force__load, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "foutput-class-dir=", foutput_class_dir_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "foverride-record-layout=", foverride_record_layout_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Override record layouts with those in the given file", 0)
+OPTION(prefix_2, "Fo", _SLASH_Fo, Joined, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set output object file, or directory (ends in / or \\)", "<file or directory>")
+OPTION(prefix_1, "fpack-derived", pack_derived_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fpack-struct=", fpack_struct_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Specify the default maximum struct packing alignment", 0)
+OPTION(prefix_1, "fpack-struct", fpack_struct, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fparse-all-comments", fparse_all_comments, Flag, f_clang_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fpascal-strings", fpascal_strings, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Recognize and construct Pascal-style string literals", 0)
+OPTION(prefix_1, "fpcc-struct-return", fpcc_struct_return, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Override the default ABI to return all structs on the stack", 0)
+OPTION(prefix_1, "fpch-preprocess", fpch_preprocess, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fpermissive", permissive_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fPIC", fPIC, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fpic", fpic, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fPIE", fPIE, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fpie", fpie, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprefetch-loop-arrays", prefetch_loop_arrays_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprintf", printf_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-correction", profile_correction_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-dir=", fprofile_dir, Joined, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-generate-sampling", profile_generate_sampling_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-instr-generate", fprofile_instr_generate, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Generate instrumented code to collect execution counts", 0)
+OPTION(prefix_1, "fprofile-instr-use=", fprofile_instr_use_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Use instrumentation data for profile-guided optimization", 0)
+OPTION(prefix_1, "fprofile-instr-use", fprofile_instr_use, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-reusedist", profile_reusedist_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-sample-use=", fprofile_sample_use_EQ, Joined, f_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Enable sample-based profile guided optimizations", 0)
+OPTION(prefix_1, "fprofile-use=", fprofile_use_EQ, Joined, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-use", profile_use_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile-values", profile_values_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprofile", profile_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fprotect-parens", protect_parens_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Fp", _SLASH_Fp, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "fp", _SLASH_fp, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "framework", framework, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "frandom-seed=", frandom_seed_EQ, Joined, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frange-check", range_check_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-4-real-10", real_4_real_10_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-4-real-16", real_4_real_16_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-4-real-8", real_4_real_8_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-8-real-10", real_8_real_10_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-8-real-16", real_8_real_16_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freal-8-real-4", real_8_real_4_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frealloc-lhs", realloc_lhs_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freciprocal-math", freciprocal_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frecord-marker=", frecord_marker_EQ, Joined, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frecursive", recursive_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freg-struct-return", freg_struct_return, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Override the default ABI to return small structs in registers", 0)
+OPTION(prefix_1, "fregs-graph", regs_graph_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freorder-blocks", anonymous_11, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frepack-arrays", repack_arrays_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "freroll-loops", freroll_loops, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Turn on loop reroller", 0)
+OPTION(prefix_1, "fretain-comments-from-system-headers", fretain_comments_from_system_headers, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "frewrite-includes", frewrite_includes, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fripa", ripa_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frounding-math", rounding_math_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "frtti", frtti, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "FR", _SLASH_FR, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Fr", _SLASH_Fr, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fsanitize-blacklist=", fsanitize_blacklist, Joined, f_clang_Group, INVALID, 0, CC1Option | CoreOption, 0,
+       "Path to blacklist file for sanitizers", 0)
+OPTION(prefix_1, "fsanitize-memory-track-origins=", fsanitize_memory_track_origins_EQ, Joined, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Enable origins tracking in MemorySanitizer", 0)
+OPTION(prefix_1, "fsanitize-memory-track-origins", fsanitize_memory_track_origins, Flag, f_clang_Group, INVALID, 0, CC1Option, 0,
+       "Enable origins tracking in MemorySanitizer", 0)
+OPTION(prefix_1, "fsanitize-recover", fsanitize_recover, Flag, f_clang_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsanitize-undefined-trap-on-error", fsanitize_undefined_trap_on_error, Flag, f_clang_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fsanitize=", fsanitize_EQ, CommaJoined, f_clang_Group, INVALID, 0, CC1Option | CoreOption, 0,
+       "Enable runtime instrumentation for bug detection: address (memory errors) | thread (race detection) | undefined (miscellaneous undefined behavior)", "<check>")
+OPTION(prefix_1, "fsched-interblock", anonymous_10, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fschedule-insns", schedule_insns_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsecond-underscore", second_underscore_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsee", see_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fshort-enums", fshort_enums, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Allocate to an enum type only as many bytes as it needs for the declared range of possible values", 0)
+OPTION(prefix_1, "fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Force wchar_t to be a short unsigned int", 0)
+OPTION(prefix_1, "fshow-column", fshow_column, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "fshow-overloads=", fshow_overloads_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Which overload candidates to show when overload resolution fails: best|all; defaults to all", 0)
+OPTION(prefix_1, "fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsign-zero", sign_zero_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsignaling-math", fsignaling_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsignaling-nans", signaling_nans_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsigned-char", fsigned_char, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsigned-zeros", fsigned_zeros, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsized-deallocation", fsized_deallocation, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable C++1y sized global deallocation functions", 0)
+OPTION(prefix_1, "fsjlj-exceptions", fsjlj_exceptions, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use SjLj style exceptions", 0)
+OPTION(prefix_1, "fslp-vectorize-aggressive", fslp_vectorize_aggressive, Flag, f_Group, INVALID, 0, 0, 0,
+       "Enable the BB vectorization passes", 0)
+OPTION(prefix_1, "fslp-vectorize", fslp_vectorize, Flag, f_Group, INVALID, 0, 0, 0,
+       "Enable the superword-level parallelism vectorization passes", 0)
+OPTION(prefix_1, "fspec-constr-count", spec_constr_count_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fspell-checking", fspell_checking, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsplit-stack", fsplit_stack, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fstack-arrays", stack_arrays_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, 0, 0, 0,
+       "Force the usage of stack protectors for all functions", 0)
+OPTION(prefix_1, "fstack-protector-strong", fstack_protector_strong, Flag, f_Group, INVALID, 0, 0, 0,
+       "Use a strong heuristic to apply stack protectors to functions", 0)
+OPTION(prefix_1, "fstack-protector", fstack_protector, Flag, f_Group, INVALID, 0, 0, 0,
+       "Enable stack protectors for functions potentially vulnerable to stack smashing", 0)
+OPTION(prefix_1, "fstandalone-debug", fstandalone_debug, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Emit full debug info for all types used by the program", 0)
+OPTION(prefix_1, "fstrength-reduce", strength_reduce_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fstrict-aliasing", fstrict_aliasing, Flag, f_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "fstrict-enums", fstrict_enums, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Enable optimizations based on the strict definition of an enum's value range", 0)
+OPTION(prefix_1, "fstrict-overflow", fstrict_overflow, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fstruct-path-tbaa", fstruct_path_tbaa, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fsyntax-only", fsyntax_only, Flag, Action_Group, INVALID, 0, DriverOption | CC1Option, 0, 0, 0)
+OPTION(prefix_2, "FS", _SLASH_FS, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0,
+       "Force synchronous PDB writes", 0)
+OPTION(prefix_1, "ftabstop=", ftabstop_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftabstop", ftabstop, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the tab stop distance.", "<N>")
+OPTION(prefix_1, "ftemplate-backtrace-limit=", ftemplate_backtrace_limit_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftemplate-backtrace-limit", ftemplate_backtrace_limit, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).", "<N>")
+OPTION(prefix_1, "ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftemplate-depth=", ftemplate_depth_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftemplate-depth", ftemplate_depth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Maximum depth of recursive template instantiation", 0)
+OPTION(prefix_1, "fterminated-vtables", anonymous_16, Flag, INVALID, fapple_kext, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftest-coverage", ftest_coverage, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fthreadsafe-statics", fthreadsafe_statics, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftime-report", ftime_report, Flag, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "ftls-model=", ftlsmodel_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "ftls-model", tls_model_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftracer", tracer_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftrap-function=", ftrap_function_EQ, Joined, f_Group, INVALID, 0, CC1Option, 0,
+       "Issue call to specified function rather than a trap instruction", 0)
+OPTION(prefix_1, "ftrapping-math", ftrapping_math, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftrapv-handler=", ftrapv_handler_EQ, Joined, f_Group, INVALID, 0, 0, 0,
+       "Specify the function to be called on overflow", "<function name>")
+OPTION(prefix_1, "ftrapv-handler", ftrapv_handler, Separate, f_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "ftrapv", ftrapv, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Trap on integer overflow", 0)
+OPTION(prefix_1, "ftree-salias", tree_salias_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftree-slp-vectorize", anonymous_14, Flag, INVALID, fslp_vectorize, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftree-vectorizer-verbose", tree_vectorizer_verbose_f, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftree-vectorize", anonymous_12, Flag, INVALID, fvectorize, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ftype-visibility", ftype_visibility, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Default type visibility", 0)
+OPTION(prefix_1, "funderscoring", underscoring_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funit-at-a-time", funit_at_a_time, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funknown-anytype", funknown_anytype, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable parser support for the __unknown_anytype type; for testing purposes only", 0)
+OPTION(prefix_1, "funroll-all-loops", unroll_all_loops_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funroll-loops", funroll_loops, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Turn on loop unroller", 0)
+OPTION(prefix_1, "funsafe-math-optimizations", funsafe_math_optimizations, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funsigned-bitfields", funsigned_bitfields, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funsigned-char", funsigned_char, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funswitch-loops", unswitch_loops_f, Flag, clang_ignored_gcc_optimization_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "funwind-tables", funwind_tables, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fuse-cxa-atexit", fuse_cxa_atexit, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fuse-init-array", fuse_init_array, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Use .init_array instead of .ctors", 0)
+OPTION(prefix_1, "fuse-ld=", fuse_ld_EQ, Joined, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fuse-register-sized-bitfield-access", fuse_register_sized_bitfield_access, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use register sized accesses to bit-fields, when possible.", 0)
+OPTION(prefix_2, "FU", _SLASH_FU, JoinedOrSeparate, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fvectorize", fvectorize, Flag, f_Group, INVALID, 0, 0, 0,
+       "Enable the loop vectorization passes", 0)
+OPTION(prefix_1, "fverbose-asm", fverbose_asm, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fvisibility-inlines-hidden", fvisibility_inlines_hidden, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Give inline C++ member functions default visibility by default", 0)
+OPTION(prefix_1, "fvisibility-ms-compat", fvisibility_ms_compat, Flag, f_Group, INVALID, 0, 0, 0,
+       "Give global types 'default' visibility and global functions and variables 'hidden' visibility by default", 0)
+OPTION(prefix_1, "fvisibility=", fvisibility_EQ, Joined, f_Group, INVALID, 0, 0, 0,
+       "Set the default symbol visibility for all global declarations", 0)
+OPTION(prefix_1, "fvisibility", fvisibility, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Default type and symbol visibility", 0)
+OPTION(prefix_1, "fwhole-file", whole_file_f, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "fwrapv", fwrapv, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Treat signed integer overflow as two's complement", 0)
+OPTION(prefix_1, "fwritable-strings", fwritable_strings, Flag, f_Group, INVALID, 0, CC1Option, 0,
+       "Store string literals as writable data", 0)
+OPTION(prefix_2, "Fx", _SLASH_Fx, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "fzero-initialized-in-bss", fzero_initialized_in_bss, Flag, f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "F", F, JoinedOrSeparate, INVALID, INVALID, 0, RenderJoined | CC1Option, 0,
+       "Add directory to framework include search path", 0)
+OPTION(prefix_2, "F", _SLASH_F, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "g0", g0, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "G1", _SLASH_G1, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "g1", g1, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "G2", _SLASH_G2, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "g2", g2, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "g3", g3, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "G=", G_EQ, Joined, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_2, "GA", _SLASH_GA, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "gcc-toolchain=", gcc_toolchain, Joined, INVALID, INVALID, 0, DriverOption, 0,
+       "Use the gcc toolchain at the given directory", 0)
+OPTION(prefix_1, "gcc-toolchain", gcc_toolchain_legacy_spelling, Separate, INVALID, gcc_toolchain, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gcoff", gcoff, Joined, g_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "gcolumn-info", gcolumn_info, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gdwarf-2", gdwarf_2, Flag, g_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Generate source-level debug information with dwarf version 2", 0)
+OPTION(prefix_1, "gdwarf-3", gdwarf_3, Flag, g_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Generate source-level debug information with dwarf version 3", 0)
+OPTION(prefix_1, "gdwarf-4", gdwarf_4, Flag, g_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Generate source-level debug information with dwarf version 4", 0)
+OPTION(prefix_1, "gdwarf-aranges", gdwarf_aranges, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Gd", _SLASH_Gd, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Ge", _SLASH_Ge, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "GF-", _SLASH_GF_, Flag, cl_Group, fwritable_strings, 0, CLOption | DriverOption, 0,
+       "Disable string pooling", 0)
+OPTION(prefix_1, "gfull", gfull, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "GF", _SLASH_GF, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "ggdb0", ggdb0, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ggdb1", ggdb1, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ggdb2", ggdb2, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ggdb3", ggdb3, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ggdb", ggdb, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "ggnu-pubnames", ggnu_pubnames, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "GH", _SLASH_GH, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Gh", _SLASH_Gh, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "GL-", _SLASH_GL_, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "gline-tables-only", gline_tables_only, Flag, g_Group, INVALID, 0, CC1Option, 0,
+       "Emit debug line number tables only", 0)
+OPTION(prefix_2, "GL", _SLASH_GL, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Gm-", _SLASH_Gm_, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "gmlt", gmlt, Flag, INVALID, gline_tables_only, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Gm", _SLASH_Gm, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "gno-column-info", gno_column_info, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gno-record-gcc-switches", gno_record_gcc_switches, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gno-strict-dwarf", gno_strict_dwarf, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gnu-pubnames", gnu_pubnames, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit newer GNU style pubnames", 0)
+OPTION(prefix_2, "GR-", _SLASH_GR_, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Disable emission of RTTI data", 0)
+OPTION(prefix_1, "grecord-gcc-switches", grecord_gcc_switches, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "GR", _SLASH_GR, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Enable emission of RTTI data", 0)
+OPTION(prefix_2, "Gr", _SLASH_Gr, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "GS-", _SLASH_GS_, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "gsplit-dwarf", gsplit_dwarf, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gstabs", gstabs, Joined, g_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "gstrict-dwarf", gstrict_dwarf, Flag, g_flags_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "GS", _SLASH_GS, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Gs", _SLASH_Gs, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "gtoggle", gtoggle, Flag, g_flags_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_2, "GT", _SLASH_GT, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "gused", gused, Flag, g_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "gvms", gvms, Joined, g_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_2, "Gw-", _SLASH_Gw_, Flag, cl_Group, fno_data_sections, 0, CLOption | DriverOption, 0,
+       "Don't put each data item in its own section", 0)
+OPTION(prefix_2, "Gw", _SLASH_Gw, Flag, cl_Group, fdata_sections, 0, CLOption | DriverOption, 0,
+       "Put each data item in its own section", 0)
+OPTION(prefix_1, "gxcoff", gxcoff, Joined, g_Group, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_2, "GX", _SLASH_GX, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Gy-", _SLASH_Gy_, Flag, cl_Group, fno_function_sections, 0, CLOption | DriverOption, 0,
+       "Don't put each function in its own section", 0)
+OPTION(prefix_2, "Gy", _SLASH_Gy, Flag, cl_Group, ffunction_sections, 0, CLOption | DriverOption, 0,
+       "Put each function in its own section", 0)
+OPTION(prefix_2, "GZ", _SLASH_GZ, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Gz", _SLASH_Gz, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "G", G, JoinedOrSeparate, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "g", g_Flag, Flag, g_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Generate source-level debug information", 0)
+OPTION(prefix_1, "header-include-file", header_include_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Filename (or -) to write header include output to", 0)
+OPTION(prefix_1, "headerpad_max_install_names", headerpad__max__install__names, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "help-hidden", _help_hidden, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "HELP", _SLASH_HELP, Flag, cl_Group, help, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_4, "help", help, Flag, INVALID, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Display available options", 0)
+OPTION(prefix_2, "help", _SLASH_help, Flag, cl_Group, help, 0, CLOption | DriverOption, 0,
+       "Display available options", 0)
+OPTION(prefix_2, "homeparams", _SLASH_homeparams, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "hotpatch", _SLASH_hotpatch, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "H", H, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Show header includes and nesting depth", 0)
+OPTION(prefix_2, "H", _SLASH_H, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "I-", I_, Flag, I_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "idirafter", idirafter, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to AFTER include search path", 0)
+OPTION(prefix_1, "iframework", iframework, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to SYSTEM framework search path", 0)
+OPTION(prefix_3, "imacros=", _imacros_EQ, Joined, INVALID, imacros, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "imacros", imacros, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Include macros from file before parsing", "<file>")
+OPTION(prefix_1, "image_base", image__base, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-barrier", _include_barrier, Flag, INVALID, I_, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-directory-after=", _include_directory_after_EQ, Joined, INVALID, idirafter, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-directory-after", _include_directory_after, Separate, INVALID, idirafter, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-directory=", _include_directory_EQ, Joined, INVALID, I, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-directory", _include_directory, Separate, INVALID, I, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "include-pch", include_pch, Separate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Include precompiled header file", "<file>")
+OPTION(prefix_3, "include-prefix=", _include_prefix_EQ, Joined, INVALID, iprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-prefix", _include_prefix, Separate, INVALID, iprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "include-pth", include_pth, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include file before parsing", "<file>")
+OPTION(prefix_3, "include-with-prefix-after=", _include_with_prefix_after_EQ, Joined, INVALID, iwithprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-with-prefix-after", _include_with_prefix_after, Separate, INVALID, iwithprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-with-prefix-before=", _include_with_prefix_before_EQ, Joined, INVALID, iwithprefixbefore, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-with-prefix-before", _include_with_prefix_before, Separate, INVALID, iwithprefixbefore, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-with-prefix=", _include_with_prefix_EQ, Joined, INVALID, iwithprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include-with-prefix", _include_with_prefix, Separate, INVALID, iwithprefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "include=", _include_EQ, Joined, INVALID, include, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "include", include, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Include file before parsing", "<file>")
+OPTION(prefix_1, "index-header-map", index_header_map, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Make the next included directory (-I or -F) an indexer header map", 0)
+OPTION(prefix_1, "init-only", init_only, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Only execute frontend initialization", 0)
+OPTION(prefix_1, "init", init, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "install_name", install__name, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "integrated-as", anonymous_19, Flag, INVALID, fintegrated_as, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "internal-externc-isystem", internal_externc_isystem, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add directory to the internal system include search path with implicit extern \"C\" semantics; these are assumed to not be user-provided and are used to model system and standard headers' paths.", "<directory>")
+OPTION(prefix_1, "internal-isystem", internal_isystem, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add directory to the internal system include search path; these are assumed to not be user-provided and are used to model system and standard headers' paths.", "<directory>")
+OPTION(prefix_1, "iprefix", iprefix, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Set the -iwithprefix/-iwithprefixbefore prefix", "<dir>")
+OPTION(prefix_1, "iquote", iquote, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to QUOTE include search path", "<directory>")
+OPTION(prefix_1, "isysroot", isysroot, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Set the system root directory (usually /)", "<dir>")
+OPTION(prefix_1, "isystem", isystem, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to SYSTEM include search path", "<directory>")
+OPTION(prefix_1, "ivfsoverlay", ivfsoverlay, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Overlay the virtual filesystem described by file over the real file system", 0)
+OPTION(prefix_1, "iwithprefixbefore", iwithprefixbefore, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Set directory to include search path with prefix", "<dir>")
+OPTION(prefix_1, "iwithprefix", iwithprefix, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Set directory to SYSTEM include search path with prefix", "<dir>")
+OPTION(prefix_1, "iwithsysroot", iwithsysroot, JoinedOrSeparate, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Add directory to SYSTEM include search path, absolute paths are relative to -isysroot", "<directory>")
+OPTION(prefix_1, "I", I, JoinedOrSeparate, I_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "Add directory to include search path", 0)
+OPTION(prefix_2, "I", _SLASH_I, JoinedOrSeparate, cl_Group, I, 0, CLOption | DriverOption, 0,
+       "Add directory to include search path", "<dir>")
+OPTION(prefix_1, "i", i, Joined, i_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "J", J, JoinedOrSeparate, gfortran_Group, INVALID, 0, RenderJoined, 0, 0, 0)
+OPTION(prefix_2, "J", _SLASH_J, Flag, cl_Group, funsigned_char, 0, CLOption | DriverOption, 0,
+       "Make char type unsigned", 0)
+OPTION(prefix_1, "keep_private_externs", keep__private__externs, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "kernel-", _SLASH_kernel_, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "kernel", _SLASH_kernel, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "language=", _language_EQ, Joined, INVALID, x, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "language", _language, Separate, INVALID, x, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "lazy_framework", lazy__framework, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "lazy_library", lazy__library, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_2, "LDd", _SLASH_LDd, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Create debug DLL", 0)
+OPTION(prefix_2, "LD", _SLASH_LD, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Create DLL", 0)
+OPTION(prefix_3, "library-directory=", _library_directory_EQ, Joined, INVALID, L, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "library-directory", _library_directory, Separate, INVALID, L, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "link", _SLASH_link, RemainingArgs, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Forward options to the linker", "<options>")
+OPTION(prefix_2, "LN", _SLASH_LN, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "load", load, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Load the named plugin (dynamic shared object)", "<dsopath>")
+OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, 0, RenderJoined, 0, 0, 0)
+OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, 0, LinkerInput | RenderJoined, 0, 0, 0)
+OPTION(prefix_1, "m16", m16, Flag, m_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "m32", m32, Flag, m_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "m3dnowa", m3dnowa, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "m3dnow", m3dnow, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "m64", m64, Flag, m_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mabi=", mabi_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Mach", Mach, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "maes", maes, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "main-file-name", main_file_name, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Main file name to use for debug info", 0)
+OPTION(prefix_1, "maltivec", maltivec, Flag, INVALID, faltivec, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "march=", march_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "marm", marm, Flag, INVALID, mno_thumb, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "masm-verbose", masm_verbose, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate verbose assembly output", 0)
+OPTION(prefix_1, "masm=", masm_EQ, Joined, m_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "mavx2", mavx2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mavx512cd", mavx512cd, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mavx512er", mavx512er, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mavx512f", mavx512f, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mavx512pf", mavx512pf, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mavx", mavx, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mbig-endian", mbig_endian, Flag, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "mbmi2", mbmi2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mbmi", mbmi, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mcheck-zero-division", mcheck_zero_division, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mcmodel=", mcmodel_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mcode-model", mcode_model, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "The code model to use", 0)
+OPTION(prefix_1, "mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mconstructor-aliases", mconstructor_aliases, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Emit complete constructors and destructors as aliases when possible", 0)
+OPTION(prefix_1, "mcpu=", mcpu_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mcrbits", mcrbits, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mcrc", mcrc, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Allow use of CRC instructions (ARM only)", 0)
+OPTION(prefix_1, "mcx16", mcx16, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_2, "MDd", _SLASH_MDd, Flag, _SLASH_M_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use DLL debug run-time", 0)
+OPTION(prefix_1, "mdebug-pass", mdebug_pass, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable additional debug output", 0)
+OPTION(prefix_1, "mdisable-fp-elim", mdisable_fp_elim, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable frame pointer elimination optimization", 0)
+OPTION(prefix_1, "mdisable-tail-calls", mdisable_tail_calls, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable tail call optimization, keeping the call stack accurate", 0)
+OPTION(prefix_1, "mdouble-float", mdouble_float, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mdspr2", mdspr2, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mdsp", mdsp, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "MD", MD, Flag, M_Group, INVALID, 0, 0, 0,
+       "Write a depfile containing user and system headers", 0)
+OPTION(prefix_2, "MD", _SLASH_MD, Flag, _SLASH_M_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use DLL run-time", 0)
+OPTION(prefix_1, "menable-no-infs", menable_no_infinities, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Allow optimization to assume there are no infinities.", 0)
+OPTION(prefix_1, "menable-no-nans", menable_no_nans, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Allow optimization to assume there are no NaNs.", 0)
+OPTION(prefix_1, "menable-unsafe-fp-math", menable_unsafe_fp_math, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Allow unsafe floating-point math optimizations which may decrease precision", 0)
+OPTION(prefix_1, "mf16c", mf16c, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mfloat-abi=", mfloat_abi_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mfloat-abi", mfloat_abi, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "The float ABI to use", 0)
+OPTION(prefix_1, "mfma4", mfma4, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mfma", mfma, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mfp32", mfp32, Flag, m_Group, INVALID, 0, 0, 0,
+       "Use 32-bit floating point registers (MIPS only)", 0)
+OPTION(prefix_1, "mfp64", mfp64, Flag, m_Group, INVALID, 0, 0, 0,
+       "Use 64-bit floating point registers (MIPS only)", 0)
+OPTION(prefix_1, "mfpmath=", mfpmath_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mfpmath", mfpmath, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Which unit to use for fp math", 0)
+OPTION(prefix_1, "mfprnd", mfprnd, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mfpu=", mfpu_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mfpxx", mfpxx, Flag, m_Group, INVALID, 0, HelpHidden, 0,
+       "Avoid FPU mode dependent operations when used with the O32 ABI", 0)
+OPTION(prefix_1, "MF", MF, JoinedOrSeparate, M_Group, INVALID, 0, 0, 0,
+       "Write depfile output from -MMD, -MD, -MM, or -M to <file>", "<file>")
+OPTION(prefix_1, "mgeneral-regs-only", mgeneral_regs_only, Flag, m_aarch64_Features_Group, INVALID, 0, 0, 0,
+       "Generate code which only uses the general purpose registers (AArch64 only)", 0)
+OPTION(prefix_1, "mglobal-merge", mglobal_merge, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "MG", MG, Flag, M_Group, INVALID, 0, CC1Option, 0,
+       "Add missing headers to depfile", 0)
+OPTION(prefix_1, "mhard-float", mhard_float, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "mhwdiv=", _mhwdiv_EQ, Joined, INVALID, mhwdiv_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mhwdiv=", mhwdiv_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "mhwdiv", _mhwdiv, Separate, INVALID, mhwdiv_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mieee-fp", mieee_fp, Flag, clang_ignored_m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mieee-rnd-near", mieee_rnd_near, Flag, m_hexagon_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "migrate", _migrate, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Run the migrator", 0)
+OPTION(prefix_1, "migrate", migrate, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Migrate source code", 0)
+OPTION(prefix_1, "mimplicit-float", mimplicit_float, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "minline-all-stringops", minline_all_stringops, Flag, clang_ignored_m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mios-simulator-version-min=", mios_simulator_version_min_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mios-version-min=", mios_version_min_EQ, Joined, INVALID, miphoneos_version_min_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mips16", mips16, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mips1", mips1, Flag, INVALID, march_EQ, "mips1\0", HelpHidden, 0,
+       "Equivalent to -march=mips1", 0)
+OPTION(prefix_1, "mips2", mips2, Flag, INVALID, march_EQ, "mips2\0", HelpHidden, 0,
+       "Equivalent to -march=mips2", 0)
+OPTION(prefix_1, "mips32r2", mips32r2, Flag, INVALID, march_EQ, "mips32r2\0", HelpHidden, 0,
+       "Equivalent to -march=mips32r2", 0)
+OPTION(prefix_1, "mips32r6", mips32r6, Flag, INVALID, march_EQ, "mips32r6\0", HelpHidden, 0,
+       "Equivalent to -march=mips32r6", 0)
+OPTION(prefix_1, "mips32", mips32, Flag, INVALID, march_EQ, "mips32\0", HelpHidden, 0,
+       "Equivalent to -march=mips32", 0)
+OPTION(prefix_1, "mips3", mips3, Flag, INVALID, march_EQ, "mips3\0", HelpHidden, 0,
+       "Equivalent to -march=mips3", 0)
+OPTION(prefix_1, "mips4", mips4, Flag, INVALID, march_EQ, "mips4\0", HelpHidden, 0,
+       "Equivalent to -march=mips4", 0)
+OPTION(prefix_1, "mips5", mips5, Flag, INVALID, march_EQ, "mips5\0", HelpHidden, 0,
+       "Equivalent to -march=mips5", 0)
+OPTION(prefix_1, "mips64r2", mips64r2, Flag, INVALID, march_EQ, "mips64r2\0", HelpHidden, 0,
+       "Equivalent to -march=mips64r2", 0)
+OPTION(prefix_1, "mips64r6", mips64r6, Flag, INVALID, march_EQ, "mips64r6\0", HelpHidden, 0,
+       "Equivalent to -march=mips64r6", 0)
+OPTION(prefix_1, "mips64", mips64, Flag, INVALID, march_EQ, "mips64\0", HelpHidden, 0,
+       "Equivalent to -march=mips64", 0)
+OPTION(prefix_1, "mkernel", mkernel, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mldc1-sdc1", mldc1_sdc1, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mlimit-float-precision", mlimit_float_precision, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Limit float precision to the given value", 0)
+OPTION(prefix_1, "mlink-bitcode-file", mlink_bitcode_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Link the given bitcode file before performing optimizations.", 0)
+OPTION(prefix_1, "mlinker-version=", mlinker_version_EQ, Joined, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "mlittle-endian", mlittle_endian, Flag, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "mllvm", mllvm, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | CoreOption, 0,
+       "Additional arguments to forward to LLVM's option processing", 0)
+OPTION(prefix_1, "mlong-calls", mlong_calls, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Generate an indirect jump to enable jumps further than 64M", 0)
+OPTION(prefix_1, "mlzcnt", mlzcnt, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "MMD", MMD, Flag, M_Group, INVALID, 0, 0, 0,
+       "Write a depfile containing user headers", 0)
+OPTION(prefix_1, "mmfcrf", mmfcrf, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mmicromips", mmicromips, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mms-bitfields", mms_bitfields, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Set the default structure layout to be compatible with the Microsoft compiler standard", 0)
+OPTION(prefix_1, "mmsa", mmsa, Flag, m_Group, INVALID, 0, 0, 0,
+       "Enable MSA ASE (MIPS only)", 0)
+OPTION(prefix_1, "MM", MM, Flag, M_Group, INVALID, 0, 0, 0,
+       "Like -MMD, but also implies -E and writes to stdout by default", 0)
+OPTION(prefix_1, "mnan=", mnan_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-3dnow", mno_3dnow, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-aes", mno_aes, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-altivec", mno_altivec, Flag, INVALID, fno_altivec, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-avx2", mno_avx2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-avx512cd", mno_avx512cd, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-avx512er", mno_avx512er, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-avx512f", mno_avx512f, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-avx512pf", mno_avx512pf, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-avx", mno_avx, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-bmi2", mno_bmi2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-bmi", mno_bmi, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-check-zero-division", mno_check_zero_division, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-constant-cfstrings", mno_constant_cfstrings, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-crbits", mno_crbits, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-dspr2", mno_dspr2, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-dsp", mno_dsp, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-f16c", mno_f16c, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-fma4", mno_fma4, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-fma", mno_fma, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-fprnd", mno_fprnd, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-global-merge", mno_global_merge, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Disable merging of globals", 0)
+OPTION(prefix_1, "mno-implicit-float", mno_implicit_float, Flag, m_Group, INVALID, 0, 0, 0,
+       "Don't generate implicit floating point instructions", 0)
+OPTION(prefix_1, "mno-inline-all-stringops", mno_inline_all_stringops, Flag, clang_ignored_m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-ldc1-sdc1", mno_ldc1_sdc1, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-long-calls", mno_long_calls, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Restore the default behaviour of not generating long calls", 0)
+OPTION(prefix_1, "mno-lzcnt", mno_lzcnt, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-mfcrf", mno_mfcrf, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-micromips", mno_micromips, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-mips16", mno_mips16, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-mmx", mno_mmx, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-msa", mno_msa, Flag, m_Group, INVALID, 0, 0, 0,
+       "Disable MSA ASE (MIPS only)", 0)
+OPTION(prefix_1, "mno-odd-spreg", mno_odd_spreg, Flag, m_Group, INVALID, 0, HelpHidden, 0,
+       "Disable odd single-precision floating point registers", 0)
+OPTION(prefix_1, "mno-omit-leaf-frame-pointer", mno_omit_leaf_frame_pointer, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-pascal-strings", mno_pascal_strings, Flag, INVALID, fno_pascal_strings, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-pclmul", mno_pclmul, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-popcntd", mno_popcntd, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-popcnt", mno_popcnt, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-prfchw", mno_prfchw, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-qpx", mno_qpx, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-rdrnd", mno_rdrnd, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-rdseed", mno_rdseed, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-relax-all", mno_relax_all, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-restrict-it", mno_restrict_it, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Allow generation of deprecated IT blocks for ARMv8. It is off by default for ARMv8 Thumb mode", 0)
+OPTION(prefix_1, "mno-rtd", mno_rtd, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-rtm", mno_rtm, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sha", mno_sha, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse4.1", mno_sse4_1, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse4.2", mno_sse4_2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse4", mno_sse4, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-stackrealign", mno_stackrealign, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-tbm", mno_tbm, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-thumb", mno_thumb, Flag, m_arm_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-unaligned-access", mno_unaligned_access, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Force all memory accesses to be aligned (AArch32/AArch64 only)", 0)
+OPTION(prefix_1, "mno-vsx", mno_vsx, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-xgot", mno_xgot, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mno-xop", mno_xop, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mno-zero-initialized-in-bss", mno_zero_initialized_in_bss, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not put zero initialized data in the BSS", 0)
+OPTION(prefix_1, "mnocrc", mnocrc, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Disallow use of CRC instructions (ARM only)", 0)
+OPTION(prefix_1, "mnoexecstack", mno_exec_stack, Flag, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Mark the file as not needing an executable stack", 0)
+OPTION(prefix_1, "modd-spreg", modd_spreg, Flag, m_Group, INVALID, 0, HelpHidden, 0,
+       "Enable odd single-precision floating point registers", 0)
+OPTION(prefix_1, "module-dependency-dir", module_dependency_dir, Separate, INVALID, INVALID, 0, CC1Option, 0,
+       "Directory to dump module dependencies to", 0)
+OPTION(prefix_1, "module-file-deps", module_file_deps, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include module files in dependency output", 0)
+OPTION(prefix_1, "module-file-info", module_file_info, Flag, Action_Group, INVALID, 0, DriverOption | CC1Option, 0, 0, 0)
+OPTION(prefix_1, "momit-leaf-frame-pointer", momit_leaf_frame_pointer, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Omit frame pointer setup for leaf functions", 0)
+OPTION(prefix_1, "moslib=", moslib_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mpascal-strings", mpascal_strings, Flag, INVALID, fpascal_strings, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mpclmul", mpclmul, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mpopcntd", mpopcntd, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mpopcnt", mpopcnt, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mprfchw", mprfchw, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "MP", MP, Flag, M_Group, INVALID, 0, CC1Option, 0,
+       "Create phony target for each dependency (other than main file)", 0)
+OPTION(prefix_2, "MP", _SLASH_MP, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "mqdsp6-compat", mqdsp6_compat, Flag, m_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Enable hexagon-qdsp6 backward compatibility", 0)
+OPTION(prefix_1, "mqpx", mqpx, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "MQ", MQ, JoinedOrSeparate, M_Group, INVALID, 0, CC1Option, 0,
+       "Specify name of main file output to quote in depfile", 0)
+OPTION(prefix_1, "mrdrnd", mrdrnd, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mrdseed", mrdseed, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mred-zone", mred_zone, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mregparm=", mregparm_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mregparm", mregparm, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Limit the number of registers available for integer arguments", 0)
+OPTION(prefix_1, "mrelax-all", mrelax_all, Flag, m_Group, INVALID, 0, CC1Option | CC1AsOption, 0,
+       "(integrated-as) Relax all machine instructions", 0)
+OPTION(prefix_1, "mrelocation-model", mrelocation_model, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "The relocation model to use", 0)
+OPTION(prefix_1, "mrestrict-it", mrestrict_it, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.", 0)
+OPTION(prefix_1, "mrtd", mrtd, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Make StdCall calling convention the default", 0)
+OPTION(prefix_1, "mrtm", mrtm, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msave-temp-labels", msave_temp_labels, Flag, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Save temporary labels in the symbol table. Note this may change .s semantics and shouldn't generally be used on compiler-generated code.", 0)
+OPTION(prefix_1, "msha", msha, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msingle-float", msingle_float, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "msmall-data-threshold=", msmall_data_threshold_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "msoft-float", msoft_float, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Use software floating point", 0)
+OPTION(prefix_1, "msse2", msse2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse3", msse3, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse4.1", msse4_1, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse4.2", msse4_2, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse4", msse4, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "msse", msse, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mstack-alignment=", mstack_alignment, Joined, m_Group, INVALID, 0, CC1Option, 0,
+       "Set the stack alignment", 0)
+OPTION(prefix_1, "mstackrealign", mstackrealign, Flag, m_Group, INVALID, 0, CC1Option, 0,
+       "Force realign the stack at entry to every function", 0)
+OPTION(prefix_1, "mstrict-align", mstrict_align, Flag, INVALID, mno_unaligned_access, 0, CC1Option | HelpHidden, 0,
+       "Force all memory accesses to be aligned (AArch64 only, same as mno-unaligned-access)", 0)
+OPTION(prefix_1, "mt-migrate-directory", mt_migrate_directory, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Directory for temporary files produced during ARC or ObjC migration", 0)
+OPTION(prefix_1, "mtbm", mtbm, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_2, "MTd", _SLASH_MTd, Flag, _SLASH_M_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use static debug run-time", 0)
+OPTION(prefix_1, "mthumb", mthumb, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mtune=", mtune_EQ, Joined, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "MT", MT, JoinedOrSeparate, M_Group, INVALID, 0, CC1Option, 0,
+       "Specify name of main file output in depfile", 0)
+OPTION(prefix_2, "MT", _SLASH_MT, Flag, _SLASH_M_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use static run-time", 0)
+OPTION(prefix_1, "multi_module", multi__module, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "multiply_defined_unused", multiply__defined__unused, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "multiply_defined", multiply__defined, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "munaligned-access", munaligned_access, Flag, m_arm_Features_Group, INVALID, 0, 0, 0,
+       "Allow memory accesses to be unaligned (AArch32/AArch64 only)", 0)
+OPTION(prefix_1, "munwind-tables", munwind_tables, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate unwinding tables for all functions", 0)
+OPTION(prefix_1, "mv1", mv1, Flag, m_hexagon_Features_Group, march_EQ, "v1\0", 0, 0, 0, 0)
+OPTION(prefix_1, "mv2", mv2, Flag, m_hexagon_Features_Group, march_EQ, "v2\0", 0, 0, 0, 0)
+OPTION(prefix_1, "mv3", mv3, Flag, m_hexagon_Features_Group, march_EQ, "v3\0", 0, 0, 0, 0)
+OPTION(prefix_1, "mv4", mv4, Flag, m_hexagon_Features_Group, march_EQ, "v4\0", 0, 0, 0, 0)
+OPTION(prefix_1, "mv5", mv5, Flag, m_hexagon_Features_Group, march_EQ, "v5\0", 0, 0, 0, 0)
+OPTION(prefix_1, "mvsx", mvsx, Flag, m_ppc_Features_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mwarn-nonportable-cfstrings", mwarn_nonportable_cfstrings, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mx32", mx32, Flag, m_Group, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_1, "mxgot", mxgot, Flag, m_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "mxop", mxop, Flag, m_x86_Features_Group, INVALID, 0, CoreOption, 0, 0, 0)
+OPTION(prefix_1, "M", M, Flag, M_Group, INVALID, 0, 0, 0,
+       "Like -MD, but also implies -E and writes to stdout by default", 0)
+OPTION(prefix_1, "no-canonical-prefixes", no_canonical_prefixes, Flag, INVALID, INVALID, 0, HelpHidden, 0,
+       "Use relative instead of canonical paths", 0)
+OPTION(prefix_1, "no-code-completion-globals", no_code_completion_globals, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not include global declarations in code-completion results.", 0)
+OPTION(prefix_1, "no-cpp-precomp", no_cpp_precomp, Flag, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "no-finalize-removal", migrator_no_finalize_removal, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not remove finalize method in gc mode", 0)
+OPTION(prefix_1, "no-implicit-float", no_implicit_float, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Don't generate implicit floating point instructions", 0)
+OPTION(prefix_1, "no-integrated-as", anonymous_20, Flag, INVALID, fno_integrated_as, 0, CC1Option | DriverOption, 0, 0, 0)
+OPTION(prefix_4, "no-integrated-cpp", no_integrated_cpp, Flag, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_3, "no-line-commands", _no_line_commands, Flag, INVALID, P, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "no-ns-alloc-error", migrator_no_nsalloc_error, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not error on use of NSAllocateCollectable/NSReallocateCollectable", 0)
+OPTION(prefix_4, "no-pedantic", no_pedantic, Flag, pedantic_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "no-standard-includes", _no_standard_includes, Flag, INVALID, nostdinc, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "no-standard-libraries", _no_standard_libraries, Flag, INVALID, nostdlib, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "no-struct-path-tbaa", no_struct_path_tbaa, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Turn off struct-path aware Type Based Alias Analysis", 0)
+OPTION(prefix_3, "no-system-header-prefix=", no_system_header_prefix, Joined, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Treat all #include paths starting with <prefix> as not including a system header.", "<prefix>")
+OPTION(prefix_3, "no-system-header-prefix", anonymous_18, Separate, INVALID, no_system_header_prefix, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "no-undefined", _no_undefined, Flag, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_3, "no-warnings", _no_warnings, Flag, INVALID, w, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "no_dead_strip_inits_and_terms", no__dead__strip__inits__and__terms, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nobuiltininc", nobuiltininc, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Disable builtin #include directories", 0)
+OPTION(prefix_1, "nocpp", nocpp, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nodefaultlibs", nodefaultlibs, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nofixprebinding", nofixprebinding, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nolibc", nolibc, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "nologo", _SLASH_nologo, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "nomultidefs", nomultidefs, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nopie", nopie, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "noprebind", noprebind, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "noseglinkedit", noseglinkedit, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nostartfiles", nostartfiles, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nostdinc++", nostdincxx, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Disable standard #include directories for the C++ standard library", 0)
+OPTION(prefix_1, "nostdinc", nostdinc, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nostdlibinc", nostdlibinc, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nostdlib", nostdlib, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "nostdsysteminc", nostdsysteminc, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Disable standard system #include directories", 0)
+OPTION(prefix_1, "n", n, Flag, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "Don't automatically start assembly file with a text section", 0)
+OPTION(prefix_1, "O0", O0, Flag, O_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "O4", O4, Flag, O_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "Ob0", _SLASH_Ob0, Flag, cl_Group, fno_inline, 0, CLOption | DriverOption, 0,
+       "Disable inlining", 0)
+OPTION(prefix_2, "Ob1", _SLASH_Ob1, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Ob2", _SLASH_Ob2, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "ObjC++", ObjCXX, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Treat source input files as Objective-C++ inputs", 0)
+OPTION(prefix_1, "objc-isystem", objc_isystem, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add directory to the ObjC SYSTEM include search path", "<directory>")
+OPTION(prefix_1, "objcmt-atomic-property", objcmt_atomic_property, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Make migration to 'atomic' properties", 0)
+OPTION(prefix_1, "objcmt-migrate-all", objcmt_migrate_all, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC", 0)
+OPTION(prefix_1, "objcmt-migrate-annotation", objcmt_migrate_annotation, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to property and method annotations", 0)
+OPTION(prefix_1, "objcmt-migrate-designated-init", objcmt_migrate_designated_init, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods", 0)
+OPTION(prefix_1, "objcmt-migrate-instancetype", objcmt_migrate_instancetype, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to infer instancetype for method result type", 0)
+OPTION(prefix_1, "objcmt-migrate-literals", objcmt_migrate_literals, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC literals", 0)
+OPTION(prefix_1, "objcmt-migrate-ns-macros", objcmt_migrate_nsmacros, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to NS_ENUM/NS_OPTIONS macros", 0)
+OPTION(prefix_1, "objcmt-migrate-property", objcmt_migrate_property, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC property", 0)
+OPTION(prefix_1, "objcmt-migrate-protocol-conformance", objcmt_migrate_protocol_conformance, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to add protocol conformance on classes", 0)
+OPTION(prefix_1, "objcmt-migrate-readonly-property", objcmt_migrate_readonly_property, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC readonly property", 0)
+OPTION(prefix_1, "objcmt-migrate-readwrite-property", objcmt_migrate_readwrite_property, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC readwrite property", 0)
+OPTION(prefix_1, "objcmt-migrate-subscripting", objcmt_migrate_subscripting, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to modern ObjC subscripting", 0)
+OPTION(prefix_1, "objcmt-ns-nonatomic-iosonly", objcmt_ns_nonatomic_iosonly, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute", 0)
+OPTION(prefix_1, "objcmt-returns-innerpointer-property", objcmt_returns_innerpointer_property, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable migration to annotate property with NS_RETURNS_INNER_POINTER", 0)
+OPTION(prefix_1, "objcmt-white-list-dir-path=", anonymous_0, Joined, INVALID, objcmt_whitelist_dir_path, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "objcmt-whitelist-dir-path=", objcmt_whitelist_dir_path, Joined, INVALID, INVALID, 0, CC1Option, 0,
+       "Only modify files with a filename contained in the provided directory path", 0)
+OPTION(prefix_1, "objcxx-isystem", objcxx_isystem, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Add directory to the ObjC++ SYSTEM include search path", "<directory>")
+OPTION(prefix_1, "ObjC", ObjC, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Treat source input files as Objective-C inputs", 0)
+OPTION(prefix_1, "object", object, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Od", _SLASH_Od, Flag, cl_Group, O0, 0, CLOption | DriverOption, 0,
+       "Disable optimization", 0)
+OPTION(prefix_1, "Ofast", Ofast, Joined, O_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "Oi-", _SLASH_Oi_, Flag, cl_Group, fno_builtin, 0, CLOption | DriverOption, 0,
+       "Disable use of builtin functions", 0)
+OPTION(prefix_2, "Oi", _SLASH_Oi, Flag, cl_Group, fbuiltin, 0, CLOption | DriverOption, 0,
+       "Enable use of builtin functions", 0)
+OPTION(prefix_2, "openmp", _SLASH_openmp, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "optimize=", _optimize_EQ, Joined, INVALID, O, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "optimize", _optimize, Flag, INVALID, O, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Os", _SLASH_Os, Flag, cl_Group, O, "s\0", CLOption | DriverOption, 0,
+       "Optimize for size", 0)
+OPTION(prefix_2, "Ot", _SLASH_Ot, Flag, cl_Group, O, "2\0", CLOption | DriverOption, 0,
+       "Optimize for speed", 0)
+OPTION(prefix_1, "output-asm-variant", output_asm_variant, Separate, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "Select the asm variant index to use for output", 0)
+OPTION(prefix_3, "output-class-directory=", _output_class_directory_EQ, Joined, INVALID, foutput_class_dir_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "output-class-directory", _output_class_directory, Separate, INVALID, foutput_class_dir_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "output=", _output_EQ, Joined, INVALID, o, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "output", _output, Separate, INVALID, o, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Ox", _SLASH_Ox, Flag, cl_Group, O, "3\0", CLOption | DriverOption, 0,
+       "Maximum optimization", 0)
+OPTION(prefix_2, "Oy-", _SLASH_Oy_, Flag, cl_Group, fno_omit_frame_pointer, 0, CLOption | DriverOption, 0,
+       "Disable frame pointer omission", 0)
+OPTION(prefix_2, "Oy", _SLASH_Oy, Flag, cl_Group, fomit_frame_pointer, 0, CLOption | DriverOption, 0,
+       "Enable frame pointer omission", 0)
+OPTION(prefix_1, "O", O_flag, Flag, INVALID, O, "2\0", CC1Option, 0, 0, 0)
+OPTION(prefix_1, "O", O, Joined, O_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "O", _SLASH_O, Joined, cl_Group, O, 0, CLOption | DriverOption, 0,
+       "Optimization level", "<n>")
+OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, 0, DriverOption | RenderAsInput | CC1Option | CC1AsOption, 0,
+       "Write output to <file>", "<file>")
+OPTION(prefix_2, "o", _SLASH_o, JoinedOrSeparate, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "pagezero_size", pagezero__size, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "param=", _param_EQ, Joined, INVALID, _param, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "param", _param, Separate, CompileOnly_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "pass-exit-codes", pass_exit_codes, Flag, INVALID, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_4, "pedantic-errors", pedantic_errors, Flag, pedantic_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_4, "pedantic", pedantic, Flag, pedantic_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "pg", pg, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable mcount instrumentation", 0)
+OPTION(prefix_1, "pic-level", pic_level, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Value for __PIC__", 0)
+OPTION(prefix_1, "pie-level", pie_level, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Value for __PIE__", 0)
+OPTION(prefix_1, "pie", pie, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "pipe", pipe, Flag, INVALID, INVALID, 0, 0, 0,
+       "Use pipes between commands, when possible", 0)
+OPTION(prefix_1, "plugin-arg-", plugin_arg, JoinedAndSeparate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Pass <arg> to plugin <name>", "<name> <arg>")
+OPTION(prefix_1, "plugin", plugin, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use the named plugin action instead of the default action (use \"help\" to list available options)", "<name>")
+OPTION(prefix_1, "preamble-bytes=", preamble_bytes_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Assume that the precompiled header is a precompiled preamble covering the first N bytes of the main file", 0)
+OPTION(prefix_1, "prebind_all_twolevel_modules", prebind__all__twolevel__modules, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "prebind", prebind, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "prefix=", _prefix_EQ, Joined, INVALID, B, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "prefix", _prefix, Separate, INVALID, B, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "preload", preload, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "preprocess", _preprocess, Flag, INVALID, E, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "print-decl-contexts", print_decl_contexts, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print DeclContexts and their Decls", 0)
+OPTION(prefix_3, "print-diagnostic-categories", _print_diagnostic_categories, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "print-file-name=", print_file_name_EQ, Joined, INVALID, INVALID, 0, 0, 0,
+       "Print the full library path of <file>", "<file>")
+OPTION(prefix_3, "print-file-name", _print_file_name, Separate, INVALID, print_file_name_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "print-ivar-layout", print_ivar_layout, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable Objective-C Ivar layout bitmap print trace", 0)
+OPTION(prefix_4, "print-libgcc-file-name", print_libgcc_file_name, Flag, INVALID, INVALID, 0, 0, 0,
+       "Print the library path for \"libgcc.a\"", 0)
+OPTION(prefix_3, "print-missing-file-dependencies", _print_missing_file_dependencies, Flag, INVALID, MG, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "print-multi-directory", print_multi_directory, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "print-multi-lib", print_multi_lib, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "print-multi-os-directory", print_multi_os_directory, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "print-preamble", print_preamble, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print the \"preamble\" of a file, which is a candidate for implicit precompiled headers.", 0)
+OPTION(prefix_4, "print-prog-name=", print_prog_name_EQ, Joined, INVALID, INVALID, 0, 0, 0,
+       "Print the full program path of <name>", "<name>")
+OPTION(prefix_3, "print-prog-name", _print_prog_name, Separate, INVALID, print_prog_name_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "print-search-dirs", print_search_dirs, Flag, INVALID, INVALID, 0, 0, 0,
+       "Print the paths used for finding libraries and programs", 0)
+OPTION(prefix_1, "print-stats", print_stats, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print performance metrics and statistics", 0)
+OPTION(prefix_1, "private_bundle", private__bundle, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "profile-blocks", _profile_blocks, Flag, INVALID, a, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "profile", _profile, Flag, INVALID, p, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "pthreads", pthreads, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "pthread", pthread, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Support POSIX threads in generated code", 0)
+OPTION(prefix_1, "P", P, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Disable linemarker output in -E mode", 0)
+OPTION(prefix_2, "P", _SLASH_P, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Preprocess to file", 0)
+OPTION(prefix_1, "p", p, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Qfast_transcendentals", _SLASH_Qfast_transcendentals, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "QIfist", _SLASH_QIfist, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Qimprecise_fwaits", _SLASH_Qimprecise_fwaits, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Qn", Qn, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "Qpar", _SLASH_Qpar, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Qunused-arguments", Qunused_arguments, Flag, INVALID, INVALID, 0, DriverOption | CoreOption, 0,
+       "Don't emit warning for unused driver arguments", 0)
+OPTION(prefix_2, "Qvec-report", _SLASH_Qvec_report, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Q", Q, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "rdynamic", rdynamic, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "read_only_relocs", read__only__relocs, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "relaxed-aliasing", relaxed_aliasing, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Turn off Type Based Alias Analysis", 0)
+OPTION(prefix_4, "relocatable-pch", relocatable_pch, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Whether to build a relocatable precompiled header", 0)
+OPTION(prefix_1, "remap-file", remap_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Replace the contents of the <from> file with the contents of the <to> file", "<from>;<to>")
+OPTION(prefix_1, "remap", remap, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "resource-dir=", resource_dir_EQ, Joined, INVALID, resource_dir, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "resource-dir", resource_dir, Separate, INVALID, INVALID, 0, DriverOption | CC1Option | HelpHidden, 0,
+       "The directory which holds the compiler resource files", 0)
+OPTION(prefix_3, "resource=", _resource_EQ, Joined, INVALID, fcompile_resource_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "resource", _resource, Separate, INVALID, fcompile_resource_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "rewrite-legacy-objc", rewrite_legacy_objc, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Rewrite Legacy Objective-C source to C++", 0)
+OPTION(prefix_1, "rewrite-macros", rewrite_macros, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Expand macros without full preprocessing", 0)
+OPTION(prefix_1, "rewrite-objc", rewrite_objc, Flag, Action_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Rewrite Objective-C source to C++", 0)
+OPTION(prefix_1, "rewrite-test", rewrite_test, Flag, Action_Group, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Rewriter playground", 0)
+OPTION(prefix_1, "Rpass-analysis=", Rpass_analysis_EQ, Joined, R_value_Group, INVALID, 0, CC1Option, 0,
+       "Report transformation analysis from optimization passes whose name matches the given POSIX regular expression", 0)
+OPTION(prefix_1, "Rpass-missed=", Rpass_missed_EQ, Joined, R_value_Group, INVALID, 0, CC1Option, 0,
+       "Report missed transformations by optimization passes whose name matches the given POSIX regular expression", 0)
+OPTION(prefix_1, "Rpass=", Rpass_EQ, Joined, R_value_Group, INVALID, 0, CC1Option, 0,
+       "Report transformations performed by optimization passes whose name matches the given POSIX regular expression", 0)
+OPTION(prefix_1, "rpath", rpath, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_2, "RTC", _SLASH_RTC, Joined, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_4, "rtlib=", rtlib_EQ, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "rtlib", _rtlib, Separate, INVALID, rtlib_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "R", R_Joined, Joined, R_Group, INVALID, 0, CC1Option | CoreOption, 0,
+       "Enable the specified remark", "<remark>")
+OPTION(prefix_1, "r", r, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "save-temps", save_temps, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Save intermediate compilation results", 0)
+OPTION(prefix_2, "sdl-", _SLASH_sdl_, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "sdl", _SLASH_sdl, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "sectalign", sectalign, MultiArg, INVALID, INVALID, 0, 0, 3, 0, 0)
+OPTION(prefix_1, "sectcreate", sectcreate, MultiArg, INVALID, INVALID, 0, 0, 3, 0, 0)
+OPTION(prefix_1, "sectobjectsymbols", sectobjectsymbols, MultiArg, INVALID, INVALID, 0, 0, 2, 0, 0)
+OPTION(prefix_1, "sectorder", sectorder, MultiArg, INVALID, INVALID, 0, 0, 3, 0, 0)
+OPTION(prefix_1, "seg1addr", seg1addr, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "seg_addr_table_filename", seg__addr__table__filename, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "seg_addr_table", seg__addr__table, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "segaddr", segaddr, MultiArg, INVALID, INVALID, 0, 0, 2, 0, 0)
+OPTION(prefix_1, "segcreate", segcreate, MultiArg, INVALID, INVALID, 0, 0, 3, 0, 0)
+OPTION(prefix_1, "seglinkedit", seglinkedit, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "segprot", segprot, MultiArg, INVALID, INVALID, 0, 0, 3, 0, 0)
+OPTION(prefix_1, "segs_read_only_addr", segs__read__only__addr, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "segs_read_write_addr", segs__read__write__addr, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "segs_read_", segs__read__, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "serialize-diagnostic-file", diagnostic_serialized_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "File for serializing diagnostics in a binary format", "<filename>")
+OPTION(prefix_4, "serialize-diagnostics", _serialize_diags, Separate, INVALID, INVALID, 0, DriverOption, 0,
+       "Serialize compiler diagnostics to a file", 0)
+OPTION(prefix_1, "shared-libasan", shared_libasan, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "shared-libgcc", shared_libgcc, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "shared", shared, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "show-encoding", show_encoding, Flag, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "Show instruction encoding information in transliterate mode", 0)
+OPTION(prefix_3, "show-includes", show_includes, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Print cl.exe style /showIncludes to stdout", 0)
+OPTION(prefix_1, "show-inst", show_inst, Flag, INVALID, INVALID, 0, CC1AsOption | NoDriverOption, 0,
+       "Show internal instruction representation in transliterate mode", 0)
+OPTION(prefix_2, "showIncludes", _SLASH_showIncludes, Flag, cl_Group, show_includes, 0, CLOption | DriverOption, 0,
+       "Print info about included files to stderr", 0)
+OPTION(prefix_3, "signed-char", _signed_char, Flag, INVALID, fsigned_char, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "single_module", single__module, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "specs=", specs_EQ, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "specs", specs, Separate, INVALID, INVALID, 0, Unsupported, 0, 0, 0)
+OPTION(prefix_1, "split-dwarf-file", split_dwarf_file, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "File name to use for split dwarf debug info output", 0)
+OPTION(prefix_1, "split-dwarf", split_dwarf, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Split out the dwarf .dwo sections", 0)
+OPTION(prefix_1, "split-stacks", split_stacks, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Try to use a split stack if possible.", 0)
+OPTION(prefix_1, "stack-protector-buffer-size", stack_protector_buffer_size, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Lower bound for a buffer to be considered for stack protection", 0)
+OPTION(prefix_1, "stack-protector", stack_protector, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Enable stack protectors", 0)
+OPTION(prefix_1, "static-define", static_define, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Should __STATIC__ be defined", 0)
+OPTION(prefix_1, "static-libgcc", static_libgcc, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "static-libgfortran", static_libgfortran, Flag, gfortran_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "static-libstdc++", static_libstdcxx, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "static", static, Flag, INVALID, INVALID, 0, NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_1, "std-default=", std_default_EQ, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "std=", std_EQ, Joined, CompileOnly_Group, INVALID, 0, CC1Option, 0,
+       "Language standard to compile for", 0)
+OPTION(prefix_4, "stdlib=", stdlib_EQ, Joined, INVALID, INVALID, 0, CC1Option, 0,
+       "C++ standard library to use", 0)
+OPTION(prefix_3, "stdlib", _stdlib, Separate, INVALID, stdlib_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "std", _std, Separate, INVALID, std_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "sub_library", sub__library, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "sub_umbrella", sub__umbrella, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "sys-header-deps", sys_header_deps, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Include system headers in dependency output", 0)
+OPTION(prefix_3, "sysroot=", _sysroot_EQ, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "sysroot", _sysroot, Separate, INVALID, _sysroot_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "system-header-prefix=", system_header_prefix, Joined, clang_i_Group, INVALID, 0, CC1Option, 0,
+       "Treat all #include paths starting with <prefix> as including a system header.", "<prefix>")
+OPTION(prefix_3, "system-header-prefix", anonymous_17, Separate, INVALID, system_header_prefix, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "S", S, Flag, Action_Group, INVALID, 0, DriverOption | CC1Option, 0,
+       "Only run preprocess and compilation steps", 0)
+OPTION(prefix_1, "s", s, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "target-abi", target_abi, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Target a particular ABI type", 0)
+OPTION(prefix_1, "target-cpu", target_cpu, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Target a specific cpu type", 0)
+OPTION(prefix_1, "target-feature", target_feature, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Target specific attributes", 0)
+OPTION(prefix_3, "target-help", _target_help, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "target-linker-version", target_linker_version, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Target linker version", 0)
+OPTION(prefix_3, "target=", target, Joined, INVALID, INVALID, 0, DriverOption | CoreOption, 0,
+       "Generate code for the given target", 0)
+OPTION(prefix_1, "target", target_legacy_spelling, Separate, INVALID, target, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Tbss", Tbss, JoinedOrSeparate, T_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "TC", _SLASH_TC, Flag, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Treat all source files as C", 0)
+OPTION(prefix_2, "Tc", _SLASH_Tc, JoinedOrSeparate, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Specify a C source file", "<filename>")
+OPTION(prefix_1, "Tdata", Tdata, JoinedOrSeparate, T_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "test-coverage", test_coverage, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Do not generate coverage files or remove coverage changes from IR", 0)
+OPTION(prefix_1, "time", time, Flag, INVALID, INVALID, 0, 0, 0,
+       "Time individual commands", 0)
+OPTION(prefix_1, "token-cache", token_cache, Separate, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Use specified token cache file", "<path>")
+OPTION(prefix_2, "TP", _SLASH_TP, Flag, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Treat all source files as C++", 0)
+OPTION(prefix_2, "Tp", _SLASH_Tp, JoinedOrSeparate, cl_compile_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Specify a C++ source file", "<filename>")
+OPTION(prefix_3, "trace-includes", _trace_includes, Flag, INVALID, H, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "traditional-cpp", traditional_cpp, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Enable some traditional CPP emulation", 0)
+OPTION(prefix_4, "traditional", traditional, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_4, "trigraphs", trigraphs, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Process trigraph sequences", 0)
+OPTION(prefix_1, "trim-egraph", trim_egraph, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Only show error-related paths in the analysis graph", 0)
+OPTION(prefix_1, "triple=", triple_EQ, Joined, INVALID, triple, 0, CC1Option | NoDriverOption, 0, 0, 0)
+OPTION(prefix_1, "triple", triple, Separate, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Specify target triple (e.g. i686-apple-darwin9)", 0)
+OPTION(prefix_1, "Ttext", Ttext, JoinedOrSeparate, T_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "twolevel_namespace_hints", twolevel__namespace__hints, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "twolevel_namespace", twolevel__namespace, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "T", T, JoinedOrSeparate, T_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "t", t, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "umbrella", umbrella, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "undefine-macro=", _undefine_macro_EQ, Joined, INVALID, U, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "undefine-macro", _undefine_macro, Separate, INVALID, U, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "undefined", undefined, JoinedOrSeparate, u_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "undef", undef, Flag, u_Group, INVALID, 0, CC1Option, 0,
+       "undef all system defines", 0)
+OPTION(prefix_1, "unexported_symbols_list", unexported__symbols__list, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "unoptimized-cfg", analysis_UnoptimizedCFG, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Generate unoptimized CFGs for all analyses", 0)
+OPTION(prefix_3, "unsigned-char", _unsigned_char, Flag, INVALID, funsigned_char, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "user-dependencies", _user_dependencies, Flag, INVALID, MM, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "U", U, JoinedOrSeparate, CompileOnly_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "U", _SLASH_U, JoinedOrSeparate, cl_Group, U, 0, CLOption | DriverOption, 0,
+       "Undefine macro", "<macro>")
+OPTION(prefix_1, "u", u, JoinedOrSeparate, u_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "u", _SLASH_u, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "vd", _SLASH_vd, Joined, cl_Group, vtordisp_mode_EQ, 0, CLOption | DriverOption, 0,
+       "Control vtordisp placement", 0)
+OPTION(prefix_1, "vectorize-loops", vectorize_loops, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run the Loop vectorization passes", 0)
+OPTION(prefix_1, "vectorize-slp-aggressive", vectorize_slp_aggressive, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run the BB vectorization passes", 0)
+OPTION(prefix_1, "vectorize-slp", vectorize_slp, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Run the SLP vectorization passes", 0)
+OPTION(prefix_3, "verbose", _verbose, Flag, INVALID, v, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "verify-debug-info", verify_debug_info, Flag, INVALID, INVALID, 0, DriverOption, 0,
+       "Verify the binary representation of debug output", 0)
+OPTION(prefix_1, "verify-pch", verify_pch, Flag, Action_Group, INVALID, 0, CC1Option, 0,
+       "Load and verify that a pre-compiled header file is not stale", 0)
+OPTION(prefix_1, "verify", verify, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Verify diagnostic output using comment directives", 0)
+OPTION(prefix_3, "version", _version, Flag, INVALID, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "version", version, Flag, INVALID, INVALID, 0, CC1Option | CC1AsOption | NoDriverOption, 0,
+       "Print the compiler version", 0)
+OPTION(prefix_4, "via-file-asm", via_file_asm, Flag, internal_debug_Group, INVALID, 0, DriverOption | HelpHidden, 0,
+       "Write assembly to file for input to assemble jobs", 0)
+OPTION(prefix_2, "vmb", _SLASH_vmb, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use a best-case representation method for member pointers", 0)
+OPTION(prefix_2, "vmg", _SLASH_vmg, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Use a most-general representation for member pointers", 0)
+OPTION(prefix_2, "vmm", _SLASH_vmm, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set the default most-general representation to multiple inheritance", 0)
+OPTION(prefix_2, "vms", _SLASH_vms, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set the default most-general representation to single inheritance", 0)
+OPTION(prefix_2, "vmv", _SLASH_vmv, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0,
+       "Set the default most-general representation to virtual inheritance", 0)
+OPTION(prefix_2, "volatile", _SLASH_volatile, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "vtordisp-mode=", vtordisp_mode_EQ, Joined, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Control vtordisp placement on win32 targets", 0)
+OPTION(prefix_1, "V", V, JoinedOrSeparate, INVALID, INVALID, 0, DriverOption | Unsupported, 0, 0, 0)
+OPTION(prefix_2, "V", _SLASH_V, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, 0, CC1Option | CoreOption, 0,
+       "Show commands to run and use verbose output", 0)
+OPTION(prefix_2, "W0", _SLASH_W0, Flag, cl_Group, w, 0, CLOption | DriverOption, 0,
+       "Disable all warnings", 0)
+OPTION(prefix_2, "W1", _SLASH_W1, Flag, cl_Group, Wall, 0, CLOption | DriverOption, 0,
+       "Enable -Wall", 0)
+OPTION(prefix_2, "W2", _SLASH_W2, Flag, cl_Group, Wall, 0, CLOption | DriverOption, 0,
+       "Enable -Wall", 0)
+OPTION(prefix_2, "W3", _SLASH_W3, Flag, cl_Group, Wall, 0, CLOption | DriverOption, 0,
+       "Enable -Wall", 0)
+OPTION(prefix_2, "W4", _SLASH_W4, Flag, cl_Group, Wall, 0, CLOption | DriverOption, 0,
+       "Enable -Wall", 0)
+OPTION(prefix_1, "Wa,", Wa_COMMA, CommaJoined, INVALID, INVALID, 0, 0, 0,
+       "Pass the comma separated arguments in <arg> to the assembler", "<arg>")
+OPTION(prefix_1, "Wall", Wall, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "Wall", _SLASH_Wall, Flag, cl_Group, Wall, 0, CLOption | DriverOption, 0,
+       "Enable -Wall", 0)
+OPTION(prefix_3, "warn-=", _warn__EQ, Joined, INVALID, W_Joined, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "warn-", _warn_, Joined, INVALID, W_Joined, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "wd4005", _SLASH_wd4005, Flag, cl_Group, W_Joined, "no-macro-redefined\0", CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Wdeprecated", Wdeprecated, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "weak-l", weak_l, Joined, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "weak_framework", weak__framework, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "weak_library", weak__library, Separate, INVALID, INVALID, 0, LinkerInput, 0, 0, 0)
+OPTION(prefix_1, "weak_reference_mismatches", weak__reference__mismatches, Separate, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Wextra", Wextra, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "Wframe-larger-than=", Wframe_larger_than_EQ, Joined, f_Group, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "whatsloaded", whatsloaded, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "whyload", whyload, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Wl,", Wl_COMMA, CommaJoined, INVALID, INVALID, 0, LinkerInput | RenderAsInput, 0,
+       "Pass the comma separated arguments in <arg> to the linker", "<arg>")
+OPTION(prefix_1, "Wlarge-by-value-copy=", Wlarge_by_value_copy_EQ, Joined, INVALID, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "Wlarge-by-value-copy", Wlarge_by_value_copy_def, Flag, INVALID, INVALID, 0, HelpHidden, 0,
+       "Warn if a function definition returns or accepts an object larger in bytes than a given value", 0)
+OPTION(prefix_1, "Wlarger-than-", Wlarger_than_, Joined, INVALID, Wlarger_than_EQ, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Wlarger-than=", Wlarger_than_EQ, Joined, clang_ignored_f_Group, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "WL", _SLASH_WL, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Wno-deprecated", Wno_deprecated, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "Wno-rewrite-macros", Wno_rewrite_macros, Flag, INVALID, INVALID, 0, CC1Option | NoDriverOption, 0,
+       "Silence ObjC rewriting warnings", 0)
+OPTION(prefix_1, "Wno-write-strings", Wno_write_strings, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "Wnonportable-cfstrings", Wnonportable_cfstrings, Joined, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "working-directory=", working_directory_EQ, Joined, INVALID, working_directory, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_1, "working-directory", working_directory, JoinedOrSeparate, INVALID, INVALID, 0, CC1Option, 0,
+       "Resolve file paths relative to the specified directory", 0)
+OPTION(prefix_1, "Wp,", Wp_COMMA, CommaJoined, INVALID, INVALID, 0, 0, 0,
+       "Pass the comma separated arguments in <arg> to the preprocessor", "<arg>")
+OPTION(prefix_2, "Wp64", _SLASH_Wp64, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_3, "write-dependencies", _write_dependencies, Flag, INVALID, MD, 0, 0, 0, 0, 0)
+OPTION(prefix_3, "write-user-dependencies", _write_user_dependencies, Flag, INVALID, MMD, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Wwrite-strings", Wwrite_strings, Flag, W_Group, INVALID, 0, CC1Option, 0, 0, 0)
+OPTION(prefix_2, "WX-", _SLASH_WX_, Flag, cl_Group, W_Joined, "no-error\0", CLOption | DriverOption, 0,
+       "Do not treat warnings as errors", 0)
+OPTION(prefix_2, "WX", _SLASH_WX, Flag, cl_Group, W_Joined, "error\0", CLOption | DriverOption, 0,
+       "Treat warnings as errors", 0)
+OPTION(prefix_1, "W", W_Joined, Joined, W_Group, INVALID, 0, CC1Option | CoreOption, 0,
+       "Enable the specified warning", "<warning>")
+OPTION(prefix_1, "w", w, Flag, INVALID, INVALID, 0, CC1Option, 0,
+       "Suppress all warnings", 0)
+OPTION(prefix_2, "w", _SLASH_w_flag, Flag, cl_Group, w, 0, CLOption | DriverOption, 0,
+       "Disable all warnings", 0)
+OPTION(prefix_2, "w", _SLASH_w, Joined, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_1, "Xanalyzer", Xanalyzer, Separate, INVALID, INVALID, 0, 0, 0,
+       "Pass <arg> to the static analyzer", "<arg>")
+OPTION(prefix_1, "Xarch_", Xarch__, JoinedAndSeparate, INVALID, INVALID, 0, DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Xassembler", Xassembler, Separate, INVALID, INVALID, 0, 0, 0,
+       "Pass <arg> to the assembler", "<arg>")
+OPTION(prefix_1, "Xclang", Xclang, Separate, INVALID, INVALID, 0, DriverOption | CoreOption, 0,
+       "Pass <arg> to the clang compiler", "<arg>")
+OPTION(prefix_1, "Xlinker", Xlinker, Separate, INVALID, INVALID, 0, LinkerInput | RenderAsInput, 0,
+       "Pass <arg> to the linker", "<arg>")
+OPTION(prefix_1, "Xpreprocessor", Xpreprocessor, Separate, INVALID, INVALID, 0, 0, 0,
+       "Pass <arg> to the preprocessor", "<arg>")
+OPTION(prefix_1, "X", X_Flag, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "X", X_Joined, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_2, "X", _SLASH_X, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "x", x, JoinedOrSeparate, INVALID, INVALID, 0, DriverOption | CC1Option, 0,
+       "Treat subsequent input files as having type <language>", "<language>")
+OPTION(prefix_2, "Y-", _SLASH_Y_, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Yc", _SLASH_Yc, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Yd", _SLASH_Yd, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Yl", _SLASH_Yl, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Yu", _SLASH_Yu, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "y", y, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Z-reserved-lib-cckext", Z_reserved_lib_cckext, Flag, reserved_lib_Group, INVALID, 0, LinkerInput | NoArgumentUnused | Unsupported, 0, 0, 0)
+OPTION(prefix_1, "Z-reserved-lib-stdc++", Z_reserved_lib_stdcxx, Flag, reserved_lib_Group, INVALID, 0, LinkerInput | NoArgumentUnused | Unsupported, 0, 0, 0)
+OPTION(prefix_1, "Z-Xlinker-no-demangle", Z_Xlinker__no_demangle, Flag, INVALID, INVALID, 0, Unsupported | NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_2, "Z7", _SLASH_Z7, Flag, cl_Group, gline_tables_only, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Za", _SLASH_Za, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Zc:forScope", _SLASH_Zc_forScope, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Zc:inline", _SLASH_Zc_inline, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Zc:rvalueCast", _SLASH_Zc_rvalueCast, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Zc:wchar_t", _SLASH_Zc_wchar_t, Flag, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Zc:", _SLASH_Zc, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Ze", _SLASH_Ze, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Zg", _SLASH_Zg, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "ZI", _SLASH_ZI, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Zi", _SLASH_Zi, Flag, cl_Group, gline_tables_only, 0, CLOption | DriverOption, 0,
+       "Enable debug information", 0)
+OPTION(prefix_1, "Zlinker-input", Zlinker_input, Separate, INVALID, INVALID, 0, Unsupported | NoArgumentUnused, 0, 0, 0)
+OPTION(prefix_2, "Zl", _SLASH_Zl, Flag, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Zm", _SLASH_Zm, Joined, cl_ignored_Group, INVALID, 0, CLOption | DriverOption | HelpHidden, 0, 0, 0)
+OPTION(prefix_2, "Zp", _SLASH_Zp, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_2, "Zs", _SLASH_Zs, Flag, cl_Group, fsyntax_only, 0, CLOption | DriverOption, 0,
+       "Syntax-check only", 0)
+OPTION(prefix_2, "ZW", _SLASH_ZW, Joined, cl_Group, INVALID, 0, CLOption | DriverOption, 0, 0, 0)
+OPTION(prefix_1, "Z", Z_Flag, Flag, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "Z", Z_Joined, Joined, INVALID, INVALID, 0, 0, 0, 0, 0)
+OPTION(prefix_1, "z", z, Separate, INVALID, INVALID, 0, LinkerInput | RenderAsInput, 0,
+       "Pass -z <arg> to the linker", "<arg>")
+OPTION(prefix_3, "", _DASH_DASH, RemainingArgs, INVALID, INVALID, 0, DriverOption | CoreOption, 0, 0, 0)
+OPTION(prefix_3, "", _, Joined, INVALID, INVALID, 0, Unsupported, 0, 0, 0)
+#endif
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
new file mode 100644
index 0000000..4e0f40c
--- /dev/null
+++ b/include/clang/Driver/Phases.h
@@ -0,0 +1,36 @@
+//===--- Phases.h - Transformations on Driver Types -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_PHASES_H_
+#define CLANG_DRIVER_PHASES_H_
+
+namespace clang {
+namespace driver {
+namespace phases {
+  /// ID - Ordered values for successive stages in the
+  /// compilation process which interact with user options.
+  enum ID {
+    Preprocess,
+    Precompile,
+    Compile,
+    Assemble,
+    Link
+  };
+
+  enum {
+    MaxNumberOfPhases = Link + 1
+  };
+
+  const char *getPhaseName(ID Id);
+
+} // end namespace phases
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
new file mode 100644
index 0000000..c79c471
--- /dev/null
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -0,0 +1,150 @@
+//===--- SanitizerArgs.h - Arguments for sanitizer tools  -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
+
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include <string>
+
+namespace clang {
+namespace driver {
+
+class Driver;
+class ToolChain;
+
+class SanitizerArgs {
+  /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
+  /// bit positions within \c Kind.
+  enum SanitizeOrdinal {
+#define SANITIZER(NAME, ID) SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
+#include "clang/Basic/Sanitizers.def"
+    SO_Count
+  };
+
+  /// Bugs to catch at runtime.
+  enum SanitizeKind {
+#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
+  ID = ALIAS, ID##Group = 1 << SO_##ID##Group,
+#include "clang/Basic/Sanitizers.def"
+    NeedsAsanRt = Address,
+    NeedsTsanRt = Thread,
+    NeedsMsanRt = Memory,
+    NeedsDfsanRt = DataFlow,
+    NeedsLeakDetection = Leak,
+    NeedsUbsanRt = Undefined | Integer,
+    NotAllowedWithTrap = Vptr,
+    HasZeroBaseShadow = Thread | Memory | DataFlow,
+    NeedsUnwindTables = Address | Thread | Memory | DataFlow
+  };
+  unsigned Kind;
+
+  std::string BlacklistFile;
+  int MsanTrackOrigins;
+  bool AsanZeroBaseShadow;
+  bool UbsanTrapOnError;
+  bool AsanSharedRuntime;
+
+ public:
+  SanitizerArgs();
+  /// Parses the sanitizer arguments from an argument list.
+  SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
+
+  bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+  bool needsSharedAsanRt() const { return AsanSharedRuntime; }
+  bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+  bool needsMsanRt() const { return Kind & NeedsMsanRt; }
+  bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
+  bool needsLsanRt() const {
+    return needsLeakDetection() && !needsAsanRt();
+  }
+  bool needsUbsanRt() const {
+    return !UbsanTrapOnError && (Kind & NeedsUbsanRt);
+  }
+  bool needsDfsanRt() const { return Kind & NeedsDfsanRt; }
+
+  bool sanitizesVptr() const { return Kind & Vptr; }
+  bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
+  bool hasZeroBaseShadow() const {
+    return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
+  }
+  bool needsUnwindTables() const { return Kind & NeedsUnwindTables; }
+  void addArgs(const llvm::opt::ArgList &Args,
+               llvm::opt::ArgStringList &CmdArgs) const;
+
+ private:
+  void clear();
+
+  /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
+  /// Returns OR of members of the \c SanitizeKind enumeration, or \c 0
+  /// if \p Value is not known.
+  static unsigned parse(const char *Value);
+
+  /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
+  /// invalid components.
+  static unsigned parse(const Driver &D, const llvm::opt::Arg *A,
+                        bool DiagnoseErrors);
+
+  /// Parse a single flag of the form -f[no]sanitize=, or
+  /// -f*-sanitizer. Sets the masks defining required change of Kind value.
+  /// Returns true if the flag was parsed successfully.
+  static bool parse(const Driver &D, const llvm::opt::ArgList &Args,
+                    const llvm::opt::Arg *A, unsigned &Add, unsigned &Remove,
+                    bool DiagnoseErrors);
+
+  /// Produce an argument string from ArgList \p Args, which shows how it
+  /// provides a sanitizer kind in \p Mask. For example, the argument list
+  /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
+  /// would produce "-fsanitize=vptr".
+  static std::string lastArgumentForKind(const Driver &D,
+                                         const llvm::opt::ArgList &Args,
+                                         unsigned Kind);
+
+  /// Produce an argument string from argument \p A, which shows how it provides
+  /// a value in \p Mask. For instance, the argument
+  /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
+  /// "-fsanitize=alignment".
+  static std::string describeSanitizeArg(const llvm::opt::ArgList &Args,
+                                         const llvm::opt::Arg *A,
+                                         unsigned Mask);
+
+  static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
+                                         std::string &BLPath);
+
+  /// Return the smallest superset of sanitizer set \p Kinds such that each
+  /// member of each group whose flag is set in \p Kinds has its flag set in the
+  /// result.
+  static unsigned expandGroups(unsigned Kinds);
+
+  /// Return the subset of \p Kinds supported by toolchain \p TC.  If
+  /// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer
+  /// removed from \p Kinds.
+  static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
+                                         const llvm::opt::ArgList &Args,
+                                         const llvm::opt::Arg *A,
+                                         bool DiagnoseErrors,
+                                         unsigned &DiagnosedKinds);
+
+  /// The flags in \p Mask are unsupported by \p TC.  If present in \p Kinds,
+  /// remove them and produce an error diagnostic referring to \p A if
+  /// \p DiagnoseErrors is true.
+  static void filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
+                                    unsigned Mask,
+                                    const llvm::opt::ArgList &Args,
+                                    const llvm::opt::Arg *A,
+                                    bool DiagnoseErrors,
+                                    unsigned &DiagnosedKinds);
+};
+
+}  // namespace driver
+}  // namespace clang
+
+#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
new file mode 100644
index 0000000..015dcf5
--- /dev/null
+++ b/include/clang/Driver/Tool.h
@@ -0,0 +1,83 @@
+//===--- Tool.h - Compilation Tools -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TOOL_H_
+#define CLANG_DRIVER_TOOL_H_
+
+#include "clang/Basic/LLVM.h"
+
+namespace llvm {
+namespace opt {
+  class ArgList;
+}
+}
+
+namespace clang {
+namespace driver {
+
+  class Compilation;
+  class InputInfo;
+  class Job;
+  class JobAction;
+  class ToolChain;
+
+  typedef SmallVector<InputInfo, 4> InputInfoList;
+
+/// Tool - Information on a specific compilation tool.
+class Tool {
+  /// The tool name (for debugging).
+  const char *Name;
+
+  /// The human readable name for the tool, for use in diagnostics.
+  const char *ShortName;
+
+  /// The tool chain this tool is a part of.
+  const ToolChain &TheToolChain;
+
+public:
+  Tool(const char *Name, const char *ShortName,
+       const ToolChain &TC);
+
+public:
+  virtual ~Tool();
+
+  const char *getName() const { return Name; }
+
+  const char *getShortName() const { return ShortName; }
+
+  const ToolChain &getToolChain() const { return TheToolChain; }
+
+  virtual bool hasIntegratedAssembler() const { return false; }
+  virtual bool hasIntegratedCPP() const = 0;
+  virtual bool isLinkJob() const { return false; }
+  virtual bool isDsymutilJob() const { return false; }
+
+  /// \brief Does this tool have "good" standardized diagnostics, or should the
+  /// driver add an additional "command failed" diagnostic on failures.
+  virtual bool hasGoodDiagnostics() const { return false; }
+
+  /// ConstructJob - Construct jobs to perform the action \p JA,
+  /// writing to \p Output and with \p Inputs, and add the jobs to
+  /// \p C.
+  ///
+  /// \param TCArgs - The argument list for this toolchain, with any
+  /// tool chain specific translations applied.
+  /// \param LinkingOutput - If this output will eventually feed the
+  /// linker, then this is the final output name of the linked image.
+  virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                            const InputInfo &Output,
+                            const InputInfoList &Inputs,
+                            const llvm::opt::ArgList &TCArgs,
+                            const char *LinkingOutput) const = 0;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
new file mode 100644
index 0000000..550e4df
--- /dev/null
+++ b/include/clang/Driver/ToolChain.h
@@ -0,0 +1,331 @@
+//===--- ToolChain.h - Collections of tools for one platform ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TOOLCHAIN_H_
+#define CLANG_DRIVER_TOOLCHAIN_H_
+
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Path.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+namespace opt {
+  class ArgList;
+  class DerivedArgList;
+  class InputArgList;
+}
+}
+
+namespace clang {
+  class ObjCRuntime;
+
+namespace driver {
+  class Compilation;
+  class Driver;
+  class JobAction;
+  class SanitizerArgs;
+  class Tool;
+
+/// ToolChain - Access to tools for a single platform.
+class ToolChain {
+public:
+  typedef SmallVector<std::string, 4> path_list;
+
+  enum CXXStdlibType {
+    CST_Libcxx,
+    CST_Libstdcxx
+  };
+
+  enum RuntimeLibType {
+    RLT_CompilerRT,
+    RLT_Libgcc
+  };
+
+private:
+  const Driver &D;
+  const llvm::Triple Triple;
+  const llvm::opt::ArgList &Args;
+
+  /// The list of toolchain specific path prefixes to search for
+  /// files.
+  path_list FilePaths;
+
+  /// The list of toolchain specific path prefixes to search for
+  /// programs.
+  path_list ProgramPaths;
+
+  mutable std::unique_ptr<Tool> Clang;
+  mutable std::unique_ptr<Tool> Assemble;
+  mutable std::unique_ptr<Tool> Link;
+  Tool *getClang() const;
+  Tool *getAssemble() const;
+  Tool *getLink() const;
+  Tool *getClangAs() const;
+
+  mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
+
+protected:
+  MultilibSet Multilibs;
+
+  ToolChain(const Driver &D, const llvm::Triple &T,
+            const llvm::opt::ArgList &Args);
+
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+  virtual Tool *getTool(Action::ActionClass AC) const;
+
+  /// \name Utilities for implementing subclasses.
+  ///@{
+  static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
+                               llvm::opt::ArgStringList &CC1Args,
+                               const Twine &Path);
+  static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs,
+                                      llvm::opt::ArgStringList &CC1Args,
+                                      const Twine &Path);
+  static void
+      addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs,
+                                      llvm::opt::ArgStringList &CC1Args,
+                                      const Twine &Path);
+  static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
+                                llvm::opt::ArgStringList &CC1Args,
+                                ArrayRef<StringRef> Paths);
+  ///@}
+
+public:
+  virtual ~ToolChain();
+
+  // Accessors
+
+  const Driver &getDriver() const;
+  const llvm::Triple &getTriple() const { return Triple; }
+
+  llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
+  StringRef getArchName() const { return Triple.getArchName(); }
+  StringRef getPlatform() const { return Triple.getVendorName(); }
+  StringRef getOS() const { return Triple.getOSName(); }
+
+  /// \brief Provide the default architecture name (as expected by -arch) for
+  /// this toolchain. Note t
+  std::string getDefaultUniversalArchName() const;
+
+  std::string getTripleString() const {
+    return Triple.getTriple();
+  }
+
+  path_list &getFilePaths() { return FilePaths; }
+  const path_list &getFilePaths() const { return FilePaths; }
+
+  path_list &getProgramPaths() { return ProgramPaths; }
+  const path_list &getProgramPaths() const { return ProgramPaths; }
+
+  const MultilibSet &getMultilibs() const { return Multilibs; }
+
+  const SanitizerArgs& getSanitizerArgs() const;
+
+  // Tool access.
+
+  /// TranslateArgs - Create a new derived argument list for any argument
+  /// translations this ToolChain may wish to perform, or 0 if no tool chain
+  /// specific translations are needed.
+  ///
+  /// \param BoundArch - The bound architecture name, or 0.
+  virtual llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args,
+                const char *BoundArch) const {
+    return nullptr;
+  }
+
+  /// Choose a tool to use to handle the action \p JA.
+  Tool *SelectTool(const JobAction &JA) const;
+
+  // Helper methods
+
+  std::string GetFilePath(const char *Name) const;
+  std::string GetProgramPath(const char *Name) const;
+
+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
+  /// the linker suffix or name.
+  std::string GetLinkerPath() const;
+
+  /// \brief Dispatch to the specific toolchain for verbose printing.
+  ///
+  /// This is used when handling the verbose option to print detailed,
+  /// toolchain-specific information useful for understanding the behavior of
+  /// the driver on a specific platform.
+  virtual void printVerboseInfo(raw_ostream &OS) const {};
+
+  // Platform defaults information
+
+  /// \brief Returns true if the toolchain is targeting a non-native
+  /// architecture.
+  virtual bool isCrossCompiling() const;
+
+  /// HasNativeLTOLinker - Check whether the linker and related tools have
+  /// native LLVM support.
+  virtual bool HasNativeLLVMSupport() const;
+
+  /// LookupTypeForExtension - Return the default language type to use for the
+  /// given extension.
+  virtual types::ID LookupTypeForExtension(const char *Ext) const;
+
+  /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
+  virtual bool IsBlocksDefault() const { return false; }
+
+  /// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
+  /// by default.
+  virtual bool IsIntegratedAssemblerDefault() const { return false; }
+
+  /// \brief Check if the toolchain should use the integrated assembler.
+  bool useIntegratedAs() const;
+
+  /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default.
+  virtual bool IsMathErrnoDefault() const { return true; }
+
+  /// IsEncodeExtendedBlockSignatureDefault - Does this tool chain enable
+  /// -fencode-extended-block-signature by default.
+  virtual bool IsEncodeExtendedBlockSignatureDefault() const { return false; }
+
+  /// IsObjCNonFragileABIDefault - Does this tool chain set
+  /// -fobjc-nonfragile-abi by default.
+  virtual bool IsObjCNonFragileABIDefault() const { return false; }
+
+  /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
+  /// mixed dispatch method be used?
+  virtual bool UseObjCMixedDispatch() const { return false; }
+
+  /// GetDefaultStackProtectorLevel - Get the default stack protector level for
+  /// this tool chain (0=off, 1=on, 2=strong, 3=all).
+  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
+    return 0;
+  }
+
+  /// GetDefaultRuntimeLibType - Get the default runtime library variant to use.
+  virtual RuntimeLibType GetDefaultRuntimeLibType() const {
+    return ToolChain::RLT_Libgcc;
+  }
+
+  /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
+  /// by default.
+  virtual bool IsUnwindTablesDefault() const;
+
+  /// \brief Test whether this toolchain defaults to PIC.
+  virtual bool isPICDefault() const = 0;
+
+  /// \brief Test whether this toolchain defaults to PIE.
+  virtual bool isPIEDefault() const = 0;
+
+  /// \brief Tests whether this toolchain forces its default for PIC, PIE or
+  /// non-PIC.  If this returns true, any PIC related flags should be ignored
+  /// and instead the results of \c isPICDefault() and \c isPIEDefault() are
+  /// used exclusively.
+  virtual bool isPICDefaultForced() const = 0;
+
+  /// SupportsProfiling - Does this tool chain support -pg.
+  virtual bool SupportsProfiling() const { return true; }
+
+  /// Does this tool chain support Objective-C garbage collection.
+  virtual bool SupportsObjCGC() const { return true; }
+
+  /// Complain if this tool chain doesn't support Objective-C ARC.
+  virtual void CheckObjCARC() const {}
+
+  /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
+  /// compile unit information.
+  virtual bool UseDwarfDebugFlags() const { return false; }
+
+  /// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
+  virtual bool UseSjLjExceptions() const { return false; }
+
+  /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking
+  /// command line arguments into account.
+  virtual std::string
+  ComputeLLVMTriple(const llvm::opt::ArgList &Args,
+                    types::ID InputType = types::TY_INVALID) const;
+
+  /// ComputeEffectiveClangTriple - Return the Clang triple to use for this
+  /// target, which may take into account the command line arguments. For
+  /// example, on Darwin the -mmacosx-version-min= command line argument (which
+  /// sets the deployment target) determines the version in the triple passed to
+  /// Clang.
+  virtual std::string ComputeEffectiveClangTriple(
+      const llvm::opt::ArgList &Args,
+      types::ID InputType = types::TY_INVALID) const;
+
+  /// getDefaultObjCRuntime - Return the default Objective-C runtime
+  /// for this platform.
+  ///
+  /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
+  virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
+
+  /// hasBlocksRuntime - Given that the user is compiling with
+  /// -fblocks, does this tool chain guarantee the existence of a
+  /// blocks runtime?
+  ///
+  /// FIXME: this really belongs on some sort of DeploymentTarget abstraction
+  virtual bool hasBlocksRuntime() const { return true; }
+
+  /// \brief Add the clang cc1 arguments for system include paths.
+  ///
+  /// This routine is responsible for adding the necessary cc1 arguments to
+  /// include headers from standard system header directories.
+  virtual void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const;
+
+  /// \brief Add options that need to be passed to cc1 for this target.
+  virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                                     llvm::opt::ArgStringList &CC1Args) const;
+
+  /// \brief Add warning options that need to be passed to cc1 for this target.
+  virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
+
+  // GetRuntimeLibType - Determine the runtime library type to use with the
+  // given compilation arguments.
+  virtual RuntimeLibType
+  GetRuntimeLibType(const llvm::opt::ArgList &Args) const;
+
+  // GetCXXStdlibType - Determine the C++ standard library type to use with the
+  // given compilation arguments.
+  virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+
+  /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
+  /// the include paths to use for the given C++ standard library type.
+  virtual void
+  AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                               llvm::opt::ArgStringList &CC1Args) const;
+
+  /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
+  /// for the given C++ standard library type.
+  virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                                   llvm::opt::ArgStringList &CmdArgs) const;
+
+  /// AddCCKextLibArgs - Add the system specific linker arguments to use
+  /// for kernel extensions (Darwin-specific).
+  virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
+                                llvm::opt::ArgStringList &CmdArgs) const;
+
+  /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
+  /// global flags for unsafe floating point math, add it and return true.
+  ///
+  /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
+  virtual bool
+  AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args,
+                                llvm::opt::ArgStringList &CmdArgs) const;
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
new file mode 100644
index 0000000..3209679
--- /dev/null
+++ b/include/clang/Driver/Types.def
@@ -0,0 +1,94 @@
+//===--- Types.def - Driver Type 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 the driver type information. Users of this file
+// must define the TYPE macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE
+#error "Define TYPE prior to including this file!"
+#endif
+
+// TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS)
+
+// The first value is the type name as a string; for types which can
+// be user specified this should be the equivalent -x option.
+
+// The second value is the type id, which will result in a
+// clang::driver::types::TY_XX enum constant.
+
+// The third value is that id of the type for preprocessed inputs of
+// this type, or INVALID if this type is not preprocessed.
+
+// The fourth value is the suffix to use when creating temporary files
+// of this type, or null if unspecified.
+
+// The fifth value is a string containing option flags. Valid values:
+//  a - The type should only be assembled.
+//  p - The type should only be precompiled.
+//  u - The type can be user specified (with -x).
+//  A - The type's temporary suffix should be appended when generating
+//      outputs of this type.
+
+
+// C family source language (with and without preprocessing).
+TYPE("cpp-output",               PP_C,         INVALID,         "i",     "u")
+TYPE("c",                        C,            PP_C,            "c",     "u")
+TYPE("cl",                       CL,           PP_C,            "cl",    "u")
+TYPE("cuda",                     CUDA,         PP_CXX,          "cpp",   "u")
+TYPE("objective-c-cpp-output",   PP_ObjC,      INVALID,         "mi",    "u")
+TYPE("objc-cpp-output",          PP_ObjC_Alias, INVALID,        "mi",    "u")
+TYPE("objective-c",              ObjC,         PP_ObjC,         "m",     "u")
+TYPE("c++-cpp-output",           PP_CXX,       INVALID,         "ii",    "u")
+TYPE("c++",                      CXX,          PP_CXX,          "cpp",   "u")
+TYPE("objective-c++-cpp-output", PP_ObjCXX,    INVALID,         "mii",   "u")
+TYPE("objc++-cpp-output",        PP_ObjCXX_Alias, INVALID,      "mii",   "u")
+TYPE("objective-c++",            ObjCXX,       PP_ObjCXX,       "mm",    "u")
+
+// C family input files to precompile.
+TYPE("c-header-cpp-output",      PP_CHeader,   INVALID,         "i",     "p")
+TYPE("c-header",                 CHeader,      PP_CHeader,      nullptr, "pu")
+TYPE("cl-header",                CLHeader,     PP_CHeader,      nullptr, "pu")
+TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID,   "mi",    "p")
+TYPE("objective-c-header",       ObjCHeader,   PP_ObjCHeader,   nullptr, "pu")
+TYPE("c++-header-cpp-output",    PP_CXXHeader, INVALID,         "ii",    "p")
+TYPE("c++-header",               CXXHeader,    PP_CXXHeader,    nullptr, "pu")
+TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
+TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, nullptr, "pu")
+
+// Other languages.
+TYPE("ada",                      Ada,          INVALID,         nullptr, "u")
+TYPE("assembler",                PP_Asm,       INVALID,         "s",     "au")
+TYPE("assembler-with-cpp",       Asm,          PP_Asm,          "S",     "au")
+TYPE("f95",                      PP_Fortran,   INVALID,         nullptr, "u")
+TYPE("f95-cpp-input",            Fortran,      PP_Fortran,      nullptr, "u")
+TYPE("java",                     Java,         INVALID,         nullptr, "u")
+
+// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
+// outputs should use the standard suffixes.
+TYPE("ir",                       LLVM_IR,      INVALID,         "ll",    "u")
+TYPE("ir",                       LLVM_BC,      INVALID,         "bc",    "u")
+TYPE("lto-ir",                   LTO_IR,       INVALID,         "s",     "")
+TYPE("lto-bc",                   LTO_BC,       INVALID,         "o",     "")
+
+// Misc.
+TYPE("ast",                      AST,          INVALID,         "ast",   "u")
+TYPE("pcm",                      ModuleFile,   INVALID,         "pcm",   "u")
+TYPE("plist",                    Plist,        INVALID,         "plist", "")
+TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",   "")
+TYPE("rewritten-legacy-objc",    RewrittenLegacyObjC,INVALID,   "cpp",   "")
+TYPE("remap",                    Remap,        INVALID,         "remap", "")
+TYPE("precompiled-header",       PCH,          INVALID,         "gch",   "A")
+TYPE("object",                   Object,       INVALID,         "o",     "")
+TYPE("treelang",                 Treelang,     INVALID,         nullptr, "u")
+TYPE("image",                    Image,        INVALID,         "out",   "")
+TYPE("dSYM",                     dSYM,         INVALID,         "dSYM",  "A")
+TYPE("dependencies",             Dependencies, INVALID,         "d",     "")
+TYPE("none",                     Nothing,      INVALID,         nullptr, "u")
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
new file mode 100644
index 0000000..cca576a
--- /dev/null
+++ b/include/clang/Driver/Types.h
@@ -0,0 +1,91 @@
+//===--- Types.h - Input & Temporary Driver Types ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_TYPES_H_
+#define CLANG_DRIVER_TYPES_H_
+
+#include "clang/Driver/Phases.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+namespace driver {
+namespace types {
+  enum ID {
+    TY_INVALID,
+#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) TY_##ID,
+#include "clang/Driver/Types.def"
+#undef TYPE
+    TY_LAST
+  };
+
+  /// getTypeName - Return the name of the type for \p Id.
+  const char *getTypeName(ID Id);
+
+  /// getPreprocessedType - Get the ID of the type for this input when
+  /// it has been preprocessed, or INVALID if this input is not
+  /// preprocessed.
+  ID getPreprocessedType(ID Id);
+
+  /// getTypeTempSuffix - Return the suffix to use when creating a
+  /// temp file of this type, or null if unspecified.
+  const char *getTypeTempSuffix(ID Id, bool CLMode = false);
+
+  /// onlyAssembleType - Should this type only be assembled.
+  bool onlyAssembleType(ID Id);
+
+  /// onlyPrecompileType - Should this type only be precompiled.
+  bool onlyPrecompileType(ID Id);
+
+  /// canTypeBeUserSpecified - Can this type be specified on the
+  /// command line (by the type name); this is used when forwarding
+  /// commands to gcc.
+  bool canTypeBeUserSpecified(ID Id);
+
+  /// appendSuffixForType - When generating outputs of this type,
+  /// should the suffix be appended (instead of replacing the existing
+  /// suffix).
+  bool appendSuffixForType(ID Id);
+
+  /// canLipoType - Is this type acceptable as the output of a
+  /// universal build (currently, just the Nothing, Image, and Object
+  /// types).
+  bool canLipoType(ID Id);
+
+  /// isAcceptedByClang - Can clang handle this input type.
+  bool isAcceptedByClang(ID Id);
+
+  /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
+  bool isCXX(ID Id);
+
+  /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
+  bool isObjC(ID Id);
+
+  /// lookupTypeForExtension - Lookup the type to use for the file
+  /// extension \p Ext.
+  ID lookupTypeForExtension(const char *Ext);
+
+  /// lookupTypeForTypSpecifier - Lookup the type to use for a user
+  /// specified type name.
+  ID lookupTypeForTypeSpecifier(const char *Name);
+
+  /// getCompilationPhases - Get the list of compilation phases ('Phases') to be
+  /// done for type 'Id'.
+  void getCompilationPhases(
+    ID Id,
+    llvm::SmallVectorImpl<phases::ID> &Phases);
+
+  /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
+  /// C type (used for clang++ emulation of g++ behaviour)
+  ID lookupCXXTypeForCType(ID Id);
+
+} // end namespace types
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
new file mode 100644
index 0000000..b24b990
--- /dev/null
+++ b/include/clang/Driver/Util.h
@@ -0,0 +1,32 @@
+//===--- Util.h - Common Driver Utilities -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_UTIL_H_
+#define CLANG_DRIVER_UTIL_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+class DiagnosticsEngine;
+
+namespace driver {
+  class Action;
+  class JobAction;
+
+  /// ArgStringMap - Type used to map a JobAction to its result file.
+  typedef llvm::DenseMap<const JobAction*, const char*> ArgStringMap;
+
+  /// ActionList - Type used for lists of actions.
+  typedef SmallVector<Action*, 3> ActionList;
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
new file mode 100644
index 0000000..5cc5b9c
--- /dev/null
+++ b/include/clang/Edit/Commit.h
@@ -0,0 +1,149 @@
+//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_COMMIT_H
+#define LLVM_CLANG_EDIT_COMMIT_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+  class LangOptions;
+  class PPConditionalDirectiveRecord;
+
+namespace edit {
+  class EditedSource;
+
+class Commit {
+public:
+  enum EditKind {
+    Act_Insert,
+    Act_InsertFromRange,
+    Act_Remove
+  };
+
+  struct Edit {
+    EditKind Kind;
+    StringRef Text;
+    SourceLocation OrigLoc;
+    FileOffset Offset;
+    FileOffset InsertFromRangeOffs;
+    unsigned Length;
+    bool BeforePrev;
+
+    SourceLocation getFileLocation(SourceManager &SM) const;
+    CharSourceRange getFileRange(SourceManager &SM) const;
+    CharSourceRange getInsertFromRange(SourceManager &SM) const;
+  };
+
+private:
+  const SourceManager &SourceMgr;
+  const LangOptions &LangOpts;
+  const PPConditionalDirectiveRecord *PPRec;
+  EditedSource *Editor;
+
+  bool IsCommitable;
+  SmallVector<Edit, 8> CachedEdits;
+  
+  llvm::BumpPtrAllocator StrAlloc;
+
+public:
+  explicit Commit(EditedSource &Editor);
+  Commit(const SourceManager &SM, const LangOptions &LangOpts,
+         const PPConditionalDirectiveRecord *PPRec = nullptr)
+    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(nullptr),
+      IsCommitable(true) { }
+
+  bool isCommitable() const { return IsCommitable; }
+
+  bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
+              bool beforePreviousInsertions = false);
+  bool insertAfterToken(SourceLocation loc, StringRef text,
+                        bool beforePreviousInsertions = false) {
+    return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
+  }
+  bool insertBefore(SourceLocation loc, StringRef text) {
+    return insert(loc, text, /*afterToken=*/false,
+                  /*beforePreviousInsertions=*/true);
+  }
+  bool insertFromRange(SourceLocation loc, CharSourceRange range,
+                       bool afterToken = false,
+                       bool beforePreviousInsertions = false);
+  bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
+
+  bool remove(CharSourceRange range);
+
+  bool replace(CharSourceRange range, StringRef text);
+  bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
+  bool replaceText(SourceLocation loc, StringRef text,
+                   StringRef replacementText);
+
+  bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
+                       bool afterToken = false,
+                       bool beforePreviousInsertions = false) {
+    return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
+                           afterToken, beforePreviousInsertions);
+  }
+  bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
+    return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
+  }
+  bool remove(SourceRange TokenRange) {
+    return remove(CharSourceRange::getTokenRange(TokenRange));
+  }
+  bool replace(SourceRange TokenRange, StringRef text) {
+    return replace(CharSourceRange::getTokenRange(TokenRange), text);
+  }
+  bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
+    return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
+                            CharSourceRange::getTokenRange(TokenInnerRange));
+  }
+
+  typedef SmallVectorImpl<Edit>::const_iterator edit_iterator;
+  edit_iterator edit_begin() const { return CachedEdits.begin(); }
+  edit_iterator edit_end() const { return CachedEdits.end(); }
+
+private:
+  void addInsert(SourceLocation OrigLoc,
+                FileOffset Offs, StringRef text, bool beforePreviousInsertions);
+  void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+                          FileOffset RangeOffs, unsigned RangeLen,
+                          bool beforePreviousInsertions);
+  void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
+
+  bool canInsert(SourceLocation loc, FileOffset &Offset);
+  bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
+                           SourceLocation &AfterLoc);
+  bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+  bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
+  bool canReplaceText(SourceLocation loc, StringRef text,
+                      FileOffset &Offs, unsigned &Len);
+
+  void commitInsert(FileOffset offset, StringRef text,
+                    bool beforePreviousInsertions);
+  void commitRemove(FileOffset offset, unsigned length);
+
+  bool isAtStartOfMacroExpansion(SourceLocation loc,
+                                 SourceLocation *MacroBegin = nullptr) const;
+  bool isAtEndOfMacroExpansion(SourceLocation loc,
+                               SourceLocation *MacroEnd = nullptr) const;
+
+  StringRef copyString(StringRef str) {
+    char *buf = StrAlloc.Allocate<char>(str.size());
+    std::memcpy(buf, str.data(), str.size());
+    return StringRef(buf, str.size());
+  }
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
new file mode 100644
index 0000000..150a5b4
--- /dev/null
+++ b/include/clang/Edit/EditedSource.h
@@ -0,0 +1,89 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H
+#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <map>
+
+namespace clang {
+  class LangOptions;
+  class PPConditionalDirectiveRecord;
+
+namespace edit {
+  class Commit;
+  class EditsReceiver;
+
+class EditedSource {
+  const SourceManager &SourceMgr;
+  const LangOptions &LangOpts;
+  const PPConditionalDirectiveRecord *PPRec;
+
+  struct FileEdit {
+    StringRef Text;
+    unsigned RemoveLen;
+
+    FileEdit() : RemoveLen(0) {}
+  };
+
+  typedef std::map<FileOffset, FileEdit> FileEditsTy;
+  FileEditsTy FileEdits;
+
+  llvm::DenseMap<unsigned, SourceLocation> ExpansionToArgMap;
+
+  llvm::BumpPtrAllocator StrAlloc;
+
+public:
+  EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
+               const PPConditionalDirectiveRecord *PPRec = nullptr)
+    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
+      StrAlloc() { }
+
+  const SourceManager &getSourceManager() const { return SourceMgr; }
+  const LangOptions &getLangOpts() const { return LangOpts; }
+  const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
+    return PPRec;
+  }
+
+  bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+
+  bool commit(const Commit &commit);
+  
+  void applyRewrites(EditsReceiver &receiver);
+  void clearRewrites();
+
+  StringRef copyString(StringRef str) {
+    char *buf = StrAlloc.Allocate<char>(str.size());
+    std::memcpy(buf, str.data(), str.size());
+    return StringRef(buf, str.size());
+  }
+  StringRef copyString(const Twine &twine);
+
+private:
+  bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
+                    bool beforePreviousInsertions);
+  bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+                             FileOffset InsertFromRangeOffs, unsigned Len,
+                             bool beforePreviousInsertions);
+  void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len);
+
+  StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
+                          bool &Invalid);
+  FileEditsTy::iterator getActionForOffset(FileOffset Offs);
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h
new file mode 100644
index 0000000..600ac28
--- /dev/null
+++ b/include/clang/Edit/EditsReceiver.h
@@ -0,0 +1,35 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITSRECEIVER_H
+#define LLVM_CLANG_EDIT_EDITSRECEIVER_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+  class SourceLocation;
+  class CharSourceRange;
+
+namespace edit {
+
+class EditsReceiver {
+public:
+  virtual ~EditsReceiver() { }
+
+  virtual void insert(SourceLocation loc, StringRef text) = 0;
+  virtual void replace(CharSourceRange range, StringRef text) = 0;
+  /// \brief By default it calls replace with an empty string.
+  virtual void remove(CharSourceRange range);
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
new file mode 100644
index 0000000..0c1e72b
--- /dev/null
+++ b/include/clang/Edit/FileOffset.h
@@ -0,0 +1,61 @@
+//===----- FileOffset.h - Offset in a file ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_FILEOFFSET_H
+#define LLVM_CLANG_EDIT_FILEOFFSET_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+namespace edit {
+
+class FileOffset {
+  FileID FID;
+  unsigned Offs;
+public:
+  FileOffset() : Offs(0) { }
+  FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) { }
+
+  bool isInvalid() const { return FID.isInvalid(); }
+
+  FileID getFID() const { return FID; }
+  unsigned getOffset() const { return Offs; }
+
+  FileOffset getWithOffset(unsigned offset) const {
+    FileOffset NewOffs = *this;
+    NewOffs.Offs += offset;
+    return NewOffs;
+  }
+
+  friend bool operator==(FileOffset LHS, FileOffset RHS) {
+    return LHS.FID == RHS.FID && LHS.Offs == RHS.Offs;
+  }
+  friend bool operator!=(FileOffset LHS, FileOffset RHS) {
+    return !(LHS == RHS);
+  }
+  friend bool operator<(FileOffset LHS, FileOffset RHS) {
+    return std::tie(LHS.FID, LHS.Offs) < std::tie(RHS.FID, RHS.Offs);
+  }
+  friend bool operator>(FileOffset LHS, FileOffset RHS) {
+    return RHS < LHS;
+  }
+  friend bool operator>=(FileOffset LHS, FileOffset RHS) {
+    return !(LHS < RHS);
+  }
+  friend bool operator<=(FileOffset LHS, FileOffset RHS) {
+    return !(RHS < LHS);
+  }
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
new file mode 100644
index 0000000..5e3425f
--- /dev/null
+++ b/include/clang/Edit/Rewriters.h
@@ -0,0 +1,41 @@
+//===--- Rewriters.h - Rewritings     ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_REWRITERS_H
+#define LLVM_CLANG_EDIT_REWRITERS_H
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class ObjCMessageExpr;
+  class ObjCMethodDecl;
+  class ObjCInterfaceDecl;
+  class ObjCProtocolDecl;
+  class NSAPI;
+  class EnumDecl;
+  class TypedefDecl;
+  class ParentMap;
+
+namespace edit {
+  class Commit;
+
+bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
+                                         const NSAPI &NS, Commit &commit);
+
+bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
+                                const NSAPI &NS, Commit &commit,
+                                const ParentMap *PMap);
+  
+bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit);
+
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
new file mode 100644
index 0000000..45cccaa
--- /dev/null
+++ b/include/clang/Format/Format.h
@@ -0,0 +1,532 @@
+//===--- Format.h - Format C++ code -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Various functions to configurably format source code.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_FORMAT_H
+#define LLVM_CLANG_FORMAT_FORMAT_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/Refactoring.h"
+#include <system_error>
+
+namespace clang {
+
+class Lexer;
+class SourceManager;
+class DiagnosticConsumer;
+
+namespace format {
+
+enum class ParseError { Success = 0, Error, Unsuitable };
+class ParseErrorCategory final : public std::error_category {
+public:
+  const char *name() const LLVM_NOEXCEPT override;
+  std::string message(int EV) const override;
+};
+const std::error_category &getParseCategory();
+std::error_code make_error_code(ParseError e);
+
+/// \brief The \c FormatStyle is used to configure the formatting to follow
+/// specific guidelines.
+struct FormatStyle {
+  /// \brief Supported languages. When stored in a configuration file, specifies
+  /// the language, that the configuration targets. When passed to the
+  /// reformat() function, enables syntax features specific to the language.
+  enum LanguageKind {
+    /// Do not use.
+    LK_None,
+    /// Should be used for C, C++, ObjectiveC, ObjectiveC++.
+    LK_Cpp,
+    /// Should be used for JavaScript.
+    LK_JavaScript,
+    /// Should be used for Protocol Buffers
+    /// (https://developers.google.com/protocol-buffers/).
+    LK_Proto
+  };
+
+  /// \brief Language, this format style is targeted at.
+  LanguageKind Language;
+
+  /// \brief The column limit.
+  ///
+  /// A column limit of \c 0 means that there is no column limit. In this case,
+  /// clang-format will respect the input's line breaking decisions within
+  /// statements unless they contradict other rules.
+  unsigned ColumnLimit;
+
+  /// \brief The maximum number of consecutive empty lines to keep.
+  unsigned MaxEmptyLinesToKeep;
+
+  /// \brief If true, empty lines at the start of blocks are kept.
+  bool KeepEmptyLinesAtTheStartOfBlocks;
+
+  /// \brief The penalty for each line break introduced inside a comment.
+  unsigned PenaltyBreakComment;
+
+  /// \brief The penalty for each line break introduced inside a string literal.
+  unsigned PenaltyBreakString;
+
+  /// \brief The penalty for each character outside of the column limit.
+  unsigned PenaltyExcessCharacter;
+
+  /// \brief The penalty for breaking before the first \c <<.
+  unsigned PenaltyBreakFirstLessLess;
+
+  /// \brief The penalty for breaking a function call after "call(".
+  unsigned PenaltyBreakBeforeFirstCallParameter;
+
+  /// \brief The & and * alignment style.
+  enum PointerAlignmentStyle {
+    /// Align pointer to the left.
+    PAS_Left,
+    /// Align pointer to the right.
+    PAS_Right,
+    /// Align pointer in the middle.
+    PAS_Middle
+  };
+
+  /// Pointer and reference alignment style.
+  PointerAlignmentStyle PointerAlignment;
+
+  /// \brief If \c true, analyze the formatted file for the most common
+  /// alignment of & and *. \c PointerAlignment is then used only as fallback.
+  bool DerivePointerAlignment;
+
+  /// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
+  int AccessModifierOffset;
+
+  /// \brief Supported language standards.
+  enum LanguageStandard {
+    /// Use C++03-compatible syntax.
+    LS_Cpp03,
+    /// Use features of C++11 (e.g. \c A<A<int>> instead of
+    /// <tt>A<A<int> ></tt>).
+    LS_Cpp11,
+    /// Automatic detection based on the input.
+    LS_Auto
+  };
+
+  /// \brief Format compatible with this standard, e.g. use
+  /// <tt>A<A<int> ></tt> instead of \c A<A<int>> for LS_Cpp03.
+  LanguageStandard Standard;
+
+  /// \brief Indent case labels one level from the switch statement.
+  ///
+  /// When \c false, use the same indentation level as for the switch statement.
+  /// Switch statement body is always indented one level more than case labels.
+  bool IndentCaseLabels;
+
+  /// \brief Indent if a function definition or declaration is wrapped after the
+  /// type.
+  bool IndentWrappedFunctionNames;
+
+  /// \brief Different ways to indent namespace contents.
+  enum NamespaceIndentationKind {
+    /// Don't indent in namespaces.
+    NI_None,
+    /// Indent only in inner namespaces (nested in other namespaces).
+    NI_Inner,
+    /// Indent in all namespaces.
+    NI_All
+  };
+
+  /// \brief The indentation used for namespaces.
+  NamespaceIndentationKind NamespaceIndentation;
+
+  /// \brief The number of spaces before trailing line comments
+  /// (\c // - comments).
+  ///
+  /// This does not affect trailing block comments (\c /**/ - comments) as those
+  /// commonly have different usage patterns and a number of special cases.
+  unsigned SpacesBeforeTrailingComments;
+
+  /// \brief If \c false, a function call's or function definition's parameters
+  /// will either all be on the same line or will have one line each.
+  bool BinPackParameters;
+
+  /// \brief If \c true, clang-format detects whether function calls and
+  /// definitions are formatted with one parameter per line.
+  ///
+  /// Each call can be bin-packed, one-per-line or inconclusive. If it is
+  /// inconclusive, e.g. completely on one line, but a decision needs to be
+  /// made, clang-format analyzes whether there are other bin-packed cases in
+  /// the input file and act accordingly.
+  ///
+  /// NOTE: This is an experimental flag, that might go away or be renamed. Do
+  /// not use this in config files, etc. Use at your own risk.
+  bool ExperimentalAutoDetectBinPacking;
+
+  /// \brief Allow putting all parameters of a function declaration onto
+  /// the next line even if \c BinPackParameters is \c false.
+  bool AllowAllParametersOfDeclarationOnNextLine;
+
+  /// \brief Penalty for putting the return type of a function onto its own
+  /// line.
+  unsigned PenaltyReturnTypeOnItsOwnLine;
+
+  /// \brief If the constructor initializers don't fit on a line, put each
+  /// initializer on its own line.
+  bool ConstructorInitializerAllOnOneLineOrOnePerLine;
+
+  /// \brief Always break constructor initializers before commas and align
+  /// the commas with the colon.
+  bool BreakConstructorInitializersBeforeComma;
+
+  /// \brief Allows contracting simple braced statements to a single line.
+  ///
+  /// E.g., this allows <tt>if (a) { return; }</tt> to be put on a single line.
+  bool AllowShortBlocksOnASingleLine;
+
+  /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single
+  /// line.
+  bool AllowShortIfStatementsOnASingleLine;
+
+  /// \brief If \c true, <tt>while (true) continue;</tt> can be put on a
+  /// single line.
+  bool AllowShortLoopsOnASingleLine;
+
+  /// \brief Different styles for merging short functions containing at most one
+  /// statement.
+  enum ShortFunctionStyle {
+    /// \brief Never merge functions into a single line.
+    SFS_None,
+    /// \brief Only merge functions defined inside a class.
+    SFS_Inline,
+    /// \brief Merge all functions fitting on a single line.
+    SFS_All,
+  };
+
+  /// \brief Dependent on the value, <tt>int f() { return 0; }</tt> can be put
+  /// on a single line.
+  ShortFunctionStyle AllowShortFunctionsOnASingleLine;
+
+  /// \brief Add a space after \c @property in Objective-C, i.e. use
+  /// <tt>\@property (readonly)</tt> instead of <tt>\@property(readonly)</tt>.
+  bool ObjCSpaceAfterProperty;
+
+  /// \brief Add a space in front of an Objective-C protocol list, i.e. use
+  /// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>.
+  bool ObjCSpaceBeforeProtocolList;
+
+  /// \brief If \c true, aligns trailing comments.
+  bool AlignTrailingComments;
+
+  /// \brief If \c true, aligns escaped newlines as far left as possible.
+  /// Otherwise puts them into the right-most column.
+  bool AlignEscapedNewlinesLeft;
+
+  /// \brief The number of columns to use for indentation.
+  unsigned IndentWidth;
+
+  /// \brief The number of columns used for tab stops.
+  unsigned TabWidth;
+
+  /// \brief The number of characters to use for indentation of constructor
+  /// initializer lists.
+  unsigned ConstructorInitializerIndentWidth;
+
+  /// \brief If \c true, always break after the <tt>template<...></tt> of a
+  /// template declaration.
+  bool AlwaysBreakTemplateDeclarations;
+
+  /// \brief If \c true, always break before multiline string literals.
+  bool AlwaysBreakBeforeMultilineStrings;
+
+  /// \brief Different ways to use tab in formatting.
+  enum UseTabStyle {
+    /// Never use tab.
+    UT_Never,
+    /// Use tabs only for indentation.
+    UT_ForIndentation,
+    /// Use tabs whenever we need to fill whitespace that spans at least from
+    /// one tab stop to the next one.
+    UT_Always
+  };
+
+  /// \brief The way to use tab characters in the resulting file.
+  UseTabStyle UseTab;
+
+  /// \brief If \c true, binary operators will be placed after line breaks.
+  bool BreakBeforeBinaryOperators;
+
+  /// \brief If \c true, ternary operators will be placed after line breaks.
+  bool BreakBeforeTernaryOperators;
+
+  /// \brief Different ways to attach braces to their surrounding context.
+  enum BraceBreakingStyle {
+    /// Always attach braces to surrounding context.
+    BS_Attach,
+    /// Like \c Attach, but break before braces on function, namespace and
+    /// class definitions.
+    BS_Linux,
+    /// Like \c Attach, but break before function definitions.
+    BS_Stroustrup,
+    /// Always break before braces.
+    BS_Allman,
+    /// Always break before braces and add an extra level of indentation to
+    /// braces of control statements, not to those of class, function
+    /// or other definitions.
+    BS_GNU
+  };
+
+  /// \brief The brace breaking style to use.
+  BraceBreakingStyle BreakBeforeBraces;
+
+  /// \brief If \c true, format braced lists as best suited for C++11 braced
+  /// lists.
+  ///
+  /// Important differences:
+  /// - No spaces inside the braced list.
+  /// - No line break before the closing brace.
+  /// - Indentation with the continuation indent, not with the block indent.
+  ///
+  /// Fundamentally, C++11 braced lists are formatted exactly like function
+  /// calls would be formatted in their place. If the braced list follows a name
+  /// (e.g. a type or variable name), clang-format formats as if the \c {} were
+  /// the parentheses of a function call with that name. If there is no name,
+  /// a zero-length name is assumed.
+  bool Cpp11BracedListStyle;
+
+  /// \brief If \c true, spaces will be inserted after '(' and before ')'.
+  bool SpacesInParentheses;
+
+  /// \brief If \c true, spaces will be inserted after '<' and before '>' in
+  /// template argument lists
+  bool SpacesInAngles;
+
+  /// \brief If \c true, spaces may be inserted into '()'.
+  bool SpaceInEmptyParentheses;
+
+  /// \brief If \c true, spaces are inserted inside container literals (e.g.
+  /// ObjC and Javascript array and dict literals).
+  bool SpacesInContainerLiterals;
+
+  /// \brief If \c true, spaces may be inserted into C style casts.
+  bool SpacesInCStyleCastParentheses;
+
+  /// \brief Different ways to put a space before opening parentheses.
+  enum SpaceBeforeParensOptions {
+    /// Never put a space before opening parentheses.
+    SBPO_Never,
+    /// Put a space before opening parentheses only after control statement
+    /// keywords (<tt>for/if/while...</tt>).
+    SBPO_ControlStatements,
+    /// Always put a space before opening parentheses, except when it's
+    /// prohibited by the syntax rules (in function-like macro definitions) or
+    /// when determined by other style rules (after unary operators, opening
+    /// parentheses, etc.)
+    SBPO_Always
+  };
+
+  /// \brief Defines in which cases to put a space before opening parentheses.
+  SpaceBeforeParensOptions SpaceBeforeParens;
+
+  /// \brief If \c false, spaces will be removed before assignment operators.
+  bool SpaceBeforeAssignmentOperators;
+
+  /// \brief Indent width for line continuations.
+  unsigned ContinuationIndentWidth;
+
+  /// \brief A regular expression that describes comments with special meaning,
+  /// which should not be split into lines or otherwise changed.
+  std::string CommentPragmas;
+
+  /// \brief Disables formatting at all.
+  bool DisableFormat;
+
+  /// \brief A vector of macros that should be interpreted as foreach loops
+  /// instead of as function calls.
+  ///
+  /// These are expected to be macros of the form:
+  /// \code
+  /// FOREACH(<variable-declaration>, ...)
+  ///   <loop-body>
+  /// \endcode
+  ///
+  /// For example: BOOST_FOREACH.
+  std::vector<std::string> ForEachMacros;
+
+  bool operator==(const FormatStyle &R) const {
+    return AccessModifierOffset == R.AccessModifierOffset &&
+           ConstructorInitializerIndentWidth ==
+               R.ConstructorInitializerIndentWidth &&
+           AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
+           AlignTrailingComments == R.AlignTrailingComments &&
+           AllowAllParametersOfDeclarationOnNextLine ==
+               R.AllowAllParametersOfDeclarationOnNextLine &&
+           AllowShortFunctionsOnASingleLine ==
+               R.AllowShortFunctionsOnASingleLine &&
+           AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
+           AllowShortIfStatementsOnASingleLine ==
+               R.AllowShortIfStatementsOnASingleLine &&
+           AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
+           AlwaysBreakTemplateDeclarations ==
+               R.AlwaysBreakTemplateDeclarations &&
+           AlwaysBreakBeforeMultilineStrings ==
+               R.AlwaysBreakBeforeMultilineStrings &&
+           BinPackParameters == R.BinPackParameters &&
+           BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
+           BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
+           BreakBeforeBraces == R.BreakBeforeBraces &&
+           BreakConstructorInitializersBeforeComma ==
+               R.BreakConstructorInitializersBeforeComma &&
+           ColumnLimit == R.ColumnLimit &&
+           ConstructorInitializerAllOnOneLineOrOnePerLine ==
+               R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
+           DerivePointerAlignment == R.DerivePointerAlignment &&
+           ExperimentalAutoDetectBinPacking ==
+               R.ExperimentalAutoDetectBinPacking &&
+           IndentCaseLabels == R.IndentCaseLabels &&
+           IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
+           IndentWidth == R.IndentWidth && Language == R.Language &&
+           MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
+           KeepEmptyLinesAtTheStartOfBlocks ==
+               R.KeepEmptyLinesAtTheStartOfBlocks &&
+           NamespaceIndentation == R.NamespaceIndentation &&
+           ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
+           ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
+           PenaltyBreakComment == R.PenaltyBreakComment &&
+           PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
+           PenaltyBreakString == R.PenaltyBreakString &&
+           PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
+           PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
+           PointerAlignment == R.PointerAlignment &&
+           SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
+           Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
+           Standard == R.Standard && TabWidth == R.TabWidth &&
+           UseTab == R.UseTab && SpacesInParentheses == R.SpacesInParentheses &&
+           SpacesInAngles == R.SpacesInAngles &&
+           SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
+           SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
+           SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
+           SpaceBeforeParens == R.SpaceBeforeParens &&
+           SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
+           ContinuationIndentWidth == R.ContinuationIndentWidth &&
+           CommentPragmas == R.CommentPragmas &&
+           ForEachMacros == R.ForEachMacros;
+  }
+};
+
+/// \brief Returns a format style complying with the LLVM coding standards:
+/// http://llvm.org/docs/CodingStandards.html.
+FormatStyle getLLVMStyle();
+
+/// \brief Returns a format style complying with one of Google's style guides:
+/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
+/// http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml.
+/// https://developers.google.com/protocol-buffers/docs/style.
+FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language);
+
+/// \brief Returns a format style complying with Chromium's style guide:
+/// http://www.chromium.org/developers/coding-style.
+FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language);
+
+/// \brief Returns a format style complying with Mozilla's style guide:
+/// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style.
+FormatStyle getMozillaStyle();
+
+/// \brief Returns a format style complying with Webkit's style guide:
+/// http://www.webkit.org/coding/coding-style.html
+FormatStyle getWebKitStyle();
+
+/// \brief Returns a format style complying with GNU Coding Standards:
+/// http://www.gnu.org/prep/standards/standards.html
+FormatStyle getGNUStyle();
+
+/// \brief Returns style indicating formatting should be not applied at all.
+FormatStyle getNoStyle();
+
+/// \brief Gets a predefined style for the specified language by name.
+///
+/// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
+/// compared case-insensitively.
+///
+/// Returns \c true if the Style has been set.
+bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
+                        FormatStyle *Style);
+
+/// \brief Parse configuration from YAML-formatted text.
+///
+/// Style->Language is used to get the base style, if the \c BasedOnStyle
+/// option is present.
+///
+/// When \c BasedOnStyle is not present, options not present in the YAML
+/// document, are retained in \p Style.
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
+
+/// \brief Gets configuration in a YAML string.
+std::string configurationAsText(const FormatStyle &Style);
+
+/// \brief Reformats the given \p Ranges in the token stream coming out of
+/// \c Lex.
+///
+/// Each range is extended on either end to its next bigger logic unit, i.e.
+/// everything that might influence its formatting or might be influenced by its
+/// formatting.
+///
+/// Returns the \c Replacements necessary to make all \p Ranges comply with
+/// \p Style.
+tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
+                               SourceManager &SourceMgr,
+                               std::vector<CharSourceRange> Ranges);
+
+/// \brief Reformats the given \p Ranges in \p Code.
+///
+/// Otherwise identical to the reformat() function consuming a \c Lexer.
+tooling::Replacements reformat(const FormatStyle &Style, StringRef Code,
+                               std::vector<tooling::Range> Ranges,
+                               StringRef FileName = "<stdin>");
+
+/// \brief Returns the \c LangOpts that the formatter expects you to set.
+///
+/// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11
+/// lexing mode, LS_Cpp03 - C++03 mode.
+LangOptions getFormattingLangOpts(
+    FormatStyle::LanguageStandard Standard = FormatStyle::LS_Cpp11);
+
+/// \brief Description to be used for help text for a llvm::cl option for
+/// specifying format style. The description is closely related to the operation
+/// of getStyle().
+extern const char *StyleOptionHelpDescription;
+
+/// \brief Construct a FormatStyle based on \c StyleName.
+///
+/// \c StyleName can take several forms:
+/// \li "{<key>: <value>, ...}" - Set specic style parameters.
+/// \li "<style name>" - One of the style names supported by
+/// getPredefinedStyle().
+/// \li "file" - Load style configuration from a file called '.clang-format'
+/// located in one of the parent directories of \c FileName or the current
+/// directory if \c FileName is empty.
+///
+/// \param[in] StyleName Style name to interpret according to the description
+/// above.
+/// \param[in] FileName Path to start search for .clang-format if \c StyleName
+/// == "file".
+/// \param[in] FallbackStyle The name of a predefined style used to fallback to
+/// in case the style can't be determined from \p StyleName.
+///
+/// \returns FormatStyle as specified by \c StyleName. If no style could be
+/// determined, the default is LLVM Style (see getLLVMStyle()).
+FormatStyle getStyle(StringRef StyleName, StringRef FileName,
+                     StringRef FallbackStyle);
+
+} // end namespace format
+} // end namespace clang
+
+namespace std {
+template <>
+struct is_error_code_enum<clang::format::ParseError> : std::true_type {};
+}
+
+#endif // LLVM_CLANG_FORMAT_FORMAT_H
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
new file mode 100644
index 0000000..366c499
--- /dev/null
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -0,0 +1,54 @@
+//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DRIVER_ASTCONSUMERS_H
+#define DRIVER_ASTCONSUMERS_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+
+class ASTConsumer;
+class CodeGenOptions;
+class DiagnosticsEngine;
+class FileManager;
+class LangOptions;
+class Preprocessor;
+class TargetOptions;
+
+// AST pretty-printer: prints out the AST in a format that is close to the
+// original C code.  The output is intended to be in a format such that
+// clang could re-parse the output back into the same AST, but the
+// implementation is still incomplete.
+ASTConsumer *CreateASTPrinter(raw_ostream *OS, StringRef FilterString);
+
+// AST dumper: dumps the raw AST in human-readable form to stderr; this is
+// intended for debugging.
+ASTConsumer *CreateASTDumper(StringRef FilterString, bool DumpLookups = false);
+
+// AST Decl node lister: prints qualified names of all filterable AST Decl
+// nodes.
+ASTConsumer *CreateASTDeclNodeLister();
+
+// Graphical AST viewer: for each function definition, creates a graph of
+// the AST and displays it with the graph viewer "dotty".  Also outputs
+// function declarations to stderr.
+ASTConsumer *CreateASTViewer();
+
+// DeclContext printer: prints out the DeclContext tree in human-readable form
+// to stderr; this is intended for debugging.
+ASTConsumer *CreateDeclContextPrinter();
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
new file mode 100644
index 0000000..42dc69a
--- /dev/null
+++ b/include/clang/Frontend/ASTUnit.h
@@ -0,0 +1,884 @@
+//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ASTUnit utility class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
+#define LLVM_CLANG_FRONTEND_ASTUNIT_H
+
+#include "clang-c/Index.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/ModuleLoader.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Support/Path.h"
+#include <cassert>
+#include <map>
+#include <memory>
+#include <string>
+#include <sys/types.h>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+class Sema;
+class ASTContext;
+class ASTReader;
+class CodeCompleteConsumer;
+class CompilerInvocation;
+class CompilerInstance;
+class Decl;
+class DiagnosticsEngine;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+class ASTFrontendAction;
+class ASTDeserializationListener;
+
+/// \brief Utility class for loading a ASTContext from an AST file.
+///
+class ASTUnit : public ModuleLoader {
+public:
+  struct StandaloneFixIt {
+    std::pair<unsigned, unsigned> RemoveRange;
+    std::pair<unsigned, unsigned> InsertFromRange;
+    std::string CodeToInsert;
+    bool BeforePreviousInsertions;
+  };
+
+  struct StandaloneDiagnostic {
+    unsigned ID;
+    DiagnosticsEngine::Level Level;
+    std::string Message;
+    std::string Filename;
+    unsigned LocOffset;
+    std::vector<std::pair<unsigned, unsigned> > Ranges;
+    std::vector<StandaloneFixIt> FixIts;
+  };
+
+private:
+  std::shared_ptr<LangOptions>            LangOpts;
+  IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
+  IntrusiveRefCntPtr<FileManager>         FileMgr;
+  IntrusiveRefCntPtr<SourceManager>       SourceMgr;
+  std::unique_ptr<HeaderSearch>           HeaderInfo;
+  IntrusiveRefCntPtr<TargetInfo>          Target;
+  IntrusiveRefCntPtr<Preprocessor>        PP;
+  IntrusiveRefCntPtr<ASTContext>          Ctx;
+  std::shared_ptr<TargetOptions>          TargetOpts;
+  IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+  IntrusiveRefCntPtr<ASTReader> Reader;
+  bool HadModuleLoaderFatalFailure;
+
+  struct ASTWriterData;
+  std::unique_ptr<ASTWriterData> WriterData;
+
+  FileSystemOptions FileSystemOpts;
+
+  /// \brief The AST consumer that received information about the translation
+  /// unit as it was parsed or loaded.
+  std::unique_ptr<ASTConsumer> Consumer;
+
+  /// \brief The semantic analysis object used to type-check the translation
+  /// unit.
+  std::unique_ptr<Sema> TheSema;
+
+  /// Optional owned invocation, just used to make the invocation used in
+  /// LoadFromCommandLine available.
+  IntrusiveRefCntPtr<CompilerInvocation> Invocation;
+  
+  // OnlyLocalDecls - when true, walking this AST should only visit declarations
+  // that come from the AST itself, not from included precompiled headers.
+  // FIXME: This is temporary; eventually, CIndex will always do this.
+  bool                              OnlyLocalDecls;
+
+  /// \brief Whether to capture any diagnostics produced.
+  bool CaptureDiagnostics;
+
+  /// \brief Track whether the main file was loaded from an AST or not.
+  bool MainFileIsAST;
+
+  /// \brief What kind of translation unit this AST represents.
+  TranslationUnitKind TUKind;
+
+  /// \brief Whether we should time each operation.
+  bool WantTiming;
+
+  /// \brief Whether the ASTUnit should delete the remapped buffers.
+  bool OwnsRemappedFileBuffers;
+  
+  /// Track the top-level decls which appeared in an ASTUnit which was loaded
+  /// from a source file.
+  //
+  // FIXME: This is just an optimization hack to avoid deserializing large parts
+  // of a PCH file when using the Index library on an ASTUnit loaded from
+  // source. In the long term we should make the Index library use efficient and
+  // more scalable search mechanisms.
+  std::vector<Decl*> TopLevelDecls;
+
+  /// \brief Sorted (by file offset) vector of pairs of file offset/Decl.
+  typedef SmallVector<std::pair<unsigned, Decl *>, 64> LocDeclsTy;
+  typedef llvm::DenseMap<FileID, LocDeclsTy *> FileDeclsTy;
+
+  /// \brief Map from FileID to the file-level declarations that it contains.
+  /// The files and decls are only local (and non-preamble) ones.
+  FileDeclsTy FileDecls;
+  
+  /// The name of the original source file used to generate this ASTUnit.
+  std::string OriginalSourceFile;
+
+  /// \brief The set of diagnostics produced when creating the preamble.
+  SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
+
+  /// \brief The set of diagnostics produced when creating this
+  /// translation unit.
+  SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
+
+  /// \brief The set of diagnostics produced when failing to parse, e.g. due
+  /// to failure to load the PCH.
+  SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics;
+
+  /// \brief The number of stored diagnostics that come from the driver
+  /// itself.
+  ///
+  /// Diagnostics that come from the driver are retained from one parse to
+  /// the next.
+  unsigned NumStoredDiagnosticsFromDriver;
+  
+  /// \brief Counter that determines when we want to try building a
+  /// precompiled preamble.
+  ///
+  /// If zero, we will never build a precompiled preamble. Otherwise,
+  /// it's treated as a counter that decrements each time we reparse
+  /// without the benefit of a precompiled preamble. When it hits 1,
+  /// we'll attempt to rebuild the precompiled header. This way, if
+  /// building the precompiled preamble fails, we won't try again for
+  /// some number of calls.
+  unsigned PreambleRebuildCounter;
+
+public:
+  class PreambleData {
+    const FileEntry *File;
+    std::vector<char> Buffer;
+    mutable unsigned NumLines;
+    
+  public:
+    PreambleData() : File(nullptr), NumLines(0) { }
+    
+    void assign(const FileEntry *F, const char *begin, const char *end) {
+      File = F;
+      Buffer.assign(begin, end);
+      NumLines = 0;
+    }
+
+    void clear() { Buffer.clear(); File = nullptr; NumLines = 0; }
+
+    size_t size() const { return Buffer.size(); }
+    bool empty() const { return Buffer.empty(); }
+
+    const char *getBufferStart() const { return &Buffer[0]; }
+
+    unsigned getNumLines() const {
+      if (NumLines)
+        return NumLines;
+      countLines();
+      return NumLines;
+    }
+
+    SourceRange getSourceRange(const SourceManager &SM) const {
+      SourceLocation FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID());
+      return SourceRange(FileLoc, FileLoc.getLocWithOffset(size()-1));
+    }
+
+  private:
+    void countLines() const;
+  };
+
+  const PreambleData &getPreambleData() const {
+    return Preamble;
+  }
+
+  /// Data used to determine if a file used in the preamble has been changed.
+  struct PreambleFileHash {
+    /// All files have size set.
+    off_t Size;
+
+    /// Modification time is set for files that are on disk.  For memory
+    /// buffers it is zero.
+    time_t ModTime;
+
+    /// Memory buffers have MD5 instead of modification time.  We don't
+    /// compute MD5 for on-disk files because we hope that modification time is
+    /// enough to tell if the file was changed.
+    llvm::MD5::MD5Result MD5;
+
+    static PreambleFileHash createForFile(off_t Size, time_t ModTime);
+    static PreambleFileHash
+    createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
+
+    friend bool operator==(const PreambleFileHash &LHS,
+                           const PreambleFileHash &RHS);
+
+    friend bool operator!=(const PreambleFileHash &LHS,
+                           const PreambleFileHash &RHS) {
+      return !(LHS == RHS);
+    }
+  };
+
+private:
+  /// \brief The contents of the preamble that has been precompiled to
+  /// \c PreambleFile.
+  PreambleData Preamble;
+
+  /// \brief Whether the preamble ends at the start of a new line.
+  /// 
+  /// Used to inform the lexer as to whether it's starting at the beginning of
+  /// a line after skipping the preamble.
+  bool PreambleEndsAtStartOfLine;
+
+  /// \brief Keeps track of the files that were used when computing the 
+  /// preamble, with both their buffer size and their modification time.
+  ///
+  /// If any of the files have changed from one compile to the next,
+  /// the preamble must be thrown away.
+  llvm::StringMap<PreambleFileHash> FilesInPreamble;
+
+  /// \brief When non-NULL, this is the buffer used to store the contents of
+  /// the main file when it has been padded for use with the precompiled
+  /// preamble.
+  llvm::MemoryBuffer *SavedMainFileBuffer;
+
+  /// \brief When non-NULL, this is the buffer used to store the
+  /// contents of the preamble when it has been padded to build the
+  /// precompiled preamble.
+  llvm::MemoryBuffer *PreambleBuffer;
+
+  /// \brief The number of warnings that occurred while parsing the preamble.
+  ///
+  /// This value will be used to restore the state of the \c DiagnosticsEngine
+  /// object when re-using the precompiled preamble. Note that only the
+  /// number of warnings matters, since we will not save the preamble
+  /// when any errors are present.
+  unsigned NumWarningsInPreamble;
+
+  /// \brief A list of the serialization ID numbers for each of the top-level
+  /// declarations parsed within the precompiled preamble.
+  std::vector<serialization::DeclID> TopLevelDeclsInPreamble;
+  
+  /// \brief Whether we should be caching code-completion results.
+  bool ShouldCacheCodeCompletionResults : 1;
+
+  /// \brief Whether to include brief documentation within the set of code
+  /// completions cached.
+  bool IncludeBriefCommentsInCodeCompletion : 1;
+
+  /// \brief True if non-system source files should be treated as volatile
+  /// (likely to change while trying to use them).
+  bool UserFilesAreVolatile : 1;
+ 
+  /// \brief The language options used when we load an AST file.
+  LangOptions ASTFileLangOpts;
+
+  static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
+                             const char **ArgBegin, const char **ArgEnd,
+                             ASTUnit &AST, bool CaptureDiagnostics);
+
+  void TranslateStoredDiagnostics(FileManager &FileMgr,
+                                  SourceManager &SrcMan,
+                      const SmallVectorImpl<StandaloneDiagnostic> &Diags,
+                            SmallVectorImpl<StoredDiagnostic> &Out);
+
+  void clearFileLevelDecls();
+
+public:
+  /// \brief A cached code-completion result, which may be introduced in one of
+  /// many different contexts.
+  struct CachedCodeCompletionResult {
+    /// \brief The code-completion string corresponding to this completion
+    /// result.
+    CodeCompletionString *Completion;
+    
+    /// \brief A bitmask that indicates which code-completion contexts should
+    /// contain this completion result.
+    ///
+    /// The bits in the bitmask correspond to the values of
+    /// CodeCompleteContext::Kind. To map from a completion context kind to a
+    /// bit, shift 1 by that number of bits. Many completions can occur in
+    /// several different contexts.
+    uint64_t ShowInContexts;
+    
+    /// \brief The priority given to this code-completion result.
+    unsigned Priority;
+    
+    /// \brief The libclang cursor kind corresponding to this code-completion 
+    /// result.
+    CXCursorKind Kind;
+    
+    /// \brief The availability of this code-completion result.
+    CXAvailabilityKind Availability;
+    
+    /// \brief The simplified type class for a non-macro completion result.
+    SimplifiedTypeClass TypeClass;
+    
+    /// \brief The type of a non-macro completion result, stored as a unique
+    /// integer used by the string map of cached completion types.
+    ///
+    /// This value will be zero if the type is not known, or a unique value
+    /// determined by the formatted type string. Se \c CachedCompletionTypes
+    /// for more information.
+    unsigned Type;
+  };
+  
+  /// \brief Retrieve the mapping from formatted type names to unique type
+  /// identifiers.
+  llvm::StringMap<unsigned> &getCachedCompletionTypes() { 
+    return CachedCompletionTypes; 
+  }
+  
+  /// \brief Retrieve the allocator used to cache global code completions.
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
+  getCachedCompletionAllocator() {
+    return CachedCompletionAllocator;
+  }
+
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() {
+    if (!CCTUInfo)
+      CCTUInfo.reset(new CodeCompletionTUInfo(
+                                            new GlobalCodeCompletionAllocator));
+    return *CCTUInfo;
+  }
+
+private:
+  /// \brief Allocator used to store cached code completions.
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
+    CachedCompletionAllocator;
+
+  std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
+
+  /// \brief The set of cached code-completion results.
+  std::vector<CachedCodeCompletionResult> CachedCompletionResults;
+  
+  /// \brief A mapping from the formatted type name to a unique number for that
+  /// type, which is used for type equality comparisons.
+  llvm::StringMap<unsigned> CachedCompletionTypes;
+  
+  /// \brief A string hash of the top-level declaration and macro definition 
+  /// names processed the last time that we reparsed the file.
+  ///
+  /// This hash value is used to determine when we need to refresh the 
+  /// global code-completion cache.
+  unsigned CompletionCacheTopLevelHashValue;
+
+  /// \brief A string hash of the top-level declaration and macro definition 
+  /// names processed the last time that we reparsed the precompiled preamble.
+  ///
+  /// This hash value is used to determine when we need to refresh the 
+  /// global code-completion cache after a rebuild of the precompiled preamble.
+  unsigned PreambleTopLevelHashValue;
+
+  /// \brief The current hash value for the top-level declaration and macro
+  /// definition names
+  unsigned CurrentTopLevelHashValue;
+  
+  /// \brief Bit used by CIndex to mark when a translation unit may be in an
+  /// inconsistent state, and is not safe to free.
+  unsigned UnsafeToFree : 1;
+
+  /// \brief Cache any "global" code-completion results, so that we can avoid
+  /// recomputing them with each completion.
+  void CacheCodeCompletionResults();
+  
+  /// \brief Clear out and deallocate 
+  void ClearCachedCompletionResults();
+  
+  ASTUnit(const ASTUnit &) LLVM_DELETED_FUNCTION;
+  void operator=(const ASTUnit &) LLVM_DELETED_FUNCTION;
+  
+  explicit ASTUnit(bool MainFileIsAST);
+
+  void CleanTemporaryFiles();
+  bool Parse(llvm::MemoryBuffer *OverrideMainBuffer);
+  
+  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> >
+  ComputePreamble(CompilerInvocation &Invocation, 
+                  unsigned MaxLines, bool &CreatedBuffer);
+  
+  llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
+                               const CompilerInvocation &PreambleInvocationIn,
+                                                     bool AllowRebuild = true,
+                                                        unsigned MaxLines = 0);
+  void RealizeTopLevelDeclsFromPreamble();
+
+  /// \brief Transfers ownership of the objects (like SourceManager) from
+  /// \param CI to this ASTUnit.
+  void transferASTDataFromCompilerInstance(CompilerInstance &CI);
+
+  /// \brief Allows us to assert that ASTUnit is not being used concurrently,
+  /// which is not supported.
+  ///
+  /// Clients should create instances of the ConcurrencyCheck class whenever
+  /// using the ASTUnit in a way that isn't intended to be concurrent, which is
+  /// just about any usage.
+  /// Becomes a noop in release mode; only useful for debug mode checking.
+  class ConcurrencyState {
+    void *Mutex; // a llvm::sys::MutexImpl in debug;
+
+  public:
+    ConcurrencyState();
+    ~ConcurrencyState();
+
+    void start();
+    void finish();
+  };
+  ConcurrencyState ConcurrencyCheckValue;
+
+public:
+  class ConcurrencyCheck {
+    ASTUnit &Self;
+    
+  public:
+    explicit ConcurrencyCheck(ASTUnit &Self)
+      : Self(Self) 
+    { 
+      Self.ConcurrencyCheckValue.start();
+    }
+    ~ConcurrencyCheck() {
+      Self.ConcurrencyCheckValue.finish();
+    }
+  };
+  friend class ConcurrencyCheck;
+  
+  ~ASTUnit();
+
+  bool isMainFileAST() const { return MainFileIsAST; }
+
+  bool isUnsafeToFree() const { return UnsafeToFree; }
+  void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
+
+  const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
+  DiagnosticsEngine &getDiagnostics()             { return *Diagnostics; }
+  
+  const SourceManager &getSourceManager() const { return *SourceMgr; }
+        SourceManager &getSourceManager()       { return *SourceMgr; }
+
+  const Preprocessor &getPreprocessor() const { return *PP; }
+        Preprocessor &getPreprocessor()       { return *PP; }
+
+  const ASTContext &getASTContext() const { return *Ctx; }
+        ASTContext &getASTContext()       { return *Ctx; }
+
+  void setASTContext(ASTContext *ctx) { Ctx = ctx; }
+  void setPreprocessor(Preprocessor *pp);
+
+  bool hasSema() const { return (bool)TheSema; }
+  Sema &getSema() const { 
+    assert(TheSema && "ASTUnit does not have a Sema object!");
+    return *TheSema;
+  }
+
+  const LangOptions &getLangOpts() const {
+    assert(LangOpts && " ASTUnit does not have language options");
+    return *LangOpts;
+  }
+  
+  const FileManager &getFileManager() const { return *FileMgr; }
+        FileManager &getFileManager()       { return *FileMgr; }
+
+  const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
+
+  StringRef getOriginalSourceFileName() {
+    return OriginalSourceFile;
+  }
+
+  ASTMutationListener *getASTMutationListener();
+  ASTDeserializationListener *getDeserializationListener();
+
+  /// \brief Add a temporary file that the ASTUnit depends on.
+  ///
+  /// This file will be erased when the ASTUnit is destroyed.
+  void addTemporaryFile(StringRef TempFile);
+
+  bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+
+  bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
+  void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
+
+  StringRef getMainFileName() const;
+
+  /// \brief If this ASTUnit came from an AST file, returns the filename for it.
+  StringRef getASTFileName() const;
+
+  typedef std::vector<Decl *>::iterator top_level_iterator;
+
+  top_level_iterator top_level_begin() {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    if (!TopLevelDeclsInPreamble.empty())
+      RealizeTopLevelDeclsFromPreamble();
+    return TopLevelDecls.begin();
+  }
+
+  top_level_iterator top_level_end() {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    if (!TopLevelDeclsInPreamble.empty())
+      RealizeTopLevelDeclsFromPreamble();
+    return TopLevelDecls.end();
+  }
+
+  std::size_t top_level_size() const {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDeclsInPreamble.size() + TopLevelDecls.size();
+  }
+
+  bool top_level_empty() const {
+    assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+    return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty();
+  }
+
+  /// \brief Add a new top-level declaration.
+  void addTopLevelDecl(Decl *D) {
+    TopLevelDecls.push_back(D);
+  }
+
+  /// \brief Add a new local file-level declaration.
+  void addFileLevelDecl(Decl *D);
+
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \p Length can be 0 to indicate a point at \p Offset instead of
+  /// a range. 
+  void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls);
+
+  /// \brief Add a new top-level declaration, identified by its ID in
+  /// the precompiled preamble.
+  void addTopLevelDeclFromPreamble(serialization::DeclID D) {
+    TopLevelDeclsInPreamble.push_back(D);
+  }
+
+  /// \brief Retrieve a reference to the current top-level name hash value.
+  ///
+  /// Note: This is used internally by the top-level tracking action
+  unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; }
+
+  /// \brief Get the source location for the given file:line:col triplet.
+  ///
+  /// The difference with SourceManager::getLocation is that this method checks
+  /// whether the requested location points inside the precompiled preamble
+  /// in which case the returned source location will be a "loaded" one.
+  SourceLocation getLocation(const FileEntry *File,
+                             unsigned Line, unsigned Col) const;
+
+  /// \brief Get the source location for the given file:offset pair.
+  SourceLocation getLocation(const FileEntry *File, unsigned Offset) const;
+
+  /// \brief If \p Loc is a loaded location from the preamble, returns
+  /// the corresponding local location of the main file, otherwise it returns
+  /// \p Loc.
+  SourceLocation mapLocationFromPreamble(SourceLocation Loc);
+
+  /// \brief If \p Loc is a local location of the main file but inside the
+  /// preamble chunk, returns the corresponding loaded location from the
+  /// preamble, otherwise it returns \p Loc.
+  SourceLocation mapLocationToPreamble(SourceLocation Loc);
+
+  bool isInPreambleFileID(SourceLocation Loc);
+  bool isInMainFileID(SourceLocation Loc);
+  SourceLocation getStartOfMainFileID();
+  SourceLocation getEndOfPreambleFileID();
+
+  /// \see mapLocationFromPreamble.
+  SourceRange mapRangeFromPreamble(SourceRange R) {
+    return SourceRange(mapLocationFromPreamble(R.getBegin()),
+                       mapLocationFromPreamble(R.getEnd()));
+  }
+
+  /// \see mapLocationToPreamble.
+  SourceRange mapRangeToPreamble(SourceRange R) {
+    return SourceRange(mapLocationToPreamble(R.getBegin()),
+                       mapLocationToPreamble(R.getEnd()));
+  }
+  
+  // Retrieve the diagnostics associated with this AST
+  typedef StoredDiagnostic *stored_diag_iterator;
+  typedef const StoredDiagnostic *stored_diag_const_iterator;
+  stored_diag_const_iterator stored_diag_begin() const { 
+    return StoredDiagnostics.begin(); 
+  }
+  stored_diag_iterator stored_diag_begin() { 
+    return StoredDiagnostics.begin(); 
+  }
+  stored_diag_const_iterator stored_diag_end() const { 
+    return StoredDiagnostics.end(); 
+  }
+  stored_diag_iterator stored_diag_end() { 
+    return StoredDiagnostics.end(); 
+  }
+  unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
+
+  stored_diag_iterator stored_diag_afterDriver_begin() {
+    if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size())
+      NumStoredDiagnosticsFromDriver = 0;
+    return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver; 
+  }
+
+  typedef std::vector<CachedCodeCompletionResult>::iterator
+    cached_completion_iterator;
+  
+  cached_completion_iterator cached_completion_begin() {
+    return CachedCompletionResults.begin();
+  }
+
+  cached_completion_iterator cached_completion_end() {
+    return CachedCompletionResults.end();
+  }
+
+  unsigned cached_completion_size() const { 
+    return CachedCompletionResults.size(); 
+  }
+
+  /// \brief Returns an iterator range for the local preprocessing entities
+  /// of the local Preprocessor, if this is a parsed source file, or the loaded
+  /// preprocessing entities of the primary module if this is an AST file.
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    getLocalPreprocessingEntities() const;
+
+  /// \brief Type for a function iterating over a number of declarations.
+  /// \returns true to continue iteration and false to abort.
+  typedef bool (*DeclVisitorFn)(void *context, const Decl *D);
+
+  /// \brief Iterate over local declarations (locally parsed if this is a parsed
+  /// source file or the loaded declarations of the primary module if this is an
+  /// AST file).
+  /// \returns true if the iteration was complete or false if it was aborted.
+  bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
+
+  /// \brief Get the PCH file if one was included.
+  const FileEntry *getPCHFile();
+
+  /// \brief Returns true if the ASTUnit was constructed from a serialized
+  /// module file.
+  bool isModuleFile();
+
+  llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
+                                       std::string *ErrorStr = nullptr);
+
+  /// \brief Determine what kind of translation unit this AST represents.
+  TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
+
+  /// \brief A mapping from a file name to the memory buffer that stores the
+  /// remapped contents of that file.
+  typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
+
+  /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. 
+  static ASTUnit *create(CompilerInvocation *CI,
+                         IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+                         bool CaptureDiagnostics,
+                         bool UserFilesAreVolatile);
+
+  /// \brief Create a ASTUnit from an AST file.
+  ///
+  /// \param Filename - The AST file to load.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  ///
+  /// \returns - The initialized ASTUnit or null if the AST failed to load.
+  static ASTUnit *LoadFromASTFile(const std::string &Filename,
+                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+                                  const FileSystemOptions &FileSystemOpts,
+                                  bool OnlyLocalDecls = false,
+                                  ArrayRef<RemappedFile> RemappedFiles = None,
+                                  bool CaptureDiagnostics = false,
+                                  bool AllowPCHWithCompilerErrors = false,
+                                  bool UserFilesAreVolatile = false);
+
+private:
+  /// \brief Helper function for \c LoadFromCompilerInvocation() and
+  /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
+  ///
+  /// \param PrecompilePreamble Whether to precompile the preamble of this
+  /// translation unit, to improve the performance of reparsing.
+  ///
+  /// \returns \c true if a catastrophic failure occurred (which means that the
+  /// \c ASTUnit itself is invalid), or \c false otherwise.
+  bool LoadFromCompilerInvocation(bool PrecompilePreamble);
+  
+public:
+  
+  /// \brief Create an ASTUnit from a source file, via a CompilerInvocation
+  /// object, by invoking the optionally provided ASTFrontendAction. 
+  ///
+  /// \param CI - The compiler invocation to use; it must have exactly one input
+  /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  ///
+  /// \param Action - The ASTFrontendAction to invoke. Its ownership is not
+  /// transferred.
+  ///
+  /// \param Unit - optionally an already created ASTUnit. Its ownership is not
+  /// transferred.
+  ///
+  /// \param Persistent - if true the returned ASTUnit will be complete.
+  /// false means the caller is only interested in getting info through the
+  /// provided \see Action.
+  ///
+  /// \param ErrAST - If non-null and parsing failed without any AST to return
+  /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
+  /// mainly to allow the caller to see the diagnostics.
+  /// This will only receive an ASTUnit if a new one was created. If an already
+  /// created ASTUnit was passed in \p Unit then the caller can check that.
+  ///
+  static ASTUnit *LoadFromCompilerInvocationAction(
+      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
+      bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool UserFilesAreVolatile = false,
+      std::unique_ptr<ASTUnit> *ErrAST = nullptr);
+
+  /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
+  /// CompilerInvocation object.
+  ///
+  /// \param CI - The compiler invocation to use; it must have exactly one input
+  /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  //
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
+      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+      bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool UserFilesAreVolatile = false);
+
+  /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
+  /// arguments, which must specify exactly one source file.
+  ///
+  /// \param ArgBegin - The beginning of the argument vector.
+  ///
+  /// \param ArgEnd - The end of the argument vector.
+  ///
+  /// \param Diags - The diagnostics engine to use for reporting errors; its
+  /// lifetime is expected to extend past that of the returned ASTUnit.
+  ///
+  /// \param ResourceFilesPath - The path to the compiler resource files.
+  ///
+  /// \param ErrAST - If non-null and parsing failed without any AST to return
+  /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit
+  /// mainly to allow the caller to see the diagnostics.
+  ///
+  // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+  // shouldn't need to specify them at construction time.
+  static ASTUnit *LoadFromCommandLine(
+      const char **ArgBegin, const char **ArgEnd,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      ArrayRef<RemappedFile> RemappedFiles = None,
+      bool RemappedFilesKeepOriginalName = true,
+      bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+      bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
+      bool UserFilesAreVolatile = false, bool ForSerialization = false,
+      std::unique_ptr<ASTUnit> *ErrAST = nullptr);
+
+  /// \brief Reparse the source files using the same command-line options that
+  /// were originally used to produce this translation unit.
+  ///
+  /// \returns True if a failure occurred that causes the ASTUnit not to
+  /// contain any translation-unit information, false otherwise.  
+  bool Reparse(ArrayRef<RemappedFile> RemappedFiles = None);
+
+  /// \brief Perform code completion at the given file, line, and
+  /// column within this translation unit.
+  ///
+  /// \param File The file in which code completion will occur.
+  ///
+  /// \param Line The line at which code completion will occur.
+  ///
+  /// \param Column The column at which code completion will occur.
+  ///
+  /// \param IncludeMacros Whether to include macros in the code-completion 
+  /// results.
+  ///
+  /// \param IncludeCodePatterns Whether to include code patterns (such as a 
+  /// for loop) in the code-completion results.
+  ///
+  /// \param IncludeBriefComments Whether to include brief documentation within
+  /// the set of code completions returned.
+  ///
+  /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
+  /// OwnedBuffers parameters are all disgusting hacks. They will go away.
+  void CodeComplete(StringRef File, unsigned Line, unsigned Column,
+                    ArrayRef<RemappedFile> RemappedFiles,
+                    bool IncludeMacros, bool IncludeCodePatterns,
+                    bool IncludeBriefComments,
+                    CodeCompleteConsumer &Consumer,
+                    DiagnosticsEngine &Diag, LangOptions &LangOpts,
+                    SourceManager &SourceMgr, FileManager &FileMgr,
+                    SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+              SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
+
+  /// \brief Save this translation unit to a file with the given name.
+  ///
+  /// \returns true if there was a file error or false if the save was
+  /// successful.
+  bool Save(StringRef File);
+
+  /// \brief Serialize this translation unit with the given output stream.
+  ///
+  /// \returns True if an error occurred, false otherwise.
+  bool serialize(raw_ostream &OS);
+
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
+    // ASTUnit doesn't know how to load modules (not that this matters).
+    return ModuleLoadResult();
+  }
+
+  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc, bool Complain) override {}
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
new file mode 100644
index 0000000..11762a9
--- /dev/null
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -0,0 +1,67 @@
+//===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
+#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include <memory>
+
+namespace clang {
+class LangOptions;
+
+/// ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics
+/// go to the first client and then the second. The first diagnostic client
+/// should be the "primary" client, and will be used for computing whether the
+/// diagnostics should be included in counts.
+class ChainedDiagnosticConsumer : public DiagnosticConsumer {
+  virtual void anchor();
+  std::unique_ptr<DiagnosticConsumer> Primary;
+  std::unique_ptr<DiagnosticConsumer> Secondary;
+
+public:
+  ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary,
+                          DiagnosticConsumer *_Secondary) {
+    Primary.reset(_Primary);
+    Secondary.reset(_Secondary);
+  }
+
+  void BeginSourceFile(const LangOptions &LO,
+                       const Preprocessor *PP) override {
+    Primary->BeginSourceFile(LO, PP);
+    Secondary->BeginSourceFile(LO, PP);
+  }
+
+  void EndSourceFile() override {
+    Secondary->EndSourceFile();
+    Primary->EndSourceFile();
+  }
+
+  void finish() override {
+    Secondary->finish();
+    Primary->finish();
+  }
+
+  bool IncludeInDiagnosticCounts() const override {
+    return Primary->IncludeInDiagnosticCounts();
+  }
+
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override {
+    // Default implementation (Warnings/errors count).
+    DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+
+    Primary->HandleDiagnostic(DiagLevel, Info);
+    Secondary->HandleDiagnostic(DiagLevel, Info);
+  }
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
new file mode 100644
index 0000000..1d92efe
--- /dev/null
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -0,0 +1,160 @@
+//===--- CodeGenOptions.def - Code generation option database ------ 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 code generation options. Users of this file
+// must define the CODEGENOPT macro to make use of this information.
+// Optionally, the user may also define ENUM_CODEGENOPT (for options
+// that have enumeration type and VALUE_CODEGENOPT is a code
+// generation option that describes a value rather than a flag.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CODEGENOPT
+#  error Define the CODEGENOPT macro to handle language options
+#endif
+
+#ifndef VALUE_CODEGENOPT
+#  define VALUE_CODEGENOPT(Name, Bits, Default) \
+CODEGENOPT(Name, Bits, Default)
+#endif
+
+#ifndef ENUM_CODEGENOPT
+#  define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+CODEGENOPT(Name, Bits, Default)
+#endif
+
+CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
+CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections
+CODEGENOPT(Autolink          , 1, 1) ///< -fno-autolink
+CODEGENOPT(AsmVerbose        , 1, 0) ///< -dA, -fverbose-asm.
+CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
+CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
+CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
+CODEGENOPT(CUDAIsDevice      , 1, 0) ///< Set when compiling for CUDA device.
+CODEGENOPT(CXAAtExit         , 1, 1) ///< Use __cxa_atexit for calling destructors.
+CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
+                                     ///< aliases to base ctors when possible.
+CODEGENOPT(DataSections      , 1, 0) ///< Set when -fdata-sections is enabled.
+CODEGENOPT(DisableFPElim     , 1, 0) ///< Set when -fomit-frame-pointer is enabled.
+CODEGENOPT(DisableFree       , 1, 0) ///< Don't free memory.
+CODEGENOPT(DisableGCov       , 1, 0) ///< Don't run the GCov pass, for testing.
+CODEGENOPT(DisableLLVMOpts   , 1, 0) ///< Don't run any optimizations, for use in
+                                     ///< getting .bc files that correspond to the
+                                     ///< internal state before optimizations are
+                                     ///< done.
+CODEGENOPT(DisableRedZone    , 1, 0) ///< Set when -mno-red-zone is enabled.
+CODEGENOPT(DisableTailCalls  , 1, 0) ///< Do not emit tail calls.
+CODEGENOPT(EmitDeclMetadata  , 1, 0) ///< Emit special metadata indicating what
+                                     ///< Decl* various IR entities came from. 
+                                     ///< Only useful when running CodeGen as a
+                                     ///< subroutine.
+CODEGENOPT(EmitGcovArcs      , 1, 0) ///< Emit coverage data files, aka. GCDA.
+CODEGENOPT(EmitGcovNotes     , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
+CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
+/// \brief FP_CONTRACT mode (on/off/fast).
+ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
+CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
+                                        ///< are required.
+CODEGENOPT(FunctionSections  , 1, 0) ///< Set when -ffunction-sections is enabled.
+CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
+                                       ///< enabled.
+CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
+CODEGENOPT(LessPreciseFPMAD  , 1, 0) ///< Enable less precise MAD instructions to
+                                     ///< be generated.
+CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
+CODEGENOPT(NoCommon          , 1, 0) ///< Set when -fno-common or C++ is enabled.
+CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
+                                       ///< enabled.
+CODEGENOPT(NoExecStack       , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
+CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
+CODEGENOPT(NoGlobalMerge     , 1, 0) ///< Set when -mno-global-merge is enabled.
+CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when -mno-implicit-float is enabled.
+CODEGENOPT(NoInfsFPMath      , 1, 0) ///< Assume FP arguments, results not +-Inf.
+CODEGENOPT(NoInline          , 1, 0) ///< Set when -fno-inline is enabled. 
+                                     ///< Disables use of the inline keyword.
+CODEGENOPT(NoNaNsFPMath      , 1, 0) ///< Assume FP arguments, results not NaN.
+CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
+/// \brief Method of Objective-C dispatch to use.
+ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy) 
+CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
+                                        ///< enabled.
+VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
+VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
+
+CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
+                                        ///< execution counts to use with PGO.
+
+  /// If -fpcc-struct-return or -freg-struct-return is specified.
+ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
+
+CODEGENOPT(RelaxAll          , 1, 0) ///< Relax all machine code instructions.
+CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is enabled.
+CODEGENOPT(StructPathTBAA    , 1, 0) ///< Whether or not to use struct-path TBAA.
+CODEGENOPT(SaveTempLabels    , 1, 0) ///< Save temporary labels.
+CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
+                                                 ///< offset in AddressSanitizer.
+CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
+                                             ///< MemorySanitizer
+CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
+                                               /// -fsanitize-undefined-trap-on-error
+CODEGENOPT(SimplifyLibCalls  , 1, 1) ///< Set when -fbuiltin is enabled.
+CODEGENOPT(SoftFloat         , 1, 0) ///< -soft-float.
+CODEGENOPT(StrictEnums       , 1, 0) ///< Optimize based on strict enum definition.
+CODEGENOPT(TimePasses        , 1, 0) ///< Set when -ftime-report is enabled.
+CODEGENOPT(UnitAtATime       , 1, 1) ///< Unused. For mirroring GCC optimization
+                                     ///< selection.
+CODEGENOPT(UnrollLoops       , 1, 0) ///< Control whether loops are unrolled.
+CODEGENOPT(RerollLoops       , 1, 0) ///< Control whether loops are rerolled.
+CODEGENOPT(UnsafeFPMath      , 1, 0) ///< Allow unsafe floating point optzns.
+CODEGENOPT(UnwindTables      , 1, 0) ///< Emit unwind tables.
+CODEGENOPT(VectorizeBB       , 1, 0) ///< Run basic block vectorizer.
+CODEGENOPT(VectorizeLoop     , 1, 0) ///< Run loop vectorizer.
+CODEGENOPT(VectorizeSLP      , 1, 0) ///< Run SLP vectorizer.
+
+  /// Attempt to use register sized accesses to bit-fields in structures, when
+  /// possible.
+CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)
+
+CODEGENOPT(VerifyModule      , 1, 1) ///< Control whether the module should be run
+                                     ///< through the LLVM Verifier.
+
+CODEGENOPT(StackRealignment  , 1, 0) ///< Control whether to permit stack
+                                     ///< realignment.
+CODEGENOPT(UseInitArray      , 1, 0) ///< Control whether to use .init_array or
+                                     ///< .ctors.
+VALUE_CODEGENOPT(StackAlignment    , 32, 0) ///< Overrides default stack 
+                                            ///< alignment, if not 0.
+CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
+                                  ///< in debug info.
+
+/// The user specified number of registers to be used for integral arguments,
+/// or 0 if unspecified.
+VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
+
+/// The lower bound for a buffer to be considered for stack protection.
+VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
+
+/// The kind of generated debug info.
+ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo)
+
+/// Dwarf version.
+VALUE_CODEGENOPT(DwarfVersion, 3, 0)
+
+/// The kind of inlining to perform.
+ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining)
+
+/// The default TLS model to use.
+ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
+
+CODEGENOPT(SanitizeRecover, 1, 1) ///< Attempt to recover from sanitizer checks
+                                  ///< by continuing execution when possible
+
+#undef CODEGENOPT
+#undef ENUM_CODEGENOPT
+#undef VALUE_CODEGENOPT
+
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
new file mode 100644
index 0000000..3d532ce
--- /dev/null
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -0,0 +1,199 @@
+//===--- CodeGenOptions.h ---------------------------------------*- 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 CodeGenOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
+#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H
+
+#include <string>
+#include <vector>
+#include "llvm/Support/Regex.h"
+
+namespace clang {
+
+/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
+/// that this large collection of bitfields is a trivial class type.
+class CodeGenOptionsBase {
+public:
+#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
+#include "clang/Frontend/CodeGenOptions.def"
+
+protected:
+#define CODEGENOPT(Name, Bits, Default)
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits;
+#include "clang/Frontend/CodeGenOptions.def"
+};
+
+/// CodeGenOptions - Track various options which control how the code
+/// is optimized and passed to the backend.
+class CodeGenOptions : public CodeGenOptionsBase {
+public:
+  enum InliningMethod {
+    NoInlining,         // Perform no inlining whatsoever.
+    NormalInlining,     // Use the standard function inlining pass.
+    OnlyAlwaysInlining  // Only run the always inlining pass.
+  };
+
+  enum ObjCDispatchMethodKind {
+    Legacy = 0,
+    NonLegacy = 1,
+    Mixed = 2
+  };
+
+  enum DebugInfoKind {
+    NoDebugInfo,          /// Don't generate debug info.
+
+    LocTrackingOnly,      /// Emit location information but do not generate
+                          /// debug info in the output. This is useful in
+                          /// cases where the backend wants to track source
+                          /// locations for instructions without actually
+                          /// emitting debug info for them (e.g., when -Rpass
+                          /// is used).
+
+    DebugLineTablesOnly,  /// Emit only debug info necessary for generating
+                          /// line number tables (-gline-tables-only).
+
+    LimitedDebugInfo,     /// Limit generated debug info to reduce size
+                          /// (-fno-standalone-debug). This emits
+                          /// forward decls for types that could be
+                          /// replaced with forward decls in the source
+                          /// code. For dynamic C++ classes type info
+                          /// is only emitted int the module that
+                          /// contains the classe's vtable.
+
+    FullDebugInfo         /// Generate complete debug info.
+  };
+
+  enum TLSModel {
+    GeneralDynamicTLSModel,
+    LocalDynamicTLSModel,
+    InitialExecTLSModel,
+    LocalExecTLSModel
+  };
+
+  enum FPContractModeKind {
+    FPC_Off,        // Form fused FP ops only where result will not be affected.
+    FPC_On,         // Form fused FP ops according to FP_CONTRACT rules.
+    FPC_Fast        // Aggressively fuse FP ops (E.g. FMA).
+  };
+
+  enum StructReturnConventionKind {
+    SRCK_Default,  // No special option was passed.
+    SRCK_OnStack,  // Small structs on the stack (-fpcc-struct-return).
+    SRCK_InRegs    // Small structs in registers (-freg-struct-return).
+  };
+
+  /// The code model to use (-mcmodel).
+  std::string CodeModel;
+
+  /// The filename with path we use for coverage files. The extension will be
+  /// replaced.
+  std::string CoverageFile;
+
+  /// The version string to put into coverage files.
+  char CoverageVersion[4];
+
+  /// Enable additional debugging information.
+  std::string DebugPass;
+
+  /// The string to embed in debug information as the current working directory.
+  std::string DebugCompilationDir;
+
+  /// The string to embed in the debug information for the compile unit, if
+  /// non-empty.
+  std::string DwarfDebugFlags;
+
+  /// The ABI to use for passing floating point arguments.
+  std::string FloatABI;
+
+  /// The float precision limit to use, if non-empty.
+  std::string LimitFloatPrecision;
+
+  /// The name of the bitcode file to link before optzns.
+  std::string LinkBitcodeFile;
+
+  /// The user provided name for the "main file", if non-empty. This is useful
+  /// in situations where the input file name does not match the original input
+  /// file, for example with -save-temps.
+  std::string MainFileName;
+
+  /// The name for the split debug info file that we'll break out. This is used
+  /// in the backend for setting the name in the skeleton cu.
+  std::string SplitDwarfFile;
+
+  /// The name of the relocation model to use.
+  std::string RelocationModel;
+
+  /// Path to blacklist file for sanitizers.
+  std::string SanitizerBlacklistFile;
+
+  /// If not an empty string, trap intrinsics are lowered to calls to this
+  /// function instead of to trap instructions.
+  std::string TrapFuncName;
+
+  /// A list of command-line options to forward to the LLVM backend.
+  std::vector<std::string> BackendOptions;
+
+  /// A list of dependent libraries.
+  std::vector<std::string> DependentLibraries;
+
+  /// Name of the profile file to use with -fprofile-sample-use.
+  std::string SampleProfileFile;
+
+  /// Name of the profile file to use as input for -fprofile-instr-use
+  std::string InstrProfileInput;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// optimization remarks. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they perform a transformation. This is enabled by the
+  /// -Rpass=regexp flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkPattern;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// missed optimization remarks. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they tried but failed to perform a transformation. This is
+  /// enabled by the -Rpass-missed=regexp flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkMissedPattern;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// optimization analyses. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they want to explain why they decided to apply or not apply
+  /// a given transformation. This is enabled by the -Rpass-analysis=regexp
+  /// flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern;
+
+public:
+  // Define accessors/mutators for code generation options of enumeration type.
+#define CODEGENOPT(Name, Bits, Default)
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+  Type get##Name() const { return static_cast<Type>(Name); } \
+  void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
+#include "clang/Frontend/CodeGenOptions.def"
+
+  CodeGenOptions() {
+#define CODEGENOPT(Name, Bits, Default) Name = Default;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
+  set##Name(Default);
+#include "clang/Frontend/CodeGenOptions.def"
+
+    RelocationModel = "pic";
+    memcpy(CoverageVersion, "402*", 4);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
new file mode 100644
index 0000000..c01f91d
--- /dev/null
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -0,0 +1,87 @@
+
+//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line parsing for source locations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
+#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+/// \brief A source location that has been parsed on the command line.
+struct ParsedSourceLocation {
+  std::string FileName;
+  unsigned Line;
+  unsigned Column;
+
+public:
+  /// Construct a parsed source location from a string; the Filename is empty on
+  /// error.
+  static ParsedSourceLocation FromString(StringRef Str) {
+    ParsedSourceLocation PSL;
+    std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
+    std::pair<StringRef, StringRef> LineSplit =
+      ColSplit.first.rsplit(':');
+
+    // If both tail splits were valid integers, return success.
+    if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
+        !LineSplit.second.getAsInteger(10, PSL.Line)) {
+      PSL.FileName = LineSplit.first;
+
+      // On the command-line, stdin may be specified via "-". Inside the
+      // compiler, stdin is called "<stdin>".
+      if (PSL.FileName == "-")
+        PSL.FileName = "<stdin>";
+    }
+
+    return PSL;
+  }
+};
+
+}
+
+namespace llvm {
+  namespace cl {
+    /// \brief Command-line option parser that parses source locations.
+    ///
+    /// Source locations are of the form filename:line:column.
+    template<>
+    class parser<clang::ParsedSourceLocation>
+      : public basic_parser<clang::ParsedSourceLocation> {
+    public:
+      inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
+                 clang::ParsedSourceLocation &Val);
+    };
+
+    bool
+    parser<clang::ParsedSourceLocation>::
+    parse(Option &O, StringRef ArgName, StringRef ArgValue,
+          clang::ParsedSourceLocation &Val) {
+      using namespace clang;
+
+      Val = ParsedSourceLocation::FromString(ArgValue);
+      if (Val.FileName.empty()) {
+        errs() << "error: "
+               << "source location must be of the form filename:line:column\n";
+        return true;
+      }
+
+      return false;
+    }
+  }
+}
+
+#endif
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
new file mode 100644
index 0000000..44e9102
--- /dev/null
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -0,0 +1,724 @@
+//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Lex/ModuleLoader.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <list>
+#include <memory>
+#include <string>
+#include <utility>
+
+namespace llvm {
+class raw_fd_ostream;
+class Timer;
+}
+
+namespace clang {
+class ASTContext;
+class ASTConsumer;
+class ASTReader;
+class CodeCompleteConsumer;
+class DiagnosticsEngine;
+class DiagnosticConsumer;
+class ExternalASTSource;
+class FileEntry;
+class FileManager;
+class FrontendAction;
+class Module;
+class Preprocessor;
+class Sema;
+class SourceManager;
+class TargetInfo;
+
+/// CompilerInstance - Helper class for managing a single instance of the Clang
+/// compiler.
+///
+/// The CompilerInstance serves two purposes:
+///  (1) It manages the various objects which are necessary to run the compiler,
+///      for example the preprocessor, the target information, and the AST
+///      context.
+///  (2) It provides utility routines for constructing and manipulating the
+///      common Clang objects.
+///
+/// The compiler instance generally owns the instance of all the objects that it
+/// manages. However, clients can still share objects by manually setting the
+/// object and retaking ownership prior to destroying the CompilerInstance.
+///
+/// The compiler instance is intended to simplify clients, but not to lock them
+/// in to the compiler instance for everything. When possible, utility functions
+/// come in two forms; a short form that reuses the CompilerInstance objects,
+/// and a long form that takes explicit instances of any required objects.
+class CompilerInstance : public ModuleLoader {
+  /// The options used in this compiler instance.
+  IntrusiveRefCntPtr<CompilerInvocation> Invocation;
+
+  /// The diagnostics engine instance.
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
+
+  /// The target being compiled for.
+  IntrusiveRefCntPtr<TargetInfo> Target;
+
+  /// The virtual file system.
+  IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
+
+  /// The file manager.
+  IntrusiveRefCntPtr<FileManager> FileMgr;
+
+  /// The source manager.
+  IntrusiveRefCntPtr<SourceManager> SourceMgr;
+
+  /// The preprocessor.
+  IntrusiveRefCntPtr<Preprocessor> PP;
+
+  /// The AST context.
+  IntrusiveRefCntPtr<ASTContext> Context;
+
+  /// The AST consumer.
+  std::unique_ptr<ASTConsumer> Consumer;
+
+  /// The code completion consumer.
+  std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
+
+  /// \brief The semantic analysis object.
+  std::unique_ptr<Sema> TheSema;
+
+  /// \brief The frontend timer
+  std::unique_ptr<llvm::Timer> FrontendTimer;
+
+  /// \brief The ASTReader, if one exists.
+  IntrusiveRefCntPtr<ASTReader> ModuleManager;
+
+  /// \brief The module dependency collector for crashdumps
+  std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
+
+  /// \brief The dependency file generator.
+  std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
+
+  std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
+
+  /// \brief The set of top-level modules that has already been loaded,
+  /// along with the module map
+  llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
+  
+  /// \brief The location of the module-import keyword for the last module
+  /// import. 
+  SourceLocation LastModuleImportLoc;
+  
+  /// \brief The result of the last module import.
+  ///
+  ModuleLoadResult LastModuleImportResult;
+
+  /// \brief Whether we should (re)build the global module index once we
+  /// have finished with this translation unit.
+  bool BuildGlobalModuleIndex;
+
+  /// \brief We have a full global module index, with all modules.
+  bool HaveFullGlobalModuleIndex;
+
+  /// \brief One or more modules failed to build.
+  bool ModuleBuildFailed;
+
+  /// \brief Holds information about the output file.
+  ///
+  /// If TempFilename is not empty we must rename it to Filename at the end.
+  /// TempFilename may be empty and Filename non-empty if creating the temporary
+  /// failed.
+  struct OutputFile {
+    std::string Filename;
+    std::string TempFilename;
+    raw_ostream *OS;
+
+    OutputFile(const std::string &filename, const std::string &tempFilename,
+               raw_ostream *os)
+      : Filename(filename), TempFilename(tempFilename), OS(os) { }
+  };
+
+  /// The list of active output files.
+  std::list<OutputFile> OutputFiles;
+
+  CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION;
+  void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION;
+public:
+  explicit CompilerInstance(bool BuildingModule = false);
+  ~CompilerInstance();
+
+  /// @name High-Level Operations
+  /// {
+
+  /// ExecuteAction - Execute the provided action against the compiler's
+  /// CompilerInvocation object.
+  ///
+  /// This function makes the following assumptions:
+  ///
+  ///  - The invocation options should be initialized. This function does not
+  ///    handle the '-help' or '-version' options, clients should handle those
+  ///    directly.
+  ///
+  ///  - The diagnostics engine should have already been created by the client.
+  ///
+  ///  - No other CompilerInstance state should have been initialized (this is
+  ///    an unchecked error).
+  ///
+  ///  - Clients should have initialized any LLVM target features that may be
+  ///    required.
+  ///
+  ///  - Clients should eventually call llvm_shutdown() upon the completion of
+  ///    this routine to ensure that any managed objects are properly destroyed.
+  ///
+  /// Note that this routine may write output to 'stderr'.
+  ///
+  /// \param Act - The action to execute.
+  /// \return - True on success.
+  //
+  // FIXME: This function should take the stream to write any debugging /
+  // verbose output to as an argument.
+  //
+  // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
+  // of the context or else not CompilerInstance specific.
+  bool ExecuteAction(FrontendAction &Act);
+
+  /// }
+  /// @name Compiler Invocation and Options
+  /// {
+
+  bool hasInvocation() const { return Invocation != nullptr; }
+
+  CompilerInvocation &getInvocation() {
+    assert(Invocation && "Compiler instance has no invocation!");
+    return *Invocation;
+  }
+
+  /// setInvocation - Replace the current invocation.
+  void setInvocation(CompilerInvocation *Value);
+
+  /// \brief Indicates whether we should (re)build the global module index.
+  bool shouldBuildGlobalModuleIndex() const;
+  
+  /// \brief Set the flag indicating whether we should (re)build the global
+  /// module index.
+  void setBuildGlobalModuleIndex(bool Build) {
+    BuildGlobalModuleIndex = Build;
+  }
+
+  /// }
+  /// @name Forwarding Methods
+  /// {
+
+  AnalyzerOptionsRef getAnalyzerOpts() {
+    return Invocation->getAnalyzerOpts();
+  }
+
+  CodeGenOptions &getCodeGenOpts() {
+    return Invocation->getCodeGenOpts();
+  }
+  const CodeGenOptions &getCodeGenOpts() const {
+    return Invocation->getCodeGenOpts();
+  }
+
+  DependencyOutputOptions &getDependencyOutputOpts() {
+    return Invocation->getDependencyOutputOpts();
+  }
+  const DependencyOutputOptions &getDependencyOutputOpts() const {
+    return Invocation->getDependencyOutputOpts();
+  }
+
+  DiagnosticOptions &getDiagnosticOpts() {
+    return Invocation->getDiagnosticOpts();
+  }
+  const DiagnosticOptions &getDiagnosticOpts() const {
+    return Invocation->getDiagnosticOpts();
+  }
+
+  const FileSystemOptions &getFileSystemOpts() const {
+    return Invocation->getFileSystemOpts();
+  }
+
+  FrontendOptions &getFrontendOpts() {
+    return Invocation->getFrontendOpts();
+  }
+  const FrontendOptions &getFrontendOpts() const {
+    return Invocation->getFrontendOpts();
+  }
+
+  HeaderSearchOptions &getHeaderSearchOpts() {
+    return Invocation->getHeaderSearchOpts();
+  }
+  const HeaderSearchOptions &getHeaderSearchOpts() const {
+    return Invocation->getHeaderSearchOpts();
+  }
+
+  LangOptions &getLangOpts() {
+    return *Invocation->getLangOpts();
+  }
+  const LangOptions &getLangOpts() const {
+    return *Invocation->getLangOpts();
+  }
+
+  PreprocessorOptions &getPreprocessorOpts() {
+    return Invocation->getPreprocessorOpts();
+  }
+  const PreprocessorOptions &getPreprocessorOpts() const {
+    return Invocation->getPreprocessorOpts();
+  }
+
+  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+    return Invocation->getPreprocessorOutputOpts();
+  }
+  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+    return Invocation->getPreprocessorOutputOpts();
+  }
+
+  TargetOptions &getTargetOpts() {
+    return Invocation->getTargetOpts();
+  }
+  const TargetOptions &getTargetOpts() const {
+    return Invocation->getTargetOpts();
+  }
+
+  /// }
+  /// @name Diagnostics Engine
+  /// {
+
+  bool hasDiagnostics() const { return Diagnostics != nullptr; }
+
+  /// Get the current diagnostics engine.
+  DiagnosticsEngine &getDiagnostics() const {
+    assert(Diagnostics && "Compiler instance has no diagnostics!");
+    return *Diagnostics;
+  }
+
+  /// setDiagnostics - Replace the current diagnostics engine.
+  void setDiagnostics(DiagnosticsEngine *Value);
+
+  DiagnosticConsumer &getDiagnosticClient() const {
+    assert(Diagnostics && Diagnostics->getClient() && 
+           "Compiler instance has no diagnostic client!");
+    return *Diagnostics->getClient();
+  }
+
+  /// }
+  /// @name Target Info
+  /// {
+
+  bool hasTarget() const { return Target != nullptr; }
+
+  TargetInfo &getTarget() const {
+    assert(Target && "Compiler instance has no target!");
+    return *Target;
+  }
+
+  /// Replace the current diagnostics engine.
+  void setTarget(TargetInfo *Value);
+
+  /// }
+  /// @name Virtual File System
+  /// {
+
+  bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
+
+  vfs::FileSystem &getVirtualFileSystem() const {
+    assert(hasVirtualFileSystem() &&
+           "Compiler instance has no virtual file system");
+    return *VirtualFileSystem;
+  }
+
+  /// \brief Replace the current virtual file system.
+  ///
+  /// \note Most clients should use setFileManager, which will implicitly reset
+  /// the virtual file system to the one contained in the file manager.
+  void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+    VirtualFileSystem = FS;
+  }
+
+  /// }
+  /// @name File Manager
+  /// {
+
+  bool hasFileManager() const { return FileMgr != nullptr; }
+
+  /// Return the current file manager to the caller.
+  FileManager &getFileManager() const {
+    assert(FileMgr && "Compiler instance has no file manager!");
+    return *FileMgr;
+  }
+  
+  void resetAndLeakFileManager() {
+    BuryPointer(FileMgr.get());
+    FileMgr.resetWithoutRelease();
+  }
+
+  /// \brief Replace the current file manager and virtual file system.
+  void setFileManager(FileManager *Value);
+
+  /// }
+  /// @name Source Manager
+  /// {
+
+  bool hasSourceManager() const { return SourceMgr != nullptr; }
+
+  /// Return the current source manager.
+  SourceManager &getSourceManager() const {
+    assert(SourceMgr && "Compiler instance has no source manager!");
+    return *SourceMgr;
+  }
+  
+  void resetAndLeakSourceManager() {
+    BuryPointer(SourceMgr.get());
+    SourceMgr.resetWithoutRelease();
+  }
+
+  /// setSourceManager - Replace the current source manager.
+  void setSourceManager(SourceManager *Value);
+
+  /// }
+  /// @name Preprocessor
+  /// {
+
+  bool hasPreprocessor() const { return PP != nullptr; }
+
+  /// Return the current preprocessor.
+  Preprocessor &getPreprocessor() const {
+    assert(PP && "Compiler instance has no preprocessor!");
+    return *PP;
+  }
+
+  void resetAndLeakPreprocessor() {
+    BuryPointer(PP.get());
+    PP.resetWithoutRelease();
+  }
+
+  /// Replace the current preprocessor.
+  void setPreprocessor(Preprocessor *Value);
+
+  /// }
+  /// @name ASTContext
+  /// {
+
+  bool hasASTContext() const { return Context != nullptr; }
+
+  ASTContext &getASTContext() const {
+    assert(Context && "Compiler instance has no AST context!");
+    return *Context;
+  }
+  
+  void resetAndLeakASTContext() {
+    BuryPointer(Context.get());
+    Context.resetWithoutRelease();
+  }
+
+  /// setASTContext - Replace the current AST context.
+  void setASTContext(ASTContext *Value);
+
+  /// \brief Replace the current Sema; the compiler instance takes ownership
+  /// of S.
+  void setSema(Sema *S);
+  
+  /// }
+  /// @name ASTConsumer
+  /// {
+
+  bool hasASTConsumer() const { return (bool)Consumer; }
+
+  ASTConsumer &getASTConsumer() const {
+    assert(Consumer && "Compiler instance has no AST consumer!");
+    return *Consumer;
+  }
+
+  /// takeASTConsumer - Remove the current AST consumer and give ownership to
+  /// the caller.
+  ASTConsumer *takeASTConsumer() { return Consumer.release(); }
+
+  /// setASTConsumer - Replace the current AST consumer; the compiler instance
+  /// takes ownership of \p Value.
+  void setASTConsumer(ASTConsumer *Value);
+
+  /// }
+  /// @name Semantic analysis
+  /// {
+  bool hasSema() const { return (bool)TheSema; }
+
+  Sema &getSema() const { 
+    assert(TheSema && "Compiler instance has no Sema object!");
+    return *TheSema;
+  }
+
+  Sema *takeSema() { return TheSema.release(); }
+  void resetAndLeakSema() { BuryPointer(TheSema.release()); }
+
+  /// }
+  /// @name Module Management
+  /// {
+
+  IntrusiveRefCntPtr<ASTReader> getModuleManager() const;
+  void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
+
+  std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
+  void setModuleDepCollector(
+      std::shared_ptr<ModuleDependencyCollector> Collector);
+
+  /// }
+  /// @name Code Completion
+  /// {
+
+  bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
+
+  CodeCompleteConsumer &getCodeCompletionConsumer() const {
+    assert(CompletionConsumer &&
+           "Compiler instance has no code completion consumer!");
+    return *CompletionConsumer;
+  }
+
+  /// takeCodeCompletionConsumer - Remove the current code completion consumer
+  /// and give ownership to the caller.
+  CodeCompleteConsumer *takeCodeCompletionConsumer() {
+    return CompletionConsumer.release();
+  }
+
+  /// setCodeCompletionConsumer - Replace the current code completion consumer;
+  /// the compiler instance takes ownership of \p Value.
+  void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
+
+  /// }
+  /// @name Frontend timer
+  /// {
+
+  bool hasFrontendTimer() const { return (bool)FrontendTimer; }
+
+  llvm::Timer &getFrontendTimer() const {
+    assert(FrontendTimer && "Compiler instance has no frontend timer!");
+    return *FrontendTimer;
+  }
+
+  /// }
+  /// @name Output Files
+  /// {
+
+  /// addOutputFile - Add an output file onto the list of tracked output files.
+  ///
+  /// \param OutFile - The output file info.
+  void addOutputFile(const OutputFile &OutFile);
+
+  /// clearOutputFiles - Clear the output file list, destroying the contained
+  /// output streams.
+  ///
+  /// \param EraseFiles - If true, attempt to erase the files from disk.
+  void clearOutputFiles(bool EraseFiles);
+
+  /// }
+  /// @name Construction Utility Methods
+  /// {
+
+  /// Create the diagnostics engine using the invocation's diagnostic options
+  /// and replace any existing one with it.
+  ///
+  /// Note that this routine also replaces the diagnostic client,
+  /// allocating one if one is not provided.
+  ///
+  /// \param Client If non-NULL, a diagnostic client that will be
+  /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
+  /// unit.
+  ///
+  /// \param ShouldOwnClient If Client is non-NULL, specifies whether 
+  /// the diagnostic object should take ownership of the client.
+  void createDiagnostics(DiagnosticConsumer *Client = nullptr,
+                         bool ShouldOwnClient = true);
+
+  /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
+  ///
+  /// If no diagnostic client is provided, this creates a
+  /// DiagnosticConsumer that is owned by the returned diagnostic
+  /// object, if using directly the caller is responsible for
+  /// releasing the returned DiagnosticsEngine's client eventually.
+  ///
+  /// \param Opts - The diagnostic options; note that the created text
+  /// diagnostic object contains a reference to these options.
+  ///
+  /// \param Client If non-NULL, a diagnostic client that will be
+  /// attached to (and, then, owned by) the returned DiagnosticsEngine
+  /// object.
+  ///
+  /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
+  /// used by some diagnostics printers (for logging purposes only).
+  ///
+  /// \return The new object on success, or null on failure.
+  static IntrusiveRefCntPtr<DiagnosticsEngine>
+  createDiagnostics(DiagnosticOptions *Opts,
+                    DiagnosticConsumer *Client = nullptr,
+                    bool ShouldOwnClient = true,
+                    const CodeGenOptions *CodeGenOpts = nullptr);
+
+  /// Create the file manager and replace any existing one with it.
+  void createFileManager();
+
+  /// Create the source manager and replace any existing one with it.
+  void createSourceManager(FileManager &FileMgr);
+
+  /// Create the preprocessor, using the invocation, file, and source managers,
+  /// and replace any existing one with it.
+  void createPreprocessor(TranslationUnitKind TUKind);
+
+  /// Create the AST context.
+  void createASTContext();
+
+  /// Create an external AST source to read a PCH file and attach it to the AST
+  /// context.
+  void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
+                                  bool AllowPCHWithCompilerErrors,
+                                  void *DeserializationListener,
+                                  bool OwnDeserializationListener);
+
+  /// Create an external AST source to read a PCH file.
+  ///
+  /// \return - The new object on success, or null on failure.
+  static ExternalASTSource *createPCHExternalASTSource(
+      StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
+      bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+      void *DeserializationListener, bool OwnDeserializationListener,
+      bool Preamble, bool UseGlobalModuleIndex);
+
+  /// Create a code completion consumer using the invocation; note that this
+  /// will cause the source manager to truncate the input source file at the
+  /// completion point.
+  void createCodeCompletionConsumer();
+
+  /// Create a code completion consumer to print code completion results, at
+  /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
+  static CodeCompleteConsumer *
+  createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
+                               unsigned Line, unsigned Column,
+                               const CodeCompleteOptions &Opts,
+                               raw_ostream &OS);
+
+  /// \brief Create the Sema object to be used for parsing.
+  void createSema(TranslationUnitKind TUKind,
+                  CodeCompleteConsumer *CompletionConsumer);
+  
+  /// Create the frontend timer and replace any existing one with it.
+  void createFrontendTimer();
+
+  /// Create the default output file (from the invocation's options) and add it
+  /// to the list of tracked output files.
+  ///
+  /// The files created by this function always use temporary files to write to
+  /// their result (that is, the data is written to a temporary file which will
+  /// atomically replace the target output on success).
+  ///
+  /// \return - Null on error.
+  llvm::raw_fd_ostream *
+  createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
+                          StringRef Extension = "");
+
+  /// Create a new output file and add it to the list of tracked output files,
+  /// optionally deriving the output path name.
+  ///
+  /// \return - Null on error.
+  llvm::raw_fd_ostream *
+  createOutputFile(StringRef OutputPath,
+                   bool Binary, bool RemoveFileOnSignal,
+                   StringRef BaseInput,
+                   StringRef Extension,
+                   bool UseTemporary,
+                   bool CreateMissingDirectories = false);
+
+  /// Create a new output file, optionally deriving the output path name.
+  ///
+  /// If \p OutputPath is empty, then createOutputFile will derive an output
+  /// path location as \p BaseInput, with any suffix removed, and \p Extension
+  /// appended. If \p OutputPath is not stdout and \p UseTemporary
+  /// is true, createOutputFile will create a new temporary file that must be
+  /// renamed to \p OutputPath in the end.
+  ///
+  /// \param OutputPath - If given, the path to the output file.
+  /// \param Error [out] - On failure, the error message.
+  /// \param BaseInput - If \p OutputPath is empty, the input path name to use
+  /// for deriving the output path.
+  /// \param Extension - The extension to use for derived output names.
+  /// \param Binary - The mode to open the file in.
+  /// \param RemoveFileOnSignal - Whether the file should be registered with
+  /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
+  /// multithreaded use, as the underlying signal mechanism is not reentrant
+  /// \param UseTemporary - Create a new temporary file that must be renamed to
+  /// OutputPath in the end.
+  /// \param CreateMissingDirectories - When \p UseTemporary is true, create
+  /// missing directories in the output path.
+  /// \param ResultPathName [out] - If given, the result path name will be
+  /// stored here on success.
+  /// \param TempPathName [out] - If given, the temporary file path name
+  /// will be stored here on success.
+  static llvm::raw_fd_ostream *
+  createOutputFile(StringRef OutputPath, std::string &Error,
+                   bool Binary, bool RemoveFileOnSignal,
+                   StringRef BaseInput,
+                   StringRef Extension,
+                   bool UseTemporary,
+                   bool CreateMissingDirectories,
+                   std::string *ResultPathName,
+                   std::string *TempPathName);
+
+  llvm::raw_null_ostream *createNullOutputFile();
+
+  /// }
+  /// @name Initialization Utility Methods
+  /// {
+
+  /// InitializeSourceManager - Initialize the source manager to set InputFile
+  /// as the main file.
+  ///
+  /// \return True on success.
+  bool InitializeSourceManager(const FrontendInputFile &Input);
+
+  /// InitializeSourceManager - Initialize the source manager to set InputFile
+  /// as the main file.
+  ///
+  /// \return True on success.
+  static bool InitializeSourceManager(const FrontendInputFile &Input,
+                DiagnosticsEngine &Diags,
+                FileManager &FileMgr,
+                SourceManager &SourceMgr,
+                const FrontendOptions &Opts);
+
+  /// }
+
+  // Create module manager.
+  void createModuleManager();
+
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override;
+
+  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc, bool Complain) override;
+
+  bool hadModuleLoaderFatalFailure() const {
+    return ModuleLoader::HadFatalFailure;
+  }
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
+
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
+
+  void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
+    DependencyCollectors.push_back(std::move(Listener));
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
new file mode 100644
index 0000000..f05ab80
--- /dev/null
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -0,0 +1,219 @@
+//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
+
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/LangStandard.h"
+#include "clang/Frontend/MigratorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace opt {
+class ArgList;
+}
+}
+
+namespace clang {
+class CompilerInvocation;
+class DiagnosticsEngine;
+
+/// \brief Fill out Opts based on the options given in Args.
+///
+/// Args must have been created from the OptTable returned by
+/// createCC1OptTable().
+///
+/// When errors are encountered, return false and, if Diags is non-null,
+/// report the error(s).
+bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
+                         DiagnosticsEngine *Diags = nullptr);
+
+class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
+  void operator=(const CompilerInvocationBase &) LLVM_DELETED_FUNCTION;
+
+public:
+  /// Options controlling the language variant.
+  std::shared_ptr<LangOptions> LangOpts;
+
+  /// Options controlling the target.
+  std::shared_ptr<TargetOptions> TargetOpts;
+
+  /// Options controlling the diagnostic engine.
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
+
+  /// Options controlling the \#include directive.
+  IntrusiveRefCntPtr<HeaderSearchOptions> HeaderSearchOpts;
+
+  /// Options controlling the preprocessor (aside from \#include handling).
+  IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts;
+
+  CompilerInvocationBase();
+  ~CompilerInvocationBase();
+
+  CompilerInvocationBase(const CompilerInvocationBase &X);
+  
+  LangOptions *getLangOpts() { return LangOpts.get(); }
+  const LangOptions *getLangOpts() const { return LangOpts.get(); }
+
+  TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
+  const TargetOptions &getTargetOpts() const {
+    return *TargetOpts.get();
+  }
+
+  DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
+
+  HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; }
+  const HeaderSearchOptions &getHeaderSearchOpts() const {
+    return *HeaderSearchOpts;
+  }
+
+  PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
+  const PreprocessorOptions &getPreprocessorOpts() const {
+    return *PreprocessorOpts;
+  }
+};
+  
+/// \brief Helper class for holding the data necessary to invoke the compiler.
+///
+/// This class is designed to represent an abstract "invocation" of the
+/// compiler, including data such as the include paths, the code generation
+/// options, the warning flags, and so on.
+class CompilerInvocation : public CompilerInvocationBase {
+  /// Options controlling the static analyzer.
+  AnalyzerOptionsRef AnalyzerOpts;
+
+  MigratorOptions MigratorOpts;
+  
+  /// Options controlling IRgen and the backend.
+  CodeGenOptions CodeGenOpts;
+
+  /// Options controlling dependency output.
+  DependencyOutputOptions DependencyOutputOpts;
+
+  /// Options controlling file system operations.
+  FileSystemOptions FileSystemOpts;
+
+  /// Options controlling the frontend itself.
+  FrontendOptions FrontendOpts;
+
+  /// Options controlling preprocessed output.
+  PreprocessorOutputOptions PreprocessorOutputOpts;
+
+public:
+  CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {}
+
+  /// @name Utility Methods
+  /// @{
+
+  /// \brief Create a compiler invocation from a list of input options.
+  /// \returns true on success.
+  ///
+  /// \param [out] Res - The resulting invocation.
+  /// \param ArgBegin - The first element in the argument vector.
+  /// \param ArgEnd - The last element in the argument vector.
+  /// \param Diags - The diagnostic engine to use for errors.
+  static bool CreateFromArgs(CompilerInvocation &Res,
+                             const char* const *ArgBegin,
+                             const char* const *ArgEnd,
+                             DiagnosticsEngine &Diags);
+
+  /// \brief Get the directory where the compiler headers
+  /// reside, relative to the compiler binary (found by the passed in
+  /// arguments).
+  ///
+  /// \param Argv0 - The program path (from argv[0]), for finding the builtin
+  /// compiler path.
+  /// \param MainAddr - The address of main (or some other function in the main
+  /// executable), for finding the builtin compiler path.
+  static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
+
+  /// \brief Set language defaults for the given input language and
+  /// language standard in the given LangOptions object.
+  ///
+  /// \param Opts - The LangOptions object to set up.
+  /// \param IK - The input language.
+  /// \param LangStd - The input language standard.
+  static void setLangDefaults(LangOptions &Opts, InputKind IK,
+                   LangStandard::Kind LangStd = LangStandard::lang_unspecified);
+  
+  /// \brief Retrieve a module hash string that is suitable for uniquely 
+  /// identifying the conditions under which the module was built.
+  std::string getModuleHash() const;
+  
+  /// @}
+  /// @name Option Subgroups
+  /// @{
+
+  AnalyzerOptionsRef getAnalyzerOpts() const {
+    return AnalyzerOpts;
+  }
+
+  MigratorOptions &getMigratorOpts() { return MigratorOpts; }
+  const MigratorOptions &getMigratorOpts() const {
+    return MigratorOpts;
+  }
+  
+  CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
+  const CodeGenOptions &getCodeGenOpts() const {
+    return CodeGenOpts;
+  }
+
+  DependencyOutputOptions &getDependencyOutputOpts() {
+    return DependencyOutputOpts;
+  }
+  const DependencyOutputOptions &getDependencyOutputOpts() const {
+    return DependencyOutputOpts;
+  }
+
+  FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
+  const FileSystemOptions &getFileSystemOpts() const {
+    return FileSystemOpts;
+  }
+
+  FrontendOptions &getFrontendOpts() { return FrontendOpts; }
+  const FrontendOptions &getFrontendOpts() const {
+    return FrontendOpts;
+  }
+
+  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+    return PreprocessorOutputOpts;
+  }
+  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+    return PreprocessorOutputOpts;
+  }
+
+  /// @}
+};
+
+namespace vfs {
+  class FileSystem;
+}
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+                                DiagnosticsEngine &Diags);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
new file mode 100644
index 0000000..5da1459
--- /dev/null
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -0,0 +1,63 @@
+//===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// DependencyOutputOptions - Options for controlling the compiler dependency
+/// file generation.
+class DependencyOutputOptions {
+public:
+  unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+  unsigned ShowHeaderIncludes : 1;   ///< Show header inclusions (-H).
+  unsigned UsePhonyTargets : 1;      ///< Include phony targets for each
+                                     /// dependency, which can avoid some 'make'
+                                     /// problems.
+  unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
+  unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
+  unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
+  
+  /// The file to write dependency output to.
+  std::string OutputFile;
+
+  /// The file to write header include output to. This is orthogonal to
+  /// ShowHeaderIncludes (-H) and will include headers mentioned in the
+  /// predefines buffer. If the output file is "-", output will be sent to
+  /// stderr.
+  std::string HeaderIncludeOutputFile;
+
+  /// A list of names to use as the targets in the dependency file; this list
+  /// must contain at least one entry.
+  std::vector<std::string> Targets;
+
+  /// \brief The file to write GraphViz-formatted header dependencies to.
+  std::string DOTOutputFile;
+
+  /// \brief The directory to copy module dependencies to when collecting them.
+  std::string ModuleDependencyOutputDir;
+
+public:
+  DependencyOutputOptions() {
+    IncludeSystemHeaders = 0;
+    ShowHeaderIncludes = 0;
+    UsePhonyTargets = 0;
+    AddMissingHeaderDeps = 0;
+    PrintShowIncludes = 0;
+    IncludeModuleFiles = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
new file mode 100644
index 0000000..ce1dc90
--- /dev/null
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -0,0 +1,176 @@
+//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class that provides support for pretty-printing of
+// diagnostics. It is used to implement the different code paths which require
+// such functionality in a consistent way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
+#define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace clang {
+
+class DiagnosticOptions;
+class LangOptions;
+class SourceManager;
+
+typedef llvm::PointerUnion<const Diagnostic *,
+                           const StoredDiagnostic *> DiagOrStoredDiag;
+  
+/// \brief Class to encapsulate the logic for formatting a diagnostic message.
+///
+/// Actual "printing" logic is implemented by subclasses.
+///
+/// This class provides an interface for building and emitting
+/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
+/// Hints, and code snippets. In the presence of macros this involves
+/// a recursive process, synthesizing notes for each macro expansion.
+///
+/// A brief worklist:
+/// FIXME: Sink the recursive printing of template instantiations into this
+/// class.
+class DiagnosticRenderer {
+protected:
+  const LangOptions &LangOpts;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+  
+  /// \brief The location of the previous diagnostic if known.
+  ///
+  /// This will be invalid in cases where there is no (known) previous
+  /// diagnostic location, or that location itself is invalid or comes from
+  /// a different source manager than SM.
+  SourceLocation LastLoc;
+  
+  /// \brief The location of the last include whose stack was printed if known.
+  ///
+  /// Same restriction as LastLoc essentially, but tracking include stack
+  /// root locations rather than diagnostic locations.
+  SourceLocation LastIncludeLoc;
+  
+  /// \brief The level of the last diagnostic emitted.
+  ///
+  /// The level of the last diagnostic emitted. Used to detect level changes
+  /// which change the amount of information displayed.
+  DiagnosticsEngine::Level LastLevel;
+
+  DiagnosticRenderer(const LangOptions &LangOpts,
+                     DiagnosticOptions *DiagOpts);
+  
+  virtual ~DiagnosticRenderer();
+  
+  virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+                                     DiagnosticsEngine::Level Level,
+                                     StringRef Message,
+                                     ArrayRef<CharSourceRange> Ranges,
+                                     const SourceManager *SM,
+                                     DiagOrStoredDiag Info) = 0;
+  
+  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                                 DiagnosticsEngine::Level Level,
+                                 ArrayRef<CharSourceRange> Ranges,
+                                 const SourceManager &SM) = 0;
+
+  virtual void emitCodeContext(SourceLocation Loc,
+                               DiagnosticsEngine::Level Level,
+                               SmallVectorImpl<CharSourceRange>& Ranges,
+                               ArrayRef<FixItHint> Hints,
+                               const SourceManager &SM) = 0;
+  
+  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                   const SourceManager &SM) = 0;
+  virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                  StringRef ModuleName,
+                                  const SourceManager &SM) = 0;
+  virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                          StringRef ModuleName,
+                                          const SourceManager &SM) = 0;
+
+  virtual void beginDiagnostic(DiagOrStoredDiag D,
+                               DiagnosticsEngine::Level Level) {}
+  virtual void endDiagnostic(DiagOrStoredDiag D,
+                             DiagnosticsEngine::Level Level) {}
+
+  
+private:
+  void emitBasicNote(StringRef Message);
+  void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
+                        DiagnosticsEngine::Level Level, const SourceManager &SM);
+  void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
+  void emitImportStack(SourceLocation Loc, const SourceManager &SM);
+  void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName,
+                                  const SourceManager &SM);
+  void emitModuleBuildStack(const SourceManager &SM);
+  void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
+                 ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints,
+                 const SourceManager &SM);
+  void emitMacroExpansions(SourceLocation Loc,
+                           DiagnosticsEngine::Level Level,
+                           ArrayRef<CharSourceRange> Ranges,
+                           ArrayRef<FixItHint> Hints,
+                           const SourceManager &SM,
+                           unsigned &MacroDepth,
+                           unsigned OnMacroInst = 0);
+public:
+  /// \brief Emit a diagnostic.
+  ///
+  /// This is the primary entry point for emitting diagnostic messages.
+  /// It handles formatting and rendering the message as well as any ancillary
+  /// information needed based on macros whose expansions impact the
+  /// diagnostic.
+  ///
+  /// \param Loc The location for this caret.
+  /// \param Level The level of the diagnostic to be emitted.
+  /// \param Message The diagnostic message to emit.
+  /// \param Ranges The underlined ranges for this code snippet.
+  /// \param FixItHints The FixIt hints active for this diagnostic.
+  /// \param SM The SourceManager; will be null if the diagnostic came from the
+  ///        frontend, thus \p Loc will be invalid.
+  void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
+                      StringRef Message, ArrayRef<CharSourceRange> Ranges,
+                      ArrayRef<FixItHint> FixItHints,
+                      const SourceManager *SM,
+                      DiagOrStoredDiag D = (Diagnostic *)nullptr);
+
+  void emitStoredDiagnostic(StoredDiagnostic &Diag);
+};
+  
+/// Subclass of DiagnosticRender that turns all subdiagostics into explicit
+/// notes.  It is up to subclasses to further define the behavior.
+class DiagnosticNoteRenderer : public DiagnosticRenderer {
+public:
+  DiagnosticNoteRenderer(const LangOptions &LangOpts,
+                         DiagnosticOptions *DiagOpts)
+    : DiagnosticRenderer(LangOpts, DiagOpts) {}
+  
+  virtual ~DiagnosticNoteRenderer();
+
+  void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                           const SourceManager &SM) override;
+
+  void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+                          StringRef ModuleName,
+                          const SourceManager &SM) override;
+
+  void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                  StringRef ModuleName,
+                                  const SourceManager &SM) override;
+
+  virtual void emitNote(SourceLocation Loc, StringRef Message,
+                        const SourceManager *SM) = 0;
+};
+} // end clang namespace
+#endif
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
new file mode 100644
index 0000000..9ac9d28
--- /dev/null
+++ b/include/clang/Frontend/FrontendAction.h
@@ -0,0 +1,289 @@
+//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::FrontendAction interface and various convenience
+/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
+/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
+/// derived from it.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+class ASTConsumer;
+class ASTMergeAction;
+class ASTUnit;
+class CompilerInstance;
+
+/// Abstract base class for actions which can be performed by the frontend.
+class FrontendAction {
+  FrontendInputFile CurrentInput;
+  std::unique_ptr<ASTUnit> CurrentASTUnit;
+  CompilerInstance *Instance;
+  friend class ASTMergeAction;
+  friend class WrapperFrontendAction;
+
+private:
+  ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
+                                        StringRef InFile);
+
+protected:
+  /// @name Implementation Action Interface
+  /// @{
+
+  /// \brief Create the AST consumer object for this action, if supported.
+  ///
+  /// This routine is called as part of BeginSourceFile(), which will
+  /// fail if the AST consumer cannot be created. This will not be called if the
+  /// action has indicated that it only uses the preprocessor.
+  ///
+  /// \param CI - The current compiler instance, provided as a convenience, see
+  /// getCompilerInstance().
+  ///
+  /// \param InFile - The current input file, provided as a convenience, see
+  /// getCurrentFile().
+  ///
+  /// \return The new AST consumer, or null on failure.
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) = 0;
+
+  /// \brief Callback before starting processing a single input, giving the
+  /// opportunity to modify the CompilerInvocation or do some other action
+  /// before BeginSourceFileAction is called.
+  ///
+  /// \return True on success; on failure BeginSourceFileAction(),
+  /// ExecuteAction() and EndSourceFileAction() will not be called.
+  virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
+
+  /// \brief Callback at the start of processing a single input.
+  ///
+  /// \return True on success; on failure ExecutionAction() and
+  /// EndSourceFileAction() will not be called.
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     StringRef Filename) {
+    return true;
+  }
+
+  /// \brief Callback to run the program action, using the initialized
+  /// compiler instance.
+  ///
+  /// This is guaranteed to only be called between BeginSourceFileAction()
+  /// and EndSourceFileAction().
+  virtual void ExecuteAction() = 0;
+
+  /// \brief Callback at the end of processing a single input.
+  ///
+  /// This is guaranteed to only be called following a successful call to
+  /// BeginSourceFileAction (and BeginSourceFile).
+  virtual void EndSourceFileAction() {}
+
+  /// \brief Callback at the end of processing a single input, to determine
+  /// if the output files should be erased or not.
+  ///
+  /// By default it returns true if a compiler error occurred.
+  /// This is guaranteed to only be called following a successful call to
+  /// BeginSourceFileAction (and BeginSourceFile).
+  virtual bool shouldEraseOutputFiles();
+
+  /// @}
+
+public:
+  FrontendAction();
+  virtual ~FrontendAction();
+
+  /// @name Compiler Instance Access
+  /// @{
+
+  CompilerInstance &getCompilerInstance() const {
+    assert(Instance && "Compiler instance not registered!");
+    return *Instance;
+  }
+
+  void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
+
+  /// @}
+  /// @name Current File Information
+  /// @{
+
+  bool isCurrentFileAST() const {
+    assert(!CurrentInput.isEmpty() && "No current file!");
+    return (bool)CurrentASTUnit;
+  }
+
+  const FrontendInputFile &getCurrentInput() const {
+    return CurrentInput;
+  }
+  
+  const StringRef getCurrentFile() const {
+    assert(!CurrentInput.isEmpty() && "No current file!");
+    return CurrentInput.getFile();
+  }
+
+  InputKind getCurrentFileKind() const {
+    assert(!CurrentInput.isEmpty() && "No current file!");
+    return CurrentInput.getKind();
+  }
+
+  ASTUnit &getCurrentASTUnit() const {
+    assert(CurrentASTUnit && "No current AST unit!");
+    return *CurrentASTUnit;
+  }
+
+  ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
+
+  void setCurrentInput(const FrontendInputFile &CurrentInput,
+                       ASTUnit *AST = nullptr);
+
+  /// @}
+  /// @name Supported Modes
+  /// @{
+
+  /// \brief Does this action only use the preprocessor?
+  ///
+  /// If so no AST context will be created and this action will be invalid
+  /// with AST file inputs.
+  virtual bool usesPreprocessorOnly() const = 0;
+
+  /// \brief For AST-based actions, the kind of translation unit we're handling.
+  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
+
+  /// \brief Does this action support use with PCH?
+  virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); }
+
+  /// \brief Does this action support use with AST files?
+  virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); }
+
+  /// \brief Does this action support use with IR files?
+  virtual bool hasIRSupport() const { return false; }
+
+  /// \brief Does this action support use with code completion?
+  virtual bool hasCodeCompletionSupport() const { return false; }
+
+  /// @}
+  /// @name Public Action Interface
+  /// @{
+
+  /// \brief Prepare the action for processing the input file \p Input.
+  ///
+  /// This is run after the options and frontend have been initialized,
+  /// but prior to executing any per-file processing.
+  ///
+  /// \param CI - The compiler instance this action is being run from. The
+  /// action may store and use this object up until the matching EndSourceFile
+  /// action.
+  ///
+  /// \param Input - The input filename and kind. Some input kinds are handled
+  /// specially, for example AST inputs, since the AST file itself contains
+  /// several objects which would normally be owned by the
+  /// CompilerInstance. When processing AST input files, these objects should
+  /// generally not be initialized in the CompilerInstance -- they will
+  /// automatically be shared with the AST file in between
+  /// BeginSourceFile() and EndSourceFile().
+  ///
+  /// \return True on success; on failure the compilation of this file should
+  /// be aborted and neither Execute() nor EndSourceFile() should be called.
+  bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
+
+  /// \brief Set the source manager's main input file, and run the action.
+  bool Execute();
+
+  /// \brief Perform any per-file post processing, deallocate per-file
+  /// objects, and run statistics and output file cleanup code.
+  void EndSourceFile();
+
+  /// @}
+};
+
+/// \brief Abstract base class to use for AST consumer-based frontend actions.
+class ASTFrontendAction : public FrontendAction {
+protected:
+  /// \brief Implement the ExecuteAction interface by running Sema on
+  /// the already-initialized AST consumer.
+  ///
+  /// This will also take care of instantiating a code completion consumer if
+  /// the user requested it and the action supports it.
+  void ExecuteAction() override;
+
+public:
+  bool usesPreprocessorOnly() const override { return false; }
+};
+
+class PluginASTAction : public ASTFrontendAction {
+  virtual void anchor();
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override = 0;
+
+public:
+  /// \brief Parse the given plugin command line arguments.
+  ///
+  /// \param CI - The compiler instance, for use in reporting diagnostics.
+  /// \return True if the parsing succeeded; otherwise the plugin will be
+  /// destroyed and no action run. The plugin is responsible for using the
+  /// CompilerInstance's Diagnostic object to report errors.
+  virtual bool ParseArgs(const CompilerInstance &CI,
+                         const std::vector<std::string> &arg) = 0;
+};
+
+/// \brief Abstract base class to use for preprocessor-based frontend actions.
+class PreprocessorFrontendAction : public FrontendAction {
+protected:
+  /// \brief Provide a default implementation which returns aborts;
+  /// this method should never be called by FrontendAction clients.
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+public:
+  bool usesPreprocessorOnly() const override { return true; }
+};
+
+/// \brief A frontend action which simply wraps some other runtime-specified
+/// frontend action.
+///
+/// Deriving from this class allows an action to inject custom logic around
+/// some existing action's behavior. It implements every virtual method in
+/// the FrontendAction interface by forwarding to the wrapped action.
+class WrapperFrontendAction : public FrontendAction {
+  std::unique_ptr<FrontendAction> WrappedAction;
+
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  bool BeginInvocation(CompilerInstance &CI) override;
+  bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+  void ExecuteAction() override;
+  void EndSourceFileAction() override;
+
+public:
+  /// Construct a WrapperFrontendAction from an existing action, taking
+  /// ownership of it.
+  WrapperFrontendAction(FrontendAction *WrappedAction);
+
+  bool usesPreprocessorOnly() const override;
+  TranslationUnitKind getTranslationUnitKind() override;
+  bool hasPCHSupport() const override;
+  bool hasASTFileSupport() const override;
+  bool hasIRSupport() const override;
+  bool hasCodeCompletionSupport() const override;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
new file mode 100644
index 0000000..84cc82c
--- /dev/null
+++ b/include/clang/Frontend/FrontendActions.h
@@ -0,0 +1,243 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class Module;
+class FileEntry;
+  
+//===----------------------------------------------------------------------===//
+// Custom Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class InitOnlyAction : public FrontendAction {
+  void ExecuteAction() override;
+
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+public:
+  // Don't claim to only use the preprocessor, we want to follow the AST path,
+  // but do nothing.
+  bool usesPreprocessorOnly() const override { return false; }
+};
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class ASTPrintAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class ASTDumpAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class ASTDeclListAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class ASTViewAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class DeclContextPrintAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class GeneratePCHAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  TranslationUnitKind getTranslationUnitKind() override {
+    return TU_Prefix;
+  }
+
+  bool hasASTFileSupport() const override { return false; }
+
+public:
+  /// \brief Compute the AST consumer arguments that will be used to
+  /// create the PCHGenerator instance returned by CreateASTConsumer.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  static bool ComputeASTConsumerArguments(CompilerInstance &CI,
+                                          StringRef InFile,
+                                          std::string &Sysroot,
+                                          std::string &OutputFile,
+                                          raw_ostream *&OS);
+};
+
+class GenerateModuleAction : public ASTFrontendAction {
+  clang::Module *Module;
+  const FileEntry *ModuleMapForUniquing;
+  bool IsSystem;
+  
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  TranslationUnitKind getTranslationUnitKind() override {
+    return TU_Module;
+  }
+
+  bool hasASTFileSupport() const override { return false; }
+
+public:
+  GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
+                       bool IsSystem = false)
+    : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)
+  { }
+
+  bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+
+  /// \brief Compute the AST consumer arguments that will be used to
+  /// create the PCHGenerator instance returned by CreateASTConsumer.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool ComputeASTConsumerArguments(CompilerInstance &CI,
+                                   StringRef InFile,
+                                   std::string &Sysroot,
+                                   std::string &OutputFile,
+                                   raw_ostream *&OS);
+};
+
+class SyntaxOnlyAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) override;
+
+public:
+  bool hasCodeCompletionSupport() const override { return true; }
+};
+
+/// \brief Dump information about the given module file, to be used for
+/// basic debugging and discovery.
+class DumpModuleInfoAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  void ExecuteAction() override;
+
+public:
+  bool hasPCHSupport() const override { return false; }
+  bool hasASTFileSupport() const override { return true; }
+  bool hasIRSupport() const override { return false; }
+  bool hasCodeCompletionSupport() const override { return false; }
+};
+
+class VerifyPCHAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  void ExecuteAction() override;
+
+public:
+  bool hasCodeCompletionSupport() const override { return false; }
+};
+
+/**
+ * \brief Frontend action adaptor that merges ASTs together.
+ *
+ * This action takes an existing AST file and "merges" it into the AST
+ * context, producing a merged context. This action is an action
+ * adaptor, which forwards most of its calls to another action that
+ * will consume the merged context.
+ */
+class ASTMergeAction : public FrontendAction {
+  /// \brief The action that the merge action adapts.
+  FrontendAction *AdaptedAction;
+  
+  /// \brief The set of AST files to merge.
+  std::vector<std::string> ASTFiles;
+
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  bool BeginSourceFileAction(CompilerInstance &CI,
+                             StringRef Filename) override;
+
+  void ExecuteAction() override;
+  void EndSourceFileAction() override;
+
+public:
+  ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles);
+  virtual ~ASTMergeAction();
+
+  bool usesPreprocessorOnly() const override;
+  TranslationUnitKind getTranslationUnitKind() override;
+  bool hasPCHSupport() const override;
+  bool hasASTFileSupport() const override;
+  bool hasCodeCompletionSupport() const override;
+};
+
+class PrintPreambleAction : public FrontendAction {
+protected:
+  void ExecuteAction() override;
+  ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) override {
+    return nullptr;
+  }
+
+  bool usesPreprocessorOnly() const override { return true; }
+};
+  
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+class DumpRawTokensAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class DumpTokensAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class GeneratePTHAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class PreprocessOnlyAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class PrintPreprocessedAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+
+  bool hasPCHSupport() const override { return true; }
+};
+  
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
new file mode 100644
index 0000000..312dbf1
--- /dev/null
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTENDDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define FRONTENDSTART
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_FRONTEND_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
new file mode 100644
index 0000000..e87da8d
--- /dev/null
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -0,0 +1,264 @@
+//===--- FrontendOptions.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
+
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Sema/CodeCompleteOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+
+namespace frontend {
+  enum ActionKind {
+    ASTDeclList,            ///< Parse ASTs and list Decl nodes.
+    ASTDump,                ///< Parse ASTs and dump them.
+    ASTPrint,               ///< Parse ASTs and print them.
+    ASTView,                ///< Parse ASTs and view them in Graphviz.
+    DumpRawTokens,          ///< Dump out raw tokens.
+    DumpTokens,             ///< Dump out preprocessed tokens.
+    EmitAssembly,           ///< Emit a .s file.
+    EmitBC,                 ///< Emit a .bc file.
+    EmitHTML,               ///< Translate input source into HTML.
+    EmitLLVM,               ///< Emit a .ll file.
+    EmitLLVMOnly,           ///< Generate LLVM IR, but do not emit anything.
+    EmitCodeGenOnly,        ///< Generate machine code, but don't emit anything.
+    EmitObj,                ///< Emit a .o file.
+    FixIt,                  ///< Parse and apply any fixits to the source.
+    GenerateModule,         ///< Generate pre-compiled module.
+    GeneratePCH,            ///< Generate pre-compiled header.
+    GeneratePTH,            ///< Generate pre-tokenized header.
+    InitOnly,               ///< Only execute frontend initialization.
+    ModuleFileInfo,         ///< Dump information about a module file.
+    VerifyPCH,              ///< Load and verify that a PCH file is usable.
+    ParseSyntaxOnly,        ///< Parse and perform semantic analysis.
+    PluginAction,           ///< Run a plugin action, \see ActionName.
+    PrintDeclContext,       ///< Print DeclContext and their Decls.
+    PrintPreamble,          ///< Print the "preamble" of the input file
+    PrintPreprocessedInput, ///< -E mode.
+    RewriteMacros,          ///< Expand macros but not \#includes.
+    RewriteObjC,            ///< ObjC->C Rewriter.
+    RewriteTest,            ///< Rewriter playground
+    RunAnalysis,            ///< Run one or more source code analyses.
+    MigrateSource,          ///< Run migrator.
+    RunPreprocessorOnly     ///< Just lex, no output.
+  };
+}
+
+enum InputKind {
+  IK_None,
+  IK_Asm,
+  IK_C,
+  IK_CXX,
+  IK_ObjC,
+  IK_ObjCXX,
+  IK_PreprocessedC,
+  IK_PreprocessedCXX,
+  IK_PreprocessedObjC,
+  IK_PreprocessedObjCXX,
+  IK_OpenCL,
+  IK_CUDA,
+  IK_AST,
+  IK_LLVM_IR
+};
+
+  
+/// \brief An input file for the front end.
+class FrontendInputFile {
+  /// \brief The file name, or "-" to read from standard input.
+  std::string File;
+
+  llvm::MemoryBuffer *Buffer;
+
+  /// \brief The kind of input, e.g., C source, AST file, LLVM IR.
+  InputKind Kind;
+
+  /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input).
+  bool IsSystem;
+
+public:
+  FrontendInputFile() : Buffer(nullptr), Kind(IK_None) { }
+  FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
+    : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
+  FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
+                    bool IsSystem = false)
+    : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
+
+  InputKind getKind() const { return Kind; }
+  bool isSystem() const { return IsSystem; }
+
+  bool isEmpty() const { return File.empty() && Buffer == nullptr; }
+  bool isFile() const { return !isBuffer(); }
+  bool isBuffer() const { return Buffer != nullptr; }
+
+  StringRef getFile() const {
+    assert(isFile());
+    return File;
+  }
+  llvm::MemoryBuffer *getBuffer() const {
+    assert(isBuffer());
+    return Buffer;
+  }
+};
+
+/// FrontendOptions - Options for controlling the behavior of the frontend.
+class FrontendOptions {
+public:
+  unsigned DisableFree : 1;                ///< Disable memory freeing on exit.
+  unsigned RelocatablePCH : 1;             ///< When generating PCH files,
+                                           /// instruct the AST writer to create
+                                           /// relocatable PCH files.
+  unsigned ShowHelp : 1;                   ///< Show the -help text.
+  unsigned ShowStats : 1;                  ///< Show frontend performance
+                                           /// metrics and statistics.
+  unsigned ShowTimers : 1;                 ///< Show timers for individual
+                                           /// actions.
+  unsigned ShowVersion : 1;                ///< Show the -version text.
+  unsigned FixWhatYouCan : 1;              ///< Apply fixes even if there are
+                                           /// unfixable errors.
+  unsigned FixOnlyWarnings : 1;            ///< Apply fixes only for warnings.
+  unsigned FixAndRecompile : 1;            ///< Apply fixes and recompile.
+  unsigned FixToTemporaries : 1;           ///< Apply fixes to temporary files.
+  unsigned ARCMTMigrateEmitARCErrors : 1;  /// Emit ARC errors even if the
+                                           /// migrator can fix them
+  unsigned SkipFunctionBodies : 1;         ///< Skip over function bodies to
+                                           /// speed up parsing in cases you do
+                                           /// not need them (e.g. with code
+                                           /// completion).
+  unsigned UseGlobalModuleIndex : 1;       ///< Whether we can use the
+                                           ///< global module index if available.
+  unsigned GenerateGlobalModuleIndex : 1;  ///< Whether we can generate the
+                                           ///< global module index if needed.
+  unsigned ASTDumpLookups : 1;             ///< Whether we include lookup table
+                                           ///< dumps in AST dumps.
+
+  CodeCompleteOptions CodeCompleteOpts;
+
+  enum {
+    ARCMT_None,
+    ARCMT_Check,
+    ARCMT_Modify,
+    ARCMT_Migrate
+  } ARCMTAction;
+
+  enum {
+    ObjCMT_None = 0,
+    /// \brief Enable migration to modern ObjC literals.
+    ObjCMT_Literals = 0x1,
+    /// \brief Enable migration to modern ObjC subscripting.
+    ObjCMT_Subscripting = 0x2,
+    /// \brief Enable migration to modern ObjC readonly property.
+    ObjCMT_ReadonlyProperty = 0x4,
+    /// \brief Enable migration to modern ObjC readwrite property.
+    ObjCMT_ReadwriteProperty = 0x8,
+    /// \brief Enable migration to modern ObjC property.
+    ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty),
+    /// \brief Enable annotation of ObjCMethods of all kinds.
+    ObjCMT_Annotation = 0x10,
+    /// \brief Enable migration of ObjC methods to 'instancetype'.
+    ObjCMT_Instancetype = 0x20,
+    /// \brief Enable migration to NS_ENUM/NS_OPTIONS macros.
+    ObjCMT_NsMacros = 0x40,
+    /// \brief Enable migration to add conforming protocols.
+    ObjCMT_ProtocolConformance = 0x80,
+    /// \brief prefer 'atomic' property over 'nonatomic'.
+    ObjCMT_AtomicProperty = 0x100,
+    /// \brief annotate property with NS_RETURNS_INNER_POINTER
+    ObjCMT_ReturnsInnerPointerProperty = 0x200,
+    /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
+    ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
+    /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
+    ObjCMT_DesignatedInitializer = 0x800,
+    ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
+                           ObjCMT_Annotation | ObjCMT_Instancetype |
+                           ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
+                           ObjCMT_NsAtomicIOSOnlyProperty |
+                           ObjCMT_DesignatedInitializer),
+    ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
+  };
+  unsigned ObjCMTAction;
+  std::string ObjCMTWhiteListPath;
+
+  std::string MTMigrateDir;
+  std::string ARCMTMigrateReportOut;
+
+  /// The input files and their types.
+  std::vector<FrontendInputFile> Inputs;
+
+  /// The output file, if any.
+  std::string OutputFile;
+
+  /// If given, the new suffix for fix-it rewritten files.
+  std::string FixItSuffix;
+
+  /// If given, filter dumped AST Decl nodes by this substring.
+  std::string ASTDumpFilter;
+
+  /// If given, enable code completion at the provided location.
+  ParsedSourceLocation CodeCompletionAt;
+
+  /// The frontend action to perform.
+  frontend::ActionKind ProgramAction;
+
+  /// The name of the action to run when using a plugin action.
+  std::string ActionName;
+
+  /// Args to pass to the plugin
+  std::vector<std::string> PluginArgs;
+
+  /// The list of plugin actions to run in addition to the normal action.
+  std::vector<std::string> AddPluginActions;
+
+  /// Args to pass to the additional plugins
+  std::vector<std::vector<std::string> > AddPluginArgs;
+
+  /// The list of plugins to load.
+  std::vector<std::string> Plugins;
+
+  /// \brief The list of AST files to merge.
+  std::vector<std::string> ASTMergeFiles;
+
+  /// \brief A list of arguments to forward to LLVM's option processing; this
+  /// should only be used for debugging and experimental features.
+  std::vector<std::string> LLVMArgs;
+
+  /// \brief File name of the file that will provide record layouts
+  /// (in the format produced by -fdump-record-layouts).
+  std::string OverrideRecordLayoutsFile;
+  
+public:
+  FrontendOptions() :
+    DisableFree(false), RelocatablePCH(false), ShowHelp(false),
+    ShowStats(false), ShowTimers(false), ShowVersion(false),
+    FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
+    FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
+    SkipFunctionBodies(false), UseGlobalModuleIndex(true),
+    GenerateGlobalModuleIndex(true), ASTDumpLookups(false),
+    ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
+    ProgramAction(frontend::ParseSyntaxOnly)
+  {}
+
+  /// getInputKindForExtension - Return the appropriate input kind for a file
+  /// extension. For example, "c" would return IK_C.
+  ///
+  /// \return The input kind for the extension, or IK_None if the extension is
+  /// not recognized.
+  static InputKind getInputKindForExtension(StringRef Extension);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
new file mode 100644
index 0000000..49be495
--- /dev/null
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -0,0 +1,26 @@
+//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H
+
+#include "clang/Frontend/FrontendAction.h"
+#include "llvm/Support/Registry.h"
+
+// Instantiated in FrontendAction.cpp.
+extern template class llvm::Registry<clang::PluginASTAction>;
+
+namespace clang {
+
+/// The frontend plugin registry.
+typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
new file mode 100644
index 0000000..9680e1f
--- /dev/null
+++ b/include/clang/Frontend/LangStandard.h
@@ -0,0 +1,100 @@
+//===--- LangStandard.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+#define LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+namespace frontend {
+
+enum LangFeatures {
+  LineComment = (1 << 0),
+  C89 = (1 << 1),
+  C99 = (1 << 2),
+  C11 = (1 << 3),
+  CPlusPlus = (1 << 4),
+  CPlusPlus11 = (1 << 5),
+  CPlusPlus1y = (1 << 6),
+  CPlusPlus1z = (1 << 7),
+  Digraphs = (1 << 8),
+  GNUMode = (1 << 9),
+  HexFloat = (1 << 10),
+  ImplicitInt = (1 << 11)
+};
+
+}
+
+/// LangStandard - Information about the properties of a particular language
+/// standard.
+struct LangStandard {
+  enum Kind {
+#define LANGSTANDARD(id, name, desc, features) \
+    lang_##id,
+#include "clang/Frontend/LangStandards.def"
+    lang_unspecified
+  };
+
+  const char *ShortName;
+  const char *Description;
+  unsigned Flags;
+
+public:
+  /// getName - Get the name of this standard.
+  const char *getName() const { return ShortName; }
+
+  /// getDescription - Get the description of this standard.
+  const char *getDescription() const { return Description; }
+
+  /// Language supports '//' comments.
+  bool hasLineComments() const { return Flags & frontend::LineComment; }
+
+  /// isC89 - Language is a superset of C89.
+  bool isC89() const { return Flags & frontend::C89; }
+
+  /// isC99 - Language is a superset of C99.
+  bool isC99() const { return Flags & frontend::C99; }
+
+  /// isC11 - Language is a superset of C11.
+  bool isC11() const { return Flags & frontend::C11; }
+
+  /// isCPlusPlus - Language is a C++ variant.
+  bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
+
+  /// isCPlusPlus11 - Language is a C++11 variant (or later).
+  bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
+
+  /// isCPlusPlus1y - Language is a C++14 variant (or later).
+  bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; }
+
+  /// isCPlusPlus1z - Language is a C++17 variant (or later).
+  bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
+
+  /// hasDigraphs - Language supports digraphs.
+  bool hasDigraphs() const { return Flags & frontend::Digraphs; }
+
+  /// isGNUMode - Language includes GNU extensions.
+  bool isGNUMode() const { return Flags & frontend::GNUMode; }
+
+  /// hasHexFloats - Language supports hexadecimal float constants.
+  bool hasHexFloats() const { return Flags & frontend::HexFloat; }
+
+  /// hasImplicitInt - Language allows variables to be typed as int implicitly.
+  bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
+
+  static const LangStandard &getLangStandardForKind(Kind K);
+  static const LangStandard *getLangStandardForName(StringRef Name);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
new file mode 100644
index 0000000..90a27b5
--- /dev/null
+++ b/include/clang/Frontend/LangStandards.def
@@ -0,0 +1,150 @@
+//===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LANGSTANDARD
+#error "LANGSTANDARD must be defined before including this file"
+#endif
+
+/// LANGSTANDARD(IDENT, NAME, DESC, FEATURES)
+///
+/// \param IDENT - The name of the standard as a C++ identifier.
+/// \param NAME - The name of the standard.
+/// \param DESC - A short description of the standard.
+/// \param FEATURES - The standard features as flags, these are enums from the
+/// clang::frontend namespace, which is assumed to be be available.
+
+// C89-ish modes.
+LANGSTANDARD(c89, "c89",
+             "ISO C 1990",
+             C89 | ImplicitInt)
+LANGSTANDARD(c90, "c90",
+             "ISO C 1990",
+             C89 | ImplicitInt)
+LANGSTANDARD(iso9899_1990, "iso9899:1990",
+             "ISO C 1990",
+             C89 | ImplicitInt)
+
+LANGSTANDARD(c94, "iso9899:199409",
+             "ISO C 1990 with amendment 1",
+             C89 | Digraphs | ImplicitInt)
+
+LANGSTANDARD(gnu89, "gnu89",
+             "ISO C 1990 with GNU extensions",
+             LineComment | C89 | Digraphs | GNUMode | ImplicitInt)
+LANGSTANDARD(gnu90, "gnu90",
+             "ISO C 1990 with GNU extensions",
+             LineComment | C89 | Digraphs | GNUMode | ImplicitInt)
+
+// C99-ish modes
+LANGSTANDARD(c99, "c99",
+             "ISO C 1999",
+             LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(c9x, "c9x",
+             "ISO C 1999",
+             LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_1999,
+             "iso9899:1999", "ISO C 1999",
+             LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_199x,
+             "iso9899:199x", "ISO C 1999",
+             LineComment | C99 | Digraphs | HexFloat)
+
+LANGSTANDARD(gnu99, "gnu99",
+             "ISO C 1999 with GNU extensions",
+             LineComment | C99 | Digraphs | GNUMode | HexFloat)
+LANGSTANDARD(gnu9x, "gnu9x",
+             "ISO C 1999 with GNU extensions",
+             LineComment | C99 | Digraphs | GNUMode | HexFloat)
+
+// C11 modes
+LANGSTANDARD(c11, "c11",
+             "ISO C 2011",
+             LineComment | C99 | C11 | Digraphs | HexFloat)
+LANGSTANDARD(c1x, "c1x",
+             "ISO C 2011",
+             LineComment | C99 | C11 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_2011,
+             "iso9899:2011", "ISO C 2011",
+             LineComment | C99 | C11 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_201x,
+             "iso9899:2011", "ISO C 2011",
+             LineComment | C99 | C11 | Digraphs | HexFloat)
+
+LANGSTANDARD(gnu11, "gnu11",
+             "ISO C 2011 with GNU extensions",
+             LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
+LANGSTANDARD(gnu1x, "gnu1x",
+             "ISO C 2011 with GNU extensions",
+             LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
+
+// C++ modes
+LANGSTANDARD(cxx98, "c++98",
+             "ISO C++ 1998 with amendments",
+             LineComment | CPlusPlus | Digraphs)
+LANGSTANDARD(cxx03, "c++03",
+             "ISO C++ 1998 with amendments",
+             LineComment | CPlusPlus | Digraphs)
+LANGSTANDARD(gnucxx98, "gnu++98",
+             "ISO C++ 1998 with amendments and GNU extensions",
+             LineComment | CPlusPlus | Digraphs | GNUMode)
+
+LANGSTANDARD(cxx0x, "c++0x",
+             "ISO C++ 2011 with amendments",
+             LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
+LANGSTANDARD(cxx11, "c++11",
+             "ISO C++ 2011 with amendments",
+             LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
+LANGSTANDARD(gnucxx0x, "gnu++0x",
+             "ISO C++ 2011 with amendments and GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
+LANGSTANDARD(gnucxx11, "gnu++11",
+             "ISO C++ 2011 with amendments and GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
+
+LANGSTANDARD(cxx1y, "c++1y",
+             "ISO C++ 2014 with amendments",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
+LANGSTANDARD(cxx14, "c++14",
+             "ISO C++ 2014 with amendments",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
+LANGSTANDARD(gnucxx1y, "gnu++1y",
+             "ISO C++ 2014 with amendments and GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
+             GNUMode)
+LANGSTANDARD(gnucxx14, "gnu++14",
+             "ISO C++ 2014 with amendments and GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
+             GNUMode)
+
+LANGSTANDARD(cxx1z, "c++1z",
+             "Working draft for ISO C++ 2017",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs)
+LANGSTANDARD(gnucxx1z, "gnu++1z",
+             "Working draft for ISO C++ 2017 with GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs | GNUMode)
+
+// OpenCL
+LANGSTANDARD(opencl, "cl",
+             "OpenCL 1.0",
+             LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(opencl11, "CL1.1",
+             "OpenCL 1.1",
+             LineComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(opencl12, "CL1.2",
+             "OpenCL 1.2",
+             LineComment | C99 | Digraphs | HexFloat)
+
+// CUDA
+LANGSTANDARD(cuda, "cuda",
+             "NVIDIA CUDA(tm)",
+             LineComment | CPlusPlus | Digraphs)
+
+#undef LANGSTANDARD
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
new file mode 100644
index 0000000..16d032b
--- /dev/null
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -0,0 +1,63 @@
+//===--- LayoutOverrideSource.h --Override Record Layouts -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
+#define LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H
+
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+  /// \brief An external AST source that overrides the layout of
+  /// a specified set of record types.
+  ///
+  /// This class is used only for testing the ability of external AST sources
+  /// to override the layout of record types. Its input is the output format
+  /// of the command-line argument -fdump-record-layouts.
+  class LayoutOverrideSource : public ExternalASTSource {
+    /// \brief The layout of a given record.
+    struct Layout {
+      /// \brief The size of the record.
+      uint64_t Size;
+      
+      /// \brief The alignment of the record.
+      uint64_t Align;
+      
+      /// \brief The offsets of the fields, in source order.
+      SmallVector<uint64_t, 8> FieldOffsets;
+    };
+    
+    /// \brief The set of layouts that will be overridden.
+    llvm::StringMap<Layout> Layouts;
+    
+  public:
+    /// \brief Create a new AST source that overrides the layout of some
+    /// set of record types.
+    ///
+    /// The file is the result of passing -fdump-record-layouts to a file.
+    explicit LayoutOverrideSource(StringRef Filename);
+    
+    /// \brief If this particular record type has an overridden layout,
+    /// return that layout.
+    bool
+    layoutRecordType(const RecordDecl *Record,
+       uint64_t &Size, uint64_t &Alignment,
+       llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+       llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+       llvm::DenseMap<const CXXRecordDecl *,
+                      CharUnits> &VirtualBaseOffsets) override;
+    
+    /// \brief Dump the overridden layouts.
+    void dump();
+  };
+}
+
+#endif
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
new file mode 100644
index 0000000..0130319
--- /dev/null
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -0,0 +1,80 @@
+//===--- LogDiagnosticPrinter.h - Log Diagnostic Client ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_LOG_DIAGNOSTIC_PRINTER_H_
+#define LLVM_CLANG_FRONTEND_LOG_DIAGNOSTIC_PRINTER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+class DiagnosticOptions;
+class LangOptions;
+
+class LogDiagnosticPrinter : public DiagnosticConsumer {
+  struct DiagEntry {
+    /// The primary message line of the diagnostic.
+    std::string Message;
+  
+    /// The source file name, if available.
+    std::string Filename;
+  
+    /// The source file line number, if available.
+    unsigned Line;
+  
+    /// The source file column number, if available.
+    unsigned Column;
+  
+    /// The ID of the diagnostic.
+    unsigned DiagnosticID;
+  
+    /// The level of the diagnostic.
+    DiagnosticsEngine::Level DiagnosticLevel;
+  };
+
+  void EmitDiagEntry(llvm::raw_ostream &OS,
+                     const LogDiagnosticPrinter::DiagEntry &DE);
+
+  raw_ostream &OS;
+  const LangOptions *LangOpts;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+
+  SourceLocation LastWarningLoc;
+  FullSourceLoc LastLoc;
+  unsigned OwnsOutputStream : 1;
+
+  SmallVector<DiagEntry, 8> Entries;
+
+  std::string MainFilename;
+  std::string DwarfDebugFlags;
+
+public:
+  LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags,
+                       bool OwnsOutputStream = false);
+  virtual ~LogDiagnosticPrinter();
+
+  void setDwarfDebugFlags(StringRef Value) {
+    DwarfDebugFlags = Value;
+  }
+
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
+    LangOpts = &LO;
+  }
+
+  void EndSourceFile() override;
+
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/MigratorOptions.h b/include/clang/Frontend/MigratorOptions.h
new file mode 100644
index 0000000..f9554e4
--- /dev/null
+++ b/include/clang/Frontend/MigratorOptions.h
@@ -0,0 +1,31 @@
+//===--- MigratorOptions.h - MigratorOptions Options ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the structures necessary for a front-end to specify
+// various migration analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
+#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
+
+namespace clang {
+
+class MigratorOptions {
+public:
+  unsigned NoNSAllocReallocError : 1;
+  unsigned NoFinalizeRemoval : 1;
+  MigratorOptions() {
+    NoNSAllocReallocError = 0;
+    NoFinalizeRemoval = 0;
+  }
+};
+
+}
+#endif
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
new file mode 100644
index 0000000..4d31104
--- /dev/null
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -0,0 +1,69 @@
+//===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- 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 MultiplexConsumer class, which can be used to
+//  multiplex ASTConsumer and SemaConsumer messages to many consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_FRONTEND_MULTIPLEXCONSUMER_H
+#define CLANG_FRONTEND_MULTIPLEXCONSUMER_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Sema/SemaConsumer.h"
+#include <memory>
+#include <vector>
+
+namespace clang {
+
+class MultiplexASTMutationListener;
+class MultiplexASTDeserializationListener;
+
+// Has a list of ASTConsumers and calls each of them. Owns its children.
+class MultiplexConsumer : public SemaConsumer {
+public:
+  // Takes ownership of the pointers in C.
+  MultiplexConsumer(ArrayRef<ASTConsumer*> C);
+  ~MultiplexConsumer();
+
+  // ASTConsumer
+  void Initialize(ASTContext &Context) override;
+  void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
+  bool HandleTopLevelDecl(DeclGroupRef D) override;
+  void HandleInlineMethodDefinition(CXXMethodDecl *D) override;
+  void HandleInterestingDecl(DeclGroupRef D) override;
+  void HandleTranslationUnit(ASTContext &Ctx) override;
+  void HandleTagDeclDefinition(TagDecl *D) override;
+  void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
+  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override;
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
+  void HandleImplicitImportDecl(ImportDecl *D) override;
+  void HandleLinkerOptionPragma(llvm::StringRef Opts) override;
+  void HandleDetectMismatch(llvm::StringRef Name,
+                            llvm::StringRef Value) override;
+  void HandleDependentLibrary(llvm::StringRef Lib) override;
+  void CompleteTentativeDefinition(VarDecl *D) override;
+  void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override;
+  ASTMutationListener *GetASTMutationListener() override;
+  ASTDeserializationListener *GetASTDeserializationListener() override;
+  void PrintStats() override;
+
+  // SemaConsumer
+  void InitializeSema(Sema &S) override;
+  void ForgetSema() override;
+
+private:
+  std::vector<ASTConsumer*> Consumers;  // Owns these.
+  std::unique_ptr<MultiplexASTMutationListener> MutationListener;
+  std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
new file mode 100644
index 0000000..e273dd6
--- /dev/null
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -0,0 +1,39 @@
+//===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+
+namespace clang {
+
+/// PreprocessorOutputOptions - Options for controlling the C preprocessor
+/// output (e.g., -E).
+class PreprocessorOutputOptions {
+public:
+  unsigned ShowCPP : 1;            ///< Print normal preprocessed output.
+  unsigned ShowComments : 1;       ///< Show comments.
+  unsigned ShowLineMarkers : 1;    ///< Show \#line markers.
+  unsigned ShowMacroComments : 1;  ///< Show comments, even in macros.
+  unsigned ShowMacros : 1;         ///< Print macro definitions.
+  unsigned RewriteIncludes : 1;    ///< Preprocess include directives only.
+
+public:
+  PreprocessorOutputOptions() {
+    ShowCPP = 0;
+    ShowComments = 0;
+    ShowLineMarkers = 1;
+    ShowMacroComments = 0;
+    ShowMacros = 0;
+    RewriteIncludes = 0;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
new file mode 100644
index 0000000..4dda1fa
--- /dev/null
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -0,0 +1,76 @@
+//===--- SerializedDiagnosticPrinter.h - Serializer for diagnostics -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
+#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTIC_PRINTER_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+
+namespace llvm {
+class raw_ostream;
+}
+
+namespace clang {
+class DiagnosticConsumer;
+class DiagnosticsEngine;
+class DiagnosticOptions;
+
+namespace serialized_diags {
+  
+enum BlockIDs {
+  /// \brief A top-level block which represents any meta data associated
+  /// with the diagostics, including versioning of the format.
+  BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+  /// \brief The this block acts as a container for all the information
+  /// for a specific diagnostic.
+  BLOCK_DIAG
+};
+
+enum RecordIDs {
+  RECORD_VERSION = 1,
+  RECORD_DIAG,
+  RECORD_SOURCE_RANGE,
+  RECORD_DIAG_FLAG,
+  RECORD_CATEGORY,
+  RECORD_FILENAME,
+  RECORD_FIXIT,
+  RECORD_FIRST = RECORD_VERSION,
+  RECORD_LAST = RECORD_FIXIT
+};
+
+/// A stable version of DiagnosticIDs::Level.
+///
+/// Do not change the order of values in this enum, and please increment the
+/// serialized diagnostics version number when you add to it.
+enum Level {
+  Ignored = 0,
+  Note,
+  Warning,
+  Error,
+  Fatal,
+  Remark
+};
+
+/// \brief Returns a DiagnosticConsumer that serializes diagnostics to
+///  a bitcode file.
+///
+/// The created DiagnosticConsumer is designed for quick and lightweight
+/// transfer of of diagnostics to the enclosing build system (e.g., an IDE).
+/// This allows wrapper tools for Clang to get diagnostics from Clang
+/// (via libclang) without needing to parse Clang's command line output.
+///
+DiagnosticConsumer *create(raw_ostream *OS,
+                           DiagnosticOptions *diags);
+
+} // end serialized_diags namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
new file mode 100644
index 0000000..acebb90
--- /dev/null
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -0,0 +1,122 @@
+//===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class that provides support for textual pretty-printing of
+// diagnostics. It is used to implement the different code paths which require
+// such functionality in a consistent way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
+
+#include "clang/Frontend/DiagnosticRenderer.h"
+
+namespace clang {
+
+/// \brief Class to encapsulate the logic for formatting and printing a textual
+/// diagnostic message.
+///
+/// This class provides an interface for building and emitting a textual
+/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
+/// Hints, and code snippets. In the presence of macros this involves
+/// a recursive process, synthesizing notes for each macro expansion.
+///
+/// The purpose of this class is to isolate the implementation of printing
+/// beautiful text diagnostics from any particular interfaces. The Clang
+/// DiagnosticClient is implemented through this class as is diagnostic
+/// printing coming out of libclang.
+class TextDiagnostic : public DiagnosticRenderer {
+  raw_ostream &OS;
+
+public:
+  TextDiagnostic(raw_ostream &OS,
+                 const LangOptions &LangOpts,
+                 DiagnosticOptions *DiagOpts);
+
+  virtual ~TextDiagnostic();
+  
+  /// \brief Print the diagonstic level to a raw_ostream.
+  ///
+  /// This is a static helper that handles colorizing the level and formatting
+  /// it into an arbitrary output stream. This is used internally by the
+  /// TextDiagnostic emission code, but it can also be used directly by
+  /// consumers that don't have a source manager or other state that the full
+  /// TextDiagnostic logic requires.
+  static void printDiagnosticLevel(raw_ostream &OS,
+                                   DiagnosticsEngine::Level Level,
+                                   bool ShowColors,
+                                   bool CLFallbackMode = false);
+
+  /// \brief Pretty-print a diagnostic message to a raw_ostream.
+  ///
+  /// This is a static helper to handle the line wrapping, colorizing, and
+  /// rendering of a diagnostic message to a particular ostream. It is
+  /// publicly visible so that clients which do not have sufficient state to
+  /// build a complete TextDiagnostic object can still get consistent
+  /// formatting of their diagnostic messages.
+  ///
+  /// \param OS Where the message is printed
+  /// \param IsSupplemental true if this is a continuation note diagnostic
+  /// \param Message The text actually printed
+  /// \param CurrentColumn The starting column of the first line, accounting
+  ///                      for any prefix.
+  /// \param Columns The number of columns to use in line-wrapping, 0 disables
+  ///                all line-wrapping.
+  /// \param ShowColors Enable colorizing of the message.
+  static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental,
+                                     StringRef Message, unsigned CurrentColumn,
+                                     unsigned Columns, bool ShowColors);
+
+protected:
+  void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
+                             DiagnosticsEngine::Level Level,
+                             StringRef Message,
+                             ArrayRef<CharSourceRange> Ranges,
+                             const SourceManager *SM,
+                             DiagOrStoredDiag D) override;
+
+  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                         DiagnosticsEngine::Level Level,
+                         ArrayRef<CharSourceRange> Ranges,
+                         const SourceManager &SM) override;
+
+  void emitCodeContext(SourceLocation Loc,
+                       DiagnosticsEngine::Level Level,
+                       SmallVectorImpl<CharSourceRange>& Ranges,
+                       ArrayRef<FixItHint> Hints,
+                       const SourceManager &SM) override {
+    emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
+  }
+
+  void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                           const SourceManager &SM) override;
+
+  void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+                          StringRef ModuleName,
+                          const SourceManager &SM) override;
+
+  void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+                                  StringRef ModuleName,
+                                  const SourceManager &SM) override;
+
+private:
+  void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
+                           SmallVectorImpl<CharSourceRange>& Ranges,
+                           ArrayRef<FixItHint> Hints,
+                           const SourceManager &SM);
+
+  void emitSnippet(StringRef SourceLine);
+
+  void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
new file mode 100644
index 0000000..fe5aa3e
--- /dev/null
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -0,0 +1,55 @@
+//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which buffers the diagnostic messages.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_BUFFER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include <vector>
+
+namespace clang {
+
+class Preprocessor;
+class SourceManager;
+
+class TextDiagnosticBuffer : public DiagnosticConsumer {
+public:
+  typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
+  typedef DiagList::iterator iterator;
+  typedef DiagList::const_iterator const_iterator;
+private:
+  DiagList Errors, Warnings, Remarks, Notes;
+public:
+  const_iterator err_begin() const  { return Errors.begin(); }
+  const_iterator err_end() const    { return Errors.end(); }
+
+  const_iterator warn_begin() const { return Warnings.begin(); }
+  const_iterator warn_end() const   { return Warnings.end(); }
+
+  const_iterator remark_begin() const { return Remarks.begin(); }
+  const_iterator remark_end() const   { return Remarks.end(); }
+
+  const_iterator note_begin() const { return Notes.begin(); }
+  const_iterator note_end() const   { return Notes.end(); }
+
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+
+  /// FlushDiagnostics - Flush the buffered diagnostics to an given
+  /// diagnostic engine.
+  void FlushDiagnostics(DiagnosticsEngine &Diags) const;
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
new file mode 100644
index 0000000..9f6d5ff
--- /dev/null
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -0,0 +1,58 @@
+//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a concrete diagnostic client, which prints the diagnostics to
+// standard error.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_PRINTER_H_
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include <memory>
+
+namespace clang {
+class DiagnosticOptions;
+class LangOptions;
+class TextDiagnostic;
+
+class TextDiagnosticPrinter : public DiagnosticConsumer {
+  raw_ostream &OS;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+
+  /// \brief Handle to the currently active text diagnostic emitter.
+  std::unique_ptr<TextDiagnostic> TextDiag;
+
+  /// A string to prefix to error messages.
+  std::string Prefix;
+
+  unsigned OwnsOutputStream : 1;
+
+public:
+  TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags,
+                        bool OwnsOutputStream = false);
+  virtual ~TextDiagnosticPrinter();
+
+  /// setPrefix - Set the diagnostic printer prefix string, which will be
+  /// printed at the start of any diagnostics. If empty, no prefix string is
+  /// used.
+  void setPrefix(std::string Value) { Prefix = Value; }
+
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override;
+  void EndSourceFile() override;
+  void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                        const Diagnostic &Info) override;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
new file mode 100644
index 0000000..4c0a7b7
--- /dev/null
+++ b/include/clang/Frontend/Utils.h
@@ -0,0 +1,212 @@
+//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for various front-end actions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_UTILS_H
+#define LLVM_CLANG_FRONTEND_UTILS_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Option/OptSpecifier.h"
+
+namespace llvm {
+class raw_fd_ostream;
+class Triple;
+
+namespace opt {
+class ArgList;
+}
+}
+
+namespace clang {
+class ASTConsumer;
+class ASTReader;
+class CompilerInstance;
+class CompilerInvocation;
+class Decl;
+class DependencyOutputOptions;
+class DiagnosticsEngine;
+class DiagnosticOptions;
+class ExternalSemaSource;
+class FileManager;
+class HeaderSearch;
+class HeaderSearchOptions;
+class IdentifierTable;
+class LangOptions;
+class Preprocessor;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class SourceManager;
+class Stmt;
+class TargetInfo;
+class FrontendOptions;
+
+/// Apply the header search options to get given HeaderSearch object.
+void ApplyHeaderSearchOptions(HeaderSearch &HS,
+                              const HeaderSearchOptions &HSOpts,
+                              const LangOptions &Lang,
+                              const llvm::Triple &triple);
+
+/// InitializePreprocessor - Initialize the preprocessor getting it and the
+/// environment ready to process a single file.
+void InitializePreprocessor(Preprocessor &PP,
+                            const PreprocessorOptions &PPOpts,
+                            const FrontendOptions &FEOpts);
+
+/// DoPrintPreprocessedInput - Implement -E mode.
+void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
+                              const PreprocessorOutputOptions &Opts);
+
+/// An interface for collecting the dependencies of a compilation. Users should
+/// use \c attachToPreprocessor and \c attachToASTReader to get all of the
+/// dependencies.
+// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to
+// use this interface.
+class DependencyCollector {
+public:
+  void attachToPreprocessor(Preprocessor &PP);
+  void attachToASTReader(ASTReader &R);
+  llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; }
+
+  /// Called when a new file is seen. Return true if \p Filename should be added
+  /// to the list of dependencies.
+  ///
+  /// The default implementation ignores <built-in> and system files.
+  virtual bool sawDependency(StringRef Filename, bool FromModule,
+                             bool IsSystem, bool IsModuleFile, bool IsMissing);
+  /// Called when the end of the main file is reached.
+  virtual void finishedMainFile() { }
+  /// Return true if system files should be passed to sawDependency().
+  virtual bool needSystemDependencies() { return false; }
+  virtual ~DependencyCollector();
+
+public: // implementation detail
+  /// Add a dependency \p Filename if it has not been seen before and
+  /// sawDependency() returns true.
+  void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem,
+                          bool IsModuleFile, bool IsMissing);
+private:
+  llvm::StringSet<> Seen;
+  std::vector<std::string> Dependencies;
+};
+
+/// Builds a depdenency file when attached to a Preprocessor (for includes) and
+/// ASTReader (for module imports), and writes it out at the end of processing
+/// a source file.  Users should attach to the ast reader whenever a module is
+/// loaded.
+class DependencyFileGenerator {
+  void *Impl; // Opaque implementation
+  DependencyFileGenerator(void *Impl);
+public:
+  static DependencyFileGenerator *CreateAndAttachToPreprocessor(
+    Preprocessor &PP, const DependencyOutputOptions &Opts);
+  void AttachToASTReader(ASTReader &R);
+};
+
+/// Collects the dependencies for imported modules into a directory.  Users
+/// should attach to the AST reader whenever a module is loaded.
+class ModuleDependencyCollector {
+  std::string DestDir;
+  bool HasErrors;
+  llvm::StringSet<> Seen;
+  vfs::YAMLVFSWriter VFSWriter;
+
+public:
+  StringRef getDest() { return DestDir; }
+  bool insertSeen(StringRef Filename) { return Seen.insert(Filename); }
+  void setHasErrors() { HasErrors = true; }
+  void addFileMapping(StringRef VPath, StringRef RPath) {
+    VFSWriter.addFileMapping(VPath, RPath);
+  }
+
+  void attachToASTReader(ASTReader &R);
+  void writeFileMap();
+  bool hasErrors() { return HasErrors; }
+  ModuleDependencyCollector(std::string DestDir)
+      : DestDir(DestDir), HasErrors(false) {}
+  ~ModuleDependencyCollector() { writeFileMap(); }
+};
+
+/// AttachDependencyGraphGen - Create a dependency graph generator, and attach
+/// it to the given preprocessor.
+  void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
+                                StringRef SysRoot);
+
+/// AttachHeaderIncludeGen - Create a header include list generator, and attach
+/// it to the given preprocessor.
+///
+/// \param ShowAllHeaders - If true, show all header information instead of just
+/// headers following the predefines buffer. This is useful for making sure
+/// includes mentioned on the command line are also reported, but differs from
+/// the default behavior used by -H.
+/// \param OutputPath - If non-empty, a path to write the header include
+/// information to, instead of writing to stderr.
+/// \param ShowDepth - Whether to indent to show the nesting of the includes.
+/// \param MSStyle - Whether to print in cl.exe /showIncludes style.
+void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false,
+                            StringRef OutputPath = "",
+                            bool ShowDepth = true, bool MSStyle = false);
+
+/// CacheTokens - Cache tokens for use with PCH. Note that this requires
+/// a seekable stream.
+void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
+
+/// The ChainedIncludesSource class converts headers to chained PCHs in
+/// memory, mainly for testing.
+IntrusiveRefCntPtr<ExternalSemaSource>
+createChainedIncludesSource(CompilerInstance &CI,
+                            IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
+
+/// createInvocationFromCommandLine - Construct a compiler invocation object for
+/// a command line argument vector.
+///
+/// \return A CompilerInvocation, or 0 if none was built for the given
+/// argument vector.
+CompilerInvocation *
+createInvocationFromCommandLine(ArrayRef<const char *> Args,
+                            IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+                                IntrusiveRefCntPtr<DiagnosticsEngine>());
+
+/// Return the value of the last argument as an integer, or a default. If Diags
+/// is non-null, emits an error if the argument is given, but non-integral.
+int getLastArgIntValue(const llvm::opt::ArgList &Args,
+                       llvm::opt::OptSpecifier Id, int Default,
+                       DiagnosticsEngine *Diags = nullptr);
+
+inline int getLastArgIntValue(const llvm::opt::ArgList &Args,
+                              llvm::opt::OptSpecifier Id, int Default,
+                              DiagnosticsEngine &Diags) {
+  return getLastArgIntValue(Args, Id, Default, &Diags);
+}
+
+uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+                               llvm::opt::OptSpecifier Id, uint64_t Default,
+                               DiagnosticsEngine *Diags = nullptr);
+
+inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+                                      llvm::opt::OptSpecifier Id,
+                                      uint64_t Default,
+                                      DiagnosticsEngine &Diags) {
+  return getLastArgUInt64Value(Args, Id, Default, &Diags);
+}
+
+// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
+// global objects, but we don't want LeakDetectors to complain, so we bury them
+// in a globally visible array.
+void BuryPointer(const void *Ptr);
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
new file mode 100644
index 0000000..9273fac
--- /dev/null
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -0,0 +1,277 @@
+//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/STLExtras.h"
+#include <climits>
+#include <memory>
+
+namespace clang {
+
+class DiagnosticsEngine;
+class TextDiagnosticBuffer;
+class FileEntry;
+
+/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
+/// markers in the input source to check that all the emitted diagnostics match
+/// those expected.
+///
+/// USING THE DIAGNOSTIC CHECKER:
+///
+/// Indicating that a line expects an error or a warning is simple. Put a
+/// comment on the line that has the diagnostic, use:
+///
+/// \code
+///   expected-{error,warning,remark,note}
+/// \endcode
+///
+/// to tag if it's an expected error, remark or warning, and place the expected
+/// text between {{ and }} markers. The full text doesn't have to be included,
+/// only enough to ensure that the correct diagnostic was emitted.
+///
+/// Here's an example:
+///
+/// \code
+///   int A = B; // expected-error {{use of undeclared identifier 'B'}}
+/// \endcode
+///
+/// You can place as many diagnostics on one line as you wish. To make the code
+/// more readable, you can use slash-newline to separate out the diagnostics.
+///
+/// Alternatively, it is possible to specify the line on which the diagnostic
+/// should appear by appending "@<line>" to "expected-<type>", for example:
+///
+/// \code
+///   #warning some text
+///   // expected-warning@10 {{some text}}
+/// \endcode
+///
+/// The line number may be absolute (as above), or relative to the current
+/// line by prefixing the number with either '+' or '-'.
+///
+/// If the diagnostic is generated in a separate file, for example in a shared
+/// header file, it may be beneficial to be able to declare the file in which
+/// the diagnostic will appear, rather than placing the expected-* directive in
+/// the actual file itself.  This can be done using the following syntax:
+///
+/// \code
+///   // expected-error@path/include.h:15 {{error message}}
+/// \endcode
+///
+/// The path can be absolute or relative and the same search paths will be used
+/// as for #include directives.  The line number in an external file may be
+/// substituted with '*' meaning that any line number will match (useful where
+/// the included file is, for example, a system header where the actual line
+/// number may change and is not critical).
+///
+/// The simple syntax above allows each specification to match exactly one
+/// error.  You can use the extended syntax to customize this. The extended
+/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
+/// "error", "warning" or "note", and \<n> is a positive integer. This allows
+/// the diagnostic to appear as many times as specified. Example:
+///
+/// \code
+///   void f(); // expected-note 2 {{previous declaration is here}}
+/// \endcode
+///
+/// Where the diagnostic is expected to occur a minimum number of times, this
+/// can be specified by appending a '+' to the number. Example:
+///
+/// \code
+///   void f(); // expected-note 0+ {{previous declaration is here}}
+///   void g(); // expected-note 1+ {{previous declaration is here}}
+/// \endcode
+///
+/// In the first example, the diagnostic becomes optional, i.e. it will be
+/// swallowed if it occurs, but will not generate an error if it does not
+/// occur.  In the second example, the diagnostic must occur at least once.
+/// As a short-hand, "one or more" can be specified simply by '+'. Example:
+///
+/// \code
+///   void g(); // expected-note + {{previous declaration is here}}
+/// \endcode
+///
+/// A range can also be specified by "<n>-<m>".  Example:
+///
+/// \code
+///   void f(); // expected-note 0-1 {{previous declaration is here}}
+/// \endcode
+///
+/// In this example, the diagnostic may appear only once, if at all.
+///
+/// Regex matching mode may be selected by appending '-re' to type and
+/// including regexes wrapped in double curly braces in the directive, such as:
+///
+/// \code
+///   expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
+/// \endcode
+///
+/// Examples matching error: "variable has incomplete type 'struct s'"
+///
+/// \code
+///   // expected-error {{variable has incomplete type 'struct s'}}
+///   // expected-error {{variable has incomplete type}}
+///
+///   // expected-error-re {{variable has type 'struct {{.}}'}}
+///   // expected-error-re {{variable has type 'struct {{.*}}'}}
+///   // expected-error-re {{variable has type 'struct {{(.*)}}'}}
+///   // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
+/// \endcode
+///
+/// VerifyDiagnosticConsumer expects at least one expected-* directive to
+/// be found inside the source code.  If no diagnostics are expected the
+/// following directive can be used to indicate this:
+///
+/// \code
+///   // expected-no-diagnostics
+/// \endcode
+///
+class VerifyDiagnosticConsumer: public DiagnosticConsumer,
+                                public CommentHandler {
+public:
+  /// Directive - Abstract class representing a parsed verify directive.
+  ///
+  class Directive {
+  public:
+    static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
+                             StringRef Text, unsigned Min, unsigned Max);
+  public:
+    /// Constant representing n or more matches.
+    static const unsigned MaxCount = UINT_MAX;
+
+    SourceLocation DirectiveLoc;
+    SourceLocation DiagnosticLoc;
+    const std::string Text;
+    unsigned Min, Max;
+    bool MatchAnyLine;
+
+    virtual ~Directive() { }
+
+    // Returns true if directive text is valid.
+    // Otherwise returns false and populates E.
+    virtual bool isValid(std::string &Error) = 0;
+
+    // Returns true on match.
+    virtual bool match(StringRef S) = 0;
+
+  protected:
+    Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
+              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
+      : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
+        Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
+    assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
+    assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
+    }
+
+  private:
+    Directive(const Directive &) LLVM_DELETED_FUNCTION;
+    void operator=(const Directive &) LLVM_DELETED_FUNCTION;
+  };
+
+  typedef std::vector<Directive*> DirectiveList;
+
+  /// ExpectedData - owns directive objects and deletes on destructor.
+  ///
+  struct ExpectedData {
+    DirectiveList Errors;
+    DirectiveList Warnings;
+    DirectiveList Remarks;
+    DirectiveList Notes;
+
+    void Reset() {
+      llvm::DeleteContainerPointers(Errors);
+      llvm::DeleteContainerPointers(Warnings);
+      llvm::DeleteContainerPointers(Remarks);
+      llvm::DeleteContainerPointers(Notes);
+    }
+
+    ~ExpectedData() { Reset(); }
+  };
+
+  enum DirectiveStatus {
+    HasNoDirectives,
+    HasNoDirectivesReported,
+    HasExpectedNoDiagnostics,
+    HasOtherExpectedDirectives
+  };
+
+private:
+  DiagnosticsEngine &Diags;
+  DiagnosticConsumer *PrimaryClient;
+  bool OwnsPrimaryClient;
+  std::unique_ptr<TextDiagnosticBuffer> Buffer;
+  const Preprocessor *CurrentPreprocessor;
+  const LangOptions *LangOpts;
+  SourceManager *SrcManager;
+  unsigned ActiveSourceFiles;
+  DirectiveStatus Status;
+  ExpectedData ED;
+
+  void CheckDiagnostics();
+  void setSourceManager(SourceManager &SM) {
+    assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
+    SrcManager = &SM;
+  }
+
+  // These facilities are used for validation in debug builds.
+  class UnparsedFileStatus {
+    llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
+  public:
+    UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
+      : Data(File, FoundDirectives) {}
+    const FileEntry *getFile() const { return Data.getPointer(); }
+    bool foundDirectives() const { return Data.getInt(); }
+  };
+  typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
+  typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
+  ParsedFilesMap ParsedFiles;
+  UnparsedFilesMap UnparsedFiles;
+
+public:
+  /// Create a new verifying diagnostic client, which will issue errors to
+  /// the currently-attached diagnostic client when a diagnostic does not match 
+  /// what is expected (as indicated in the source file).
+  VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
+  ~VerifyDiagnosticConsumer();
+
+  void BeginSourceFile(const LangOptions &LangOpts,
+                       const Preprocessor *PP) override;
+
+  void EndSourceFile() override;
+
+  enum ParsedStatus {
+    /// File has been processed via HandleComment.
+    IsParsed,
+
+    /// File has diagnostics and may have directives.
+    IsUnparsed,
+
+    /// File has diagnostics but guaranteed no directives.
+    IsUnparsedNoDirectives
+  };
+
+  /// \brief Update lists of parsed and unparsed files.
+  void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
+
+  bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
+
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+};
+
+} // end namspace clang
+
+#endif
diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h
new file mode 100644
index 0000000..031ee7d
--- /dev/null
+++ b/include/clang/FrontendTool/Utils.h
@@ -0,0 +1,30 @@
+//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for various front-end actions
+//  which were split from Frontend to minimise Frontend's dependencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H
+#define LLVM_CLANG_FRONTENDTOOL_UTILS_H
+
+namespace clang {
+
+class CompilerInstance;
+
+/// ExecuteCompilerInvocation - Execute the given actions described by the
+/// compiler invocation object in the given compiler instance.
+///
+/// \return - True on success.
+bool ExecuteCompilerInvocation(CompilerInstance *Clang);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
new file mode 100644
index 0000000..bb7b71a
--- /dev/null
+++ b/include/clang/Index/CommentToXML.h
@@ -0,0 +1,52 @@
+//===--- CommentToXML.h - Convert comments to XML representation ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_COMMENTTOXML_H
+#define LLVM_CLANG_INDEX_COMMENTTOXML_H
+
+#include "clang/Basic/LLVM.h"
+#include <memory>
+
+namespace clang {
+class ASTContext;
+
+namespace comments {
+class FullComment;
+class HTMLTagComment;
+}
+
+namespace index {
+class SimpleFormatContext;
+
+class CommentToXMLConverter {
+  std::unique_ptr<SimpleFormatContext> FormatContext;
+  unsigned FormatInMemoryUniqueId;
+
+public:
+  CommentToXMLConverter();
+  ~CommentToXMLConverter();
+
+  void convertCommentToHTML(const comments::FullComment *FC,
+                            SmallVectorImpl<char> &HTML,
+                            const ASTContext &Context);
+
+  void convertHTMLTagNodeToText(const comments::HTMLTagComment *HTC,
+                                SmallVectorImpl<char> &Text,
+                                const ASTContext &Context);
+
+  void convertCommentToXML(const comments::FullComment *FC,
+                           SmallVectorImpl<char> &XML,
+                           const ASTContext &Context);
+};
+
+} // namespace index
+} // namespace clang
+
+#endif // LLVM_CLANG_INDEX_COMMENTTOXML_H
+
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
new file mode 100644
index 0000000..3195dee
--- /dev/null
+++ b/include/clang/Index/USRGeneration.h
@@ -0,0 +1,62 @@
+//===- USRGeneration.h - Routines for USR generation ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_USRGENERATION_H
+#define LLVM_CLANG_INDEX_USRGENERATION_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+class Decl;
+class MacroDefinition;
+class SourceManager;
+
+namespace index {
+
+static inline StringRef getUSRSpacePrefix() {
+  return "c:";
+}
+
+/// \brief Generate a USR for a Decl, including the USR prefix.
+/// \returns true if the results should be ignored, false otherwise.
+bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
+
+/// \brief Generate a USR fragment for an Objective-C class.
+void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS);
+
+/// \brief Generate a USR fragment for an Objective-C class category.
+void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS);
+
+/// \brief Generate a USR fragment for an Objective-C instance variable.  The
+/// complete USR can be created by concatenating the USR for the
+/// encompassing class with this USR fragment.
+void generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS);
+
+/// \brief Generate a USR fragment for an Objective-C method.
+void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod,
+                              raw_ostream &OS);
+
+/// \brief Generate a USR fragment for an Objective-C property.
+void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS);
+
+/// \brief Generate a USR fragment for an Objective-C protocol.
+void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
+
+/// \brief Generate a USR for a macro, including the USR prefix.
+///
+/// \returns true on error, false on success.
+bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
+                         SmallVectorImpl<char> &Buf);
+
+} // namespace index
+} // namespace clang
+
+#endif // LLVM_CLANG_IDE_USRGENERATION_H
+
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
new file mode 100644
index 0000000..91c3b78
--- /dev/null
+++ b/include/clang/Lex/CodeCompletionHandler.h
@@ -0,0 +1,71 @@
+//===--- CodeCompletionHandler.h - Preprocessor code completion -*- 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 CodeCompletionHandler interface, which provides
+//  code-completion callbacks for the preprocessor.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
+
+namespace clang {
+
+class IdentifierInfo;
+class MacroInfo;
+  
+/// \brief Callback handler that receives notifications when performing code 
+/// completion within the preprocessor.
+class CodeCompletionHandler {
+public:
+  virtual ~CodeCompletionHandler();
+  
+  /// \brief Callback invoked when performing code completion for a preprocessor
+  /// directive.
+  ///
+  /// This callback will be invoked when the preprocessor processes a '#' at the
+  /// start of a line, followed by the code-completion token.
+  ///
+  /// \param InConditional Whether we're inside a preprocessor conditional
+  /// already.
+  virtual void CodeCompleteDirective(bool InConditional) { }
+  
+  /// \brief Callback invoked when performing code completion within a block of
+  /// code that was excluded due to preprocessor conditionals.
+  virtual void CodeCompleteInConditionalExclusion() { }
+  
+  /// \brief Callback invoked when performing code completion in a context
+  /// where the name of a macro is expected.
+  ///
+  /// \param IsDefinition Whether this is the definition of a macro, e.g.,
+  /// in a \#define.
+  virtual void CodeCompleteMacroName(bool IsDefinition) { }
+  
+  /// \brief Callback invoked when performing code completion in a preprocessor
+  /// expression, such as the condition of an \#if or \#elif directive.
+  virtual void CodeCompletePreprocessorExpression() { }
+  
+  /// \brief Callback invoked when performing code completion inside a 
+  /// function-like macro argument.
+  ///
+  /// There will be another callback invocation after the macro arguments are
+  /// parsed, so this callback should generally be used to note that the next
+  /// callback is invoked inside a macro argument.
+  virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
+                                         MacroInfo *MacroInfo,
+                                         unsigned ArgumentIndex) { }
+
+  /// \brief Callback invoked when performing code completion in a part of the
+  /// file where we expect natural language, e.g., a comment, string, or 
+  /// \#error directive.
+  virtual void CodeCompleteNaturalLanguage() { }
+};
+  
+}
+
+#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
new file mode 100644
index 0000000..9edf119
--- /dev/null
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -0,0 +1,192 @@
+//===--- DirectoryLookup.h - Info for searching for headers -----*- 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 DirectoryLookup interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/ModuleMap.h"
+
+namespace clang {
+class HeaderMap;
+class DirectoryEntry;
+class FileEntry;
+class HeaderSearch;
+class Module;
+  
+/// DirectoryLookup - This class represents one entry in the search list that
+/// specifies the search order for directories in \#include directives.  It
+/// represents either a directory, a framework, or a headermap.
+///
+class DirectoryLookup {
+public:
+  enum LookupType_t {
+    LT_NormalDir,
+    LT_Framework,
+    LT_HeaderMap
+  };
+private:
+  union {  // This union is discriminated by isHeaderMap.
+    /// Dir - This is the actual directory that we're referring to for a normal
+    /// directory or a framework.
+    const DirectoryEntry *Dir;
+
+    /// Map - This is the HeaderMap if this is a headermap lookup.
+    ///
+    const HeaderMap *Map;
+  } u;
+
+  /// DirCharacteristic - The type of directory this is: this is an instance of
+  /// SrcMgr::CharacteristicKind.
+  unsigned DirCharacteristic : 2;
+
+  /// LookupType - This indicates whether this DirectoryLookup object is a
+  /// normal directory, a framework, or a headermap.
+  unsigned LookupType : 2;
+  
+  /// \brief Whether this is a header map used when building a framework.
+  unsigned IsIndexHeaderMap : 1;
+
+  /// \brief Whether we've performed an exhaustive search for module maps
+  /// within the subdirectories of this directory.
+  unsigned SearchedAllModuleMaps : 1;
+  
+public:
+  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+  /// 'dir'.
+  DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
+                  bool isFramework)
+    : DirCharacteristic(DT),
+      LookupType(isFramework ? LT_Framework : LT_NormalDir),
+      IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {
+    u.Dir = dir;
+  }
+
+  /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
+  /// 'map'.
+  DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
+                  bool isIndexHeaderMap)
+    : DirCharacteristic(DT), LookupType(LT_HeaderMap),
+      IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {
+    u.Map = map;
+  }
+
+  /// getLookupType - Return the kind of directory lookup that this is: either a
+  /// normal directory, a framework path, or a HeaderMap.
+  LookupType_t getLookupType() const { return (LookupType_t)LookupType; }
+
+  /// getName - Return the directory or filename corresponding to this lookup
+  /// object.
+  const char *getName() const;
+
+  /// getDir - Return the directory that this entry refers to.
+  ///
+  const DirectoryEntry *getDir() const {
+    return isNormalDir() ? u.Dir : nullptr;
+  }
+
+  /// getFrameworkDir - Return the directory that this framework refers to.
+  ///
+  const DirectoryEntry *getFrameworkDir() const {
+    return isFramework() ? u.Dir : nullptr;
+  }
+
+  /// getHeaderMap - Return the directory that this entry refers to.
+  ///
+  const HeaderMap *getHeaderMap() const {
+    return isHeaderMap() ? u.Map : nullptr;
+  }
+
+  /// isNormalDir - Return true if this is a normal directory, not a header map.
+  bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
+
+  /// isFramework - True if this is a framework directory.
+  ///
+  bool isFramework() const { return getLookupType() == LT_Framework; }
+
+  /// isHeaderMap - Return true if this is a header map, not a normal directory.
+  bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; }
+
+  /// \brief Determine whether we have already searched this entire
+  /// directory for module maps.
+  bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; }
+
+  /// \brief Specify whether we have already searched all of the subdirectories
+  /// for module maps.
+  void setSearchedAllModuleMaps(bool SAMM) {
+    SearchedAllModuleMaps = SAMM;
+  }
+
+  /// DirCharacteristic - The type of directory this is, one of the DirType enum
+  /// values.
+  SrcMgr::CharacteristicKind getDirCharacteristic() const {
+    return (SrcMgr::CharacteristicKind)DirCharacteristic;
+  }
+
+  /// \brief Whether this describes a system header directory.
+  bool isSystemHeaderDirectory() const {
+    return getDirCharacteristic() != SrcMgr::C_User;
+  }
+
+  /// \brief Whether this header map is building a framework or not.
+  bool isIndexHeaderMap() const { 
+    return isHeaderMap() && IsIndexHeaderMap; 
+  }
+  
+  /// LookupFile - Lookup the specified file in this search path, returning it
+  /// if it exists or returning null if not.
+  ///
+  /// \param Filename The file to look up relative to the search paths.
+  ///
+  /// \param HS The header search instance to search with.
+  ///
+  /// \param SearchPath If not NULL, will be set to the search path relative
+  /// to which the file was found.
+  ///
+  /// \param RelativePath If not NULL, will be set to the path relative to
+  /// SearchPath at which the file was found. This only differs from the
+  /// Filename for framework includes.
+  ///
+  /// \param SuggestedModule If non-null, and the file found is semantically
+  /// part of a known module, this will be set to the module that should
+  /// be imported instead of preprocessing/parsing the file found.
+  ///
+  /// \param [out] InUserSpecifiedSystemFramework If the file is found,
+  /// set to true if the file is located in a framework that has been
+  /// user-specified to be treated as a system framework.
+  ///
+  /// \param [out] MappedName if this is a headermap which maps the filename to
+  /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
+  /// vector and point Filename to it.
+  const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
+                              SmallVectorImpl<char> *SearchPath,
+                              SmallVectorImpl<char> *RelativePath,
+                              ModuleMap::KnownHeader *SuggestedModule,
+                              bool &InUserSpecifiedSystemFramework,
+                              bool &HasBeenMapped,
+                              SmallVectorImpl<char> &MappedName) const;
+
+private:
+  const FileEntry *DoFrameworkLookup(
+      StringRef Filename, HeaderSearch &HS,
+      SmallVectorImpl<char> *SearchPath,
+      SmallVectorImpl<char> *RelativePath,
+      ModuleMap::KnownHeader *SuggestedModule,
+      bool &InUserSpecifiedSystemHeader) const;
+
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
new file mode 100644
index 0000000..d9a4de4
--- /dev/null
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -0,0 +1,39 @@
+//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- 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 ExternalPreprocessorSource interface, which enables
+//  construction of macro definitions from some external source.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
+
+namespace clang {
+
+class IdentifierInfo;
+
+/// \brief Abstract interface for external sources of preprocessor 
+/// information.
+///
+/// This abstract class allows an external sources (such as the \c ASTReader) 
+/// to provide additional macro definitions.
+class ExternalPreprocessorSource {
+public:
+  virtual ~ExternalPreprocessorSource();
+  
+  /// \brief Read the set of macros defined by this external macro source.
+  virtual void ReadDefinedMacros() = 0;
+  
+  /// \brief Update an out-of-date identifier.
+  virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
+};
+  
+}
+
+#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
new file mode 100644
index 0000000..8e78b5a
--- /dev/null
+++ b/include/clang/Lex/HeaderMap.h
@@ -0,0 +1,78 @@
+//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- 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 HeaderMap interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERMAP_H
+#define LLVM_CLANG_LEX_HEADERMAP_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MemoryBuffer;
+}
+namespace clang {
+  class FileEntry;
+  class FileManager;
+  struct HMapBucket;
+  struct HMapHeader;
+
+/// This class represents an Apple concept known as a 'header map'.  To the
+/// \#include file resolution process, it basically acts like a directory of
+/// symlinks to files.  Its advantages are that it is dense and more efficient
+/// to create and process than a directory of symlinks.
+class HeaderMap {
+  HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION;
+  void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION;
+
+  const llvm::MemoryBuffer *FileBuffer;
+  bool NeedsBSwap;
+
+  HeaderMap(const llvm::MemoryBuffer *File, bool BSwap)
+    : FileBuffer(File), NeedsBSwap(BSwap) {
+  }
+public:
+  ~HeaderMap();
+
+  /// HeaderMap::Create - This attempts to load the specified file as a header
+  /// map.  If it doesn't look like a HeaderMap, it gives up and returns null.
+  static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
+
+  /// LookupFile - Check to see if the specified relative filename is located in
+  /// this HeaderMap.  If so, open it and return its FileEntry.
+  /// If RawPath is not NULL and the file is found, RawPath will be set to the
+  /// raw path at which the file was found in the file system. For example,
+  /// for a search path ".." and a filename "../file.h" this would be
+  /// "../../file.h".
+  const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
+
+  /// If the specified relative filename is located in this HeaderMap return
+  /// the filename it is mapped to, otherwise return an empty StringRef.
+  StringRef lookupFilename(StringRef Filename,
+                           SmallVectorImpl<char> &DestPath) const;
+
+  /// getFileName - Return the filename of the headermap.
+  const char *getFileName() const;
+
+  /// dump - Print the contents of this headermap to stderr.
+  void dump() const;
+
+private:
+  unsigned getEndianAdjustedWord(unsigned X) const;
+  const HMapHeader &getHeader() const;
+  HMapBucket getBucket(unsigned BucketNo) const;
+  const char *getString(unsigned StrTabIdx) const;
+};
+
+} // end namespace clang.
+
+#endif
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
new file mode 100644
index 0000000..0342629
--- /dev/null
+++ b/include/clang/Lex/HeaderSearch.h
@@ -0,0 +1,672 @@
+//===--- HeaderSearch.h - Resolve Header File Locations ---------*- 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 HeaderSearch interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
+#define LLVM_CLANG_LEX_HEADERSEARCH_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/ModuleMap.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+#include <vector>
+
+namespace clang {
+  
+class DiagnosticsEngine;  
+class ExternalIdentifierLookup;
+class FileEntry;
+class FileManager;
+class HeaderSearchOptions;
+class IdentifierInfo;
+
+/// \brief The preprocessor keeps track of this information for each
+/// file that is \#included.
+struct HeaderFileInfo {
+  /// \brief True if this is a \#import'd or \#pragma once file.
+  unsigned isImport : 1;
+
+  /// \brief True if this is a \#pragma once file.
+  unsigned isPragmaOnce : 1;
+
+  /// DirInfo - Keep track of whether this is a system header, and if so,
+  /// whether it is C++ clean or not.  This can be set by the include paths or
+  /// by \#pragma gcc system_header.  This is an instance of
+  /// SrcMgr::CharacteristicKind.
+  unsigned DirInfo : 2;
+
+  /// \brief Whether this header file info was supplied by an external source.
+  unsigned External : 1;
+
+  /// \brief Whether this header is part of a module.
+  unsigned isModuleHeader : 1;
+
+  /// \brief Whether this header is part of the module that we are building.
+  unsigned isCompilingModuleHeader : 1;
+
+  /// \brief Whether this header is part of the module that we are building.
+  /// This is an instance of ModuleMap::ModuleHeaderRole.
+  unsigned HeaderRole : 2;
+  
+  /// \brief Whether this structure is considered to already have been
+  /// "resolved", meaning that it was loaded from the external source.
+  unsigned Resolved : 1;
+  
+  /// \brief Whether this is a header inside a framework that is currently
+  /// being built. 
+  ///
+  /// When a framework is being built, the headers have not yet been placed
+  /// into the appropriate framework subdirectories, and therefore are
+  /// provided via a header map. This bit indicates when this is one of
+  /// those framework headers.
+  unsigned IndexHeaderMapHeader : 1;
+
+  /// \brief Whether this file had been looked up as a header.
+  unsigned IsValid : 1;
+  
+  /// \brief The number of times the file has been included already.
+  unsigned short NumIncludes;
+
+  /// \brief The ID number of the controlling macro.
+  ///
+  /// This ID number will be non-zero when there is a controlling
+  /// macro whose IdentifierInfo may not yet have been loaded from
+  /// external storage.
+  unsigned ControllingMacroID;
+
+  /// If this file has a \#ifndef XXX (or equivalent) guard that
+  /// protects the entire contents of the file, this is the identifier
+  /// for the macro that controls whether or not it has any effect.
+  ///
+  /// Note: Most clients should use getControllingMacro() to access
+  /// the controlling macro of this header, since
+  /// getControllingMacro() is able to load a controlling macro from
+  /// external storage.
+  const IdentifierInfo *ControllingMacro;
+
+  /// \brief If this header came from a framework include, this is the name
+  /// of the framework.
+  StringRef Framework;
+  
+  HeaderFileInfo()
+    : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
+      External(false), isModuleHeader(false), isCompilingModuleHeader(false),
+      HeaderRole(ModuleMap::NormalHeader),
+      Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
+      NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr)  {}
+
+  /// \brief Retrieve the controlling macro for this header file, if
+  /// any.
+  const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
+  
+  /// \brief Determine whether this is a non-default header file info, e.g.,
+  /// it corresponds to an actual header we've included or tried to include.
+  bool isNonDefault() const {
+    return isImport || isPragmaOnce || NumIncludes || ControllingMacro || 
+      ControllingMacroID;
+  }
+
+  /// \brief Get the HeaderRole properly typed.
+  ModuleMap::ModuleHeaderRole getHeaderRole() const {
+    return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole);
+  }
+
+  /// \brief Set the HeaderRole properly typed.
+  void setHeaderRole(ModuleMap::ModuleHeaderRole Role) {
+    HeaderRole = Role;
+  }
+};
+
+/// \brief An external source of header file information, which may supply
+/// information about header files already included.
+class ExternalHeaderFileInfoSource {
+public:
+  virtual ~ExternalHeaderFileInfoSource();
+  
+  /// \brief Retrieve the header file information for the given file entry.
+  ///
+  /// \returns Header file information for the given file entry, with the
+  /// \c External bit set. If the file entry is not known, return a 
+  /// default-constructed \c HeaderFileInfo.
+  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
+};
+  
+/// \brief Encapsulates the information needed to find the file referenced
+/// by a \#include or \#include_next, (sub-)framework lookup, etc.
+class HeaderSearch {
+  /// This structure is used to record entries in our framework cache.
+  struct FrameworkCacheEntry {
+    /// The directory entry which should be used for the cached framework.
+    const DirectoryEntry *Directory;
+
+    /// Whether this framework has been "user-specified" to be treated as if it
+    /// were a system framework (even if it was found outside a system framework
+    /// directory).
+    bool IsUserSpecifiedSystemFramework;
+  };
+
+  /// \brief Header-search options used to initialize this header search.
+  IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
+
+  DiagnosticsEngine &Diags;
+  FileManager &FileMgr;
+  /// \#include search path information.  Requests for \#include "x" search the
+  /// directory of the \#including file first, then each directory in SearchDirs
+  /// consecutively. Requests for <x> search the current dir first, then each
+  /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
+  /// NoCurDirSearch is true, then the check for the file in the current
+  /// directory is suppressed.
+  std::vector<DirectoryLookup> SearchDirs;
+  unsigned AngledDirIdx;
+  unsigned SystemDirIdx;
+  bool NoCurDirSearch;
+
+  /// \brief \#include prefixes for which the 'system header' property is
+  /// overridden.
+  ///
+  /// For a \#include "x" or \#include \<x> directive, the last string in this
+  /// list which is a prefix of 'x' determines whether the file is treated as
+  /// a system header.
+  std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
+
+  /// \brief The path to the module cache.
+  std::string ModuleCachePath;
+  
+  /// \brief All of the preprocessor-specific data about files that are
+  /// included, indexed by the FileEntry's UID.
+  std::vector<HeaderFileInfo> FileInfo;
+
+  /// Keeps track of each lookup performed by LookupFile.
+  struct LookupFileCacheInfo {
+    /// Starting index in SearchDirs that the cached search was performed from.
+    /// If there is a hit and this value doesn't match the current query, the
+    /// cache has to be ignored.
+    unsigned StartIdx;
+    /// The entry in SearchDirs that satisfied the query.
+    unsigned HitIdx;
+    /// This is non-null if the original filename was mapped to a framework
+    /// include via a headermap.
+    const char *MappedName;
+
+    /// Default constructor -- Initialize all members with zero.
+    LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
+
+    void reset(unsigned StartIdx) {
+      this->StartIdx = StartIdx;
+      this->MappedName = nullptr;
+    }
+  };
+  llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
+
+  /// \brief Collection mapping a framework or subframework
+  /// name like "Carbon" to the Carbon.framework directory.
+  llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
+
+  /// IncludeAliases - maps include file names (including the quotes or
+  /// angle brackets) to other include file names.  This is used to support the
+  /// include_alias pragma for Microsoft compatibility.
+  typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
+    IncludeAliasMap;
+  std::unique_ptr<IncludeAliasMap> IncludeAliases;
+
+  /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
+  /// headermaps.  This vector owns the headermap.
+  std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
+
+  /// \brief The mapping between modules and headers.
+  mutable ModuleMap ModMap;
+  
+  /// \brief Describes whether a given directory has a module map in it.
+  llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
+  
+  /// \brief Uniqued set of framework names, which is used to track which 
+  /// headers were included as framework headers.
+  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
+  
+  /// \brief Entity used to resolve the identifier IDs of controlling
+  /// macros into IdentifierInfo pointers, as needed.
+  ExternalIdentifierLookup *ExternalLookup;
+
+  /// \brief Entity used to look up stored header file information.
+  ExternalHeaderFileInfoSource *ExternalSource;
+  
+  // Various statistics we track for performance analysis.
+  unsigned NumIncluded;
+  unsigned NumMultiIncludeFileOptzn;
+  unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+
+  bool EnabledModules;
+
+  // HeaderSearch doesn't support default or copy construction.
+  HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION;
+  void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION;
+
+  friend class DirectoryLookup;
+  
+public:
+  HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+               SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+               const LangOptions &LangOpts, const TargetInfo *Target);
+  ~HeaderSearch();
+
+  /// \brief Retrieve the header-search options with which this header search
+  /// was initialized.
+  HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
+  
+  FileManager &getFileMgr() const { return FileMgr; }
+
+  /// \brief Interface for setting the file search paths.
+  void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
+                      unsigned angledDirIdx, unsigned systemDirIdx,
+                      bool noCurDirSearch) {
+    assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
+        "Directory indicies are unordered");
+    SearchDirs = dirs;
+    AngledDirIdx = angledDirIdx;
+    SystemDirIdx = systemDirIdx;
+    NoCurDirSearch = noCurDirSearch;
+    //LookupFileCache.clear();
+  }
+
+  /// \brief Add an additional search path.
+  void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
+    unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
+    SearchDirs.insert(SearchDirs.begin() + idx, dir);
+    if (!isAngled)
+      AngledDirIdx++;
+    SystemDirIdx++;
+  }
+
+  /// \brief Set the list of system header prefixes.
+  void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
+    SystemHeaderPrefixes.assign(P.begin(), P.end());
+  }
+
+  /// \brief Checks whether the map exists or not.
+  bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
+
+  /// \brief Map the source include name to the dest include name.
+  ///
+  /// The Source should include the angle brackets or quotes, the dest 
+  /// should not.  This allows for distinction between <> and "" headers.
+  void AddIncludeAlias(StringRef Source, StringRef Dest) {
+    if (!IncludeAliases)
+      IncludeAliases.reset(new IncludeAliasMap);
+    (*IncludeAliases)[Source] = Dest;
+  }
+
+  /// MapHeaderToIncludeAlias - Maps one header file name to a different header
+  /// file name, for use with the include_alias pragma.  Note that the source
+  /// file name should include the angle brackets or quotes.  Returns StringRef
+  /// as null if the header cannot be mapped.
+  StringRef MapHeaderToIncludeAlias(StringRef Source) {
+    assert(IncludeAliases && "Trying to map headers when there's no map");
+
+    // Do any filename replacements before anything else
+    IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
+    if (Iter != IncludeAliases->end())
+      return Iter->second;
+    return StringRef();
+  }
+
+  /// \brief Set the path to the module cache.
+  void setModuleCachePath(StringRef CachePath) {
+    ModuleCachePath = CachePath;
+  }
+  
+  /// \brief Retrieve the path to the module cache.
+  StringRef getModuleCachePath() const { return ModuleCachePath; }
+
+  /// \brief Consider modules when including files from this directory.
+  void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
+    DirectoryHasModuleMap[Dir] = true;
+  }
+  
+  /// \brief Forget everything we know about headers so far.
+  void ClearFileInfo() {
+    FileInfo.clear();
+  }
+
+  void SetExternalLookup(ExternalIdentifierLookup *EIL) {
+    ExternalLookup = EIL;
+  }
+
+  ExternalIdentifierLookup *getExternalLookup() const {
+    return ExternalLookup;
+  }
+  
+  /// \brief Set the external source of header information.
+  void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
+    ExternalSource = ES;
+  }
+  
+  /// \brief Set the target information for the header search, if not
+  /// already known.
+  void setTarget(const TargetInfo &Target);
+  
+  /// \brief Given a "foo" or \<foo> reference, look up the indicated file,
+  /// return null on failure.
+  ///
+  /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
+  /// the file was found in, or null if not applicable.
+  ///
+  /// \param IncludeLoc Used for diagnostics if valid.
+  ///
+  /// \param isAngled indicates whether the file reference is a <> reference.
+  ///
+  /// \param CurDir If non-null, the file was found in the specified directory
+  /// search location.  This is used to implement \#include_next.
+  ///
+  /// \param Includers Indicates where the \#including file(s) are, in case
+  /// relative searches are needed. In reverse order of inclusion.
+  ///
+  /// \param SearchPath If non-null, will be set to the search path relative
+  /// to which the file was found. If the include path is absolute, SearchPath
+  /// will be set to an empty string.
+  ///
+  /// \param RelativePath If non-null, will be set to the path relative to
+  /// SearchPath at which the file was found. This only differs from the
+  /// Filename for framework includes.
+  ///
+  /// \param SuggestedModule If non-null, and the file found is semantically
+  /// part of a known module, this will be set to the module that should
+  /// be imported instead of preprocessing/parsing the file found.
+  const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc,
+                              bool isAngled, const DirectoryLookup *FromDir,
+                              const DirectoryLookup *&CurDir,
+                              ArrayRef<const FileEntry *> Includers,
+                              SmallVectorImpl<char> *SearchPath,
+                              SmallVectorImpl<char> *RelativePath,
+                              ModuleMap::KnownHeader *SuggestedModule,
+                              bool SkipCache = false);
+
+  /// \brief Look up a subframework for the specified \#include file.
+  ///
+  /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
+  /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
+  /// HIToolbox is a subframework within Carbon.framework.  If so, return
+  /// the FileEntry for the designated file, otherwise return null.
+  const FileEntry *LookupSubframeworkHeader(
+      StringRef Filename,
+      const FileEntry *RelativeFileEnt,
+      SmallVectorImpl<char> *SearchPath,
+      SmallVectorImpl<char> *RelativePath,
+      ModuleMap::KnownHeader *SuggestedModule);
+
+  /// \brief Look up the specified framework name in our framework cache.
+  /// \returns The DirectoryEntry it is in if we know, null otherwise.
+  FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
+    return FrameworkMap.GetOrCreateValue(FWName).getValue();
+  }
+
+  /// \brief Mark the specified file as a target of of a \#include,
+  /// \#include_next, or \#import directive.
+  ///
+  /// \return false if \#including the file will have no effect or true
+  /// if we should include it.
+  bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
+
+
+  /// \brief Return whether the specified file is a normal header,
+  /// a system header, or a C++ friendly system header.
+  SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
+    return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
+  }
+
+  /// \brief Mark the specified file as a "once only" file, e.g. due to
+  /// \#pragma once.
+  void MarkFileIncludeOnce(const FileEntry *File) {
+    HeaderFileInfo &FI = getFileInfo(File);
+    FI.isImport = true;
+    FI.isPragmaOnce = true;
+  }
+
+  /// \brief Mark the specified file as a system header, e.g. due to
+  /// \#pragma GCC system_header.
+  void MarkFileSystemHeader(const FileEntry *File) {
+    getFileInfo(File).DirInfo = SrcMgr::C_System;
+  }
+
+  /// \brief Mark the specified file as part of a module.
+  void MarkFileModuleHeader(const FileEntry *File,
+                            ModuleMap::ModuleHeaderRole Role,
+                            bool IsCompiledModuleHeader);
+
+  /// \brief Increment the count for the number of times the specified
+  /// FileEntry has been entered.
+  void IncrementIncludeCount(const FileEntry *File) {
+    ++getFileInfo(File).NumIncludes;
+  }
+
+  /// \brief Mark the specified file as having a controlling macro.
+  ///
+  /// This is used by the multiple-include optimization to eliminate
+  /// no-op \#includes.
+  void SetFileControllingMacro(const FileEntry *File,
+                               const IdentifierInfo *ControllingMacro) {
+    getFileInfo(File).ControllingMacro = ControllingMacro;
+  }
+
+  /// \brief Return true if this is the first time encountering this header.
+  bool FirstTimeLexingFile(const FileEntry *File) {
+    return getFileInfo(File).NumIncludes == 1;
+  }
+
+  /// \brief Determine whether this file is intended to be safe from
+  /// multiple inclusions, e.g., it has \#pragma once or a controlling
+  /// macro.
+  ///
+  /// This routine does not consider the effect of \#import
+  bool isFileMultipleIncludeGuarded(const FileEntry *File);
+
+  /// CreateHeaderMap - This method returns a HeaderMap for the specified
+  /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
+  const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+
+  /// Returns true if modules are enabled.
+  bool enabledModules() const { return EnabledModules; }
+
+  /// \brief Retrieve the name of the module file that should be used to 
+  /// load the given module.
+  ///
+  /// \param Module The module whose module file name will be returned.
+  ///
+  /// \returns The name of the module file that corresponds to this module,
+  /// or an empty string if this module does not correspond to any module file.
+  std::string getModuleFileName(Module *Module);
+
+  /// \brief Retrieve the name of the module file that should be used to 
+  /// load a module with the given name.
+  ///
+  /// \param ModuleName The module whose module file name will be returned.
+  ///
+  /// \param ModuleMapPath A path that when combined with \c ModuleName
+  /// uniquely identifies this module. See Module::ModuleMap.
+  ///
+  /// \returns The name of the module file that corresponds to this module,
+  /// or an empty string if this module does not correspond to any module file.
+  std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
+
+  /// \brief Lookup a module Search for a module with the given name.
+  ///
+  /// \param ModuleName The name of the module we're looking for.
+  ///
+  /// \param AllowSearch Whether we are allowed to search in the various
+  /// search directories to produce a module definition. If not, this lookup
+  /// will only return an already-known module.
+  ///
+  /// \returns The module with the given name.
+  Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
+
+  /// \brief Try to find a module map file in the given directory, returning
+  /// \c nullptr if none is found.
+  const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
+                                       bool IsFramework);
+  
+  void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
+
+  /// \brief Determine whether there is a module map that may map the header
+  /// with the given file name to a (sub)module.
+  /// Always returns false if modules are disabled.
+  ///
+  /// \param Filename The name of the file.
+  ///
+  /// \param Root The "root" directory, at which we should stop looking for
+  /// module maps.
+  ///
+  /// \param IsSystem Whether the directories we're looking at are system
+  /// header directories.
+  bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
+                    bool IsSystem);
+  
+  /// \brief Retrieve the module that corresponds to the given file, if any.
+  ///
+  /// \param File The header that we wish to map to a module.
+  ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
+  
+  /// \brief Read the contents of the given module map file.
+  ///
+  /// \param File The module map file.
+  /// \param IsSystem Whether this file is in a system header directory.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
+
+  /// \brief Collect the set of all known, top-level modules.
+  ///
+  /// \param Modules Will be filled with the set of known, top-level modules.
+  void collectAllModules(SmallVectorImpl<Module *> &Modules);
+
+  /// \brief Load all known, top-level system modules.
+  void loadTopLevelSystemModules();
+
+private:
+  /// \brief Retrieve a module with the given name, which may be part of the
+  /// given framework.
+  ///
+  /// \param Name The name of the module to retrieve.
+  ///
+  /// \param Dir The framework directory (e.g., ModuleName.framework).
+  ///
+  /// \param IsSystem Whether the framework directory is part of the system
+  /// frameworks.
+  ///
+  /// \returns The module, if found; otherwise, null.
+  Module *loadFrameworkModule(StringRef Name, 
+                              const DirectoryEntry *Dir,
+                              bool IsSystem);
+
+  /// \brief Load all of the module maps within the immediate subdirectories
+  /// of the given search directory.
+  void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
+
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
+    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
+  }
+
+public:
+  /// \brief Retrieve the module map.
+  ModuleMap &getModuleMap() { return ModMap; }
+  
+  unsigned header_file_size() const { return FileInfo.size(); }
+
+  /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
+  /// if one exists.
+  bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
+
+  // Used by external tools
+  typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
+  search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
+  search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
+  unsigned search_dir_size() const { return SearchDirs.size(); }
+
+  search_dir_iterator quoted_dir_begin() const {
+    return SearchDirs.begin();
+  }
+  search_dir_iterator quoted_dir_end() const {
+    return SearchDirs.begin() + AngledDirIdx;
+  }
+
+  search_dir_iterator angled_dir_begin() const {
+    return SearchDirs.begin() + AngledDirIdx;
+  }
+  search_dir_iterator angled_dir_end() const {
+    return SearchDirs.begin() + SystemDirIdx;
+  }
+
+  search_dir_iterator system_dir_begin() const {
+    return SearchDirs.begin() + SystemDirIdx;
+  }
+  search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
+
+  /// \brief Retrieve a uniqued framework name.
+  StringRef getUniqueFrameworkName(StringRef Framework);
+  
+  void PrintStats();
+  
+  size_t getTotalMemory() const;
+
+  static std::string NormalizeDashIncludePath(StringRef File,
+                                              FileManager &FileMgr);
+
+private:
+  /// \brief Describes what happened when we tried to load a module map file.
+  enum LoadModuleMapResult {
+    /// \brief The module map file had already been loaded.
+    LMM_AlreadyLoaded,
+    /// \brief The module map file was loaded by this invocation.
+    LMM_NewlyLoaded,
+    /// \brief There is was directory with the given name.
+    LMM_NoDirectory,
+    /// \brief There was either no module map file or the module map file was
+    /// invalid.
+    LMM_InvalidModuleMap
+  };
+
+  LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
+                                            bool IsSystem);
+
+  /// \brief Try to load the module map file in the given directory.
+  ///
+  /// \param DirName The name of the directory where we will look for a module
+  /// map file.
+  /// \param IsSystem Whether this is a system header directory.
+  /// \param IsFramework Whether this is a framework directory.
+  ///
+  /// \returns The result of attempting to load the module map file from the
+  /// named directory.
+  LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
+                                        bool IsFramework);
+
+  /// \brief Try to load the module map file in the given directory.
+  ///
+  /// \param Dir The directory where we will look for a module map file.
+  /// \param IsSystem Whether this is a system header directory.
+  /// \param IsFramework Whether this is a framework directory.
+  ///
+  /// \returns The result of attempting to load the module map file from the
+  /// named directory.
+  LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
+                                        bool IsSystem, bool IsFramework);
+
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+  HeaderFileInfo &getFileInfo(const FileEntry *FE);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
new file mode 100644
index 0000000..06024b2
--- /dev/null
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -0,0 +1,193 @@
+//===--- HeaderSearchOptions.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
+#define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace frontend {
+  /// IncludeDirGroup - Identifiers the group a include entry belongs to, which
+  /// represents its relative positive in the search list.  A \#include of a ""
+  /// path starts at the -iquote group, then searches the Angled group, then
+  /// searches the system group, etc.
+  enum IncludeDirGroup {
+    Quoted = 0,     ///< '\#include ""' paths, added by 'gcc -iquote'.
+    Angled,         ///< Paths for '\#include <>' added by '-I'.
+    IndexHeaderMap, ///< Like Angled, but marks header maps used when
+                       ///  building frameworks.
+    System,         ///< Like Angled, but marks system directories.
+    ExternCSystem,  ///< Like System, but headers are implicitly wrapped in
+                    ///  extern "C".
+    CSystem,        ///< Like System, but only used for C.
+    CXXSystem,      ///< Like System, but only used for C++.
+    ObjCSystem,     ///< Like System, but only used for ObjC.
+    ObjCXXSystem,   ///< Like System, but only used for ObjC++.
+    After           ///< Like System, but searched after the system directories.
+  };
+}
+
+/// HeaderSearchOptions - Helper class for storing options related to the
+/// initialization of the HeaderSearch object.
+class HeaderSearchOptions : public RefCountedBase<HeaderSearchOptions> {
+public:
+  struct Entry {
+    std::string Path;
+    frontend::IncludeDirGroup Group;
+    unsigned IsFramework : 1;
+    
+    /// IgnoreSysRoot - This is false if an absolute path should be treated
+    /// relative to the sysroot, or true if it should always be the absolute
+    /// path.
+    unsigned IgnoreSysRoot : 1;
+
+    Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
+          bool ignoreSysRoot)
+      : Path(path), Group(group), IsFramework(isFramework),
+        IgnoreSysRoot(ignoreSysRoot) {}
+  };
+
+  struct SystemHeaderPrefix {
+    /// A prefix to be matched against paths in \#include directives.
+    std::string Prefix;
+
+    /// True if paths beginning with this prefix should be treated as system
+    /// headers.
+    bool IsSystemHeader;
+
+    SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
+      : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
+  };
+
+  /// If non-empty, the directory to use as a "virtual system root" for include
+  /// paths.
+  std::string Sysroot;
+
+  /// User specified include entries.
+  std::vector<Entry> UserEntries;
+
+  /// User-specified system header prefixes.
+  std::vector<SystemHeaderPrefix> SystemHeaderPrefixes;
+
+  /// The directory which holds the compiler resource files (builtin includes,
+  /// etc.).
+  std::string ResourceDir;
+
+  /// \brief The directory used for the module cache.
+  std::string ModuleCachePath;
+
+  /// \brief The directory used for a user build.
+  std::string ModuleUserBuildPath;
+
+  /// \brief Whether we should disable the use of the hash string within the
+  /// module cache.
+  ///
+  /// Note: Only used for testing!
+  unsigned DisableModuleHash : 1;
+
+  /// \brief Interpret module maps.  This option is implied by full modules.
+  unsigned ModuleMaps : 1;
+
+  /// \brief The interval (in seconds) between pruning operations.
+  ///
+  /// This operation is expensive, because it requires Clang to walk through
+  /// the directory structure of the module cache, stat()'ing and removing
+  /// files.
+  ///
+  /// The default value is large, e.g., the operation runs once a week.
+  unsigned ModuleCachePruneInterval;
+
+  /// \brief The time (in seconds) after which an unused module file will be
+  /// considered unused and will, therefore, be pruned.
+  ///
+  /// When the module cache is pruned, any module file that has not been
+  /// accessed in this many seconds will be removed. The default value is
+  /// large, e.g., a month, to avoid forcing infrequently-used modules to be
+  /// regenerated often.
+  unsigned ModuleCachePruneAfter;
+
+  /// \brief The time in seconds when the build session started.
+  ///
+  /// This time is used by other optimizations in header search and module
+  /// loading.
+  uint64_t BuildSessionTimestamp;
+
+  /// \brief The set of macro names that should be ignored for the purposes
+  /// of computing the module hash.
+  llvm::SetVector<std::string> ModulesIgnoreMacros;
+
+  /// \brief The set of user-provided module-map-files.
+  llvm::SetVector<std::string> ModuleMapFiles;
+
+  /// \brief The set of user-provided virtual filesystem overlay files.
+  std::vector<std::string> VFSOverlayFiles;
+
+  /// Include the compiler builtin includes.
+  unsigned UseBuiltinIncludes : 1;
+
+  /// Include the system standard include search directories.
+  unsigned UseStandardSystemIncludes : 1;
+
+  /// Include the system standard C++ library include search directories.
+  unsigned UseStandardCXXIncludes : 1;
+
+  /// Use libc++ instead of the default libstdc++.
+  unsigned UseLibcxx : 1;
+
+  /// Whether header search information should be output as for -v.
+  unsigned Verbose : 1;
+
+  /// \brief If true, skip verifying input files used by modules if the
+  /// module was already verified during this build session (see
+  /// \c BuildSessionTimestamp).
+  unsigned ModulesValidateOncePerBuildSession : 1;
+
+  /// \brief Whether to validate system input files when a module is loaded.
+  unsigned ModulesValidateSystemHeaders : 1;
+
+public:
+  HeaderSearchOptions(StringRef _Sysroot = "/")
+    : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0),
+      ModuleCachePruneInterval(7*24*60*60),
+      ModuleCachePruneAfter(31*24*60*60),
+      BuildSessionTimestamp(0),
+      UseBuiltinIncludes(true),
+      UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
+      UseLibcxx(false), Verbose(false),
+      ModulesValidateOncePerBuildSession(false),
+      ModulesValidateSystemHeaders(false) {}
+
+  /// AddPath - Add the \p Path path to the specified \p Group list.
+  void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
+               bool IsFramework, bool IgnoreSysRoot) {
+    UserEntries.push_back(Entry(Path, Group, IsFramework, IgnoreSysRoot));
+  }
+
+  /// AddSystemHeaderPrefix - Override whether \#include directives naming a
+  /// path starting with \p Prefix should be considered as naming a system
+  /// header.
+  void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
+    SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader));
+  }
+
+  void AddVFSOverlayFile(StringRef Name) {
+    VFSOverlayFiles.push_back(Name);
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
new file mode 100644
index 0000000..85424aa
--- /dev/null
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICLEX_H
+#define LLVM_CLANG_DIAGNOSTICLEX_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define LEXSTART
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_LEX_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
new file mode 100644
index 0000000..edcf883
--- /dev/null
+++ b/include/clang/Lex/Lexer.h
@@ -0,0 +1,645 @@
+//===--- Lexer.h - C Language Family Lexer ----------------------*- 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 Lexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEXER_H
+#define LLVM_CLANG_LEXER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PreprocessorLexer.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <string>
+
+namespace clang {
+class DiagnosticsEngine;
+class SourceManager;
+class Preprocessor;
+class DiagnosticBuilder;
+
+/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be
+/// recovering from.
+enum ConflictMarkerKind {
+  /// Not within a conflict marker.
+  CMK_None,
+  /// A normal or diff3 conflict marker, initiated by at least 7 "<"s,
+  /// separated by at least 7 "="s or "|"s, and terminated by at least 7 ">"s.
+  CMK_Normal,
+  /// A Perforce-style conflict marker, initiated by 4 ">"s,
+  /// separated by 4 "="s, and terminated by 4 "<"s.
+  CMK_Perforce
+};
+
+/// Lexer - This provides a simple interface that turns a text buffer into a
+/// stream of tokens.  This provides no support for file reading or buffering,
+/// or buffering/seeking of tokens, only forward lexing is supported.  It relies
+/// on the specified Preprocessor object to handle preprocessor directives, etc.
+class Lexer : public PreprocessorLexer {
+  void anchor() override;
+
+  //===--------------------------------------------------------------------===//
+  // Constant configuration values for this lexer.
+  const char *BufferStart;       // Start of the buffer.
+  const char *BufferEnd;         // End of the buffer.
+  SourceLocation FileLoc;        // Location for start of file.
+  LangOptions LangOpts;          // LangOpts enabled by this language (cache).
+  bool Is_PragmaLexer;           // True if lexer for _Pragma handling.
+  
+  //===--------------------------------------------------------------------===//
+  // Context-specific lexing flags set by the preprocessor.
+  //
+
+  /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace
+  /// and return them as tokens.  This is used for -C and -CC modes, and
+  /// whitespace preservation can be useful for some clients that want to lex
+  /// the file in raw mode and get every character from the file.
+  ///
+  /// When this is set to 2 it returns comments and whitespace.  When set to 1
+  /// it returns comments, when it is set to 0 it returns normal tokens only.
+  unsigned char ExtendedTokenMode;
+
+  //===--------------------------------------------------------------------===//
+  // Context that changes as the file is lexed.
+  // NOTE: any state that mutates when in raw mode must have save/restore code
+  // in Lexer::isNextPPTokenLParen.
+
+  // BufferPtr - Current pointer into the buffer.  This is the next character
+  // to be lexed.
+  const char *BufferPtr;
+
+  // IsAtStartOfLine - True if the next lexed token should get the "start of
+  // line" flag set on it.
+  bool IsAtStartOfLine;
+
+  bool IsAtPhysicalStartOfLine;
+
+  bool HasLeadingSpace;
+
+  bool HasLeadingEmptyMacro;
+
+  // CurrentConflictMarkerState - The kind of conflict marker we are handling.
+  ConflictMarkerKind CurrentConflictMarkerState;
+
+  Lexer(const Lexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const Lexer &) LLVM_DELETED_FUNCTION;
+  friend class Preprocessor;
+
+  void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
+public:
+
+  /// Lexer constructor - Create a new lexer object for the specified buffer
+  /// with the specified preprocessor managing the lexing process.  This lexer
+  /// assumes that the associated file buffer and Preprocessor objects will
+  /// outlive it, so it doesn't take ownership of either of them.
+  Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP);
+
+  /// Lexer constructor - Create a new raw lexer object.  This object is only
+  /// suitable for calls to 'LexFromRawLexer'.  This lexer assumes that the
+  /// text range will outlive it, so it doesn't take ownership of it.
+  Lexer(SourceLocation FileLoc, const LangOptions &LangOpts,
+        const char *BufStart, const char *BufPtr, const char *BufEnd);
+
+  /// Lexer constructor - Create a new raw lexer object.  This object is only
+  /// suitable for calls to 'LexFromRawLexer'.  This lexer assumes that the
+  /// text range will outlive it, so it doesn't take ownership of it.
+  Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
+        const SourceManager &SM, const LangOptions &LangOpts);
+
+  /// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
+  /// _Pragma expansion.  This has a variety of magic semantics that this method
+  /// sets up.  It returns a new'd Lexer that must be delete'd when done.
+  static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc,
+                                   SourceLocation ExpansionLocStart,
+                                   SourceLocation ExpansionLocEnd,
+                                   unsigned TokLen, Preprocessor &PP);
+
+
+  /// getLangOpts - Return the language features currently enabled.
+  /// NOTE: this lexer modifies features as a file is parsed!
+  const LangOptions &getLangOpts() const { return LangOpts; }
+
+  /// getFileLoc - Return the File Location for the file we are lexing out of.
+  /// The physical location encodes the location where the characters come from,
+  /// the virtual location encodes where we should *claim* the characters came
+  /// from.  Currently this is only used by _Pragma handling.
+  SourceLocation getFileLoc() const { return FileLoc; }
+
+private:
+  /// Lex - Return the next token in the file.  If this is the end of file, it
+  /// return the tok::eof token.  This implicitly involves the preprocessor.
+  bool Lex(Token &Result);
+
+public:
+  /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
+  bool isPragmaLexer() const { return Is_PragmaLexer; }
+
+private:
+  /// IndirectLex - An indirect call to 'Lex' that can be invoked via
+  ///  the PreprocessorLexer interface.
+  void IndirectLex(Token &Result) override { Lex(Result); }
+
+public:
+  /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no
+  /// associated preprocessor object.  Return true if the 'next character to
+  /// read' pointer points at the end of the lexer buffer, false otherwise.
+  bool LexFromRawLexer(Token &Result) {
+    assert(LexingRawMode && "Not already in raw mode!");
+    Lex(Result);
+    // Note that lexing to the end of the buffer doesn't implicitly delete the
+    // lexer when in raw mode.
+    return BufferPtr == BufferEnd;
+  }
+
+  /// isKeepWhitespaceMode - Return true if the lexer should return tokens for
+  /// every character in the file, including whitespace and comments.  This
+  /// should only be used in raw mode, as the preprocessor is not prepared to
+  /// deal with the excess tokens.
+  bool isKeepWhitespaceMode() const {
+    return ExtendedTokenMode > 1;
+  }
+
+  /// SetKeepWhitespaceMode - This method lets clients enable or disable
+  /// whitespace retention mode.
+  void SetKeepWhitespaceMode(bool Val) {
+    assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
+           "Can only retain whitespace in raw mode or -traditional-cpp");
+    ExtendedTokenMode = Val ? 2 : 0;
+  }
+
+  /// inKeepCommentMode - Return true if the lexer should return comments as
+  /// tokens.
+  bool inKeepCommentMode() const {
+    return ExtendedTokenMode > 0;
+  }
+
+  /// SetCommentRetentionMode - Change the comment retention mode of the lexer
+  /// to the specified mode.  This is really only useful when lexing in raw
+  /// mode, because otherwise the lexer needs to manage this.
+  void SetCommentRetentionState(bool Mode) {
+    assert(!isKeepWhitespaceMode() &&
+           "Can't play with comment retention state when retaining whitespace");
+    ExtendedTokenMode = Mode ? 1 : 0;
+  }
+
+  /// Sets the extended token mode back to its initial value, according to the
+  /// language options and preprocessor. This controls whether the lexer
+  /// produces comment and whitespace tokens.
+  ///
+  /// This requires the lexer to have an associated preprocessor. A standalone
+  /// lexer has nothing to reset to.
+  void resetExtendedTokenMode();
+
+  /// Gets source code buffer.
+  StringRef getBuffer() const {
+    return StringRef(BufferStart, BufferEnd - BufferStart);
+  }
+
+  /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
+  /// uninterpreted string.  This switches the lexer out of directive mode.
+  void ReadToEndOfLine(SmallVectorImpl<char> *Result = nullptr);
+
+
+  /// Diag - Forwarding function for diagnostics.  This translate a source
+  /// position in the current buffer into a SourceLocation object for rendering.
+  DiagnosticBuilder Diag(const char *Loc, unsigned DiagID) const;
+
+  /// getSourceLocation - Return a source location identifier for the specified
+  /// offset in the current file.
+  SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const;
+
+  /// getSourceLocation - Return a source location for the next character in
+  /// the current file.
+  SourceLocation getSourceLocation() override {
+    return getSourceLocation(BufferPtr);
+  }
+
+  /// \brief Return the current location in the buffer.
+  const char *getBufferLocation() const { return BufferPtr; }
+  
+  /// Stringify - Convert the specified string into a C string by escaping '\'
+  /// and " characters.  This does not add surrounding ""'s to the string.
+  /// If Charify is true, this escapes the ' character instead of ".
+  static std::string Stringify(const std::string &Str, bool Charify = false);
+
+  /// Stringify - Convert the specified string into a C string by escaping '\'
+  /// and " characters.  This does not add surrounding ""'s to the string.
+  static void Stringify(SmallVectorImpl<char> &Str);
+
+  
+  /// getSpelling - This method is used to get the spelling of a token into a
+  /// preallocated buffer, instead of as an std::string.  The caller is required
+  /// to allocate enough space for the token, which is guaranteed to be at least
+  /// Tok.getLength() bytes long.  The length of the actual result is returned.
+  ///
+  /// Note that this method may do two possible things: it may either fill in
+  /// the buffer specified with characters, or it may *change the input pointer*
+  /// to point to a constant buffer with the data already in it (avoiding a
+  /// copy).  The caller is not allowed to modify the returned buffer pointer
+  /// if an internal buffer is returned.
+  static unsigned getSpelling(const Token &Tok, const char *&Buffer, 
+                              const SourceManager &SourceMgr,
+                              const LangOptions &LangOpts,
+                              bool *Invalid = nullptr);
+  
+  /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
+  /// token is the characters used to represent the token in the source file
+  /// after trigraph expansion and escaped-newline folding.  In particular, this
+  /// wants to get the true, uncanonicalized, spelling of things like digraphs
+  /// UCNs, etc.
+  static std::string getSpelling(const Token &Tok,
+                                 const SourceManager &SourceMgr,
+                                 const LangOptions &LangOpts, 
+                                 bool *Invalid = nullptr);
+
+  /// getSpelling - This method is used to get the spelling of the
+  /// token at the given source location.  If, as is usually true, it
+  /// is not necessary to copy any data, then the returned string may
+  /// not point into the provided buffer.
+  ///
+  /// This method lexes at the expansion depth of the given
+  /// location and does not jump to the expansion or spelling
+  /// location.
+  static StringRef getSpelling(SourceLocation loc,
+                               SmallVectorImpl<char> &buffer,
+                               const SourceManager &SourceMgr,
+                               const LangOptions &LangOpts,
+                               bool *invalid = nullptr);
+  
+  /// MeasureTokenLength - Relex the token at the specified location and return
+  /// its length in bytes in the input file.  If the token needs cleaning (e.g.
+  /// includes a trigraph or an escaped newline) then this count includes bytes
+  /// that are part of that.
+  static unsigned MeasureTokenLength(SourceLocation Loc,
+                                     const SourceManager &SM,
+                                     const LangOptions &LangOpts);
+
+  /// \brief Relex the token at the specified location.
+  /// \returns true if there was a failure, false on success.
+  static bool getRawToken(SourceLocation Loc, Token &Result,
+                          const SourceManager &SM,
+                          const LangOptions &LangOpts,
+                          bool IgnoreWhiteSpace = false);
+
+  /// \brief Given a location any where in a source buffer, find the location
+  /// that corresponds to the beginning of the token in which the original
+  /// source location lands.
+  static SourceLocation GetBeginningOfToken(SourceLocation Loc,
+                                            const SourceManager &SM,
+                                            const LangOptions &LangOpts);
+  
+  /// AdvanceToTokenCharacter - If the current SourceLocation specifies a
+  /// location at the start of a token, return a new location that specifies a
+  /// character within the token.  This handles trigraphs and escaped newlines.
+  static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
+                                                unsigned Character,
+                                                const SourceManager &SM,
+                                                const LangOptions &LangOpts);
+  
+  /// \brief Computes the source location just past the end of the
+  /// token at this source location.
+  ///
+  /// This routine can be used to produce a source location that
+  /// points just past the end of the token referenced by \p Loc, and
+  /// is generally used when a diagnostic needs to point just after a
+  /// token where it expected something different that it received. If
+  /// the returned source location would not be meaningful (e.g., if
+  /// it points into a macro), this routine returns an invalid
+  /// source location.
+  ///
+  /// \param Offset an offset from the end of the token, where the source
+  /// location should refer to. The default offset (0) produces a source
+  /// location pointing just past the end of the token; an offset of 1 produces
+  /// a source location pointing to the last character in the token, etc.
+  static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
+                                            const SourceManager &SM,
+                                            const LangOptions &LangOpts);
+
+  /// \brief Returns true if the given MacroID location points at the first
+  /// token of the macro expansion.
+  ///
+  /// \param MacroBegin If non-null and function returns true, it is set to
+  /// begin location of the macro.
+  static bool isAtStartOfMacroExpansion(SourceLocation loc,
+                                        const SourceManager &SM,
+                                        const LangOptions &LangOpts,
+                                        SourceLocation *MacroBegin = nullptr);
+
+  /// \brief Returns true if the given MacroID location points at the last
+  /// token of the macro expansion.
+  ///
+  /// \param MacroEnd If non-null and function returns true, it is set to
+  /// end location of the macro.
+  static bool isAtEndOfMacroExpansion(SourceLocation loc,
+                                      const SourceManager &SM,
+                                      const LangOptions &LangOpts,
+                                      SourceLocation *MacroEnd = nullptr);
+
+  /// \brief Accepts a range and returns a character range with file locations.
+  ///
+  /// Returns a null range if a part of the range resides inside a macro
+  /// expansion or the range does not reside on the same FileID.
+  ///
+  /// This function is trying to deal with macros and return a range based on
+  /// file locations. The cases where it can successfully handle macros are:
+  ///
+  /// -begin or end range lies at the start or end of a macro expansion, in
+  ///  which case the location will be set to the expansion point, e.g:
+  ///    \#define M 1 2
+  ///    a M
+  /// If you have a range [a, 2] (where 2 came from the macro), the function
+  /// will return a range for "a M"
+  /// if you have range [a, 1], the function will fail because the range
+  /// overlaps with only a part of the macro
+  ///
+  /// -The macro is a function macro and the range can be mapped to the macro
+  ///  arguments, e.g:
+  ///    \#define M 1 2
+  ///    \#define FM(x) x
+  ///    FM(a b M)
+  /// if you have range [b, 2], the function will return the file range "b M"
+  /// inside the macro arguments.
+  /// if you have range [a, 2], the function will return the file range
+  /// "FM(a b M)" since the range includes all of the macro expansion.
+  static CharSourceRange makeFileCharRange(CharSourceRange Range,
+                                           const SourceManager &SM,
+                                           const LangOptions &LangOpts);
+
+  /// \brief Returns a string for the source that the range encompasses.
+  static StringRef getSourceText(CharSourceRange Range,
+                                 const SourceManager &SM,
+                                 const LangOptions &LangOpts,
+                                 bool *Invalid = nullptr);
+
+  /// \brief Retrieve the name of the immediate macro expansion.
+  ///
+  /// This routine starts from a source location, and finds the name of the macro
+  /// responsible for its immediate expansion. It looks through any intervening
+  /// macro argument expansions to compute this. It returns a StringRef which
+  /// refers to the SourceManager-owned buffer of the source where that macro
+  /// name is spelled. Thus, the result shouldn't out-live that SourceManager.
+  static StringRef getImmediateMacroName(SourceLocation Loc,
+                                         const SourceManager &SM,
+                                         const LangOptions &LangOpts);
+
+  /// \brief Compute the preamble of the given file.
+  ///
+  /// The preamble of a file contains the initial comments, include directives,
+  /// and other preprocessor directives that occur before the code in this
+  /// particular file actually begins. The preamble of the main source file is
+  /// a potential prefix header.
+  ///
+  /// \param Buffer The memory buffer containing the file's contents.
+  ///
+  /// \param MaxLines If non-zero, restrict the length of the preamble
+  /// to fewer than this number of lines.
+  ///
+  /// \returns The offset into the file where the preamble ends and the rest
+  /// of the file begins along with a boolean value indicating whether 
+  /// the preamble ends at the beginning of a new line.
+  static std::pair<unsigned, bool>
+  ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts,
+                  unsigned MaxLines = 0);
+
+  /// \brief Checks that the given token is the first token that occurs after
+  /// the given location (this excludes comments and whitespace). Returns the
+  /// location immediately after the specified token. If the token is not found
+  /// or the location is inside a macro, the returned source location will be
+  /// invalid.
+  static SourceLocation findLocationAfterToken(SourceLocation loc,
+                                         tok::TokenKind TKind,
+                                         const SourceManager &SM,
+                                         const LangOptions &LangOpts,
+                                         bool SkipTrailingWhitespaceAndNewLine);
+
+  /// \brief Returns true if the given character could appear in an identifier.
+  static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
+
+  /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
+  /// emit a warning.
+  static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
+                                          const LangOptions &LangOpts) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) {
+      Size = 1;
+      return *Ptr;
+    }
+
+    Size = 0;
+    return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Internal implementation interfaces.
+private:
+
+  /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
+  /// by Lex.
+  ///
+  bool LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine);
+
+  bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr);
+
+  /// Given that a token begins with the Unicode character \p C, figure out
+  /// what kind of token it is and dispatch to the appropriate lexing helper
+  /// function.
+  bool LexUnicode(Token &Result, uint32_t C, const char *CurPtr);
+
+  /// FormTokenWithChars - When we lex a token, we have identified a span
+  /// starting at BufferPtr, going to TokEnd that forms the token.  This method
+  /// takes that range and assigns it to the token as its location and size.  In
+  /// addition, since tokens cannot overlap, this also updates BufferPtr to be
+  /// TokEnd.
+  void FormTokenWithChars(Token &Result, const char *TokEnd,
+                          tok::TokenKind Kind) {
+    unsigned TokLen = TokEnd-BufferPtr;
+    Result.setLength(TokLen);
+    Result.setLocation(getSourceLocation(BufferPtr, TokLen));
+    Result.setKind(Kind);
+    BufferPtr = TokEnd;
+  }
+
+  /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
+  /// tok::l_paren token, 0 if it is something else and 2 if there are no more
+  /// tokens in the buffer controlled by this lexer.
+  unsigned isNextPPTokenLParen();
+
+  //===--------------------------------------------------------------------===//
+  // Lexer character reading interfaces.
+
+  // This lexer is built on two interfaces for reading characters, both of which
+  // automatically provide phase 1/2 translation.  getAndAdvanceChar is used
+  // when we know that we will be reading a character from the input buffer and
+  // that this character will be part of the result token. This occurs in (f.e.)
+  // string processing, because we know we need to read until we find the
+  // closing '"' character.
+  //
+  // The second interface is the combination of getCharAndSize with
+  // ConsumeChar.  getCharAndSize reads a phase 1/2 translated character,
+  // returning it and its size.  If the lexer decides that this character is
+  // part of the current token, it calls ConsumeChar on it.  This two stage
+  // approach allows us to emit diagnostics for characters (e.g. warnings about
+  // trigraphs), knowing that they only are emitted if the character is
+  // consumed.
+
+  /// isObviouslySimpleCharacter - Return true if the specified character is
+  /// obviously the same in translation phase 1 and translation phase 3.  This
+  /// can return false for characters that end up being the same, but it will
+  /// never return true for something that needs to be mapped.
+  static bool isObviouslySimpleCharacter(char C) {
+    return C != '?' && C != '\\';
+  }
+
+  /// getAndAdvanceChar - Read a single 'character' from the specified buffer,
+  /// advance over it, and return it.  This is tricky in several cases.  Here we
+  /// just handle the trivial case and fall-back to the non-inlined
+  /// getCharAndSizeSlow method to handle the hard case.
+  inline char getAndAdvanceChar(const char *&Ptr, Token &Tok) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++;
+
+    unsigned Size = 0;
+    char C = getCharAndSizeSlow(Ptr, Size, &Tok);
+    Ptr += Size;
+    return C;
+  }
+
+  /// ConsumeChar - When a character (identified by getCharAndSize) is consumed
+  /// and added to a given token, check to see if there are diagnostics that
+  /// need to be emitted or flags that need to be set on the token.  If so, do
+  /// it.
+  const char *ConsumeChar(const char *Ptr, unsigned Size, Token &Tok) {
+    // Normal case, we consumed exactly one token.  Just return it.
+    if (Size == 1)
+      return Ptr+Size;
+
+    // Otherwise, re-lex the character with a current token, allowing
+    // diagnostics to be emitted and flags to be set.
+    Size = 0;
+    getCharAndSizeSlow(Ptr, Size, &Tok);
+    return Ptr+Size;
+  }
+
+  /// getCharAndSize - Peek a single 'character' from the specified buffer,
+  /// get its size, and return it.  This is tricky in several cases.  Here we
+  /// just handle the trivial case and fall-back to the non-inlined
+  /// getCharAndSizeSlow method to handle the hard case.
+  inline char getCharAndSize(const char *Ptr, unsigned &Size) {
+    // If this is not a trigraph and not a UCN or escaped newline, return
+    // quickly.
+    if (isObviouslySimpleCharacter(Ptr[0])) {
+      Size = 1;
+      return *Ptr;
+    }
+
+    Size = 0;
+    return getCharAndSizeSlow(Ptr, Size);
+  }
+
+  /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
+  /// method.
+  char getCharAndSizeSlow(const char *Ptr, unsigned &Size,
+                          Token *Tok = nullptr);
+
+  /// getEscapedNewLineSize - Return the size of the specified escaped newline,
+  /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
+  /// to this function.
+  static unsigned getEscapedNewLineSize(const char *P);
+
+  /// SkipEscapedNewLines - If P points to an escaped newline (or a series of
+  /// them), skip over them and return the first non-escaped-newline found,
+  /// otherwise return P.
+  static const char *SkipEscapedNewLines(const char *P);
+
+  /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
+  /// diagnostic.
+  static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
+                                       const LangOptions &LangOpts);
+
+  //===--------------------------------------------------------------------===//
+  // Other lexer functions.
+
+  void SkipBytes(unsigned Bytes, bool StartOfLine);
+
+  void PropagateLineStartLeadingSpaceInfo(Token &Result);
+
+  const char *LexUDSuffix(Token &Result, const char *CurPtr,
+                          bool IsStringLiteral);
+
+  // Helper functions to lex the remainder of a token of the specific type.
+  bool LexIdentifier         (Token &Result, const char *CurPtr);
+  bool LexNumericConstant    (Token &Result, const char *CurPtr);
+  bool LexStringLiteral      (Token &Result, const char *CurPtr,
+                              tok::TokenKind Kind);
+  bool LexRawStringLiteral   (Token &Result, const char *CurPtr,
+                              tok::TokenKind Kind);
+  bool LexAngledStringLiteral(Token &Result, const char *CurPtr);
+  bool LexCharConstant       (Token &Result, const char *CurPtr,
+                              tok::TokenKind Kind);
+  bool LexEndOfFile          (Token &Result, const char *CurPtr);
+  bool SkipWhitespace        (Token &Result, const char *CurPtr,
+                              bool &TokAtPhysicalStartOfLine);
+  bool SkipLineComment       (Token &Result, const char *CurPtr,
+                              bool &TokAtPhysicalStartOfLine);
+  bool SkipBlockComment      (Token &Result, const char *CurPtr,
+                              bool &TokAtPhysicalStartOfLine);
+  bool SaveLineComment       (Token &Result, const char *CurPtr);
+  
+  bool IsStartOfConflictMarker(const char *CurPtr);
+  bool HandleEndOfConflictMarker(const char *CurPtr);
+
+  bool isCodeCompletionPoint(const char *CurPtr) const;
+  void cutOffLexing() { BufferPtr = BufferEnd; }
+
+  bool isHexaLiteral(const char *Start, const LangOptions &LangOpts);
+
+
+  /// Read a universal character name.
+  ///
+  /// \param CurPtr The position in the source buffer after the initial '\'.
+  ///               If the UCN is syntactically well-formed (but not necessarily
+  ///               valid), this parameter will be updated to point to the
+  ///               character after the UCN.
+  /// \param SlashLoc The position in the source buffer of the '\'.
+  /// \param Tok The token being formed. Pass \c NULL to suppress diagnostics
+  ///            and handle token formation in the caller.
+  ///
+  /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
+  ///         invalid.
+  uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
+
+  /// \brief Try to consume a UCN as part of an identifier at the current
+  /// location.
+  /// \param CurPtr Initially points to the range of characters in the source
+  ///               buffer containing the '\'. Updated to point past the end of
+  ///               the UCN on success.
+  /// \param Size The number of characters occupied by the '\' (including
+  ///             trigraphs and escaped newlines).
+  /// \param Result The token being produced. Marked as containing a UCN on
+  ///               success.
+  /// \return \c true if a UCN was lexed and it produced an acceptable
+  ///         identifier character, \c false otherwise.
+  bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
+                               Token &Result);
+
+  /// \brief Try to consume an identifier character encoded in UTF-8.
+  /// \param CurPtr Points to the start of the (potential) UTF-8 code unit
+  ///        sequence. On success, updated to point past the end of it.
+  /// \return \c true if a UTF-8 sequence mapping to an acceptable identifier
+  ///         character was lexed, \c false otherwise.
+  bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
new file mode 100644
index 0000000..b7fcc5d
--- /dev/null
+++ b/include/clang/Lex/LiteralSupport.h
@@ -0,0 +1,260 @@
+//===--- LiteralSupport.h ---------------------------------------*- 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 NumericLiteralParser, CharLiteralParser, and
+// StringLiteralParser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LITERALSUPPORT_H
+#define CLANG_LITERALSUPPORT_H
+
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+
+class DiagnosticsEngine;
+class Preprocessor;
+class Token;
+class SourceLocation;
+class TargetInfo;
+class SourceManager;
+class LangOptions;
+
+/// Copy characters from Input to Buf, expanding any UCNs.
+void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input);
+
+/// NumericLiteralParser - This performs strict semantic analysis of the content
+/// of a ppnumber, classifying it as either integer, floating, or erroneous,
+/// determines the radix of the value and can convert it to a useful value.
+class NumericLiteralParser {
+  Preprocessor &PP; // needed for diagnostics
+
+  const char *const ThisTokBegin;
+  const char *const ThisTokEnd;
+  const char *DigitsBegin, *SuffixBegin; // markers
+  const char *s; // cursor
+
+  unsigned radix;
+
+  bool saw_exponent, saw_period, saw_ud_suffix;
+
+  SmallString<32> UDSuffixBuf;
+
+public:
+  NumericLiteralParser(StringRef TokSpelling,
+                       SourceLocation TokLoc,
+                       Preprocessor &PP);
+  bool hadError;
+  bool isUnsigned;
+  bool isLong;        // This is *not* set for long long.
+  bool isLongLong;
+  bool isFloat;       // 1.0f
+  bool isImaginary;   // 1.0i
+  uint8_t MicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
+
+  bool isIntegerLiteral() const {
+    return !saw_period && !saw_exponent;
+  }
+  bool isFloatingLiteral() const {
+    return saw_period || saw_exponent;
+  }
+
+  bool hasUDSuffix() const {
+    return saw_ud_suffix;
+  }
+  StringRef getUDSuffix() const {
+    assert(saw_ud_suffix);
+    return UDSuffixBuf;
+  }
+  unsigned getUDSuffixOffset() const {
+    assert(saw_ud_suffix);
+    return SuffixBegin - ThisTokBegin;
+  }
+
+  static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix);
+
+  unsigned getRadix() const { return radix; }
+
+  /// GetIntegerValue - Convert this numeric literal value to an APInt that
+  /// matches Val's input width.  If there is an overflow (i.e., if the unsigned
+  /// value read is larger than the APInt's bits will hold), set Val to the low
+  /// bits of the result and return true.  Otherwise, return false.
+  bool GetIntegerValue(llvm::APInt &Val);
+
+  /// GetFloatValue - Convert this numeric literal to a floating value, using
+  /// the specified APFloat fltSemantics (specifying float, double, etc).
+  /// The optional bool isExact (passed-by-reference) has its value
+  /// set to true if the returned APFloat can represent the number in the
+  /// literal exactly, and false otherwise.
+  llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
+
+private:
+
+  void ParseNumberStartingWithZero(SourceLocation TokLoc);
+
+  static bool isDigitSeparator(char C) { return C == '\''; }
+
+  enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits };
+
+  /// \brief Ensure that we don't have a digit separator here.
+  void checkSeparator(SourceLocation TokLoc, const char *Pos,
+                      CheckSeparatorKind IsAfterDigits);
+
+  /// SkipHexDigits - Read and skip over any hex digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipHexDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr)))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipOctalDigits - Read and skip over any octal digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipOctalDigits(const char *ptr) {
+    while (ptr != ThisTokEnd &&
+           ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr)))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipDigits - Read and skip over any digits, up to End.
+  /// Return a pointer to the first non-hex digit or End.
+  const char *SkipDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr)))
+      ptr++;
+    return ptr;
+  }
+
+  /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
+  /// Return a pointer to the first non-binary digit or End.
+  const char *SkipBinaryDigits(const char *ptr) {
+    while (ptr != ThisTokEnd &&
+           (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr)))
+      ptr++;
+    return ptr;
+  }
+
+};
+
+/// CharLiteralParser - Perform interpretation and semantic analysis of a
+/// character literal.
+class CharLiteralParser {
+  uint64_t Value;
+  tok::TokenKind Kind;
+  bool IsMultiChar;
+  bool HadError;
+  SmallString<32> UDSuffixBuf;
+  unsigned UDSuffixOffset;
+public:
+  CharLiteralParser(const char *begin, const char *end,
+                    SourceLocation Loc, Preprocessor &PP,
+                    tok::TokenKind kind);
+
+  bool hadError() const { return HadError; }
+  bool isAscii() const { return Kind == tok::char_constant; }
+  bool isWide() const { return Kind == tok::wide_char_constant; }
+  bool isUTF16() const { return Kind == tok::utf16_char_constant; }
+  bool isUTF32() const { return Kind == tok::utf32_char_constant; }
+  bool isMultiChar() const { return IsMultiChar; }
+  uint64_t getValue() const { return Value; }
+  StringRef getUDSuffix() const { return UDSuffixBuf; }
+  unsigned getUDSuffixOffset() const {
+    assert(!UDSuffixBuf.empty() && "no ud-suffix");
+    return UDSuffixOffset;
+  }
+};
+
+/// StringLiteralParser - This decodes string escape characters and performs
+/// wide string analysis and Translation Phase #6 (concatenation of string
+/// literals) (C99 5.1.1.2p1).
+class StringLiteralParser {
+  const SourceManager &SM;
+  const LangOptions &Features;
+  const TargetInfo &Target;
+  DiagnosticsEngine *Diags;
+  
+  unsigned MaxTokenLength;
+  unsigned SizeBound;
+  unsigned CharByteWidth;
+  tok::TokenKind Kind;
+  SmallString<512> ResultBuf;
+  char *ResultPtr; // cursor
+  SmallString<32> UDSuffixBuf;
+  unsigned UDSuffixToken;
+  unsigned UDSuffixOffset;
+public:
+  StringLiteralParser(ArrayRef<Token> StringToks,
+                      Preprocessor &PP, bool Complain = true);
+  StringLiteralParser(ArrayRef<Token> StringToks,
+                      const SourceManager &sm, const LangOptions &features,
+                      const TargetInfo &target,
+                      DiagnosticsEngine *diags = nullptr)
+    : SM(sm), Features(features), Target(target), Diags(diags),
+      MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
+      ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
+    init(StringToks);
+  }
+    
+
+  bool hadError;
+  bool Pascal;
+
+  StringRef GetString() const {
+    return StringRef(ResultBuf.data(), GetStringLength());
+  }
+  unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); }
+
+  unsigned GetNumStringChars() const {
+    return GetStringLength() / CharByteWidth;
+  }
+  /// getOffsetOfStringByte - This function returns the offset of the
+  /// specified byte of the string data represented by Token.  This handles
+  /// advancing over escape sequences in the string.
+  ///
+  /// If the Diagnostics pointer is non-null, then this will do semantic
+  /// checking of the string literal and emit errors and warnings.
+  unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const;
+
+  bool isAscii() const { return Kind == tok::string_literal; }
+  bool isWide() const { return Kind == tok::wide_string_literal; }
+  bool isUTF8() const { return Kind == tok::utf8_string_literal; }
+  bool isUTF16() const { return Kind == tok::utf16_string_literal; }
+  bool isUTF32() const { return Kind == tok::utf32_string_literal; }
+  bool isPascal() const { return Pascal; }
+
+  StringRef getUDSuffix() const { return UDSuffixBuf; }
+
+  /// Get the index of a token containing a ud-suffix.
+  unsigned getUDSuffixToken() const {
+    assert(!UDSuffixBuf.empty() && "no ud-suffix");
+    return UDSuffixToken;
+  }
+  /// Get the spelling offset of the first byte of the ud-suffix.
+  unsigned getUDSuffixOffset() const {
+    assert(!UDSuffixBuf.empty() && "no ud-suffix");
+    return UDSuffixOffset;
+  }
+
+private:
+  void init(ArrayRef<Token> StringToks);
+  bool CopyStringFragment(const Token &Tok, const char *TokBegin,
+                          StringRef Fragment);
+  void DiagnoseLexingError(SourceLocation Loc);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
new file mode 100644
index 0000000..4c0120c
--- /dev/null
+++ b/include/clang/Lex/MacroArgs.h
@@ -0,0 +1,126 @@
+//===--- MacroArgs.h - Formal argument info for Macros ----------*- 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 MacroArgs interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROARGS_H
+#define LLVM_CLANG_MACROARGS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <vector>
+
+namespace clang {
+  class MacroInfo;
+  class Preprocessor;
+  class Token;
+  class SourceLocation;
+
+/// MacroArgs - An instance of this class captures information about
+/// the formal arguments specified to a function-like macro invocation.
+class MacroArgs {
+  /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
+  /// arguments.  All of the actual argument tokens are allocated immediately
+  /// after the MacroArgs object in memory.  This is all of the arguments
+  /// concatenated together, with 'EOF' markers at the end of each argument.
+  unsigned NumUnexpArgTokens;
+
+  /// VarargsElided - True if this is a C99 style varargs macro invocation and
+  /// there was no argument specified for the "..." argument.  If the argument
+  /// was specified (even empty) or this isn't a C99 style varargs function, or
+  /// if in strict mode and the C99 varargs macro had only a ... argument, this
+  /// is false.
+  bool VarargsElided;
+  
+  /// PreExpArgTokens - Pre-expanded tokens for arguments that need them.  Empty
+  /// if not yet computed.  This includes the EOF marker at the end of the
+  /// stream.
+  std::vector<std::vector<Token> > PreExpArgTokens;
+
+  /// StringifiedArgs - This contains arguments in 'stringified' form.  If the
+  /// stringified form of an argument has not yet been computed, this is empty.
+  std::vector<Token> StringifiedArgs;
+
+  /// ArgCache - This is a linked list of MacroArgs objects that the
+  /// Preprocessor owns which we use to avoid thrashing malloc/free.
+  MacroArgs *ArgCache;
+
+  MacroArgs(unsigned NumToks, bool varargsElided)
+    : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
+      ArgCache(nullptr) {}
+  ~MacroArgs() {}
+public:
+  /// MacroArgs ctor function - Create a new MacroArgs object with the specified
+  /// macro and argument info.
+  static MacroArgs *create(const MacroInfo *MI,
+                           ArrayRef<Token> UnexpArgTokens,
+                           bool VarargsElided, Preprocessor &PP);
+
+  /// destroy - Destroy and deallocate the memory for this object.
+  ///
+  void destroy(Preprocessor &PP);
+
+  /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
+  /// by pre-expansion, return false.  Otherwise, conservatively return true.
+  bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;
+
+  /// getUnexpArgument - Return a pointer to the first token of the unexpanded
+  /// token list for the specified formal.
+  ///
+  const Token *getUnexpArgument(unsigned Arg) const;
+
+  /// getArgLength - Given a pointer to an expanded or unexpanded argument,
+  /// return the number of tokens, not counting the EOF, that make up the
+  /// argument.
+  static unsigned getArgLength(const Token *ArgPtr);
+
+  /// getPreExpArgument - Return the pre-expanded form of the specified
+  /// argument.
+  const std::vector<Token> &
+    getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
+
+  /// getStringifiedArgument - Compute, cache, and return the specified argument
+  /// that has been 'stringified' as required by the # operator.
+  const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP,
+                                      SourceLocation ExpansionLocStart,
+                                      SourceLocation ExpansionLocEnd);
+
+  /// getNumArguments - Return the number of arguments passed into this macro
+  /// invocation.
+  unsigned getNumArguments() const { return NumUnexpArgTokens; }
+
+
+  /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
+  /// invocation and there was no argument specified for the "..." argument.  If
+  /// the argument was specified (even empty) or this isn't a C99 style varargs
+  /// function, or if in strict mode and the C99 varargs macro had only a ...
+  /// argument, this returns false.
+  bool isVarargsElidedUse() const { return VarargsElided; }
+
+  /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
+  /// tokens into the literal string token that should be produced by the C #
+  /// preprocessor operator.  If Charify is true, then it should be turned into
+  /// a character literal for the Microsoft charize (#@) extension.
+  ///
+  static Token StringifyArgument(const Token *ArgToks,
+                                 Preprocessor &PP, bool Charify,
+                                 SourceLocation ExpansionLocStart,
+                                 SourceLocation ExpansionLocEnd);
+  
+  
+  /// deallocate - This should only be called by the Preprocessor when managing
+  /// its freelist.
+  MacroArgs *deallocate();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
new file mode 100644
index 0000000..e9a66e8
--- /dev/null
+++ b/include/clang/Lex/MacroInfo.h
@@ -0,0 +1,549 @@
+//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROINFO_H
+#define LLVM_CLANG_MACROINFO_H
+
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
+
+namespace clang {
+class Preprocessor;
+
+/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
+///
+/// There's an instance of this class for every #define.
+class MacroInfo {
+  //===--------------------------------------------------------------------===//
+  // State set when the macro is defined.
+
+  /// \brief The location the macro is defined.
+  SourceLocation Location;
+  /// \brief The location of the last token in the macro.
+  SourceLocation EndLocation;
+
+  /// \brief The list of arguments for a function-like macro.
+  ///
+  /// ArgumentList points to the first of NumArguments pointers.
+  ///
+  /// This can be empty, for, e.g. "#define X()".  In a C99-style variadic macro, this
+  /// includes the \c __VA_ARGS__ identifier on the list.
+  IdentifierInfo **ArgumentList;
+
+  /// \see ArgumentList
+  unsigned NumArguments;
+  
+  /// \brief This is the list of tokens that the macro is defined to.
+  SmallVector<Token, 8> ReplacementTokens;
+
+  /// \brief Length in characters of the macro definition.
+  mutable unsigned DefinitionLength;
+  mutable bool IsDefinitionLengthCached : 1;
+
+  /// \brief True if this macro is function-like, false if it is object-like.
+  bool IsFunctionLike : 1;
+
+  /// \brief True if this macro is of the form "#define X(...)" or
+  /// "#define X(Y,Z,...)".
+  ///
+  /// The __VA_ARGS__ token should be replaced with the contents of "..." in an
+  /// invocation.
+  bool IsC99Varargs : 1;
+
+  /// \brief True if this macro is of the form "#define X(a...)".
+  ///
+  /// The "a" identifier in the replacement list will be replaced with all arguments
+  /// of the macro starting with the specified one.
+  bool IsGNUVarargs : 1;
+
+  /// \brief True if this macro requires processing before expansion.
+  ///
+  /// This is the case for builtin macros such as __LINE__, so long as they have
+  /// not been redefined, but not for regular predefined macros from the "<built-in>"
+  /// memory buffer (see Preprocessing::getPredefinesFileID).
+  bool IsBuiltinMacro : 1;
+
+  /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__"
+  bool HasCommaPasting : 1;
+  
+private:
+  //===--------------------------------------------------------------------===//
+  // State that changes as the macro is used.
+
+  /// \brief True if we have started an expansion of this macro already.
+  ///
+  /// This disables recursive expansion, which would be quite bad for things
+  /// like \#define A A.
+  bool IsDisabled : 1;
+
+  /// \brief True if this macro is either defined in the main file and has
+  /// been used, or if it is not defined in the main file.
+  ///
+  /// This is used to emit -Wunused-macros diagnostics.
+  bool IsUsed : 1;
+
+  /// \brief True if this macro can be redefined without emitting a warning.
+  bool IsAllowRedefinitionsWithoutWarning : 1;
+
+  /// \brief Must warn if the macro is unused at the end of translation unit.
+  bool IsWarnIfUnused : 1;
+
+  /// \brief Whether this macro info was loaded from an AST file.
+  unsigned FromASTFile : 1;
+
+  /// \brief Whether this macro was used as header guard.
+  bool UsedForHeaderGuard : 1;
+
+  ~MacroInfo() {
+    assert(!ArgumentList && "Didn't call destroy before dtor!");
+  }
+
+public:
+  MacroInfo(SourceLocation DefLoc);
+  
+  /// \brief Free the argument list of the macro.
+  ///
+  /// This restores this MacroInfo to a state where it can be reused for other
+  /// devious purposes.
+  void FreeArgumentList() {
+    ArgumentList = nullptr;
+    NumArguments = 0;
+  }
+
+  /// \brief Destroy this MacroInfo object.
+  void Destroy() {
+    FreeArgumentList();
+    this->~MacroInfo();
+  }
+
+  /// \brief Return the location that the macro was defined at.
+  SourceLocation getDefinitionLoc() const { return Location; }
+
+  /// \brief Set the location of the last token in the macro.
+  void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; }
+
+  /// \brief Return the location of the last token in the macro.
+  SourceLocation getDefinitionEndLoc() const { return EndLocation; }
+
+  /// \brief Get length in characters of the macro definition.
+  unsigned getDefinitionLength(SourceManager &SM) const {
+    if (IsDefinitionLengthCached)
+      return DefinitionLength;
+    return getDefinitionLengthSlow(SM);
+  }
+
+  /// \brief Return true if the specified macro definition is equal to
+  /// this macro in spelling, arguments, and whitespace.
+  ///
+  /// \param Syntactically if true, the macro definitions can be identical even
+  /// if they use different identifiers for the function macro parameters.
+  /// Otherwise the comparison is lexical and this implements the rules in
+  /// C99 6.10.3.
+  bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
+                     bool Syntactically) const;
+
+  /// \brief Set or clear the isBuiltinMacro flag.
+  void setIsBuiltinMacro(bool Val = true) {
+    IsBuiltinMacro = Val;
+  }
+
+  /// \brief Set the value of the IsUsed flag.
+  void setIsUsed(bool Val) {
+    IsUsed = Val;
+  }
+
+  /// \brief Set the value of the IsAllowRedefinitionsWithoutWarning flag.
+  void setIsAllowRedefinitionsWithoutWarning(bool Val) {
+    IsAllowRedefinitionsWithoutWarning = Val;
+  }
+
+  /// \brief Set the value of the IsWarnIfUnused flag.
+  void setIsWarnIfUnused(bool val) {
+    IsWarnIfUnused = val;
+  }
+
+  /// \brief Set the specified list of identifiers as the argument list for
+  /// this macro.
+  void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
+                       llvm::BumpPtrAllocator &PPAllocator) {
+    assert(ArgumentList == nullptr && NumArguments == 0 &&
+           "Argument list already set!");
+    if (NumArgs == 0) return;
+
+    NumArguments = NumArgs;
+    ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs);
+    for (unsigned i = 0; i != NumArgs; ++i)
+      ArgumentList[i] = List[i];
+  }
+
+  /// Arguments - The list of arguments for a function-like macro.  This can be
+  /// empty, for, e.g. "#define X()".
+  typedef IdentifierInfo* const *arg_iterator;
+  bool arg_empty() const { return NumArguments == 0; }
+  arg_iterator arg_begin() const { return ArgumentList; }
+  arg_iterator arg_end() const { return ArgumentList+NumArguments; }
+  unsigned getNumArgs() const { return NumArguments; }
+
+  /// \brief Return the argument number of the specified identifier,
+  /// or -1 if the identifier is not a formal argument identifier.
+  int getArgumentNum(IdentifierInfo *Arg) const {
+    for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+      if (*I == Arg) return I-arg_begin();
+    return -1;
+  }
+
+  /// Function/Object-likeness.  Keep track of whether this macro has formal
+  /// parameters.
+  void setIsFunctionLike() { IsFunctionLike = true; }
+  bool isFunctionLike() const { return IsFunctionLike; }
+  bool isObjectLike() const { return !IsFunctionLike; }
+
+  /// Varargs querying methods.  This can only be set for function-like macros.
+  void setIsC99Varargs() { IsC99Varargs = true; }
+  void setIsGNUVarargs() { IsGNUVarargs = true; }
+  bool isC99Varargs() const { return IsC99Varargs; }
+  bool isGNUVarargs() const { return IsGNUVarargs; }
+  bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
+
+  /// \brief Return true if this macro requires processing before expansion.
+  ///
+  /// This is true only for builtin macro, such as \__LINE__, whose values
+  /// are not given by fixed textual expansions.  Regular predefined macros
+  /// from the "<built-in>" buffer are not reported as builtins by this
+  /// function.
+  bool isBuiltinMacro() const { return IsBuiltinMacro; }
+
+  bool hasCommaPasting() const { return HasCommaPasting; }
+  void setHasCommaPasting() { HasCommaPasting = true; }
+
+  /// \brief Return false if this macro is defined in the main file and has
+  /// not yet been used.
+  bool isUsed() const { return IsUsed; }
+
+  /// \brief Return true if this macro can be redefined without warning.
+  bool isAllowRedefinitionsWithoutWarning() const {
+    return IsAllowRedefinitionsWithoutWarning;
+  }
+
+  /// \brief Return true if we should emit a warning if the macro is unused.
+  bool isWarnIfUnused() const {
+    return IsWarnIfUnused;
+  }
+
+  /// \brief Return the number of tokens that this macro expands to.
+  ///
+  unsigned getNumTokens() const {
+    return ReplacementTokens.size();
+  }
+
+  const Token &getReplacementToken(unsigned Tok) const {
+    assert(Tok < ReplacementTokens.size() && "Invalid token #");
+    return ReplacementTokens[Tok];
+  }
+
+  typedef SmallVectorImpl<Token>::const_iterator tokens_iterator;
+  tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
+  tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
+  bool tokens_empty() const { return ReplacementTokens.empty(); }
+
+  /// \brief Add the specified token to the replacement text for the macro.
+  void AddTokenToBody(const Token &Tok) {
+    assert(!IsDefinitionLengthCached &&
+          "Changing replacement tokens after definition length got calculated");
+    ReplacementTokens.push_back(Tok);
+  }
+
+  /// \brief Return true if this macro is enabled.
+  ///
+  /// In other words, that we are not currently in an expansion of this macro.
+  bool isEnabled() const { return !IsDisabled; }
+
+  void EnableMacro() {
+    assert(IsDisabled && "Cannot enable an already-enabled macro!");
+    IsDisabled = false;
+  }
+
+  void DisableMacro() {
+    assert(!IsDisabled && "Cannot disable an already-disabled macro!");
+    IsDisabled = true;
+  }
+
+  /// \brief Determine whether this macro info came from an AST file (such as
+  /// a precompiled header or module) rather than having been parsed.
+  bool isFromASTFile() const { return FromASTFile; }
+
+  /// \brief Determine whether this macro was used for a header guard.
+  bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
+
+  void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
+
+  /// \brief Retrieve the global ID of the module that owns this particular
+  /// macro info.
+  unsigned getOwningModuleID() const {
+    if (isFromASTFile())
+      return *(const unsigned*)(this+1);
+
+    return 0;
+  }
+
+  void dump() const;
+
+private:
+  unsigned getDefinitionLengthSlow(SourceManager &SM) const;
+
+  void setOwningModuleID(unsigned ID) {
+    assert(isFromASTFile());
+    *(unsigned*)(this+1) = ID;
+  }
+
+  friend class Preprocessor;
+};
+
+class DefMacroDirective;
+
+/// \brief Encapsulates changes to the "macros namespace" (the location where
+/// the macro name became active, the location where it was undefined, etc.).
+///
+/// MacroDirectives, associated with an identifier, are used to model the macro
+/// history. Usually a macro definition (MacroInfo) is where a macro name
+/// becomes active (MacroDirective) but modules can have their own macro
+/// history, separate from the local (current translation unit) macro history.
+///
+/// For example, if "@import A;" imports macro FOO, there will be a new local
+/// MacroDirective created to indicate that "FOO" became active at the import
+/// location. Module "A" itself will contain another MacroDirective in its macro
+/// history (at the point of the definition of FOO) and both MacroDirectives
+/// will point to the same MacroInfo object.
+///
+class MacroDirective {
+public:
+  enum Kind {
+    MD_Define,
+    MD_Undefine,
+    MD_Visibility
+  };
+
+protected:
+  /// \brief Previous macro directive for the same identifier, or NULL.
+  MacroDirective *Previous;
+
+  SourceLocation Loc;
+
+  /// \brief MacroDirective kind.
+  unsigned MDKind : 2;
+
+  /// \brief True if the macro directive was loaded from a PCH file.
+  bool IsFromPCH : 1;
+
+  // Used by DefMacroDirective -----------------------------------------------//
+
+  /// \brief True if this macro was imported from a module.
+  bool IsImported : 1;
+
+  /// \brief Whether the definition of this macro is ambiguous, due to
+  /// multiple definitions coming in from multiple modules.
+  bool IsAmbiguous : 1;
+
+  // Used by VisibilityMacroDirective ----------------------------------------//
+
+  /// \brief Whether the macro has public visibility (when described in a
+  /// module).
+  bool IsPublic : 1;
+
+  MacroDirective(Kind K, SourceLocation Loc)
+    : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
+      IsImported(false), IsAmbiguous(false),
+      IsPublic(true) {
+  } 
+
+public:
+  Kind getKind() const { return Kind(MDKind); }
+
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Set previous definition of the macro with the same name.
+  void setPrevious(MacroDirective *Prev) {
+    Previous = Prev;
+  }
+
+  /// \brief Get previous definition of the macro with the same name.
+  const MacroDirective *getPrevious() const { return Previous; }
+
+  /// \brief Get previous definition of the macro with the same name.
+  MacroDirective *getPrevious() { return Previous; }
+
+  /// \brief Return true if the macro directive was loaded from a PCH file.
+  bool isFromPCH() const { return IsFromPCH; }
+
+  void setIsFromPCH() { IsFromPCH = true; }
+
+  class DefInfo {
+    DefMacroDirective *DefDirective;
+    SourceLocation UndefLoc;
+    bool IsPublic;
+
+  public:
+    DefInfo() : DefDirective(nullptr) { }
+
+    DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
+            bool isPublic)
+      : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
+
+    const DefMacroDirective *getDirective() const { return DefDirective; }
+          DefMacroDirective *getDirective()       { return DefDirective; }
+
+    inline SourceLocation getLocation() const;
+    inline MacroInfo *getMacroInfo();
+    const MacroInfo *getMacroInfo() const {
+      return const_cast<DefInfo*>(this)->getMacroInfo();
+    }
+
+    SourceLocation getUndefLocation() const { return UndefLoc; }
+    bool isUndefined() const { return UndefLoc.isValid(); }
+
+    bool isPublic() const { return IsPublic; }
+
+    bool isValid() const { return DefDirective != nullptr; }
+    bool isInvalid() const { return !isValid(); }
+
+    LLVM_EXPLICIT operator bool() const { return isValid(); }
+
+    inline DefInfo getPreviousDefinition();
+    const DefInfo getPreviousDefinition() const {
+      return const_cast<DefInfo*>(this)->getPreviousDefinition();
+    }
+  };
+
+  /// \brief Traverses the macro directives history and returns the next
+  /// macro definition directive along with info about its undefined location
+  /// (if there is one) and if it is public or private.
+  DefInfo getDefinition();
+  const DefInfo getDefinition() const {
+    return const_cast<MacroDirective*>(this)->getDefinition();
+  }
+
+  bool isDefined() const {
+    if (const DefInfo Def = getDefinition())
+      return !Def.isUndefined();
+    return false;
+  }
+
+  const MacroInfo *getMacroInfo() const {
+    return getDefinition().getMacroInfo();
+  }
+  MacroInfo *getMacroInfo() {
+    return getDefinition().getMacroInfo();
+  }
+
+  /// \brief Find macro definition active in the specified source location. If
+  /// this macro was not defined there, return NULL.
+  const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+
+  void dump() const;
+
+  static bool classof(const MacroDirective *) { return true; }
+};
+
+/// \brief A directive for a defined macro or a macro imported from a module.
+class DefMacroDirective : public MacroDirective {
+  MacroInfo *Info;
+
+public:
+  explicit DefMacroDirective(MacroInfo *MI)
+    : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+    assert(MI && "MacroInfo is null");
+  }
+
+  DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
+    : MacroDirective(MD_Define, Loc), Info(MI) {
+    assert(MI && "MacroInfo is null");
+    IsImported = isImported;
+  }
+
+  /// \brief The data for the macro definition.
+  const MacroInfo *getInfo() const { return Info; }
+  MacroInfo *getInfo() { return Info; }
+
+  /// \brief True if this macro was imported from a module.
+  bool isImported() const { return IsImported; }
+
+  /// \brief Determine whether this macro definition is ambiguous with
+  /// other macro definitions.
+  bool isAmbiguous() const { return IsAmbiguous; }
+
+  /// \brief Set whether this macro definition is ambiguous.
+  void setAmbiguous(bool Val) { IsAmbiguous = Val; }
+
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Define;
+  }
+  static bool classof(const DefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for an undefined macro.
+class UndefMacroDirective : public MacroDirective  {
+public:
+  explicit UndefMacroDirective(SourceLocation UndefLoc)
+    : MacroDirective(MD_Undefine, UndefLoc) {
+    assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+  }
+
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Undefine;
+  }
+  static bool classof(const UndefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for setting the module visibility of a macro.
+class VisibilityMacroDirective : public MacroDirective  {
+public:
+  explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
+    : MacroDirective(MD_Visibility, Loc) {
+    IsPublic = Public;
+  }
+
+  /// \brief Determine whether this macro is part of the public API of its
+  /// module.
+  bool isPublic() const { return IsPublic; }
+
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Visibility;
+  }
+  static bool classof(const VisibilityMacroDirective *) { return true; }
+};
+
+inline SourceLocation MacroDirective::DefInfo::getLocation() const {
+  if (isInvalid())
+    return SourceLocation();
+  return DefDirective->getLocation();
+}
+
+inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
+  if (isInvalid())
+    return nullptr;
+  return DefDirective->getInfo();
+}
+
+inline MacroDirective::DefInfo
+MacroDirective::DefInfo::getPreviousDefinition() {
+  if (isInvalid() || DefDirective->getPrevious() == nullptr)
+    return DefInfo();
+  return DefDirective->getPrevious()->getDefinition();
+}
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
new file mode 100644
index 0000000..7869799
--- /dev/null
+++ b/include/clang/Lex/ModuleLoader.h
@@ -0,0 +1,130 @@
+//===--- ModuleLoader.h - Module Loader Interface ---------------*- 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 ModuleLoader interface, which is responsible for 
+//  loading named modules.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_MODULE_LOADER_H
+#define LLVM_CLANG_LEX_MODULE_LOADER_H
+
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+class GlobalModuleIndex;
+class IdentifierInfo;
+class Module;
+
+/// \brief A sequence of identifier/location pairs used to describe a particular
+/// module or submodule, e.g., std.vector.
+typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation> > ModuleIdPath;
+
+/// \brief Describes the result of attempting to load a module.
+class ModuleLoadResult {
+  llvm::PointerIntPair<Module *, 1, bool> Storage;
+
+public:
+  ModuleLoadResult() : Storage() { }
+
+  ModuleLoadResult(Module *module, bool missingExpected)
+    : Storage(module, missingExpected) { }
+
+  operator Module *() const { return Storage.getPointer(); }
+
+  /// \brief Determines whether the module, which failed to load, was
+  /// actually a submodule that we expected to see (based on implying the
+  /// submodule from header structure), but didn't materialize in the actual
+  /// module.
+  bool isMissingExpected() const { return Storage.getInt(); }
+};
+
+/// \brief Abstract interface for a module loader.
+///
+/// This abstract interface describes a module loader, which is responsible
+/// for resolving a module name (e.g., "std") to an actual module file, and
+/// then loading that module.
+class ModuleLoader {
+  // Building a module if true.
+  bool BuildingModule;
+public:
+  explicit ModuleLoader(bool BuildingModule = false) :
+    BuildingModule(BuildingModule),
+    HadFatalFailure(false) {}
+
+  virtual ~ModuleLoader();
+  
+  /// \brief Returns true if this instance is building a module.
+  bool buildingModule() const {
+    return BuildingModule;
+  }
+  /// \brief Flag indicating whether this instance is building a module.
+  void setBuildingModule(bool BuildingModuleFlag) {
+    BuildingModule = BuildingModuleFlag;
+  }
+ 
+  /// \brief Attempt to load the given module.
+  ///
+  /// This routine attempts to load the module described by the given 
+  /// parameters.
+  ///
+  /// \param ImportLoc The location of the 'import' keyword.
+  ///
+  /// \param Path The identifiers (and their locations) of the module
+  /// "path", e.g., "std.vector" would be split into "std" and "vector".
+  /// 
+  /// \param Visibility The visibility provided for the names in the loaded
+  /// module.
+  ///
+  /// \param IsInclusionDirective Indicates that this module is being loaded
+  /// implicitly, due to the presence of an inclusion directive. Otherwise,
+  /// it is being loaded due to an import declaration.
+  ///
+  /// \returns If successful, returns the loaded module. Otherwise, returns 
+  /// NULL to indicate that the module could not be loaded.
+  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
+                                      ModuleIdPath Path,
+                                      Module::NameVisibilityKind Visibility,
+                                      bool IsInclusionDirective) = 0;
+
+  /// \brief Make the given module visible.
+  virtual void makeModuleVisible(Module *Mod,
+                                 Module::NameVisibilityKind Visibility,
+                                 SourceLocation ImportLoc,
+                                 bool Complain) = 0;
+
+  /// \brief Load, create, or return global module.
+  /// This function returns an existing global module index, if one
+  /// had already been loaded or created, or loads one if it
+  /// exists, or creates one if it doesn't exist.
+  /// Also, importantly, if the index doesn't cover all the modules
+  /// in the module map, it will be update to do so here, because
+  /// of its use in searching for needed module imports and
+  /// associated fixit messages.
+  /// \param TriggerLoc The location for what triggered the load.
+  /// \returns Returns null if load failed.
+  virtual GlobalModuleIndex *loadGlobalModuleIndex(
+                                                SourceLocation TriggerLoc) = 0;
+
+  /// Check global module index for missing imports.
+  /// \param Name The symbol name to look for.
+  /// \param TriggerLoc The location for what triggered the load.
+  /// \returns Returns true if any modules with that symbol found.
+  virtual bool lookupMissingImports(StringRef Name,
+                                    SourceLocation TriggerLoc) = 0;
+
+  bool HadFatalFailure;
+};
+  
+}
+
+#endif
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
new file mode 100644
index 0000000..a86a927
--- /dev/null
+++ b/include/clang/Lex/ModuleMap.h
@@ -0,0 +1,427 @@
+//===--- ModuleMap.h - Describe the layout of modules -----------*- 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 ModuleMap interface, which describes the layout of a
+// module as it relates to headers.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_LEX_MODULEMAP_H
+#define LLVM_CLANG_LEX_MODULEMAP_H
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace clang {
+  
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+class DiagnosticConsumer;
+class DiagnosticsEngine;
+class HeaderSearch;
+class ModuleMapParser;
+  
+class ModuleMap {
+  SourceManager &SourceMgr;
+  DiagnosticsEngine &Diags;
+  const LangOptions &LangOpts;
+  const TargetInfo *Target;
+  HeaderSearch &HeaderInfo;
+  
+  /// \brief The directory used for Clang-supplied, builtin include headers,
+  /// such as "stdint.h".
+  const DirectoryEntry *BuiltinIncludeDir;
+  
+  /// \brief Language options used to parse the module map itself.
+  ///
+  /// These are always simple C language options.
+  LangOptions MMapLangOpts;
+
+  // The module that we are building; related to \c LangOptions::CurrentModule.
+  Module *CompilingModule;
+
+public:
+  // The module that the .cc source file is associated with.
+  Module *SourceModule;
+  std::string SourceModuleName;
+
+private:
+  /// \brief The top-level modules that are known.
+  llvm::StringMap<Module *> Modules;
+
+public:
+  /// \brief Describes the role of a module header.
+  enum ModuleHeaderRole {
+    /// \brief This header is normally included in the module.
+    NormalHeader,
+    /// \brief This header is included but private.
+    PrivateHeader,
+    /// \brief This header is explicitly excluded from the module.
+    ExcludedHeader
+    // Caution: Adding an enumerator needs other changes.
+    // Adjust the number of bits for KnownHeader::Storage.
+    // Adjust the bitfield HeaderFileInfo::HeaderRole size.
+    // Adjust the HeaderFileInfoTrait::ReadData streaming.
+    // Adjust the HeaderFileInfoTrait::EmitData streaming.
+  };
+
+  /// \brief A header that is known to reside within a given module,
+  /// whether it was included or excluded.
+  class KnownHeader {
+    llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
+
+  public:
+    KnownHeader() : Storage(nullptr, NormalHeader) { }
+    KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
+
+    /// \brief Retrieve the module the header is stored in.
+    Module *getModule() const { return Storage.getPointer(); }
+
+    /// \brief The role of this header within the module.
+    ModuleHeaderRole getRole() const { return Storage.getInt(); }
+
+    /// \brief Whether this header is available in the module.
+    bool isAvailable() const { 
+      return getRole() != ExcludedHeader && getModule()->isAvailable(); 
+    }
+
+    // \brief Whether this known header is valid (i.e., it has an
+    // associated module).
+    LLVM_EXPLICIT operator bool() const {
+      return Storage.getPointer() != nullptr;
+    }
+  };
+
+private:
+  typedef llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1> >
+  HeadersMap;
+
+  /// \brief Mapping from each header to the module that owns the contents of
+  /// that header.
+  HeadersMap Headers;
+  
+  /// \brief Mapping from directories with umbrella headers to the module
+  /// that is generated from the umbrella header.
+  ///
+  /// This mapping is used to map headers that haven't explicitly been named
+  /// in the module map over to the module that includes them via its umbrella
+  /// header.
+  llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
+
+  /// \brief A directory for which framework modules can be inferred.
+  struct InferredDirectory {
+    InferredDirectory() : InferModules(), InferSystemModules() { }
+
+    /// \brief Whether to infer modules from this directory.
+    unsigned InferModules : 1;
+
+    /// \brief Whether the modules we infer are [system] modules.
+    unsigned InferSystemModules : 1;
+
+    /// \brief If \c InferModules is non-zero, the module map file that allowed
+    /// inferred modules.  Otherwise, nullptr.
+    const FileEntry *ModuleMapFile;
+
+    /// \brief The names of modules that cannot be inferred within this
+    /// directory.
+    SmallVector<std::string, 2> ExcludedModules;
+  };
+
+  /// \brief A mapping from directories to information about inferring
+  /// framework modules from within those directories.
+  llvm::DenseMap<const DirectoryEntry *, InferredDirectory> InferredDirectories;
+
+  /// \brief Describes whether we haved parsed a particular file as a module
+  /// map.
+  llvm::DenseMap<const FileEntry *, bool> ParsedModuleMap;
+
+  friend class ModuleMapParser;
+  
+  /// \brief Resolve the given export declaration into an actual export
+  /// declaration.
+  ///
+  /// \param Mod The module in which we're resolving the export declaration.
+  ///
+  /// \param Unresolved The export declaration to resolve.
+  ///
+  /// \param Complain Whether this routine should complain about unresolvable
+  /// exports.
+  ///
+  /// \returns The resolved export declaration, which will have a NULL pointer
+  /// if the export could not be resolved.
+  Module::ExportDecl 
+  resolveExport(Module *Mod, const Module::UnresolvedExportDecl &Unresolved,
+                bool Complain) const;
+
+  /// \brief Resolve the given module id to an actual module.
+  ///
+  /// \param Id The module-id to resolve.
+  ///
+  /// \param Mod The module in which we're resolving the module-id.
+  ///
+  /// \param Complain Whether this routine should complain about unresolvable
+  /// module-ids.
+  ///
+  /// \returns The resolved module, or null if the module-id could not be
+  /// resolved.
+  Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
+
+  /// \brief Looks up the modules that \p File corresponds to.
+  ///
+  /// If \p File represents a builtin header within Clang's builtin include
+  /// directory, this also loads all of the module maps to see if it will get
+  /// associated with a specific module (e.g. in /usr/include).
+  HeadersMap::iterator findKnownHeader(const FileEntry *File);
+
+  /// \brief Searches for a module whose umbrella directory contains \p File.
+  ///
+  /// \param File The header to search for.
+  ///
+  /// \param IntermediateDirs On success, contains the set of directories
+  /// searched before finding \p File.
+  KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
+                    SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
+
+  /// \brief A convenience method to determine if \p File is (possibly nested)
+  /// in an umbrella directory.
+  bool isHeaderInUmbrellaDirs(const FileEntry *File) {
+    SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
+    return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
+  }
+
+public:
+  /// \brief Construct a new module map.
+  ///
+  /// \param SourceMgr The source manager used to find module files and headers.
+  /// This source manager should be shared with the header-search mechanism,
+  /// since they will refer to the same headers.
+  ///
+  /// \param Diags A diagnostic engine used for diagnostics.
+  ///
+  /// \param LangOpts Language options for this translation unit.
+  ///
+  /// \param Target The target for this translation unit.
+  ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+            const LangOptions &LangOpts, const TargetInfo *Target,
+            HeaderSearch &HeaderInfo);
+
+  /// \brief Destroy the module map.
+  ///
+  ~ModuleMap();
+
+  /// \brief Set the target information.
+  void setTarget(const TargetInfo &Target);
+
+  /// \brief Set the directory that contains Clang-supplied include
+  /// files, such as our stdarg.h or tgmath.h.
+  void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
+    BuiltinIncludeDir = Dir;
+  }
+
+  /// \brief Retrieve the module that owns the given header file, if any.
+  ///
+  /// \param File The header file that is likely to be included.
+  ///
+  /// \param RequestingModule Specifies the module the header is intended to be
+  /// used from.  Used to disambiguate if a header is present in multiple
+  /// modules.
+  ///
+  /// \returns The module KnownHeader, which provides the module that owns the
+  /// given header file.  The KnownHeader is default constructed to indicate
+  /// that no module owns this header file.
+  KnownHeader findModuleForHeader(const FileEntry *File,
+                                  Module *RequestingModule = nullptr);
+
+  /// \brief Reports errors if a module must not include a specific file.
+  ///
+  /// \param RequestingModule The module including a file.
+  ///
+  /// \param FilenameLoc The location of the inclusion's filename.
+  ///
+  /// \param Filename The included filename as written.
+  ///
+  /// \param File The included file.
+  void diagnoseHeaderInclusion(Module *RequestingModule,
+                               SourceLocation FilenameLoc, StringRef Filename,
+                               const FileEntry *File);
+
+  /// \brief Determine whether the given header is part of a module
+  /// marked 'unavailable'.
+  bool isHeaderInUnavailableModule(const FileEntry *Header) const;
+
+  /// \brief Determine whether the given header is unavailable as part
+  /// of the specified module.
+  bool isHeaderUnavailableInModule(const FileEntry *Header,
+                                   const Module *RequestingModule) const;
+
+  /// \brief Retrieve a module with the given name.
+  ///
+  /// \param Name The name of the module to look up.
+  ///
+  /// \returns The named module, if known; otherwise, returns null.
+  Module *findModule(StringRef Name) const;
+
+  /// \brief Retrieve a module with the given name using lexical name lookup,
+  /// starting at the given context.
+  ///
+  /// \param Name The name of the module to look up.
+  ///
+  /// \param Context The module context, from which we will perform lexical
+  /// name lookup.
+  ///
+  /// \returns The named module, if known; otherwise, returns null.
+  Module *lookupModuleUnqualified(StringRef Name, Module *Context) const;
+
+  /// \brief Retrieve a module with the given name within the given context,
+  /// using direct (qualified) name lookup.
+  ///
+  /// \param Name The name of the module to look up.
+  /// 
+  /// \param Context The module for which we will look for a submodule. If
+  /// null, we will look for a top-level module.
+  ///
+  /// \returns The named submodule, if known; otherwose, returns null.
+  Module *lookupModuleQualified(StringRef Name, Module *Context) const;
+  
+  /// \brief Find a new module or submodule, or create it if it does not already
+  /// exist.
+  ///
+  /// \param Name The name of the module to find or create.
+  ///
+  /// \param Parent The module that will act as the parent of this submodule,
+  /// or NULL to indicate that this is a top-level module.
+  ///
+  /// \param ModuleMap The module map that defines or allows the inference of
+  /// this module.
+  ///
+  /// \param IsFramework Whether this is a framework module.
+  ///
+  /// \param IsExplicit Whether this is an explicit submodule.
+  ///
+  /// \returns The found or newly-created module, along with a boolean value
+  /// that will be true if the module is newly-created.
+  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
+                                               const FileEntry *ModuleMap,
+                                               bool IsFramework,
+                                               bool IsExplicit);
+
+  /// \brief Determine whether we can infer a framework module a framework
+  /// with the given name in the given
+  ///
+  /// \param ParentDir The directory that is the parent of the framework
+  /// directory.
+  ///
+  /// \param Name The name of the module.
+  ///
+  /// \param IsSystem Will be set to 'true' if the inferred module must be a
+  /// system module.
+  ///
+  /// \returns true if we are allowed to infer a framework module, and false
+  /// otherwise.
+  bool canInferFrameworkModule(const DirectoryEntry *ParentDir,
+                               StringRef Name, bool &IsSystem) const;
+
+  /// \brief Infer the contents of a framework module map from the given
+  /// framework directory.
+  Module *inferFrameworkModule(StringRef ModuleName, 
+                               const DirectoryEntry *FrameworkDir,
+                               bool IsSystem, Module *Parent);
+  
+  /// \brief Retrieve the module map file containing the definition of the given
+  /// module.
+  ///
+  /// \param Module The module whose module map file will be returned, if known.
+  ///
+  /// \returns The file entry for the module map file containing the given
+  /// module, or NULL if the module definition was inferred.
+  const FileEntry *getContainingModuleMapFile(Module *Module) const;
+
+  /// \brief Resolve all of the unresolved exports in the given module.
+  ///
+  /// \param Mod The module whose exports should be resolved.
+  ///
+  /// \param Complain Whether to emit diagnostics for failures.
+  ///
+  /// \returns true if any errors were encountered while resolving exports,
+  /// false otherwise.
+  bool resolveExports(Module *Mod, bool Complain);
+
+  /// \brief Resolve all of the unresolved uses in the given module.
+  ///
+  /// \param Mod The module whose uses should be resolved.
+  ///
+  /// \param Complain Whether to emit diagnostics for failures.
+  ///
+  /// \returns true if any errors were encountered while resolving uses,
+  /// false otherwise.
+  bool resolveUses(Module *Mod, bool Complain);
+
+  /// \brief Resolve all of the unresolved conflicts in the given module.
+  ///
+  /// \param Mod The module whose conflicts should be resolved.
+  ///
+  /// \param Complain Whether to emit diagnostics for failures.
+  ///
+  /// \returns true if any errors were encountered while resolving conflicts,
+  /// false otherwise.
+  bool resolveConflicts(Module *Mod, bool Complain);
+
+  /// \brief Infers the (sub)module based on the given source location and
+  /// source manager.
+  ///
+  /// \param Loc The location within the source that we are querying, along
+  /// with its source manager.
+  ///
+  /// \returns The module that owns this source location, or null if no
+  /// module owns this source location.
+  Module *inferModuleFromLocation(FullSourceLoc Loc);
+  
+  /// \brief Sets the umbrella header of the given module to the given
+  /// header.
+  void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader);
+
+  /// \brief Sets the umbrella directory of the given module to the given
+  /// directory.
+  void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir);
+
+  /// \brief Adds this header to the given module.
+  /// \param Role The role of the header wrt the module.
+  void addHeader(Module *Mod, const FileEntry *Header,
+                 ModuleHeaderRole Role);
+
+  /// \brief Parse the given module map file, and record any modules we 
+  /// encounter.
+  ///
+  /// \param File The file to be parsed.
+  ///
+  /// \param IsSystem Whether this module map file is in a system header
+  /// directory, and therefore should be considered a system module.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool parseModuleMapFile(const FileEntry *File, bool IsSystem);
+    
+  /// \brief Dump the contents of the module map, for debugging purposes.
+  void dump();
+  
+  typedef llvm::StringMap<Module *>::const_iterator module_iterator;
+  module_iterator module_begin() const { return Modules.begin(); }
+  module_iterator module_end()   const { return Modules.end(); }
+};
+  
+}
+#endif
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
new file mode 100644
index 0000000..e3c6de5
--- /dev/null
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -0,0 +1,181 @@
+//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the MultipleIncludeOpt interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+class IdentifierInfo;
+
+/// \brief Implements the simple state machine that the Lexer class uses to
+/// detect files subject to the 'multiple-include' optimization.
+///
+/// The public methods in this class are triggered by various
+/// events that occur when a file is lexed, and after the entire file is lexed,
+/// information about which macro (if any) controls the header is returned.
+class MultipleIncludeOpt {
+  /// ReadAnyTokens - This is set to false when a file is first opened and true
+  /// any time a token is returned to the client or a (non-multiple-include)
+  /// directive is parsed.  When the final \#endif is parsed this is reset back
+  /// to false, that way any tokens before the first \#ifdef or after the last
+  /// \#endif can be easily detected.
+  bool ReadAnyTokens;
+
+  /// ImmediatelyAfterTopLevelIfndef - This is true when the only tokens
+  /// processed in the file so far is an #ifndef and an identifier.  Used in
+  /// the detection of header guards in a file.
+  bool ImmediatelyAfterTopLevelIfndef;
+
+  /// ReadAnyTokens - This is set to false when a file is first opened and true
+  /// any time a token is returned to the client or a (non-multiple-include)
+  /// directive is parsed.  When the final #endif is parsed this is reset back
+  /// to false, that way any tokens before the first #ifdef or after the last
+  /// #endif can be easily detected.
+  bool DidMacroExpansion;
+
+  /// TheMacro - The controlling macro for a file, if valid.
+  ///
+  const IdentifierInfo *TheMacro;
+
+  /// DefinedMacro - The macro defined right after TheMacro, if any.
+  const IdentifierInfo *DefinedMacro;
+
+  SourceLocation MacroLoc;
+  SourceLocation DefinedLoc;
+public:
+  MultipleIncludeOpt() {
+    ReadAnyTokens = false;
+    ImmediatelyAfterTopLevelIfndef = false;
+    DidMacroExpansion = false;
+    TheMacro = nullptr;
+    DefinedMacro = nullptr;
+  }
+
+  SourceLocation GetMacroLocation() const {
+    return MacroLoc;
+  }
+
+  SourceLocation GetDefinedLocation() const {
+    return DefinedLoc;
+  }
+
+  void resetImmediatelyAfterTopLevelIfndef() {
+    ImmediatelyAfterTopLevelIfndef = false;
+  }
+
+  void SetDefinedMacro(IdentifierInfo *M, SourceLocation Loc) {
+    DefinedMacro = M;
+    DefinedLoc = Loc;
+  }
+
+  /// Invalidate - Permanently mark this file as not being suitable for the
+  /// include-file optimization.
+  void Invalidate() {
+    // If we have read tokens but have no controlling macro, the state-machine
+    // below can never "accept".
+    ReadAnyTokens = true;
+    ImmediatelyAfterTopLevelIfndef = false;
+    DefinedMacro = nullptr;
+    TheMacro = nullptr;
+  }
+
+  /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
+  /// top of the file when reading preprocessor directives.  Otherwise, reading
+  /// the "ifndef x" would count as reading tokens.
+  bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
+
+  /// getImmediatelyAfterTopLevelIfndef - returns true if the last directive
+  /// was an #ifndef at the beginning of the file.
+  bool getImmediatelyAfterTopLevelIfndef() const {
+    return ImmediatelyAfterTopLevelIfndef;
+  }
+
+  // If a token is read, remember that we have seen a side-effect in this file.
+  void ReadToken() {
+    ReadAnyTokens = true;
+    ImmediatelyAfterTopLevelIfndef = false;
+  }
+
+  /// ExpandedMacro - When a macro is expanded with this lexer as the current
+  /// buffer, this method is called to disable the MIOpt if needed.
+  void ExpandedMacro() { DidMacroExpansion = true; }
+
+  /// \brief Called when entering a top-level \#ifndef directive (or the
+  /// "\#if !defined" equivalent) without any preceding tokens.
+  ///
+  /// Note, we don't care about the input value of 'ReadAnyTokens'.  The caller
+  /// ensures that this is only called if there are no tokens read before the
+  /// \#ifndef.  The caller is required to do this, because reading the \#if
+  /// line obviously reads in in tokens.
+  void EnterTopLevelIfndef(const IdentifierInfo *M, SourceLocation Loc) {
+    // If the macro is already set, this is after the top-level #endif.
+    if (TheMacro)
+      return Invalidate();
+
+    // If we have already expanded a macro by the end of the #ifndef line, then
+    // there is a macro expansion *in* the #ifndef line.  This means that the
+    // condition could evaluate differently when subsequently #included.  Reject
+    // this.
+    if (DidMacroExpansion)
+      return Invalidate();
+
+    // Remember that we're in the #if and that we have the macro.
+    ReadAnyTokens = true;
+    ImmediatelyAfterTopLevelIfndef = true;
+    TheMacro = M;
+    MacroLoc = Loc;
+  }
+
+  /// \brief Invoked when a top level conditional (except \#ifndef) is found.
+  void EnterTopLevelConditional() {
+    // If a conditional directive (except #ifndef) is found at the top level,
+    // there is a chunk of the file not guarded by the controlling macro.
+    Invalidate();
+  }
+
+  /// \brief Called when the lexer exits the top-level conditional.
+  void ExitTopLevelConditional() {
+    // If we have a macro, that means the top of the file was ok.  Set our state
+    // back to "not having read any tokens" so we can detect anything after the
+    // #endif.
+    if (!TheMacro) return Invalidate();
+
+    // At this point, we haven't "read any tokens" but we do have a controlling
+    // macro.
+    ReadAnyTokens = false;
+    ImmediatelyAfterTopLevelIfndef = false;
+  }
+
+  /// \brief Once the entire file has been lexed, if there is a controlling
+  /// macro, return it.
+  const IdentifierInfo *GetControllingMacroAtEndOfFile() const {
+    // If we haven't read any tokens after the #endif, return the controlling
+    // macro if it's valid (if it isn't, it will be null).
+    if (!ReadAnyTokens)
+      return TheMacro;
+    return nullptr;
+  }
+
+  /// \brief If the ControllingMacro is followed by a macro definition, return
+  /// the macro that was defined.
+  const IdentifierInfo *GetDefinedMacro() const {
+    return DefinedMacro;
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
new file mode 100644
index 0000000..7f1ea34
--- /dev/null
+++ b/include/clang/Lex/PPCallbacks.h
@@ -0,0 +1,511 @@
+//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the PPCallbacks interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
+#define LLVM_CLANG_LEX_PPCALLBACKS_H
+
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Lex/ModuleLoader.h"
+#include "clang/Lex/Pragma.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace clang {
+  class SourceLocation;
+  class Token;
+  class IdentifierInfo;
+  class MacroDirective;
+  class MacroArgs;
+
+/// \brief This interface provides a way to observe the actions of the
+/// preprocessor as it does its thing.
+///
+/// Clients can define their hooks here to implement preprocessor level tools.
+class PPCallbacks {
+public:
+  virtual ~PPCallbacks();
+
+  enum FileChangeReason {
+    EnterFile, ExitFile, SystemHeaderPragma, RenameFile
+  };
+
+  /// \brief Callback invoked whenever a source file is entered or exited.
+  ///
+  /// \param Loc Indicates the new location.
+  /// \param PrevFID the file that was exited if \p Reason is ExitFile.
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType,
+                           FileID PrevFID = FileID()) {
+  }
+
+  /// \brief Callback invoked whenever a source file is skipped as the result
+  /// of header guard optimization.
+  ///
+  /// \param ParentFile The file that \#included the skipped file.
+  ///
+  /// \param FilenameTok The token in ParentFile that indicates the
+  /// skipped file.
+  virtual void FileSkipped(const FileEntry &ParentFile,
+                           const Token &FilenameTok,
+                           SrcMgr::CharacteristicKind FileType) {
+  }
+
+  /// \brief Callback invoked whenever an inclusion directive results in a
+  /// file-not-found error.
+  ///
+  /// \param FileName The name of the file being included, as written in the 
+  /// source code.
+  ///
+  /// \param RecoveryPath If this client indicates that it can recover from 
+  /// this missing file, the client should set this as an additional header
+  /// search patch.
+  ///
+  /// \returns true to indicate that the preprocessor should attempt to recover
+  /// by adding \p RecoveryPath as a header search path.
+  virtual bool FileNotFound(StringRef FileName,
+                            SmallVectorImpl<char> &RecoveryPath) {
+    return false;
+  }
+
+  /// \brief Callback invoked whenever an inclusion directive of
+  /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
+  /// of whether the inclusion will actually result in an inclusion.
+  ///
+  /// \param HashLoc The location of the '#' that starts the inclusion 
+  /// directive.
+  ///
+  /// \param IncludeTok The token that indicates the kind of inclusion 
+  /// directive, e.g., 'include' or 'import'.
+  ///
+  /// \param FileName The name of the file being included, as written in the 
+  /// source code.
+  ///
+  /// \param IsAngled Whether the file name was enclosed in angle brackets;
+  /// otherwise, it was enclosed in quotes.
+  ///
+  /// \param FilenameRange The character range of the quotes or angle brackets
+  /// for the written file name.
+  ///
+  /// \param File The actual file that may be included by this inclusion 
+  /// directive.
+  ///
+  /// \param SearchPath Contains the search path which was used to find the file
+  /// in the file system. If the file was found via an absolute include path,
+  /// SearchPath will be empty. For framework includes, the SearchPath and
+  /// RelativePath will be split up. For example, if an include of "Some/Some.h"
+  /// is found via the framework path
+  /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be
+  /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be
+  /// "Some.h".
+  ///
+  /// \param RelativePath The path relative to SearchPath, at which the include
+  /// file was found. This is equal to FileName except for framework includes.
+  ///
+  /// \param Imported The module, whenever an inclusion directive was
+  /// automatically turned into a module import or null otherwise.
+  ///
+  virtual void InclusionDirective(SourceLocation HashLoc,
+                                  const Token &IncludeTok,
+                                  StringRef FileName,
+                                  bool IsAngled,
+                                  CharSourceRange FilenameRange,
+                                  const FileEntry *File,
+                                  StringRef SearchPath,
+                                  StringRef RelativePath,
+                                  const Module *Imported) {
+  }
+
+  /// \brief Callback invoked whenever there was an explicit module-import
+  /// syntax.
+  ///
+  /// \param ImportLoc The location of import directive token.
+  ///
+  /// \param Path The identifiers (and their locations) of the module
+  /// "path", e.g., "std.vector" would be split into "std" and "vector".
+  ///
+  /// \param Imported The imported module; can be null if importing failed.
+  ///
+  virtual void moduleImport(SourceLocation ImportLoc,
+                            ModuleIdPath Path,
+                            const Module *Imported) {
+  }
+
+  /// \brief Callback invoked when the end of the main file is reached.
+  ///
+  /// No subsequent callbacks will be made.
+  virtual void EndOfMainFile() {
+  }
+
+  /// \brief Callback invoked when a \#ident or \#sccs directive is read.
+  /// \param Loc The location of the directive.
+  /// \param str The text of the directive.
+  ///
+  virtual void Ident(SourceLocation Loc, const std::string &str) {
+  }
+
+  /// \brief Callback invoked when start reading any pragma directive.
+  virtual void PragmaDirective(SourceLocation Loc,
+                               PragmaIntroducerKind Introducer) {
+  }
+
+  /// \brief Callback invoked when a \#pragma comment directive is read.
+  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                             const std::string &Str) {
+  }
+
+  /// \brief Callback invoked when a \#pragma detect_mismatch directive is
+  /// read.
+  virtual void PragmaDetectMismatch(SourceLocation Loc,
+                                    const std::string &Name,
+                                    const std::string &Value) {
+  }
+
+  /// \brief Callback invoked when a \#pragma clang __debug directive is read.
+  /// \param Loc The location of the debug directive.
+  /// \param DebugType The identifier following __debug.
+  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
+  }
+
+  /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage.
+  enum PragmaMessageKind {
+    /// \brief \#pragma message has been invoked.
+    PMK_Message,
+
+    /// \brief \#pragma GCC warning has been invoked.
+    PMK_Warning,
+
+    /// \brief \#pragma GCC error has been invoked.
+    PMK_Error
+  };
+
+  /// \brief Callback invoked when a \#pragma message directive is read.
+  /// \param Loc The location of the message directive.
+  /// \param Namespace The namespace of the message directive.
+  /// \param Kind The type of the message directive.
+  /// \param Str The text of the message directive.
+  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
+                             PragmaMessageKind Kind, StringRef Str) {
+  }
+
+  /// \brief Callback invoked when a \#pragma gcc dianostic push directive
+  /// is read.
+  virtual void PragmaDiagnosticPush(SourceLocation Loc,
+                                    StringRef Namespace) {
+  }
+
+  /// \brief Callback invoked when a \#pragma gcc dianostic pop directive
+  /// is read.
+  virtual void PragmaDiagnosticPop(SourceLocation Loc,
+                                   StringRef Namespace) {
+  }
+
+  /// \brief Callback invoked when a \#pragma gcc dianostic directive is read.
+  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
+                                diag::Severity mapping, StringRef Str) {}
+
+  /// \brief Called when an OpenCL extension is either disabled or
+  /// enabled with a pragma.
+  virtual void PragmaOpenCLExtension(SourceLocation NameLoc, 
+                                     const IdentifierInfo *Name,
+                                     SourceLocation StateLoc, unsigned State) {
+  }
+
+  /// \brief Callback invoked when a \#pragma warning directive is read.
+  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+                             ArrayRef<int> Ids) {
+  }
+
+  /// \brief Callback invoked when a \#pragma warning(push) directive is read.
+  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
+  }
+
+  /// \brief Callback invoked when a \#pragma warning(pop) directive is read.
+  virtual void PragmaWarningPop(SourceLocation Loc) {
+  }
+
+  /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
+  /// macro invocation is found.
+  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+                            SourceRange Range, const MacroArgs *Args) {
+  }
+
+  /// \brief Hook called whenever a macro definition is seen.
+  virtual void MacroDefined(const Token &MacroNameTok,
+                            const MacroDirective *MD) {
+  }
+
+  /// \brief Hook called whenever a macro \#undef is seen.
+  ///
+  /// MD is released immediately following this callback.
+  virtual void MacroUndefined(const Token &MacroNameTok,
+                              const MacroDirective *MD) {
+  }
+  
+  /// \brief Hook called whenever the 'defined' operator is seen.
+  /// \param MD The MacroDirective if the name was a macro, null otherwise.
+  virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+                       SourceRange Range) {
+  }
+  
+  /// \brief Hook called when a source range is skipped.
+  /// \param Range The SourceRange that was skipped. The range begins at the
+  /// \#if/\#else directive and ends after the \#endif/\#else directive.
+  virtual void SourceRangeSkipped(SourceRange Range) {
+  }
+
+  enum ConditionValueKind {
+    CVK_NotEvaluated, CVK_False, CVK_True
+  };
+
+  /// \brief Hook called whenever an \#if is seen.
+  /// \param Loc the source location of the directive.
+  /// \param ConditionRange The SourceRange of the expression being tested.
+  /// \param ConditionValue The evaluated value of the condition.
+  ///
+  // FIXME: better to pass in a list (or tree!) of Tokens.
+  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
+                  ConditionValueKind ConditionValue) {
+  }
+
+  /// \brief Hook called whenever an \#elif is seen.
+  /// \param Loc the source location of the directive.
+  /// \param ConditionRange The SourceRange of the expression being tested.
+  /// \param ConditionValue The evaluated value of the condition.
+  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
+  // FIXME: better to pass in a list (or tree!) of Tokens.
+  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
+                    ConditionValueKind ConditionValue, SourceLocation IfLoc) {
+  }
+
+  /// \brief Hook called whenever an \#ifdef is seen.
+  /// \param Loc the source location of the directive.
+  /// \param MacroNameTok Information on the token being tested.
+  /// \param MD The MacroDirective if the name was a macro, null otherwise.
+  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+                     const MacroDirective *MD) {
+  }
+
+  /// \brief Hook called whenever an \#ifndef is seen.
+  /// \param Loc the source location of the directive.
+  /// \param MacroNameTok Information on the token being tested.
+  /// \param MD The MacroDirective if the name was a macro, null otherwise.
+  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+                      const MacroDirective *MD) {
+  }
+
+  /// \brief Hook called whenever an \#else is seen.
+  /// \param Loc the source location of the directive.
+  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
+  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
+  }
+
+  /// \brief Hook called whenever an \#endif is seen.
+  /// \param Loc the source location of the directive.
+  /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
+  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
+  }
+};
+
+/// \brief Simple wrapper class for chaining callbacks.
+class PPChainedCallbacks : public PPCallbacks {
+  virtual void anchor();
+  PPCallbacks *First, *Second;
+
+public:
+  PPChainedCallbacks(PPCallbacks *_First, PPCallbacks *_Second)
+    : First(_First), Second(_Second) {}
+  ~PPChainedCallbacks() {
+    delete Second;
+    delete First;
+  }
+
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override {
+    First->FileChanged(Loc, Reason, FileType, PrevFID);
+    Second->FileChanged(Loc, Reason, FileType, PrevFID);
+  }
+
+  void FileSkipped(const FileEntry &ParentFile,
+                   const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override {
+    First->FileSkipped(ParentFile, FilenameTok, FileType);
+    Second->FileSkipped(ParentFile, FilenameTok, FileType);
+  }
+
+  bool FileNotFound(StringRef FileName,
+                    SmallVectorImpl<char> &RecoveryPath) override {
+    return First->FileNotFound(FileName, RecoveryPath) ||
+           Second->FileNotFound(FileName, RecoveryPath);
+  }
+
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
+    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
+                              FilenameRange, File, SearchPath, RelativePath,
+                              Imported);
+    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
+                               FilenameRange, File, SearchPath, RelativePath,
+                               Imported);
+  }
+
+  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
+                    const Module *Imported) override {
+    First->moduleImport(ImportLoc, Path, Imported);
+    Second->moduleImport(ImportLoc, Path, Imported);
+  }
+
+  void EndOfMainFile() override {
+    First->EndOfMainFile();
+    Second->EndOfMainFile();
+  }
+
+  void Ident(SourceLocation Loc, const std::string &str) override {
+    First->Ident(Loc, str);
+    Second->Ident(Loc, str);
+  }
+
+  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                     const std::string &Str) override {
+    First->PragmaComment(Loc, Kind, Str);
+    Second->PragmaComment(Loc, Kind, Str);
+  }
+
+  void PragmaDetectMismatch(SourceLocation Loc, const std::string &Name,
+                            const std::string &Value) override {
+    First->PragmaDetectMismatch(Loc, Name, Value);
+    Second->PragmaDetectMismatch(Loc, Name, Value);
+  }
+
+  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
+                     PragmaMessageKind Kind, StringRef Str) override {
+    First->PragmaMessage(Loc, Namespace, Kind, Str);
+    Second->PragmaMessage(Loc, Namespace, Kind, Str);
+  }
+
+  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
+    First->PragmaDiagnosticPush(Loc, Namespace);
+    Second->PragmaDiagnosticPush(Loc, Namespace);
+  }
+
+  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
+    First->PragmaDiagnosticPop(Loc, Namespace);
+    Second->PragmaDiagnosticPop(Loc, Namespace);
+  }
+
+  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
+                        diag::Severity mapping, StringRef Str) override {
+    First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
+    Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
+  }
+
+  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
+                             SourceLocation StateLoc, unsigned State) override {
+    First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
+    Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
+  }
+
+  void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+                     ArrayRef<int> Ids) override {
+    First->PragmaWarning(Loc, WarningSpec, Ids);
+    Second->PragmaWarning(Loc, WarningSpec, Ids);
+  }
+
+  void PragmaWarningPush(SourceLocation Loc, int Level) override {
+    First->PragmaWarningPush(Loc, Level);
+    Second->PragmaWarningPush(Loc, Level);
+  }
+
+  void PragmaWarningPop(SourceLocation Loc) override {
+    First->PragmaWarningPop(Loc);
+    Second->PragmaWarningPop(Loc);
+  }
+
+  void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+                    SourceRange Range, const MacroArgs *Args) override {
+    First->MacroExpands(MacroNameTok, MD, Range, Args);
+    Second->MacroExpands(MacroNameTok, MD, Range, Args);
+  }
+
+  void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
+    First->MacroDefined(MacroNameTok, MD);
+    Second->MacroDefined(MacroNameTok, MD);
+  }
+
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDirective *MD) override {
+    First->MacroUndefined(MacroNameTok, MD);
+    Second->MacroUndefined(MacroNameTok, MD);
+  }
+
+  void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+               SourceRange Range) override {
+    First->Defined(MacroNameTok, MD, Range);
+    Second->Defined(MacroNameTok, MD, Range);
+  }
+
+  void SourceRangeSkipped(SourceRange Range) override {
+    First->SourceRangeSkipped(Range);
+    Second->SourceRangeSkipped(Range);
+  }
+
+  /// \brief Hook called whenever an \#if is seen.
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override {
+    First->If(Loc, ConditionRange, ConditionValue);
+    Second->If(Loc, ConditionRange, ConditionValue);
+  }
+
+  /// \brief Hook called whenever an \#elif is seen.
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
+    First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
+    Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
+  }
+
+  /// \brief Hook called whenever an \#ifdef is seen.
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDirective *MD) override {
+    First->Ifdef(Loc, MacroNameTok, MD);
+    Second->Ifdef(Loc, MacroNameTok, MD);
+  }
+
+  /// \brief Hook called whenever an \#ifndef is seen.
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDirective *MD) override {
+    First->Ifndef(Loc, MacroNameTok, MD);
+    Second->Ifndef(Loc, MacroNameTok, MD);
+  }
+
+  /// \brief Hook called whenever an \#else is seen.
+  void Else(SourceLocation Loc, SourceLocation IfLoc) override {
+    First->Else(Loc, IfLoc);
+    Second->Else(Loc, IfLoc);
+  }
+
+  /// \brief Hook called whenever an \#endif is seen.
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
+    First->Endif(Loc, IfLoc);
+    Second->Endif(Loc, IfLoc);
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
new file mode 100644
index 0000000..00d2d57
--- /dev/null
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -0,0 +1,103 @@
+//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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 PPConditionalDirectiveRecord class, which maintains
+//  a record of conditional directive regions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+#define LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+  
+/// \brief Records preprocessor conditional directive regions and allows
+/// querying in which region source locations belong to.
+class PPConditionalDirectiveRecord : public PPCallbacks {
+  SourceManager &SourceMgr;
+  
+  SmallVector<SourceLocation, 6> CondDirectiveStack;
+
+  class CondDirectiveLoc {
+    SourceLocation Loc;
+    SourceLocation RegionLoc;
+
+  public:
+    CondDirectiveLoc(SourceLocation Loc, SourceLocation RegionLoc)
+      : Loc(Loc), RegionLoc(RegionLoc) {}
+
+    SourceLocation getLoc() const { return Loc; }
+    SourceLocation getRegionLoc() const { return RegionLoc; }
+
+    class Comp {
+      SourceManager &SM;
+    public:
+      explicit Comp(SourceManager &SM) : SM(SM) {}
+      bool operator()(const CondDirectiveLoc &LHS,
+                      const CondDirectiveLoc &RHS) {
+        return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS.getLoc());
+      }
+      bool operator()(const CondDirectiveLoc &LHS, SourceLocation RHS) {
+        return SM.isBeforeInTranslationUnit(LHS.getLoc(), RHS);
+      }
+      bool operator()(SourceLocation LHS, const CondDirectiveLoc &RHS) {
+        return SM.isBeforeInTranslationUnit(LHS, RHS.getLoc());
+      }
+    };
+  };
+
+  typedef std::vector<CondDirectiveLoc> CondDirectiveLocsTy;
+  /// \brief The locations of conditional directives in source order.
+  CondDirectiveLocsTy CondDirectiveLocs;
+
+  void addCondDirectiveLoc(CondDirectiveLoc DirLoc);
+
+public:
+  /// \brief Construct a new preprocessing record.
+  explicit PPConditionalDirectiveRecord(SourceManager &SM);
+
+  size_t getTotalMemory() const;
+
+  SourceManager &getSourceManager() const { return SourceMgr; }
+
+  /// \brief Returns true if the given range intersects with a conditional
+  /// directive. if a \#if/\#endif block is fully contained within the range,
+  /// this function will return false.
+  bool rangeIntersectsConditionalDirective(SourceRange Range) const;
+
+  /// \brief Returns true if the given locations are in different regions,
+  /// separated by conditional directive blocks.
+  bool areInDifferentConditionalDirectiveRegion(SourceLocation LHS,
+                                                SourceLocation RHS) const {
+    return findConditionalDirectiveRegionLoc(LHS) !=
+        findConditionalDirectiveRegionLoc(RHS);
+  }
+
+  SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
+
+private:
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override;
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDirective *MD) override;
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDirective *MD) override;
+  void Else(SourceLocation Loc, SourceLocation IfLoc) override;
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LEX_PPCONDITIONALDIRECTIVERECORD_H
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
new file mode 100644
index 0000000..2352cce
--- /dev/null
+++ b/include/clang/Lex/PTHLexer.h
@@ -0,0 +1,105 @@
+//===--- PTHLexer.h - Lexer based on Pre-tokenized input --------*- 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 PTHLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PTHLEXER_H
+#define LLVM_CLANG_PTHLEXER_H
+
+#include "clang/Lex/PreprocessorLexer.h"
+
+namespace clang {
+
+class PTHManager;
+class PTHSpellingSearch;
+
+class PTHLexer : public PreprocessorLexer {
+  SourceLocation FileStartLoc;
+
+  /// TokBuf - Buffer from PTH file containing raw token data.
+  const unsigned char* TokBuf;
+
+  /// CurPtr - Pointer into current offset of the token buffer where
+  ///  the next token will be read.
+  const unsigned char* CurPtr;
+
+  /// LastHashTokPtr - Pointer into TokBuf of the last processed '#'
+  ///  token that appears at the start of a line.
+  const unsigned char* LastHashTokPtr;
+
+  /// PPCond - Pointer to a side table in the PTH file that provides a
+  ///  a consise summary of the preproccessor conditional block structure.
+  ///  This is used to perform quick skipping of conditional blocks.
+  const unsigned char* PPCond;
+
+  /// CurPPCondPtr - Pointer inside PPCond that refers to the next entry
+  ///  to process when doing quick skipping of preprocessor blocks.
+  const unsigned char* CurPPCondPtr;
+
+  PTHLexer(const PTHLexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const PTHLexer &) LLVM_DELETED_FUNCTION;
+
+  /// ReadToken - Used by PTHLexer to read tokens TokBuf.
+  void ReadToken(Token& T);
+  
+  bool LexEndOfFile(Token &Result);
+
+  /// PTHMgr - The PTHManager object that created this PTHLexer.
+  PTHManager& PTHMgr;
+
+  Token EofToken;
+
+protected:
+  friend class PTHManager;
+
+  /// Create a PTHLexer for the specified token stream.
+  PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D,
+           const unsigned char* ppcond, PTHManager &PM);
+public:
+
+  ~PTHLexer() {}
+
+  /// Lex - Return the next token.
+  bool Lex(Token &Tok);
+
+  void getEOF(Token &Tok);
+
+  /// DiscardToEndOfLine - Read the rest of the current preprocessor line as an
+  /// uninterpreted string.  This switches the lexer out of directive mode.
+  void DiscardToEndOfLine();
+
+  /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
+  /// tok::l_paren token, 0 if it is something else and 2 if there are no more
+  /// tokens controlled by this lexer.
+  unsigned isNextPPTokenLParen() {
+    // isNextPPTokenLParen is not on the hot path, and all we care about is
+    // whether or not we are at a token with kind tok::eof or tok::l_paren.
+    // Just read the first byte from the current token pointer to determine
+    // its kind.
+    tok::TokenKind x = (tok::TokenKind)*CurPtr;
+    return x == tok::eof ? 2 : x == tok::l_paren;
+  }
+
+  /// IndirectLex - An indirect call to 'Lex' that can be invoked via
+  ///  the PreprocessorLexer interface.
+  void IndirectLex(Token &Result) override { Lex(Result); }
+
+  /// getSourceLocation - Return a source location for the token in
+  /// the current file.
+  SourceLocation getSourceLocation() override;
+
+  /// SkipBlock - Used by Preprocessor to skip the current conditional block.
+  bool SkipBlock();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
new file mode 100644
index 0000000..11b5cea
--- /dev/null
+++ b/include/clang/Lex/PTHManager.h
@@ -0,0 +1,139 @@
+//===--- PTHManager.h - Manager object for PTH processing -------*- 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 PTHManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PTHMANAGER_H
+#define LLVM_CLANG_PTHMANAGER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/PTHLexer.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <string>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class FileEntry;
+class PTHLexer;
+class DiagnosticsEngine;
+class FileSystemStatCache;
+
+class PTHManager : public IdentifierInfoLookup {
+  friend class PTHLexer;
+
+  /// The memory mapped PTH file.
+  const llvm::MemoryBuffer* Buf;
+
+  /// Alloc - Allocator used for IdentifierInfo objects.
+  llvm::BumpPtrAllocator Alloc;
+
+  /// IdMap - A lazily generated cache mapping from persistent identifiers to
+  ///  IdentifierInfo*.
+  IdentifierInfo** PerIDCache;
+
+  /// FileLookup - Abstract data structure used for mapping between files
+  ///  and token data in the PTH file.
+  void* FileLookup;
+
+  /// IdDataTable - Array representing the mapping from persistent IDs to the
+  ///  data offset within the PTH file containing the information to
+  ///  reconsitute an IdentifierInfo.
+  const unsigned char* const IdDataTable;
+
+  /// SortedIdTable - Abstract data structure mapping from strings to
+  ///  persistent IDs.  This is used by get().
+  void* StringIdLookup;
+
+  /// NumIds - The number of identifiers in the PTH file.
+  const unsigned NumIds;
+
+  /// PP - The Preprocessor object that will use this PTHManager to create
+  ///  PTHLexer objects.
+  Preprocessor* PP;
+
+  /// SpellingBase - The base offset within the PTH memory buffer that
+  ///  contains the cached spellings for literals.
+  const unsigned char* const SpellingBase;
+
+  /// OriginalSourceFile - A null-terminated C-string that specifies the name
+  ///  if the file (if any) that was to used to generate the PTH cache.
+  const char* OriginalSourceFile;
+
+  /// This constructor is intended to only be called by the static 'Create'
+  /// method.
+  PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup,
+             const unsigned char* idDataTable, IdentifierInfo** perIDCache,
+             void* stringIdLookup, unsigned numIds,
+             const unsigned char* spellingBase, const char *originalSourceFile);
+
+  PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION;
+  void operator=(const PTHManager &) LLVM_DELETED_FUNCTION;
+
+  /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached
+  ///  spelling for a token.
+  unsigned getSpellingAtPTHOffset(unsigned PTHOffset, const char*& Buffer);
+
+  /// GetIdentifierInfo - Used to reconstruct IdentifierInfo objects from the
+  ///  PTH file.
+  inline IdentifierInfo* GetIdentifierInfo(unsigned PersistentID) {
+    // Check if the IdentifierInfo has already been resolved.
+    if (IdentifierInfo* II = PerIDCache[PersistentID])
+      return II;
+    return LazilyCreateIdentifierInfo(PersistentID);
+  }
+  IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID);
+
+public:
+  // The current PTH version.
+  enum { Version = 10 };
+
+  ~PTHManager();
+
+  /// getOriginalSourceFile - Return the full path to the original header
+  ///  file name that was used to generate the PTH cache.
+  const char* getOriginalSourceFile() const {
+    return OriginalSourceFile;
+  }
+
+  /// get - Return the identifier token info for the specified named identifier.
+  ///  Unlike the version in IdentifierTable, this returns a pointer instead
+  ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
+  ///  be found.
+  IdentifierInfo *get(StringRef Name) override;
+
+  /// Create - This method creates PTHManager objects.  The 'file' argument
+  ///  is the name of the PTH file.  This method returns NULL upon failure.
+  static PTHManager *Create(const std::string& file, DiagnosticsEngine &Diags);
+
+  void setPreprocessor(Preprocessor *pp) { PP = pp; }
+
+  /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the
+  ///  specified file.  This method returns NULL if no cached tokens exist.
+  ///  It is the responsibility of the caller to 'delete' the returned object.
+  PTHLexer *CreateLexer(FileID FID);
+
+  /// createStatCache - Returns a FileSystemStatCache object for use with
+  ///  FileManager objects.  These objects use the PTH data to speed up
+  ///  calls to stat by memoizing their results from when the PTH file
+  ///  was generated.
+  FileSystemStatCache *createStatCache();
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
new file mode 100644
index 0000000..4a695a0
--- /dev/null
+++ b/include/clang/Lex/Pragma.h
@@ -0,0 +1,126 @@
+//===--- Pragma.h - Pragma registration and handling ------------*- 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 PragmaHandler and PragmaTable interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PRAGMA_H
+#define LLVM_CLANG_PRAGMA_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+
+namespace clang {
+  class Preprocessor;
+  class Token;
+  class IdentifierInfo;
+  class PragmaNamespace;
+
+  /**
+   * \brief Describes how the pragma was introduced, e.g., with \#pragma,
+   * _Pragma, or __pragma.
+   */
+  enum PragmaIntroducerKind {
+    /**
+     * \brief The pragma was introduced via \#pragma.
+     */
+    PIK_HashPragma,
+    
+    /**
+     * \brief The pragma was introduced via the C99 _Pragma(string-literal).
+     */
+    PIK__Pragma,
+    
+    /**
+     * \brief The pragma was introduced via the Microsoft 
+     * __pragma(token-string).
+     */
+    PIK___pragma
+  };
+  
+/// PragmaHandler - Instances of this interface defined to handle the various
+/// pragmas that the language front-end uses.  Each handler optionally has a
+/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
+/// that identifier is found.  If a handler does not match any of the declared
+/// pragmas the handler with a null identifier is invoked, if it exists.
+///
+/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
+/// we treat "\#pragma STDC" and "\#pragma GCC" as namespaces that contain other
+/// pragmas.
+class PragmaHandler {
+  std::string Name;
+public:
+  explicit PragmaHandler(StringRef name) : Name(name) {}
+  PragmaHandler() {}
+  virtual ~PragmaHandler();
+
+  StringRef getName() const { return Name; }
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &FirstToken) = 0;
+
+  /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
+  /// using a dynamic_cast, but doesn't require RTTI.
+  virtual PragmaNamespace *getIfNamespace() { return nullptr; }
+};
+
+/// EmptyPragmaHandler - A pragma handler which takes no action, which can be
+/// used to ignore particular pragmas.
+class EmptyPragmaHandler : public PragmaHandler {
+public:
+  EmptyPragmaHandler();
+
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
+/// allowing hierarchical pragmas to be defined.  Common examples of namespaces
+/// are "\#pragma GCC", "\#pragma STDC", and "\#pragma omp", but any namespaces
+/// may be (potentially recursively) defined.
+class PragmaNamespace : public PragmaHandler {
+  /// Handlers - This is a map of the handlers in this namespace with their name
+  /// as key.
+  ///
+  llvm::StringMap<PragmaHandler*> Handlers;
+public:
+  explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {}
+  virtual ~PragmaNamespace();
+
+  /// FindHandler - Check to see if there is already a handler for the
+  /// specified name.  If not, return the handler for the null name if it
+  /// exists, otherwise return null.  If IgnoreNull is true (the default) then
+  /// the null handler isn't returned on failure to match.
+  PragmaHandler *FindHandler(StringRef Name,
+                             bool IgnoreNull = true) const;
+
+  /// AddPragma - Add a pragma to this namespace.
+  ///
+  void AddPragma(PragmaHandler *Handler);
+
+  /// RemovePragmaHandler - Remove the given handler from the
+  /// namespace.
+  void RemovePragmaHandler(PragmaHandler *Handler);
+
+  bool IsEmpty() {
+    return Handlers.empty();
+  }
+
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+
+  PragmaNamespace *getIfNamespace() override { return this; }
+};
+
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
new file mode 100644
index 0000000..4609fe3
--- /dev/null
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -0,0 +1,616 @@
+//===--- PreprocessingRecord.h - Record of Preprocessing --------*- 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 PreprocessingRecord class, which maintains a record
+//  of what occurred during preprocessing.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
+#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
+
+namespace clang {
+  class IdentifierInfo;
+  class MacroInfo;
+  class PreprocessingRecord;
+}
+
+/// \brief Allocates memory within a Clang preprocessing record.
+void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+                   unsigned alignment = 8) throw();
+
+/// \brief Frees memory allocated in a Clang preprocessing record.
+void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+                     unsigned) throw();
+
+namespace clang {
+  class MacroDefinition;
+  class FileEntry;
+
+  /// \brief Base class that describes a preprocessed entity, which may be a
+  /// preprocessor directive or macro expansion.
+  class PreprocessedEntity {
+  public:
+    /// \brief The kind of preprocessed entity an object describes.
+    enum EntityKind {
+      /// \brief Indicates a problem trying to load the preprocessed entity.
+      InvalidKind,
+
+      /// \brief A macro expansion.
+      MacroExpansionKind,
+      
+      /// \defgroup Preprocessing directives
+      /// @{
+      
+      /// \brief A macro definition.
+      MacroDefinitionKind,
+      
+      /// \brief An inclusion directive, such as \c \#include, \c
+      /// \#import, or \c \#include_next.
+      InclusionDirectiveKind,
+
+      /// @}
+
+      FirstPreprocessingDirective = MacroDefinitionKind,
+      LastPreprocessingDirective = InclusionDirectiveKind
+    };
+
+  private:
+    /// \brief The kind of preprocessed entity that this object describes.
+    EntityKind Kind;
+    
+    /// \brief The source range that covers this preprocessed entity.
+    SourceRange Range;
+    
+  protected:
+    PreprocessedEntity(EntityKind Kind, SourceRange Range)
+      : Kind(Kind), Range(Range) { }
+
+    friend class PreprocessingRecord;
+
+  public:
+    /// \brief Retrieve the kind of preprocessed entity stored in this object.
+    EntityKind getKind() const { return Kind; }
+    
+    /// \brief Retrieve the source range that covers this entire preprocessed 
+    /// entity.
+    SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+
+    /// \brief Returns true if there was a problem loading the preprocessed
+    /// entity.
+    bool isInvalid() const { return Kind == InvalidKind; }
+
+    // Only allow allocation of preprocessed entities using the allocator 
+    // in PreprocessingRecord or by doing a placement new.
+    void* operator new(size_t bytes, PreprocessingRecord& PR,
+                       unsigned alignment = 8) throw() {
+      return ::operator new(bytes, PR, alignment);
+    }
+    
+    void* operator new(size_t bytes, void* mem) throw() {
+      return mem;
+    }
+    
+    void operator delete(void* ptr, PreprocessingRecord& PR, 
+                         unsigned alignment) throw() {
+      return ::operator delete(ptr, PR, alignment);
+    }
+    
+    void operator delete(void*, std::size_t) throw() { }
+    void operator delete(void*, void*) throw() { }
+    
+  private:
+    // Make vanilla 'new' and 'delete' illegal for preprocessed entities.
+    void* operator new(size_t bytes) throw();
+    void operator delete(void* data) throw();
+  };
+  
+  /// \brief Records the presence of a preprocessor directive.
+  class PreprocessingDirective : public PreprocessedEntity {
+  public:
+    PreprocessingDirective(EntityKind Kind, SourceRange Range) 
+      : PreprocessedEntity(Kind, Range) { }
+    
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PD) { 
+      return PD->getKind() >= FirstPreprocessingDirective &&
+             PD->getKind() <= LastPreprocessingDirective;
+    }
+  };
+  
+  /// \brief Record the location of a macro definition.
+  class MacroDefinition : public PreprocessingDirective {
+    /// \brief The name of the macro being defined.
+    const IdentifierInfo *Name;
+
+  public:
+    explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range)
+      : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { }
+    
+    /// \brief Retrieve the name of the macro being defined.
+    const IdentifierInfo *getName() const { return Name; }
+    
+    /// \brief Retrieve the location of the macro name in the definition.
+    SourceLocation getLocation() const { return getSourceRange().getBegin(); }
+    
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PE) {
+      return PE->getKind() == MacroDefinitionKind;
+    }
+  };
+  
+  /// \brief Records the location of a macro expansion.
+  class MacroExpansion : public PreprocessedEntity {
+    /// \brief The definition of this macro or the name of the macro if it is
+    /// a builtin macro.
+    llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef; 
+
+  public:
+    MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range)
+      : PreprocessedEntity(MacroExpansionKind, Range),
+        NameOrDef(BuiltinName) { }
+
+    MacroExpansion(MacroDefinition *Definition, SourceRange Range)
+      : PreprocessedEntity(MacroExpansionKind, Range),
+        NameOrDef(Definition) { }
+
+    /// \brief True if it is a builtin macro.
+    bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); }
+    
+    /// \brief The name of the macro being expanded.
+    const IdentifierInfo *getName() const {
+      if (MacroDefinition *Def = getDefinition())
+        return Def->getName();
+      return NameOrDef.get<IdentifierInfo*>();
+    }
+    
+    /// \brief The definition of the macro being expanded. May return null if
+    /// this is a builtin macro.
+    MacroDefinition *getDefinition() const {
+      return NameOrDef.dyn_cast<MacroDefinition *>();
+    }
+
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PE) {
+      return PE->getKind() == MacroExpansionKind;
+    }
+  };
+
+  /// \brief Record the location of an inclusion directive, such as an
+  /// \c \#include or \c \#import statement.
+  class InclusionDirective : public PreprocessingDirective {
+  public:
+    /// \brief The kind of inclusion directives known to the
+    /// preprocessor.
+    enum InclusionKind {
+      /// \brief An \c \#include directive.
+      Include,
+      /// \brief An Objective-C \c \#import directive.
+      Import,
+      /// \brief A GNU \c \#include_next directive.
+      IncludeNext,
+      /// \brief A Clang \c \#__include_macros directive.
+      IncludeMacros
+    };
+
+  private:
+    /// \brief The name of the file that was included, as written in
+    /// the source.
+    StringRef FileName;
+
+    /// \brief Whether the file name was in quotation marks; otherwise, it was
+    /// in angle brackets.
+    unsigned InQuotes : 1;
+
+    /// \brief The kind of inclusion directive we have.
+    ///
+    /// This is a value of type InclusionKind.
+    unsigned Kind : 2;
+
+    /// \brief Whether the inclusion directive was automatically turned into
+    /// a module import.
+    unsigned ImportedModule : 1;
+
+    /// \brief The file that was included.
+    const FileEntry *File;
+
+  public:
+    InclusionDirective(PreprocessingRecord &PPRec,
+                       InclusionKind Kind, StringRef FileName, 
+                       bool InQuotes, bool ImportedModule,
+                       const FileEntry *File, SourceRange Range);
+    
+    /// \brief Determine what kind of inclusion directive this is.
+    InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
+    
+    /// \brief Retrieve the included file name as it was written in the source.
+    StringRef getFileName() const { return FileName; }
+    
+    /// \brief Determine whether the included file name was written in quotes;
+    /// otherwise, it was written in angle brackets.
+    bool wasInQuotes() const { return InQuotes; }
+
+    /// \brief Determine whether the inclusion directive was automatically
+    /// turned into a module import.
+    bool importedModule() const { return ImportedModule; }
+    
+    /// \brief Retrieve the file entry for the actual file that was included
+    /// by this directive.
+    const FileEntry *getFile() const { return File; }
+        
+    // Implement isa/cast/dyncast/etc.
+    static bool classof(const PreprocessedEntity *PE) {
+      return PE->getKind() == InclusionDirectiveKind;
+    }
+  };
+  
+  /// \brief An abstract class that should be subclassed by any external source
+  /// of preprocessing record entries.
+  class ExternalPreprocessingRecordSource {
+  public:
+    virtual ~ExternalPreprocessingRecordSource();
+    
+    /// \brief Read a preallocated preprocessed entity from the external source.
+    ///
+    /// \returns null if an error occurred that prevented the preprocessed
+    /// entity from being loaded.
+    virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) = 0;
+
+    /// \brief Returns a pair of [Begin, End) indices of preallocated
+    /// preprocessed entities that \p Range encompasses.
+    virtual std::pair<unsigned, unsigned>
+        findPreprocessedEntitiesInRange(SourceRange Range) = 0;
+
+    /// \brief Optionally returns true or false if the preallocated preprocessed
+    /// entity with index \p Index came from file \p FID.
+    virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+                                                        FileID FID) {
+      return None;
+    }
+  };
+  
+  /// \brief A record of the steps taken while preprocessing a source file,
+  /// including the various preprocessing directives processed, macros 
+  /// expanded, etc.
+  class PreprocessingRecord : public PPCallbacks {
+    SourceManager &SourceMgr;
+    
+    /// \brief Allocator used to store preprocessing objects.
+    llvm::BumpPtrAllocator BumpAlloc;
+
+    /// \brief The set of preprocessed entities in this record, in order they
+    /// were seen.
+    std::vector<PreprocessedEntity *> PreprocessedEntities;
+    
+    /// \brief The set of preprocessed entities in this record that have been
+    /// loaded from external sources.
+    ///
+    /// The entries in this vector are loaded lazily from the external source,
+    /// and are referenced by the iterator using negative indices.
+    std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
+
+    /// \brief The set of ranges that were skipped by the preprocessor,
+    std::vector<SourceRange> SkippedRanges;
+
+    /// \brief Global (loaded or local) ID for a preprocessed entity.
+    /// Negative values are used to indicate preprocessed entities
+    /// loaded from the external source while non-negative values are used to
+    /// indicate preprocessed entities introduced by the current preprocessor.
+    /// Value -1 corresponds to element 0 in the loaded entities vector,
+    /// value -2 corresponds to element 1 in the loaded entities vector, etc.
+    /// Value 0 is an invalid value, the index to local entities is 1-based,
+    /// value 1 corresponds to element 0 in the local entities vector,
+    /// value 2 corresponds to element 1 in the local entities vector, etc.
+    class PPEntityID {
+      int ID;
+      explicit PPEntityID(int ID) : ID(ID) {}
+      friend class PreprocessingRecord;
+    public:
+      PPEntityID() : ID(0) {}
+    };
+
+    static PPEntityID getPPEntityID(unsigned Index, bool isLoaded) {
+      return isLoaded ? PPEntityID(-int(Index)-1) : PPEntityID(Index+1);
+    }
+
+    /// \brief Mapping from MacroInfo structures to their definitions.
+    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+
+    /// \brief External source of preprocessed entities.
+    ExternalPreprocessingRecordSource *ExternalSource;
+
+    /// \brief Retrieve the preprocessed entity at the given ID.
+    PreprocessedEntity *getPreprocessedEntity(PPEntityID PPID);
+
+    /// \brief Retrieve the loaded preprocessed entity at the given index.
+    PreprocessedEntity *getLoadedPreprocessedEntity(unsigned Index);
+    
+    /// \brief Determine the number of preprocessed entities that were
+    /// loaded (or can be loaded) from an external source.
+    unsigned getNumLoadedPreprocessedEntities() const {
+      return LoadedPreprocessedEntities.size();
+    }
+
+    /// \brief Returns a pair of [Begin, End) indices of local preprocessed
+    /// entities that \p Range encompasses.
+    std::pair<unsigned, unsigned>
+      findLocalPreprocessedEntitiesInRange(SourceRange Range) const;
+    unsigned findBeginLocalPreprocessedEntity(SourceLocation Loc) const;
+    unsigned findEndLocalPreprocessedEntity(SourceLocation Loc) const;
+
+    /// \brief Allocate space for a new set of loaded preprocessed entities.
+    ///
+    /// \returns The index into the set of loaded preprocessed entities, which
+    /// corresponds to the first newly-allocated entity.
+    unsigned allocateLoadedEntities(unsigned NumEntities);
+
+    /// \brief Register a new macro definition.
+    void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def);
+    
+  public:
+    /// \brief Construct a new preprocessing record.
+    explicit PreprocessingRecord(SourceManager &SM);
+    
+    /// \brief Allocate memory in the preprocessing record.
+    void *Allocate(unsigned Size, unsigned Align = 8) {
+      return BumpAlloc.Allocate(Size, Align);
+    }
+    
+    /// \brief Deallocate memory in the preprocessing record.
+    void Deallocate(void *Ptr) { }
+
+    size_t getTotalMemory() const;
+
+    SourceManager &getSourceManager() const { return SourceMgr; }
+
+    // Iteration over the preprocessed entities.
+    class iterator {
+      PreprocessingRecord *Self;
+      
+      /// \brief Position within the preprocessed entity sequence.
+      ///
+      /// In a complete iteration, the Position field walks the range [-M, N),
+      /// where negative values are used to indicate preprocessed entities
+      /// loaded from the external source while non-negative values are used to
+      /// indicate preprocessed entities introduced by the current preprocessor.
+      /// However, to provide iteration in source order (for, e.g., chained
+      /// precompiled headers), dereferencing the iterator flips the negative
+      /// values (corresponding to loaded entities), so that position -M 
+      /// corresponds to element 0 in the loaded entities vector, position -M+1
+      /// corresponds to element 1 in the loaded entities vector, etc. This
+      /// gives us a reasonably efficient, source-order walk.
+      int Position;
+      
+    public:
+      typedef PreprocessedEntity *value_type;
+      typedef value_type&         reference;
+      typedef value_type*         pointer;
+      typedef std::random_access_iterator_tag iterator_category;
+      typedef int                 difference_type;
+      
+      iterator() : Self(nullptr), Position(0) { }
+      
+      iterator(PreprocessingRecord *Self, int Position)
+        : Self(Self), Position(Position) { }
+      
+      value_type operator*() const {
+        bool isLoaded = Position < 0;
+        unsigned Index = isLoaded ?
+            Self->LoadedPreprocessedEntities.size() + Position : Position;
+        PPEntityID ID = Self->getPPEntityID(Index, isLoaded);
+        return Self->getPreprocessedEntity(ID);
+      }
+      
+      value_type operator[](difference_type D) {
+        return *(*this + D);
+      }
+      
+      iterator &operator++() {
+        ++Position;
+        return *this;
+      }
+      
+      iterator operator++(int) {
+        iterator Prev(*this);
+        ++Position;
+        return Prev;
+      }
+
+      iterator &operator--() {
+        --Position;
+        return *this;
+      }
+      
+      iterator operator--(int) {
+        iterator Prev(*this);
+        --Position;
+        return Prev;
+      }
+
+      friend bool operator==(const iterator &X, const iterator &Y) {
+        return X.Position == Y.Position;
+      }
+
+      friend bool operator!=(const iterator &X, const iterator &Y) {
+        return X.Position != Y.Position;
+      }
+      
+      friend bool operator<(const iterator &X, const iterator &Y) {
+        return X.Position < Y.Position;
+      }
+
+      friend bool operator>(const iterator &X, const iterator &Y) {
+        return X.Position > Y.Position;
+      }
+
+      friend bool operator<=(const iterator &X, const iterator &Y) {
+        return X.Position < Y.Position;
+      }
+      
+      friend bool operator>=(const iterator &X, const iterator &Y) {
+        return X.Position > Y.Position;
+      }
+
+      friend iterator& operator+=(iterator &X, difference_type D) {
+        X.Position += D;
+        return X;
+      }
+
+      friend iterator& operator-=(iterator &X, difference_type D) {
+        X.Position -= D;
+        return X;
+      }
+
+      friend iterator operator+(iterator X, difference_type D) {
+        X.Position += D;
+        return X;
+      }
+
+      friend iterator operator+(difference_type D, iterator X) {
+        X.Position += D;
+        return X;
+      }
+
+      friend difference_type operator-(const iterator &X, const iterator &Y) {
+        return X.Position - Y.Position;
+      }
+
+      friend iterator operator-(iterator X, difference_type D) {
+        X.Position -= D;
+        return X;
+      }
+      friend class PreprocessingRecord;
+    };
+    friend class iterator;
+
+    /// \brief Begin iterator for all preprocessed entities.
+    iterator begin() {
+      return iterator(this, -(int)LoadedPreprocessedEntities.size());
+    }
+
+    /// \brief End iterator for all preprocessed entities.
+    iterator end() {
+      return iterator(this, PreprocessedEntities.size());
+    }
+
+    /// \brief Begin iterator for local, non-loaded, preprocessed entities.
+    iterator local_begin() {
+      return iterator(this, 0);
+    }
+
+    /// \brief End iterator for local, non-loaded, preprocessed entities.
+    iterator local_end() {
+      return iterator(this, PreprocessedEntities.size());
+    }
+
+    /// \brief begin/end iterator pair for the given range of loaded
+    /// preprocessed entities.
+    std::pair<iterator, iterator>
+    getIteratorsForLoadedRange(unsigned start, unsigned count) {
+      unsigned end = start + count;
+      assert(end <= LoadedPreprocessedEntities.size());
+      return std::make_pair(
+                   iterator(this, int(start)-LoadedPreprocessedEntities.size()),
+                   iterator(this, int(end)-LoadedPreprocessedEntities.size()));
+    }
+
+    /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
+    /// that source range \p R encompasses.
+    ///
+    /// \param R the range to look for preprocessed entities.
+    ///
+    std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R);
+
+    /// \brief Returns true if the preprocessed entity that \p PPEI iterator
+    /// points to is coming from the file \p FID.
+    ///
+    /// Can be used to avoid implicit deserializations of preallocated
+    /// preprocessed entities if we only care about entities of a specific file
+    /// and not from files \#included in the range given at
+    /// \see getPreprocessedEntitiesInRange.
+    bool isEntityInFileID(iterator PPEI, FileID FID);
+
+    /// \brief Add a new preprocessed entity to this record.
+    PPEntityID addPreprocessedEntity(PreprocessedEntity *Entity);
+
+    /// \brief Set the external source for preprocessed entities.
+    void SetExternalSource(ExternalPreprocessingRecordSource &Source);
+
+    /// \brief Retrieve the external source for preprocessed entities.
+    ExternalPreprocessingRecordSource *getExternalSource() const {
+      return ExternalSource;
+    }
+    
+    /// \brief Retrieve the macro definition that corresponds to the given
+    /// \c MacroInfo.
+    MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+
+    /// \brief Retrieve all ranges that got skipped while preprocessing.
+    const std::vector<SourceRange> &getSkippedRanges() const {
+      return SkippedRanges;
+    }
+        
+  private:
+    void MacroExpands(const Token &Id, const MacroDirective *MD,
+                      SourceRange Range, const MacroArgs *Args) override;
+    void MacroDefined(const Token &Id, const MacroDirective *MD) override;
+    void MacroUndefined(const Token &Id, const MacroDirective *MD) override;
+    void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                            StringRef FileName, bool IsAngled,
+                            CharSourceRange FilenameRange,
+                            const FileEntry *File, StringRef SearchPath,
+                            StringRef RelativePath,
+                            const Module *Imported) override;
+    void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+               const MacroDirective *MD) override;
+    void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+                const MacroDirective *MD) override;
+    /// \brief Hook called whenever the 'defined' operator is seen.
+    void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+                 SourceRange Range) override;
+
+    void SourceRangeSkipped(SourceRange Range) override;
+
+    void addMacroExpansion(const Token &Id, const MacroInfo *MI,
+                           SourceRange Range);
+
+    /// \brief Cached result of the last \see getPreprocessedEntitiesInRange
+    /// query.
+    struct {
+      SourceRange Range;
+      std::pair<int, int> Result;
+    } CachedRangeQuery;
+
+    std::pair<int, int> getPreprocessedEntitiesInRangeSlow(SourceRange R);
+
+    friend class ASTReader;
+    friend class ASTWriter;
+  };
+} // end namespace clang
+
+inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,
+                          unsigned alignment) throw() {
+  return PR.Allocate(bytes, alignment);
+}
+
+inline void operator delete(void* ptr, clang::PreprocessingRecord& PR,
+                            unsigned) throw() {
+  PR.Deallocate(ptr);
+}
+
+#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
new file mode 100644
index 0000000..d4b4ba2
--- /dev/null
+++ b/include/clang/Lex/Preprocessor.h
@@ -0,0 +1,1583 @@
+//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::Preprocessor interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
+#define LLVM_CLANG_LEX_PREPROCESSOR_H
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/ModuleMap.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/PTHManager.h"
+#include "clang/Lex/TokenLexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+  template<unsigned InternalLen> class SmallString;
+}
+
+namespace clang {
+
+class SourceManager;
+class ExternalPreprocessorSource;
+class FileManager;
+class FileEntry;
+class HeaderSearch;
+class PragmaNamespace;
+class PragmaHandler;
+class CommentHandler;
+class ScratchBuffer;
+class TargetInfo;
+class PPCallbacks;
+class CodeCompletionHandler;
+class DirectoryLookup;
+class PreprocessingRecord;
+class ModuleLoader;
+class PreprocessorOptions;
+
+/// \brief Stores token information for comparing actual tokens with
+/// predefined values.  Only handles simple tokens and identifiers.
+class TokenValue {
+  tok::TokenKind Kind;
+  IdentifierInfo *II;
+
+public:
+  TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
+    assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
+    assert(Kind != tok::identifier &&
+           "Identifiers should be created by TokenValue(IdentifierInfo *)");
+    assert(!tok::isLiteral(Kind) && "Literals are not supported.");
+    assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
+  }
+  TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
+  bool operator==(const Token &Tok) const {
+    return Tok.getKind() == Kind &&
+        (!II || II == Tok.getIdentifierInfo());
+  }
+};
+
+/// \brief Engages in a tight little dance with the lexer to efficiently
+/// preprocess tokens.
+///
+/// Lexers know only about tokens within a single source file, and don't
+/// know anything about preprocessor-level issues like the \#include stack,
+/// token expansion, etc.
+class Preprocessor : public RefCountedBase<Preprocessor> {
+  IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
+  DiagnosticsEngine        *Diags;
+  LangOptions       &LangOpts;
+  const TargetInfo  *Target;
+  FileManager       &FileMgr;
+  SourceManager     &SourceMgr;
+  ScratchBuffer     *ScratchBuf;
+  HeaderSearch      &HeaderInfo;
+  ModuleLoader      &TheModuleLoader;
+
+  /// \brief External source of macros.
+  ExternalPreprocessorSource *ExternalSource;
+
+
+  /// An optional PTHManager object used for getting tokens from
+  /// a token cache rather than lexing the original source file.
+  std::unique_ptr<PTHManager> PTH;
+
+  /// A BumpPtrAllocator object used to quickly allocate and release
+  /// objects internal to the Preprocessor.
+  llvm::BumpPtrAllocator BP;
+
+  /// Identifiers for builtin macros and other builtins.
+  IdentifierInfo *Ident__LINE__, *Ident__FILE__;   // __LINE__, __FILE__
+  IdentifierInfo *Ident__DATE__, *Ident__TIME__;   // __DATE__, __TIME__
+  IdentifierInfo *Ident__INCLUDE_LEVEL__;          // __INCLUDE_LEVEL__
+  IdentifierInfo *Ident__BASE_FILE__;              // __BASE_FILE__
+  IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
+  IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
+  IdentifierInfo *Ident_Pragma, *Ident__pragma;    // _Pragma, __pragma
+  IdentifierInfo *Ident__identifier;               // __identifier
+  IdentifierInfo *Ident__VA_ARGS__;                // __VA_ARGS__
+  IdentifierInfo *Ident__has_feature;              // __has_feature
+  IdentifierInfo *Ident__has_extension;            // __has_extension
+  IdentifierInfo *Ident__has_builtin;              // __has_builtin
+  IdentifierInfo *Ident__has_attribute;            // __has_attribute
+  IdentifierInfo *Ident__has_include;              // __has_include
+  IdentifierInfo *Ident__has_include_next;         // __has_include_next
+  IdentifierInfo *Ident__has_warning;              // __has_warning
+  IdentifierInfo *Ident__is_identifier;            // __is_identifier
+  IdentifierInfo *Ident__building_module;          // __building_module
+  IdentifierInfo *Ident__MODULE__;                 // __MODULE__
+
+  SourceLocation DATELoc, TIMELoc;
+  unsigned CounterValue;  // Next __COUNTER__ value.
+
+  enum {
+    /// \brief Maximum depth of \#includes.
+    MaxAllowedIncludeStackDepth = 200
+  };
+
+  // State that is set before the preprocessor begins.
+  bool KeepComments : 1;
+  bool KeepMacroComments : 1;
+  bool SuppressIncludeNotFoundError : 1;
+
+  // State that changes while the preprocessor runs:
+  bool InMacroArgs : 1;            // True if parsing fn macro invocation args.
+
+  /// Whether the preprocessor owns the header search object.
+  bool OwnsHeaderSearch : 1;
+
+  /// True if macro expansion is disabled.
+  bool DisableMacroExpansion : 1;
+
+  /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
+  /// when parsing preprocessor directives.
+  bool MacroExpansionInDirectivesOverride : 1;
+
+  class ResetMacroExpansionHelper;
+
+  /// \brief Whether we have already loaded macros from the external source.
+  mutable bool ReadMacrosFromExternalSource : 1;
+
+  /// \brief True if pragmas are enabled.
+  bool PragmasEnabled : 1;
+
+  /// \brief True if the current build action is a preprocessing action.
+  bool PreprocessedOutput : 1;
+
+  /// \brief True if we are currently preprocessing a #if or #elif directive
+  bool ParsingIfOrElifDirective;
+
+  /// \brief True if we are pre-expanding macro arguments.
+  bool InMacroArgPreExpansion;
+
+  /// \brief Mapping/lookup information for all identifiers in
+  /// the program, including program keywords.
+  mutable IdentifierTable Identifiers;
+
+  /// \brief This table contains all the selectors in the program.
+  ///
+  /// Unlike IdentifierTable above, this table *isn't* populated by the
+  /// preprocessor. It is declared/expanded here because its role/lifetime is
+  /// conceptually similar to the IdentifierTable. In addition, the current
+  /// control flow (in clang::ParseAST()), make it convenient to put here.
+  ///
+  /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
+  /// the lifetime of the preprocessor.
+  SelectorTable Selectors;
+
+  /// \brief Information about builtins.
+  Builtin::Context BuiltinInfo;
+
+  /// \brief Tracks all of the pragmas that the client registered
+  /// with this preprocessor.
+  PragmaNamespace *PragmaHandlers;
+
+  /// \brief Tracks all of the comment handlers that the client registered
+  /// with this preprocessor.
+  std::vector<CommentHandler *> CommentHandlers;
+
+  /// \brief True if we want to ignore EOF token and continue later on (thus 
+  /// avoid tearing the Lexer and etc. down).
+  bool IncrementalProcessing;
+
+  /// The kind of translation unit we are processing.
+  TranslationUnitKind TUKind;
+
+  /// \brief The code-completion handler.
+  CodeCompletionHandler *CodeComplete;
+
+  /// \brief The file that we're performing code-completion for, if any.
+  const FileEntry *CodeCompletionFile;
+
+  /// \brief The offset in file for the code-completion point.
+  unsigned CodeCompletionOffset;
+
+  /// \brief The location for the code-completion point. This gets instantiated
+  /// when the CodeCompletionFile gets \#include'ed for preprocessing.
+  SourceLocation CodeCompletionLoc;
+
+  /// \brief The start location for the file of the code-completion point.
+  ///
+  /// This gets instantiated when the CodeCompletionFile gets \#include'ed
+  /// for preprocessing.
+  SourceLocation CodeCompletionFileLoc;
+
+  /// \brief The source location of the \c import contextual keyword we just 
+  /// lexed, if any.
+  SourceLocation ModuleImportLoc;
+
+  /// \brief The module import path that we're currently processing.
+  SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
+
+  /// \brief Whether the last token we lexed was an '@'.
+  bool LastTokenWasAt;
+
+  /// \brief Whether the module import expects an identifier next. Otherwise,
+  /// it expects a '.' or ';'.
+  bool ModuleImportExpectsIdentifier;
+  
+  /// \brief The source location of the currently-active
+  /// \#pragma clang arc_cf_code_audited begin.
+  SourceLocation PragmaARCCFCodeAuditedLoc;
+
+  /// \brief True if we hit the code-completion point.
+  bool CodeCompletionReached;
+
+  /// \brief The number of bytes that we will initially skip when entering the
+  /// main file, along with a flag that indicates whether skipping this number
+  /// of bytes will place the lexer at the start of a line.
+  ///
+  /// This is used when loading a precompiled preamble.
+  std::pair<unsigned, bool> SkipMainFilePreamble;
+
+  /// \brief The current top of the stack that we're lexing from if
+  /// not expanding a macro and we are lexing directly from source code.
+  ///
+  /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  std::unique_ptr<Lexer> CurLexer;
+
+  /// \brief The current top of stack that we're lexing from if
+  /// not expanding from a macro and we are lexing from a PTH cache.
+  ///
+  /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  std::unique_ptr<PTHLexer> CurPTHLexer;
+
+  /// \brief The current top of the stack what we're lexing from
+  /// if not expanding a macro.
+  ///
+  /// This is an alias for either CurLexer or  CurPTHLexer.
+  PreprocessorLexer *CurPPLexer;
+
+  /// \brief Used to find the current FileEntry, if CurLexer is non-null
+  /// and if applicable.
+  ///
+  /// This allows us to implement \#include_next and find directory-specific
+  /// properties.
+  const DirectoryLookup *CurDirLookup;
+
+  /// \brief The current macro we are expanding, if we are expanding a macro.
+  ///
+  /// One of CurLexer and CurTokenLexer must be null.
+  std::unique_ptr<TokenLexer> CurTokenLexer;
+
+  /// \brief The kind of lexer we're currently working with.
+  enum CurLexerKind {
+    CLK_Lexer,
+    CLK_PTHLexer,
+    CLK_TokenLexer,
+    CLK_CachingLexer,
+    CLK_LexAfterModuleImport
+  } CurLexerKind;
+
+  /// \brief If the current lexer is for a submodule that is being built, this
+  /// is that submodule.
+  Module *CurSubmodule;
+
+  /// \brief Keeps track of the stack of files currently
+  /// \#included, and macros currently being expanded from, not counting
+  /// CurLexer/CurTokenLexer.
+  struct IncludeStackInfo {
+    enum CurLexerKind           CurLexerKind;
+    Module                     *TheSubmodule;
+    std::unique_ptr<Lexer>      TheLexer;
+    std::unique_ptr<PTHLexer>   ThePTHLexer;
+    PreprocessorLexer          *ThePPLexer;
+    std::unique_ptr<TokenLexer> TheTokenLexer;
+    const DirectoryLookup      *TheDirLookup;
+
+    // The following constructors are completely useless copies of the default
+    // versions, only needed to pacify MSVC.
+    IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
+                     std::unique_ptr<Lexer> &&TheLexer,
+                     std::unique_ptr<PTHLexer> &&ThePTHLexer,
+                     PreprocessorLexer *ThePPLexer,
+                     std::unique_ptr<TokenLexer> &&TheTokenLexer,
+                     const DirectoryLookup *TheDirLookup)
+        : CurLexerKind(std::move(CurLexerKind)),
+          TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
+          ThePTHLexer(std::move(ThePTHLexer)),
+          ThePPLexer(std::move(ThePPLexer)),
+          TheTokenLexer(std::move(TheTokenLexer)),
+          TheDirLookup(std::move(TheDirLookup)) {}
+    IncludeStackInfo(IncludeStackInfo &&RHS)
+        : CurLexerKind(std::move(RHS.CurLexerKind)),
+          TheSubmodule(std::move(RHS.TheSubmodule)),
+          TheLexer(std::move(RHS.TheLexer)),
+          ThePTHLexer(std::move(RHS.ThePTHLexer)),
+          ThePPLexer(std::move(RHS.ThePPLexer)),
+          TheTokenLexer(std::move(RHS.TheTokenLexer)),
+          TheDirLookup(std::move(RHS.TheDirLookup)) {}
+  };
+  std::vector<IncludeStackInfo> IncludeMacroStack;
+
+  /// \brief Actions invoked when some preprocessor activity is
+  /// encountered (e.g. a file is \#included, etc).
+  PPCallbacks *Callbacks;
+
+  struct MacroExpandsInfo {
+    Token Tok;
+    MacroDirective *MD;
+    SourceRange Range;
+    MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range)
+      : Tok(Tok), MD(MD), Range(Range) { }
+  };
+  SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
+
+  /// For each IdentifierInfo that was associated with a macro, we
+  /// keep a mapping to the history of all macro definitions and #undefs in
+  /// the reverse order (the latest one is in the head of the list).
+  llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
+  friend class ASTReader;
+  
+  /// \brief Macros that we want to warn because they are not used at the end
+  /// of the translation unit.
+  ///
+  /// We store just their SourceLocations instead of
+  /// something like MacroInfo*. The benefit of this is that when we are
+  /// deserializing from PCH, we don't need to deserialize identifier & macros
+  /// just so that we can report that they are unused, we just warn using
+  /// the SourceLocations of this set (that will be filled by the ASTReader).
+  /// We are using SmallPtrSet instead of a vector for faster removal.
+  typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
+  WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
+
+  /// \brief A "freelist" of MacroArg objects that can be
+  /// reused for quick allocation.
+  MacroArgs *MacroArgCache;
+  friend class MacroArgs;
+
+  /// For each IdentifierInfo used in a \#pragma push_macro directive,
+  /// we keep a MacroInfo stack used to restore the previous macro value.
+  llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
+
+  // Various statistics we track for performance analysis.
+  unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
+  unsigned NumIf, NumElse, NumEndif;
+  unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
+  unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
+  unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
+  unsigned NumSkipped;
+
+  /// \brief The predefined macros that preprocessor should use from the
+  /// command line etc.
+  std::string Predefines;
+
+  /// \brief The file ID for the preprocessor predefines.
+  FileID PredefinesFileID;
+
+  /// \{
+  /// \brief Cache of macro expanders to reduce malloc traffic.
+  enum { TokenLexerCacheSize = 8 };
+  unsigned NumCachedTokenLexers;
+  TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+  /// \}
+
+  /// \brief Keeps macro expanded tokens for TokenLexers.
+  //
+  /// Works like a stack; a TokenLexer adds the macro expanded tokens that is
+  /// going to lex in the cache and when it finishes the tokens are removed
+  /// from the end of the cache.
+  SmallVector<Token, 16> MacroExpandedTokens;
+  std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
+
+  /// \brief A record of the macro definitions and expansions that
+  /// occurred during preprocessing.
+  ///
+  /// This is an optional side structure that can be enabled with
+  /// \c createPreprocessingRecord() prior to preprocessing.
+  PreprocessingRecord *Record;
+
+private:  // Cached tokens state.
+  typedef SmallVector<Token, 1> CachedTokensTy;
+
+  /// \brief Cached tokens are stored here when we do backtracking or
+  /// lookahead. They are "lexed" by the CachingLex() method.
+  CachedTokensTy CachedTokens;
+
+  /// \brief The position of the cached token that CachingLex() should
+  /// "lex" next.
+  ///
+  /// If it points beyond the CachedTokens vector, it means that a normal
+  /// Lex() should be invoked.
+  CachedTokensTy::size_type CachedLexPos;
+
+  /// \brief Stack of backtrack positions, allowing nested backtracks.
+  ///
+  /// The EnableBacktrackAtThisPos() method pushes a position to
+  /// indicate where CachedLexPos should be set when the BackTrack() method is
+  /// invoked (at which point the last position is popped).
+  std::vector<CachedTokensTy::size_type> BacktrackPositions;
+
+  struct MacroInfoChain {
+    MacroInfo MI;
+    MacroInfoChain *Next;
+    MacroInfoChain *Prev;
+  };
+
+  /// MacroInfos are managed as a chain for easy disposal.  This is the head
+  /// of that list.
+  MacroInfoChain *MIChainHead;
+
+  /// A "freelist" of MacroInfo objects that can be reused for quick
+  /// allocation.
+  MacroInfoChain *MICache;
+
+  struct DeserializedMacroInfoChain {
+    MacroInfo MI;
+    unsigned OwningModuleID; // MUST be immediately after the MacroInfo object
+                     // so it can be accessed by MacroInfo::getOwningModuleID().
+    DeserializedMacroInfoChain *Next;
+  };
+  DeserializedMacroInfoChain *DeserialMIChainHead;
+
+public:
+  Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+               DiagnosticsEngine &diags, LangOptions &opts,
+               SourceManager &SM, HeaderSearch &Headers,
+               ModuleLoader &TheModuleLoader,
+               IdentifierInfoLookup *IILookup = nullptr,
+               bool OwnsHeaderSearch = false,
+               TranslationUnitKind TUKind = TU_Complete);
+
+  ~Preprocessor();
+
+  /// \brief Initialize the preprocessor using information about the target.
+  ///
+  /// \param Target is owned by the caller and must remain valid for the
+  /// lifetime of the preprocessor.
+  void Initialize(const TargetInfo &Target);
+
+  /// \brief Retrieve the preprocessor options used to initialize this
+  /// preprocessor.
+  PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
+  
+  DiagnosticsEngine &getDiagnostics() const { return *Diags; }
+  void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
+
+  const LangOptions &getLangOpts() const { return LangOpts; }
+  const TargetInfo &getTargetInfo() const { return *Target; }
+  FileManager &getFileManager() const { return FileMgr; }
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
+
+  IdentifierTable &getIdentifierTable() { return Identifiers; }
+  SelectorTable &getSelectorTable() { return Selectors; }
+  Builtin::Context &getBuiltinInfo() { return BuiltinInfo; }
+  llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; }
+
+  void setPTHManager(PTHManager* pm);
+
+  PTHManager *getPTHManager() { return PTH.get(); }
+
+  void setExternalSource(ExternalPreprocessorSource *Source) {
+    ExternalSource = Source;
+  }
+
+  ExternalPreprocessorSource *getExternalSource() const {
+    return ExternalSource;
+  }
+
+  /// \brief Retrieve the module loader associated with this preprocessor.
+  ModuleLoader &getModuleLoader() const { return TheModuleLoader; }
+
+  bool hadModuleLoaderFatalFailure() const {
+    return TheModuleLoader.HadFatalFailure;
+  }
+
+  /// \brief True if we are currently preprocessing a #if or #elif directive
+  bool isParsingIfOrElifDirective() const { 
+    return ParsingIfOrElifDirective;
+  }
+
+  /// \brief Control whether the preprocessor retains comments in output.
+  void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
+    this->KeepComments = KeepComments | KeepMacroComments;
+    this->KeepMacroComments = KeepMacroComments;
+  }
+
+  bool getCommentRetentionState() const { return KeepComments; }
+
+  void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
+  bool getPragmasEnabled() const { return PragmasEnabled; }
+
+  void SetSuppressIncludeNotFoundError(bool Suppress) {
+    SuppressIncludeNotFoundError = Suppress;
+  }
+
+  bool GetSuppressIncludeNotFoundError() {
+    return SuppressIncludeNotFoundError;
+  }
+
+  /// Sets whether the preprocessor is responsible for producing output or if
+  /// it is producing tokens to be consumed by Parse and Sema.
+  void setPreprocessedOutput(bool IsPreprocessedOutput) {
+    PreprocessedOutput = IsPreprocessedOutput;
+  }
+
+  /// Returns true if the preprocessor is responsible for generating output,
+  /// false if it is producing tokens to be consumed by Parse and Sema.
+  bool isPreprocessedOutput() const { return PreprocessedOutput; }
+
+  /// \brief Return true if we are lexing directly from the specified lexer.
+  bool isCurrentLexer(const PreprocessorLexer *L) const {
+    return CurPPLexer == L;
+  }
+
+  /// \brief Return the current lexer being lexed from.
+  ///
+  /// Note that this ignores any potentially active macro expansions and _Pragma
+  /// expansions going on at the time.
+  PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
+
+  /// \brief Return the current file lexer being lexed from.
+  ///
+  /// Note that this ignores any potentially active macro expansions and _Pragma
+  /// expansions going on at the time.
+  PreprocessorLexer *getCurrentFileLexer() const;
+
+  /// \brief Returns the FileID for the preprocessor predefines.
+  FileID getPredefinesFileID() const { return PredefinesFileID; }
+
+  /// \{
+  /// \brief Accessors for preprocessor callbacks.
+  ///
+  /// Note that this class takes ownership of any PPCallbacks object given to
+  /// it.
+  PPCallbacks *getPPCallbacks() const { return Callbacks; }
+  void addPPCallbacks(PPCallbacks *C) {
+    if (Callbacks)
+      C = new PPChainedCallbacks(C, Callbacks);
+    Callbacks = C;
+  }
+  /// \}
+
+  /// \brief Given an identifier, return its latest MacroDirective if it is
+  /// \#defined or null if it isn't \#define'd.
+  MacroDirective *getMacroDirective(IdentifierInfo *II) const {
+    if (!II->hasMacroDefinition())
+      return nullptr;
+
+    MacroDirective *MD = getMacroDirectiveHistory(II);
+    assert(MD->isDefined() && "Macro is undefined!");
+    return MD;
+  }
+
+  const MacroInfo *getMacroInfo(IdentifierInfo *II) const {
+    return const_cast<Preprocessor*>(this)->getMacroInfo(II);
+  }
+
+  MacroInfo *getMacroInfo(IdentifierInfo *II) {
+    if (MacroDirective *MD = getMacroDirective(II))
+      return MD->getMacroInfo();
+    return nullptr;
+  }
+
+  /// \brief Given an identifier, return the (probably #undef'd) MacroInfo
+  /// representing the most recent macro definition.
+  ///
+  /// One can iterate over all previous macro definitions from the most recent
+  /// one. This should only be called for identifiers that hadMacroDefinition().
+  MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
+
+  /// \brief Add a directive to the macro directive history for this identifier.
+  void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+  DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
+                                             SourceLocation Loc,
+                                             bool isImported) {
+    DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+    appendMacroDirective(II, MD);
+    return MD;
+  }
+  DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
+    return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+  }
+  /// \brief Set a MacroDirective that was loaded from a PCH file.
+  void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+
+  /// \{
+  /// Iterators for the macro history table. Currently defined macros have
+  /// IdentifierInfo::hasMacroDefinition() set and an empty
+  /// MacroInfo::getUndefLoc() at the head of the list.
+  typedef llvm::DenseMap<const IdentifierInfo *,
+                         MacroDirective*>::const_iterator macro_iterator;
+  macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
+  macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+  /// \}
+
+  /// \brief Return the name of the macro defined before \p Loc that has
+  /// spelling \p Tokens.  If there are multiple macros with same spelling,
+  /// return the last one defined.
+  StringRef getLastMacroWithSpelling(SourceLocation Loc,
+                                     ArrayRef<TokenValue> Tokens) const;
+
+  const std::string &getPredefines() const { return Predefines; }
+  /// \brief Set the predefines for this Preprocessor.
+  ///
+  /// These predefines are automatically injected when parsing the main file.
+  void setPredefines(const char *P) { Predefines = P; }
+  void setPredefines(const std::string &P) { Predefines = P; }
+
+  /// Return information about the specified preprocessor
+  /// identifier token.
+  IdentifierInfo *getIdentifierInfo(StringRef Name) const {
+    return &Identifiers.get(Name);
+  }
+
+  /// \brief Add the specified pragma handler to this preprocessor.
+  ///
+  /// If \p Namespace is non-null, then it is a token required to exist on the
+  /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
+  void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
+  void AddPragmaHandler(PragmaHandler *Handler) {
+    AddPragmaHandler(StringRef(), Handler);
+  }
+
+  /// \brief Remove the specific pragma handler from this preprocessor.
+  ///
+  /// If \p Namespace is non-null, then it should be the namespace that
+  /// \p Handler was added to. It is an error to remove a handler that
+  /// has not been registered.
+  void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
+  void RemovePragmaHandler(PragmaHandler *Handler) {
+    RemovePragmaHandler(StringRef(), Handler);
+  }
+
+  /// Install empty handlers for all pragmas (making them ignored).
+  void IgnorePragmas();
+
+  /// \brief Add the specified comment handler to the preprocessor.
+  void addCommentHandler(CommentHandler *Handler);
+
+  /// \brief Remove the specified comment handler.
+  ///
+  /// It is an error to remove a handler that has not been registered.
+  void removeCommentHandler(CommentHandler *Handler);
+
+  /// \brief Set the code completion handler to the given object.
+  void setCodeCompletionHandler(CodeCompletionHandler &Handler) {
+    CodeComplete = &Handler;
+  }
+
+  /// \brief Retrieve the current code-completion handler.
+  CodeCompletionHandler *getCodeCompletionHandler() const {
+    return CodeComplete;
+  }
+
+  /// \brief Clear out the code completion handler.
+  void clearCodeCompletionHandler() {
+    CodeComplete = nullptr;
+  }
+
+  /// \brief Hook used by the lexer to invoke the "natural language" code
+  /// completion point.
+  void CodeCompleteNaturalLanguage();
+
+  /// \brief Retrieve the preprocessing record, or NULL if there is no
+  /// preprocessing record.
+  PreprocessingRecord *getPreprocessingRecord() const { return Record; }
+
+  /// \brief Create a new preprocessing record, which will keep track of
+  /// all macro expansions, macro definitions, etc.
+  void createPreprocessingRecord();
+
+  /// \brief Enter the specified FileID as the main source file,
+  /// which implicitly adds the builtin defines etc.
+  void EnterMainSourceFile();
+
+  /// \brief Inform the preprocessor callbacks that processing is complete.
+  void EndSourceFile();
+
+  /// \brief Add a source file to the top of the include stack and
+  /// start lexing tokens from it instead of the current buffer.
+  ///
+  /// Emits a diagnostic, doesn't enter the file, and returns true on error.
+  bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+                       SourceLocation Loc);
+
+  /// \brief Add a Macro to the top of the include stack and start lexing
+  /// tokens from it instead of the current buffer.
+  ///
+  /// \param Args specifies the tokens input to a function-like macro.
+  /// \param ILEnd specifies the location of the ')' for a function-like macro
+  /// or the identifier for an object-like macro.
+  void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
+                  MacroArgs *Args);
+
+  /// \brief Add a "macro" context to the top of the include stack,
+  /// which will cause the lexer to start returning the specified tokens.
+  ///
+  /// If \p DisableMacroExpansion is true, tokens lexed from the token stream
+  /// will not be subject to further macro expansion. Otherwise, these tokens
+  /// will be re-macro-expanded when/if expansion is enabled.
+  ///
+  /// If \p OwnsTokens is false, this method assumes that the specified stream
+  /// of tokens has a permanent owner somewhere, so they do not need to be
+  /// copied. If it is true, it assumes the array of tokens is allocated with
+  /// \c new[] and must be freed.
+  void EnterTokenStream(const Token *Toks, unsigned NumToks,
+                        bool DisableMacroExpansion, bool OwnsTokens);
+
+  /// \brief Pop the current lexer/macro exp off the top of the lexer stack.
+  ///
+  /// This should only be used in situations where the current state of the
+  /// top-of-stack lexer is known.
+  void RemoveTopOfLexerStack();
+
+  /// From the point that this method is called, and until
+  /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+  /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
+  /// make the Preprocessor re-lex the same tokens.
+  ///
+  /// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
+  /// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
+  /// be combined with the EnableBacktrackAtThisPos calls in reverse order.
+  ///
+  /// NOTE: *DO NOT* forget to call either CommitBacktrackedTokens or Backtrack
+  /// at some point after EnableBacktrackAtThisPos. If you don't, caching of
+  /// tokens will continue indefinitely.
+  ///
+  void EnableBacktrackAtThisPos();
+
+  /// \brief Disable the last EnableBacktrackAtThisPos call.
+  void CommitBacktrackedTokens();
+
+  /// \brief Make Preprocessor re-lex the tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  void Backtrack();
+
+  /// \brief True if EnableBacktrackAtThisPos() was called and
+  /// caching of tokens is on.
+  bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
+
+  /// \brief Lex the next token for this preprocessor.
+  void Lex(Token &Result);
+
+  void LexAfterModuleImport(Token &Result);
+
+  /// \brief Lex a string literal, which may be the concatenation of multiple
+  /// string literals and may even come from macro expansion.
+  /// \returns true on success, false if a error diagnostic has been generated.
+  bool LexStringLiteral(Token &Result, std::string &String,
+                        const char *DiagnosticTag, bool AllowMacroExpansion) {
+    if (AllowMacroExpansion)
+      Lex(Result);
+    else
+      LexUnexpandedToken(Result);
+    return FinishLexStringLiteral(Result, String, DiagnosticTag,
+                                  AllowMacroExpansion);
+  }
+
+  /// \brief Complete the lexing of a string literal where the first token has
+  /// already been lexed (see LexStringLiteral).
+  bool FinishLexStringLiteral(Token &Result, std::string &String,
+                              const char *DiagnosticTag,
+                              bool AllowMacroExpansion);
+
+  /// \brief Lex a token.  If it's a comment, keep lexing until we get
+  /// something not a comment.
+  ///
+  /// This is useful in -E -C mode where comments would foul up preprocessor
+  /// directive handling.
+  void LexNonComment(Token &Result) {
+    do
+      Lex(Result);
+    while (Result.getKind() == tok::comment);
+  }
+
+  /// \brief Just like Lex, but disables macro expansion of identifier tokens.
+  void LexUnexpandedToken(Token &Result) {
+    // Disable macro expansion.
+    bool OldVal = DisableMacroExpansion;
+    DisableMacroExpansion = true;
+    // Lex the token.
+    Lex(Result);
+
+    // Reenable it.
+    DisableMacroExpansion = OldVal;
+  }
+
+  /// \brief Like LexNonComment, but this disables macro expansion of
+  /// identifier tokens.
+  void LexUnexpandedNonComment(Token &Result) {
+    do
+      LexUnexpandedToken(Result);
+    while (Result.getKind() == tok::comment);
+  }
+
+  /// \brief Parses a simple integer literal to get its numeric value.  Floating
+  /// point literals and user defined literals are rejected.  Used primarily to
+  /// handle pragmas that accept integer arguments.
+  bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
+
+  /// Disables macro expansion everywhere except for preprocessor directives.
+  void SetMacroExpansionOnlyInDirectives() {
+    DisableMacroExpansion = true;
+    MacroExpansionInDirectivesOverride = true;
+  }
+
+  /// \brief Peeks ahead N tokens and returns that token without consuming any
+  /// tokens.
+  ///
+  /// LookAhead(0) returns the next token that would be returned by Lex(),
+  /// LookAhead(1) returns the token after it, etc.  This returns normal
+  /// tokens after phase 5.  As such, it is equivalent to using
+  /// 'Lex', not 'LexUnexpandedToken'.
+  const Token &LookAhead(unsigned N) {
+    if (CachedLexPos + N < CachedTokens.size())
+      return CachedTokens[CachedLexPos+N];
+    else
+      return PeekAhead(N+1);
+  }
+
+  /// \brief When backtracking is enabled and tokens are cached,
+  /// this allows to revert a specific number of tokens.
+  ///
+  /// Note that the number of tokens being reverted should be up to the last
+  /// backtrack position, not more.
+  void RevertCachedTokens(unsigned N) {
+    assert(isBacktrackEnabled() &&
+           "Should only be called when tokens are cached for backtracking");
+    assert(signed(CachedLexPos) - signed(N) >= signed(BacktrackPositions.back())
+         && "Should revert tokens up to the last backtrack position, not more");
+    assert(signed(CachedLexPos) - signed(N) >= 0 &&
+           "Corrupted backtrack positions ?");
+    CachedLexPos -= N;
+  }
+
+  /// \brief Enters a token in the token stream to be lexed next.
+  ///
+  /// If BackTrack() is called afterwards, the token will remain at the
+  /// insertion point.
+  void EnterToken(const Token &Tok) {
+    EnterCachingLexMode();
+    CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
+  }
+
+  /// We notify the Preprocessor that if it is caching tokens (because
+  /// backtrack is enabled) it should replace the most recent cached tokens
+  /// with the given annotation token. This function has no effect if
+  /// backtracking is not enabled.
+  ///
+  /// Note that the use of this function is just for optimization, so that the
+  /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
+  /// invoked.
+  void AnnotateCachedTokens(const Token &Tok) {
+    assert(Tok.isAnnotation() && "Expected annotation token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      AnnotatePreviousCachedTokens(Tok);
+  }
+
+  /// Get the location of the last cached token, suitable for setting the end
+  /// location of an annotation token.
+  SourceLocation getLastCachedTokenLocation() const {
+    assert(CachedLexPos != 0);
+    return CachedTokens[CachedLexPos-1].getLocation();
+  }
+
+  /// \brief Replace the last token with an annotation token.
+  ///
+  /// Like AnnotateCachedTokens(), this routine replaces an
+  /// already-parsed (and resolved) token with an annotation
+  /// token. However, this routine only replaces the last token with
+  /// the annotation token; it does not affect any other cached
+  /// tokens. This function has no effect if backtracking is not
+  /// enabled.
+  void ReplaceLastTokenWithAnnotation(const Token &Tok) {
+    assert(Tok.isAnnotation() && "Expected annotation token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      CachedTokens[CachedLexPos-1] = Tok;
+  }
+
+  /// Update the current token to represent the provided
+  /// identifier, in order to cache an action performed by typo correction.
+  void TypoCorrectToken(const Token &Tok) {
+    assert(Tok.getIdentifierInfo() && "Expected identifier token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      CachedTokens[CachedLexPos-1] = Tok;
+  }
+
+  /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
+  /// CurTokenLexer pointers.
+  void recomputeCurLexerKind();
+
+  /// \brief Returns true if incremental processing is enabled
+  bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
+
+  /// \brief Enables the incremental processing
+  void enableIncrementalProcessing(bool value = true) {
+    IncrementalProcessing = value;
+  }
+  
+  /// \brief Specify the point at which code-completion will be performed.
+  ///
+  /// \param File the file in which code completion should occur. If
+  /// this file is included multiple times, code-completion will
+  /// perform completion the first time it is included. If NULL, this
+  /// function clears out the code-completion point.
+  ///
+  /// \param Line the line at which code completion should occur
+  /// (1-based).
+  ///
+  /// \param Column the column at which code completion should occur
+  /// (1-based).
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool SetCodeCompletionPoint(const FileEntry *File,
+                              unsigned Line, unsigned Column);
+
+  /// \brief Determine if we are performing code completion.
+  bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
+
+  /// \brief Returns the location of the code-completion point.
+  ///
+  /// Returns an invalid location if code-completion is not enabled or the file
+  /// containing the code-completion point has not been lexed yet.
+  SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
+
+  /// \brief Returns the start location of the file of code-completion point.
+  ///
+  /// Returns an invalid location if code-completion is not enabled or the file
+  /// containing the code-completion point has not been lexed yet.
+  SourceLocation getCodeCompletionFileLoc() const {
+    return CodeCompletionFileLoc;
+  }
+
+  /// \brief Returns true if code-completion is enabled and we have hit the
+  /// code-completion point.
+  bool isCodeCompletionReached() const { return CodeCompletionReached; }
+
+  /// \brief Note that we hit the code-completion point.
+  void setCodeCompletionReached() {
+    assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
+    CodeCompletionReached = true;
+    // Silence any diagnostics that occur after we hit the code-completion.
+    getDiagnostics().setSuppressAllDiagnostics(true);
+  }
+
+  /// \brief The location of the currently-active \#pragma clang
+  /// arc_cf_code_audited begin.
+  ///
+  /// Returns an invalid location if there is no such pragma active.
+  SourceLocation getPragmaARCCFCodeAuditedLoc() const {
+    return PragmaARCCFCodeAuditedLoc;
+  }
+
+  /// \brief Set the location of the currently-active \#pragma clang
+  /// arc_cf_code_audited begin.  An invalid location ends the pragma.
+  void setPragmaARCCFCodeAuditedLoc(SourceLocation Loc) {
+    PragmaARCCFCodeAuditedLoc = Loc;
+  }
+
+  /// \brief Instruct the preprocessor to skip part of the main source file.
+  ///
+  /// \param Bytes The number of bytes in the preamble to skip.
+  ///
+  /// \param StartOfLine Whether skipping these bytes puts the lexer at the
+  /// start of a line.
+  void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) {
+    SkipMainFilePreamble.first = Bytes;
+    SkipMainFilePreamble.second = StartOfLine;
+  }
+
+  /// Forwarding function for diagnostics.  This emits a diagnostic at
+  /// the specified Token's location, translating the token's start
+  /// position in the current buffer into a SourcePosition object for rendering.
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
+    return Diags->Report(Loc, DiagID);
+  }
+
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) const {
+    return Diags->Report(Tok.getLocation(), DiagID);
+  }
+
+  /// Return the 'spelling' of the token at the given
+  /// location; does not go up to the spelling location or down to the
+  /// expansion location.
+  ///
+  /// \param buffer A buffer which will be used only if the token requires
+  ///   "cleaning", e.g. if it contains trigraphs or escaped newlines
+  /// \param invalid If non-null, will be set \c true if an error occurs.
+  StringRef getSpelling(SourceLocation loc,
+                        SmallVectorImpl<char> &buffer,
+                        bool *invalid = nullptr) const {
+    return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
+  }
+
+  /// \brief Return the 'spelling' of the Tok token.
+  ///
+  /// The spelling of a token is the characters used to represent the token in
+  /// the source file after trigraph expansion and escaped-newline folding.  In
+  /// particular, this wants to get the true, uncanonicalized, spelling of
+  /// things like digraphs, UCNs, etc.
+  ///
+  /// \param Invalid If non-null, will be set \c true if an error occurs.
+  std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
+    return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
+  }
+
+  /// \brief Get the spelling of a token into a preallocated buffer, instead
+  /// of as an std::string.
+  ///
+  /// The caller is required to allocate enough space for the token, which is
+  /// guaranteed to be at least Tok.getLength() bytes long. The length of the
+  /// actual result is returned.
+  ///
+  /// Note that this method may do two possible things: it may either fill in
+  /// the buffer specified with characters, or it may *change the input pointer*
+  /// to point to a constant buffer with the data already in it (avoiding a
+  /// copy).  The caller is not allowed to modify the returned buffer pointer
+  /// if an internal buffer is returned.
+  unsigned getSpelling(const Token &Tok, const char *&Buffer,
+                       bool *Invalid = nullptr) const {
+    return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
+  }
+
+  /// \brief Get the spelling of a token into a SmallVector.
+  ///
+  /// Note that the returned StringRef may not point to the
+  /// supplied buffer if a copy can be avoided.
+  StringRef getSpelling(const Token &Tok,
+                        SmallVectorImpl<char> &Buffer,
+                        bool *Invalid = nullptr) const;
+
+  /// \brief Relex the token at the specified location.
+  /// \returns true if there was a failure, false on success.
+  bool getRawToken(SourceLocation Loc, Token &Result,
+                   bool IgnoreWhiteSpace = false) {
+    return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
+  }
+
+  /// \brief Given a Token \p Tok that is a numeric constant with length 1,
+  /// return the character.
+  char
+  getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
+                                              bool *Invalid = nullptr) const {
+    assert(Tok.is(tok::numeric_constant) &&
+           Tok.getLength() == 1 && "Called on unsupported token");
+    assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
+
+    // If the token is carrying a literal data pointer, just use it.
+    if (const char *D = Tok.getLiteralData())
+      return *D;
+
+    // Otherwise, fall back on getCharacterData, which is slower, but always
+    // works.
+    return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid);
+  }
+
+  /// \brief Retrieve the name of the immediate macro expansion.
+  ///
+  /// This routine starts from a source location, and finds the name of the
+  /// macro responsible for its immediate expansion. It looks through any
+  /// intervening macro argument expansions to compute this. It returns a
+  /// StringRef that refers to the SourceManager-owned buffer of the source
+  /// where that macro name is spelled. Thus, the result shouldn't out-live
+  /// the SourceManager.
+  StringRef getImmediateMacroName(SourceLocation Loc) {
+    return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
+  }
+
+  /// \brief Plop the specified string into a scratch buffer and set the
+  /// specified token's location and length to it. 
+  ///
+  /// If specified, the source location provides a location of the expansion
+  /// point of the token.
+  void CreateString(StringRef Str, Token &Tok,
+                    SourceLocation ExpansionLocStart = SourceLocation(),
+                    SourceLocation ExpansionLocEnd = SourceLocation());
+
+  /// \brief Computes the source location just past the end of the
+  /// token at this source location.
+  ///
+  /// This routine can be used to produce a source location that
+  /// points just past the end of the token referenced by \p Loc, and
+  /// is generally used when a diagnostic needs to point just after a
+  /// token where it expected something different that it received. If
+  /// the returned source location would not be meaningful (e.g., if
+  /// it points into a macro), this routine returns an invalid
+  /// source location.
+  ///
+  /// \param Offset an offset from the end of the token, where the source
+  /// location should refer to. The default offset (0) produces a source
+  /// location pointing just past the end of the token; an offset of 1 produces
+  /// a source location pointing to the last character in the token, etc.
+  SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
+    return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
+  }
+
+  /// \brief Returns true if the given MacroID location points at the first
+  /// token of the macro expansion.
+  ///
+  /// \param MacroBegin If non-null and function returns true, it is set to
+  /// begin location of the macro.
+  bool isAtStartOfMacroExpansion(SourceLocation loc,
+                                 SourceLocation *MacroBegin = nullptr) const {
+    return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
+                                            MacroBegin);
+  }
+
+  /// \brief Returns true if the given MacroID location points at the last
+  /// token of the macro expansion.
+  ///
+  /// \param MacroEnd If non-null and function returns true, it is set to
+  /// end location of the macro.
+  bool isAtEndOfMacroExpansion(SourceLocation loc,
+                               SourceLocation *MacroEnd = nullptr) const {
+    return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
+  }
+
+  /// \brief Print the token to stderr, used for debugging.
+  void DumpToken(const Token &Tok, bool DumpFlags = false) const;
+  void DumpLocation(SourceLocation Loc) const;
+  void DumpMacro(const MacroInfo &MI) const;
+
+  /// \brief Given a location that specifies the start of a
+  /// token, return a new location that specifies a character within the token.
+  SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
+                                         unsigned Char) const {
+    return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
+  }
+
+  /// \brief Increment the counters for the number of token paste operations
+  /// performed.
+  ///
+  /// If fast was specified, this is a 'fast paste' case we handled.
+  void IncrementPasteCounter(bool isFast) {
+    if (isFast)
+      ++NumFastTokenPaste;
+    else
+      ++NumTokenPaste;
+  }
+
+  void PrintStats();
+
+  size_t getTotalMemory() const;
+
+  /// When the macro expander pastes together a comment (/##/) in Microsoft
+  /// mode, this method handles updating the current state, returning the
+  /// token on the next source line.
+  void HandleMicrosoftCommentPaste(Token &Tok);
+
+  //===--------------------------------------------------------------------===//
+  // Preprocessor callback methods.  These are invoked by a lexer as various
+  // directives and events are found.
+
+  /// Given a tok::raw_identifier token, look up the
+  /// identifier information for the token and install it into the token,
+  /// updating the token kind accordingly.
+  IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
+
+private:
+  llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
+
+public:
+
+  /// \brief Specifies the reason for poisoning an identifier.
+  ///
+  /// If that identifier is accessed while poisoned, then this reason will be
+  /// used instead of the default "poisoned" diagnostic.
+  void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
+
+  /// \brief Display reason for poisoned identifier.
+  void HandlePoisonedIdentifier(Token & Tok);
+
+  void MaybeHandlePoisonedIdentifier(Token & Identifier) {
+    if(IdentifierInfo * II = Identifier.getIdentifierInfo()) {
+      if(II->isPoisoned()) {
+        HandlePoisonedIdentifier(Identifier);
+      }
+    }
+  }
+
+private:
+  /// Identifiers used for SEH handling in Borland. These are only
+  /// allowed in particular circumstances
+  // __except block
+  IdentifierInfo *Ident__exception_code,
+                 *Ident___exception_code,
+                 *Ident_GetExceptionCode;
+  // __except filter expression
+  IdentifierInfo *Ident__exception_info,
+                 *Ident___exception_info,
+                 *Ident_GetExceptionInfo;
+  // __finally
+  IdentifierInfo *Ident__abnormal_termination,
+                 *Ident___abnormal_termination,
+                 *Ident_AbnormalTermination;
+
+  const char *getCurLexerEndPos();
+
+public:
+  void PoisonSEHIdentifiers(bool Poison = true); // Borland
+
+  /// \brief Callback invoked when the lexer reads an identifier and has
+  /// filled in the tokens IdentifierInfo member. 
+  ///
+  /// This callback potentially macro expands it or turns it into a named
+  /// token (like 'for').
+  ///
+  /// \returns true if we actually computed a token, false if we need to
+  /// lex again.
+  bool HandleIdentifier(Token &Identifier);
+
+
+  /// \brief Callback invoked when the lexer hits the end of the current file.
+  ///
+  /// This either returns the EOF token and returns true, or
+  /// pops a level off the include stack and returns false, at which point the
+  /// client should call lex again.
+  bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
+
+  /// \brief Callback invoked when the current TokenLexer hits the end of its
+  /// token stream.
+  bool HandleEndOfTokenLexer(Token &Result);
+
+  /// \brief Callback invoked when the lexer sees a # token at the start of a
+  /// line.
+  ///
+  /// This consumes the directive, modifies the lexer/preprocessor state, and
+  /// advances the lexer(s) so that the next token read is the correct one.
+  void HandleDirective(Token &Result);
+
+  /// \brief Ensure that the next token is a tok::eod token.
+  ///
+  /// If not, emit a diagnostic and consume up until the eod.
+  /// If \p EnableMacros is true, then we consider macros that expand to zero
+  /// tokens as being ok.
+  void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
+
+  /// \brief Read and discard all tokens remaining on the current line until
+  /// the tok::eod token is found.
+  void DiscardUntilEndOfDirective();
+
+  /// \brief Returns true if the preprocessor has seen a use of
+  /// __DATE__ or __TIME__ in the file so far.
+  bool SawDateOrTime() const {
+    return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
+  }
+  unsigned getCounterValue() const { return CounterValue; }
+  void setCounterValue(unsigned V) { CounterValue = V; }
+
+  /// \brief Retrieves the module that we're currently building, if any.
+  Module *getCurrentModule();
+  
+  /// \brief Allocate a new MacroInfo object with the provided SourceLocation.
+  MacroInfo *AllocateMacroInfo(SourceLocation L);
+
+  /// \brief Allocate a new MacroInfo object loaded from an AST file.
+  MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L,
+                                           unsigned SubModuleID);
+
+  /// \brief Turn the specified lexer token into a fully checked and spelled
+  /// filename, e.g. as an operand of \#include. 
+  ///
+  /// The caller is expected to provide a buffer that is large enough to hold
+  /// the spelling of the filename, but is also expected to handle the case
+  /// when this method decides to use a different buffer.
+  ///
+  /// \returns true if the input filename was in <>'s or false if it was
+  /// in ""'s.
+  bool GetIncludeFilenameSpelling(SourceLocation Loc,StringRef &Filename);
+
+  /// \brief Given a "foo" or \<foo> reference, look up the indicated file.
+  ///
+  /// Returns null on failure.  \p isAngled indicates whether the file
+  /// reference is for system \#include's or not (i.e. using <> instead of "").
+  const FileEntry *LookupFile(SourceLocation FilenameLoc, StringRef Filename,
+                              bool isAngled, const DirectoryLookup *FromDir,
+                              const DirectoryLookup *&CurDir,
+                              SmallVectorImpl<char> *SearchPath,
+                              SmallVectorImpl<char> *RelativePath,
+                              ModuleMap::KnownHeader *SuggestedModule,
+                              bool SkipCache = false);
+
+  /// \brief Get the DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable. 
+  ///
+  /// This allows us to implement \#include_next and find directory-specific
+  /// properties.
+  const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
+
+  /// \brief Return true if we're in the top-level file, not in a \#include.
+  bool isInPrimaryFile() const;
+
+  /// \brief Handle cases where the \#include name is expanded
+  /// from a macro as multiple tokens, which need to be glued together. 
+  ///
+  /// This occurs for code like:
+  /// \code
+  ///    \#define FOO <x/y.h>
+  ///    \#include FOO
+  /// \endcode
+  /// because in this case, "<x/y.h>" is returned as 7 tokens, not one.
+  ///
+  /// This code concatenates and consumes tokens up to the '>' token.  It
+  /// returns false if the > was found, otherwise it returns true if it finds
+  /// and consumes the EOD marker.
+  bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
+                              SourceLocation &End);
+
+  /// \brief Lex an on-off-switch (C99 6.10.6p2) and verify that it is
+  /// followed by EOD.  Return true if the token is not a valid on-off-switch.
+  bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
+
+  bool CheckMacroName(Token &MacroNameTok, char isDefineUndef);
+
+private:
+
+  void PushIncludeMacroStack() {
+    IncludeMacroStack.push_back(IncludeStackInfo(
+        CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
+        CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
+    CurPPLexer = nullptr;
+  }
+
+  void PopIncludeMacroStack() {
+    CurLexer = std::move(IncludeMacroStack.back().TheLexer);
+    CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer);
+    CurPPLexer = IncludeMacroStack.back().ThePPLexer;
+    CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
+    CurDirLookup  = IncludeMacroStack.back().TheDirLookup;
+    CurSubmodule = IncludeMacroStack.back().TheSubmodule;
+    CurLexerKind = IncludeMacroStack.back().CurLexerKind;
+    IncludeMacroStack.pop_back();
+  }
+
+  void PropagateLineStartLeadingSpaceInfo(Token &Result);
+
+  /// \brief Allocate a new MacroInfo object.
+  MacroInfo *AllocateMacroInfo();
+
+  DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+                                               SourceLocation Loc,
+                                               bool isImported);
+  UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+  VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
+                                                             bool isPublic);
+
+  /// \brief Release the specified MacroInfo for re-use.
+  ///
+  /// This memory will  be reused for allocating new MacroInfo objects.
+  void ReleaseMacroInfo(MacroInfo* MI);
+
+  /// \brief Lex and validate a macro name, which occurs after a
+  /// \#define or \#undef. 
+  ///
+  /// This emits a diagnostic, sets the token kind to eod,
+  /// and discards the rest of the macro line if the macro name is invalid.
+  void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
+
+  /// The ( starting an argument list of a macro definition has just been read.
+  /// Lex the rest of the arguments and the closing ), updating \p MI with
+  /// what we learn and saving in \p LastTok the last token read.
+  /// Return true if an error occurs parsing the arg list.
+  bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
+
+  /// We just read a \#if or related directive and decided that the
+  /// subsequent tokens are in the \#if'd out portion of the
+  /// file.  Lex the rest of the file, until we see an \#endif.  If \p
+  /// FoundNonSkipPortion is true, then we have already emitted code for part of
+  /// this \#if directive, so \#else/\#elif blocks should never be entered. If
+  /// \p FoundElse is false, then \#else directives are ok, if not, then we have
+  /// already seen one so a \#else directive is a duplicate.  When this returns,
+  /// the caller can lex the first valid token.
+  void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+                                    bool FoundNonSkipPortion, bool FoundElse,
+                                    SourceLocation ElseLoc = SourceLocation());
+
+  /// \brief A fast PTH version of SkipExcludedConditionalBlock.
+  void PTHSkipExcludedConditionalBlock();
+
+  /// \brief Evaluate an integer constant expression that may occur after a
+  /// \#if or \#elif directive and return it as a bool.
+  ///
+  /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
+  bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
+
+  /// \brief Install the standard preprocessor pragmas:
+  /// \#pragma GCC poison/system_header/dependency and \#pragma once.
+  void RegisterBuiltinPragmas();
+
+  /// \brief Register builtin macros such as __LINE__ with the identifier table.
+  void RegisterBuiltinMacros();
+
+  /// If an identifier token is read that is to be expanded as a macro, handle
+  /// it and return the next token as 'Tok'.  If we lexed a token, return true;
+  /// otherwise the caller should lex again.
+  bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
+
+  /// \brief Cache macro expanded tokens for TokenLexers.
+  //
+  /// Works like a stack; a TokenLexer adds the macro expanded tokens that is
+  /// going to lex in the cache and when it finishes the tokens are removed
+  /// from the end of the cache.
+  Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
+                                  ArrayRef<Token> tokens);
+  void removeCachedMacroExpandedTokensOfLastLexer();
+  friend void TokenLexer::ExpandFunctionArguments();
+
+  /// Determine whether the next preprocessor token to be
+  /// lexed is a '('.  If so, consume the token and return true, if not, this
+  /// method should have no observable side-effect on the lexed tokens.
+  bool isNextPPTokenLParen();
+
+  /// After reading "MACRO(", this method is invoked to read all of the formal
+  /// arguments specified for the macro invocation.  Returns null on error.
+  MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
+                                       SourceLocation &ExpansionEnd);
+
+  /// \brief If an identifier token is read that is to be expanded
+  /// as a builtin macro, handle it and return the next token as 'Tok'.
+  void ExpandBuiltinMacro(Token &Tok);
+
+  /// \brief Read a \c _Pragma directive, slice it up, process it, then
+  /// return the first token after the directive.
+  /// This assumes that the \c _Pragma token has just been read into \p Tok.
+  void Handle_Pragma(Token &Tok);
+
+  /// \brief Like Handle_Pragma except the pragma text is not enclosed within
+  /// a string literal.
+  void HandleMicrosoft__pragma(Token &Tok);
+
+  /// \brief Add a lexer to the top of the include stack and
+  /// start lexing tokens from it instead of the current buffer.
+  void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
+
+  /// \brief Add a lexer to the top of the include stack and
+  /// start getting tokens from it using the PTH cache.
+  void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
+
+  /// \brief Set the FileID for the preprocessor predefines.
+  void setPredefinesFileID(FileID FID) {
+    assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
+    PredefinesFileID = FID;
+  }
+
+  /// \brief Returns true if we are lexing from a file and not a
+  /// pragma or a macro.
+  static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
+    return L ? !L->isPragmaLexer() : P != nullptr;
+  }
+
+  static bool IsFileLexer(const IncludeStackInfo& I) {
+    return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
+  }
+
+  bool IsFileLexer() const {
+    return IsFileLexer(CurLexer.get(), CurPPLexer);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Caching stuff.
+  void CachingLex(Token &Result);
+  bool InCachingLexMode() const {
+    // If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
+    // that we are past EOF, not that we are in CachingLex mode.
+    return !CurPPLexer && !CurTokenLexer && !CurPTHLexer &&
+           !IncludeMacroStack.empty();
+  }
+  void EnterCachingLexMode();
+  void ExitCachingLexMode() {
+    if (InCachingLexMode())
+      RemoveTopOfLexerStack();
+  }
+  const Token &PeekAhead(unsigned N);
+  void AnnotatePreviousCachedTokens(const Token &Tok);
+
+  //===--------------------------------------------------------------------===//
+  /// Handle*Directive - implement the various preprocessor directives.  These
+  /// should side-effect the current preprocessor object so that the next call
+  /// to Lex() will return the appropriate token next.
+  void HandleLineDirective(Token &Tok);
+  void HandleDigitDirective(Token &Tok);
+  void HandleUserDiagnosticDirective(Token &Tok, bool isWarning);
+  void HandleIdentSCCSDirective(Token &Tok);
+  void HandleMacroPublicDirective(Token &Tok);
+  void HandleMacroPrivateDirective(Token &Tok);
+
+  // File inclusion.
+  void HandleIncludeDirective(SourceLocation HashLoc,
+                              Token &Tok,
+                              const DirectoryLookup *LookupFrom = nullptr,
+                              bool isImport = false);
+  void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
+  void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
+  void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
+  void HandleMicrosoftImportDirective(Token &Tok);
+
+  // Module inclusion testing.
+  /// \brief Find the module for the source or header file that \p FilenameLoc
+  /// points to.
+  Module *getModuleForLocation(SourceLocation FilenameLoc);
+
+  // Macro handling.
+  void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
+  void HandleUndefDirective(Token &Tok);
+
+  // Conditional Inclusion.
+  void HandleIfdefDirective(Token &Tok, bool isIfndef,
+                            bool ReadAnyTokensBeforeDirective);
+  void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
+  void HandleEndifDirective(Token &Tok);
+  void HandleElseDirective(Token &Tok);
+  void HandleElifDirective(Token &Tok);
+
+  // Pragmas.
+  void HandlePragmaDirective(SourceLocation IntroducerLoc,
+                             PragmaIntroducerKind Introducer);
+public:
+  void HandlePragmaOnce(Token &OnceTok);
+  void HandlePragmaMark();
+  void HandlePragmaPoison(Token &PoisonTok);
+  void HandlePragmaSystemHeader(Token &SysHeaderTok);
+  void HandlePragmaDependency(Token &DependencyTok);
+  void HandlePragmaPushMacro(Token &Tok);
+  void HandlePragmaPopMacro(Token &Tok);
+  void HandlePragmaIncludeAlias(Token &Tok);
+  IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok);
+
+  // Return true and store the first token only if any CommentHandler
+  // has inserted some tokens and getCommentRetentionState() is false.
+  bool HandleComment(Token &Token, SourceRange Comment);
+
+  /// \brief A macro is used, update information about macros that need unused
+  /// warnings.
+  void markMacroAsUsed(MacroInfo *MI);
+};
+
+/// \brief Abstract base class that describes a handler that will receive
+/// source ranges for each of the comments encountered in the source file.
+class CommentHandler {
+public:
+  virtual ~CommentHandler();
+
+  // The handler shall return true if it has pushed any tokens
+  // to be read using e.g. EnterToken or EnterTokenStream.
+  virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
new file mode 100644
index 0000000..ed226ae
--- /dev/null
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -0,0 +1,183 @@
+//===--- PreprocessorLexer.h - C Language Family Lexer ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the PreprocessorLexer interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PreprocessorLexer_H
+#define LLVM_CLANG_PreprocessorLexer_H
+
+#include "clang/Lex/MultipleIncludeOpt.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class FileEntry;
+class Preprocessor;
+
+class PreprocessorLexer {
+  virtual void anchor();
+protected:
+  Preprocessor *PP;              // Preprocessor object controlling lexing.
+
+  /// The SourceManager FileID corresponding to the file being lexed.
+  const FileID FID;
+
+  /// \brief Number of SLocEntries before lexing the file.
+  unsigned InitialNumSLocEntries;
+
+  //===--------------------------------------------------------------------===//
+  // Context-specific lexing flags set by the preprocessor.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief True when parsing \#XXX; turns '\\n' into a tok::eod token.
+  bool ParsingPreprocessorDirective;
+
+  /// \brief True after \#include; turns \<xx> into a tok::angle_string_literal
+  /// token.
+  bool ParsingFilename;
+
+  /// \brief True if in raw mode.
+  ///
+  /// Raw mode disables interpretation of tokens and is a far faster mode to
+  /// lex in than non-raw-mode.  This flag:
+  ///  1. If EOF of the current lexer is found, the include stack isn't popped.
+  ///  2. Identifier information is not looked up for identifier tokens.  As an
+  ///     effect of this, implicit macro expansion is naturally disabled.
+  ///  3. "#" tokens at the start of a line are treated as normal tokens, not
+  ///     implicitly transformed by the lexer.
+  ///  4. All diagnostic messages are disabled.
+  ///  5. No callbacks are made into the preprocessor.
+  ///
+  /// Note that in raw mode that the PP pointer may be null.
+  bool LexingRawMode;
+
+  /// \brief A state machine that detects the \#ifndef-wrapping a file
+  /// idiom for the multiple-include optimization.
+  MultipleIncludeOpt MIOpt;
+
+  /// \brief Information about the set of \#if/\#ifdef/\#ifndef blocks
+  /// we are currently in.
+  SmallVector<PPConditionalInfo, 4> ConditionalStack;
+
+  PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION;
+  friend class Preprocessor;
+
+  PreprocessorLexer(Preprocessor *pp, FileID fid);
+
+  PreprocessorLexer()
+    : PP(nullptr), InitialNumSLocEntries(0),
+      ParsingPreprocessorDirective(false),
+      ParsingFilename(false),
+      LexingRawMode(false) {}
+
+  virtual ~PreprocessorLexer() {}
+
+  virtual void IndirectLex(Token& Result) = 0;
+
+  /// \brief Return the source location for the next observable location.
+  virtual SourceLocation getSourceLocation() = 0;
+
+  //===--------------------------------------------------------------------===//
+  // #if directive handling.
+
+  /// pushConditionalLevel - When we enter a \#if directive, this keeps track of
+  /// what we are currently in for diagnostic emission (e.g. \#if with missing
+  /// \#endif).
+  void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
+                            bool FoundNonSkip, bool FoundElse) {
+    PPConditionalInfo CI;
+    CI.IfLoc = DirectiveStart;
+    CI.WasSkipping = WasSkipping;
+    CI.FoundNonSkip = FoundNonSkip;
+    CI.FoundElse = FoundElse;
+    ConditionalStack.push_back(CI);
+  }
+  void pushConditionalLevel(const PPConditionalInfo &CI) {
+    ConditionalStack.push_back(CI);
+  }
+
+  /// popConditionalLevel - Remove an entry off the top of the conditional
+  /// stack, returning information about it.  If the conditional stack is empty,
+  /// this returns true and does not fill in the arguments.
+  bool popConditionalLevel(PPConditionalInfo &CI) {
+    if (ConditionalStack.empty())
+      return true;
+    CI = ConditionalStack.pop_back_val();
+    return false;
+  }
+
+  /// \brief Return the top of the conditional stack.
+  /// \pre This requires that there be a conditional active.
+  PPConditionalInfo &peekConditionalLevel() {
+    assert(!ConditionalStack.empty() && "No conditionals active!");
+    return ConditionalStack.back();
+  }
+
+  unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
+
+public:
+
+  //===--------------------------------------------------------------------===//
+  // Misc. lexing methods.
+
+  /// \brief After the preprocessor has parsed a \#include, lex and
+  /// (potentially) macro expand the filename.
+  ///
+  /// If the sequence parsed is not lexically legal, emit a diagnostic and
+  /// return a result EOD token.
+  void LexIncludeFilename(Token &Result);
+
+  /// \brief Inform the lexer whether or not we are currently lexing a
+  /// preprocessor directive.
+  void setParsingPreprocessorDirective(bool f) {
+    ParsingPreprocessorDirective = f;
+  }
+
+  /// \brief Return true if this lexer is in raw mode or not.
+  bool isLexingRawMode() const { return LexingRawMode; }
+
+  /// \brief Return the preprocessor object for this lexer.
+  Preprocessor *getPP() const { return PP; }
+
+  FileID getFileID() const {
+    assert(PP &&
+      "PreprocessorLexer::getFileID() should only be used with a Preprocessor");
+    return FID;
+  }
+
+  /// \brief Number of SLocEntries before lexing the file.
+  unsigned getInitialNumSLocEntries() const {
+    return InitialNumSLocEntries;
+  }
+
+  /// getFileEntry - Return the FileEntry corresponding to this FileID.  Like
+  /// getFileID(), this only works for lexers with attached preprocessors.
+  const FileEntry *getFileEntry() const;
+
+  /// \brief Iterator that traverses the current stack of preprocessor
+  /// conditional directives (\#if/\#ifdef/\#ifndef).
+  typedef SmallVectorImpl<PPConditionalInfo>::const_iterator 
+    conditional_iterator;
+
+  conditional_iterator conditional_begin() const { 
+    return ConditionalStack.begin(); 
+  }
+  conditional_iterator conditional_end() const { 
+    return ConditionalStack.end(); 
+  }
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
new file mode 100644
index 0000000..135c87f
--- /dev/null
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -0,0 +1,189 @@
+//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
+#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include <cassert>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class Preprocessor;
+class LangOptions;
+
+/// \brief Enumerate the kinds of standard library that 
+enum ObjCXXARCStandardLibraryKind {
+  ARCXX_nolib,
+  /// \brief libc++
+  ARCXX_libcxx,
+  /// \brief libstdc++
+  ARCXX_libstdcxx
+};
+  
+/// PreprocessorOptions - This class is used for passing the various options
+/// used in preprocessor initialization to InitializePreprocessor().
+class PreprocessorOptions : public RefCountedBase<PreprocessorOptions> {
+public:
+  std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
+  std::vector<std::string> Includes;
+  std::vector<std::string> MacroIncludes;
+
+  /// \brief Initialize the preprocessor with the compiler and target specific
+  /// predefines.
+  unsigned UsePredefines : 1;
+
+  /// \brief Whether we should maintain a detailed record of all macro
+  /// definitions and expansions.
+  unsigned DetailedRecord : 1;
+
+  /// The implicit PCH included at the start of the translation unit, or empty.
+  std::string ImplicitPCHInclude;
+
+  /// \brief Headers that will be converted to chained PCHs in memory.
+  std::vector<std::string> ChainedIncludes;
+
+  /// \brief When true, disables most of the normal validation performed on
+  /// precompiled headers.
+  bool DisablePCHValidation;
+
+  /// \brief When true, a PCH with compiler errors will not be rejected.
+  bool AllowPCHWithCompilerErrors;
+
+  /// \brief Dump declarations that are deserialized from PCH, for testing.
+  bool DumpDeserializedPCHDecls;
+
+  /// \brief This is a set of names for decls that we do not want to be
+  /// deserialized, and we emit an error if they are; for testing purposes.
+  std::set<std::string> DeserializedPCHDeclsToErrorOn;
+
+  /// \brief If non-zero, the implicit PCH include is actually a precompiled
+  /// preamble that covers this number of bytes in the main source file.
+  ///
+  /// The boolean indicates whether the preamble ends at the start of a new
+  /// line.
+  std::pair<unsigned, bool> PrecompiledPreambleBytes;
+  
+  /// The implicit PTH input included at the start of the translation unit, or
+  /// empty.
+  std::string ImplicitPTHInclude;
+
+  /// If given, a PTH cache file to use for speeding up header parsing.
+  std::string TokenCache;
+
+  /// \brief True if the SourceManager should report the original file name for
+  /// contents of files that were remapped to other files. Defaults to true.
+  bool RemappedFilesKeepOriginalName;
+
+  /// \brief The set of file remappings, which take existing files on
+  /// the system (the first part of each pair) and gives them the
+  /// contents of other files on the system (the second part of each
+  /// pair).
+  std::vector<std::pair<std::string, std::string>> RemappedFiles;
+
+  /// \brief The set of file-to-buffer remappings, which take existing files
+  /// on the system (the first part of each pair) and gives them the contents
+  /// of the specified memory buffer (the second part of each pair).
+  std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
+
+  /// \brief Whether the compiler instance should retain (i.e., not free)
+  /// the buffers associated with remapped files.
+  ///
+  /// This flag defaults to false; it can be set true only through direct
+  /// manipulation of the compiler invocation object, in cases where the 
+  /// compiler invocation and its buffers will be reused.
+  bool RetainRemappedFileBuffers;
+  
+  /// \brief The Objective-C++ ARC standard library that we should support,
+  /// by providing appropriate definitions to retrofit the standard library
+  /// with support for lifetime-qualified pointers.
+  ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
+    
+  /// \brief Records the set of modules
+  class FailedModulesSet : public RefCountedBase<FailedModulesSet> {
+    llvm::StringSet<> Failed;
+
+  public:
+    bool hasAlreadyFailed(StringRef module) {
+      return Failed.count(module) > 0;
+    }
+
+    void addFailed(StringRef module) {
+      Failed.insert(module);
+    }
+  };
+  
+  /// \brief The set of modules that failed to build.
+  ///
+  /// This pointer will be shared among all of the compiler instances created
+  /// to (re)build modules, so that once a module fails to build anywhere,
+  /// other instances will see that the module has failed and won't try to
+  /// build it again.
+  IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
+
+public:
+  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
+                          DisablePCHValidation(false),
+                          AllowPCHWithCompilerErrors(false),
+                          DumpDeserializedPCHDecls(false),
+                          PrecompiledPreambleBytes(0, true),
+                          RemappedFilesKeepOriginalName(true),
+                          RetainRemappedFileBuffers(false),
+                          ObjCXXARCStandardLibrary(ARCXX_nolib) { }
+
+  void addMacroDef(StringRef Name) {
+    Macros.push_back(std::make_pair(Name, false));
+  }
+  void addMacroUndef(StringRef Name) {
+    Macros.push_back(std::make_pair(Name, true));
+  }
+  void addRemappedFile(StringRef From, StringRef To) {
+    RemappedFiles.push_back(std::make_pair(From, To));
+  }
+
+  void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
+    RemappedFileBuffers.push_back(std::make_pair(From, To));
+  }
+
+  void clearRemappedFiles() {
+    RemappedFiles.clear();
+    RemappedFileBuffers.clear();
+  }
+  
+  /// \brief Reset any options that are not considered when building a
+  /// module.
+  void resetNonModularOptions() {
+    Includes.clear();
+    MacroIncludes.clear();
+    ChainedIncludes.clear();
+    DumpDeserializedPCHDecls = false;
+    ImplicitPCHInclude.clear();
+    ImplicitPTHInclude.clear();
+    TokenCache.clear();
+    RetainRemappedFileBuffers = true;
+    PrecompiledPreambleBytes.first = 0;
+    PrecompiledPreambleBytes.second = 0;
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
new file mode 100644
index 0000000..f03515f
--- /dev/null
+++ b/include/clang/Lex/ScratchBuffer.h
@@ -0,0 +1,45 @@
+//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- 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 ScratchBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCRATCHBUFFER_H
+#define LLVM_CLANG_SCRATCHBUFFER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+  class SourceManager;
+
+/// ScratchBuffer - This class exposes a simple interface for the dynamic
+/// construction of tokens.  This is used for builtin macros (e.g. __LINE__) as
+/// well as token pasting, etc.
+class ScratchBuffer {
+  SourceManager &SourceMgr;
+  char *CurBuffer;
+  SourceLocation BufferStartLoc;
+  unsigned BytesUsed;
+public:
+  ScratchBuffer(SourceManager &SM);
+
+  /// getToken - Splat the specified text into a temporary MemoryBuffer and
+  /// return a SourceLocation that refers to the token.  This is just like the
+  /// previous method, but returns a location that indicates the physloc of the
+  /// token.
+  SourceLocation getToken(const char *Buf, unsigned Len, const char *&DestPtr);
+
+private:
+  void AllocScratchBuffer(unsigned RequestLen);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
new file mode 100644
index 0000000..c8b77d1
--- /dev/null
+++ b/include/clang/Lex/Token.h
@@ -0,0 +1,293 @@
+//===--- Token.h - Token interface ------------------------------*- 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 Token interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKEN_H
+#define LLVM_CLANG_TOKEN_H
+
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstdlib>
+
+namespace clang {
+
+class IdentifierInfo;
+
+/// Token - This structure provides full information about a lexed token.
+/// It is not intended to be space efficient, it is intended to return as much
+/// information as possible about each returned token.  This is expected to be
+/// compressed into a smaller form if memory footprint is important.
+///
+/// The parser can create a special "annotation token" representing a stream of
+/// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>"
+/// can be represented by a single typename annotation token that carries
+/// information about the SourceRange of the tokens and the type object.
+class Token {
+  /// The location of the token.
+  SourceLocation Loc;
+
+  // Conceptually these next two fields could be in a union.  However, this
+  // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical
+  // routine. Keeping as separate members with casts until a more beautiful fix
+  // presents itself.
+
+  /// UintData - This holds either the length of the token text, when
+  /// a normal token, or the end of the SourceRange when an annotation
+  /// token.
+  unsigned UintData;
+
+  /// PtrData - This is a union of four different pointer types, which depends
+  /// on what type of token this is:
+  ///  Identifiers, keywords, etc:
+  ///    This is an IdentifierInfo*, which contains the uniqued identifier
+  ///    spelling.
+  ///  Literals:  isLiteral() returns true.
+  ///    This is a pointer to the start of the token in a text buffer, which
+  ///    may be dirty (have trigraphs / escaped newlines).
+  ///  Annotations (resolved type names, C++ scopes, etc): isAnnotation().
+  ///    This is a pointer to sema-specific data for the annotation token.
+  ///  Other:
+  ///    This is null.
+  void *PtrData;
+
+  /// Kind - The actual flavor of token this is.
+  tok::TokenKind Kind;
+
+  /// Flags - Bits we track about this token, members of the TokenFlags enum.
+  unsigned char Flags;
+public:
+
+  // Various flags set per token:
+  enum TokenFlags {
+    StartOfLine   = 0x01,  // At start of line or only after whitespace
+                           // (considering the line after macro expansion).
+    LeadingSpace  = 0x02,  // Whitespace exists before this token (considering 
+                           // whitespace after macro expansion).
+    DisableExpand = 0x04,  // This identifier may never be macro expanded.
+    NeedsCleaning = 0x08,  // Contained an escaped newline or trigraph.
+    LeadingEmptyMacro = 0x10, // Empty macro exists before this token.
+    HasUDSuffix = 0x20,    // This string or character literal has a ud-suffix.
+    HasUCN = 0x40,         // This identifier contains a UCN.
+    IgnoredComma = 0x80    // This comma is not a macro argument separator (MS).
+  };
+
+  tok::TokenKind getKind() const { return Kind; }
+  void setKind(tok::TokenKind K) { Kind = K; }
+
+  /// is/isNot - Predicates to check if this token is a specific kind, as in
+  /// "if (Tok.is(tok::l_brace)) {...}".
+  bool is(tok::TokenKind K) const { return Kind == K; }
+  bool isNot(tok::TokenKind K) const { return Kind != K; }
+
+  /// \brief Return true if this is a raw identifier (when lexing
+  /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
+  bool isAnyIdentifier() const {
+    return tok::isAnyIdentifier(getKind());
+  }
+
+  /// \brief Return true if this is a "literal", like a numeric
+  /// constant, string, etc.
+  bool isLiteral() const {
+    return tok::isLiteral(getKind());
+  }
+
+  /// \brief Return true if this is any of tok::annot_* kind tokens.
+  bool isAnnotation() const {
+    return tok::isAnnotation(getKind());
+  }
+
+  /// \brief Return a source location identifier for the specified
+  /// offset in the current file.
+  SourceLocation getLocation() const { return Loc; }
+  unsigned getLength() const {
+    assert(!isAnnotation() && "Annotation tokens have no length field");
+    return UintData;
+  }
+
+  void setLocation(SourceLocation L) { Loc = L; }
+  void setLength(unsigned Len) {
+    assert(!isAnnotation() && "Annotation tokens have no length field");
+    UintData = Len;
+  }
+
+  SourceLocation getAnnotationEndLoc() const {
+    assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
+    return SourceLocation::getFromRawEncoding(UintData);
+  }
+  void setAnnotationEndLoc(SourceLocation L) {
+    assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token");
+    UintData = L.getRawEncoding();
+  }
+
+  SourceLocation getLastLoc() const {
+    return isAnnotation() ? getAnnotationEndLoc() : getLocation();
+  }
+
+  /// \brief SourceRange of the group of tokens that this annotation token
+  /// represents.
+  SourceRange getAnnotationRange() const {
+    return SourceRange(getLocation(), getAnnotationEndLoc());
+  }
+  void setAnnotationRange(SourceRange R) {
+    setLocation(R.getBegin());
+    setAnnotationEndLoc(R.getEnd());
+  }
+
+  const char *getName() const { return tok::getTokenName(Kind); }
+
+  /// \brief Reset all flags to cleared.
+  void startToken() {
+    Kind = tok::unknown;
+    Flags = 0;
+    PtrData = nullptr;
+    UintData = 0;
+    Loc = SourceLocation();
+  }
+
+  IdentifierInfo *getIdentifierInfo() const {
+    assert(isNot(tok::raw_identifier) &&
+           "getIdentifierInfo() on a tok::raw_identifier token!");
+    assert(!isAnnotation() &&
+           "getIdentifierInfo() on an annotation token!");
+    if (isLiteral()) return nullptr;
+    return (IdentifierInfo*) PtrData;
+  }
+  void setIdentifierInfo(IdentifierInfo *II) {
+    PtrData = (void*) II;
+  }
+
+  /// getRawIdentifier - For a raw identifier token (i.e., an identifier
+  /// lexed in raw mode), returns a reference to the text substring in the
+  /// buffer if known.
+  StringRef getRawIdentifier() const {
+    assert(is(tok::raw_identifier));
+    return StringRef(reinterpret_cast<const char *>(PtrData), getLength());
+  }
+  void setRawIdentifierData(const char *Ptr) {
+    assert(is(tok::raw_identifier));
+    PtrData = const_cast<char*>(Ptr);
+  }
+
+  /// getLiteralData - For a literal token (numeric constant, string, etc), this
+  /// returns a pointer to the start of it in the text buffer if known, null
+  /// otherwise.
+  const char *getLiteralData() const {
+    assert(isLiteral() && "Cannot get literal data of non-literal");
+    return reinterpret_cast<const char*>(PtrData);
+  }
+  void setLiteralData(const char *Ptr) {
+    assert(isLiteral() && "Cannot set literal data of non-literal");
+    PtrData = const_cast<char*>(Ptr);
+  }
+
+  void *getAnnotationValue() const {
+    assert(isAnnotation() && "Used AnnotVal on non-annotation token");
+    return PtrData;
+  }
+  void setAnnotationValue(void *val) {
+    assert(isAnnotation() && "Used AnnotVal on non-annotation token");
+    PtrData = val;
+  }
+
+  /// \brief Set the specified flag.
+  void setFlag(TokenFlags Flag) {
+    Flags |= Flag;
+  }
+
+  /// \brief Unset the specified flag.
+  void clearFlag(TokenFlags Flag) {
+    Flags &= ~Flag;
+  }
+
+  /// \brief Return the internal represtation of the flags.
+  ///
+  /// This is only intended for low-level operations such as writing tokens to
+  /// disk.
+  unsigned getFlags() const {
+    return Flags;
+  }
+
+  /// \brief Set a flag to either true or false.
+  void setFlagValue(TokenFlags Flag, bool Val) {
+    if (Val)
+      setFlag(Flag);
+    else
+      clearFlag(Flag);
+  }
+
+  /// isAtStartOfLine - Return true if this token is at the start of a line.
+  ///
+  bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; }
+
+  /// \brief Return true if this token has whitespace before it.
+  ///
+  bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; }
+
+  /// \brief Return true if this identifier token should never
+  /// be expanded in the future, due to C99 6.10.3.4p2.
+  bool isExpandDisabled() const {
+    return (Flags & DisableExpand) ? true : false;
+  }
+
+  /// \brief Return true if we have an ObjC keyword identifier.
+  bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const;
+
+  /// \brief Return the ObjC keyword kind.
+  tok::ObjCKeywordKind getObjCKeywordID() const;
+
+  /// \brief Return true if this token has trigraphs or escaped newlines in it.
+  bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
+
+  /// \brief Return true if this token has an empty macro before it.
+  ///
+  bool hasLeadingEmptyMacro() const {
+    return (Flags & LeadingEmptyMacro) ? true : false;
+  }
+
+  /// \brief Return true if this token is a string or character literal which
+  /// has a ud-suffix.
+  bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; }
+
+  /// Returns true if this token contains a universal character name.
+  bool hasUCN() const { return (Flags & HasUCN) ? true : false; }
+};
+
+/// \brief Information about the conditional stack (\#if directives)
+/// currently active.
+struct PPConditionalInfo {
+  /// \brief Location where the conditional started.
+  SourceLocation IfLoc;
+
+  /// \brief True if this was contained in a skipping directive, e.g.,
+  /// in a "\#if 0" block.
+  bool WasSkipping;
+
+  /// \brief True if we have emitted tokens already, and now we're in
+  /// an \#else block or something.  Only useful in Skipping blocks.
+  bool FoundNonSkip;
+
+  /// \brief True if we've seen a \#else in this block.  If so,
+  /// \#elif/\#else directives are not allowed.
+  bool FoundElse;
+};
+
+}  // end namespace clang
+
+namespace llvm {
+  template <>
+  struct isPodLike<clang::Token> { static const bool value = true; };
+}  // end namespace llvm
+
+#endif
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
new file mode 100644
index 0000000..551300f
--- /dev/null
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -0,0 +1,72 @@
+//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- 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 TokenConcatenation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LEX_TOKEN_CONCATENATION_H
+#define CLANG_LEX_TOKEN_CONCATENATION_H
+
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+  class Preprocessor;
+  class Token;
+
+  /// TokenConcatenation class, which answers the question of
+  ///   "Is it safe to emit two tokens without a whitespace between them, or
+  ///    would that cause implicit concatenation of the tokens?"
+  ///
+  /// For example, it emitting two identifiers "foo" and "bar" next to each
+  /// other would cause the lexer to produce one "foobar" token.  Emitting "1"
+  /// and ")" next to each other is safe.
+  ///
+  class TokenConcatenation {
+    Preprocessor &PP;
+
+    enum AvoidConcatInfo {
+      /// By default, a token never needs to avoid concatenation.  Most tokens
+      /// (e.g. ',', ')', etc) don't cause a problem when concatenated.
+      aci_never_avoid_concat = 0,
+
+      /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
+      /// token's requirements, and it needs to know the first character of the
+      /// token.
+      aci_custom_firstchar = 1,
+
+      /// aci_custom - AvoidConcat contains custom code to handle this token's
+      /// requirements, but it doesn't need to know the first character of the
+      /// token.
+      aci_custom = 2,
+
+      /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
+      /// character.  For example, "<<" turns into "<<=" when followed by an =.
+      aci_avoid_equal = 4
+    };
+
+    /// TokenInfo - This array contains information for each token on what
+    /// action to take when avoiding concatenation of tokens in the AvoidConcat
+    /// method.
+    char TokenInfo[tok::NUM_TOKENS];
+  public:
+    TokenConcatenation(Preprocessor &PP);
+
+    bool AvoidConcat(const Token &PrevPrevTok, 
+                     const Token &PrevTok, 
+                     const Token &Tok) const;
+
+  private:
+    /// IsIdentifierStringPrefix - Return true if the spelling of the token
+    /// is literally 'L', 'u', 'U', or 'u8'.
+    bool IsIdentifierStringPrefix(const Token &Tok) const;
+  };
+  } // end clang namespace
+
+#endif
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
new file mode 100644
index 0000000..a873a2e
--- /dev/null
+++ b/include/clang/Lex/TokenLexer.h
@@ -0,0 +1,205 @@
+//===--- TokenLexer.h - Lex from a token buffer -----------------*- 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 TokenLexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENLEXER_H
+#define LLVM_CLANG_TOKENLEXER_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+  class MacroInfo;
+  class Preprocessor;
+  class Token;
+  class MacroArgs;
+
+/// TokenLexer - This implements a lexer that returns tokens from a macro body
+/// or token stream instead of lexing from a character buffer.  This is used for
+/// macro expansion and _Pragma handling, for example.
+///
+class TokenLexer {
+  /// Macro - The macro we are expanding from.  This is null if expanding a
+  /// token stream.
+  ///
+  MacroInfo *Macro;
+
+  /// ActualArgs - The actual arguments specified for a function-like macro, or
+  /// null.  The TokenLexer owns the pointed-to object.
+  MacroArgs *ActualArgs;
+
+  /// PP - The current preprocessor object we are expanding for.
+  ///
+  Preprocessor &PP;
+
+  /// Tokens - This is the pointer to an array of tokens that the macro is
+  /// defined to, with arguments expanded for function-like macros.  If this is
+  /// a token stream, these are the tokens we are returning.  This points into
+  /// the macro definition we are lexing from, a cache buffer that is owned by
+  /// the preprocessor, or some other buffer that we may or may not own
+  /// (depending on OwnsTokens).
+  /// Note that if it points into Preprocessor's cache buffer, the Preprocessor
+  /// may update the pointer as needed.
+  const Token *Tokens;
+  friend class Preprocessor;
+
+  /// NumTokens - This is the length of the Tokens array.
+  ///
+  unsigned NumTokens;
+
+  /// CurToken - This is the next token that Lex will return.
+  ///
+  unsigned CurToken;
+
+  /// ExpandLocStart/End - The source location range where this macro was
+  /// expanded.
+  SourceLocation ExpandLocStart, ExpandLocEnd;
+
+  /// \brief Source location pointing at the source location entry chunk that
+  /// was reserved for the current macro expansion.
+  SourceLocation MacroExpansionStart;
+  
+  /// \brief The offset of the macro expansion in the
+  /// "source location address space".
+  unsigned MacroStartSLocOffset;
+
+  /// \brief Location of the macro definition.
+  SourceLocation MacroDefStart;
+  /// \brief Length of the macro definition.
+  unsigned MacroDefLength;
+
+  /// Lexical information about the expansion point of the macro: the identifier
+  /// that the macro expanded from had these properties.
+  bool AtStartOfLine : 1;
+  bool HasLeadingSpace : 1;
+
+  // NextTokGetsSpace - When this is true, the next token appended to the
+  // output list during function argument expansion will get a leading space,
+  // regardless of whether it had one to begin with or not. This is used for
+  // placemarker support. If still true after function argument expansion, the
+  // leading space will be applied to the first token following the macro
+  // expansion.
+  bool NextTokGetsSpace : 1;
+
+  /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
+  /// array, and thus needs to free it when destroyed.  For simple object-like
+  /// macros (for example) we just point into the token buffer of the macro
+  /// definition, we don't make a copy of it.
+  bool OwnsTokens : 1;
+
+  /// DisableMacroExpansion - This is true when tokens lexed from the TokenLexer
+  /// should not be subject to further macro expansion.
+  bool DisableMacroExpansion : 1;
+
+  TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION;
+public:
+  /// Create a TokenLexer for the specified macro with the specified actual
+  /// arguments.  Note that this ctor takes ownership of the ActualArgs pointer.
+  /// ILEnd specifies the location of the ')' for a function-like macro or the
+  /// identifier for an object-like macro.
+  TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
+             MacroArgs *ActualArgs, Preprocessor &pp)
+    : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+    Init(Tok, ILEnd, MI, ActualArgs);
+  }
+
+  /// Init - Initialize this TokenLexer to expand from the specified macro
+  /// with the specified argument information.  Note that this ctor takes
+  /// ownership of the ActualArgs pointer.  ILEnd specifies the location of the
+  /// ')' for a function-like macro or the identifier for an object-like macro.
+  void Init(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
+            MacroArgs *ActualArgs);
+
+  /// Create a TokenLexer for the specified token stream.  If 'OwnsTokens' is
+  /// specified, this takes ownership of the tokens and delete[]'s them when
+  /// the token lexer is empty.
+  TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
+             bool ownsTokens, Preprocessor &pp)
+    : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
+    Init(TokArray, NumToks, DisableExpansion, ownsTokens);
+  }
+
+  /// Init - Initialize this TokenLexer with the specified token stream.
+  /// This does not take ownership of the specified token vector.
+  ///
+  /// DisableExpansion is true when macro expansion of tokens lexed from this
+  /// stream should be disabled.
+  void Init(const Token *TokArray, unsigned NumToks,
+            bool DisableMacroExpansion, bool OwnsTokens);
+
+  ~TokenLexer() { destroy(); }
+
+  /// isNextTokenLParen - If the next token lexed will pop this macro off the
+  /// expansion stack, return 2.  If the next unexpanded token is a '(', return
+  /// 1, otherwise return 0.
+  unsigned isNextTokenLParen() const;
+
+  /// Lex - Lex and return a token from this macro stream.
+  bool Lex(Token &Tok);
+
+  /// isParsingPreprocessorDirective - Return true if we are in the middle of a
+  /// preprocessor directive.
+  bool isParsingPreprocessorDirective() const;
+
+private:
+  void destroy();
+
+  /// isAtEnd - Return true if the next lex call will pop this macro off the
+  /// include stack.
+  bool isAtEnd() const {
+    return CurToken == NumTokens;
+  }
+
+  /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
+  /// operator.  Read the ## and RHS, and paste the LHS/RHS together.  If there
+  /// are is another ## after it, chomp it iteratively.  Return the result as
+  /// Tok.  If this returns true, the caller should immediately return the
+  /// token.
+  bool PasteTokens(Token &Tok);
+
+  /// Expand the arguments of a function-like macro so that we can quickly
+  /// return preexpanded tokens from Tokens.
+  void ExpandFunctionArguments();
+
+  /// HandleMicrosoftCommentPaste - In microsoft compatibility mode, /##/ pastes
+  /// together to form a comment that comments out everything in the current
+  /// macro, other active macros, and anything left on the current physical
+  /// source line of the expanded buffer.  Handle this by returning the
+  /// first token on the next line.
+  void HandleMicrosoftCommentPaste(Token &Tok);
+
+  /// \brief If \p loc is a FileID and points inside the current macro
+  /// definition, returns the appropriate source location pointing at the
+  /// macro expansion source location entry.
+  SourceLocation getExpansionLocForMacroDefLoc(SourceLocation loc) const;
+
+  /// \brief Creates SLocEntries and updates the locations of macro argument
+  /// tokens to their new expanded locations.
+  ///
+  /// \param ArgIdSpellLoc the location of the macro argument id inside the
+  /// macro definition.
+  void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
+                                  Token *begin_tokens, Token *end_tokens);
+
+  /// Remove comma ahead of __VA_ARGS__, if present, according to compiler
+  /// dialect settings.  Returns true if the comma is removed.
+  bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks,
+                                    bool HasPasteOperator,
+                                    MacroInfo *Macro, unsigned MacroArgNo,
+                                    Preprocessor &PP);
+
+  void PropagateLineStartLeadingSpaceInfo(Token &Result);
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/AttrParserStringSwitches.inc b/include/clang/Parse/AttrParserStringSwitches.inc
new file mode 100644
index 0000000..80403c1
--- /dev/null
+++ b/include/clang/Parse/AttrParserStringSwitches.inc
@@ -0,0 +1,101 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Parser-related llvm::StringSwitch cases                                     *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)
+.Case("acquire_capability", true)
+.Case("acquire_shared_capability", true)
+.Case("exclusive_lock_function", true)
+.Case("shared_lock_function", true)
+.Case("acquired_after", true)
+.Case("acquired_before", true)
+.Case("assert_capability", true)
+.Case("assert_shared_capability", true)
+.Case("assert_exclusive_lock", true)
+.Case("assert_shared_lock", true)
+.Case("exclusive_trylock_function", true)
+.Case("guarded_by", true)
+.Case("lock_returned", true)
+.Case("locks_excluded", true)
+.Case("pt_guarded_by", true)
+.Case("release_capability", true)
+.Case("release_shared_capability", true)
+.Case("release_generic_capability", true)
+.Case("unlock_function", true)
+.Case("requires_capability", true)
+.Case("exclusive_locks_required", true)
+.Case("requires_shared_capability", true)
+.Case("shared_locks_required", true)
+.Case("shared_trylock_function", true)
+.Case("try_acquire_capability", true)
+.Case("try_acquire_shared_capability", true)
+#endif // CLANG_ATTR_ARG_CONTEXT_LIST
+
+#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)
+.Case("interrupt", true)
+.Case("argument_with_type_tag", true)
+.Case("pointer_with_type_tag", true)
+.Case("availability", true)
+.Case("blocks", true)
+.Case("consumable", true)
+.Case("format", true)
+.Case("loop", true)
+.Case("unroll", true)
+.Case("mode", true)
+.Case("objc_bridge", true)
+.Case("objc_bridge_mutable", true)
+.Case("objc_bridge_related", true)
+.Case("objc_gc", true)
+.Case("objc_method_family", true)
+.Case("objc_ownership", true)
+.Case("ownership_holds", true)
+.Case("ownership_returns", true)
+.Case("ownership_takes", true)
+.Case("param_typestate", true)
+.Case("pcs", true)
+.Case("return_typestate", true)
+.Case("set_typestate", true)
+.Case("test_typestate", true)
+.Case("type_tag_for_datatype", true)
+.Case("type_visibility", true)
+.Case("visibility", true)
+#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST
+
+#if defined(CLANG_ATTR_TYPE_ARG_LIST)
+.Case("iboutletcollection", true)
+.Case("vec_type_hint", true)
+#endif // CLANG_ATTR_TYPE_ARG_LIST
+
+#if defined(CLANG_ATTR_LATE_PARSED_LIST)
+.Case("acquire_capability", 1)
+.Case("acquire_shared_capability", 1)
+.Case("exclusive_lock_function", 1)
+.Case("shared_lock_function", 1)
+.Case("acquired_after", 1)
+.Case("acquired_before", 1)
+.Case("assert_capability", 1)
+.Case("assert_shared_capability", 1)
+.Case("assert_exclusive_lock", 1)
+.Case("assert_shared_lock", 1)
+.Case("exclusive_trylock_function", 1)
+.Case("guarded_by", 1)
+.Case("lock_returned", 1)
+.Case("locks_excluded", 1)
+.Case("pt_guarded_by", 1)
+.Case("release_capability", 1)
+.Case("release_shared_capability", 1)
+.Case("release_generic_capability", 1)
+.Case("unlock_function", 1)
+.Case("requires_capability", 1)
+.Case("exclusive_locks_required", 1)
+.Case("requires_shared_capability", 1)
+.Case("shared_locks_required", 1)
+.Case("shared_trylock_function", 1)
+.Case("try_acquire_capability", 1)
+.Case("try_acquire_shared_capability", 1)
+#endif // CLANG_ATTR_LATE_PARSED_LIST
+
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
new file mode 100644
index 0000000..21f9701
--- /dev/null
+++ b/include/clang/Parse/ParseAST.h
@@ -0,0 +1,49 @@
+//===--- ParseAST.h - Define the ParseAST method ----------------*- 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 clang::ParseAST method.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_PARSEAST_H
+#define LLVM_CLANG_PARSE_PARSEAST_H
+
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+  class Preprocessor;
+  class ASTConsumer;
+  class ASTContext;
+  class CodeCompleteConsumer;
+  class Sema;
+
+  /// \brief Parse the entire file specified, notifying the ASTConsumer as
+  /// the file is parsed.
+  ///
+  /// This operation inserts the parsed decls into the translation
+  /// unit held by Ctx.
+  ///
+  /// \param TUKind The kind of translation unit being parsed.
+  ///
+  /// \param CompletionConsumer If given, an object to consume code completion
+  /// results.
+  void ParseAST(Preprocessor &pp, ASTConsumer *C,
+                ASTContext &Ctx, bool PrintStats = false,
+                TranslationUnitKind TUKind = TU_Complete,
+                CodeCompleteConsumer *CompletionConsumer = nullptr,
+                bool SkipFunctionBodies = false);
+
+  /// \brief Parse the main file known to the preprocessor, producing an 
+  /// abstract syntax tree.
+  void ParseAST(Sema &S, bool PrintStats = false,
+                bool SkipFunctionBodies = false);
+  
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
new file mode 100644
index 0000000..b593806
--- /dev/null
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICPARSE_H
+#define LLVM_CLANG_DIAGNOSTICPARSE_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define PARSESTART
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_PARSE_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
new file mode 100644
index 0000000..c58c41a
--- /dev/null
+++ b/include/clang/Parse/Parser.h
@@ -0,0 +1,2484 @@
+//===--- Parser.h - C Language Parser ---------------------------*- 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 Parser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_PARSER_H
+#define LLVM_CLANG_PARSE_PARSER_H
+
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/OperatorPrecedence.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LoopHint.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/SaveAndRestore.h"
+#include <memory>
+#include <stack>
+
+namespace clang {
+  class PragmaHandler;
+  class Scope;
+  class BalancedDelimiterTracker;
+  class CorrectionCandidateCallback;
+  class DeclGroupRef;
+  class DiagnosticBuilder;
+  class Parser;
+  class ParsingDeclRAIIObject;
+  class ParsingDeclSpec;
+  class ParsingDeclarator;
+  class ParsingFieldDeclarator;
+  class ColonProtectionRAIIObject;
+  class InMessageExpressionRAIIObject;
+  class PoisonSEHIdentifiersRAIIObject;
+  class VersionTuple;
+  class OMPClause;
+
+/// Parser - This implements a parser for the C family of languages.  After
+/// parsing units of the grammar, productions are invoked to handle whatever has
+/// been read.
+///
+class Parser : public CodeCompletionHandler {
+  friend class ColonProtectionRAIIObject;
+  friend class InMessageExpressionRAIIObject;
+  friend class PoisonSEHIdentifiersRAIIObject;
+  friend class ObjCDeclContextSwitch;
+  friend class ParenBraceBracketBalancer;
+  friend class BalancedDelimiterTracker;
+
+  Preprocessor &PP;
+
+  /// Tok - The current token we are peeking ahead.  All parsing methods assume
+  /// that this is valid.
+  Token Tok;
+
+  // PrevTokLocation - The location of the token we previously
+  // consumed. This token is used for diagnostics where we expected to
+  // see a token following another token (e.g., the ';' at the end of
+  // a statement).
+  SourceLocation PrevTokLocation;
+
+  unsigned short ParenCount, BracketCount, BraceCount;
+
+  /// Actions - These are the callbacks we invoke as we parse various constructs
+  /// in the file.
+  Sema &Actions;
+
+  DiagnosticsEngine &Diags;
+
+  /// ScopeCache - Cache scopes to reduce malloc traffic.
+  enum { ScopeCacheSize = 16 };
+  unsigned NumCachedScopes;
+  Scope *ScopeCache[ScopeCacheSize];
+
+  /// Identifiers used for SEH handling in Borland. These are only
+  /// allowed in particular circumstances
+  // __except block
+  IdentifierInfo *Ident__exception_code,
+                 *Ident___exception_code,
+                 *Ident_GetExceptionCode;
+  // __except filter expression
+  IdentifierInfo *Ident__exception_info,
+                 *Ident___exception_info,
+                 *Ident_GetExceptionInfo;
+  // __finally
+  IdentifierInfo *Ident__abnormal_termination,
+                 *Ident___abnormal_termination,
+                 *Ident_AbnormalTermination;
+
+  /// Contextual keywords for Microsoft extensions.
+  IdentifierInfo *Ident__except;
+  mutable IdentifierInfo *Ident_sealed;
+
+  /// Ident_super - IdentifierInfo for "super", to support fast
+  /// comparison.
+  IdentifierInfo *Ident_super;
+  /// Ident_vector, Ident_pixel, Ident_bool - cached IdentifierInfo's
+  /// for "vector", "pixel", and "bool" fast comparison.  Only present
+  /// if AltiVec enabled.
+  IdentifierInfo *Ident_vector;
+  IdentifierInfo *Ident_pixel;
+  IdentifierInfo *Ident_bool;
+
+  /// Objective-C contextual keywords.
+  mutable IdentifierInfo *Ident_instancetype;
+
+  /// \brief Identifier for "introduced".
+  IdentifierInfo *Ident_introduced;
+
+  /// \brief Identifier for "deprecated".
+  IdentifierInfo *Ident_deprecated;
+
+  /// \brief Identifier for "obsoleted".
+  IdentifierInfo *Ident_obsoleted;
+
+  /// \brief Identifier for "unavailable".
+  IdentifierInfo *Ident_unavailable;
+  
+  /// \brief Identifier for "message".
+  IdentifierInfo *Ident_message;
+
+  /// C++0x contextual keywords.
+  mutable IdentifierInfo *Ident_final;
+  mutable IdentifierInfo *Ident_override;
+
+  // Some token kinds such as C++ type traits can be reverted to identifiers and
+  // still get used as keywords depending on context.
+  llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>
+  ContextualKeywords;
+
+  std::unique_ptr<PragmaHandler> AlignHandler;
+  std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
+  std::unique_ptr<PragmaHandler> OptionsHandler;
+  std::unique_ptr<PragmaHandler> PackHandler;
+  std::unique_ptr<PragmaHandler> MSStructHandler;
+  std::unique_ptr<PragmaHandler> UnusedHandler;
+  std::unique_ptr<PragmaHandler> WeakHandler;
+  std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
+  std::unique_ptr<PragmaHandler> FPContractHandler;
+  std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
+  std::unique_ptr<PragmaHandler> OpenMPHandler;
+  std::unique_ptr<PragmaHandler> MSCommentHandler;
+  std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+  std::unique_ptr<PragmaHandler> MSPointersToMembers;
+  std::unique_ptr<PragmaHandler> MSVtorDisp;
+  std::unique_ptr<PragmaHandler> MSInitSeg;
+  std::unique_ptr<PragmaHandler> MSDataSeg;
+  std::unique_ptr<PragmaHandler> MSBSSSeg;
+  std::unique_ptr<PragmaHandler> MSConstSeg;
+  std::unique_ptr<PragmaHandler> MSCodeSeg;
+  std::unique_ptr<PragmaHandler> MSSection;
+  std::unique_ptr<PragmaHandler> OptimizeHandler;
+  std::unique_ptr<PragmaHandler> LoopHintHandler;
+  std::unique_ptr<PragmaHandler> UnrollHintHandler;
+
+  std::unique_ptr<CommentHandler> CommentSemaHandler;
+
+  /// Whether the '>' token acts as an operator or not. This will be
+  /// true except when we are parsing an expression within a C++
+  /// template argument list, where the '>' closes the template
+  /// argument list.
+  bool GreaterThanIsOperator;
+
+  /// ColonIsSacred - When this is false, we aggressively try to recover from
+  /// code like "foo : bar" as if it were a typo for "foo :: bar".  This is not
+  /// safe in case statements and a few other things.  This is managed by the
+  /// ColonProtectionRAIIObject RAII object.
+  bool ColonIsSacred;
+
+  /// \brief When true, we are directly inside an Objective-C message
+  /// send expression.
+  ///
+  /// This is managed by the \c InMessageExpressionRAIIObject class, and
+  /// should not be set directly.
+  bool InMessageExpression;
+
+  /// The "depth" of the template parameters currently being parsed.
+  unsigned TemplateParameterDepth;
+
+  /// \brief RAII class that manages the template parameter depth.
+  class TemplateParameterDepthRAII {
+    unsigned &Depth;
+    unsigned AddedLevels;
+  public:
+    explicit TemplateParameterDepthRAII(unsigned &Depth)
+      : Depth(Depth), AddedLevels(0) {}
+
+    ~TemplateParameterDepthRAII() {
+      Depth -= AddedLevels;
+    }
+
+    void operator++() {
+      ++Depth;
+      ++AddedLevels;
+    }
+    void addDepth(unsigned D) {
+      Depth += D;
+      AddedLevels += D;
+    }
+    unsigned getDepth() const { return Depth; }
+  };
+
+  /// Factory object for creating AttributeList objects.
+  AttributeFactory AttrFactory;
+
+  /// \brief Gathers and cleans up TemplateIdAnnotations when parsing of a
+  /// top-level declaration is finished.
+  SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
+
+  /// \brief Identifiers which have been declared within a tentative parse.
+  SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
+
+  IdentifierInfo *getSEHExceptKeyword();
+
+  /// True if we are within an Objective-C container while parsing C-like decls.
+  ///
+  /// This is necessary because Sema thinks we have left the container
+  /// to parse the C-like decls, meaning Actions.getObjCDeclContext() will
+  /// be NULL.
+  bool ParsingInObjCContainer;
+
+  bool SkipFunctionBodies;
+
+public:
+  Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
+  ~Parser();
+
+  const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
+  const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+  Preprocessor &getPreprocessor() const { return PP; }
+  Sema &getActions() const { return Actions; }
+  AttributeFactory &getAttrFactory() { return AttrFactory; }
+
+  const Token &getCurToken() const { return Tok; }
+  Scope *getCurScope() const { return Actions.getCurScope(); }
+  void incrementMSLocalManglingNumber() const {
+    return Actions.incrementMSLocalManglingNumber();
+  }
+
+  Decl  *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
+
+  // Type forwarding.  All of these are statically 'void*', but they may all be
+  // different actual classes based on the actions in place.
+  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
+  typedef OpaquePtr<TemplateName> TemplateTy;
+
+  typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
+
+  typedef clang::ExprResult        ExprResult;
+  typedef clang::StmtResult        StmtResult;
+  typedef clang::BaseResult        BaseResult;
+  typedef clang::MemInitResult     MemInitResult;
+  typedef clang::TypeResult        TypeResult;
+
+  typedef Expr *ExprArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef Sema::FullExprArg FullExprArg;
+
+  ExprResult ExprError() { return ExprResult(true); }
+  StmtResult StmtError() { return StmtResult(true); }
+
+  ExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
+  StmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
+
+  ExprResult ExprEmpty() { return ExprResult(false); }
+
+  // Parsing methods.
+
+  /// Initialize - Warm up the parser.
+  ///
+  void Initialize();
+
+  /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
+  /// the EOF was encountered.
+  bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+  bool ParseTopLevelDecl() {
+    DeclGroupPtrTy Result;
+    return ParseTopLevelDecl(Result);
+  }
+
+  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+  /// This does not work with special tokens: string literals, code completion
+  /// and balanced tokens must be handled using the specific consume methods.
+  /// Returns the location of the consumed token.
+  SourceLocation ConsumeToken() {
+    assert(!isTokenSpecial() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  bool TryConsumeToken(tok::TokenKind Expected) {
+    if (Tok.isNot(Expected))
+      return false;
+    assert(!isTokenSpecial() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return true;
+  }
+
+  bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
+    if (!TryConsumeToken(Expected))
+      return false;
+    Loc = PrevTokLocation;
+    return true;
+  }
+
+private:
+  //===--------------------------------------------------------------------===//
+  // Low-Level token peeking and consumption methods.
+  //
+
+  /// isTokenParen - Return true if the cur token is '(' or ')'.
+  bool isTokenParen() const {
+    return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
+  }
+  /// isTokenBracket - Return true if the cur token is '[' or ']'.
+  bool isTokenBracket() const {
+    return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
+  }
+  /// isTokenBrace - Return true if the cur token is '{' or '}'.
+  bool isTokenBrace() const {
+    return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
+  }
+  /// isTokenStringLiteral - True if this token is a string-literal.
+  bool isTokenStringLiteral() const {
+    return tok::isStringLiteral(Tok.getKind());
+  }
+  /// isTokenSpecial - True if this token requires special consumption methods.
+  bool isTokenSpecial() const {
+    return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
+           isTokenBrace() || Tok.is(tok::code_completion);
+  }
+
+  /// \brief Returns true if the current token is '=' or is a type of '='.
+  /// For typos, give a fixit to '='
+  bool isTokenEqualOrEqualTypo();
+
+  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
+  /// current token type.  This should only be used in cases where the type of
+  /// the token really isn't known, e.g. in error recovery.
+  SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
+    if (isTokenParen())
+      return ConsumeParen();
+    if (isTokenBracket())
+      return ConsumeBracket();
+    if (isTokenBrace())
+      return ConsumeBrace();
+    if (isTokenStringLiteral())
+      return ConsumeStringToken();
+    if (Tok.is(tok::code_completion))
+      return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+                                      : handleUnexpectedCodeCompletionToken();
+    return ConsumeToken();
+  }
+
+  /// ConsumeParen - This consume method keeps the paren count up-to-date.
+  ///
+  SourceLocation ConsumeParen() {
+    assert(isTokenParen() && "wrong consume method");
+    if (Tok.getKind() == tok::l_paren)
+      ++ParenCount;
+    else if (ParenCount)
+      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
+  ///
+  SourceLocation ConsumeBracket() {
+    assert(isTokenBracket() && "wrong consume method");
+    if (Tok.getKind() == tok::l_square)
+      ++BracketCount;
+    else if (BracketCount)
+      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
+
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
+  ///
+  SourceLocation ConsumeBrace() {
+    assert(isTokenBrace() && "wrong consume method");
+    if (Tok.getKind() == tok::l_brace)
+      ++BraceCount;
+    else if (BraceCount)
+      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
+
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
+  /// and returning the token kind.  This method is specific to strings, as it
+  /// handles string literal concatenation, as per C99 5.1.1.2, translation
+  /// phase #6.
+  SourceLocation ConsumeStringToken() {
+    assert(isTokenStringLiteral() &&
+           "Should only consume string literals with this method");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  /// \brief Consume the current code-completion token.
+  ///
+  /// This routine can be called to consume the code-completion token and
+  /// continue processing in special cases where \c cutOffParsing() isn't
+  /// desired, such as token caching or completion with lookahead.
+  SourceLocation ConsumeCodeCompletionToken() {
+    assert(Tok.is(tok::code_completion));
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return PrevTokLocation;
+  }
+
+  ///\ brief When we are consuming a code-completion token without having
+  /// matched specific position in the grammar, provide code-completion results
+  /// based on context.
+  ///
+  /// \returns the source location of the code-completion token.
+  SourceLocation handleUnexpectedCodeCompletionToken();
+
+  /// \brief Abruptly cut off parsing; mainly used when we have reached the
+  /// code-completion point.
+  void cutOffParsing() {
+    if (PP.isCodeCompletionEnabled())
+      PP.setCodeCompletionReached();
+    // Cut off parsing by acting as if we reached the end-of-file.
+    Tok.setKind(tok::eof);
+  }
+
+  /// \brief Determine if we're at the end of the file or at a transition
+  /// between modules.
+  bool isEofOrEom() {
+    tok::TokenKind Kind = Tok.getKind();
+    return Kind == tok::eof || Kind == tok::annot_module_begin ||
+           Kind == tok::annot_module_end || Kind == tok::annot_module_include;
+  }
+
+  /// \brief Initialize all pragma handlers.
+  void initializePragmaHandlers();
+
+  /// \brief Destroy and reset all pragma handlers.
+  void resetPragmaHandlers();
+
+  /// \brief Handle the annotation token produced for #pragma unused(...)
+  void HandlePragmaUnused();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma GCC visibility...
+  void HandlePragmaVisibility();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma pack...
+  void HandlePragmaPack();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma ms_struct...
+  void HandlePragmaMSStruct();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma comment...
+  void HandlePragmaMSComment();
+
+  void HandlePragmaMSPointersToMembers();
+
+  void HandlePragmaMSVtorDisp();
+
+  void HandlePragmaMSPragma();
+  bool HandlePragmaMSSection(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+  bool HandlePragmaMSSegment(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+  bool HandlePragmaMSInitSeg(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma align...
+  void HandlePragmaAlign();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma weak id...
+  void HandlePragmaWeak();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma weak id = id...
+  void HandlePragmaWeakAlias();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma redefine_extname...
+  void HandlePragmaRedefineExtname();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma STDC FP_CONTRACT...
+  void HandlePragmaFPContract();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma OPENCL EXTENSION...
+  void HandlePragmaOpenCLExtension();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma clang __debug captured
+  StmtResult HandlePragmaCaptured();
+
+  /// \brief Handle the annotation token produced for
+  /// #pragma clang loop and #pragma unroll.
+  LoopHint HandlePragmaLoopHint();
+
+  /// GetLookAheadToken - This peeks ahead N tokens and returns that token
+  /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
+  /// returns the token after Tok, etc.
+  ///
+  /// Note that this differs from the Preprocessor's LookAhead method, because
+  /// the Parser always has one token lexed that the preprocessor doesn't.
+  ///
+  const Token &GetLookAheadToken(unsigned N) {
+    if (N == 0 || Tok.is(tok::eof)) return Tok;
+    return PP.LookAhead(N-1);
+  }
+
+public:
+  /// NextToken - This peeks ahead one token and returns it without
+  /// consuming it.
+  const Token &NextToken() {
+    return PP.LookAhead(0);
+  }
+
+  /// getTypeAnnotation - Read a parsed type out of an annotation token.
+  static ParsedType getTypeAnnotation(Token &Tok) {
+    return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
+  }
+
+private:
+  static void setTypeAnnotation(Token &Tok, ParsedType T) {
+    Tok.setAnnotationValue(T.getAsOpaquePtr());
+  }
+
+  /// \brief Read an already-translated primary expression out of an annotation
+  /// token.
+  static ExprResult getExprAnnotation(Token &Tok) {
+    return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
+  }
+
+  /// \brief Set the primary expression corresponding to the given annotation
+  /// token.
+  static void setExprAnnotation(Token &Tok, ExprResult ER) {
+    Tok.setAnnotationValue(ER.getAsOpaquePointer());
+  }
+
+public:
+  // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
+  // find a type name by attempting typo correction.
+  bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false,
+                                   bool NeedType = false);
+  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
+                                                 bool NeedType,
+                                                 CXXScopeSpec &SS,
+                                                 bool IsNewScope);
+  bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+
+private:
+  enum AnnotatedNameKind {
+    /// Annotation has failed and emitted an error.
+    ANK_Error,
+    /// The identifier is a tentatively-declared name.
+    ANK_TentativeDecl,
+    /// The identifier is a template name. FIXME: Add an annotation for that.
+    ANK_TemplateName,
+    /// The identifier can't be resolved.
+    ANK_Unresolved,
+    /// Annotation was successful.
+    ANK_Success
+  };
+  AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
+                                    CorrectionCandidateCallback *CCC = nullptr);
+
+  /// Push a tok::annot_cxxscope token onto the token stream.
+  void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
+
+  /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
+  /// replacing them with the non-context-sensitive keywords.  This returns
+  /// true if the token was replaced.
+  bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID,
+                       bool &isInvalid) {
+    if (!getLangOpts().AltiVec ||
+        (Tok.getIdentifierInfo() != Ident_vector &&
+         Tok.getIdentifierInfo() != Ident_pixel &&
+         Tok.getIdentifierInfo() != Ident_bool))
+      return false;
+
+    return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
+  }
+
+  /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
+  /// identifier token, replacing it with the non-context-sensitive __vector.
+  /// This returns true if the token was replaced.
+  bool TryAltiVecVectorToken() {
+    if (!getLangOpts().AltiVec ||
+        Tok.getIdentifierInfo() != Ident_vector) return false;
+    return TryAltiVecVectorTokenOutOfLine();
+  }
+
+  bool TryAltiVecVectorTokenOutOfLine();
+  bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
+                                const char *&PrevSpec, unsigned &DiagID,
+                                bool &isInvalid);
+
+  /// TryKeywordIdentFallback - For compatibility with system headers using
+  /// keywords as identifiers, attempt to convert the current token to an
+  /// identifier and optionally disable the keyword for the remainder of the
+  /// translation unit. This returns false if the token was not replaced,
+  /// otherwise emits a diagnostic and returns true.
+  bool TryKeywordIdentFallback(bool DisableKeyword);
+
+  /// TryIdentKeywordUpgrade - Convert the current identifier token back to
+  /// its original kind and return true if it was disabled by
+  /// TryKeywordIdentFallback(), otherwise return false. Use this to
+  /// contextually enable keywords.
+  bool TryIdentKeywordUpgrade();
+
+  /// \brief Get the TemplateIdAnnotation from the token.
+  TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
+
+  /// TentativeParsingAction - An object that is used as a kind of "tentative
+  /// parsing transaction". It gets instantiated to mark the token position and
+  /// after the token consumption is done, Commit() or Revert() is called to
+  /// either "commit the consumed tokens" or revert to the previously marked
+  /// token position. Example:
+  ///
+  ///   TentativeParsingAction TPA(*this);
+  ///   ConsumeToken();
+  ///   ....
+  ///   TPA.Revert();
+  ///
+  class TentativeParsingAction {
+    Parser &P;
+    Token PrevTok;
+    size_t PrevTentativelyDeclaredIdentifierCount;
+    unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
+    bool isActive;
+
+  public:
+    explicit TentativeParsingAction(Parser& p) : P(p) {
+      PrevTok = P.Tok;
+      PrevTentativelyDeclaredIdentifierCount =
+          P.TentativelyDeclaredIdentifiers.size();
+      PrevParenCount = P.ParenCount;
+      PrevBracketCount = P.BracketCount;
+      PrevBraceCount = P.BraceCount;
+      P.PP.EnableBacktrackAtThisPos();
+      isActive = true;
+    }
+    void Commit() {
+      assert(isActive && "Parsing action was finished!");
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
+      P.PP.CommitBacktrackedTokens();
+      isActive = false;
+    }
+    void Revert() {
+      assert(isActive && "Parsing action was finished!");
+      P.PP.Backtrack();
+      P.Tok = PrevTok;
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
+      P.ParenCount = PrevParenCount;
+      P.BracketCount = PrevBracketCount;
+      P.BraceCount = PrevBraceCount;
+      isActive = false;
+    }
+    ~TentativeParsingAction() {
+      assert(!isActive && "Forgot to call Commit or Revert!");
+    }
+  };
+  class UnannotatedTentativeParsingAction;
+
+  /// ObjCDeclContextSwitch - An object used to switch context from
+  /// an objective-c decl context to its enclosing decl context and
+  /// back.
+  class ObjCDeclContextSwitch {
+    Parser &P;
+    Decl *DC;
+    SaveAndRestore<bool> WithinObjCContainer;
+  public:
+    explicit ObjCDeclContextSwitch(Parser &p)
+      : P(p), DC(p.getObjCDeclContext()),
+        WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
+      if (DC)
+        P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
+    }
+    ~ObjCDeclContextSwitch() {
+      if (DC)
+        P.Actions.ActOnObjCReenterContainerContext(cast<DeclContext>(DC));
+    }
+  };
+
+  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+  /// input.  If so, it is consumed and false is returned.
+  ///
+  /// If a trivial punctuator misspelling is encountered, a FixIt error
+  /// diagnostic is issued and false is returned after recovery.
+  ///
+  /// If the input is malformed, this emits the specified diagnostic and true is
+  /// returned.
+  bool ExpectAndConsume(tok::TokenKind ExpectedTok,
+                        unsigned Diag = diag::err_expected,
+                        StringRef DiagMsg = "");
+
+  /// \brief The parser expects a semicolon and, if present, will consume it.
+  ///
+  /// If the next token is not a semicolon, this emits the specified diagnostic,
+  /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
+  /// to the semicolon, consumes that extra token.
+  bool ExpectAndConsumeSemi(unsigned DiagID);
+
+  /// \brief The kind of extra semi diagnostic to emit.
+  enum ExtraSemiKind {
+    OutsideFunction = 0,
+    InsideStruct = 1,
+    InstanceVariableList = 2,
+    AfterMemberFunctionDefinition = 3
+  };
+
+  /// \brief Consume any extra semi-colons until the end of the line.
+  void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
+
+public:
+  //===--------------------------------------------------------------------===//
+  // Scope manipulation
+
+  /// ParseScope - Introduces a new scope for parsing. The kind of
+  /// scope is determined by ScopeFlags. Objects of this type should
+  /// be created on the stack to coincide with the position where the
+  /// parser enters the new scope, and this object's constructor will
+  /// create that new scope. Similarly, once the object is destroyed
+  /// the parser will exit the scope.
+  class ParseScope {
+    Parser *Self;
+    ParseScope(const ParseScope &) LLVM_DELETED_FUNCTION;
+    void operator=(const ParseScope &) LLVM_DELETED_FUNCTION;
+
+  public:
+    // ParseScope - Construct a new object to manage a scope in the
+    // parser Self where the new Scope is created with the flags
+    // ScopeFlags, but only when we aren't about to enter a compound statement.
+    ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
+               bool BeforeCompoundStmt = false)
+      : Self(Self) {
+      if (EnteredScope && !BeforeCompoundStmt)
+        Self->EnterScope(ScopeFlags);
+      else {
+        if (BeforeCompoundStmt)
+          Self->incrementMSLocalManglingNumber();
+
+        this->Self = nullptr;
+      }
+    }
+
+    // Exit - Exit the scope associated with this object now, rather
+    // than waiting until the object is destroyed.
+    void Exit() {
+      if (Self) {
+        Self->ExitScope();
+        Self = nullptr;
+      }
+    }
+
+    ~ParseScope() {
+      Exit();
+    }
+  };
+
+  /// EnterScope - Start a new scope.
+  void EnterScope(unsigned ScopeFlags);
+
+  /// ExitScope - Pop a scope off the scope stack.
+  void ExitScope();
+
+private:
+  /// \brief RAII object used to modify the scope flags for the current scope.
+  class ParseScopeFlags {
+    Scope *CurScope;
+    unsigned OldFlags;
+    ParseScopeFlags(const ParseScopeFlags &) LLVM_DELETED_FUNCTION;
+    void operator=(const ParseScopeFlags &) LLVM_DELETED_FUNCTION;
+
+  public:
+    ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
+    ~ParseScopeFlags();
+  };
+
+  //===--------------------------------------------------------------------===//
+  // Diagnostic Emission and Error recovery.
+
+public:
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+  DiagnosticBuilder Diag(unsigned DiagID) {
+    return Diag(Tok, DiagID);
+  }
+
+private:
+  void SuggestParentheses(SourceLocation Loc, unsigned DK,
+                          SourceRange ParenRange);
+  void CheckNestedObjCContexts(SourceLocation AtLoc);
+
+public:
+
+  /// \brief Control flags for SkipUntil functions.
+  enum SkipUntilFlags {
+    StopAtSemi = 1 << 0,  ///< Stop skipping at semicolon
+    /// \brief Stop skipping at specified token, but don't skip the token itself
+    StopBeforeMatch = 1 << 1,
+    StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
+  };
+
+  friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L,
+                                                 SkipUntilFlags R) {
+    return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
+                                       static_cast<unsigned>(R));
+  }
+
+  /// SkipUntil - Read tokens until we get to the specified token, then consume
+  /// it (unless StopBeforeMatch is specified).  Because we cannot guarantee
+  /// that the token will ever occur, this skips to the next token, or to some
+  /// likely good stopping point.  If Flags has StopAtSemi flag, skipping will
+  /// stop at a ';' character.
+  ///
+  /// If SkipUntil finds the specified token, it returns true, otherwise it
+  /// returns false.
+  bool SkipUntil(tok::TokenKind T,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    return SkipUntil(llvm::makeArrayRef(T), Flags);
+  }
+  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    tok::TokenKind TokArray[] = {T1, T2};
+    return SkipUntil(TokArray, Flags);
+  }
+  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
+    tok::TokenKind TokArray[] = {T1, T2, T3};
+    return SkipUntil(TokArray, Flags);
+  }
+  bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
+                 SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
+
+  /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
+  /// point for skipping past a simple-declaration.
+  void SkipMalformedDecl();
+
+private:
+  //===--------------------------------------------------------------------===//
+  // Lexing and parsing of C++ inline methods.
+
+  struct ParsingClass;
+
+  /// [class.mem]p1: "... the class is regarded as complete within
+  /// - function bodies
+  /// - default arguments
+  /// - exception-specifications (TODO: C++0x)
+  /// - and brace-or-equal-initializers for non-static data members
+  /// (including such things in nested classes)."
+  /// LateParsedDeclarations build the tree of those elements so they can
+  /// be parsed after parsing the top-level class.
+  class LateParsedDeclaration {
+  public:
+    virtual ~LateParsedDeclaration();
+
+    virtual void ParseLexedMethodDeclarations();
+    virtual void ParseLexedMemberInitializers();
+    virtual void ParseLexedMethodDefs();
+    virtual void ParseLexedAttributes();
+  };
+
+  /// Inner node of the LateParsedDeclaration tree that parses
+  /// all its members recursively.
+  class LateParsedClass : public LateParsedDeclaration {
+  public:
+    LateParsedClass(Parser *P, ParsingClass *C);
+    virtual ~LateParsedClass();
+
+    void ParseLexedMethodDeclarations() override;
+    void ParseLexedMemberInitializers() override;
+    void ParseLexedMethodDefs() override;
+    void ParseLexedAttributes() override;
+
+  private:
+    Parser *Self;
+    ParsingClass *Class;
+  };
+
+  /// Contains the lexed tokens of an attribute with arguments that
+  /// may reference member variables and so need to be parsed at the
+  /// end of the class declaration after parsing all other member
+  /// member declarations.
+  /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
+  /// LateParsedTokens.
+  struct LateParsedAttribute : public LateParsedDeclaration {
+    Parser *Self;
+    CachedTokens Toks;
+    IdentifierInfo &AttrName;
+    SourceLocation AttrNameLoc;
+    SmallVector<Decl*, 2> Decls;
+
+    explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
+                                 SourceLocation Loc)
+      : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
+
+    void ParseLexedAttributes() override;
+
+    void addDecl(Decl *D) { Decls.push_back(D); }
+  };
+
+  // A list of late-parsed attributes.  Used by ParseGNUAttributes.
+  class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
+  public:
+    LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { }
+
+    bool parseSoon() { return ParseSoon; }
+
+  private:
+    bool ParseSoon;  // Are we planning to parse these shortly after creation?
+  };
+
+  /// Contains the lexed tokens of a member function definition
+  /// which needs to be parsed at the end of the class declaration
+  /// after parsing all other member declarations.
+  struct LexedMethod : public LateParsedDeclaration {
+    Parser *Self;
+    Decl *D;
+    CachedTokens Toks;
+
+    /// \brief Whether this member function had an associated template
+    /// scope. When true, D is a template declaration.
+    /// otherwise, it is a member function declaration.
+    bool TemplateScope;
+
+    explicit LexedMethod(Parser* P, Decl *MD)
+      : Self(P), D(MD), TemplateScope(false) {}
+
+    void ParseLexedMethodDefs() override;
+  };
+
+  /// LateParsedDefaultArgument - Keeps track of a parameter that may
+  /// have a default argument that cannot be parsed yet because it
+  /// occurs within a member function declaration inside the class
+  /// (C++ [class.mem]p2).
+  struct LateParsedDefaultArgument {
+    explicit LateParsedDefaultArgument(Decl *P,
+                                       CachedTokens *Toks = nullptr)
+      : Param(P), Toks(Toks) { }
+
+    /// Param - The parameter declaration for this parameter.
+    Decl *Param;
+
+    /// Toks - The sequence of tokens that comprises the default
+    /// argument expression, not including the '=' or the terminating
+    /// ')' or ','. This will be NULL for parameters that have no
+    /// default argument.
+    CachedTokens *Toks;
+  };
+
+  /// LateParsedMethodDeclaration - A method declaration inside a class that
+  /// contains at least one entity whose parsing needs to be delayed
+  /// until the class itself is completely-defined, such as a default
+  /// argument (C++ [class.mem]p2).
+  struct LateParsedMethodDeclaration : public LateParsedDeclaration {
+    explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
+      : Self(P), Method(M), TemplateScope(false),
+        ExceptionSpecTokens(nullptr) {}
+
+    void ParseLexedMethodDeclarations() override;
+
+    Parser* Self;
+
+    /// Method - The method declaration.
+    Decl *Method;
+
+    /// \brief Whether this member function had an associated template
+    /// scope. When true, D is a template declaration.
+    /// othewise, it is a member function declaration.
+    bool TemplateScope;
+
+    /// DefaultArgs - Contains the parameters of the function and
+    /// their default arguments. At least one of the parameters will
+    /// have a default argument, but all of the parameters of the
+    /// method will be stored so that they can be reintroduced into
+    /// scope at the appropriate times.
+    SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
+  
+    /// \brief The set of tokens that make up an exception-specification that
+    /// has not yet been parsed.
+    CachedTokens *ExceptionSpecTokens;
+  };
+
+  /// LateParsedMemberInitializer - An initializer for a non-static class data
+  /// member whose parsing must to be delayed until the class is completely
+  /// defined (C++11 [class.mem]p2).
+  struct LateParsedMemberInitializer : public LateParsedDeclaration {
+    LateParsedMemberInitializer(Parser *P, Decl *FD)
+      : Self(P), Field(FD) { }
+
+    void ParseLexedMemberInitializers() override;
+
+    Parser *Self;
+
+    /// Field - The field declaration.
+    Decl *Field;
+
+    /// CachedTokens - The sequence of tokens that comprises the initializer,
+    /// including any leading '='.
+    CachedTokens Toks;
+  };
+
+  /// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
+  /// C++ class, its method declarations that contain parts that won't be
+  /// parsed until after the definition is completed (C++ [class.mem]p2),
+  /// the method declarations and possibly attached inline definitions
+  /// will be stored here with the tokens that will be parsed to create those 
+  /// entities.
+  typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
+
+  /// \brief Representation of a class that has been parsed, including
+  /// any member function declarations or definitions that need to be
+  /// parsed after the corresponding top-level class is complete.
+  struct ParsingClass {
+    ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
+      : TopLevelClass(TopLevelClass), TemplateScope(false),
+        IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { }
+
+    /// \brief Whether this is a "top-level" class, meaning that it is
+    /// not nested within another class.
+    bool TopLevelClass : 1;
+
+    /// \brief Whether this class had an associated template
+    /// scope. When true, TagOrTemplate is a template declaration;
+    /// othewise, it is a tag declaration.
+    bool TemplateScope : 1;
+
+    /// \brief Whether this class is an __interface.
+    bool IsInterface : 1;
+
+    /// \brief The class or class template whose definition we are parsing.
+    Decl *TagOrTemplate;
+
+    /// LateParsedDeclarations - Method declarations, inline definitions and
+    /// nested classes that contain pieces whose parsing will be delayed until
+    /// the top-level class is fully defined.
+    LateParsedDeclarationsContainer LateParsedDeclarations;
+  };
+
+  /// \brief The stack of classes that is currently being
+  /// parsed. Nested and local classes will be pushed onto this stack
+  /// when they are parsed, and removed afterward.
+  std::stack<ParsingClass *> ClassStack;
+
+  ParsingClass &getCurrentClass() {
+    assert(!ClassStack.empty() && "No lexed method stacks!");
+    return *ClassStack.top();
+  }
+
+  /// \brief RAII object used to manage the parsing of a class definition.
+  class ParsingClassDefinition {
+    Parser &P;
+    bool Popped;
+    Sema::ParsingClassState State;
+
+  public:
+    ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
+                           bool IsInterface)
+      : P(P), Popped(false),
+        State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
+    }
+
+    /// \brief Pop this class of the stack.
+    void Pop() {
+      assert(!Popped && "Nested class has already been popped");
+      Popped = true;
+      P.PopParsingClass(State);
+    }
+
+    ~ParsingClassDefinition() {
+      if (!Popped)
+        P.PopParsingClass(State);
+    }
+  };
+
+  /// \brief Contains information about any template-specific
+  /// information that has been parsed prior to parsing declaration
+  /// specifiers.
+  struct ParsedTemplateInfo {
+    ParsedTemplateInfo()
+      : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { }
+
+    ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
+                       bool isSpecialization,
+                       bool lastParameterListWasEmpty = false)
+      : Kind(isSpecialization? ExplicitSpecialization : Template),
+        TemplateParams(TemplateParams),
+        LastParameterListWasEmpty(lastParameterListWasEmpty) { }
+
+    explicit ParsedTemplateInfo(SourceLocation ExternLoc,
+                                SourceLocation TemplateLoc)
+      : Kind(ExplicitInstantiation), TemplateParams(nullptr),
+        ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
+        LastParameterListWasEmpty(false){ }
+
+    /// \brief The kind of template we are parsing.
+    enum {
+      /// \brief We are not parsing a template at all.
+      NonTemplate = 0,
+      /// \brief We are parsing a template declaration.
+      Template,
+      /// \brief We are parsing an explicit specialization.
+      ExplicitSpecialization,
+      /// \brief We are parsing an explicit instantiation.
+      ExplicitInstantiation
+    } Kind;
+
+    /// \brief The template parameter lists, for template declarations
+    /// and explicit specializations.
+    TemplateParameterLists *TemplateParams;
+
+    /// \brief The location of the 'extern' keyword, if any, for an explicit
+    /// instantiation
+    SourceLocation ExternLoc;
+
+    /// \brief The location of the 'template' keyword, for an explicit
+    /// instantiation.
+    SourceLocation TemplateLoc;
+
+    /// \brief Whether the last template parameter list was empty.
+    bool LastParameterListWasEmpty;
+
+    SourceRange getSourceRange() const LLVM_READONLY;
+  };
+
+  void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
+  void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
+
+  static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
+
+  Sema::ParsingClassState
+  PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
+  void DeallocateParsedClasses(ParsingClass *Class);
+  void PopParsingClass(Sema::ParsingClassState);
+
+  enum CachedInitKind {
+    CIK_DefaultArgument,
+    CIK_DefaultInitializer
+  };
+
+  NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
+                                AttributeList *AccessAttrs,
+                                ParsingDeclarator &D,
+                                const ParsedTemplateInfo &TemplateInfo,
+                                const VirtSpecifiers& VS,
+                                FunctionDefinitionKind DefinitionKind,
+                                ExprResult& Init);
+  void ParseCXXNonStaticMemberInitializer(Decl *VarD);
+  void ParseLexedAttributes(ParsingClass &Class);
+  void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
+                               bool EnterScope, bool OnDefinition);
+  void ParseLexedAttribute(LateParsedAttribute &LA,
+                           bool EnterScope, bool OnDefinition);
+  void ParseLexedMethodDeclarations(ParsingClass &Class);
+  void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
+  void ParseLexedMethodDefs(ParsingClass &Class);
+  void ParseLexedMethodDef(LexedMethod &LM);
+  void ParseLexedMemberInitializers(ParsingClass &Class);
+  void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
+  void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
+  bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
+  bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
+  bool ConsumeAndStoreConditional(CachedTokens &Toks);
+  bool ConsumeAndStoreUntil(tok::TokenKind T1,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true) {
+    return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
+  }
+  bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
+                            CachedTokens &Toks,
+                            bool StopAtSemi = true,
+                            bool ConsumeFinalToken = true);
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.9: External Definitions.
+  struct ParsedAttributesWithRange : ParsedAttributes {
+    ParsedAttributesWithRange(AttributeFactory &factory)
+      : ParsedAttributes(factory) {}
+
+    SourceRange Range;
+  };
+
+  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
+                                          ParsingDeclSpec *DS = nullptr);
+  bool isDeclarationAfterDeclarator();
+  bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
+  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
+                                                  ParsedAttributesWithRange &attrs,
+                                                  ParsingDeclSpec *DS = nullptr,
+                                                  AccessSpecifier AS = AS_none);
+  DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
+                                                ParsingDeclSpec &DS,
+                                                AccessSpecifier AS);
+
+  Decl *ParseFunctionDefinition(ParsingDeclarator &D,
+                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                 LateParsedAttrList *LateParsedAttrs = nullptr);
+  void ParseKNRParamDeclarations(Declarator &D);
+  // EndLoc, if non-NULL, is filled with the location of the last token of
+  // the simple-asm.
+  ExprResult ParseSimpleAsm(SourceLocation *EndLoc = nullptr);
+  ExprResult ParseAsmStringLiteral();
+
+  // Objective-C External Declarations
+  void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
+  DeclGroupPtrTy ParseObjCAtDirectives();
+  DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
+  Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
+                                        ParsedAttributes &prefixAttrs);
+  void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
+                                        BalancedDelimiterTracker &T,
+                                        SmallVectorImpl<Decl *> &AllIvarDecls,
+                                        bool RBraceMissing);
+  void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
+                                       tok::ObjCKeywordKind visibility,
+                                       SourceLocation atLoc);
+  bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
+                                   SmallVectorImpl<SourceLocation> &PLocs,
+                                   bool WarnOnDeclarations,
+                                   SourceLocation &LAngleLoc,
+                                   SourceLocation &EndProtoLoc);
+  bool ParseObjCProtocolQualifiers(DeclSpec &DS);
+  void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
+                                  Decl *CDecl);
+  DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+                                                ParsedAttributes &prefixAttrs);
+
+  struct ObjCImplParsingDataRAII {
+    Parser &P;
+    Decl *Dcl;
+    bool HasCFunction;
+    typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
+    LateParsedObjCMethodContainer LateParsedObjCMethods;
+
+    ObjCImplParsingDataRAII(Parser &parser, Decl *D)
+      : P(parser), Dcl(D), HasCFunction(false) {
+      P.CurParsedObjCImpl = this;
+      Finished = false;
+    }
+    ~ObjCImplParsingDataRAII();
+
+    void finish(SourceRange AtEnd);
+    bool isFinished() const { return Finished; }
+
+  private:
+    bool Finished;
+  };
+  ObjCImplParsingDataRAII *CurParsedObjCImpl;
+  void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
+
+  DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
+  DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
+  Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
+  Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
+  Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
+
+  IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
+  // Definitions for Objective-c context sensitive keywords recognition.
+  enum ObjCTypeQual {
+    objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
+    objc_NumQuals
+  };
+  IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
+
+  bool isTokIdentifier_in() const;
+
+  ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, Declarator::TheContext Ctx,
+                               ParsedAttributes *ParamAttrs);
+  void ParseObjCMethodRequirement();
+  Decl *ParseObjCMethodPrototype(
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition = true);
+  Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
+            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
+            bool MethodDefinition=true);
+  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
+
+  Decl *ParseObjCMethodDefinition();
+
+public:
+  //===--------------------------------------------------------------------===//
+  // C99 6.5: Expressions.
+
+  /// TypeCastState - State whether an expression is or may be a type cast.
+  enum TypeCastState {
+    NotTypeCast = 0,
+    MaybeTypeCast,
+    IsTypeCast
+  };
+
+  ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
+  ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
+  // Expr that doesn't include commas.
+  ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
+
+  ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
+                                  unsigned &NumLineToksConsumed,
+                                  void *Info,
+                                  bool IsUnevaluated);
+
+private:
+  ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
+
+  ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
+
+  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS,
+                                        prec::Level MinPrec);
+  ExprResult ParseCastExpression(bool isUnaryExpression,
+                                 bool isAddressOfOperand,
+                                 bool &NotCastExpr,
+                                 TypeCastState isTypeCast);
+  ExprResult ParseCastExpression(bool isUnaryExpression,
+                                 bool isAddressOfOperand = false,
+                                 TypeCastState isTypeCast = NotTypeCast);
+
+  /// Returns true if the next token cannot start an expression.
+  bool isNotExpressionStart();
+
+  /// Returns true if the next token would start a postfix-expression
+  /// suffix.
+  bool isPostfixExpressionSuffixStart() {
+    tok::TokenKind K = Tok.getKind();
+    return (K == tok::l_square || K == tok::l_paren ||
+            K == tok::period || K == tok::arrow ||
+            K == tok::plusplus || K == tok::minusminus);
+  }
+
+  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
+  ExprResult ParseUnaryExprOrTypeTraitExpression();
+  ExprResult ParseBuiltinPrimaryExpression();
+
+  ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
+                                                     bool &isCastExpr,
+                                                     ParsedType &CastTy,
+                                                     SourceRange &CastRange);
+
+  typedef SmallVector<Expr*, 20> ExprListTy;
+  typedef SmallVector<SourceLocation, 20> CommaLocsTy;
+
+  /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
+  bool
+  ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
+                      SmallVectorImpl<SourceLocation> &CommaLocs,
+                      void (Sema::*Completer)(Scope *S, Expr *Data,
+                                              ArrayRef<Expr *> Args) = nullptr,
+                      Expr *Data = nullptr);
+
+  /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
+  /// used for misc language extensions.
+  bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
+                                 SmallVectorImpl<SourceLocation> &CommaLocs);
+
+
+  /// ParenParseOption - Control what ParseParenExpression will parse.
+  enum ParenParseOption {
+    SimpleExpr,      // Only parse '(' expression ')'
+    CompoundStmt,    // Also allow '(' compound-statement ')'
+    CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
+    CastExpr         // Also allow '(' type-name ')' <anything>
+  };
+  ExprResult ParseParenExpression(ParenParseOption &ExprType,
+                                        bool stopIfCastExpr,
+                                        bool isTypeCast,
+                                        ParsedType &CastTy,
+                                        SourceLocation &RParenLoc);
+
+  ExprResult ParseCXXAmbiguousParenExpression(
+      ParenParseOption &ExprType, ParsedType &CastTy,
+      BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
+  ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
+                                                  SourceLocation LParenLoc,
+                                                  SourceLocation RParenLoc);
+
+  ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
+
+  ExprResult ParseGenericSelectionExpression();
+  
+  ExprResult ParseObjCBoolLiteral();
+
+  //===--------------------------------------------------------------------===//
+  // C++ Expressions
+  ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
+
+  bool areTokensAdjacent(const Token &A, const Token &B);
+
+  void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr,
+                                  bool EnteringContext, IdentifierInfo &II,
+                                  CXXScopeSpec &SS);
+
+  bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
+                                      ParsedType ObjectType,
+                                      bool EnteringContext,
+                                      bool *MayBePseudoDestructor = nullptr,
+                                      bool IsTypename = false,
+                                      IdentifierInfo **LastII = nullptr);
+
+  void CheckForLParenAfterColonColon();
+
+  //===--------------------------------------------------------------------===//
+  // C++0x 5.1.2: Lambda expressions
+
+  // [...] () -> type {...}
+  ExprResult ParseLambdaExpression();
+  ExprResult TryParseLambdaExpression();
+  Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro,
+                                           bool *SkippedInits = nullptr);
+  bool TryParseLambdaIntroducer(LambdaIntroducer &Intro);
+  ExprResult ParseLambdaExpressionAfterIntroducer(
+               LambdaIntroducer &Intro);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Casts
+  ExprResult ParseCXXCasts();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2p1: C++ Type Identification
+  ExprResult ParseCXXTypeid();
+
+  //===--------------------------------------------------------------------===//
+  //  C++ : Microsoft __uuidof Expression
+  ExprResult ParseCXXUuidof();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.4: C++ Pseudo-Destructor Expressions
+  ExprResult ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
+                                            tok::TokenKind OpKind,
+                                            CXXScopeSpec &SS,
+                                            ParsedType ObjectType);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 9.3.2: C++ 'this' pointer
+  ExprResult ParseCXXThis();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 15: C++ Throw Expression
+  ExprResult ParseThrowExpression();
+
+  ExceptionSpecificationType tryParseExceptionSpecification(
+                    SourceRange &SpecificationRange,
+                    SmallVectorImpl<ParsedType> &DynamicExceptions,
+                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
+                    ExprResult &NoexceptExpr);
+
+  // EndLoc is filled with the location of the last token of the specification.
+  ExceptionSpecificationType ParseDynamicExceptionSpecification(
+                                  SourceRange &SpecificationRange,
+                                  SmallVectorImpl<ParsedType> &Exceptions,
+                                  SmallVectorImpl<SourceRange> &Ranges);
+
+  //===--------------------------------------------------------------------===//
+  // C++0x 8: Function declaration trailing-return-type
+  TypeResult ParseTrailingReturnType(SourceRange &Range);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 2.13.5: C++ Boolean Literals
+  ExprResult ParseCXXBoolLiteral();
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.2.3: Explicit type conversion (functional notation)
+  ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+
+  /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
+  /// This should only be called when the current token is known to be part of
+  /// simple-type-specifier.
+  void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
+
+  bool ParseCXXTypeSpecifierSeq(DeclSpec &DS);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 5.3.4 and 5.3.5: C++ new and delete
+  bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
+                                   Declarator &D);
+  void ParseDirectNewDeclarator(Declarator &D);
+  ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
+  ExprResult ParseCXXDeleteExpression(bool UseGlobal,
+                                            SourceLocation Start);
+
+  //===--------------------------------------------------------------------===//
+  // C++ if/switch/while condition expression.
+  bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,
+                         SourceLocation Loc, bool ConvertToBoolean);
+
+  //===--------------------------------------------------------------------===//
+  // C++ types
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.7.8: Initialization.
+
+  /// ParseInitializer
+  ///       initializer: [C99 6.7.8]
+  ///         assignment-expression
+  ///         '{' ...
+  ExprResult ParseInitializer() {
+    if (Tok.isNot(tok::l_brace))
+      return ParseAssignmentExpression();
+    return ParseBraceInitializer();
+  }
+  bool MayBeDesignationStart();
+  ExprResult ParseBraceInitializer();
+  ExprResult ParseInitializerWithPotentialDesignator();
+
+  //===--------------------------------------------------------------------===//
+  // clang Expressions
+
+  ExprResult ParseBlockLiteralExpression();  // ^{...}
+
+  //===--------------------------------------------------------------------===//
+  // Objective-C Expressions
+  ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
+  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
+  ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
+  ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
+  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
+  ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
+  ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+  bool isSimpleObjCMessageExpression();
+  ExprResult ParseObjCMessageExpression();
+  ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
+                                            SourceLocation SuperLoc,
+                                            ParsedType ReceiverType,
+                                            ExprArg ReceiverExpr);
+  ExprResult ParseAssignmentExprWithObjCMessageExprStart(
+      SourceLocation LBracloc, SourceLocation SuperLoc,
+      ParsedType ReceiverType, ExprArg ReceiverExpr);
+  bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
+    
+  //===--------------------------------------------------------------------===//
+  // C99 6.8: Statements and Blocks.
+
+  /// A SmallVector of statements, with stack size 32 (as that is the only one
+  /// used.)
+  typedef SmallVector<Stmt*, 32> StmtVector;
+  /// A SmallVector of expressions, with stack size 12 (the maximum used.)
+  typedef SmallVector<Expr*, 12> ExprVector;
+  /// A SmallVector of types.
+  typedef SmallVector<ParsedType, 12> TypeVector;
+
+  StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr);
+  StmtResult
+  ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
+                              SourceLocation *TrailingElseLoc = nullptr);
+  StmtResult ParseStatementOrDeclarationAfterAttributes(
+                                         StmtVector &Stmts,
+                                         bool OnlyStatement,
+                                         SourceLocation *TrailingElseLoc,
+                                         ParsedAttributesWithRange &Attrs);
+  StmtResult ParseExprStatement();
+  StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs);
+  StmtResult ParseCaseStatement(bool MissingCase = false,
+                                ExprResult Expr = ExprResult());
+  StmtResult ParseDefaultStatement();
+  StmtResult ParseCompoundStatement(bool isStmtExpr = false);
+  StmtResult ParseCompoundStatement(bool isStmtExpr,
+                                    unsigned ScopeFlags);
+  void ParseCompoundStatementLeadingPragmas();
+  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
+  bool ParseParenExprOrCondition(ExprResult &ExprResult,
+                                 Decl *&DeclResult,
+                                 SourceLocation Loc,
+                                 bool ConvertToBoolean);
+  StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
+  StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
+  StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
+  StmtResult ParseDoStatement();
+  StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
+  StmtResult ParseGotoStatement();
+  StmtResult ParseContinueStatement();
+  StmtResult ParseBreakStatement();
+  StmtResult ParseReturnStatement();
+  StmtResult ParseAsmStatement(bool &msAsm);
+  StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
+  StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
+                                 SourceLocation *TrailingElseLoc,
+                                 ParsedAttributesWithRange &Attrs);
+
+  /// \brief Describes the behavior that should be taken for an __if_exists
+  /// block.
+  enum IfExistsBehavior {
+    /// \brief Parse the block; this code is always used.
+    IEB_Parse,
+    /// \brief Skip the block entirely; this code is never used.
+    IEB_Skip,
+    /// \brief Parse the block as a dependent block, which may be used in
+    /// some template instantiations but not others.
+    IEB_Dependent
+  };
+
+  /// \brief Describes the condition of a Microsoft __if_exists or
+  /// __if_not_exists block.
+  struct IfExistsCondition {
+    /// \brief The location of the initial keyword.
+    SourceLocation KeywordLoc;
+    /// \brief Whether this is an __if_exists block (rather than an
+    /// __if_not_exists block).
+    bool IsIfExists;
+
+    /// \brief Nested-name-specifier preceding the name.
+    CXXScopeSpec SS;
+
+    /// \brief The name we're looking for.
+    UnqualifiedId Name;
+
+    /// \brief The behavior of this __if_exists or __if_not_exists block
+    /// should.
+    IfExistsBehavior Behavior;
+  };
+
+  bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
+  void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
+  void ParseMicrosoftIfExistsExternalDeclaration();
+  void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
+                                              AccessSpecifier& CurAS);
+  bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
+                                              bool &InitExprsOk);
+  bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
+                           SmallVectorImpl<Expr *> &Constraints,
+                           SmallVectorImpl<Expr *> &Exprs);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 6: Statements and Blocks
+
+  StmtResult ParseCXXTryBlock();
+  StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
+  StmtResult ParseCXXCatchBlock(bool FnCatch = false);
+
+  //===--------------------------------------------------------------------===//
+  // MS: SEH Statements and Blocks
+
+  StmtResult ParseSEHTryBlock();
+  StmtResult ParseSEHTryBlockCommon(SourceLocation Loc);
+  StmtResult ParseSEHExceptBlock(SourceLocation Loc);
+  StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
+  StmtResult ParseSEHLeaveStatement();
+
+  //===--------------------------------------------------------------------===//
+  // Objective-C Statements
+
+  StmtResult ParseObjCAtStatement(SourceLocation atLoc);
+  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
+  StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
+  StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
+
+
+  //===--------------------------------------------------------------------===//
+  // C99 6.7: Declarations.
+
+  /// A context for parsing declaration specifiers.  TODO: flesh this
+  /// out, there are other significant restrictions on specifiers than
+  /// would be best implemented in the parser.
+  enum DeclSpecContext {
+    DSC_normal, // normal context
+    DSC_class,  // class context, enables 'friend'
+    DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
+    DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
+    DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
+    DSC_top_level, // top-level/namespace declaration context
+    DSC_template_type_arg // template type argument context
+  };
+
+  /// Is this a context in which we are parsing just a type-specifier (or
+  /// trailing-type-specifier)?
+  static bool isTypeSpecifier(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DSC_normal:
+    case DSC_class:
+    case DSC_top_level:
+      return false;
+
+    case DSC_template_type_arg:
+    case DSC_type_specifier:
+    case DSC_trailing:
+    case DSC_alias_declaration:
+      return true;
+    }
+    llvm_unreachable("Missing DeclSpecContext case");
+  }
+
+  /// Information on a C++0x for-range-initializer found while parsing a
+  /// declaration which turns out to be a for-range-declaration.
+  struct ForRangeInit {
+    SourceLocation ColonLoc;
+    ExprResult RangeExpr;
+
+    bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
+  };
+
+  DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts,
+                                  unsigned Context, SourceLocation &DeclEnd,
+                                  ParsedAttributesWithRange &attrs);
+  DeclGroupPtrTy ParseSimpleDeclaration(StmtVector &Stmts,
+                                        unsigned Context,
+                                        SourceLocation &DeclEnd,
+                                        ParsedAttributesWithRange &attrs,
+                                        bool RequireSemi,
+                                        ForRangeInit *FRI = nullptr);
+  bool MightBeDeclarator(unsigned Context);
+  DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
+                                bool AllowFunctionDefinitions,
+                                SourceLocation *DeclEnd = nullptr,
+                                ForRangeInit *FRI = nullptr);
+  Decl *ParseDeclarationAfterDeclarator(Declarator &D,
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  bool ParseAsmAttributesAfterDeclarator(Declarator &D);
+  Decl *ParseDeclarationAfterDeclaratorAndAttributes(
+      Declarator &D,
+      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+      ForRangeInit *FRI = nullptr);
+  Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
+  Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
+
+  /// \brief When in code-completion, skip parsing of the function/method body
+  /// unless the body contains the code-completion point.
+  ///
+  /// \returns true if the function body was skipped.
+  bool trySkippingFunctionBody();
+
+  bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
+                        const ParsedTemplateInfo &TemplateInfo,
+                        AccessSpecifier AS, DeclSpecContext DSC, 
+                        ParsedAttributesWithRange &Attrs);
+  DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
+  void ParseDeclarationSpecifiers(DeclSpec &DS,
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                  AccessSpecifier AS = AS_none,
+                                  DeclSpecContext DSC = DSC_normal,
+                                  LateParsedAttrList *LateAttrs = nullptr);
+  bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
+                                       DeclSpecContext DSContext,
+                                       LateParsedAttrList *LateAttrs = nullptr);
+
+  void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
+                                   DeclSpecContext DSC = DSC_normal);
+
+  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
+                                  Declarator::TheContext Context);
+
+  void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
+                          const ParsedTemplateInfo &TemplateInfo,
+                          AccessSpecifier AS, DeclSpecContext DSC);
+  void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
+  void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+                            Decl *TagDecl);
+
+  struct FieldCallback {
+    virtual void invoke(ParsingFieldDeclarator &Field) = 0;
+    virtual ~FieldCallback() {}
+
+  private:
+    virtual void _anchor();
+  };
+  struct ObjCPropertyCallback;
+
+  void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
+
+  bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
+  bool isTypeSpecifierQualifier();
+  bool isTypeQualifier() const;
+
+  /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
+  /// is definitely a type-specifier.  Return false if it isn't part of a type
+  /// specifier or if we're not sure.
+  bool isKnownToBeTypeSpecifier(const Token &Tok) const;
+
+  /// \brief Return true if we know that we are definitely looking at a
+  /// decl-specifier, and isn't part of an expression such as a function-style
+  /// cast. Return false if it's no a decl-specifier, or we're not sure.
+  bool isKnownToBeDeclarationSpecifier() {
+    if (getLangOpts().CPlusPlus)
+      return isCXXDeclarationSpecifier() == TPResult::True;
+    return isDeclarationSpecifier(true);
+  }
+
+  /// isDeclarationStatement - Disambiguates between a declaration or an
+  /// expression statement, when parsing function bodies.
+  /// Returns true for declaration, false for expression.
+  bool isDeclarationStatement() {
+    if (getLangOpts().CPlusPlus)
+      return isCXXDeclarationStatement();
+    return isDeclarationSpecifier(true);
+  }
+
+  /// isForInitDeclaration - Disambiguates between a declaration or an
+  /// expression in the context of the C 'clause-1' or the C++
+  // 'for-init-statement' part of a 'for' statement.
+  /// Returns true for declaration, false for expression.
+  bool isForInitDeclaration() {
+    if (getLangOpts().CPlusPlus)
+      return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
+    return isDeclarationSpecifier(true);
+  }
+
+  /// \brief Determine whether this is a C++1z for-range-identifier.
+  bool isForRangeIdentifier();
+
+  /// \brief Determine whether we are currently at the start of an Objective-C
+  /// class message that appears to be missing the open bracket '['.
+  bool isStartOfObjCClassMessageMissingOpenBracket();
+
+  /// \brief Starting with a scope specifier, identifier, or
+  /// template-id that refers to the current class, determine whether
+  /// this is a constructor declarator.
+  bool isConstructorDeclarator(bool Unqualified);
+
+  /// \brief Specifies the context in which type-id/expression
+  /// disambiguation will occur.
+  enum TentativeCXXTypeIdContext {
+    TypeIdInParens,
+    TypeIdUnambiguous,
+    TypeIdAsTemplateArgument
+  };
+
+
+  /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
+  /// whether the parens contain an expression or a type-id.
+  /// Returns true for a type-id and false for an expression.
+  bool isTypeIdInParens(bool &isAmbiguous) {
+    if (getLangOpts().CPlusPlus)
+      return isCXXTypeId(TypeIdInParens, isAmbiguous);
+    isAmbiguous = false;
+    return isTypeSpecifierQualifier();
+  }
+  bool isTypeIdInParens() {
+    bool isAmbiguous;
+    return isTypeIdInParens(isAmbiguous);
+  }
+
+  /// \brief Checks if the current tokens form type-id or expression.
+  /// It is similar to isTypeIdInParens but does not suppose that type-id
+  /// is in parenthesis.
+  bool isTypeIdUnambiguously() {
+    bool IsAmbiguous;
+    if (getLangOpts().CPlusPlus)
+      return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
+    return isTypeSpecifierQualifier();
+  }
+
+  /// isCXXDeclarationStatement - C++-specialized function that disambiguates
+  /// between a declaration or an expression statement, when parsing function
+  /// bodies. Returns true for declaration, false for expression.
+  bool isCXXDeclarationStatement();
+
+  /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
+  /// between a simple-declaration or an expression-statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  /// Returns false if the statement is disambiguated as expression.
+  bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
+
+  /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
+  /// a constructor-style initializer, when parsing declaration statements.
+  /// Returns true for function declarator and false for constructor-style
+  /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration 
+  /// might be a constructor-style initializer.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
+
+  /// isCXXConditionDeclaration - Disambiguates between a declaration or an
+  /// expression for a condition of a if/switch/while/for statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  bool isCXXConditionDeclaration();
+
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
+  bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
+    bool isAmbiguous;
+    return isCXXTypeId(Context, isAmbiguous);
+  }
+
+  /// TPResult - Used as the result value for functions whose purpose is to
+  /// disambiguate C++ constructs by "tentatively parsing" them.
+  enum class TPResult {
+    True, False, Ambiguous, Error
+  };
+
+  /// \brief Based only on the given token kind, determine whether we know that
+  /// we're at the start of an expression or a type-specifier-seq (which may
+  /// be an expression, in C++).
+  ///
+  /// This routine does not attempt to resolve any of the trick cases, e.g.,
+  /// those involving lookup of identifiers.
+  ///
+  /// \returns \c TPR_true if this token starts an expression, \c TPR_false if
+  /// this token starts a type-specifier-seq, or \c TPR_ambiguous if it cannot
+  /// tell.
+  TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
+
+  /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
+  /// declaration specifier, TPResult::False if it is not,
+  /// TPResult::Ambiguous if it could be either a decl-specifier or a
+  /// function-style cast, and TPResult::Error if a parsing error was
+  /// encountered. If it could be a braced C++11 function-style cast, returns
+  /// BracedCastResult.
+  /// Doesn't consume tokens.
+  TPResult
+  isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
+                            bool *HasMissingTypename = nullptr);
+
+  /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
+  /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
+  /// a type-specifier other than a cv-qualifier.
+  bool isCXXDeclarationSpecifierAType();
+
+  /// \brief Determine whether an identifier has been tentatively declared as a
+  /// non-type. Such tentative declarations should not be found to name a type
+  /// during a tentative parse, but also should not be annotated as a non-type.
+  bool isTentativelyDeclared(IdentifierInfo *II);
+
+  // "Tentative parsing" functions, used for disambiguation. If a parsing error
+  // is encountered they will return TPResult::Error.
+  // Returning TPResult::True/False indicates that the ambiguity was
+  // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
+  // that more tentative parsing is necessary for disambiguation.
+  // They all consume tokens, so backtracking should be used after calling them.
+
+  TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
+  TPResult TryParseTypeofSpecifier();
+  TPResult TryParseProtocolQualifiers();
+  TPResult TryParsePtrOperatorSeq();
+  TPResult TryParseOperatorId();
+  TPResult TryParseInitDeclaratorList();
+  TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
+  TPResult
+  TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
+                                     bool VersusTemplateArg = false);
+  TPResult TryParseFunctionDeclarator();
+  TPResult TryParseBracketDeclarator();
+  TPResult TryConsumeDeclarationSpecifier();
+
+public:
+  TypeResult ParseTypeName(SourceRange *Range = nullptr,
+                           Declarator::TheContext Context
+                             = Declarator::TypeNameContext,
+                           AccessSpecifier AS = AS_none,
+                           Decl **OwnedType = nullptr,
+                           ParsedAttributes *Attrs = nullptr);
+
+private:
+  void ParseBlockId(SourceLocation CaretLoc);
+
+  // Check for the start of a C++11 attribute-specifier-seq in a context where
+  // an attribute is not allowed.
+  bool CheckProhibitedCXX11Attribute() {
+    assert(Tok.is(tok::l_square));
+    if (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))
+      return false;
+    return DiagnoseProhibitedCXX11Attribute();
+  }
+  bool DiagnoseProhibitedCXX11Attribute();
+  void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+                                    SourceLocation CorrectLocation) {
+    if (!getLangOpts().CPlusPlus11)
+      return;
+    if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
+        Tok.isNot(tok::kw_alignas))
+      return;
+    DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
+  }
+  void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+                                       SourceLocation CorrectLocation);
+
+  void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
+    if (!attrs.Range.isValid()) return;
+    DiagnoseProhibitedAttributes(attrs);
+    attrs.clear();
+  }
+  void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
+
+  // Forbid C++11 attributes that appear on certain syntactic 
+  // locations which standard permits but we don't supported yet, 
+  // for example, attributes appertain to decl specifiers.
+  void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
+
+  /// \brief Skip C++11 attributes and return the end location of the last one.
+  /// \returns SourceLocation() if there are no attributes.
+  SourceLocation SkipCXX11Attributes();
+
+  /// \brief Diagnose and skip C++11 attributes that appear in syntactic
+  /// locations where attributes are not allowed.
+  void DiagnoseAndSkipCXX11Attributes();
+
+  /// \brief Parses syntax-generic attribute arguments for attributes which are
+  /// known to the implementation, and adds them to the given ParsedAttributes
+  /// list with the given attribute syntax. Returns the number of arguments
+  /// parsed for the attribute.
+  unsigned
+  ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                           ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                           IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                           AttributeList::Syntax Syntax);
+
+  void MaybeParseGNUAttributes(Declarator &D,
+                               LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.is(tok::kw___attribute)) {
+      ParsedAttributes attrs(AttrFactory);
+      SourceLocation endLoc;
+      ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
+      D.takeAttributes(attrs, endLoc);
+    }
+  }
+  void MaybeParseGNUAttributes(ParsedAttributes &attrs,
+                               SourceLocation *endLoc = nullptr,
+                               LateParsedAttrList *LateAttrs = nullptr) {
+    if (Tok.is(tok::kw___attribute))
+      ParseGNUAttributes(attrs, endLoc, LateAttrs);
+  }
+  void ParseGNUAttributes(ParsedAttributes &attrs,
+                          SourceLocation *endLoc = nullptr,
+                          LateParsedAttrList *LateAttrs = nullptr,
+                          Declarator *D = nullptr);
+  void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
+                             SourceLocation AttrNameLoc,
+                             ParsedAttributes &Attrs,
+                             SourceLocation *EndLoc,
+                             IdentifierInfo *ScopeName,
+                             SourceLocation ScopeLoc,
+                             AttributeList::Syntax Syntax,
+                             Declarator *D);
+  IdentifierLoc *ParseIdentifierLoc();
+
+  void MaybeParseCXX11Attributes(Declarator &D) {
+    if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+      ParsedAttributesWithRange attrs(AttrFactory);
+      SourceLocation endLoc;
+      ParseCXX11Attributes(attrs, &endLoc);
+      D.takeAttributes(attrs, endLoc);
+    }
+  }
+  void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
+                                 SourceLocation *endLoc = nullptr) {
+    if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
+      ParsedAttributesWithRange attrsWithRange(AttrFactory);
+      ParseCXX11Attributes(attrsWithRange, endLoc);
+      attrs.takeAllFrom(attrsWithRange);
+    }
+  }
+  void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
+                                 SourceLocation *endLoc = nullptr,
+                                 bool OuterMightBeMessageSend = false) {
+    if (getLangOpts().CPlusPlus11 &&
+        isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
+      ParseCXX11Attributes(attrs, endLoc);
+  }
+
+  void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
+                                    SourceLocation *EndLoc = nullptr);
+  void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
+                            SourceLocation *EndLoc = nullptr);
+  /// \brief Parses a C++-style attribute argument list. Returns true if this
+  /// results in adding an attribute to the ParsedAttributes list.
+  bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
+                               SourceLocation AttrNameLoc,
+                               ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                               IdentifierInfo *ScopeName,
+                               SourceLocation ScopeLoc);
+
+  IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
+
+  void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
+                                     SourceLocation *endLoc = nullptr) {
+    if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
+      ParseMicrosoftAttributes(attrs, endLoc);
+  }
+  void ParseMicrosoftAttributes(ParsedAttributes &attrs,
+                                SourceLocation *endLoc = nullptr);
+  void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs);
+  bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  ParsedAttributes &Attrs);
+  void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
+  void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
+  void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
+  void ParseOpenCLAttributes(ParsedAttributes &attrs);
+  void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
+
+  VersionTuple ParseVersionTuple(SourceRange &Range);
+  void ParseAvailabilityAttribute(IdentifierInfo &Availability,
+                                  SourceLocation AvailabilityLoc,
+                                  ParsedAttributes &attrs,
+                                  SourceLocation *endLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  AttributeList::Syntax Syntax);
+
+  void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+                                       SourceLocation ObjCBridgeRelatedLoc,
+                                       ParsedAttributes &attrs,
+                                       SourceLocation *endLoc,
+                                       IdentifierInfo *ScopeName,
+                                       SourceLocation ScopeLoc,
+                                       AttributeList::Syntax Syntax);
+
+  void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
+                                        SourceLocation AttrNameLoc,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation *EndLoc,
+                                        IdentifierInfo *ScopeName,
+                                        SourceLocation ScopeLoc,
+                                        AttributeList::Syntax Syntax);
+
+  void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
+                                 SourceLocation AttrNameLoc,
+                                 ParsedAttributes &Attrs,
+                                 SourceLocation *EndLoc,
+                                 IdentifierInfo *ScopeName,
+                                 SourceLocation ScopeLoc,
+                                 AttributeList::Syntax Syntax);
+
+  void ParseTypeofSpecifier(DeclSpec &DS);
+  SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
+  void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
+                                         SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
+  void ParseAtomicSpecifier(DeclSpec &DS);
+
+  ExprResult ParseAlignArgument(SourceLocation Start,
+                                SourceLocation &EllipsisLoc);
+  void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
+                               SourceLocation *endLoc = nullptr);
+
+  VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
+  VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
+    return isCXX11VirtSpecifier(Tok);
+  }
+  void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface);
+
+  bool isCXX11FinalKeyword() const;
+
+  /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
+  /// enter a new C++ declarator scope and exit it when the function is
+  /// finished.
+  class DeclaratorScopeObj {
+    Parser &P;
+    CXXScopeSpec &SS;
+    bool EnteredScope;
+    bool CreatedScope;
+  public:
+    DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
+      : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
+
+    void EnterDeclaratorScope() {
+      assert(!EnteredScope && "Already entered the scope!");
+      assert(SS.isSet() && "C++ scope was not set!");
+
+      CreatedScope = true;
+      P.EnterScope(0); // Not a decl scope.
+
+      if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
+        EnteredScope = true;
+    }
+
+    ~DeclaratorScopeObj() {
+      if (EnteredScope) {
+        assert(SS.isSet() && "C++ scope was cleared ?");
+        P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
+      }
+      if (CreatedScope)
+        P.ExitScope();
+    }
+  };
+
+  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
+  void ParseDeclarator(Declarator &D);
+  /// A function that parses a variant of direct-declarator.
+  typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
+  void ParseDeclaratorInternal(Declarator &D,
+                               DirectDeclParseFunction DirectDeclParser);
+
+  void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
+                                 bool CXX11AttributesAllowed = true,
+                                 bool AtomicAllowed = true,
+                                 bool IdentifierRequired = false);
+  void ParseDirectDeclarator(Declarator &D);
+  void ParseParenDeclarator(Declarator &D);
+  void ParseFunctionDeclarator(Declarator &D,
+                               ParsedAttributes &attrs,
+                               BalancedDelimiterTracker &Tracker,
+                               bool IsAmbiguous,
+                               bool RequiresArg = false);
+  bool isFunctionDeclaratorIdentifierList();
+  void ParseFunctionDeclaratorIdentifierList(
+         Declarator &D,
+         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
+  void ParseParameterDeclarationClause(
+         Declarator &D,
+         ParsedAttributes &attrs,
+         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+         SourceLocation &EllipsisLoc);
+  void ParseBracketDeclarator(Declarator &D);
+  void ParseMisplacedBracketDeclarator(Declarator &D);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 7: Declarations [dcl.dcl]
+
+  /// The kind of attribute specifier we have found.
+  enum CXX11AttributeKind {
+    /// This is not an attribute specifier.
+    CAK_NotAttributeSpecifier,
+    /// This should be treated as an attribute-specifier.
+    CAK_AttributeSpecifier,
+    /// The next tokens are '[[', but this is not an attribute-specifier. This
+    /// is ill-formed by C++11 [dcl.attr.grammar]p6.
+    CAK_InvalidAttributeSpecifier
+  };
+  CXX11AttributeKind
+  isCXX11AttributeSpecifier(bool Disambiguate = false,
+                            bool OuterMightBeMessageSend = false);
+
+  void DiagnoseUnexpectedNamespace(NamedDecl *Context);
+
+  Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd,
+                       SourceLocation InlineLoc = SourceLocation());
+  void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
+                           std::vector<IdentifierInfo*>& Ident,
+                           std::vector<SourceLocation>& NamespaceLoc,
+                           unsigned int index, SourceLocation& InlineLoc,
+                           ParsedAttributes& attrs,
+                           BalancedDelimiterTracker &Tracker);
+  Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
+  Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                         const ParsedTemplateInfo &TemplateInfo,
+                                         SourceLocation &DeclEnd,
+                                         ParsedAttributesWithRange &attrs,
+                                         Decl **OwnedType = nullptr);
+  Decl *ParseUsingDirective(unsigned Context,
+                            SourceLocation UsingLoc,
+                            SourceLocation &DeclEnd,
+                            ParsedAttributes &attrs);
+  Decl *ParseUsingDeclaration(unsigned Context,
+                              const ParsedTemplateInfo &TemplateInfo,
+                              SourceLocation UsingLoc,
+                              SourceLocation &DeclEnd,
+                              AccessSpecifier AS = AS_none,
+                              Decl **OwnedType = nullptr);
+  Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
+  Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
+                            SourceLocation AliasLoc, IdentifierInfo *Alias,
+                            SourceLocation &DeclEnd);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 9: classes [class] and C structs/unions.
+  bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
+  void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
+                           DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
+                           AccessSpecifier AS, bool EnteringContext,
+                           DeclSpecContext DSC, 
+                           ParsedAttributesWithRange &Attributes);
+  void ParseCXXMemberSpecification(SourceLocation StartLoc,
+                                   SourceLocation AttrFixitLoc,
+                                   ParsedAttributesWithRange &Attrs,
+                                   unsigned TagType,
+                                   Decl *TagDecl);
+  ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
+                                       SourceLocation &EqualLoc);
+  void ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
+                                                 VirtSpecifiers &VS,
+                                                 ExprResult &BitfieldSize,
+                                                 LateParsedAttrList &LateAttrs);
+  void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr,
+                  const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                  ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
+  void ParseConstructorInitializer(Decl *ConstructorDecl);
+  MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
+  void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
+                                      Decl *ThisDecl);
+
+  //===--------------------------------------------------------------------===//
+  // C++ 10: Derived classes [class.derived]
+  TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
+                                    SourceLocation &EndLocation);
+  void ParseBaseClause(Decl *ClassDecl);
+  BaseResult ParseBaseSpecifier(Decl *ClassDecl);
+  AccessSpecifier getAccessSpecifierIfPresent() const;
+
+  bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
+                                    SourceLocation TemplateKWLoc,
+                                    IdentifierInfo *Name,
+                                    SourceLocation NameLoc,
+                                    bool EnteringContext,
+                                    ParsedType ObjectType,
+                                    UnqualifiedId &Id,
+                                    bool AssumeTemplateId);
+  bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
+                                  ParsedType ObjectType,
+                                  UnqualifiedId &Result);
+
+  //===--------------------------------------------------------------------===//
+  // OpenMP: Directives and clauses.
+  /// \brief Parses declarative OpenMP directives.
+  DeclGroupPtrTy ParseOpenMPDeclarativeDirective();
+  /// \brief Parses simple list of variables.
+  ///
+  /// \param Kind Kind of the directive.
+  /// \param [out] VarList List of referenced variables.
+  /// \param AllowScopeSpecifier true, if the variables can have fully
+  /// qualified names.
+  ///
+  bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
+                                SmallVectorImpl<Expr *> &VarList,
+                                bool AllowScopeSpecifier);
+  /// \brief Parses declarative or executable directive.
+  ///
+  /// \param StandAloneAllowed true if allowed stand-alone directives,
+  /// false - otherwise
+  ///
+  StmtResult
+  ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed);
+  /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind.
+  ///
+  /// \param DKind Kind of current directive.
+  /// \param CKind Kind of current clause.
+  /// \param FirstClause true, if this is the first clause of a kind \a CKind
+  /// in current directive.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
+                               OpenMPClauseKind CKind, bool FirstClause);
+  /// \brief Parses clause with a single expression of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind);
+  /// \brief Parses simple clause of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause with a single expression and an additional argument
+  /// of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause without any additional arguments.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause with the list of variables of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPVarListClause(OpenMPClauseKind Kind);
+public:
+  bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
+                          bool AllowDestructorName,
+                          bool AllowConstructorName,
+                          ParsedType ObjectType,
+                          SourceLocation& TemplateKWLoc,
+                          UnqualifiedId &Result);
+
+private:
+  //===--------------------------------------------------------------------===//
+  // C++ 14: Templates [temp]
+
+  // C++ 14.1: Template Parameters [temp.param]
+  Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
+                                          SourceLocation &DeclEnd,
+                                          AccessSpecifier AS = AS_none,
+                                          AttributeList *AccessAttrs = nullptr);
+  Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
+                                                 SourceLocation &DeclEnd,
+                                                 AccessSpecifier AS,
+                                                 AttributeList *AccessAttrs);
+  Decl *ParseSingleDeclarationAfterTemplate(
+                                       unsigned Context,
+                                       const ParsedTemplateInfo &TemplateInfo,
+                                       ParsingDeclRAIIObject &DiagsFromParams,
+                                       SourceLocation &DeclEnd,
+                                       AccessSpecifier AS=AS_none,
+                                       AttributeList *AccessAttrs = nullptr);
+  bool ParseTemplateParameters(unsigned Depth,
+                               SmallVectorImpl<Decl*> &TemplateParams,
+                               SourceLocation &LAngleLoc,
+                               SourceLocation &RAngleLoc);
+  bool ParseTemplateParameterList(unsigned Depth,
+                                  SmallVectorImpl<Decl*> &TemplateParams);
+  bool isStartOfTemplateTypeParameter();
+  Decl *ParseTemplateParameter(unsigned Depth, unsigned Position);
+  Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
+  Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
+  Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+  void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                 SourceLocation CorrectLoc,
+                                 bool AlreadyHasEllipsis,
+                                 bool IdentifierHasName);
+  void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                             Declarator &D);
+  // C++ 14.3: Template arguments [temp.arg]
+  typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+
+  bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
+                                      bool ConsumeLastToken);
+  bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
+                                        SourceLocation TemplateNameLoc,
+                                        const CXXScopeSpec &SS,
+                                        bool ConsumeLastToken,
+                                        SourceLocation &LAngleLoc,
+                                        TemplateArgList &TemplateArgs,
+                                        SourceLocation &RAngleLoc);
+
+  bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+                               CXXScopeSpec &SS,
+                               SourceLocation TemplateKWLoc,
+                               UnqualifiedId &TemplateName,
+                               bool AllowTypeAnnotation = true);
+  void AnnotateTemplateIdTokenAsType();
+  bool IsTemplateArgumentList(unsigned Skip = 0);
+  bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+  ParsedTemplateArgument ParseTemplateTemplateArgument();
+  ParsedTemplateArgument ParseTemplateArgument();
+  Decl *ParseExplicitInstantiation(unsigned Context,
+                                   SourceLocation ExternLoc,
+                                   SourceLocation TemplateLoc,
+                                   SourceLocation &DeclEnd,
+                                   AccessSpecifier AS = AS_none);
+
+  //===--------------------------------------------------------------------===//
+  // Modules
+  DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
+
+  //===--------------------------------------------------------------------===//
+  // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
+  ExprResult ParseTypeTrait();
+  
+  //===--------------------------------------------------------------------===//
+  // Embarcadero: Arary and Expression Traits
+  ExprResult ParseArrayTypeTrait();
+  ExprResult ParseExpressionTrait();
+
+  //===--------------------------------------------------------------------===//
+  // Preprocessor code-completion pass-through
+  void CodeCompleteDirective(bool InConditional) override;
+  void CodeCompleteInConditionalExclusion() override;
+  void CodeCompleteMacroName(bool IsDefinition) override;
+  void CodeCompletePreprocessorExpression() override;
+  void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
+                                 unsigned ArgumentIndex) override;
+  void CodeCompleteNaturalLanguage() override;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h
new file mode 100644
index 0000000..a6109bf
--- /dev/null
+++ b/include/clang/Rewrite/Core/DeltaTree.h
@@ -0,0 +1,50 @@
+//===--- DeltaTree.h - B-Tree for Rewrite Delta tracking --------*- 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 DeltaTree class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_REWRITE_DELTATREE_H
+#define CLANG_REWRITE_DELTATREE_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+
+  /// DeltaTree - a multiway search tree (BTree) structure with some fancy
+  /// features.  B-Trees are generally more memory and cache efficient than
+  /// binary trees, because they store multiple keys/values in each node.  This
+  /// implements a key/value mapping from index to delta, and allows fast lookup
+  /// on index.  However, an added (important) bonus is that it can also
+  /// efficiently tell us the full accumulated delta for a specific file offset
+  /// as well, without traversing the whole tree.
+  class DeltaTree {
+    void *Root;    // "DeltaTreeNode *"
+    void operator=(const DeltaTree &) LLVM_DELETED_FUNCTION;
+  public:
+    DeltaTree();
+
+    // Note: Currently we only support copying when the RHS is empty.
+    DeltaTree(const DeltaTree &RHS);
+    ~DeltaTree();
+
+    /// getDeltaAt - Return the accumulated delta at the specified file offset.
+    /// This includes all insertions or delections that occurred *before* the
+    /// specified file index.
+    int getDeltaAt(unsigned FileIndex) const;
+
+    /// AddDelta - When a change is made that shifts around the text buffer,
+    /// this method is used to record that info.  It inserts a delta of 'Delta'
+    /// into the current DeltaTree at offset FileIndex.
+    void AddDelta(unsigned FileIndex, int Delta);
+  };
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
new file mode 100644
index 0000000..ec061dc
--- /dev/null
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -0,0 +1,81 @@
+//==- HTMLRewrite.h - Translate source code into prettified HTML ---*- 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 set of functions used for translating source code
+//  into beautified HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_HTMLREWRITER_H
+#define LLVM_CLANG_HTMLREWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <string>
+
+namespace clang {
+
+class Rewriter;
+class RewriteBuffer;
+class Preprocessor;
+
+namespace html {
+
+  /// HighlightRange - Highlight a range in the source code with the specified
+  /// start/end tags.  B/E must be in the same file.  This ensures that
+  /// start/end tags are placed at the start/end of each line if the range is
+  /// multiline.
+  void HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
+                      const char *StartTag, const char *EndTag);
+
+  /// HighlightRange - Highlight a range in the source code with the specified
+  /// start/end tags.  The Start/end of the range must be in the same file.
+  /// This ensures that start/end tags are placed at the start/end of each line
+  /// if the range is multiline.
+  inline void HighlightRange(Rewriter &R, SourceRange Range,
+                             const char *StartTag, const char *EndTag) {
+    HighlightRange(R, Range.getBegin(), Range.getEnd(), StartTag, EndTag);
+  }
+
+  /// HighlightRange - This is the same as the above method, but takes
+  /// decomposed file locations.
+  void HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
+                      const char *BufferStart,
+                      const char *StartTag, const char *EndTag);
+
+  /// EscapeText - HTMLize a specified file so that special characters are
+  /// are translated so that they are not interpreted as HTML tags.
+  void EscapeText(Rewriter& R, FileID FID,
+                  bool EscapeSpaces = false, bool ReplaceTabs = false);
+
+  /// EscapeText - HTMLized the provided string so that special characters
+  ///  in 's' are not interpreted as HTML tags.  Unlike the version of
+  ///  EscapeText that rewrites a file, this version by default replaces tabs
+  ///  with spaces.
+  std::string EscapeText(StringRef s,
+                         bool EscapeSpaces = false, bool ReplaceTabs = false);
+
+  void AddLineNumbers(Rewriter& R, FileID FID);
+
+  void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
+                                         const char *title = nullptr);
+
+  /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+  /// information about keywords, comments, etc.
+  void SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP);
+
+  /// HighlightMacros - This uses the macro table state from the end of the
+  /// file, to reexpand macros and insert (into the HTML) information about the
+  /// macro expansions.  This won't be perfectly perfect, but it will be
+  /// reasonably close.
+  void HighlightMacros(Rewriter &R, FileID FID, const Preprocessor &PP);
+
+} // end html namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
new file mode 100644
index 0000000..f312aed
--- /dev/null
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -0,0 +1,244 @@
+//===--- RewriteRope.h - Rope specialized for rewriter ----------*- 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 RewriteRope class, which is a powerful string class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITEROPE_H
+#define LLVM_CLANG_REWRITEROPE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+
+namespace clang {
+  //===--------------------------------------------------------------------===//
+  // RopeRefCountString Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopeRefCountString - This struct is allocated with 'new char[]' from the
+  /// heap, and represents a reference counted chunk of string data.  When its
+  /// ref count drops to zero, it is delete[]'d.  This is primarily managed
+  /// through the RopePiece class below.
+  struct RopeRefCountString {
+    unsigned RefCount;
+    char Data[1];  //  Variable sized.
+
+    void addRef() {
+      ++RefCount;
+    }
+
+    void dropRef() {
+      if (--RefCount == 0)
+        delete [] (char*)this;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePiece Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopePiece - This class represents a view into a RopeRefCountString object.
+  /// This allows references to string data to be efficiently chopped up and
+  /// moved around without having to push around the string data itself.
+  ///
+  /// For example, we could have a 1M RopePiece and want to insert something
+  /// into the middle of it.  To do this, we split it into two RopePiece objects
+  /// that both refer to the same underlying RopeRefCountString (just with
+  /// different offsets) which is a nice constant time operation.
+  struct RopePiece {
+    RopeRefCountString *StrData;
+    unsigned StartOffs;
+    unsigned EndOffs;
+
+    RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
+
+    RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
+      : StrData(Str), StartOffs(Start), EndOffs(End) {
+      if (StrData)
+        StrData->addRef();
+    }
+    RopePiece(const RopePiece &RP)
+      : StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
+      if (StrData)
+        StrData->addRef();
+    }
+
+    ~RopePiece() {
+      if (StrData)
+        StrData->dropRef();
+    }
+
+    void operator=(const RopePiece &RHS) {
+      if (StrData != RHS.StrData) {
+        if (StrData)
+          StrData->dropRef();
+        StrData = RHS.StrData;
+        if (StrData)
+          StrData->addRef();
+      }
+      StartOffs = RHS.StartOffs;
+      EndOffs = RHS.EndOffs;
+    }
+
+    const char &operator[](unsigned Offset) const {
+      return StrData->Data[Offset+StartOffs];
+    }
+    char &operator[](unsigned Offset) {
+      return StrData->Data[Offset+StartOffs];
+    }
+
+    unsigned size() const { return EndOffs-StartOffs; }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePieceBTreeIterator Class
+  //===--------------------------------------------------------------------===//
+
+  /// RopePieceBTreeIterator - This class provides read-only forward iteration
+  /// over bytes that are in a RopePieceBTree.  This first iterates over bytes
+  /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
+  /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
+  class RopePieceBTreeIterator :
+      public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
+    /// CurNode - The current B+Tree node that we are inspecting.
+    const void /*RopePieceBTreeLeaf*/ *CurNode;
+    /// CurPiece - The current RopePiece in the B+Tree node that we're
+    /// inspecting.
+    const RopePiece *CurPiece;
+    /// CurChar - The current byte in the RopePiece we are pointing to.
+    unsigned CurChar;
+  public:
+    // begin iterator.
+    RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
+    // end iterator
+    RopePieceBTreeIterator()
+      : CurNode(nullptr), CurPiece(nullptr), CurChar(0) {}
+
+    char operator*() const {
+      return (*CurPiece)[CurChar];
+    }
+
+    bool operator==(const RopePieceBTreeIterator &RHS) const {
+      return CurPiece == RHS.CurPiece && CurChar == RHS.CurChar;
+    }
+    bool operator!=(const RopePieceBTreeIterator &RHS) const {
+      return !operator==(RHS);
+    }
+
+    RopePieceBTreeIterator& operator++() {   // Preincrement
+      if (CurChar+1 < CurPiece->size())
+        ++CurChar;
+      else
+        MoveToNextPiece();
+      return *this;
+    }
+    inline RopePieceBTreeIterator operator++(int) { // Postincrement
+      RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
+    }
+
+    llvm::StringRef piece() const {
+      return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
+    }
+
+    void MoveToNextPiece();
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RopePieceBTree Class
+  //===--------------------------------------------------------------------===//
+
+  class RopePieceBTree {
+    void /*RopePieceBTreeNode*/ *Root;
+    void operator=(const RopePieceBTree &) LLVM_DELETED_FUNCTION;
+  public:
+    RopePieceBTree();
+    RopePieceBTree(const RopePieceBTree &RHS);
+    ~RopePieceBTree();
+
+    typedef RopePieceBTreeIterator iterator;
+    iterator begin() const { return iterator(Root); }
+    iterator end() const { return iterator(); }
+    unsigned size() const;
+    unsigned empty() const { return size() == 0; }
+
+    void clear();
+
+    void insert(unsigned Offset, const RopePiece &R);
+
+    void erase(unsigned Offset, unsigned NumBytes);
+  };
+
+  //===--------------------------------------------------------------------===//
+  // RewriteRope Class
+  //===--------------------------------------------------------------------===//
+
+/// RewriteRope - A powerful string class.  This class supports extremely
+/// efficient insertions and deletions into the middle of it, even for
+/// ridiculously long strings.
+class RewriteRope {
+  RopePieceBTree Chunks;
+
+  /// We allocate space for string data out of a buffer of size AllocChunkSize.
+  /// This keeps track of how much space is left.
+  RopeRefCountString *AllocBuffer;
+  unsigned AllocOffs;
+  enum { AllocChunkSize = 4080 };
+
+public:
+  RewriteRope() :  AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {}
+  RewriteRope(const RewriteRope &RHS)
+    : Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
+  }
+
+  ~RewriteRope() {
+    // If we had an allocation buffer, drop our reference to it.
+    if (AllocBuffer)
+      AllocBuffer->dropRef();
+  }
+
+  typedef RopePieceBTree::iterator iterator;
+  typedef RopePieceBTree::iterator const_iterator;
+  iterator begin() const { return Chunks.begin(); }
+  iterator end() const  { return Chunks.end(); }
+  unsigned size() const { return Chunks.size(); }
+
+  void clear() {
+    Chunks.clear();
+  }
+
+  void assign(const char *Start, const char *End) {
+    clear();
+    if (Start != End)
+      Chunks.insert(0, MakeRopeString(Start, End));
+  }
+
+  void insert(unsigned Offset, const char *Start, const char *End) {
+    assert(Offset <= size() && "Invalid position to insert!");
+    if (Start == End) return;
+    Chunks.insert(Offset, MakeRopeString(Start, End));
+  }
+
+  void erase(unsigned Offset, unsigned NumBytes) {
+    assert(Offset+NumBytes <= size() && "Invalid region to erase!");
+    if (NumBytes == 0) return;
+    Chunks.erase(Offset, NumBytes);
+  }
+
+private:
+  RopePiece MakeRopeString(const char *Start, const char *End);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
new file mode 100644
index 0000000..7b22fb4
--- /dev/null
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -0,0 +1,300 @@
+//===--- Rewriter.h - Code rewriting interface ------------------*- 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 Rewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITER_H
+#define LLVM_CLANG_REWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/Core/DeltaTree.h"
+#include "clang/Rewrite/Core/RewriteRope.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstring>
+#include <map>
+#include <string>
+
+namespace clang {
+  class LangOptions;
+  class Rewriter;
+  class SourceManager;
+  class Stmt;
+
+/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
+/// input with modifications get a new RewriteBuffer associated with them.  The
+/// RewriteBuffer captures the modified text itself as well as information used
+/// to map between SourceLocation's in the original input and offsets in the
+/// RewriteBuffer.  For example, if text is inserted into the buffer, any
+/// locations after the insertion point have to be mapped.
+class RewriteBuffer {
+  friend class Rewriter;
+  /// Deltas - Keep track of all the deltas in the source code due to insertions
+  /// and deletions.
+  DeltaTree Deltas;
+  RewriteRope Buffer;
+public:
+  typedef RewriteRope::const_iterator iterator;
+  iterator begin() const { return Buffer.begin(); }
+  iterator end() const { return Buffer.end(); }
+  unsigned size() const { return Buffer.size(); }
+
+  /// \brief Write to \p Stream the result of applying all changes to the
+  /// original buffer.
+  /// Note that it isn't safe to use this function to overwrite memory mapped
+  /// files in-place (PR17960). Consider using a higher-level utility such as
+  /// Rewriter::overwriteChangedFiles() instead.
+  ///
+  /// The original buffer is not actually changed.
+  raw_ostream &write(raw_ostream &Stream) const;
+
+  /// RemoveText - Remove the specified text.
+  void RemoveText(unsigned OrigOffset, unsigned Size,
+                  bool removeLineIfEmpty = false);
+
+  /// InsertText - Insert some text at the specified point, where the offset in
+  /// the buffer is specified relative to the original SourceBuffer.  The
+  /// text is inserted after the specified location.
+  ///
+  void InsertText(unsigned OrigOffset, StringRef Str,
+                  bool InsertAfter = true);
+
+
+  /// InsertTextBefore - Insert some text before the specified point, where the
+  /// offset in the buffer is specified relative to the original
+  /// SourceBuffer. The text is inserted before the specified location.  This is
+  /// method is the same as InsertText with "InsertAfter == false".
+  void InsertTextBefore(unsigned OrigOffset, StringRef Str) {
+    InsertText(OrigOffset, Str, false);
+  }
+
+  /// InsertTextAfter - Insert some text at the specified point, where the
+  /// offset in the buffer is specified relative to the original SourceBuffer.
+  /// The text is inserted after the specified location.
+  void InsertTextAfter(unsigned OrigOffset, StringRef Str) {
+    InsertText(OrigOffset, Str);
+  }
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                   StringRef NewStr);
+
+private:  // Methods only usable by Rewriter.
+
+  /// Initialize - Start this rewrite buffer out with a copy of the unmodified
+  /// input buffer.
+  void Initialize(const char *BufStart, const char *BufEnd) {
+    Buffer.assign(BufStart, BufEnd);
+  }
+
+  /// getMappedOffset - Given an offset into the original SourceBuffer that this
+  /// RewriteBuffer is based on, map it into the offset space of the
+  /// RewriteBuffer.  If AfterInserts is true and if the OrigOffset indicates a
+  /// position where text is inserted, the location returned will be after any
+  /// inserted text at the position.
+  unsigned getMappedOffset(unsigned OrigOffset,
+                           bool AfterInserts = false) const{
+    return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
+  }
+
+  /// AddInsertDelta - When an insertion is made at a position, this
+  /// method is used to record that information.
+  void AddInsertDelta(unsigned OrigOffset, int Change) {
+    return Deltas.AddDelta(2*OrigOffset, Change);
+  }
+
+  /// AddReplaceDelta - When a replacement/deletion is made at a position, this
+  /// method is used to record that information.
+  void AddReplaceDelta(unsigned OrigOffset, int Change) {
+    return Deltas.AddDelta(2*OrigOffset+1, Change);
+  }
+};
+
+
+/// Rewriter - This is the main interface to the rewrite buffers.  Its primary
+/// job is to dispatch high-level requests to the low-level RewriteBuffers that
+/// are involved.
+class Rewriter {
+  SourceManager *SourceMgr;
+  const LangOptions *LangOpts;
+  std::map<FileID, RewriteBuffer> RewriteBuffers;
+public:
+  struct RewriteOptions {
+    /// \brief Given a source range, true to include previous inserts at the
+    /// beginning of the range as part of the range itself (true by default).
+    bool IncludeInsertsAtBeginOfRange;
+    /// \brief Given a source range, true to include previous inserts at the
+    /// end of the range as part of the range itself (true by default).
+    bool IncludeInsertsAtEndOfRange;
+    /// \brief If true and removing some text leaves a blank line
+    /// also remove the empty line (false by default).
+    bool RemoveLineIfEmpty;
+
+    RewriteOptions()
+      : IncludeInsertsAtBeginOfRange(true),
+        IncludeInsertsAtEndOfRange(true),
+        RemoveLineIfEmpty(false) { }
+  };
+
+  typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
+  typedef std::map<FileID, RewriteBuffer>::const_iterator const_buffer_iterator;
+
+  explicit Rewriter(SourceManager &SM, const LangOptions &LO)
+    : SourceMgr(&SM), LangOpts(&LO) {}
+  explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
+
+  void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
+    SourceMgr = &SM;
+    LangOpts = &LO;
+  }
+  SourceManager &getSourceMgr() const { return *SourceMgr; }
+  const LangOptions &getLangOpts() const { return *LangOpts; }
+
+  /// isRewritable - Return true if this location is a raw file location, which
+  /// is rewritable.  Locations from macros, etc are not rewritable.
+  static bool isRewritable(SourceLocation Loc) {
+    return Loc.isFileID();
+  }
+
+  /// getRangeSize - Return the size in bytes of the specified range if they
+  /// are in the same file.  If not, this returns -1.
+  int getRangeSize(SourceRange Range,
+                   RewriteOptions opts = RewriteOptions()) const;
+  int getRangeSize(const CharSourceRange &Range,
+                   RewriteOptions opts = RewriteOptions()) const;
+
+  /// getRewrittenText - Return the rewritten form of the text in the specified
+  /// range.  If the start or end of the range was unrewritable or if they are
+  /// in different buffers, this returns an empty string.
+  ///
+  /// Note that this method is not particularly efficient.
+  ///
+  std::string getRewrittenText(SourceRange Range) const;
+
+  /// InsertText - Insert the specified string at the specified location in the
+  /// original buffer.  This method returns true (and does nothing) if the input
+  /// location was not rewritable, false otherwise.
+  ///
+  /// \param indentNewLines if true new lines in the string are indented
+  /// using the indentation of the source line in position \p Loc.
+  bool InsertText(SourceLocation Loc, StringRef Str,
+                  bool InsertAfter = true, bool indentNewLines = false);
+
+  /// InsertTextAfter - Insert the specified string at the specified location in
+  ///  the original buffer.  This method returns true (and does nothing) if
+  ///  the input location was not rewritable, false otherwise.  Text is
+  ///  inserted after any other text that has been previously inserted
+  ///  at the some point (the default behavior for InsertText).
+  bool InsertTextAfter(SourceLocation Loc, StringRef Str) {
+    return InsertText(Loc, Str);
+  }
+
+  /// \brief Insert the specified string after the token in the
+  /// specified location.
+  bool InsertTextAfterToken(SourceLocation Loc, StringRef Str);
+
+  /// InsertText - Insert the specified string at the specified location in the
+  /// original buffer.  This method returns true (and does nothing) if the input
+  /// location was not rewritable, false otherwise.  Text is
+  /// inserted before any other text that has been previously inserted
+  /// at the some point.
+  bool InsertTextBefore(SourceLocation Loc, StringRef Str) {
+    return InsertText(Loc, Str, false);
+  }
+
+  /// RemoveText - Remove the specified text region.
+  bool RemoveText(SourceLocation Start, unsigned Length,
+                  RewriteOptions opts = RewriteOptions());
+
+  /// \brief Remove the specified text region.
+  bool RemoveText(CharSourceRange range,
+                  RewriteOptions opts = RewriteOptions()) {
+    return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
+  }
+
+  /// \brief Remove the specified text region.
+  bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) {
+    return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
+  }
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  bool ReplaceText(SourceLocation Start, unsigned OrigLength,
+                   StringRef NewStr);
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  bool ReplaceText(SourceRange range, StringRef NewStr) {
+    return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
+  }
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  bool ReplaceText(SourceRange range, SourceRange replacementRange);
+
+  /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
+  /// printer to generate the replacement code.  This returns true if the input
+  /// could not be rewritten, or false if successful.
+  bool ReplaceStmt(Stmt *From, Stmt *To);
+
+  /// \brief Increase indentation for the lines between the given source range.
+  /// To determine what the indentation should be, 'parentIndent' is used
+  /// that should be at a source location with an indentation one degree
+  /// lower than the given range.
+  bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent);
+  bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) {
+    return IncreaseIndentation(CharSourceRange::getTokenRange(range),
+                               parentIndent);
+  }
+
+  /// ConvertToString converts statement 'From' to a string using the
+  /// pretty printer.
+  std::string ConvertToString(Stmt *From);
+
+  /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
+  /// buffer, and allows you to write on it directly.  This is useful if you
+  /// want efficient low-level access to apis for scribbling on one specific
+  /// FileID's buffer.
+  RewriteBuffer &getEditBuffer(FileID FID);
+
+  /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
+  /// If no modification has been made to it, return null.
+  const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
+    std::map<FileID, RewriteBuffer>::const_iterator I =
+      RewriteBuffers.find(FID);
+    return I == RewriteBuffers.end() ? nullptr : &I->second;
+  }
+
+  // Iterators over rewrite buffers.
+  buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
+  buffer_iterator buffer_end() { return RewriteBuffers.end(); }
+  const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); }
+  const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); }
+
+  /// overwriteChangedFiles - Save all changed files to disk.
+  ///
+  /// Returns true if any files were not saved successfully.
+  /// Outputs diagnostics via the source manager's diagnostic engine
+  /// in case of an error.
+  bool overwriteChangedFiles();
+
+private:
+  unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
new file mode 100644
index 0000000..c313b45
--- /dev/null
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -0,0 +1,79 @@
+//===--- TokenRewriter.h - Token-based Rewriter -----------------*- 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 TokenRewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENREWRITER_H
+#define LLVM_CLANG_TOKENREWRITER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Token.h"
+#include <list>
+#include <map>
+#include <memory>
+
+namespace clang {
+  class LangOptions;
+  class ScratchBuffer;
+
+  class TokenRewriter {
+    /// TokenList - This is the list of raw tokens that make up this file.  Each
+    /// of these tokens has a unique SourceLocation, which is a FileID.
+    std::list<Token> TokenList;
+
+    /// TokenRefTy - This is the type used to refer to a token in the TokenList.
+    typedef std::list<Token>::iterator TokenRefTy;
+
+    /// TokenAtLoc - This map indicates which token exists at a specific
+    /// SourceLocation.  Since each token has a unique SourceLocation, this is a
+    /// one to one map.  The token can return its own location directly, to map
+    /// backwards.
+    std::map<SourceLocation, TokenRefTy> TokenAtLoc;
+
+    /// ScratchBuf - This is the buffer that we create scratch tokens from.
+    ///
+    std::unique_ptr<ScratchBuffer> ScratchBuf;
+
+    TokenRewriter(const TokenRewriter &) LLVM_DELETED_FUNCTION;
+    void operator=(const TokenRewriter &) LLVM_DELETED_FUNCTION;
+  public:
+    /// TokenRewriter - This creates a TokenRewriter for the file with the
+    /// specified FileID.
+    TokenRewriter(FileID FID, SourceManager &SM, const LangOptions &LO);
+    ~TokenRewriter();
+
+    typedef std::list<Token>::const_iterator token_iterator;
+    token_iterator token_begin() const { return TokenList.begin(); }
+    token_iterator token_end() const { return TokenList.end(); }
+
+
+    token_iterator AddTokenBefore(token_iterator I, const char *Val);
+    token_iterator AddTokenAfter(token_iterator I, const char *Val) {
+      assert(I != token_end() && "Cannot insert after token_end()!");
+      return AddTokenBefore(++I, Val);
+    }
+
+  private:
+    /// RemapIterator - Convert from token_iterator (a const iterator) to
+    /// TokenRefTy (a non-const iterator).
+    TokenRefTy RemapIterator(token_iterator I);
+
+    /// AddToken - Add the specified token into the Rewriter before the other
+    /// position.
+    TokenRefTy AddToken(const Token &T, TokenRefTy Where);
+  };
+
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h
new file mode 100644
index 0000000..584af3f
--- /dev/null
+++ b/include/clang/Rewrite/Frontend/ASTConsumers.h
@@ -0,0 +1,49 @@
+//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef REWRITE_ASTCONSUMERS_H
+#define REWRITE_ASTCONSUMERS_H
+
+#include "clang/Basic/LLVM.h"
+#include <string>
+
+namespace clang {
+
+class ASTConsumer;
+class DiagnosticsEngine;
+class LangOptions;
+class Preprocessor;
+
+// ObjC rewriter: attempts to rewrite ObjC constructs into pure C code.
+// This is considered experimental, and only works with Apple's ObjC runtime.
+ASTConsumer *CreateObjCRewriter(const std::string &InFile,
+                                raw_ostream *OS,
+                                DiagnosticsEngine &Diags,
+                                const LangOptions &LOpts,
+                                bool SilenceRewriteMacroWarning);
+ASTConsumer *CreateModernObjCRewriter(const std::string &InFile,
+                                raw_ostream *OS,
+                                DiagnosticsEngine &Diags,
+                                const LangOptions &LOpts,
+                                bool SilenceRewriteMacroWarning,
+                                bool LineInfo);
+
+/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
+/// HTML with syntax highlighting suitable for viewing in a web-browser.
+ASTConsumer *CreateHTMLPrinter(raw_ostream *OS, Preprocessor &PP,
+                               bool SyntaxHighlight = true,
+                               bool HighlightMacros = true);
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
new file mode 100644
index 0000000..3ad8f40
--- /dev/null
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -0,0 +1,128 @@
+//===--- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a diagnostic client adaptor that performs rewrites as
+// suggested by code modification hints attached to diagnostics. It
+// then forwards any diagnostics to the adapted diagnostic client.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
+#define LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Edit/EditedSource.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+
+namespace clang {
+
+class SourceManager;
+class FileEntry;
+
+class FixItOptions {
+public:
+  FixItOptions() : FixWhatYouCan(false),
+                   FixOnlyWarnings(false), Silent(false) { }
+
+  virtual ~FixItOptions();
+
+  /// \brief This file is about to be rewritten. Return the name of the file
+  /// that is okay to write to.
+  ///
+  /// \param fd out parameter for file descriptor. After the call it may be set
+  /// to an open file descriptor for the returned filename, or it will be -1
+  /// otherwise.
+  ///
+  virtual std::string RewriteFilename(const std::string &Filename, int &fd) = 0;
+
+  /// \brief Whether to abort fixing a file when not all errors could be fixed.
+  bool FixWhatYouCan;
+
+  /// \brief Whether to only fix warnings and not errors.
+  bool FixOnlyWarnings;
+
+  /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
+  /// if it is an error or a fixit was applied as part of the diagnostic.
+  /// It basically silences warnings without accompanying fixits.
+  bool Silent;
+};
+
+class FixItRewriter : public DiagnosticConsumer {
+  /// \brief The diagnostics machinery.
+  DiagnosticsEngine &Diags;
+
+  edit::EditedSource Editor;
+
+  /// \brief The rewriter used to perform the various code
+  /// modifications.
+  Rewriter Rewrite;
+
+  /// \brief The diagnostic client that performs the actual formatting
+  /// of error messages.
+  DiagnosticConsumer *Client;
+  bool OwnsClient;
+
+  /// \brief Turn an input path into an output path. NULL implies overwriting
+  /// the original.
+  FixItOptions *FixItOpts;
+
+  /// \brief The number of rewriter failures.
+  unsigned NumFailures;
+
+  /// \brief Whether the previous diagnostic was not passed to the consumer.
+  bool PrevDiagSilenced;
+
+public:
+  typedef Rewriter::buffer_iterator iterator;
+
+  /// \brief Initialize a new fix-it rewriter.
+  FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
+                const LangOptions &LangOpts, FixItOptions *FixItOpts);
+
+  /// \brief Destroy the fix-it rewriter.
+  ~FixItRewriter();
+
+  /// \brief Check whether there are modifications for a given file.
+  bool IsModified(FileID ID) const {
+    return Rewrite.getRewriteBufferFor(ID) != nullptr;
+  }
+
+  // Iteration over files with changes.
+  iterator buffer_begin() { return Rewrite.buffer_begin(); }
+  iterator buffer_end() { return Rewrite.buffer_end(); }
+
+  /// \brief Write a single modified source file.
+  ///
+  /// \returns true if there was an error, false otherwise.
+  bool WriteFixedFile(FileID ID, raw_ostream &OS);
+
+  /// \brief Write the modified source files.
+  ///
+  /// \returns true if there was an error, false otherwise.
+  bool WriteFixedFiles(
+     std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
+
+  /// IncludeInDiagnosticCounts - This method (whose default implementation
+  /// returns true) indicates whether the diagnostics handled by this
+  /// DiagnosticConsumer should be included in the number of diagnostics
+  /// reported by DiagnosticsEngine.
+  bool IncludeInDiagnosticCounts() const override;
+
+  /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+  /// capturing it to a log as needed.
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+
+  /// \brief Emit a diagnostic via the adapted diagnostic client.
+  void Diag(SourceLocation Loc, unsigned DiagID);
+};
+
+}
+
+#endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
new file mode 100644
index 0000000..fc79270
--- /dev/null
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -0,0 +1,83 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+#define LLVM_CLANG_REWRITE_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+class FixItRewriter;
+class FixItOptions;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class HTMLPrintAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class FixItAction : public ASTFrontendAction {
+protected:
+  std::unique_ptr<FixItRewriter> Rewriter;
+  std::unique_ptr<FixItOptions> FixItOpts;
+
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  bool BeginSourceFileAction(CompilerInstance &CI,
+                             StringRef Filename) override;
+
+  void EndSourceFileAction() override;
+
+  bool hasASTFileSupport() const override { return false; }
+
+public:
+  FixItAction();
+  ~FixItAction();
+};
+
+/// \brief Emits changes to temporary files and uses them for the original
+/// frontend action.
+class FixItRecompile : public WrapperFrontendAction {
+public:
+  FixItRecompile(FrontendAction *WrappedAction)
+    : WrapperFrontendAction(WrappedAction) {}
+
+protected:
+  bool BeginInvocation(CompilerInstance &CI) override;
+};
+
+class RewriteObjCAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+class RewriteMacrosAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class RewriteTestAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+class RewriteIncludesAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction() override;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Rewrite/Frontend/Rewriters.h b/include/clang/Rewrite/Frontend/Rewriters.h
new file mode 100644
index 0000000..f5ade5a
--- /dev/null
+++ b/include/clang/Rewrite/Frontend/Rewriters.h
@@ -0,0 +1,35 @@
+//===--- Rewriters.h - Rewriter implementations     -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header contains miscellaneous utilities for various front-end actions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_REWRITE_REWRITERS_H
+#define LLVM_CLANG_REWRITE_REWRITERS_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+class Preprocessor;
+class PreprocessorOutputOptions;
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);
+
+/// DoRewriteTest - A simple test for the TokenRewriter class.
+void DoRewriteTest(Preprocessor &PP, raw_ostream *OS);
+
+/// RewriteIncludesInInput - Implement -frewrite-includes mode.
+void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                            const PreprocessorOutputOptions &Opts);
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
new file mode 100644
index 0000000..432c4e2
--- /dev/null
+++ b/include/clang/Sema/AnalysisBasedWarnings.h
@@ -0,0 +1,103 @@
+//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- 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 AnalysisBasedWarnings, a worker object used by Sema
+// that issues warnings based on dataflow-analysis.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
+#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+
+class BlockExpr;
+class Decl;
+class FunctionDecl;
+class ObjCMethodDecl;
+class QualType;
+class Sema;
+namespace sema {
+  class FunctionScopeInfo;
+}
+
+namespace sema {
+
+class AnalysisBasedWarnings {
+public:
+  class Policy {
+    friend class AnalysisBasedWarnings;
+    // The warnings to run.
+    unsigned enableCheckFallThrough : 1;
+    unsigned enableCheckUnreachable : 1;
+    unsigned enableThreadSafetyAnalysis : 1;
+    unsigned enableConsumedAnalysis : 1;
+  public:
+    Policy();
+    void disableCheckFallThrough() { enableCheckFallThrough = 0; }
+  };
+
+private:
+  Sema &S;
+  Policy DefaultPolicy;
+
+  enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
+  llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
+
+  /// \name Statistics
+  /// @{
+
+  /// \brief Number of function CFGs built and analyzed.
+  unsigned NumFunctionsAnalyzed;
+
+  /// \brief Number of functions for which the CFG could not be successfully
+  /// built.
+  unsigned NumFunctionsWithBadCFGs;
+
+  /// \brief Total number of blocks across all CFGs.
+  unsigned NumCFGBlocks;
+
+  /// \brief Largest number of CFG blocks for a single function analyzed.
+  unsigned MaxCFGBlocksPerFunction;
+
+  /// \brief Total number of CFGs with variables analyzed for uninitialized
+  /// uses.
+  unsigned NumUninitAnalysisFunctions;
+
+  /// \brief Total number of variables analyzed for uninitialized uses.
+  unsigned NumUninitAnalysisVariables;
+
+  /// \brief Max number of variables analyzed for uninitialized uses in a single
+  /// function.
+  unsigned MaxUninitAnalysisVariablesPerFunction;
+
+  /// \brief Total number of block visits during uninitialized use analysis.
+  unsigned NumUninitAnalysisBlockVisits;
+
+  /// \brief Max number of block visits during uninitialized use analysis of
+  /// a single function.
+  unsigned MaxUninitAnalysisBlockVisitsPerFunction;
+
+  /// @}
+
+public:
+  AnalysisBasedWarnings(Sema &s);
+
+  void IssueWarnings(Policy P, FunctionScopeInfo *fscope,
+                     const Decl *D, const BlockExpr *blkExpr);
+
+  Policy getDefaultPolicy() { return DefaultPolicy; }
+
+  void PrintStats() const;
+};
+
+}} // end namespace clang::sema
+
+#endif
diff --git a/include/clang/Sema/AttrParsedAttrImpl.inc b/include/clang/Sema/AttrParsedAttrImpl.inc
new file mode 100644
index 0000000..f022eb6
--- /dev/null
+++ b/include/clang/Sema/AttrParsedAttrImpl.inc
@@ -0,0 +1,1524 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Parsed attribute helpers                                                    *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+static bool defaultAppertainsTo(Sema &, const AttributeList &,const Decl *) {
+  return true;
+}
+
+static bool defaultDiagnoseLangOpts(Sema &, const AttributeList &) {
+  return true;
+}
+
+static bool defaultTargetRequirements(const llvm::Triple &) {
+  return true;
+}
+
+static unsigned defaultSpellingIndexToSemanticSpelling(const AttributeList &Attr) {
+  return UINT_MAX;
+}
+
+static bool isTargetarmthumbmsp430(const llvm::Triple &T) {
+  llvm::Triple::ArchType Arch = T.getArch();
+  return (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb || Arch == llvm::Triple::msp430);
+}
+
+static bool checkAcquireCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned AcquireCapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_acquire_capability,
+    CXX11_clang_acquire_capability,
+    GNU_acquire_shared_capability,
+    CXX11_clang_acquire_shared_capability,
+    GNU_exclusive_lock_function,
+    GNU_shared_lock_function
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_acquire_capability;
+    case 1: return CXX11_clang_acquire_capability;
+    case 2: return GNU_acquire_shared_capability;
+    case 3: return CXX11_clang_acquire_shared_capability;
+    case 4: return GNU_exclusive_lock_function;
+    case 5: return GNU_shared_lock_function;
+  }
+}
+
+static bool isSharedVar(const Decl *D) {
+  if (const VarDecl *S = dyn_cast<VarDecl>(D))
+    return S->hasGlobalStorage() && !S->getTLSKind();
+  return false;
+}
+
+static bool checkAcquiredAfterAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkAcquiredBeforeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static unsigned AlignedAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_aligned,
+    CXX11_gnu_aligned,
+    Declspec_align,
+    Keyword_alignas,
+    Keyword_Alignas
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_aligned;
+    case 1: return CXX11_gnu_aligned;
+    case 2: return Declspec_align;
+    case 3: return Keyword_alignas;
+    case 4: return Keyword_Alignas;
+  }
+}
+
+static bool checkAlwaysInlineAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned AlwaysInlineAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_always_inline,
+    CXX11_gnu_always_inline,
+    Keyword_forceinline
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_always_inline;
+    case 1: return CXX11_gnu_always_inline;
+    case 2: return Keyword_forceinline;
+  }
+}
+
+static bool checkArcWeakrefUnavailableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCInterface;
+    return false;
+  }
+  return true;
+}
+
+static unsigned ArgumentWithTypeTagAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_argument_with_type_tag,
+    GNU_pointer_with_type_tag
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_argument_with_type_tag;
+    case 1: return GNU_pointer_with_type_tag;
+  }
+}
+
+static bool checkAssertCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned AssertCapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_assert_capability,
+    CXX11_clang_assert_capability,
+    GNU_assert_shared_capability,
+    CXX11_clang_assert_shared_capability
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_assert_capability;
+    case 1: return CXX11_clang_assert_capability;
+    case 2: return GNU_assert_shared_capability;
+    case 3: return CXX11_clang_assert_shared_capability;
+  }
+}
+
+static bool checkAssertExclusiveLockAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkAssertSharedLockAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCFAuditedTransferAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCFConsumedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCFUnknownTransferAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCUDAConstantAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCUDALangOpts(Sema &S, const AttributeList &Attr) {
+  if (S.LangOpts.CUDA)
+    return true;
+
+  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+  return false;
+}
+
+static bool checkCUDADeviceAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariableOrFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCUDAGlobalAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCUDAHostAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isFunctionLike(const Decl *D) {
+  if (const Decl *S = dyn_cast<Decl>(D))
+    return S->getFunctionType(false) != NULL;
+  return false;
+}
+
+static bool checkCUDALaunchBoundsAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isFunctionLike(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionOrMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCUDASharedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCXX11NoReturnAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCallableWhenAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool isStruct(const Decl *D) {
+  if (const RecordDecl *S = dyn_cast<RecordDecl>(D))
+    return !S->isUnion();
+  return false;
+}
+
+static bool checkCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isStruct(D) && !isa<TypedefNameDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedStructOrTypedef;
+    return false;
+  }
+  return true;
+}
+
+static unsigned CapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_capability,
+    CXX11_clang_capability,
+    GNU_shared_capability,
+    CXX11_clang_shared_capability
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_capability;
+    case 1: return CXX11_clang_capability;
+    case 2: return GNU_shared_capability;
+    case 3: return CXX11_clang_shared_capability;
+  }
+}
+
+static bool checkCarriesDependencyAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ParmVarDecl>(D) && !isa<ObjCMethodDecl>(D) && !isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionMethodOrParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCleanupAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkColdAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkCommonAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkConstructorAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkConsumableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedClass;
+    return false;
+  }
+  return true;
+}
+
+static bool checkConsumableAutoCastAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedClass;
+    return false;
+  }
+  return true;
+}
+
+static bool checkConsumableSetOnReadAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedClass;
+    return false;
+  }
+  return true;
+}
+
+static bool checkDLLExportAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D) && !isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : ExpectedVariableOrFunction);
+    return false;
+  }
+  return true;
+}
+
+static bool isTargetx86x86_64armthumbWin32(const llvm::Triple &T) {
+  llvm::Triple::ArchType Arch = T.getArch();
+  llvm::Triple::OSType OS = T.getOS();
+  return (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) && (OS == llvm::Triple::Win32);
+}
+
+static bool checkDLLImportAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D) && !isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : ExpectedVariableOrFunction);
+    return false;
+  }
+  return true;
+}
+
+static bool checkDestructorAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkEnableIfAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkExclusiveTrylockFunctionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkExtVectorTypeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<TypedefNameDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedType;
+    return false;
+  }
+  return true;
+}
+
+static bool checkFlattenAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isHasFunctionProto(const Decl *D) {
+  if (const Decl *S = dyn_cast<Decl>(D))
+    return (S->getFunctionType(true) != NULL &&
+                              isa<FunctionProtoType>(S->getFunctionType())) ||
+                                       isa<ObjCMethodDecl>(S) ||
+                                       isa<BlockDecl>(S);
+  return false;
+}
+
+static bool checkFormatAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isa<BlockDecl>(D) && !isHasFunctionProto(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkFormatArgAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isHasFunctionProto(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkGNUInlineAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkGuardedByAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkGuardedVarAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkHotAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isObjCInstanceMethod(const Decl *D) {
+  if (const ObjCMethodDecl *S = dyn_cast<ObjCMethodDecl>(D))
+    return S->isInstanceMethod();
+  return false;
+}
+
+static bool checkIBActionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isObjCInstanceMethod(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjCInstanceMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkInitPriorityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkLockReturnedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkLockableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool checkLocksExcludedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned LoopHintAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    Pragma_clang_loop,
+    Pragma_unroll
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Pragma_clang_loop;
+    case 1: return Pragma_unroll;
+  }
+}
+
+static bool checkMicrosoftExtLangOpts(Sema &S, const AttributeList &Attr) {
+  if (S.LangOpts.MicrosoftExt)
+    return true;
+
+  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+  return false;
+}
+
+static unsigned MSInheritanceAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    Keyword_single_inheritance,
+    Keyword_multiple_inheritance,
+    Keyword_virtual_inheritance,
+    Keyword_unspecified_inheritance
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Keyword_single_inheritance;
+    case 1: return Keyword_multiple_inheritance;
+    case 2: return Keyword_virtual_inheritance;
+    case 3: return Keyword_unspecified_inheritance;
+  }
+}
+
+static bool checkMinSizeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionOrMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkMips16AppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isTargetmipsmipsel(const llvm::Triple &T) {
+  llvm::Triple::ArchType Arch = T.getArch();
+  return (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel);
+}
+
+static bool checkMsStructAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool checkNSConsumedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNSConsumesSelfAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNakedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoCommonAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoDuplicateAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoInlineAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoInstrumentFunctionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoMips16AppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoSanitizeAddressAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned NoSanitizeAddressAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_no_address_safety_analysis,
+    CXX11_gnu_no_address_safety_analysis,
+    GNU_no_sanitize_address,
+    CXX11_gnu_no_sanitize_address
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_no_address_safety_analysis;
+    case 1: return CXX11_gnu_no_address_safety_analysis;
+    case 2: return GNU_no_sanitize_address;
+    case 3: return CXX11_gnu_no_sanitize_address;
+  }
+}
+
+static bool checkNoSanitizeMemoryAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoSanitizeThreadAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoSplitStackAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNoThreadSafetyAnalysisAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkNonNullAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isHasFunctionProto(D) && !isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionMethodOrParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCBridgeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCBridgeMutableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCBridgeRelatedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool isObjCInterfaceDeclInitMethod(const Decl *D) {
+  if (const ObjCMethodDecl *S = dyn_cast<ObjCMethodDecl>(D))
+    return S->getMethodFamily() == OMF_init &&
+                                 (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
+                                  (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
+            cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()));
+  return false;
+}
+
+static bool checkObjCDesignatedInitializerAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isObjCInterfaceDeclInitMethod(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjCInterfaceDeclInitMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCExceptionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCInterface;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCExplicitProtocolImplAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCProtocolDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCProtocol;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCMethodFamilyAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCPreciseLifetimeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCRequiresPropertyDefsAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCInterface;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCRequiresSuperAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCReturnsInnerPointerAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isa<ObjCPropertyDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethodOrProperty;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCRootClassAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCInterface;
+    return false;
+  }
+  return true;
+}
+
+static bool checkObjCRuntimeNameAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCInterfaceDecl>(D) && !isa<ObjCProtocolDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedObjectiveCInterfaceOrProtocol;
+    return false;
+  }
+  return true;
+}
+
+static bool checkOpenCLImageAccessAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedParameter;
+    return false;
+  }
+  return true;
+}
+
+static unsigned OpenCLImageAccessAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    Keyword_read_only,
+    Keyword_write_only,
+    Keyword_read_write
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return Keyword_read_only;
+    case 1: return Keyword_read_only;
+    case 2: return Keyword_write_only;
+    case 3: return Keyword_write_only;
+    case 4: return Keyword_read_write;
+    case 5: return Keyword_read_write;
+  }
+}
+
+static bool checkOpenCLKernelAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkOptimizeNoneAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionOrMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkOverloadableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkOwnershipAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isHasFunctionProto(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned OwnershipAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_ownership_holds,
+    GNU_ownership_returns,
+    GNU_ownership_takes
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_ownership_holds;
+    case 1: return GNU_ownership_returns;
+    case 2: return GNU_ownership_takes;
+  }
+}
+
+static bool checkParamTypestateAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkPtGuardedByAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkPtGuardedVarAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FieldDecl>(D) && !isSharedVar(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFieldOrGlobalVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkReleaseCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned ReleaseCapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_release_capability,
+    CXX11_clang_release_capability,
+    GNU_release_shared_capability,
+    CXX11_clang_release_shared_capability,
+    GNU_release_generic_capability,
+    CXX11_clang_release_generic_capability,
+    GNU_unlock_function
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_release_capability;
+    case 1: return CXX11_clang_release_capability;
+    case 2: return GNU_release_shared_capability;
+    case 3: return CXX11_clang_release_shared_capability;
+    case 4: return GNU_release_generic_capability;
+    case 5: return CXX11_clang_release_generic_capability;
+    case 6: return GNU_unlock_function;
+  }
+}
+
+static bool checkReqdWorkGroupSizeAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkRequiresCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned RequiresCapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_requires_capability,
+    CXX11_clang_requires_capability,
+    GNU_exclusive_locks_required,
+    GNU_requires_shared_capability,
+    CXX11_clang_requires_shared_capability,
+    GNU_shared_locks_required
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_requires_capability;
+    case 1: return CXX11_clang_requires_capability;
+    case 2: return GNU_exclusive_locks_required;
+    case 3: return GNU_requires_shared_capability;
+    case 4: return CXX11_clang_requires_shared_capability;
+    case 5: return GNU_shared_locks_required;
+  }
+}
+
+static bool checkReturnTypestateAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isa<ParmVarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionMethodOrParameter;
+    return false;
+  }
+  return true;
+}
+
+static bool checkReturnsNonNullAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionOrMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkReturnsTwiceAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkScopedLockableAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool isGlobalVar(const Decl *D) {
+  if (const VarDecl *S = dyn_cast<VarDecl>(D))
+    return S->hasGlobalStorage();
+  return false;
+}
+
+static bool checkSectionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D) && !isGlobalVar(D) && !isa<ObjCMethodDecl>(D) && !isa<ObjCPropertyDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionGlobalVarMethodOrProperty;
+    return false;
+  }
+  return true;
+}
+
+static unsigned SectionAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_section,
+    CXX11_gnu_section,
+    Declspec_allocate
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_section;
+    case 1: return CXX11_gnu_section;
+    case 2: return Declspec_allocate;
+  }
+}
+
+static bool checkSetTypestateAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkSharedTrylockFunctionAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isTLSVar(const Decl *D) {
+  if (const VarDecl *S = dyn_cast<VarDecl>(D))
+    return S->getTLSKind() != 0;
+  return false;
+}
+
+static bool checkTLSModelAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isTLSVar(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedTLSVar;
+    return false;
+  }
+  return true;
+}
+
+static bool checkTestTypestateAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXMethodDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedMethod;
+    return false;
+  }
+  return true;
+}
+
+static bool checkThreadAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return false;
+  }
+  return true;
+}
+
+static bool checkTryAcquireCapabilityAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static unsigned TryAcquireCapabilityAttrSpellingMap(const AttributeList &Attr) {
+  enum Spelling {
+    GNU_try_acquire_capability,
+    CXX11_clang_try_acquire_capability,
+    GNU_try_acquire_shared_capability,
+    CXX11_clang_try_acquire_shared_capability
+  };
+
+  unsigned Idx = Attr.getAttributeSpellingListIndex();
+  switch (Idx) {
+    default: llvm_unreachable("Unknown spelling list index");
+    case 0: return GNU_try_acquire_capability;
+    case 1: return CXX11_clang_try_acquire_capability;
+    case 2: return GNU_try_acquire_shared_capability;
+    case 3: return CXX11_clang_try_acquire_shared_capability;
+  }
+}
+
+static bool checkUnusedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D) && !isa<ObjCMethodDecl>(D) && !isFunctionLike(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariableFunctionOrLabel;
+    return false;
+  }
+  return true;
+}
+
+static bool checkMicrosoftExtBorlandLangOpts(Sema &S, const AttributeList &Attr) {
+  if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland)
+    return true;
+
+  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+  return false;
+}
+
+static bool checkVecReturnAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedClass;
+    return false;
+  }
+  return true;
+}
+
+static bool checkVecTypeHintAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkWarnUnusedAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<RecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : ExpectedStructOrUnion);
+    return false;
+  }
+  return true;
+}
+
+static bool checkWarnUnusedResultAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D) && !isFunctionLike(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionMethodOrClass;
+    return false;
+  }
+  return true;
+}
+
+static bool checkWeakAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D) && !isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << (S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : ExpectedVariableOrFunction);
+    return false;
+  }
+  return true;
+}
+
+static bool checkWeakRefAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariableOrFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool checkWorkGroupSizeHintAppertainsTo(Sema &S, const AttributeList &Attr, const Decl *D) {
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunction;
+    return false;
+  }
+  return true;
+}
+
+static bool isTargetx86(const llvm::Triple &T) {
+  llvm::Triple::ArchType Arch = T.getArch();
+  return (Arch == llvm::Triple::x86);
+}
+
+static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {
+  { 0, 1, 1, 1, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, isTargetarmthumbmsp430, defaultSpellingIndexToSemanticSpelling },  // AT_Interrupt
+  { 0, 1, 0, 0, 0, 0, checkAcquireCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, AcquireCapabilityAttrSpellingMap },  // AT_AcquireCapability
+  { 0, 1, 0, 0, 0, 0, checkAcquiredAfterAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AcquiredAfter
+  { 0, 1, 0, 0, 0, 0, checkAcquiredBeforeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AcquiredBefore
+  { 1, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AddressSpace
+  { 1, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Alias
+  { 0, 1, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, AlignedAttrSpellingMap },  // AT_Aligned
+  { 0, 0, 0, 0, 0, 1, checkAlwaysInlineAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, AlwaysInlineAttrSpellingMap },  // AT_AlwaysInline
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AnalyzerNoReturn
+  { 1, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Annotate
+  { 0, 0, 0, 0, 0, 0, checkArcWeakrefUnavailableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ArcWeakrefUnavailable
+  { 4, 0, 1, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, ArgumentWithTypeTagAttrSpellingMap },  // AT_ArgumentWithTypeTag
+  { 1, 0, 0, 0, 0, 0, checkAssertCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, AssertCapabilityAttrSpellingMap },  // AT_AssertCapability
+  { 0, 1, 0, 0, 0, 0, checkAssertExclusiveLockAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AssertExclusiveLock
+  { 0, 1, 0, 0, 0, 0, checkAssertSharedLockAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_AssertSharedLock
+  { 6, 0, 1, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Availability
+  { 1, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Blocks
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CDecl
+  { 0, 0, 0, 0, 0, 0, checkCFAuditedTransferAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CFAuditedTransfer
+  { 0, 0, 0, 0, 0, 0, checkCFConsumedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CFConsumed
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CFReturnsNotRetained
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CFReturnsRetained
+  { 0, 0, 0, 0, 0, 0, checkCFUnknownTransferAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CFUnknownTransfer
+  { 0, 0, 0, 0, 0, 0, checkCUDAConstantAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDAConstant
+  { 0, 0, 0, 0, 0, 0, checkCUDADeviceAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDADevice
+  { 0, 0, 0, 0, 0, 0, checkCUDAGlobalAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDAGlobal
+  { 0, 0, 0, 0, 0, 0, checkCUDAHostAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDAHost
+  { 1, 1, 0, 0, 0, 0, checkCUDALaunchBoundsAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDALaunchBounds
+  { 0, 0, 0, 0, 0, 0, checkCUDASharedAppertainsTo, checkCUDALangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CUDAShared
+  { 0, 0, 0, 0, 0, 0, checkCXX11NoReturnAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CXX11NoReturn
+  { 0, 1, 0, 0, 0, 0, checkCallableWhenAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CallableWhen
+  { 1, 0, 0, 0, 0, 0, checkCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, CapabilityAttrSpellingMap },  // AT_Capability
+  { 0, 0, 0, 0, 0, 0, checkCarriesDependencyAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_CarriesDependency
+  { 1, 0, 0, 0, 0, 1, checkCleanupAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Cleanup
+  { 0, 0, 0, 0, 0, 1, checkColdAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Cold
+  { 0, 0, 0, 0, 0, 1, checkCommonAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Common
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Const
+  { 0, 1, 0, 0, 0, 1, checkConstructorAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Constructor
+  { 1, 0, 0, 0, 0, 0, checkConsumableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Consumable
+  { 0, 0, 0, 0, 0, 0, checkConsumableAutoCastAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ConsumableAutoCast
+  { 0, 0, 0, 0, 0, 0, checkConsumableSetOnReadAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ConsumableSetOnRead
+  { 0, 0, 0, 1, 0, 1, checkDLLExportAppertainsTo, defaultDiagnoseLangOpts, isTargetx86x86_64armthumbWin32, defaultSpellingIndexToSemanticSpelling },  // AT_DLLExport
+  { 0, 0, 0, 1, 0, 1, checkDLLImportAppertainsTo, defaultDiagnoseLangOpts, isTargetx86x86_64armthumbWin32, defaultSpellingIndexToSemanticSpelling },  // AT_DLLImport
+  { 0, 1, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Deprecated
+  { 0, 1, 0, 0, 0, 1, checkDestructorAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Destructor
+  { 2, 0, 0, 0, 0, 0, checkEnableIfAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_EnableIf
+  { 1, 1, 0, 0, 0, 0, checkExclusiveTrylockFunctionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ExclusiveTrylockFunction
+  { 1, 0, 0, 0, 0, 0, checkExtVectorTypeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ExtVectorType
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_FallThrough
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_FastCall
+  { 0, 0, 0, 0, 0, 1, checkFlattenAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Flatten
+  { 3, 0, 0, 0, 0, 1, checkFormatAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Format
+  { 1, 0, 0, 0, 0, 1, checkFormatArgAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_FormatArg
+  { 0, 0, 0, 0, 0, 1, checkGNUInlineAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_GNUInline
+  { 1, 0, 0, 0, 0, 0, checkGuardedByAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_GuardedBy
+  { 0, 0, 0, 0, 0, 0, checkGuardedVarAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_GuardedVar
+  { 0, 0, 0, 0, 0, 1, checkHotAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Hot
+  { 0, 0, 0, 0, 0, 0, checkIBActionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_IBAction
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_IBOutlet
+  { 0, 1, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_IBOutletCollection
+  { 1, 0, 0, 0, 0, 0, checkInitPriorityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_InitPriority
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_IntelOclBicc
+  { 1, 0, 0, 0, 0, 0, checkLockReturnedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_LockReturned
+  { 0, 0, 0, 0, 0, 0, checkLockableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Lockable
+  { 0, 1, 0, 0, 0, 0, checkLocksExcludedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_LocksExcluded
+  { 1, 1, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, LoopHintAttrSpellingMap },  // AT_LoopHint
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_MSABI
+  { 0, 1, 0, 0, 0, 0, defaultAppertainsTo, checkMicrosoftExtLangOpts, defaultTargetRequirements, MSInheritanceAttrSpellingMap },  // AT_MSInheritance
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Malloc
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_MayAlias
+  { 0, 0, 0, 0, 0, 0, checkMinSizeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_MinSize
+  { 0, 0, 0, 1, 0, 1, checkMips16AppertainsTo, defaultDiagnoseLangOpts, isTargetmipsmipsel, defaultSpellingIndexToSemanticSpelling },  // AT_Mips16
+  { 1, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Mode
+  { 0, 0, 0, 0, 0, 1, checkMsStructAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_MsStruct
+  { 0, 0, 0, 0, 0, 0, checkNSConsumedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NSConsumed
+  { 0, 0, 0, 0, 0, 0, checkNSConsumesSelfAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NSConsumesSelf
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NSReturnsAutoreleased
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NSReturnsNotRetained
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NSReturnsRetained
+  { 0, 0, 0, 0, 0, 1, checkNakedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Naked
+  { 1, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NeonPolyVectorType
+  { 1, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NeonVectorType
+  { 0, 0, 0, 0, 0, 1, checkNoCommonAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoCommon
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoDebug
+  { 0, 0, 0, 0, 0, 0, checkNoDuplicateAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoDuplicate
+  { 0, 0, 0, 0, 0, 1, checkNoInlineAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoInline
+  { 0, 0, 0, 0, 0, 1, checkNoInstrumentFunctionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoInstrumentFunction
+  { 0, 0, 0, 1, 0, 1, checkNoMips16AppertainsTo, defaultDiagnoseLangOpts, isTargetmipsmipsel, defaultSpellingIndexToSemanticSpelling },  // AT_NoMips16
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoReturn
+  { 0, 0, 0, 0, 0, 1, checkNoSanitizeAddressAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, NoSanitizeAddressAttrSpellingMap },  // AT_NoSanitizeAddress
+  { 0, 0, 0, 0, 0, 0, checkNoSanitizeMemoryAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoSanitizeMemory
+  { 0, 0, 0, 0, 0, 0, checkNoSanitizeThreadAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoSanitizeThread
+  { 0, 0, 0, 0, 0, 1, checkNoSplitStackAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoSplitStack
+  { 0, 0, 0, 0, 0, 0, checkNoThreadSafetyAnalysisAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoThreadSafetyAnalysis
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NoThrow
+  { 0, 1, 0, 0, 0, 1, checkNonNullAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_NonNull
+  { 1, 0, 0, 0, 0, 0, checkObjCBridgeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCBridge
+  { 1, 0, 0, 0, 0, 0, checkObjCBridgeMutableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCBridgeMutable
+  { 3, 0, 1, 0, 0, 0, checkObjCBridgeRelatedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCBridgeRelated
+  { 0, 0, 0, 0, 0, 0, checkObjCDesignatedInitializerAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCDesignatedInitializer
+  { 0, 0, 0, 0, 0, 0, checkObjCExceptionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCException
+  { 0, 0, 0, 0, 0, 0, checkObjCExplicitProtocolImplAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCExplicitProtocolImpl
+  { 1, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCGC
+  { 1, 0, 0, 0, 0, 0, checkObjCMethodFamilyAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCMethodFamily
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCNSObject
+  { 1, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCOwnership
+  { 0, 0, 0, 0, 0, 0, checkObjCPreciseLifetimeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCPreciseLifetime
+  { 0, 0, 0, 0, 0, 0, checkObjCRequiresPropertyDefsAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCRequiresPropertyDefs
+  { 0, 0, 0, 0, 0, 0, checkObjCRequiresSuperAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCRequiresSuper
+  { 0, 0, 0, 0, 0, 0, checkObjCReturnsInnerPointerAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCReturnsInnerPointer
+  { 0, 0, 0, 0, 0, 0, checkObjCRootClassAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCRootClass
+  { 1, 0, 0, 0, 0, 0, checkObjCRuntimeNameAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ObjCRuntimeName
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OpenCLConstantAddressSpace
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OpenCLGlobalAddressSpace
+  { 0, 0, 0, 0, 0, 0, checkOpenCLImageAccessAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, OpenCLImageAccessAttrSpellingMap },  // AT_OpenCLImageAccess
+  { 0, 0, 0, 0, 0, 0, checkOpenCLKernelAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OpenCLKernel
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OpenCLLocalAddressSpace
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OpenCLPrivateAddressSpace
+  { 0, 0, 0, 0, 0, 0, checkOptimizeNoneAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_OptimizeNone
+  { 0, 0, 0, 0, 0, 0, checkOverloadableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Overloadable
+  { 1, 1, 0, 0, 0, 0, checkOwnershipAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, OwnershipAttrSpellingMap },  // AT_Ownership
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Packed
+  { 1, 0, 0, 0, 0, 0, checkParamTypestateAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ParamTypestate
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Pascal
+  { 1, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Pcs
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_PnaclCall
+  { 1, 0, 0, 0, 0, 0, checkPtGuardedByAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_PtGuardedBy
+  { 0, 0, 0, 0, 0, 0, checkPtGuardedVarAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_PtGuardedVar
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Ptr32
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Ptr64
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Pure
+  { 1, 0, 0, 0, 1, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Regparm
+  { 0, 1, 0, 0, 0, 0, checkReleaseCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, ReleaseCapabilityAttrSpellingMap },  // AT_ReleaseCapability
+  { 3, 0, 0, 0, 0, 0, checkReqdWorkGroupSizeAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ReqdWorkGroupSize
+  { 0, 1, 0, 0, 0, 0, checkRequiresCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, RequiresCapabilityAttrSpellingMap },  // AT_RequiresCapability
+  { 1, 0, 0, 0, 0, 0, checkReturnTypestateAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ReturnTypestate
+  { 0, 0, 0, 0, 0, 1, checkReturnsNonNullAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ReturnsNonNull
+  { 0, 0, 0, 0, 0, 1, checkReturnsTwiceAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ReturnsTwice
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_SPtr
+  { 0, 0, 0, 0, 0, 0, checkScopedLockableAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ScopedLockable
+  { 1, 0, 0, 0, 0, 1, checkSectionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, SectionAttrSpellingMap },  // AT_Section
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, checkMicrosoftExtLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_SelectAny
+  { 0, 2, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Sentinel
+  { 1, 0, 0, 0, 0, 0, checkSetTypestateAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_SetTypestate
+  { 1, 1, 0, 0, 0, 0, checkSharedTrylockFunctionAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_SharedTrylockFunction
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_StdCall
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_SysVABI
+  { 1, 0, 0, 0, 0, 1, checkTLSModelAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_TLSModel
+  { 1, 0, 0, 0, 0, 0, checkTestTypestateAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_TestTypestate
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_ThisCall
+  { 0, 0, 0, 0, 0, 0, checkThreadAppertainsTo, checkMicrosoftExtLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Thread
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_TransparentUnion
+  { 1, 1, 0, 0, 0, 0, checkTryAcquireCapabilityAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, TryAcquireCapabilityAttrSpellingMap },  // AT_TryAcquireCapability
+  { 4, 0, 1, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_TypeTagForDatatype
+  { 1, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_TypeVisibility
+  { 0, 0, 0, 0, 1, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_UPtr
+  { 0, 1, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Unavailable
+  { 0, 0, 0, 0, 0, 1, checkUnusedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Unused
+  { 0, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Used
+  { 1, 0, 0, 0, 0, 0, defaultAppertainsTo, checkMicrosoftExtBorlandLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Uuid
+  { 0, 0, 0, 0, 0, 0, checkVecReturnAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_VecReturn
+  { 1, 0, 0, 0, 0, 0, checkVecTypeHintAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_VecTypeHint
+  { 1, 0, 0, 0, 1, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_VectorSize
+  { 1, 0, 0, 0, 0, 1, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Visibility
+  { 0, 0, 0, 0, 0, 0, checkWarnUnusedAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_WarnUnused
+  { 0, 0, 0, 0, 0, 1, checkWarnUnusedResultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_WarnUnusedResult
+  { 0, 0, 0, 0, 0, 1, checkWeakAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_Weak
+  { 0, 0, 0, 0, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_WeakImport
+  { 0, 1, 0, 0, 0, 1, checkWeakRefAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_WeakRef
+  { 3, 0, 0, 0, 0, 0, checkWorkGroupSizeHintAppertainsTo, defaultDiagnoseLangOpts, defaultTargetRequirements, defaultSpellingIndexToSemanticSpelling },  // AT_WorkGroupSizeHint
+  { 0, 0, 0, 1, 0, 0, defaultAppertainsTo, defaultDiagnoseLangOpts, isTargetx86, defaultSpellingIndexToSemanticSpelling }  // AT_X86ForceAlignArgPointer
+};
+
diff --git a/include/clang/Sema/AttrParsedAttrKinds.inc b/include/clang/Sema/AttrParsedAttrKinds.inc
new file mode 100644
index 0000000..fd298f9
--- /dev/null
+++ b/include/clang/Sema/AttrParsedAttrKinds.inc
@@ -0,0 +1,1886 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute name matcher                                                      *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+static AttributeList::Kind getAttrKind(StringRef Name, AttributeList::Syntax Syntax) {
+  if (AttributeList::AS_GNU == Syntax) {
+  switch (Name.size()) {
+  default: break;
+  case 3:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ot", 2))
+        break;
+      return AttributeList::AT_Hot;	 // "hot"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cs", 2))
+        break;
+      return AttributeList::AT_Pcs;	 // "pcs"
+    }
+    break;
+  case 4:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "old", 3))
+        break;
+      return AttributeList::AT_Cold;	 // "cold"
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ost", 3))
+        break;
+      return AttributeList::AT_CUDAHost;	 // "host"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ode", 3))
+        break;
+      return AttributeList::AT_Mode;	 // "mode"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ure", 3))
+        break;
+      return AttributeList::AT_Pure;	 // "pure"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "sed", 3))
+        break;
+      return AttributeList::AT_Used;	 // "used"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eak", 3))
+        break;
+      return AttributeList::AT_Weak;	 // "weak"
+    }
+    break;
+  case 5:	 // 4 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lias", 4))
+        break;
+      return AttributeList::AT_Alias;	 // "alias"
+    case 'c':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ecl", 3))
+          break;
+        return AttributeList::AT_CDecl;	 // "cdecl"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nst", 3))
+          break;
+        return AttributeList::AT_Const;	 // "const"
+      }
+      break;
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "aked", 4))
+        break;
+      return AttributeList::AT_Naked;	 // "naked"
+    }
+    break;
+  case 6:	 // 12 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "locks", 5))
+        break;
+      return AttributeList::AT_Blocks;	 // "blocks"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ommon", 5))
+        break;
+      return AttributeList::AT_Common;	 // "common"
+    case 'd':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "evice", 5))
+        break;
+      return AttributeList::AT_CUDADevice;	 // "device"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ormat", 5))
+        break;
+      return AttributeList::AT_Format;	 // "format"
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lobal", 5))
+        break;
+      return AttributeList::AT_CUDAGlobal;	 // "global"
+    case 'm':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "lloc", 4))
+          break;
+        return AttributeList::AT_Malloc;	 // "malloc"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ps16", 4))
+          break;
+        return AttributeList::AT_Mips16;	 // "mips16"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_abi", 4))
+          break;
+        return AttributeList::AT_MSABI;	 // "ms_abi"
+      }
+      break;
+    case 'p':	 // 2 strings to match.
+      if (Name[1] != 'a')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ked", 3))
+          break;
+        return AttributeList::AT_Packed;	 // "packed"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "cal", 3))
+          break;
+        return AttributeList::AT_Pascal;	 // "pascal"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hared", 5))
+        break;
+      return AttributeList::AT_CUDAShared;	 // "shared"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nused", 5))
+        break;
+      return AttributeList::AT_Unused;	 // "unused"
+    }
+    break;
+  case 7:	 // 15 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "_const", 6))
+        break;
+      return AttributeList::AT_Const;	 // "__const"
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ligned", 6))
+        break;
+      return AttributeList::AT_Aligned;	 // "aligned"
+    case 'b':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ounded", 6))
+        break;
+      return AttributeList::IgnoredAttribute;	 // "bounded"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "leanup", 6))
+        break;
+      return AttributeList::AT_Cleanup;	 // "cleanup"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "latten", 6))
+        break;
+      return AttributeList::AT_Flatten;	 // "flatten"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "insize", 6))
+        break;
+      return AttributeList::AT_MinSize;	 // "minsize"
+    case 'n':	 // 3 strings to match.
+      if (Name[1] != 'o')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ebug", 4))
+          break;
+        return AttributeList::AT_NoDebug;	 // "nodebug"
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "null", 4))
+          break;
+        return AttributeList::AT_NonNull;	 // "nonnull"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "hrow", 4))
+          break;
+        return AttributeList::AT_NoThrow;	 // "nothrow"
+      }
+      break;
+    case 'o':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "jc_gc", 5))
+          break;
+        return AttributeList::AT_ObjCGC;	 // "objc_gc"
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "tnone", 5))
+          break;
+        return AttributeList::AT_OptimizeNone;	 // "optnone"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "egparm", 6))
+        break;
+      return AttributeList::AT_Regparm;	 // "regparm"
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ction", 5))
+          break;
+        return AttributeList::AT_Section;	 // "section"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "dcall", 5))
+          break;
+        return AttributeList::AT_StdCall;	 // "stdcall"
+      }
+      break;
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eakref", 6))
+        break;
+      return AttributeList::AT_WeakRef;	 // "weakref"
+    }
+    break;
+  case 8:	 // 14 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'N':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "SObject", 7))
+        break;
+      return AttributeList::AT_ObjCNSObject;	 // "NSObject"
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nnotate", 7))
+        break;
+      return AttributeList::AT_Annotate;	 // "annotate"
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "onstant", 7))
+        break;
+      return AttributeList::AT_CUDAConstant;	 // "constant"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "astcall", 7))
+        break;
+      return AttributeList::AT_FastCall;	 // "fastcall"
+    case 'i':	 // 2 strings to match.
+      if (Name[1] != 'b')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ction", 5))
+          break;
+        return AttributeList::AT_IBAction;	 // "ibaction"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "utlet", 5))
+          break;
+        return AttributeList::AT_IBOutlet;	 // "iboutlet"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ockable", 7))
+        break;
+      return AttributeList::AT_Lockable;	 // "lockable"
+    case 'n':	 // 4 strings to match.
+      if (Name[1] != 'o')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ommon", 5))
+          break;
+        return AttributeList::AT_NoCommon;	 // "nocommon"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "nline", 5))
+          break;
+        return AttributeList::AT_NoInline;	 // "noinline"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ips16", 5))
+          break;
+        return AttributeList::AT_NoMips16;	 // "nomips16"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "eturn", 5))
+          break;
+        return AttributeList::AT_NoReturn;	 // "noreturn"
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ntinel", 6))
+          break;
+        return AttributeList::AT_Sentinel;	 // "sentinel"
+      case 'y':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "sv_abi", 6))
+          break;
+        return AttributeList::AT_SysVABI;	 // "sysv_abi"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hiscall", 7))
+        break;
+      return AttributeList::AT_ThisCall;	 // "thiscall"
+    }
+    break;
+  case 9:	 // 9 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "ll", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "xport", 5))
+          break;
+        return AttributeList::AT_DLLExport;	 // "dllexport"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "mport", 5))
+          break;
+        return AttributeList::AT_DLLImport;	 // "dllimport"
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nable_if", 8))
+        break;
+      return AttributeList::AT_EnableIf;	 // "enable_if"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nterrupt", 8))
+        break;
+      return AttributeList::AT_Interrupt;	 // "interrupt"
+    case 'm':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "y_alias", 7))
+          break;
+        return AttributeList::AT_MayAlias;	 // "may_alias"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_struct", 7))
+          break;
+        return AttributeList::AT_MsStruct;	 // "ms_struct"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "naclcall", 8))
+        break;
+      return AttributeList::AT_PnaclCall;	 // "pnaclcall"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ls_model", 8))
+        break;
+      return AttributeList::AT_TLSModel;	 // "tls_model"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ecreturn", 8))
+        break;
+      return AttributeList::AT_VecReturn;	 // "vecreturn"
+    }
+    break;
+  case 10:	 // 8 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "pability", 8))
+          break;
+        return AttributeList::AT_Capability;	 // "capability"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nsumable", 8))
+          break;
+        return AttributeList::AT_Consumable;	 // "consumable"
+      }
+      break;
+    case 'd':	 // 2 strings to match.
+      if (Name[1] != 'e')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "recated", 7))
+          break;
+        return AttributeList::AT_Deprecated;	 // "deprecated"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "tructor", 7))
+          break;
+        return AttributeList::AT_Destructor;	 // "destructor"
+      }
+      break;
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ormat_arg", 9))
+        break;
+      return AttributeList::AT_FormatArg;	 // "format_arg"
+    case 'g':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "u_inline", 8))
+          break;
+        return AttributeList::AT_GNUInline;	 // "gnu_inline"
+      case 'u':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "arded_by", 8))
+          break;
+        return AttributeList::AT_GuardedBy;	 // "guarded_by"
+      }
+      break;
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "isibility", 9))
+        break;
+      return AttributeList::AT_Visibility;	 // "visibility"
+    }
+    break;
+  case 11:	 // 10 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_consumed", 9))
+          break;
+        return AttributeList::AT_CFConsumed;	 // "cf_consumed"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nstructor", 9))
+          break;
+        return AttributeList::AT_Constructor;	 // "constructor"
+      }
+      break;
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "uarded_var", 10))
+        break;
+      return AttributeList::AT_GuardedVar;	 // "guarded_var"
+    case 'n':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "duplicate", 9))
+          break;
+        return AttributeList::AT_NoDuplicate;	 // "noduplicate"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_consumed", 9))
+          break;
+        return AttributeList::AT_NSConsumed;	 // "ns_consumed"
+      }
+      break;
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bjc_bridge", 10))
+        break;
+      return AttributeList::AT_ObjCBridge;	 // "objc_bridge"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "navailable", 10))
+        break;
+      return AttributeList::AT_Unavailable;	 // "unavailable"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ector_size", 10))
+        break;
+      return AttributeList::AT_VectorSize;	 // "vector_size"
+    case 'w':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "rn_unused", 9))
+          break;
+        return AttributeList::AT_WarnUnused;	 // "warn_unused"
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ak_import", 9))
+          break;
+        return AttributeList::AT_WeakImport;	 // "weak_import"
+      }
+      break;
+    }
+    break;
+  case 12:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "vailability", 11))
+        break;
+      return AttributeList::AT_Availability;	 // "availability"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "verloadable", 11))
+        break;
+      return AttributeList::AT_Overloadable;	 // "overloadable"
+    }
+    break;
+  case 13:	 // 10 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "dress_space", 11))
+          break;
+        return AttributeList::AT_AddressSpace;	 // "address_space"
+      case 'l':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ways_inline", 11))
+          break;
+        return AttributeList::AT_AlwaysInline;	 // "always_inline"
+      }
+      break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "allable_when", 12))
+        break;
+      return AttributeList::AT_CallableWhen;	 // "callable_when"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nit_priority", 12))
+        break;
+      return AttributeList::AT_InitPriority;	 // "init_priority"
+    case 'l':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "unch_bounds", 11))
+          break;
+        return AttributeList::AT_CUDALaunchBounds;	 // "launch_bounds"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ck_returned", 11))
+          break;
+        return AttributeList::AT_LockReturned;	 // "lock_returned"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "t_guarded_by", 12))
+        break;
+      return AttributeList::AT_PtGuardedBy;	 // "pt_guarded_by"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eturns_twice", 12))
+        break;
+      return AttributeList::AT_ReturnsTwice;	 // "returns_twice"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "et_typestate", 12))
+        break;
+      return AttributeList::AT_SetTypestate;	 // "set_typestate"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ec_type_hint", 12))
+        break;
+      return AttributeList::AT_VecTypeHint;	 // "vec_type_hint"
+    }
+    break;
+  case 14:	 // 8 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cquired_after", 13))
+        break;
+      return AttributeList::AT_AcquiredAfter;	 // "acquired_after"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ntel_ocl_bicc", 13))
+        break;
+      return AttributeList::AT_IntelOclBicc;	 // "intel_ocl_bicc"
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ocks_excluded", 13))
+        break;
+      return AttributeList::AT_LocksExcluded;	 // "locks_excluded"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "o_split_stack", 13))
+        break;
+      return AttributeList::AT_NoSplitStack;	 // "no_split_stack"
+    case 'o':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "bjc_", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "xception", 8))
+          break;
+        return AttributeList::AT_ObjCException;	 // "objc_exception"
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "wnership", 8))
+          break;
+        return AttributeList::AT_ObjCOwnership;	 // "objc_ownership"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "t_guarded_var", 13))
+        break;
+      return AttributeList::AT_PtGuardedVar;	 // "pt_guarded_var"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "est_typestate", 13))
+        break;
+      return AttributeList::AT_TestTypestate;	 // "test_typestate"
+    }
+    break;
+  case 15:	 // 10 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cquired_before", 14))
+        break;
+      return AttributeList::AT_AcquiredBefore;	 // "acquired_before"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "xt_vector_type", 14))
+        break;
+      return AttributeList::AT_ExtVectorType;	 // "ext_vector_type"
+    case 'o':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "jc_root_class", 13))
+          break;
+        return AttributeList::AT_ObjCRootClass;	 // "objc_root_class"
+      case 'w':	 // 2 strings to match.
+        if (memcmp(Name.data()+2, "nership_", 8))
+          break;
+        switch (Name[10]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(Name.data()+11, "olds", 4))
+            break;
+          return AttributeList::AT_Ownership;	 // "ownership_holds"
+        case 't':	 // 1 string to match.
+          if (memcmp(Name.data()+11, "akes", 4))
+            break;
+          return AttributeList::AT_Ownership;	 // "ownership_takes"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "aram_typestate", 14))
+        break;
+      return AttributeList::AT_ParamTypestate;	 // "param_typestate"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eturns_nonnull", 14))
+        break;
+      return AttributeList::AT_ReturnsNonNull;	 // "returns_nonnull"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "coped_lockable", 14))
+        break;
+      return AttributeList::AT_ScopedLockable;	 // "scoped_lockable"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ype_visibility", 14))
+        break;
+      return AttributeList::AT_TypeVisibility;	 // "type_visibility"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nlock_function", 14))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "unlock_function"
+    }
+    break;
+  case 16:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'n':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "on_vector_type", 14))
+          break;
+        return AttributeList::AT_NeonVectorType;	 // "neon_vector_type"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_consumes_self", 14))
+          break;
+        return AttributeList::AT_NSConsumesSelf;	 // "ns_consumes_self"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eturn_typestate", 15))
+        break;
+      return AttributeList::AT_ReturnTypestate;	 // "return_typestate"
+    }
+    break;
+  case 17:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "alyzer_noreturn", 15))
+          break;
+        return AttributeList::AT_AnalyzerNoReturn;	 // "analyzer_noreturn"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "sert_capability", 15))
+          break;
+        return AttributeList::AT_AssertCapability;	 // "assert_capability"
+      }
+      break;
+    case 'o':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "jc_runtime_name", 15))
+          break;
+        return AttributeList::AT_ObjCRuntimeName;	 // "objc_runtime_name"
+      case 'w':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "nership_returns", 15))
+          break;
+        return AttributeList::AT_Ownership;	 // "ownership_returns"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hared_capability", 16))
+        break;
+      return AttributeList::AT_Capability;	 // "shared_capability"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ransparent_union", 16))
+        break;
+      return AttributeList::AT_TransparentUnion;	 // "transparent_union"
+    }
+    break;
+  case 18:	 // 9 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "quire_capability", 16))
+          break;
+        return AttributeList::AT_AcquireCapability;	 // "acquire_capability"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "sert_shared_lock", 16))
+          break;
+        return AttributeList::AT_AssertSharedLock;	 // "assert_shared_lock"
+      }
+      break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "arries_dependency", 17))
+        break;
+      return AttributeList::AT_CarriesDependency;	 // "carries_dependency"
+    case 'i':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "boutletcollection", 17))
+        break;
+      return AttributeList::AT_IBOutletCollection;	 // "iboutletcollection"
+    case 'n':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "o_sanitize_", 11))
+        break;
+      switch (Name[12]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+13, "emory", 5))
+          break;
+        return AttributeList::AT_NoSanitizeMemory;	 // "no_sanitize_memory"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+13, "hread", 5))
+          break;
+        return AttributeList::AT_NoSanitizeThread;	 // "no_sanitize_thread"
+      }
+      break;
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bjc_method_family", 17))
+        break;
+      return AttributeList::AT_ObjCMethodFamily;	 // "objc_method_family"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elease_capability", 17))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "release_capability"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "arn_unused_result", 17))
+        break;
+      return AttributeList::AT_WarnUnusedResult;	 // "warn_unused_result"
+    }
+    break;
+  case 19:	 // 9 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 3 strings to match.
+      if (memcmp(Name.data()+1, "f_", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "udited_transfer", 15))
+          break;
+        return AttributeList::AT_CFAuditedTransfer;	 // "cf_audited_transfer"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "eturns_retained", 15))
+          break;
+        return AttributeList::AT_CFReturnsRetained;	 // "cf_returns_retained"
+      case 'u':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "nknown_transfer", 15))
+          break;
+        return AttributeList::AT_CFUnknownTransfer;	 // "cf_unknown_transfer"
+      }
+      break;
+    case 'n':	 // 2 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_sanitize_address", 17))
+          break;
+        return AttributeList::AT_NoSanitizeAddress;	 // "no_sanitize_address"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "_returns_retained", 17))
+          break;
+        return AttributeList::AT_NSReturnsRetained;	 // "ns_returns_retained"
+      }
+      break;
+    case 'o':	 // 3 strings to match.
+      if (memcmp(Name.data()+1, "bjc_", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case 'b':	 // 2 strings to match.
+        if (memcmp(Name.data()+6, "ridge_", 6))
+          break;
+        switch (Name[12]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(Name.data()+13, "utable", 6))
+            break;
+          return AttributeList::AT_ObjCBridgeMutable;	 // "objc_bridge_mutable"
+        case 'r':	 // 1 string to match.
+          if (memcmp(Name.data()+13, "elated", 6))
+            break;
+          return AttributeList::AT_ObjCBridgeRelated;	 // "objc_bridge_related"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "equires_super", 13))
+          break;
+        return AttributeList::AT_ObjCRequiresSuper;	 // "objc_requires_super"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "equires_capability", 18))
+        break;
+      return AttributeList::AT_RequiresCapability;	 // "requires_capability"
+    }
+    break;
+  case 20:	 // 4 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eon_polyvector_type", 19))
+        break;
+      return AttributeList::AT_NeonPolyVectorType;	 // "neon_polyvector_type"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "eqd_work_group_size", 19))
+        break;
+      return AttributeList::AT_ReqdWorkGroupSize;	 // "reqd_work_group_size"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hared_lock_function", 19))
+        break;
+      return AttributeList::AT_AcquireCapability;	 // "shared_lock_function"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ork_group_size_hint", 19))
+        break;
+      return AttributeList::AT_WorkGroupSizeHint;	 // "work_group_size_hint"
+    }
+    break;
+  case 21:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ssert_exclusive_lock", 20))
+        break;
+      return AttributeList::AT_AssertExclusiveLock;	 // "assert_exclusive_lock"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bjc_precise_lifetime", 20))
+        break;
+      return AttributeList::AT_ObjCPreciseLifetime;	 // "objc_precise_lifetime"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ointer_with_type_tag", 20))
+        break;
+      return AttributeList::AT_ArgumentWithTypeTag;	 // "pointer_with_type_tag"
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hared_locks_required", 20))
+        break;
+      return AttributeList::AT_RequiresCapability;	 // "shared_locks_required"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ype_tag_for_datatype", 20))
+        break;
+      return AttributeList::AT_TypeTagForDatatype;	 // "type_tag_for_datatype"
+    }
+    break;
+  case 22:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rgument_with_type_tag", 21))
+        break;
+      return AttributeList::AT_ArgumentWithTypeTag;	 // "argument_with_type_tag"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "o_instrument_function", 21))
+        break;
+      return AttributeList::AT_NoInstrumentFunction;	 // "no_instrument_function"
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ry_acquire_capability", 21))
+        break;
+      return AttributeList::AT_TryAcquireCapability;	 // "try_acquire_capability"
+    }
+    break;
+  case 23:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "f_returns_not_retained", 22))
+        break;
+      return AttributeList::AT_CFReturnsNotRetained;	 // "cf_returns_not_retained"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "xclusive_lock_function", 22))
+        break;
+      return AttributeList::AT_AcquireCapability;	 // "exclusive_lock_function"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "orce_align_arg_pointer", 22))
+        break;
+      return AttributeList::AT_X86ForceAlignArgPointer;	 // "force_align_arg_pointer"
+    case 'n':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "s_returns_", 10))
+        break;
+      switch (Name[11]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+12, "utoreleased", 11))
+          break;
+        return AttributeList::AT_NSReturnsAutoreleased;	 // "ns_returns_autoreleased"
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+12, "ot_retained", 11))
+          break;
+        return AttributeList::AT_NSReturnsNotRetained;	 // "ns_returns_not_retained"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "hared_trylock_function", 22))
+        break;
+      return AttributeList::AT_SharedTrylockFunction;	 // "shared_trylock_function"
+    }
+    break;
+  case 24:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ssert_shared_capability", 23))
+        break;
+      return AttributeList::AT_AssertCapability;	 // "assert_shared_capability"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "xclusive_locks_required", 23))
+        break;
+      return AttributeList::AT_RequiresCapability;	 // "exclusive_locks_required"
+    }
+    break;
+  case 25:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "cquire_shared_capability", 24))
+        break;
+      return AttributeList::AT_AcquireCapability;	 // "acquire_shared_capability"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "o_thread_safety_analysis", 24))
+        break;
+      return AttributeList::AT_NoThreadSafetyAnalysis;	 // "no_thread_safety_analysis"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "elease_shared_capability", 24))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "release_shared_capability"
+    }
+    break;
+  case 26:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "onsumable_auto_cast_state", 25))
+        break;
+      return AttributeList::AT_ConsumableAutoCast;	 // "consumable_auto_cast_state"
+    case 'e':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "xclusive_trylock_function", 25))
+        break;
+      return AttributeList::AT_ExclusiveTrylockFunction;	 // "exclusive_trylock_function"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "o_address_safety_analysis", 25))
+        break;
+      return AttributeList::AT_NoSanitizeAddress;	 // "no_address_safety_analysis"
+    case 'o':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "bjc_returns_inner_pointer", 25))
+        break;
+      return AttributeList::AT_ObjCReturnsInnerPointer;	 // "objc_returns_inner_pointer"
+    case 'r':	 // 2 strings to match.
+      if (Name[1] != 'e')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "ease_generic_capability", 23))
+          break;
+        return AttributeList::AT_ReleaseCapability;	 // "release_generic_capability"
+      case 'q':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "uires_shared_capability", 23))
+          break;
+        return AttributeList::AT_RequiresCapability;	 // "requires_shared_capability"
+      }
+      break;
+    }
+    break;
+  case 27:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "objc_designated_initializer", 27))
+      break;
+    return AttributeList::AT_ObjCDesignatedInitializer;	 // "objc_designated_initializer"
+  case 28:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "consumable_set_state_on_read", 28))
+      break;
+    return AttributeList::AT_ConsumableSetOnRead;	 // "consumable_set_state_on_read"
+  case 29:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "try_acquire_shared_capability", 29))
+      break;
+    return AttributeList::AT_TryAcquireCapability;	 // "try_acquire_shared_capability"
+  case 34:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "objc_requires_property_definitions", 34))
+      break;
+    return AttributeList::AT_ObjCRequiresPropertyDefs;	 // "objc_requires_property_definitions"
+  case 35:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "objc_arc_weak_reference_unavailable", 35))
+      break;
+    return AttributeList::AT_ArcWeakrefUnavailable;	 // "objc_arc_weak_reference_unavailable"
+  case 46:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "objc_protocol_requires_explicit_implementation", 46))
+      break;
+    return AttributeList::AT_ObjCExplicitProtocolImpl;	 // "objc_protocol_requires_explicit_implementation"
+  }
+  } else if (AttributeList::AS_Declspec == Syntax) {
+  switch (Name.size()) {
+  default: break;
+  case 4:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "uuid", 4))
+      break;
+    return AttributeList::AT_Uuid;	 // "uuid"
+  case 5:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lign", 4))
+        break;
+      return AttributeList::AT_Aligned;	 // "align"
+    case 'n':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "aked", 4))
+        break;
+      return AttributeList::AT_Naked;	 // "naked"
+    }
+    break;
+  case 6:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "thread", 6))
+      break;
+    return AttributeList::AT_Thread;	 // "thread"
+  case 7:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "nothrow", 7))
+      break;
+    return AttributeList::AT_NoThrow;	 // "nothrow"
+  case 8:	 // 4 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "llocate", 7))
+        break;
+      return AttributeList::AT_Section;	 // "allocate"
+    case 'n':	 // 2 strings to match.
+      if (Name[1] != 'o')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "nline", 5))
+          break;
+        return AttributeList::AT_NoInline;	 // "noinline"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "eturn", 5))
+          break;
+        return AttributeList::AT_NoReturn;	 // "noreturn"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "roperty", 7))
+        break;
+      return AttributeList::IgnoredAttribute;	 // "property"
+    }
+    break;
+  case 9:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "ll", 2))
+        break;
+      switch (Name[3]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "xport", 5))
+          break;
+        return AttributeList::AT_DLLExport;	 // "dllexport"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+4, "mport", 5))
+          break;
+        return AttributeList::AT_DLLImport;	 // "dllimport"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "electany", 8))
+        break;
+      return AttributeList::AT_SelectAny;	 // "selectany"
+    }
+    break;
+  case 10:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "deprecated", 10))
+      break;
+    return AttributeList::AT_Deprecated;	 // "deprecated"
+  }
+  } else if (AttributeList::AS_CXX11 == Syntax) {
+  switch (Name.size()) {
+  default: break;
+  case 8:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'h':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ot", 2))
+        break;
+      return AttributeList::AT_Hot;	 // "gnu::hot"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "cs", 2))
+        break;
+      return AttributeList::AT_Pcs;	 // "gnu::pcs"
+    }
+    break;
+  case 9:	 // 5 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "old", 3))
+        break;
+      return AttributeList::AT_Cold;	 // "gnu::cold"
+    case 'm':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ode", 3))
+        break;
+      return AttributeList::AT_Mode;	 // "gnu::mode"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ure", 3))
+        break;
+      return AttributeList::AT_Pure;	 // "gnu::pure"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "sed", 3))
+        break;
+      return AttributeList::AT_Used;	 // "gnu::used"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "eak", 3))
+        break;
+      return AttributeList::AT_Weak;	 // "gnu::weak"
+    }
+    break;
+  case 10:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case ':':	 // 1 string to match.
+      if (memcmp(Name.data()+1, ":noreturn", 9))
+        break;
+      return AttributeList::AT_CXX11NoReturn;	 // "::noreturn"
+    case 'g':	 // 4 strings to match.
+      if (memcmp(Name.data()+1, "nu::", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "lias", 4))
+          break;
+        return AttributeList::AT_Alias;	 // "gnu::alias"
+      case 'c':	 // 2 strings to match.
+        switch (Name[6]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "ecl", 3))
+            break;
+          return AttributeList::AT_CDecl;	 // "gnu::cdecl"
+        case 'o':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "nst", 3))
+            break;
+          return AttributeList::AT_Const;	 // "gnu::const"
+        }
+        break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "aked", 4))
+          break;
+        return AttributeList::AT_Naked;	 // "gnu::naked"
+      }
+      break;
+    }
+    break;
+  case 11:	 // 7 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ommon", 5))
+        break;
+      return AttributeList::AT_Common;	 // "gnu::common"
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ormat", 5))
+        break;
+      return AttributeList::AT_Format;	 // "gnu::format"
+    case 'm':	 // 3 strings to match.
+      switch (Name[6]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "lloc", 4))
+          break;
+        return AttributeList::AT_Malloc;	 // "gnu::malloc"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "ps16", 4))
+          break;
+        return AttributeList::AT_Mips16;	 // "gnu::mips16"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "_abi", 4))
+          break;
+        return AttributeList::AT_MSABI;	 // "gnu::ms_abi"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "acked", 5))
+        break;
+      return AttributeList::AT_Packed;	 // "gnu::packed"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "nused", 5))
+        break;
+      return AttributeList::AT_Unused;	 // "gnu::unused"
+    }
+    break;
+  case 12:	 // 11 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case ':':	 // 1 string to match.
+      if (memcmp(Name.data()+1, ":deprecated", 11))
+        break;
+      return AttributeList::AT_Deprecated;	 // "::deprecated"
+    case 'g':	 // 10 strings to match.
+      if (memcmp(Name.data()+1, "nu::", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case '_':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "_const", 6))
+          break;
+        return AttributeList::AT_Const;	 // "gnu::__const"
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "ligned", 6))
+          break;
+        return AttributeList::AT_Aligned;	 // "gnu::aligned"
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "leanup", 6))
+          break;
+        return AttributeList::AT_Cleanup;	 // "gnu::cleanup"
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "latten", 6))
+          break;
+        return AttributeList::AT_Flatten;	 // "gnu::flatten"
+      case 'n':	 // 2 strings to match.
+        if (Name[6] != 'o')
+          break;
+        switch (Name[7]) {
+        default: break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(Name.data()+8, "null", 4))
+            break;
+          return AttributeList::AT_NonNull;	 // "gnu::nonnull"
+        case 't':	 // 1 string to match.
+          if (memcmp(Name.data()+8, "hrow", 4))
+            break;
+          return AttributeList::AT_NoThrow;	 // "gnu::nothrow"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "egparm", 6))
+          break;
+        return AttributeList::AT_Regparm;	 // "gnu::regparm"
+      case 's':	 // 2 strings to match.
+        switch (Name[6]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "ction", 5))
+            break;
+          return AttributeList::AT_Section;	 // "gnu::section"
+        case 't':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "dcall", 5))
+            break;
+          return AttributeList::AT_StdCall;	 // "gnu::stdcall"
+        }
+        break;
+      case 'w':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "eakref", 6))
+          break;
+        return AttributeList::AT_WeakRef;	 // "gnu::weakref"
+      }
+      break;
+    }
+    break;
+  case 13:	 // 8 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "astcall", 7))
+        break;
+      return AttributeList::AT_FastCall;	 // "gnu::fastcall"
+    case 'n':	 // 4 strings to match.
+      if (Name[6] != 'o')
+        break;
+      switch (Name[7]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "ommon", 5))
+          break;
+        return AttributeList::AT_NoCommon;	 // "gnu::nocommon"
+      case 'i':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "nline", 5))
+          break;
+        return AttributeList::AT_NoInline;	 // "gnu::noinline"
+      case 'm':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "ips16", 5))
+          break;
+        return AttributeList::AT_NoMips16;	 // "gnu::nomips16"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "eturn", 5))
+          break;
+        return AttributeList::AT_NoReturn;	 // "gnu::noreturn"
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      switch (Name[6]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "ntinel", 6))
+          break;
+        return AttributeList::AT_Sentinel;	 // "gnu::sentinel"
+      case 'y':	 // 1 string to match.
+        if (memcmp(Name.data()+7, "sv_abi", 6))
+          break;
+        return AttributeList::AT_SysVABI;	 // "gnu::sysv_abi"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "hiscall", 7))
+        break;
+      return AttributeList::AT_ThisCall;	 // "gnu::thiscall"
+    }
+    break;
+  case 14:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lang::optnone", 13))
+        break;
+      return AttributeList::AT_OptimizeNone;	 // "clang::optnone"
+    case 'g':	 // 5 strings to match.
+      if (memcmp(Name.data()+1, "nu::", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(Name.data()+6, "ll", 2))
+          break;
+        switch (Name[8]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(Name.data()+9, "xport", 5))
+            break;
+          return AttributeList::AT_DLLExport;	 // "gnu::dllexport"
+        case 'i':	 // 1 string to match.
+          if (memcmp(Name.data()+9, "mport", 5))
+            break;
+          return AttributeList::AT_DLLImport;	 // "gnu::dllimport"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        switch (Name[6]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "y_alias", 7))
+            break;
+          return AttributeList::AT_MayAlias;	 // "gnu::may_alias"
+        case 's':	 // 1 string to match.
+          if (memcmp(Name.data()+7, "_struct", 7))
+            break;
+          return AttributeList::AT_MsStruct;	 // "gnu::ms_struct"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "ls_model", 8))
+          break;
+        return AttributeList::AT_TLSModel;	 // "gnu::tls_model"
+      }
+      break;
+    }
+    break;
+  case 15:	 // 5 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (Name[6] != 'e')
+        break;
+      switch (Name[7]) {
+      default: break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "recated", 7))
+          break;
+        return AttributeList::AT_Deprecated;	 // "gnu::deprecated"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "tructor", 7))
+          break;
+        return AttributeList::AT_Destructor;	 // "gnu::destructor"
+      }
+      break;
+    case 'f':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ormat_arg", 9))
+        break;
+      return AttributeList::AT_FormatArg;	 // "gnu::format_arg"
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "nu_inline", 9))
+        break;
+      return AttributeList::AT_GNUInline;	 // "gnu::gnu_inline"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "isibility", 9))
+        break;
+      return AttributeList::AT_Visibility;	 // "gnu::visibility"
+    }
+    break;
+  case 16:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "gnu::", 5))
+      break;
+    switch (Name[5]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "onstructor", 10))
+        break;
+      return AttributeList::AT_Constructor;	 // "gnu::constructor"
+    case 'v':	 // 1 string to match.
+      if (memcmp(Name.data()+6, "ector_size", 10))
+        break;
+      return AttributeList::AT_VectorSize;	 // "gnu::vector_size"
+    }
+    break;
+  case 17:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "clang::capability", 17))
+      break;
+    return AttributeList::AT_Capability;	 // "clang::capability"
+  case 18:	 // 4 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "lang::", 6))
+        break;
+      switch (Name[7]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "allthrough", 10))
+          break;
+        return AttributeList::AT_FallThrough;	 // "clang::fallthrough"
+      case 'n':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "oduplicate", 10))
+          break;
+        return AttributeList::AT_NoDuplicate;	 // "clang::noduplicate"
+      }
+      break;
+    case 'g':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "nu::", 4))
+        break;
+      switch (Name[5]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "lways_inline", 12))
+          break;
+        return AttributeList::AT_AlwaysInline;	 // "gnu::always_inline"
+      case 'r':	 // 1 string to match.
+        if (memcmp(Name.data()+6, "eturns_twice", 12))
+          break;
+        return AttributeList::AT_ReturnsTwice;	 // "gnu::returns_twice"
+      }
+      break;
+    }
+    break;
+  case 19:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "gnu::no_split_stack", 19))
+      break;
+    return AttributeList::AT_NoSplitStack;	 // "gnu::no_split_stack"
+  case 20:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case ':':	 // 1 string to match.
+      if (memcmp(Name.data()+1, ":carries_dependency", 19))
+        break;
+      return AttributeList::AT_CarriesDependency;	 // "::carries_dependency"
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nu::returns_nonnull", 19))
+        break;
+      return AttributeList::AT_ReturnsNonNull;	 // "gnu::returns_nonnull"
+    }
+    break;
+  case 22:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lang::type_visibility", 21))
+        break;
+      return AttributeList::AT_TypeVisibility;	 // "clang::type_visibility"
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nu::transparent_union", 21))
+        break;
+      return AttributeList::AT_TransparentUnion;	 // "gnu::transparent_union"
+    }
+    break;
+  case 23:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "gnu::warn_unused_result", 23))
+      break;
+    return AttributeList::AT_WarnUnusedResult;	 // "gnu::warn_unused_result"
+  case 24:	 // 3 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 2 strings to match.
+      if (memcmp(Name.data()+1, "lang::", 6))
+        break;
+      switch (Name[7]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "ssert_capability", 16))
+          break;
+        return AttributeList::AT_AssertCapability;	 // "clang::assert_capability"
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+8, "hared_capability", 16))
+          break;
+        return AttributeList::AT_Capability;	 // "clang::shared_capability"
+      }
+      break;
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nu::no_sanitize_address", 23))
+        break;
+      return AttributeList::AT_NoSanitizeAddress;	 // "gnu::no_sanitize_address"
+    }
+    break;
+  case 25:	 // 3 strings to match.
+    if (memcmp(Name.data()+0, "clang::", 7))
+      break;
+    switch (Name[7]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+8, "cquire_capability", 17))
+        break;
+      return AttributeList::AT_AcquireCapability;	 // "clang::acquire_capability"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+8, "elease_capability", 17))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "clang::release_capability"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+8, "arn_unused_result", 17))
+        break;
+      return AttributeList::AT_WarnUnusedResult;	 // "clang::warn_unused_result"
+    }
+    break;
+  case 26:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "clang::requires_capability", 26))
+      break;
+    return AttributeList::AT_RequiresCapability;	 // "clang::requires_capability"
+  case 27:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "gnu::no_instrument_function", 27))
+      break;
+    return AttributeList::AT_NoInstrumentFunction;	 // "gnu::no_instrument_function"
+  case 29:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "clang::try_acquire_capability", 29))
+      break;
+    return AttributeList::AT_TryAcquireCapability;	 // "clang::try_acquire_capability"
+  case 31:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lang::assert_shared_capability", 30))
+        break;
+      return AttributeList::AT_AssertCapability;	 // "clang::assert_shared_capability"
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "nu::no_address_safety_analysis", 30))
+        break;
+      return AttributeList::AT_NoSanitizeAddress;	 // "gnu::no_address_safety_analysis"
+    }
+    break;
+  case 32:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "clang::", 7))
+      break;
+    switch (Name[7]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+8, "cquire_shared_capability", 24))
+        break;
+      return AttributeList::AT_AcquireCapability;	 // "clang::acquire_shared_capability"
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+8, "elease_shared_capability", 24))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "clang::release_shared_capability"
+    }
+    break;
+  case 33:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "clang::re", 9))
+      break;
+    switch (Name[9]) {
+    default: break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+10, "ease_generic_capability", 23))
+        break;
+      return AttributeList::AT_ReleaseCapability;	 // "clang::release_generic_capability"
+    case 'q':	 // 1 string to match.
+      if (memcmp(Name.data()+10, "uires_shared_capability", 23))
+        break;
+      return AttributeList::AT_RequiresCapability;	 // "clang::requires_shared_capability"
+    }
+    break;
+  case 36:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "clang::try_acquire_shared_capability", 36))
+      break;
+    return AttributeList::AT_TryAcquireCapability;	 // "clang::try_acquire_shared_capability"
+  }
+  } else if (AttributeList::AS_Keyword == Syntax) {
+  switch (Name.size()) {
+  default: break;
+  case 5:	 // 2 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "_w64", 4))
+        break;
+      return AttributeList::IgnoredAttribute;	 // "__w64"
+    case 'l':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ocal", 4))
+        break;
+      return AttributeList::AT_OpenCLLocalAddressSpace;	 // "local"
+    }
+    break;
+  case 6:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 3 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case '_':	 // 2 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "ptr", 3))
+            break;
+          return AttributeList::AT_SPtr;	 // "__sptr"
+        case 'u':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "ptr", 3))
+            break;
+          return AttributeList::AT_UPtr;	 // "__uptr"
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "decl", 4))
+          break;
+        return AttributeList::AT_CDecl;	 // "_cdecl"
+      }
+      break;
+    case 'g':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lobal", 5))
+        break;
+      return AttributeList::AT_OpenCLGlobalAddressSpace;	 // "global"
+    case 'k':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ernel", 5))
+        break;
+      return AttributeList::AT_OpenCLKernel;	 // "kernel"
+    }
+    break;
+  case 7:	 // 7 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 5 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case '_':	 // 4 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "decl", 4))
+            break;
+          return AttributeList::AT_CDecl;	 // "__cdecl"
+        case 'l':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "ocal", 4))
+            break;
+          return AttributeList::AT_OpenCLLocalAddressSpace;	 // "__local"
+        case 'p':	 // 2 strings to match.
+          if (memcmp(Name.data()+3, "tr", 2))
+            break;
+          switch (Name[5]) {
+          default: break;
+          case '3':	 // 1 string to match.
+            if (Name[6] != '2')
+              break;
+            return AttributeList::AT_Ptr32;	 // "__ptr32"
+          case '6':	 // 1 string to match.
+            if (Name[6] != '4')
+              break;
+            return AttributeList::AT_Ptr64;	 // "__ptr64"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "ascal", 5))
+          break;
+        return AttributeList::AT_Pascal;	 // "_pascal"
+      }
+      break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "lignas", 6))
+        break;
+      return AttributeList::AT_Aligned;	 // "alignas"
+    case 'p':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rivate", 6))
+        break;
+      return AttributeList::AT_OpenCLPrivateAddressSpace;	 // "private"
+    }
+    break;
+  case 8:	 // 6 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 5 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case 'A':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "lignas", 6))
+          break;
+        return AttributeList::AT_Aligned;	 // "_Alignas"
+      case '_':	 // 3 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'g':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "lobal", 5))
+            break;
+          return AttributeList::AT_OpenCLGlobalAddressSpace;	 // "__global"
+        case 'k':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "ernel", 5))
+            break;
+          return AttributeList::AT_OpenCLKernel;	 // "__kernel"
+        case 'p':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "ascal", 5))
+            break;
+          return AttributeList::AT_Pascal;	 // "__pascal"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "tdcall", 6))
+          break;
+        return AttributeList::AT_StdCall;	 // "_stdcall"
+      }
+      break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "onstant", 7))
+        break;
+      return AttributeList::AT_OpenCLConstantAddressSpace;	 // "constant"
+    }
+    break;
+  case 9:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 4 strings to match.
+      switch (Name[1]) {
+      default: break;
+      case '_':	 // 2 strings to match.
+        switch (Name[2]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "rivate", 6))
+            break;
+          return AttributeList::AT_OpenCLPrivateAddressSpace;	 // "__private"
+        case 's':	 // 1 string to match.
+          if (memcmp(Name.data()+3, "tdcall", 6))
+            break;
+          return AttributeList::AT_StdCall;	 // "__stdcall"
+        }
+        break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "astcall", 7))
+          break;
+        return AttributeList::AT_FastCall;	 // "_fastcall"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+2, "hiscall", 7))
+          break;
+        return AttributeList::AT_ThisCall;	 // "_thiscall"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ead_only", 8))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "read_only"
+    }
+    break;
+  case 10:	 // 5 strings to match.
+    switch (Name[0]) {
+    default: break;
+    case '_':	 // 3 strings to match.
+      if (Name[1] != '_')
+        break;
+      switch (Name[2]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "onstant", 7))
+          break;
+        return AttributeList::AT_OpenCLConstantAddressSpace;	 // "__constant"
+      case 'f':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "astcall", 7))
+          break;
+        return AttributeList::AT_FastCall;	 // "__fastcall"
+      case 't':	 // 1 string to match.
+        if (memcmp(Name.data()+3, "hiscall", 7))
+          break;
+        return AttributeList::AT_ThisCall;	 // "__thiscall"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "ead_write", 9))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "read_write"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+1, "rite_only", 9))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "write_only"
+    }
+    break;
+  case 11:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "__", 2))
+      break;
+    switch (Name[2]) {
+    default: break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+3, "ead_only", 8))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "__read_only"
+    case 'u':	 // 1 string to match.
+      if (memcmp(Name.data()+3, "naligned", 8))
+        break;
+      return AttributeList::IgnoredAttribute;	 // "__unaligned"
+    }
+    break;
+  case 12:	 // 2 strings to match.
+    if (memcmp(Name.data()+0, "__", 2))
+      break;
+    switch (Name[2]) {
+    default: break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(Name.data()+3, "ead_write", 9))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "__read_write"
+    case 'w':	 // 1 string to match.
+      if (memcmp(Name.data()+3, "rite_only", 9))
+        break;
+      return AttributeList::AT_OpenCLImageAccess;	 // "__write_only"
+    }
+    break;
+  case 13:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "__forceinline", 13))
+      break;
+    return AttributeList::AT_AlwaysInline;	 // "__forceinline"
+  case 20:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "__single_inheritance", 20))
+      break;
+    return AttributeList::AT_MSInheritance;	 // "__single_inheritance"
+  case 21:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "__virtual_inheritance", 21))
+      break;
+    return AttributeList::AT_MSInheritance;	 // "__virtual_inheritance"
+  case 22:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "__multiple_inheritance", 22))
+      break;
+    return AttributeList::AT_MSInheritance;	 // "__multiple_inheritance"
+  case 25:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "__unspecified_inheritance", 25))
+      break;
+    return AttributeList::AT_MSInheritance;	 // "__unspecified_inheritance"
+  }
+  } else if (AttributeList::AS_Pragma == Syntax) {
+  switch (Name.size()) {
+  default: break;
+  case 4:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "loop", 4))
+      break;
+    return AttributeList::AT_LoopHint;	 // "loop"
+  case 6:	 // 1 string to match.
+    if (memcmp(Name.data()+0, "unroll", 6))
+      break;
+    return AttributeList::AT_LoopHint;	 // "unroll"
+  }
+  }
+  return AttributeList::UnknownAttribute;
+}
diff --git a/include/clang/Sema/AttrParsedAttrList.inc b/include/clang/Sema/AttrParsedAttrList.inc
new file mode 100644
index 0000000..c19031b
--- /dev/null
+++ b/include/clang/Sema/AttrParsedAttrList.inc
@@ -0,0 +1,183 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*List of all attributes that Clang recognizes                                *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef PARSED_ATTR
+#define PARSED_ATTR(NAME) NAME
+#endif
+
+PARSED_ATTR(Interrupt)
+PARSED_ATTR(AcquireCapability)
+PARSED_ATTR(AcquiredAfter)
+PARSED_ATTR(AcquiredBefore)
+PARSED_ATTR(AddressSpace)
+PARSED_ATTR(Alias)
+PARSED_ATTR(Aligned)
+PARSED_ATTR(AlwaysInline)
+PARSED_ATTR(AnalyzerNoReturn)
+PARSED_ATTR(Annotate)
+PARSED_ATTR(ArcWeakrefUnavailable)
+PARSED_ATTR(ArgumentWithTypeTag)
+PARSED_ATTR(AssertCapability)
+PARSED_ATTR(AssertExclusiveLock)
+PARSED_ATTR(AssertSharedLock)
+PARSED_ATTR(Availability)
+PARSED_ATTR(Blocks)
+PARSED_ATTR(CDecl)
+PARSED_ATTR(CFAuditedTransfer)
+PARSED_ATTR(CFConsumed)
+PARSED_ATTR(CFReturnsNotRetained)
+PARSED_ATTR(CFReturnsRetained)
+PARSED_ATTR(CFUnknownTransfer)
+PARSED_ATTR(CUDAConstant)
+PARSED_ATTR(CUDADevice)
+PARSED_ATTR(CUDAGlobal)
+PARSED_ATTR(CUDAHost)
+PARSED_ATTR(CUDALaunchBounds)
+PARSED_ATTR(CUDAShared)
+PARSED_ATTR(CXX11NoReturn)
+PARSED_ATTR(CallableWhen)
+PARSED_ATTR(Capability)
+PARSED_ATTR(CarriesDependency)
+PARSED_ATTR(Cleanup)
+PARSED_ATTR(Cold)
+PARSED_ATTR(Common)
+PARSED_ATTR(Const)
+PARSED_ATTR(Constructor)
+PARSED_ATTR(Consumable)
+PARSED_ATTR(ConsumableAutoCast)
+PARSED_ATTR(ConsumableSetOnRead)
+PARSED_ATTR(DLLExport)
+PARSED_ATTR(DLLImport)
+PARSED_ATTR(Deprecated)
+PARSED_ATTR(Destructor)
+PARSED_ATTR(EnableIf)
+PARSED_ATTR(ExclusiveTrylockFunction)
+PARSED_ATTR(ExtVectorType)
+PARSED_ATTR(FallThrough)
+PARSED_ATTR(FastCall)
+PARSED_ATTR(Flatten)
+PARSED_ATTR(Format)
+PARSED_ATTR(FormatArg)
+PARSED_ATTR(GNUInline)
+PARSED_ATTR(GuardedBy)
+PARSED_ATTR(GuardedVar)
+PARSED_ATTR(Hot)
+PARSED_ATTR(IBAction)
+PARSED_ATTR(IBOutlet)
+PARSED_ATTR(IBOutletCollection)
+PARSED_ATTR(InitPriority)
+PARSED_ATTR(IntelOclBicc)
+PARSED_ATTR(LockReturned)
+PARSED_ATTR(Lockable)
+PARSED_ATTR(LocksExcluded)
+PARSED_ATTR(LoopHint)
+PARSED_ATTR(MSABI)
+PARSED_ATTR(MSInheritance)
+PARSED_ATTR(Malloc)
+PARSED_ATTR(MayAlias)
+PARSED_ATTR(MinSize)
+PARSED_ATTR(Mips16)
+PARSED_ATTR(Mode)
+PARSED_ATTR(MsStruct)
+PARSED_ATTR(NSConsumed)
+PARSED_ATTR(NSConsumesSelf)
+PARSED_ATTR(NSReturnsAutoreleased)
+PARSED_ATTR(NSReturnsNotRetained)
+PARSED_ATTR(NSReturnsRetained)
+PARSED_ATTR(Naked)
+PARSED_ATTR(NeonPolyVectorType)
+PARSED_ATTR(NeonVectorType)
+PARSED_ATTR(NoCommon)
+PARSED_ATTR(NoDebug)
+PARSED_ATTR(NoDuplicate)
+PARSED_ATTR(NoInline)
+PARSED_ATTR(NoInstrumentFunction)
+PARSED_ATTR(NoMips16)
+PARSED_ATTR(NoReturn)
+PARSED_ATTR(NoSanitizeAddress)
+PARSED_ATTR(NoSanitizeMemory)
+PARSED_ATTR(NoSanitizeThread)
+PARSED_ATTR(NoSplitStack)
+PARSED_ATTR(NoThreadSafetyAnalysis)
+PARSED_ATTR(NoThrow)
+PARSED_ATTR(NonNull)
+PARSED_ATTR(ObjCBridge)
+PARSED_ATTR(ObjCBridgeMutable)
+PARSED_ATTR(ObjCBridgeRelated)
+PARSED_ATTR(ObjCDesignatedInitializer)
+PARSED_ATTR(ObjCException)
+PARSED_ATTR(ObjCExplicitProtocolImpl)
+PARSED_ATTR(ObjCGC)
+PARSED_ATTR(ObjCMethodFamily)
+PARSED_ATTR(ObjCNSObject)
+PARSED_ATTR(ObjCOwnership)
+PARSED_ATTR(ObjCPreciseLifetime)
+PARSED_ATTR(ObjCRequiresPropertyDefs)
+PARSED_ATTR(ObjCRequiresSuper)
+PARSED_ATTR(ObjCReturnsInnerPointer)
+PARSED_ATTR(ObjCRootClass)
+PARSED_ATTR(ObjCRuntimeName)
+PARSED_ATTR(OpenCLConstantAddressSpace)
+PARSED_ATTR(OpenCLGlobalAddressSpace)
+PARSED_ATTR(OpenCLImageAccess)
+PARSED_ATTR(OpenCLKernel)
+PARSED_ATTR(OpenCLLocalAddressSpace)
+PARSED_ATTR(OpenCLPrivateAddressSpace)
+PARSED_ATTR(OptimizeNone)
+PARSED_ATTR(Overloadable)
+PARSED_ATTR(Ownership)
+PARSED_ATTR(Packed)
+PARSED_ATTR(ParamTypestate)
+PARSED_ATTR(Pascal)
+PARSED_ATTR(Pcs)
+PARSED_ATTR(PnaclCall)
+PARSED_ATTR(PtGuardedBy)
+PARSED_ATTR(PtGuardedVar)
+PARSED_ATTR(Ptr32)
+PARSED_ATTR(Ptr64)
+PARSED_ATTR(Pure)
+PARSED_ATTR(Regparm)
+PARSED_ATTR(ReleaseCapability)
+PARSED_ATTR(ReqdWorkGroupSize)
+PARSED_ATTR(RequiresCapability)
+PARSED_ATTR(ReturnTypestate)
+PARSED_ATTR(ReturnsNonNull)
+PARSED_ATTR(ReturnsTwice)
+PARSED_ATTR(SPtr)
+PARSED_ATTR(ScopedLockable)
+PARSED_ATTR(Section)
+PARSED_ATTR(SelectAny)
+PARSED_ATTR(Sentinel)
+PARSED_ATTR(SetTypestate)
+PARSED_ATTR(SharedTrylockFunction)
+PARSED_ATTR(StdCall)
+PARSED_ATTR(SysVABI)
+PARSED_ATTR(TLSModel)
+PARSED_ATTR(TestTypestate)
+PARSED_ATTR(ThisCall)
+PARSED_ATTR(Thread)
+PARSED_ATTR(TransparentUnion)
+PARSED_ATTR(TryAcquireCapability)
+PARSED_ATTR(TypeTagForDatatype)
+PARSED_ATTR(TypeVisibility)
+PARSED_ATTR(UPtr)
+PARSED_ATTR(Unavailable)
+PARSED_ATTR(Unused)
+PARSED_ATTR(Used)
+PARSED_ATTR(Uuid)
+PARSED_ATTR(VecReturn)
+PARSED_ATTR(VecTypeHint)
+PARSED_ATTR(VectorSize)
+PARSED_ATTR(Visibility)
+PARSED_ATTR(WarnUnused)
+PARSED_ATTR(WarnUnusedResult)
+PARSED_ATTR(Weak)
+PARSED_ATTR(WeakImport)
+PARSED_ATTR(WeakRef)
+PARSED_ATTR(WorkGroupSizeHint)
+PARSED_ATTR(X86ForceAlignArgPointer)
diff --git a/include/clang/Sema/AttrSpellingListIndex.inc b/include/clang/Sema/AttrSpellingListIndex.inc
new file mode 100644
index 0000000..9fdd1ea
--- /dev/null
+++ b/include/clang/Sema/AttrSpellingListIndex.inc
@@ -0,0 +1,1127 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Code to translate different attribute spellings into internal identifiers   *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+  switch (AttrKind) {
+  default:
+    llvm_unreachable("Unknown attribute kind!");
+    break;
+  case AT_Interrupt: {
+    if (Name == "interrupt" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_AcquireCapability: {
+    if (Name == "acquire_capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "acquire_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "acquire_shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "acquire_shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 3;
+    if (Name == "exclusive_lock_function" && SyntaxUsed == 0 && Scope == "")
+        return 4;
+    if (Name == "shared_lock_function" && SyntaxUsed == 0 && Scope == "")
+        return 5;
+    break;
+  }
+  case AT_AcquiredAfter: {
+    if (Name == "acquired_after" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_AcquiredBefore: {
+    if (Name == "acquired_before" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_AddressSpace: {
+    if (Name == "address_space" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Alias: {
+    if (Name == "alias" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "alias" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Aligned: {
+    if (Name == "aligned" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "aligned" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "align" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    if (Name == "alignas" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    if (Name == "_Alignas" && SyntaxUsed == 3 && Scope == "")
+        return 4;
+    break;
+  }
+  case AT_AlwaysInline: {
+    if (Name == "always_inline" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "always_inline" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__forceinline" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_AnalyzerNoReturn: {
+    if (Name == "analyzer_noreturn" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Annotate: {
+    if (Name == "annotate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ArcWeakrefUnavailable: {
+    if (Name == "objc_arc_weak_reference_unavailable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ArgumentWithTypeTag: {
+    if (Name == "argument_with_type_tag" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "pointer_with_type_tag" && SyntaxUsed == 0 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_AssertCapability: {
+    if (Name == "assert_capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "assert_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "assert_shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "assert_shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 3;
+    break;
+  }
+  case AT_AssertExclusiveLock: {
+    if (Name == "assert_exclusive_lock" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_AssertSharedLock: {
+    if (Name == "assert_shared_lock" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Availability: {
+    if (Name == "availability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Blocks: {
+    if (Name == "blocks" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CDecl: {
+    if (Name == "cdecl" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "cdecl" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__cdecl" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "_cdecl" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_CFAuditedTransfer: {
+    if (Name == "cf_audited_transfer" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CFConsumed: {
+    if (Name == "cf_consumed" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CFReturnsNotRetained: {
+    if (Name == "cf_returns_not_retained" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CFReturnsRetained: {
+    if (Name == "cf_returns_retained" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CFUnknownTransfer: {
+    if (Name == "cf_unknown_transfer" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDAConstant: {
+    if (Name == "constant" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDADevice: {
+    if (Name == "device" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDAGlobal: {
+    if (Name == "global" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDAHost: {
+    if (Name == "host" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDALaunchBounds: {
+    if (Name == "launch_bounds" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CUDAShared: {
+    if (Name == "shared" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CXX11NoReturn: {
+    if (Name == "noreturn" && SyntaxUsed == 1 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_CallableWhen: {
+    if (Name == "callable_when" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Capability: {
+    if (Name == "capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 3;
+    break;
+  }
+  case AT_CarriesDependency: {
+    if (Name == "carries_dependency" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "carries_dependency" && SyntaxUsed == 1 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_Cleanup: {
+    if (Name == "cleanup" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "cleanup" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Cold: {
+    if (Name == "cold" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "cold" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Common: {
+    if (Name == "common" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "common" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Const: {
+    if (Name == "const" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "const" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__const" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "__const" && SyntaxUsed == 1 && Scope == "gnu")
+        return 3;
+    break;
+  }
+  case AT_Constructor: {
+    if (Name == "constructor" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "constructor" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Consumable: {
+    if (Name == "consumable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ConsumableAutoCast: {
+    if (Name == "consumable_auto_cast_state" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ConsumableSetOnRead: {
+    if (Name == "consumable_set_state_on_read" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_DLLExport: {
+    if (Name == "dllexport" && SyntaxUsed == 2 && Scope == "")
+        return 0;
+    if (Name == "dllexport" && SyntaxUsed == 0 && Scope == "")
+        return 1;
+    if (Name == "dllexport" && SyntaxUsed == 1 && Scope == "gnu")
+        return 2;
+    break;
+  }
+  case AT_DLLImport: {
+    if (Name == "dllimport" && SyntaxUsed == 2 && Scope == "")
+        return 0;
+    if (Name == "dllimport" && SyntaxUsed == 0 && Scope == "")
+        return 1;
+    if (Name == "dllimport" && SyntaxUsed == 1 && Scope == "gnu")
+        return 2;
+    break;
+  }
+  case AT_Deprecated: {
+    if (Name == "deprecated" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "deprecated" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "deprecated" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    if (Name == "deprecated" && SyntaxUsed == 1 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_Destructor: {
+    if (Name == "destructor" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "destructor" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_EnableIf: {
+    if (Name == "enable_if" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ExclusiveTrylockFunction: {
+    if (Name == "exclusive_trylock_function" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ExtVectorType: {
+    if (Name == "ext_vector_type" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_FallThrough: {
+    if (Name == "fallthrough" && SyntaxUsed == 1 && Scope == "clang")
+        return 0;
+    break;
+  }
+  case AT_FastCall: {
+    if (Name == "fastcall" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "fastcall" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__fastcall" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "_fastcall" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_Flatten: {
+    if (Name == "flatten" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "flatten" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Format: {
+    if (Name == "format" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "format" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_FormatArg: {
+    if (Name == "format_arg" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "format_arg" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_GNUInline: {
+    if (Name == "gnu_inline" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "gnu_inline" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_GuardedBy: {
+    if (Name == "guarded_by" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_GuardedVar: {
+    if (Name == "guarded_var" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Hot: {
+    if (Name == "hot" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "hot" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_IBAction: {
+    if (Name == "ibaction" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_IBOutlet: {
+    if (Name == "iboutlet" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_IBOutletCollection: {
+    if (Name == "iboutletcollection" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_InitPriority: {
+    if (Name == "init_priority" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_IntelOclBicc: {
+    if (Name == "intel_ocl_bicc" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_LockReturned: {
+    if (Name == "lock_returned" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Lockable: {
+    if (Name == "lockable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_LocksExcluded: {
+    if (Name == "locks_excluded" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_LoopHint: {
+    if (Name == "loop" && SyntaxUsed == 4 && Scope == "clang")
+        return 0;
+    if (Name == "unroll" && SyntaxUsed == 4 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_MSABI: {
+    if (Name == "ms_abi" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "ms_abi" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_MSInheritance: {
+    if (Name == "__single_inheritance" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "__multiple_inheritance" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    if (Name == "__virtual_inheritance" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "__unspecified_inheritance" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_Malloc: {
+    if (Name == "malloc" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "malloc" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_MayAlias: {
+    if (Name == "may_alias" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "may_alias" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_MinSize: {
+    if (Name == "minsize" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Mips16: {
+    if (Name == "mips16" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "mips16" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Mode: {
+    if (Name == "mode" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "mode" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_MsStruct: {
+    if (Name == "ms_struct" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "ms_struct" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_NSConsumed: {
+    if (Name == "ns_consumed" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NSConsumesSelf: {
+    if (Name == "ns_consumes_self" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NSReturnsAutoreleased: {
+    if (Name == "ns_returns_autoreleased" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NSReturnsNotRetained: {
+    if (Name == "ns_returns_not_retained" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NSReturnsRetained: {
+    if (Name == "ns_returns_retained" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Naked: {
+    if (Name == "naked" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "naked" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "naked" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_NeonPolyVectorType: {
+    if (Name == "neon_polyvector_type" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NeonVectorType: {
+    if (Name == "neon_vector_type" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NoCommon: {
+    if (Name == "nocommon" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "nocommon" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_NoDebug: {
+    if (Name == "nodebug" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NoDuplicate: {
+    if (Name == "noduplicate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "noduplicate" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    break;
+  }
+  case AT_NoInline: {
+    if (Name == "noinline" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "noinline" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "noinline" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_NoInstrumentFunction: {
+    if (Name == "no_instrument_function" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "no_instrument_function" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_NoMips16: {
+    if (Name == "nomips16" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "nomips16" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_NoReturn: {
+    if (Name == "noreturn" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "noreturn" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "noreturn" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_NoSanitizeAddress: {
+    if (Name == "no_address_safety_analysis" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "no_address_safety_analysis" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "no_sanitize_address" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "no_sanitize_address" && SyntaxUsed == 1 && Scope == "gnu")
+        return 3;
+    break;
+  }
+  case AT_NoSanitizeMemory: {
+    if (Name == "no_sanitize_memory" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NoSanitizeThread: {
+    if (Name == "no_sanitize_thread" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NoSplitStack: {
+    if (Name == "no_split_stack" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "no_split_stack" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_NoThreadSafetyAnalysis: {
+    if (Name == "no_thread_safety_analysis" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_NoThrow: {
+    if (Name == "nothrow" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "nothrow" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "nothrow" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_NonNull: {
+    if (Name == "nonnull" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "nonnull" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_ObjCBridge: {
+    if (Name == "objc_bridge" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCBridgeMutable: {
+    if (Name == "objc_bridge_mutable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCBridgeRelated: {
+    if (Name == "objc_bridge_related" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCDesignatedInitializer: {
+    if (Name == "objc_designated_initializer" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCException: {
+    if (Name == "objc_exception" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCExplicitProtocolImpl: {
+    if (Name == "objc_protocol_requires_explicit_implementation" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCGC: {
+    if (Name == "objc_gc" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCMethodFamily: {
+    if (Name == "objc_method_family" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCNSObject: {
+    if (Name == "NSObject" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCOwnership: {
+    if (Name == "objc_ownership" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCPreciseLifetime: {
+    if (Name == "objc_precise_lifetime" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCRequiresPropertyDefs: {
+    if (Name == "objc_requires_property_definitions" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCRequiresSuper: {
+    if (Name == "objc_requires_super" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCReturnsInnerPointer: {
+    if (Name == "objc_returns_inner_pointer" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCRootClass: {
+    if (Name == "objc_root_class" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ObjCRuntimeName: {
+    if (Name == "objc_runtime_name" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_OpenCLConstantAddressSpace: {
+    if (Name == "__constant" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "constant" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_OpenCLGlobalAddressSpace: {
+    if (Name == "__global" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "global" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_OpenCLImageAccess: {
+    if (Name == "__read_only" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "read_only" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    if (Name == "__write_only" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "write_only" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    if (Name == "__read_write" && SyntaxUsed == 3 && Scope == "")
+        return 4;
+    if (Name == "read_write" && SyntaxUsed == 3 && Scope == "")
+        return 5;
+    break;
+  }
+  case AT_OpenCLKernel: {
+    if (Name == "__kernel" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "kernel" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_OpenCLLocalAddressSpace: {
+    if (Name == "__local" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "local" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_OpenCLPrivateAddressSpace: {
+    if (Name == "__private" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    if (Name == "private" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    break;
+  }
+  case AT_OptimizeNone: {
+    if (Name == "optnone" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "optnone" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    break;
+  }
+  case AT_Overloadable: {
+    if (Name == "overloadable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Ownership: {
+    if (Name == "ownership_holds" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "ownership_returns" && SyntaxUsed == 0 && Scope == "")
+        return 1;
+    if (Name == "ownership_takes" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_Packed: {
+    if (Name == "packed" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "packed" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_ParamTypestate: {
+    if (Name == "param_typestate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Pascal: {
+    if (Name == "pascal" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "__pascal" && SyntaxUsed == 3 && Scope == "")
+        return 1;
+    if (Name == "_pascal" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_Pcs: {
+    if (Name == "pcs" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "pcs" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_PnaclCall: {
+    if (Name == "pnaclcall" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_PtGuardedBy: {
+    if (Name == "pt_guarded_by" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_PtGuardedVar: {
+    if (Name == "pt_guarded_var" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Ptr32: {
+    if (Name == "__ptr32" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Ptr64: {
+    if (Name == "__ptr64" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Pure: {
+    if (Name == "pure" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "pure" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Regparm: {
+    if (Name == "regparm" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "regparm" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_ReleaseCapability: {
+    if (Name == "release_capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "release_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "release_shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "release_shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 3;
+    if (Name == "release_generic_capability" && SyntaxUsed == 0 && Scope == "")
+        return 4;
+    if (Name == "release_generic_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 5;
+    if (Name == "unlock_function" && SyntaxUsed == 0 && Scope == "")
+        return 6;
+    break;
+  }
+  case AT_ReqdWorkGroupSize: {
+    if (Name == "reqd_work_group_size" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_RequiresCapability: {
+    if (Name == "requires_capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "requires_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "exclusive_locks_required" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "requires_shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 3;
+    if (Name == "requires_shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 4;
+    if (Name == "shared_locks_required" && SyntaxUsed == 0 && Scope == "")
+        return 5;
+    break;
+  }
+  case AT_ReturnTypestate: {
+    if (Name == "return_typestate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ReturnsNonNull: {
+    if (Name == "returns_nonnull" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "returns_nonnull" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_ReturnsTwice: {
+    if (Name == "returns_twice" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "returns_twice" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_SPtr: {
+    if (Name == "__sptr" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ScopedLockable: {
+    if (Name == "scoped_lockable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Section: {
+    if (Name == "section" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "section" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "allocate" && SyntaxUsed == 2 && Scope == "")
+        return 2;
+    break;
+  }
+  case AT_SelectAny: {
+    if (Name == "selectany" && SyntaxUsed == 2 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Sentinel: {
+    if (Name == "sentinel" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "sentinel" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_SetTypestate: {
+    if (Name == "set_typestate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_SharedTrylockFunction: {
+    if (Name == "shared_trylock_function" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_StdCall: {
+    if (Name == "stdcall" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "stdcall" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__stdcall" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "_stdcall" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_SysVABI: {
+    if (Name == "sysv_abi" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "sysv_abi" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_TLSModel: {
+    if (Name == "tls_model" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "tls_model" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_TestTypestate: {
+    if (Name == "test_typestate" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_ThisCall: {
+    if (Name == "thiscall" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "thiscall" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "__thiscall" && SyntaxUsed == 3 && Scope == "")
+        return 2;
+    if (Name == "_thiscall" && SyntaxUsed == 3 && Scope == "")
+        return 3;
+    break;
+  }
+  case AT_Thread: {
+    if (Name == "thread" && SyntaxUsed == 2 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_TransparentUnion: {
+    if (Name == "transparent_union" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "transparent_union" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_TryAcquireCapability: {
+    if (Name == "try_acquire_capability" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "try_acquire_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    if (Name == "try_acquire_shared_capability" && SyntaxUsed == 0 && Scope == "")
+        return 2;
+    if (Name == "try_acquire_shared_capability" && SyntaxUsed == 1 && Scope == "clang")
+        return 3;
+    break;
+  }
+  case AT_TypeTagForDatatype: {
+    if (Name == "type_tag_for_datatype" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_TypeVisibility: {
+    if (Name == "type_visibility" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "type_visibility" && SyntaxUsed == 1 && Scope == "clang")
+        return 1;
+    break;
+  }
+  case AT_UPtr: {
+    if (Name == "__uptr" && SyntaxUsed == 3 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Unavailable: {
+    if (Name == "unavailable" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_Unused: {
+    if (Name == "unused" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "unused" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Used: {
+    if (Name == "used" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "used" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Uuid: {
+    if (Name == "uuid" && SyntaxUsed == 2 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_VecReturn: {
+    if (Name == "vecreturn" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_VecTypeHint: {
+    if (Name == "vec_type_hint" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_VectorSize: {
+    if (Name == "vector_size" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "vector_size" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_Visibility: {
+    if (Name == "visibility" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "visibility" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_WarnUnused: {
+    if (Name == "warn_unused" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_WarnUnusedResult: {
+    if (Name == "warn_unused_result" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "warn_unused_result" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    if (Name == "warn_unused_result" && SyntaxUsed == 1 && Scope == "clang")
+        return 2;
+    break;
+  }
+  case AT_Weak: {
+    if (Name == "weak" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "weak" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_WeakImport: {
+    if (Name == "weak_import" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_WeakRef: {
+    if (Name == "weakref" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    if (Name == "weakref" && SyntaxUsed == 1 && Scope == "gnu")
+        return 1;
+    break;
+  }
+  case AT_WorkGroupSizeHint: {
+    if (Name == "work_group_size_hint" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  case AT_X86ForceAlignArgPointer: {
+    if (Name == "force_align_arg_pointer" && SyntaxUsed == 0 && Scope == "")
+        return 0;
+    break;
+  }
+  }
+  return 0;
diff --git a/include/clang/Sema/AttrTemplateInstantiate.inc b/include/clang/Sema/AttrTemplateInstantiate.inc
new file mode 100644
index 0000000..a4291f1
--- /dev/null
+++ b/include/clang/Sema/AttrTemplateInstantiate.inc
@@ -0,0 +1,842 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Template instantiation code for attributes                                  *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+namespace clang {
+namespace sema {
+
+Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
+        const MultiLevelTemplateArgumentList &TemplateArgs) {
+  switch (At->getKind()) {
+    default:
+      break;
+    case attr::ARMInterrupt: {
+      const ARMInterruptAttr *A = cast<ARMInterruptAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AcquireCapability: {
+      const AcquireCapabilityAttr *A = cast<AcquireCapabilityAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) AcquireCapabilityAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::AcquiredAfter: {
+      const AcquiredAfterAttr *A = cast<AcquiredAfterAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) AcquiredAfterAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::AcquiredBefore: {
+      const AcquiredBeforeAttr *A = cast<AcquiredBeforeAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) AcquiredBeforeAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::Alias: {
+      const AliasAttr *A = cast<AliasAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AlignMac68k: {
+      const AlignMac68kAttr *A = cast<AlignMac68kAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Aligned: {
+      const AlignedAttr *A = cast<AlignedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AlwaysInline: {
+      const AlwaysInlineAttr *A = cast<AlwaysInlineAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AnalyzerNoReturn: {
+      const AnalyzerNoReturnAttr *A = cast<AnalyzerNoReturnAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Annotate: {
+      const AnnotateAttr *A = cast<AnnotateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ArcWeakrefUnavailable: {
+      const ArcWeakrefUnavailableAttr *A = cast<ArcWeakrefUnavailableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ArgumentWithTypeTag: {
+      const ArgumentWithTypeTagAttr *A = cast<ArgumentWithTypeTagAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AsmLabel: {
+      const AsmLabelAttr *A = cast<AsmLabelAttr>(At);
+      return A->clone(C);
+    }
+    case attr::AssertCapability: {
+      const AssertCapabilityAttr *A = cast<AssertCapabilityAttr>(At);
+      Expr * tempInstExpr;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getExpr(), TemplateArgs);
+        tempInstExpr = Result.getAs<Expr>();
+      }
+      return new (C) AssertCapabilityAttr(A->getLocation(), C, tempInstExpr, A->getSpellingListIndex());
+    }
+    case attr::AssertExclusiveLock: {
+      const AssertExclusiveLockAttr *A = cast<AssertExclusiveLockAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) AssertExclusiveLockAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::AssertSharedLock: {
+      const AssertSharedLockAttr *A = cast<AssertSharedLockAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) AssertSharedLockAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::Availability: {
+      const AvailabilityAttr *A = cast<AvailabilityAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Blocks: {
+      const BlocksAttr *A = cast<BlocksAttr>(At);
+      return A->clone(C);
+    }
+    case attr::C11NoReturn: {
+      const C11NoReturnAttr *A = cast<C11NoReturnAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CDecl: {
+      const CDeclAttr *A = cast<CDeclAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CFAuditedTransfer: {
+      const CFAuditedTransferAttr *A = cast<CFAuditedTransferAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CFConsumed: {
+      const CFConsumedAttr *A = cast<CFConsumedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CFReturnsNotRetained: {
+      const CFReturnsNotRetainedAttr *A = cast<CFReturnsNotRetainedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CFReturnsRetained: {
+      const CFReturnsRetainedAttr *A = cast<CFReturnsRetainedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CFUnknownTransfer: {
+      const CFUnknownTransferAttr *A = cast<CFUnknownTransferAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDAConstant: {
+      const CUDAConstantAttr *A = cast<CUDAConstantAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDADevice: {
+      const CUDADeviceAttr *A = cast<CUDADeviceAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDAGlobal: {
+      const CUDAGlobalAttr *A = cast<CUDAGlobalAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDAHost: {
+      const CUDAHostAttr *A = cast<CUDAHostAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDALaunchBounds: {
+      const CUDALaunchBoundsAttr *A = cast<CUDALaunchBoundsAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CUDAShared: {
+      const CUDASharedAttr *A = cast<CUDASharedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CXX11NoReturn: {
+      const CXX11NoReturnAttr *A = cast<CXX11NoReturnAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CallableWhen: {
+      const CallableWhenAttr *A = cast<CallableWhenAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Capability: {
+      const CapabilityAttr *A = cast<CapabilityAttr>(At);
+      return A->clone(C);
+    }
+    case attr::CarriesDependency: {
+      const CarriesDependencyAttr *A = cast<CarriesDependencyAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Cleanup: {
+      const CleanupAttr *A = cast<CleanupAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Cold: {
+      const ColdAttr *A = cast<ColdAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Common: {
+      const CommonAttr *A = cast<CommonAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Const: {
+      const ConstAttr *A = cast<ConstAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Constructor: {
+      const ConstructorAttr *A = cast<ConstructorAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Consumable: {
+      const ConsumableAttr *A = cast<ConsumableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ConsumableAutoCast: {
+      const ConsumableAutoCastAttr *A = cast<ConsumableAutoCastAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ConsumableSetOnRead: {
+      const ConsumableSetOnReadAttr *A = cast<ConsumableSetOnReadAttr>(At);
+      return A->clone(C);
+    }
+    case attr::DLLExport: {
+      const DLLExportAttr *A = cast<DLLExportAttr>(At);
+      return A->clone(C);
+    }
+    case attr::DLLImport: {
+      const DLLImportAttr *A = cast<DLLImportAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Deprecated: {
+      const DeprecatedAttr *A = cast<DeprecatedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Destructor: {
+      const DestructorAttr *A = cast<DestructorAttr>(At);
+      return A->clone(C);
+    }
+    case attr::EnableIf: {
+      const EnableIfAttr *A = cast<EnableIfAttr>(At);
+      Expr * tempInstCond;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs);
+        tempInstCond = Result.getAs<Expr>();
+      }
+      return new (C) EnableIfAttr(A->getLocation(), C, tempInstCond, A->getMessage(), A->getSpellingListIndex());
+    }
+    case attr::ExclusiveTrylockFunction: {
+      const ExclusiveTrylockFunctionAttr *A = cast<ExclusiveTrylockFunctionAttr>(At);
+      Expr * tempInstSuccessValue;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getSuccessValue(), TemplateArgs);
+        tempInstSuccessValue = Result.getAs<Expr>();
+      }
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) ExclusiveTrylockFunctionAttr(A->getLocation(), C, tempInstSuccessValue, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::FallThrough: {
+      const FallThroughAttr *A = cast<FallThroughAttr>(At);
+      return A->clone(C);
+    }
+    case attr::FastCall: {
+      const FastCallAttr *A = cast<FastCallAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Final: {
+      const FinalAttr *A = cast<FinalAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Flatten: {
+      const FlattenAttr *A = cast<FlattenAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Format: {
+      const FormatAttr *A = cast<FormatAttr>(At);
+      return A->clone(C);
+    }
+    case attr::FormatArg: {
+      const FormatArgAttr *A = cast<FormatArgAttr>(At);
+      return A->clone(C);
+    }
+    case attr::GNUInline: {
+      const GNUInlineAttr *A = cast<GNUInlineAttr>(At);
+      return A->clone(C);
+    }
+    case attr::GuardedBy: {
+      const GuardedByAttr *A = cast<GuardedByAttr>(At);
+      Expr * tempInstArg;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getArg(), TemplateArgs);
+        tempInstArg = Result.getAs<Expr>();
+      }
+      return new (C) GuardedByAttr(A->getLocation(), C, tempInstArg, A->getSpellingListIndex());
+    }
+    case attr::GuardedVar: {
+      const GuardedVarAttr *A = cast<GuardedVarAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Hot: {
+      const HotAttr *A = cast<HotAttr>(At);
+      return A->clone(C);
+    }
+    case attr::IBAction: {
+      const IBActionAttr *A = cast<IBActionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::IBOutlet: {
+      const IBOutletAttr *A = cast<IBOutletAttr>(At);
+      return A->clone(C);
+    }
+    case attr::IBOutletCollection: {
+      const IBOutletCollectionAttr *A = cast<IBOutletCollectionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::InitPriority: {
+      const InitPriorityAttr *A = cast<InitPriorityAttr>(At);
+      return A->clone(C);
+    }
+    case attr::InitSeg: {
+      const InitSegAttr *A = cast<InitSegAttr>(At);
+      return A->clone(C);
+    }
+    case attr::IntelOclBicc: {
+      const IntelOclBiccAttr *A = cast<IntelOclBiccAttr>(At);
+      return A->clone(C);
+    }
+    case attr::LockReturned: {
+      const LockReturnedAttr *A = cast<LockReturnedAttr>(At);
+      Expr * tempInstArg;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getArg(), TemplateArgs);
+        tempInstArg = Result.getAs<Expr>();
+      }
+      return new (C) LockReturnedAttr(A->getLocation(), C, tempInstArg, A->getSpellingListIndex());
+    }
+    case attr::LocksExcluded: {
+      const LocksExcludedAttr *A = cast<LocksExcludedAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) LocksExcludedAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::LoopHint: {
+      const LoopHintAttr *A = cast<LoopHintAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MSABI: {
+      const MSABIAttr *A = cast<MSABIAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MSInheritance: {
+      const MSInheritanceAttr *A = cast<MSInheritanceAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MSP430Interrupt: {
+      const MSP430InterruptAttr *A = cast<MSP430InterruptAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MSVtorDisp: {
+      const MSVtorDispAttr *A = cast<MSVtorDispAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Malloc: {
+      const MallocAttr *A = cast<MallocAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MaxFieldAlignment: {
+      const MaxFieldAlignmentAttr *A = cast<MaxFieldAlignmentAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MayAlias: {
+      const MayAliasAttr *A = cast<MayAliasAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MinSize: {
+      const MinSizeAttr *A = cast<MinSizeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Mips16: {
+      const Mips16Attr *A = cast<Mips16Attr>(At);
+      return A->clone(C);
+    }
+    case attr::Mode: {
+      const ModeAttr *A = cast<ModeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::MsStruct: {
+      const MsStructAttr *A = cast<MsStructAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NSConsumed: {
+      const NSConsumedAttr *A = cast<NSConsumedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NSConsumesSelf: {
+      const NSConsumesSelfAttr *A = cast<NSConsumesSelfAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NSReturnsAutoreleased: {
+      const NSReturnsAutoreleasedAttr *A = cast<NSReturnsAutoreleasedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NSReturnsNotRetained: {
+      const NSReturnsNotRetainedAttr *A = cast<NSReturnsNotRetainedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NSReturnsRetained: {
+      const NSReturnsRetainedAttr *A = cast<NSReturnsRetainedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Naked: {
+      const NakedAttr *A = cast<NakedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoCommon: {
+      const NoCommonAttr *A = cast<NoCommonAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoDebug: {
+      const NoDebugAttr *A = cast<NoDebugAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoDuplicate: {
+      const NoDuplicateAttr *A = cast<NoDuplicateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoInline: {
+      const NoInlineAttr *A = cast<NoInlineAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoInstrumentFunction: {
+      const NoInstrumentFunctionAttr *A = cast<NoInstrumentFunctionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoMips16: {
+      const NoMips16Attr *A = cast<NoMips16Attr>(At);
+      return A->clone(C);
+    }
+    case attr::NoReturn: {
+      const NoReturnAttr *A = cast<NoReturnAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoSanitizeAddress: {
+      const NoSanitizeAddressAttr *A = cast<NoSanitizeAddressAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoSanitizeMemory: {
+      const NoSanitizeMemoryAttr *A = cast<NoSanitizeMemoryAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoSanitizeThread: {
+      const NoSanitizeThreadAttr *A = cast<NoSanitizeThreadAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoSplitStack: {
+      const NoSplitStackAttr *A = cast<NoSplitStackAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoThreadSafetyAnalysis: {
+      const NoThreadSafetyAnalysisAttr *A = cast<NoThreadSafetyAnalysisAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NoThrow: {
+      const NoThrowAttr *A = cast<NoThrowAttr>(At);
+      return A->clone(C);
+    }
+    case attr::NonNull: {
+      const NonNullAttr *A = cast<NonNullAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCBridge: {
+      const ObjCBridgeAttr *A = cast<ObjCBridgeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCBridgeMutable: {
+      const ObjCBridgeMutableAttr *A = cast<ObjCBridgeMutableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCBridgeRelated: {
+      const ObjCBridgeRelatedAttr *A = cast<ObjCBridgeRelatedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCDesignatedInitializer: {
+      const ObjCDesignatedInitializerAttr *A = cast<ObjCDesignatedInitializerAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCException: {
+      const ObjCExceptionAttr *A = cast<ObjCExceptionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCExplicitProtocolImpl: {
+      const ObjCExplicitProtocolImplAttr *A = cast<ObjCExplicitProtocolImplAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCMethodFamily: {
+      const ObjCMethodFamilyAttr *A = cast<ObjCMethodFamilyAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCNSObject: {
+      const ObjCNSObjectAttr *A = cast<ObjCNSObjectAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCPreciseLifetime: {
+      const ObjCPreciseLifetimeAttr *A = cast<ObjCPreciseLifetimeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCRequiresPropertyDefs: {
+      const ObjCRequiresPropertyDefsAttr *A = cast<ObjCRequiresPropertyDefsAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCRequiresSuper: {
+      const ObjCRequiresSuperAttr *A = cast<ObjCRequiresSuperAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCReturnsInnerPointer: {
+      const ObjCReturnsInnerPointerAttr *A = cast<ObjCReturnsInnerPointerAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCRootClass: {
+      const ObjCRootClassAttr *A = cast<ObjCRootClassAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ObjCRuntimeName: {
+      const ObjCRuntimeNameAttr *A = cast<ObjCRuntimeNameAttr>(At);
+      return A->clone(C);
+    }
+    case attr::OpenCLImageAccess: {
+      const OpenCLImageAccessAttr *A = cast<OpenCLImageAccessAttr>(At);
+      return A->clone(C);
+    }
+    case attr::OpenCLKernel: {
+      const OpenCLKernelAttr *A = cast<OpenCLKernelAttr>(At);
+      return A->clone(C);
+    }
+    case attr::OptimizeNone: {
+      const OptimizeNoneAttr *A = cast<OptimizeNoneAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Overloadable: {
+      const OverloadableAttr *A = cast<OverloadableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Override: {
+      const OverrideAttr *A = cast<OverrideAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Ownership: {
+      const OwnershipAttr *A = cast<OwnershipAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Packed: {
+      const PackedAttr *A = cast<PackedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ParamTypestate: {
+      const ParamTypestateAttr *A = cast<ParamTypestateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Pascal: {
+      const PascalAttr *A = cast<PascalAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Pcs: {
+      const PcsAttr *A = cast<PcsAttr>(At);
+      return A->clone(C);
+    }
+    case attr::PnaclCall: {
+      const PnaclCallAttr *A = cast<PnaclCallAttr>(At);
+      return A->clone(C);
+    }
+    case attr::PtGuardedBy: {
+      const PtGuardedByAttr *A = cast<PtGuardedByAttr>(At);
+      Expr * tempInstArg;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getArg(), TemplateArgs);
+        tempInstArg = Result.getAs<Expr>();
+      }
+      return new (C) PtGuardedByAttr(A->getLocation(), C, tempInstArg, A->getSpellingListIndex());
+    }
+    case attr::PtGuardedVar: {
+      const PtGuardedVarAttr *A = cast<PtGuardedVarAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Pure: {
+      const PureAttr *A = cast<PureAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ReleaseCapability: {
+      const ReleaseCapabilityAttr *A = cast<ReleaseCapabilityAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) ReleaseCapabilityAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::ReqdWorkGroupSize: {
+      const ReqdWorkGroupSizeAttr *A = cast<ReqdWorkGroupSizeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::RequiresCapability: {
+      const RequiresCapabilityAttr *A = cast<RequiresCapabilityAttr>(At);
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) RequiresCapabilityAttr(A->getLocation(), C, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::ReturnTypestate: {
+      const ReturnTypestateAttr *A = cast<ReturnTypestateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ReturnsNonNull: {
+      const ReturnsNonNullAttr *A = cast<ReturnsNonNullAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ReturnsTwice: {
+      const ReturnsTwiceAttr *A = cast<ReturnsTwiceAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ScopedLockable: {
+      const ScopedLockableAttr *A = cast<ScopedLockableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Section: {
+      const SectionAttr *A = cast<SectionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::SelectAny: {
+      const SelectAnyAttr *A = cast<SelectAnyAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Sentinel: {
+      const SentinelAttr *A = cast<SentinelAttr>(At);
+      return A->clone(C);
+    }
+    case attr::SetTypestate: {
+      const SetTypestateAttr *A = cast<SetTypestateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::SharedTrylockFunction: {
+      const SharedTrylockFunctionAttr *A = cast<SharedTrylockFunctionAttr>(At);
+      Expr * tempInstSuccessValue;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getSuccessValue(), TemplateArgs);
+        tempInstSuccessValue = Result.getAs<Expr>();
+      }
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) SharedTrylockFunctionAttr(A->getLocation(), C, tempInstSuccessValue, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::StdCall: {
+      const StdCallAttr *A = cast<StdCallAttr>(At);
+      return A->clone(C);
+    }
+    case attr::SysVABI: {
+      const SysVABIAttr *A = cast<SysVABIAttr>(At);
+      return A->clone(C);
+    }
+    case attr::TLSModel: {
+      const TLSModelAttr *A = cast<TLSModelAttr>(At);
+      return A->clone(C);
+    }
+    case attr::TestTypestate: {
+      const TestTypestateAttr *A = cast<TestTypestateAttr>(At);
+      return A->clone(C);
+    }
+    case attr::ThisCall: {
+      const ThisCallAttr *A = cast<ThisCallAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Thread: {
+      const ThreadAttr *A = cast<ThreadAttr>(At);
+      return A->clone(C);
+    }
+    case attr::TransparentUnion: {
+      const TransparentUnionAttr *A = cast<TransparentUnionAttr>(At);
+      return A->clone(C);
+    }
+    case attr::TryAcquireCapability: {
+      const TryAcquireCapabilityAttr *A = cast<TryAcquireCapabilityAttr>(At);
+      Expr * tempInstSuccessValue;
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        ExprResult Result = S.SubstExpr(A->getSuccessValue(), TemplateArgs);
+        tempInstSuccessValue = Result.getAs<Expr>();
+      }
+      Expr * *tempInstArgs = new (C, 16) Expr *[A->args_size()];
+      {
+        EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+        Expr * *TI = tempInstArgs;
+        Expr * *I = A->args_begin();
+        Expr * *E = A->args_end();
+        for (; I != E; ++I, ++TI) {
+          ExprResult Result = S.SubstExpr(*I, TemplateArgs);
+          *TI = Result.getAs<Expr>();
+        }
+      }
+      return new (C) TryAcquireCapabilityAttr(A->getLocation(), C, tempInstSuccessValue, tempInstArgs, A->args_size(), A->getSpellingListIndex());
+    }
+    case attr::TypeTagForDatatype: {
+      const TypeTagForDatatypeAttr *A = cast<TypeTagForDatatypeAttr>(At);
+      return A->clone(C);
+    }
+    case attr::TypeVisibility: {
+      return NULL;
+    }
+    case attr::Unavailable: {
+      const UnavailableAttr *A = cast<UnavailableAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Unused: {
+      const UnusedAttr *A = cast<UnusedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Used: {
+      const UsedAttr *A = cast<UsedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Uuid: {
+      const UuidAttr *A = cast<UuidAttr>(At);
+      return A->clone(C);
+    }
+    case attr::VecReturn: {
+      const VecReturnAttr *A = cast<VecReturnAttr>(At);
+      return A->clone(C);
+    }
+    case attr::VecTypeHint: {
+      const VecTypeHintAttr *A = cast<VecTypeHintAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Visibility: {
+      return NULL;
+    }
+    case attr::WarnUnused: {
+      const WarnUnusedAttr *A = cast<WarnUnusedAttr>(At);
+      return A->clone(C);
+    }
+    case attr::WarnUnusedResult: {
+      const WarnUnusedResultAttr *A = cast<WarnUnusedResultAttr>(At);
+      return A->clone(C);
+    }
+    case attr::Weak: {
+      const WeakAttr *A = cast<WeakAttr>(At);
+      return A->clone(C);
+    }
+    case attr::WeakImport: {
+      const WeakImportAttr *A = cast<WeakImportAttr>(At);
+      return A->clone(C);
+    }
+    case attr::WeakRef: {
+      const WeakRefAttr *A = cast<WeakRefAttr>(At);
+      return A->clone(C);
+    }
+    case attr::WorkGroupSizeHint: {
+      const WorkGroupSizeHintAttr *A = cast<WorkGroupSizeHintAttr>(At);
+      return A->clone(C);
+    }
+    case attr::X86ForceAlignArgPointer: {
+      const X86ForceAlignArgPointerAttr *A = cast<X86ForceAlignArgPointerAttr>(At);
+      return A->clone(C);
+    }
+  } // end switch
+  llvm_unreachable("Unknown attribute!");
+  return 0;
+}
+
+} // end namespace sema
+} // end namespace clang
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
new file mode 100644
index 0000000..c21c19f
--- /dev/null
+++ b/include/clang/Sema/AttributeList.h
@@ -0,0 +1,850 @@
+//===--- AttributeList.h - Parsed attribute sets ----------------*- 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 AttributeList class, which is used to collect
+// parsed attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_ATTRLIST_H
+#define LLVM_CLANG_SEMA_ATTRLIST_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/VersionTuple.h"
+#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
+
+namespace clang {
+  class ASTContext;
+  class IdentifierInfo;
+  class Expr;
+
+/// \brief Represents information about a change in availability for
+/// an entity, which is part of the encoding of the 'availability'
+/// attribute.
+struct AvailabilityChange {
+  /// \brief The location of the keyword indicating the kind of change.
+  SourceLocation KeywordLoc;
+
+  /// \brief The version number at which the change occurred.
+  VersionTuple Version;
+
+  /// \brief The source range covering the version number.
+  SourceRange VersionRange;
+
+  /// \brief Determine whether this availability change is valid.
+  bool isValid() const { return !Version.empty(); }
+};
+
+/// \brief Wraps an identifier and optional source location for the identifier.
+struct IdentifierLoc {
+  SourceLocation Loc;
+  IdentifierInfo *Ident;
+
+  static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
+                               IdentifierInfo *Ident);
+};
+
+/// \brief A union of the various pointer types that can be passed to an
+/// AttributeList as an argument.
+typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
+typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
+
+/// AttributeList - Represents a syntactic attribute.
+///
+/// For a GNU attribute, there are four forms of this construct:
+///
+/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
+/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
+/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
+/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
+///
+class AttributeList { // TODO: This should really be called ParsedAttribute
+public:
+  /// The style used to specify an attribute.
+  enum Syntax {
+    /// __attribute__((...))
+    AS_GNU,
+    /// [[...]]
+    AS_CXX11,
+    /// __declspec(...)
+    AS_Declspec,
+    /// __ptr16, alignas(...), etc.
+    AS_Keyword,
+    /// #pragma ...
+    AS_Pragma
+  };
+
+private:
+  IdentifierInfo *AttrName;
+  IdentifierInfo *ScopeName;
+  SourceRange AttrRange;
+  SourceLocation ScopeLoc;
+  SourceLocation EllipsisLoc;
+
+  /// The number of expression arguments this attribute has.
+  /// The expressions themselves are stored after the object.
+  unsigned NumArgs : 16;
+
+  /// Corresponds to the Syntax enum.
+  unsigned SyntaxUsed : 2;
+
+  /// True if already diagnosed as invalid.
+  mutable unsigned Invalid : 1;
+
+  /// True if this attribute was used as a type attribute.
+  mutable unsigned UsedAsTypeAttr : 1;
+
+  /// True if this has the extra information associated with an
+  /// availability attribute.
+  unsigned IsAvailability : 1;
+
+  /// True if this has extra information associated with a
+  /// type_tag_for_datatype attribute.
+  unsigned IsTypeTagForDatatype : 1;
+
+  /// True if this has extra information associated with a
+  /// Microsoft __delcspec(property) attribute.
+  unsigned IsProperty : 1;
+
+  /// True if this has a ParsedType
+  unsigned HasParsedType : 1;
+
+  unsigned AttrKind : 8;
+
+  /// \brief The location of the 'unavailable' keyword in an
+  /// availability attribute.
+  SourceLocation UnavailableLoc;
+  
+  const Expr *MessageExpr;
+
+  /// The next attribute in the current position.
+  AttributeList *NextInPosition;
+
+  /// The next attribute allocated in the current Pool.
+  AttributeList *NextInPool;
+
+  /// Arguments, if any, are stored immediately following the object.
+  ArgsUnion *getArgsBuffer() {
+    return reinterpret_cast<ArgsUnion*>(this+1);
+  }
+  ArgsUnion const *getArgsBuffer() const {
+    return reinterpret_cast<ArgsUnion const *>(this+1);
+  }
+
+  enum AvailabilitySlot {
+    IntroducedSlot, DeprecatedSlot, ObsoletedSlot
+  };
+
+  /// Availability information is stored immediately following the arguments,
+  /// if any, at the end of the object.
+  AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {    
+    return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
+                                                 + NumArgs)[index];
+  }
+  const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
+    return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
+                                                       + NumArgs)[index];
+  }
+
+public:
+  struct TypeTagForDatatypeData {
+    ParsedType *MatchingCType;
+    unsigned LayoutCompatible : 1;
+    unsigned MustBeNull : 1;
+  };
+  struct PropertyData {
+    IdentifierInfo *GetterId, *SetterId;
+    PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
+    : GetterId(getterId), SetterId(setterId) {}
+  };
+
+private:
+  /// Type tag information is stored immediately following the arguments, if
+  /// any, at the end of the object.  They are mutually exlusive with
+  /// availability slots.
+  TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
+    return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
+  }
+
+  const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
+    return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
+                                                            + NumArgs);
+  }
+
+  /// The type buffer immediately follows the object and are mutually exclusive
+  /// with arguments.
+  ParsedType &getTypeBuffer() {
+    return *reinterpret_cast<ParsedType *>(this + 1);
+  }
+
+  const ParsedType &getTypeBuffer() const {
+    return *reinterpret_cast<const ParsedType *>(this + 1);
+  }
+
+  /// The property data immediately follows the object is is mutually exclusive
+  /// with arguments.
+  PropertyData &getPropertyDataBuffer() {
+    assert(IsProperty);
+    return *reinterpret_cast<PropertyData*>(this + 1);
+  }
+
+  const PropertyData &getPropertyDataBuffer() const {
+    assert(IsProperty);
+    return *reinterpret_cast<const PropertyData*>(this + 1);
+  }
+
+  AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
+  void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
+  void operator delete(void *) LLVM_DELETED_FUNCTION;
+  ~AttributeList() LLVM_DELETED_FUNCTION;
+
+  size_t allocated_size() const;
+
+  /// Constructor for attributes with expression arguments.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                ArgsUnion *args, unsigned numArgs,
+                Syntax syntaxUsed, SourceLocation ellipsisLoc)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
+      SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
+      IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
+      HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
+    if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
+  /// Constructor for availability attributes.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierLoc *Parm, const AvailabilityChange &introduced,
+                const AvailabilityChange &deprecated,
+                const AvailabilityChange &obsoleted,
+                SourceLocation unavailable, 
+                const Expr *messageExpr,
+                Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
+      Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
+      IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+      UnavailableLoc(unavailable), MessageExpr(messageExpr),
+      NextInPosition(nullptr), NextInPool(nullptr) {
+    ArgsUnion PVal(Parm);
+    memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
+    new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
+    new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
+    new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
+  /// Constructor for objc_bridge_related attributes.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierLoc *Parm1,
+                IdentifierLoc *Parm2,
+                IdentifierLoc *Parm3,
+                Syntax syntaxUsed)
+  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+    ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
+    Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+    IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+    NextInPosition(nullptr), NextInPool(nullptr) {
+    ArgsVector Args;
+    Args.push_back(Parm1);
+    Args.push_back(Parm2);
+    Args.push_back(Parm3);
+    memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+  
+  /// Constructor for type_tag_for_datatype attribute.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierLoc *ArgKind, ParsedType matchingCType,
+                bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
+      Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+      IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
+      NextInPosition(nullptr), NextInPool(nullptr) {
+    ArgsUnion PVal(ArgKind);
+    memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
+    TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
+    new (&ExtraData.MatchingCType) ParsedType(matchingCType);
+    ExtraData.LayoutCompatible = layoutCompatible;
+    ExtraData.MustBeNull = mustBeNull;
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
+  /// Constructor for attributes with a single type argument.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                ParsedType typeArg, Syntax syntaxUsed)
+      : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+        ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
+        Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+        IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
+        NextInPosition(nullptr), NextInPool(nullptr) {
+    new (&getTypeBuffer()) ParsedType(typeArg);
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
+  /// Constructor for microsoft __declspec(property) attribute.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierInfo *getterId, IdentifierInfo *setterId,
+                Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+      ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
+      Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+      IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
+      NextInPosition(nullptr), NextInPool(nullptr) {
+    new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
+  friend class AttributePool;
+  friend class AttributeFactory;
+
+public:
+  enum Kind {           
+    #define PARSED_ATTR(NAME) AT_##NAME,
+    #include "clang/Sema/AttrParsedAttrList.inc"
+    #undef PARSED_ATTR
+    IgnoredAttribute,
+    UnknownAttribute
+  };
+
+  IdentifierInfo *getName() const { return AttrName; }
+  SourceLocation getLoc() const { return AttrRange.getBegin(); }
+  SourceRange getRange() const { return AttrRange; }
+  
+  bool hasScope() const { return ScopeName; }
+  IdentifierInfo *getScopeName() const { return ScopeName; }
+  SourceLocation getScopeLoc() const { return ScopeLoc; }
+  
+  bool hasParsedType() const { return HasParsedType; }
+
+  /// Is this the Microsoft __declspec(property) attribute?
+  bool isDeclspecPropertyAttribute() const  {
+    return IsProperty;
+  }
+
+  bool isAlignasAttribute() const {
+    // FIXME: Use a better mechanism to determine this.
+    return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
+  }
+
+  bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
+  bool isCXX11Attribute() const {
+    return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
+  }
+  bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
+
+  bool isInvalid() const { return Invalid; }
+  void setInvalid(bool b = true) const { Invalid = b; }
+
+  bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
+  void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
+
+  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
+  Kind getKind() const { return Kind(AttrKind); }
+  static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
+                      Syntax SyntaxUsed);
+
+  AttributeList *getNext() const { return NextInPosition; }
+  void setNext(AttributeList *N) { NextInPosition = N; }
+
+  /// getNumArgs - Return the number of actual arguments to this attribute.
+  unsigned getNumArgs() const { return NumArgs; }
+
+  /// getArg - Return the specified argument.
+  ArgsUnion getArg(unsigned Arg) const {
+    assert(Arg < NumArgs && "Arg access out of range!");
+    return getArgsBuffer()[Arg];
+  }
+
+  bool isArgExpr(unsigned Arg) const {
+    return Arg < NumArgs && getArg(Arg).is<Expr*>();
+  }
+  Expr *getArgAsExpr(unsigned Arg) const {
+    return getArg(Arg).get<Expr*>();
+  }
+
+  bool isArgIdent(unsigned Arg) const {
+    return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
+  }
+  IdentifierLoc *getArgAsIdent(unsigned Arg) const {
+    return getArg(Arg).get<IdentifierLoc*>();
+  }
+
+  const AvailabilityChange &getAvailabilityIntroduced() const {
+    assert(getKind() == AT_Availability && "Not an availability attribute");
+    return getAvailabilitySlot(IntroducedSlot);
+  }
+
+  const AvailabilityChange &getAvailabilityDeprecated() const {
+    assert(getKind() == AT_Availability && "Not an availability attribute");
+    return getAvailabilitySlot(DeprecatedSlot);
+  }
+
+  const AvailabilityChange &getAvailabilityObsoleted() const {
+    assert(getKind() == AT_Availability && "Not an availability attribute");
+    return getAvailabilitySlot(ObsoletedSlot);
+  }
+
+  SourceLocation getUnavailableLoc() const {
+    assert(getKind() == AT_Availability && "Not an availability attribute");
+    return UnavailableLoc;
+  }
+  
+  const Expr * getMessageExpr() const {
+    assert(getKind() == AT_Availability && "Not an availability attribute");
+    return MessageExpr;
+  }
+
+  const ParsedType &getMatchingCType() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return *getTypeTagForDatatypeDataSlot().MatchingCType;
+  }
+
+  bool getLayoutCompatible() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return getTypeTagForDatatypeDataSlot().LayoutCompatible;
+  }
+
+  bool getMustBeNull() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return getTypeTagForDatatypeDataSlot().MustBeNull;
+  }
+
+  const ParsedType &getTypeArg() const {
+    assert(HasParsedType && "Not a type attribute");
+    return getTypeBuffer();
+  }
+
+  const PropertyData &getPropertyData() const {
+    assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
+    return getPropertyDataBuffer();
+  }
+
+  /// \brief Get an index into the attribute spelling list
+  /// defined in Attr.td. This index is used by an attribute
+  /// to pretty print itself.
+  unsigned getAttributeSpellingListIndex() const;
+
+  bool isTargetSpecificAttr() const;
+  bool isTypeAttr() const;
+
+  bool hasCustomParsing() const;
+  unsigned getMinArgs() const;
+  unsigned getMaxArgs() const;
+  bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
+  bool diagnoseLangOpts(class Sema &S) const;
+  bool existsInTarget(const llvm::Triple &T) const;
+  bool isKnownToGCC() const;
+
+  /// \brief If the parsed attribute has a semantic equivalent, and it would
+  /// have a semantic Spelling enumeration (due to having semantically-distinct
+  /// spelling variations), return the value of that semantic spelling. If the
+  /// parsed attribute does not have a semantic equivalent, or would not have
+  /// a Spelling enumeration, the value UINT_MAX is returned.
+  unsigned getSemanticSpelling() const;
+};
+
+/// A factory, from which one makes pools, from which one creates
+/// individual attributes which are deallocated with the pool.
+///
+/// Note that it's tolerably cheap to create and destroy one of
+/// these as long as you don't actually allocate anything in it.
+class AttributeFactory {
+public:
+  enum {
+    /// The required allocation size of an availability attribute,
+    /// which we want to ensure is a multiple of sizeof(void*).
+    AvailabilityAllocSize =
+      sizeof(AttributeList)
+      + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
+         sizeof(ArgsUnion) - 1)
+         / sizeof(void*) * sizeof(void*)),
+    TypeTagForDatatypeAllocSize =
+      sizeof(AttributeList)
+      + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
+         sizeof(ArgsUnion) - 1)
+        / sizeof(void*) * sizeof(void*),
+    PropertyAllocSize =
+      sizeof(AttributeList)
+      + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
+        / sizeof(void*) * sizeof(void*)
+  };
+
+private:
+  enum {
+    /// The number of free lists we want to be sure to support
+    /// inline.  This is just enough that availability attributes
+    /// don't surpass it.  It's actually very unlikely we'll see an
+    /// attribute that needs more than that; on x86-64 you'd need 10
+    /// expression arguments, and on i386 you'd need 19.
+    InlineFreeListsCapacity =
+      1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
+  };
+
+  llvm::BumpPtrAllocator Alloc;
+
+  /// Free lists.  The index is determined by the following formula:
+  ///   (size - sizeof(AttributeList)) / sizeof(void*)
+  SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
+
+  // The following are the private interface used by AttributePool.
+  friend class AttributePool;
+
+  /// Allocate an attribute of the given size.
+  void *allocate(size_t size);
+
+  /// Reclaim all the attributes in the given pool chain, which is
+  /// non-empty.  Note that the current implementation is safe
+  /// against reclaiming things which were not actually allocated
+  /// with the allocator, although of course it's important to make
+  /// sure that their allocator lives at least as long as this one.
+  void reclaimPool(AttributeList *head);
+
+public:
+  AttributeFactory();
+  ~AttributeFactory();
+};
+
+class AttributePool {
+  AttributeFactory &Factory;
+  AttributeList *Head;
+
+  void *allocate(size_t size) {
+    return Factory.allocate(size);
+  }
+
+  AttributeList *add(AttributeList *attr) {
+    // We don't care about the order of the pool.
+    attr->NextInPool = Head;
+    Head = attr;
+    return attr;
+  }
+
+  void takePool(AttributeList *pool);
+
+public:
+  /// Create a new pool for a factory.
+  AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
+
+  /// Move the given pool's allocations to this pool.
+  AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
+    pool.Head = nullptr;
+  }
+
+  AttributeFactory &getFactory() const { return Factory; }
+
+  void clear() {
+    if (Head) {
+      Factory.reclaimPool(Head);
+      Head = nullptr;
+    }
+  }
+
+  /// Take the given pool's allocations and add them to this pool.
+  void takeAllFrom(AttributePool &pool) {
+    if (pool.Head) {
+      takePool(pool.Head);
+      pool.Head = nullptr;
+    }
+  }
+
+  ~AttributePool() {
+    if (Head) Factory.reclaimPool(Head);
+  }
+
+  AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        ArgsUnion *args, unsigned numArgs,
+                        AttributeList::Syntax syntax,
+                        SourceLocation ellipsisLoc = SourceLocation()) {
+    void *memory = allocate(sizeof(AttributeList)
+                            + numArgs * sizeof(ArgsUnion));
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          args, numArgs, syntax,
+                                          ellipsisLoc));
+  }
+
+  AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param,
+                        const AvailabilityChange &introduced,
+                        const AvailabilityChange &deprecated,
+                        const AvailabilityChange &obsoleted,
+                        SourceLocation unavailable,
+                        const Expr *MessageExpr,
+                        AttributeList::Syntax syntax) {
+    void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          Param, introduced, deprecated,
+                                          obsoleted, unavailable, MessageExpr,
+                                          syntax));
+  }
+
+  AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param1,
+                        IdentifierLoc *Param2,
+                        IdentifierLoc *Param3,
+                        AttributeList::Syntax syntax) {
+    size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
+    void *memory = allocate(size);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          Param1, Param2, Param3,
+                                          syntax));
+  }
+
+  AttributeList *createTypeTagForDatatype(
+                    IdentifierInfo *attrName, SourceRange attrRange,
+                    IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                    IdentifierLoc *argumentKind, ParsedType matchingCType,
+                    bool layoutCompatible, bool mustBeNull,
+                    AttributeList::Syntax syntax) {
+    void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          argumentKind, matchingCType,
+                                          layoutCompatible, mustBeNull,
+                                          syntax));
+  }
+
+  AttributeList *createTypeAttribute(
+                    IdentifierInfo *attrName, SourceRange attrRange,
+                    IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                    ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+    void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          typeArg, syntaxUsed));
+  }
+
+  AttributeList *createPropertyAttribute(
+                    IdentifierInfo *attrName, SourceRange attrRange,
+                    IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                    IdentifierInfo *getterId, IdentifierInfo *setterId,
+                    AttributeList::Syntax syntaxUsed) {
+    void *memory = allocate(AttributeFactory::PropertyAllocSize);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          getterId, setterId,
+                                          syntaxUsed));
+  }
+};
+
+/// ParsedAttributes - A collection of parsed attributes.  Currently
+/// we don't differentiate between the various attribute syntaxes,
+/// which is basically silly.
+///
+/// Right now this is a very lightweight container, but the expectation
+/// is that this will become significantly more serious.
+class ParsedAttributes {
+public:
+  ParsedAttributes(AttributeFactory &factory)
+    : pool(factory), list(nullptr) {
+  }
+
+  ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
+
+  AttributePool &getPool() const { return pool; }
+
+  bool empty() const { return list == nullptr; }
+
+  void add(AttributeList *newAttr) {
+    assert(newAttr);
+    assert(newAttr->getNext() == nullptr);
+    newAttr->setNext(list);
+    list = newAttr;
+  }
+
+  void addAll(AttributeList *newList) {
+    if (!newList) return;
+
+    AttributeList *lastInNewList = newList;
+    while (AttributeList *next = lastInNewList->getNext())
+      lastInNewList = next;
+
+    lastInNewList->setNext(list);
+    list = newList;
+  }
+
+  void set(AttributeList *newList) {
+    list = newList;
+  }
+
+  void takeAllFrom(ParsedAttributes &attrs) {
+    addAll(attrs.list);
+    attrs.list = nullptr;
+    pool.takeAllFrom(attrs.pool);
+  }
+
+  void clear() { list = nullptr; pool.clear(); }
+  AttributeList *getList() const { return list; }
+
+  /// Returns a reference to the attribute list.  Try not to introduce
+  /// dependencies on this method, it may not be long-lived.
+  AttributeList *&getListRef() { return list; }
+
+  /// Add attribute with expression arguments.
+  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        ArgsUnion *args, unsigned numArgs,
+                        AttributeList::Syntax syntax,
+                        SourceLocation ellipsisLoc = SourceLocation()) {
+    AttributeList *attr =
+      pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
+                  syntax, ellipsisLoc);
+    add(attr);
+    return attr;
+  }
+
+  /// Add availability attribute.
+  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param,
+                        const AvailabilityChange &introduced,
+                        const AvailabilityChange &deprecated,
+                        const AvailabilityChange &obsoleted,
+                        SourceLocation unavailable,
+                        const Expr *MessageExpr,
+                        AttributeList::Syntax syntax) {
+    AttributeList *attr =
+      pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
+                  deprecated, obsoleted, unavailable, MessageExpr, syntax);
+    add(attr);
+    return attr;
+  }
+
+  /// Add objc_bridge_related attribute.
+  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param1,
+                        IdentifierLoc *Param2,
+                        IdentifierLoc *Param3,
+                        AttributeList::Syntax syntax) {
+    AttributeList *attr =
+      pool.create(attrName, attrRange, scopeName, scopeLoc,
+                  Param1, Param2, Param3, syntax);
+    add(attr);
+    return attr;
+  }
+
+  /// Add type_tag_for_datatype attribute.
+  AttributeList *addNewTypeTagForDatatype(
+                        IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *argumentKind, ParsedType matchingCType,
+                        bool layoutCompatible, bool mustBeNull,
+                        AttributeList::Syntax syntax) {
+    AttributeList *attr =
+      pool.createTypeTagForDatatype(attrName, attrRange,
+                                    scopeName, scopeLoc,
+                                    argumentKind, matchingCType,
+                                    layoutCompatible, mustBeNull, syntax);
+    add(attr);
+    return attr;
+  }
+
+  /// Add an attribute with a single type argument.
+  AttributeList *
+  addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
+                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
+    AttributeList *attr =
+        pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
+                                 typeArg, syntaxUsed);
+    add(attr);
+    return attr;
+  }
+
+  /// Add microsoft __delspec(property) attribute.
+  AttributeList *
+  addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
+                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                 IdentifierInfo *getterId, IdentifierInfo *setterId,
+                 AttributeList::Syntax syntaxUsed) {
+    AttributeList *attr =
+        pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
+                                     getterId, setterId, syntaxUsed);
+    add(attr);
+    return attr;
+  }
+
+private:
+  mutable AttributePool pool;
+  AttributeList *list;
+};
+
+/// These constants match the enumerated choices of
+/// err_attribute_argument_n_type and err_attribute_argument_type.
+enum AttributeArgumentNType {
+  AANT_ArgumentIntOrBool,
+  AANT_ArgumentIntegerConstant,
+  AANT_ArgumentString,
+  AANT_ArgumentIdentifier
+};
+
+/// These constants match the enumerated choices of
+/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
+enum AttributeDeclKind {
+  ExpectedFunction,
+  ExpectedUnion,
+  ExpectedVariableOrFunction,
+  ExpectedFunctionOrMethod,
+  ExpectedParameter,
+  ExpectedFunctionMethodOrBlock,
+  ExpectedFunctionMethodOrClass,
+  ExpectedFunctionMethodOrParameter,
+  ExpectedClass,
+  ExpectedVariable,
+  ExpectedMethod,
+  ExpectedVariableFunctionOrLabel,
+  ExpectedFieldOrGlobalVar,
+  ExpectedStruct,
+  ExpectedVariableFunctionOrTag,
+  ExpectedTLSVar,
+  ExpectedVariableOrField,
+  ExpectedVariableFieldOrTag,
+  ExpectedTypeOrNamespace,
+  ExpectedObjectiveCInterface,
+  ExpectedMethodOrProperty,
+  ExpectedStructOrUnion,
+  ExpectedStructOrUnionOrClass,
+  ExpectedType,
+  ExpectedObjCInstanceMethod,
+  ExpectedObjCInterfaceDeclInitMethod,
+  ExpectedFunctionVariableOrClass,
+  ExpectedObjectiveCProtocol,
+  ExpectedFunctionGlobalVarMethodOrProperty,
+  ExpectedStructOrTypedef,
+  ExpectedObjectiveCInterfaceOrProtocol
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h
new file mode 100644
index 0000000..6685751
--- /dev/null
+++ b/include/clang/Sema/CXXFieldCollector.h
@@ -0,0 +1,80 @@
+//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides CXXFieldCollector that is used during parsing & semantic
+//  analysis of C++ classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
+#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class FieldDecl;
+
+/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
+/// C++ classes.
+class CXXFieldCollector {
+  /// Fields - Contains all FieldDecls collected during parsing of a C++
+  /// class. When a nested class is entered, its fields are appended to the
+  /// fields of its parent class, when it is exited its fields are removed.
+  SmallVector<FieldDecl*, 32> Fields;
+
+  /// FieldCount - Each entry represents the number of fields collected during
+  /// the parsing of a C++ class. When a nested class is entered, a new field
+  /// count is pushed, when it is exited, the field count is popped.
+  SmallVector<size_t, 4> FieldCount;
+
+  // Example:
+  //
+  // class C {
+  //   int x,y;
+  //   class NC {
+  //     int q;
+  //     // At this point, Fields contains [x,y,q] decls and FieldCount contains
+  //     // [2,1].
+  //   };
+  //   int z;
+  //   // At this point, Fields contains [x,y,z] decls and FieldCount contains
+  //   // [3].
+  // };
+
+public:
+  /// StartClass - Called by Sema::ActOnStartCXXClassDef.
+  void StartClass() { FieldCount.push_back(0); }
+
+  /// Add - Called by Sema::ActOnCXXMemberDeclarator.
+  void Add(FieldDecl *D) {
+    Fields.push_back(D);
+    ++FieldCount.back();
+  }
+
+  /// getCurNumField - The number of fields added to the currently parsed class.
+  size_t getCurNumFields() const {
+    assert(!FieldCount.empty() && "no currently-parsed class");
+    return FieldCount.back();
+  }
+
+  /// getCurFields - Pointer to array of fields added to the currently parsed
+  /// class.
+  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
+
+  /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
+  void FinishClass() {
+    Fields.resize(Fields.size() - getCurNumFields());
+    FieldCount.pop_back();
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
new file mode 100644
index 0000000..92a4e9a
--- /dev/null
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -0,0 +1,985 @@
+//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- 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 CodeCompleteConsumer class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
+#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
+
+#include "clang-c/Index.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/Type.h"
+#include "clang/Sema/CodeCompleteOptions.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <string>
+
+namespace clang {
+
+class Decl;
+
+/// \brief Default priority values for code-completion results based
+/// on their kind.
+enum {
+  /// \brief Priority for the next initialization in a constructor initializer
+  /// list.
+  CCP_NextInitializer = 7,
+  /// \brief Priority for an enumeration constant inside a switch whose
+  /// condition is of the enumeration type.
+  CCP_EnumInCase = 7,
+  /// \brief Priority for a send-to-super completion.
+  CCP_SuperCompletion = 20,
+  /// \brief Priority for a declaration that is in the local scope.
+  CCP_LocalDeclaration = 34,
+  /// \brief Priority for a member declaration found from the current
+  /// method or member function.
+  CCP_MemberDeclaration = 35,
+  /// \brief Priority for a language keyword (that isn't any of the other
+  /// categories).
+  CCP_Keyword = 40,
+  /// \brief Priority for a code pattern.
+  CCP_CodePattern = 40,
+  /// \brief Priority for a non-type declaration.
+  CCP_Declaration = 50,
+  /// \brief Priority for a type.
+  CCP_Type = CCP_Declaration,
+  /// \brief Priority for a constant value (e.g., enumerator).
+  CCP_Constant = 65,
+  /// \brief Priority for a preprocessor macro.
+  CCP_Macro = 70,
+  /// \brief Priority for a nested-name-specifier.
+  CCP_NestedNameSpecifier = 75,
+  /// \brief Priority for a result that isn't likely to be what the user wants,
+  /// but is included for completeness.
+  CCP_Unlikely = 80,
+
+  /// \brief Priority for the Objective-C "_cmd" implicit parameter.
+  CCP_ObjC_cmd = CCP_Unlikely
+};
+
+/// \brief Priority value deltas that are added to code-completion results
+/// based on the context of the result.
+enum {
+  /// \brief The result is in a base class.
+  CCD_InBaseClass = 2,
+  /// \brief The result is a C++ non-static member function whose qualifiers
+  /// exactly match the object type on which the member function can be called.
+  CCD_ObjectQualifierMatch = -1,
+  /// \brief The selector of the given message exactly matches the selector
+  /// of the current method, which might imply that some kind of delegation
+  /// is occurring.
+  CCD_SelectorMatch = -3,
+
+  /// \brief Adjustment to the "bool" type in Objective-C, where the typedef
+  /// "BOOL" is preferred.
+  CCD_bool_in_ObjC = 1,
+
+  /// \brief Adjustment for KVC code pattern priorities when it doesn't look
+  /// like the
+  CCD_ProbablyNotObjCCollection = 15,
+
+  /// \brief An Objective-C method being used as a property.
+  CCD_MethodAsProperty = 2
+};
+
+/// \brief Priority value factors by which we will divide or multiply the
+/// priority of a code-completion result.
+enum {
+  /// \brief Divide by this factor when a code-completion result's type exactly
+  /// matches the type we expect.
+  CCF_ExactTypeMatch = 4,
+  /// \brief Divide by this factor when a code-completion result's type is
+  /// similar to the type we expect (e.g., both arithmetic types, both
+  /// Objective-C object pointer types).
+  CCF_SimilarTypeMatch = 2
+};
+
+/// \brief A simplified classification of types used when determining
+/// "similar" types for code completion.
+enum SimplifiedTypeClass {
+  STC_Arithmetic,
+  STC_Array,
+  STC_Block,
+  STC_Function,
+  STC_ObjectiveC,
+  STC_Other,
+  STC_Pointer,
+  STC_Record,
+  STC_Void
+};
+
+/// \brief Determine the simplified type class of the given canonical type.
+SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
+
+/// \brief Determine the type that this declaration will have if it is used
+/// as a type or in an expression.
+QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);
+
+/// \brief Determine the priority to be given to a macro code completion result
+/// with the given name.
+///
+/// \param MacroName The name of the macro.
+///
+/// \param LangOpts Options describing the current language dialect.
+///
+/// \param PreferredTypeIsPointer Whether the preferred type for the context
+/// of this macro is a pointer type.
+unsigned getMacroUsagePriority(StringRef MacroName,
+                               const LangOptions &LangOpts,
+                               bool PreferredTypeIsPointer = false);
+
+/// \brief Determine the libclang cursor kind associated with the given
+/// declaration.
+CXCursorKind getCursorKindForDecl(const Decl *D);
+
+class FunctionDecl;
+class FunctionType;
+class FunctionTemplateDecl;
+class IdentifierInfo;
+class NamedDecl;
+class NestedNameSpecifier;
+class Sema;
+
+/// \brief The context in which code completion occurred, so that the
+/// code-completion consumer can process the results accordingly.
+class CodeCompletionContext {
+public:
+  enum Kind {
+    /// \brief An unspecified code-completion context.
+    CCC_Other,
+    /// \brief An unspecified code-completion context where we should also add
+    /// macro completions.
+    CCC_OtherWithMacros,
+    /// \brief Code completion occurred within a "top-level" completion context,
+    /// e.g., at namespace or global scope.
+    CCC_TopLevel,
+    /// \brief Code completion occurred within an Objective-C interface,
+    /// protocol, or category interface.
+    CCC_ObjCInterface,
+    /// \brief Code completion occurred within an Objective-C implementation
+    /// or category implementation.
+    CCC_ObjCImplementation,
+    /// \brief Code completion occurred within the instance variable list of
+    /// an Objective-C interface, implementation, or category implementation.
+    CCC_ObjCIvarList,
+    /// \brief Code completion occurred within a class, struct, or union.
+    CCC_ClassStructUnion,
+    /// \brief Code completion occurred where a statement (or declaration) is
+    /// expected in a function, method, or block.
+    CCC_Statement,
+    /// \brief Code completion occurred where an expression is expected.
+    CCC_Expression,
+    /// \brief Code completion occurred where an Objective-C message receiver
+    /// is expected.
+    CCC_ObjCMessageReceiver,
+    /// \brief Code completion occurred on the right-hand side of a member
+    /// access expression using the dot operator.
+    ///
+    /// The results of this completion are the members of the type being
+    /// accessed. The type itself is available via
+    /// \c CodeCompletionContext::getType().
+    CCC_DotMemberAccess,
+    /// \brief Code completion occurred on the right-hand side of a member
+    /// access expression using the arrow operator.
+    ///
+    /// The results of this completion are the members of the type being
+    /// accessed. The type itself is available via
+    /// \c CodeCompletionContext::getType().
+    CCC_ArrowMemberAccess,
+    /// \brief Code completion occurred on the right-hand side of an Objective-C
+    /// property access expression.
+    ///
+    /// The results of this completion are the members of the type being
+    /// accessed. The type itself is available via
+    /// \c CodeCompletionContext::getType().
+    CCC_ObjCPropertyAccess,
+    /// \brief Code completion occurred after the "enum" keyword, to indicate
+    /// an enumeration name.
+    CCC_EnumTag,
+    /// \brief Code completion occurred after the "union" keyword, to indicate
+    /// a union name.
+    CCC_UnionTag,
+    /// \brief Code completion occurred after the "struct" or "class" keyword,
+    /// to indicate a struct or class name.
+    CCC_ClassOrStructTag,
+    /// \brief Code completion occurred where a protocol name is expected.
+    CCC_ObjCProtocolName,
+    /// \brief Code completion occurred where a namespace or namespace alias
+    /// is expected.
+    CCC_Namespace,
+    /// \brief Code completion occurred where a type name is expected.
+    CCC_Type,
+    /// \brief Code completion occurred where a new name is expected.
+    CCC_Name,
+    /// \brief Code completion occurred where a new name is expected and a
+    /// qualified name is permissible.
+    CCC_PotentiallyQualifiedName,
+    /// \brief Code completion occurred where an macro is being defined.
+    CCC_MacroName,
+    /// \brief Code completion occurred where a macro name is expected
+    /// (without any arguments, in the case of a function-like macro).
+    CCC_MacroNameUse,
+    /// \brief Code completion occurred within a preprocessor expression.
+    CCC_PreprocessorExpression,
+    /// \brief Code completion occurred where a preprocessor directive is
+    /// expected.
+    CCC_PreprocessorDirective,
+    /// \brief Code completion occurred in a context where natural language is
+    /// expected, e.g., a comment or string literal.
+    ///
+    /// This context usually implies that no completions should be added,
+    /// unless they come from an appropriate natural-language dictionary.
+    CCC_NaturalLanguage,
+    /// \brief Code completion for a selector, as in an \@selector expression.
+    CCC_SelectorName,
+    /// \brief Code completion within a type-qualifier list.
+    CCC_TypeQualifiers,
+    /// \brief Code completion in a parenthesized expression, which means that
+    /// we may also have types here in C and Objective-C (as well as in C++).
+    CCC_ParenthesizedExpression,
+    /// \brief Code completion where an Objective-C instance message is
+    /// expected.
+    CCC_ObjCInstanceMessage,
+    /// \brief Code completion where an Objective-C class message is expected.
+    CCC_ObjCClassMessage,
+    /// \brief Code completion where the name of an Objective-C class is
+    /// expected.
+    CCC_ObjCInterfaceName,
+    /// \brief Code completion where an Objective-C category name is expected.
+    CCC_ObjCCategoryName,
+    /// \brief An unknown context, in which we are recovering from a parsing
+    /// error and don't know which completions we should give.
+    CCC_Recovery
+  };
+
+private:
+  enum Kind Kind;
+
+  /// \brief The type that would prefer to see at this point (e.g., the type
+  /// of an initializer or function parameter).
+  QualType PreferredType;
+
+  /// \brief The type of the base object in a member access expression.
+  QualType BaseType;
+
+  /// \brief The identifiers for Objective-C selector parts.
+  ArrayRef<IdentifierInfo *> SelIdents;
+
+public:
+  /// \brief Construct a new code-completion context of the given kind.
+  CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { }
+
+  /// \brief Construct a new code-completion context of the given kind.
+  CodeCompletionContext(enum Kind Kind, QualType T,
+                        ArrayRef<IdentifierInfo *> SelIdents = None)
+                        : Kind(Kind),
+                          SelIdents(SelIdents) {
+    if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess ||
+        Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage ||
+        Kind == CCC_ObjCInstanceMessage)
+      BaseType = T;
+    else
+      PreferredType = T;
+  }
+
+  /// \brief Retrieve the kind of code-completion context.
+  enum Kind getKind() const { return Kind; }
+
+  /// \brief Retrieve the type that this expression would prefer to have, e.g.,
+  /// if the expression is a variable initializer or a function argument, the
+  /// type of the corresponding variable or function parameter.
+  QualType getPreferredType() const { return PreferredType; }
+
+  /// \brief Retrieve the type of the base object in a member-access
+  /// expression.
+  QualType getBaseType() const { return BaseType; }
+
+  /// \brief Retrieve the Objective-C selector identifiers.
+  ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; }
+
+  /// \brief Determines whether we want C++ constructors as results within this
+  /// context.
+  bool wantConstructorResults() const;
+};
+
+
+/// \brief A "string" used to describe how code completion can
+/// be performed for an entity.
+///
+/// A code completion string typically shows how a particular entity can be
+/// used. For example, the code completion string for a function would show
+/// the syntax to call it, including the parentheses, placeholders for the
+/// arguments, etc.
+class CodeCompletionString {
+public:
+  /// \brief The different kinds of "chunks" that can occur within a code
+  /// completion string.
+  enum ChunkKind {
+    /// \brief The piece of text that the user is expected to type to
+    /// match the code-completion string, typically a keyword or the name of a
+    /// declarator or macro.
+    CK_TypedText,
+    /// \brief A piece of text that should be placed in the buffer, e.g.,
+    /// parentheses or a comma in a function call.
+    CK_Text,
+    /// \brief A code completion string that is entirely optional. For example,
+    /// an optional code completion string that describes the default arguments
+    /// in a function call.
+    CK_Optional,
+    /// \brief A string that acts as a placeholder for, e.g., a function
+    /// call argument.
+    CK_Placeholder,
+    /// \brief A piece of text that describes something about the result but
+    /// should not be inserted into the buffer.
+    CK_Informative,
+    /// \brief A piece of text that describes the type of an entity or, for
+    /// functions and methods, the return type.
+    CK_ResultType,
+    /// \brief A piece of text that describes the parameter that corresponds
+    /// to the code-completion location within a function call, message send,
+    /// macro invocation, etc.
+    CK_CurrentParameter,
+    /// \brief A left parenthesis ('(').
+    CK_LeftParen,
+    /// \brief A right parenthesis (')').
+    CK_RightParen,
+    /// \brief A left bracket ('[').
+    CK_LeftBracket,
+    /// \brief A right bracket (']').
+    CK_RightBracket,
+    /// \brief A left brace ('{').
+    CK_LeftBrace,
+    /// \brief A right brace ('}').
+    CK_RightBrace,
+    /// \brief A left angle bracket ('<').
+    CK_LeftAngle,
+    /// \brief A right angle bracket ('>').
+    CK_RightAngle,
+    /// \brief A comma separator (',').
+    CK_Comma,
+    /// \brief A colon (':').
+    CK_Colon,
+    /// \brief A semicolon (';').
+    CK_SemiColon,
+    /// \brief An '=' sign.
+    CK_Equal,
+    /// \brief Horizontal whitespace (' ').
+    CK_HorizontalSpace,
+    /// \brief Vertical whitespace ('\\n' or '\\r\\n', depending on the
+    /// platform).
+    CK_VerticalSpace
+  };
+
+  /// \brief One piece of the code completion string.
+  struct Chunk {
+    /// \brief The kind of data stored in this piece of the code completion
+    /// string.
+    ChunkKind Kind;
+
+    union {
+      /// \brief The text string associated with a CK_Text, CK_Placeholder,
+      /// CK_Informative, or CK_Comma chunk.
+      /// The string is owned by the chunk and will be deallocated
+      /// (with delete[]) when the chunk is destroyed.
+      const char *Text;
+
+      /// \brief The code completion string associated with a CK_Optional chunk.
+      /// The optional code completion string is owned by the chunk, and will
+      /// be deallocated (with delete) when the chunk is destroyed.
+      CodeCompletionString *Optional;
+    };
+
+    Chunk() : Kind(CK_Text), Text(nullptr) { }
+
+    explicit Chunk(ChunkKind Kind, const char *Text = "");
+
+    /// \brief Create a new text chunk.
+    static Chunk CreateText(const char *Text);
+
+    /// \brief Create a new optional chunk.
+    static Chunk CreateOptional(CodeCompletionString *Optional);
+
+    /// \brief Create a new placeholder chunk.
+    static Chunk CreatePlaceholder(const char *Placeholder);
+
+    /// \brief Create a new informative chunk.
+    static Chunk CreateInformative(const char *Informative);
+
+    /// \brief Create a new result type chunk.
+    static Chunk CreateResultType(const char *ResultType);
+
+    /// \brief Create a new current-parameter chunk.
+    static Chunk CreateCurrentParameter(const char *CurrentParameter);
+  };
+
+private:
+  /// \brief The number of chunks stored in this string.
+  unsigned NumChunks : 16;
+
+  /// \brief The number of annotations for this code-completion result.
+  unsigned NumAnnotations : 16;
+
+  /// \brief The priority of this code-completion string.
+  unsigned Priority : 16;
+
+  /// \brief The availability of this code-completion result.
+  unsigned Availability : 2;
+  
+  /// \brief The name of the parent context.
+  StringRef ParentName;
+
+  /// \brief A brief documentation comment attached to the declaration of
+  /// entity being completed by this result.
+  const char *BriefComment;
+  
+  CodeCompletionString(const CodeCompletionString &) LLVM_DELETED_FUNCTION;
+  void operator=(const CodeCompletionString &) LLVM_DELETED_FUNCTION;
+
+  CodeCompletionString(const Chunk *Chunks, unsigned NumChunks,
+                       unsigned Priority, CXAvailabilityKind Availability,
+                       const char **Annotations, unsigned NumAnnotations,
+                       StringRef ParentName,
+                       const char *BriefComment);
+  ~CodeCompletionString() { }
+
+  friend class CodeCompletionBuilder;
+  friend class CodeCompletionResult;
+
+public:
+  typedef const Chunk *iterator;
+  iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); }
+  iterator end() const { return begin() + NumChunks; }
+  bool empty() const { return NumChunks == 0; }
+  unsigned size() const { return NumChunks; }
+
+  const Chunk &operator[](unsigned I) const {
+    assert(I < size() && "Chunk index out-of-range");
+    return begin()[I];
+  }
+
+  /// \brief Returns the text in the TypedText chunk.
+  const char *getTypedText() const;
+
+  /// \brief Retrieve the priority of this code completion result.
+  unsigned getPriority() const { return Priority; }
+
+  /// \brief Retrieve the availability of this code completion result.
+  unsigned getAvailability() const { return Availability; }
+
+  /// \brief Retrieve the number of annotations for this code completion result.
+  unsigned getAnnotationCount() const;
+
+  /// \brief Retrieve the annotation string specified by \c AnnotationNr.
+  const char *getAnnotation(unsigned AnnotationNr) const;
+  
+  /// \brief Retrieve the name of the parent context.
+  StringRef getParentContextName() const {
+    return ParentName;
+  }
+
+  const char *getBriefComment() const {
+    return BriefComment;
+  }
+  
+  /// \brief Retrieve a string representation of the code completion string,
+  /// which is mainly useful for debugging.
+  std::string getAsString() const;
+};
+
+/// \brief An allocator used specifically for the purpose of code completion.
+class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
+public:
+  /// \brief Copy the given string into this allocator.
+  const char *CopyString(StringRef String);
+
+  /// \brief Copy the given string into this allocator.
+  const char *CopyString(Twine String);
+
+  // \brief Copy the given string into this allocator.
+  const char *CopyString(const char *String) {
+    return CopyString(StringRef(String));
+  }
+
+  /// \brief Copy the given string into this allocator.
+  const char *CopyString(const std::string &String) {
+    return CopyString(StringRef(String));
+  }
+};
+
+/// \brief Allocator for a cached set of global code completions.
+class GlobalCodeCompletionAllocator 
+  : public CodeCompletionAllocator,
+    public RefCountedBase<GlobalCodeCompletionAllocator>
+{
+
+};
+
+class CodeCompletionTUInfo {
+  llvm::DenseMap<const DeclContext *, StringRef> ParentNames;
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef;
+
+public:
+  explicit CodeCompletionTUInfo(
+                    IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator)
+    : AllocatorRef(Allocator) { }
+
+  IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const {
+    return AllocatorRef;
+  }
+  CodeCompletionAllocator &getAllocator() const {
+    assert(AllocatorRef);
+    return *AllocatorRef;
+  }
+
+  StringRef getParentName(const DeclContext *DC);
+};
+
+} // end namespace clang
+
+namespace llvm {
+  template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
+    static const bool value = true;
+  };
+}
+
+namespace clang {
+
+/// \brief A builder class used to construct new code-completion strings.
+class CodeCompletionBuilder {
+public:
+  typedef CodeCompletionString::Chunk Chunk;
+
+private:
+  CodeCompletionAllocator &Allocator;
+  CodeCompletionTUInfo &CCTUInfo;
+  unsigned Priority;
+  CXAvailabilityKind Availability;
+  StringRef ParentName;
+  const char *BriefComment;
+  
+  /// \brief The chunks stored in this string.
+  SmallVector<Chunk, 4> Chunks;
+
+  SmallVector<const char *, 2> Annotations;
+
+public:
+  CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
+                        CodeCompletionTUInfo &CCTUInfo)
+    : Allocator(Allocator), CCTUInfo(CCTUInfo),
+      Priority(0), Availability(CXAvailability_Available),
+      BriefComment(nullptr) { }
+
+  CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
+                        CodeCompletionTUInfo &CCTUInfo,
+                        unsigned Priority, CXAvailabilityKind Availability)
+    : Allocator(Allocator), CCTUInfo(CCTUInfo),
+      Priority(Priority), Availability(Availability),
+      BriefComment(nullptr) { }
+
+  /// \brief Retrieve the allocator into which the code completion
+  /// strings should be allocated.
+  CodeCompletionAllocator &getAllocator() const { return Allocator; }
+
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; }
+
+  /// \brief Take the resulting completion string.
+  ///
+  /// This operation can only be performed once.
+  CodeCompletionString *TakeString();
+
+  /// \brief Add a new typed-text chunk.
+  void AddTypedTextChunk(const char *Text);
+
+  /// \brief Add a new text chunk.
+  void AddTextChunk(const char *Text);
+
+  /// \brief Add a new optional chunk.
+  void AddOptionalChunk(CodeCompletionString *Optional);
+
+  /// \brief Add a new placeholder chunk.
+  void AddPlaceholderChunk(const char *Placeholder);
+
+  /// \brief Add a new informative chunk.
+  void AddInformativeChunk(const char *Text);
+
+  /// \brief Add a new result-type chunk.
+  void AddResultTypeChunk(const char *ResultType);
+
+  /// \brief Add a new current-parameter chunk.
+  void AddCurrentParameterChunk(const char *CurrentParameter);
+
+  /// \brief Add a new chunk.
+  void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text = "");
+
+  void AddAnnotation(const char *A) { Annotations.push_back(A); }
+
+  /// \brief Add the parent context information to this code completion.
+  void addParentContext(const DeclContext *DC);
+
+  const char *getBriefComment() const { return BriefComment; }
+  void addBriefComment(StringRef Comment);
+  
+  StringRef getParentName() const { return ParentName; }
+};
+
+/// \brief Captures a result of code completion.
+class CodeCompletionResult {
+public:
+  /// \brief Describes the kind of result generated.
+  enum ResultKind {
+    RK_Declaration = 0, ///< Refers to a declaration
+    RK_Keyword,         ///< Refers to a keyword or symbol.
+    RK_Macro,           ///< Refers to a macro
+    RK_Pattern          ///< Refers to a precomputed pattern.
+  };
+
+  /// \brief When Kind == RK_Declaration or RK_Pattern, the declaration we are
+  /// referring to. In the latter case, the declaration might be NULL.
+  const NamedDecl *Declaration;
+
+  union {
+    /// \brief When Kind == RK_Keyword, the string representing the keyword
+    /// or symbol's spelling.
+    const char *Keyword;
+
+    /// \brief When Kind == RK_Pattern, the code-completion string that
+    /// describes the completion text to insert.
+    CodeCompletionString *Pattern;
+
+    /// \brief When Kind == RK_Macro, the identifier that refers to a macro.
+    const IdentifierInfo *Macro;
+  };
+
+  /// \brief The priority of this particular code-completion result.
+  unsigned Priority;
+
+  /// \brief Specifies which parameter (of a function, Objective-C method,
+  /// macro, etc.) we should start with when formatting the result.
+  unsigned StartParameter;
+
+  /// \brief The kind of result stored here.
+  ResultKind Kind;
+
+  /// \brief The cursor kind that describes this result.
+  CXCursorKind CursorKind;
+
+  /// \brief The availability of this result.
+  CXAvailabilityKind Availability;
+
+  /// \brief Whether this result is hidden by another name.
+  bool Hidden : 1;
+
+  /// \brief Whether this result was found via lookup into a base class.
+  bool QualifierIsInformative : 1;
+
+  /// \brief Whether this declaration is the beginning of a
+  /// nested-name-specifier and, therefore, should be followed by '::'.
+  bool StartsNestedNameSpecifier : 1;
+
+  /// \brief Whether all parameters (of a function, Objective-C
+  /// method, etc.) should be considered "informative".
+  bool AllParametersAreInformative : 1;
+
+  /// \brief Whether we're completing a declaration of the given entity,
+  /// rather than a use of that entity.
+  bool DeclaringEntity : 1;
+
+  /// \brief If the result should have a nested-name-specifier, this is it.
+  /// When \c QualifierIsInformative, the nested-name-specifier is
+  /// informative rather than required.
+  NestedNameSpecifier *Qualifier;
+
+  /// \brief Build a result that refers to a declaration.
+  CodeCompletionResult(const NamedDecl *Declaration,
+                       unsigned Priority,
+                       NestedNameSpecifier *Qualifier = nullptr,
+                       bool QualifierIsInformative = false,
+                       bool Accessible = true)
+    : Declaration(Declaration), Priority(Priority),
+      StartParameter(0), Kind(RK_Declaration),
+      Availability(CXAvailability_Available), Hidden(false),
+      QualifierIsInformative(QualifierIsInformative),
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+      DeclaringEntity(false), Qualifier(Qualifier) {
+    computeCursorKindAndAvailability(Accessible);
+  }
+
+  /// \brief Build a result that refers to a keyword or symbol.
+  CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
+    : Declaration(nullptr), Keyword(Keyword), Priority(Priority),
+      StartParameter(0), Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
+      Availability(CXAvailability_Available), Hidden(false),
+      QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {}
+
+  /// \brief Build a result that refers to a macro.
+  CodeCompletionResult(const IdentifierInfo *Macro,
+                       unsigned Priority = CCP_Macro)
+    : Declaration(nullptr), Macro(Macro), Priority(Priority), StartParameter(0),
+      Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition),
+      Availability(CXAvailability_Available), Hidden(false),
+      QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {}
+
+  /// \brief Build a result that refers to a pattern.
+  CodeCompletionResult(CodeCompletionString *Pattern,
+                       unsigned Priority = CCP_CodePattern,
+                       CXCursorKind CursorKind = CXCursor_NotImplemented,
+                   CXAvailabilityKind Availability = CXAvailability_Available,
+                       const NamedDecl *D = nullptr)
+    : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
+      Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability),
+      Hidden(false), QualifierIsInformative(0),
+      StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+      DeclaringEntity(false), Qualifier(nullptr)
+  {
+  }
+
+  /// \brief Build a result that refers to a pattern with an associated
+  /// declaration.
+  CodeCompletionResult(CodeCompletionString *Pattern, NamedDecl *D,
+                       unsigned Priority)
+    : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
+      Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false),
+      QualifierIsInformative(false), StartsNestedNameSpecifier(false),
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {
+    computeCursorKindAndAvailability();
+  }  
+  
+  /// \brief Retrieve the declaration stored in this result.
+  const NamedDecl *getDeclaration() const {
+    assert(Kind == RK_Declaration && "Not a declaration result");
+    return Declaration;
+  }
+
+  /// \brief Retrieve the keyword stored in this result.
+  const char *getKeyword() const {
+    assert(Kind == RK_Keyword && "Not a keyword result");
+    return Keyword;
+  }
+
+  /// \brief Create a new code-completion string that describes how to insert
+  /// this result into a program.
+  ///
+  /// \param S The semantic analysis that created the result.
+  ///
+  /// \param Allocator The allocator that will be used to allocate the
+  /// string itself.
+  CodeCompletionString *CreateCodeCompletionString(Sema &S,
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo,
+                                           bool IncludeBriefComments);
+  CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx,
+                                                   Preprocessor &PP,
+                                           CodeCompletionAllocator &Allocator,
+                                           CodeCompletionTUInfo &CCTUInfo,
+                                           bool IncludeBriefComments);
+
+private:
+  void computeCursorKindAndAvailability(bool Accessible = true);
+};
+
+bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y);
+
+inline bool operator>(const CodeCompletionResult &X,
+                      const CodeCompletionResult &Y) {
+  return Y < X;
+}
+
+inline bool operator<=(const CodeCompletionResult &X,
+                      const CodeCompletionResult &Y) {
+  return !(Y < X);
+}
+
+inline bool operator>=(const CodeCompletionResult &X,
+                       const CodeCompletionResult &Y) {
+  return !(X < Y);
+}
+
+
+raw_ostream &operator<<(raw_ostream &OS,
+                              const CodeCompletionString &CCS);
+
+/// \brief Abstract interface for a consumer of code-completion
+/// information.
+class CodeCompleteConsumer {
+protected:
+  const CodeCompleteOptions CodeCompleteOpts;
+
+  /// \brief Whether the output format for the code-completion consumer is
+  /// binary.
+  bool OutputIsBinary;
+
+public:
+  class OverloadCandidate {
+  public:
+    /// \brief Describes the type of overload candidate.
+    enum CandidateKind {
+      /// \brief The candidate is a function declaration.
+      CK_Function,
+      /// \brief The candidate is a function template.
+      CK_FunctionTemplate,
+      /// \brief The "candidate" is actually a variable, expression, or block
+      /// for which we only have a function prototype.
+      CK_FunctionType
+    };
+
+  private:
+    /// \brief The kind of overload candidate.
+    CandidateKind Kind;
+
+    union {
+      /// \brief The function overload candidate, available when
+      /// Kind == CK_Function.
+      FunctionDecl *Function;
+
+      /// \brief The function template overload candidate, available when
+      /// Kind == CK_FunctionTemplate.
+      FunctionTemplateDecl *FunctionTemplate;
+
+      /// \brief The function type that describes the entity being called,
+      /// when Kind == CK_FunctionType.
+      const FunctionType *Type;
+    };
+
+  public:
+    OverloadCandidate(FunctionDecl *Function)
+      : Kind(CK_Function), Function(Function) { }
+
+    OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
+      : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { }
+
+    OverloadCandidate(const FunctionType *Type)
+      : Kind(CK_FunctionType), Type(Type) { }
+
+    /// \brief Determine the kind of overload candidate.
+    CandidateKind getKind() const { return Kind; }
+
+    /// \brief Retrieve the function overload candidate or the templated
+    /// function declaration for a function template.
+    FunctionDecl *getFunction() const;
+
+    /// \brief Retrieve the function template overload candidate.
+    FunctionTemplateDecl *getFunctionTemplate() const {
+      assert(getKind() == CK_FunctionTemplate && "Not a function template");
+      return FunctionTemplate;
+    }
+
+    /// \brief Retrieve the function type of the entity, regardless of how the
+    /// function is stored.
+    const FunctionType *getFunctionType() const;
+
+    /// \brief Create a new code-completion string that describes the function
+    /// signature of this overload candidate.
+    CodeCompletionString *CreateSignatureString(unsigned CurrentArg,
+                                                Sema &S,
+                                      CodeCompletionAllocator &Allocator,
+                                      CodeCompletionTUInfo &CCTUInfo) const;
+  };
+
+  CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
+                       bool OutputIsBinary)
+    : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary)
+  { }
+
+  /// \brief Whether the code-completion consumer wants to see macros.
+  bool includeMacros() const {
+    return CodeCompleteOpts.IncludeMacros;
+  }
+
+  /// \brief Whether the code-completion consumer wants to see code patterns.
+  bool includeCodePatterns() const {
+    return CodeCompleteOpts.IncludeCodePatterns;
+  }
+
+  /// \brief Whether to include global (top-level) declaration results.
+  bool includeGlobals() const {
+    return CodeCompleteOpts.IncludeGlobals;
+  }
+
+  /// \brief Whether to include brief documentation comments within the set of
+  /// code completions returned.
+  bool includeBriefComments() const {
+    return CodeCompleteOpts.IncludeBriefComments;
+  }
+
+  /// \brief Determine whether the output of this consumer is binary.
+  bool isOutputBinary() const { return OutputIsBinary; }
+
+  /// \brief Deregisters and destroys this code-completion consumer.
+  virtual ~CodeCompleteConsumer();
+
+  /// \name Code-completion callbacks
+  //@{
+  /// \brief Process the finalized code-completion results.
+  virtual void ProcessCodeCompleteResults(Sema &S,
+                                          CodeCompletionContext Context,
+                                          CodeCompletionResult *Results,
+                                          unsigned NumResults) { }
+
+  /// \param S the semantic-analyzer object for which code-completion is being
+  /// done.
+  ///
+  /// \param CurrentArg the index of the current argument.
+  ///
+  /// \param Candidates an array of overload candidates.
+  ///
+  /// \param NumCandidates the number of overload candidates
+  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                         OverloadCandidate *Candidates,
+                                         unsigned NumCandidates) { }
+  //@}
+
+  /// \brief Retrieve the allocator that will be used to allocate
+  /// code completion strings.
+  virtual CodeCompletionAllocator &getAllocator() = 0;
+
+  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0;
+};
+
+/// \brief A simple code-completion consumer that prints the results it
+/// receives in a simple format.
+class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
+  /// \brief The raw output stream.
+  raw_ostream &OS;
+
+  CodeCompletionTUInfo CCTUInfo;
+
+public:
+  /// \brief Create a new printing code-completion consumer that prints its
+  /// results to the given raw output stream.
+  PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
+                               raw_ostream &OS)
+    : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
+      CCTUInfo(new GlobalCodeCompletionAllocator) {}
+
+  /// \brief Prints the finalized code-completion results.
+  void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
+                                  CodeCompletionResult *Results,
+                                  unsigned NumResults) override;
+
+  void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                 OverloadCandidate *Candidates,
+                                 unsigned NumCandidates) override;
+
+  CodeCompletionAllocator &getAllocator() override {
+    return CCTUInfo.getAllocator();
+  }
+
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
new file mode 100644
index 0000000..e43496f
--- /dev/null
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -0,0 +1,37 @@
+//===---- CodeCompleteOptions.h - Code Completion Options -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H
+#define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H
+
+/// Options controlling the behavior of code completion.
+class CodeCompleteOptions {
+public:
+  /// Show macros in code completion results.
+  unsigned IncludeMacros : 1;
+
+  /// Show code patterns in code completion results.
+  unsigned IncludeCodePatterns : 1;
+
+  /// Show top-level decls in code completion results.
+  unsigned IncludeGlobals : 1;
+
+  /// Show brief documentation comments in code completion results.
+  unsigned IncludeBriefComments : 1;
+
+  CodeCompleteOptions() :
+      IncludeMacros(0),
+      IncludeCodePatterns(0),
+      IncludeGlobals(1),
+      IncludeBriefComments(0)
+  { }
+};
+
+#endif
+
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
new file mode 100644
index 0000000..8364dfc
--- /dev/null
+++ b/include/clang/Sema/DeclSpec.h
@@ -0,0 +1,2199 @@
+//===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines the classes used to store parsed information about
+/// declaration-specifiers and declarators.
+///
+/// \verbatim
+///   static const int volatile x, *y, *(*(*z)[10])(const void *x);
+///   ------------------------- -  --  ---------------------------
+///     declaration-specifiers  \  |   /
+///                            declarators
+/// \endverbatim
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DECLSPEC_H
+#define LLVM_CLANG_SEMA_DECLSPEC_H
+
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/Lambda.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/Token.h"
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+  class ASTContext;
+  class TypeLoc;
+  class LangOptions;
+  class DiagnosticsEngine;
+  class IdentifierInfo;
+  class NamespaceAliasDecl;
+  class NamespaceDecl;
+  class NestedNameSpecifier;
+  class NestedNameSpecifierLoc;
+  class ObjCDeclSpec;
+  class Preprocessor;
+  class Sema;
+  class Declarator;
+  struct TemplateIdAnnotation;
+
+/// \brief Represents a C++ nested-name-specifier or a global scope specifier.
+///
+/// These can be in 3 states:
+///   1) Not present, identified by isEmpty()
+///   2) Present, identified by isNotEmpty()
+///      2.a) Valid, idenified by isValid()
+///      2.b) Invalid, identified by isInvalid().
+///
+/// isSet() is deprecated because it mostly corresponded to "valid" but was
+/// often used as if it meant "present".
+///
+/// The actual scope is described by getScopeRep().
+class CXXScopeSpec {
+  SourceRange Range;  
+  NestedNameSpecifierLocBuilder Builder;
+
+public:
+  const SourceRange &getRange() const { return Range; }
+  void setRange(const SourceRange &R) { Range = R; }
+  void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
+  void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); }
+  SourceLocation getBeginLoc() const { return Range.getBegin(); }
+  SourceLocation getEndLoc() const { return Range.getEnd(); }
+
+  /// \brief Retrieve the representation of the nested-name-specifier.
+  NestedNameSpecifier *getScopeRep() const { 
+    return Builder.getRepresentation(); 
+  }
+
+  /// \brief Extend the current nested-name-specifier by another
+  /// nested-name-specifier component of the form 'type::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
+  ///
+  /// \param TL The TypeLoc that describes the type preceding the '::'.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
+              SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another 
+  /// nested-name-specifier component of the form 'identifier::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Identifier The identifier.
+  ///
+  /// \param IdentifierLoc The location of the identifier.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
+              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another 
+  /// nested-name-specifier component of the form 'namespace::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Namespace The namespace.
+  ///
+  /// \param NamespaceLoc The location of the namespace name.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+              SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Extend the current nested-name-specifier by another 
+  /// nested-name-specifier component of the form 'namespace-alias::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Alias The namespace alias.
+  ///
+  /// \param AliasLoc The location of the namespace alias 
+  /// name.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
+
+  /// \brief Turn this (empty) nested-name-specifier into the global
+  /// nested-name-specifier '::'.
+  void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+  
+  /// \brief Make a new nested-name-specifier from incomplete source-location
+  /// information.
+  ///
+  /// FIXME: This routine should be used very, very rarely, in cases where we
+  /// need to synthesize a nested-name-specifier. Most code should instead use
+  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
+  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, 
+                   SourceRange R);
+  
+  /// \brief Adopt an existing nested-name-specifier (with source-range 
+  /// information).
+  void Adopt(NestedNameSpecifierLoc Other);
+  
+  /// \brief Retrieve a nested-name-specifier with location information, copied
+  /// into the given AST context.
+  ///
+  /// \param Context The context into which this nested-name-specifier will be
+  /// copied.
+  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+
+  /// \brief Retrieve the location of the name in the last qualifier
+  /// in this nested name specifier.
+  ///
+  /// For example, the location of \c bar
+  /// in
+  /// \verbatim
+  ///   \::foo::bar<0>::
+  ///           ^~~
+  /// \endverbatim
+  SourceLocation getLastQualifierNameLoc() const;
+
+  /// No scope specifier.
+  bool isEmpty() const { return !Range.isValid(); }
+  /// A scope specifier is present, but may be valid or invalid.
+  bool isNotEmpty() const { return !isEmpty(); }
+
+  /// An error occurred during parsing of the scope specifier.
+  bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; }
+  /// A scope specifier is present, and it refers to a real scope.
+  bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; }
+
+  /// \brief Indicate that this nested-name-specifier is invalid.
+  void SetInvalid(SourceRange R) { 
+    assert(R.isValid() && "Must have a valid source range");
+    if (Range.getBegin().isInvalid())
+      Range.setBegin(R.getBegin());
+    Range.setEnd(R.getEnd());
+    Builder.Clear();
+  }
+  
+  /// Deprecated.  Some call sites intend isNotEmpty() while others intend
+  /// isValid().
+  bool isSet() const { return getScopeRep() != nullptr; }
+
+  void clear() {
+    Range = SourceRange();
+    Builder.Clear();
+  }
+
+  /// \brief Retrieve the data associated with the source-location information.
+  char *location_data() const { return Builder.getBuffer().first; }
+  
+  /// \brief Retrieve the size of the data associated with source-location 
+  /// information.
+  unsigned location_size() const { return Builder.getBuffer().second; }
+};
+
+/// \brief Captures information about "declaration specifiers".
+///
+/// "Declaration specifiers" encompasses storage-class-specifiers,
+/// type-specifiers, type-qualifiers, and function-specifiers.
+class DeclSpec {
+public:
+  /// \brief storage-class-specifier
+  /// \note The order of these enumerators is important for diagnostics.
+  enum SCS {
+    SCS_unspecified = 0,
+    SCS_typedef,
+    SCS_extern,
+    SCS_static,
+    SCS_auto,
+    SCS_register,
+    SCS_private_extern,
+    SCS_mutable
+  };
+
+  // Import thread storage class specifier enumeration and constants.
+  // These can be combined with SCS_extern and SCS_static.
+  typedef ThreadStorageClassSpecifier TSCS;
+  static const TSCS TSCS_unspecified = clang::TSCS_unspecified;
+  static const TSCS TSCS___thread = clang::TSCS___thread;
+  static const TSCS TSCS_thread_local = clang::TSCS_thread_local;
+  static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local;
+
+  // Import type specifier width enumeration and constants.
+  typedef TypeSpecifierWidth TSW;
+  static const TSW TSW_unspecified = clang::TSW_unspecified;
+  static const TSW TSW_short = clang::TSW_short;
+  static const TSW TSW_long = clang::TSW_long;
+  static const TSW TSW_longlong = clang::TSW_longlong;
+  
+  enum TSC {
+    TSC_unspecified,
+    TSC_imaginary,
+    TSC_complex
+  };
+
+  // Import type specifier sign enumeration and constants.
+  typedef TypeSpecifierSign TSS;
+  static const TSS TSS_unspecified = clang::TSS_unspecified;
+  static const TSS TSS_signed = clang::TSS_signed;
+  static const TSS TSS_unsigned = clang::TSS_unsigned;
+
+  // Import type specifier type enumeration and constants.
+  typedef TypeSpecifierType TST;
+  static const TST TST_unspecified = clang::TST_unspecified;
+  static const TST TST_void = clang::TST_void;
+  static const TST TST_char = clang::TST_char;
+  static const TST TST_wchar = clang::TST_wchar;
+  static const TST TST_char16 = clang::TST_char16;
+  static const TST TST_char32 = clang::TST_char32;
+  static const TST TST_int = clang::TST_int;
+  static const TST TST_int128 = clang::TST_int128;
+  static const TST TST_half = clang::TST_half;
+  static const TST TST_float = clang::TST_float;
+  static const TST TST_double = clang::TST_double;
+  static const TST TST_bool = clang::TST_bool;
+  static const TST TST_decimal32 = clang::TST_decimal32;
+  static const TST TST_decimal64 = clang::TST_decimal64;
+  static const TST TST_decimal128 = clang::TST_decimal128;
+  static const TST TST_enum = clang::TST_enum;
+  static const TST TST_union = clang::TST_union;
+  static const TST TST_struct = clang::TST_struct;
+  static const TST TST_interface = clang::TST_interface;
+  static const TST TST_class = clang::TST_class;
+  static const TST TST_typename = clang::TST_typename;
+  static const TST TST_typeofType = clang::TST_typeofType;
+  static const TST TST_typeofExpr = clang::TST_typeofExpr;
+  static const TST TST_decltype = clang::TST_decltype;
+  static const TST TST_decltype_auto = clang::TST_decltype_auto;
+  static const TST TST_underlyingType = clang::TST_underlyingType;
+  static const TST TST_auto = clang::TST_auto;
+  static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
+  static const TST TST_atomic = clang::TST_atomic;
+  static const TST TST_error = clang::TST_error;
+
+  // type-qualifiers
+  enum TQ {   // NOTE: These flags must be kept in sync with Qualifiers::TQ.
+    TQ_unspecified = 0,
+    TQ_const       = 1,
+    TQ_restrict    = 2,
+    TQ_volatile    = 4,
+    // This has no corresponding Qualifiers::TQ value, because it's not treated
+    // as a qualifier in our type system.
+    TQ_atomic      = 8
+  };
+
+  /// ParsedSpecifiers - Flags to query which specifiers were applied.  This is
+  /// returned by getParsedSpecifiers.
+  enum ParsedSpecifiers {
+    PQ_None                  = 0,
+    PQ_StorageClassSpecifier = 1,
+    PQ_TypeSpecifier         = 2,
+    PQ_TypeQualifier         = 4,
+    PQ_FunctionSpecifier     = 8
+  };
+
+private:
+  // storage-class-specifier
+  /*SCS*/unsigned StorageClassSpec : 3;
+  /*TSCS*/unsigned ThreadStorageClassSpec : 2;
+  unsigned SCS_extern_in_linkage_spec : 1;
+
+  // type-specifier
+  /*TSW*/unsigned TypeSpecWidth : 2;
+  /*TSC*/unsigned TypeSpecComplex : 2;
+  /*TSS*/unsigned TypeSpecSign : 2;
+  /*TST*/unsigned TypeSpecType : 6;
+  unsigned TypeAltiVecVector : 1;
+  unsigned TypeAltiVecPixel : 1;
+  unsigned TypeAltiVecBool : 1;
+  unsigned TypeSpecOwned : 1;
+
+  // type-qualifiers
+  unsigned TypeQualifiers : 4;  // Bitwise OR of TQ.
+
+  // function-specifier
+  unsigned FS_inline_specified : 1;
+  unsigned FS_forceinline_specified: 1;
+  unsigned FS_virtual_specified : 1;
+  unsigned FS_explicit_specified : 1;
+  unsigned FS_noreturn_specified : 1;
+
+  // friend-specifier
+  unsigned Friend_specified : 1;
+
+  // constexpr-specifier
+  unsigned Constexpr_specified : 1;
+
+  union {
+    UnionParsedType TypeRep;
+    Decl *DeclRep;
+    Expr *ExprRep;
+  };
+
+  // attributes.
+  ParsedAttributes Attrs;
+
+  // Scope specifier for the type spec, if applicable.
+  CXXScopeSpec TypeScope;
+
+  // List of protocol qualifiers for objective-c classes.  Used for
+  // protocol-qualified interfaces "NString<foo>" and protocol-qualified id
+  // "id<foo>".
+  Decl * const *ProtocolQualifiers;
+  unsigned NumProtocolQualifiers;
+  SourceLocation ProtocolLAngleLoc;
+  SourceLocation *ProtocolLocs;
+
+  // SourceLocation info.  These are null if the item wasn't specified or if
+  // the setting was synthesized.
+  SourceRange Range;
+
+  SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc;
+  SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+  /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union,
+  /// typename, then this is the location of the named type (if present);
+  /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and
+  /// TSTNameLoc provides source range info for tag types.
+  SourceLocation TSTNameLoc;
+  SourceRange TypeofParensRange;
+  SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc;
+  SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc;
+  SourceLocation FS_forceinlineLoc;
+  SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc;
+
+  WrittenBuiltinSpecs writtenBS;
+  void SaveWrittenBuiltinSpecs();
+
+  ObjCDeclSpec *ObjCQualifiers;
+
+  static bool isTypeRep(TST T) {
+    return (T == TST_typename || T == TST_typeofType ||
+            T == TST_underlyingType || T == TST_atomic);
+  }
+  static bool isExprRep(TST T) {
+    return (T == TST_typeofExpr || T == TST_decltype);
+  }
+
+  DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION;
+  void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION;
+public:
+  static bool isDeclRep(TST T) {
+    return (T == TST_enum || T == TST_struct ||
+            T == TST_interface || T == TST_union ||
+            T == TST_class);
+  }
+
+  DeclSpec(AttributeFactory &attrFactory)
+    : StorageClassSpec(SCS_unspecified),
+      ThreadStorageClassSpec(TSCS_unspecified),
+      SCS_extern_in_linkage_spec(false),
+      TypeSpecWidth(TSW_unspecified),
+      TypeSpecComplex(TSC_unspecified),
+      TypeSpecSign(TSS_unspecified),
+      TypeSpecType(TST_unspecified),
+      TypeAltiVecVector(false),
+      TypeAltiVecPixel(false),
+      TypeAltiVecBool(false),
+      TypeSpecOwned(false),
+      TypeQualifiers(TQ_unspecified),
+      FS_inline_specified(false),
+      FS_forceinline_specified(false),
+      FS_virtual_specified(false),
+      FS_explicit_specified(false),
+      FS_noreturn_specified(false),
+      Friend_specified(false),
+      Constexpr_specified(false),
+      Attrs(attrFactory),
+      ProtocolQualifiers(nullptr),
+      NumProtocolQualifiers(0),
+      ProtocolLocs(nullptr),
+      writtenBS(),
+      ObjCQualifiers(nullptr) {
+  }
+  ~DeclSpec() {
+    delete [] ProtocolQualifiers;
+    delete [] ProtocolLocs;
+  }
+  // storage-class-specifier
+  SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; }
+  TSCS getThreadStorageClassSpec() const {
+    return (TSCS)ThreadStorageClassSpec;
+  }
+  bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; }
+  void setExternInLinkageSpec(bool Value) {
+    SCS_extern_in_linkage_spec = Value;
+  }
+
+  SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+  SourceLocation getThreadStorageClassSpecLoc() const {
+    return ThreadStorageClassSpecLoc;
+  }
+
+  void ClearStorageClassSpecs() {
+    StorageClassSpec           = DeclSpec::SCS_unspecified;
+    ThreadStorageClassSpec     = DeclSpec::TSCS_unspecified;
+    SCS_extern_in_linkage_spec = false;
+    StorageClassSpecLoc        = SourceLocation();
+    ThreadStorageClassSpecLoc  = SourceLocation();
+  }
+
+  void ClearTypeSpecType() {
+    TypeSpecType = DeclSpec::TST_unspecified;
+    TypeSpecOwned = false;
+    TSTLoc = SourceLocation();
+  }
+
+  // type-specifier
+  TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; }
+  TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
+  TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
+  TST getTypeSpecType() const { return (TST)TypeSpecType; }
+  bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
+  bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
+  bool isTypeAltiVecBool() const { return TypeAltiVecBool; }
+  bool isTypeSpecOwned() const { return TypeSpecOwned; }
+  ParsedType getRepAsType() const {
+    assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
+    return TypeRep;
+  }
+  Decl *getRepAsDecl() const {
+    assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl");
+    return DeclRep;
+  }
+  Expr *getRepAsExpr() const {
+    assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr");
+    return ExprRep;
+  }
+  CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
+  const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
+
+  const SourceRange &getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
+  SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+  SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
+  SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
+  SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+  SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
+
+  SourceLocation getTypeSpecTypeNameLoc() const {
+    assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename);
+    return TSTNameLoc;
+  }
+
+  SourceRange getTypeofParensRange() const { return TypeofParensRange; }
+  void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
+
+  bool containsPlaceholderType() const {
+    return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto;
+  }
+
+  bool hasTagDefinition() const;
+
+  /// \brief Turn a type-specifier-type into a string like "_Bool" or "union".
+  static const char *getSpecifierName(DeclSpec::TST T,
+                                      const PrintingPolicy &Policy);
+  static const char *getSpecifierName(DeclSpec::TQ Q);
+  static const char *getSpecifierName(DeclSpec::TSS S);
+  static const char *getSpecifierName(DeclSpec::TSC C);
+  static const char *getSpecifierName(DeclSpec::TSW W);
+  static const char *getSpecifierName(DeclSpec::SCS S);
+  static const char *getSpecifierName(DeclSpec::TSCS S);
+
+  // type-qualifiers
+
+  /// getTypeQualifiers - Return a set of TQs.
+  unsigned getTypeQualifiers() const { return TypeQualifiers; }
+  SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
+  SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
+  SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
+  SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; }
+
+  /// \brief Clear out all of the type qualifiers.
+  void ClearTypeQualifiers() {
+    TypeQualifiers = 0;
+    TQ_constLoc = SourceLocation();
+    TQ_restrictLoc = SourceLocation();
+    TQ_volatileLoc = SourceLocation();
+    TQ_atomicLoc = SourceLocation();
+  }
+
+  // function-specifier
+  bool isInlineSpecified() const {
+    return FS_inline_specified | FS_forceinline_specified;
+  }
+  SourceLocation getInlineSpecLoc() const {
+    return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc;
+  }
+
+  bool isVirtualSpecified() const { return FS_virtual_specified; }
+  SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; }
+
+  bool isExplicitSpecified() const { return FS_explicit_specified; }
+  SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; }
+
+  bool isNoreturnSpecified() const { return FS_noreturn_specified; }
+  SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; }
+
+  void ClearFunctionSpecs() {
+    FS_inline_specified = false;
+    FS_inlineLoc = SourceLocation();
+    FS_forceinline_specified = false;
+    FS_forceinlineLoc = SourceLocation();
+    FS_virtual_specified = false;
+    FS_virtualLoc = SourceLocation();
+    FS_explicit_specified = false;
+    FS_explicitLoc = SourceLocation();
+    FS_noreturn_specified = false;
+    FS_noreturnLoc = SourceLocation();
+  }
+
+  /// \brief Return true if any type-specifier has been found.
+  bool hasTypeSpecifier() const {
+    return getTypeSpecType() != DeclSpec::TST_unspecified ||
+           getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
+           getTypeSpecComplex() != DeclSpec::TSC_unspecified ||
+           getTypeSpecSign() != DeclSpec::TSS_unspecified;
+  }
+
+  /// \brief Return a bitmask of which flavors of specifiers this
+  /// DeclSpec includes.
+  unsigned getParsedSpecifiers() const;
+
+  /// isEmpty - Return true if this declaration specifier is completely empty:
+  /// no tokens were parsed in the production of it.
+  bool isEmpty() const {
+    return getParsedSpecifiers() == DeclSpec::PQ_None;
+  }
+
+  void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
+  void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
+
+  /// These methods set the specified attribute of the DeclSpec and
+  /// return false if there was no error.  If an error occurs (for
+  /// example, if we tried to set "auto" on a spec with "extern"
+  /// already set), they return true and set PrevSpec and DiagID
+  /// such that
+  ///   Diag(Loc, DiagID) << PrevSpec;
+  /// will yield a useful result.
+  ///
+  /// TODO: use a more general approach that still allows these
+  /// diagnostics to be ignored when desired.
+  bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
+                           const char *&PrevSpec, unsigned &DiagID,
+                           const PrintingPolicy &Policy);
+  bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
+                                 const char *&PrevSpec, unsigned &DiagID);
+  bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
+                        unsigned &DiagID, const PrintingPolicy &Policy);
+  bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
+                          unsigned &DiagID);
+  bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, const PrintingPolicy &Policy);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, ParsedType Rep,
+                       const PrintingPolicy &Policy);
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, Decl *Rep, bool Owned,
+                       const PrintingPolicy &Policy);
+  bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
+                       SourceLocation TagNameLoc, const char *&PrevSpec,
+                       unsigned &DiagID, ParsedType Rep,
+                       const PrintingPolicy &Policy);
+  bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
+                       SourceLocation TagNameLoc, const char *&PrevSpec,
+                       unsigned &DiagID, Decl *Rep, bool Owned,
+                       const PrintingPolicy &Policy);
+
+  bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+                       unsigned &DiagID, Expr *Rep,
+                       const PrintingPolicy &policy);
+  bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
+  bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
+  bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
+  bool SetTypeSpecError();
+  void UpdateDeclRep(Decl *Rep) {
+    assert(isDeclRep((TST) TypeSpecType));
+    DeclRep = Rep;
+  }
+  void UpdateTypeRep(ParsedType Rep) {
+    assert(isTypeRep((TST) TypeSpecType));
+    TypeRep = Rep;
+  }
+  void UpdateExprRep(Expr *Rep) {
+    assert(isExprRep((TST) TypeSpecType));
+    ExprRep = Rep;
+  }
+
+  bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+                   unsigned &DiagID, const LangOptions &Lang);
+
+  bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+                             unsigned &DiagID);
+  bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec,
+                                  unsigned &DiagID);
+  bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+                              unsigned &DiagID);
+  bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+                               unsigned &DiagID);
+  bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec,
+                               unsigned &DiagID);
+
+  bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+                     unsigned &DiagID);
+  bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec,
+                            unsigned &DiagID);
+  bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+                        unsigned &DiagID);
+
+  bool isFriendSpecified() const { return Friend_specified; }
+  SourceLocation getFriendSpecLoc() const { return FriendLoc; }
+
+  bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
+  SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; }
+  
+  bool isConstexprSpecified() const { return Constexpr_specified; }
+  SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
+
+  void ClearConstexprSpec() {
+    Constexpr_specified = false;
+    ConstexprLoc = SourceLocation();
+  }
+
+  AttributePool &getAttributePool() const {
+    return Attrs.getPool();
+  }
+
+  /// \brief Concatenates two attribute lists.
+  ///
+  /// The GCC attribute syntax allows for the following:
+  ///
+  /// \code
+  /// short __attribute__(( unused, deprecated ))
+  /// int __attribute__(( may_alias, aligned(16) )) var;
+  /// \endcode
+  ///
+  /// This declares 4 attributes using 2 lists. The following syntax is
+  /// also allowed and equivalent to the previous declaration.
+  ///
+  /// \code
+  /// short __attribute__((unused)) __attribute__((deprecated))
+  /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
+  /// \endcode
+  ///
+  void addAttributes(AttributeList *AL) {
+    Attrs.addAll(AL);
+  }
+
+  bool hasAttributes() const { return !Attrs.empty(); }
+
+  ParsedAttributes &getAttributes() { return Attrs; }
+  const ParsedAttributes &getAttributes() const { return Attrs; }
+
+  void takeAttributesFrom(ParsedAttributes &attrs) {
+    Attrs.takeAllFrom(attrs);
+  }
+
+  typedef Decl * const *ProtocolQualifierListTy;
+  ProtocolQualifierListTy getProtocolQualifiers() const {
+    return ProtocolQualifiers;
+  }
+  SourceLocation *getProtocolLocs() const { return ProtocolLocs; }
+  unsigned getNumProtocolQualifiers() const {
+    return NumProtocolQualifiers;
+  }
+  SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; }
+  void setProtocolQualifiers(Decl * const *Protos, unsigned NP,
+                             SourceLocation *ProtoLocs,
+                             SourceLocation LAngleLoc);
+
+  /// Finish - This does final analysis of the declspec, issuing diagnostics for
+  /// things like "_Imaginary" (lacking an FP type).  After calling this method,
+  /// DeclSpec is guaranteed self-consistent, even if an error occurred.
+  void Finish(DiagnosticsEngine &D, Preprocessor &PP,
+              const PrintingPolicy &Policy);
+
+  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
+    return writtenBS;
+  }
+
+  ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; }
+  void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; }
+
+  /// \brief Checks if this DeclSpec can stand alone, without a Declarator.
+  ///
+  /// Only tag declspecs can stand alone.
+  bool isMissingDeclaratorOk();
+};
+
+/// \brief Captures information about "declaration specifiers" specific to
+/// Objective-C.
+class ObjCDeclSpec {
+public:
+  /// ObjCDeclQualifier - Qualifier used on types in method
+  /// declarations.  Not all combinations are sensible.  Parameters
+  /// can be one of { in, out, inout } with one of { bycopy, byref }.
+  /// Returns can either be { oneway } or not.
+  ///
+  /// This should be kept in sync with Decl::ObjCDeclQualifier.
+  enum ObjCDeclQualifier {
+    DQ_None = 0x0,
+    DQ_In = 0x1,
+    DQ_Inout = 0x2,
+    DQ_Out = 0x4,
+    DQ_Bycopy = 0x8,
+    DQ_Byref = 0x10,
+    DQ_Oneway = 0x20
+  };
+
+  /// PropertyAttributeKind - list of property attributes.
+  enum ObjCPropertyAttributeKind {
+    DQ_PR_noattr = 0x0,
+    DQ_PR_readonly = 0x01,
+    DQ_PR_getter = 0x02,
+    DQ_PR_assign = 0x04,
+    DQ_PR_readwrite = 0x08,
+    DQ_PR_retain = 0x10,
+    DQ_PR_copy = 0x20,
+    DQ_PR_nonatomic = 0x40,
+    DQ_PR_setter = 0x80,
+    DQ_PR_atomic = 0x100,
+    DQ_PR_weak =   0x200,
+    DQ_PR_strong = 0x400,
+    DQ_PR_unsafe_unretained = 0x800
+  };
+
+
+  ObjCDeclSpec()
+    : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
+      GetterName(nullptr), SetterName(nullptr) { }
+  ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
+  void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
+    objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
+  }
+
+  ObjCPropertyAttributeKind getPropertyAttributes() const {
+    return ObjCPropertyAttributeKind(PropertyAttributes);
+  }
+  void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) {
+    PropertyAttributes =
+      (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal);
+  }
+
+  const IdentifierInfo *getGetterName() const { return GetterName; }
+  IdentifierInfo *getGetterName() { return GetterName; }
+  void setGetterName(IdentifierInfo *name) { GetterName = name; }
+
+  const IdentifierInfo *getSetterName() const { return SetterName; }
+  IdentifierInfo *getSetterName() { return SetterName; }
+  void setSetterName(IdentifierInfo *name) { SetterName = name; }
+
+private:
+  // FIXME: These two are unrelated and mutually exclusive. So perhaps
+  // we can put them in a union to reflect their mutual exclusivity
+  // (space saving is negligible).
+  ObjCDeclQualifier objcDeclQualifier : 6;
+
+  // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
+  unsigned PropertyAttributes : 12;
+  IdentifierInfo *GetterName;    // getter name or NULL if no getter
+  IdentifierInfo *SetterName;    // setter name or NULL if no setter
+};
+
+/// \brief Represents a C++ unqualified-id that has been parsed. 
+class UnqualifiedId {
+private:
+  UnqualifiedId(const UnqualifiedId &Other) LLVM_DELETED_FUNCTION;
+  const UnqualifiedId &operator=(const UnqualifiedId &) LLVM_DELETED_FUNCTION;
+
+public:
+  /// \brief Describes the kind of unqualified-id parsed.
+  enum IdKind {
+    /// \brief An identifier.
+    IK_Identifier,
+    /// \brief An overloaded operator name, e.g., operator+.
+    IK_OperatorFunctionId,
+    /// \brief A conversion function name, e.g., operator int.
+    IK_ConversionFunctionId,
+    /// \brief A user-defined literal name, e.g., operator "" _i.
+    IK_LiteralOperatorId,
+    /// \brief A constructor name.
+    IK_ConstructorName,
+    /// \brief A constructor named via a template-id.
+    IK_ConstructorTemplateId,
+    /// \brief A destructor name.
+    IK_DestructorName,
+    /// \brief A template-id, e.g., f<int>.
+    IK_TemplateId,
+    /// \brief An implicit 'self' parameter
+    IK_ImplicitSelfParam
+  } Kind;
+
+  struct OFI {
+    /// \brief The kind of overloaded operator.
+    OverloadedOperatorKind Operator;
+
+    /// \brief The source locations of the individual tokens that name
+    /// the operator, e.g., the "new", "[", and "]" tokens in 
+    /// operator new []. 
+    ///
+    /// Different operators have different numbers of tokens in their name,
+    /// up to three. Any remaining source locations in this array will be
+    /// set to an invalid value for operators with fewer than three tokens.
+    unsigned SymbolLocations[3];
+  };
+
+  /// \brief Anonymous union that holds extra data associated with the
+  /// parsed unqualified-id.
+  union {
+    /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind
+    /// == IK_UserLiteralId, the identifier suffix.
+    IdentifierInfo *Identifier;
+    
+    /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
+    /// that we parsed.
+    struct OFI OperatorFunctionId;
+    
+    /// \brief When Kind == IK_ConversionFunctionId, the type that the 
+    /// conversion function names.
+    UnionParsedType ConversionFunctionId;
+
+    /// \brief When Kind == IK_ConstructorName, the class-name of the type
+    /// whose constructor is being referenced.
+    UnionParsedType ConstructorName;
+    
+    /// \brief When Kind == IK_DestructorName, the type referred to by the
+    /// class-name.
+    UnionParsedType DestructorName;
+    
+    /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId,
+    /// the template-id annotation that contains the template name and
+    /// template arguments.
+    TemplateIdAnnotation *TemplateId;
+  };
+  
+  /// \brief The location of the first token that describes this unqualified-id,
+  /// which will be the location of the identifier, "operator" keyword,
+  /// tilde (for a destructor), or the template name of a template-id.
+  SourceLocation StartLocation;
+  
+  /// \brief The location of the last token that describes this unqualified-id.
+  SourceLocation EndLocation;
+  
+  UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
+
+  /// \brief Clear out this unqualified-id, setting it to default (invalid) 
+  /// state.
+  void clear() {
+    Kind = IK_Identifier;
+    Identifier = nullptr;
+    StartLocation = SourceLocation();
+    EndLocation = SourceLocation();
+  }
+  
+  /// \brief Determine whether this unqualified-id refers to a valid name.
+  bool isValid() const { return StartLocation.isValid(); }
+
+  /// \brief Determine whether this unqualified-id refers to an invalid name.
+  bool isInvalid() const { return !isValid(); }
+  
+  /// \brief Determine what kind of name we have.
+  IdKind getKind() const { return Kind; }
+  void setKind(IdKind kind) { Kind = kind; } 
+  
+  /// \brief Specify that this unqualified-id was parsed as an identifier.
+  ///
+  /// \param Id the parsed identifier.
+  /// \param IdLoc the location of the parsed identifier.
+  void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) {
+    Kind = IK_Identifier;
+    Identifier = const_cast<IdentifierInfo *>(Id);
+    StartLocation = EndLocation = IdLoc;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as an 
+  /// operator-function-id.
+  ///
+  /// \param OperatorLoc the location of the 'operator' keyword.
+  ///
+  /// \param Op the overloaded operator.
+  ///
+  /// \param SymbolLocations the locations of the individual operator symbols
+  /// in the operator.
+  void setOperatorFunctionId(SourceLocation OperatorLoc, 
+                             OverloadedOperatorKind Op,
+                             SourceLocation SymbolLocations[3]);
+  
+  /// \brief Specify that this unqualified-id was parsed as a 
+  /// conversion-function-id.
+  ///
+  /// \param OperatorLoc the location of the 'operator' keyword.
+  ///
+  /// \param Ty the type to which this conversion function is converting.
+  ///
+  /// \param EndLoc the location of the last token that makes up the type name.
+  void setConversionFunctionId(SourceLocation OperatorLoc, 
+                               ParsedType Ty,
+                               SourceLocation EndLoc) {
+    Kind = IK_ConversionFunctionId;
+    StartLocation = OperatorLoc;
+    EndLocation = EndLoc;
+    ConversionFunctionId = Ty;
+  }
+
+  /// \brief Specific that this unqualified-id was parsed as a
+  /// literal-operator-id.
+  ///
+  /// \param Id the parsed identifier.
+  ///
+  /// \param OpLoc the location of the 'operator' keyword.
+  ///
+  /// \param IdLoc the location of the identifier.
+  void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
+                              SourceLocation IdLoc) {
+    Kind = IK_LiteralOperatorId;
+    Identifier = const_cast<IdentifierInfo *>(Id);
+    StartLocation = OpLoc;
+    EndLocation = IdLoc;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as a constructor name.
+  ///
+  /// \param ClassType the class type referred to by the constructor name.
+  ///
+  /// \param ClassNameLoc the location of the class name.
+  ///
+  /// \param EndLoc the location of the last token that makes up the type name.
+  void setConstructorName(ParsedType ClassType, 
+                          SourceLocation ClassNameLoc,
+                          SourceLocation EndLoc) {
+    Kind = IK_ConstructorName;
+    StartLocation = ClassNameLoc;
+    EndLocation = EndLoc;
+    ConstructorName = ClassType;
+  }
+
+  /// \brief Specify that this unqualified-id was parsed as a
+  /// template-id that names a constructor.
+  ///
+  /// \param TemplateId the template-id annotation that describes the parsed
+  /// template-id. This UnqualifiedId instance will take ownership of the
+  /// \p TemplateId and will free it on destruction.
+  void setConstructorTemplateId(TemplateIdAnnotation *TemplateId);
+
+  /// \brief Specify that this unqualified-id was parsed as a destructor name.
+  ///
+  /// \param TildeLoc the location of the '~' that introduces the destructor
+  /// name.
+  ///
+  /// \param ClassType the name of the class referred to by the destructor name.
+  void setDestructorName(SourceLocation TildeLoc,
+                         ParsedType ClassType,
+                         SourceLocation EndLoc) {
+    Kind = IK_DestructorName;
+    StartLocation = TildeLoc;
+    EndLocation = EndLoc;
+    DestructorName = ClassType;
+  }
+  
+  /// \brief Specify that this unqualified-id was parsed as a template-id.
+  ///
+  /// \param TemplateId the template-id annotation that describes the parsed
+  /// template-id. This UnqualifiedId instance will take ownership of the
+  /// \p TemplateId and will free it on destruction.
+  void setTemplateId(TemplateIdAnnotation *TemplateId);
+
+  /// \brief Return the source range that covers this unqualified-id.
+  SourceRange getSourceRange() const LLVM_READONLY { 
+    return SourceRange(StartLocation, EndLocation); 
+  }
+  SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; }
+};
+
+/// \brief A set of tokens that has been cached for later parsing.
+typedef SmallVector<Token, 4> CachedTokens;
+
+/// \brief One instance of this struct is used for each type in a
+/// declarator that is parsed.
+///
+/// This is intended to be a small value object.
+struct DeclaratorChunk {
+  enum {
+    Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren
+  } Kind;
+
+  /// Loc - The place where this type was defined.
+  SourceLocation Loc;
+  /// EndLoc - If valid, the place where this chunck ends.
+  SourceLocation EndLoc;
+
+  struct TypeInfoCommon {
+    AttributeList *AttrList;
+  };
+
+  struct PointerTypeInfo : TypeInfoCommon {
+    /// The type qualifiers: const/volatile/restrict/atomic.
+    unsigned TypeQuals : 4;
+
+    /// The location of the const-qualifier, if any.
+    unsigned ConstQualLoc;
+
+    /// The location of the volatile-qualifier, if any.
+    unsigned VolatileQualLoc;
+
+    /// The location of the restrict-qualifier, if any.
+    unsigned RestrictQualLoc;
+
+    /// The location of the _Atomic-qualifier, if any.
+    unsigned AtomicQualLoc;
+
+    void destroy() {
+    }
+  };
+
+  struct ReferenceTypeInfo : TypeInfoCommon {
+    /// The type qualifier: restrict. [GNU] C++ extension
+    bool HasRestrict : 1;
+    /// True if this is an lvalue reference, false if it's an rvalue reference.
+    bool LValueRef : 1;
+    void destroy() {
+    }
+  };
+
+  struct ArrayTypeInfo : TypeInfoCommon {
+    /// The type qualifiers for the array: const/volatile/restrict/_Atomic.
+    unsigned TypeQuals : 4;
+
+    /// True if this dimension included the 'static' keyword.
+    bool hasStatic : 1;
+
+    /// True if this dimension was [*].  In this case, NumElts is null.
+    bool isStar : 1;
+
+    /// This is the size of the array, or null if [] or [*] was specified.
+    /// Since the parser is multi-purpose, and we don't want to impose a root
+    /// expression class on all clients, NumElts is untyped.
+    Expr *NumElts;
+
+    void destroy() {}
+  };
+
+  /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+  /// declarator is parsed.  There are two interesting styles of parameters
+  /// here:
+  /// K&R-style identifier lists and parameter type lists.  K&R-style identifier
+  /// lists will have information about the identifier, but no type information.
+  /// Parameter type lists will have type info (if the actions module provides
+  /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
+  struct ParamInfo {
+    IdentifierInfo *Ident;
+    SourceLocation IdentLoc;
+    Decl *Param;
+
+    /// DefaultArgTokens - When the parameter's default argument
+    /// cannot be parsed immediately (because it occurs within the
+    /// declaration of a member function), it will be stored here as a
+    /// sequence of tokens to be parsed once the class definition is
+    /// complete. Non-NULL indicates that there is a default argument.
+    CachedTokens *DefaultArgTokens;
+
+    ParamInfo() {}
+    ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
+              Decl *param,
+              CachedTokens *DefArgTokens = nullptr)
+      : Ident(ident), IdentLoc(iloc), Param(param),
+        DefaultArgTokens(DefArgTokens) {}
+  };
+
+  struct TypeAndRange {
+    ParsedType Ty;
+    SourceRange Range;
+  };
+
+  struct FunctionTypeInfo : TypeInfoCommon {
+    /// hasPrototype - This is true if the function had at least one typed
+    /// parameter.  If the function is () or (a,b,c), then it has no prototype,
+    /// and is treated as a K&R-style function.
+    unsigned hasPrototype : 1;
+
+    /// isVariadic - If this function has a prototype, and if that
+    /// proto ends with ',...)', this is true. When true, EllipsisLoc
+    /// contains the location of the ellipsis.
+    unsigned isVariadic : 1;
+
+    /// Can this declaration be a constructor-style initializer?
+    unsigned isAmbiguous : 1;
+
+    /// \brief Whether the ref-qualifier (if any) is an lvalue reference.
+    /// Otherwise, it's an rvalue reference.
+    unsigned RefQualifierIsLValueRef : 1;
+
+    /// The type qualifiers: const/volatile/restrict.
+    /// The qualifier bitmask values are the same as in QualType.
+    unsigned TypeQuals : 3;
+
+    /// ExceptionSpecType - An ExceptionSpecificationType value.
+    unsigned ExceptionSpecType : 3;
+
+    /// DeleteParams - If this is true, we need to delete[] Params.
+    unsigned DeleteParams : 1;
+
+    /// HasTrailingReturnType - If this is true, a trailing return type was
+    /// specified.
+    unsigned HasTrailingReturnType : 1;
+
+    /// The location of the left parenthesis in the source.
+    unsigned LParenLoc;
+
+    /// When isVariadic is true, the location of the ellipsis in the source.
+    unsigned EllipsisLoc;
+
+    /// The location of the right parenthesis in the source.
+    unsigned RParenLoc;
+
+    /// NumParams - This is the number of formal parameters specified by the
+    /// declarator.
+    unsigned NumParams;
+
+    /// NumExceptions - This is the number of types in the dynamic-exception-
+    /// decl, if the function has one.
+    unsigned NumExceptions;
+
+    /// \brief The location of the ref-qualifier, if any.
+    ///
+    /// If this is an invalid location, there is no ref-qualifier.
+    unsigned RefQualifierLoc;
+
+    /// \brief The location of the const-qualifier, if any.
+    ///
+    /// If this is an invalid location, there is no const-qualifier.
+    unsigned ConstQualifierLoc;
+
+    /// \brief The location of the volatile-qualifier, if any.
+    ///
+    /// If this is an invalid location, there is no volatile-qualifier.
+    unsigned VolatileQualifierLoc;
+
+    /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if
+    /// any.
+    unsigned MutableLoc;
+
+    /// \brief The location of the keyword introducing the spec, if any.
+    unsigned ExceptionSpecLoc;
+
+    /// Params - This is a pointer to a new[]'d array of ParamInfo objects that
+    /// describe the parameters specified by this function declarator.  null if
+    /// there are no parameters specified.
+    ParamInfo *Params;
+
+    union {
+      /// \brief Pointer to a new[]'d array of TypeAndRange objects that
+      /// contain the types in the function's dynamic exception specification
+      /// and their locations, if there is one.
+      TypeAndRange *Exceptions;
+
+      /// \brief Pointer to the expression in the noexcept-specifier of this
+      /// function, if it has one.
+      Expr *NoexceptExpr;
+    };
+
+    /// \brief If HasTrailingReturnType is true, this is the trailing return
+    /// type specified.
+    UnionParsedType TrailingReturnType;
+
+    /// \brief Reset the parameter list to having zero parameters.
+    ///
+    /// This is used in various places for error recovery.
+    void freeParams() {
+      for (unsigned I = 0; I < NumParams; ++I) {
+        delete Params[I].DefaultArgTokens;
+        Params[I].DefaultArgTokens = nullptr;
+      }
+      if (DeleteParams) {
+        delete[] Params;
+        DeleteParams = false;
+      }
+      NumParams = 0;
+    }
+
+    void destroy() {
+      if (DeleteParams)
+        delete[] Params;
+      if (getExceptionSpecType() == EST_Dynamic)
+        delete[] Exceptions;
+    }
+
+    /// isKNRPrototype - Return true if this is a K&R style identifier list,
+    /// like "void foo(a,b,c)".  In a function definition, this will be followed
+    /// by the parameter type definitions.
+    bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; }
+
+    SourceLocation getLParenLoc() const {
+      return SourceLocation::getFromRawEncoding(LParenLoc);
+    }
+
+    SourceLocation getEllipsisLoc() const {
+      return SourceLocation::getFromRawEncoding(EllipsisLoc);
+    }
+
+    SourceLocation getRParenLoc() const {
+      return SourceLocation::getFromRawEncoding(RParenLoc);
+    }
+
+    SourceLocation getExceptionSpecLoc() const {
+      return SourceLocation::getFromRawEncoding(ExceptionSpecLoc);
+    }
+
+    /// \brief Retrieve the location of the ref-qualifier, if any.
+    SourceLocation getRefQualifierLoc() const {
+      return SourceLocation::getFromRawEncoding(RefQualifierLoc);
+    }
+
+    /// \brief Retrieve the location of the ref-qualifier, if any.
+    SourceLocation getConstQualifierLoc() const {
+      return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
+    }
+
+    /// \brief Retrieve the location of the ref-qualifier, if any.
+    SourceLocation getVolatileQualifierLoc() const {
+      return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
+    }
+
+    /// \brief Retrieve the location of the 'mutable' qualifier, if any.
+    SourceLocation getMutableLoc() const {
+      return SourceLocation::getFromRawEncoding(MutableLoc);
+    }
+
+    /// \brief Determine whether this function declaration contains a 
+    /// ref-qualifier.
+    bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
+
+    /// \brief Determine whether this lambda-declarator contains a 'mutable'
+    /// qualifier.
+    bool hasMutableQualifier() const { return getMutableLoc().isValid(); }
+
+    /// \brief Get the type of exception specification this function has.
+    ExceptionSpecificationType getExceptionSpecType() const {
+      return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+    }
+
+    /// \brief Determine whether this function declarator had a
+    /// trailing-return-type.
+    bool hasTrailingReturnType() const { return HasTrailingReturnType; }
+
+    /// \brief Get the trailing-return-type for this function declarator.
+    ParsedType getTrailingReturnType() const { return TrailingReturnType; }
+  };
+
+  struct BlockPointerTypeInfo : TypeInfoCommon {
+    /// For now, sema will catch these as invalid.
+    /// The type qualifiers: const/volatile/restrict/_Atomic.
+    unsigned TypeQuals : 4;
+
+    void destroy() {
+    }
+  };
+
+  struct MemberPointerTypeInfo : TypeInfoCommon {
+    /// The type qualifiers: const/volatile/restrict/_Atomic.
+    unsigned TypeQuals : 4;
+    // CXXScopeSpec has a constructor, so it can't be a direct member.
+    // So we need some pointer-aligned storage and a bit of trickery.
+    union {
+      void *Aligner;
+      char Mem[sizeof(CXXScopeSpec)];
+    } ScopeMem;
+    CXXScopeSpec &Scope() {
+      return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem);
+    }
+    const CXXScopeSpec &Scope() const {
+      return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem);
+    }
+    void destroy() {
+      Scope().~CXXScopeSpec();
+    }
+  };
+
+  union {
+    TypeInfoCommon        Common;
+    PointerTypeInfo       Ptr;
+    ReferenceTypeInfo     Ref;
+    ArrayTypeInfo         Arr;
+    FunctionTypeInfo      Fun;
+    BlockPointerTypeInfo  Cls;
+    MemberPointerTypeInfo Mem;
+  };
+
+  void destroy() {
+    switch (Kind) {
+    case DeclaratorChunk::Function:      return Fun.destroy();
+    case DeclaratorChunk::Pointer:       return Ptr.destroy();
+    case DeclaratorChunk::BlockPointer:  return Cls.destroy();
+    case DeclaratorChunk::Reference:     return Ref.destroy();
+    case DeclaratorChunk::Array:         return Arr.destroy();
+    case DeclaratorChunk::MemberPointer: return Mem.destroy();
+    case DeclaratorChunk::Paren:         return;
+    }
+  }
+
+  /// \brief If there are attributes applied to this declaratorchunk, return
+  /// them.
+  const AttributeList *getAttrs() const {
+    return Common.AttrList;
+  }
+
+  AttributeList *&getAttrListRef() {
+    return Common.AttrList;
+  }
+
+  /// \brief Return a DeclaratorChunk for a pointer.
+  static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
+                                    SourceLocation ConstQualLoc,
+                                    SourceLocation VolatileQualLoc,
+                                    SourceLocation RestrictQualLoc) {
+    DeclaratorChunk I;
+    I.Kind                = Pointer;
+    I.Loc                 = Loc;
+    I.Ptr.TypeQuals       = TypeQuals;
+    I.Ptr.ConstQualLoc    = ConstQualLoc.getRawEncoding();
+    I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
+    I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
+    I.Ptr.AttrList        = nullptr;
+    return I;
+  }
+
+  /// \brief Return a DeclaratorChunk for a reference.
+  static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
+                                      bool lvalue) {
+    DeclaratorChunk I;
+    I.Kind            = Reference;
+    I.Loc             = Loc;
+    I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
+    I.Ref.LValueRef   = lvalue;
+    I.Ref.AttrList    = nullptr;
+    return I;
+  }
+
+  /// \brief Return a DeclaratorChunk for an array.
+  static DeclaratorChunk getArray(unsigned TypeQuals,
+                                  bool isStatic, bool isStar, Expr *NumElts,
+                                  SourceLocation LBLoc, SourceLocation RBLoc) {
+    DeclaratorChunk I;
+    I.Kind          = Array;
+    I.Loc           = LBLoc;
+    I.EndLoc        = RBLoc;
+    I.Arr.AttrList  = nullptr;
+    I.Arr.TypeQuals = TypeQuals;
+    I.Arr.hasStatic = isStatic;
+    I.Arr.isStar    = isStar;
+    I.Arr.NumElts   = NumElts;
+    return I;
+  }
+
+  /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+  /// "TheDeclarator" is the declarator that this will be added to.
+  static DeclaratorChunk getFunction(bool HasProto,
+                                     bool IsAmbiguous,
+                                     SourceLocation LParenLoc,
+                                     ParamInfo *Params, unsigned NumParams,
+                                     SourceLocation EllipsisLoc,
+                                     SourceLocation RParenLoc,
+                                     unsigned TypeQuals,
+                                     bool RefQualifierIsLvalueRef,
+                                     SourceLocation RefQualifierLoc,
+                                     SourceLocation ConstQualifierLoc,
+                                     SourceLocation VolatileQualifierLoc,
+                                     SourceLocation MutableLoc,
+                                     ExceptionSpecificationType ESpecType,
+                                     SourceLocation ESpecLoc,
+                                     ParsedType *Exceptions,
+                                     SourceRange *ExceptionRanges,
+                                     unsigned NumExceptions,
+                                     Expr *NoexceptExpr,
+                                     SourceLocation LocalRangeBegin,
+                                     SourceLocation LocalRangeEnd,
+                                     Declarator &TheDeclarator,
+                                     TypeResult TrailingReturnType =
+                                                    TypeResult());
+
+  /// \brief Return a DeclaratorChunk for a block.
+  static DeclaratorChunk getBlockPointer(unsigned TypeQuals,
+                                         SourceLocation Loc) {
+    DeclaratorChunk I;
+    I.Kind          = BlockPointer;
+    I.Loc           = Loc;
+    I.Cls.TypeQuals = TypeQuals;
+    I.Cls.AttrList  = nullptr;
+    return I;
+  }
+
+  static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
+                                          unsigned TypeQuals,
+                                          SourceLocation Loc) {
+    DeclaratorChunk I;
+    I.Kind          = MemberPointer;
+    I.Loc           = Loc;
+    I.Mem.TypeQuals = TypeQuals;
+    I.Mem.AttrList  = nullptr;
+    new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
+    return I;
+  }
+
+  /// \brief Return a DeclaratorChunk for a paren.
+  static DeclaratorChunk getParen(SourceLocation LParenLoc,
+                                  SourceLocation RParenLoc) {
+    DeclaratorChunk I;
+    I.Kind          = Paren;
+    I.Loc           = LParenLoc;
+    I.EndLoc        = RParenLoc;
+    I.Common.AttrList = nullptr;
+    return I;
+  }
+
+  bool isParen() const {
+    return Kind == Paren;
+  }
+};
+
+/// \brief Described the kind of function definition (if any) provided for
+/// a function.
+enum FunctionDefinitionKind {
+  FDK_Declaration,
+  FDK_Definition,
+  FDK_Defaulted,
+  FDK_Deleted
+};
+
+/// \brief Information about one declarator, including the parsed type
+/// information and the identifier.
+///
+/// When the declarator is fully formed, this is turned into the appropriate
+/// Decl object.
+///
+/// Declarators come in two types: normal declarators and abstract declarators.
+/// Abstract declarators are used when parsing types, and don't have an
+/// identifier.  Normal declarators do have ID's.
+///
+/// Instances of this class should be a transient object that lives on the
+/// stack, not objects that are allocated in large quantities on the heap.
+class Declarator {
+public:
+  enum TheContext {
+    FileContext,         // File scope declaration.
+    PrototypeContext,    // Within a function prototype.
+    ObjCResultContext,   // An ObjC method result type.
+    ObjCParameterContext,// An ObjC method parameter type.
+    KNRTypeListContext,  // K&R type definition list for formals.
+    TypeNameContext,     // Abstract declarator for types.
+    MemberContext,       // Struct/Union field.
+    BlockContext,        // Declaration within a block in a function.
+    ForContext,          // Declaration within first part of a for loop.
+    ConditionContext,    // Condition declaration in a C++ if/switch/while/for.
+    TemplateParamContext,// Within a template parameter list.
+    CXXNewContext,       // C++ new-expression.
+    CXXCatchContext,     // C++ catch exception-declaration
+    ObjCCatchContext,    // Objective-C catch exception-declaration
+    BlockLiteralContext, // Block literal declarator.
+    LambdaExprContext,   // Lambda-expression declarator.
+    LambdaExprParameterContext, // Lambda-expression parameter declarator.
+    ConversionIdContext, // C++ conversion-type-id.
+    TrailingReturnContext, // C++11 trailing-type-specifier.
+    TemplateTypeArgContext, // Template type argument.
+    AliasDeclContext,    // C++11 alias-declaration.
+    AliasTemplateContext // C++11 alias-declaration template.
+  };
+
+private:
+  const DeclSpec &DS;
+  CXXScopeSpec SS;
+  UnqualifiedId Name;
+  SourceRange Range;
+
+  /// \brief Where we are parsing this declarator.
+  TheContext Context;
+
+  /// DeclTypeInfo - This holds each type that the declarator includes as it is
+  /// parsed.  This is pushed from the identifier out, which means that element
+  /// #0 will be the most closely bound to the identifier, and
+  /// DeclTypeInfo.back() will be the least closely bound.
+  SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
+
+  /// InvalidType - Set by Sema::GetTypeForDeclarator().
+  bool InvalidType : 1;
+
+  /// GroupingParens - Set by Parser::ParseParenDeclarator().
+  bool GroupingParens : 1;
+
+  /// FunctionDefinition - Is this Declarator for a function or member 
+  /// definition and, if so, what kind?
+  ///
+  /// Actually a FunctionDefinitionKind.
+  unsigned FunctionDefinition : 2;
+
+  /// \brief Is this Declarator a redeclaration?
+  bool Redeclaration : 1;
+
+  /// Attrs - Attributes.
+  ParsedAttributes Attrs;
+
+  /// \brief The asm label, if specified.
+  Expr *AsmLabel;
+
+  /// InlineParams - This is a local array used for the first function decl
+  /// chunk to avoid going to the heap for the common case when we have one
+  /// function chunk in the declarator.
+  DeclaratorChunk::ParamInfo InlineParams[16];
+  bool InlineParamsUsed;
+
+  /// \brief true if the declaration is preceded by \c __extension__.
+  bool Extension : 1;
+
+  /// \brief If this is the second or subsequent declarator in this declaration,
+  /// the location of the comma before this declarator.
+  SourceLocation CommaLoc;
+
+  /// \brief If provided, the source location of the ellipsis used to describe
+  /// this declarator as a parameter pack.
+  SourceLocation EllipsisLoc;
+  
+  friend struct DeclaratorChunk;
+
+public:
+  Declarator(const DeclSpec &ds, TheContext C)
+    : DS(ds), Range(ds.getSourceRange()), Context(C),
+      InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
+      GroupingParens(false), FunctionDefinition(FDK_Declaration), 
+      Redeclaration(false),
+      Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
+      InlineParamsUsed(false), Extension(false) {
+  }
+
+  ~Declarator() {
+    clear();
+  }
+  /// getDeclSpec - Return the declaration-specifier that this declarator was
+  /// declared with.
+  const DeclSpec &getDeclSpec() const { return DS; }
+
+  /// getMutableDeclSpec - Return a non-const version of the DeclSpec.  This
+  /// should be used with extreme care: declspecs can often be shared between
+  /// multiple declarators, so mutating the DeclSpec affects all of the
+  /// Declarators.  This should only be done when the declspec is known to not
+  /// be shared or when in error recovery etc.
+  DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); }
+
+  AttributePool &getAttributePool() const {
+    return Attrs.getPool();
+  }
+
+  /// getCXXScopeSpec - Return the C++ scope specifier (global scope or
+  /// nested-name-specifier) that is part of the declarator-id.
+  const CXXScopeSpec &getCXXScopeSpec() const { return SS; }
+  CXXScopeSpec &getCXXScopeSpec() { return SS; }
+
+  /// \brief Retrieve the name specified by this declarator.
+  UnqualifiedId &getName() { return Name; }
+  
+  TheContext getContext() const { return Context; }
+
+  bool isPrototypeContext() const {
+    return (Context == PrototypeContext ||
+            Context == ObjCParameterContext ||
+            Context == ObjCResultContext ||
+            Context == LambdaExprParameterContext);
+  }
+
+  /// \brief Get the source range that spans this declarator.
+  const SourceRange &getSourceRange() const LLVM_READONLY { return Range; }
+  SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
+  void SetSourceRange(SourceRange R) { Range = R; }
+  /// SetRangeBegin - Set the start of the source range to Loc, unless it's
+  /// invalid.
+  void SetRangeBegin(SourceLocation Loc) {
+    if (!Loc.isInvalid())
+      Range.setBegin(Loc);
+  }
+  /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
+  void SetRangeEnd(SourceLocation Loc) {
+    if (!Loc.isInvalid())
+      Range.setEnd(Loc);
+  }
+  /// ExtendWithDeclSpec - Extend the declarator source range to include the
+  /// given declspec, unless its location is invalid. Adopts the range start if
+  /// the current range start is invalid.
+  void ExtendWithDeclSpec(const DeclSpec &DS) {
+    const SourceRange &SR = DS.getSourceRange();
+    if (Range.getBegin().isInvalid())
+      Range.setBegin(SR.getBegin());
+    if (!SR.getEnd().isInvalid())
+      Range.setEnd(SR.getEnd());
+  }
+
+  /// \brief Reset the contents of this Declarator.
+  void clear() {
+    SS.clear();
+    Name.clear();
+    Range = DS.getSourceRange();
+    
+    for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
+      DeclTypeInfo[i].destroy();
+    DeclTypeInfo.clear();
+    Attrs.clear();
+    AsmLabel = nullptr;
+    InlineParamsUsed = false;
+    CommaLoc = SourceLocation();
+    EllipsisLoc = SourceLocation();
+  }
+
+  /// mayOmitIdentifier - Return true if the identifier is either optional or
+  /// not allowed.  This is true for typenames, prototypes, and template
+  /// parameter lists.
+  bool mayOmitIdentifier() const {
+    switch (Context) {
+    case FileContext:
+    case KNRTypeListContext:
+    case MemberContext:
+    case BlockContext:
+    case ForContext:
+    case ConditionContext:
+      return false;
+
+    case TypeNameContext:
+    case AliasDeclContext:
+    case AliasTemplateContext:
+    case PrototypeContext:
+    case LambdaExprParameterContext:
+    case ObjCParameterContext:
+    case ObjCResultContext:
+    case TemplateParamContext:
+    case CXXNewContext:
+    case CXXCatchContext:
+    case ObjCCatchContext:
+    case BlockLiteralContext:
+    case LambdaExprContext:
+    case ConversionIdContext:
+    case TemplateTypeArgContext:
+    case TrailingReturnContext:
+      return true;
+    }
+    llvm_unreachable("unknown context kind!");
+  }
+
+  /// mayHaveIdentifier - Return true if the identifier is either optional or
+  /// required.  This is true for normal declarators and prototypes, but not
+  /// typenames.
+  bool mayHaveIdentifier() const {
+    switch (Context) {
+    case FileContext:
+    case KNRTypeListContext:
+    case MemberContext:
+    case BlockContext:
+    case ForContext:
+    case ConditionContext:
+    case PrototypeContext:
+    case LambdaExprParameterContext:
+    case TemplateParamContext:
+    case CXXCatchContext:
+    case ObjCCatchContext:
+      return true;
+
+    case TypeNameContext:
+    case CXXNewContext:
+    case AliasDeclContext:
+    case AliasTemplateContext:
+    case ObjCParameterContext:
+    case ObjCResultContext:
+    case BlockLiteralContext:
+    case LambdaExprContext:
+    case ConversionIdContext:
+    case TemplateTypeArgContext:
+    case TrailingReturnContext:
+      return false;
+    }
+    llvm_unreachable("unknown context kind!");
+  }
+
+  /// diagnoseIdentifier - Return true if the identifier is prohibited and
+  /// should be diagnosed (because it cannot be anything else).
+  bool diagnoseIdentifier() const {
+    switch (Context) {
+    case FileContext:
+    case KNRTypeListContext:
+    case MemberContext:
+    case BlockContext:
+    case ForContext:
+    case ConditionContext:
+    case PrototypeContext:
+    case LambdaExprParameterContext:
+    case TemplateParamContext:
+    case CXXCatchContext:
+    case ObjCCatchContext:
+    case TypeNameContext:
+    case ConversionIdContext:
+    case ObjCParameterContext:
+    case ObjCResultContext:
+    case BlockLiteralContext:
+    case CXXNewContext:
+    case LambdaExprContext:
+      return false;
+
+    case AliasDeclContext:
+    case AliasTemplateContext:
+    case TemplateTypeArgContext:
+    case TrailingReturnContext:
+      return true;
+    }
+    llvm_unreachable("unknown context kind!");
+  }
+
+  /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be
+  /// followed by a C++ direct initializer, e.g. "int x(1);".
+  bool mayBeFollowedByCXXDirectInit() const {
+    if (hasGroupingParens()) return false;
+
+    if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+      return false;
+
+    if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern &&
+        Context != FileContext)
+      return false;
+
+    // Special names can't have direct initializers.
+    if (Name.getKind() != UnqualifiedId::IK_Identifier)
+      return false;
+
+    switch (Context) {
+    case FileContext:
+    case BlockContext:
+    case ForContext:
+      return true;
+
+    case ConditionContext:
+      // This may not be followed by a direct initializer, but it can't be a
+      // function declaration either, and we'd prefer to perform a tentative
+      // parse in order to produce the right diagnostic.
+      return true;
+
+    case KNRTypeListContext:
+    case MemberContext:
+    case PrototypeContext:
+    case LambdaExprParameterContext:
+    case ObjCParameterContext:
+    case ObjCResultContext:
+    case TemplateParamContext:
+    case CXXCatchContext:
+    case ObjCCatchContext:
+    case TypeNameContext:
+    case CXXNewContext:
+    case AliasDeclContext:
+    case AliasTemplateContext:
+    case BlockLiteralContext:
+    case LambdaExprContext:
+    case ConversionIdContext:
+    case TemplateTypeArgContext:
+    case TrailingReturnContext:
+      return false;
+    }
+    llvm_unreachable("unknown context kind!");
+  }
+
+  /// isPastIdentifier - Return true if we have parsed beyond the point where
+  /// the
+  bool isPastIdentifier() const { return Name.isValid(); }
+
+  /// hasName - Whether this declarator has a name, which might be an
+  /// identifier (accessible via getIdentifier()) or some kind of
+  /// special C++ name (constructor, destructor, etc.).
+  bool hasName() const { 
+    return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier;
+  }
+
+  IdentifierInfo *getIdentifier() const { 
+    if (Name.getKind() == UnqualifiedId::IK_Identifier)
+      return Name.Identifier;
+    
+    return nullptr;
+  }
+  SourceLocation getIdentifierLoc() const { return Name.StartLocation; }
+
+  /// \brief Set the name of this declarator to be the given identifier.
+  void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) {
+    Name.setIdentifier(Id, IdLoc);
+  }
+  
+  /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
+  /// EndLoc, which should be the last token of the chunk.
+  void AddTypeInfo(const DeclaratorChunk &TI,
+                   ParsedAttributes &attrs,
+                   SourceLocation EndLoc) {
+    DeclTypeInfo.push_back(TI);
+    DeclTypeInfo.back().getAttrListRef() = attrs.getList();
+    getAttributePool().takeAllFrom(attrs.getPool());
+
+    if (!EndLoc.isInvalid())
+      SetRangeEnd(EndLoc);
+  }
+
+  /// \brief Add a new innermost chunk to this declarator.
+  void AddInnermostTypeInfo(const DeclaratorChunk &TI) {
+    DeclTypeInfo.insert(DeclTypeInfo.begin(), TI);
+  }
+
+  /// \brief Return the number of types applied to this declarator.
+  unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
+
+  /// Return the specified TypeInfo from this declarator.  TypeInfo #0 is
+  /// closest to the identifier.
+  const DeclaratorChunk &getTypeObject(unsigned i) const {
+    assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+    return DeclTypeInfo[i];
+  }
+  DeclaratorChunk &getTypeObject(unsigned i) {
+    assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+    return DeclTypeInfo[i];
+  }
+
+  void DropFirstTypeObject() {
+    assert(!DeclTypeInfo.empty() && "No type chunks to drop.");
+    DeclTypeInfo.front().destroy();
+    DeclTypeInfo.erase(DeclTypeInfo.begin());
+  }
+
+  /// Return the innermost (closest to the declarator) chunk of this
+  /// declarator that is not a parens chunk, or null if there are no
+  /// non-parens chunks.
+  const DeclaratorChunk *getInnermostNonParenChunk() const {
+    for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
+      if (!DeclTypeInfo[i].isParen())
+        return &DeclTypeInfo[i];
+    }
+    return nullptr;
+  }
+
+  /// Return the outermost (furthest from the declarator) chunk of
+  /// this declarator that is not a parens chunk, or null if there are
+  /// no non-parens chunks.
+  const DeclaratorChunk *getOutermostNonParenChunk() const {
+    for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) {
+      if (!DeclTypeInfo[i-1].isParen())
+        return &DeclTypeInfo[i-1];
+    }
+    return nullptr;
+  }
+
+  /// isArrayOfUnknownBound - This method returns true if the declarator
+  /// is a declarator for an array of unknown bound (looking through
+  /// parentheses).
+  bool isArrayOfUnknownBound() const {
+    const DeclaratorChunk *chunk = getInnermostNonParenChunk();
+    return (chunk && chunk->Kind == DeclaratorChunk::Array &&
+            !chunk->Arr.NumElts);
+  }
+
+  /// isFunctionDeclarator - This method returns true if the declarator
+  /// is a function declarator (looking through parentheses).
+  /// If true is returned, then the reference type parameter idx is
+  /// assigned with the index of the declaration chunk.
+  bool isFunctionDeclarator(unsigned& idx) const {
+    for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
+      switch (DeclTypeInfo[i].Kind) {
+      case DeclaratorChunk::Function:
+        idx = i;
+        return true;
+      case DeclaratorChunk::Paren:
+        continue;
+      case DeclaratorChunk::Pointer:
+      case DeclaratorChunk::Reference:
+      case DeclaratorChunk::Array:
+      case DeclaratorChunk::BlockPointer:
+      case DeclaratorChunk::MemberPointer:
+        return false;
+      }
+      llvm_unreachable("Invalid type chunk");
+    }
+    return false;
+  }
+
+  /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
+  /// this method returns true if the identifier is a function declarator
+  /// (looking through parentheses).
+  bool isFunctionDeclarator() const {
+    unsigned index;
+    return isFunctionDeclarator(index);
+  }
+
+  /// getFunctionTypeInfo - Retrieves the function type info object
+  /// (looking through parentheses).
+  DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() {
+    assert(isFunctionDeclarator() && "Not a function declarator!");
+    unsigned index = 0;
+    isFunctionDeclarator(index);
+    return DeclTypeInfo[index].Fun;
+  }
+
+  /// getFunctionTypeInfo - Retrieves the function type info object
+  /// (looking through parentheses).
+  const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const {
+    return const_cast<Declarator*>(this)->getFunctionTypeInfo();
+  }
+
+  /// \brief Determine whether the declaration that will be produced from 
+  /// this declaration will be a function.
+  /// 
+  /// A declaration can declare a function even if the declarator itself
+  /// isn't a function declarator, if the type specifier refers to a function
+  /// type. This routine checks for both cases.
+  bool isDeclarationOfFunction() const;
+
+  /// \brief Return true if this declaration appears in a context where a
+  /// function declarator would be a function declaration.
+  bool isFunctionDeclarationContext() const {
+    if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
+      return false;
+
+    switch (Context) {
+    case FileContext:
+    case MemberContext:
+    case BlockContext:
+      return true;
+
+    case ForContext:
+    case ConditionContext:
+    case KNRTypeListContext:
+    case TypeNameContext:
+    case AliasDeclContext:
+    case AliasTemplateContext:
+    case PrototypeContext:
+    case LambdaExprParameterContext:
+    case ObjCParameterContext:
+    case ObjCResultContext:
+    case TemplateParamContext:
+    case CXXNewContext:
+    case CXXCatchContext:
+    case ObjCCatchContext:
+    case BlockLiteralContext:
+    case LambdaExprContext:
+    case ConversionIdContext:
+    case TemplateTypeArgContext:
+    case TrailingReturnContext:
+      return false;
+    }
+    llvm_unreachable("unknown context kind!");
+  }
+  
+  /// \brief Return true if a function declarator at this position would be a
+  /// function declaration.
+  bool isFunctionDeclaratorAFunctionDeclaration() const {
+    if (!isFunctionDeclarationContext())
+      return false;
+
+    for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I)
+      if (getTypeObject(I).Kind != DeclaratorChunk::Paren)
+        return false;
+
+    return true;
+  }
+
+  /// takeAttributes - Takes attributes from the given parsed-attributes
+  /// set and add them to this declarator.
+  ///
+  /// These examples both add 3 attributes to "var":
+  ///  short int var __attribute__((aligned(16),common,deprecated));
+  ///  short int x, __attribute__((aligned(16)) var
+  ///                                 __attribute__((common,deprecated));
+  ///
+  /// Also extends the range of the declarator.
+  void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
+    Attrs.takeAllFrom(attrs);
+
+    if (!lastLoc.isInvalid())
+      SetRangeEnd(lastLoc);
+  }
+
+  const AttributeList *getAttributes() const { return Attrs.getList(); }
+  AttributeList *getAttributes() { return Attrs.getList(); }
+
+  AttributeList *&getAttrListRef() { return Attrs.getListRef(); }
+
+  /// hasAttributes - do we contain any attributes?
+  bool hasAttributes() const {
+    if (getAttributes() || getDeclSpec().hasAttributes()) return true;
+    for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
+      if (getTypeObject(i).getAttrs())
+        return true;
+    return false;
+  }
+
+  /// \brief Return a source range list of C++11 attributes associated
+  /// with the declarator.
+  void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
+    AttributeList *AttrList = Attrs.getList();
+    while (AttrList) {
+      if (AttrList->isCXX11Attribute())
+        Ranges.push_back(AttrList->getRange());
+      AttrList = AttrList->getNext();
+    }
+  }
+
+  void setAsmLabel(Expr *E) { AsmLabel = E; }
+  Expr *getAsmLabel() const { return AsmLabel; }
+
+  void setExtension(bool Val = true) { Extension = Val; }
+  bool getExtension() const { return Extension; }
+
+  void setInvalidType(bool Val = true) { InvalidType = Val; }
+  bool isInvalidType() const {
+    return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error;
+  }
+
+  void setGroupingParens(bool flag) { GroupingParens = flag; }
+  bool hasGroupingParens() const { return GroupingParens; }
+
+  bool isFirstDeclarator() const { return !CommaLoc.isValid(); }
+  SourceLocation getCommaLoc() const { return CommaLoc; }
+  void setCommaLoc(SourceLocation CL) { CommaLoc = CL; }
+
+  bool hasEllipsis() const { return EllipsisLoc.isValid(); }
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+  void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; }
+
+  void setFunctionDefinitionKind(FunctionDefinitionKind Val) { 
+    FunctionDefinition = Val; 
+  }
+  
+  bool isFunctionDefinition() const {
+    return getFunctionDefinitionKind() != FDK_Declaration;
+  }
+  
+  FunctionDefinitionKind getFunctionDefinitionKind() const { 
+    return (FunctionDefinitionKind)FunctionDefinition; 
+  }
+
+  /// Returns true if this declares a real member and not a friend.
+  bool isFirstDeclarationOfMember() {
+    return getContext() == MemberContext && !getDeclSpec().isFriendSpecified();
+  }
+
+  /// Returns true if this declares a static member.  This cannot be called on a
+  /// declarator outside of a MemberContext because we won't know until
+  /// redeclaration time if the decl is static.
+  bool isStaticMember();
+
+  void setRedeclaration(bool Val) { Redeclaration = Val; }
+  bool isRedeclaration() const { return Redeclaration; }
+};
+
+/// \brief This little struct is used to capture information about
+/// structure field declarators, which is basically just a bitfield size.
+struct FieldDeclarator {
+  Declarator D;
+  Expr *BitfieldSize;
+  explicit FieldDeclarator(const DeclSpec &DS)
+    : D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { }
+};
+
+/// \brief Represents a C++11 virt-specifier-seq.
+class VirtSpecifiers {
+public:
+  enum Specifier {
+    VS_None = 0,
+    VS_Override = 1,
+    VS_Final = 2,
+    VS_Sealed = 4
+  };
+
+  VirtSpecifiers() : Specifiers(0) { }
+
+  bool SetSpecifier(Specifier VS, SourceLocation Loc,
+                    const char *&PrevSpec);
+
+  bool isUnset() const { return Specifiers == 0; }
+
+  bool isOverrideSpecified() const { return Specifiers & VS_Override; }
+  SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
+
+  bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); }
+  bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; }
+  SourceLocation getFinalLoc() const { return VS_finalLoc; }
+
+  void clear() { Specifiers = 0; }
+
+  static const char *getSpecifierName(Specifier VS);
+
+  SourceLocation getLastLocation() const { return LastLocation; }
+  
+private:
+  unsigned Specifiers;
+
+  SourceLocation VS_overrideLoc, VS_finalLoc;
+  SourceLocation LastLocation;
+};
+
+/// \brief Represents a complete lambda introducer.
+struct LambdaIntroducer {
+  /// \brief An individual capture in a lambda introducer.
+  struct LambdaCapture {
+    LambdaCaptureKind Kind;
+    SourceLocation Loc;
+    IdentifierInfo *Id;
+    SourceLocation EllipsisLoc;
+    ExprResult Init;
+    ParsedType InitCaptureType;
+    LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
+                  IdentifierInfo *Id, SourceLocation EllipsisLoc,
+                  ExprResult Init, ParsedType InitCaptureType)
+        : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init),
+          InitCaptureType(InitCaptureType) {}
+  };
+
+  SourceRange Range;
+  SourceLocation DefaultLoc;
+  LambdaCaptureDefault Default;
+  SmallVector<LambdaCapture, 4> Captures;
+
+  LambdaIntroducer()
+    : Default(LCD_None) {}
+
+  /// \brief Append a capture in a lambda introducer.
+  void addCapture(LambdaCaptureKind Kind,
+                  SourceLocation Loc,
+                  IdentifierInfo* Id,
+                  SourceLocation EllipsisLoc,
+                  ExprResult Init, 
+                  ParsedType InitCaptureType) {
+    Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, 
+        InitCaptureType));
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
new file mode 100644
index 0000000..85551f8
--- /dev/null
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -0,0 +1,294 @@
+//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the classes clang::DelayedDiagnostic and 
+/// clang::AccessedEntity.
+///
+/// DelayedDiangostic is used to record diagnostics that are being
+/// conditionally produced during declarator parsing.  Certain kinds of
+/// diagnostics -- notably deprecation and access control -- are suppressed
+/// based on semantic properties of the parsed declaration that aren't known
+/// until it is fully parsed.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
+#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H
+
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+namespace sema {
+
+/// A declaration being accessed, together with information about how
+/// it was accessed.
+class AccessedEntity {
+public:
+  /// A member declaration found through lookup.  The target is the
+  /// member.
+  enum MemberNonce { Member };
+
+  /// A hierarchy (base-to-derived or derived-to-base) conversion.
+  /// The target is the base class.
+  enum BaseNonce { Base };
+
+  bool isMemberAccess() const { return IsMember; }
+
+  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
+                 MemberNonce _,
+                 CXXRecordDecl *NamingClass,
+                 DeclAccessPair FoundDecl,
+                 QualType BaseObjectType)
+    : Access(FoundDecl.getAccess()), IsMember(true),
+      Target(FoundDecl.getDecl()), NamingClass(NamingClass),
+      BaseObjectType(BaseObjectType), Diag(0, Allocator) {
+  }
+
+  AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator,
+                 BaseNonce _,
+                 CXXRecordDecl *BaseClass,
+                 CXXRecordDecl *DerivedClass,
+                 AccessSpecifier Access)
+    : Access(Access), IsMember(false),
+      Target(BaseClass),
+      NamingClass(DerivedClass),
+      Diag(0, Allocator) {
+  }
+
+  bool isQuiet() const { return Diag.getDiagID() == 0; }
+
+  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+
+  // These apply to member decls...
+  NamedDecl *getTargetDecl() const { return Target; }
+  CXXRecordDecl *getNamingClass() const { return NamingClass; }
+
+  // ...and these apply to hierarchy conversions.
+  CXXRecordDecl *getBaseClass() const {
+    assert(!IsMember); return cast<CXXRecordDecl>(Target);
+  }
+  CXXRecordDecl *getDerivedClass() const { return NamingClass; }
+
+  /// Retrieves the base object type, important when accessing
+  /// an instance member.
+  QualType getBaseObjectType() const { return BaseObjectType; }
+
+  /// Sets a diagnostic to be performed.  The diagnostic is given
+  /// four (additional) arguments:
+  ///   %0 - 0 if the entity was private, 1 if protected
+  ///   %1 - the DeclarationName of the entity
+  ///   %2 - the TypeDecl type of the naming class
+  ///   %3 - the TypeDecl type of the declaring class
+  void setDiag(const PartialDiagnostic &PDiag) {
+    assert(isQuiet() && "partial diagnostic already defined");
+    Diag = PDiag;
+  }
+  PartialDiagnostic &setDiag(unsigned DiagID) {
+    assert(isQuiet() && "partial diagnostic already defined");
+    assert(DiagID && "creating null diagnostic");
+    Diag.Reset(DiagID);
+    return Diag;
+  }
+  const PartialDiagnostic &getDiag() const {
+    return Diag;
+  }
+
+private:
+  unsigned Access : 2;
+  unsigned IsMember : 1;
+  NamedDecl *Target;
+  CXXRecordDecl *NamingClass;
+  QualType BaseObjectType;
+  PartialDiagnostic Diag;
+};
+
+/// A diagnostic message which has been conditionally emitted pending
+/// the complete parsing of the current declaration.
+class DelayedDiagnostic {
+public:
+  enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
+
+  unsigned char Kind; // actually a DDKind
+  bool Triggered;
+
+  SourceLocation Loc;
+
+  void Destroy();
+
+  static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
+                                            SourceLocation Loc,
+                                            const NamedDecl *D,
+                                            const ObjCInterfaceDecl *UnknownObjCClass,
+                                            const ObjCPropertyDecl  *ObjCProperty,
+                                            StringRef Msg,
+                                            bool ObjCPropertyAccess);
+
+
+  static DelayedDiagnostic makeAccess(SourceLocation Loc,
+                                      const AccessedEntity &Entity) {
+    DelayedDiagnostic DD;
+    DD.Kind = Access;
+    DD.Triggered = false;
+    DD.Loc = Loc;
+    new (&DD.getAccessData()) AccessedEntity(Entity);
+    return DD;
+  }
+
+  static DelayedDiagnostic makeForbiddenType(SourceLocation loc,
+                                             unsigned diagnostic,
+                                             QualType type,
+                                             unsigned argument) {
+    DelayedDiagnostic DD;
+    DD.Kind = ForbiddenType;
+    DD.Triggered = false;
+    DD.Loc = loc;
+    DD.ForbiddenTypeData.Diagnostic = diagnostic;
+    DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr();
+    DD.ForbiddenTypeData.Argument = argument;
+    return DD;
+  }
+
+  AccessedEntity &getAccessData() {
+    assert(Kind == Access && "Not an access diagnostic.");
+    return *reinterpret_cast<AccessedEntity*>(AccessData);
+  }
+  const AccessedEntity &getAccessData() const {
+    assert(Kind == Access && "Not an access diagnostic.");
+    return *reinterpret_cast<const AccessedEntity*>(AccessData);
+  }
+
+  const NamedDecl *getDeprecationDecl() const {
+    assert((Kind == Deprecation || Kind == Unavailable) &&
+           "Not a deprecation diagnostic.");
+    return DeprecationData.Decl;
+  }
+
+  StringRef getDeprecationMessage() const {
+    assert((Kind == Deprecation || Kind == Unavailable) &&
+           "Not a deprecation diagnostic.");
+    return StringRef(DeprecationData.Message,
+                           DeprecationData.MessageLen);
+  }
+
+  /// The diagnostic ID to emit.  Used like so:
+  ///   Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
+  ///     << diag.getForbiddenTypeOperand()
+  ///     << diag.getForbiddenTypeArgument();
+  unsigned getForbiddenTypeDiagnostic() const {
+    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
+    return ForbiddenTypeData.Diagnostic;
+  }
+
+  unsigned getForbiddenTypeArgument() const {
+    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
+    return ForbiddenTypeData.Argument;
+  }
+
+  QualType getForbiddenTypeOperand() const {
+    assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
+    return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
+  }
+  
+  const ObjCInterfaceDecl *getUnknownObjCClass() const {
+    return DeprecationData.UnknownObjCClass;
+  }
+
+  const ObjCPropertyDecl *getObjCProperty() const {
+    return DeprecationData.ObjCProperty;
+  }
+    
+  bool getObjCPropertyAccess() const {
+    return DeprecationData.ObjCPropertyAccess;
+  }
+  
+private:
+
+  struct DD {
+    const NamedDecl *Decl;
+    const ObjCInterfaceDecl *UnknownObjCClass;
+    const ObjCPropertyDecl  *ObjCProperty;
+    const char *Message;
+    size_t MessageLen;
+    bool ObjCPropertyAccess;
+  };
+
+  struct FTD {
+    unsigned Diagnostic;
+    unsigned Argument;
+    void *OperandType;
+  };
+
+  union {
+    /// Deprecation
+    struct DD DeprecationData;
+    struct FTD ForbiddenTypeData;
+
+    /// Access control.
+    char AccessData[sizeof(AccessedEntity)];
+  };
+};
+
+/// \brief A collection of diagnostics which were delayed.
+class DelayedDiagnosticPool {
+  const DelayedDiagnosticPool *Parent;
+  SmallVector<DelayedDiagnostic, 4> Diagnostics;
+
+  DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
+  void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION;
+public:
+  DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {}
+  ~DelayedDiagnosticPool() {
+    for (SmallVectorImpl<DelayedDiagnostic>::iterator
+           i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i)
+      i->Destroy();
+  }
+
+  const DelayedDiagnosticPool *getParent() const { return Parent; }
+
+  /// Does this pool, or any of its ancestors, contain any diagnostics?
+  bool empty() const {
+    return (Diagnostics.empty() && (!Parent || Parent->empty()));
+  }
+
+  /// Add a diagnostic to this pool.
+  void add(const DelayedDiagnostic &diag) {
+    Diagnostics.push_back(diag);
+  }
+
+  /// Steal the diagnostics from the given pool.
+  void steal(DelayedDiagnosticPool &pool) {
+    if (pool.Diagnostics.empty()) return;
+
+    if (Diagnostics.empty()) {
+      Diagnostics = std::move(pool.Diagnostics);
+    } else {
+      Diagnostics.append(pool.pool_begin(), pool.pool_end());
+    }
+    pool.Diagnostics.clear();
+  }
+
+  typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator;
+  pool_iterator pool_begin() const { return Diagnostics.begin(); }
+  pool_iterator pool_end() const { return Diagnostics.end(); }
+  bool pool_empty() const { return Diagnostics.empty(); }
+};
+
+}
+
+/// Add a diagnostic to the current delay pool.
+inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) {
+  assert(shouldDelayDiagnostics() && "trying to delay without pool");
+  CurPool->add(diag);
+}
+
+
+}
+
+#endif
diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h
new file mode 100644
index 0000000..55603fe
--- /dev/null
+++ b/include/clang/Sema/Designator.h
@@ -0,0 +1,210 @@
+//===--- Designator.h - Initialization Designator ---------------*- 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 interfaces used to represent designators (a la
+// C99 designated initializers) during parsing.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
+#define LLVM_CLANG_SEMA_DESIGNATOR_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class Expr;
+class IdentifierInfo;
+class Sema;
+
+/// Designator - A designator in a C99 designated initializer.
+///
+/// This class is a discriminated union which holds the various
+/// different sorts of designators possible.  A Designation is an array of
+/// these.  An example of a designator are things like this:
+///     [8] .field [47]        // C99 designation: 3 designators
+///     [8 ... 47]  field:     // GNU extensions: 2 designators
+/// These occur in initializers, e.g.:
+///  int a[10] = {2, 4, [8]=9, 10};
+///
+class Designator {
+public:
+  enum DesignatorKind {
+    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
+  };
+private:
+  DesignatorKind Kind;
+
+  struct FieldDesignatorInfo {
+    const IdentifierInfo *II;
+    unsigned DotLoc;
+    unsigned NameLoc;
+  };
+  struct ArrayDesignatorInfo {
+    Expr *Index;
+    unsigned LBracketLoc;
+    mutable unsigned  RBracketLoc;
+  };
+  struct ArrayRangeDesignatorInfo {
+    Expr *Start, *End;
+    unsigned LBracketLoc, EllipsisLoc;
+    mutable unsigned RBracketLoc;
+  };
+
+  union {
+    FieldDesignatorInfo FieldInfo;
+    ArrayDesignatorInfo ArrayInfo;
+    ArrayRangeDesignatorInfo ArrayRangeInfo;
+  };
+
+public:
+
+  DesignatorKind getKind() const { return Kind; }
+  bool isFieldDesignator() const { return Kind == FieldDesignator; }
+  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
+  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
+
+  const IdentifierInfo *getField() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return FieldInfo.II;
+  }
+
+  SourceLocation getDotLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
+  }
+
+  SourceLocation getFieldLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
+  }
+
+  Expr *getArrayIndex() const {
+    assert(isArrayDesignator() && "Invalid accessor");
+    return ArrayInfo.Index;
+  }
+
+  Expr *getArrayRangeStart() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayRangeInfo.Start;
+  }
+  Expr *getArrayRangeEnd() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayRangeInfo.End;
+  }
+
+  SourceLocation getLBracketLoc() const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
+    else
+      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
+  }
+
+  SourceLocation getRBracketLoc() const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
+    else
+      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
+  }
+
+  SourceLocation getEllipsisLoc() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
+  }
+
+  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
+                             SourceLocation NameLoc) {
+    Designator D;
+    D.Kind = FieldDesignator;
+    D.FieldInfo.II = II;
+    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
+    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
+    return D;
+  }
+
+  static Designator getArray(Expr *Index,
+                             SourceLocation LBracketLoc) {
+    Designator D;
+    D.Kind = ArrayDesignator;
+    D.ArrayInfo.Index = Index;
+    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
+    D.ArrayInfo.RBracketLoc = 0;
+    return D;
+  }
+
+  static Designator getArrayRange(Expr *Start,
+                                  Expr *End,
+                                  SourceLocation LBracketLoc,
+                                  SourceLocation EllipsisLoc) {
+    Designator D;
+    D.Kind = ArrayRangeDesignator;
+    D.ArrayRangeInfo.Start = Start;
+    D.ArrayRangeInfo.End = End;
+    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
+    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
+    D.ArrayRangeInfo.RBracketLoc = 0;
+    return D;
+  }
+
+  void setRBracketLoc(SourceLocation RBracketLoc) const {
+    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
+           "Invalid accessor");
+    if (isArrayDesignator())
+      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
+    else
+      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
+  }
+
+  /// ClearExprs - Null out any expression references, which prevents
+  /// them from being 'delete'd later.
+  void ClearExprs(Sema &Actions) {}
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in
+  /// this designator.
+  void FreeExprs(Sema &Actions) {}
+};
+
+
+/// Designation - Represent a full designation, which is a sequence of
+/// designators.  This class is mostly a helper for InitListDesignations.
+class Designation {
+  /// Designators - The actual designators for this initializer.
+  SmallVector<Designator, 2> Designators;
+
+public:
+  /// AddDesignator - Add a designator to the end of this list.
+  void AddDesignator(Designator D) {
+    Designators.push_back(D);
+  }
+
+  bool empty() const { return Designators.empty(); }
+
+  unsigned getNumDesignators() const { return Designators.size(); }
+  const Designator &getDesignator(unsigned Idx) const {
+    assert(Idx < Designators.size());
+    return Designators[Idx];
+  }
+
+  /// ClearExprs - Null out any expression references, which prevents them from
+  /// being 'delete'd later.
+  void ClearExprs(Sema &Actions) {}
+
+  /// FreeExprs - Release any unclaimed memory for the expressions in this
+  /// designation.
+  void FreeExprs(Sema &Actions) {}
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
new file mode 100644
index 0000000..325abdf
--- /dev/null
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -0,0 +1,230 @@
+//===--- ExternalSemaSource.h - External Sema Interface ---------*- 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 ExternalSemaSource interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H
+
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/Type.h"
+#include "clang/Sema/TypoCorrection.h"
+#include "clang/Sema/Weak.h"
+#include "llvm/ADT/MapVector.h"
+#include <utility>
+
+namespace clang {
+
+class CXXConstructorDecl;
+class CXXRecordDecl;
+class DeclaratorDecl;
+class LookupResult;
+struct ObjCMethodList;
+class Scope;
+class Sema;
+class TypedefNameDecl;
+class ValueDecl;
+class VarDecl;
+struct LateParsedTemplate;
+
+/// \brief A simple structure that captures a vtable use for the purposes of
+/// the \c ExternalSemaSource.
+struct ExternalVTableUse {
+  CXXRecordDecl *Record;
+  SourceLocation Location;
+  bool DefinitionRequired;
+};
+  
+/// \brief An abstract interface that should be implemented by
+/// external AST sources that also provide information for semantic
+/// analysis.
+class ExternalSemaSource : public ExternalASTSource {
+public:
+  ExternalSemaSource() {
+    ExternalASTSource::SemaSource = true;
+  }
+
+  ~ExternalSemaSource();
+
+  /// \brief Initialize the semantic source with the Sema instance
+  /// being used to perform semantic analysis on the abstract syntax
+  /// tree.
+  virtual void InitializeSema(Sema &S) {}
+
+  /// \brief Inform the semantic consumer that Sema is no longer available.
+  virtual void ForgetSema() {}
+
+  /// \brief Load the contents of the global method pool for a given
+  /// selector.
+  virtual void ReadMethodPool(Selector Sel);
+
+  /// \brief Load the set of namespaces that are known to the external source,
+  /// which will be used during typo correction.
+  virtual void ReadKnownNamespaces(
+                           SmallVectorImpl<NamespaceDecl *> &Namespaces);
+
+  /// \brief Load the set of used but not defined functions or variables with
+  /// internal linkage, or used but not defined internal functions.
+  virtual void ReadUndefinedButUsed(
+                         llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
+
+  /// \brief Do last resort, unqualified lookup on a LookupResult that
+  /// Sema cannot find.
+  ///
+  /// \param R a LookupResult that is being recovered.
+  ///
+  /// \param S the Scope of the identifier occurrence.
+  ///
+  /// \return true to tell Sema to recover using the LookupResult.
+  virtual bool LookupUnqualified(LookupResult &R, Scope *S) { return false; }
+
+  /// \brief Read the set of tentative definitions known to the external Sema
+  /// source.
+  ///
+  /// The external source should append its own tentative definitions to the
+  /// given vector of tentative definitions. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  virtual void ReadTentativeDefinitions(
+                                  SmallVectorImpl<VarDecl *> &TentativeDefs) {}
+  
+  /// \brief Read the set of unused file-scope declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own unused, filed-scope to the
+  /// given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  virtual void ReadUnusedFileScopedDecls(
+                 SmallVectorImpl<const DeclaratorDecl *> &Decls) {}
+  
+  /// \brief Read the set of delegating constructors known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own delegating constructors to the
+  /// given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  virtual void ReadDelegatingConstructors(
+                 SmallVectorImpl<CXXConstructorDecl *> &Decls) {}
+
+  /// \brief Read the set of ext_vector type declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own ext_vector type declarations to
+  /// the given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {}
+
+  /// \brief Read the set of dynamic classes known to the external Sema source.
+  ///
+  /// The external source should append its own dynamic classes to
+  /// the given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {}
+
+  /// \brief Read the set of locally-scoped external declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own locally-scoped external
+  /// declarations to the given vector of declarations. Note that this routine 
+  /// may be invoked multiple times; the external source should take care not 
+  /// to introduce the same declarations repeatedly.
+  virtual void ReadLocallyScopedExternCDecls(
+                 SmallVectorImpl<NamedDecl *> &Decls) {}
+
+  /// \brief Read the set of referenced selectors known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own referenced selectors to the 
+  /// given vector of selectors. Note that this routine 
+  /// may be invoked multiple times; the external source should take care not 
+  /// to introduce the same selectors repeatedly.
+  virtual void ReadReferencedSelectors(
+                 SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {}
+
+  /// \brief Read the set of weak, undeclared identifiers known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own weak, undeclared identifiers to
+  /// the given vector. Note that this routine may be invoked multiple times; 
+  /// the external source should take care not to introduce the same identifiers
+  /// repeatedly.
+  virtual void ReadWeakUndeclaredIdentifiers(
+                 SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {}
+
+  /// \brief Read the set of used vtables known to the external Sema source.
+  ///
+  /// The external source should append its own used vtables to the given
+  /// vector. Note that this routine may be invoked multiple times; the external
+  /// source should take care not to introduce the same vtables repeatedly.
+  virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {}
+
+  /// \brief Read the set of pending instantiations known to the external
+  /// Sema source.
+  ///
+  /// The external source should append its own pending instantiations to the
+  /// given vector. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same instantiations
+  /// repeatedly.
+  virtual void ReadPendingInstantiations(
+                 SmallVectorImpl<std::pair<ValueDecl *, 
+                                           SourceLocation> > &Pending) {}
+
+  /// \brief Read the set of late parsed template functions for this source.
+  ///
+  /// The external source should insert its own late parsed template functions
+  /// into the map. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same map entries
+  /// repeatedly.
+  virtual void ReadLateParsedTemplates(
+      llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {}
+
+  /// \copydoc Sema::CorrectTypo
+  /// \note LookupKind must correspond to a valid Sema::LookupNameKind
+  ///
+  /// ExternalSemaSource::CorrectTypo is always given the first chance to
+  /// correct a typo (really, to offer suggestions to repair a failed lookup).
+  /// It will even be called when SpellChecking is turned off or after a
+  /// fatal error has already been detected.
+  virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
+                                     int LookupKind, Scope *S, CXXScopeSpec *SS,
+                                     CorrectionCandidateCallback &CCC,
+                                     DeclContext *MemberContext,
+                                     bool EnteringContext,
+                                     const ObjCObjectPointerType *OPT) {
+    return TypoCorrection();
+  }
+
+  /// \brief Produces a diagnostic note if the external source contains a
+  /// complete definition for \p T.
+  ///
+  /// \param Loc the location at which a complete type was required but not
+  /// provided
+  ///
+  /// \param T the \c QualType that should have been complete at \p Loc
+  ///
+  /// \return true if a diagnostic was produced, false otherwise.
+  virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
+                                                QualType T) {
+    return false;
+  }
+
+  // isa/cast/dyn_cast support
+  static bool classof(const ExternalASTSource *Source) {
+    return Source->SemaSource;
+  }
+}; 
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
new file mode 100644
index 0000000..b2404bc
--- /dev/null
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -0,0 +1,213 @@
+//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 IdentifierResolver class, which is used for lexical
+// scoped lookup, based on declaration names.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
+#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DeclContext;
+class DeclarationName;
+class ExternalPreprocessorSource;
+class NamedDecl;
+class Preprocessor;
+class Scope;
+  
+/// IdentifierResolver - Keeps track of shadowed decls on enclosing
+/// scopes.  It manages the shadowing chains of declaration names and
+/// implements efficient decl lookup based on a declaration name.
+class IdentifierResolver {
+
+  /// IdDeclInfo - Keeps track of information about decls associated
+  /// to a particular declaration name. IdDeclInfos are lazily
+  /// constructed and assigned to a declaration name the first time a
+  /// decl with that declaration name is shadowed in some scope.
+  class IdDeclInfo {
+  public:
+    typedef SmallVector<NamedDecl*, 2> DeclsTy;
+
+    inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
+    inline DeclsTy::iterator decls_end() { return Decls.end(); }
+
+    void AddDecl(NamedDecl *D) { Decls.push_back(D); }
+
+    /// RemoveDecl - Remove the decl from the scope chain.
+    /// The decl must already be part of the decl chain.
+    void RemoveDecl(NamedDecl *D);
+
+    /// \brief Insert the given declaration at the given position in the list.
+    void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
+      Decls.insert(Pos, D);
+    }
+                    
+  private:
+    DeclsTy Decls;
+  };
+
+public:
+
+  /// iterator - Iterate over the decls of a specified declaration name.
+  /// It will walk or not the parent declaration contexts depending on how
+  /// it was instantiated.
+  class iterator {
+  public:
+    typedef NamedDecl *             value_type;
+    typedef NamedDecl *             reference;
+    typedef NamedDecl *             pointer;
+    typedef std::input_iterator_tag iterator_category;
+    typedef std::ptrdiff_t          difference_type;
+
+    /// Ptr - There are 3 forms that 'Ptr' represents:
+    /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
+    /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
+    ///    same declaration context. (Ptr & 0x3 == 0x1)
+    /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
+    ///    declaration contexts too. (Ptr & 0x3 == 0x3)
+    uintptr_t Ptr;
+    typedef IdDeclInfo::DeclsTy::iterator BaseIter;
+
+    /// A single NamedDecl. (Ptr & 0x1 == 0)
+    iterator(NamedDecl *D) {
+      Ptr = reinterpret_cast<uintptr_t>(D);
+      assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
+    }
+    /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
+    /// contexts depending on 'LookInParentCtx'.
+    iterator(BaseIter I) {
+      Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
+    }
+
+    bool isIterator() const { return (Ptr & 0x1); }
+
+    BaseIter getIterator() const {
+      assert(isIterator() && "Ptr not an iterator!");
+      return reinterpret_cast<BaseIter>(Ptr & ~0x3);
+    }
+
+    friend class IdentifierResolver;
+
+    void incrementSlowCase();
+  public:
+    iterator() : Ptr(0) {}
+
+    NamedDecl *operator*() const {
+      if (isIterator())
+        return *getIterator();
+      else
+        return reinterpret_cast<NamedDecl*>(Ptr);
+    }
+
+    bool operator==(const iterator &RHS) const {
+      return Ptr == RHS.Ptr;
+    }
+    bool operator!=(const iterator &RHS) const {
+      return Ptr != RHS.Ptr;
+    }
+
+    // Preincrement.
+    iterator& operator++() {
+      if (!isIterator()) // common case.
+        Ptr = 0;
+      else
+        incrementSlowCase();
+      return *this;
+    }
+
+    uintptr_t getAsOpaqueValue() const { return Ptr; }
+
+    static iterator getFromOpaqueValue(uintptr_t P) {
+      iterator Result;
+      Result.Ptr = P;
+      return Result;
+    }
+  };
+
+  /// begin - Returns an iterator for decls with the name 'Name'.
+  iterator begin(DeclarationName Name);
+
+  /// end - Returns an iterator that has 'finished'.
+  iterator end() {
+    return iterator();
+  }
+
+  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
+  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
+  /// true if 'D' belongs to the given declaration context.
+  ///
+  /// \param AllowInlineNamespace If \c true, we are checking whether a prior
+  ///        declaration is in scope in a declaration that requires a prior
+  ///        declaration (because it is either explicitly qualified or is a
+  ///        template instantiation or specialization). In this case, a
+  ///        declaration is in scope if it's in the inline namespace set of the
+  ///        context.
+  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
+                     bool AllowInlineNamespace = false) const;
+
+  /// AddDecl - Link the decl to its shadowed decl chain.
+  void AddDecl(NamedDecl *D);
+
+  /// RemoveDecl - Unlink the decl from its shadowed decl chain.
+  /// The decl must already be part of the decl chain.
+  void RemoveDecl(NamedDecl *D);
+
+  /// \brief Insert the given declaration after the given iterator
+  /// position.
+  void InsertDeclAfter(iterator Pos, NamedDecl *D);
+
+  /// \brief Try to add the given declaration to the top level scope, if it
+  /// (or a redeclaration of it) hasn't already been added.
+  ///
+  /// \param D The externally-produced declaration to add.
+  ///
+  /// \param Name The name of the externally-produced declaration.
+  ///
+  /// \returns true if the declaration was added, false otherwise.
+  bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
+  
+  explicit IdentifierResolver(Preprocessor &PP);
+  ~IdentifierResolver();
+
+private:
+  const LangOptions &LangOpt;
+  Preprocessor &PP;
+  
+  class IdDeclInfoMap;
+  IdDeclInfoMap *IdDeclInfos;
+
+  void updatingIdentifier(IdentifierInfo &II);
+  void readingIdentifier(IdentifierInfo &II);
+  
+  /// FETokenInfo contains a Decl pointer if lower bit == 0.
+  static inline bool isDeclPtr(void *Ptr) {
+    return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
+  }
+
+  /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
+  static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
+    assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
+          && "Ptr not a IdDeclInfo* !");
+    return reinterpret_cast<IdDeclInfo*>(
+                    reinterpret_cast<uintptr_t>(Ptr) & ~0x1
+                                                            );
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
new file mode 100644
index 0000000..9f342b2
--- /dev/null
+++ b/include/clang/Sema/Initialization.h
@@ -0,0 +1,1127 @@
+//===--- Initialization.h - Semantic Analysis for Initializers --*- 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 supporting data types for initialization of objects.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H
+#define LLVM_CLANG_SEMA_INITIALIZATION_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/Overload.h"
+#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+
+namespace clang {
+  
+class CXXBaseSpecifier;
+class DeclaratorDecl;
+class DeclaratorInfo;
+class FieldDecl;
+class FunctionDecl;
+class ParmVarDecl;
+class Sema;
+class TypeLoc;
+class VarDecl;
+class ObjCMethodDecl;
+  
+/// \brief Describes an entity that is being initialized.
+class InitializedEntity {
+public:
+  /// \brief Specifies the kind of entity being initialized.
+  enum EntityKind {
+    /// \brief The entity being initialized is a variable.
+    EK_Variable,
+    /// \brief The entity being initialized is a function parameter.
+    EK_Parameter,
+    /// \brief The entity being initialized is the result of a function call.
+    EK_Result,
+    /// \brief The entity being initialized is an exception object that
+    /// is being thrown.
+    EK_Exception,
+    /// \brief The entity being initialized is a non-static data member 
+    /// subobject.
+    EK_Member,
+    /// \brief The entity being initialized is an element of an array.
+    EK_ArrayElement,
+    /// \brief The entity being initialized is an object (or array of
+    /// objects) allocated via new.
+    EK_New,
+    /// \brief The entity being initialized is a temporary object.
+    EK_Temporary,
+    /// \brief The entity being initialized is a base member subobject.
+    EK_Base,
+    /// \brief The initialization is being done by a delegating constructor.
+    EK_Delegating,
+    /// \brief The entity being initialized is an element of a vector.
+    /// or vector.
+    EK_VectorElement,
+    /// \brief The entity being initialized is a field of block descriptor for
+    /// the copied-in c++ object.
+    EK_BlockElement,
+    /// \brief The entity being initialized is the real or imaginary part of a
+    /// complex number.
+    EK_ComplexElement,
+    /// \brief The entity being initialized is the field that captures a 
+    /// variable in a lambda.
+    EK_LambdaCapture,
+    /// \brief The entity being initialized is the initializer for a compound
+    /// literal.
+    EK_CompoundLiteralInit,
+    /// \brief The entity being implicitly initialized back to the formal
+    /// result type.
+    EK_RelatedResult,
+    /// \brief The entity being initialized is a function parameter; function
+    /// is member of group of audited CF APIs.
+    EK_Parameter_CF_Audited
+
+    // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
+    // enum as an index for its first %select.  When modifying this list,
+    // that diagnostic text needs to be updated as well.
+  };
+  
+private:
+  /// \brief The kind of entity being initialized.
+  EntityKind Kind;
+
+  /// \brief If non-NULL, the parent entity in which this
+  /// initialization occurs.
+  const InitializedEntity *Parent;
+
+  /// \brief The type of the object or reference being initialized.
+  QualType Type;
+
+  /// \brief The mangling number for the next reference temporary to be created.
+  mutable unsigned ManglingNumber;
+
+  struct LN {
+    /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
+    /// location of the 'return', 'throw', or 'new' keyword,
+    /// respectively. When Kind == EK_Temporary, the location where
+    /// the temporary is being created.
+    unsigned Location;
+
+    /// \brief Whether the entity being initialized may end up using the
+    /// named return value optimization (NRVO).
+    bool NRVO;
+  };
+
+  struct C {
+    /// \brief The name of the variable being captured by an EK_LambdaCapture.
+    IdentifierInfo *VarID;
+
+    /// \brief The source location at which the capture occurs.
+    unsigned Location;
+  };
+
+  union {
+    /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
+    /// FieldDecl, respectively.
+    DeclaratorDecl *VariableOrMember;
+    
+    /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
+    /// result type was implicitly changed to accommodate ARC semantics.
+    ObjCMethodDecl *MethodDecl;
+
+    /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the
+    /// low bit indicating whether the parameter is "consumed".
+    uintptr_t Parameter;
+    
+    /// \brief When Kind == EK_Temporary or EK_CompoundLiteralInit, the type
+    /// source information for the temporary.
+    TypeSourceInfo *TypeInfo;
+
+    struct LN LocAndNRVO;
+    
+    /// \brief When Kind == EK_Base, the base specifier that provides the 
+    /// base class. The lower bit specifies whether the base is an inherited
+    /// virtual base.
+    uintptr_t Base;
+
+    /// \brief When Kind == EK_ArrayElement, EK_VectorElement, or
+    /// EK_ComplexElement, the index of the array or vector element being
+    /// initialized. 
+    unsigned Index;
+
+    struct C Capture;
+  };
+
+  InitializedEntity() : ManglingNumber(0) {}
+
+  /// \brief Create the initialization entity for a variable.
+  InitializedEntity(VarDecl *Var)
+    : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()),
+      ManglingNumber(0), VariableOrMember(Var) { }
+  
+  /// \brief Create the initialization entity for the result of a
+  /// function, throwing an object, performing an explicit cast, or
+  /// initializing a parameter for which there is no declaration.
+  InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
+                    bool NRVO = false)
+    : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0)
+  {
+    LocAndNRVO.Location = Loc.getRawEncoding();
+    LocAndNRVO.NRVO = NRVO;
+  }
+  
+  /// \brief Create the initialization entity for a member subobject.
+  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
+    : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
+      ManglingNumber(0), VariableOrMember(Member) { }
+  
+  /// \brief Create the initialization entity for an array element.
+  InitializedEntity(ASTContext &Context, unsigned Index, 
+                    const InitializedEntity &Parent);
+
+  /// \brief Create the initialization entity for a lambda capture.
+  InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
+    : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType),
+      ManglingNumber(0)
+  {
+    Capture.VarID = VarID;
+    Capture.Location = Loc.getRawEncoding();
+  }
+  
+public:
+  /// \brief Create the initialization entity for a variable.
+  static InitializedEntity InitializeVariable(VarDecl *Var) {
+    return InitializedEntity(Var);
+  }
+
+  /// \brief Create the initialization entity for a parameter.
+  static InitializedEntity InitializeParameter(ASTContext &Context,
+                                               ParmVarDecl *Parm) {
+    return InitializeParameter(Context, Parm, Parm->getType());
+  }
+
+  /// \brief Create the initialization entity for a parameter, but use
+  /// another type.
+  static InitializedEntity InitializeParameter(ASTContext &Context,
+                                               ParmVarDecl *Parm,
+                                               QualType Type) {
+    bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
+                     Parm->hasAttr<NSConsumedAttr>());
+
+    InitializedEntity Entity;
+    Entity.Kind = EK_Parameter;
+    Entity.Type =
+      Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
+    Entity.Parent = nullptr;
+    Entity.Parameter
+      = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
+    return Entity;
+  }
+
+  /// \brief Create the initialization entity for a parameter that is
+  /// only known by its type.
+  static InitializedEntity InitializeParameter(ASTContext &Context,
+                                               QualType Type,
+                                               bool Consumed) {
+    InitializedEntity Entity;
+    Entity.Kind = EK_Parameter;
+    Entity.Type = Context.getVariableArrayDecayedType(Type);
+    Entity.Parent = nullptr;
+    Entity.Parameter = (Consumed);
+    return Entity;
+  }
+
+  /// \brief Create the initialization entity for the result of a function.
+  static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
+                                            QualType Type, bool NRVO) {
+    return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
+  }
+
+  static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
+                                           QualType Type, bool NRVO) {
+    return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
+  }
+  
+  /// \brief Create the initialization entity for an exception object.
+  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
+                                               QualType Type, bool NRVO) {
+    return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
+  }
+
+  /// \brief Create the initialization entity for an object allocated via new.
+  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
+    return InitializedEntity(EK_New, NewLoc, Type);
+  }
+  
+  /// \brief Create the initialization entity for a temporary.
+  static InitializedEntity InitializeTemporary(QualType Type) {
+    InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
+    Result.TypeInfo = nullptr;
+    return Result;
+  }
+
+  /// \brief Create the initialization entity for a temporary.
+  static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) {
+    InitializedEntity Result(EK_Temporary, SourceLocation(), 
+                             TypeInfo->getType());
+    Result.TypeInfo = TypeInfo;
+    return Result;
+  }
+  
+  /// \brief Create the initialization entity for a related result.
+  static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
+                                                   QualType Type) {
+    InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
+    Result.MethodDecl = MD;
+    return Result;
+  }
+
+
+  /// \brief Create the initialization entity for a base class subobject.
+  static InitializedEntity InitializeBase(ASTContext &Context,
+                                          const CXXBaseSpecifier *Base,
+                                          bool IsInheritedVirtualBase);
+
+  /// \brief Create the initialization entity for a delegated constructor.
+  static InitializedEntity InitializeDelegation(QualType Type) {
+    return InitializedEntity(EK_Delegating, SourceLocation(), Type);
+  }
+  
+  /// \brief Create the initialization entity for a member subobject.
+  static InitializedEntity
+  InitializeMember(FieldDecl *Member,
+                   const InitializedEntity *Parent = nullptr) {
+    return InitializedEntity(Member, Parent);
+  }
+  
+  /// \brief Create the initialization entity for a member subobject.
+  static InitializedEntity
+  InitializeMember(IndirectFieldDecl *Member,
+                   const InitializedEntity *Parent = nullptr) {
+    return InitializedEntity(Member->getAnonField(), Parent);
+  }
+
+  /// \brief Create the initialization entity for an array element.
+  static InitializedEntity InitializeElement(ASTContext &Context, 
+                                             unsigned Index, 
+                                             const InitializedEntity &Parent) {
+    return InitializedEntity(Context, Index, Parent);
+  }
+
+  /// \brief Create the initialization entity for a lambda capture.
+  static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
+                                                   QualType FieldType,
+                                                   SourceLocation Loc) {
+    return InitializedEntity(VarID, FieldType, Loc);
+  }
+
+  /// \brief Create the entity for a compound literal initializer.
+  static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) {
+    InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(),
+                             TSI->getType());
+    Result.TypeInfo = TSI;
+    return Result;
+  }
+
+
+  /// \brief Determine the kind of initialization.
+  EntityKind getKind() const { return Kind; }
+  
+  /// \brief Retrieve the parent of the entity being initialized, when
+  /// the initialization itself is occurring within the context of a
+  /// larger initialization.
+  const InitializedEntity *getParent() const { return Parent; }
+
+  /// \brief Retrieve type being initialized.
+  QualType getType() const { return Type; }
+  
+  /// \brief Retrieve complete type-source information for the object being 
+  /// constructed, if known.
+  TypeSourceInfo *getTypeSourceInfo() const {
+    if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
+      return TypeInfo;
+    
+    return nullptr;
+  }
+  
+  /// \brief Retrieve the name of the entity being initialized.
+  DeclarationName getName() const;
+
+  /// \brief Retrieve the variable, parameter, or field being
+  /// initialized.
+  DeclaratorDecl *getDecl() const;
+  
+  /// \brief Retrieve the ObjectiveC method being initialized.
+  ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
+
+  /// \brief Determine whether this initialization allows the named return 
+  /// value optimization, which also applies to thrown objects.
+  bool allowsNRVO() const;
+
+  bool isParameterKind() const {
+    return (getKind() == EK_Parameter  ||
+            getKind() == EK_Parameter_CF_Audited);
+  }
+  /// \brief Determine whether this initialization consumes the
+  /// parameter.
+  bool isParameterConsumed() const {
+    assert(isParameterKind() && "Not a parameter");
+    return (Parameter & 1);
+  }
+                                  
+  /// \brief Retrieve the base specifier.
+  const CXXBaseSpecifier *getBaseSpecifier() const {
+    assert(getKind() == EK_Base && "Not a base specifier");
+    return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1);
+  }
+
+  /// \brief Return whether the base is an inherited virtual base.
+  bool isInheritedVirtualBase() const {
+    assert(getKind() == EK_Base && "Not a base specifier");
+    return Base & 0x1;
+  }
+
+  /// \brief Determine the location of the 'return' keyword when initializing
+  /// the result of a function call.
+  SourceLocation getReturnLoc() const {
+    assert(getKind() == EK_Result && "No 'return' location!");
+    return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
+  }
+
+  /// \brief Determine the location of the 'throw' keyword when initializing
+  /// an exception object.
+  SourceLocation getThrowLoc() const {
+    assert(getKind() == EK_Exception && "No 'throw' location!");
+    return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
+  }
+
+  /// \brief If this is an array, vector, or complex number element, get the
+  /// element's index.
+  unsigned getElementIndex() const {
+    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
+           getKind() == EK_ComplexElement);
+    return Index;
+  }
+  /// \brief If this is already the initializer for an array or vector
+  /// element, sets the element index.
+  void setElementIndex(unsigned Index) {
+    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
+           getKind() == EK_ComplexElement);
+    this->Index = Index;
+  }
+  /// \brief For a lambda capture, return the capture's name.
+  StringRef getCapturedVarName() const {
+    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
+    return Capture.VarID->getName();
+  }
+  /// \brief Determine the location of the capture when initializing
+  /// field from a captured variable in a lambda.
+  SourceLocation getCaptureLoc() const {
+    assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
+    return SourceLocation::getFromRawEncoding(Capture.Location);
+  }
+  
+  void setParameterCFAudited() {
+    Kind = EK_Parameter_CF_Audited;
+  }
+
+  unsigned allocateManglingNumber() const { return ++ManglingNumber; }
+
+  /// Dump a representation of the initialized entity to standard error,
+  /// for debugging purposes.
+  void dump() const;
+
+private:
+  unsigned dumpImpl(raw_ostream &OS) const;
+};
+  
+/// \brief Describes the kind of initialization being performed, along with 
+/// location information for tokens related to the initialization (equal sign,
+/// parentheses).
+class InitializationKind {
+public:
+  /// \brief The kind of initialization being performed.
+  enum InitKind {
+    IK_Direct,       ///< Direct initialization
+    IK_DirectList,   ///< Direct list-initialization
+    IK_Copy,         ///< Copy initialization
+    IK_Default,      ///< Default initialization
+    IK_Value         ///< Value initialization
+  };
+  
+private:
+  /// \brief The context of the initialization.
+  enum InitContext {
+    IC_Normal,         ///< Normal context
+    IC_ExplicitConvs,  ///< Normal context, but allows explicit conversion funcs
+    IC_Implicit,       ///< Implicit context (value initialization)
+    IC_StaticCast,     ///< Static cast context
+    IC_CStyleCast,     ///< C-style cast context
+    IC_FunctionalCast  ///< Functional cast context
+  };
+  
+  /// \brief The kind of initialization being performed.
+  InitKind Kind : 8;
+
+  /// \brief The context of the initialization.
+  InitContext Context : 8;
+  
+  /// \brief The source locations involved in the initialization.
+  SourceLocation Locations[3];
+  
+  InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1, 
+                     SourceLocation Loc2, SourceLocation Loc3)
+    : Kind(Kind), Context(Context)
+  {
+    Locations[0] = Loc1;
+    Locations[1] = Loc2;
+    Locations[2] = Loc3;
+  }
+  
+public:
+  /// \brief Create a direct initialization.
+  static InitializationKind CreateDirect(SourceLocation InitLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation RParenLoc) {
+    return InitializationKind(IK_Direct, IC_Normal,
+                              InitLoc, LParenLoc, RParenLoc);
+  }
+
+  static InitializationKind CreateDirectList(SourceLocation InitLoc) {
+    return InitializationKind(IK_DirectList, IC_Normal,
+                              InitLoc, InitLoc, InitLoc);
+  }
+
+  /// \brief Create a direct initialization due to a cast that isn't a C-style 
+  /// or functional cast.
+  static InitializationKind CreateCast(SourceRange TypeRange) {
+    return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
+                              TypeRange.getBegin(), TypeRange.getEnd());
+  }
+  
+  /// \brief Create a direct initialization for a C-style cast.
+  static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
+                                             SourceRange TypeRange,
+                                             bool InitList) {
+    // C++ cast syntax doesn't permit init lists, but C compound literals are
+    // exactly that.
+    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+                              IC_CStyleCast, StartLoc, TypeRange.getBegin(),
+                              TypeRange.getEnd());
+  }
+
+  /// \brief Create a direct initialization for a functional cast.
+  static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
+                                                 bool InitList) {
+    return InitializationKind(InitList ? IK_DirectList : IK_Direct,
+                              IC_FunctionalCast, TypeRange.getBegin(),
+                              TypeRange.getBegin(), TypeRange.getEnd());
+  }
+
+  /// \brief Create a copy initialization.
+  static InitializationKind CreateCopy(SourceLocation InitLoc,
+                                       SourceLocation EqualLoc,
+                                       bool AllowExplicitConvs = false) {
+    return InitializationKind(IK_Copy, 
+                              AllowExplicitConvs? IC_ExplicitConvs : IC_Normal,
+                              InitLoc, EqualLoc, EqualLoc);
+  }
+  
+  /// \brief Create a default initialization.
+  static InitializationKind CreateDefault(SourceLocation InitLoc) {
+    return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
+  }
+  
+  /// \brief Create a value initialization.
+  static InitializationKind CreateValue(SourceLocation InitLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation RParenLoc,
+                                        bool isImplicit = false) {
+    return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
+                              InitLoc, LParenLoc, RParenLoc);
+  }
+  
+  /// \brief Determine the initialization kind.
+  InitKind getKind() const {
+    return Kind;
+  }
+  
+  /// \brief Determine whether this initialization is an explicit cast.
+  bool isExplicitCast() const {
+    return Context >= IC_StaticCast;
+  }
+  
+  /// \brief Determine whether this initialization is a C-style cast.
+  bool isCStyleOrFunctionalCast() const { 
+    return Context >= IC_CStyleCast; 
+  }
+
+  /// \brief Determine whether this is a C-style cast.
+  bool isCStyleCast() const {
+    return Context == IC_CStyleCast;
+  }
+
+  /// \brief Determine whether this is a functional-style cast.
+  bool isFunctionalCast() const {
+    return Context == IC_FunctionalCast;
+  }
+
+  /// \brief Determine whether this initialization is an implicit
+  /// value-initialization, e.g., as occurs during aggregate
+  /// initialization.
+  bool isImplicitValueInit() const { return Context == IC_Implicit; }
+
+  /// \brief Retrieve the location at which initialization is occurring.
+  SourceLocation getLocation() const { return Locations[0]; }
+  
+  /// \brief Retrieve the source range that covers the initialization.
+  SourceRange getRange() const { 
+    return SourceRange(Locations[0], Locations[2]);
+  }
+  
+  /// \brief Retrieve the location of the equal sign for copy initialization
+  /// (if present).
+  SourceLocation getEqualLoc() const {
+    assert(Kind == IK_Copy && "Only copy initialization has an '='");
+    return Locations[1];
+  }
+
+  bool isCopyInit() const { return Kind == IK_Copy; }
+
+  /// \brief Retrieve whether this initialization allows the use of explicit
+  ///        constructors.
+  bool AllowExplicit() const { return !isCopyInit(); }
+
+  /// \brief Retrieve whether this initialization allows the use of explicit
+  /// conversion functions when binding a reference. If the reference is the
+  /// first parameter in a copy or move constructor, such conversions are
+  /// permitted even though we are performing copy-initialization.
+  bool allowExplicitConversionFunctionsInRefBinding() const {
+    return !isCopyInit() || Context == IC_ExplicitConvs;
+  }
+  
+  /// \brief Retrieve the source range containing the locations of the open
+  /// and closing parentheses for value and direct initializations.
+  SourceRange getParenRange() const {
+    assert((Kind == IK_Direct || Kind == IK_Value) &&
+           "Only direct- and value-initialization have parentheses");
+    return SourceRange(Locations[1], Locations[2]);
+  }
+};
+
+/// \brief Describes the sequence of initializations required to initialize
+/// a given object or reference with a set of arguments.
+class InitializationSequence {
+public:
+  /// \brief Describes the kind of initialization sequence computed.
+  enum SequenceKind {
+    /// \brief A failed initialization sequence. The failure kind tells what
+    /// happened.
+    FailedSequence = 0,
+
+    /// \brief A dependent initialization, which could not be
+    /// type-checked due to the presence of dependent types or
+    /// dependently-typed expressions.
+    DependentSequence,
+
+    /// \brief A normal sequence.
+    NormalSequence
+  };
+  
+  /// \brief Describes the kind of a particular step in an initialization
+  /// sequence.
+  enum StepKind {
+    /// \brief Resolve the address of an overloaded function to a specific
+    /// function declaration.
+    SK_ResolveAddressOfOverloadedFunction,
+    /// \brief Perform a derived-to-base cast, producing an rvalue.
+    SK_CastDerivedToBaseRValue,
+    /// \brief Perform a derived-to-base cast, producing an xvalue.
+    SK_CastDerivedToBaseXValue,
+    /// \brief Perform a derived-to-base cast, producing an lvalue.
+    SK_CastDerivedToBaseLValue,
+    /// \brief Reference binding to an lvalue.
+    SK_BindReference,
+    /// \brief Reference binding to a temporary.
+    SK_BindReferenceToTemporary,
+    /// \brief An optional copy of a temporary object to another
+    /// temporary object, which is permitted (but not required) by
+    /// C++98/03 but not C++0x.
+    SK_ExtraneousCopyToTemporary,
+    /// \brief Perform a user-defined conversion, either via a conversion
+    /// function or via a constructor.
+    SK_UserConversion,
+    /// \brief Perform a qualification conversion, producing an rvalue.
+    SK_QualificationConversionRValue,
+    /// \brief Perform a qualification conversion, producing an xvalue.
+    SK_QualificationConversionXValue,
+    /// \brief Perform a qualification conversion, producing an lvalue.
+    SK_QualificationConversionLValue,
+    /// \brief Perform a conversion adding _Atomic to a type.
+    SK_AtomicConversion,
+    /// \brief Perform a load from a glvalue, producing an rvalue.
+    SK_LValueToRValue,
+    /// \brief Perform an implicit conversion sequence.
+    SK_ConversionSequence,
+    /// \brief Perform an implicit conversion sequence without narrowing.
+    SK_ConversionSequenceNoNarrowing,
+    /// \brief Perform list-initialization without a constructor.
+    SK_ListInitialization,
+    /// \brief Unwrap the single-element initializer list for a reference.
+    SK_UnwrapInitList,
+    /// \brief Rewrap the single-element initializer list for a reference.
+    SK_RewrapInitList,
+    /// \brief Perform initialization via a constructor.
+    SK_ConstructorInitialization,
+    /// \brief Perform initialization via a constructor, taking arguments from
+    /// a single InitListExpr.
+    SK_ConstructorInitializationFromList,
+    /// \brief Zero-initialize the object
+    SK_ZeroInitialization,
+    /// \brief C assignment
+    SK_CAssignment,
+    /// \brief Initialization by string
+    SK_StringInit,
+    /// \brief An initialization that "converts" an Objective-C object
+    /// (not a point to an object) to another Objective-C object type.
+    SK_ObjCObjectConversion,
+    /// \brief Array initialization (from an array rvalue).
+    /// This is a GNU C extension.
+    SK_ArrayInit,
+    /// \brief Array initialization from a parenthesized initializer list.
+    /// This is a GNU C++ extension.
+    SK_ParenthesizedArrayInit,
+    /// \brief Pass an object by indirect copy-and-restore.
+    SK_PassByIndirectCopyRestore,
+    /// \brief Pass an object by indirect restore.
+    SK_PassByIndirectRestore,
+    /// \brief Produce an Objective-C object pointer.
+    SK_ProduceObjCObject,
+    /// \brief Construct a std::initializer_list from an initializer list.
+    SK_StdInitializerList,
+    /// \brief Perform initialization via a constructor taking a single
+    /// std::initializer_list argument.
+    SK_StdInitializerListConstructorCall,
+    /// \brief Initialize an OpenCL sampler from an integer.
+    SK_OCLSamplerInit,
+    /// \brief Passing zero to a function where OpenCL event_t is expected.
+    SK_OCLZeroEvent
+  };
+  
+  /// \brief A single step in the initialization sequence.
+  class Step {
+  public:
+    /// \brief The kind of conversion or initialization step we are taking.
+    StepKind Kind;
+    
+    // \brief The type that results from this initialization.
+    QualType Type;
+
+    struct F {
+      bool HadMultipleCandidates;
+      FunctionDecl *Function;
+      DeclAccessPair FoundDecl;
+    };
+
+    union {
+      /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
+      /// SK_UserConversion, the function that the expression should be 
+      /// resolved to or the conversion function to call, respectively.
+      /// When Kind == SK_ConstructorInitialization or SK_ListConstruction,
+      /// the constructor to be called.
+      ///
+      /// Always a FunctionDecl, plus a Boolean flag telling if it was
+      /// selected from an overloaded set having size greater than 1.
+      /// For conversion decls, the naming class is the source type.
+      /// For construct decls, the naming class is the target type.
+      struct F Function;
+
+      /// \brief When Kind = SK_ConversionSequence, the implicit conversion
+      /// sequence.
+      ImplicitConversionSequence *ICS;
+
+      /// \brief When Kind = SK_RewrapInitList, the syntactic form of the
+      /// wrapping list.
+      InitListExpr *WrappingSyntacticList;
+    };
+
+    void Destroy();
+  };
+  
+private:
+  /// \brief The kind of initialization sequence computed.
+  enum SequenceKind SequenceKind;
+  
+  /// \brief Steps taken by this initialization.
+  SmallVector<Step, 4> Steps;
+  
+public:
+  /// \brief Describes why initialization failed.
+  enum FailureKind {
+    /// \brief Too many initializers provided for a reference.
+    FK_TooManyInitsForReference,
+    /// \brief Array must be initialized with an initializer list.
+    FK_ArrayNeedsInitList,
+    /// \brief Array must be initialized with an initializer list or a 
+    /// string literal.
+    FK_ArrayNeedsInitListOrStringLiteral,
+    /// \brief Array must be initialized with an initializer list or a
+    /// wide string literal.
+    FK_ArrayNeedsInitListOrWideStringLiteral,
+    /// \brief Initializing a wide char array with narrow string literal.
+    FK_NarrowStringIntoWideCharArray,
+    /// \brief Initializing char array with wide string literal.
+    FK_WideStringIntoCharArray,
+    /// \brief Initializing wide char array with incompatible wide string
+    /// literal.
+    FK_IncompatWideStringIntoWideChar,
+    /// \brief Array type mismatch.
+    FK_ArrayTypeMismatch,
+    /// \brief Non-constant array initializer
+    FK_NonConstantArrayInit,
+    /// \brief Cannot resolve the address of an overloaded function.
+    FK_AddressOfOverloadFailed,
+    /// \brief Overloading due to reference initialization failed.
+    FK_ReferenceInitOverloadFailed,
+    /// \brief Non-const lvalue reference binding to a temporary.
+    FK_NonConstLValueReferenceBindingToTemporary,
+    /// \brief Non-const lvalue reference binding to an lvalue of unrelated
+    /// type.
+    FK_NonConstLValueReferenceBindingToUnrelated,
+    /// \brief Rvalue reference binding to an lvalue.
+    FK_RValueReferenceBindingToLValue,
+    /// \brief Reference binding drops qualifiers.
+    FK_ReferenceInitDropsQualifiers,
+    /// \brief Reference binding failed.
+    FK_ReferenceInitFailed,
+    /// \brief Implicit conversion failed.
+    FK_ConversionFailed,
+    /// \brief Implicit conversion failed.
+    FK_ConversionFromPropertyFailed,
+    /// \brief Too many initializers for scalar
+    FK_TooManyInitsForScalar,
+    /// \brief Reference initialization from an initializer list
+    FK_ReferenceBindingToInitList,
+    /// \brief Initialization of some unused destination type with an
+    /// initializer list.
+    FK_InitListBadDestinationType,
+    /// \brief Overloading for a user-defined conversion failed.
+    FK_UserConversionOverloadFailed,
+    /// \brief Overloading for initialization by constructor failed.
+    FK_ConstructorOverloadFailed,
+    /// \brief Overloading for list-initialization by constructor failed.
+    FK_ListConstructorOverloadFailed,
+    /// \brief Default-initialization of a 'const' object.
+    FK_DefaultInitOfConst,
+    /// \brief Initialization of an incomplete type.
+    FK_Incomplete,
+    /// \brief Variable-length array must not have an initializer.
+    FK_VariableLengthArrayHasInitializer,
+    /// \brief List initialization failed at some point.
+    FK_ListInitializationFailed,
+    /// \brief Initializer has a placeholder type which cannot be
+    /// resolved by initialization.
+    FK_PlaceholderType,
+    /// \brief List-copy-initialization chose an explicit constructor.
+    FK_ExplicitConstructor
+  };
+  
+private:
+  /// \brief The reason why initialization failed.
+  FailureKind Failure;
+
+  /// \brief The failed result of overload resolution.
+  OverloadingResult FailedOverloadResult;
+  
+  /// \brief The candidate set created when initialization failed.
+  OverloadCandidateSet FailedCandidateSet;
+
+  /// \brief The incomplete type that caused a failure.
+  QualType FailedIncompleteType;
+  
+  /// \brief Prints a follow-up note that highlights the location of
+  /// the initialized entity, if it's remote.
+  void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
+
+public:
+  /// \brief Try to perform initialization of the given entity, creating a 
+  /// record of the steps required to perform the initialization.
+  ///
+  /// The generated initialization sequence will either contain enough
+  /// information to diagnose 
+  ///
+  /// \param S the semantic analysis object.
+  ///
+  /// \param Entity the entity being initialized.
+  ///
+  /// \param Kind the kind of initialization being performed.
+  ///
+  /// \param Args the argument(s) provided for initialization.
+  ///
+  /// \param TopLevelOfInitList true if we are initializing from an expression
+  ///        at the top level inside an initializer list. This disallows
+  ///        narrowing conversions in C++11 onwards.
+  InitializationSequence(Sema &S, 
+                         const InitializedEntity &Entity,
+                         const InitializationKind &Kind,
+                         MultiExprArg Args,
+                         bool TopLevelOfInitList = false);
+  void InitializeFrom(Sema &S, const InitializedEntity &Entity,
+                      const InitializationKind &Kind, MultiExprArg Args,
+                      bool TopLevelOfInitList);
+
+  ~InitializationSequence();
+  
+  /// \brief Perform the actual initialization of the given entity based on
+  /// the computed initialization sequence.
+  ///
+  /// \param S the semantic analysis object.
+  ///
+  /// \param Entity the entity being initialized.
+  ///
+  /// \param Kind the kind of initialization being performed.
+  ///
+  /// \param Args the argument(s) provided for initialization, ownership of
+  /// which is transferred into the routine.
+  ///
+  /// \param ResultType if non-NULL, will be set to the type of the
+  /// initialized object, which is the type of the declaration in most
+  /// cases. However, when the initialized object is a variable of
+  /// incomplete array type and the initializer is an initializer
+  /// list, this type will be set to the completed array type.
+  ///
+  /// \returns an expression that performs the actual object initialization, if
+  /// the initialization is well-formed. Otherwise, emits diagnostics
+  /// and returns an invalid expression.
+  ExprResult Perform(Sema &S,
+                     const InitializedEntity &Entity,
+                     const InitializationKind &Kind,
+                     MultiExprArg Args,
+                     QualType *ResultType = nullptr);
+  
+  /// \brief Diagnose an potentially-invalid initialization sequence.
+  ///
+  /// \returns true if the initialization sequence was ill-formed, 
+  /// false otherwise.
+  bool Diagnose(Sema &S, 
+                const InitializedEntity &Entity,
+                const InitializationKind &Kind,
+                ArrayRef<Expr *> Args);
+  
+  /// \brief Determine the kind of initialization sequence computed.
+  enum SequenceKind getKind() const { return SequenceKind; }
+  
+  /// \brief Set the kind of sequence computed.
+  void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
+  
+  /// \brief Determine whether the initialization sequence is valid.
+  LLVM_EXPLICIT operator bool() const { return !Failed(); }
+
+  /// \brief Determine whether the initialization sequence is invalid.
+  bool Failed() const { return SequenceKind == FailedSequence; }
+
+  typedef SmallVectorImpl<Step>::const_iterator step_iterator;
+  step_iterator step_begin() const { return Steps.begin(); }
+  step_iterator step_end()   const { return Steps.end(); }
+
+  /// \brief Determine whether this initialization is a direct reference 
+  /// binding (C++ [dcl.init.ref]).
+  bool isDirectReferenceBinding() const;
+  
+  /// \brief Determine whether this initialization failed due to an ambiguity.
+  bool isAmbiguous() const;
+  
+  /// \brief Determine whether this initialization is direct call to a 
+  /// constructor.
+  bool isConstructorInitialization() const;
+
+  /// \brief Returns whether the last step in this initialization sequence is a
+  /// narrowing conversion, defined by C++0x [dcl.init.list]p7.
+  ///
+  /// If this function returns true, *isInitializerConstant will be set to
+  /// describe whether *Initializer was a constant expression.  If
+  /// *isInitializerConstant is set to true, *ConstantValue will be set to the
+  /// evaluated value of *Initializer.
+  bool endsWithNarrowing(ASTContext &Ctx, const Expr *Initializer,
+                         bool *isInitializerConstant,
+                         APValue *ConstantValue) const;
+
+  /// \brief Add a new step in the initialization that resolves the address
+  /// of an overloaded function to a specific function declaration.
+  ///
+  /// \param Function the function to which the overloaded function reference
+  /// resolves.
+  void AddAddressOverloadResolutionStep(FunctionDecl *Function,
+                                        DeclAccessPair Found,
+                                        bool HadMultipleCandidates);
+
+  /// \brief Add a new step in the initialization that performs a derived-to-
+  /// base cast.
+  ///
+  /// \param BaseType the base type to which we will be casting.
+  ///
+  /// \param Category Indicates whether the result will be treated as an
+  /// rvalue, an xvalue, or an lvalue.
+  void AddDerivedToBaseCastStep(QualType BaseType,
+                                ExprValueKind Category);
+     
+  /// \brief Add a new step binding a reference to an object.
+  ///
+  /// \param BindingTemporary True if we are binding a reference to a temporary
+  /// object (thereby extending its lifetime); false if we are binding to an
+  /// lvalue or an lvalue treated as an rvalue.
+  void AddReferenceBindingStep(QualType T, bool BindingTemporary);
+
+  /// \brief Add a new step that makes an extraneous copy of the input
+  /// to a temporary of the same class type.
+  ///
+  /// This extraneous copy only occurs during reference binding in
+  /// C++98/03, where we are permitted (but not required) to introduce
+  /// an extra copy. At a bare minimum, we must check that we could
+  /// call the copy constructor, and produce a diagnostic if the copy
+  /// constructor is inaccessible or no copy constructor matches.
+  //
+  /// \param T The type of the temporary being created.
+  void AddExtraneousCopyToTemporary(QualType T);
+
+  /// \brief Add a new step invoking a conversion function, which is either
+  /// a constructor or a conversion function.
+  void AddUserConversionStep(FunctionDecl *Function,
+                             DeclAccessPair FoundDecl,
+                             QualType T,
+                             bool HadMultipleCandidates);
+
+  /// \brief Add a new step that performs a qualification conversion to the
+  /// given type.
+  void AddQualificationConversionStep(QualType Ty,
+                                     ExprValueKind Category);
+
+  /// \brief Add a new step that performs conversion from non-atomic to atomic
+  /// type.
+  void AddAtomicConversionStep(QualType Ty);
+
+  /// \brief Add a new step that performs a load of the given type.
+  ///
+  /// Although the term "LValueToRValue" is conventional, this applies to both
+  /// lvalues and xvalues.
+  void AddLValueToRValueStep(QualType Ty);
+
+  /// \brief Add a new step that applies an implicit conversion sequence.
+  void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
+                                 QualType T, bool TopLevelOfInitList = false);
+
+  /// \brief Add a list-initialization step.
+  void AddListInitializationStep(QualType T);
+
+  /// \brief Add a constructor-initialization step.
+  ///
+  /// \param FromInitList The constructor call is syntactically an initializer
+  /// list.
+  /// \param AsInitList The constructor is called as an init list constructor.
+  void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
+                                        AccessSpecifier Access,
+                                        QualType T,
+                                        bool HadMultipleCandidates,
+                                        bool FromInitList, bool AsInitList);
+
+  /// \brief Add a zero-initialization step.
+  void AddZeroInitializationStep(QualType T);
+
+  /// \brief Add a C assignment step.
+  //
+  // FIXME: It isn't clear whether this should ever be needed;
+  // ideally, we would handle everything needed in C in the common
+  // path. However, that isn't the case yet.
+  void AddCAssignmentStep(QualType T);
+
+  /// \brief Add a string init step.
+  void AddStringInitStep(QualType T);
+
+  /// \brief Add an Objective-C object conversion step, which is
+  /// always a no-op.
+  void AddObjCObjectConversionStep(QualType T);
+
+  /// \brief Add an array initialization step.
+  void AddArrayInitStep(QualType T);
+
+  /// \brief Add a parenthesized array initialization step.
+  void AddParenthesizedArrayInitStep(QualType T);
+
+  /// \brief Add a step to pass an object by indirect copy-restore.
+  void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy);
+
+  /// \brief Add a step to "produce" an Objective-C object (by
+  /// retaining it).
+  void AddProduceObjCObjectStep(QualType T);
+
+  /// \brief Add a step to construct a std::initializer_list object from an
+  /// initializer list.
+  void AddStdInitializerListConstructionStep(QualType T);
+
+  /// \brief Add a step to initialize an OpenCL sampler from an integer
+  /// constant.
+  void AddOCLSamplerInitStep(QualType T);
+
+  /// \brief Add a step to initialize an OpenCL event_t from a NULL
+  /// constant.
+  void AddOCLZeroEventStep(QualType T);
+
+  /// \brief Add steps to unwrap a initializer list for a reference around a
+  /// single element and rewrap it at the end.
+  void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
+
+  /// \brief Note that this initialization sequence failed.
+  void SetFailed(FailureKind Failure) {
+    SequenceKind = FailedSequence;
+    this->Failure = Failure;
+    assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) &&
+           "Incomplete type failure requires a type!");
+  }
+  
+  /// \brief Note that this initialization sequence failed due to failed
+  /// overload resolution.
+  void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
+  
+  /// \brief Retrieve a reference to the candidate set when overload
+  /// resolution fails.
+  OverloadCandidateSet &getFailedCandidateSet() {
+    return FailedCandidateSet;
+  }
+
+  /// \brief Get the overloading result, for when the initialization
+  /// sequence failed due to a bad overload.
+  OverloadingResult getFailedOverloadResult() const {
+    return FailedOverloadResult;
+  }
+
+  /// \brief Note that this initialization sequence failed due to an
+  /// incomplete type.
+  void setIncompleteTypeFailure(QualType IncompleteType) {
+    FailedIncompleteType = IncompleteType;
+    SetFailed(FK_Incomplete);
+  }
+
+  /// \brief Determine why initialization failed.
+  FailureKind getFailureKind() const {
+    assert(Failed() && "Not an initialization failure!");
+    return Failure;
+  }
+
+  /// \brief Dump a representation of this initialization sequence to 
+  /// the given stream, for debugging purposes.
+  void dump(raw_ostream &OS) const;
+  
+  /// \brief Dump a representation of this initialization sequence to 
+  /// standard error, for debugging purposes.
+  void dump() const;
+};
+  
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_INITIALIZATION_H
diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h
new file mode 100644
index 0000000..63dfa72
--- /dev/null
+++ b/include/clang/Sema/LocInfoType.h
@@ -0,0 +1,62 @@
+//===--- LocInfoType.h - Parsed Type with Location Information---*- 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 LocInfoType class, which holds a type and its
+// source-location information.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H
+#define LLVM_CLANG_SEMA_LOCINFOTYPE_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+class TypeSourceInfo;
+
+/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
+/// parsing.
+///
+/// LocInfoType is a "transient" type, only needed for passing to/from Parser
+/// and Sema, when we want to preserve type source info for a parsed type.
+/// It will not participate in the type system semantics in any way.
+class LocInfoType : public Type {
+  enum {
+    // The last number that can fit in Type's TC.
+    // Avoids conflict with an existing Type class.
+    LocInfo = Type::TypeLast + 1
+  };
+
+  TypeSourceInfo *DeclInfo;
+
+  LocInfoType(QualType ty, TypeSourceInfo *TInfo)
+    : Type((TypeClass)LocInfo, ty, ty->isDependentType(),
+           ty->isInstantiationDependentType(),
+           ty->isVariablyModifiedType(),
+           ty->containsUnexpandedParameterPack()),
+      DeclInfo(TInfo) {
+    assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
+  }
+  friend class Sema;
+
+public:
+  QualType getType() const { return getCanonicalTypeInternal(); }
+  TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
+
+  void getAsStringInternal(std::string &Str,
+                           const PrintingPolicy &Policy) const;
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == (TypeClass)LocInfo;
+  }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
new file mode 100644
index 0000000..00cc164
--- /dev/null
+++ b/include/clang/Sema/Lookup.h
@@ -0,0 +1,755 @@
+//===--- Lookup.h - Classes for name lookup ---------------------*- 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 LookupResult class, which is integral to
+// Sema's name-lookup subsystem.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LOOKUP_H
+#define LLVM_CLANG_SEMA_LOOKUP_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+
+/// @brief Represents the results of name lookup.
+///
+/// An instance of the LookupResult class captures the results of a
+/// single name lookup, which can return no result (nothing found),
+/// a single declaration, a set of overloaded functions, or an
+/// ambiguity. Use the getKind() method to determine which of these
+/// results occurred for a given lookup.
+class LookupResult {
+public:
+  enum LookupResultKind {
+    /// @brief No entity found met the criteria.
+    NotFound = 0,
+
+    /// @brief No entity found met the criteria within the current 
+    /// instantiation,, but there were dependent base classes of the 
+    /// current instantiation that could not be searched.
+    NotFoundInCurrentInstantiation,
+    
+    /// @brief Name lookup found a single declaration that met the
+    /// criteria.  getFoundDecl() will return this declaration.
+    Found,
+
+    /// @brief Name lookup found a set of overloaded functions that
+    /// met the criteria.
+    FoundOverloaded,
+
+    /// @brief Name lookup found an unresolvable value declaration
+    /// and cannot yet complete.  This only happens in C++ dependent
+    /// contexts with dependent using declarations.
+    FoundUnresolvedValue,
+
+    /// @brief Name lookup results in an ambiguity; use
+    /// getAmbiguityKind to figure out what kind of ambiguity
+    /// we have.
+    Ambiguous
+  };
+
+  enum AmbiguityKind {
+    /// Name lookup results in an ambiguity because multiple
+    /// entities that meet the lookup criteria were found in
+    /// subobjects of different types. For example:
+    /// @code
+    /// struct A { void f(int); }
+    /// struct B { void f(double); }
+    /// struct C : A, B { };
+    /// void test(C c) {
+    ///   c.f(0); // error: A::f and B::f come from subobjects of different
+    ///           // types. overload resolution is not performed.
+    /// }
+    /// @endcode
+    AmbiguousBaseSubobjectTypes,
+
+    /// Name lookup results in an ambiguity because multiple
+    /// nonstatic entities that meet the lookup criteria were found
+    /// in different subobjects of the same type. For example:
+    /// @code
+    /// struct A { int x; };
+    /// struct B : A { };
+    /// struct C : A { };
+    /// struct D : B, C { };
+    /// int test(D d) {
+    ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
+    /// }
+    /// @endcode
+    AmbiguousBaseSubobjects,
+
+    /// Name lookup results in an ambiguity because multiple definitions
+    /// of entity that meet the lookup criteria were found in different
+    /// declaration contexts.
+    /// @code
+    /// namespace A {
+    ///   int i;
+    ///   namespace B { int i; }
+    ///   int test() {
+    ///     using namespace B;
+    ///     return i; // error 'i' is found in namespace A and A::B
+    ///    }
+    /// }
+    /// @endcode
+    AmbiguousReference,
+
+    /// Name lookup results in an ambiguity because an entity with a
+    /// tag name was hidden by an entity with an ordinary name from
+    /// a different context.
+    /// @code
+    /// namespace A { struct Foo {}; }
+    /// namespace B { void Foo(); }
+    /// namespace C {
+    ///   using namespace A;
+    ///   using namespace B;
+    /// }
+    /// void test() {
+    ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
+    ///             // different namespace
+    /// }
+    /// @endcode
+    AmbiguousTagHiding
+  };
+
+  /// A little identifier for flagging temporary lookup results.
+  enum TemporaryToken {
+    Temporary
+  };
+
+  typedef UnresolvedSetImpl::iterator iterator;
+
+  LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
+               Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(nullptr),
+      NamingClass(nullptr),
+      SemaRef(SemaRef),
+      NameInfo(NameInfo),
+      LookupKind(LookupKind),
+      IDNS(0),
+      Redecl(Redecl != Sema::NotForRedeclaration),
+      HideTags(true),
+      Diagnose(Redecl == Sema::NotForRedeclaration),
+      AllowHidden(Redecl == Sema::ForRedeclaration),
+      Shadowed(false)
+  {
+    configure();
+  }
+
+  // TODO: consider whether this constructor should be restricted to take
+  // as input a const IndentifierInfo* (instead of Name),
+  // forcing other cases towards the constructor taking a DNInfo.
+  LookupResult(Sema &SemaRef, DeclarationName Name,
+               SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(nullptr),
+      NamingClass(nullptr),
+      SemaRef(SemaRef),
+      NameInfo(Name, NameLoc),
+      LookupKind(LookupKind),
+      IDNS(0),
+      Redecl(Redecl != Sema::NotForRedeclaration),
+      HideTags(true),
+      Diagnose(Redecl == Sema::NotForRedeclaration),
+      AllowHidden(Redecl == Sema::ForRedeclaration),
+      Shadowed(false)
+  {
+    configure();
+  }
+
+  /// Creates a temporary lookup result, initializing its core data
+  /// using the information from another result.  Diagnostics are always
+  /// disabled.
+  LookupResult(TemporaryToken _, const LookupResult &Other)
+    : ResultKind(NotFound),
+      Paths(nullptr),
+      NamingClass(nullptr),
+      SemaRef(Other.SemaRef),
+      NameInfo(Other.NameInfo),
+      LookupKind(Other.LookupKind),
+      IDNS(Other.IDNS),
+      Redecl(Other.Redecl),
+      HideTags(Other.HideTags),
+      Diagnose(false),
+      AllowHidden(Other.AllowHidden),
+      Shadowed(false)
+  {}
+
+  ~LookupResult() {
+    if (Diagnose) diagnose();
+    if (Paths) deletePaths(Paths);
+  }
+
+  /// Gets the name info to look up.
+  const DeclarationNameInfo &getLookupNameInfo() const {
+    return NameInfo;
+  }
+
+  /// \brief Sets the name info to look up.
+  void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
+    this->NameInfo = NameInfo;
+  }
+
+  /// Gets the name to look up.
+  DeclarationName getLookupName() const {
+    return NameInfo.getName();
+  }
+
+  /// \brief Sets the name to look up.
+  void setLookupName(DeclarationName Name) {
+    NameInfo.setName(Name);
+  }
+
+  /// Gets the kind of lookup to perform.
+  Sema::LookupNameKind getLookupKind() const {
+    return LookupKind;
+  }
+
+  /// True if this lookup is just looking for an existing declaration.
+  bool isForRedeclaration() const {
+    return Redecl;
+  }
+
+  /// \brief Specify whether hidden declarations are visible, e.g.,
+  /// for recovery reasons.
+  void setAllowHidden(bool AH) {
+    AllowHidden = AH;
+  }
+
+  /// \brief Determine whether this lookup is permitted to see hidden
+  /// declarations, such as those in modules that have not yet been imported.
+  bool isHiddenDeclarationVisible() const {
+    return AllowHidden || LookupKind == Sema::LookupTagName;
+  }
+  
+  /// Sets whether tag declarations should be hidden by non-tag
+  /// declarations during resolution.  The default is true.
+  void setHideTags(bool Hide) {
+    HideTags = Hide;
+  }
+
+  bool isAmbiguous() const {
+    return getResultKind() == Ambiguous;
+  }
+
+  /// Determines if this names a single result which is not an
+  /// unresolved value using decl.  If so, it is safe to call
+  /// getFoundDecl().
+  bool isSingleResult() const {
+    return getResultKind() == Found;
+  }
+
+  /// Determines if the results are overloaded.
+  bool isOverloadedResult() const {
+    return getResultKind() == FoundOverloaded;
+  }
+
+  bool isUnresolvableResult() const {
+    return getResultKind() == FoundUnresolvedValue;
+  }
+
+  LookupResultKind getResultKind() const {
+    assert(sanity());
+    return ResultKind;
+  }
+
+  AmbiguityKind getAmbiguityKind() const {
+    assert(isAmbiguous());
+    return Ambiguity;
+  }
+
+  const UnresolvedSetImpl &asUnresolvedSet() const {
+    return Decls;
+  }
+
+  iterator begin() const { return iterator(Decls.begin()); }
+  iterator end() const { return iterator(Decls.end()); }
+
+  /// \brief Return true if no decls were found
+  bool empty() const { return Decls.empty(); }
+
+  /// \brief Return the base paths structure that's associated with
+  /// these results, or null if none is.
+  CXXBasePaths *getBasePaths() const {
+    return Paths;
+  }
+
+  /// \brief Determine whether the given declaration is visible to the
+  /// program.
+  static bool isVisible(Sema &SemaRef, NamedDecl *D) {
+    // If this declaration is not hidden, it's visible.
+    if (!D->isHidden())
+      return true;
+
+    if (SemaRef.ActiveTemplateInstantiations.empty())
+      return false;
+
+    // During template instantiation, we can refer to hidden declarations, if
+    // they were visible in any module along the path of instantiation.
+    return isVisibleSlow(SemaRef, D);
+  }
+
+  /// \brief Retrieve the accepted (re)declaration of the given declaration,
+  /// if there is one.
+  NamedDecl *getAcceptableDecl(NamedDecl *D) const {
+    if (!D->isInIdentifierNamespace(IDNS))
+      return nullptr;
+
+    if (isHiddenDeclarationVisible() || isVisible(SemaRef, D))
+      return D;
+
+    return getAcceptableDeclSlow(D);
+  }
+
+private:
+  static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
+  NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
+
+public:
+  /// \brief Returns the identifier namespace mask for this lookup.
+  unsigned getIdentifierNamespace() const {
+    return IDNS;
+  }
+
+  /// \brief Returns whether these results arose from performing a
+  /// lookup into a class.
+  bool isClassLookup() const {
+    return NamingClass != nullptr;
+  }
+
+  /// \brief Returns the 'naming class' for this lookup, i.e. the
+  /// class which was looked into to find these results.
+  ///
+  /// C++0x [class.access.base]p5:
+  ///   The access to a member is affected by the class in which the
+  ///   member is named. This naming class is the class in which the
+  ///   member name was looked up and found. [Note: this class can be
+  ///   explicit, e.g., when a qualified-id is used, or implicit,
+  ///   e.g., when a class member access operator (5.2.5) is used
+  ///   (including cases where an implicit "this->" is added). If both
+  ///   a class member access operator and a qualified-id are used to
+  ///   name the member (as in p->T::m), the class naming the member
+  ///   is the class named by the nested-name-specifier of the
+  ///   qualified-id (that is, T). -- end note ]
+  ///
+  /// This is set by the lookup routines when they find results in a class.
+  CXXRecordDecl *getNamingClass() const {
+    return NamingClass;
+  }
+
+  /// \brief Sets the 'naming class' for this lookup.
+  void setNamingClass(CXXRecordDecl *Record) {
+    NamingClass = Record;
+  }
+
+  /// \brief Returns the base object type associated with this lookup;
+  /// important for [class.protected].  Most lookups do not have an
+  /// associated base object.
+  QualType getBaseObjectType() const {
+    return BaseObjectType;
+  }
+
+  /// \brief Sets the base object type for this lookup.
+  void setBaseObjectType(QualType T) {
+    BaseObjectType = T;
+  }
+
+  /// \brief Add a declaration to these results with its natural access.
+  /// Does not test the acceptance criteria.
+  void addDecl(NamedDecl *D) {
+    addDecl(D, D->getAccess());
+  }
+
+  /// \brief Add a declaration to these results with the given access.
+  /// Does not test the acceptance criteria.
+  void addDecl(NamedDecl *D, AccessSpecifier AS) {
+    Decls.addDecl(D, AS);
+    ResultKind = Found;
+  }
+
+  /// \brief Add all the declarations from another set of lookup
+  /// results.
+  void addAllDecls(const LookupResult &Other) {
+    Decls.append(Other.Decls.begin(), Other.Decls.end());
+    ResultKind = Found;
+  }
+
+  /// \brief Determine whether no result was found because we could not
+  /// search into dependent base classes of the current instantiation.
+  bool wasNotFoundInCurrentInstantiation() const {
+    return ResultKind == NotFoundInCurrentInstantiation;
+  }
+  
+  /// \brief Note that while no result was found in the current instantiation,
+  /// there were dependent base classes that could not be searched.
+  void setNotFoundInCurrentInstantiation() {
+    assert(ResultKind == NotFound && Decls.empty());
+    ResultKind = NotFoundInCurrentInstantiation;
+  }
+
+  /// \brief Determine whether the lookup result was shadowed by some other
+  /// declaration that lookup ignored.
+  bool isShadowed() const { return Shadowed; }
+
+  /// \brief Note that we found and ignored a declaration while performing
+  /// lookup.
+  void setShadowed() { Shadowed = true; }
+
+  /// \brief Resolves the result kind of the lookup, possibly hiding
+  /// decls.
+  ///
+  /// This should be called in any environment where lookup might
+  /// generate multiple lookup results.
+  void resolveKind();
+
+  /// \brief Re-resolves the result kind of the lookup after a set of
+  /// removals has been performed.
+  void resolveKindAfterFilter() {
+    if (Decls.empty()) {
+      if (ResultKind != NotFoundInCurrentInstantiation)
+        ResultKind = NotFound;
+
+      if (Paths) {
+        deletePaths(Paths);
+        Paths = nullptr;
+      }
+    } else {
+      AmbiguityKind SavedAK = Ambiguity;
+      ResultKind = Found;
+      resolveKind();
+
+      // If we didn't make the lookup unambiguous, restore the old
+      // ambiguity kind.
+      if (ResultKind == Ambiguous) {
+        Ambiguity = SavedAK;
+      } else if (Paths) {
+        deletePaths(Paths);
+        Paths = nullptr;
+      }
+    }
+  }
+
+  template <class DeclClass>
+  DeclClass *getAsSingle() const {
+    if (getResultKind() != Found) return nullptr;
+    return dyn_cast<DeclClass>(getFoundDecl());
+  }
+
+  /// \brief Fetch the unique decl found by this lookup.  Asserts
+  /// that one was found.
+  ///
+  /// This is intended for users who have examined the result kind
+  /// and are certain that there is only one result.
+  NamedDecl *getFoundDecl() const {
+    assert(getResultKind() == Found
+           && "getFoundDecl called on non-unique result");
+    return (*begin())->getUnderlyingDecl();
+  }
+
+  /// Fetches a representative decl.  Useful for lazy diagnostics.
+  NamedDecl *getRepresentativeDecl() const {
+    assert(!Decls.empty() && "cannot get representative of empty set");
+    return *begin();
+  }
+
+  /// \brief Asks if the result is a single tag decl.
+  bool isSingleTagDecl() const {
+    return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
+  }
+
+  /// \brief Make these results show that the name was found in
+  /// base classes of different types.
+  ///
+  /// The given paths object is copied and invalidated.
+  void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
+
+  /// \brief Make these results show that the name was found in
+  /// distinct base classes of the same type.
+  ///
+  /// The given paths object is copied and invalidated.
+  void setAmbiguousBaseSubobjects(CXXBasePaths &P);
+
+  /// \brief Make these results show that the name was found in
+  /// different contexts and a tag decl was hidden by an ordinary
+  /// decl in a different context.
+  void setAmbiguousQualifiedTagHiding() {
+    setAmbiguous(AmbiguousTagHiding);
+  }
+
+  /// \brief Clears out any current state.
+  void clear() {
+    ResultKind = NotFound;
+    Decls.clear();
+    if (Paths) deletePaths(Paths);
+    Paths = nullptr;
+    NamingClass = nullptr;
+    Shadowed = false;
+  }
+
+  /// \brief Clears out any current state and re-initializes for a
+  /// different kind of lookup.
+  void clear(Sema::LookupNameKind Kind) {
+    clear();
+    LookupKind = Kind;
+    configure();
+  }
+
+  /// \brief Change this lookup's redeclaration kind.
+  void setRedeclarationKind(Sema::RedeclarationKind RK) {
+    Redecl = RK;
+    AllowHidden = (RK == Sema::ForRedeclaration);
+    configure();
+  }
+
+  void print(raw_ostream &);
+
+  /// Suppress the diagnostics that would normally fire because of this
+  /// lookup.  This happens during (e.g.) redeclaration lookups.
+  void suppressDiagnostics() {
+    Diagnose = false;
+  }
+
+  /// Determines whether this lookup is suppressing diagnostics.
+  bool isSuppressingDiagnostics() const {
+    return !Diagnose;
+  }
+
+  /// Sets a 'context' source range.
+  void setContextRange(SourceRange SR) {
+    NameContextRange = SR;
+  }
+
+  /// Gets the source range of the context of this name; for C++
+  /// qualified lookups, this is the source range of the scope
+  /// specifier.
+  SourceRange getContextRange() const {
+    return NameContextRange;
+  }
+
+  /// Gets the location of the identifier.  This isn't always defined:
+  /// sometimes we're doing lookups on synthesized names.
+  SourceLocation getNameLoc() const {
+    return NameInfo.getLoc();
+  }
+
+  /// \brief Get the Sema object that this lookup result is searching
+  /// with.
+  Sema &getSema() const { return SemaRef; }
+
+  /// A class for iterating through a result set and possibly
+  /// filtering out results.  The results returned are possibly
+  /// sugared.
+  class Filter {
+    LookupResult &Results;
+    LookupResult::iterator I;
+    bool Changed;
+    bool CalledDone;
+    
+    friend class LookupResult;
+    Filter(LookupResult &Results)
+      : Results(Results), I(Results.begin()), Changed(false), CalledDone(false)
+    {}
+
+  public:
+    ~Filter() {
+      assert(CalledDone &&
+             "LookupResult::Filter destroyed without done() call");
+    }
+
+    bool hasNext() const {
+      return I != Results.end();
+    }
+
+    NamedDecl *next() {
+      assert(I != Results.end() && "next() called on empty filter");
+      return *I++;
+    }
+
+    /// Restart the iteration.
+    void restart() {
+      I = Results.begin();
+    }
+
+    /// Erase the last element returned from this iterator.
+    void erase() {
+      Results.Decls.erase(--I);
+      Changed = true;
+    }
+
+    /// Replaces the current entry with the given one, preserving the
+    /// access bits.
+    void replace(NamedDecl *D) {
+      Results.Decls.replace(I-1, D);
+      Changed = true;
+    }
+
+    /// Replaces the current entry with the given one.
+    void replace(NamedDecl *D, AccessSpecifier AS) {
+      Results.Decls.replace(I-1, D, AS);
+      Changed = true;
+    }
+
+    void done() {
+      assert(!CalledDone && "done() called twice");
+      CalledDone = true;
+
+      if (Changed)
+        Results.resolveKindAfterFilter();
+    }
+  };
+
+  /// Create a filter for this result set.
+  Filter makeFilter() {
+    return Filter(*this);
+  }
+
+  void setFindLocalExtern(bool FindLocalExtern) {
+    if (FindLocalExtern)
+      IDNS |= Decl::IDNS_LocalExtern;
+    else
+      IDNS &= ~Decl::IDNS_LocalExtern;
+  }
+
+private:
+  void diagnose() {
+    if (isAmbiguous())
+      SemaRef.DiagnoseAmbiguousLookup(*this);
+    else if (isClassLookup() && SemaRef.getLangOpts().AccessControl)
+      SemaRef.CheckLookupAccess(*this);
+  }
+
+  void setAmbiguous(AmbiguityKind AK) {
+    ResultKind = Ambiguous;
+    Ambiguity = AK;
+  }
+
+  void addDeclsFromBasePaths(const CXXBasePaths &P);
+  void configure();
+
+  // Sanity checks.
+  bool sanity() const;
+
+  bool sanityCheckUnresolved() const {
+    for (iterator I = begin(), E = end(); I != E; ++I)
+      if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
+        return true;
+    return false;
+  }
+
+  static void deletePaths(CXXBasePaths *);
+
+  // Results.
+  LookupResultKind ResultKind;
+  AmbiguityKind Ambiguity; // ill-defined unless ambiguous
+  UnresolvedSet<8> Decls;
+  CXXBasePaths *Paths;
+  CXXRecordDecl *NamingClass;
+  QualType BaseObjectType;
+
+  // Parameters.
+  Sema &SemaRef;
+  DeclarationNameInfo NameInfo;
+  SourceRange NameContextRange;
+  Sema::LookupNameKind LookupKind;
+  unsigned IDNS; // set by configure()
+
+  bool Redecl;
+
+  /// \brief True if tag declarations should be hidden if non-tags
+  ///   are present
+  bool HideTags;
+
+  bool Diagnose;
+
+  /// \brief True if we should allow hidden declarations to be 'visible'.
+  bool AllowHidden;
+
+  /// \brief True if the found declarations were shadowed by some other
+  /// declaration that we skipped. This only happens when \c LookupKind
+  /// is \c LookupRedeclarationWithLinkage.
+  bool Shadowed;
+};
+
+/// \brief Consumes visible declarations found when searching for
+/// all visible names within a given scope or context.
+///
+/// This abstract class is meant to be subclassed by clients of \c
+/// Sema::LookupVisibleDecls(), each of which should override the \c
+/// FoundDecl() function to process declarations as they are found.
+class VisibleDeclConsumer {
+public:
+  /// \brief Destroys the visible declaration consumer.
+  virtual ~VisibleDeclConsumer();
+
+  /// \brief Determine whether hidden declarations (from unimported
+  /// modules) should be given to this consumer. By default, they
+  /// are not included.
+  virtual bool includeHiddenDecls() const;
+
+  /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
+  /// declaration visible from the current scope or context.
+  ///
+  /// \param ND the declaration found.
+  ///
+  /// \param Hiding a declaration that hides the declaration \p ND,
+  /// or NULL if no such declaration exists.
+  ///
+  /// \param Ctx the original context from which the lookup started.
+  ///
+  /// \param InBaseClass whether this declaration was found in base
+  /// class of the context we searched.
+  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+                         bool InBaseClass) = 0;
+};
+
+/// \brief A class for storing results from argument-dependent lookup.
+class ADLResult {
+private:
+  /// A map from canonical decls to the 'most recent' decl.
+  llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
+
+public:
+  /// Adds a new ADL candidate to this map.
+  void insert(NamedDecl *D);
+
+  /// Removes any data associated with a given decl.
+  void erase(NamedDecl *D) {
+    Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
+  }
+
+  class iterator
+      : public std::iterator<std::forward_iterator_tag, NamedDecl *> {
+    typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
+    inner_iterator iter;
+
+    friend class ADLResult;
+    iterator(const inner_iterator &iter) : iter(iter) {}
+  public:
+    iterator() {}
+
+    iterator &operator++() { ++iter; return *this; }
+    iterator operator++(int) { return iterator(iter++); }
+
+    value_type operator*() const { return iter->second; }
+
+    bool operator==(const iterator &other) const { return iter == other.iter; }
+    bool operator!=(const iterator &other) const { return iter != other.iter; }
+  };
+
+  iterator begin() { return iterator(Decls.begin()); }
+  iterator end() { return iterator(Decls.end()); }
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
new file mode 100644
index 0000000..d4b985d
--- /dev/null
+++ b/include/clang/Sema/LoopHint.h
@@ -0,0 +1,40 @@
+//===--- LoopHint.h - Types for LoopHint ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LOOPHINT_H
+#define LLVM_CLANG_SEMA_LOOPHINT_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.h"
+
+namespace clang {
+
+/// \brief Loop optimization hint for loop and unroll pragmas.
+struct LoopHint {
+  // Source range of the directive.
+  SourceRange Range;
+  // Identifier corresponding to the name of the pragma.  "loop" for
+  // "#pragma clang loop" directives and "unroll" for "#pragma unroll"
+  // hints.
+  IdentifierLoc *PragmaNameLoc;
+  // Name of the loop hint.  Examples: "unroll", "vectorize".  In the
+  // "#pragma unroll" case, this is identical to PragmaNameLoc.
+  IdentifierLoc *OptionLoc;
+  // Identifier for the hint argument.  If null, then the hint has no argument
+  // such as for "#pragma unroll".
+  IdentifierLoc *ValueLoc;
+  // Expression for the hint argument if it exists, null otherwise.
+  Expr *ValueExpr;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_LOOPHINT_H
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
new file mode 100644
index 0000000..7860b6d
--- /dev/null
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -0,0 +1,371 @@
+//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- 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 ExternalSemaSource interface, dispatching to all clients
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
+#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
+
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Weak.h"
+#include "llvm/ADT/SmallVector.h"
+#include <utility>
+
+namespace clang {
+
+  class CXXConstructorDecl;
+  class CXXRecordDecl;
+  class DeclaratorDecl;
+  struct ExternalVTableUse;
+  class LookupResult;
+  class NamespaceDecl;
+  class Scope;
+  class Sema;
+  class TypedefNameDecl;
+  class ValueDecl;
+  class VarDecl;
+
+
+/// \brief An abstract interface that should be implemented by
+/// external AST sources that also provide information for semantic
+/// analysis.
+class MultiplexExternalSemaSource : public ExternalSemaSource {
+
+private:
+  SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them.
+
+public:
+  
+  ///\brief Constructs a new multiplexing external sema source and appends the
+  /// given element to it.
+  ///
+  ///\param[in] s1 - A non-null (old) ExternalSemaSource.
+  ///\param[in] s2 - A non-null (new) ExternalSemaSource.
+  ///
+  MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2);
+
+  ~MultiplexExternalSemaSource();
+
+  ///\brief Appends new source to the source list.
+  ///
+  ///\param[in] source - An ExternalSemaSource.
+  ///
+  void addSource(ExternalSemaSource &source);
+
+  //===--------------------------------------------------------------------===//
+  // ExternalASTSource.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  Decl *GetExternalDecl(uint32_t ID) override;
+
+  /// \brief Complete the redeclaration chain if it's been extended since the
+  /// previous generation of the AST source.
+  void CompleteRedeclChain(const Decl *D) override;
+
+  /// \brief Resolve a selector ID into a selector.
+  Selector GetExternalSelector(uint32_t ID) override;
+
+  /// \brief Returns the number of selectors known to the external AST
+  /// source.
+  uint32_t GetNumExternalSelectors() override;
+
+  /// \brief Resolve the offset of a statement in the decl stream into
+  /// a statement.
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
+
+  /// \brief Resolve the offset of a set of C++ base specifiers in the decl
+  /// stream into an array of specifiers.
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
+
+  /// \brief Find all declarations with the given name in the
+  /// given context.
+  bool
+  FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override;
+
+  /// \brief Ensures that the table of all visible declarations inside this
+  /// context is up to date.
+  void completeVisibleDeclsMap(const DeclContext *DC) override;
+
+  /// \brief Finds all declarations lexically contained within the given
+  /// DeclContext, after applying an optional filter predicate.
+  ///
+  /// \param isKindWeWant a predicate function that returns true if the passed
+  /// declaration kind is one we are looking for. If NULL, all declarations
+  /// are returned.
+  ///
+  /// \return an indication of whether the load succeeded or failed.
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                bool (*isKindWeWant)(Decl::Kind),
+                                SmallVectorImpl<Decl*> &Result) override;
+
+  /// \brief Finds all declarations lexically contained within the given
+  /// DeclContext.
+  ///
+  /// \return true if an error occurred
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                SmallVectorImpl<Decl*> &Result) {
+    return FindExternalLexicalDecls(DC, nullptr, Result);
+  }
+
+  template <typename DeclTy>
+  ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
+                                  SmallVectorImpl<Decl*> &Result) {
+    return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
+  }
+
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \p Length can be 0 to indicate a point at \p Offset instead of
+  /// a range. 
+  void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls) override;
+
+  /// \brief Gives the external AST source an opportunity to complete
+  /// an incomplete type.
+  void CompleteType(TagDecl *Tag) override;
+
+  /// \brief Gives the external AST source an opportunity to complete an
+  /// incomplete Objective-C class.
+  ///
+  /// This routine will only be invoked if the "externally completed" bit is
+  /// set on the ObjCInterfaceDecl via the function 
+  /// \c ObjCInterfaceDecl::setExternallyCompleted().
+  void CompleteType(ObjCInterfaceDecl *Class) override;
+
+  /// \brief Loads comment ranges.
+  void ReadComments() override;
+
+  /// \brief Notify ExternalASTSource that we started deserialization of
+  /// a decl or type so until FinishedDeserializing is called there may be
+  /// decls that are initializing. Must be paired with FinishedDeserializing.
+  void StartedDeserializing() override;
+
+  /// \brief Notify ExternalASTSource that we finished the deserialization of
+  /// a decl or type. Must be paired with StartedDeserializing.
+  void FinishedDeserializing() override;
+
+  /// \brief Function that will be invoked when we begin parsing a new
+  /// translation unit involving this external AST source.
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
+
+  /// \brief Print any statistics that have been gathered regarding
+  /// the external AST source.
+  void PrintStats() override;
+  
+  
+  /// \brief Perform layout on the given record.
+  ///
+  /// This routine allows the external AST source to provide an specific 
+  /// layout for a record, overriding the layout that would normally be
+  /// constructed. It is intended for clients who receive specific layout
+  /// details rather than source code (such as LLDB). The client is expected
+  /// to fill in the field offsets, base offsets, virtual base offsets, and
+  /// complete object size.
+  ///
+  /// \param Record The record whose layout is being requested.
+  ///
+  /// \param Size The final size of the record, in bits.
+  ///
+  /// \param Alignment The final alignment of the record, in bits.
+  ///
+  /// \param FieldOffsets The offset of each of the fields within the record,
+  /// expressed in bits. All of the fields must be provided with offsets.
+  ///
+  /// \param BaseOffsets The offset of each of the direct, non-virtual base
+  /// classes. If any bases are not given offsets, the bases will be laid 
+  /// out according to the ABI.
+  ///
+  /// \param VirtualBaseOffsets The offset of each of the virtual base classes
+  /// (either direct or not). If any bases are not given offsets, the bases will 
+  /// be laid out according to the ABI.
+  /// 
+  /// \returns true if the record layout was provided, false otherwise.
+  bool
+  layoutRecordType(const RecordDecl *Record,
+                   uint64_t &Size, uint64_t &Alignment,
+                   llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+                 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+                 llvm::DenseMap<const CXXRecordDecl *,
+                                CharUnits> &VirtualBaseOffsets) override;
+
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
+
+  //===--------------------------------------------------------------------===//
+  // ExternalSemaSource.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Initialize the semantic source with the Sema instance
+  /// being used to perform semantic analysis on the abstract syntax
+  /// tree.
+  void InitializeSema(Sema &S) override;
+
+  /// \brief Inform the semantic consumer that Sema is no longer available.
+  void ForgetSema() override;
+
+  /// \brief Load the contents of the global method pool for a given
+  /// selector.
+  void ReadMethodPool(Selector Sel) override;
+
+  /// \brief Load the set of namespaces that are known to the external source,
+  /// which will be used during typo correction.
+  void
+  ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces) override;
+
+  /// \brief Load the set of used but not defined functions or variables with
+  /// internal linkage, or used but not defined inline functions.
+  void ReadUndefinedButUsed(
+                llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override;
+
+  /// \brief Do last resort, unqualified lookup on a LookupResult that
+  /// Sema cannot find.
+  ///
+  /// \param R a LookupResult that is being recovered.
+  ///
+  /// \param S the Scope of the identifier occurrence.
+  ///
+  /// \return true to tell Sema to recover using the LookupResult.
+  bool LookupUnqualified(LookupResult &R, Scope *S) override;
+
+  /// \brief Read the set of tentative definitions known to the external Sema
+  /// source.
+  ///
+  /// The external source should append its own tentative definitions to the
+  /// given vector of tentative definitions. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override;
+
+  /// \brief Read the set of unused file-scope declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own unused, filed-scope to the
+  /// given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  void ReadUnusedFileScopedDecls(
+                        SmallVectorImpl<const DeclaratorDecl*> &Decls) override;
+
+  /// \brief Read the set of delegating constructors known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own delegating constructors to the
+  /// given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  void ReadDelegatingConstructors(
+                          SmallVectorImpl<CXXConstructorDecl*> &Decls) override;
+
+  /// \brief Read the set of ext_vector type declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own ext_vector type declarations to
+  /// the given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
+
+  /// \brief Read the set of dynamic classes known to the external Sema source.
+  ///
+  /// The external source should append its own dynamic classes to
+  /// the given vector of declarations. Note that this routine may be
+  /// invoked multiple times; the external source should take care not to
+  /// introduce the same declarations repeatedly.
+  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override;
+
+  /// \brief Read the set of locally-scoped extern "C" declarations known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own locally-scoped external
+  /// declarations to the given vector of declarations. Note that this routine
+  /// may be invoked multiple times; the external source should take care not
+  /// to introduce the same declarations repeatedly.
+  void ReadLocallyScopedExternCDecls(
+                                   SmallVectorImpl<NamedDecl*> &Decls) override;
+
+  /// \brief Read the set of referenced selectors known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own referenced selectors to the 
+  /// given vector of selectors. Note that this routine 
+  /// may be invoked multiple times; the external source should take care not 
+  /// to introduce the same selectors repeatedly.
+  void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
+                                              SourceLocation> > &Sels) override;
+
+  /// \brief Read the set of weak, undeclared identifiers known to the
+  /// external Sema source.
+  ///
+  /// The external source should append its own weak, undeclared identifiers to
+  /// the given vector. Note that this routine may be invoked multiple times; 
+  /// the external source should take care not to introduce the same identifiers
+  /// repeatedly.
+  void ReadWeakUndeclaredIdentifiers(
+           SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override;
+
+  /// \brief Read the set of used vtables known to the external Sema source.
+  ///
+  /// The external source should append its own used vtables to the given
+  /// vector. Note that this routine may be invoked multiple times; the external
+  /// source should take care not to introduce the same vtables repeatedly.
+  void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
+
+  /// \brief Read the set of pending instantiations known to the external
+  /// Sema source.
+  ///
+  /// The external source should append its own pending instantiations to the
+  /// given vector. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same instantiations
+  /// repeatedly.
+  void ReadPendingInstantiations(
+     SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
+
+  /// \brief Read the set of late parsed template functions for this source.
+  ///
+  /// The external source should insert its own late parsed template functions
+  /// into the map. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same map entries
+  /// repeatedly.
+  void ReadLateParsedTemplates(
+                         llvm::DenseMap<const FunctionDecl *,
+                                        LateParsedTemplate *> &LPTMap) override;
+
+  /// \copydoc ExternalSemaSource::CorrectTypo
+  /// \note Returns the first nonempty correction.
+  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
+                             int LookupKind, Scope *S, CXXScopeSpec *SS,
+                             CorrectionCandidateCallback &CCC,
+                             DeclContext *MemberContext,
+                             bool EnteringContext,
+                             const ObjCObjectPointerType *OPT) override;
+
+  /// \brief Produces a diagnostic note if one of the attached sources
+  /// contains a complete definition for \p T. Queries the sources in list
+  /// order until the first one claims that a diagnostic was produced.
+  ///
+  /// \param Loc the location at which a complete type was required but not
+  /// provided
+  ///
+  /// \param T the \c QualType that should have been complete at \p Loc
+  ///
+  /// \return true if a diagnostic was produced, false otherwise.
+  bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
+                                        QualType T) override;
+
+  // isa/cast/dyn_cast support
+  static bool classof(const MultiplexExternalSemaSource*) { return true; }
+  //static bool classof(const ExternalSemaSource*) { return true; }
+}; 
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
new file mode 100644
index 0000000..2003356
--- /dev/null
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -0,0 +1,41 @@
+//===--- ObjCMethodList.h - A singly linked list of methods -----*- 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 ObjCMethodList, a singly-linked list of methods.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
+#define LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H
+
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+class ObjCMethodDecl;
+
+/// ObjCMethodList - a linked list of methods with different signatures.
+struct ObjCMethodList {
+  ObjCMethodDecl *Method;
+  /// \brief The next list object and 2 bits for extra info.
+  llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
+
+  ObjCMethodList() : Method(nullptr) { }
+  ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C)
+    : Method(M), NextAndExtraBits(C, 0) { }
+
+  ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); }
+  unsigned getBits() const { return NextAndExtraBits.getInt(); }
+  void setNext(ObjCMethodList *L) { NextAndExtraBits.setPointer(L); }
+  void setBits(unsigned B) { NextAndExtraBits.setInt(B); }
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
new file mode 100644
index 0000000..7c221a2
--- /dev/null
+++ b/include/clang/Sema/Overload.h
@@ -0,0 +1,798 @@
+//===--- Overload.h - C++ Overloading ---------------------------*- 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 data structures and types used in C++
+// overload resolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
+#define LLVM_CLANG_SEMA_OVERLOAD_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Sema/SemaFixItUtils.h"
+#include "clang/Sema/TemplateDeduction.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+  class ASTContext;
+  class CXXConstructorDecl;
+  class CXXConversionDecl;
+  class FunctionDecl;
+  class Sema;
+
+  /// OverloadingResult - Capture the result of performing overload
+  /// resolution.
+  enum OverloadingResult {
+    OR_Success,             ///< Overload resolution succeeded.
+    OR_No_Viable_Function,  ///< No viable function found.
+    OR_Ambiguous,           ///< Ambiguous candidates found.
+    OR_Deleted              ///< Succeeded, but refers to a deleted function.
+  };
+  
+  enum OverloadCandidateDisplayKind {
+    /// Requests that all candidates be shown.  Viable candidates will
+    /// be printed first.
+    OCD_AllCandidates,
+
+    /// Requests that only viable candidates be shown.
+    OCD_ViableCandidates
+  };
+
+  /// ImplicitConversionKind - The kind of implicit conversion used to
+  /// convert an argument to a parameter's type. The enumerator values
+  /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
+  /// better conversion kinds have smaller values.
+  enum ImplicitConversionKind {
+    ICK_Identity = 0,          ///< Identity conversion (no conversion)
+    ICK_Lvalue_To_Rvalue,      ///< Lvalue-to-rvalue conversion (C++ 4.1)
+    ICK_Array_To_Pointer,      ///< Array-to-pointer conversion (C++ 4.2)
+    ICK_Function_To_Pointer,   ///< Function-to-pointer (C++ 4.3)
+    ICK_NoReturn_Adjustment,   ///< Removal of noreturn from a type (Clang)
+    ICK_Qualification,         ///< Qualification conversions (C++ 4.4)
+    ICK_Integral_Promotion,    ///< Integral promotions (C++ 4.5)
+    ICK_Floating_Promotion,    ///< Floating point promotions (C++ 4.6)
+    ICK_Complex_Promotion,     ///< Complex promotions (Clang extension)
+    ICK_Integral_Conversion,   ///< Integral conversions (C++ 4.7)
+    ICK_Floating_Conversion,   ///< Floating point conversions (C++ 4.8)
+    ICK_Complex_Conversion,    ///< Complex conversions (C99 6.3.1.6)
+    ICK_Floating_Integral,     ///< Floating-integral conversions (C++ 4.9)
+    ICK_Pointer_Conversion,    ///< Pointer conversions (C++ 4.10)
+    ICK_Pointer_Member,        ///< Pointer-to-member conversions (C++ 4.11)
+    ICK_Boolean_Conversion,    ///< Boolean conversions (C++ 4.12)
+    ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
+    ICK_Derived_To_Base,       ///< Derived-to-base (C++ [over.best.ics])
+    ICK_Vector_Conversion,     ///< Vector conversions
+    ICK_Vector_Splat,          ///< A vector splat from an arithmetic type
+    ICK_Complex_Real,          ///< Complex-real conversions (C99 6.3.1.7)
+    ICK_Block_Pointer_Conversion,    ///< Block Pointer conversions 
+    ICK_TransparentUnionConversion, ///< Transparent Union Conversions
+    ICK_Writeback_Conversion,  ///< Objective-C ARC writeback conversion
+    ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
+    ICK_Num_Conversion_Kinds   ///< The number of conversion kinds
+  };
+
+  /// ImplicitConversionCategory - The category of an implicit
+  /// conversion kind. The enumerator values match with Table 9 of
+  /// (C++ 13.3.3.1.1) and are listed such that better conversion
+  /// categories have smaller values.
+  enum ImplicitConversionCategory {
+    ICC_Identity = 0,              ///< Identity
+    ICC_Lvalue_Transformation,     ///< Lvalue transformation
+    ICC_Qualification_Adjustment,  ///< Qualification adjustment
+    ICC_Promotion,                 ///< Promotion
+    ICC_Conversion                 ///< Conversion
+  };
+
+  ImplicitConversionCategory
+  GetConversionCategory(ImplicitConversionKind Kind);
+
+  /// ImplicitConversionRank - The rank of an implicit conversion
+  /// kind. The enumerator values match with Table 9 of (C++
+  /// 13.3.3.1.1) and are listed such that better conversion ranks
+  /// have smaller values.
+  enum ImplicitConversionRank {
+    ICR_Exact_Match = 0,         ///< Exact Match
+    ICR_Promotion,               ///< Promotion
+    ICR_Conversion,              ///< Conversion
+    ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion
+    ICR_Writeback_Conversion     ///< ObjC ARC writeback conversion
+  };
+
+  ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
+
+  /// NarrowingKind - The kind of narrowing conversion being performed by a
+  /// standard conversion sequence according to C++11 [dcl.init.list]p7.
+  enum NarrowingKind {
+    /// Not a narrowing conversion.
+    NK_Not_Narrowing,
+
+    /// A narrowing conversion by virtue of the source and destination types.
+    NK_Type_Narrowing,
+
+    /// A narrowing conversion, because a constant expression got narrowed.
+    NK_Constant_Narrowing,
+
+    /// A narrowing conversion, because a non-constant-expression variable might
+    /// have got narrowed.
+    NK_Variable_Narrowing
+  };
+
+  /// StandardConversionSequence - represents a standard conversion
+  /// sequence (C++ 13.3.3.1.1). A standard conversion sequence
+  /// contains between zero and three conversions. If a particular
+  /// conversion is not needed, it will be set to the identity conversion
+  /// (ICK_Identity). Note that the three conversions are
+  /// specified as separate members (rather than in an array) so that
+  /// we can keep the size of a standard conversion sequence to a
+  /// single word.
+  class StandardConversionSequence {
+  public:
+    /// First -- The first conversion can be an lvalue-to-rvalue
+    /// conversion, array-to-pointer conversion, or
+    /// function-to-pointer conversion.
+    ImplicitConversionKind First : 8;
+
+    /// Second - The second conversion can be an integral promotion,
+    /// floating point promotion, integral conversion, floating point
+    /// conversion, floating-integral conversion, pointer conversion,
+    /// pointer-to-member conversion, or boolean conversion.
+    ImplicitConversionKind Second : 8;
+
+    /// Third - The third conversion can be a qualification conversion.
+    ImplicitConversionKind Third : 8;
+
+    /// \brief Whether this is the deprecated conversion of a
+    /// string literal to a pointer to non-const character data
+    /// (C++ 4.2p2).
+    unsigned DeprecatedStringLiteralToCharPtr : 1;
+
+    /// \brief Whether the qualification conversion involves a change in the
+    /// Objective-C lifetime (for automatic reference counting).
+    unsigned QualificationIncludesObjCLifetime : 1;
+    
+    /// IncompatibleObjC - Whether this is an Objective-C conversion
+    /// that we should warn about (if we actually use it).
+    unsigned IncompatibleObjC : 1;
+
+    /// ReferenceBinding - True when this is a reference binding
+    /// (C++ [over.ics.ref]).
+    unsigned ReferenceBinding : 1;
+
+    /// DirectBinding - True when this is a reference binding that is a
+    /// direct binding (C++ [dcl.init.ref]).
+    unsigned DirectBinding : 1;
+
+    /// \brief Whether this is an lvalue reference binding (otherwise, it's
+    /// an rvalue reference binding).
+    unsigned IsLvalueReference : 1;
+    
+    /// \brief Whether we're binding to a function lvalue.
+    unsigned BindsToFunctionLvalue : 1;
+    
+    /// \brief Whether we're binding to an rvalue.
+    unsigned BindsToRvalue : 1;
+    
+    /// \brief Whether this binds an implicit object argument to a 
+    /// non-static member function without a ref-qualifier.
+    unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1;
+    
+    /// \brief Whether this binds a reference to an object with a different
+    /// Objective-C lifetime qualifier.
+    unsigned ObjCLifetimeConversionBinding : 1;
+    
+    /// FromType - The type that this conversion is converting
+    /// from. This is an opaque pointer that can be translated into a
+    /// QualType.
+    void *FromTypePtr;
+
+    /// ToType - The types that this conversion is converting to in
+    /// each step. This is an opaque pointer that can be translated
+    /// into a QualType.
+    void *ToTypePtrs[3];
+
+    /// CopyConstructor - The copy constructor that is used to perform
+    /// this conversion, when the conversion is actually just the
+    /// initialization of an object via copy constructor. Such
+    /// conversions are either identity conversions or derived-to-base
+    /// conversions.
+    CXXConstructorDecl *CopyConstructor;
+
+    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+    void setToType(unsigned Idx, QualType T) { 
+      assert(Idx < 3 && "To type index is out of range");
+      ToTypePtrs[Idx] = T.getAsOpaquePtr(); 
+    }
+    void setAllToTypes(QualType T) {
+      ToTypePtrs[0] = T.getAsOpaquePtr(); 
+      ToTypePtrs[1] = ToTypePtrs[0];
+      ToTypePtrs[2] = ToTypePtrs[0];
+    }
+
+    QualType getFromType() const {
+      return QualType::getFromOpaquePtr(FromTypePtr);
+    }
+    QualType getToType(unsigned Idx) const {
+      assert(Idx < 3 && "To type index is out of range");
+      return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
+    }
+
+    void setAsIdentityConversion();
+    
+    bool isIdentityConversion() const {
+      return Second == ICK_Identity && Third == ICK_Identity;
+    }
+    
+    ImplicitConversionRank getRank() const;
+    NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted,
+                                   APValue &ConstantValue,
+                                   QualType &ConstantType) const;
+    bool isPointerConversionToBool() const;
+    bool isPointerConversionToVoidPointer(ASTContext& Context) const;
+    void dump() const;
+  };
+
+  /// UserDefinedConversionSequence - Represents a user-defined
+  /// conversion sequence (C++ 13.3.3.1.2).
+  struct UserDefinedConversionSequence {
+    /// \brief Represents the standard conversion that occurs before
+    /// the actual user-defined conversion.
+    ///
+    /// C++11 13.3.3.1.2p1:
+    ///   If the user-defined conversion is specified by a constructor
+    ///   (12.3.1), the initial standard conversion sequence converts
+    ///   the source type to the type required by the argument of the
+    ///   constructor. If the user-defined conversion is specified by
+    ///   a conversion function (12.3.2), the initial standard
+    ///   conversion sequence converts the source type to the implicit
+    ///   object parameter of the conversion function.
+    StandardConversionSequence Before;
+
+    /// EllipsisConversion - When this is true, it means user-defined
+    /// conversion sequence starts with a ... (ellipsis) conversion, instead of
+    /// a standard conversion. In this case, 'Before' field must be ignored.
+    // FIXME. I much rather put this as the first field. But there seems to be
+    // a gcc code gen. bug which causes a crash in a test. Putting it here seems
+    // to work around the crash.
+    bool EllipsisConversion : 1;
+
+    /// HadMultipleCandidates - When this is true, it means that the
+    /// conversion function was resolved from an overloaded set having
+    /// size greater than 1.
+    bool HadMultipleCandidates : 1;
+
+    /// After - Represents the standard conversion that occurs after
+    /// the actual user-defined conversion.
+    StandardConversionSequence After;
+
+    /// ConversionFunction - The function that will perform the
+    /// user-defined conversion. Null if the conversion is an
+    /// aggregate initialization from an initializer list.
+    FunctionDecl* ConversionFunction;
+
+    /// \brief The declaration that we found via name lookup, which might be
+    /// the same as \c ConversionFunction or it might be a using declaration
+    /// that refers to \c ConversionFunction.
+    DeclAccessPair FoundConversionFunction;
+
+    void dump() const;
+  };
+
+  /// Represents an ambiguous user-defined conversion sequence.
+  struct AmbiguousConversionSequence {
+    typedef SmallVector<FunctionDecl*, 4> ConversionSet;
+
+    void *FromTypePtr;
+    void *ToTypePtr;
+    char Buffer[sizeof(ConversionSet)];
+
+    QualType getFromType() const {
+      return QualType::getFromOpaquePtr(FromTypePtr);
+    }
+    QualType getToType() const {
+      return QualType::getFromOpaquePtr(ToTypePtr);
+    }
+    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+    void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
+
+    ConversionSet &conversions() {
+      return *reinterpret_cast<ConversionSet*>(Buffer);
+    }
+
+    const ConversionSet &conversions() const {
+      return *reinterpret_cast<const ConversionSet*>(Buffer);
+    }
+
+    void addConversion(FunctionDecl *D) {
+      conversions().push_back(D);
+    }
+
+    typedef ConversionSet::iterator iterator;
+    iterator begin() { return conversions().begin(); }
+    iterator end() { return conversions().end(); }
+
+    typedef ConversionSet::const_iterator const_iterator;
+    const_iterator begin() const { return conversions().begin(); }
+    const_iterator end() const { return conversions().end(); }
+
+    void construct();
+    void destruct();
+    void copyFrom(const AmbiguousConversionSequence &);
+  };
+
+  /// BadConversionSequence - Records information about an invalid
+  /// conversion sequence.
+  struct BadConversionSequence {
+    enum FailureKind {
+      no_conversion,
+      unrelated_class,
+      bad_qualifiers,
+      lvalue_ref_to_rvalue,
+      rvalue_ref_to_lvalue
+    };
+
+    // This can be null, e.g. for implicit object arguments.
+    Expr *FromExpr;
+
+    FailureKind Kind;
+
+  private:
+    // The type we're converting from (an opaque QualType).
+    void *FromTy;
+
+    // The type we're converting to (an opaque QualType).
+    void *ToTy;
+
+  public:
+    void init(FailureKind K, Expr *From, QualType To) {
+      init(K, From->getType(), To);
+      FromExpr = From;
+    }
+    void init(FailureKind K, QualType From, QualType To) {
+      Kind = K;
+      FromExpr = nullptr;
+      setFromType(From);
+      setToType(To);
+    }
+
+    QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); }
+    QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); }
+
+    void setFromExpr(Expr *E) {
+      FromExpr = E;
+      setFromType(E->getType());
+    }
+    void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
+    void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
+  };
+
+  /// ImplicitConversionSequence - Represents an implicit conversion
+  /// sequence, which may be a standard conversion sequence
+  /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
+  /// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
+  class ImplicitConversionSequence {
+  public:
+    /// Kind - The kind of implicit conversion sequence. BadConversion
+    /// specifies that there is no conversion from the source type to
+    /// the target type.  AmbiguousConversion represents the unique
+    /// ambiguous conversion (C++0x [over.best.ics]p10).
+    enum Kind {
+      StandardConversion = 0,
+      UserDefinedConversion,
+      AmbiguousConversion,
+      EllipsisConversion,
+      BadConversion
+    };
+
+  private:
+    enum {
+      Uninitialized = BadConversion + 1
+    };
+
+    /// ConversionKind - The kind of implicit conversion sequence.
+    unsigned ConversionKind : 30;
+
+    /// \brief Whether the target is really a std::initializer_list, and the
+    /// sequence only represents the worst element conversion.
+    bool StdInitializerListElement : 1;
+
+    void setKind(Kind K) {
+      destruct();
+      ConversionKind = K;
+    }
+
+    void destruct() {
+      if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
+    }
+
+  public:
+    union {
+      /// When ConversionKind == StandardConversion, provides the
+      /// details of the standard conversion sequence.
+      StandardConversionSequence Standard;
+
+      /// When ConversionKind == UserDefinedConversion, provides the
+      /// details of the user-defined conversion sequence.
+      UserDefinedConversionSequence UserDefined;
+
+      /// When ConversionKind == AmbiguousConversion, provides the
+      /// details of the ambiguous conversion.
+      AmbiguousConversionSequence Ambiguous;
+
+      /// When ConversionKind == BadConversion, provides the details
+      /// of the bad conversion.
+      BadConversionSequence Bad;
+    };
+
+    ImplicitConversionSequence()
+      : ConversionKind(Uninitialized), StdInitializerListElement(false)
+    {}
+    ~ImplicitConversionSequence() {
+      destruct();
+    }
+    ImplicitConversionSequence(const ImplicitConversionSequence &Other)
+      : ConversionKind(Other.ConversionKind),
+        StdInitializerListElement(Other.StdInitializerListElement)
+    {
+      switch (ConversionKind) {
+      case Uninitialized: break;
+      case StandardConversion: Standard = Other.Standard; break;
+      case UserDefinedConversion: UserDefined = Other.UserDefined; break;
+      case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
+      case EllipsisConversion: break;
+      case BadConversion: Bad = Other.Bad; break;
+      }
+    }
+
+    ImplicitConversionSequence &
+        operator=(const ImplicitConversionSequence &Other) {
+      destruct();
+      new (this) ImplicitConversionSequence(Other);
+      return *this;
+    }
+    
+    Kind getKind() const {
+      assert(isInitialized() && "querying uninitialized conversion");
+      return Kind(ConversionKind);
+    }
+    
+    /// \brief Return a ranking of the implicit conversion sequence
+    /// kind, where smaller ranks represent better conversion
+    /// sequences.
+    ///
+    /// In particular, this routine gives user-defined conversion
+    /// sequences and ambiguous conversion sequences the same rank,
+    /// per C++ [over.best.ics]p10.
+    unsigned getKindRank() const {
+      switch (getKind()) {
+      case StandardConversion: 
+        return 0;
+
+      case UserDefinedConversion:
+      case AmbiguousConversion: 
+        return 1;
+
+      case EllipsisConversion:
+        return 2;
+
+      case BadConversion:
+        return 3;
+      }
+
+      llvm_unreachable("Invalid ImplicitConversionSequence::Kind!");
+    }
+
+    bool isBad() const { return getKind() == BadConversion; }
+    bool isStandard() const { return getKind() == StandardConversion; }
+    bool isEllipsis() const { return getKind() == EllipsisConversion; }
+    bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
+    bool isUserDefined() const { return getKind() == UserDefinedConversion; }
+    bool isFailure() const { return isBad() || isAmbiguous(); }
+
+    /// Determines whether this conversion sequence has been
+    /// initialized.  Most operations should never need to query
+    /// uninitialized conversions and should assert as above.
+    bool isInitialized() const { return ConversionKind != Uninitialized; }
+
+    /// Sets this sequence as a bad conversion for an explicit argument.
+    void setBad(BadConversionSequence::FailureKind Failure,
+                Expr *FromExpr, QualType ToType) {
+      setKind(BadConversion);
+      Bad.init(Failure, FromExpr, ToType);
+    }
+
+    /// Sets this sequence as a bad conversion for an implicit argument.
+    void setBad(BadConversionSequence::FailureKind Failure,
+                QualType FromType, QualType ToType) {
+      setKind(BadConversion);
+      Bad.init(Failure, FromType, ToType);
+    }
+
+    void setStandard() { setKind(StandardConversion); }
+    void setEllipsis() { setKind(EllipsisConversion); }
+    void setUserDefined() { setKind(UserDefinedConversion); }
+    void setAmbiguous() {
+      if (ConversionKind == AmbiguousConversion) return;
+      ConversionKind = AmbiguousConversion;
+      Ambiguous.construct();
+    }
+
+    /// \brief Whether the target is really a std::initializer_list, and the
+    /// sequence only represents the worst element conversion.
+    bool isStdInitializerListElement() const {
+      return StdInitializerListElement;
+    }
+
+    void setStdInitializerListElement(bool V = true) {
+      StdInitializerListElement = V;
+    }
+
+    // The result of a comparison between implicit conversion
+    // sequences. Use Sema::CompareImplicitConversionSequences to
+    // actually perform the comparison.
+    enum CompareKind {
+      Better = -1,
+      Indistinguishable = 0,
+      Worse = 1
+    };
+
+    void DiagnoseAmbiguousConversion(Sema &S,
+                                     SourceLocation CaretLoc,
+                                     const PartialDiagnostic &PDiag) const;
+
+    void dump() const;
+  };
+
+  enum OverloadFailureKind {
+    ovl_fail_too_many_arguments,
+    ovl_fail_too_few_arguments,
+    ovl_fail_bad_conversion,
+    ovl_fail_bad_deduction,
+
+    /// This conversion candidate was not considered because it
+    /// duplicates the work of a trivial or derived-to-base
+    /// conversion.
+    ovl_fail_trivial_conversion,
+
+    /// This conversion candidate is not viable because its result
+    /// type is not implicitly convertible to the desired type.
+    ovl_fail_bad_final_conversion,
+    
+    /// This conversion function template specialization candidate is not 
+    /// viable because the final conversion was not an exact match.
+    ovl_fail_final_conversion_not_exact,
+
+    /// (CUDA) This candidate was not viable because the callee
+    /// was not accessible from the caller's target (i.e. host->device,
+    /// global->host, device->host).
+    ovl_fail_bad_target,
+
+    /// This candidate function was not viable because an enable_if
+    /// attribute disabled it.
+    ovl_fail_enable_if
+  };
+
+  /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
+  struct OverloadCandidate {
+    /// Function - The actual function that this candidate
+    /// represents. When NULL, this is a built-in candidate
+    /// (C++ [over.oper]) or a surrogate for a conversion to a
+    /// function pointer or reference (C++ [over.call.object]).
+    FunctionDecl *Function;
+
+    /// FoundDecl - The original declaration that was looked up /
+    /// invented / otherwise found, together with its access.
+    /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
+    DeclAccessPair FoundDecl;
+
+    // BuiltinTypes - Provides the return and parameter types of a
+    // built-in overload candidate. Only valid when Function is NULL.
+    struct {
+      QualType ResultTy;
+      QualType ParamTypes[3];
+    } BuiltinTypes;
+
+    /// Surrogate - The conversion function for which this candidate
+    /// is a surrogate, but only if IsSurrogate is true.
+    CXXConversionDecl *Surrogate;
+
+    /// Conversions - The conversion sequences used to convert the
+    /// function arguments to the function parameters, the pointer points to a
+    /// fixed size array with NumConversions elements. The memory is owned by
+    /// the OverloadCandidateSet.
+    ImplicitConversionSequence *Conversions;
+
+    /// The FixIt hints which can be used to fix the Bad candidate.
+    ConversionFixItGenerator Fix;
+
+    /// NumConversions - The number of elements in the Conversions array.
+    unsigned NumConversions;
+
+    /// Viable - True to indicate that this overload candidate is viable.
+    bool Viable;
+
+    /// IsSurrogate - True to indicate that this candidate is a
+    /// surrogate for a conversion to a function pointer or reference
+    /// (C++ [over.call.object]).
+    bool IsSurrogate;
+
+    /// IgnoreObjectArgument - True to indicate that the first
+    /// argument's conversion, which for this function represents the
+    /// implicit object argument, should be ignored. This will be true
+    /// when the candidate is a static member function (where the
+    /// implicit object argument is just a placeholder) or a
+    /// non-static member function when the call doesn't have an
+    /// object argument.
+    bool IgnoreObjectArgument;
+
+    /// FailureKind - The reason why this candidate is not viable.
+    /// Actually an OverloadFailureKind.
+    unsigned char FailureKind;
+
+    /// \brief The number of call arguments that were explicitly provided,
+    /// to be used while performing partial ordering of function templates.
+    unsigned ExplicitCallArguments;
+
+    union {
+      DeductionFailureInfo DeductionFailure;
+      
+      /// FinalConversion - For a conversion function (where Function is
+      /// a CXXConversionDecl), the standard conversion that occurs
+      /// after the call to the overload candidate to convert the result
+      /// of calling the conversion function to the required type.
+      StandardConversionSequence FinalConversion;
+    };
+
+    /// hasAmbiguousConversion - Returns whether this overload
+    /// candidate requires an ambiguous conversion or not.
+    bool hasAmbiguousConversion() const {
+      for (unsigned i = 0, e = NumConversions; i != e; ++i) {
+        if (!Conversions[i].isInitialized()) return false;
+        if (Conversions[i].isAmbiguous()) return true;
+      }
+      return false;
+    }
+
+    bool TryToFixBadConversion(unsigned Idx, Sema &S) {
+      bool CanFix = Fix.tryToFixConversion(
+                      Conversions[Idx].Bad.FromExpr,
+                      Conversions[Idx].Bad.getFromType(),
+                      Conversions[Idx].Bad.getToType(), S);
+
+      // If at least one conversion fails, the candidate cannot be fixed.
+      if (!CanFix)
+        Fix.clear();
+
+      return CanFix;
+    }
+
+    unsigned getNumParams() const {
+      if (IsSurrogate) {
+        auto STy = Surrogate->getConversionType();
+        while (STy->isPointerType() || STy->isReferenceType())
+          STy = STy->getPointeeType();
+        return STy->getAs<FunctionProtoType>()->getNumParams();
+      }
+      if (Function)
+        return Function->getNumParams();
+      return ExplicitCallArguments;
+    }
+  };
+
+  /// OverloadCandidateSet - A set of overload candidates, used in C++
+  /// overload resolution (C++ 13.3).
+  class OverloadCandidateSet {
+  public:
+    enum CandidateSetKind {
+      /// Normal lookup.
+      CSK_Normal,
+      /// Lookup for candidates for a call using operator syntax. Candidates
+      /// that have no parameters of class type will be skipped unless there
+      /// is a parameter of (reference to) enum type and the corresponding
+      /// argument is of the same enum type.
+      CSK_Operator
+    };
+
+  private:
+    SmallVector<OverloadCandidate, 16> Candidates;
+    llvm::SmallPtrSet<Decl *, 16> Functions;
+
+    // Allocator for OverloadCandidate::Conversions. We store the first few
+    // elements inline to avoid allocation for small sets.
+    llvm::BumpPtrAllocator ConversionSequenceAllocator;
+
+    SourceLocation Loc;
+    CandidateSetKind Kind;
+
+    unsigned NumInlineSequences;
+    char InlineSpace[16 * sizeof(ImplicitConversionSequence)];
+
+    OverloadCandidateSet(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION;
+    void operator=(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION;
+
+    void destroyCandidates();
+
+  public:
+    OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
+        : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
+    ~OverloadCandidateSet() { destroyCandidates(); }
+
+    SourceLocation getLocation() const { return Loc; }
+    CandidateSetKind getKind() const { return Kind; }
+
+    /// \brief Determine when this overload candidate will be new to the
+    /// overload set.
+    bool isNewCandidate(Decl *F) { 
+      return Functions.insert(F->getCanonicalDecl()); 
+    }
+
+    /// \brief Clear out all of the candidates.
+    void clear();
+
+    typedef SmallVectorImpl<OverloadCandidate>::iterator iterator;
+    iterator begin() { return Candidates.begin(); }
+    iterator end() { return Candidates.end(); }
+
+    size_t size() const { return Candidates.size(); }
+    bool empty() const { return Candidates.empty(); }
+
+    /// \brief Add a new candidate with NumConversions conversion sequence slots
+    /// to the overload set.
+    OverloadCandidate &addCandidate(unsigned NumConversions = 0) {
+      Candidates.push_back(OverloadCandidate());
+      OverloadCandidate &C = Candidates.back();
+
+      // Assign space from the inline array if there are enough free slots
+      // available.
+      if (NumConversions + NumInlineSequences <= 16) {
+        ImplicitConversionSequence *I =
+          (ImplicitConversionSequence*)InlineSpace;
+        C.Conversions = &I[NumInlineSequences];
+        NumInlineSequences += NumConversions;
+      } else {
+        // Otherwise get memory from the allocator.
+        C.Conversions = ConversionSequenceAllocator
+                          .Allocate<ImplicitConversionSequence>(NumConversions);
+      }
+
+      // Construct the new objects.
+      for (unsigned i = 0; i != NumConversions; ++i)
+        new (&C.Conversions[i]) ImplicitConversionSequence();
+
+      C.NumConversions = NumConversions;
+      return C;
+    }
+
+    /// Find the best viable function on this overload set, if it exists.
+    OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
+                                         OverloadCandidateSet::iterator& Best,
+                                         bool UserDefinedConversion = false);
+
+    void NoteCandidates(Sema &S,
+                        OverloadCandidateDisplayKind OCD,
+                        ArrayRef<Expr *> Args,
+                        StringRef Opc = "",
+                        SourceLocation Loc = SourceLocation());
+  };
+
+  bool isBetterOverloadCandidate(Sema &S,
+                                 const OverloadCandidate& Cand1,
+                                 const OverloadCandidate& Cand2,
+                                 SourceLocation Loc,
+                                 bool UserDefinedConversion = false);
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
new file mode 100644
index 0000000..8031562
--- /dev/null
+++ b/include/clang/Sema/Ownership.h
@@ -0,0 +1,287 @@
+//===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file contains classes for managing ownership of Stmt and Expr nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_OWNERSHIP_H
+#define LLVM_CLANG_SEMA_OWNERSHIP_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+//===----------------------------------------------------------------------===//
+// OpaquePtr
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+  class CXXCtorInitializer;
+  class CXXBaseSpecifier;
+  class Decl;
+  class Expr;
+  class ParsedTemplateArgument;
+  class QualType;
+  class Stmt;
+  class TemplateName;
+  class TemplateParameterList;
+
+  /// \brief Wrapper for void* pointer.
+  /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
+  ///               a pointer.
+  ///
+  /// This is a very simple POD type that wraps a pointer that the Parser
+  /// doesn't know about but that Sema or another client does.  The PtrTy
+  /// template argument is used to make sure that "Decl" pointers are not
+  /// compatible with "Type" pointers for example.
+  template <class PtrTy>
+  class OpaquePtr {
+    void *Ptr;
+    explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {}
+
+    typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
+
+  public:
+    OpaquePtr() : Ptr(nullptr) {}
+
+    static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
+
+    /// \brief Returns plain pointer to the entity pointed by this wrapper.
+    /// \tparam PointeeT Type of pointed entity.
+    ///
+    /// It is identical to getPtrAs<PointeeT*>.
+    template <typename PointeeT> PointeeT* getPtrTo() const {
+      return get();
+    }
+
+    /// \brief Returns pointer converted to the specified type.
+    /// \tparam PtrT Result pointer type.  There must be implicit conversion
+    ///              from PtrTy to PtrT.
+    ///
+    /// In contrast to getPtrTo, this method allows the return type to be
+    /// a smart pointer.
+    template <typename PtrT> PtrT getPtrAs() const {
+      return get();
+    }
+
+    PtrTy get() const {
+      return Traits::getFromVoidPointer(Ptr);
+    }
+
+    void set(PtrTy P) {
+      Ptr = Traits::getAsVoidPointer(P);
+    }
+
+    LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
+
+    void *getAsOpaquePtr() const { return Ptr; }
+    static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
+  };
+
+  /// UnionOpaquePtr - A version of OpaquePtr suitable for membership
+  /// in a union.
+  template <class T> struct UnionOpaquePtr {
+    void *Ptr;
+
+    static UnionOpaquePtr make(OpaquePtr<T> P) {
+      UnionOpaquePtr OP = { P.getAsOpaquePtr() };
+      return OP;
+    }
+
+    OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); }
+    operator OpaquePtr<T>() const { return get(); }
+
+    UnionOpaquePtr &operator=(OpaquePtr<T> P) {
+      Ptr = P.getAsOpaquePtr();
+      return *this;
+    }
+  };
+}
+
+namespace llvm {
+  template <class T>
+  class PointerLikeTypeTraits<clang::OpaquePtr<T> > {
+  public:
+    static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) {
+      // FIXME: Doesn't work? return P.getAs< void >();
+      return P.getAsOpaquePtr();
+    }
+    static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) {
+      return clang::OpaquePtr<T>::getFromOpaquePtr(P);
+    }
+    enum { NumLowBitsAvailable = 0 };
+  };
+
+  template <class T>
+  struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; };
+}
+
+namespace clang {
+  // Basic
+  class DiagnosticBuilder;
+
+  // Determines whether the low bit of the result pointer for the
+  // given UID is always zero. If so, ActionResult will use that bit
+  // for it's "invalid" flag.
+  template<class Ptr>
+  struct IsResultPtrLowBitFree {
+    static const bool value = false;
+  };
+
+  /// ActionResult - This structure is used while parsing/acting on
+  /// expressions, stmts, etc.  It encapsulates both the object returned by
+  /// the action, plus a sense of whether or not it is valid.
+  /// When CompressInvalid is true, the "invalid" flag will be
+  /// stored in the low bit of the Val pointer.
+  template<class PtrTy,
+           bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
+  class ActionResult {
+    PtrTy Val;
+    bool Invalid;
+
+  public:
+    ActionResult(bool Invalid = false)
+      : Val(PtrTy()), Invalid(Invalid) {}
+    ActionResult(PtrTy val) : Val(val), Invalid(false) {}
+    ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
+
+    // These two overloads prevent void* -> bool conversions.
+    ActionResult(const void *);
+    ActionResult(volatile void *);
+
+    bool isInvalid() const { return Invalid; }
+    bool isUsable() const { return !Invalid && Val; }
+    bool isUnset() const { return !Invalid && !Val; }
+
+    PtrTy get() const { return Val; }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
+
+    void set(PtrTy V) { Val = V; }
+
+    const ActionResult &operator=(PtrTy RHS) {
+      Val = RHS;
+      Invalid = false;
+      return *this;
+    }
+  };
+
+  // This ActionResult partial specialization places the "invalid"
+  // flag into the low bit of the pointer.
+  template<typename PtrTy>
+  class ActionResult<PtrTy, true> {
+    // A pointer whose low bit is 1 if this result is invalid, 0
+    // otherwise.
+    uintptr_t PtrWithInvalid;
+    typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits;
+  public:
+    ActionResult(bool Invalid = false)
+      : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { }
+
+    ActionResult(PtrTy V) {
+      void *VP = PtrTraits::getAsVoidPointer(V);
+      PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+      assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+    }
+    ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { }
+
+    // These two overloads prevent void* -> bool conversions.
+    ActionResult(const void *);
+    ActionResult(volatile void *);
+
+    bool isInvalid() const { return PtrWithInvalid & 0x01; }
+    bool isUsable() const { return PtrWithInvalid > 0x01; }
+    bool isUnset() const { return PtrWithInvalid == 0; }
+
+    PtrTy get() const {
+      void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
+      return PtrTraits::getFromVoidPointer(VP);
+    }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
+
+    void set(PtrTy V) {
+      void *VP = PtrTraits::getAsVoidPointer(V);
+      PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+      assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+    }
+
+    const ActionResult &operator=(PtrTy RHS) {
+      void *VP = PtrTraits::getAsVoidPointer(RHS);
+      PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
+      assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
+      return *this;
+    }
+
+    // For types where we can fit a flag in with the pointer, provide
+    // conversions to/from pointer type.
+    static ActionResult getFromOpaquePointer(void *P) {
+      ActionResult Result;
+      Result.PtrWithInvalid = (uintptr_t)P;
+      return Result;
+    }
+    void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; }
+  };
+
+  /// An opaque type for threading parsed type information through the
+  /// parser.
+  typedef OpaquePtr<QualType> ParsedType;
+  typedef UnionOpaquePtr<QualType> UnionParsedType;
+
+  // We can re-use the low bit of expression, statement, base, and
+  // member-initializer pointers for the "invalid" flag of
+  // ActionResult.
+  template<> struct IsResultPtrLowBitFree<Expr*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<Stmt*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
+    static const bool value = true;
+  };
+  template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> {
+    static const bool value = true;
+  };
+
+  typedef ActionResult<Expr*> ExprResult;
+  typedef ActionResult<Stmt*> StmtResult;
+  typedef ActionResult<ParsedType> TypeResult;
+  typedef ActionResult<CXXBaseSpecifier*> BaseResult;
+  typedef ActionResult<CXXCtorInitializer*> MemInitResult;
+
+  typedef ActionResult<Decl*> DeclResult;
+  typedef OpaquePtr<TemplateName> ParsedTemplateTy;
+
+  typedef MutableArrayRef<Expr*> MultiExprArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
+  typedef MutableArrayRef<ParsedType> MultiTypeArg;
+  typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
+
+  inline ExprResult ExprError() { return ExprResult(true); }
+  inline StmtResult StmtError() { return StmtResult(true); }
+
+  inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
+  inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
+
+  inline ExprResult ExprEmpty() { return ExprResult(false); }
+  inline StmtResult StmtEmpty() { return StmtResult(false); }
+
+  inline Expr *AssertSuccess(ExprResult R) {
+    assert(!R.isInvalid() && "operation was asserted to never fail!");
+    return R.get();
+  }
+
+  inline Stmt *AssertSuccess(StmtResult R) {
+    assert(!R.isInvalid() && "operation was asserted to never fail!");
+    return R.get();
+  }
+}
+
+#endif
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
new file mode 100644
index 0000000..b36425f
--- /dev/null
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -0,0 +1,214 @@
+//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides data structures that store the parsed representation of
+//  templates.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
+#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
+
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Ownership.h"
+#include <cassert>
+
+namespace clang {  
+  /// \brief Represents the parsed form of a C++ template argument.
+  class ParsedTemplateArgument {
+  public:
+    /// \brief Describes the kind of template argument that was parsed.
+    enum KindType {
+      /// \brief A template type parameter, stored as a type.
+      Type,
+      /// \brief A non-type template parameter, stored as an expression.
+      NonType,
+      /// \brief A template template argument, stored as a template name.
+      Template
+    };
+
+    /// \brief Build an empty template argument. 
+    ///
+    /// This template argument is invalid.
+    ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
+    
+    /// \brief Create a template type argument or non-type template argument.
+    ///
+    /// \param Arg the template type argument or non-type template argument.
+    /// \param Loc the location of the type.
+    ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
+      : Kind(Kind), Arg(Arg), Loc(Loc) { }
+    
+    /// \brief Create a template template argument.
+    ///
+    /// \param SS the C++ scope specifier that precedes the template name, if
+    /// any.
+    ///
+    /// \param Template the template to which this template template 
+    /// argument refers.
+    ///
+    /// \param TemplateLoc the location of the template name.
+    ParsedTemplateArgument(const CXXScopeSpec &SS,
+                           ParsedTemplateTy Template, 
+                           SourceLocation TemplateLoc) 
+      : Kind(ParsedTemplateArgument::Template),
+        Arg(Template.getAsOpaquePtr()), 
+        SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
+    
+    /// \brief Determine whether the given template argument is invalid.
+    bool isInvalid() const { return Arg == nullptr; }
+    
+    /// \brief Determine what kind of template argument we have.
+    KindType getKind() const { return Kind; }
+    
+    /// \brief Retrieve the template type argument's type.
+    ParsedType getAsType() const {
+      assert(Kind == Type && "Not a template type argument");
+      return ParsedType::getFromOpaquePtr(Arg);
+    }
+    
+    /// \brief Retrieve the non-type template argument's expression.
+    Expr *getAsExpr() const {
+      assert(Kind == NonType && "Not a non-type template argument");
+      return static_cast<Expr*>(Arg);
+    }
+    
+    /// \brief Retrieve the template template argument's template name.
+    ParsedTemplateTy getAsTemplate() const {
+      assert(Kind == Template && "Not a template template argument");
+      return ParsedTemplateTy::getFromOpaquePtr(Arg);
+    }
+    
+    /// \brief Retrieve the location of the template argument.
+    SourceLocation getLocation() const { return Loc; }
+    
+    /// \brief Retrieve the nested-name-specifier that precedes the template
+    /// name in a template template argument.
+    const CXXScopeSpec &getScopeSpec() const {
+      assert(Kind == Template && 
+             "Only template template arguments can have a scope specifier");
+      return SS;
+    }
+    
+    /// \brief Retrieve the location of the ellipsis that makes a template
+    /// template argument into a pack expansion.
+    SourceLocation getEllipsisLoc() const {
+      assert(Kind == Template && 
+             "Only template template arguments can have an ellipsis");
+      return EllipsisLoc;
+    }
+    
+    /// \brief Retrieve a pack expansion of the given template template
+    /// argument.
+    ///
+    /// \param EllipsisLoc The location of the ellipsis.
+    ParsedTemplateArgument getTemplatePackExpansion(
+                                              SourceLocation EllipsisLoc) const;
+    
+  private:
+    KindType Kind;
+    
+    /// \brief The actual template argument representation, which may be
+    /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
+    /// expression), or an ActionBase::TemplateTy (for a template).
+    void *Arg;
+
+    /// \brief The nested-name-specifier that can accompany a template template
+    /// argument.
+    CXXScopeSpec SS;
+
+    /// \brief the location of the template argument.
+    SourceLocation Loc;
+
+    /// \brief The ellipsis location that can accompany a template template
+    /// argument (turning it into a template template argument expansion).
+    SourceLocation EllipsisLoc;
+  };
+  
+  /// \brief Information about a template-id annotation
+  /// token.
+  ///
+  /// A template-id annotation token contains the template declaration, 
+  /// template arguments, whether those template arguments were types, 
+  /// expressions, or template names, and the source locations for important 
+  /// tokens. All of the information about template arguments is allocated 
+  /// directly after this structure.
+  struct TemplateIdAnnotation {
+    /// \brief The nested-name-specifier that precedes the template name.
+    CXXScopeSpec SS;
+
+    /// TemplateKWLoc - The location of the template keyword within the
+    /// source.
+    SourceLocation TemplateKWLoc;
+
+    /// TemplateNameLoc - The location of the template name within the
+    /// source.
+    SourceLocation TemplateNameLoc;
+    
+    /// FIXME: Temporarily stores the name of a specialization
+    IdentifierInfo *Name;
+    
+    /// FIXME: Temporarily stores the overloaded operator kind.
+    OverloadedOperatorKind Operator;
+    
+    /// The declaration of the template corresponding to the
+    /// template-name.
+    ParsedTemplateTy Template;
+    
+    /// The kind of template that Template refers to.
+    TemplateNameKind Kind;
+    
+    /// The location of the '<' before the template argument
+    /// list.
+    SourceLocation LAngleLoc;
+    
+    /// The location of the '>' after the template argument
+    /// list.
+    SourceLocation RAngleLoc;
+    
+    /// NumArgs - The number of template arguments.
+    unsigned NumArgs;
+    
+    /// \brief Retrieves a pointer to the template arguments
+    ParsedTemplateArgument *getTemplateArgs() { 
+      return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
+    }
+
+    /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
+    /// appends it to List.
+    static TemplateIdAnnotation *
+    Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
+      TemplateIdAnnotation *TemplateId
+        = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
+                                      sizeof(ParsedTemplateArgument) * NumArgs);
+      TemplateId->NumArgs = NumArgs;
+      
+      // Default-construct nested-name-specifier.
+      new (&TemplateId->SS) CXXScopeSpec();
+      
+      // Default-construct parsed template arguments.
+      ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
+      for (unsigned I = 0; I != NumArgs; ++I)
+        new (TemplateArgs + I) ParsedTemplateArgument();
+      
+      List.push_back(TemplateId);
+      return TemplateId;
+    }
+    
+    void Destroy() { 
+      SS.~CXXScopeSpec();
+      free(this); 
+    }
+  };
+
+  /// Retrieves the range of the given template parameter lists.
+  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
+                                     unsigned NumParams);  
+}
+
+#endif
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
new file mode 100644
index 0000000..c0c772d
--- /dev/null
+++ b/include/clang/Sema/PrettyDeclStackTrace.h
@@ -0,0 +1,47 @@
+//===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- 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 an llvm::PrettyStackTraceEntry object for showing
+// that a particular declaration was being processed when a crash
+// occurred.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
+#define LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace clang {
+
+class Decl;
+class Sema;
+class SourceManager;
+
+/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while
+/// parsing something related to a declaration, include that
+/// declaration in the stack trace.
+class PrettyDeclStackTraceEntry : public llvm::PrettyStackTraceEntry {
+  Sema &S;
+  Decl *TheDecl;
+  SourceLocation Loc;
+  const char *Message;
+
+public:
+  PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc,
+                            const char *Msg)
+    : S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
+
+  void print(raw_ostream &OS) const override;
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
new file mode 100644
index 0000000..8e4e2ef
--- /dev/null
+++ b/include/clang/Sema/Scope.h
@@ -0,0 +1,473 @@
+//===--- Scope.h - Scope interface ------------------------------*- 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 Scope interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SCOPE_H
+#define LLVM_CLANG_SEMA_SCOPE_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+}
+
+namespace clang {
+
+class Decl;
+class UsingDirectiveDecl;
+class VarDecl;
+
+/// Scope - A scope is a transient data structure that is used while parsing the
+/// program.  It assists with resolving identifiers to the appropriate
+/// declaration.
+///
+class Scope {
+public:
+  /// ScopeFlags - These are bitfields that are or'd together when creating a
+  /// scope, which defines the sorts of things the scope contains.
+  enum ScopeFlags {
+    /// \brief This indicates that the scope corresponds to a function, which
+    /// means that labels are set here.
+    FnScope       = 0x01,
+
+    /// \brief This is a while, do, switch, for, etc that can have break
+    /// statements embedded into it.
+    BreakScope    = 0x02,
+
+    /// \brief This is a while, do, for, which can have continue statements
+    /// embedded into it.
+    ContinueScope = 0x04,
+
+    /// \brief This is a scope that can contain a declaration.  Some scopes
+    /// just contain loop constructs but don't contain decls.
+    DeclScope = 0x08,
+
+    /// \brief The controlling scope in a if/switch/while/for statement.
+    ControlScope = 0x10,
+
+    /// \brief The scope of a struct/union/class definition.
+    ClassScope = 0x20,
+
+    /// \brief This is a scope that corresponds to a block/closure object.
+    /// Blocks serve as top-level scopes for some objects like labels, they
+    /// also prevent things like break and continue.  BlockScopes always have
+    /// the FnScope and DeclScope flags set as well.
+    BlockScope = 0x40,
+
+    /// \brief This is a scope that corresponds to the
+    /// template parameters of a C++ template. Template parameter
+    /// scope starts at the 'template' keyword and ends when the
+    /// template declaration ends.
+    TemplateParamScope = 0x80,
+
+    /// \brief This is a scope that corresponds to the
+    /// parameters within a function prototype.
+    FunctionPrototypeScope = 0x100,
+
+    /// \brief This is a scope that corresponds to the parameters within
+    /// a function prototype for a function declaration (as opposed to any
+    /// other kind of function declarator). Always has FunctionPrototypeScope
+    /// set as well.
+    FunctionDeclarationScope = 0x200,
+
+    /// \brief This is a scope that corresponds to the Objective-C
+    /// \@catch statement.
+    AtCatchScope = 0x400,
+    
+    /// \brief This scope corresponds to an Objective-C method body.
+    /// It always has FnScope and DeclScope set as well.
+    ObjCMethodScope = 0x800,
+
+    /// \brief This is a scope that corresponds to a switch statement.
+    SwitchScope = 0x1000,
+
+    /// \brief This is the scope of a C++ try statement.
+    TryScope = 0x2000,
+
+    /// \brief This is the scope for a function-level C++ try or catch scope.
+    FnTryCatchScope = 0x4000,
+
+    /// \brief This is the scope of OpenMP executable directive.
+    OpenMPDirectiveScope = 0x8000,
+
+    /// \brief This is the scope of some OpenMP loop directive.
+    OpenMPLoopDirectiveScope = 0x10000,
+
+    /// \brief This is the scope of some OpenMP simd directive.
+    /// For example, it is used for 'omp simd', 'omp for simd'.
+    /// This flag is propagated to children scopes.
+    OpenMPSimdDirectiveScope = 0x20000,
+
+    /// This scope corresponds to an enum.
+    EnumScope = 0x40000,
+
+    /// This scope corresponds to a SEH try.
+    SEHTryScope = 0x80000,
+  };
+private:
+  /// The parent scope for this scope.  This is null for the translation-unit
+  /// scope.
+  Scope *AnyParent;
+
+  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+  /// interrelates with other control flow statements.
+  unsigned Flags;
+
+  /// Depth - This is the depth of this scope.  The translation-unit scope has
+  /// depth 0.
+  unsigned short Depth;
+
+  /// \brief Declarations with static linkage are mangled with the number of
+  /// scopes seen as a component.
+  unsigned short MSLocalManglingNumber;
+
+  /// \brief SEH __try blocks get uniquely numbered within a function.  This
+  /// variable holds the index for an SEH try block.
+  short SEHTryIndex;
+
+  /// \brief SEH __try blocks get uniquely numbered within a function.  This
+  /// variable holds the next free index at a function's scope.
+  short SEHTryIndexPool;
+
+  /// PrototypeDepth - This is the number of function prototype scopes
+  /// enclosing this scope, including this scope.
+  unsigned short PrototypeDepth;
+
+  /// PrototypeIndex - This is the number of parameters currently
+  /// declared in this scope.
+  unsigned short PrototypeIndex;
+
+  /// FnParent - If this scope has a parent scope that is a function body, this
+  /// pointer is non-null and points to it.  This is used for label processing.
+  Scope *FnParent;
+  Scope *MSLocalManglingParent;
+  Scope *SEHTryParent;
+
+  /// BreakParent/ContinueParent - This is a direct link to the innermost
+  /// BreakScope/ContinueScope which contains the contents of this scope
+  /// for control flow purposes (and might be this scope itself), or null
+  /// if there is no such scope.
+  Scope *BreakParent, *ContinueParent;
+
+  /// BlockParent - This is a direct link to the immediately containing
+  /// BlockScope if this scope is not one, or null if there is none.
+  Scope *BlockParent;
+
+  /// TemplateParamParent - This is a direct link to the
+  /// immediately containing template parameter scope. In the
+  /// case of nested templates, template parameter scopes can have
+  /// other template parameter scopes as parents.
+  Scope *TemplateParamParent;
+
+  /// DeclsInScope - This keeps track of all declarations in this scope.  When
+  /// the declaration is added to the scope, it is set as the current
+  /// declaration for the identifier in the IdentifierTable.  When the scope is
+  /// popped, these declarations are removed from the IdentifierTable's notion
+  /// of current declaration.  It is up to the current Action implementation to
+  /// implement these semantics.
+  typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy;
+  DeclSetTy DeclsInScope;
+
+  /// The DeclContext with which this scope is associated. For
+  /// example, the entity of a class scope is the class itself, the
+  /// entity of a function scope is a function, etc.
+  DeclContext *Entity;
+
+  typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy;
+  UsingDirectivesTy UsingDirectives;
+
+  /// \brief Used to determine if errors occurred in this scope.
+  DiagnosticErrorTrap ErrorTrap;
+
+  /// A lattice consisting of undefined, a single NRVO candidate variable in
+  /// this scope, or over-defined. The bit is true when over-defined.
+  llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+
+public:
+  Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
+    : ErrorTrap(Diag) {
+    Init(Parent, ScopeFlags);
+  }
+
+  /// getFlags - Return the flags for this scope.
+  ///
+  unsigned getFlags() const { return Flags; }
+  void setFlags(unsigned F) { Flags = F; }
+
+  /// isBlockScope - Return true if this scope correspond to a closure.
+  bool isBlockScope() const { return Flags & BlockScope; }
+
+  /// getParent - Return the scope that this is nested in.
+  ///
+  const Scope *getParent() const { return AnyParent; }
+  Scope *getParent() { return AnyParent; }
+
+  /// getFnParent - Return the closest scope that is a function body.
+  ///
+  const Scope *getFnParent() const { return FnParent; }
+  Scope *getFnParent() { return FnParent; }
+
+  const Scope *getMSLocalManglingParent() const {
+    return MSLocalManglingParent;
+  }
+  Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
+
+  /// getContinueParent - Return the closest scope that a continue statement
+  /// would be affected by.
+  Scope *getContinueParent() {
+    return ContinueParent;
+  }
+
+  const Scope *getContinueParent() const {
+    return const_cast<Scope*>(this)->getContinueParent();
+  }
+
+  /// getBreakParent - Return the closest scope that a break statement
+  /// would be affected by.
+  Scope *getBreakParent() {
+    return BreakParent;
+  }
+  const Scope *getBreakParent() const {
+    return const_cast<Scope*>(this)->getBreakParent();
+  }
+
+  Scope *getBlockParent() { return BlockParent; }
+  const Scope *getBlockParent() const { return BlockParent; }
+
+  Scope *getTemplateParamParent() { return TemplateParamParent; }
+  const Scope *getTemplateParamParent() const { return TemplateParamParent; }
+
+  /// Returns the number of function prototype scopes in this scope
+  /// chain.
+  unsigned getFunctionPrototypeDepth() const {
+    return PrototypeDepth;
+  }
+
+  /// Return the number of parameters declared in this function
+  /// prototype, increasing it by one for the next call.
+  unsigned getNextFunctionPrototypeIndex() {
+    assert(isFunctionPrototypeScope());
+    return PrototypeIndex++;
+  }
+
+  typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
+  decl_range decls() const {
+    return decl_range(DeclsInScope.begin(), DeclsInScope.end());
+  }
+  bool decl_empty() const { return DeclsInScope.empty(); }
+
+  void AddDecl(Decl *D) {
+    DeclsInScope.insert(D);
+  }
+
+  void RemoveDecl(Decl *D) {
+    DeclsInScope.erase(D);
+  }
+
+  void incrementMSLocalManglingNumber() {
+    if (Scope *MSLMP = getMSLocalManglingParent())
+      MSLMP->MSLocalManglingNumber += 1;
+  }
+
+  void decrementMSLocalManglingNumber() {
+    if (Scope *MSLMP = getMSLocalManglingParent())
+      MSLMP->MSLocalManglingNumber -= 1;
+  }
+
+  unsigned getMSLocalManglingNumber() const {
+    if (const Scope *MSLMP = getMSLocalManglingParent())
+      return MSLMP->MSLocalManglingNumber;
+    return 1;
+  }
+
+  int getSEHTryIndex() {
+    return SEHTryIndex;
+  }
+
+  int getSEHTryParentIndex() const {
+    return SEHTryParent ? SEHTryParent->SEHTryIndex : -1;
+  }
+
+  /// isDeclScope - Return true if this is the scope that the specified decl is
+  /// declared in.
+  bool isDeclScope(Decl *D) {
+    return DeclsInScope.count(D) != 0;
+  }
+
+  DeclContext *getEntity() const { return Entity; }
+  void setEntity(DeclContext *E) { Entity = E; }
+
+  bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
+
+  bool hasUnrecoverableErrorOccurred() const {
+    return ErrorTrap.hasUnrecoverableErrorOccurred();
+  }
+
+  /// isClassScope - Return true if this scope is a class/struct/union scope.
+  bool isClassScope() const {
+    return (getFlags() & Scope::ClassScope);
+  }
+
+  /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
+  /// method scope or is inside one.
+  bool isInCXXInlineMethodScope() const {
+    if (const Scope *FnS = getFnParent()) {
+      assert(FnS->getParent() && "TUScope not created?");
+      return FnS->getParent()->isClassScope();
+    }
+    return false;
+  }
+  
+  /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
+  /// Objective-C method body.  Note that this method is not constant time.
+  bool isInObjcMethodScope() const {
+    for (const Scope *S = this; S; S = S->getParent()) {
+      // If this scope is an objc method scope, then we succeed.
+      if (S->getFlags() & ObjCMethodScope)
+        return true;
+    }
+    return false;
+  }
+
+  /// isInObjcMethodOuterScope - Return true if this scope is an
+  /// Objective-C method outer most body.
+  bool isInObjcMethodOuterScope() const {
+    if (const Scope *S = this) {
+      // If this scope is an objc method scope, then we succeed.
+      if (S->getFlags() & ObjCMethodScope)
+        return true;
+    }
+    return false;
+  }
+
+  
+  /// isTemplateParamScope - Return true if this scope is a C++
+  /// template parameter scope.
+  bool isTemplateParamScope() const {
+    return getFlags() & Scope::TemplateParamScope;
+  }
+
+  /// isFunctionPrototypeScope - Return true if this scope is a
+  /// function prototype scope.
+  bool isFunctionPrototypeScope() const {
+    return getFlags() & Scope::FunctionPrototypeScope;
+  }
+
+  /// isAtCatchScope - Return true if this scope is \@catch.
+  bool isAtCatchScope() const {
+    return getFlags() & Scope::AtCatchScope;
+  }
+
+  /// isSwitchScope - Return true if this scope is a switch scope.
+  bool isSwitchScope() const {
+    for (const Scope *S = this; S; S = S->getParent()) {
+      if (S->getFlags() & Scope::SwitchScope)
+        return true;
+      else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
+                                Scope::BlockScope | Scope::TemplateParamScope |
+                                Scope::FunctionPrototypeScope |
+                                Scope::AtCatchScope | Scope::ObjCMethodScope))
+        return false;
+    }
+    return false;
+  }
+
+  /// \brief Determines whether this scope is the OpenMP directive scope
+  bool isOpenMPDirectiveScope() const {
+    return (getFlags() & Scope::OpenMPDirectiveScope);
+  }
+
+  /// \brief Determine whether this scope is some OpenMP loop directive scope
+  /// (for example, 'omp for', 'omp simd').
+  bool isOpenMPLoopDirectiveScope() const {
+    if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
+      assert(isOpenMPDirectiveScope() &&
+             "OpenMP loop directive scope is not a directive scope");
+      return true;
+    }
+    return false;
+  }
+
+  /// \brief Determine whether this scope is (or is nested into) some OpenMP
+  /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
+  bool isOpenMPSimdDirectiveScope() const {
+    return getFlags() & Scope::OpenMPSimdDirectiveScope;
+  }
+
+  /// \brief Determine whether this scope is a loop having OpenMP loop
+  /// directive attached.
+  bool isOpenMPLoopScope() const {
+    const Scope *P = getParent();
+    return P && P->isOpenMPLoopDirectiveScope();
+  }
+
+  /// \brief Determine whether this scope is a C++ 'try' block.
+  bool isTryScope() const { return getFlags() & Scope::TryScope; }
+
+  /// \brief Determine whether this scope is a SEH '__try' block.
+  bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
+
+  /// containedInPrototypeScope - Return true if this or a parent scope
+  /// is a FunctionPrototypeScope.
+  bool containedInPrototypeScope() const;
+
+  void PushUsingDirective(UsingDirectiveDecl *UDir) {
+    UsingDirectives.push_back(UDir);
+  }
+
+  typedef llvm::iterator_range<UsingDirectivesTy::iterator>
+    using_directives_range;
+
+  using_directives_range using_directives() {
+    return using_directives_range(UsingDirectives.begin(),
+                                  UsingDirectives.end());
+  }
+
+  void addNRVOCandidate(VarDecl *VD) {
+    if (NRVO.getInt())
+      return;
+    if (NRVO.getPointer() == nullptr) {
+      NRVO.setPointer(VD);
+      return;
+    }
+    if (NRVO.getPointer() != VD)
+      setNoNRVO();
+  }
+
+  void setNoNRVO() {
+    NRVO.setInt(1);
+    NRVO.setPointer(nullptr);
+  }
+
+  void mergeNRVOIntoParent();
+
+  /// Init - This is used by the parser to implement scope caching.
+  ///
+  void Init(Scope *parent, unsigned flags);
+
+  /// \brief Sets up the specified scope flags and adjusts the scope state
+  /// variables accordingly.
+  ///
+  void AddFlags(unsigned Flags);
+
+  void dumpImpl(raw_ostream &OS) const;
+  void dump() const;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
new file mode 100644
index 0000000..63427aa
--- /dev/null
+++ b/include/clang/Sema/ScopeInfo.h
@@ -0,0 +1,820 @@
+//===--- ScopeInfo.h - Information about a semantic context -----*- 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 FunctionScopeInfo and its subclasses, which contain
+// information about a single function, block, lambda, or method body.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
+#define LLVM_CLANG_SEMA_SCOPE_INFO_H
+
+#include "clang/AST/Type.h"
+#include "clang/Basic/CapturedStmt.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Sema/Ownership.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+
+namespace clang {
+
+class Decl;
+class BlockDecl;
+class CapturedDecl;
+class CXXMethodDecl;
+class FieldDecl;
+class ObjCPropertyDecl;
+class IdentifierInfo;
+class ImplicitParamDecl;
+class LabelDecl;
+class ReturnStmt;
+class Scope;
+class SwitchStmt;
+class TemplateTypeParmDecl;
+class TemplateParameterList;
+class VarDecl;
+class DeclRefExpr;
+class MemberExpr;
+class ObjCIvarRefExpr;
+class ObjCPropertyRefExpr;
+class ObjCMessageExpr;
+
+namespace sema {
+
+/// \brief Contains information about the compound statement currently being
+/// parsed.
+class CompoundScopeInfo {
+public:
+  CompoundScopeInfo()
+    : HasEmptyLoopBodies(false) { }
+
+  /// \brief Whether this compound stamement contains `for' or `while' loops
+  /// with empty bodies.
+  bool HasEmptyLoopBodies;
+
+  void setHasEmptyLoopBodies() {
+    HasEmptyLoopBodies = true;
+  }
+};
+
+class PossiblyUnreachableDiag {
+public:
+  PartialDiagnostic PD;
+  SourceLocation Loc;
+  const Stmt *stmt;
+  
+  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
+                          const Stmt *stmt)
+    : PD(PD), Loc(Loc), stmt(stmt) {}
+};
+    
+/// \brief Retains information about a function, method, or block that is
+/// currently being parsed.
+class FunctionScopeInfo {
+protected:
+  enum ScopeKind {
+    SK_Function,
+    SK_Block,
+    SK_Lambda,
+    SK_CapturedRegion
+  };
+  
+public:
+  /// \brief What kind of scope we are describing.
+  ///
+  ScopeKind Kind;
+
+  /// \brief Whether this function contains a VLA, \@try, try, C++
+  /// initializer, or anything else that can't be jumped past.
+  bool HasBranchProtectedScope;
+
+  /// \brief Whether this function contains any switches or direct gotos.
+  bool HasBranchIntoScope;
+
+  /// \brief Whether this function contains any indirect gotos.
+  bool HasIndirectGoto;
+
+  /// \brief Whether a statement was dropped because it was invalid.
+  bool HasDroppedStmt;
+
+  /// A flag that is set when parsing a method that must call super's
+  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
+  /// with \c __attribute__((objc_requires_super)).
+  bool ObjCShouldCallSuper;
+
+  /// True when this is a method marked as a designated initializer.
+  bool ObjCIsDesignatedInit;
+  /// This starts true for a method marked as designated initializer and will
+  /// be set to false if there is an invocation to a designated initializer of
+  /// the super class.
+  bool ObjCWarnForNoDesignatedInitChain;
+
+  /// True when this is an initializer method not marked as a designated
+  /// initializer within a class that has at least one initializer marked as a
+  /// designated initializer.
+  bool ObjCIsSecondaryInit;
+  /// This starts true for a secondary initializer method and will be set to
+  /// false if there is an invocation of an initializer on 'self'.
+  bool ObjCWarnForNoInitDelegation;
+
+  /// \brief Used to determine if errors occurred in this function or block.
+  DiagnosticErrorTrap ErrorTrap;
+
+  /// SwitchStack - This is the current set of active switch statements in the
+  /// block.
+  SmallVector<SwitchStmt*, 8> SwitchStack;
+
+  /// \brief The list of return statements that occur within the function or
+  /// block, if there is any chance of applying the named return value
+  /// optimization, or if we need to infer a return type.
+  SmallVector<ReturnStmt*, 4> Returns;
+
+  /// \brief The stack of currently active compound stamement scopes in the
+  /// function.
+  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
+
+  /// \brief A list of PartialDiagnostics created but delayed within the
+  /// current function scope.  These diagnostics are vetted for reachability
+  /// prior to being emitted.
+  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
+
+public:
+  /// Represents a simple identification of a weak object.
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  ///
+  /// This is used to determine if two weak accesses refer to the same object.
+  /// Here are some examples of how various accesses are "profiled":
+  ///
+  /// Access Expression |     "Base" Decl     |          "Property" Decl
+  /// :---------------: | :-----------------: | :------------------------------:
+  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
+  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
+  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
+  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
+  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
+  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
+  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
+  /// weakVar           | 0 (known)           | weakVar (VarDecl)
+  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
+  ///
+  /// Objects are identified with only two Decls to make it reasonably fast to
+  /// compare them.
+  class WeakObjectProfileTy {
+    /// The base object decl, as described in the class documentation.
+    ///
+    /// The extra flag is "true" if the Base and Property are enough to uniquely
+    /// identify the object in memory.
+    ///
+    /// \sa isExactProfile()
+    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
+    BaseInfoTy Base;
+
+    /// The "property" decl, as described in the class documentation.
+    ///
+    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
+    /// case of "implicit" properties (regular methods accessed via dot syntax).
+    const NamedDecl *Property;
+
+    /// Used to find the proper base profile for a given base expression.
+    static BaseInfoTy getBaseInfo(const Expr *BaseE);
+
+    // For use in DenseMap.
+    friend class DenseMapInfo;
+    inline WeakObjectProfileTy();
+    static inline WeakObjectProfileTy getSentinel();
+
+  public:
+    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
+    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
+    WeakObjectProfileTy(const DeclRefExpr *RE);
+    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
+
+    const NamedDecl *getBase() const { return Base.getPointer(); }
+    const NamedDecl *getProperty() const { return Property; }
+
+    /// Returns true if the object base specifies a known object in memory,
+    /// rather than, say, an instance variable or property of another object.
+    ///
+    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
+    /// considered an exact profile if \c foo is a local variable, even if
+    /// another variable \c foo2 refers to the same object as \c foo.
+    ///
+    /// For increased precision, accesses with base variables that are
+    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
+    /// be exact, though this is not true for arbitrary variables
+    /// (foo.prop1.prop2).
+    bool isExactProfile() const {
+      return Base.getInt();
+    }
+
+    bool operator==(const WeakObjectProfileTy &Other) const {
+      return Base == Other.Base && Property == Other.Property;
+    }
+
+    // For use in DenseMap.
+    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
+    // because by that point the DenseMap in FunctionScopeInfo has already been
+    // instantiated.
+    class DenseMapInfo {
+    public:
+      static inline WeakObjectProfileTy getEmptyKey() {
+        return WeakObjectProfileTy();
+      }
+      static inline WeakObjectProfileTy getTombstoneKey() {
+        return WeakObjectProfileTy::getSentinel();
+      }
+
+      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
+        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
+        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
+                                                           Val.Property));
+      }
+
+      static bool isEqual(const WeakObjectProfileTy &LHS,
+                          const WeakObjectProfileTy &RHS) {
+        return LHS == RHS;
+      }
+    };
+  };
+
+  /// Represents a single use of a weak object.
+  ///
+  /// Stores both the expression and whether the access is potentially unsafe
+  /// (i.e. it could potentially be warned about).
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  class WeakUseTy {
+    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
+  public:
+    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
+
+    const Expr *getUseExpr() const { return Rep.getPointer(); }
+    bool isUnsafe() const { return Rep.getInt(); }
+    void markSafe() { Rep.setInt(false); }
+
+    bool operator==(const WeakUseTy &Other) const {
+      return Rep == Other.Rep;
+    }
+  };
+
+  /// Used to collect uses of a particular weak object in a function body.
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
+
+  /// Used to collect all uses of weak objects in a function body.
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
+                              WeakObjectProfileTy::DenseMapInfo>
+          WeakObjectUseMap;
+
+private:
+  /// Used to collect all uses of weak objects in this function body.
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  WeakObjectUseMap WeakObjectUses;
+
+public:
+  /// Record that a weak object was accessed.
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  template <typename ExprT>
+  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
+
+  void recordUseOfWeak(const ObjCMessageExpr *Msg,
+                       const ObjCPropertyDecl *Prop);
+
+  /// Record that a given expression is a "safe" access of a weak object (e.g.
+  /// assigning it to a strong variable.)
+  ///
+  /// Part of the implementation of -Wrepeated-use-of-weak.
+  void markSafeWeakUse(const Expr *E);
+
+  const WeakObjectUseMap &getWeakObjectUses() const {
+    return WeakObjectUses;
+  }
+
+  void setHasBranchIntoScope() {
+    HasBranchIntoScope = true;
+  }
+
+  void setHasBranchProtectedScope() {
+    HasBranchProtectedScope = true;
+  }
+
+  void setHasIndirectGoto() {
+    HasIndirectGoto = true;
+  }
+
+  void setHasDroppedStmt() {
+    HasDroppedStmt = true;
+  }
+
+  bool NeedsScopeChecking() const {
+    return !HasDroppedStmt &&
+        (HasIndirectGoto ||
+          (HasBranchProtectedScope && HasBranchIntoScope));
+  }
+  
+  FunctionScopeInfo(DiagnosticsEngine &Diag)
+    : Kind(SK_Function),
+      HasBranchProtectedScope(false),
+      HasBranchIntoScope(false),
+      HasIndirectGoto(false),
+      HasDroppedStmt(false),
+      ObjCShouldCallSuper(false),
+      ObjCIsDesignatedInit(false),
+      ObjCWarnForNoDesignatedInitChain(false),
+      ObjCIsSecondaryInit(false),
+      ObjCWarnForNoInitDelegation(false),
+      ErrorTrap(Diag) { }
+
+  virtual ~FunctionScopeInfo();
+
+  /// \brief Clear out the information in this function scope, making it
+  /// suitable for reuse.
+  void Clear();
+};
+
+class CapturingScopeInfo : public FunctionScopeInfo {
+public:
+  enum ImplicitCaptureStyle {
+    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
+    ImpCap_CapturedRegion
+  };
+
+  ImplicitCaptureStyle ImpCaptureStyle;
+
+  class Capture {
+    // There are three categories of capture: capturing 'this', capturing
+    // local variables, and C++1y initialized captures (which can have an
+    // arbitrary initializer, and don't really capture in the traditional
+    // sense at all).
+    //
+    // There are three ways to capture a local variable:
+    //  - capture by copy in the C++11 sense,
+    //  - capture by reference in the C++11 sense, and
+    //  - __block capture.
+    // Lambdas explicitly specify capture by copy or capture by reference.
+    // For blocks, __block capture applies to variables with that annotation,
+    // variables of reference type are captured by reference, and other
+    // variables are captured by copy.
+    enum CaptureKind {
+      Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This
+    };
+
+    /// The variable being captured (if we are not capturing 'this') and whether
+    /// this is a nested capture.
+    llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
+
+    /// Expression to initialize a field of the given type, and the kind of
+    /// capture (if this is a capture and not an init-capture). The expression
+    /// is only required if we are capturing ByVal and the variable's type has
+    /// a non-trivial copy constructor.
+    llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
+
+    /// \brief The source location at which the first capture occurred.
+    SourceLocation Loc;
+
+    /// \brief The location of the ellipsis that expands a parameter pack.
+    SourceLocation EllipsisLoc;
+
+    /// \brief The type as it was captured, which is in effect the type of the
+    /// non-static data member that would hold the capture.
+    QualType CaptureType;
+
+  public:
+    Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
+            SourceLocation Loc, SourceLocation EllipsisLoc,
+            QualType CaptureType, Expr *Cpy)
+        : VarAndNested(Var, IsNested),
+          InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
+                                      ByRef ? Cap_ByRef : Cap_ByCopy),
+          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
+
+    enum IsThisCapture { ThisCapture };
+    Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
+            QualType CaptureType, Expr *Cpy)
+        : VarAndNested(nullptr, IsNested),
+          InitExprAndCaptureKind(Cpy, Cap_This),
+          Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
+
+    bool isThisCapture() const {
+      return InitExprAndCaptureKind.getInt() == Cap_This;
+    }
+    bool isVariableCapture() const {
+      return InitExprAndCaptureKind.getInt() != Cap_This;
+    }
+    bool isCopyCapture() const {
+      return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
+    }
+    bool isReferenceCapture() const {
+      return InitExprAndCaptureKind.getInt() == Cap_ByRef;
+    }
+    bool isBlockCapture() const {
+      return InitExprAndCaptureKind.getInt() == Cap_Block;
+    }
+    bool isNested() { return VarAndNested.getInt(); }
+
+    VarDecl *getVariable() const {
+      return VarAndNested.getPointer();
+    }
+    
+    /// \brief Retrieve the location at which this variable was captured.
+    SourceLocation getLocation() const { return Loc; }
+    
+    /// \brief Retrieve the source location of the ellipsis, whose presence
+    /// indicates that the capture is a pack expansion.
+    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+    
+    /// \brief Retrieve the capture type for this capture, which is effectively
+    /// the type of the non-static data member in the lambda/block structure
+    /// that would store this capture.
+    QualType getCaptureType() const { return CaptureType; }
+    
+    Expr *getInitExpr() const {
+      return InitExprAndCaptureKind.getPointer();
+    }
+  };
+
+  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
+    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
+      HasImplicitReturnType(false)
+     {}
+
+  /// CaptureMap - A map of captured variables to (index+1) into Captures.
+  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
+
+  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
+  /// zero if 'this' is not captured.
+  unsigned CXXThisCaptureIndex;
+
+  /// Captures - The captures.
+  SmallVector<Capture, 4> Captures;
+
+  /// \brief - Whether the target type of return statements in this context
+  /// is deduced (e.g. a lambda or block with omitted return type).
+  bool HasImplicitReturnType;
+
+  /// ReturnType - The target type of return statements in this context,
+  /// or null if unknown.
+  QualType ReturnType;
+
+  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
+                  SourceLocation Loc, SourceLocation EllipsisLoc, 
+                  QualType CaptureType, Expr *Cpy) {
+    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 
+                               EllipsisLoc, CaptureType, Cpy));
+    CaptureMap[Var] = Captures.size();
+  }
+
+  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
+                      Expr *Cpy);
+
+  /// \brief Determine whether the C++ 'this' is captured.
+  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
+  
+  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
+  Capture &getCXXThisCapture() {
+    assert(isCXXThisCaptured() && "this has not been captured");
+    return Captures[CXXThisCaptureIndex - 1];
+  }
+  
+  /// \brief Determine whether the given variable has been captured.
+  bool isCaptured(VarDecl *Var) const {
+    return CaptureMap.count(Var);
+  }
+  
+  /// \brief Retrieve the capture of the given variable, if it has been
+  /// captured already.
+  Capture &getCapture(VarDecl *Var) {
+    assert(isCaptured(Var) && "Variable has not been captured");
+    return Captures[CaptureMap[Var] - 1];
+  }
+
+  const Capture &getCapture(VarDecl *Var) const {
+    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
+      = CaptureMap.find(Var);
+    assert(Known != CaptureMap.end() && "Variable has not been captured");
+    return Captures[Known->second - 1];
+  }
+
+  static bool classof(const FunctionScopeInfo *FSI) { 
+    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
+                                 || FSI->Kind == SK_CapturedRegion;
+  }
+};
+
+/// \brief Retains information about a block that is currently being parsed.
+class BlockScopeInfo : public CapturingScopeInfo {
+public:
+  BlockDecl *TheDecl;
+  
+  /// TheScope - This is the scope for the block itself, which contains
+  /// arguments etc.
+  Scope *TheScope;
+
+  /// BlockType - The function type of the block, if one was given.
+  /// Its return type may be BuiltinType::Dependent.
+  QualType FunctionType;
+
+  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
+    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
+      TheScope(BlockScope)
+  {
+    Kind = SK_Block;
+  }
+
+  virtual ~BlockScopeInfo();
+
+  static bool classof(const FunctionScopeInfo *FSI) { 
+    return FSI->Kind == SK_Block; 
+  }
+};
+
+/// \brief Retains information about a captured region.
+class CapturedRegionScopeInfo: public CapturingScopeInfo {
+public:
+  /// \brief The CapturedDecl for this statement.
+  CapturedDecl *TheCapturedDecl;
+  /// \brief The captured record type.
+  RecordDecl *TheRecordDecl;
+  /// \brief This is the enclosing scope of the captured region.
+  Scope *TheScope;
+  /// \brief The implicit parameter for the captured variables.
+  ImplicitParamDecl *ContextParam;
+  /// \brief The kind of captured region.
+  CapturedRegionKind CapRegionKind;
+
+  CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
+                          RecordDecl *RD, ImplicitParamDecl *Context,
+                          CapturedRegionKind K)
+    : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
+      TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
+      ContextParam(Context), CapRegionKind(K)
+  {
+    Kind = SK_CapturedRegion;
+  }
+
+  virtual ~CapturedRegionScopeInfo();
+
+  /// \brief A descriptive name for the kind of captured region this is.
+  StringRef getRegionName() const {
+    switch (CapRegionKind) {
+    case CR_Default:
+      return "default captured statement";
+    case CR_OpenMP:
+      return "OpenMP region";
+    }
+    llvm_unreachable("Invalid captured region kind!");
+  }
+
+  static bool classof(const FunctionScopeInfo *FSI) {
+    return FSI->Kind == SK_CapturedRegion;
+  }
+};
+
+class LambdaScopeInfo : public CapturingScopeInfo {
+public:
+  /// \brief The class that describes the lambda.
+  CXXRecordDecl *Lambda;
+
+  /// \brief The lambda's compiler-generated \c operator().
+  CXXMethodDecl *CallOperator;
+
+  /// \brief Source range covering the lambda introducer [...].
+  SourceRange IntroducerRange;
+
+  /// \brief Source location of the '&' or '=' specifying the default capture
+  /// type, if any.
+  SourceLocation CaptureDefaultLoc;
+
+  /// \brief The number of captures in the \c Captures list that are
+  /// explicit captures.
+  unsigned NumExplicitCaptures;
+
+  /// \brief Whether this is a mutable lambda.
+  bool Mutable;
+
+  /// \brief Whether the (empty) parameter list is explicit.
+  bool ExplicitParams;
+
+  /// \brief Whether any of the capture expressions requires cleanups.
+  bool ExprNeedsCleanups;
+
+  /// \brief Whether the lambda contains an unexpanded parameter pack.
+  bool ContainsUnexpandedParameterPack;
+
+  /// \brief Variables used to index into by-copy array captures.
+  SmallVector<VarDecl *, 4> ArrayIndexVars;
+
+  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
+  /// its list of array index variables.
+  SmallVector<unsigned, 4> ArrayIndexStarts;
+  
+  /// \brief If this is a generic lambda, use this as the depth of 
+  /// each 'auto' parameter, during initial AST construction.
+  unsigned AutoTemplateParameterDepth;
+
+  /// \brief Store the list of the auto parameters for a generic lambda.
+  /// If this is a generic lambda, store the list of the auto 
+  /// parameters converted into TemplateTypeParmDecls into a vector
+  /// that can be used to construct the generic lambda's template
+  /// parameter list, during initial AST construction.
+  SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
+
+  /// If this is a generic lambda, and the template parameter
+  /// list has been created (from the AutoTemplateParams) then
+  /// store a reference to it (cache it to avoid reconstructing it).
+  TemplateParameterList *GLTemplateParameterList;
+  
+  /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs
+  ///  or MemberExprs) that refer to local variables in a generic lambda
+  ///  or a lambda in a potentially-evaluated-if-used context.
+  ///  
+  ///  Potentially capturable variables of a nested lambda that might need 
+  ///   to be captured by the lambda are housed here.  
+  ///  This is specifically useful for generic lambdas or
+  ///  lambdas within a a potentially evaluated-if-used context.
+  ///  If an enclosing variable is named in an expression of a lambda nested
+  ///  within a generic lambda, we don't always know know whether the variable 
+  ///  will truly be odr-used (i.e. need to be captured) by that nested lambda,
+  ///  until its instantiation. But we still need to capture it in the 
+  ///  enclosing lambda if all intervening lambdas can capture the variable.
+
+  llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs;
+
+  /// \brief Contains all variable-referring-expressions that refer
+  ///  to local variables that are usable as constant expressions and
+  ///  do not involve an odr-use (they may still need to be captured
+  ///  if the enclosing full-expression is instantiation dependent).
+  llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs; 
+
+  SourceLocation PotentialThisCaptureLocation;
+
+  LambdaScopeInfo(DiagnosticsEngine &Diag)
+    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
+      CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
+      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
+      AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr)
+  {
+    Kind = SK_Lambda;
+  }
+
+  virtual ~LambdaScopeInfo();
+
+  /// \brief Note when all explicit captures have been added.
+  void finishedExplicitCaptures() {
+    NumExplicitCaptures = Captures.size();
+  }
+
+  static bool classof(const FunctionScopeInfo *FSI) {
+    return FSI->Kind == SK_Lambda;
+  }
+
+  ///
+  /// \brief Add a variable that might potentially be captured by the 
+  /// lambda and therefore the enclosing lambdas. 
+  /// 
+  /// This is also used by enclosing lambda's to speculatively capture 
+  /// variables that nested lambda's - depending on their enclosing
+  /// specialization - might need to capture.
+  /// Consider:
+  /// void f(int, int); <-- don't capture
+  /// void f(const int&, double); <-- capture
+  /// void foo() {
+  ///   const int x = 10;
+  ///   auto L = [=](auto a) { // capture 'x'
+  ///      return [=](auto b) { 
+  ///        f(x, a);  // we may or may not need to capture 'x'
+  ///      };
+  ///   };
+  /// }
+  void addPotentialCapture(Expr *VarExpr) {
+    assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr));
+    PotentiallyCapturingExprs.push_back(VarExpr);
+  }
+  
+  void addPotentialThisCapture(SourceLocation Loc) {
+    PotentialThisCaptureLocation = Loc;
+  }
+  bool hasPotentialThisCapture() const { 
+    return PotentialThisCaptureLocation.isValid(); 
+  }
+
+  /// \brief Mark a variable's reference in a lambda as non-odr using.
+  ///
+  /// For generic lambdas, if a variable is named in a potentially evaluated 
+  /// expression, where the enclosing full expression is dependent then we 
+  /// must capture the variable (given a default capture).
+  /// This is accomplished by recording all references to variables 
+  /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of 
+  /// PotentialCaptures. All such variables have to be captured by that lambda,
+  /// except for as described below.
+  /// If that variable is usable as a constant expression and is named in a 
+  /// manner that does not involve its odr-use (e.g. undergoes 
+  /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the
+  /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
+  /// if we can determine that the full expression is not instantiation-
+  /// dependent, then we can entirely avoid its capture. 
+  ///
+  ///   const int n = 0;
+  ///   [&] (auto x) {
+  ///     (void)+n + x;
+  ///   };
+  /// Interestingly, this strategy would involve a capture of n, even though 
+  /// it's obviously not odr-used here, because the full-expression is 
+  /// instantiation-dependent.  It could be useful to avoid capturing such
+  /// variables, even when they are referred to in an instantiation-dependent
+  /// expression, if we can unambiguously determine that they shall never be
+  /// odr-used.  This would involve removal of the variable-referring-expression
+  /// from the array of PotentialCaptures during the lvalue-to-rvalue 
+  /// conversions.  But per the working draft N3797, (post-chicago 2013) we must
+  /// capture such variables. 
+  /// Before anyone is tempted to implement a strategy for not-capturing 'n',
+  /// consider the insightful warning in: 
+  ///    /cfe-commits/Week-of-Mon-20131104/092596.html
+  /// "The problem is that the set of captures for a lambda is part of the ABI
+  ///  (since lambda layout can be made visible through inline functions and the
+  ///  like), and there are no guarantees as to which cases we'll manage to build
+  ///  an lvalue-to-rvalue conversion in, when parsing a template -- some
+  ///  seemingly harmless change elsewhere in Sema could cause us to start or stop
+  ///  building such a node. So we need a rule that anyone can implement and get
+  ///  exactly the same result".
+  ///    
+  void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
+    assert(isa<DeclRefExpr>(CapturingVarExpr) 
+        || isa<MemberExpr>(CapturingVarExpr));
+    NonODRUsedCapturingExprs.insert(CapturingVarExpr);
+  }
+  bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
+    assert(isa<DeclRefExpr>(CapturingVarExpr) 
+      || isa<MemberExpr>(CapturingVarExpr));
+    return NonODRUsedCapturingExprs.count(CapturingVarExpr);
+  }
+  void removePotentialCapture(Expr *E) {
+    PotentiallyCapturingExprs.erase(
+        std::remove(PotentiallyCapturingExprs.begin(), 
+            PotentiallyCapturingExprs.end(), E), 
+        PotentiallyCapturingExprs.end());
+  }
+  void clearPotentialCaptures() {
+    PotentiallyCapturingExprs.clear();
+    PotentialThisCaptureLocation = SourceLocation();
+  }
+  unsigned getNumPotentialVariableCaptures() const { 
+    return PotentiallyCapturingExprs.size(); 
+  }
+
+  bool hasPotentialCaptures() const { 
+    return getNumPotentialVariableCaptures() || 
+                                  PotentialThisCaptureLocation.isValid(); 
+  }
+
+  // When passed the index, returns the VarDecl and Expr associated
+  // with the index.
+  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
+};
+
+FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
+  : Base(nullptr, false), Property(nullptr) {}
+
+FunctionScopeInfo::WeakObjectProfileTy
+FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
+  FunctionScopeInfo::WeakObjectProfileTy Result;
+  Result.Base.setInt(true);
+  return Result;
+}
+
+template <typename ExprT>
+void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
+  assert(E);
+  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
+  Uses.push_back(WeakUseTy(E, IsRead));
+}
+
+inline void
+CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
+                                   QualType CaptureType, Expr *Cpy) {
+  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
+                             Cpy));
+  CXXThisCaptureIndex = Captures.size();
+
+  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
+    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
+}
+
+} // end namespace sema
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
new file mode 100644
index 0000000..e254afd
--- /dev/null
+++ b/include/clang/Sema/Sema.h
@@ -0,0 +1,8504 @@
+//===--- Sema.h - Semantic Analysis & AST Building --------------*- 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 Sema class, which performs semantic analysis and
+// builds ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SEMA_H
+#define LLVM_CLANG_SEMA_SEMA_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/MangleNumberingContext.h"
+#include "clang/AST/NSAPI.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/ExpressionTraits.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TemplateKinds.h"
+#include "clang/Basic/TypeTraits.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/LocInfoType.h"
+#include "clang/Sema/ObjCMethodList.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/TypoCorrection.h"
+#include "clang/Sema/Weak.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include <deque>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+  class APSInt;
+  template <typename ValueT> struct DenseMapInfo;
+  template <typename ValueT, typename ValueInfoT> class DenseSet;
+  class SmallBitVector;
+  class InlineAsmIdentifierInfo;
+}
+
+namespace clang {
+  class ADLResult;
+  class ASTConsumer;
+  class ASTContext;
+  class ASTMutationListener;
+  class ASTReader;
+  class ASTWriter;
+  class ArrayType;
+  class AttributeList;
+  class BlockDecl;
+  class CapturedDecl;
+  class CXXBasePath;
+  class CXXBasePaths;
+  class CXXBindTemporaryExpr;
+  typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
+  class CXXConstructorDecl;
+  class CXXConversionDecl;
+  class CXXDestructorDecl;
+  class CXXFieldCollector;
+  class CXXMemberCallExpr;
+  class CXXMethodDecl;
+  class CXXScopeSpec;
+  class CXXTemporary;
+  class CXXTryStmt;
+  class CallExpr;
+  class ClassTemplateDecl;
+  class ClassTemplatePartialSpecializationDecl;
+  class ClassTemplateSpecializationDecl;
+  class VarTemplatePartialSpecializationDecl;
+  class CodeCompleteConsumer;
+  class CodeCompletionAllocator;
+  class CodeCompletionTUInfo;
+  class CodeCompletionResult;
+  class Decl;
+  class DeclAccessPair;
+  class DeclContext;
+  class DeclRefExpr;
+  class DeclaratorDecl;
+  class DeducedTemplateArgument;
+  class DependentDiagnostic;
+  class DesignatedInitExpr;
+  class Designation;
+  class EnableIfAttr;
+  class EnumConstantDecl;
+  class Expr;
+  class ExtVectorType;
+  class ExternalSemaSource;
+  class FormatAttr;
+  class FriendDecl;
+  class FunctionDecl;
+  class FunctionProtoType;
+  class FunctionTemplateDecl;
+  class ImplicitConversionSequence;
+  class InitListExpr;
+  class InitializationKind;
+  class InitializationSequence;
+  class InitializedEntity;
+  class IntegerLiteral;
+  class LabelStmt;
+  class LambdaExpr;
+  class LangOptions;
+  class LocalInstantiationScope;
+  class LookupResult;
+  class MacroInfo;
+  typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+  class ModuleLoader;
+  class MultiLevelTemplateArgumentList;
+  class NamedDecl;
+  class NonNullAttr;
+  class ObjCCategoryDecl;
+  class ObjCCategoryImplDecl;
+  class ObjCCompatibleAliasDecl;
+  class ObjCContainerDecl;
+  class ObjCImplDecl;
+  class ObjCImplementationDecl;
+  class ObjCInterfaceDecl;
+  class ObjCIvarDecl;
+  template <class T> class ObjCList;
+  class ObjCMessageExpr;
+  class ObjCMethodDecl;
+  class ObjCPropertyDecl;
+  class ObjCProtocolDecl;
+  class OMPThreadPrivateDecl;
+  class OMPClause;
+  class OverloadCandidateSet;
+  class OverloadExpr;
+  class ParenListExpr;
+  class ParmVarDecl;
+  class Preprocessor;
+  class PseudoDestructorTypeStorage;
+  class PseudoObjectExpr;
+  class QualType;
+  class StandardConversionSequence;
+  class Stmt;
+  class StringLiteral;
+  class SwitchStmt;
+  class TemplateArgument;
+  class TemplateArgumentList;
+  class TemplateArgumentLoc;
+  class TemplateDecl;
+  class TemplateParameterList;
+  class TemplatePartialOrderingContext;
+  class TemplateTemplateParmDecl;
+  class Token;
+  class TypeAliasDecl;
+  class TypedefDecl;
+  class TypedefNameDecl;
+  class TypeLoc;
+  class UnqualifiedId;
+  class UnresolvedLookupExpr;
+  class UnresolvedMemberExpr;
+  class UnresolvedSetImpl;
+  class UnresolvedSetIterator;
+  class UsingDecl;
+  class UsingShadowDecl;
+  class ValueDecl;
+  class VarDecl;
+  class VarTemplateSpecializationDecl;
+  class VisibilityAttr;
+  class VisibleDeclConsumer;
+  class IndirectFieldDecl;
+  struct DeductionFailureInfo;
+  class TemplateSpecCandidateSet;
+
+namespace sema {
+  class AccessedEntity;
+  class BlockScopeInfo;
+  class CapturedRegionScopeInfo;
+  class CapturingScopeInfo;
+  class CompoundScopeInfo;
+  class DelayedDiagnostic;
+  class DelayedDiagnosticPool;
+  class FunctionScopeInfo;
+  class LambdaScopeInfo;
+  class PossiblyUnreachableDiag;
+  class TemplateDeductionInfo;
+}
+
+// FIXME: No way to easily map from TemplateTypeParmTypes to
+// TemplateTypeParmDecls, so we have this horrible PointerUnion.
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>,
+                  SourceLocation> UnexpandedParameterPack;
+
+/// Sema - This implements semantic analysis and AST building for C.
+class Sema {
+  Sema(const Sema &) LLVM_DELETED_FUNCTION;
+  void operator=(const Sema &) LLVM_DELETED_FUNCTION;
+
+  ///\brief Source of additional semantic information.
+  ExternalSemaSource *ExternalSource;
+
+  ///\brief Whether Sema has generated a multiplexer and has to delete it.
+  bool isMultiplexExternalSource;
+
+  static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
+
+  static bool
+  shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, const NamedDecl *New) {
+    // We are about to link these. It is now safe to compute the linkage of
+    // the new decl. If the new decl has external linkage, we will
+    // link it with the hidden decl (which also has external linkage) and
+    // it will keep having external linkage. If it has internal linkage, we
+    // will not link it. Since it has no previous decls, it will remain
+    // with internal linkage.
+    return !Old->isHidden() || New->isExternallyVisible();
+  }
+
+public:
+  typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
+  typedef OpaquePtr<TemplateName> TemplateTy;
+  typedef OpaquePtr<QualType> TypeTy;
+
+  OpenCLOptions OpenCLFeatures;
+  FPOptions FPFeatures;
+
+  const LangOptions &LangOpts;
+  Preprocessor &PP;
+  ASTContext &Context;
+  ASTConsumer &Consumer;
+  DiagnosticsEngine &Diags;
+  SourceManager &SourceMgr;
+
+  /// \brief Flag indicating whether or not to collect detailed statistics.
+  bool CollectStats;
+
+  /// \brief Code-completion consumer.
+  CodeCompleteConsumer *CodeCompleter;
+
+  /// CurContext - This is the current declaration context of parsing.
+  DeclContext *CurContext;
+
+  /// \brief Generally null except when we temporarily switch decl contexts,
+  /// like in \see ActOnObjCTemporaryExitContainerContext.
+  DeclContext *OriginalLexicalContext;
+
+  /// VAListTagName - The declaration name corresponding to __va_list_tag.
+  /// This is used as part of a hack to omit that class from ADL results.
+  DeclarationName VAListTagName;
+
+  /// PackContext - Manages the stack for \#pragma pack. An alignment
+  /// of 0 indicates default alignment.
+  void *PackContext; // Really a "PragmaPackStack*"
+
+  bool MSStructPragmaOn; // True when \#pragma ms_struct on
+
+  /// \brief Controls member pointer representation format under the MS ABI.
+  LangOptions::PragmaMSPointersToMembersKind
+      MSPointerToMemberRepresentationMethod;
+
+  enum PragmaVtorDispKind {
+    PVDK_Push,          ///< #pragma vtordisp(push, mode)
+    PVDK_Set,           ///< #pragma vtordisp(mode)
+    PVDK_Pop,           ///< #pragma vtordisp(pop)
+    PVDK_Reset          ///< #pragma vtordisp()
+  };
+
+  enum PragmaMsStackAction {
+    PSK_Reset,    // #pragma ()
+    PSK_Set,      // #pragma ("name")
+    PSK_Push,     // #pragma (push[, id])
+    PSK_Push_Set, // #pragma (push[, id], "name")
+    PSK_Pop,      // #pragma (pop[, id])
+    PSK_Pop_Set,  // #pragma (pop[, id], "name")
+  };
+
+  /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
+  /// C++ ABI.  Possible values are 0, 1, and 2, which mean:
+  ///
+  /// 0: Suppress all vtordisps
+  /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial
+  ///    structors
+  /// 2: Always insert vtordisps to support RTTI on partially constructed
+  ///    objects
+  ///
+  /// The stack always has at least one element in it.
+  SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack;
+
+  /// \brief Source location for newly created implicit MSInheritanceAttrs
+  SourceLocation ImplicitMSInheritanceAttrLoc;
+
+  template<typename ValueType>
+  struct PragmaStack {
+    struct Slot {
+      llvm::StringRef StackSlotLabel;
+      ValueType Value;
+      SourceLocation PragmaLocation;
+      Slot(llvm::StringRef StackSlotLabel,
+           ValueType Value,
+           SourceLocation PragmaLocation)
+        : StackSlotLabel(StackSlotLabel), Value(Value),
+          PragmaLocation(PragmaLocation) {}
+    };
+    void Act(SourceLocation PragmaLocation,
+             PragmaMsStackAction Action,
+             llvm::StringRef StackSlotLabel,
+             ValueType Value);
+    explicit PragmaStack(const ValueType &Value)
+      : CurrentValue(Value) {}
+    SmallVector<Slot, 2> Stack;
+    ValueType CurrentValue;
+    SourceLocation CurrentPragmaLocation;
+  };
+  // FIXME: We should serialize / deserialize these if they occur in a PCH (but
+  // we shouldn't do so if they're in a module).
+  PragmaStack<StringLiteral *> DataSegStack;
+  PragmaStack<StringLiteral *> BSSSegStack;
+  PragmaStack<StringLiteral *> ConstSegStack;
+  PragmaStack<StringLiteral *> CodeSegStack;
+
+  /// Last section used with #pragma init_seg.
+  StringLiteral *CurInitSeg;
+  SourceLocation CurInitSegLoc;
+
+  /// VisContext - Manages the stack for \#pragma GCC visibility.
+  void *VisContext; // Really a "PragmaVisStack*"
+
+  /// \brief This represents the last location of a "#pragma clang optimize off"
+  /// directive if such a directive has not been closed by an "on" yet. If
+  /// optimizations are currently "on", this is set to an invalid location.
+  SourceLocation OptimizeOffPragmaLocation;
+
+  /// \brief Flag indicating if Sema is building a recovery call expression.
+  ///
+  /// This flag is used to avoid building recovery call expressions
+  /// if Sema is already doing so, which would cause infinite recursions.
+  bool IsBuildingRecoveryCallExpr;
+
+  /// ExprNeedsCleanups - True if the current evaluation context
+  /// requires cleanups to be run at its conclusion.
+  bool ExprNeedsCleanups;
+
+  /// ExprCleanupObjects - This is the stack of objects requiring
+  /// cleanup that are created by the current full expression.  The
+  /// element type here is ExprWithCleanups::Object.
+  SmallVector<BlockDecl*, 8> ExprCleanupObjects;
+
+  /// \brief Store a list of either DeclRefExprs or MemberExprs
+  ///  that contain a reference to a variable (constant) that may or may not
+  ///  be odr-used in this Expr, and we won't know until all lvalue-to-rvalue
+  ///  and discarded value conversions have been applied to all subexpressions 
+  ///  of the enclosing full expression.  This is cleared at the end of each 
+  ///  full expression. 
+  llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
+
+  /// \brief Stack containing information about each of the nested
+  /// function, block, and method scopes that are currently active.
+  ///
+  /// This array is never empty.  Clients should ignore the first
+  /// element, which is used to cache a single FunctionScopeInfo
+  /// that's used to parse every top-level function.
+  SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
+
+  typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
+                     &ExternalSemaSource::ReadExtVectorDecls, 2, 2>
+    ExtVectorDeclsType;
+
+  /// ExtVectorDecls - This is a list all the extended vector types. This allows
+  /// us to associate a raw vector type with one of the ext_vector type names.
+  /// This is only necessary for issuing pretty diagnostics.
+  ExtVectorDeclsType ExtVectorDecls;
+
+  /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
+  std::unique_ptr<CXXFieldCollector> FieldCollector;
+
+  typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType;
+
+  /// \brief Set containing all declared private fields that are not used.
+  NamedDeclSetType UnusedPrivateFields;
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
+
+  /// PureVirtualClassDiagSet - a set of class declarations which we have
+  /// emitted a list of pure virtual functions. Used to prevent emitting the
+  /// same list more than once.
+  std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet;
+
+  /// ParsingInitForAutoVars - a set of declarations with auto types for which
+  /// we are currently parsing the initializer.
+  llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars;
+
+  /// \brief A mapping from external names to the most recent
+  /// locally-scoped extern "C" declaration with that name.
+  ///
+  /// This map contains external declarations introduced in local
+  /// scopes, e.g.,
+  ///
+  /// \code
+  /// extern "C" void f() {
+  ///   void foo(int, int);
+  /// }
+  /// \endcode
+  ///
+  /// Here, the name "foo" will be associated with the declaration of
+  /// "foo" within f. This name is not visible outside of
+  /// "f". However, we still find it in two cases:
+  ///
+  ///   - If we are declaring another global or extern "C" entity with
+  ///     the name "foo", we can find "foo" as a previous declaration,
+  ///     so that the types of this external declaration can be checked
+  ///     for compatibility.
+  ///
+  ///   - If we would implicitly declare "foo" (e.g., due to a call to
+  ///     "foo" in C when no prototype or definition is visible), then
+  ///     we find this declaration of "foo" and complain that it is
+  ///     not visible.
+  llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls;
+
+  /// \brief Look for a locally scoped extern "C" declaration by the given name.
+  NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name);
+
+  typedef LazyVector<VarDecl *, ExternalSemaSource,
+                     &ExternalSemaSource::ReadTentativeDefinitions, 2, 2>
+    TentativeDefinitionsType;
+
+  /// \brief All the tentative definitions encountered in the TU.
+  TentativeDefinitionsType TentativeDefinitions;
+
+  typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource,
+                     &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2>
+    UnusedFileScopedDeclsType;
+
+  /// \brief The set of file scoped decls seen so far that have not been used
+  /// and must warn if not used. Only contains the first declaration.
+  UnusedFileScopedDeclsType UnusedFileScopedDecls;
+
+  typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource,
+                     &ExternalSemaSource::ReadDelegatingConstructors, 2, 2>
+    DelegatingCtorDeclsType;
+
+  /// \brief All the delegating constructors seen so far in the file, used for
+  /// cycle detection at the end of the TU.
+  DelegatingCtorDeclsType DelegatingCtorDecls;
+
+  /// \brief All the overriding destructors seen during a class definition
+  /// (there could be multiple due to nested classes) that had their exception
+  /// spec checks delayed, plus the overridden destructor.
+  SmallVector<std::pair<const CXXDestructorDecl*,
+                              const CXXDestructorDecl*>, 2>
+      DelayedDestructorExceptionSpecChecks;
+
+  /// \brief All the members seen during a class definition which were both
+  /// explicitly defaulted and had explicitly-specified exception
+  /// specifications, along with the function type containing their
+  /// user-specified exception specification. Those exception specifications
+  /// were overridden with the default specifications, but we still need to
+  /// check whether they are compatible with the default specification, and
+  /// we can't do that until the nesting set of class definitions is complete.
+  SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
+    DelayedDefaultedMemberExceptionSpecs;
+
+  typedef llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *>
+  LateParsedTemplateMapT;
+  LateParsedTemplateMapT LateParsedTemplateMap;
+
+  /// \brief Callback to the parser to parse templated functions when needed.
+  typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT);
+  LateTemplateParserCB *LateTemplateParser;
+  void *OpaqueParser;
+
+  void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) {
+    LateTemplateParser = LTP;
+    OpaqueParser = P;
+  }
+
+  class DelayedDiagnostics;
+
+  class DelayedDiagnosticsState {
+    sema::DelayedDiagnosticPool *SavedPool;
+    friend class Sema::DelayedDiagnostics;
+  };
+  typedef DelayedDiagnosticsState ParsingDeclState;
+  typedef DelayedDiagnosticsState ProcessingContextState;
+
+  /// A class which encapsulates the logic for delaying diagnostics
+  /// during parsing and other processing.
+  class DelayedDiagnostics {
+    /// \brief The current pool of diagnostics into which delayed
+    /// diagnostics should go.
+    sema::DelayedDiagnosticPool *CurPool;
+
+  public:
+    DelayedDiagnostics() : CurPool(nullptr) {}
+
+    /// Adds a delayed diagnostic.
+    void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
+
+    /// Determines whether diagnostics should be delayed.
+    bool shouldDelayDiagnostics() { return CurPool != nullptr; }
+
+    /// Returns the current delayed-diagnostics pool.
+    sema::DelayedDiagnosticPool *getCurrentPool() const {
+      return CurPool;
+    }
+
+    /// Enter a new scope.  Access and deprecation diagnostics will be
+    /// collected in this pool.
+    DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) {
+      DelayedDiagnosticsState state;
+      state.SavedPool = CurPool;
+      CurPool = &pool;
+      return state;
+    }
+
+    /// Leave a delayed-diagnostic state that was previously pushed.
+    /// Do not emit any of the diagnostics.  This is performed as part
+    /// of the bookkeeping of popping a pool "properly".
+    void popWithoutEmitting(DelayedDiagnosticsState state) {
+      CurPool = state.SavedPool;
+    }
+
+    /// Enter a new scope where access and deprecation diagnostics are
+    /// not delayed.
+    DelayedDiagnosticsState pushUndelayed() {
+      DelayedDiagnosticsState state;
+      state.SavedPool = CurPool;
+      CurPool = nullptr;
+      return state;
+    }
+
+    /// Undo a previous pushUndelayed().
+    void popUndelayed(DelayedDiagnosticsState state) {
+      assert(CurPool == nullptr);
+      CurPool = state.SavedPool;
+    }
+  } DelayedDiagnostics;
+
+  /// A RAII object to temporarily push a declaration context.
+  class ContextRAII {
+  private:
+    Sema &S;
+    DeclContext *SavedContext;
+    ProcessingContextState SavedContextState;
+    QualType SavedCXXThisTypeOverride;
+
+  public:
+    ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
+      : S(S), SavedContext(S.CurContext),
+        SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
+        SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
+    {
+      assert(ContextToPush && "pushing null context");
+      S.CurContext = ContextToPush;
+      if (NewThisContext)
+        S.CXXThisTypeOverride = QualType();
+    }
+
+    void pop() {
+      if (!SavedContext) return;
+      S.CurContext = SavedContext;
+      S.DelayedDiagnostics.popUndelayed(SavedContextState);
+      S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
+      SavedContext = nullptr;
+    }
+
+    ~ContextRAII() {
+      pop();
+    }
+  };
+
+  /// \brief RAII object to handle the state changes required to synthesize
+  /// a function body.
+  class SynthesizedFunctionScope {
+    Sema &S;
+    Sema::ContextRAII SavedContext;
+    
+  public:
+    SynthesizedFunctionScope(Sema &S, DeclContext *DC)
+      : S(S), SavedContext(S, DC) 
+    {
+      S.PushFunctionScope();
+      S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+    }
+    
+    ~SynthesizedFunctionScope() {
+      S.PopExpressionEvaluationContext();
+      S.PopFunctionScopeInfo();
+    }
+  };
+
+  /// WeakUndeclaredIdentifiers - Identifiers contained in
+  /// \#pragma weak before declared. rare. may alias another
+  /// identifier, declared or undeclared
+  llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
+
+  /// ExtnameUndeclaredIdentifiers - Identifiers contained in
+  /// \#pragma redefine_extname before declared.  Used in Solaris system headers
+  /// to define functions that occur in multiple standards to call the version
+  /// in the currently selected standard.
+  llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers;
+
+
+  /// \brief Load weak undeclared identifiers from the external source.
+  void LoadExternalWeakUndeclaredIdentifiers();
+
+  /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
+  /// \#pragma weak during processing of other Decls.
+  /// I couldn't figure out a clean way to generate these in-line, so
+  /// we store them here and handle separately -- which is a hack.
+  /// It would be best to refactor this.
+  SmallVector<Decl*,2> WeakTopLevelDecl;
+
+  IdentifierResolver IdResolver;
+
+  /// Translation Unit Scope - useful to Objective-C actions that need
+  /// to lookup file scope declarations in the "ordinary" C decl namespace.
+  /// For example, user-defined classes, built-in "id" type, etc.
+  Scope *TUScope;
+
+  /// \brief The C++ "std" namespace, where the standard library resides.
+  LazyDeclPtr StdNamespace;
+
+  /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
+  /// standard library.
+  LazyDeclPtr StdBadAlloc;
+
+  /// \brief The C++ "std::initializer_list" template, which is defined in
+  /// \<initializer_list>.
+  ClassTemplateDecl *StdInitializerList;
+
+  /// \brief The C++ "type_info" declaration, which is defined in \<typeinfo>.
+  RecordDecl *CXXTypeInfoDecl;
+
+  /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files.
+  RecordDecl *MSVCGuidDecl;
+
+  /// \brief Caches identifiers/selectors for NSFoundation APIs.
+  std::unique_ptr<NSAPI> NSAPIObj;
+
+  /// \brief The declaration of the Objective-C NSNumber class.
+  ObjCInterfaceDecl *NSNumberDecl;
+
+  /// \brief Pointer to NSNumber type (NSNumber *).
+  QualType NSNumberPointer;
+
+  /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
+  ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
+
+  /// \brief The declaration of the Objective-C NSString class.
+  ObjCInterfaceDecl *NSStringDecl;
+
+  /// \brief Pointer to NSString type (NSString *).
+  QualType NSStringPointer;
+
+  /// \brief The declaration of the stringWithUTF8String: method.
+  ObjCMethodDecl *StringWithUTF8StringMethod;
+
+  /// \brief The declaration of the Objective-C NSArray class.
+  ObjCInterfaceDecl *NSArrayDecl;
+
+  /// \brief The declaration of the arrayWithObjects:count: method.
+  ObjCMethodDecl *ArrayWithObjectsMethod;
+
+  /// \brief The declaration of the Objective-C NSDictionary class.
+  ObjCInterfaceDecl *NSDictionaryDecl;
+
+  /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method.
+  ObjCMethodDecl *DictionaryWithObjectsMethod;
+
+  /// \brief id<NSCopying> type.
+  QualType QIDNSCopying;
+
+  /// \brief will hold 'respondsToSelector:'
+  Selector RespondsToSelectorSel;
+  
+  /// A flag to remember whether the implicit forms of operator new and delete
+  /// have been declared.
+  bool GlobalNewDeleteDeclared;
+
+  /// A flag to indicate that we're in a context that permits abstract
+  /// references to fields.  This is really a 
+  bool AllowAbstractFieldReference;
+
+  /// \brief Describes how the expressions currently being parsed are
+  /// evaluated at run-time, if at all.
+  enum ExpressionEvaluationContext {
+    /// \brief The current expression and its subexpressions occur within an
+    /// unevaluated operand (C++11 [expr]p7), such as the subexpression of
+    /// \c sizeof, where the type of the expression may be significant but
+    /// no code will be generated to evaluate the value of the expression at
+    /// run time.
+    Unevaluated,
+
+    /// \brief The current expression occurs within an unevaluated
+    /// operand that unconditionally permits abstract references to
+    /// fields, such as a SIZE operator in MS-style inline assembly.
+    UnevaluatedAbstract,
+
+    /// \brief The current context is "potentially evaluated" in C++11 terms,
+    /// but the expression is evaluated at compile-time (like the values of
+    /// cases in a switch statement).
+    ConstantEvaluated,
+
+    /// \brief The current expression is potentially evaluated at run time,
+    /// which means that code may be generated to evaluate the value of the
+    /// expression at run time.
+    PotentiallyEvaluated,
+
+    /// \brief The current expression is potentially evaluated, but any
+    /// declarations referenced inside that expression are only used if
+    /// in fact the current expression is used.
+    ///
+    /// This value is used when parsing default function arguments, for which
+    /// we would like to provide diagnostics (e.g., passing non-POD arguments
+    /// through varargs) but do not want to mark declarations as "referenced"
+    /// until the default argument is used.
+    PotentiallyEvaluatedIfUsed
+  };
+
+  /// \brief Data structure used to record current or nested
+  /// expression evaluation contexts.
+  struct ExpressionEvaluationContextRecord {
+    /// \brief The expression evaluation context.
+    ExpressionEvaluationContext Context;
+
+    /// \brief Whether the enclosing context needed a cleanup.
+    bool ParentNeedsCleanups;
+
+    /// \brief Whether we are in a decltype expression.
+    bool IsDecltype;
+
+    /// \brief The number of active cleanup objects when we entered
+    /// this expression evaluation context.
+    unsigned NumCleanupObjects;
+
+    llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
+
+    /// \brief The lambdas that are present within this context, if it
+    /// is indeed an unevaluated context.
+    SmallVector<LambdaExpr *, 2> Lambdas;
+
+    /// \brief The declaration that provides context for lambda expressions
+    /// and block literals if the normal declaration context does not
+    /// suffice, e.g., in a default function argument.
+    Decl *ManglingContextDecl;
+
+    /// \brief The context information used to mangle lambda expressions
+    /// and block literals within this context.
+    ///
+    /// This mangling information is allocated lazily, since most contexts
+    /// do not have lambda expressions or block literals.
+    IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering;
+
+    /// \brief If we are processing a decltype type, a set of call expressions
+    /// for which we have deferred checking the completeness of the return type.
+    SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
+
+    /// \brief If we are processing a decltype type, a set of temporary binding
+    /// expressions for which we have deferred checking the destructor.
+    SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
+
+    ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
+                                      unsigned NumCleanupObjects,
+                                      bool ParentNeedsCleanups,
+                                      Decl *ManglingContextDecl,
+                                      bool IsDecltype)
+      : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
+        IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
+        ManglingContextDecl(ManglingContextDecl), MangleNumbering() { }
+
+    /// \brief Retrieve the mangling numbering context, used to consistently
+    /// number constructs like lambdas for mangling.
+    MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
+
+    bool isUnevaluated() const {
+      return Context == Unevaluated || Context == UnevaluatedAbstract;
+    }
+  };
+
+  /// A stack of expression evaluation contexts.
+  SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
+
+  /// \brief Compute the mangling number context for a lambda expression or
+  /// block literal.
+  ///
+  /// \param DC - The DeclContext containing the lambda expression or
+  /// block literal.
+  /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl
+  /// associated with the context, if relevant.
+  MangleNumberingContext *getCurrentMangleNumberContext(
+    const DeclContext *DC,
+    Decl *&ManglingContextDecl);
+
+
+  /// SpecialMemberOverloadResult - The overloading result for a special member
+  /// function.
+  ///
+  /// This is basically a wrapper around PointerIntPair. The lowest bits of the
+  /// integer are used to determine whether overload resolution succeeded.
+  class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
+  public:
+    enum Kind {
+      NoMemberOrDeleted,
+      Ambiguous,
+      Success
+    };
+
+  private:
+    llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
+
+  public:
+    SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
+      : FastFoldingSetNode(ID)
+    {}
+
+    CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
+    void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
+
+    Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
+    void setKind(Kind K) { Pair.setInt(K); }
+  };
+
+  /// \brief A cache of special member function overload resolution results
+  /// for C++ records.
+  llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache;
+
+  /// \brief The kind of translation unit we are processing.
+  ///
+  /// When we're processing a complete translation unit, Sema will perform
+  /// end-of-translation-unit semantic tasks (such as creating
+  /// initializers for tentative definitions in C) once parsing has
+  /// completed. Modules and precompiled headers perform different kinds of
+  /// checks.
+  TranslationUnitKind TUKind;
+
+  llvm::BumpPtrAllocator BumpAlloc;
+
+  /// \brief The number of SFINAE diagnostics that have been trapped.
+  unsigned NumSFINAEErrors;
+
+  typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>>
+    UnparsedDefaultArgInstantiationsMap;
+
+  /// \brief A mapping from parameters with unparsed default arguments to the
+  /// set of instantiations of each parameter.
+  ///
+  /// This mapping is a temporary data structure used when parsing
+  /// nested class templates or nested classes of class templates,
+  /// where we might end up instantiating an inner class before the
+  /// default arguments of its methods have been parsed.
+  UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations;
+
+  // Contains the locations of the beginning of unparsed default
+  // argument locations.
+  llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs;
+
+  /// UndefinedInternals - all the used, undefined objects which require a
+  /// definition in this translation unit.
+  llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed;
+
+  /// Obtain a sorted list of functions that are undefined but ODR-used.
+  void getUndefinedButUsed(
+      SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
+
+  typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
+  typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
+
+  /// Method Pool - allows efficient lookup when typechecking messages to "id".
+  /// We need to maintain a list, since selectors can have differing signatures
+  /// across classes. In Cocoa, this happens to be extremely uncommon (only 1%
+  /// of selectors are "overloaded").
+  /// At the head of the list it is recorded whether there were 0, 1, or >= 2
+  /// methods inside categories with a particular selector.
+  GlobalMethodPool MethodPool;
+
+  /// Method selectors used in a \@selector expression. Used for implementation
+  /// of -Wselector.
+  llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors;
+
+  /// Kinds of C++ special members.
+  enum CXXSpecialMember {
+    CXXDefaultConstructor,
+    CXXCopyConstructor,
+    CXXMoveConstructor,
+    CXXCopyAssignment,
+    CXXMoveAssignment,
+    CXXDestructor,
+    CXXInvalid
+  };
+
+  typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl;
+
+  /// The C++ special members which we are currently in the process of
+  /// declaring. If this process recursively triggers the declaration of the
+  /// same special member, we should act as if it is not yet declared.
+  llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
+
+  void ReadMethodPool(Selector Sel);
+
+  /// Private Helper predicate to check for 'self'.
+  bool isSelfExpr(Expr *RExpr);
+  bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method);
+
+  /// \brief Cause the active diagnostic on the DiagosticsEngine to be
+  /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and
+  /// should not be used elsewhere.
+  void EmitCurrentDiagnostic(unsigned DiagID);
+
+  /// Records and restores the FP_CONTRACT state on entry/exit of compound
+  /// statements.
+  class FPContractStateRAII {
+  public:
+    FPContractStateRAII(Sema& S)
+      : S(S), OldFPContractState(S.FPFeatures.fp_contract) {}
+    ~FPContractStateRAII() {
+      S.FPFeatures.fp_contract = OldFPContractState;
+    }
+  private:
+    Sema& S;
+    bool OldFPContractState : 1;
+  };
+
+  void addImplicitTypedef(StringRef Name, QualType T);
+
+public:
+  Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
+       TranslationUnitKind TUKind = TU_Complete,
+       CodeCompleteConsumer *CompletionConsumer = nullptr);
+  ~Sema();
+
+  /// \brief Perform initialization that occurs after the parser has been
+  /// initialized but before it parses anything.
+  void Initialize();
+
+  const LangOptions &getLangOpts() const { return LangOpts; }
+  OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
+  FPOptions     &getFPOptions() { return FPFeatures; }
+
+  DiagnosticsEngine &getDiagnostics() const { return Diags; }
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  Preprocessor &getPreprocessor() const { return PP; }
+  ASTContext &getASTContext() const { return Context; }
+  ASTConsumer &getASTConsumer() const { return Consumer; }
+  ASTMutationListener *getASTMutationListener() const;
+  ExternalSemaSource* getExternalSource() const { return ExternalSource; }
+
+  ///\brief Registers an external source. If an external source already exists,
+  /// creates a multiplex external source and appends to it.
+  ///
+  ///\param[in] E - A non-null external sema source.
+  ///
+  void addExternalSource(ExternalSemaSource *E);
+
+  void PrintStats() const;
+
+  /// \brief Helper class that creates diagnostics with optional
+  /// template instantiation stacks.
+  ///
+  /// This class provides a wrapper around the basic DiagnosticBuilder
+  /// class that emits diagnostics. SemaDiagnosticBuilder is
+  /// responsible for emitting the diagnostic (as DiagnosticBuilder
+  /// does) and, if the diagnostic comes from inside a template
+  /// instantiation, printing the template instantiation stack as
+  /// well.
+  class SemaDiagnosticBuilder : public DiagnosticBuilder {
+    Sema &SemaRef;
+    unsigned DiagID;
+
+  public:
+    SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
+      : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
+
+    ~SemaDiagnosticBuilder() {
+      // If we aren't active, there is nothing to do.
+      if (!isActive()) return;
+
+      // Otherwise, we need to emit the diagnostic. First flush the underlying
+      // DiagnosticBuilder data, and clear the diagnostic builder itself so it
+      // won't emit the diagnostic in its own destructor.
+      //
+      // This seems wasteful, in that as written the DiagnosticBuilder dtor will
+      // do its own needless checks to see if the diagnostic needs to be
+      // emitted. However, because we take care to ensure that the builder
+      // objects never escape, a sufficiently smart compiler will be able to
+      // eliminate that code.
+      FlushCounts();
+      Clear();
+
+      // Dispatch to Sema to emit the diagnostic.
+      SemaRef.EmitCurrentDiagnostic(DiagID);
+    }
+
+    /// Teach operator<< to produce an object of the correct type.
+    template<typename T>
+    friend const SemaDiagnosticBuilder &operator<<(
+        const SemaDiagnosticBuilder &Diag, const T &Value) {
+      const DiagnosticBuilder &BaseDiag = Diag;
+      BaseDiag << Value;
+      return Diag;
+    }
+  };
+
+  /// \brief Emit a diagnostic.
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+    DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
+    return SemaDiagnosticBuilder(DB, *this, DiagID);
+  }
+
+  /// \brief Emit a partial diagnostic.
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
+
+  /// \brief Build a partial diagnostic.
+  PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h
+
+  bool findMacroSpelling(SourceLocation &loc, StringRef name);
+
+  /// \brief Get a string to suggest for zero-initialization of a type.
+  std::string
+  getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const;
+  std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const;
+
+  /// \brief Calls \c Lexer::getLocForEndOfToken()
+  SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
+
+  /// \brief Retrieve the module loader associated with the preprocessor.
+  ModuleLoader &getModuleLoader() const;
+
+  void ActOnEndOfTranslationUnit();
+
+  void CheckDelegatingCtorCycles();
+
+  Scope *getScopeForContext(DeclContext *Ctx);
+
+  void PushFunctionScope();
+  void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
+  sema::LambdaScopeInfo *PushLambdaScope();
+
+  /// \brief This is used to inform Sema what the current TemplateParameterDepth
+  /// is during Parsing.  Currently it is used to pass on the depth
+  /// when parsing generic lambda 'auto' parameters.
+  void RecordParsingTemplateParameterDepth(unsigned Depth);
+  
+  void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
+                               RecordDecl *RD,
+                               CapturedRegionKind K);
+  void
+  PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr,
+                       const Decl *D = nullptr,
+                       const BlockExpr *blkExpr = nullptr);
+
+  sema::FunctionScopeInfo *getCurFunction() const {
+    return FunctionScopes.back();
+  }
+  
+  sema::FunctionScopeInfo *getEnclosingFunction() const {
+    if (FunctionScopes.empty())
+      return nullptr;
+    
+    for (int e = FunctionScopes.size()-1; e >= 0; --e) {
+      if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
+        continue;
+      return FunctionScopes[e];
+    }
+    return nullptr;
+  }
+  
+  template <typename ExprT>
+  void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
+    if (!isUnevaluatedContext())
+      getCurFunction()->recordUseOfWeak(E, IsRead);
+  }
+  
+  void PushCompoundScope();
+  void PopCompoundScope();
+
+  sema::CompoundScopeInfo &getCurCompoundScope() const;
+
+  bool hasAnyUnrecoverableErrorsInThisFunction() const;
+
+  /// \brief Retrieve the current block, if any.
+  sema::BlockScopeInfo *getCurBlock();
+
+  /// \brief Retrieve the current lambda scope info, if any.
+  sema::LambdaScopeInfo *getCurLambda();
+
+  /// \brief Retrieve the current generic lambda info, if any.
+  sema::LambdaScopeInfo *getCurGenericLambda();
+
+  /// \brief Retrieve the current captured region, if any.
+  sema::CapturedRegionScopeInfo *getCurCapturedRegion();
+
+  /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls
+  SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
+
+  void ActOnComment(SourceRange Comment);
+
+  //===--------------------------------------------------------------------===//
+  // Type Analysis / Processing: SemaType.cpp.
+  //
+
+  QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs,
+                              const DeclSpec *DS = nullptr);
+  QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA,
+                              const DeclSpec *DS = nullptr);
+  QualType BuildPointerType(QualType T,
+                            SourceLocation Loc, DeclarationName Entity);
+  QualType BuildReferenceType(QualType T, bool LValueRef,
+                              SourceLocation Loc, DeclarationName Entity);
+  QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
+                          Expr *ArraySize, unsigned Quals,
+                          SourceRange Brackets, DeclarationName Entity);
+  QualType BuildExtVectorType(QualType T, Expr *ArraySize,
+                              SourceLocation AttrLoc);
+
+  bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
+
+  /// \brief Build a function type.
+  ///
+  /// This routine checks the function type according to C++ rules and
+  /// under the assumption that the result type and parameter types have
+  /// just been instantiated from a template. It therefore duplicates
+  /// some of the behavior of GetTypeForDeclarator, but in a much
+  /// simpler form that is only suitable for this narrow use case.
+  ///
+  /// \param T The return type of the function.
+  ///
+  /// \param ParamTypes The parameter types of the function. This array
+  /// will be modified to account for adjustments to the types of the
+  /// function parameters.
+  ///
+  /// \param Loc The location of the entity whose type involves this
+  /// function type or, if there is no such entity, the location of the
+  /// type that will have function type.
+  ///
+  /// \param Entity The name of the entity that involves the function
+  /// type, if known.
+  ///
+  /// \param EPI Extra information about the function type. Usually this will
+  /// be taken from an existing function with the same prototype.
+  ///
+  /// \returns A suitable function type, if there are no errors. The
+  /// unqualified type will always be a FunctionProtoType.
+  /// Otherwise, returns a NULL type.
+  QualType BuildFunctionType(QualType T,
+                             MutableArrayRef<QualType> ParamTypes,
+                             SourceLocation Loc, DeclarationName Entity,
+                             const FunctionProtoType::ExtProtoInfo &EPI);
+
+  QualType BuildMemberPointerType(QualType T, QualType Class,
+                                  SourceLocation Loc,
+                                  DeclarationName Entity);
+  QualType BuildBlockPointerType(QualType T,
+                                 SourceLocation Loc, DeclarationName Entity);
+  QualType BuildParenType(QualType T);
+  QualType BuildAtomicType(QualType T, SourceLocation Loc);
+
+  TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
+  TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
+  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
+                                               TypeSourceInfo *ReturnTypeInfo);
+
+  /// \brief Package the given type and TSI into a ParsedType.
+  ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
+  DeclarationNameInfo GetNameForDeclarator(Declarator &D);
+  DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
+  static QualType GetTypeFromParser(ParsedType Ty,
+                                    TypeSourceInfo **TInfo = nullptr);
+  CanThrowResult canThrow(const Expr *E);
+  const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
+                                                const FunctionProtoType *FPT);
+  void UpdateExceptionSpec(FunctionDecl *FD,
+                           const FunctionProtoType::ExtProtoInfo &EPI);
+  bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range);
+  bool CheckDistantExceptionSpec(QualType T);
+  bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
+  bool CheckEquivalentExceptionSpec(
+      const FunctionProtoType *Old, SourceLocation OldLoc,
+      const FunctionProtoType *New, SourceLocation NewLoc);
+  bool CheckEquivalentExceptionSpec(
+      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Old, SourceLocation OldLoc,
+      const FunctionProtoType *New, SourceLocation NewLoc,
+      bool *MissingExceptionSpecification = nullptr,
+      bool *MissingEmptyExceptionSpecification = nullptr,
+      bool AllowNoexceptAllMatchWithNoSpec = false,
+      bool IsOperatorNew = false);
+  bool CheckExceptionSpecSubset(
+      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Superset, SourceLocation SuperLoc,
+      const FunctionProtoType *Subset, SourceLocation SubLoc);
+  bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
+      const FunctionProtoType *Target, SourceLocation TargetLoc,
+      const FunctionProtoType *Source, SourceLocation SourceLoc);
+
+  TypeResult ActOnTypeName(Scope *S, Declarator &D);
+
+  /// \brief The parser has parsed the context-sensitive type 'instancetype'
+  /// in an Objective-C message declaration. Return the appropriate type.
+  ParsedType ActOnObjCInstanceType(SourceLocation Loc);
+
+  /// \brief Abstract class used to diagnose incomplete types.
+  struct TypeDiagnoser {
+    bool Suppressed;
+
+    TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { }
+
+    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0;
+    virtual ~TypeDiagnoser() {}
+  };
+
+  static int getPrintable(int I) { return I; }
+  static unsigned getPrintable(unsigned I) { return I; }
+  static bool getPrintable(bool B) { return B; }
+  static const char * getPrintable(const char *S) { return S; }
+  static StringRef getPrintable(StringRef S) { return S; }
+  static const std::string &getPrintable(const std::string &S) { return S; }
+  static const IdentifierInfo *getPrintable(const IdentifierInfo *II) {
+    return II;
+  }
+  static DeclarationName getPrintable(DeclarationName N) { return N; }
+  static QualType getPrintable(QualType T) { return T; }
+  static SourceRange getPrintable(SourceRange R) { return R; }
+  static SourceRange getPrintable(SourceLocation L) { return L; }
+  static SourceRange getPrintable(Expr *E) { return E->getSourceRange(); }
+  static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();}
+
+  template<typename T1>
+  class BoundTypeDiagnoser1 : public TypeDiagnoser {
+    unsigned DiagID;
+    const T1 &Arg1;
+
+  public:
+    BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1)
+      : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { }
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
+      if (Suppressed) return;
+      S.Diag(Loc, DiagID) << getPrintable(Arg1) << T;
+    }
+
+    virtual ~BoundTypeDiagnoser1() { }
+  };
+
+  template<typename T1, typename T2>
+  class BoundTypeDiagnoser2 : public TypeDiagnoser {
+    unsigned DiagID;
+    const T1 &Arg1;
+    const T2 &Arg2;
+
+  public:
+    BoundTypeDiagnoser2(unsigned DiagID, const T1 &Arg1,
+                                  const T2 &Arg2)
+      : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
+        Arg2(Arg2) { }
+
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
+      if (Suppressed) return;
+      S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T;
+    }
+
+    virtual ~BoundTypeDiagnoser2() { }
+  };
+
+  template<typename T1, typename T2, typename T3>
+  class BoundTypeDiagnoser3 : public TypeDiagnoser {
+    unsigned DiagID;
+    const T1 &Arg1;
+    const T2 &Arg2;
+    const T3 &Arg3;
+
+  public:
+    BoundTypeDiagnoser3(unsigned DiagID, const T1 &Arg1,
+                                  const T2 &Arg2, const T3 &Arg3)
+    : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
+      Arg2(Arg2), Arg3(Arg3) { }
+
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
+      if (Suppressed) return;
+      S.Diag(Loc, DiagID)
+        << getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T;
+    }
+
+    virtual ~BoundTypeDiagnoser3() { }
+  };
+
+private:
+  bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
+                           TypeDiagnoser &Diagnoser);
+public:
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           TypeDiagnoser &Diagnoser);
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID);
+
+  template<typename T1>
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID, const T1 &Arg1) {
+    BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
+    return RequireCompleteType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2>
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID, const T1 &Arg1, const T2 &Arg2) {
+    BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
+    return RequireCompleteType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2, typename T3>
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           unsigned DiagID, const T1 &Arg1, const T2 &Arg2,
+                           const T3 &Arg3) {
+    BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2,
+                                                        Arg3);
+    return RequireCompleteType(Loc, T, Diagnoser);
+  }
+
+  bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser);
+  bool RequireCompleteExprType(Expr *E, unsigned DiagID);
+
+  template<typename T1>
+  bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1) {
+    BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
+    return RequireCompleteExprType(E, Diagnoser);
+  }
+
+  template<typename T1, typename T2>
+  bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1,
+                               const T2 &Arg2) {
+    BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
+    return RequireCompleteExprType(E, Diagnoser);
+  }
+
+  template<typename T1, typename T2, typename T3>
+  bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1,
+                               const T2 &Arg2, const T3 &Arg3) {
+    BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2,
+                                                        Arg3);
+    return RequireCompleteExprType(E, Diagnoser);
+  }
+
+  bool RequireLiteralType(SourceLocation Loc, QualType T,
+                          TypeDiagnoser &Diagnoser);
+  bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID);
+
+  template<typename T1>
+  bool RequireLiteralType(SourceLocation Loc, QualType T,
+                          unsigned DiagID, const T1 &Arg1) {
+    BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
+    return RequireLiteralType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2>
+  bool RequireLiteralType(SourceLocation Loc, QualType T,
+                          unsigned DiagID, const T1 &Arg1, const T2 &Arg2) {
+    BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
+    return RequireLiteralType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2, typename T3>
+  bool RequireLiteralType(SourceLocation Loc, QualType T,
+                          unsigned DiagID, const T1 &Arg1, const T2 &Arg2,
+                          const T3 &Arg3) {
+    BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2,
+                                                        Arg3);
+    return RequireLiteralType(Loc, T, Diagnoser);
+  }
+
+  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
+                             const CXXScopeSpec &SS, QualType T);
+
+  QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
+  QualType BuildDecltypeType(Expr *E, SourceLocation Loc);
+  QualType BuildUnaryTransformType(QualType BaseType,
+                                   UnaryTransformType::UTTKind UKind,
+                                   SourceLocation Loc);
+
+  //===--------------------------------------------------------------------===//
+  // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
+  //
+
+  /// List of decls defined in a function prototype. This contains EnumConstants
+  /// that incorrectly end up in translation unit scope because there is no
+  /// function to pin them on. ActOnFunctionDeclarator reads this list and patches
+  /// them into the FunctionDecl.
+  std::vector<NamedDecl*> DeclsInPrototypeScope;
+
+  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
+
+  void DiagnoseUseOfUnimplementedSelectors();
+
+  bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;
+
+  ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
+                         Scope *S, CXXScopeSpec *SS = nullptr,
+                         bool isClassName = false,
+                         bool HasTrailingDot = false,
+                         ParsedType ObjectType = ParsedType(),
+                         bool IsCtorOrDtorName = false,
+                         bool WantNontrivialTypeSourceInfo = false,
+                         IdentifierInfo **CorrectedII = nullptr);
+  TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
+  bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
+  void DiagnoseUnknownTypeName(IdentifierInfo *&II,
+                               SourceLocation IILoc,
+                               Scope *S,
+                               CXXScopeSpec *SS,
+                               ParsedType &SuggestedType,
+                               bool AllowClassTemplates = false);
+
+  /// \brief For compatibility with MSVC, we delay parsing of some default
+  /// template type arguments until instantiation time.  Emits a warning and
+  /// returns a synthesized DependentNameType that isn't really dependent on any
+  /// other template arguments.
+  ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+                                            SourceLocation NameLoc);
+
+  /// \brief Describes the result of the name lookup and resolution performed
+  /// by \c ClassifyName().
+  enum NameClassificationKind {
+    NC_Unknown,
+    NC_Error,
+    NC_Keyword,
+    NC_Type,
+    NC_Expression,
+    NC_NestedNameSpecifier,
+    NC_TypeTemplate,
+    NC_VarTemplate,
+    NC_FunctionTemplate
+  };
+
+  class NameClassification {
+    NameClassificationKind Kind;
+    ExprResult Expr;
+    TemplateName Template;
+    ParsedType Type;
+    const IdentifierInfo *Keyword;
+
+    explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {}
+
+  public:
+    NameClassification(ExprResult Expr) : Kind(NC_Expression), Expr(Expr) {}
+
+    NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {}
+
+    NameClassification(const IdentifierInfo *Keyword)
+      : Kind(NC_Keyword), Keyword(Keyword) { }
+
+    static NameClassification Error() {
+      return NameClassification(NC_Error);
+    }
+
+    static NameClassification Unknown() {
+      return NameClassification(NC_Unknown);
+    }
+
+    static NameClassification NestedNameSpecifier() {
+      return NameClassification(NC_NestedNameSpecifier);
+    }
+
+    static NameClassification TypeTemplate(TemplateName Name) {
+      NameClassification Result(NC_TypeTemplate);
+      Result.Template = Name;
+      return Result;
+    }
+
+    static NameClassification VarTemplate(TemplateName Name) {
+      NameClassification Result(NC_VarTemplate);
+      Result.Template = Name;
+      return Result;
+    }
+
+    static NameClassification FunctionTemplate(TemplateName Name) {
+      NameClassification Result(NC_FunctionTemplate);
+      Result.Template = Name;
+      return Result;
+    }
+
+    NameClassificationKind getKind() const { return Kind; }
+
+    ParsedType getType() const {
+      assert(Kind == NC_Type);
+      return Type;
+    }
+
+    ExprResult getExpression() const {
+      assert(Kind == NC_Expression);
+      return Expr;
+    }
+
+    TemplateName getTemplateName() const {
+      assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate ||
+             Kind == NC_VarTemplate);
+      return Template;
+    }
+
+    TemplateNameKind getTemplateNameKind() const {
+      switch (Kind) {
+      case NC_TypeTemplate:
+        return TNK_Type_template;
+      case NC_FunctionTemplate:
+        return TNK_Function_template;
+      case NC_VarTemplate:
+        return TNK_Var_template;
+      default:
+        llvm_unreachable("unsupported name classification.");
+      }
+    }
+  };
+
+  /// \brief Perform name lookup on the given name, classifying it based on
+  /// the results of name lookup and the following token.
+  ///
+  /// This routine is used by the parser to resolve identifiers and help direct
+  /// parsing. When the identifier cannot be found, this routine will attempt
+  /// to correct the typo and classify based on the resulting name.
+  ///
+  /// \param S The scope in which we're performing name lookup.
+  ///
+  /// \param SS The nested-name-specifier that precedes the name.
+  ///
+  /// \param Name The identifier. If typo correction finds an alternative name,
+  /// this pointer parameter will be updated accordingly.
+  ///
+  /// \param NameLoc The location of the identifier.
+  ///
+  /// \param NextToken The token following the identifier. Used to help
+  /// disambiguate the name.
+  ///
+  /// \param IsAddressOfOperand True if this name is the operand of a unary
+  ///        address of ('&') expression, assuming it is classified as an
+  ///        expression.
+  ///
+  /// \param CCC The correction callback, if typo correction is desired.
+  NameClassification ClassifyName(Scope *S,
+                                  CXXScopeSpec &SS,
+                                  IdentifierInfo *&Name,
+                                  SourceLocation NameLoc,
+                                  const Token &NextToken,
+                                  bool IsAddressOfOperand,
+                                  CorrectionCandidateCallback *CCC = nullptr);
+
+  Decl *ActOnDeclarator(Scope *S, Declarator &D);
+
+  NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
+                              MultiTemplateParamsArg TemplateParameterLists);
+  void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S);
+  bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
+  bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
+                                    DeclarationName Name,
+                                    SourceLocation Loc);
+  void
+  diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+                            SourceLocation FallbackLoc,
+                            SourceLocation ConstQualLoc = SourceLocation(),
+                            SourceLocation VolatileQualLoc = SourceLocation(),
+                            SourceLocation RestrictQualLoc = SourceLocation(),
+                            SourceLocation AtomicQualLoc = SourceLocation());
+
+  static bool adjustContextForLocalExternDecl(DeclContext *&DC);
+  void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
+  void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
+  void CheckShadow(Scope *S, VarDecl *D);
+  void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);
+  void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D);
+  NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                    TypeSourceInfo *TInfo,
+                                    LookupResult &Previous);
+  NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D,
+                                  LookupResult &Previous, bool &Redeclaration);
+  NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
+                                     TypeSourceInfo *TInfo,
+                                     LookupResult &Previous,
+                                     MultiTemplateParamsArg TemplateParamLists,
+                                     bool &AddToScope);
+  // Returns true if the variable declaration is a redeclaration
+  bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
+  void CheckVariableDeclarationType(VarDecl *NewVD);
+  void CheckCompleteVariableDeclaration(VarDecl *var);
+  void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
+
+  NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                     TypeSourceInfo *TInfo,
+                                     LookupResult &Previous,
+                                     MultiTemplateParamsArg TemplateParamLists,
+                                     bool &AddToScope);
+  bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
+
+  bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
+  bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
+
+  void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD);
+  void FindHiddenVirtualMethods(CXXMethodDecl *MD,
+                          SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods);
+  void NoteHiddenVirtualMethods(CXXMethodDecl *MD,
+                          SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods);
+  // Returns true if the function declaration is a redeclaration
+  bool CheckFunctionDeclaration(Scope *S,
+                                FunctionDecl *NewFD, LookupResult &Previous,
+                                bool IsExplicitSpecialization);
+  void CheckMain(FunctionDecl *FD, const DeclSpec &D);
+  void CheckMSVCRTEntryPoint(FunctionDecl *FD);
+  Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
+  ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
+                                          SourceLocation Loc,
+                                          QualType T);
+  ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
+                              SourceLocation NameLoc, IdentifierInfo *Name,
+                              QualType T, TypeSourceInfo *TSInfo,
+                              StorageClass SC);
+  void ActOnParamDefaultArgument(Decl *param,
+                                 SourceLocation EqualLoc,
+                                 Expr *defarg);
+  void ActOnParamUnparsedDefaultArgument(Decl *param,
+                                         SourceLocation EqualLoc,
+                                         SourceLocation ArgLoc);
+  void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
+  bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
+                               SourceLocation EqualLoc);
+
+  void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit,
+                            bool TypeMayContainAuto);
+  void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
+  void ActOnInitializerError(Decl *Dcl);
+  void ActOnCXXForRangeDecl(Decl *D);
+  StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+                                        IdentifierInfo *Ident,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation AttrEnd);
+  void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
+  void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
+  void FinalizeDeclaration(Decl *D);
+  DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                                         ArrayRef<Decl *> Group);
+  DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
+                                      bool TypeMayContainAuto = true);
+
+  /// Should be called on all declarations that might have attached
+  /// documentation comments.
+  void ActOnDocumentableDecl(Decl *D);
+  void ActOnDocumentableDecls(ArrayRef<Decl *> Group);
+
+  void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
+                                       SourceLocation LocAfterDecls);
+  void CheckForFunctionRedefinition(FunctionDecl *FD,
+                                    const FunctionDecl *EffectiveDefinition =
+                                        nullptr);
+  Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
+  Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
+  void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
+  bool isObjCMethodDecl(Decl *D) {
+    return D && isa<ObjCMethodDecl>(D);
+  }
+
+  /// \brief Determine whether we can delay parsing the body of a function or
+  /// function template until it is used, assuming we don't care about emitting
+  /// code for that function.
+  ///
+  /// This will be \c false if we may need the body of the function in the
+  /// middle of parsing an expression (where it's impractical to switch to
+  /// parsing a different function), for instance, if it's constexpr in C++11
+  /// or has an 'auto' return type in C++14. These cases are essentially bugs.
+  bool canDelayFunctionBody(const Declarator &D);
+
+  /// \brief Determine whether we can skip parsing the body of a function
+  /// definition, assuming we don't care about analyzing its body or emitting
+  /// code for that function.
+  ///
+  /// This will be \c false only if we may need the body of the function in
+  /// order to parse the rest of the program (for instance, if it is
+  /// \c constexpr in C++11 or has an 'auto' return type in C++14).
+  bool canSkipFunctionBody(Decl *D);
+
+  void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
+  Decl *ActOnSkippedFunctionBody(Decl *Decl);
+  void ActOnFinishInlineMethodDef(CXXMethodDecl *D);
+
+  /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
+  /// attribute for which parsing is delayed.
+  void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs);
+
+  /// \brief Diagnose any unused parameters in the given sequence of
+  /// ParmVarDecl pointers.
+  void DiagnoseUnusedParameters(ParmVarDecl * const *Begin,
+                                ParmVarDecl * const *End);
+
+  /// \brief Diagnose whether the size of parameters or return value of a
+  /// function or obj-c method definition is pass-by-value and larger than a
+  /// specified threshold.
+  void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin,
+                                              ParmVarDecl * const *End,
+                                              QualType ReturnTy,
+                                              NamedDecl *D);
+
+  void DiagnoseInvalidJumps(Stmt *Body);
+  Decl *ActOnFileScopeAsmDecl(Expr *expr,
+                              SourceLocation AsmLoc,
+                              SourceLocation RParenLoc);
+
+  /// \brief Handle a C++11 empty-declaration and attribute-declaration.
+  Decl *ActOnEmptyDeclaration(Scope *S,
+                              AttributeList *AttrList,
+                              SourceLocation SemiLoc);
+
+  /// \brief The parser has processed a module import declaration.
+  ///
+  /// \param AtLoc The location of the '@' symbol, if any.
+  ///
+  /// \param ImportLoc The location of the 'import' keyword.
+  ///
+  /// \param Path The module access path.
+  DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
+                               ModuleIdPath Path);
+
+  /// \brief The parser has processed a module import translated from a
+  /// #include or similar preprocessing directive.
+  void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
+
+  /// \brief Create an implicit import of the given module at the given
+  /// source location, for error recovery, if possible.
+  ///
+  /// This routine is typically used when an entity found by name lookup
+  /// is actually hidden within a module that we know about but the user
+  /// has forgotten to import.
+  void createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+                                                  Module *Mod);
+
+  /// \brief Retrieve a suitable printing policy.
+  PrintingPolicy getPrintingPolicy() const {
+    return getPrintingPolicy(Context, PP);
+  }
+
+  /// \brief Retrieve a suitable printing policy.
+  static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx,
+                                          const Preprocessor &PP);
+
+  /// Scope actions.
+  void ActOnPopScope(SourceLocation Loc, Scope *S);
+  void ActOnTranslationUnitScope(Scope *S);
+
+  Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                   DeclSpec &DS);
+  Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                   DeclSpec &DS,
+                                   MultiTemplateParamsArg TemplateParams,
+                                   bool IsExplicitInstantiation = false);
+
+  Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                    AccessSpecifier AS,
+                                    RecordDecl *Record,
+                                    const PrintingPolicy &Policy);
+
+  Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
+                                       RecordDecl *Record);
+
+  bool isAcceptableTagRedeclaration(const TagDecl *Previous,
+                                    TagTypeKind NewTag, bool isDefinition,
+                                    SourceLocation NewTagLoc,
+                                    const IdentifierInfo &Name);
+
+  enum TagUseKind {
+    TUK_Reference,   // Reference to a tag:  'struct foo *X;'
+    TUK_Declaration, // Fwd decl of a tag:   'struct foo;'
+    TUK_Definition,  // Definition of a tag: 'struct foo { int X; } Y;'
+    TUK_Friend       // Friend declaration:  'friend struct foo;'
+  };
+
+  Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                 SourceLocation KWLoc, CXXScopeSpec &SS,
+                 IdentifierInfo *Name, SourceLocation NameLoc,
+                 AttributeList *Attr, AccessSpecifier AS,
+                 SourceLocation ModulePrivateLoc,
+                 MultiTemplateParamsArg TemplateParameterLists,
+                 bool &OwnedDecl, bool &IsDependent,
+                 SourceLocation ScopedEnumKWLoc,
+                 bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
+                 bool IsTypeSpecifier);
+
+  Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
+                                unsigned TagSpec, SourceLocation TagLoc,
+                                CXXScopeSpec &SS,
+                                IdentifierInfo *Name, SourceLocation NameLoc,
+                                AttributeList *Attr,
+                                MultiTemplateParamsArg TempParamLists);
+
+  TypeResult ActOnDependentTag(Scope *S,
+                               unsigned TagSpec,
+                               TagUseKind TUK,
+                               const CXXScopeSpec &SS,
+                               IdentifierInfo *Name,
+                               SourceLocation TagLoc,
+                               SourceLocation NameLoc);
+
+  void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
+                 IdentifierInfo *ClassName,
+                 SmallVectorImpl<Decl *> &Decls);
+  Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart,
+                   Declarator &D, Expr *BitfieldWidth);
+
+  FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
+                         Declarator &D, Expr *BitfieldWidth,
+                         InClassInitStyle InitStyle,
+                         AccessSpecifier AS);
+  MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD,
+                                   SourceLocation DeclStart,
+                                   Declarator &D, Expr *BitfieldWidth,
+                                   InClassInitStyle InitStyle,
+                                   AccessSpecifier AS,
+                                   AttributeList *MSPropertyAttr);
+
+  FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
+                            TypeSourceInfo *TInfo,
+                            RecordDecl *Record, SourceLocation Loc,
+                            bool Mutable, Expr *BitfieldWidth,
+                            InClassInitStyle InitStyle,
+                            SourceLocation TSSL,
+                            AccessSpecifier AS, NamedDecl *PrevDecl,
+                            Declarator *D = nullptr);
+
+  bool CheckNontrivialField(FieldDecl *FD);
+  void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
+  bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM,
+                              bool Diagnose = false);
+  CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
+  void ActOnLastBitfield(SourceLocation DeclStart,
+                         SmallVectorImpl<Decl *> &AllIvarDecls);
+  Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
+                  Declarator &D, Expr *BitfieldWidth,
+                  tok::ObjCKeywordKind visibility);
+
+  // This is used for both record definitions and ObjC interface declarations.
+  void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl,
+                   ArrayRef<Decl *> Fields,
+                   SourceLocation LBrac, SourceLocation RBrac,
+                   AttributeList *AttrList);
+
+  /// ActOnTagStartDefinition - Invoked when we have entered the
+  /// scope of a tag's definition (e.g., for an enumeration, class,
+  /// struct, or union).
+  void ActOnTagStartDefinition(Scope *S, Decl *TagDecl);
+
+  Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
+
+  /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
+  /// C++ record definition's base-specifiers clause and are starting its
+  /// member declarations.
+  void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl,
+                                       SourceLocation FinalLoc,
+                                       bool IsFinalSpelledSealed,
+                                       SourceLocation LBraceLoc);
+
+  /// ActOnTagFinishDefinition - Invoked once we have finished parsing
+  /// the definition of a tag (enumeration, class, struct, or union).
+  void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl,
+                                SourceLocation RBraceLoc);
+
+  void ActOnObjCContainerFinishDefinition();
+
+  /// \brief Invoked when we must temporarily exit the objective-c container
+  /// scope for parsing/looking-up C constructs.
+  ///
+  /// Must be followed by a call to \see ActOnObjCReenterContainerContext
+  void ActOnObjCTemporaryExitContainerContext(DeclContext *DC);
+  void ActOnObjCReenterContainerContext(DeclContext *DC);
+
+  /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
+  /// error parsing the definition of a tag.
+  void ActOnTagDefinitionError(Scope *S, Decl *TagDecl);
+
+  EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
+                                      EnumConstantDecl *LastEnumConst,
+                                      SourceLocation IdLoc,
+                                      IdentifierInfo *Id,
+                                      Expr *val);
+  bool CheckEnumUnderlyingType(TypeSourceInfo *TI);
+  bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
+                              QualType EnumUnderlyingTy, const EnumDecl *Prev);
+
+  Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
+                          SourceLocation IdLoc, IdentifierInfo *Id,
+                          AttributeList *Attrs,
+                          SourceLocation EqualLoc, Expr *Val);
+  void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
+                     SourceLocation RBraceLoc, Decl *EnumDecl,
+                     ArrayRef<Decl *> Elements,
+                     Scope *S, AttributeList *Attr);
+
+  DeclContext *getContainingDC(DeclContext *DC);
+
+  /// Set the current declaration context until it gets popped.
+  void PushDeclContext(Scope *S, DeclContext *DC);
+  void PopDeclContext();
+
+  /// EnterDeclaratorContext - Used when we must lookup names in the context
+  /// of a declarator's nested name specifier.
+  void EnterDeclaratorContext(Scope *S, DeclContext *DC);
+  void ExitDeclaratorContext(Scope *S);
+
+  /// Push the parameters of D, which must be a function, into scope.
+  void ActOnReenterFunctionContext(Scope* S, Decl* D);
+  void ActOnExitFunctionContext();
+
+  DeclContext *getFunctionLevelDeclContext();
+
+  /// getCurFunctionDecl - If inside of a function body, this returns a pointer
+  /// to the function decl for the function being parsed.  If we're currently
+  /// in a 'block', this returns the containing context.
+  FunctionDecl *getCurFunctionDecl();
+
+  /// getCurMethodDecl - If inside of a method body, this returns a pointer to
+  /// the method decl for the method being parsed.  If we're currently
+  /// in a 'block', this returns the containing context.
+  ObjCMethodDecl *getCurMethodDecl();
+
+  /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
+  /// or C function we're in, otherwise return null.  If we're currently
+  /// in a 'block', this returns the containing context.
+  NamedDecl *getCurFunctionOrMethodDecl();
+
+  /// Add this decl to the scope shadowed decl chains.
+  void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
+
+  /// \brief Make the given externally-produced declaration visible at the
+  /// top level scope.
+  ///
+  /// \param D The externally-produced declaration to push.
+  ///
+  /// \param Name The name of the externally-produced declaration.
+  void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
+
+  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
+  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
+  /// true if 'D' belongs to the given declaration context.
+  ///
+  /// \param AllowInlineNamespace If \c true, allow the declaration to be in the
+  ///        enclosing namespace set of the context, rather than contained
+  ///        directly within it.
+  bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr,
+                     bool AllowInlineNamespace = false);
+
+  /// Finds the scope corresponding to the given decl context, if it
+  /// happens to be an enclosing scope.  Otherwise return NULL.
+  static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC);
+
+  /// Subroutines of ActOnDeclarator().
+  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
+                                TypeSourceInfo *TInfo);
+  bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
+
+  /// Attribute merging methods. Return true if a new attribute was added.
+  AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
+                                          IdentifierInfo *Platform,
+                                          VersionTuple Introduced,
+                                          VersionTuple Deprecated,
+                                          VersionTuple Obsoleted,
+                                          bool IsUnavailable,
+                                          StringRef Message,
+                                          bool Override,
+                                          unsigned AttrSpellingListIndex);
+  TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
+                                       TypeVisibilityAttr::VisibilityType Vis,
+                                              unsigned AttrSpellingListIndex);
+  VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
+                                      VisibilityAttr::VisibilityType Vis,
+                                      unsigned AttrSpellingListIndex);
+  DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
+                                    unsigned AttrSpellingListIndex);
+  DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
+                                    unsigned AttrSpellingListIndex);
+  MSInheritanceAttr *
+  mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
+                         unsigned AttrSpellingListIndex,
+                         MSInheritanceAttr::Spelling SemanticSpelling);
+  FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
+                              IdentifierInfo *Format, int FormatIdx,
+                              int FirstArg, unsigned AttrSpellingListIndex);
+  SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
+                                unsigned AttrSpellingListIndex);
+
+  /// \brief Describes the kind of merge to perform for availability
+  /// attributes (including "deprecated", "unavailable", and "availability").
+  enum AvailabilityMergeKind {
+    /// \brief Don't merge availability attributes at all.
+    AMK_None,
+    /// \brief Merge availability attributes for a redeclaration, which requires
+    /// an exact match.
+    AMK_Redeclaration,
+    /// \brief Merge availability attributes for an override, which requires
+    /// an exact match or a weakening of constraints.
+    AMK_Override
+  };
+
+  void mergeDeclAttributes(NamedDecl *New, Decl *Old,
+                           AvailabilityMergeKind AMK = AMK_Redeclaration);
+  void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
+  bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
+                         bool MergeTypeWithOld);
+  bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
+                                    Scope *S, bool MergeTypeWithOld);
+  void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
+  void MergeVarDecl(VarDecl *New, LookupResult &Previous);
+  void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
+  void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
+  bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
+
+  // AssignmentAction - This is used by all the assignment diagnostic functions
+  // to represent what is actually causing the operation
+  enum AssignmentAction {
+    AA_Assigning,
+    AA_Passing,
+    AA_Returning,
+    AA_Converting,
+    AA_Initializing,
+    AA_Sending,
+    AA_Casting,
+    AA_Passing_CFAudited
+  };
+
+  /// C++ Overloading.
+  enum OverloadKind {
+    /// This is a legitimate overload: the existing declarations are
+    /// functions or function templates with different signatures.
+    Ovl_Overload,
+
+    /// This is not an overload because the signature exactly matches
+    /// an existing declaration.
+    Ovl_Match,
+
+    /// This is not an overload because the lookup results contain a
+    /// non-function.
+    Ovl_NonFunction
+  };
+  OverloadKind CheckOverload(Scope *S,
+                             FunctionDecl *New,
+                             const LookupResult &OldDecls,
+                             NamedDecl *&OldDecl,
+                             bool IsForUsingDecl);
+  bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);
+
+  /// \brief Checks availability of the function depending on the current
+  /// function context.Inside an unavailable function,unavailability is ignored.
+  ///
+  /// \returns true if \p FD is unavailable and current context is inside
+  /// an available function, false otherwise.
+  bool isFunctionConsideredUnavailable(FunctionDecl *FD);
+
+  ImplicitConversionSequence
+  TryImplicitConversion(Expr *From, QualType ToType,
+                        bool SuppressUserConversions,
+                        bool AllowExplicit,
+                        bool InOverloadResolution,
+                        bool CStyle,
+                        bool AllowObjCWritebackConversion);
+
+  bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
+  bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
+  bool IsComplexPromotion(QualType FromType, QualType ToType);
+  bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                           bool InOverloadResolution,
+                           QualType& ConvertedType, bool &IncompatibleObjC);
+  bool isObjCPointerConversion(QualType FromType, QualType ToType,
+                               QualType& ConvertedType, bool &IncompatibleObjC);
+  bool isObjCWritebackConversion(QualType FromType, QualType ToType,
+                                 QualType &ConvertedType);
+  bool IsBlockPointerConversion(QualType FromType, QualType ToType,
+                                QualType& ConvertedType);
+  bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
+                                  const FunctionProtoType *NewType,
+                                  unsigned *ArgPos = nullptr);
+  void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
+                                  QualType FromType, QualType ToType);
+
+  CastKind PrepareCastToObjCObjectPointer(ExprResult &E);
+  bool CheckPointerConversion(Expr *From, QualType ToType,
+                              CastKind &Kind,
+                              CXXCastPath& BasePath,
+                              bool IgnoreBaseAccess);
+  bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
+                                 bool InOverloadResolution,
+                                 QualType &ConvertedType);
+  bool CheckMemberPointerConversion(Expr *From, QualType ToType,
+                                    CastKind &Kind,
+                                    CXXCastPath &BasePath,
+                                    bool IgnoreBaseAccess);
+  bool IsQualificationConversion(QualType FromType, QualType ToType,
+                                 bool CStyle, bool &ObjCLifetimeConversion);
+  bool IsNoReturnConversion(QualType FromType, QualType ToType,
+                            QualType &ResultTy);
+  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
+  bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
+
+  ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
+                                             const VarDecl *NRVOCandidate,
+                                             QualType ResultType,
+                                             Expr *Value,
+                                             bool AllowNRVO = true);
+
+  bool CanPerformCopyInitialization(const InitializedEntity &Entity,
+                                    ExprResult Init);
+  ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
+                                       SourceLocation EqualLoc,
+                                       ExprResult Init,
+                                       bool TopLevelOfInitList = false,
+                                       bool AllowExplicit = false);
+  ExprResult PerformObjectArgumentInitialization(Expr *From,
+                                                 NestedNameSpecifier *Qualifier,
+                                                 NamedDecl *FoundDecl,
+                                                 CXXMethodDecl *Method);
+
+  ExprResult PerformContextuallyConvertToBool(Expr *From);
+  ExprResult PerformContextuallyConvertToObjCPointer(Expr *From);
+
+  /// Contexts in which a converted constant expression is required.
+  enum CCEKind {
+    CCEK_CaseValue,   ///< Expression in a case label.
+    CCEK_Enumerator,  ///< Enumerator value with fixed underlying type.
+    CCEK_TemplateArg, ///< Value of a non-type template parameter.
+    CCEK_NewExpr      ///< Constant expression in a noptr-new-declarator.
+  };
+  ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
+                                              llvm::APSInt &Value, CCEKind CCE);
+
+  /// \brief Abstract base class used to perform a contextual implicit
+  /// conversion from an expression to any type passing a filter.
+  class ContextualImplicitConverter {
+  public:
+    bool Suppress;
+    bool SuppressConversion;
+
+    ContextualImplicitConverter(bool Suppress = false,
+                                bool SuppressConversion = false)
+        : Suppress(Suppress), SuppressConversion(SuppressConversion) {}
+
+    /// \brief Determine whether the specified type is a valid destination type
+    /// for this conversion.
+    virtual bool match(QualType T) = 0;
+
+    /// \brief Emits a diagnostic complaining that the expression does not have
+    /// integral or enumeration type.
+    virtual SemaDiagnosticBuilder
+    diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0;
+
+    /// \brief Emits a diagnostic when the expression has incomplete class type.
+    virtual SemaDiagnosticBuilder
+    diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0;
+
+    /// \brief Emits a diagnostic when the only matching conversion function
+    /// is explicit.
+    virtual SemaDiagnosticBuilder diagnoseExplicitConv(
+        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0;
+
+    /// \brief Emits a note for the explicit conversion function.
+    virtual SemaDiagnosticBuilder
+    noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
+
+    /// \brief Emits a diagnostic when there are multiple possible conversion
+    /// functions.
+    virtual SemaDiagnosticBuilder
+    diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0;
+
+    /// \brief Emits a note for one of the candidate conversions.
+    virtual SemaDiagnosticBuilder
+    noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0;
+
+    /// \brief Emits a diagnostic when we picked a conversion function
+    /// (for cases when we are not allowed to pick a conversion function).
+    virtual SemaDiagnosticBuilder diagnoseConversion(
+        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0;
+
+    virtual ~ContextualImplicitConverter() {}
+  };
+
+  class ICEConvertDiagnoser : public ContextualImplicitConverter {
+    bool AllowScopedEnumerations;
+
+  public:
+    ICEConvertDiagnoser(bool AllowScopedEnumerations,
+                        bool Suppress, bool SuppressConversion)
+        : ContextualImplicitConverter(Suppress, SuppressConversion),
+          AllowScopedEnumerations(AllowScopedEnumerations) {}
+
+    /// Match an integral or (possibly scoped) enumeration type.
+    bool match(QualType T) override;
+
+    SemaDiagnosticBuilder
+    diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override {
+      return diagnoseNotInt(S, Loc, T);
+    }
+
+    /// \brief Emits a diagnostic complaining that the expression does not have
+    /// integral or enumeration type.
+    virtual SemaDiagnosticBuilder
+    diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0;
+  };
+
+  /// Perform a contextual implicit conversion.
+  ExprResult PerformContextualImplicitConversion(
+      SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter);
+
+
+  enum ObjCSubscriptKind {
+    OS_Array,
+    OS_Dictionary,
+    OS_Error
+  };
+  ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE);
+
+  // Note that LK_String is intentionally after the other literals, as
+  // this is used for diagnostics logic.
+  enum ObjCLiteralKind {
+    LK_Array,
+    LK_Dictionary,
+    LK_Numeric,
+    LK_Boxed,
+    LK_String,
+    LK_Block,
+    LK_None
+  };
+  ObjCLiteralKind CheckLiteralKind(Expr *FromE);
+
+  ExprResult PerformObjectMemberConversion(Expr *From,
+                                           NestedNameSpecifier *Qualifier,
+                                           NamedDecl *FoundDecl,
+                                           NamedDecl *Member);
+
+  // Members have to be NamespaceDecl* or TranslationUnitDecl*.
+  // TODO: make this is a typesafe union.
+  typedef llvm::SmallPtrSet<DeclContext   *, 16> AssociatedNamespaceSet;
+  typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
+
+  void AddOverloadCandidate(FunctionDecl *Function,
+                            DeclAccessPair FoundDecl,
+                            ArrayRef<Expr *> Args,
+                            OverloadCandidateSet& CandidateSet,
+                            bool SuppressUserConversions = false,
+                            bool PartialOverloading = false,
+                            bool AllowExplicit = false);
+  void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
+                      ArrayRef<Expr *> Args,
+                      OverloadCandidateSet &CandidateSet,
+                      bool SuppressUserConversions = false,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
+  void AddMethodCandidate(DeclAccessPair FoundDecl,
+                          QualType ObjectType,
+                          Expr::Classification ObjectClassification,
+                          ArrayRef<Expr *> Args,
+                          OverloadCandidateSet& CandidateSet,
+                          bool SuppressUserConversion = false);
+  void AddMethodCandidate(CXXMethodDecl *Method,
+                          DeclAccessPair FoundDecl,
+                          CXXRecordDecl *ActingContext, QualType ObjectType,
+                          Expr::Classification ObjectClassification,
+                          ArrayRef<Expr *> Args,
+                          OverloadCandidateSet& CandidateSet,
+                          bool SuppressUserConversions = false);
+  void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
+                                  DeclAccessPair FoundDecl,
+                                  CXXRecordDecl *ActingContext,
+                                 TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                  QualType ObjectType,
+                                  Expr::Classification ObjectClassification,
+                                  ArrayRef<Expr *> Args,
+                                  OverloadCandidateSet& CandidateSet,
+                                  bool SuppressUserConversions = false);
+  void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                    DeclAccessPair FoundDecl,
+                                 TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                    ArrayRef<Expr *> Args,
+                                    OverloadCandidateSet& CandidateSet,
+                                    bool SuppressUserConversions = false);
+  void AddConversionCandidate(CXXConversionDecl *Conversion,
+                              DeclAccessPair FoundDecl,
+                              CXXRecordDecl *ActingContext,
+                              Expr *From, QualType ToType,
+                              OverloadCandidateSet& CandidateSet,
+                              bool AllowObjCConversionOnExplicit);
+  void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                      DeclAccessPair FoundDecl,
+                                      CXXRecordDecl *ActingContext,
+                                      Expr *From, QualType ToType,
+                                      OverloadCandidateSet &CandidateSet,
+                                      bool AllowObjCConversionOnExplicit);
+  void AddSurrogateCandidate(CXXConversionDecl *Conversion,
+                             DeclAccessPair FoundDecl,
+                             CXXRecordDecl *ActingContext,
+                             const FunctionProtoType *Proto,
+                             Expr *Object, ArrayRef<Expr *> Args,
+                             OverloadCandidateSet& CandidateSet);
+  void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
+                                   SourceLocation OpLoc, ArrayRef<Expr *> Args,
+                                   OverloadCandidateSet& CandidateSet,
+                                   SourceRange OpRange = SourceRange());
+  void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
+                           ArrayRef<Expr *> Args, 
+                           OverloadCandidateSet& CandidateSet,
+                           bool IsAssignmentOperator = false,
+                           unsigned NumContextualBoolArguments = 0);
+  void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
+                                    SourceLocation OpLoc, ArrayRef<Expr *> Args,
+                                    OverloadCandidateSet& CandidateSet);
+  void AddArgumentDependentLookupCandidates(DeclarationName Name,
+                                            SourceLocation Loc,
+                                            ArrayRef<Expr *> Args,
+                                TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                            OverloadCandidateSet& CandidateSet,
+                                            bool PartialOverloading = false);
+
+  // Emit as a 'note' the specific overload candidate
+  void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType());
+
+  // Emit as a series of 'note's all template and non-templates
+  // identified by the expression Expr
+  void NoteAllOverloadCandidates(Expr* E, QualType DestType = QualType());
+
+  /// Check the enable_if expressions on the given function. Returns the first
+  /// failing attribute, or NULL if they were all successful.
+  EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+                              bool MissingImplicitThis = false);
+
+  // [PossiblyAFunctionType]  -->   [Return]
+  // NonFunctionType --> NonFunctionType
+  // R (A) --> R(A)
+  // R (*)(A) --> R (A)
+  // R (&)(A) --> R (A)
+  // R (S::*)(A) --> R (A)
+  QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType);
+
+  FunctionDecl *
+  ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
+                                     QualType TargetType,
+                                     bool Complain,
+                                     DeclAccessPair &Found,
+                                     bool *pHadMultipleCandidates = nullptr);
+
+  FunctionDecl *
+  ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
+                                              bool Complain = false,
+                                              DeclAccessPair *Found = nullptr);
+
+  bool ResolveAndFixSingleFunctionTemplateSpecialization(
+                      ExprResult &SrcExpr,
+                      bool DoFunctionPointerConverion = false,
+                      bool Complain = false,
+                      const SourceRange& OpRangeForComplaining = SourceRange(),
+                      QualType DestTypeForComplaining = QualType(),
+                      unsigned DiagIDForComplaining = 0);
+
+
+  Expr *FixOverloadedFunctionReference(Expr *E,
+                                       DeclAccessPair FoundDecl,
+                                       FunctionDecl *Fn);
+  ExprResult FixOverloadedFunctionReference(ExprResult,
+                                            DeclAccessPair FoundDecl,
+                                            FunctionDecl *Fn);
+
+  void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
+                                   ArrayRef<Expr *> Args,
+                                   OverloadCandidateSet &CandidateSet,
+                                   bool PartialOverloading = false);
+
+  // An enum used to represent the different possible results of building a
+  // range-based for loop.
+  enum ForRangeStatus {
+    FRS_Success,
+    FRS_NoViableFunction,
+    FRS_DiagnosticIssued
+  };
+
+  // An enum to represent whether something is dealing with a call to begin()
+  // or a call to end() in a range-based for loop.
+  enum BeginEndFunction {
+    BEF_begin,
+    BEF_end
+  };
+
+  ForRangeStatus BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc,
+                                           SourceLocation RangeLoc,
+                                           VarDecl *Decl,
+                                           BeginEndFunction BEF,
+                                           const DeclarationNameInfo &NameInfo,
+                                           LookupResult &MemberLookup,
+                                           OverloadCandidateSet *CandidateSet,
+                                           Expr *Range, ExprResult *CallExpr);
+
+  ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
+                                     UnresolvedLookupExpr *ULE,
+                                     SourceLocation LParenLoc,
+                                     MultiExprArg Args,
+                                     SourceLocation RParenLoc,
+                                     Expr *ExecConfig,
+                                     bool AllowTypoCorrection=true);
+
+  bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
+                              MultiExprArg Args, SourceLocation RParenLoc,
+                              OverloadCandidateSet *CandidateSet,
+                              ExprResult *Result);
+
+  ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
+                                     unsigned Opc,
+                                     const UnresolvedSetImpl &Fns,
+                                     Expr *input);
+
+  ExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
+                                   unsigned Opc,
+                                   const UnresolvedSetImpl &Fns,
+                                   Expr *LHS, Expr *RHS);
+
+  ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
+                                                SourceLocation RLoc,
+                                                Expr *Base,Expr *Idx);
+
+  ExprResult
+  BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
+                            SourceLocation LParenLoc,
+                            MultiExprArg Args,
+                            SourceLocation RParenLoc);
+  ExprResult
+  BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
+                               MultiExprArg Args,
+                               SourceLocation RParenLoc);
+
+  ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base,
+                                      SourceLocation OpLoc,
+                                      bool *NoArrowOperatorFound = nullptr);
+
+  /// CheckCallReturnType - Checks that a call expression's return type is
+  /// complete. Returns true on failure. The location passed in is the location
+  /// that best represents the call.
+  bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
+                           CallExpr *CE, FunctionDecl *FD);
+
+  /// Helpers for dealing with blocks and functions.
+  bool CheckParmsForFunctionDef(ParmVarDecl *const *Param,
+                                ParmVarDecl *const *ParamEnd,
+                                bool CheckParameterNames);
+  void CheckCXXDefaultArguments(FunctionDecl *FD);
+  void CheckExtraCXXDefaultArguments(Declarator &D);
+  Scope *getNonFieldDeclScope(Scope *S);
+
+  /// \name Name lookup
+  ///
+  /// These routines provide name lookup that is used during semantic
+  /// analysis to resolve the various kinds of names (identifiers,
+  /// overloaded operator names, constructor names, etc.) into zero or
+  /// more declarations within a particular scope. The major entry
+  /// points are LookupName, which performs unqualified name lookup,
+  /// and LookupQualifiedName, which performs qualified name lookup.
+  ///
+  /// All name lookup is performed based on some specific criteria,
+  /// which specify what names will be visible to name lookup and how
+  /// far name lookup should work. These criteria are important both
+  /// for capturing language semantics (certain lookups will ignore
+  /// certain names, for example) and for performance, since name
+  /// lookup is often a bottleneck in the compilation of C++. Name
+  /// lookup criteria is specified via the LookupCriteria enumeration.
+  ///
+  /// The results of name lookup can vary based on the kind of name
+  /// lookup performed, the current language, and the translation
+  /// unit. In C, for example, name lookup will either return nothing
+  /// (no entity found) or a single declaration. In C++, name lookup
+  /// can additionally refer to a set of overloaded functions or
+  /// result in an ambiguity. All of the possible results of name
+  /// lookup are captured by the LookupResult class, which provides
+  /// the ability to distinguish among them.
+  //@{
+
+  /// @brief Describes the kind of name lookup to perform.
+  enum LookupNameKind {
+    /// Ordinary name lookup, which finds ordinary names (functions,
+    /// variables, typedefs, etc.) in C and most kinds of names
+    /// (functions, variables, members, types, etc.) in C++.
+    LookupOrdinaryName = 0,
+    /// Tag name lookup, which finds the names of enums, classes,
+    /// structs, and unions.
+    LookupTagName,
+    /// Label name lookup.
+    LookupLabel,
+    /// Member name lookup, which finds the names of
+    /// class/struct/union members.
+    LookupMemberName,
+    /// Look up of an operator name (e.g., operator+) for use with
+    /// operator overloading. This lookup is similar to ordinary name
+    /// lookup, but will ignore any declarations that are class members.
+    LookupOperatorName,
+    /// Look up of a name that precedes the '::' scope resolution
+    /// operator in C++. This lookup completely ignores operator, object,
+    /// function, and enumerator names (C++ [basic.lookup.qual]p1).
+    LookupNestedNameSpecifierName,
+    /// Look up a namespace name within a C++ using directive or
+    /// namespace alias definition, ignoring non-namespace names (C++
+    /// [basic.lookup.udir]p1).
+    LookupNamespaceName,
+    /// Look up all declarations in a scope with the given name,
+    /// including resolved using declarations.  This is appropriate
+    /// for checking redeclarations for a using declaration.
+    LookupUsingDeclName,
+    /// Look up an ordinary name that is going to be redeclared as a
+    /// name with linkage. This lookup ignores any declarations that
+    /// are outside of the current scope unless they have linkage. See
+    /// C99 6.2.2p4-5 and C++ [basic.link]p6.
+    LookupRedeclarationWithLinkage,
+    /// Look up a friend of a local class. This lookup does not look
+    /// outside the innermost non-class scope. See C++11 [class.friend]p11.
+    LookupLocalFriendName,
+    /// Look up the name of an Objective-C protocol.
+    LookupObjCProtocolName,
+    /// Look up implicit 'self' parameter of an objective-c method.
+    LookupObjCImplicitSelfParam,
+    /// \brief Look up any declaration with any name.
+    LookupAnyName
+  };
+
+  /// \brief Specifies whether (or how) name lookup is being performed for a
+  /// redeclaration (vs. a reference).
+  enum RedeclarationKind {
+    /// \brief The lookup is a reference to this name that is not for the
+    /// purpose of redeclaring the name.
+    NotForRedeclaration = 0,
+    /// \brief The lookup results will be used for redeclaration of a name,
+    /// if an entity by that name already exists.
+    ForRedeclaration
+  };
+
+  /// \brief The possible outcomes of name lookup for a literal operator.
+  enum LiteralOperatorLookupResult {
+    /// \brief The lookup resulted in an error.
+    LOLR_Error,
+    /// \brief The lookup found a single 'cooked' literal operator, which
+    /// expects a normal literal to be built and passed to it.
+    LOLR_Cooked,
+    /// \brief The lookup found a single 'raw' literal operator, which expects
+    /// a string literal containing the spelling of the literal token.
+    LOLR_Raw,
+    /// \brief The lookup found an overload set of literal operator templates,
+    /// which expect the characters of the spelling of the literal token to be
+    /// passed as a non-type template argument pack.
+    LOLR_Template,
+    /// \brief The lookup found an overload set of literal operator templates,
+    /// which expect the character type and characters of the spelling of the
+    /// string literal token to be passed as template arguments.
+    LOLR_StringTemplate
+  };
+
+  SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
+                                                   CXXSpecialMember SM,
+                                                   bool ConstArg,
+                                                   bool VolatileArg,
+                                                   bool RValueThis,
+                                                   bool ConstThis,
+                                                   bool VolatileThis);
+
+private:
+  bool CppLookupName(LookupResult &R, Scope *S);
+
+  // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
+  //
+  // The boolean value will be true to indicate that the namespace was loaded
+  // from an AST/PCH file, or false otherwise.
+  llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces;
+
+  /// \brief Whether we have already loaded known namespaces from an extenal
+  /// source.
+  bool LoadedExternalKnownNamespaces;
+
+public:
+  /// \brief Look up a name, looking for a single declaration.  Return
+  /// null if the results were absent, ambiguous, or overloaded.
+  ///
+  /// It is preferable to use the elaborated form and explicitly handle
+  /// ambiguity and overloaded.
+  NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
+                              SourceLocation Loc,
+                              LookupNameKind NameKind,
+                              RedeclarationKind Redecl
+                                = NotForRedeclaration);
+  bool LookupName(LookupResult &R, Scope *S,
+                  bool AllowBuiltinCreation = false);
+  bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
+                           bool InUnqualifiedLookup = false);
+  bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
+                        bool AllowBuiltinCreation = false,
+                        bool EnteringContext = false);
+  ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc,
+                                   RedeclarationKind Redecl
+                                     = NotForRedeclaration);
+
+  void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
+                                    QualType T1, QualType T2,
+                                    UnresolvedSetImpl &Functions);
+  void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
+                                            DeclAccessPair Operator,
+                                            QualType T1, QualType T2);
+
+  LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
+                                 SourceLocation GnuLabelLoc = SourceLocation());
+
+  DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
+  CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
+  CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class,
+                                               unsigned Quals);
+  CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals,
+                                         bool RValueThis, unsigned ThisQuals);
+  CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class,
+                                              unsigned Quals);
+  CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals,
+                                        bool RValueThis, unsigned ThisQuals);
+  CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
+
+  bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id);
+  LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
+                                                    ArrayRef<QualType> ArgTys,
+                                                    bool AllowRaw,
+                                                    bool AllowTemplate,
+                                                    bool AllowStringTemplate);
+  bool isKnownName(StringRef name);
+
+  void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
+                               ArrayRef<Expr *> Args, ADLResult &Functions);
+
+  void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
+  void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
+                          VisibleDeclConsumer &Consumer,
+                          bool IncludeGlobalScope = true);
+
+  enum CorrectTypoKind {
+    CTK_NonError,     // CorrectTypo used in a non error recovery situation.
+    CTK_ErrorRecovery // CorrectTypo used in normal error recovery.
+  };
+
+  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
+                             Sema::LookupNameKind LookupKind,
+                             Scope *S, CXXScopeSpec *SS,
+                             CorrectionCandidateCallback &CCC,
+                             CorrectTypoKind Mode,
+                             DeclContext *MemberContext = nullptr,
+                             bool EnteringContext = false,
+                             const ObjCObjectPointerType *OPT = nullptr,
+                             bool RecordFailure = true);
+
+  void diagnoseTypo(const TypoCorrection &Correction,
+                    const PartialDiagnostic &TypoDiag,
+                    bool ErrorRecovery = true);
+
+  void diagnoseTypo(const TypoCorrection &Correction,
+                    const PartialDiagnostic &TypoDiag,
+                    const PartialDiagnostic &PrevNote,
+                    bool ErrorRecovery = true);
+
+  void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
+                                          ArrayRef<Expr *> Args,
+                                   AssociatedNamespaceSet &AssociatedNamespaces,
+                                   AssociatedClassSet &AssociatedClasses);
+
+  void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
+                            bool ConsiderLinkage, bool AllowInlineNamespace);
+
+  void DiagnoseAmbiguousLookup(LookupResult &Result);
+  //@}
+
+  ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                          SourceLocation IdLoc,
+                                          bool TypoCorrection = false);
+  NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
+                                 Scope *S, bool ForRedeclaration,
+                                 SourceLocation Loc);
+  NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
+                                      Scope *S);
+  void AddKnownFunctionAttributes(FunctionDecl *FD);
+
+  // More parsing and symbol table subroutines.
+
+  void ProcessPragmaWeak(Scope *S, Decl *D);
+  // Decl attributes - this routine is the top level dispatcher.
+  void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
+  void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL,
+                                bool IncludeCXX11Attributes = true);
+  bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
+                                      const AttributeList *AttrList);
+
+  void checkUnusedDeclAttributes(Declarator &D);
+
+  bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
+  bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
+                            const FunctionDecl *FD = nullptr);
+  bool CheckNoReturnAttr(const AttributeList &attr);
+  bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
+                                      unsigned ArgNum, StringRef &Str,
+                                      SourceLocation *ArgLocation = nullptr);
+  bool checkMSInheritanceAttrOnDefinition(
+      CXXRecordDecl *RD, SourceRange Range, bool BestCase,
+      MSInheritanceAttr::Spelling SemanticSpelling);
+
+  void CheckAlignasUnderalignment(Decl *D);
+
+  /// Adjust the calling convention of a method to be the ABI default if it
+  /// wasn't specified explicitly.  This handles method types formed from
+  /// function type typedefs and typename template arguments.
+  void adjustMemberFunctionCC(QualType &T, bool IsStatic);
+
+  // Check if there is an explicit attribute, but only look through parens.
+  // The intent is to look for an attribute on the current declarator, but not
+  // one that came from a typedef.
+  bool hasExplicitCallingConv(QualType &T);
+
+  /// Get the outermost AttributedType node that sets a calling convention.
+  /// Valid types should not have multiple attributes with different CCs.
+  const AttributedType *getCallingConvAttributedType(QualType T) const;
+
+  /// \brief Stmt attributes - this routine is the top level dispatcher.
+  StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
+                                   SourceRange Range);
+
+  void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
+                                   ObjCMethodDecl *MethodDecl,
+                                   bool IsProtocolMethodDecl);
+
+  void CheckConflictingOverridingMethod(ObjCMethodDecl *Method,
+                                   ObjCMethodDecl *Overridden,
+                                   bool IsProtocolMethodDecl);
+
+  /// WarnExactTypedMethods - This routine issues a warning if method
+  /// implementation declaration matches exactly that of its declaration.
+  void WarnExactTypedMethods(ObjCMethodDecl *Method,
+                             ObjCMethodDecl *MethodDecl,
+                             bool IsProtocolMethodDecl);
+
+  typedef llvm::SmallPtrSet<Selector, 8> SelectorSet;
+  typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap;
+
+  /// CheckImplementationIvars - This routine checks if the instance variables
+  /// listed in the implelementation match those listed in the interface.
+  void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
+                                ObjCIvarDecl **Fields, unsigned nIvars,
+                                SourceLocation Loc);
+
+  /// ImplMethodsVsClassMethods - This is main routine to warn if any method
+  /// remains unimplemented in the class or category \@implementation.
+  void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
+                                 ObjCContainerDecl* IDecl,
+                                 bool IncompleteImpl = false);
+
+  /// DiagnoseUnimplementedProperties - This routine warns on those properties
+  /// which must be implemented by this implementation.
+  void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl *CDecl,
+                                       bool SynthesizeProperties);
+
+  /// DefaultSynthesizeProperties - This routine default synthesizes all
+  /// properties which must be synthesized in the class's \@implementation.
+  void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
+                                    ObjCInterfaceDecl *IDecl);
+  void DefaultSynthesizeProperties(Scope *S, Decl *D);
+
+  /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
+  /// an ivar synthesized for 'Method' and 'Method' is a property accessor
+  /// declared in class 'IFace'.
+  bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace,
+                                      ObjCMethodDecl *Method, ObjCIvarDecl *IV);
+  
+  /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
+  /// backs the property is not used in the property's accessor.
+  void DiagnoseUnusedBackingIvarInAccessor(Scope *S,
+                                           const ObjCImplementationDecl *ImplD);
+  
+  /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and
+  /// it property has a backing ivar, returns this ivar; otherwise, returns NULL.
+  /// It also returns ivar's property on success.
+  ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
+                                               const ObjCPropertyDecl *&PDecl) const;
+  
+  /// Called by ActOnProperty to handle \@property declarations in
+  /// class extensions.
+  ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S,
+                      SourceLocation AtLoc,
+                      SourceLocation LParenLoc,
+                      FieldDeclarator &FD,
+                      Selector GetterSel,
+                      Selector SetterSel,
+                      const bool isAssign,
+                      const bool isReadWrite,
+                      const unsigned Attributes,
+                      const unsigned AttributesAsWritten,
+                      bool *isOverridingProperty,
+                      TypeSourceInfo *T,
+                      tok::ObjCKeywordKind MethodImplKind);
+
+  /// Called by ActOnProperty and HandlePropertyInClassExtension to
+  /// handle creating the ObjcPropertyDecl for a category or \@interface.
+  ObjCPropertyDecl *CreatePropertyDecl(Scope *S,
+                                       ObjCContainerDecl *CDecl,
+                                       SourceLocation AtLoc,
+                                       SourceLocation LParenLoc,
+                                       FieldDeclarator &FD,
+                                       Selector GetterSel,
+                                       Selector SetterSel,
+                                       const bool isAssign,
+                                       const bool isReadWrite,
+                                       const unsigned Attributes,
+                                       const unsigned AttributesAsWritten,
+                                       TypeSourceInfo *T,
+                                       tok::ObjCKeywordKind MethodImplKind,
+                                       DeclContext *lexicalDC = nullptr);
+
+  /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
+  /// warning) when atomic property has one but not the other user-declared
+  /// setter or getter.
+  void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
+                                       ObjCContainerDecl* IDecl);
+
+  void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
+
+  void DiagnoseMissingDesignatedInitOverrides(
+                                          const ObjCImplementationDecl *ImplD,
+                                          const ObjCInterfaceDecl *IFD);
+
+  void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
+
+  enum MethodMatchStrategy {
+    MMS_loose,
+    MMS_strict
+  };
+
+  /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
+  /// true, or false, accordingly.
+  bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
+                                  const ObjCMethodDecl *PrevMethod,
+                                  MethodMatchStrategy strategy = MMS_strict);
+
+  /// MatchAllMethodDeclarations - Check methods declaraed in interface or
+  /// or protocol against those declared in their implementations.
+  void MatchAllMethodDeclarations(const SelectorSet &InsMap,
+                                  const SelectorSet &ClsMap,
+                                  SelectorSet &InsMapSeen,
+                                  SelectorSet &ClsMapSeen,
+                                  ObjCImplDecl* IMPDecl,
+                                  ObjCContainerDecl* IDecl,
+                                  bool &IncompleteImpl,
+                                  bool ImmediateClass,
+                                  bool WarnCategoryMethodImpl=false);
+
+  /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in
+  /// category matches with those implemented in its primary class and
+  /// warns each time an exact match is found.
+  void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP);
+
+  /// \brief Add the given method to the list of globally-known methods.
+  void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
+
+private:
+  /// AddMethodToGlobalPool - Add an instance or factory method to the global
+  /// pool. See descriptoin of AddInstanceMethodToGlobalPool.
+  void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance);
+
+  /// LookupMethodInGlobalPool - Returns the instance or factory method and
+  /// optionally warns if there are multiple signatures.
+  ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R,
+                                           bool receiverIdOrClass,
+                                           bool warn, bool instance);
+
+  /// \brief Record the typo correction failure and return an empty correction.
+  TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc,
+                                  bool RecordFailure = true,
+                                  bool IsUnqualifiedLookup = false) {
+    if (IsUnqualifiedLookup)
+      (void)UnqualifiedTyposCorrected[Typo];
+    if (RecordFailure)
+      TypoCorrectionFailures[Typo].insert(TypoLoc);
+    return TypoCorrection();
+  }
+
+public:
+  /// AddInstanceMethodToGlobalPool - All instance methods in a translation
+  /// unit are added to a global pool. This allows us to efficiently associate
+  /// a selector with a method declaraation for purposes of typechecking
+  /// messages sent to "id" (where the class of the object is unknown).
+  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
+    AddMethodToGlobalPool(Method, impl, /*instance*/true);
+  }
+
+  /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
+  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) {
+    AddMethodToGlobalPool(Method, impl, /*instance*/false);
+  }
+
+  /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
+  /// pool.
+  void AddAnyMethodToGlobalPool(Decl *D);
+
+  /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
+                                                   bool receiverIdOrClass=false,
+                                                   bool warn=true) {
+    return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass,
+                                    warn, /*instance*/true);
+  }
+
+  /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
+  /// there are multiple signatures.
+  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R,
+                                                  bool receiverIdOrClass=false,
+                                                  bool warn=true) {
+    return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass,
+                                    warn, /*instance*/false);
+  }
+
+  const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel,
+                              QualType ObjectType=QualType());
+  /// LookupImplementedMethodInGlobalPool - Returns the method which has an
+  /// implementation.
+  ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
+
+  /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
+  /// initialization.
+  void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
+                                  SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
+  //===--------------------------------------------------------------------===//
+  // Statement Parsing Callbacks: SemaStmt.cpp.
+public:
+  class FullExprArg {
+  public:
+    FullExprArg(Sema &actions) : E(nullptr) { }
+
+    // FIXME: The const_cast here is ugly. RValue references would make this
+    // much nicer (or we could duplicate a bunch of the move semantics
+    // emulation code from Ownership.h).
+    FullExprArg(const FullExprArg& Other) : E(Other.E) {}
+
+    ExprResult release() {
+      return E;
+    }
+
+    Expr *get() const { return E; }
+
+    Expr *operator->() {
+      return E;
+    }
+
+  private:
+    // FIXME: No need to make the entire Sema class a friend when it's just
+    // Sema::MakeFullExpr that needs access to the constructor below.
+    friend class Sema;
+
+    explicit FullExprArg(Expr *expr) : E(expr) {}
+
+    Expr *E;
+  };
+
+  FullExprArg MakeFullExpr(Expr *Arg) {
+    return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
+  }
+  FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
+    return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
+  }
+  FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
+    ExprResult FE =
+      ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
+                          /*DiscardedValue*/ true);
+    return FullExprArg(FE.get());
+  }
+
+  StmtResult ActOnExprStmt(ExprResult Arg);
+  StmtResult ActOnExprStmtError();
+
+  StmtResult ActOnNullStmt(SourceLocation SemiLoc,
+                           bool HasLeadingEmptyMacro = false);
+
+  void ActOnStartOfCompoundStmt();
+  void ActOnFinishOfCompoundStmt();
+  StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+                               ArrayRef<Stmt *> Elts, bool isStmtExpr);
+
+  /// \brief A RAII object to enter scope of a compound statement.
+  class CompoundScopeRAII {
+  public:
+    CompoundScopeRAII(Sema &S): S(S) {
+      S.ActOnStartOfCompoundStmt();
+    }
+
+    ~CompoundScopeRAII() {
+      S.ActOnFinishOfCompoundStmt();
+    }
+
+  private:
+    Sema &S;
+  };
+
+  StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
+                                   SourceLocation StartLoc,
+                                   SourceLocation EndLoc);
+  void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
+  StmtResult ActOnForEachLValueExpr(Expr *E);
+  StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
+                                   SourceLocation DotDotDotLoc, Expr *RHSVal,
+                                   SourceLocation ColonLoc);
+  void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt);
+
+  StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+                                      SourceLocation ColonLoc,
+                                      Stmt *SubStmt, Scope *CurScope);
+  StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
+                            SourceLocation ColonLoc, Stmt *SubStmt);
+
+  StmtResult ActOnAttributedStmt(SourceLocation AttrLoc,
+                                 ArrayRef<const Attr*> Attrs,
+                                 Stmt *SubStmt);
+
+  StmtResult ActOnIfStmt(SourceLocation IfLoc,
+                         FullExprArg CondVal, Decl *CondVar,
+                         Stmt *ThenVal,
+                         SourceLocation ElseLoc, Stmt *ElseVal);
+  StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
+                                            Expr *Cond,
+                                            Decl *CondVar);
+  StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+                                           Stmt *Switch, Stmt *Body);
+  StmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                            FullExprArg Cond,
+                            Decl *CondVar, Stmt *Body);
+  StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
+                                 SourceLocation WhileLoc,
+                                 SourceLocation CondLParen, Expr *Cond,
+                                 SourceLocation CondRParen);
+
+  StmtResult ActOnForStmt(SourceLocation ForLoc,
+                          SourceLocation LParenLoc,
+                          Stmt *First, FullExprArg Second,
+                          Decl *SecondVar,
+                          FullExprArg Third,
+                          SourceLocation RParenLoc,
+                          Stmt *Body);
+  ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc,
+                                           Expr *collection);
+  StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+                                        Stmt *First, Expr *collection,
+                                        SourceLocation RParenLoc);
+  StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body);
+
+  enum BuildForRangeKind {
+    /// Initial building of a for-range statement.
+    BFRK_Build,
+    /// Instantiation or recovery rebuild of a for-range statement. Don't
+    /// attempt any typo-correction.
+    BFRK_Rebuild,
+    /// Determining whether a for-range statement could be built. Avoid any
+    /// unnecessary or irreversible actions.
+    BFRK_Check
+  };
+
+  StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, Stmt *LoopVar,
+                                  SourceLocation ColonLoc, Expr *Collection,
+                                  SourceLocation RParenLoc,
+                                  BuildForRangeKind Kind);
+  StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc,
+                                  SourceLocation ColonLoc,
+                                  Stmt *RangeDecl, Stmt *BeginEndDecl,
+                                  Expr *Cond, Expr *Inc,
+                                  Stmt *LoopVarDecl,
+                                  SourceLocation RParenLoc,
+                                  BuildForRangeKind Kind);
+  StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body);
+
+  StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+                           SourceLocation LabelLoc,
+                           LabelDecl *TheDecl);
+  StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+                                   SourceLocation StarLoc,
+                                   Expr *DestExp);
+  StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope);
+  StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope);
+
+  void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+                                CapturedRegionKind Kind, unsigned NumParams);
+  typedef std::pair<StringRef, QualType> CapturedParamNameType;
+  void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+                                CapturedRegionKind Kind,
+                                ArrayRef<CapturedParamNameType> Params);
+  StmtResult ActOnCapturedRegionEnd(Stmt *S);
+  void ActOnCapturedRegionError();
+  RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
+                                           SourceLocation Loc,
+                                           unsigned NumParams);
+  VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
+                                   bool AllowFunctionParameters);
+  bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
+                              bool AllowFunctionParameters);
+
+  StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
+                             Scope *CurScope);
+  StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
+  StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
+
+  StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
+                             bool IsVolatile, unsigned NumOutputs,
+                             unsigned NumInputs, IdentifierInfo **Names,
+                             MultiExprArg Constraints, MultiExprArg Exprs,
+                             Expr *AsmString, MultiExprArg Clobbers,
+                             SourceLocation RParenLoc);
+
+  ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
+                                       SourceLocation TemplateKWLoc,
+                                       UnqualifiedId &Id,
+                                       llvm::InlineAsmIdentifierInfo &Info,
+                                       bool IsUnevaluatedContext);
+  bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                            unsigned &Offset, SourceLocation AsmLoc);
+  StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
+                            ArrayRef<Token> AsmToks,
+                            StringRef AsmString,
+                            unsigned NumOutputs, unsigned NumInputs,
+                            ArrayRef<StringRef> Constraints,
+                            ArrayRef<StringRef> Clobbers,
+                            ArrayRef<Expr*> Exprs,
+                            SourceLocation EndLoc);
+
+  VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
+                                  SourceLocation StartLoc,
+                                  SourceLocation IdLoc, IdentifierInfo *Id,
+                                  bool Invalid = false);
+
+  Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D);
+
+  StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen,
+                                  Decl *Parm, Stmt *Body);
+
+  StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body);
+
+  StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
+                                MultiStmtArg Catch, Stmt *Finally);
+
+  StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw);
+  StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw,
+                                  Scope *CurScope);
+  ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc,
+                                            Expr *operand);
+  StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                         Expr *SynchExpr,
+                                         Stmt *SynchBody);
+
+  StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body);
+
+  VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo,
+                                     SourceLocation StartLoc,
+                                     SourceLocation IdLoc,
+                                     IdentifierInfo *Id);
+
+  Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D);
+
+  StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
+                                Decl *ExDecl, Stmt *HandlerBlock);
+  StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
+                              ArrayRef<Stmt *> Handlers);
+
+  StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ?
+                              SourceLocation TryLoc, Stmt *TryBlock,
+                              Stmt *Handler, int HandlerIndex,
+                              int HandlerParentIndex);
+  StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr,
+                                 Stmt *Block);
+  StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block);
+  StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope);
+
+  void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
+
+  bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const;
+
+  /// \brief If it's a file scoped decl that must warn if not used, keep track
+  /// of it.
+  void MarkUnusedFileScopedDecl(const DeclaratorDecl *D);
+
+  /// DiagnoseUnusedExprResult - If the statement passed in is an expression
+  /// whose result is unused, warn.
+  void DiagnoseUnusedExprResult(const Stmt *S);
+  void DiagnoseUnusedDecl(const NamedDecl *ND);
+
+  /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
+  /// statement as a \p Body, and it is located on the same line.
+  ///
+  /// This helps prevent bugs due to typos, such as:
+  ///     if (condition);
+  ///       do_stuff();
+  void DiagnoseEmptyStmtBody(SourceLocation StmtLoc,
+                             const Stmt *Body,
+                             unsigned DiagID);
+
+  /// Warn if a for/while loop statement \p S, which is followed by
+  /// \p PossibleBody, has a suspicious null statement as a body.
+  void DiagnoseEmptyLoopBody(const Stmt *S,
+                             const Stmt *PossibleBody);
+
+  ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
+    return DelayedDiagnostics.push(pool);
+  }
+  void PopParsingDeclaration(ParsingDeclState state, Decl *decl);
+
+  typedef ProcessingContextState ParsingClassState;
+  ParsingClassState PushParsingClass() {
+    return DelayedDiagnostics.pushUndelayed();
+  }
+  void PopParsingClass(ParsingClassState state) {
+    DelayedDiagnostics.popUndelayed(state);
+  }
+
+  void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
+
+  enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable };
+
+  void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
+                               NamedDecl *D, StringRef Message,
+                               SourceLocation Loc,
+                               const ObjCInterfaceDecl *UnknownObjCClass,
+                               const ObjCPropertyDecl  *ObjCProperty,
+                               bool ObjCPropertyAccess);
+
+  void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+
+  bool makeUnavailableInSystemHeader(SourceLocation loc,
+                                     StringRef message);
+
+  //===--------------------------------------------------------------------===//
+  // Expression Parsing Callbacks: SemaExpr.cpp.
+
+  bool CanUseDecl(NamedDecl *D);
+  bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
+                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr,
+                         bool ObjCPropertyAccess=false);
+  void NoteDeletedFunction(FunctionDecl *FD);
+  std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
+  bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
+                                        ObjCMethodDecl *Getter,
+                                        SourceLocation Loc);
+  void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+                             ArrayRef<Expr *> Args);
+
+  void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
+                                       Decl *LambdaContextDecl = nullptr,
+                                       bool IsDecltype = false);
+  enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
+  void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
+                                       ReuseLambdaContextDecl_t,
+                                       bool IsDecltype = false);
+  void PopExpressionEvaluationContext();
+
+  void DiscardCleanupsInEvaluationContext();
+
+  ExprResult TransformToPotentiallyEvaluated(Expr *E);
+  ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
+
+  ExprResult ActOnConstantExpression(ExprResult Res);
+
+  // Functions for marking a declaration referenced.  These functions also
+  // contain the relevant logic for marking if a reference to a function or
+  // variable is an odr-use (in the C++11 sense).  There are separate variants
+  // for expressions referring to a decl; these exist because odr-use marking
+  // needs to be delayed for some constant variables when we build one of the
+  // named expressions.
+  void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
+  void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
+  void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
+  void MarkDeclRefReferenced(DeclRefExpr *E);
+  void MarkMemberReferenced(MemberExpr *E);
+
+  void UpdateMarkingForLValueToRValue(Expr *E);
+  void CleanupVarDeclMarking();
+
+  enum TryCaptureKind {
+    TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef
+  };
+
+  /// \brief Try to capture the given variable.
+  ///
+  /// \param Var The variable to capture.
+  ///
+  /// \param Loc The location at which the capture occurs.
+  ///
+  /// \param Kind The kind of capture, which may be implicit (for either a
+  /// block or a lambda), or explicit by-value or by-reference (for a lambda).
+  ///
+  /// \param EllipsisLoc The location of the ellipsis, if one is provided in
+  /// an explicit lambda capture.
+  ///
+  /// \param BuildAndDiagnose Whether we are actually supposed to add the
+  /// captures or diagnose errors. If false, this routine merely check whether
+  /// the capture can occur without performing the capture itself or complaining
+  /// if the variable cannot be captured.
+  ///
+  /// \param CaptureType Will be set to the type of the field used to capture
+  /// this variable in the innermost block or lambda. Only valid when the
+  /// variable can be captured.
+  ///
+  /// \param DeclRefType Will be set to the type of a reference to the capture
+  /// from within the current scope. Only valid when the variable can be
+  /// captured.
+  ///
+  /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
+  /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
+  /// This is useful when enclosing lambdas must speculatively capture 
+  /// variables that may or may not be used in certain specializations of
+  /// a nested generic lambda.
+  /// 
+  /// \returns true if an error occurred (i.e., the variable cannot be
+  /// captured) and false if the capture succeeded.
+  bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
+                          SourceLocation EllipsisLoc, bool BuildAndDiagnose,
+                          QualType &CaptureType,
+                          QualType &DeclRefType, 
+                          const unsigned *const FunctionScopeIndexToStopAt);
+
+  /// \brief Try to capture the given variable.
+  bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
+                          TryCaptureKind Kind = TryCapture_Implicit,
+                          SourceLocation EllipsisLoc = SourceLocation());
+
+  /// \brief Given a variable, determine the type that a reference to that
+  /// variable will have in the given scope.
+  QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
+
+  void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
+  void MarkDeclarationsReferencedInExpr(Expr *E,
+                                        bool SkipLocalVariables = false);
+
+  /// \brief Try to recover by turning the given expression into a
+  /// call.  Returns true if recovery was attempted or an error was
+  /// emitted; this may also leave the ExprResult invalid.
+  bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
+                            bool ForceComplain = false,
+                            bool (*IsPlausibleResult)(QualType) = nullptr);
+
+  /// \brief Figure out if an expression could be turned into a call.
+  bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
+                     UnresolvedSetImpl &NonTemplateOverloads);
+
+  /// \brief Conditionally issue a diagnostic based on the current
+  /// evaluation context.
+  ///
+  /// \param Statement If Statement is non-null, delay reporting the
+  /// diagnostic until the function body is parsed, and then do a basic
+  /// reachability analysis to determine if the statement is reachable.
+  /// If it is unreachable, the diagnostic will not be emitted.
+  bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
+                           const PartialDiagnostic &PD);
+
+  // Primary Expressions.
+  SourceRange getExprRange(Expr *E) const;
+
+  ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
+                               SourceLocation TemplateKWLoc,
+                               UnqualifiedId &Id,
+                               bool HasTrailingLParen, bool IsAddressOfOperand,
+                               CorrectionCandidateCallback *CCC = nullptr,
+                               bool IsInlineAsmIdentifier = false);
+
+  void DecomposeUnqualifiedId(const UnqualifiedId &Id,
+                              TemplateArgumentListInfo &Buffer,
+                              DeclarationNameInfo &NameInfo,
+                              const TemplateArgumentListInfo *&TemplateArgs);
+
+  bool
+  DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+                      CorrectionCandidateCallback &CCC,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
+                      ArrayRef<Expr *> Args = None);
+
+  ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
+                                IdentifierInfo *II,
+                                bool AllowBuiltinCreation=false);
+
+  ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
+                                        SourceLocation TemplateKWLoc,
+                                        const DeclarationNameInfo &NameInfo,
+                                        bool isAddressOfOperand,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                              ExprValueKind VK,
+                              SourceLocation Loc,
+                              const CXXScopeSpec *SS = nullptr);
+  ExprResult
+  BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
+                   const DeclarationNameInfo &NameInfo,
+                   const CXXScopeSpec *SS = nullptr,
+                   NamedDecl *FoundD = nullptr,
+                   const TemplateArgumentListInfo *TemplateArgs = nullptr);
+  ExprResult
+  BuildAnonymousStructUnionMemberReference(
+      const CXXScopeSpec &SS,
+      SourceLocation nameLoc,
+      IndirectFieldDecl *indirectField,
+      DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none),
+      Expr *baseObjectExpr = nullptr,
+      SourceLocation opLoc = SourceLocation());
+
+  ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
+                                             SourceLocation TemplateKWLoc,
+                                             LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs);
+  ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
+                                     SourceLocation TemplateKWLoc,
+                                     LookupResult &R,
+                                const TemplateArgumentListInfo *TemplateArgs,
+                                     bool IsDefiniteInstance);
+  bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
+                                  const LookupResult &R,
+                                  bool HasTrailingLParen);
+
+  ExprResult BuildQualifiedDeclarationNameExpr(
+      CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo,
+      bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
+
+  ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
+                                       SourceLocation TemplateKWLoc,
+                                const DeclarationNameInfo &NameInfo,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                      LookupResult &R,
+                                      bool NeedsADL);
+  ExprResult BuildDeclarationNameExpr(
+      const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
+      NamedDecl *FoundD = nullptr,
+      const TemplateArgumentListInfo *TemplateArgs = nullptr);
+
+  ExprResult BuildLiteralOperatorCall(LookupResult &R,
+                      DeclarationNameInfo &SuffixInfo,
+                      ArrayRef<Expr *> Args,
+                      SourceLocation LitEndLoc,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
+
+  ExprResult BuildPredefinedExpr(SourceLocation Loc,
+                                 PredefinedExpr::IdentType IT);
+  ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
+  ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
+  ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
+  ExprResult ActOnCharacterConstant(const Token &Tok,
+                                    Scope *UDLScope = nullptr);
+  ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
+  ExprResult ActOnParenListExpr(SourceLocation L,
+                                SourceLocation R,
+                                MultiExprArg Val);
+
+  /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+  /// fragments (e.g. "foo" "bar" L"baz").
+  ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks,
+                                Scope *UDLScope = nullptr);
+
+  ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
+                                       SourceLocation DefaultLoc,
+                                       SourceLocation RParenLoc,
+                                       Expr *ControllingExpr,
+                                       ArrayRef<ParsedType> ArgTypes,
+                                       ArrayRef<Expr *> ArgExprs);
+  ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc,
+                                        SourceLocation DefaultLoc,
+                                        SourceLocation RParenLoc,
+                                        Expr *ControllingExpr,
+                                        ArrayRef<TypeSourceInfo *> Types,
+                                        ArrayRef<Expr *> Exprs);
+
+  // Binary/Unary Operators.  'Tok' is the token for the operator.
+  ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
+                                  Expr *InputExpr);
+  ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                          UnaryOperatorKind Opc, Expr *Input);
+  ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                          tok::TokenKind Op, Expr *Input);
+
+  QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc);
+
+  ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
+                                            SourceLocation OpLoc,
+                                            UnaryExprOrTypeTrait ExprKind,
+                                            SourceRange R);
+  ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
+                                            UnaryExprOrTypeTrait ExprKind);
+  ExprResult
+    ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
+                                  UnaryExprOrTypeTrait ExprKind,
+                                  bool IsType, void *TyOrEx,
+                                  const SourceRange &ArgRange);
+
+  ExprResult CheckPlaceholderExpr(Expr *E);
+  bool CheckVecStepExpr(Expr *E);
+
+  bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind);
+  bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc,
+                                        SourceRange ExprRange,
+                                        UnaryExprOrTypeTrait ExprKind);
+  ExprResult ActOnSizeofParameterPackExpr(Scope *S,
+                                          SourceLocation OpLoc,
+                                          IdentifierInfo &Name,
+                                          SourceLocation NameLoc,
+                                          SourceLocation RParenLoc);
+  ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
+                                 tok::TokenKind Kind, Expr *Input);
+
+  ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
+                                     Expr *Idx, SourceLocation RLoc);
+  ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+                                             Expr *Idx, SourceLocation RLoc);
+
+  // This struct is for use by ActOnMemberAccess to allow
+  // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
+  // changing the access operator from a '.' to a '->' (to see if that is the
+  // change needed to fix an error about an unknown member, e.g. when the class
+  // defines a custom operator->).
+  struct ActOnMemberAccessExtraArgs {
+    Scope *S;
+    UnqualifiedId &Id;
+    Decl *ObjCImpDecl;
+    bool HasTrailingLParen;
+  };
+
+  ExprResult BuildMemberReferenceExpr(
+      Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
+      CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+      NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
+      const TemplateArgumentListInfo *TemplateArgs,
+      ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+
+  ExprResult
+  BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
+                           bool IsArrow, const CXXScopeSpec &SS,
+                           SourceLocation TemplateKWLoc,
+                           NamedDecl *FirstQualifierInScope, LookupResult &R,
+                           const TemplateArgumentListInfo *TemplateArgs,
+                           bool SuppressQualifierCheck = false,
+                           ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+
+  ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
+
+  bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
+                                     const CXXScopeSpec &SS,
+                                     const LookupResult &R);
+
+  ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType,
+                                      bool IsArrow, SourceLocation OpLoc,
+                                      const CXXScopeSpec &SS,
+                                      SourceLocation TemplateKWLoc,
+                                      NamedDecl *FirstQualifierInScope,
+                               const DeclarationNameInfo &NameInfo,
+                               const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base,
+                                   SourceLocation OpLoc,
+                                   tok::TokenKind OpKind,
+                                   CXXScopeSpec &SS,
+                                   SourceLocation TemplateKWLoc,
+                                   UnqualifiedId &Member,
+                                   Decl *ObjCImpDecl,
+                                   bool HasTrailingLParen);
+
+  void ActOnDefaultCtorInitializers(Decl *CDtorDecl);
+  bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
+                               FunctionDecl *FDecl,
+                               const FunctionProtoType *Proto,
+                               ArrayRef<Expr *> Args,
+                               SourceLocation RParenLoc,
+                               bool ExecConfig = false);
+  void CheckStaticArrayArgument(SourceLocation CallLoc,
+                                ParmVarDecl *Param,
+                                const Expr *ArgExpr);
+
+  /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
+  /// This provides the location of the left/right parens and a list of comma
+  /// locations.
+  ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
+                           MultiExprArg ArgExprs, SourceLocation RParenLoc,
+                           Expr *ExecConfig = nullptr,
+                           bool IsExecConfig = false);
+  ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
+                                   SourceLocation LParenLoc,
+                                   ArrayRef<Expr *> Arg,
+                                   SourceLocation RParenLoc,
+                                   Expr *Config = nullptr,
+                                   bool IsExecConfig = false);
+
+  ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
+                                     MultiExprArg ExecConfig,
+                                     SourceLocation GGGLoc);
+
+  ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
+                           Declarator &D, ParsedType &Ty,
+                           SourceLocation RParenLoc, Expr *CastExpr);
+  ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
+                                 TypeSourceInfo *Ty,
+                                 SourceLocation RParenLoc,
+                                 Expr *Op);
+  CastKind PrepareScalarCast(ExprResult &src, QualType destType);
+
+  /// \brief Build an altivec or OpenCL literal.
+  ExprResult BuildVectorLiteral(SourceLocation LParenLoc,
+                                SourceLocation RParenLoc, Expr *E,
+                                TypeSourceInfo *TInfo);
+
+  ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME);
+
+  ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
+                                  ParsedType Ty,
+                                  SourceLocation RParenLoc,
+                                  Expr *InitExpr);
+
+  ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
+                                      TypeSourceInfo *TInfo,
+                                      SourceLocation RParenLoc,
+                                      Expr *LiteralExpr);
+
+  ExprResult ActOnInitList(SourceLocation LBraceLoc,
+                           MultiExprArg InitArgList,
+                           SourceLocation RBraceLoc);
+
+  ExprResult ActOnDesignatedInitializer(Designation &Desig,
+                                        SourceLocation Loc,
+                                        bool GNUSyntax,
+                                        ExprResult Init);
+
+  ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                        tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr);
+  ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
+                        BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr);
+  ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc,
+                                Expr *LHSExpr, Expr *RHSExpr);
+
+  /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
+  /// in the case of a the GNU conditional expr extension.
+  ExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
+                                SourceLocation ColonLoc,
+                                Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr);
+
+  /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
+  ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
+                            LabelDecl *TheDecl);
+
+  void ActOnStartStmtExpr();
+  ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
+                           SourceLocation RPLoc); // "({..})"
+  void ActOnStmtExprError();
+
+  // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+  struct OffsetOfComponent {
+    SourceLocation LocStart, LocEnd;
+    bool isBrackets;  // true if [expr], false if .ident
+    union {
+      IdentifierInfo *IdentInfo;
+      Expr *E;
+    } U;
+  };
+
+  /// __builtin_offsetof(type, a.b[123][456].c)
+  ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+                                  TypeSourceInfo *TInfo,
+                                  OffsetOfComponent *CompPtr,
+                                  unsigned NumComponents,
+                                  SourceLocation RParenLoc);
+  ExprResult ActOnBuiltinOffsetOf(Scope *S,
+                                  SourceLocation BuiltinLoc,
+                                  SourceLocation TypeLoc,
+                                  ParsedType ParsedArgTy,
+                                  OffsetOfComponent *CompPtr,
+                                  unsigned NumComponents,
+                                  SourceLocation RParenLoc);
+
+  // __builtin_choose_expr(constExpr, expr1, expr2)
+  ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
+                             Expr *CondExpr, Expr *LHSExpr,
+                             Expr *RHSExpr, SourceLocation RPLoc);
+
+  // __builtin_va_arg(expr, type)
+  ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty,
+                        SourceLocation RPLoc);
+  ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
+                            TypeSourceInfo *TInfo, SourceLocation RPLoc);
+
+  // __null
+  ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
+
+  bool CheckCaseExpression(Expr *E);
+
+  /// \brief Describes the result of an "if-exists" condition check.
+  enum IfExistsResult {
+    /// \brief The symbol exists.
+    IER_Exists,
+
+    /// \brief The symbol does not exist.
+    IER_DoesNotExist,
+
+    /// \brief The name is a dependent name, so the results will differ
+    /// from one instantiation to the next.
+    IER_Dependent,
+
+    /// \brief An error occurred.
+    IER_Error
+  };
+
+  IfExistsResult
+  CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS,
+                               const DeclarationNameInfo &TargetNameInfo);
+
+  IfExistsResult
+  CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
+                               bool IsIfExists, CXXScopeSpec &SS,
+                               UnqualifiedId &Name);
+
+  StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
+                                        bool IsIfExists,
+                                        NestedNameSpecifierLoc QualifierLoc,
+                                        DeclarationNameInfo NameInfo,
+                                        Stmt *Nested);
+  StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
+                                        bool IsIfExists,
+                                        CXXScopeSpec &SS, UnqualifiedId &Name,
+                                        Stmt *Nested);
+
+  //===------------------------- "Block" Extension ------------------------===//
+
+  /// ActOnBlockStart - This callback is invoked when a block literal is
+  /// started.
+  void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
+
+  /// ActOnBlockArguments - This callback allows processing of block arguments.
+  /// If there are no arguments, this is still invoked.
+  void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
+                           Scope *CurScope);
+
+  /// ActOnBlockError - If there is an error parsing a block, this callback
+  /// is invoked to pop the information about the block from the action impl.
+  void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
+
+  /// ActOnBlockStmtExpr - This is called when the body of a block statement
+  /// literal was successfully completed.  ^(int x){...}
+  ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body,
+                                Scope *CurScope);
+
+  //===---------------------------- Clang Extensions ----------------------===//
+
+  /// __builtin_convertvector(...)
+  ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy,
+                                    SourceLocation BuiltinLoc,
+                                    SourceLocation RParenLoc);
+
+  //===---------------------------- OpenCL Features -----------------------===//
+
+  /// __builtin_astype(...)
+  ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy,
+                             SourceLocation BuiltinLoc,
+                             SourceLocation RParenLoc);
+
+  //===---------------------------- C++ Features --------------------------===//
+
+  // Act on C++ namespaces
+  Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc,
+                               SourceLocation NamespaceLoc,
+                               SourceLocation IdentLoc,
+                               IdentifierInfo *Ident,
+                               SourceLocation LBrace,
+                               AttributeList *AttrList);
+  void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
+
+  NamespaceDecl *getStdNamespace() const;
+  NamespaceDecl *getOrCreateStdNamespace();
+
+  CXXRecordDecl *getStdBadAlloc() const;
+
+  /// \brief Tests whether Ty is an instance of std::initializer_list and, if
+  /// it is and Element is not NULL, assigns the element type to Element.
+  bool isStdInitializerList(QualType Ty, QualType *Element);
+
+  /// \brief Looks for the std::initializer_list template and instantiates it
+  /// with Element, or emits an error if it's not found.
+  ///
+  /// \returns The instantiated template, or null on error.
+  QualType BuildStdInitializerList(QualType Element, SourceLocation Loc);
+
+  /// \brief Determine whether Ctor is an initializer-list constructor, as
+  /// defined in [dcl.init.list]p2.
+  bool isInitListConstructor(const CXXConstructorDecl *Ctor);
+
+  Decl *ActOnUsingDirective(Scope *CurScope,
+                            SourceLocation UsingLoc,
+                            SourceLocation NamespcLoc,
+                            CXXScopeSpec &SS,
+                            SourceLocation IdentLoc,
+                            IdentifierInfo *NamespcName,
+                            AttributeList *AttrList);
+
+  void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
+
+  Decl *ActOnNamespaceAliasDef(Scope *CurScope,
+                               SourceLocation NamespaceLoc,
+                               SourceLocation AliasLoc,
+                               IdentifierInfo *Alias,
+                               CXXScopeSpec &SS,
+                               SourceLocation IdentLoc,
+                               IdentifierInfo *Ident);
+
+  void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
+  bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
+                            const LookupResult &PreviousDecls,
+                            UsingShadowDecl *&PrevShadow);
+  UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
+                                        NamedDecl *Target,
+                                        UsingShadowDecl *PrevDecl);
+
+  bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
+                                   bool HasTypenameKeyword,
+                                   const CXXScopeSpec &SS,
+                                   SourceLocation NameLoc,
+                                   const LookupResult &Previous);
+  bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
+                               const CXXScopeSpec &SS,
+                               const DeclarationNameInfo &NameInfo,
+                               SourceLocation NameLoc);
+
+  NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+                                   SourceLocation UsingLoc,
+                                   CXXScopeSpec &SS,
+                                   DeclarationNameInfo NameInfo,
+                                   AttributeList *AttrList,
+                                   bool IsInstantiation,
+                                   bool HasTypenameKeyword,
+                                   SourceLocation TypenameLoc);
+
+  bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
+
+  Decl *ActOnUsingDeclaration(Scope *CurScope,
+                              AccessSpecifier AS,
+                              bool HasUsingKeyword,
+                              SourceLocation UsingLoc,
+                              CXXScopeSpec &SS,
+                              UnqualifiedId &Name,
+                              AttributeList *AttrList,
+                              bool HasTypenameKeyword,
+                              SourceLocation TypenameLoc);
+  Decl *ActOnAliasDeclaration(Scope *CurScope,
+                              AccessSpecifier AS,
+                              MultiTemplateParamsArg TemplateParams,
+                              SourceLocation UsingLoc,
+                              UnqualifiedId &Name,
+                              AttributeList *AttrList,
+                              TypeResult Type);
+
+  /// BuildCXXConstructExpr - Creates a complete call to a constructor,
+  /// including handling of its default argument expressions.
+  ///
+  /// \param ConstructKind - a CXXConstructExpr::ConstructionKind
+  ExprResult
+  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                        CXXConstructorDecl *Constructor, MultiExprArg Exprs,
+                        bool HadMultipleCandidates, bool IsListInitialization,
+                        bool IsStdInitListInitialization,
+                        bool RequiresZeroInit, unsigned ConstructKind,
+                        SourceRange ParenRange);
+
+  // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
+  // the constructor can be elidable?
+  ExprResult
+  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
+                        CXXConstructorDecl *Constructor, bool Elidable,
+                        MultiExprArg Exprs, bool HadMultipleCandidates,
+                        bool IsListInitialization,
+                        bool IsStdInitListInitialization, bool RequiresZeroInit,
+                        unsigned ConstructKind, SourceRange ParenRange);
+
+  /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
+  /// the default expr if needed.
+  ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+                                    FunctionDecl *FD,
+                                    ParmVarDecl *Param);
+
+  /// FinalizeVarWithDestructor - Prepare for calling destructor on the
+  /// constructed variable.
+  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
+
+  /// \brief Helper class that collects exception specifications for
+  /// implicitly-declared special member functions.
+  class ImplicitExceptionSpecification {
+    // Pointer to allow copying
+    Sema *Self;
+    // We order exception specifications thus:
+    // noexcept is the most restrictive, but is only used in C++11.
+    // throw() comes next.
+    // Then a throw(collected exceptions)
+    // Finally no specification, which is expressed as noexcept(false).
+    // throw(...) is used instead if any called function uses it.
+    ExceptionSpecificationType ComputedEST;
+    llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
+    SmallVector<QualType, 4> Exceptions;
+
+    void ClearExceptions() {
+      ExceptionsSeen.clear();
+      Exceptions.clear();
+    }
+
+  public:
+    explicit ImplicitExceptionSpecification(Sema &Self)
+      : Self(&Self), ComputedEST(EST_BasicNoexcept) {
+      if (!Self.getLangOpts().CPlusPlus11)
+        ComputedEST = EST_DynamicNone;
+    }
+
+    /// \brief Get the computed exception specification type.
+    ExceptionSpecificationType getExceptionSpecType() const {
+      assert(ComputedEST != EST_ComputedNoexcept &&
+             "noexcept(expr) should not be a possible result");
+      return ComputedEST;
+    }
+
+    /// \brief The number of exceptions in the exception specification.
+    unsigned size() const { return Exceptions.size(); }
+
+    /// \brief The set of exceptions in the exception specification.
+    const QualType *data() const { return Exceptions.data(); }
+
+    /// \brief Integrate another called method into the collected data.
+    void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method);
+
+    /// \brief Integrate an invoked expression into the collected data.
+    void CalledExpr(Expr *E);
+
+    /// \brief Overwrite an EPI's exception specification with this
+    /// computed exception specification.
+    void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
+      EPI.ExceptionSpecType = getExceptionSpecType();
+      if (EPI.ExceptionSpecType == EST_Dynamic) {
+        EPI.NumExceptions = size();
+        EPI.Exceptions = data();
+      } else if (EPI.ExceptionSpecType == EST_None) {
+        /// C++11 [except.spec]p14:
+        ///   The exception-specification is noexcept(false) if the set of
+        ///   potential exceptions of the special member function contains "any"
+        EPI.ExceptionSpecType = EST_ComputedNoexcept;
+        EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
+                                                     tok::kw_false).get();
+      }
+    }
+    FunctionProtoType::ExtProtoInfo getEPI() const {
+      FunctionProtoType::ExtProtoInfo EPI;
+      getEPI(EPI);
+      return EPI;
+    }
+  };
+
+  /// \brief Determine what sort of exception specification a defaulted
+  /// copy constructor of a class will have.
+  ImplicitExceptionSpecification
+  ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
+                                           CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification a defaulted
+  /// default constructor of a class will have, and whether the parameter
+  /// will be const.
+  ImplicitExceptionSpecification
+  ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification a defautled
+  /// copy assignment operator of a class will have, and whether the
+  /// parameter will be const.
+  ImplicitExceptionSpecification
+  ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification a defaulted move
+  /// constructor of a class will have.
+  ImplicitExceptionSpecification
+  ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification a defaulted move
+  /// assignment operator of a class will have.
+  ImplicitExceptionSpecification
+  ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification a defaulted
+  /// destructor of a class will have.
+  ImplicitExceptionSpecification
+  ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Determine what sort of exception specification an inheriting
+  /// constructor of a class will have.
+  ImplicitExceptionSpecification
+  ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD);
+
+  /// \brief Evaluate the implicit exception specification for a defaulted
+  /// special member function.
+  void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD);
+
+  /// \brief Check the given exception-specification and update the
+  /// extended prototype information with the results.
+  void checkExceptionSpecification(ExceptionSpecificationType EST,
+                                   ArrayRef<ParsedType> DynamicExceptions,
+                                   ArrayRef<SourceRange> DynamicExceptionRanges,
+                                   Expr *NoexceptExpr,
+                                   SmallVectorImpl<QualType> &Exceptions,
+                                   FunctionProtoType::ExtProtoInfo &EPI);
+
+  /// \brief Determine if a special member function should have a deleted
+  /// definition when it is defaulted.
+  bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+                                 bool Diagnose = false);
+
+  /// \brief Declare the implicit default constructor for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit
+  /// default constructor will be added.
+  ///
+  /// \returns The implicitly-declared default constructor.
+  CXXConstructorDecl *DeclareImplicitDefaultConstructor(
+                                                     CXXRecordDecl *ClassDecl);
+
+  /// DefineImplicitDefaultConstructor - Checks for feasibility of
+  /// defining this constructor as the default constructor.
+  void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
+                                        CXXConstructorDecl *Constructor);
+
+  /// \brief Declare the implicit destructor for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit
+  /// destructor will be added.
+  ///
+  /// \returns The implicitly-declared destructor.
+  CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl);
+
+  /// DefineImplicitDestructor - Checks for feasibility of
+  /// defining this destructor as the default destructor.
+  void DefineImplicitDestructor(SourceLocation CurrentLocation,
+                                CXXDestructorDecl *Destructor);
+
+  /// \brief Build an exception spec for destructors that don't have one.
+  ///
+  /// C++11 says that user-defined destructors with no exception spec get one
+  /// that looks as if the destructor was implicitly declared.
+  void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
+                                     CXXDestructorDecl *Destructor);
+
+  /// \brief Declare all inheriting constructors for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the inheriting
+  /// constructors will be added.
+  void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl);
+
+  /// \brief Define the specified inheriting constructor.
+  void DefineInheritingConstructor(SourceLocation UseLoc,
+                                   CXXConstructorDecl *Constructor);
+
+  /// \brief Declare the implicit copy constructor for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit
+  /// copy constructor will be added.
+  ///
+  /// \returns The implicitly-declared copy constructor.
+  CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl);
+
+  /// DefineImplicitCopyConstructor - Checks for feasibility of
+  /// defining this constructor as the copy constructor.
+  void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
+                                     CXXConstructorDecl *Constructor);
+
+  /// \brief Declare the implicit move constructor for the given class.
+  ///
+  /// \param ClassDecl The Class declaration into which the implicit
+  /// move constructor will be added.
+  ///
+  /// \returns The implicitly-declared move constructor, or NULL if it wasn't
+  /// declared.
+  CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl);
+
+  /// DefineImplicitMoveConstructor - Checks for feasibility of
+  /// defining this constructor as the move constructor.
+  void DefineImplicitMoveConstructor(SourceLocation CurrentLocation,
+                                     CXXConstructorDecl *Constructor);
+
+  /// \brief Declare the implicit copy assignment operator for the given class.
+  ///
+  /// \param ClassDecl The class declaration into which the implicit
+  /// copy assignment operator will be added.
+  ///
+  /// \returns The implicitly-declared copy assignment operator.
+  CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
+
+  /// \brief Defines an implicitly-declared copy assignment operator.
+  void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
+                                    CXXMethodDecl *MethodDecl);
+
+  /// \brief Declare the implicit move assignment operator for the given class.
+  ///
+  /// \param ClassDecl The Class declaration into which the implicit
+  /// move assignment operator will be added.
+  ///
+  /// \returns The implicitly-declared move assignment operator, or NULL if it
+  /// wasn't declared.
+  CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl);
+
+  /// \brief Defines an implicitly-declared move assignment operator.
+  void DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
+                                    CXXMethodDecl *MethodDecl);
+
+  /// \brief Force the declaration of any implicitly-declared members of this
+  /// class.
+  void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
+
+  /// \brief Determine whether the given function is an implicitly-deleted
+  /// special member function.
+  bool isImplicitlyDeleted(FunctionDecl *FD);
+
+  /// \brief Check whether 'this' shows up in the type of a static member
+  /// function after the (naturally empty) cv-qualifier-seq would be.
+  ///
+  /// \returns true if an error occurred.
+  bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method);
+
+  /// \brief Whether this' shows up in the exception specification of a static
+  /// member function.
+  bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method);
+
+  /// \brief Check whether 'this' shows up in the attributes of the given
+  /// static member function.
+  ///
+  /// \returns true if an error occurred.
+  bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method);
+
+  /// MaybeBindToTemporary - If the passed in expression has a record type with
+  /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
+  /// it simply returns the passed in expression.
+  ExprResult MaybeBindToTemporary(Expr *E);
+
+  bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
+                               MultiExprArg ArgsPtr,
+                               SourceLocation Loc,
+                               SmallVectorImpl<Expr*> &ConvertedArgs,
+                               bool AllowExplicit = false,
+                               bool IsListInitialization = false);
+
+  ParsedType getInheritingConstructorName(CXXScopeSpec &SS,
+                                          SourceLocation NameLoc,
+                                          IdentifierInfo &Name);
+
+  ParsedType getDestructorName(SourceLocation TildeLoc,
+                               IdentifierInfo &II, SourceLocation NameLoc,
+                               Scope *S, CXXScopeSpec &SS,
+                               ParsedType ObjectType,
+                               bool EnteringContext);
+
+  ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType);
+
+  // Checks that reinterpret casts don't have undefined behavior.
+  void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
+                                      bool IsDereference, SourceRange Range);
+
+  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
+  ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
+                               tok::TokenKind Kind,
+                               SourceLocation LAngleBracketLoc,
+                               Declarator &D,
+                               SourceLocation RAngleBracketLoc,
+                               SourceLocation LParenLoc,
+                               Expr *E,
+                               SourceLocation RParenLoc);
+
+  ExprResult BuildCXXNamedCast(SourceLocation OpLoc,
+                               tok::TokenKind Kind,
+                               TypeSourceInfo *Ty,
+                               Expr *E,
+                               SourceRange AngleBrackets,
+                               SourceRange Parens);
+
+  ExprResult BuildCXXTypeId(QualType TypeInfoType,
+                            SourceLocation TypeidLoc,
+                            TypeSourceInfo *Operand,
+                            SourceLocation RParenLoc);
+  ExprResult BuildCXXTypeId(QualType TypeInfoType,
+                            SourceLocation TypeidLoc,
+                            Expr *Operand,
+                            SourceLocation RParenLoc);
+
+  /// ActOnCXXTypeid - Parse typeid( something ).
+  ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+                            SourceLocation LParenLoc, bool isType,
+                            void *TyOrExpr,
+                            SourceLocation RParenLoc);
+
+  ExprResult BuildCXXUuidof(QualType TypeInfoType,
+                            SourceLocation TypeidLoc,
+                            TypeSourceInfo *Operand,
+                            SourceLocation RParenLoc);
+  ExprResult BuildCXXUuidof(QualType TypeInfoType,
+                            SourceLocation TypeidLoc,
+                            Expr *Operand,
+                            SourceLocation RParenLoc);
+
+  /// ActOnCXXUuidof - Parse __uuidof( something ).
+  ExprResult ActOnCXXUuidof(SourceLocation OpLoc,
+                            SourceLocation LParenLoc, bool isType,
+                            void *TyOrExpr,
+                            SourceLocation RParenLoc);
+
+
+  //// ActOnCXXThis -  Parse 'this' pointer.
+  ExprResult ActOnCXXThis(SourceLocation loc);
+
+  /// \brief Try to retrieve the type of the 'this' pointer.
+  ///
+  /// \returns The type of 'this', if possible. Otherwise, returns a NULL type.
+  QualType getCurrentThisType();
+
+  /// \brief When non-NULL, the C++ 'this' expression is allowed despite the
+  /// current context not being a non-static member function. In such cases,
+  /// this provides the type used for 'this'.
+  QualType CXXThisTypeOverride;
+
+  /// \brief RAII object used to temporarily allow the C++ 'this' expression
+  /// to be used, with the given qualifiers on the current class type.
+  class CXXThisScopeRAII {
+    Sema &S;
+    QualType OldCXXThisTypeOverride;
+    bool Enabled;
+
+  public:
+    /// \brief Introduce a new scope where 'this' may be allowed (when enabled),
+    /// using the given declaration (which is either a class template or a
+    /// class) along with the given qualifiers.
+    /// along with the qualifiers placed on '*this'.
+    CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals,
+                     bool Enabled = true);
+
+    ~CXXThisScopeRAII();
+  };
+
+  /// \brief Make sure the value of 'this' is actually available in the current
+  /// context, if it is a potentially evaluated context.
+  ///
+  /// \param Loc The location at which the capture of 'this' occurs.
+  ///
+  /// \param Explicit Whether 'this' is explicitly captured in a lambda
+  /// capture list.
+  ///
+  /// \param FunctionScopeIndexToStopAt If non-null, it points to the index
+  /// of the FunctionScopeInfo stack beyond which we do not attempt to capture.
+  /// This is useful when enclosing lambdas must speculatively capture 
+  /// 'this' that may or may not be used in certain specializations of
+  /// a nested generic lambda (depending on whether the name resolves to 
+  /// a non-static member function or a static function).
+  /// \return returns 'true' if failed, 'false' if success.
+  bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, 
+      bool BuildAndDiagnose = true,
+      const unsigned *const FunctionScopeIndexToStopAt = nullptr);
+
+  /// \brief Determine whether the given type is the type of *this that is used
+  /// outside of the body of a member function for a type that is currently
+  /// being defined.
+  bool isThisOutsideMemberFunctionBody(QualType BaseType);
+
+  /// ActOnCXXBoolLiteral - Parse {true,false} literals.
+  ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
+
+
+  /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
+  ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
+
+  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
+  ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
+
+  //// ActOnCXXThrow -  Parse throw expressions.
+  ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr);
+  ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
+                           bool IsThrownVarInScope);
+  ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
+                                  bool IsThrownVarInScope);
+
+  /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
+  /// Can be interpreted either as function-style casting ("int(x)")
+  /// or class type construction ("ClassType(x,y,z)")
+  /// or creation of a value-initialized type ("int()").
+  ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep,
+                                       SourceLocation LParenLoc,
+                                       MultiExprArg Exprs,
+                                       SourceLocation RParenLoc);
+
+  ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type,
+                                       SourceLocation LParenLoc,
+                                       MultiExprArg Exprs,
+                                       SourceLocation RParenLoc);
+
+  /// ActOnCXXNew - Parsed a C++ 'new' expression.
+  ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
+                         SourceLocation PlacementLParen,
+                         MultiExprArg PlacementArgs,
+                         SourceLocation PlacementRParen,
+                         SourceRange TypeIdParens, Declarator &D,
+                         Expr *Initializer);
+  ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal,
+                         SourceLocation PlacementLParen,
+                         MultiExprArg PlacementArgs,
+                         SourceLocation PlacementRParen,
+                         SourceRange TypeIdParens,
+                         QualType AllocType,
+                         TypeSourceInfo *AllocTypeInfo,
+                         Expr *ArraySize,
+                         SourceRange DirectInitRange,
+                         Expr *Initializer,
+                         bool TypeMayContainAuto = true);
+
+  bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
+                          SourceRange R);
+  bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
+                               bool UseGlobal, QualType AllocType, bool IsArray,
+                               MultiExprArg PlaceArgs,
+                               FunctionDecl *&OperatorNew,
+                               FunctionDecl *&OperatorDelete);
+  bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
+                              DeclarationName Name, MultiExprArg Args,
+                              DeclContext *Ctx,
+                              bool AllowMissing, FunctionDecl *&Operator,
+                              bool Diagnose = true);
+  void DeclareGlobalNewDelete();
+  void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
+                                       QualType Param1,
+                                       QualType Param2 = QualType(),
+                                       bool addMallocAttr = false);
+
+  bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
+                                DeclarationName Name, FunctionDecl* &Operator,
+                                bool Diagnose = true);
+  FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
+                                              bool CanProvideSize,
+                                              DeclarationName Name);
+
+  /// ActOnCXXDelete - Parsed a C++ 'delete' expression
+  ExprResult ActOnCXXDelete(SourceLocation StartLoc,
+                            bool UseGlobal, bool ArrayForm,
+                            Expr *Operand);
+
+  DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
+  ExprResult CheckConditionVariable(VarDecl *ConditionVar,
+                                    SourceLocation StmtLoc,
+                                    bool ConvertToBoolean);
+
+  ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,
+                               Expr *Operand, SourceLocation RParen);
+  ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
+                                  SourceLocation RParen);
+
+  /// \brief Parsed one of the type trait support pseudo-functions.
+  ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
+                            ArrayRef<ParsedType> Args,
+                            SourceLocation RParenLoc);
+  ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
+                            ArrayRef<TypeSourceInfo *> Args,
+                            SourceLocation RParenLoc);
+
+  /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
+  /// pseudo-functions.
+  ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,
+                                 SourceLocation KWLoc,
+                                 ParsedType LhsTy,
+                                 Expr *DimExpr,
+                                 SourceLocation RParen);
+
+  ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT,
+                                 SourceLocation KWLoc,
+                                 TypeSourceInfo *TSInfo,
+                                 Expr *DimExpr,
+                                 SourceLocation RParen);
+
+  /// ActOnExpressionTrait - Parsed one of the unary type trait support
+  /// pseudo-functions.
+  ExprResult ActOnExpressionTrait(ExpressionTrait OET,
+                                  SourceLocation KWLoc,
+                                  Expr *Queried,
+                                  SourceLocation RParen);
+
+  ExprResult BuildExpressionTrait(ExpressionTrait OET,
+                                  SourceLocation KWLoc,
+                                  Expr *Queried,
+                                  SourceLocation RParen);
+
+  ExprResult ActOnStartCXXMemberReference(Scope *S,
+                                          Expr *Base,
+                                          SourceLocation OpLoc,
+                                          tok::TokenKind OpKind,
+                                          ParsedType &ObjectType,
+                                          bool &MayBePseudoDestructor);
+
+  ExprResult DiagnoseDtorReference(SourceLocation NameLoc, Expr *MemExpr);
+
+  ExprResult BuildPseudoDestructorExpr(Expr *Base,
+                                       SourceLocation OpLoc,
+                                       tok::TokenKind OpKind,
+                                       const CXXScopeSpec &SS,
+                                       TypeSourceInfo *ScopeType,
+                                       SourceLocation CCLoc,
+                                       SourceLocation TildeLoc,
+                                     PseudoDestructorTypeStorage DestroyedType,
+                                       bool HasTrailingLParen);
+
+  ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
+                                       SourceLocation OpLoc,
+                                       tok::TokenKind OpKind,
+                                       CXXScopeSpec &SS,
+                                       UnqualifiedId &FirstTypeName,
+                                       SourceLocation CCLoc,
+                                       SourceLocation TildeLoc,
+                                       UnqualifiedId &SecondTypeName,
+                                       bool HasTrailingLParen);
+
+  ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
+                                       SourceLocation OpLoc,
+                                       tok::TokenKind OpKind,
+                                       SourceLocation TildeLoc,
+                                       const DeclSpec& DS,
+                                       bool HasTrailingLParen);
+
+  /// MaybeCreateExprWithCleanups - If the current full-expression
+  /// requires any cleanups, surround it with a ExprWithCleanups node.
+  /// Otherwise, just returns the passed-in expression.
+  Expr *MaybeCreateExprWithCleanups(Expr *SubExpr);
+  Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt);
+  ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr);
+
+  ExprResult ActOnFinishFullExpr(Expr *Expr) {
+    return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
+                                          : SourceLocation());
+  }
+  ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
+                                 bool DiscardedValue = false,
+                                 bool IsConstexpr = false,
+                                 bool IsLambdaInitCaptureInitializer = false);
+  StmtResult ActOnFinishFullStmt(Stmt *Stmt);
+
+  // Marks SS invalid if it represents an incomplete type.
+  bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
+
+  DeclContext *computeDeclContext(QualType T);
+  DeclContext *computeDeclContext(const CXXScopeSpec &SS,
+                                  bool EnteringContext = false);
+  bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
+  CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
+
+  /// \brief The parser has parsed a global nested-name-specifier '::'.
+  ///
+  /// \param S The scope in which this nested-name-specifier occurs.
+  ///
+  /// \param CCLoc The location of the '::'.
+  ///
+  /// \param SS The nested-name-specifier, which will be updated in-place
+  /// to reflect the parsed nested-name-specifier.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
+                                    CXXScopeSpec &SS);
+
+  bool isAcceptableNestedNameSpecifier(const NamedDecl *SD);
+  NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
+
+  bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
+                                    SourceLocation IdLoc,
+                                    IdentifierInfo &II,
+                                    ParsedType ObjectType);
+
+  bool BuildCXXNestedNameSpecifier(Scope *S,
+                                   IdentifierInfo &Identifier,
+                                   SourceLocation IdentifierLoc,
+                                   SourceLocation CCLoc,
+                                   QualType ObjectType,
+                                   bool EnteringContext,
+                                   CXXScopeSpec &SS,
+                                   NamedDecl *ScopeLookupResult,
+                                   bool ErrorRecoveryLookup,
+                                   bool *IsCorrectedToColon = nullptr);
+
+  /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
+  ///
+  /// \param S The scope in which this nested-name-specifier occurs.
+  ///
+  /// \param Identifier The identifier preceding the '::'.
+  ///
+  /// \param IdentifierLoc The location of the identifier.
+  ///
+  /// \param CCLoc The location of the '::'.
+  ///
+  /// \param ObjectType The type of the object, if we're parsing
+  /// nested-name-specifier in a member access expression.
+  ///
+  /// \param EnteringContext Whether we're entering the context nominated by
+  /// this nested-name-specifier.
+  ///
+  /// \param SS The nested-name-specifier, which is both an input
+  /// parameter (the nested-name-specifier before this type) and an
+  /// output parameter (containing the full nested-name-specifier,
+  /// including this new type).
+  ///
+  /// \param ErrorRecoveryLookup If true, then this method is called to improve
+  /// error recovery. In this case do not emit error message.
+  ///
+  /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':'
+  /// are allowed.  The bool value pointed by this parameter is set to 'true'
+  /// if the identifier is treated as if it was followed by ':', not '::'.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool ActOnCXXNestedNameSpecifier(Scope *S,
+                                   IdentifierInfo &Identifier,
+                                   SourceLocation IdentifierLoc,
+                                   SourceLocation CCLoc,
+                                   ParsedType ObjectType,
+                                   bool EnteringContext,
+                                   CXXScopeSpec &SS,
+                                   bool ErrorRecoveryLookup = false,
+                                   bool *IsCorrectedToColon = nullptr);
+
+  ExprResult ActOnDecltypeExpression(Expr *E);
+
+  bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
+                                           const DeclSpec &DS,
+                                           SourceLocation ColonColonLoc);
+
+  bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
+                                 IdentifierInfo &Identifier,
+                                 SourceLocation IdentifierLoc,
+                                 SourceLocation ColonLoc,
+                                 ParsedType ObjectType,
+                                 bool EnteringContext);
+
+  /// \brief The parser has parsed a nested-name-specifier
+  /// 'template[opt] template-name < template-args >::'.
+  ///
+  /// \param S The scope in which this nested-name-specifier occurs.
+  ///
+  /// \param SS The nested-name-specifier, which is both an input
+  /// parameter (the nested-name-specifier before this type) and an
+  /// output parameter (containing the full nested-name-specifier,
+  /// including this new type).
+  ///
+  /// \param TemplateKWLoc the location of the 'template' keyword, if any.
+  /// \param TemplateName the template name.
+  /// \param TemplateNameLoc The location of the template name.
+  /// \param LAngleLoc The location of the opening angle bracket  ('<').
+  /// \param TemplateArgs The template arguments.
+  /// \param RAngleLoc The location of the closing angle bracket  ('>').
+  /// \param CCLoc The location of the '::'.
+  ///
+  /// \param EnteringContext Whether we're entering the context of the
+  /// nested-name-specifier.
+  ///
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool ActOnCXXNestedNameSpecifier(Scope *S,
+                                   CXXScopeSpec &SS,
+                                   SourceLocation TemplateKWLoc,
+                                   TemplateTy TemplateName,
+                                   SourceLocation TemplateNameLoc,
+                                   SourceLocation LAngleLoc,
+                                   ASTTemplateArgsPtr TemplateArgs,
+                                   SourceLocation RAngleLoc,
+                                   SourceLocation CCLoc,
+                                   bool EnteringContext);
+
+  /// \brief Given a C++ nested-name-specifier, produce an annotation value
+  /// that the parser can use later to reconstruct the given
+  /// nested-name-specifier.
+  ///
+  /// \param SS A nested-name-specifier.
+  ///
+  /// \returns A pointer containing all of the information in the
+  /// nested-name-specifier \p SS.
+  void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS);
+
+  /// \brief Given an annotation pointer for a nested-name-specifier, restore
+  /// the nested-name-specifier structure.
+  ///
+  /// \param Annotation The annotation pointer, produced by
+  /// \c SaveNestedNameSpecifierAnnotation().
+  ///
+  /// \param AnnotationRange The source range corresponding to the annotation.
+  ///
+  /// \param SS The nested-name-specifier that will be updated with the contents
+  /// of the annotation pointer.
+  void RestoreNestedNameSpecifierAnnotation(void *Annotation,
+                                            SourceRange AnnotationRange,
+                                            CXXScopeSpec &SS);
+
+  bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+
+  /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
+  /// scope or nested-name-specifier) is parsed, part of a declarator-id.
+  /// After this method is called, according to [C++ 3.4.3p3], names should be
+  /// looked up in the declarator-id's scope, until the declarator is parsed and
+  /// ActOnCXXExitDeclaratorScope is called.
+  /// The 'SS' should be a non-empty valid CXXScopeSpec.
+  bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS);
+
+  /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
+  /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
+  /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
+  /// Used to indicate that names should revert to being looked up in the
+  /// defining scope.
+  void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
+
+  /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
+  /// initializer for the declaration 'Dcl'.
+  /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
+  /// static data member of class X, names should be looked up in the scope of
+  /// class X.
+  void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl);
+
+  /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
+  /// initializer for the declaration 'Dcl'.
+  void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl);
+
+  /// \brief Create a new lambda closure type.
+  CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
+                                         TypeSourceInfo *Info,
+                                         bool KnownDependent, 
+                                         LambdaCaptureDefault CaptureDefault);
+
+  /// \brief Start the definition of a lambda expression.
+  CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
+                                       SourceRange IntroducerRange,
+                                       TypeSourceInfo *MethodType,
+                                       SourceLocation EndLoc,
+                                       ArrayRef<ParmVarDecl *> Params);
+
+  /// \brief Endow the lambda scope info with the relevant properties.
+  void buildLambdaScope(sema::LambdaScopeInfo *LSI, 
+                        CXXMethodDecl *CallOperator,
+                        SourceRange IntroducerRange,
+                        LambdaCaptureDefault CaptureDefault,
+                        SourceLocation CaptureDefaultLoc,
+                        bool ExplicitParams,
+                        bool ExplicitResultType,
+                        bool Mutable);
+
+  /// \brief Perform initialization analysis of the init-capture and perform
+  /// any implicit conversions such as an lvalue-to-rvalue conversion if
+  /// not being used to initialize a reference.
+  QualType performLambdaInitCaptureInitialization(SourceLocation Loc, 
+      bool ByRef, IdentifierInfo *Id, Expr *&Init);
+  /// \brief Create a dummy variable within the declcontext of the lambda's
+  ///  call operator, for name lookup purposes for a lambda init capture.
+  ///  
+  ///  CodeGen handles emission of lambda captures, ignoring these dummy
+  ///  variables appropriately.
+  VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, 
+    QualType InitCaptureType, IdentifierInfo *Id, Expr *Init);
+
+  /// \brief Build the implicit field for an init-capture.
+  FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var);
+
+  /// \brief Note that we have finished the explicit captures for the
+  /// given lambda.
+  void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
+
+  /// \brief Introduce the lambda parameters into scope.
+  void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
+
+  /// \brief Deduce a block or lambda's return type based on the return
+  /// statements present in the body.
+  void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
+
+  /// ActOnStartOfLambdaDefinition - This is called just before we start
+  /// parsing the body of a lambda; it analyzes the explicit captures and
+  /// arguments, and sets up various data-structures for the body of the
+  /// lambda.
+  void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
+                                    Declarator &ParamInfo, Scope *CurScope);
+
+  /// ActOnLambdaError - If there is an error parsing a lambda, this callback
+  /// is invoked to pop the information about the lambda.
+  void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
+                        bool IsInstantiation = false);
+
+  /// ActOnLambdaExpr - This is called when the body of a lambda expression
+  /// was successfully completed.
+  ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
+                             Scope *CurScope,
+                             bool IsInstantiation = false);
+
+  /// \brief Define the "body" of the conversion from a lambda object to a
+  /// function pointer.
+  ///
+  /// This routine doesn't actually define a sensible body; rather, it fills
+  /// in the initialization expression needed to copy the lambda object into
+  /// the block, and IR generation actually generates the real body of the
+  /// block pointer conversion.
+  void DefineImplicitLambdaToFunctionPointerConversion(
+         SourceLocation CurrentLoc, CXXConversionDecl *Conv);
+
+  /// \brief Define the "body" of the conversion from a lambda object to a
+  /// block pointer.
+  ///
+  /// This routine doesn't actually define a sensible body; rather, it fills
+  /// in the initialization expression needed to copy the lambda object into
+  /// the block, and IR generation actually generates the real body of the
+  /// block pointer conversion.
+  void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc,
+                                                    CXXConversionDecl *Conv);
+
+  ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
+                                           SourceLocation ConvLocation,
+                                           CXXConversionDecl *Conv,
+                                           Expr *Src);
+
+  // ParseObjCStringLiteral - Parse Objective-C string literals.
+  ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                    Expr **Strings,
+                                    unsigned NumStrings);
+
+  ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
+
+  /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
+  /// numeric literal expression. Type of the expression will be "NSNumber *"
+  /// or "id" if NSNumber is unavailable.
+  ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number);
+  ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc,
+                                  bool Value);
+  ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
+
+  /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the
+  /// '@' prefixed parenthesized expression. The type of the expression will
+  /// either be "NSNumber *" or "NSString *" depending on the type of
+  /// ValueType, which is allowed to be a built-in numeric type or
+  /// "char *" or "const char *".
+  ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr);
+
+  ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
+                                          Expr *IndexExpr,
+                                          ObjCMethodDecl *getterMethod,
+                                          ObjCMethodDecl *setterMethod);
+
+  ExprResult BuildObjCDictionaryLiteral(SourceRange SR,
+                                        ObjCDictionaryElement *Elements,
+                                        unsigned NumElements);
+
+  ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
+                                  TypeSourceInfo *EncodedTypeInfo,
+                                  SourceLocation RParenLoc);
+  ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
+                                    CXXConversionDecl *Method,
+                                    bool HadMultipleCandidates);
+
+  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                       SourceLocation EncodeLoc,
+                                       SourceLocation LParenLoc,
+                                       ParsedType Ty,
+                                       SourceLocation RParenLoc);
+
+  /// ParseObjCSelectorExpression - Build selector expression for \@selector
+  ExprResult ParseObjCSelectorExpression(Selector Sel,
+                                         SourceLocation AtLoc,
+                                         SourceLocation SelLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation RParenLoc,
+                                         bool WarnMultipleSelectors);
+
+  /// ParseObjCProtocolExpression - Build protocol expression for \@protocol
+  ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
+                                         SourceLocation AtLoc,
+                                         SourceLocation ProtoLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation ProtoIdLoc,
+                                         SourceLocation RParenLoc);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Declarations
+  //
+  Decl *ActOnStartLinkageSpecification(Scope *S,
+                                       SourceLocation ExternLoc,
+                                       Expr *LangStr,
+                                       SourceLocation LBraceLoc);
+  Decl *ActOnFinishLinkageSpecification(Scope *S,
+                                        Decl *LinkageSpec,
+                                        SourceLocation RBraceLoc);
+
+
+  //===--------------------------------------------------------------------===//
+  // C++ Classes
+  //
+  bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
+                          const CXXScopeSpec *SS = nullptr);
+  bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
+
+  bool ActOnAccessSpecifier(AccessSpecifier Access,
+                            SourceLocation ASLoc,
+                            SourceLocation ColonLoc,
+                            AttributeList *Attrs = nullptr);
+
+  NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
+                                 Declarator &D,
+                                 MultiTemplateParamsArg TemplateParameterLists,
+                                 Expr *BitfieldWidth, const VirtSpecifiers &VS,
+                                 InClassInitStyle InitStyle);
+
+  void ActOnStartCXXInClassMemberInitializer();
+  void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl,
+                                              SourceLocation EqualLoc,
+                                              Expr *Init);
+
+  MemInitResult ActOnMemInitializer(Decl *ConstructorD,
+                                    Scope *S,
+                                    CXXScopeSpec &SS,
+                                    IdentifierInfo *MemberOrBase,
+                                    ParsedType TemplateTypeTy,
+                                    const DeclSpec &DS,
+                                    SourceLocation IdLoc,
+                                    SourceLocation LParenLoc,
+                                    ArrayRef<Expr *> Args,
+                                    SourceLocation RParenLoc,
+                                    SourceLocation EllipsisLoc);
+
+  MemInitResult ActOnMemInitializer(Decl *ConstructorD,
+                                    Scope *S,
+                                    CXXScopeSpec &SS,
+                                    IdentifierInfo *MemberOrBase,
+                                    ParsedType TemplateTypeTy,
+                                    const DeclSpec &DS,
+                                    SourceLocation IdLoc,
+                                    Expr *InitList,
+                                    SourceLocation EllipsisLoc);
+
+  MemInitResult BuildMemInitializer(Decl *ConstructorD,
+                                    Scope *S,
+                                    CXXScopeSpec &SS,
+                                    IdentifierInfo *MemberOrBase,
+                                    ParsedType TemplateTypeTy,
+                                    const DeclSpec &DS,
+                                    SourceLocation IdLoc,
+                                    Expr *Init,
+                                    SourceLocation EllipsisLoc);
+
+  MemInitResult BuildMemberInitializer(ValueDecl *Member,
+                                       Expr *Init,
+                                       SourceLocation IdLoc);
+
+  MemInitResult BuildBaseInitializer(QualType BaseType,
+                                     TypeSourceInfo *BaseTInfo,
+                                     Expr *Init,
+                                     CXXRecordDecl *ClassDecl,
+                                     SourceLocation EllipsisLoc);
+
+  MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo,
+                                           Expr *Init,
+                                           CXXRecordDecl *ClassDecl);
+
+  bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
+                                CXXCtorInitializer *Initializer);
+
+  bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
+                           ArrayRef<CXXCtorInitializer *> Initializers = None);
+
+  void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
+
+
+  /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
+  /// mark all the non-trivial destructors of its members and bases as
+  /// referenced.
+  void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
+                                              CXXRecordDecl *Record);
+
+  /// \brief The list of classes whose vtables have been used within
+  /// this translation unit, and the source locations at which the
+  /// first use occurred.
+  typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse;
+
+  /// \brief The list of vtables that are required but have not yet been
+  /// materialized.
+  SmallVector<VTableUse, 16> VTableUses;
+
+  /// \brief The set of classes whose vtables have been used within
+  /// this translation unit, and a bit that will be true if the vtable is
+  /// required to be emitted (otherwise, it should be emitted only if needed
+  /// by code generation).
+  llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed;
+
+  /// \brief Load any externally-stored vtable uses.
+  void LoadExternalVTableUses();
+
+  typedef LazyVector<CXXRecordDecl *, ExternalSemaSource,
+                     &ExternalSemaSource::ReadDynamicClasses, 2, 2>
+    DynamicClassesType;
+
+  /// \brief A list of all of the dynamic classes in this translation
+  /// unit.
+  DynamicClassesType DynamicClasses;
+
+  /// \brief Note that the vtable for the given class was used at the
+  /// given location.
+  void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
+                      bool DefinitionRequired = false);
+
+  /// \brief Mark the exception specifications of all virtual member functions
+  /// in the given class as needed.
+  void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
+                                             const CXXRecordDecl *RD);
+
+  /// MarkVirtualMembersReferenced - Will mark all members of the given
+  /// CXXRecordDecl referenced.
+  void MarkVirtualMembersReferenced(SourceLocation Loc,
+                                    const CXXRecordDecl *RD);
+
+  /// \brief Define all of the vtables that have been used in this
+  /// translation unit and reference any virtual members used by those
+  /// vtables.
+  ///
+  /// \returns true if any work was done, false otherwise.
+  bool DefineUsedVTables();
+
+  void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
+
+  void ActOnMemInitializers(Decl *ConstructorDecl,
+                            SourceLocation ColonLoc,
+                            ArrayRef<CXXCtorInitializer*> MemInits,
+                            bool AnyErrors);
+
+  void CheckCompletedCXXClass(CXXRecordDecl *Record);
+  void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
+                                         Decl *TagDecl,
+                                         SourceLocation LBrac,
+                                         SourceLocation RBrac,
+                                         AttributeList *AttrList);
+  void ActOnFinishCXXMemberDecls();
+
+  void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
+  unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);
+  void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
+  void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
+  void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
+  void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record);
+  void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
+  void ActOnFinishDelayedMemberInitializers(Decl *Record);
+  void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD,
+                                CachedTokens &Toks);
+  void UnmarkAsLateParsedTemplate(FunctionDecl *FD);
+  bool IsInsideALocalClassWithinATemplateFunction();
+
+  Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
+                                     Expr *AssertExpr,
+                                     Expr *AssertMessageExpr,
+                                     SourceLocation RParenLoc);
+  Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
+                                     Expr *AssertExpr,
+                                     StringLiteral *AssertMessageExpr,
+                                     SourceLocation RParenLoc,
+                                     bool Failed);
+
+  FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart,
+                                  SourceLocation FriendLoc,
+                                  TypeSourceInfo *TSInfo);
+  Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+                            MultiTemplateParamsArg TemplateParams);
+  NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D,
+                                     MultiTemplateParamsArg TemplateParams);
+
+  QualType CheckConstructorDeclarator(Declarator &D, QualType R,
+                                      StorageClass& SC);
+  void CheckConstructor(CXXConstructorDecl *Constructor);
+  QualType CheckDestructorDeclarator(Declarator &D, QualType R,
+                                     StorageClass& SC);
+  bool CheckDestructor(CXXDestructorDecl *Destructor);
+  void CheckConversionDeclarator(Declarator &D, QualType &R,
+                                 StorageClass& SC);
+  Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
+
+  void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
+  void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
+                                                   const FunctionProtoType *T);
+  void CheckDelayedMemberExceptionSpecs();
+
+  //===--------------------------------------------------------------------===//
+  // C++ Derived Classes
+  //
+
+  /// ActOnBaseSpecifier - Parsed a base specifier
+  CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
+                                       SourceRange SpecifierRange,
+                                       bool Virtual, AccessSpecifier Access,
+                                       TypeSourceInfo *TInfo,
+                                       SourceLocation EllipsisLoc);
+
+  BaseResult ActOnBaseSpecifier(Decl *classdecl,
+                                SourceRange SpecifierRange,
+                                ParsedAttributes &Attrs,
+                                bool Virtual, AccessSpecifier Access,
+                                ParsedType basetype,
+                                SourceLocation BaseLoc,
+                                SourceLocation EllipsisLoc);
+
+  bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
+                            unsigned NumBases);
+  void ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases,
+                           unsigned NumBases);
+
+  bool IsDerivedFrom(QualType Derived, QualType Base);
+  bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
+
+  // FIXME: I don't like this name.
+  void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath);
+
+  bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath);
+
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    SourceLocation Loc, SourceRange Range,
+                                    CXXCastPath *BasePath = nullptr,
+                                    bool IgnoreAccess = false);
+  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
+                                    unsigned InaccessibleBaseID,
+                                    unsigned AmbigiousBaseConvID,
+                                    SourceLocation Loc, SourceRange Range,
+                                    DeclarationName Name,
+                                    CXXCastPath *BasePath);
+
+  std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
+
+  bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
+                                         const CXXMethodDecl *Old);
+
+  /// CheckOverridingFunctionReturnType - Checks whether the return types are
+  /// covariant, according to C++ [class.virtual]p5.
+  bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
+                                         const CXXMethodDecl *Old);
+
+  /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
+  /// spec is a subset of base spec.
+  bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
+                                            const CXXMethodDecl *Old);
+
+  bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
+
+  /// CheckOverrideControl - Check C++11 override control semantics.
+  void CheckOverrideControl(NamedDecl *D);
+
+  /// CheckForFunctionMarkedFinal - Checks whether a virtual member function
+  /// overrides a virtual member function marked 'final', according to
+  /// C++11 [class.virtual]p4.
+  bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New,
+                                              const CXXMethodDecl *Old);
+
+
+  //===--------------------------------------------------------------------===//
+  // C++ Access Control
+  //
+
+  enum AccessResult {
+    AR_accessible,
+    AR_inaccessible,
+    AR_dependent,
+    AR_delayed
+  };
+
+  bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
+                                NamedDecl *PrevMemberDecl,
+                                AccessSpecifier LexicalAS);
+
+  AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
+                                           DeclAccessPair FoundDecl);
+  AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
+                                           DeclAccessPair FoundDecl);
+  AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
+                                     SourceRange PlacementRange,
+                                     CXXRecordDecl *NamingClass,
+                                     DeclAccessPair FoundDecl,
+                                     bool Diagnose = true);
+  AccessResult CheckConstructorAccess(SourceLocation Loc,
+                                      CXXConstructorDecl *D,
+                                      const InitializedEntity &Entity,
+                                      AccessSpecifier Access,
+                                      bool IsCopyBindingRefToTemp = false);
+  AccessResult CheckConstructorAccess(SourceLocation Loc,
+                                      CXXConstructorDecl *D,
+                                      const InitializedEntity &Entity,
+                                      AccessSpecifier Access,
+                                      const PartialDiagnostic &PDiag);
+  AccessResult CheckDestructorAccess(SourceLocation Loc,
+                                     CXXDestructorDecl *Dtor,
+                                     const PartialDiagnostic &PDiag,
+                                     QualType objectType = QualType());
+  AccessResult CheckFriendAccess(NamedDecl *D);
+  AccessResult CheckMemberAccess(SourceLocation UseLoc,
+                                 CXXRecordDecl *NamingClass,
+                                 DeclAccessPair Found);
+  AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
+                                         Expr *ObjectExpr,
+                                         Expr *ArgExpr,
+                                         DeclAccessPair FoundDecl);
+  AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
+                                          DeclAccessPair FoundDecl);
+  AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
+                                    QualType Base, QualType Derived,
+                                    const CXXBasePath &Path,
+                                    unsigned DiagID,
+                                    bool ForceCheck = false,
+                                    bool ForceUnprivileged = false);
+  void CheckLookupAccess(const LookupResult &R);
+  bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
+  bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
+                                            AccessSpecifier access,
+                                            QualType objectType);
+
+  void HandleDependentAccessCheck(const DependentDiagnostic &DD,
+                         const MultiLevelTemplateArgumentList &TemplateArgs);
+  void PerformDependentDiagnostics(const DeclContext *Pattern,
+                        const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+
+  /// \brief When true, access checking violations are treated as SFINAE
+  /// failures rather than hard errors.
+  bool AccessCheckingSFINAE;
+
+  enum AbstractDiagSelID {
+    AbstractNone = -1,
+    AbstractReturnType,
+    AbstractParamType,
+    AbstractVariableType,
+    AbstractFieldType,
+    AbstractIvarType,
+    AbstractSynthesizedIvarType,
+    AbstractArrayType
+  };
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              TypeDiagnoser &Diagnoser);
+  template<typename T1>
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              unsigned DiagID,
+                              const T1 &Arg1) {
+    BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
+    return RequireNonAbstractType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2>
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              unsigned DiagID,
+                              const T1 &Arg1, const T2 &Arg2) {
+    BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
+    return RequireNonAbstractType(Loc, T, Diagnoser);
+  }
+
+  template<typename T1, typename T2, typename T3>
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
+                              unsigned DiagID,
+                              const T1 &Arg1, const T2 &Arg2, const T3 &Arg3) {
+    BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, Arg3);
+    return RequireNonAbstractType(Loc, T, Diagnoser);
+  }
+
+  void DiagnoseAbstractType(const CXXRecordDecl *RD);
+
+  bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
+                              AbstractDiagSelID SelID = AbstractNone);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Overloaded Operators [C++ 13.5]
+  //
+
+  bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
+
+  bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Templates [C++ 14]
+  //
+  void FilterAcceptableTemplateNames(LookupResult &R,
+                                     bool AllowFunctionTemplates = true);
+  bool hasAnyAcceptableTemplateNames(LookupResult &R,
+                                     bool AllowFunctionTemplates = true);
+
+  void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
+                          QualType ObjectType, bool EnteringContext,
+                          bool &MemberOfUnknownSpecialization);
+
+  TemplateNameKind isTemplateName(Scope *S,
+                                  CXXScopeSpec &SS,
+                                  bool hasTemplateKeyword,
+                                  UnqualifiedId &Name,
+                                  ParsedType ObjectType,
+                                  bool EnteringContext,
+                                  TemplateTy &Template,
+                                  bool &MemberOfUnknownSpecialization);
+
+  bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
+                                   SourceLocation IILoc,
+                                   Scope *S,
+                                   const CXXScopeSpec *SS,
+                                   TemplateTy &SuggestedTemplate,
+                                   TemplateNameKind &SuggestedKind);
+
+  void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
+  TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
+
+  Decl *ActOnTypeParameter(Scope *S, bool Typename,
+                           SourceLocation EllipsisLoc,
+                           SourceLocation KeyLoc,
+                           IdentifierInfo *ParamName,
+                           SourceLocation ParamNameLoc,
+                           unsigned Depth, unsigned Position,
+                           SourceLocation EqualLoc,
+                           ParsedType DefaultArg);
+
+  QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
+  Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                      unsigned Depth,
+                                      unsigned Position,
+                                      SourceLocation EqualLoc,
+                                      Expr *DefaultArg);
+  Decl *ActOnTemplateTemplateParameter(Scope *S,
+                                       SourceLocation TmpLoc,
+                                       TemplateParameterList *Params,
+                                       SourceLocation EllipsisLoc,
+                                       IdentifierInfo *ParamName,
+                                       SourceLocation ParamNameLoc,
+                                       unsigned Depth,
+                                       unsigned Position,
+                                       SourceLocation EqualLoc,
+                                       ParsedTemplateArgument DefaultArg);
+
+  TemplateParameterList *
+  ActOnTemplateParameterList(unsigned Depth,
+                             SourceLocation ExportLoc,
+                             SourceLocation TemplateLoc,
+                             SourceLocation LAngleLoc,
+                             Decl **Params, unsigned NumParams,
+                             SourceLocation RAngleLoc);
+
+  /// \brief The context in which we are checking a template parameter list.
+  enum TemplateParamListContext {
+    TPC_ClassTemplate,
+    TPC_VarTemplate,
+    TPC_FunctionTemplate,
+    TPC_ClassTemplateMember,
+    TPC_FriendClassTemplate,
+    TPC_FriendFunctionTemplate,
+    TPC_FriendFunctionTemplateDefinition,
+    TPC_TypeAliasTemplate
+  };
+
+  bool CheckTemplateParameterList(TemplateParameterList *NewParams,
+                                  TemplateParameterList *OldParams,
+                                  TemplateParamListContext TPC);
+  TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
+      SourceLocation DeclStartLoc, SourceLocation DeclLoc,
+      const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
+      ArrayRef<TemplateParameterList *> ParamLists,
+      bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid);
+
+  DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                                SourceLocation KWLoc, CXXScopeSpec &SS,
+                                IdentifierInfo *Name, SourceLocation NameLoc,
+                                AttributeList *Attr,
+                                TemplateParameterList *TemplateParams,
+                                AccessSpecifier AS,
+                                SourceLocation ModulePrivateLoc,
+                                SourceLocation FriendLoc,
+                                unsigned NumOuterTemplateParamLists,
+                            TemplateParameterList **OuterTemplateParamLists);
+
+  void translateTemplateArguments(const ASTTemplateArgsPtr &In,
+                                  TemplateArgumentListInfo &Out);
+
+  void NoteAllFoundTemplates(TemplateName Name);
+
+  QualType CheckTemplateIdType(TemplateName Template,
+                               SourceLocation TemplateLoc,
+                              TemplateArgumentListInfo &TemplateArgs);
+
+  TypeResult
+  ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+                      TemplateTy Template, SourceLocation TemplateLoc,
+                      SourceLocation LAngleLoc,
+                      ASTTemplateArgsPtr TemplateArgs,
+                      SourceLocation RAngleLoc,
+                      bool IsCtorOrDtorName = false);
+
+  /// \brief Parsed an elaborated-type-specifier that refers to a template-id,
+  /// such as \c class T::template apply<U>.
+  TypeResult ActOnTagTemplateIdType(TagUseKind TUK,
+                                    TypeSpecifierType TagSpec,
+                                    SourceLocation TagLoc,
+                                    CXXScopeSpec &SS,
+                                    SourceLocation TemplateKWLoc,
+                                    TemplateTy TemplateD,
+                                    SourceLocation TemplateLoc,
+                                    SourceLocation LAngleLoc,
+                                    ASTTemplateArgsPtr TemplateArgsIn,
+                                    SourceLocation RAngleLoc);
+
+  DeclResult ActOnVarTemplateSpecialization(
+      Scope *S, Declarator &D, TypeSourceInfo *DI,
+      SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
+      StorageClass SC, bool IsPartialSpecialization);
+
+  DeclResult CheckVarTemplateId(VarTemplateDecl *Template,
+                                SourceLocation TemplateLoc,
+                                SourceLocation TemplateNameLoc,
+                                const TemplateArgumentListInfo &TemplateArgs);
+
+  ExprResult CheckVarTemplateId(const CXXScopeSpec &SS,
+                                const DeclarationNameInfo &NameInfo,
+                                VarTemplateDecl *Template,
+                                SourceLocation TemplateLoc,
+                                const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
+                                 SourceLocation TemplateKWLoc,
+                                 LookupResult &R,
+                                 bool RequiresADL,
+                               const TemplateArgumentListInfo *TemplateArgs);
+
+  ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
+                                          SourceLocation TemplateKWLoc,
+                               const DeclarationNameInfo &NameInfo,
+                               const TemplateArgumentListInfo *TemplateArgs);
+
+  TemplateNameKind ActOnDependentTemplateName(Scope *S,
+                                              CXXScopeSpec &SS,
+                                              SourceLocation TemplateKWLoc,
+                                              UnqualifiedId &Name,
+                                              ParsedType ObjectType,
+                                              bool EnteringContext,
+                                              TemplateTy &Template);
+
+  DeclResult
+  ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
+                                   SourceLocation KWLoc,
+                                   SourceLocation ModulePrivateLoc,
+                                   TemplateIdAnnotation &TemplateId,
+                                   AttributeList *Attr,
+                                 MultiTemplateParamsArg TemplateParameterLists);
+
+  Decl *ActOnTemplateDeclarator(Scope *S,
+                                MultiTemplateParamsArg TemplateParameterLists,
+                                Declarator &D);
+
+  Decl *ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+                                  MultiTemplateParamsArg TemplateParameterLists,
+                                        Declarator &D);
+
+  bool
+  CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
+                                         TemplateSpecializationKind NewTSK,
+                                         NamedDecl *PrevDecl,
+                                         TemplateSpecializationKind PrevTSK,
+                                         SourceLocation PrevPtOfInstantiation,
+                                         bool &SuppressNew);
+
+  bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
+                    const TemplateArgumentListInfo &ExplicitTemplateArgs,
+                                                    LookupResult &Previous);
+
+  bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
+                         TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                           LookupResult &Previous);
+  bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
+
+  DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             const CXXScopeSpec &SS,
+                             TemplateTy Template,
+                             SourceLocation TemplateNameLoc,
+                             SourceLocation LAngleLoc,
+                             ASTTemplateArgsPtr TemplateArgs,
+                             SourceLocation RAngleLoc,
+                             AttributeList *Attr);
+
+  DeclResult
+  ActOnExplicitInstantiation(Scope *S,
+                             SourceLocation ExternLoc,
+                             SourceLocation TemplateLoc,
+                             unsigned TagSpec,
+                             SourceLocation KWLoc,
+                             CXXScopeSpec &SS,
+                             IdentifierInfo *Name,
+                             SourceLocation NameLoc,
+                             AttributeList *Attr);
+
+  DeclResult ActOnExplicitInstantiation(Scope *S,
+                                        SourceLocation ExternLoc,
+                                        SourceLocation TemplateLoc,
+                                        Declarator &D);
+
+  TemplateArgumentLoc
+  SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
+                                          SourceLocation TemplateLoc,
+                                          SourceLocation RAngleLoc,
+                                          Decl *Param,
+                                          SmallVectorImpl<TemplateArgument>
+                                            &Converted,
+                                          bool &HasDefaultArg);
+
+  /// \brief Specifies the context in which a particular template
+  /// argument is being checked.
+  enum CheckTemplateArgumentKind {
+    /// \brief The template argument was specified in the code or was
+    /// instantiated with some deduced template arguments.
+    CTAK_Specified,
+
+    /// \brief The template argument was deduced via template argument
+    /// deduction.
+    CTAK_Deduced,
+
+    /// \brief The template argument was deduced from an array bound
+    /// via template argument deduction.
+    CTAK_DeducedFromArrayBound
+  };
+
+  bool CheckTemplateArgument(NamedDecl *Param,
+                             TemplateArgumentLoc &Arg,
+                             NamedDecl *Template,
+                             SourceLocation TemplateLoc,
+                             SourceLocation RAngleLoc,
+                             unsigned ArgumentPackIndex,
+                           SmallVectorImpl<TemplateArgument> &Converted,
+                             CheckTemplateArgumentKind CTAK = CTAK_Specified);
+
+  /// \brief Check that the given template arguments can be be provided to
+  /// the given template, converting the arguments along the way.
+  ///
+  /// \param Template The template to which the template arguments are being
+  /// provided.
+  ///
+  /// \param TemplateLoc The location of the template name in the source.
+  ///
+  /// \param TemplateArgs The list of template arguments. If the template is
+  /// a template template parameter, this function may extend the set of
+  /// template arguments to also include substituted, defaulted template
+  /// arguments.
+  ///
+  /// \param PartialTemplateArgs True if the list of template arguments is
+  /// intentionally partial, e.g., because we're checking just the initial
+  /// set of template arguments.
+  ///
+  /// \param Converted Will receive the converted, canonicalized template
+  /// arguments.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool CheckTemplateArgumentList(TemplateDecl *Template,
+                                 SourceLocation TemplateLoc,
+                                 TemplateArgumentListInfo &TemplateArgs,
+                                 bool PartialTemplateArgs,
+                           SmallVectorImpl<TemplateArgument> &Converted);
+
+  bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+                                 TemplateArgumentLoc &Arg,
+                           SmallVectorImpl<TemplateArgument> &Converted);
+
+  bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
+                             TypeSourceInfo *Arg);
+  ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+                                   QualType InstantiatedParamType, Expr *Arg,
+                                   TemplateArgument &Converted,
+                               CheckTemplateArgumentKind CTAK = CTAK_Specified);
+  bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
+                             TemplateArgumentLoc &Arg,
+                             unsigned ArgumentPackIndex);
+
+  ExprResult
+  BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
+                                          QualType ParamType,
+                                          SourceLocation Loc);
+  ExprResult
+  BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
+                                              SourceLocation Loc);
+
+  /// \brief Enumeration describing how template parameter lists are compared
+  /// for equality.
+  enum TemplateParameterListEqualKind {
+    /// \brief We are matching the template parameter lists of two templates
+    /// that might be redeclarations.
+    ///
+    /// \code
+    /// template<typename T> struct X;
+    /// template<typename T> struct X;
+    /// \endcode
+    TPL_TemplateMatch,
+
+    /// \brief We are matching the template parameter lists of two template
+    /// template parameters as part of matching the template parameter lists
+    /// of two templates that might be redeclarations.
+    ///
+    /// \code
+    /// template<template<int I> class TT> struct X;
+    /// template<template<int Value> class Other> struct X;
+    /// \endcode
+    TPL_TemplateTemplateParmMatch,
+
+    /// \brief We are matching the template parameter lists of a template
+    /// template argument against the template parameter lists of a template
+    /// template parameter.
+    ///
+    /// \code
+    /// template<template<int Value> class Metafun> struct X;
+    /// template<int Value> struct integer_c;
+    /// X<integer_c> xic;
+    /// \endcode
+    TPL_TemplateTemplateArgumentMatch
+  };
+
+  bool TemplateParameterListsAreEqual(TemplateParameterList *New,
+                                      TemplateParameterList *Old,
+                                      bool Complain,
+                                      TemplateParameterListEqualKind Kind,
+                                      SourceLocation TemplateArgLoc
+                                        = SourceLocation());
+
+  bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
+
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier, e.g., "typename T::type".
+  ///
+  /// \param S The scope in which this typename type occurs.
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param II the identifier we're retrieving (e.g., 'type' in the example).
+  /// \param IdLoc the location of the identifier.
+  TypeResult
+  ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+                    const CXXScopeSpec &SS, const IdentifierInfo &II,
+                    SourceLocation IdLoc);
+
+  /// \brief Called when the parser has parsed a C++ typename
+  /// specifier that ends in a template-id, e.g.,
+  /// "typename MetaFun::template apply<T1, T2>".
+  ///
+  /// \param S The scope in which this typename type occurs.
+  /// \param TypenameLoc the location of the 'typename' keyword
+  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
+  /// \param TemplateLoc the location of the 'template' keyword, if any.
+  /// \param TemplateName The template name.
+  /// \param TemplateNameLoc The location of the template name.
+  /// \param LAngleLoc The location of the opening angle bracket  ('<').
+  /// \param TemplateArgs The template arguments.
+  /// \param RAngleLoc The location of the closing angle bracket  ('>').
+  TypeResult
+  ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
+                    const CXXScopeSpec &SS,
+                    SourceLocation TemplateLoc,
+                    TemplateTy TemplateName,
+                    SourceLocation TemplateNameLoc,
+                    SourceLocation LAngleLoc,
+                    ASTTemplateArgsPtr TemplateArgs,
+                    SourceLocation RAngleLoc);
+
+  QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
+                             SourceLocation KeywordLoc,
+                             NestedNameSpecifierLoc QualifierLoc,
+                             const IdentifierInfo &II,
+                             SourceLocation IILoc);
+
+  TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
+                                                    SourceLocation Loc,
+                                                    DeclarationName Name);
+  bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
+
+  ExprResult RebuildExprInCurrentInstantiation(Expr *E);
+  bool RebuildTemplateParamsInCurrentInstantiation(
+                                                TemplateParameterList *Params);
+
+  std::string
+  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                  const TemplateArgumentList &Args);
+
+  std::string
+  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
+                                  const TemplateArgument *Args,
+                                  unsigned NumArgs);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Variadic Templates (C++0x [temp.variadic])
+  //===--------------------------------------------------------------------===//
+
+  /// \brief The context in which an unexpanded parameter pack is
+  /// being diagnosed.
+  ///
+  /// Note that the values of this enumeration line up with the first
+  /// argument to the \c err_unexpanded_parameter_pack diagnostic.
+  enum UnexpandedParameterPackContext {
+    /// \brief An arbitrary expression.
+    UPPC_Expression = 0,
+
+    /// \brief The base type of a class type.
+    UPPC_BaseType,
+
+    /// \brief The type of an arbitrary declaration.
+    UPPC_DeclarationType,
+
+    /// \brief The type of a data member.
+    UPPC_DataMemberType,
+
+    /// \brief The size of a bit-field.
+    UPPC_BitFieldWidth,
+
+    /// \brief The expression in a static assertion.
+    UPPC_StaticAssertExpression,
+
+    /// \brief The fixed underlying type of an enumeration.
+    UPPC_FixedUnderlyingType,
+
+    /// \brief The enumerator value.
+    UPPC_EnumeratorValue,
+
+    /// \brief A using declaration.
+    UPPC_UsingDeclaration,
+
+    /// \brief A friend declaration.
+    UPPC_FriendDeclaration,
+
+    /// \brief A declaration qualifier.
+    UPPC_DeclarationQualifier,
+
+    /// \brief An initializer.
+    UPPC_Initializer,
+
+    /// \brief A default argument.
+    UPPC_DefaultArgument,
+
+    /// \brief The type of a non-type template parameter.
+    UPPC_NonTypeTemplateParameterType,
+
+    /// \brief The type of an exception.
+    UPPC_ExceptionType,
+
+    /// \brief Partial specialization.
+    UPPC_PartialSpecialization,
+
+    /// \brief Microsoft __if_exists.
+    UPPC_IfExists,
+
+    /// \brief Microsoft __if_not_exists.
+    UPPC_IfNotExists,
+
+    /// \brief Lambda expression.
+    UPPC_Lambda,
+
+    /// \brief Block expression,
+    UPPC_Block
+  };
+
+  /// \brief Diagnose unexpanded parameter packs.
+  ///
+  /// \param Loc The location at which we should emit the diagnostic.
+  ///
+  /// \param UPPC The context in which we are diagnosing unexpanded
+  /// parameter packs.
+  ///
+  /// \param Unexpanded the set of unexpanded parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
+                                        UnexpandedParameterPackContext UPPC,
+                                  ArrayRef<UnexpandedParameterPack> Unexpanded);
+
+  /// \brief If the given type contains an unexpanded parameter pack,
+  /// diagnose the error.
+  ///
+  /// \param Loc The source location where a diagnostc should be emitted.
+  ///
+  /// \param T The type that is being checked for unexpanded parameter
+  /// packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T,
+                                       UnexpandedParameterPackContext UPPC);
+
+  /// \brief If the given expression contains an unexpanded parameter
+  /// pack, diagnose the error.
+  ///
+  /// \param E The expression that is being checked for unexpanded
+  /// parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(Expr *E,
+                       UnexpandedParameterPackContext UPPC = UPPC_Expression);
+
+  /// \brief If the given nested-name-specifier contains an unexpanded
+  /// parameter pack, diagnose the error.
+  ///
+  /// \param SS The nested-name-specifier that is being checked for
+  /// unexpanded parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
+                                       UnexpandedParameterPackContext UPPC);
+
+  /// \brief If the given name contains an unexpanded parameter pack,
+  /// diagnose the error.
+  ///
+  /// \param NameInfo The name (with source location information) that
+  /// is being checked for unexpanded parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
+                                       UnexpandedParameterPackContext UPPC);
+
+  /// \brief If the given template name contains an unexpanded parameter pack,
+  /// diagnose the error.
+  ///
+  /// \param Loc The location of the template name.
+  ///
+  /// \param Template The template name that is being checked for unexpanded
+  /// parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(SourceLocation Loc,
+                                       TemplateName Template,
+                                       UnexpandedParameterPackContext UPPC);
+
+  /// \brief If the given template argument contains an unexpanded parameter
+  /// pack, diagnose the error.
+  ///
+  /// \param Arg The template argument that is being checked for unexpanded
+  /// parameter packs.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
+                                       UnexpandedParameterPackContext UPPC);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// template argument.
+  ///
+  /// \param Arg The template argument that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(TemplateArgument Arg,
+                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// template argument.
+  ///
+  /// \param Arg The template argument that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
+                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// type.
+  ///
+  /// \param T The type that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(QualType T,
+                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// type.
+  ///
+  /// \param TL The type that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(TypeLoc TL,
+                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// nested-name-specifier.
+  ///
+  /// \param SS The nested-name-specifier that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(CXXScopeSpec &SS,
+                         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Collect the set of unexpanded parameter packs within the given
+  /// name.
+  ///
+  /// \param NameInfo The name that will be traversed to find
+  /// unexpanded parameter packs.
+  void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
+                         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded);
+
+  /// \brief Invoked when parsing a template argument followed by an
+  /// ellipsis, which creates a pack expansion.
+  ///
+  /// \param Arg The template argument preceding the ellipsis, which
+  /// may already be invalid.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis.
+  ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg,
+                                            SourceLocation EllipsisLoc);
+
+  /// \brief Invoked when parsing a type followed by an ellipsis, which
+  /// creates a pack expansion.
+  ///
+  /// \param Type The type preceding the ellipsis, which will become
+  /// the pattern of the pack expansion.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis.
+  TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc);
+
+  /// \brief Construct a pack expansion type from the pattern of the pack
+  /// expansion.
+  TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
+                                     SourceLocation EllipsisLoc,
+                                     Optional<unsigned> NumExpansions);
+
+  /// \brief Construct a pack expansion type from the pattern of the pack
+  /// expansion.
+  QualType CheckPackExpansion(QualType Pattern,
+                              SourceRange PatternRange,
+                              SourceLocation EllipsisLoc,
+                              Optional<unsigned> NumExpansions);
+
+  /// \brief Invoked when parsing an expression followed by an ellipsis, which
+  /// creates a pack expansion.
+  ///
+  /// \param Pattern The expression preceding the ellipsis, which will become
+  /// the pattern of the pack expansion.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis.
+  ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc);
+
+  /// \brief Invoked when parsing an expression followed by an ellipsis, which
+  /// creates a pack expansion.
+  ///
+  /// \param Pattern The expression preceding the ellipsis, which will become
+  /// the pattern of the pack expansion.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis.
+  ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
+                                Optional<unsigned> NumExpansions);
+
+  /// \brief Determine whether we could expand a pack expansion with the
+  /// given set of parameter packs into separate arguments by repeatedly
+  /// transforming the pattern.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis that identifies the
+  /// pack expansion.
+  ///
+  /// \param PatternRange The source range that covers the entire pattern of
+  /// the pack expansion.
+  ///
+  /// \param Unexpanded The set of unexpanded parameter packs within the
+  /// pattern.
+  ///
+  /// \param ShouldExpand Will be set to \c true if the transformer should
+  /// expand the corresponding pack expansions into separate arguments. When
+  /// set, \c NumExpansions must also be set.
+  ///
+  /// \param RetainExpansion Whether the caller should add an unexpanded
+  /// pack expansion after all of the expanded arguments. This is used
+  /// when extending explicitly-specified template argument packs per
+  /// C++0x [temp.arg.explicit]p9.
+  ///
+  /// \param NumExpansions The number of separate arguments that will be in
+  /// the expanded form of the corresponding pack expansion. This is both an
+  /// input and an output parameter, which can be set by the caller if the
+  /// number of expansions is known a priori (e.g., due to a prior substitution)
+  /// and will be set by the callee when the number of expansions is known.
+  /// The callee must set this value when \c ShouldExpand is \c true; it may
+  /// set this value in other cases.
+  ///
+  /// \returns true if an error occurred (e.g., because the parameter packs
+  /// are to be instantiated with arguments of different lengths), false
+  /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
+  /// must be set.
+  bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
+                                       SourceRange PatternRange,
+                             ArrayRef<UnexpandedParameterPack> Unexpanded,
+                             const MultiLevelTemplateArgumentList &TemplateArgs,
+                                       bool &ShouldExpand,
+                                       bool &RetainExpansion,
+                                       Optional<unsigned> &NumExpansions);
+
+  /// \brief Determine the number of arguments in the given pack expansion
+  /// type.
+  ///
+  /// This routine assumes that the number of arguments in the expansion is
+  /// consistent across all of the unexpanded parameter packs in its pattern.
+  ///
+  /// Returns an empty Optional if the type can't be expanded.
+  Optional<unsigned> getNumArgumentsInExpansion(QualType T,
+      const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  /// \brief Determine whether the given declarator contains any unexpanded
+  /// parameter packs.
+  ///
+  /// This routine is used by the parser to disambiguate function declarators
+  /// with an ellipsis prior to the ')', e.g.,
+  ///
+  /// \code
+  ///   void f(T...);
+  /// \endcode
+  ///
+  /// To determine whether we have an (unnamed) function parameter pack or
+  /// a variadic function.
+  ///
+  /// \returns true if the declarator contains any unexpanded parameter packs,
+  /// false otherwise.
+  bool containsUnexpandedParameterPacks(Declarator &D);
+
+  /// \brief Returns the pattern of the pack expansion for a template argument.
+  ///
+  /// \param OrigLoc The template argument to expand.
+  ///
+  /// \param Ellipsis Will be set to the location of the ellipsis.
+  ///
+  /// \param NumExpansions Will be set to the number of expansions that will
+  /// be generated from this pack expansion, if known a priori.
+  TemplateArgumentLoc getTemplateArgumentPackExpansionPattern(
+      TemplateArgumentLoc OrigLoc,
+      SourceLocation &Ellipsis,
+      Optional<unsigned> &NumExpansions) const;
+
+  //===--------------------------------------------------------------------===//
+  // C++ Template Argument Deduction (C++ [temp.deduct])
+  //===--------------------------------------------------------------------===//
+
+  QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType);
+
+  /// \brief Describes the result of template argument deduction.
+  ///
+  /// The TemplateDeductionResult enumeration describes the result of
+  /// template argument deduction, as returned from
+  /// DeduceTemplateArguments(). The separate TemplateDeductionInfo
+  /// structure provides additional information about the results of
+  /// template argument deduction, e.g., the deduced template argument
+  /// list (if successful) or the specific template parameters or
+  /// deduced arguments that were involved in the failure.
+  enum TemplateDeductionResult {
+    /// \brief Template argument deduction was successful.
+    TDK_Success = 0,
+    /// \brief The declaration was invalid; do nothing.
+    TDK_Invalid,
+    /// \brief Template argument deduction exceeded the maximum template
+    /// instantiation depth (which has already been diagnosed).
+    TDK_InstantiationDepth,
+    /// \brief Template argument deduction did not deduce a value
+    /// for every template parameter.
+    TDK_Incomplete,
+    /// \brief Template argument deduction produced inconsistent
+    /// deduced values for the given template parameter.
+    TDK_Inconsistent,
+    /// \brief Template argument deduction failed due to inconsistent
+    /// cv-qualifiers on a template parameter type that would
+    /// otherwise be deduced, e.g., we tried to deduce T in "const T"
+    /// but were given a non-const "X".
+    TDK_Underqualified,
+    /// \brief Substitution of the deduced template argument values
+    /// resulted in an error.
+    TDK_SubstitutionFailure,
+    /// \brief A non-depnedent component of the parameter did not match the
+    /// corresponding component of the argument.
+    TDK_NonDeducedMismatch,
+    /// \brief When performing template argument deduction for a function
+    /// template, there were too many call arguments.
+    TDK_TooManyArguments,
+    /// \brief When performing template argument deduction for a function
+    /// template, there were too few call arguments.
+    TDK_TooFewArguments,
+    /// \brief The explicitly-specified template arguments were not valid
+    /// template arguments for the given template.
+    TDK_InvalidExplicitArguments,
+    /// \brief The arguments included an overloaded function name that could
+    /// not be resolved to a suitable function.
+    TDK_FailedOverloadResolution,
+    /// \brief Deduction failed; that's all we know.
+    TDK_MiscellaneousDeductionFailure
+  };
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
+                          const TemplateArgumentList &TemplateArgs,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
+                          const TemplateArgumentList &TemplateArgs,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult SubstituteExplicitTemplateArguments(
+      FunctionTemplateDecl *FunctionTemplate,
+      TemplateArgumentListInfo &ExplicitTemplateArgs,
+      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+      SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType,
+      sema::TemplateDeductionInfo &Info);
+
+  /// brief A function argument from which we performed template argument
+  // deduction for a call.
+  struct OriginalCallArg {
+    OriginalCallArg(QualType OriginalParamType,
+                    unsigned ArgIdx,
+                    QualType OriginalArgType)
+      : OriginalParamType(OriginalParamType), ArgIdx(ArgIdx),
+        OriginalArgType(OriginalArgType) { }
+
+    QualType OriginalParamType;
+    unsigned ArgIdx;
+    QualType OriginalArgType;
+  };
+
+  TemplateDeductionResult
+  FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
+                      SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                                  unsigned NumExplicitlySpecified,
+                                  FunctionDecl *&Specialization,
+                                  sema::TemplateDeductionInfo &Info,
+           SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          ArrayRef<Expr *> Args,
+                          FunctionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          QualType ArgFunctionType,
+                          FunctionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info,
+                          bool InOverloadResolution = false);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          QualType ToType,
+                          CXXConversionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info);
+
+  TemplateDeductionResult
+  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+                          TemplateArgumentListInfo *ExplicitTemplateArgs,
+                          FunctionDecl *&Specialization,
+                          sema::TemplateDeductionInfo &Info,
+                          bool InOverloadResolution = false);
+
+  /// \brief Substitute Replacement for \p auto in \p TypeWithAuto
+  QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement);
+  /// \brief Substitute Replacement for auto in TypeWithAuto
+  TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, 
+                                          QualType Replacement);
+
+  /// \brief Result type of DeduceAutoType.
+  enum DeduceAutoResult {
+    DAR_Succeeded,
+    DAR_Failed,
+    DAR_FailedAlreadyDiagnosed
+  };
+
+  DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
+                                  QualType &Result);
+  DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer,
+                                  QualType &Result);
+  void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
+  bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
+                        bool Diagnose = true);
+
+  bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
+                                        SourceLocation ReturnLoc,
+                                        Expr *&RetExpr, AutoType *AT);
+
+  FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
+                                                   FunctionTemplateDecl *FT2,
+                                                   SourceLocation Loc,
+                                           TemplatePartialOrderingContext TPOC,
+                                                   unsigned NumCallArguments1,
+                                                   unsigned NumCallArguments2);
+  UnresolvedSetIterator
+  getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
+                     TemplateSpecCandidateSet &FailedCandidates,
+                     SourceLocation Loc,
+                     const PartialDiagnostic &NoneDiag,
+                     const PartialDiagnostic &AmbigDiag,
+                     const PartialDiagnostic &CandidateDiag,
+                     bool Complain = true, QualType TargetType = QualType());
+
+  ClassTemplatePartialSpecializationDecl *
+  getMoreSpecializedPartialSpecialization(
+                                  ClassTemplatePartialSpecializationDecl *PS1,
+                                  ClassTemplatePartialSpecializationDecl *PS2,
+                                  SourceLocation Loc);
+
+  VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization(
+      VarTemplatePartialSpecializationDecl *PS1,
+      VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc);
+
+  void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
+                                  bool OnlyDeduced,
+                                  unsigned Depth,
+                                  llvm::SmallBitVector &Used);
+  void MarkDeducedTemplateParameters(
+                                  const FunctionTemplateDecl *FunctionTemplate,
+                                  llvm::SmallBitVector &Deduced) {
+    return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced);
+  }
+  static void MarkDeducedTemplateParameters(ASTContext &Ctx,
+                                  const FunctionTemplateDecl *FunctionTemplate,
+                                  llvm::SmallBitVector &Deduced);
+
+  //===--------------------------------------------------------------------===//
+  // C++ Template Instantiation
+  //
+
+  MultiLevelTemplateArgumentList
+  getTemplateInstantiationArgs(NamedDecl *D,
+                               const TemplateArgumentList *Innermost = nullptr,
+                               bool RelativeToPrimary = false,
+                               const FunctionDecl *Pattern = nullptr);
+
+  /// \brief A template instantiation that is currently in progress.
+  struct ActiveTemplateInstantiation {
+    /// \brief The kind of template instantiation we are performing
+    enum InstantiationKind {
+      /// We are instantiating a template declaration. The entity is
+      /// the declaration we're instantiating (e.g., a CXXRecordDecl).
+      TemplateInstantiation,
+
+      /// We are instantiating a default argument for a template
+      /// parameter. The Entity is the template, and
+      /// TemplateArgs/NumTemplateArguments provides the template
+      /// arguments as specified.
+      /// FIXME: Use a TemplateArgumentList
+      DefaultTemplateArgumentInstantiation,
+
+      /// We are instantiating a default argument for a function.
+      /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
+      /// provides the template arguments as specified.
+      DefaultFunctionArgumentInstantiation,
+
+      /// We are substituting explicit template arguments provided for
+      /// a function template. The entity is a FunctionTemplateDecl.
+      ExplicitTemplateArgumentSubstitution,
+
+      /// We are substituting template argument determined as part of
+      /// template argument deduction for either a class template
+      /// partial specialization or a function template. The
+      /// Entity is either a ClassTemplatePartialSpecializationDecl or
+      /// a FunctionTemplateDecl.
+      DeducedTemplateArgumentSubstitution,
+
+      /// We are substituting prior template arguments into a new
+      /// template parameter. The template parameter itself is either a
+      /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
+      PriorTemplateArgumentSubstitution,
+
+      /// We are checking the validity of a default template argument that
+      /// has been used when naming a template-id.
+      DefaultTemplateArgumentChecking,
+
+      /// We are instantiating the exception specification for a function
+      /// template which was deferred until it was needed.
+      ExceptionSpecInstantiation
+    } Kind;
+
+    /// \brief The point of instantiation within the source code.
+    SourceLocation PointOfInstantiation;
+
+    /// \brief The template (or partial specialization) in which we are
+    /// performing the instantiation, for substitutions of prior template
+    /// arguments.
+    NamedDecl *Template;
+
+    /// \brief The entity that is being instantiated.
+    Decl *Entity;
+
+    /// \brief The list of template arguments we are substituting, if they
+    /// are not part of the entity.
+    const TemplateArgument *TemplateArgs;
+
+    /// \brief The number of template arguments in TemplateArgs.
+    unsigned NumTemplateArgs;
+
+    /// \brief The template deduction info object associated with the
+    /// substitution or checking of explicit or deduced template arguments.
+    sema::TemplateDeductionInfo *DeductionInfo;
+
+    /// \brief The source range that covers the construct that cause
+    /// the instantiation, e.g., the template-id that causes a class
+    /// template instantiation.
+    SourceRange InstantiationRange;
+
+    ActiveTemplateInstantiation()
+      : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr),
+        TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {}
+
+    /// \brief Determines whether this template is an actual instantiation
+    /// that should be counted toward the maximum instantiation depth.
+    bool isInstantiationRecord() const;
+
+    friend bool operator==(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      if (X.Kind != Y.Kind)
+        return false;
+
+      if (X.Entity != Y.Entity)
+        return false;
+
+      switch (X.Kind) {
+      case TemplateInstantiation:
+      case ExceptionSpecInstantiation:
+        return true;
+
+      case PriorTemplateArgumentSubstitution:
+      case DefaultTemplateArgumentChecking:
+        return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs;
+
+      case DefaultTemplateArgumentInstantiation:
+      case ExplicitTemplateArgumentSubstitution:
+      case DeducedTemplateArgumentSubstitution:
+      case DefaultFunctionArgumentInstantiation:
+        return X.TemplateArgs == Y.TemplateArgs;
+
+      }
+
+      llvm_unreachable("Invalid InstantiationKind!");
+    }
+
+    friend bool operator!=(const ActiveTemplateInstantiation &X,
+                           const ActiveTemplateInstantiation &Y) {
+      return !(X == Y);
+    }
+  };
+
+  /// \brief List of active template instantiations.
+  ///
+  /// This vector is treated as a stack. As one template instantiation
+  /// requires another template instantiation, additional
+  /// instantiations are pushed onto the stack up to a
+  /// user-configurable limit LangOptions::InstantiationDepth.
+  SmallVector<ActiveTemplateInstantiation, 16>
+    ActiveTemplateInstantiations;
+
+  /// \brief Extra modules inspected when performing a lookup during a template
+  /// instantiation. Computed lazily.
+  SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
+
+  /// \brief Cache of additional modules that should be used for name lookup
+  /// within the current template instantiation. Computed lazily; use
+  /// getLookupModules() to get a complete set.
+  llvm::DenseSet<Module*> LookupModulesCache;
+
+  /// \brief Get the set of additional modules that should be checked during
+  /// name lookup. A module and its imports become visible when instanting a
+  /// template defined within it.
+  llvm::DenseSet<Module*> &getLookupModules();
+
+  /// \brief Whether we are in a SFINAE context that is not associated with
+  /// template instantiation.
+  ///
+  /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
+  /// of a template instantiation or template argument deduction.
+  bool InNonInstantiationSFINAEContext;
+
+  /// \brief The number of ActiveTemplateInstantiation entries in
+  /// \c ActiveTemplateInstantiations that are not actual instantiations and,
+  /// therefore, should not be counted as part of the instantiation depth.
+  unsigned NonInstantiationEntries;
+
+  /// \brief The last template from which a template instantiation
+  /// error or warning was produced.
+  ///
+  /// This value is used to suppress printing of redundant template
+  /// instantiation backtraces when there are multiple errors in the
+  /// same instantiation. FIXME: Does this belong in Sema? It's tough
+  /// to implement it anywhere else.
+  ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
+
+  /// \brief The current index into pack expansion arguments that will be
+  /// used for substitution of parameter packs.
+  ///
+  /// The pack expansion index will be -1 to indicate that parameter packs
+  /// should be instantiated as themselves. Otherwise, the index specifies
+  /// which argument within the parameter pack will be used for substitution.
+  int ArgumentPackSubstitutionIndex;
+
+  /// \brief RAII object used to change the argument pack substitution index
+  /// within a \c Sema object.
+  ///
+  /// See \c ArgumentPackSubstitutionIndex for more information.
+  class ArgumentPackSubstitutionIndexRAII {
+    Sema &Self;
+    int OldSubstitutionIndex;
+
+  public:
+    ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex)
+      : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) {
+      Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex;
+    }
+
+    ~ArgumentPackSubstitutionIndexRAII() {
+      Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex;
+    }
+  };
+
+  friend class ArgumentPackSubstitutionRAII;
+
+  /// \brief The stack of calls expression undergoing template instantiation.
+  ///
+  /// The top of this stack is used by a fixit instantiating unresolved
+  /// function calls to fix the AST to match the textual change it prints.
+  SmallVector<CallExpr *, 8> CallsUndergoingInstantiation;
+
+  /// \brief For each declaration that involved template argument deduction, the
+  /// set of diagnostics that were suppressed during that template argument
+  /// deduction.
+  ///
+  /// FIXME: Serialize this structure to the AST file.
+  typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> >
+    SuppressedDiagnosticsMap;
+  SuppressedDiagnosticsMap SuppressedDiagnostics;
+
+  /// \brief A stack object to be created when performing template
+  /// instantiation.
+  ///
+  /// Construction of an object of type \c InstantiatingTemplate
+  /// pushes the current instantiation onto the stack of active
+  /// instantiations. If the size of this stack exceeds the maximum
+  /// number of recursive template instantiations, construction
+  /// produces an error and evaluates true.
+  ///
+  /// Destruction of this object will pop the named instantiation off
+  /// the stack.
+  struct InstantiatingTemplate {
+    /// \brief Note that we are instantiating a class template,
+    /// function template, or a member thereof.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          Decl *Entity,
+                          SourceRange InstantiationRange = SourceRange());
+
+    struct ExceptionSpecification {};
+    /// \brief Note that we are instantiating an exception specification
+    /// of a function template.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          FunctionDecl *Entity, ExceptionSpecification,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating a default argument in a
+    /// template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating a default argument in a
+    /// template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          FunctionTemplateDecl *FunctionTemplate,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          ActiveTemplateInstantiation::InstantiationKind Kind,
+                          sema::TemplateDeductionInfo &DeductionInfo,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating as part of template
+    /// argument deduction for a class template partial
+    /// specialization.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          ClassTemplatePartialSpecializationDecl *PartialSpec,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          sema::TemplateDeductionInfo &DeductionInfo,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are instantiating as part of template
+    /// argument deduction for a variable template partial
+    /// specialization.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          VarTemplatePartialSpecializationDecl *PartialSpec,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          sema::TemplateDeductionInfo &DeductionInfo,
+                          SourceRange InstantiationRange = SourceRange());
+
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          ParmVarDecl *Param,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          SourceRange InstantiationRange = SourceRange());
+
+    /// \brief Note that we are substituting prior template arguments into a
+    /// non-type parameter.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          NamedDecl *Template,
+                          NonTypeTemplateParmDecl *Param,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          SourceRange InstantiationRange);
+
+    /// \brief Note that we are substituting prior template arguments into a
+    /// template template parameter.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          NamedDecl *Template,
+                          TemplateTemplateParmDecl *Param,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          SourceRange InstantiationRange);
+
+    /// \brief Note that we are checking the default template argument
+    /// against the template parameter for a given template-id.
+    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+                          TemplateDecl *Template,
+                          NamedDecl *Param,
+                          ArrayRef<TemplateArgument> TemplateArgs,
+                          SourceRange InstantiationRange);
+
+
+    /// \brief Note that we have finished instantiating this template.
+    void Clear();
+
+    ~InstantiatingTemplate() { Clear(); }
+
+    /// \brief Determines whether we have exceeded the maximum
+    /// recursive template instantiations.
+    bool isInvalid() const { return Invalid; }
+
+  private:
+    Sema &SemaRef;
+    bool Invalid;
+    bool SavedInNonInstantiationSFINAEContext;
+    bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
+                                 SourceRange InstantiationRange);
+
+    // FIXME: Replace this with a constructor once we can use delegating
+    // constructors in llvm.
+    void Initialize(
+        ActiveTemplateInstantiation::InstantiationKind Kind,
+        SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
+        Decl *Entity, NamedDecl *Template = nullptr,
+        ArrayRef<TemplateArgument> TemplateArgs = ArrayRef<TemplateArgument>(),
+        sema::TemplateDeductionInfo *DeductionInfo = nullptr);
+
+    InstantiatingTemplate(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION;
+
+    InstantiatingTemplate&
+    operator=(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION;
+  };
+
+  void PrintInstantiationStack();
+
+  /// \brief Determines whether we are currently in a context where
+  /// template argument substitution failures are not considered
+  /// errors.
+  ///
+  /// \returns An empty \c Optional if we're not in a SFINAE context.
+  /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
+  /// template-deduction context object, which can be used to capture
+  /// diagnostics that will be suppressed.
+  Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
+
+  /// \brief Determines whether we are currently in a context that
+  /// is not evaluated as per C++ [expr] p5.
+  bool isUnevaluatedContext() const {
+    assert(!ExprEvalContexts.empty() &&
+           "Must be in an expression evaluation context");
+    return ExprEvalContexts.back().isUnevaluated();
+  }
+
+  /// \brief RAII class used to determine whether SFINAE has
+  /// trapped any errors that occur during template argument
+  /// deduction.
+  class SFINAETrap {
+    Sema &SemaRef;
+    unsigned PrevSFINAEErrors;
+    bool PrevInNonInstantiationSFINAEContext;
+    bool PrevAccessCheckingSFINAE;
+
+  public:
+    explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false)
+      : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
+        PrevInNonInstantiationSFINAEContext(
+                                      SemaRef.InNonInstantiationSFINAEContext),
+        PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE)
+    {
+      if (!SemaRef.isSFINAEContext())
+        SemaRef.InNonInstantiationSFINAEContext = true;
+      SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE;
+    }
+
+    ~SFINAETrap() {
+      SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
+      SemaRef.InNonInstantiationSFINAEContext
+        = PrevInNonInstantiationSFINAEContext;
+      SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
+    }
+
+    /// \brief Determine whether any SFINAE errors have been trapped.
+    bool hasErrorOccurred() const {
+      return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
+    }
+  };
+
+  /// \brief RAII class used to indicate that we are performing provisional
+  /// semantic analysis to determine the validity of a construct, so
+  /// typo-correction and diagnostics in the immediate context (not within
+  /// implicitly-instantiated templates) should be suppressed.
+  class TentativeAnalysisScope {
+    Sema &SemaRef;
+    // FIXME: Using a SFINAETrap for this is a hack.
+    SFINAETrap Trap;
+    bool PrevDisableTypoCorrection;
+  public:
+    explicit TentativeAnalysisScope(Sema &SemaRef)
+        : SemaRef(SemaRef), Trap(SemaRef, true),
+          PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) {
+      SemaRef.DisableTypoCorrection = true;
+    }
+    ~TentativeAnalysisScope() {
+      SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection;
+    }
+  };
+
+  /// \brief The current instantiation scope used to store local
+  /// variables.
+  LocalInstantiationScope *CurrentInstantiationScope;
+
+  /// \brief Tracks whether we are in a context where typo correction is
+  /// disabled.
+  bool DisableTypoCorrection;
+
+  /// \brief The number of typos corrected by CorrectTypo.
+  unsigned TyposCorrected;
+
+  typedef llvm::DenseMap<IdentifierInfo *, TypoCorrection>
+    UnqualifiedTyposCorrectedMap;
+
+  /// \brief A cache containing the results of typo correction for unqualified
+  /// name lookup.
+  ///
+  /// The string is the string that we corrected to (which may be empty, if
+  /// there was no correction), while the boolean will be true when the
+  /// string represents a keyword.
+  UnqualifiedTyposCorrectedMap UnqualifiedTyposCorrected;
+
+  typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet;
+  typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations;
+
+  /// \brief A cache containing identifiers for which typo correction failed and
+  /// their locations, so that repeated attempts to correct an identifier in a
+  /// given location are ignored if typo correction already failed for it.
+  IdentifierSourceLocations TypoCorrectionFailures;
+
+  /// \brief Worker object for performing CFG-based warnings.
+  sema::AnalysisBasedWarnings AnalysisWarnings;
+
+  /// \brief An entity for which implicit template instantiation is required.
+  ///
+  /// The source location associated with the declaration is the first place in
+  /// the source code where the declaration was "used". It is not necessarily
+  /// the point of instantiation (which will be either before or after the
+  /// namespace-scope declaration that triggered this implicit instantiation),
+  /// However, it is the location that diagnostics should generally refer to,
+  /// because users will need to know what code triggered the instantiation.
+  typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
+
+  /// \brief The queue of implicit template instantiations that are required
+  /// but have not yet been performed.
+  std::deque<PendingImplicitInstantiation> PendingInstantiations;
+
+  /// \brief The queue of implicit template instantiations that are required
+  /// and must be performed within the current local scope.
+  ///
+  /// This queue is only used for member functions of local classes in
+  /// templates, which must be instantiated in the same scope as their
+  /// enclosing function, so that they can reference function-local
+  /// types, static variables, enumerators, etc.
+  std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
+
+  class SavePendingLocalImplicitInstantiationsRAII {
+  public:
+    SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
+      SavedPendingLocalImplicitInstantiations.swap(
+          S.PendingLocalImplicitInstantiations);
+    }
+
+    ~SavePendingLocalImplicitInstantiationsRAII() {
+      assert(S.PendingLocalImplicitInstantiations.empty() &&
+             "there shouldn't be any pending local implicit instantiations");
+      SavedPendingLocalImplicitInstantiations.swap(
+          S.PendingLocalImplicitInstantiations);
+    }
+
+  private:
+    Sema &S;
+    std::deque<PendingImplicitInstantiation>
+    SavedPendingLocalImplicitInstantiations;
+  };
+
+  void PerformPendingInstantiations(bool LocalOnly = false);
+
+  TypeSourceInfo *SubstType(TypeSourceInfo *T,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                            SourceLocation Loc, DeclarationName Entity);
+
+  QualType SubstType(QualType T,
+                     const MultiLevelTemplateArgumentList &TemplateArgs,
+                     SourceLocation Loc, DeclarationName Entity);
+
+  TypeSourceInfo *SubstType(TypeLoc TL,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                            SourceLocation Loc, DeclarationName Entity);
+
+  TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                        SourceLocation Loc,
+                                        DeclarationName Entity,
+                                        CXXRecordDecl *ThisContext,
+                                        unsigned ThisTypeQuals);
+  ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                                int indexAdjustment,
+                                Optional<unsigned> NumExpansions,
+                                bool ExpectParameterPack);
+  bool SubstParmTypes(SourceLocation Loc,
+                      ParmVarDecl **Params, unsigned NumParams,
+                      const MultiLevelTemplateArgumentList &TemplateArgs,
+                      SmallVectorImpl<QualType> &ParamTypes,
+                      SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr);
+  ExprResult SubstExpr(Expr *E,
+                       const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  /// \brief Substitute the given template arguments into a list of
+  /// expressions, expanding pack expansions if required.
+  ///
+  /// \param Exprs The list of expressions to substitute into.
+  ///
+  /// \param NumExprs The number of expressions in \p Exprs.
+  ///
+  /// \param IsCall Whether this is some form of call, in which case
+  /// default arguments will be dropped.
+  ///
+  /// \param TemplateArgs The set of template arguments to substitute.
+  ///
+  /// \param Outputs Will receive all of the substituted arguments.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall,
+                  const MultiLevelTemplateArgumentList &TemplateArgs,
+                  SmallVectorImpl<Expr *> &Outputs);
+
+  StmtResult SubstStmt(Stmt *S,
+                       const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  Decl *SubstDecl(Decl *D, DeclContext *Owner,
+                  const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  ExprResult SubstInitializer(Expr *E,
+                       const MultiLevelTemplateArgumentList &TemplateArgs,
+                       bool CXXDirectInit);
+
+  bool
+  SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
+                      CXXRecordDecl *Pattern,
+                      const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  bool
+  InstantiateClass(SourceLocation PointOfInstantiation,
+                   CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
+                   const MultiLevelTemplateArgumentList &TemplateArgs,
+                   TemplateSpecializationKind TSK,
+                   bool Complain = true);
+
+  bool InstantiateEnum(SourceLocation PointOfInstantiation,
+                       EnumDecl *Instantiation, EnumDecl *Pattern,
+                       const MultiLevelTemplateArgumentList &TemplateArgs,
+                       TemplateSpecializationKind TSK);
+
+  struct LateInstantiatedAttribute {
+    const Attr *TmplAttr;
+    LocalInstantiationScope *Scope;
+    Decl *NewDecl;
+
+    LateInstantiatedAttribute(const Attr *A, LocalInstantiationScope *S,
+                              Decl *D)
+      : TmplAttr(A), Scope(S), NewDecl(D)
+    { }
+  };
+  typedef SmallVector<LateInstantiatedAttribute, 16> LateInstantiatedAttrVec;
+
+  void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                        const Decl *Pattern, Decl *Inst,
+                        LateInstantiatedAttrVec *LateAttrs = nullptr,
+                        LocalInstantiationScope *OuterMostScope = nullptr);
+
+  bool
+  InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
+                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                           TemplateSpecializationKind TSK,
+                           bool Complain = true);
+
+  void InstantiateClassMembers(SourceLocation PointOfInstantiation,
+                               CXXRecordDecl *Instantiation,
+                            const MultiLevelTemplateArgumentList &TemplateArgs,
+                               TemplateSpecializationKind TSK);
+
+  void InstantiateClassTemplateSpecializationMembers(
+                                          SourceLocation PointOfInstantiation,
+                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
+                                                TemplateSpecializationKind TSK);
+
+  NestedNameSpecifierLoc
+  SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  DeclarationNameInfo
+  SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
+  TemplateName
+  SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name,
+                    SourceLocation Loc,
+                    const MultiLevelTemplateArgumentList &TemplateArgs);
+  bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,
+             TemplateArgumentListInfo &Result,
+             const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  void InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
+                                FunctionDecl *Function);
+  void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+                                     FunctionDecl *Function,
+                                     bool Recursive = false,
+                                     bool DefinitionRequired = false);
+  VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
+      VarTemplateDecl *VarTemplate, VarDecl *FromVar,
+      const TemplateArgumentList &TemplateArgList,
+      const TemplateArgumentListInfo &TemplateArgsInfo,
+      SmallVectorImpl<TemplateArgument> &Converted,
+      SourceLocation PointOfInstantiation, void *InsertPos,
+      LateInstantiatedAttrVec *LateAttrs = nullptr,
+      LocalInstantiationScope *StartingScope = nullptr);
+  VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl(
+      VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
+      const MultiLevelTemplateArgumentList &TemplateArgs);
+  void
+  BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar,
+                             const MultiLevelTemplateArgumentList &TemplateArgs,
+                             LateInstantiatedAttrVec *LateAttrs,
+                             DeclContext *Owner,
+                             LocalInstantiationScope *StartingScope,
+                             bool InstantiatingVarTemplate = false);
+  void InstantiateVariableInitializer(
+      VarDecl *Var, VarDecl *OldVar,
+      const MultiLevelTemplateArgumentList &TemplateArgs);
+  void InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
+                                     VarDecl *Var, bool Recursive = false,
+                                     bool DefinitionRequired = false);
+  void InstantiateStaticDataMemberDefinition(
+                                     SourceLocation PointOfInstantiation,
+                                     VarDecl *Var,
+                                     bool Recursive = false,
+                                     bool DefinitionRequired = false);
+
+  void InstantiateMemInitializers(CXXConstructorDecl *New,
+                                  const CXXConstructorDecl *Tmpl,
+                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
+                          const MultiLevelTemplateArgumentList &TemplateArgs);
+  DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
+                          const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  // Objective-C declarations.
+  enum ObjCContainerKind {
+    OCK_None = -1,
+    OCK_Interface = 0,
+    OCK_Protocol,
+    OCK_Category,
+    OCK_ClassExtension,
+    OCK_Implementation,
+    OCK_CategoryImplementation
+  };
+  ObjCContainerKind getObjCContainerKind() const;
+
+  Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
+                                 IdentifierInfo *ClassName,
+                                 SourceLocation ClassLoc,
+                                 IdentifierInfo *SuperName,
+                                 SourceLocation SuperLoc,
+                                 Decl * const *ProtoRefs,
+                                 unsigned NumProtoRefs,
+                                 const SourceLocation *ProtoLocs,
+                                 SourceLocation EndProtoLoc,
+                                 AttributeList *AttrList);
+  
+  void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
+                               IdentifierInfo *SuperName,
+                               SourceLocation SuperLoc);
+
+  Decl *ActOnCompatibilityAlias(
+                    SourceLocation AtCompatibilityAliasLoc,
+                    IdentifierInfo *AliasName,  SourceLocation AliasLocation,
+                    IdentifierInfo *ClassName, SourceLocation ClassLocation);
+
+  bool CheckForwardProtocolDeclarationForCircularDependency(
+    IdentifierInfo *PName,
+    SourceLocation &PLoc, SourceLocation PrevLoc,
+    const ObjCList<ObjCProtocolDecl> &PList);
+
+  Decl *ActOnStartProtocolInterface(
+                    SourceLocation AtProtoInterfaceLoc,
+                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
+                    Decl * const *ProtoRefNames, unsigned NumProtoRefs,
+                    const SourceLocation *ProtoLocs,
+                    SourceLocation EndProtoLoc,
+                    AttributeList *AttrList);
+
+  Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
+                                    IdentifierInfo *ClassName,
+                                    SourceLocation ClassLoc,
+                                    IdentifierInfo *CategoryName,
+                                    SourceLocation CategoryLoc,
+                                    Decl * const *ProtoRefs,
+                                    unsigned NumProtoRefs,
+                                    const SourceLocation *ProtoLocs,
+                                    SourceLocation EndProtoLoc);
+
+  Decl *ActOnStartClassImplementation(
+                    SourceLocation AtClassImplLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperClassname,
+                    SourceLocation SuperClassLoc);
+
+  Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc,
+                                         IdentifierInfo *ClassName,
+                                         SourceLocation ClassLoc,
+                                         IdentifierInfo *CatName,
+                                         SourceLocation CatLoc);
+
+  DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl,
+                                               ArrayRef<Decl *> Decls);
+
+  DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
+                                     IdentifierInfo **IdentList,
+                                     SourceLocation *IdentLocs,
+                                     unsigned NumElts);
+
+  DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
+                                        const IdentifierLocPair *IdentList,
+                                        unsigned NumElts,
+                                        AttributeList *attrList);
+
+  void FindProtocolDeclaration(bool WarnOnDeclarations,
+                               const IdentifierLocPair *ProtocolId,
+                               unsigned NumProtocols,
+                               SmallVectorImpl<Decl *> &Protocols);
+
+  /// Ensure attributes are consistent with type.
+  /// \param [in, out] Attributes The attributes to check; they will
+  /// be modified to be consistent with \p PropertyTy.
+  void CheckObjCPropertyAttributes(Decl *PropertyPtrTy,
+                                   SourceLocation Loc,
+                                   unsigned &Attributes,
+                                   bool propertyInPrimaryClass);
+
+  /// Process the specified property declaration and create decls for the
+  /// setters and getters as needed.
+  /// \param property The property declaration being processed
+  /// \param CD The semantic container for the property
+  /// \param redeclaredProperty Declaration for property if redeclared
+  ///        in class extension.
+  /// \param lexicalDC Container for redeclaredProperty.
+  void ProcessPropertyDecl(ObjCPropertyDecl *property,
+                           ObjCContainerDecl *CD,
+                           ObjCPropertyDecl *redeclaredProperty = nullptr,
+                           ObjCContainerDecl *lexicalDC = nullptr);
+
+
+  void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
+                                ObjCPropertyDecl *SuperProperty,
+                                const IdentifierInfo *Name,
+                                bool OverridingProtocolProperty);
+
+  void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
+                                        ObjCInterfaceDecl *ID);
+
+  Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd,
+                   ArrayRef<Decl *> allMethods = None,
+                   ArrayRef<DeclGroupPtrTy> allTUVars = None);
+
+  Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
+                      SourceLocation LParenLoc,
+                      FieldDeclarator &FD, ObjCDeclSpec &ODS,
+                      Selector GetterSel, Selector SetterSel,
+                      bool *OverridingProperty,
+                      tok::ObjCKeywordKind MethodImplKind,
+                      DeclContext *lexicalDC = nullptr);
+
+  Decl *ActOnPropertyImplDecl(Scope *S,
+                              SourceLocation AtLoc,
+                              SourceLocation PropertyLoc,
+                              bool ImplKind,
+                              IdentifierInfo *PropertyId,
+                              IdentifierInfo *PropertyIvar,
+                              SourceLocation PropertyIvarLoc);
+
+  enum ObjCSpecialMethodKind {
+    OSMK_None,
+    OSMK_Alloc,
+    OSMK_New,
+    OSMK_Copy,
+    OSMK_RetainingInit,
+    OSMK_NonRetainingInit
+  };
+
+  struct ObjCArgInfo {
+    IdentifierInfo *Name;
+    SourceLocation NameLoc;
+    // The Type is null if no type was specified, and the DeclSpec is invalid
+    // in this case.
+    ParsedType Type;
+    ObjCDeclSpec DeclSpec;
+
+    /// ArgAttrs - Attribute list for this argument.
+    AttributeList *ArgAttrs;
+  };
+
+  Decl *ActOnMethodDeclaration(
+    Scope *S,
+    SourceLocation BeginLoc, // location of the + or -.
+    SourceLocation EndLoc,   // location of the ; or {.
+    tok::TokenKind MethodType,
+    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
+    ArrayRef<SourceLocation> SelectorLocs, Selector Sel,
+    // optional arguments. The number of types/arguments is obtained
+    // from the Sel.getNumArgs().
+    ObjCArgInfo *ArgInfo,
+    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
+    AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
+    bool isVariadic, bool MethodDefinition);
+
+  ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
+                                              const ObjCObjectPointerType *OPT,
+                                              bool IsInstance);
+  ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty,
+                                           bool IsInstance);
+
+  bool CheckARCMethodDecl(ObjCMethodDecl *method);
+  bool inferObjCARCLifetime(ValueDecl *decl);
+
+  ExprResult
+  HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+                            Expr *BaseExpr,
+                            SourceLocation OpLoc,
+                            DeclarationName MemberName,
+                            SourceLocation MemberLoc,
+                            SourceLocation SuperLoc, QualType SuperType,
+                            bool Super);
+
+  ExprResult
+  ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+                            IdentifierInfo &propertyName,
+                            SourceLocation receiverNameLoc,
+                            SourceLocation propertyNameLoc);
+
+  ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc);
+
+  /// \brief Describes the kind of message expression indicated by a message
+  /// send that starts with an identifier.
+  enum ObjCMessageKind {
+    /// \brief The message is sent to 'super'.
+    ObjCSuperMessage,
+    /// \brief The message is an instance message.
+    ObjCInstanceMessage,
+    /// \brief The message is a class message, and the identifier is a type
+    /// name.
+    ObjCClassMessage
+  };
+
+  ObjCMessageKind getObjCMessageKind(Scope *S,
+                                     IdentifierInfo *Name,
+                                     SourceLocation NameLoc,
+                                     bool IsSuper,
+                                     bool HasTrailingDot,
+                                     ParsedType &ReceiverType);
+
+  ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+                               Selector Sel,
+                               SourceLocation LBracLoc,
+                               ArrayRef<SourceLocation> SelectorLocs,
+                               SourceLocation RBracLoc,
+                               MultiExprArg Args);
+
+  ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+                               QualType ReceiverType,
+                               SourceLocation SuperLoc,
+                               Selector Sel,
+                               ObjCMethodDecl *Method,
+                               SourceLocation LBracLoc,
+                               ArrayRef<SourceLocation> SelectorLocs,
+                               SourceLocation RBracLoc,
+                               MultiExprArg Args,
+                               bool isImplicit = false);
+
+  ExprResult BuildClassMessageImplicit(QualType ReceiverType,
+                                       bool isSuperReceiver,
+                                       SourceLocation Loc,
+                                       Selector Sel,
+                                       ObjCMethodDecl *Method,
+                                       MultiExprArg Args);
+
+  ExprResult ActOnClassMessage(Scope *S,
+                               ParsedType Receiver,
+                               Selector Sel,
+                               SourceLocation LBracLoc,
+                               ArrayRef<SourceLocation> SelectorLocs,
+                               SourceLocation RBracLoc,
+                               MultiExprArg Args);
+
+  ExprResult BuildInstanceMessage(Expr *Receiver,
+                                  QualType ReceiverType,
+                                  SourceLocation SuperLoc,
+                                  Selector Sel,
+                                  ObjCMethodDecl *Method,
+                                  SourceLocation LBracLoc,
+                                  ArrayRef<SourceLocation> SelectorLocs,
+                                  SourceLocation RBracLoc,
+                                  MultiExprArg Args,
+                                  bool isImplicit = false);
+
+  ExprResult BuildInstanceMessageImplicit(Expr *Receiver,
+                                          QualType ReceiverType,
+                                          SourceLocation Loc,
+                                          Selector Sel,
+                                          ObjCMethodDecl *Method,
+                                          MultiExprArg Args);
+
+  ExprResult ActOnInstanceMessage(Scope *S,
+                                  Expr *Receiver,
+                                  Selector Sel,
+                                  SourceLocation LBracLoc,
+                                  ArrayRef<SourceLocation> SelectorLocs,
+                                  SourceLocation RBracLoc,
+                                  MultiExprArg Args);
+
+  ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc,
+                                  ObjCBridgeCastKind Kind,
+                                  SourceLocation BridgeKeywordLoc,
+                                  TypeSourceInfo *TSInfo,
+                                  Expr *SubExpr);
+
+  ExprResult ActOnObjCBridgedCast(Scope *S,
+                                  SourceLocation LParenLoc,
+                                  ObjCBridgeCastKind Kind,
+                                  SourceLocation BridgeKeywordLoc,
+                                  ParsedType Type,
+                                  SourceLocation RParenLoc,
+                                  Expr *SubExpr);
+  
+  void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
+  
+  void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr);
+  
+  bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
+                                     CastKind &Kind);
+  
+  bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
+                                        QualType DestType, QualType SrcType,
+                                        ObjCInterfaceDecl *&RelatedClass,
+                                        ObjCMethodDecl *&ClassMethod,
+                                        ObjCMethodDecl *&InstanceMethod,
+                                        TypedefNameDecl *&TDNDecl,
+                                        bool CfToNs);
+  
+  bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+                                         QualType DestType, QualType SrcType,
+                                         Expr *&SrcExpr);
+  
+  bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
+  
+  bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
+
+  /// \brief Check whether the given new method is a valid override of the
+  /// given overridden method, and set any properties that should be inherited.
+  void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
+                               const ObjCMethodDecl *Overridden);
+
+  /// \brief Describes the compatibility of a result type with its method.
+  enum ResultTypeCompatibilityKind {
+    RTC_Compatible,
+    RTC_Incompatible,
+    RTC_Unknown
+  };
+
+  void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
+                                ObjCInterfaceDecl *CurrentClass,
+                                ResultTypeCompatibilityKind RTC);
+
+  enum PragmaOptionsAlignKind {
+    POAK_Native,  // #pragma options align=native
+    POAK_Natural, // #pragma options align=natural
+    POAK_Packed,  // #pragma options align=packed
+    POAK_Power,   // #pragma options align=power
+    POAK_Mac68k,  // #pragma options align=mac68k
+    POAK_Reset    // #pragma options align=reset
+  };
+
+  /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align.
+  void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
+                               SourceLocation PragmaLoc);
+
+  enum PragmaPackKind {
+    PPK_Default, // #pragma pack([n])
+    PPK_Show,    // #pragma pack(show), only supported by MSVC.
+    PPK_Push,    // #pragma pack(push, [identifier], [n])
+    PPK_Pop      // #pragma pack(pop, [identifier], [n])
+  };
+
+  enum PragmaMSStructKind {
+    PMSST_OFF,  // #pragms ms_struct off
+    PMSST_ON    // #pragms ms_struct on
+  };
+
+  enum PragmaMSCommentKind {
+    PCK_Unknown,
+    PCK_Linker,   // #pragma comment(linker, ...)
+    PCK_Lib,      // #pragma comment(lib, ...)
+    PCK_Compiler, // #pragma comment(compiler, ...)
+    PCK_ExeStr,   // #pragma comment(exestr, ...)
+    PCK_User      // #pragma comment(user, ...)
+  };
+
+  /// ActOnPragmaPack - Called on well formed \#pragma pack(...).
+  void ActOnPragmaPack(PragmaPackKind Kind,
+                       IdentifierInfo *Name,
+                       Expr *Alignment,
+                       SourceLocation PragmaLoc,
+                       SourceLocation LParenLoc,
+                       SourceLocation RParenLoc);
+
+  /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
+  void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
+
+  /// ActOnPragmaMSComment - Called on well formed
+  /// \#pragma comment(kind, "arg").
+  void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);
+
+  /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
+  /// pointers_to_members(representation method[, general purpose
+  /// representation]).
+  void ActOnPragmaMSPointersToMembers(
+      LangOptions::PragmaMSPointersToMembersKind Kind,
+      SourceLocation PragmaLoc);
+
+  /// \brief Called on well formed \#pragma vtordisp().
+  void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
+                             MSVtorDispAttr::Mode Value);
+
+  enum PragmaSectionKind {
+    PSK_DataSeg,
+    PSK_BSSSeg,
+    PSK_ConstSeg,
+    PSK_CodeSeg,
+  };
+
+  enum PragmaSectionFlag : unsigned {
+    PSF_None = 0,
+    PSF_Read = 0x1,
+    PSF_Write = 0x2,
+    PSF_Execute = 0x4,
+    PSF_Implicit = 0x8,
+    PSF_Invalid = 0x80000000U,
+  };
+
+  struct SectionInfo {
+    DeclaratorDecl *Decl;
+    SourceLocation PragmaSectionLocation;
+    int SectionFlags;
+    SectionInfo() {}
+    SectionInfo(DeclaratorDecl *Decl,
+                SourceLocation PragmaSectionLocation,
+                int SectionFlags)
+      : Decl(Decl),
+        PragmaSectionLocation(PragmaSectionLocation),
+        SectionFlags(SectionFlags) {}
+  };
+
+  llvm::StringMap<SectionInfo> SectionInfos;
+  bool UnifySection(const StringRef &SectionName, 
+                    int SectionFlags,
+                    DeclaratorDecl *TheDecl);
+  bool UnifySection(const StringRef &SectionName,
+                    int SectionFlags,
+                    SourceLocation PragmaSectionLocation);
+
+  /// \brief Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg.
+  void ActOnPragmaMSSeg(SourceLocation PragmaLocation,
+                        PragmaMsStackAction Action,
+                        llvm::StringRef StackSlotLabel,
+                        StringLiteral *SegmentName,
+                        llvm::StringRef PragmaName);
+
+  /// \brief Called on well formed \#pragma section().
+  void ActOnPragmaMSSection(SourceLocation PragmaLocation,
+                            int SectionFlags, StringLiteral *SegmentName);
+
+  /// \brief Called on well-formed \#pragma init_seg().
+  void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
+                            StringLiteral *SegmentName);
+
+  /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
+  void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
+
+  /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'.
+  void ActOnPragmaUnused(const Token &Identifier,
+                         Scope *curScope,
+                         SourceLocation PragmaLoc);
+
+  /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... .
+  void ActOnPragmaVisibility(const IdentifierInfo* VisType,
+                             SourceLocation PragmaLoc);
+
+  NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
+                                 SourceLocation Loc);
+  void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
+
+  /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident.
+  void ActOnPragmaWeakID(IdentifierInfo* WeakName,
+                         SourceLocation PragmaLoc,
+                         SourceLocation WeakNameLoc);
+
+  /// ActOnPragmaRedefineExtname - Called on well formed
+  /// \#pragma redefine_extname oldname newname.
+  void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName,
+                                  IdentifierInfo* AliasName,
+                                  SourceLocation PragmaLoc,
+                                  SourceLocation WeakNameLoc,
+                                  SourceLocation AliasNameLoc);
+
+  /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident.
+  void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
+                            IdentifierInfo* AliasName,
+                            SourceLocation PragmaLoc,
+                            SourceLocation WeakNameLoc,
+                            SourceLocation AliasNameLoc);
+
+  /// ActOnPragmaFPContract - Called on well formed
+  /// \#pragma {STDC,OPENCL} FP_CONTRACT
+  void ActOnPragmaFPContract(tok::OnOffSwitch OOS);
+
+  /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
+  /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
+  void AddAlignmentAttributesForRecord(RecordDecl *RD);
+
+  /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record.
+  void AddMsStructLayoutForRecord(RecordDecl *RD);
+
+  /// FreePackedContext - Deallocate and null out PackContext.
+  void FreePackedContext();
+
+  /// PushNamespaceVisibilityAttr - Note that we've entered a
+  /// namespace with a visibility attribute.
+  void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
+                                   SourceLocation Loc);
+
+  /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used,
+  /// add an appropriate visibility attribute.
+  void AddPushedVisibilityAttribute(Decl *RD);
+
+  /// PopPragmaVisibility - Pop the top element of the visibility stack; used
+  /// for '\#pragma GCC visibility' and visibility attributes on namespaces.
+  void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc);
+
+  /// FreeVisContext - Deallocate and null out VisContext.
+  void FreeVisContext();
+
+  /// AddCFAuditedAttribute - Check whether we're currently within
+  /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding
+  /// the appropriate attribute.
+  void AddCFAuditedAttribute(Decl *D);
+
+  /// \brief Called on well formed \#pragma clang optimize.
+  void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
+
+  /// \brief Get the location for the currently active "\#pragma clang optimize
+  /// off". If this location is invalid, then the state of the pragma is "on".
+  SourceLocation getOptimizeOffPragmaLocation() const {
+    return OptimizeOffPragmaLocation;
+  }
+
+  /// \brief Only called on function definitions; if there is a pragma in scope
+  /// with the effect of a range-based optnone, consider marking the function
+  /// with attribute optnone.
+  void AddRangeBasedOptnone(FunctionDecl *FD);
+
+  /// \brief Adds the 'optnone' attribute to the function declaration if there
+  /// are no conflicts; Loc represents the location causing the 'optnone'
+  /// attribute to be added (usually because of a pragma).
+  void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
+
+  /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
+  void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
+                      unsigned SpellingListIndex, bool IsPackExpansion);
+  void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
+                      unsigned SpellingListIndex, bool IsPackExpansion);
+
+  // OpenMP directives and clauses.
+private:
+  void *VarDataSharingAttributesStack;
+  /// \brief Initialization of data-sharing attributes stack.
+  void InitDataSharingAttributesStack();
+  void DestroyDataSharingAttributesStack();
+  ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
+                                                   OpenMPClauseKind CKind);
+public:
+  ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
+                                                    Expr *Op);
+  /// \brief Called on start of new data sharing attribute block.
+  void StartOpenMPDSABlock(OpenMPDirectiveKind K,
+                           const DeclarationNameInfo &DirName, Scope *CurScope,
+                           SourceLocation Loc);
+  /// \brief Called on end of data sharing attribute block.
+  void EndOpenMPDSABlock(Stmt *CurDirective);
+
+  // OpenMP directives and clauses.
+  /// \brief Called on correct id-expression from the '#pragma omp
+  /// threadprivate'.
+  ExprResult ActOnOpenMPIdExpression(Scope *CurScope,
+                                     CXXScopeSpec &ScopeSpec,
+                                     const DeclarationNameInfo &Id);
+  /// \brief Called on well-formed '#pragma omp threadprivate'.
+  DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
+                                     SourceLocation Loc,
+                                     ArrayRef<Expr *> VarList);
+  /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
+  OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
+                                     SourceLocation Loc,
+                                     ArrayRef<Expr *> VarList);
+
+  /// \brief Initialization of captured region for OpenMP region.
+  void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
+  StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                            const DeclarationNameInfo &DirName,
+                                            ArrayRef<OMPClause *> Clauses,
+                                            Stmt *AStmt,
+                                            SourceLocation StartLoc,
+                                            SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp parallel' after parsing
+  /// of the  associated statement.
+  StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
+                                          Stmt *AStmt,
+                                          SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp simd' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPSimdDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp for' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp sections' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp section' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp single' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+                                        Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp critical' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
+  /// of the  associated statement.
+  StmtResult ActOnOpenMPParallelForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp parallel sections' after
+  /// parsing of the  associated statement.
+  StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                                  Stmt *AStmt,
+                                                  SourceLocation StartLoc,
+                                                  SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp task' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
+                                      Stmt *AStmt, SourceLocation StartLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp taskyield'.
+  StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
+                                           SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp barrier'.
+  StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp taskwait'.
+  StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp flush'.
+  StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+                                       SourceLocation StartLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
+                                         Expr *Expr,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed 'if' clause.
+  OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc);
+  /// \brief Called on well-formed 'final' clause.
+  OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc);
+  /// \brief Called on well-formed 'num_threads' clause.
+  OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed 'safelen' clause.
+  OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'collapse' clause.
+  OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
+                                     unsigned Argument,
+                                     SourceLocation ArgumentLoc,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'default' clause.
+  OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
+                                      SourceLocation KindLoc,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'proc_bind' clause.
+  OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
+                                       SourceLocation KindLoc,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+                                                unsigned Argument, Expr *Expr,
+                                                SourceLocation StartLoc,
+                                                SourceLocation LParenLoc,
+                                                SourceLocation ArgumentLoc,
+                                                SourceLocation CommaLoc,
+                                                SourceLocation EndLoc);
+  /// \brief Called on well-formed 'schedule' clause.
+  OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind,
+                                       Expr *ChunkSize, SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation KindLoc,
+                                       SourceLocation CommaLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc,
+                               SourceLocation EndLoc);
+  /// \brief Called on well-formed 'ordered' clause.
+  OMPClause *ActOnOpenMPOrderedClause(SourceLocation StartLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'nowait' clause.
+  OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'untied' clause.
+  OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'mergeable' clause.
+  OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+
+  OMPClause *
+  ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,
+                           Expr *TailExpr, SourceLocation StartLoc,
+                           SourceLocation LParenLoc, SourceLocation ColonLoc,
+                           SourceLocation EndLoc,
+                           CXXScopeSpec &ReductionIdScopeSpec,
+                           const DeclarationNameInfo &ReductionId);
+  /// \brief Called on well-formed 'private' clause.
+  OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'firstprivate' clause.
+  OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
+                                           SourceLocation StartLoc,
+                                           SourceLocation LParenLoc,
+                                           SourceLocation EndLoc);
+  /// \brief Called on well-formed 'lastprivate' clause.
+  OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed 'shared' clause.
+  OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'reduction' clause.
+  OMPClause *
+  ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+                             SourceLocation LParenLoc, SourceLocation ColonLoc,
+                             SourceLocation EndLoc,
+                             CXXScopeSpec &ReductionIdScopeSpec,
+                             const DeclarationNameInfo &ReductionId);
+  /// \brief Called on well-formed 'linear' clause.
+  OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
+                                     Expr *Step,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation ColonLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'aligned' clause.
+  OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
+                                      Expr *Alignment,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation ColonLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'copyin' clause.
+  OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'copyprivate' clause.
+  OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed 'flush' pseudo clause.
+  OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+                                    SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc);
+
+  /// \brief The kind of conversion being performed.
+  enum CheckedConversionKind {
+    /// \brief An implicit conversion.
+    CCK_ImplicitConversion,
+    /// \brief A C-style cast.
+    CCK_CStyleCast,
+    /// \brief A functional-style cast.
+    CCK_FunctionalCast,
+    /// \brief A cast other than a C-style cast.
+    CCK_OtherCast
+  };
+
+  /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
+  /// cast.  If there is already an implicit cast, merge into the existing one.
+  /// If isLvalue, the result of the cast is an lvalue.
+  ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
+                               ExprValueKind VK = VK_RValue,
+                               const CXXCastPath *BasePath = nullptr,
+                               CheckedConversionKind CCK
+                                  = CCK_ImplicitConversion);
+
+  /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
+  /// to the conversion from scalar type ScalarTy to the Boolean type.
+  static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy);
+
+  /// IgnoredValueConversions - Given that an expression's result is
+  /// syntactically ignored, perform any conversions that are
+  /// required.
+  ExprResult IgnoredValueConversions(Expr *E);
+
+  // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
+  // functions and arrays to their respective pointers (C99 6.3.2.1).
+  ExprResult UsualUnaryConversions(Expr *E);
+
+  /// CallExprUnaryConversions - a special case of an unary conversion
+  /// performed on a function designator of a call expression.
+  ExprResult CallExprUnaryConversions(Expr *E);
+
+  // DefaultFunctionArrayConversion - converts functions and arrays
+  // to their respective pointers (C99 6.3.2.1).
+  ExprResult DefaultFunctionArrayConversion(Expr *E);
+
+  // DefaultFunctionArrayLvalueConversion - converts functions and
+  // arrays to their respective pointers and performs the
+  // lvalue-to-rvalue conversion.
+  ExprResult DefaultFunctionArrayLvalueConversion(Expr *E);
+
+  // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on
+  // the operand.  This is DefaultFunctionArrayLvalueConversion,
+  // except that it assumes the operand isn't of function or array
+  // type.
+  ExprResult DefaultLvalueConversion(Expr *E);
+
+  // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+  // do not have a prototype. Integer promotions are performed on each
+  // argument, and arguments that have type float are promoted to double.
+  ExprResult DefaultArgumentPromotion(Expr *E);
+
+  // Used for emitting the right warning by DefaultVariadicArgumentPromotion
+  enum VariadicCallType {
+    VariadicFunction,
+    VariadicBlock,
+    VariadicMethod,
+    VariadicConstructor,
+    VariadicDoesNotApply
+  };
+
+  VariadicCallType getVariadicCallType(FunctionDecl *FDecl,
+                                       const FunctionProtoType *Proto,
+                                       Expr *Fn);
+
+  // Used for determining in which context a type is allowed to be passed to a
+  // vararg function.
+  enum VarArgKind {
+    VAK_Valid,
+    VAK_ValidInCXX11,
+    VAK_Undefined,
+    VAK_Invalid
+  };
+
+  // Determines which VarArgKind fits an expression.
+  VarArgKind isValidVarArgType(const QualType &Ty);
+
+  /// Check to see if the given expression is a valid argument to a variadic
+  /// function, issuing a diagnostic if not.
+  void checkVariadicArgument(const Expr *E, VariadicCallType CT);
+
+  /// Check to see if a given expression could have '.c_str()' called on it.
+  bool hasCStrMethod(const Expr *E);
+
+  /// GatherArgumentsForCall - Collector argument expressions for various
+  /// form of call prototypes.
+  bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
+                              const FunctionProtoType *Proto,
+                              unsigned FirstParam, ArrayRef<Expr *> Args,
+                              SmallVectorImpl<Expr *> &AllArgs,
+                              VariadicCallType CallType = VariadicDoesNotApply,
+                              bool AllowExplicit = false,
+                              bool IsListInitialization = false);
+
+  // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
+  // will create a runtime trap if the resulting type is not a POD type.
+  ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
+                                              FunctionDecl *FDecl);
+
+  // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
+  // operands and then handles various conversions that are common to binary
+  // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
+  // routine returns the first non-arithmetic type found. The client is
+  // responsible for emitting appropriate error diagnostics.
+  QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
+                                      bool IsCompAssign = false);
+
+  /// AssignConvertType - All of the 'assignment' semantic checks return this
+  /// enum to indicate whether the assignment was allowed.  These checks are
+  /// done for simple assignments, as well as initialization, return from
+  /// function, argument passing, etc.  The query is phrased in terms of a
+  /// source and destination type.
+  enum AssignConvertType {
+    /// Compatible - the types are compatible according to the standard.
+    Compatible,
+
+    /// PointerToInt - The assignment converts a pointer to an int, which we
+    /// accept as an extension.
+    PointerToInt,
+
+    /// IntToPointer - The assignment converts an int to a pointer, which we
+    /// accept as an extension.
+    IntToPointer,
+
+    /// FunctionVoidPointer - The assignment is between a function pointer and
+    /// void*, which the standard doesn't allow, but we accept as an extension.
+    FunctionVoidPointer,
+
+    /// IncompatiblePointer - The assignment is between two pointers types that
+    /// are not compatible, but we accept them as an extension.
+    IncompatiblePointer,
+
+    /// IncompatiblePointer - The assignment is between two pointers types which
+    /// point to integers which have a different sign, but are otherwise
+    /// identical. This is a subset of the above, but broken out because it's by
+    /// far the most common case of incompatible pointers.
+    IncompatiblePointerSign,
+
+    /// CompatiblePointerDiscardsQualifiers - The assignment discards
+    /// c/v/r qualifiers, which we accept as an extension.
+    CompatiblePointerDiscardsQualifiers,
+
+    /// IncompatiblePointerDiscardsQualifiers - The assignment
+    /// discards qualifiers that we don't permit to be discarded,
+    /// like address spaces.
+    IncompatiblePointerDiscardsQualifiers,
+
+    /// IncompatibleNestedPointerQualifiers - The assignment is between two
+    /// nested pointer types, and the qualifiers other than the first two
+    /// levels differ e.g. char ** -> const char **, but we accept them as an
+    /// extension.
+    IncompatibleNestedPointerQualifiers,
+
+    /// IncompatibleVectors - The assignment is between two vector types that
+    /// have the same size, which we accept as an extension.
+    IncompatibleVectors,
+
+    /// IntToBlockPointer - The assignment converts an int to a block
+    /// pointer. We disallow this.
+    IntToBlockPointer,
+
+    /// IncompatibleBlockPointer - The assignment is between two block
+    /// pointers types that are not compatible.
+    IncompatibleBlockPointer,
+
+    /// IncompatibleObjCQualifiedId - The assignment is between a qualified
+    /// id type and something else (that is incompatible with it). For example,
+    /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
+    IncompatibleObjCQualifiedId,
+
+    /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an
+    /// object with __weak qualifier.
+    IncompatibleObjCWeakRef,
+
+    /// Incompatible - We reject this conversion outright, it is invalid to
+    /// represent it in the AST.
+    Incompatible
+  };
+
+  /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
+  /// assignment conversion type specified by ConvTy.  This returns true if the
+  /// conversion was invalid or false if the conversion was accepted.
+  bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
+                                SourceLocation Loc,
+                                QualType DstType, QualType SrcType,
+                                Expr *SrcExpr, AssignmentAction Action,
+                                bool *Complained = nullptr);
+
+  /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
+  /// integer not in the range of enum values.
+  void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
+                              Expr *SrcExpr);
+
+  /// CheckAssignmentConstraints - Perform type checking for assignment,
+  /// argument passing, variable initialization, and function return values.
+  /// C99 6.5.16.
+  AssignConvertType CheckAssignmentConstraints(SourceLocation Loc,
+                                               QualType LHSType,
+                                               QualType RHSType);
+
+  /// Check assignment constraints and prepare for a conversion of the
+  /// RHS to the LHS type.
+  AssignConvertType CheckAssignmentConstraints(QualType LHSType,
+                                               ExprResult &RHS,
+                                               CastKind &Kind);
+
+  // CheckSingleAssignmentConstraints - Currently used by
+  // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
+  // this routine performs the default function/array converions.
+  AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType,
+                                                     ExprResult &RHS,
+                                                     bool Diagnose = true,
+                                                     bool DiagnoseCFAudited = false);
+
+  // \brief If the lhs type is a transparent union, check whether we
+  // can initialize the transparent union with the given expression.
+  AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType,
+                                                             ExprResult &RHS);
+
+  bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
+
+  bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
+
+  ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+                                       AssignmentAction Action,
+                                       bool AllowExplicit = false);
+  ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+                                       AssignmentAction Action,
+                                       bool AllowExplicit,
+                                       ImplicitConversionSequence& ICS);
+  ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+                                       const ImplicitConversionSequence& ICS,
+                                       AssignmentAction Action,
+                                       CheckedConversionKind CCK
+                                          = CCK_ImplicitConversion);
+  ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
+                                       const StandardConversionSequence& SCS,
+                                       AssignmentAction Action,
+                                       CheckedConversionKind CCK);
+
+  /// the following "Check" methods will return a valid/converted QualType
+  /// or a null QualType (indicating an error diagnostic was issued).
+
+  /// type checking binary operators (subroutines of CreateBuiltinBinOp).
+  QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS,
+                           ExprResult &RHS);
+  QualType CheckPointerToMemberOperands( // C++ 5.5
+    ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK,
+    SourceLocation OpLoc, bool isIndirect);
+  QualType CheckMultiplyDivideOperands( // C99 6.5.5
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign,
+    bool IsDivide);
+  QualType CheckRemainderOperands( // C99 6.5.5
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
+    bool IsCompAssign = false);
+  QualType CheckAdditionOperands( // C99 6.5.6
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
+    QualType* CompLHSTy = nullptr);
+  QualType CheckSubtractionOperands( // C99 6.5.6
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
+    QualType* CompLHSTy = nullptr);
+  QualType CheckShiftOperands( // C99 6.5.7
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
+    bool IsCompAssign = false);
+  QualType CheckCompareOperands( // C99 6.5.8/9
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned OpaqueOpc,
+                                bool isRelational);
+  QualType CheckBitwiseOperands( // C99 6.5.[10...12]
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
+    bool IsCompAssign = false);
+  QualType CheckLogicalOperands( // C99 6.5.[13,14]
+    ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc);
+  // CheckAssignmentOperands is used for both simple and compound assignment.
+  // For simple assignment, pass both expressions and a null converted type.
+  // For compound assignment, pass both expressions and the converted type.
+  QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
+    Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType);
+
+  ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc,
+                                     UnaryOperatorKind Opcode, Expr *Op);
+  ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc,
+                                         BinaryOperatorKind Opcode,
+                                         Expr *LHS, Expr *RHS);
+  ExprResult checkPseudoObjectRValue(Expr *E);
+  Expr *recreateSyntacticForm(PseudoObjectExpr *E);
+
+  QualType CheckConditionalOperands( // C99 6.5.15
+    ExprResult &Cond, ExprResult &LHS, ExprResult &RHS,
+    ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc);
+  QualType CXXCheckConditionalOperands( // C++ 5.16
+    ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
+    ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
+  QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
+                                    bool *NonStandardCompositeType = nullptr);
+  QualType FindCompositePointerType(SourceLocation Loc,
+                                    ExprResult &E1, ExprResult &E2,
+                                    bool *NonStandardCompositeType = nullptr) {
+    Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
+    QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
+                                                  NonStandardCompositeType);
+    E1 = E1Tmp;
+    E2 = E2Tmp;
+    return Composite;
+  }
+
+  QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
+                                        SourceLocation QuestionLoc);
+
+  bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
+                                  SourceLocation QuestionLoc);
+
+  void DiagnoseAlwaysNonNullPointer(Expr *E,
+                                    Expr::NullPointerConstantKind NullType,
+                                    bool IsEqual, SourceRange Range);
+
+  /// type checking for vector binary operators.
+  QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
+                               SourceLocation Loc, bool IsCompAssign);
+  QualType GetSignedVectorType(QualType V);
+  QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
+                                      SourceLocation Loc, bool isRelational);
+  QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
+                                      SourceLocation Loc);
+
+  bool isLaxVectorConversion(QualType srcType, QualType destType);
+
+  /// type checking declaration initializers (C99 6.7.8)
+  bool CheckForConstantInitializer(Expr *e, QualType t);
+
+  // type checking C++ declaration initializers (C++ [dcl.init]).
+
+  /// ReferenceCompareResult - Expresses the result of comparing two
+  /// types (cv1 T1 and cv2 T2) to determine their compatibility for the
+  /// purposes of initialization by reference (C++ [dcl.init.ref]p4).
+  enum ReferenceCompareResult {
+    /// Ref_Incompatible - The two types are incompatible, so direct
+    /// reference binding is not possible.
+    Ref_Incompatible = 0,
+    /// Ref_Related - The two types are reference-related, which means
+    /// that their unqualified forms (T1 and T2) are either the same
+    /// or T1 is a base class of T2.
+    Ref_Related,
+    /// Ref_Compatible_With_Added_Qualification - The two types are
+    /// reference-compatible with added qualification, meaning that
+    /// they are reference-compatible and the qualifiers on T1 (cv1)
+    /// are greater than the qualifiers on T2 (cv2).
+    Ref_Compatible_With_Added_Qualification,
+    /// Ref_Compatible - The two types are reference-compatible and
+    /// have equivalent qualifiers (cv1 == cv2).
+    Ref_Compatible
+  };
+
+  ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc,
+                                                      QualType T1, QualType T2,
+                                                      bool &DerivedToBase,
+                                                      bool &ObjCConversion,
+                                                bool &ObjCLifetimeConversion);
+
+  ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
+                                 Expr *CastExpr, CastKind &CastKind,
+                                 ExprValueKind &VK, CXXCastPath &Path);
+
+  /// \brief Force an expression with unknown-type to an expression of the
+  /// given type.
+  ExprResult forceUnknownAnyToType(Expr *E, QualType ToType);
+
+  /// \brief Type-check an expression that's being passed to an
+  /// __unknown_anytype parameter.
+  ExprResult checkUnknownAnyArg(SourceLocation callLoc,
+                                Expr *result, QualType &paramType);
+
+  // CheckVectorCast - check type constraints for vectors.
+  // Since vectors are an extension, there are no C standard reference for this.
+  // We allow casting between vectors and integer datatypes of the same size.
+  // returns true if the cast is invalid
+  bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
+                       CastKind &Kind);
+
+  // CheckExtVectorCast - check type constraints for extended vectors.
+  // Since vectors are an extension, there are no C standard reference for this.
+  // We allow casting between vectors and integer datatypes of the same size,
+  // or vectors and the element type of that vector.
+  // returns the cast expr
+  ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr,
+                                CastKind &Kind);
+
+  ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
+                                        SourceLocation LParenLoc,
+                                        Expr *CastExpr,
+                                        SourceLocation RParenLoc);
+
+  enum ARCConversionResult { ACR_okay, ACR_unbridged };
+
+  /// \brief Checks for invalid conversions and casts between
+  /// retainable pointers and other pointer kinds.
+  ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
+                                             QualType castType, Expr *&op,
+                                             CheckedConversionKind CCK,
+                                             bool DiagnoseCFAudited = false,
+                                             BinaryOperatorKind Opc = BO_PtrMemD
+                                             );
+
+  Expr *stripARCUnbridgedCast(Expr *e);
+  void diagnoseARCUnbridgedCast(Expr *e);
+
+  bool CheckObjCARCUnavailableWeakConversion(QualType castType,
+                                             QualType ExprType);
+
+  /// checkRetainCycles - Check whether an Objective-C message send
+  /// might create an obvious retain cycle.
+  void checkRetainCycles(ObjCMessageExpr *msg);
+  void checkRetainCycles(Expr *receiver, Expr *argument);
+  void checkRetainCycles(VarDecl *Var, Expr *Init);
+
+  /// checkUnsafeAssigns - Check whether +1 expr is being assigned
+  /// to weak/__unsafe_unretained type.
+  bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS);
+
+  /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned
+  /// to weak/__unsafe_unretained expression.
+  void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS);
+
+  /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
+  /// \param Method - May be null.
+  /// \param [out] ReturnType - The return type of the send.
+  /// \return true iff there were any incompatible types.
+  bool CheckMessageArgumentTypes(QualType ReceiverType,
+                                 MultiExprArg Args, Selector Sel,
+                                 ArrayRef<SourceLocation> SelectorLocs,
+                                 ObjCMethodDecl *Method, bool isClassMessage,
+                                 bool isSuperMessage,
+                                 SourceLocation lbrac, SourceLocation rbrac,
+                                 QualType &ReturnType, ExprValueKind &VK);
+
+  /// \brief Determine the result of a message send expression based on
+  /// the type of the receiver, the method expected to receive the message,
+  /// and the form of the message send.
+  QualType getMessageSendResultType(QualType ReceiverType,
+                                    ObjCMethodDecl *Method,
+                                    bool isClassMessage, bool isSuperMessage);
+
+  /// \brief If the given expression involves a message send to a method
+  /// with a related result type, emit a note describing what happened.
+  void EmitRelatedResultTypeNote(const Expr *E);
+
+  /// \brief Given that we had incompatible pointer types in a return
+  /// statement, check whether we're in a method with a related result
+  /// type, and if so, emit a note describing what happened.
+  void EmitRelatedResultTypeNoteForReturn(QualType destType);
+
+  /// CheckBooleanCondition - Diagnose problems involving the use of
+  /// the given expression as a boolean condition (e.g. in an if
+  /// statement).  Also performs the standard function and array
+  /// decays, possibly changing the input variable.
+  ///
+  /// \param Loc - A location associated with the condition, e.g. the
+  /// 'if' keyword.
+  /// \return true iff there were any errors
+  ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);
+
+  ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                   Expr *SubExpr);
+
+  /// DiagnoseAssignmentAsCondition - Given that an expression is
+  /// being used as a boolean condition, warn if it's an assignment.
+  void DiagnoseAssignmentAsCondition(Expr *E);
+
+  /// \brief Redundant parentheses over an equality comparison can indicate
+  /// that the user intended an assignment used as condition.
+  void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE);
+
+  /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
+  ExprResult CheckCXXBooleanCondition(Expr *CondExpr);
+
+  /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
+  /// the specified width and sign.  If an overflow occurs, detect it and emit
+  /// the specified diagnostic.
+  void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
+                                          unsigned NewWidth, bool NewSign,
+                                          SourceLocation Loc, unsigned DiagID);
+
+  /// Checks that the Objective-C declaration is declared in the global scope.
+  /// Emits an error and marks the declaration as invalid if it's not declared
+  /// in the global scope.
+  bool CheckObjCDeclScope(Decl *D);
+
+  /// \brief Abstract base class used for diagnosing integer constant
+  /// expression violations.
+  class VerifyICEDiagnoser {
+  public:
+    bool Suppress;
+
+    VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { }
+
+    virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0;
+    virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR);
+    virtual ~VerifyICEDiagnoser() { }
+  };
+
+  /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE,
+  /// and reports the appropriate diagnostics. Returns false on success.
+  /// Can optionally return the value of the expression.
+  ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+                                             VerifyICEDiagnoser &Diagnoser,
+                                             bool AllowFold = true);
+  ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+                                             unsigned DiagID,
+                                             bool AllowFold = true);
+  ExprResult VerifyIntegerConstantExpression(Expr *E,
+                                             llvm::APSInt *Result = nullptr);
+
+  /// VerifyBitField - verifies that a bit field expression is an ICE and has
+  /// the correct width, and that the field type is valid.
+  /// Returns false on success.
+  /// Can optionally return whether the bit-field is of width 0
+  ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+                            QualType FieldTy, bool IsMsStruct,
+                            Expr *BitWidth, bool *ZeroWidth = nullptr);
+
+  enum CUDAFunctionTarget {
+    CFT_Device,
+    CFT_Global,
+    CFT_Host,
+    CFT_HostDevice
+  };
+
+  CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D);
+
+  bool CheckCUDATarget(CUDAFunctionTarget CallerTarget,
+                       CUDAFunctionTarget CalleeTarget);
+
+  bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) {
+    return CheckCUDATarget(IdentifyCUDATarget(Caller),
+                           IdentifyCUDATarget(Callee));
+  }
+
+  /// \name Code completion
+  //@{
+  /// \brief Describes the context in which code completion occurs.
+  enum ParserCompletionContext {
+    /// \brief Code completion occurs at top-level or namespace context.
+    PCC_Namespace,
+    /// \brief Code completion occurs within a class, struct, or union.
+    PCC_Class,
+    /// \brief Code completion occurs within an Objective-C interface, protocol,
+    /// or category.
+    PCC_ObjCInterface,
+    /// \brief Code completion occurs within an Objective-C implementation or
+    /// category implementation
+    PCC_ObjCImplementation,
+    /// \brief Code completion occurs within the list of instance variables
+    /// in an Objective-C interface, protocol, category, or implementation.
+    PCC_ObjCInstanceVariableList,
+    /// \brief Code completion occurs following one or more template
+    /// headers.
+    PCC_Template,
+    /// \brief Code completion occurs following one or more template
+    /// headers within a class.
+    PCC_MemberTemplate,
+    /// \brief Code completion occurs within an expression.
+    PCC_Expression,
+    /// \brief Code completion occurs within a statement, which may
+    /// also be an expression or a declaration.
+    PCC_Statement,
+    /// \brief Code completion occurs at the beginning of the
+    /// initialization statement (or expression) in a for loop.
+    PCC_ForInit,
+    /// \brief Code completion occurs within the condition of an if,
+    /// while, switch, or for statement.
+    PCC_Condition,
+    /// \brief Code completion occurs within the body of a function on a
+    /// recovery path, where we do not have a specific handle on our position
+    /// in the grammar.
+    PCC_RecoveryInFunction,
+    /// \brief Code completion occurs where only a type is permitted.
+    PCC_Type,
+    /// \brief Code completion occurs in a parenthesized expression, which
+    /// might also be a type cast.
+    PCC_ParenthesizedExpression,
+    /// \brief Code completion occurs within a sequence of declaration
+    /// specifiers within a function, method, or block.
+    PCC_LocalDeclarationSpecifiers
+  };
+
+  void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
+  void CodeCompleteOrdinaryName(Scope *S,
+                                ParserCompletionContext CompletionContext);
+  void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
+                            bool AllowNonIdentifiers,
+                            bool AllowNestedNameSpecifiers);
+
+  struct CodeCompleteExpressionData;
+  void CodeCompleteExpression(Scope *S,
+                              const CodeCompleteExpressionData &Data);
+  void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
+                                       SourceLocation OpLoc,
+                                       bool IsArrow);
+  void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
+  void CodeCompleteTag(Scope *S, unsigned TagSpec);
+  void CodeCompleteTypeQualifiers(DeclSpec &DS);
+  void CodeCompleteCase(Scope *S);
+  void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
+  void CodeCompleteInitializer(Scope *S, Decl *D);
+  void CodeCompleteReturn(Scope *S);
+  void CodeCompleteAfterIf(Scope *S);
+  void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS);
+
+  void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
+                               bool EnteringContext);
+  void CodeCompleteUsing(Scope *S);
+  void CodeCompleteUsingDirective(Scope *S);
+  void CodeCompleteNamespaceDecl(Scope *S);
+  void CodeCompleteNamespaceAliasDecl(Scope *S);
+  void CodeCompleteOperatorName(Scope *S);
+  void CodeCompleteConstructorInitializer(
+                                Decl *Constructor,
+                                ArrayRef<CXXCtorInitializer *> Initializers);
+
+  void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro,
+                                    bool AfterAmpersand);
+
+  void CodeCompleteObjCAtDirective(Scope *S);
+  void CodeCompleteObjCAtVisibility(Scope *S);
+  void CodeCompleteObjCAtStatement(Scope *S);
+  void CodeCompleteObjCAtExpression(Scope *S);
+  void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
+  void CodeCompleteObjCPropertyGetter(Scope *S);
+  void CodeCompleteObjCPropertySetter(Scope *S);
+  void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS,
+                                   bool IsParameter);
+  void CodeCompleteObjCMessageReceiver(Scope *S);
+  void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+                                    ArrayRef<IdentifierInfo *> SelIdents,
+                                    bool AtArgumentExpression);
+  void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+                                    ArrayRef<IdentifierInfo *> SelIdents,
+                                    bool AtArgumentExpression,
+                                    bool IsSuper = false);
+  void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
+                                       ArrayRef<IdentifierInfo *> SelIdents,
+                                       bool AtArgumentExpression,
+                                       ObjCInterfaceDecl *Super = nullptr);
+  void CodeCompleteObjCForCollection(Scope *S,
+                                     DeclGroupPtrTy IterationVar);
+  void CodeCompleteObjCSelector(Scope *S,
+                                ArrayRef<IdentifierInfo *> SelIdents);
+  void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
+                                          unsigned NumProtocols);
+  void CodeCompleteObjCProtocolDecl(Scope *S);
+  void CodeCompleteObjCInterfaceDecl(Scope *S);
+  void CodeCompleteObjCSuperclass(Scope *S,
+                                  IdentifierInfo *ClassName,
+                                  SourceLocation ClassNameLoc);
+  void CodeCompleteObjCImplementationDecl(Scope *S);
+  void CodeCompleteObjCInterfaceCategory(Scope *S,
+                                         IdentifierInfo *ClassName,
+                                         SourceLocation ClassNameLoc);
+  void CodeCompleteObjCImplementationCategory(Scope *S,
+                                              IdentifierInfo *ClassName,
+                                              SourceLocation ClassNameLoc);
+  void CodeCompleteObjCPropertyDefinition(Scope *S);
+  void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+                                              IdentifierInfo *PropertyName);
+  void CodeCompleteObjCMethodDecl(Scope *S,
+                                  bool IsInstanceMethod,
+                                  ParsedType ReturnType);
+  void CodeCompleteObjCMethodDeclSelector(Scope *S,
+                                          bool IsInstanceMethod,
+                                          bool AtParameterName,
+                                          ParsedType ReturnType,
+                                          ArrayRef<IdentifierInfo *> SelIdents);
+  void CodeCompletePreprocessorDirective(bool InConditional);
+  void CodeCompleteInPreprocessorConditionalExclusion(Scope *S);
+  void CodeCompletePreprocessorMacroName(bool IsDefinition);
+  void CodeCompletePreprocessorExpression();
+  void CodeCompletePreprocessorMacroArgument(Scope *S,
+                                             IdentifierInfo *Macro,
+                                             MacroInfo *MacroInfo,
+                                             unsigned Argument);
+  void CodeCompleteNaturalLanguage();
+  void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
+                                   CodeCompletionTUInfo &CCTUInfo,
+                  SmallVectorImpl<CodeCompletionResult> &Results);
+  //@}
+
+  //===--------------------------------------------------------------------===//
+  // Extra semantic analysis beyond the C type system
+
+public:
+  SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
+                                                unsigned ByteNo) const;
+
+private:
+  void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
+                        const ArraySubscriptExpr *ASE=nullptr,
+                        bool AllowOnePastEnd=true, bool IndexNegated=false);
+  void CheckArrayAccess(const Expr *E);
+  // Used to grab the relevant information from a FormatAttr and a
+  // FunctionDeclaration.
+  struct FormatStringInfo {
+    unsigned FormatIdx;
+    unsigned FirstDataArg;
+    bool HasVAListArg;
+  };
+
+  bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember,
+                           FormatStringInfo *FSI);
+  bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
+                         const FunctionProtoType *Proto);
+  bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
+                           ArrayRef<const Expr *> Args);
+  bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
+                        const FunctionProtoType *Proto);
+  bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto);
+  void CheckConstructorCall(FunctionDecl *FDecl,
+                            ArrayRef<const Expr *> Args,
+                            const FunctionProtoType *Proto,
+                            SourceLocation Loc);
+
+  void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
+                 unsigned NumParams, bool IsMemberFunction, SourceLocation Loc,
+                 SourceRange Range, VariadicCallType CallType);
+
+  bool CheckObjCString(Expr *Arg);
+
+  ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+
+  bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
+                                    unsigned MaxWidth);
+  bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+
+  bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+
+  bool SemaBuiltinVAStart(CallExpr *TheCall);
+  bool SemaBuiltinVAStartARM(CallExpr *Call);
+  bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
+  bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
+
+public:
+  // Used by C++ template instantiation.
+  ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
+  ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
+                                   SourceLocation BuiltinLoc,
+                                   SourceLocation RParenLoc);
+
+private:
+  bool SemaBuiltinPrefetch(CallExpr *TheCall);
+  bool SemaBuiltinAssume(CallExpr *TheCall);
+  bool SemaBuiltinLongjmp(CallExpr *TheCall);
+  ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
+  ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
+                                     AtomicExpr::AtomicOp Op);
+  bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
+                              llvm::APSInt &Result);
+  bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
+                                   int Low, int High);
+
+public:
+  enum FormatStringType {
+    FST_Scanf,
+    FST_Printf,
+    FST_NSString,
+    FST_Strftime,
+    FST_Strfmon,
+    FST_Kprintf,
+    FST_Unknown
+  };
+  static FormatStringType GetFormatStringType(const FormatAttr *Format);
+
+  void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
+                         ArrayRef<const Expr *> Args, bool HasVAListArg,
+                         unsigned format_idx, unsigned firstDataArg,
+                         FormatStringType Type, bool inFunctionCall,
+                         VariadicCallType CallType,
+                         llvm::SmallBitVector &CheckedVarArgs);
+
+private:
+  bool CheckFormatArguments(const FormatAttr *Format,
+                            ArrayRef<const Expr *> Args,
+                            bool IsCXXMember,
+                            VariadicCallType CallType,
+                            SourceLocation Loc, SourceRange Range,
+                            llvm::SmallBitVector &CheckedVarArgs);
+  bool CheckFormatArguments(ArrayRef<const Expr *> Args,
+                            bool HasVAListArg, unsigned format_idx,
+                            unsigned firstDataArg, FormatStringType Type,
+                            VariadicCallType CallType,
+                            SourceLocation Loc, SourceRange range,
+                            llvm::SmallBitVector &CheckedVarArgs);
+
+  void CheckAbsoluteValueFunction(const CallExpr *Call,
+                                  const FunctionDecl *FDecl,
+                                  IdentifierInfo *FnInfo);
+
+  void CheckMemaccessArguments(const CallExpr *Call,
+                               unsigned BId,
+                               IdentifierInfo *FnName);
+
+  void CheckStrlcpycatArguments(const CallExpr *Call,
+                                IdentifierInfo *FnName);
+
+  void CheckStrncatArguments(const CallExpr *Call,
+                             IdentifierInfo *FnName);
+
+  void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
+                          SourceLocation ReturnLoc,
+                          bool isObjCMethod = false,
+                          const AttrVec *Attrs = nullptr,
+                          const FunctionDecl *FD = nullptr);
+
+  void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
+  void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
+  void CheckForIntOverflow(Expr *E);
+  void CheckUnsequencedOperations(Expr *E);
+
+  /// \brief Perform semantic checks on a completed expression. This will either
+  /// be a full-expression or a default argument expression.
+  void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(),
+                          bool IsConstexpr = false);
+
+  void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
+                                   Expr *Init);
+
+  /// \brief Check if the given expression contains 'break' or 'continue'
+  /// statement that produces control flow different from GCC.
+  void CheckBreakContinueBinding(Expr *E);
+
+public:
+  /// \brief Register a magic integral constant to be used as a type tag.
+  void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
+                                  uint64_t MagicValue, QualType Type,
+                                  bool LayoutCompatible, bool MustBeNull);
+
+  struct TypeTagData {
+    TypeTagData() {}
+
+    TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) :
+        Type(Type), LayoutCompatible(LayoutCompatible),
+        MustBeNull(MustBeNull)
+    {}
+
+    QualType Type;
+
+    /// If true, \c Type should be compared with other expression's types for
+    /// layout-compatibility.
+    unsigned LayoutCompatible : 1;
+    unsigned MustBeNull : 1;
+  };
+
+  /// A pair of ArgumentKind identifier and magic value.  This uniquely
+  /// identifies the magic value.
+  typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue;
+
+private:
+  /// \brief A map from magic value to type information.
+  std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>>
+      TypeTagForDatatypeMagicValues;
+
+  /// \brief Peform checks on a call of a function with argument_with_type_tag
+  /// or pointer_with_type_tag attributes.
+  void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
+                                const Expr * const *ExprArgs);
+
+  /// \brief The parser's current scope.
+  ///
+  /// The parser maintains this state here.
+  Scope *CurScope;
+
+  mutable IdentifierInfo *Ident_super;
+  mutable IdentifierInfo *Ident___float128;
+
+protected:
+  friend class Parser;
+  friend class InitializationSequence;
+  friend class ASTReader;
+  friend class ASTWriter;
+
+public:
+  /// \brief Retrieve the parser's current scope.
+  ///
+  /// This routine must only be used when it is certain that semantic analysis
+  /// and the parser are in precisely the same context, which is not the case
+  /// when, e.g., we are performing any kind of template instantiation.
+  /// Therefore, the only safe places to use this scope are in the parser
+  /// itself and in routines directly invoked from the parser and *never* from
+  /// template substitution or instantiation.
+  Scope *getCurScope() const { return CurScope; }
+
+  void incrementMSLocalManglingNumber() const {
+    return CurScope->incrementMSLocalManglingNumber();
+  }
+
+  IdentifierInfo *getSuperIdentifier() const;
+  IdentifierInfo *getFloat128Identifier() const;
+
+  Decl *getObjCDeclContext() const;
+
+  DeclContext *getCurLexicalContext() const {
+    return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
+  }
+
+  AvailabilityResult getCurContextAvailability() const;
+  
+  const DeclContext *getCurObjCLexicalContext() const {
+    const DeclContext *DC = getCurLexicalContext();
+    // A category implicitly has the attribute of the interface.
+    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC))
+      DC = CatD->getClassInterface();
+    return DC;
+  }
+};
+
+/// \brief RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {
+  Sema &Actions;
+
+public:
+  EnterExpressionEvaluationContext(Sema &Actions,
+                                   Sema::ExpressionEvaluationContext NewContext,
+                                   Decl *LambdaContextDecl = nullptr,
+                                   bool IsDecltype = false)
+    : Actions(Actions) {
+    Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
+                                            IsDecltype);
+  }
+  EnterExpressionEvaluationContext(Sema &Actions,
+                                   Sema::ExpressionEvaluationContext NewContext,
+                                   Sema::ReuseLambdaContextDecl_t,
+                                   bool IsDecltype = false)
+    : Actions(Actions) {
+    Actions.PushExpressionEvaluationContext(NewContext, 
+                                            Sema::ReuseLambdaContextDecl,
+                                            IsDecltype);
+  }
+
+  ~EnterExpressionEvaluationContext() {
+    Actions.PopExpressionEvaluationContext();
+  }
+};
+
+DeductionFailureInfo
+MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK,
+                         sema::TemplateDeductionInfo &Info);
+
+/// \brief Contains a late templated function.
+/// Will be parsed at the end of the translation unit, used by Sema & Parser.
+struct LateParsedTemplate {
+  CachedTokens Toks;
+  /// \brief The template function declaration to be late parsed.
+  Decl *D;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
new file mode 100644
index 0000000..676646a
--- /dev/null
+++ b/include/clang/Sema/SemaConsumer.h
@@ -0,0 +1,48 @@
+//===--- SemaConsumer.h - Abstract interface for AST semantics --*- 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 SemaConsumer class, a subclass of
+//  ASTConsumer that is used by AST clients that also require
+//  additional semantic analysis.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_SEMACONSUMER_H
+#define LLVM_CLANG_SEMA_SEMACONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+
+namespace clang {
+  class Sema;
+
+  /// \brief An abstract interface that should be implemented by
+  /// clients that read ASTs and then require further semantic
+  /// analysis of the entities in those ASTs.
+  class SemaConsumer : public ASTConsumer {
+    virtual void anchor();
+  public:
+    SemaConsumer() {
+      ASTConsumer::SemaConsumer = true;
+    }
+
+    /// \brief Initialize the semantic consumer with the Sema instance
+    /// being used to perform semantic analysis on the abstract syntax
+    /// tree.
+    virtual void InitializeSema(Sema &S) {}
+
+    /// \brief Inform the semantic consumer that Sema is no longer available.
+    virtual void ForgetSema() {}
+
+    // isa/cast/dyn_cast support
+    static bool classof(const ASTConsumer *Consumer) {
+      return Consumer->SemaConsumer;
+    }
+  };
+}
+
+#endif
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
new file mode 100644
index 0000000..fdf9593
--- /dev/null
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTICSEMA_H
+#define LLVM_CLANG_DIAGNOSTICSEMA_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define SEMASTART
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_SEMA_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h
new file mode 100644
index 0000000..fffca67
--- /dev/null
+++ b/include/clang/Sema/SemaFixItUtils.h
@@ -0,0 +1,91 @@
+//===--- SemaFixItUtils.h - Sema FixIts -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines helper classes for generation of Sema FixItHints.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SEMA_FIXITUTILS_H
+#define LLVM_CLANG_SEMA_FIXITUTILS_H
+
+#include "clang/AST/Expr.h"
+
+namespace clang {
+
+enum OverloadFixItKind {
+  OFIK_Undefined = 0,
+  OFIK_Dereference,
+  OFIK_TakeAddress,
+  OFIK_RemoveDereference,
+  OFIK_RemoveTakeAddress
+};
+
+class Sema;
+
+/// The class facilities generation and storage of conversion FixIts. Hints for
+/// new conversions are added using TryToFixConversion method. The default type
+/// conversion checker can be reset.
+struct ConversionFixItGenerator {
+  /// Performs a simple check to see if From type can be converted to To type.
+  static bool compareTypesSimple(CanQualType From,
+                                 CanQualType To,
+                                 Sema &S,
+                                 SourceLocation Loc,
+                                 ExprValueKind FromVK);
+
+  /// The list of Hints generated so far.
+  std::vector<FixItHint> Hints;
+
+  /// The number of Conversions fixed. This can be different from the size
+  /// of the Hints vector since we allow multiple FixIts per conversion.
+  unsigned NumConversionsFixed;
+
+  /// The type of fix applied. If multiple conversions are fixed, corresponds
+  /// to the kid of the very first conversion.
+  OverloadFixItKind Kind;
+
+  typedef bool (*TypeComparisonFuncTy) (const CanQualType FromTy,
+                                        const CanQualType ToTy,
+                                        Sema &S,
+                                        SourceLocation Loc,
+                                        ExprValueKind FromVK);
+  /// The type comparison function used to decide if expression FromExpr of
+  /// type FromTy can be converted to ToTy. For example, one could check if
+  /// an implicit conversion exists. Returns true if comparison exists.
+  TypeComparisonFuncTy CompareTypes;
+
+  ConversionFixItGenerator(TypeComparisonFuncTy Foo): NumConversionsFixed(0),
+                                                      Kind(OFIK_Undefined),
+                                                      CompareTypes(Foo) {}
+
+  ConversionFixItGenerator(): NumConversionsFixed(0),
+                              Kind(OFIK_Undefined),
+                              CompareTypes(compareTypesSimple) {}
+
+  /// Resets the default conversion checker method.
+  void setConversionChecker(TypeComparisonFuncTy Foo) {
+    CompareTypes = Foo;
+  }
+
+  /// If possible, generates and stores a fix for the given conversion.
+  bool tryToFixConversion(const Expr *FromExpr,
+                          const QualType FromQTy, const QualType ToQTy,
+                          Sema &S);
+
+  void clear() {
+    Hints.clear();
+    NumConversionsFixed = 0;
+  }
+
+  bool isNull() {
+    return (NumConversionsFixed == 0);
+  }
+};
+
+} // endof namespace clang
+#endif // LLVM_CLANG_SEMA_FIXITUTILS_H
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
new file mode 100644
index 0000000..9199b0f
--- /dev/null
+++ b/include/clang/Sema/SemaInternal.h
@@ -0,0 +1,91 @@
+//===--- SemaInternal.h - Internal Sema Interfaces --------------*- 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 common API and #includes for the internal
+// implementation of Sema.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+#define LLVM_CLANG_SEMA_SEMA_INTERNAL_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+namespace clang {
+
+inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
+  return PartialDiagnostic(DiagID, Context.getDiagAllocator());
+}
+
+inline bool
+FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+  return FTI.NumParams == 1 && !FTI.isVariadic &&
+         FTI.Params[0].Ident == nullptr && FTI.Params[0].Param &&
+         cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
+}
+
+inline bool
+FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+  // Assume FTI is well-formed.
+  return FTI.NumParams && !FTIHasSingleVoidParameter(FTI);
+}
+
+// This requires the variable to be non-dependent and the initializer
+// to not be value dependent.
+inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
+  const VarDecl *DefVD = nullptr;
+  return !isa<ParmVarDecl>(Var) &&
+    Var->isUsableInConstantExpressions(Context) &&
+    Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); 
+}
+
+// Directly mark a variable odr-used. Given a choice, prefer to use 
+// MarkVariableReferenced since it does additional checks and then 
+// calls MarkVarDeclODRUsed.
+// If the variable must be captured:
+//  - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
+//  - else capture it in the DeclContext that maps to the 
+//    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.  
+inline void MarkVarDeclODRUsed(VarDecl *Var,
+    SourceLocation Loc, Sema &SemaRef,
+    const unsigned *const FunctionScopeIndexToStopAt) {
+  // Keep track of used but undefined variables.
+  // FIXME: We shouldn't suppress this warning for static data members.
+  if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
+    !Var->isExternallyVisible() &&
+    !(Var->isStaticDataMember() && Var->hasInit())) {
+      SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
+      if (old.isInvalid()) old = Loc;
+  }
+  QualType CaptureType, DeclRefType;
+  SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, 
+    /*EllipsisLoc*/ SourceLocation(),
+    /*BuildAndDiagnose*/ true, 
+    CaptureType, DeclRefType, 
+    FunctionScopeIndexToStopAt);
+
+  Var->markUsed(SemaRef.Context);
+}
+
+/// Return a DLL attribute from the declaration.
+inline InheritableAttr *getDLLAttr(Decl *D) {
+  assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
+         "A declaration cannot be both dllimport and dllexport.");
+  if (auto *Import = D->getAttr<DLLImportAttr>())
+    return Import;
+  if (auto *Export = D->getAttr<DLLExportAttr>())
+    return Export;
+  return nullptr;
+}
+
+}
+
+#endif
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
new file mode 100644
index 0000000..f636750
--- /dev/null
+++ b/include/clang/Sema/SemaLambda.h
@@ -0,0 +1,36 @@
+//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides some common utility functions for processing
+/// Lambdas.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LAMBDA_H
+#define LLVM_CLANG_SEMA_LAMBDA_H
+#include "clang/AST/ASTLambda.h"
+#include "clang/Sema/ScopeInfo.h"
+namespace clang {
+ 
+
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-capable' for 
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-capable lambda's LambdaScopeInfo. 
+/// See Implementation for more detailed comments. 
+
+Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
+    ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
+    VarDecl *VarToCapture, Sema &S);
+
+} // clang
+
+#endif // LLVM_CLANG_SEMA_LAMBDA_H
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
new file mode 100644
index 0000000..c08a5df
--- /dev/null
+++ b/include/clang/Sema/Template.h
@@ -0,0 +1,511 @@
+//===------- SemaTemplate.h - C++ Templates ---------------------*- 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 types used in the semantic analysis of C++ templates.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
+#define LLVM_CLANG_SEMA_TEMPLATE_H
+
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <utility>
+
+namespace clang {
+  /// \brief Data structure that captures multiple levels of template argument
+  /// lists for use in template instantiation.
+  ///
+  /// Multiple levels of template arguments occur when instantiating the 
+  /// definitions of member templates. For example:
+  ///
+  /// \code
+  /// template<typename T>
+  /// struct X {
+  ///   template<T Value>
+  ///   struct Y {
+  ///     void f();
+  ///   };
+  /// };
+  /// \endcode
+  ///
+  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
+  /// list will contain a template argument list (int) at depth 0 and a
+  /// template argument list (17) at depth 1.
+  class MultiLevelTemplateArgumentList {
+    /// \brief The template argument list at a certain template depth 
+    typedef ArrayRef<TemplateArgument> ArgList;
+
+    /// \brief The template argument lists, stored from the innermost template
+    /// argument list (first) to the outermost template argument list (last).
+    SmallVector<ArgList, 4> TemplateArgumentLists;
+    
+  public:
+    /// \brief Construct an empty set of template argument lists.
+    MultiLevelTemplateArgumentList() { }
+    
+    /// \brief Construct a single-level template argument list.
+    explicit 
+    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
+      addOuterTemplateArguments(&TemplateArgs);
+    }
+    
+    /// \brief Determine the number of levels in this template argument
+    /// list.
+    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
+    
+    /// \brief Retrieve the template argument at a given depth and index.
+    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
+      assert(Depth < TemplateArgumentLists.size());
+      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
+      return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
+    }
+    
+    /// \brief Determine whether there is a non-NULL template argument at the
+    /// given depth and index.
+    ///
+    /// There must exist a template argument list at the given depth.
+    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
+      assert(Depth < TemplateArgumentLists.size());
+      
+      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
+        return false;
+      
+      return !(*this)(Depth, Index).isNull();
+    }
+    
+    /// \brief Clear out a specific template argument.
+    void setArgument(unsigned Depth, unsigned Index,
+                     TemplateArgument Arg) {
+      assert(Depth < TemplateArgumentLists.size());
+      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
+      const_cast<TemplateArgument&>(
+                TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
+        = Arg;
+    }
+    
+    /// \brief Add a new outermost level to the multi-level template argument 
+    /// list.
+    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
+      addOuterTemplateArguments(ArgList(TemplateArgs->data(),
+                                        TemplateArgs->size()));
+    }
+
+    /// \brief Add a new outmost level to the multi-level template argument
+    /// list.
+    void addOuterTemplateArguments(ArgList Args) {
+      TemplateArgumentLists.push_back(Args);
+    }
+
+    /// \brief Retrieve the innermost template argument list.
+    const ArgList &getInnermost() const { 
+      return TemplateArgumentLists.front(); 
+    }
+  };
+  
+  /// \brief The context in which partial ordering of function templates occurs.
+  enum TPOC {
+    /// \brief Partial ordering of function templates for a function call.
+    TPOC_Call,
+    /// \brief Partial ordering of function templates for a call to a 
+    /// conversion function.
+    TPOC_Conversion,
+    /// \brief Partial ordering of function templates in other contexts, e.g.,
+    /// taking the address of a function template or matching a function 
+    /// template specialization to a function template.
+    TPOC_Other
+  };
+
+  // This is lame but unavoidable in a world without forward
+  // declarations of enums.  The alternatives are to either pollute
+  // Sema.h (by including this file) or sacrifice type safety (by
+  // making Sema.h declare things as enums).
+  class TemplatePartialOrderingContext {
+    TPOC Value;
+  public:
+    TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
+    operator TPOC() const { return Value; }
+  };
+
+  /// \brief Captures a template argument whose value has been deduced
+  /// via c++ template argument deduction.
+  class DeducedTemplateArgument : public TemplateArgument {
+    /// \brief For a non-type template argument, whether the value was
+    /// deduced from an array bound.
+    bool DeducedFromArrayBound;
+
+  public:
+    DeducedTemplateArgument()
+      : TemplateArgument(), DeducedFromArrayBound(false) { }
+
+    DeducedTemplateArgument(const TemplateArgument &Arg,
+                            bool DeducedFromArrayBound = false)
+      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief Construct an integral non-type template argument that
+    /// has been deduced, possibly from an array bound.
+    DeducedTemplateArgument(ASTContext &Ctx,
+                            const llvm::APSInt &Value,
+                            QualType ValueType,
+                            bool DeducedFromArrayBound)
+      : TemplateArgument(Ctx, Value, ValueType),
+        DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief For a non-type template argument, determine whether the
+    /// template argument was deduced from an array bound.
+    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
+
+    /// \brief Specify whether the given non-type template argument
+    /// was deduced from an array bound.
+    void setDeducedFromArrayBound(bool Deduced) {
+      DeducedFromArrayBound = Deduced;
+    }
+  };
+
+  /// \brief A stack-allocated class that identifies which local
+  /// variable declaration instantiations are present in this scope.
+  ///
+  /// A new instance of this class type will be created whenever we
+  /// instantiate a new function declaration, which will have its own
+  /// set of parameter declarations.
+  class LocalInstantiationScope {
+  public:
+    /// \brief A set of declarations.
+    typedef SmallVector<Decl *, 4> DeclArgumentPack;
+    
+  private:
+    /// \brief Reference to the semantic analysis that is performing
+    /// this template instantiation.
+    Sema &SemaRef;
+
+    typedef llvm::SmallDenseMap<
+        const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>
+    LocalDeclsMap;
+
+    /// \brief A mapping from local declarations that occur
+    /// within a template to their instantiations.
+    ///
+    /// This mapping is used during instantiation to keep track of,
+    /// e.g., function parameter and variable declarations. For example,
+    /// given:
+    ///
+    /// \code
+    ///   template<typename T> T add(T x, T y) { return x + y; }
+    /// \endcode
+    ///
+    /// when we instantiate add<int>, we will introduce a mapping from
+    /// the ParmVarDecl for 'x' that occurs in the template to the
+    /// instantiated ParmVarDecl for 'x'.
+    ///
+    /// For a parameter pack, the local instantiation scope may contain a
+    /// set of instantiated parameters. This is stored as a DeclArgumentPack
+    /// pointer.
+    LocalDeclsMap LocalDecls;
+
+    /// \brief The set of argument packs we've allocated.
+    SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
+    
+    /// \brief The outer scope, which contains local variable
+    /// definitions from some other instantiation (that may not be
+    /// relevant to this particular scope).
+    LocalInstantiationScope *Outer;
+
+    /// \brief Whether we have already exited this scope.
+    bool Exited;
+
+    /// \brief Whether to combine this scope with the outer scope, such that
+    /// lookup will search our outer scope.
+    bool CombineWithOuterScope;
+    
+    /// \brief If non-NULL, the template parameter pack that has been
+    /// partially substituted per C++0x [temp.arg.explicit]p9.
+    NamedDecl *PartiallySubstitutedPack;
+    
+    /// \brief If \c PartiallySubstitutedPack is non-null, the set of
+    /// explicitly-specified template arguments in that pack.
+    const TemplateArgument *ArgsInPartiallySubstitutedPack;    
+    
+    /// \brief If \c PartiallySubstitutedPack, the number of 
+    /// explicitly-specified template arguments in 
+    /// ArgsInPartiallySubstitutedPack.
+    unsigned NumArgsInPartiallySubstitutedPack;
+
+    // This class is non-copyable
+    LocalInstantiationScope(
+      const LocalInstantiationScope &) LLVM_DELETED_FUNCTION;
+    void operator=(const LocalInstantiationScope &) LLVM_DELETED_FUNCTION;
+
+  public:
+    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
+      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
+        Exited(false), CombineWithOuterScope(CombineWithOuterScope),
+        PartiallySubstitutedPack(nullptr)
+    {
+      SemaRef.CurrentInstantiationScope = this;
+    }
+
+    ~LocalInstantiationScope() {
+      Exit();
+    }
+    
+    const Sema &getSema() const { return SemaRef; }
+
+    /// \brief Exit this local instantiation scope early.
+    void Exit() {
+      if (Exited)
+        return;
+      
+      for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
+        delete ArgumentPacks[I];
+        
+      SemaRef.CurrentInstantiationScope = Outer;
+      Exited = true;
+    }
+
+    /// \brief Clone this scope, and all outer scopes, down to the given
+    /// outermost scope.
+    LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
+      if (this == Outermost) return this;
+      LocalInstantiationScope *newScope =
+        new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
+
+      newScope->Outer = nullptr;
+      if (Outer)
+        newScope->Outer = Outer->cloneScopes(Outermost);
+
+      newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
+      newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
+      newScope->NumArgsInPartiallySubstitutedPack =
+        NumArgsInPartiallySubstitutedPack;
+
+      for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
+           I != E; ++I) {
+        const Decl *D = I->first;
+        llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
+          newScope->LocalDecls[D];
+        if (I->second.is<Decl *>()) {
+          Stored = I->second.get<Decl *>();
+        } else {
+          DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
+          DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
+          Stored = NewPack;
+          newScope->ArgumentPacks.push_back(NewPack);
+        }
+      }
+      return newScope;
+    }
+
+    /// \brief deletes the given scope, and all otuer scopes, down to the
+    /// given outermost scope.
+    static void deleteScopes(LocalInstantiationScope *Scope,
+                             LocalInstantiationScope *Outermost) {
+      while (Scope && Scope != Outermost) {
+        LocalInstantiationScope *Out = Scope->Outer;
+        delete Scope;
+        Scope = Out;
+      }
+    }
+
+    /// \brief Find the instantiation of the declaration D within the current
+    /// instantiation scope.
+    ///
+    /// \param D The declaration whose instantiation we are searching for.
+    ///
+    /// \returns A pointer to the declaration or argument pack of declarations
+    /// to which the declaration \c D is instantiated, if found. Otherwise,
+    /// returns NULL.
+    llvm::PointerUnion<Decl *, DeclArgumentPack *> *
+    findInstantiationOf(const Decl *D);
+
+    void InstantiatedLocal(const Decl *D, Decl *Inst);
+    void InstantiatedLocalPackArg(const Decl *D, Decl *Inst);
+    void MakeInstantiatedLocalArgPack(const Decl *D);
+    
+    /// \brief Note that the given parameter pack has been partially substituted
+    /// via explicit specification of template arguments 
+    /// (C++0x [temp.arg.explicit]p9).
+    ///
+    /// \param Pack The parameter pack, which will always be a template
+    /// parameter pack.
+    ///
+    /// \param ExplicitArgs The explicitly-specified template arguments provided
+    /// for this parameter pack.
+    ///
+    /// \param NumExplicitArgs The number of explicitly-specified template
+    /// arguments provided for this parameter pack.
+    void SetPartiallySubstitutedPack(NamedDecl *Pack, 
+                                     const TemplateArgument *ExplicitArgs,
+                                     unsigned NumExplicitArgs);
+
+    /// \brief Reset the partially-substituted pack when it is no longer of
+    /// interest.
+    void ResetPartiallySubstitutedPack() {
+      assert(PartiallySubstitutedPack && "No partially-substituted pack");
+      PartiallySubstitutedPack = nullptr;
+      ArgsInPartiallySubstitutedPack = nullptr;
+      NumArgsInPartiallySubstitutedPack = 0;
+    }
+
+    /// \brief Retrieve the partially-substitued template parameter pack.
+    ///
+    /// If there is no partially-substituted parameter pack, returns NULL.
+    NamedDecl *
+    getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
+                                unsigned *NumExplicitArgs = nullptr) const;
+  };
+
+  class TemplateDeclInstantiator
+    : public DeclVisitor<TemplateDeclInstantiator, Decl *> 
+  {
+    Sema &SemaRef;
+    Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
+    DeclContext *Owner;
+    const MultiLevelTemplateArgumentList &TemplateArgs;
+    Sema::LateInstantiatedAttrVec* LateAttrs;
+    LocalInstantiationScope *StartingScope;
+
+    /// \brief A list of out-of-line class template partial
+    /// specializations that will need to be instantiated after the
+    /// enclosing class's instantiation is complete.
+    SmallVector<std::pair<ClassTemplateDecl *,
+                                ClassTemplatePartialSpecializationDecl *>, 4>
+      OutOfLinePartialSpecs;
+
+    /// \brief A list of out-of-line variable template partial
+    /// specializations that will need to be instantiated after the
+    /// enclosing variable's instantiation is complete.
+    /// FIXME: Verify that this is needed.
+    SmallVector<
+        std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
+    OutOfLineVarPartialSpecs;
+
+  public:
+    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
+                             const MultiLevelTemplateArgumentList &TemplateArgs)
+      : SemaRef(SemaRef),
+        SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
+        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
+        StartingScope(nullptr) {}
+
+// Define all the decl visitors using DeclNodes.inc
+#define DECL(DERIVED, BASE) \
+    Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
+#define ABSTRACT_DECL(DECL)
+
+// Decls which never appear inside a class or function.
+#define OBJCCONTAINER(DERIVED, BASE)
+#define FILESCOPEASM(DERIVED, BASE)
+#define IMPORT(DERIVED, BASE)
+#define LINKAGESPEC(DERIVED, BASE)
+#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
+#define OBJCMETHOD(DERIVED, BASE)
+#define OBJCIVAR(DERIVED, BASE)
+#define OBJCPROPERTY(DERIVED, BASE)
+#define OBJCPROPERTYIMPL(DERIVED, BASE)
+#define EMPTY(DERIVED, BASE)
+
+// Decls which use special-case instantiation code.
+#define BLOCK(DERIVED, BASE)
+#define CAPTURED(DERIVED, BASE)
+#define IMPLICITPARAM(DERIVED, BASE)
+
+#include "clang/AST/DeclNodes.inc"
+
+    // A few supplemental visitor functions.
+    Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
+                             TemplateParameterList *TemplateParams,
+                             bool IsClassScopeSpecialization = false);
+    Decl *VisitFunctionDecl(FunctionDecl *D,
+                            TemplateParameterList *TemplateParams);
+    Decl *VisitDecl(Decl *D);
+    Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate);
+
+    // Enable late instantiation of attributes.  Late instantiated attributes
+    // will be stored in LA.
+    void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
+      LateAttrs = LA;
+      StartingScope = SemaRef.CurrentInstantiationScope;
+    }
+
+    // Disable late instantiation of attributes.
+    void disableLateAttributeInstantiation() {
+      LateAttrs = nullptr;
+      StartingScope = nullptr;
+    }
+
+    LocalInstantiationScope *getStartingScope() const { return StartingScope; }
+
+    typedef 
+      SmallVectorImpl<std::pair<ClassTemplateDecl *,
+                                     ClassTemplatePartialSpecializationDecl *> >
+        ::iterator
+      delayed_partial_spec_iterator;
+
+    typedef SmallVectorImpl<std::pair<
+        VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator
+    delayed_var_partial_spec_iterator;
+
+    /// \brief Return an iterator to the beginning of the set of
+    /// "delayed" partial specializations, which must be passed to
+    /// InstantiateClassTemplatePartialSpecialization once the class
+    /// definition has been completed.
+    delayed_partial_spec_iterator delayed_partial_spec_begin() {
+      return OutOfLinePartialSpecs.begin();
+    }
+
+    delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
+      return OutOfLineVarPartialSpecs.begin();
+    }
+
+    /// \brief Return an iterator to the end of the set of
+    /// "delayed" partial specializations, which must be passed to
+    /// InstantiateClassTemplatePartialSpecialization once the class
+    /// definition has been completed.
+    delayed_partial_spec_iterator delayed_partial_spec_end() {
+      return OutOfLinePartialSpecs.end();
+    }
+
+    delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
+      return OutOfLineVarPartialSpecs.end();
+    }
+
+    // Helper functions for instantiating methods.
+    TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
+                             SmallVectorImpl<ParmVarDecl *> &Params);
+    bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
+    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
+
+    TemplateParameterList *
+      SubstTemplateParams(TemplateParameterList *List);
+
+    bool SubstQualifier(const DeclaratorDecl *OldDecl,
+                        DeclaratorDecl *NewDecl);
+    bool SubstQualifier(const TagDecl *OldDecl,
+                        TagDecl *NewDecl);
+
+    Decl *VisitVarTemplateSpecializationDecl(
+        VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
+        const TemplateArgumentListInfo &TemplateArgsInfo,
+        ArrayRef<TemplateArgument> Converted);
+
+    Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
+    ClassTemplatePartialSpecializationDecl *
+    InstantiateClassTemplatePartialSpecialization(
+                                              ClassTemplateDecl *ClassTemplate,
+                           ClassTemplatePartialSpecializationDecl *PartialSpec);
+    VarTemplatePartialSpecializationDecl *
+    InstantiateVarTemplatePartialSpecialization(
+        VarTemplateDecl *VarTemplate,
+        VarTemplatePartialSpecializationDecl *PartialSpec);
+    void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
+  };  
+}
+
+#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
new file mode 100644
index 0000000..2c2c36d
--- /dev/null
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -0,0 +1,293 @@
+//===- TemplateDeduction.h - C++ template argument deduction ----*- 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 types used with Sema's template argument deduction
+// routines.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
+#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
+
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+struct DeducedPack;
+class TemplateArgumentList;
+class Sema;
+
+namespace sema {
+
+/// \brief Provides information about an attempted template argument
+/// deduction, whose success or failure was described by a
+/// TemplateDeductionResult value.
+class TemplateDeductionInfo {
+  /// \brief The deduced template argument list.
+  ///
+  TemplateArgumentList *Deduced;
+
+  /// \brief The source location at which template argument
+  /// deduction is occurring.
+  SourceLocation Loc;
+
+  /// \brief Have we suppressed an error during deduction?
+  bool HasSFINAEDiagnostic;
+
+  /// \brief Warnings (and follow-on notes) that were suppressed due to
+  /// SFINAE while performing template argument deduction.
+  SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
+
+  TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
+  void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
+
+public:
+  TemplateDeductionInfo(SourceLocation Loc)
+    : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
+      Expression(nullptr) {}
+
+  /// \brief Returns the location at which template argument is
+  /// occurring.
+  SourceLocation getLocation() const {
+    return Loc;
+  }
+
+  /// \brief Take ownership of the deduced template argument list.
+  TemplateArgumentList *take() {
+    TemplateArgumentList *Result = Deduced;
+    Deduced = nullptr;
+    return Result;
+  }
+
+  /// \brief Take ownership of the SFINAE diagnostic.
+  void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
+    assert(HasSFINAEDiagnostic);
+    PD.first = SuppressedDiagnostics.front().first;
+    PD.second.swap(SuppressedDiagnostics.front().second);
+    SuppressedDiagnostics.clear();
+    HasSFINAEDiagnostic = false;
+  }
+
+  /// \brief Provide a new template argument list that contains the
+  /// results of template argument deduction.
+  void reset(TemplateArgumentList *NewDeduced) {
+    Deduced = NewDeduced;
+  }
+
+  /// \brief Is a SFINAE diagnostic available?
+  bool hasSFINAEDiagnostic() const {
+    return HasSFINAEDiagnostic;
+  }
+
+  /// \brief Set the diagnostic which caused the SFINAE failure.
+  void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
+    // Only collect the first diagnostic.
+    if (HasSFINAEDiagnostic)
+      return;
+    SuppressedDiagnostics.clear();
+    SuppressedDiagnostics.push_back(
+        std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
+    SuppressedDiagnostics.back().second.swap(PD);
+    HasSFINAEDiagnostic = true;
+  }
+
+  /// \brief Add a new diagnostic to the set of diagnostics
+  void addSuppressedDiagnostic(SourceLocation Loc,
+                               PartialDiagnostic PD) {
+    if (HasSFINAEDiagnostic)
+      return;
+    SuppressedDiagnostics.push_back(
+        std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
+    SuppressedDiagnostics.back().second.swap(PD);
+  }
+
+  /// \brief Iterator over the set of suppressed diagnostics.
+  typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
+    diag_iterator;
+
+  /// \brief Returns an iterator at the beginning of the sequence of suppressed
+  /// diagnostics.
+  diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
+
+  /// \brief Returns an iterator at the end of the sequence of suppressed
+  /// diagnostics.
+  diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
+
+  /// \brief The template parameter to which a template argument
+  /// deduction failure refers.
+  ///
+  /// Depending on the result of template argument deduction, this
+  /// template parameter may have different meanings:
+  ///
+  ///   TDK_Incomplete: this is the first template parameter whose
+  ///   corresponding template argument was not deduced.
+  ///
+  ///   TDK_Inconsistent: this is the template parameter for which
+  ///   two different template argument values were deduced.
+  TemplateParameter Param;
+
+  /// \brief The first template argument to which the template
+  /// argument deduction failure refers.
+  ///
+  /// Depending on the result of the template argument deduction,
+  /// this template argument may have different meanings:
+  ///
+  ///   TDK_Inconsistent: this argument is the first value deduced
+  ///   for the corresponding template parameter.
+  ///
+  ///   TDK_SubstitutionFailure: this argument is the template
+  ///   argument we were instantiating when we encountered an error.
+  ///
+  ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
+  ///   of the deduction, directly provided in the source code.
+  TemplateArgument FirstArg;
+
+  /// \brief The second template argument to which the template
+  /// argument deduction failure refers.
+  ///
+  ///   TDK_NonDeducedMismatch: this is the mismatching component of the
+  ///   'argument' of the deduction, from which we are deducing arguments.
+  ///
+  /// FIXME: Finish documenting this.
+  TemplateArgument SecondArg;
+
+  /// \brief The expression which caused a deduction failure.
+  ///
+  ///   TDK_FailedOverloadResolution: this argument is the reference to
+  ///   an overloaded function which could not be resolved to a specific
+  ///   function.
+  Expr *Expression;
+
+  /// \brief Information on packs that we're currently expanding.
+  ///
+  /// FIXME: This should be kept internal to SemaTemplateDeduction.
+  SmallVector<DeducedPack *, 8> PendingDeducedPacks;
+};
+
+} // end namespace sema
+
+/// A structure used to record information about a failed
+/// template argument deduction, for diagnosis.
+struct DeductionFailureInfo {
+  /// A Sema::TemplateDeductionResult.
+  unsigned Result : 8;
+
+  /// \brief Indicates whether a diagnostic is stored in Diagnostic.
+  unsigned HasDiagnostic : 1;
+
+  /// \brief Opaque pointer containing additional data about
+  /// this deduction failure.
+  void *Data;
+
+  /// \brief A diagnostic indicating why deduction failed.
+  union {
+    void *Align;
+    char Diagnostic[sizeof(PartialDiagnosticAt)];
+  };
+
+  /// \brief Retrieve the diagnostic which caused this deduction failure,
+  /// if any.
+  PartialDiagnosticAt *getSFINAEDiagnostic();
+
+  /// \brief Retrieve the template parameter this deduction failure
+  /// refers to, if any.
+  TemplateParameter getTemplateParameter();
+
+  /// \brief Retrieve the template argument list associated with this
+  /// deduction failure, if any.
+  TemplateArgumentList *getTemplateArgumentList();
+
+  /// \brief Return the first template argument this deduction failure
+  /// refers to, if any.
+  const TemplateArgument *getFirstArg();
+
+  /// \brief Return the second template argument this deduction failure
+  /// refers to, if any.
+  const TemplateArgument *getSecondArg();
+
+  /// \brief Return the expression this deduction failure refers to,
+  /// if any.
+  Expr *getExpr();
+
+  /// \brief Free any memory associated with this deduction failure.
+  void Destroy();
+};
+
+/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
+/// which keeps track of template argument deduction failure info, when
+/// handling explicit specializations (and instantiations) of templates
+/// beyond function overloading.
+/// For now, assume that the candidates are non-matching specializations.
+/// TODO: In the future, we may need to unify/generalize this with
+/// OverloadCandidate.
+struct TemplateSpecCandidate {
+  /// Specialization - The actual specialization that this candidate
+  /// represents. When NULL, this may be a built-in candidate.
+  Decl *Specialization;
+
+  /// Template argument deduction info
+  DeductionFailureInfo DeductionFailure;
+
+  void set(Decl *Spec, DeductionFailureInfo Info) {
+    Specialization = Spec;
+    DeductionFailure = Info;
+  }
+
+  /// Diagnose a template argument deduction failure.
+  void NoteDeductionFailure(Sema &S);
+};
+
+/// TemplateSpecCandidateSet - A set of generalized overload candidates,
+/// used in template specializations.
+/// TODO: In the future, we may need to unify/generalize this with
+/// OverloadCandidateSet.
+class TemplateSpecCandidateSet {
+  SmallVector<TemplateSpecCandidate, 16> Candidates;
+  SourceLocation Loc;
+
+  TemplateSpecCandidateSet(
+      const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
+  void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
+
+  void destroyCandidates();
+
+public:
+  TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
+  ~TemplateSpecCandidateSet() { destroyCandidates(); }
+
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Clear out all of the candidates.
+  /// TODO: This may be unnecessary.
+  void clear();
+
+  typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
+  iterator begin() { return Candidates.begin(); }
+  iterator end() { return Candidates.end(); }
+
+  size_t size() const { return Candidates.size(); }
+  bool empty() const { return Candidates.empty(); }
+
+  /// \brief Add a new candidate with NumConversions conversion sequence slots
+  /// to the overload set.
+  TemplateSpecCandidate &addCandidate() {
+    Candidates.push_back(TemplateSpecCandidate());
+    return Candidates.back();
+  }
+
+  void NoteCandidates(Sema &S, SourceLocation Loc);
+
+  void NoteCandidates(Sema &S, SourceLocation Loc) const {
+    const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
new file mode 100644
index 0000000..6cab59c
--- /dev/null
+++ b/include/clang/Sema/TypoCorrection.h
@@ -0,0 +1,338 @@
+//===--- TypoCorrection.h - Class for typo correction results ---*- 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 TypoCorrection class, which stores the results of
+// Sema's typo correction (Sema::CorrectTypo).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H
+#define LLVM_CLANG_SEMA_TYPOCORRECTION_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/Sema/DeclSpec.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+/// @brief Simple class containing the result of Sema::CorrectTypo
+class TypoCorrection {
+public:
+  // "Distance" for unusable corrections
+  static const unsigned InvalidDistance = ~0U;
+  // The largest distance still considered valid (larger edit distances are
+  // mapped to InvalidDistance by getEditDistance).
+  static const unsigned MaximumDistance = 10000U;
+
+  // Relative weightings of the "edit distance" components. The higher the
+  // weight, the more of a penalty to fitness the component will give (higher
+  // weights mean greater contribution to the total edit distance, with the
+  // best correction candidates having the lowest edit distance).
+  static const unsigned CharDistanceWeight = 100U;
+  static const unsigned QualifierDistanceWeight = 110U;
+  static const unsigned CallbackDistanceWeight = 150U;
+
+  TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
+                 NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
+                 unsigned QualifierDistance = 0)
+      : CorrectionName(Name), CorrectionNameSpec(NNS),
+        CharDistance(CharDistance), QualifierDistance(QualifierDistance),
+        CallbackDistance(0), ForceSpecifierReplacement(false),
+        RequiresImport(false) {
+    if (NameDecl)
+      CorrectionDecls.push_back(NameDecl);
+  }
+
+  TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
+                 unsigned CharDistance = 0)
+      : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
+        CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
+        ForceSpecifierReplacement(false), RequiresImport(false) {
+    if (Name)
+      CorrectionDecls.push_back(Name);
+  }
+
+  TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
+                 unsigned CharDistance = 0)
+      : CorrectionName(Name), CorrectionNameSpec(NNS),
+        CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
+        ForceSpecifierReplacement(false), RequiresImport(false) {}
+
+  TypoCorrection()
+      : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
+        CallbackDistance(0), ForceSpecifierReplacement(false),
+        RequiresImport(false) {}
+
+  /// \brief Gets the DeclarationName of the typo correction
+  DeclarationName getCorrection() const { return CorrectionName; }
+  IdentifierInfo* getCorrectionAsIdentifierInfo() const {
+    return CorrectionName.getAsIdentifierInfo();
+  }
+
+  /// \brief Gets the NestedNameSpecifier needed to use the typo correction
+  NestedNameSpecifier* getCorrectionSpecifier() const {
+    return CorrectionNameSpec;
+  }
+  void setCorrectionSpecifier(NestedNameSpecifier* NNS) {
+    CorrectionNameSpec = NNS;
+    ForceSpecifierReplacement = (NNS != nullptr);
+  }
+
+  void WillReplaceSpecifier(bool ForceReplacement) {
+    ForceSpecifierReplacement = ForceReplacement;
+  }
+
+  bool WillReplaceSpecifier() const {
+    return ForceSpecifierReplacement;
+  }
+
+  void setQualifierDistance(unsigned ED) {
+    QualifierDistance = ED;
+  }
+
+  void setCallbackDistance(unsigned ED) {
+    CallbackDistance = ED;
+  }
+
+  // Convert the given weighted edit distance to a roughly equivalent number of
+  // single-character edits (typically for comparison to the length of the
+  // string being edited).
+  static unsigned NormalizeEditDistance(unsigned ED) {
+    if (ED > MaximumDistance)
+      return InvalidDistance;
+    return (ED + CharDistanceWeight / 2) / CharDistanceWeight;
+  }
+
+  /// \brief Gets the "edit distance" of the typo correction from the typo.
+  /// If Normalized is true, scale the distance down by the CharDistanceWeight
+  /// to return the edit distance in terms of single-character edits.
+  unsigned getEditDistance(bool Normalized = true) const {
+    if (CharDistance > MaximumDistance || QualifierDistance > MaximumDistance ||
+        CallbackDistance > MaximumDistance)
+      return InvalidDistance;
+    unsigned ED =
+        CharDistance * CharDistanceWeight +
+        QualifierDistance * QualifierDistanceWeight +
+        CallbackDistance * CallbackDistanceWeight;
+    if (ED > MaximumDistance)
+      return InvalidDistance;
+    // Half the CharDistanceWeight is added to ED to simulate rounding since
+    // integer division truncates the value (i.e. round-to-nearest-int instead
+    // of round-to-zero).
+    return Normalized ? NormalizeEditDistance(ED) : ED;
+  }
+
+  /// \brief Gets the pointer to the declaration of the typo correction
+  NamedDecl *getCorrectionDecl() const {
+    return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr;
+  }
+  template <class DeclClass>
+  DeclClass *getCorrectionDeclAs() const {
+    return dyn_cast_or_null<DeclClass>(getCorrectionDecl());
+  }
+
+  /// \brief Clears the list of NamedDecls.
+  void ClearCorrectionDecls() {
+    CorrectionDecls.clear();
+  }
+
+  /// \brief Clears the list of NamedDecls before adding the new one.
+  void setCorrectionDecl(NamedDecl *CDecl) {
+    CorrectionDecls.clear();
+    addCorrectionDecl(CDecl);
+  }
+
+  /// \brief Clears the list of NamedDecls and adds the given set.
+  void setCorrectionDecls(ArrayRef<NamedDecl*> Decls) {
+    CorrectionDecls.clear();
+    CorrectionDecls.insert(CorrectionDecls.begin(), Decls.begin(), Decls.end());
+  }
+
+  /// \brief Add the given NamedDecl to the list of NamedDecls that are the
+  /// declarations associated with the DeclarationName of this TypoCorrection
+  void addCorrectionDecl(NamedDecl *CDecl);
+
+  std::string getAsString(const LangOptions &LO) const;
+  std::string getQuoted(const LangOptions &LO) const {
+    return "'" + getAsString(LO) + "'";
+  }
+
+  /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName
+  LLVM_EXPLICIT operator bool() const { return bool(CorrectionName); }
+
+  /// \brief Mark this TypoCorrection as being a keyword.
+  /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be
+  /// added to the list of the correction's NamedDecl pointers, NULL is added
+  /// as the only element in the list to mark this TypoCorrection as a keyword.
+  void makeKeyword() {
+    CorrectionDecls.clear();
+    CorrectionDecls.push_back(nullptr);
+    ForceSpecifierReplacement = true;
+  }
+
+  // Check if this TypoCorrection is a keyword by checking if the first
+  // item in CorrectionDecls is NULL.
+  bool isKeyword() const {
+    return !CorrectionDecls.empty() &&
+        CorrectionDecls.front() == nullptr;
+  }
+
+  // Check if this TypoCorrection is the given keyword.
+  template<std::size_t StrLen>
+  bool isKeyword(const char (&Str)[StrLen]) const {
+    return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str);
+  }
+
+  // Returns true if the correction either is a keyword or has a known decl.
+  bool isResolved() const { return !CorrectionDecls.empty(); }
+
+  bool isOverloaded() const {
+    return CorrectionDecls.size() > 1;
+  }
+
+  void setCorrectionRange(CXXScopeSpec *SS,
+                          const DeclarationNameInfo &TypoName) {
+    CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty()
+                                 ? SS->getBeginLoc()
+                                 : TypoName.getLoc());
+    CorrectionRange.setEnd(TypoName.getLoc());
+  }
+
+  SourceRange getCorrectionRange() const {
+    return CorrectionRange;
+  }
+
+  typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator;
+  decl_iterator begin() {
+    return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
+  }
+  decl_iterator end() { return CorrectionDecls.end(); }
+  typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_iterator;
+  const_decl_iterator begin() const {
+    return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin();
+  }
+  const_decl_iterator end() const { return CorrectionDecls.end(); }
+
+  /// \brief Returns whether this typo correction is correcting to a
+  /// declaration that was declared in a module that has not been imported.
+  bool requiresImport() const { return RequiresImport; }
+  void setRequiresImport(bool Req) { RequiresImport = Req; }
+
+private:
+  bool hasCorrectionDecl() const {
+    return (!isKeyword() && !CorrectionDecls.empty());
+  }
+
+  // Results.
+  DeclarationName CorrectionName;
+  NestedNameSpecifier *CorrectionNameSpec;
+  SmallVector<NamedDecl *, 1> CorrectionDecls;
+  unsigned CharDistance;
+  unsigned QualifierDistance;
+  unsigned CallbackDistance;
+  SourceRange CorrectionRange;
+  bool ForceSpecifierReplacement;
+  bool RequiresImport;
+};
+
+/// @brief Base class for callback objects used by Sema::CorrectTypo to check
+/// the validity of a potential typo correction.
+class CorrectionCandidateCallback {
+public:
+  static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
+
+  CorrectionCandidateCallback()
+      : WantTypeSpecifiers(true), WantExpressionKeywords(true),
+        WantCXXNamedCasts(true), WantRemainingKeywords(true),
+        WantObjCSuper(false), IsObjCIvarLookup(false),
+        IsAddressOfOperand(false) {}
+
+  virtual ~CorrectionCandidateCallback() {}
+
+  /// \brief Simple predicate used by the default RankCandidate to
+  /// determine whether to return an edit distance of 0 or InvalidDistance.
+  /// This can be overrided by validators that only need to determine if a
+  /// candidate is viable, without ranking potentially viable candidates.
+  /// Only ValidateCandidate or RankCandidate need to be overriden by a
+  /// callback wishing to check the viability of correction candidates.
+  /// The default predicate always returns true if the candidate is not a type
+  /// name or keyword, true for types if WantTypeSpecifiers is true, and true
+  /// for keywords if WantTypeSpecifiers, WantExpressionKeywords,
+  /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true.
+  virtual bool ValidateCandidate(const TypoCorrection &candidate);
+
+  /// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank
+  /// to a candidate (where a lower value represents a better candidate), or
+  /// returning InvalidDistance if the candidate is not at all viable. For
+  /// validation callbacks that only need to determine if a candidate is viable,
+  /// the default RankCandidate returns either 0 or InvalidDistance depending
+  /// whether ValidateCandidate returns true or false.
+  virtual unsigned RankCandidate(const TypoCorrection &candidate) {
+    return ValidateCandidate(candidate) ? 0 : InvalidDistance;
+  }
+
+  // Flags for context-dependent keywords.
+  // TODO: Expand these to apply to non-keywords or possibly remove them.
+  bool WantTypeSpecifiers;
+  bool WantExpressionKeywords;
+  bool WantCXXNamedCasts;
+  bool WantRemainingKeywords;
+  bool WantObjCSuper;
+  // Temporary hack for the one case where a CorrectTypoContext enum is used
+  // when looking up results.
+  bool IsObjCIvarLookup;
+  bool IsAddressOfOperand;
+};
+
+/// @brief Simple template class for restricting typo correction candidates
+/// to ones having a single Decl* of the given type.
+template <class C>
+class DeclFilterCCC : public CorrectionCandidateCallback {
+public:
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
+    return candidate.getCorrectionDeclAs<C>();
+  }
+};
+
+// @brief Callback class to limit the allowed keywords and to only accept typo
+// corrections that are keywords or whose decls refer to functions (or template
+// functions) that accept the given number of arguments.
+class FunctionCallFilterCCC : public CorrectionCandidateCallback {
+public:
+  FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
+                        bool HasExplicitTemplateArgs,
+                        MemberExpr *ME = nullptr);
+
+  bool ValidateCandidate(const TypoCorrection &candidate) override;
+
+ private:
+  unsigned NumArgs;
+  bool HasExplicitTemplateArgs;
+  DeclContext *CurContext;
+  MemberExpr *MemberFn;
+};
+
+// @brief Callback class that effectively disabled typo correction
+class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
+public:
+  NoTypoCorrectionCCC() {
+    WantTypeSpecifiers = false;
+    WantExpressionKeywords = false;
+    WantCXXNamedCasts = false;
+    WantRemainingKeywords = false;
+  }
+
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
+    return false;
+  }
+};
+
+}
+
+#endif
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
new file mode 100644
index 0000000..9c7212e
--- /dev/null
+++ b/include/clang/Sema/Weak.h
@@ -0,0 +1,46 @@
+//===-- UnresolvedSet.h - Unresolved sets of declarations  ------*- 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 WeakInfo class, which is used to store
+//  information about the target of a #pragma weak directive.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_WEAK_H
+#define LLVM_CLANG_SEMA_WEAK_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+/// \brief Captures information about a \#pragma weak directive.
+class WeakInfo {
+  IdentifierInfo *alias;  // alias (optional)
+  SourceLocation loc;     // for diagnostics
+  bool used;              // identifier later declared?
+public:
+  WeakInfo()
+    : alias(nullptr), loc(SourceLocation()), used(false) {}
+  WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
+    : alias(Alias), loc(Loc), used(false) {}
+  inline IdentifierInfo * getAlias() const { return alias; }
+  inline SourceLocation getLocation() const { return loc; }
+  void setUsed(bool Used=true) { used = Used; }
+  inline bool getUsed() { return used; }
+  bool operator==(WeakInfo RHS) const {
+    return alias == RHS.getAlias() && loc == RHS.getLocation();
+  }
+  bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_WEAK_H
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
new file mode 100644
index 0000000..7ae1977
--- /dev/null
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -0,0 +1,1445 @@
+//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for Clang serialized AST files.
+//
+// The enum values defined in this file should be considered permanent.  If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_PCHBITCODES_H
+#define LLVM_CLANG_FRONTEND_PCHBITCODES_H
+
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+  namespace serialization {
+    /// \brief AST file major version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST file format changes in a way that makes it
+    /// incompatible with previous versions (such that a reader
+    /// designed for the previous version could not support reading
+    /// the new version), this number should be increased.
+    ///
+    /// Version 4 of AST files also requires that the version control branch and
+    /// revision match exactly, since there is no backward compatibility of
+    /// AST files at this time.
+    const unsigned VERSION_MAJOR = 5;
+
+    /// \brief AST file minor version number supported by this version of
+    /// Clang.
+    ///
+    /// Whenever the AST format changes in a way that is still
+    /// compatible with previous versions (such that a reader designed
+    /// for the previous version could still support reading the new
+    /// version by ignoring new kinds of subblocks), this number
+    /// should be increased.
+    const unsigned VERSION_MINOR = 0;
+
+    /// \brief An ID number that refers to an identifier in an AST file.
+    /// 
+    /// The ID numbers of identifiers are consecutive (in order of discovery)
+    /// and start at 1. 0 is reserved for NULL.
+    typedef uint32_t IdentifierID;
+    
+    /// \brief An ID number that refers to a declaration in an AST file.
+    ///
+    /// The ID numbers of declarations are consecutive (in order of
+    /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. 
+    /// At the start of a chain of precompiled headers, declaration ID 1 is 
+    /// used for the translation unit declaration.
+    typedef uint32_t DeclID;
+
+    /// \brief a Decl::Kind/DeclID pair.
+    typedef std::pair<uint32_t, DeclID> KindDeclIDPair;
+
+    // FIXME: Turn these into classes so we can have some type safety when
+    // we go from local ID to global and vice-versa.
+    typedef DeclID LocalDeclID;
+    typedef DeclID GlobalDeclID;
+
+    /// \brief An ID number that refers to a type in an AST file.
+    ///
+    /// The ID of a type is partitioned into two parts: the lower
+    /// three bits are used to store the const/volatile/restrict
+    /// qualifiers (as with QualType) and the upper bits provide a
+    /// type index. The type index values are partitioned into two
+    /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type
+    /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a
+    /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are
+    /// other types that have serialized representations.
+    typedef uint32_t TypeID;
+
+    /// \brief A type index; the type ID with the qualifier bits removed.
+    class TypeIdx {
+      uint32_t Idx;
+    public:
+      TypeIdx() : Idx(0) { }
+      explicit TypeIdx(uint32_t index) : Idx(index) { }
+
+      uint32_t getIndex() const { return Idx; }
+      TypeID asTypeID(unsigned FastQuals) const {
+        if (Idx == uint32_t(-1))
+          return TypeID(-1);
+        
+        return (Idx << Qualifiers::FastWidth) | FastQuals;
+      }
+      static TypeIdx fromTypeID(TypeID ID) {
+        if (ID == TypeID(-1))
+          return TypeIdx(-1);
+        
+        return TypeIdx(ID >> Qualifiers::FastWidth);
+      }
+    };
+
+    /// A structure for putting "fast"-unqualified QualTypes into a
+    /// DenseMap.  This uses the standard pointer hash function.
+    struct UnsafeQualTypeDenseMapInfo {
+      static inline bool isEqual(QualType A, QualType B) { return A == B; }
+      static inline QualType getEmptyKey() {
+        return QualType::getFromOpaquePtr((void*) 1);
+      }
+      static inline QualType getTombstoneKey() {
+        return QualType::getFromOpaquePtr((void*) 2);
+      }
+      static inline unsigned getHashValue(QualType T) {
+        assert(!T.getLocalFastQualifiers() && 
+               "hash invalid for types with fast quals");
+        uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+        return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
+      }
+    };
+
+    /// \brief An ID number that refers to an identifier in an AST file.
+    typedef uint32_t IdentID;
+
+    /// \brief The number of predefined identifier IDs.
+    const unsigned int NUM_PREDEF_IDENT_IDS = 1;
+
+    /// \brief An ID number that refers to a macro in an AST file.
+    typedef uint32_t MacroID;
+
+    /// \brief A global ID number that refers to a macro in an AST file.
+    typedef uint32_t GlobalMacroID;
+
+    /// \brief A local to a module ID number that refers to a macro in an
+    /// AST file.
+    typedef uint32_t LocalMacroID;
+
+    /// \brief The number of predefined macro IDs.
+    const unsigned int NUM_PREDEF_MACRO_IDS = 1;
+
+    /// \brief An ID number that refers to an ObjC selector in an AST file.
+    typedef uint32_t SelectorID;
+
+    /// \brief The number of predefined selector IDs.
+    const unsigned int NUM_PREDEF_SELECTOR_IDS = 1;
+    
+    /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an 
+    /// AST file.
+    typedef uint32_t CXXBaseSpecifiersID;
+    
+    /// \brief An ID number that refers to an entity in the detailed
+    /// preprocessing record.
+    typedef uint32_t PreprocessedEntityID;
+
+    /// \brief An ID number that refers to a submodule in a module file.
+    typedef uint32_t SubmoduleID;
+    
+    /// \brief The number of predefined submodule IDs.
+    const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1;
+
+    /// \brief Source range/offset of a preprocessed entity.
+    struct PPEntityOffset {
+      /// \brief Raw source location of beginning of range.
+      unsigned Begin;
+      /// \brief Raw source location of end of range.
+      unsigned End;
+      /// \brief Offset in the AST file.
+      uint32_t BitOffset;
+
+      PPEntityOffset(SourceRange R, uint32_t BitOffset)
+        : Begin(R.getBegin().getRawEncoding()),
+          End(R.getEnd().getRawEncoding()),
+          BitOffset(BitOffset) { }
+    };
+
+    /// \brief Source range/offset of a preprocessed entity.
+    struct DeclOffset {
+      /// \brief Raw source location.
+      unsigned Loc;
+      /// \brief Offset in the AST file.
+      uint32_t BitOffset;
+
+      DeclOffset() : Loc(0), BitOffset(0) { }
+      DeclOffset(SourceLocation Loc, uint32_t BitOffset)
+        : Loc(Loc.getRawEncoding()),
+          BitOffset(BitOffset) { }
+      void setLocation(SourceLocation L) {
+        Loc = L.getRawEncoding();
+      }
+    };
+
+    /// \brief The number of predefined preprocessed entity IDs.
+    const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
+
+    /// \brief Describes the various kinds of blocks that occur within
+    /// an AST file.
+    enum BlockIDs {
+      /// \brief The AST block, which acts as a container around the
+      /// full AST block.
+      AST_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+      /// \brief The block containing information about the source
+      /// manager.
+      SOURCE_MANAGER_BLOCK_ID,
+
+      /// \brief The block containing information about the
+      /// preprocessor.
+      PREPROCESSOR_BLOCK_ID,
+
+      /// \brief The block containing the definitions of all of the
+      /// types and decls used within the AST file.
+      DECLTYPES_BLOCK_ID,
+
+      /// \brief The block containing the detailed preprocessing record.
+      PREPROCESSOR_DETAIL_BLOCK_ID,
+      
+      /// \brief The block containing the submodule structure.
+      SUBMODULE_BLOCK_ID,
+
+      /// \brief The block containing comments.
+      COMMENTS_BLOCK_ID,
+
+      /// \brief The control block, which contains all of the
+      /// information that needs to be validated prior to committing
+      /// to loading the AST file.
+      CONTROL_BLOCK_ID,
+
+      /// \brief The block of input files, which were used as inputs
+      /// to create this AST file.
+      ///
+      /// This block is part of the control block.
+      INPUT_FILES_BLOCK_ID
+    };
+
+    /// \brief Record types that occur within the control block.
+    enum ControlRecordTypes {
+      /// \brief AST file metadata, including the AST file version number
+      /// and information about the compiler used to build this AST file.
+      METADATA = 1,
+
+      /// \brief Record code for the list of other AST files imported by
+      /// this AST file.
+      IMPORTS = 2,
+
+      /// \brief Record code for the language options table.
+      ///
+      /// The record with this code contains the contents of the
+      /// LangOptions structure. We serialize the entire contents of
+      /// the structure, and let the reader decide which options are
+      /// actually important to check.
+      LANGUAGE_OPTIONS = 3,
+
+      /// \brief Record code for the target options table.
+      TARGET_OPTIONS = 4,
+
+      /// \brief Record code for the original file that was used to
+      /// generate the AST file, including both its file ID and its
+      /// name.
+      ORIGINAL_FILE = 5,
+      
+      /// \brief The directory that the PCH was originally created in.
+      ORIGINAL_PCH_DIR = 6,
+
+      /// \brief Record code for file ID of the file or buffer that was used to
+      /// generate the AST file.
+      ORIGINAL_FILE_ID = 7,
+
+      /// \brief Offsets into the input-files block where input files
+      /// reside.
+      INPUT_FILE_OFFSETS = 8,
+
+      /// \brief Record code for the diagnostic options table.
+      DIAGNOSTIC_OPTIONS = 9,
+
+      /// \brief Record code for the filesystem options table.
+      FILE_SYSTEM_OPTIONS = 10,
+
+      /// \brief Record code for the headers search options table.
+      HEADER_SEARCH_OPTIONS = 11,
+
+      /// \brief Record code for the preprocessor options table.
+      PREPROCESSOR_OPTIONS = 12,
+
+      /// \brief Record code for the module name.
+      MODULE_NAME = 13,
+
+      /// \brief Record code for the module map file that was used to build this
+      /// AST file.
+      MODULE_MAP_FILE = 14
+    };
+
+    /// \brief Record types that occur within the input-files block
+    /// inside the control block.
+    enum InputFileRecordTypes {
+      /// \brief An input file.
+      INPUT_FILE = 1
+    };
+
+    /// \brief Record types that occur within the AST block itself.
+    enum ASTRecordTypes {
+      /// \brief Record code for the offsets of each type.
+      ///
+      /// The TYPE_OFFSET constant describes the record that occurs
+      /// within the AST block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by 
+      /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
+      /// of a type. For a given type ID @c T, the lower three bits of
+      /// @c T are its qualifiers (const, volatile, restrict), as in
+      /// the QualType class. The upper bits, after being shifted and
+      /// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
+      /// TYPE_OFFSET block to determine the offset of that type's
+      /// corresponding record within the DECLTYPES_BLOCK_ID block.
+      TYPE_OFFSET = 1,
+
+      /// \brief Record code for the offsets of each decl.
+      ///
+      /// The DECL_OFFSET constant describes the record that occurs
+      /// within the block identified by DECL_OFFSETS_BLOCK_ID within
+      /// the AST block. The record itself is an array of offsets that
+      /// point into the declarations and types block (identified by
+      /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
+      /// record, after subtracting one to account for the use of
+      /// declaration ID 0 for a NULL declaration pointer. Index 0 is
+      /// reserved for the translation unit declaration.
+      DECL_OFFSET = 2,
+
+      /// \brief Record code for the table of offsets of each
+      /// identifier ID.
+      ///
+      /// The offset table contains offsets into the blob stored in
+      /// the IDENTIFIER_TABLE record. Each offset points to the
+      /// NULL-terminated string that corresponds to that identifier.
+      IDENTIFIER_OFFSET = 3,
+
+      /// \brief This is so that older clang versions, before the introduction
+      /// of the control block, can read and reject the newer PCH format.
+      /// *DON"T CHANGE THIS NUMBER*.
+      METADATA_OLD_FORMAT = 4,
+
+      /// \brief Record code for the identifier table.
+      ///
+      /// The identifier table is a simple blob that contains
+      /// NULL-terminated strings for all of the identifiers
+      /// referenced by the AST file. The IDENTIFIER_OFFSET table
+      /// contains the mapping from identifier IDs to the characters
+      /// in this blob. Note that the starting offsets of all of the
+      /// identifiers are odd, so that, when the identifier offset
+      /// table is loaded in, we can use the low bit to distinguish
+      /// between offsets (for unresolved identifier IDs) and
+      /// IdentifierInfo pointers (for already-resolved identifier
+      /// IDs).
+      IDENTIFIER_TABLE = 5,
+
+      /// \brief Record code for the array of eagerly deserialized decls.
+      ///
+      /// The AST file contains a list of all of the declarations that should be
+      /// eagerly deserialized present within the parsed headers, stored as an
+      /// array of declaration IDs. These declarations will be
+      /// reported to the AST consumer after the AST file has been
+      /// read, since their presence can affect the semantics of the
+      /// program (e.g., for code generation).
+      EAGERLY_DESERIALIZED_DECLS = 6,
+
+      /// \brief Record code for the set of non-builtin, special
+      /// types.
+      ///
+      /// This record contains the type IDs for the various type nodes
+      /// that are constructed during semantic analysis (e.g.,
+      /// __builtin_va_list). The SPECIAL_TYPE_* constants provide
+      /// offsets into this record.
+      SPECIAL_TYPES = 7,
+
+      /// \brief Record code for the extra statistics we gather while
+      /// generating an AST file.
+      STATISTICS = 8,
+
+      /// \brief Record code for the array of tentative definitions.
+      TENTATIVE_DEFINITIONS = 9,
+
+      /// \brief Record code for the array of locally-scoped extern "C"
+      /// declarations.
+      LOCALLY_SCOPED_EXTERN_C_DECLS = 10,
+
+      /// \brief Record code for the table of offsets into the
+      /// Objective-C method pool.
+      SELECTOR_OFFSETS = 11,
+
+      /// \brief Record code for the Objective-C method pool,
+      METHOD_POOL = 12,
+
+      /// \brief The value of the next __COUNTER__ to dispense.
+      /// [PP_COUNTER_VALUE, Val]
+      PP_COUNTER_VALUE = 13,
+
+      /// \brief Record code for the table of offsets into the block
+      /// of source-location information.
+      SOURCE_LOCATION_OFFSETS = 14,
+
+      /// \brief Record code for the set of source location entries
+      /// that need to be preloaded by the AST reader.
+      ///
+      /// This set contains the source location entry for the
+      /// predefines buffer and for any file entries that need to be
+      /// preloaded.
+      SOURCE_LOCATION_PRELOADS = 15,
+
+      /// \brief Record code for the set of ext_vector type names.
+      EXT_VECTOR_DECLS = 16,
+      
+      /// \brief Record code for the array of unused file scoped decls.
+      UNUSED_FILESCOPED_DECLS = 17,
+      
+      /// \brief Record code for the table of offsets to entries in the
+      /// preprocessing record.
+      PPD_ENTITIES_OFFSETS = 18,
+
+      /// \brief Record code for the array of VTable uses.
+      VTABLE_USES = 19,
+
+      /// \brief Record code for the array of dynamic classes.
+      DYNAMIC_CLASSES = 20,
+
+      /// \brief Record code for referenced selector pool.
+      REFERENCED_SELECTOR_POOL = 21,
+
+      /// \brief Record code for an update to the TU's lexically contained
+      /// declarations.
+      TU_UPDATE_LEXICAL = 22,
+      
+      /// \brief Record code for the array describing the locations (in the
+      /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by
+      /// the first known ID.
+      LOCAL_REDECLARATIONS_MAP = 23,
+
+      /// \brief Record code for declarations that Sema keeps references of.
+      SEMA_DECL_REFS = 24,
+
+      /// \brief Record code for weak undeclared identifiers.
+      WEAK_UNDECLARED_IDENTIFIERS = 25,
+
+      /// \brief Record code for pending implicit instantiations.
+      PENDING_IMPLICIT_INSTANTIATIONS = 26,
+
+      /// \brief Record code for a decl replacement block.
+      ///
+      /// If a declaration is modified after having been deserialized, and then
+      /// written to a dependent AST file, its ID and offset must be added to
+      /// the replacement block.
+      DECL_REPLACEMENTS = 27,
+
+      /// \brief Record code for an update to a decl context's lookup table.
+      ///
+      /// In practice, this should only be used for the TU and namespaces.
+      UPDATE_VISIBLE = 28,
+
+      /// \brief Record for offsets of DECL_UPDATES records for declarations
+      /// that were modified after being deserialized and need updates.
+      DECL_UPDATE_OFFSETS = 29,
+
+      /// \brief Record of updates for a declaration that was modified after
+      /// being deserialized.
+      DECL_UPDATES = 30,
+      
+      /// \brief Record code for the table of offsets to CXXBaseSpecifier
+      /// sets.
+      CXX_BASE_SPECIFIER_OFFSETS = 31,
+
+      /// \brief Record code for \#pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS = 32,
+
+      /// \brief Record code for special CUDA declarations.
+      CUDA_SPECIAL_DECL_REFS = 33,
+      
+      /// \brief Record code for header search information.
+      HEADER_SEARCH_TABLE = 34,
+
+      /// \brief Record code for floating point \#pragma options.
+      FP_PRAGMA_OPTIONS = 35,
+
+      /// \brief Record code for enabled OpenCL extensions.
+      OPENCL_EXTENSIONS = 36,
+
+      /// \brief The list of delegating constructor declarations.
+      DELEGATING_CTORS = 37,
+
+      /// \brief Record code for the set of known namespaces, which are used
+      /// for typo correction.
+      KNOWN_NAMESPACES = 38,
+
+      /// \brief Record code for the remapping information used to relate
+      /// loaded modules to the various offsets and IDs(e.g., source location 
+      /// offests, declaration and type IDs) that are used in that module to
+      /// refer to other modules.
+      MODULE_OFFSET_MAP = 39,
+
+      /// \brief Record code for the source manager line table information,
+      /// which stores information about \#line directives.
+      SOURCE_MANAGER_LINE_TABLE = 40,
+
+      /// \brief Record code for map of Objective-C class definition IDs to the 
+      /// ObjC categories in a module that are attached to that class.
+      OBJC_CATEGORIES_MAP = 41,
+
+      /// \brief Record code for a file sorted array of DeclIDs in a module.
+      FILE_SORTED_DECLS = 42,
+      
+      /// \brief Record code for an array of all of the (sub)modules that were
+      /// imported by the AST file.
+      IMPORTED_MODULES = 43,
+      
+      /// \brief Record code for the set of merged declarations in an AST file.
+      MERGED_DECLARATIONS = 44,
+      
+      /// \brief Record code for the array of redeclaration chains.
+      ///
+      /// This array can only be interpreted properly using the local 
+      /// redeclarations map.
+      LOCAL_REDECLARATIONS = 45,
+      
+      /// \brief Record code for the array of Objective-C categories (including
+      /// extensions).
+      ///
+      /// This array can only be interpreted properly using the Objective-C
+      /// categories map.
+      OBJC_CATEGORIES = 46,
+
+      /// \brief Record code for the table of offsets of each macro ID.
+      ///
+      /// The offset table contains offsets into the blob stored in
+      /// the preprocessor block. Each offset points to the corresponding
+      /// macro definition.
+      MACRO_OFFSET = 47,
+
+      /// \brief Mapping table from the identifier ID to the offset of the
+      /// macro directive history for the identifier.
+      MACRO_TABLE = 48,
+
+      /// \brief Record code for undefined but used functions and variables that
+      /// need a definition in this TU.
+      UNDEFINED_BUT_USED = 49,
+
+      /// \brief Record code for late parsed template functions.
+      LATE_PARSED_TEMPLATE = 50,
+
+      /// \brief Record code for \#pragma optimize options.
+      OPTIMIZE_PRAGMA_OPTIONS = 51
+    };
+
+    /// \brief Record types used within a source manager block.
+    enum SourceManagerRecordTypes {
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// file.
+      SM_SLOC_FILE_ENTRY = 1,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// buffer.
+      SM_SLOC_BUFFER_ENTRY = 2,
+      /// \brief Describes a blob that contains the data for a buffer
+      /// entry. This kind of record always directly follows a
+      /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an
+      /// overridden buffer.
+      SM_SLOC_BUFFER_BLOB = 3,
+      /// \brief Describes a source location entry (SLocEntry) for a
+      /// macro expansion.
+      SM_SLOC_EXPANSION_ENTRY = 4
+    };
+
+    /// \brief Record types used within a preprocessor block.
+    enum PreprocessorRecordTypes {
+      // The macros in the PP section are a PP_MACRO_* instance followed by a
+      // list of PP_TOKEN instances for each token in the definition.
+
+      /// \brief An object-like macro definition.
+      /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed]
+      PP_MACRO_OBJECT_LIKE = 1,
+
+      /// \brief A function-like macro definition.
+      /// [PP_MACRO_FUNCTION_LIKE, \<ObjectLikeStuff>, IsC99Varargs,
+      /// IsGNUVarars, NumArgs, ArgIdentInfoID* ]
+      PP_MACRO_FUNCTION_LIKE = 2,
+
+      /// \brief Describes one token.
+      /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
+      PP_TOKEN = 3,
+
+      /// \brief The macro directives history for a particular identifier.
+      PP_MACRO_DIRECTIVE_HISTORY = 4
+    };
+
+    /// \brief Record types used within a preprocessor detail block.
+    enum PreprocessorDetailRecordTypes {
+      /// \brief Describes a macro expansion within the preprocessing record.
+      PPD_MACRO_EXPANSION = 0,
+      
+      /// \brief Describes a macro definition within the preprocessing record.
+      PPD_MACRO_DEFINITION = 1,
+      
+      /// \brief Describes an inclusion directive within the preprocessing
+      /// record.
+      PPD_INCLUSION_DIRECTIVE = 2
+    };
+    
+    /// \brief Record types used within a submodule description block.
+    enum SubmoduleRecordTypes {
+      /// \brief Metadata for submodules as a whole.
+      SUBMODULE_METADATA = 0,
+      /// \brief Defines the major attributes of a submodule, including its
+      /// name and parent.
+      SUBMODULE_DEFINITION = 1,
+      /// \brief Specifies the umbrella header used to create this module,
+      /// if any.
+      SUBMODULE_UMBRELLA_HEADER = 2,
+      /// \brief Specifies a header that falls into this (sub)module.
+      SUBMODULE_HEADER = 3,
+      /// \brief Specifies a top-level header that falls into this (sub)module.
+      SUBMODULE_TOPHEADER = 4,
+      /// \brief Specifies an umbrella directory.
+      SUBMODULE_UMBRELLA_DIR = 5,
+      /// \brief Specifies the submodules that are imported by this 
+      /// submodule.
+      SUBMODULE_IMPORTS = 6,
+      /// \brief Specifies the submodules that are re-exported from this 
+      /// submodule.
+      SUBMODULE_EXPORTS = 7,
+      /// \brief Specifies a required feature.
+      SUBMODULE_REQUIRES = 8,
+      /// \brief Specifies a header that has been explicitly excluded
+      /// from this submodule.
+      SUBMODULE_EXCLUDED_HEADER = 9,
+      /// \brief Specifies a library or framework to link against.
+      SUBMODULE_LINK_LIBRARY = 10,
+      /// \brief Specifies a configuration macro for this module.
+      SUBMODULE_CONFIG_MACRO = 11,
+      /// \brief Specifies a conflict with another module.
+      SUBMODULE_CONFLICT = 12,
+      /// \brief Specifies a header that is private to this submodule.
+      SUBMODULE_PRIVATE_HEADER = 13
+    };
+
+    /// \brief Record types used within a comments block.
+    enum CommentRecordTypes {
+      COMMENTS_RAW_COMMENT = 0
+    };
+
+    /// \defgroup ASTAST AST file AST constants
+    ///
+    /// The constants in this group describe various components of the
+    /// abstract syntax tree within an AST file.
+    ///
+    /// @{
+
+    /// \brief Predefined type IDs.
+    ///
+    /// These type IDs correspond to predefined types in the AST
+    /// context, such as built-in types (int) and special place-holder
+    /// types (the \<overload> and \<dependent> type markers). Such
+    /// types are never actually serialized, since they will be built
+    /// by the AST context when it is created.
+    enum PredefinedTypeIDs {
+      /// \brief The NULL type.
+      PREDEF_TYPE_NULL_ID       = 0,
+      /// \brief The void type.
+      PREDEF_TYPE_VOID_ID       = 1,
+      /// \brief The 'bool' or '_Bool' type.
+      PREDEF_TYPE_BOOL_ID       = 2,
+      /// \brief The 'char' type, when it is unsigned.
+      PREDEF_TYPE_CHAR_U_ID     = 3,
+      /// \brief The 'unsigned char' type.
+      PREDEF_TYPE_UCHAR_ID      = 4,
+      /// \brief The 'unsigned short' type.
+      PREDEF_TYPE_USHORT_ID     = 5,
+      /// \brief The 'unsigned int' type.
+      PREDEF_TYPE_UINT_ID       = 6,
+      /// \brief The 'unsigned long' type.
+      PREDEF_TYPE_ULONG_ID      = 7,
+      /// \brief The 'unsigned long long' type.
+      PREDEF_TYPE_ULONGLONG_ID  = 8,
+      /// \brief The 'char' type, when it is signed.
+      PREDEF_TYPE_CHAR_S_ID     = 9,
+      /// \brief The 'signed char' type.
+      PREDEF_TYPE_SCHAR_ID      = 10,
+      /// \brief The C++ 'wchar_t' type.
+      PREDEF_TYPE_WCHAR_ID      = 11,
+      /// \brief The (signed) 'short' type.
+      PREDEF_TYPE_SHORT_ID      = 12,
+      /// \brief The (signed) 'int' type.
+      PREDEF_TYPE_INT_ID        = 13,
+      /// \brief The (signed) 'long' type.
+      PREDEF_TYPE_LONG_ID       = 14,
+      /// \brief The (signed) 'long long' type.
+      PREDEF_TYPE_LONGLONG_ID   = 15,
+      /// \brief The 'float' type.
+      PREDEF_TYPE_FLOAT_ID      = 16,
+      /// \brief The 'double' type.
+      PREDEF_TYPE_DOUBLE_ID     = 17,
+      /// \brief The 'long double' type.
+      PREDEF_TYPE_LONGDOUBLE_ID = 18,
+      /// \brief The placeholder type for overloaded function sets.
+      PREDEF_TYPE_OVERLOAD_ID   = 19,
+      /// \brief The placeholder type for dependent types.
+      PREDEF_TYPE_DEPENDENT_ID  = 20,
+      /// \brief The '__uint128_t' type.
+      PREDEF_TYPE_UINT128_ID    = 21,
+      /// \brief The '__int128_t' type.
+      PREDEF_TYPE_INT128_ID     = 22,
+      /// \brief The type of 'nullptr'.
+      PREDEF_TYPE_NULLPTR_ID    = 23,
+      /// \brief The C++ 'char16_t' type.
+      PREDEF_TYPE_CHAR16_ID     = 24,
+      /// \brief The C++ 'char32_t' type.
+      PREDEF_TYPE_CHAR32_ID     = 25,
+      /// \brief The ObjC 'id' type.
+      PREDEF_TYPE_OBJC_ID       = 26,
+      /// \brief The ObjC 'Class' type.
+      PREDEF_TYPE_OBJC_CLASS    = 27,
+      /// \brief The ObjC 'SEL' type.
+      PREDEF_TYPE_OBJC_SEL      = 28,
+      /// \brief The 'unknown any' placeholder type.
+      PREDEF_TYPE_UNKNOWN_ANY   = 29,
+      /// \brief The placeholder type for bound member functions.
+      PREDEF_TYPE_BOUND_MEMBER  = 30,
+      /// \brief The "auto" deduction type.
+      PREDEF_TYPE_AUTO_DEDUCT   = 31,
+      /// \brief The "auto &&" deduction type.
+      PREDEF_TYPE_AUTO_RREF_DEDUCT = 32,
+      /// \brief The OpenCL 'half' / ARM NEON __fp16 type.
+      PREDEF_TYPE_HALF_ID       = 33,
+      /// \brief ARC's unbridged-cast placeholder type.
+      PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
+      /// \brief The pseudo-object placeholder type.
+      PREDEF_TYPE_PSEUDO_OBJECT = 35,
+      /// \brief The __va_list_tag placeholder type.
+      PREDEF_TYPE_VA_LIST_TAG = 36,
+      /// \brief The placeholder type for builtin functions.
+      PREDEF_TYPE_BUILTIN_FN = 37,
+      /// \brief OpenCL 1d image type.
+      PREDEF_TYPE_IMAGE1D_ID    = 38,
+      /// \brief OpenCL 1d image array type.
+      PREDEF_TYPE_IMAGE1D_ARR_ID = 39,
+      /// \brief OpenCL 1d image buffer type.
+      PREDEF_TYPE_IMAGE1D_BUFF_ID = 40,
+      /// \brief OpenCL 2d image type.
+      PREDEF_TYPE_IMAGE2D_ID    = 41,
+      /// \brief OpenCL 2d image array type.
+      PREDEF_TYPE_IMAGE2D_ARR_ID = 42,
+      /// \brief OpenCL 3d image type.
+      PREDEF_TYPE_IMAGE3D_ID    = 43,
+      /// \brief OpenCL event type.
+      PREDEF_TYPE_EVENT_ID      = 44,
+      /// \brief OpenCL sampler type.
+      PREDEF_TYPE_SAMPLER_ID    = 45
+    };
+
+    /// \brief The number of predefined type IDs that are reserved for
+    /// the PREDEF_TYPE_* constants.
+    ///
+    /// Type IDs for non-predefined types will start at
+    /// NUM_PREDEF_TYPE_IDs.
+    const unsigned NUM_PREDEF_TYPE_IDS = 100;
+
+    /// \brief The number of allowed abbreviations in bits
+    const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
+
+    /// \brief Record codes for each kind of type.
+    ///
+    /// These constants describe the type records that can occur within a
+    /// block identified by DECLTYPES_BLOCK_ID in the AST file. Each
+    /// constant describes a record for a specific type class in the
+    /// AST.
+    enum TypeCode {
+      /// \brief An ExtQualType record.
+      TYPE_EXT_QUAL                 = 1,
+      /// \brief A ComplexType record.
+      TYPE_COMPLEX                  = 3,
+      /// \brief A PointerType record.
+      TYPE_POINTER                  = 4,
+      /// \brief A BlockPointerType record.
+      TYPE_BLOCK_POINTER            = 5,
+      /// \brief An LValueReferenceType record.
+      TYPE_LVALUE_REFERENCE         = 6,
+      /// \brief An RValueReferenceType record.
+      TYPE_RVALUE_REFERENCE         = 7,
+      /// \brief A MemberPointerType record.
+      TYPE_MEMBER_POINTER           = 8,
+      /// \brief A ConstantArrayType record.
+      TYPE_CONSTANT_ARRAY           = 9,
+      /// \brief An IncompleteArrayType record.
+      TYPE_INCOMPLETE_ARRAY         = 10,
+      /// \brief A VariableArrayType record.
+      TYPE_VARIABLE_ARRAY           = 11,
+      /// \brief A VectorType record.
+      TYPE_VECTOR                   = 12,
+      /// \brief An ExtVectorType record.
+      TYPE_EXT_VECTOR               = 13,
+      /// \brief A FunctionNoProtoType record.
+      TYPE_FUNCTION_NO_PROTO        = 14,
+      /// \brief A FunctionProtoType record.
+      TYPE_FUNCTION_PROTO           = 15,
+      /// \brief A TypedefType record.
+      TYPE_TYPEDEF                  = 16,
+      /// \brief A TypeOfExprType record.
+      TYPE_TYPEOF_EXPR              = 17,
+      /// \brief A TypeOfType record.
+      TYPE_TYPEOF                   = 18,
+      /// \brief A RecordType record.
+      TYPE_RECORD                   = 19,
+      /// \brief An EnumType record.
+      TYPE_ENUM                     = 20,
+      /// \brief An ObjCInterfaceType record.
+      TYPE_OBJC_INTERFACE           = 21,
+      /// \brief An ObjCObjectPointerType record.
+      TYPE_OBJC_OBJECT_POINTER      = 22,
+      /// \brief a DecltypeType record.
+      TYPE_DECLTYPE                 = 23,
+      /// \brief An ElaboratedType record.
+      TYPE_ELABORATED               = 24,
+      /// \brief A SubstTemplateTypeParmType record.
+      TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
+      /// \brief An UnresolvedUsingType record.
+      TYPE_UNRESOLVED_USING         = 26,
+      /// \brief An InjectedClassNameType record.
+      TYPE_INJECTED_CLASS_NAME      = 27,
+      /// \brief An ObjCObjectType record.
+      TYPE_OBJC_OBJECT              = 28,
+      /// \brief An TemplateTypeParmType record.
+      TYPE_TEMPLATE_TYPE_PARM       = 29,
+      /// \brief An TemplateSpecializationType record.
+      TYPE_TEMPLATE_SPECIALIZATION  = 30,
+      /// \brief A DependentNameType record.
+      TYPE_DEPENDENT_NAME           = 31,
+      /// \brief A DependentTemplateSpecializationType record.
+      TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32,
+      /// \brief A DependentSizedArrayType record.
+      TYPE_DEPENDENT_SIZED_ARRAY    = 33,
+      /// \brief A ParenType record.
+      TYPE_PAREN                    = 34,
+      /// \brief A PackExpansionType record.
+      TYPE_PACK_EXPANSION           = 35,
+      /// \brief An AttributedType record.
+      TYPE_ATTRIBUTED               = 36,
+      /// \brief A SubstTemplateTypeParmPackType record.
+      TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
+      /// \brief A AutoType record.
+      TYPE_AUTO                  = 38,
+      /// \brief A UnaryTransformType record.
+      TYPE_UNARY_TRANSFORM       = 39,
+      /// \brief An AtomicType record.
+      TYPE_ATOMIC                = 40,
+      /// \brief A DecayedType record.
+      TYPE_DECAYED               = 41,
+      /// \brief An AdjustedType record.
+      TYPE_ADJUSTED              = 42
+    };
+
+    /// \brief The type IDs for special types constructed by semantic
+    /// analysis.
+    ///
+    /// The constants in this enumeration are indices into the
+    /// SPECIAL_TYPES record.
+    enum SpecialTypeIDs {
+      /// \brief CFConstantString type
+      SPECIAL_TYPE_CF_CONSTANT_STRING          = 0,
+      /// \brief C FILE typedef type
+      SPECIAL_TYPE_FILE                        = 1,
+      /// \brief C jmp_buf typedef type
+      SPECIAL_TYPE_JMP_BUF                     = 2,
+      /// \brief C sigjmp_buf typedef type
+      SPECIAL_TYPE_SIGJMP_BUF                  = 3,
+      /// \brief Objective-C "id" redefinition type
+      SPECIAL_TYPE_OBJC_ID_REDEFINITION        = 4,
+      /// \brief Objective-C "Class" redefinition type
+      SPECIAL_TYPE_OBJC_CLASS_REDEFINITION     = 5,
+      /// \brief Objective-C "SEL" redefinition type
+      SPECIAL_TYPE_OBJC_SEL_REDEFINITION       = 6,
+      /// \brief C ucontext_t typedef type
+      SPECIAL_TYPE_UCONTEXT_T                  = 7
+    };
+    
+    /// \brief The number of special type IDs.
+    const unsigned NumSpecialTypeIDs = 8;
+
+    /// \brief Predefined declaration IDs.
+    ///
+    /// These declaration IDs correspond to predefined declarations in the AST
+    /// context, such as the NULL declaration ID. Such declarations are never
+    /// actually serialized, since they will be built by the AST context when 
+    /// it is created.
+    enum PredefinedDeclIDs {
+      /// \brief The NULL declaration.
+      PREDEF_DECL_NULL_ID       = 0,
+      
+      /// \brief The translation unit.
+      PREDEF_DECL_TRANSLATION_UNIT_ID = 1,
+      
+      /// \brief The Objective-C 'id' type.
+      PREDEF_DECL_OBJC_ID_ID = 2,
+      
+      /// \brief The Objective-C 'SEL' type.
+      PREDEF_DECL_OBJC_SEL_ID = 3,
+      
+      /// \brief The Objective-C 'Class' type.
+      PREDEF_DECL_OBJC_CLASS_ID = 4,
+            
+      /// \brief The Objective-C 'Protocol' type.
+      PREDEF_DECL_OBJC_PROTOCOL_ID = 5,
+      
+      /// \brief The signed 128-bit integer type.
+      PREDEF_DECL_INT_128_ID = 6,
+
+      /// \brief The unsigned 128-bit integer type.
+      PREDEF_DECL_UNSIGNED_INT_128_ID = 7,
+      
+      /// \brief The internal 'instancetype' typedef.
+      PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8,
+
+      /// \brief The internal '__builtin_va_list' typedef.
+      PREDEF_DECL_BUILTIN_VA_LIST_ID = 9
+    };
+
+    /// \brief The number of declaration IDs that are predefined.
+    ///
+    /// For more information about predefined declarations, see the
+    /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
+    const unsigned int NUM_PREDEF_DECL_IDS = 10;
+    
+    /// \brief Record codes for each kind of declaration.
+    ///
+    /// These constants describe the declaration records that can occur within
+    /// a declarations block (identified by DECLS_BLOCK_ID). Each
+    /// constant describes a record for a specific declaration class
+    /// in the AST.
+    enum DeclCode {
+      /// \brief A TypedefDecl record.
+      DECL_TYPEDEF = 51,
+      /// \brief A TypeAliasDecl record.
+      DECL_TYPEALIAS,
+      /// \brief An EnumDecl record.
+      DECL_ENUM,
+      /// \brief A RecordDecl record.
+      DECL_RECORD,
+      /// \brief An EnumConstantDecl record.
+      DECL_ENUM_CONSTANT,
+      /// \brief A FunctionDecl record.
+      DECL_FUNCTION,
+      /// \brief A ObjCMethodDecl record.
+      DECL_OBJC_METHOD,
+      /// \brief A ObjCInterfaceDecl record.
+      DECL_OBJC_INTERFACE,
+      /// \brief A ObjCProtocolDecl record.
+      DECL_OBJC_PROTOCOL,
+      /// \brief A ObjCIvarDecl record.
+      DECL_OBJC_IVAR,
+      /// \brief A ObjCAtDefsFieldDecl record.
+      DECL_OBJC_AT_DEFS_FIELD,
+      /// \brief A ObjCCategoryDecl record.
+      DECL_OBJC_CATEGORY,
+      /// \brief A ObjCCategoryImplDecl record.
+      DECL_OBJC_CATEGORY_IMPL,
+      /// \brief A ObjCImplementationDecl record.
+      DECL_OBJC_IMPLEMENTATION,
+      /// \brief A ObjCCompatibleAliasDecl record.
+      DECL_OBJC_COMPATIBLE_ALIAS,
+      /// \brief A ObjCPropertyDecl record.
+      DECL_OBJC_PROPERTY,
+      /// \brief A ObjCPropertyImplDecl record.
+      DECL_OBJC_PROPERTY_IMPL,
+      /// \brief A FieldDecl record.
+      DECL_FIELD,
+      /// \brief A MSPropertyDecl record.
+      DECL_MS_PROPERTY,
+      /// \brief A VarDecl record.
+      DECL_VAR,
+      /// \brief An ImplicitParamDecl record.
+      DECL_IMPLICIT_PARAM,
+      /// \brief A ParmVarDecl record.
+      DECL_PARM_VAR,
+      /// \brief A FileScopeAsmDecl record.
+      DECL_FILE_SCOPE_ASM,
+      /// \brief A BlockDecl record.
+      DECL_BLOCK,
+      /// \brief A CapturedDecl record.
+      DECL_CAPTURED,
+      /// \brief A record that stores the set of declarations that are
+      /// lexically stored within a given DeclContext.
+      ///
+      /// The record itself is a blob that is an array of declaration IDs,
+      /// in the order in which those declarations were added to the
+      /// declaration context. This data is used when iterating over
+      /// the contents of a DeclContext, e.g., via
+      /// DeclContext::decls_begin() and DeclContext::decls_end().
+      DECL_CONTEXT_LEXICAL,
+      /// \brief A record that stores the set of declarations that are
+      /// visible from a given DeclContext.
+      ///
+      /// The record itself stores a set of mappings, each of which
+      /// associates a declaration name with one or more declaration
+      /// IDs. This data is used when performing qualified name lookup
+      /// into a DeclContext via DeclContext::lookup.
+      DECL_CONTEXT_VISIBLE,
+      /// \brief A LabelDecl record.
+      DECL_LABEL,
+      /// \brief A NamespaceDecl record.
+      DECL_NAMESPACE,
+      /// \brief A NamespaceAliasDecl record.
+      DECL_NAMESPACE_ALIAS,
+      /// \brief A UsingDecl record.
+      DECL_USING,
+      /// \brief A UsingShadowDecl record.
+      DECL_USING_SHADOW,
+      /// \brief A UsingDirecitveDecl record.
+      DECL_USING_DIRECTIVE,
+      /// \brief An UnresolvedUsingValueDecl record.
+      DECL_UNRESOLVED_USING_VALUE,
+      /// \brief An UnresolvedUsingTypenameDecl record.
+      DECL_UNRESOLVED_USING_TYPENAME,
+      /// \brief A LinkageSpecDecl record.
+      DECL_LINKAGE_SPEC,
+      /// \brief A CXXRecordDecl record.
+      DECL_CXX_RECORD,
+      /// \brief A CXXMethodDecl record.
+      DECL_CXX_METHOD,
+      /// \brief A CXXConstructorDecl record.
+      DECL_CXX_CONSTRUCTOR,
+      /// \brief A CXXDestructorDecl record.
+      DECL_CXX_DESTRUCTOR,
+      /// \brief A CXXConversionDecl record.
+      DECL_CXX_CONVERSION,
+      /// \brief An AccessSpecDecl record.
+      DECL_ACCESS_SPEC,
+
+      /// \brief A FriendDecl record.
+      DECL_FRIEND,
+      /// \brief A FriendTemplateDecl record.
+      DECL_FRIEND_TEMPLATE,
+      /// \brief A ClassTemplateDecl record.
+      DECL_CLASS_TEMPLATE,
+      /// \brief A ClassTemplateSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_SPECIALIZATION,
+      /// \brief A ClassTemplatePartialSpecializationDecl record.
+      DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+      /// \brief A VarTemplateDecl record.
+      DECL_VAR_TEMPLATE,
+      /// \brief A VarTemplateSpecializationDecl record.
+      DECL_VAR_TEMPLATE_SPECIALIZATION,
+      /// \brief A VarTemplatePartialSpecializationDecl record.
+      DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION,
+      /// \brief A FunctionTemplateDecl record.
+      DECL_FUNCTION_TEMPLATE,
+      /// \brief A TemplateTypeParmDecl record.
+      DECL_TEMPLATE_TYPE_PARM,
+      /// \brief A NonTypeTemplateParmDecl record.
+      DECL_NON_TYPE_TEMPLATE_PARM,
+      /// \brief A TemplateTemplateParmDecl record.
+      DECL_TEMPLATE_TEMPLATE_PARM,
+      /// \brief A TypeAliasTemplateDecl record.
+      DECL_TYPE_ALIAS_TEMPLATE,
+      /// \brief A StaticAssertDecl record.
+      DECL_STATIC_ASSERT,
+      /// \brief A record containing CXXBaseSpecifiers.
+      DECL_CXX_BASE_SPECIFIERS,
+      /// \brief A IndirectFieldDecl record.
+      DECL_INDIRECTFIELD,
+      /// \brief A NonTypeTemplateParmDecl record that stores an expanded
+      /// non-type template parameter pack.
+      DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK,
+      /// \brief A TemplateTemplateParmDecl record that stores an expanded
+      /// template template parameter pack.
+      DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
+      /// \brief A ClassScopeFunctionSpecializationDecl record a class scope
+      /// function specialization. (Microsoft extension).
+      DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
+      /// \brief An ImportDecl recording a module import.
+      DECL_IMPORT,
+      /// \brief An OMPThreadPrivateDecl record.
+      DECL_OMP_THREADPRIVATE,
+      /// \brief An EmptyDecl record.
+      DECL_EMPTY
+    };
+
+    /// \brief Record codes for each kind of statement or expression.
+    ///
+    /// These constants describe the records that describe statements
+    /// or expressions. These records  occur within type and declarations
+    /// block, so they begin with record values of 100.  Each constant 
+    /// describes a record for a specific statement or expression class in the
+    /// AST.
+    enum StmtCode {
+      /// \brief A marker record that indicates that we are at the end
+      /// of an expression.
+      STMT_STOP = 100,
+      /// \brief A NULL expression.
+      STMT_NULL_PTR,
+      /// \brief A reference to a previously [de]serialized Stmt record.
+      STMT_REF_PTR,
+      /// \brief A NullStmt record.
+      STMT_NULL,
+      /// \brief A CompoundStmt record.
+      STMT_COMPOUND,
+      /// \brief A CaseStmt record.
+      STMT_CASE,
+      /// \brief A DefaultStmt record.
+      STMT_DEFAULT,
+      /// \brief A LabelStmt record.
+      STMT_LABEL,
+      /// \brief An AttributedStmt record.
+      STMT_ATTRIBUTED,
+      /// \brief An IfStmt record.
+      STMT_IF,
+      /// \brief A SwitchStmt record.
+      STMT_SWITCH,
+      /// \brief A WhileStmt record.
+      STMT_WHILE,
+      /// \brief A DoStmt record.
+      STMT_DO,
+      /// \brief A ForStmt record.
+      STMT_FOR,
+      /// \brief A GotoStmt record.
+      STMT_GOTO,
+      /// \brief An IndirectGotoStmt record.
+      STMT_INDIRECT_GOTO,
+      /// \brief A ContinueStmt record.
+      STMT_CONTINUE,
+      /// \brief A BreakStmt record.
+      STMT_BREAK,
+      /// \brief A ReturnStmt record.
+      STMT_RETURN,
+      /// \brief A DeclStmt record.
+      STMT_DECL,
+      /// \brief A CapturedStmt record.
+      STMT_CAPTURED,
+      /// \brief A GCC-style AsmStmt record.
+      STMT_GCCASM,
+      /// \brief A MS-style AsmStmt record.
+      STMT_MSASM,
+      /// \brief A PredefinedExpr record.
+      EXPR_PREDEFINED,
+      /// \brief A DeclRefExpr record.
+      EXPR_DECL_REF,
+      /// \brief An IntegerLiteral record.
+      EXPR_INTEGER_LITERAL,
+      /// \brief A FloatingLiteral record.
+      EXPR_FLOATING_LITERAL,
+      /// \brief An ImaginaryLiteral record.
+      EXPR_IMAGINARY_LITERAL,
+      /// \brief A StringLiteral record.
+      EXPR_STRING_LITERAL,
+      /// \brief A CharacterLiteral record.
+      EXPR_CHARACTER_LITERAL,
+      /// \brief A ParenExpr record.
+      EXPR_PAREN,
+      /// \brief A ParenListExpr record.
+      EXPR_PAREN_LIST,
+      /// \brief A UnaryOperator record.
+      EXPR_UNARY_OPERATOR,
+      /// \brief An OffsetOfExpr record.
+      EXPR_OFFSETOF,
+      /// \brief A SizefAlignOfExpr record.
+      EXPR_SIZEOF_ALIGN_OF,
+      /// \brief An ArraySubscriptExpr record.
+      EXPR_ARRAY_SUBSCRIPT,
+      /// \brief A CallExpr record.
+      EXPR_CALL,
+      /// \brief A MemberExpr record.
+      EXPR_MEMBER,
+      /// \brief A BinaryOperator record.
+      EXPR_BINARY_OPERATOR,
+      /// \brief A CompoundAssignOperator record.
+      EXPR_COMPOUND_ASSIGN_OPERATOR,
+      /// \brief A ConditionOperator record.
+      EXPR_CONDITIONAL_OPERATOR,
+      /// \brief An ImplicitCastExpr record.
+      EXPR_IMPLICIT_CAST,
+      /// \brief A CStyleCastExpr record.
+      EXPR_CSTYLE_CAST,
+      /// \brief A CompoundLiteralExpr record.
+      EXPR_COMPOUND_LITERAL,
+      /// \brief An ExtVectorElementExpr record.
+      EXPR_EXT_VECTOR_ELEMENT,
+      /// \brief An InitListExpr record.
+      EXPR_INIT_LIST,
+      /// \brief A DesignatedInitExpr record.
+      EXPR_DESIGNATED_INIT,
+      /// \brief An ImplicitValueInitExpr record.
+      EXPR_IMPLICIT_VALUE_INIT,
+      /// \brief A VAArgExpr record.
+      EXPR_VA_ARG,
+      /// \brief An AddrLabelExpr record.
+      EXPR_ADDR_LABEL,
+      /// \brief A StmtExpr record.
+      EXPR_STMT,
+      /// \brief A ChooseExpr record.
+      EXPR_CHOOSE,
+      /// \brief A GNUNullExpr record.
+      EXPR_GNU_NULL,
+      /// \brief A ShuffleVectorExpr record.
+      EXPR_SHUFFLE_VECTOR,
+      /// \brief A ConvertVectorExpr record.
+      EXPR_CONVERT_VECTOR,
+      /// \brief BlockExpr
+      EXPR_BLOCK,
+      /// \brief A GenericSelectionExpr record.
+      EXPR_GENERIC_SELECTION,
+      /// \brief A PseudoObjectExpr record.
+      EXPR_PSEUDO_OBJECT,
+      /// \brief An AtomicExpr record.
+      EXPR_ATOMIC,
+
+      // Objective-C
+
+      /// \brief An ObjCStringLiteral record.
+      EXPR_OBJC_STRING_LITERAL,
+
+      EXPR_OBJC_BOXED_EXPRESSION,
+      EXPR_OBJC_ARRAY_LITERAL,
+      EXPR_OBJC_DICTIONARY_LITERAL,
+
+    
+      /// \brief An ObjCEncodeExpr record.
+      EXPR_OBJC_ENCODE,
+      /// \brief An ObjCSelectorExpr record.
+      EXPR_OBJC_SELECTOR_EXPR,
+      /// \brief An ObjCProtocolExpr record.
+      EXPR_OBJC_PROTOCOL_EXPR,
+      /// \brief An ObjCIvarRefExpr record.
+      EXPR_OBJC_IVAR_REF_EXPR,
+      /// \brief An ObjCPropertyRefExpr record.
+      EXPR_OBJC_PROPERTY_REF_EXPR,
+      /// \brief An ObjCSubscriptRefExpr record.
+      EXPR_OBJC_SUBSCRIPT_REF_EXPR,
+      /// \brief UNUSED
+      EXPR_OBJC_KVC_REF_EXPR,
+      /// \brief An ObjCMessageExpr record.
+      EXPR_OBJC_MESSAGE_EXPR,
+      /// \brief An ObjCIsa Expr record.
+      EXPR_OBJC_ISA,
+      /// \brief An ObjCIndirectCopyRestoreExpr record.
+      EXPR_OBJC_INDIRECT_COPY_RESTORE,
+
+      /// \brief An ObjCForCollectionStmt record.
+      STMT_OBJC_FOR_COLLECTION,
+      /// \brief An ObjCAtCatchStmt record.
+      STMT_OBJC_CATCH,
+      /// \brief An ObjCAtFinallyStmt record.
+      STMT_OBJC_FINALLY,
+      /// \brief An ObjCAtTryStmt record.
+      STMT_OBJC_AT_TRY,
+      /// \brief An ObjCAtSynchronizedStmt record.
+      STMT_OBJC_AT_SYNCHRONIZED,
+      /// \brief An ObjCAtThrowStmt record.
+      STMT_OBJC_AT_THROW,
+      /// \brief An ObjCAutoreleasePoolStmt record.
+      STMT_OBJC_AUTORELEASE_POOL,
+      /// \brief A ObjCBoolLiteralExpr record.
+      EXPR_OBJC_BOOL_LITERAL,
+
+      // C++
+      
+      /// \brief A CXXCatchStmt record.
+      STMT_CXX_CATCH,
+      /// \brief A CXXTryStmt record.
+      STMT_CXX_TRY,
+      /// \brief A CXXForRangeStmt record.
+      STMT_CXX_FOR_RANGE,
+
+      /// \brief A CXXOperatorCallExpr record.
+      EXPR_CXX_OPERATOR_CALL,
+      /// \brief A CXXMemberCallExpr record.
+      EXPR_CXX_MEMBER_CALL,
+      /// \brief A CXXConstructExpr record.
+      EXPR_CXX_CONSTRUCT,
+      /// \brief A CXXTemporaryObjectExpr record.
+      EXPR_CXX_TEMPORARY_OBJECT,
+      /// \brief A CXXStaticCastExpr record.
+      EXPR_CXX_STATIC_CAST,
+      /// \brief A CXXDynamicCastExpr record.
+      EXPR_CXX_DYNAMIC_CAST,
+      /// \brief A CXXReinterpretCastExpr record.
+      EXPR_CXX_REINTERPRET_CAST,
+      /// \brief A CXXConstCastExpr record.
+      EXPR_CXX_CONST_CAST,
+      /// \brief A CXXFunctionalCastExpr record.
+      EXPR_CXX_FUNCTIONAL_CAST,
+      /// \brief A UserDefinedLiteral record.
+      EXPR_USER_DEFINED_LITERAL,
+      /// \brief A CXXStdInitializerListExpr record.
+      EXPR_CXX_STD_INITIALIZER_LIST,
+      /// \brief A CXXBoolLiteralExpr record.
+      EXPR_CXX_BOOL_LITERAL,
+      EXPR_CXX_NULL_PTR_LITERAL,  // CXXNullPtrLiteralExpr
+      EXPR_CXX_TYPEID_EXPR,       // CXXTypeidExpr (of expr).
+      EXPR_CXX_TYPEID_TYPE,       // CXXTypeidExpr (of type).
+      EXPR_CXX_THIS,              // CXXThisExpr
+      EXPR_CXX_THROW,             // CXXThrowExpr
+      EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
+      EXPR_CXX_DEFAULT_INIT,      // CXXDefaultInitExpr
+      EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
+
+      EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
+      EXPR_CXX_NEW,               // CXXNewExpr
+      EXPR_CXX_DELETE,            // CXXDeleteExpr
+      EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
+      
+      EXPR_EXPR_WITH_CLEANUPS,    // ExprWithCleanups
+      
+      EXPR_CXX_DEPENDENT_SCOPE_MEMBER,   // CXXDependentScopeMemberExpr
+      EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr
+      EXPR_CXX_UNRESOLVED_CONSTRUCT,     // CXXUnresolvedConstructExpr
+      EXPR_CXX_UNRESOLVED_MEMBER,        // UnresolvedMemberExpr
+      EXPR_CXX_UNRESOLVED_LOOKUP,        // UnresolvedLookupExpr
+
+      EXPR_CXX_EXPRESSION_TRAIT,  // ExpressionTraitExpr
+      EXPR_CXX_NOEXCEPT,          // CXXNoexceptExpr
+
+      EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
+      EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
+      EXPR_TYPE_TRAIT,            // TypeTraitExpr
+      EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
+      
+      EXPR_PACK_EXPANSION,        // PackExpansionExpr
+      EXPR_SIZEOF_PACK,           // SizeOfPackExpr
+      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr
+      EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
+      EXPR_FUNCTION_PARM_PACK,    // FunctionParmPackExpr
+      EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr
+      
+      // CUDA
+      EXPR_CUDA_KERNEL_CALL,       // CUDAKernelCallExpr      
+
+      // OpenCL
+      EXPR_ASTYPE,                 // AsTypeExpr
+
+      // Microsoft
+      EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
+      EXPR_CXX_UUIDOF_EXPR,       // CXXUuidofExpr (of expr).
+      EXPR_CXX_UUIDOF_TYPE,       // CXXUuidofExpr (of type).
+      STMT_SEH_LEAVE,             // SEHLeaveStmt
+      STMT_SEH_EXCEPT,            // SEHExceptStmt
+      STMT_SEH_FINALLY,           // SEHFinallyStmt
+      STMT_SEH_TRY,               // SEHTryStmt
+
+      // OpenMP drectives
+      STMT_OMP_PARALLEL_DIRECTIVE,
+      STMT_OMP_SIMD_DIRECTIVE,
+      STMT_OMP_FOR_DIRECTIVE,
+      STMT_OMP_SECTIONS_DIRECTIVE,
+      STMT_OMP_SECTION_DIRECTIVE,
+      STMT_OMP_SINGLE_DIRECTIVE,
+      STMT_OMP_MASTER_DIRECTIVE,
+      STMT_OMP_CRITICAL_DIRECTIVE,
+      STMT_OMP_PARALLEL_FOR_DIRECTIVE,
+      STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
+      STMT_OMP_TASK_DIRECTIVE,
+      STMT_OMP_TASKYIELD_DIRECTIVE,
+      STMT_OMP_BARRIER_DIRECTIVE,
+      STMT_OMP_TASKWAIT_DIRECTIVE,
+      STMT_OMP_FLUSH_DIRECTIVE,
+
+      // ARC
+      EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
+      
+      STMT_MS_DEPENDENT_EXISTS,   // MSDependentExistsStmt
+      EXPR_LAMBDA                 // LambdaExpr
+    };
+
+    /// \brief The kinds of designators that can occur in a
+    /// DesignatedInitExpr.
+    enum DesignatorTypes {
+      /// \brief Field designator where only the field name is known.
+      DESIG_FIELD_NAME  = 0,
+      /// \brief Field designator where the field has been resolved to
+      /// a declaration.
+      DESIG_FIELD_DECL  = 1,
+      /// \brief Array designator.
+      DESIG_ARRAY       = 2,
+      /// \brief GNU array range designator.
+      DESIG_ARRAY_RANGE = 3
+    };
+
+    /// \brief The different kinds of data that can occur in a
+    /// CtorInitializer.
+    enum CtorInitializerType {
+      CTOR_INITIALIZER_BASE,
+      CTOR_INITIALIZER_DELEGATING,
+      CTOR_INITIALIZER_MEMBER,
+      CTOR_INITIALIZER_INDIRECT_MEMBER
+    };
+
+    /// \brief Describes the redeclarations of a declaration.
+    struct LocalRedeclarationsInfo {
+      DeclID FirstID;      // The ID of the first declaration
+      unsigned Offset;     // Offset into the array of redeclaration chains.
+      
+      friend bool operator<(const LocalRedeclarationsInfo &X,
+                            const LocalRedeclarationsInfo &Y) {
+        return X.FirstID < Y.FirstID;
+      }
+      
+      friend bool operator>(const LocalRedeclarationsInfo &X,
+                            const LocalRedeclarationsInfo &Y) {
+        return X.FirstID > Y.FirstID;
+      }
+      
+      friend bool operator<=(const LocalRedeclarationsInfo &X,
+                             const LocalRedeclarationsInfo &Y) {
+        return X.FirstID <= Y.FirstID;
+      }
+      
+      friend bool operator>=(const LocalRedeclarationsInfo &X,
+                             const LocalRedeclarationsInfo &Y) {
+        return X.FirstID >= Y.FirstID;
+      }
+    };
+
+    /// \brief Describes the categories of an Objective-C class.
+    struct ObjCCategoriesInfo {
+      DeclID DefinitionID; // The ID of the definition
+      unsigned Offset;     // Offset into the array of category lists.
+      
+      friend bool operator<(const ObjCCategoriesInfo &X,
+                            const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID < Y.DefinitionID;
+      }
+      
+      friend bool operator>(const ObjCCategoriesInfo &X,
+                            const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID > Y.DefinitionID;
+      }
+      
+      friend bool operator<=(const ObjCCategoriesInfo &X,
+                             const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID <= Y.DefinitionID;
+      }
+      
+      friend bool operator>=(const ObjCCategoriesInfo &X,
+                             const ObjCCategoriesInfo &Y) {
+        return X.DefinitionID >= Y.DefinitionID;
+      }
+    };
+
+    /// @}
+  }
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
new file mode 100644
index 0000000..180f554
--- /dev/null
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -0,0 +1,59 @@
+//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- 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 ASTDeserializationListener class, which is notified
+//  by the ASTReader whenever a type or declaration is deserialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+#define LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Serialization/ASTBitCodes.h"
+
+namespace clang {
+
+class Decl;
+class ASTReader;
+class QualType;
+class MacroDefinition;
+class MacroInfo;
+class Module;
+  
+class ASTDeserializationListener {
+public:
+  virtual ~ASTDeserializationListener();
+
+  /// \brief The ASTReader was initialized.
+  virtual void ReaderInitialized(ASTReader *Reader) { }
+
+  /// \brief An identifier was deserialized from the AST file.
+  virtual void IdentifierRead(serialization::IdentID ID,
+                              IdentifierInfo *II) { }
+  /// \brief A macro was read from the AST file.
+  virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { }
+  /// \brief A type was deserialized from the AST file. The ID here has the
+  ///        qualifier bits already removed, and T is guaranteed to be locally
+  ///        unqualified.
+  virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { }
+  /// \brief A decl was deserialized from the AST file.
+  virtual void DeclRead(serialization::DeclID ID, const Decl *D) { }
+  /// \brief A selector was read from the AST file.
+  virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) { }
+  /// \brief A macro definition was read from the AST file.
+  virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, 
+                                   MacroDefinition *MD) { }
+  /// \brief A module definition was read from the AST file.
+  virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) { }
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
new file mode 100644
index 0000000..3f44440
--- /dev/null
+++ b/include/clang/Serialization/ASTReader.h
@@ -0,0 +1,2104 @@
+//===--- ASTReader.h - AST File Reader --------------------------*- 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 ASTReader class, which reads AST files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_AST_READER_H
+#define LLVM_CLANG_FRONTEND_AST_READER_H
+
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/Module.h"
+#include "clang/Serialization/ModuleManager.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/DataTypes.h"
+#include <deque>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class AddrLabelExpr;
+class ASTConsumer;
+class ASTContext;
+class ASTIdentifierIterator;
+class ASTUnit; // FIXME: Layering violation and egregious hack.
+class Attr;
+class Decl;
+class DeclContext;
+class DefMacroDirective;
+class DiagnosticOptions;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXConstructorDecl;
+class CXXCtorInitializer;
+class GlobalModuleIndex;
+class GotoStmt;
+class MacroDefinition;
+class MacroDirective;
+class NamedDecl;
+class OpaqueValueExpr;
+class Preprocessor;
+class PreprocessorOptions;
+class Sema;
+class SwitchCase;
+class ASTDeserializationListener;
+class ASTWriter;
+class ASTReader;
+class ASTDeclReader;
+class ASTStmtReader;
+class TypeLocReader;
+struct HeaderFileInfo;
+class VersionTuple;
+class TargetOptions;
+class LazyASTUnresolvedSet;
+
+/// \brief Abstract interface for callback invocations by the ASTReader.
+///
+/// While reading an AST file, the ASTReader will call the methods of the
+/// listener to pass on specific information. Some of the listener methods can
+/// return true to indicate to the ASTReader that the information (and
+/// consequently the AST file) is invalid.
+class ASTReaderListener {
+public:
+  virtual ~ASTReaderListener();
+
+  /// \brief Receives the full Clang version information.
+  ///
+  /// \returns true to indicate that the version is invalid. Subclasses should
+  /// generally defer to this implementation.
+  virtual bool ReadFullVersionInformation(StringRef FullVersion) {
+    return FullVersion != getClangFullRepositoryVersion();
+  }
+
+  virtual void ReadModuleName(StringRef ModuleName) {}
+  virtual void ReadModuleMapFile(StringRef ModuleMapPath) {}
+
+  /// \brief Receives the language options.
+  ///
+  /// \returns true to indicate the options are invalid or false otherwise.
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
+                                   bool Complain) {
+    return false;
+  }
+
+  /// \brief Receives the target options.
+  ///
+  /// \returns true to indicate the target options are invalid, or false
+  /// otherwise.
+  virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                                 bool Complain) {
+    return false;
+  }
+
+  /// \brief Receives the diagnostic options.
+  ///
+  /// \returns true to indicate the diagnostic options are invalid, or false
+  /// otherwise.
+  virtual bool
+  ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                        bool Complain) {
+    return false;
+  }
+
+  /// \brief Receives the file system options.
+  ///
+  /// \returns true to indicate the file system options are invalid, or false
+  /// otherwise.
+  virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                                     bool Complain) {
+    return false;
+  }
+
+  /// \brief Receives the header search options.
+  ///
+  /// \returns true to indicate the header search options are invalid, or false
+  /// otherwise.
+  virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+                                       bool Complain) {
+    return false;
+  }
+
+  /// \brief Receives the preprocessor options.
+  ///
+  /// \param SuggestedPredefines Can be filled in with the set of predefines
+  /// that are suggested by the preprocessor options. Typically only used when
+  /// loading a precompiled header.
+  ///
+  /// \returns true to indicate the preprocessor options are invalid, or false
+  /// otherwise.
+  virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                                       bool Complain,
+                                       std::string &SuggestedPredefines) {
+    return false;
+  }
+
+  /// \brief Receives __COUNTER__ value.
+  virtual void ReadCounter(const serialization::ModuleFile &M,
+                           unsigned Value) {}
+
+  /// This is called for each AST file loaded.
+  virtual void visitModuleFile(StringRef Filename) {}
+
+  /// \brief Returns true if this \c ASTReaderListener wants to receive the
+  /// input files of the AST file via \c visitInputFile, false otherwise.
+  virtual bool needsInputFileVisitation() { return false; }
+  /// \brief Returns true if this \c ASTReaderListener wants to receive the
+  /// system input files of the AST file via \c visitInputFile, false otherwise.
+  virtual bool needsSystemInputFileVisitation() { return false; }
+  /// \brief if \c needsInputFileVisitation returns true, this is called for
+  /// each non-system input file of the AST File. If
+  /// \c needsSystemInputFileVisitation is true, then it is called for all
+  /// system input files as well.
+  ///
+  /// \returns true to continue receiving the next input file, false to stop.
+  virtual bool visitInputFile(StringRef Filename, bool isSystem,
+                              bool isOverridden) {
+    return true;
+  }
+};
+
+/// \brief Simple wrapper class for chaining listeners.
+class ChainedASTReaderListener : public ASTReaderListener {
+  std::unique_ptr<ASTReaderListener> First;
+  std::unique_ptr<ASTReaderListener> Second;
+
+public:
+  /// Takes ownership of \p First and \p Second.
+  ChainedASTReaderListener(ASTReaderListener *First, ASTReaderListener *Second)
+      : First(First), Second(Second) { }
+
+  bool ReadFullVersionInformation(StringRef FullVersion) override;
+  void ReadModuleName(StringRef ModuleName) override;
+  void ReadModuleMapFile(StringRef ModuleMapPath) override;
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
+  bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                         bool Complain) override;
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             bool Complain) override;
+  bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                             bool Complain) override;
+
+  bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+                               bool Complain) override;
+  bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                               bool Complain,
+                               std::string &SuggestedPredefines) override;
+
+  void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
+  bool needsInputFileVisitation() override;
+  bool needsSystemInputFileVisitation() override;
+  void visitModuleFile(StringRef Filename) override;
+  bool visitInputFile(StringRef Filename, bool isSystem,
+                      bool isOverridden) override;
+};
+
+/// \brief ASTReaderListener implementation to validate the information of
+/// the PCH file against an initialized Preprocessor.
+class PCHValidator : public ASTReaderListener {
+  Preprocessor &PP;
+  ASTReader &Reader;
+
+public:
+  PCHValidator(Preprocessor &PP, ASTReader &Reader)
+    : PP(PP), Reader(Reader) {}
+
+  bool ReadLanguageOptions(const LangOptions &LangOpts,
+                           bool Complain) override;
+  bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                         bool Complain) override;
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             bool Complain) override;
+  bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+                               std::string &SuggestedPredefines) override;
+  void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
+
+private:
+  void Error(const char *Msg);
+};
+
+namespace serialization {
+
+class ReadMethodPoolVisitor;
+
+namespace reader {
+  class ASTIdentifierLookupTrait;
+  /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
+  typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
+    ASTDeclContextNameLookupTable;
+}
+
+} // end namespace serialization
+
+/// \brief Reads an AST files chain containing the contents of a translation
+/// unit.
+///
+/// The ASTReader class reads bitstreams (produced by the ASTWriter
+/// class) containing the serialized representation of a given
+/// abstract syntax tree and its supporting data structures. An
+/// instance of the ASTReader can be attached to an ASTContext object,
+/// which will provide access to the contents of the AST files.
+///
+/// The AST reader provides lazy de-serialization of declarations, as
+/// required when traversing the AST. Only those AST nodes that are
+/// actually required will be de-serialized.
+class ASTReader
+  : public ExternalPreprocessorSource,
+    public ExternalPreprocessingRecordSource,
+    public ExternalHeaderFileInfoSource,
+    public ExternalSemaSource,
+    public IdentifierInfoLookup,
+    public ExternalIdentifierLookup,
+    public ExternalSLocEntrySource
+{
+public:
+  typedef SmallVector<uint64_t, 64> RecordData;
+  typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+
+  /// \brief The result of reading the control block of an AST file, which
+  /// can fail for various reasons.
+  enum ASTReadResult {
+    /// \brief The control block was read successfully. Aside from failures,
+    /// the AST file is safe to read into the current context.
+    Success,
+    /// \brief The AST file itself appears corrupted.
+    Failure,
+    /// \brief The AST file was missing.
+    Missing,
+    /// \brief The AST file is out-of-date relative to its input files,
+    /// and needs to be regenerated.
+    OutOfDate,
+    /// \brief The AST file was written by a different version of Clang.
+    VersionMismatch,
+    /// \brief The AST file was writtten with a different language/target
+    /// configuration.
+    ConfigurationMismatch,
+    /// \brief The AST file has errors.
+    HadErrors
+  };
+  
+  /// \brief Types of AST files.
+  friend class PCHValidator;
+  friend class ASTDeclReader;
+  friend class ASTStmtReader;
+  friend class ASTIdentifierIterator;
+  friend class serialization::reader::ASTIdentifierLookupTrait;
+  friend class TypeLocReader;
+  friend class ASTWriter;
+  friend class ASTUnit; // ASTUnit needs to remap source locations.
+  friend class serialization::ReadMethodPoolVisitor;
+
+  typedef serialization::ModuleFile ModuleFile;
+  typedef serialization::ModuleKind ModuleKind;
+  typedef serialization::ModuleManager ModuleManager;
+
+  typedef ModuleManager::ModuleIterator ModuleIterator;
+  typedef ModuleManager::ModuleConstIterator ModuleConstIterator;
+  typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator;
+
+private:
+  /// \brief The receiver of some callbacks invoked by ASTReader.
+  std::unique_ptr<ASTReaderListener> Listener;
+
+  /// \brief The receiver of deserialization events.
+  ASTDeserializationListener *DeserializationListener;
+  bool OwnsDeserializationListener;
+
+  SourceManager &SourceMgr;
+  FileManager &FileMgr;
+  DiagnosticsEngine &Diags;
+
+  /// \brief The semantic analysis object that will be processing the
+  /// AST files and the translation unit that uses it.
+  Sema *SemaObj;
+
+  /// \brief The preprocessor that will be loading the source file.
+  Preprocessor &PP;
+
+  /// \brief The AST context into which we'll read the AST files.
+  ASTContext &Context;
+
+  /// \brief The AST consumer.
+  ASTConsumer *Consumer;
+
+  /// \brief The module manager which manages modules and their dependencies
+  ModuleManager ModuleMgr;
+
+  /// \brief The location where the module file will be considered as
+  /// imported from. For non-module AST types it should be invalid.
+  SourceLocation CurrentImportLoc;
+
+  /// \brief The global module index, if loaded.
+  std::unique_ptr<GlobalModuleIndex> GlobalIndex;
+
+  /// \brief A map of global bit offsets to the module that stores entities
+  /// at those bit offsets.
+  ContinuousRangeMap<uint64_t, ModuleFile*, 4> GlobalBitOffsetsMap;
+
+  /// \brief A map of negated SLocEntryIDs to the modules containing them.
+  ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap;
+
+  typedef ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocOffsetMapType;
+
+  /// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset)
+  /// SourceLocation offsets to the modules containing them.
+  GlobalSLocOffsetMapType GlobalSLocOffsetMap;
+
+  /// \brief Types that have already been loaded from the chain.
+  ///
+  /// When the pointer at index I is non-NULL, the type with
+  /// ID = (I + 1) << FastQual::Width has already been loaded
+  std::vector<QualType> TypesLoaded;
+
+  typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>
+    GlobalTypeMapType;
+
+  /// \brief Mapping from global type IDs to the module in which the
+  /// type resides along with the offset that should be added to the
+  /// global type ID to produce a local ID.
+  GlobalTypeMapType GlobalTypeMap;
+
+  /// \brief Declarations that have already been loaded from the chain.
+  ///
+  /// When the pointer at index I is non-NULL, the declaration with ID
+  /// = I + 1 has already been loaded.
+  std::vector<Decl *> DeclsLoaded;
+
+  typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>
+    GlobalDeclMapType;
+
+  /// \brief Mapping from global declaration IDs to the module in which the
+  /// declaration resides.
+  GlobalDeclMapType GlobalDeclMap;
+
+  typedef std::pair<ModuleFile *, uint64_t> FileOffset;
+  typedef SmallVector<FileOffset, 2> FileOffsetsTy;
+  typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy>
+      DeclUpdateOffsetsMap;
+
+  /// \brief Declarations that have modifications residing in a later file
+  /// in the chain.
+  DeclUpdateOffsetsMap DeclUpdateOffsets;
+
+  /// \brief Declaration updates for already-loaded declarations that we need
+  /// to apply once we finish processing an import.
+  llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16>
+      PendingUpdateRecords;
+
+  struct ReplacedDeclInfo {
+    ModuleFile *Mod;
+    uint64_t Offset;
+    unsigned RawLoc;
+
+    ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {}
+    ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc)
+      : Mod(Mod), Offset(Offset), RawLoc(RawLoc) {}
+  };
+
+  typedef llvm::DenseMap<serialization::DeclID, ReplacedDeclInfo>
+      DeclReplacementMap;
+  /// \brief Declarations that have been replaced in a later file in the chain.
+  DeclReplacementMap ReplacedDecls;
+
+  struct FileDeclsInfo {
+    ModuleFile *Mod;
+    ArrayRef<serialization::LocalDeclID> Decls;
+
+    FileDeclsInfo() : Mod(nullptr) {}
+    FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
+      : Mod(Mod), Decls(Decls) {}
+  };
+
+  /// \brief Map from a FileID to the file-level declarations that it contains.
+  llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs;
+
+  // Updates for visible decls can occur for other contexts than just the
+  // TU, and when we read those update records, the actual context will not
+  // be available yet (unless it's the TU), so have this pending map using the
+  // ID as a key. It will be realized when the context is actually loaded.
+  typedef
+    SmallVector<std::pair<serialization::reader::ASTDeclContextNameLookupTable *,
+                          ModuleFile*>, 1> DeclContextVisibleUpdates;
+  typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
+      DeclContextVisibleUpdatesPending;
+
+  /// \brief Updates to the visible declarations of declaration contexts that
+  /// haven't been loaded yet.
+  DeclContextVisibleUpdatesPending PendingVisibleUpdates;
+  
+  /// \brief The set of C++ or Objective-C classes that have forward 
+  /// declarations that have not yet been linked to their definitions.
+  llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
+
+  typedef llvm::MapVector<Decl *, uint64_t,
+                          llvm::SmallDenseMap<Decl *, unsigned, 4>,
+                          SmallVector<std::pair<Decl *, uint64_t>, 4> >
+    PendingBodiesMap;
+
+  /// \brief Functions or methods that have bodies that will be attached.
+  PendingBodiesMap PendingBodies;
+
+  /// \brief Read the records that describe the contents of declcontexts.
+  bool ReadDeclContextStorage(ModuleFile &M,
+                              llvm::BitstreamCursor &Cursor,
+                              const std::pair<uint64_t, uint64_t> &Offsets,
+                              serialization::DeclContextInfo &Info);
+
+  /// \brief A vector containing identifiers that have already been
+  /// loaded.
+  ///
+  /// If the pointer at index I is non-NULL, then it refers to the
+  /// IdentifierInfo for the identifier with ID=I+1 that has already
+  /// been loaded.
+  std::vector<IdentifierInfo *> IdentifiersLoaded;
+
+  typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>
+    GlobalIdentifierMapType;
+
+  /// \brief Mapping from global identifier IDs to the module in which the
+  /// identifier resides along with the offset that should be added to the
+  /// global identifier ID to produce a local ID.
+  GlobalIdentifierMapType GlobalIdentifierMap;
+
+  /// \brief A vector containing macros that have already been
+  /// loaded.
+  ///
+  /// If the pointer at index I is non-NULL, then it refers to the
+  /// MacroInfo for the identifier with ID=I+1 that has already
+  /// been loaded.
+  std::vector<MacroInfo *> MacrosLoaded;
+
+  typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>
+    GlobalMacroMapType;
+
+  /// \brief Mapping from global macro IDs to the module in which the
+  /// macro resides along with the offset that should be added to the
+  /// global macro ID to produce a local ID.
+  GlobalMacroMapType GlobalMacroMap;
+
+  /// \brief A vector containing submodules that have already been loaded.
+  ///
+  /// This vector is indexed by the Submodule ID (-1). NULL submodule entries
+  /// indicate that the particular submodule ID has not yet been loaded.
+  SmallVector<Module *, 2> SubmodulesLoaded;
+  
+  typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>
+    GlobalSubmoduleMapType;
+  
+  /// \brief Mapping from global submodule IDs to the module file in which the
+  /// submodule resides along with the offset that should be added to the
+  /// global submodule ID to produce a local ID.
+  GlobalSubmoduleMapType GlobalSubmoduleMap;
+
+  /// \brief Information on a macro definition or undefinition that is visible
+  /// at the end of a submodule.
+  struct ModuleMacroInfo;
+
+  /// \brief An entity that has been hidden.
+  class HiddenName {
+  public:
+    enum NameKind {
+      Declaration,
+      Macro
+    } Kind;
+
+  private:
+    union {
+      Decl *D;
+      ModuleMacroInfo *MMI;
+    };
+
+    IdentifierInfo *Id;
+
+  public:
+    HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
+
+    HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI)
+      : Kind(Macro), MMI(MMI), Id(II) { }
+
+    NameKind getKind() const { return Kind; }
+
+    Decl *getDecl() const {
+      assert(getKind() == Declaration && "Hidden name is not a declaration");
+      return D;
+    }
+
+    std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const {
+      assert(getKind() == Macro && "Hidden name is not a macro!");
+      return std::make_pair(Id, MMI);
+    }
+  };
+
+  typedef llvm::SmallDenseMap<IdentifierInfo*,
+                              ModuleMacroInfo*> HiddenMacrosMap;
+
+  /// \brief A set of hidden declarations.
+  struct HiddenNames {
+    SmallVector<Decl*, 2> HiddenDecls;
+    HiddenMacrosMap HiddenMacros;
+  };
+
+  typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
+
+  /// \brief A mapping from each of the hidden submodules to the deserialized
+  /// declarations in that submodule that could be made visible.
+  HiddenNamesMapType HiddenNamesMap;
+  
+  
+  /// \brief A module import, export, or conflict that hasn't yet been resolved.
+  struct UnresolvedModuleRef {
+    /// \brief The file in which this module resides.
+    ModuleFile *File;
+    
+    /// \brief The module that is importing or exporting.
+    Module *Mod;
+
+    /// \brief The kind of module reference.
+    enum { Import, Export, Conflict } Kind;
+
+    /// \brief The local ID of the module that is being exported.
+    unsigned ID;
+
+    /// \brief Whether this is a wildcard export.
+    unsigned IsWildcard : 1;
+
+    /// \brief String data.
+    StringRef String;
+  };
+  
+  /// \brief The set of module imports and exports that still need to be 
+  /// resolved.
+  SmallVector<UnresolvedModuleRef, 2> UnresolvedModuleRefs;
+  
+  /// \brief A vector containing selectors that have already been loaded.
+  ///
+  /// This vector is indexed by the Selector ID (-1). NULL selector
+  /// entries indicate that the particular selector ID has not yet
+  /// been loaded.
+  SmallVector<Selector, 16> SelectorsLoaded;
+
+  typedef ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>
+    GlobalSelectorMapType;
+
+  /// \brief Mapping from global selector IDs to the module in which the
+
+  /// global selector ID to produce a local ID.
+  GlobalSelectorMapType GlobalSelectorMap;
+
+  /// \brief The generation number of the last time we loaded data from the
+  /// global method pool for this selector.
+  llvm::DenseMap<Selector, unsigned> SelectorGeneration;
+
+  struct PendingMacroInfo {
+    ModuleFile *M;
+
+    struct ModuleMacroDataTy {
+      uint32_t MacID;
+      serialization::SubmoduleID *Overrides;
+    };
+    struct PCHMacroDataTy {
+      uint64_t MacroDirectivesOffset;
+    };
+
+    union {
+      ModuleMacroDataTy ModuleMacroData;
+      PCHMacroDataTy PCHMacroData;
+    };
+
+    PendingMacroInfo(ModuleFile *M,
+                     uint32_t MacID,
+                     serialization::SubmoduleID *Overrides) : M(M) {
+      ModuleMacroData.MacID = MacID;
+      ModuleMacroData.Overrides = Overrides;
+    }
+
+    PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
+      PCHMacroData.MacroDirectivesOffset = MacroDirectivesOffset;
+    }
+  };
+
+  typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
+    PendingMacroIDsMap;
+
+  /// \brief Mapping from identifiers that have a macro history to the global
+  /// IDs have not yet been deserialized to the global IDs of those macros.
+  PendingMacroIDsMap PendingMacroIDs;
+
+  typedef ContinuousRangeMap<unsigned, ModuleFile *, 4>
+    GlobalPreprocessedEntityMapType;
+
+  /// \brief Mapping from global preprocessing entity IDs to the module in
+  /// which the preprocessed entity resides along with the offset that should be
+  /// added to the global preprocessing entitiy ID to produce a local ID.
+  GlobalPreprocessedEntityMapType GlobalPreprocessedEntityMap;
+
+  /// \name CodeGen-relevant special data
+  /// \brief Fields containing data that is relevant to CodeGen.
+  //@{
+
+  /// \brief The IDs of all declarations that fulfill the criteria of
+  /// "interesting" decls.
+  ///
+  /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
+  /// in the chain. The referenced declarations are deserialized and passed to
+  /// the consumer eagerly.
+  SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
+
+  /// \brief The IDs of all tentative definitions stored in the chain.
+  ///
+  /// Sema keeps track of all tentative definitions in a TU because it has to
+  /// complete them and pass them on to CodeGen. Thus, tentative definitions in
+  /// the PCH chain must be eagerly deserialized.
+  SmallVector<uint64_t, 16> TentativeDefinitions;
+
+  /// \brief The IDs of all CXXRecordDecls stored in the chain whose VTables are
+  /// used.
+  ///
+  /// CodeGen has to emit VTables for these records, so they have to be eagerly
+  /// deserialized.
+  SmallVector<uint64_t, 64> VTableUses;
+
+  /// \brief A snapshot of the pending instantiations in the chain.
+  ///
+  /// This record tracks the instantiations that Sema has to perform at the
+  /// end of the TU. It consists of a pair of values for every pending
+  /// instantiation where the first value is the ID of the decl and the second
+  /// is the instantiation location.
+  SmallVector<uint64_t, 64> PendingInstantiations;
+
+  //@}
+
+  /// \name DiagnosticsEngine-relevant special data
+  /// \brief Fields containing data that is used for generating diagnostics
+  //@{
+
+  /// \brief A snapshot of Sema's unused file-scoped variable tracking, for
+  /// generating warnings.
+  SmallVector<uint64_t, 16> UnusedFileScopedDecls;
+
+  /// \brief A list of all the delegating constructors we've seen, to diagnose
+  /// cycles.
+  SmallVector<uint64_t, 4> DelegatingCtorDecls;
+
+  /// \brief Method selectors used in a @selector expression. Used for
+  /// implementation of -Wselector.
+  SmallVector<uint64_t, 64> ReferencedSelectorsData;
+
+  /// \brief A snapshot of Sema's weak undeclared identifier tracking, for
+  /// generating warnings.
+  SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
+
+  /// \brief The IDs of type aliases for ext_vectors that exist in the chain.
+  ///
+  /// Used by Sema for finding sugared names for ext_vectors in diagnostics.
+  SmallVector<uint64_t, 4> ExtVectorDecls;
+
+  //@}
+
+  /// \name Sema-relevant special data
+  /// \brief Fields containing data that is used for semantic analysis
+  //@{
+
+  /// \brief The IDs of all locally scoped extern "C" decls in the chain.
+  ///
+  /// Sema tracks these to validate that the types are consistent across all
+  /// local extern "C" declarations.
+  SmallVector<uint64_t, 16> LocallyScopedExternCDecls;
+
+  /// \brief The IDs of all dynamic class declarations in the chain.
+  ///
+  /// Sema tracks these because it checks for the key functions being defined
+  /// at the end of the TU, in which case it directs CodeGen to emit the VTable.
+  SmallVector<uint64_t, 16> DynamicClasses;
+
+  /// \brief The IDs of the declarations Sema stores directly.
+  ///
+  /// Sema tracks a few important decls, such as namespace std, directly.
+  SmallVector<uint64_t, 4> SemaDeclRefs;
+
+  /// \brief The IDs of the types ASTContext stores directly.
+  ///
+  /// The AST context tracks a few important types, such as va_list, directly.
+  SmallVector<uint64_t, 16> SpecialTypes;
+
+  /// \brief The IDs of CUDA-specific declarations ASTContext stores directly.
+  ///
+  /// The AST context tracks a few important decls, currently cudaConfigureCall,
+  /// directly.
+  SmallVector<uint64_t, 2> CUDASpecialDeclRefs;
+
+  /// \brief The floating point pragma option settings.
+  SmallVector<uint64_t, 1> FPPragmaOptions;
+
+  /// \brief The pragma clang optimize location (if the pragma state is "off").
+  SourceLocation OptimizeOffPragmaLocation;
+
+  /// \brief The OpenCL extension settings.
+  SmallVector<uint64_t, 1> OpenCLExtensions;
+
+  /// \brief A list of the namespaces we've seen.
+  SmallVector<uint64_t, 4> KnownNamespaces;
+
+  /// \brief A list of undefined decls with internal linkage followed by the
+  /// SourceLocation of a matching ODR-use.
+  SmallVector<uint64_t, 8> UndefinedButUsed;
+
+  // \brief A list of late parsed template function data.
+  SmallVector<uint64_t, 1> LateParsedTemplates;
+
+  struct ImportedSubmodule {
+    serialization::SubmoduleID ID;
+    SourceLocation ImportLoc;
+
+    ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
+      : ID(ID), ImportLoc(ImportLoc) {}
+  };
+
+  /// \brief A list of modules that were imported by precompiled headers or
+  /// any other non-module AST file.
+  SmallVector<ImportedSubmodule, 2> ImportedModules;
+  //@}
+
+  /// \brief The directory that the PCH we are reading is stored in.
+  std::string CurrentDir;
+
+  /// \brief The system include root to be used when loading the
+  /// precompiled header.
+  std::string isysroot;
+
+  /// \brief Whether to disable the normal validation performed on precompiled
+  /// headers when they are loaded.
+  bool DisableValidation;
+
+  /// \brief Whether to accept an AST file with compiler errors.
+  bool AllowASTWithCompilerErrors;
+
+  /// \brief Whether to accept an AST file that has a different configuration
+  /// from the current compiler instance.
+  bool AllowConfigurationMismatch;
+
+  /// \brief Whether validate system input files.
+  bool ValidateSystemInputs;
+
+  /// \brief Whether we are allowed to use the global module index.
+  bool UseGlobalIndex;
+
+  /// \brief Whether we have tried loading the global module index yet.
+  bool TriedLoadingGlobalIndex;
+
+  typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
+  /// \brief Mapping from switch-case IDs in the chain to switch-case statements
+  ///
+  /// Statements usually don't have IDs, but switch cases need them, so that the
+  /// switch statement can refer to them.
+  SwitchCaseMapTy SwitchCaseStmts;
+
+  SwitchCaseMapTy *CurrSwitchCaseStmts;
+
+  /// \brief The number of source location entries de-serialized from
+  /// the PCH file.
+  unsigned NumSLocEntriesRead;
+
+  /// \brief The number of source location entries in the chain.
+  unsigned TotalNumSLocEntries;
+
+  /// \brief The number of statements (and expressions) de-serialized
+  /// from the chain.
+  unsigned NumStatementsRead;
+
+  /// \brief The total number of statements (and expressions) stored
+  /// in the chain.
+  unsigned TotalNumStatements;
+
+  /// \brief The number of macros de-serialized from the chain.
+  unsigned NumMacrosRead;
+
+  /// \brief The total number of macros stored in the chain.
+  unsigned TotalNumMacros;
+
+  /// \brief The number of lookups into identifier tables.
+  unsigned NumIdentifierLookups;
+
+  /// \brief The number of lookups into identifier tables that succeed.
+  unsigned NumIdentifierLookupHits;
+
+  /// \brief The number of selectors that have been read.
+  unsigned NumSelectorsRead;
+
+  /// \brief The number of method pool entries that have been read.
+  unsigned NumMethodPoolEntriesRead;
+
+  /// \brief The number of times we have looked up a selector in the method
+  /// pool.
+  unsigned NumMethodPoolLookups;
+
+  /// \brief The number of times we have looked up a selector in the method
+  /// pool and found something.
+  unsigned NumMethodPoolHits;
+
+  /// \brief The number of times we have looked up a selector in the method
+  /// pool within a specific module.
+  unsigned NumMethodPoolTableLookups;
+
+  /// \brief The number of times we have looked up a selector in the method
+  /// pool within a specific module and found something.
+  unsigned NumMethodPoolTableHits;
+
+  /// \brief The total number of method pool entries in the selector table.
+  unsigned TotalNumMethodPoolEntries;
+
+  /// Number of lexical decl contexts read/total.
+  unsigned NumLexicalDeclContextsRead, TotalLexicalDeclContexts;
+
+  /// Number of visible decl contexts read/total.
+  unsigned NumVisibleDeclContextsRead, TotalVisibleDeclContexts;
+
+  /// Total size of modules, in bits, currently loaded
+  uint64_t TotalModulesSizeInBits;
+
+  /// \brief Number of Decl/types that are currently deserializing.
+  unsigned NumCurrentElementsDeserializing;
+
+  /// \brief Set true while we are in the process of passing deserialized
+  /// "interesting" decls to consumer inside FinishedDeserializing().
+  /// This is used as a guard to avoid recursively repeating the process of
+  /// passing decls to consumer.
+  bool PassingDeclsToConsumer;
+
+  /// Number of CXX base specifiers currently loaded
+  unsigned NumCXXBaseSpecifiersLoaded;
+
+  /// \brief The set of identifiers that were read while the AST reader was
+  /// (recursively) loading declarations.
+  ///
+  /// The declarations on the identifier chain for these identifiers will be
+  /// loaded once the recursive loading has completed.
+  llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> >
+    PendingIdentifierInfos;
+
+  /// \brief The generation number of each identifier, which keeps track of
+  /// the last time we loaded information about this identifier.
+  llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration;
+  
+  /// \brief Contains declarations and definitions that will be
+  /// "interesting" to the ASTConsumer, when we get that AST consumer.
+  ///
+  /// "Interesting" declarations are those that have data that may
+  /// need to be emitted, such as inline function definitions or
+  /// Objective-C protocols.
+  std::deque<Decl *> InterestingDecls;
+
+  /// \brief The set of redeclarable declarations that have been deserialized
+  /// since the last time the declaration chains were linked.
+  llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized;
+  
+  /// \brief The list of redeclaration chains that still need to be 
+  /// reconstructed.
+  ///
+  /// Each element is the global declaration ID of the first declaration in
+  /// the chain. Elements in this vector should be unique; use 
+  /// PendingDeclChainsKnown to ensure uniqueness.
+  SmallVector<serialization::DeclID, 16> PendingDeclChains;
+
+  /// \brief Keeps track of the elements added to PendingDeclChains.
+  llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
+
+  /// \brief The list of canonical declarations whose redeclaration chains
+  /// need to be marked as incomplete once we're done deserializing things.
+  SmallVector<Decl *, 16> PendingIncompleteDeclChains;
+
+  /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
+  /// been loaded but its DeclContext was not set yet.
+  struct PendingDeclContextInfo {
+    Decl *D;
+    serialization::GlobalDeclID SemaDC;
+    serialization::GlobalDeclID LexicalDC;
+  };
+
+  /// \brief The set of Decls that have been loaded but their DeclContexts are
+  /// not set yet.
+  ///
+  /// The DeclContexts for these Decls will be set once recursive loading has
+  /// been completed.
+  std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
+
+  /// \brief The set of NamedDecls that have been loaded, but are members of a
+  /// context that has been merged into another context where the corresponding
+  /// declaration is either missing or has not yet been loaded.
+  ///
+  /// We will check whether the corresponding declaration is in fact missing
+  /// once recursing loading has been completed.
+  llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks;
+
+  /// \brief Record definitions in which we found an ODR violation.
+  llvm::SmallDenseMap<CXXRecordDecl *, llvm::TinyPtrVector<CXXRecordDecl *>, 2>
+      PendingOdrMergeFailures;
+
+  /// \brief DeclContexts in which we have diagnosed an ODR violation.
+  llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
+
+  /// \brief The set of Objective-C categories that have been deserialized
+  /// since the last time the declaration chains were linked.
+  llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
+
+  /// \brief The set of Objective-C class definitions that have already been
+  /// loaded, for which we will need to check for categories whenever a new
+  /// module is loaded.
+  SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
+
+  /// \brief A mapping from a primary context for a declaration chain to the
+  /// other declarations of that entity that also have name lookup tables.
+  /// Used when we merge together two class definitions that have different
+  /// sets of declared special member functions.
+  llvm::DenseMap<const DeclContext*, SmallVector<const DeclContext*, 2>>
+      MergedLookups;
+
+  typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
+    MergedDeclsMap;
+    
+  /// \brief A mapping from canonical declarations to the set of additional
+  /// (global, previously-canonical) declaration IDs that have been merged with
+  /// that canonical declaration.
+  MergedDeclsMap MergedDecls;
+  
+  typedef llvm::DenseMap<serialization::GlobalDeclID, 
+                         SmallVector<serialization::DeclID, 2> >
+    StoredMergedDeclsMap;
+  
+  /// \brief A mapping from canonical declaration IDs to the set of additional
+  /// declaration IDs that have been merged with that canonical declaration.
+  ///
+  /// This is the deserialized representation of the entries in MergedDecls.
+  /// When we query entries in MergedDecls, they will be augmented with entries
+  /// from StoredMergedDecls.
+  StoredMergedDeclsMap StoredMergedDecls;
+  
+  /// \brief Combine the stored merged declarations for the given canonical
+  /// declaration into the set of merged declarations.
+  ///
+  /// \returns An iterator into MergedDecls that corresponds to the position of
+  /// the given canonical declaration.
+  MergedDeclsMap::iterator
+  combineStoredMergedDecls(Decl *Canon, serialization::GlobalDeclID CanonID);
+
+  /// \brief A mapping from DeclContexts to the semantic DeclContext that we
+  /// are treating as the definition of the entity. This is used, for instance,
+  /// when merging implicit instantiations of class templates across modules.
+  llvm::DenseMap<DeclContext *, DeclContext *> MergedDeclContexts;
+
+  /// \brief A mapping from canonical declarations of enums to their canonical
+  /// definitions. Only populated when using modules in C++.
+  llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions;
+
+  /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
+  SmallVector<Stmt *, 16> StmtStack;
+
+  /// \brief What kind of records we are reading.
+  enum ReadingKind {
+    Read_None, Read_Decl, Read_Type, Read_Stmt
+  };
+
+  /// \brief What kind of records we are reading.
+  ReadingKind ReadingKind;
+
+  /// \brief RAII object to change the reading kind.
+  class ReadingKindTracker {
+    ASTReader &Reader;
+    enum ReadingKind PrevKind;
+
+    ReadingKindTracker(const ReadingKindTracker &) LLVM_DELETED_FUNCTION;
+    void operator=(const ReadingKindTracker &) LLVM_DELETED_FUNCTION;
+
+  public:
+    ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader)
+      : Reader(reader), PrevKind(Reader.ReadingKind) {
+      Reader.ReadingKind = newKind;
+    }
+
+    ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; }
+  };
+
+  /// \brief Suggested contents of the predefines buffer, after this
+  /// PCH file has been processed.
+  ///
+  /// In most cases, this string will be empty, because the predefines
+  /// buffer computed to build the PCH file will be identical to the
+  /// predefines buffer computed from the command line. However, when
+  /// there are differences that the PCH reader can work around, this
+  /// predefines buffer may contain additional definitions.
+  std::string SuggestedPredefines;
+
+  /// \brief Reads a statement from the specified cursor.
+  Stmt *ReadStmtFromStream(ModuleFile &F);
+
+  struct InputFileInfo {
+    std::string Filename;
+    off_t StoredSize;
+    time_t StoredTime;
+    bool Overridden;
+  };
+
+  /// \brief Reads the stored information about an input file.
+  InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
+  /// \brief A convenience method to read the filename from an input file.
+  std::string getInputFileName(ModuleFile &F, unsigned ID);
+
+  /// \brief Retrieve the file entry and 'overridden' bit for an input
+  /// file in the given module file.
+  serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
+                                        bool Complain = true);
+
+  /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take
+  /// into account all the necessary relocations.
+  const FileEntry *getFileEntry(StringRef filename);
+
+  void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename);
+
+  struct ImportedModule {
+    ModuleFile *Mod;
+    ModuleFile *ImportedBy;
+    SourceLocation ImportLoc;
+
+    ImportedModule(ModuleFile *Mod,
+                   ModuleFile *ImportedBy,
+                   SourceLocation ImportLoc)
+      : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { }
+  };
+
+  ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type,
+                            SourceLocation ImportLoc, ModuleFile *ImportedBy,
+                            SmallVectorImpl<ImportedModule> &Loaded,
+                            off_t ExpectedSize, time_t ExpectedModTime,
+                            unsigned ClientLoadCapabilities);
+  ASTReadResult ReadControlBlock(ModuleFile &F,
+                                 SmallVectorImpl<ImportedModule> &Loaded,
+                                 const ModuleFile *ImportedBy,
+                                 unsigned ClientLoadCapabilities);
+  ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
+  bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
+  bool ReadSourceManagerBlock(ModuleFile &F);
+  llvm::BitstreamCursor &SLocCursorForID(int ID);
+  SourceLocation getImportLocation(ModuleFile *F);
+  ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
+                                   unsigned ClientLoadCapabilities);
+  static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
+                                   ASTReaderListener &Listener);
+  static bool ParseTargetOptions(const RecordData &Record, bool Complain,
+                                 ASTReaderListener &Listener);
+  static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain,
+                                     ASTReaderListener &Listener);
+  static bool ParseFileSystemOptions(const RecordData &Record, bool Complain,
+                                     ASTReaderListener &Listener);
+  static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
+                                       ASTReaderListener &Listener);
+  static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain,
+                                       ASTReaderListener &Listener,
+                                       std::string &SuggestedPredefines);
+
+  struct RecordLocation {
+    RecordLocation(ModuleFile *M, uint64_t O)
+      : F(M), Offset(O) {}
+    ModuleFile *F;
+    uint64_t Offset;
+  };
+
+  QualType readTypeRecord(unsigned Index);
+  void readExceptionSpec(ModuleFile &ModuleFile,
+                         SmallVectorImpl<QualType> &ExceptionStorage,
+                         FunctionProtoType::ExtProtoInfo &EPI,
+                         const RecordData &Record, unsigned &Index);
+  RecordLocation TypeCursorForIndex(unsigned Index);
+  void LoadedDecl(unsigned Index, Decl *D);
+  Decl *ReadDeclRecord(serialization::DeclID ID);
+  void markIncompleteDeclChain(Decl *Canon);
+  RecordLocation DeclCursorForID(serialization::DeclID ID,
+                                 unsigned &RawLocation);
+  void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
+  void loadPendingDeclChain(serialization::GlobalDeclID ID);
+  void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D,
+                          unsigned PreviousGeneration = 0);
+
+  RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
+  uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset);
+
+  /// \brief Returns the first preprocessed entity ID that begins or ends after
+  /// \arg Loc.
+  serialization::PreprocessedEntityID
+  findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
+
+  /// \brief Find the next module that contains entities and return the ID
+  /// of the first entry.
+  ///
+  /// \param SLocMapI points at a chunk of a module that contains no
+  /// preprocessed entities or the entities it contains are not the
+  /// ones we are looking for.
+  serialization::PreprocessedEntityID
+    findNextPreprocessedEntity(
+                        GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
+
+  /// \brief Returns (ModuleFile, Local index) pair for \p GlobalIndex of a
+  /// preprocessed entity.
+  std::pair<ModuleFile *, unsigned>
+    getModulePreprocessedEntity(unsigned GlobalIndex);
+
+  /// \brief Returns (begin, end) pair for the preprocessed entities of a
+  /// particular module.
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    getModulePreprocessedEntities(ModuleFile &Mod) const;
+
+  class ModuleDeclIterator {
+    ASTReader *Reader;
+    ModuleFile *Mod;
+    const serialization::LocalDeclID *Pos;
+
+  public:
+    typedef const Decl *value_type;
+    typedef value_type&         reference;
+    typedef value_type*         pointer;
+
+    ModuleDeclIterator() : Reader(nullptr), Mod(nullptr), Pos(nullptr) { }
+
+    ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
+                       const serialization::LocalDeclID *Pos)
+      : Reader(Reader), Mod(Mod), Pos(Pos) { }
+
+    value_type operator*() const {
+      return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *Pos));
+    }
+
+    ModuleDeclIterator &operator++() {
+      ++Pos;
+      return *this;
+    }
+
+    ModuleDeclIterator operator++(int) {
+      ModuleDeclIterator Prev(*this);
+      ++Pos;
+      return Prev;
+    }
+
+    ModuleDeclIterator &operator--() {
+      --Pos;
+      return *this;
+    }
+
+    ModuleDeclIterator operator--(int) {
+      ModuleDeclIterator Prev(*this);
+      --Pos;
+      return Prev;
+    }
+
+    friend bool operator==(const ModuleDeclIterator &LHS,
+                           const ModuleDeclIterator &RHS) {
+      assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod);
+      return LHS.Pos == RHS.Pos;
+    }
+
+    friend bool operator!=(const ModuleDeclIterator &LHS,
+                           const ModuleDeclIterator &RHS) {
+      assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod);
+      return LHS.Pos != RHS.Pos;
+    }
+  };
+
+  std::pair<ModuleDeclIterator, ModuleDeclIterator>
+    getModuleFileLevelDecls(ModuleFile &Mod);
+
+  void PassInterestingDeclsToConsumer();
+  void PassInterestingDeclToConsumer(Decl *D);
+
+  void finishPendingActions();
+
+  void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
+
+  void addPendingDeclContextInfo(Decl *D,
+                                 serialization::GlobalDeclID SemaDC,
+                                 serialization::GlobalDeclID LexicalDC) {
+    assert(D);
+    PendingDeclContextInfo Info = { D, SemaDC, LexicalDC };
+    PendingDeclContextInfos.push_back(Info);
+  }
+
+  /// \brief Produce an error diagnostic and return true.
+  ///
+  /// This routine should only be used for fatal errors that have to
+  /// do with non-routine failures (e.g., corrupted AST file).
+  void Error(StringRef Msg);
+  void Error(unsigned DiagID, StringRef Arg1 = StringRef(),
+             StringRef Arg2 = StringRef());
+
+  ASTReader(const ASTReader &) LLVM_DELETED_FUNCTION;
+  void operator=(const ASTReader &) LLVM_DELETED_FUNCTION;
+public:
+  /// \brief Load the AST file and validate its contents against the given
+  /// Preprocessor.
+  ///
+  /// \param PP the preprocessor associated with the context in which this
+  /// precompiled header will be loaded.
+  ///
+  /// \param Context the AST context that this precompiled header will be
+  /// loaded into.
+  ///
+  /// \param isysroot If non-NULL, the system include path specified by the
+  /// user. This is only used with relocatable PCH files. If non-NULL,
+  /// a relocatable PCH file will use the default path "/".
+  ///
+  /// \param DisableValidation If true, the AST reader will suppress most
+  /// of its regular consistency checking, allowing the use of precompiled
+  /// headers that cannot be determined to be compatible.
+  ///
+  /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
+  /// AST file the was created out of an AST with compiler errors,
+  /// otherwise it will reject it.
+  ///
+  /// \param AllowConfigurationMismatch If true, the AST reader will not check
+  /// for configuration differences between the AST file and the invocation.
+  ///
+  /// \param ValidateSystemInputs If true, the AST reader will validate
+  /// system input files in addition to user input files. This is only
+  /// meaningful if \p DisableValidation is false.
+  ///
+  /// \param UseGlobalIndex If true, the AST reader will try to load and use
+  /// the global module index.
+  ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
+            bool DisableValidation = false,
+            bool AllowASTWithCompilerErrors = false,
+            bool AllowConfigurationMismatch = false,
+            bool ValidateSystemInputs = false,
+            bool UseGlobalIndex = true);
+
+  ~ASTReader();
+
+  SourceManager &getSourceManager() const { return SourceMgr; }
+  FileManager &getFileManager() const { return FileMgr; }
+
+  /// \brief Flags that indicate what kind of AST loading failures the client
+  /// of the AST reader can directly handle.
+  ///
+  /// When a client states that it can handle a particular kind of failure,
+  /// the AST reader will not emit errors when producing that kind of failure.
+  enum LoadFailureCapabilities {
+    /// \brief The client can't handle any AST loading failures.
+    ARR_None = 0,
+    /// \brief The client can handle an AST file that cannot load because it
+    /// is missing.
+    ARR_Missing = 0x1,
+    /// \brief The client can handle an AST file that cannot load because it
+    /// is out-of-date relative to its input files.
+    ARR_OutOfDate = 0x2,
+    /// \brief The client can handle an AST file that cannot load because it
+    /// was built with a different version of Clang.
+    ARR_VersionMismatch = 0x4,
+    /// \brief The client can handle an AST file that cannot load because it's
+    /// compiled configuration doesn't match that of the context it was
+    /// loaded into.
+    ARR_ConfigurationMismatch = 0x8
+  };
+
+  /// \brief Load the AST file designated by the given file name.
+  ///
+  /// \param FileName The name of the AST file to load.
+  ///
+  /// \param Type The kind of AST being loaded, e.g., PCH, module, main file,
+  /// or preamble.
+  ///
+  /// \param ImportLoc the location where the module file will be considered as
+  /// imported from. For non-module AST types it should be invalid.
+  ///
+  /// \param ClientLoadCapabilities The set of client load-failure
+  /// capabilities, represented as a bitset of the enumerators of
+  /// LoadFailureCapabilities.
+  ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type,
+                        SourceLocation ImportLoc,
+                        unsigned ClientLoadCapabilities);
+
+  /// \brief Make the entities in the given module and any of its (non-explicit)
+  /// submodules visible to name lookup.
+  ///
+  /// \param Mod The module whose names should be made visible.
+  ///
+  /// \param NameVisibility The level of visibility to give the names in the
+  /// module.  Visibility can only be increased over time.
+  ///
+  /// \param ImportLoc The location at which the import occurs.
+  ///
+  /// \param Complain Whether to complain about conflicting module imports.
+  void makeModuleVisible(Module *Mod,
+                         Module::NameVisibilityKind NameVisibility,
+                         SourceLocation ImportLoc,
+                         bool Complain);
+
+  /// \brief Make the names within this set of hidden names visible.
+  void makeNamesVisible(const HiddenNames &Names, Module *Owner,
+                        bool FromFinalization);
+
+  /// \brief Set the AST callbacks listener.
+  void setListener(ASTReaderListener *listener) {
+    Listener.reset(listener);
+  }
+
+  /// \brief Add an AST callbak listener.
+  ///
+  /// Takes ownership of \p L.
+  void addListener(ASTReaderListener *L) {
+    if (Listener)
+      L = new ChainedASTReaderListener(L, Listener.release());
+    Listener.reset(L);
+  }
+
+  /// \brief Set the AST deserialization listener.
+  void setDeserializationListener(ASTDeserializationListener *Listener,
+                                  bool TakeOwnership = false);
+
+  /// \brief Determine whether this AST reader has a global index.
+  bool hasGlobalIndex() const { return (bool)GlobalIndex; }
+
+  /// \brief Return global module index.
+  GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
+
+  /// \brief Reset reader for a reload try.
+  void resetForReload() { TriedLoadingGlobalIndex = false; }
+
+  /// \brief Attempts to load the global index.
+  ///
+  /// \returns true if loading the global index has failed for any reason.
+  bool loadGlobalIndex();
+
+  /// \brief Determine whether we tried to load the global index, but failed,
+  /// e.g., because it is out-of-date or does not exist.
+  bool isGlobalIndexUnavailable() const;
+  
+  /// \brief Initializes the ASTContext
+  void InitializeContext();
+
+  /// \brief Update the state of Sema after loading some additional modules.
+  void UpdateSema();
+
+  /// \brief Add in-memory (virtual file) buffer.
+  void addInMemoryBuffer(StringRef &FileName, llvm::MemoryBuffer *Buffer) {
+    ModuleMgr.addInMemoryBuffer(FileName, Buffer);
+  }
+
+  /// \brief Finalizes the AST reader's state before writing an AST file to
+  /// disk.
+  ///
+  /// This operation may undo temporary state in the AST that should not be
+  /// emitted.
+  void finalizeForWriting();
+
+  /// \brief Retrieve the module manager.
+  ModuleManager &getModuleManager() { return ModuleMgr; }
+
+  /// \brief Retrieve the preprocessor.
+  Preprocessor &getPreprocessor() const { return PP; }
+
+  /// \brief Retrieve the name of the original source file name for the primary
+  /// module file.
+  StringRef getOriginalSourceFile() {
+    return ModuleMgr.getPrimaryModule().OriginalSourceFileName; 
+  }
+
+  /// \brief Retrieve the name of the original source file name directly from
+  /// the AST file, without actually loading the AST file.
+  static std::string getOriginalSourceFile(const std::string &ASTFileName,
+                                           FileManager &FileMgr,
+                                           DiagnosticsEngine &Diags);
+
+  /// \brief Read the control block for the named AST file.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  static bool readASTFileControlBlock(StringRef Filename,
+                                      FileManager &FileMgr,
+                                      ASTReaderListener &Listener);
+
+  /// \brief Determine whether the given AST file is acceptable to load into a
+  /// translation unit with the given language and target options.
+  static bool isAcceptableASTFile(StringRef Filename,
+                                  FileManager &FileMgr,
+                                  const LangOptions &LangOpts,
+                                  const TargetOptions &TargetOpts,
+                                  const PreprocessorOptions &PPOpts);
+
+  /// \brief Returns the suggested contents of the predefines buffer,
+  /// which contains a (typically-empty) subset of the predefines
+  /// build prior to including the precompiled header.
+  const std::string &getSuggestedPredefines() { return SuggestedPredefines; }
+
+  /// \brief Read a preallocated preprocessed entity from the external source.
+  ///
+  /// \returns null if an error occurred that prevented the preprocessed
+  /// entity from being loaded.
+  PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) override;
+
+  /// \brief Returns a pair of [Begin, End) indices of preallocated
+  /// preprocessed entities that \p Range encompasses.
+  std::pair<unsigned, unsigned>
+      findPreprocessedEntitiesInRange(SourceRange Range) override;
+
+  /// \brief Optionally returns true or false if the preallocated preprocessed
+  /// entity with index \p Index came from file \p FID.
+  Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+                                              FileID FID) override;
+
+  /// \brief Read the header file information for the given file entry.
+  HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
+
+  void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
+
+  /// \brief Returns the number of source locations found in the chain.
+  unsigned getTotalNumSLocs() const {
+    return TotalNumSLocEntries;
+  }
+
+  /// \brief Returns the number of identifiers found in the chain.
+  unsigned getTotalNumIdentifiers() const {
+    return static_cast<unsigned>(IdentifiersLoaded.size());
+  }
+
+  /// \brief Returns the number of macros found in the chain.
+  unsigned getTotalNumMacros() const {
+    return static_cast<unsigned>(MacrosLoaded.size());
+  }
+
+  /// \brief Returns the number of types found in the chain.
+  unsigned getTotalNumTypes() const {
+    return static_cast<unsigned>(TypesLoaded.size());
+  }
+
+  /// \brief Returns the number of declarations found in the chain.
+  unsigned getTotalNumDecls() const {
+    return static_cast<unsigned>(DeclsLoaded.size());
+  }
+
+  /// \brief Returns the number of submodules known.
+  unsigned getTotalNumSubmodules() const {
+    return static_cast<unsigned>(SubmodulesLoaded.size());
+  }
+  
+  /// \brief Returns the number of selectors found in the chain.
+  unsigned getTotalNumSelectors() const {
+    return static_cast<unsigned>(SelectorsLoaded.size());
+  }
+
+  /// \brief Returns the number of preprocessed entities known to the AST
+  /// reader.
+  unsigned getTotalNumPreprocessedEntities() const {
+    unsigned Result = 0;
+    for (ModuleConstIterator I = ModuleMgr.begin(),
+        E = ModuleMgr.end(); I != E; ++I) {
+      Result += (*I)->NumPreprocessedEntities;
+    }
+
+    return Result;
+  }
+
+  /// \brief Returns the number of C++ base specifiers found in the chain.
+  unsigned getTotalNumCXXBaseSpecifiers() const {
+    return NumCXXBaseSpecifiersLoaded;
+  }
+
+  /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+  /// given TemplateArgument kind.
+  TemplateArgumentLocInfo
+  GetTemplateArgumentLocInfo(ModuleFile &F, TemplateArgument::ArgKind Kind,
+                             const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads a TemplateArgumentLoc.
+  TemplateArgumentLoc
+  ReadTemplateArgumentLoc(ModuleFile &F,
+                          const RecordData &Record, unsigned &Idx);
+
+  const ASTTemplateArgumentListInfo*
+  ReadASTTemplateArgumentListInfo(ModuleFile &F,
+                                  const RecordData &Record, unsigned &Index);
+
+  /// \brief Reads a declarator info from the given record.
+  TypeSourceInfo *GetTypeSourceInfo(ModuleFile &F,
+                                    const RecordData &Record, unsigned &Idx);
+
+  /// \brief Resolve a type ID into a type, potentially building a new
+  /// type.
+  QualType GetType(serialization::TypeID ID);
+
+  /// \brief Resolve a local type ID within a given AST file into a type.
+  QualType getLocalType(ModuleFile &F, unsigned LocalID);
+
+  /// \brief Map a local type ID within a given AST file into a global type ID.
+  serialization::TypeID getGlobalTypeID(ModuleFile &F, unsigned LocalID) const;
+
+  /// \brief Read a type from the current position in the given record, which
+  /// was read from the given AST file.
+  QualType readType(ModuleFile &F, const RecordData &Record, unsigned &Idx) {
+    if (Idx >= Record.size())
+      return QualType();
+
+    return getLocalType(F, Record[Idx++]);
+  }
+
+  /// \brief Map from a local declaration ID within a given module to a
+  /// global declaration ID.
+  serialization::DeclID getGlobalDeclID(ModuleFile &F,
+                                      serialization::LocalDeclID LocalID) const;
+
+  /// \brief Returns true if global DeclID \p ID originated from module \p M.
+  bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const;
+
+  /// \brief Retrieve the module file that owns the given declaration, or NULL
+  /// if the declaration is not from a module file.
+  ModuleFile *getOwningModuleFile(const Decl *D);
+
+  /// \brief Get the best name we know for the module that owns the given
+  /// declaration, or an empty string if the declaration is not from a module.
+  std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
+  /// \brief Returns the source location for the decl \p ID.
+  SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
+
+  /// \brief Resolve a declaration ID into a declaration, potentially
+  /// building a new declaration.
+  Decl *GetDecl(serialization::DeclID ID);
+  Decl *GetExternalDecl(uint32_t ID) override;
+
+  /// \brief Resolve a declaration ID into a declaration. Return 0 if it's not
+  /// been loaded yet.
+  Decl *GetExistingDecl(serialization::DeclID ID);
+
+  /// \brief Reads a declaration with the given local ID in the given module.
+  Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) {
+    return GetDecl(getGlobalDeclID(F, LocalID));
+  }
+
+  /// \brief Reads a declaration with the given local ID in the given module.
+  ///
+  /// \returns The requested declaration, casted to the given return type.
+  template<typename T>
+  T *GetLocalDeclAs(ModuleFile &F, uint32_t LocalID) {
+    return cast_or_null<T>(GetLocalDecl(F, LocalID));
+  }
+
+  /// \brief Map a global declaration ID into the declaration ID used to 
+  /// refer to this declaration within the given module fule.
+  ///
+  /// \returns the global ID of the given declaration as known in the given
+  /// module file.
+  serialization::DeclID 
+  mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
+                                  serialization::DeclID GlobalID);
+  
+  /// \brief Reads a declaration ID from the given position in a record in the
+  /// given module.
+  ///
+  /// \returns The declaration ID read from the record, adjusted to a global ID.
+  serialization::DeclID ReadDeclID(ModuleFile &F, const RecordData &Record,
+                                   unsigned &Idx);
+
+  /// \brief Reads a declaration from the given position in a record in the
+  /// given module.
+  Decl *ReadDecl(ModuleFile &F, const RecordData &R, unsigned &I) {
+    return GetDecl(ReadDeclID(F, R, I));
+  }
+
+  /// \brief Reads a declaration from the given position in a record in the
+  /// given module.
+  ///
+  /// \returns The declaration read from this location, casted to the given
+  /// result type.
+  template<typename T>
+  T *ReadDeclAs(ModuleFile &F, const RecordData &R, unsigned &I) {
+    return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
+  }
+
+  /// \brief If any redeclarations of \p D have been imported since it was
+  /// last checked, this digs out those redeclarations and adds them to the
+  /// redeclaration chain for \p D.
+  void CompleteRedeclChain(const Decl *D) override;
+
+  /// \brief Read a CXXBaseSpecifiers ID form the given record and
+  /// return its global bit offset.
+  uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
+                                 unsigned &Idx);
+
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
+
+  /// \brief Resolve the offset of a statement into a statement.
+  ///
+  /// This operation will read a new statement from the external
+  /// source each time it is called, and is meant to be used via a
+  /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
+
+  /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
+  /// specified cursor.  Read the abbreviations that are at the top of the block
+  /// and then leave the cursor pointing into the block.
+  bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID);
+
+  /// \brief Finds all the visible declarations with a given name.
+  /// The current implementation of this method just loads the entire
+  /// lookup table as unmaterialized references.
+  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                      DeclarationName Name) override;
+
+  /// \brief Read all of the declarations lexically stored in a
+  /// declaration context.
+  ///
+  /// \param DC The declaration context whose declarations will be
+  /// read.
+  ///
+  /// \param Decls Vector that will contain the declarations loaded
+  /// from the external source. The caller is responsible for merging
+  /// these declarations with any declarations already stored in the
+  /// declaration context.
+  ///
+  /// \returns true if there was an error while reading the
+  /// declarations for this declaration context.
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                bool (*isKindWeWant)(Decl::Kind),
+                                SmallVectorImpl<Decl*> &Decls) override;
+
+  /// \brief Get the decls that are contained in a file in the Offset/Length
+  /// range. \p Length can be 0 to indicate a point at \p Offset instead of
+  /// a range.
+  void FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls) override;
+
+  /// \brief Notify ASTReader that we started deserialization of
+  /// a decl or type so until FinishedDeserializing is called there may be
+  /// decls that are initializing. Must be paired with FinishedDeserializing.
+  void StartedDeserializing() override { ++NumCurrentElementsDeserializing; }
+
+  /// \brief Notify ASTReader that we finished the deserialization of
+  /// a decl or type. Must be paired with StartedDeserializing.
+  void FinishedDeserializing() override;
+
+  /// \brief Function that will be invoked when we begin parsing a new
+  /// translation unit involving this external AST source.
+  ///
+  /// This function will provide all of the external definitions to
+  /// the ASTConsumer.
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
+
+  /// \brief Print some statistics about AST usage.
+  void PrintStats() override;
+
+  /// \brief Dump information about the AST reader to standard error.
+  void dump();
+
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
+
+  /// \brief Initialize the semantic source with the Sema instance
+  /// being used to perform semantic analysis on the abstract syntax
+  /// tree.
+  void InitializeSema(Sema &S) override;
+
+  /// \brief Inform the semantic consumer that Sema is no longer available.
+  void ForgetSema() override { SemaObj = nullptr; }
+
+  /// \brief Retrieve the IdentifierInfo for the named identifier.
+  ///
+  /// This routine builds a new IdentifierInfo for the given identifier. If any
+  /// declarations with this name are visible from translation unit scope, their
+  /// declarations will be deserialized and introduced into the declaration
+  /// chain of the identifier.
+  virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
+  IdentifierInfo *get(StringRef Name) override {
+    return get(Name.begin(), Name.end());
+  }
+
+  /// \brief Retrieve an iterator into the set of all identifiers
+  /// in all loaded AST files.
+  IdentifierIterator *getIdentifiers() override;
+
+  /// \brief Load the contents of the global method pool for a given
+  /// selector.
+  void ReadMethodPool(Selector Sel) override;
+
+  /// \brief Load the set of namespaces that are known to the external source,
+  /// which will be used during typo correction.
+  void ReadKnownNamespaces(
+                         SmallVectorImpl<NamespaceDecl *> &Namespaces) override;
+
+  void ReadUndefinedButUsed(
+               llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override;
+
+  void ReadTentativeDefinitions(
+                            SmallVectorImpl<VarDecl *> &TentativeDefs) override;
+
+  void ReadUnusedFileScopedDecls(
+                       SmallVectorImpl<const DeclaratorDecl *> &Decls) override;
+
+  void ReadDelegatingConstructors(
+                         SmallVectorImpl<CXXConstructorDecl *> &Decls) override;
+
+  void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override;
+
+  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override;
+
+  void ReadLocallyScopedExternCDecls(
+                                  SmallVectorImpl<NamedDecl *> &Decls) override;
+
+  void ReadReferencedSelectors(
+          SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
+
+  void ReadWeakUndeclaredIdentifiers(
+          SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override;
+
+  void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
+
+  void ReadPendingInstantiations(
+                 SmallVectorImpl<std::pair<ValueDecl *,
+                                           SourceLocation> > &Pending) override;
+
+  void ReadLateParsedTemplates(
+                         llvm::DenseMap<const FunctionDecl *,
+                                        LateParsedTemplate *> &LPTMap) override;
+
+  /// \brief Load a selector from disk, registering its ID if it exists.
+  void LoadSelector(Selector Sel);
+
+  void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
+  void SetGloballyVisibleDecls(IdentifierInfo *II,
+                               const SmallVectorImpl<uint32_t> &DeclIDs,
+                               SmallVectorImpl<Decl *> *Decls = nullptr);
+
+  /// \brief Report a diagnostic.
+  DiagnosticBuilder Diag(unsigned DiagID);
+
+  /// \brief Report a diagnostic.
+  DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+
+  IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);
+
+  IdentifierInfo *GetIdentifierInfo(ModuleFile &M, const RecordData &Record,
+                                    unsigned &Idx) {
+    return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++]));
+  }
+
+  IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) override {
+    // Note that we are loading an identifier.
+    Deserializing AnIdentifier(this);
+
+    return DecodeIdentifierInfo(ID);
+  }
+
+  IdentifierInfo *getLocalIdentifier(ModuleFile &M, unsigned LocalID);
+
+  serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
+                                                    unsigned LocalID);
+
+  ModuleMacroInfo *getModuleMacro(const PendingMacroInfo &PMInfo);
+
+  void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
+
+  void installPCHMacroDirectives(IdentifierInfo *II,
+                                 ModuleFile &M, uint64_t Offset);
+
+  void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+                            Module *Owner, bool FromFinalization);
+
+  typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
+  llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
+
+  void
+  removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
+                         ArrayRef<serialization::SubmoduleID> Overrides);
+
+  AmbiguousMacros *
+  removeOverriddenMacros(IdentifierInfo *II,
+                         ArrayRef<serialization::SubmoduleID> Overrides);
+
+  /// \brief Retrieve the macro with the given ID.
+  MacroInfo *getMacro(serialization::MacroID ID);
+
+  /// \brief Retrieve the global macro ID corresponding to the given local
+  /// ID within the given module file.
+  serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID);
+
+  /// \brief Read the source location entry with index ID.
+  bool ReadSLocEntry(int ID) override;
+
+  /// \brief Retrieve the module import location and module name for the
+  /// given source manager entry ID.
+  std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) override;
+
+  /// \brief Retrieve the global submodule ID given a module and its local ID
+  /// number.
+  serialization::SubmoduleID 
+  getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);
+  
+  /// \brief Retrieve the submodule that corresponds to a global submodule ID.
+  ///
+  Module *getSubmodule(serialization::SubmoduleID GlobalID);
+
+  /// \brief Retrieve the module that corresponds to the given module ID.
+  ///
+  /// Note: overrides method in ExternalASTSource
+  Module *getModule(unsigned ID) override;
+
+  /// \brief Retrieve a selector from the given module with its local ID
+  /// number.
+  Selector getLocalSelector(ModuleFile &M, unsigned LocalID);
+
+  Selector DecodeSelector(serialization::SelectorID Idx);
+
+  Selector GetExternalSelector(serialization::SelectorID ID) override;
+  uint32_t GetNumExternalSelectors() override;
+
+  Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) {
+    return getLocalSelector(M, Record[Idx++]);
+  }
+
+  /// \brief Retrieve the global selector ID that corresponds to this
+  /// the local selector ID in a given module.
+  serialization::SelectorID getGlobalSelectorID(ModuleFile &F,
+                                                unsigned LocalID) const;
+
+  /// \brief Read a declaration name.
+  DeclarationName ReadDeclarationName(ModuleFile &F,
+                                      const RecordData &Record, unsigned &Idx);
+  void ReadDeclarationNameLoc(ModuleFile &F,
+                              DeclarationNameLoc &DNLoc, DeclarationName Name,
+                              const RecordData &Record, unsigned &Idx);
+  void ReadDeclarationNameInfo(ModuleFile &F, DeclarationNameInfo &NameInfo,
+                               const RecordData &Record, unsigned &Idx);
+
+  void ReadQualifierInfo(ModuleFile &F, QualifierInfo &Info,
+                         const RecordData &Record, unsigned &Idx);
+
+  NestedNameSpecifier *ReadNestedNameSpecifier(ModuleFile &F,
+                                               const RecordData &Record,
+                                               unsigned &Idx);
+
+  NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(ModuleFile &F,
+                                                    const RecordData &Record,
+                                                    unsigned &Idx);
+
+  /// \brief Read a template name.
+  TemplateName ReadTemplateName(ModuleFile &F, const RecordData &Record,
+                                unsigned &Idx);
+
+  /// \brief Read a template argument.
+  TemplateArgument ReadTemplateArgument(ModuleFile &F,
+                                        const RecordData &Record,unsigned &Idx);
+
+  /// \brief Read a template parameter list.
+  TemplateParameterList *ReadTemplateParameterList(ModuleFile &F,
+                                                   const RecordData &Record,
+                                                   unsigned &Idx);
+
+  /// \brief Read a template argument array.
+  void
+  ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
+                           ModuleFile &F, const RecordData &Record,
+                           unsigned &Idx);
+
+  /// \brief Read a UnresolvedSet structure.
+  void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set,
+                         const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a C++ base specifier.
+  CXXBaseSpecifier ReadCXXBaseSpecifier(ModuleFile &F,
+                                        const RecordData &Record,unsigned &Idx);
+
+  /// \brief Read a CXXCtorInitializer array.
+  std::pair<CXXCtorInitializer **, unsigned>
+  ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
+                          unsigned &Idx);
+
+  /// \brief Read a source location from raw form.
+  SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) const {
+    SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw);
+    assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != ModuleFile.SLocRemap.end() &&
+           "Cannot find offset to remap.");
+    int Remap = ModuleFile.SLocRemap.find(Loc.getOffset())->second;
+    return Loc.getLocWithOffset(Remap);
+  }
+
+  /// \brief Read a source location.
+  SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
+                                    const RecordDataImpl &Record,
+                                    unsigned &Idx) {
+    return ReadSourceLocation(ModuleFile, Record[Idx++]);
+  }
+
+  /// \brief Read a source range.
+  SourceRange ReadSourceRange(ModuleFile &F,
+                              const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read an integral value
+  llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a signed integral value
+  llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a floating-point value
+  llvm::APFloat ReadAPFloat(const RecordData &Record,
+                            const llvm::fltSemantics &Sem, unsigned &Idx);
+
+  // \brief Read a string
+  static std::string ReadString(const RecordData &Record, unsigned &Idx);
+
+  /// \brief Read a version tuple.
+  static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx);
+
+  CXXTemporary *ReadCXXTemporary(ModuleFile &F, const RecordData &Record,
+                                 unsigned &Idx);
+
+  /// \brief Reads attributes from the current stream position.
+  void ReadAttributes(ModuleFile &F, AttrVec &Attrs,
+                      const RecordData &Record, unsigned &Idx);
+
+  /// \brief Reads a statement.
+  Stmt *ReadStmt(ModuleFile &F);
+
+  /// \brief Reads an expression.
+  Expr *ReadExpr(ModuleFile &F);
+
+  /// \brief Reads a sub-statement operand during statement reading.
+  Stmt *ReadSubStmt() {
+    assert(ReadingKind == Read_Stmt &&
+           "Should be called only during statement reading!");
+    // Subexpressions are stored from last to first, so the next Stmt we need
+    // is at the back of the stack.
+    assert(!StmtStack.empty() && "Read too many sub-statements!");
+    return StmtStack.pop_back_val();
+  }
+
+  /// \brief Reads a sub-expression operand during statement reading.
+  Expr *ReadSubExpr();
+
+  /// \brief Reads a token out of a record.
+  Token ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx);
+
+  /// \brief Reads the macro record located at the given offset.
+  MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
+
+  /// \brief Determine the global preprocessed entity ID that corresponds to
+  /// the given local ID within the given module.
+  serialization::PreprocessedEntityID
+  getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const;
+
+  /// \brief Add a macro to resolve imported from a module.
+  ///
+  /// \param II The name of the macro.
+  /// \param M The module file.
+  /// \param GMacID The global macro ID that is associated with this identifier.
+  void addPendingMacroFromModule(IdentifierInfo *II,
+                                 ModuleFile *M,
+                                 serialization::GlobalMacroID GMacID,
+                                 ArrayRef<serialization::SubmoduleID>);
+
+  /// \brief Add a macro to deserialize its macro directive history from a PCH.
+  ///
+  /// \param II The name of the macro.
+  /// \param M The module file.
+  /// \param MacroDirectivesOffset Offset of the serialized macro directive
+  /// history.
+  void addPendingMacroFromPCH(IdentifierInfo *II,
+                              ModuleFile *M, uint64_t MacroDirectivesOffset);
+
+  /// \brief Read the set of macros defined by this external macro source.
+  void ReadDefinedMacros() override;
+
+  /// \brief Update an out-of-date identifier.
+  void updateOutOfDateIdentifier(IdentifierInfo &II) override;
+
+  /// \brief Note that this identifier is up-to-date.
+  void markIdentifierUpToDate(IdentifierInfo *II);
+
+  /// \brief Load all external visible decls in the given DeclContext.
+  void completeVisibleDeclsMap(const DeclContext *DC) override;
+
+  /// \brief Retrieve the AST context that this AST reader supplements.
+  ASTContext &getContext() { return Context; }
+
+  // \brief Contains declarations that were loaded before we have
+  // access to a Sema object.
+  SmallVector<NamedDecl *, 16> PreloadedDecls;
+
+  /// \brief Retrieve the semantic analysis object used to analyze the
+  /// translation unit in which the precompiled header is being
+  /// imported.
+  Sema *getSema() { return SemaObj; }
+
+  /// \brief Retrieve the identifier table associated with the
+  /// preprocessor.
+  IdentifierTable &getIdentifierTable();
+
+  /// \brief Record that the given ID maps to the given switch-case
+  /// statement.
+  void RecordSwitchCaseID(SwitchCase *SC, unsigned ID);
+
+  /// \brief Retrieve the switch-case statement with the given ID.
+  SwitchCase *getSwitchCaseWithID(unsigned ID);
+
+  void ClearSwitchCaseIDs();
+
+  /// \brief Cursors for comments blocks.
+  SmallVector<std::pair<llvm::BitstreamCursor,
+                        serialization::ModuleFile *>, 8> CommentsCursors;
+
+  //RIDErief Loads comments ranges.
+  void ReadComments() override;
+};
+
+/// \brief Helper class that saves the current stream position and
+/// then restores it when destroyed.
+struct SavedStreamPosition {
+  explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
+    : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+
+  ~SavedStreamPosition() {
+    Cursor.JumpToBit(Offset);
+  }
+
+private:
+  llvm::BitstreamCursor &Cursor;
+  uint64_t Offset;
+};
+
+inline void PCHValidator::Error(const char *Msg) {
+  Reader.Error(Msg);
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
new file mode 100644
index 0000000..ad6ecdd
--- /dev/null
+++ b/include/clang/Serialization/ASTWriter.h
@@ -0,0 +1,815 @@
+//===--- ASTWriter.h - AST File Writer --------------------------*- 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 ASTWriter class, which writes an AST file
+//  containing a serialized representation of a translation unit.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
+#define LLVM_CLANG_FRONTEND_AST_WRITER_H
+
+#include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Sema/SemaConsumer.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ASTDeserializationListener.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include <map>
+#include <queue>
+#include <vector>
+
+namespace llvm {
+  class APFloat;
+  class APInt;
+  class BitstreamWriter;
+}
+
+namespace clang {
+
+class ASTContext;
+class NestedNameSpecifier;
+class CXXBaseSpecifier;
+class CXXCtorInitializer;
+class FileEntry;
+class FPOptions;
+class HeaderSearch;
+class HeaderSearchOptions;
+class IdentifierResolver;
+class MacroDefinition;
+class MacroDirective;
+class MacroInfo;
+class OpaqueValueExpr;
+class OpenCLOptions;
+class ASTReader;
+class Module;
+class PreprocessedEntity;
+class PreprocessingRecord;
+class Preprocessor;
+class Sema;
+class SourceManager;
+class SwitchCase;
+class TargetInfo;
+class Token;
+class VersionTuple;
+class ASTUnresolvedSet;
+
+namespace SrcMgr { class SLocEntry; }
+
+/// \brief Writes an AST file containing the contents of a translation unit.
+///
+/// The ASTWriter class produces a bitstream containing the serialized
+/// representation of a given abstract syntax tree and its supporting
+/// data structures. This bitstream can be de-serialized via an
+/// instance of the ASTReader class.
+class ASTWriter : public ASTDeserializationListener,
+                  public ASTMutationListener {
+public:
+  typedef SmallVector<uint64_t, 64> RecordData;
+  typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+
+  friend class ASTDeclWriter;
+  friend class ASTStmtWriter;
+private:
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream, plus those deserialized from a chained PCH.
+  ///
+  /// The ID numbers of types are consecutive (in order of discovery)
+  /// and start at 1. 0 is reserved for NULL. When types are actually
+  /// stored in the stream, the ID number is shifted by 2 bits to
+  /// allow for the const/volatile qualifiers.
+  ///
+  /// Keys in the map never have const/volatile qualifiers.
+  typedef llvm::DenseMap<QualType, serialization::TypeIdx,
+                         serialization::UnsafeQualTypeDenseMapInfo>
+    TypeIdxMap;
+
+  /// \brief The bitstream writer used to emit this precompiled header.
+  llvm::BitstreamWriter &Stream;
+
+  /// \brief The ASTContext we're writing.
+  ASTContext *Context;
+
+  /// \brief The preprocessor we're writing.
+  Preprocessor *PP;
+
+  /// \brief The reader of existing AST files, if we're chaining.
+  ASTReader *Chain;
+
+  /// \brief The module we're currently writing, if any.
+  Module *WritingModule;
+                    
+  /// \brief Indicates when the AST writing is actively performing
+  /// serialization, rather than just queueing updates.
+  bool WritingAST;
+
+  /// \brief Indicates that we are done serializing the collection of decls
+  /// and types to emit.
+  bool DoneWritingDeclsAndTypes;
+
+  /// \brief Indicates that the AST contained compiler errors.
+  bool ASTHasCompilerErrors;
+
+  /// \brief Mapping from input file entries to the index into the
+  /// offset table where information about that input file is stored.
+  llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs;
+
+  /// \brief Stores a declaration or a type to be written to the AST file.
+  class DeclOrType {
+  public:
+    DeclOrType(Decl *D) : Stored(D), IsType(false) { }
+    DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
+
+    bool isType() const { return IsType; }
+    bool isDecl() const { return !IsType; }
+
+    QualType getType() const {
+      assert(isType() && "Not a type!");
+      return QualType::getFromOpaquePtr(Stored);
+    }
+
+    Decl *getDecl() const {
+      assert(isDecl() && "Not a decl!");
+      return static_cast<Decl *>(Stored);
+    }
+
+  private:
+    void *Stored;
+    bool IsType;
+  };
+
+  /// \brief The declarations and types to emit.
+  std::queue<DeclOrType> DeclTypesToEmit;
+
+  /// \brief The first ID number we can use for our own declarations.
+  serialization::DeclID FirstDeclID;
+
+  /// \brief The decl ID that will be assigned to the next new decl.
+  serialization::DeclID NextDeclID;
+
+  /// \brief Map that provides the ID numbers of each declaration within
+  /// the output stream, as well as those deserialized from a chained PCH.
+  ///
+  /// The ID numbers of declarations are consecutive (in order of
+  /// discovery) and start at 2. 1 is reserved for the translation
+  /// unit, while 0 is reserved for NULL.
+  llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs;
+
+  /// \brief Offset of each declaration in the bitstream, indexed by
+  /// the declaration's ID.
+  std::vector<serialization::DeclOffset> DeclOffsets;
+
+  /// \brief Sorted (by file offset) vector of pairs of file offset/DeclID.
+  typedef SmallVector<std::pair<unsigned, serialization::DeclID>, 64>
+    LocDeclIDsTy;
+  struct DeclIDInFileInfo {
+    LocDeclIDsTy DeclIDs;
+    /// \brief Set when the DeclIDs vectors from all files are joined, this
+    /// indicates the index that this particular vector has in the global one.
+    unsigned FirstDeclIndex;
+  };
+  typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy;
+
+  /// \brief Map from file SLocEntries to info about the file-level declarations
+  /// that it contains.
+  FileDeclIDsTy FileDeclIDs;
+
+  void associateDeclWithFile(const Decl *D, serialization::DeclID);
+
+  /// \brief The first ID number we can use for our own types.
+  serialization::TypeID FirstTypeID;
+
+  /// \brief The type ID that will be assigned to the next new type.
+  serialization::TypeID NextTypeID;
+
+  /// \brief Map that provides the ID numbers of each type within the
+  /// output stream, plus those deserialized from a chained PCH.
+  ///
+  /// The ID numbers of types are consecutive (in order of discovery)
+  /// and start at 1. 0 is reserved for NULL. When types are actually
+  /// stored in the stream, the ID number is shifted by 2 bits to
+  /// allow for the const/volatile qualifiers.
+  ///
+  /// Keys in the map never have const/volatile qualifiers.
+  TypeIdxMap TypeIdxs;
+
+  /// \brief Offset of each type in the bitstream, indexed by
+  /// the type's ID.
+  std::vector<uint32_t> TypeOffsets;
+
+  /// \brief The first ID number we can use for our own identifiers.
+  serialization::IdentID FirstIdentID;
+
+  /// \brief The identifier ID that will be assigned to the next new identifier.
+  serialization::IdentID NextIdentID;
+
+  /// \brief Map that provides the ID numbers of each identifier in
+  /// the output stream.
+  ///
+  /// The ID numbers for identifiers are consecutive (in order of
+  /// discovery), starting at 1. An ID of zero refers to a NULL
+  /// IdentifierInfo.
+  llvm::DenseMap<const IdentifierInfo *, serialization::IdentID> IdentifierIDs;
+
+  /// \brief The first ID number we can use for our own macros.
+  serialization::MacroID FirstMacroID;
+
+  /// \brief The identifier ID that will be assigned to the next new identifier.
+  serialization::MacroID NextMacroID;
+
+  /// \brief Map that provides the ID numbers of each macro.
+  llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
+
+  struct MacroInfoToEmitData {
+    const IdentifierInfo *Name;
+    MacroInfo *MI;
+    serialization::MacroID ID;
+  };
+  /// \brief The macro infos to emit.
+  std::vector<MacroInfoToEmitData> MacroInfosToEmit;
+
+  llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
+
+  /// @name FlushStmt Caches
+  /// @{
+
+  /// \brief Set of parent Stmts for the currently serializing sub-stmt.
+  llvm::DenseSet<Stmt *> ParentStmts;
+
+  /// \brief Offsets of sub-stmts already serialized. The offset points
+  /// just after the stmt record.
+  llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
+
+  /// @}
+
+  /// \brief Offsets of each of the identifier IDs into the identifier
+  /// table.
+  std::vector<uint32_t> IdentifierOffsets;
+
+  /// \brief The first ID number we can use for our own submodules.
+  serialization::SubmoduleID FirstSubmoduleID;
+  
+  /// \brief The submodule ID that will be assigned to the next new submodule.
+  serialization::SubmoduleID NextSubmoduleID;
+
+  /// \brief The first ID number we can use for our own selectors.
+  serialization::SelectorID FirstSelectorID;
+
+  /// \brief The selector ID that will be assigned to the next new selector.
+  serialization::SelectorID NextSelectorID;
+
+  /// \brief Map that provides the ID numbers of each Selector.
+  llvm::DenseMap<Selector, serialization::SelectorID> SelectorIDs;
+
+  /// \brief Offset of each selector within the method pool/selector
+  /// table, indexed by the Selector ID (-1).
+  std::vector<uint32_t> SelectorOffsets;
+
+  /// \brief Mapping from macro definitions (as they occur in the preprocessing
+  /// record) to the macro IDs.
+  llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
+      MacroDefinitions;
+
+  /// An update to a Decl.
+  class DeclUpdate {
+    /// A DeclUpdateKind.
+    unsigned Kind;
+    union {
+      const Decl *Dcl;
+      void *Type;
+      unsigned Loc;
+      unsigned Val;
+    };
+
+  public:
+    DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
+    DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
+    DeclUpdate(unsigned Kind, QualType Type)
+        : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
+    DeclUpdate(unsigned Kind, SourceLocation Loc)
+        : Kind(Kind), Loc(Loc.getRawEncoding()) {}
+    DeclUpdate(unsigned Kind, unsigned Val)
+        : Kind(Kind), Val(Val) {}
+
+    unsigned getKind() const { return Kind; }
+    const Decl *getDecl() const { return Dcl; }
+    QualType getType() const { return QualType::getFromOpaquePtr(Type); }
+    SourceLocation getLoc() const {
+      return SourceLocation::getFromRawEncoding(Loc);
+    }
+    unsigned getNumber() const { return Val; }
+  };
+
+  typedef SmallVector<DeclUpdate, 1> UpdateRecord;
+  typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap;
+  /// \brief Mapping from declarations that came from a chained PCH to the
+  /// record containing modifications to them.
+  DeclUpdateMap DeclUpdates;
+
+  typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
+  /// \brief Map of first declarations from a chained PCH that point to the
+  /// most recent declarations in another PCH.
+  FirstLatestDeclMap FirstLatestDecls;
+
+  /// \brief Declarations encountered that might be external
+  /// definitions.
+  ///
+  /// We keep track of external definitions and other 'interesting' declarations
+  /// as we are emitting declarations to the AST file. The AST file contains a
+  /// separate record for these declarations, which are provided to the AST
+  /// consumer by the AST reader. This is behavior is required to properly cope with,
+  /// e.g., tentative variable definitions that occur within
+  /// headers. The declarations themselves are stored as declaration
+  /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
+  /// record.
+  SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
+
+  /// \brief DeclContexts that have received extensions since their serialized
+  /// form.
+  ///
+  /// For namespaces, when we're chaining and encountering a namespace, we check
+  /// if its primary namespace comes from the chain. If it does, we add the
+  /// primary to this set, so that we can write out lexical content updates for
+  /// it.
+  llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts;
+
+  /// \brief Keeps track of visible decls that were added in DeclContexts
+  /// coming from another AST file.
+  SmallVector<const Decl *, 16> UpdatingVisibleDecls;
+
+  typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy;
+  /// \brief Decls that will be replaced in the current dependent AST file.
+  DeclsToRewriteTy DeclsToRewrite;
+
+  /// \brief The set of Objective-C class that have categories we
+  /// should serialize.
+  llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
+                    
+  struct ReplacedDeclInfo {
+    serialization::DeclID ID;
+    uint64_t Offset;
+    unsigned Loc;
+
+    ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {}
+    ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset,
+                     SourceLocation Loc)
+      : ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {}
+  };
+
+  /// \brief Decls that have been replaced in the current dependent AST file.
+  ///
+  /// When a decl changes fundamentally after being deserialized (this shouldn't
+  /// happen, but the ObjC AST nodes are designed this way), it will be
+  /// serialized again. In this case, it is registered here, so that the reader
+  /// knows to read the updated version.
+  SmallVector<ReplacedDeclInfo, 16> ReplacedDecls;
+                 
+  /// \brief The set of declarations that may have redeclaration chains that
+  /// need to be serialized.
+  llvm::SetVector<Decl *, SmallVector<Decl *, 4>,
+                  llvm::SmallPtrSet<Decl *, 4> > Redeclarations;
+                                      
+  /// \brief Statements that we've encountered while serializing a
+  /// declaration or type.
+  SmallVector<Stmt *, 16> StmtsToEmit;
+
+  /// \brief Statements collection to use for ASTWriter::AddStmt().
+  /// It will point to StmtsToEmit unless it is overriden.
+  SmallVector<Stmt *, 16> *CollectedStmts;
+
+  /// \brief Mapping from SwitchCase statements to IDs.
+  llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
+
+  /// \brief The number of statements written to the AST file.
+  unsigned NumStatements;
+
+  /// \brief The number of macros written to the AST file.
+  unsigned NumMacros;
+
+  /// \brief The number of lexical declcontexts written to the AST
+  /// file.
+  unsigned NumLexicalDeclContexts;
+
+  /// \brief The number of visible declcontexts written to the AST
+  /// file.
+  unsigned NumVisibleDeclContexts;
+
+  /// \brief The offset of each CXXBaseSpecifier set within the AST.
+  SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets;
+
+  /// \brief The first ID number we can use for our own base specifiers.
+  serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID;
+
+  /// \brief The base specifiers ID that will be assigned to the next new
+  /// set of C++ base specifiers.
+  serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID;
+
+  /// \brief A set of C++ base specifiers that is queued to be written into the
+  /// AST file.
+  struct QueuedCXXBaseSpecifiers {
+    QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { }
+
+    QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID,
+                            CXXBaseSpecifier const *Bases,
+                            CXXBaseSpecifier const *BasesEnd)
+      : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { }
+
+    serialization::CXXBaseSpecifiersID ID;
+    CXXBaseSpecifier const * Bases;
+    CXXBaseSpecifier const * BasesEnd;
+  };
+
+  /// \brief Queue of C++ base specifiers to be written to the AST file,
+  /// in the order they should be written.
+  SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
+
+  /// \brief A mapping from each known submodule to its ID number, which will
+  /// be a positive integer.
+  llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
+                    
+  /// \brief Retrieve or create a submodule ID for this module.
+  unsigned getSubmoduleID(Module *Mod);
+                    
+  /// \brief Write the given subexpression to the bitstream.
+  void WriteSubStmt(Stmt *S,
+                    llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
+                    llvm::DenseSet<Stmt *> &ParentStmts);
+
+  void WriteBlockInfoBlock();
+  void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                         StringRef isysroot, const std::string &OutputFile);
+  void WriteInputFiles(SourceManager &SourceMgr,
+                       HeaderSearchOptions &HSOpts,
+                       StringRef isysroot,
+                       bool Modules);
+  void WriteSourceManagerBlock(SourceManager &SourceMgr,
+                               const Preprocessor &PP,
+                               StringRef isysroot);
+  void WritePreprocessor(const Preprocessor &PP, bool IsModule);
+  void WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot);
+  void WritePreprocessorDetail(PreprocessingRecord &PPRec);
+  void WriteSubmodules(Module *WritingModule);
+                                        
+  void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
+                                     bool isModule);
+  void WriteCXXBaseSpecifiersOffsets();
+  void WriteType(QualType T);
+  uint32_t GenerateNameLookupTable(const DeclContext *DC,
+                                   llvm::SmallVectorImpl<char> &LookupTable);
+  uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
+  uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
+  void WriteTypeDeclOffsets();
+  void WriteFileDeclIDsMap();
+  void WriteComments();
+  void WriteSelectors(Sema &SemaRef);
+  void WriteReferencedSelectorsPool(Sema &SemaRef);
+  void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
+                            bool IsModule);
+  void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
+  void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
+  void WriteDeclReplacementsBlock();
+  void WriteDeclContextVisibleUpdate(const DeclContext *DC);
+  void WriteFPPragmaOptions(const FPOptions &Opts);
+  void WriteOpenCLExtensions(Sema &SemaRef);
+  void WriteObjCCategories();
+  void WriteRedeclarations();
+  void WriteMergedDecls();
+  void WriteLateParsedTemplates(Sema &SemaRef);
+  void WriteOptimizePragmaOptions(Sema &SemaRef);
+
+  unsigned DeclParmVarAbbrev;
+  unsigned DeclContextLexicalAbbrev;
+  unsigned DeclContextVisibleLookupAbbrev;
+  unsigned UpdateVisibleAbbrev;
+  unsigned DeclRefExprAbbrev;
+  unsigned CharacterLiteralAbbrev;
+  unsigned DeclRecordAbbrev;
+  unsigned IntegerLiteralAbbrev;
+  unsigned DeclTypedefAbbrev;
+  unsigned DeclVarAbbrev;
+  unsigned DeclFieldAbbrev;
+  unsigned DeclEnumAbbrev;
+  unsigned DeclObjCIvarAbbrev;
+
+  void WriteDeclsBlockAbbrevs();
+  void WriteDecl(ASTContext &Context, Decl *D);
+  void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
+
+  void WriteASTCore(Sema &SemaRef,
+                    StringRef isysroot, const std::string &OutputFile,
+                    Module *WritingModule);
+
+public:
+  /// \brief Create a new precompiled header writer that outputs to
+  /// the given bitstream.
+  ASTWriter(llvm::BitstreamWriter &Stream);
+  ~ASTWriter();
+
+  /// \brief Write a precompiled header for the given semantic analysis.
+  ///
+  /// \param SemaRef a reference to the semantic analysis object that processed
+  /// the AST to be written into the precompiled header.
+  ///
+  /// \param WritingModule The module that we are writing. If null, we are
+  /// writing a precompiled header.
+  ///
+  /// \param isysroot if non-empty, write a relocatable file whose headers
+  /// are relative to the given system root.
+  void WriteAST(Sema &SemaRef,
+                const std::string &OutputFile,
+                Module *WritingModule, StringRef isysroot,
+                bool hasErrors = false);
+
+  /// \brief Emit a token.
+  void AddToken(const Token &Tok, RecordDataImpl &Record);
+
+  /// \brief Emit a source location.
+  void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
+
+  /// \brief Emit a source range.
+  void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
+
+  /// \brief Emit an integral value.
+  void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record);
+
+  /// \brief Emit a signed integral value.
+  void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record);
+
+  /// \brief Emit a floating-point value.
+  void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record);
+
+  /// \brief Emit a reference to an identifier.
+  void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
+
+  /// \brief Emit a Selector (which is a smart pointer reference).
+  void AddSelectorRef(Selector, RecordDataImpl &Record);
+
+  /// \brief Emit a CXXTemporary.
+  void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record);
+
+  /// \brief Emit a set of C++ base specifiers to the record.
+  void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
+                               CXXBaseSpecifier const *BasesEnd,
+                               RecordDataImpl &Record);
+
+  /// \brief Get the unique number used to refer to the given selector.
+  serialization::SelectorID getSelectorRef(Selector Sel);
+
+  /// \brief Get the unique number used to refer to the given identifier.
+  serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
+
+  /// \brief Get the unique number used to refer to the given macro.
+  serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
+
+  /// \brief Determine the ID of an already-emitted macro.
+  serialization::MacroID getMacroID(MacroInfo *MI);
+
+  uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
+
+  /// \brief Emit a reference to a type.
+  void AddTypeRef(QualType T, RecordDataImpl &Record);
+
+  /// \brief Force a type to be emitted and get its ID.
+  serialization::TypeID GetOrCreateTypeID(QualType T);
+
+  /// \brief Determine the type ID of an already-emitted type.
+  serialization::TypeID getTypeID(QualType T) const;
+
+  /// \brief Force a type to be emitted and get its index.
+  serialization::TypeIdx GetOrCreateTypeIdx( QualType T);
+
+  /// \brief Determine the type index of an already-emitted type.
+  serialization::TypeIdx getTypeIdx(QualType T) const;
+
+  /// \brief Emits a reference to a declarator info.
+  void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
+
+  /// \brief Emits a type with source-location information.
+  void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
+
+  /// \brief Emits a template argument location info.
+  void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+                                  const TemplateArgumentLocInfo &Arg,
+                                  RecordDataImpl &Record);
+
+  /// \brief Emits a template argument location.
+  void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+                              RecordDataImpl &Record);
+
+  /// \brief Emits an AST template argument list info.
+  void AddASTTemplateArgumentListInfo(
+                          const ASTTemplateArgumentListInfo *ASTTemplArgList,
+                          RecordDataImpl &Record);
+
+  /// \brief Emit a reference to a declaration.
+  void AddDeclRef(const Decl *D, RecordDataImpl &Record);
+
+
+  /// \brief Force a declaration to be emitted and get its ID.
+  serialization::DeclID GetDeclRef(const Decl *D);
+
+  /// \brief Determine the declaration ID of an already-emitted
+  /// declaration.
+  serialization::DeclID getDeclID(const Decl *D);
+
+  /// \brief Emit a declaration name.
+  void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record);
+  void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
+                             DeclarationName Name, RecordDataImpl &Record);
+  void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                              RecordDataImpl &Record);
+
+  void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record);
+
+  /// \brief Emit a nested name specifier.
+  void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
+
+  /// \brief Emit a nested name specifier with source-location information.
+  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                                 RecordDataImpl &Record);
+
+  /// \brief Emit a template name.
+  void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
+
+  /// \brief Emit a template argument.
+  void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record);
+
+  /// \brief Emit a template parameter list.
+  void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
+                                RecordDataImpl &Record);
+
+  /// \brief Emit a template argument list.
+  void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
+                                RecordDataImpl &Record);
+
+  /// \brief Emit a UnresolvedSet structure.
+  void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
+
+  /// \brief Emit a C++ base specifier.
+  void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
+                           RecordDataImpl &Record);
+
+  /// \brief Emit a CXXCtorInitializer array.
+  void AddCXXCtorInitializers(
+                             const CXXCtorInitializer * const *CtorInitializers,
+                             unsigned NumCtorInitializers,
+                             RecordDataImpl &Record);
+
+  void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record);
+
+  /// \brief Add a string to the given record.
+  void AddString(StringRef Str, RecordDataImpl &Record);
+
+  /// \brief Add a version tuple to the given record
+  void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
+
+  /// \brief Mark a declaration context as needing an update.
+  void AddUpdatedDeclContext(const DeclContext *DC);
+
+  void RewriteDecl(const Decl *D) {
+    DeclsToRewrite.insert(D);
+  }
+
+  bool isRewritten(const Decl *D) const {
+    return DeclsToRewrite.count(D);
+  }
+
+  /// \brief Infer the submodule ID that contains an entity at the given
+  /// source location.
+  serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
+
+  /// \brief Retrieve a submodule ID for this module.
+  /// Returns 0 If no ID has been associated with the module.
+  unsigned getExistingSubmoduleID(Module *Mod) const;
+
+  /// \brief Note that the identifier II occurs at the given offset
+  /// within the identifier table.
+  void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
+
+  /// \brief Note that the selector Sel occurs at the given offset
+  /// within the method pool/selector table.
+  void SetSelectorOffset(Selector Sel, uint32_t Offset);
+
+  /// \brief Add the given statement or expression to the queue of
+  /// statements to emit.
+  ///
+  /// This routine should be used when emitting types and declarations
+  /// that have expressions as part of their formulation. Once the
+  /// type or declaration has been written, call FlushStmts() to write
+  /// the corresponding statements just after the type or
+  /// declaration.
+  void AddStmt(Stmt *S) {
+      CollectedStmts->push_back(S);
+  }
+
+  /// \brief Flush all of the statements and expressions that have
+  /// been added to the queue via AddStmt().
+  void FlushStmts();
+
+  /// \brief Flush all of the C++ base specifier sets that have been added
+  /// via \c AddCXXBaseSpecifiersRef().
+  void FlushCXXBaseSpecifiers();
+
+  /// \brief Record an ID for the given switch-case statement.
+  unsigned RecordSwitchCaseID(SwitchCase *S);
+
+  /// \brief Retrieve the ID for the given switch-case statement.
+  unsigned getSwitchCaseID(SwitchCase *S);
+
+  void ClearSwitchCaseIDs();
+
+  unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
+  unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
+  unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
+  unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
+  unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
+  unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
+  unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
+  unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
+  unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
+  unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
+
+  bool hasChain() const { return Chain; }
+
+  // ASTDeserializationListener implementation
+  void ReaderInitialized(ASTReader *Reader) override;
+  void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
+  void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
+  void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+  void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
+  void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
+                           MacroDefinition *MD) override;
+  void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
+
+  // ASTMutationListener implementation.
+  void CompletedTagDefinition(const TagDecl *D) override;
+  void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
+  void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
+  void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                             const ClassTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+                               const VarTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+                                      const FunctionDecl *D) override;
+  void ResolvedExceptionSpec(const FunctionDecl *FD) override;
+  void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
+  void CompletedImplicitDefinition(const FunctionDecl *D) override;
+  void StaticDataMemberInstantiated(const VarDecl *D) override;
+  void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
+  void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+                                    const ObjCInterfaceDecl *IFD) override;
+  void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                    const ObjCPropertyDecl *OrigProp,
+                                    const ObjCCategoryDecl *ClassExt) override;
+  void DeclarationMarkedUsed(const Decl *D) override;
+};
+
+/// \brief AST and semantic-analysis consumer that generates a
+/// precompiled header from the parsed source code.
+class PCHGenerator : public SemaConsumer {
+  const Preprocessor &PP;
+  std::string OutputFile;
+  clang::Module *Module;
+  std::string isysroot;
+  raw_ostream *Out;
+  Sema *SemaPtr;
+  SmallVector<char, 128> Buffer;
+  llvm::BitstreamWriter Stream;
+  ASTWriter Writer;
+  bool AllowASTWithErrors;
+  bool HasEmittedPCH;
+
+protected:
+  ASTWriter &getWriter() { return Writer; }
+  const ASTWriter &getWriter() const { return Writer; }
+
+public:
+  PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
+               clang::Module *Module,
+               StringRef isysroot, raw_ostream *Out,
+               bool AllowASTWithErrors = false);
+  ~PCHGenerator();
+  void InitializeSema(Sema &S) override { SemaPtr = &S; }
+  void HandleTranslationUnit(ASTContext &Ctx) override;
+  ASTMutationListener *GetASTMutationListener() override;
+  ASTDeserializationListener *GetASTDeserializationListener() override;
+
+  bool hasEmittedPCH() const { return HasEmittedPCH; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Serialization/AttrPCHRead.inc b/include/clang/Serialization/AttrPCHRead.inc
new file mode 100644
index 0000000..c2cc7d5
--- /dev/null
+++ b/include/clang/Serialization/AttrPCHRead.inc
@@ -0,0 +1,1614 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute deserialization code                                              *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+  switch (Kind) {
+  default:
+    llvm_unreachable("Unknown attribute!");
+  case attr::ARMInterrupt: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    ARMInterruptAttr::InterruptType interrupt(static_cast<ARMInterruptAttr::InterruptType>(Record[Idx++]));
+    New = new (Context) ARMInterruptAttr(Range, Context, interrupt, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AcquireCapability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) AcquireCapabilityAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AcquiredAfter: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) AcquiredAfterAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AcquiredBefore: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) AcquiredBeforeAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Alias: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string aliasee= ReadString(Record, Idx);
+    New = new (Context) AliasAttr(Range, Context, aliasee, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AlignMac68k: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) AlignMac68kAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Aligned: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    bool isalignmentExpr = Record[Idx++];
+    void *alignmentPtr;
+    if (isalignmentExpr)
+      alignmentPtr = ReadExpr(F);
+    else
+      alignmentPtr = GetTypeSourceInfo(F, Record, Idx);
+    New = new (Context) AlignedAttr(Range, Context, isalignmentExpr, alignmentPtr, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AlwaysInline: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) AlwaysInlineAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AnalyzerNoReturn: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) AnalyzerNoReturnAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Annotate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string annotation= ReadString(Record, Idx);
+    New = new (Context) AnnotateAttr(Range, Context, annotation, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ArcWeakrefUnavailable: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ArcWeakrefUnavailableAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ArgumentWithTypeTag: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * argumentKind = GetIdentifierInfo(F, Record, Idx);
+    unsigned argumentIdx = Record[Idx++];
+    unsigned typeTagIdx = Record[Idx++];
+    bool isPointer = Record[Idx++];
+    New = new (Context) ArgumentWithTypeTagAttr(Range, Context, argumentKind, argumentIdx, typeTagIdx, isPointer, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AsmLabel: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string label= ReadString(Record, Idx);
+    New = new (Context) AsmLabelAttr(Range, Context, label, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AssertCapability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * expr = ReadExpr(F);
+    New = new (Context) AssertCapabilityAttr(Range, Context, expr, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AssertExclusiveLock: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) AssertExclusiveLockAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::AssertSharedLock: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) AssertSharedLockAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Availability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * platform = GetIdentifierInfo(F, Record, Idx);
+    VersionTuple introduced= ReadVersionTuple(Record, Idx);
+    VersionTuple deprecated= ReadVersionTuple(Record, Idx);
+    VersionTuple obsoleted= ReadVersionTuple(Record, Idx);
+    bool unavailable = Record[Idx++];
+    std::string message= ReadString(Record, Idx);
+    New = new (Context) AvailabilityAttr(Range, Context, platform, introduced, deprecated, obsoleted, unavailable, message, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Blocks: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    BlocksAttr::BlockType type(static_cast<BlocksAttr::BlockType>(Record[Idx++]));
+    New = new (Context) BlocksAttr(Range, Context, type, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::C11NoReturn: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) C11NoReturnAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CDecl: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CDeclAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CFAuditedTransfer: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CFAuditedTransferAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CFConsumed: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CFConsumedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CFReturnsNotRetained: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CFReturnsNotRetainedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CFReturnsRetained: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CFReturnsRetainedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CFUnknownTransfer: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CFUnknownTransferAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDAConstant: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CUDAConstantAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDADevice: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CUDADeviceAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDAGlobal: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CUDAGlobalAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDAHost: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CUDAHostAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDALaunchBounds: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    int maxThreads = Record[Idx++];
+    int minBlocks = Record[Idx++];
+    New = new (Context) CUDALaunchBoundsAttr(Range, Context, maxThreads, minBlocks, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CUDAShared: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CUDASharedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CXX11NoReturn: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CXX11NoReturnAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CallableWhen: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned callableStatesSize = Record[Idx++];
+    SmallVector<CallableWhenAttr::ConsumedState, 4> callableStates;
+    callableStates.reserve(callableStatesSize);
+    for (unsigned i = callableStatesSize; i; --i)
+      callableStates.push_back(static_cast<CallableWhenAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) CallableWhenAttr(Range, Context, callableStates.data(), callableStatesSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Capability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string name= ReadString(Record, Idx);
+    New = new (Context) CapabilityAttr(Range, Context, name, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::CarriesDependency: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CarriesDependencyAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Cleanup: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    FunctionDecl * functionDecl = GetLocalDeclAs<FunctionDecl >(F, Record[Idx++]);
+    New = new (Context) CleanupAttr(Range, Context, functionDecl, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Cold: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ColdAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Common: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) CommonAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Const: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ConstAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Constructor: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    int priority = Record[Idx++];
+    New = new (Context) ConstructorAttr(Range, Context, priority, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Consumable: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    ConsumableAttr::ConsumedState defaultState(static_cast<ConsumableAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) ConsumableAttr(Range, Context, defaultState, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ConsumableAutoCast: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ConsumableAutoCastAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ConsumableSetOnRead: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ConsumableSetOnReadAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::DLLExport: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) DLLExportAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::DLLImport: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) DLLImportAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Deprecated: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string message= ReadString(Record, Idx);
+    New = new (Context) DeprecatedAttr(Range, Context, message, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Destructor: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    int priority = Record[Idx++];
+    New = new (Context) DestructorAttr(Range, Context, priority, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::EnableIf: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * cond = ReadExpr(F);
+    std::string message= ReadString(Record, Idx);
+    New = new (Context) EnableIfAttr(Range, Context, cond, message, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ExclusiveTrylockFunction: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * successValue = ReadExpr(F);
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) ExclusiveTrylockFunctionAttr(Range, Context, successValue, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::FallThrough: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) FallThroughAttr(Range, Context, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::FastCall: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) FastCallAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Final: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) FinalAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Flatten: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) FlattenAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Format: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * type = GetIdentifierInfo(F, Record, Idx);
+    int formatIdx = Record[Idx++];
+    int firstArg = Record[Idx++];
+    New = new (Context) FormatAttr(Range, Context, type, formatIdx, firstArg, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::FormatArg: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    int formatIdx = Record[Idx++];
+    New = new (Context) FormatArgAttr(Range, Context, formatIdx, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::GNUInline: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) GNUInlineAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::GuardedBy: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * arg = ReadExpr(F);
+    New = new (Context) GuardedByAttr(Range, Context, arg, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::GuardedVar: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) GuardedVarAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Hot: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) HotAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::IBAction: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) IBActionAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::IBOutlet: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) IBOutletAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::IBOutletCollection: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    TypeSourceInfo * interface = GetTypeSourceInfo(F, Record, Idx);
+    New = new (Context) IBOutletCollectionAttr(Range, Context, interface, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::InitPriority: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned priority = Record[Idx++];
+    New = new (Context) InitPriorityAttr(Range, Context, priority, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::InitSeg: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string section= ReadString(Record, Idx);
+    New = new (Context) InitSegAttr(Range, Context, section, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::IntelOclBicc: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) IntelOclBiccAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::LockReturned: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * arg = ReadExpr(F);
+    New = new (Context) LockReturnedAttr(Range, Context, arg, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::LocksExcluded: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) LocksExcludedAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::LoopHint: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    LoopHintAttr::OptionType option(static_cast<LoopHintAttr::OptionType>(Record[Idx++]));
+    int value = Record[Idx++];
+    New = new (Context) LoopHintAttr(Range, Context, option, value, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MSABI: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) MSABIAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MSInheritance: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    bool bestCase = Record[Idx++];
+    New = new (Context) MSInheritanceAttr(Range, Context, bestCase, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MSP430Interrupt: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned number = Record[Idx++];
+    New = new (Context) MSP430InterruptAttr(Range, Context, number, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MSVtorDisp: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned vdm = Record[Idx++];
+    New = new (Context) MSVtorDispAttr(Range, Context, vdm, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Malloc: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) MallocAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MaxFieldAlignment: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned alignment = Record[Idx++];
+    New = new (Context) MaxFieldAlignmentAttr(Range, Context, alignment, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MayAlias: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) MayAliasAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MinSize: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) MinSizeAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Mips16: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) Mips16Attr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Mode: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * mode = GetIdentifierInfo(F, Record, Idx);
+    New = new (Context) ModeAttr(Range, Context, mode, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::MsStruct: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) MsStructAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NSConsumed: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NSConsumedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NSConsumesSelf: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NSConsumesSelfAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NSReturnsAutoreleased: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NSReturnsAutoreleasedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NSReturnsNotRetained: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NSReturnsNotRetainedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NSReturnsRetained: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NSReturnsRetainedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Naked: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NakedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoCommon: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoCommonAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoDebug: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoDebugAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoDuplicate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoDuplicateAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoInline: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoInlineAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoInstrumentFunction: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoInstrumentFunctionAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoMips16: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoMips16Attr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoReturn: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoReturnAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoSanitizeAddress: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoSanitizeAddressAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoSanitizeMemory: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoSanitizeMemoryAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoSanitizeThread: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoSanitizeThreadAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoSplitStack: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoSplitStackAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoThreadSafetyAnalysis: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoThreadSafetyAnalysisAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NoThrow: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) NoThrowAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::NonNull: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<unsigned, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(Record[Idx++]);
+    New = new (Context) NonNullAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCBridge: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * bridgedType = GetIdentifierInfo(F, Record, Idx);
+    New = new (Context) ObjCBridgeAttr(Range, Context, bridgedType, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCBridgeMutable: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * bridgedType = GetIdentifierInfo(F, Record, Idx);
+    New = new (Context) ObjCBridgeMutableAttr(Range, Context, bridgedType, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCBridgeRelated: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * relatedClass = GetIdentifierInfo(F, Record, Idx);
+    IdentifierInfo * classMethod = GetIdentifierInfo(F, Record, Idx);
+    IdentifierInfo * instanceMethod = GetIdentifierInfo(F, Record, Idx);
+    New = new (Context) ObjCBridgeRelatedAttr(Range, Context, relatedClass, classMethod, instanceMethod, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCDesignatedInitializer: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCDesignatedInitializerAttr(Range, Context, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCException: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCExceptionAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCExplicitProtocolImpl: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCExplicitProtocolImplAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCMethodFamily: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    ObjCMethodFamilyAttr::FamilyKind family(static_cast<ObjCMethodFamilyAttr::FamilyKind>(Record[Idx++]));
+    New = new (Context) ObjCMethodFamilyAttr(Range, Context, family, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCNSObject: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCNSObjectAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCPreciseLifetime: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCPreciseLifetimeAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCRequiresPropertyDefs: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCRequiresPropertyDefsAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCRequiresSuper: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCRequiresSuperAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCReturnsInnerPointer: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCReturnsInnerPointerAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCRootClass: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ObjCRootClassAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ObjCRuntimeName: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string metadataName= ReadString(Record, Idx);
+    New = new (Context) ObjCRuntimeNameAttr(Range, Context, metadataName, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::OpenCLImageAccess: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) OpenCLImageAccessAttr(Range, Context, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::OpenCLKernel: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) OpenCLKernelAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::OptimizeNone: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) OptimizeNoneAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Overloadable: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) OverloadableAttr(Range, Context, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Override: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) OverrideAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Ownership: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * module = GetIdentifierInfo(F, Record, Idx);
+  unsigned argsSize = Record[Idx++];
+  SmallVector<unsigned, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(Record[Idx++]);
+    New = new (Context) OwnershipAttr(Range, Context, module, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Packed: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) PackedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ParamTypestate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    ParamTypestateAttr::ConsumedState paramState(static_cast<ParamTypestateAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) ParamTypestateAttr(Range, Context, paramState, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Pascal: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) PascalAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Pcs: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    PcsAttr::PCSType pCS(static_cast<PcsAttr::PCSType>(Record[Idx++]));
+    New = new (Context) PcsAttr(Range, Context, pCS, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::PnaclCall: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) PnaclCallAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::PtGuardedBy: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * arg = ReadExpr(F);
+    New = new (Context) PtGuardedByAttr(Range, Context, arg, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::PtGuardedVar: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) PtGuardedVarAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Pure: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) PureAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ReleaseCapability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) ReleaseCapabilityAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ReqdWorkGroupSize: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned xDim = Record[Idx++];
+    unsigned yDim = Record[Idx++];
+    unsigned zDim = Record[Idx++];
+    New = new (Context) ReqdWorkGroupSizeAttr(Range, Context, xDim, yDim, zDim, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::RequiresCapability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) RequiresCapabilityAttr(Range, Context, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ReturnTypestate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    ReturnTypestateAttr::ConsumedState state(static_cast<ReturnTypestateAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) ReturnTypestateAttr(Range, Context, state, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ReturnsNonNull: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ReturnsNonNullAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ReturnsTwice: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ReturnsTwiceAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ScopedLockable: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ScopedLockableAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Section: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string name= ReadString(Record, Idx);
+    New = new (Context) SectionAttr(Range, Context, name, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::SelectAny: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) SelectAnyAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Sentinel: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    int sentinel = Record[Idx++];
+    int nullPos = Record[Idx++];
+    New = new (Context) SentinelAttr(Range, Context, sentinel, nullPos, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::SetTypestate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    SetTypestateAttr::ConsumedState newState(static_cast<SetTypestateAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) SetTypestateAttr(Range, Context, newState, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::SharedTrylockFunction: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * successValue = ReadExpr(F);
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) SharedTrylockFunctionAttr(Range, Context, successValue, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::StdCall: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) StdCallAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::SysVABI: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) SysVABIAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TLSModel: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string model= ReadString(Record, Idx);
+    New = new (Context) TLSModelAttr(Range, Context, model, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TestTypestate: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    TestTypestateAttr::ConsumedState testState(static_cast<TestTypestateAttr::ConsumedState>(Record[Idx++]));
+    New = new (Context) TestTypestateAttr(Range, Context, testState, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::ThisCall: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ThisCallAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Thread: {
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) ThreadAttr(Range, Context, Spelling);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TransparentUnion: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) TransparentUnionAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TryAcquireCapability: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    Expr * successValue = ReadExpr(F);
+  unsigned argsSize = Record[Idx++];
+  SmallVector<Expr *, 4> args;
+  args.reserve(argsSize);
+    for (unsigned i = argsSize; i; --i)
+    args.push_back(ReadExpr(F));
+    New = new (Context) TryAcquireCapabilityAttr(Range, Context, successValue, args.data(), argsSize, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TypeTagForDatatype: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    IdentifierInfo * argumentKind = GetIdentifierInfo(F, Record, Idx);
+    TypeSourceInfo * matchingCType = GetTypeSourceInfo(F, Record, Idx);
+    bool layoutCompatible = Record[Idx++];
+    bool mustBeNull = Record[Idx++];
+    New = new (Context) TypeTagForDatatypeAttr(Range, Context, argumentKind, matchingCType, layoutCompatible, mustBeNull, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::TypeVisibility: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    TypeVisibilityAttr::VisibilityType visibility(static_cast<TypeVisibilityAttr::VisibilityType>(Record[Idx++]));
+    New = new (Context) TypeVisibilityAttr(Range, Context, visibility, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Unavailable: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string message= ReadString(Record, Idx);
+    New = new (Context) UnavailableAttr(Range, Context, message, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Unused: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) UnusedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Used: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) UsedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Uuid: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string guid= ReadString(Record, Idx);
+    New = new (Context) UuidAttr(Range, Context, guid, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::VecReturn: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) VecReturnAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::VecTypeHint: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    TypeSourceInfo * typeHint = GetTypeSourceInfo(F, Record, Idx);
+    New = new (Context) VecTypeHintAttr(Range, Context, typeHint, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Visibility: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    VisibilityAttr::VisibilityType visibility(static_cast<VisibilityAttr::VisibilityType>(Record[Idx++]));
+    New = new (Context) VisibilityAttr(Range, Context, visibility, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::WarnUnused: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) WarnUnusedAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::WarnUnusedResult: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) WarnUnusedResultAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::Weak: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) WeakAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::WeakImport: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) WeakImportAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::WeakRef: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    std::string aliasee= ReadString(Record, Idx);
+    New = new (Context) WeakRefAttr(Range, Context, aliasee, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::WorkGroupSizeHint: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    unsigned xDim = Record[Idx++];
+    unsigned yDim = Record[Idx++];
+    unsigned zDim = Record[Idx++];
+    New = new (Context) WorkGroupSizeHintAttr(Range, Context, xDim, yDim, zDim, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  case attr::X86ForceAlignArgPointer: {
+    bool isInherited = Record[Idx++];
+    bool isImplicit = Record[Idx++];
+    unsigned Spelling = Record[Idx++];
+    New = new (Context) X86ForceAlignArgPointerAttr(Range, Context, Spelling);
+    cast<InheritableAttr>(New)->setInherited(isInherited);
+    New->setImplicit(isImplicit);
+    break;
+  }
+  }
diff --git a/include/clang/Serialization/AttrPCHWrite.inc b/include/clang/Serialization/AttrPCHWrite.inc
new file mode 100644
index 0000000..d53993a
--- /dev/null
+++ b/include/clang/Serialization/AttrPCHWrite.inc
@@ -0,0 +1,1265 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Attribute serialization code                                                *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+  switch (A->getKind()) {
+  default:
+    llvm_unreachable("Unknown attribute kind!");
+    break;
+  case attr::ARMInterrupt: {
+    const ARMInterruptAttr *SA = cast<ARMInterruptAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getInterrupt());
+    break;
+  }
+  case attr::AcquireCapability: {
+    const AcquireCapabilityAttr *SA = cast<AcquireCapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::AcquiredAfter: {
+    const AcquiredAfterAttr *SA = cast<AcquiredAfterAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::AcquiredBefore: {
+    const AcquiredBeforeAttr *SA = cast<AcquiredBeforeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::Alias: {
+    const AliasAttr *SA = cast<AliasAttr>(A);
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getAliasee(), Record);
+    break;
+  }
+  case attr::AlignMac68k: {
+    const AlignMac68kAttr *SA = cast<AlignMac68kAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Aligned: {
+    const AlignedAttr *SA = cast<AlignedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->isAlignmentExpr());
+    if (SA->isAlignmentExpr())
+      AddStmt(SA->getAlignmentExpr());
+    else
+      AddTypeSourceInfo(SA->getAlignmentType(), Record);
+    break;
+  }
+  case attr::AlwaysInline: {
+    const AlwaysInlineAttr *SA = cast<AlwaysInlineAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::AnalyzerNoReturn: {
+    const AnalyzerNoReturnAttr *SA = cast<AnalyzerNoReturnAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Annotate: {
+    const AnnotateAttr *SA = cast<AnnotateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getAnnotation(), Record);
+    break;
+  }
+  case attr::ArcWeakrefUnavailable: {
+    const ArcWeakrefUnavailableAttr *SA = cast<ArcWeakrefUnavailableAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ArgumentWithTypeTag: {
+    const ArgumentWithTypeTagAttr *SA = cast<ArgumentWithTypeTagAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getArgumentKind(), Record);
+    Record.push_back(SA->getArgumentIdx());
+    Record.push_back(SA->getTypeTagIdx());
+    Record.push_back(SA->getIsPointer());
+    break;
+  }
+  case attr::AsmLabel: {
+    const AsmLabelAttr *SA = cast<AsmLabelAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getLabel(), Record);
+    break;
+  }
+  case attr::AssertCapability: {
+    const AssertCapabilityAttr *SA = cast<AssertCapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getExpr());
+    break;
+  }
+  case attr::AssertExclusiveLock: {
+    const AssertExclusiveLockAttr *SA = cast<AssertExclusiveLockAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::AssertSharedLock: {
+    const AssertSharedLockAttr *SA = cast<AssertSharedLockAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::Availability: {
+    const AvailabilityAttr *SA = cast<AvailabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getPlatform(), Record);
+    AddVersionTuple(SA->getIntroduced(), Record);
+    AddVersionTuple(SA->getDeprecated(), Record);
+    AddVersionTuple(SA->getObsoleted(), Record);
+    Record.push_back(SA->getUnavailable());
+    AddString(SA->getMessage(), Record);
+    break;
+  }
+  case attr::Blocks: {
+    const BlocksAttr *SA = cast<BlocksAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getType());
+    break;
+  }
+  case attr::C11NoReturn: {
+    const C11NoReturnAttr *SA = cast<C11NoReturnAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CDecl: {
+    const CDeclAttr *SA = cast<CDeclAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CFAuditedTransfer: {
+    const CFAuditedTransferAttr *SA = cast<CFAuditedTransferAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CFConsumed: {
+    const CFConsumedAttr *SA = cast<CFConsumedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CFReturnsNotRetained: {
+    const CFReturnsNotRetainedAttr *SA = cast<CFReturnsNotRetainedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CFReturnsRetained: {
+    const CFReturnsRetainedAttr *SA = cast<CFReturnsRetainedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CFUnknownTransfer: {
+    const CFUnknownTransferAttr *SA = cast<CFUnknownTransferAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CUDAConstant: {
+    const CUDAConstantAttr *SA = cast<CUDAConstantAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CUDADevice: {
+    const CUDADeviceAttr *SA = cast<CUDADeviceAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CUDAGlobal: {
+    const CUDAGlobalAttr *SA = cast<CUDAGlobalAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CUDAHost: {
+    const CUDAHostAttr *SA = cast<CUDAHostAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CUDALaunchBounds: {
+    const CUDALaunchBoundsAttr *SA = cast<CUDALaunchBoundsAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getMaxThreads());
+    Record.push_back(SA->getMinBlocks());
+    break;
+  }
+  case attr::CUDAShared: {
+    const CUDASharedAttr *SA = cast<CUDASharedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CXX11NoReturn: {
+    const CXX11NoReturnAttr *SA = cast<CXX11NoReturnAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::CallableWhen: {
+    const CallableWhenAttr *SA = cast<CallableWhenAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->callableStates_size());
+    for (CallableWhenAttr::callableStates_iterator i = SA->callableStates_begin(), e = SA->callableStates_end(); i != e; ++i)
+      Record.push_back((*i));
+    break;
+  }
+  case attr::Capability: {
+    const CapabilityAttr *SA = cast<CapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getName(), Record);
+    break;
+  }
+  case attr::CarriesDependency: {
+    const CarriesDependencyAttr *SA = cast<CarriesDependencyAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Cleanup: {
+    const CleanupAttr *SA = cast<CleanupAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddDeclRef(SA->getFunctionDecl(), Record);
+    break;
+  }
+  case attr::Cold: {
+    const ColdAttr *SA = cast<ColdAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Common: {
+    const CommonAttr *SA = cast<CommonAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Const: {
+    const ConstAttr *SA = cast<ConstAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Constructor: {
+    const ConstructorAttr *SA = cast<ConstructorAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getPriority());
+    break;
+  }
+  case attr::Consumable: {
+    const ConsumableAttr *SA = cast<ConsumableAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getDefaultState());
+    break;
+  }
+  case attr::ConsumableAutoCast: {
+    const ConsumableAutoCastAttr *SA = cast<ConsumableAutoCastAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ConsumableSetOnRead: {
+    const ConsumableSetOnReadAttr *SA = cast<ConsumableSetOnReadAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::DLLExport: {
+    const DLLExportAttr *SA = cast<DLLExportAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::DLLImport: {
+    const DLLImportAttr *SA = cast<DLLImportAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Deprecated: {
+    const DeprecatedAttr *SA = cast<DeprecatedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getMessage(), Record);
+    break;
+  }
+  case attr::Destructor: {
+    const DestructorAttr *SA = cast<DestructorAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getPriority());
+    break;
+  }
+  case attr::EnableIf: {
+    const EnableIfAttr *SA = cast<EnableIfAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getCond());
+    AddString(SA->getMessage(), Record);
+    break;
+  }
+  case attr::ExclusiveTrylockFunction: {
+    const ExclusiveTrylockFunctionAttr *SA = cast<ExclusiveTrylockFunctionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getSuccessValue());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::FallThrough: {
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::FastCall: {
+    const FastCallAttr *SA = cast<FastCallAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Final: {
+    const FinalAttr *SA = cast<FinalAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Flatten: {
+    const FlattenAttr *SA = cast<FlattenAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Format: {
+    const FormatAttr *SA = cast<FormatAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getType(), Record);
+    Record.push_back(SA->getFormatIdx());
+    Record.push_back(SA->getFirstArg());
+    break;
+  }
+  case attr::FormatArg: {
+    const FormatArgAttr *SA = cast<FormatArgAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getFormatIdx());
+    break;
+  }
+  case attr::GNUInline: {
+    const GNUInlineAttr *SA = cast<GNUInlineAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::GuardedBy: {
+    const GuardedByAttr *SA = cast<GuardedByAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getArg());
+    break;
+  }
+  case attr::GuardedVar: {
+    const GuardedVarAttr *SA = cast<GuardedVarAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Hot: {
+    const HotAttr *SA = cast<HotAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::IBAction: {
+    const IBActionAttr *SA = cast<IBActionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::IBOutlet: {
+    const IBOutletAttr *SA = cast<IBOutletAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::IBOutletCollection: {
+    const IBOutletCollectionAttr *SA = cast<IBOutletCollectionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddTypeSourceInfo(SA->getInterfaceLoc(), Record);
+    break;
+  }
+  case attr::InitPriority: {
+    const InitPriorityAttr *SA = cast<InitPriorityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getPriority());
+    break;
+  }
+  case attr::InitSeg: {
+    const InitSegAttr *SA = cast<InitSegAttr>(A);
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getSection(), Record);
+    break;
+  }
+  case attr::IntelOclBicc: {
+    const IntelOclBiccAttr *SA = cast<IntelOclBiccAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::LockReturned: {
+    const LockReturnedAttr *SA = cast<LockReturnedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getArg());
+    break;
+  }
+  case attr::LocksExcluded: {
+    const LocksExcludedAttr *SA = cast<LocksExcludedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::LoopHint: {
+    const LoopHintAttr *SA = cast<LoopHintAttr>(A);
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getOption());
+    Record.push_back(SA->getValue());
+    break;
+  }
+  case attr::MSABI: {
+    const MSABIAttr *SA = cast<MSABIAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::MSInheritance: {
+    const MSInheritanceAttr *SA = cast<MSInheritanceAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getBestCase());
+    break;
+  }
+  case attr::MSP430Interrupt: {
+    const MSP430InterruptAttr *SA = cast<MSP430InterruptAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getNumber());
+    break;
+  }
+  case attr::MSVtorDisp: {
+    const MSVtorDispAttr *SA = cast<MSVtorDispAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getVdm());
+    break;
+  }
+  case attr::Malloc: {
+    const MallocAttr *SA = cast<MallocAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::MaxFieldAlignment: {
+    const MaxFieldAlignmentAttr *SA = cast<MaxFieldAlignmentAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getAlignment());
+    break;
+  }
+  case attr::MayAlias: {
+    const MayAliasAttr *SA = cast<MayAliasAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::MinSize: {
+    const MinSizeAttr *SA = cast<MinSizeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Mips16: {
+    const Mips16Attr *SA = cast<Mips16Attr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Mode: {
+    const ModeAttr *SA = cast<ModeAttr>(A);
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getMode(), Record);
+    break;
+  }
+  case attr::MsStruct: {
+    const MsStructAttr *SA = cast<MsStructAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NSConsumed: {
+    const NSConsumedAttr *SA = cast<NSConsumedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NSConsumesSelf: {
+    const NSConsumesSelfAttr *SA = cast<NSConsumesSelfAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NSReturnsAutoreleased: {
+    const NSReturnsAutoreleasedAttr *SA = cast<NSReturnsAutoreleasedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NSReturnsNotRetained: {
+    const NSReturnsNotRetainedAttr *SA = cast<NSReturnsNotRetainedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NSReturnsRetained: {
+    const NSReturnsRetainedAttr *SA = cast<NSReturnsRetainedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Naked: {
+    const NakedAttr *SA = cast<NakedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoCommon: {
+    const NoCommonAttr *SA = cast<NoCommonAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoDebug: {
+    const NoDebugAttr *SA = cast<NoDebugAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoDuplicate: {
+    const NoDuplicateAttr *SA = cast<NoDuplicateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoInline: {
+    const NoInlineAttr *SA = cast<NoInlineAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoInstrumentFunction: {
+    const NoInstrumentFunctionAttr *SA = cast<NoInstrumentFunctionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoMips16: {
+    const NoMips16Attr *SA = cast<NoMips16Attr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoReturn: {
+    const NoReturnAttr *SA = cast<NoReturnAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoSanitizeAddress: {
+    const NoSanitizeAddressAttr *SA = cast<NoSanitizeAddressAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoSanitizeMemory: {
+    const NoSanitizeMemoryAttr *SA = cast<NoSanitizeMemoryAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoSanitizeThread: {
+    const NoSanitizeThreadAttr *SA = cast<NoSanitizeThreadAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoSplitStack: {
+    const NoSplitStackAttr *SA = cast<NoSplitStackAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoThreadSafetyAnalysis: {
+    const NoThreadSafetyAnalysisAttr *SA = cast<NoThreadSafetyAnalysisAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NoThrow: {
+    const NoThrowAttr *SA = cast<NoThrowAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::NonNull: {
+    const NonNullAttr *SA = cast<NonNullAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      Record.push_back(Val);
+    break;
+  }
+  case attr::ObjCBridge: {
+    const ObjCBridgeAttr *SA = cast<ObjCBridgeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getBridgedType(), Record);
+    break;
+  }
+  case attr::ObjCBridgeMutable: {
+    const ObjCBridgeMutableAttr *SA = cast<ObjCBridgeMutableAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getBridgedType(), Record);
+    break;
+  }
+  case attr::ObjCBridgeRelated: {
+    const ObjCBridgeRelatedAttr *SA = cast<ObjCBridgeRelatedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getRelatedClass(), Record);
+    AddIdentifierRef(SA->getClassMethod(), Record);
+    AddIdentifierRef(SA->getInstanceMethod(), Record);
+    break;
+  }
+  case attr::ObjCDesignatedInitializer: {
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCException: {
+    const ObjCExceptionAttr *SA = cast<ObjCExceptionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCExplicitProtocolImpl: {
+    const ObjCExplicitProtocolImplAttr *SA = cast<ObjCExplicitProtocolImplAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCMethodFamily: {
+    const ObjCMethodFamilyAttr *SA = cast<ObjCMethodFamilyAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getFamily());
+    break;
+  }
+  case attr::ObjCNSObject: {
+    const ObjCNSObjectAttr *SA = cast<ObjCNSObjectAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCPreciseLifetime: {
+    const ObjCPreciseLifetimeAttr *SA = cast<ObjCPreciseLifetimeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCRequiresPropertyDefs: {
+    const ObjCRequiresPropertyDefsAttr *SA = cast<ObjCRequiresPropertyDefsAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCRequiresSuper: {
+    const ObjCRequiresSuperAttr *SA = cast<ObjCRequiresSuperAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCReturnsInnerPointer: {
+    const ObjCReturnsInnerPointerAttr *SA = cast<ObjCReturnsInnerPointerAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCRootClass: {
+    const ObjCRootClassAttr *SA = cast<ObjCRootClassAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ObjCRuntimeName: {
+    const ObjCRuntimeNameAttr *SA = cast<ObjCRuntimeNameAttr>(A);
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getMetadataName(), Record);
+    break;
+  }
+  case attr::OpenCLImageAccess: {
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::OpenCLKernel: {
+    const OpenCLKernelAttr *SA = cast<OpenCLKernelAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::OptimizeNone: {
+    const OptimizeNoneAttr *SA = cast<OptimizeNoneAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Overloadable: {
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Override: {
+    const OverrideAttr *SA = cast<OverrideAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Ownership: {
+    const OwnershipAttr *SA = cast<OwnershipAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getModule(), Record);
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      Record.push_back(Val);
+    break;
+  }
+  case attr::Packed: {
+    const PackedAttr *SA = cast<PackedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ParamTypestate: {
+    const ParamTypestateAttr *SA = cast<ParamTypestateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getParamState());
+    break;
+  }
+  case attr::Pascal: {
+    const PascalAttr *SA = cast<PascalAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Pcs: {
+    const PcsAttr *SA = cast<PcsAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getPCS());
+    break;
+  }
+  case attr::PnaclCall: {
+    const PnaclCallAttr *SA = cast<PnaclCallAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::PtGuardedBy: {
+    const PtGuardedByAttr *SA = cast<PtGuardedByAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getArg());
+    break;
+  }
+  case attr::PtGuardedVar: {
+    const PtGuardedVarAttr *SA = cast<PtGuardedVarAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Pure: {
+    const PureAttr *SA = cast<PureAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ReleaseCapability: {
+    const ReleaseCapabilityAttr *SA = cast<ReleaseCapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::ReqdWorkGroupSize: {
+    const ReqdWorkGroupSizeAttr *SA = cast<ReqdWorkGroupSizeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getXDim());
+    Record.push_back(SA->getYDim());
+    Record.push_back(SA->getZDim());
+    break;
+  }
+  case attr::RequiresCapability: {
+    const RequiresCapabilityAttr *SA = cast<RequiresCapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::ReturnTypestate: {
+    const ReturnTypestateAttr *SA = cast<ReturnTypestateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getState());
+    break;
+  }
+  case attr::ReturnsNonNull: {
+    const ReturnsNonNullAttr *SA = cast<ReturnsNonNullAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ReturnsTwice: {
+    const ReturnsTwiceAttr *SA = cast<ReturnsTwiceAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::ScopedLockable: {
+    const ScopedLockableAttr *SA = cast<ScopedLockableAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Section: {
+    const SectionAttr *SA = cast<SectionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getName(), Record);
+    break;
+  }
+  case attr::SelectAny: {
+    const SelectAnyAttr *SA = cast<SelectAnyAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Sentinel: {
+    const SentinelAttr *SA = cast<SentinelAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getSentinel());
+    Record.push_back(SA->getNullPos());
+    break;
+  }
+  case attr::SetTypestate: {
+    const SetTypestateAttr *SA = cast<SetTypestateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getNewState());
+    break;
+  }
+  case attr::SharedTrylockFunction: {
+    const SharedTrylockFunctionAttr *SA = cast<SharedTrylockFunctionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getSuccessValue());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::StdCall: {
+    const StdCallAttr *SA = cast<StdCallAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::SysVABI: {
+    const SysVABIAttr *SA = cast<SysVABIAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::TLSModel: {
+    const TLSModelAttr *SA = cast<TLSModelAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getModel(), Record);
+    break;
+  }
+  case attr::TestTypestate: {
+    const TestTypestateAttr *SA = cast<TestTypestateAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getTestState());
+    break;
+  }
+  case attr::ThisCall: {
+    const ThisCallAttr *SA = cast<ThisCallAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Thread: {
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::TransparentUnion: {
+    const TransparentUnionAttr *SA = cast<TransparentUnionAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::TryAcquireCapability: {
+    const TryAcquireCapabilityAttr *SA = cast<TryAcquireCapabilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddStmt(SA->getSuccessValue());
+    Record.push_back(SA->args_size());
+    for (auto &Val : SA->args())
+      AddStmt(Val);
+    break;
+  }
+  case attr::TypeTagForDatatype: {
+    const TypeTagForDatatypeAttr *SA = cast<TypeTagForDatatypeAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddIdentifierRef(SA->getArgumentKind(), Record);
+    AddTypeSourceInfo(SA->getMatchingCTypeLoc(), Record);
+    Record.push_back(SA->getLayoutCompatible());
+    Record.push_back(SA->getMustBeNull());
+    break;
+  }
+  case attr::TypeVisibility: {
+    const TypeVisibilityAttr *SA = cast<TypeVisibilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getVisibility());
+    break;
+  }
+  case attr::Unavailable: {
+    const UnavailableAttr *SA = cast<UnavailableAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getMessage(), Record);
+    break;
+  }
+  case attr::Unused: {
+    const UnusedAttr *SA = cast<UnusedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Used: {
+    const UsedAttr *SA = cast<UsedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Uuid: {
+    const UuidAttr *SA = cast<UuidAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getGuid(), Record);
+    break;
+  }
+  case attr::VecReturn: {
+    const VecReturnAttr *SA = cast<VecReturnAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::VecTypeHint: {
+    const VecTypeHintAttr *SA = cast<VecTypeHintAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddTypeSourceInfo(SA->getTypeHintLoc(), Record);
+    break;
+  }
+  case attr::Visibility: {
+    const VisibilityAttr *SA = cast<VisibilityAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+Record.push_back(SA->getVisibility());
+    break;
+  }
+  case attr::WarnUnused: {
+    const WarnUnusedAttr *SA = cast<WarnUnusedAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::WarnUnusedResult: {
+    const WarnUnusedResultAttr *SA = cast<WarnUnusedResultAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::Weak: {
+    const WeakAttr *SA = cast<WeakAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::WeakImport: {
+    const WeakImportAttr *SA = cast<WeakImportAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  case attr::WeakRef: {
+    const WeakRefAttr *SA = cast<WeakRefAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    AddString(SA->getAliasee(), Record);
+    break;
+  }
+  case attr::WorkGroupSizeHint: {
+    const WorkGroupSizeHintAttr *SA = cast<WorkGroupSizeHintAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    Record.push_back(SA->getXDim());
+    Record.push_back(SA->getYDim());
+    Record.push_back(SA->getZDim());
+    break;
+  }
+  case attr::X86ForceAlignArgPointer: {
+    const X86ForceAlignArgPointerAttr *SA = cast<X86ForceAlignArgPointerAttr>(A);
+    Record.push_back(SA->isInherited());
+    Record.push_back(A->isImplicit());
+    Record.push_back(A->getSpellingListIndex());
+    break;
+  }
+  }
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
new file mode 100644
index 0000000..f8ef8a1
--- /dev/null
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -0,0 +1,131 @@
+//===--- ContinuousRangeMap.h - Map with int range as key -------*- 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 ContinuousRangeMap class, which is a highly
+//  specialized container used by serialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
+#define LLVM_CLANG_SERIALIZATION_CONTINUOUS_RANGE_MAP_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+#include <algorithm>
+#include <utility>
+
+namespace clang {
+
+/// \brief A map from continuous integer ranges to some value, with a very
+/// specialized interface.
+///
+/// CRM maps from integer ranges to values. The ranges are continuous, i.e.
+/// where one ends, the next one begins. So if the map contains the stops I0-3,
+/// the first range is from I0 to I1, the second from I1 to I2, the third from
+/// I2 to I3 and the last from I3 to infinity.
+///
+/// Ranges must be inserted in order. Inserting a new stop I4 into the map will
+/// shrink the fourth range to I3 to I4 and add the new range I4 to inf.
+template <typename Int, typename V, unsigned InitialCapacity>
+class ContinuousRangeMap {
+public:
+  typedef std::pair<Int, V> value_type;
+  typedef value_type &reference;
+  typedef const value_type &const_reference;
+  typedef value_type *pointer;
+  typedef const value_type *const_pointer;
+
+private:
+  typedef SmallVector<value_type, InitialCapacity> Representation;
+  Representation Rep;
+
+  struct Compare {
+    bool operator ()(const_reference L, Int R) const {
+      return L.first < R;
+    }
+    bool operator ()(Int L, const_reference R) const {
+      return L < R.first;
+    }
+    bool operator ()(Int L, Int R) const { 
+      return L < R;
+    }
+    bool operator ()(const_reference L, const_reference R) const {
+      return L.first < R.first;
+    }
+  };
+
+public:
+  void insert(const value_type &Val) {
+    if (!Rep.empty() && Rep.back() == Val)
+      return;
+
+    assert((Rep.empty() || Rep.back().first < Val.first) &&
+           "Must insert keys in order.");
+    Rep.push_back(Val);
+  }
+  
+  void insertOrReplace(const value_type &Val) {
+    iterator I = std::lower_bound(Rep.begin(), Rep.end(), Val, Compare());
+    if (I != Rep.end() && I->first == Val.first) {
+      I->second = Val.second;
+      return;
+    }
+    
+    Rep.insert(I, Val);
+  }
+
+  typedef typename Representation::iterator iterator;
+  typedef typename Representation::const_iterator const_iterator;
+
+  iterator begin() { return Rep.begin(); }
+  iterator end() { return Rep.end(); }
+  const_iterator begin() const { return Rep.begin(); }
+  const_iterator end() const { return Rep.end(); }
+
+  iterator find(Int K) {
+    iterator I = std::upper_bound(Rep.begin(), Rep.end(), K, Compare());
+    // I points to the first entry with a key > K, which is the range that
+    // follows the one containing K.
+    if (I == Rep.begin())
+      return Rep.end();
+    --I;
+    return I;
+  }
+  const_iterator find(Int K) const {
+    return const_cast<ContinuousRangeMap*>(this)->find(K);
+  }
+
+  reference back() { return Rep.back(); }
+  const_reference back() const { return Rep.back(); }
+  
+  /// \brief An object that helps properly build a continuous range map
+  /// from a set of values.
+  class Builder {
+    ContinuousRangeMap &Self;
+    
+    Builder(const Builder&) LLVM_DELETED_FUNCTION;
+    Builder &operator=(const Builder&) LLVM_DELETED_FUNCTION;
+    
+  public:
+    explicit Builder(ContinuousRangeMap &Self) : Self(Self) { }
+    
+    ~Builder() {
+      std::sort(Self.Rep.begin(), Self.Rep.end(), Compare());
+    }
+    
+    void insert(const value_type &Val) {
+      Self.Rep.push_back(Val);
+    }
+  };
+  friend class Builder;
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
new file mode 100644
index 0000000..1f0d752
--- /dev/null
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -0,0 +1,203 @@
+//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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 GlobalModuleIndex class, which manages a global index
+// containing all of the identifiers known to the various modules within a given
+// subdirectory of the module cache. It is used to improve the performance of
+// queries such as "do any modules know about this identifier?"
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+#define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <utility>
+
+namespace llvm {
+class BitstreamCursor;
+class MemoryBuffer;
+}
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class FileManager;
+class IdentifierIterator;
+
+namespace serialization {
+  class ModuleFile;
+}
+
+using llvm::SmallVector;
+using llvm::SmallVectorImpl;
+using llvm::StringRef;
+using serialization::ModuleFile;
+
+/// \brief A global index for a set of module files, providing information about
+/// the identifiers within those module files.
+///
+/// The global index is an aid for name lookup into modules, offering a central
+/// place where one can look for identifiers determine which
+/// module files contain any information about that identifier. This
+/// allows the client to restrict the search to only those module files known
+/// to have a information about that identifier, improving performance. Moreover,
+/// the global module index may know about module files that have not been
+/// imported, and can be queried to determine which modules the current
+/// translation could or should load to fix a problem.
+class GlobalModuleIndex {
+  /// \brief Buffer containing the index file, which is lazily accessed so long
+  /// as the global module index is live.
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+  /// \brief The hash table.
+  ///
+  /// This pointer actually points to a IdentifierIndexTable object,
+  /// but that type is only accessible within the implementation of
+  /// GlobalModuleIndex.
+  void *IdentifierIndex;
+
+  /// \brief Information about a given module file.
+  struct ModuleInfo {
+    ModuleInfo() : File(), Size(), ModTime() { }
+
+    /// \brief The module file, once it has been resolved.
+    ModuleFile *File;
+
+    /// \brief The module file name.
+    std::string FileName;
+
+    /// \brief Size of the module file at the time the global index was built.
+    off_t Size;
+
+    /// \brief Modification time of the module file at the time the global
+    /// index was built.
+    time_t ModTime;
+
+    /// \brief The module IDs on which this module directly depends.
+    /// FIXME: We don't really need a vector here.
+    llvm::SmallVector<unsigned, 4> Dependencies;
+  };
+
+  /// \brief A mapping from module IDs to information about each module.
+  ///
+  /// This vector may have gaps, if module files have been removed or have
+  /// been updated since the index was built. A gap is indicated by an empty
+  /// file name.
+  llvm::SmallVector<ModuleInfo, 16> Modules;
+
+  /// \brief Lazily-populated mapping from module files to their
+  /// corresponding index into the \c Modules vector.
+  llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
+
+  /// \brief The set of modules that have not yet been resolved.
+  ///
+  /// The string is just the name of the module itself, which maps to the
+  /// module ID.
+  llvm::StringMap<unsigned> UnresolvedModules;
+
+  /// \brief The number of identifier lookups we performed.
+  unsigned NumIdentifierLookups;
+
+  /// \brief The number of identifier lookup hits, where we recognize the
+  /// identifier.
+  unsigned NumIdentifierLookupHits;
+  
+  /// \brief Internal constructor. Use \c readIndex() to read an index.
+  explicit GlobalModuleIndex(llvm::MemoryBuffer *Buffer,
+                             llvm::BitstreamCursor Cursor);
+
+  GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+  GlobalModuleIndex &operator=(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION;
+
+public:
+  ~GlobalModuleIndex();
+
+  /// \brief An error code returned when trying to read an index.
+  enum ErrorCode {
+    /// \brief No error occurred.
+    EC_None,
+    /// \brief No index was found.
+    EC_NotFound,
+    /// \brief Some other process is currently building the index; it is not
+    /// available yet.
+    EC_Building,
+    /// \brief There was an unspecified I/O error reading or writing the index.
+    EC_IOError
+  };
+
+  /// \brief Read a global index file for the given directory.
+  ///
+  /// \param Path The path to the specific module cache where the module files
+  /// for the intended configuration reside.
+  ///
+  /// \returns A pair containing the global module index (if it exists) and
+  /// the error code.
+  static std::pair<GlobalModuleIndex *, ErrorCode>
+  readIndex(StringRef Path);
+
+  /// \brief Returns an iterator for identifiers stored in the index table.
+  ///
+  /// The caller accepts ownership of the returned object.
+  IdentifierIterator *createIdentifierIterator() const;
+
+  /// \brief Retrieve the set of modules that have up-to-date indexes.
+  ///
+  /// \param ModuleFiles Will be populated with the set of module files that
+  /// have been indexed.
+  void getKnownModules(SmallVectorImpl<ModuleFile *> &ModuleFiles);
+
+  /// \brief Retrieve the set of module files on which the given module file
+  /// directly depends.
+  void getModuleDependencies(ModuleFile *File,
+                             SmallVectorImpl<ModuleFile *> &Dependencies);
+
+  /// \brief A set of module files in which we found a result.
+  typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
+  
+  /// \brief Look for all of the module files with information about the given
+  /// identifier, e.g., a global function, variable, or type with that name.
+  ///
+  /// \param Name The identifier to look for.
+  ///
+  /// \param Hits Will be populated with the set of module files that have
+  /// information about this name.
+  ///
+  /// \returns true if the identifier is known to the index, false otherwise.
+  bool lookupIdentifier(StringRef Name, HitSet &Hits);
+
+  /// \brief Note that the given module file has been loaded.
+  ///
+  /// \returns false if the global module index has information about this
+  /// module file, and true otherwise.
+  bool loadedModuleFile(ModuleFile *File);
+
+  /// \brief Print statistics to standard error.
+  void printStats();
+
+  /// \brief Print debugging view to standard error.
+  void dump();
+
+  /// \brief Write a global index into the given
+  ///
+  /// \param FileMgr The file manager to use to load module files.
+  ///
+  /// \param Path The path to the directory containing module files, into
+  /// which the global index will be written.
+  static ErrorCode writeIndex(FileManager &FileMgr, StringRef Path);
+};
+
+}
+
+#endif
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
new file mode 100644
index 0000000..4952039
--- /dev/null
+++ b/include/clang/Serialization/Module.h
@@ -0,0 +1,469 @@
+//===--- Module.h - Module description --------------------------*- 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 Module class, which describes a module that has
+//  been loaded from an AST file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_MODULE_H
+#define LLVM_CLANG_SERIALIZATION_MODULE_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Serialization/ASTBitCodes.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+template <typename Info> class OnDiskChainedHashTable;
+template <typename Info> class OnDiskIterableChainedHashTable;
+}
+
+namespace clang {
+
+class FileEntry;
+class DeclContext;
+class Module;
+
+namespace serialization {
+
+namespace reader {
+  class ASTDeclContextNameLookupTrait;
+}
+
+/// \brief Specifies the kind of module that has been loaded.
+enum ModuleKind {
+  MK_Module,   ///< File is a module proper.
+  MK_PCH,      ///< File is a PCH file treated as such.
+  MK_Preamble, ///< File is a PCH file treated as the preamble.
+  MK_MainFile  ///< File is a PCH file treated as the actual main file.
+};
+
+/// \brief Information about the contents of a DeclContext.
+struct DeclContextInfo {
+  DeclContextInfo()
+    : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
+
+  llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
+    *NameLookupTableData; // an ASTDeclContextNameLookupTable.
+  const KindDeclIDPair *LexicalDecls;
+  unsigned NumLexicalDecls;
+};
+
+/// \brief The input file that has been loaded from this AST file, along with
+/// bools indicating whether this was an overridden buffer or if it was
+/// out-of-date or not-found.
+class InputFile {
+  enum {
+    Overridden = 1,
+    OutOfDate = 2,
+    NotFound = 3
+  };
+  llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
+
+public:
+  InputFile() {}
+  InputFile(const FileEntry *File,
+            bool isOverridden = false, bool isOutOfDate = false) {
+    assert(!(isOverridden && isOutOfDate) &&
+           "an overridden cannot be out-of-date");
+    unsigned intVal = 0;
+    if (isOverridden)
+      intVal = Overridden;
+    else if (isOutOfDate)
+      intVal = OutOfDate;
+    Val.setPointerAndInt(File, intVal);
+  }
+
+  static InputFile getNotFound() {
+    InputFile File;
+    File.Val.setInt(NotFound);
+    return File;
+  }
+
+  const FileEntry *getFile() const { return Val.getPointer(); }
+  bool isOverridden() const { return Val.getInt() == Overridden; }
+  bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
+  bool isNotFound() const { return Val.getInt() == NotFound; }
+};
+
+/// \brief Information about a module that has been loaded by the ASTReader.
+///
+/// Each instance of the Module class corresponds to a single AST file, which
+/// may be a precompiled header, precompiled preamble, a module, or an AST file
+/// of some sort loaded as the main file, all of which are specific formulations
+/// of the general notion of a "module". A module may depend on any number of
+/// other modules.
+class ModuleFile {
+public:
+  ModuleFile(ModuleKind Kind, unsigned Generation);
+  ~ModuleFile();
+
+  // === General information ===
+
+  /// \brief The index of this module in the list of modules.
+  unsigned Index;
+
+  /// \brief The type of this module.
+  ModuleKind Kind;
+
+  /// \brief The file name of the module file.
+  std::string FileName;
+
+  /// \brief The name of the module.
+  std::string ModuleName;
+
+  std::string getTimestampFilename() const {
+    return FileName + ".timestamp";
+  }
+
+  /// \brief The original source file name that was used to build the
+  /// primary AST file, which may have been modified for
+  /// relocatable-pch support.
+  std::string OriginalSourceFileName;
+
+  /// \brief The actual original source file name that was used to
+  /// build this AST file.
+  std::string ActualOriginalSourceFileName;
+
+  /// \brief The file ID for the original source file that was used to
+  /// build this AST file.
+  FileID OriginalSourceFileID;
+
+  /// \brief The directory that the PCH was originally created in. Used to
+  /// allow resolving headers even after headers+PCH was moved to a new path.
+  std::string OriginalDir;
+
+  std::string ModuleMapPath;
+
+  /// \brief Whether this precompiled header is a relocatable PCH file.
+  bool RelocatablePCH;
+
+  /// \brief The file entry for the module file.
+  const FileEntry *File;
+
+  /// \brief Whether this module has been directly imported by the
+  /// user.
+  bool DirectlyImported;
+
+  /// \brief The generation of which this module file is a part.
+  unsigned Generation;
+  
+  /// \brief The memory buffer that stores the data associated with
+  /// this AST file.
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+  /// \brief The size of this file, in bits.
+  uint64_t SizeInBits;
+
+  /// \brief The global bit offset (or base) of this module
+  uint64_t GlobalBitOffset;
+
+  /// \brief The bitstream reader from which we'll read the AST file.
+  llvm::BitstreamReader StreamFile;
+
+  /// \brief The main bitstream cursor for the main block.
+  llvm::BitstreamCursor Stream;
+
+  /// \brief The source location where the module was explicitly or implicitly
+  /// imported in the local translation unit.
+  ///
+  /// If module A depends on and imports module B, both modules will have the
+  /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
+  /// source location inside module A).
+  ///
+  /// WARNING: This is largely useless. It doesn't tell you when a module was
+  /// made visible, just when the first submodule of that module was imported.
+  SourceLocation DirectImportLoc;
+
+  /// \brief The source location where this module was first imported.
+  SourceLocation ImportLoc;
+
+  /// \brief The first source location in this module.
+  SourceLocation FirstLoc;
+
+  // === Input Files ===
+  /// \brief The cursor to the start of the input-files block.
+  llvm::BitstreamCursor InputFilesCursor;
+
+  /// \brief Offsets for all of the input file entries in the AST file.
+  const uint32_t *InputFileOffsets;
+
+  /// \brief The input files that have been loaded from this AST file.
+  std::vector<InputFile> InputFilesLoaded;
+
+  /// \brief If non-zero, specifies the time when we last validated input
+  /// files.  Zero means we never validated them.
+  ///
+  /// The time is specified in seconds since the start of the Epoch.
+  uint64_t InputFilesValidationTimestamp;
+
+  // === Source Locations ===
+
+  /// \brief Cursor used to read source location entries.
+  llvm::BitstreamCursor SLocEntryCursor;
+
+  /// \brief The number of source location entries in this AST file.
+  unsigned LocalNumSLocEntries;
+
+  /// \brief The base ID in the source manager's view of this module.
+  int SLocEntryBaseID;
+
+  /// \brief The base offset in the source manager's view of this module.
+  unsigned SLocEntryBaseOffset;
+
+  /// \brief Offsets for all of the source location entries in the
+  /// AST file.
+  const uint32_t *SLocEntryOffsets;
+
+  /// \brief SLocEntries that we're going to preload.
+  SmallVector<uint64_t, 4> PreloadSLocEntries;
+
+  /// \brief Remapping table for source locations in this module.
+  ContinuousRangeMap<uint32_t, int, 2> SLocRemap;
+
+  // === Identifiers ===
+
+  /// \brief The number of identifiers in this AST file.
+  unsigned LocalNumIdentifiers;
+
+  /// \brief Offsets into the identifier table data.
+  ///
+  /// This array is indexed by the identifier ID (-1), and provides
+  /// the offset into IdentifierTableData where the string data is
+  /// stored.
+  const uint32_t *IdentifierOffsets;
+
+  /// \brief Base identifier ID for identifiers local to this module.
+  serialization::IdentID BaseIdentifierID;
+
+  /// \brief Remapping table for identifier IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
+
+  /// \brief Actual data for the on-disk hash table of identifiers.
+  ///
+  /// This pointer points into a memory buffer, where the on-disk hash
+  /// table for identifiers actually lives.
+  const char *IdentifierTableData;
+
+  /// \brief A pointer to an on-disk hash table of opaque type
+  /// IdentifierHashTable.
+  void *IdentifierLookupTable;
+
+  // === Macros ===
+
+  /// \brief The cursor to the start of the preprocessor block, which stores
+  /// all of the macro definitions.
+  llvm::BitstreamCursor MacroCursor;
+
+  /// \brief The number of macros in this AST file.
+  unsigned LocalNumMacros;
+
+  /// \brief Offsets of macros in the preprocessor block.
+  ///
+  /// This array is indexed by the macro ID (-1), and provides
+  /// the offset into the preprocessor block where macro definitions are
+  /// stored.
+  const uint32_t *MacroOffsets;
+
+  /// \brief Base macro ID for macros local to this module.
+  serialization::MacroID BaseMacroID;
+
+  /// \brief Remapping table for macro IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
+
+  /// \brief The offset of the start of the set of defined macros.
+  uint64_t MacroStartOffset;
+
+  // === Detailed PreprocessingRecord ===
+
+  /// \brief The cursor to the start of the (optional) detailed preprocessing
+  /// record block.
+  llvm::BitstreamCursor PreprocessorDetailCursor;
+
+  /// \brief The offset of the start of the preprocessor detail cursor.
+  uint64_t PreprocessorDetailStartOffset;
+
+  /// \brief Base preprocessed entity ID for preprocessed entities local to
+  /// this module.
+  serialization::PreprocessedEntityID BasePreprocessedEntityID;
+
+  /// \brief Remapping table for preprocessed entity IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
+
+  const PPEntityOffset *PreprocessedEntityOffsets;
+  unsigned NumPreprocessedEntities;
+
+  // === Header search information ===
+
+  /// \brief The number of local HeaderFileInfo structures.
+  unsigned LocalNumHeaderFileInfos;
+
+  /// \brief Actual data for the on-disk hash table of header file
+  /// information.
+  ///
+  /// This pointer points into a memory buffer, where the on-disk hash
+  /// table for header file information actually lives.
+  const char *HeaderFileInfoTableData;
+
+  /// \brief The on-disk hash table that contains information about each of
+  /// the header files.
+  void *HeaderFileInfoTable;
+
+  // === Submodule information ===  
+  /// \brief The number of submodules in this module.
+  unsigned LocalNumSubmodules;
+  
+  /// \brief Base submodule ID for submodules local to this module.
+  serialization::SubmoduleID BaseSubmoduleID;
+  
+  /// \brief Remapping table for submodule IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
+  
+  // === Selectors ===
+
+  /// \brief The number of selectors new to this file.
+  ///
+  /// This is the number of entries in SelectorOffsets.
+  unsigned LocalNumSelectors;
+
+  /// \brief Offsets into the selector lookup table's data array
+  /// where each selector resides.
+  const uint32_t *SelectorOffsets;
+
+  /// \brief Base selector ID for selectors local to this module.
+  serialization::SelectorID BaseSelectorID;
+
+  /// \brief Remapping table for selector IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
+
+  /// \brief A pointer to the character data that comprises the selector table
+  ///
+  /// The SelectorOffsets table refers into this memory.
+  const unsigned char *SelectorLookupTableData;
+
+  /// \brief A pointer to an on-disk hash table of opaque type
+  /// ASTSelectorLookupTable.
+  ///
+  /// This hash table provides the IDs of all selectors, and the associated
+  /// instance and factory methods.
+  void *SelectorLookupTable;
+
+  // === Declarations ===
+
+  /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It
+  /// has read all the abbreviations at the start of the block and is ready to
+  /// jump around with these in context.
+  llvm::BitstreamCursor DeclsCursor;
+
+  /// \brief The number of declarations in this AST file.
+  unsigned LocalNumDecls;
+
+  /// \brief Offset of each declaration within the bitstream, indexed
+  /// by the declaration ID (-1).
+  const DeclOffset *DeclOffsets;
+
+  /// \brief Base declaration ID for declarations local to this module.
+  serialization::DeclID BaseDeclID;
+
+  /// \brief Remapping table for declaration IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
+
+  /// \brief Mapping from the module files that this module file depends on
+  /// to the base declaration ID for that module as it is understood within this
+  /// module.
+  ///
+  /// This is effectively a reverse global-to-local mapping for declaration
+  /// IDs, so that we can interpret a true global ID (for this translation unit)
+  /// as a local ID (for this module file).
+  llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
+
+  /// \brief The number of C++ base specifier sets in this AST file.
+  unsigned LocalNumCXXBaseSpecifiers;
+
+  /// \brief Offset of each C++ base specifier set within the bitstream,
+  /// indexed by the C++ base specifier set ID (-1).
+  const uint32_t *CXXBaseSpecifiersOffsets;
+
+  typedef llvm::DenseMap<const DeclContext *, DeclContextInfo>
+  DeclContextInfosMap;
+
+  /// \brief Information about the lexical and visible declarations
+  /// for each DeclContext.
+  DeclContextInfosMap DeclContextInfos;
+
+  /// \brief Array of file-level DeclIDs sorted by file.
+  const serialization::DeclID *FileSortedDecls;
+  unsigned NumFileSortedDecls;
+
+  /// \brief Array of redeclaration chain location information within this 
+  /// module file, sorted by the first declaration ID.
+  const serialization::LocalRedeclarationsInfo *RedeclarationsMap;
+
+  /// \brief The number of redeclaration info entries in RedeclarationsMap.
+  unsigned LocalNumRedeclarationsInMap;
+  
+  /// \brief The redeclaration chains for declarations local to this
+  /// module file.
+  SmallVector<uint64_t, 1> RedeclarationChains;
+  
+  /// \brief Array of category list location information within this 
+  /// module file, sorted by the definition ID.
+  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
+  
+  /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
+  unsigned LocalNumObjCCategoriesInMap;
+  
+  /// \brief The Objective-C category lists for categories known to this
+  /// module.
+  SmallVector<uint64_t, 1> ObjCCategories;
+
+  // === Types ===
+
+  /// \brief The number of types in this AST file.
+  unsigned LocalNumTypes;
+
+  /// \brief Offset of each type within the bitstream, indexed by the
+  /// type ID, or the representation of a Type*.
+  const uint32_t *TypeOffsets;
+
+  /// \brief Base type ID for types local to this module as represented in
+  /// the global type ID space.
+  serialization::TypeID BaseTypeIndex;
+
+  /// \brief Remapping table for type IDs in this module.
+  ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
+
+  // === Miscellaneous ===
+
+  /// \brief Diagnostic IDs and their mappings that the user changed.
+  SmallVector<uint64_t, 8> PragmaDiagMappings;
+
+  /// \brief List of modules which depend on this module
+  llvm::SetVector<ModuleFile *> ImportedBy;
+
+  /// \brief List of modules which this module depends on
+  llvm::SetVector<ModuleFile *> Imports;
+
+  /// \brief Determine whether this module was directly imported at
+  /// any point during translation.
+  bool isDirectlyImported() const { return DirectlyImported; }
+
+  /// \brief Dump debugging output for this module.
+  void dump();
+};
+
+} // end namespace serialization
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
new file mode 100644
index 0000000..3259902
--- /dev/null
+++ b/include/clang/Serialization/ModuleManager.h
@@ -0,0 +1,285 @@
+//===--- ModuleManager.cpp - Module Manager ---------------------*- 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 ModuleManager class, which manages a set of loaded
+//  modules for the ASTReader.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
+#define LLVM_CLANG_SERIALIZATION_MODULE_MANAGER_H
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Serialization/Module.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang { 
+
+class GlobalModuleIndex;
+class ModuleMap;
+
+namespace serialization {
+
+/// \brief Manages the set of modules loaded by an AST reader.
+class ModuleManager {
+  /// \brief The chain of AST files. The first entry is the one named by the
+  /// user, the last one is the one that doesn't depend on anything further.
+  SmallVector<ModuleFile *, 2> Chain;
+  
+  /// \brief All loaded modules, indexed by name.
+  llvm::DenseMap<const FileEntry *, ModuleFile *> Modules;
+  
+  /// \brief FileManager that handles translating between filenames and
+  /// FileEntry *.
+  FileManager &FileMgr;
+  
+  /// \brief A lookup of in-memory (virtual file) buffers
+  llvm::DenseMap<const FileEntry *, llvm::MemoryBuffer *> InMemoryBuffers;
+
+  /// \brief The visitation order.
+  SmallVector<ModuleFile *, 4> VisitOrder;
+      
+  /// \brief The list of module files that both we and the global module index
+  /// know about.
+  ///
+  /// Either the global index or the module manager may have modules that the
+  /// other does not know about, because the global index can be out-of-date
+  /// (in which case the module manager could have modules it does not) and
+  /// this particular translation unit might not have loaded all of the modules
+  /// known to the global index.
+  SmallVector<ModuleFile *, 4> ModulesInCommonWithGlobalIndex;
+
+  /// \brief The global module index, if one is attached.
+  ///
+  /// The global module index will actually be owned by the ASTReader; this is
+  /// just an non-owning pointer.
+  GlobalModuleIndex *GlobalIndex;
+
+  /// \brief State used by the "visit" operation to avoid malloc traffic in
+  /// calls to visit().
+  struct VisitState {
+    explicit VisitState(unsigned N)
+      : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
+    {
+      Stack.reserve(N);
+    }
+
+    ~VisitState() {
+      delete NextState;
+    }
+
+    /// \brief The stack used when marking the imports of a particular module
+    /// as not-to-be-visited.
+    SmallVector<ModuleFile *, 4> Stack;
+
+    /// \brief The visit number of each module file, which indicates when
+    /// this module file was last visited.
+    SmallVector<unsigned, 4> VisitNumber;
+
+    /// \brief The next visit number to use to mark visited module files.
+    unsigned NextVisitNumber;
+
+    /// \brief The next visit state.
+    VisitState *NextState;
+  };
+
+  /// \brief The first visit() state in the chain.
+  VisitState *FirstVisitState;
+
+  VisitState *allocateVisitState();
+  void returnVisitState(VisitState *State);
+
+public:
+  typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
+  typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
+  typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
+  typedef std::pair<uint32_t, StringRef> ModuleOffset;
+  
+  explicit ModuleManager(FileManager &FileMgr);
+  ~ModuleManager();
+  
+  /// \brief Forward iterator to traverse all loaded modules.  This is reverse
+  /// source-order.
+  ModuleIterator begin() { return Chain.begin(); }
+  /// \brief Forward iterator end-point to traverse all loaded modules
+  ModuleIterator end() { return Chain.end(); }
+  
+  /// \brief Const forward iterator to traverse all loaded modules.  This is 
+  /// in reverse source-order.
+  ModuleConstIterator begin() const { return Chain.begin(); }
+  /// \brief Const forward iterator end-point to traverse all loaded modules
+  ModuleConstIterator end() const { return Chain.end(); }
+  
+  /// \brief Reverse iterator to traverse all loaded modules.  This is in 
+  /// source order.
+  ModuleReverseIterator rbegin() { return Chain.rbegin(); }
+  /// \brief Reverse iterator end-point to traverse all loaded modules.
+  ModuleReverseIterator rend() { return Chain.rend(); }
+  
+  /// \brief Returns the primary module associated with the manager, that is,
+  /// the first module loaded
+  ModuleFile &getPrimaryModule() { return *Chain[0]; }
+  
+  /// \brief Returns the primary module associated with the manager, that is,
+  /// the first module loaded.
+  ModuleFile &getPrimaryModule() const { return *Chain[0]; }
+  
+  /// \brief Returns the module associated with the given index
+  ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
+  
+  /// \brief Returns the module associated with the given name
+  ModuleFile *lookup(StringRef Name);
+
+  /// \brief Returns the module associated with the given module file.
+  ModuleFile *lookup(const FileEntry *File);
+
+  /// \brief Returns the in-memory (virtual file) buffer with the given name
+  llvm::MemoryBuffer *lookupBuffer(StringRef Name);
+  
+  /// \brief Number of modules loaded
+  unsigned size() const { return Chain.size(); }
+
+  /// \brief The result of attempting to add a new module.
+  enum AddModuleResult {
+    /// \brief The module file had already been loaded.
+    AlreadyLoaded,
+    /// \brief The module file was just loaded in response to this call.
+    NewlyLoaded,
+    /// \brief The module file is missing.
+    Missing,
+    /// \brief The module file is out-of-date.
+    OutOfDate
+  };
+
+  /// \brief Attempts to create a new module and add it to the list of known
+  /// modules.
+  ///
+  /// \param FileName The file name of the module to be loaded.
+  ///
+  /// \param Type The kind of module being loaded.
+  ///
+  /// \param ImportLoc The location at which the module is imported.
+  ///
+  /// \param ImportedBy The module that is importing this module, or NULL if
+  /// this module is imported directly by the user.
+  ///
+  /// \param Generation The generation in which this module was loaded.
+  ///
+  /// \param ExpectedSize The expected size of the module file, used for
+  /// validation. This will be zero if unknown.
+  ///
+  /// \param ExpectedModTime The expected modification time of the module
+  /// file, used for validation. This will be zero if unknown.
+  ///
+  /// \param Module A pointer to the module file if the module was successfully
+  /// loaded.
+  ///
+  /// \param ErrorStr Will be set to a non-empty string if any errors occurred
+  /// while trying to load the module.
+  ///
+  /// \return A pointer to the module that corresponds to this file name,
+  /// and a value indicating whether the module was loaded.
+  AddModuleResult addModule(StringRef FileName, ModuleKind Type,
+                            SourceLocation ImportLoc,
+                            ModuleFile *ImportedBy, unsigned Generation,
+                            off_t ExpectedSize, time_t ExpectedModTime,
+                            ModuleFile *&Module,
+                            std::string &ErrorStr);
+
+  /// \brief Remove the given set of modules.
+  void removeModules(ModuleIterator first, ModuleIterator last,
+                     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
+                     ModuleMap *modMap);
+
+  /// \brief Add an in-memory buffer the list of known buffers
+  void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
+
+  /// \brief Set the global module index.
+  void setGlobalIndex(GlobalModuleIndex *Index);
+
+  /// \brief Notification from the AST reader that the given module file
+  /// has been "accepted", and will not (can not) be unloaded.
+  void moduleFileAccepted(ModuleFile *MF);
+
+  /// \brief Visit each of the modules.
+  ///
+  /// This routine visits each of the modules, starting with the
+  /// "root" modules that no other loaded modules depend on, and
+  /// proceeding to the leaf modules, visiting each module only once
+  /// during the traversal.
+  ///
+  /// This traversal is intended to support various "lookup"
+  /// operations that can find data in any of the loaded modules.
+  ///
+  /// \param Visitor A visitor function that will be invoked with each
+  /// module and the given user data pointer. The return value must be
+  /// convertible to bool; when false, the visitation continues to
+  /// modules that the current module depends on. When true, the
+  /// visitation skips any modules that the current module depends on.
+  ///
+  /// \param UserData User data associated with the visitor object, which
+  /// will be passed along to the visitor.
+  ///
+  /// \param ModuleFilesHit If non-NULL, contains the set of module files
+  /// that we know we need to visit because the global module index told us to.
+  /// Any module that is known to both the global module index and the module
+  /// manager that is *not* in this set can be skipped.
+  void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
+             llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = nullptr);
+  
+  /// \brief Visit each of the modules with a depth-first traversal.
+  ///
+  /// This routine visits each of the modules known to the module
+  /// manager using a depth-first search, starting with the first
+  /// loaded module. The traversal invokes the callback both before
+  /// traversing the children (preorder traversal) and after
+  /// traversing the children (postorder traversal).
+  ///
+  /// \param Visitor A visitor function that will be invoked with each
+  /// module and given a \c Preorder flag that indicates whether we're
+  /// visiting the module before or after visiting its children.  The
+  /// visitor may return true at any time to abort the depth-first
+  /// visitation.
+  ///
+  /// \param UserData User data ssociated with the visitor object,
+  /// which will be passed along to the user.
+  void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder, 
+                                       void *UserData), 
+                       void *UserData);
+
+  /// \brief Attempt to resolve the given module file name to a file entry.
+  ///
+  /// \param FileName The name of the module file.
+  ///
+  /// \param ExpectedSize The size that the module file is expected to have.
+  /// If the actual size differs, the resolver should return \c true.
+  ///
+  /// \param ExpectedModTime The modification time that the module file is
+  /// expected to have. If the actual modification time differs, the resolver
+  /// should return \c true.
+  ///
+  /// \param File Will be set to the file if there is one, or null
+  /// otherwise.
+  ///
+  /// \returns True if a file exists but does not meet the size/
+  /// modification time criteria, false if the file is either available and
+  /// suitable, or is missing.
+  bool lookupModuleFile(StringRef FileName,
+                        off_t ExpectedSize,
+                        time_t ExpectedModTime,
+                        const FileEntry *&File);
+
+  /// \brief View the graphviz representation of the module graph.
+  void viewGraph();
+};
+
+} } // end namespace clang::serialization
+
+#endif
diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h
new file mode 100644
index 0000000..c28cfea
--- /dev/null
+++ b/include/clang/Serialization/SerializationDiagnostic.h
@@ -0,0 +1,28 @@
+//===--- SerializationDiagnostic.h - Serialization Diagnostics -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SERIALIZATIONDIAGNOSTIC_H
+#define LLVM_CLANG_SERIALIZATIONDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+  namespace diag {
+    enum {
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
+             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+#define SERIALIZATIONSTART
+#include "clang/Basic/DiagnosticSerializationKinds.inc"
+#undef DIAG
+      NUM_BUILTIN_SERIALIZATION_DIAGNOSTICS
+    };
+  }  // end namespace diag
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
new file mode 100644
index 0000000..cf0a30a
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Checkers/ClangCheckers.h
@@ -0,0 +1,22 @@
+//===--- ClangCheckers.h - Provides builtin checkers ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
+#define LLVM_CLANG_STATICANALYZER_CHECKERS_CLANGCHECKERS_H
+
+namespace clang {
+namespace ento {
+class CheckerRegistry;
+
+void registerBuiltinCheckers(CheckerRegistry &registry);
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
new file mode 100644
index 0000000..eee38e9
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
@@ -0,0 +1,28 @@
+//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- 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 interface to call a set of intra-procedural (local)
+//  checkers that use flow/path-sensitive analyses to find bugs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_LOCALCHECKERS_H
+#define LLVM_CLANG_GR_LOCALCHECKERS_H
+
+namespace clang {
+namespace ento {
+
+class ExprEngine;
+
+void RegisterCallInliner(ExprEngine &Eng);
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
new file mode 100644
index 0000000..26335bf
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -0,0 +1,218 @@
+//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- 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 core data structures for retain count "summaries"
+//  for Objective-C and Core Foundation APIs.  These summaries are used
+//  by the static analyzer to summarize the retain/release effects of
+//  function and method calls.  This drives a path-sensitive typestate
+//  analysis in the static analyzer, but can also potentially be used by
+//  other clients.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_OBJCRETAINCOUNT_H
+#define LLVM_CLANG_OBJCRETAINCOUNT_H
+
+namespace clang { namespace ento { namespace objc_retain {
+
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+enum ArgEffect {
+  /// There is no effect.
+  DoNothing,
+
+  /// The argument is treated as if an -autorelease message had been sent to
+  /// the referenced object.
+  Autorelease,
+
+  /// The argument is treated as if an -dealloc message had been sent to
+  /// the referenced object.
+  Dealloc,
+
+  /// The argument has its reference count decreased by 1.  This is as
+  /// if CFRelease has been called on the argument.
+  DecRef,
+
+  /// The argument has its reference count decreased by 1.  This is as
+  /// if a -release message has been sent to the argument.  This differs
+  /// in behavior from DecRef when GC is enabled.
+  DecRefMsg,
+
+  /// The argument has its reference count decreased by 1 to model
+  /// a transferred bridge cast under ARC.
+  DecRefBridgedTransferred,
+
+  /// The argument has its reference count increased by 1.  This is as
+  /// if a -retain message has been sent to the argument.  This differs
+  /// in behavior from IncRef when GC is enabled.
+  IncRefMsg,
+
+  /// The argument has its reference count increased by 1.  This is as
+  /// if CFRetain has been called on the argument.
+  IncRef,
+
+  /// The argument acts as if has been passed to CFMakeCollectable, which
+  /// transfers the object to the Garbage Collector under GC.
+  MakeCollectable,
+
+  /// The argument is treated as potentially escaping, meaning that
+  /// even when its reference count hits 0 it should be treated as still
+  /// possibly being alive as someone else *may* be holding onto the object.
+  MayEscape,
+
+  /// All typestate tracking of the object ceases.  This is usually employed
+  /// when the effect of the call is completely unknown.
+  StopTracking,
+
+  /// All typestate tracking of the object ceases.  Unlike StopTracking,
+  /// this is also enforced when the method body is inlined.
+  ///
+  /// In some cases, we obtain a better summary for this checker
+  /// by looking at the call site than by inlining the function.
+  /// Signifies that we should stop tracking the symbol even if
+  /// the function is inlined.
+  StopTrackingHard,
+
+  /// Performs the combined functionality of DecRef and StopTrackingHard.
+  ///
+  /// The models the effect that the called function decrements the reference
+  /// count of the argument and all typestate tracking on that argument
+  /// should cease.
+  DecRefAndStopTrackingHard,
+
+  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
+  ///
+  /// The models the effect that the called function decrements the reference
+  /// count of the argument and all typestate tracking on that argument
+  /// should cease.
+  DecRefMsgAndStopTrackingHard
+};
+
+/// RetEffect summarizes a call's retain/release behavior with respect
+/// to its return value.
+class RetEffect {
+public:
+  enum Kind {
+    /// Indicates that no retain count information is tracked for
+    /// the return value.
+    NoRet,
+    /// Indicates that the returned value is an owned (+1) symbol.
+    OwnedSymbol,
+    /// Indicates that the returned value is an owned (+1) symbol and
+    /// that it should be treated as freshly allocated.
+    OwnedAllocatedSymbol,
+    /// Indicates that the returned value is an object with retain count
+    /// semantics but that it is not owned (+0).  This is the default
+    /// for getters, etc.
+    NotOwnedSymbol,
+    /// Indicates that the object is not owned and controlled by the
+    /// Garbage collector.
+    GCNotOwnedSymbol,
+    /// Indicates that the return value is an owned object when the
+    /// receiver is also a tracked object.
+    OwnedWhenTrackedReceiver,
+    // Treat this function as returning a non-tracked symbol even if
+    // the function has been inlined. This is used where the call
+    // site summary is more presise than the summary indirectly produced
+    // by inlining the function
+    NoRetHard
+  };
+  
+  /// Determines the object kind of a tracked object.
+  enum ObjKind {
+    /// Indicates that the tracked object is a CF object.  This is
+    /// important between GC and non-GC code.
+    CF,
+    /// Indicates that the tracked object is an Objective-C object.
+    ObjC,
+    /// Indicates that the tracked object could be a CF or Objective-C object.
+    AnyObj
+  };
+  
+private:
+  Kind K;
+  ObjKind O;
+  
+  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
+  
+public:
+  Kind getKind() const { return K; }
+  
+  ObjKind getObjKind() const { return O; }
+  
+  bool isOwned() const {
+    return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
+    K == OwnedWhenTrackedReceiver;
+  }
+  
+  bool notOwned() const {
+    return K == NotOwnedSymbol;
+  }
+  
+  bool operator==(const RetEffect &Other) const {
+    return K == Other.K && O == Other.O;
+  }
+  
+  static RetEffect MakeOwnedWhenTrackedReceiver() {
+    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+  }
+  
+  static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
+    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
+  }
+  static RetEffect MakeNotOwned(ObjKind o) {
+    return RetEffect(NotOwnedSymbol, o);
+  }
+  static RetEffect MakeGCNotOwned() {
+    return RetEffect(GCNotOwnedSymbol, ObjC);
+  }
+  static RetEffect MakeNoRet() {
+    return RetEffect(NoRet);
+  }
+  static RetEffect MakeNoRetHard() {
+    return RetEffect(NoRetHard);
+  }
+};
+
+/// Encapsulates the retain count semantics on the arguments, return value,
+/// and receiver (if any) of a function/method call.
+///
+/// Note that construction of these objects is not highly efficient.  That
+/// is okay for clients where creating these objects isn't really a bottleneck.
+/// The purpose of the API is to provide something simple.  The actual
+/// static analyzer checker that implements retain/release typestate
+/// tracking uses something more efficient.
+class CallEffects {
+  llvm::SmallVector<ArgEffect, 10> Args;
+  RetEffect Ret;
+  ArgEffect Receiver;
+
+  CallEffects(const RetEffect &R) : Ret(R) {}
+
+public:
+  /// Returns the argument effects for a call.
+  ArrayRef<ArgEffect> getArgs() const { return Args; }
+
+  /// Returns the effects on the receiver.
+  ArgEffect getReceiver() const { return Receiver; }
+
+  /// Returns the effect on the return value.
+  RetEffect getReturnValue() const { return Ret; }
+
+  /// Return the CallEfect for a given Objective-C method.
+  static CallEffects getEffect(const ObjCMethodDecl *MD);
+
+  /// Return the CallEfect for a given C/C++ function.
+  static CallEffects getEffect(const FunctionDecl *FD);
+};
+
+}}}
+
+#endif
+
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
new file mode 100644
index 0000000..3355f4b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -0,0 +1,57 @@
+//===-- Analyses.def - Metadata about Static Analyses -----------*- 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 set of static analyses used by AnalysisConsumer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ANALYSIS_STORE
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
+
+#ifndef ANALYSIS_CONSTRAINTS
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
+#endif
+
+ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
+
+#ifndef ANALYSIS_DIAGNOSTICS
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
+#endif
+
+ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
+
+#ifndef ANALYSIS_PURGE
+#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)
+#endif
+
+ANALYSIS_PURGE(PurgeStmt,  "statement", "Purge symbols, bindings, and constraints before every statement")
+ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
+ANALYSIS_PURGE(PurgeNone,  "none", "Do not purge symbols, bindings, or constraints")
+
+#ifndef ANALYSIS_INLINING_MODE
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
+#endif
+
+ANALYSIS_INLINING_MODE(All,  "all", "Analyze all functions as top level")
+ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined")
+
+#undef ANALYSIS_STORE
+#undef ANALYSIS_CONSTRAINTS
+#undef ANALYSIS_DIAGNOSTICS
+#undef ANALYSIS_PURGE
+#undef ANALYSIS_INLINING_MODE
+#undef ANALYSIS_IPA
+
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
new file mode 100644
index 0000000..978c3e2
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -0,0 +1,447 @@
+//===--- AnalyzerOptions.h - Analysis Engine Options ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines various options for the static analyzer that are set
+// by the frontend and are consulted throughout the analyzer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYZEROPTIONS_H
+#define LLVM_CLANG_ANALYZEROPTIONS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+class ASTConsumer;
+class DiagnosticsEngine;
+class Preprocessor;
+class LangOptions;
+
+/// Analysis - Set of available source code analyses.
+enum Analyses {
+#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+NumAnalyses
+};
+
+/// AnalysisStores - Set of available analysis store models.
+enum AnalysisStores {
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+NumStores
+};
+
+/// AnalysisConstraints - Set of available constraint models.
+enum AnalysisConstraints {
+#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+NumConstraints
+};
+
+/// AnalysisDiagClients - Set of available diagnostic clients for rendering
+///  analysis results.
+enum AnalysisDiagClients {
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+PD_NONE,
+NUM_ANALYSIS_DIAG_CLIENTS
+};
+
+/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
+enum AnalysisPurgeMode {
+#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+NumPurgeModes
+};
+
+/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
+enum AnalysisInliningMode {
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+NumInliningModes
+};
+
+/// \brief Describes the different kinds of C++ member functions which can be
+/// considered for inlining by the analyzer.
+///
+/// These options are cumulative; enabling one kind of member function will
+/// enable all kinds with lower enum values.
+enum CXXInlineableMemberKind {
+  // Uninitialized = 0,
+
+  /// A dummy mode in which no C++ inlining is enabled.
+  CIMK_None = 1,
+
+  /// Refers to regular member function and operator calls.
+  CIMK_MemberFunctions,
+
+  /// Refers to constructors (implicit or explicit).
+  ///
+  /// Note that a constructor will not be inlined if the corresponding
+  /// destructor is non-trivial.
+  CIMK_Constructors,
+
+  /// Refers to destructors (implicit or explicit).
+  CIMK_Destructors
+};
+
+/// \brief Describes the different modes of inter-procedural analysis.
+enum IPAKind {
+  IPAK_NotSet = 0,
+
+  /// Perform only intra-procedural analysis.
+  IPAK_None = 1,
+
+  /// Inline C functions and blocks when their definitions are available.
+  IPAK_BasicInlining = 2,
+
+  /// Inline callees(C, C++, ObjC) when their definitions are available.
+  IPAK_Inlining = 3,
+
+  /// Enable inlining of dynamically dispatched methods.
+  IPAK_DynamicDispatch = 4,
+
+  /// Enable inlining of dynamically dispatched methods, bifurcate paths when
+  /// exact type info is unavailable.
+  IPAK_DynamicDispatchBifurcate = 5
+};
+
+class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
+public:
+  typedef llvm::StringMap<std::string> ConfigTable;
+
+  /// \brief Pair of checker name and enable/disable.
+  std::vector<std::pair<std::string, bool> > CheckersControlList;
+  
+  /// \brief A key-value table of use-specified configuration values.
+  ConfigTable Config;
+  AnalysisStores AnalysisStoreOpt;
+  AnalysisConstraints AnalysisConstraintsOpt;
+  AnalysisDiagClients AnalysisDiagOpt;
+  AnalysisPurgeMode AnalysisPurgeOpt;
+  
+  std::string AnalyzeSpecificFunction;
+  
+  /// \brief The maximum number of times the analyzer visits a block.
+  unsigned maxBlockVisitOnPath;
+  
+  
+  unsigned ShowCheckerHelp : 1;
+  unsigned AnalyzeAll : 1;
+  unsigned AnalyzerDisplayProgress : 1;
+  unsigned AnalyzeNestedBlocks : 1;
+
+  /// \brief The flag regulates if we should eagerly assume evaluations of
+  /// conditionals, thus, bifurcating the path.
+  ///
+  /// This flag indicates how the engine should handle expressions such as: 'x =
+  /// (y != 0)'.  When this flag is true then the subexpression 'y != 0' will be
+  /// eagerly assumed to be true or false, thus evaluating it to the integers 0
+  /// or 1 respectively.  The upside is that this can increase analysis
+  /// precision until we have a better way to lazily evaluate such logic.  The
+  /// downside is that it eagerly bifurcates paths.
+  unsigned eagerlyAssumeBinOpBifurcation : 1;
+  
+  unsigned TrimGraph : 1;
+  unsigned visualizeExplodedGraphWithGraphViz : 1;
+  unsigned visualizeExplodedGraphWithUbiGraph : 1;
+  unsigned UnoptimizedCFG : 1;
+  unsigned PrintStats : 1;
+  
+  /// \brief Do not re-analyze paths leading to exhausted nodes with a different
+  /// strategy. We get better code coverage when retry is enabled.
+  unsigned NoRetryExhausted : 1;
+  
+  /// \brief The inlining stack depth limit.
+  unsigned InlineMaxStackDepth;
+  
+  /// \brief The mode of function selection used during inlining.
+  AnalysisInliningMode InliningMode;
+
+private:
+  /// \brief Describes the kinds for high-level analyzer mode.
+  enum UserModeKind {
+    UMK_NotSet = 0,
+    /// Perform shallow but fast analyzes.
+    UMK_Shallow = 1,
+    /// Perform deep analyzes.
+    UMK_Deep = 2
+  };
+
+  /// Controls the high-level analyzer mode, which influences the default 
+  /// settings for some of the lower-level config options (such as IPAMode).
+  /// \sa getUserMode
+  UserModeKind UserMode;
+
+  /// Controls the mode of inter-procedural analysis.
+  IPAKind IPAMode;
+
+  /// Controls which C++ member functions will be considered for inlining.
+  CXXInlineableMemberKind CXXMemberInliningMode;
+  
+  /// \sa includeTemporaryDtorsInCFG
+  Optional<bool> IncludeTemporaryDtorsInCFG;
+  
+  /// \sa mayInlineCXXStandardLibrary
+  Optional<bool> InlineCXXStandardLibrary;
+  
+  /// \sa mayInlineTemplateFunctions
+  Optional<bool> InlineTemplateFunctions;
+
+  /// \sa mayInlineCXXAllocator
+  Optional<bool> InlineCXXAllocator;
+
+  /// \sa mayInlineCXXContainerMethods
+  Optional<bool> InlineCXXContainerMethods;
+
+  /// \sa mayInlineCXXSharedPtrDtor
+  Optional<bool> InlineCXXSharedPtrDtor;
+
+  /// \sa mayInlineObjCMethod
+  Optional<bool> ObjCInliningMode;
+
+  // Cache of the "ipa-always-inline-size" setting.
+  // \sa getAlwaysInlineSize
+  Optional<unsigned> AlwaysInlineSize;
+
+  /// \sa shouldSuppressNullReturnPaths
+  Optional<bool> SuppressNullReturnPaths;
+
+  // \sa getMaxInlinableSize
+  Optional<unsigned> MaxInlinableSize;
+
+  /// \sa shouldAvoidSuppressingNullArgumentPaths
+  Optional<bool> AvoidSuppressingNullArgumentPaths;
+
+  /// \sa shouldSuppressInlinedDefensiveChecks
+  Optional<bool> SuppressInlinedDefensiveChecks;
+
+  /// \sa shouldSuppressFromCXXStandardLibrary
+  Optional<bool> SuppressFromCXXStandardLibrary;
+
+  /// \sa reportIssuesInMainSourceFile
+  Optional<bool> ReportIssuesInMainSourceFile;
+
+  /// \sa StableReportFilename
+  Optional<bool> StableReportFilename;
+
+  /// \sa getGraphTrimInterval
+  Optional<unsigned> GraphTrimInterval;
+
+  /// \sa getMaxTimesInlineLarge
+  Optional<unsigned> MaxTimesInlineLarge;
+
+  /// \sa getMaxNodesPerTopLevelFunction
+  Optional<unsigned> MaxNodesPerTopLevelFunction;
+
+public:
+  /// Interprets an option's string value as a boolean.
+  ///
+  /// Accepts the strings "true" and "false".
+  /// If an option value is not provided, returns the given \p DefaultVal.
+  bool getBooleanOption(StringRef Name, bool DefaultVal);
+
+  /// Variant that accepts a Optional value to cache the result.
+  bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal);
+
+  /// Interprets an option's string value as an integer value.
+  int getOptionAsInteger(StringRef Name, int DefaultVal);
+
+  /// \brief Retrieves and sets the UserMode. This is a high-level option,
+  /// which is used to set other low-level options. It is not accessible
+  /// outside of AnalyzerOptions.
+  UserModeKind getUserMode();
+
+  /// \brief Returns the inter-procedural analysis mode.
+  IPAKind getIPAMode();
+
+  /// Returns the option controlling which C++ member functions will be
+  /// considered for inlining.
+  ///
+  /// This is controlled by the 'c++-inlining' config option.
+  ///
+  /// \sa CXXMemberInliningMode
+  bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K);
+
+  /// Returns true if ObjectiveC inlining is enabled, false otherwise.
+  bool mayInlineObjCMethod();
+
+  /// Returns whether or not the destructors for C++ temporary objects should
+  /// be included in the CFG.
+  ///
+  /// This is controlled by the 'cfg-temporary-dtors' config option, which
+  /// accepts the values "true" and "false".
+  bool includeTemporaryDtorsInCFG();
+
+  /// Returns whether or not C++ standard library functions may be considered
+  /// for inlining.
+  ///
+  /// This is controlled by the 'c++-stdlib-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineCXXStandardLibrary();
+
+  /// Returns whether or not templated functions may be considered for inlining.
+  ///
+  /// This is controlled by the 'c++-template-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineTemplateFunctions();
+
+  /// Returns whether or not allocator call may be considered for inlining.
+  ///
+  /// This is controlled by the 'c++-allocator-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineCXXAllocator();
+
+  /// Returns whether or not methods of C++ container objects may be considered
+  /// for inlining.
+  ///
+  /// This is controlled by the 'c++-container-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineCXXContainerMethods();
+
+  /// Returns whether or not the destructor of C++ 'shared_ptr' may be
+  /// considered for inlining.
+  ///
+  /// This covers std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr,
+  /// and indeed any destructor named "~shared_ptr".
+  ///
+  /// This is controlled by the 'c++-shared_ptr-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineCXXSharedPtrDtor();
+
+  /// Returns whether or not paths that go through null returns should be
+  /// suppressed.
+  ///
+  /// This is a heuristic for avoiding bug reports with paths that go through
+  /// inlined functions that are more defensive than their callers.
+  ///
+  /// This is controlled by the 'suppress-null-return-paths' config option,
+  /// which accepts the values "true" and "false".
+  bool shouldSuppressNullReturnPaths();
+
+  /// Returns whether a bug report should \em not be suppressed if its path
+  /// includes a call with a null argument, even if that call has a null return.
+  ///
+  /// This option has no effect when #shouldSuppressNullReturnPaths() is false.
+  ///
+  /// This is a counter-heuristic to avoid false negatives.
+  ///
+  /// This is controlled by the 'avoid-suppressing-null-argument-paths' config
+  /// option, which accepts the values "true" and "false".
+  bool shouldAvoidSuppressingNullArgumentPaths();
+
+  /// Returns whether or not diagnostics containing inlined defensive NULL
+  /// checks should be suppressed.
+  ///
+  /// This is controlled by the 'suppress-inlined-defensive-checks' config
+  /// option, which accepts the values "true" and "false".
+  bool shouldSuppressInlinedDefensiveChecks();
+
+  /// Returns whether or not diagnostics reported within the C++ standard
+  /// library should be suppressed.
+  ///
+  /// This is controlled by the 'suppress-c++-stdlib' config option,
+  /// which accepts the values "true" and "false".
+  bool shouldSuppressFromCXXStandardLibrary();
+
+  /// Returns whether or not the diagnostic report should be always reported
+  /// in the main source file and not the headers.
+  ///
+  /// This is controlled by the 'report-in-main-source-file' config option,
+  /// which accepts the values "true" and "false".
+  bool shouldReportIssuesInMainSourceFile();
+
+  /// Returns whether or not the report filename should be random or not.
+  ///
+  /// This is controlled by the 'stable-report-filename' config option,
+  /// which accepts the values "true" and "false". Default = false
+  bool shouldWriteStableReportFilename();
+
+  /// Returns whether irrelevant parts of a bug report path should be pruned
+  /// out of the final output.
+  ///
+  /// This is controlled by the 'prune-paths' config option, which accepts the
+  /// values "true" and "false".
+  bool shouldPrunePaths();
+
+  /// Returns true if 'static' initializers should be in conditional logic
+  /// in the CFG.
+  bool shouldConditionalizeStaticInitializers();
+
+  // Returns the size of the functions (in basic blocks), which should be
+  // considered to be small enough to always inline.
+  //
+  // This is controlled by "ipa-always-inline-size" analyzer-config option.
+  unsigned getAlwaysInlineSize();
+
+  // Returns the bound on the number of basic blocks in an inlined function
+  // (50 by default).
+  //
+  // This is controlled by "-analyzer-config max-inlinable-size" option.
+  unsigned getMaxInlinableSize();
+
+  /// Returns true if the analyzer engine should synthesize fake bodies
+  /// for well-known functions.
+  bool shouldSynthesizeBodies();
+
+  /// Returns how often nodes in the ExplodedGraph should be recycled to save
+  /// memory.
+  ///
+  /// This is controlled by the 'graph-trim-interval' config option. To disable
+  /// node reclamation, set the option to "0".
+  unsigned getGraphTrimInterval();
+
+  /// Returns the maximum times a large function could be inlined.
+  ///
+  /// This is controlled by the 'max-times-inline-large' config option.
+  unsigned getMaxTimesInlineLarge();
+
+  /// Returns the maximum number of nodes the analyzer can generate while
+  /// exploring a top level function (for each exploded graph).
+  /// 150000 is default; 0 means no limit.
+  ///
+  /// This is controlled by the 'max-nodes' config option.
+  unsigned getMaxNodesPerTopLevelFunction();
+
+public:
+  AnalyzerOptions() :
+    AnalysisStoreOpt(RegionStoreModel),
+    AnalysisConstraintsOpt(RangeConstraintsModel),
+    AnalysisDiagOpt(PD_HTML),
+    AnalysisPurgeOpt(PurgeStmt),
+    ShowCheckerHelp(0),
+    AnalyzeAll(0),
+    AnalyzerDisplayProgress(0),
+    AnalyzeNestedBlocks(0),
+    eagerlyAssumeBinOpBifurcation(0),
+    TrimGraph(0),
+    visualizeExplodedGraphWithGraphViz(0),
+    visualizeExplodedGraphWithUbiGraph(0),
+    UnoptimizedCFG(0),
+    PrintStats(0),
+    NoRetryExhausted(0),
+    // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
+    InlineMaxStackDepth(5),
+    InliningMode(NoRedundancy),
+    UserMode(UMK_NotSet),
+    IPAMode(IPAK_NotSet),
+    CXXMemberInliningMode() {}
+
+};
+  
+typedef IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;
+  
+}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
new file mode 100644
index 0000000..5371231
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -0,0 +1,558 @@
+//===---  BugReporter.h - Generate PathDiagnostics --------------*- 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 BugReporter, a utility class for generating
+//  PathDiagnostics for analyses based on ProgramState.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_BUGREPORTER
+#define LLVM_CLANG_GR_BUGREPORTER
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+
+namespace clang {
+
+class ASTContext;
+class DiagnosticsEngine;
+class Stmt;
+class ParentMap;
+
+namespace ento {
+
+class PathDiagnostic;
+class ExplodedNode;
+class ExplodedGraph;
+class BugReport;
+class BugReporter;
+class BugReporterContext;
+class ExprEngine;
+class BugType;
+
+//===----------------------------------------------------------------------===//
+// Interface for individual bug reports.
+//===----------------------------------------------------------------------===//
+
+/// This class provides an interface through which checkers can create
+/// individual bug reports.
+class BugReport : public llvm::ilist_node<BugReport> {
+public:  
+  class NodeResolver {
+    virtual void anchor();
+  public:
+    virtual ~NodeResolver() {}
+    virtual const ExplodedNode*
+            getOriginalNode(const ExplodedNode *N) = 0;
+  };
+
+  typedef const SourceRange *ranges_iterator;
+  typedef SmallVector<BugReporterVisitor *, 8> VisitorList;
+  typedef VisitorList::iterator visitor_iterator;
+  typedef SmallVector<StringRef, 2> ExtraTextList;
+
+protected:
+  friend class BugReporter;
+  friend class BugReportEquivClass;
+
+  BugType& BT;
+  const Decl *DeclWithIssue;
+  std::string ShortDescription;
+  std::string Description;
+  PathDiagnosticLocation Location;
+  PathDiagnosticLocation UniqueingLocation;
+  const Decl *UniqueingDecl;
+  
+  const ExplodedNode *ErrorNode;
+  SmallVector<SourceRange, 4> Ranges;
+  ExtraTextList ExtraText;
+  
+  typedef llvm::DenseSet<SymbolRef> Symbols;
+  typedef llvm::DenseSet<const MemRegion *> Regions;
+
+  /// A (stack of) a set of symbols that are registered with this
+  /// report as being "interesting", and thus used to help decide which
+  /// diagnostics to include when constructing the final path diagnostic.
+  /// The stack is largely used by BugReporter when generating PathDiagnostics
+  /// for multiple PathDiagnosticConsumers.
+  SmallVector<Symbols *, 2> interestingSymbols;
+
+  /// A (stack of) set of regions that are registered with this report as being
+  /// "interesting", and thus used to help decide which diagnostics
+  /// to include when constructing the final path diagnostic.
+  /// The stack is largely used by BugReporter when generating PathDiagnostics
+  /// for multiple PathDiagnosticConsumers.
+  SmallVector<Regions *, 2> interestingRegions;
+
+  /// A set of location contexts that correspoind to call sites which should be
+  /// considered "interesting".
+  llvm::SmallSet<const LocationContext *, 2> InterestingLocationContexts;
+
+  /// A set of custom visitors which generate "event" diagnostics at
+  /// interesting points in the path.
+  VisitorList Callbacks;
+
+  /// Used for ensuring the visitors are only added once.
+  llvm::FoldingSet<BugReporterVisitor> CallbacksSet;
+
+  /// Used for clients to tell if the report's configuration has changed
+  /// since the last time they checked.
+  unsigned ConfigurationChangeToken;
+  
+  /// When set, this flag disables all callstack pruning from a diagnostic
+  /// path.  This is useful for some reports that want maximum fidelty
+  /// when reporting an issue.
+  bool DoNotPrunePath;
+
+  /// Used to track unique reasons why a bug report might be invalid.
+  ///
+  /// \sa markInvalid
+  /// \sa removeInvalidation
+  typedef std::pair<const void *, const void *> InvalidationRecord;
+
+  /// If non-empty, this bug report is likely a false positive and should not be
+  /// shown to the user.
+  ///
+  /// \sa markInvalid
+  /// \sa removeInvalidation
+  llvm::SmallSet<InvalidationRecord, 4> Invalidations;
+
+private:
+  // Used internally by BugReporter.
+  Symbols &getInterestingSymbols();
+  Regions &getInterestingRegions();
+
+  void lazyInitializeInterestingSets();
+  void pushInterestingSymbolsAndRegions();
+  void popInterestingSymbolsAndRegions();
+
+public:
+  BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
+    : BT(bt), DeclWithIssue(nullptr), Description(desc), ErrorNode(errornode),
+      ConfigurationChangeToken(0), DoNotPrunePath(false) {}
+
+  BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
+            const ExplodedNode *errornode)
+    : BT(bt), DeclWithIssue(nullptr), ShortDescription(shortDesc),
+      Description(desc), ErrorNode(errornode), ConfigurationChangeToken(0),
+      DoNotPrunePath(false) {}
+
+  BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
+    : BT(bt), DeclWithIssue(nullptr), Description(desc), Location(l),
+      ErrorNode(nullptr), ConfigurationChangeToken(0), DoNotPrunePath(false) {}
+
+  /// \brief Create a BugReport with a custom uniqueing location.
+  ///
+  /// The reports that have the same report location, description, bug type, and
+  /// ranges are uniqued - only one of the equivalent reports will be presented
+  /// to the user. This method allows to rest the location which should be used
+  /// for uniquing reports. For example, memory leaks checker, could set this to
+  /// the allocation site, rather then the location where the bug is reported.
+  BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
+            PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
+    : BT(bt), DeclWithIssue(nullptr), Description(desc),
+      UniqueingLocation(LocationToUnique),
+      UniqueingDecl(DeclToUnique),
+      ErrorNode(errornode), ConfigurationChangeToken(0),
+      DoNotPrunePath(false) {}
+
+  virtual ~BugReport();
+
+  const BugType& getBugType() const { return BT; }
+  BugType& getBugType() { return BT; }
+
+  const ExplodedNode *getErrorNode() const { return ErrorNode; }
+
+  const StringRef getDescription() const { return Description; }
+
+  const StringRef getShortDescription(bool UseFallback = true) const {
+    if (ShortDescription.empty() && UseFallback)
+      return Description;
+    return ShortDescription;
+  }
+
+  /// Indicates whether or not any path pruning should take place
+  /// when generating a PathDiagnostic from this BugReport.
+  bool shouldPrunePath() const { return !DoNotPrunePath; }
+
+  /// Disable all path pruning when generating a PathDiagnostic.
+  void disablePathPruning() { DoNotPrunePath = true; }
+  
+  void markInteresting(SymbolRef sym);
+  void markInteresting(const MemRegion *R);
+  void markInteresting(SVal V);
+  void markInteresting(const LocationContext *LC);
+  
+  bool isInteresting(SymbolRef sym);
+  bool isInteresting(const MemRegion *R);
+  bool isInteresting(SVal V);
+  bool isInteresting(const LocationContext *LC);
+
+  unsigned getConfigurationChangeToken() const {
+    return ConfigurationChangeToken;
+  }
+
+  /// Returns whether or not this report should be considered valid.
+  ///
+  /// Invalid reports are those that have been classified as likely false
+  /// positives after the fact.
+  bool isValid() const {
+    return Invalidations.empty();
+  }
+
+  /// Marks the current report as invalid, meaning that it is probably a false
+  /// positive and should not be reported to the user.
+  ///
+  /// The \p Tag and \p Data arguments are intended to be opaque identifiers for
+  /// this particular invalidation, where \p Tag represents the visitor
+  /// responsible for invalidation, and \p Data represents the reason this
+  /// visitor decided to invalidate the bug report.
+  ///
+  /// \sa removeInvalidation
+  void markInvalid(const void *Tag, const void *Data) {
+    Invalidations.insert(std::make_pair(Tag, Data));
+  }
+
+  /// Reverses the effects of a previous invalidation.
+  ///
+  /// \sa markInvalid
+  void removeInvalidation(const void *Tag, const void *Data) {
+    Invalidations.erase(std::make_pair(Tag, Data));
+  }
+  
+  /// Return the canonical declaration, be it a method or class, where
+  /// this issue semantically occurred.
+  const Decl *getDeclWithIssue() const;
+  
+  /// Specifically set the Decl where an issue occurred.  This isn't necessary
+  /// for BugReports that cover a path as it will be automatically inferred.
+  void setDeclWithIssue(const Decl *declWithIssue) {
+    DeclWithIssue = declWithIssue;
+  }
+  
+  /// \brief This allows for addition of meta data to the diagnostic.
+  ///
+  /// Currently, only the HTMLDiagnosticClient knows how to display it. 
+  void addExtraText(StringRef S) {
+    ExtraText.push_back(S);
+  }
+
+  virtual const ExtraTextList &getExtraText() {
+    return ExtraText;
+  }
+
+  /// \brief Return the "definitive" location of the reported bug.
+  ///
+  ///  While a bug can span an entire path, usually there is a specific
+  ///  location that can be used to identify where the key issue occurred.
+  ///  This location is used by clients rendering diagnostics.
+  virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const;
+
+  /// \brief Get the location on which the report should be uniqued.
+  PathDiagnosticLocation getUniqueingLocation() const {
+    return UniqueingLocation;
+  }
+  
+  /// \brief Get the declaration containing the uniqueing location.
+  const Decl *getUniqueingDecl() const {
+    return UniqueingDecl;
+  }
+
+  const Stmt *getStmt() const;
+
+  /// \brief Add a range to a bug report.
+  ///
+  /// Ranges are used to highlight regions of interest in the source code.
+  /// They should be at the same source code line as the BugReport location.
+  /// By default, the source range of the statement corresponding to the error
+  /// node will be used; add a single invalid range to specify absence of
+  /// ranges.
+  void addRange(SourceRange R) {
+    assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used "
+                           "to specify that the report does not have a range.");
+    Ranges.push_back(R);
+  }
+
+  /// \brief Get the SourceRanges associated with the report.
+  virtual std::pair<ranges_iterator, ranges_iterator> getRanges();
+
+  /// \brief Add custom or predefined bug report visitors to this report.
+  ///
+  /// The visitors should be used when the default trace is not sufficient.
+  /// For example, they allow constructing a more elaborate trace.
+  /// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
+  /// registerFindLastStore(), registerNilReceiverVisitor(), and
+  /// registerVarDeclsLastStore().
+  void addVisitor(BugReporterVisitor *visitor);
+
+	/// Iterators through the custom diagnostic visitors.
+  visitor_iterator visitor_begin() { return Callbacks.begin(); }
+  visitor_iterator visitor_end() { return Callbacks.end(); }
+
+  /// Profile to identify equivalent bug reports for error report coalescing.
+  /// Reports are uniqued to ensure that we do not emit multiple diagnostics
+  /// for each bug.
+  virtual void Profile(llvm::FoldingSetNodeID& hash) const;
+};
+
+} // end ento namespace
+} // end clang namespace
+
+namespace llvm {
+  template<> struct ilist_traits<clang::ento::BugReport>
+    : public ilist_default_traits<clang::ento::BugReport> {
+    clang::ento::BugReport *createSentinel() const {
+      return static_cast<clang::ento::BugReport *>(&Sentinel);
+    }
+    void destroySentinel(clang::ento::BugReport *) const {}
+
+    clang::ento::BugReport *provideInitialHead() const {
+      return createSentinel();
+    }
+    clang::ento::BugReport *ensureHead(clang::ento::BugReport *) const {
+      return createSentinel();
+    }
+  private:
+    mutable ilist_half_node<clang::ento::BugReport> Sentinel;
+  };
+}
+
+namespace clang {
+namespace ento {
+
+//===----------------------------------------------------------------------===//
+// BugTypes (collections of related reports).
+//===----------------------------------------------------------------------===//
+
+class BugReportEquivClass : public llvm::FoldingSetNode {
+  /// List of *owned* BugReport objects.
+  llvm::ilist<BugReport> Reports;
+
+  friend class BugReporter;
+  void AddReport(BugReport* R) { Reports.push_back(R); }
+public:
+  BugReportEquivClass(BugReport* R) { Reports.push_back(R); }
+  ~BugReportEquivClass();
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    assert(!Reports.empty());
+    Reports.front().Profile(ID);
+  }
+
+  typedef llvm::ilist<BugReport>::iterator iterator;
+  typedef llvm::ilist<BugReport>::const_iterator const_iterator;
+
+  iterator begin() { return Reports.begin(); }
+  iterator end() { return Reports.end(); }
+
+  const_iterator begin() const { return Reports.begin(); }
+  const_iterator end() const { return Reports.end(); }
+};
+
+//===----------------------------------------------------------------------===//
+// BugReporter and friends.
+//===----------------------------------------------------------------------===//
+
+class BugReporterData {
+public:
+  virtual ~BugReporterData();
+  virtual DiagnosticsEngine& getDiagnostic() = 0;
+  virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0;
+  virtual ASTContext &getASTContext() = 0;
+  virtual SourceManager& getSourceManager() = 0;
+  virtual AnalyzerOptions& getAnalyzerOptions() = 0;
+};
+
+/// BugReporter is a utility class for generating PathDiagnostics for analysis.
+/// It collects the BugReports and BugTypes and knows how to generate
+/// and flush the corresponding diagnostics.
+class BugReporter {
+public:
+  enum Kind { BaseBRKind, GRBugReporterKind };
+
+private:
+  typedef llvm::ImmutableSet<BugType*> BugTypesTy;
+  BugTypesTy::Factory F;
+  BugTypesTy BugTypes;
+
+  const Kind kind;
+  BugReporterData& D;
+
+  /// Generate and flush the diagnostics for the given bug report.
+  void FlushReport(BugReportEquivClass& EQ);
+
+  /// Generate and flush the diagnostics for the given bug report
+  /// and PathDiagnosticConsumer.
+  void FlushReport(BugReport *exampleReport,
+                   PathDiagnosticConsumer &PD,
+                   ArrayRef<BugReport*> BugReports);
+
+  /// The set of bug reports tracked by the BugReporter.
+  llvm::FoldingSet<BugReportEquivClass> EQClasses;
+  /// A vector of BugReports for tracking the allocated pointers and cleanup.
+  std::vector<BugReportEquivClass *> EQClassesVector;
+
+protected:
+  BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k),
+                                            D(d) {}
+
+public:
+  BugReporter(BugReporterData& d) : BugTypes(F.getEmptySet()), kind(BaseBRKind),
+                                    D(d) {}
+  virtual ~BugReporter();
+
+  /// \brief Generate and flush diagnostics for all bug reports.
+  void FlushReports();
+
+  Kind getKind() const { return kind; }
+
+  DiagnosticsEngine& getDiagnostic() {
+    return D.getDiagnostic();
+  }
+
+  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() {
+    return D.getPathDiagnosticConsumers();
+  }
+
+  /// \brief Iterator over the set of BugTypes tracked by the BugReporter.
+  typedef BugTypesTy::iterator iterator;
+  iterator begin() { return BugTypes.begin(); }
+  iterator end() { return BugTypes.end(); }
+
+  /// \brief Iterator over the set of BugReports tracked by the BugReporter.
+  typedef llvm::FoldingSet<BugReportEquivClass>::iterator EQClasses_iterator;
+  EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); }
+  EQClasses_iterator EQClasses_end() { return EQClasses.end(); }
+
+  ASTContext &getContext() { return D.getASTContext(); }
+
+  SourceManager& getSourceManager() { return D.getSourceManager(); }
+
+  AnalyzerOptions& getAnalyzerOptions() { return D.getAnalyzerOptions(); }
+
+  virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic,
+                                      PathDiagnosticConsumer &PC,
+                                      ArrayRef<BugReport *> &bugReports) {
+    return true;
+  }
+
+  bool RemoveUnneededCalls(PathPieces &pieces, BugReport *R);
+
+  void Register(BugType *BT);
+
+  /// \brief Add the given report to the set of reports tracked by BugReporter.
+  ///
+  /// The reports are usually generated by the checkers. Further, they are
+  /// folded based on the profile value, which is done to coalesce similar
+  /// reports.
+  void emitReport(BugReport *R);
+
+  void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
+                       StringRef BugName, StringRef BugCategory,
+                       StringRef BugStr, PathDiagnosticLocation Loc,
+                       ArrayRef<SourceRange> Ranges = None);
+
+  void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
+                       StringRef BugName, StringRef BugCategory,
+                       StringRef BugStr, PathDiagnosticLocation Loc,
+                       ArrayRef<SourceRange> Ranges = None);
+
+private:
+  llvm::StringMap<BugType *> StrBugTypes;
+
+  /// \brief Returns a BugType that is associated with the given name and
+  /// category.
+  BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+                             StringRef category);
+};
+
+// FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.
+class GRBugReporter : public BugReporter {
+  ExprEngine& Eng;
+public:
+  GRBugReporter(BugReporterData& d, ExprEngine& eng)
+    : BugReporter(d, GRBugReporterKind), Eng(eng) {}
+
+  virtual ~GRBugReporter();
+
+  /// getEngine - Return the analysis engine used to analyze a given
+  ///  function or method.
+  ExprEngine &getEngine() { return Eng; }
+
+  /// getGraph - Get the exploded graph created by the analysis engine
+  ///  for the analyzed method or function.
+  ExplodedGraph &getGraph();
+
+  /// getStateManager - Return the state manager used by the analysis
+  ///  engine.
+  ProgramStateManager &getStateManager();
+
+  /// Generates a path corresponding to one of the given bug reports.
+  ///
+  /// Which report is used for path generation is not specified. The
+  /// bug reporter will try to pick the shortest path, but this is not
+  /// guaranteed.
+  ///
+  /// \return True if the report was valid and a path was generated,
+  ///         false if the reports should be considered invalid.
+  bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC,
+                              ArrayRef<BugReport*> &bugReports) override;
+
+  /// classof - Used by isa<>, cast<>, and dyn_cast<>.
+  static bool classof(const BugReporter* R) {
+    return R->getKind() == GRBugReporterKind;
+  }
+};
+
+class BugReporterContext {
+  virtual void anchor();
+  GRBugReporter &BR;
+public:
+  BugReporterContext(GRBugReporter& br) : BR(br) {}
+
+  virtual ~BugReporterContext() {}
+
+  GRBugReporter& getBugReporter() { return BR; }
+
+  ExplodedGraph &getGraph() { return BR.getGraph(); }
+
+  ProgramStateManager& getStateManager() {
+    return BR.getStateManager();
+  }
+
+  SValBuilder& getSValBuilder() {
+    return getStateManager().getSValBuilder();
+  }
+
+  ASTContext &getASTContext() {
+    return BR.getContext();
+  }
+
+  SourceManager& getSourceManager() {
+    return BR.getSourceManager();
+  }
+
+  virtual BugReport::NodeResolver& getNodeResolver() = 0;
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
new file mode 100644
index 0000000..f352f80
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -0,0 +1,367 @@
+//===---  BugReporterVisitor.h - Generate PathDiagnostics -------*- 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 BugReporterVisitors, which are used to generate enhanced
+//  diagnostic traces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_BUGREPORTERVISITOR
+#define LLVM_CLANG_GR_BUGREPORTERVISITOR
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang {
+
+namespace ento {
+
+class BugReport;
+class BugReporterContext;
+class ExplodedNode;
+class MemRegion;
+class PathDiagnosticPiece;
+
+/// \brief BugReporterVisitors are used to add custom diagnostics along a path.
+///
+/// Custom visitors should subclass the BugReporterVisitorImpl class for a
+/// default implementation of the clone() method.
+/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+/// default implementation of clone() will NOT do the right thing, and you
+/// will have to provide your own implementation.)
+class BugReporterVisitor : public llvm::FoldingSetNode {
+public:
+  virtual ~BugReporterVisitor();
+
+  /// \brief Returns a copy of this BugReporter.
+  ///
+  /// Custom BugReporterVisitors should not override this method directly.
+  /// Instead, they should inherit from BugReporterVisitorImpl and provide
+  /// a protected or public copy constructor.
+  ///
+  /// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+  /// default implementation of clone() will NOT do the right thing, and you
+  /// will have to provide your own implementation.)
+  virtual BugReporterVisitor *clone() const = 0;
+
+  /// \brief Return a diagnostic piece which should be associated with the
+  /// given node.
+  ///
+  /// The last parameter can be used to register a new visitor with the given
+  /// BugReport while processing a node.
+  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+                                         const ExplodedNode *Pred,
+                                         BugReporterContext &BRC,
+                                         BugReport &BR) = 0;
+
+  /// \brief Provide custom definition for the final diagnostic piece on the
+  /// path - the piece, which is displayed before the path is expanded.
+  ///
+  /// If returns NULL the default implementation will be used.
+  /// Also note that at most one visitor of a BugReport should generate a
+  /// non-NULL end of path diagnostic piece.
+  virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+                                          const ExplodedNode *N,
+                                          BugReport &BR);
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
+
+  /// \brief Generates the default final diagnostic piece.
+  static PathDiagnosticPiece *getDefaultEndPath(BugReporterContext &BRC,
+                                                const ExplodedNode *N,
+                                                BugReport &BR);
+
+};
+
+/// This class provides a convenience implementation for clone() using the
+/// Curiously-Recurring Template Pattern. If you are implementing a custom
+/// BugReporterVisitor, subclass BugReporterVisitorImpl and provide a public
+/// or protected copy constructor.
+///
+/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+/// default implementation of clone() will NOT do the right thing, and you
+/// will have to provide your own implementation.)
+template <class DERIVED>
+class BugReporterVisitorImpl : public BugReporterVisitor {
+  BugReporterVisitor *clone() const override {
+    return new DERIVED(*static_cast<const DERIVED *>(this));
+  }
+};
+
+class FindLastStoreBRVisitor
+  : public BugReporterVisitorImpl<FindLastStoreBRVisitor>
+{
+  const MemRegion *R;
+  SVal V;
+  bool Satisfied;
+
+  /// If the visitor is tracking the value directly responsible for the
+  /// bug, we are going to employ false positive suppression.
+  bool EnableNullFPSuppression;
+
+public:
+  /// Creates a visitor for every VarDecl inside a Stmt and registers it with
+  /// the BugReport.
+  static void registerStatementVarDecls(BugReport &BR, const Stmt *S,
+                                        bool EnableNullFPSuppression);
+
+  FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
+                         bool InEnableNullFPSuppression)
+  : R(R),
+    V(V),
+    Satisfied(false),
+    EnableNullFPSuppression(InEnableNullFPSuppression) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+};
+
+class TrackConstraintBRVisitor
+  : public BugReporterVisitorImpl<TrackConstraintBRVisitor>
+{
+  DefinedSVal Constraint;
+  bool Assumption;
+  bool IsSatisfied;
+  bool IsZeroCheck;
+
+  /// We should start tracking from the last node along the path in which the
+  /// value is constrained.
+  bool IsTrackingTurnedOn;
+
+public:
+  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
+  : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
+    IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
+    IsTrackingTurnedOn(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+
+private:
+  /// Checks if the constraint is valid in the current state.
+  bool isUnderconstrained(const ExplodedNode *N) const;
+
+};
+
+/// \class NilReceiverBRVisitor
+/// \brief Prints path notes when a message is sent to a nil receiver.
+class NilReceiverBRVisitor
+  : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
+public:
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+
+  /// If the statement is a message send expression with nil receiver, returns
+  /// the receiver expression. Returns NULL otherwise.
+  static const Expr *getNilReceiver(const Stmt *S, const ExplodedNode *N);
+};
+
+/// Visitor that tries to report interesting diagnostics from conditions.
+class ConditionBRVisitor : public BugReporterVisitorImpl<ConditionBRVisitor> {
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *Prev,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+
+  PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
+                                     const ExplodedNode *Prev,
+                                     BugReporterContext &BRC,
+                                     BugReport &BR);
+  
+  PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
+                                       const ExplodedNode *N,
+                                       const CFGBlock *srcBlk,
+                                       const CFGBlock *dstBlk,
+                                       BugReport &R,
+                                       BugReporterContext &BRC);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     bool tookTrue,
+                                     BugReporterContext &BRC,
+                                     BugReport &R,
+                                     const ExplodedNode *N);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     const DeclRefExpr *DR,
+                                     const bool tookTrue,
+                                     BugReporterContext &BRC,
+                                     BugReport &R,
+                                     const ExplodedNode *N);
+
+  PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
+                                     const BinaryOperator *BExpr,
+                                     const bool tookTrue,
+                                     BugReporterContext &BRC,
+                                     BugReport &R,
+                                     const ExplodedNode *N);
+  
+  PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
+                                              const Expr *CondVarExpr,
+                                              const bool tookTrue,
+                                              BugReporterContext &BRC,
+                                              BugReport &R,
+                                              const ExplodedNode *N);
+
+  bool patternMatch(const Expr *Ex,
+                    raw_ostream &Out,
+                    BugReporterContext &BRC,
+                    BugReport &R,
+                    const ExplodedNode *N,
+                    Optional<bool> &prunable);
+};
+
+/// \brief Suppress reports that might lead to known false positives.
+///
+/// Currently this suppresses reports based on locations of bugs.
+class LikelyFalsePositiveSuppressionBRVisitor
+  : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
+public:
+  static void *getTag() {
+    static int Tag = 0;
+    return static_cast<void *>(&Tag);
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    ID.AddPointer(getTag());
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *Prev,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override {
+    return nullptr;
+  }
+
+  PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+                                  const ExplodedNode *N,
+                                  BugReport &BR) override;
+};
+
+/// \brief When a region containing undefined value or '0' value is passed 
+/// as an argument in a call, marks the call as interesting.
+///
+/// As a result, BugReporter will not prune the path through the function even
+/// if the region's contents are not modified/accessed by the call.
+class UndefOrNullArgVisitor
+  : public BugReporterVisitorImpl<UndefOrNullArgVisitor> {
+
+  /// The interesting memory region this visitor is tracking.
+  const MemRegion *R;
+
+public:
+  UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int Tag = 0;
+    ID.AddPointer(&Tag);
+    ID.AddPointer(R);
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *PrevN,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+};
+
+class SuppressInlineDefensiveChecksVisitor
+: public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor>
+{
+  /// The symbolic value for which we are tracking constraints.
+  /// This value is constrained to null in the end of path.
+  DefinedSVal V;
+
+  /// Track if we found the node where the constraint was first added.
+  bool IsSatisfied;
+
+  /// Since the visitors can be registered on nodes previous to the last
+  /// node in the BugReport, but the path traversal always starts with the last
+  /// node, the visitor invariant (that we start with a node in which V is null)
+  /// might not hold when node visitation starts. We are going to start tracking
+  /// from the last node in which the value is null.
+  bool IsTrackingTurnedOn;
+
+public:
+  SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+                                 const ExplodedNode *Pred,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+};
+
+namespace bugreporter {
+
+/// Attempts to add visitors to trace a null or undefined value back to its
+/// point of origin, whether it is a symbol constrained to null or an explicit
+/// assignment.
+///
+/// \param N A node "downstream" from the evaluation of the statement.
+/// \param S The statement whose value is null or undefined.
+/// \param R The bug report to which visitors should be attached.
+/// \param IsArg Whether the statement is an argument to an inlined function.
+///              If this is the case, \p N \em must be the CallEnter node for
+///              the function.
+/// \param EnableNullFPSuppression Whether we should employ false positive
+///         suppression (inlined defensive checks, returned null).
+///
+/// \return Whether or not the function was able to add visitors for this
+///         statement. Note that returning \c true does not actually imply
+///         that any visitors were added.
+bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
+                           bool IsArg = false,
+                           bool EnableNullFPSuppression = true);
+
+const Expr *getDerefExpr(const Stmt *S);
+const Stmt *GetDenomExpr(const ExplodedNode *N);
+const Stmt *GetRetValExpr(const ExplodedNode *N);
+bool isDeclRefExprToReference(const Expr *E);
+
+
+} // end namespace clang
+} // end namespace ento
+} // end namespace bugreporter
+
+
+#endif //LLVM_CLANG_GR__BUGREPORTERVISITOR
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
new file mode 100644
index 0000000..24c7785
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -0,0 +1,81 @@
+//===---  BugType.h - Bug Information Desciption ----------------*- 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 BugType, a class representing a bug type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
+#define LLVM_CLANG_ANALYSIS_BUGTYPE
+
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <string>
+
+namespace clang {
+
+namespace ento {
+
+class BugReporter;
+class ExplodedNode;
+class ExprEngine;
+
+class BugType {
+private:
+  const CheckName Check;
+  const std::string Name;
+  const std::string Category;
+  bool SuppressonSink;
+
+  virtual void anchor();
+public:
+  BugType(class CheckName check, StringRef name, StringRef cat)
+      : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
+  BugType(const CheckerBase *checker, StringRef name, StringRef cat)
+      : Check(checker->getCheckName()), Name(name), Category(cat),
+        SuppressonSink(false) {}
+  virtual ~BugType() {}
+
+  // FIXME: Should these be made strings as well?
+  StringRef getName() const { return Name; }
+  StringRef getCategory() const { return Category; }
+  StringRef getCheckName() const { return Check.getName(); }
+
+  /// isSuppressOnSink - Returns true if bug reports associated with this bug
+  ///  type should be suppressed if the end node of the report is post-dominated
+  ///  by a sink node.
+  bool isSuppressOnSink() const { return SuppressonSink; }
+  void setSuppressOnSink(bool x) { SuppressonSink = x; }
+
+  virtual void FlushReports(BugReporter& BR);
+};
+
+class BuiltinBug : public BugType {
+  const std::string desc;
+  void anchor() override;
+public:
+  BuiltinBug(class CheckName check, const char *name, const char *description)
+      : BugType(check, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name,
+             const char *description)
+      : BugType(checker, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name)
+      : BugType(checker, name, categories::LogicError), desc(name) {}
+
+  StringRef getDescription() const { return desc; }
+};
+
+} // end GR namespace
+
+} // end clang namespace
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
new file mode 100644
index 0000000..3f0fe96
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -0,0 +1,25 @@
+//=--- CommonBugCategories.h - Provides common issue categories -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
+#define LLVM_CLANG_STATIC_ANALYZER_BUG_CATEGORIES_H
+
+// Common strings used for the "category" of many static analyzer issues.
+namespace clang {
+  namespace ento {
+    namespace categories {
+      extern const char * const CoreFoundationObjectiveC;
+      extern const char * const LogicError;
+      extern const char * const MemoryCoreFoundationObjectiveC;
+      extern const char * const UnixAPI;
+    }
+  }
+}
+#endif
+
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
new file mode 100644
index 0000000..5a578d0
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -0,0 +1,845 @@
+//===--- PathDiagnostic.h - Path-Specific Diagnostic Handling ---*- 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 PathDiagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
+#define LLVM_CLANG_PATH_DIAGNOSTIC_H
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include <deque>
+#include <iterator>
+#include <list>
+#include <string>
+#include <vector>
+
+namespace clang {
+class ConditionalOperator;
+class AnalysisDeclContext;
+class BinaryOperator;
+class CompoundStmt;
+class Decl;
+class LocationContext;
+class MemberExpr;
+class ParentMap;
+class ProgramPoint;
+class SourceManager;
+class Stmt;
+class CallExpr;
+
+namespace ento {
+
+class ExplodedNode;
+class SymExpr;
+typedef const SymExpr* SymbolRef;
+
+//===----------------------------------------------------------------------===//
+// High-level interface for handlers of path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnostic;
+
+class PathDiagnosticConsumer {
+public:
+  class PDFileEntry : public llvm::FoldingSetNode {
+  public:
+    PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {}
+
+    typedef std::vector<std::pair<StringRef, StringRef> > ConsumerFiles;
+    
+    /// \brief A vector of <consumer,file> pairs.
+    ConsumerFiles files;
+    
+    /// \brief A precomputed hash tag used for uniquing PDFileEntry objects.
+    const llvm::FoldingSetNodeID NodeID;
+
+    /// \brief Used for profiling in the FoldingSet.
+    void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; }
+  };
+  
+  struct FilesMade : public llvm::FoldingSet<PDFileEntry> {
+    llvm::BumpPtrAllocator Alloc;
+
+    ~FilesMade();
+
+    void addDiagnostic(const PathDiagnostic &PD,
+                       StringRef ConsumerName,
+                       StringRef fileName);
+    
+    PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD);
+  };
+
+private:
+  virtual void anchor();
+public:
+  PathDiagnosticConsumer() : flushed(false) {}
+  virtual ~PathDiagnosticConsumer();
+
+  void FlushDiagnostics(FilesMade *FilesMade);
+
+  virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
+                                    FilesMade *filesMade) = 0;
+
+  virtual StringRef getName() const = 0;
+  
+  void HandlePathDiagnostic(PathDiagnostic *D);
+
+  enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive };
+  virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
+  virtual bool supportsLogicalOpControlFlow() const { return false; }
+  
+  /// Return true if the PathDiagnosticConsumer supports individual
+  /// PathDiagnostics that span multiple files.
+  virtual bool supportsCrossFileDiagnostics() const { return false; }
+
+protected:
+  bool flushed;
+  llvm::FoldingSet<PathDiagnostic> Diags;
+};
+
+//===----------------------------------------------------------------------===//
+// Path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnosticRange : public SourceRange {
+public:
+  bool isPoint;
+
+  PathDiagnosticRange(const SourceRange &R, bool isP = false)
+    : SourceRange(R), isPoint(isP) {}
+
+  PathDiagnosticRange() : isPoint(false) {}
+};
+
+typedef llvm::PointerUnion<const LocationContext*, AnalysisDeclContext*>
+                                                   LocationOrAnalysisDeclContext;
+
+class PathDiagnosticLocation {
+private:
+  enum Kind { RangeK, SingleLocK, StmtK, DeclK } K;
+  const Stmt *S;
+  const Decl *D;
+  const SourceManager *SM;
+  FullSourceLoc Loc;
+  PathDiagnosticRange Range;
+
+  PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
+                         Kind kind)
+    : K(kind), S(nullptr), D(nullptr), SM(&sm),
+      Loc(genLocation(L)), Range(genRange()) {
+  }
+
+  FullSourceLoc genLocation(
+      SourceLocation L = SourceLocation(),
+      LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
+
+  PathDiagnosticRange genRange(
+      LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
+
+public:
+  /// Create an invalid location.
+  PathDiagnosticLocation()
+    : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
+
+  /// Create a location corresponding to the given statement.
+  PathDiagnosticLocation(const Stmt *s,
+                         const SourceManager &sm,
+                         LocationOrAnalysisDeclContext lac)
+    : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
+      S(K == StmtK ? s : nullptr),
+      D(nullptr), SM(&sm),
+      Loc(genLocation(SourceLocation(), lac)),
+      Range(genRange(lac)) {
+    assert(K == SingleLocK || S);
+    assert(K == SingleLocK || Loc.isValid());
+    assert(K == SingleLocK || Range.isValid());
+  }
+
+  /// Create a location corresponding to the given declaration.
+  PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
+    : K(DeclK), S(nullptr), D(d), SM(&sm),
+      Loc(genLocation()), Range(genRange()) {
+    assert(D);
+    assert(Loc.isValid());
+    assert(Range.isValid());
+  }
+
+  /// Create a location at an explicit offset in the source.
+  ///
+  /// This should only be used if there are no more appropriate constructors.
+  PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
+    : K(SingleLocK), S(nullptr), D(nullptr), SM(&sm), Loc(loc, sm),
+      Range(genRange()) {
+    assert(Loc.isValid());
+    assert(Range.isValid());
+  }
+
+  /// Create a location corresponding to the given declaration.
+  static PathDiagnosticLocation create(const Decl *D,
+                                       const SourceManager &SM) {
+    return PathDiagnosticLocation(D, SM);
+  }
+
+  /// Create a location for the beginning of the declaration.
+  static PathDiagnosticLocation createBegin(const Decl *D,
+                                            const SourceManager &SM);
+
+  /// Create a location for the beginning of the statement.
+  static PathDiagnosticLocation createBegin(const Stmt *S,
+                                            const SourceManager &SM,
+                                            const LocationOrAnalysisDeclContext LAC);
+
+  /// Create a location for the end of the statement.
+  ///
+  /// If the statement is a CompoundStatement, the location will point to the
+  /// closing brace instead of following it.
+  static PathDiagnosticLocation createEnd(const Stmt *S,
+                                          const SourceManager &SM,
+                                       const LocationOrAnalysisDeclContext LAC);
+
+  /// Create the location for the operator of the binary expression.
+  /// Assumes the statement has a valid location.
+  static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO,
+                                                  const SourceManager &SM);
+  static PathDiagnosticLocation createConditionalColonLoc(
+                                                  const ConditionalOperator *CO,
+                                                  const SourceManager &SM);
+
+  /// For member expressions, return the location of the '.' or '->'.
+  /// Assumes the statement has a valid location.
+  static PathDiagnosticLocation createMemberLoc(const MemberExpr *ME,
+                                                const SourceManager &SM);
+
+  /// Create a location for the beginning of the compound statement.
+  /// Assumes the statement has a valid location.
+  static PathDiagnosticLocation createBeginBrace(const CompoundStmt *CS,
+                                                 const SourceManager &SM);
+
+  /// Create a location for the end of the compound statement.
+  /// Assumes the statement has a valid location.
+  static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS,
+                                               const SourceManager &SM);
+
+  /// Create a location for the beginning of the enclosing declaration body.
+  /// Defaults to the beginning of the first statement in the declaration body.
+  static PathDiagnosticLocation createDeclBegin(const LocationContext *LC,
+                                                const SourceManager &SM);
+
+  /// Constructs a location for the end of the enclosing declaration body.
+  /// Defaults to the end of brace.
+  static PathDiagnosticLocation createDeclEnd(const LocationContext *LC,
+                                                   const SourceManager &SM);
+
+  /// Create a location corresponding to the given valid ExplodedNode.
+  static PathDiagnosticLocation create(const ProgramPoint& P,
+                                       const SourceManager &SMng);
+
+  /// Create a location corresponding to the next valid ExplodedNode as end
+  /// of path location.
+  static PathDiagnosticLocation createEndOfPath(const ExplodedNode* N,
+                                                const SourceManager &SM);
+
+  /// Convert the given location into a single kind location.
+  static PathDiagnosticLocation createSingleLocation(
+                                             const PathDiagnosticLocation &PDL);
+
+  bool operator==(const PathDiagnosticLocation &X) const {
+    return K == X.K && Loc == X.Loc && Range == X.Range;
+  }
+
+  bool operator!=(const PathDiagnosticLocation &X) const {
+    return !(*this == X);
+  }
+
+  bool isValid() const {
+    return SM != nullptr;
+  }
+
+  FullSourceLoc asLocation() const {
+    return Loc;
+  }
+
+  PathDiagnosticRange asRange() const {
+    return Range;
+  }
+
+  const Stmt *asStmt() const { assert(isValid()); return S; }
+  const Decl *asDecl() const { assert(isValid()); return D; }
+
+  bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
+
+  void invalidate() {
+    *this = PathDiagnosticLocation();
+  }
+
+  void flatten();
+
+  const SourceManager& getManager() const { assert(isValid()); return *SM; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  void dump() const;
+
+  /// \brief Given an exploded node, retrieve the statement that should be used 
+  /// for the diagnostic location.
+  static const Stmt *getStmt(const ExplodedNode *N);
+
+  /// \brief Retrieve the statement corresponding to the successor node.
+  static const Stmt *getNextStmt(const ExplodedNode *N);
+};
+
+class PathDiagnosticLocationPair {
+private:
+  PathDiagnosticLocation Start, End;
+public:
+  PathDiagnosticLocationPair(const PathDiagnosticLocation &start,
+                             const PathDiagnosticLocation &end)
+    : Start(start), End(end) {}
+
+  const PathDiagnosticLocation &getStart() const { return Start; }
+  const PathDiagnosticLocation &getEnd() const { return End; }
+
+  void setStart(const PathDiagnosticLocation &L) { Start = L; }
+  void setEnd(const PathDiagnosticLocation &L) { End = L; }
+
+  void flatten() {
+    Start.flatten();
+    End.flatten();
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Start.Profile(ID);
+    End.Profile(ID);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Path "pieces" for path-sensitive diagnostics.
+//===----------------------------------------------------------------------===//
+
+class PathDiagnosticPiece : public RefCountedBaseVPTR {
+public:
+  enum Kind { ControlFlow, Event, Macro, Call };
+  enum DisplayHint { Above, Below };
+
+private:
+  const std::string str;
+  const Kind kind;
+  const DisplayHint Hint;
+
+  /// \brief In the containing bug report, this piece is the last piece from
+  /// the main source file.
+  bool LastInMainSourceFile;
+  
+  /// A constant string that can be used to tag the PathDiagnosticPiece,
+  /// typically with the identification of the creator.  The actual pointer
+  /// value is meant to be an identifier; the string itself is useful for
+  /// debugging.
+  StringRef Tag;
+
+  std::vector<SourceRange> ranges;
+
+  PathDiagnosticPiece() LLVM_DELETED_FUNCTION;
+  PathDiagnosticPiece(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION;
+  void operator=(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION;
+
+protected:
+  PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint = Below);
+
+  PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
+
+public:
+  virtual ~PathDiagnosticPiece();
+
+  StringRef getString() const { return str; }
+
+  /// Tag this PathDiagnosticPiece with the given C-string.
+  void setTag(const char *tag) { Tag = tag; }
+  
+  /// Return the opaque tag (if any) on the PathDiagnosticPiece.
+  const void *getTag() const { return Tag.data(); }
+  
+  /// Return the string representation of the tag.  This is useful
+  /// for debugging.
+  StringRef getTagStr() const { return Tag; }
+  
+  /// getDisplayHint - Return a hint indicating where the diagnostic should
+  ///  be displayed by the PathDiagnosticConsumer.
+  DisplayHint getDisplayHint() const { return Hint; }
+
+  virtual PathDiagnosticLocation getLocation() const = 0;
+  virtual void flattenLocations() = 0;
+
+  Kind getKind() const { return kind; }
+
+  void addRange(SourceRange R) {
+    if (!R.isValid())
+      return;
+    ranges.push_back(R);
+  }
+
+  void addRange(SourceLocation B, SourceLocation E) {
+    if (!B.isValid() || !E.isValid())
+      return;
+    ranges.push_back(SourceRange(B,E));
+  }
+
+  /// Return the SourceRanges associated with this PathDiagnosticPiece.
+  ArrayRef<SourceRange> getRanges() const { return ranges; }
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  void setAsLastInMainSourceFile() {
+    LastInMainSourceFile = true;
+  }
+
+  bool isLastInMainSourceFile() const {
+    return LastInMainSourceFile;
+  }
+
+  virtual void dump() const = 0;
+};
+  
+  
+class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+  void flattenTo(PathPieces &Primary, PathPieces &Current,
+                 bool ShouldFlattenMacros) const;
+public:
+  ~PathPieces();
+
+  PathPieces flatten(bool ShouldFlattenMacros) const {
+    PathPieces Result;
+    flattenTo(Result, Result, ShouldFlattenMacros);
+    return Result;
+  }
+
+  void dump() const;
+};
+
+class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
+private:
+  PathDiagnosticLocation Pos;
+public:
+  PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
+                          StringRef s,
+                          PathDiagnosticPiece::Kind k,
+                          bool addPosRange = true)
+  : PathDiagnosticPiece(s, k), Pos(pos) {
+    assert(Pos.isValid() && Pos.asLocation().isValid() &&
+           "PathDiagnosticSpotPiece's must have a valid location.");
+    if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
+  }
+
+  PathDiagnosticLocation getLocation() const override { return Pos; }
+  void flattenLocations() override { Pos.flatten(); }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static bool classof(const PathDiagnosticPiece *P) {
+    return P->getKind() == Event || P->getKind() == Macro;
+  }
+};
+
+/// \brief Interface for classes constructing Stack hints.
+///
+/// If a PathDiagnosticEvent occurs in a different frame than the final 
+/// diagnostic the hints can be used to summarize the effect of the call.
+class StackHintGenerator {
+public:
+  virtual ~StackHintGenerator() = 0;
+
+  /// \brief Construct the Diagnostic message for the given ExplodedNode.
+  virtual std::string getMessage(const ExplodedNode *N) = 0;
+};
+
+/// \brief Constructs a Stack hint for the given symbol.
+///
+/// The class knows how to construct the stack hint message based on
+/// traversing the CallExpr associated with the call and checking if the given
+/// symbol is returned or is one of the arguments.
+/// The hint can be customized by redefining 'getMessageForX()' methods.
+class StackHintGeneratorForSymbol : public StackHintGenerator {
+private:
+  SymbolRef Sym;
+  std::string Msg;
+
+public:
+  StackHintGeneratorForSymbol(SymbolRef S, StringRef M) : Sym(S), Msg(M) {}
+  virtual ~StackHintGeneratorForSymbol() {}
+
+  /// \brief Search the call expression for the symbol Sym and dispatch the
+  /// 'getMessageForX()' methods to construct a specific message.
+  std::string getMessage(const ExplodedNode *N) override;
+
+  /// Produces the message of the following form:
+  ///   'Msg via Nth parameter'
+  virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex);
+  virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
+    return Msg;
+  }
+  virtual std::string getMessageForSymbolNotFound() {
+    return Msg;
+  }
+};
+
+class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
+  Optional<bool> IsPrunable;
+
+  /// If the event occurs in a different frame than the final diagnostic,
+  /// supply a message that will be used to construct an extra hint on the
+  /// returns from all the calls on the stack from this event to the final
+  /// diagnostic.
+  std::unique_ptr<StackHintGenerator> CallStackHint;
+
+public:
+  PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
+                           StringRef s, bool addPosRange = true,
+                           StackHintGenerator *stackHint = nullptr)
+    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
+      CallStackHint(stackHint) {}
+
+  ~PathDiagnosticEventPiece();
+
+  /// Mark the diagnostic piece as being potentially prunable.  This
+  /// flag may have been previously set, at which point it will not
+  /// be reset unless one specifies to do so.
+  void setPrunable(bool isPrunable, bool override = false) {
+    if (IsPrunable.hasValue() && !override)
+     return;
+    IsPrunable = isPrunable;
+  }
+
+  /// Return true if the diagnostic piece is prunable.
+  bool isPrunable() const {
+    return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
+  }
+
+  bool hasCallStackHint() { return (bool)CallStackHint; }
+
+  /// Produce the hint for the given node. The node contains 
+  /// information about the call for which the diagnostic can be generated.
+  std::string getCallStackMessage(const ExplodedNode *N) {
+    if (CallStackHint)
+      return CallStackHint->getMessage(N);
+    return "";  
+  }
+
+  void dump() const override;
+
+  static inline bool classof(const PathDiagnosticPiece *P) {
+    return P->getKind() == Event;
+  }
+};
+
+class PathDiagnosticCallPiece : public PathDiagnosticPiece {
+  PathDiagnosticCallPiece(const Decl *callerD,
+                          const PathDiagnosticLocation &callReturnPos)
+    : PathDiagnosticPiece(Call), Caller(callerD), Callee(nullptr),
+      NoExit(false), callReturn(callReturnPos) {}
+
+  PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
+    : PathDiagnosticPiece(Call), Caller(caller), Callee(nullptr),
+      NoExit(true), path(oldPath) {}
+  
+  const Decl *Caller;
+  const Decl *Callee;
+
+  // Flag signifying that this diagnostic has only call enter and no matching
+  // call exit.
+  bool NoExit;
+
+  // The custom string, which should appear after the call Return Diagnostic.
+  // TODO: Should we allow multiple diagnostics?
+  std::string CallStackMessage;
+
+public:
+  PathDiagnosticLocation callEnter;
+  PathDiagnosticLocation callEnterWithin;
+  PathDiagnosticLocation callReturn;  
+  PathPieces path;
+  
+  virtual ~PathDiagnosticCallPiece();
+  
+  const Decl *getCaller() const { return Caller; }
+  
+  const Decl *getCallee() const { return Callee; }
+  void setCallee(const CallEnter &CE, const SourceManager &SM);
+  
+  bool hasCallStackMessage() { return !CallStackMessage.empty(); }
+  void setCallStackMessage(StringRef st) {
+    CallStackMessage = st;
+  }
+
+  PathDiagnosticLocation getLocation() const override {
+    return callEnter;
+  }
+  
+  IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallEnterEvent() const;
+  IntrusiveRefCntPtr<PathDiagnosticEventPiece>
+    getCallEnterWithinCallerEvent() const;
+  IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
+
+  void flattenLocations() override {
+    callEnter.flatten();
+    callReturn.flatten();
+    for (PathPieces::iterator I = path.begin(), 
+         E = path.end(); I != E; ++I) (*I)->flattenLocations();
+  }
+  
+  static PathDiagnosticCallPiece *construct(const ExplodedNode *N,
+                                            const CallExitEnd &CE,
+                                            const SourceManager &SM);
+  
+  static PathDiagnosticCallPiece *construct(PathPieces &pieces,
+                                            const Decl *caller);
+
+  void dump() const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static inline bool classof(const PathDiagnosticPiece *P) {
+    return P->getKind() == Call;
+  }
+};
+
+class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
+  std::vector<PathDiagnosticLocationPair> LPairs;
+public:
+  PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
+                                 const PathDiagnosticLocation &endPos,
+                                 StringRef s)
+    : PathDiagnosticPiece(s, ControlFlow) {
+      LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+    }
+
+  PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
+                                 const PathDiagnosticLocation &endPos)
+    : PathDiagnosticPiece(ControlFlow) {
+      LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
+    }
+
+  ~PathDiagnosticControlFlowPiece();
+
+  PathDiagnosticLocation getStartLocation() const {
+    assert(!LPairs.empty() &&
+           "PathDiagnosticControlFlowPiece needs at least one location.");
+    return LPairs[0].getStart();
+  }
+
+  PathDiagnosticLocation getEndLocation() const {
+    assert(!LPairs.empty() &&
+           "PathDiagnosticControlFlowPiece needs at least one location.");
+    return LPairs[0].getEnd();
+  }
+
+  void setStartLocation(const PathDiagnosticLocation &L) {
+    LPairs[0].setStart(L);
+  }
+
+  void setEndLocation(const PathDiagnosticLocation &L) {
+    LPairs[0].setEnd(L);
+  }
+
+  void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
+
+  PathDiagnosticLocation getLocation() const override {
+    return getStartLocation();
+  }
+
+  typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
+  iterator begin() { return LPairs.begin(); }
+  iterator end()   { return LPairs.end(); }
+
+  void flattenLocations() override {
+    for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
+  }
+
+  typedef std::vector<PathDiagnosticLocationPair>::const_iterator
+          const_iterator;
+  const_iterator begin() const { return LPairs.begin(); }
+  const_iterator end() const   { return LPairs.end(); }
+
+  static inline bool classof(const PathDiagnosticPiece *P) {
+    return P->getKind() == ControlFlow;
+  }
+
+  void dump() const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+};
+
+class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
+public:
+  PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
+    : PathDiagnosticSpotPiece(pos, "", Macro) {}
+
+  ~PathDiagnosticMacroPiece();
+
+  PathPieces subPieces;
+  
+  bool containsEvent() const;
+
+  void flattenLocations() override {
+    PathDiagnosticSpotPiece::flattenLocations();
+    for (PathPieces::iterator I = subPieces.begin(), 
+         E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
+  }
+
+  static inline bool classof(const PathDiagnosticPiece *P) {
+    return P->getKind() == Macro;
+  }
+
+  void dump() const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+};
+
+/// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
+///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
+///  each which represent the pieces of the path.
+class PathDiagnostic : public llvm::FoldingSetNode {
+  std::string CheckName;
+  const Decl *DeclWithIssue;
+  std::string BugType;
+  std::string VerboseDesc;
+  std::string ShortDesc;
+  std::string Category;
+  std::deque<std::string> OtherDesc;
+
+  /// \brief Loc The location of the path diagnostic report.
+  PathDiagnosticLocation Loc;
+
+  PathPieces pathImpl;
+  SmallVector<PathPieces *, 3> pathStack;
+  
+  /// \brief Important bug uniqueing location.
+  /// The location info is useful to differentiate between bugs.
+  PathDiagnosticLocation UniqueingLoc;
+  const Decl *UniqueingDecl;
+
+  PathDiagnostic() LLVM_DELETED_FUNCTION;
+public:
+  PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+                 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
+                 StringRef category, PathDiagnosticLocation LocationToUnique,
+                 const Decl *DeclToUnique);
+
+  ~PathDiagnostic();
+  
+  const PathPieces &path;
+
+  /// Return the path currently used by builders for constructing the 
+  /// PathDiagnostic.
+  PathPieces &getActivePath() {
+    if (pathStack.empty())
+      return pathImpl;
+    return *pathStack.back();
+  }
+  
+  /// Return a mutable version of 'path'.
+  PathPieces &getMutablePieces() {
+    return pathImpl;
+  }
+    
+  /// Return the unrolled size of the path.
+  unsigned full_size();
+
+  void pushActivePath(PathPieces *p) { pathStack.push_back(p); }
+  void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); }
+
+  bool isWithinCall() const { return !pathStack.empty(); }
+
+  void setEndOfPath(PathDiagnosticPiece *EndPiece) {
+    assert(!Loc.isValid() && "End location already set!");
+    Loc = EndPiece->getLocation();
+    assert(Loc.isValid() && "Invalid location for end-of-path piece");
+    getActivePath().push_back(EndPiece);
+  }
+
+  void appendToDesc(StringRef S) {
+    if (!ShortDesc.empty())
+      ShortDesc.append(S);
+    VerboseDesc.append(S);
+  }
+
+  void resetPath() {
+    pathStack.clear();
+    pathImpl.clear();
+    Loc = PathDiagnosticLocation();
+  }
+
+  /// \brief If the last piece of the report point to the header file, resets
+  /// the location of the report to be the last location in the main source
+  /// file.
+  void resetDiagnosticLocationToMainFile();
+
+  StringRef getVerboseDescription() const { return VerboseDesc; }
+  StringRef getShortDescription() const {
+    return ShortDesc.empty() ? VerboseDesc : ShortDesc;
+  }
+  StringRef getCheckName() const { return CheckName; }
+  StringRef getBugType() const { return BugType; }
+  StringRef getCategory() const { return Category; }
+
+  /// Return the semantic context where an issue occurred.  If the
+  /// issue occurs along a path, this represents the "central" area
+  /// where the bug manifests.
+  const Decl *getDeclWithIssue() const { return DeclWithIssue; }
+
+  typedef std::deque<std::string>::const_iterator meta_iterator;
+  meta_iterator meta_begin() const { return OtherDesc.begin(); }
+  meta_iterator meta_end() const { return OtherDesc.end(); }
+  void addMeta(StringRef s) { OtherDesc.push_back(s); }
+
+  PathDiagnosticLocation getLocation() const {
+    assert(Loc.isValid() && "No report location set yet!");
+    return Loc;
+  }
+
+  /// \brief Get the location on which the report should be uniqued.
+  PathDiagnosticLocation getUniqueingLoc() const {
+    return UniqueingLoc;
+  }
+
+  /// \brief Get the declaration containing the uniqueing location.
+  const Decl *getUniqueingDecl() const {
+    return UniqueingDecl;
+  }
+
+  void flattenLocations() {
+    Loc.flatten();
+    for (PathPieces::iterator I = pathImpl.begin(), E = pathImpl.end(); 
+         I != E; ++I) (*I)->flattenLocations();
+  }
+
+  /// Profiles the diagnostic, independent of the path it references.
+  ///
+  /// This can be used to merge diagnostics that refer to the same issue
+  /// along different paths.
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  /// Profiles the diagnostic, including its path.
+  ///
+  /// Two diagnostics with the same issue along different paths will generate
+  /// different profiles.
+  void FullProfile(llvm::FoldingSetNodeID &ID) const;
+};  
+
+} // end GR namespace
+
+} //end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
new file mode 100644
index 0000000..b9a5b8a
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -0,0 +1,566 @@
+//== Checker.h - Registration mechanism for checkers -------------*- 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 Checker, used to create and register checkers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_CORE_CHECKER
+#define LLVM_CLANG_SA_CORE_CHECKER
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/Support/Casting.h"
+
+namespace clang {
+namespace ento {
+  class BugReporter;
+
+namespace check {
+
+struct _VoidCheck {
+  static void _register(void *checker, CheckerManager &mgr) { }
+};
+
+template <typename DECL>
+class ASTDecl {
+  template <typename CHECKER>
+  static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
+                         BugReporter &BR) {
+    ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
+  }
+
+  static bool _handlesDecl(const Decl *D) {
+    return isa<DECL>(D);
+  }
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
+                                                       _checkDecl<CHECKER>),
+                         _handlesDecl);
+  }
+};
+
+class ASTCodeBody {
+  template <typename CHECKER>
+  static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
+                         BugReporter &BR) {
+    ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
+                                                       _checkBody<CHECKER>));
+  }
+};
+
+class EndOfTranslationUnit {
+  template <typename CHECKER>
+  static void _checkEndOfTranslationUnit(void *checker,
+                                         const TranslationUnitDecl *TU, 
+                                         AnalysisManager& mgr,
+                                         BugReporter &BR) {
+    ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr){
+    mgr._registerForEndOfTranslationUnit(
+                              CheckerManager::CheckEndOfTranslationUnit(checker,
+                                          _checkEndOfTranslationUnit<CHECKER>));
+  }
+};
+
+template <typename STMT>
+class PreStmt {
+  template <typename CHECKER>
+  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
+  }
+
+  static bool _handlesStmt(const Stmt *S) {
+    return isa<STMT>(S);
+  }
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
+                                                          _checkStmt<CHECKER>),
+                            _handlesStmt);
+  }
+};
+
+template <typename STMT>
+class PostStmt {
+  template <typename CHECKER>
+  static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
+  }
+
+  static bool _handlesStmt(const Stmt *S) {
+    return isa<STMT>(S);
+  }
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
+                                                           _checkStmt<CHECKER>),
+                             _handlesStmt);
+  }
+};
+
+class PreObjCMessage {
+  template <typename CHECKER>
+  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
+                                CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPreObjCMessage(
+     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
+  }
+};
+
+class PostObjCMessage {
+  template <typename CHECKER>
+  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
+                                CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPostObjCMessage(
+     CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
+  }
+};
+
+class PreCall {
+  template <typename CHECKER>
+  static void _checkCall(void *checker, const CallEvent &msg,
+                         CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPreCall(msg, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPreCall(
+     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+  }
+};
+
+class PostCall {
+  template <typename CHECKER>
+  static void _checkCall(void *checker, const CallEvent &msg,
+                         CheckerContext &C) {
+    ((const CHECKER *)checker)->checkPostCall(msg, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPostCall(
+     CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+  }
+};
+
+class Location {
+  template <typename CHECKER>
+  static void _checkLocation(void *checker,
+                             const SVal &location, bool isLoad, const Stmt *S,
+                             CheckerContext &C) {
+    ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForLocation(
+           CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
+  }
+};
+
+class Bind {
+  template <typename CHECKER>
+  static void _checkBind(void *checker,
+                         const SVal &location, const SVal &val, const Stmt *S,
+                         CheckerContext &C) {
+    ((const CHECKER *)checker)->checkBind(location, val, S, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForBind(
+           CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
+  }
+};
+
+class EndAnalysis {
+  template <typename CHECKER>
+  static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
+                                BugReporter &BR, ExprEngine &Eng) {
+    ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForEndAnalysis(
+     CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
+  }
+};
+
+class EndFunction {
+  template <typename CHECKER>
+  static void _checkEndFunction(void *checker,
+                                CheckerContext &C) {
+    ((const CHECKER *)checker)->checkEndFunction(C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForEndFunction(
+     CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
+  }
+};
+
+class BranchCondition {
+  template <typename CHECKER>
+  static void _checkBranchCondition(void *checker, const Stmt *Condition,
+                                    CheckerContext & C) {
+    ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForBranchCondition(
+      CheckerManager::CheckBranchConditionFunc(checker,
+                                               _checkBranchCondition<CHECKER>));
+  }
+};
+
+class LiveSymbols {
+  template <typename CHECKER>
+  static void _checkLiveSymbols(void *checker, ProgramStateRef state,
+                                SymbolReaper &SR) {
+    ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForLiveSymbols(
+     CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
+  }
+};
+
+class DeadSymbols {
+  template <typename CHECKER>
+  static void _checkDeadSymbols(void *checker,
+                                SymbolReaper &SR, CheckerContext &C) {
+    ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForDeadSymbols(
+     CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
+  }
+};
+
+class RegionChanges {
+  template <typename CHECKER>
+  static ProgramStateRef 
+  _checkRegionChanges(void *checker,
+                      ProgramStateRef state,
+                      const InvalidatedSymbols *invalidated,
+                      ArrayRef<const MemRegion *> Explicits,
+                      ArrayRef<const MemRegion *> Regions,
+                      const CallEvent *Call) {
+    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
+                                                      Explicits, Regions, Call);
+  }
+  template <typename CHECKER>
+  static bool _wantsRegionChangeUpdate(void *checker,
+                                       ProgramStateRef state) {
+    return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForRegionChanges(
+          CheckerManager::CheckRegionChangesFunc(checker,
+                                                 _checkRegionChanges<CHECKER>),
+          CheckerManager::WantsRegionChangeUpdateFunc(checker,
+                                            _wantsRegionChangeUpdate<CHECKER>));
+  }
+};
+
+class PointerEscape {
+  template <typename CHECKER>
+  static ProgramStateRef
+  _checkPointerEscape(void *Checker,
+                     ProgramStateRef State,
+                     const InvalidatedSymbols &Escaped,
+                     const CallEvent *Call,
+                     PointerEscapeKind Kind,
+                     RegionAndSymbolInvalidationTraits *ETraits) {
+
+    if (!ETraits)
+      return ((const CHECKER *)Checker)->checkPointerEscape(State,
+                                                            Escaped,
+                                                            Call,
+                                                            Kind);
+
+    InvalidatedSymbols RegularEscape;
+    for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
+                                            E = Escaped.end(); I != E; ++I)
+      if (!ETraits->hasTrait(*I,
+              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+          !ETraits->hasTrait(*I,
+              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+        RegularEscape.insert(*I);
+
+    if (RegularEscape.empty())
+      return State;
+
+    return ((const CHECKER *)Checker)->checkPointerEscape(State,
+                                                          RegularEscape,
+                                                          Call,
+                                                          Kind);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPointerEscape(
+          CheckerManager::CheckPointerEscapeFunc(checker,
+                                                _checkPointerEscape<CHECKER>));
+  }
+};
+
+class ConstPointerEscape {
+  template <typename CHECKER>
+  static ProgramStateRef
+  _checkConstPointerEscape(void *Checker,
+                      ProgramStateRef State,
+                      const InvalidatedSymbols &Escaped,
+                      const CallEvent *Call,
+                      PointerEscapeKind Kind,
+                      RegionAndSymbolInvalidationTraits *ETraits) {
+
+    if (!ETraits)
+      return State;
+
+    InvalidatedSymbols ConstEscape;
+    for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 
+                                            E = Escaped.end(); I != E; ++I)
+      if (ETraits->hasTrait(*I,
+              RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+          !ETraits->hasTrait(*I,
+              RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+        ConstEscape.insert(*I);
+
+    if (ConstEscape.empty())
+      return State;
+
+    return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
+                                                               ConstEscape,
+                                                               Call,
+                                                               Kind);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForPointerEscape(
+      CheckerManager::CheckPointerEscapeFunc(checker,
+                                            _checkConstPointerEscape<CHECKER>));
+  }
+};
+
+  
+template <typename EVENT>
+class Event {
+  template <typename CHECKER>
+  static void _checkEvent(void *checker, const void *event) {
+    ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
+  }
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerListenerForEvent<EVENT>(
+                 CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
+  }
+};
+
+} // end check namespace
+
+namespace eval {
+
+class Assume {
+  template <typename CHECKER>
+  static ProgramStateRef _evalAssume(void *checker,
+                                         ProgramStateRef state,
+                                         const SVal &cond,
+                                         bool assumption) {
+    return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForEvalAssume(
+                 CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
+  }
+};
+
+class Call {
+  template <typename CHECKER>
+  static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
+    return ((const CHECKER *)checker)->evalCall(CE, C);
+  }
+
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerForEvalCall(
+                     CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
+  }
+};
+
+} // end eval namespace
+
+class CheckerBase : public ProgramPointTag {
+  CheckName Name;
+  friend class ::clang::ento::CheckerManager;
+
+public:
+  StringRef getTagDescription() const override;
+  CheckName getCheckName() const;
+
+  /// See CheckerManager::runCheckersForPrintState.
+  virtual void printState(raw_ostream &Out, ProgramStateRef State,
+                          const char *NL, const char *Sep) const { }
+};
+
+/// Dump checker name to stream.
+raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
+
+/// Tag that can use a checker name as a message provider 
+/// (see SimpleProgramPointTag).
+class CheckerProgramPointTag : public SimpleProgramPointTag {
+public:
+  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
+  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
+};
+
+template <typename CHECK1, typename CHECK2=check::_VoidCheck,
+          typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
+          typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
+          typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck,
+          typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck,
+          typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck,
+          typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck,
+          typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck,
+          typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck,
+          typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck,
+          typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck,
+          typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck>
+class Checker;
+
+template <>
+class Checker<check::_VoidCheck>
+  : public CheckerBase 
+{
+  virtual void anchor();
+public:
+  static void _register(void *checker, CheckerManager &mgr) { }
+};
+
+template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4,
+          typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8,
+          typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12,
+          typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16,
+          typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20,
+          typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24>
+class Checker
+    : public CHECK1,
+      public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
+                     CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
+                     CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
+                     CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> {
+public:
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    CHECK1::_register(checker, mgr);
+    Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7,
+            CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13,
+            CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19,
+            CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr);
+  }
+};
+
+template <typename EVENT>
+class EventDispatcher {
+  CheckerManager *Mgr;
+public:
+  EventDispatcher() : Mgr(nullptr) { }
+
+  template <typename CHECKER>
+  static void _register(CHECKER *checker, CheckerManager &mgr) {
+    mgr._registerDispatcherForEvent<EVENT>();
+    static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
+  }
+
+  void dispatchEvent(const EVENT &event) const {
+    Mgr->_dispatchEvent(event);
+  }
+};
+
+/// \brief We dereferenced a location that may be null.
+struct ImplicitNullDerefEvent {
+  SVal Location;
+  bool IsLoad;
+  ExplodedNode *SinkNode;
+  BugReporter *BR;
+};
+
+/// \brief A helper class which wraps a boolean value set to false by default.
+///
+/// This class should behave exactly like 'bool' except that it doesn't need to
+/// be explicitly initialized.
+struct DefaultBool {
+  bool val;
+  DefaultBool() : val(false) {}
+  /*implicit*/ operator bool&() { return val; }
+  /*implicit*/ operator const bool&() const { return val; }
+  DefaultBool &operator=(bool b) { val = b; return *this; }
+};
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
new file mode 100644
index 0000000..b364115
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -0,0 +1,662 @@
+//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the Static Analyzer Checker Manager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
+#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+  class Decl;
+  class Stmt;
+  class CallExpr;
+
+namespace ento {
+  class CheckerBase;
+  class CheckerRegistry;
+  class ExprEngine;
+  class AnalysisManager;
+  class BugReporter;
+  class CheckerContext;
+  class ObjCMethodCall;
+  class SVal;
+  class ExplodedNode;
+  class ExplodedNodeSet;
+  class ExplodedGraph;
+  class ProgramState;
+  class NodeBuilder;
+  struct NodeBuilderContext;
+  class MemRegion;
+  class SymbolReaper;
+
+template <typename T> class CheckerFn;
+
+template <typename RET, typename P1, typename P2, typename P3, typename P4,
+          typename P5>
+class CheckerFn<RET(P1, P2, P3, P4, P5)> {
+  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
+    return Fn(Checker, p1, p2, p3, p4, p5);
+  }
+};
+
+template <typename RET, typename P1, typename P2, typename P3, typename P4>
+class CheckerFn<RET(P1, P2, P3, P4)> {
+  typedef RET (*Func)(void *, P1, P2, P3, P4);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { 
+    return Fn(Checker, p1, p2, p3, p4);
+  } 
+};
+
+template <typename RET, typename P1, typename P2, typename P3>
+class CheckerFn<RET(P1, P2, P3)> {
+  typedef RET (*Func)(void *, P1, P2, P3);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } 
+};
+
+template <typename RET, typename P1, typename P2>
+class CheckerFn<RET(P1, P2)> {
+  typedef RET (*Func)(void *, P1, P2);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } 
+};
+
+template <typename RET, typename P1>
+class CheckerFn<RET(P1)> {
+  typedef RET (*Func)(void *, P1);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()(P1 p1) const { return Fn(Checker, p1); } 
+};
+
+template <typename RET>
+class CheckerFn<RET()> {
+  typedef RET (*Func)(void *);
+  Func Fn;
+public:
+  CheckerBase *Checker;
+  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
+  RET operator()() const { return Fn(Checker); } 
+};
+
+/// \brief Describes the different reasons a pointer escapes
+/// during analysis.
+enum PointerEscapeKind {
+  /// A pointer escapes due to binding its value to a location
+  /// that the analyzer cannot track.
+  PSK_EscapeOnBind,
+
+  /// The pointer has been passed to a function call directly.
+  PSK_DirectEscapeOnCall,
+
+  /// The pointer has been passed to a function indirectly.
+  /// For example, the pointer is accessible through an
+  /// argument to a function.
+  PSK_IndirectEscapeOnCall,
+
+  /// The reason for pointer escape is unknown. For example, 
+  /// a region containing this pointer is invalidated.
+  PSK_EscapeOther
+};
+
+// This wrapper is used to ensure that only StringRefs originating from the
+// CheckerRegistry are used as check names. We want to make sure all check
+// name strings have a lifetime that keeps them alive at least until the path
+// diagnostics have been processed.
+class CheckName {
+  StringRef Name;
+  friend class ::clang::ento::CheckerRegistry;
+  explicit CheckName(StringRef Name) : Name(Name) {}
+
+public:
+  CheckName() {}
+  CheckName(const CheckName &Other) : Name(Other.Name) {}
+  StringRef getName() const { return Name; }
+};
+
+class CheckerManager {
+  const LangOptions LangOpts;
+  AnalyzerOptionsRef AOptions;
+  CheckName CurrentCheckName;
+
+public:
+  CheckerManager(const LangOptions &langOpts,
+                 AnalyzerOptionsRef AOptions)
+    : LangOpts(langOpts),
+      AOptions(AOptions) {}
+
+  ~CheckerManager();
+
+  void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
+  CheckName getCurrentCheckName() const { return CurrentCheckName; }
+
+  bool hasPathSensitiveCheckers() const;
+
+  void finishedCheckerRegistration();
+
+  const LangOptions &getLangOpts() const { return LangOpts; }
+  AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
+
+  typedef CheckerBase *CheckerRef;
+  typedef const void *CheckerTag;
+  typedef CheckerFn<void ()> CheckerDtor;
+
+//===----------------------------------------------------------------------===//
+// registerChecker
+//===----------------------------------------------------------------------===//
+
+  /// \brief Used to register checkers.
+  ///
+  /// \returns a pointer to the checker object.
+  template <typename CHECKER>
+  CHECKER *registerChecker() {
+    CheckerTag tag = getTag<CHECKER>();
+    CheckerRef &ref = CheckerTags[tag];
+    if (ref)
+      return static_cast<CHECKER *>(ref); // already registered.
+
+    CHECKER *checker = new CHECKER();
+    checker->Name = CurrentCheckName;
+    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
+    CHECKER::_register(checker, *this);
+    ref = checker;
+    return checker;
+  }
+
+  template <typename CHECKER>
+  CHECKER *registerChecker(AnalyzerOptions &AOpts) {
+    CheckerTag tag = getTag<CHECKER>();
+    CheckerRef &ref = CheckerTags[tag];
+    if (ref)
+      return static_cast<CHECKER *>(ref); // already registered.
+
+    CHECKER *checker = new CHECKER(AOpts);
+    checker->Name = CurrentCheckName;
+    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
+    CHECKER::_register(checker, *this);
+    ref = checker;
+    return checker;
+  }
+
+//===----------------------------------------------------------------------===//
+// Functions for running checkers for AST traversing..
+//===----------------------------------------------------------------------===//
+
+  /// \brief Run checkers handling Decls.
+  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
+                            BugReporter &BR);
+
+  /// \brief Run checkers handling Decls containing a Stmt body.
+  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
+                            BugReporter &BR);
+
+//===----------------------------------------------------------------------===//
+// Functions for running checkers for path-sensitive checking.
+//===----------------------------------------------------------------------===//
+
+  /// \brief Run checkers for pre-visiting Stmts.
+  ///
+  /// The notification is performed for every explored CFGElement, which does
+  /// not include the control flow statements such as IfStmt.
+  ///
+  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
+  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
+                             const ExplodedNodeSet &Src,
+                             const Stmt *S,
+                             ExprEngine &Eng) {
+    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
+  }
+
+  /// \brief Run checkers for post-visiting Stmts.
+  ///
+  /// The notification is performed for every explored CFGElement, which does
+  /// not include the control flow statements such as IfStmt.
+  ///
+  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
+  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
+                              const ExplodedNodeSet &Src,
+                              const Stmt *S,
+                              ExprEngine &Eng,
+                              bool wasInlined = false) {
+    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
+  }
+
+  /// \brief Run checkers for visiting Stmts.
+  void runCheckersForStmt(bool isPreVisit,
+                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
+                          const Stmt *S, ExprEngine &Eng,
+                          bool wasInlined = false);
+
+  /// \brief Run checkers for pre-visiting obj-c messages.
+  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
+                                    const ExplodedNodeSet &Src,
+                                    const ObjCMethodCall &msg,
+                                    ExprEngine &Eng) {
+    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
+  }
+
+  /// \brief Run checkers for post-visiting obj-c messages.
+  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
+                                     const ExplodedNodeSet &Src,
+                                     const ObjCMethodCall &msg,
+                                     ExprEngine &Eng,
+                                     bool wasInlined = false) {
+    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
+                              wasInlined);
+  }
+
+  /// \brief Run checkers for visiting obj-c messages.
+  void runCheckersForObjCMessage(bool isPreVisit,
+                                 ExplodedNodeSet &Dst,
+                                 const ExplodedNodeSet &Src,
+                                 const ObjCMethodCall &msg, ExprEngine &Eng,
+                                 bool wasInlined = false);
+
+  /// \brief Run checkers for pre-visiting obj-c messages.
+  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
+                             const CallEvent &Call, ExprEngine &Eng) {
+    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
+  }
+
+  /// \brief Run checkers for post-visiting obj-c messages.
+  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
+                              const CallEvent &Call, ExprEngine &Eng,
+                              bool wasInlined = false) {
+    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
+                            wasInlined);
+  }
+
+  /// \brief Run checkers for visiting obj-c messages.
+  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
+                               const ExplodedNodeSet &Src,
+                               const CallEvent &Call, ExprEngine &Eng,
+                               bool wasInlined = false);
+
+  /// \brief Run checkers for load/store of a location.
+  void runCheckersForLocation(ExplodedNodeSet &Dst,
+                              const ExplodedNodeSet &Src,
+                              SVal location,
+                              bool isLoad,
+                              const Stmt *NodeEx,
+                              const Stmt *BoundEx,
+                              ExprEngine &Eng);
+
+  /// \brief Run checkers for binding of a value to a location.
+  void runCheckersForBind(ExplodedNodeSet &Dst,
+                          const ExplodedNodeSet &Src,
+                          SVal location, SVal val,
+                          const Stmt *S, ExprEngine &Eng,
+                          const ProgramPoint &PP);
+
+  /// \brief Run checkers for end of analysis.
+  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
+                                 ExprEngine &Eng);
+
+  /// \brief Run checkers on end of function.
+  void runCheckersForEndFunction(NodeBuilderContext &BC,
+                                 ExplodedNodeSet &Dst,
+                                 ExplodedNode *Pred,
+                                 ExprEngine &Eng);
+
+  /// \brief Run checkers for branch condition.
+  void runCheckersForBranchCondition(const Stmt *condition,
+                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
+                                     ExprEngine &Eng);
+
+  /// \brief Run checkers for live symbols.
+  ///
+  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
+  /// register symbols of interest as live. These symbols will not be marked
+  /// dead and removed.
+  void runCheckersForLiveSymbols(ProgramStateRef state,
+                                 SymbolReaper &SymReaper);
+
+  /// \brief Run checkers for dead symbols.
+  ///
+  /// Notifies checkers when symbols become dead. For example, this allows
+  /// checkers to aggressively clean up/reduce the checker state and produce
+  /// precise diagnostics.
+  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
+                                 const ExplodedNodeSet &Src,
+                                 SymbolReaper &SymReaper, const Stmt *S,
+                                 ExprEngine &Eng,
+                                 ProgramPoint::Kind K);
+
+  /// \brief True if at least one checker wants to check region changes.
+  bool wantsRegionChangeUpdate(ProgramStateRef state);
+
+  /// \brief Run checkers for region changes.
+  ///
+  /// This corresponds to the check::RegionChanges callback.
+  /// \param state The current program state.
+  /// \param invalidated A set of all symbols potentially touched by the change.
+  /// \param ExplicitRegions The regions explicitly requested for invalidation.
+  ///   For example, in the case of a function call, these would be arguments.
+  /// \param Regions The transitive closure of accessible regions,
+  ///   i.e. all regions that may have been touched by this change.
+  /// \param Call The call expression wrapper if the regions are invalidated
+  ///   by a call.
+  ProgramStateRef
+  runCheckersForRegionChanges(ProgramStateRef state,
+                              const InvalidatedSymbols *invalidated,
+                              ArrayRef<const MemRegion *> ExplicitRegions,
+                              ArrayRef<const MemRegion *> Regions,
+                              const CallEvent *Call);
+
+  /// \brief Run checkers when pointers escape.
+  ///
+  /// This notifies the checkers about pointer escape, which occurs whenever
+  /// the analyzer cannot track the symbol any more. For example, as a
+  /// result of assigning a pointer into a global or when it's passed to a 
+  /// function call the analyzer cannot model.
+  /// 
+  /// \param State The state at the point of escape.
+  /// \param Escaped The list of escaped symbols.
+  /// \param Call The corresponding CallEvent, if the symbols escape as 
+  ///        parameters to the given call.
+  /// \param Kind The reason of pointer escape.
+  /// \param ITraits Information about invalidation for a particular 
+  ///        region/symbol.
+  /// \returns Checkers can modify the state by returning a new one.
+  ProgramStateRef 
+  runCheckersForPointerEscape(ProgramStateRef State,
+                              const InvalidatedSymbols &Escaped,
+                              const CallEvent *Call,
+                              PointerEscapeKind Kind,
+                             RegionAndSymbolInvalidationTraits *ITraits);
+
+  /// \brief Run checkers for handling assumptions on symbolic values.
+  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
+                                           SVal Cond, bool Assumption);
+
+  /// \brief Run checkers for evaluating a call.
+  ///
+  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
+  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
+                              const ExplodedNodeSet &Src,
+                              const CallEvent &CE, ExprEngine &Eng);
+  
+  /// \brief Run checkers for the entire Translation Unit.
+  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
+                                         AnalysisManager &mgr,
+                                         BugReporter &BR);
+
+  /// \brief Run checkers for debug-printing a ProgramState.
+  ///
+  /// Unlike most other callbacks, any checker can simply implement the virtual
+  /// method CheckerBase::printState if it has custom data to print.
+  /// \param Out The output stream
+  /// \param State The state being printed
+  /// \param NL The preferred representation of a newline.
+  /// \param Sep The preferred separator between different kinds of data.
+  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
+                                const char *NL, const char *Sep);
+
+//===----------------------------------------------------------------------===//
+// Internal registration functions for AST traversing.
+//===----------------------------------------------------------------------===//
+
+  // Functions used by the registration mechanism, checkers should not touch
+  // these directly.
+
+  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
+      CheckDeclFunc;
+
+  typedef bool (*HandlesDeclFunc)(const Decl *D);
+  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
+
+  void _registerForBody(CheckDeclFunc checkfn);
+
+//===----------------------------------------------------------------------===//
+// Internal registration functions for path-sensitive checking.
+//===----------------------------------------------------------------------===//
+
+  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
+  
+  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
+      CheckObjCMessageFunc;
+
+  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
+      CheckCallFunc;
+  
+  typedef CheckerFn<void (const SVal &location, bool isLoad,
+                          const Stmt *S,
+                          CheckerContext &)>
+      CheckLocationFunc;
+  
+  typedef CheckerFn<void (const SVal &location, const SVal &val, 
+                          const Stmt *S, CheckerContext &)> 
+      CheckBindFunc;
+  
+  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
+      CheckEndAnalysisFunc;
+  
+  typedef CheckerFn<void (CheckerContext &)>
+      CheckEndFunctionFunc;
+  
+  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
+      CheckBranchConditionFunc;
+  
+  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
+      CheckDeadSymbolsFunc;
+  
+  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
+  
+  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
+                                const InvalidatedSymbols *symbols,
+                                ArrayRef<const MemRegion *> ExplicitRegions,
+                                ArrayRef<const MemRegion *> Regions,
+                                const CallEvent *Call)>
+      CheckRegionChangesFunc;
+  
+  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
+
+  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
+                                     const InvalidatedSymbols &Escaped,
+                                     const CallEvent *Call,
+                                     PointerEscapeKind Kind,
+                                     RegionAndSymbolInvalidationTraits *ITraits)>
+      CheckPointerEscapeFunc;
+  
+  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
+                                          const SVal &cond, bool assumption)>
+      EvalAssumeFunc;
+  
+  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
+      EvalCallFunc;
+
+  typedef CheckerFn<void (const TranslationUnitDecl *,
+                          AnalysisManager&, BugReporter &)>
+      CheckEndOfTranslationUnit;
+
+  typedef bool (*HandlesStmtFunc)(const Stmt *D);
+  void _registerForPreStmt(CheckStmtFunc checkfn,
+                           HandlesStmtFunc isForStmtFn);
+  void _registerForPostStmt(CheckStmtFunc checkfn,
+                            HandlesStmtFunc isForStmtFn);
+
+  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
+  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
+
+  void _registerForPreCall(CheckCallFunc checkfn);
+  void _registerForPostCall(CheckCallFunc checkfn);
+
+  void _registerForLocation(CheckLocationFunc checkfn);
+
+  void _registerForBind(CheckBindFunc checkfn);
+
+  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
+
+  void _registerForEndFunction(CheckEndFunctionFunc checkfn);
+
+  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
+
+  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
+
+  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
+
+  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
+                                 WantsRegionChangeUpdateFunc wantUpdateFn);
+
+  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
+
+  void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
+
+  void _registerForEvalAssume(EvalAssumeFunc checkfn);
+
+  void _registerForEvalCall(EvalCallFunc checkfn);
+
+  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
+
+//===----------------------------------------------------------------------===//
+// Internal registration functions for events.
+//===----------------------------------------------------------------------===//
+
+  typedef void *EventTag;
+  typedef CheckerFn<void (const void *event)> CheckEventFunc;
+
+  template <typename EVENT>
+  void _registerListenerForEvent(CheckEventFunc checkfn) {
+    EventInfo &info = Events[getTag<EVENT>()];
+    info.Checkers.push_back(checkfn);    
+  }
+
+  template <typename EVENT>
+  void _registerDispatcherForEvent() {
+    EventInfo &info = Events[getTag<EVENT>()];
+    info.HasDispatcher = true;
+  }
+
+  template <typename EVENT>
+  void _dispatchEvent(const EVENT &event) const {
+    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
+    if (I == Events.end())
+      return;
+    const EventInfo &info = I->second;
+    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
+      info.Checkers[i](&event);
+  }
+
+//===----------------------------------------------------------------------===//
+// Implementation details.
+//===----------------------------------------------------------------------===//
+
+private:
+  template <typename CHECKER>
+  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
+
+  template <typename T>
+  static void *getTag() { static int tag; return &tag; }
+
+  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
+
+  std::vector<CheckerDtor> CheckerDtors;
+
+  struct DeclCheckerInfo {
+    CheckDeclFunc CheckFn;
+    HandlesDeclFunc IsForDeclFn;
+  };
+  std::vector<DeclCheckerInfo> DeclCheckers;
+
+  std::vector<CheckDeclFunc> BodyCheckers;
+
+  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
+  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
+  CachedDeclCheckersMapTy CachedDeclCheckersMap;
+
+  struct StmtCheckerInfo {
+    CheckStmtFunc CheckFn;
+    HandlesStmtFunc IsForStmtFn;
+    bool IsPreVisit;
+  };
+  std::vector<StmtCheckerInfo> StmtCheckers;
+
+  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
+  typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
+  CachedStmtCheckersMapTy CachedStmtCheckersMap;
+
+  const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
+                                                     bool isPreVisit);
+
+  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
+  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
+
+  std::vector<CheckCallFunc> PreCallCheckers;
+  std::vector<CheckCallFunc> PostCallCheckers;
+
+  std::vector<CheckLocationFunc> LocationCheckers;
+
+  std::vector<CheckBindFunc> BindCheckers;
+
+  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
+
+  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
+
+  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
+
+  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
+
+  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
+
+  struct RegionChangesCheckerInfo {
+    CheckRegionChangesFunc CheckFn;
+    WantsRegionChangeUpdateFunc WantUpdateFn;
+  };
+  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
+
+  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
+
+  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
+
+  std::vector<EvalCallFunc> EvalCallCheckers;
+
+  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
+
+  struct EventInfo {
+    SmallVector<CheckEventFunc, 4> Checkers;
+    bool HasDispatcher;
+    EventInfo() : HasDispatcher(false) { }
+  };
+  
+  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
+  EventsTy Events;
+};
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
new file mode 100644
index 0000000..e981871
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
@@ -0,0 +1,44 @@
+//===--- CheckerOptInfo.h - Specifies which checkers to use -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
+#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace ento {
+
+/// Represents a request to include or exclude a checker or package from a
+/// specific analysis run.
+///
+/// \sa CheckerRegistry::initializeManager
+class CheckerOptInfo {
+  StringRef Name;
+  bool Enable;
+  bool Claimed;
+
+public:
+  CheckerOptInfo(StringRef name, bool enable)
+    : Name(name), Enable(enable), Claimed(false) { }
+  
+  StringRef getName() const { return Name; }
+  bool isEnabled() const { return Enable; }
+  bool isDisabled() const { return !isEnabled(); }
+
+  bool isClaimed() const { return Claimed; }
+  bool isUnclaimed() const { return !isClaimed(); }
+  void claim() { Claimed = true; }
+};
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
new file mode 100644
index 0000000..ca68a74
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
@@ -0,0 +1,133 @@
+//===--- CheckerRegistry.h - Maintains all available checkers ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
+#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include <vector>
+
+// FIXME: move this information to an HTML file in docs/.
+// At the very least, a checker plugin is a dynamic library that exports
+// clang_analyzerAPIVersionString. This should be defined as follows:
+//
+//   extern "C"
+//   const char clang_analyzerAPIVersionString[] =
+//     CLANG_ANALYZER_API_VERSION_STRING;
+//
+// This is used to check whether the current version of the analyzer is known to
+// be incompatible with a plugin. Plugins with incompatible version strings,
+// or without a version string at all, will not be loaded.
+//
+// To add a custom checker to the analyzer, the plugin must also define the
+// function clang_registerCheckers. For example:
+//
+//    extern "C"
+//    void clang_registerCheckers (CheckerRegistry &registry) {
+//      registry.addChecker<MainCallChecker>("example.MainCallChecker",
+//        "Disallows calls to functions called main");
+//    }
+//
+// The first method argument is the full name of the checker, including its
+// enclosing package. By convention, the registered name of a checker is the
+// name of the associated class (the template argument).
+// The second method argument is a short human-readable description of the
+// checker.
+//
+// The clang_registerCheckers function may add any number of checkers to the
+// registry. If any checkers require additional initialization, use the three-
+// argument form of CheckerRegistry::addChecker.
+// 
+// To load a checker plugin, specify the full path to the dynamic library as
+// the argument to the -load option in the cc1 frontend. You can then enable
+// your custom checker using the -analyzer-checker:
+//
+//   clang -cc1 -load </path/to/plugin.dylib> -analyze
+//     -analyzer-checker=<example.MainCallChecker>
+//
+// For a complete working example, see examples/analyzer-plugin.
+
+#ifndef CLANG_ANALYZER_API_VERSION_STRING
+// FIXME: The Clang version string is not particularly granular;
+// the analyzer infrastructure can change a lot between releases.
+// Unfortunately, this string has to be statically embedded in each plugin,
+// so we can't just use the functions defined in Version.h.
+#include "clang/Basic/Version.h"
+#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
+#endif
+
+namespace clang {
+namespace ento {
+
+class CheckerOptInfo;
+
+/// Manages a set of available checkers for running a static analysis.
+/// The checkers are organized into packages by full name, where including
+/// a package will recursively include all subpackages and checkers within it.
+/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be
+/// included if initializeManager() is called with an option of "core",
+/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
+class CheckerRegistry {
+public:
+  /// Initialization functions perform any necessary setup for a checker.
+  /// They should include a call to CheckerManager::registerChecker.
+  typedef void (*InitializationFunction)(CheckerManager &);
+  struct CheckerInfo {
+    InitializationFunction Initialize;
+    StringRef FullName;
+    StringRef Desc;
+
+    CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc)
+    : Initialize(fn), FullName(name), Desc(desc) {}
+  };
+
+  typedef std::vector<CheckerInfo> CheckerInfoList;
+
+private:
+  template <typename T>
+  static void initializeManager(CheckerManager &mgr) {
+    mgr.registerChecker<T>();
+  }
+
+public:
+  /// Adds a checker to the registry. Use this non-templated overload when your
+  /// checker requires custom initialization.
+  void addChecker(InitializationFunction fn, StringRef fullName,
+                  StringRef desc);
+
+  /// Adds a checker to the registry. Use this templated overload when your
+  /// checker does not require any custom initialization.
+  template <class T>
+  void addChecker(StringRef fullName, StringRef desc) {
+    // Avoid MSVC's Compiler Error C2276:
+    // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
+    addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc);
+  }
+
+  /// Initializes a CheckerManager by calling the initialization functions for
+  /// all checkers specified by the given CheckerOptInfo list. The order of this
+  /// list is significant; later options can be used to reverse earlier ones.
+  /// This can be used to exclude certain checkers in an included package.
+  void initializeManager(CheckerManager &mgr,
+                         SmallVectorImpl<CheckerOptInfo> &opts) const;
+
+  /// Prints the name and description of all checkers in this registry.
+  /// This output is not intended to be machine-parseable.
+  void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ;
+
+private:
+  mutable CheckerInfoList Checkers;
+  mutable llvm::StringMap<size_t> Packages;
+};
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
new file mode 100644
index 0000000..43e9166
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -0,0 +1,40 @@
+//===--- PathDiagnosticClients.h - Path Diagnostic Clients ------*- 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 interface to create different path diagostic clients.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
+#define LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class AnalyzerOptions;
+class Preprocessor;
+
+namespace ento {
+
+class PathDiagnosticConsumer;
+typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
+
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\
+void CREATEFN(AnalyzerOptions &AnalyzerOpts,\
+              PathDiagnosticConsumers &C,\
+              const std::string &Prefix,\
+              const Preprocessor &PP);
+#include "clang/StaticAnalyzer/Core/Analyses.def"
+
+} // end 'ento' namespace
+} // end 'clang' namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
new file mode 100644
index 0000000..37be69a
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -0,0 +1,109 @@
+//== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_CORE_APSINTTYPE_H
+#define LLVM_CLANG_SA_CORE_APSINTTYPE_H
+
+#include "llvm/ADT/APSInt.h"
+#include <tuple>
+
+namespace clang {
+namespace ento {
+
+/// \brief A record of the "type" of an APSInt, used for conversions.
+class APSIntType {
+  uint32_t BitWidth;
+  bool IsUnsigned;
+
+public:
+  APSIntType(uint32_t Width, bool Unsigned)
+    : BitWidth(Width), IsUnsigned(Unsigned) {}
+
+  /* implicit */ APSIntType(const llvm::APSInt &Value)
+    : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}
+
+  uint32_t getBitWidth() const { return BitWidth; }
+  bool isUnsigned() const { return IsUnsigned; }
+
+  /// \brief Convert a given APSInt, in place, to match this type.
+  ///
+  /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives
+  /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF).
+  void apply(llvm::APSInt &Value) const {
+    // Note the order here. We extend first to preserve the sign, if this value
+    // is signed, /then/ match the signedness of the result type.
+    Value = Value.extOrTrunc(BitWidth);
+    Value.setIsUnsigned(IsUnsigned);
+  }
+
+  /// Convert and return a new APSInt with the given value, but this
+  /// type's bit width and signedness.
+  ///
+  /// \see apply
+  llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY {
+    llvm::APSInt Result(Value, Value.isUnsigned());
+    apply(Result);
+    return Result;
+  }
+
+  /// Returns an all-zero value for this type.
+  llvm::APSInt getZeroValue() const LLVM_READONLY {
+    return llvm::APSInt(BitWidth, IsUnsigned);
+  }
+
+  /// Returns the minimum value for this type.
+  llvm::APSInt getMinValue() const LLVM_READONLY {
+    return llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
+  }
+
+  /// Returns the maximum value for this type.
+  llvm::APSInt getMaxValue() const LLVM_READONLY {
+    return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
+  }
+
+  llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY {
+    return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue);
+  }
+
+  /// Used to classify whether a value is representable using this type.
+  ///
+  /// \see testInRange
+  enum RangeTestResultKind {
+    RTR_Below = -1, ///< Value is less than the minimum representable value.
+    RTR_Within = 0, ///< Value is representable using this type.
+    RTR_Above = 1   ///< Value is greater than the maximum representable value.
+  };
+
+  /// Tests whether a given value is losslessly representable using this type.
+  ///
+  /// \param Val The value to test.
+  /// \param AllowMixedSign Whether or not to allow signedness conversions.
+  ///                       This determines whether -1s8 is considered in range
+  ///                       for 'unsigned char' (u8).
+  RangeTestResultKind testInRange(const llvm::APSInt &Val,
+                                  bool AllowMixedSign) const LLVM_READONLY;
+  
+  bool operator==(const APSIntType &Other) const {
+    return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
+  }
+
+  /// \brief Provide an ordering for finding a common conversion type.
+  ///
+  /// Unsigned integers are considered to be better conversion types than
+  /// signed integers of the same width.
+  bool operator<(const APSIntType &Other) const {
+    return std::tie(BitWidth, IsUnsigned) <
+           std::tie(Other.BitWidth, Other.IsUnsigned);
+  }
+};
+    
+} // end ento namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
new file mode 100644
index 0000000..1a398b8
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -0,0 +1,132 @@
+//== AnalysisManager.h - Path sensitive analysis data manager ------*- 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 AnalysisManager class that manages the data and policy
+// for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_ANALYSISMANAGER_H
+#define LLVM_CLANG_GR_ANALYSISMANAGER_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
+
+namespace clang {
+
+namespace ento {
+  class CheckerManager;
+
+class AnalysisManager : public BugReporterData {
+  virtual void anchor();
+  AnalysisDeclContextManager AnaCtxMgr;
+
+  ASTContext &Ctx;
+  DiagnosticsEngine &Diags;
+  const LangOptions &LangOpts;
+  PathDiagnosticConsumers PathConsumers;
+
+  // Configurable components creators.
+  StoreManagerCreator CreateStoreMgr;
+  ConstraintManagerCreator CreateConstraintMgr;
+
+  CheckerManager *CheckerMgr;
+
+public:
+  AnalyzerOptions &options;
+  
+  AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags,
+                  const LangOptions &lang,
+                  const PathDiagnosticConsumers &Consumers,
+                  StoreManagerCreator storemgr,
+                  ConstraintManagerCreator constraintmgr, 
+                  CheckerManager *checkerMgr,
+                  AnalyzerOptions &Options);
+
+  ~AnalysisManager();
+  
+  void ClearContexts() {
+    AnaCtxMgr.clear();
+  }
+  
+  AnalysisDeclContextManager& getAnalysisDeclContextManager() {
+    return AnaCtxMgr;
+  }
+
+  StoreManagerCreator getStoreManagerCreator() {
+    return CreateStoreMgr;
+  }
+
+  AnalyzerOptions& getAnalyzerOptions() override {
+    return options;
+  }
+
+  ConstraintManagerCreator getConstraintManagerCreator() {
+    return CreateConstraintMgr;
+  }
+
+  CheckerManager *getCheckerManager() const { return CheckerMgr; }
+
+  ASTContext &getASTContext() override {
+    return Ctx;
+  }
+
+  SourceManager &getSourceManager() override {
+    return getASTContext().getSourceManager();
+  }
+
+  DiagnosticsEngine &getDiagnostic() override {
+    return Diags;
+  }
+
+  const LangOptions &getLangOpts() const {
+    return LangOpts;
+  }
+
+  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override {
+    return PathConsumers;
+  }
+
+  void FlushDiagnostics();
+
+  bool shouldVisualize() const {
+    return options.visualizeExplodedGraphWithGraphViz ||
+           options.visualizeExplodedGraphWithUbiGraph;
+  }
+
+  bool shouldInlineCall() const {
+    return options.getIPAMode() != IPAK_None;
+  }
+
+  CFG *getCFG(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getCFG();
+  }
+
+  template <typename T>
+  T *getAnalysis(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getAnalysis<T>();
+  }
+
+  ParentMap &getParentMap(Decl const *D) {
+    return AnaCtxMgr.getContext(D)->getParentMap();
+  }
+
+  AnalysisDeclContext *getAnalysisDeclContext(const Decl *D) {
+    return AnaCtxMgr.getContext(D);
+  }
+};
+
+} // enAnaCtxMgrspace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
new file mode 100644
index 0000000..08905fd
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -0,0 +1,200 @@
+//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
+//  of APSInt objects and symbolic constraints used by ExprEngine
+//  and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H
+#define LLVM_CLANG_GR_BASICVALUEFACTORY_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+
+namespace clang {
+namespace ento {
+
+class CompoundValData : public llvm::FoldingSetNode {
+  QualType T;
+  llvm::ImmutableList<SVal> L;
+
+public:
+  CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
+    : T(t), L(l) {}
+
+  typedef llvm::ImmutableList<SVal>::iterator iterator;
+  iterator begin() const { return L.begin(); }
+  iterator end() const { return L.end(); }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
+                      llvm::ImmutableList<SVal> L);
+
+  void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
+};
+
+class LazyCompoundValData : public llvm::FoldingSetNode {
+  StoreRef store;
+  const TypedValueRegion *region;
+public:
+  LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
+    : store(st), region(r) {}
+
+  const void *getStore() const { return store.getStore(); }
+  const TypedValueRegion *getRegion() const { return region; }
+
+  static void Profile(llvm::FoldingSetNodeID& ID,
+                      const StoreRef &store,
+                      const TypedValueRegion *region);
+
+  void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
+};
+
+class BasicValueFactory {
+  typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
+          APSIntSetTy;
+
+  ASTContext &Ctx;
+  llvm::BumpPtrAllocator& BPAlloc;
+
+  APSIntSetTy   APSIntSet;
+  void *        PersistentSVals;
+  void *        PersistentSValPairs;
+
+  llvm::ImmutableList<SVal>::Factory SValListFactory;
+  llvm::FoldingSet<CompoundValData>  CompoundValDataSet;
+  llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet;
+
+  // This is private because external clients should use the factory
+  // method that takes a QualType.
+  const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+
+public:
+  BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
+    : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
+      PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
+
+  ~BasicValueFactory();
+
+  ASTContext &getContext() const { return Ctx; }
+
+  const llvm::APSInt& getValue(const llvm::APSInt& X);
+  const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
+  const llvm::APSInt& getValue(uint64_t X, QualType T);
+
+  /// Returns the type of the APSInt used to store values of the given QualType.
+  APSIntType getAPSIntType(QualType T) const {
+    assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
+    return APSIntType(Ctx.getTypeSize(T),
+                      !T->isSignedIntegerOrEnumerationType());
+  }
+
+  /// Convert - Create a new persistent APSInt with the same value as 'From'
+  ///  but with the bitwidth and signedness of 'To'.
+  const llvm::APSInt &Convert(const llvm::APSInt& To,
+                              const llvm::APSInt& From) {
+    APSIntType TargetType(To);
+    if (TargetType == APSIntType(From))
+      return From;
+
+    return getValue(TargetType.convert(From));
+  }
+  
+  const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+    APSIntType TargetType = getAPSIntType(T);
+    if (TargetType == APSIntType(From))
+      return From;
+    
+    return getValue(TargetType.convert(From));
+  }
+
+  const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
+    QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
+    return getValue(X, T);
+  }
+
+  inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) {
+    return getValue(APSIntType(v).getMaxValue());
+  }
+
+  inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) {
+    return getValue(APSIntType(v).getMinValue());
+  }
+
+  inline const llvm::APSInt& getMaxValue(QualType T) {
+    return getValue(getAPSIntType(T).getMaxValue());
+  }
+
+  inline const llvm::APSInt& getMinValue(QualType T) {
+    return getValue(getAPSIntType(T).getMinValue());
+  }
+
+  inline const llvm::APSInt& Add1(const llvm::APSInt& V) {
+    llvm::APSInt X = V;
+    ++X;
+    return getValue(X);
+  }
+
+  inline const llvm::APSInt& Sub1(const llvm::APSInt& V) {
+    llvm::APSInt X = V;
+    --X;
+    return getValue(X);
+  }
+
+  inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) {
+    return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+  }
+
+  inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
+    return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+  }
+
+  inline const llvm::APSInt& getTruthValue(bool b, QualType T) {
+    return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false);
+  }
+
+  inline const llvm::APSInt& getTruthValue(bool b) {
+    return getTruthValue(b, Ctx.getLogicalOperationType());
+  }
+
+  const CompoundValData *getCompoundValData(QualType T,
+                                            llvm::ImmutableList<SVal> Vals);
+
+  const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store,
+                                            const TypedValueRegion *region);
+
+  llvm::ImmutableList<SVal> getEmptySValList() {
+    return SValListFactory.getEmptyList();
+  }
+
+  llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
+    return SValListFactory.add(X, L);
+  }
+
+  const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
+                                     const llvm::APSInt& V1,
+                                     const llvm::APSInt& V2);
+
+  const std::pair<SVal, uintptr_t>&
+  getPersistentSValWithData(const SVal& V, uintptr_t Data);
+
+  const std::pair<SVal, SVal>&
+  getPersistentSValPair(const SVal& V1, const SVal& V2);
+
+  const SVal* getPersistentSVal(SVal X);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
new file mode 100644
index 0000000..0408070
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -0,0 +1,60 @@
+//==- BlockCounter.h - ADT for counting block visits ---------------*- 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 BlockCounter, an abstract data type used to count
+//  the number of times a given block has been visited along a path
+//  analyzed by CoreEngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_BLOCKCOUNTER
+#define LLVM_CLANG_GR_BLOCKCOUNTER
+
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+class StackFrameContext;
+
+namespace ento {
+
+/// \class BlockCounter
+/// \brief An abstract data type used to count the number of times a given
+/// block has been visited along a path analyzed by CoreEngine.
+class BlockCounter {
+  void *Data;
+
+  BlockCounter(void *D) : Data(D) {}
+
+public:
+  BlockCounter() : Data(nullptr) {}
+
+  unsigned getNumVisited(const StackFrameContext *CallSite, 
+                         unsigned BlockID) const;
+
+  class Factory {
+    void *F;
+  public:
+    Factory(llvm::BumpPtrAllocator& Alloc);
+    ~Factory();
+
+    BlockCounter GetEmptyCounter();
+    BlockCounter IncrementCount(BlockCounter BC, 
+                                  const StackFrameContext *CallSite,
+                                  unsigned BlockID);
+  };
+
+  friend class Factory;
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
new file mode 100644
index 0000000..4a5426b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -0,0 +1,1032 @@
+//===- CallEvent.h - Wrapper for all function and method calls ----*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file defines CallEvent and its subclasses, which represent path-
+/// sensitive instances of different kinds of function and method calls
+/// (C, C++, and Objective-C).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
+#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+class ProgramPoint;
+class ProgramPointTag;
+
+namespace ento {
+
+enum CallEventKind {
+  CE_Function,
+  CE_CXXMember,
+  CE_CXXMemberOperator,
+  CE_CXXDestructor,
+  CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
+  CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor,
+  CE_CXXConstructor,
+  CE_CXXAllocator,
+  CE_BEG_FUNCTION_CALLS = CE_Function,
+  CE_END_FUNCTION_CALLS = CE_CXXAllocator,
+  CE_Block,
+  CE_ObjCMessage
+};
+
+class CallEvent;
+class CallEventManager;
+
+template<typename T = CallEvent>
+class CallEventRef : public IntrusiveRefCntPtr<const T> {
+public:
+  CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {}
+  CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
+
+  CallEventRef<T> cloneWithState(ProgramStateRef State) const {
+    return this->get()->template cloneWithState<T>(State);
+  }
+
+  // Allow implicit conversions to a superclass type, since CallEventRef
+  // behaves like a pointer-to-const.
+  template <typename SuperT>
+  operator CallEventRef<SuperT> () const {
+    return this->get();
+  }
+};
+
+/// \class RuntimeDefinition 
+/// \brief Defines the runtime definition of the called function.
+/// 
+/// Encapsulates the information we have about which Decl will be used 
+/// when the call is executed on the given path. When dealing with dynamic
+/// dispatch, the information is based on DynamicTypeInfo and might not be 
+/// precise.
+class RuntimeDefinition {
+  /// The Declaration of the function which could be called at runtime.
+  /// NULL if not available.
+  const Decl *D;
+
+  /// The region representing an object (ObjC/C++) on which the method is
+  /// called. With dynamic dispatch, the method definition depends on the
+  /// runtime type of this object. NULL when the DynamicTypeInfo is
+  /// precise.
+  const MemRegion *R;
+
+public:
+  RuntimeDefinition(): D(nullptr), R(nullptr) {}
+  RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
+  RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
+  const Decl *getDecl() { return D; }
+    
+  /// \brief Check if the definition we have is precise. 
+  /// If not, it is possible that the call dispatches to another definition at 
+  /// execution time.
+  bool mayHaveOtherDefinitions() { return R != nullptr; }
+  
+  /// When other definitions are possible, returns the region whose runtime type 
+  /// determines the method definition.
+  const MemRegion *getDispatchRegion() { return R; }
+};
+
+/// \brief Represents an abstract call to a function or method along a
+/// particular path.
+///
+/// CallEvents are created through the factory methods of CallEventManager.
+///
+/// CallEvents should always be cheap to create and destroy. In order for
+/// CallEventManager to be able to re-use CallEvent-sized memory blocks,
+/// subclasses of CallEvent may not add any data members to the base class.
+/// Use the "Data" and "Location" fields instead.
+class CallEvent {
+public:
+  typedef CallEventKind Kind;
+
+private:
+  ProgramStateRef State;
+  const LocationContext *LCtx;
+  llvm::PointerUnion<const Expr *, const Decl *> Origin;
+
+  void operator=(const CallEvent &) LLVM_DELETED_FUNCTION;
+
+protected:
+  // This is user data for subclasses.
+  const void *Data;
+
+  // This is user data for subclasses.
+  // This should come right before RefCount, so that the two fields can be
+  // packed together on LP64 platforms.
+  SourceLocation Location;
+
+private:
+  mutable unsigned RefCount;
+
+  template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
+  void Retain() const { ++RefCount; }
+  void Release() const;
+
+protected:
+  friend class CallEventManager;
+
+  CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
+    : State(state), LCtx(lctx), Origin(E), RefCount(0) {}
+
+  CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
+    : State(state), LCtx(lctx), Origin(D), RefCount(0) {}
+
+  // DO NOT MAKE PUBLIC
+  CallEvent(const CallEvent &Original)
+    : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
+      Data(Original.Data), Location(Original.Location), RefCount(0) {}
+
+  /// Copies this CallEvent, with vtable intact, into a new block of memory.
+  virtual void cloneTo(void *Dest) const = 0;
+
+  /// \brief Get the value of arbitrary expressions at this point in the path.
+  SVal getSVal(const Stmt *S) const {
+    return getState()->getSVal(S, getLocationContext());
+  }
+
+
+  typedef SmallVectorImpl<SVal> ValueList;
+
+  /// \brief Used to specify non-argument regions that will be invalidated as a
+  /// result of this call.
+  virtual void getExtraInvalidatedValues(ValueList &Values) const {}
+
+public:
+  virtual ~CallEvent() {}
+
+  /// \brief Returns the kind of call this is.
+  virtual Kind getKind() const = 0;
+
+  /// \brief Returns the declaration of the function or method that will be
+  /// called. May be null.
+  virtual const Decl *getDecl() const {
+    return Origin.dyn_cast<const Decl *>();
+  }
+
+  /// \brief The state in which the call is being evaluated.
+  const ProgramStateRef &getState() const {
+    return State;
+  }
+
+  /// \brief The context in which the call is being evaluated.
+  const LocationContext *getLocationContext() const {
+    return LCtx;
+  }
+
+  /// \brief Returns the definition of the function or method that will be
+  /// called.
+  virtual RuntimeDefinition getRuntimeDefinition() const = 0;
+
+  /// \brief Returns the expression whose value will be the result of this call.
+  /// May be null.
+  const Expr *getOriginExpr() const {
+    return Origin.dyn_cast<const Expr *>();
+  }
+
+  /// \brief Returns the number of arguments (explicit and implicit).
+  ///
+  /// Note that this may be greater than the number of parameters in the
+  /// callee's declaration, and that it may include arguments not written in
+  /// the source.
+  virtual unsigned getNumArgs() const = 0;
+
+  /// \brief Returns true if the callee is known to be from a system header.
+  bool isInSystemHeader() const {
+    const Decl *D = getDecl();
+    if (!D)
+      return false;
+
+    SourceLocation Loc = D->getLocation();
+    if (Loc.isValid()) {
+      const SourceManager &SM =
+        getState()->getStateManager().getContext().getSourceManager();
+      return SM.isInSystemHeader(D->getLocation());
+    }
+
+    // Special case for implicitly-declared global operator new/delete.
+    // These should be considered system functions.
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
+
+    return false;
+  }
+
+  /// \brief Returns a source range for the entire call, suitable for
+  /// outputting in diagnostics.
+  virtual SourceRange getSourceRange() const {
+    return getOriginExpr()->getSourceRange();
+  }
+
+  /// \brief Returns the value of a given argument at the time of the call.
+  virtual SVal getArgSVal(unsigned Index) const;
+
+  /// \brief Returns the expression associated with a given argument.
+  /// May be null if this expression does not appear in the source.
+  virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; }
+
+  /// \brief Returns the source range for errors associated with this argument.
+  ///
+  /// May be invalid if the argument is not written in the source.
+  virtual SourceRange getArgSourceRange(unsigned Index) const;
+
+  /// \brief Returns the result type, adjusted for references.
+  QualType getResultType() const;
+
+  /// \brief Returns the return value of the call.
+  ///
+  /// This should only be called if the CallEvent was created using a state in
+  /// which the return value has already been bound to the origin expression.
+  SVal getReturnValue() const;
+
+  /// \brief Returns true if any of the arguments appear to represent callbacks.
+  bool hasNonZeroCallbackArg() const;
+
+  /// \brief Returns true if any of the arguments are known to escape to long-
+  /// term storage, even if this method will not modify them.
+  // NOTE: The exact semantics of this are still being defined!
+  // We don't really want a list of hardcoded exceptions in the long run,
+  // but we don't want duplicated lists of known APIs in the short term either.
+  virtual bool argumentsMayEscape() const {
+    return hasNonZeroCallbackArg();
+  }
+
+  /// \brief Returns true if the callee is an externally-visible function in the
+  /// top-level namespace, such as \c malloc.
+  ///
+  /// You can use this call to determine that a particular function really is
+  /// a library function and not, say, a C++ member function with the same name.
+  ///
+  /// If a name is provided, the function must additionally match the given
+  /// name.
+  ///
+  /// Note that this deliberately excludes C++ library functions in the \c std
+  /// namespace, but will include C library functions accessed through the
+  /// \c std namespace. This also does not check if the function is declared
+  /// as 'extern "C"', or if it uses C++ name mangling.
+  // FIXME: Add a helper for checking namespaces.
+  // FIXME: Move this down to AnyFunctionCall once checkers have more
+  // precise callbacks.
+  bool isGlobalCFunction(StringRef SpecificName = StringRef()) const;
+
+  /// \brief Returns the name of the callee, if its name is a simple identifier.
+  ///
+  /// Note that this will fail for Objective-C methods, blocks, and C++
+  /// overloaded operators. The former is named by a Selector rather than a
+  /// simple identifier, and the latter two do not have names.
+  // FIXME: Move this down to AnyFunctionCall once checkers have more
+  // precise callbacks.
+  const IdentifierInfo *getCalleeIdentifier() const {
+    const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
+    if (!ND)
+      return nullptr;
+    return ND->getIdentifier();
+  }
+
+  /// \brief Returns an appropriate ProgramPoint for this call.
+  ProgramPoint getProgramPoint(bool IsPreVisit = false,
+                               const ProgramPointTag *Tag = nullptr) const;
+
+  /// \brief Returns a new state with all argument regions invalidated.
+  ///
+  /// This accepts an alternate state in case some processing has already
+  /// occurred.
+  ProgramStateRef invalidateRegions(unsigned BlockCount,
+                                    ProgramStateRef Orig = nullptr) const;
+
+  typedef std::pair<Loc, SVal> FrameBindingTy;
+  typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
+
+  /// Populates the given SmallVector with the bindings in the callee's stack
+  /// frame at the start of this call.
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const = 0;
+
+  /// Returns a copy of this CallEvent, but using the given state.
+  template <typename T>
+  CallEventRef<T> cloneWithState(ProgramStateRef NewState) const;
+
+  /// Returns a copy of this CallEvent, but using the given state.
+  CallEventRef<> cloneWithState(ProgramStateRef NewState) const {
+    return cloneWithState<CallEvent>(NewState);
+  }
+
+  /// \brief Returns true if this is a statement is a function or method call
+  /// of some kind.
+  static bool isCallStmt(const Stmt *S);
+
+  /// \brief Returns the result type of a function or method declaration.
+  ///
+  /// This will return a null QualType if the result type cannot be determined.
+  static QualType getDeclaredResultType(const Decl *D);
+
+  /// \brief Returns true if the given decl is known to be variadic.
+  ///
+  /// \p D must not be null.
+  static bool isVariadic(const Decl *D);
+
+  // Iterator access to formal parameters and their types.
+private:
+  typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
+
+public:
+  /// Return call's formal parameters.
+  ///
+  /// Remember that the number of formal parameters may not match the number
+  /// of arguments for all calls. However, the first parameter will always
+  /// correspond with the argument value returned by \c getArgSVal(0).
+  virtual ArrayRef<ParmVarDecl*> parameters() const = 0;
+
+  typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, get_type_fun>
+    param_type_iterator;
+
+  /// Returns an iterator over the types of the call's formal parameters.
+  ///
+  /// This uses the callee decl found by default name lookup rather than the
+  /// definition because it represents a public interface, and probably has
+  /// more annotations.
+  param_type_iterator param_type_begin() const {
+    return llvm::map_iterator(parameters().begin(),
+                              get_type_fun(&ParmVarDecl::getType));
+  }
+  /// \sa param_type_begin()
+  param_type_iterator param_type_end() const {
+    return llvm::map_iterator(parameters().end(),
+                              get_type_fun(&ParmVarDecl::getType));
+  }
+
+  // For debugging purposes only
+  void dump(raw_ostream &Out) const;
+  void dump() const;
+};
+
+
+/// \brief Represents a call to any sort of function that might have a
+/// FunctionDecl.
+class AnyFunctionCall : public CallEvent {
+protected:
+  AnyFunctionCall(const Expr *E, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : CallEvent(E, St, LCtx) {}
+  AnyFunctionCall(const Decl *D, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : CallEvent(D, St, LCtx) {}
+  AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {}
+
+public:
+  // This function is overridden by subclasses, but they must return
+  // a FunctionDecl.
+  const FunctionDecl *getDecl() const override {
+    return cast<FunctionDecl>(CallEvent::getDecl());
+  }
+
+  RuntimeDefinition getRuntimeDefinition() const override {
+    const FunctionDecl *FD = getDecl();
+    // Note that the AnalysisDeclContext will have the FunctionDecl with
+    // the definition (if one exists).
+    if (FD) {
+      AnalysisDeclContext *AD =
+        getLocationContext()->getAnalysisDeclContext()->
+        getManager()->getContext(FD);
+      if (AD->getBody())
+        return RuntimeDefinition(AD->getDecl());
+    }
+
+    return RuntimeDefinition();
+  }
+
+  bool argumentsMayEscape() const override;
+
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
+
+  ArrayRef<ParmVarDecl *> parameters() const override;
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
+           CA->getKind() <= CE_END_FUNCTION_CALLS;
+  }
+};
+
+/// \brief Represents a C function or static C++ member function call.
+///
+/// Example: \c fun()
+class SimpleFunctionCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
+                     const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {}
+  SimpleFunctionCall(const SimpleFunctionCall &Other)
+    : AnyFunctionCall(Other) {}
+  void cloneTo(void *Dest) const override {
+    new (Dest) SimpleFunctionCall(*this);
+  }
+
+public:
+  virtual const CallExpr *getOriginExpr() const {
+    return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  const FunctionDecl *getDecl() const override;
+
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  Kind getKind() const override { return CE_Function; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_Function;
+  }
+};
+
+/// \brief Represents a call to a block.
+///
+/// Example: <tt>^{ /* ... */ }()</tt>
+class BlockCall : public CallEvent {
+  friend class CallEventManager;
+
+protected:
+  BlockCall(const CallExpr *CE, ProgramStateRef St,
+            const LocationContext *LCtx)
+    : CallEvent(CE, St, LCtx) {}
+
+  BlockCall(const BlockCall &Other) : CallEvent(Other) {}
+  void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
+
+  void getExtraInvalidatedValues(ValueList &Values) const override;
+
+public:
+  virtual const CallExpr *getOriginExpr() const {
+    return cast<CallExpr>(CallEvent::getOriginExpr());
+  }
+
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  /// \brief Returns the region associated with this instance of the block.
+  ///
+  /// This may be NULL if the block's origin is unknown.
+  const BlockDataRegion *getBlockRegion() const;
+
+  const BlockDecl *getDecl() const override {
+    const BlockDataRegion *BR = getBlockRegion();
+    if (!BR)
+      return nullptr;
+    return BR->getDecl();
+  }
+
+  RuntimeDefinition getRuntimeDefinition() const override {
+    return RuntimeDefinition(getDecl());
+  }
+
+  bool argumentsMayEscape() const override {
+    return true;
+  }
+
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
+
+  ArrayRef<ParmVarDecl*> parameters() const override;
+
+  Kind getKind() const override { return CE_Block; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_Block;
+  }
+};
+
+/// \brief Represents a non-static C++ member function call, no matter how
+/// it is written.
+class CXXInstanceCall : public AnyFunctionCall {
+protected:
+  void getExtraInvalidatedValues(ValueList &Values) const override;
+
+  CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {}
+  CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(D, St, LCtx) {}
+
+
+  CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
+
+public:
+  /// \brief Returns the expression representing the implicit 'this' object.
+  virtual const Expr *getCXXThisExpr() const { return nullptr; }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  virtual SVal getCXXThisVal() const;
+
+  const FunctionDecl *getDecl() const override;
+
+  RuntimeDefinition getRuntimeDefinition() const override;
+
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
+           CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
+  }
+};
+
+/// \brief Represents a non-static C++ member function call.
+///
+/// Example: \c obj.fun()
+class CXXMemberCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
+                const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
+  void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
+
+public:
+  virtual const CXXMemberCallExpr *getOriginExpr() const {
+    return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  unsigned getNumArgs() const override {
+    if (const CallExpr *CE = getOriginExpr())
+      return CE->getNumArgs();
+    return 0;
+  }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  const Expr *getCXXThisExpr() const override;
+
+  RuntimeDefinition getRuntimeDefinition() const override;
+
+  Kind getKind() const override { return CE_CXXMember; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMember;
+  }
+};
+
+/// \brief Represents a C++ overloaded operator call where the operator is
+/// implemented as a non-static member function.
+///
+/// Example: <tt>iter + 1</tt>
+class CXXMemberOperatorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
+                        const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
+    : CXXInstanceCall(Other) {}
+  void cloneTo(void *Dest) const override {
+    new (Dest) CXXMemberOperatorCall(*this);
+  }
+
+public:
+  virtual const CXXOperatorCallExpr *getOriginExpr() const {
+    return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  unsigned getNumArgs() const override {
+    return getOriginExpr()->getNumArgs() - 1;
+  }
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index + 1);
+  }
+
+  const Expr *getCXXThisExpr() const override;
+
+  Kind getKind() const override { return CE_CXXMemberOperator; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMemberOperator;
+  }
+};
+
+/// \brief Represents an implicit call to a C++ destructor.
+///
+/// This can occur at the end of a scope (for automatic objects), at the end
+/// of a full-expression (for temporaries), or as part of a delete.
+class CXXDestructorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  typedef llvm::PointerIntPair<const MemRegion *, 1, bool> DtorDataTy;
+
+  /// Creates an implicit destructor.
+  ///
+  /// \param DD The destructor that will be called.
+  /// \param Trigger The statement whose completion causes this destructor call.
+  /// \param Target The object region to be destructed.
+  /// \param St The path-sensitive state at this point in the program.
+  /// \param LCtx The location context at this point in the program.
+  CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
+                    const MemRegion *Target, bool IsBaseDestructor,
+                    ProgramStateRef St, const LocationContext *LCtx)
+    : CXXInstanceCall(DD, St, LCtx) {
+    Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
+    Location = Trigger->getLocEnd();
+  }
+
+  CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
+  void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
+
+public:
+  SourceRange getSourceRange() const override { return Location; }
+  unsigned getNumArgs() const override { return 0; }
+
+  RuntimeDefinition getRuntimeDefinition() const override;
+
+  /// \brief Returns the value of the implicit 'this' object.
+  SVal getCXXThisVal() const override;
+
+  /// Returns true if this is a call to a base class destructor.
+  bool isBaseDestructor() const {
+    return DtorDataTy::getFromOpaqueValue(Data).getInt();
+  }
+
+  Kind getKind() const override { return CE_CXXDestructor; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXDestructor;
+  }
+};
+
+/// \brief Represents a call to a C++ constructor.
+///
+/// Example: \c T(1)
+class CXXConstructorCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  /// Creates a constructor call.
+  ///
+  /// \param CE The constructor expression as written in the source.
+  /// \param Target The region where the object should be constructed. If NULL,
+  ///               a new symbolic region will be used.
+  /// \param St The path-sensitive state at this point in the program.
+  /// \param LCtx The location context at this point in the program.
+  CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target,
+                     ProgramStateRef St, const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {
+    Data = Target;
+  }
+
+  CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
+  void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
+
+  void getExtraInvalidatedValues(ValueList &Values) const override;
+
+public:
+  virtual const CXXConstructExpr *getOriginExpr() const {
+    return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  const CXXConstructorDecl *getDecl() const override {
+    return getOriginExpr()->getConstructor();
+  }
+
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  SVal getCXXThisVal() const;
+
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
+
+  Kind getKind() const override { return CE_CXXConstructor; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXConstructor;
+  }
+};
+
+/// \brief Represents the memory allocation call in a C++ new-expression.
+///
+/// This is a call to "operator new".
+class CXXAllocatorCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
+                   const LocationContext *LCtx)
+    : AnyFunctionCall(E, St, LCtx) {}
+
+  CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
+  void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
+
+public:
+  virtual const CXXNewExpr *getOriginExpr() const {
+    return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  const FunctionDecl *getDecl() const override {
+    return getOriginExpr()->getOperatorNew();
+  }
+
+  unsigned getNumArgs() const override {
+    return getOriginExpr()->getNumPlacementArgs() + 1;
+  }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    // The first argument of an allocator call is the size of the allocation.
+    if (Index == 0)
+      return nullptr;
+    return getOriginExpr()->getPlacementArg(Index - 1);
+  }
+
+  Kind getKind() const override { return CE_CXXAllocator; }
+
+  static bool classof(const CallEvent *CE) {
+    return CE->getKind() == CE_CXXAllocator;
+  }
+};
+
+/// \brief Represents the ways an Objective-C message send can occur.
+//
+// Note to maintainers: OCM_Message should always be last, since it does not
+// need to fit in the Data field's low bits.
+enum ObjCMessageKind {
+  OCM_PropertyAccess,
+  OCM_Subscript,
+  OCM_Message
+};
+
+/// \brief Represents any expression that calls an Objective-C method.
+///
+/// This includes all of the kinds listed in ObjCMessageKind.
+class ObjCMethodCall : public CallEvent {
+  friend class CallEventManager;
+
+  const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
+
+protected:
+  ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
+                 const LocationContext *LCtx)
+    : CallEvent(Msg, St, LCtx) {
+    Data = nullptr;
+  }
+
+  ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
+  void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
+
+  void getExtraInvalidatedValues(ValueList &Values) const override;
+
+  /// Check if the selector may have multiple definitions (may have overrides).
+  virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
+                                        Selector Sel) const;
+
+public:
+  virtual const ObjCMessageExpr *getOriginExpr() const {
+    return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
+  }
+  const ObjCMethodDecl *getDecl() const override {
+    return getOriginExpr()->getMethodDecl();
+  }
+  unsigned getNumArgs() const override {
+    return getOriginExpr()->getNumArgs();
+  }
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  bool isInstanceMessage() const {
+    return getOriginExpr()->isInstanceMessage();
+  }
+  ObjCMethodFamily getMethodFamily() const {
+    return getOriginExpr()->getMethodFamily();
+  }
+  Selector getSelector() const {
+    return getOriginExpr()->getSelector();
+  }
+
+  SourceRange getSourceRange() const override;
+
+  /// \brief Returns the value of the receiver at the time of this call.
+  SVal getReceiverSVal() const;
+
+  /// \brief Return the value of 'self' if available.
+  SVal getSelfSVal() const;
+
+  /// \brief Get the interface for the receiver.
+  ///
+  /// This works whether this is an instance message or a class message.
+  /// However, it currently just uses the static type of the receiver.
+  const ObjCInterfaceDecl *getReceiverInterface() const {
+    return getOriginExpr()->getReceiverInterface();
+  }
+
+  /// \brief Checks if the receiver refers to 'self' or 'super'.
+  bool isReceiverSelfOrSuper() const;
+
+  /// Returns how the message was written in the source (property access,
+  /// subscript, or explicit message send).
+  ObjCMessageKind getMessageKind() const;
+
+  /// Returns true if this property access or subscript is a setter (has the
+  /// form of an assignment).
+  bool isSetter() const {
+    switch (getMessageKind()) {
+    case OCM_Message:
+      llvm_unreachable("This is not a pseudo-object access!");
+    case OCM_PropertyAccess:
+      return getNumArgs() > 0;
+    case OCM_Subscript:
+      return getNumArgs() > 1;
+    }
+    llvm_unreachable("Unknown message kind");
+  }
+
+  RuntimeDefinition getRuntimeDefinition() const override;
+
+  bool argumentsMayEscape() const override;
+
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
+
+  ArrayRef<ParmVarDecl*> parameters() const override;
+
+  Kind getKind() const override { return CE_ObjCMessage; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_ObjCMessage;
+  }
+};
+
+
+/// \brief Manages the lifetime of CallEvent objects.
+///
+/// CallEventManager provides a way to create arbitrary CallEvents "on the
+/// stack" as if they were value objects by keeping a cache of CallEvent-sized
+/// memory blocks. The CallEvents created by CallEventManager are only valid
+/// for the lifetime of the OwnedCallEvent that holds them; right now these
+/// objects cannot be copied and ownership cannot be transferred.
+class CallEventManager {
+  friend class CallEvent;
+
+  llvm::BumpPtrAllocator &Alloc;
+  SmallVector<void *, 8> Cache;
+  typedef SimpleFunctionCall CallEventTemplateTy;
+
+  void reclaim(const void *Memory) {
+    Cache.push_back(const_cast<void *>(Memory));
+  }
+
+  /// Returns memory that can be initialized as a CallEvent.
+  void *allocate() {
+    if (Cache.empty())
+      return Alloc.Allocate<CallEventTemplateTy>();
+    else
+      return Cache.pop_back_val();
+  }
+
+  template <typename T, typename Arg>
+  T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
+    return new (allocate()) T(A, St, LCtx);
+  }
+
+  template <typename T, typename Arg1, typename Arg2>
+  T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
+    return new (allocate()) T(A1, A2, St, LCtx);
+  }
+
+  template <typename T, typename Arg1, typename Arg2, typename Arg3>
+  T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
+            const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
+    return new (allocate()) T(A1, A2, A3, St, LCtx);
+  }
+
+  template <typename T, typename Arg1, typename Arg2, typename Arg3,
+            typename Arg4>
+  T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
+            const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
+    return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
+  }
+
+public:
+  CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
+
+
+  CallEventRef<>
+  getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
+
+
+  CallEventRef<>
+  getSimpleCall(const CallExpr *E, ProgramStateRef State,
+                const LocationContext *LCtx);
+
+  CallEventRef<ObjCMethodCall>
+  getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State,
+                    const LocationContext *LCtx) {
+    return create<ObjCMethodCall>(E, State, LCtx);
+  }
+
+  CallEventRef<CXXConstructorCall>
+  getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target,
+                        ProgramStateRef State, const LocationContext *LCtx) {
+    return create<CXXConstructorCall>(E, Target, State, LCtx);
+  }
+
+  CallEventRef<CXXDestructorCall>
+  getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
+                       const MemRegion *Target, bool IsBase,
+                       ProgramStateRef State, const LocationContext *LCtx) {
+    return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx);
+  }
+
+  CallEventRef<CXXAllocatorCall>
+  getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State,
+                      const LocationContext *LCtx) {
+    return create<CXXAllocatorCall>(E, State, LCtx);
+  }
+};
+
+
+template <typename T>
+CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
+  assert(isa<T>(*this) && "Cloning to unrelated type");
+  static_assert(sizeof(T) == sizeof(CallEvent),
+                "Subclasses may not add fields");
+
+  if (NewState == State)
+    return cast<T>(this);
+
+  CallEventManager &Mgr = State->getStateManager().getCallEventManager();
+  T *Copy = static_cast<T *>(Mgr.allocate());
+  cloneTo(Copy);
+  assert(Copy->getKind() == this->getKind() && "Bad copy");
+
+  Copy->State = NewState;
+  return Copy;
+}
+
+inline void CallEvent::Release() const {
+  assert(RefCount > 0 && "Reference count is already zero.");
+  --RefCount;
+
+  if (RefCount > 0)
+    return;
+
+  CallEventManager &Mgr = State->getStateManager().getCallEventManager();
+  Mgr.reclaim(this);
+
+  this->~CallEvent();
+}
+
+} // end namespace ento
+} // end namespace clang
+
+namespace llvm {
+  // Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
+  template<class T> struct simplify_type< clang::ento::CallEventRef<T> > {
+    typedef const T *SimpleType;
+
+    static SimpleType
+    getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
+      return Val.get();
+    }
+  };
+}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
new file mode 100644
index 0000000..5a33bdf
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -0,0 +1,311 @@
+//== CheckerContext.h - Context info for path-sensitive checkers--*- 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 CheckerContext that provides contextual info for
+// path-sensitive checkers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
+#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+
+namespace clang {
+namespace ento {
+
+  /// Declares an immutable map of type \p NameTy, suitable for placement into
+  /// the ProgramState. This is implementing using llvm::ImmutableMap.
+  ///
+  /// \code
+  /// State = State->set<Name>(K, V);
+  /// const Value *V = State->get<Name>(K); // Returns NULL if not in the map.
+  /// State = State->remove<Name>(K);
+  /// NameTy Map = State->get<Name>();
+  /// \endcode
+  ///
+  /// The macro should not be used inside namespaces, or for traits that must
+  /// be accessible from more than one translation unit.
+  #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \
+    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \
+                                     CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value))
+
+  /// Declares an immutable set of type \p NameTy, suitable for placement into
+  /// the ProgramState. This is implementing using llvm::ImmutableSet.
+  ///
+  /// \code
+  /// State = State->add<Name>(E);
+  /// State = State->remove<Name>(E);
+  /// bool Present = State->contains<Name>(E);
+  /// NameTy Set = State->get<Name>();
+  /// \endcode
+  ///
+  /// The macro should not be used inside namespaces, or for traits that must
+  /// be accessible from more than one translation unit.
+  #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \
+    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>)
+  
+  /// Declares an immutable list of type \p NameTy, suitable for placement into
+  /// the ProgramState. This is implementing using llvm::ImmutableList.
+  ///
+  /// \code
+  /// State = State->add<Name>(E); // Adds to the /end/ of the list.
+  /// bool Present = State->contains<Name>(E);
+  /// NameTy List = State->get<Name>();
+  /// \endcode
+  ///
+  /// The macro should not be used inside namespaces, or for traits that must
+  /// be accessible from more than one translation unit.
+  #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \
+    REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList<Elem>)
+
+
+class CheckerContext {
+  ExprEngine &Eng;
+  /// The current exploded(symbolic execution) graph node.
+  ExplodedNode *Pred;
+  /// The flag is true if the (state of the execution) has been modified
+  /// by the checker using this context. For example, a new transition has been
+  /// added or a bug report issued.
+  bool Changed;
+  /// The tagged location, which is used to generate all new nodes.
+  const ProgramPoint Location;
+  NodeBuilder &NB;
+
+public:
+  /// If we are post visiting a call, this flag will be set if the
+  /// call was inlined.  In all other cases it will be false.
+  const bool wasInlined;
+  
+  CheckerContext(NodeBuilder &builder,
+                 ExprEngine &eng,
+                 ExplodedNode *pred,
+                 const ProgramPoint &loc,
+                 bool wasInlined = false)
+    : Eng(eng),
+      Pred(pred),
+      Changed(false),
+      Location(loc),
+      NB(builder),
+      wasInlined(wasInlined) {
+    assert(Pred->getState() &&
+           "We should not call the checkers on an empty state.");
+  }
+
+  AnalysisManager &getAnalysisManager() {
+    return Eng.getAnalysisManager();
+  }
+
+  ConstraintManager &getConstraintManager() {
+    return Eng.getConstraintManager();
+  }
+
+  StoreManager &getStoreManager() {
+    return Eng.getStoreManager();
+  }
+  
+  /// \brief Returns the previous node in the exploded graph, which includes
+  /// the state of the program before the checker ran. Note, checkers should
+  /// not retain the node in their state since the nodes might get invalidated.
+  ExplodedNode *getPredecessor() { return Pred; }
+  const ProgramStateRef &getState() const { return Pred->getState(); }
+
+  /// \brief Check if the checker changed the state of the execution; ex: added
+  /// a new transition or a bug report.
+  bool isDifferent() { return Changed; }
+
+  /// \brief Returns the number of times the current block has been visited
+  /// along the analyzed path.
+  unsigned blockCount() const {
+    return NB.getContext().blockCount();
+  }
+
+  ASTContext &getASTContext() {
+    return Eng.getContext();
+  }
+
+  const LangOptions &getLangOpts() const {
+    return Eng.getContext().getLangOpts();
+  }
+
+  const LocationContext *getLocationContext() const {
+    return Pred->getLocationContext();
+  }
+
+  const StackFrameContext *getStackFrame() const {
+    return Pred->getStackFrame();
+  }
+
+  /// Return true if the current LocationContext has no caller context.
+  bool inTopFrame() const { return getLocationContext()->inTopFrame();  }
+
+  BugReporter &getBugReporter() {
+    return Eng.getBugReporter();
+  }
+  
+  SourceManager &getSourceManager() {
+    return getBugReporter().getSourceManager();
+  }
+
+  SValBuilder &getSValBuilder() {
+    return Eng.getSValBuilder();
+  }
+
+  SymbolManager &getSymbolManager() {
+    return getSValBuilder().getSymbolManager();
+  }
+
+  bool isObjCGCEnabled() const {
+    return Eng.isObjCGCEnabled();
+  }
+
+  ProgramStateManager &getStateManager() {
+    return Eng.getStateManager();
+  }
+
+  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
+    return Pred->getLocationContext()->getAnalysisDeclContext();
+  }
+
+  /// \brief Get the blockID.
+  unsigned getBlockID() const {
+    return NB.getContext().getBlock()->getBlockID();
+  }
+
+  /// \brief If the given node corresponds to a PostStore program point,
+  /// retrieve the location region as it was uttered in the code.
+  ///
+  /// This utility can be useful for generating extensive diagnostics, for
+  /// example, for finding variables that the given symbol was assigned to.
+  static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
+    ProgramPoint L = N->getLocation();
+    if (Optional<PostStore> PSL = L.getAs<PostStore>())
+      return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
+    return nullptr;
+  }
+
+  /// \brief Get the value of arbitrary expressions at this point in the path.
+  SVal getSVal(const Stmt *S) const {
+    return getState()->getSVal(S, getLocationContext());
+  }
+
+  /// \brief Generates a new transition in the program state graph
+  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
+  ///
+  /// @param State The state of the generated node. If not specified, the state
+  ///        will not be changed, but the new node will have the checker's tag.
+  /// @param Tag The tag is used to uniquely identify the creation site. If no
+  ///        tag is specified, a default tag, unique to the given checker,
+  ///        will be used. Tags are used to prevent states generated at
+  ///        different sites from caching out.
+  ExplodedNode *addTransition(ProgramStateRef State = nullptr,
+                              const ProgramPointTag *Tag = nullptr) {
+    return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
+  }
+
+  /// \brief Generates a new transition with the given predecessor.
+  /// Allows checkers to generate a chain of nodes.
+  ///
+  /// @param State The state of the generated node.
+  /// @param Pred The transition will be generated from the specified Pred node
+  ///             to the newly generated node.
+  /// @param Tag The tag to uniquely identify the creation site.
+  ExplodedNode *addTransition(ProgramStateRef State,
+                              ExplodedNode *Pred,
+                              const ProgramPointTag *Tag = nullptr) {
+    return addTransitionImpl(State, false, Pred, Tag);
+  }
+
+  /// \brief Generate a sink node. Generating a sink stops exploration of the
+  /// given path.
+  ExplodedNode *generateSink(ProgramStateRef State = nullptr,
+                             ExplodedNode *Pred = nullptr,
+                             const ProgramPointTag *Tag = nullptr) {
+    return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
+  }
+
+  /// \brief Emit the diagnostics report.
+  void emitReport(BugReport *R) {
+    Changed = true;
+    Eng.getBugReporter().emitReport(R);
+  }
+
+  /// \brief Get the declaration of the called function (path-sensitive).
+  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
+
+  /// \brief Get the name of the called function (path-sensitive).
+  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
+
+  /// \brief Get the identifier of the called function (path-sensitive).
+  const IdentifierInfo *getCalleeIdentifier(const CallExpr *CE) const {
+    const FunctionDecl *FunDecl = getCalleeDecl(CE);
+    if (FunDecl)
+      return FunDecl->getIdentifier();
+    else
+      return nullptr;
+  }
+
+  /// \brief Get the name of the called function (path-sensitive).
+  StringRef getCalleeName(const CallExpr *CE) const {
+    const FunctionDecl *FunDecl = getCalleeDecl(CE);
+    return getCalleeName(FunDecl);
+  }
+
+  /// \brief Returns true if the callee is an externally-visible function in the
+  /// top-level namespace, such as \c malloc.
+  ///
+  /// If a name is provided, the function must additionally match the given
+  /// name.
+  ///
+  /// Note that this deliberately excludes C++ library functions in the \c std
+  /// namespace, but will include C library functions accessed through the
+  /// \c std namespace. This also does not check if the function is declared
+  /// as 'extern "C"', or if it uses C++ name mangling.
+  static bool isCLibraryFunction(const FunctionDecl *FD,
+                                 StringRef Name = StringRef());
+
+  /// \brief Depending on wither the location corresponds to a macro, return 
+  /// either the macro name or the token spelling.
+  ///
+  /// This could be useful when checkers' logic depends on whether a function
+  /// is called with a given macro argument. For example:
+  ///   s = socket(AF_INET,..)
+  /// If AF_INET is a macro, the result should be treated as a source of taint.
+  ///
+  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
+  StringRef getMacroNameOrSpelling(SourceLocation &Loc);
+
+private:
+  ExplodedNode *addTransitionImpl(ProgramStateRef State,
+                                 bool MarkAsSink,
+                                 ExplodedNode *P = nullptr,
+                                 const ProgramPointTag *Tag = nullptr) {
+    if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
+      return Pred;
+
+    Changed = true;
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    if (!P)
+      P = Pred;
+
+    ExplodedNode *node;
+    if (MarkAsSink)
+      node = NB.generateSink(LocalLoc, State, P);
+    else
+      node = NB.generateNode(LocalLoc, State, P);
+    return node;
+  }
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
new file mode 100644
index 0000000..12547e0
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
@@ -0,0 +1,43 @@
+//== CheckerHelpers.h - Helper functions for checkers ------------*- 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 CheckerVisitor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_PATHSENSITIVE_CHECKERHELPERS
+#define LLVM_CLANG_GR_PATHSENSITIVE_CHECKERHELPERS
+
+#include "clang/AST/Stmt.h"
+
+namespace clang {
+
+namespace ento {
+
+bool containsMacro(const Stmt *S);
+bool containsEnum(const Stmt *S);
+bool containsStaticLocal(const Stmt *S);
+bool containsBuiltinOffsetOf(const Stmt *S);
+template <class T> bool containsStmt(const Stmt *S) {
+  if (isa<T>(S))
+      return true;
+
+  for (Stmt::const_child_range I = S->children(); I; ++I)
+    if (const Stmt *child = *I)
+      if (containsStmt<T>(child))
+        return true;
+
+  return false;
+}
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
new file mode 100644
index 0000000..51bb89b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -0,0 +1,158 @@
+//== ConstraintManager.h - Constraints on symbolic values.-------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the interface to manage constraints on symbolic values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
+#define LLVM_CLANG_GR_CONSTRAINT_MANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/Support/SaveAndRestore.h"
+
+namespace llvm {
+class APSInt;
+}
+
+namespace clang {
+namespace ento {
+
+class SubEngine;
+
+class ConditionTruthVal {
+  Optional<bool> Val;
+public:
+  /// Construct a ConditionTruthVal indicating the constraint is constrained
+  /// to either true or false, depending on the boolean value provided.
+  ConditionTruthVal(bool constraint) : Val(constraint) {}
+
+  /// Construct a ConstraintVal indicating the constraint is underconstrained.
+  ConditionTruthVal() {}
+  
+  /// Return true if the constraint is perfectly constrained to 'true'.
+  bool isConstrainedTrue() const {
+    return Val.hasValue() && Val.getValue();
+  }
+
+  /// Return true if the constraint is perfectly constrained to 'false'.
+  bool isConstrainedFalse() const {
+    return Val.hasValue() && !Val.getValue();
+  }
+
+  /// Return true if the constrained is perfectly constrained.
+  bool isConstrained() const {
+    return Val.hasValue();
+  }
+
+  /// Return true if the constrained is underconstrained and we do not know
+  /// if the constraint is true of value.
+  bool isUnderconstrained() const {
+    return !Val.hasValue();
+  }
+};
+  
+class ConstraintManager {
+public:
+  ConstraintManager() : NotifyAssumeClients(true) {}
+  
+  virtual ~ConstraintManager();
+  virtual ProgramStateRef assume(ProgramStateRef state,
+                                 DefinedSVal Cond,
+                                 bool Assumption) = 0;
+
+  typedef std::pair<ProgramStateRef, ProgramStateRef> ProgramStatePair;
+
+  /// Returns a pair of states (StTrue, StFalse) where the given condition is
+  /// assumed to be true or false, respectively.
+  ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond) {
+    ProgramStateRef StTrue = assume(State, Cond, true);
+
+    // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
+    // because the existing constraints already establish this.
+    if (!StTrue) {
+#ifndef __OPTIMIZE__
+      // This check is expensive and should be disabled even in Release+Asserts
+      // builds.
+      // FIXME: __OPTIMIZE__ is a GNU extension that Clang implements but MSVC
+      // does not. Is there a good equivalent there?
+      assert(assume(State, Cond, false) && "System is over constrained.");
+#endif
+      return ProgramStatePair((ProgramStateRef)nullptr, State);
+    }
+
+    ProgramStateRef StFalse = assume(State, Cond, false);
+    if (!StFalse) {
+      // We are careful to return the original state, /not/ StTrue,
+      // because we want to avoid having callers generate a new node
+      // in the ExplodedGraph.
+      return ProgramStatePair(State, (ProgramStateRef)nullptr);
+    }
+
+    return ProgramStatePair(StTrue, StFalse);
+  }
+
+  /// \brief If a symbol is perfectly constrained to a constant, attempt
+  /// to return the concrete value.
+  ///
+  /// Note that a ConstraintManager is not obligated to return a concretized
+  /// value for a symbol, even if it is perfectly constrained.
+  virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
+                                        SymbolRef sym) const {
+    return nullptr;
+  }
+
+  virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
+                                                 SymbolReaper& SymReaper) = 0;
+
+  virtual void print(ProgramStateRef state,
+                     raw_ostream &Out,
+                     const char* nl,
+                     const char *sep) = 0;
+
+  virtual void EndPath(ProgramStateRef state) {}
+  
+  /// Convenience method to query the state to see if a symbol is null or
+  /// not null, or if neither assumption can be made.
+  ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
+    SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false);
+
+    return checkNull(State, Sym);
+  }
+
+protected:
+  /// A flag to indicate that clients should be notified of assumptions.
+  /// By default this is the case, but sometimes this needs to be restricted
+  /// to avoid infinite recursions within the ConstraintManager.
+  ///
+  /// Note that this flag allows the ConstraintManager to be re-entrant,
+  /// but not thread-safe.
+  bool NotifyAssumeClients;
+
+  /// canReasonAbout - Not all ConstraintManagers can accurately reason about
+  ///  all SVal values.  This method returns true if the ConstraintManager can
+  ///  reasonably handle a given SVal value.  This is typically queried by
+  ///  ExprEngine to determine if the value should be replaced with a
+  ///  conjured symbolic value in order to recover some precision.
+  virtual bool canReasonAbout(SVal X) const = 0;
+
+  /// Returns whether or not a symbol is known to be null ("true"), known to be
+  /// non-null ("false"), or may be either ("underconstrained"). 
+  virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
+};
+
+ConstraintManager* CreateRangeConstraintManager(ProgramStateManager& statemgr,
+                                                SubEngine *subengine);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
new file mode 100644
index 0000000..76ace6d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -0,0 +1,552 @@
+//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- 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 generic engine for intraprocedural, path-sensitive,
+//  dataflow analysis via graph reachability.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_COREENGINE
+#define LLVM_CLANG_GR_COREENGINE
+
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
+#include <memory>
+
+namespace clang {
+
+class ProgramPointTag;
+  
+namespace ento {
+
+class NodeBuilder;
+
+//===----------------------------------------------------------------------===//
+/// CoreEngine - Implements the core logic of the graph-reachability
+///   analysis. It traverses the CFG and generates the ExplodedGraph.
+///   Program "states" are treated as opaque void pointers.
+///   The template class CoreEngine (which subclasses CoreEngine)
+///   provides the matching component to the engine that knows the actual types
+///   for states.  Note that this engine only dispatches to transfer functions
+///   at the statement and block-level.  The analyses themselves must implement
+///   any transfer function logic and the sub-expression level (if any).
+class CoreEngine {
+  friend struct NodeBuilderContext;
+  friend class NodeBuilder;
+  friend class ExprEngine;
+  friend class CommonNodeBuilder;
+  friend class IndirectGotoNodeBuilder;
+  friend class SwitchNodeBuilder;
+  friend class EndOfFunctionNodeBuilder;
+public:
+  typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
+            BlocksExhausted;
+  
+  typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
+            BlocksAborted;
+
+private:
+
+  SubEngine& SubEng;
+
+  /// G - The simulation graph.  Each node is a (location,state) pair.
+  std::unique_ptr<ExplodedGraph> G;
+
+  /// WList - A set of queued nodes that need to be processed by the
+  ///  worklist algorithm.  It is up to the implementation of WList to decide
+  ///  the order that nodes are processed.
+  std::unique_ptr<WorkList> WList;
+
+  /// BCounterFactory - A factory object for created BlockCounter objects.
+  ///   These are used to record for key nodes in the ExplodedGraph the
+  ///   number of times different CFGBlocks have been visited along a path.
+  BlockCounter::Factory BCounterFactory;
+
+  /// The locations where we stopped doing work because we visited a location
+  ///  too many times.
+  BlocksExhausted blocksExhausted;
+  
+  /// The locations where we stopped because the engine aborted analysis,
+  /// usually because it could not reason about something.
+  BlocksAborted blocksAborted;
+
+  /// The information about functions shared by the whole translation unit.
+  /// (This data is owned by AnalysisConsumer.)
+  FunctionSummariesTy *FunctionSummaries;
+
+  void generateNode(const ProgramPoint &Loc,
+                    ProgramStateRef State,
+                    ExplodedNode *Pred);
+
+  void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred);
+  void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred);
+  void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred);
+  void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred);
+
+  void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B,
+                    ExplodedNode *Pred);
+
+  /// Handle conditional logic for running static initializers.
+  void HandleStaticInit(const DeclStmt *DS, const CFGBlock *B,
+                        ExplodedNode *Pred);
+
+private:
+  CoreEngine(const CoreEngine &) LLVM_DELETED_FUNCTION;
+  void operator=(const CoreEngine &) LLVM_DELETED_FUNCTION;
+
+  ExplodedNode *generateCallExitBeginNode(ExplodedNode *N);
+
+public:
+  /// Construct a CoreEngine object to analyze the provided CFG.
+  CoreEngine(SubEngine& subengine,
+             FunctionSummariesTy *FS)
+    : SubEng(subengine), G(new ExplodedGraph()),
+      WList(WorkList::makeDFS()),
+      BCounterFactory(G->getAllocator()),
+      FunctionSummaries(FS){}
+
+  /// getGraph - Returns the exploded graph.
+  ExplodedGraph& getGraph() { return *G.get(); }
+
+  /// takeGraph - Returns the exploded graph.  Ownership of the graph is
+  ///  transferred to the caller.
+  ExplodedGraph *takeGraph() { return G.release(); }
+
+  /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
+  ///  steps.  Returns true if there is still simulation state on the worklist.
+  bool ExecuteWorkList(const LocationContext *L, unsigned Steps,
+                       ProgramStateRef InitState);
+  /// Returns true if there is still simulation state on the worklist.
+  bool ExecuteWorkListWithInitialState(const LocationContext *L,
+                                       unsigned Steps,
+                                       ProgramStateRef InitState, 
+                                       ExplodedNodeSet &Dst);
+
+  /// Dispatch the work list item based on the given location information.
+  /// Use Pred parameter as the predecessor state.
+  void dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc,
+                        const WorkListUnit& WU);
+
+  // Functions for external checking of whether we have unfinished work
+  bool wasBlockAborted() const { return !blocksAborted.empty(); }
+  bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
+  bool hasWorkRemaining() const { return wasBlocksExhausted() || 
+                                         WList->hasWork() || 
+                                         wasBlockAborted(); }
+
+  /// Inform the CoreEngine that a basic block was aborted because
+  /// it could not be completely analyzed.
+  void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
+    blocksAborted.push_back(std::make_pair(block, node));
+  }
+  
+  WorkList *getWorkList() const { return WList.get(); }
+
+  BlocksExhausted::const_iterator blocks_exhausted_begin() const {
+    return blocksExhausted.begin();
+  }
+  BlocksExhausted::const_iterator blocks_exhausted_end() const {
+    return blocksExhausted.end();
+  }
+  BlocksAborted::const_iterator blocks_aborted_begin() const {
+    return blocksAborted.begin();
+  }
+  BlocksAborted::const_iterator blocks_aborted_end() const {
+    return blocksAborted.end();
+  }
+
+  /// \brief Enqueue the given set of nodes onto the work list.
+  void enqueue(ExplodedNodeSet &Set);
+
+  /// \brief Enqueue nodes that were created as a result of processing
+  /// a statement onto the work list.
+  void enqueue(ExplodedNodeSet &Set, const CFGBlock *Block, unsigned Idx);
+
+  /// \brief enqueue the nodes corresponding to the end of function onto the
+  /// end of path / work list.
+  void enqueueEndOfFunction(ExplodedNodeSet &Set);
+
+  /// \brief Enqueue a single node created as a result of statement processing.
+  void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
+};
+
+// TODO: Turn into a calss.
+struct NodeBuilderContext {
+  const CoreEngine &Eng;
+  const CFGBlock *Block;
+  const LocationContext *LC;
+  NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
+    : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
+
+  /// \brief Return the CFGBlock associated with this builder.
+  const CFGBlock *getBlock() const { return Block; }
+
+  /// \brief Returns the number of times the current basic block has been
+  /// visited on the exploded graph path.
+  unsigned blockCount() const {
+    return Eng.WList->getBlockCounter().getNumVisited(
+                    LC->getCurrentStackFrame(),
+                    Block->getBlockID());
+  }
+};
+
+/// \class NodeBuilder
+/// \brief This is the simplest builder which generates nodes in the
+/// ExplodedGraph.
+///
+/// The main benefit of the builder is that it automatically tracks the
+/// frontier nodes (or destination set). This is the set of nodes which should
+/// be propagated to the next step / builder. They are the nodes which have been
+/// added to the builder (either as the input node set or as the newly
+/// constructed nodes) but did not have any outgoing transitions added.
+class NodeBuilder {
+  virtual void anchor();
+protected:
+  const NodeBuilderContext &C;
+
+  /// Specifies if the builder results have been finalized. For example, if it
+  /// is set to false, autotransitions are yet to be generated.
+  bool Finalized;
+  bool HasGeneratedNodes;
+  /// \brief The frontier set - a set of nodes which need to be propagated after
+  /// the builder dies.
+  ExplodedNodeSet &Frontier;
+
+  /// Checkes if the results are ready.
+  virtual bool checkResults() {
+    if (!Finalized)
+      return false;
+    return true;
+  }
+
+  bool hasNoSinksInFrontier() {
+    for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) {
+      if ((*I)->isSink())
+        return false;
+    }
+    return true;
+  }
+
+  /// Allow subclasses to finalize results before result_begin() is executed.
+  virtual void finalizeResults() {}
+  
+  ExplodedNode *generateNodeImpl(const ProgramPoint &PP,
+                                 ProgramStateRef State,
+                                 ExplodedNode *Pred,
+                                 bool MarkAsSink = false);
+
+public:
+  NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+              const NodeBuilderContext &Ctx, bool F = true)
+    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+    Frontier.Add(SrcNode);
+  }
+
+  NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+              const NodeBuilderContext &Ctx, bool F = true)
+    : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+    Frontier.insert(SrcSet);
+    assert(hasNoSinksInFrontier());
+  }
+
+  virtual ~NodeBuilder() {}
+
+  /// \brief Generates a node in the ExplodedGraph.
+  ExplodedNode *generateNode(const ProgramPoint &PP,
+                             ProgramStateRef State,
+                             ExplodedNode *Pred) {
+    return generateNodeImpl(PP, State, Pred, false);
+  }
+
+  /// \brief Generates a sink in the ExplodedGraph.
+  ///
+  /// When a node is marked as sink, the exploration from the node is stopped -
+  /// the node becomes the last node on the path and certain kinds of bugs are
+  /// suppressed.
+  ExplodedNode *generateSink(const ProgramPoint &PP,
+                             ProgramStateRef State,
+                             ExplodedNode *Pred) {
+    return generateNodeImpl(PP, State, Pred, true);
+  }
+
+  const ExplodedNodeSet &getResults() {
+    finalizeResults();
+    assert(checkResults());
+    return Frontier;
+  }
+
+  typedef ExplodedNodeSet::iterator iterator;
+  /// \brief Iterators through the results frontier.
+  inline iterator begin() {
+    finalizeResults();
+    assert(checkResults());
+    return Frontier.begin();
+  }
+  inline iterator end() {
+    finalizeResults();
+    return Frontier.end();
+  }
+
+  const NodeBuilderContext &getContext() { return C; }
+  bool hasGeneratedNodes() { return HasGeneratedNodes; }
+
+  void takeNodes(const ExplodedNodeSet &S) {
+    for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I )
+      Frontier.erase(*I);
+  }
+  void takeNodes(ExplodedNode *N) { Frontier.erase(N); }
+  void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
+  void addNodes(ExplodedNode *N) { Frontier.Add(N); }
+};
+
+/// \class NodeBuilderWithSinks
+/// \brief This node builder keeps track of the generated sink nodes.
+class NodeBuilderWithSinks: public NodeBuilder {
+  void anchor() override;
+protected:
+  SmallVector<ExplodedNode*, 2> sinksGenerated;
+  ProgramPoint &Location;
+
+public:
+  NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
+                       const NodeBuilderContext &Ctx, ProgramPoint &L)
+    : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
+
+  ExplodedNode *generateNode(ProgramStateRef State,
+                             ExplodedNode *Pred,
+                             const ProgramPointTag *Tag = nullptr) {
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    return NodeBuilder::generateNode(LocalLoc, State, Pred);
+  }
+
+  ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
+                             const ProgramPointTag *Tag = nullptr) {
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
+    if (N && N->isSink())
+      sinksGenerated.push_back(N);
+    return N;
+  }
+
+  const SmallVectorImpl<ExplodedNode*> &getSinks() const {
+    return sinksGenerated;
+  }
+};
+
+/// \class StmtNodeBuilder
+/// \brief This builder class is useful for generating nodes that resulted from
+/// visiting a statement. The main difference from its parent NodeBuilder is
+/// that it creates a statement specific ProgramPoint.
+class StmtNodeBuilder: public NodeBuilder {
+  NodeBuilder *EnclosingBldr;
+public:
+
+  /// \brief Constructs a StmtNodeBuilder. If the builder is going to process
+  /// nodes currently owned by another builder(with larger scope), use
+  /// Enclosing builder to transfer ownership.
+  StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+                  const NodeBuilderContext &Ctx,
+                  NodeBuilder *Enclosing = nullptr)
+    : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
+    if (EnclosingBldr)
+      EnclosingBldr->takeNodes(SrcNode);
+  }
+
+  StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+                  const NodeBuilderContext &Ctx,
+                  NodeBuilder *Enclosing = nullptr)
+    : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
+    if (EnclosingBldr)
+      for (ExplodedNodeSet::iterator I = SrcSet.begin(),
+                                     E = SrcSet.end(); I != E; ++I )
+        EnclosingBldr->takeNodes(*I);
+  }
+
+  virtual ~StmtNodeBuilder();
+
+  using NodeBuilder::generateNode;
+  using NodeBuilder::generateSink;
+
+  ExplodedNode *generateNode(const Stmt *S,
+                             ExplodedNode *Pred,
+                             ProgramStateRef St,
+                             const ProgramPointTag *tag = nullptr,
+                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
+    const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
+                                  Pred->getLocationContext(), tag);
+    return NodeBuilder::generateNode(L, St, Pred);
+  }
+
+  ExplodedNode *generateSink(const Stmt *S,
+                             ExplodedNode *Pred,
+                             ProgramStateRef St,
+                             const ProgramPointTag *tag = nullptr,
+                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
+    const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
+                                  Pred->getLocationContext(), tag);
+    return NodeBuilder::generateSink(L, St, Pred);
+  }
+};
+
+/// \brief BranchNodeBuilder is responsible for constructing the nodes
+/// corresponding to the two branches of the if statement - true and false.
+class BranchNodeBuilder: public NodeBuilder {
+  void anchor() override;
+  const CFGBlock *DstT;
+  const CFGBlock *DstF;
+
+  bool InFeasibleTrue;
+  bool InFeasibleFalse;
+
+public:
+  BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+                    const NodeBuilderContext &C,
+                    const CFGBlock *dstT, const CFGBlock *dstF)
+  : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
+    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
+    // The branch node builder does not generate autotransitions.
+    // If there are no successors it means that both branches are infeasible.
+    takeNodes(SrcNode);
+  }
+
+  BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+                    const NodeBuilderContext &C,
+                    const CFGBlock *dstT, const CFGBlock *dstF)
+  : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
+    InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
+    takeNodes(SrcSet);
+  }
+
+  ExplodedNode *generateNode(ProgramStateRef State, bool branch,
+                             ExplodedNode *Pred);
+
+  const CFGBlock *getTargetBlock(bool branch) const {
+    return branch ? DstT : DstF;
+  }
+
+  void markInfeasible(bool branch) {
+    if (branch)
+      InFeasibleTrue = true;
+    else
+      InFeasibleFalse = true;
+  }
+
+  bool isFeasible(bool branch) {
+    return branch ? !InFeasibleTrue : !InFeasibleFalse;
+  }
+};
+
+class IndirectGotoNodeBuilder {
+  CoreEngine& Eng;
+  const CFGBlock *Src;
+  const CFGBlock &DispatchBlock;
+  const Expr *E;
+  ExplodedNode *Pred;
+
+public:
+  IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, 
+                    const Expr *e, const CFGBlock *dispatch, CoreEngine* eng)
+    : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {}
+
+  class iterator {
+    CFGBlock::const_succ_iterator I;
+
+    friend class IndirectGotoNodeBuilder;
+    iterator(CFGBlock::const_succ_iterator i) : I(i) {}
+  public:
+
+    iterator &operator++() { ++I; return *this; }
+    bool operator!=(const iterator &X) const { return I != X.I; }
+
+    const LabelDecl *getLabel() const {
+      return cast<LabelStmt>((*I)->getLabel())->getDecl();
+    }
+
+    const CFGBlock *getBlock() const {
+      return *I;
+    }
+  };
+
+  iterator begin() { return iterator(DispatchBlock.succ_begin()); }
+  iterator end() { return iterator(DispatchBlock.succ_end()); }
+
+  ExplodedNode *generateNode(const iterator &I,
+                             ProgramStateRef State,
+                             bool isSink = false);
+
+  const Expr *getTarget() const { return E; }
+
+  ProgramStateRef getState() const { return Pred->State; }
+  
+  const LocationContext *getLocationContext() const {
+    return Pred->getLocationContext();
+  }
+};
+
+class SwitchNodeBuilder {
+  CoreEngine& Eng;
+  const CFGBlock *Src;
+  const Expr *Condition;
+  ExplodedNode *Pred;
+
+public:
+  SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src,
+                    const Expr *condition, CoreEngine* eng)
+  : Eng(*eng), Src(src), Condition(condition), Pred(pred) {}
+
+  class iterator {
+    CFGBlock::const_succ_reverse_iterator I;
+
+    friend class SwitchNodeBuilder;
+    iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {}
+
+  public:
+    iterator &operator++() { ++I; return *this; }
+    bool operator!=(const iterator &X) const { return I != X.I; }
+    bool operator==(const iterator &X) const { return I == X.I; }
+
+    const CaseStmt *getCase() const {
+      return cast<CaseStmt>((*I)->getLabel());
+    }
+
+    const CFGBlock *getBlock() const {
+      return *I;
+    }
+  };
+
+  iterator begin() { return iterator(Src->succ_rbegin()+1); }
+  iterator end() { return iterator(Src->succ_rend()); }
+
+  const SwitchStmt *getSwitch() const {
+    return cast<SwitchStmt>(Src->getTerminator());
+  }
+
+  ExplodedNode *generateCaseStmtNode(const iterator &I,
+                                     ProgramStateRef State);
+
+  ExplodedNode *generateDefaultCaseNode(ProgramStateRef State,
+                                        bool isSink = false);
+
+  const Expr *getCondition() const { return Condition; }
+
+  ProgramStateRef getState() const { return Pred->State; }
+  
+  const LocationContext *getLocationContext() const {
+    return Pred->getLocationContext();
+  }
+};
+
+} // end ento namespace
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
new file mode 100644
index 0000000..5ac97db
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
@@ -0,0 +1,52 @@
+//== DynamicTypeInfo.h - Runtime type information ----------------*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SA_CORE_DYNAMICTYPEINFO_H
+#define LLVM_CLANG_SA_CORE_DYNAMICTYPEINFO_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+namespace ento {
+
+/// \brief Stores the currently inferred strictest bound on the runtime type
+/// of a region in a given state along the analysis path.
+class DynamicTypeInfo {
+private:
+  QualType T;
+  bool CanBeASubClass;
+
+public:
+
+  DynamicTypeInfo() : T(QualType()) {}
+  DynamicTypeInfo(QualType WithType, bool CanBeSub = true)
+    : T(WithType), CanBeASubClass(CanBeSub) {}
+
+  /// \brief Return false if no dynamic type info is available.
+  bool isValid() const { return !T.isNull(); }
+
+  /// \brief Returns the currently inferred upper bound on the runtime type.
+  QualType getType() const { return T; }
+
+  /// \brief Returns false if the type information is precise (the type T is
+  /// the only type in the lattice), true otherwise.
+  bool canBeASubClass() const { return CanBeASubClass; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.Add(T);
+    ID.AddInteger((unsigned)CanBeASubClass);
+  }
+  bool operator==(const DynamicTypeInfo &X) const {
+    return T == X.T && CanBeASubClass == X.CanBeASubClass;
+  }
+};
+
+} // end ento
+} // end clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
new file mode 100644
index 0000000..f3a582d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -0,0 +1,128 @@
+//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the Environment and EnvironmentManager classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_ENVIRONMENT_H
+#define LLVM_CLANG_GR_ENVIRONMENT_H
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace clang {
+
+class LiveVariables;
+
+namespace ento {
+
+class EnvironmentManager;
+class SValBuilder;
+
+/// An entry in the environment consists of a Stmt and an LocationContext.
+/// This allows the environment to manage context-sensitive bindings,
+/// which is essentially for modeling recursive function analysis, among
+/// other things.
+class EnvironmentEntry : public std::pair<const Stmt*,
+                                          const StackFrameContext *> {
+public:
+  EnvironmentEntry(const Stmt *s, const LocationContext *L);
+
+  const Stmt *getStmt() const { return first; }
+  const LocationContext *getLocationContext() const { return second; }
+  
+  /// Profile an EnvironmentEntry for inclusion in a FoldingSet.
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const EnvironmentEntry &E) {
+    ID.AddPointer(E.getStmt());
+    ID.AddPointer(E.getLocationContext());
+  }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, *this);
+  }
+};
+
+/// An immutable map from EnvironemntEntries to SVals.
+class Environment {
+private:
+  friend class EnvironmentManager;
+
+  // Type definitions.
+  typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
+
+  // Data.
+  BindingsTy ExprBindings;
+
+  Environment(BindingsTy eb)
+    : ExprBindings(eb) {}
+
+  SVal lookupExpr(const EnvironmentEntry &E) const;
+
+public:
+  typedef BindingsTy::iterator iterator;
+  iterator begin() const { return ExprBindings.begin(); }
+  iterator end() const { return ExprBindings.end(); }
+
+  /// Fetches the current binding of the expression in the
+  /// Environment.
+  SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const;
+
+  /// Profile - Profile the contents of an Environment object for use
+  ///  in a FoldingSet.
+  static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) {
+    env->ExprBindings.Profile(ID);
+  }
+
+  /// Profile - Used to profile the contents of this object for inclusion
+  ///  in a FoldingSet.
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, this);
+  }
+
+  bool operator==(const Environment& RHS) const {
+    return ExprBindings == RHS.ExprBindings;
+  }
+  
+  void print(raw_ostream &Out, const char *NL, const char *Sep) const;
+  
+private:
+  void printAux(raw_ostream &Out, bool printLocations,
+                const char *NL, const char *Sep) const;
+};
+
+class EnvironmentManager {
+private:
+  typedef Environment::BindingsTy::Factory FactoryTy;
+  FactoryTy F;
+
+public:
+  EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
+  ~EnvironmentManager() {}
+
+  Environment getInitialEnvironment() {
+    return Environment(F.getEmptyMap());
+  }
+
+  /// Bind a symbolic value to the given environment entry.
+  Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V,
+                       bool Invalidate);
+
+  Environment removeDeadBindings(Environment Env,
+                                 SymbolReaper &SymReaper,
+                                 ProgramStateRef state);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
new file mode 100644
index 0000000..98092ef
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -0,0 +1,498 @@
+//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- 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 template classes ExplodedNode and ExplodedGraph,
+//  which represent a path-sensitive, intra-procedural "exploded graph."
+//  See "Precise interprocedural dataflow analysis via graph reachability"
+//  by Reps, Horwitz, and Sagiv
+//  (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
+//  exploded graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_EXPLODEDGRAPH
+#define LLVM_CLANG_GR_EXPLODEDGRAPH
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Analysis/Support/BumpVector.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include <memory>
+#include <vector>
+
+namespace clang {
+
+class CFG;
+
+namespace ento {
+
+class ExplodedGraph;
+
+//===----------------------------------------------------------------------===//
+// ExplodedGraph "implementation" classes.  These classes are not typed to
+// contain a specific kind of state.  Typed-specialized versions are defined
+// on top of these classes.
+//===----------------------------------------------------------------------===//
+
+// ExplodedNode is not constified all over the engine because we need to add
+// successors to it at any time after creating it.
+
+class ExplodedNode : public llvm::FoldingSetNode {
+  friend class ExplodedGraph;
+  friend class CoreEngine;
+  friend class NodeBuilder;
+  friend class BranchNodeBuilder;
+  friend class IndirectGotoNodeBuilder;
+  friend class SwitchNodeBuilder;
+  friend class EndOfFunctionNodeBuilder;
+
+  /// Efficiently stores a list of ExplodedNodes, or an optional flag.
+  ///
+  /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing
+  /// for the case when there is only one node in the group. This is a fairly
+  /// common case in an ExplodedGraph, where most nodes have only one
+  /// predecessor and many have only one successor. It can also be used to
+  /// store a flag rather than a node list, which ExplodedNode uses to mark
+  /// whether a node is a sink. If the flag is set, the group is implicitly
+  /// empty and no nodes may be added.
+  class NodeGroup {
+    // Conceptually a discriminated union. If the low bit is set, the node is
+    // a sink. If the low bit is not set, the pointer refers to the storage
+    // for the nodes in the group.
+    // This is not a PointerIntPair in order to keep the storage type opaque.
+    uintptr_t P;
+    
+  public:
+    NodeGroup(bool Flag = false) : P(Flag) {
+      assert(getFlag() == Flag);
+    }
+
+    ExplodedNode * const *begin() const;
+
+    ExplodedNode * const *end() const;
+
+    unsigned size() const;
+
+    bool empty() const { return P == 0 || getFlag() != 0; }
+
+    /// Adds a node to the list.
+    ///
+    /// The group must not have been created with its flag set.
+    void addNode(ExplodedNode *N, ExplodedGraph &G);
+
+    /// Replaces the single node in this group with a new node.
+    ///
+    /// Note that this should only be used when you know the group was not
+    /// created with its flag set, and that the group is empty or contains
+    /// only a single node.
+    void replaceNode(ExplodedNode *node);
+
+    /// Returns whether this group was created with its flag set.
+    bool getFlag() const {
+      return (P & 1);
+    }
+  };
+
+  /// Location - The program location (within a function body) associated
+  ///  with this node.
+  const ProgramPoint Location;
+
+  /// State - The state associated with this node.
+  ProgramStateRef State;
+
+  /// Preds - The predecessors of this node.
+  NodeGroup Preds;
+
+  /// Succs - The successors of this node.
+  NodeGroup Succs;
+
+public:
+
+  explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
+                        bool IsSink)
+    : Location(loc), State(state), Succs(IsSink) {
+    assert(isSink() == IsSink);
+  }
+  
+  ~ExplodedNode() {}
+
+  /// getLocation - Returns the edge associated with the given node.
+  ProgramPoint getLocation() const { return Location; }
+
+  const LocationContext *getLocationContext() const {
+    return getLocation().getLocationContext();
+  }
+
+  const StackFrameContext *getStackFrame() const {
+    return getLocationContext()->getCurrentStackFrame();
+  }
+
+  const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
+
+  CFG &getCFG() const { return *getLocationContext()->getCFG(); }
+
+  ParentMap &getParentMap() const {return getLocationContext()->getParentMap();}
+
+  template <typename T>
+  T &getAnalysis() const {
+    return *getLocationContext()->getAnalysis<T>();
+  }
+
+  const ProgramStateRef &getState() const { return State; }
+
+  template <typename T>
+  Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
+    return Location.getAs<T>();
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID,
+                      const ProgramPoint &Loc,
+                      const ProgramStateRef &state,
+                      bool IsSink) {
+    ID.Add(Loc);
+    ID.AddPointer(state.get());
+    ID.AddBoolean(IsSink);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    // We avoid copy constructors by not using accessors.
+    Profile(ID, Location, State, isSink());
+  }
+
+  /// addPredeccessor - Adds a predecessor to the current node, and
+  ///  in tandem add this node as a successor of the other node.
+  void addPredecessor(ExplodedNode *V, ExplodedGraph &G);
+
+  unsigned succ_size() const { return Succs.size(); }
+  unsigned pred_size() const { return Preds.size(); }
+  bool succ_empty() const { return Succs.empty(); }
+  bool pred_empty() const { return Preds.empty(); }
+
+  bool isSink() const { return Succs.getFlag(); }
+
+  bool hasSinglePred() const {
+    return (pred_size() == 1);
+  }
+
+  ExplodedNode *getFirstPred() {
+    return pred_empty() ? nullptr : *(pred_begin());
+  }
+
+  const ExplodedNode *getFirstPred() const {
+    return const_cast<ExplodedNode*>(this)->getFirstPred();
+  }
+
+  const ExplodedNode *getFirstSucc() const {
+    return succ_empty() ? nullptr : *(succ_begin());
+  }
+
+  // Iterators over successor and predecessor vertices.
+  typedef ExplodedNode*       const *       succ_iterator;
+  typedef const ExplodedNode* const * const_succ_iterator;
+  typedef ExplodedNode*       const *       pred_iterator;
+  typedef const ExplodedNode* const * const_pred_iterator;
+
+  pred_iterator pred_begin() { return Preds.begin(); }
+  pred_iterator pred_end() { return Preds.end(); }
+
+  const_pred_iterator pred_begin() const {
+    return const_cast<ExplodedNode*>(this)->pred_begin();
+  }
+  const_pred_iterator pred_end() const {
+    return const_cast<ExplodedNode*>(this)->pred_end();
+  }
+
+  succ_iterator succ_begin() { return Succs.begin(); }
+  succ_iterator succ_end() { return Succs.end(); }
+
+  const_succ_iterator succ_begin() const {
+    return const_cast<ExplodedNode*>(this)->succ_begin();
+  }
+  const_succ_iterator succ_end() const {
+    return const_cast<ExplodedNode*>(this)->succ_end();
+  }
+
+  // For debugging.
+
+public:
+
+  class Auditor {
+  public:
+    virtual ~Auditor();
+    virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0;
+  };
+
+  static void SetAuditor(Auditor* A);
+  
+private:
+  void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); }
+  void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); }
+};
+
+typedef llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>
+        InterExplodedGraphMap;
+
+class ExplodedGraph {
+protected:
+  friend class CoreEngine;
+
+  // Type definitions.
+  typedef std::vector<ExplodedNode *> NodeVector;
+
+  /// The roots of the simulation graph. Usually there will be only
+  /// one, but clients are free to establish multiple subgraphs within a single
+  /// SimulGraph. Moreover, these subgraphs can often merge when paths from
+  /// different roots reach the same state at the same program location.
+  NodeVector Roots;
+
+  /// The nodes in the simulation graph which have been
+  /// specially marked as the endpoint of an abstract simulation path.
+  NodeVector EndNodes;
+
+  /// Nodes - The nodes in the graph.
+  llvm::FoldingSet<ExplodedNode> Nodes;
+
+  /// BVC - Allocator and context for allocating nodes and their predecessor
+  /// and successor groups.
+  BumpVectorContext BVC;
+
+  /// NumNodes - The number of nodes in the graph.
+  unsigned NumNodes;
+  
+  /// A list of recently allocated nodes that can potentially be recycled.
+  NodeVector ChangedNodes;
+  
+  /// A list of nodes that can be reused.
+  NodeVector FreeNodes;
+  
+  /// Determines how often nodes are reclaimed.
+  ///
+  /// If this is 0, nodes will never be reclaimed.
+  unsigned ReclaimNodeInterval;
+  
+  /// Counter to determine when to reclaim nodes.
+  unsigned ReclaimCounter;
+
+public:
+
+  /// \brief Retrieve the node associated with a (Location,State) pair,
+  ///  where the 'Location' is a ProgramPoint in the CFG.  If no node for
+  ///  this pair exists, it is created. IsNew is set to true if
+  ///  the node was freshly created.
+  ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State,
+                        bool IsSink = false,
+                        bool* IsNew = nullptr);
+
+  ExplodedGraph* MakeEmptyGraph() const {
+    return new ExplodedGraph();
+  }
+
+  /// addRoot - Add an untyped node to the set of roots.
+  ExplodedNode *addRoot(ExplodedNode *V) {
+    Roots.push_back(V);
+    return V;
+  }
+
+  /// addEndOfPath - Add an untyped node to the set of EOP nodes.
+  ExplodedNode *addEndOfPath(ExplodedNode *V) {
+    EndNodes.push_back(V);
+    return V;
+  }
+
+  ExplodedGraph();
+
+  ~ExplodedGraph();
+  
+  unsigned num_roots() const { return Roots.size(); }
+  unsigned num_eops() const { return EndNodes.size(); }
+
+  bool empty() const { return NumNodes == 0; }
+  unsigned size() const { return NumNodes; }
+
+  // Iterators.
+  typedef ExplodedNode                        NodeTy;
+  typedef llvm::FoldingSet<ExplodedNode>      AllNodesTy;
+  typedef NodeVector::iterator                roots_iterator;
+  typedef NodeVector::const_iterator          const_roots_iterator;
+  typedef NodeVector::iterator                eop_iterator;
+  typedef NodeVector::const_iterator          const_eop_iterator;
+  typedef AllNodesTy::iterator                node_iterator;
+  typedef AllNodesTy::const_iterator          const_node_iterator;
+
+  node_iterator nodes_begin() { return Nodes.begin(); }
+
+  node_iterator nodes_end() { return Nodes.end(); }
+
+  const_node_iterator nodes_begin() const { return Nodes.begin(); }
+
+  const_node_iterator nodes_end() const { return Nodes.end(); }
+
+  roots_iterator roots_begin() { return Roots.begin(); }
+
+  roots_iterator roots_end() { return Roots.end(); }
+
+  const_roots_iterator roots_begin() const { return Roots.begin(); }
+
+  const_roots_iterator roots_end() const { return Roots.end(); }
+
+  eop_iterator eop_begin() { return EndNodes.begin(); }
+
+  eop_iterator eop_end() { return EndNodes.end(); }
+
+  const_eop_iterator eop_begin() const { return EndNodes.begin(); }
+
+  const_eop_iterator eop_end() const { return EndNodes.end(); }
+
+  llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); }
+  BumpVectorContext &getNodeAllocator() { return BVC; }
+
+  typedef llvm::DenseMap<const ExplodedNode*, ExplodedNode*> NodeMap;
+
+  /// Creates a trimmed version of the graph that only contains paths leading
+  /// to the given nodes.
+  ///
+  /// \param Nodes The nodes which must appear in the final graph. Presumably
+  ///              these are end-of-path nodes (i.e. they have no successors).
+  /// \param[out] ForwardMap A optional map from nodes in this graph to nodes in
+  ///                        the returned graph.
+  /// \param[out] InverseMap An optional map from nodes in the returned graph to
+  ///                        nodes in this graph.
+  /// \returns The trimmed graph
+  ExplodedGraph *trim(ArrayRef<const NodeTy *> Nodes,
+                      InterExplodedGraphMap *ForwardMap = nullptr,
+                      InterExplodedGraphMap *InverseMap = nullptr) const;
+
+  /// Enable tracking of recently allocated nodes for potential reclamation
+  /// when calling reclaimRecentlyAllocatedNodes().
+  void enableNodeReclamation(unsigned Interval) {
+    ReclaimCounter = ReclaimNodeInterval = Interval;
+  }
+
+  /// Reclaim "uninteresting" nodes created since the last time this method
+  /// was called.
+  void reclaimRecentlyAllocatedNodes();
+
+  /// \brief Returns true if nodes for the given expression kind are always
+  ///        kept around.
+  static bool isInterestingLValueExpr(const Expr *Ex);
+
+private:
+  bool shouldCollect(const ExplodedNode *node);
+  void collectNode(ExplodedNode *node);
+};
+
+class ExplodedNodeSet {
+  typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
+  ImplTy Impl;
+
+public:
+  ExplodedNodeSet(ExplodedNode *N) {
+    assert (N && !static_cast<ExplodedNode*>(N)->isSink());
+    Impl.insert(N);
+  }
+
+  ExplodedNodeSet() {}
+
+  inline void Add(ExplodedNode *N) {
+    if (N && !static_cast<ExplodedNode*>(N)->isSink()) Impl.insert(N);
+  }
+
+  typedef ImplTy::iterator       iterator;
+  typedef ImplTy::const_iterator const_iterator;
+
+  unsigned size() const { return Impl.size();  }
+  bool empty()    const { return Impl.empty(); }
+  bool erase(ExplodedNode *N) { return Impl.erase(N); }
+
+  void clear() { Impl.clear(); }
+  void insert(const ExplodedNodeSet &S) {
+    assert(&S != this);
+    if (empty())
+      Impl = S.Impl;
+    else
+      Impl.insert(S.begin(), S.end());
+  }
+
+  inline iterator begin() { return Impl.begin(); }
+  inline iterator end()   { return Impl.end();   }
+
+  inline const_iterator begin() const { return Impl.begin(); }
+  inline const_iterator end()   const { return Impl.end();   }
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+// GraphTraits
+
+namespace llvm {
+  template<> struct GraphTraits<clang::ento::ExplodedNode*> {
+    typedef clang::ento::ExplodedNode NodeType;
+    typedef NodeType::succ_iterator  ChildIteratorType;
+    typedef llvm::df_iterator<NodeType*>      nodes_iterator;
+
+    static inline NodeType* getEntryNode(NodeType* N) {
+      return N;
+    }
+
+    static inline ChildIteratorType child_begin(NodeType* N) {
+      return N->succ_begin();
+    }
+
+    static inline ChildIteratorType child_end(NodeType* N) {
+      return N->succ_end();
+    }
+
+    static inline nodes_iterator nodes_begin(NodeType* N) {
+      return df_begin(N);
+    }
+
+    static inline nodes_iterator nodes_end(NodeType* N) {
+      return df_end(N);
+    }
+  };
+
+  template<> struct GraphTraits<const clang::ento::ExplodedNode*> {
+    typedef const clang::ento::ExplodedNode NodeType;
+    typedef NodeType::const_succ_iterator   ChildIteratorType;
+    typedef llvm::df_iterator<NodeType*>       nodes_iterator;
+
+    static inline NodeType* getEntryNode(NodeType* N) {
+      return N;
+    }
+
+    static inline ChildIteratorType child_begin(NodeType* N) {
+      return N->succ_begin();
+    }
+
+    static inline ChildIteratorType child_end(NodeType* N) {
+      return N->succ_end();
+    }
+
+    static inline nodes_iterator nodes_begin(NodeType* N) {
+      return df_begin(N);
+    }
+
+    static inline nodes_iterator nodes_end(NodeType* N) {
+      return df_end(N);
+    }
+  };
+
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
new file mode 100644
index 0000000..0fb4a24
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -0,0 +1,607 @@
+//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- 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 meta-engine for path-sensitive dataflow analysis that
+//  is built on CoreEngine, but provides the boilerplate to execute transfer
+//  functions and build the ExplodedGraph at the expression level.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_EXPRENGINE
+#define LLVM_CLANG_GR_EXPRENGINE
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
+
+namespace clang {
+
+class AnalysisDeclContextManager;
+class CXXCatchStmt;
+class CXXConstructExpr;
+class CXXDeleteExpr;
+class CXXNewExpr;
+class CXXTemporaryObjectExpr;
+class CXXThisExpr;
+class MaterializeTemporaryExpr;
+class ObjCAtSynchronizedStmt;
+class ObjCForCollectionStmt;
+  
+namespace ento {
+
+class AnalysisManager;
+class CallEvent;
+class CXXConstructorCall;
+
+class ExprEngine : public SubEngine {
+public:
+  /// The modes of inlining, which override the default analysis-wide settings.
+  enum InliningModes {
+    /// Follow the default settings for inlining callees.
+    Inline_Regular = 0,
+    /// Do minimal inlining of callees.
+    Inline_Minimal = 0x1
+  };
+
+private:
+  AnalysisManager &AMgr;
+  
+  AnalysisDeclContextManager &AnalysisDeclContexts;
+
+  CoreEngine Engine;
+
+  /// G - the simulation graph.
+  ExplodedGraph& G;
+
+  /// StateMgr - Object that manages the data for all created states.
+  ProgramStateManager StateMgr;
+
+  /// SymMgr - Object that manages the symbol information.
+  SymbolManager& SymMgr;
+
+  /// svalBuilder - SValBuilder object that creates SVals from expressions.
+  SValBuilder &svalBuilder;
+
+  unsigned int currStmtIdx;
+  const NodeBuilderContext *currBldrCtx;
+  
+  /// Helper object to determine if an Objective-C message expression
+  /// implicitly never returns.
+  ObjCNoReturn ObjCNoRet;
+  
+  /// Whether or not GC is enabled in this analysis.
+  bool ObjCGCEnabled;
+
+  /// The BugReporter associated with this engine.  It is important that
+  ///  this object be placed at the very end of member variables so that its
+  ///  destructor is called before the rest of the ExprEngine is destroyed.
+  GRBugReporter BR;
+
+  /// The functions which have been analyzed through inlining. This is owned by
+  /// AnalysisConsumer. It can be null.
+  SetOfConstDecls *VisitedCallees;
+
+  /// The flag, which specifies the mode of inlining for the engine.
+  InliningModes HowToInline;
+
+public:
+  ExprEngine(AnalysisManager &mgr, bool gcEnabled,
+             SetOfConstDecls *VisitedCalleesIn,
+             FunctionSummariesTy *FS,
+             InliningModes HowToInlineIn);
+
+  ~ExprEngine();
+
+  /// Returns true if there is still simulation state on the worklist.
+  bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
+    return Engine.ExecuteWorkList(L, Steps, nullptr);
+  }
+
+  /// Execute the work list with an initial state. Nodes that reaches the exit
+  /// of the function are added into the Dst set, which represent the exit
+  /// state of the function call. Returns true if there is still simulation
+  /// state on the worklist.
+  bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
+                                       ProgramStateRef InitState, 
+                                       ExplodedNodeSet &Dst) {
+    return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
+  }
+
+  /// getContext - Return the ASTContext associated with this analysis.
+  ASTContext &getContext() const { return AMgr.getASTContext(); }
+
+  AnalysisManager &getAnalysisManager() override { return AMgr; }
+
+  CheckerManager &getCheckerManager() const {
+    return *AMgr.getCheckerManager();
+  }
+
+  SValBuilder &getSValBuilder() { return svalBuilder; }
+
+  BugReporter& getBugReporter() { return BR; }
+
+  const NodeBuilderContext &getBuilderContext() {
+    assert(currBldrCtx);
+    return *currBldrCtx;
+  }
+
+  bool isObjCGCEnabled() { return ObjCGCEnabled; }
+
+  const Stmt *getStmt() const;
+
+  void GenerateAutoTransition(ExplodedNode *N);
+  void enqueueEndOfPath(ExplodedNodeSet &S);
+  void GenerateCallExitNode(ExplodedNode *N);
+
+  /// Visualize the ExplodedGraph created by executing the simulation.
+  void ViewGraph(bool trim = false);
+
+  /// Visualize a trimmed ExplodedGraph that only contains paths to the given
+  /// nodes.
+  void ViewGraph(ArrayRef<const ExplodedNode*> Nodes);
+
+  /// getInitialState - Return the initial state used for the root vertex
+  ///  in the ExplodedGraph.
+  ProgramStateRef getInitialState(const LocationContext *InitLoc) override;
+
+  ExplodedGraph& getGraph() { return G; }
+  const ExplodedGraph& getGraph() const { return G; }
+
+  /// \brief Run the analyzer's garbage collection - remove dead symbols and
+  /// bindings from the state.
+  ///
+  /// Checkers can participate in this process with two callbacks:
+  /// \c checkLiveSymbols and \c checkDeadSymbols. See the CheckerDocumentation
+  /// class for more information.
+  ///
+  /// \param Node The predecessor node, from which the processing should start.
+  /// \param Out The returned set of output nodes.
+  /// \param ReferenceStmt The statement which is about to be processed.
+  ///        Everything needed for this statement should be considered live.
+  ///        A null statement means that everything in child LocationContexts
+  ///        is dead.
+  /// \param LC The location context of the \p ReferenceStmt. A null location
+  ///        context means that we have reached the end of analysis and that
+  ///        all statements and local variables should be considered dead.
+  /// \param DiagnosticStmt Used as a location for any warnings that should
+  ///        occur while removing the dead (e.g. leaks). By default, the
+  ///        \p ReferenceStmt is used.
+  /// \param K Denotes whether this is a pre- or post-statement purge. This
+  ///        must only be ProgramPoint::PostStmtPurgeDeadSymbolsKind if an
+  ///        entire location context is being cleared, in which case the
+  ///        \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise,
+  ///        it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default)
+  ///        and \p ReferenceStmt must be valid (non-null).
+  void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
+            const Stmt *ReferenceStmt, const LocationContext *LC,
+            const Stmt *DiagnosticStmt = nullptr,
+            ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
+
+  /// processCFGElement - Called by CoreEngine. Used to generate new successor
+  ///  nodes by processing the 'effects' of a CFG element.
+  void processCFGElement(const CFGElement E, ExplodedNode *Pred,
+                         unsigned StmtIdx, NodeBuilderContext *Ctx) override;
+
+  void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
+
+  void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
+
+  void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
+
+  void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
+
+  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
+                               ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void ProcessDeleteDtor(const CFGDeleteDtor D,
+                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void ProcessBaseDtor(const CFGBaseDtor D,
+                       ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void ProcessMemberDtor(const CFGMemberDtor D,
+                         ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void ProcessTemporaryDtor(const CFGTemporaryDtor D, 
+                            ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// Called by CoreEngine when processing the entrance of a CFGBlock.
+  void processCFGBlockEntrance(const BlockEdge &L,
+                               NodeBuilderWithSinks &nodeBuilder,
+                               ExplodedNode *Pred) override;
+ 
+  /// ProcessBranch - Called by CoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a branch condition.
+  void processBranch(const Stmt *Condition, const Stmt *Term, 
+                     NodeBuilderContext& BuilderCtx,
+                     ExplodedNode *Pred,
+                     ExplodedNodeSet &Dst,
+                     const CFGBlock *DstT,
+                     const CFGBlock *DstF) override;
+
+  /// Called by CoreEngine.  Used to processing branching behavior
+  /// at static initalizers.
+  void processStaticInitializer(const DeclStmt *DS,
+                                NodeBuilderContext& BuilderCtx,
+                                ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst,
+                                const CFGBlock *DstT,
+                                const CFGBlock *DstF) override;
+
+  /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a computed goto jump.
+  void processIndirectGoto(IndirectGotoNodeBuilder& builder) override;
+
+  /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a switch statement.
+  void processSwitch(SwitchNodeBuilder& builder) override;
+
+  /// Called by CoreEngine.  Used to generate end-of-path
+  /// nodes when the control reaches the end of a function.
+  void processEndOfFunction(NodeBuilderContext& BC,
+                            ExplodedNode *Pred) override;
+
+  /// Remove dead bindings/symbols before exiting a function.
+  void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
+                                 ExplodedNode *Pred,
+                                 ExplodedNodeSet &Dst);
+
+  /// Generate the entry node of the callee.
+  void processCallEnter(CallEnter CE, ExplodedNode *Pred) override;
+
+  /// Generate the sequence of nodes that simulate the call exit and the post
+  /// visit for CallExpr.
+  void processCallExit(ExplodedNode *Pred) override;
+
+  /// Called by CoreEngine when the analysis worklist has terminated.
+  void processEndWorklist(bool hasWorkRemaining) override;
+
+  /// evalAssume - Callback function invoked by the ConstraintManager when
+  ///  making assumptions about state values.
+  ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
+                                bool assumption) override;
+
+  /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
+  ///  region change should trigger a processRegionChanges update.
+  bool wantsRegionChangeUpdate(ProgramStateRef state) override;
+
+  /// processRegionChanges - Called by ProgramStateManager whenever a change is made
+  ///  to the store. Used to update checkers that track region values.
+  ProgramStateRef 
+  processRegionChanges(ProgramStateRef state,
+                       const InvalidatedSymbols *invalidated,
+                       ArrayRef<const MemRegion *> ExplicitRegions,
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallEvent *Call) override;
+
+  /// printState - Called by ProgramStateManager to print checker-specific data.
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) override;
+
+  ProgramStateManager& getStateManager() override { return StateMgr; }
+
+  StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
+
+  ConstraintManager& getConstraintManager() {
+    return StateMgr.getConstraintManager();
+  }
+
+  // FIXME: Remove when we migrate over to just using SValBuilder.
+  BasicValueFactory& getBasicVals() {
+    return StateMgr.getBasicVals();
+  }
+
+  // FIXME: Remove when we migrate over to just using ValueManager.
+  SymbolManager& getSymbolManager() { return SymMgr; }
+  const SymbolManager& getSymbolManager() const { return SymMgr; }
+
+  // Functions for external checking of whether we have unfinished work
+  bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
+  bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
+  bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
+
+  const CoreEngine &getCoreEngine() const { return Engine; }
+
+public:
+  /// Visit - Transfer function logic for all statements.  Dispatches to
+  ///  other functions that handle specific kinds of statements.
+  void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// VisitArraySubscriptExpr - Transfer function for array accesses.
+  void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex,
+                                   ExplodedNode *Pred,
+                                   ExplodedNodeSet &Dst);
+
+  /// VisitGCCAsmStmt - Transfer function logic for inline asm.
+  void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
+                       ExplodedNodeSet &Dst);
+
+  /// VisitMSAsmStmt - Transfer function logic for MS inline asm.
+  void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
+                      ExplodedNodeSet &Dst);
+
+  /// VisitBlockExpr - Transfer function logic for BlockExprs.
+  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, 
+                      ExplodedNodeSet &Dst);
+
+  /// VisitBinaryOperator - Transfer function logic for binary operators.
+  void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, 
+                           ExplodedNodeSet &Dst);
+
+
+  /// VisitCall - Transfer function for function calls.
+  void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
+                     ExplodedNodeSet &Dst);
+
+  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
+  void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
+                ExplodedNodeSet &Dst);
+
+  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
+  void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, 
+                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
+  void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D,
+                              ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  
+  /// VisitDeclStmt - Transfer function logic for DeclStmts.
+  void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, 
+                     ExplodedNodeSet &Dst);
+
+  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
+  void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, 
+                        ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  
+  void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred,
+                         ExplodedNodeSet &Dst);
+
+  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
+  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
+                        ExplodedNodeSet &Dst);
+
+  /// VisitMemberExpr - Transfer function for member expressions.
+  void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 
+                           ExplodedNodeSet &Dst);
+
+  /// Transfer function logic for ObjCAtSynchronizedStmts.
+  void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
+                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// Transfer function logic for computing the lvalue of an Objective-C ivar.
+  void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst);
+
+  /// VisitObjCForCollectionStmt - Transfer function logic for
+  ///  ObjCForCollectionStmt.
+  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 
+                                  ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
+                        ExplodedNodeSet &Dst);
+
+  /// VisitReturnStmt - Transfer function logic for return statements.
+  void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, 
+                       ExplodedNodeSet &Dst);
+  
+  /// VisitOffsetOfExpr - Transfer function for offsetof.
+  void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred,
+                         ExplodedNodeSet &Dst);
+
+  /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
+  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
+                              ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  /// VisitUnaryOperator - Transfer function logic for unary operators.
+  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, 
+                          ExplodedNodeSet &Dst);
+
+  /// Handle ++ and -- (both pre- and post-increment).
+  void VisitIncrementDecrementOperator(const UnaryOperator* U,
+                                       ExplodedNode *Pred,
+                                       ExplodedNodeSet &Dst);
+  
+  void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
+                         ExplodedNodeSet &Dst);
+
+  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 
+                        ExplodedNodeSet & Dst);
+
+  void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst);
+
+  void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest,
+                          const Stmt *S, bool IsBaseDtor,
+                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
+  void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+                                ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst);
+
+  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
+                       ExplodedNodeSet &Dst);
+
+  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
+                          ExplodedNodeSet &Dst);
+
+  /// Create a C++ temporary object for an rvalue.
+  void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
+                                ExplodedNode *Pred, 
+                                ExplodedNodeSet &Dst);
+  
+  /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic
+  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
+  ///  with those assumptions.
+  void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
+                         const Expr *Ex);
+  
+  std::pair<const ProgramPointTag *, const ProgramPointTag*>
+    geteagerlyAssumeBinOpBifurcationTags();
+
+  SVal evalMinus(SVal X) {
+    return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
+  }
+
+  SVal evalComplement(SVal X) {
+    return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
+  }
+
+public:
+
+  SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
+                 NonLoc L, NonLoc R, QualType T) {
+    return svalBuilder.evalBinOpNN(state, op, L, R, T);
+  }
+
+  SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
+                 NonLoc L, SVal R, QualType T) {
+    return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
+                                                 R.castAs<NonLoc>(), T) : R;
+  }
+
+  SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
+                 SVal LHS, SVal RHS, QualType T) {
+    return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
+  }
+  
+protected:
+  /// evalBind - Handle the semantics of binding a value to a specific location.
+  ///  This method is used by evalStore, VisitDeclStmt, and others.
+  void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
+                SVal location, SVal Val, bool atDeclInit = false,
+                const ProgramPoint *PP = nullptr);
+
+  /// Call PointerEscape callback when a value escapes as a result of bind.
+  ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
+                                              SVal Loc, SVal Val) override;
+  /// Call PointerEscape callback when a value escapes as a result of
+  /// region invalidation.
+  /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
+  ProgramStateRef notifyCheckersOfPointerEscape(
+                           ProgramStateRef State,
+                           const InvalidatedSymbols *Invalidated,
+                           ArrayRef<const MemRegion *> ExplicitRegions,
+                           ArrayRef<const MemRegion *> Regions,
+                           const CallEvent *Call,
+                           RegionAndSymbolInvalidationTraits &ITraits) override;
+
+public:
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  // FIXME: Comment on the meaning of the arguments, when 'St' may not
+  // be the same as Pred->state, and when 'location' may not be the
+  // same as state->getLValue(Ex).
+  /// Simulate a read of the result of Ex.
+  void evalLoad(ExplodedNodeSet &Dst,
+                const Expr *NodeEx,  /* Eventually will be a CFGStmt */
+                const Expr *BoundExpr,
+                ExplodedNode *Pred,
+                ProgramStateRef St,
+                SVal location,
+                const ProgramPointTag *tag = nullptr,
+                QualType LoadTy = QualType());
+
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
+                 ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
+                 const ProgramPointTag *tag = nullptr);
+
+  /// \brief Create a new state in which the call return value is binded to the
+  /// call origin expression.
+  ProgramStateRef bindReturnValue(const CallEvent &Call,
+                                  const LocationContext *LCtx,
+                                  ProgramStateRef State);
+
+  /// Evaluate a call, running pre- and post-call checks and allowing checkers
+  /// to be responsible for handling the evaluation of the call itself.
+  void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
+                const CallEvent &Call);
+
+  /// \brief Default implementation of call evaluation.
+  void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
+                       const CallEvent &Call);
+private:
+  void evalLoadCommon(ExplodedNodeSet &Dst,
+                      const Expr *NodeEx,  /* Eventually will be a CFGStmt */
+                      const Expr *BoundEx,
+                      ExplodedNode *Pred,
+                      ProgramStateRef St,
+                      SVal location,
+                      const ProgramPointTag *tag,
+                      QualType LoadTy);
+
+  // FIXME: 'tag' should be removed, and a LocationContext should be used
+  // instead.
+  void evalLocation(ExplodedNodeSet &Dst,
+                    const Stmt *NodeEx, /* This will eventually be a CFGStmt */
+                    const Stmt *BoundEx,
+                    ExplodedNode *Pred,
+                    ProgramStateRef St, SVal location,
+                    const ProgramPointTag *tag, bool isLoad);
+
+  /// Count the stack depth and determine if the call is recursive.
+  void examineStackFrames(const Decl *D, const LocationContext *LCtx,
+                          bool &IsRecursive, unsigned &StackDepth);
+
+  /// Checks our policies and decides weither the given call should be inlined.
+  bool shouldInlineCall(const CallEvent &Call, const Decl *D,
+                        const ExplodedNode *Pred);
+
+  bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
+                  ExplodedNode *Pred, ProgramStateRef State);
+
+  /// \brief Conservatively evaluate call by invalidating regions and binding
+  /// a conjured return value.
+  void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
+                            ExplodedNode *Pred, ProgramStateRef State);
+
+  /// \brief Either inline or process the call conservatively (or both), based
+  /// on DynamicDispatchBifurcation data.
+  void BifurcateCall(const MemRegion *BifurReg,
+                     const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
+                     ExplodedNode *Pred);
+
+  bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
+
+  /// Models a trivial copy or move constructor or trivial assignment operator
+  /// call with a simple bind.
+  void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
+                          const CallEvent &Call);
+
+  /// If the value of the given expression is a NonLoc, copy it into a new
+  /// temporary object region, and replace the value of the expression with
+  /// that.
+  ///
+  /// If \p ResultE is provided, the new region will be bound to this expression
+  /// instead of \p E.
+  ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
+                                                const LocationContext *LC,
+                                                const Expr *E,
+                                                const Expr *ResultE = nullptr);
+};
+
+/// Traits for storing the call processing policy inside GDM.
+/// The GDM stores the corresponding CallExpr pointer.
+// FIXME: This does not use the nice trait macros because it must be accessible
+// from multiple translation units.
+struct ReplayWithoutInlining{};
+template <>
+struct ProgramStateTrait<ReplayWithoutInlining> :
+  public ProgramStatePartialTrait<const void*> {
+  static void *GDMIndex() { static int index = 0; return &index; }
+};
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
new file mode 100644
index 0000000..169af93
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -0,0 +1,140 @@
+//== FunctionSummary.h - Stores summaries of functions. ------------*- 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 summary of a function gathered/used by static analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
+#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include <deque>
+
+namespace clang {
+class Decl;
+
+namespace ento {
+typedef std::deque<Decl*> SetOfDecls;
+typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
+
+class FunctionSummariesTy {
+  class FunctionSummary {
+  public:
+    /// Marks the IDs of the basic blocks visited during the analyzes.
+    llvm::SmallBitVector VisitedBasicBlocks;
+
+    /// Total number of blocks in the function.
+    unsigned TotalBasicBlocks : 30;
+
+    /// True if this function has been checked against the rules for which
+    /// functions may be inlined.
+    unsigned InlineChecked : 1;
+
+    /// True if this function may be inlined.
+    unsigned MayInline : 1;
+
+    /// The number of times the function has been inlined.
+    unsigned TimesInlined : 32;
+
+    FunctionSummary() :
+      TotalBasicBlocks(0),
+      InlineChecked(0),
+      TimesInlined(0) {}
+  };
+
+  typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
+  MapTy Map;
+
+public:
+  MapTy::iterator findOrInsertSummary(const Decl *D) {
+    MapTy::iterator I = Map.find(D);
+    if (I != Map.end())
+      return I;
+
+    typedef std::pair<const Decl *, FunctionSummary> KVPair;
+    I = Map.insert(KVPair(D, FunctionSummary())).first;
+    assert(I != Map.end());
+    return I;
+  }
+
+  void markMayInline(const Decl *D) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    I->second.InlineChecked = 1;
+    I->second.MayInline = 1;
+  }
+
+  void markShouldNotInline(const Decl *D) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    I->second.InlineChecked = 1;
+    I->second.MayInline = 0;
+  }
+
+  void markReachedMaxBlockCount(const Decl *D) {
+    markShouldNotInline(D);
+  }
+
+  Optional<bool> mayInline(const Decl *D) {
+    MapTy::const_iterator I = Map.find(D);
+    if (I != Map.end() && I->second.InlineChecked)
+      return I->second.MayInline;
+    return None;
+  }
+
+  void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
+    assert(ID < TotalIDs);
+    if (TotalIDs > Blocks.size()) {
+      Blocks.resize(TotalIDs);
+      I->second.TotalBasicBlocks = TotalIDs;
+    }
+    Blocks.set(ID);
+  }
+
+  unsigned getNumVisitedBasicBlocks(const Decl* D) {
+    MapTy::const_iterator I = Map.find(D);
+    if (I != Map.end())
+      return I->second.VisitedBasicBlocks.count();
+    return 0;
+  }
+
+  unsigned getNumTimesInlined(const Decl* D) {
+    MapTy::const_iterator I = Map.find(D);
+    if (I != Map.end())
+      return I->second.TimesInlined;
+    return 0;
+  }
+
+  void bumpNumTimesInlined(const Decl* D) {
+    MapTy::iterator I = findOrInsertSummary(D);
+    I->second.TimesInlined++;
+  }
+
+  /// Get the percentage of the reachable blocks.
+  unsigned getPercentBlocksReachable(const Decl *D) {
+    MapTy::const_iterator I = Map.find(D);
+      if (I != Map.end())
+        return ((I->second.VisitedBasicBlocks.count() * 100) /
+                 I->second.TotalBasicBlocks);
+    return 0;
+  }
+
+  unsigned getTotalNumBasicBlocks();
+  unsigned getTotalNumVisitedBasicBlocks();
+
+};
+
+}} // end clang ento namespaces
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
new file mode 100644
index 0000000..92b082d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -0,0 +1,1364 @@
+//== MemRegion.h - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses.  MemRegion defines a
+//  partially-typed abstraction of memory useful for path-sensitive dataflow
+//  analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_MEMREGION_H
+#define LLVM_CLANG_GR_MEMREGION_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <string>
+
+namespace clang {
+
+class LocationContext;
+class StackFrameContext;
+
+namespace ento {
+
+class CodeTextRegion;
+class MemRegionManager;
+class MemSpaceRegion;
+class SValBuilder;
+class SymbolicRegion;
+class VarRegion;
+
+/// Represent a region's offset within the top level base region.
+class RegionOffset {
+  /// The base region.
+  const MemRegion *R;
+
+  /// The bit offset within the base region. It shouldn't be negative.
+  int64_t Offset;
+
+public:
+  // We're using a const instead of an enumeration due to the size required;
+  // Visual Studio will only create enumerations of size int, not long long.
+  static const int64_t Symbolic = INT64_MAX;
+
+  RegionOffset() : R(nullptr) {}
+  RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
+
+  const MemRegion *getRegion() const { return R; }
+
+  bool hasSymbolicOffset() const { return Offset == Symbolic; }
+
+  int64_t getOffset() const {
+    assert(!hasSymbolicOffset());
+    return Offset;
+  }
+
+  bool isValid() const { return R; }
+};
+
+//===----------------------------------------------------------------------===//
+// Base region classes.
+//===----------------------------------------------------------------------===//
+
+/// MemRegion - The root abstract class for all memory regions.
+class MemRegion : public llvm::FoldingSetNode {
+  friend class MemRegionManager;
+public:
+  enum Kind {
+    // Memory spaces.
+    GenericMemSpaceRegionKind,
+    StackLocalsSpaceRegionKind,
+    StackArgumentsSpaceRegionKind,
+    HeapSpaceRegionKind,
+    UnknownSpaceRegionKind,
+    StaticGlobalSpaceRegionKind,
+    GlobalInternalSpaceRegionKind,
+    GlobalSystemSpaceRegionKind,
+    GlobalImmutableSpaceRegionKind,
+    BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
+    END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
+    BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
+    END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
+    BEG_MEMSPACES = GenericMemSpaceRegionKind,
+    END_MEMSPACES = GlobalImmutableSpaceRegionKind,
+    // Untyped regions.
+    SymbolicRegionKind,
+    AllocaRegionKind,
+    // Typed regions.
+    BEG_TYPED_REGIONS,
+    FunctionTextRegionKind = BEG_TYPED_REGIONS,
+    BlockTextRegionKind,
+    BlockDataRegionKind,
+    BEG_TYPED_VALUE_REGIONS,
+    CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
+    CXXThisRegionKind,
+    StringRegionKind,
+    ObjCStringRegionKind,
+    ElementRegionKind,
+    // Decl Regions.
+    BEG_DECL_REGIONS,
+    VarRegionKind = BEG_DECL_REGIONS,
+    FieldRegionKind,
+    ObjCIvarRegionKind,
+    END_DECL_REGIONS = ObjCIvarRegionKind,
+    CXXTempObjectRegionKind,
+    CXXBaseObjectRegionKind,
+    END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
+    END_TYPED_REGIONS = CXXBaseObjectRegionKind
+  };
+    
+private:
+  const Kind kind;
+
+protected:
+  MemRegion(Kind k) : kind(k) {}
+  virtual ~MemRegion();
+
+public:
+  ASTContext &getContext() const;
+
+  virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
+
+  virtual MemRegionManager* getMemRegionManager() const = 0;
+
+  const MemSpaceRegion *getMemorySpace() const;
+
+  const MemRegion *getBaseRegion() const;
+
+  /// Check if the region is a subregion of the given region.
+  virtual bool isSubRegionOf(const MemRegion *R) const;
+
+  const MemRegion *StripCasts(bool StripBaseCasts = true) const;
+
+  /// \brief If this is a symbolic region, returns the region. Otherwise,
+  /// goes up the base chain looking for the first symbolic base region.
+  const SymbolicRegion *getSymbolicBase() const;
+
+  bool hasGlobalsOrParametersStorage() const;
+
+  bool hasStackStorage() const;
+  
+  bool hasStackNonParametersStorage() const;
+  
+  bool hasStackParametersStorage() const;
+
+  /// Compute the offset within the top level memory object.
+  RegionOffset getAsOffset() const;
+
+  /// \brief Get a string representation of a region for debug use.
+  std::string getString() const;
+
+  virtual void dumpToStream(raw_ostream &os) const;
+
+  void dump() const;
+
+  /// \brief Returns true if this region can be printed in a user-friendly way.
+  virtual bool canPrintPretty() const;
+
+  /// \brief Print the region for use in diagnostics.
+  virtual void printPretty(raw_ostream &os) const;
+
+  /// \brief Returns true if this region's textual representation can be used
+  /// as part of a larger expression.
+  virtual bool canPrintPrettyAsExpr() const;
+
+  /// \brief Print the region as expression.
+  ///
+  /// When this region represents a subexpression, the method is for printing
+  /// an expression containing it.
+  virtual void printPrettyAsExpr(raw_ostream &os) const;
+
+  Kind getKind() const { return kind; }
+
+  template<typename RegionTy> const RegionTy* getAs() const;
+
+  virtual bool isBoundable() const { return false; }
+};
+
+/// MemSpaceRegion - A memory region that represents a "memory space";
+///  for example, the set of global variables, the stack frame, etc.
+class MemSpaceRegion : public MemRegion {
+protected:
+  friend class MemRegionManager;
+  
+  MemRegionManager *Mgr;
+
+  MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
+    : MemRegion(k), Mgr(mgr) {
+    assert(classof(this));
+  }
+
+  MemRegionManager* getMemRegionManager() const override { return Mgr; }
+
+public:
+  bool isBoundable() const override { return false; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
+  }
+};
+  
+class GlobalsSpaceRegion : public MemSpaceRegion {
+  virtual void anchor();
+protected:
+  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
+    : MemSpaceRegion(mgr, k) {}
+public:
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
+  }
+};
+
+/// \brief The region of the static variables within the current CodeTextRegion
+/// scope.
+///
+/// Currently, only the static locals are placed there, so we know that these
+/// variables do not get invalidated by calls to other functions.
+class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+  friend class MemRegionManager;
+
+  const CodeTextRegion *CR;
+  
+  StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
+    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  const CodeTextRegion *getCodeRegion() const { return CR; }
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StaticGlobalSpaceRegionKind;
+  }
+};
+
+/// \brief The region for all the non-static global variables.
+///
+/// This class is further split into subclasses for efficient implementation of
+/// invalidating a set of related global values as is done in
+/// RegionStoreManager::invalidateRegions (instead of finding all the dependent
+/// globals, we invalidate the whole parent region).
+class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+  friend class MemRegionManager;
+  
+protected:
+  NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
+    : GlobalsSpaceRegion(mgr, k) {}
+  
+public:
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
+           k <= END_NON_STATIC_GLOBAL_MEMSPACES;
+  }
+};
+
+/// \brief The region containing globals which are defined in system/external
+/// headers and are considered modifiable by system calls (ex: errno).
+class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
+  friend class MemRegionManager;
+
+  GlobalSystemSpaceRegion(MemRegionManager *mgr)
+    : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
+
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == GlobalSystemSpaceRegionKind;
+  }
+};
+
+/// \brief The region containing globals which are considered not to be modified
+/// or point to data which could be modified as a result of a function call
+/// (system or internal). Ex: Const global scalars would be modeled as part of
+/// this region. This region also includes most system globals since they have
+/// low chance of being modified.
+class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
+  friend class MemRegionManager;
+
+  GlobalImmutableSpaceRegion(MemRegionManager *mgr)
+    : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
+
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == GlobalImmutableSpaceRegionKind;
+  }
+};
+
+/// \brief The region containing globals which can be modified by calls to
+/// "internally" defined functions - (for now just) functions other then system
+/// calls.
+class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
+  friend class MemRegionManager;
+
+  GlobalInternalSpaceRegion(MemRegionManager *mgr)
+    : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
+
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == GlobalInternalSpaceRegionKind;
+  }
+};
+
+class HeapSpaceRegion : public MemSpaceRegion {
+  virtual void anchor();
+  friend class MemRegionManager;
+  
+  HeapSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == HeapSpaceRegionKind;
+  }
+};
+  
+class UnknownSpaceRegion : public MemSpaceRegion {
+  virtual void anchor();
+  friend class MemRegionManager;
+  UnknownSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == UnknownSpaceRegionKind;
+  }
+};
+  
+class StackSpaceRegion : public MemSpaceRegion {
+private:
+  const StackFrameContext *SFC;
+
+protected:
+  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
+    : MemSpaceRegion(mgr, k), SFC(sfc) {
+    assert(classof(this));
+  }
+
+public:  
+  const StackFrameContext *getStackFrame() const { return SFC; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= StackLocalsSpaceRegionKind &&
+           k <= StackArgumentsSpaceRegionKind;
+  }  
+};
+  
+class StackLocalsSpaceRegion : public StackSpaceRegion {
+  virtual void anchor();
+  friend class MemRegionManager;
+  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackLocalsSpaceRegionKind;
+  }
+};
+
+class StackArgumentsSpaceRegion : public StackSpaceRegion {
+private:
+  virtual void anchor();
+  friend class MemRegionManager;
+  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackArgumentsSpaceRegionKind;
+  }
+};
+
+
+/// SubRegion - A region that subsets another larger region.  Most regions
+///  are subclasses of SubRegion.
+class SubRegion : public MemRegion {
+private:
+  virtual void anchor();
+protected:
+  const MemRegion* superRegion;
+  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
+public:
+  const MemRegion* getSuperRegion() const {
+    return superRegion;
+  }
+
+  /// getExtent - Returns the size of the region in bytes.
+  virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
+    return UnknownVal();
+  }
+
+  MemRegionManager* getMemRegionManager() const override;
+
+  bool isSubRegionOf(const MemRegion* R) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() > END_MEMSPACES;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// MemRegion subclasses.
+//===----------------------------------------------------------------------===//
+
+/// AllocaRegion - A region that represents an untyped blob of bytes created
+///  by a call to 'alloca'.
+class AllocaRegion : public SubRegion {
+  friend class MemRegionManager;
+protected:
+  unsigned Cnt; // Block counter.  Used to distinguish different pieces of
+                // memory allocated by alloca at the same call site.
+  const Expr *Ex;
+
+  AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
+    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
+
+public:
+
+  const Expr *getExpr() const { return Ex; }
+
+  bool isBoundable() const override { return true; }
+
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
+                            unsigned Cnt, const MemRegion *superRegion);
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == AllocaRegionKind;
+  }
+};
+
+/// TypedRegion - An abstract class representing regions that are typed.
+class TypedRegion : public SubRegion {
+public:
+  void anchor() override;
+protected:
+  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
+
+public:
+  virtual QualType getLocationType() const = 0;
+
+  QualType getDesugaredLocationType(ASTContext &Context) const {
+    return getLocationType().getDesugaredType(Context);
+  }
+
+  bool isBoundable() const override { return true; }
+
+  static bool classof(const MemRegion* R) {
+    unsigned k = R->getKind();
+    return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
+  }
+};
+
+/// TypedValueRegion - An abstract class representing regions having a typed value.
+class TypedValueRegion : public TypedRegion {
+public:
+  void anchor() override;
+protected:
+  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
+
+public:
+  virtual QualType getValueType() const = 0;
+
+  QualType getLocationType() const override {
+    // FIXME: We can possibly optimize this later to cache this value.
+    QualType T = getValueType();
+    ASTContext &ctx = getContext();
+    if (T->getAs<ObjCObjectType>())
+      return ctx.getObjCObjectPointerType(T);
+    return ctx.getPointerType(getValueType());
+  }
+
+  QualType getDesugaredValueType(ASTContext &Context) const {
+    QualType T = getValueType();
+    return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
+  }
+
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
+
+  static bool classof(const MemRegion* R) {
+    unsigned k = R->getKind();
+    return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
+  }
+};
+
+
+class CodeTextRegion : public TypedRegion {
+public:
+  void anchor() override;
+protected:
+  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
+public:
+  bool isBoundable() const override { return false; }
+
+  static bool classof(const MemRegion* R) {
+    Kind k = R->getKind();
+    return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
+  }
+};
+
+/// FunctionTextRegion - A region that represents code texts of function.
+class FunctionTextRegion : public CodeTextRegion {
+  const NamedDecl *FD;
+public:
+  FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg)
+    : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
+    assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
+  }
+
+  QualType getLocationType() const override {
+    const ASTContext &Ctx = getContext();
+    if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
+      return Ctx.getPointerType(D->getType());
+    }
+
+    assert(isa<ObjCMethodDecl>(FD));
+    assert(false && "Getting the type of ObjCMethod is not supported yet");
+
+    // TODO: We might want to return a different type here (ex: id (*ty)(...))
+    //       depending on how it is used.
+    return QualType();
+  }
+
+  const NamedDecl *getDecl() const {
+    return FD;
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
+                            const MemRegion*);
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == FunctionTextRegionKind;
+  }
+};
+  
+  
+/// BlockTextRegion - A region that represents code texts of blocks (closures).
+///  Blocks are represented with two kinds of regions.  BlockTextRegions
+///  represent the "code", while BlockDataRegions represent instances of blocks,
+///  which correspond to "code+data".  The distinction is important, because
+///  like a closure a block captures the values of externally referenced
+///  variables.
+class BlockTextRegion : public CodeTextRegion {
+  friend class MemRegionManager;
+
+  const BlockDecl *BD;
+  AnalysisDeclContext *AC;
+  CanQualType locTy;
+
+  BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
+                  AnalysisDeclContext *ac, const MemRegion* sreg)
+    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+
+public:
+  QualType getLocationType() const override {
+    return locTy;
+  }
+  
+  const BlockDecl *getDecl() const {
+    return BD;
+  }
+
+  AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
+
+  virtual void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
+                            CanQualType, const AnalysisDeclContext*,
+                            const MemRegion*);
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == BlockTextRegionKind;
+  }
+};
+  
+/// BlockDataRegion - A region that represents a block instance.
+///  Blocks are represented with two kinds of regions.  BlockTextRegions
+///  represent the "code", while BlockDataRegions represent instances of blocks,
+///  which correspond to "code+data".  The distinction is important, because
+///  like a closure a block captures the values of externally referenced
+///  variables.
+class BlockDataRegion : public TypedRegion {
+  friend class MemRegionManager;
+  const BlockTextRegion *BC;
+  const LocationContext *LC; // Can be null */
+  unsigned BlockCount;
+  void *ReferencedVars;
+  void *OriginalVars;
+
+  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
+                  unsigned count, const MemRegion *sreg)
+  : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
+     BlockCount(count),
+    ReferencedVars(nullptr), OriginalVars(nullptr) {}
+
+public:
+  const BlockTextRegion *getCodeRegion() const { return BC; }
+  
+  const BlockDecl *getDecl() const { return BC->getDecl(); }
+
+  QualType getLocationType() const override { return BC->getLocationType(); }
+
+  class referenced_vars_iterator {
+    const MemRegion * const *R;
+    const MemRegion * const *OriginalR;
+  public:
+    explicit referenced_vars_iterator(const MemRegion * const *r,
+                                      const MemRegion * const *originalR)
+      : R(r), OriginalR(originalR) {}
+
+    const VarRegion *getCapturedRegion() const {
+      return cast<VarRegion>(*R);
+    }
+    const VarRegion *getOriginalRegion() const {
+      return cast<VarRegion>(*OriginalR);
+    }
+
+    bool operator==(const referenced_vars_iterator &I) const {
+      assert((R == nullptr) == (I.R == nullptr));
+      return I.R == R;
+    }
+    bool operator!=(const referenced_vars_iterator &I) const {
+      assert((R == nullptr) == (I.R == nullptr));
+      return I.R != R;
+    }
+    referenced_vars_iterator &operator++() {
+      ++R;
+      ++OriginalR;
+      return *this;
+    }
+  };
+
+  /// Return the original region for a captured region, if
+  /// one exists.
+  const VarRegion *getOriginalRegion(const VarRegion *VR) const;
+      
+  referenced_vars_iterator referenced_vars_begin() const;
+  referenced_vars_iterator referenced_vars_end() const;  
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
+                            const LocationContext *, unsigned,
+                            const MemRegion *);
+    
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == BlockDataRegionKind;
+  }
+private:
+  void LazyInitializeReferencedVars();
+  std::pair<const VarRegion *, const VarRegion *>
+  getCaptureRegions(const VarDecl *VD);
+};
+
+/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
+///  clases, SymbolicRegion represents a region that serves as an alias for
+///  either a real region, a NULL pointer, etc.  It essentially is used to
+///  map the concept of symbolic values into the domain of regions.  Symbolic
+///  regions do not need to be typed.
+class SymbolicRegion : public SubRegion {
+protected:
+  const SymbolRef sym;
+
+public:
+  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
+    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
+
+  SymbolRef getSymbol() const {
+    return sym;
+  }
+
+  bool isBoundable() const override { return true; }
+
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            SymbolRef sym,
+                            const MemRegion* superRegion);
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == SymbolicRegionKind;
+  }
+};
+
+/// StringRegion - Region associated with a StringLiteral.
+class StringRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+  const StringLiteral* Str;
+protected:
+
+  StringRegion(const StringLiteral* str, const MemRegion* sreg)
+    : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            const StringLiteral* Str,
+                            const MemRegion* superRegion);
+
+public:
+
+  const StringLiteral* getStringLiteral() const { return Str; }
+
+  QualType getValueType() const override {
+    return Str->getType();
+  }
+
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
+
+  bool isBoundable() const override { return false; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override {
+    ProfileRegion(ID, Str, superRegion);
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == StringRegionKind;
+  }
+};
+  
+/// The region associated with an ObjCStringLiteral.
+class ObjCStringRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+  const ObjCStringLiteral* Str;
+protected:
+  
+  ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
+  : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
+  
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            const ObjCStringLiteral* Str,
+                            const MemRegion* superRegion);
+  
+public:
+  
+  const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
+
+  QualType getValueType() const override {
+    return Str->getType();
+  }
+
+  bool isBoundable() const override { return false; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override {
+    ProfileRegion(ID, Str, superRegion);
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ObjCStringRegionKind;
+  }
+};
+
+/// CompoundLiteralRegion - A memory region representing a compound literal.
+///   Compound literals are essentially temporaries that are stack allocated
+///   or in the global constant pool.
+class CompoundLiteralRegion : public TypedValueRegion {
+private:
+  friend class MemRegionManager;
+  const CompoundLiteralExpr *CL;
+
+  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
+    : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+                            const CompoundLiteralExpr *CL,
+                            const MemRegion* superRegion);
+public:
+  QualType getValueType() const override {
+    return CL->getType();
+  }
+
+  bool isBoundable() const override { return !CL->isFileScope(); }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CompoundLiteralRegionKind;
+  }
+};
+
+class DeclRegion : public TypedValueRegion {
+protected:
+  const Decl *D;
+
+  DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
+    : TypedValueRegion(sReg, k), D(d) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
+                      const MemRegion* superRegion, Kind k);
+
+public:
+  const Decl *getDecl() const { return D; }
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static bool classof(const MemRegion* R) {
+    unsigned k = R->getKind();
+    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
+  }
+};
+
+class VarRegion : public DeclRegion {
+  friend class MemRegionManager;
+
+  // Constructors and private methods.
+  VarRegion(const VarDecl *vd, const MemRegion* sReg)
+    : DeclRegion(vd, sReg, VarRegionKind) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
+                            const MemRegion *superRegion) {
+    DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+public:
+  const VarDecl *getDecl() const { return cast<VarDecl>(D); }
+
+  const StackFrameContext *getStackFrame() const;
+
+  QualType getValueType() const override {
+    // FIXME: We can cache this if needed.
+    return getDecl()->getType();
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == VarRegionKind;
+  }
+
+  bool canPrintPrettyAsExpr() const override;
+
+  void printPrettyAsExpr(raw_ostream &os) const override;
+};
+  
+/// CXXThisRegion - Represents the region for the implicit 'this' parameter
+///  in a call to a C++ method.  This region doesn't represent the object
+///  referred to by 'this', but rather 'this' itself.
+class CXXThisRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+  CXXThisRegion(const PointerType *thisPointerTy,
+                const MemRegion *sReg)
+    : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+                            const PointerType *PT,
+                            const MemRegion *sReg);
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+public:
+  QualType getValueType() const override {
+    return QualType(ThisPointerTy, 0);
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CXXThisRegionKind;
+  }
+
+private:
+  const PointerType *ThisPointerTy;
+};
+
+class FieldRegion : public DeclRegion {
+  friend class MemRegionManager;
+
+  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
+    : DeclRegion(fd, sReg, FieldRegionKind) {}
+
+public:
+  const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
+
+  QualType getValueType() const override {
+    // FIXME: We can cache this if needed.
+    return getDecl()->getType();
+  }
+
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
+                            const MemRegion* superRegion) {
+    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
+  }
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == FieldRegionKind;
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  bool canPrintPretty() const override;
+  void printPretty(raw_ostream &os) const override;
+  bool canPrintPrettyAsExpr() const override;
+  void printPrettyAsExpr(raw_ostream &os) const override;
+};
+
+class ObjCIvarRegion : public DeclRegion {
+
+  friend class MemRegionManager;
+
+  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
+                            const MemRegion* superRegion);
+
+public:
+  const ObjCIvarDecl *getDecl() const;
+  QualType getValueType() const override;
+
+  bool canPrintPrettyAsExpr() const override;
+  void printPrettyAsExpr(raw_ostream &os) const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ObjCIvarRegionKind;
+  }
+};
+//===----------------------------------------------------------------------===//
+// Auxiliary data classes for use with MemRegions.
+//===----------------------------------------------------------------------===//
+
+class ElementRegion;
+
+class RegionRawOffset {
+private:
+  friend class ElementRegion;
+
+  const MemRegion *Region;
+  CharUnits Offset;
+
+  RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
+    : Region(reg), Offset(offset) {}
+
+public:
+  // FIXME: Eventually support symbolic offsets.
+  CharUnits getOffset() const { return Offset; }
+  const MemRegion *getRegion() const { return Region; }
+
+  void dumpToStream(raw_ostream &os) const;
+  void dump() const;
+};
+
+/// \brief ElementRegin is used to represent both array elements and casts.
+class ElementRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+
+  QualType ElementType;
+  NonLoc Index;
+
+  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
+    : TypedValueRegion(sReg, ElementRegionKind),
+      ElementType(elementType), Index(Idx) {
+    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
+            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
+           "The index must be signed");
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
+                            SVal Idx, const MemRegion* superRegion);
+
+public:
+
+  NonLoc getIndex() const { return Index; }
+
+  QualType getValueType() const override {
+    return ElementType;
+  }
+
+  QualType getElementType() const {
+    return ElementType;
+  }
+  /// Compute the offset within the array. The array might also be a subobject.
+  RegionRawOffset getAsArrayOffset() const;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == ElementRegionKind;
+  }
+};
+
+// C++ temporary object associated with an expression.
+class CXXTempObjectRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+
+  Expr const *Ex;
+
+  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 
+    : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+                            Expr const *E, const MemRegion *sReg);
+  
+public:
+  const Expr *getExpr() const { return Ex; }
+
+  QualType getValueType() const override {
+    return Ex->getType();
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == CXXTempObjectRegionKind;
+  }
+};
+
+// CXXBaseObjectRegion represents a base object within a C++ object. It is 
+// identified by the base class declaration and the region of its parent object.
+class CXXBaseObjectRegion : public TypedValueRegion {
+  friend class MemRegionManager;
+
+  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
+
+  CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
+                      const MemRegion *SReg)
+    : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
+                            bool IsVirtual, const MemRegion *SReg);
+
+public:
+  const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
+  bool isVirtual() const { return Data.getInt(); }
+
+  QualType getValueType() const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  static bool classof(const MemRegion *region) {
+    return region->getKind() == CXXBaseObjectRegionKind;
+  }
+
+  bool canPrintPrettyAsExpr() const override;
+
+  void printPrettyAsExpr(raw_ostream &os) const override;
+};
+
+template<typename RegionTy>
+const RegionTy* MemRegion::getAs() const {
+  if (const RegionTy* RT = dyn_cast<RegionTy>(this))
+    return RT;
+
+  return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// MemRegionManager - Factory object for creating regions.
+//===----------------------------------------------------------------------===//
+
+class MemRegionManager {
+  ASTContext &C;
+  llvm::BumpPtrAllocator& A;
+  llvm::FoldingSet<MemRegion> Regions;
+
+  GlobalInternalSpaceRegion *InternalGlobals;
+  GlobalSystemSpaceRegion *SystemGlobals;
+  GlobalImmutableSpaceRegion *ImmutableGlobals;
+
+  
+  llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 
+    StackLocalsSpaceRegions;
+  llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
+    StackArgumentsSpaceRegions;
+  llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
+    StaticsGlobalSpaceRegions;
+
+  HeapSpaceRegion *heap;
+  UnknownSpaceRegion *unknown;
+  MemSpaceRegion *code;
+
+public:
+  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a)
+    : C(c), A(a), InternalGlobals(nullptr), SystemGlobals(nullptr),
+      ImmutableGlobals(nullptr), heap(nullptr), unknown(nullptr),
+      code(nullptr) {}
+
+  ~MemRegionManager();
+
+  ASTContext &getContext() { return C; }
+  
+  llvm::BumpPtrAllocator &getAllocator() { return A; }
+
+  /// getStackLocalsRegion - Retrieve the memory region associated with the
+  ///  specified stack frame.
+  const StackLocalsSpaceRegion *
+  getStackLocalsRegion(const StackFrameContext *STC);
+
+  /// getStackArgumentsRegion - Retrieve the memory region associated with
+  ///  function/method arguments of the specified stack frame.
+  const StackArgumentsSpaceRegion *
+  getStackArgumentsRegion(const StackFrameContext *STC);
+
+  /// getGlobalsRegion - Retrieve the memory region associated with
+  ///  global variables.
+  const GlobalsSpaceRegion *getGlobalsRegion(
+      MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
+      const CodeTextRegion *R = nullptr);
+
+  /// getHeapRegion - Retrieve the memory region associated with the
+  ///  generic "heap".
+  const HeapSpaceRegion *getHeapRegion();
+
+  /// getUnknownRegion - Retrieve the memory region associated with unknown
+  /// memory space.
+  const MemSpaceRegion *getUnknownRegion();
+
+  const MemSpaceRegion *getCodeRegion();
+
+  /// getAllocaRegion - Retrieve a region associated with a call to alloca().
+  const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
+                                      const LocationContext *LC);
+
+  /// getCompoundLiteralRegion - Retrieve the region associated with a
+  ///  given CompoundLiteral.
+  const CompoundLiteralRegion*
+  getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
+                           const LocationContext *LC);
+  
+  /// getCXXThisRegion - Retrieve the [artificial] region associated with the
+  ///  parameter 'this'.
+  const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
+                                        const LocationContext *LC);
+
+  /// \brief Retrieve or create a "symbolic" memory region.
+  const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
+
+  /// \brief Return a unique symbolic region belonging to heap memory space.
+  const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
+
+  const StringRegion *getStringRegion(const StringLiteral* Str);
+
+  const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
+
+  /// getVarRegion - Retrieve or create the memory region associated with
+  ///  a specified VarDecl and LocationContext.
+  const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+
+  /// getVarRegion - Retrieve or create the memory region associated with
+  ///  a specified VarDecl and super region.
+  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
+  
+  /// getElementRegion - Retrieve the memory region associated with the
+  ///  associated element type, index, and super region.
+  const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
+                                        const MemRegion *superRegion,
+                                        ASTContext &Ctx);
+
+  const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
+                                                 const MemRegion *superRegion) {
+    return getElementRegion(ER->getElementType(), ER->getIndex(),
+                            superRegion, ER->getContext());
+  }
+
+  /// getFieldRegion - Retrieve or create the memory region associated with
+  ///  a specified FieldDecl.  'superRegion' corresponds to the containing
+  ///  memory region (which typically represents the memory representing
+  ///  a structure or class).
+  const FieldRegion *getFieldRegion(const FieldDecl *fd,
+                                    const MemRegion* superRegion);
+
+  const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
+                                             const MemRegion *superRegion) {
+    return getFieldRegion(FR->getDecl(), superRegion);
+  }
+
+  /// getObjCIvarRegion - Retrieve or create the memory region associated with
+  ///   a specified Objective-c instance variable.  'superRegion' corresponds
+  ///   to the containing region (which typically represents the Objective-C
+  ///   object).
+  const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
+                                          const MemRegion* superRegion);
+
+  const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
+                                                    LocationContext const *LC);
+
+  /// Create a CXXBaseObjectRegion with the given base class for region
+  /// \p Super.
+  ///
+  /// The type of \p Super is assumed be a class deriving from \p BaseClass.
+  const CXXBaseObjectRegion *
+  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
+                         bool IsVirtual);
+
+  /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
+  /// super region.
+  const CXXBaseObjectRegion *
+  getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 
+                                  const MemRegion *superRegion) {
+    return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
+                                  baseReg->isVirtual());
+  }
+
+  const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
+  const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
+                                            CanQualType locTy,
+                                            AnalysisDeclContext *AC);
+  
+  /// getBlockDataRegion - Get the memory region associated with an instance
+  ///  of a block.  Unlike many other MemRegions, the LocationContext*
+  ///  argument is allowed to be NULL for cases where we have no known
+  ///  context.
+  const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
+                                            const LocationContext *lc,
+                                            unsigned blockCount);
+
+  /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
+  /// by static references. This differs from getCXXTempObjectRegion in the
+  /// super-region used.
+  const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
+
+private:
+  template <typename RegionTy, typename A1>
+  RegionTy* getRegion(const A1 a1);
+
+  template <typename RegionTy, typename A1>
+  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
+
+  template <typename RegionTy, typename A1, typename A2>
+  RegionTy* getRegion(const A1 a1, const A2 a2);
+
+  template <typename RegionTy, typename A1, typename A2>
+  RegionTy* getSubRegion(const A1 a1, const A2 a2,
+                         const MemRegion* superRegion);
+
+  template <typename RegionTy, typename A1, typename A2, typename A3>
+  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+                         const MemRegion* superRegion);
+  
+  template <typename REG>
+  const REG* LazyAllocate(REG*& region);
+  
+  template <typename REG, typename ARG>
+  const REG* LazyAllocate(REG*& region, ARG a);
+};
+
+//===----------------------------------------------------------------------===//
+// Out-of-line member definitions.
+//===----------------------------------------------------------------------===//
+
+inline ASTContext &MemRegion::getContext() const {
+  return getMemRegionManager()->getContext();
+}
+
+//===----------------------------------------------------------------------===//
+// Means for storing region/symbol handling traits.
+//===----------------------------------------------------------------------===//
+
+/// Information about invalidation for a particular region/symbol.
+class RegionAndSymbolInvalidationTraits {
+  typedef unsigned char StorageTypeForKinds;
+  llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap;
+  llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap;
+
+  typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator
+      const_region_iterator;
+  typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator
+      const_symbol_iterator;
+
+public:
+  /// \brief Describes different invalidation traits.
+  enum InvalidationKinds {
+    /// Tells that a region's contents is not changed.
+    TK_PreserveContents = 0x1,
+    /// Suppress pointer-escaping of a region.
+    TK_SuppressEscape = 0x2
+
+    // Do not forget to extend StorageTypeForKinds if number of traits exceed 
+    // the number of bits StorageTypeForKinds can store.
+  };
+
+  void setTrait(SymbolRef Sym, InvalidationKinds IK);
+  void setTrait(const MemRegion *MR, InvalidationKinds IK);
+  bool hasTrait(SymbolRef Sym, InvalidationKinds IK);
+  bool hasTrait(const MemRegion *MR, InvalidationKinds IK);
+};
+  
+} // end GR namespace
+
+} // end clang namespace
+
+//===----------------------------------------------------------------------===//
+// Pretty-printing regions.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+static inline raw_ostream &operator<<(raw_ostream &os,
+                                      const clang::ento::MemRegion* R) {
+  R->dumpToStream(os);
+  return os;
+}
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
new file mode 100644
index 0000000..4902ef5
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -0,0 +1,819 @@
+//== ProgramState.h - Path-sensitive "State" for tracking values -*- 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 state of the program along the analysisa path.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_VALUESTATE_H
+#define LLVM_CLANG_GR_VALUESTATE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Environment.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+class APSInt;
+}
+
+namespace clang {
+class ASTContext;
+
+namespace ento {
+
+class CallEvent;
+class CallEventManager;
+
+typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
+                                                       SubEngine*);
+typedef StoreManager* (*StoreManagerCreator)(ProgramStateManager&);
+
+//===----------------------------------------------------------------------===//
+// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ProgramStatePartialTrait;
+
+template <typename T> struct ProgramStateTrait {
+  typedef typename T::data_type data_type;
+  static inline void *MakeVoidPtr(data_type D) { return (void*) D; }
+  static inline data_type MakeData(void *const* P) {
+    return P ? (data_type) *P : (data_type) 0;
+  }
+};
+
+/// \class ProgramState
+/// ProgramState - This class encapsulates:
+///
+///    1. A mapping from expressions to values (Environment)
+///    2. A mapping from locations to values (Store)
+///    3. Constraints on symbolic values (GenericDataMap)
+///
+///  Together these represent the "abstract state" of a program.
+///
+///  ProgramState is intended to be used as a functional object; that is,
+///  once it is created and made "persistent" in a FoldingSet, its
+///  values will never change.
+class ProgramState : public llvm::FoldingSetNode {
+public:
+  typedef llvm::ImmutableSet<llvm::APSInt*>                IntSetTy;
+  typedef llvm::ImmutableMap<void*, void*>                 GenericDataMap;
+
+private:
+  void operator=(const ProgramState& R) LLVM_DELETED_FUNCTION;
+
+  friend class ProgramStateManager;
+  friend class ExplodedGraph;
+  friend class ExplodedNode;
+
+  ProgramStateManager *stateMgr;
+  Environment Env;           // Maps a Stmt to its current SVal.
+  Store store;               // Maps a location to its current value.
+  GenericDataMap   GDM;      // Custom data stored by a client of this class.
+  unsigned refCount;
+
+  /// makeWithStore - Return a ProgramState with the same values as the current
+  ///  state with the exception of using the specified Store.
+  ProgramStateRef makeWithStore(const StoreRef &store) const;
+
+  void setStore(const StoreRef &storeRef);
+
+public:
+  /// This ctor is used when creating the first ProgramState object.
+  ProgramState(ProgramStateManager *mgr, const Environment& env,
+          StoreRef st, GenericDataMap gdm);
+    
+  /// Copy ctor - We must explicitly define this or else the "Next" ptr
+  ///  in FoldingSetNode will also get copied.
+  ProgramState(const ProgramState &RHS);
+  
+  ~ProgramState();
+
+  /// Return the ProgramStateManager associated with this state.
+  ProgramStateManager &getStateManager() const {
+    return *stateMgr;
+  }
+  
+  /// Return the ConstraintManager.
+  ConstraintManager &getConstraintManager() const;
+
+  /// getEnvironment - Return the environment associated with this state.
+  ///  The environment is the mapping from expressions to values.
+  const Environment& getEnvironment() const { return Env; }
+
+  /// Return the store associated with this state.  The store
+  ///  is a mapping from locations to values.
+  Store getStore() const { return store; }
+
+  
+  /// getGDM - Return the generic data map associated with this state.
+  GenericDataMap getGDM() const { return GDM; }
+
+  void setGDM(GenericDataMap gdm) { GDM = gdm; }
+
+  /// Profile - Profile the contents of a ProgramState object for use in a
+  ///  FoldingSet.  Two ProgramState objects are considered equal if they
+  ///  have the same Environment, Store, and GenericDataMap.
+  static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) {
+    V->Env.Profile(ID);
+    ID.AddPointer(V->store);
+    V->GDM.Profile(ID);
+  }
+
+  /// Profile - Used to profile the contents of this object for inclusion
+  ///  in a FoldingSet.
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, this);
+  }
+
+  BasicValueFactory &getBasicVals() const;
+  SymbolManager &getSymbolManager() const;
+
+  //==---------------------------------------------------------------------==//
+  // Constraints on values.
+  //==---------------------------------------------------------------------==//
+  //
+  // Each ProgramState records constraints on symbolic values.  These constraints
+  // are managed using the ConstraintManager associated with a ProgramStateManager.
+  // As constraints gradually accrue on symbolic values, added constraints
+  // may conflict and indicate that a state is infeasible (as no real values
+  // could satisfy all the constraints).  This is the principal mechanism
+  // for modeling path-sensitivity in ExprEngine/ProgramState.
+  //
+  // Various "assume" methods form the interface for adding constraints to
+  // symbolic values.  A call to 'assume' indicates an assumption being placed
+  // on one or symbolic values.  'assume' methods take the following inputs:
+  //
+  //  (1) A ProgramState object representing the current state.
+  //
+  //  (2) The assumed constraint (which is specific to a given "assume" method).
+  //
+  //  (3) A binary value "Assumption" that indicates whether the constraint is
+  //      assumed to be true or false.
+  //
+  // The output of "assume*" is a new ProgramState object with the added constraints.
+  // If no new state is feasible, NULL is returned.
+  //
+
+  /// Assumes that the value of \p cond is zero (if \p assumption is "false")
+  /// or non-zero (if \p assumption is "true").
+  ///
+  /// This returns a new state with the added constraint on \p cond.
+  /// If no new state is feasible, NULL is returned.
+  ProgramStateRef assume(DefinedOrUnknownSVal cond, bool assumption) const;
+
+  /// Assumes both "true" and "false" for \p cond, and returns both
+  /// corresponding states (respectively).
+  ///
+  /// This is more efficient than calling assume() twice. Note that one (but not
+  /// both) of the returned states may be NULL.
+  std::pair<ProgramStateRef, ProgramStateRef>
+  assume(DefinedOrUnknownSVal cond) const;
+
+  ProgramStateRef assumeInBound(DefinedOrUnknownSVal idx,
+                               DefinedOrUnknownSVal upperBound,
+                               bool assumption,
+                               QualType IndexType = QualType()) const;
+  
+  /// \brief Check if the given SVal is constrained to zero or is a zero
+  ///        constant.
+  ConditionTruthVal isNull(SVal V) const;
+  
+  /// Utility method for getting regions.
+  const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
+
+  //==---------------------------------------------------------------------==//
+  // Binding and retrieving values to/from the environment and symbolic store.
+  //==---------------------------------------------------------------------==//
+
+  /// Create a new state by binding the value 'V' to the statement 'S' in the
+  /// state's environment.
+  ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx,
+                               SVal V, bool Invalidate = true) const;
+
+  ProgramStateRef bindLoc(Loc location,
+                          SVal V,
+                          bool notifyChanges = true) const;
+
+  ProgramStateRef bindLoc(SVal location, SVal V) const;
+
+  ProgramStateRef bindDefault(SVal loc, SVal V) const;
+
+  ProgramStateRef killBinding(Loc LV) const;
+
+  /// \brief Returns the state with bindings for the given regions
+  ///  cleared from the store.
+  ///
+  /// Optionally invalidates global regions as well.
+  ///
+  /// \param Regions the set of regions to be invalidated.
+  /// \param E the expression that caused the invalidation.
+  /// \param BlockCount The number of times the current basic block has been
+  //         visited.
+  /// \param CausesPointerEscape the flag is set to true when
+  ///        the invalidation entails escape of a symbol (representing a
+  ///        pointer). For example, due to it being passed as an argument in a
+  ///        call.
+  /// \param IS the set of invalidated symbols.
+  /// \param Call if non-null, the invalidated regions represent parameters to
+  ///        the call and should be considered directly invalidated.
+  /// \param ITraits information about special handling for a particular 
+  ///        region/symbol.
+  ProgramStateRef
+  invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
+                    unsigned BlockCount, const LocationContext *LCtx,
+                    bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+                    const CallEvent *Call = nullptr,
+                    RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
+
+  ProgramStateRef
+  invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
+                    unsigned BlockCount, const LocationContext *LCtx,
+                    bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+                    const CallEvent *Call = nullptr,
+                    RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
+
+  /// enterStackFrame - Returns the state for entry to the given stack frame,
+  ///  preserving the current state.
+  ProgramStateRef enterStackFrame(const CallEvent &Call,
+                                  const StackFrameContext *CalleeCtx) const;
+
+  /// Get the lvalue for a variable reference.
+  Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
+
+  Loc getLValue(const CompoundLiteralExpr *literal, 
+                const LocationContext *LC) const;
+
+  /// Get the lvalue for an ivar reference.
+  SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
+
+  /// Get the lvalue for a field reference.
+  SVal getLValue(const FieldDecl *decl, SVal Base) const;
+
+  /// Get the lvalue for an indirect field reference.
+  SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const;
+
+  /// Get the lvalue for an array index.
+  SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
+
+  /// Returns the SVal bound to the statement 'S' in the state's environment.
+  SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
+  
+  SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
+
+  /// \brief Return the value bound to the specified location.
+  /// Returns UnknownVal() if none found.
+  SVal getSVal(Loc LV, QualType T = QualType()) const;
+
+  /// Returns the "raw" SVal bound to LV before any value simplfication.
+  SVal getRawSVal(Loc LV, QualType T= QualType()) const;
+
+  /// \brief Return the value bound to the specified location.
+  /// Returns UnknownVal() if none found.
+  SVal getSVal(const MemRegion* R) const;
+
+  SVal getSValAsScalarOrLoc(const MemRegion *R) const;
+  
+  /// \brief Visits the symbols reachable from the given SVal using the provided
+  /// SymbolVisitor.
+  ///
+  /// This is a convenience API. Consider using ScanReachableSymbols class
+  /// directly when making multiple scans on the same state with the same
+  /// visitor to avoid repeated initialization cost.
+  /// \sa ScanReachableSymbols
+  bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
+  
+  /// \brief Visits the symbols reachable from the SVals in the given range
+  /// using the provided SymbolVisitor.
+  bool scanReachableSymbols(const SVal *I, const SVal *E,
+                            SymbolVisitor &visitor) const;
+  
+  /// \brief Visits the symbols reachable from the regions in the given
+  /// MemRegions range using the provided SymbolVisitor.
+  bool scanReachableSymbols(const MemRegion * const *I, 
+                            const MemRegion * const *E,
+                            SymbolVisitor &visitor) const;
+
+  template <typename CB> CB scanReachableSymbols(SVal val) const;
+  template <typename CB> CB scanReachableSymbols(const SVal *beg,
+                                                 const SVal *end) const;
+  
+  template <typename CB> CB
+  scanReachableSymbols(const MemRegion * const *beg,
+                       const MemRegion * const *end) const;
+
+  /// Create a new state in which the statement is marked as tainted.
+  ProgramStateRef addTaint(const Stmt *S, const LocationContext *LCtx,
+                               TaintTagType Kind = TaintTagGeneric) const;
+
+  /// Create a new state in which the symbol is marked as tainted.
+  ProgramStateRef addTaint(SymbolRef S,
+                               TaintTagType Kind = TaintTagGeneric) const;
+
+  /// Create a new state in which the region symbol is marked as tainted.
+  ProgramStateRef addTaint(const MemRegion *R,
+                               TaintTagType Kind = TaintTagGeneric) const;
+
+  /// Check if the statement is tainted in the current state.
+  bool isTainted(const Stmt *S, const LocationContext *LCtx,
+                 TaintTagType Kind = TaintTagGeneric) const;
+  bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
+  bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
+  bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
+
+  /// \brief Get dynamic type information for a region.
+  DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const;
+
+  /// \brief Set dynamic type information of the region; return the new state.
+  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
+                                     DynamicTypeInfo NewTy) const;
+
+  /// \brief Set dynamic type information of the region; return the new state.
+  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
+                                     QualType NewTy,
+                                     bool CanBeSubClassed = true) const {
+    return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed));
+  }
+
+  //==---------------------------------------------------------------------==//
+  // Accessing the Generic Data Map (GDM).
+  //==---------------------------------------------------------------------==//
+
+  void *const* FindGDM(void *K) const;
+
+  template<typename T>
+  ProgramStateRef add(typename ProgramStateTrait<T>::key_type K) const;
+
+  template <typename T>
+  typename ProgramStateTrait<T>::data_type
+  get() const {
+    return ProgramStateTrait<T>::MakeData(FindGDM(ProgramStateTrait<T>::GDMIndex()));
+  }
+
+  template<typename T>
+  typename ProgramStateTrait<T>::lookup_type
+  get(typename ProgramStateTrait<T>::key_type key) const {
+    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
+    return ProgramStateTrait<T>::Lookup(ProgramStateTrait<T>::MakeData(d), key);
+  }
+
+  template <typename T>
+  typename ProgramStateTrait<T>::context_type get_context() const;
+
+
+  template<typename T>
+  ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K) const;
+
+  template<typename T>
+  ProgramStateRef remove(typename ProgramStateTrait<T>::key_type K,
+                        typename ProgramStateTrait<T>::context_type C) const;
+  template <typename T>
+  ProgramStateRef remove() const;
+
+  template<typename T>
+  ProgramStateRef set(typename ProgramStateTrait<T>::data_type D) const;
+
+  template<typename T>
+  ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
+                     typename ProgramStateTrait<T>::value_type E) const;
+
+  template<typename T>
+  ProgramStateRef set(typename ProgramStateTrait<T>::key_type K,
+                     typename ProgramStateTrait<T>::value_type E,
+                     typename ProgramStateTrait<T>::context_type C) const;
+
+  template<typename T>
+  bool contains(typename ProgramStateTrait<T>::key_type key) const {
+    void *const* d = FindGDM(ProgramStateTrait<T>::GDMIndex());
+    return ProgramStateTrait<T>::Contains(ProgramStateTrait<T>::MakeData(d), key);
+  }
+
+  // Pretty-printing.
+  void print(raw_ostream &Out, const char *nl = "\n",
+             const char *sep = "") const;
+  void printDOT(raw_ostream &Out) const;
+  void printTaint(raw_ostream &Out, const char *nl = "\n",
+                  const char *sep = "") const;
+
+  void dump() const;
+  void dumpTaint() const;
+
+private:
+  friend void ProgramStateRetain(const ProgramState *state);
+  friend void ProgramStateRelease(const ProgramState *state);
+
+  /// \sa invalidateValues()
+  /// \sa invalidateRegions()
+  ProgramStateRef
+  invalidateRegionsImpl(ArrayRef<SVal> Values,
+                        const Expr *E, unsigned BlockCount,
+                        const LocationContext *LCtx,
+                        bool ResultsInSymbolEscape,
+                        InvalidatedSymbols *IS,
+                        RegionAndSymbolInvalidationTraits *HTraits,
+                        const CallEvent *Call) const;
+};
+
+//===----------------------------------------------------------------------===//
+// ProgramStateManager - Factory object for ProgramStates.
+//===----------------------------------------------------------------------===//
+
+class ProgramStateManager {
+  friend class ProgramState;
+  friend void ProgramStateRelease(const ProgramState *state);
+private:
+  /// Eng - The SubEngine that owns this state manager.
+  SubEngine *Eng; /* Can be null. */
+
+  EnvironmentManager                   EnvMgr;
+  std::unique_ptr<StoreManager>        StoreMgr;
+  std::unique_ptr<ConstraintManager>   ConstraintMgr;
+
+  ProgramState::GenericDataMap::Factory     GDMFactory;
+
+  typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
+  GDMContextsTy GDMContexts;
+
+  /// StateSet - FoldingSet containing all the states created for analyzing
+  ///  a particular function.  This is used to unique states.
+  llvm::FoldingSet<ProgramState> StateSet;
+
+  /// Object that manages the data for all created SVals.
+  std::unique_ptr<SValBuilder> svalBuilder;
+
+  /// Manages memory for created CallEvents.
+  std::unique_ptr<CallEventManager> CallEventMgr;
+
+  /// A BumpPtrAllocator to allocate states.
+  llvm::BumpPtrAllocator &Alloc;
+  
+  /// A vector of ProgramStates that we can reuse.
+  std::vector<ProgramState *> freeStates;
+
+public:
+  ProgramStateManager(ASTContext &Ctx,
+                 StoreManagerCreator CreateStoreManager,
+                 ConstraintManagerCreator CreateConstraintManager,
+                 llvm::BumpPtrAllocator& alloc,
+                 SubEngine *subeng);
+
+  ~ProgramStateManager();
+
+  ProgramStateRef getInitialState(const LocationContext *InitLoc);
+
+  ASTContext &getContext() { return svalBuilder->getContext(); }
+  const ASTContext &getContext() const { return svalBuilder->getContext(); }
+
+  BasicValueFactory &getBasicVals() {
+    return svalBuilder->getBasicValueFactory();
+  }
+
+  SValBuilder &getSValBuilder() {
+    return *svalBuilder;
+  }
+
+  SymbolManager &getSymbolManager() {
+    return svalBuilder->getSymbolManager();
+  }
+  const SymbolManager &getSymbolManager() const {
+    return svalBuilder->getSymbolManager();
+  }
+
+  llvm::BumpPtrAllocator& getAllocator() { return Alloc; }
+
+  MemRegionManager& getRegionManager() {
+    return svalBuilder->getRegionManager();
+  }
+  const MemRegionManager& getRegionManager() const {
+    return svalBuilder->getRegionManager();
+  }
+
+  CallEventManager &getCallEventManager() { return *CallEventMgr; }
+
+  StoreManager& getStoreManager() { return *StoreMgr; }
+  ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
+  SubEngine* getOwningEngine() { return Eng; }
+
+  ProgramStateRef removeDeadBindings(ProgramStateRef St,
+                                    const StackFrameContext *LCtx,
+                                    SymbolReaper& SymReaper);
+
+public:
+
+  SVal ArrayToPointer(Loc Array, QualType ElementTy) {
+    return StoreMgr->ArrayToPointer(Array, ElementTy);
+  }
+
+  // Methods that manipulate the GDM.
+  ProgramStateRef addGDM(ProgramStateRef St, void *Key, void *Data);
+  ProgramStateRef removeGDM(ProgramStateRef state, void *Key);
+
+  // Methods that query & manipulate the Store.
+
+  void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) {
+    StoreMgr->iterBindings(state->getStore(), F);
+  }
+
+  ProgramStateRef getPersistentState(ProgramState &Impl);
+  ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
+                                           ProgramStateRef GDMState);
+
+  bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
+    return S1->Env == S2->Env;
+  }
+
+  bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
+    return S1->store == S2->store;
+  }
+
+  //==---------------------------------------------------------------------==//
+  // Generic Data Map methods.
+  //==---------------------------------------------------------------------==//
+  //
+  // ProgramStateManager and ProgramState support a "generic data map" that allows
+  // different clients of ProgramState objects to embed arbitrary data within a
+  // ProgramState object.  The generic data map is essentially an immutable map
+  // from a "tag" (that acts as the "key" for a client) and opaque values.
+  // Tags/keys and values are simply void* values.  The typical way that clients
+  // generate unique tags are by taking the address of a static variable.
+  // Clients are responsible for ensuring that data values referred to by a
+  // the data pointer are immutable (and thus are essentially purely functional
+  // data).
+  //
+  // The templated methods below use the ProgramStateTrait<T> class
+  // to resolve keys into the GDM and to return data values to clients.
+  //
+
+  // Trait based GDM dispatch.
+  template <typename T>
+  ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait<T>::data_type D) {
+    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
+                  ProgramStateTrait<T>::MakeVoidPtr(D));
+  }
+
+  template<typename T>
+  ProgramStateRef set(ProgramStateRef st,
+                     typename ProgramStateTrait<T>::key_type K,
+                     typename ProgramStateTrait<T>::value_type V,
+                     typename ProgramStateTrait<T>::context_type C) {
+
+    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
+     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Set(st->get<T>(), K, V, C)));
+  }
+
+  template <typename T>
+  ProgramStateRef add(ProgramStateRef st,
+                     typename ProgramStateTrait<T>::key_type K,
+                     typename ProgramStateTrait<T>::context_type C) {
+    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
+        ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Add(st->get<T>(), K, C)));
+  }
+
+  template <typename T>
+  ProgramStateRef remove(ProgramStateRef st,
+                        typename ProgramStateTrait<T>::key_type K,
+                        typename ProgramStateTrait<T>::context_type C) {
+
+    return addGDM(st, ProgramStateTrait<T>::GDMIndex(),
+     ProgramStateTrait<T>::MakeVoidPtr(ProgramStateTrait<T>::Remove(st->get<T>(), K, C)));
+  }
+
+  template <typename T>
+  ProgramStateRef remove(ProgramStateRef st) {
+    return removeGDM(st, ProgramStateTrait<T>::GDMIndex());
+  }
+
+  void *FindGDMContext(void *index,
+                       void *(*CreateContext)(llvm::BumpPtrAllocator&),
+                       void  (*DeleteContext)(void*));
+
+  template <typename T>
+  typename ProgramStateTrait<T>::context_type get_context() {
+    void *p = FindGDMContext(ProgramStateTrait<T>::GDMIndex(),
+                             ProgramStateTrait<T>::CreateContext,
+                             ProgramStateTrait<T>::DeleteContext);
+
+    return ProgramStateTrait<T>::MakeContext(p);
+  }
+
+  void EndPath(ProgramStateRef St) {
+    ConstraintMgr->EndPath(St);
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Out-of-line method definitions for ProgramState.
+//===----------------------------------------------------------------------===//
+
+inline ConstraintManager &ProgramState::getConstraintManager() const {
+  return stateMgr->getConstraintManager();
+}
+  
+inline const VarRegion* ProgramState::getRegion(const VarDecl *D,
+                                                const LocationContext *LC) const 
+{
+  return getStateManager().getRegionManager().getVarRegion(D, LC);
+}
+
+inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
+                                      bool Assumption) const {
+  if (Cond.isUnknown())
+    return this;
+
+  return getStateManager().ConstraintMgr
+      ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
+}
+  
+inline std::pair<ProgramStateRef , ProgramStateRef >
+ProgramState::assume(DefinedOrUnknownSVal Cond) const {
+  if (Cond.isUnknown())
+    return std::make_pair(this, this);
+
+  return getStateManager().ConstraintMgr
+      ->assumeDual(this, Cond.castAs<DefinedSVal>());
+}
+
+inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
+  if (Optional<Loc> L = LV.getAs<Loc>())
+    return bindLoc(*L, V);
+  return this;
+}
+
+inline Loc ProgramState::getLValue(const VarDecl *VD,
+                               const LocationContext *LC) const {
+  return getStateManager().StoreMgr->getLValueVar(VD, LC);
+}
+
+inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal,
+                               const LocationContext *LC) const {
+  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
+}
+
+inline SVal ProgramState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
+  return getStateManager().StoreMgr->getLValueIvar(D, Base);
+}
+
+inline SVal ProgramState::getLValue(const FieldDecl *D, SVal Base) const {
+  return getStateManager().StoreMgr->getLValueField(D, Base);
+}
+
+inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
+                                    SVal Base) const {
+  StoreManager &SM = *getStateManager().StoreMgr;
+  for (const auto *I : D->chain()) {
+    Base = SM.getLValueField(cast<FieldDecl>(I), Base);
+  }
+
+  return Base;
+}
+
+inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
+  if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
+    return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
+  return UnknownVal();
+}
+
+inline SVal ProgramState::getSVal(const Stmt *Ex,
+                                  const LocationContext *LCtx) const{
+  return Env.getSVal(EnvironmentEntry(Ex, LCtx),
+                     *getStateManager().svalBuilder);
+}
+
+inline SVal
+ProgramState::getSValAsScalarOrLoc(const Stmt *S,
+                                   const LocationContext *LCtx) const {
+  if (const Expr *Ex = dyn_cast<Expr>(S)) {
+    QualType T = Ex->getType();
+    if (Ex->isGLValue() || Loc::isLocType(T) ||
+        T->isIntegralOrEnumerationType())
+      return getSVal(S, LCtx);
+  }
+
+  return UnknownVal();
+}
+
+inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const {
+  return getStateManager().StoreMgr->getBinding(getStore(), LV, T);
+}
+
+inline SVal ProgramState::getSVal(const MemRegion* R) const {
+  return getStateManager().StoreMgr->getBinding(getStore(),
+                                                loc::MemRegionVal(R));
+}
+
+inline BasicValueFactory &ProgramState::getBasicVals() const {
+  return getStateManager().getBasicVals();
+}
+
+inline SymbolManager &ProgramState::getSymbolManager() const {
+  return getStateManager().getSymbolManager();
+}
+
+template<typename T>
+ProgramStateRef ProgramState::add(typename ProgramStateTrait<T>::key_type K) const {
+  return getStateManager().add<T>(this, K, get_context<T>());
+}
+
+template <typename T>
+typename ProgramStateTrait<T>::context_type ProgramState::get_context() const {
+  return getStateManager().get_context<T>();
+}
+
+template<typename T>
+ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K) const {
+  return getStateManager().remove<T>(this, K, get_context<T>());
+}
+
+template<typename T>
+ProgramStateRef ProgramState::remove(typename ProgramStateTrait<T>::key_type K,
+                               typename ProgramStateTrait<T>::context_type C) const {
+  return getStateManager().remove<T>(this, K, C);
+}
+
+template <typename T>
+ProgramStateRef ProgramState::remove() const {
+  return getStateManager().remove<T>(this);
+}
+
+template<typename T>
+ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::data_type D) const {
+  return getStateManager().set<T>(this, D);
+}
+
+template<typename T>
+ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
+                            typename ProgramStateTrait<T>::value_type E) const {
+  return getStateManager().set<T>(this, K, E, get_context<T>());
+}
+
+template<typename T>
+ProgramStateRef ProgramState::set(typename ProgramStateTrait<T>::key_type K,
+                            typename ProgramStateTrait<T>::value_type E,
+                            typename ProgramStateTrait<T>::context_type C) const {
+  return getStateManager().set<T>(this, K, E, C);
+}
+
+template <typename CB>
+CB ProgramState::scanReachableSymbols(SVal val) const {
+  CB cb(this);
+  scanReachableSymbols(val, cb);
+  return cb;
+}
+  
+template <typename CB>
+CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
+  CB cb(this);
+  scanReachableSymbols(beg, end, cb);
+  return cb;
+}
+
+template <typename CB>
+CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
+                                 const MemRegion * const *end) const {
+  CB cb(this);
+  scanReachableSymbols(beg, end, cb);
+  return cb;
+}
+
+/// \class ScanReachableSymbols
+/// A Utility class that allows to visit the reachable symbols using a custom
+/// SymbolVisitor.
+class ScanReachableSymbols {
+  typedef llvm::DenseSet<const void*> VisitedItems;
+
+  VisitedItems visited;
+  ProgramStateRef state;
+  SymbolVisitor &visitor;
+public:
+
+  ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
+    : state(st), visitor(v) {}
+
+  bool scan(nonloc::LazyCompoundVal val);
+  bool scan(nonloc::CompoundVal val);
+  bool scan(SVal val);
+  bool scan(const MemRegion *R);
+  bool scan(const SymExpr *sym);
+};
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
new file mode 100644
index 0000000..823bde7
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -0,0 +1,245 @@
+//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- 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 partial implementations of template specializations of
+//  the class ProgramStateTrait<>.  ProgramStateTrait<> is used by ProgramState 
+//  to implement set/get methods for manipulating a ProgramState's
+//  generic data map.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
+#define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  template <typename K, typename D, typename I> class ImmutableMap;
+  template <typename K, typename I> class ImmutableSet;
+  template <typename T> class ImmutableList;
+  template <typename T> class ImmutableListImpl;
+}
+
+namespace clang {
+
+namespace ento {
+  template <typename T> struct ProgramStatePartialTrait;
+
+  /// Declares a program state trait for type \p Type called \p Name, and
+  /// introduce a typedef named \c NameTy.
+  /// The macro should not be used inside namespaces, or for traits that must
+  /// be accessible from more than one translation unit.
+  #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
+    namespace { \
+      class Name {}; \
+      typedef Type Name ## Ty; \
+    } \
+    namespace clang { \
+    namespace ento { \
+      template <> \
+      struct ProgramStateTrait<Name> \
+        : public ProgramStatePartialTrait<Name ## Ty> { \
+        static void *GDMIndex() { static int Index; return &Index; } \
+      }; \
+    } \
+    }
+
+
+  // Partial-specialization for ImmutableMap.
+
+  template <typename Key, typename Data, typename Info>
+  struct ProgramStatePartialTrait< llvm::ImmutableMap<Key,Data,Info> > {
+    typedef llvm::ImmutableMap<Key,Data,Info> data_type;
+    typedef typename data_type::Factory&      context_type;
+    typedef Key                               key_type;
+    typedef Data                              value_type;
+    typedef const value_type*                 lookup_type;
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? data_type((typename data_type::TreeTy*) *p)
+               : data_type(nullptr);
+    }
+    static inline void *MakeVoidPtr(data_type B) {
+      return B.getRoot();
+    }
+    static lookup_type Lookup(data_type B, key_type K) {
+      return B.lookup(K);
+    }
+    static data_type Set(data_type B, key_type K, value_type E,context_type F){
+      return F.add(B, K, E);
+    }
+
+    static data_type Remove(data_type B, key_type K, context_type F) {
+      return F.remove(B, K);
+    }
+
+    static inline context_type MakeContext(void *p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void *Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+
+  /// Helper for registering a map trait.
+  ///
+  /// If the map type were written directly in the invocation of
+  /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments
+  /// would be treated as a macro argument separator, which is wrong.
+  /// This allows the user to specify a map type in a way that the preprocessor
+  /// can deal with.
+  #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap<Key, Value>
+
+
+  // Partial-specialization for ImmutableSet.
+
+  template <typename Key, typename Info>
+  struct ProgramStatePartialTrait< llvm::ImmutableSet<Key,Info> > {
+    typedef llvm::ImmutableSet<Key,Info>      data_type;
+    typedef typename data_type::Factory&      context_type;
+    typedef Key                               key_type;
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? data_type((typename data_type::TreeTy*) *p)
+               : data_type(nullptr);
+    }
+
+    static inline void *MakeVoidPtr(data_type B) {
+      return B.getRoot();
+    }
+
+    static data_type Add(data_type B, key_type K, context_type F) {
+      return F.add(B, K);
+    }
+
+    static data_type Remove(data_type B, key_type K, context_type F) {
+      return F.remove(B, K);
+    }
+
+    static bool Contains(data_type B, key_type K) {
+      return B.contains(K);
+    }
+
+    static inline context_type MakeContext(void *p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void *Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+
+
+  // Partial-specialization for ImmutableList.
+
+  template <typename T>
+  struct ProgramStatePartialTrait< llvm::ImmutableList<T> > {
+    typedef llvm::ImmutableList<T>            data_type;
+    typedef T                                 key_type;
+    typedef typename data_type::Factory&      context_type;
+
+    static data_type Add(data_type L, key_type K, context_type F) {
+      return F.add(K, L);
+    }
+
+    static bool Contains(data_type L, key_type K) {
+      return L.contains(K);
+    }
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
+               : data_type(nullptr);
+    }
+
+    static inline void *MakeVoidPtr(data_type D) {
+      return const_cast<llvm::ImmutableListImpl<T> *>(D.getInternalPointer());
+    }
+
+    static inline context_type MakeContext(void *p) {
+      return *((typename data_type::Factory*) p);
+    }
+
+    static void *CreateContext(llvm::BumpPtrAllocator& Alloc) {
+      return new typename data_type::Factory(Alloc);
+    }
+
+    static void DeleteContext(void *Ctx) {
+      delete (typename data_type::Factory*) Ctx;
+    }
+  };
+
+  
+  // Partial specialization for bool.
+  template <> struct ProgramStatePartialTrait<bool> {
+    typedef bool data_type;
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? (data_type) (uintptr_t) *p
+               : data_type();
+    }
+    static inline void *MakeVoidPtr(data_type d) {
+      return (void*) (uintptr_t) d;
+    }
+  };
+  
+  // Partial specialization for unsigned.
+  template <> struct ProgramStatePartialTrait<unsigned> {
+    typedef unsigned data_type;
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? (data_type) (uintptr_t) *p
+               : data_type();
+    }
+    static inline void *MakeVoidPtr(data_type d) {
+      return (void*) (uintptr_t) d;
+    }
+  };
+
+  // Partial specialization for void*.
+  template <> struct ProgramStatePartialTrait<void*> {
+    typedef void *data_type;
+
+    static inline data_type MakeData(void *const* p) {
+      return p ? *p
+               : data_type();
+    }
+    static inline void *MakeVoidPtr(data_type d) {
+      return d;
+    }
+  };
+
+  // Partial specialization for const void *.
+  template <> struct ProgramStatePartialTrait<const void *> {
+    typedef const void *data_type;
+
+    static inline data_type MakeData(void * const *p) {
+      return p ? *p : data_type();
+    }
+
+    static inline void *MakeVoidPtr(data_type d) {
+      return const_cast<void *>(d);
+    }
+  };
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
new file mode 100644
index 0000000..371f3c5
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
@@ -0,0 +1,43 @@
+//== ProgramState_Fwd.h - Incomplete declarations of ProgramState -*- C++ -*--=/
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PROGRAMSTATE_FWD_H
+#define LLVM_CLANG_PROGRAMSTATE_FWD_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+namespace clang {
+namespace ento {
+  class ProgramState;
+  class ProgramStateManager;
+  void ProgramStateRetain(const ProgramState *state);
+  void ProgramStateRelease(const ProgramState *state);
+}
+}
+
+namespace llvm {
+  template <> struct IntrusiveRefCntPtrInfo<const clang::ento::ProgramState> {
+    static void retain(const clang::ento::ProgramState *state) {
+      clang::ento::ProgramStateRetain(state);
+    }
+    static void release(const clang::ento::ProgramState *state) {
+      clang::ento::ProgramStateRelease(state);
+    }
+  };
+}
+
+namespace clang {
+namespace ento {
+  typedef IntrusiveRefCntPtr<const ProgramState> ProgramStateRef;
+}
+}
+
+#endif
+
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
new file mode 100644
index 0000000..29fb413
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -0,0 +1,333 @@
+// SValBuilder.h - Construction of SVals from evaluating expressions -*- 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 SValBuilder, a class that defines the interface for
+//  "symbolical evaluators" which construct an SVal from an expression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_SVALBUILDER
+#define LLVM_CLANG_GR_SVALBUILDER
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+
+namespace clang {
+
+class CXXBoolLiteralExpr;
+
+namespace ento {
+
+class SValBuilder {
+  virtual void anchor();
+protected:
+  ASTContext &Context;
+  
+  /// Manager of APSInt values.
+  BasicValueFactory BasicVals;
+
+  /// Manages the creation of symbols.
+  SymbolManager SymMgr;
+
+  /// Manages the creation of memory regions.
+  MemRegionManager MemMgr;
+
+  ProgramStateManager &StateMgr;
+
+  /// The scalar type to use for array indices.
+  const QualType ArrayIndexTy;
+  
+  /// The width of the scalar type used for array indices.
+  const unsigned ArrayIndexWidth;
+
+  virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy) = 0;
+  virtual SVal evalCastFromLoc(Loc val, QualType castTy) = 0;
+
+public:
+  // FIXME: Make these protected again once RegionStoreManager correctly
+  // handles loads from different bound value types.
+  virtual SVal dispatchCast(SVal val, QualType castTy) = 0;
+
+public:
+  SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
+              ProgramStateManager &stateMgr)
+    : Context(context), BasicVals(context, alloc),
+      SymMgr(context, BasicVals, alloc),
+      MemMgr(context, alloc),
+      StateMgr(stateMgr),
+      ArrayIndexTy(context.IntTy),
+      ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
+
+  virtual ~SValBuilder() {}
+
+  bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) {
+    return haveSameType(Sym1->getType(), Sym2->getType());
+  }
+
+  bool haveSameType(QualType Ty1, QualType Ty2) {
+    // FIXME: Remove the second disjunct when we support symbolic
+    // truncation/extension.
+    return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) ||
+            (Ty1->isIntegralOrEnumerationType() &&
+             Ty2->isIntegralOrEnumerationType()));
+  }
+
+  SVal evalCast(SVal val, QualType castTy, QualType originalType);
+  
+  virtual SVal evalMinus(NonLoc val) = 0;
+
+  virtual SVal evalComplement(NonLoc val) = 0;
+
+  /// Create a new value which represents a binary expression with two non-
+  /// location operands.
+  virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
+                           NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+  /// Create a new value which represents a binary expression with two memory
+  /// location operands.
+  virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
+                           Loc lhs, Loc rhs, QualType resultTy) = 0;
+
+  /// Create a new value which represents a binary expression with a memory
+  /// location and non-location operands. For example, this would be used to
+  /// evaluate a pointer arithmetic operation.
+  virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
+                           Loc lhs, NonLoc rhs, QualType resultTy) = 0;
+
+  /// Evaluates a given SVal. If the SVal has only one possible (integer) value,
+  /// that value is returned. Otherwise, returns NULL.
+  virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
+  
+  /// Constructs a symbolic expression for two non-location values.
+  SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op,
+                      NonLoc lhs, NonLoc rhs, QualType resultTy);
+
+  SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
+                 SVal lhs, SVal rhs, QualType type);
+  
+  DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
+                              DefinedOrUnknownSVal rhs);
+
+  ASTContext &getContext() { return Context; }
+  const ASTContext &getContext() const { return Context; }
+
+  ProgramStateManager &getStateManager() { return StateMgr; }
+  
+  QualType getConditionType() const {
+    return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy;
+  }
+  
+  QualType getArrayIndexType() const {
+    return ArrayIndexTy;
+  }
+
+  BasicValueFactory &getBasicValueFactory() { return BasicVals; }
+  const BasicValueFactory &getBasicValueFactory() const { return BasicVals; }
+
+  SymbolManager &getSymbolManager() { return SymMgr; }
+  const SymbolManager &getSymbolManager() const { return SymMgr; }
+
+  MemRegionManager &getRegionManager() { return MemMgr; }
+  const MemRegionManager &getRegionManager() const { return MemMgr; }
+
+  // Forwarding methods to SymbolManager.
+
+  const SymbolConjured* conjureSymbol(const Stmt *stmt,
+                                      const LocationContext *LCtx,
+                                      QualType type,
+                                      unsigned visitCount,
+                                      const void *symbolTag = nullptr) {
+    return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
+  }
+
+  const SymbolConjured* conjureSymbol(const Expr *expr,
+                                      const LocationContext *LCtx,
+                                      unsigned visitCount,
+                                      const void *symbolTag = nullptr) {
+    return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
+  }
+
+  /// Construct an SVal representing '0' for the specified type.
+  DefinedOrUnknownSVal makeZeroVal(QualType type);
+
+  /// Make a unique symbol for value of region.
+  DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region);
+
+  /// \brief Create a new symbol with a unique 'name'.
+  ///
+  /// We resort to conjured symbols when we cannot construct a derived symbol.
+  /// The advantage of symbols derived/built from other symbols is that we
+  /// preserve the relation between related(or even equivalent) expressions, so
+  /// conjured symbols should be used sparingly.
+  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
+                                        const Expr *expr,
+                                        const LocationContext *LCtx,
+                                        unsigned count);
+  DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag,
+                                        const Expr *expr,
+                                        const LocationContext *LCtx,
+                                        QualType type,
+                                        unsigned count);
+  
+  DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt,
+                                        const LocationContext *LCtx,
+                                        QualType type,
+                                        unsigned visitCount);
+  /// \brief Conjure a symbol representing heap allocated memory region.
+  ///
+  /// Note, the expression should represent a location.
+  DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
+                                                const LocationContext *LCtx,
+                                                unsigned Count);
+
+  DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
+      SymbolRef parentSymbol, const TypedValueRegion *region);
+
+  DefinedSVal getMetadataSymbolVal(
+      const void *symbolTag, const MemRegion *region,
+      const Expr *expr, QualType type, unsigned count);
+
+  DefinedSVal getFunctionPointer(const FunctionDecl *func);
+  
+  DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
+                              const LocationContext *locContext,
+                              unsigned blockCount);
+
+  /// Returns the value of \p E, if it can be determined in a non-path-sensitive
+  /// manner.
+  ///
+  /// If \p E is not a constant or cannot be modeled, returns \c None.
+  Optional<SVal> getConstantVal(const Expr *E);
+
+  NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
+    return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
+  }
+
+  NonLoc makeLazyCompoundVal(const StoreRef &store, 
+                             const TypedValueRegion *region) {
+    return nonloc::LazyCompoundVal(
+        BasicVals.getLazyCompoundValData(store, region));
+  }
+
+  NonLoc makeZeroArrayIndex() {
+    return nonloc::ConcreteInt(BasicVals.getValue(0, ArrayIndexTy));
+  }
+
+  NonLoc makeArrayIndex(uint64_t idx) {
+    return nonloc::ConcreteInt(BasicVals.getValue(idx, ArrayIndexTy));
+  }
+
+  SVal convertToArrayIndex(SVal val);
+
+  nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
+    return nonloc::ConcreteInt(
+        BasicVals.getValue(integer->getValue(),
+                     integer->getType()->isUnsignedIntegerOrEnumerationType()));
+  }
+
+  nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) {
+    return makeTruthVal(boolean->getValue(), boolean->getType());
+  }
+
+  nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean);
+
+  nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) {
+    return nonloc::ConcreteInt(BasicVals.getValue(integer));
+  }
+
+  loc::ConcreteInt makeIntLocVal(const llvm::APSInt &integer) {
+    return loc::ConcreteInt(BasicVals.getValue(integer));
+  }
+
+  NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned));
+  }
+
+  DefinedSVal makeIntVal(uint64_t integer, QualType type) {
+    if (Loc::isLocType(type))
+      return loc::ConcreteInt(BasicVals.getValue(integer, type));
+
+    return nonloc::ConcreteInt(BasicVals.getValue(integer, type));
+  }
+
+  NonLoc makeIntVal(uint64_t integer, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned));
+  }
+
+  NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned) {
+    return nonloc::ConcreteInt(
+        BasicVals.getIntWithPtrWidth(integer, isUnsigned));
+  }
+
+  NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
+    return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
+  }
+
+  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                    const llvm::APSInt& rhs, QualType type);
+
+  NonLoc makeNonLoc(const llvm::APSInt& rhs, BinaryOperator::Opcode op,
+                    const SymExpr *lhs, QualType type);
+
+  NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+                    const SymExpr *rhs, QualType type);
+
+  /// \brief Create a NonLoc value for cast.
+  NonLoc makeNonLoc(const SymExpr *operand, QualType fromTy, QualType toTy);
+
+  nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
+    return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));
+  }
+
+  nonloc::ConcreteInt makeTruthVal(bool b) {
+    return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
+  }
+
+  Loc makeNull() {
+    return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
+  }
+
+  Loc makeLoc(SymbolRef sym) {
+    return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
+  }
+
+  Loc makeLoc(const MemRegion* region) {
+    return loc::MemRegionVal(region);
+  }
+
+  Loc makeLoc(const AddrLabelExpr *expr) {
+    return loc::GotoLabel(expr->getLabel());
+  }
+
+  Loc makeLoc(const llvm::APSInt& integer) {
+    return loc::ConcreteInt(BasicVals.getValue(integer));
+  }
+
+  /// Return a memory region for the 'this' object reference.
+  loc::MemRegionVal getCXXThis(const CXXMethodDecl *D,
+                               const StackFrameContext *SFC);
+
+  /// Return a memory region for the 'this' object reference.
+  loc::MemRegionVal getCXXThis(const CXXRecordDecl *D,
+                               const StackFrameContext *SFC);
+};
+
+SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
+                                     ASTContext &context,
+                                     ProgramStateManager &stateMgr);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
new file mode 100644
index 0000000..d50c3be
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -0,0 +1,574 @@
+//== SVals.h - Abstract Values for Static Analysis ---------*- 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 SVal, Loc, and NonLoc, classes that represent
+//  abstract r-values for use with path-sensitive value tracking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_RVALUE_H
+#define LLVM_CLANG_GR_RVALUE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/ImmutableList.h"
+
+//==------------------------------------------------------------------------==//
+//  Base SVal types.
+//==------------------------------------------------------------------------==//
+
+namespace clang {
+
+namespace ento {
+
+class CompoundValData;
+class LazyCompoundValData;
+class ProgramState;
+class BasicValueFactory;
+class MemRegion;
+class TypedValueRegion;
+class MemRegionManager;
+class ProgramStateManager;
+class SValBuilder;
+
+/// SVal - This represents a symbolic expression, which can be either
+///  an L-value or an R-value.
+///
+class SVal {
+public:
+  enum BaseKind {
+    // The enumerators must be representable using 2 bits.
+    UndefinedKind = 0,  // for subclass UndefinedVal (an uninitialized value)
+    UnknownKind = 1,    // for subclass UnknownVal (a void value)
+    LocKind = 2,        // for subclass Loc (an L-value)
+    NonLocKind = 3      // for subclass NonLoc (an R-value that's not
+                        //   an L-value)
+  };
+  enum { BaseBits = 2, BaseMask = 0x3 };
+
+protected:
+  const void *Data;
+
+  /// The lowest 2 bits are a BaseKind (0 -- 3).
+  ///  The higher bits are an unsigned "kind" value.
+  unsigned Kind;
+
+  explicit SVal(const void *d, bool isLoc, unsigned ValKind)
+  : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
+
+  explicit SVal(BaseKind k, const void *D = nullptr)
+    : Data(D), Kind(k) {}
+
+public:
+  explicit SVal() : Data(nullptr), Kind(0) {}
+
+  /// \brief Convert to the specified SVal type, asserting that this SVal is of
+  /// the desired type.
+  template<typename T>
+  T castAs() const {
+    assert(T::isKind(*this));
+    T t;
+    SVal& sv = t;
+    sv = *this;
+    return t;
+  }
+
+  /// \brief Convert to the specified SVal type, returning None if this SVal is
+  /// not of the desired type.
+  template<typename T>
+  Optional<T> getAs() const {
+    if (!T::isKind(*this))
+      return None;
+    T t;
+    SVal& sv = t;
+    sv = *this;
+    return t;
+  }
+
+  /// BufferTy - A temporary buffer to hold a set of SVals.
+  typedef SmallVector<SVal,5> BufferTy;
+
+  inline unsigned getRawKind() const { return Kind; }
+  inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
+  inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
+
+  // This method is required for using SVal in a FoldingSetNode.  It
+  // extracts a unique signature for this SVal object.
+  inline void Profile(llvm::FoldingSetNodeID& ID) const {
+    ID.AddInteger((unsigned) getRawKind());
+    ID.AddPointer(Data);
+  }
+
+  inline bool operator==(const SVal& R) const {
+    return getRawKind() == R.getRawKind() && Data == R.Data;
+  }
+
+  inline bool operator!=(const SVal& R) const {
+    return !(*this == R);
+  }
+
+  inline bool isUnknown() const {
+    return getRawKind() == UnknownKind;
+  }
+
+  inline bool isUndef() const {
+    return getRawKind() == UndefinedKind;
+  }
+
+  inline bool isUnknownOrUndef() const {
+    return getRawKind() <= UnknownKind;
+  }
+
+  inline bool isValid() const {
+    return getRawKind() > UnknownKind;
+  }
+
+  bool isConstant() const;
+
+  bool isConstant(int I) const;
+
+  bool isZeroConstant() const;
+
+  /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
+  bool hasConjuredSymbol() const;
+
+  /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
+  /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
+  /// Otherwise return 0.
+  const FunctionDecl *getAsFunctionDecl() const;
+
+  /// \brief If this SVal is a location and wraps a symbol, return that
+  ///  SymbolRef. Otherwise return 0.
+  ///
+  /// Casts are ignored during lookup.
+  /// \param IncludeBaseRegions The boolean that controls whether the search
+  /// should continue to the base regions if the region is not symbolic.
+  SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const;
+
+  /// Get the symbol in the SVal or its base region.
+  SymbolRef getLocSymbolInBase() const;
+
+  /// \brief If this SVal wraps a symbol return that SymbolRef.
+  /// Otherwise, return 0.
+  ///
+  /// Casts are ignored during lookup.
+  /// \param IncludeBaseRegions The boolean that controls whether the search
+  /// should continue to the base regions if the region is not symbolic.
+  SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
+
+  /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
+  ///  return that expression.  Otherwise return NULL.
+  const SymExpr *getAsSymbolicExpression() const;
+
+  const SymExpr* getAsSymExpr() const;
+
+  const MemRegion *getAsRegion() const;
+
+  void dumpToStream(raw_ostream &OS) const;
+  void dump() const;
+
+  SymExpr::symbol_iterator symbol_begin() const {
+    const SymExpr *SE = getAsSymbolicExpression();
+    if (SE)
+      return SE->symbol_begin();
+    else
+      return SymExpr::symbol_iterator();
+  }
+
+  SymExpr::symbol_iterator symbol_end() const { 
+    return SymExpr::symbol_end();
+  }
+};
+
+
+class UndefinedVal : public SVal {
+public:
+  UndefinedVal() : SVal(UndefinedKind) {}
+
+private:
+  friend class SVal;
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == UndefinedKind;
+  }
+};
+
+class DefinedOrUnknownSVal : public SVal {
+private:
+  // We want calling these methods to be a compiler error since they are
+  // tautologically false.
+  bool isUndef() const LLVM_DELETED_FUNCTION;
+  bool isValid() const LLVM_DELETED_FUNCTION;
+  
+protected:
+  DefinedOrUnknownSVal() {}
+  explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
+    : SVal(d, isLoc, ValKind) {}
+  
+  explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr)
+    : SVal(k, D) {}
+  
+private:
+  friend class SVal;
+  static bool isKind(const SVal& V) {
+    return !V.isUndef();
+  }
+};
+  
+class UnknownVal : public DefinedOrUnknownSVal {
+public:
+  explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
+  
+private:
+  friend class SVal;
+  static bool isKind(const SVal &V) {
+    return V.getBaseKind() == UnknownKind;
+  }
+};
+
+class DefinedSVal : public DefinedOrUnknownSVal {
+private:
+  // We want calling these methods to be a compiler error since they are
+  // tautologically true/false.
+  bool isUnknown() const LLVM_DELETED_FUNCTION;
+  bool isUnknownOrUndef() const LLVM_DELETED_FUNCTION;
+  bool isValid() const LLVM_DELETED_FUNCTION;
+protected:
+  DefinedSVal() {}
+  explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
+    : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
+private:
+  friend class SVal;
+  static bool isKind(const SVal& V) {
+    return !V.isUnknownOrUndef();
+  }
+};
+
+
+/// \brief Represents an SVal that is guaranteed to not be UnknownVal.
+class KnownSVal : public SVal {
+  KnownSVal() {}
+  friend class SVal;
+  static bool isKind(const SVal &V) {
+    return !V.isUnknown();
+  }
+public:
+  KnownSVal(const DefinedSVal &V) : SVal(V) {}
+  KnownSVal(const UndefinedVal &V) : SVal(V) {}
+};
+
+class NonLoc : public DefinedSVal {
+protected:
+  NonLoc() {}
+  explicit NonLoc(unsigned SubKind, const void *d)
+    : DefinedSVal(d, false, SubKind) {}
+
+public:
+  void dumpToStream(raw_ostream &Out) const;
+
+private:
+  friend class SVal;
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind;
+  }
+};
+
+class Loc : public DefinedSVal {
+protected:
+  Loc() {}
+  explicit Loc(unsigned SubKind, const void *D)
+  : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
+
+public:
+  void dumpToStream(raw_ostream &Out) const;
+
+  static inline bool isLocType(QualType T) {
+    return T->isAnyPointerType() || T->isBlockPointerType() || 
+           T->isReferenceType() || T->isNullPtrType();
+  }
+
+private:
+  friend class SVal;
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == LocKind;
+  }
+};
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of NonLoc.
+//==------------------------------------------------------------------------==//
+
+namespace nonloc {
+
+enum Kind { ConcreteIntKind, SymbolValKind,
+            LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
+
+/// \brief Represents symbolic expression.
+class SymbolVal : public NonLoc {
+public:
+  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
+
+  SymbolRef getSymbol() const {
+    return (const SymExpr*) Data;
+  }
+
+  bool isExpression() const {
+    return !isa<SymbolData>(getSymbol());
+  }
+
+private:
+  friend class SVal;
+  SymbolVal() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == SymbolValKind;
+  }
+
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == SymbolValKind;
+  }
+};
+
+/// \brief Value representing integer constant.
+class ConcreteInt : public NonLoc {
+public:
+  explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
+
+  const llvm::APSInt& getValue() const {
+    return *static_cast<const llvm::APSInt*>(Data);
+  }
+
+  // Transfer functions for binary/unary operations on ConcreteInts.
+  SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
+                 const ConcreteInt& R) const;
+
+  ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
+
+  ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
+
+private:
+  friend class SVal;
+  ConcreteInt() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == ConcreteIntKind;
+  }
+
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == ConcreteIntKind;
+  }
+};
+
+class LocAsInteger : public NonLoc {
+  friend class ento::SValBuilder;
+
+  explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
+      : NonLoc(LocAsIntegerKind, &data) {
+    assert (data.first.getAs<Loc>());
+  }
+
+public:
+
+  Loc getLoc() const {
+    const std::pair<SVal, uintptr_t> *D =
+      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
+    return D->first.castAs<Loc>();
+  }
+
+  Loc getPersistentLoc() const {
+    const std::pair<SVal, uintptr_t> *D =
+      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
+    const SVal& V = D->first;
+    return V.castAs<Loc>();
+  }
+
+  unsigned getNumBits() const {
+    const std::pair<SVal, uintptr_t> *D =
+      static_cast<const std::pair<SVal, uintptr_t> *>(Data);
+    return D->second;
+  }
+
+private:
+  friend class SVal;
+  LocAsInteger() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == LocAsIntegerKind;
+  }
+
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == LocAsIntegerKind;
+  }
+};
+
+class CompoundVal : public NonLoc {
+  friend class ento::SValBuilder;
+
+  explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
+
+public:
+  const CompoundValData* getValue() const {
+    return static_cast<const CompoundValData*>(Data);
+  }
+
+  typedef llvm::ImmutableList<SVal>::iterator iterator;
+  iterator begin() const;
+  iterator end() const;
+
+private:
+  friend class SVal;
+  CompoundVal() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
+  }
+
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == CompoundValKind;
+  }
+};
+
+class LazyCompoundVal : public NonLoc {
+  friend class ento::SValBuilder;
+
+  explicit LazyCompoundVal(const LazyCompoundValData *D)
+    : NonLoc(LazyCompoundValKind, D) {}
+public:
+  const LazyCompoundValData *getCVData() const {
+    return static_cast<const LazyCompoundValData*>(Data);
+  }
+  const void *getStore() const;
+  const TypedValueRegion *getRegion() const;
+
+private:
+  friend class SVal;
+  LazyCompoundVal() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == LazyCompoundValKind;
+  }
+  static bool isKind(const NonLoc& V) {
+    return V.getSubKind() == LazyCompoundValKind;
+  }
+};
+
+} // end namespace ento::nonloc
+
+//==------------------------------------------------------------------------==//
+//  Subclasses of Loc.
+//==------------------------------------------------------------------------==//
+
+namespace loc {
+
+enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind };
+
+class GotoLabel : public Loc {
+public:
+  explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
+
+  const LabelDecl *getLabel() const {
+    return static_cast<const LabelDecl*>(Data);
+  }
+
+private:
+  friend class SVal;
+  GotoLabel() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
+  }
+
+  static bool isKind(const Loc& V) {
+    return V.getSubKind() == GotoLabelKind;
+  }
+};
+
+
+class MemRegionVal : public Loc {
+public:
+  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionKind, r) {}
+
+  /// \brief Get the underlining region.
+  const MemRegion* getRegion() const {
+    return static_cast<const MemRegion*>(Data);
+  }
+
+  /// \brief Get the underlining region and strip casts.
+  const MemRegion* stripCasts(bool StripBaseCasts = true) const;
+
+  template <typename REGION>
+  const REGION* getRegionAs() const {
+    return dyn_cast<REGION>(getRegion());
+  }
+
+  inline bool operator==(const MemRegionVal& R) const {
+    return getRegion() == R.getRegion();
+  }
+
+  inline bool operator!=(const MemRegionVal& R) const {
+    return getRegion() != R.getRegion();
+  }
+
+private:
+  friend class SVal;
+  MemRegionVal() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == LocKind &&
+           V.getSubKind() == MemRegionKind;
+  }
+
+  static bool isKind(const Loc& V) {
+    return V.getSubKind() == MemRegionKind;
+  }
+};
+
+class ConcreteInt : public Loc {
+public:
+  explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
+
+  const llvm::APSInt& getValue() const {
+    return *static_cast<const llvm::APSInt*>(Data);
+  }
+
+  // Transfer functions for binary/unary operations on ConcreteInts.
+  SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+                 const ConcreteInt& R) const;
+
+private:
+  friend class SVal;
+  ConcreteInt() {}
+  static bool isKind(const SVal& V) {
+    return V.getBaseKind() == LocKind &&
+           V.getSubKind() == ConcreteIntKind;
+  }
+
+  static bool isKind(const Loc& V) {
+    return V.getSubKind() == ConcreteIntKind;
+  }
+};
+
+} // end ento::loc namespace
+
+} // end ento namespace
+
+} // end clang namespace
+
+namespace llvm {
+static inline raw_ostream &operator<<(raw_ostream &os,
+                                            clang::ento::SVal V) {
+  V.dumpToStream(os);
+  return os;
+}
+
+template <typename T> struct isPodLike;
+template <> struct isPodLike<clang::ento::SVal> {
+  static const bool value = true;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
new file mode 100644
index 0000000..84c3166
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -0,0 +1,286 @@
+//== Store.h - Interface for maps from Locations to Values ------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the types Store and StoreManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_STORE_H
+#define LLVM_CLANG_GR_STORE_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+
+class Stmt;
+class Expr;
+class ObjCIvarDecl;
+class CXXBasePath;
+class StackFrameContext;
+
+namespace ento {
+
+class CallEvent;
+class ProgramState;
+class ProgramStateManager;
+class ScanReachableSymbols;
+
+typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+
+class StoreManager {
+protected:
+  SValBuilder &svalBuilder;
+  ProgramStateManager &StateMgr;
+
+  /// MRMgr - Manages region objects associated with this StoreManager.
+  MemRegionManager &MRMgr;
+  ASTContext &Ctx;
+
+  StoreManager(ProgramStateManager &stateMgr);
+
+public:
+  virtual ~StoreManager() {}
+
+  /// Return the value bound to specified location in a given state.
+  /// \param[in] store The analysis state.
+  /// \param[in] loc The symbolic memory location.
+  /// \param[in] T An optional type that provides a hint indicating the
+  ///   expected type of the returned value.  This is used if the value is
+  ///   lazily computed.
+  /// \return The value bound to the location \c loc.
+  virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
+
+  /// Return a state with the specified value bound to the given location.
+  /// \param[in] store The analysis state.
+  /// \param[in] loc The symbolic memory location.
+  /// \param[in] val The value to bind to location \c loc.
+  /// \return A pointer to a ProgramState object that contains the same
+  ///   bindings as \c state with the addition of having the value specified
+  ///   by \c val bound to the location given for \c loc.
+  virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
+
+  virtual StoreRef BindDefault(Store store, const MemRegion *R, SVal V);
+
+  /// \brief Create a new store with the specified binding removed.
+  /// \param ST the original store, that is the basis for the new store.
+  /// \param L the location whose binding should be removed.
+  virtual StoreRef killBinding(Store ST, Loc L) = 0;
+
+  /// getInitialStore - Returns the initial "empty" store representing the
+  ///  value bindings upon entry to an analyzed function.
+  virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0;
+
+  /// getRegionManager - Returns the internal RegionManager object that is
+  ///  used to query and manipulate MemRegion objects.
+  MemRegionManager& getRegionManager() { return MRMgr; }
+
+  virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
+    return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC));
+  }
+
+  Loc getLValueCompoundLiteral(const CompoundLiteralExpr *CL,
+                               const LocationContext *LC) {
+    return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
+  }
+
+  virtual SVal getLValueIvar(const ObjCIvarDecl *decl, SVal base);
+
+  virtual SVal getLValueField(const FieldDecl *D, SVal Base) {
+    return getLValueFieldOrIvar(D, Base);
+  }
+
+  virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
+
+  // FIXME: This should soon be eliminated altogether; clients should deal with
+  // region extents directly.
+  virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state, 
+                                                 const MemRegion *region,
+                                                 QualType EleTy) {
+    return UnknownVal();
+  }
+
+  /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
+  ///  conversions between arrays and pointers.
+  virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
+
+  /// Evaluates a chain of derived-to-base casts through the path specified in
+  /// \p Cast.
+  SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast);
+
+  /// Evaluates a chain of derived-to-base casts through the specified path.
+  SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath);
+
+  /// Evaluates a derived-to-base cast through a single level of derivation.
+  SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType,
+                         bool IsVirtual);
+
+  /// \brief Evaluates C++ dynamic_cast cast.
+  /// The callback may result in the following 3 scenarios:
+  ///  - Successful cast (ex: derived is subclass of base).
+  ///  - Failed cast (ex: derived is definitely not a subclass of base).
+  ///  - We don't know (base is a symbolic region and we don't have 
+  ///    enough info to determine if the cast will succeed at run time).
+  /// The function returns an SVal representing the derived class; it's
+  /// valid only if Failed flag is set to false.
+  SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed);
+
+  const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+
+  /// castRegion - Used by ExprEngine::VisitCast to handle casts from
+  ///  a MemRegion* to a specific location type.  'R' is the region being
+  ///  casted and 'CastToTy' the result type of the cast.
+  const MemRegion *castRegion(const MemRegion *region, QualType CastToTy);
+
+  virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
+                                      SymbolReaper& SymReaper) = 0;
+
+  virtual bool includedInBindings(Store store,
+                                  const MemRegion *region) const = 0;
+  
+  /// If the StoreManager supports it, increment the reference count of
+  /// the specified Store object.
+  virtual void incrementReferenceCount(Store store) {}
+
+  /// If the StoreManager supports it, decrement the reference count of
+  /// the specified Store object.  If the reference count hits 0, the memory
+  /// associated with the object is recycled.
+  virtual void decrementReferenceCount(Store store) {}
+
+  typedef SmallVector<const MemRegion *, 8> InvalidatedRegions;
+
+  /// invalidateRegions - Clears out the specified regions from the store,
+  ///  marking their values as unknown. Depending on the store, this may also
+  ///  invalidate additional regions that may have changed based on accessing
+  ///  the given regions. Optionally, invalidates non-static globals as well.
+  /// \param[in] store The initial store
+  /// \param[in] Values The values to invalidate.
+  /// \param[in] E The current statement being evaluated. Used to conjure
+  ///   symbols to mark the values of invalidated regions.
+  /// \param[in] Count The current block count. Used to conjure
+  ///   symbols to mark the values of invalidated regions.
+  /// \param[in] Call The call expression which will be used to determine which
+  ///   globals should get invalidated.
+  /// \param[in,out] IS A set to fill with any symbols that are no longer
+  ///   accessible. Pass \c NULL if this information will not be used.
+  /// \param[in] ITraits Information about invalidation for a particular 
+  ///   region/symbol.
+  /// \param[in,out] InvalidatedTopLevel A vector to fill with regions
+  ////  explicitly being invalidated. Pass \c NULL if this
+  ///   information will not be used.
+  /// \param[in,out] Invalidated A vector to fill with any regions being
+  ///   invalidated. This should include any regions explicitly invalidated
+  ///   even if they do not currently have bindings. Pass \c NULL if this
+  ///   information will not be used.
+  virtual StoreRef invalidateRegions(Store store,
+                                  ArrayRef<SVal> Values,
+                                  const Expr *E, unsigned Count,
+                                  const LocationContext *LCtx,
+                                  const CallEvent *Call,
+                                  InvalidatedSymbols &IS,
+                                  RegionAndSymbolInvalidationTraits &ITraits,
+                                  InvalidatedRegions *InvalidatedTopLevel,
+                                  InvalidatedRegions *Invalidated) = 0;
+
+  /// enterStackFrame - Let the StoreManager to do something when execution
+  /// engine is about to execute into a callee.
+  StoreRef enterStackFrame(Store store,
+                           const CallEvent &Call,
+                           const StackFrameContext *CalleeCtx);
+
+  /// Finds the transitive closure of symbols within the given region.
+  ///
+  /// Returns false if the visitor aborted the scan.
+  virtual bool scanReachableSymbols(Store S, const MemRegion *R,
+                                    ScanReachableSymbols &Visitor) = 0;
+
+  virtual void print(Store store, raw_ostream &Out,
+                     const char* nl, const char *sep) = 0;
+
+  class BindingsHandler {
+  public:
+    virtual ~BindingsHandler();
+    virtual bool HandleBinding(StoreManager& SMgr, Store store,
+                               const MemRegion *region, SVal val) = 0;
+  };
+
+  class FindUniqueBinding :
+  public BindingsHandler {
+    SymbolRef Sym;
+    const MemRegion* Binding;
+    bool First;
+
+  public:
+    FindUniqueBinding(SymbolRef sym)
+      : Sym(sym), Binding(nullptr), First(true) {}
+
+    bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
+                       SVal val) override;
+    LLVM_EXPLICIT operator bool() { return First && Binding; }
+    const MemRegion *getRegion() { return Binding; }
+  };
+
+  /// iterBindings - Iterate over the bindings in the Store.
+  virtual void iterBindings(Store store, BindingsHandler& f) = 0;
+
+protected:
+  const MemRegion *MakeElementRegion(const MemRegion *baseRegion,
+                                     QualType pointeeTy, uint64_t index = 0);
+
+  /// CastRetrievedVal - Used by subclasses of StoreManager to implement
+  ///  implicit casts that arise from loads from regions that are reinterpreted
+  ///  as another region.
+  SVal CastRetrievedVal(SVal val, const TypedValueRegion *region, 
+                        QualType castTy, bool performTestOnly = true);
+
+private:
+  SVal getLValueFieldOrIvar(const Decl *decl, SVal base);
+};
+
+
+inline StoreRef::StoreRef(Store store, StoreManager & smgr)
+  : store(store), mgr(smgr) {
+  if (store)
+    mgr.incrementReferenceCount(store);
+}
+
+inline StoreRef::StoreRef(const StoreRef &sr) 
+  : store(sr.store), mgr(sr.mgr)
+{ 
+  if (store)
+    mgr.incrementReferenceCount(store);
+}
+  
+inline StoreRef::~StoreRef() {
+  if (store)
+    mgr.decrementReferenceCount(store);
+}
+  
+inline StoreRef &StoreRef::operator=(StoreRef const &newStore) {
+  assert(&newStore.mgr == &mgr);
+  if (store != newStore.store) {
+    mgr.incrementReferenceCount(newStore.store);
+    mgr.decrementReferenceCount(store);
+    store = newStore.getStore();
+  }
+  return *this;
+}
+
+// FIXME: Do we need to pass ProgramStateManager anymore?
+StoreManager *CreateRegionStoreManager(ProgramStateManager& StMgr);
+StoreManager *CreateFieldsOnlyRegionStoreManager(ProgramStateManager& StMgr);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
new file mode 100644
index 0000000..d5ba003
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
@@ -0,0 +1,51 @@
+//== StoreRef.h - Smart pointer for store objects ---------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defined the type StoreRef.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_STOREREF_H
+#define LLVM_CLANG_GR_STOREREF_H
+
+#include <cassert>
+
+namespace clang {
+namespace ento {
+  
+/// Store - This opaque type encapsulates an immutable mapping from
+///  locations to values.  At a high-level, it represents the symbolic
+///  memory model.  Different subclasses of StoreManager may choose
+///  different types to represent the locations and values.
+typedef const void *Store;
+  
+class StoreManager;
+  
+class StoreRef {
+  Store store;
+  StoreManager &mgr;
+public:
+  StoreRef(Store, StoreManager &);
+  StoreRef(const StoreRef &);
+  StoreRef &operator=(StoreRef const &);
+  
+  bool operator==(const StoreRef &x) const {
+    assert(&mgr == &x.mgr);
+    return x.store == store;
+  }
+  bool operator!=(const StoreRef &x) const { return !operator==(x); }
+  
+  ~StoreRef();
+  
+  Store getStore() const { return store; }
+  const StoreManager &getStoreManager() const { return mgr; }
+};
+
+}}
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
new file mode 100644
index 0000000..3482e8d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -0,0 +1,152 @@
+//== SubEngine.h - Interface of the subengine of CoreEngine --------*- 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 interface of a subengine of the CoreEngine.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_GR_SUBENGINE_H
+#define LLVM_CLANG_GR_SUBENGINE_H
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+
+namespace clang {
+
+class CFGBlock;
+class CFGElement;
+class LocationContext;
+class Stmt;
+
+namespace ento {
+  
+struct NodeBuilderContext;
+class AnalysisManager;
+class ExplodedNodeSet;
+class ExplodedNode;
+class ProgramState;
+class ProgramStateManager;
+class BlockCounter;
+class BranchNodeBuilder;
+class IndirectGotoNodeBuilder;
+class SwitchNodeBuilder;
+class EndOfFunctionNodeBuilder;
+class NodeBuilderWithSinks;
+class MemRegion;
+
+class SubEngine {
+  virtual void anchor();
+public:
+  virtual ~SubEngine() {}
+
+  virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
+
+  virtual AnalysisManager &getAnalysisManager() = 0;
+
+  virtual ProgramStateManager &getStateManager() = 0;
+
+  /// Called by CoreEngine. Used to generate new successor
+  /// nodes by processing the 'effects' of a block-level statement.
+  virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
+                                 unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
+
+  /// Called by CoreEngine when it starts processing a CFGBlock.  The
+  /// SubEngine is expected to populate dstNodes with new nodes representing
+  /// updated analysis state, or generate no nodes at all if it doesn't.
+  virtual void processCFGBlockEntrance(const BlockEdge &L,
+                                       NodeBuilderWithSinks &nodeBuilder,
+                                       ExplodedNode *Pred) = 0;
+
+  /// Called by CoreEngine.  Used to generate successor
+  ///  nodes by processing the 'effects' of a branch condition.
+  virtual void processBranch(const Stmt *Condition, const Stmt *Term,
+                             NodeBuilderContext& BuilderCtx,
+                             ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst,
+                             const CFGBlock *DstT,
+                             const CFGBlock *DstF) = 0;
+
+  /// Called by CoreEngine.  Used to processing branching behavior
+  /// at static initalizers.
+  virtual void processStaticInitializer(const DeclStmt *DS,
+                                        NodeBuilderContext& BuilderCtx,
+                                        ExplodedNode *Pred,
+                                        ExplodedNodeSet &Dst,
+                                        const CFGBlock *DstT,
+                                        const CFGBlock *DstF) = 0;
+
+  /// Called by CoreEngine.  Used to generate successor
+  /// nodes by processing the 'effects' of a computed goto jump.
+  virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
+
+  /// Called by CoreEngine.  Used to generate successor
+  /// nodes by processing the 'effects' of a switch statement.
+  virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
+
+  /// Called by CoreEngine.  Used to generate end-of-path
+  /// nodes when the control reaches the end of a function.
+  virtual void processEndOfFunction(NodeBuilderContext& BC,
+                                    ExplodedNode *Pred) = 0;
+
+  // Generate the entry node of the callee.
+  virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0;
+
+  // Generate the first post callsite node.
+  virtual void processCallExit(ExplodedNode *Pred) = 0;
+
+  /// Called by ConstraintManager. Used to call checker-specific
+  /// logic for handling assumptions on symbolic values.
+  virtual ProgramStateRef processAssume(ProgramStateRef state,
+                                       SVal cond, bool assumption) = 0;
+
+  /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
+  ///  region change should trigger a processRegionChanges update.
+  virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
+
+  /// processRegionChanges - Called by ProgramStateManager whenever a change is
+  /// made to the store. Used to update checkers that track region values.
+  virtual ProgramStateRef 
+  processRegionChanges(ProgramStateRef state,
+                       const InvalidatedSymbols *invalidated,
+                       ArrayRef<const MemRegion *> ExplicitRegions,
+                       ArrayRef<const MemRegion *> Regions,
+                       const CallEvent *Call) = 0;
+
+
+  inline ProgramStateRef 
+  processRegionChange(ProgramStateRef state,
+                      const MemRegion* MR) {
+    return processRegionChanges(state, nullptr, MR, MR, nullptr);
+  }
+
+  virtual ProgramStateRef
+  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+
+  virtual ProgramStateRef
+  notifyCheckersOfPointerEscape(ProgramStateRef State,
+                           const InvalidatedSymbols *Invalidated,
+                           ArrayRef<const MemRegion *> ExplicitRegions,
+                           ArrayRef<const MemRegion *> Regions,
+                           const CallEvent *Call,
+                           RegionAndSymbolInvalidationTraits &HTraits) = 0;
+
+  /// printState - Called by ProgramStateManager to print checker-specific data.
+  virtual void printState(raw_ostream &Out, ProgramStateRef State,
+                          const char *NL, const char *Sep) = 0;
+
+  /// Called by CoreEngine when the analysis worklist is either empty or the
+  //  maximum number of analysis steps have been reached.
+  virtual void processEndWorklist(bool hasWorkRemaining) = 0;
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
new file mode 100644
index 0000000..ed87851
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
@@ -0,0 +1,61 @@
+//== SummaryManager.h - Generic handling of function summaries --*- 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 SummaryManager and related classes, which provides
+//  a generic mechanism for managing function summaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_SUMMARY
+#define LLVM_CLANG_GR_SUMMARY
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+
+namespace clang {
+
+namespace ento {
+
+namespace summMgr {
+
+  
+/* Key kinds:
+ 
+ - C functions
+ - C++ functions (name + parameter types)
+ - ObjC methods:
+   - Class, selector (class method)
+   - Class, selector (instance method)
+   - Category, selector (instance method)
+   - Protocol, selector (instance method)
+ - C++ methods
+  - Class, function name + parameter types + const
+ */
+  
+class SummaryKey {
+  
+};
+
+} // end namespace clang::summMgr
+  
+class SummaryManagerImpl {
+  
+};
+
+  
+template <typename T>
+class SummaryManager : SummaryManagerImpl {
+  
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
new file mode 100644
index 0000000..2b5cc18
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -0,0 +1,676 @@
+//== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values
+//  created for use by ExprEngine and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_SYMMGR_H
+#define LLVM_CLANG_GR_SYMMGR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace clang {
+  class ASTContext;
+  class StackFrameContext;
+
+namespace ento {
+  class BasicValueFactory;
+  class MemRegion;
+  class SubRegion;
+  class TypedValueRegion;
+  class VarRegion;
+
+/// \brief Symbolic value. These values used to capture symbolic execution of
+/// the program.
+class SymExpr : public llvm::FoldingSetNode {
+  virtual void anchor();
+public:
+  enum Kind { RegionValueKind, ConjuredKind, DerivedKind, ExtentKind,
+              MetadataKind,
+              BEGIN_SYMBOLS = RegionValueKind,
+              END_SYMBOLS = MetadataKind,
+              SymIntKind, IntSymKind, SymSymKind,
+              BEGIN_BINARYSYMEXPRS = SymIntKind,
+              END_BINARYSYMEXPRS = SymSymKind,
+              CastSymbolKind };
+private:
+  Kind K;
+
+protected:
+  SymExpr(Kind k) : K(k) {}
+
+public:
+  virtual ~SymExpr() {}
+
+  Kind getKind() const { return K; }
+
+  virtual void dump() const;
+
+  virtual void dumpToStream(raw_ostream &os) const {}
+
+  virtual QualType getType() const = 0;
+  virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
+
+  /// \brief Iterator over symbols that the current symbol depends on.
+  ///
+  /// For SymbolData, it's the symbol itself; for expressions, it's the
+  /// expression symbol and all the operands in it. Note, SymbolDerived is
+  /// treated as SymbolData - the iterator will NOT visit the parent region.
+  class symbol_iterator {
+    SmallVector<const SymExpr*, 5> itr;
+    void expand();
+  public:
+    symbol_iterator() {}
+    symbol_iterator(const SymExpr *SE);
+
+    symbol_iterator &operator++();
+    const SymExpr* operator*();
+
+    bool operator==(const symbol_iterator &X) const;
+    bool operator!=(const symbol_iterator &X) const;
+  };
+
+  symbol_iterator symbol_begin() const {
+    return symbol_iterator(this);
+  }
+  static symbol_iterator symbol_end() { return symbol_iterator(); }
+
+  unsigned computeComplexity() const;
+};
+
+typedef const SymExpr* SymbolRef;
+typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
+
+typedef unsigned SymbolID;
+/// \brief A symbol representing data which can be stored in a memory location
+/// (region).
+class SymbolData : public SymExpr {
+  void anchor() override;
+  const SymbolID Sym;
+
+protected:
+  SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
+
+public:
+  virtual ~SymbolData() {}
+
+  SymbolID getSymbolID() const { return Sym; }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    Kind k = SE->getKind();
+    return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS;
+  }
+};
+
+///\brief A symbol representing the value stored at a MemRegion.
+class SymbolRegionValue : public SymbolData {
+  const TypedValueRegion *R;
+
+public:
+  SymbolRegionValue(SymbolID sym, const TypedValueRegion *r)
+    : SymbolData(RegionValueKind, sym), R(r) {}
+
+  const TypedValueRegion* getRegion() const { return R; }
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) {
+    profile.AddInteger((unsigned) RegionValueKind);
+    profile.AddPointer(R);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& profile) override {
+    Profile(profile, R);
+  }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  QualType getType() const override;
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == RegionValueKind;
+  }
+};
+
+/// A symbol representing the result of an expression in the case when we do
+/// not know anything about what the expression is.
+class SymbolConjured : public SymbolData {
+  const Stmt *S;
+  QualType T;
+  unsigned Count;
+  const LocationContext *LCtx;
+  const void *SymbolTag;
+
+public:
+  SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
+		 QualType t, unsigned count,
+                 const void *symbolTag)
+    : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count),
+      LCtx(lctx),
+      SymbolTag(symbolTag) {}
+
+  const Stmt *getStmt() const { return S; }
+  unsigned getCount() const { return Count; }
+  const void *getTag() const { return SymbolTag; }
+
+  QualType getType() const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S,
+                      QualType T, unsigned Count, const LocationContext *LCtx,
+                      const void *SymbolTag) {
+    profile.AddInteger((unsigned) ConjuredKind);
+    profile.AddPointer(S);
+    profile.AddPointer(LCtx);
+    profile.Add(T);
+    profile.AddInteger(Count);
+    profile.AddPointer(SymbolTag);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& profile) override {
+    Profile(profile, S, T, Count, LCtx, SymbolTag);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == ConjuredKind;
+  }
+};
+
+/// A symbol representing the value of a MemRegion whose parent region has
+/// symbolic value.
+class SymbolDerived : public SymbolData {
+  SymbolRef parentSymbol;
+  const TypedValueRegion *R;
+
+public:
+  SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r)
+    : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {}
+
+  SymbolRef getParentSymbol() const { return parentSymbol; }
+  const TypedValueRegion *getRegion() const { return R; }
+
+  QualType getType() const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
+                      const TypedValueRegion *r) {
+    profile.AddInteger((unsigned) DerivedKind);
+    profile.AddPointer(r);
+    profile.AddPointer(parent);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& profile) override {
+    Profile(profile, parentSymbol, R);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == DerivedKind;
+  }
+};
+
+/// SymbolExtent - Represents the extent (size in bytes) of a bounded region.
+///  Clients should not ask the SymbolManager for a region's extent. Always use
+///  SubRegion::getExtent instead -- the value returned may not be a symbol.
+class SymbolExtent : public SymbolData {
+  const SubRegion *R;
+  
+public:
+  SymbolExtent(SymbolID sym, const SubRegion *r)
+  : SymbolData(ExtentKind, sym), R(r) {}
+
+  const SubRegion *getRegion() const { return R; }
+
+  QualType getType() const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
+    profile.AddInteger((unsigned) ExtentKind);
+    profile.AddPointer(R);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& profile) override {
+    Profile(profile, R);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == ExtentKind;
+  }
+};
+
+/// SymbolMetadata - Represents path-dependent metadata about a specific region.
+///  Metadata symbols remain live as long as they are marked as in use before
+///  dead-symbol sweeping AND their associated regions are still alive.
+///  Intended for use by checkers.
+class SymbolMetadata : public SymbolData {
+  const MemRegion* R;
+  const Stmt *S;
+  QualType T;
+  unsigned Count;
+  const void *Tag;
+public:
+  SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
+                 unsigned count, const void *tag)
+  : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {}
+
+  const MemRegion *getRegion() const { return R; }
+  const Stmt *getStmt() const { return S; }
+  unsigned getCount() const { return Count; }
+  const void *getTag() const { return Tag; }
+
+  QualType getType() const override;
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
+                      const Stmt *S, QualType T, unsigned Count,
+                      const void *Tag) {
+    profile.AddInteger((unsigned) MetadataKind);
+    profile.AddPointer(R);
+    profile.AddPointer(S);
+    profile.Add(T);
+    profile.AddInteger(Count);
+    profile.AddPointer(Tag);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& profile) override {
+    Profile(profile, R, S, T, Count, Tag);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == MetadataKind;
+  }
+};
+
+/// \brief Represents a cast expression.
+class SymbolCast : public SymExpr {
+  const SymExpr *Operand;
+  /// Type of the operand.
+  QualType FromTy;
+  /// The type of the result.
+  QualType ToTy;
+
+public:
+  SymbolCast(const SymExpr *In, QualType From, QualType To) :
+    SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { }
+
+  QualType getType() const override { return ToTy; }
+
+  const SymExpr *getOperand() const { return Operand; }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& ID,
+                      const SymExpr *In, QualType From, QualType To) {
+    ID.AddInteger((unsigned) CastSymbolKind);
+    ID.AddPointer(In);
+    ID.Add(From);
+    ID.Add(To);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) override {
+    Profile(ID, Operand, FromTy, ToTy);
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == CastSymbolKind;
+  }
+};
+
+/// \brief Represents a symbolic expression involving a binary operator 
+class BinarySymExpr : public SymExpr {
+  BinaryOperator::Opcode Op;
+  QualType T;
+
+protected:
+  BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
+    : SymExpr(k), Op(op), T(t) {}
+
+public:
+  // FIXME: We probably need to make this out-of-line to avoid redundant
+  // generation of virtual functions.
+  QualType getType() const override { return T; }
+
+  BinaryOperator::Opcode getOpcode() const { return Op; }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    Kind k = SE->getKind();
+    return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
+  }
+};
+
+/// \brief Represents a symbolic expression like 'x' + 3.
+class SymIntExpr : public BinarySymExpr {
+  const SymExpr *LHS;
+  const llvm::APSInt& RHS;
+
+public:
+  SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+             const llvm::APSInt& rhs, QualType t)
+    : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {}
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  const SymExpr *getLHS() const { return LHS; }
+  const llvm::APSInt &getRHS() const { return RHS; }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
+                      BinaryOperator::Opcode op, const llvm::APSInt& rhs,
+                      QualType t) {
+    ID.AddInteger((unsigned) SymIntKind);
+    ID.AddPointer(lhs);
+    ID.AddInteger(op);
+    ID.AddPointer(&rhs);
+    ID.Add(t);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) override {
+    Profile(ID, LHS, getOpcode(), RHS, getType());
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == SymIntKind;
+  }
+};
+
+/// \brief Represents a symbolic expression like 3 - 'x'.
+class IntSymExpr : public BinarySymExpr {
+  const llvm::APSInt& LHS;
+  const SymExpr *RHS;
+
+public:
+  IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op,
+             const SymExpr *rhs, QualType t)
+    : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {}
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  const SymExpr *getRHS() const { return RHS; }
+  const llvm::APSInt &getLHS() const { return LHS; }
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs,
+                      BinaryOperator::Opcode op, const SymExpr *rhs,
+                      QualType t) {
+    ID.AddInteger((unsigned) IntSymKind);
+    ID.AddPointer(&lhs);
+    ID.AddInteger(op);
+    ID.AddPointer(rhs);
+    ID.Add(t);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) override {
+    Profile(ID, LHS, getOpcode(), RHS, getType());
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == IntSymKind;
+  }
+};
+
+/// \brief Represents a symbolic expression like 'x' + 'y'.
+class SymSymExpr : public BinarySymExpr {
+  const SymExpr *LHS;
+  const SymExpr *RHS;
+
+public:
+  SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
+             QualType t)
+    : BinarySymExpr(SymSymKind, op, t), LHS(lhs), RHS(rhs) {}
+
+  const SymExpr *getLHS() const { return LHS; }
+  const SymExpr *getRHS() const { return RHS; }
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
+                    BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
+    ID.AddInteger((unsigned) SymSymKind);
+    ID.AddPointer(lhs);
+    ID.AddInteger(op);
+    ID.AddPointer(rhs);
+    ID.Add(t);
+  }
+
+  void Profile(llvm::FoldingSetNodeID& ID) override {
+    Profile(ID, LHS, getOpcode(), RHS, getType());
+  }
+
+  // Implement isa<T> support.
+  static inline bool classof(const SymExpr *SE) {
+    return SE->getKind() == SymSymKind;
+  }
+};
+
+class SymbolManager {
+  typedef llvm::FoldingSet<SymExpr> DataSetTy;
+  typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy*> SymbolDependTy;
+
+  DataSetTy DataSet;
+  /// Stores the extra dependencies between symbols: the data should be kept
+  /// alive as long as the key is live.
+  SymbolDependTy SymbolDependencies;
+  unsigned SymbolCounter;
+  llvm::BumpPtrAllocator& BPAlloc;
+  BasicValueFactory &BV;
+  ASTContext &Ctx;
+
+public:
+  SymbolManager(ASTContext &ctx, BasicValueFactory &bv,
+                llvm::BumpPtrAllocator& bpalloc)
+    : SymbolDependencies(16), SymbolCounter(0),
+      BPAlloc(bpalloc), BV(bv), Ctx(ctx) {}
+
+  ~SymbolManager();
+
+  static bool canSymbolicate(QualType T);
+
+  /// \brief Make a unique symbol for MemRegion R according to its kind.
+  const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R);
+
+  const SymbolConjured* conjureSymbol(const Stmt *E,
+                                      const LocationContext *LCtx,
+                                      QualType T,
+                                      unsigned VisitCount,
+                                      const void *SymbolTag = nullptr);
+
+  const SymbolConjured* conjureSymbol(const Expr *E,
+                                      const LocationContext *LCtx,
+                                      unsigned VisitCount,
+                                      const void *SymbolTag = nullptr) {
+    return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag);
+  }
+
+  const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol,
+                                        const TypedValueRegion *R);
+
+  const SymbolExtent *getExtentSymbol(const SubRegion *R);
+
+  /// \brief Creates a metadata symbol associated with a specific region.
+  ///
+  /// VisitCount can be used to differentiate regions corresponding to
+  /// different loop iterations, thus, making the symbol path-dependent.
+  const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
+                                          QualType T, unsigned VisitCount,
+                                          const void *SymbolTag = nullptr);
+
+  const SymbolCast* getCastSymbol(const SymExpr *Operand,
+                                  QualType From, QualType To);
+
+  const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                  const llvm::APSInt& rhs, QualType t);
+
+  const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op,
+                                  const llvm::APSInt& rhs, QualType t) {
+    return getSymIntExpr(&lhs, op, rhs, t);
+  }
+
+  const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs,
+                                  BinaryOperator::Opcode op,
+                                  const SymExpr *rhs, QualType t);
+
+  const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
+                                  const SymExpr *rhs, QualType t);
+
+  QualType getType(const SymExpr *SE) const {
+    return SE->getType();
+  }
+
+  /// \brief Add artificial symbol dependency.
+  ///
+  /// The dependent symbol should stay alive as long as the primary is alive.
+  void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent);
+
+  const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary);
+
+  ASTContext &getContext() { return Ctx; }
+  BasicValueFactory &getBasicVals() { return BV; }
+};
+
+/// \brief A class responsible for cleaning up unused symbols.
+class SymbolReaper {
+  enum SymbolStatus {
+    NotProcessed,
+    HaveMarkedDependents
+  };
+
+  typedef llvm::DenseSet<SymbolRef> SymbolSetTy;
+  typedef llvm::DenseMap<SymbolRef, SymbolStatus> SymbolMapTy;
+  typedef llvm::DenseSet<const MemRegion *> RegionSetTy;
+
+  SymbolMapTy TheLiving;
+  SymbolSetTy MetadataInUse;
+  SymbolSetTy TheDead;
+
+  RegionSetTy RegionRoots;
+  
+  const StackFrameContext *LCtx;
+  const Stmt *Loc;
+  SymbolManager& SymMgr;
+  StoreRef reapedStore;
+  llvm::DenseMap<const MemRegion *, unsigned> includedRegionCache;
+
+public:
+  /// \brief Construct a reaper object, which removes everything which is not
+  /// live before we execute statement s in the given location context.
+  ///
+  /// If the statement is NULL, everything is this and parent contexts is
+  /// considered live.
+  /// If the stack frame context is NULL, everything on stack is considered
+  /// dead.
+  SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr,
+               StoreManager &storeMgr)
+   : LCtx(Ctx), Loc(s), SymMgr(symmgr),
+     reapedStore(nullptr, storeMgr) {}
+
+  ~SymbolReaper() {}
+
+  const LocationContext *getLocationContext() const { return LCtx; }
+
+  bool isLive(SymbolRef sym);
+  bool isLiveRegion(const MemRegion *region);
+  bool isLive(const Stmt *ExprVal, const LocationContext *LCtx) const;
+  bool isLive(const VarRegion *VR, bool includeStoreBindings = false) const;
+
+  /// \brief Unconditionally marks a symbol as live.
+  ///
+  /// This should never be
+  /// used by checkers, only by the state infrastructure such as the store and
+  /// environment. Checkers should instead use metadata symbols and markInUse.
+  void markLive(SymbolRef sym);
+
+  /// \brief Marks a symbol as important to a checker.
+  ///
+  /// For metadata symbols,
+  /// this will keep the symbol alive as long as its associated region is also
+  /// live. For other symbols, this has no effect; checkers are not permitted
+  /// to influence the life of other symbols. This should be used before any
+  /// symbol marking has occurred, i.e. in the MarkLiveSymbols callback.
+  void markInUse(SymbolRef sym);
+
+  /// \brief If a symbol is known to be live, marks the symbol as live.
+  ///
+  ///  Otherwise, if the symbol cannot be proven live, it is marked as dead.
+  ///  Returns true if the symbol is dead, false if live.
+  bool maybeDead(SymbolRef sym);
+
+  typedef SymbolSetTy::const_iterator dead_iterator;
+  dead_iterator dead_begin() const { return TheDead.begin(); }
+  dead_iterator dead_end() const { return TheDead.end(); }
+
+  bool hasDeadSymbols() const {
+    return !TheDead.empty();
+  }
+  
+  typedef RegionSetTy::const_iterator region_iterator;
+  region_iterator region_begin() const { return RegionRoots.begin(); }
+  region_iterator region_end() const { return RegionRoots.end(); }
+
+  /// \brief Returns whether or not a symbol has been confirmed dead.
+  ///
+  /// This should only be called once all marking of dead symbols has completed.
+  /// (For checkers, this means only in the evalDeadSymbols callback.)
+  bool isDead(SymbolRef sym) const {
+    return TheDead.count(sym);
+  }
+  
+  void markLive(const MemRegion *region);
+  
+  /// \brief Set to the value of the symbolic store after
+  /// StoreManager::removeDeadBindings has been called.
+  void setReapedStore(StoreRef st) { reapedStore = st; }
+
+private:
+  /// Mark the symbols dependent on the input symbol as live.
+  void markDependentsLive(SymbolRef sym);
+};
+
+class SymbolVisitor {
+public:
+  /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols.
+  ///
+  /// The method returns \c true if symbols should continue be scanned and \c
+  /// false otherwise.
+  virtual bool VisitSymbol(SymbolRef sym) = 0;
+  virtual bool VisitMemRegion(const MemRegion *region) { return true; }
+  virtual ~SymbolVisitor();
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+namespace llvm {
+static inline raw_ostream &operator<<(raw_ostream &os,
+                                      const clang::ento::SymExpr *SE) {
+  SE->dumpToStream(os);
+  return os;
+}
+} // end llvm namespace
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
new file mode 100644
index 0000000..4c58d4b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
@@ -0,0 +1,46 @@
+//== TaintManager.h - Managing taint --------------------------- -*- 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 APIs for adding, removing, querying symbol taint.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TAINTMANAGER_H
+#define LLVM_CLANG_TAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace clang {
+namespace ento {
+
+/// The GDM component containing the tainted root symbols. We lazily infer the
+/// taint of the dependent symbols. Currently, this is a map from a symbol to
+/// tag kind. TODO: Should support multiple tag kinds.
+// FIXME: This does not use the nice trait macros because it must be accessible
+// from multiple translation units.
+struct TaintMap {};
+typedef llvm::ImmutableMap<SymbolRef, TaintTagType> TaintMapImpl;
+template<> struct ProgramStateTrait<TaintMap>
+    :  public ProgramStatePartialTrait<TaintMapImpl> {
+  static void *GDMIndex() { static int index = 0; return &index; }
+};
+
+class TaintManager {
+
+  TaintManager() {}
+};
+
+}
+}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
new file mode 100644
index 0000000..8ddc8b9
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
@@ -0,0 +1,27 @@
+//== TaintTag.h - Path-sensitive "State" for tracking values -*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a set of taint tags. Several tags are used to differentiate kinds
+// of taint.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_TAINTTAG_H
+#define LLVM_CLANG_TAINTTAG_H
+
+namespace clang {
+namespace ento {
+
+/// The type of taint, which helps to differentiate between different types of
+/// taint.
+typedef unsigned TaintTagType;
+static const TaintTagType TaintTagGeneric = 0;
+
+}}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
new file mode 100644
index 0000000..3ed145d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -0,0 +1,100 @@
+//==- WorkList.h - Worklist class used by CoreEngine ---------------*- 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 WorkList, a pure virtual class that represents an opaque
+//  worklist used by CoreEngine to explore the reachability state space.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_WORKLIST
+#define LLVM_CLANG_GR_WORKLIST
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include <cassert>
+
+namespace clang {
+  
+class CFGBlock;
+
+namespace ento {
+
+class WorkListUnit {
+  ExplodedNode *node;
+  BlockCounter counter;
+  const CFGBlock *block;
+  unsigned blockIdx; // This is the index of the next statement.
+
+public:
+  WorkListUnit(ExplodedNode *N, BlockCounter C,
+               const CFGBlock *B, unsigned idx)
+  : node(N),
+    counter(C),
+    block(B),
+    blockIdx(idx) {}
+
+  explicit WorkListUnit(ExplodedNode *N, BlockCounter C)
+  : node(N),
+    counter(C),
+    block(nullptr),
+    blockIdx(0) {}
+
+  /// Returns the node associated with the worklist unit.
+  ExplodedNode *getNode() const { return node; }
+  
+  /// Returns the block counter map associated with the worklist unit.
+  BlockCounter getBlockCounter() const { return counter; }
+
+  /// Returns the CFGblock associated with the worklist unit.
+  const CFGBlock *getBlock() const { return block; }
+  
+  /// Return the index within the CFGBlock for the worklist unit.
+  unsigned getIndex() const { return blockIdx; }
+};
+
+class WorkList {
+  BlockCounter CurrentCounter;
+public:
+  virtual ~WorkList();
+  virtual bool hasWork() const = 0;
+
+  virtual void enqueue(const WorkListUnit& U) = 0;
+
+  void enqueue(ExplodedNode *N, const CFGBlock *B, unsigned idx) {
+    enqueue(WorkListUnit(N, CurrentCounter, B, idx));
+  }
+
+  void enqueue(ExplodedNode *N) {
+    assert(N->getLocation().getKind() != ProgramPoint::PostStmtKind);
+    enqueue(WorkListUnit(N, CurrentCounter));
+  }
+
+  virtual WorkListUnit dequeue() = 0;
+
+  void setBlockCounter(BlockCounter C) { CurrentCounter = C; }
+  BlockCounter getBlockCounter() const { return CurrentCounter; }
+
+  class Visitor {
+  public:
+    Visitor() {}
+    virtual ~Visitor();
+    virtual bool visit(const WorkListUnit &U) = 0;
+  };
+  virtual bool visitItemsInWorkList(Visitor &V) = 0;
+  
+  static WorkList *makeDFS();
+  static WorkList *makeBFS();
+  static WorkList *makeBFSBlockDFSContents();
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
new file mode 100644
index 0000000..30e5d3d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -0,0 +1,49 @@
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the functions necessary for a front-end to run various
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H
+#define LLVM_CLANG_GR_ANALYSISCONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include <string>
+
+namespace clang {
+
+class Preprocessor;
+class DiagnosticsEngine;
+
+namespace ento {
+class CheckerManager;
+
+class AnalysisASTConsumer : public ASTConsumer {
+public:
+  virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
+};
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes.  (The set of analyses run is controlled by command-line
+/// options.)
+AnalysisASTConsumer *CreateAnalysisConsumer(const Preprocessor &pp,
+                                            const std::string &output,
+                                            AnalyzerOptionsRef opts,
+                                            ArrayRef<std::string> plugins);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
new file mode 100644
index 0000000..1df8c09
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -0,0 +1,33 @@
+//===-- CheckerRegistration.h - Checker Registration Function ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H
+#define LLVM_CLANG_SA_FRONTEND_CHECKERREGISTRATION_H
+
+#include "clang/Basic/LLVM.h"
+#include <string>
+
+namespace clang {
+  class AnalyzerOptions;
+  class LangOptions;
+  class DiagnosticsEngine;
+
+namespace ento {
+  class CheckerManager;
+
+CheckerManager *createCheckerManager(AnalyzerOptions &opts,
+                                     const LangOptions &langOpts,
+                                     ArrayRef<std::string> plugins,
+                                     DiagnosticsEngine &diags);
+
+} // end ento namespace
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
new file mode 100644
index 0000000..21ecfc2
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -0,0 +1,35 @@
+//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_FRONTENDACTIONS_H
+#define LLVM_CLANG_GR_FRONTENDACTIONS_H
+
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+
+namespace ento {
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+class AnalysisAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+};
+
+void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
+
+} // end GR namespace
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
new file mode 100644
index 0000000..765e7d2
--- /dev/null
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -0,0 +1,65 @@
+//===--- ArgumentsAdjusters.h - Command line arguments adjuster -*- 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 base abstract class ArgumentsAdjuster and its descendants.
+// These classes are intended to modify command line arguments obtained from
+// a compilation database before they are used to run a frontend action.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
+#define LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace tooling {
+
+/// \brief A sequence of command line arguments.
+typedef std::vector<std::string> CommandLineArguments;
+
+/// \brief Abstract interface for a command line adjusters.
+///
+/// This abstract interface describes a command line argument adjuster,
+/// which is responsible for command line arguments modification before
+/// the arguments are used to run a frontend action.
+class ArgumentsAdjuster {
+  virtual void anchor();
+public:
+  /// \brief Returns adjusted command line arguments.
+  ///
+  /// \param Args Input sequence of command line arguments.
+  ///
+  /// \returns Modified sequence of command line arguments.
+  virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0;
+  virtual ~ArgumentsAdjuster() {
+  }
+};
+
+/// \brief Syntax check only command line adjuster.
+///
+/// This class implements ArgumentsAdjuster interface and converts input
+/// command line arguments to the "syntax check only" variant.
+class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster {
+  CommandLineArguments Adjust(const CommandLineArguments &Args) override;
+};
+
+/// \brief An argument adjuster which removes output-related command line
+/// arguments.
+class ClangStripOutputAdjuster : public ArgumentsAdjuster {
+  CommandLineArguments Adjust(const CommandLineArguments &Args) override;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
+
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
new file mode 100644
index 0000000..815ede8
--- /dev/null
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -0,0 +1,97 @@
+//===- CommonOptionsParser.h - common options for clang tools -*- C++ -*-=====//
+//
+//                     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 CommonOptionsParser class used to parse common
+//  command-line options for clang tools, so that they can be run as separate
+//  command-line applications with a consistent common interface for handling
+//  compilation database and input files.
+//
+//  It provides a common subset of command-line options, common algorithm
+//  for locating a compilation database and source files, and help messages
+//  for the basic command-line interface.
+//
+//  It creates a CompilationDatabase and reads common command-line options.
+//
+//  This class uses the Clang Tooling infrastructure, see
+//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+//  for details on setting it up with LLVM source tree.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
+#define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace clang {
+namespace tooling {
+/// \brief A parser for options common to all command-line Clang tools.
+///
+/// Parses a common subset of command-line arguments, locates and loads a
+/// compilation commands database and runs a tool with user-specified action. It
+/// also contains a help message for the common command-line options.
+///
+/// An example of usage:
+/// \code
+/// #include "clang/Frontend/FrontendActions.h"
+/// #include "clang/Tooling/CommonOptionsParser.h"
+/// #include "llvm/Support/CommandLine.h"
+///
+/// using namespace clang::tooling;
+/// using namespace llvm;
+///
+/// static cl::OptionCategory MyToolCategory("My tool options");
+/// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
+/// static cl::extrahelp MoreHelp("\nMore help text...");
+/// static cl::opt<bool> YourOwnOption(...);
+/// ...
+///
+/// int main(int argc, const char **argv) {
+///   CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
+///   ClangTool Tool(OptionsParser.getCompilations(),
+///                  OptionsParser.getSourcePathListi());
+///   return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
+/// }
+/// \endcode
+class CommonOptionsParser {
+public:
+  /// \brief Parses command-line, initializes a compilation database.
+  ///
+  /// This constructor can change argc and argv contents, e.g. consume
+  /// command-line options used for creating FixedCompilationDatabase.
+  ///
+  /// All options not belonging to \p Category become hidden.
+  ///
+  /// This constructor exits program in case of error.
+  CommonOptionsParser(int &argc, const char **argv,
+                      llvm::cl::OptionCategory &Category,
+                      const char *Overview = nullptr);
+
+  /// Returns a reference to the loaded compilations database.
+  CompilationDatabase &getCompilations() {
+    return *Compilations;
+  }
+
+  /// Returns a list of source file paths to process.
+  std::vector<std::string> getSourcePathList() {
+    return SourcePathList;
+  }
+
+  static const char *const HelpMessage;
+
+private:
+  std::unique_ptr<CompilationDatabase> Compilations;
+  std::vector<std::string> SourcePathList;
+};
+
+}  // namespace tooling
+}  // namespace clang
+
+#endif  // LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
new file mode 100644
index 0000000..d1e729a
--- /dev/null
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -0,0 +1,216 @@
+//===--- CompilationDatabase.h - --------------------------------*- 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 an interface and multiple implementations for
+//  CompilationDatabases.
+//
+//  While C++ refactoring and analysis tools are not compilers, and thus
+//  don't run as part of the build system, they need the exact information
+//  of a build in order to be able to correctly understand the C++ code of
+//  the project. This information is provided via the CompilationDatabase
+//  interface.
+//
+//  To create a CompilationDatabase from a build directory one can call
+//  CompilationDatabase::loadFromDirectory(), which deduces the correct
+//  compilation database from the root of the build tree.
+//
+//  See the concrete subclasses of CompilationDatabase for currently supported
+//  formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
+#define LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+/// \brief Specifies the working directory and command of a compilation.
+struct CompileCommand {
+  CompileCommand() {}
+  CompileCommand(Twine Directory, std::vector<std::string> CommandLine)
+      : Directory(Directory.str()), CommandLine(std::move(CommandLine)) {}
+
+  /// \brief The working directory the command was executed from.
+  std::string Directory;
+
+  /// \brief The command line that was executed.
+  std::vector<std::string> CommandLine;
+
+  /// \brief An optional mapping from each file's path to its content for all
+  /// files needed for the compilation that are not available via the file
+  /// system.
+  ///
+  /// Note that a tool implementation is required to fall back to the file
+  /// system if a source file is not provided in the mapped sources, as
+  /// compilation databases will usually not provide all files in mapped sources
+  /// for performance reasons.
+  std::vector<std::pair<std::string, std::string> > MappedSources;
+};
+
+/// \brief Interface for compilation databases.
+///
+/// A compilation database allows the user to retrieve all compile command lines
+/// that a specified file is compiled with in a project.
+/// The retrieved compile command lines can be used to run clang tools over
+/// a subset of the files in a project.
+class CompilationDatabase {
+public:
+  virtual ~CompilationDatabase();
+
+  /// \brief Loads a compilation database from a build directory.
+  ///
+  /// Looks at the specified 'BuildDirectory' and creates a compilation database
+  /// that allows to query compile commands for source files in the
+  /// corresponding source tree.
+  ///
+  /// Returns NULL and sets ErrorMessage if we were not able to build up a
+  /// compilation database for the build directory.
+  ///
+  /// FIXME: Currently only supports JSON compilation databases, which
+  /// are named 'compile_commands.json' in the given directory. Extend this
+  /// for other build types (like ninja build files).
+  static CompilationDatabase *loadFromDirectory(StringRef BuildDirectory,
+                                                std::string &ErrorMessage);
+
+  /// \brief Tries to detect a compilation database location and load it.
+  ///
+  /// Looks for a compilation database in all parent paths of file 'SourceFile'
+  /// by calling loadFromDirectory.
+  static CompilationDatabase *autoDetectFromSource(StringRef SourceFile,
+                                                   std::string &ErrorMessage);
+
+  /// \brief Tries to detect a compilation database location and load it.
+  ///
+  /// Looks for a compilation database in directory 'SourceDir' and all
+  /// its parent paths by calling loadFromDirectory.
+  static CompilationDatabase *autoDetectFromDirectory(StringRef SourceDir,
+                                                      std::string &ErrorMessage);
+
+  /// \brief Returns all compile commands in which the specified file was
+  /// compiled.
+  ///
+  /// This includes compile comamnds that span multiple source files.
+  /// For example, consider a project with the following compilations:
+  /// $ clang++ -o test a.cc b.cc t.cc
+  /// $ clang++ -o production a.cc b.cc -DPRODUCTION
+  /// A compilation database representing the project would return both command
+  /// lines for a.cc and b.cc and only the first command line for t.cc.
+  virtual std::vector<CompileCommand> getCompileCommands(
+    StringRef FilePath) const = 0;
+
+  /// \brief Returns the list of all files available in the compilation database.
+  virtual std::vector<std::string> getAllFiles() const = 0;
+
+  /// \brief Returns all compile commands for all the files in the compilation
+  /// database.
+  ///
+  /// FIXME: Add a layer in Tooling that provides an interface to run a tool
+  /// over all files in a compilation database. Not all build systems have the
+  /// ability to provide a feasible implementation for \c getAllCompileCommands.
+  virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
+};
+
+/// \brief Interface for compilation database plugins.
+///
+/// A compilation database plugin allows the user to register custom compilation
+/// databases that are picked up as compilation database if the corresponding
+/// library is linked in. To register a plugin, declare a static variable like:
+///
+/// \code
+/// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin>
+/// X("my-compilation-database", "Reads my own compilation database");
+/// \endcode
+class CompilationDatabasePlugin {
+public:
+  virtual ~CompilationDatabasePlugin();
+
+  /// \brief Loads a compilation database from a build directory.
+  ///
+  /// \see CompilationDatabase::loadFromDirectory().
+  virtual CompilationDatabase *loadFromDirectory(StringRef Directory,
+                                                 std::string &ErrorMessage) = 0;
+};
+
+/// \brief A compilation database that returns a single compile command line.
+///
+/// Useful when we want a tool to behave more like a compiler invocation.
+class FixedCompilationDatabase : public CompilationDatabase {
+public:
+  /// \brief Creates a FixedCompilationDatabase from the arguments after "--".
+  ///
+  /// Parses the given command line for "--". If "--" is found, the rest of
+  /// the arguments will make up the command line in the returned
+  /// FixedCompilationDatabase.
+  /// The arguments after "--" must not include positional parameters or the
+  /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase
+  /// when a CompileCommand is requested. The argv[0] of the returned command
+  /// line will be "clang-tool".
+  ///
+  /// Returns NULL in case "--" is not found.
+  ///
+  /// The argument list is meant to be compatible with normal llvm command line
+  /// parsing in main methods.
+  /// int main(int argc, char **argv) {
+  ///   std::unique_ptr<FixedCompilationDatabase> Compilations(
+  ///     FixedCompilationDatabase::loadFromCommandLine(argc, argv));
+  ///   cl::ParseCommandLineOptions(argc, argv);
+  ///   ...
+  /// }
+  ///
+  /// \param Argc The number of command line arguments - will be changed to
+  /// the number of arguments before "--", if "--" was found in the argument
+  /// list.
+  /// \param Argv Points to the command line arguments.
+  /// \param Directory The base directory used in the FixedCompilationDatabase.
+  static FixedCompilationDatabase *loadFromCommandLine(int &Argc,
+                                                       const char **Argv,
+                                                       Twine Directory = ".");
+
+  /// \brief Constructs a compilation data base from a specified directory
+  /// and command line.
+  FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
+
+  /// \brief Returns the given compile command.
+  ///
+  /// Will always return a vector with one entry that contains the directory
+  /// and command line specified at construction with "clang-tool" as argv[0]
+  /// and 'FilePath' as positional argument.
+  std::vector<CompileCommand>
+  getCompileCommands(StringRef FilePath) const override;
+
+  /// \brief Returns the list of all files available in the compilation database.
+  ///
+  /// Note: This is always an empty list for the fixed compilation database.
+  std::vector<std::string> getAllFiles() const override;
+
+  /// \brief Returns all compile commands for all the files in the compilation
+  /// database.
+  ///
+  /// Note: This is always an empty list for the fixed compilation database.
+  std::vector<CompileCommand> getAllCompileCommands() const override;
+
+private:
+  /// This is built up to contain a single entry vector to be returned from
+  /// getCompileCommands after adding the positional argument.
+  std::vector<CompileCommand> CompileCommands;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_COMPILATION_DATABASE_H
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
new file mode 100644
index 0000000..84fcd24
--- /dev/null
+++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -0,0 +1,27 @@
+//===--- CompilationDatabasePluginRegistry.h - ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
+#define LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
+
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/Support/Registry.h"
+
+namespace clang {
+namespace tooling {
+
+class CompilationDatabasePlugin;
+
+typedef llvm::Registry<CompilationDatabasePlugin>
+    CompilationDatabasePluginRegistry;
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_COMPILATION_DATABASE_PLUGIN_REGISTRY_H
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
new file mode 100644
index 0000000..be37baf
--- /dev/null
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -0,0 +1,89 @@
+//===--- FileMatchTrie.h - --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements a match trie to find the matching file in a compilation
+//  database based on a given path in the presence of symlinks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
+#define LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+struct PathComparator {
+  virtual ~PathComparator() {}
+  virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
+};
+class FileMatchTrieNode;
+
+/// \brief A trie to efficiently match against the entries of the compilation
+/// database in order of matching suffix length.
+///
+/// When a clang tool is supposed to operate on a specific file, we have to
+/// find the corresponding file in the compilation database. Although entries
+/// in the compilation database are keyed by filename, a simple string match
+/// is insufficient because of symlinks. Commonly, a project hierarchy looks
+/// like this:
+///   /<project-root>/src/<path>/<somefile>.cc      (used as input for the tool)
+///   /<project-root>/build/<symlink-to-src>/<path>/<somefile>.cc (stored in DB)
+///
+/// Furthermore, there might be symlinks inside the source folder or inside the
+/// database, so that the same source file is translated with different build
+/// options.
+///
+/// For a given input file, the \c FileMatchTrie finds its entries in order
+/// of matching suffix length. For each suffix length, there might be one or
+/// more entries in the database. For each of those entries, it calls
+/// \c llvm::sys::fs::equivalent() (injected as \c PathComparator). There might
+/// be zero or more entries with the same matching suffix length that are
+/// equivalent to the input file. Three cases are distinguished:
+/// 0  equivalent files: Continue with the next suffix length.
+/// 1  equivalent file:  Best match found, return it.
+/// >1 equivalent files: Match is ambiguous, return error.
+class FileMatchTrie {
+public:
+  FileMatchTrie();
+
+  /// \brief Construct a new \c FileMatchTrie with the given \c PathComparator.
+  ///
+  /// The \c FileMatchTrie takes ownership of 'Comparator'. Used for testing.
+  FileMatchTrie(PathComparator* Comparator);
+
+  ~FileMatchTrie();
+
+  /// \brief Insert a new absolute path. Relative paths are ignored.
+  void insert(StringRef NewPath);
+
+  /// \brief Finds the corresponding file in this trie.
+  ///
+  /// Returns file name stored in this trie that is equivalent to 'FileName'
+  /// according to 'Comparator', if it can be uniquely identified. If there
+  /// are no matches an empty \c StringRef is returned. If there are ambigious
+  /// matches, an empty \c StringRef is returned and a corresponding message
+  /// written to 'Error'.
+  StringRef findEquivalent(StringRef FileName,
+                           raw_ostream &Error) const;
+private:
+  FileMatchTrieNode *Root;
+  std::unique_ptr<PathComparator> Comparator;
+};
+
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
new file mode 100644
index 0000000..1b33359
--- /dev/null
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -0,0 +1,115 @@
+//===--- JSONCompilationDatabase.h - ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  The JSONCompilationDatabase finds compilation databases supplied as a file
+//  'compile_commands.json'.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
+#define LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/FileMatchTrie.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+/// \brief A JSON based compilation database.
+///
+/// JSON compilation database files must contain a list of JSON objects which
+/// provide the command lines in the attributes 'directory', 'command' and
+/// 'file':
+/// [
+///   { "directory": "<working directory of the compile>",
+///     "command": "<compile command line>",
+///     "file": "<path to source file>"
+///   },
+///   ...
+/// ]
+/// Each object entry defines one compile action. The specified file is
+/// considered to be the main source file for the translation unit.
+///
+/// JSON compilation databases can for example be generated in CMake projects
+/// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS.
+class JSONCompilationDatabase : public CompilationDatabase {
+public:
+  /// \brief Loads a JSON compilation database from the specified file.
+  ///
+  /// Returns NULL and sets ErrorMessage if the database could not be
+  /// loaded from the given file.
+  static JSONCompilationDatabase *loadFromFile(StringRef FilePath,
+                                               std::string &ErrorMessage);
+
+  /// \brief Loads a JSON compilation database from a data buffer.
+  ///
+  /// Returns NULL and sets ErrorMessage if the database could not be loaded.
+  static JSONCompilationDatabase *loadFromBuffer(StringRef DatabaseString,
+                                                 std::string &ErrorMessage);
+
+  /// \brief Returns all compile comamnds in which the specified file was
+  /// compiled.
+  ///
+  /// FIXME: Currently FilePath must be an absolute path inside the
+  /// source directory which does not have symlinks resolved.
+  std::vector<CompileCommand>
+  getCompileCommands(StringRef FilePath) const override;
+
+  /// \brief Returns the list of all files available in the compilation database.
+  ///
+  /// These are the 'file' entries of the JSON objects.
+  std::vector<std::string> getAllFiles() const override;
+
+  /// \brief Returns all compile commands for all the files in the compilation
+  /// database.
+  std::vector<CompileCommand> getAllCompileCommands() const override;
+
+private:
+  /// \brief Constructs a JSON compilation database on a memory buffer.
+  JSONCompilationDatabase(llvm::MemoryBuffer *Database)
+    : Database(Database), YAMLStream(Database->getBuffer(), SM) {}
+
+  /// \brief Parses the database file and creates the index.
+  ///
+  /// Returns whether parsing succeeded. Sets ErrorMessage if parsing
+  /// failed.
+  bool parse(std::string &ErrorMessage);
+
+  // Tuple (directory, commandline) where 'commandline' pointing to the
+  // corresponding nodes in the YAML stream.
+  typedef std::pair<llvm::yaml::ScalarNode*,
+                    llvm::yaml::ScalarNode*> CompileCommandRef;
+
+  /// \brief Converts the given array of CompileCommandRefs to CompileCommands.
+  void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
+                   std::vector<CompileCommand> &Commands) const;
+
+  // Maps file paths to the compile command lines for that file.
+  llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile;
+
+  FileMatchTrie MatchTrie;
+
+  std::unique_ptr<llvm::MemoryBuffer> Database;
+  llvm::SourceMgr SM;
+  llvm::yaml::Stream YAMLStream;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_JSON_COMPILATION_DATABASE_H
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
new file mode 100644
index 0000000..cd2fb9f
--- /dev/null
+++ b/include/clang/Tooling/Refactoring.h
@@ -0,0 +1,244 @@
+//===--- Refactoring.h - Framework for clang refactoring tools --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Interfaces supporting refactorings that span multiple translation units.
+//  While single translation unit refactorings are supported via the Rewriter,
+//  when refactoring multiple translation units changes must be stored in a
+//  SourceManager independent form, duplicate changes need to be removed, and
+//  all changes must be applied at once at the end of the refactoring so that
+//  the code is always parseable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTORING_H
+#define LLVM_CLANG_TOOLING_REFACTORING_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include <set>
+#include <string>
+
+namespace clang {
+
+class Rewriter;
+class SourceLocation;
+
+namespace tooling {
+
+/// \brief A source range independent of the \c SourceManager.
+class Range {
+public:
+  Range() : Offset(0), Length(0) {}
+  Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
+
+  /// \brief Accessors.
+  /// @{
+  unsigned getOffset() const { return Offset; }
+  unsigned getLength() const { return Length; }
+  /// @}
+
+  /// \name Range Predicates
+  /// @{
+  /// \brief Whether this range overlaps with \p RHS or not.
+  bool overlapsWith(Range RHS) const {
+    return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
+  }
+
+  /// \brief Whether this range contains \p RHS or not.
+  bool contains(Range RHS) const {
+    return RHS.Offset >= Offset &&
+           (RHS.Offset + RHS.Length) <= (Offset + Length);
+  }
+  /// @}
+
+private:
+  unsigned Offset;
+  unsigned Length;
+};
+
+/// \brief A text replacement.
+///
+/// Represents a SourceManager independent replacement of a range of text in a
+/// specific file.
+class Replacement {
+public:
+  /// \brief Creates an invalid (not applicable) replacement.
+  Replacement();
+
+  /// \brief Creates a replacement of the range [Offset, Offset+Length) in
+  /// FilePath with ReplacementText.
+  ///
+  /// \param FilePath A source file accessible via a SourceManager.
+  /// \param Offset The byte offset of the start of the range in the file.
+  /// \param Length The length of the range in bytes.
+  Replacement(StringRef FilePath, unsigned Offset,
+              unsigned Length, StringRef ReplacementText);
+
+  /// \brief Creates a Replacement of the range [Start, Start+Length) with
+  /// ReplacementText.
+  Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
+              StringRef ReplacementText);
+
+  /// \brief Creates a Replacement of the given range with ReplacementText.
+  Replacement(const SourceManager &Sources, const CharSourceRange &Range,
+              StringRef ReplacementText);
+
+  /// \brief Creates a Replacement of the node with ReplacementText.
+  template <typename Node>
+  Replacement(const SourceManager &Sources, const Node &NodeToReplace,
+              StringRef ReplacementText);
+
+  /// \brief Returns whether this replacement can be applied to a file.
+  ///
+  /// Only replacements that are in a valid file can be applied.
+  bool isApplicable() const;
+
+  /// \brief Accessors.
+  /// @{
+  StringRef getFilePath() const { return FilePath; }
+  unsigned getOffset() const { return ReplacementRange.getOffset(); }
+  unsigned getLength() const { return ReplacementRange.getLength(); }
+  StringRef getReplacementText() const { return ReplacementText; }
+  /// @}
+
+  /// \brief Applies the replacement on the Rewriter.
+  bool apply(Rewriter &Rewrite) const;
+
+  /// \brief Returns a human readable string representation.
+  std::string toString() const;
+
+ private:
+  void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
+                             unsigned Length, StringRef ReplacementText);
+  void setFromSourceRange(const SourceManager &Sources,
+                          const CharSourceRange &Range,
+                          StringRef ReplacementText);
+
+  std::string FilePath;
+  Range ReplacementRange;
+  std::string ReplacementText;
+};
+
+/// \brief Less-than operator between two Replacements.
+bool operator<(const Replacement &LHS, const Replacement &RHS);
+
+/// \brief Equal-to operator between two Replacements.
+bool operator==(const Replacement &LHS, const Replacement &RHS);
+
+/// \brief A set of Replacements.
+/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
+typedef std::set<Replacement> Replacements;
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
+
+/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
+///
+/// Replacement applications happen independently of the success of
+/// other applications.
+///
+/// \returns true if all replacements apply. false otherwise.
+bool applyAllReplacements(const std::vector<Replacement> &Replaces,
+                          Rewriter &Rewrite);
+
+/// \brief Applies all replacements in \p Replaces to \p Code.
+///
+/// This completely ignores the path stored in each replacement. If one or more
+/// replacements cannot be applied, this returns an empty \c string.
+std::string applyAllReplacements(StringRef Code, const Replacements &Replaces);
+
+/// \brief Calculates how a code \p Position is shifted when \p Replaces are
+/// applied.
+unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
+
+/// \brief Calculates how a code \p Position is shifted when \p Replaces are
+/// applied.
+///
+/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
+unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
+                             unsigned Position);
+
+/// \brief Removes duplicate Replacements and reports if Replacements conflict
+/// with one another.
+///
+/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
+///
+/// This function sorts \p Replaces so that conflicts can be reported simply by
+/// offset into \p Replaces and number of elements in the conflict.
+void deduplicate(std::vector<Replacement> &Replaces,
+                 std::vector<Range> &Conflicts);
+
+/// \brief Collection of Replacements generated from a single translation unit.
+struct TranslationUnitReplacements {
+  /// Name of the main source for the translation unit.
+  std::string MainSourceFile;
+
+  /// A freeform chunk of text to describe the context of the replacements.
+  /// Will be printed, for example, when detecting conflicts during replacement
+  /// deduplication.
+  std::string Context;
+
+  std::vector<Replacement> Replacements;
+};
+
+/// \brief A tool to run refactorings.
+///
+/// This is a refactoring specific version of \see ClangTool. FrontendActions
+/// passed to run() and runAndSave() should add replacements to
+/// getReplacements().
+class RefactoringTool : public ClangTool {
+public:
+  /// \see ClangTool::ClangTool.
+  RefactoringTool(const CompilationDatabase &Compilations,
+                  ArrayRef<std::string> SourcePaths);
+
+  /// \brief Returns the set of replacements to which replacements should
+  /// be added during the run of the tool.
+  Replacements &getReplacements();
+
+  /// \brief Call run(), apply all generated replacements, and immediately save
+  /// the results to disk.
+  ///
+  /// \returns 0 upon success. Non-zero upon failure.
+  int runAndSave(FrontendActionFactory *ActionFactory);
+
+  /// \brief Apply all stored replacements to the given Rewriter.
+  ///
+  /// Replacement applications happen independently of the success of other
+  /// applications.
+  ///
+  /// \returns true if all replacements apply. false otherwise.
+  bool applyAllReplacements(Rewriter &Rewrite);
+
+private:
+  /// \brief Write all refactored files to disk.
+  int saveRewrittenFiles(Rewriter &Rewrite);
+
+private:
+  Replacements Replace;
+};
+
+template <typename Node>
+Replacement::Replacement(const SourceManager &Sources,
+                         const Node &NodeToReplace, StringRef ReplacementText) {
+  const CharSourceRange Range =
+      CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
+  setFromSourceRange(Sources, Range, ReplacementText);
+}
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // end namespace LLVM_CLANG_TOOLING_REFACTORING_H
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
new file mode 100644
index 0000000..19f2774
--- /dev/null
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -0,0 +1,90 @@
+//===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Provides callbacks to make common kinds of refactorings easy.
+//
+//  The general idea is to construct a matcher expression that describes a
+//  subtree match on the AST and then replace the corresponding source code
+//  either by some specific text or some other AST node.
+//
+//  Example:
+//  int main(int argc, char **argv) {
+//    ClangTool Tool(argc, argv);
+//    MatchFinder Finder;
+//    ReplaceStmtWithText Callback("integer", "42");
+//    Finder.AddMatcher(id("integer", expression(integerLiteral())), Callback);
+//    return Tool.run(newFrontendActionFactory(&Finder));
+//  }
+//
+//  This will replace all integer literals with "42".
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
+#define LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring.h"
+
+namespace clang {
+namespace tooling {
+
+/// \brief Base class for RefactoringCallbacks.
+///
+/// Collects \c tooling::Replacements while running.
+class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
+public:
+  RefactoringCallback();
+  Replacements &getReplacements();
+
+protected:
+  Replacements Replace;
+};
+
+/// \brief Replace the text of the statement bound to \c FromId with the text in
+/// \c ToText.
+class ReplaceStmtWithText : public RefactoringCallback {
+public:
+  ReplaceStmtWithText(StringRef FromId, StringRef ToText);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::string FromId;
+  std::string ToText;
+};
+
+/// \brief Replace the text of the statement bound to \c FromId with the text of
+/// the statement bound to \c ToId.
+class ReplaceStmtWithStmt : public RefactoringCallback {
+public:
+  ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::string FromId;
+  std::string ToId;
+};
+
+/// \brief Replace an if-statement bound to \c Id with the outdented text of its
+/// body, choosing the consequent or the alternative based on whether
+/// \c PickTrueBranch is true.
+class ReplaceIfStmtWithItsBody : public RefactoringCallback {
+public:
+  ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::string Id;
+  const bool PickTrueBranch;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTORING_CALLBACKS_H
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
new file mode 100644
index 0000000..ac9f469
--- /dev/null
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -0,0 +1,76 @@
+//===-- ReplacementsYaml.h -- Serialiazation for Replacements ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines the structure of a YAML document for serializing
+/// replacements.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
+#define LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
+
+#include "clang/Tooling/Refactoring.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <string>
+#include <vector>
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
+
+namespace llvm {
+namespace yaml {
+
+/// \brief Specialized MappingTraits to describe how a Replacement is
+/// (de)serialized.
+template <> struct MappingTraits<clang::tooling::Replacement> {
+  /// \brief Helper to (de)serialize a Replacement since we don't have direct
+  /// access to its data members.
+  struct NormalizedReplacement {
+    NormalizedReplacement(const IO &)
+        : FilePath(""), Offset(0), Length(0), ReplacementText("") {}
+
+    NormalizedReplacement(const IO &, const clang::tooling::Replacement &R)
+        : FilePath(R.getFilePath()), Offset(R.getOffset()),
+          Length(R.getLength()), ReplacementText(R.getReplacementText()) {}
+
+    clang::tooling::Replacement denormalize(const IO &) {
+      return clang::tooling::Replacement(FilePath, Offset, Length,
+                                         ReplacementText);
+    }
+
+    std::string FilePath;
+    unsigned int Offset;
+    unsigned int Length;
+    std::string ReplacementText;
+  };
+
+  static void mapping(IO &Io, clang::tooling::Replacement &R) {
+    MappingNormalization<NormalizedReplacement, clang::tooling::Replacement>
+    Keys(Io, R);
+    Io.mapRequired("FilePath", Keys->FilePath);
+    Io.mapRequired("Offset", Keys->Offset);
+    Io.mapRequired("Length", Keys->Length);
+    Io.mapRequired("ReplacementText", Keys->ReplacementText);
+  }
+};
+
+/// \brief Specialized MappingTraits to describe how a
+/// TranslationUnitReplacements is (de)serialized.
+template <> struct MappingTraits<clang::tooling::TranslationUnitReplacements> {
+  static void mapping(IO &Io,
+                      clang::tooling::TranslationUnitReplacements &Doc) {
+    Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
+    Io.mapOptional("Context", Doc.Context, std::string());
+    Io.mapRequired("Replacements", Doc.Replacements);
+  }
+};
+} // end namespace yaml
+} // end namespace llvm
+
+#endif // LLVM_CLANG_TOOLING_REPLACEMENTS_YAML_H
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
new file mode 100644
index 0000000..769acd3
--- /dev/null
+++ b/include/clang/Tooling/Tooling.h
@@ -0,0 +1,387 @@
+//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements functions to run clang tools standalone instead
+//  of running them as a plugin.
+//
+//  A ClangTool is initialized with a CompilationDatabase and a set of files
+//  to run over. The tool will then run a user-specified FrontendAction over
+//  all TUs in which the given files are compiled.
+//
+//  It is also possible to run a FrontendAction over a snippet of code by
+//  calling runToolOnCode, which is useful for unit testing.
+//
+//  Applications that need more fine grained control over how to run
+//  multiple FrontendActions over code can use ToolInvocation.
+//
+//  Example tools:
+//  - running clang -fsyntax-only over source code from an editor to get
+//    fast syntax checks
+//  - running match/replace tools over C++ code
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_TOOLING_H
+#define LLVM_CLANG_TOOLING_TOOLING_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Driver/Util.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/ArgumentsAdjusters.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+namespace driver {
+class Compilation;
+} // end namespace driver
+
+class CompilerInvocation;
+class SourceManager;
+class FrontendAction;
+
+namespace tooling {
+
+/// \brief Interface to process a clang::CompilerInvocation.
+///
+/// If your tool is based on FrontendAction, you should be deriving from
+/// FrontendActionFactory instead.
+class ToolAction {
+public:
+  virtual ~ToolAction();
+
+  /// \brief Perform an action for an invocation.
+  virtual bool runInvocation(clang::CompilerInvocation *Invocation,
+                             FileManager *Files,
+                             DiagnosticConsumer *DiagConsumer) = 0;
+};
+
+/// \brief Interface to generate clang::FrontendActions.
+///
+/// Having a factory interface allows, for example, a new FrontendAction to be
+/// created for each translation unit processed by ClangTool.  This class is
+/// also a ToolAction which uses the FrontendActions created by create() to
+/// process each translation unit.
+class FrontendActionFactory : public ToolAction {
+public:
+  virtual ~FrontendActionFactory();
+
+  /// \brief Invokes the compiler with a FrontendAction created by create().
+  bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+                     DiagnosticConsumer *DiagConsumer) override;
+
+  /// \brief Returns a new clang::FrontendAction.
+  ///
+  /// The caller takes ownership of the returned action.
+  virtual clang::FrontendAction *create() = 0;
+};
+
+/// \brief Returns a new FrontendActionFactory for a given type.
+///
+/// T must derive from clang::FrontendAction.
+///
+/// Example:
+/// FrontendActionFactory *Factory =
+///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
+template <typename T>
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
+
+/// \brief Callbacks called before and after each source file processed by a
+/// FrontendAction created by the FrontedActionFactory returned by \c
+/// newFrontendActionFactory.
+class SourceFileCallbacks {
+public:
+  virtual ~SourceFileCallbacks() {}
+
+  /// \brief Called before a source file is processed by a FrontEndAction.
+  /// \see clang::FrontendAction::BeginSourceFileAction
+  virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) {
+    return true;
+  }
+
+  /// \brief Called after a source file is processed by a FrontendAction.
+  /// \see clang::FrontendAction::EndSourceFileAction
+  virtual void handleEndSource() {}
+};
+
+/// \brief Returns a new FrontendActionFactory for any type that provides an
+/// implementation of newASTConsumer().
+///
+/// FactoryT must implement: ASTConsumer *newASTConsumer().
+///
+/// Example:
+/// struct ProvidesASTConsumers {
+///   clang::ASTConsumer *newASTConsumer();
+/// } Factory;
+/// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
+///   newFrontendActionFactory(&Factory));
+template <typename FactoryT>
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
+    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
+
+/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
+///
+/// \param ToolAction The action to run over the code.
+/// \param Code C++ code.
+/// \param FileName The file name which 'Code' will be mapped as.
+///
+/// \return - True if 'ToolAction' was successfully executed.
+bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
+                   const Twine &FileName = "input.cc");
+
+/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
+///        with additional other flags.
+///
+/// \param ToolAction The action to run over the code.
+/// \param Code C++ code.
+/// \param Args Additional flags to pass on.
+/// \param FileName The file name which 'Code' will be mapped as.
+///
+/// \return - True if 'ToolAction' was successfully executed.
+bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
+                           const std::vector<std::string> &Args,
+                           const Twine &FileName = "input.cc");
+
+/// \brief Builds an AST for 'Code'.
+///
+/// \param Code C++ code.
+/// \param FileName The file name which 'Code' will be mapped as.
+///
+/// \return The resulting AST or null if an error occurred.
+std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
+                                          const Twine &FileName = "input.cc");
+
+/// \brief Builds an AST for 'Code' with additional flags.
+///
+/// \param Code C++ code.
+/// \param Args Additional flags to pass on.
+/// \param FileName The file name which 'Code' will be mapped as.
+///
+/// \return The resulting AST or null if an error occurred.
+std::unique_ptr<ASTUnit>
+buildASTFromCodeWithArgs(const Twine &Code,
+                         const std::vector<std::string> &Args,
+                         const Twine &FileName = "input.cc");
+
+/// \brief Utility to run a FrontendAction in a single clang invocation.
+class ToolInvocation {
+ public:
+  /// \brief Create a tool invocation.
+  ///
+  /// \param CommandLine The command line arguments to clang. Note that clang
+  /// uses its binary name (CommandLine[0]) to locate its builtin headers.
+  /// Callers have to ensure that they are installed in a compatible location
+  /// (see clang driver implementation) or mapped in via mapVirtualFile.
+  /// \param FAction The action to be executed. Class takes ownership.
+  /// \param Files The FileManager used for the execution. Class does not take
+  /// ownership.
+  ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
+                 FileManager *Files);
+
+  /// \brief Create a tool invocation.
+  ///
+  /// \param CommandLine The command line arguments to clang.
+  /// \param Action The action to be executed.
+  /// \param Files The FileManager used for the execution.
+  ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
+                 FileManager *Files);
+
+  ~ToolInvocation();
+
+  /// \brief Set a \c DiagnosticConsumer to use during parsing.
+  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+
+  /// \brief Map a virtual file to be used while running the tool.
+  ///
+  /// \param FilePath The path at which the content will be mapped.
+  /// \param Content A null terminated buffer of the file's content.
+  void mapVirtualFile(StringRef FilePath, StringRef Content);
+
+  /// \brief Run the clang invocation.
+  ///
+  /// \returns True if there were no errors during execution.
+  bool run();
+
+ private:
+  void addFileMappingsTo(SourceManager &SourceManager);
+
+  bool runInvocation(const char *BinaryName,
+                     clang::driver::Compilation *Compilation,
+                     clang::CompilerInvocation *Invocation);
+
+  std::vector<std::string> CommandLine;
+  ToolAction *Action;
+  bool OwnsAction;
+  FileManager *Files;
+  // Maps <file name> -> <file content>.
+  llvm::StringMap<StringRef> MappedFileContents;
+  DiagnosticConsumer *DiagConsumer;
+};
+
+/// \brief Utility to run a FrontendAction over a set of files.
+///
+/// This class is written to be usable for command line utilities.
+/// By default the class uses ClangSyntaxOnlyAdjuster to modify
+/// command line arguments before the arguments are used to run
+/// a frontend action. One could install an additional command line
+/// arguments adjuster by calling the appendArgumentsAdjuster() method.
+class ClangTool {
+ public:
+  /// \brief Constructs a clang tool to run over a list of files.
+  ///
+  /// \param Compilations The CompilationDatabase which contains the compile
+  ///        command lines for the given source paths.
+  /// \param SourcePaths The source files to run over. If a source files is
+  ///        not found in Compilations, it is skipped.
+  ClangTool(const CompilationDatabase &Compilations,
+            ArrayRef<std::string> SourcePaths);
+
+  virtual ~ClangTool() { clearArgumentsAdjusters(); }
+
+  /// \brief Set a \c DiagnosticConsumer to use during parsing.
+  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+
+  /// \brief Map a virtual file to be used while running the tool.
+  ///
+  /// \param FilePath The path at which the content will be mapped.
+  /// \param Content A null terminated buffer of the file's content.
+  void mapVirtualFile(StringRef FilePath, StringRef Content);
+
+  /// \brief Install command line arguments adjuster.
+  ///
+  /// \param Adjuster Command line arguments adjuster.
+  //
+  /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead.
+  /// Remove it once all callers are gone.
+  void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
+
+  /// \brief Append a command line arguments adjuster to the adjuster chain.
+  ///
+  /// \param Adjuster An argument adjuster, which will be run on the output of
+  ///        previous argument adjusters.
+  void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
+
+  /// \brief Clear the command line arguments adjuster chain.
+  void clearArgumentsAdjusters();
+
+  /// Runs an action over all files specified in the command line.
+  ///
+  /// \param Action Tool action.
+  int run(ToolAction *Action);
+
+  /// \brief Create an AST for each file specified in the command line and
+  /// append them to ASTs.
+  int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
+
+  /// \brief Returns the file manager used in the tool.
+  ///
+  /// The file manager is shared between all translation units.
+  FileManager &getFiles() { return *Files; }
+
+ private:
+  // We store compile commands as pair (file name, compile command).
+  std::vector< std::pair<std::string, CompileCommand> > CompileCommands;
+
+  llvm::IntrusiveRefCntPtr<FileManager> Files;
+  // Contains a list of pairs (<file name>, <file content>).
+  std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
+
+  SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters;
+
+  DiagnosticConsumer *DiagConsumer;
+};
+
+template <typename T>
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
+  class SimpleFrontendActionFactory : public FrontendActionFactory {
+  public:
+    clang::FrontendAction *create() override { return new T; }
+  };
+
+  return std::unique_ptr<FrontendActionFactory>(
+      new SimpleFrontendActionFactory);
+}
+
+template <typename FactoryT>
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
+    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
+  class FrontendActionFactoryAdapter : public FrontendActionFactory {
+  public:
+    explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
+                                          SourceFileCallbacks *Callbacks)
+      : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
+
+    clang::FrontendAction *create() override {
+      return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
+    }
+
+  private:
+    class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
+    public:
+      ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
+                             SourceFileCallbacks *Callbacks)
+        : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
+
+      clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
+                                            StringRef) override {
+        return ConsumerFactory->newASTConsumer();
+      }
+
+    protected:
+      bool BeginSourceFileAction(CompilerInstance &CI,
+                                 StringRef Filename) override {
+        if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
+          return false;
+        if (Callbacks)
+          return Callbacks->handleBeginSource(CI, Filename);
+        return true;
+      }
+      void EndSourceFileAction() override {
+        if (Callbacks)
+          Callbacks->handleEndSource();
+        clang::ASTFrontendAction::EndSourceFileAction();
+      }
+
+    private:
+      FactoryT *ConsumerFactory;
+      SourceFileCallbacks *Callbacks;
+    };
+    FactoryT *ConsumerFactory;
+    SourceFileCallbacks *Callbacks;
+  };
+
+  return std::unique_ptr<FrontendActionFactory>(
+      new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
+}
+
+/// \brief Returns the absolute path of \c File, by prepending it with
+/// the current directory if \c File is not absolute.
+///
+/// Otherwise returns \c File.
+/// If 'File' starts with "./", the returned path will not contain the "./".
+/// Otherwise, the returned path will contain the literal path-concatenation of
+/// the current directory and \c File.
+///
+/// The difference to llvm::sys::fs::make_absolute is the canonicalization this
+/// does by removing "./" and computing native paths.
+///
+/// \param File Either an absolute or relative path.
+std::string getAbsolutePath(StringRef File);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_TOOLING_H
diff --git a/include/libunwind.h b/include/libunwind.h
new file mode 100644
index 0000000..7057070
--- /dev/null
+++ b/include/libunwind.h
@@ -0,0 +1,505 @@
+//===---------------------------- libunwind.h -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+// Compatible with libuwind API documented at:
+//   http://www.nongnu.org/libunwind/man/libunwind(3).html
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LIBUNWIND__
+#define __LIBUNWIND__
+
+#include <stdint.h>
+#include <stddef.h>
+
+// FIXME: This is also in unwind.h and cxxabi.h, can we consolidate?
+#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
+    !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
+#define LIBCXXABI_ARM_EHABI 1
+#else
+#define LIBCXXABI_ARM_EHABI 0
+#endif
+
+#if __APPLE__
+  #include <Availability.h>
+    #if __arm__
+       #define LIBUNWIND_AVAIL __attribute__((unavailable))
+    #else
+      #define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0)
+    #endif
+#else
+  #define LIBUNWIND_AVAIL
+#endif
+
+/* error codes */
+enum {
+  UNW_ESUCCESS      = 0,     /* no error */
+  UNW_EUNSPEC       = -6540, /* unspecified (general) error */
+  UNW_ENOMEM        = -6541, /* out of memory */
+  UNW_EBADREG       = -6542, /* bad register number */
+  UNW_EREADONLYREG  = -6543, /* attempt to write read-only register */
+  UNW_ESTOPUNWIND   = -6544, /* stop unwinding */
+  UNW_EINVALIDIP    = -6545, /* invalid IP */
+  UNW_EBADFRAME     = -6546, /* bad frame */
+  UNW_EINVAL        = -6547, /* unsupported operation or bad value */
+  UNW_EBADVERSION   = -6548, /* unwind info has unsupported version */
+  UNW_ENOINFO       = -6549  /* no unwind info found */
+};
+
+struct unw_context_t {
+  uint64_t data[128];
+};
+typedef struct unw_context_t unw_context_t;
+
+struct unw_cursor_t {
+  uint64_t data[140];
+};
+typedef struct unw_cursor_t unw_cursor_t;
+
+typedef struct unw_addr_space *unw_addr_space_t;
+
+typedef int unw_regnum_t;
+#if LIBCXXABI_ARM_EHABI
+typedef uint32_t unw_word_t;
+typedef uint64_t unw_fpreg_t;
+#else
+typedef uint64_t unw_word_t;
+typedef double unw_fpreg_t;
+#endif
+
+struct unw_proc_info_t {
+  unw_word_t  start_ip;         /* start address of function */
+  unw_word_t  end_ip;           /* address after end of function */
+  unw_word_t  lsda;             /* address of language specific data area, */
+                                /*  or zero if not used */
+  unw_word_t  handler;          /* personality routine, or zero if not used */
+  unw_word_t  gp;               /* not used */
+  unw_word_t  flags;            /* not used */
+  uint32_t    format;           /* compact unwind encoding, or zero if none */
+  uint32_t    unwind_info_size; /* size of dwarf unwind info, or zero if none */
+  unw_word_t  unwind_info;      /* address of dwarf unwind info, or zero */
+  unw_word_t  extra;            /* mach_header of mach-o image containing func */
+};
+typedef struct unw_proc_info_t unw_proc_info_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int unw_getcontext(unw_context_t *) LIBUNWIND_AVAIL;
+extern int unw_init_local(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL;
+extern int unw_step(unw_cursor_t *) LIBUNWIND_AVAIL;
+extern int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *) LIBUNWIND_AVAIL;
+extern int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *) LIBUNWIND_AVAIL;
+extern int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t) LIBUNWIND_AVAIL;
+extern int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t)  LIBUNWIND_AVAIL;
+extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL;
+
+#if __arm__
+/* Save VFP registers in FSTMX format (instead of FSTMD). */
+extern void unw_save_vfp_as_X(unw_cursor_t *) LIBUNWIND_AVAIL;
+#endif
+
+
+extern const char *unw_regname(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
+extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL;
+extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
+extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
+extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
+//extern int       unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
+
+#if UNW_REMOTE
+/*
+ * Mac OS X "remote" API for unwinding other processes on same machine
+ *
+ */
+extern unw_addr_space_t unw_local_addr_space;
+extern unw_addr_space_t unw_create_addr_space_for_task(task_t);
+extern void unw_destroy_addr_space(unw_addr_space_t);
+extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *);
+#endif
+
+/*
+ * traditional libuwind "remote" API
+ *   NOT IMPLEMENTED on Mac OS X
+ *
+ * extern int               unw_init_remote(unw_cursor_t*, unw_addr_space_t,
+ *                                          thread_t*);
+ * extern unw_accessors_t   unw_get_accessors(unw_addr_space_t);
+ * extern unw_addr_space_t  unw_create_addr_space(unw_accessors_t, int);
+ * extern void              unw_flush_cache(unw_addr_space_t, unw_word_t,
+ *                                          unw_word_t);
+ * extern int               unw_set_caching_policy(unw_addr_space_t,
+ *                                                 unw_caching_policy_t);
+ * extern void              _U_dyn_register(unw_dyn_info_t*);
+ * extern void              _U_dyn_cancel(unw_dyn_info_t*);
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+// architecture independent register numbers
+enum {
+  UNW_REG_IP = -1, // instruction pointer
+  UNW_REG_SP = -2, // stack pointer
+};
+
+// 32-bit x86 registers
+enum {
+  UNW_X86_EAX = 0,
+  UNW_X86_ECX = 1,
+  UNW_X86_EDX = 2,
+  UNW_X86_EBX = 3,
+  UNW_X86_EBP = 4,
+  UNW_X86_ESP = 5,
+  UNW_X86_ESI = 6,
+  UNW_X86_EDI = 7
+};
+
+// 64-bit x86_64 registers
+enum {
+  UNW_X86_64_RAX = 0,
+  UNW_X86_64_RDX = 1,
+  UNW_X86_64_RCX = 2,
+  UNW_X86_64_RBX = 3,
+  UNW_X86_64_RSI = 4,
+  UNW_X86_64_RDI = 5,
+  UNW_X86_64_RBP = 6,
+  UNW_X86_64_RSP = 7,
+  UNW_X86_64_R8  = 8,
+  UNW_X86_64_R9  = 9,
+  UNW_X86_64_R10 = 10,
+  UNW_X86_64_R11 = 11,
+  UNW_X86_64_R12 = 12,
+  UNW_X86_64_R13 = 13,
+  UNW_X86_64_R14 = 14,
+  UNW_X86_64_R15 = 15
+};
+
+
+// 32-bit ppc register numbers
+enum {
+  UNW_PPC_R0  = 0,
+  UNW_PPC_R1  = 1,
+  UNW_PPC_R2  = 2,
+  UNW_PPC_R3  = 3,
+  UNW_PPC_R4  = 4,
+  UNW_PPC_R5  = 5,
+  UNW_PPC_R6  = 6,
+  UNW_PPC_R7  = 7,
+  UNW_PPC_R8  = 8,
+  UNW_PPC_R9  = 9,
+  UNW_PPC_R10 = 10,
+  UNW_PPC_R11 = 11,
+  UNW_PPC_R12 = 12,
+  UNW_PPC_R13 = 13,
+  UNW_PPC_R14 = 14,
+  UNW_PPC_R15 = 15,
+  UNW_PPC_R16 = 16,
+  UNW_PPC_R17 = 17,
+  UNW_PPC_R18 = 18,
+  UNW_PPC_R19 = 19,
+  UNW_PPC_R20 = 20,
+  UNW_PPC_R21 = 21,
+  UNW_PPC_R22 = 22,
+  UNW_PPC_R23 = 23,
+  UNW_PPC_R24 = 24,
+  UNW_PPC_R25 = 25,
+  UNW_PPC_R26 = 26,
+  UNW_PPC_R27 = 27,
+  UNW_PPC_R28 = 28,
+  UNW_PPC_R29 = 29,
+  UNW_PPC_R30 = 30,
+  UNW_PPC_R31 = 31,
+  UNW_PPC_F0  = 32,
+  UNW_PPC_F1  = 33,
+  UNW_PPC_F2  = 34,
+  UNW_PPC_F3  = 35,
+  UNW_PPC_F4  = 36,
+  UNW_PPC_F5  = 37,
+  UNW_PPC_F6  = 38,
+  UNW_PPC_F7  = 39,
+  UNW_PPC_F8  = 40,
+  UNW_PPC_F9  = 41,
+  UNW_PPC_F10 = 42,
+  UNW_PPC_F11 = 43,
+  UNW_PPC_F12 = 44,
+  UNW_PPC_F13 = 45,
+  UNW_PPC_F14 = 46,
+  UNW_PPC_F15 = 47,
+  UNW_PPC_F16 = 48,
+  UNW_PPC_F17 = 49,
+  UNW_PPC_F18 = 50,
+  UNW_PPC_F19 = 51,
+  UNW_PPC_F20 = 52,
+  UNW_PPC_F21 = 53,
+  UNW_PPC_F22 = 54,
+  UNW_PPC_F23 = 55,
+  UNW_PPC_F24 = 56,
+  UNW_PPC_F25 = 57,
+  UNW_PPC_F26 = 58,
+  UNW_PPC_F27 = 59,
+  UNW_PPC_F28 = 60,
+  UNW_PPC_F29 = 61,
+  UNW_PPC_F30 = 62,
+  UNW_PPC_F31 = 63,
+  UNW_PPC_MQ  = 64,
+  UNW_PPC_LR  = 65,
+  UNW_PPC_CTR = 66,
+  UNW_PPC_AP  = 67,
+  UNW_PPC_CR0 = 68,
+  UNW_PPC_CR1 = 69,
+  UNW_PPC_CR2 = 70,
+  UNW_PPC_CR3 = 71,
+  UNW_PPC_CR4 = 72,
+  UNW_PPC_CR5 = 73,
+  UNW_PPC_CR6 = 74,
+  UNW_PPC_CR7 = 75,
+  UNW_PPC_XER = 76,
+  UNW_PPC_V0  = 77,
+  UNW_PPC_V1  = 78,
+  UNW_PPC_V2  = 79,
+  UNW_PPC_V3  = 80,
+  UNW_PPC_V4  = 81,
+  UNW_PPC_V5  = 82,
+  UNW_PPC_V6  = 83,
+  UNW_PPC_V7  = 84,
+  UNW_PPC_V8  = 85,
+  UNW_PPC_V9  = 86,
+  UNW_PPC_V10 = 87,
+  UNW_PPC_V11 = 88,
+  UNW_PPC_V12 = 89,
+  UNW_PPC_V13 = 90,
+  UNW_PPC_V14 = 91,
+  UNW_PPC_V15 = 92,
+  UNW_PPC_V16 = 93,
+  UNW_PPC_V17 = 94,
+  UNW_PPC_V18 = 95,
+  UNW_PPC_V19 = 96,
+  UNW_PPC_V20 = 97,
+  UNW_PPC_V21 = 98,
+  UNW_PPC_V22 = 99,
+  UNW_PPC_V23 = 100,
+  UNW_PPC_V24 = 101,
+  UNW_PPC_V25 = 102,
+  UNW_PPC_V26 = 103,
+  UNW_PPC_V27 = 104,
+  UNW_PPC_V28 = 105,
+  UNW_PPC_V29 = 106,
+  UNW_PPC_V30 = 107,
+  UNW_PPC_V31 = 108,
+  UNW_PPC_VRSAVE  = 109,
+  UNW_PPC_VSCR    = 110,
+  UNW_PPC_SPE_ACC = 111,
+  UNW_PPC_SPEFSCR = 112
+};
+
+// 64-bit ARM64 registers
+enum {
+  UNW_ARM64_X0  = 0,
+  UNW_ARM64_X1  = 1,
+  UNW_ARM64_X2  = 2,
+  UNW_ARM64_X3  = 3,
+  UNW_ARM64_X4  = 4,
+  UNW_ARM64_X5  = 5,
+  UNW_ARM64_X6  = 6,
+  UNW_ARM64_X7  = 7,
+  UNW_ARM64_X8  = 8,
+  UNW_ARM64_X9  = 9,
+  UNW_ARM64_X10 = 10,
+  UNW_ARM64_X11 = 11,
+  UNW_ARM64_X12 = 12,
+  UNW_ARM64_X13 = 13,
+  UNW_ARM64_X14 = 14,
+  UNW_ARM64_X15 = 15,
+  UNW_ARM64_X16 = 16,
+  UNW_ARM64_X17 = 17,
+  UNW_ARM64_X18 = 18,
+  UNW_ARM64_X19 = 19,
+  UNW_ARM64_X20 = 20,
+  UNW_ARM64_X21 = 21,
+  UNW_ARM64_X22 = 22,
+  UNW_ARM64_X23 = 23,
+  UNW_ARM64_X24 = 24,
+  UNW_ARM64_X25 = 25,
+  UNW_ARM64_X26 = 26,
+  UNW_ARM64_X27 = 27,
+  UNW_ARM64_X28 = 28,
+  UNW_ARM64_X29 = 29,
+  UNW_ARM64_FP  = 29,
+  UNW_ARM64_X30 = 30,
+  UNW_ARM64_LR  = 30,
+  UNW_ARM64_X31 = 31,
+  UNW_ARM64_SP  = 31,
+  // reserved block
+  UNW_ARM64_D0  = 64,
+  UNW_ARM64_D1  = 65,
+  UNW_ARM64_D2  = 66,
+  UNW_ARM64_D3  = 67,
+  UNW_ARM64_D4  = 68,
+  UNW_ARM64_D5  = 69,
+  UNW_ARM64_D6  = 70,
+  UNW_ARM64_D7  = 71,
+  UNW_ARM64_D8  = 72,
+  UNW_ARM64_D9  = 73,
+  UNW_ARM64_D10 = 74,
+  UNW_ARM64_D11 = 75,
+  UNW_ARM64_D12 = 76,
+  UNW_ARM64_D13 = 77,
+  UNW_ARM64_D14 = 78,
+  UNW_ARM64_D15 = 79,
+  UNW_ARM64_D16 = 80,
+  UNW_ARM64_D17 = 81,
+  UNW_ARM64_D18 = 82,
+  UNW_ARM64_D19 = 83,
+  UNW_ARM64_D20 = 84,
+  UNW_ARM64_D21 = 85,
+  UNW_ARM64_D22 = 86,
+  UNW_ARM64_D23 = 87,
+  UNW_ARM64_D24 = 88,
+  UNW_ARM64_D25 = 89,
+  UNW_ARM64_D26 = 90,
+  UNW_ARM64_D27 = 91,
+  UNW_ARM64_D28 = 92,
+  UNW_ARM64_D29 = 93,
+  UNW_ARM64_D30 = 94,
+  UNW_ARM64_D31 = 95,
+};
+
+// 32-bit ARM registers. Numbers match DWARF for ARM spec #3.1 Table 1.
+// Naming scheme uses recommendations given in Note 4 for VFP-v2 and VFP-v3.
+// In this scheme, even though the 64-bit floating point registers D0-D31
+// overlap physically with the 32-bit floating pointer registers S0-S31,
+// they are given a non-overlapping range of register numbers.
+//
+// Commented out ranges are not preserved during unwinding.
+enum {
+  UNW_ARM_R0  = 0,
+  UNW_ARM_R1  = 1,
+  UNW_ARM_R2  = 2,
+  UNW_ARM_R3  = 3,
+  UNW_ARM_R4  = 4,
+  UNW_ARM_R5  = 5,
+  UNW_ARM_R6  = 6,
+  UNW_ARM_R7  = 7,
+  UNW_ARM_R8  = 8,
+  UNW_ARM_R9  = 9,
+  UNW_ARM_R10 = 10,
+  UNW_ARM_R11 = 11,
+  UNW_ARM_R12 = 12,
+  UNW_ARM_SP  = 13,  // Logical alias for UNW_REG_SP
+  UNW_ARM_R13 = 13,
+  UNW_ARM_LR  = 14,
+  UNW_ARM_R14 = 14,
+  UNW_ARM_IP  = 15,  // Logical alias for UNW_REG_IP
+  UNW_ARM_R15 = 15,
+  // 16-63 -- OBSOLETE. Used in VFP1 to represent both S0-S31 and D0-D31.
+  UNW_ARM_S0  = 64,
+  UNW_ARM_S1  = 65,
+  UNW_ARM_S2  = 66,
+  UNW_ARM_S3  = 67,
+  UNW_ARM_S4  = 68,
+  UNW_ARM_S5  = 69,
+  UNW_ARM_S6  = 70,
+  UNW_ARM_S7  = 71,
+  UNW_ARM_S8  = 72,
+  UNW_ARM_S9  = 73,
+  UNW_ARM_S10 = 74,
+  UNW_ARM_S11 = 75,
+  UNW_ARM_S12 = 76,
+  UNW_ARM_S13 = 77,
+  UNW_ARM_S14 = 78,
+  UNW_ARM_S15 = 79,
+  UNW_ARM_S16 = 80,
+  UNW_ARM_S17 = 81,
+  UNW_ARM_S18 = 82,
+  UNW_ARM_S19 = 83,
+  UNW_ARM_S20 = 84,
+  UNW_ARM_S21 = 85,
+  UNW_ARM_S22 = 86,
+  UNW_ARM_S23 = 87,
+  UNW_ARM_S24 = 88,
+  UNW_ARM_S25 = 89,
+  UNW_ARM_S26 = 90,
+  UNW_ARM_S27 = 91,
+  UNW_ARM_S28 = 92,
+  UNW_ARM_S29 = 93,
+  UNW_ARM_S30 = 94,
+  UNW_ARM_S31 = 95,
+  //  96-103 -- OBSOLETE. F0-F7. Used by the FPA system. Superseded by VFP.
+  // 104-111 -- wCGR0-wCGR7, ACC0-ACC7 (Intel wireless MMX)
+  UNW_ARM_WR0 = 112,
+  UNW_ARM_WR1 = 113,
+  UNW_ARM_WR2 = 114,
+  UNW_ARM_WR3 = 115,
+  UNW_ARM_WR4 = 116,
+  UNW_ARM_WR5 = 117,
+  UNW_ARM_WR6 = 118,
+  UNW_ARM_WR7 = 119,
+  UNW_ARM_WR8 = 120,
+  UNW_ARM_WR9 = 121,
+  UNW_ARM_WR10 = 122,
+  UNW_ARM_WR11 = 123,
+  UNW_ARM_WR12 = 124,
+  UNW_ARM_WR13 = 125,
+  UNW_ARM_WR14 = 126,
+  UNW_ARM_WR15 = 127,
+  // 128-133 -- SPSR, SPSR_{FIQ|IRQ|ABT|UND|SVC}
+  // 134-143 -- Reserved
+  // 144-150 -- R8_USR–R14_USR
+  // 151-157 -- R8_FIQ–R14_FIQ
+  // 158-159 -- R13_IRQ–R14_IRQ
+  // 160-161 -- R13_ABT–R14_ABT
+  // 162-163 -- R13_UND–R14_UND
+  // 164-165 -- R13_SVC–R14_SVC
+  // 166-191 -- Reserved
+  UNW_ARM_WC0 = 192,
+  UNW_ARM_WC1 = 193,
+  UNW_ARM_WC2 = 194,
+  UNW_ARM_WC3 = 195,
+  // 196-199 -- wC4-wC7 (Intel wireless MMX control)
+  // 200-255 -- Reserved
+  UNW_ARM_D0  = 256,
+  UNW_ARM_D1  = 257,
+  UNW_ARM_D2  = 258,
+  UNW_ARM_D3  = 259,
+  UNW_ARM_D4  = 260,
+  UNW_ARM_D5  = 261,
+  UNW_ARM_D6  = 262,
+  UNW_ARM_D7  = 263,
+  UNW_ARM_D8  = 264,
+  UNW_ARM_D9  = 265,
+  UNW_ARM_D10 = 266,
+  UNW_ARM_D11 = 267,
+  UNW_ARM_D12 = 268,
+  UNW_ARM_D13 = 269,
+  UNW_ARM_D14 = 270,
+  UNW_ARM_D15 = 271,
+  UNW_ARM_D16 = 272,
+  UNW_ARM_D17 = 273,
+  UNW_ARM_D18 = 274,
+  UNW_ARM_D19 = 275,
+  UNW_ARM_D20 = 276,
+  UNW_ARM_D21 = 277,
+  UNW_ARM_D22 = 278,
+  UNW_ARM_D23 = 279,
+  UNW_ARM_D24 = 280,
+  UNW_ARM_D25 = 281,
+  UNW_ARM_D26 = 282,
+  UNW_ARM_D27 = 283,
+  UNW_ARM_D28 = 284,
+  UNW_ARM_D29 = 285,
+  UNW_ARM_D30 = 286,
+  UNW_ARM_D31 = 287,
+  // 288-319 -- Reserved for VFP/Neon
+  // 320-8191 -- Reserved
+  // 8192-16383 -- Unspecified vendor co-processor register.
+};
+
+#endif
diff --git a/include/llvm-c/Analysis.h b/include/llvm-c/Analysis.h
new file mode 100644
index 0000000..f0bdddc
--- /dev/null
+++ b/include/llvm-c/Analysis.h
@@ -0,0 +1,65 @@
+/*===-- llvm-c/Analysis.h - Analysis Library C Interface --------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMAnalysis.a, which           *|
+|* implements various analyses of the LLVM IR.                                *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_ANALYSIS_H
+#define LLVM_C_ANALYSIS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCAnalysis Analysis
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+typedef enum {
+  LLVMAbortProcessAction, /* verifier will print to stderr and abort() */
+  LLVMPrintMessageAction, /* verifier will print to stderr and return 1 */
+  LLVMReturnStatusAction  /* verifier will just return 1 */
+} LLVMVerifierFailureAction;
+
+
+/* Verifies that a module is valid, taking the specified action if not.
+   Optionally returns a human-readable description of any invalid constructs.
+   OutMessage must be disposed with LLVMDisposeMessage. */
+LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
+                          char **OutMessage);
+
+/* Verifies that a single function is valid, taking the specified action. Useful
+   for debugging. */
+LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
+
+/* Open up a ghostview window that displays the CFG of the current function.
+   Useful for debugging. */
+void LLVMViewFunctionCFG(LLVMValueRef Fn);
+void LLVMViewFunctionCFGOnly(LLVMValueRef Fn);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/BitReader.h b/include/llvm-c/BitReader.h
new file mode 100644
index 0000000..7af209b
--- /dev/null
+++ b/include/llvm-c/BitReader.h
@@ -0,0 +1,76 @@
+/*===-- llvm-c/BitReader.h - BitReader Library C Interface ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMBitReader.a, which          *|
+|* implements input of the LLVM bitcode format.                               *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_BITCODEREADER_H
+#define LLVM_C_BITCODEREADER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCBitReader Bit Reader
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/* Builds a module from the bitcode in the specified memory buffer, returning a
+   reference to the module via the OutModule parameter. Returns 0 on success.
+   Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+                          LLVMModuleRef *OutModule, char **OutMessage);
+
+LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+                                   LLVMMemoryBufferRef MemBuf,
+                                   LLVMModuleRef *OutModule, char **OutMessage);
+
+/** Reads a module from the specified path, returning via the OutMP parameter
+    a module provider which performs lazy deserialization. Returns 0 on success.
+    Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+                                       LLVMMemoryBufferRef MemBuf,
+                                       LLVMModuleRef *OutM,
+                                       char **OutMessage);
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+                              char **OutMessage);
+
+
+/** Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
+LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
+                                               LLVMMemoryBufferRef MemBuf,
+                                               LLVMModuleProviderRef *OutMP,
+                                               char **OutMessage);
+
+/** Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+                                      LLVMModuleProviderRef *OutMP,
+                                      char **OutMessage);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/BitWriter.h b/include/llvm-c/BitWriter.h
new file mode 100644
index 0000000..f605e24
--- /dev/null
+++ b/include/llvm-c/BitWriter.h
@@ -0,0 +1,56 @@
+/*===-- llvm-c/BitWriter.h - BitWriter Library C Interface ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMBitWriter.a, which          *|
+|* implements output of the LLVM bitcode format.                              *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_BITCODEWRITER_H
+#define LLVM_C_BITCODEWRITER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCBitWriter Bit Writer
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/*===-- Operations on modules ---------------------------------------------===*/
+
+/** Writes a module to the specified path. Returns 0 on success. */
+int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path);
+
+/** Writes a module to an open file descriptor. Returns 0 on success. */
+int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+                         int Unbuffered);
+
+/** Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file
+    descriptor. Returns 0 on success. Closes the Handle. */
+int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
new file mode 100644
index 0000000..fdff77b
--- /dev/null
+++ b/include/llvm-c/Core.h
@@ -0,0 +1,2881 @@
+/*===-- llvm-c/Core.h - Core Library C Interface ------------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMCore.a, which implements    *|
+|* the LLVM intermediate representation.                                      *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_CORE_H
+#define LLVM_C_CORE_H
+
+#include "llvm-c/Support.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMC LLVM-C: C interface to LLVM
+ *
+ * This module exposes parts of the LLVM library as a C API.
+ *
+ * @{
+ */
+
+/**
+ * @defgroup LLVMCTransforms Transforms
+ */
+
+/**
+ * @defgroup LLVMCCore Core
+ *
+ * This modules provide an interface to libLLVMCore, which implements
+ * the LLVM intermediate representation as well as other related types
+ * and utilities.
+ *
+ * LLVM uses a polymorphic type hierarchy which C cannot represent, therefore
+ * parameters must be passed as base types. Despite the declared types, most
+ * of the functions provided operate only on branches of the type hierarchy.
+ * The declared parameter names are descriptive and specify which type is
+ * required. Additionally, each type hierarchy is documented along with the
+ * functions that operate upon it. For more detail, refer to LLVM's C++ code.
+ * If in doubt, refer to Core.cpp, which performs parameter downcasts in the
+ * form unwrap<RequiredType>(Param).
+ *
+ * Many exotic languages can interoperate with C code but have a harder time
+ * with C++ due to name mangling. So in addition to C, this interface enables
+ * tools written in such languages.
+ *
+ * @{
+ */
+
+/**
+ * @defgroup LLVMCCoreTypes Types and Enumerations
+ *
+ * @{
+ */
+
+/* Opaque types. */
+
+/**
+ * The top-level container for all LLVM global data. See the LLVMContext class.
+ */
+typedef struct LLVMOpaqueContext *LLVMContextRef;
+
+/**
+ * The top-level container for all other LLVM Intermediate Representation (IR)
+ * objects.
+ *
+ * @see llvm::Module
+ */
+typedef struct LLVMOpaqueModule *LLVMModuleRef;
+
+/**
+ * Each value in the LLVM IR has a type, an LLVMTypeRef.
+ *
+ * @see llvm::Type
+ */
+typedef struct LLVMOpaqueType *LLVMTypeRef;
+
+/**
+ * Represents an individual value in LLVM IR.
+ *
+ * This models llvm::Value.
+ */
+typedef struct LLVMOpaqueValue *LLVMValueRef;
+
+/**
+ * Represents a basic block of instructions in LLVM IR.
+ *
+ * This models llvm::BasicBlock.
+ */
+typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
+
+/**
+ * Represents an LLVM basic block builder.
+ *
+ * This models llvm::IRBuilder.
+ */
+typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
+
+/**
+ * Interface used to provide a module to JIT or interpreter.
+ * This is now just a synonym for llvm::Module, but we have to keep using the
+ * different type to keep binary compatibility.
+ */
+typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
+
+/** @see llvm::PassManagerBase */
+typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
+
+/** @see llvm::PassRegistry */
+typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef;
+
+/**
+ * Used to get the users and usees of a Value.
+ *
+ * @see llvm::Use */
+typedef struct LLVMOpaqueUse *LLVMUseRef;
+
+
+/**
+ * @see llvm::DiagnosticInfo
+ */
+typedef struct LLVMOpaqueDiagnosticInfo *LLVMDiagnosticInfoRef;
+
+typedef enum {
+    LLVMZExtAttribute       = 1<<0,
+    LLVMSExtAttribute       = 1<<1,
+    LLVMNoReturnAttribute   = 1<<2,
+    LLVMInRegAttribute      = 1<<3,
+    LLVMStructRetAttribute  = 1<<4,
+    LLVMNoUnwindAttribute   = 1<<5,
+    LLVMNoAliasAttribute    = 1<<6,
+    LLVMByValAttribute      = 1<<7,
+    LLVMNestAttribute       = 1<<8,
+    LLVMReadNoneAttribute   = 1<<9,
+    LLVMReadOnlyAttribute   = 1<<10,
+    LLVMNoInlineAttribute   = 1<<11,
+    LLVMAlwaysInlineAttribute    = 1<<12,
+    LLVMOptimizeForSizeAttribute = 1<<13,
+    LLVMStackProtectAttribute    = 1<<14,
+    LLVMStackProtectReqAttribute = 1<<15,
+    LLVMAlignment = 31<<16,
+    LLVMNoCaptureAttribute  = 1<<21,
+    LLVMNoRedZoneAttribute  = 1<<22,
+    LLVMNoImplicitFloatAttribute = 1<<23,
+    LLVMNakedAttribute      = 1<<24,
+    LLVMInlineHintAttribute = 1<<25,
+    LLVMStackAlignment = 7<<26,
+    LLVMReturnsTwice = 1 << 29,
+    LLVMUWTable = 1 << 30,
+    LLVMNonLazyBind = 1 << 31
+
+    /* FIXME: These attributes are currently not included in the C API as
+       a temporary measure until the API/ABI impact to the C API is understood
+       and the path forward agreed upon.
+    LLVMAddressSafety = 1ULL << 32,
+    LLVMStackProtectStrongAttribute = 1ULL<<33,
+    LLVMCold = 1ULL << 34,
+    LLVMOptimizeNone = 1ULL << 35,
+    LLVMInAllocaAttribute = 1ULL << 36,
+    LLVMNonNullAttribute = 1ULL << 37,
+    LLVMJumpTableAttribute = 1ULL << 38,
+    LLVMDereferenceableAttribute = 1ULL << 39,
+    */
+} LLVMAttribute;
+
+typedef enum {
+  /* Terminator Instructions */
+  LLVMRet            = 1,
+  LLVMBr             = 2,
+  LLVMSwitch         = 3,
+  LLVMIndirectBr     = 4,
+  LLVMInvoke         = 5,
+  /* removed 6 due to API changes */
+  LLVMUnreachable    = 7,
+
+  /* Standard Binary Operators */
+  LLVMAdd            = 8,
+  LLVMFAdd           = 9,
+  LLVMSub            = 10,
+  LLVMFSub           = 11,
+  LLVMMul            = 12,
+  LLVMFMul           = 13,
+  LLVMUDiv           = 14,
+  LLVMSDiv           = 15,
+  LLVMFDiv           = 16,
+  LLVMURem           = 17,
+  LLVMSRem           = 18,
+  LLVMFRem           = 19,
+
+  /* Logical Operators */
+  LLVMShl            = 20,
+  LLVMLShr           = 21,
+  LLVMAShr           = 22,
+  LLVMAnd            = 23,
+  LLVMOr             = 24,
+  LLVMXor            = 25,
+
+  /* Memory Operators */
+  LLVMAlloca         = 26,
+  LLVMLoad           = 27,
+  LLVMStore          = 28,
+  LLVMGetElementPtr  = 29,
+
+  /* Cast Operators */
+  LLVMTrunc          = 30,
+  LLVMZExt           = 31,
+  LLVMSExt           = 32,
+  LLVMFPToUI         = 33,
+  LLVMFPToSI         = 34,
+  LLVMUIToFP         = 35,
+  LLVMSIToFP         = 36,
+  LLVMFPTrunc        = 37,
+  LLVMFPExt          = 38,
+  LLVMPtrToInt       = 39,
+  LLVMIntToPtr       = 40,
+  LLVMBitCast        = 41,
+  LLVMAddrSpaceCast  = 60,
+
+  /* Other Operators */
+  LLVMICmp           = 42,
+  LLVMFCmp           = 43,
+  LLVMPHI            = 44,
+  LLVMCall           = 45,
+  LLVMSelect         = 46,
+  LLVMUserOp1        = 47,
+  LLVMUserOp2        = 48,
+  LLVMVAArg          = 49,
+  LLVMExtractElement = 50,
+  LLVMInsertElement  = 51,
+  LLVMShuffleVector  = 52,
+  LLVMExtractValue   = 53,
+  LLVMInsertValue    = 54,
+
+  /* Atomic operators */
+  LLVMFence          = 55,
+  LLVMAtomicCmpXchg  = 56,
+  LLVMAtomicRMW      = 57,
+
+  /* Exception Handling Operators */
+  LLVMResume         = 58,
+  LLVMLandingPad     = 59
+
+} LLVMOpcode;
+
+typedef enum {
+  LLVMVoidTypeKind,        /**< type with no size */
+  LLVMHalfTypeKind,        /**< 16 bit floating point type */
+  LLVMFloatTypeKind,       /**< 32 bit floating point type */
+  LLVMDoubleTypeKind,      /**< 64 bit floating point type */
+  LLVMX86_FP80TypeKind,    /**< 80 bit floating point type (X87) */
+  LLVMFP128TypeKind,       /**< 128 bit floating point type (112-bit mantissa)*/
+  LLVMPPC_FP128TypeKind,   /**< 128 bit floating point type (two 64-bits) */
+  LLVMLabelTypeKind,       /**< Labels */
+  LLVMIntegerTypeKind,     /**< Arbitrary bit width integers */
+  LLVMFunctionTypeKind,    /**< Functions */
+  LLVMStructTypeKind,      /**< Structures */
+  LLVMArrayTypeKind,       /**< Arrays */
+  LLVMPointerTypeKind,     /**< Pointers */
+  LLVMVectorTypeKind,      /**< SIMD 'packed' format, or other vector type */
+  LLVMMetadataTypeKind,    /**< Metadata */
+  LLVMX86_MMXTypeKind      /**< X86 MMX */
+} LLVMTypeKind;
+
+typedef enum {
+  LLVMExternalLinkage,    /**< Externally visible function */
+  LLVMAvailableExternallyLinkage,
+  LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/
+  LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something
+                            equivalent. */
+  LLVMLinkOnceODRAutoHideLinkage, /**< Obsolete */
+  LLVMWeakAnyLinkage,     /**< Keep one copy of function when linking (weak) */
+  LLVMWeakODRLinkage,     /**< Same, but only replaced by something
+                            equivalent. */
+  LLVMAppendingLinkage,   /**< Special purpose, only applies to global arrays */
+  LLVMInternalLinkage,    /**< Rename collisions when linking (static
+                               functions) */
+  LLVMPrivateLinkage,     /**< Like Internal, but omit from symbol table */
+  LLVMDLLImportLinkage,   /**< Obsolete */
+  LLVMDLLExportLinkage,   /**< Obsolete */
+  LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
+  LLVMGhostLinkage,       /**< Obsolete */
+  LLVMCommonLinkage,      /**< Tentative definitions */
+  LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */
+  LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */
+} LLVMLinkage;
+
+typedef enum {
+  LLVMDefaultVisibility,  /**< The GV is visible */
+  LLVMHiddenVisibility,   /**< The GV is hidden */
+  LLVMProtectedVisibility /**< The GV is protected */
+} LLVMVisibility;
+
+typedef enum {
+  LLVMDefaultStorageClass   = 0,
+  LLVMDLLImportStorageClass = 1, /**< Function to be imported from DLL. */
+  LLVMDLLExportStorageClass = 2  /**< Function to be accessible from DLL. */
+} LLVMDLLStorageClass;
+
+typedef enum {
+  LLVMCCallConv           = 0,
+  LLVMFastCallConv        = 8,
+  LLVMColdCallConv        = 9,
+  LLVMWebKitJSCallConv    = 12,
+  LLVMAnyRegCallConv      = 13,
+  LLVMX86StdcallCallConv  = 64,
+  LLVMX86FastcallCallConv = 65
+} LLVMCallConv;
+
+typedef enum {
+  LLVMIntEQ = 32, /**< equal */
+  LLVMIntNE,      /**< not equal */
+  LLVMIntUGT,     /**< unsigned greater than */
+  LLVMIntUGE,     /**< unsigned greater or equal */
+  LLVMIntULT,     /**< unsigned less than */
+  LLVMIntULE,     /**< unsigned less or equal */
+  LLVMIntSGT,     /**< signed greater than */
+  LLVMIntSGE,     /**< signed greater or equal */
+  LLVMIntSLT,     /**< signed less than */
+  LLVMIntSLE      /**< signed less or equal */
+} LLVMIntPredicate;
+
+typedef enum {
+  LLVMRealPredicateFalse, /**< Always false (always folded) */
+  LLVMRealOEQ,            /**< True if ordered and equal */
+  LLVMRealOGT,            /**< True if ordered and greater than */
+  LLVMRealOGE,            /**< True if ordered and greater than or equal */
+  LLVMRealOLT,            /**< True if ordered and less than */
+  LLVMRealOLE,            /**< True if ordered and less than or equal */
+  LLVMRealONE,            /**< True if ordered and operands are unequal */
+  LLVMRealORD,            /**< True if ordered (no nans) */
+  LLVMRealUNO,            /**< True if unordered: isnan(X) | isnan(Y) */
+  LLVMRealUEQ,            /**< True if unordered or equal */
+  LLVMRealUGT,            /**< True if unordered or greater than */
+  LLVMRealUGE,            /**< True if unordered, greater than, or equal */
+  LLVMRealULT,            /**< True if unordered or less than */
+  LLVMRealULE,            /**< True if unordered, less than, or equal */
+  LLVMRealUNE,            /**< True if unordered or not equal */
+  LLVMRealPredicateTrue   /**< Always true (always folded) */
+} LLVMRealPredicate;
+
+typedef enum {
+  LLVMLandingPadCatch,    /**< A catch clause   */
+  LLVMLandingPadFilter    /**< A filter clause  */
+} LLVMLandingPadClauseTy;
+
+typedef enum {
+  LLVMNotThreadLocal = 0,
+  LLVMGeneralDynamicTLSModel,
+  LLVMLocalDynamicTLSModel,
+  LLVMInitialExecTLSModel,
+  LLVMLocalExecTLSModel
+} LLVMThreadLocalMode;
+
+typedef enum {
+  LLVMAtomicOrderingNotAtomic = 0, /**< A load or store which is not atomic */
+  LLVMAtomicOrderingUnordered = 1, /**< Lowest level of atomicity, guarantees
+                                     somewhat sane results, lock free. */
+  LLVMAtomicOrderingMonotonic = 2, /**< guarantees that if you take all the
+                                     operations affecting a specific address,
+                                     a consistent ordering exists */
+  LLVMAtomicOrderingAcquire = 4, /**< Acquire provides a barrier of the sort
+                                   necessary to acquire a lock to access other
+                                   memory with normal loads and stores. */
+  LLVMAtomicOrderingRelease = 5, /**< Release is similar to Acquire, but with
+                                   a barrier of the sort necessary to release
+                                   a lock. */
+  LLVMAtomicOrderingAcquireRelease = 6, /**< provides both an Acquire and a
+                                          Release barrier (for fences and
+                                          operations which both read and write
+                                           memory). */
+  LLVMAtomicOrderingSequentiallyConsistent = 7 /**< provides Acquire semantics
+                                                 for loads and Release
+                                                 semantics for stores.
+                                                 Additionally, it guarantees
+                                                 that a total ordering exists
+                                                 between all
+                                                 SequentiallyConsistent
+                                                 operations. */
+} LLVMAtomicOrdering;
+
+typedef enum {
+    LLVMAtomicRMWBinOpXchg, /**< Set the new value and return the one old */
+    LLVMAtomicRMWBinOpAdd, /**< Add a value and return the old one */
+    LLVMAtomicRMWBinOpSub, /**< Subtract a value and return the old one */
+    LLVMAtomicRMWBinOpAnd, /**< And a value and return the old one */
+    LLVMAtomicRMWBinOpNand, /**< Not-And a value and return the old one */
+    LLVMAtomicRMWBinOpOr, /**< OR a value and return the old one */
+    LLVMAtomicRMWBinOpXor, /**< Xor a value and return the old one */
+    LLVMAtomicRMWBinOpMax, /**< Sets the value if it's greater than the
+                             original using a signed comparison and return
+                             the old one */
+    LLVMAtomicRMWBinOpMin, /**< Sets the value if it's Smaller than the
+                             original using a signed comparison and return
+                             the old one */
+    LLVMAtomicRMWBinOpUMax, /**< Sets the value if it's greater than the
+                             original using an unsigned comparison and return
+                             the old one */
+    LLVMAtomicRMWBinOpUMin /**< Sets the value if it's greater than the
+                             original using an unsigned comparison  and return
+                             the old one */
+} LLVMAtomicRMWBinOp;
+
+typedef enum {
+    LLVMDSError,
+    LLVMDSWarning,
+    LLVMDSRemark,
+    LLVMDSNote
+} LLVMDiagnosticSeverity;
+
+/**
+ * @}
+ */
+
+void LLVMInitializeCore(LLVMPassRegistryRef R);
+
+/** Deallocate and destroy all ManagedStatic variables.
+    @see llvm::llvm_shutdown
+    @see ManagedStatic */
+void LLVMShutdown(void);
+
+
+/*===-- Error handling ----------------------------------------------------===*/
+
+char *LLVMCreateMessage(const char *Message);
+void LLVMDisposeMessage(char *Message);
+
+typedef void (*LLVMFatalErrorHandler)(const char *Reason);
+
+/**
+ * Install a fatal error handler. By default, if LLVM detects a fatal error, it
+ * will call exit(1). This may not be appropriate in many contexts. For example,
+ * doing exit(1) will bypass many crash reporting/tracing system tools. This
+ * function allows you to install a callback that will be invoked prior to the
+ * call to exit(1).
+ */
+void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler);
+
+/**
+ * Reset the fatal error handler. This resets LLVM's fatal error handling
+ * behavior to the default.
+ */
+void LLVMResetFatalErrorHandler(void);
+
+/**
+ * Enable LLVM's built-in stack trace code. This intercepts the OS's crash
+ * signals and prints which component of LLVM you were in at the time if the
+ * crash.
+ */
+void LLVMEnablePrettyStackTrace(void);
+
+/**
+ * @defgroup LLVMCCoreContext Contexts
+ *
+ * Contexts are execution states for the core LLVM IR system.
+ *
+ * Most types are tied to a context instance. Multiple contexts can
+ * exist simultaneously. A single context is not thread safe. However,
+ * different contexts can execute on different threads simultaneously.
+ *
+ * @{
+ */
+
+typedef void (*LLVMDiagnosticHandler)(LLVMDiagnosticInfoRef, void *);
+typedef void (*LLVMYieldCallback)(LLVMContextRef, void *);
+
+/**
+ * Create a new context.
+ *
+ * Every call to this function should be paired with a call to
+ * LLVMContextDispose() or the context will leak memory.
+ */
+LLVMContextRef LLVMContextCreate(void);
+
+/**
+ * Obtain the global context instance.
+ */
+LLVMContextRef LLVMGetGlobalContext(void);
+
+/**
+ * Set the diagnostic handler for this context.
+ */
+void LLVMContextSetDiagnosticHandler(LLVMContextRef C,
+                                     LLVMDiagnosticHandler Handler,
+                                     void *DiagnosticContext);
+
+/**
+ * Set the yield callback function for this context.
+ *
+ * @see LLVMContext::setYieldCallback()
+ */
+void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback,
+                                 void *OpaqueHandle);
+
+/**
+ * Destroy a context instance.
+ *
+ * This should be called for every call to LLVMContextCreate() or memory
+ * will be leaked.
+ */
+void LLVMContextDispose(LLVMContextRef C);
+
+/**
+ * Return a string representation of the DiagnosticInfo. Use
+ * LLVMDisposeMessage to free the string.
+ *
+ * @see DiagnosticInfo::print()
+ */
+char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI);
+
+/**
+ * Return an enum LLVMDiagnosticSeverity.
+ *
+ * @see DiagnosticInfo::getSeverity()
+ */
+LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI);
+
+unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
+                                  unsigned SLen);
+unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreModule Modules
+ *
+ * Modules represent the top-level structure in an LLVM program. An LLVM
+ * module is effectively a translation unit or a collection of
+ * translation units merged together.
+ *
+ * @{
+ */
+
+/**
+ * Create a new, empty module in the global context.
+ *
+ * This is equivalent to calling LLVMModuleCreateWithNameInContext with
+ * LLVMGetGlobalContext() as the context parameter.
+ *
+ * Every invocation should be paired with LLVMDisposeModule() or memory
+ * will be leaked.
+ */
+LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
+
+/**
+ * Create a new, empty module in a specific context.
+ *
+ * Every invocation should be paired with LLVMDisposeModule() or memory
+ * will be leaked.
+ */
+LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID,
+                                                LLVMContextRef C);
+
+/**
+ * Destroy a module instance.
+ *
+ * This must be called for every created module or memory will be
+ * leaked.
+ */
+void LLVMDisposeModule(LLVMModuleRef M);
+
+/**
+ * Obtain the data layout for a module.
+ *
+ * @see Module::getDataLayout()
+ */
+const char *LLVMGetDataLayout(LLVMModuleRef M);
+
+/**
+ * Set the data layout for a module.
+ *
+ * @see Module::setDataLayout()
+ */
+void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple);
+
+/**
+ * Obtain the target triple for a module.
+ *
+ * @see Module::getTargetTriple()
+ */
+const char *LLVMGetTarget(LLVMModuleRef M);
+
+/**
+ * Set the target triple for a module.
+ *
+ * @see Module::setTargetTriple()
+ */
+void LLVMSetTarget(LLVMModuleRef M, const char *Triple);
+
+/**
+ * Dump a representation of a module to stderr.
+ *
+ * @see Module::dump()
+ */
+void LLVMDumpModule(LLVMModuleRef M);
+
+/**
+ * Print a representation of a module to a file. The ErrorMessage needs to be
+ * disposed with LLVMDisposeMessage. Returns 0 on success, 1 otherwise.
+ *
+ * @see Module::print()
+ */
+LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename,
+                               char **ErrorMessage);
+
+/**
+ * Return a string representation of the module. Use
+ * LLVMDisposeMessage to free the string.
+ *
+ * @see Module::print()
+ */
+char *LLVMPrintModuleToString(LLVMModuleRef M);
+
+/**
+ * Set inline assembly for a module.
+ *
+ * @see Module::setModuleInlineAsm()
+ */
+void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm);
+
+/**
+ * Obtain the context to which this module is associated.
+ *
+ * @see Module::getContext()
+ */
+LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
+
+/**
+ * Obtain a Type from a module by its registered name.
+ */
+LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
+
+/**
+ * Obtain the number of operands for named metadata in a module.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ */
+unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name);
+
+/**
+ * Obtain the named metadata operands for a module.
+ *
+ * The passed LLVMValueRef pointer should refer to an array of
+ * LLVMValueRef at least LLVMGetNamedMetadataNumOperands long. This
+ * array will be populated with the LLVMValueRef instances. Each
+ * instance corresponds to a llvm::MDNode.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ * @see llvm::MDNode::getOperand()
+ */
+void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest);
+
+/**
+ * Add an operand to named metadata.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ * @see llvm::MDNode::addOperand()
+ */
+void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name,
+                                 LLVMValueRef Val);
+
+/**
+ * Add a function to a module under a specified name.
+ *
+ * @see llvm::Function::Create()
+ */
+LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
+                             LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain a Function value from a Module by its name.
+ *
+ * The returned value corresponds to a llvm::Function value.
+ *
+ * @see llvm::Module::getFunction()
+ */
+LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name);
+
+/**
+ * Obtain an iterator to the first Function in a Module.
+ *
+ * @see llvm::Module::begin()
+ */
+LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M);
+
+/**
+ * Obtain an iterator to the last Function in a Module.
+ *
+ * @see llvm::Module::end()
+ */
+LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M);
+
+/**
+ * Advance a Function iterator to the next Function.
+ *
+ * Returns NULL if the iterator was already at the end and there are no more
+ * functions.
+ */
+LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn);
+
+/**
+ * Decrement a Function iterator to the previous Function.
+ *
+ * Returns NULL if the iterator was already at the beginning and there are
+ * no previous functions.
+ */
+LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreType Types
+ *
+ * Types represent the type of a value.
+ *
+ * Types are associated with a context instance. The context internally
+ * deduplicates types so there is only 1 instance of a specific type
+ * alive at a time. In other words, a unique type is shared among all
+ * consumers within a context.
+ *
+ * A Type in the C API corresponds to llvm::Type.
+ *
+ * Types have the following hierarchy:
+ *
+ *   types:
+ *     integer type
+ *     real type
+ *     function type
+ *     sequence types:
+ *       array type
+ *       pointer type
+ *       vector type
+ *     void type
+ *     label type
+ *     opaque type
+ *
+ * @{
+ */
+
+/**
+ * Obtain the enumerated type of a Type instance.
+ *
+ * @see llvm::Type:getTypeID()
+ */
+LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
+
+/**
+ * Whether the type has a known size.
+ *
+ * Things that don't have a size are abstract types, labels, and void.a
+ *
+ * @see llvm::Type::isSized()
+ */
+LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty);
+
+/**
+ * Obtain the context to which this type instance is associated.
+ *
+ * @see llvm::Type::getContext()
+ */
+LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty);
+
+/**
+ * Dump a representation of a type to stderr.
+ *
+ * @see llvm::Type::dump()
+ */
+void LLVMDumpType(LLVMTypeRef Val);
+
+/**
+ * Return a string representation of the type. Use
+ * LLVMDisposeMessage to free the string.
+ *
+ * @see llvm::Type::print()
+ */
+char *LLVMPrintTypeToString(LLVMTypeRef Val);
+
+/**
+ * @defgroup LLVMCCoreTypeInt Integer Types
+ *
+ * Functions in this section operate on integer types.
+ *
+ * @{
+ */
+
+/**
+ * Obtain an integer type from a context with specified bit width.
+ */
+LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits);
+
+/**
+ * Obtain an integer type from the global context with a specified bit
+ * width.
+ */
+LLVMTypeRef LLVMInt1Type(void);
+LLVMTypeRef LLVMInt8Type(void);
+LLVMTypeRef LLVMInt16Type(void);
+LLVMTypeRef LLVMInt32Type(void);
+LLVMTypeRef LLVMInt64Type(void);
+LLVMTypeRef LLVMIntType(unsigned NumBits);
+unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeFloat Floating Point Types
+ *
+ * @{
+ */
+
+/**
+ * Obtain a 16-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 32-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 64-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 80-bit floating point type (X87) from a context.
+ */
+LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 128-bit floating point type (112-bit mantissa) from a
+ * context.
+ */
+LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 128-bit floating point type (two 64-bits) from a context.
+ */
+LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a floating point type from the global context.
+ *
+ * These map to the functions in this group of the same name.
+ */
+LLVMTypeRef LLVMHalfType(void);
+LLVMTypeRef LLVMFloatType(void);
+LLVMTypeRef LLVMDoubleType(void);
+LLVMTypeRef LLVMX86FP80Type(void);
+LLVMTypeRef LLVMFP128Type(void);
+LLVMTypeRef LLVMPPCFP128Type(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeFunction Function Types
+ *
+ * @{
+ */
+
+/**
+ * Obtain a function type consisting of a specified signature.
+ *
+ * The function is defined as a tuple of a return Type, a list of
+ * parameter types, and whether the function is variadic.
+ */
+LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType,
+                             LLVMTypeRef *ParamTypes, unsigned ParamCount,
+                             LLVMBool IsVarArg);
+
+/**
+ * Returns whether a function type is variadic.
+ */
+LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the Type this function Type returns.
+ */
+LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the number of parameters this function accepts.
+ */
+unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the types of a function's parameters.
+ *
+ * The Dest parameter should point to a pre-allocated array of
+ * LLVMTypeRef at least LLVMCountParamTypes() large. On return, the
+ * first LLVMCountParamTypes() entries in the array will be populated
+ * with LLVMTypeRef instances.
+ *
+ * @param FunctionTy The function type to operate on.
+ * @param Dest Memory address of an array to be filled with result.
+ */
+void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeStruct Structure Types
+ *
+ * These functions relate to LLVMTypeRef instances.
+ *
+ * @see llvm::StructType
+ *
+ * @{
+ */
+
+/**
+ * Create a new structure type in a context.
+ *
+ * A structure is specified by a list of inner elements/types and
+ * whether these can be packed together.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+                                    unsigned ElementCount, LLVMBool Packed);
+
+/**
+ * Create a new structure type in the global context.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
+                           LLVMBool Packed);
+
+/**
+ * Create an empty structure in a context having a specified name.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
+
+/**
+ * Obtain the name of a structure.
+ *
+ * @see llvm::StructType::getName()
+ */
+const char *LLVMGetStructName(LLVMTypeRef Ty);
+
+/**
+ * Set the contents of a structure type.
+ *
+ * @see llvm::StructType::setBody()
+ */
+void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
+                       unsigned ElementCount, LLVMBool Packed);
+
+/**
+ * Get the number of elements defined inside the structure.
+ *
+ * @see llvm::StructType::getNumElements()
+ */
+unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
+
+/**
+ * Get the elements within a structure.
+ *
+ * The function is passed the address of a pre-allocated array of
+ * LLVMTypeRef at least LLVMCountStructElementTypes() long. After
+ * invocation, this array will be populated with the structure's
+ * elements. The objects in the destination array will have a lifetime
+ * of the structure type itself, which is the lifetime of the context it
+ * is contained in.
+ */
+void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
+
+/**
+ * Determine whether a structure is packed.
+ *
+ * @see llvm::StructType::isPacked()
+ */
+LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
+
+/**
+ * Determine whether a structure is opaque.
+ *
+ * @see llvm::StructType::isOpaque()
+ */
+LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup LLVMCCoreTypeSequential Sequential Types
+ *
+ * Sequential types represents "arrays" of types. This is a super class
+ * for array, vector, and pointer types.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the type of elements within a sequential type.
+ *
+ * This works on array, vector, and pointer types.
+ *
+ * @see llvm::SequentialType::getElementType()
+ */
+LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty);
+
+/**
+ * Create a fixed size array type that refers to a specific type.
+ *
+ * The created type will exist in the context that its element type
+ * exists in.
+ *
+ * @see llvm::ArrayType::get()
+ */
+LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
+
+/**
+ * Obtain the length of an array type.
+ *
+ * This only works on types that represent arrays.
+ *
+ * @see llvm::ArrayType::getNumElements()
+ */
+unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy);
+
+/**
+ * Create a pointer type that points to a defined type.
+ *
+ * The created type will exist in the context that its pointee type
+ * exists in.
+ *
+ * @see llvm::PointerType::get()
+ */
+LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
+
+/**
+ * Obtain the address space of a pointer type.
+ *
+ * This only works on types that represent pointers.
+ *
+ * @see llvm::PointerType::getAddressSpace()
+ */
+unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy);
+
+/**
+ * Create a vector type that contains a defined type and has a specific
+ * number of elements.
+ *
+ * The created type will exist in the context thats its element type
+ * exists in.
+ *
+ * @see llvm::VectorType::get()
+ */
+LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount);
+
+/**
+ * Obtain the number of elements in a vector type.
+ *
+ * This only works on types that represent vectors.
+ *
+ * @see llvm::VectorType::getNumElements()
+ */
+unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeOther Other Types
+ *
+ * @{
+ */
+
+/**
+ * Create a void type in a context.
+ */
+LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C);
+
+/**
+ * Create a label type in a context.
+ */
+LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
+
+/**
+ * Create a X86 MMX type in a context.
+ */
+LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
+
+/**
+ * These are similar to the above functions except they operate on the
+ * global context.
+ */
+LLVMTypeRef LLVMVoidType(void);
+LLVMTypeRef LLVMLabelType(void);
+LLVMTypeRef LLVMX86MMXType(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValues Values
+ *
+ * The bulk of LLVM's object model consists of values, which comprise a very
+ * rich type hierarchy.
+ *
+ * LLVMValueRef essentially represents llvm::Value. There is a rich
+ * hierarchy of classes within this type. Depending on the instance
+ * obtained, not all APIs are available.
+ *
+ * Callers can determine the type of an LLVMValueRef by calling the
+ * LLVMIsA* family of functions (e.g. LLVMIsAArgument()). These
+ * functions are defined by a macro, so it isn't obvious which are
+ * available by looking at the Doxygen source code. Instead, look at the
+ * source definition of LLVM_FOR_EACH_VALUE_SUBCLASS and note the list
+ * of value names given. These value names also correspond to classes in
+ * the llvm::Value hierarchy.
+ *
+ * @{
+ */
+
+#define LLVM_FOR_EACH_VALUE_SUBCLASS(macro) \
+  macro(Argument)                           \
+  macro(BasicBlock)                         \
+  macro(InlineAsm)                          \
+  macro(MDNode)                             \
+  macro(MDString)                           \
+  macro(User)                               \
+    macro(Constant)                         \
+      macro(BlockAddress)                   \
+      macro(ConstantAggregateZero)          \
+      macro(ConstantArray)                  \
+      macro(ConstantDataSequential)         \
+        macro(ConstantDataArray)            \
+        macro(ConstantDataVector)           \
+      macro(ConstantExpr)                   \
+      macro(ConstantFP)                     \
+      macro(ConstantInt)                    \
+      macro(ConstantPointerNull)            \
+      macro(ConstantStruct)                 \
+      macro(ConstantVector)                 \
+      macro(GlobalValue)                    \
+        macro(GlobalAlias)                  \
+        macro(GlobalObject)                 \
+          macro(Function)                   \
+          macro(GlobalVariable)             \
+      macro(UndefValue)                     \
+    macro(Instruction)                      \
+      macro(BinaryOperator)                 \
+      macro(CallInst)                       \
+        macro(IntrinsicInst)                \
+          macro(DbgInfoIntrinsic)           \
+            macro(DbgDeclareInst)           \
+          macro(MemIntrinsic)               \
+            macro(MemCpyInst)               \
+            macro(MemMoveInst)              \
+            macro(MemSetInst)               \
+      macro(CmpInst)                        \
+        macro(FCmpInst)                     \
+        macro(ICmpInst)                     \
+      macro(ExtractElementInst)             \
+      macro(GetElementPtrInst)              \
+      macro(InsertElementInst)              \
+      macro(InsertValueInst)                \
+      macro(LandingPadInst)                 \
+      macro(PHINode)                        \
+      macro(SelectInst)                     \
+      macro(ShuffleVectorInst)              \
+      macro(StoreInst)                      \
+      macro(TerminatorInst)                 \
+        macro(BranchInst)                   \
+        macro(IndirectBrInst)               \
+        macro(InvokeInst)                   \
+        macro(ReturnInst)                   \
+        macro(SwitchInst)                   \
+        macro(UnreachableInst)              \
+        macro(ResumeInst)                   \
+      macro(UnaryInstruction)               \
+        macro(AllocaInst)                   \
+        macro(CastInst)                     \
+          macro(AddrSpaceCastInst)          \
+          macro(BitCastInst)                \
+          macro(FPExtInst)                  \
+          macro(FPToSIInst)                 \
+          macro(FPToUIInst)                 \
+          macro(FPTruncInst)                \
+          macro(IntToPtrInst)               \
+          macro(PtrToIntInst)               \
+          macro(SExtInst)                   \
+          macro(SIToFPInst)                 \
+          macro(TruncInst)                  \
+          macro(UIToFPInst)                 \
+          macro(ZExtInst)                   \
+        macro(ExtractValueInst)             \
+        macro(LoadInst)                     \
+        macro(VAArgInst)
+
+/**
+ * @defgroup LLVMCCoreValueGeneral General APIs
+ *
+ * Functions in this section work on all LLVMValueRef instances,
+ * regardless of their sub-type. They correspond to functions available
+ * on llvm::Value.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the type of a value.
+ *
+ * @see llvm::Value::getType()
+ */
+LLVMTypeRef LLVMTypeOf(LLVMValueRef Val);
+
+/**
+ * Obtain the string name of a value.
+ *
+ * @see llvm::Value::getName()
+ */
+const char *LLVMGetValueName(LLVMValueRef Val);
+
+/**
+ * Set the string name of a value.
+ *
+ * @see llvm::Value::setName()
+ */
+void LLVMSetValueName(LLVMValueRef Val, const char *Name);
+
+/**
+ * Dump a representation of a value to stderr.
+ *
+ * @see llvm::Value::dump()
+ */
+void LLVMDumpValue(LLVMValueRef Val);
+
+/**
+ * Return a string representation of the value. Use
+ * LLVMDisposeMessage to free the string.
+ *
+ * @see llvm::Value::print()
+ */
+char *LLVMPrintValueToString(LLVMValueRef Val);
+
+/**
+ * Replace all uses of a value with another one.
+ *
+ * @see llvm::Value::replaceAllUsesWith()
+ */
+void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
+
+/**
+ * Determine whether the specified constant instance is constant.
+ */
+LLVMBool LLVMIsConstant(LLVMValueRef Val);
+
+/**
+ * Determine whether a value instance is undefined.
+ */
+LLVMBool LLVMIsUndef(LLVMValueRef Val);
+
+/**
+ * Convert value instances between types.
+ *
+ * Internally, an LLVMValueRef is "pinned" to a specific type. This
+ * series of functions allows you to cast an instance to a specific
+ * type.
+ *
+ * If the cast is not valid for the specified type, NULL is returned.
+ *
+ * @see llvm::dyn_cast_or_null<>
+ */
+#define LLVM_DECLARE_VALUE_CAST(name) \
+  LLVMValueRef LLVMIsA##name(LLVMValueRef Val);
+LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST)
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueUses Usage
+ *
+ * This module defines functions that allow you to inspect the uses of a
+ * LLVMValueRef.
+ *
+ * It is possible to obtain an LLVMUseRef for any LLVMValueRef instance.
+ * Each LLVMUseRef (which corresponds to a llvm::Use instance) holds a
+ * llvm::User and llvm::Value.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the first use of a value.
+ *
+ * Uses are obtained in an iterator fashion. First, call this function
+ * to obtain a reference to the first use. Then, call LLVMGetNextUse()
+ * on that instance and all subsequently obtained instances until
+ * LLVMGetNextUse() returns NULL.
+ *
+ * @see llvm::Value::use_begin()
+ */
+LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val);
+
+/**
+ * Obtain the next use of a value.
+ *
+ * This effectively advances the iterator. It returns NULL if you are on
+ * the final use and no more are available.
+ */
+LLVMUseRef LLVMGetNextUse(LLVMUseRef U);
+
+/**
+ * Obtain the user value for a user.
+ *
+ * The returned value corresponds to a llvm::User type.
+ *
+ * @see llvm::Use::getUser()
+ */
+LLVMValueRef LLVMGetUser(LLVMUseRef U);
+
+/**
+ * Obtain the value this use corresponds to.
+ *
+ * @see llvm::Use::get().
+ */
+LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueUser User value
+ *
+ * Function in this group pertain to LLVMValueRef instances that descent
+ * from llvm::User. This includes constants, instructions, and
+ * operators.
+ *
+ * @{
+ */
+
+/**
+ * Obtain an operand at a specific index in a llvm::User value.
+ *
+ * @see llvm::User::getOperand()
+ */
+LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
+
+/**
+ * Set an operand at a specific index in a llvm::User value.
+ *
+ * @see llvm::User::setOperand()
+ */
+void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val);
+
+/**
+ * Obtain the number of operands in a llvm::User value.
+ *
+ * @see llvm::User::getNumOperands()
+ */
+int LLVMGetNumOperands(LLVMValueRef Val);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstant Constants
+ *
+ * This section contains APIs for interacting with LLVMValueRef that
+ * correspond to llvm::Constant instances.
+ *
+ * These functions will work for any LLVMValueRef in the llvm::Constant
+ * class hierarchy.
+ *
+ * @{
+ */
+
+/**
+ * Obtain a constant value referring to the null instance of a type.
+ *
+ * @see llvm::Constant::getNullValue()
+ */
+LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
+
+/**
+ * Obtain a constant value referring to the instance of a type
+ * consisting of all ones.
+ *
+ * This is only valid for integer types.
+ *
+ * @see llvm::Constant::getAllOnesValue()
+ */
+LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty);
+
+/**
+ * Obtain a constant value referring to an undefined value of a type.
+ *
+ * @see llvm::UndefValue::get()
+ */
+LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty);
+
+/**
+ * Determine whether a value instance is null.
+ *
+ * @see llvm::Constant::isNullValue()
+ */
+LLVMBool LLVMIsNull(LLVMValueRef Val);
+
+/**
+ * Obtain a constant that is a constant pointer pointing to NULL for a
+ * specified type.
+ */
+LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty);
+
+/**
+ * @defgroup LLVMCCoreValueConstantScalar Scalar constants
+ *
+ * Functions in this group model LLVMValueRef instances that correspond
+ * to constants referring to scalar types.
+ *
+ * For integer types, the LLVMTypeRef parameter should correspond to a
+ * llvm::IntegerType instance and the returned LLVMValueRef will
+ * correspond to a llvm::ConstantInt.
+ *
+ * For floating point types, the LLVMTypeRef returned corresponds to a
+ * llvm::ConstantFP.
+ *
+ * @{
+ */
+
+/**
+ * Obtain a constant value for an integer type.
+ *
+ * The returned value corresponds to a llvm::ConstantInt.
+ *
+ * @see llvm::ConstantInt::get()
+ *
+ * @param IntTy Integer type to obtain value of.
+ * @param N The value the returned instance should refer to.
+ * @param SignExtend Whether to sign extend the produced value.
+ */
+LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
+                          LLVMBool SignExtend);
+
+/**
+ * Obtain a constant value for an integer of arbitrary precision.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy,
+                                              unsigned NumWords,
+                                              const uint64_t Words[]);
+
+/**
+ * Obtain a constant value for an integer parsed from a string.
+ *
+ * A similar API, LLVMConstIntOfStringAndSize is also available. If the
+ * string's length is available, it is preferred to call that function
+ * instead.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char *Text,
+                                  uint8_t Radix);
+
+/**
+ * Obtain a constant value for an integer parsed from a string with
+ * specified length.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char *Text,
+                                         unsigned SLen, uint8_t Radix);
+
+/**
+ * Obtain a constant value referring to a double floating point value.
+ */
+LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N);
+
+/**
+ * Obtain a constant for a floating point value parsed from a string.
+ *
+ * A similar API, LLVMConstRealOfStringAndSize is also available. It
+ * should be used if the input string's length is known.
+ */
+LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text);
+
+/**
+ * Obtain a constant for a floating point value parsed from a string.
+ */
+LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char *Text,
+                                          unsigned SLen);
+
+/**
+ * Obtain the zero extended value for an integer constant value.
+ *
+ * @see llvm::ConstantInt::getZExtValue()
+ */
+unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal);
+
+/**
+ * Obtain the sign extended value for an integer constant value.
+ *
+ * @see llvm::ConstantInt::getSExtValue()
+ */
+long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantComposite Composite Constants
+ *
+ * Functions in this group operate on composite constants.
+ *
+ * @{
+ */
+
+/**
+ * Create a ConstantDataSequential and initialize it with a string.
+ *
+ * @see llvm::ConstantDataArray::getString()
+ */
+LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str,
+                                      unsigned Length, LLVMBool DontNullTerminate);
+
+/**
+ * Create a ConstantDataSequential with string content in the global context.
+ *
+ * This is the same as LLVMConstStringInContext except it operates on the
+ * global context.
+ *
+ * @see LLVMConstStringInContext()
+ * @see llvm::ConstantDataArray::getString()
+ */
+LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
+                             LLVMBool DontNullTerminate);
+
+/**
+ * Create an anonymous ConstantStruct with the specified values.
+ *
+ * @see llvm::ConstantStruct::getAnon()
+ */
+LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
+                                      LLVMValueRef *ConstantVals,
+                                      unsigned Count, LLVMBool Packed);
+
+/**
+ * Create a ConstantStruct in the global Context.
+ *
+ * This is the same as LLVMConstStructInContext except it operates on the
+ * global Context.
+ *
+ * @see LLVMConstStructInContext()
+ */
+LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
+                             LLVMBool Packed);
+
+/**
+ * Create a ConstantArray from values.
+ *
+ * @see llvm::ConstantArray::get()
+ */
+LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
+                            LLVMValueRef *ConstantVals, unsigned Length);
+
+/**
+ * Create a non-anonymous ConstantStruct from values.
+ *
+ * @see llvm::ConstantStruct::get()
+ */
+LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy,
+                                  LLVMValueRef *ConstantVals,
+                                  unsigned Count);
+
+/**
+ * Create a ConstantVector from values.
+ *
+ * @see llvm::ConstantVector::get()
+ */
+LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantExpressions Constant Expressions
+ *
+ * Functions in this group correspond to APIs on llvm::ConstantExpr.
+ *
+ * @see llvm::ConstantExpr.
+ *
+ * @{
+ */
+LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty);
+LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
+LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate,
+                           LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate,
+                           LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
+                          LLVMValueRef *ConstantIndices, unsigned NumIndices);
+LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
+                                  LLVMValueRef *ConstantIndices,
+                                  unsigned NumIndices);
+LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
+                                    LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal,
+                                    LLVMTypeRef ToType);
+LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal,
+                                     LLVMTypeRef ToType);
+LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
+                                  LLVMTypeRef ToType);
+LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
+                              LLVMBool isSigned);
+LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
+                             LLVMValueRef ConstantIfTrue,
+                             LLVMValueRef ConstantIfFalse);
+LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
+                                     LLVMValueRef IndexConstant);
+LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
+                                    LLVMValueRef ElementValueConstant,
+                                    LLVMValueRef IndexConstant);
+LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
+                                    LLVMValueRef VectorBConstant,
+                                    LLVMValueRef MaskConstant);
+LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
+                                   unsigned NumIdx);
+LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
+                                  LLVMValueRef ElementValueConstant,
+                                  unsigned *IdxList, unsigned NumIdx);
+LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
+                                const char *AsmString, const char *Constraints,
+                                LLVMBool HasSideEffects, LLVMBool IsAlignStack);
+LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantGlobals Global Values
+ *
+ * This group contains functions that operate on global values. Functions in
+ * this group relate to functions in the llvm::GlobalValue class tree.
+ *
+ * @see llvm::GlobalValue
+ *
+ * @{
+ */
+
+LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
+LLVMBool LLVMIsDeclaration(LLVMValueRef Global);
+LLVMLinkage LLVMGetLinkage(LLVMValueRef Global);
+void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage);
+const char *LLVMGetSection(LLVMValueRef Global);
+void LLVMSetSection(LLVMValueRef Global, const char *Section);
+LLVMVisibility LLVMGetVisibility(LLVMValueRef Global);
+void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz);
+LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global);
+void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class);
+LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global);
+void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr);
+
+/**
+ * @defgroup LLVMCCoreValueWithAlignment Values with alignment
+ *
+ * Functions in this group only apply to values with alignment, i.e.
+ * global variables, load and store instructions.
+ */
+
+/**
+ * Obtain the preferred alignment of the value.
+ * @see llvm::AllocaInst::getAlignment()
+ * @see llvm::LoadInst::getAlignment()
+ * @see llvm::StoreInst::getAlignment()
+ * @see llvm::GlobalValue::getAlignment()
+ */
+unsigned LLVMGetAlignment(LLVMValueRef V);
+
+/**
+ * Set the preferred alignment of the value.
+ * @see llvm::AllocaInst::setAlignment()
+ * @see llvm::LoadInst::setAlignment()
+ * @see llvm::StoreInst::setAlignment()
+ * @see llvm::GlobalValue::setAlignment()
+ */
+void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes);
+
+/**
+  * @}
+  */
+
+/**
+ * @defgroup LLVMCoreValueConstantGlobalVariable Global Variables
+ *
+ * This group contains functions that operate on global variable values.
+ *
+ * @see llvm::GlobalVariable
+ *
+ * @{
+ */
+LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+                                         const char *Name,
+                                         unsigned AddressSpace);
+LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name);
+LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
+LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M);
+LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar);
+LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar);
+void LLVMDeleteGlobal(LLVMValueRef GlobalVar);
+LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar);
+void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
+LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar);
+void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal);
+LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
+void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant);
+LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar);
+void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode);
+LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar);
+void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases
+ *
+ * This group contains function that operate on global alias values.
+ *
+ * @see llvm::GlobalAlias
+ *
+ * @{
+ */
+LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
+                          const char *Name);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueFunction Function values
+ *
+ * Functions in this group operate on LLVMValueRef instances that
+ * correspond to llvm::Function instances.
+ *
+ * @see llvm::Function
+ *
+ * @{
+ */
+
+/**
+ * Remove a function from its containing module and deletes it.
+ *
+ * @see llvm::Function::eraseFromParent()
+ */
+void LLVMDeleteFunction(LLVMValueRef Fn);
+
+/**
+ * Obtain the ID number from a function instance.
+ *
+ * @see llvm::Function::getIntrinsicID()
+ */
+unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
+
+/**
+ * Obtain the calling function of a function.
+ *
+ * The returned value corresponds to the LLVMCallConv enumeration.
+ *
+ * @see llvm::Function::getCallingConv()
+ */
+unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn);
+
+/**
+ * Set the calling convention of a function.
+ *
+ * @see llvm::Function::setCallingConv()
+ *
+ * @param Fn Function to operate on
+ * @param CC LLVMCallConv to set calling convention to
+ */
+void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC);
+
+/**
+ * Obtain the name of the garbage collector to use during code
+ * generation.
+ *
+ * @see llvm::Function::getGC()
+ */
+const char *LLVMGetGC(LLVMValueRef Fn);
+
+/**
+ * Define the garbage collector to use during code generation.
+ *
+ * @see llvm::Function::setGC()
+ */
+void LLVMSetGC(LLVMValueRef Fn, const char *Name);
+
+/**
+ * Add an attribute to a function.
+ *
+ * @see llvm::Function::addAttribute()
+ */
+void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);
+
+/**
+ * Add a target-dependent attribute to a fuction
+ * @see llvm::AttrBuilder::addAttribute()
+ */
+void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A,
+                                        const char *V);
+
+/**
+ * Obtain an attribute from a function.
+ *
+ * @see llvm::Function::getAttributes()
+ */
+LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn);
+
+/**
+ * Remove an attribute from a function.
+ */
+void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);
+
+/**
+ * @defgroup LLVMCCoreValueFunctionParameters Function Parameters
+ *
+ * Functions in this group relate to arguments/parameters on functions.
+ *
+ * Functions in this group expect LLVMValueRef instances that correspond
+ * to llvm::Function instances.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the number of parameters in a function.
+ *
+ * @see llvm::Function::arg_size()
+ */
+unsigned LLVMCountParams(LLVMValueRef Fn);
+
+/**
+ * Obtain the parameters in a function.
+ *
+ * The takes a pointer to a pre-allocated array of LLVMValueRef that is
+ * at least LLVMCountParams() long. This array will be filled with
+ * LLVMValueRef instances which correspond to the parameters the
+ * function receives. Each LLVMValueRef corresponds to a llvm::Argument
+ * instance.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params);
+
+/**
+ * Obtain the parameter at the specified index.
+ *
+ * Parameters are indexed from 0.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index);
+
+/**
+ * Obtain the function to which this argument belongs.
+ *
+ * Unlike other functions in this group, this one takes an LLVMValueRef
+ * that corresponds to a llvm::Attribute.
+ *
+ * The returned LLVMValueRef is the llvm::Function to which this
+ * argument belongs.
+ */
+LLVMValueRef LLVMGetParamParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the first parameter to a function.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn);
+
+/**
+ * Obtain the last parameter to a function.
+ *
+ * @see llvm::Function::arg_end()
+ */
+LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn);
+
+/**
+ * Obtain the next parameter to a function.
+ *
+ * This takes an LLVMValueRef obtained from LLVMGetFirstParam() (which is
+ * actually a wrapped iterator) and obtains the next parameter from the
+ * underlying iterator.
+ */
+LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg);
+
+/**
+ * Obtain the previous parameter to a function.
+ *
+ * This is the opposite of LLVMGetNextParam().
+ */
+LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg);
+
+/**
+ * Add an attribute to a function argument.
+ *
+ * @see llvm::Argument::addAttr()
+ */
+void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA);
+
+/**
+ * Remove an attribute from a function argument.
+ *
+ * @see llvm::Argument::removeAttr()
+ */
+void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA);
+
+/**
+ * Get an attribute from a function argument.
+ */
+LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
+
+/**
+ * Set the alignment for a function parameter.
+ *
+ * @see llvm::Argument::addAttr()
+ * @see llvm::AttrBuilder::addAlignmentAttr()
+ */
+void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueMetadata Metadata
+ *
+ * @{
+ */
+
+/**
+ * Obtain a MDString value from a context.
+ *
+ * The returned instance corresponds to the llvm::MDString class.
+ *
+ * The instance is specified by string data of a specified length. The
+ * string content is copied, so the backing memory can be freed after
+ * this function returns.
+ */
+LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
+                                   unsigned SLen);
+
+/**
+ * Obtain a MDString value from the global context.
+ */
+LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
+
+/**
+ * Obtain a MDNode value from a context.
+ *
+ * The returned value corresponds to the llvm::MDNode class.
+ */
+LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
+                                 unsigned Count);
+
+/**
+ * Obtain a MDNode value from the global context.
+ */
+LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
+
+/**
+ * Obtain the underlying string from a MDString value.
+ *
+ * @param V Instance to obtain string from.
+ * @param Len Memory address which will hold length of returned string.
+ * @return String data in MDString.
+ */
+const char  *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
+
+/**
+ * Obtain the number of operands from an MDNode value.
+ *
+ * @param V MDNode to get number of operands from.
+ * @return Number of operands of the MDNode.
+ */
+unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V);
+
+/**
+ * Obtain the given MDNode's operands.
+ *
+ * The passed LLVMValueRef pointer should point to enough memory to hold all of
+ * the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as
+ * LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the
+ * MDNode's operands.
+ *
+ * @param V MDNode to get the operands from.
+ * @param Dest Destination array for operands.
+ */
+void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueBasicBlock Basic Block
+ *
+ * A basic block represents a single entry single exit section of code.
+ * Basic blocks contain a list of instructions which form the body of
+ * the block.
+ *
+ * Basic blocks belong to functions. They have the type of label.
+ *
+ * Basic blocks are themselves values. However, the C API models them as
+ * LLVMBasicBlockRef.
+ *
+ * @see llvm::BasicBlock
+ *
+ * @{
+ */
+
+/**
+ * Convert a basic block instance to a value type.
+ */
+LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB);
+
+/**
+ * Determine whether an LLVMValueRef is itself a basic block.
+ */
+LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val);
+
+/**
+ * Convert an LLVMValueRef to an LLVMBasicBlockRef instance.
+ */
+LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
+
+/**
+ * Obtain the function to which a basic block belongs.
+ *
+ * @see llvm::BasicBlock::getParent()
+ */
+LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the terminator instruction for a basic block.
+ *
+ * If the basic block does not have a terminator (it is not well-formed
+ * if it doesn't), then NULL is returned.
+ *
+ * The returned LLVMValueRef corresponds to a llvm::TerminatorInst.
+ *
+ * @see llvm::BasicBlock::getTerminator()
+ */
+LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the number of basic blocks in a function.
+ *
+ * @param Fn Function value to operate on.
+ */
+unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
+
+/**
+ * Obtain all of the basic blocks in a function.
+ *
+ * This operates on a function value. The BasicBlocks parameter is a
+ * pointer to a pre-allocated array of LLVMBasicBlockRef of at least
+ * LLVMCountBasicBlocks() in length. This array is populated with
+ * LLVMBasicBlockRef instances.
+ */
+void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
+
+/**
+ * Obtain the first basic block in a function.
+ *
+ * The returned basic block can be used as an iterator. You will likely
+ * eventually call into LLVMGetNextBasicBlock() with it.
+ *
+ * @see llvm::Function::begin()
+ */
+LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Obtain the last basic block in a function.
+ *
+ * @see llvm::Function::end()
+ */
+LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Advance a basic block iterator.
+ */
+LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Go backwards in a basic block iterator.
+ */
+LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the basic block that corresponds to the entry point of a
+ * function.
+ *
+ * @see llvm::Function::getEntryBlock()
+ */
+LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Append a basic block to the end of a function.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C,
+                                                LLVMValueRef Fn,
+                                                const char *Name);
+
+/**
+ * Append a basic block to the end of a function using the global
+ * context.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name);
+
+/**
+ * Insert a basic block in a function before another basic block.
+ *
+ * The function to add to is determined by the function of the
+ * passed basic block.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C,
+                                                LLVMBasicBlockRef BB,
+                                                const char *Name);
+
+/**
+ * Insert a basic block in a function using the global context.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
+                                       const char *Name);
+
+/**
+ * Remove a basic block from a function and delete it.
+ *
+ * This deletes the basic block from its containing function and deletes
+ * the basic block itself.
+ *
+ * @see llvm::BasicBlock::eraseFromParent()
+ */
+void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Remove a basic block from a function.
+ *
+ * This deletes the basic block from its containing function but keep
+ * the basic block alive.
+ *
+ * @see llvm::BasicBlock::removeFromParent()
+ */
+void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB);
+
+/**
+ * Move a basic block to before another one.
+ *
+ * @see llvm::BasicBlock::moveBefore()
+ */
+void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
+
+/**
+ * Move a basic block to after another one.
+ *
+ * @see llvm::BasicBlock::moveAfter()
+ */
+void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
+
+/**
+ * Obtain the first instruction in a basic block.
+ *
+ * The returned LLVMValueRef corresponds to a llvm::Instruction
+ * instance.
+ */
+LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the last instruction in a basic block.
+ *
+ * The returned LLVMValueRef corresponds to an LLVM:Instruction.
+ */
+LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueInstruction Instructions
+ *
+ * Functions in this group relate to the inspection and manipulation of
+ * individual instructions.
+ *
+ * In the C++ API, an instruction is modeled by llvm::Instruction. This
+ * class has a large number of descendents. llvm::Instruction is a
+ * llvm::Value and in the C API, instructions are modeled by
+ * LLVMValueRef.
+ *
+ * This group also contains sub-groups which operate on specific
+ * llvm::Instruction types, e.g. llvm::CallInst.
+ *
+ * @{
+ */
+
+/**
+ * Determine whether an instruction has any metadata attached.
+ */
+int LLVMHasMetadata(LLVMValueRef Val);
+
+/**
+ * Return metadata associated with an instruction value.
+ */
+LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID);
+
+/**
+ * Set metadata associated with an instruction value.
+ */
+void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node);
+
+/**
+ * Obtain the basic block to which an instruction belongs.
+ *
+ * @see llvm::Instruction::getParent()
+ */
+LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the instruction that occurs after the one specified.
+ *
+ * The next instruction will be from the same basic block.
+ *
+ * If this is the last instruction in a basic block, NULL will be
+ * returned.
+ */
+LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
+
+/**
+ * Obtain the instruction that occurred before this one.
+ *
+ * If the instruction is the first instruction in a basic block, NULL
+ * will be returned.
+ */
+LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
+
+/**
+ * Remove and delete an instruction.
+ *
+ * The instruction specified is removed from its containing building
+ * block and then deleted.
+ *
+ * @see llvm::Instruction::eraseFromParent()
+ */
+void LLVMInstructionEraseFromParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the code opcode for an individual instruction.
+ *
+ * @see llvm::Instruction::getOpCode()
+ */
+LLVMOpcode   LLVMGetInstructionOpcode(LLVMValueRef Inst);
+
+/**
+ * Obtain the predicate of an instruction.
+ *
+ * This is only valid for instructions that correspond to llvm::ICmpInst
+ * or llvm::ConstantExpr whose opcode is llvm::Instruction::ICmp.
+ *
+ * @see llvm::ICmpInst::getPredicate()
+ */
+LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst);
+
+/**
+ * @defgroup LLVMCCoreValueInstructionCall Call Sites and Invocations
+ *
+ * Functions in this group apply to instructions that refer to call
+ * sites and invocations. These correspond to C++ types in the
+ * llvm::CallInst class tree.
+ *
+ * @{
+ */
+
+/**
+ * Set the calling convention for a call instruction.
+ *
+ * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
+ * llvm::InvokeInst.
+ *
+ * @see llvm::CallInst::setCallingConv()
+ * @see llvm::InvokeInst::setCallingConv()
+ */
+void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC);
+
+/**
+ * Obtain the calling convention for a call instruction.
+ *
+ * This is the opposite of LLVMSetInstructionCallConv(). Reads its
+ * usage.
+ *
+ * @see LLVMSetInstructionCallConv()
+ */
+unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr);
+
+
+void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute);
+void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
+                              LLVMAttribute);
+void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
+                                unsigned align);
+
+/**
+ * Obtain whether a call instruction is a tail call.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::isTailCall()
+ */
+LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
+
+/**
+ * Set whether a call instruction is a tail call.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::setTailCall()
+ */
+void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
+
+/**
+ * @}
+ */
+
+/**
+ * Obtain the default destination basic block of a switch instruction.
+ *
+ * This only works on llvm::SwitchInst instructions.
+ *
+ * @see llvm::SwitchInst::getDefaultDest()
+ */
+LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr);
+
+/**
+ * @defgroup LLVMCCoreValueInstructionPHINode PHI Nodes
+ *
+ * Functions in this group only apply to instructions that map to
+ * llvm::PHINode instances.
+ *
+ * @{
+ */
+
+/**
+ * Add an incoming value to the end of a PHI list.
+ */
+void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
+                     LLVMBasicBlockRef *IncomingBlocks, unsigned Count);
+
+/**
+ * Obtain the number of incoming basic blocks to a PHI node.
+ */
+unsigned LLVMCountIncoming(LLVMValueRef PhiNode);
+
+/**
+ * Obtain an incoming value to a PHI node as an LLVMValueRef.
+ */
+LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index);
+
+/**
+ * Obtain an incoming value to a PHI node as an LLVMBasicBlockRef.
+ */
+LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreInstructionBuilder Instruction Builders
+ *
+ * An instruction builder represents a point within a basic block and is
+ * the exclusive means of building instructions using the C interface.
+ *
+ * @{
+ */
+
+LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C);
+LLVMBuilderRef LLVMCreateBuilder(void);
+void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
+                         LLVMValueRef Instr);
+void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr);
+void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block);
+LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder);
+void LLVMClearInsertionPosition(LLVMBuilderRef Builder);
+void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr);
+void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr,
+                                   const char *Name);
+void LLVMDisposeBuilder(LLVMBuilderRef Builder);
+
+/* Metadata */
+void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L);
+LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder);
+void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst);
+
+/* Terminators */
+LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
+LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
+LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef, LLVMValueRef *RetVals,
+                                   unsigned N);
+LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest);
+LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
+LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
+                             LLVMBasicBlockRef Else, unsigned NumCases);
+LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
+                                 unsigned NumDests);
+LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
+                             LLVMValueRef *Args, unsigned NumArgs,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
+                             const char *Name);
+LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
+                                 LLVMValueRef PersFn, unsigned NumClauses,
+                                 const char *Name);
+LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
+LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
+
+/* Add a case to the switch instruction */
+void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
+                 LLVMBasicBlockRef Dest);
+
+/* Add a destination to the indirectbr instruction */
+void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
+
+/* Add a catch or filter clause to the landingpad instruction */
+void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal);
+
+/* Set the 'cleanup' flag in the landingpad instruction */
+void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
+
+/* Arithmetic */
+LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                             const char *Name);
+LLVMValueRef LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                                const char *Name);
+LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
+                            LLVMValueRef LHS, LLVMValueRef RHS,
+                            const char *Name);
+LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
+                             const char *Name);
+LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
+                             const char *Name);
+LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+
+/* Memory */
+LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal);
+LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal,
+                           const char *Name);
+LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr);
+LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+                          LLVMValueRef *Indices, unsigned NumIndices,
+                          const char *Name);
+LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+                                  LLVMValueRef *Indices, unsigned NumIndices,
+                                  const char *Name);
+LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+                                unsigned Idx, const char *Name);
+LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str,
+                                   const char *Name);
+LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str,
+                                      const char *Name);
+LLVMBool LLVMGetVolatile(LLVMValueRef MemoryAccessInst);
+void LLVMSetVolatile(LLVMValueRef MemoryAccessInst, LLVMBool IsVolatile);
+
+/* Casts */
+LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef, LLVMValueRef Val,
+                                    LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+                                    LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+                                    LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+                                     LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
+                                  LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/
+                              LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+
+/* Comparisons */
+LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+
+/* Miscellaneous instructions */
+LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn,
+                           LLVMValueRef *Args, unsigned NumArgs,
+                           const char *Name);
+LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If,
+                             LLVMValueRef Then, LLVMValueRef Else,
+                             const char *Name);
+LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty,
+                            const char *Name);
+LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal,
+                                     LLVMValueRef Index, const char *Name);
+LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal,
+                                    LLVMValueRef EltVal, LLVMValueRef Index,
+                                    const char *Name);
+LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
+                                    LLVMValueRef V2, LLVMValueRef Mask,
+                                    const char *Name);
+LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef, LLVMValueRef AggVal,
+                                   unsigned Index, const char *Name);
+LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal,
+                                  LLVMValueRef EltVal, unsigned Index,
+                                  const char *Name);
+
+LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val,
+                             const char *Name);
+LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val,
+                                const char *Name);
+LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
+                              LLVMValueRef RHS, const char *Name);
+LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering ordering,
+                            LLVMBool singleThread, const char *Name);
+LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op,
+                                LLVMValueRef PTR, LLVMValueRef Val,
+                                LLVMAtomicOrdering ordering,
+                                LLVMBool singleThread);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreModuleProvider Module Providers
+ *
+ * @{
+ */
+
+/**
+ * Changes the type of M so it can be passed to FunctionPassManagers and the
+ * JIT.  They take ModuleProviders for historical reasons.
+ */
+LLVMModuleProviderRef
+LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
+
+/**
+ * Destroys the module M.
+ */
+void LLVMDisposeModuleProvider(LLVMModuleProviderRef M);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreMemoryBuffers Memory Buffers
+ *
+ * @{
+ */
+
+LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
+                                                  LLVMMemoryBufferRef *OutMemBuf,
+                                                  char **OutMessage);
+LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
+                                         char **OutMessage);
+LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange(const char *InputData,
+                                                          size_t InputDataLength,
+                                                          const char *BufferName,
+                                                          LLVMBool RequiresNullTerminator);
+LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy(const char *InputData,
+                                                              size_t InputDataLength,
+                                                              const char *BufferName);
+const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf);
+size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf);
+void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCorePassRegistry Pass Registry
+ *
+ * @{
+ */
+
+/** Return the global pass registry, for use with initialization functions.
+    @see llvm::PassRegistry::getPassRegistry */
+LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCorePassManagers Pass Managers
+ *
+ * @{
+ */
+
+/** Constructs a new whole-module pass pipeline. This type of pipeline is
+    suitable for link-time optimization and whole-module transformations.
+    @see llvm::PassManager::PassManager */
+LLVMPassManagerRef LLVMCreatePassManager(void);
+
+/** Constructs a new function-by-function pass pipeline over the module
+    provider. It does not take ownership of the module provider. This type of
+    pipeline is suitable for code generation and JIT compilation tasks.
+    @see llvm::FunctionPassManager::FunctionPassManager */
+LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M);
+
+/** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */
+LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
+
+/** Initializes, executes on the provided module, and finalizes all of the
+    passes scheduled in the pass manager. Returns 1 if any of the passes
+    modified the module, 0 otherwise.
+    @see llvm::PassManager::run(Module&) */
+LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
+
+/** Initializes all of the function passes scheduled in the function pass
+    manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+    @see llvm::FunctionPassManager::doInitialization */
+LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Executes all of the function passes scheduled in the function pass manager
+    on the provided function. Returns 1 if any of the passes modified the
+    function, false otherwise.
+    @see llvm::FunctionPassManager::run(Function&) */
+LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
+
+/** Finalizes all of the function passes scheduled in in the function pass
+    manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+    @see llvm::FunctionPassManager::doFinalization */
+LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Frees the memory of a pass pipeline. For function pipelines, does not free
+    the module provider.
+    @see llvm::PassManagerBase::~PassManagerBase. */
+void LLVMDisposePassManager(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreThreading Threading
+ *
+ * Handle the structures needed to make LLVM safe for multithreading.
+ *
+ * @{
+ */
+
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+    time define LLVM_ENABLE_THREADS.  This function always returns
+    LLVMIsMultithreaded(). */
+LLVMBool LLVMStartMultithreaded(void);
+
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+    time define LLVM_ENABLE_THREADS. */
+void LLVMStopMultithreaded(void);
+
+/** Check whether LLVM is executing in thread-safe mode or not.
+    @see llvm::llvm_is_multithreaded */
+LLVMBool LLVMIsMultithreaded(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_CORE_H) */
diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h
new file mode 100644
index 0000000..8f31150
--- /dev/null
+++ b/include/llvm-c/Disassembler.h
@@ -0,0 +1,240 @@
+/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public interface to a disassembler library.         *|
+|* LLVM provides an implementation of this interface.                         *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_DISASSEMBLER_H
+#define LLVM_C_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <stddef.h>
+
+/**
+ * @defgroup LLVMCDisassembler Disassembler
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/**
+ * An opaque reference to a disassembler context.
+ */
+typedef void *LLVMDisasmContextRef;
+
+/**
+ * The type for the operand information call back function.  This is called to
+ * get the symbolic information for an operand of an instruction.  Typically
+ * this is from the relocation information, symbol table, etc.  That block of
+ * information is saved when the disassembler context is created and passed to
+ * the call back in the DisInfo parameter.  The instruction containing operand
+ * is at the PC parameter.  For some instruction sets, there can be more than
+ * one operand with symbolic information.  To determine the symbolic operand
+ * information for each operand, the bytes for the specific operand in the
+ * instruction are specified by the Offset parameter and its byte widith is the
+ * size parameter.  For instructions sets with fixed widths and one symbolic
+ * operand per instruction, the Offset parameter will be zero and Size parameter
+ * will be the instruction width.  The information is returned in TagBuf and is
+ * Triple specific with its specific information defined by the value of
+ * TagType for that Triple.  If symbolic information is returned the function
+ * returns 1, otherwise it returns 0.
+ */
+typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC,
+                                  uint64_t Offset, uint64_t Size,
+                                  int TagType, void *TagBuf);
+
+/**
+ * The initial support in LLVM MC for the most general form of a relocatable
+ * expression is "AddSymbol - SubtractSymbol + Offset".  For some Darwin targets
+ * this full form is encoded in the relocation information so that AddSymbol and
+ * SubtractSymbol can be link edited independent of each other.  Many other
+ * platforms only allow a relocatable expression of the form AddSymbol + Offset
+ * to be encoded.
+ *
+ * The LLVMOpInfoCallback() for the TagType value of 1 uses the struct
+ * LLVMOpInfo1.  The value of the relocatable expression for the operand,
+ * including any PC adjustment, is passed in to the call back in the Value
+ * field.  The symbolic information about the operand is returned using all
+ * the fields of the structure with the Offset of the relocatable expression
+ * returned in the Value field.  It is possible that some symbols in the
+ * relocatable expression were assembly temporary symbols, for example
+ * "Ldata - LpicBase + constant", and only the Values of the symbols without
+ * symbol names are present in the relocation information.  The VariantKind
+ * type is one of the Target specific #defines below and is used to print
+ * operands like "_foo@GOT", ":lower16:_foo", etc.
+ */
+struct LLVMOpInfoSymbol1 {
+  uint64_t Present;  /* 1 if this symbol is present */
+  const char *Name;  /* symbol name if not NULL */
+  uint64_t Value;    /* symbol value if name is NULL */
+};
+
+struct LLVMOpInfo1 {
+  struct LLVMOpInfoSymbol1 AddSymbol;
+  struct LLVMOpInfoSymbol1 SubtractSymbol;
+  uint64_t Value;
+  uint64_t VariantKind;
+};
+
+/**
+ * The operand VariantKinds for symbolic disassembly.
+ */
+#define LLVMDisassembler_VariantKind_None 0 /* all targets */
+
+/**
+ * The ARM target VariantKinds.
+ */
+#define LLVMDisassembler_VariantKind_ARM_HI16 1 /* :upper16: */
+#define LLVMDisassembler_VariantKind_ARM_LO16 2 /* :lower16: */
+
+/**
+ * The ARM64 target VariantKinds.
+ */
+#define LLVMDisassembler_VariantKind_ARM64_PAGE       1 /* @page */
+#define LLVMDisassembler_VariantKind_ARM64_PAGEOFF    2 /* @pageoff */
+#define LLVMDisassembler_VariantKind_ARM64_GOTPAGE    3 /* @gotpage */
+#define LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF 4 /* @gotpageoff */
+#define LLVMDisassembler_VariantKind_ARM64_TLVP       5 /* @tvlppage */
+#define LLVMDisassembler_VariantKind_ARM64_TLVOFF     6 /* @tvlppageoff */
+
+/**
+ * The type for the symbol lookup function.  This may be called by the
+ * disassembler for things like adding a comment for a PC plus a constant
+ * offset load instruction to use a symbol name instead of a load address value.
+ * It is passed the block information is saved when the disassembler context is
+ * created and the ReferenceValue to look up as a symbol.  If no symbol is found
+ * for the ReferenceValue NULL is returned.  The ReferenceType of the
+ * instruction is passed indirectly as is the PC of the instruction in
+ * ReferencePC.  If the output reference can be determined its type is returned
+ * indirectly in ReferenceType along with ReferenceName if any, or that is set
+ * to NULL.
+ */
+typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
+                                                uint64_t ReferenceValue,
+                                                uint64_t *ReferenceType,
+                                                uint64_t ReferencePC,
+                                                const char **ReferenceName);
+/**
+ * The reference types on input and output.
+ */
+/* No input reference type or no output reference type. */
+#define LLVMDisassembler_ReferenceType_InOut_None 0
+
+/* The input reference is from a branch instruction. */
+#define LLVMDisassembler_ReferenceType_In_Branch 1
+/* The input reference is from a PC relative load instruction. */
+#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2
+
+/* The input reference is from an ARM64::ADRP instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADRP 0x100000001
+/* The input reference is from an ARM64::ADDXri instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADDXri 0x100000002
+/* The input reference is from an ARM64::LDRXui instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_LDRXui 0x100000003
+/* The input reference is from an ARM64::LDRXl instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_LDRXl 0x100000004
+/* The input reference is from an ARM64::ADR instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADR 0x100000005
+
+/* The output reference is to as symbol stub. */
+#define LLVMDisassembler_ReferenceType_Out_SymbolStub 1
+/* The output reference is to a symbol address in a literal pool. */
+#define LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr 2
+/* The output reference is to a cstring address in a literal pool. */
+#define LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr 3
+
+/* The output reference is to a Objective-C CoreFoundation string. */
+#define LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref 4
+/* The output reference is to a Objective-C message. */
+#define LLVMDisassembler_ReferenceType_Out_Objc_Message 5
+/* The output reference is to a Objective-C message ref. */
+#define LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref 6
+/* The output reference is to a Objective-C selector ref. */
+#define LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref 7
+/* The output reference is to a Objective-C class ref. */
+#define LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref 8
+
+/* The output reference is to a C++ symbol name. */
+#define LLVMDisassembler_ReferenceType_DeMangled_Name 9
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* !defined(__cplusplus) */
+
+/**
+ * Create a disassembler for the TripleName.  Symbolic disassembly is supported
+ * by passing a block of information in the DisInfo parameter and specifying the
+ * TagType and callback functions as described above.  These can all be passed
+ * as NULL.  If successful, this returns a disassembler context.  If not, it
+ * returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU()
+ * with an empty CPU name.
+ */
+LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
+                                      int TagType, LLVMOpInfoCallback GetOpInfo,
+                                      LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Create a disassembler for the TripleName and a specific CPU.  Symbolic
+ * disassembly is supported by passing a block of information in the DisInfo
+ * parameter and specifying the TagType and callback functions as described
+ * above.  These can all be passed * as NULL.  If successful, this returns a
+ * disassembler context.  If not, it returns NULL.
+ */
+LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
+                                         void *DisInfo, int TagType,
+                                         LLVMOpInfoCallback GetOpInfo,
+                                         LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Set the disassembler's options.  Returns 1 if it can set the Options and 0
+ * otherwise.
+ */
+int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
+
+/* The option to produce marked up assembly. */
+#define LLVMDisassembler_Option_UseMarkup 1
+/* The option to print immediates as hex. */
+#define LLVMDisassembler_Option_PrintImmHex 2
+/* The option use the other assembler printer variant */
+#define LLVMDisassembler_Option_AsmPrinterVariant 4
+/* The option to set comment on instructions */
+#define LLVMDisassembler_Option_SetInstrComments 8
+  /* The option to print latency information alongside instructions */
+#define LLVMDisassembler_Option_PrintLatency 16
+
+/**
+ * Dispose of a disassembler context.
+ */
+void LLVMDisasmDispose(LLVMDisasmContextRef DC);
+
+/**
+ * Disassemble a single instruction using the disassembler context specified in
+ * the parameter DC.  The bytes of the instruction are specified in the
+ * parameter Bytes, and contains at least BytesSize number of bytes.  The
+ * instruction is at the address specified by the PC parameter.  If a valid
+ * instruction can be disassembled, its string is returned indirectly in
+ * OutString whose size is specified in the parameter OutStringSize.  This
+ * function returns the number of bytes in the instruction or zero if there was
+ * no valid instruction.
+ */
+size_t LLVMDisasmInstruction(LLVMDisasmContextRef DC, uint8_t *Bytes,
+                             uint64_t BytesSize, uint64_t PC,
+                             char *OutString, size_t OutStringSize);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_DISASSEMBLER_H) */
diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h
new file mode 100644
index 0000000..7cdf0d7
--- /dev/null
+++ b/include/llvm-c/ExecutionEngine.h
@@ -0,0 +1,214 @@
+/*===-- llvm-c/ExecutionEngine.h - ExecutionEngine Lib C Iface --*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMExecutionEngine.o, which    *|
+|* implements various analyses of the LLVM IR.                                *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_EXECUTIONENGINE_H
+#define LLVM_C_EXECUTIONENGINE_H
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCExecutionEngine Execution Engine
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+void LLVMLinkInJIT(void);
+void LLVMLinkInMCJIT(void);
+void LLVMLinkInInterpreter(void);
+
+typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
+typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
+typedef struct LLVMOpaqueMCJITMemoryManager *LLVMMCJITMemoryManagerRef;
+
+struct LLVMMCJITCompilerOptions {
+  unsigned OptLevel;
+  LLVMCodeModel CodeModel;
+  LLVMBool NoFramePointerElim;
+  LLVMBool EnableFastISel;
+  LLVMMCJITMemoryManagerRef MCJMM;
+};
+
+/*===-- Operations on generic values --------------------------------------===*/
+
+LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
+                                                unsigned long long N,
+                                                LLVMBool IsSigned);
+
+LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P);
+
+LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N);
+
+unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef);
+
+unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenVal,
+                                         LLVMBool IsSigned);
+
+void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal);
+
+double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal);
+
+void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
+
+/*===-- Operations on execution engines -----------------------------------===*/
+
+LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
+                                            LLVMModuleRef M,
+                                            char **OutError);
+
+LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
+                                        LLVMModuleRef M,
+                                        char **OutError);
+
+LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+                                        LLVMModuleRef M,
+                                        unsigned OptLevel,
+                                        char **OutError);
+
+void LLVMInitializeMCJITCompilerOptions(
+  struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions);
+
+/**
+ * Create an MCJIT execution engine for a module, with the given options. It is
+ * the responsibility of the caller to ensure that all fields in Options up to
+ * the given SizeOfOptions are initialized. It is correct to pass a smaller
+ * value of SizeOfOptions that omits some fields. The canonical way of using
+ * this is:
+ *
+ * LLVMMCJITCompilerOptions options;
+ * LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
+ * ... fill in those options you care about
+ * LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options),
+ *                                  &error);
+ *
+ * Note that this is also correct, though possibly suboptimal:
+ *
+ * LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error);
+ */
+LLVMBool LLVMCreateMCJITCompilerForModule(
+  LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
+  struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions,
+  char **OutError);
+
+/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */
+LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
+                                   LLVMModuleProviderRef MP,
+                                   char **OutError);
+
+/** Deprecated: Use LLVMCreateInterpreterForModule instead. */
+LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
+                               LLVMModuleProviderRef MP,
+                               char **OutError);
+
+/** Deprecated: Use LLVMCreateJITCompilerForModule instead. */
+LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
+                               LLVMModuleProviderRef MP,
+                               unsigned OptLevel,
+                               char **OutError);
+
+void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE);
+
+void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE);
+
+void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE);
+
+int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
+                          unsigned ArgC, const char * const *ArgV,
+                          const char * const *EnvP);
+
+LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
+                                    unsigned NumArgs,
+                                    LLVMGenericValueRef *Args);
+
+void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
+
+void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M);
+
+/** Deprecated: Use LLVMAddModule instead. */
+void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
+
+LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
+                          LLVMModuleRef *OutMod, char **OutError);
+
+/** Deprecated: Use LLVMRemoveModule instead. */
+LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
+                                  LLVMModuleProviderRef MP,
+                                  LLVMModuleRef *OutMod, char **OutError);
+
+LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
+                          LLVMValueRef *OutFn);
+
+void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
+                                     LLVMValueRef Fn);
+
+LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
+LLVMTargetMachineRef
+LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE);
+
+void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
+                          void* Addr);
+
+void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global);
+
+/*===-- Operations on memory managers -------------------------------------===*/
+
+typedef uint8_t *(*LLVMMemoryManagerAllocateCodeSectionCallback)(
+  void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID,
+  const char *SectionName);
+typedef uint8_t *(*LLVMMemoryManagerAllocateDataSectionCallback)(
+  void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID,
+  const char *SectionName, LLVMBool IsReadOnly);
+typedef LLVMBool (*LLVMMemoryManagerFinalizeMemoryCallback)(
+  void *Opaque, char **ErrMsg);
+typedef void (*LLVMMemoryManagerDestroyCallback)(void *Opaque);
+
+/**
+ * Create a simple custom MCJIT memory manager. This memory manager can
+ * intercept allocations in a module-oblivious way. This will return NULL
+ * if any of the passed functions are NULL.
+ *
+ * @param Opaque An opaque client object to pass back to the callbacks.
+ * @param AllocateCodeSection Allocate a block of memory for executable code.
+ * @param AllocateDataSection Allocate a block of memory for data.
+ * @param FinalizeMemory Set page permissions and flush cache. Return 0 on
+ *   success, 1 on error.
+ */
+LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
+  void *Opaque,
+  LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
+  LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
+  LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
+  LLVMMemoryManagerDestroyCallback Destroy);
+
+void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/include/llvm-c/IRReader.h b/include/llvm-c/IRReader.h
new file mode 100644
index 0000000..5001afb
--- /dev/null
+++ b/include/llvm-c/IRReader.h
@@ -0,0 +1,40 @@
+/*===-- llvm-c/IRReader.h - IR Reader C Interface -----------------*- 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 C interface to the IR Reader.                        *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_IRREADER_H
+#define LLVM_C_IRREADER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Read LLVM IR from a memory buffer and convert it into an in-memory Module
+ * object. Returns 0 on success.
+ * Optionally returns a human-readable description of any errors that
+ * occurred during parsing IR. OutMessage must be disposed with
+ * LLVMDisposeMessage.
+ *
+ * @see llvm::ParseIR()
+ */
+LLVMBool LLVMParseIRInContext(LLVMContextRef ContextRef,
+                              LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+                              char **OutMessage);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Initialization.h b/include/llvm-c/Initialization.h
new file mode 100644
index 0000000..ada4738
--- /dev/null
+++ b/include/llvm-c/Initialization.h
@@ -0,0 +1,55 @@
+/*===-- llvm-c/Initialization.h - Initialization C Interface ------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to LLVM initialization routines,      *|
+|* which must be called before you can use the functionality provided by      *|
+|* the corresponding LLVM library.                                            *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_INITIALIZEPASSES_H
+#define LLVM_C_INITIALIZEPASSES_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCInitialization Initialization Routines
+ * @ingroup LLVMC
+ *
+ * This module contains routines used to initialize the LLVM system.
+ *
+ * @{
+ */
+
+void LLVMInitializeCore(LLVMPassRegistryRef R);
+void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
+void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
+void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R);
+void LLVMInitializeVectorization(LLVMPassRegistryRef R);
+void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
+void LLVMInitializeIPO(LLVMPassRegistryRef R);
+void LLVMInitializeInstrumentation(LLVMPassRegistryRef R);
+void LLVMInitializeAnalysis(LLVMPassRegistryRef R);
+void LLVMInitializeIPA(LLVMPassRegistryRef R);
+void LLVMInitializeCodeGen(LLVMPassRegistryRef R);
+void LLVMInitializeTarget(LLVMPassRegistryRef R);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/LinkTimeOptimizer.h b/include/llvm-c/LinkTimeOptimizer.h
new file mode 100644
index 0000000..8bcf599
--- /dev/null
+++ b/include/llvm-c/LinkTimeOptimizer.h
@@ -0,0 +1,69 @@
+//===-- llvm/LinkTimeOptimizer.h - LTO Public C Interface -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header provides a C API to use the LLVM link time optimization
+// library. This is intended to be used by linkers which are C-only in
+// their implementation for performing LTO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_C_LINKTIMEOPTIMIZER_H
+#define LLVM_C_LINKTIMEOPTIMIZER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCLinkTimeOptimizer Link Time Optimization
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+  /// This provides a dummy type for pointers to the LTO object.
+  typedef void* llvm_lto_t;
+
+  /// This provides a C-visible enumerator to manage status codes.
+  /// This should map exactly onto the C++ enumerator LTOStatus.
+  typedef enum llvm_lto_status {
+    LLVM_LTO_UNKNOWN,
+    LLVM_LTO_OPT_SUCCESS,
+    LLVM_LTO_READ_SUCCESS,
+    LLVM_LTO_READ_FAILURE,
+    LLVM_LTO_WRITE_FAILURE,
+    LLVM_LTO_NO_TARGET,
+    LLVM_LTO_NO_WORK,
+    LLVM_LTO_MODULE_MERGE_FAILURE,
+    LLVM_LTO_ASM_FAILURE,
+
+    //  Added C-specific error codes
+    LLVM_LTO_NULL_OBJECT
+  } llvm_lto_status_t;
+
+  /// This provides C interface to initialize link time optimizer. This allows
+  /// linker to use dlopen() interface to dynamically load LinkTimeOptimizer.
+  /// extern "C" helps, because dlopen() interface uses name to find the symbol.
+  extern llvm_lto_t llvm_create_optimizer(void);
+  extern void llvm_destroy_optimizer(llvm_lto_t lto);
+
+  extern llvm_lto_status_t llvm_read_object_file
+    (llvm_lto_t lto, const char* input_filename);
+  extern llvm_lto_status_t llvm_optimize_modules
+    (llvm_lto_t lto, const char* output_filename);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Linker.h b/include/llvm-c/Linker.h
new file mode 100644
index 0000000..9f337cf
--- /dev/null
+++ b/include/llvm-c/Linker.h
@@ -0,0 +1,42 @@
+/*===-- llvm-c/Linker.h - Module Linker C Interface -------------*- 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 C interface to the module/file/archive linker.       *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_LINKER_H
+#define LLVM_C_LINKER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum {
+  LLVMLinkerDestroySource = 0, /* Allow source module to be destroyed. */
+  LLVMLinkerPreserveSource = 1 /* Preserve the source module. */
+} LLVMLinkerMode;
+
+
+/* Links the source module into the destination module, taking ownership
+ * of the source module away from the caller. Optionally returns a
+ * human-readable description of any errors that occurred in linking.
+ * OutMessage must be disposed with LLVMDisposeMessage. The return value
+ * is true if an error occurred, false otherwise. */
+LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
+                         LLVMLinkerMode Mode, char **OutMessage);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h
new file mode 100644
index 0000000..447fcea
--- /dev/null
+++ b/include/llvm-c/Object.h
@@ -0,0 +1,101 @@
+/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is distributed under the University of Illinois Open Source      */
+/* License. See LICENSE.TXT for details.                                      */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+/*                                                                            */
+/* This header declares the C interface to libLLVMObject.a, which             */
+/* implements object file reading and writing.                                */
+/*                                                                            */
+/* Many exotic languages can interoperate with C code but have a harder time  */
+/* with C++ due to name mangling. So in addition to C, this interface enables */
+/* tools written in such languages.                                           */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_OBJECT_H
+#define LLVM_C_OBJECT_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Config/llvm-config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCObject Object file reading and writing
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+// Opaque type wrappers
+typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
+typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
+typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef;
+typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef;
+
+// ObjectFile creation
+LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf);
+void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
+
+// ObjectFile Section iterators
+LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
+void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
+LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
+                                LLVMSectionIteratorRef SI);
+void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
+void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
+                                 LLVMSymbolIteratorRef Sym);
+
+// ObjectFile Symbol iterators
+LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile);
+void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI);
+LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
+                                LLVMSymbolIteratorRef SI);
+void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI);
+
+// SectionRef accessors
+const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
+uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
+const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
+uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI);
+LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
+                                 LLVMSymbolIteratorRef Sym);
+
+// Section Relocation iterators
+LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section);
+void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef RI);
+LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
+                                       LLVMRelocationIteratorRef RI);
+void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef RI);
+
+
+// SymbolRef accessors
+const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI);
+uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI);
+uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI);
+
+// RelocationRef accessors
+uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI);
+uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI);
+LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI);
+uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI);
+// NOTE: Caller takes ownership of returned string of the two
+// following functions.
+const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI);
+const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/include/llvm-c/Support.h b/include/llvm-c/Support.h
new file mode 100644
index 0000000..4e6ff22
--- /dev/null
+++ b/include/llvm-c/Support.h
@@ -0,0 +1,54 @@
+/*===-- llvm-c/Support.h - Support C Interface --------------------*- 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 C interface to the LLVM support library.             *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_SUPPORT_H
+#define LLVM_C_SUPPORT_H
+
+#include "llvm/Support/DataTypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCSupportTypes Types and Enumerations
+ *
+ * @{
+ */
+
+typedef int LLVMBool;
+
+/**
+ * Used to pass regions of memory through LLVM interfaces.
+ *
+ * @see llvm::MemoryBuffer
+ */
+typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
+
+/**
+ * @}
+ */
+
+/**
+ * This function permanently loads the dynamic library at the given path.
+ * It is safe to call this function multiple times for the same library.
+ *
+ * @see sys::DynamicLibrary::LoadLibraryPermanently()
+  */
+LLVMBool LLVMLoadLibraryPermanently(const char* Filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h
new file mode 100644
index 0000000..b465b4b
--- /dev/null
+++ b/include/llvm-c/Target.h
@@ -0,0 +1,290 @@
+/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is distributed under the University of Illinois Open Source      */
+/* License. See LICENSE.TXT for details.                                      */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+/*                                                                            */
+/* This header declares the C interface to libLLVMTarget.a, which             */
+/* implements target information.                                             */
+/*                                                                            */
+/* Many exotic languages can interoperate with C code but have a harder time  */
+/* with C++ due to name mangling. So in addition to C, this interface enables */
+/* tools written in such languages.                                           */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TARGET_H
+#define LLVM_C_TARGET_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Config/llvm-config.h"
+
+#if defined(_MSC_VER) && !defined(inline)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTarget Target information
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
+
+typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
+typedef struct LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef;
+
+/* Declare all of the target-initialization functions that are available. */
+#define LLVM_TARGET(TargetName) \
+  void LLVMInitialize##TargetName##TargetInfo(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+
+#define LLVM_TARGET(TargetName) \
+  void LLVMInitialize##TargetName##TargetMC(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available assembly printer initialization functions. */
+#define LLVM_ASM_PRINTER(TargetName) \
+  void LLVMInitialize##TargetName##AsmPrinter(void);
+#include "llvm/Config/AsmPrinters.def"
+#undef LLVM_ASM_PRINTER  /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available assembly parser initialization functions. */
+#define LLVM_ASM_PARSER(TargetName) \
+  void LLVMInitialize##TargetName##AsmParser(void);
+#include "llvm/Config/AsmParsers.def"
+#undef LLVM_ASM_PARSER  /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available disassembler initialization functions. */
+#define LLVM_DISASSEMBLER(TargetName) \
+  void LLVMInitialize##TargetName##Disassembler(void);
+#include "llvm/Config/Disassemblers.def"
+#undef LLVM_DISASSEMBLER  /* Explicit undef to make SWIG happier */
+
+/** LLVMInitializeAllTargetInfos - The main program should call this function if
+    it wants access to all available targets that LLVM is configured to
+    support. */
+static inline void LLVMInitializeAllTargetInfos(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllTargets - The main program should call this function if it
+    wants to link in all available targets that LLVM is configured to
+    support. */
+static inline void LLVMInitializeAllTargets(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllTargetMCs - The main program should call this function if
+    it wants access to all available target MC that LLVM is configured to
+    support. */
+static inline void LLVMInitializeAllTargetMCs(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllAsmPrinters - The main program should call this function if
+    it wants all asm printers that LLVM is configured to support, to make them
+    available via the TargetRegistry. */
+static inline void LLVMInitializeAllAsmPrinters(void) {
+#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+#undef LLVM_ASM_PRINTER  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllAsmParsers - The main program should call this function if
+    it wants all asm parsers that LLVM is configured to support, to make them
+    available via the TargetRegistry. */
+static inline void LLVMInitializeAllAsmParsers(void) {
+#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+#undef LLVM_ASM_PARSER  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllDisassemblers - The main program should call this function
+    if it wants all disassemblers that LLVM is configured to support, to make
+    them available via the TargetRegistry. */
+static inline void LLVMInitializeAllDisassemblers(void) {
+#define LLVM_DISASSEMBLER(TargetName) \
+  LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+#undef LLVM_DISASSEMBLER  /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeNativeTarget - The main program should call this function to
+    initialize the native target corresponding to the host.  This is useful
+    for JIT applications to ensure that the target gets linked in correctly. */
+static inline LLVMBool LLVMInitializeNativeTarget(void) {
+  /* If we have a native target, initialize it to ensure it is linked in. */
+#ifdef LLVM_NATIVE_TARGET
+  LLVM_NATIVE_TARGETINFO();
+  LLVM_NATIVE_TARGET();
+  LLVM_NATIVE_TARGETMC();
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+/** LLVMInitializeNativeTargetAsmParser - The main program should call this
+    function to initialize the parser for the native target corresponding to the
+    host. */
+static inline LLVMBool LLVMInitializeNativeAsmParser(void) {
+#ifdef LLVM_NATIVE_ASMPARSER
+  LLVM_NATIVE_ASMPARSER();
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+/** LLVMInitializeNativeTargetAsmPrinter - The main program should call this
+    function to initialize the printer for the native target corresponding to
+    the host. */
+static inline LLVMBool LLVMInitializeNativeAsmPrinter(void) {
+#ifdef LLVM_NATIVE_ASMPRINTER
+  LLVM_NATIVE_ASMPRINTER();
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+/** LLVMInitializeNativeTargetDisassembler - The main program should call this
+    function to initialize the disassembler for the native target corresponding
+    to the host. */
+static inline LLVMBool LLVMInitializeNativeDisassembler(void) {
+#ifdef LLVM_NATIVE_DISASSEMBLER
+  LLVM_NATIVE_DISASSEMBLER();
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+/*===-- Target Data -------------------------------------------------------===*/
+
+/** Creates target data from a target layout string.
+    See the constructor llvm::DataLayout::DataLayout. */
+LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
+
+/** Adds target data information to a pass manager. This does not take ownership
+    of the target data.
+    See the method llvm::PassManagerBase::add. */
+void LLVMAddTargetData(LLVMTargetDataRef TD, LLVMPassManagerRef PM);
+
+/** Adds target library information to a pass manager. This does not take
+    ownership of the target library info.
+    See the method llvm::PassManagerBase::add. */
+void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef TLI,
+                              LLVMPassManagerRef PM);
+
+/** Converts target data to a target layout string. The string must be disposed
+    with LLVMDisposeMessage.
+    See the constructor llvm::DataLayout::DataLayout. */
+char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef TD);
+
+/** Returns the byte order of a target, either LLVMBigEndian or
+    LLVMLittleEndian.
+    See the method llvm::DataLayout::isLittleEndian. */
+enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef TD);
+
+/** Returns the pointer size in bytes for a target.
+    See the method llvm::DataLayout::getPointerSize. */
+unsigned LLVMPointerSize(LLVMTargetDataRef TD);
+
+/** Returns the pointer size in bytes for a target for a specified
+    address space.
+    See the method llvm::DataLayout::getPointerSize. */
+unsigned LLVMPointerSizeForAS(LLVMTargetDataRef TD, unsigned AS);
+
+/** Returns the integer type that is the same size as a pointer on a target.
+    See the method llvm::DataLayout::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef TD);
+
+/** Returns the integer type that is the same size as a pointer on a target.
+    This version allows the address space to be specified.
+    See the method llvm::DataLayout::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef TD, unsigned AS);
+
+/** Returns the integer type that is the same size as a pointer on a target.
+    See the method llvm::DataLayout::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrTypeInContext(LLVMContextRef C, LLVMTargetDataRef TD);
+
+/** Returns the integer type that is the same size as a pointer on a target.
+    This version allows the address space to be specified.
+    See the method llvm::DataLayout::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrTypeForASInContext(LLVMContextRef C, LLVMTargetDataRef TD,
+                                         unsigned AS);
+
+/** Computes the size of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeSizeInBits. */
+unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the storage size of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeStoreSize. */
+unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the ABI size of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeAllocSize. */
+unsigned long long LLVMABISizeOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the ABI alignment of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeABISize. */
+unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the call frame alignment of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeABISize. */
+unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the preferred alignment of a type in bytes for a target.
+    See the method llvm::DataLayout::getTypeABISize. */
+unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty);
+
+/** Computes the preferred alignment of a global variable in bytes for a target.
+    See the method llvm::DataLayout::getPreferredAlignment. */
+unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef TD,
+                                        LLVMValueRef GlobalVar);
+
+/** Computes the structure element that contains the byte offset for a target.
+    See the method llvm::StructLayout::getElementContainingOffset. */
+unsigned LLVMElementAtOffset(LLVMTargetDataRef TD, LLVMTypeRef StructTy,
+                             unsigned long long Offset);
+
+/** Computes the byte offset of the indexed struct element for a target.
+    See the method llvm::StructLayout::getElementContainingOffset. */
+unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef TD,
+                                       LLVMTypeRef StructTy, unsigned Element);
+
+/** Deallocates a TargetData.
+    See the destructor llvm::DataLayout::~DataLayout. */
+void LLVMDisposeTargetData(LLVMTargetDataRef TD);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h
new file mode 100644
index 0000000..d4993e7
--- /dev/null
+++ b/include/llvm-c/TargetMachine.h
@@ -0,0 +1,147 @@
+/*===-- llvm-c/TargetMachine.h - Target Machine Library C Interface - C++ -*-=*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to the Target and TargetMachine       *|
+|* classes, which can be used to generate assembly or object files.           *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TARGETMACHINE_H
+#define LLVM_C_TARGETMACHINE_H
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Target.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
+typedef struct LLVMTarget *LLVMTargetRef;
+
+typedef enum {
+    LLVMCodeGenLevelNone,
+    LLVMCodeGenLevelLess,
+    LLVMCodeGenLevelDefault,
+    LLVMCodeGenLevelAggressive
+} LLVMCodeGenOptLevel;
+
+typedef enum {
+    LLVMRelocDefault,
+    LLVMRelocStatic,
+    LLVMRelocPIC,
+    LLVMRelocDynamicNoPic
+} LLVMRelocMode;
+
+typedef enum {
+    LLVMCodeModelDefault,
+    LLVMCodeModelJITDefault,
+    LLVMCodeModelSmall,
+    LLVMCodeModelKernel,
+    LLVMCodeModelMedium,
+    LLVMCodeModelLarge
+} LLVMCodeModel;
+
+typedef enum {
+    LLVMAssemblyFile,
+    LLVMObjectFile
+} LLVMCodeGenFileType;
+
+/** Returns the first llvm::Target in the registered targets list. */
+LLVMTargetRef LLVMGetFirstTarget(void);
+/** Returns the next llvm::Target given a previous one (or null if there's none) */
+LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
+
+/*===-- Target ------------------------------------------------------------===*/
+/** Finds the target corresponding to the given name and stores it in \p T.
+  Returns 0 on success. */
+LLVMTargetRef LLVMGetTargetFromName(const char *Name);
+
+/** Finds the target corresponding to the given triple and stores it in \p T.
+  Returns 0 on success. Optionally returns any error in ErrorMessage.
+  Use LLVMDisposeMessage to dispose the message. */
+LLVMBool LLVMGetTargetFromTriple(const char* Triple, LLVMTargetRef *T,
+                                 char **ErrorMessage);
+
+/** Returns the name of a target. See llvm::Target::getName */
+const char *LLVMGetTargetName(LLVMTargetRef T);
+
+/** Returns the description  of a target. See llvm::Target::getDescription */
+const char *LLVMGetTargetDescription(LLVMTargetRef T);
+
+/** Returns if the target has a JIT */
+LLVMBool LLVMTargetHasJIT(LLVMTargetRef T);
+
+/** Returns if the target has a TargetMachine associated */
+LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T);
+
+/** Returns if the target as an ASM backend (required for emitting output) */
+LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T);
+
+/*===-- Target Machine ----------------------------------------------------===*/
+/** Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine */
+LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
+  const char *Triple, const char *CPU, const char *Features,
+  LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, LLVMCodeModel CodeModel);
+
+/** Dispose the LLVMTargetMachineRef instance generated by
+  LLVMCreateTargetMachine. */
+void LLVMDisposeTargetMachine(LLVMTargetMachineRef T);
+
+/** Returns the Target used in a TargetMachine */
+LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T);
+
+/** Returns the triple used creating this target machine. See
+  llvm::TargetMachine::getTriple. The result needs to be disposed with
+  LLVMDisposeMessage. */
+char *LLVMGetTargetMachineTriple(LLVMTargetMachineRef T);
+
+/** Returns the cpu used creating this target machine. See
+  llvm::TargetMachine::getCPU. The result needs to be disposed with
+  LLVMDisposeMessage. */
+char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
+
+/** Returns the feature string used creating this target machine. See
+  llvm::TargetMachine::getFeatureString. The result needs to be disposed with
+  LLVMDisposeMessage. */
+char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
+
+/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */
+LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
+
+/** Set the target machine's ASM verbosity. */
+void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
+                                      LLVMBool VerboseAsm);
+
+/** Emits an asm or object file for the given module to the filename. This
+  wraps several c++ only classes (among them a file stream). Returns any
+  error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
+LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
+  char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
+
+/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */
+LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
+  LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);
+
+/*===-- Triple ------------------------------------------------------------===*/
+/** Get a triple for the host machine as a string. The result needs to be
+  disposed with LLVMDisposeMessage. */
+char* LLVMGetDefaultTargetTriple(void);
+
+/** Adds the target-specific analysis passes to the pass manager. */
+void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Transforms/IPO.h b/include/llvm-c/Transforms/IPO.h
new file mode 100644
index 0000000..4480780
--- /dev/null
+++ b/include/llvm-c/Transforms/IPO.h
@@ -0,0 +1,81 @@
+/*===-- IPO.h - Interprocedural Transformations C Interface -----*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMIPO.a, which implements     *|
+|* various interprocedural transformations of the LLVM IR.                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_IPO_H
+#define LLVM_C_TRANSFORMS_IPO_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsIPO Interprocedural transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createArgumentPromotionPass function. */
+void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM);
+
+/** See llvm::createConstantMergePass function. */
+void LLVMAddConstantMergePass(LLVMPassManagerRef PM);
+
+/** See llvm::createDeadArgEliminationPass function. */
+void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createFunctionAttrsPass function. */
+void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);
+
+/** See llvm::createFunctionInliningPass function. */
+void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM);
+
+/** See llvm::createAlwaysInlinerPass function. */
+void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGlobalDCEPass function. */
+void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGlobalOptimizerPass function. */
+void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIPConstantPropagationPass function. */
+void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createPruneEHPass function. */
+void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIPSCCPPass function. */
+void LLVMAddIPSCCPPass(LLVMPassManagerRef PM);
+
+/** See llvm::createInternalizePass function. */
+void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain);
+
+/** See llvm::createStripDeadPrototypesPass function. */
+void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM);
+
+/** See llvm::createStripSymbolsPass function. */
+void LLVMAddStripSymbolsPass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/include/llvm-c/Transforms/PassManagerBuilder.h b/include/llvm-c/Transforms/PassManagerBuilder.h
new file mode 100644
index 0000000..3d7a9d6
--- /dev/null
+++ b/include/llvm-c/Transforms/PassManagerBuilder.h
@@ -0,0 +1,90 @@
+/*===-- llvm-c/Transform/PassManagerBuilder.h - PMB C Interface ---*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to the PassManagerBuilder class.      *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
+#define LLVM_C_TRANSFORMS_PASSMANAGERBUILDER_H
+
+#include "llvm-c/Core.h"
+
+typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsPassManagerBuilder Pass manager builder
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::PassManagerBuilder. */
+LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void);
+void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB);
+
+/** See llvm::PassManagerBuilder::OptLevel. */
+void
+LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
+                                  unsigned OptLevel);
+
+/** See llvm::PassManagerBuilder::SizeLevel. */
+void
+LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
+                                   unsigned SizeLevel);
+
+/** See llvm::PassManagerBuilder::DisableUnitAtATime. */
+void
+LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
+                                            LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::DisableUnrollLoops. */
+void
+LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
+                                            LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::DisableSimplifyLibCalls */
+void
+LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
+                                                 LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::Inliner. */
+void
+LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
+                                              unsigned Threshold);
+
+/** See llvm::PassManagerBuilder::populateFunctionPassManager. */
+void
+LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
+                                                  LLVMPassManagerRef PM);
+
+/** See llvm::PassManagerBuilder::populateModulePassManager. */
+void
+LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
+                                                LLVMPassManagerRef PM);
+
+/** See llvm::PassManagerBuilder::populateLTOPassManager. */
+void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
+                                                  LLVMPassManagerRef PM,
+                                                  LLVMBool Internalize,
+                                                  LLVMBool RunInliner);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h
new file mode 100644
index 0000000..0ca72ce
--- /dev/null
+++ b/include/llvm-c/Transforms/Scalar.h
@@ -0,0 +1,146 @@
+/*===-- Scalar.h - Scalar Transformation Library C Interface ----*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMScalarOpts.a, which         *|
+|* implements various scalar transformations of the LLVM IR.                  *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_SCALAR_H
+#define LLVM_C_TRANSFORMS_SCALAR_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsScalar Scalar transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createAggressiveDCEPass function. */
+void LLVMAddAggressiveDCEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createCFGSimplificationPass function. */
+void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createDeadStoreEliminationPass function. */
+void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarizerPass function. */
+void LLVMAddScalarizerPass(LLVMPassManagerRef PM);
+
+/** See llvm::createMergedLoadStoreMotionPass function. */
+void LLVMAddMergedLoadStoreMotionPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGVNPass function. */
+void LLVMAddGVNPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIndVarSimplifyPass function. */
+void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef PM);
+
+/** See llvm::createInstructionCombiningPass function. */
+void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM);
+
+/** See llvm::createJumpThreadingPass function. */
+void LLVMAddJumpThreadingPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLICMPass function. */
+void LLVMAddLICMPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopDeletionPass function. */
+void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopIdiomPass function */
+void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopRotatePass function. */
+void LLVMAddLoopRotatePass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopRerollPass function. */
+void LLVMAddLoopRerollPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopUnrollPass function. */
+void LLVMAddLoopUnrollPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopUnswitchPass function. */
+void LLVMAddLoopUnswitchPass(LLVMPassManagerRef PM);
+
+/** See llvm::createMemCpyOptPass function. */
+void LLVMAddMemCpyOptPass(LLVMPassManagerRef PM);
+
+/** See llvm::createPartiallyInlineLibCallsPass function. */
+void LLVMAddPartiallyInlineLibCallsPass(LLVMPassManagerRef PM);
+
+/** See llvm::createPromoteMemoryToRegisterPass function. */
+void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
+
+/** See llvm::createReassociatePass function. */
+void LLVMAddReassociatePass(LLVMPassManagerRef PM);
+
+/** See llvm::createSCCPPass function. */
+void LLVMAddSCCPPass(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPassSSA(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM,
+                                                  int Threshold);
+
+/** See llvm::createSimplifyLibCallsPass function. */
+void LLVMAddSimplifyLibCallsPass(LLVMPassManagerRef PM);
+
+/** See llvm::createTailCallEliminationPass function. */
+void LLVMAddTailCallEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createConstantPropagationPass function. */
+void LLVMAddConstantPropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::demotePromoteMemoryToRegisterPass function. */
+void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef PM);
+
+/** See llvm::createVerifierPass function. */
+void LLVMAddVerifierPass(LLVMPassManagerRef PM);
+
+/** See llvm::createCorrelatedValuePropagationPass function */
+void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createEarlyCSEPass function */
+void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLowerExpectIntrinsicPass function */
+void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM);
+
+/** See llvm::createTypeBasedAliasAnalysisPass function */
+void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
+
+/** See llvm::createBasicAliasAnalysisPass function */
+void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/include/llvm-c/Transforms/Vectorize.h b/include/llvm-c/Transforms/Vectorize.h
new file mode 100644
index 0000000..c9102da
--- /dev/null
+++ b/include/llvm-c/Transforms/Vectorize.h
@@ -0,0 +1,54 @@
+/*===---------------------------Vectorize.h --------------------- -*- C -*-===*\
+|*===----------- Vectorization Transformation Library C Interface ---------===*|
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header declares the C interface to libLLVMVectorize.a, which          *|
+|* implements various vectorization transformations of the LLVM IR.           *|
+|*                                                                            *|
+|* Many exotic languages can interoperate with C code but have a harder time  *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages.                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_VECTORIZE_H
+#define LLVM_C_TRANSFORMS_VECTORIZE_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsVectorize Vectorization transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createBBVectorizePass function. */
+void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopVectorizePass function. */
+void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
+
+/** See llvm::createSLPVectorizerPass function. */
+void LLVMAddSLPVectorizePass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
+
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
new file mode 100644
index 0000000..c525710
--- /dev/null
+++ b/include/llvm-c/lto.h
@@ -0,0 +1,465 @@
+/*===-- llvm-c/lto.h - LTO Public C Interface ---------------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides public interface to an abstract link time optimization*|
+|* library.  LLVM provides an implementation of this interface for use with   *|
+|* llvm bitcode files.                                                        *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_LTO_H
+#define LLVM_C_LTO_H
+
+#include <stddef.h>
+#include <sys/types.h>
+
+#ifndef __cplusplus
+#if !defined(_MSC_VER)
+#include <stdbool.h>
+typedef bool lto_bool_t;
+#else
+/* MSVC in particular does not have anything like _Bool or bool in C, but we can
+   at least make sure the type is the same size.  The implementation side will
+   use C++ bool. */
+typedef unsigned char lto_bool_t;
+#endif
+#else
+typedef bool lto_bool_t;
+#endif
+
+/**
+ * @defgroup LLVMCLTO LTO
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+#define LTO_API_VERSION 10
+
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
+typedef enum {
+    LTO_SYMBOL_ALIGNMENT_MASK              = 0x0000001F, /* log2 of alignment */
+    LTO_SYMBOL_PERMISSIONS_MASK            = 0x000000E0,
+    LTO_SYMBOL_PERMISSIONS_CODE            = 0x000000A0,
+    LTO_SYMBOL_PERMISSIONS_DATA            = 0x000000C0,
+    LTO_SYMBOL_PERMISSIONS_RODATA          = 0x00000080,
+    LTO_SYMBOL_DEFINITION_MASK             = 0x00000700,
+    LTO_SYMBOL_DEFINITION_REGULAR          = 0x00000100,
+    LTO_SYMBOL_DEFINITION_TENTATIVE        = 0x00000200,
+    LTO_SYMBOL_DEFINITION_WEAK             = 0x00000300,
+    LTO_SYMBOL_DEFINITION_UNDEFINED        = 0x00000400,
+    LTO_SYMBOL_DEFINITION_WEAKUNDEF        = 0x00000500,
+    LTO_SYMBOL_SCOPE_MASK                  = 0x00003800,
+    LTO_SYMBOL_SCOPE_INTERNAL              = 0x00000800,
+    LTO_SYMBOL_SCOPE_HIDDEN                = 0x00001000,
+    LTO_SYMBOL_SCOPE_PROTECTED             = 0x00002000,
+    LTO_SYMBOL_SCOPE_DEFAULT               = 0x00001800,
+    LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800
+} lto_symbol_attributes;
+
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
+typedef enum {
+    LTO_DEBUG_MODEL_NONE         = 0,
+    LTO_DEBUG_MODEL_DWARF        = 1
+} lto_debug_model;
+
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
+typedef enum {
+    LTO_CODEGEN_PIC_MODEL_STATIC         = 0,
+    LTO_CODEGEN_PIC_MODEL_DYNAMIC        = 1,
+    LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC = 2,
+    LTO_CODEGEN_PIC_MODEL_DEFAULT        = 3
+} lto_codegen_model;
+
+/** opaque reference to a loaded object module */
+typedef struct LLVMOpaqueLTOModule *lto_module_t;
+
+/** opaque reference to a code generator */
+typedef struct LLVMOpaqueLTOCodeGenerator *lto_code_gen_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns a printable string.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern const char*
+lto_get_version(void);
+
+
+/**
+ * Returns the last error string or NULL if last operation was successful.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern const char*
+lto_get_error_message(void);
+
+/**
+ * Checks if a file is a loadable object file.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_module_is_object_file(const char* path);
+
+
+/**
+ * Checks if a file is a loadable object compiled for requested target.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_module_is_object_file_for_target(const char* path,
+                                     const char* target_triple_prefix);
+
+
+/**
+ * Checks if a buffer is a loadable object file.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_module_is_object_file_in_memory(const void* mem, size_t length);
+
+
+/**
+ * Checks if a buffer is a loadable object compiled for requested target.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
+                                              const char* target_triple_prefix);
+
+
+/**
+ * Loads an object file from disk.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_module_t
+lto_module_create(const char* path);
+
+
+/**
+ * Loads an object file from memory.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_module_t
+lto_module_create_from_memory(const void* mem, size_t length);
+
+/**
+ * Loads an object file from memory with an extra path argument.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=9
+ */
+extern lto_module_t
+lto_module_create_from_memory_with_path(const void* mem, size_t length,
+                                        const char *path);
+
+/**
+ * Loads an object file from disk. The seek point of fd is not preserved.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=5
+ */
+extern lto_module_t
+lto_module_create_from_fd(int fd, const char *path, size_t file_size);
+
+/**
+ * Loads an object file from disk. The seek point of fd is not preserved.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=5
+ */
+extern lto_module_t
+lto_module_create_from_fd_at_offset(int fd, const char *path, size_t file_size,
+                                    size_t map_size, off_t offset);
+
+/**
+ * Frees all memory internally allocated by the module.
+ * Upon return the lto_module_t is no longer valid.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern void
+lto_module_dispose(lto_module_t mod);
+
+/**
+ * Returns triple string which the object module was compiled under.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern const char*
+lto_module_get_target_triple(lto_module_t mod);
+
+/**
+ * Sets triple string with which the object will be codegened.
+ *
+ * \since LTO_API_VERSION=4
+ */
+extern void
+lto_module_set_target_triple(lto_module_t mod, const char *triple);
+
+
+/**
+ * Returns the number of symbols in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern unsigned int
+lto_module_get_num_symbols(lto_module_t mod);
+
+
+/**
+ * Returns the name of the ith symbol in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern const char*
+lto_module_get_symbol_name(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Returns the attributes of the ith symbol in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_symbol_attributes
+lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Returns the number of dependent libraries in the object module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern unsigned int
+lto_module_get_num_deplibs(lto_module_t mod);
+
+
+/**
+ * Returns the ith dependent library in the module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern const char*
+lto_module_get_deplib(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Returns the number of linker options in the object module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern unsigned int
+lto_module_get_num_linkeropts(lto_module_t mod);
+
+
+/**
+ * Returns the ith linker option in the module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern const char*
+lto_module_get_linkeropt(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Diagnostic severity.
+ *
+ * \since LTO_API_VERSION=7
+ */
+typedef enum {
+  LTO_DS_ERROR = 0,
+  LTO_DS_WARNING = 1,
+  LTO_DS_REMARK = 3, // Added in LTO_API_VERSION=10.
+  LTO_DS_NOTE = 2
+} lto_codegen_diagnostic_severity_t;
+
+/**
+ * Diagnostic handler type.
+ * \p severity defines the severity.
+ * \p diag is the actual diagnostic.
+ * The diagnostic is not prefixed by any of severity keyword, e.g., 'error: '.
+ * \p ctxt is used to pass the context set with the diagnostic handler.
+ *
+ * \since LTO_API_VERSION=7
+ */
+typedef void (*lto_diagnostic_handler_t)(
+    lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt);
+
+/**
+ * Set a diagnostic handler and the related context (void *).
+ * This is more general than lto_get_error_message, as the diagnostic handler
+ * can be called at anytime within lto.
+ *
+ * \since LTO_API_VERSION=7
+ */
+extern void lto_codegen_set_diagnostic_handler(lto_code_gen_t,
+                                               lto_diagnostic_handler_t,
+                                               void *);
+
+/**
+ * Instantiates a code generator.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_code_gen_t
+lto_codegen_create(void);
+
+/**
+ * Frees all code generator and all memory it internally allocated.
+ * Upon return the lto_code_gen_t is no longer valid.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern void
+lto_codegen_dispose(lto_code_gen_t);
+
+/**
+ * Add an object module to the set of modules for which code will be generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod);
+
+/**
+ * Sets if debug info should be generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model);
+
+
+/**
+ * Sets which PIC code model to generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern lto_bool_t
+lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);
+
+
+/**
+ * Sets the cpu to generate code for.
+ *
+ * \since LTO_API_VERSION=4
+ */
+extern void
+lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu);
+
+
+/**
+ * Sets the location of the assembler tool to run. If not set, libLTO
+ * will use gcc to invoke the assembler.
+ *
+ * \since LTO_API_VERSION=3
+ */
+extern void
+lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path);
+
+/**
+ * Sets extra arguments that libLTO should pass to the assembler.
+ *
+ * \since LTO_API_VERSION=4
+ */
+extern void
+lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
+                               int nargs);
+
+/**
+ * Adds to a list of all global symbols that must exist in the final generated
+ * code. If a function is not listed there, it might be inlined into every usage
+ * and optimized away.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern void
+lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
+
+/**
+ * Writes a new object file at the specified path that contains the
+ * merged contents of all modules added so far.
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=5
+ */
+extern lto_bool_t
+lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
+
+/**
+ * Generates code for all added modules into one native object file.
+ * On success returns a pointer to a generated mach-o/ELF buffer and
+ * length set to the buffer size.  The buffer is owned by the
+ * lto_code_gen_t and will be freed when lto_codegen_dispose()
+ * is called, or lto_codegen_compile() is called again.
+ * On failure, returns NULL (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern const void*
+lto_codegen_compile(lto_code_gen_t cg, size_t* length);
+
+/**
+ * Generates code for all added modules into one native object file.
+ * The name of the file is written to name. Returns true on error.
+ *
+ * \since LTO_API_VERSION=5
+ */
+extern lto_bool_t
+lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
+
+
+/**
+ * Sets options to help debug codegen bugs.
+ *
+ * \since prior to LTO_API_VERSION=3
+ */
+extern void
+lto_codegen_debug_options(lto_code_gen_t cg, const char *);
+
+/**
+ * Initializes LLVM disassemblers.
+ * FIXME: This doesn't really belong here.
+ *
+ * \since LTO_API_VERSION=5
+ */
+extern void
+lto_initialize_disassembler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
new file mode 100644
index 0000000..50f1463
--- /dev/null
+++ b/include/llvm/ADT/APFloat.h
@@ -0,0 +1,583 @@
+//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief
+/// This file declares a class to represent arbitrary precision floating point
+/// values and provide a variety of arithmetic operations on them.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_APFLOAT_H
+#define LLVM_ADT_APFLOAT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+struct fltSemantics;
+class APSInt;
+class StringRef;
+
+/// Enum that represents what fraction of the LSB truncated bits of an fp number
+/// represent.
+///
+/// This essentially combines the roles of guard and sticky bits.
+enum lostFraction { // Example of truncated bits:
+  lfExactlyZero,    // 000000
+  lfLessThanHalf,   // 0xxxxx  x's not all zero
+  lfExactlyHalf,    // 100000
+  lfMoreThanHalf    // 1xxxxx  x's not all zero
+};
+
+/// \brief A self-contained host- and target-independent arbitrary-precision
+/// floating-point software implementation.
+///
+/// APFloat uses bignum integer arithmetic as provided by static functions in
+/// the APInt class.  The library will work with bignum integers whose parts are
+/// any unsigned type at least 16 bits wide, but 64 bits is recommended.
+///
+/// Written for clarity rather than speed, in particular with a view to use in
+/// the front-end of a cross compiler so that target arithmetic can be correctly
+/// performed on the host.  Performance should nonetheless be reasonable,
+/// particularly for its intended use.  It may be useful as a base
+/// implementation for a run-time library during development of a faster
+/// target-specific one.
+///
+/// All 5 rounding modes in the IEEE-754R draft are handled correctly for all
+/// implemented operations.  Currently implemented operations are add, subtract,
+/// multiply, divide, fused-multiply-add, conversion-to-float,
+/// conversion-to-integer and conversion-from-integer.  New rounding modes
+/// (e.g. away from zero) can be added with three or four lines of code.
+///
+/// Four formats are built-in: IEEE single precision, double precision,
+/// quadruple precision, and x87 80-bit extended double (when operating with
+/// full extended precision).  Adding a new format that obeys IEEE semantics
+/// only requires adding two lines of code: a declaration and definition of the
+/// format.
+///
+/// All operations return the status of that operation as an exception bit-mask,
+/// so multiple operations can be done consecutively with their results or-ed
+/// together.  The returned status can be useful for compiler diagnostics; e.g.,
+/// inexact, underflow and overflow can be easily diagnosed on constant folding,
+/// and compiler optimizers can determine what exceptions would be raised by
+/// folding operations and optimize, or perhaps not optimize, accordingly.
+///
+/// At present, underflow tininess is detected after rounding; it should be
+/// straight forward to add support for the before-rounding case too.
+///
+/// The library reads hexadecimal floating point numbers as per C99, and
+/// correctly rounds if necessary according to the specified rounding mode.
+/// Syntax is required to have been validated by the caller.  It also converts
+/// floating point numbers to hexadecimal text as per the C99 %a and %A
+/// conversions.  The output precision (or alternatively the natural minimal
+/// precision) can be specified; if the requested precision is less than the
+/// natural precision the output is correctly rounded for the specified rounding
+/// mode.
+///
+/// It also reads decimal floating point numbers and correctly rounds according
+/// to the specified rounding mode.
+///
+/// Conversion to decimal text is not currently implemented.
+///
+/// Non-zero finite numbers are represented internally as a sign bit, a 16-bit
+/// signed exponent, and the significand as an array of integer parts.  After
+/// normalization of a number of precision P the exponent is within the range of
+/// the format, and if the number is not denormal the P-th bit of the
+/// significand is set as an explicit integer bit.  For denormals the most
+/// significant bit is shifted right so that the exponent is maintained at the
+/// format's minimum, so that the smallest denormal has just the least
+/// significant bit of the significand set.  The sign of zeroes and infinities
+/// is significant; the exponent and significand of such numbers is not stored,
+/// but has a known implicit (deterministic) value: 0 for the significands, 0
+/// for zero exponent, all 1 bits for infinity exponent.  For NaNs the sign and
+/// significand are deterministic, although not really meaningful, and preserved
+/// in non-conversion operations.  The exponent is implicitly all 1 bits.
+///
+/// APFloat does not provide any exception handling beyond default exception
+/// handling. We represent Signaling NaNs via IEEE-754R 2008 6.2.1 should clause
+/// by encoding Signaling NaNs with the first bit of its trailing significand as
+/// 0.
+///
+/// TODO
+/// ====
+///
+/// Some features that may or may not be worth adding:
+///
+/// Binary to decimal conversion (hard).
+///
+/// Optional ability to detect underflow tininess before rounding.
+///
+/// New formats: x87 in single and double precision mode (IEEE apart from
+/// extended exponent range) (hard).
+///
+/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward.
+///
+class APFloat {
+public:
+
+  /// A signed type to represent a floating point numbers unbiased exponent.
+  typedef signed short ExponentType;
+
+  /// \name Floating Point Semantics.
+  /// @{
+
+  static const fltSemantics IEEEhalf;
+  static const fltSemantics IEEEsingle;
+  static const fltSemantics IEEEdouble;
+  static const fltSemantics IEEEquad;
+  static const fltSemantics PPCDoubleDouble;
+  static const fltSemantics x87DoubleExtended;
+
+  /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
+  /// anything real.
+  static const fltSemantics Bogus;
+
+  /// @}
+
+  static unsigned int semanticsPrecision(const fltSemantics &);
+
+  /// IEEE-754R 5.11: Floating Point Comparison Relations.
+  enum cmpResult {
+    cmpLessThan,
+    cmpEqual,
+    cmpGreaterThan,
+    cmpUnordered
+  };
+
+  /// IEEE-754R 4.3: Rounding-direction attributes.
+  enum roundingMode {
+    rmNearestTiesToEven,
+    rmTowardPositive,
+    rmTowardNegative,
+    rmTowardZero,
+    rmNearestTiesToAway
+  };
+
+  /// IEEE-754R 7: Default exception handling.
+  ///
+  /// opUnderflow or opOverflow are always returned or-ed with opInexact.
+  enum opStatus {
+    opOK = 0x00,
+    opInvalidOp = 0x01,
+    opDivByZero = 0x02,
+    opOverflow = 0x04,
+    opUnderflow = 0x08,
+    opInexact = 0x10
+  };
+
+  /// Category of internally-represented number.
+  enum fltCategory {
+    fcInfinity,
+    fcNaN,
+    fcNormal,
+    fcZero
+  };
+
+  /// Convenience enum used to construct an uninitialized APFloat.
+  enum uninitializedTag {
+    uninitialized
+  };
+
+  /// \name Constructors
+  /// @{
+
+  APFloat(const fltSemantics &); // Default construct to 0.0
+  APFloat(const fltSemantics &, StringRef);
+  APFloat(const fltSemantics &, integerPart);
+  APFloat(const fltSemantics &, uninitializedTag);
+  APFloat(const fltSemantics &, const APInt &);
+  explicit APFloat(double d);
+  explicit APFloat(float f);
+  APFloat(const APFloat &);
+  APFloat(APFloat &&);
+  ~APFloat();
+
+  /// @}
+
+  /// \brief Returns whether this instance allocated memory.
+  bool needsCleanup() const { return partCount() > 1; }
+
+  /// \name Convenience "constructors"
+  /// @{
+
+  /// Factory for Positive and Negative Zero.
+  ///
+  /// \param Negative True iff the number should be negative.
+  static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+    APFloat Val(Sem, uninitialized);
+    Val.makeZero(Negative);
+    return Val;
+  }
+
+  /// Factory for Positive and Negative Infinity.
+  ///
+  /// \param Negative True iff the number should be negative.
+  static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+    APFloat Val(Sem, uninitialized);
+    Val.makeInf(Negative);
+    return Val;
+  }
+
+  /// Factory for QNaN values.
+  ///
+  /// \param Negative - True iff the NaN generated should be negative.
+  /// \param type - The unspecified fill bits for creating the NaN, 0 by
+  /// default.  The value is truncated as necessary.
+  static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+                        unsigned type = 0) {
+    if (type) {
+      APInt fill(64, type);
+      return getQNaN(Sem, Negative, &fill);
+    } else {
+      return getQNaN(Sem, Negative, nullptr);
+    }
+  }
+
+  /// Factory for QNaN values.
+  static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
+                         const APInt *payload = nullptr) {
+    return makeNaN(Sem, false, Negative, payload);
+  }
+
+  /// Factory for SNaN values.
+  static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
+                         const APInt *payload = nullptr) {
+    return makeNaN(Sem, true, Negative, payload);
+  }
+
+  /// Returns the largest finite number in the given semantics.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static APFloat getLargest(const fltSemantics &Sem, bool Negative = false);
+
+  /// Returns the smallest (by magnitude) finite number in the given semantics.
+  /// Might be denormalized, which implies a relative loss of precision.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false);
+
+  /// Returns the smallest (by magnitude) normalized finite number in the given
+  /// semantics.
+  ///
+  /// \param Negative - True iff the number should be negative
+  static APFloat getSmallestNormalized(const fltSemantics &Sem,
+                                       bool Negative = false);
+
+  /// Returns a float which is bitcasted from an all one value int.
+  ///
+  /// \param BitWidth - Select float type
+  /// \param isIEEE   - If 128 bit number, select between PPC and IEEE
+  static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
+
+  /// @}
+
+  /// Used to insert APFloat objects, or objects that contain APFloat objects,
+  /// into FoldingSets.
+  void Profile(FoldingSetNodeID &NID) const;
+
+  /// \brief Used by the Bitcode serializer to emit APInts to Bitcode.
+  void Emit(Serializer &S) const;
+
+  /// \brief Used by the Bitcode deserializer to deserialize APInts.
+  static APFloat ReadVal(Deserializer &D);
+
+  /// \name Arithmetic
+  /// @{
+
+  opStatus add(const APFloat &, roundingMode);
+  opStatus subtract(const APFloat &, roundingMode);
+  opStatus multiply(const APFloat &, roundingMode);
+  opStatus divide(const APFloat &, roundingMode);
+  /// IEEE remainder.
+  opStatus remainder(const APFloat &);
+  /// C fmod, or llvm frem.
+  opStatus mod(const APFloat &, roundingMode);
+  opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
+  opStatus roundToIntegral(roundingMode);
+  /// IEEE-754R 5.3.1: nextUp/nextDown.
+  opStatus next(bool nextDown);
+
+  /// @}
+
+  /// \name Sign operations.
+  /// @{
+
+  void changeSign();
+  void clearSign();
+  void copySign(const APFloat &);
+
+  /// @}
+
+  /// \name Conversions
+  /// @{
+
+  opStatus convert(const fltSemantics &, roundingMode, bool *);
+  opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode,
+                            bool *) const;
+  opStatus convertToInteger(APSInt &, roundingMode, bool *) const;
+  opStatus convertFromAPInt(const APInt &, bool, roundingMode);
+  opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+                                          bool, roundingMode);
+  opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+                                          bool, roundingMode);
+  opStatus convertFromString(StringRef, roundingMode);
+  APInt bitcastToAPInt() const;
+  double convertToDouble() const;
+  float convertToFloat() const;
+
+  /// @}
+
+  /// The definition of equality is not straightforward for floating point, so
+  /// we won't use operator==.  Use one of the following, or write whatever it
+  /// is you really mean.
+  bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION;
+
+  /// IEEE comparison with another floating point number (NaNs compare
+  /// unordered, 0==-0).
+  cmpResult compare(const APFloat &) const;
+
+  /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
+  bool bitwiseIsEqual(const APFloat &) const;
+
+  /// Write out a hexadecimal representation of the floating point value to DST,
+  /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
+  /// Return the number of characters written, excluding the terminating NUL.
+  unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+                                  bool upperCase, roundingMode) const;
+
+  /// \name IEEE-754R 5.7.2 General operations.
+  /// @{
+
+  /// IEEE-754R isSignMinus: Returns true if and only if the current value is
+  /// negative.
+  ///
+  /// This applies to zeros and NaNs as well.
+  bool isNegative() const { return sign; }
+
+  /// IEEE-754R isNormal: Returns true if and only if the current value is normal.
+  ///
+  /// This implies that the current value of the float is not zero, subnormal,
+  /// infinite, or NaN following the definition of normality from IEEE-754R.
+  bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
+
+  /// Returns true if and only if the current value is zero, subnormal, or
+  /// normal.
+  ///
+  /// This means that the value is not infinite or NaN.
+  bool isFinite() const { return !isNaN() && !isInfinity(); }
+
+  /// Returns true if and only if the float is plus or minus zero.
+  bool isZero() const { return category == fcZero; }
+
+  /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
+  /// denormal.
+  bool isDenormal() const;
+
+  /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
+  bool isInfinity() const { return category == fcInfinity; }
+
+  /// Returns true if and only if the float is a quiet or signaling NaN.
+  bool isNaN() const { return category == fcNaN; }
+
+  /// Returns true if and only if the float is a signaling NaN.
+  bool isSignaling() const;
+
+  /// @}
+
+  /// \name Simple Queries
+  /// @{
+
+  fltCategory getCategory() const { return category; }
+  const fltSemantics &getSemantics() const { return *semantics; }
+  bool isNonZero() const { return category != fcZero; }
+  bool isFiniteNonZero() const { return isFinite() && !isZero(); }
+  bool isPosZero() const { return isZero() && !isNegative(); }
+  bool isNegZero() const { return isZero() && isNegative(); }
+
+  /// Returns true if and only if the number has the smallest possible non-zero
+  /// magnitude in the current semantics.
+  bool isSmallest() const;
+
+  /// Returns true if and only if the number has the largest possible finite
+  /// magnitude in the current semantics.
+  bool isLargest() const;
+
+  /// @}
+
+  APFloat &operator=(const APFloat &);
+  APFloat &operator=(APFloat &&);
+
+  /// \brief Overload to compute a hash code for an APFloat value.
+  ///
+  /// Note that the use of hash codes for floating point values is in general
+  /// frought with peril. Equality is hard to define for these values. For
+  /// example, should negative and positive zero hash to different codes? Are
+  /// they equal or not? This hash value implementation specifically
+  /// emphasizes producing different codes for different inputs in order to
+  /// be used in canonicalization and memoization. As such, equality is
+  /// bitwiseIsEqual, and 0 != -0.
+  friend hash_code hash_value(const APFloat &Arg);
+
+  /// Converts this value into a decimal string.
+  ///
+  /// \param FormatPrecision The maximum number of digits of
+  ///   precision to output.  If there are fewer digits available,
+  ///   zero padding will not be used unless the value is
+  ///   integral and small enough to be expressed in
+  ///   FormatPrecision digits.  0 means to use the natural
+  ///   precision of the number.
+  /// \param FormatMaxPadding The maximum number of zeros to
+  ///   consider inserting before falling back to scientific
+  ///   notation.  0 means to always use scientific notation.
+  ///
+  /// Number       Precision    MaxPadding      Result
+  /// ------       ---------    ----------      ------
+  /// 1.01E+4              5             2       10100
+  /// 1.01E+4              4             2       1.01E+4
+  /// 1.01E+4              5             1       1.01E+4
+  /// 1.01E-2              5             2       0.0101
+  /// 1.01E-2              4             2       0.0101
+  /// 1.01E-2              4             1       1.01E-2
+  void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
+                unsigned FormatMaxPadding = 3) const;
+
+  /// If this value has an exact multiplicative inverse, store it in inv and
+  /// return true.
+  bool getExactInverse(APFloat *inv) const;
+
+private:
+
+  /// \name Simple Queries
+  /// @{
+
+  integerPart *significandParts();
+  const integerPart *significandParts() const;
+  unsigned int partCount() const;
+
+  /// @}
+
+  /// \name Significand operations.
+  /// @{
+
+  integerPart addSignificand(const APFloat &);
+  integerPart subtractSignificand(const APFloat &, integerPart);
+  lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
+  lostFraction multiplySignificand(const APFloat &, const APFloat *);
+  lostFraction divideSignificand(const APFloat &);
+  void incrementSignificand();
+  void initialize(const fltSemantics *);
+  void shiftSignificandLeft(unsigned int);
+  lostFraction shiftSignificandRight(unsigned int);
+  unsigned int significandLSB() const;
+  unsigned int significandMSB() const;
+  void zeroSignificand();
+  /// Return true if the significand excluding the integral bit is all ones.
+  bool isSignificandAllOnes() const;
+  /// Return true if the significand excluding the integral bit is all zeros.
+  bool isSignificandAllZeros() const;
+
+  /// @}
+
+  /// \name Arithmetic on special values.
+  /// @{
+
+  opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
+  opStatus divideSpecials(const APFloat &);
+  opStatus multiplySpecials(const APFloat &);
+  opStatus modSpecials(const APFloat &);
+
+  /// @}
+
+  /// \name Special value setters.
+  /// @{
+
+  void makeLargest(bool Neg = false);
+  void makeSmallest(bool Neg = false);
+  void makeNaN(bool SNaN = false, bool Neg = false,
+               const APInt *fill = nullptr);
+  static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+                         const APInt *fill);
+  void makeInf(bool Neg = false);
+  void makeZero(bool Neg = false);
+
+  /// @}
+
+  /// \name Miscellany
+  /// @{
+
+  bool convertFromStringSpecials(StringRef str);
+  opStatus normalize(roundingMode, lostFraction);
+  opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
+  cmpResult compareAbsoluteValue(const APFloat &) const;
+  opStatus handleOverflow(roundingMode);
+  bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
+  opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+                                        roundingMode, bool *) const;
+  opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+                                    roundingMode);
+  opStatus convertFromHexadecimalString(StringRef, roundingMode);
+  opStatus convertFromDecimalString(StringRef, roundingMode);
+  char *convertNormalToHexString(char *, unsigned int, bool,
+                                 roundingMode) const;
+  opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
+                                        roundingMode);
+
+  /// @}
+
+  APInt convertHalfAPFloatToAPInt() const;
+  APInt convertFloatAPFloatToAPInt() const;
+  APInt convertDoubleAPFloatToAPInt() const;
+  APInt convertQuadrupleAPFloatToAPInt() const;
+  APInt convertF80LongDoubleAPFloatToAPInt() const;
+  APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+  void initFromAPInt(const fltSemantics *Sem, const APInt &api);
+  void initFromHalfAPInt(const APInt &api);
+  void initFromFloatAPInt(const APInt &api);
+  void initFromDoubleAPInt(const APInt &api);
+  void initFromQuadrupleAPInt(const APInt &api);
+  void initFromF80LongDoubleAPInt(const APInt &api);
+  void initFromPPCDoubleDoubleAPInt(const APInt &api);
+
+  void assign(const APFloat &);
+  void copySignificand(const APFloat &);
+  void freeSignificand();
+
+  /// The semantics that this value obeys.
+  const fltSemantics *semantics;
+
+  /// A binary fraction with an explicit integer bit.
+  ///
+  /// The significand must be at least one bit wider than the target precision.
+  union Significand {
+    integerPart part;
+    integerPart *parts;
+  } significand;
+
+  /// The signed unbiased exponent of the value.
+  ExponentType exponent;
+
+  /// What kind of floating point number this is.
+  ///
+  /// Only 2 bits are required, but VisualStudio incorrectly sign extends it.
+  /// Using the extra bit keeps it from failing under VisualStudio.
+  fltCategory category : 3;
+
+  /// Sign bit of the number.
+  unsigned int sign : 1;
+};
+
+/// See friend declaration above.
+///
+/// This additional declaration is required in order to compile LLVM with IBM
+/// xlC compiler.
+hash_code hash_value(const APFloat &Arg);
+} // namespace llvm
+
+#endif // LLVM_ADT_APFLOAT_H
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
new file mode 100644
index 0000000..aa3c3f6
--- /dev/null
+++ b/include/llvm/ADT/APInt.h
@@ -0,0 +1,1889 @@
+//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements a class to represent arbitrary precision
+/// integral constant values and operations on them.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_APINT_H
+#define LLVM_ADT_APINT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+class Deserializer;
+class FoldingSetNodeID;
+class Serializer;
+class StringRef;
+class hash_code;
+class raw_ostream;
+
+template <typename T> class SmallVectorImpl;
+
+// An unsigned host type used as a single part of a multi-part
+// bignum.
+typedef uint64_t integerPart;
+
+const unsigned int host_char_bit = 8;
+const unsigned int integerPartWidth =
+    host_char_bit * static_cast<unsigned int>(sizeof(integerPart));
+
+//===----------------------------------------------------------------------===//
+//                              APInt Class
+//===----------------------------------------------------------------------===//
+
+/// \brief Class for arbitrary precision integers.
+///
+/// APInt is a functional replacement for common case unsigned integer type like
+/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
+/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
+/// than 64-bits of precision. APInt provides a variety of arithmetic operators
+/// and methods to manipulate integer values of any bit-width. It supports both
+/// the typical integer arithmetic and comparison operations as well as bitwise
+/// manipulation.
+///
+/// The class has several invariants worth noting:
+///   * All bit, byte, and word positions are zero-based.
+///   * Once the bit width is set, it doesn't change except by the Truncate,
+///     SignExtend, or ZeroExtend operations.
+///   * All binary operators must be on APInt instances of the same bit width.
+///     Attempting to use these operators on instances with different bit
+///     widths will yield an assertion.
+///   * The value is stored canonically as an unsigned value. For operations
+///     where it makes a difference, there are both signed and unsigned variants
+///     of the operation. For example, sdiv and udiv. However, because the bit
+///     widths must be the same, operations such as Mul and Add produce the same
+///     results regardless of whether the values are interpreted as signed or
+///     not.
+///   * In general, the class tries to follow the style of computation that LLVM
+///     uses in its IR. This simplifies its use for LLVM.
+///
+class APInt {
+  unsigned BitWidth; ///< The number of bits in this APInt.
+
+  /// This union is used to store the integer value. When the
+  /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
+  union {
+    uint64_t VAL;   ///< Used to store the <= 64 bits integer value.
+    uint64_t *pVal; ///< Used to store the >64 bits integer value.
+  };
+
+  /// This enum is used to hold the constants we needed for APInt.
+  enum {
+    /// Bits in a word
+    APINT_BITS_PER_WORD =
+        static_cast<unsigned int>(sizeof(uint64_t)) * CHAR_BIT,
+    /// Byte size of a word
+    APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
+  };
+
+  /// \brief Fast internal constructor
+  ///
+  /// This constructor is used only internally for speed of construction of
+  /// temporaries. It is unsafe for general use so it is not public.
+  APInt(uint64_t *val, unsigned bits) : BitWidth(bits), pVal(val) {}
+
+  /// \brief Determine if this APInt just has one word to store value.
+  ///
+  /// \returns true if the number of bits <= 64, false otherwise.
+  bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; }
+
+  /// \brief Determine which word a bit is in.
+  ///
+  /// \returns the word position for the specified bit position.
+  static unsigned whichWord(unsigned bitPosition) {
+    return bitPosition / APINT_BITS_PER_WORD;
+  }
+
+  /// \brief Determine which bit in a word a bit is in.
+  ///
+  /// \returns the bit position in a word for the specified bit position
+  /// in the APInt.
+  static unsigned whichBit(unsigned bitPosition) {
+    return bitPosition % APINT_BITS_PER_WORD;
+  }
+
+  /// \brief Get a single bit mask.
+  ///
+  /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
+  /// This method generates and returns a uint64_t (word) mask for a single
+  /// bit at a specific bit position. This is used to mask the bit in the
+  /// corresponding word.
+  static uint64_t maskBit(unsigned bitPosition) {
+    return 1ULL << whichBit(bitPosition);
+  }
+
+  /// \brief Clear unused high order bits
+  ///
+  /// This method is used internally to clear the to "N" bits in the high order
+  /// word that are not used by the APInt. This is needed after the most
+  /// significant word is assigned a value to ensure that those bits are
+  /// zero'd out.
+  APInt &clearUnusedBits() {
+    // Compute how many bits are used in the final word
+    unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
+    if (wordBits == 0)
+      // If all bits are used, we want to leave the value alone. This also
+      // avoids the undefined behavior of >> when the shift is the same size as
+      // the word size (64).
+      return *this;
+
+    // Mask out the high bits.
+    uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+    if (isSingleWord())
+      VAL &= mask;
+    else
+      pVal[getNumWords() - 1] &= mask;
+    return *this;
+  }
+
+  /// \brief Get the word corresponding to a bit position
+  /// \returns the corresponding word for the specified bit position.
+  uint64_t getWord(unsigned bitPosition) const {
+    return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+  }
+
+  /// \brief Convert a char array into an APInt
+  ///
+  /// \param radix 2, 8, 10, 16, or 36
+  /// Converts a string into a number.  The string must be non-empty
+  /// and well-formed as a number of the given base. The bit-width
+  /// must be sufficient to hold the result.
+  ///
+  /// This is used by the constructors that take string arguments.
+  ///
+  /// StringRef::getAsInteger is superficially similar but (1) does
+  /// not assume that the string is well-formed and (2) grows the
+  /// result to hold the input.
+  void fromString(unsigned numBits, StringRef str, uint8_t radix);
+
+  /// \brief An internal division function for dividing APInts.
+  ///
+  /// This is used by the toString method to divide by the radix. It simply
+  /// provides a more convenient form of divide for internal use since KnuthDiv
+  /// has specific constraints on its inputs. If those constraints are not met
+  /// then it provides a simpler form of divide.
+  static void divide(const APInt LHS, unsigned lhsWords, const APInt &RHS,
+                     unsigned rhsWords, APInt *Quotient, APInt *Remainder);
+
+  /// out-of-line slow case for inline constructor
+  void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
+
+  /// shared code between two array constructors
+  void initFromArray(ArrayRef<uint64_t> array);
+
+  /// out-of-line slow case for inline copy constructor
+  void initSlowCase(const APInt &that);
+
+  /// out-of-line slow case for shl
+  APInt shlSlowCase(unsigned shiftAmt) const;
+
+  /// out-of-line slow case for operator&
+  APInt AndSlowCase(const APInt &RHS) const;
+
+  /// out-of-line slow case for operator|
+  APInt OrSlowCase(const APInt &RHS) const;
+
+  /// out-of-line slow case for operator^
+  APInt XorSlowCase(const APInt &RHS) const;
+
+  /// out-of-line slow case for operator=
+  APInt &AssignSlowCase(const APInt &RHS);
+
+  /// out-of-line slow case for operator==
+  bool EqualSlowCase(const APInt &RHS) const;
+
+  /// out-of-line slow case for operator==
+  bool EqualSlowCase(uint64_t Val) const;
+
+  /// out-of-line slow case for countLeadingZeros
+  unsigned countLeadingZerosSlowCase() const;
+
+  /// out-of-line slow case for countTrailingOnes
+  unsigned countTrailingOnesSlowCase() const;
+
+  /// out-of-line slow case for countPopulation
+  unsigned countPopulationSlowCase() const;
+
+public:
+  /// \name Constructors
+  /// @{
+
+  /// \brief Create a new APInt of numBits width, initialized as val.
+  ///
+  /// If isSigned is true then val is treated as if it were a signed value
+  /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
+  /// will be done. Otherwise, no sign extension occurs (high order bits beyond
+  /// the range of val are zero filled).
+  ///
+  /// \param numBits the bit width of the constructed APInt
+  /// \param val the initial value of the APInt
+  /// \param isSigned how to treat signedness of val
+  APInt(unsigned numBits, uint64_t val, bool isSigned = false)
+      : BitWidth(numBits), VAL(0) {
+    assert(BitWidth && "bitwidth too small");
+    if (isSingleWord())
+      VAL = val;
+    else
+      initSlowCase(numBits, val, isSigned);
+    clearUnusedBits();
+  }
+
+  /// \brief Construct an APInt of numBits width, initialized as bigVal[].
+  ///
+  /// Note that bigVal.size() can be smaller or larger than the corresponding
+  /// bit width but any extraneous bits will be dropped.
+  ///
+  /// \param numBits the bit width of the constructed APInt
+  /// \param bigVal a sequence of words to form the initial value of the APInt
+  APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
+
+  /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
+  /// deprecated because this constructor is prone to ambiguity with the
+  /// APInt(unsigned, uint64_t, bool) constructor.
+  ///
+  /// If this overload is ever deleted, care should be taken to prevent calls
+  /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
+  /// constructor.
+  APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
+
+  /// \brief Construct an APInt from a string representation.
+  ///
+  /// This constructor interprets the string \p str in the given radix. The
+  /// interpretation stops when the first character that is not suitable for the
+  /// radix is encountered, or the end of the string. Acceptable radix values
+  /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
+  /// string to require more bits than numBits.
+  ///
+  /// \param numBits the bit width of the constructed APInt
+  /// \param str the string to be interpreted
+  /// \param radix the radix to use for the conversion
+  APInt(unsigned numBits, StringRef str, uint8_t radix);
+
+  /// Simply makes *this a copy of that.
+  /// @brief Copy Constructor.
+  APInt(const APInt &that) : BitWidth(that.BitWidth), VAL(0) {
+    assert(BitWidth && "bitwidth too small");
+    if (isSingleWord())
+      VAL = that.VAL;
+    else
+      initSlowCase(that);
+  }
+
+  /// \brief Move Constructor.
+  APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) {
+    that.BitWidth = 0;
+  }
+
+  /// \brief Destructor.
+  ~APInt() {
+    if (needsCleanup())
+      delete[] pVal;
+  }
+
+  /// \brief Default constructor that creates an uninitialized APInt.
+  ///
+  /// This is useful for object deserialization (pair this with the static
+  ///  method Read).
+  explicit APInt() : BitWidth(1) {}
+
+  /// \brief Returns whether this instance allocated memory.
+  bool needsCleanup() const { return !isSingleWord(); }
+
+  /// Used to insert APInt objects, or objects that contain APInt objects, into
+  ///  FoldingSets.
+  void Profile(FoldingSetNodeID &id) const;
+
+  /// @}
+  /// \name Value Tests
+  /// @{
+
+  /// \brief Determine sign of this APInt.
+  ///
+  /// This tests the high bit of this APInt to determine if it is set.
+  ///
+  /// \returns true if this APInt is negative, false otherwise
+  bool isNegative() const { return (*this)[BitWidth - 1]; }
+
+  /// \brief Determine if this APInt Value is non-negative (>= 0)
+  ///
+  /// This tests the high bit of the APInt to determine if it is unset.
+  bool isNonNegative() const { return !isNegative(); }
+
+  /// \brief Determine if this APInt Value is positive.
+  ///
+  /// This tests if the value of this APInt is positive (> 0). Note
+  /// that 0 is not a positive value.
+  ///
+  /// \returns true if this APInt is positive.
+  bool isStrictlyPositive() const { return isNonNegative() && !!*this; }
+
+  /// \brief Determine if all bits are set
+  ///
+  /// This checks to see if the value has all bits of the APInt are set or not.
+  bool isAllOnesValue() const {
+    if (isSingleWord())
+      return VAL == ~integerPart(0) >> (APINT_BITS_PER_WORD - BitWidth);
+    return countPopulationSlowCase() == BitWidth;
+  }
+
+  /// \brief Determine if this is the largest unsigned value.
+  ///
+  /// This checks to see if the value of this APInt is the maximum unsigned
+  /// value for the APInt's bit width.
+  bool isMaxValue() const { return isAllOnesValue(); }
+
+  /// \brief Determine if this is the largest signed value.
+  ///
+  /// This checks to see if the value of this APInt is the maximum signed
+  /// value for the APInt's bit width.
+  bool isMaxSignedValue() const {
+    return BitWidth == 1 ? VAL == 0
+                         : !isNegative() && countPopulation() == BitWidth - 1;
+  }
+
+  /// \brief Determine if this is the smallest unsigned value.
+  ///
+  /// This checks to see if the value of this APInt is the minimum unsigned
+  /// value for the APInt's bit width.
+  bool isMinValue() const { return !*this; }
+
+  /// \brief Determine if this is the smallest signed value.
+  ///
+  /// This checks to see if the value of this APInt is the minimum signed
+  /// value for the APInt's bit width.
+  bool isMinSignedValue() const {
+    return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
+  }
+
+  /// \brief Check if this APInt has an N-bits unsigned integer value.
+  bool isIntN(unsigned N) const {
+    assert(N && "N == 0 ???");
+    return getActiveBits() <= N;
+  }
+
+  /// \brief Check if this APInt has an N-bits signed integer value.
+  bool isSignedIntN(unsigned N) const {
+    assert(N && "N == 0 ???");
+    return getMinSignedBits() <= N;
+  }
+
+  /// \brief Check if this APInt's value is a power of two greater than zero.
+  ///
+  /// \returns true if the argument APInt value is a power of two > 0.
+  bool isPowerOf2() const {
+    if (isSingleWord())
+      return isPowerOf2_64(VAL);
+    return countPopulationSlowCase() == 1;
+  }
+
+  /// \brief Check if the APInt's value is returned by getSignBit.
+  ///
+  /// \returns true if this is the value returned by getSignBit.
+  bool isSignBit() const { return isMinSignedValue(); }
+
+  /// \brief Convert APInt to a boolean value.
+  ///
+  /// This converts the APInt to a boolean value as a test against zero.
+  bool getBoolValue() const { return !!*this; }
+
+  /// If this value is smaller than the specified limit, return it, otherwise
+  /// return the limit value.  This causes the value to saturate to the limit.
+  uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+    return (getActiveBits() > 64 || getZExtValue() > Limit) ? Limit
+                                                            : getZExtValue();
+  }
+
+  /// @}
+  /// \name Value Generators
+  /// @{
+
+  /// \brief Gets maximum unsigned value of APInt for specific bit width.
+  static APInt getMaxValue(unsigned numBits) {
+    return getAllOnesValue(numBits);
+  }
+
+  /// \brief Gets maximum signed value of APInt for a specific bit width.
+  static APInt getSignedMaxValue(unsigned numBits) {
+    APInt API = getAllOnesValue(numBits);
+    API.clearBit(numBits - 1);
+    return API;
+  }
+
+  /// \brief Gets minimum unsigned value of APInt for a specific bit width.
+  static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
+
+  /// \brief Gets minimum signed value of APInt for a specific bit width.
+  static APInt getSignedMinValue(unsigned numBits) {
+    APInt API(numBits, 0);
+    API.setBit(numBits - 1);
+    return API;
+  }
+
+  /// \brief Get the SignBit for a specific bit width.
+  ///
+  /// This is just a wrapper function of getSignedMinValue(), and it helps code
+  /// readability when we want to get a SignBit.
+  static APInt getSignBit(unsigned BitWidth) {
+    return getSignedMinValue(BitWidth);
+  }
+
+  /// \brief Get the all-ones value.
+  ///
+  /// \returns the all-ones value for an APInt of the specified bit-width.
+  static APInt getAllOnesValue(unsigned numBits) {
+    return APInt(numBits, UINT64_MAX, true);
+  }
+
+  /// \brief Get the '0' value.
+  ///
+  /// \returns the '0' value for an APInt of the specified bit-width.
+  static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); }
+
+  /// \brief Compute an APInt containing numBits highbits from this APInt.
+  ///
+  /// Get an APInt with the same BitWidth as this APInt, just zero mask
+  /// the low bits and right shift to the least significant bit.
+  ///
+  /// \returns the high "numBits" bits of this APInt.
+  APInt getHiBits(unsigned numBits) const;
+
+  /// \brief Compute an APInt containing numBits lowbits from this APInt.
+  ///
+  /// Get an APInt with the same BitWidth as this APInt, just zero mask
+  /// the high bits.
+  ///
+  /// \returns the low "numBits" bits of this APInt.
+  APInt getLoBits(unsigned numBits) const;
+
+  /// \brief Return an APInt with exactly one bit set in the result.
+  static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
+    APInt Res(numBits, 0);
+    Res.setBit(BitNo);
+    return Res;
+  }
+
+  /// \brief Get a value with a block of bits set.
+  ///
+  /// Constructs an APInt value that has a contiguous range of bits set. The
+  /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
+  /// bits will be zero. For example, with parameters(32, 0, 16) you would get
+  /// 0x0000FFFF. If hiBit is less than loBit then the set bits "wrap". For
+  /// example, with parameters (32, 28, 4), you would get 0xF000000F.
+  ///
+  /// \param numBits the intended bit width of the result
+  /// \param loBit the index of the lowest bit set.
+  /// \param hiBit the index of the highest bit set.
+  ///
+  /// \returns An APInt value with the requested bits set.
+  static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
+    assert(hiBit <= numBits && "hiBit out of range");
+    assert(loBit < numBits && "loBit out of range");
+    if (hiBit < loBit)
+      return getLowBitsSet(numBits, hiBit) |
+             getHighBitsSet(numBits, numBits - loBit);
+    return getLowBitsSet(numBits, hiBit - loBit).shl(loBit);
+  }
+
+  /// \brief Get a value with high bits set
+  ///
+  /// Constructs an APInt value that has the top hiBitsSet bits set.
+  ///
+  /// \param numBits the bitwidth of the result
+  /// \param hiBitsSet the number of high-order bits set in the result.
+  static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
+    assert(hiBitsSet <= numBits && "Too many bits to set!");
+    // Handle a degenerate case, to avoid shifting by word size
+    if (hiBitsSet == 0)
+      return APInt(numBits, 0);
+    unsigned shiftAmt = numBits - hiBitsSet;
+    // For small values, return quickly
+    if (numBits <= APINT_BITS_PER_WORD)
+      return APInt(numBits, ~0ULL << shiftAmt);
+    return getAllOnesValue(numBits).shl(shiftAmt);
+  }
+
+  /// \brief Get a value with low bits set
+  ///
+  /// Constructs an APInt value that has the bottom loBitsSet bits set.
+  ///
+  /// \param numBits the bitwidth of the result
+  /// \param loBitsSet the number of low-order bits set in the result.
+  static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
+    assert(loBitsSet <= numBits && "Too many bits to set!");
+    // Handle a degenerate case, to avoid shifting by word size
+    if (loBitsSet == 0)
+      return APInt(numBits, 0);
+    if (loBitsSet == APINT_BITS_PER_WORD)
+      return APInt(numBits, UINT64_MAX);
+    // For small values, return quickly.
+    if (loBitsSet <= APINT_BITS_PER_WORD)
+      return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet));
+    return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
+  }
+
+  /// \brief Return a value containing V broadcasted over NewLen bits.
+  static APInt getSplat(unsigned NewLen, const APInt &V) {
+    assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
+
+    APInt Val = V.zextOrSelf(NewLen);
+    for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
+      Val |= Val << I;
+
+    return Val;
+  }
+
+  /// \brief Determine if two APInts have the same value, after zero-extending
+  /// one of them (if needed!) to ensure that the bit-widths match.
+  static bool isSameValue(const APInt &I1, const APInt &I2) {
+    if (I1.getBitWidth() == I2.getBitWidth())
+      return I1 == I2;
+
+    if (I1.getBitWidth() > I2.getBitWidth())
+      return I1 == I2.zext(I1.getBitWidth());
+
+    return I1.zext(I2.getBitWidth()) == I2;
+  }
+
+  /// \brief Overload to compute a hash_code for an APInt value.
+  friend hash_code hash_value(const APInt &Arg);
+
+  /// This function returns a pointer to the internal storage of the APInt.
+  /// This is useful for writing out the APInt in binary form without any
+  /// conversions.
+  const uint64_t *getRawData() const {
+    if (isSingleWord())
+      return &VAL;
+    return &pVal[0];
+  }
+
+  /// @}
+  /// \name Unary Operators
+  /// @{
+
+  /// \brief Postfix increment operator.
+  ///
+  /// \returns a new APInt value representing *this incremented by one
+  const APInt operator++(int) {
+    APInt API(*this);
+    ++(*this);
+    return API;
+  }
+
+  /// \brief Prefix increment operator.
+  ///
+  /// \returns *this incremented by one
+  APInt &operator++();
+
+  /// \brief Postfix decrement operator.
+  ///
+  /// \returns a new APInt representing *this decremented by one.
+  const APInt operator--(int) {
+    APInt API(*this);
+    --(*this);
+    return API;
+  }
+
+  /// \brief Prefix decrement operator.
+  ///
+  /// \returns *this decremented by one.
+  APInt &operator--();
+
+  /// \brief Unary bitwise complement operator.
+  ///
+  /// Performs a bitwise complement operation on this APInt.
+  ///
+  /// \returns an APInt that is the bitwise complement of *this
+  APInt operator~() const {
+    APInt Result(*this);
+    Result.flipAllBits();
+    return Result;
+  }
+
+  /// \brief Unary negation operator
+  ///
+  /// Negates *this using two's complement logic.
+  ///
+  /// \returns An APInt value representing the negation of *this.
+  APInt operator-() const { return APInt(BitWidth, 0) - (*this); }
+
+  /// \brief Logical negation operator.
+  ///
+  /// Performs logical negation operation on this APInt.
+  ///
+  /// \returns true if *this is zero, false otherwise.
+  bool operator!() const {
+    if (isSingleWord())
+      return !VAL;
+
+    for (unsigned i = 0; i != getNumWords(); ++i)
+      if (pVal[i])
+        return false;
+    return true;
+  }
+
+  /// @}
+  /// \name Assignment Operators
+  /// @{
+
+  /// \brief Copy assignment operator.
+  ///
+  /// \returns *this after assignment of RHS.
+  APInt &operator=(const APInt &RHS) {
+    // If the bitwidths are the same, we can avoid mucking with memory
+    if (isSingleWord() && RHS.isSingleWord()) {
+      VAL = RHS.VAL;
+      BitWidth = RHS.BitWidth;
+      return clearUnusedBits();
+    }
+
+    return AssignSlowCase(RHS);
+  }
+
+  /// @brief Move assignment operator.
+  APInt &operator=(APInt &&that) {
+    if (!isSingleWord())
+      delete[] pVal;
+
+    BitWidth = that.BitWidth;
+    VAL = that.VAL;
+
+    that.BitWidth = 0;
+
+    return *this;
+  }
+
+  /// \brief Assignment operator.
+  ///
+  /// The RHS value is assigned to *this. If the significant bits in RHS exceed
+  /// the bit width, the excess bits are truncated. If the bit width is larger
+  /// than 64, the value is zero filled in the unspecified high order bits.
+  ///
+  /// \returns *this after assignment of RHS value.
+  APInt &operator=(uint64_t RHS);
+
+  /// \brief Bitwise AND assignment operator.
+  ///
+  /// Performs a bitwise AND operation on this APInt and RHS. The result is
+  /// assigned to *this.
+  ///
+  /// \returns *this after ANDing with RHS.
+  APInt &operator&=(const APInt &RHS);
+
+  /// \brief Bitwise OR assignment operator.
+  ///
+  /// Performs a bitwise OR operation on this APInt and RHS. The result is
+  /// assigned *this;
+  ///
+  /// \returns *this after ORing with RHS.
+  APInt &operator|=(const APInt &RHS);
+
+  /// \brief Bitwise OR assignment operator.
+  ///
+  /// Performs a bitwise OR operation on this APInt and RHS. RHS is
+  /// logically zero-extended or truncated to match the bit-width of
+  /// the LHS.
+  APInt &operator|=(uint64_t RHS) {
+    if (isSingleWord()) {
+      VAL |= RHS;
+      clearUnusedBits();
+    } else {
+      pVal[0] |= RHS;
+    }
+    return *this;
+  }
+
+  /// \brief Bitwise XOR assignment operator.
+  ///
+  /// Performs a bitwise XOR operation on this APInt and RHS. The result is
+  /// assigned to *this.
+  ///
+  /// \returns *this after XORing with RHS.
+  APInt &operator^=(const APInt &RHS);
+
+  /// \brief Multiplication assignment operator.
+  ///
+  /// Multiplies this APInt by RHS and assigns the result to *this.
+  ///
+  /// \returns *this
+  APInt &operator*=(const APInt &RHS);
+
+  /// \brief Addition assignment operator.
+  ///
+  /// Adds RHS to *this and assigns the result to *this.
+  ///
+  /// \returns *this
+  APInt &operator+=(const APInt &RHS);
+
+  /// \brief Subtraction assignment operator.
+  ///
+  /// Subtracts RHS from *this and assigns the result to *this.
+  ///
+  /// \returns *this
+  APInt &operator-=(const APInt &RHS);
+
+  /// \brief Left-shift assignment function.
+  ///
+  /// Shifts *this left by shiftAmt and assigns the result to *this.
+  ///
+  /// \returns *this after shifting left by shiftAmt
+  APInt &operator<<=(unsigned shiftAmt) {
+    *this = shl(shiftAmt);
+    return *this;
+  }
+
+  /// @}
+  /// \name Binary Operators
+  /// @{
+
+  /// \brief Bitwise AND operator.
+  ///
+  /// Performs a bitwise AND operation on *this and RHS.
+  ///
+  /// \returns An APInt value representing the bitwise AND of *this and RHS.
+  APInt operator&(const APInt &RHS) const {
+    assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+    if (isSingleWord())
+      return APInt(getBitWidth(), VAL & RHS.VAL);
+    return AndSlowCase(RHS);
+  }
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APInt &RHS) const {
+    return this->operator&(RHS);
+  }
+
+  /// \brief Bitwise OR operator.
+  ///
+  /// Performs a bitwise OR operation on *this and RHS.
+  ///
+  /// \returns An APInt value representing the bitwise OR of *this and RHS.
+  APInt operator|(const APInt &RHS) const {
+    assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+    if (isSingleWord())
+      return APInt(getBitWidth(), VAL | RHS.VAL);
+    return OrSlowCase(RHS);
+  }
+
+  /// \brief Bitwise OR function.
+  ///
+  /// Performs a bitwise or on *this and RHS. This is implemented bny simply
+  /// calling operator|.
+  ///
+  /// \returns An APInt value representing the bitwise OR of *this and RHS.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APInt &RHS) const {
+    return this->operator|(RHS);
+  }
+
+  /// \brief Bitwise XOR operator.
+  ///
+  /// Performs a bitwise XOR operation on *this and RHS.
+  ///
+  /// \returns An APInt value representing the bitwise XOR of *this and RHS.
+  APInt operator^(const APInt &RHS) const {
+    assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+    if (isSingleWord())
+      return APInt(BitWidth, VAL ^ RHS.VAL);
+    return XorSlowCase(RHS);
+  }
+
+  /// \brief Bitwise XOR function.
+  ///
+  /// Performs a bitwise XOR operation on *this and RHS. This is implemented
+  /// through the usage of operator^.
+  ///
+  /// \returns An APInt value representing the bitwise XOR of *this and RHS.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APInt &RHS) const {
+    return this->operator^(RHS);
+  }
+
+  /// \brief Multiplication operator.
+  ///
+  /// Multiplies this APInt by RHS and returns the result.
+  APInt operator*(const APInt &RHS) const;
+
+  /// \brief Addition operator.
+  ///
+  /// Adds RHS to this APInt and returns the result.
+  APInt operator+(const APInt &RHS) const;
+  APInt operator+(uint64_t RHS) const { return (*this) + APInt(BitWidth, RHS); }
+
+  /// \brief Subtraction operator.
+  ///
+  /// Subtracts RHS from this APInt and returns the result.
+  APInt operator-(const APInt &RHS) const;
+  APInt operator-(uint64_t RHS) const { return (*this) - APInt(BitWidth, RHS); }
+
+  /// \brief Left logical shift operator.
+  ///
+  /// Shifts this APInt left by \p Bits and returns the result.
+  APInt operator<<(unsigned Bits) const { return shl(Bits); }
+
+  /// \brief Left logical shift operator.
+  ///
+  /// Shifts this APInt left by \p Bits and returns the result.
+  APInt operator<<(const APInt &Bits) const { return shl(Bits); }
+
+  /// \brief Arithmetic right-shift function.
+  ///
+  /// Arithmetic right-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(unsigned shiftAmt) const;
+
+  /// \brief Logical right-shift function.
+  ///
+  /// Logical right-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(unsigned shiftAmt) const;
+
+  /// \brief Left-shift function.
+  ///
+  /// Left-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(unsigned shiftAmt) const {
+    assert(shiftAmt <= BitWidth && "Invalid shift amount");
+    if (isSingleWord()) {
+      if (shiftAmt >= BitWidth)
+        return APInt(BitWidth, 0); // avoid undefined shift results
+      return APInt(BitWidth, VAL << shiftAmt);
+    }
+    return shlSlowCase(shiftAmt);
+  }
+
+  /// \brief Rotate left by rotateAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(unsigned rotateAmt) const;
+
+  /// \brief Rotate right by rotateAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(unsigned rotateAmt) const;
+
+  /// \brief Arithmetic right-shift function.
+  ///
+  /// Arithmetic right-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(const APInt &shiftAmt) const;
+
+  /// \brief Logical right-shift function.
+  ///
+  /// Logical right-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(const APInt &shiftAmt) const;
+
+  /// \brief Left-shift function.
+  ///
+  /// Left-shift this APInt by shiftAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(const APInt &shiftAmt) const;
+
+  /// \brief Rotate left by rotateAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(const APInt &rotateAmt) const;
+
+  /// \brief Rotate right by rotateAmt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(const APInt &rotateAmt) const;
+
+  /// \brief Unsigned division operation.
+  ///
+  /// Perform an unsigned divide operation on this APInt by RHS. Both this and
+  /// RHS are treated as unsigned quantities for purposes of this division.
+  ///
+  /// \returns a new APInt value containing the division result
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT udiv(const APInt &RHS) const;
+
+  /// \brief Signed division function for APInt.
+  ///
+  /// Signed divide this APInt by APInt RHS.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const;
+
+  /// \brief Unsigned remainder operation.
+  ///
+  /// Perform an unsigned remainder operation on this APInt with RHS being the
+  /// divisor. Both this and RHS are treated as unsigned quantities for purposes
+  /// of this operation. Note that this is a true remainder operation and not a
+  /// modulo operation because the sign follows the sign of the dividend which
+  /// is *this.
+  ///
+  /// \returns a new APInt value containing the remainder result
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT urem(const APInt &RHS) const;
+
+  /// \brief Function for signed remainder operation.
+  ///
+  /// Signed remainder operation on APInt.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT srem(const APInt &RHS) const;
+
+  /// \brief Dual division/remainder interface.
+  ///
+  /// Sometimes it is convenient to divide two APInt values and obtain both the
+  /// quotient and remainder. This function does both operations in the same
+  /// computation making it a little more efficient. The pair of input arguments
+  /// may overlap with the pair of output arguments. It is safe to call
+  /// udivrem(X, Y, X, Y), for example.
+  static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
+                      APInt &Remainder);
+
+  static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
+                      APInt &Remainder);
+
+  // Operations that return overflow indicators.
+  APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
+  APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
+  APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
+  APInt usub_ov(const APInt &RHS, bool &Overflow) const;
+  APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
+  APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+  APInt umul_ov(const APInt &RHS, bool &Overflow) const;
+  APInt sshl_ov(unsigned Amt, bool &Overflow) const;
+
+  /// \brief Array-indexing support.
+  ///
+  /// \returns the bit value at bitPosition
+  bool operator[](unsigned bitPosition) const {
+    assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
+    return (maskBit(bitPosition) &
+            (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) !=
+           0;
+  }
+
+  /// @}
+  /// \name Comparison Operators
+  /// @{
+
+  /// \brief Equality operator.
+  ///
+  /// Compares this APInt with RHS for the validity of the equality
+  /// relationship.
+  bool operator==(const APInt &RHS) const {
+    assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
+    if (isSingleWord())
+      return VAL == RHS.VAL;
+    return EqualSlowCase(RHS);
+  }
+
+  /// \brief Equality operator.
+  ///
+  /// Compares this APInt with a uint64_t for the validity of the equality
+  /// relationship.
+  ///
+  /// \returns true if *this == Val
+  bool operator==(uint64_t Val) const {
+    if (isSingleWord())
+      return VAL == Val;
+    return EqualSlowCase(Val);
+  }
+
+  /// \brief Equality comparison.
+  ///
+  /// Compares this APInt with RHS for the validity of the equality
+  /// relationship.
+  ///
+  /// \returns true if *this == Val
+  bool eq(const APInt &RHS) const { return (*this) == RHS; }
+
+  /// \brief Inequality operator.
+  ///
+  /// Compares this APInt with RHS for the validity of the inequality
+  /// relationship.
+  ///
+  /// \returns true if *this != Val
+  bool operator!=(const APInt &RHS) const { return !((*this) == RHS); }
+
+  /// \brief Inequality operator.
+  ///
+  /// Compares this APInt with a uint64_t for the validity of the inequality
+  /// relationship.
+  ///
+  /// \returns true if *this != Val
+  bool operator!=(uint64_t Val) const { return !((*this) == Val); }
+
+  /// \brief Inequality comparison
+  ///
+  /// Compares this APInt with RHS for the validity of the inequality
+  /// relationship.
+  ///
+  /// \returns true if *this != Val
+  bool ne(const APInt &RHS) const { return !((*this) == RHS); }
+
+  /// \brief Unsigned less than comparison
+  ///
+  /// Regards both *this and RHS as unsigned quantities and compares them for
+  /// the validity of the less-than relationship.
+  ///
+  /// \returns true if *this < RHS when both are considered unsigned.
+  bool ult(const APInt &RHS) const;
+
+  /// \brief Unsigned less than comparison
+  ///
+  /// Regards both *this as an unsigned quantity and compares it with RHS for
+  /// the validity of the less-than relationship.
+  ///
+  /// \returns true if *this < RHS when considered unsigned.
+  bool ult(uint64_t RHS) const { return ult(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Signed less than comparison
+  ///
+  /// Regards both *this and RHS as signed quantities and compares them for
+  /// validity of the less-than relationship.
+  ///
+  /// \returns true if *this < RHS when both are considered signed.
+  bool slt(const APInt &RHS) const;
+
+  /// \brief Signed less than comparison
+  ///
+  /// Regards both *this as a signed quantity and compares it with RHS for
+  /// the validity of the less-than relationship.
+  ///
+  /// \returns true if *this < RHS when considered signed.
+  bool slt(uint64_t RHS) const { return slt(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Unsigned less or equal comparison
+  ///
+  /// Regards both *this and RHS as unsigned quantities and compares them for
+  /// validity of the less-or-equal relationship.
+  ///
+  /// \returns true if *this <= RHS when both are considered unsigned.
+  bool ule(const APInt &RHS) const { return ult(RHS) || eq(RHS); }
+
+  /// \brief Unsigned less or equal comparison
+  ///
+  /// Regards both *this as an unsigned quantity and compares it with RHS for
+  /// the validity of the less-or-equal relationship.
+  ///
+  /// \returns true if *this <= RHS when considered unsigned.
+  bool ule(uint64_t RHS) const { return ule(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Signed less or equal comparison
+  ///
+  /// Regards both *this and RHS as signed quantities and compares them for
+  /// validity of the less-or-equal relationship.
+  ///
+  /// \returns true if *this <= RHS when both are considered signed.
+  bool sle(const APInt &RHS) const { return slt(RHS) || eq(RHS); }
+
+  /// \brief Signed less or equal comparison
+  ///
+  /// Regards both *this as a signed quantity and compares it with RHS for the
+  /// validity of the less-or-equal relationship.
+  ///
+  /// \returns true if *this <= RHS when considered signed.
+  bool sle(uint64_t RHS) const { return sle(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Unsigned greather than comparison
+  ///
+  /// Regards both *this and RHS as unsigned quantities and compares them for
+  /// the validity of the greater-than relationship.
+  ///
+  /// \returns true if *this > RHS when both are considered unsigned.
+  bool ugt(const APInt &RHS) const { return !ult(RHS) && !eq(RHS); }
+
+  /// \brief Unsigned greater than comparison
+  ///
+  /// Regards both *this as an unsigned quantity and compares it with RHS for
+  /// the validity of the greater-than relationship.
+  ///
+  /// \returns true if *this > RHS when considered unsigned.
+  bool ugt(uint64_t RHS) const { return ugt(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Signed greather than comparison
+  ///
+  /// Regards both *this and RHS as signed quantities and compares them for the
+  /// validity of the greater-than relationship.
+  ///
+  /// \returns true if *this > RHS when both are considered signed.
+  bool sgt(const APInt &RHS) const { return !slt(RHS) && !eq(RHS); }
+
+  /// \brief Signed greater than comparison
+  ///
+  /// Regards both *this as a signed quantity and compares it with RHS for
+  /// the validity of the greater-than relationship.
+  ///
+  /// \returns true if *this > RHS when considered signed.
+  bool sgt(uint64_t RHS) const { return sgt(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Unsigned greater or equal comparison
+  ///
+  /// Regards both *this and RHS as unsigned quantities and compares them for
+  /// validity of the greater-or-equal relationship.
+  ///
+  /// \returns true if *this >= RHS when both are considered unsigned.
+  bool uge(const APInt &RHS) const { return !ult(RHS); }
+
+  /// \brief Unsigned greater or equal comparison
+  ///
+  /// Regards both *this as an unsigned quantity and compares it with RHS for
+  /// the validity of the greater-or-equal relationship.
+  ///
+  /// \returns true if *this >= RHS when considered unsigned.
+  bool uge(uint64_t RHS) const { return uge(APInt(getBitWidth(), RHS)); }
+
+  /// \brief Signed greather or equal comparison
+  ///
+  /// Regards both *this and RHS as signed quantities and compares them for
+  /// validity of the greater-or-equal relationship.
+  ///
+  /// \returns true if *this >= RHS when both are considered signed.
+  bool sge(const APInt &RHS) const { return !slt(RHS); }
+
+  /// \brief Signed greater or equal comparison
+  ///
+  /// Regards both *this as a signed quantity and compares it with RHS for
+  /// the validity of the greater-or-equal relationship.
+  ///
+  /// \returns true if *this >= RHS when considered signed.
+  bool sge(uint64_t RHS) const { return sge(APInt(getBitWidth(), RHS)); }
+
+  /// This operation tests if there are any pairs of corresponding bits
+  /// between this APInt and RHS that are both set.
+  bool intersects(const APInt &RHS) const { return (*this & RHS) != 0; }
+
+  /// @}
+  /// \name Resizing Operators
+  /// @{
+
+  /// \brief Truncate to new width.
+  ///
+  /// Truncate the APInt to a specified width. It is an error to specify a width
+  /// that is greater than or equal to the current width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(unsigned width) const;
+
+  /// \brief Sign extend to a new width.
+  ///
+  /// This operation sign extends the APInt to a new width. If the high order
+  /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
+  /// It is an error to specify a width that is less than or equal to the
+  /// current width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT sext(unsigned width) const;
+
+  /// \brief Zero extend to a new width.
+  ///
+  /// This operation zero extends the APInt to a new width. The high order bits
+  /// are filled with 0 bits.  It is an error to specify a width that is less
+  /// than or equal to the current width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT zext(unsigned width) const;
+
+  /// \brief Sign extend or truncate to width
+  ///
+  /// Make this APInt have the bit width given by \p width. The value is sign
+  /// extended, truncated, or left alone to make it that width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrTrunc(unsigned width) const;
+
+  /// \brief Zero extend or truncate to width
+  ///
+  /// Make this APInt have the bit width given by \p width. The value is zero
+  /// extended, truncated, or left alone to make it that width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrTrunc(unsigned width) const;
+
+  /// \brief Sign extend or truncate to width
+  ///
+  /// Make this APInt have the bit width given by \p width. The value is sign
+  /// extended, or left alone to make it that width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrSelf(unsigned width) const;
+
+  /// \brief Zero extend or truncate to width
+  ///
+  /// Make this APInt have the bit width given by \p width. The value is zero
+  /// extended, or left alone to make it that width.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrSelf(unsigned width) const;
+
+  /// @}
+  /// \name Bit Manipulation Operators
+  /// @{
+
+  /// \brief Set every bit to 1.
+  void setAllBits() {
+    if (isSingleWord())
+      VAL = UINT64_MAX;
+    else {
+      // Set all the bits in all the words.
+      for (unsigned i = 0; i < getNumWords(); ++i)
+        pVal[i] = UINT64_MAX;
+    }
+    // Clear the unused ones
+    clearUnusedBits();
+  }
+
+  /// \brief Set a given bit to 1.
+  ///
+  /// Set the given bit to 1 whose position is given as "bitPosition".
+  void setBit(unsigned bitPosition);
+
+  /// \brief Set every bit to 0.
+  void clearAllBits() {
+    if (isSingleWord())
+      VAL = 0;
+    else
+      memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+  }
+
+  /// \brief Set a given bit to 0.
+  ///
+  /// Set the given bit to 0 whose position is given as "bitPosition".
+  void clearBit(unsigned bitPosition);
+
+  /// \brief Toggle every bit to its opposite value.
+  void flipAllBits() {
+    if (isSingleWord())
+      VAL ^= UINT64_MAX;
+    else {
+      for (unsigned i = 0; i < getNumWords(); ++i)
+        pVal[i] ^= UINT64_MAX;
+    }
+    clearUnusedBits();
+  }
+
+  /// \brief Toggles a given bit to its opposite value.
+  ///
+  /// Toggle a given bit to its opposite value whose position is given
+  /// as "bitPosition".
+  void flipBit(unsigned bitPosition);
+
+  /// @}
+  /// \name Value Characterization Functions
+  /// @{
+
+  /// \brief Return the number of bits in the APInt.
+  unsigned getBitWidth() const { return BitWidth; }
+
+  /// \brief Get the number of words.
+  ///
+  /// Here one word's bitwidth equals to that of uint64_t.
+  ///
+  /// \returns the number of words to hold the integer value of this APInt.
+  unsigned getNumWords() const { return getNumWords(BitWidth); }
+
+  /// \brief Get the number of words.
+  ///
+  /// *NOTE* Here one word's bitwidth equals to that of uint64_t.
+  ///
+  /// \returns the number of words to hold the integer value with a given bit
+  /// width.
+  static unsigned getNumWords(unsigned BitWidth) {
+    return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+  }
+
+  /// \brief Compute the number of active bits in the value
+  ///
+  /// This function returns the number of active bits which is defined as the
+  /// bit width minus the number of leading zeros. This is used in several
+  /// computations to see how "wide" the value is.
+  unsigned getActiveBits() const { return BitWidth - countLeadingZeros(); }
+
+  /// \brief Compute the number of active words in the value of this APInt.
+  ///
+  /// This is used in conjunction with getActiveData to extract the raw value of
+  /// the APInt.
+  unsigned getActiveWords() const {
+    unsigned numActiveBits = getActiveBits();
+    return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
+  }
+
+  /// \brief Get the minimum bit size for this signed APInt
+  ///
+  /// Computes the minimum bit width for this APInt while considering it to be a
+  /// signed (and probably negative) value. If the value is not negative, this
+  /// function returns the same value as getActiveBits()+1. Otherwise, it
+  /// returns the smallest bit width that will retain the negative value. For
+  /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
+  /// for -1, this function will always return 1.
+  unsigned getMinSignedBits() const {
+    if (isNegative())
+      return BitWidth - countLeadingOnes() + 1;
+    return getActiveBits() + 1;
+  }
+
+  /// \brief Get zero extended value
+  ///
+  /// This method attempts to return the value of this APInt as a zero extended
+  /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
+  /// uint64_t. Otherwise an assertion will result.
+  uint64_t getZExtValue() const {
+    if (isSingleWord())
+      return VAL;
+    assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
+    return pVal[0];
+  }
+
+  /// \brief Get sign extended value
+  ///
+  /// This method attempts to return the value of this APInt as a sign extended
+  /// int64_t. The bit width must be <= 64 or the value must fit within an
+  /// int64_t. Otherwise an assertion will result.
+  int64_t getSExtValue() const {
+    if (isSingleWord())
+      return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
+             (APINT_BITS_PER_WORD - BitWidth);
+    assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
+    return int64_t(pVal[0]);
+  }
+
+  /// \brief Get bits required for string value.
+  ///
+  /// This method determines how many bits are required to hold the APInt
+  /// equivalent of the string given by \p str.
+  static unsigned getBitsNeeded(StringRef str, uint8_t radix);
+
+  /// \brief The APInt version of the countLeadingZeros functions in
+  ///   MathExtras.h.
+  ///
+  /// It counts the number of zeros from the most significant bit to the first
+  /// one bit.
+  ///
+  /// \returns BitWidth if the value is zero, otherwise returns the number of
+  ///   zeros from the most significant bit to the first one bits.
+  unsigned countLeadingZeros() const {
+    if (isSingleWord()) {
+      unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
+      return llvm::countLeadingZeros(VAL) - unusedBits;
+    }
+    return countLeadingZerosSlowCase();
+  }
+
+  /// \brief Count the number of leading one bits.
+  ///
+  /// This function is an APInt version of the countLeadingOnes_{32,64}
+  /// functions in MathExtras.h. It counts the number of ones from the most
+  /// significant bit to the first zero bit.
+  ///
+  /// \returns 0 if the high order bit is not set, otherwise returns the number
+  /// of 1 bits from the most significant to the least
+  unsigned countLeadingOnes() const;
+
+  /// Computes the number of leading bits of this APInt that are equal to its
+  /// sign bit.
+  unsigned getNumSignBits() const {
+    return isNegative() ? countLeadingOnes() : countLeadingZeros();
+  }
+
+  /// \brief Count the number of trailing zero bits.
+  ///
+  /// This function is an APInt version of the countTrailingZeros_{32,64}
+  /// functions in MathExtras.h. It counts the number of zeros from the least
+  /// significant bit to the first set bit.
+  ///
+  /// \returns BitWidth if the value is zero, otherwise returns the number of
+  /// zeros from the least significant bit to the first one bit.
+  unsigned countTrailingZeros() const;
+
+  /// \brief Count the number of trailing one bits.
+  ///
+  /// This function is an APInt version of the countTrailingOnes_{32,64}
+  /// functions in MathExtras.h. It counts the number of ones from the least
+  /// significant bit to the first zero bit.
+  ///
+  /// \returns BitWidth if the value is all ones, otherwise returns the number
+  /// of ones from the least significant bit to the first zero bit.
+  unsigned countTrailingOnes() const {
+    if (isSingleWord())
+      return CountTrailingOnes_64(VAL);
+    return countTrailingOnesSlowCase();
+  }
+
+  /// \brief Count the number of bits set.
+  ///
+  /// This function is an APInt version of the countPopulation_{32,64} functions
+  /// in MathExtras.h. It counts the number of 1 bits in the APInt value.
+  ///
+  /// \returns 0 if the value is zero, otherwise returns the number of set bits.
+  unsigned countPopulation() const {
+    if (isSingleWord())
+      return CountPopulation_64(VAL);
+    return countPopulationSlowCase();
+  }
+
+  /// @}
+  /// \name Conversion Functions
+  /// @{
+  void print(raw_ostream &OS, bool isSigned) const;
+
+  /// Converts an APInt to a string and append it to Str.  Str is commonly a
+  /// SmallString.
+  void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
+                bool formatAsCLiteral = false) const;
+
+  /// Considers the APInt to be unsigned and converts it into a string in the
+  /// radix given. The radix can be 2, 8, 10 16, or 36.
+  void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+    toString(Str, Radix, false, false);
+  }
+
+  /// Considers the APInt to be signed and converts it into a string in the
+  /// radix given. The radix can be 2, 8, 10, 16, or 36.
+  void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+    toString(Str, Radix, true, false);
+  }
+
+  /// \brief Return the APInt as a std::string.
+  ///
+  /// Note that this is an inefficient method.  It is better to pass in a
+  /// SmallVector/SmallString to the methods above to avoid thrashing the heap
+  /// for the string.
+  std::string toString(unsigned Radix, bool Signed) const;
+
+  /// \returns a byte-swapped representation of this APInt Value.
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT byteSwap() const;
+
+  /// \brief Converts this APInt to a double value.
+  double roundToDouble(bool isSigned) const;
+
+  /// \brief Converts this unsigned APInt to a double value.
+  double roundToDouble() const { return roundToDouble(false); }
+
+  /// \brief Converts this signed APInt to a double value.
+  double signedRoundToDouble() const { return roundToDouble(true); }
+
+  /// \brief Converts APInt bits to a double
+  ///
+  /// The conversion does not do a translation from integer to double, it just
+  /// re-interprets the bits as a double. Note that it is valid to do this on
+  /// any bit width. Exactly 64 bits will be translated.
+  double bitsToDouble() const {
+    union {
+      uint64_t I;
+      double D;
+    } T;
+    T.I = (isSingleWord() ? VAL : pVal[0]);
+    return T.D;
+  }
+
+  /// \brief Converts APInt bits to a double
+  ///
+  /// The conversion does not do a translation from integer to float, it just
+  /// re-interprets the bits as a float. Note that it is valid to do this on
+  /// any bit width. Exactly 32 bits will be translated.
+  float bitsToFloat() const {
+    union {
+      unsigned I;
+      float F;
+    } T;
+    T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
+    return T.F;
+  }
+
+  /// \brief Converts a double to APInt bits.
+  ///
+  /// The conversion does not do a translation from double to integer, it just
+  /// re-interprets the bits of the double.
+  static APInt LLVM_ATTRIBUTE_UNUSED_RESULT doubleToBits(double V) {
+    union {
+      uint64_t I;
+      double D;
+    } T;
+    T.D = V;
+    return APInt(sizeof T * CHAR_BIT, T.I);
+  }
+
+  /// \brief Converts a float to APInt bits.
+  ///
+  /// The conversion does not do a translation from float to integer, it just
+  /// re-interprets the bits of the float.
+  static APInt LLVM_ATTRIBUTE_UNUSED_RESULT floatToBits(float V) {
+    union {
+      unsigned I;
+      float F;
+    } T;
+    T.F = V;
+    return APInt(sizeof T * CHAR_BIT, T.I);
+  }
+
+  /// @}
+  /// \name Mathematics Operations
+  /// @{
+
+  /// \returns the floor log base 2 of this APInt.
+  unsigned logBase2() const { return BitWidth - 1 - countLeadingZeros(); }
+
+  /// \returns the ceil log base 2 of this APInt.
+  unsigned ceilLogBase2() const {
+    return BitWidth - (*this - 1).countLeadingZeros();
+  }
+
+  /// \returns the nearest log base 2 of this APInt. Ties round up.
+  ///
+  /// NOTE: When we have a BitWidth of 1, we define:
+  /// 
+  ///   log2(0) = UINT32_MAX
+  ///   log2(1) = 0
+  ///
+  /// to get around any mathematical concerns resulting from
+  /// referencing 2 in a space where 2 does no exist.
+  unsigned nearestLogBase2() const {
+    // Special case when we have a bitwidth of 1. If VAL is 1, then we
+    // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+    // UINT32_MAX.
+    if (BitWidth == 1)
+      return VAL - 1;
+
+    // Handle the zero case.
+    if (!getBoolValue())
+      return UINT32_MAX;
+
+    // The non-zero case is handled by computing:
+    //
+    //   nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1].
+    //
+    // where x[i] is referring to the value of the ith bit of x.
+    unsigned lg = logBase2();
+    return lg + unsigned((*this)[lg - 1]);
+  }
+
+  /// \returns the log base 2 of this APInt if its an exact power of two, -1
+  /// otherwise
+  int32_t exactLogBase2() const {
+    if (!isPowerOf2())
+      return -1;
+    return logBase2();
+  }
+
+  /// \brief Compute the square root
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT sqrt() const;
+
+  /// \brief Get the absolute value;
+  ///
+  /// If *this is < 0 then return -(*this), otherwise *this;
+  APInt LLVM_ATTRIBUTE_UNUSED_RESULT abs() const {
+    if (isNegative())
+      return -(*this);
+    return *this;
+  }
+
+  /// \returns the multiplicative inverse for a given modulo.
+  APInt multiplicativeInverse(const APInt &modulo) const;
+
+  /// @}
+  /// \name Support for division by constant
+  /// @{
+
+  /// Calculate the magic number for signed division by a constant.
+  struct ms;
+  ms magic() const;
+
+  /// Calculate the magic number for unsigned division by a constant.
+  struct mu;
+  mu magicu(unsigned LeadingZeros = 0) const;
+
+  /// @}
+  /// \name Building-block Operations for APInt and APFloat
+  /// @{
+
+  // These building block operations operate on a representation of arbitrary
+  // precision, two's-complement, bignum integer values. They should be
+  // sufficient to implement APInt and APFloat bignum requirements. Inputs are
+  // generally a pointer to the base of an array of integer parts, representing
+  // an unsigned bignum, and a count of how many parts there are.
+
+  /// Sets the least significant part of a bignum to the input value, and zeroes
+  /// out higher parts.
+  static void tcSet(integerPart *, integerPart, unsigned int);
+
+  /// Assign one bignum to another.
+  static void tcAssign(integerPart *, const integerPart *, unsigned int);
+
+  /// Returns true if a bignum is zero, false otherwise.
+  static bool tcIsZero(const integerPart *, unsigned int);
+
+  /// Extract the given bit of a bignum; returns 0 or 1.  Zero-based.
+  static int tcExtractBit(const integerPart *, unsigned int bit);
+
+  /// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
+  /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
+  /// significant bit of DST.  All high bits above srcBITS in DST are
+  /// zero-filled.
+  static void tcExtract(integerPart *, unsigned int dstCount,
+                        const integerPart *, unsigned int srcBits,
+                        unsigned int srcLSB);
+
+  /// Set the given bit of a bignum.  Zero-based.
+  static void tcSetBit(integerPart *, unsigned int bit);
+
+  /// Clear the given bit of a bignum.  Zero-based.
+  static void tcClearBit(integerPart *, unsigned int bit);
+
+  /// Returns the bit number of the least or most significant set bit of a
+  /// number.  If the input number has no bits set -1U is returned.
+  static unsigned int tcLSB(const integerPart *, unsigned int);
+  static unsigned int tcMSB(const integerPart *parts, unsigned int n);
+
+  /// Negate a bignum in-place.
+  static void tcNegate(integerPart *, unsigned int);
+
+  /// DST += RHS + CARRY where CARRY is zero or one.  Returns the carry flag.
+  static integerPart tcAdd(integerPart *, const integerPart *,
+                           integerPart carry, unsigned);
+
+  /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
+  static integerPart tcSubtract(integerPart *, const integerPart *,
+                                integerPart carry, unsigned);
+
+  /// DST += SRC * MULTIPLIER + PART   if add is true
+  /// DST  = SRC * MULTIPLIER + PART   if add is false
+  ///
+  /// Requires 0 <= DSTPARTS <= SRCPARTS + 1.  If DST overlaps SRC they must
+  /// start at the same point, i.e. DST == SRC.
+  ///
+  /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is returned.
+  /// Otherwise DST is filled with the least significant DSTPARTS parts of the
+  /// result, and if all of the omitted higher parts were zero return zero,
+  /// otherwise overflow occurred and return one.
+  static int tcMultiplyPart(integerPart *dst, const integerPart *src,
+                            integerPart multiplier, integerPart carry,
+                            unsigned int srcParts, unsigned int dstParts,
+                            bool add);
+
+  /// DST = LHS * RHS, where DST has the same width as the operands and is
+  /// filled with the least significant parts of the result.  Returns one if
+  /// overflow occurred, otherwise zero.  DST must be disjoint from both
+  /// operands.
+  static int tcMultiply(integerPart *, const integerPart *, const integerPart *,
+                        unsigned);
+
+  /// DST = LHS * RHS, where DST has width the sum of the widths of the
+  /// operands.  No overflow occurs.  DST must be disjoint from both
+  /// operands. Returns the number of parts required to hold the result.
+  static unsigned int tcFullMultiply(integerPart *, const integerPart *,
+                                     const integerPart *, unsigned, unsigned);
+
+  /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
+  /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
+  /// REMAINDER to the remainder, return zero.  i.e.
+  ///
+  ///  OLD_LHS = RHS * LHS + REMAINDER
+  ///
+  /// SCRATCH is a bignum of the same size as the operands and result for use by
+  /// the routine; its contents need not be initialized and are destroyed.  LHS,
+  /// REMAINDER and SCRATCH must be distinct.
+  static int tcDivide(integerPart *lhs, const integerPart *rhs,
+                      integerPart *remainder, integerPart *scratch,
+                      unsigned int parts);
+
+  /// Shift a bignum left COUNT bits.  Shifted in bits are zero.  There are no
+  /// restrictions on COUNT.
+  static void tcShiftLeft(integerPart *, unsigned int parts,
+                          unsigned int count);
+
+  /// Shift a bignum right COUNT bits.  Shifted in bits are zero.  There are no
+  /// restrictions on COUNT.
+  static void tcShiftRight(integerPart *, unsigned int parts,
+                           unsigned int count);
+
+  /// The obvious AND, OR and XOR and complement operations.
+  static void tcAnd(integerPart *, const integerPart *, unsigned int);
+  static void tcOr(integerPart *, const integerPart *, unsigned int);
+  static void tcXor(integerPart *, const integerPart *, unsigned int);
+  static void tcComplement(integerPart *, unsigned int);
+
+  /// Comparison (unsigned) of two bignums.
+  static int tcCompare(const integerPart *, const integerPart *, unsigned int);
+
+  /// Increment a bignum in-place.  Return the carry flag.
+  static integerPart tcIncrement(integerPart *, unsigned int);
+
+  /// Decrement a bignum in-place.  Return the borrow flag.
+  static integerPart tcDecrement(integerPart *, unsigned int);
+
+  /// Set the least significant BITS and clear the rest.
+  static void tcSetLeastSignificantBits(integerPart *, unsigned int,
+                                        unsigned int bits);
+
+  /// \brief debug method
+  void dump() const;
+
+  /// @}
+};
+
+/// Magic data for optimising signed division by a constant.
+struct APInt::ms {
+  APInt m;    ///< magic number
+  unsigned s; ///< shift amount
+};
+
+/// Magic data for optimising unsigned division by a constant.
+struct APInt::mu {
+  APInt m;    ///< magic number
+  bool a;     ///< add indicator
+  unsigned s; ///< shift amount
+};
+
+inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
+
+inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
+  I.print(OS, true);
+  return OS;
+}
+
+namespace APIntOps {
+
+/// \brief Determine the smaller of two APInts considered to be signed.
+inline APInt smin(const APInt &A, const APInt &B) { return A.slt(B) ? A : B; }
+
+/// \brief Determine the larger of two APInts considered to be signed.
+inline APInt smax(const APInt &A, const APInt &B) { return A.sgt(B) ? A : B; }
+
+/// \brief Determine the smaller of two APInts considered to be signed.
+inline APInt umin(const APInt &A, const APInt &B) { return A.ult(B) ? A : B; }
+
+/// \brief Determine the larger of two APInts considered to be unsigned.
+inline APInt umax(const APInt &A, const APInt &B) { return A.ugt(B) ? A : B; }
+
+/// \brief Check if the specified APInt has a N-bits unsigned integer value.
+inline bool isIntN(unsigned N, const APInt &APIVal) { return APIVal.isIntN(N); }
+
+/// \brief Check if the specified APInt has a N-bits signed integer value.
+inline bool isSignedIntN(unsigned N, const APInt &APIVal) {
+  return APIVal.isSignedIntN(N);
+}
+
+/// \returns true if the argument APInt value is a sequence of ones starting at
+/// the least significant bit with the remainder zero.
+inline bool isMask(unsigned numBits, const APInt &APIVal) {
+  return numBits <= APIVal.getBitWidth() &&
+         APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits);
+}
+
+/// \brief Return true if the argument APInt value contains a sequence of ones
+/// with the remainder zero.
+inline bool isShiftedMask(unsigned numBits, const APInt &APIVal) {
+  return isMask(numBits, (APIVal - APInt(numBits, 1)) | APIVal);
+}
+
+/// \brief Returns a byte-swapped representation of the specified APInt Value.
+inline APInt byteSwap(const APInt &APIVal) { return APIVal.byteSwap(); }
+
+/// \brief Returns the floor log base 2 of the specified APInt value.
+inline unsigned logBase2(const APInt &APIVal) { return APIVal.logBase2(); }
+
+/// \brief Compute GCD of two APInt values.
+///
+/// This function returns the greatest common divisor of the two APInt values
+/// using Euclid's algorithm.
+///
+/// \returns the greatest common divisor of Val1 and Val2
+APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2);
+
+/// \brief Converts the given APInt to a double value.
+///
+/// Treats the APInt as an unsigned value for conversion purposes.
+inline double RoundAPIntToDouble(const APInt &APIVal) {
+  return APIVal.roundToDouble();
+}
+
+/// \brief Converts the given APInt to a double value.
+///
+/// Treats the APInt as a signed value for conversion purposes.
+inline double RoundSignedAPIntToDouble(const APInt &APIVal) {
+  return APIVal.signedRoundToDouble();
+}
+
+/// \brief Converts the given APInt to a float vlalue.
+inline float RoundAPIntToFloat(const APInt &APIVal) {
+  return float(RoundAPIntToDouble(APIVal));
+}
+
+/// \brief Converts the given APInt to a float value.
+///
+/// Treast the APInt as a signed value for conversion purposes.
+inline float RoundSignedAPIntToFloat(const APInt &APIVal) {
+  return float(APIVal.signedRoundToDouble());
+}
+
+/// \brief Converts the given double value into a APInt.
+///
+/// This function convert a double value to an APInt value.
+APInt RoundDoubleToAPInt(double Double, unsigned width);
+
+/// \brief Converts a float value into a APInt.
+///
+/// Converts a float value into an APInt value.
+inline APInt RoundFloatToAPInt(float Float, unsigned width) {
+  return RoundDoubleToAPInt(double(Float), width);
+}
+
+/// \brief Arithmetic right-shift function.
+///
+/// Arithmetic right-shift the APInt by shiftAmt.
+inline APInt ashr(const APInt &LHS, unsigned shiftAmt) {
+  return LHS.ashr(shiftAmt);
+}
+
+/// \brief Logical right-shift function.
+///
+/// Logical right-shift the APInt by shiftAmt.
+inline APInt lshr(const APInt &LHS, unsigned shiftAmt) {
+  return LHS.lshr(shiftAmt);
+}
+
+/// \brief Left-shift function.
+///
+/// Left-shift the APInt by shiftAmt.
+inline APInt shl(const APInt &LHS, unsigned shiftAmt) {
+  return LHS.shl(shiftAmt);
+}
+
+/// \brief Signed division function for APInt.
+///
+/// Signed divide APInt LHS by APInt RHS.
+inline APInt sdiv(const APInt &LHS, const APInt &RHS) { return LHS.sdiv(RHS); }
+
+/// \brief Unsigned division function for APInt.
+///
+/// Unsigned divide APInt LHS by APInt RHS.
+inline APInt udiv(const APInt &LHS, const APInt &RHS) { return LHS.udiv(RHS); }
+
+/// \brief Function for signed remainder operation.
+///
+/// Signed remainder operation on APInt.
+inline APInt srem(const APInt &LHS, const APInt &RHS) { return LHS.srem(RHS); }
+
+/// \brief Function for unsigned remainder operation.
+///
+/// Unsigned remainder operation on APInt.
+inline APInt urem(const APInt &LHS, const APInt &RHS) { return LHS.urem(RHS); }
+
+/// \brief Function for multiplication operation.
+///
+/// Performs multiplication on APInt values.
+inline APInt mul(const APInt &LHS, const APInt &RHS) { return LHS * RHS; }
+
+/// \brief Function for addition operation.
+///
+/// Performs addition on APInt values.
+inline APInt add(const APInt &LHS, const APInt &RHS) { return LHS + RHS; }
+
+/// \brief Function for subtraction operation.
+///
+/// Performs subtraction on APInt values.
+inline APInt sub(const APInt &LHS, const APInt &RHS) { return LHS - RHS; }
+
+/// \brief Bitwise AND function for APInt.
+///
+/// Performs bitwise AND operation on APInt LHS and
+/// APInt RHS.
+inline APInt And(const APInt &LHS, const APInt &RHS) { return LHS & RHS; }
+
+/// \brief Bitwise OR function for APInt.
+///
+/// Performs bitwise OR operation on APInt LHS and APInt RHS.
+inline APInt Or(const APInt &LHS, const APInt &RHS) { return LHS | RHS; }
+
+/// \brief Bitwise XOR function for APInt.
+///
+/// Performs bitwise XOR operation on APInt.
+inline APInt Xor(const APInt &LHS, const APInt &RHS) { return LHS ^ RHS; }
+
+/// \brief Bitwise complement function.
+///
+/// Performs a bitwise complement operation on APInt.
+inline APInt Not(const APInt &APIVal) { return ~APIVal; }
+
+} // End of APIntOps namespace
+
+// See friend declaration above. This additional declaration is required in
+// order to compile LLVM with IBM xlC compiler.
+hash_code hash_value(const APInt &Arg);
+} // End of llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
new file mode 100644
index 0000000..ee34e9b
--- /dev/null
+++ b/include/llvm/ADT/APSInt.h
@@ -0,0 +1,306 @@
+//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
+//
+//                     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 APSInt class, which is a simple class that
+// represents an arbitrary sized integer that knows its signedness.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_APSINT_H
+#define LLVM_ADT_APSINT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+class APSInt : public APInt {
+  bool IsUnsigned;
+public:
+  /// Default constructor that creates an uninitialized APInt.
+  explicit APSInt() : IsUnsigned(false) {}
+
+  /// APSInt ctor - Create an APSInt with the specified width, default to
+  /// unsigned.
+  explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
+   : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
+
+  explicit APSInt(APInt I, bool isUnsigned = true)
+   : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
+
+  APSInt &operator=(APInt RHS) {
+    // Retain our current sign.
+    APInt::operator=(std::move(RHS));
+    return *this;
+  }
+
+  APSInt &operator=(uint64_t RHS) {
+    // Retain our current sign.
+    APInt::operator=(RHS);
+    return *this;
+  }
+
+  // Query sign information.
+  bool isSigned() const { return !IsUnsigned; }
+  bool isUnsigned() const { return IsUnsigned; }
+  void setIsUnsigned(bool Val) { IsUnsigned = Val; }
+  void setIsSigned(bool Val) { IsUnsigned = !Val; }
+
+  /// toString - Append this APSInt to the specified SmallString.
+  void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+    APInt::toString(Str, Radix, isSigned());
+  }
+  /// toString - Converts an APInt to a std::string.  This is an inefficient
+  /// method; you should prefer passing in a SmallString instead.
+  std::string toString(unsigned Radix) const {
+    return APInt::toString(Radix, isSigned());
+  }
+  using APInt::toString;
+
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const {
+    return APSInt(APInt::trunc(width), IsUnsigned);
+  }
+
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extend(uint32_t width) const {
+    if (IsUnsigned)
+      return APSInt(zext(width), IsUnsigned);
+    else
+      return APSInt(sext(width), IsUnsigned);
+  }
+
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extOrTrunc(uint32_t width) const {
+      if (IsUnsigned)
+        return APSInt(zextOrTrunc(width), IsUnsigned);
+      else
+        return APSInt(sextOrTrunc(width), IsUnsigned);
+  }
+
+  const APSInt &operator%=(const APSInt &RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    if (IsUnsigned)
+      *this = urem(RHS);
+    else
+      *this = srem(RHS);
+    return *this;
+  }
+  const APSInt &operator/=(const APSInt &RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    if (IsUnsigned)
+      *this = udiv(RHS);
+    else
+      *this = sdiv(RHS);
+    return *this;
+  }
+  APSInt operator%(const APSInt &RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
+  }
+  APSInt operator/(const APSInt &RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
+  }
+
+  APSInt operator>>(unsigned Amt) const {
+    return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
+  }
+  APSInt& operator>>=(unsigned Amt) {
+    *this = *this >> Amt;
+    return *this;
+  }
+
+  inline bool operator<(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? ult(RHS) : slt(RHS);
+  }
+  inline bool operator>(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? ugt(RHS) : sgt(RHS);
+  }
+  inline bool operator<=(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? ule(RHS) : sle(RHS);
+  }
+  inline bool operator>=(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return IsUnsigned ? uge(RHS) : sge(RHS);
+  }
+  inline bool operator==(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return eq(RHS);
+  }
+  inline bool operator==(int64_t RHS) const {
+    return isSameValue(*this, APSInt(APInt(64, RHS), true));
+  }
+  inline bool operator!=(const APSInt& RHS) const {
+    return !((*this) == RHS);
+  }
+  inline bool operator!=(int64_t RHS) const {
+    return !((*this) == RHS);
+  }
+
+  // The remaining operators just wrap the logic of APInt, but retain the
+  // signedness information.
+
+  APSInt operator<<(unsigned Bits) const {
+    return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
+  }
+  APSInt& operator<<=(unsigned Amt) {
+    *this = *this << Amt;
+    return *this;
+  }
+
+  APSInt& operator++() {
+    ++(static_cast<APInt&>(*this));
+    return *this;
+  }
+  APSInt& operator--() {
+    --(static_cast<APInt&>(*this));
+    return *this;
+  }
+  APSInt operator++(int) {
+    return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
+  }
+  APSInt operator--(int) {
+    return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
+  }
+  APSInt operator-() const {
+    return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
+  }
+  APSInt& operator+=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) += RHS;
+    return *this;
+  }
+  APSInt& operator-=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) -= RHS;
+    return *this;
+  }
+  APSInt& operator*=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) *= RHS;
+    return *this;
+  }
+  APSInt& operator&=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) &= RHS;
+    return *this;
+  }
+  APSInt& operator|=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) |= RHS;
+    return *this;
+  }
+  APSInt& operator^=(const APSInt& RHS) {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    static_cast<APInt&>(*this) ^= RHS;
+    return *this;
+  }
+
+  APSInt operator&(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
+  }
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APSInt& RHS) const {
+    return this->operator&(RHS);
+  }
+
+  APSInt operator|(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
+  }
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APSInt& RHS) const {
+    return this->operator|(RHS);
+  }
+
+
+  APSInt operator^(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
+  }
+  APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APSInt& RHS) const {
+    return this->operator^(RHS);
+  }
+
+  APSInt operator*(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
+  }
+  APSInt operator+(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
+  }
+  APSInt operator-(const APSInt& RHS) const {
+    assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+    return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
+  }
+  APSInt operator~() const {
+    return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
+  }
+
+  /// getMaxValue - Return the APSInt representing the maximum integer value
+  ///  with the given bit width and signedness.
+  static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
+    return APSInt(Unsigned ? APInt::getMaxValue(numBits)
+                           : APInt::getSignedMaxValue(numBits), Unsigned);
+  }
+
+  /// getMinValue - Return the APSInt representing the minimum integer value
+  ///  with the given bit width and signedness.
+  static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
+    return APSInt(Unsigned ? APInt::getMinValue(numBits)
+                           : APInt::getSignedMinValue(numBits), Unsigned);
+  }
+
+  /// \brief Determine if two APSInts have the same value, zero- or
+  /// sign-extending as needed.  
+  static bool isSameValue(const APSInt &I1, const APSInt &I2) {
+    if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
+      return I1 == I2;
+
+    // Check for a bit-width mismatch.
+    if (I1.getBitWidth() > I2.getBitWidth())
+      return isSameValue(I1, I2.extend(I1.getBitWidth()));
+    else if (I2.getBitWidth() > I1.getBitWidth())
+      return isSameValue(I1.extend(I2.getBitWidth()), I2);
+
+    // We have a signedness mismatch. Turn the signed value into an unsigned
+    // value.
+    if (I1.isSigned()) {
+      if (I1.isNegative())
+        return false;
+
+      return APSInt(I1, true) == I2;
+    }
+
+    if (I2.isNegative())
+      return false;
+
+    return I1 == APSInt(I2, true);
+  }
+
+  /// Profile - Used to insert APSInt objects, or objects that contain APSInt
+  ///  objects, into FoldingSets.
+  void Profile(FoldingSetNodeID& ID) const;
+};
+
+inline bool operator==(int64_t V1, const APSInt& V2) {
+  return V2 == V1;
+}
+inline bool operator!=(int64_t V1, const APSInt& V2) {
+  return V2 != V1;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
+  I.print(OS, I.isSigned());
+  return OS;
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
new file mode 100644
index 0000000..0fff505
--- /dev/null
+++ b/include/llvm/ADT/ArrayRef.h
@@ -0,0 +1,339 @@
+//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ARRAYREF_H
+#define LLVM_ADT_ARRAYREF_H
+
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace llvm {
+
+  /// ArrayRef - Represent a constant reference to an array (0 or more elements
+  /// consecutively in memory), i.e. a start pointer and a length.  It allows
+  /// various APIs to take consecutive elements easily and conveniently.
+  ///
+  /// This class does not own the underlying data, it is expected to be used in
+  /// situations where the data resides in some other buffer, whose lifetime
+  /// extends past that of the ArrayRef. For this reason, it is not in general
+  /// safe to store an ArrayRef.
+  ///
+  /// This is intended to be trivially copyable, so it should be passed by
+  /// value.
+  template<typename T>
+  class ArrayRef {
+  public:
+    typedef const T *iterator;
+    typedef const T *const_iterator;
+    typedef size_t size_type;
+
+    typedef std::reverse_iterator<iterator> reverse_iterator;
+
+  private:
+    /// The start of the array, in an external buffer.
+    const T *Data;
+
+    /// The number of elements.
+    size_type Length;
+
+  public:
+    /// @name Constructors
+    /// @{
+
+    /// Construct an empty ArrayRef.
+    /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {}
+
+    /// Construct an empty ArrayRef from None.
+    /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {}
+
+    /// Construct an ArrayRef from a single element.
+    /*implicit*/ ArrayRef(const T &OneElt)
+      : Data(&OneElt), Length(1) {}
+
+    /// Construct an ArrayRef from a pointer and length.
+    /*implicit*/ ArrayRef(const T *data, size_t length)
+      : Data(data), Length(length) {}
+
+    /// Construct an ArrayRef from a range.
+    ArrayRef(const T *begin, const T *end)
+      : Data(begin), Length(end - begin) {}
+
+    /// Construct an ArrayRef from a SmallVector. This is templated in order to
+    /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
+    /// copy-construct an ArrayRef.
+    template<typename U>
+    /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
+      : Data(Vec.data()), Length(Vec.size()) {
+    }
+
+    /// Construct an ArrayRef from a std::vector.
+    template<typename A>
+    /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
+      : Data(Vec.data()), Length(Vec.size()) {}
+
+    /// Construct an ArrayRef from a C array.
+    template <size_t N>
+    /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N])
+      : Data(Arr), Length(N) {}
+
+#if LLVM_HAS_INITIALIZER_LISTS
+    /// Construct an ArrayRef from a std::initializer_list.
+    /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
+    : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
+      Length(Vec.size()) {}
+#endif
+
+    /// @}
+    /// @name Simple Operations
+    /// @{
+
+    iterator begin() const { return Data; }
+    iterator end() const { return Data + Length; }
+
+    reverse_iterator rbegin() const { return reverse_iterator(end()); }
+    reverse_iterator rend() const { return reverse_iterator(begin()); }
+
+    /// empty - Check if the array is empty.
+    bool empty() const { return Length == 0; }
+
+    const T *data() const { return Data; }
+
+    /// size - Get the array size.
+    size_t size() const { return Length; }
+
+    /// front - Get the first element.
+    const T &front() const {
+      assert(!empty());
+      return Data[0];
+    }
+
+    /// back - Get the last element.
+    const T &back() const {
+      assert(!empty());
+      return Data[Length-1];
+    }
+
+    // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
+    template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
+      T *Buff = A.template Allocate<T>(Length);
+      std::copy(begin(), end(), Buff);
+      return ArrayRef<T>(Buff, Length);
+    }
+
+    /// equals - Check for element-wise equality.
+    bool equals(ArrayRef RHS) const {
+      if (Length != RHS.Length)
+        return false;
+      return std::equal(begin(), end(), RHS.begin());
+    }
+
+    /// slice(n) - Chop off the first N elements of the array.
+    ArrayRef<T> slice(unsigned N) const {
+      assert(N <= size() && "Invalid specifier");
+      return ArrayRef<T>(data()+N, size()-N);
+    }
+
+    /// slice(n, m) - Chop off the first N elements of the array, and keep M
+    /// elements in the array.
+    ArrayRef<T> slice(unsigned N, unsigned M) const {
+      assert(N+M <= size() && "Invalid specifier");
+      return ArrayRef<T>(data()+N, M);
+    }
+
+    // \brief Drop the last \p N elements of the array.
+    ArrayRef<T> drop_back(unsigned N = 1) const {
+      assert(size() >= N && "Dropping more elements than exist");
+      return slice(0, size() - N);
+    }
+
+    /// @}
+    /// @name Operator Overloads
+    /// @{
+    const T &operator[](size_t Index) const {
+      assert(Index < Length && "Invalid index!");
+      return Data[Index];
+    }
+
+    /// @}
+    /// @name Expensive Operations
+    /// @{
+    std::vector<T> vec() const {
+      return std::vector<T>(Data, Data+Length);
+    }
+
+    /// @}
+    /// @name Conversion operators
+    /// @{
+    operator std::vector<T>() const {
+      return std::vector<T>(Data, Data+Length);
+    }
+
+    /// @}
+  };
+
+  /// MutableArrayRef - Represent a mutable reference to an array (0 or more
+  /// elements consecutively in memory), i.e. a start pointer and a length.  It
+  /// allows various APIs to take and modify consecutive elements easily and
+  /// conveniently.
+  ///
+  /// This class does not own the underlying data, it is expected to be used in
+  /// situations where the data resides in some other buffer, whose lifetime
+  /// extends past that of the MutableArrayRef. For this reason, it is not in
+  /// general safe to store a MutableArrayRef.
+  ///
+  /// This is intended to be trivially copyable, so it should be passed by
+  /// value.
+  template<typename T>
+  class MutableArrayRef : public ArrayRef<T> {
+  public:
+    typedef T *iterator;
+
+    typedef std::reverse_iterator<iterator> reverse_iterator;
+
+    /// Construct an empty MutableArrayRef.
+    /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
+
+    /// Construct an empty MutableArrayRef from None.
+    /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
+
+    /// Construct an MutableArrayRef from a single element.
+    /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
+
+    /// Construct an MutableArrayRef from a pointer and length.
+    /*implicit*/ MutableArrayRef(T *data, size_t length)
+      : ArrayRef<T>(data, length) {}
+
+    /// Construct an MutableArrayRef from a range.
+    MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
+
+    /// Construct an MutableArrayRef from a SmallVector.
+    /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
+    : ArrayRef<T>(Vec) {}
+
+    /// Construct a MutableArrayRef from a std::vector.
+    /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
+    : ArrayRef<T>(Vec) {}
+
+    /// Construct an MutableArrayRef from a C array.
+    template <size_t N>
+    /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N])
+      : ArrayRef<T>(Arr) {}
+
+    T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
+
+    iterator begin() const { return data(); }
+    iterator end() const { return data() + this->size(); }
+
+    reverse_iterator rbegin() const { return reverse_iterator(end()); }
+    reverse_iterator rend() const { return reverse_iterator(begin()); }
+
+    /// front - Get the first element.
+    T &front() const {
+      assert(!this->empty());
+      return data()[0];
+    }
+
+    /// back - Get the last element.
+    T &back() const {
+      assert(!this->empty());
+      return data()[this->size()-1];
+    }
+
+    /// slice(n) - Chop off the first N elements of the array.
+    MutableArrayRef<T> slice(unsigned N) const {
+      assert(N <= this->size() && "Invalid specifier");
+      return MutableArrayRef<T>(data()+N, this->size()-N);
+    }
+
+    /// slice(n, m) - Chop off the first N elements of the array, and keep M
+    /// elements in the array.
+    MutableArrayRef<T> slice(unsigned N, unsigned M) const {
+      assert(N+M <= this->size() && "Invalid specifier");
+      return MutableArrayRef<T>(data()+N, M);
+    }
+
+    /// @}
+    /// @name Operator Overloads
+    /// @{
+    T &operator[](size_t Index) const {
+      assert(Index < this->size() && "Invalid index!");
+      return data()[Index];
+    }
+  };
+
+  /// @name ArrayRef Convenience constructors
+  /// @{
+
+  /// Construct an ArrayRef from a single element.
+  template<typename T>
+  ArrayRef<T> makeArrayRef(const T &OneElt) {
+    return OneElt;
+  }
+
+  /// Construct an ArrayRef from a pointer and length.
+  template<typename T>
+  ArrayRef<T> makeArrayRef(const T *data, size_t length) {
+    return ArrayRef<T>(data, length);
+  }
+
+  /// Construct an ArrayRef from a range.
+  template<typename T>
+  ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
+    return ArrayRef<T>(begin, end);
+  }
+
+  /// Construct an ArrayRef from a SmallVector.
+  template <typename T>
+  ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
+    return Vec;
+  }
+
+  /// Construct an ArrayRef from a SmallVector.
+  template <typename T, unsigned N>
+  ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
+    return Vec;
+  }
+
+  /// Construct an ArrayRef from a std::vector.
+  template<typename T>
+  ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
+    return Vec;
+  }
+
+  /// Construct an ArrayRef from a C array.
+  template<typename T, size_t N>
+  ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
+    return ArrayRef<T>(Arr);
+  }
+
+  /// @}
+  /// @name ArrayRef Comparison Operators
+  /// @{
+
+  template<typename T>
+  inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+    return LHS.equals(RHS);
+  }
+
+  template<typename T>
+  inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+    return !(LHS == RHS);
+  }
+
+  /// @}
+
+  // ArrayRefs can be treated like a POD type.
+  template <typename T> struct isPodLike;
+  template <typename T> struct isPodLike<ArrayRef<T> > {
+    static const bool value = true;
+  };
+}
+
+#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
new file mode 100644
index 0000000..34e2284
--- /dev/null
+++ b/include/llvm/ADT/BitVector.h
@@ -0,0 +1,595 @@
+//===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
+//
+//                     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 BitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITVECTOR_H
+#define LLVM_ADT_BITVECTOR_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <climits>
+#include <cstdlib>
+
+namespace llvm {
+
+class BitVector {
+  typedef unsigned long BitWord;
+
+  enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
+
+  BitWord  *Bits;        // Actual bits.
+  unsigned Size;         // Size of bitvector in bits.
+  unsigned Capacity;     // Size of allocated memory in BitWord.
+
+public:
+  typedef unsigned size_type;
+  // Encapsulation of a single bit.
+  class reference {
+    friend class BitVector;
+
+    BitWord *WordRef;
+    unsigned BitPos;
+
+    reference();  // Undefined
+
+  public:
+    reference(BitVector &b, unsigned Idx) {
+      WordRef = &b.Bits[Idx / BITWORD_SIZE];
+      BitPos = Idx % BITWORD_SIZE;
+    }
+
+    ~reference() {}
+
+    reference &operator=(reference t) {
+      *this = bool(t);
+      return *this;
+    }
+
+    reference& operator=(bool t) {
+      if (t)
+        *WordRef |= BitWord(1) << BitPos;
+      else
+        *WordRef &= ~(BitWord(1) << BitPos);
+      return *this;
+    }
+
+    operator bool() const {
+      return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
+    }
+  };
+
+
+  /// BitVector default ctor - Creates an empty bitvector.
+  BitVector() : Size(0), Capacity(0) {
+    Bits = nullptr;
+  }
+
+  /// BitVector ctor - Creates a bitvector of specified number of bits. All
+  /// bits are initialized to the specified value.
+  explicit BitVector(unsigned s, bool t = false) : Size(s) {
+    Capacity = NumBitWords(s);
+    Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+    init_words(Bits, Capacity, t);
+    if (t)
+      clear_unused_bits();
+  }
+
+  /// BitVector copy ctor.
+  BitVector(const BitVector &RHS) : Size(RHS.size()) {
+    if (Size == 0) {
+      Bits = nullptr;
+      Capacity = 0;
+      return;
+    }
+
+    Capacity = NumBitWords(RHS.size());
+    Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+    std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
+  }
+
+  BitVector(BitVector &&RHS)
+    : Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
+    RHS.Bits = nullptr;
+  }
+
+  ~BitVector() {
+    std::free(Bits);
+  }
+
+  /// empty - Tests whether there are no bits in this bitvector.
+  bool empty() const { return Size == 0; }
+
+  /// size - Returns the number of bits in this bitvector.
+  size_type size() const { return Size; }
+
+  /// count - Returns the number of bits which are set.
+  size_type count() const {
+    unsigned NumBits = 0;
+    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+      if (sizeof(BitWord) == 4)
+        NumBits += CountPopulation_32((uint32_t)Bits[i]);
+      else if (sizeof(BitWord) == 8)
+        NumBits += CountPopulation_64(Bits[i]);
+      else
+        llvm_unreachable("Unsupported!");
+    return NumBits;
+  }
+
+  /// any - Returns true if any bit is set.
+  bool any() const {
+    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+      if (Bits[i] != 0)
+        return true;
+    return false;
+  }
+
+  /// all - Returns true if all bits are set.
+  bool all() const {
+    for (unsigned i = 0; i < Size / BITWORD_SIZE; ++i)
+      if (Bits[i] != ~0UL)
+        return false;
+
+    // If bits remain check that they are ones. The unused bits are always zero.
+    if (unsigned Remainder = Size % BITWORD_SIZE)
+      return Bits[Size / BITWORD_SIZE] == (1UL << Remainder) - 1;
+
+    return true;
+  }
+
+  /// none - Returns true if none of the bits are set.
+  bool none() const {
+    return !any();
+  }
+
+  /// find_first - Returns the index of the first set bit, -1 if none
+  /// of the bits are set.
+  int find_first() const {
+    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+      if (Bits[i] != 0) {
+        if (sizeof(BitWord) == 4)
+          return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
+        if (sizeof(BitWord) == 8)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        llvm_unreachable("Unsupported!");
+      }
+    return -1;
+  }
+
+  /// find_next - Returns the index of the next set bit following the
+  /// "Prev" bit. Returns -1 if the next set bit is not found.
+  int find_next(unsigned Prev) const {
+    ++Prev;
+    if (Prev >= Size)
+      return -1;
+
+    unsigned WordPos = Prev / BITWORD_SIZE;
+    unsigned BitPos = Prev % BITWORD_SIZE;
+    BitWord Copy = Bits[WordPos];
+    // Mask off previous bits.
+    Copy &= ~0UL << BitPos;
+
+    if (Copy != 0) {
+      if (sizeof(BitWord) == 4)
+        return WordPos * BITWORD_SIZE + countTrailingZeros((uint32_t)Copy);
+      if (sizeof(BitWord) == 8)
+        return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
+      llvm_unreachable("Unsupported!");
+    }
+
+    // Check subsequent words.
+    for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
+      if (Bits[i] != 0) {
+        if (sizeof(BitWord) == 4)
+          return i * BITWORD_SIZE + countTrailingZeros((uint32_t)Bits[i]);
+        if (sizeof(BitWord) == 8)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        llvm_unreachable("Unsupported!");
+      }
+    return -1;
+  }
+
+  /// clear - Clear all bits.
+  void clear() {
+    Size = 0;
+  }
+
+  /// resize - Grow or shrink the bitvector.
+  void resize(unsigned N, bool t = false) {
+    if (N > Capacity * BITWORD_SIZE) {
+      unsigned OldCapacity = Capacity;
+      grow(N);
+      init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+    }
+
+    // Set any old unused bits that are now included in the BitVector. This
+    // may set bits that are not included in the new vector, but we will clear
+    // them back out below.
+    if (N > Size)
+      set_unused_bits(t);
+
+    // Update the size, and clear out any bits that are now unused
+    unsigned OldSize = Size;
+    Size = N;
+    if (t || N < OldSize)
+      clear_unused_bits();
+  }
+
+  void reserve(unsigned N) {
+    if (N > Capacity * BITWORD_SIZE)
+      grow(N);
+  }
+
+  // Set, reset, flip
+  BitVector &set() {
+    init_words(Bits, Capacity, true);
+    clear_unused_bits();
+    return *this;
+  }
+
+  BitVector &set(unsigned Idx) {
+    Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
+    return *this;
+  }
+
+  /// set - Efficiently set a range of bits in [I, E)
+  BitVector &set(unsigned I, unsigned E) {
+    assert(I <= E && "Attempted to set backwards range!");
+    assert(E <= size() && "Attempted to set out-of-bounds range!");
+
+    if (I == E) return *this;
+
+    if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
+      BitWord EMask = 1UL << (E % BITWORD_SIZE);
+      BitWord IMask = 1UL << (I % BITWORD_SIZE);
+      BitWord Mask = EMask - IMask;
+      Bits[I / BITWORD_SIZE] |= Mask;
+      return *this;
+    }
+
+    BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
+    Bits[I / BITWORD_SIZE] |= PrefixMask;
+    I = RoundUpToAlignment(I, BITWORD_SIZE);
+
+    for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
+      Bits[I / BITWORD_SIZE] = ~0UL;
+
+    BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
+    if (I < E)
+      Bits[I / BITWORD_SIZE] |= PostfixMask;
+
+    return *this;
+  }
+
+  BitVector &reset() {
+    init_words(Bits, Capacity, false);
+    return *this;
+  }
+
+  BitVector &reset(unsigned Idx) {
+    Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
+    return *this;
+  }
+
+  /// reset - Efficiently reset a range of bits in [I, E)
+  BitVector &reset(unsigned I, unsigned E) {
+    assert(I <= E && "Attempted to reset backwards range!");
+    assert(E <= size() && "Attempted to reset out-of-bounds range!");
+
+    if (I == E) return *this;
+
+    if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
+      BitWord EMask = 1UL << (E % BITWORD_SIZE);
+      BitWord IMask = 1UL << (I % BITWORD_SIZE);
+      BitWord Mask = EMask - IMask;
+      Bits[I / BITWORD_SIZE] &= ~Mask;
+      return *this;
+    }
+
+    BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
+    Bits[I / BITWORD_SIZE] &= ~PrefixMask;
+    I = RoundUpToAlignment(I, BITWORD_SIZE);
+
+    for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
+      Bits[I / BITWORD_SIZE] = 0UL;
+
+    BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
+    if (I < E)
+      Bits[I / BITWORD_SIZE] &= ~PostfixMask;
+
+    return *this;
+  }
+
+  BitVector &flip() {
+    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+      Bits[i] = ~Bits[i];
+    clear_unused_bits();
+    return *this;
+  }
+
+  BitVector &flip(unsigned Idx) {
+    Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
+    return *this;
+  }
+
+  // Indexing.
+  reference operator[](unsigned Idx) {
+    assert (Idx < Size && "Out-of-bounds Bit access.");
+    return reference(*this, Idx);
+  }
+
+  bool operator[](unsigned Idx) const {
+    assert (Idx < Size && "Out-of-bounds Bit access.");
+    BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
+    return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
+  }
+
+  bool test(unsigned Idx) const {
+    return (*this)[Idx];
+  }
+
+  /// Test if any common bits are set.
+  bool anyCommon(const BitVector &RHS) const {
+    unsigned ThisWords = NumBitWords(size());
+    unsigned RHSWords  = NumBitWords(RHS.size());
+    for (unsigned i = 0, e = std::min(ThisWords, RHSWords); i != e; ++i)
+      if (Bits[i] & RHS.Bits[i])
+        return true;
+    return false;
+  }
+
+  // Comparison operators.
+  bool operator==(const BitVector &RHS) const {
+    unsigned ThisWords = NumBitWords(size());
+    unsigned RHSWords  = NumBitWords(RHS.size());
+    unsigned i;
+    for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+      if (Bits[i] != RHS.Bits[i])
+        return false;
+
+    // Verify that any extra words are all zeros.
+    if (i != ThisWords) {
+      for (; i != ThisWords; ++i)
+        if (Bits[i])
+          return false;
+    } else if (i != RHSWords) {
+      for (; i != RHSWords; ++i)
+        if (RHS.Bits[i])
+          return false;
+    }
+    return true;
+  }
+
+  bool operator!=(const BitVector &RHS) const {
+    return !(*this == RHS);
+  }
+
+  /// Intersection, union, disjoint union.
+  BitVector &operator&=(const BitVector &RHS) {
+    unsigned ThisWords = NumBitWords(size());
+    unsigned RHSWords  = NumBitWords(RHS.size());
+    unsigned i;
+    for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+      Bits[i] &= RHS.Bits[i];
+
+    // Any bits that are just in this bitvector become zero, because they aren't
+    // in the RHS bit vector.  Any words only in RHS are ignored because they
+    // are already zero in the LHS.
+    for (; i != ThisWords; ++i)
+      Bits[i] = 0;
+
+    return *this;
+  }
+
+  /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
+  BitVector &reset(const BitVector &RHS) {
+    unsigned ThisWords = NumBitWords(size());
+    unsigned RHSWords  = NumBitWords(RHS.size());
+    unsigned i;
+    for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+      Bits[i] &= ~RHS.Bits[i];
+    return *this;
+  }
+
+  /// test - Check if (This - RHS) is zero.
+  /// This is the same as reset(RHS) and any().
+  bool test(const BitVector &RHS) const {
+    unsigned ThisWords = NumBitWords(size());
+    unsigned RHSWords  = NumBitWords(RHS.size());
+    unsigned i;
+    for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+      if ((Bits[i] & ~RHS.Bits[i]) != 0)
+        return true;
+
+    for (; i != ThisWords ; ++i)
+      if (Bits[i] != 0)
+        return true;
+
+    return false;
+  }
+
+  BitVector &operator|=(const BitVector &RHS) {
+    if (size() < RHS.size())
+      resize(RHS.size());
+    for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
+      Bits[i] |= RHS.Bits[i];
+    return *this;
+  }
+
+  BitVector &operator^=(const BitVector &RHS) {
+    if (size() < RHS.size())
+      resize(RHS.size());
+    for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
+      Bits[i] ^= RHS.Bits[i];
+    return *this;
+  }
+
+  // Assignment operator.
+  const BitVector &operator=(const BitVector &RHS) {
+    if (this == &RHS) return *this;
+
+    Size = RHS.size();
+    unsigned RHSWords = NumBitWords(Size);
+    if (Size <= Capacity * BITWORD_SIZE) {
+      if (Size)
+        std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
+      clear_unused_bits();
+      return *this;
+    }
+
+    // Grow the bitvector to have enough elements.
+    Capacity = RHSWords;
+    BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+    std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
+
+    // Destroy the old bits.
+    std::free(Bits);
+    Bits = NewBits;
+
+    return *this;
+  }
+
+  const BitVector &operator=(BitVector &&RHS) {
+    if (this == &RHS) return *this;
+
+    std::free(Bits);
+    Bits = RHS.Bits;
+    Size = RHS.Size;
+    Capacity = RHS.Capacity;
+
+    RHS.Bits = nullptr;
+
+    return *this;
+  }
+
+  void swap(BitVector &RHS) {
+    std::swap(Bits, RHS.Bits);
+    std::swap(Size, RHS.Size);
+    std::swap(Capacity, RHS.Capacity);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Portable bit mask operations.
+  //===--------------------------------------------------------------------===//
+  //
+  // These methods all operate on arrays of uint32_t, each holding 32 bits. The
+  // fixed word size makes it easier to work with literal bit vector constants
+  // in portable code.
+  //
+  // The LSB in each word is the lowest numbered bit.  The size of a portable
+  // bit mask is always a whole multiple of 32 bits.  If no bit mask size is
+  // given, the bit mask is assumed to cover the entire BitVector.
+
+  /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
+  /// This computes "*this |= Mask".
+  void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    applyMask<true, false>(Mask, MaskWords);
+  }
+
+  /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
+  /// Don't resize. This computes "*this &= ~Mask".
+  void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    applyMask<false, false>(Mask, MaskWords);
+  }
+
+  /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
+  /// Don't resize.  This computes "*this |= ~Mask".
+  void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    applyMask<true, true>(Mask, MaskWords);
+  }
+
+  /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
+  /// Don't resize.  This computes "*this &= Mask".
+  void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    applyMask<false, true>(Mask, MaskWords);
+  }
+
+private:
+  unsigned NumBitWords(unsigned S) const {
+    return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
+  }
+
+  // Set the unused bits in the high words.
+  void set_unused_bits(bool t = true) {
+    //  Set high words first.
+    unsigned UsedWords = NumBitWords(Size);
+    if (Capacity > UsedWords)
+      init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+
+    //  Then set any stray high bits of the last used word.
+    unsigned ExtraBits = Size % BITWORD_SIZE;
+    if (ExtraBits) {
+      BitWord ExtraBitMask = ~0UL << ExtraBits;
+      if (t)
+        Bits[UsedWords-1] |= ExtraBitMask;
+      else
+        Bits[UsedWords-1] &= ~ExtraBitMask;
+    }
+  }
+
+  // Clear the unused bits in the high words.
+  void clear_unused_bits() {
+    set_unused_bits(false);
+  }
+
+  void grow(unsigned NewSize) {
+    Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
+    Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
+
+    clear_unused_bits();
+  }
+
+  void init_words(BitWord *B, unsigned NumWords, bool t) {
+    memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+  }
+
+  template<bool AddBits, bool InvertMask>
+  void applyMask(const uint32_t *Mask, unsigned MaskWords) {
+    assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size.");
+    MaskWords = std::min(MaskWords, (size() + 31) / 32);
+    const unsigned Scale = BITWORD_SIZE / 32;
+    unsigned i;
+    for (i = 0; MaskWords >= Scale; ++i, MaskWords -= Scale) {
+      BitWord BW = Bits[i];
+      // This inner loop should unroll completely when BITWORD_SIZE > 32.
+      for (unsigned b = 0; b != BITWORD_SIZE; b += 32) {
+        uint32_t M = *Mask++;
+        if (InvertMask) M = ~M;
+        if (AddBits) BW |=   BitWord(M) << b;
+        else         BW &= ~(BitWord(M) << b);
+      }
+      Bits[i] = BW;
+    }
+    for (unsigned b = 0; MaskWords; b += 32, --MaskWords) {
+      uint32_t M = *Mask++;
+      if (InvertMask) M = ~M;
+      if (AddBits) Bits[i] |=   BitWord(M) << b;
+      else         Bits[i] &= ~(BitWord(M) << b);
+    }
+    if (AddBits)
+      clear_unused_bits();
+  }
+};
+
+} // End llvm namespace
+
+namespace std {
+  /// Implement std::swap in terms of BitVector swap.
+  inline void
+  swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
+    LHS.swap(RHS);
+  }
+}
+
+#endif
diff --git a/include/llvm/ADT/DAGDeltaAlgorithm.h b/include/llvm/ADT/DAGDeltaAlgorithm.h
new file mode 100644
index 0000000..3dd862c
--- /dev/null
+++ b/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -0,0 +1,77 @@
+//===--- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ----*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
+#define LLVM_ADT_DAGDELTAALGORITHM_H
+
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+/// DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimizing
+/// directed acyclic graphs using a predicate function.
+///
+/// The result of the algorithm is a subset of the input change set which is
+/// guaranteed to satisfy the predicate, assuming that the input set did. For
+/// well formed predicates, the result set is guaranteed to be such that
+/// removing any single element not required by the dependencies on the other
+/// elements would falsify the predicate.
+///
+/// The DAG should be used to represent dependencies in the changes which are
+/// likely to hold across the predicate function. That is, for a particular
+/// changeset S and predicate P:
+///
+///   P(S) => P(S union pred(S))
+///
+/// The minization algorithm uses this dependency information to attempt to
+/// eagerly prune large subsets of changes. As with \see DeltaAlgorithm, the DAG
+/// is not required to satisfy this property, but the algorithm will run
+/// substantially fewer tests with appropriate dependencies. \see DeltaAlgorithm
+/// for more information on the properties which the predicate function itself
+/// should satisfy.
+class DAGDeltaAlgorithm {
+  virtual void anchor();
+public:
+  typedef unsigned change_ty;
+  typedef std::pair<change_ty, change_ty> edge_ty;
+
+  // FIXME: Use a decent data structure.
+  typedef std::set<change_ty> changeset_ty;
+  typedef std::vector<changeset_ty> changesetlist_ty;
+
+public:
+  virtual ~DAGDeltaAlgorithm() {}
+
+  /// Run - Minimize the DAG formed by the \p Changes vertices and the
+  /// \p Dependencies edges by executing \see ExecuteOneTest() on subsets of
+  /// changes and returning the smallest set which still satisfies the test
+  /// predicate and the input \p Dependencies.
+  ///
+  /// \param Changes The list of changes.
+  ///
+  /// \param Dependencies The list of dependencies amongst changes. For each
+  /// (x,y) in \p Dependencies, both x and y must be in \p Changes. The
+  /// minimization algorithm guarantees that for each tested changed set S,
+  /// \f$ x \in S \f$ implies \f$ y \in S \f$. It is an error to have cyclic
+  /// dependencies.
+  changeset_ty Run(const changeset_ty &Changes,
+                   const std::vector<edge_ty> &Dependencies);
+
+  /// UpdatedSearchState - Callback used when the search state changes.
+  virtual void UpdatedSearchState(const changeset_ty &Changes,
+                                  const changesetlist_ty &Sets,
+                                  const changeset_ty &Required) {}
+
+  /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
+  virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h
new file mode 100644
index 0000000..4d07e04
--- /dev/null
+++ b/include/llvm/ADT/DeltaAlgorithm.h
@@ -0,0 +1,91 @@
+//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DELTAALGORITHM_H
+#define LLVM_ADT_DELTAALGORITHM_H
+
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+/// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '99)
+/// for minimizing arbitrary sets using a predicate function.
+///
+/// The result of the algorithm is a subset of the input change set which is
+/// guaranteed to satisfy the predicate, assuming that the input set did. For
+/// well formed predicates, the result set is guaranteed to be such that
+/// removing any single element would falsify the predicate.
+///
+/// For best results the predicate function *should* (but need not) satisfy
+/// certain properties, in particular:
+///  (1) The predicate should return false on an empty set and true on the full
+///  set.
+///  (2) If the predicate returns true for a set of changes, it should return
+///  true for all supersets of that set.
+///
+/// It is not an error to provide a predicate that does not satisfy these
+/// requirements, and the algorithm will generally produce reasonable
+/// results. However, it may run substantially more tests than with a good
+/// predicate.
+class DeltaAlgorithm {
+public:
+  typedef unsigned change_ty;
+  // FIXME: Use a decent data structure.
+  typedef std::set<change_ty> changeset_ty;
+  typedef std::vector<changeset_ty> changesetlist_ty;
+
+private:
+  /// Cache of failed test results. Successful test results are never cached
+  /// since we always reduce following a success.
+  std::set<changeset_ty> FailedTestsCache;
+
+  /// GetTestResult - Get the test result for the \p Changes from the
+  /// cache, executing the test if necessary.
+  ///
+  /// \param Changes - The change set to test.
+  /// \return - The test result.
+  bool GetTestResult(const changeset_ty &Changes);
+
+  /// Split - Partition a set of changes \p S into one or two subsets.
+  void Split(const changeset_ty &S, changesetlist_ty &Res);
+
+  /// Delta - Minimize a set of \p Changes which has been partioned into
+  /// smaller sets, by attempting to remove individual subsets.
+  changeset_ty Delta(const changeset_ty &Changes,
+                     const changesetlist_ty &Sets);
+
+  /// Search - Search for a subset (or subsets) in \p Sets which can be
+  /// removed from \p Changes while still satisfying the predicate.
+  ///
+  /// \param Res - On success, a subset of Changes which satisfies the
+  /// predicate.
+  /// \return - True on success.
+  bool Search(const changeset_ty &Changes, const changesetlist_ty &Sets,
+              changeset_ty &Res);
+              
+protected:
+  /// UpdatedSearchState - Callback used when the search state changes.
+  virtual void UpdatedSearchState(const changeset_ty &Changes,
+                                  const changesetlist_ty &Sets) {}
+
+  /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
+  virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
+
+public:
+  virtual ~DeltaAlgorithm();
+
+  /// Run - Minimize the set \p Changes by executing \see ExecuteOneTest() on
+  /// subsets of changes and returning the smallest set which still satisfies
+  /// the test predicate.
+  changeset_ty Run(const changeset_ty &Changes);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
new file mode 100644
index 0000000..85f37b9
--- /dev/null
+++ b/include/llvm/ADT/DenseMap.h
@@ -0,0 +1,1046 @@
+//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- 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 DenseMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAP_H
+#define LLVM_ADT_DENSEMAP_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <climits>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <new>
+#include <utility>
+
+namespace llvm {
+
+template<typename KeyT, typename ValueT,
+         typename KeyInfoT = DenseMapInfo<KeyT>,
+         bool IsConst = false>
+class DenseMapIterator;
+
+template<typename DerivedT,
+         typename KeyT, typename ValueT, typename KeyInfoT>
+class DenseMapBase {
+protected:
+  typedef std::pair<KeyT, ValueT> BucketT;
+
+public:
+  typedef unsigned size_type;
+  typedef KeyT key_type;
+  typedef ValueT mapped_type;
+  typedef BucketT value_type;
+
+  typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
+  typedef DenseMapIterator<KeyT, ValueT,
+                           KeyInfoT, true> const_iterator;
+  inline iterator begin() {
+    // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
+    return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
+  }
+  inline iterator end() {
+    return iterator(getBucketsEnd(), getBucketsEnd(), true);
+  }
+  inline const_iterator begin() const {
+    return empty() ? end() : const_iterator(getBuckets(), getBucketsEnd());
+  }
+  inline const_iterator end() const {
+    return const_iterator(getBucketsEnd(), getBucketsEnd(), true);
+  }
+
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
+    return getNumEntries() == 0;
+  }
+  unsigned size() const { return getNumEntries(); }
+
+  /// Grow the densemap so that it has at least Size buckets. Does not shrink
+  void resize(size_type Size) {
+    if (Size > getNumBuckets())
+      grow(Size);
+  }
+
+  void clear() {
+    if (getNumEntries() == 0 && getNumTombstones() == 0) return;
+
+    // If the capacity of the array is huge, and the # elements used is small,
+    // shrink the array.
+    if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
+      shrink_and_clear();
+      return;
+    }
+
+    const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+    for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
+      if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
+        if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
+          P->second.~ValueT();
+          decrementNumEntries();
+        }
+        P->first = EmptyKey;
+      }
+    }
+    assert(getNumEntries() == 0 && "Node count imbalance!");
+    setNumTombstones(0);
+  }
+
+  /// Return 1 if the specified key is in the map, 0 otherwise.
+  size_type count(const KeyT &Val) const {
+    const BucketT *TheBucket;
+    return LookupBucketFor(Val, TheBucket) ? 1 : 0;
+  }
+
+  iterator find(const KeyT &Val) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return iterator(TheBucket, getBucketsEnd(), true);
+    return end();
+  }
+  const_iterator find(const KeyT &Val) const {
+    const BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return const_iterator(TheBucket, getBucketsEnd(), true);
+    return end();
+  }
+
+  /// Alternate version of find() which allows a different, and possibly
+  /// less expensive, key type.
+  /// The DenseMapInfo is responsible for supplying methods
+  /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
+  /// type used.
+  template<class LookupKeyT>
+  iterator find_as(const LookupKeyT &Val) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return iterator(TheBucket, getBucketsEnd(), true);
+    return end();
+  }
+  template<class LookupKeyT>
+  const_iterator find_as(const LookupKeyT &Val) const {
+    const BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return const_iterator(TheBucket, getBucketsEnd(), true);
+    return end();
+  }
+
+  /// lookup - Return the entry for the specified key, or a default
+  /// constructed value if no such entry exists.
+  ValueT lookup(const KeyT &Val) const {
+    const BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return TheBucket->second;
+    return ValueT();
+  }
+
+  // Inserts key,value pair into the map if the key isn't already in the map.
+  // If the key is already in the map, it returns false and doesn't update the
+  // value.
+  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(KV.first, TheBucket))
+      return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
+                            false); // Already in map.
+
+    // Otherwise, insert the new element.
+    TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
+    return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
+  }
+
+  // Inserts key,value pair into the map if the key isn't already in the map.
+  // If the key is already in the map, it returns false and doesn't update the
+  // value.
+  std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(KV.first, TheBucket))
+      return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
+                            false); // Already in map.
+    
+    // Otherwise, insert the new element.
+    TheBucket = InsertIntoBucket(std::move(KV.first),
+                                 std::move(KV.second),
+                                 TheBucket);
+    return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
+  }
+
+  /// insert - Range insertion of pairs.
+  template<typename InputIt>
+  void insert(InputIt I, InputIt E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+
+
+  bool erase(const KeyT &Val) {
+    BucketT *TheBucket;
+    if (!LookupBucketFor(Val, TheBucket))
+      return false; // not in map.
+
+    TheBucket->second.~ValueT();
+    TheBucket->first = getTombstoneKey();
+    decrementNumEntries();
+    incrementNumTombstones();
+    return true;
+  }
+  void erase(iterator I) {
+    BucketT *TheBucket = &*I;
+    TheBucket->second.~ValueT();
+    TheBucket->first = getTombstoneKey();
+    decrementNumEntries();
+    incrementNumTombstones();
+  }
+
+  value_type& FindAndConstruct(const KeyT &Key) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Key, TheBucket))
+      return *TheBucket;
+
+    return *InsertIntoBucket(Key, ValueT(), TheBucket);
+  }
+
+  ValueT &operator[](const KeyT &Key) {
+    return FindAndConstruct(Key).second;
+  }
+
+  value_type& FindAndConstruct(KeyT &&Key) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Key, TheBucket))
+      return *TheBucket;
+
+    return *InsertIntoBucket(std::move(Key), ValueT(), TheBucket);
+  }
+
+  ValueT &operator[](KeyT &&Key) {
+    return FindAndConstruct(std::move(Key)).second;
+  }
+
+  /// isPointerIntoBucketsArray - Return true if the specified pointer points
+  /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
+  /// value in the DenseMap).
+  bool isPointerIntoBucketsArray(const void *Ptr) const {
+    return Ptr >= getBuckets() && Ptr < getBucketsEnd();
+  }
+
+  /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+  /// array.  In conjunction with the previous method, this can be used to
+  /// determine whether an insertion caused the DenseMap to reallocate.
+  const void *getPointerIntoBucketsArray() const { return getBuckets(); }
+
+protected:
+  DenseMapBase() {}
+
+  void destroyAll() {
+    if (getNumBuckets() == 0) // Nothing to do.
+      return;
+
+    const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+    for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
+      if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+          !KeyInfoT::isEqual(P->first, TombstoneKey))
+        P->second.~ValueT();
+      P->first.~KeyT();
+    }
+
+#ifndef NDEBUG
+    memset((void*)getBuckets(), 0x5a, sizeof(BucketT)*getNumBuckets());
+#endif
+  }
+
+  void initEmpty() {
+    setNumEntries(0);
+    setNumTombstones(0);
+
+    assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
+           "# initial buckets must be a power of two!");
+    const KeyT EmptyKey = getEmptyKey();
+    for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
+      new (&B->first) KeyT(EmptyKey);
+  }
+
+  void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
+    initEmpty();
+
+    // Insert all the old elements.
+    const KeyT EmptyKey = getEmptyKey();
+    const KeyT TombstoneKey = getTombstoneKey();
+    for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
+      if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+          !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+        // Insert the key/value into the new table.
+        BucketT *DestBucket;
+        bool FoundVal = LookupBucketFor(B->first, DestBucket);
+        (void)FoundVal; // silence warning.
+        assert(!FoundVal && "Key already in new map?");
+        DestBucket->first = std::move(B->first);
+        new (&DestBucket->second) ValueT(std::move(B->second));
+        incrementNumEntries();
+
+        // Free the value.
+        B->second.~ValueT();
+      }
+      B->first.~KeyT();
+    }
+
+#ifndef NDEBUG
+    if (OldBucketsBegin != OldBucketsEnd)
+      memset((void*)OldBucketsBegin, 0x5a,
+             sizeof(BucketT) * (OldBucketsEnd - OldBucketsBegin));
+#endif
+  }
+
+  template <typename OtherBaseT>
+  void copyFrom(const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT>& other) {
+    assert(getNumBuckets() == other.getNumBuckets());
+
+    setNumEntries(other.getNumEntries());
+    setNumTombstones(other.getNumTombstones());
+
+    if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
+      memcpy(getBuckets(), other.getBuckets(),
+             getNumBuckets() * sizeof(BucketT));
+    else
+      for (size_t i = 0; i < getNumBuckets(); ++i) {
+        new (&getBuckets()[i].first) KeyT(other.getBuckets()[i].first);
+        if (!KeyInfoT::isEqual(getBuckets()[i].first, getEmptyKey()) &&
+            !KeyInfoT::isEqual(getBuckets()[i].first, getTombstoneKey()))
+          new (&getBuckets()[i].second) ValueT(other.getBuckets()[i].second);
+      }
+  }
+
+  void swap(DenseMapBase& RHS) {
+    std::swap(getNumEntries(), RHS.getNumEntries());
+    std::swap(getNumTombstones(), RHS.getNumTombstones());
+  }
+
+  static unsigned getHashValue(const KeyT &Val) {
+    return KeyInfoT::getHashValue(Val);
+  }
+  template<typename LookupKeyT>
+  static unsigned getHashValue(const LookupKeyT &Val) {
+    return KeyInfoT::getHashValue(Val);
+  }
+  static const KeyT getEmptyKey() {
+    return KeyInfoT::getEmptyKey();
+  }
+  static const KeyT getTombstoneKey() {
+    return KeyInfoT::getTombstoneKey();
+  }
+
+private:
+  unsigned getNumEntries() const {
+    return static_cast<const DerivedT *>(this)->getNumEntries();
+  }
+  void setNumEntries(unsigned Num) {
+    static_cast<DerivedT *>(this)->setNumEntries(Num);
+  }
+  void incrementNumEntries() {
+    setNumEntries(getNumEntries() + 1);
+  }
+  void decrementNumEntries() {
+    setNumEntries(getNumEntries() - 1);
+  }
+  unsigned getNumTombstones() const {
+    return static_cast<const DerivedT *>(this)->getNumTombstones();
+  }
+  void setNumTombstones(unsigned Num) {
+    static_cast<DerivedT *>(this)->setNumTombstones(Num);
+  }
+  void incrementNumTombstones() {
+    setNumTombstones(getNumTombstones() + 1);
+  }
+  void decrementNumTombstones() {
+    setNumTombstones(getNumTombstones() - 1);
+  }
+  const BucketT *getBuckets() const {
+    return static_cast<const DerivedT *>(this)->getBuckets();
+  }
+  BucketT *getBuckets() {
+    return static_cast<DerivedT *>(this)->getBuckets();
+  }
+  unsigned getNumBuckets() const {
+    return static_cast<const DerivedT *>(this)->getNumBuckets();
+  }
+  BucketT *getBucketsEnd() {
+    return getBuckets() + getNumBuckets();
+  }
+  const BucketT *getBucketsEnd() const {
+    return getBuckets() + getNumBuckets();
+  }
+
+  void grow(unsigned AtLeast) {
+    static_cast<DerivedT *>(this)->grow(AtLeast);
+  }
+
+  void shrink_and_clear() {
+    static_cast<DerivedT *>(this)->shrink_and_clear();
+  }
+
+
+  BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+                            BucketT *TheBucket) {
+    TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+    TheBucket->first = Key;
+    new (&TheBucket->second) ValueT(Value);
+    return TheBucket;
+  }
+
+  BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
+                            BucketT *TheBucket) {
+    TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+    TheBucket->first = Key;
+    new (&TheBucket->second) ValueT(std::move(Value));
+    return TheBucket;
+  }
+
+  BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
+    TheBucket = InsertIntoBucketImpl(Key, TheBucket);
+
+    TheBucket->first = std::move(Key);
+    new (&TheBucket->second) ValueT(std::move(Value));
+    return TheBucket;
+  }
+
+  BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
+    // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
+    // the buckets are empty (meaning that many are filled with tombstones),
+    // grow the table.
+    //
+    // The later case is tricky.  For example, if we had one empty bucket with
+    // tons of tombstones, failing lookups (e.g. for insertion) would have to
+    // probe almost the entire table until it found the empty bucket.  If the
+    // table completely filled with tombstones, no lookup would ever succeed,
+    // causing infinite loops in lookup.
+    unsigned NewNumEntries = getNumEntries() + 1;
+    unsigned NumBuckets = getNumBuckets();
+    if (NewNumEntries*4 >= NumBuckets*3) {
+      this->grow(NumBuckets * 2);
+      LookupBucketFor(Key, TheBucket);
+      NumBuckets = getNumBuckets();
+    } else if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
+      this->grow(NumBuckets);
+      LookupBucketFor(Key, TheBucket);
+    }
+    assert(TheBucket);
+
+    // Only update the state after we've grown our bucket space appropriately
+    // so that when growing buckets we have self-consistent entry count.
+    incrementNumEntries();
+
+    // If we are writing over a tombstone, remember this.
+    const KeyT EmptyKey = getEmptyKey();
+    if (!KeyInfoT::isEqual(TheBucket->first, EmptyKey))
+      decrementNumTombstones();
+
+    return TheBucket;
+  }
+
+  /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+  /// FoundBucket.  If the bucket contains the key and a value, this returns
+  /// true, otherwise it returns a bucket with an empty marker or tombstone and
+  /// returns false.
+  template<typename LookupKeyT>
+  bool LookupBucketFor(const LookupKeyT &Val,
+                       const BucketT *&FoundBucket) const {
+    const BucketT *BucketsPtr = getBuckets();
+    const unsigned NumBuckets = getNumBuckets();
+
+    if (NumBuckets == 0) {
+      FoundBucket = nullptr;
+      return false;
+    }
+
+    // FoundTombstone - Keep track of whether we find a tombstone while probing.
+    const BucketT *FoundTombstone = nullptr;
+    const KeyT EmptyKey = getEmptyKey();
+    const KeyT TombstoneKey = getTombstoneKey();
+    assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
+           !KeyInfoT::isEqual(Val, TombstoneKey) &&
+           "Empty/Tombstone value shouldn't be inserted into map!");
+
+    unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
+    unsigned ProbeAmt = 1;
+    while (1) {
+      const BucketT *ThisBucket = BucketsPtr + BucketNo;
+      // Found Val's bucket?  If so, return it.
+      if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
+        FoundBucket = ThisBucket;
+        return true;
+      }
+
+      // If we found an empty bucket, the key doesn't exist in the set.
+      // Insert it and return the default value.
+      if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
+        // If we've already seen a tombstone while probing, fill it in instead
+        // of the empty bucket we eventually probed to.
+        FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+        return false;
+      }
+
+      // If this is a tombstone, remember it.  If Val ends up not in the map, we
+      // prefer to return it than something that would require more probing.
+      if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
+        FoundTombstone = ThisBucket;  // Remember the first tombstone found.
+
+      // Otherwise, it's a hash collision or a tombstone, continue quadratic
+      // probing.
+      BucketNo += ProbeAmt++;
+      BucketNo &= (NumBuckets-1);
+    }
+  }
+
+  template <typename LookupKeyT>
+  bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
+    const BucketT *ConstFoundBucket;
+    bool Result = const_cast<const DenseMapBase *>(this)
+      ->LookupBucketFor(Val, ConstFoundBucket);
+    FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
+    return Result;
+  }
+
+public:
+  /// Return the approximate size (in bytes) of the actual map.
+  /// This is just the raw memory used by DenseMap.
+  /// If entries are pointers to objects, the size of the referenced objects
+  /// are not included.
+  size_t getMemorySize() const {
+    return getNumBuckets() * sizeof(BucketT);
+  }
+};
+
+template<typename KeyT, typename ValueT,
+         typename KeyInfoT = DenseMapInfo<KeyT> >
+class DenseMap
+    : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT>,
+                          KeyT, ValueT, KeyInfoT> {
+  // Lift some types from the dependent base class into this class for
+  // simplicity of referring to them.
+  typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT> BaseT;
+  typedef typename BaseT::BucketT BucketT;
+  friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT>;
+
+  BucketT *Buckets;
+  unsigned NumEntries;
+  unsigned NumTombstones;
+  unsigned NumBuckets;
+
+public:
+  explicit DenseMap(unsigned NumInitBuckets = 0) {
+    init(NumInitBuckets);
+  }
+
+  DenseMap(const DenseMap &other) : BaseT() {
+    init(0);
+    copyFrom(other);
+  }
+
+  DenseMap(DenseMap &&other) : BaseT() {
+    init(0);
+    swap(other);
+  }
+
+  template<typename InputIt>
+  DenseMap(const InputIt &I, const InputIt &E) {
+    init(NextPowerOf2(std::distance(I, E)));
+    this->insert(I, E);
+  }
+
+  ~DenseMap() {
+    this->destroyAll();
+    operator delete(Buckets);
+  }
+
+  void swap(DenseMap& RHS) {
+    std::swap(Buckets, RHS.Buckets);
+    std::swap(NumEntries, RHS.NumEntries);
+    std::swap(NumTombstones, RHS.NumTombstones);
+    std::swap(NumBuckets, RHS.NumBuckets);
+  }
+
+  DenseMap& operator=(const DenseMap& other) {
+    copyFrom(other);
+    return *this;
+  }
+
+  DenseMap& operator=(DenseMap &&other) {
+    this->destroyAll();
+    operator delete(Buckets);
+    init(0);
+    swap(other);
+    return *this;
+  }
+
+  void copyFrom(const DenseMap& other) {
+    this->destroyAll();
+    operator delete(Buckets);
+    if (allocateBuckets(other.NumBuckets)) {
+      this->BaseT::copyFrom(other);
+    } else {
+      NumEntries = 0;
+      NumTombstones = 0;
+    }
+  }
+
+  void init(unsigned InitBuckets) {
+    if (allocateBuckets(InitBuckets)) {
+      this->BaseT::initEmpty();
+    } else {
+      NumEntries = 0;
+      NumTombstones = 0;
+    }
+  }
+
+  void grow(unsigned AtLeast) {
+    unsigned OldNumBuckets = NumBuckets;
+    BucketT *OldBuckets = Buckets;
+
+    allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
+    assert(Buckets);
+    if (!OldBuckets) {
+      this->BaseT::initEmpty();
+      return;
+    }
+
+    this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
+
+    // Free the old table.
+    operator delete(OldBuckets);
+  }
+
+  void shrink_and_clear() {
+    unsigned OldNumEntries = NumEntries;
+    this->destroyAll();
+
+    // Reduce the number of buckets.
+    unsigned NewNumBuckets = 0;
+    if (OldNumEntries)
+      NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
+    if (NewNumBuckets == NumBuckets) {
+      this->BaseT::initEmpty();
+      return;
+    }
+
+    operator delete(Buckets);
+    init(NewNumBuckets);
+  }
+
+private:
+  unsigned getNumEntries() const {
+    return NumEntries;
+  }
+  void setNumEntries(unsigned Num) {
+    NumEntries = Num;
+  }
+
+  unsigned getNumTombstones() const {
+    return NumTombstones;
+  }
+  void setNumTombstones(unsigned Num) {
+    NumTombstones = Num;
+  }
+
+  BucketT *getBuckets() const {
+    return Buckets;
+  }
+
+  unsigned getNumBuckets() const {
+    return NumBuckets;
+  }
+
+  bool allocateBuckets(unsigned Num) {
+    NumBuckets = Num;
+    if (NumBuckets == 0) {
+      Buckets = nullptr;
+      return false;
+    }
+
+    Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
+    return true;
+  }
+};
+
+template<typename KeyT, typename ValueT,
+         unsigned InlineBuckets = 4,
+         typename KeyInfoT = DenseMapInfo<KeyT> >
+class SmallDenseMap
+    : public DenseMapBase<SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT>,
+                          KeyT, ValueT, KeyInfoT> {
+  // Lift some types from the dependent base class into this class for
+  // simplicity of referring to them.
+  typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT> BaseT;
+  typedef typename BaseT::BucketT BucketT;
+  friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT>;
+
+  unsigned Small : 1;
+  unsigned NumEntries : 31;
+  unsigned NumTombstones;
+
+  struct LargeRep {
+    BucketT *Buckets;
+    unsigned NumBuckets;
+  };
+
+  /// A "union" of an inline bucket array and the struct representing
+  /// a large bucket. This union will be discriminated by the 'Small' bit.
+  AlignedCharArrayUnion<BucketT[InlineBuckets], LargeRep> storage;
+
+public:
+  explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
+    init(NumInitBuckets);
+  }
+
+  SmallDenseMap(const SmallDenseMap &other) : BaseT() {
+    init(0);
+    copyFrom(other);
+  }
+
+  SmallDenseMap(SmallDenseMap &&other) : BaseT() {
+    init(0);
+    swap(other);
+  }
+
+  template<typename InputIt>
+  SmallDenseMap(const InputIt &I, const InputIt &E) {
+    init(NextPowerOf2(std::distance(I, E)));
+    this->insert(I, E);
+  }
+
+  ~SmallDenseMap() {
+    this->destroyAll();
+    deallocateBuckets();
+  }
+
+  void swap(SmallDenseMap& RHS) {
+    unsigned TmpNumEntries = RHS.NumEntries;
+    RHS.NumEntries = NumEntries;
+    NumEntries = TmpNumEntries;
+    std::swap(NumTombstones, RHS.NumTombstones);
+
+    const KeyT EmptyKey = this->getEmptyKey();
+    const KeyT TombstoneKey = this->getTombstoneKey();
+    if (Small && RHS.Small) {
+      // If we're swapping inline bucket arrays, we have to cope with some of
+      // the tricky bits of DenseMap's storage system: the buckets are not
+      // fully initialized. Thus we swap every key, but we may have
+      // a one-directional move of the value.
+      for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
+        BucketT *LHSB = &getInlineBuckets()[i],
+                *RHSB = &RHS.getInlineBuckets()[i];
+        bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->first, EmptyKey) &&
+                            !KeyInfoT::isEqual(LHSB->first, TombstoneKey));
+        bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->first, EmptyKey) &&
+                            !KeyInfoT::isEqual(RHSB->first, TombstoneKey));
+        if (hasLHSValue && hasRHSValue) {
+          // Swap together if we can...
+          std::swap(*LHSB, *RHSB);
+          continue;
+        }
+        // Swap separately and handle any assymetry.
+        std::swap(LHSB->first, RHSB->first);
+        if (hasLHSValue) {
+          new (&RHSB->second) ValueT(std::move(LHSB->second));
+          LHSB->second.~ValueT();
+        } else if (hasRHSValue) {
+          new (&LHSB->second) ValueT(std::move(RHSB->second));
+          RHSB->second.~ValueT();
+        }
+      }
+      return;
+    }
+    if (!Small && !RHS.Small) {
+      std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
+      std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
+      return;
+    }
+
+    SmallDenseMap &SmallSide = Small ? *this : RHS;
+    SmallDenseMap &LargeSide = Small ? RHS : *this;
+
+    // First stash the large side's rep and move the small side across.
+    LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
+    LargeSide.getLargeRep()->~LargeRep();
+    LargeSide.Small = true;
+    // This is similar to the standard move-from-old-buckets, but the bucket
+    // count hasn't actually rotated in this case. So we have to carefully
+    // move construct the keys and values into their new locations, but there
+    // is no need to re-hash things.
+    for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
+      BucketT *NewB = &LargeSide.getInlineBuckets()[i],
+              *OldB = &SmallSide.getInlineBuckets()[i];
+      new (&NewB->first) KeyT(std::move(OldB->first));
+      OldB->first.~KeyT();
+      if (!KeyInfoT::isEqual(NewB->first, EmptyKey) &&
+          !KeyInfoT::isEqual(NewB->first, TombstoneKey)) {
+        new (&NewB->second) ValueT(std::move(OldB->second));
+        OldB->second.~ValueT();
+      }
+    }
+
+    // The hard part of moving the small buckets across is done, just move
+    // the TmpRep into its new home.
+    SmallSide.Small = false;
+    new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
+  }
+
+  SmallDenseMap& operator=(const SmallDenseMap& other) {
+    copyFrom(other);
+    return *this;
+  }
+
+  SmallDenseMap& operator=(SmallDenseMap &&other) {
+    this->destroyAll();
+    deallocateBuckets();
+    init(0);
+    swap(other);
+    return *this;
+  }
+
+  void copyFrom(const SmallDenseMap& other) {
+    this->destroyAll();
+    deallocateBuckets();
+    Small = true;
+    if (other.getNumBuckets() > InlineBuckets) {
+      Small = false;
+      new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
+    }
+    this->BaseT::copyFrom(other);
+  }
+
+  void init(unsigned InitBuckets) {
+    Small = true;
+    if (InitBuckets > InlineBuckets) {
+      Small = false;
+      new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
+    }
+    this->BaseT::initEmpty();
+  }
+
+  void grow(unsigned AtLeast) {
+    if (AtLeast >= InlineBuckets)
+      AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
+
+    if (Small) {
+      if (AtLeast < InlineBuckets)
+        return; // Nothing to do.
+
+      // First move the inline buckets into a temporary storage.
+      AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
+      BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
+      BucketT *TmpEnd = TmpBegin;
+
+      // Loop over the buckets, moving non-empty, non-tombstones into the
+      // temporary storage. Have the loop move the TmpEnd forward as it goes.
+      const KeyT EmptyKey = this->getEmptyKey();
+      const KeyT TombstoneKey = this->getTombstoneKey();
+      for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) {
+        if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+            !KeyInfoT::isEqual(P->first, TombstoneKey)) {
+          assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
+                 "Too many inline buckets!");
+          new (&TmpEnd->first) KeyT(std::move(P->first));
+          new (&TmpEnd->second) ValueT(std::move(P->second));
+          ++TmpEnd;
+          P->second.~ValueT();
+        }
+        P->first.~KeyT();
+      }
+
+      // Now make this map use the large rep, and move all the entries back
+      // into it.
+      Small = false;
+      new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
+      this->moveFromOldBuckets(TmpBegin, TmpEnd);
+      return;
+    }
+
+    LargeRep OldRep = std::move(*getLargeRep());
+    getLargeRep()->~LargeRep();
+    if (AtLeast <= InlineBuckets) {
+      Small = true;
+    } else {
+      new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
+    }
+
+    this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
+
+    // Free the old table.
+    operator delete(OldRep.Buckets);
+  }
+
+  void shrink_and_clear() {
+    unsigned OldSize = this->size();
+    this->destroyAll();
+
+    // Reduce the number of buckets.
+    unsigned NewNumBuckets = 0;
+    if (OldSize) {
+      NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
+      if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
+        NewNumBuckets = 64;
+    }
+    if ((Small && NewNumBuckets <= InlineBuckets) ||
+        (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
+      this->BaseT::initEmpty();
+      return;
+    }
+
+    deallocateBuckets();
+    init(NewNumBuckets);
+  }
+
+private:
+  unsigned getNumEntries() const {
+    return NumEntries;
+  }
+  void setNumEntries(unsigned Num) {
+    assert(Num < INT_MAX && "Cannot support more than INT_MAX entries");
+    NumEntries = Num;
+  }
+
+  unsigned getNumTombstones() const {
+    return NumTombstones;
+  }
+  void setNumTombstones(unsigned Num) {
+    NumTombstones = Num;
+  }
+
+  const BucketT *getInlineBuckets() const {
+    assert(Small);
+    // Note that this cast does not violate aliasing rules as we assert that
+    // the memory's dynamic type is the small, inline bucket buffer, and the
+    // 'storage.buffer' static type is 'char *'.
+    return reinterpret_cast<const BucketT *>(storage.buffer);
+  }
+  BucketT *getInlineBuckets() {
+    return const_cast<BucketT *>(
+      const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
+  }
+  const LargeRep *getLargeRep() const {
+    assert(!Small);
+    // Note, same rule about aliasing as with getInlineBuckets.
+    return reinterpret_cast<const LargeRep *>(storage.buffer);
+  }
+  LargeRep *getLargeRep() {
+    return const_cast<LargeRep *>(
+      const_cast<const SmallDenseMap *>(this)->getLargeRep());
+  }
+
+  const BucketT *getBuckets() const {
+    return Small ? getInlineBuckets() : getLargeRep()->Buckets;
+  }
+  BucketT *getBuckets() {
+    return const_cast<BucketT *>(
+      const_cast<const SmallDenseMap *>(this)->getBuckets());
+  }
+  unsigned getNumBuckets() const {
+    return Small ? InlineBuckets : getLargeRep()->NumBuckets;
+  }
+
+  void deallocateBuckets() {
+    if (Small)
+      return;
+
+    operator delete(getLargeRep()->Buckets);
+    getLargeRep()->~LargeRep();
+  }
+
+  LargeRep allocateBuckets(unsigned Num) {
+    assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
+    LargeRep Rep = {
+      static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
+    };
+    return Rep;
+  }
+};
+
+template<typename KeyT, typename ValueT,
+         typename KeyInfoT, bool IsConst>
+class DenseMapIterator {
+  typedef std::pair<KeyT, ValueT> Bucket;
+  typedef DenseMapIterator<KeyT, ValueT,
+                           KeyInfoT, true> ConstIterator;
+  friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
+public:
+  typedef ptrdiff_t difference_type;
+  typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
+  value_type;
+  typedef value_type *pointer;
+  typedef value_type &reference;
+  typedef std::forward_iterator_tag iterator_category;
+private:
+  pointer Ptr, End;
+public:
+  DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
+
+  DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
+    : Ptr(Pos), End(E) {
+    if (!NoAdvance) AdvancePastEmptyBuckets();
+  }
+
+  // If IsConst is true this is a converting constructor from iterator to
+  // const_iterator and the default copy constructor is used.
+  // Otherwise this is a copy constructor for iterator.
+  DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
+                                          KeyInfoT, false>& I)
+    : Ptr(I.Ptr), End(I.End) {}
+
+  reference operator*() const {
+    return *Ptr;
+  }
+  pointer operator->() const {
+    return Ptr;
+  }
+
+  bool operator==(const ConstIterator &RHS) const {
+    return Ptr == RHS.operator->();
+  }
+  bool operator!=(const ConstIterator &RHS) const {
+    return Ptr != RHS.operator->();
+  }
+
+  inline DenseMapIterator& operator++() {  // Preincrement
+    ++Ptr;
+    AdvancePastEmptyBuckets();
+    return *this;
+  }
+  DenseMapIterator operator++(int) {  // Postincrement
+    DenseMapIterator tmp = *this; ++*this; return tmp;
+  }
+
+private:
+  void AdvancePastEmptyBuckets() {
+    const KeyT Empty = KeyInfoT::getEmptyKey();
+    const KeyT Tombstone = KeyInfoT::getTombstoneKey();
+
+    while (Ptr != End &&
+           (KeyInfoT::isEqual(Ptr->first, Empty) ||
+            KeyInfoT::isEqual(Ptr->first, Tombstone)))
+      ++Ptr;
+  }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT>
+static inline size_t
+capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
+  return X.getMemorySize();
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
new file mode 100644
index 0000000..6f17a64
--- /dev/null
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -0,0 +1,168 @@
+//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- 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 DenseMapInfo traits for DenseMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAPINFO_H
+#define LLVM_ADT_DENSEMAPINFO_H
+
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo {
+  //static inline T getEmptyKey();
+  //static inline T getTombstoneKey();
+  //static unsigned getHashValue(const T &Val);
+  //static bool isEqual(const T &LHS, const T &RHS);
+};
+
+// Provide DenseMapInfo for all pointers.
+template<typename T>
+struct DenseMapInfo<T*> {
+  static inline T* getEmptyKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-1);
+    Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+    return reinterpret_cast<T*>(Val);
+  }
+  static inline T* getTombstoneKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-2);
+    Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+    return reinterpret_cast<T*>(Val);
+  }
+  static unsigned getHashValue(const T *PtrVal) {
+    return (unsigned((uintptr_t)PtrVal) >> 4) ^
+           (unsigned((uintptr_t)PtrVal) >> 9);
+  }
+  static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
+};
+
+// Provide DenseMapInfo for chars.
+template<> struct DenseMapInfo<char> {
+  static inline char getEmptyKey() { return ~0; }
+  static inline char getTombstoneKey() { return ~0 - 1; }
+  static unsigned getHashValue(const char& Val) { return Val * 37U; }
+  static bool isEqual(const char &LHS, const char &RHS) {
+    return LHS == RHS;
+  }
+};
+  
+// Provide DenseMapInfo for unsigned ints.
+template<> struct DenseMapInfo<unsigned> {
+  static inline unsigned getEmptyKey() { return ~0U; }
+  static inline unsigned getTombstoneKey() { return ~0U - 1; }
+  static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
+  static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for unsigned longs.
+template<> struct DenseMapInfo<unsigned long> {
+  static inline unsigned long getEmptyKey() { return ~0UL; }
+  static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
+  static unsigned getHashValue(const unsigned long& Val) {
+    return (unsigned)(Val * 37UL);
+  }
+  static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for unsigned long longs.
+template<> struct DenseMapInfo<unsigned long long> {
+  static inline unsigned long long getEmptyKey() { return ~0ULL; }
+  static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
+  static unsigned getHashValue(const unsigned long long& Val) {
+    return (unsigned)(Val * 37ULL);
+  }
+  static bool isEqual(const unsigned long long& LHS,
+                      const unsigned long long& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for ints.
+template<> struct DenseMapInfo<int> {
+  static inline int getEmptyKey() { return 0x7fffffff; }
+  static inline int getTombstoneKey() { return -0x7fffffff - 1; }
+  static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
+  static bool isEqual(const int& LHS, const int& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for longs.
+template<> struct DenseMapInfo<long> {
+  static inline long getEmptyKey() {
+    return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
+  }
+  static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
+  static unsigned getHashValue(const long& Val) {
+    return (unsigned)(Val * 37UL);
+  }
+  static bool isEqual(const long& LHS, const long& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for long longs.
+template<> struct DenseMapInfo<long long> {
+  static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
+  static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
+  static unsigned getHashValue(const long long& Val) {
+    return (unsigned)(Val * 37ULL);
+  }
+  static bool isEqual(const long long& LHS,
+                      const long long& RHS) {
+    return LHS == RHS;
+  }
+};
+
+// Provide DenseMapInfo for all pairs whose members have info.
+template<typename T, typename U>
+struct DenseMapInfo<std::pair<T, U> > {
+  typedef std::pair<T, U> Pair;
+  typedef DenseMapInfo<T> FirstInfo;
+  typedef DenseMapInfo<U> SecondInfo;
+
+  static inline Pair getEmptyKey() {
+    return std::make_pair(FirstInfo::getEmptyKey(),
+                          SecondInfo::getEmptyKey());
+  }
+  static inline Pair getTombstoneKey() {
+    return std::make_pair(FirstInfo::getTombstoneKey(),
+                          SecondInfo::getTombstoneKey());
+  }
+  static unsigned getHashValue(const Pair& PairVal) {
+    uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
+          | (uint64_t)SecondInfo::getHashValue(PairVal.second);
+    key += ~(key << 32);
+    key ^= (key >> 22);
+    key += ~(key << 13);
+    key ^= (key >> 8);
+    key += (key << 3);
+    key ^= (key >> 15);
+    key += ~(key << 27);
+    key ^= (key >> 31);
+    return (unsigned)key;
+  }
+  static bool isEqual(const Pair &LHS, const Pair &RHS) {
+    return FirstInfo::isEqual(LHS.first, RHS.first) &&
+           SecondInfo::isEqual(LHS.second, RHS.second);
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
new file mode 100644
index 0000000..37a81b0
--- /dev/null
+++ b/include/llvm/ADT/DenseSet.h
@@ -0,0 +1,130 @@
+//===- llvm/ADT/DenseSet.h - Dense probed hash table ------------*- 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 DenseSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSESET_H
+#define LLVM_ADT_DENSESET_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+/// DenseSet - This implements a dense probed hash-table based set.
+///
+/// FIXME: This is currently implemented directly in terms of DenseMap, this
+/// should be optimized later if there is a need.
+template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseSet {
+  typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
+  MapTy TheMap;
+public:
+  typedef ValueT key_type;
+  typedef ValueT value_type;
+  typedef unsigned size_type;

+
+  explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
+
+  bool empty() const { return TheMap.empty(); }
+  size_type size() const { return TheMap.size(); }
+  size_t getMemorySize() const { return TheMap.getMemorySize(); }
+
+  /// Grow the DenseSet so that it has at least Size buckets. Will not shrink
+  /// the Size of the set.
+  void resize(size_t Size) { TheMap.resize(Size); }
+
+  void clear() {
+    TheMap.clear();
+  }
+
+  /// Return 1 if the specified key is in the set, 0 otherwise.

+  size_type count(const ValueT &V) const {
+    return TheMap.count(V);
+  }
+
+  bool erase(const ValueT &V) {
+    return TheMap.erase(V);
+  }
+
+  void swap(DenseSet& RHS) {
+    TheMap.swap(RHS.TheMap);
+  }
+
+  // Iterators.
+
+  class Iterator {
+    typename MapTy::iterator I;
+    friend class DenseSet;
+  public:
+    typedef typename MapTy::iterator::difference_type difference_type;
+    typedef ValueT value_type;
+    typedef value_type *pointer;
+    typedef value_type &reference;
+    typedef std::forward_iterator_tag iterator_category;
+
+    Iterator(const typename MapTy::iterator &i) : I(i) {}
+
+    ValueT& operator*() { return I->first; }
+    ValueT* operator->() { return &I->first; }
+
+    Iterator& operator++() { ++I; return *this; }
+    bool operator==(const Iterator& X) const { return I == X.I; }
+    bool operator!=(const Iterator& X) const { return I != X.I; }
+  };
+
+  class ConstIterator {
+    typename MapTy::const_iterator I;
+    friend class DenseSet;
+  public:
+    typedef typename MapTy::const_iterator::difference_type difference_type;
+    typedef ValueT value_type;
+    typedef value_type *pointer;
+    typedef value_type &reference;
+    typedef std::forward_iterator_tag iterator_category;
+
+    ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
+
+    const ValueT& operator*() { return I->first; }
+    const ValueT* operator->() { return &I->first; }
+
+    ConstIterator& operator++() { ++I; return *this; }
+    bool operator==(const ConstIterator& X) const { return I == X.I; }
+    bool operator!=(const ConstIterator& X) const { return I != X.I; }
+  };
+
+  typedef Iterator      iterator;
+  typedef ConstIterator const_iterator;
+
+  iterator begin() { return Iterator(TheMap.begin()); }
+  iterator end() { return Iterator(TheMap.end()); }
+
+  const_iterator begin() const { return ConstIterator(TheMap.begin()); }
+  const_iterator end() const { return ConstIterator(TheMap.end()); }
+
+  iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); }
+  void erase(Iterator I) { return TheMap.erase(I.I); }
+  void erase(ConstIterator CI) { return TheMap.erase(CI.I); }
+
+  std::pair<iterator, bool> insert(const ValueT &V) {
+    return TheMap.insert(std::make_pair(V, 0));
+  }
+  
+  // Range insertion of values.
+  template<typename InputIt>
+  void insert(InputIt I, InputIt E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
new file mode 100644
index 0000000..dfba43f
--- /dev/null
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -0,0 +1,281 @@
+//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build generic depth
+// first graph iterator.  This file exposes the following functions/types:
+//
+// df_begin/df_end/df_iterator
+//   * Normal depth-first iteration - visit a node and then all of its children.
+//
+// idf_begin/idf_end/idf_iterator
+//   * Depth-first iteration on the 'inverse' graph.
+//
+// df_ext_begin/df_ext_end/df_ext_iterator
+//   * Normal depth-first iteration - visit a node and then all of its children.
+//     This iterator stores the 'visited' set in an external set, which allows
+//     it to be more efficient, and allows external clients to use the set for
+//     other purposes.
+//
+// idf_ext_begin/idf_ext_end/idf_ext_iterator
+//   * Depth-first iteration on the 'inverse' graph.
+//     This iterator stores the 'visited' set in an external set, which allows
+//     it to be more efficient, and allows external clients to use the set for
+//     other purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
+#define LLVM_ADT_DEPTHFIRSTITERATOR_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// df_iterator_storage - A private class which is used to figure out where to
+// store the visited set.
+template<class SetType, bool External>   // Non-external set
+class df_iterator_storage {
+public:
+  SetType Visited;
+};
+
+template<class SetType>
+class df_iterator_storage<SetType, true> {
+public:
+  df_iterator_storage(SetType &VSet) : Visited(VSet) {}
+  df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
+  SetType &Visited;
+};
+
+
+// Generic Depth First Iterator
+template<class GraphT,
+class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+         bool ExtStorage = false, class GT = GraphTraits<GraphT> >
+class df_iterator : public std::iterator<std::forward_iterator_tag,
+                                         typename GT::NodeType, ptrdiff_t>,
+                    public df_iterator_storage<SetType, ExtStorage> {
+  typedef std::iterator<std::forward_iterator_tag,
+                        typename GT::NodeType, ptrdiff_t> super;
+
+  typedef typename GT::NodeType          NodeType;
+  typedef typename GT::ChildIteratorType ChildItTy;
+  typedef PointerIntPair<NodeType*, 1>   PointerIntTy;
+
+  // VisitStack - Used to maintain the ordering.  Top = current block
+  // First element is node pointer, second is the 'next child' to visit
+  // if the int in PointerIntTy is 0, the 'next child' to visit is invalid
+  std::vector<std::pair<PointerIntTy, ChildItTy> > VisitStack;
+private:
+  inline df_iterator(NodeType *Node) {
+    this->Visited.insert(Node);
+    VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0), 
+                                        GT::child_begin(Node)));
+  }
+  inline df_iterator() { 
+    // End is when stack is empty 
+  }
+  inline df_iterator(NodeType *Node, SetType &S)
+    : df_iterator_storage<SetType, ExtStorage>(S) {
+    if (!S.count(Node)) {
+      VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0), 
+                                          GT::child_begin(Node)));
+      this->Visited.insert(Node);
+    }
+  }
+  inline df_iterator(SetType &S)
+    : df_iterator_storage<SetType, ExtStorage>(S) {
+    // End is when stack is empty
+  }
+
+  inline void toNext() {
+    do {
+      std::pair<PointerIntTy, ChildItTy> &Top = VisitStack.back();
+      NodeType *Node = Top.first.getPointer();
+      ChildItTy &It  = Top.second;
+      if (!Top.first.getInt()) {
+        // now retrieve the real begin of the children before we dive in
+        It = GT::child_begin(Node);
+        Top.first.setInt(1);
+      }
+
+      while (It != GT::child_end(Node)) {
+        NodeType *Next = *It++;
+        // Has our next sibling been visited?
+        if (Next && !this->Visited.count(Next)) {  
+          // No, do it now.
+          this->Visited.insert(Next);
+          VisitStack.push_back(std::make_pair(PointerIntTy(Next, 0), 
+                                              GT::child_begin(Next)));
+          return;
+        }
+      }
+
+      // Oops, ran out of successors... go up a level on the stack.
+      VisitStack.pop_back();
+    } while (!VisitStack.empty());
+  }
+
+public:
+  typedef typename super::pointer pointer;
+  typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+  // Provide static begin and end methods as our public "constructors"
+  static inline _Self begin(const GraphT& G) {
+    return _Self(GT::getEntryNode(G));
+  }
+  static inline _Self end(const GraphT& G) { return _Self(); }
+
+  // Static begin and end methods as our public ctors for external iterators
+  static inline _Self begin(const GraphT& G, SetType &S) {
+    return _Self(GT::getEntryNode(G), S);
+  }
+  static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
+
+  inline bool operator==(const _Self& x) const {
+    return VisitStack == x.VisitStack;
+  }
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  inline pointer operator*() const {
+    return VisitStack.back().first.getPointer();
+  }
+
+  // This is a nonstandard operator-> that dereferences the pointer an extra
+  // time... so that you can actually call methods ON the Node, because
+  // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
+  //
+  inline NodeType *operator->() const { return operator*(); }
+
+  inline _Self& operator++() {   // Preincrement
+    toNext();
+    return *this;
+  }
+
+  // skips all children of the current node and traverses to next node
+  //
+  inline _Self& skipChildren() {  
+    VisitStack.pop_back();
+    if (!VisitStack.empty())
+      toNext();
+    return *this;
+  }
+
+  inline _Self operator++(int) { // Postincrement
+    _Self tmp = *this; ++*this; return tmp;
+  }
+
+  // nodeVisited - return true if this iterator has already visited the
+  // specified node.  This is public, and will probably be used to iterate over
+  // nodes that a depth first iteration did not find: ie unreachable nodes.
+  //
+  inline bool nodeVisited(NodeType *Node) const {
+    return this->Visited.count(Node) != 0;
+  }
+
+  /// getPathLength - Return the length of the path from the entry node to the
+  /// current node, counting both nodes.
+  unsigned getPathLength() const { return VisitStack.size(); }
+
+  /// getPath - Return the n'th node in the path from the entry node to the
+  /// current node.
+  NodeType *getPath(unsigned n) const {
+    return VisitStack[n].first.getPointer();
+  }
+};
+
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+df_iterator<T> df_begin(const T& G) {
+  return df_iterator<T>::begin(G);
+}
+
+template <class T>
+df_iterator<T> df_end(const T& G) {
+  return df_iterator<T>::end(G);
+}
+
+// Provide an accessor method to use them in range-based patterns.
+template <class T>
+iterator_range<df_iterator<T>> depth_first(const T& G) {
+  return iterator_range<df_iterator<T>>(df_begin(G), df_end(G));
+}
+
+// Provide global definitions of external depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct df_ext_iterator : public df_iterator<T, SetTy, true> {
+  df_ext_iterator(const df_iterator<T, SetTy, true> &V)
+    : df_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_begin(const T& G, SetTy &S) {
+  return df_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
+  return df_ext_iterator<T, SetTy>::end(G, S);
+}
+
+
+// Provide global definitions of inverse depth first iterators...
+template <class T,
+  class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
+          bool External = false>
+struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
+  idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
+    : df_iterator<Inverse<T>, SetTy, External>(V) {}
+};
+
+template <class T>
+idf_iterator<T> idf_begin(const T& G) {
+  return idf_iterator<T>::begin(Inverse<T>(G));
+}
+
+template <class T>
+idf_iterator<T> idf_end(const T& G){
+  return idf_iterator<T>::end(Inverse<T>(G));
+}
+
+// Provide an accessor method to use them in range-based patterns.
+template <class T>
+iterator_range<idf_iterator<T>> inverse_depth_first(const T& G) {
+  return iterator_range<idf_iterator<T>>(idf_begin(G), idf_end(G));
+}
+
+// Provide global definitions of external inverse depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
+  idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
+    : idf_iterator<T, SetTy, true>(V) {}
+  idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
+    : idf_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_begin(const T& G, SetTy &S) {
+  return idf_ext_iterator<T, SetTy>::begin(Inverse<T>(G), S);
+}
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
+  return idf_ext_iterator<T, SetTy>::end(Inverse<T>(G), S);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
new file mode 100644
index 0000000..e0396c7
--- /dev/null
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -0,0 +1,282 @@
+//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic implementation of equivalence classes through the use Tarjan's
+// efficient union-find algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
+#define LLVM_ADT_EQUIVALENCECLASSES_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <set>
+
+namespace llvm {
+
+/// EquivalenceClasses - This represents a collection of equivalence classes and
+/// supports three efficient operations: insert an element into a class of its
+/// own, union two classes, and find the class for a given element.  In
+/// addition to these modification methods, it is possible to iterate over all
+/// of the equivalence classes and all of the elements in a class.
+///
+/// This implementation is an efficient implementation that only stores one copy
+/// of the element being indexed per entry in the set, and allows any arbitrary
+/// type to be indexed (as long as it can be ordered with operator<).
+///
+/// Here is a simple example using integers:
+///
+/// \code
+///  EquivalenceClasses<int> EC;
+///  EC.unionSets(1, 2);                // insert 1, 2 into the same set
+///  EC.insert(4); EC.insert(5);        // insert 4, 5 into own sets
+///  EC.unionSets(5, 1);                // merge the set for 1 with 5's set.
+///
+///  for (EquivalenceClasses<int>::iterator I = EC.begin(), E = EC.end();
+///       I != E; ++I) {           // Iterate over all of the equivalence sets.
+///    if (!I->isLeader()) continue;   // Ignore non-leader sets.
+///    for (EquivalenceClasses<int>::member_iterator MI = EC.member_begin(I);
+///         MI != EC.member_end(); ++MI)   // Loop over members in this set.
+///      cerr << *MI << " ";  // Print member.
+///    cerr << "\n";   // Finish set.
+///  }
+/// \endcode
+///
+/// This example prints:
+///   4
+///   5 1 2
+///
+template <class ElemTy>
+class EquivalenceClasses {
+  /// ECValue - The EquivalenceClasses data structure is just a set of these.
+  /// Each of these represents a relation for a value.  First it stores the
+  /// value itself, which provides the ordering that the set queries.  Next, it
+  /// provides a "next pointer", which is used to enumerate all of the elements
+  /// in the unioned set.  Finally, it defines either a "end of list pointer" or
+  /// "leader pointer" depending on whether the value itself is a leader.  A
+  /// "leader pointer" points to the node that is the leader for this element,
+  /// if the node is not a leader.  A "end of list pointer" points to the last
+  /// node in the list of members of this list.  Whether or not a node is a
+  /// leader is determined by a bit stolen from one of the pointers.
+  class ECValue {
+    friend class EquivalenceClasses;
+    mutable const ECValue *Leader, *Next;
+    ElemTy Data;
+    // ECValue ctor - Start out with EndOfList pointing to this node, Next is
+    // Null, isLeader = true.
+    ECValue(const ElemTy &Elt)
+      : Leader(this), Next((ECValue*)(intptr_t)1), Data(Elt) {}
+
+    const ECValue *getLeader() const {
+      if (isLeader()) return this;
+      if (Leader->isLeader()) return Leader;
+      // Path compression.
+      return Leader = Leader->getLeader();
+    }
+    const ECValue *getEndOfList() const {
+      assert(isLeader() && "Cannot get the end of a list for a non-leader!");
+      return Leader;
+    }
+
+    void setNext(const ECValue *NewNext) const {
+      assert(getNext() == nullptr && "Already has a next pointer!");
+      Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader());
+    }
+  public:
+    ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1),
+                                  Data(RHS.Data) {
+      // Only support copying of singleton nodes.
+      assert(RHS.isLeader() && RHS.getNext() == nullptr && "Not a singleton!");
+    }
+
+    bool operator<(const ECValue &UFN) const { return Data < UFN.Data; }
+
+    bool isLeader() const { return (intptr_t)Next & 1; }
+    const ElemTy &getData() const { return Data; }
+
+    const ECValue *getNext() const {
+      return (ECValue*)((intptr_t)Next & ~(intptr_t)1);
+    }
+
+    template<typename T>
+    bool operator<(const T &Val) const { return Data < Val; }
+  };
+
+  /// TheMapping - This implicitly provides a mapping from ElemTy values to the
+  /// ECValues, it just keeps the key as part of the value.
+  std::set<ECValue> TheMapping;
+
+public:
+  EquivalenceClasses() {}
+  EquivalenceClasses(const EquivalenceClasses &RHS) {
+    operator=(RHS);
+  }
+
+  const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) {
+    TheMapping.clear();
+    for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
+      if (I->isLeader()) {
+        member_iterator MI = RHS.member_begin(I);
+        member_iterator LeaderIt = member_begin(insert(*MI));
+        for (++MI; MI != member_end(); ++MI)
+          unionSets(LeaderIt, member_begin(insert(*MI)));
+      }
+    return *this;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Inspection methods
+  //
+
+  /// iterator* - Provides a way to iterate over all values in the set.
+  typedef typename std::set<ECValue>::const_iterator iterator;
+  iterator begin() const { return TheMapping.begin(); }
+  iterator end() const { return TheMapping.end(); }
+
+  bool empty() const { return TheMapping.empty(); }
+
+  /// member_* Iterate over the members of an equivalence class.
+  ///
+  class member_iterator;
+  member_iterator member_begin(iterator I) const {
+    // Only leaders provide anything to iterate over.
+    return member_iterator(I->isLeader() ? &*I : nullptr);
+  }
+  member_iterator member_end() const {
+    return member_iterator(nullptr);
+  }
+
+  /// findValue - Return an iterator to the specified value.  If it does not
+  /// exist, end() is returned.
+  iterator findValue(const ElemTy &V) const {
+    return TheMapping.find(V);
+  }
+
+  /// getLeaderValue - Return the leader for the specified value that is in the
+  /// set.  It is an error to call this method for a value that is not yet in
+  /// the set.  For that, call getOrInsertLeaderValue(V).
+  const ElemTy &getLeaderValue(const ElemTy &V) const {
+    member_iterator MI = findLeader(V);
+    assert(MI != member_end() && "Value is not in the set!");
+    return *MI;
+  }
+
+  /// getOrInsertLeaderValue - Return the leader for the specified value that is
+  /// in the set.  If the member is not in the set, it is inserted, then
+  /// returned.
+  const ElemTy &getOrInsertLeaderValue(const ElemTy &V) {
+    member_iterator MI = findLeader(insert(V));
+    assert(MI != member_end() && "Value is not in the set!");
+    return *MI;
+  }
+
+  /// getNumClasses - Return the number of equivalence classes in this set.
+  /// Note that this is a linear time operation.
+  unsigned getNumClasses() const {
+    unsigned NC = 0;
+    for (iterator I = begin(), E = end(); I != E; ++I)
+      if (I->isLeader()) ++NC;
+    return NC;
+  }
+
+
+  //===--------------------------------------------------------------------===//
+  // Mutation methods
+
+  /// insert - Insert a new value into the union/find set, ignoring the request
+  /// if the value already exists.
+  iterator insert(const ElemTy &Data) {
+    return TheMapping.insert(ECValue(Data)).first;
+  }
+
+  /// findLeader - Given a value in the set, return a member iterator for the
+  /// equivalence class it is in.  This does the path-compression part that
+  /// makes union-find "union findy".  This returns an end iterator if the value
+  /// is not in the equivalence class.
+  ///
+  member_iterator findLeader(iterator I) const {
+    if (I == TheMapping.end()) return member_end();
+    return member_iterator(I->getLeader());
+  }
+  member_iterator findLeader(const ElemTy &V) const {
+    return findLeader(TheMapping.find(V));
+  }
+
+
+  /// union - Merge the two equivalence sets for the specified values, inserting
+  /// them if they do not already exist in the equivalence set.
+  member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) {
+    iterator V1I = insert(V1), V2I = insert(V2);
+    return unionSets(findLeader(V1I), findLeader(V2I));
+  }
+  member_iterator unionSets(member_iterator L1, member_iterator L2) {
+    assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!");
+    if (L1 == L2) return L1;   // Unifying the same two sets, noop.
+
+    // Otherwise, this is a real union operation.  Set the end of the L1 list to
+    // point to the L2 leader node.
+    const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node;
+    L1LV.getEndOfList()->setNext(&L2LV);
+
+    // Update L1LV's end of list pointer.
+    L1LV.Leader = L2LV.getEndOfList();
+
+    // Clear L2's leader flag:
+    L2LV.Next = L2LV.getNext();
+
+    // L2's leader is now L1.
+    L2LV.Leader = &L1LV;
+    return L1;
+  }
+
+  class member_iterator : public std::iterator<std::forward_iterator_tag,
+                                               const ElemTy, ptrdiff_t> {
+    typedef std::iterator<std::forward_iterator_tag,
+                          const ElemTy, ptrdiff_t> super;
+    const ECValue *Node;
+    friend class EquivalenceClasses;
+  public:
+    typedef size_t size_type;
+    typedef typename super::pointer pointer;
+    typedef typename super::reference reference;
+
+    explicit member_iterator() {}
+    explicit member_iterator(const ECValue *N) : Node(N) {}
+
+    reference operator*() const {
+      assert(Node != nullptr && "Dereferencing end()!");
+      return Node->getData();
+    }
+    reference operator->() const { return operator*(); }
+
+    member_iterator &operator++() {
+      assert(Node != nullptr && "++'d off the end of the list!");
+      Node = Node->getNext();
+      return *this;
+    }
+
+    member_iterator operator++(int) {    // postincrement operators.
+      member_iterator tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    bool operator==(const member_iterator &RHS) const {
+      return Node == RHS.Node;
+    }
+    bool operator!=(const member_iterator &RHS) const {
+      return Node != RHS.Node;
+    }
+  };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 0000000..14c5933
--- /dev/null
+++ b/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,807 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- 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 hash set that can be used to remove duplication of nodes
+// in a graph.  This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FOLDINGSET_H
+#define LLVM_ADT_FOLDINGSET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class APFloat;
+  class APInt;
+
+/// This folding set used for two purposes:
+///   1. Given information about a node we want to create, look up the unique
+///      instance of the node in the set.  If the node already exists, return
+///      it, otherwise return the bucket it should be inserted into.
+///   2. Given a node that has already been created, remove it from the set.
+///
+/// This class is implemented as a single-link chained hash table, where the
+/// "buckets" are actually the nodes themselves (the next pointer is in the
+/// node).  The last node points back to the bucket to simplify node removal.
+///
+/// Any node that is to be included in the folding set must be a subclass of
+/// FoldingSetNode.  The node class must also define a Profile method used to
+/// establish the unique bits of data for the node.  The Profile method is
+/// passed a FoldingSetNodeID object which is used to gather the bits.  Just
+/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+/// NOTE: That the folding set does not own the nodes and it is the
+/// responsibility of the user to dispose of the nodes.
+///
+/// Eg.
+///    class MyNode : public FoldingSetNode {
+///    private:
+///      std::string Name;
+///      unsigned Value;
+///    public:
+///      MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+///       ...
+///      void Profile(FoldingSetNodeID &ID) const {
+///        ID.AddString(Name);
+///        ID.AddInteger(Value);
+///      }
+///      ...
+///    };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+///    FoldingSet<MyNode> MyFoldingSet;
+///
+/// Four public methods are available to manipulate the folding set;
+///
+/// 1) If you have an existing node that you want add to the set but unsure
+/// that the node might already exist then call;
+///
+///    MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+///   FoldingSetNodeID ID;
+///   ID.AddString(Name);
+///   ID.AddInteger(Value);
+///   void *InsertPoint;
+///
+///    MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
+/// node with FindNodeOrInsertPos;
+///
+///    InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+///    bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node existed in the folding set.
+
+class FoldingSetNodeID;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality.  The main
+/// structure is an array of buckets.  Each bucket is indexed by the hash of
+/// the nodes it contains.  The bucket itself points to the nodes contained
+/// in the bucket via a singly linked list.  The last node in the list points
+/// back to the bucket to facilitate node removal.
+///
+class FoldingSetImpl {
+protected:
+  /// Buckets - Array of bucket chains.
+  ///
+  void **Buckets;
+
+  /// NumBuckets - Length of the Buckets array.  Always a power of 2.
+  ///
+  unsigned NumBuckets;
+
+  /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
+  /// is greater than twice the number of buckets.
+  unsigned NumNodes;
+
+public:
+  explicit FoldingSetImpl(unsigned Log2InitSize = 6);
+  virtual ~FoldingSetImpl();
+
+  //===--------------------------------------------------------------------===//
+  /// Node - This class is used to maintain the singly linked bucket list in
+  /// a folding set.
+  ///
+  class Node {
+  private:
+    // NextInFoldingSetBucket - next link in the bucket list.
+    void *NextInFoldingSetBucket;
+
+  public:
+
+    Node() : NextInFoldingSetBucket(nullptr) {}
+
+    // Accessors
+    void *getNextInBucket() const { return NextInFoldingSetBucket; }
+    void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
+  };
+
+  /// clear - Remove all nodes from the folding set.
+  void clear();
+
+  /// RemoveNode - Remove a node from the folding set, returning true if one
+  /// was removed or false if the node was not in the folding set.
+  bool RemoveNode(Node *N);
+
+  /// GetOrInsertNode - If there is an existing simple Node exactly
+  /// equal to the specified node, return it.  Otherwise, insert 'N' and return
+  /// it instead.
+  Node *GetOrInsertNode(Node *N);
+
+  /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
+  /// return it.  If not, return the insertion token that will make insertion
+  /// faster.
+  Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
+
+  /// InsertNode - Insert the specified node into the folding set, knowing that
+  /// it is not already in the folding set.  InsertPos must be obtained from
+  /// FindNodeOrInsertPos.
+  void InsertNode(Node *N, void *InsertPos);
+
+  /// InsertNode - Insert the specified node into the folding set, knowing that
+  /// it is not already in the folding set.
+  void InsertNode(Node *N) {
+    Node *Inserted = GetOrInsertNode(N);
+    (void)Inserted;
+    assert(Inserted == N && "Node already inserted!");
+  }
+
+  /// size - Returns the number of nodes in the folding set.
+  unsigned size() const { return NumNodes; }
+
+  /// empty - Returns true if there are no nodes in the folding set.
+  bool empty() const { return NumNodes == 0; }
+
+private:
+
+  /// GrowHashTable - Double the size of the hash table and rehash everything.
+  ///
+  void GrowHashTable();
+
+protected:
+
+  /// GetNodeProfile - Instantiations of the FoldingSet template implement
+  /// this function to gather data bits for the given node.
+  virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
+  /// NodeEquals - Instantiations of the FoldingSet template implement
+  /// this function to compare the given node with the given ID.
+  virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+                          FoldingSetNodeID &TempID) const=0;
+  /// ComputeNodeHash - Instantiations of the FoldingSet template implement
+  /// this function to compute a hash value for the given node.
+  virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
+};
+
+//===----------------------------------------------------------------------===//
+
+template<typename T> struct FoldingSetTrait;
+
+/// DefaultFoldingSetTrait - This class provides default implementations
+/// for FoldingSetTrait implementations.
+///
+template<typename T> struct DefaultFoldingSetTrait {
+  static void Profile(const T &X, FoldingSetNodeID &ID) {
+    X.Profile(ID);
+  }
+  static void Profile(T &X, FoldingSetNodeID &ID) {
+    X.Profile(ID);
+  }
+
+  // Equals - Test if the profile for X would match ID, using TempID
+  // to compute a temporary ID if necessary. The default implementation
+  // just calls Profile and does a regular comparison. Implementations
+  // can override this to provide more efficient implementations.
+  static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
+                            FoldingSetNodeID &TempID);
+
+  // ComputeHash - Compute a hash value for X, using TempID to
+  // compute a temporary ID if necessary. The default implementation
+  // just calls Profile and does a regular hash computation.
+  // Implementations can override this to provide more efficient
+  // implementations.
+  static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID);
+};
+
+/// FoldingSetTrait - This trait class is used to define behavior of how
+/// to "profile" (in the FoldingSet parlance) an object of a given type.
+/// The default behavior is to invoke a 'Profile' method on an object, but
+/// through template specialization the behavior can be tailored for specific
+/// types.  Combined with the FoldingSetNodeWrapper class, one can add objects
+/// to FoldingSets that were not originally designed to have that behavior.
+template<typename T> struct FoldingSetTrait
+  : public DefaultFoldingSetTrait<T> {};
+
+template<typename T, typename Ctx> struct ContextualFoldingSetTrait;
+
+/// DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but
+/// for ContextualFoldingSets.
+template<typename T, typename Ctx>
+struct DefaultContextualFoldingSetTrait {
+  static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
+    X.Profile(ID, Context);
+  }
+  static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
+                            FoldingSetNodeID &TempID, Ctx Context);
+  static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
+                                     Ctx Context);
+};
+
+/// ContextualFoldingSetTrait - Like FoldingSetTrait, but for
+/// ContextualFoldingSets.
+template<typename T, typename Ctx> struct ContextualFoldingSetTrait
+  : public DefaultContextualFoldingSetTrait<T, Ctx> {};
+
+//===--------------------------------------------------------------------===//
+/// FoldingSetNodeIDRef - This class describes a reference to an interned
+/// FoldingSetNodeID, which can be a useful to store node id data rather
+/// than using plain FoldingSetNodeIDs, since the 32-element SmallVector
+/// is often much larger than necessary, and the possibility of heap
+/// allocation means it requires a non-trivial destructor call.
+class FoldingSetNodeIDRef {
+  const unsigned *Data;
+  size_t Size;
+public:
+  FoldingSetNodeIDRef() : Data(nullptr), Size(0) {}
+  FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
+
+  /// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
+  /// used to lookup the node in the FoldingSetImpl.
+  unsigned ComputeHash() const;
+
+  bool operator==(FoldingSetNodeIDRef) const;
+
+  bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
+
+  /// Used to compare the "ordering" of two nodes as defined by the
+  /// profiled bits and their ordering defined by memcmp().
+  bool operator<(FoldingSetNodeIDRef) const;
+
+  const unsigned *getData() const { return Data; }
+  size_t getSize() const { return Size; }
+};
+
+//===--------------------------------------------------------------------===//
+/// FoldingSetNodeID - This class is used to gather all the unique data bits of
+/// a node.  When all the bits are gathered this class is used to produce a
+/// hash value for the node.
+///
+class FoldingSetNodeID {
+  /// Bits - Vector of all the data bits that make the node unique.
+  /// Use a SmallVector to avoid a heap allocation in the common case.
+  SmallVector<unsigned, 32> Bits;
+
+public:
+  FoldingSetNodeID() {}
+
+  FoldingSetNodeID(FoldingSetNodeIDRef Ref)
+    : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
+
+  /// Add* - Add various data types to Bit data.
+  ///
+  void AddPointer(const void *Ptr);
+  void AddInteger(signed I);
+  void AddInteger(unsigned I);
+  void AddInteger(long I);
+  void AddInteger(unsigned long I);
+  void AddInteger(long long I);
+  void AddInteger(unsigned long long I);
+  void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
+  void AddString(StringRef String);
+  void AddNodeID(const FoldingSetNodeID &ID);
+
+  template <typename T>
+  inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
+
+  /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
+  /// object to be used to compute a new profile.
+  inline void clear() { Bits.clear(); }
+
+  /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
+  /// to lookup the node in the FoldingSetImpl.
+  unsigned ComputeHash() const;
+
+  /// operator== - Used to compare two nodes to each other.
+  ///
+  bool operator==(const FoldingSetNodeID &RHS) const;
+  bool operator==(const FoldingSetNodeIDRef RHS) const;
+
+  bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
+  bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);}
+
+  /// Used to compare the "ordering" of two nodes as defined by the
+  /// profiled bits and their ordering defined by memcmp().
+  bool operator<(const FoldingSetNodeID &RHS) const;
+  bool operator<(const FoldingSetNodeIDRef RHS) const;
+
+  /// Intern - Copy this node's data to a memory region allocated from the
+  /// given allocator and return a FoldingSetNodeIDRef describing the
+  /// interned data.
+  FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
+};
+
+// Convenience type to hide the implementation of the folding set.
+typedef FoldingSetImpl::Node FoldingSetNode;
+template<class T> class FoldingSetIterator;
+template<class T> class FoldingSetBucketIterator;
+
+// Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
+// require the definition of FoldingSetNodeID.
+template<typename T>
+inline bool
+DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID,
+                                  unsigned /*IDHash*/,
+                                  FoldingSetNodeID &TempID) {
+  FoldingSetTrait<T>::Profile(X, TempID);
+  return TempID == ID;
+}
+template<typename T>
+inline unsigned
+DefaultFoldingSetTrait<T>::ComputeHash(T &X, FoldingSetNodeID &TempID) {
+  FoldingSetTrait<T>::Profile(X, TempID);
+  return TempID.ComputeHash();
+}
+template<typename T, typename Ctx>
+inline bool
+DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X,
+                                                 const FoldingSetNodeID &ID,
+                                                 unsigned /*IDHash*/,
+                                                 FoldingSetNodeID &TempID,
+                                                 Ctx Context) {
+  ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
+  return TempID == ID;
+}
+template<typename T, typename Ctx>
+inline unsigned
+DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
+                                                      FoldingSetNodeID &TempID,
+                                                      Ctx Context) {
+  ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
+  return TempID.ComputeHash();
+}
+
+//===----------------------------------------------------------------------===//
+/// FoldingSet - This template class is used to instantiate a specialized
+/// implementation of the folding set to the node class T.  T must be a
+/// subclass of FoldingSetNode and implement a Profile function.
+///
+template<class T> class FoldingSet : public FoldingSetImpl {
+private:
+  /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+  /// way to convert nodes into a unique specifier.
+  void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
+    T *TN = static_cast<T *>(N);
+    FoldingSetTrait<T>::Profile(*TN, ID);
+  }
+  /// NodeEquals - Instantiations may optionally provide a way to compare a
+  /// node with a specified ID.
+  bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+                  FoldingSetNodeID &TempID) const override {
+    T *TN = static_cast<T *>(N);
+    return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
+  }
+  /// ComputeNodeHash - Instantiations may optionally provide a way to compute a
+  /// hash value directly from a node.
+  unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
+    T *TN = static_cast<T *>(N);
+    return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
+  }
+
+public:
+  explicit FoldingSet(unsigned Log2InitSize = 6)
+  : FoldingSetImpl(Log2InitSize)
+  {}
+
+  typedef FoldingSetIterator<T> iterator;
+  iterator begin() { return iterator(Buckets); }
+  iterator end() { return iterator(Buckets+NumBuckets); }
+
+  typedef FoldingSetIterator<const T> const_iterator;
+  const_iterator begin() const { return const_iterator(Buckets); }
+  const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+  typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+  bucket_iterator bucket_begin(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+  }
+
+  bucket_iterator bucket_end(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+  }
+
+  /// GetOrInsertNode - If there is an existing simple Node exactly
+  /// equal to the specified node, return it.  Otherwise, insert 'N' and
+  /// return it instead.
+  T *GetOrInsertNode(Node *N) {
+    return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+  }
+
+  /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
+  /// return it.  If not, return the insertion token that will make insertion
+  /// faster.
+  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+    return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// ContextualFoldingSet - This template class is a further refinement
+/// of FoldingSet which provides a context argument when calling
+/// Profile on its nodes.  Currently, that argument is fixed at
+/// initialization time.
+///
+/// T must be a subclass of FoldingSetNode and implement a Profile
+/// function with signature
+///   void Profile(llvm::FoldingSetNodeID &, Ctx);
+template <class T, class Ctx>
+class ContextualFoldingSet : public FoldingSetImpl {
+  // Unfortunately, this can't derive from FoldingSet<T> because the
+  // construction vtable for FoldingSet<T> requires
+  // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
+  // requires a single-argument T::Profile().
+
+private:
+  Ctx Context;
+
+  /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+  /// way to convert nodes into a unique specifier.
+  void GetNodeProfile(FoldingSetImpl::Node *N,
+                      FoldingSetNodeID &ID) const override {
+    T *TN = static_cast<T *>(N);
+    ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
+  }
+  bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID,
+                  unsigned IDHash, FoldingSetNodeID &TempID) const override {
+    T *TN = static_cast<T *>(N);
+    return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
+                                                     Context);
+  }
+  unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
+                           FoldingSetNodeID &TempID) const override {
+    T *TN = static_cast<T *>(N);
+    return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
+  }
+
+public:
+  explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
+  : FoldingSetImpl(Log2InitSize), Context(Context)
+  {}
+
+  Ctx getContext() const { return Context; }
+
+
+  typedef FoldingSetIterator<T> iterator;
+  iterator begin() { return iterator(Buckets); }
+  iterator end() { return iterator(Buckets+NumBuckets); }
+
+  typedef FoldingSetIterator<const T> const_iterator;
+  const_iterator begin() const { return const_iterator(Buckets); }
+  const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+  typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+  bucket_iterator bucket_begin(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+  }
+
+  bucket_iterator bucket_end(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+  }
+
+  /// GetOrInsertNode - If there is an existing simple Node exactly
+  /// equal to the specified node, return it.  Otherwise, insert 'N'
+  /// and return it instead.
+  T *GetOrInsertNode(Node *N) {
+    return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+  }
+
+  /// FindNodeOrInsertPos - Look up the node specified by ID.  If it
+  /// exists, return it.  If not, return the insertion token that will
+  /// make insertion faster.
+  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+    return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetVectorIterator - This implements an iterator for
+/// FoldingSetVector. It is only necessary because FoldingSetIterator provides
+/// a value_type of T, while the vector in FoldingSetVector exposes
+/// a value_type of T*. Fortunately, FoldingSetIterator doesn't expose very
+/// much besides operator* and operator->, so we just wrap the inner vector
+/// iterator and perform the extra dereference.
+template <class T, class VectorIteratorT>
+class FoldingSetVectorIterator {
+  // Provide a typedef to workaround the lack of correct injected class name
+  // support in older GCCs.
+  typedef FoldingSetVectorIterator<T, VectorIteratorT> SelfT;
+
+  VectorIteratorT Iterator;
+
+public:
+  FoldingSetVectorIterator(VectorIteratorT I) : Iterator(I) {}
+
+  bool operator==(const SelfT &RHS) const {
+    return Iterator == RHS.Iterator;
+  }
+  bool operator!=(const SelfT &RHS) const {
+    return Iterator != RHS.Iterator;
+  }
+
+  T &operator*() const { return **Iterator; }
+
+  T *operator->() const { return *Iterator; }
+
+  inline SelfT &operator++() {
+    ++Iterator;
+    return *this;
+  }
+  SelfT operator++(int) {
+    SelfT tmp = *this;
+    ++*this;
+    return tmp;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetVector - This template class combines a FoldingSet and a vector
+/// to provide the interface of FoldingSet but with deterministic iteration
+/// order based on the insertion order. T must be a subclass of FoldingSetNode
+/// and implement a Profile function.
+template <class T, class VectorT = SmallVector<T*, 8> >
+class FoldingSetVector {
+  FoldingSet<T> Set;
+  VectorT Vector;
+
+public:
+  explicit FoldingSetVector(unsigned Log2InitSize = 6)
+      : Set(Log2InitSize) {
+  }
+
+  typedef FoldingSetVectorIterator<T, typename VectorT::iterator> iterator;
+  iterator begin() { return Vector.begin(); }
+  iterator end()   { return Vector.end(); }
+
+  typedef FoldingSetVectorIterator<const T, typename VectorT::const_iterator>
+    const_iterator;
+  const_iterator begin() const { return Vector.begin(); }
+  const_iterator end()   const { return Vector.end(); }
+
+  /// clear - Remove all nodes from the folding set.
+  void clear() { Set.clear(); Vector.clear(); }
+
+  /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
+  /// return it.  If not, return the insertion token that will make insertion
+  /// faster.
+  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+    return Set.FindNodeOrInsertPos(ID, InsertPos);
+  }
+
+  /// GetOrInsertNode - If there is an existing simple Node exactly
+  /// equal to the specified node, return it.  Otherwise, insert 'N' and
+  /// return it instead.
+  T *GetOrInsertNode(T *N) {
+    T *Result = Set.GetOrInsertNode(N);
+    if (Result == N) Vector.push_back(N);
+    return Result;
+  }
+
+  /// InsertNode - Insert the specified node into the folding set, knowing that
+  /// it is not already in the folding set.  InsertPos must be obtained from
+  /// FindNodeOrInsertPos.
+  void InsertNode(T *N, void *InsertPos) {
+    Set.InsertNode(N, InsertPos);
+    Vector.push_back(N);
+  }
+
+  /// InsertNode - Insert the specified node into the folding set, knowing that
+  /// it is not already in the folding set.
+  void InsertNode(T *N) {
+    Set.InsertNode(N);
+    Vector.push_back(N);
+  }
+
+  /// size - Returns the number of nodes in the folding set.
+  unsigned size() const { return Set.size(); }
+
+  /// empty - Returns true if there are no nodes in the folding set.
+  bool empty() const { return Set.empty(); }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetIteratorImpl - This is the common iterator support shared by all
+/// folding sets, which knows how to walk the folding set hash table.
+class FoldingSetIteratorImpl {
+protected:
+  FoldingSetNode *NodePtr;
+  FoldingSetIteratorImpl(void **Bucket);
+  void advance();
+
+public:
+  bool operator==(const FoldingSetIteratorImpl &RHS) const {
+    return NodePtr == RHS.NodePtr;
+  }
+  bool operator!=(const FoldingSetIteratorImpl &RHS) const {
+    return NodePtr != RHS.NodePtr;
+  }
+};
+
+
+template<class T>
+class FoldingSetIterator : public FoldingSetIteratorImpl {
+public:
+  explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
+
+  T &operator*() const {
+    return *static_cast<T*>(NodePtr);
+  }
+
+  T *operator->() const {
+    return static_cast<T*>(NodePtr);
+  }
+
+  inline FoldingSetIterator &operator++() {          // Preincrement
+    advance();
+    return *this;
+  }
+  FoldingSetIterator operator++(int) {        // Postincrement
+    FoldingSetIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
+/// shared by all folding sets, which knows how to walk a particular bucket
+/// of a folding set hash table.
+
+class FoldingSetBucketIteratorImpl {
+protected:
+  void *Ptr;
+
+  explicit FoldingSetBucketIteratorImpl(void **Bucket);
+
+  FoldingSetBucketIteratorImpl(void **Bucket, bool)
+    : Ptr(Bucket) {}
+
+  void advance() {
+    void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
+    uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
+    Ptr = reinterpret_cast<void*>(x);
+  }
+
+public:
+  bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
+    return Ptr == RHS.Ptr;
+  }
+  bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const {
+    return Ptr != RHS.Ptr;
+  }
+};
+
+
+template<class T>
+class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
+public:
+  explicit FoldingSetBucketIterator(void **Bucket) :
+    FoldingSetBucketIteratorImpl(Bucket) {}
+
+  FoldingSetBucketIterator(void **Bucket, bool) :
+    FoldingSetBucketIteratorImpl(Bucket, true) {}
+
+  T &operator*() const { return *static_cast<T*>(Ptr); }
+  T *operator->() const { return static_cast<T*>(Ptr); }
+
+  inline FoldingSetBucketIterator &operator++() { // Preincrement
+    advance();
+    return *this;
+  }
+  FoldingSetBucketIterator operator++(int) {      // Postincrement
+    FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
+/// types in an enclosing object so that they can be inserted into FoldingSets.
+template <typename T>
+class FoldingSetNodeWrapper : public FoldingSetNode {
+  T data;
+public:
+  explicit FoldingSetNodeWrapper(const T &x) : data(x) {}
+  virtual ~FoldingSetNodeWrapper() {}
+
+  template<typename A1>
+  explicit FoldingSetNodeWrapper(const A1 &a1)
+    : data(a1) {}
+
+  template <typename A1, typename A2>
+  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2)
+    : data(a1,a2) {}
+
+  template <typename A1, typename A2, typename A3>
+  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3)
+    : data(a1,a2,a3) {}
+
+  template <typename A1, typename A2, typename A3, typename A4>
+  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
+                                 const A4 &a4)
+    : data(a1,a2,a3,a4) {}
+
+  template <typename A1, typename A2, typename A3, typename A4, typename A5>
+  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
+                                 const A4 &a4, const A5 &a5)
+  : data(a1,a2,a3,a4,a5) {}
+
+
+  void Profile(FoldingSetNodeID &ID) { FoldingSetTrait<T>::Profile(data, ID); }
+
+  T &getValue() { return data; }
+  const T &getValue() const { return data; }
+
+  operator T&() { return data; }
+  operator const T&() const { return data; }
+};
+
+//===----------------------------------------------------------------------===//
+/// FastFoldingSetNode - This is a subclass of FoldingSetNode which stores
+/// a FoldingSetNodeID value rather than requiring the node to recompute it
+/// each time it is needed. This trades space for speed (which can be
+/// significant if the ID is long), and it also permits nodes to drop
+/// information that would otherwise only be required for recomputing an ID.
+class FastFoldingSetNode : public FoldingSetNode {
+  FoldingSetNodeID FastID;
+protected:
+  explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
+public:
+  void Profile(FoldingSetNodeID &ID) const { 
+    ID.AddNodeID(FastID); 
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Partial specializations of FoldingSetTrait.
+
+template<typename T> struct FoldingSetTrait<T*> {
+  static inline void Profile(T *X, FoldingSetNodeID &ID) {
+    ID.AddPointer(X);
+  }
+};
+template <typename T1, typename T2>
+struct FoldingSetTrait<std::pair<T1, T2>> {
+  static inline void Profile(const std::pair<T1, T2> &P,
+                             llvm::FoldingSetNodeID &ID) {
+    ID.Add(P.first);
+    ID.Add(P.second);
+  }
+};
+} // End of namespace llvm.
+
+#endif
diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h
new file mode 100644
index 0000000..823caef
--- /dev/null
+++ b/include/llvm/ADT/GraphTraits.h
@@ -0,0 +1,106 @@
+//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- 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 little GraphTraits<X> template class that should be
+// specialized by classes that want to be iteratable by generic graph iterators.
+//
+// This file also defines the marker class Inverse that is used to iterate over
+// graphs in a graph defined, inverse ordering...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_GRAPHTRAITS_H
+#define LLVM_ADT_GRAPHTRAITS_H
+
+namespace llvm {
+
+// GraphTraits - This class should be specialized by different graph types...
+// which is why the default version is empty.
+//
+template<class GraphType>
+struct GraphTraits {
+  // Elements to provide:
+
+  // typedef NodeType          - Type of Node in the graph
+  // typedef ChildIteratorType - Type used to iterate over children in graph
+
+  // static NodeType *getEntryNode(const GraphType &)
+  //    Return the entry node of the graph
+
+  // static ChildIteratorType child_begin(NodeType *)
+  // static ChildIteratorType child_end  (NodeType *)
+  //    Return iterators that point to the beginning and ending of the child
+  //    node list for the specified node.
+  //
+
+
+  // typedef  ...iterator nodes_iterator;
+  // static nodes_iterator nodes_begin(GraphType *G)
+  // static nodes_iterator nodes_end  (GraphType *G)
+  //    nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+
+  // static unsigned       size       (GraphType *G)
+  //    Return total number of nodes in the graph
+  //
+
+
+  // If anyone tries to use this class without having an appropriate
+  // specialization, make an error.  If you get this error, it's because you
+  // need to include the appropriate specialization of GraphTraits<> for your
+  // graph, or you need to define it for a new graph type. Either that or
+  // your argument to XXX_begin(...) is unknown or needs to have the proper .h
+  // file #include'd.
+  //
+  typedef typename GraphType::UnknownGraphTypeError NodeType;
+};
+
+
+// Inverse - This class is used as a little marker class to tell the graph
+// iterator to iterate over the graph in a graph defined "Inverse" ordering.
+// Not all graphs define an inverse ordering, and if they do, it depends on
+// the graph exactly what that is.  Here's an example of usage with the
+// df_iterator:
+//
+// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+// Which is equivalent to:
+// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+template <class GraphType>
+struct Inverse {
+  const GraphType &Graph;
+
+  inline Inverse(const GraphType &G) : Graph(G) {}
+};
+
+// Provide a partial specialization of GraphTraits so that the inverse of an
+// inverse falls back to the original graph.
+template<class T>
+struct GraphTraits<Inverse<Inverse<T> > > {
+  typedef typename GraphTraits<T>::NodeType NodeType;
+  typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
+
+  static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
+    return GraphTraits<T>::getEntryNode(G->Graph.Graph);
+  }
+
+  static ChildIteratorType child_begin(NodeType* N) {
+    return GraphTraits<T>::child_begin(N);
+  }
+
+  static ChildIteratorType child_end(NodeType* N) {
+    return GraphTraits<T>::child_end(N);
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
new file mode 100644
index 0000000..abf02b8
--- /dev/null
+++ b/include/llvm/ADT/Hashing.h
@@ -0,0 +1,764 @@
+//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
+//
+//                     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 newly proposed standard C++ interfaces for hashing
+// arbitrary data and building hash functions for user-defined types. This
+// interface was originally proposed in N3333[1] and is currently under review
+// for inclusion in a future TR and/or standard.
+//
+// The primary interfaces provide are comprised of one type and three functions:
+//
+//  -- 'hash_code' class is an opaque type representing the hash code for some
+//     data. It is the intended product of hashing, and can be used to implement
+//     hash tables, checksumming, and other common uses of hashes. It is not an
+//     integer type (although it can be converted to one) because it is risky
+//     to assume much about the internals of a hash_code. In particular, each
+//     execution of the program has a high probability of producing a different
+//     hash_code for a given input. Thus their values are not stable to save or
+//     persist, and should only be used during the execution for the
+//     construction of hashing datastructures.
+//
+//  -- 'hash_value' is a function designed to be overloaded for each
+//     user-defined type which wishes to be used within a hashing context. It
+//     should be overloaded within the user-defined type's namespace and found
+//     via ADL. Overloads for primitive types are provided by this library.
+//
+//  -- 'hash_combine' and 'hash_combine_range' are functions designed to aid
+//      programmers in easily and intuitively combining a set of data into
+//      a single hash_code for their object. They should only logically be used
+//      within the implementation of a 'hash_value' routine or similar context.
+//
+// Note that 'hash_combine_range' contains very special logic for hashing
+// a contiguous array of integers or pointers. This logic is *extremely* fast,
+// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were
+// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys
+// under 32-bytes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASHING_H
+#define LLVM_ADT_HASHING_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <iterator>
+#include <utility>
+
+// Allow detecting C++11 feature availability when building with Clang without
+// breaking other compilers.
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+namespace llvm {
+
+/// \brief An opaque object representing a hash code.
+///
+/// This object represents the result of hashing some entity. It is intended to
+/// be used to implement hashtables or other hashing-based data structures.
+/// While it wraps and exposes a numeric value, this value should not be
+/// trusted to be stable or predictable across processes or executions.
+///
+/// In order to obtain the hash_code for an object 'x':
+/// \code
+///   using llvm::hash_value;
+///   llvm::hash_code code = hash_value(x);
+/// \endcode
+class hash_code {
+  size_t value;
+
+public:
+  /// \brief Default construct a hash_code.
+  /// Note that this leaves the value uninitialized.
+  hash_code() {}
+
+  /// \brief Form a hash code directly from a numerical value.
+  hash_code(size_t value) : value(value) {}
+
+  /// \brief Convert the hash code to its numerical value for use.
+  /*explicit*/ operator size_t() const { return value; }
+
+  friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
+    return lhs.value == rhs.value;
+  }
+  friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
+    return lhs.value != rhs.value;
+  }
+
+  /// \brief Allow a hash_code to be directly run through hash_value.
+  friend size_t hash_value(const hash_code &code) { return code.value; }
+};
+
+/// \brief Compute a hash_code for any integer value.
+///
+/// Note that this function is intended to compute the same hash_code for
+/// a particular value without regard to the pre-promotion type. This is in
+/// contrast to hash_combine which may produce different hash_codes for
+/// differing argument types even if they would implicit promote to a common
+/// type without changing the value.
+template <typename T>
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
+hash_value(T value);
+
+/// \brief Compute a hash_code for a pointer's address.
+///
+/// N.B.: This hashes the *address*. Not the value and not the type.
+template <typename T> hash_code hash_value(const T *ptr);
+
+/// \brief Compute a hash_code for a pair of objects.
+template <typename T, typename U>
+hash_code hash_value(const std::pair<T, U> &arg);
+
+/// \brief Compute a hash_code for a standard string.
+template <typename T>
+hash_code hash_value(const std::basic_string<T> &arg);
+
+
+/// \brief Override the execution seed with a fixed value.
+///
+/// This hashing library uses a per-execution seed designed to change on each
+/// run with high probability in order to ensure that the hash codes are not
+/// attackable and to ensure that output which is intended to be stable does
+/// not rely on the particulars of the hash codes produced.
+///
+/// That said, there are use cases where it is important to be able to
+/// reproduce *exactly* a specific behavior. To that end, we provide a function
+/// which will forcibly set the seed to a fixed value. This must be done at the
+/// start of the program, before any hashes are computed. Also, it cannot be
+/// undone. This makes it thread-hostile and very hard to use outside of
+/// immediately on start of a simple program designed for reproducible
+/// behavior.
+void set_fixed_execution_hash_seed(size_t fixed_value);
+
+
+// All of the implementation details of actually computing the various hash
+// code values are held within this namespace. These routines are included in
+// the header file mainly to allow inlining and constant propagation.
+namespace hashing {
+namespace detail {
+
+inline uint64_t fetch64(const char *p) {
+  uint64_t result;
+  memcpy(&result, p, sizeof(result));
+  if (sys::IsBigEndianHost)
+    sys::swapByteOrder(result);
+  return result;
+}
+
+inline uint32_t fetch32(const char *p) {
+  uint32_t result;
+  memcpy(&result, p, sizeof(result));
+  if (sys::IsBigEndianHost)
+    sys::swapByteOrder(result);
+  return result;
+}
+
+/// Some primes between 2^63 and 2^64 for various uses.
+static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
+static const uint64_t k1 = 0xb492b66fbe98f273ULL;
+static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
+static const uint64_t k3 = 0xc949d7c7509e6557ULL;
+
+/// \brief Bitwise right rotate.
+/// Normally this will compile to a single instruction, especially if the
+/// shift is a manifest constant.
+inline uint64_t rotate(uint64_t val, size_t shift) {
+  // Avoid shifting by 64: doing so yields an undefined result.
+  return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
+}
+
+inline uint64_t shift_mix(uint64_t val) {
+  return val ^ (val >> 47);
+}
+
+inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) {
+  // Murmur-inspired hashing.
+  const uint64_t kMul = 0x9ddfea08eb382d69ULL;
+  uint64_t a = (low ^ high) * kMul;
+  a ^= (a >> 47);
+  uint64_t b = (high ^ a) * kMul;
+  b ^= (b >> 47);
+  b *= kMul;
+  return b;
+}
+
+inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
+  uint8_t a = s[0];
+  uint8_t b = s[len >> 1];
+  uint8_t c = s[len - 1];
+  uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
+  uint32_t z = len + (static_cast<uint32_t>(c) << 2);
+  return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
+}
+
+inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
+  uint64_t a = fetch32(s);
+  return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
+}
+
+inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
+  uint64_t a = fetch64(s);
+  uint64_t b = fetch64(s + len - 8);
+  return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
+}
+
+inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
+  uint64_t a = fetch64(s) * k1;
+  uint64_t b = fetch64(s + 8);
+  uint64_t c = fetch64(s + len - 8) * k2;
+  uint64_t d = fetch64(s + len - 16) * k0;
+  return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d,
+                       a + rotate(b ^ k3, 20) - c + len + seed);
+}
+
+inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
+  uint64_t z = fetch64(s + 24);
+  uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
+  uint64_t b = rotate(a + z, 52);
+  uint64_t c = rotate(a, 37);
+  a += fetch64(s + 8);
+  c += rotate(a, 7);
+  a += fetch64(s + 16);
+  uint64_t vf = a + z;
+  uint64_t vs = b + rotate(a, 31) + c;
+  a = fetch64(s + 16) + fetch64(s + len - 32);
+  z = fetch64(s + len - 8);
+  b = rotate(a + z, 52);
+  c = rotate(a, 37);
+  a += fetch64(s + len - 24);
+  c += rotate(a, 7);
+  a += fetch64(s + len - 16);
+  uint64_t wf = a + z;
+  uint64_t ws = b + rotate(a, 31) + c;
+  uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
+  return shift_mix((seed ^ (r * k0)) + vs) * k2;
+}
+
+inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
+  if (length >= 4 && length <= 8)
+    return hash_4to8_bytes(s, length, seed);
+  if (length > 8 && length <= 16)
+    return hash_9to16_bytes(s, length, seed);
+  if (length > 16 && length <= 32)
+    return hash_17to32_bytes(s, length, seed);
+  if (length > 32)
+    return hash_33to64_bytes(s, length, seed);
+  if (length != 0)
+    return hash_1to3_bytes(s, length, seed);
+
+  return k2 ^ seed;
+}
+
+/// \brief The intermediate state used during hashing.
+/// Currently, the algorithm for computing hash codes is based on CityHash and
+/// keeps 56 bytes of arbitrary state.
+struct hash_state {
+  uint64_t h0, h1, h2, h3, h4, h5, h6;
+
+  /// \brief Create a new hash_state structure and initialize it based on the
+  /// seed and the first 64-byte chunk.
+  /// This effectively performs the initial mix.
+  static hash_state create(const char *s, uint64_t seed) {
+    hash_state state = {
+      0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49),
+      seed * k1, shift_mix(seed), 0 };
+    state.h6 = hash_16_bytes(state.h4, state.h5);
+    state.mix(s);
+    return state;
+  }
+
+  /// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a'
+  /// and 'b', including whatever is already in 'a' and 'b'.
+  static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
+    a += fetch64(s);
+    uint64_t c = fetch64(s + 24);
+    b = rotate(b + a + c, 21);
+    uint64_t d = a;
+    a += fetch64(s + 8) + fetch64(s + 16);
+    b += rotate(a, 44) + d;
+    a += c;
+  }
+
+  /// \brief Mix in a 64-byte buffer of data.
+  /// We mix all 64 bytes even when the chunk length is smaller, but we
+  /// record the actual length.
+  void mix(const char *s) {
+    h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
+    h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1;
+    h0 ^= h6;
+    h1 += h3 + fetch64(s + 40);
+    h2 = rotate(h2 + h5, 33) * k1;
+    h3 = h4 * k1;
+    h4 = h0 + h5;
+    mix_32_bytes(s, h3, h4);
+    h5 = h2 + h6;
+    h6 = h1 + fetch64(s + 16);
+    mix_32_bytes(s + 32, h5, h6);
+    std::swap(h2, h0);
+  }
+
+  /// \brief Compute the final 64-bit hash code value based on the current
+  /// state and the length of bytes hashed.
+  uint64_t finalize(size_t length) {
+    return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
+                         hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
+  }
+};
+
+
+/// \brief A global, fixed seed-override variable.
+///
+/// This variable can be set using the \see llvm::set_fixed_execution_seed
+/// function. See that function for details. Do not, under any circumstances,
+/// set or read this variable.
+extern size_t fixed_seed_override;
+
+inline size_t get_execution_seed() {
+  // FIXME: This needs to be a per-execution seed. This is just a placeholder
+  // implementation. Switching to a per-execution seed is likely to flush out
+  // instability bugs and so will happen as its own commit.
+  //
+  // However, if there is a fixed seed override set the first time this is
+  // called, return that instead of the per-execution seed.
+  const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
+  static size_t seed = fixed_seed_override ? fixed_seed_override
+                                           : (size_t)seed_prime;
+  return seed;
+}
+
+
+/// \brief Trait to indicate whether a type's bits can be hashed directly.
+///
+/// A type trait which is true if we want to combine values for hashing by
+/// reading the underlying data. It is false if values of this type must
+/// first be passed to hash_value, and the resulting hash_codes combined.
+//
+// FIXME: We want to replace is_integral_or_enum and is_pointer here with
+// a predicate which asserts that comparing the underlying storage of two
+// values of the type for equality is equivalent to comparing the two values
+// for equality. For all the platforms we care about, this holds for integers
+// and pointers, but there are platforms where it doesn't and we would like to
+// support user-defined types which happen to satisfy this property.
+template <typename T> struct is_hashable_data
+  : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
+                                   std::is_pointer<T>::value) &&
+                                  64 % sizeof(T) == 0)> {};
+
+// Special case std::pair to detect when both types are viable and when there
+// is no alignment-derived padding in the pair. This is a bit of a lie because
+// std::pair isn't truly POD, but it's close enough in all reasonable
+// implementations for our use case of hashing the underlying data.
+template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
+  : std::integral_constant<bool, (is_hashable_data<T>::value &&
+                                  is_hashable_data<U>::value &&
+                                  (sizeof(T) + sizeof(U)) ==
+                                   sizeof(std::pair<T, U>))> {};
+
+/// \brief Helper to get the hashable data representation for a type.
+/// This variant is enabled when the type itself can be used.
+template <typename T>
+typename std::enable_if<is_hashable_data<T>::value, T>::type
+get_hashable_data(const T &value) {
+  return value;
+}
+/// \brief Helper to get the hashable data representation for a type.
+/// This variant is enabled when we must first call hash_value and use the
+/// result as our data.
+template <typename T>
+typename std::enable_if<!is_hashable_data<T>::value, size_t>::type
+get_hashable_data(const T &value) {
+  using ::llvm::hash_value;
+  return hash_value(value);
+}
+
+/// \brief Helper to store data from a value into a buffer and advance the
+/// pointer into that buffer.
+///
+/// This routine first checks whether there is enough space in the provided
+/// buffer, and if not immediately returns false. If there is space, it
+/// copies the underlying bytes of value into the buffer, advances the
+/// buffer_ptr past the copied bytes, and returns true.
+template <typename T>
+bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
+                       size_t offset = 0) {
+  size_t store_size = sizeof(value) - offset;
+  if (buffer_ptr + store_size > buffer_end)
+    return false;
+  const char *value_data = reinterpret_cast<const char *>(&value);
+  memcpy(buffer_ptr, value_data + offset, store_size);
+  buffer_ptr += store_size;
+  return true;
+}
+
+/// \brief Implement the combining of integral values into a hash_code.
+///
+/// This overload is selected when the value type of the iterator is
+/// integral. Rather than computing a hash_code for each object and then
+/// combining them, this (as an optimization) directly combines the integers.
+template <typename InputIteratorT>
+hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
+  const size_t seed = get_execution_seed();
+  char buffer[64], *buffer_ptr = buffer;
+  char *const buffer_end = std::end(buffer);
+  while (first != last && store_and_advance(buffer_ptr, buffer_end,
+                                            get_hashable_data(*first)))
+    ++first;
+  if (first == last)
+    return hash_short(buffer, buffer_ptr - buffer, seed);
+  assert(buffer_ptr == buffer_end);
+
+  hash_state state = state.create(buffer, seed);
+  size_t length = 64;
+  while (first != last) {
+    // Fill up the buffer. We don't clear it, which re-mixes the last round
+    // when only a partial 64-byte chunk is left.
+    buffer_ptr = buffer;
+    while (first != last && store_and_advance(buffer_ptr, buffer_end,
+                                              get_hashable_data(*first)))
+      ++first;
+
+    // Rotate the buffer if we did a partial fill in order to simulate doing
+    // a mix of the last 64-bytes. That is how the algorithm works when we
+    // have a contiguous byte sequence, and we want to emulate that here.
+    std::rotate(buffer, buffer_ptr, buffer_end);
+
+    // Mix this chunk into the current state.
+    state.mix(buffer);
+    length += buffer_ptr - buffer;
+  };
+
+  return state.finalize(length);
+}
+
+/// \brief Implement the combining of integral values into a hash_code.
+///
+/// This overload is selected when the value type of the iterator is integral
+/// and when the input iterator is actually a pointer. Rather than computing
+/// a hash_code for each object and then combining them, this (as an
+/// optimization) directly combines the integers. Also, because the integers
+/// are stored in contiguous memory, this routine avoids copying each value
+/// and directly reads from the underlying memory.
+template <typename ValueT>
+typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type
+hash_combine_range_impl(ValueT *first, ValueT *last) {
+  const size_t seed = get_execution_seed();
+  const char *s_begin = reinterpret_cast<const char *>(first);
+  const char *s_end = reinterpret_cast<const char *>(last);
+  const size_t length = std::distance(s_begin, s_end);
+  if (length <= 64)
+    return hash_short(s_begin, length, seed);
+
+  const char *s_aligned_end = s_begin + (length & ~63);
+  hash_state state = state.create(s_begin, seed);
+  s_begin += 64;
+  while (s_begin != s_aligned_end) {
+    state.mix(s_begin);
+    s_begin += 64;
+  }
+  if (length & 63)
+    state.mix(s_end - 64);
+
+  return state.finalize(length);
+}
+
+} // namespace detail
+} // namespace hashing
+
+
+/// \brief Compute a hash_code for a sequence of values.
+///
+/// This hashes a sequence of values. It produces the same hash_code as
+/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
+/// and is significantly faster given pointers and types which can be hashed as
+/// a sequence of bytes.
+template <typename InputIteratorT>
+hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
+  return ::llvm::hashing::detail::hash_combine_range_impl(first, last);
+}
+
+
+// Implementation details for hash_combine.
+namespace hashing {
+namespace detail {
+
+/// \brief Helper class to manage the recursive combining of hash_combine
+/// arguments.
+///
+/// This class exists to manage the state and various calls involved in the
+/// recursive combining of arguments used in hash_combine. It is particularly
+/// useful at minimizing the code in the recursive calls to ease the pain
+/// caused by a lack of variadic functions.
+struct hash_combine_recursive_helper {
+  char buffer[64];
+  hash_state state;
+  const size_t seed;
+
+public:
+  /// \brief Construct a recursive hash combining helper.
+  ///
+  /// This sets up the state for a recursive hash combine, including getting
+  /// the seed and buffer setup.
+  hash_combine_recursive_helper()
+    : seed(get_execution_seed()) {}
+
+  /// \brief Combine one chunk of data into the current in-flight hash.
+  ///
+  /// This merges one chunk of data into the hash. First it tries to buffer
+  /// the data. If the buffer is full, it hashes the buffer into its
+  /// hash_state, empties it, and then merges the new chunk in. This also
+  /// handles cases where the data straddles the end of the buffer.
+  template <typename T>
+  char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
+    if (!store_and_advance(buffer_ptr, buffer_end, data)) {
+      // Check for skew which prevents the buffer from being packed, and do
+      // a partial store into the buffer to fill it. This is only a concern
+      // with the variadic combine because that formation can have varying
+      // argument types.
+      size_t partial_store_size = buffer_end - buffer_ptr;
+      memcpy(buffer_ptr, &data, partial_store_size);
+
+      // If the store fails, our buffer is full and ready to hash. We have to
+      // either initialize the hash state (on the first full buffer) or mix
+      // this buffer into the existing hash state. Length tracks the *hashed*
+      // length, not the buffered length.
+      if (length == 0) {
+        state = state.create(buffer, seed);
+        length = 64;
+      } else {
+        // Mix this chunk into the current state and bump length up by 64.
+        state.mix(buffer);
+        length += 64;
+      }
+      // Reset the buffer_ptr to the head of the buffer for the next chunk of
+      // data.
+      buffer_ptr = buffer;
+
+      // Try again to store into the buffer -- this cannot fail as we only
+      // store types smaller than the buffer.
+      if (!store_and_advance(buffer_ptr, buffer_end, data,
+                             partial_store_size))
+        abort();
+    }
+    return buffer_ptr;
+  }
+
+#if defined(__has_feature) && __has_feature(__cxx_variadic_templates__)
+
+  /// \brief Recursive, variadic combining method.
+  ///
+  /// This function recurses through each argument, combining that argument
+  /// into a single hash.
+  template <typename T, typename ...Ts>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T &arg, const Ts &...args) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
+
+    // Recurse to the next argument.
+    return combine(length, buffer_ptr, buffer_end, args...);
+  }
+
+#else
+  // Manually expanded recursive combining methods. See variadic above for
+  // documentation.
+
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+            typename T6>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                    const T4 &arg4, const T5 &arg5, const T6 &arg6) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6);
+  }
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                    const T4 &arg4, const T5 &arg5) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5);
+  }
+  template <typename T1, typename T2, typename T3, typename T4>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                    const T4 &arg4) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4);
+  }
+  template <typename T1, typename T2, typename T3>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1, const T2 &arg2, const T3 &arg3) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end, arg2, arg3);
+  }
+  template <typename T1, typename T2>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1, const T2 &arg2) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end, arg2);
+  }
+  template <typename T1>
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+                    const T1 &arg1) {
+    buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+    return combine(length, buffer_ptr, buffer_end);
+  }
+
+#endif
+
+  /// \brief Base case for recursive, variadic combining.
+  ///
+  /// The base case when combining arguments recursively is reached when all
+  /// arguments have been handled. It flushes the remaining buffer and
+  /// constructs a hash_code.
+  hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
+    // Check whether the entire set of values fit in the buffer. If so, we'll
+    // use the optimized short hashing routine and skip state entirely.
+    if (length == 0)
+      return hash_short(buffer, buffer_ptr - buffer, seed);
+
+    // Mix the final buffer, rotating it if we did a partial fill in order to
+    // simulate doing a mix of the last 64-bytes. That is how the algorithm
+    // works when we have a contiguous byte sequence, and we want to emulate
+    // that here.
+    std::rotate(buffer, buffer_ptr, buffer_end);
+
+    // Mix this chunk into the current state.
+    state.mix(buffer);
+    length += buffer_ptr - buffer;
+
+    return state.finalize(length);
+  }
+};
+
+} // namespace detail
+} // namespace hashing
+
+
+#if __has_feature(__cxx_variadic_templates__)
+
+/// \brief Combine values into a single hash_code.
+///
+/// This routine accepts a varying number of arguments of any type. It will
+/// attempt to combine them into a single hash_code. For user-defined types it
+/// attempts to call a \see hash_value overload (via ADL) for the type. For
+/// integer and pointer types it directly combines their data into the
+/// resulting hash_code.
+///
+/// The result is suitable for returning from a user's hash_value
+/// *implementation* for their user-defined type. Consumers of a type should
+/// *not* call this routine, they should instead call 'hash_value'.
+template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
+  // Recursively hash each argument using a helper class.
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
+}
+
+#else
+
+// What follows are manually exploded overloads for each argument width. See
+// the above variadic definition for documentation and specification.
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                       const T4 &arg4, const T5 &arg5, const T6 &arg6) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64,
+                        arg1, arg2, arg3, arg4, arg5, arg6);
+}
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                       const T4 &arg4, const T5 &arg5) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64,
+                        arg1, arg2, arg3, arg4, arg5);
+}
+template <typename T1, typename T2, typename T3, typename T4>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+                       const T4 &arg4) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64,
+                        arg1, arg2, arg3, arg4);
+}
+template <typename T1, typename T2, typename T3>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3);
+}
+template <typename T1, typename T2>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2);
+}
+template <typename T1>
+hash_code hash_combine(const T1 &arg1) {
+  ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+  return helper.combine(0, helper.buffer, helper.buffer + 64, arg1);
+}
+
+#endif
+
+
+// Implementation details for implementations of hash_value overloads provided
+// here.
+namespace hashing {
+namespace detail {
+
+/// \brief Helper to hash the value of a single integer.
+///
+/// Overloads for smaller integer types are not provided to ensure consistent
+/// behavior in the presence of integral promotions. Essentially,
+/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
+inline hash_code hash_integer_value(uint64_t value) {
+  // Similar to hash_4to8_bytes but using a seed instead of length.
+  const uint64_t seed = get_execution_seed();
+  const char *s = reinterpret_cast<const char *>(&value);
+  const uint64_t a = fetch32(s);
+  return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
+}
+
+} // namespace detail
+} // namespace hashing
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T>
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
+hash_value(T value) {
+  return ::llvm::hashing::detail::hash_integer_value(value);
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T> hash_code hash_value(const T *ptr) {
+  return ::llvm::hashing::detail::hash_integer_value(
+    reinterpret_cast<uintptr_t>(ptr));
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T, typename U>
+hash_code hash_value(const std::pair<T, U> &arg) {
+  return hash_combine(arg.first, arg.second);
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T>
+hash_code hash_value(const std::basic_string<T> &arg) {
+  return hash_combine_range(arg.begin(), arg.end());
+}
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
new file mode 100644
index 0000000..7f0c239
--- /dev/null
+++ b/include/llvm/ADT/ImmutableList.h
@@ -0,0 +1,229 @@
+//==--- ImmutableList.h - Immutable (functional) list interface --*- 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 ImmutableList class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMUTABLELIST_H
+#define LLVM_ADT_IMMUTABLELIST_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+template <typename T> class ImmutableListFactory;
+
+template <typename T>
+class ImmutableListImpl : public FoldingSetNode {
+  T Head;
+  const ImmutableListImpl* Tail;
+
+  ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0)
+    : Head(head), Tail(tail) {}
+
+  friend class ImmutableListFactory<T>;
+
+  void operator=(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
+  ImmutableListImpl(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
+
+public:
+  const T& getHead() const { return Head; }
+  const ImmutableListImpl* getTail() const { return Tail; }
+
+  static inline void Profile(FoldingSetNodeID& ID, const T& H,
+                             const ImmutableListImpl* L){
+    ID.AddPointer(L);
+    ID.Add(H);
+  }
+
+  void Profile(FoldingSetNodeID& ID) {
+    Profile(ID, Head, Tail);
+  }
+};
+
+/// ImmutableList - This class represents an immutable (functional) list.
+///  It is implemented as a smart pointer (wraps ImmutableListImpl), so it
+///  it is intended to always be copied by value as if it were a pointer.
+///  This interface matches ImmutableSet and ImmutableMap.  ImmutableList
+///  objects should almost never be created directly, and instead should
+///  be created by ImmutableListFactory objects that manage the lifetime
+///  of a group of lists.  When the factory object is reclaimed, all lists
+///  created by that factory are released as well.
+template <typename T>
+class ImmutableList {
+public:
+  typedef T value_type;
+  typedef ImmutableListFactory<T> Factory;
+
+private:
+  const ImmutableListImpl<T>* X;
+
+public:
+  // This constructor should normally only be called by ImmutableListFactory<T>.
+  // There may be cases, however, when one needs to extract the internal pointer
+  // and reconstruct a list object from that pointer.
+  ImmutableList(const ImmutableListImpl<T>* x = 0) : X(x) {}
+
+  const ImmutableListImpl<T>* getInternalPointer() const {
+    return X;
+  }
+
+  class iterator {
+    const ImmutableListImpl<T>* L;
+  public:
+    iterator() : L(0) {}
+    iterator(ImmutableList l) : L(l.getInternalPointer()) {}
+
+    iterator& operator++() { L = L->getTail(); return *this; }
+    bool operator==(const iterator& I) const { return L == I.L; }
+    bool operator!=(const iterator& I) const { return L != I.L; }
+    const value_type& operator*() const { return L->getHead(); }
+    ImmutableList getList() const { return L; }
+  };
+
+  /// begin - Returns an iterator referring to the head of the list, or
+  ///  an iterator denoting the end of the list if the list is empty.
+  iterator begin() const { return iterator(X); }
+
+  /// end - Returns an iterator denoting the end of the list.  This iterator
+  ///  does not refer to a valid list element.
+  iterator end() const { return iterator(); }
+
+  /// isEmpty - Returns true if the list is empty.
+  bool isEmpty() const { return !X; }
+
+  bool contains(const T& V) const {
+    for (iterator I = begin(), E = end(); I != E; ++I) {
+      if (*I == V)
+        return true;
+    }
+    return false;
+  }
+
+  /// isEqual - Returns true if two lists are equal.  Because all lists created
+  ///  from the same ImmutableListFactory are uniqued, this has O(1) complexity
+  ///  because it the contents of the list do not need to be compared.  Note
+  ///  that you should only compare two lists created from the same
+  ///  ImmutableListFactory.
+  bool isEqual(const ImmutableList& L) const { return X == L.X; }
+
+  bool operator==(const ImmutableList& L) const { return isEqual(L); }
+
+  /// getHead - Returns the head of the list.
+  const T& getHead() {
+    assert (!isEmpty() && "Cannot get the head of an empty list.");
+    return X->getHead();
+  }
+
+  /// getTail - Returns the tail of the list, which is another (possibly empty)
+  ///  ImmutableList.
+  ImmutableList getTail() {
+    return X ? X->getTail() : 0;
+  }
+
+  void Profile(FoldingSetNodeID& ID) const {
+    ID.AddPointer(X);
+  }
+};
+
+template <typename T>
+class ImmutableListFactory {
+  typedef ImmutableListImpl<T> ListTy;
+  typedef FoldingSet<ListTy>   CacheTy;
+
+  CacheTy Cache;
+  uintptr_t Allocator;
+
+  bool ownsAllocator() const {
+    return Allocator & 0x1 ? false : true;
+  }
+
+  BumpPtrAllocator& getAllocator() const {
+    return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+  }
+
+public:
+  ImmutableListFactory()
+    : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+  ImmutableListFactory(BumpPtrAllocator& Alloc)
+  : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+  ~ImmutableListFactory() {
+    if (ownsAllocator()) delete &getAllocator();
+  }
+
+  ImmutableList<T> concat(const T& Head, ImmutableList<T> Tail) {
+    // Profile the new list to see if it already exists in our cache.
+    FoldingSetNodeID ID;
+    void* InsertPos;
+
+    const ListTy* TailImpl = Tail.getInternalPointer();
+    ListTy::Profile(ID, Head, TailImpl);
+    ListTy* L = Cache.FindNodeOrInsertPos(ID, InsertPos);
+
+    if (!L) {
+      // The list does not exist in our cache.  Create it.
+      BumpPtrAllocator& A = getAllocator();
+      L = (ListTy*) A.Allocate<ListTy>();
+      new (L) ListTy(Head, TailImpl);
+
+      // Insert the new list into the cache.
+      Cache.InsertNode(L, InsertPos);
+    }
+
+    return L;
+  }
+
+  ImmutableList<T> add(const T& D, ImmutableList<T> L) {
+    return concat(D, L);
+  }
+
+  ImmutableList<T> getEmptyList() const {
+    return ImmutableList<T>(0);
+  }
+
+  ImmutableList<T> create(const T& X) {
+    return Concat(X, getEmptyList());
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Partially-specialized Traits.
+//===----------------------------------------------------------------------===//
+
+template<typename T> struct DenseMapInfo;
+template<typename T> struct DenseMapInfo<ImmutableList<T> > {
+  static inline ImmutableList<T> getEmptyKey() {
+    return reinterpret_cast<ImmutableListImpl<T>*>(-1);
+  }
+  static inline ImmutableList<T> getTombstoneKey() {
+    return reinterpret_cast<ImmutableListImpl<T>*>(-2);
+  }
+  static unsigned getHashValue(ImmutableList<T> X) {
+    uintptr_t PtrVal = reinterpret_cast<uintptr_t>(X.getInternalPointer());
+    return (unsigned((uintptr_t)PtrVal) >> 4) ^
+           (unsigned((uintptr_t)PtrVal) >> 9);
+  }
+  static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
+    return X1 == X2;
+  }
+};
+
+template <typename T> struct isPodLike;
+template <typename T>
+struct isPodLike<ImmutableList<T> > { static const bool value = true; };
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
new file mode 100644
index 0000000..11f281b
--- /dev/null
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -0,0 +1,439 @@
+//===--- ImmutableMap.h - Immutable (functional) map interface --*- 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 ImmutableMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMUTABLEMAP_H
+#define LLVM_ADT_IMMUTABLEMAP_H
+
+#include "llvm/ADT/ImmutableSet.h"
+
+namespace llvm {
+
+/// ImutKeyValueInfo -Traits class used by ImmutableMap.  While both the first
+/// and second elements in a pair are used to generate profile information,
+/// only the first element (the key) is used by isEqual and isLess.
+template <typename T, typename S>
+struct ImutKeyValueInfo {
+  typedef const std::pair<T,S> value_type;
+  typedef const value_type& value_type_ref;
+  typedef const T   key_type;
+  typedef const T&  key_type_ref;
+  typedef const S   data_type;
+  typedef const S&  data_type_ref;
+
+  static inline key_type_ref KeyOfValue(value_type_ref V) {
+    return V.first;
+  }
+
+  static inline data_type_ref DataOfValue(value_type_ref V) {
+    return V.second;
+  }
+
+  static inline bool isEqual(key_type_ref L, key_type_ref R) {
+    return ImutContainerInfo<T>::isEqual(L,R);
+  }
+  static inline bool isLess(key_type_ref L, key_type_ref R) {
+    return ImutContainerInfo<T>::isLess(L,R);
+  }
+
+  static inline bool isDataEqual(data_type_ref L, data_type_ref R) {
+    return ImutContainerInfo<S>::isEqual(L,R);
+  }
+
+  static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
+    ImutContainerInfo<T>::Profile(ID, V.first);
+    ImutContainerInfo<S>::Profile(ID, V.second);
+  }
+};
+
+
+template <typename KeyT, typename ValT,
+          typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMap {
+public:
+  typedef typename ValInfo::value_type      value_type;
+  typedef typename ValInfo::value_type_ref  value_type_ref;
+  typedef typename ValInfo::key_type        key_type;
+  typedef typename ValInfo::key_type_ref    key_type_ref;
+  typedef typename ValInfo::data_type       data_type;
+  typedef typename ValInfo::data_type_ref   data_type_ref;
+  typedef ImutAVLTree<ValInfo>              TreeTy;
+
+protected:
+  TreeTy* Root;
+
+public:
+  /// Constructs a map from a pointer to a tree root.  In general one
+  /// should use a Factory object to create maps instead of directly
+  /// invoking the constructor, but there are cases where make this
+  /// constructor public is useful.
+  explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableMap(const ImmutableMap &X) : Root(X.Root) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableMap &operator=(const ImmutableMap &X) {
+    if (Root != X.Root) {
+      if (X.Root) { X.Root->retain(); }
+      if (Root) { Root->release(); }
+      Root = X.Root;
+    }
+    return *this;
+  }
+  ~ImmutableMap() {
+    if (Root) { Root->release(); }
+  }
+
+  class Factory {
+    typename TreeTy::Factory F;
+    const bool Canonicalize;
+
+  public:
+    Factory(bool canonicalize = true)
+      : Canonicalize(canonicalize) {}
+    
+    Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
+      : F(Alloc), Canonicalize(canonicalize) {}
+
+    ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); }
+
+    ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+      TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
+      return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
+    }
+
+    ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
+      TreeTy *T = F.remove(Old.Root,K);
+      return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
+    }
+
+    typename TreeTy::Factory *getTreeFactory() const {
+      return const_cast<typename TreeTy::Factory *>(&F);
+    }
+
+  private:
+    Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
+    void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
+  };
+
+  bool contains(key_type_ref K) const {
+    return Root ? Root->contains(K) : false;
+  }
+
+  bool operator==(const ImmutableMap &RHS) const {
+    return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+  }
+
+  bool operator!=(const ImmutableMap &RHS) const {
+    return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+  }
+
+  TreeTy *getRoot() const {
+    if (Root) { Root->retain(); }
+    return Root;
+  }
+
+  TreeTy *getRootWithoutRetain() const {
+    return Root;
+  }
+  
+  void manualRetain() {
+    if (Root) Root->retain();
+  }
+  
+  void manualRelease() {
+    if (Root) Root->release();
+  }
+
+  bool isEmpty() const { return !Root; }
+
+  //===--------------------------------------------------===//
+  // Foreach - A limited form of map iteration.
+  //===--------------------------------------------------===//
+
+private:
+  template <typename Callback>
+  struct CBWrapper {
+    Callback C;
+    void operator()(value_type_ref V) { C(V.first,V.second); }
+  };
+
+  template <typename Callback>
+  struct CBWrapperRef {
+    Callback &C;
+    CBWrapperRef(Callback& c) : C(c) {}
+
+    void operator()(value_type_ref V) { C(V.first,V.second); }
+  };
+
+public:
+  template <typename Callback>
+  void foreach(Callback& C) {
+    if (Root) {
+      CBWrapperRef<Callback> CB(C);
+      Root->foreach(CB);
+    }
+  }
+
+  template <typename Callback>
+  void foreach() {
+    if (Root) {
+      CBWrapper<Callback> CB;
+      Root->foreach(CB);
+    }
+  }
+
+  //===--------------------------------------------------===//
+  // For testing.
+  //===--------------------------------------------------===//
+
+  void verify() const { if (Root) Root->verify(); }
+
+  //===--------------------------------------------------===//
+  // Iterators.
+  //===--------------------------------------------------===//
+
+  class iterator {
+    typename TreeTy::iterator itr;
+
+    iterator() {}
+    iterator(TreeTy* t) : itr(t) {}
+    friend class ImmutableMap;
+
+  public:
+    typedef ptrdiff_t difference_type;
+    typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type;
+    typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference;
+    typedef typename iterator::value_type *pointer;
+    typedef std::bidirectional_iterator_tag iterator_category;
+
+    typename iterator::reference operator*() const { return itr->getValue(); }
+    typename iterator::pointer   operator->() const { return &itr->getValue(); }
+
+    key_type_ref getKey() const { return itr->getValue().first; }
+    data_type_ref getData() const { return itr->getValue().second; }
+
+    iterator& operator++() { ++itr; return *this; }
+    iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+    iterator& operator--() { --itr; return *this; }
+    iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
+
+    bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+    bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+  };
+
+  iterator begin() const { return iterator(Root); }
+  iterator end() const { return iterator(); }
+
+  data_type* lookup(key_type_ref K) const {
+    if (Root) {
+      TreeTy* T = Root->find(K);
+      if (T) return &T->getValue().second;
+    }
+
+    return nullptr;
+  }
+  
+  /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+  ///  which key is the highest in the ordering of keys in the map.  This
+  ///  method returns NULL if the map is empty.
+  value_type* getMaxElement() const {
+    return Root ? &(Root->getMaxElement()->getValue()) : nullptr;
+  }
+
+  //===--------------------------------------------------===//
+  // Utility methods.
+  //===--------------------------------------------------===//
+
+  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+  static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
+    ID.AddPointer(M.Root);
+  }
+
+  inline void Profile(FoldingSetNodeID& ID) const {
+    return Profile(ID,*this);
+  }
+};
+
+// NOTE: This will possibly become the new implementation of ImmutableMap some day.
+template <typename KeyT, typename ValT,
+typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMapRef {
+public:
+  typedef typename ValInfo::value_type      value_type;
+  typedef typename ValInfo::value_type_ref  value_type_ref;
+  typedef typename ValInfo::key_type        key_type;
+  typedef typename ValInfo::key_type_ref    key_type_ref;
+  typedef typename ValInfo::data_type       data_type;
+  typedef typename ValInfo::data_type_ref   data_type_ref;
+  typedef ImutAVLTree<ValInfo>              TreeTy;
+  typedef typename TreeTy::Factory          FactoryTy;
+  
+protected:
+  TreeTy *Root;
+  FactoryTy *Factory;
+  
+public:
+  /// Constructs a map from a pointer to a tree root.  In general one
+  /// should use a Factory object to create maps instead of directly
+  /// invoking the constructor, but there are cases where make this
+  /// constructor public is useful.
+  explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F) 
+    : Root(const_cast<TreeTy*>(R)),
+      Factory(F) {
+    if (Root) { Root->retain(); }
+  }
+
+  explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
+                           typename ImmutableMap<KeyT, ValT>::Factory &F)
+    : Root(X.getRootWithoutRetain()),
+      Factory(F.getTreeFactory()) {
+    if (Root) { Root->retain(); }
+  }
+  
+  ImmutableMapRef(const ImmutableMapRef &X)
+    : Root(X.Root),
+      Factory(X.Factory) {
+    if (Root) { Root->retain(); }
+  }
+
+  ImmutableMapRef &operator=(const ImmutableMapRef &X) {
+    if (Root != X.Root) {
+      if (X.Root)
+        X.Root->retain();
+      
+      if (Root)
+        Root->release();
+      
+      Root = X.Root;
+      Factory = X.Factory;
+    }
+    return *this;
+  }
+
+  ~ImmutableMapRef() {
+    if (Root)
+      Root->release();
+  }
+  
+  static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
+    return ImmutableMapRef(0, F);
+  }
+
+  void manualRetain() {
+    if (Root) Root->retain();
+  }
+
+  void manualRelease() {
+    if (Root) Root->release();
+  }
+
+  ImmutableMapRef add(key_type_ref K, data_type_ref D) const {
+    TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
+    return ImmutableMapRef(NewT, Factory);
+  }
+
+  ImmutableMapRef remove(key_type_ref K) const {
+    TreeTy *NewT = Factory->remove(Root, K);
+    return ImmutableMapRef(NewT, Factory);
+  }
+  
+  bool contains(key_type_ref K) const {
+    return Root ? Root->contains(K) : false;
+  }
+  
+  ImmutableMap<KeyT, ValT> asImmutableMap() const {
+    return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
+  }
+  
+  bool operator==(const ImmutableMapRef &RHS) const {
+    return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+  }
+  
+  bool operator!=(const ImmutableMapRef &RHS) const {
+    return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+  }
+    
+  bool isEmpty() const { return !Root; }
+    
+  //===--------------------------------------------------===//
+  // For testing.
+  //===--------------------------------------------------===//
+  
+  void verify() const { if (Root) Root->verify(); }
+  
+  //===--------------------------------------------------===//
+  // Iterators.
+  //===--------------------------------------------------===//
+  
+  class iterator {
+    typename TreeTy::iterator itr;
+    
+    iterator() {}
+    iterator(TreeTy* t) : itr(t) {}
+    friend class ImmutableMapRef;
+    
+  public:
+    value_type_ref operator*() const { return itr->getValue(); }
+    value_type*    operator->() const { return &itr->getValue(); }
+    
+    key_type_ref getKey() const { return itr->getValue().first; }
+    data_type_ref getData() const { return itr->getValue().second; }
+    
+    
+    iterator& operator++() { ++itr; return *this; }
+    iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+    iterator& operator--() { --itr; return *this; }
+    iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
+    bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+    bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+  };
+  
+  iterator begin() const { return iterator(Root); }
+  iterator end() const { return iterator(); }
+  
+  data_type* lookup(key_type_ref K) const {
+    if (Root) {
+      TreeTy* T = Root->find(K);
+      if (T) return &T->getValue().second;
+    }
+    
+    return 0;
+  }
+  
+  /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+  ///  which key is the highest in the ordering of keys in the map.  This
+  ///  method returns NULL if the map is empty.
+  value_type* getMaxElement() const {
+    return Root ? &(Root->getMaxElement()->getValue()) : 0;
+  }
+  
+  //===--------------------------------------------------===//
+  // Utility methods.
+  //===--------------------------------------------------===//
+  
+  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+  
+  static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
+    ID.AddPointer(M.Root);
+  }
+  
+  inline void Profile(FoldingSetNodeID& ID) const {
+    return Profile(ID, *this);
+  }
+};
+  
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
new file mode 100644
index 0000000..5a3d8ad
--- /dev/null
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -0,0 +1,1240 @@
+//===--- ImmutableSet.h - Immutable (functional) set interface --*- 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 ImutAVLTree and ImmutableSet classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMUTABLESET_H
+#define LLVM_ADT_IMMUTABLESET_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <functional>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Definition.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo> class ImutAVLFactory;
+template <typename ImutInfo> class ImutIntervalAVLFactory;
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
+template <typename ImutInfo> class ImutAVLTreeGenericIterator;
+
+template <typename ImutInfo >
+class ImutAVLTree {
+public:
+  typedef typename ImutInfo::key_type_ref   key_type_ref;
+  typedef typename ImutInfo::value_type     value_type;
+  typedef typename ImutInfo::value_type_ref value_type_ref;
+
+  typedef ImutAVLFactory<ImutInfo>          Factory;
+  friend class ImutAVLFactory<ImutInfo>;
+  friend class ImutIntervalAVLFactory<ImutInfo>;
+
+  friend class ImutAVLTreeGenericIterator<ImutInfo>;
+
+  typedef ImutAVLTreeInOrderIterator<ImutInfo>  iterator;
+
+  //===----------------------------------------------------===//
+  // Public Interface.
+  //===----------------------------------------------------===//
+
+  /// Return a pointer to the left subtree.  This value
+  ///  is NULL if there is no left subtree.
+  ImutAVLTree *getLeft() const { return left; }
+
+  /// Return a pointer to the right subtree.  This value is
+  ///  NULL if there is no right subtree.
+  ImutAVLTree *getRight() const { return right; }
+
+  /// getHeight - Returns the height of the tree.  A tree with no subtrees
+  ///  has a height of 1.
+  unsigned getHeight() const { return height; }
+
+  /// getValue - Returns the data value associated with the tree node.
+  const value_type& getValue() const { return value; }
+
+  /// find - Finds the subtree associated with the specified key value.
+  ///  This method returns NULL if no matching subtree is found.
+  ImutAVLTree* find(key_type_ref K) {
+    ImutAVLTree *T = this;
+    while (T) {
+      key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
+      if (ImutInfo::isEqual(K,CurrentKey))
+        return T;
+      else if (ImutInfo::isLess(K,CurrentKey))
+        T = T->getLeft();
+      else
+        T = T->getRight();
+    }
+    return nullptr;
+  }
+
+  /// getMaxElement - Find the subtree associated with the highest ranged
+  ///  key value.
+  ImutAVLTree* getMaxElement() {
+    ImutAVLTree *T = this;
+    ImutAVLTree *Right = T->getRight();
+    while (Right) { T = Right; Right = T->getRight(); }
+    return T;
+  }
+
+  /// size - Returns the number of nodes in the tree, which includes
+  ///  both leaves and non-leaf nodes.
+  unsigned size() const {
+    unsigned n = 1;
+    if (const ImutAVLTree* L = getLeft())
+      n += L->size();
+    if (const ImutAVLTree* R = getRight())
+      n += R->size();
+    return n;
+  }
+
+  /// begin - Returns an iterator that iterates over the nodes of the tree
+  ///  in an inorder traversal.  The returned iterator thus refers to the
+  ///  the tree node with the minimum data element.
+  iterator begin() const { return iterator(this); }
+
+  /// end - Returns an iterator for the tree that denotes the end of an
+  ///  inorder traversal.
+  iterator end() const { return iterator(); }
+
+  bool isElementEqual(value_type_ref V) const {
+    // Compare the keys.
+    if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
+                           ImutInfo::KeyOfValue(V)))
+      return false;
+
+    // Also compare the data values.
+    if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
+                               ImutInfo::DataOfValue(V)))
+      return false;
+
+    return true;
+  }
+
+  bool isElementEqual(const ImutAVLTree* RHS) const {
+    return isElementEqual(RHS->getValue());
+  }
+
+  /// isEqual - Compares two trees for structural equality and returns true
+  ///   if they are equal.  This worst case performance of this operation is
+  //    linear in the sizes of the trees.
+  bool isEqual(const ImutAVLTree& RHS) const {
+    if (&RHS == this)
+      return true;
+
+    iterator LItr = begin(), LEnd = end();
+    iterator RItr = RHS.begin(), REnd = RHS.end();
+
+    while (LItr != LEnd && RItr != REnd) {
+      if (*LItr == *RItr) {
+        LItr.skipSubTree();
+        RItr.skipSubTree();
+        continue;
+      }
+
+      if (!LItr->isElementEqual(*RItr))
+        return false;
+
+      ++LItr;
+      ++RItr;
+    }
+
+    return LItr == LEnd && RItr == REnd;
+  }
+
+  /// isNotEqual - Compares two trees for structural inequality.  Performance
+  ///  is the same is isEqual.
+  bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
+
+  /// contains - Returns true if this tree contains a subtree (node) that
+  ///  has an data element that matches the specified key.  Complexity
+  ///  is logarithmic in the size of the tree.
+  bool contains(key_type_ref K) { return (bool) find(K); }
+
+  /// foreach - A member template the accepts invokes operator() on a functor
+  ///  object (specifed by Callback) for every node/subtree in the tree.
+  ///  Nodes are visited using an inorder traversal.
+  template <typename Callback>
+  void foreach(Callback& C) {
+    if (ImutAVLTree* L = getLeft())
+      L->foreach(C);
+
+    C(value);
+
+    if (ImutAVLTree* R = getRight())
+      R->foreach(C);
+  }
+
+  /// validateTree - A utility method that checks that the balancing and
+  ///  ordering invariants of the tree are satisifed.  It is a recursive
+  ///  method that returns the height of the tree, which is then consumed
+  ///  by the enclosing validateTree call.  External callers should ignore the
+  ///  return value.  An invalid tree will cause an assertion to fire in
+  ///  a debug build.
+  unsigned validateTree() const {
+    unsigned HL = getLeft() ? getLeft()->validateTree() : 0;
+    unsigned HR = getRight() ? getRight()->validateTree() : 0;
+    (void) HL;
+    (void) HR;
+
+    assert(getHeight() == ( HL > HR ? HL : HR ) + 1
+            && "Height calculation wrong");
+
+    assert((HL > HR ? HL-HR : HR-HL) <= 2
+           && "Balancing invariant violated");
+
+    assert((!getLeft() ||
+            ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+                             ImutInfo::KeyOfValue(getValue()))) &&
+           "Value in left child is not less that current value");
+
+
+    assert(!(getRight() ||
+             ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+                              ImutInfo::KeyOfValue(getRight()->getValue()))) &&
+           "Current value is not less that value of right child");
+
+    return getHeight();
+  }
+
+  //===----------------------------------------------------===//
+  // Internal values.
+  //===----------------------------------------------------===//
+
+private:
+  Factory *factory;
+  ImutAVLTree *left;
+  ImutAVLTree *right;
+  ImutAVLTree *prev;
+  ImutAVLTree *next;
+
+  unsigned height         : 28;
+  unsigned IsMutable      : 1;
+  unsigned IsDigestCached : 1;
+  unsigned IsCanonicalized : 1;
+
+  value_type value;
+  uint32_t digest;
+  uint32_t refCount;
+
+  //===----------------------------------------------------===//
+  // Internal methods (node manipulation; used by Factory).
+  //===----------------------------------------------------===//
+
+private:
+  /// ImutAVLTree - Internal constructor that is only called by
+  ///   ImutAVLFactory.
+  ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
+              unsigned height)
+    : factory(f), left(l), right(r), prev(nullptr), next(nullptr),
+      height(height), IsMutable(true), IsDigestCached(false),
+      IsCanonicalized(0), value(v), digest(0), refCount(0)
+  {
+    if (left) left->retain();
+    if (right) right->retain();
+  }
+
+  /// isMutable - Returns true if the left and right subtree references
+  ///  (as well as height) can be changed.  If this method returns false,
+  ///  the tree is truly immutable.  Trees returned from an ImutAVLFactory
+  ///  object should always have this method return true.  Further, if this
+  ///  method returns false for an instance of ImutAVLTree, all subtrees
+  ///  will also have this method return false.  The converse is not true.
+  bool isMutable() const { return IsMutable; }
+
+  /// hasCachedDigest - Returns true if the digest for this tree is cached.
+  ///  This can only be true if the tree is immutable.
+  bool hasCachedDigest() const { return IsDigestCached; }
+
+  //===----------------------------------------------------===//
+  // Mutating operations.  A tree root can be manipulated as
+  // long as its reference has not "escaped" from internal
+  // methods of a factory object (see below).  When a tree
+  // pointer is externally viewable by client code, the
+  // internal "mutable bit" is cleared to mark the tree
+  // immutable.  Note that a tree that still has its mutable
+  // bit set may have children (subtrees) that are themselves
+  // immutable.
+  //===----------------------------------------------------===//
+
+  /// markImmutable - Clears the mutable flag for a tree.  After this happens,
+  ///   it is an error to call setLeft(), setRight(), and setHeight().
+  void markImmutable() {
+    assert(isMutable() && "Mutable flag already removed.");
+    IsMutable = false;
+  }
+
+  /// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
+  void markedCachedDigest() {
+    assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
+    IsDigestCached = true;
+  }
+
+  /// setHeight - Changes the height of the tree.  Used internally by
+  ///  ImutAVLFactory.
+  void setHeight(unsigned h) {
+    assert(isMutable() && "Only a mutable tree can have its height changed.");
+    height = h;
+  }
+
+  static inline
+  uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+    uint32_t digest = 0;
+
+    if (L)
+      digest += L->computeDigest();
+
+    // Compute digest of stored data.
+    FoldingSetNodeID ID;
+    ImutInfo::Profile(ID,V);
+    digest += ID.ComputeHash();
+
+    if (R)
+      digest += R->computeDigest();
+
+    return digest;
+  }
+
+  inline uint32_t computeDigest() {
+    // Check the lowest bit to determine if digest has actually been
+    // pre-computed.
+    if (hasCachedDigest())
+      return digest;
+
+    uint32_t X = computeDigest(getLeft(), getRight(), getValue());
+    digest = X;
+    markedCachedDigest();
+    return X;
+  }
+
+  //===----------------------------------------------------===//
+  // Reference count operations.
+  //===----------------------------------------------------===//
+
+public:
+  void retain() { ++refCount; }
+  void release() {
+    assert(refCount > 0);
+    if (--refCount == 0)
+      destroy();
+  }
+  void destroy() {
+    if (left)
+      left->release();
+    if (right)
+      right->release();
+    if (IsCanonicalized) {
+      if (next)
+        next->prev = prev;
+
+      if (prev)
+        prev->next = next;
+      else
+        factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
+    }
+
+    // We need to clear the mutability bit in case we are
+    // destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
+    IsMutable = false;
+    factory->freeNodes.push_back(this);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Factory class.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo >
+class ImutAVLFactory {
+  friend class ImutAVLTree<ImutInfo>;
+  typedef ImutAVLTree<ImutInfo> TreeTy;
+  typedef typename TreeTy::value_type_ref value_type_ref;
+  typedef typename TreeTy::key_type_ref   key_type_ref;
+
+  typedef DenseMap<unsigned, TreeTy*> CacheTy;
+
+  CacheTy Cache;
+  uintptr_t Allocator;
+  std::vector<TreeTy*> createdNodes;
+  std::vector<TreeTy*> freeNodes;
+
+  bool ownsAllocator() const {
+    return Allocator & 0x1 ? false : true;
+  }
+
+  BumpPtrAllocator& getAllocator() const {
+    return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+  }
+
+  //===--------------------------------------------------===//
+  // Public interface.
+  //===--------------------------------------------------===//
+
+public:
+  ImutAVLFactory()
+    : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+  ImutAVLFactory(BumpPtrAllocator& Alloc)
+    : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+  ~ImutAVLFactory() {
+    if (ownsAllocator()) delete &getAllocator();
+  }
+
+  TreeTy* add(TreeTy* T, value_type_ref V) {
+    T = add_internal(V,T);
+    markImmutable(T);
+    recoverNodes();
+    return T;
+  }
+
+  TreeTy* remove(TreeTy* T, key_type_ref V) {
+    T = remove_internal(V,T);
+    markImmutable(T);
+    recoverNodes();
+    return T;
+  }
+
+  TreeTy* getEmptyTree() const { return nullptr; }
+
+protected:
+
+  //===--------------------------------------------------===//
+  // A bunch of quick helper functions used for reasoning
+  // about the properties of trees and their children.
+  // These have succinct names so that the balancing code
+  // is as terse (and readable) as possible.
+  //===--------------------------------------------------===//
+
+  bool            isEmpty(TreeTy* T) const { return !T; }
+  unsigned        getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; }
+  TreeTy*         getLeft(TreeTy* T) const { return T->getLeft(); }
+  TreeTy*         getRight(TreeTy* T) const { return T->getRight(); }
+  value_type_ref  getValue(TreeTy* T) const { return T->value; }
+
+  // Make sure the index is not the Tombstone or Entry key of the DenseMap.
+  static inline unsigned maskCacheIndex(unsigned I) {
+    return (I & ~0x02);
+  }
+
+  unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
+    unsigned hl = getHeight(L);
+    unsigned hr = getHeight(R);
+    return (hl > hr ? hl : hr) + 1;
+  }
+
+  static bool compareTreeWithSection(TreeTy* T,
+                                     typename TreeTy::iterator& TI,
+                                     typename TreeTy::iterator& TE) {
+    typename TreeTy::iterator I = T->begin(), E = T->end();
+    for ( ; I!=E ; ++I, ++TI) {
+      if (TI == TE || !I->isElementEqual(*TI))
+        return false;
+    }
+    return true;
+  }
+
+  //===--------------------------------------------------===//
+  // "createNode" is used to generate new tree roots that link
+  // to other trees.  The functon may also simply move links
+  // in an existing root if that root is still marked mutable.
+  // This is necessary because otherwise our balancing code
+  // would leak memory as it would create nodes that are
+  // then discarded later before the finished tree is
+  // returned to the caller.
+  //===--------------------------------------------------===//
+
+  TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+    BumpPtrAllocator& A = getAllocator();
+    TreeTy* T;
+    if (!freeNodes.empty()) {
+      T = freeNodes.back();
+      freeNodes.pop_back();
+      assert(T != L);
+      assert(T != R);
+    } else {
+      T = (TreeTy*) A.Allocate<TreeTy>();
+    }
+    new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
+    createdNodes.push_back(T);
+    return T;
+  }
+
+  TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) {
+    return createNode(newLeft, getValue(oldTree), newRight);
+  }
+
+  void recoverNodes() {
+    for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
+      TreeTy *N = createdNodes[i];
+      if (N->isMutable() && N->refCount == 0)
+        N->destroy();
+    }
+    createdNodes.clear();
+  }
+
+  /// balanceTree - Used by add_internal and remove_internal to
+  ///  balance a newly created tree.
+  TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) {
+    unsigned hl = getHeight(L);
+    unsigned hr = getHeight(R);
+
+    if (hl > hr + 2) {
+      assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
+
+      TreeTy *LL = getLeft(L);
+      TreeTy *LR = getRight(L);
+
+      if (getHeight(LL) >= getHeight(LR))
+        return createNode(LL, L, createNode(LR,V,R));
+
+      assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
+
+      TreeTy *LRL = getLeft(LR);
+      TreeTy *LRR = getRight(LR);
+
+      return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
+    }
+
+    if (hr > hl + 2) {
+      assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
+
+      TreeTy *RL = getLeft(R);
+      TreeTy *RR = getRight(R);
+
+      if (getHeight(RR) >= getHeight(RL))
+        return createNode(createNode(L,V,RL), R, RR);
+
+      assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
+
+      TreeTy *RLL = getLeft(RL);
+      TreeTy *RLR = getRight(RL);
+
+      return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
+    }
+
+    return createNode(L,V,R);
+  }
+
+  /// add_internal - Creates a new tree that includes the specified
+  ///  data and the data from the original tree.  If the original tree
+  ///  already contained the data item, the original tree is returned.
+  TreeTy* add_internal(value_type_ref V, TreeTy* T) {
+    if (isEmpty(T))
+      return createNode(T, V, T);
+    assert(!T->isMutable());
+
+    key_type_ref K = ImutInfo::KeyOfValue(V);
+    key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
+
+    if (ImutInfo::isEqual(K,KCurrent))
+      return createNode(getLeft(T), V, getRight(T));
+    else if (ImutInfo::isLess(K,KCurrent))
+      return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T));
+    else
+      return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T)));
+  }
+
+  /// remove_internal - Creates a new tree that includes all the data
+  ///  from the original tree except the specified data.  If the
+  ///  specified data did not exist in the original tree, the original
+  ///  tree is returned.
+  TreeTy* remove_internal(key_type_ref K, TreeTy* T) {
+    if (isEmpty(T))
+      return T;
+
+    assert(!T->isMutable());
+
+    key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
+
+    if (ImutInfo::isEqual(K,KCurrent)) {
+      return combineTrees(getLeft(T), getRight(T));
+    } else if (ImutInfo::isLess(K,KCurrent)) {
+      return balanceTree(remove_internal(K, getLeft(T)),
+                                            getValue(T), getRight(T));
+    } else {
+      return balanceTree(getLeft(T), getValue(T),
+                         remove_internal(K, getRight(T)));
+    }
+  }
+
+  TreeTy* combineTrees(TreeTy* L, TreeTy* R) {
+    if (isEmpty(L))
+      return R;
+    if (isEmpty(R))
+      return L;
+    TreeTy* OldNode;
+    TreeTy* newRight = removeMinBinding(R,OldNode);
+    return balanceTree(L, getValue(OldNode), newRight);
+  }
+
+  TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) {
+    assert(!isEmpty(T));
+    if (isEmpty(getLeft(T))) {
+      Noderemoved = T;
+      return getRight(T);
+    }
+    return balanceTree(removeMinBinding(getLeft(T), Noderemoved),
+                       getValue(T), getRight(T));
+  }
+
+  /// markImmutable - Clears the mutable bits of a root and all of its
+  ///  descendants.
+  void markImmutable(TreeTy* T) {
+    if (!T || !T->isMutable())
+      return;
+    T->markImmutable();
+    markImmutable(getLeft(T));
+    markImmutable(getRight(T));
+  }
+
+public:
+  TreeTy *getCanonicalTree(TreeTy *TNew) {
+    if (!TNew)
+      return nullptr;
+
+    if (TNew->IsCanonicalized)
+      return TNew;
+
+    // Search the hashtable for another tree with the same digest, and
+    // if find a collision compare those trees by their contents.
+    unsigned digest = TNew->computeDigest();
+    TreeTy *&entry = Cache[maskCacheIndex(digest)];
+    do {
+      if (!entry)
+        break;
+      for (TreeTy *T = entry ; T != nullptr; T = T->next) {
+        // Compare the Contents('T') with Contents('TNew')
+        typename TreeTy::iterator TI = T->begin(), TE = T->end();
+        if (!compareTreeWithSection(TNew, TI, TE))
+          continue;
+        if (TI != TE)
+          continue; // T has more contents than TNew.
+        // Trees did match!  Return 'T'.
+        if (TNew->refCount == 0)
+          TNew->destroy();
+        return T;
+      }
+      entry->prev = TNew;
+      TNew->next = entry;
+    }
+    while (false);
+
+    entry = TNew;
+    TNew->IsCanonicalized = true;
+    return TNew;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Iterators.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo>
+class ImutAVLTreeGenericIterator {
+  SmallVector<uintptr_t,20> stack;
+public:
+  enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
+                   Flags=0x3 };
+
+  typedef ImutAVLTree<ImutInfo> TreeTy;
+  typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
+
+  inline ImutAVLTreeGenericIterator() {}
+  inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+    if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
+  }
+
+  TreeTy* operator*() const {
+    assert(!stack.empty());
+    return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+  }
+
+  uintptr_t getVisitState() const {
+    assert(!stack.empty());
+    return stack.back() & Flags;
+  }
+
+
+  bool atEnd() const { return stack.empty(); }
+
+  bool atBeginning() const {
+    return stack.size() == 1 && getVisitState() == VisitedNone;
+  }
+
+  void skipToParent() {
+    assert(!stack.empty());
+    stack.pop_back();
+    if (stack.empty())
+      return;
+    switch (getVisitState()) {
+      case VisitedNone:
+        stack.back() |= VisitedLeft;
+        break;
+      case VisitedLeft:
+        stack.back() |= VisitedRight;
+        break;
+      default:
+        llvm_unreachable("Unreachable.");
+    }
+  }
+
+  inline bool operator==(const _Self& x) const {
+    return stack == x.stack;
+  }
+
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  _Self& operator++() {
+    assert(!stack.empty());
+    TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+    assert(Current);
+    switch (getVisitState()) {
+      case VisitedNone:
+        if (TreeTy* L = Current->getLeft())
+          stack.push_back(reinterpret_cast<uintptr_t>(L));
+        else
+          stack.back() |= VisitedLeft;
+        break;
+      case VisitedLeft:
+        if (TreeTy* R = Current->getRight())
+          stack.push_back(reinterpret_cast<uintptr_t>(R));
+        else
+          stack.back() |= VisitedRight;
+        break;
+      case VisitedRight:
+        skipToParent();
+        break;
+      default:
+        llvm_unreachable("Unreachable.");
+    }
+    return *this;
+  }
+
+  _Self& operator--() {
+    assert(!stack.empty());
+    TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+    assert(Current);
+    switch (getVisitState()) {
+      case VisitedNone:
+        stack.pop_back();
+        break;
+      case VisitedLeft:
+        stack.back() &= ~Flags; // Set state to "VisitedNone."
+        if (TreeTy* L = Current->getLeft())
+          stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
+        break;
+      case VisitedRight:
+        stack.back() &= ~Flags;
+        stack.back() |= VisitedLeft;
+        if (TreeTy* R = Current->getRight())
+          stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
+        break;
+      default:
+        llvm_unreachable("Unreachable.");
+    }
+    return *this;
+  }
+};
+
+template <typename ImutInfo>
+class ImutAVLTreeInOrderIterator {
+  typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+  InternalIteratorTy InternalItr;
+
+public:
+  typedef ImutAVLTree<ImutInfo> TreeTy;
+  typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
+
+  ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
+    if (Root) operator++(); // Advance to first element.
+  }
+
+  ImutAVLTreeInOrderIterator() : InternalItr() {}
+
+  inline bool operator==(const _Self& x) const {
+    return InternalItr == x.InternalItr;
+  }
+
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  inline TreeTy* operator*() const { return *InternalItr; }
+  inline TreeTy* operator->() const { return *InternalItr; }
+
+  inline _Self& operator++() {
+    do ++InternalItr;
+    while (!InternalItr.atEnd() &&
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+    return *this;
+  }
+
+  inline _Self& operator--() {
+    do --InternalItr;
+    while (!InternalItr.atBeginning() &&
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+    return *this;
+  }
+
+  inline void skipSubTree() {
+    InternalItr.skipToParent();
+
+    while (!InternalItr.atEnd() &&
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
+      ++InternalItr;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes for Profile information.
+//===----------------------------------------------------------------------===//
+
+/// Generic profile template.  The default behavior is to invoke the
+/// profile method of an object.  Specializations for primitive integers
+/// and generic handling of pointers is done below.
+template <typename T>
+struct ImutProfileInfo {
+  typedef const T  value_type;
+  typedef const T& value_type_ref;
+
+  static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+    FoldingSetTrait<T>::Profile(X,ID);
+  }
+};
+
+/// Profile traits for integers.
+template <typename T>
+struct ImutProfileInteger {
+  typedef const T  value_type;
+  typedef const T& value_type_ref;
+
+  static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+    ID.AddInteger(X);
+  }
+};
+
+#define PROFILE_INTEGER_INFO(X)\
+template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
+
+PROFILE_INTEGER_INFO(char)
+PROFILE_INTEGER_INFO(unsigned char)
+PROFILE_INTEGER_INFO(short)
+PROFILE_INTEGER_INFO(unsigned short)
+PROFILE_INTEGER_INFO(unsigned)
+PROFILE_INTEGER_INFO(signed)
+PROFILE_INTEGER_INFO(long)
+PROFILE_INTEGER_INFO(unsigned long)
+PROFILE_INTEGER_INFO(long long)
+PROFILE_INTEGER_INFO(unsigned long long)
+
+#undef PROFILE_INTEGER_INFO
+
+/// Profile traits for booleans.
+template <>
+struct ImutProfileInfo<bool> {
+  typedef const bool  value_type;
+  typedef const bool& value_type_ref;
+
+  static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+    ID.AddBoolean(X);
+  }
+};
+
+
+/// Generic profile trait for pointer types.  We treat pointers as
+/// references to unique objects.
+template <typename T>
+struct ImutProfileInfo<T*> {
+  typedef const T*   value_type;
+  typedef value_type value_type_ref;
+
+  static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
+    ID.AddPointer(X);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes that contain element comparison operators and type
+//  definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap.  These
+//  inherit from the profile traits (ImutProfileInfo) to include operations
+//  for element profiling.
+//===----------------------------------------------------------------------===//
+
+
+/// ImutContainerInfo - Generic definition of comparison operations for
+///   elements of immutable containers that defaults to using
+///   std::equal_to<> and std::less<> to perform comparison of elements.
+template <typename T>
+struct ImutContainerInfo : public ImutProfileInfo<T> {
+  typedef typename ImutProfileInfo<T>::value_type      value_type;
+  typedef typename ImutProfileInfo<T>::value_type_ref  value_type_ref;
+  typedef value_type      key_type;
+  typedef value_type_ref  key_type_ref;
+  typedef bool            data_type;
+  typedef bool            data_type_ref;
+
+  static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+  static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+  static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+    return std::equal_to<key_type>()(LHS,RHS);
+  }
+
+  static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+    return std::less<key_type>()(LHS,RHS);
+  }
+
+  static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+/// ImutContainerInfo - Specialization for pointer values to treat pointers
+///  as references to unique objects.  Pointers are thus compared by
+///  their addresses.
+template <typename T>
+struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
+  typedef typename ImutProfileInfo<T*>::value_type      value_type;
+  typedef typename ImutProfileInfo<T*>::value_type_ref  value_type_ref;
+  typedef value_type      key_type;
+  typedef value_type_ref  key_type_ref;
+  typedef bool            data_type;
+  typedef bool            data_type_ref;
+
+  static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+  static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+  static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+    return LHS == RHS;
+  }
+
+  static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+    return LHS < RHS;
+  }
+
+  static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable Set
+//===----------------------------------------------------------------------===//
+
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSet {
+public:
+  typedef typename ValInfo::value_type      value_type;
+  typedef typename ValInfo::value_type_ref  value_type_ref;
+  typedef ImutAVLTree<ValInfo> TreeTy;
+
+private:
+  TreeTy *Root;
+
+public:
+  /// Constructs a set from a pointer to a tree root.  In general one
+  /// should use a Factory object to create sets instead of directly
+  /// invoking the constructor, but there are cases where make this
+  /// constructor public is useful.
+  explicit ImmutableSet(TreeTy* R) : Root(R) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableSet &operator=(const ImmutableSet &X) {
+    if (Root != X.Root) {
+      if (X.Root) { X.Root->retain(); }
+      if (Root) { Root->release(); }
+      Root = X.Root;
+    }
+    return *this;
+  }
+  ~ImmutableSet() {
+    if (Root) { Root->release(); }
+  }
+
+  class Factory {
+    typename TreeTy::Factory F;
+    const bool Canonicalize;
+
+  public:
+    Factory(bool canonicalize = true)
+      : Canonicalize(canonicalize) {}
+
+    Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
+      : F(Alloc), Canonicalize(canonicalize) {}
+
+    /// getEmptySet - Returns an immutable set that contains no elements.
+    ImmutableSet getEmptySet() {
+      return ImmutableSet(F.getEmptyTree());
+    }
+
+    /// add - Creates a new immutable set that contains all of the values
+    ///  of the original set with the addition of the specified value.  If
+    ///  the original set already included the value, then the original set is
+    ///  returned and no memory is allocated.  The time and space complexity
+    ///  of this operation is logarithmic in the size of the original set.
+    ///  The memory allocated to represent the set is released when the
+    ///  factory object that created the set is destroyed.
+    ImmutableSet add(ImmutableSet Old, value_type_ref V) {
+      TreeTy *NewT = F.add(Old.Root, V);
+      return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
+    }
+
+    /// remove - Creates a new immutable set that contains all of the values
+    ///  of the original set with the exception of the specified value.  If
+    ///  the original set did not contain the value, the original set is
+    ///  returned and no memory is allocated.  The time and space complexity
+    ///  of this operation is logarithmic in the size of the original set.
+    ///  The memory allocated to represent the set is released when the
+    ///  factory object that created the set is destroyed.
+    ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
+      TreeTy *NewT = F.remove(Old.Root, V);
+      return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
+    }
+
+    BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
+
+    typename TreeTy::Factory *getTreeFactory() const {
+      return const_cast<typename TreeTy::Factory *>(&F);
+    }
+
+  private:
+    Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
+    void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
+  };
+
+  friend class Factory;
+
+  /// Returns true if the set contains the specified value.
+  bool contains(value_type_ref V) const {
+    return Root ? Root->contains(V) : false;
+  }
+
+  bool operator==(const ImmutableSet &RHS) const {
+    return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+  }
+
+  bool operator!=(const ImmutableSet &RHS) const {
+    return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+  }
+
+  TreeTy *getRoot() {
+    if (Root) { Root->retain(); }
+    return Root;
+  }
+
+  TreeTy *getRootWithoutRetain() const {
+    return Root;
+  }
+
+  /// isEmpty - Return true if the set contains no elements.
+  bool isEmpty() const { return !Root; }
+
+  /// isSingleton - Return true if the set contains exactly one element.
+  ///   This method runs in constant time.
+  bool isSingleton() const { return getHeight() == 1; }
+
+  template <typename Callback>
+  void foreach(Callback& C) { if (Root) Root->foreach(C); }
+
+  template <typename Callback>
+  void foreach() { if (Root) { Callback C; Root->foreach(C); } }
+
+  //===--------------------------------------------------===//
+  // Iterators.
+  //===--------------------------------------------------===//
+
+  class iterator {
+    typename TreeTy::iterator itr;
+
+    iterator() {}
+    iterator(TreeTy* t) : itr(t) {}
+    friend class ImmutableSet<ValT,ValInfo>;
+
+  public:
+    typedef ptrdiff_t difference_type;
+    typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type;
+    typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference;
+    typedef typename iterator::value_type *pointer;
+    typedef std::bidirectional_iterator_tag iterator_category;
+
+    typename iterator::reference operator*() const { return itr->getValue(); }
+    typename iterator::pointer   operator->() const { return &(operator*()); }
+
+    iterator& operator++() { ++itr; return *this; }
+    iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+    iterator& operator--() { --itr; return *this; }
+    iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
+
+    bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+    bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+  };
+
+  iterator begin() const { return iterator(Root); }
+  iterator end() const { return iterator(); }
+
+  //===--------------------------------------------------===//
+  // Utility methods.
+  //===--------------------------------------------------===//
+
+  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+  static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) {
+    ID.AddPointer(S.Root);
+  }
+
+  inline void Profile(FoldingSetNodeID& ID) const {
+    return Profile(ID,*this);
+  }
+
+  //===--------------------------------------------------===//
+  // For testing.
+  //===--------------------------------------------------===//
+
+  void validateTree() const { if (Root) Root->validateTree(); }
+};
+
+// NOTE: This may some day replace the current ImmutableSet.
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSetRef {
+public:
+  typedef typename ValInfo::value_type      value_type;
+  typedef typename ValInfo::value_type_ref  value_type_ref;
+  typedef ImutAVLTree<ValInfo> TreeTy;
+  typedef typename TreeTy::Factory          FactoryTy;
+
+private:
+  TreeTy *Root;
+  FactoryTy *Factory;
+
+public:
+  /// Constructs a set from a pointer to a tree root.  In general one
+  /// should use a Factory object to create sets instead of directly
+  /// invoking the constructor, but there are cases where make this
+  /// constructor public is useful.
+  explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
+    : Root(R),
+      Factory(F) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableSetRef(const ImmutableSetRef &X)
+    : Root(X.Root),
+      Factory(X.Factory) {
+    if (Root) { Root->retain(); }
+  }
+  ImmutableSetRef &operator=(const ImmutableSetRef &X) {
+    if (Root != X.Root) {
+      if (X.Root) { X.Root->retain(); }
+      if (Root) { Root->release(); }
+      Root = X.Root;
+      Factory = X.Factory;
+    }
+    return *this;
+  }
+  ~ImmutableSetRef() {
+    if (Root) { Root->release(); }
+  }
+
+  static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
+    return ImmutableSetRef(0, F);
+  }
+
+  ImmutableSetRef add(value_type_ref V) {
+    return ImmutableSetRef(Factory->add(Root, V), Factory);
+  }
+
+  ImmutableSetRef remove(value_type_ref V) {
+    return ImmutableSetRef(Factory->remove(Root, V), Factory);
+  }
+
+  /// Returns true if the set contains the specified value.
+  bool contains(value_type_ref V) const {
+    return Root ? Root->contains(V) : false;
+  }
+
+  ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
+    return ImmutableSet<ValT>(canonicalize ?
+                              Factory->getCanonicalTree(Root) : Root);
+  }
+
+  TreeTy *getRootWithoutRetain() const {
+    return Root;
+  }
+
+  bool operator==(const ImmutableSetRef &RHS) const {
+    return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+  }
+
+  bool operator!=(const ImmutableSetRef &RHS) const {
+    return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+  }
+
+  /// isEmpty - Return true if the set contains no elements.
+  bool isEmpty() const { return !Root; }
+
+  /// isSingleton - Return true if the set contains exactly one element.
+  ///   This method runs in constant time.
+  bool isSingleton() const { return getHeight() == 1; }
+
+  //===--------------------------------------------------===//
+  // Iterators.
+  //===--------------------------------------------------===//
+
+  class iterator {
+    typename TreeTy::iterator itr;
+    iterator(TreeTy* t) : itr(t) {}
+    friend class ImmutableSetRef<ValT,ValInfo>;
+  public:
+    iterator() {}
+    inline value_type_ref operator*() const { return itr->getValue(); }
+    inline iterator& operator++() { ++itr; return *this; }
+    inline iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+    inline iterator& operator--() { --itr; return *this; }
+    inline iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
+    inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+    inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+    inline value_type *operator->() const { return &(operator*()); }
+  };
+
+  iterator begin() const { return iterator(Root); }
+  iterator end() const { return iterator(); }
+
+  //===--------------------------------------------------===//
+  // Utility methods.
+  //===--------------------------------------------------===//
+
+  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+  static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
+    ID.AddPointer(S.Root);
+  }
+
+  inline void Profile(FoldingSetNodeID& ID) const {
+    return Profile(ID,*this);
+  }
+
+  //===--------------------------------------------------===//
+  // For testing.
+  //===--------------------------------------------------===//
+
+  void validateTree() const { if (Root) Root->validateTree(); }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
new file mode 100644
index 0000000..2ffb505
--- /dev/null
+++ b/include/llvm/ADT/IndexedMap.h
@@ -0,0 +1,82 @@
+//===- llvm/ADT/IndexedMap.h - An index map implementation ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an indexed map. The index map template takes two
+// types. The first is the mapped type and the second is a functor
+// that maps its argument to a size_t. On instantiation a "null" value
+// can be provided to be used as a "does not exist" indicator in the
+// map. A member function grow() is provided that given the value of
+// the maximally indexed key (the argument of the functor) makes sure
+// the map has enough space for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INDEXEDMAP_H
+#define LLVM_ADT_INDEXEDMAP_H
+
+#include "llvm/ADT/STLExtras.h"
+#include <cassert>
+#include <functional>
+#include <vector>
+
+namespace llvm {
+
+template <typename T, typename ToIndexT = llvm::identity<unsigned> >
+  class IndexedMap {
+    typedef typename ToIndexT::argument_type IndexT;
+    typedef std::vector<T> StorageT;
+    StorageT storage_;
+    T nullVal_;
+    ToIndexT toIndex_;
+
+  public:
+    IndexedMap() : nullVal_(T()) { }
+
+    explicit IndexedMap(const T& val) : nullVal_(val) { }
+
+    typename StorageT::reference operator[](IndexT n) {
+      assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+      return storage_[toIndex_(n)];
+    }
+
+    typename StorageT::const_reference operator[](IndexT n) const {
+      assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+      return storage_[toIndex_(n)];
+    }
+
+    void reserve(typename StorageT::size_type s) {
+      storage_.reserve(s);
+    }
+
+    void resize(typename StorageT::size_type s) {
+      storage_.resize(s, nullVal_);
+    }
+
+    void clear() {
+      storage_.clear();
+    }
+
+    void grow(IndexT n) {
+      unsigned NewSize = toIndex_(n) + 1;
+      if (NewSize > storage_.size())
+        resize(NewSize);
+    }
+
+    bool inBounds(IndexT n) const {
+      return toIndex_(n) < storage_.size();
+    }
+
+    typename StorageT::size_type size() const {
+      return storage_.size();
+    }
+  };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/IntEqClasses.h b/include/llvm/ADT/IntEqClasses.h
new file mode 100644
index 0000000..8e75c48
--- /dev/null
+++ b/include/llvm/ADT/IntEqClasses.h
@@ -0,0 +1,88 @@
+//===-- llvm/ADT/IntEqClasses.h - Equiv. Classes of Integers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Equivalence classes for small integers. This is a mapping of the integers
+// 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
+//
+// Initially each integer has its own equivalence class. Classes are joined by
+// passing a representative member of each class to join().
+//
+// Once the classes are built, compress() will number them 0 .. M-1 and prevent
+// further changes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTEQCLASSES_H
+#define LLVM_ADT_INTEQCLASSES_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class IntEqClasses {
+  /// EC - When uncompressed, map each integer to a smaller member of its
+  /// equivalence class. The class leader is the smallest member and maps to
+  /// itself.
+  ///
+  /// When compressed, EC[i] is the equivalence class of i.
+  SmallVector<unsigned, 8> EC;
+
+  /// NumClasses - The number of equivalence classes when compressed, or 0 when
+  /// uncompressed.
+  unsigned NumClasses;
+
+public:
+  /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
+  IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); }
+
+  /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
+  /// equivalence classes.
+  /// This requires an uncompressed map.
+  void grow(unsigned N);
+
+  /// clear - Clear all classes so that grow() will assign a unique class to
+  /// every integer.
+  void clear() {
+    EC.clear();
+    NumClasses = 0;
+  }
+
+  /// join - Join the equivalence classes of a and b. After joining classes,
+  /// findLeader(a) == findLeader(b).
+  /// This requires an uncompressed map.
+  void join(unsigned a, unsigned b);
+
+  /// findLeader - Compute the leader of a's equivalence class. This is the
+  /// smallest member of the class.
+  /// This requires an uncompressed map.
+  unsigned findLeader(unsigned a) const;
+
+  /// compress - Compress equivalence classes by numbering them 0 .. M.
+  /// This makes the equivalence class map immutable.
+  void compress();
+
+  /// getNumClasses - Return the number of equivalence classes after compress()
+  /// was called.
+  unsigned getNumClasses() const { return NumClasses; }
+
+  /// operator[] - Return a's equivalence class number, 0 .. getNumClasses()-1.
+  /// This requires a compressed map.
+  unsigned operator[](unsigned a) const {
+    assert(NumClasses && "operator[] called before compress()");
+    return EC[a];
+  }
+
+  /// uncompress - Change back to the uncompressed representation that allows
+  /// editing.
+  void uncompress();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
new file mode 100644
index 0000000..46549ee
--- /dev/null
+++ b/include/llvm/ADT/IntervalMap.h
@@ -0,0 +1,2166 @@
+//===- llvm/ADT/IntervalMap.h - A sorted interval map -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a coalescing interval map for small objects.
+//
+// KeyT objects are mapped to ValT objects. Intervals of keys that map to the
+// same value are represented in a compressed form.
+//
+// Iterators provide ordered access to the compressed intervals rather than the
+// individual keys, and insert and erase operations use key intervals as well.
+//
+// Like SmallVector, IntervalMap will store the first N intervals in the map
+// object itself without any allocations. When space is exhausted it switches to
+// a B+-tree representation with very small overhead for small key and value
+// objects.
+//
+// A Traits class specifies how keys are compared. It also allows IntervalMap to
+// work with both closed and half-open intervals.
+//
+// Keys and values are not stored next to each other in a std::pair, so we don't
+// provide such a value_type. Dereferencing iterators only returns the mapped
+// value. The interval bounds are accessible through the start() and stop()
+// iterator methods.
+//
+// IntervalMap is optimized for small key and value objects, 4 or 8 bytes each
+// is the optimal size. For large objects use std::map instead.
+//
+//===----------------------------------------------------------------------===//
+//
+// Synopsis:
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap {
+// public:
+//   typedef KeyT key_type;
+//   typedef ValT mapped_type;
+//   typedef RecyclingAllocator<...> Allocator;
+//   class iterator;
+//   class const_iterator;
+//
+//   explicit IntervalMap(Allocator&);
+//   ~IntervalMap():
+//
+//   bool empty() const;
+//   KeyT start() const;
+//   KeyT stop() const;
+//   ValT lookup(KeyT x, Value NotFound = Value()) const;
+//
+//   const_iterator begin() const;
+//   const_iterator end() const;
+//   iterator begin();
+//   iterator end();
+//   const_iterator find(KeyT x) const;
+//   iterator find(KeyT x);
+//
+//   void insert(KeyT a, KeyT b, ValT y);
+//   void clear();
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::const_iterator :
+//   public std::iterator<std::bidirectional_iterator_tag, ValT> {
+// public:
+//   bool operator==(const const_iterator &) const;
+//   bool operator!=(const const_iterator &) const;
+//   bool valid() const;
+//
+//   const KeyT &start() const;
+//   const KeyT &stop() const;
+//   const ValT &value() const;
+//   const ValT &operator*() const;
+//   const ValT *operator->() const;
+//
+//   const_iterator &operator++();
+//   const_iterator &operator++(int);
+//   const_iterator &operator--();
+//   const_iterator &operator--(int);
+//   void goToBegin();
+//   void goToEnd();
+//   void find(KeyT x);
+//   void advanceTo(KeyT x);
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::iterator : public const_iterator {
+// public:
+//   void insert(KeyT a, KeyT b, Value y);
+//   void erase();
+// };
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTERVALMAP_H
+#define LLVM_ADT_INTERVALMAP_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include <iterator>
+
+namespace llvm {
+
+
+//===----------------------------------------------------------------------===//
+//---                              Key traits                              ---//
+//===----------------------------------------------------------------------===//
+//
+// The IntervalMap works with closed or half-open intervals.
+// Adjacent intervals that map to the same value are coalesced.
+//
+// The IntervalMapInfo traits class is used to determine if a key is contained
+// in an interval, and if two intervals are adjacent so they can be coalesced.
+// The provided implementation works for closed integer intervals, other keys
+// probably need a specialized version.
+//
+// The point x is contained in [a;b] when !startLess(x, a) && !stopLess(b, x).
+//
+// It is assumed that (a;b] half-open intervals are not used, only [a;b) is
+// allowed. This is so that stopLess(a, b) can be used to determine if two
+// intervals overlap.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+struct IntervalMapInfo {
+
+  /// startLess - Return true if x is not in [a;b].
+  /// This is x < a both for closed intervals and for [a;b) half-open intervals.
+  static inline bool startLess(const T &x, const T &a) {
+    return x < a;
+  }
+
+  /// stopLess - Return true if x is not in [a;b].
+  /// This is b < x for a closed interval, b <= x for [a;b) half-open intervals.
+  static inline bool stopLess(const T &b, const T &x) {
+    return b < x;
+  }
+
+  /// adjacent - Return true when the intervals [x;a] and [b;y] can coalesce.
+  /// This is a+1 == b for closed intervals, a == b for half-open intervals.
+  static inline bool adjacent(const T &a, const T &b) {
+    return a+1 == b;
+  }
+
+};
+
+template <typename T>
+struct IntervalMapHalfOpenInfo {
+
+  /// startLess - Return true if x is not in [a;b).
+  static inline bool startLess(const T &x, const T &a) {
+    return x < a;
+  }
+
+  /// stopLess - Return true if x is not in [a;b).
+  static inline bool stopLess(const T &b, const T &x) {
+    return b <= x;
+  }
+
+  /// adjacent - Return true when the intervals [x;a) and [b;y) can coalesce.
+  static inline bool adjacent(const T &a, const T &b) {
+    return a == b;
+  }
+
+};
+
+/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
+/// It should be considered private to the implementation.
+namespace IntervalMapImpl {
+
+// Forward declarations.
+template <typename, typename, unsigned, typename> class LeafNode;
+template <typename, typename, unsigned, typename> class BranchNode;
+
+typedef std::pair<unsigned,unsigned> IdxPair;
+
+
+//===----------------------------------------------------------------------===//
+//---                    IntervalMapImpl::NodeBase                         ---//
+//===----------------------------------------------------------------------===//
+//
+// Both leaf and branch nodes store vectors of pairs.
+// Leaves store ((KeyT, KeyT), ValT) pairs, branches use (NodeRef, KeyT).
+//
+// Keys and values are stored in separate arrays to avoid padding caused by
+// different object alignments. This also helps improve locality of reference
+// when searching the keys.
+//
+// The nodes don't know how many elements they contain - that information is
+// stored elsewhere. Omitting the size field prevents padding and allows a node
+// to fill the allocated cache lines completely.
+//
+// These are typical key and value sizes, the node branching factor (N), and
+// wasted space when nodes are sized to fit in three cache lines (192 bytes):
+//
+//   T1  T2   N Waste  Used by
+//    4   4  24   0    Branch<4> (32-bit pointers)
+//    8   4  16   0    Leaf<4,4>, Branch<4>
+//    8   8  12   0    Leaf<4,8>, Branch<8>
+//   16   4   9  12    Leaf<8,4>
+//   16   8   8   0    Leaf<8,8>
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T1, typename T2, unsigned N>
+class NodeBase {
+public:
+  enum { Capacity = N };
+
+  T1 first[N];
+  T2 second[N];
+
+  /// copy - Copy elements from another node.
+  /// @param Other Node elements are copied from.
+  /// @param i     Beginning of the source range in other.
+  /// @param j     Beginning of the destination range in this.
+  /// @param Count Number of elements to copy.
+  template <unsigned M>
+  void copy(const NodeBase<T1, T2, M> &Other, unsigned i,
+            unsigned j, unsigned Count) {
+    assert(i + Count <= M && "Invalid source range");
+    assert(j + Count <= N && "Invalid dest range");
+    for (unsigned e = i + Count; i != e; ++i, ++j) {
+      first[j]  = Other.first[i];
+      second[j] = Other.second[i];
+    }
+  }
+
+  /// moveLeft - Move elements to the left.
+  /// @param i     Beginning of the source range.
+  /// @param j     Beginning of the destination range.
+  /// @param Count Number of elements to copy.
+  void moveLeft(unsigned i, unsigned j, unsigned Count) {
+    assert(j <= i && "Use moveRight shift elements right");
+    copy(*this, i, j, Count);
+  }
+
+  /// moveRight - Move elements to the right.
+  /// @param i     Beginning of the source range.
+  /// @param j     Beginning of the destination range.
+  /// @param Count Number of elements to copy.
+  void moveRight(unsigned i, unsigned j, unsigned Count) {
+    assert(i <= j && "Use moveLeft shift elements left");
+    assert(j + Count <= N && "Invalid range");
+    while (Count--) {
+      first[j + Count]  = first[i + Count];
+      second[j + Count] = second[i + Count];
+    }
+  }
+
+  /// erase - Erase elements [i;j).
+  /// @param i    Beginning of the range to erase.
+  /// @param j    End of the range. (Exclusive).
+  /// @param Size Number of elements in node.
+  void erase(unsigned i, unsigned j, unsigned Size) {
+    moveLeft(j, i, Size - j);
+  }
+
+  /// erase - Erase element at i.
+  /// @param i    Index of element to erase.
+  /// @param Size Number of elements in node.
+  void erase(unsigned i, unsigned Size) {
+    erase(i, i+1, Size);
+  }
+
+  /// shift - Shift elements [i;size) 1 position to the right.
+  /// @param i    Beginning of the range to move.
+  /// @param Size Number of elements in node.
+  void shift(unsigned i, unsigned Size) {
+    moveRight(i, i + 1, Size - i);
+  }
+
+  /// transferToLeftSib - Transfer elements to a left sibling node.
+  /// @param Size  Number of elements in this.
+  /// @param Sib   Left sibling node.
+  /// @param SSize Number of elements in sib.
+  /// @param Count Number of elements to transfer.
+  void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+                         unsigned Count) {
+    Sib.copy(*this, 0, SSize, Count);
+    erase(0, Count, Size);
+  }
+
+  /// transferToRightSib - Transfer elements to a right sibling node.
+  /// @param Size  Number of elements in this.
+  /// @param Sib   Right sibling node.
+  /// @param SSize Number of elements in sib.
+  /// @param Count Number of elements to transfer.
+  void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+                          unsigned Count) {
+    Sib.moveRight(0, Count, SSize);
+    Sib.copy(*this, Size-Count, 0, Count);
+  }
+
+  /// adjustFromLeftSib - Adjust the number if elements in this node by moving
+  /// elements to or from a left sibling node.
+  /// @param Size  Number of elements in this.
+  /// @param Sib   Right sibling node.
+  /// @param SSize Number of elements in sib.
+  /// @param Add   The number of elements to add to this node, possibly < 0.
+  /// @return      Number of elements added to this node, possibly negative.
+  int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add) {
+    if (Add > 0) {
+      // We want to grow, copy from sib.
+      unsigned Count = std::min(std::min(unsigned(Add), SSize), N - Size);
+      Sib.transferToRightSib(SSize, *this, Size, Count);
+      return Count;
+    } else {
+      // We want to shrink, copy to sib.
+      unsigned Count = std::min(std::min(unsigned(-Add), Size), N - SSize);
+      transferToLeftSib(Size, Sib, SSize, Count);
+      return -Count;
+    }
+  }
+};
+
+/// IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
+/// @param Node  Array of pointers to sibling nodes.
+/// @param Nodes Number of nodes.
+/// @param CurSize Array of current node sizes, will be overwritten.
+/// @param NewSize Array of desired node sizes.
+template <typename NodeT>
+void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
+                        unsigned CurSize[], const unsigned NewSize[]) {
+  // Move elements right.
+  for (int n = Nodes - 1; n; --n) {
+    if (CurSize[n] == NewSize[n])
+      continue;
+    for (int m = n - 1; m != -1; --m) {
+      int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
+                                         NewSize[n] - CurSize[n]);
+      CurSize[m] -= d;
+      CurSize[n] += d;
+      // Keep going if the current node was exhausted.
+      if (CurSize[n] >= NewSize[n])
+          break;
+    }
+  }
+
+  if (Nodes == 0)
+    return;
+
+  // Move elements left.
+  for (unsigned n = 0; n != Nodes - 1; ++n) {
+    if (CurSize[n] == NewSize[n])
+      continue;
+    for (unsigned m = n + 1; m != Nodes; ++m) {
+      int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
+                                        CurSize[n] -  NewSize[n]);
+      CurSize[m] += d;
+      CurSize[n] -= d;
+      // Keep going if the current node was exhausted.
+      if (CurSize[n] >= NewSize[n])
+          break;
+    }
+  }
+
+#ifndef NDEBUG
+  for (unsigned n = 0; n != Nodes; n++)
+    assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
+#endif
+}
+
+/// IntervalMapImpl::distribute - Compute a new distribution of node elements
+/// after an overflow or underflow. Reserve space for a new element at Position,
+/// and compute the node that will hold Position after redistributing node
+/// elements.
+///
+/// It is required that
+///
+///   Elements == sum(CurSize), and
+///   Elements + Grow <= Nodes * Capacity.
+///
+/// NewSize[] will be filled in such that:
+///
+///   sum(NewSize) == Elements, and
+///   NewSize[i] <= Capacity.
+///
+/// The returned index is the node where Position will go, so:
+///
+///   sum(NewSize[0..idx-1]) <= Position
+///   sum(NewSize[0..idx])   >= Position
+///
+/// The last equality, sum(NewSize[0..idx]) == Position, can only happen when
+/// Grow is set and NewSize[idx] == Capacity-1. The index points to the node
+/// before the one holding the Position'th element where there is room for an
+/// insertion.
+///
+/// @param Nodes    The number of nodes.
+/// @param Elements Total elements in all nodes.
+/// @param Capacity The capacity of each node.
+/// @param CurSize  Array[Nodes] of current node sizes, or NULL.
+/// @param NewSize  Array[Nodes] to receive the new node sizes.
+/// @param Position Insert position.
+/// @param Grow     Reserve space for a new element at Position.
+/// @return         (node, offset) for Position.
+IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
+                   const unsigned *CurSize, unsigned NewSize[],
+                   unsigned Position, bool Grow);
+
+
+//===----------------------------------------------------------------------===//
+//---                   IntervalMapImpl::NodeSizer                         ---//
+//===----------------------------------------------------------------------===//
+//
+// Compute node sizes from key and value types.
+//
+// The branching factors are chosen to make nodes fit in three cache lines.
+// This may not be possible if keys or values are very large. Such large objects
+// are handled correctly, but a std::map would probably give better performance.
+//
+//===----------------------------------------------------------------------===//
+
+enum {
+  // Cache line size. Most architectures have 32 or 64 byte cache lines.
+  // We use 64 bytes here because it provides good branching factors.
+  Log2CacheLine = 6,
+  CacheLineBytes = 1 << Log2CacheLine,
+  DesiredNodeBytes = 3 * CacheLineBytes
+};
+
+template <typename KeyT, typename ValT>
+struct NodeSizer {
+  enum {
+    // Compute the leaf node branching factor that makes a node fit in three
+    // cache lines. The branching factor must be at least 3, or some B+-tree
+    // balancing algorithms won't work.
+    // LeafSize can't be larger than CacheLineBytes. This is required by the
+    // PointerIntPair used by NodeRef.
+    DesiredLeafSize = DesiredNodeBytes /
+      static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)),
+    MinLeafSize = 3,
+    LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
+  };
+
+  typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase;
+
+  enum {
+    // Now that we have the leaf branching factor, compute the actual allocation
+    // unit size by rounding up to a whole number of cache lines.
+    AllocBytes = (sizeof(LeafBase) + CacheLineBytes-1) & ~(CacheLineBytes-1),
+
+    // Determine the branching factor for branch nodes.
+    BranchSize = AllocBytes /
+      static_cast<unsigned>(sizeof(KeyT) + sizeof(void*))
+  };
+
+  /// Allocator - The recycling allocator used for both branch and leaf nodes.
+  /// This typedef is very likely to be identical for all IntervalMaps with
+  /// reasonably sized entries, so the same allocator can be shared among
+  /// different kinds of maps.
+  typedef RecyclingAllocator<BumpPtrAllocator, char,
+                             AllocBytes, CacheLineBytes> Allocator;
+
+};
+
+
+//===----------------------------------------------------------------------===//
+//---                     IntervalMapImpl::NodeRef                         ---//
+//===----------------------------------------------------------------------===//
+//
+// B+-tree nodes can be leaves or branches, so we need a polymorphic node
+// pointer that can point to both kinds.
+//
+// All nodes are cache line aligned and the low 6 bits of a node pointer are
+// always 0. These bits are used to store the number of elements in the
+// referenced node. Besides saving space, placing node sizes in the parents
+// allow tree balancing algorithms to run without faulting cache lines for nodes
+// that may not need to be modified.
+//
+// A NodeRef doesn't know whether it references a leaf node or a branch node.
+// It is the responsibility of the caller to use the correct types.
+//
+// Nodes are never supposed to be empty, and it is invalid to store a node size
+// of 0 in a NodeRef. The valid range of sizes is 1-64.
+//
+//===----------------------------------------------------------------------===//
+
+class NodeRef {
+  struct CacheAlignedPointerTraits {
+    static inline void *getAsVoidPointer(void *P) { return P; }
+    static inline void *getFromVoidPointer(void *P) { return P; }
+    enum { NumLowBitsAvailable = Log2CacheLine };
+  };
+  PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
+
+public:
+  /// NodeRef - Create a null ref.
+  NodeRef() {}
+
+  /// operator bool - Detect a null ref.
+  LLVM_EXPLICIT operator bool() const { return pip.getOpaqueValue(); }
+
+  /// NodeRef - Create a reference to the node p with n elements.
+  template <typename NodeT>
+  NodeRef(NodeT *p, unsigned n) : pip(p, n - 1) {
+    assert(n <= NodeT::Capacity && "Size too big for node");
+  }
+
+  /// size - Return the number of elements in the referenced node.
+  unsigned size() const { return pip.getInt() + 1; }
+
+  /// setSize - Update the node size.
+  void setSize(unsigned n) { pip.setInt(n - 1); }
+
+  /// subtree - Access the i'th subtree reference in a branch node.
+  /// This depends on branch nodes storing the NodeRef array as their first
+  /// member.
+  NodeRef &subtree(unsigned i) const {
+    return reinterpret_cast<NodeRef*>(pip.getPointer())[i];
+  }
+
+  /// get - Dereference as a NodeT reference.
+  template <typename NodeT>
+  NodeT &get() const {
+    return *reinterpret_cast<NodeT*>(pip.getPointer());
+  }
+
+  bool operator==(const NodeRef &RHS) const {
+    if (pip == RHS.pip)
+      return true;
+    assert(pip.getPointer() != RHS.pip.getPointer() && "Inconsistent NodeRefs");
+    return false;
+  }
+
+  bool operator!=(const NodeRef &RHS) const {
+    return !operator==(RHS);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//---                      IntervalMapImpl::LeafNode                       ---//
+//===----------------------------------------------------------------------===//
+//
+// Leaf nodes store up to N disjoint intervals with corresponding values.
+//
+// The intervals are kept sorted and fully coalesced so there are no adjacent
+// intervals mapping to the same value.
+//
+// These constraints are always satisfied:
+//
+// - Traits::stopLess(start(i), stop(i))    - Non-empty, sane intervals.
+//
+// - Traits::stopLess(stop(i), start(i + 1) - Sorted.
+//
+// - value(i) != value(i + 1) || !Traits::adjacent(stop(i), start(i + 1))
+//                                          - Fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class LeafNode : public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
+public:
+  const KeyT &start(unsigned i) const { return this->first[i].first; }
+  const KeyT &stop(unsigned i) const { return this->first[i].second; }
+  const ValT &value(unsigned i) const { return this->second[i]; }
+
+  KeyT &start(unsigned i) { return this->first[i].first; }
+  KeyT &stop(unsigned i) { return this->first[i].second; }
+  ValT &value(unsigned i) { return this->second[i]; }
+
+  /// findFrom - Find the first interval after i that may contain x.
+  /// @param i    Starting index for the search.
+  /// @param Size Number of elements in node.
+  /// @param x    Key to search for.
+  /// @return     First index with !stopLess(key[i].stop, x), or size.
+  ///             This is the first interval that can possibly contain x.
+  unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+    assert(i <= Size && Size <= N && "Bad indices");
+    assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+           "Index is past the needed point");
+    while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+    return i;
+  }
+
+  /// safeFind - Find an interval that is known to exist. This is the same as
+  /// findFrom except is it assumed that x is at least within range of the last
+  /// interval.
+  /// @param i Starting index for the search.
+  /// @param x Key to search for.
+  /// @return  First index with !stopLess(key[i].stop, x), never size.
+  ///          This is the first interval that can possibly contain x.
+  unsigned safeFind(unsigned i, KeyT x) const {
+    assert(i < N && "Bad index");
+    assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+           "Index is past the needed point");
+    while (Traits::stopLess(stop(i), x)) ++i;
+    assert(i < N && "Unsafe intervals");
+    return i;
+  }
+
+  /// safeLookup - Lookup mapped value for a safe key.
+  /// It is assumed that x is within range of the last entry.
+  /// @param x        Key to search for.
+  /// @param NotFound Value to return if x is not in any interval.
+  /// @return         The mapped value at x or NotFound.
+  ValT safeLookup(KeyT x, ValT NotFound) const {
+    unsigned i = safeFind(0, x);
+    return Traits::startLess(x, start(i)) ? NotFound : value(i);
+  }
+
+  unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y);
+};
+
+/// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as
+/// possible. This may cause the node to grow by 1, or it may cause the node
+/// to shrink because of coalescing.
+/// @param Pos  Starting index = insertFrom(0, size, a)
+/// @param Size Number of elements in node.
+/// @param a    Interval start.
+/// @param b    Interval stop.
+/// @param y    Value be mapped.
+/// @return     (insert position, new size), or (i, Capacity+1) on overflow.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+unsigned LeafNode<KeyT, ValT, N, Traits>::
+insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y) {
+  unsigned i = Pos;
+  assert(i <= Size && Size <= N && "Invalid index");
+  assert(!Traits::stopLess(b, a) && "Invalid interval");
+
+  // Verify the findFrom invariant.
+  assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
+  assert((i == Size || !Traits::stopLess(stop(i), a)));
+  assert((i == Size || Traits::stopLess(b, start(i))) && "Overlapping insert");
+
+  // Coalesce with previous interval.
+  if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
+    Pos = i - 1;
+    // Also coalesce with next interval?
+    if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
+      stop(i - 1) = stop(i);
+      this->erase(i, Size);
+      return Size - 1;
+    }
+    stop(i - 1) = b;
+    return Size;
+  }
+
+  // Detect overflow.
+  if (i == N)
+    return N + 1;
+
+  // Add new interval at end.
+  if (i == Size) {
+    start(i) = a;
+    stop(i) = b;
+    value(i) = y;
+    return Size + 1;
+  }
+
+  // Try to coalesce with following interval.
+  if (value(i) == y && Traits::adjacent(b, start(i))) {
+    start(i) = a;
+    return Size;
+  }
+
+  // We must insert before i. Detect overflow.
+  if (Size == N)
+    return N + 1;
+
+  // Insert before i.
+  this->shift(i, Size);
+  start(i) = a;
+  stop(i) = b;
+  value(i) = y;
+  return Size + 1;
+}
+
+
+//===----------------------------------------------------------------------===//
+//---                   IntervalMapImpl::BranchNode                        ---//
+//===----------------------------------------------------------------------===//
+//
+// A branch node stores references to 1--N subtrees all of the same height.
+//
+// The key array in a branch node holds the rightmost stop key of each subtree.
+// It is redundant to store the last stop key since it can be found in the
+// parent node, but doing so makes tree balancing a lot simpler.
+//
+// It is unusual for a branch node to only have one subtree, but it can happen
+// in the root node if it is smaller than the normal nodes.
+//
+// When all of the leaf nodes from all the subtrees are concatenated, they must
+// satisfy the same constraints as a single leaf node. They must be sorted,
+// sane, and fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class BranchNode : public NodeBase<NodeRef, KeyT, N> {
+public:
+  const KeyT &stop(unsigned i) const { return this->second[i]; }
+  const NodeRef &subtree(unsigned i) const { return this->first[i]; }
+
+  KeyT &stop(unsigned i) { return this->second[i]; }
+  NodeRef &subtree(unsigned i) { return this->first[i]; }
+
+  /// findFrom - Find the first subtree after i that may contain x.
+  /// @param i    Starting index for the search.
+  /// @param Size Number of elements in node.
+  /// @param x    Key to search for.
+  /// @return     First index with !stopLess(key[i], x), or size.
+  ///             This is the first subtree that can possibly contain x.
+  unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+    assert(i <= Size && Size <= N && "Bad indices");
+    assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+           "Index to findFrom is past the needed point");
+    while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+    return i;
+  }
+
+  /// safeFind - Find a subtree that is known to exist. This is the same as
+  /// findFrom except is it assumed that x is in range.
+  /// @param i Starting index for the search.
+  /// @param x Key to search for.
+  /// @return  First index with !stopLess(key[i], x), never size.
+  ///          This is the first subtree that can possibly contain x.
+  unsigned safeFind(unsigned i, KeyT x) const {
+    assert(i < N && "Bad index");
+    assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+           "Index is past the needed point");
+    while (Traits::stopLess(stop(i), x)) ++i;
+    assert(i < N && "Unsafe intervals");
+    return i;
+  }
+
+  /// safeLookup - Get the subtree containing x, Assuming that x is in range.
+  /// @param x Key to search for.
+  /// @return  Subtree containing x
+  NodeRef safeLookup(KeyT x) const {
+    return subtree(safeFind(0, x));
+  }
+
+  /// insert - Insert a new (subtree, stop) pair.
+  /// @param i    Insert position, following entries will be shifted.
+  /// @param Size Number of elements in node.
+  /// @param Node Subtree to insert.
+  /// @param Stop Last key in subtree.
+  void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop) {
+    assert(Size < N && "branch node overflow");
+    assert(i <= Size && "Bad insert position");
+    this->shift(i, Size);
+    subtree(i) = Node;
+    stop(i) = Stop;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//---                         IntervalMapImpl::Path                        ---//
+//===----------------------------------------------------------------------===//
+//
+// A Path is used by iterators to represent a position in a B+-tree, and the
+// path to get there from the root.
+//
+// The Path class also contains the tree navigation code that doesn't have to
+// be templatized.
+//
+//===----------------------------------------------------------------------===//
+
+class Path {
+  /// Entry - Each step in the path is a node pointer and an offset into that
+  /// node.
+  struct Entry {
+    void *node;
+    unsigned size;
+    unsigned offset;
+
+    Entry(void *Node, unsigned Size, unsigned Offset)
+      : node(Node), size(Size), offset(Offset) {}
+
+    Entry(NodeRef Node, unsigned Offset)
+      : node(&Node.subtree(0)), size(Node.size()), offset(Offset) {}
+
+    NodeRef &subtree(unsigned i) const {
+      return reinterpret_cast<NodeRef*>(node)[i];
+    }
+  };
+
+  /// path - The path entries, path[0] is the root node, path.back() is a leaf.
+  SmallVector<Entry, 4> path;
+
+public:
+  // Node accessors.
+  template <typename NodeT> NodeT &node(unsigned Level) const {
+    return *reinterpret_cast<NodeT*>(path[Level].node);
+  }
+  unsigned size(unsigned Level) const { return path[Level].size; }
+  unsigned offset(unsigned Level) const { return path[Level].offset; }
+  unsigned &offset(unsigned Level) { return path[Level].offset; }
+
+  // Leaf accessors.
+  template <typename NodeT> NodeT &leaf() const {
+    return *reinterpret_cast<NodeT*>(path.back().node);
+  }
+  unsigned leafSize() const { return path.back().size; }
+  unsigned leafOffset() const { return path.back().offset; }
+  unsigned &leafOffset() { return path.back().offset; }
+
+  /// valid - Return true if path is at a valid node, not at end().
+  bool valid() const {
+    return !path.empty() && path.front().offset < path.front().size;
+  }
+
+  /// height - Return the height of the tree corresponding to this path.
+  /// This matches map->height in a full path.
+  unsigned height() const { return path.size() - 1; }
+
+  /// subtree - Get the subtree referenced from Level. When the path is
+  /// consistent, node(Level + 1) == subtree(Level).
+  /// @param Level 0..height-1. The leaves have no subtrees.
+  NodeRef &subtree(unsigned Level) const {
+    return path[Level].subtree(path[Level].offset);
+  }
+
+  /// reset - Reset cached information about node(Level) from subtree(Level -1).
+  /// @param Level 1..height. THe node to update after parent node changed.
+  void reset(unsigned Level) {
+    path[Level] = Entry(subtree(Level - 1), offset(Level));
+  }
+
+  /// push - Add entry to path.
+  /// @param Node Node to add, should be subtree(path.size()-1).
+  /// @param Offset Offset into Node.
+  void push(NodeRef Node, unsigned Offset) {
+    path.push_back(Entry(Node, Offset));
+  }
+
+  /// pop - Remove the last path entry.
+  void pop() {
+    path.pop_back();
+  }
+
+  /// setSize - Set the size of a node both in the path and in the tree.
+  /// @param Level 0..height. Note that setting the root size won't change
+  ///              map->rootSize.
+  /// @param Size New node size.
+  void setSize(unsigned Level, unsigned Size) {
+    path[Level].size = Size;
+    if (Level)
+      subtree(Level - 1).setSize(Size);
+  }
+
+  /// setRoot - Clear the path and set a new root node.
+  /// @param Node New root node.
+  /// @param Size New root size.
+  /// @param Offset Offset into root node.
+  void setRoot(void *Node, unsigned Size, unsigned Offset) {
+    path.clear();
+    path.push_back(Entry(Node, Size, Offset));
+  }
+
+  /// replaceRoot - Replace the current root node with two new entries after the
+  /// tree height has increased.
+  /// @param Root The new root node.
+  /// @param Size Number of entries in the new root.
+  /// @param Offsets Offsets into the root and first branch nodes.
+  void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
+
+  /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+  /// @param Level Get the sibling to node(Level).
+  /// @return Left sibling, or NodeRef().
+  NodeRef getLeftSibling(unsigned Level) const;
+
+  /// moveLeft - Move path to the left sibling at Level. Leave nodes below Level
+  /// unaltered.
+  /// @param Level Move node(Level).
+  void moveLeft(unsigned Level);
+
+  /// fillLeft - Grow path to Height by taking leftmost branches.
+  /// @param Height The target height.
+  void fillLeft(unsigned Height) {
+    while (height() < Height)
+      push(subtree(height()), 0);
+  }
+
+  /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+  /// @param Level Get the sinbling to node(Level).
+  /// @return Left sibling, or NodeRef().
+  NodeRef getRightSibling(unsigned Level) const;
+
+  /// moveRight - Move path to the left sibling at Level. Leave nodes below
+  /// Level unaltered.
+  /// @param Level Move node(Level).
+  void moveRight(unsigned Level);
+
+  /// atBegin - Return true if path is at begin().
+  bool atBegin() const {
+    for (unsigned i = 0, e = path.size(); i != e; ++i)
+      if (path[i].offset != 0)
+        return false;
+    return true;
+  }
+
+  /// atLastEntry - Return true if the path is at the last entry of the node at
+  /// Level.
+  /// @param Level Node to examine.
+  bool atLastEntry(unsigned Level) const {
+    return path[Level].offset == path[Level].size - 1;
+  }
+
+  /// legalizeForInsert - Prepare the path for an insertion at Level. When the
+  /// path is at end(), node(Level) may not be a legal node. legalizeForInsert
+  /// ensures that node(Level) is real by moving back to the last node at Level,
+  /// and setting offset(Level) to size(Level) if required.
+  /// @param Level The level where an insertion is about to take place.
+  void legalizeForInsert(unsigned Level) {
+    if (valid())
+      return;
+    moveLeft(Level);
+    ++path[Level].offset;
+  }
+};
+
+} // namespace IntervalMapImpl
+
+
+//===----------------------------------------------------------------------===//
+//---                          IntervalMap                                ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT,
+          unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
+          typename Traits = IntervalMapInfo<KeyT> >
+class IntervalMap {
+  typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer;
+  typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf;
+  typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>
+    Branch;
+  typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf;
+  typedef IntervalMapImpl::IdxPair IdxPair;
+
+  // The RootLeaf capacity is given as a template parameter. We must compute the
+  // corresponding RootBranch capacity.
+  enum {
+    DesiredRootBranchCap = (sizeof(RootLeaf) - sizeof(KeyT)) /
+      (sizeof(KeyT) + sizeof(IntervalMapImpl::NodeRef)),
+    RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
+  };
+
+  typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>
+    RootBranch;
+
+  // When branched, we store a global start key as well as the branch node.
+  struct RootBranchData {
+    KeyT start;
+    RootBranch node;
+  };
+
+  enum {
+    RootDataSize = sizeof(RootBranchData) > sizeof(RootLeaf) ?
+                   sizeof(RootBranchData) : sizeof(RootLeaf)
+  };
+
+public:
+  typedef typename Sizer::Allocator Allocator;
+  typedef KeyT KeyType;
+  typedef ValT ValueType;
+  typedef Traits KeyTraits;
+
+private:
+  // The root data is either a RootLeaf or a RootBranchData instance.
+  // We can't put them in a union since C++03 doesn't allow non-trivial
+  // constructors in unions.
+  // Instead, we use a char array with pointer alignment. The alignment is
+  // ensured by the allocator member in the class, but still verified in the
+  // constructor. We don't support keys or values that are more aligned than a
+  // pointer.
+  char data[RootDataSize];
+
+  // Tree height.
+  // 0: Leaves in root.
+  // 1: Root points to leaf.
+  // 2: root->branch->leaf ...
+  unsigned height;
+
+  // Number of entries in the root node.
+  unsigned rootSize;
+
+  // Allocator used for creating external nodes.
+  Allocator &allocator;
+
+  /// dataAs - Represent data as a node type without breaking aliasing rules.
+  template <typename T>
+  T &dataAs() const {
+    union {
+      const char *d;
+      T *t;
+    } u;
+    u.d = data;
+    return *u.t;
+  }
+
+  const RootLeaf &rootLeaf() const {
+    assert(!branched() && "Cannot acces leaf data in branched root");
+    return dataAs<RootLeaf>();
+  }
+  RootLeaf &rootLeaf() {
+    assert(!branched() && "Cannot acces leaf data in branched root");
+    return dataAs<RootLeaf>();
+  }
+  RootBranchData &rootBranchData() const {
+    assert(branched() && "Cannot access branch data in non-branched root");
+    return dataAs<RootBranchData>();
+  }
+  RootBranchData &rootBranchData() {
+    assert(branched() && "Cannot access branch data in non-branched root");
+    return dataAs<RootBranchData>();
+  }
+  const RootBranch &rootBranch() const { return rootBranchData().node; }
+  RootBranch &rootBranch()             { return rootBranchData().node; }
+  KeyT rootBranchStart() const { return rootBranchData().start; }
+  KeyT &rootBranchStart()      { return rootBranchData().start; }
+
+  template <typename NodeT> NodeT *newNode() {
+    return new(allocator.template Allocate<NodeT>()) NodeT();
+  }
+
+  template <typename NodeT> void deleteNode(NodeT *P) {
+    P->~NodeT();
+    allocator.Deallocate(P);
+  }
+
+  IdxPair branchRoot(unsigned Position);
+  IdxPair splitRoot(unsigned Position);
+
+  void switchRootToBranch() {
+    rootLeaf().~RootLeaf();
+    height = 1;
+    new (&rootBranchData()) RootBranchData();
+  }
+
+  void switchRootToLeaf() {
+    rootBranchData().~RootBranchData();
+    height = 0;
+    new(&rootLeaf()) RootLeaf();
+  }
+
+  bool branched() const { return height > 0; }
+
+  ValT treeSafeLookup(KeyT x, ValT NotFound) const;
+  void visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
+                  unsigned Level));
+  void deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level);
+
+public:
+  explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
+    assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 &&
+           "Insufficient alignment");
+    new(&rootLeaf()) RootLeaf();
+  }
+
+  ~IntervalMap() {
+    clear();
+    rootLeaf().~RootLeaf();
+  }
+
+  /// empty -  Return true when no intervals are mapped.
+  bool empty() const {
+    return rootSize == 0;
+  }
+
+  /// start - Return the smallest mapped key in a non-empty map.
+  KeyT start() const {
+    assert(!empty() && "Empty IntervalMap has no start");
+    return !branched() ? rootLeaf().start(0) : rootBranchStart();
+  }
+
+  /// stop - Return the largest mapped key in a non-empty map.
+  KeyT stop() const {
+    assert(!empty() && "Empty IntervalMap has no stop");
+    return !branched() ? rootLeaf().stop(rootSize - 1) :
+                         rootBranch().stop(rootSize - 1);
+  }
+
+  /// lookup - Return the mapped value at x or NotFound.
+  ValT lookup(KeyT x, ValT NotFound = ValT()) const {
+    if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
+      return NotFound;
+    return branched() ? treeSafeLookup(x, NotFound) :
+                        rootLeaf().safeLookup(x, NotFound);
+  }
+
+  /// insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
+  /// It is assumed that no key in the interval is mapped to another value, but
+  /// overlapping intervals already mapped to y will be coalesced.
+  void insert(KeyT a, KeyT b, ValT y) {
+    if (branched() || rootSize == RootLeaf::Capacity)
+      return find(a).insert(a, b, y);
+
+    // Easy insert into root leaf.
+    unsigned p = rootLeaf().findFrom(0, rootSize, a);
+    rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
+  }
+
+  /// clear - Remove all entries.
+  void clear();
+
+  class const_iterator;
+  class iterator;
+  friend class const_iterator;
+  friend class iterator;
+
+  const_iterator begin() const {
+    const_iterator I(*this);
+    I.goToBegin();
+    return I;
+  }
+
+  iterator begin() {
+    iterator I(*this);
+    I.goToBegin();
+    return I;
+  }
+
+  const_iterator end() const {
+    const_iterator I(*this);
+    I.goToEnd();
+    return I;
+  }
+
+  iterator end() {
+    iterator I(*this);
+    I.goToEnd();
+    return I;
+  }
+
+  /// find - Return an iterator pointing to the first interval ending at or
+  /// after x, or end().
+  const_iterator find(KeyT x) const {
+    const_iterator I(*this);
+    I.find(x);
+    return I;
+  }
+
+  iterator find(KeyT x) {
+    iterator I(*this);
+    I.find(x);
+    return I;
+  }
+};
+
+/// treeSafeLookup - Return the mapped value at x or NotFound, assuming a
+/// branched root.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+ValT IntervalMap<KeyT, ValT, N, Traits>::
+treeSafeLookup(KeyT x, ValT NotFound) const {
+  assert(branched() && "treeLookup assumes a branched root");
+
+  IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
+  for (unsigned h = height-1; h; --h)
+    NR = NR.get<Branch>().safeLookup(x);
+  return NR.get<Leaf>().safeLookup(x, NotFound);
+}
+
+
+// branchRoot - Switch from a leaf root to a branched root.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+branchRoot(unsigned Position) {
+  using namespace IntervalMapImpl;
+  // How many external leaf nodes to hold RootLeaf+1?
+  const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
+
+  // Compute element distribution among new nodes.
+  unsigned size[Nodes];
+  IdxPair NewOffset(0, Position);
+
+  // Is is very common for the root node to be smaller than external nodes.
+  if (Nodes == 1)
+    size[0] = rootSize;
+  else
+    NewOffset = distribute(Nodes, rootSize, Leaf::Capacity,  nullptr, size,
+                           Position, true);
+
+  // Allocate new nodes.
+  unsigned pos = 0;
+  NodeRef node[Nodes];
+  for (unsigned n = 0; n != Nodes; ++n) {
+    Leaf *L = newNode<Leaf>();
+    L->copy(rootLeaf(), pos, 0, size[n]);
+    node[n] = NodeRef(L, size[n]);
+    pos += size[n];
+  }
+
+  // Destroy the old leaf node, construct branch node instead.
+  switchRootToBranch();
+  for (unsigned n = 0; n != Nodes; ++n) {
+    rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
+    rootBranch().subtree(n) = node[n];
+  }
+  rootBranchStart() = node[0].template get<Leaf>().start(0);
+  rootSize = Nodes;
+  return NewOffset;
+}
+
+// splitRoot - Split the current BranchRoot into multiple Branch nodes.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+splitRoot(unsigned Position) {
+  using namespace IntervalMapImpl;
+  // How many external leaf nodes to hold RootBranch+1?
+  const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
+
+  // Compute element distribution among new nodes.
+  unsigned Size[Nodes];
+  IdxPair NewOffset(0, Position);
+
+  // Is is very common for the root node to be smaller than external nodes.
+  if (Nodes == 1)
+    Size[0] = rootSize;
+  else
+    NewOffset = distribute(Nodes, rootSize, Leaf::Capacity,  nullptr, Size,
+                           Position, true);
+
+  // Allocate new nodes.
+  unsigned Pos = 0;
+  NodeRef Node[Nodes];
+  for (unsigned n = 0; n != Nodes; ++n) {
+    Branch *B = newNode<Branch>();
+    B->copy(rootBranch(), Pos, 0, Size[n]);
+    Node[n] = NodeRef(B, Size[n]);
+    Pos += Size[n];
+  }
+
+  for (unsigned n = 0; n != Nodes; ++n) {
+    rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
+    rootBranch().subtree(n) = Node[n];
+  }
+  rootSize = Nodes;
+  ++height;
+  return NewOffset;
+}
+
+/// visitNodes - Visit each external node.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef, unsigned Height)) {
+  if (!branched())
+    return;
+  SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
+
+  // Collect level 0 nodes from the root.
+  for (unsigned i = 0; i != rootSize; ++i)
+    Refs.push_back(rootBranch().subtree(i));
+
+  // Visit all branch nodes.
+  for (unsigned h = height - 1; h; --h) {
+    for (unsigned i = 0, e = Refs.size(); i != e; ++i) {
+      for (unsigned j = 0, s = Refs[i].size(); j != s; ++j)
+        NextRefs.push_back(Refs[i].subtree(j));
+      (this->*f)(Refs[i], h);
+    }
+    Refs.clear();
+    Refs.swap(NextRefs);
+  }
+
+  // Visit all leaf nodes.
+  for (unsigned i = 0, e = Refs.size(); i != e; ++i)
+    (this->*f)(Refs[i], 0);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level) {
+  if (Level)
+    deleteNode(&Node.get<Branch>());
+  else
+    deleteNode(&Node.get<Leaf>());
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+clear() {
+  if (branched()) {
+    visitNodes(&IntervalMap::deleteNode);
+    switchRootToLeaf();
+  }
+  rootSize = 0;
+}
+
+//===----------------------------------------------------------------------===//
+//---                   IntervalMap::const_iterator                       ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
+  public std::iterator<std::bidirectional_iterator_tag, ValT> {
+protected:
+  friend class IntervalMap;
+
+  // The map referred to.
+  IntervalMap *map;
+
+  // We store a full path from the root to the current position.
+  // The path may be partially filled, but never between iterator calls.
+  IntervalMapImpl::Path path;
+
+  explicit const_iterator(const IntervalMap &map) :
+    map(const_cast<IntervalMap*>(&map)) {}
+
+  bool branched() const {
+    assert(map && "Invalid iterator");
+    return map->branched();
+  }
+
+  void setRoot(unsigned Offset) {
+    if (branched())
+      path.setRoot(&map->rootBranch(), map->rootSize, Offset);
+    else
+      path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
+  }
+
+  void pathFillFind(KeyT x);
+  void treeFind(KeyT x);
+  void treeAdvanceTo(KeyT x);
+
+  /// unsafeStart - Writable access to start() for iterator.
+  KeyT &unsafeStart() const {
+    assert(valid() && "Cannot access invalid iterator");
+    return branched() ? path.leaf<Leaf>().start(path.leafOffset()) :
+                        path.leaf<RootLeaf>().start(path.leafOffset());
+  }
+
+  /// unsafeStop - Writable access to stop() for iterator.
+  KeyT &unsafeStop() const {
+    assert(valid() && "Cannot access invalid iterator");
+    return branched() ? path.leaf<Leaf>().stop(path.leafOffset()) :
+                        path.leaf<RootLeaf>().stop(path.leafOffset());
+  }
+
+  /// unsafeValue - Writable access to value() for iterator.
+  ValT &unsafeValue() const {
+    assert(valid() && "Cannot access invalid iterator");
+    return branched() ? path.leaf<Leaf>().value(path.leafOffset()) :
+                        path.leaf<RootLeaf>().value(path.leafOffset());
+  }
+
+public:
+  /// const_iterator - Create an iterator that isn't pointing anywhere.
+  const_iterator() : map(nullptr) {}
+
+  /// setMap - Change the map iterated over. This call must be followed by a
+  /// call to goToBegin(), goToEnd(), or find()
+  void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); }
+
+  /// valid - Return true if the current position is valid, false for end().
+  bool valid() const { return path.valid(); }
+
+  /// atBegin - Return true if the current position is the first map entry.
+  bool atBegin() const { return path.atBegin(); }
+
+  /// start - Return the beginning of the current interval.
+  const KeyT &start() const { return unsafeStart(); }
+
+  /// stop - Return the end of the current interval.
+  const KeyT &stop() const { return unsafeStop(); }
+
+  /// value - Return the mapped value at the current interval.
+  const ValT &value() const { return unsafeValue(); }
+
+  const ValT &operator*() const { return value(); }
+
+  bool operator==(const const_iterator &RHS) const {
+    assert(map == RHS.map && "Cannot compare iterators from different maps");
+    if (!valid())
+      return !RHS.valid();
+    if (path.leafOffset() != RHS.path.leafOffset())
+      return false;
+    return &path.template leaf<Leaf>() == &RHS.path.template leaf<Leaf>();
+  }
+
+  bool operator!=(const const_iterator &RHS) const {
+    return !operator==(RHS);
+  }
+
+  /// goToBegin - Move to the first interval in map.
+  void goToBegin() {
+    setRoot(0);
+    if (branched())
+      path.fillLeft(map->height);
+  }
+
+  /// goToEnd - Move beyond the last interval in map.
+  void goToEnd() {
+    setRoot(map->rootSize);
+  }
+
+  /// preincrement - move to the next interval.
+  const_iterator &operator++() {
+    assert(valid() && "Cannot increment end()");
+    if (++path.leafOffset() == path.leafSize() && branched())
+      path.moveRight(map->height);
+    return *this;
+  }
+
+  /// postincrement - Dont do that!
+  const_iterator operator++(int) {
+    const_iterator tmp = *this;
+    operator++();
+    return tmp;
+  }
+
+  /// predecrement - move to the previous interval.
+  const_iterator &operator--() {
+    if (path.leafOffset() && (valid() || !branched()))
+      --path.leafOffset();
+    else
+      path.moveLeft(map->height);
+    return *this;
+  }
+
+  /// postdecrement - Dont do that!
+  const_iterator operator--(int) {
+    const_iterator tmp = *this;
+    operator--();
+    return tmp;
+  }
+
+  /// find - Move to the first interval with stop >= x, or end().
+  /// This is a full search from the root, the current position is ignored.
+  void find(KeyT x) {
+    if (branched())
+      treeFind(x);
+    else
+      setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
+  }
+
+  /// advanceTo - Move to the first interval with stop >= x, or end().
+  /// The search is started from the current position, and no earlier positions
+  /// can be found. This is much faster than find() for small moves.
+  void advanceTo(KeyT x) {
+    if (!valid())
+      return;
+    if (branched())
+      treeAdvanceTo(x);
+    else
+      path.leafOffset() =
+        map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
+  }
+
+};
+
+/// pathFillFind - Complete path by searching for x.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::pathFillFind(KeyT x) {
+  IntervalMapImpl::NodeRef NR = path.subtree(path.height());
+  for (unsigned i = map->height - path.height() - 1; i; --i) {
+    unsigned p = NR.get<Branch>().safeFind(0, x);
+    path.push(NR, p);
+    NR = NR.subtree(p);
+  }
+  path.push(NR, NR.get<Leaf>().safeFind(0, x));
+}
+
+/// treeFind - Find in a branched tree.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeFind(KeyT x) {
+  setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
+  if (valid())
+    pathFillFind(x);
+}
+
+/// treeAdvanceTo - Find position after the current one.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeAdvanceTo(KeyT x) {
+  // Can we stay on the same leaf node?
+  if (!Traits::stopLess(path.leaf<Leaf>().stop(path.leafSize() - 1), x)) {
+    path.leafOffset() = path.leaf<Leaf>().safeFind(path.leafOffset(), x);
+    return;
+  }
+
+  // Drop the current leaf.
+  path.pop();
+
+  // Search towards the root for a usable subtree.
+  if (path.height()) {
+    for (unsigned l = path.height() - 1; l; --l) {
+      if (!Traits::stopLess(path.node<Branch>(l).stop(path.offset(l)), x)) {
+        // The branch node at l+1 is usable
+        path.offset(l + 1) =
+          path.node<Branch>(l + 1).safeFind(path.offset(l + 1), x);
+        return pathFillFind(x);
+      }
+      path.pop();
+    }
+    // Is the level-1 Branch usable?
+    if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
+      path.offset(1) = path.node<Branch>(1).safeFind(path.offset(1), x);
+      return pathFillFind(x);
+    }
+  }
+
+  // We reached the root.
+  setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
+  if (valid())
+    pathFillFind(x);
+}
+
+//===----------------------------------------------------------------------===//
+//---                       IntervalMap::iterator                         ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
+  friend class IntervalMap;
+  typedef IntervalMapImpl::IdxPair IdxPair;
+
+  explicit iterator(IntervalMap &map) : const_iterator(map) {}
+
+  void setNodeStop(unsigned Level, KeyT Stop);
+  bool insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop);
+  template <typename NodeT> bool overflow(unsigned Level);
+  void treeInsert(KeyT a, KeyT b, ValT y);
+  void eraseNode(unsigned Level);
+  void treeErase(bool UpdateRoot = true);
+  bool canCoalesceLeft(KeyT Start, ValT x);
+  bool canCoalesceRight(KeyT Stop, ValT x);
+
+public:
+  /// iterator - Create null iterator.
+  iterator() {}
+
+  /// setStart - Move the start of the current interval.
+  /// This may cause coalescing with the previous interval.
+  /// @param a New start key, must not overlap the previous interval.
+  void setStart(KeyT a);
+
+  /// setStop - Move the end of the current interval.
+  /// This may cause coalescing with the following interval.
+  /// @param b New stop key, must not overlap the following interval.
+  void setStop(KeyT b);
+
+  /// setValue - Change the mapped value of the current interval.
+  /// This may cause coalescing with the previous and following intervals.
+  /// @param x New value.
+  void setValue(ValT x);
+
+  /// setStartUnchecked - Move the start of the current interval without
+  /// checking for coalescing or overlaps.
+  /// This should only be used when it is known that coalescing is not required.
+  /// @param a New start key.
+  void setStartUnchecked(KeyT a) { this->unsafeStart() = a; }
+
+  /// setStopUnchecked - Move the end of the current interval without checking
+  /// for coalescing or overlaps.
+  /// This should only be used when it is known that coalescing is not required.
+  /// @param b New stop key.
+  void setStopUnchecked(KeyT b) {
+    this->unsafeStop() = b;
+    // Update keys in branch nodes as well.
+    if (this->path.atLastEntry(this->path.height()))
+      setNodeStop(this->path.height(), b);
+  }
+
+  /// setValueUnchecked - Change the mapped value of the current interval
+  /// without checking for coalescing.
+  /// @param x New value.
+  void setValueUnchecked(ValT x) { this->unsafeValue() = x; }
+
+  /// insert - Insert mapping [a;b] -> y before the current position.
+  void insert(KeyT a, KeyT b, ValT y);
+
+  /// erase - Erase the current interval.
+  void erase();
+
+  iterator &operator++() {
+    const_iterator::operator++();
+    return *this;
+  }
+
+  iterator operator++(int) {
+    iterator tmp = *this;
+    operator++();
+    return tmp;
+  }
+
+  iterator &operator--() {
+    const_iterator::operator--();
+    return *this;
+  }
+
+  iterator operator--(int) {
+    iterator tmp = *this;
+    operator--();
+    return tmp;
+  }
+
+};
+
+/// canCoalesceLeft - Can the current interval coalesce to the left after
+/// changing start or value?
+/// @param Start New start of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceLeft(KeyT Start, ValT Value) {
+  using namespace IntervalMapImpl;
+  Path &P = this->path;
+  if (!this->branched()) {
+    unsigned i = P.leafOffset();
+    RootLeaf &Node = P.leaf<RootLeaf>();
+    return i && Node.value(i-1) == Value &&
+                Traits::adjacent(Node.stop(i-1), Start);
+  }
+  // Branched.
+  if (unsigned i = P.leafOffset()) {
+    Leaf &Node = P.leaf<Leaf>();
+    return Node.value(i-1) == Value && Traits::adjacent(Node.stop(i-1), Start);
+  } else if (NodeRef NR = P.getLeftSibling(P.height())) {
+    unsigned i = NR.size() - 1;
+    Leaf &Node = NR.get<Leaf>();
+    return Node.value(i) == Value && Traits::adjacent(Node.stop(i), Start);
+  }
+  return false;
+}
+
+/// canCoalesceRight - Can the current interval coalesce to the right after
+/// changing stop or value?
+/// @param Stop New stop of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceRight(KeyT Stop, ValT Value) {
+  using namespace IntervalMapImpl;
+  Path &P = this->path;
+  unsigned i = P.leafOffset() + 1;
+  if (!this->branched()) {
+    if (i >= P.leafSize())
+      return false;
+    RootLeaf &Node = P.leaf<RootLeaf>();
+    return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+  }
+  // Branched.
+  if (i < P.leafSize()) {
+    Leaf &Node = P.leaf<Leaf>();
+    return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+  } else if (NodeRef NR = P.getRightSibling(P.height())) {
+    Leaf &Node = NR.get<Leaf>();
+    return Node.value(0) == Value && Traits::adjacent(Stop, Node.start(0));
+  }
+  return false;
+}
+
+/// setNodeStop - Update the stop key of the current node at level and above.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setNodeStop(unsigned Level, KeyT Stop) {
+  // There are no references to the root node, so nothing to update.
+  if (!Level)
+    return;
+  IntervalMapImpl::Path &P = this->path;
+  // Update nodes pointing to the current node.
+  while (--Level) {
+    P.node<Branch>(Level).stop(P.offset(Level)) = Stop;
+    if (!P.atLastEntry(Level))
+      return;
+  }
+  // Update root separately since it has a different layout.
+  P.node<RootBranch>(Level).stop(P.offset(Level)) = Stop;
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStart(KeyT a) {
+  assert(Traits::stopLess(a, this->stop()) && "Cannot move start beyond stop");
+  KeyT &CurStart = this->unsafeStart();
+  if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
+    CurStart = a;
+    return;
+  }
+  // Coalesce with the interval to the left.
+  --*this;
+  a = this->start();
+  erase();
+  setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStop(KeyT b) {
+  assert(Traits::stopLess(this->start(), b) && "Cannot move stop beyond start");
+  if (Traits::startLess(b, this->stop()) ||
+      !canCoalesceRight(b, this->value())) {
+    setStopUnchecked(b);
+    return;
+  }
+  // Coalesce with interval to the right.
+  KeyT a = this->start();
+  erase();
+  setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setValue(ValT x) {
+  setValueUnchecked(x);
+  if (canCoalesceRight(this->stop(), x)) {
+    KeyT a = this->start();
+    erase();
+    setStartUnchecked(a);
+  }
+  if (canCoalesceLeft(this->start(), x)) {
+    --*this;
+    KeyT a = this->start();
+    erase();
+    setStartUnchecked(a);
+  }
+}
+
+/// insertNode - insert a node before the current path at level.
+/// Leave the current path pointing at the new node.
+/// @param Level path index of the node to be inserted.
+/// @param Node The node to be inserted.
+/// @param Stop The last index in the new node.
+/// @return True if the tree height was increased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop) {
+  assert(Level && "Cannot insert next to the root");
+  bool SplitRoot = false;
+  IntervalMap &IM = *this->map;
+  IntervalMapImpl::Path &P = this->path;
+
+  if (Level == 1) {
+    // Insert into the root branch node.
+    if (IM.rootSize < RootBranch::Capacity) {
+      IM.rootBranch().insert(P.offset(0), IM.rootSize, Node, Stop);
+      P.setSize(0, ++IM.rootSize);
+      P.reset(Level);
+      return SplitRoot;
+    }
+
+    // We need to split the root while keeping our position.
+    SplitRoot = true;
+    IdxPair Offset = IM.splitRoot(P.offset(0));
+    P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+    // Fall through to insert at the new higher level.
+    ++Level;
+  }
+
+  // When inserting before end(), make sure we have a valid path.
+  P.legalizeForInsert(--Level);
+
+  // Insert into the branch node at Level-1.
+  if (P.size(Level) == Branch::Capacity) {
+    // Branch node is full, handle handle the overflow.
+    assert(!SplitRoot && "Cannot overflow after splitting the root");
+    SplitRoot = overflow<Branch>(Level);
+    Level += SplitRoot;
+  }
+  P.node<Branch>(Level).insert(P.offset(Level), P.size(Level), Node, Stop);
+  P.setSize(Level, P.size(Level) + 1);
+  if (P.atLastEntry(Level))
+    setNodeStop(Level, Stop);
+  P.reset(Level + 1);
+  return SplitRoot;
+}
+
+// insert
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insert(KeyT a, KeyT b, ValT y) {
+  if (this->branched())
+    return treeInsert(a, b, y);
+  IntervalMap &IM = *this->map;
+  IntervalMapImpl::Path &P = this->path;
+
+  // Try simple root leaf insert.
+  unsigned Size = IM.rootLeaf().insertFrom(P.leafOffset(), IM.rootSize, a, b, y);
+
+  // Was the root node insert successful?
+  if (Size <= RootLeaf::Capacity) {
+    P.setSize(0, IM.rootSize = Size);
+    return;
+  }
+
+  // Root leaf node is full, we must branch.
+  IdxPair Offset = IM.branchRoot(P.leafOffset());
+  P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+  // Now it fits in the new leaf.
+  treeInsert(a, b, y);
+}
+
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeInsert(KeyT a, KeyT b, ValT y) {
+  using namespace IntervalMapImpl;
+  Path &P = this->path;
+
+  if (!P.valid())
+    P.legalizeForInsert(this->map->height);
+
+  // Check if this insertion will extend the node to the left.
+  if (P.leafOffset() == 0 && Traits::startLess(a, P.leaf<Leaf>().start(0))) {
+    // Node is growing to the left, will it affect a left sibling node?
+    if (NodeRef Sib = P.getLeftSibling(P.height())) {
+      Leaf &SibLeaf = Sib.get<Leaf>();
+      unsigned SibOfs = Sib.size() - 1;
+      if (SibLeaf.value(SibOfs) == y &&
+          Traits::adjacent(SibLeaf.stop(SibOfs), a)) {
+        // This insertion will coalesce with the last entry in SibLeaf. We can
+        // handle it in two ways:
+        //  1. Extend SibLeaf.stop to b and be done, or
+        //  2. Extend a to SibLeaf, erase the SibLeaf entry and continue.
+        // We prefer 1., but need 2 when coalescing to the right as well.
+        Leaf &CurLeaf = P.leaf<Leaf>();
+        P.moveLeft(P.height());
+        if (Traits::stopLess(b, CurLeaf.start(0)) &&
+            (y != CurLeaf.value(0) || !Traits::adjacent(b, CurLeaf.start(0)))) {
+          // Easy, just extend SibLeaf and we're done.
+          setNodeStop(P.height(), SibLeaf.stop(SibOfs) = b);
+          return;
+        } else {
+          // We have both left and right coalescing. Erase the old SibLeaf entry
+          // and continue inserting the larger interval.
+          a = SibLeaf.start(SibOfs);
+          treeErase(/* UpdateRoot= */false);
+        }
+      }
+    } else {
+      // No left sibling means we are at begin(). Update cached bound.
+      this->map->rootBranchStart() = a;
+    }
+  }
+
+  // When we are inserting at the end of a leaf node, we must update stops.
+  unsigned Size = P.leafSize();
+  bool Grow = P.leafOffset() == Size;
+  Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), Size, a, b, y);
+
+  // Leaf insertion unsuccessful? Overflow and try again.
+  if (Size > Leaf::Capacity) {
+    overflow<Leaf>(P.height());
+    Grow = P.leafOffset() == P.leafSize();
+    Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), P.leafSize(), a, b, y);
+    assert(Size <= Leaf::Capacity && "overflow() didn't make room");
+  }
+
+  // Inserted, update offset and leaf size.
+  P.setSize(P.height(), Size);
+
+  // Insert was the last node entry, update stops.
+  if (Grow)
+    setNodeStop(P.height(), b);
+}
+
+/// erase - erase the current interval and move to the next position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::erase() {
+  IntervalMap &IM = *this->map;
+  IntervalMapImpl::Path &P = this->path;
+  assert(P.valid() && "Cannot erase end()");
+  if (this->branched())
+    return treeErase();
+  IM.rootLeaf().erase(P.leafOffset(), IM.rootSize);
+  P.setSize(0, --IM.rootSize);
+}
+
+/// treeErase - erase() for a branched tree.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeErase(bool UpdateRoot) {
+  IntervalMap &IM = *this->map;
+  IntervalMapImpl::Path &P = this->path;
+  Leaf &Node = P.leaf<Leaf>();
+
+  // Nodes are not allowed to become empty.
+  if (P.leafSize() == 1) {
+    IM.deleteNode(&Node);
+    eraseNode(IM.height);
+    // Update rootBranchStart if we erased begin().
+    if (UpdateRoot && IM.branched() && P.valid() && P.atBegin())
+      IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+    return;
+  }
+
+  // Erase current entry.
+  Node.erase(P.leafOffset(), P.leafSize());
+  unsigned NewSize = P.leafSize() - 1;
+  P.setSize(IM.height, NewSize);
+  // When we erase the last entry, update stop and move to a legal position.
+  if (P.leafOffset() == NewSize) {
+    setNodeStop(IM.height, Node.stop(NewSize - 1));
+    P.moveRight(IM.height);
+  } else if (UpdateRoot && P.atBegin())
+    IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+}
+
+/// eraseNode - Erase the current node at Level from its parent and move path to
+/// the first entry of the next sibling node.
+/// The node must be deallocated by the caller.
+/// @param Level 1..height, the root node cannot be erased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::eraseNode(unsigned Level) {
+  assert(Level && "Cannot erase root node");
+  IntervalMap &IM = *this->map;
+  IntervalMapImpl::Path &P = this->path;
+
+  if (--Level == 0) {
+    IM.rootBranch().erase(P.offset(0), IM.rootSize);
+    P.setSize(0, --IM.rootSize);
+    // If this cleared the root, switch to height=0.
+    if (IM.empty()) {
+      IM.switchRootToLeaf();
+      this->setRoot(0);
+      return;
+    }
+  } else {
+    // Remove node ref from branch node at Level.
+    Branch &Parent = P.node<Branch>(Level);
+    if (P.size(Level) == 1) {
+      // Branch node became empty, remove it recursively.
+      IM.deleteNode(&Parent);
+      eraseNode(Level);
+    } else {
+      // Branch node won't become empty.
+      Parent.erase(P.offset(Level), P.size(Level));
+      unsigned NewSize = P.size(Level) - 1;
+      P.setSize(Level, NewSize);
+      // If we removed the last branch, update stop and move to a legal pos.
+      if (P.offset(Level) == NewSize) {
+        setNodeStop(Level, Parent.stop(NewSize - 1));
+        P.moveRight(Level);
+      }
+    }
+  }
+  // Update path cache for the new right sibling position.
+  if (P.valid()) {
+    P.reset(Level + 1);
+    P.offset(Level + 1) = 0;
+  }
+}
+
+/// overflow - Distribute entries of the current node evenly among
+/// its siblings and ensure that the current node is not full.
+/// This may require allocating a new node.
+/// @tparam NodeT The type of node at Level (Leaf or Branch).
+/// @param Level path index of the overflowing node.
+/// @return True when the tree height was changed.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+template <typename NodeT>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::overflow(unsigned Level) {
+  using namespace IntervalMapImpl;
+  Path &P = this->path;
+  unsigned CurSize[4];
+  NodeT *Node[4];
+  unsigned Nodes = 0;
+  unsigned Elements = 0;
+  unsigned Offset = P.offset(Level);
+
+  // Do we have a left sibling?
+  NodeRef LeftSib = P.getLeftSibling(Level);
+  if (LeftSib) {
+    Offset += Elements = CurSize[Nodes] = LeftSib.size();
+    Node[Nodes++] = &LeftSib.get<NodeT>();
+  }
+
+  // Current node.
+  Elements += CurSize[Nodes] = P.size(Level);
+  Node[Nodes++] = &P.node<NodeT>(Level);
+
+  // Do we have a right sibling?
+  NodeRef RightSib = P.getRightSibling(Level);
+  if (RightSib) {
+    Elements += CurSize[Nodes] = RightSib.size();
+    Node[Nodes++] = &RightSib.get<NodeT>();
+  }
+
+  // Do we need to allocate a new node?
+  unsigned NewNode = 0;
+  if (Elements + 1 > Nodes * NodeT::Capacity) {
+    // Insert NewNode at the penultimate position, or after a single node.
+    NewNode = Nodes == 1 ? 1 : Nodes - 1;
+    CurSize[Nodes] = CurSize[NewNode];
+    Node[Nodes] = Node[NewNode];
+    CurSize[NewNode] = 0;
+    Node[NewNode] = this->map->template newNode<NodeT>();
+    ++Nodes;
+  }
+
+  // Compute the new element distribution.
+  unsigned NewSize[4];
+  IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity,
+                                 CurSize, NewSize, Offset, true);
+  adjustSiblingSizes(Node, Nodes, CurSize, NewSize);
+
+  // Move current location to the leftmost node.
+  if (LeftSib)
+    P.moveLeft(Level);
+
+  // Elements have been rearranged, now update node sizes and stops.
+  bool SplitRoot = false;
+  unsigned Pos = 0;
+  for (;;) {
+    KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
+    if (NewNode && Pos == NewNode) {
+      SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
+      Level += SplitRoot;
+    } else {
+      P.setSize(Level, NewSize[Pos]);
+      setNodeStop(Level, Stop);
+    }
+    if (Pos + 1 == Nodes)
+      break;
+    P.moveRight(Level);
+    ++Pos;
+  }
+
+  // Where was I? Find NewOffset.
+  while(Pos != NewOffset.first) {
+    P.moveLeft(Level);
+    --Pos;
+  }
+  P.offset(Level) = NewOffset.second;
+  return SplitRoot;
+}
+
+//===----------------------------------------------------------------------===//
+//---                       IntervalMapOverlaps                           ----//
+//===----------------------------------------------------------------------===//
+
+/// IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two
+/// IntervalMaps. The maps may be different, but the KeyT and Traits types
+/// should be the same.
+///
+/// Typical uses:
+///
+/// 1. Test for overlap:
+///    bool overlap = IntervalMapOverlaps(a, b).valid();
+///
+/// 2. Enumerate overlaps:
+///    for (IntervalMapOverlaps I(a, b); I.valid() ; ++I) { ... }
+///
+template <typename MapA, typename MapB>
+class IntervalMapOverlaps {
+  typedef typename MapA::KeyType KeyType;
+  typedef typename MapA::KeyTraits Traits;
+  typename MapA::const_iterator posA;
+  typename MapB::const_iterator posB;
+
+  /// advance - Move posA and posB forward until reaching an overlap, or until
+  /// either meets end.
+  /// Don't move the iterators if they are already overlapping.
+  void advance() {
+    if (!valid())
+      return;
+
+    if (Traits::stopLess(posA.stop(), posB.start())) {
+      // A ends before B begins. Catch up.
+      posA.advanceTo(posB.start());
+      if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+        return;
+    } else if (Traits::stopLess(posB.stop(), posA.start())) {
+      // B ends before A begins. Catch up.
+      posB.advanceTo(posA.start());
+      if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+        return;
+    } else
+      // Already overlapping.
+      return;
+
+    for (;;) {
+      // Make a.end > b.start.
+      posA.advanceTo(posB.start());
+      if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+        return;
+      // Make b.end > a.start.
+      posB.advanceTo(posA.start());
+      if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+        return;
+    }
+  }
+
+public:
+  /// IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
+  IntervalMapOverlaps(const MapA &a, const MapB &b)
+    : posA(b.empty() ? a.end() : a.find(b.start())),
+      posB(posA.valid() ? b.find(posA.start()) : b.end()) { advance(); }
+
+  /// valid - Return true if iterator is at an overlap.
+  bool valid() const {
+    return posA.valid() && posB.valid();
+  }
+
+  /// a - access the left hand side in the overlap.
+  const typename MapA::const_iterator &a() const { return posA; }
+
+  /// b - access the right hand side in the overlap.
+  const typename MapB::const_iterator &b() const { return posB; }
+
+  /// start - Beginning of the overlapping interval.
+  KeyType start() const {
+    KeyType ak = a().start();
+    KeyType bk = b().start();
+    return Traits::startLess(ak, bk) ? bk : ak;
+  }
+
+  /// stop - End of the overlapping interval.
+  KeyType stop() const {
+    KeyType ak = a().stop();
+    KeyType bk = b().stop();
+    return Traits::startLess(ak, bk) ? ak : bk;
+  }
+
+  /// skipA - Move to the next overlap that doesn't involve a().
+  void skipA() {
+    ++posA;
+    advance();
+  }
+
+  /// skipB - Move to the next overlap that doesn't involve b().
+  void skipB() {
+    ++posB;
+    advance();
+  }
+
+  /// Preincrement - Move to the next overlap.
+  IntervalMapOverlaps &operator++() {
+    // Bump the iterator that ends first. The other one may have more overlaps.
+    if (Traits::startLess(posB.stop(), posA.stop()))
+      skipB();
+    else
+      skipA();
+    return *this;
+  }
+
+  /// advanceTo - Move to the first overlapping interval with
+  /// stopLess(x, stop()).
+  void advanceTo(KeyType x) {
+    if (!valid())
+      return;
+    // Make sure advanceTo sees monotonic keys.
+    if (Traits::stopLess(posA.stop(), x))
+      posA.advanceTo(x);
+    if (Traits::stopLess(posB.stop(), x))
+      posB.advanceTo(x);
+    advance();
+  }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
new file mode 100644
index 0000000..f9df378
--- /dev/null
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -0,0 +1,284 @@
+//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- 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 IntrusiveRefCntPtr, a template class that
+// implements a "smart" pointer for objects that maintain their own
+// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two
+// generic base classes for objects that wish to have their lifetimes
+// managed using reference counting.
+//
+// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added
+// LLVM-style casting.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
+#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include <atomic>
+#include <memory>
+
+namespace llvm {
+
+  template <class T>
+  class IntrusiveRefCntPtr;
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBase - A generic base class for objects that wish to
+///  have their lifetimes managed using reference counts. Classes
+///  subclass RefCountedBase to obtain such functionality, and are
+///  typically handled with IntrusiveRefCntPtr "smart pointers" (see below)
+///  which automatically handle the management of reference counts.
+///  Objects that subclass RefCountedBase should not be allocated on
+///  the stack, as invoking "delete" (which is called when the
+///  reference count hits 0) on such objects is an error.
+//===----------------------------------------------------------------------===//
+  template <class Derived>
+  class RefCountedBase {
+    mutable unsigned ref_cnt;
+
+  public:
+    RefCountedBase() : ref_cnt(0) {}
+    RefCountedBase(const RefCountedBase &) : ref_cnt(0) {}
+
+    void Retain() const { ++ref_cnt; }
+    void Release() const {
+      assert (ref_cnt > 0 && "Reference count is already zero.");
+      if (--ref_cnt == 0) delete static_cast<const Derived*>(this);
+    }
+  };
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBaseVPTR - A class that has the same function as
+///  RefCountedBase, but with a virtual destructor. Should be used
+///  instead of RefCountedBase for classes that already have virtual
+///  methods to enforce dynamic allocation via 'new'. Classes that
+///  inherit from RefCountedBaseVPTR can't be allocated on stack -
+///  attempting to do this will produce a compile error.
+//===----------------------------------------------------------------------===//
+  class RefCountedBaseVPTR {
+    mutable unsigned ref_cnt;
+    virtual void anchor();
+
+  protected:
+    RefCountedBaseVPTR() : ref_cnt(0) {}
+    RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
+
+    virtual ~RefCountedBaseVPTR() {}
+
+    void Retain() const { ++ref_cnt; }
+    void Release() const {
+      assert (ref_cnt > 0 && "Reference count is already zero.");
+      if (--ref_cnt == 0) delete this;
+    }
+
+    template <typename T>
+    friend struct IntrusiveRefCntPtrInfo;
+  };
+
+  
+  template <typename T> struct IntrusiveRefCntPtrInfo {
+    static void retain(T *obj) { obj->Retain(); }
+    static void release(T *obj) { obj->Release(); }
+  };
+
+/// \brief A thread-safe version of \c llvm::RefCountedBase.
+///
+/// A generic base class for objects that wish to have their lifetimes managed
+/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to
+/// obtain such functionality, and are typically handled with
+/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the
+/// management of reference counts.
+template <class Derived>
+class ThreadSafeRefCountedBase {
+  mutable std::atomic<int> RefCount;
+
+protected:
+  ThreadSafeRefCountedBase() : RefCount(0) {}
+
+public:
+  void Retain() const { ++RefCount; }
+
+  void Release() const {
+    int NewRefCount = --RefCount;
+    assert(NewRefCount >= 0 && "Reference count was already zero.");
+    if (NewRefCount == 0)
+      delete static_cast<const Derived*>(this);
+  }
+};
+  
+//===----------------------------------------------------------------------===//
+/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
+///  that assumes the wrapped object has a reference count associated
+///  with it that can be managed via calls to
+///  IntrusivePtrAddRef/IntrusivePtrRelease.  The smart pointers
+///  manage reference counts via the RAII idiom: upon creation of
+///  smart pointer the reference count of the wrapped object is
+///  incremented and upon destruction of the smart pointer the
+///  reference count is decremented.  This class also safely handles
+///  wrapping NULL pointers.
+///
+/// Reference counting is implemented via calls to
+///  Obj->Retain()/Obj->Release(). Release() is required to destroy
+///  the object when the reference count reaches zero. Inheriting from
+///  RefCountedBase/RefCountedBaseVPTR takes care of this
+///  automatically.
+//===----------------------------------------------------------------------===//
+  template <typename T>
+  class IntrusiveRefCntPtr {
+    T* Obj;
+
+  public:
+    typedef T element_type;
+
+    explicit IntrusiveRefCntPtr() : Obj(nullptr) {}
+
+    IntrusiveRefCntPtr(T* obj) : Obj(obj) {
+      retain();
+    }
+
+    IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) {
+      retain();
+    }
+
+    IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
+      S.Obj = nullptr;
+    }
+
+    template <class X>
+    IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.get()) {
+      S.Obj = 0;
+    }
+
+    template <class X>
+    IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
+      : Obj(S.get()) {
+      retain();
+    }
+
+    IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr S) {
+      swap(S);
+      return *this;
+    }
+
+    ~IntrusiveRefCntPtr() { release(); }
+
+    T& operator*() const { return *Obj; }
+
+    T* operator->() const { return Obj; }
+
+    T* get() const { return Obj; }
+
+    LLVM_EXPLICIT operator bool() const { return Obj; }
+
+    void swap(IntrusiveRefCntPtr& other) {
+      T* tmp = other.Obj;
+      other.Obj = Obj;
+      Obj = tmp;
+    }
+
+    void reset() {
+      release();
+      Obj = nullptr;
+    }
+
+    void resetWithoutRelease() {
+      Obj = 0;
+    }
+
+  private:
+    void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
+    void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
+  };
+
+  template<class T, class U>
+  inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+                         const IntrusiveRefCntPtr<U>& B)
+  {
+    return A.get() == B.get();
+  }
+
+  template<class T, class U>
+  inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+                         const IntrusiveRefCntPtr<U>& B)
+  {
+    return A.get() != B.get();
+  }
+
+  template<class T, class U>
+  inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+                         U* B)
+  {
+    return A.get() == B;
+  }
+
+  template<class T, class U>
+  inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+                         U* B)
+  {
+    return A.get() != B;
+  }
+
+  template<class T, class U>
+  inline bool operator==(T* A,
+                         const IntrusiveRefCntPtr<U>& B)
+  {
+    return A == B.get();
+  }
+
+  template<class T, class U>
+  inline bool operator!=(T* A,
+                         const IntrusiveRefCntPtr<U>& B)
+  {
+    return A != B.get();
+  }
+
+  template <class T>
+  bool operator==(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
+    return !B;
+  }
+
+  template <class T>
+  bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
+    return B == A;
+  }
+
+  template <class T>
+  bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {
+    return !(A == B);
+  }
+
+  template <class T>
+  bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
+    return !(A == B);
+  }
+
+//===----------------------------------------------------------------------===//
+// LLVM-style downcasting support for IntrusiveRefCntPtr objects
+//===----------------------------------------------------------------------===//
+
+  template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
+    typedef T* SimpleType;
+    static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
+      return Val.get();
+    }
+  };
+
+  template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
+    typedef /*const*/ T* SimpleType;
+    static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+      return Val.get();
+    }
+  };
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
new file mode 100644
index 0000000..4e1fc15
--- /dev/null
+++ b/include/llvm/ADT/MapVector.h
@@ -0,0 +1,181 @@
+//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a map that provides insertion order iteration. The
+// interface is purposefully minimal. The key is assumed to be cheap to copy
+// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
+// a std::vector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_MAPVECTOR_H
+#define LLVM_ADT_MAPVECTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+
+namespace llvm {
+
+/// This class implements a map that also provides access to all stored values
+/// in a deterministic order. The values are kept in a std::vector and the
+/// mapping is done with DenseMap from Keys to indexes in that vector.
+template<typename KeyT, typename ValueT,
+         typename MapType = llvm::DenseMap<KeyT, unsigned>,
+         typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
+class MapVector {
+  typedef typename VectorType::size_type size_type;
+
+  MapType Map;
+  VectorType Vector;
+
+public:
+  typedef typename VectorType::iterator iterator;
+  typedef typename VectorType::const_iterator const_iterator;
+
+  size_type size() const {
+    return Vector.size();
+  }
+
+  iterator begin() {
+    return Vector.begin();
+  }
+
+  const_iterator begin() const {
+    return Vector.begin();
+  }
+
+  iterator end() {
+    return Vector.end();
+  }
+
+  const_iterator end() const {
+    return Vector.end();
+  }
+
+  bool empty() const {
+    return Vector.empty();
+  }
+
+  std::pair<KeyT, ValueT>       &front()       { return Vector.front(); }
+  const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
+  std::pair<KeyT, ValueT>       &back()        { return Vector.back(); }
+  const std::pair<KeyT, ValueT> &back()  const { return Vector.back(); }
+
+  void clear() {
+    Map.clear();
+    Vector.clear();
+  }
+
+  ValueT &operator[](const KeyT &Key) {
+    std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
+    std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+    unsigned &I = Result.first->second;
+    if (Result.second) {
+      Vector.push_back(std::make_pair(Key, ValueT()));
+      I = Vector.size() - 1;
+    }
+    return Vector[I].second;
+  }
+
+  ValueT lookup(const KeyT &Key) const {
+    typename MapType::const_iterator Pos = Map.find(Key);
+    return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
+  }
+
+  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+    std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+    std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+    unsigned &I = Result.first->second;
+    if (Result.second) {
+      Vector.push_back(std::make_pair(KV.first, KV.second));
+      I = Vector.size() - 1;
+      return std::make_pair(std::prev(end()), true);
+    }
+    return std::make_pair(begin() + I, false);
+  }
+
+  size_type count(const KeyT &Key) const {
+    typename MapType::const_iterator Pos = Map.find(Key);
+    return Pos == Map.end()? 0 : 1;
+  }
+
+  iterator find(const KeyT &Key) {
+    typename MapType::const_iterator Pos = Map.find(Key);
+    return Pos == Map.end()? Vector.end() :
+                            (Vector.begin() + Pos->second);
+  }
+
+  const_iterator find(const KeyT &Key) const {
+    typename MapType::const_iterator Pos = Map.find(Key);
+    return Pos == Map.end()? Vector.end() :
+                            (Vector.begin() + Pos->second);
+  }
+
+  /// \brief Remove the last element from the vector.
+  void pop_back() {
+    typename MapType::iterator Pos = Map.find(Vector.back().first);
+    Map.erase(Pos);
+    Vector.pop_back();
+  }
+
+  /// \brief Remove the element given by Iterator.
+  ///
+  /// Returns an iterator to the element following the one which was removed,
+  /// which may be end().
+  ///
+  /// \note This is a deceivingly expensive operation (linear time).  It's
+  /// usually better to use \a remove_if() if possible.
+  typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
+    Map.erase(Iterator->first);
+    auto Next = Vector.erase(Iterator);
+    if (Next == Vector.end())
+      return Next;
+
+    // Update indices in the map.
+    size_t Index = Next - Vector.begin();
+    for (auto &I : Map) {
+      assert(I.second != Index && "Index was already erased!");
+      if (I.second > Index)
+        --I.second;
+    }
+    return Next;
+  }
+
+  /// \brief Remove the elements that match the predicate.
+  ///
+  /// Erase all elements that match \c Pred in a single pass.  Takes linear
+  /// time.
+  template <class Predicate> void remove_if(Predicate Pred);
+};
+
+template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
+template <class Function>
+void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
+  auto O = Vector.begin();
+  for (auto I = O, E = Vector.end(); I != E; ++I) {
+    if (Pred(*I)) {
+      // Erase from the map.
+      Map.erase(I->first);
+      continue;
+    }
+
+    if (I != O) {
+      // Move the value and update the index in the map.
+      *O = std::move(*I);
+      Map[O->first] = O - Vector.begin();
+    }
+    ++O;
+  }
+  // Erase trailing entries in the vector.
+  Vector.erase(O, Vector.end());
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h
new file mode 100644
index 0000000..5793bd2
--- /dev/null
+++ b/include/llvm/ADT/None.h
@@ -0,0 +1,27 @@
+//===-- None.h - Simple null value for implicit construction ------*- 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 None, an enumerator for use in implicit constructors
+//  of various (usually templated) types to make such construction more
+//  terse.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_NONE_H
+#define LLVM_ADT_NONE_H
+
+namespace llvm {
+/// \brief A simple null object to allow implicit construction of Optional<T>
+/// and similar types without having to spell out the specialization's name.
+enum NoneType {
+  None
+};
+}
+
+#endif
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
new file mode 100644
index 0000000..ae8344d
--- /dev/null
+++ b/include/llvm/ADT/Optional.h
@@ -0,0 +1,188 @@
+//===-- Optional.h - Simple variant for passing optional values ---*- 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 Optional, a template class modeled in the spirit of
+//  OCaml's 'opt' variant.  The idea is to strongly type whether or not
+//  a value can be optional.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_OPTIONAL_H
+#define LLVM_ADT_OPTIONAL_H
+
+#include "llvm/ADT/None.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+
+template<typename T>
+class Optional {
+  AlignedCharArrayUnion<T> storage;
+  bool hasVal;
+public:
+  Optional(NoneType) : hasVal(false) {}
+  explicit Optional() : hasVal(false) {}
+  Optional(const T &y) : hasVal(true) {
+    new (storage.buffer) T(y);
+  }
+  Optional(const Optional &O) : hasVal(O.hasVal) {
+    if (hasVal)
+      new (storage.buffer) T(*O);
+  }
+
+  Optional(T &&y) : hasVal(true) {
+    new (storage.buffer) T(std::forward<T>(y));
+  }
+  Optional(Optional<T> &&O) : hasVal(O) {
+    if (O) {
+      new (storage.buffer) T(std::move(*O));
+      O.reset();
+    }
+  }
+  Optional &operator=(T &&y) {
+    if (hasVal)
+      **this = std::move(y);
+    else {
+      new (storage.buffer) T(std::move(y));
+      hasVal = true;
+    }
+    return *this;
+  }
+  Optional &operator=(Optional &&O) {
+    if (!O)
+      reset();
+    else {
+      *this = std::move(*O);
+      O.reset();
+    }
+    return *this;
+  }
+
+  static inline Optional create(const T* y) {
+    return y ? Optional(*y) : Optional();
+  }
+
+  // FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
+  // could be made more efficient by passing by value, possibly unifying them
+  // with the rvalue versions above - but this could place a different set of
+  // requirements (notably: the existence of a default ctor) when implemented
+  // in that way. Careful SFINAE to avoid such pitfalls would be required.
+  Optional &operator=(const T &y) {
+    if (hasVal)
+      **this = y;
+    else {
+      new (storage.buffer) T(y);
+      hasVal = true;
+    }
+    return *this;
+  }
+
+  Optional &operator=(const Optional &O) {
+    if (!O)
+      reset();
+    else
+      *this = *O;
+    return *this;
+  }
+
+  void reset() {
+    if (hasVal) {
+      (**this).~T();
+      hasVal = false;
+    }
+  }
+
+  ~Optional() {
+    reset();
+  }
+
+  const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
+  T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
+  const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+  T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+
+  LLVM_EXPLICIT operator bool() const { return hasVal; }
+  bool hasValue() const { return hasVal; }
+  const T* operator->() const { return getPointer(); }
+  T* operator->() { return getPointer(); }
+  const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+  T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
+  T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
+#endif
+};
+
+template <typename T> struct isPodLike;
+template <typename T> struct isPodLike<Optional<T> > {
+  // An Optional<T> is pod-like if T is.
+  static const bool value = isPodLike<T>::value;
+};
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator==(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator!=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>(const Optional<T> &X, const Optional<U> &Y);
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h
new file mode 100644
index 0000000..1ae2a77
--- /dev/null
+++ b/include/llvm/ADT/PackedVector.h
@@ -0,0 +1,159 @@
+//===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===//
+//
+//                     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 PackedVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_PACKEDVECTOR_H
+#define LLVM_ADT_PACKEDVECTOR_H
+
+#include "llvm/ADT/BitVector.h"
+#include <limits>
+
+namespace llvm {
+
+template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
+class PackedVectorBase;
+
+// This won't be necessary if we can specialize members without specializing
+// the parent template.
+template <typename T, unsigned BitNum, typename BitVectorTy>
+class PackedVectorBase<T, BitNum, BitVectorTy, false> {
+protected:
+  static T getValue(const BitVectorTy &Bits, unsigned Idx) {
+    T val = T();
+    for (unsigned i = 0; i != BitNum; ++i)
+      val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
+    return val;
+  }
+
+  static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
+    assert((val >> BitNum) == 0 && "value is too big");
+    for (unsigned i = 0; i != BitNum; ++i)
+      Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
+  }
+};
+
+template <typename T, unsigned BitNum, typename BitVectorTy>
+class PackedVectorBase<T, BitNum, BitVectorTy, true> {
+protected:
+  static T getValue(const BitVectorTy &Bits, unsigned Idx) {
+    T val = T();
+    for (unsigned i = 0; i != BitNum-1; ++i)
+      val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
+    if (Bits[(Idx << (BitNum-1)) + BitNum-1])
+      val = ~val;
+    return val;
+  }
+
+  static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
+    if (val < 0) {
+      val = ~val;
+      Bits.set((Idx << (BitNum-1)) + BitNum-1);
+    }
+    assert((val >> (BitNum-1)) == 0 && "value is too big");
+    for (unsigned i = 0; i != BitNum-1; ++i)
+      Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
+  }
+};
+
+/// \brief Store a vector of values using a specific number of bits for each
+/// value. Both signed and unsigned types can be used, e.g
+/// @code
+///   PackedVector<signed, 2> vec;
+/// @endcode
+/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
+/// an assertion.
+template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
+class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
+                                            std::numeric_limits<T>::is_signed> {
+  BitVectorTy Bits;
+  typedef PackedVectorBase<T, BitNum, BitVectorTy,
+                           std::numeric_limits<T>::is_signed> base;
+
+public:
+  class reference {
+    PackedVector &Vec;
+    const unsigned Idx;
+
+    reference();  // Undefined    
+  public:
+    reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { }    
+
+    reference &operator=(T val) {
+      Vec.setValue(Vec.Bits, Idx, val);
+      return *this;
+    }
+    operator T() const {
+      return Vec.getValue(Vec.Bits, Idx);
+    }
+  };
+
+  PackedVector() { }
+  explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { }
+
+  bool empty() const { return Bits.empty(); }
+
+  unsigned size() const { return Bits.size() >> (BitNum-1); }
+  
+  void clear() { Bits.clear(); }
+  
+  void resize(unsigned N) { Bits.resize(N << (BitNum-1)); }
+
+  void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); }
+
+  PackedVector &reset() {
+    Bits.reset();
+    return *this;
+  }
+
+  void push_back(T val) {
+    resize(size()+1);
+    (*this)[size()-1] = val;
+  }
+
+  reference operator[](unsigned Idx) {
+    return reference(*this, Idx);
+  }
+
+  T operator[](unsigned Idx) const {
+    return base::getValue(Bits, Idx);
+  }
+
+  bool operator==(const PackedVector &RHS) const {
+    return Bits == RHS.Bits;
+  }
+
+  bool operator!=(const PackedVector &RHS) const {
+    return Bits != RHS.Bits;
+  }
+
+  const PackedVector &operator=(const PackedVector &RHS) {
+    Bits = RHS.Bits;
+    return *this;
+  }
+
+  PackedVector &operator|=(const PackedVector &RHS) {
+    Bits |= RHS.Bits;
+    return *this;
+  }
+
+  void swap(PackedVector &RHS) {
+    Bits.swap(RHS.Bits);
+  }
+};
+
+// Leave BitNum=0 undefined. 
+template <typename T>
+class PackedVector<T, 0>;
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
new file mode 100644
index 0000000..45a40db
--- /dev/null
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -0,0 +1,204 @@
+//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- 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 PointerIntPair class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERINTPAIR_H
+#define LLVM_ADT_POINTERINTPAIR_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+#include <limits>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo;
+
+/// PointerIntPair - This class implements a pair of a pointer and small
+/// integer.  It is designed to represent this in the space required by one
+/// pointer by bitmangling the integer into the low part of the pointer.  This
+/// can only be done for small integers: typically up to 3 bits, but it depends
+/// on the number of bits available according to PointerLikeTypeTraits for the
+/// type.
+///
+/// Note that PointerIntPair always puts the IntVal part in the highest bits
+/// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
+/// the bool into bit #2, not bit #0, which allows the low two bits to be used
+/// for something else.  For example, this allows:
+///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
+/// ... and the two bools will land in different bits.
+///
+template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
+          typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
+class PointerIntPair {
+  intptr_t Value;
+  static_assert(PtrTraits::NumLowBitsAvailable <
+                std::numeric_limits<uintptr_t>::digits,
+                "cannot use a pointer type that has all bits free");
+  static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
+                "PointerIntPair with integer size too large for pointer");
+  enum : uintptr_t {
+    /// PointerBitMask - The bits that come from the pointer.
+    PointerBitMask =
+      ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
+
+    /// IntShift - The number of low bits that we reserve for other uses, and
+    /// keep zero.
+    IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
+    
+    /// IntMask - This is the unshifted mask for valid bits of the int type.
+    IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
+    
+    // ShiftedIntMask - This is the bits for the integer shifted in place.
+    ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
+  };
+public:
+  PointerIntPair() : Value(0) {}
+  PointerIntPair(PointerTy PtrVal, IntType IntVal) {
+    setPointerAndInt(PtrVal, IntVal);
+  }
+  explicit PointerIntPair(PointerTy PtrVal) {
+    initWithPointer(PtrVal);
+  }
+
+  PointerTy getPointer() const {
+    return PtrTraits::getFromVoidPointer(
+                         reinterpret_cast<void*>(Value & PointerBitMask));
+  }
+
+  IntType getInt() const {
+    return (IntType)((Value >> IntShift) & IntMask);
+  }
+
+  void setPointer(PointerTy PtrVal) {
+    intptr_t PtrWord
+      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
+    assert((PtrWord & ~PointerBitMask) == 0 &&
+           "Pointer is not sufficiently aligned");
+    // Preserve all low bits, just update the pointer.
+    Value = PtrWord | (Value & ~PointerBitMask);
+  }
+
+  void setInt(IntType IntVal) {
+    intptr_t IntWord = static_cast<intptr_t>(IntVal);
+    assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
+    
+    // Preserve all bits other than the ones we are updating.
+    Value &= ~ShiftedIntMask;     // Remove integer field.
+    Value |= IntWord << IntShift;  // Set new integer.
+  }
+
+  void initWithPointer(PointerTy PtrVal) {
+    intptr_t PtrWord
+      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
+    assert((PtrWord & ~PointerBitMask) == 0 &&
+           "Pointer is not sufficiently aligned");
+    Value = PtrWord;
+  }
+
+  void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
+    intptr_t PtrWord
+      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
+    assert((PtrWord & ~PointerBitMask) == 0 &&
+           "Pointer is not sufficiently aligned");
+    intptr_t IntWord = static_cast<intptr_t>(IntVal);
+    assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
+
+    Value = PtrWord | (IntWord << IntShift);
+  }
+
+  PointerTy const *getAddrOfPointer() const {
+    return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
+  }
+
+  PointerTy *getAddrOfPointer() {
+    assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
+           "Can only return the address if IntBits is cleared and "
+           "PtrTraits doesn't change the pointer");
+    return reinterpret_cast<PointerTy *>(&Value);
+  }
+
+  void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
+  void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
+
+  static PointerIntPair getFromOpaqueValue(void *V) {
+    PointerIntPair P; P.setFromOpaqueValue(V); return P; 
+  }
+
+  // Allow PointerIntPairs to be created from const void * if and only if the
+  // pointer type could be created from a const void *.
+  static PointerIntPair getFromOpaqueValue(const void *V) {
+    (void)PtrTraits::getFromVoidPointer(V);
+    return getFromOpaqueValue(const_cast<void *>(V));
+  }
+
+  bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
+  bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
+  bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
+  bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
+  bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
+  bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
+};
+
+template <typename T> struct isPodLike;
+template<typename PointerTy, unsigned IntBits, typename IntType>
+struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
+   static const bool value = true;
+};
+  
+// Provide specialization of DenseMapInfo for PointerIntPair.
+template<typename PointerTy, unsigned IntBits, typename IntType>
+struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
+  typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
+  static Ty getEmptyKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-1);
+    Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
+    return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
+  }
+  static Ty getTombstoneKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-2);
+    Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+    return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
+  }
+  static unsigned getHashValue(Ty V) {
+    uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
+    return unsigned(IV) ^ unsigned(IV >> 9);
+  }
+  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
+};
+
+// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
+template<typename PointerTy, unsigned IntBits, typename IntType,
+         typename PtrTraits>
+class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
+                                           PtrTraits> > {
+public:
+  static inline void *
+  getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
+    return P.getOpaqueValue();
+  }
+  static inline PointerIntPair<PointerTy, IntBits, IntType>
+  getFromVoidPointer(void *P) {
+    return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
+  }
+  static inline PointerIntPair<PointerTy, IntBits, IntType>
+  getFromVoidPointer(const void *P) {
+    return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
+  }
+  enum {
+    NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
+  };
+};
+
+} // end namespace llvm
+#endif
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
new file mode 100644
index 0000000..a6dddd2
--- /dev/null
+++ b/include/llvm/ADT/PointerUnion.h
@@ -0,0 +1,506 @@
+//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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 PointerUnion class, which is a discriminated union of
+// pointer types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERUNION_H
+#define LLVM_ADT_POINTERUNION_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+  template <typename T>
+  struct PointerUnionTypeSelectorReturn {
+    typedef T Return;
+  };
+
+  /// \brief Get a type based on whether two types are the same or not. For:
+  /// @code
+  /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
+  /// @endcode
+  /// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
+  template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+  struct PointerUnionTypeSelector {
+    typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
+  };
+
+  template <typename T, typename RET_EQ, typename RET_NE>
+  struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
+    typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
+  };
+
+  template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+  struct PointerUnionTypeSelectorReturn<
+                            PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
+    typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
+        Return;
+  };
+
+  /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+  /// for the two template arguments.
+  template <typename PT1, typename PT2>
+  class PointerUnionUIntTraits {
+  public:
+    static inline void *getAsVoidPointer(void *P) { return P; }
+    static inline void *getFromVoidPointer(void *P) { return P; }
+    enum {
+      PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
+      PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
+      NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
+    };
+  };
+  
+  /// PointerUnion - This implements a discriminated union of two pointer types,
+  /// and keeps the discriminator bit-mangled into the low bits of the pointer.
+  /// This allows the implementation to be extremely efficient in space, but
+  /// permits a very natural and type-safe API.
+  ///
+  /// Common use patterns would be something like this:
+  ///    PointerUnion<int*, float*> P;
+  ///    P = (int*)0;
+  ///    printf("%d %d", P.is<int*>(), P.is<float*>());  // prints "1 0"
+  ///    X = P.get<int*>();     // ok.
+  ///    Y = P.get<float*>();   // runtime assertion failure.
+  ///    Z = P.get<double*>();  // compile time failure.
+  ///    P = (float*)0;
+  ///    Y = P.get<float*>();   // ok.
+  ///    X = P.get<int*>();     // runtime assertion failure.
+  template <typename PT1, typename PT2>
+  class PointerUnion {
+  public:
+    typedef PointerIntPair<void*, 1, bool, 
+                           PointerUnionUIntTraits<PT1,PT2> > ValTy;
+  private:
+    ValTy Val;
+
+    struct IsPT1 {
+      static const int Num = 0;
+    };
+    struct IsPT2 {
+      static const int Num = 1;
+    };
+    template <typename T>
+    struct UNION_DOESNT_CONTAIN_TYPE { };
+
+  public:
+    PointerUnion() {}
+    
+    PointerUnion(PT1 V) : Val(
+      const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
+    }
+    PointerUnion(PT2 V) : Val(
+      const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
+    }
+    
+    /// isNull - Return true if the pointer held in the union is null,
+    /// regardless of which type it is.
+    bool isNull() const {
+      // Convert from the void* to one of the pointer types, to make sure that
+      // we recursively strip off low bits if we have a nested PointerUnion.
+      return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
+    }
+    LLVM_EXPLICIT operator bool() const { return !isNull(); }
+
+    /// is<T>() return true if the Union currently holds the type matching T.
+    template<typename T>
+    int is() const {
+      typedef typename
+        ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
+          ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
+                                    UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
+      int TyNo = Ty::Num;
+      return static_cast<int>(Val.getInt()) == TyNo;
+    }
+    
+    /// get<T>() - Return the value of the specified pointer type. If the
+    /// specified pointer type is incorrect, assert.
+    template<typename T>
+    T get() const {
+      assert(is<T>() && "Invalid accessor called");
+      return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+    }
+    
+    /// dyn_cast<T>() - If the current value is of the specified pointer type,
+    /// return it, otherwise return null.
+    template<typename T>
+    T dyn_cast() const {
+      if (is<T>()) return get<T>();
+      return T();
+    }
+
+    /// \brief If the union is set to the first pointer type get an address
+    /// pointing to it.
+    PT1 const *getAddrOfPtr1() const {
+      return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
+    }
+
+    /// \brief If the union is set to the first pointer type get an address
+    /// pointing to it.
+    PT1 *getAddrOfPtr1() {
+      assert(is<PT1>() && "Val is not the first pointer");
+      assert(get<PT1>() == Val.getPointer() &&
+         "Can't get the address because PointerLikeTypeTraits changes the ptr");
+      return (PT1 *)Val.getAddrOfPointer();
+    }
+
+    /// \brief Assignment from nullptr which just clears the union.
+    const PointerUnion &operator=(std::nullptr_t) {
+      Val.initWithPointer(nullptr);
+      return *this;
+    }
+    
+    /// Assignment operators - Allow assigning into this union from either
+    /// pointer type, setting the discriminator to remember what it came from.
+    const PointerUnion &operator=(const PT1 &RHS) {
+      Val.initWithPointer(
+         const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
+      return *this;
+    }
+    const PointerUnion &operator=(const PT2 &RHS) {
+      Val.setPointerAndInt(
+        const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
+        1);
+      return *this;
+    }
+    
+    void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+    static inline PointerUnion getFromOpaqueValue(void *VP) {
+      PointerUnion V;
+      V.Val = ValTy::getFromOpaqueValue(VP);
+      return V;
+    }
+  };
+
+  template<typename PT1, typename PT2>
+  static bool operator==(PointerUnion<PT1, PT2> lhs,
+                         PointerUnion<PT1, PT2> rhs) {
+    return lhs.getOpaqueValue() == rhs.getOpaqueValue();
+  }
+
+  template<typename PT1, typename PT2>
+  static bool operator!=(PointerUnion<PT1, PT2> lhs,
+                         PointerUnion<PT1, PT2> rhs) {
+    return lhs.getOpaqueValue() != rhs.getOpaqueValue();
+  }
+
+  // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
+  // # low bits available = min(PT1bits,PT2bits)-1.
+  template<typename PT1, typename PT2>
+  class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
+  public:
+    static inline void *
+    getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+      return P.getOpaqueValue();
+    }
+    static inline PointerUnion<PT1, PT2>
+    getFromVoidPointer(void *P) {
+      return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+    }
+    
+    // The number of bits available are the min of the two pointer types.
+    enum {
+      NumLowBitsAvailable = 
+        PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
+          ::NumLowBitsAvailable
+    };
+  };
+  
+  
+  /// PointerUnion3 - This is a pointer union of three pointer types.  See
+  /// documentation for PointerUnion for usage.
+  template <typename PT1, typename PT2, typename PT3>
+  class PointerUnion3 {
+  public:
+    typedef PointerUnion<PT1, PT2> InnerUnion;
+    typedef PointerUnion<InnerUnion, PT3> ValTy;
+  private:
+    ValTy Val;
+
+    struct IsInnerUnion {
+      ValTy Val;
+      IsInnerUnion(ValTy val) : Val(val) { }
+      template<typename T>
+      int is() const {
+        return Val.template is<InnerUnion>() && 
+               Val.template get<InnerUnion>().template is<T>();
+      }
+      template<typename T>
+      T get() const {
+        return Val.template get<InnerUnion>().template get<T>();
+      }
+    };
+
+    struct IsPT3 {
+      ValTy Val;
+      IsPT3(ValTy val) : Val(val) { }
+      template<typename T>
+      int is() const {
+        return Val.template is<T>();
+      }
+      template<typename T>
+      T get() const {
+        return Val.template get<T>();
+      }
+    };
+
+  public:
+    PointerUnion3() {}
+    
+    PointerUnion3(PT1 V) {
+      Val = InnerUnion(V);
+    }
+    PointerUnion3(PT2 V) {
+      Val = InnerUnion(V);
+    }
+    PointerUnion3(PT3 V) {
+      Val = V;
+    }
+    
+    /// isNull - Return true if the pointer held in the union is null,
+    /// regardless of which type it is.
+    bool isNull() const { return Val.isNull(); }
+    LLVM_EXPLICIT operator bool() const { return !isNull(); }
+    
+    /// is<T>() return true if the Union currently holds the type matching T.
+    template<typename T>
+    int is() const {
+      // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+      typedef typename
+        ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
+          ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
+                                                                   >::Return Ty;
+      return Ty(Val).template is<T>();
+    }
+    
+    /// get<T>() - Return the value of the specified pointer type. If the
+    /// specified pointer type is incorrect, assert.
+    template<typename T>
+    T get() const {
+      assert(is<T>() && "Invalid accessor called");
+      // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+      typedef typename
+        ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
+          ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
+                                                                   >::Return Ty;
+      return Ty(Val).template get<T>();
+    }
+    
+    /// dyn_cast<T>() - If the current value is of the specified pointer type,
+    /// return it, otherwise return null.
+    template<typename T>
+    T dyn_cast() const {
+      if (is<T>()) return get<T>();
+      return T();
+    }
+
+    /// \brief Assignment from nullptr which just clears the union.
+    const PointerUnion3 &operator=(std::nullptr_t) {
+      Val = nullptr;
+      return *this;
+    }
+    
+    /// Assignment operators - Allow assigning into this union from either
+    /// pointer type, setting the discriminator to remember what it came from.
+    const PointerUnion3 &operator=(const PT1 &RHS) {
+      Val = InnerUnion(RHS);
+      return *this;
+    }
+    const PointerUnion3 &operator=(const PT2 &RHS) {
+      Val = InnerUnion(RHS);
+      return *this;
+    }
+    const PointerUnion3 &operator=(const PT3 &RHS) {
+      Val = RHS;
+      return *this;
+    }
+    
+    void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+    static inline PointerUnion3 getFromOpaqueValue(void *VP) {
+      PointerUnion3 V;
+      V.Val = ValTy::getFromOpaqueValue(VP);
+      return V;
+    }
+  };
+ 
+  // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
+  // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+  template<typename PT1, typename PT2, typename PT3>
+  class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
+  public:
+    static inline void *
+    getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
+      return P.getOpaqueValue();
+    }
+    static inline PointerUnion3<PT1, PT2, PT3>
+    getFromVoidPointer(void *P) {
+      return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
+    }
+    
+    // The number of bits available are the min of the two pointer types.
+    enum {
+      NumLowBitsAvailable = 
+        PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
+          ::NumLowBitsAvailable
+    };
+  };
+
+  /// PointerUnion4 - This is a pointer union of four pointer types.  See
+  /// documentation for PointerUnion for usage.
+  template <typename PT1, typename PT2, typename PT3, typename PT4>
+  class PointerUnion4 {
+  public:
+    typedef PointerUnion<PT1, PT2> InnerUnion1;
+    typedef PointerUnion<PT3, PT4> InnerUnion2;
+    typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
+  private:
+    ValTy Val;
+  public:
+    PointerUnion4() {}
+    
+    PointerUnion4(PT1 V) {
+      Val = InnerUnion1(V);
+    }
+    PointerUnion4(PT2 V) {
+      Val = InnerUnion1(V);
+    }
+    PointerUnion4(PT3 V) {
+      Val = InnerUnion2(V);
+    }
+    PointerUnion4(PT4 V) {
+      Val = InnerUnion2(V);
+    }
+    
+    /// isNull - Return true if the pointer held in the union is null,
+    /// regardless of which type it is.
+    bool isNull() const { return Val.isNull(); }
+    LLVM_EXPLICIT operator bool() const { return !isNull(); }
+    
+    /// is<T>() return true if the Union currently holds the type matching T.
+    template<typename T>
+    int is() const {
+      // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+      typedef typename
+        ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
+          ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
+                                                                   >::Return Ty;
+      return Val.template is<Ty>() && 
+             Val.template get<Ty>().template is<T>();
+    }
+    
+    /// get<T>() - Return the value of the specified pointer type. If the
+    /// specified pointer type is incorrect, assert.
+    template<typename T>
+    T get() const {
+      assert(is<T>() && "Invalid accessor called");
+      // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+      typedef typename
+        ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
+          ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
+                                                                   >::Return Ty;
+      return Val.template get<Ty>().template get<T>();
+    }
+    
+    /// dyn_cast<T>() - If the current value is of the specified pointer type,
+    /// return it, otherwise return null.
+    template<typename T>
+    T dyn_cast() const {
+      if (is<T>()) return get<T>();
+      return T();
+    }
+
+    /// \brief Assignment from nullptr which just clears the union.
+    const PointerUnion4 &operator=(std::nullptr_t) {
+      Val = nullptr;
+      return *this;
+    }
+    
+    /// Assignment operators - Allow assigning into this union from either
+    /// pointer type, setting the discriminator to remember what it came from.
+    const PointerUnion4 &operator=(const PT1 &RHS) {
+      Val = InnerUnion1(RHS);
+      return *this;
+    }
+    const PointerUnion4 &operator=(const PT2 &RHS) {
+      Val = InnerUnion1(RHS);
+      return *this;
+    }
+    const PointerUnion4 &operator=(const PT3 &RHS) {
+      Val = InnerUnion2(RHS);
+      return *this;
+    }
+    const PointerUnion4 &operator=(const PT4 &RHS) {
+      Val = InnerUnion2(RHS);
+      return *this;
+    }
+    
+    void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+    static inline PointerUnion4 getFromOpaqueValue(void *VP) {
+      PointerUnion4 V;
+      V.Val = ValTy::getFromOpaqueValue(VP);
+      return V;
+    }
+  };
+  
+  // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
+  // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+  template<typename PT1, typename PT2, typename PT3, typename PT4>
+  class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
+  public:
+    static inline void *
+    getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
+      return P.getOpaqueValue();
+    }
+    static inline PointerUnion4<PT1, PT2, PT3, PT4>
+    getFromVoidPointer(void *P) {
+      return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
+    }
+    
+    // The number of bits available are the min of the two pointer types.
+    enum {
+      NumLowBitsAvailable = 
+        PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
+          ::NumLowBitsAvailable
+    };
+  };
+
+  // Teach DenseMap how to use PointerUnions as keys.
+  template<typename T, typename U>
+  struct DenseMapInfo<PointerUnion<T, U> > {
+    typedef PointerUnion<T, U> Pair;
+    typedef DenseMapInfo<T> FirstInfo;
+    typedef DenseMapInfo<U> SecondInfo;
+
+    static inline Pair getEmptyKey() {
+      return Pair(FirstInfo::getEmptyKey());
+    }
+    static inline Pair getTombstoneKey() {
+      return Pair(FirstInfo::getTombstoneKey());
+    }
+    static unsigned getHashValue(const Pair &PairVal) {
+      intptr_t key = (intptr_t)PairVal.getOpaqueValue();
+      return DenseMapInfo<intptr_t>::getHashValue(key);
+    }
+    static bool isEqual(const Pair &LHS, const Pair &RHS) {
+      return LHS.template is<T>() == RHS.template is<T>() &&
+             (LHS.template is<T>() ?
+              FirstInfo::isEqual(LHS.template get<T>(),
+                                 RHS.template get<T>()) :
+              SecondInfo::isEqual(LHS.template get<U>(),
+                                  RHS.template get<U>()));
+    }
+  };
+}
+
+#endif
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
new file mode 100644
index 0000000..dd8cc74
--- /dev/null
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -0,0 +1,279 @@
+//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic graph
+// post order iterator.  This should work over any graph type that has a
+// GraphTraits specialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POSTORDERITERATOR_H
+#define LLVM_ADT_POSTORDERITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// The po_iterator_storage template provides access to the set of already
+// visited nodes during the po_iterator's depth-first traversal.
+//
+// The default implementation simply contains a set of visited nodes, while
+// the Extended=true version uses a reference to an external set.
+//
+// It is possible to prune the depth-first traversal in several ways:
+//
+// - When providing an external set that already contains some graph nodes,
+//   those nodes won't be visited again. This is useful for restarting a
+//   post-order traversal on a graph with nodes that aren't dominated by a
+//   single node.
+//
+// - By providing a custom SetType class, unwanted graph nodes can be excluded
+//   by having the insert() function return false. This could for example
+//   confine a CFG traversal to blocks in a specific loop.
+//
+// - Finally, by specializing the po_iterator_storage template itself, graph
+//   edges can be pruned by returning false in the insertEdge() function. This
+//   could be used to remove loop back-edges from the CFG seen by po_iterator.
+//
+// A specialized po_iterator_storage class can observe both the pre-order and
+// the post-order. The insertEdge() function is called in a pre-order, while
+// the finishPostorder() function is called just before the po_iterator moves
+// on to the next node.
+
+/// Default po_iterator_storage implementation with an internal set object.
+template<class SetType, bool External>
+class po_iterator_storage {
+  SetType Visited;
+public:
+  // Return true if edge destination should be visited.
+  template<typename NodeType>
+  bool insertEdge(NodeType *From, NodeType *To) {
+    return Visited.insert(To);
+  }
+
+  // Called after all children of BB have been visited.
+  template<typename NodeType>
+  void finishPostorder(NodeType *BB) {}
+};
+
+/// Specialization of po_iterator_storage that references an external set.
+template<class SetType>
+class po_iterator_storage<SetType, true> {
+  SetType &Visited;
+public:
+  po_iterator_storage(SetType &VSet) : Visited(VSet) {}
+  po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
+
+  // Return true if edge destination should be visited, called with From = 0 for
+  // the root node.
+  // Graph edges can be pruned by specializing this function.
+  template<class NodeType>
+  bool insertEdge(NodeType *From, NodeType *To) { return Visited.insert(To); }
+
+  // Called after all children of BB have been visited.
+  template<class NodeType>
+  void finishPostorder(NodeType *BB) {}
+};
+
+template<class GraphT,
+  class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+  bool ExtStorage = false,
+  class GT = GraphTraits<GraphT> >
+class po_iterator : public std::iterator<std::forward_iterator_tag,
+                                         typename GT::NodeType, ptrdiff_t>,
+                    public po_iterator_storage<SetType, ExtStorage> {
+  typedef std::iterator<std::forward_iterator_tag,
+                        typename GT::NodeType, ptrdiff_t> super;
+  typedef typename GT::NodeType          NodeType;
+  typedef typename GT::ChildIteratorType ChildItTy;
+
+  // VisitStack - Used to maintain the ordering.  Top = current block
+  // First element is basic block pointer, second is the 'next child' to visit
+  std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+  void traverseChild() {
+    while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+      NodeType *BB = *VisitStack.back().second++;
+      if (this->insertEdge(VisitStack.back().first, BB)) {
+        // If the block is not visited...
+        VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+      }
+    }
+  }
+
+  inline po_iterator(NodeType *BB) {
+    this->insertEdge((NodeType*)nullptr, BB);
+    VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+    traverseChild();
+  }
+  inline po_iterator() {} // End is when stack is empty.
+
+  inline po_iterator(NodeType *BB, SetType &S) :
+    po_iterator_storage<SetType, ExtStorage>(S) {
+    if (this->insertEdge((NodeType*)nullptr, BB)) {
+      VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+      traverseChild();
+    }
+  }
+
+  inline po_iterator(SetType &S) :
+      po_iterator_storage<SetType, ExtStorage>(S) {
+  } // End is when stack is empty.
+public:
+  typedef typename super::pointer pointer;
+  typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+  // Provide static "constructors"...
+  static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
+  static inline _Self end  (GraphT G) { return _Self(); }
+
+  static inline _Self begin(GraphT G, SetType &S) {
+    return _Self(GT::getEntryNode(G), S);
+  }
+  static inline _Self end  (GraphT G, SetType &S) { return _Self(S); }
+
+  inline bool operator==(const _Self& x) const {
+    return VisitStack == x.VisitStack;
+  }
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  inline pointer operator*() const {
+    return VisitStack.back().first;
+  }
+
+  // This is a nonstandard operator-> that dereferences the pointer an extra
+  // time... so that you can actually call methods ON the BasicBlock, because
+  // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
+  //
+  inline NodeType *operator->() const { return operator*(); }
+
+  inline _Self& operator++() {   // Preincrement
+    this->finishPostorder(VisitStack.back().first);
+    VisitStack.pop_back();
+    if (!VisitStack.empty())
+      traverseChild();
+    return *this;
+  }
+
+  inline _Self operator++(int) { // Postincrement
+    _Self tmp = *this; ++*this; return tmp;
+  }
+};
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+template <class T>
+po_iterator<T> po_end  (T G) { return po_iterator<T>::end(G); }
+
+// Provide global definitions of external postorder iterators...
+template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
+struct po_ext_iterator : public po_iterator<T, SetType, true> {
+  po_ext_iterator(const po_iterator<T, SetType, true> &V) :
+  po_iterator<T, SetType, true>(V) {}
+};
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
+  return po_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
+  return po_ext_iterator<T, SetType>::end(G, S);
+}
+
+// Provide global definitions of inverse post order iterators...
+template <class T,
+          class SetType = std::set<typename GraphTraits<T>::NodeType*>,
+          bool External = false>
+struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
+  ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
+     po_iterator<Inverse<T>, SetType, External> (V) {}
+};
+
+template <class T>
+ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+  return ipo_iterator<T>::begin(G, Reverse);
+}
+
+template <class T>
+ipo_iterator<T> ipo_end(T G){
+  return ipo_iterator<T>::end(G);
+}
+
+// Provide global definitions of external inverse postorder iterators...
+template <class T,
+          class SetType = std::set<typename GraphTraits<T>::NodeType*> >
+struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
+  ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
+    ipo_iterator<T, SetType, true>(V) {}
+  ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
+    ipo_iterator<T, SetType, true>(V) {}
+};
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+  return ipo_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+  return ipo_ext_iterator<T, SetType>::end(G, S);
+}
+
+//===--------------------------------------------------------------------===//
+// Reverse Post Order CFG iterator code
+//===--------------------------------------------------------------------===//
+//
+// This is used to visit basic blocks in a method in reverse post order.  This
+// class is awkward to use because I don't know a good incremental algorithm to
+// computer RPO from a graph.  Because of this, the construction of the
+// ReversePostOrderTraversal object is expensive (it must walk the entire graph
+// with a postorder iterator to build the data structures).  The moral of this
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
+//
+// This class should be used like this:
+// {
+//   ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+//   for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+//      ...
+//   }
+//   for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+//      ...
+//   }
+// }
+//
+
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class ReversePostOrderTraversal {
+  typedef typename GT::NodeType NodeType;
+  std::vector<NodeType*> Blocks;       // Block list in normal PO order
+  inline void Initialize(NodeType *BB) {
+    std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
+  }
+public:
+  typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+  inline ReversePostOrderTraversal(GraphT G) {
+    Initialize(GT::getEntryNode(G));
+  }
+
+  // Because we want a reverse post order, use reverse iterators from the vector
+  inline rpo_iterator begin() { return Blocks.rbegin(); }
+  inline rpo_iterator end()   { return Blocks.rend(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/PriorityQueue.h b/include/llvm/ADT/PriorityQueue.h
new file mode 100644
index 0000000..827d0b3
--- /dev/null
+++ b/include/llvm/ADT/PriorityQueue.h
@@ -0,0 +1,84 @@
+//===- llvm/ADT/PriorityQueue.h - Priority queues ---------------*- 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 PriorityQueue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_PRIORITYQUEUE_H
+#define LLVM_ADT_PRIORITYQUEUE_H
+
+#include <algorithm>
+#include <queue>
+
+namespace llvm {
+
+/// PriorityQueue - This class behaves like std::priority_queue and
+/// provides a few additional convenience functions.
+///
+template<class T,
+         class Sequence = std::vector<T>,
+         class Compare = std::less<typename Sequence::value_type> >
+class PriorityQueue : public std::priority_queue<T, Sequence, Compare> {
+public:
+  explicit PriorityQueue(const Compare &compare = Compare(),
+                         const Sequence &sequence = Sequence())
+    : std::priority_queue<T, Sequence, Compare>(compare, sequence)
+  {}
+
+  template<class Iterator>
+  PriorityQueue(Iterator begin, Iterator end,
+                const Compare &compare = Compare(),
+                const Sequence &sequence = Sequence())
+    : std::priority_queue<T, Sequence, Compare>(begin, end, compare, sequence)
+  {}
+
+  /// erase_one - Erase one element from the queue, regardless of its
+  /// position. This operation performs a linear search to find an element
+  /// equal to t, but then uses all logarithmic-time algorithms to do
+  /// the erase operation.
+  ///
+  void erase_one(const T &t) {
+    // Linear-search to find the element.
+    typename Sequence::size_type i =
+      std::find(this->c.begin(), this->c.end(), t) - this->c.begin();
+
+    // Logarithmic-time heap bubble-up.
+    while (i != 0) {
+      typename Sequence::size_type parent = (i - 1) / 2;
+      this->c[i] = this->c[parent];
+      i = parent;
+    }
+
+    // The element we want to remove is now at the root, so we can use
+    // priority_queue's plain pop to remove it.
+    this->pop();
+  }
+
+  /// reheapify - If an element in the queue has changed in a way that
+  /// affects its standing in the comparison function, the queue's
+  /// internal state becomes invalid. Calling reheapify() resets the
+  /// queue's state, making it valid again. This operation has time
+  /// complexity proportional to the number of elements in the queue,
+  /// so don't plan to use it a lot.
+  ///
+  void reheapify() {
+    std::make_heap(this->c.begin(), this->c.end(), this->comp);
+  }
+
+  /// clear - Erase all elements from the queue.
+  ///
+  void clear() {
+    this->c.clear();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
new file mode 100644
index 0000000..bc74416
--- /dev/null
+++ b/include/llvm/ADT/SCCIterator.h
@@ -0,0 +1,245 @@
+//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This builds on the llvm/ADT/GraphTraits.h file to find the strongly
+/// connected components (SCCs) of a graph in O(N+E) time using Tarjan's DFS
+/// algorithm.
+///
+/// The SCC iterator has the important property that if a node in SCC S1 has an
+/// edge to a node in SCC S2, then it visits S1 *after* S2.
+///
+/// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. (NOTE:
+/// This requires some simple wrappers and is not supported yet.)
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCCITERATOR_H
+#define LLVM_ADT_SCCITERATOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
+#include <vector>
+
+namespace llvm {
+
+/// \brief Enumerate the SCCs of a directed graph in reverse topological order
+/// of the SCC DAG.
+///
+/// This is implemented using Tarjan's DFS algorithm using an internal stack to
+/// build up a vector of nodes in a particular SCC. Note that it is a forward
+/// iterator and thus you cannot backtrack or re-visit nodes.
+template <class GraphT, class GT = GraphTraits<GraphT>>
+class scc_iterator
+    : public iterator_facade_base<
+          scc_iterator<GraphT, GT>, std::forward_iterator_tag,
+          const std::vector<typename GT::NodeType *>, ptrdiff_t> {
+  typedef typename GT::NodeType NodeType;
+  typedef typename GT::ChildIteratorType ChildItTy;
+  typedef std::vector<NodeType *> SccTy;
+  typedef typename scc_iterator::reference reference;
+
+  /// Element of VisitStack during DFS.
+  struct StackElement {
+    NodeType *Node;       ///< The current node pointer.
+    ChildItTy NextChild;  ///< The next child, modified inplace during DFS.
+    unsigned MinVisited;  ///< Minimum uplink value of all children of Node.
+
+    StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min)
+      : Node(Node), NextChild(Child), MinVisited(Min) {}
+
+    bool operator==(const StackElement &Other) const {
+      return Node == Other.Node &&
+             NextChild == Other.NextChild &&
+             MinVisited == Other.MinVisited;
+    }
+  };
+
+  /// The visit counters used to detect when a complete SCC is on the stack.
+  /// visitNum is the global counter.
+  ///
+  /// nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
+  unsigned visitNum;
+  DenseMap<NodeType *, unsigned> nodeVisitNumbers;
+
+  /// Stack holding nodes of the SCC.
+  std::vector<NodeType *> SCCNodeStack;
+
+  /// The current SCC, retrieved using operator*().
+  SccTy CurrentSCC;
+
+  /// DFS stack, Used to maintain the ordering.  The top contains the current
+  /// node, the next child to visit, and the minimum uplink value of all child
+  std::vector<StackElement> VisitStack;
+
+  /// A single "visit" within the non-recursive DFS traversal.
+  void DFSVisitOne(NodeType *N);
+
+  /// The stack-based DFS traversal; defined below.
+  void DFSVisitChildren();
+
+  /// Compute the next SCC using the DFS traversal.
+  void GetNextSCC();
+
+  scc_iterator(NodeType *entryN) : visitNum(0) {
+    DFSVisitOne(entryN);
+    GetNextSCC();
+  }
+
+  /// End is when the DFS stack is empty.
+  scc_iterator() {}
+
+public:
+  static scc_iterator begin(const GraphT &G) {
+    return scc_iterator(GT::getEntryNode(G));
+  }
+  static scc_iterator end(const GraphT &) { return scc_iterator(); }
+
+  /// \brief Direct loop termination test which is more efficient than
+  /// comparison with \c end().
+  bool isAtEnd() const {
+    assert(!CurrentSCC.empty() || VisitStack.empty());
+    return CurrentSCC.empty();
+  }
+
+  bool operator==(const scc_iterator &x) const {
+    return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
+  }
+
+  scc_iterator &operator++() {
+    GetNextSCC();
+    return *this;
+  }
+
+  reference operator*() const {
+    assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+    return CurrentSCC;
+  }
+
+  /// \brief Test if the current SCC has a loop.
+  ///
+  /// If the SCC has more than one node, this is trivially true.  If not, it may
+  /// still contain a loop if the node has an edge back to itself.
+  bool hasLoop() const;
+
+  /// This informs the \c scc_iterator that the specified \c Old node
+  /// has been deleted, and \c New is to be used in its place.
+  void ReplaceNode(NodeType *Old, NodeType *New) {
+    assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
+    nodeVisitNumbers[New] = nodeVisitNumbers[Old];
+    nodeVisitNumbers.erase(Old);
+  }
+};
+
+template <class GraphT, class GT>
+void scc_iterator<GraphT, GT>::DFSVisitOne(NodeType *N) {
+  ++visitNum;
+  nodeVisitNumbers[N] = visitNum;
+  SCCNodeStack.push_back(N);
+  VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum));
+#if 0 // Enable if needed when debugging.
+  dbgs() << "TarjanSCC: Node " << N <<
+        " : visitNum = " << visitNum << "\n";
+#endif
+}
+
+template <class GraphT, class GT>
+void scc_iterator<GraphT, GT>::DFSVisitChildren() {
+  assert(!VisitStack.empty());
+  while (VisitStack.back().NextChild != GT::child_end(VisitStack.back().Node)) {
+    // TOS has at least one more child so continue DFS
+    NodeType *childN = *VisitStack.back().NextChild++;
+    typename DenseMap<NodeType *, unsigned>::iterator Visited =
+        nodeVisitNumbers.find(childN);
+    if (Visited == nodeVisitNumbers.end()) {
+      // this node has never been seen.
+      DFSVisitOne(childN);
+      continue;
+    }
+
+    unsigned childNum = Visited->second;
+    if (VisitStack.back().MinVisited > childNum)
+      VisitStack.back().MinVisited = childNum;
+  }
+}
+
+template <class GraphT, class GT> void scc_iterator<GraphT, GT>::GetNextSCC() {
+  CurrentSCC.clear(); // Prepare to compute the next SCC
+  while (!VisitStack.empty()) {
+    DFSVisitChildren();
+
+    // Pop the leaf on top of the VisitStack.
+    NodeType *visitingN = VisitStack.back().Node;
+    unsigned minVisitNum = VisitStack.back().MinVisited;
+    assert(VisitStack.back().NextChild == GT::child_end(visitingN));
+    VisitStack.pop_back();
+
+    // Propagate MinVisitNum to parent so we can detect the SCC starting node.
+    if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum)
+      VisitStack.back().MinVisited = minVisitNum;
+
+#if 0 // Enable if needed when debugging.
+    dbgs() << "TarjanSCC: Popped node " << visitingN <<
+          " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+          nodeVisitNumbers[visitingN] << "\n";
+#endif
+
+    if (minVisitNum != nodeVisitNumbers[visitingN])
+      continue;
+
+    // A full SCC is on the SCCNodeStack!  It includes all nodes below
+    // visitingN on the stack.  Copy those nodes to CurrentSCC,
+    // reset their minVisit values, and return (this suspends
+    // the DFS traversal till the next ++).
+    do {
+      CurrentSCC.push_back(SCCNodeStack.back());
+      SCCNodeStack.pop_back();
+      nodeVisitNumbers[CurrentSCC.back()] = ~0U;
+    } while (CurrentSCC.back() != visitingN);
+    return;
+  }
+}
+
+template <class GraphT, class GT>
+bool scc_iterator<GraphT, GT>::hasLoop() const {
+    assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+    if (CurrentSCC.size() > 1)
+      return true;
+    NodeType *N = CurrentSCC.front();
+    for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE;
+         ++CI)
+      if (*CI == N)
+        return true;
+    return false;
+  }
+
+/// \brief Construct the begin iterator for a deduced graph type T.
+template <class T> scc_iterator<T> scc_begin(const T &G) {
+  return scc_iterator<T>::begin(G);
+}
+
+/// \brief Construct the end iterator for a deduced graph type T.
+template <class T> scc_iterator<T> scc_end(const T &G) {
+  return scc_iterator<T>::end(G);
+}
+
+/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>.
+template <class T> scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
+  return scc_iterator<Inverse<T> >::begin(G);
+}
+
+/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>.
+template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
+  return scc_iterator<Inverse<T> >::end(G);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
new file mode 100644
index 0000000..1cef393
--- /dev/null
+++ b/include/llvm/ADT/STLExtras.h
@@ -0,0 +1,542 @@
+//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL at all.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
+
+#include "llvm/Support/Compiler.h"
+#include <cstddef> // for std::size_t
+#include <cstdlib> // for qsort
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <utility> // for std::pair
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//     Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+template<class Ty>
+struct identity : public std::unary_function<Ty, Ty> {
+  Ty &operator()(Ty &self) const {
+    return self;
+  }
+  const Ty &operator()(const Ty &self) const {
+    return self;
+  }
+};
+
+template<class Ty>
+struct less_ptr : public std::binary_function<Ty, Ty, bool> {
+  bool operator()(const Ty* left, const Ty* right) const {
+    return *left < *right;
+  }
+};
+
+template<class Ty>
+struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
+  bool operator()(const Ty* left, const Ty* right) const {
+    return *right < *left;
+  }
+};
+
+/// An efficient, type-erasing, non-owning reference to a callable. This is
+/// intended for use as the type of a function parameter that is not used
+/// after the function in question returns.
+///
+/// This class does not own the callable, so it is not in general safe to store
+/// a function_ref.
+template<typename Fn> class function_ref;
+
+#if LLVM_HAS_VARIADIC_TEMPLATES
+
+template<typename Ret, typename ...Params>
+class function_ref<Ret(Params...)> {
+  Ret (*callback)(intptr_t callable, Params ...params);
+  intptr_t callable;
+
+  template<typename Callable>
+  static Ret callback_fn(intptr_t callable, Params ...params) {
+    return (*reinterpret_cast<Callable*>(callable))(
+        std::forward<Params>(params)...);
+  }
+
+public:
+  template<typename Callable>
+  function_ref(Callable &&callable)
+      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
+  Ret operator()(Params ...params) const {
+    return callback(callable, std::forward<Params>(params)...);
+  }
+};
+
+#else
+
+template<typename Ret>
+class function_ref<Ret()> {
+  Ret (*callback)(intptr_t callable);
+  intptr_t callable;
+
+  template<typename Callable>
+  static Ret callback_fn(intptr_t callable) {
+    return (*reinterpret_cast<Callable*>(callable))();
+  }
+
+public:
+  template<typename Callable>
+  function_ref(Callable &&callable)
+      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
+  Ret operator()() const { return callback(callable); }
+};
+
+template<typename Ret, typename Param1>
+class function_ref<Ret(Param1)> {
+  Ret (*callback)(intptr_t callable, Param1 param1);
+  intptr_t callable;
+
+  template<typename Callable>
+  static Ret callback_fn(intptr_t callable, Param1 param1) {
+    return (*reinterpret_cast<Callable*>(callable))(
+        std::forward<Param1>(param1));
+  }
+
+public:
+  template<typename Callable>
+  function_ref(Callable &&callable)
+      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
+  Ret operator()(Param1 param1) {
+    return callback(callable, std::forward<Param1>(param1));
+  }
+};
+
+template<typename Ret, typename Param1, typename Param2>
+class function_ref<Ret(Param1, Param2)> {
+  Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2);
+  intptr_t callable;
+
+  template<typename Callable>
+  static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2) {
+    return (*reinterpret_cast<Callable*>(callable))(
+        std::forward<Param1>(param1),
+        std::forward<Param2>(param2));
+  }
+
+public:
+  template<typename Callable>
+  function_ref(Callable &&callable)
+      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
+  Ret operator()(Param1 param1, Param2 param2) {
+    return callback(callable,
+                    std::forward<Param1>(param1),
+                    std::forward<Param2>(param2));
+  }
+};
+
+template<typename Ret, typename Param1, typename Param2, typename Param3>
+class function_ref<Ret(Param1, Param2, Param3)> {
+  Ret (*callback)(intptr_t callable, Param1 param1, Param2 param2, Param3 param3);
+  intptr_t callable;
+
+  template<typename Callable>
+  static Ret callback_fn(intptr_t callable, Param1 param1, Param2 param2,
+                         Param3 param3) {
+    return (*reinterpret_cast<Callable*>(callable))(
+        std::forward<Param1>(param1),
+        std::forward<Param2>(param2),
+        std::forward<Param3>(param3));
+  }
+
+public:
+  template<typename Callable>
+  function_ref(Callable &&callable)
+      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+        callable(reinterpret_cast<intptr_t>(&callable)) {}
+  Ret operator()(Param1 param1, Param2 param2, Param3 param3) {
+    return callback(callable,
+                    std::forward<Param1>(param1),
+                    std::forward<Param2>(param2),
+                    std::forward<Param3>(param3));
+  }
+};
+
+#endif
+
+// deleter - Very very very simple method that is used to invoke operator
+// delete on something.  It is used like this:
+//
+//   for_each(V.begin(), B.end(), deleter<Interval>);
+//
+template <class T>
+inline void deleter(T *Ptr) {
+  delete Ptr;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//     Extra additions to <iterator>
+//===----------------------------------------------------------------------===//
+
+// mapped_iterator - This is a simple iterator adapter that causes a function to
+// be dereferenced whenever operator* is invoked on the iterator.
+//
+template <class RootIt, class UnaryFunc>
+class mapped_iterator {
+  RootIt current;
+  UnaryFunc Fn;
+public:
+  typedef typename std::iterator_traits<RootIt>::iterator_category
+          iterator_category;
+  typedef typename std::iterator_traits<RootIt>::difference_type
+          difference_type;
+  typedef typename UnaryFunc::result_type value_type;
+
+  typedef void pointer;
+  //typedef typename UnaryFunc::result_type *pointer;
+  typedef void reference;        // Can't modify value returned by fn
+
+  typedef RootIt iterator_type;
+  typedef mapped_iterator<RootIt, UnaryFunc> _Self;
+
+  inline const RootIt &getCurrent() const { return current; }
+  inline const UnaryFunc &getFunc() const { return Fn; }
+
+  inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
+    : current(I), Fn(F) {}
+
+  inline value_type operator*() const {   // All this work to do this
+    return Fn(*current);         // little change
+  }
+
+  _Self& operator++() { ++current; return *this; }
+  _Self& operator--() { --current; return *this; }
+  _Self  operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
+  _Self  operator--(int) { _Self __tmp = *this; --current; return __tmp; }
+  _Self  operator+    (difference_type n) const {
+    return _Self(current + n, Fn);
+  }
+  _Self& operator+=   (difference_type n) { current += n; return *this; }
+  _Self  operator-    (difference_type n) const {
+    return _Self(current - n, Fn);
+  }
+  _Self& operator-=   (difference_type n) { current -= n; return *this; }
+  reference operator[](difference_type n) const { return *(*this + n); }
+
+  inline bool operator!=(const _Self &X) const { return !operator==(X); }
+  inline bool operator==(const _Self &X) const { return current == X.current; }
+  inline bool operator< (const _Self &X) const { return current <  X.current; }
+
+  inline difference_type operator-(const _Self &X) const {
+    return current - X.current;
+  }
+};
+
+template <class _Iterator, class Func>
+inline mapped_iterator<_Iterator, Func>
+operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
+          const mapped_iterator<_Iterator, Func>& X) {
+  return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
+}
+
+
+// map_iterator - Provide a convenient way to create mapped_iterators, just like
+// make_pair is useful for creating pairs...
+//
+template <class ItTy, class FuncTy>
+inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
+  return mapped_iterator<ItTy, FuncTy>(I, F);
+}
+
+//===----------------------------------------------------------------------===//
+//     Extra additions to <utility>
+//===----------------------------------------------------------------------===//
+
+/// \brief Function object to check whether the first component of a std::pair
+/// compares less than the first component of another std::pair.
+struct less_first {
+  template <typename T> bool operator()(const T &lhs, const T &rhs) const {
+    return lhs.first < rhs.first;
+  }
+};
+
+/// \brief Function object to check whether the second component of a std::pair
+/// compares less than the second component of another std::pair.
+struct less_second {
+  template <typename T> bool operator()(const T &lhs, const T &rhs) const {
+    return lhs.second < rhs.second;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//     Extra additions for arrays
+//===----------------------------------------------------------------------===//
+
+/// Find the length of an array.
+template <class T, std::size_t N>
+LLVM_CONSTEXPR inline size_t array_lengthof(T (&)[N]) {
+  return N;
+}
+
+/// Adapt std::less<T> for array_pod_sort.
+template<typename T>
+inline int array_pod_sort_comparator(const void *P1, const void *P2) {
+  if (std::less<T>()(*reinterpret_cast<const T*>(P1),
+                     *reinterpret_cast<const T*>(P2)))
+    return -1;
+  if (std::less<T>()(*reinterpret_cast<const T*>(P2),
+                     *reinterpret_cast<const T*>(P1)))
+    return 1;
+  return 0;
+}
+
+/// get_array_pod_sort_comparator - This is an internal helper function used to
+/// get type deduction of T right.
+template<typename T>
+inline int (*get_array_pod_sort_comparator(const T &))
+             (const void*, const void*) {
+  return array_pod_sort_comparator<T>;
+}
+
+
+/// array_pod_sort - This sorts an array with the specified start and end
+/// extent.  This is just like std::sort, except that it calls qsort instead of
+/// using an inlined template.  qsort is slightly slower than std::sort, but
+/// most sorts are not performance critical in LLVM and std::sort has to be
+/// template instantiated for each type, leading to significant measured code
+/// bloat.  This function should generally be used instead of std::sort where
+/// possible.
+///
+/// This function assumes that you have simple POD-like types that can be
+/// compared with std::less and can be moved with memcpy.  If this isn't true,
+/// you should use std::sort.
+///
+/// NOTE: If qsort_r were portable, we could allow a custom comparator and
+/// default to std::less.
+template<class IteratorTy>
+inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
+  // Don't dereference start iterator of empty sequence.
+  if (Start == End) return;
+  qsort(&*Start, End-Start, sizeof(*Start),
+        get_array_pod_sort_comparator(*Start));
+}
+
+template <class IteratorTy>
+inline void array_pod_sort(
+    IteratorTy Start, IteratorTy End,
+    int (*Compare)(
+        const typename std::iterator_traits<IteratorTy>::value_type *,
+        const typename std::iterator_traits<IteratorTy>::value_type *)) {
+  // Don't dereference start iterator of empty sequence.
+  if (Start == End) return;
+  qsort(&*Start, End - Start, sizeof(*Start),
+        reinterpret_cast<int (*)(const void *, const void *)>(Compare));
+}
+
+//===----------------------------------------------------------------------===//
+//     Extra additions to <algorithm>
+//===----------------------------------------------------------------------===//
+
+/// For a container of pointers, deletes the pointers and then clears the
+/// container.
+template<typename Container>
+void DeleteContainerPointers(Container &C) {
+  for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
+    delete *I;
+  C.clear();
+}
+
+/// In a container of pairs (usually a map) whose second element is a pointer,
+/// deletes the second elements and then clears the container.
+template<typename Container>
+void DeleteContainerSeconds(Container &C) {
+  for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
+    delete I->second;
+  C.clear();
+}
+
+//===----------------------------------------------------------------------===//
+//     Extra additions to <memory>
+//===----------------------------------------------------------------------===//
+
+#if LLVM_HAS_VARIADIC_TEMPLATES
+
+// Implement make_unique according to N3656.
+
+/// \brief Constructs a `new T()` with the given args and returns a
+///        `unique_ptr<T>` which owns the object.
+///
+/// Example:
+///
+///     auto p = make_unique<int>();
+///     auto p = make_unique<std::tuple<int, int>>(0, 1);
+template <class T, class... Args>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Args &&... args) {
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+/// \brief Constructs a `new T[n]` with the given args and returns a
+///        `unique_ptr<T[]>` which owns the object.
+///
+/// \param n size of the new array.
+///
+/// Example:
+///
+///     auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
+template <class T>
+typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
+                        std::unique_ptr<T>>::type
+make_unique(size_t n) {
+  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+/// This function isn't used and is only here to provide better compile errors.
+template <class T, class... Args>
+typename std::enable_if<std::extent<T>::value != 0>::type
+make_unique(Args &&...) LLVM_DELETED_FUNCTION;
+
+#else
+
+template <class T>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique() {
+  return std::unique_ptr<T>(new T());
+}
+
+template <class T, class Arg1>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1) {
+  return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1)));
+}
+
+template <class T, class Arg1, class Arg2>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3) {
+  return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1),
+                                  std::forward<Arg2>(arg2),
+                                  std::forward<Arg3>(arg3)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+          class Arg6>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+            Arg6 &&arg6) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5), std::forward<Arg6>(arg6)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+          class Arg6, class Arg7>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+            Arg6 &&arg6, Arg7 &&arg7) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+            std::forward<Arg7>(arg7)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+          class Arg6, class Arg7, class Arg8>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+            Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+            std::forward<Arg7>(arg7), std::forward<Arg8>(arg8)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+          class Arg6, class Arg7, class Arg8, class Arg9>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+            Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+            std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+            std::forward<Arg9>(arg9)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+          class Arg6, class Arg7, class Arg8, class Arg9, class Arg10>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+            Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9, Arg10 &&arg10) {
+  return std::unique_ptr<T>(
+      new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+            std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+            std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+            std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+            std::forward<Arg9>(arg9), std::forward<Arg10>(arg10)));
+}
+
+template <class T>
+typename std::enable_if<std::is_array<T>::value &&std::extent<T>::value == 0,
+                        std::unique_ptr<T>>::type
+make_unique(size_t n) {
+  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+#endif
+
+template<typename First, typename Second>
+struct pair_hash {
+  size_t operator()(const std::pair<First, Second> &P) const {
+    return std::hash<First>()(P.first) * 31 + std::hash<Second>()(P.second);
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
new file mode 100644
index 0000000..02a6ea3
--- /dev/null
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -0,0 +1,256 @@
+//===- ScopedHashTable.h - A simple scoped hash table ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an efficient scoped hash table, which is useful for
+// things like dominator-based optimizations.  This allows clients to do things
+// like this:
+//
+//  ScopedHashTable<int, int> HT;
+//  {
+//    ScopedHashTableScope<int, int> Scope1(HT);
+//    HT.insert(0, 0);
+//    HT.insert(1, 1);
+//    {
+//      ScopedHashTableScope<int, int> Scope2(HT);
+//      HT.insert(0, 42);
+//    }
+//  }
+//
+// Looking up the value for "0" in the Scope2 block will return 42.  Looking
+// up the value for 0 before 42 is inserted or after Scope2 is popped will
+// return 0.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCOPEDHASHTABLE_H
+#define LLVM_ADT_SCOPEDHASHTABLE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+          typename AllocatorTy = MallocAllocator>
+class ScopedHashTable;
+
+template <typename K, typename V>
+class ScopedHashTableVal {
+  ScopedHashTableVal *NextInScope;
+  ScopedHashTableVal *NextForKey;
+  K Key;
+  V Val;
+  ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {}
+public:
+
+  const K &getKey() const { return Key; }
+  const V &getValue() const { return Val; }
+  V &getValue() { return Val; }
+
+  ScopedHashTableVal *getNextForKey() { return NextForKey; }
+  const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
+  ScopedHashTableVal *getNextInScope() { return NextInScope; }
+  
+  template <typename AllocatorTy>
+  static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope,
+                                    ScopedHashTableVal *nextForKey,
+                                    const K &key, const V &val,
+                                    AllocatorTy &Allocator) {
+    ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>();
+    // Set up the value.
+    new (New) ScopedHashTableVal(key, val);
+    New->NextInScope = nextInScope;
+    New->NextForKey = nextForKey; 
+    return New;
+  }
+  
+  template <typename AllocatorTy>
+  void Destroy(AllocatorTy &Allocator) {
+    // Free memory referenced by the item.
+    this->~ScopedHashTableVal();
+    Allocator.Deallocate(this);
+  }
+};
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+          typename AllocatorTy = MallocAllocator>
+class ScopedHashTableScope {
+  /// HT - The hashtable that we are active for.
+  ScopedHashTable<K, V, KInfo, AllocatorTy> &HT;
+
+  /// PrevScope - This is the scope that we are shadowing in HT.
+  ScopedHashTableScope *PrevScope;
+
+  /// LastValInScope - This is the last value that was inserted for this scope
+  /// or null if none have been inserted yet.
+  ScopedHashTableVal<K, V> *LastValInScope;
+  void operator=(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
+  ScopedHashTableScope(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
+public:
+  ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
+  ~ScopedHashTableScope();
+
+  ScopedHashTableScope *getParentScope() { return PrevScope; }
+  const ScopedHashTableScope *getParentScope() const { return PrevScope; }
+  
+private:
+  friend class ScopedHashTable<K, V, KInfo, AllocatorTy>;
+  ScopedHashTableVal<K, V> *getLastValInScope() {
+    return LastValInScope;
+  }
+  void setLastValInScope(ScopedHashTableVal<K, V> *Val) {
+    LastValInScope = Val;
+  }
+};
+
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+class ScopedHashTableIterator {
+  ScopedHashTableVal<K, V> *Node;
+public:
+  ScopedHashTableIterator(ScopedHashTableVal<K, V> *node) : Node(node) {}
+
+  V &operator*() const {
+    assert(Node && "Dereference end()");
+    return Node->getValue();
+  }
+  V *operator->() const {
+    return &Node->getValue();
+  }
+
+  bool operator==(const ScopedHashTableIterator &RHS) const {
+    return Node == RHS.Node;
+  }
+  bool operator!=(const ScopedHashTableIterator &RHS) const {
+    return Node != RHS.Node;
+  }
+
+  inline ScopedHashTableIterator& operator++() {          // Preincrement
+    assert(Node && "incrementing past end()");
+    Node = Node->getNextForKey();
+    return *this;
+  }
+  ScopedHashTableIterator operator++(int) {        // Postincrement
+    ScopedHashTableIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+
+template <typename K, typename V, typename KInfo, typename AllocatorTy>
+class ScopedHashTable {
+public:
+  /// ScopeTy - This is a helpful typedef that allows clients to get easy access
+  /// to the name of the scope for this hash table.
+  typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
+  typedef unsigned size_type;

+private:
+  typedef ScopedHashTableVal<K, V> ValTy;
+  DenseMap<K, ValTy*, KInfo> TopLevelMap;
+  ScopeTy *CurScope;
+  
+  AllocatorTy Allocator;
+  
+  ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
+  void operator=(const ScopedHashTable&);  // NOT YET IMPLEMENTED
+  friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
+public:
+  ScopedHashTable() : CurScope(nullptr) {}
+  ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
+  ~ScopedHashTable() {
+    assert(!CurScope && TopLevelMap.empty() && "Scope imbalance!");
+  }
+  
+
+  /// Access to the allocator.
+  AllocatorTy &getAllocator() { return Allocator; }
+  const AllocatorTy &getAllocator() const { return Allocator; }
+
+  /// Return 1 if the specified key is in the table, 0 otherwise.

+  size_type count(const K &Key) const {
+    return TopLevelMap.count(Key);
+  }
+
+  V lookup(const K &Key) {
+    typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
+    if (I != TopLevelMap.end())
+      return I->second->getValue();
+      
+    return V();
+  }
+
+  void insert(const K &Key, const V &Val) {
+    insertIntoScope(CurScope, Key, Val);
+  }
+
+  typedef ScopedHashTableIterator<K, V, KInfo> iterator;
+
+  iterator end() { return iterator(0); }
+
+  iterator begin(const K &Key) {
+    typename DenseMap<K, ValTy*, KInfo>::iterator I =
+      TopLevelMap.find(Key);
+    if (I == TopLevelMap.end()) return end();
+    return iterator(I->second);
+  }
+  
+  ScopeTy *getCurScope() { return CurScope; }
+  const ScopeTy *getCurScope() const { return CurScope; }
+
+  /// insertIntoScope - This inserts the specified key/value at the specified
+  /// (possibly not the current) scope.  While it is ok to insert into a scope
+  /// that isn't the current one, it isn't ok to insert *underneath* an existing
+  /// value of the specified key.
+  void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) {
+    assert(S && "No scope active!");
+    ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key];
+    KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val,
+                             Allocator);
+    S->setLastValInScope(KeyEntry);
+  }
+};
+
+/// ScopedHashTableScope ctor - Install this as the current scope for the hash
+/// table.
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::
+  ScopedHashTableScope(ScopedHashTable<K, V, KInfo, Allocator> &ht) : HT(ht) {
+  PrevScope = HT.CurScope;
+  HT.CurScope = this;
+  LastValInScope = nullptr;
+}
+
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::~ScopedHashTableScope() {
+  assert(HT.CurScope == this && "Scope imbalance!");
+  HT.CurScope = PrevScope;
+
+  // Pop and delete all values corresponding to this scope.
+  while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
+    // Pop this value out of the TopLevelMap.
+    if (!ThisEntry->getNextForKey()) {
+      assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
+             "Scope imbalance!");
+      HT.TopLevelMap.erase(ThisEntry->getKey());
+    } else {
+      ScopedHashTableVal<K, V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
+      assert(KeyEntry == ThisEntry && "Scope imbalance!");
+      KeyEntry = ThisEntry->getNextForKey();
+    }
+
+    // Pop this value out of the scope.
+    LastValInScope = ThisEntry->getNextInScope();
+
+    // Delete this entry.
+    ThisEntry->Destroy(HT.getAllocator());
+  }
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h
new file mode 100644
index 0000000..71f5db3
--- /dev/null
+++ b/include/llvm/ADT/SetOperations.h
@@ -0,0 +1,71 @@
+//===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- 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 generic set operations that may be used on set's of
+// different types, and different element types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETOPERATIONS_H
+#define LLVM_ADT_SETOPERATIONS_H
+
+namespace llvm {
+
+/// set_union(A, B) - Compute A := A u B, return whether A changed.
+///
+template <class S1Ty, class S2Ty>
+bool set_union(S1Ty &S1, const S2Ty &S2) {
+  bool Changed = false;
+
+  for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+       SI != SE; ++SI)
+    if (S1.insert(*SI).second)
+      Changed = true;
+
+  return Changed;
+}
+
+/// set_intersect(A, B) - Compute A := A ^ B
+/// Identical to set_intersection, except that it works on set<>'s and
+/// is nicer to use.  Functionally, this iterates through S1, removing
+/// elements that are not contained in S2.
+///
+template <class S1Ty, class S2Ty>
+void set_intersect(S1Ty &S1, const S2Ty &S2) {
+   for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
+     const typename S1Ty::key_type &E = *I;
+     ++I;
+     if (!S2.count(E)) S1.erase(E);   // Erase element if not in S2
+   }
+}
+
+/// set_difference(A, B) - Return A - B
+///
+template <class S1Ty, class S2Ty>
+S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {
+  S1Ty Result;
+  for (typename S1Ty::const_iterator SI = S1.begin(), SE = S1.end();
+       SI != SE; ++SI)
+    if (!S2.count(*SI))       // if the element is not in set2
+      Result.insert(*SI);
+  return Result;
+}
+
+/// set_subtract(A, B) - Compute A := A - B
+///
+template <class S1Ty, class S2Ty>
+void set_subtract(S1Ty &S1, const S2Ty &S2) {
+  for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+       SI != SE; ++SI)
+    S1.erase(*SI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
new file mode 100644
index 0000000..1e7d237
--- /dev/null
+++ b/include/llvm/ADT/SetVector.h
@@ -0,0 +1,231 @@
+//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a set that has insertion order iteration
+// characteristics. This is useful for keeping a set of things that need to be
+// visited later but in a deterministic order (insertion order). The interface
+// is purposefully minimal.
+//
+// This file defines SetVector and SmallSetVector, which performs no allocations
+// if the SetVector has less than a certain number of elements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETVECTOR_H
+#define LLVM_ADT_SETVECTOR_H
+
+#include "llvm/ADT/SmallSet.h"
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+/// \brief A vector that has set insertion semantics.
+///
+/// This adapter class provides a way to keep a set of things that also has the
+/// property of a deterministic iteration order. The order of iteration is the
+/// order of insertion.
+template <typename T, typename Vector = std::vector<T>,
+                      typename Set = SmallSet<T, 16> >
+class SetVector {
+public:
+  typedef T value_type;
+  typedef T key_type;
+  typedef T& reference;
+  typedef const T& const_reference;
+  typedef Set set_type;
+  typedef Vector vector_type;
+  typedef typename vector_type::const_iterator iterator;
+  typedef typename vector_type::const_iterator const_iterator;
+  typedef typename vector_type::size_type size_type;
+
+  /// \brief Construct an empty SetVector
+  SetVector() {}
+
+  /// \brief Initialize a SetVector with a range of elements
+  template<typename It>
+  SetVector(It Start, It End) {
+    insert(Start, End);
+  }
+
+  /// \brief Determine if the SetVector is empty or not.
+  bool empty() const {
+    return vector_.empty();
+  }
+
+  /// \brief Determine the number of elements in the SetVector.
+  size_type size() const {
+    return vector_.size();
+  }
+
+  /// \brief Get an iterator to the beginning of the SetVector.
+  iterator begin() {
+    return vector_.begin();
+  }
+
+  /// \brief Get a const_iterator to the beginning of the SetVector.
+  const_iterator begin() const {
+    return vector_.begin();
+  }
+
+  /// \brief Get an iterator to the end of the SetVector.
+  iterator end() {
+    return vector_.end();
+  }
+
+  /// \brief Get a const_iterator to the end of the SetVector.
+  const_iterator end() const {
+    return vector_.end();
+  }
+
+  /// \brief Return the last element of the SetVector.
+  const T &back() const {
+    assert(!empty() && "Cannot call back() on empty SetVector!");
+    return vector_.back();
+  }
+
+  /// \brief Index into the SetVector.
+  const_reference operator[](size_type n) const {
+    assert(n < vector_.size() && "SetVector access out of range!");
+    return vector_[n];
+  }
+
+  /// \brief Insert a new element into the SetVector.
+  /// \returns true iff the element was inserted into the SetVector.
+  bool insert(const value_type &X) {
+    bool result = set_.insert(X);
+    if (result)
+      vector_.push_back(X);
+    return result;
+  }
+
+  /// \brief Insert a range of elements into the SetVector.
+  template<typename It>
+  void insert(It Start, It End) {
+    for (; Start != End; ++Start)
+      if (set_.insert(*Start))
+        vector_.push_back(*Start);
+  }
+
+  /// \brief Remove an item from the set vector.
+  bool remove(const value_type& X) {
+    if (set_.erase(X)) {
+      typename vector_type::iterator I =
+        std::find(vector_.begin(), vector_.end(), X);
+      assert(I != vector_.end() && "Corrupted SetVector instances!");
+      vector_.erase(I);
+      return true;
+    }
+    return false;
+  }
+
+  /// \brief Remove items from the set vector based on a predicate function.
+  ///
+  /// This is intended to be equivalent to the following code, if we could
+  /// write it:
+  ///
+  /// \code
+  ///   V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
+  /// \endcode
+  ///
+  /// However, SetVector doesn't expose non-const iterators, making any
+  /// algorithm like remove_if impossible to use.
+  ///
+  /// \returns true if any element is removed.
+  template <typename UnaryPredicate>
+  bool remove_if(UnaryPredicate P) {
+    typename vector_type::iterator I
+      = std::remove_if(vector_.begin(), vector_.end(),
+                       TestAndEraseFromSet<UnaryPredicate>(P, set_));
+    if (I == vector_.end())
+      return false;
+    vector_.erase(I, vector_.end());
+    return true;
+  }
+
+
+  /// \brief Count the number of elements of a given key in the SetVector.
+  /// \returns 0 if the element is not in the SetVector, 1 if it is.
+  size_type count(const key_type &key) const {
+    return set_.count(key);
+  }
+
+  /// \brief Completely clear the SetVector
+  void clear() {
+    set_.clear();
+    vector_.clear();
+  }
+
+  /// \brief Remove the last element of the SetVector.
+  void pop_back() {
+    assert(!empty() && "Cannot remove an element from an empty SetVector!");
+    set_.erase(back());
+    vector_.pop_back();
+  }
+  
+  T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
+    T Ret = back();
+    pop_back();
+    return Ret;
+  }
+
+  bool operator==(const SetVector &that) const {
+    return vector_ == that.vector_;
+  }
+
+  bool operator!=(const SetVector &that) const {
+    return vector_ != that.vector_;
+  }
+
+private:
+  /// \brief A wrapper predicate designed for use with std::remove_if.
+  ///
+  /// This predicate wraps a predicate suitable for use with std::remove_if to
+  /// call set_.erase(x) on each element which is slated for removal.
+  template <typename UnaryPredicate>
+  class TestAndEraseFromSet {
+    UnaryPredicate P;
+    set_type &set_;
+
+  public:
+    TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
+
+    template <typename ArgumentT>
+    bool operator()(const ArgumentT &Arg) {
+      if (P(Arg)) {
+        set_.erase(Arg);
+        return true;
+      }
+      return false;
+    }
+  };
+
+  set_type set_;         ///< The set.
+  vector_type vector_;   ///< The vector.
+};
+
+/// \brief A SetVector that performs no allocations if smaller than
+/// a certain size.
+template <typename T, unsigned N>
+class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
+public:
+  SmallSetVector() {}
+
+  /// \brief Initialize a SmallSetVector with a range of elements
+  template<typename It>
+  SmallSetVector(It Start, It End) {
+    this->insert(Start, End);
+  }
+};
+
+} // End llvm namespace
+
+// vim: sw=2 ai
+#endif
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
new file mode 100644
index 0000000..0922017
--- /dev/null
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -0,0 +1,605 @@
+//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===//
+//
+//                     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 SmallBitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLBITVECTOR_H
+#define LLVM_ADT_SMALLBITVECTOR_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+
+namespace llvm {
+
+/// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array),
+/// optimized for the case when the array is small.  It contains one
+/// pointer-sized field, which is directly used as a plain collection of bits
+/// when possible, or as a pointer to a larger heap-allocated array when
+/// necessary.  This allows normal "small" cases to be fast without losing
+/// generality for large inputs.
+///
+class SmallBitVector {
+  // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
+  // unnecessary level of indirection. It would be more efficient to use a
+  // pointer to memory containing size, allocation size, and the array of bits.
+  uintptr_t X;
+
+  enum {
+    // The number of bits in this class.
+    NumBaseBits = sizeof(uintptr_t) * CHAR_BIT,
+
+    // One bit is used to discriminate between small and large mode. The
+    // remaining bits are used for the small-mode representation.
+    SmallNumRawBits = NumBaseBits - 1,
+
+    // A few more bits are used to store the size of the bit set in small mode.
+    // Theoretically this is a ceil-log2. These bits are encoded in the most
+    // significant bits of the raw bits.
+    SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
+                        NumBaseBits == 64 ? 6 :
+                        SmallNumRawBits),
+
+    // The remaining bits are used to store the actual set in small mode.
+    SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
+  };
+
+public:
+  typedef unsigned size_type;

+  // Encapsulation of a single bit.
+  class reference {
+    SmallBitVector &TheVector;
+    unsigned BitPos;
+
+  public:
+    reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
+
+    reference& operator=(reference t) {
+      *this = bool(t);
+      return *this;
+    }
+
+    reference& operator=(bool t) {
+      if (t)
+        TheVector.set(BitPos);
+      else
+        TheVector.reset(BitPos);
+      return *this;
+    }
+
+    operator bool() const {
+      return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
+    }
+  };
+
+private:
+  bool isSmall() const {
+    return X & uintptr_t(1);
+  }
+
+  BitVector *getPointer() const {
+    assert(!isSmall());
+    return reinterpret_cast<BitVector *>(X);
+  }
+
+  void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
+    X = 1;
+    setSmallSize(NewSize);
+    setSmallBits(NewSmallBits);
+  }
+
+  void switchToLarge(BitVector *BV) {
+    X = reinterpret_cast<uintptr_t>(BV);
+    assert(!isSmall() && "Tried to use an unaligned pointer");
+  }
+
+  // Return all the bits used for the "small" representation; this includes
+  // bits for the size as well as the element bits.
+  uintptr_t getSmallRawBits() const {
+    assert(isSmall());
+    return X >> 1;
+  }
+
+  void setSmallRawBits(uintptr_t NewRawBits) {
+    assert(isSmall());
+    X = (NewRawBits << 1) | uintptr_t(1);
+  }
+
+  // Return the size.
+  size_t getSmallSize() const {
+    return getSmallRawBits() >> SmallNumDataBits;
+  }
+
+  void setSmallSize(size_t Size) {
+    setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
+  }
+
+  // Return the element bits.
+  uintptr_t getSmallBits() const {
+    return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
+  }
+
+  void setSmallBits(uintptr_t NewBits) {
+    setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
+                    (getSmallSize() << SmallNumDataBits));
+  }
+
+public:
+  /// SmallBitVector default ctor - Creates an empty bitvector.
+  SmallBitVector() : X(1) {}
+
+  /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
+  /// bits are initialized to the specified value.
+  explicit SmallBitVector(unsigned s, bool t = false) {
+    if (s <= SmallNumDataBits)
+      switchToSmall(t ? ~uintptr_t(0) : 0, s);
+    else
+      switchToLarge(new BitVector(s, t));
+  }
+
+  /// SmallBitVector copy ctor.
+  SmallBitVector(const SmallBitVector &RHS) {
+    if (RHS.isSmall())
+      X = RHS.X;
+    else
+      switchToLarge(new BitVector(*RHS.getPointer()));
+  }
+
+  SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
+    RHS.X = 1;
+  }
+
+  ~SmallBitVector() {
+    if (!isSmall())
+      delete getPointer();
+  }
+
+  /// empty - Tests whether there are no bits in this bitvector.
+  bool empty() const {
+    return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
+  }
+
+  /// size - Returns the number of bits in this bitvector.
+  size_t size() const {
+    return isSmall() ? getSmallSize() : getPointer()->size();
+  }
+
+  /// count - Returns the number of bits which are set.
+  size_type count() const {
+    if (isSmall()) {
+      uintptr_t Bits = getSmallBits();
+      if (NumBaseBits == 32)
+        return CountPopulation_32(Bits);
+      if (NumBaseBits == 64)
+        return CountPopulation_64(Bits);
+      llvm_unreachable("Unsupported!");
+    }
+    return getPointer()->count();
+  }
+
+  /// any - Returns true if any bit is set.
+  bool any() const {
+    if (isSmall())
+      return getSmallBits() != 0;
+    return getPointer()->any();
+  }
+
+  /// all - Returns true if all bits are set.
+  bool all() const {
+    if (isSmall())
+      return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
+    return getPointer()->all();
+  }
+
+  /// none - Returns true if none of the bits are set.
+  bool none() const {
+    if (isSmall())
+      return getSmallBits() == 0;
+    return getPointer()->none();
+  }
+
+  /// find_first - Returns the index of the first set bit, -1 if none
+  /// of the bits are set.
+  int find_first() const {
+    if (isSmall()) {
+      uintptr_t Bits = getSmallBits();
+      if (Bits == 0)
+        return -1;
+      if (NumBaseBits == 32)
+        return countTrailingZeros(Bits);
+      if (NumBaseBits == 64)
+        return countTrailingZeros(Bits);
+      llvm_unreachable("Unsupported!");
+    }
+    return getPointer()->find_first();
+  }
+
+  /// find_next - Returns the index of the next set bit following the
+  /// "Prev" bit. Returns -1 if the next set bit is not found.
+  int find_next(unsigned Prev) const {
+    if (isSmall()) {
+      uintptr_t Bits = getSmallBits();
+      // Mask off previous bits.
+      Bits &= ~uintptr_t(0) << (Prev + 1);
+      if (Bits == 0 || Prev + 1 >= getSmallSize())
+        return -1;
+      if (NumBaseBits == 32)
+        return countTrailingZeros(Bits);
+      if (NumBaseBits == 64)
+        return countTrailingZeros(Bits);
+      llvm_unreachable("Unsupported!");
+    }
+    return getPointer()->find_next(Prev);
+  }
+
+  /// clear - Clear all bits.
+  void clear() {
+    if (!isSmall())
+      delete getPointer();
+    switchToSmall(0, 0);
+  }
+
+  /// resize - Grow or shrink the bitvector.
+  void resize(unsigned N, bool t = false) {
+    if (!isSmall()) {
+      getPointer()->resize(N, t);
+    } else if (SmallNumDataBits >= N) {
+      uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
+      setSmallSize(N);
+      setSmallBits(NewBits | getSmallBits());
+    } else {
+      BitVector *BV = new BitVector(N, t);
+      uintptr_t OldBits = getSmallBits();
+      for (size_t i = 0, e = getSmallSize(); i != e; ++i)
+        (*BV)[i] = (OldBits >> i) & 1;
+      switchToLarge(BV);
+    }
+  }
+
+  void reserve(unsigned N) {
+    if (isSmall()) {
+      if (N > SmallNumDataBits) {
+        uintptr_t OldBits = getSmallRawBits();
+        size_t SmallSize = getSmallSize();
+        BitVector *BV = new BitVector(SmallSize);
+        for (size_t i = 0; i < SmallSize; ++i)
+          if ((OldBits >> i) & 1)
+            BV->set(i);
+        BV->reserve(N);
+        switchToLarge(BV);
+      }
+    } else {
+      getPointer()->reserve(N);
+    }
+  }
+
+  // Set, reset, flip
+  SmallBitVector &set() {
+    if (isSmall())
+      setSmallBits(~uintptr_t(0));
+    else
+      getPointer()->set();
+    return *this;
+  }
+
+  SmallBitVector &set(unsigned Idx) {
+    if (isSmall())
+      setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
+    else
+      getPointer()->set(Idx);
+    return *this;
+  }
+
+  /// set - Efficiently set a range of bits in [I, E)
+  SmallBitVector &set(unsigned I, unsigned E) {
+    assert(I <= E && "Attempted to set backwards range!");
+    assert(E <= size() && "Attempted to set out-of-bounds range!");
+    if (I == E) return *this;
+    if (isSmall()) {
+      uintptr_t EMask = ((uintptr_t)1) << E;
+      uintptr_t IMask = ((uintptr_t)1) << I;
+      uintptr_t Mask = EMask - IMask;
+      setSmallBits(getSmallBits() | Mask);
+    } else
+      getPointer()->set(I, E);
+    return *this;
+  }
+
+  SmallBitVector &reset() {
+    if (isSmall())
+      setSmallBits(0);
+    else
+      getPointer()->reset();
+    return *this;
+  }
+
+  SmallBitVector &reset(unsigned Idx) {
+    if (isSmall())
+      setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
+    else
+      getPointer()->reset(Idx);
+    return *this;
+  }
+
+  /// reset - Efficiently reset a range of bits in [I, E)
+  SmallBitVector &reset(unsigned I, unsigned E) {
+    assert(I <= E && "Attempted to reset backwards range!");
+    assert(E <= size() && "Attempted to reset out-of-bounds range!");
+    if (I == E) return *this;
+    if (isSmall()) {
+      uintptr_t EMask = ((uintptr_t)1) << E;
+      uintptr_t IMask = ((uintptr_t)1) << I;
+      uintptr_t Mask = EMask - IMask;
+      setSmallBits(getSmallBits() & ~Mask);
+    } else
+      getPointer()->reset(I, E);
+    return *this;
+  }
+
+  SmallBitVector &flip() {
+    if (isSmall())
+      setSmallBits(~getSmallBits());
+    else
+      getPointer()->flip();
+    return *this;
+  }
+
+  SmallBitVector &flip(unsigned Idx) {
+    if (isSmall())
+      setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
+    else
+      getPointer()->flip(Idx);
+    return *this;
+  }
+
+  // No argument flip.
+  SmallBitVector operator~() const {
+    return SmallBitVector(*this).flip();
+  }
+
+  // Indexing.
+  reference operator[](unsigned Idx) {
+    assert(Idx < size() && "Out-of-bounds Bit access.");
+    return reference(*this, Idx);
+  }
+
+  bool operator[](unsigned Idx) const {
+    assert(Idx < size() && "Out-of-bounds Bit access.");
+    if (isSmall())
+      return ((getSmallBits() >> Idx) & 1) != 0;
+    return getPointer()->operator[](Idx);
+  }
+
+  bool test(unsigned Idx) const {
+    return (*this)[Idx];
+  }
+
+  /// Test if any common bits are set.
+  bool anyCommon(const SmallBitVector &RHS) const {
+    if (isSmall() && RHS.isSmall())
+      return (getSmallBits() & RHS.getSmallBits()) != 0;
+    if (!isSmall() && !RHS.isSmall())
+      return getPointer()->anyCommon(*RHS.getPointer());
+
+    for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+      if (test(i) && RHS.test(i))
+        return true;
+    return false;
+  }
+
+  // Comparison operators.
+  bool operator==(const SmallBitVector &RHS) const {
+    if (size() != RHS.size())
+      return false;
+    if (isSmall())
+      return getSmallBits() == RHS.getSmallBits();
+    else
+      return *getPointer() == *RHS.getPointer();
+  }
+
+  bool operator!=(const SmallBitVector &RHS) const {
+    return !(*this == RHS);
+  }
+
+  // Intersection, union, disjoint union.
+  SmallBitVector &operator&=(const SmallBitVector &RHS) {
+    resize(std::max(size(), RHS.size()));
+    if (isSmall())
+      setSmallBits(getSmallBits() & RHS.getSmallBits());
+    else if (!RHS.isSmall())
+      getPointer()->operator&=(*RHS.getPointer());
+    else {
+      SmallBitVector Copy = RHS;
+      Copy.resize(size());
+      getPointer()->operator&=(*Copy.getPointer());
+    }
+    return *this;
+  }
+
+  /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
+  SmallBitVector &reset(const SmallBitVector &RHS) {
+    if (isSmall() && RHS.isSmall())
+      setSmallBits(getSmallBits() & ~RHS.getSmallBits());
+    else if (!isSmall() && !RHS.isSmall())
+      getPointer()->reset(*RHS.getPointer());
+    else
+      for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+        if (RHS.test(i))
+          reset(i);
+
+    return *this;
+  }
+
+  /// test - Check if (This - RHS) is zero.
+  /// This is the same as reset(RHS) and any().
+  bool test(const SmallBitVector &RHS) const {
+    if (isSmall() && RHS.isSmall())
+      return (getSmallBits() & ~RHS.getSmallBits()) != 0;
+    if (!isSmall() && !RHS.isSmall())
+      return getPointer()->test(*RHS.getPointer());
+
+    unsigned i, e;
+    for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+      if (test(i) && !RHS.test(i))
+        return true;
+
+    for (e = size(); i != e; ++i)
+      if (test(i))
+        return true;
+
+    return false;
+  }
+
+  SmallBitVector &operator|=(const SmallBitVector &RHS) {
+    resize(std::max(size(), RHS.size()));
+    if (isSmall())
+      setSmallBits(getSmallBits() | RHS.getSmallBits());
+    else if (!RHS.isSmall())
+      getPointer()->operator|=(*RHS.getPointer());
+    else {
+      SmallBitVector Copy = RHS;
+      Copy.resize(size());
+      getPointer()->operator|=(*Copy.getPointer());
+    }
+    return *this;
+  }
+
+  SmallBitVector &operator^=(const SmallBitVector &RHS) {
+    resize(std::max(size(), RHS.size()));
+    if (isSmall())
+      setSmallBits(getSmallBits() ^ RHS.getSmallBits());
+    else if (!RHS.isSmall())
+      getPointer()->operator^=(*RHS.getPointer());
+    else {
+      SmallBitVector Copy = RHS;
+      Copy.resize(size());
+      getPointer()->operator^=(*Copy.getPointer());
+    }
+    return *this;
+  }
+
+  // Assignment operator.
+  const SmallBitVector &operator=(const SmallBitVector &RHS) {
+    if (isSmall()) {
+      if (RHS.isSmall())
+        X = RHS.X;
+      else
+        switchToLarge(new BitVector(*RHS.getPointer()));
+    } else {
+      if (!RHS.isSmall())
+        *getPointer() = *RHS.getPointer();
+      else {
+        delete getPointer();
+        X = RHS.X;
+      }
+    }
+    return *this;
+  }
+
+  const SmallBitVector &operator=(SmallBitVector &&RHS) {
+    if (this != &RHS) {
+      clear();
+      swap(RHS);
+    }
+    return *this;
+  }
+
+  void swap(SmallBitVector &RHS) {
+    std::swap(X, RHS.X);
+  }
+
+  /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
+  /// This computes "*this |= Mask".
+  void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    if (isSmall())
+      applyMask<true, false>(Mask, MaskWords);
+    else
+      getPointer()->setBitsInMask(Mask, MaskWords);
+  }
+
+  /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
+  /// Don't resize. This computes "*this &= ~Mask".
+  void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    if (isSmall())
+      applyMask<false, false>(Mask, MaskWords);
+    else
+      getPointer()->clearBitsInMask(Mask, MaskWords);
+  }
+
+  /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
+  /// Don't resize.  This computes "*this |= ~Mask".
+  void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    if (isSmall())
+      applyMask<true, true>(Mask, MaskWords);
+    else
+      getPointer()->setBitsNotInMask(Mask, MaskWords);
+  }
+
+  /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
+  /// Don't resize.  This computes "*this &= Mask".
+  void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+    if (isSmall())
+      applyMask<false, true>(Mask, MaskWords);
+    else
+      getPointer()->clearBitsNotInMask(Mask, MaskWords);
+  }
+
+private:
+  template<bool AddBits, bool InvertMask>
+  void applyMask(const uint32_t *Mask, unsigned MaskWords) {
+    assert((NumBaseBits == 64 || NumBaseBits == 32) && "Unsupported word size");
+    if (NumBaseBits == 64 && MaskWords >= 2) {
+      uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
+      if (InvertMask) M = ~M;
+      if (AddBits) setSmallBits(getSmallBits() | M);
+      else         setSmallBits(getSmallBits() & ~M);
+    } else {
+      uint32_t M = Mask[0];
+      if (InvertMask) M = ~M;
+      if (AddBits) setSmallBits(getSmallBits() | M);
+      else         setSmallBits(getSmallBits() & ~M);
+    }
+  }
+};
+
+inline SmallBitVector
+operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+  SmallBitVector Result(LHS);
+  Result &= RHS;
+  return Result;
+}
+
+inline SmallBitVector
+operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+  SmallBitVector Result(LHS);
+  Result |= RHS;
+  return Result;
+}
+
+inline SmallBitVector
+operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+  SmallBitVector Result(LHS);
+  Result ^= RHS;
+  return Result;
+}
+
+} // End llvm namespace
+
+namespace std {
+  /// Implement std::swap in terms of BitVector swap.
+  inline void
+  swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
+    LHS.swap(RHS);
+  }
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
new file mode 100644
index 0000000..74f3fd4
--- /dev/null
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -0,0 +1,340 @@
+//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- 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 SmallPtrSet class.  See the doxygen comment for
+// SmallPtrSetImplBase for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLPTRSET_H
+#define LLVM_ADT_SMALLPTRSET_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+
+namespace llvm {
+
+class SmallPtrSetIteratorImpl;
+
+/// SmallPtrSetImplBase - This is the common code shared among all the
+/// SmallPtrSet<>'s, which is almost everything.  SmallPtrSet has two modes, one
+/// for small and one for large sets.
+///
+/// Small sets use an array of pointers allocated in the SmallPtrSet object,
+/// which is treated as a simple array of pointers.  When a pointer is added to
+/// the set, the array is scanned to see if the element already exists, if not
+/// the element is 'pushed back' onto the array.  If we run out of space in the
+/// array, we grow into the 'large set' case.  SmallSet should be used when the
+/// sets are often small.  In this case, no memory allocation is used, and only
+/// light-weight and cache-efficient scanning is used.
+///
+/// Large sets use a classic exponentially-probed hash table.  Empty buckets are
+/// represented with an illegal pointer value (-1) to allow null pointers to be
+/// inserted.  Tombstones are represented with another illegal pointer value
+/// (-2), to allow deletion.  The hash table is resized when the table is 3/4 or
+/// more.  When this happens, the table is doubled in size.
+///
+class SmallPtrSetImplBase {
+  friend class SmallPtrSetIteratorImpl;
+protected:
+  /// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
+  const void **SmallArray;
+  /// CurArray - This is the current set of buckets.  If equal to SmallArray,
+  /// then the set is in 'small mode'.
+  const void **CurArray;
+  /// CurArraySize - The allocated size of CurArray, always a power of two.
+  unsigned CurArraySize;
+
+  // If small, this is # elts allocated consecutively
+  unsigned NumElements;
+  unsigned NumTombstones;
+
+  // Helpers to copy and move construct a SmallPtrSet.
+  SmallPtrSetImplBase(const void **SmallStorage, const SmallPtrSetImplBase &that);
+  SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
+                  SmallPtrSetImplBase &&that);
+  explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize) :
+    SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
+    assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
+           "Initial size must be a power of two!");
+    clear();
+  }
+  ~SmallPtrSetImplBase();
+
+public:
+  typedef unsigned size_type;
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; }
+  size_type size() const { return NumElements; }
+
+  void clear() {
+    // If the capacity of the array is huge, and the # elements used is small,
+    // shrink the array.
+    if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
+      return shrink_and_clear();
+
+    // Fill the array with empty markers.
+    memset(CurArray, -1, CurArraySize*sizeof(void*));
+    NumElements = 0;
+    NumTombstones = 0;
+  }
+
+protected:
+  static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
+  static void *getEmptyMarker() {
+    // Note that -1 is chosen to make clear() efficiently implementable with
+    // memset and because it's not a valid pointer value.
+    return reinterpret_cast<void*>(-1);
+  }
+
+  /// insert_imp - This returns true if the pointer was new to the set, false if
+  /// it was already in the set.  This is hidden from the client so that the
+  /// derived class can check that the right type of pointer is passed in.
+  bool insert_imp(const void * Ptr);
+
+  /// erase_imp - If the set contains the specified pointer, remove it and
+  /// return true, otherwise return false.  This is hidden from the client so
+  /// that the derived class can check that the right type of pointer is passed
+  /// in.
+  bool erase_imp(const void * Ptr);
+
+  bool count_imp(const void * Ptr) const {
+    if (isSmall()) {
+      // Linear search for the item.
+      for (const void *const *APtr = SmallArray,
+                      *const *E = SmallArray+NumElements; APtr != E; ++APtr)
+        if (*APtr == Ptr)
+          return true;
+      return false;
+    }
+
+    // Big set case.
+    return *FindBucketFor(Ptr) == Ptr;
+  }
+
+private:
+  bool isSmall() const { return CurArray == SmallArray; }
+
+  const void * const *FindBucketFor(const void *Ptr) const;
+  void shrink_and_clear();
+
+  /// Grow - Allocate a larger backing store for the buckets and move it over.
+  void Grow(unsigned NewSize);
+
+  void operator=(const SmallPtrSetImplBase &RHS) LLVM_DELETED_FUNCTION;
+protected:
+  /// swap - Swaps the elements of two sets.
+  /// Note: This method assumes that both sets have the same small size.
+  void swap(SmallPtrSetImplBase &RHS);
+
+  void CopyFrom(const SmallPtrSetImplBase &RHS);
+  void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS);
+};
+
+/// SmallPtrSetIteratorImpl - This is the common base class shared between all
+/// instances of SmallPtrSetIterator.
+class SmallPtrSetIteratorImpl {
+protected:
+  const void *const *Bucket;
+  const void *const *End;
+public:
+  explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
+    : Bucket(BP), End(E) {
+      AdvanceIfNotValid();
+  }
+
+  bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
+    return Bucket == RHS.Bucket;
+  }
+  bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
+    return Bucket != RHS.Bucket;
+  }
+
+protected:
+  /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
+  /// that is.   This is guaranteed to stop because the end() bucket is marked
+  /// valid.
+  void AdvanceIfNotValid() {
+    assert(Bucket <= End);
+    while (Bucket != End &&
+           (*Bucket == SmallPtrSetImplBase::getEmptyMarker() ||
+            *Bucket == SmallPtrSetImplBase::getTombstoneMarker()))
+      ++Bucket;
+  }
+};
+
+/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
+template<typename PtrTy>
+class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
+  typedef PointerLikeTypeTraits<PtrTy> PtrTraits;
+  
+public:
+  typedef PtrTy                     value_type;
+  typedef PtrTy                     reference;
+  typedef PtrTy                     pointer;
+  typedef std::ptrdiff_t            difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+  
+  explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
+    : SmallPtrSetIteratorImpl(BP, E) {}
+
+  // Most methods provided by baseclass.
+
+  const PtrTy operator*() const {
+    assert(Bucket < End);
+    return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
+  }
+
+  inline SmallPtrSetIterator& operator++() {          // Preincrement
+    ++Bucket;
+    AdvanceIfNotValid();
+    return *this;
+  }
+
+  SmallPtrSetIterator operator++(int) {        // Postincrement
+    SmallPtrSetIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+/// RoundUpToPowerOfTwo - This is a helper template that rounds N up to the next
+/// power of two (which means N itself if N is already a power of two).
+template<unsigned N>
+struct RoundUpToPowerOfTwo;
+
+/// RoundUpToPowerOfTwoH - If N is not a power of two, increase it.  This is a
+/// helper template used to implement RoundUpToPowerOfTwo.
+template<unsigned N, bool isPowerTwo>
+struct RoundUpToPowerOfTwoH {
+  enum { Val = N };
+};
+template<unsigned N>
+struct RoundUpToPowerOfTwoH<N, false> {
+  enum {
+    // We could just use NextVal = N+1, but this converges faster.  N|(N-1) sets
+    // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
+    Val = RoundUpToPowerOfTwo<(N|(N-1)) + 1>::Val
+  };
+};
+
+template<unsigned N>
+struct RoundUpToPowerOfTwo {
+  enum { Val = RoundUpToPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
+};
+  
+
+/// \brief A templated base class for \c SmallPtrSet which provides the
+/// typesafe interface that is common across all small sizes.
+///
+/// This is particularly useful for passing around between interface boundaries
+/// to avoid encoding a particular small size in the interface boundary.
+template <typename PtrType>
+class SmallPtrSetImpl : public SmallPtrSetImplBase {
+  typedef PointerLikeTypeTraits<PtrType> PtrTraits;
+protected:
+  // Constructors that forward to the base.
+  SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
+      : SmallPtrSetImplBase(SmallStorage, that) {}
+  SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
+                  SmallPtrSetImpl &&that)
+      : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {}
+  explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize)
+      : SmallPtrSetImplBase(SmallStorage, SmallSize) {}
+
+public:
+  /// insert - This returns true if the pointer was new to the set, false if it
+  /// was already in the set.
+  bool insert(PtrType Ptr) {
+    return insert_imp(PtrTraits::getAsVoidPointer(Ptr));
+  }
+
+  /// erase - If the set contains the specified pointer, remove it and return
+  /// true, otherwise return false.
+  bool erase(PtrType Ptr) {
+    return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
+  }
+
+  /// count - Return 1 if the specified pointer is in the set, 0 otherwise.
+  size_type count(PtrType Ptr) const {
+    return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
+  }
+
+  template <typename IterT>
+  void insert(IterT I, IterT E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+
+  typedef SmallPtrSetIterator<PtrType> iterator;
+  typedef SmallPtrSetIterator<PtrType> const_iterator;
+  inline iterator begin() const {
+    return iterator(CurArray, CurArray+CurArraySize);
+  }
+  inline iterator end() const {
+    return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
+  }
+};
+
+/// SmallPtrSet - This class implements a set which is optimized for holding
+/// SmallSize or less elements.  This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two.  See the comments above
+/// SmallPtrSetImplBase for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
+  typedef SmallPtrSetImpl<PtrType> BaseT;
+
+  // Make sure that SmallSize is a power of two, round up if not.
+  enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
+  /// SmallStorage - Fixed size storage used in 'small mode'.
+  const void *SmallStorage[SmallSizePowTwo];
+public:
+  SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {}
+  SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {}
+  SmallPtrSet(SmallPtrSet &&that)
+      : BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {}
+
+  template<typename It>
+  SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
+    this->insert(I, E);
+  }
+
+  SmallPtrSet<PtrType, SmallSize> &
+  operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
+    if (&RHS != this)
+      this->CopyFrom(RHS);
+    return *this;
+  }
+
+  SmallPtrSet<PtrType, SmallSize>&
+  operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
+    if (&RHS != this)
+      this->MoveFrom(SmallSizePowTwo, std::move(RHS));
+    return *this;
+  }
+
+  /// swap - Swaps the elements of two sets.
+  void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
+    SmallPtrSetImplBase::swap(RHS);
+  }
+};
+
+}
+
+namespace std {
+  /// Implement std::swap in terms of SmallPtrSet swap.
+  template<class T, unsigned N>
+  inline void swap(llvm::SmallPtrSet<T, N> &LHS, llvm::SmallPtrSet<T, N> &RHS) {
+    LHS.swap(RHS);
+  }
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
new file mode 100644
index 0000000..bb1971e
--- /dev/null
+++ b/include/llvm/ADT/SmallSet.h
@@ -0,0 +1,123 @@
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- 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 SmallSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSET_H
+#define LLVM_ADT_SMALLSET_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <set>
+
+namespace llvm {
+
+/// SmallSet - This maintains a set of unique values, optimizing for the case
+/// when the set is small (less than N).  In this case, the set can be
+/// maintained with no mallocs.  If the set gets large, we expand to using an
+/// std::set to maintain reasonable lookup times.
+///
+/// Note that this set does not provide a way to iterate over members in the
+/// set.
+template <typename T, unsigned N,  typename C = std::less<T> >
+class SmallSet {
+  /// Use a SmallVector to hold the elements here (even though it will never
+  /// reach its 'large' stage) to avoid calling the default ctors of elements
+  /// we will never use.
+  SmallVector<T, N> Vector;
+  std::set<T, C> Set;
+  typedef typename SmallVector<T, N>::const_iterator VIterator;
+  typedef typename SmallVector<T, N>::iterator mutable_iterator;
+public:
+  typedef size_t size_type;
+  SmallSet() {}
+
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
+    return Vector.empty() && Set.empty();
+  }
+
+  size_type size() const {
+    return isSmall() ? Vector.size() : Set.size();
+  }
+
+  /// count - Return 1 if the element is in the set, 0 otherwise.
+  size_type count(const T &V) const {
+    if (isSmall()) {
+      // Since the collection is small, just do a linear search.
+      return vfind(V) == Vector.end() ? 0 : 1;
+    } else {
+      return Set.count(V);
+    }
+  }
+
+  /// insert - Insert an element into the set if it isn't already there.
+  /// Returns true if the element is inserted (it was not in the set before).
+  bool insert(const T &V) {
+    if (!isSmall())
+      return Set.insert(V).second;
+
+    VIterator I = vfind(V);
+    if (I != Vector.end())    // Don't reinsert if it already exists.
+      return false;
+    if (Vector.size() < N) {
+      Vector.push_back(V);
+      return true;
+    }
+
+    // Otherwise, grow from vector to set.
+    while (!Vector.empty()) {
+      Set.insert(Vector.back());
+      Vector.pop_back();
+    }
+    Set.insert(V);
+    return true;
+  }
+
+  template <typename IterT>
+  void insert(IterT I, IterT E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+  
+  bool erase(const T &V) {
+    if (!isSmall())
+      return Set.erase(V);
+    for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+      if (*I == V) {
+        Vector.erase(I);
+        return true;
+      }
+    return false;
+  }
+
+  void clear() {
+    Vector.clear();
+    Set.clear();
+  }
+private:
+  bool isSmall() const { return Set.empty(); }
+
+  VIterator vfind(const T &V) const {
+    for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+      if (*I == V)
+        return I;
+    return Vector.end();
+  }
+};
+
+/// If this set is of pointer values, transparently switch over to using
+/// SmallPtrSet for performance.
+template <typename PointeeType, unsigned N>
+class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
new file mode 100644
index 0000000..e569f54
--- /dev/null
+++ b/include/llvm/ADT/SmallString.h
@@ -0,0 +1,297 @@
+//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- 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 SmallString class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSTRING_H
+#define LLVM_ADT_SMALLSTRING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// SmallString - A SmallString is just a SmallVector with methods and accessors
+/// that make it work better as a string (e.g. operator+ etc).
+template<unsigned InternalLen>
+class SmallString : public SmallVector<char, InternalLen> {
+public:
+  /// Default ctor - Initialize to empty.
+  SmallString() {}
+
+  /// Initialize from a StringRef.
+  SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
+
+  /// Initialize with a range.
+  template<typename ItTy>
+  SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
+
+  // Note that in order to add new overloads for append & assign, we have to
+  // duplicate the inherited versions so as not to inadvertently hide them.
+
+  /// @}
+  /// @name String Assignment
+  /// @{
+
+  /// Assign from a repeated element.
+  void assign(size_t NumElts, char Elt) {
+    this->SmallVectorImpl<char>::assign(NumElts, Elt);
+  }
+
+  /// Assign from an iterator pair.
+  template<typename in_iter>
+  void assign(in_iter S, in_iter E) {
+    this->clear();
+    SmallVectorImpl<char>::append(S, E);
+  }
+
+  /// Assign from a StringRef.
+  void assign(StringRef RHS) {
+    this->clear();
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// Assign from a SmallVector.
+  void assign(const SmallVectorImpl<char> &RHS) {
+    this->clear();
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// @}
+  /// @name String Concatenation
+  /// @{
+
+  /// Append from an iterator pair.
+  template<typename in_iter>
+  void append(in_iter S, in_iter E) {
+    SmallVectorImpl<char>::append(S, E);
+  }
+
+  void append(size_t NumInputs, char Elt) {
+    SmallVectorImpl<char>::append(NumInputs, Elt);
+  }
+
+
+  /// Append from a StringRef.
+  void append(StringRef RHS) {
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// Append from a SmallVector.
+  void append(const SmallVectorImpl<char> &RHS) {
+    SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+  }
+
+  /// @}
+  /// @name String Comparison
+  /// @{
+
+  /// Check for string equality.  This is more efficient than compare() when
+  /// the relative ordering of inequal strings isn't needed.
+  bool equals(StringRef RHS) const {
+    return str().equals(RHS);
+  }
+
+  /// Check for string equality, ignoring case.
+  bool equals_lower(StringRef RHS) const {
+    return str().equals_lower(RHS);
+  }
+
+  /// Compare two strings; the result is -1, 0, or 1 if this string is
+  /// lexicographically less than, equal to, or greater than the \p RHS.
+  int compare(StringRef RHS) const {
+    return str().compare(RHS);
+  }
+
+  /// compare_lower - Compare two strings, ignoring case.
+  int compare_lower(StringRef RHS) const {
+    return str().compare_lower(RHS);
+  }
+
+  /// compare_numeric - Compare two strings, treating sequences of digits as
+  /// numbers.
+  int compare_numeric(StringRef RHS) const {
+    return str().compare_numeric(RHS);
+  }
+
+  /// @}
+  /// @name String Predicates
+  /// @{
+
+  /// startswith - Check if this string starts with the given \p Prefix.
+  bool startswith(StringRef Prefix) const {
+    return str().startswith(Prefix);
+  }
+
+  /// endswith - Check if this string ends with the given \p Suffix.
+  bool endswith(StringRef Suffix) const {
+    return str().endswith(Suffix);
+  }
+
+  /// @}
+  /// @name String Searching
+  /// @{
+
+  /// find - Search for the first character \p C in the string.
+  ///
+  /// \return - The index of the first occurrence of \p C, or npos if not
+  /// found.
+  size_t find(char C, size_t From = 0) const {
+    return str().find(C, From);
+  }
+
+  /// Search for the first string \p Str in the string.
+  ///
+  /// \returns The index of the first occurrence of \p Str, or npos if not
+  /// found.
+  size_t find(StringRef Str, size_t From = 0) const {
+    return str().find(Str, From);
+  }
+
+  /// Search for the last character \p C in the string.
+  ///
+  /// \returns The index of the last occurrence of \p C, or npos if not
+  /// found.
+  size_t rfind(char C, size_t From = StringRef::npos) const {
+    return str().rfind(C, From);
+  }
+
+  /// Search for the last string \p Str in the string.
+  ///
+  /// \returns The index of the last occurrence of \p Str, or npos if not
+  /// found.
+  size_t rfind(StringRef Str) const {
+    return str().rfind(Str);
+  }
+
+  /// Find the first character in the string that is \p C, or npos if not
+  /// found. Same as find.
+  size_t find_first_of(char C, size_t From = 0) const {
+    return str().find_first_of(C, From);
+  }
+
+  /// Find the first character in the string that is in \p Chars, or npos if
+  /// not found.
+  ///
+  /// Complexity: O(size() + Chars.size())
+  size_t find_first_of(StringRef Chars, size_t From = 0) const {
+    return str().find_first_of(Chars, From);
+  }
+
+  /// Find the first character in the string that is not \p C or npos if not
+  /// found.
+  size_t find_first_not_of(char C, size_t From = 0) const {
+    return str().find_first_not_of(C, From);
+  }
+
+  /// Find the first character in the string that is not in the string
+  /// \p Chars, or npos if not found.
+  ///
+  /// Complexity: O(size() + Chars.size())
+  size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
+    return str().find_first_not_of(Chars, From);
+  }
+
+  /// Find the last character in the string that is \p C, or npos if not
+  /// found.
+  size_t find_last_of(char C, size_t From = StringRef::npos) const {
+    return str().find_last_of(C, From);
+  }
+
+  /// Find the last character in the string that is in \p C, or npos if not
+  /// found.
+  ///
+  /// Complexity: O(size() + Chars.size())
+  size_t find_last_of(
+      StringRef Chars, size_t From = StringRef::npos) const {
+    return str().find_last_of(Chars, From);
+  }
+
+  /// @}
+  /// @name Helpful Algorithms
+  /// @{
+
+  /// Return the number of occurrences of \p C in the string.
+  size_t count(char C) const {
+    return str().count(C);
+  }
+
+  /// Return the number of non-overlapped occurrences of \p Str in the
+  /// string.
+  size_t count(StringRef Str) const {
+    return str().count(Str);
+  }
+
+  /// @}
+  /// @name Substring Operations
+  /// @{
+
+  /// Return a reference to the substring from [Start, Start + N).
+  ///
+  /// \param Start The index of the starting character in the substring; if
+  /// the index is npos or greater than the length of the string then the
+  /// empty substring will be returned.
+  ///
+  /// \param N The number of characters to included in the substring. If \p N
+  /// exceeds the number of characters remaining in the string, the string
+  /// suffix (starting with \p Start) will be returned.
+  StringRef substr(size_t Start, size_t N = StringRef::npos) const {
+    return str().substr(Start, N);
+  }
+
+  /// Return a reference to the substring from [Start, End).
+  ///
+  /// \param Start The index of the starting character in the substring; if
+  /// the index is npos or greater than the length of the string then the
+  /// empty substring will be returned.
+  ///
+  /// \param End The index following the last character to include in the
+  /// substring. If this is npos, or less than \p Start, or exceeds the
+  /// number of characters remaining in the string, the string suffix
+  /// (starting with \p Start) will be returned.
+  StringRef slice(size_t Start, size_t End) const {
+    return str().slice(Start, End);
+  }
+
+  // Extra methods.
+
+  /// Explicit conversion to StringRef.
+  StringRef str() const { return StringRef(this->begin(), this->size()); }
+
+  // TODO: Make this const, if it's safe...
+  const char* c_str() {
+    this->push_back(0);
+    this->pop_back();
+    return this->data();
+  }
+
+  /// Implicit conversion to StringRef.
+  operator StringRef() const { return str(); }
+
+  // Extra operators.
+  const SmallString &operator=(StringRef RHS) {
+    this->clear();
+    return *this += RHS;
+  }
+
+  SmallString &operator+=(StringRef RHS) {
+    this->append(RHS.begin(), RHS.end());
+    return *this;
+  }
+  SmallString &operator+=(char C) {
+    this->push_back(C);
+    return *this;
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
new file mode 100644
index 0000000..82538e9
--- /dev/null
+++ b/include/llvm/ADT/SmallVector.h
@@ -0,0 +1,912 @@
+//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- 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 SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLVECTOR_H
+#define LLVM_ADT_SMALLVECTOR_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <iterator>
+#include <memory>
+
+namespace llvm {
+
+/// SmallVectorBase - This is all the non-templated stuff common to all
+/// SmallVectors.
+class SmallVectorBase {
+protected:
+  void *BeginX, *EndX, *CapacityX;
+
+protected:
+  SmallVectorBase(void *FirstEl, size_t Size)
+    : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
+
+  /// grow_pod - This is an implementation of the grow() method which only works
+  /// on POD-like data types and is out of line to reduce code duplication.
+  void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
+
+public:
+  /// size_in_bytes - This returns size()*sizeof(T).
+  size_t size_in_bytes() const {
+    return size_t((char*)EndX - (char*)BeginX);
+  }
+
+  /// capacity_in_bytes - This returns capacity()*sizeof(T).
+  size_t capacity_in_bytes() const {
+    return size_t((char*)CapacityX - (char*)BeginX);
+  }
+
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; }
+};
+
+template <typename T, unsigned N> struct SmallVectorStorage;
+
+/// SmallVectorTemplateCommon - This is the part of SmallVectorTemplateBase
+/// which does not depend on whether the type T is a POD. The extra dummy
+/// template argument is used by ArrayRef to avoid unnecessarily requiring T
+/// to be complete.
+template <typename T, typename = void>
+class SmallVectorTemplateCommon : public SmallVectorBase {
+private:
+  template <typename, unsigned> friend struct SmallVectorStorage;
+
+  // Allocate raw space for N elements of type T.  If T has a ctor or dtor, we
+  // don't want it to be automatically run, so we need to represent the space as
+  // something else.  Use an array of char of sufficient alignment.
+  typedef llvm::AlignedCharArrayUnion<T> U;
+  U FirstEl;
+  // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
+
+protected:
+  SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
+
+  void grow_pod(size_t MinSizeInBytes, size_t TSize) {
+    SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
+  }
+
+  /// isSmall - Return true if this is a smallvector which has not had dynamic
+  /// memory allocated for it.
+  bool isSmall() const {
+    return BeginX == static_cast<const void*>(&FirstEl);
+  }
+
+  /// resetToSmall - Put this vector in a state of being small.
+  void resetToSmall() {
+    BeginX = EndX = CapacityX = &FirstEl;
+  }
+
+  void setEnd(T *P) { this->EndX = P; }
+public:
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T value_type;
+  typedef T *iterator;
+  typedef const T *const_iterator;
+
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+
+  typedef T &reference;
+  typedef const T &const_reference;
+  typedef T *pointer;
+  typedef const T *const_pointer;
+
+  // forward iterator creation methods.
+  iterator begin() { return (iterator)this->BeginX; }
+  const_iterator begin() const { return (const_iterator)this->BeginX; }
+  iterator end() { return (iterator)this->EndX; }
+  const_iterator end() const { return (const_iterator)this->EndX; }
+protected:
+  iterator capacity_ptr() { return (iterator)this->CapacityX; }
+  const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
+public:
+
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+  size_type size() const { return end()-begin(); }
+  size_type max_size() const { return size_type(-1) / sizeof(T); }
+
+  /// capacity - Return the total number of elements in the currently allocated
+  /// buffer.
+  size_t capacity() const { return capacity_ptr() - begin(); }
+
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  pointer data() { return pointer(begin()); }
+  /// data - Return a pointer to the vector's buffer, even if empty().
+  const_pointer data() const { return const_pointer(begin()); }
+
+  reference operator[](unsigned idx) {
+    assert(begin() + idx < end());
+    return begin()[idx];
+  }
+  const_reference operator[](unsigned idx) const {
+    assert(begin() + idx < end());
+    return begin()[idx];
+  }
+
+  reference front() {
+    assert(!empty());
+    return begin()[0];
+  }
+  const_reference front() const {
+    assert(!empty());
+    return begin()[0];
+  }
+
+  reference back() {
+    assert(!empty());
+    return end()[-1];
+  }
+  const_reference back() const {
+    assert(!empty());
+    return end()[-1];
+  }
+};
+
+/// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
+/// implementations that are designed to work with non-POD-like T's.
+template <typename T, bool isPodLike>
+class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
+protected:
+  SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
+
+  static void destroy_range(T *S, T *E) {
+    while (S != E) {
+      --E;
+      E->~T();
+    }
+  }
+
+  /// move - Use move-assignment to move the range [I, E) onto the
+  /// objects starting with "Dest".  This is just <memory>'s
+  /// std::move, but not all stdlibs actually provide that.
+  template<typename It1, typename It2>
+  static It2 move(It1 I, It1 E, It2 Dest) {
+    for (; I != E; ++I, ++Dest)
+      *Dest = ::std::move(*I);
+    return Dest;
+  }
+
+  /// move_backward - Use move-assignment to move the range
+  /// [I, E) onto the objects ending at "Dest", moving objects
+  /// in reverse order.  This is just <algorithm>'s
+  /// std::move_backward, but not all stdlibs actually provide that.
+  template<typename It1, typename It2>
+  static It2 move_backward(It1 I, It1 E, It2 Dest) {
+    while (I != E)
+      *--Dest = ::std::move(*--E);
+    return Dest;
+  }
+
+  /// uninitialized_move - Move the range [I, E) into the uninitialized
+  /// memory starting with "Dest", constructing elements as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_move(It1 I, It1 E, It2 Dest) {
+    for (; I != E; ++I, ++Dest)
+      ::new ((void*) &*Dest) T(::std::move(*I));
+  }
+
+  /// uninitialized_copy - Copy the range [I, E) onto the uninitialized
+  /// memory starting with "Dest", constructing elements as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+    std::uninitialized_copy(I, E, Dest);
+  }
+
+  /// grow - Grow the allocated memory (without initializing new
+  /// elements), doubling the size of the allocated memory.
+  /// Guarantees space for at least one more element, or MinSize more
+  /// elements if specified.
+  void grow(size_t MinSize = 0);
+
+public:
+  void push_back(const T &Elt) {
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    ::new ((void*) this->end()) T(Elt);
+    this->setEnd(this->end()+1);
+  }
+
+  void push_back(T &&Elt) {
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    ::new ((void*) this->end()) T(::std::move(Elt));
+    this->setEnd(this->end()+1);
+  }
+
+  void pop_back() {
+    this->setEnd(this->end()-1);
+    this->end()->~T();
+  }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T, bool isPodLike>
+void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
+  size_t CurCapacity = this->capacity();
+  size_t CurSize = this->size();
+  // Always grow, even from zero.
+  size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
+  if (NewCapacity < MinSize)
+    NewCapacity = MinSize;
+  T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
+
+  // Move the elements over.
+  this->uninitialized_move(this->begin(), this->end(), NewElts);
+
+  // Destroy the original elements.
+  destroy_range(this->begin(), this->end());
+
+  // If this wasn't grown from the inline copy, deallocate the old space.
+  if (!this->isSmall())
+    free(this->begin());
+
+  this->setEnd(NewElts+CurSize);
+  this->BeginX = NewElts;
+  this->CapacityX = this->begin()+NewCapacity;
+}
+
+
+/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
+/// implementations that are designed to work with POD-like T's.
+template <typename T>
+class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
+protected:
+  SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
+
+  // No need to do a destroy loop for POD's.
+  static void destroy_range(T *, T *) {}
+
+  /// move - Use move-assignment to move the range [I, E) onto the
+  /// objects starting with "Dest".  For PODs, this is just memcpy.
+  template<typename It1, typename It2>
+  static It2 move(It1 I, It1 E, It2 Dest) {
+    return ::std::copy(I, E, Dest);
+  }
+
+  /// move_backward - Use move-assignment to move the range
+  /// [I, E) onto the objects ending at "Dest", moving objects
+  /// in reverse order.
+  template<typename It1, typename It2>
+  static It2 move_backward(It1 I, It1 E, It2 Dest) {
+    return ::std::copy_backward(I, E, Dest);
+  }
+
+  /// uninitialized_move - Move the range [I, E) onto the uninitialized memory
+  /// starting with "Dest", constructing elements into it as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_move(It1 I, It1 E, It2 Dest) {
+    // Just do a copy.
+    uninitialized_copy(I, E, Dest);
+  }
+
+  /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+  /// starting with "Dest", constructing elements into it as needed.
+  template<typename It1, typename It2>
+  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+    // Arbitrary iterator types; just use the basic implementation.
+    std::uninitialized_copy(I, E, Dest);
+  }
+
+  /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+  /// starting with "Dest", constructing elements into it as needed.
+  template<typename T1, typename T2>
+  static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) {
+    // Use memcpy for PODs iterated by pointers (which includes SmallVector
+    // iterators): std::uninitialized_copy optimizes to memmove, but we can
+    // use memcpy here.
+    memcpy(Dest, I, (E-I)*sizeof(T));
+  }
+
+  /// grow - double the size of the allocated memory, guaranteeing space for at
+  /// least one more element or MinSize if specified.
+  void grow(size_t MinSize = 0) {
+    this->grow_pod(MinSize*sizeof(T), sizeof(T));
+  }
+public:
+  void push_back(const T &Elt) {
+    if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+      this->grow();
+    memcpy(this->end(), &Elt, sizeof(T));
+    this->setEnd(this->end()+1);
+  }
+
+  void pop_back() {
+    this->setEnd(this->end()-1);
+  }
+};
+
+
+/// SmallVectorImpl - This class consists of common code factored out of the
+/// SmallVector class to reduce code duplication based on the SmallVector 'N'
+/// template parameter.
+template <typename T>
+class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
+  typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
+
+  SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
+public:
+  typedef typename SuperClass::iterator iterator;
+  typedef typename SuperClass::size_type size_type;
+
+protected:
+  // Default ctor - Initialize to empty.
+  explicit SmallVectorImpl(unsigned N)
+    : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
+  }
+
+public:
+  ~SmallVectorImpl() {
+    // Destroy the constructed elements in the vector.
+    this->destroy_range(this->begin(), this->end());
+
+    // If this wasn't grown from the inline copy, deallocate the old space.
+    if (!this->isSmall())
+      free(this->begin());
+  }
+
+
+  void clear() {
+    this->destroy_range(this->begin(), this->end());
+    this->EndX = this->BeginX;
+  }
+
+  void resize(unsigned N) {
+    if (N < this->size()) {
+      this->destroy_range(this->begin()+N, this->end());
+      this->setEnd(this->begin()+N);
+    } else if (N > this->size()) {
+      if (this->capacity() < N)
+        this->grow(N);
+      for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
+        new (&*I) T();
+      this->setEnd(this->begin()+N);
+    }
+  }
+
+  void resize(unsigned N, const T &NV) {
+    if (N < this->size()) {
+      this->destroy_range(this->begin()+N, this->end());
+      this->setEnd(this->begin()+N);
+    } else if (N > this->size()) {
+      if (this->capacity() < N)
+        this->grow(N);
+      std::uninitialized_fill(this->end(), this->begin()+N, NV);
+      this->setEnd(this->begin()+N);
+    }
+  }
+
+  void reserve(unsigned N) {
+    if (this->capacity() < N)
+      this->grow(N);
+  }
+
+  T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
+    T Result = ::std::move(this->back());
+    this->pop_back();
+    return Result;
+  }
+
+  void swap(SmallVectorImpl &RHS);
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  template<typename in_iter>
+  void append(in_iter in_start, in_iter in_end) {
+    size_type NumInputs = std::distance(in_start, in_end);
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(this->size()+NumInputs);
+
+    // Copy the new elements over.
+    // TODO: NEED To compile time dispatch on whether in_iter is a random access
+    // iterator to use the fast uninitialized_copy.
+    std::uninitialized_copy(in_start, in_end, this->end());
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  /// append - Add the specified range to the end of the SmallVector.
+  ///
+  void append(size_type NumInputs, const T &Elt) {
+    // Grow allocated space if needed.
+    if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+      this->grow(this->size()+NumInputs);
+
+    // Copy the new elements over.
+    std::uninitialized_fill_n(this->end(), NumInputs, Elt);
+    this->setEnd(this->end() + NumInputs);
+  }
+
+  void assign(unsigned NumElts, const T &Elt) {
+    clear();
+    if (this->capacity() < NumElts)
+      this->grow(NumElts);
+    this->setEnd(this->begin()+NumElts);
+    std::uninitialized_fill(this->begin(), this->end(), Elt);
+  }
+
+  iterator erase(iterator I) {
+    assert(I >= this->begin() && "Iterator to erase is out of bounds.");
+    assert(I < this->end() && "Erasing at past-the-end iterator.");
+
+    iterator N = I;
+    // Shift all elts down one.
+    this->move(I+1, this->end(), I);
+    // Drop the last elt.
+    this->pop_back();
+    return(N);
+  }
+
+  iterator erase(iterator S, iterator E) {
+    assert(S >= this->begin() && "Range to erase is out of bounds.");
+    assert(S <= E && "Trying to erase invalid range.");
+    assert(E <= this->end() && "Trying to erase past the end.");
+
+    iterator N = S;
+    // Shift all elts down.
+    iterator I = this->move(E, this->end(), S);
+    // Drop the last elts.
+    this->destroy_range(I, this->end());
+    this->setEnd(I);
+    return(N);
+  }
+
+  iterator insert(iterator I, T &&Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      this->push_back(::std::move(Elt));
+      return this->end()-1;
+    }
+
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+
+    if (this->EndX >= this->CapacityX) {
+      size_t EltNo = I-this->begin();
+      this->grow();
+      I = this->begin()+EltNo;
+    }
+
+    ::new ((void*) this->end()) T(::std::move(this->back()));
+    // Push everything else over.
+    this->move_backward(I, this->end()-1, this->end());
+    this->setEnd(this->end()+1);
+
+    // If we just moved the element we're inserting, be sure to update
+    // the reference.
+    T *EltPtr = &Elt;
+    if (I <= EltPtr && EltPtr < this->EndX)
+      ++EltPtr;
+
+    *I = ::std::move(*EltPtr);
+    return I;
+  }
+
+  iterator insert(iterator I, const T &Elt) {
+    if (I == this->end()) {  // Important special case for empty vector.
+      this->push_back(Elt);
+      return this->end()-1;
+    }
+
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+
+    if (this->EndX >= this->CapacityX) {
+      size_t EltNo = I-this->begin();
+      this->grow();
+      I = this->begin()+EltNo;
+    }
+    ::new ((void*) this->end()) T(std::move(this->back()));
+    // Push everything else over.
+    this->move_backward(I, this->end()-1, this->end());
+    this->setEnd(this->end()+1);
+
+    // If we just moved the element we're inserting, be sure to update
+    // the reference.
+    const T *EltPtr = &Elt;
+    if (I <= EltPtr && EltPtr < this->EndX)
+      ++EltPtr;
+
+    *I = *EltPtr;
+    return I;
+  }
+
+  iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(NumToInsert, Elt);
+      return this->begin()+InsertElt;
+    }
+
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+
+    // Ensure there is enough space.
+    reserve(static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(std::move_iterator<iterator>(this->end() - NumToInsert),
+             std::move_iterator<iterator>(this->end()));
+
+      // Copy the existing elements that get replaced.
+      this->move_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::fill_n(I, NumToInsert, Elt);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Move over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    std::fill_n(I, NumOverwritten, Elt);
+
+    // Insert the non-overwritten middle part.
+    std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+    return I;
+  }
+
+  template<typename ItTy>
+  iterator insert(iterator I, ItTy From, ItTy To) {
+    // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+    size_t InsertElt = I - this->begin();
+
+    if (I == this->end()) {  // Important special case for empty vector.
+      append(From, To);
+      return this->begin()+InsertElt;
+    }
+
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+
+    size_t NumToInsert = std::distance(From, To);
+
+    // Ensure there is enough space.
+    reserve(static_cast<unsigned>(this->size() + NumToInsert));
+
+    // Uninvalidate the iterator.
+    I = this->begin()+InsertElt;
+
+    // If there are more elements between the insertion point and the end of the
+    // range than there are being inserted, we can use a simple approach to
+    // insertion.  Since we already reserved space, we know that this won't
+    // reallocate the vector.
+    if (size_t(this->end()-I) >= NumToInsert) {
+      T *OldEnd = this->end();
+      append(std::move_iterator<iterator>(this->end() - NumToInsert),
+             std::move_iterator<iterator>(this->end()));
+
+      // Copy the existing elements that get replaced.
+      this->move_backward(I, OldEnd-NumToInsert, OldEnd);
+
+      std::copy(From, To, I);
+      return I;
+    }
+
+    // Otherwise, we're inserting more elements than exist already, and we're
+    // not inserting at the end.
+
+    // Move over the elements that we're about to overwrite.
+    T *OldEnd = this->end();
+    this->setEnd(this->end() + NumToInsert);
+    size_t NumOverwritten = OldEnd-I;
+    this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
+
+    // Replace the overwritten part.
+    for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
+      *J = *From;
+      ++J; ++From;
+    }
+
+    // Insert the non-overwritten middle part.
+    this->uninitialized_copy(From, To, OldEnd);
+    return I;
+  }
+
+  SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+
+  SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
+
+  bool operator==(const SmallVectorImpl &RHS) const {
+    if (this->size() != RHS.size()) return false;
+    return std::equal(this->begin(), this->end(), RHS.begin());
+  }
+  bool operator!=(const SmallVectorImpl &RHS) const {
+    return !(*this == RHS);
+  }
+
+  bool operator<(const SmallVectorImpl &RHS) const {
+    return std::lexicographical_compare(this->begin(), this->end(),
+                                        RHS.begin(), RHS.end());
+  }
+
+  /// Set the array size to \p N, which the current array must have enough
+  /// capacity for.
+  ///
+  /// This does not construct or destroy any elements in the vector.
+  ///
+  /// Clients can use this in conjunction with capacity() to write past the end
+  /// of the buffer when they know that more elements are available, and only
+  /// update the size later. This avoids the cost of value initializing elements
+  /// which will only be overwritten.
+  void set_size(unsigned N) {
+    assert(N <= this->capacity());
+    this->setEnd(this->begin() + N);
+  }
+};
+
+
+template <typename T>
+void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
+  if (this == &RHS) return;
+
+  // We can only avoid copying elements if neither vector is small.
+  if (!this->isSmall() && !RHS.isSmall()) {
+    std::swap(this->BeginX, RHS.BeginX);
+    std::swap(this->EndX, RHS.EndX);
+    std::swap(this->CapacityX, RHS.CapacityX);
+    return;
+  }
+  if (RHS.size() > this->capacity())
+    this->grow(RHS.size());
+  if (this->size() > RHS.capacity())
+    RHS.grow(this->size());
+
+  // Swap the shared elements.
+  size_t NumShared = this->size();
+  if (NumShared > RHS.size()) NumShared = RHS.size();
+  for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
+    std::swap((*this)[i], RHS[i]);
+
+  // Copy over the extra elts.
+  if (this->size() > RHS.size()) {
+    size_t EltDiff = this->size() - RHS.size();
+    this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
+    RHS.setEnd(RHS.end()+EltDiff);
+    this->destroy_range(this->begin()+NumShared, this->end());
+    this->setEnd(this->begin()+NumShared);
+  } else if (RHS.size() > this->size()) {
+    size_t EltDiff = RHS.size() - this->size();
+    this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
+    this->setEnd(this->end() + EltDiff);
+    this->destroy_range(RHS.begin()+NumShared, RHS.end());
+    RHS.setEnd(RHS.begin()+NumShared);
+  }
+}
+
+template <typename T>
+SmallVectorImpl<T> &SmallVectorImpl<T>::
+  operator=(const SmallVectorImpl<T> &RHS) {
+  // Avoid self-assignment.
+  if (this == &RHS) return *this;
+
+  // If we already have sufficient space, assign the common elements, then
+  // destroy any excess.
+  size_t RHSSize = RHS.size();
+  size_t CurSize = this->size();
+  if (CurSize >= RHSSize) {
+    // Assign common elements.
+    iterator NewEnd;
+    if (RHSSize)
+      NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
+    else
+      NewEnd = this->begin();
+
+    // Destroy excess elements.
+    this->destroy_range(NewEnd, this->end());
+
+    // Trim.
+    this->setEnd(NewEnd);
+    return *this;
+  }
+
+  // If we have to grow to have enough elements, destroy the current elements.
+  // This allows us to avoid copying them during the grow.
+  // FIXME: don't do this if they're efficiently moveable.
+  if (this->capacity() < RHSSize) {
+    // Destroy current elements.
+    this->destroy_range(this->begin(), this->end());
+    this->setEnd(this->begin());
+    CurSize = 0;
+    this->grow(RHSSize);
+  } else if (CurSize) {
+    // Otherwise, use assignment for the already-constructed elements.
+    std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
+  }
+
+  // Copy construct the new elements in place.
+  this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
+                           this->begin()+CurSize);
+
+  // Set end.
+  this->setEnd(this->begin()+RHSSize);
+  return *this;
+}
+
+template <typename T>
+SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
+  // Avoid self-assignment.
+  if (this == &RHS) return *this;
+
+  // If the RHS isn't small, clear this vector and then steal its buffer.
+  if (!RHS.isSmall()) {
+    this->destroy_range(this->begin(), this->end());
+    if (!this->isSmall()) free(this->begin());
+    this->BeginX = RHS.BeginX;
+    this->EndX = RHS.EndX;
+    this->CapacityX = RHS.CapacityX;
+    RHS.resetToSmall();
+    return *this;
+  }
+
+  // If we already have sufficient space, assign the common elements, then
+  // destroy any excess.
+  size_t RHSSize = RHS.size();
+  size_t CurSize = this->size();
+  if (CurSize >= RHSSize) {
+    // Assign common elements.
+    iterator NewEnd = this->begin();
+    if (RHSSize)
+      NewEnd = this->move(RHS.begin(), RHS.end(), NewEnd);
+
+    // Destroy excess elements and trim the bounds.
+    this->destroy_range(NewEnd, this->end());
+    this->setEnd(NewEnd);
+
+    // Clear the RHS.
+    RHS.clear();
+
+    return *this;
+  }
+
+  // If we have to grow to have enough elements, destroy the current elements.
+  // This allows us to avoid copying them during the grow.
+  // FIXME: this may not actually make any sense if we can efficiently move
+  // elements.
+  if (this->capacity() < RHSSize) {
+    // Destroy current elements.
+    this->destroy_range(this->begin(), this->end());
+    this->setEnd(this->begin());
+    CurSize = 0;
+    this->grow(RHSSize);
+  } else if (CurSize) {
+    // Otherwise, use assignment for the already-constructed elements.
+    this->move(RHS.begin(), RHS.begin()+CurSize, this->begin());
+  }
+
+  // Move-construct the new elements in place.
+  this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
+                           this->begin()+CurSize);
+
+  // Set end.
+  this->setEnd(this->begin()+RHSSize);
+
+  RHS.clear();
+  return *this;
+}
+
+/// Storage for the SmallVector elements which aren't contained in
+/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
+/// element is in the base class. This is specialized for the N=1 and N=0 cases
+/// to avoid allocating unnecessary storage.
+template <typename T, unsigned N>
+struct SmallVectorStorage {
+  typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
+};
+template <typename T> struct SmallVectorStorage<T, 1> {};
+template <typename T> struct SmallVectorStorage<T, 0> {};
+
+/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
+/// for the case when the array is small.  It contains some number of elements
+/// in-place, which allows it to avoid heap allocation when the actual number of
+/// elements is below that threshold.  This allows normal "small" cases to be
+/// fast without losing generality for large inputs.
+///
+/// Note that this does not attempt to be exception safe.
+///
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+  /// Storage - Inline space for elements which aren't stored in the base class.
+  SmallVectorStorage<T, N> Storage;
+public:
+  SmallVector() : SmallVectorImpl<T>(N) {
+  }
+
+  explicit SmallVector(unsigned Size, const T &Value = T())
+    : SmallVectorImpl<T>(N) {
+    this->assign(Size, Value);
+  }
+
+  template<typename ItTy>
+  SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
+    this->append(S, E);
+  }
+
+  template <typename RangeTy>
+  explicit SmallVector(const llvm::iterator_range<RangeTy> R)
+      : SmallVectorImpl<T>(N) {
+    this->append(R.begin(), R.end());
+  }
+
+  SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
+    if (!RHS.empty())
+      SmallVectorImpl<T>::operator=(RHS);
+  }
+
+  const SmallVector &operator=(const SmallVector &RHS) {
+    SmallVectorImpl<T>::operator=(RHS);
+    return *this;
+  }
+
+  SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
+    if (!RHS.empty())
+      SmallVectorImpl<T>::operator=(::std::move(RHS));
+  }
+
+  const SmallVector &operator=(SmallVector &&RHS) {
+    SmallVectorImpl<T>::operator=(::std::move(RHS));
+    return *this;
+  }
+};
+
+template<typename T, unsigned N>
+static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
+  return X.capacity_in_bytes();
+}
+
+} // End llvm namespace
+
+namespace std {
+  /// Implement std::swap in terms of SmallVector swap.
+  template<typename T>
+  inline void
+  swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
+    LHS.swap(RHS);
+  }
+
+  /// Implement std::swap in terms of SmallVector swap.
+  template<typename T, unsigned N>
+  inline void
+  swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
+    LHS.swap(RHS);
+  }
+}
+
+#endif
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
new file mode 100644
index 0000000..36754d6
--- /dev/null
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -0,0 +1,898 @@
+//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- 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 SparseBitVector class.  See the doxygen comment for
+// SparseBitVector for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEBITVECTOR_H
+#define LLVM_ADT_SPARSEBITVECTOR_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+
+/// SparseBitVector is an implementation of a bitvector that is sparse by only
+/// storing the elements that have non-zero bits set.  In order to make this
+/// fast for the most common cases, SparseBitVector is implemented as a linked
+/// list of SparseBitVectorElements.  We maintain a pointer to the last
+/// SparseBitVectorElement accessed (in the form of a list iterator), in order
+/// to make multiple in-order test/set constant time after the first one is
+/// executed.  Note that using vectors to store SparseBitVectorElement's does
+/// not work out very well because it causes insertion in the middle to take
+/// enormous amounts of time with a large amount of bits.  Other structures that
+/// have better worst cases for insertion in the middle (various balanced trees,
+/// etc) do not perform as well in practice as a linked list with this iterator
+/// kept up to date.  They are also significantly more memory intensive.
+
+
+template <unsigned ElementSize = 128>
+struct SparseBitVectorElement
+  : public ilist_node<SparseBitVectorElement<ElementSize> > {
+public:
+  typedef unsigned long BitWord;
+  typedef unsigned size_type;

+  enum {
+    BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
+    BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
+    BITS_PER_ELEMENT = ElementSize
+  };
+
+private:
+  // Index of Element in terms of where first bit starts.
+  unsigned ElementIndex;
+  BitWord Bits[BITWORDS_PER_ELEMENT];
+  // Needed for sentinels
+  friend struct ilist_sentinel_traits<SparseBitVectorElement>;
+  SparseBitVectorElement() {
+    ElementIndex = ~0U;
+    memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+  }
+
+public:
+  explicit SparseBitVectorElement(unsigned Idx) {
+    ElementIndex = Idx;
+    memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+  }
+
+  // Comparison.
+  bool operator==(const SparseBitVectorElement &RHS) const {
+    if (ElementIndex != RHS.ElementIndex)
+      return false;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+      if (Bits[i] != RHS.Bits[i])
+        return false;
+    return true;
+  }
+
+  bool operator!=(const SparseBitVectorElement &RHS) const {
+    return !(*this == RHS);
+  }
+
+  // Return the bits that make up word Idx in our element.
+  BitWord word(unsigned Idx) const {
+    assert (Idx < BITWORDS_PER_ELEMENT);
+    return Bits[Idx];
+  }
+
+  unsigned index() const {
+    return ElementIndex;
+  }
+
+  bool empty() const {
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+      if (Bits[i])
+        return false;
+    return true;
+  }
+
+  void set(unsigned Idx) {
+    Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+  }
+
+  bool test_and_set (unsigned Idx) {
+    bool old = test(Idx);
+    if (!old) {
+      set(Idx);
+      return true;
+    }
+    return false;
+  }
+
+  void reset(unsigned Idx) {
+    Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+  }
+
+  bool test(unsigned Idx) const {
+    return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
+  }
+
+  size_type count() const {
+    unsigned NumBits = 0;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+      if (sizeof(BitWord) == 4)
+        NumBits += CountPopulation_32(Bits[i]);
+      else if (sizeof(BitWord) == 8)
+        NumBits += CountPopulation_64(Bits[i]);
+      else
+        llvm_unreachable("Unsupported!");
+    return NumBits;
+  }
+
+  /// find_first - Returns the index of the first set bit.
+  int find_first() const {
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+      if (Bits[i] != 0) {
+        if (sizeof(BitWord) == 4)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        if (sizeof(BitWord) == 8)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        llvm_unreachable("Unsupported!");
+      }
+    llvm_unreachable("Illegal empty element");
+  }
+
+  /// find_next - Returns the index of the next set bit starting from the
+  /// "Curr" bit. Returns -1 if the next set bit is not found.
+  int find_next(unsigned Curr) const {
+    if (Curr >= BITS_PER_ELEMENT)
+      return -1;
+
+    unsigned WordPos = Curr / BITWORD_SIZE;
+    unsigned BitPos = Curr % BITWORD_SIZE;
+    BitWord Copy = Bits[WordPos];
+    assert (WordPos <= BITWORDS_PER_ELEMENT
+            && "Word Position outside of element");
+
+    // Mask off previous bits.
+    Copy &= ~0UL << BitPos;
+
+    if (Copy != 0) {
+      if (sizeof(BitWord) == 4)
+        return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
+      if (sizeof(BitWord) == 8)
+        return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
+      llvm_unreachable("Unsupported!");
+    }
+
+    // Check subsequent words.
+    for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
+      if (Bits[i] != 0) {
+        if (sizeof(BitWord) == 4)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        if (sizeof(BitWord) == 8)
+          return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
+        llvm_unreachable("Unsupported!");
+      }
+    return -1;
+  }
+
+  // Union this element with RHS and return true if this one changed.
+  bool unionWith(const SparseBitVectorElement &RHS) {
+    bool changed = false;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+      BitWord old = changed ? 0 : Bits[i];
+
+      Bits[i] |= RHS.Bits[i];
+      if (!changed && old != Bits[i])
+        changed = true;
+    }
+    return changed;
+  }
+
+  // Return true if we have any bits in common with RHS
+  bool intersects(const SparseBitVectorElement &RHS) const {
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+      if (RHS.Bits[i] & Bits[i])
+        return true;
+    }
+    return false;
+  }
+
+  // Intersect this Element with RHS and return true if this one changed.
+  // BecameZero is set to true if this element became all-zero bits.
+  bool intersectWith(const SparseBitVectorElement &RHS,
+                     bool &BecameZero) {
+    bool changed = false;
+    bool allzero = true;
+
+    BecameZero = false;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+      BitWord old = changed ? 0 : Bits[i];
+
+      Bits[i] &= RHS.Bits[i];
+      if (Bits[i] != 0)
+        allzero = false;
+
+      if (!changed && old != Bits[i])
+        changed = true;
+    }
+    BecameZero = allzero;
+    return changed;
+  }
+  // Intersect this Element with the complement of RHS and return true if this
+  // one changed.  BecameZero is set to true if this element became all-zero
+  // bits.
+  bool intersectWithComplement(const SparseBitVectorElement &RHS,
+                               bool &BecameZero) {
+    bool changed = false;
+    bool allzero = true;
+
+    BecameZero = false;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+      BitWord old = changed ? 0 : Bits[i];
+
+      Bits[i] &= ~RHS.Bits[i];
+      if (Bits[i] != 0)
+        allzero = false;
+
+      if (!changed && old != Bits[i])
+        changed = true;
+    }
+    BecameZero = allzero;
+    return changed;
+  }
+  // Three argument version of intersectWithComplement that intersects
+  // RHS1 & ~RHS2 into this element
+  void intersectWithComplement(const SparseBitVectorElement &RHS1,
+                               const SparseBitVectorElement &RHS2,
+                               bool &BecameZero) {
+    bool allzero = true;
+
+    BecameZero = false;
+    for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+      Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
+      if (Bits[i] != 0)
+        allzero = false;
+    }
+    BecameZero = allzero;
+  }
+};
+
+template <unsigned ElementSize>
+struct ilist_traits<SparseBitVectorElement<ElementSize> >
+  : public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
+  typedef SparseBitVectorElement<ElementSize> Element;
+
+  Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
+  static void destroySentinel(Element *) {}
+
+  Element *provideInitialHead() const { return createSentinel(); }
+  Element *ensureHead(Element *) const { return createSentinel(); }
+  static void noteHead(Element *, Element *) {}
+
+private:
+  mutable ilist_half_node<Element> Sentinel;
+};
+
+template <unsigned ElementSize = 128>
+class SparseBitVector {
+  typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
+  typedef typename ElementList::iterator ElementListIter;
+  typedef typename ElementList::const_iterator ElementListConstIter;
+  enum {
+    BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
+  };
+
+  // Pointer to our current Element.
+  ElementListIter CurrElementIter;
+  ElementList Elements;
+
+  // This is like std::lower_bound, except we do linear searching from the
+  // current position.
+  ElementListIter FindLowerBound(unsigned ElementIndex) {
+
+    if (Elements.empty()) {
+      CurrElementIter = Elements.begin();
+      return Elements.begin();
+    }
+
+    // Make sure our current iterator is valid.
+    if (CurrElementIter == Elements.end())
+      --CurrElementIter;
+
+    // Search from our current iterator, either backwards or forwards,
+    // depending on what element we are looking for.
+    ElementListIter ElementIter = CurrElementIter;
+    if (CurrElementIter->index() == ElementIndex) {
+      return ElementIter;
+    } else if (CurrElementIter->index() > ElementIndex) {
+      while (ElementIter != Elements.begin()
+             && ElementIter->index() > ElementIndex)
+        --ElementIter;
+    } else {
+      while (ElementIter != Elements.end() &&
+             ElementIter->index() < ElementIndex)
+        ++ElementIter;
+    }
+    CurrElementIter = ElementIter;
+    return ElementIter;
+  }
+
+  // Iterator to walk set bits in the bitmap.  This iterator is a lot uglier
+  // than it would be, in order to be efficient.
+  class SparseBitVectorIterator {
+  private:
+    bool AtEnd;
+
+    const SparseBitVector<ElementSize> *BitVector;
+
+    // Current element inside of bitmap.
+    ElementListConstIter Iter;
+
+    // Current bit number inside of our bitmap.
+    unsigned BitNumber;
+
+    // Current word number inside of our element.
+    unsigned WordNumber;
+
+    // Current bits from the element.
+    typename SparseBitVectorElement<ElementSize>::BitWord Bits;
+
+    // Move our iterator to the first non-zero bit in the bitmap.
+    void AdvanceToFirstNonZero() {
+      if (AtEnd)
+        return;
+      if (BitVector->Elements.empty()) {
+        AtEnd = true;
+        return;
+      }
+      Iter = BitVector->Elements.begin();
+      BitNumber = Iter->index() * ElementSize;
+      unsigned BitPos = Iter->find_first();
+      BitNumber += BitPos;
+      WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+      Bits = Iter->word(WordNumber);
+      Bits >>= BitPos % BITWORD_SIZE;
+    }
+
+    // Move our iterator to the next non-zero bit.
+    void AdvanceToNextNonZero() {
+      if (AtEnd)
+        return;
+
+      while (Bits && !(Bits & 1)) {
+        Bits >>= 1;
+        BitNumber += 1;
+      }
+
+      // See if we ran out of Bits in this word.
+      if (!Bits) {
+        int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
+        // If we ran out of set bits in this element, move to next element.
+        if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
+          ++Iter;
+          WordNumber = 0;
+
+          // We may run out of elements in the bitmap.
+          if (Iter == BitVector->Elements.end()) {
+            AtEnd = true;
+            return;
+          }
+          // Set up for next non-zero word in bitmap.
+          BitNumber = Iter->index() * ElementSize;
+          NextSetBitNumber = Iter->find_first();
+          BitNumber += NextSetBitNumber;
+          WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+          Bits = Iter->word(WordNumber);
+          Bits >>= NextSetBitNumber % BITWORD_SIZE;
+        } else {
+          WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
+          Bits = Iter->word(WordNumber);
+          Bits >>= NextSetBitNumber % BITWORD_SIZE;
+          BitNumber = Iter->index() * ElementSize;
+          BitNumber += NextSetBitNumber;
+        }
+      }
+    }
+  public:
+    // Preincrement.
+    inline SparseBitVectorIterator& operator++() {
+      ++BitNumber;
+      Bits >>= 1;
+      AdvanceToNextNonZero();
+      return *this;
+    }
+
+    // Postincrement.
+    inline SparseBitVectorIterator operator++(int) {
+      SparseBitVectorIterator tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    // Return the current set bit number.
+    unsigned operator*() const {
+      return BitNumber;
+    }
+
+    bool operator==(const SparseBitVectorIterator &RHS) const {
+      // If they are both at the end, ignore the rest of the fields.
+      if (AtEnd && RHS.AtEnd)
+        return true;
+      // Otherwise they are the same if they have the same bit number and
+      // bitmap.
+      return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
+    }
+    bool operator!=(const SparseBitVectorIterator &RHS) const {
+      return !(*this == RHS);
+    }
+    SparseBitVectorIterator(): BitVector(NULL) {
+    }
+
+
+    SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
+                            bool end = false):BitVector(RHS) {
+      Iter = BitVector->Elements.begin();
+      BitNumber = 0;
+      Bits = 0;
+      WordNumber = ~0;
+      AtEnd = end;
+      AdvanceToFirstNonZero();
+    }
+  };
+public:
+  typedef SparseBitVectorIterator iterator;
+
+  SparseBitVector () {
+    CurrElementIter = Elements.begin ();
+  }
+
+  ~SparseBitVector() {
+  }
+
+  // SparseBitVector copy ctor.
+  SparseBitVector(const SparseBitVector &RHS) {
+    ElementListConstIter ElementIter = RHS.Elements.begin();
+    while (ElementIter != RHS.Elements.end()) {
+      Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+      ++ElementIter;
+    }
+
+    CurrElementIter = Elements.begin ();
+  }
+
+  // Clear.
+  void clear() {
+    Elements.clear();
+  }
+
+  // Assignment
+  SparseBitVector& operator=(const SparseBitVector& RHS) {
+    Elements.clear();
+
+    ElementListConstIter ElementIter = RHS.Elements.begin();
+    while (ElementIter != RHS.Elements.end()) {
+      Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+      ++ElementIter;
+    }
+
+    CurrElementIter = Elements.begin ();
+
+    return *this;
+  }
+
+  // Test, Reset, and Set a bit in the bitmap.
+  bool test(unsigned Idx) {
+    if (Elements.empty())
+      return false;
+
+    unsigned ElementIndex = Idx / ElementSize;
+    ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+    // If we can't find an element that is supposed to contain this bit, there
+    // is nothing more to do.
+    if (ElementIter == Elements.end() ||
+        ElementIter->index() != ElementIndex)
+      return false;
+    return ElementIter->test(Idx % ElementSize);
+  }
+
+  void reset(unsigned Idx) {
+    if (Elements.empty())
+      return;
+
+    unsigned ElementIndex = Idx / ElementSize;
+    ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+    // If we can't find an element that is supposed to contain this bit, there
+    // is nothing more to do.
+    if (ElementIter == Elements.end() ||
+        ElementIter->index() != ElementIndex)
+      return;
+    ElementIter->reset(Idx % ElementSize);
+
+    // When the element is zeroed out, delete it.
+    if (ElementIter->empty()) {
+      ++CurrElementIter;
+      Elements.erase(ElementIter);
+    }
+  }
+
+  void set(unsigned Idx) {
+    unsigned ElementIndex = Idx / ElementSize;
+    SparseBitVectorElement<ElementSize> *Element;
+    ElementListIter ElementIter;
+    if (Elements.empty()) {
+      Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+      ElementIter = Elements.insert(Elements.end(), Element);
+
+    } else {
+      ElementIter = FindLowerBound(ElementIndex);
+
+      if (ElementIter == Elements.end() ||
+          ElementIter->index() != ElementIndex) {
+        Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+        // We may have hit the beginning of our SparseBitVector, in which case,
+        // we may need to insert right after this element, which requires moving
+        // the current iterator forward one, because insert does insert before.
+        if (ElementIter != Elements.end() &&
+            ElementIter->index() < ElementIndex)
+          ElementIter = Elements.insert(++ElementIter, Element);
+        else
+          ElementIter = Elements.insert(ElementIter, Element);
+      }
+    }
+    CurrElementIter = ElementIter;
+
+    ElementIter->set(Idx % ElementSize);
+  }
+
+  bool test_and_set (unsigned Idx) {
+    bool old = test(Idx);
+    if (!old) {
+      set(Idx);
+      return true;
+    }
+    return false;
+  }
+
+  bool operator!=(const SparseBitVector &RHS) const {
+    return !(*this == RHS);
+  }
+
+  bool operator==(const SparseBitVector &RHS) const {
+    ElementListConstIter Iter1 = Elements.begin();
+    ElementListConstIter Iter2 = RHS.Elements.begin();
+
+    for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
+         ++Iter1, ++Iter2) {
+      if (*Iter1 != *Iter2)
+        return false;
+    }
+    return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
+  }
+
+  // Union our bitmap with the RHS and return true if we changed.
+  bool operator|=(const SparseBitVector &RHS) {
+    bool changed = false;
+    ElementListIter Iter1 = Elements.begin();
+    ElementListConstIter Iter2 = RHS.Elements.begin();
+
+    // If RHS is empty, we are done
+    if (RHS.Elements.empty())
+      return false;
+
+    while (Iter2 != RHS.Elements.end()) {
+      if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
+        Elements.insert(Iter1,
+                        new SparseBitVectorElement<ElementSize>(*Iter2));
+        ++Iter2;
+        changed = true;
+      } else if (Iter1->index() == Iter2->index()) {
+        changed |= Iter1->unionWith(*Iter2);
+        ++Iter1;
+        ++Iter2;
+      } else {
+        ++Iter1;
+      }
+    }
+    CurrElementIter = Elements.begin();
+    return changed;
+  }
+
+  // Intersect our bitmap with the RHS and return true if ours changed.
+  bool operator&=(const SparseBitVector &RHS) {
+    bool changed = false;
+    ElementListIter Iter1 = Elements.begin();
+    ElementListConstIter Iter2 = RHS.Elements.begin();
+
+    // Check if both bitmaps are empty.
+    if (Elements.empty() && RHS.Elements.empty())
+      return false;
+
+    // Loop through, intersecting as we go, erasing elements when necessary.
+    while (Iter2 != RHS.Elements.end()) {
+      if (Iter1 == Elements.end()) {
+        CurrElementIter = Elements.begin();
+        return changed;
+      }
+
+      if (Iter1->index() > Iter2->index()) {
+        ++Iter2;
+      } else if (Iter1->index() == Iter2->index()) {
+        bool BecameZero;
+        changed |= Iter1->intersectWith(*Iter2, BecameZero);
+        if (BecameZero) {
+          ElementListIter IterTmp = Iter1;
+          ++Iter1;
+          Elements.erase(IterTmp);
+        } else {
+          ++Iter1;
+        }
+        ++Iter2;
+      } else {
+        ElementListIter IterTmp = Iter1;
+        ++Iter1;
+        Elements.erase(IterTmp);
+      }
+    }
+    Elements.erase(Iter1, Elements.end());
+    CurrElementIter = Elements.begin();
+    return changed;
+  }
+
+  // Intersect our bitmap with the complement of the RHS and return true
+  // if ours changed.
+  bool intersectWithComplement(const SparseBitVector &RHS) {
+    bool changed = false;
+    ElementListIter Iter1 = Elements.begin();
+    ElementListConstIter Iter2 = RHS.Elements.begin();
+
+    // If either our bitmap or RHS is empty, we are done
+    if (Elements.empty() || RHS.Elements.empty())
+      return false;
+
+    // Loop through, intersecting as we go, erasing elements when necessary.
+    while (Iter2 != RHS.Elements.end()) {
+      if (Iter1 == Elements.end()) {
+        CurrElementIter = Elements.begin();
+        return changed;
+      }
+
+      if (Iter1->index() > Iter2->index()) {
+        ++Iter2;
+      } else if (Iter1->index() == Iter2->index()) {
+        bool BecameZero;
+        changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
+        if (BecameZero) {
+          ElementListIter IterTmp = Iter1;
+          ++Iter1;
+          Elements.erase(IterTmp);
+        } else {
+          ++Iter1;
+        }
+        ++Iter2;
+      } else {
+        ++Iter1;
+      }
+    }
+    CurrElementIter = Elements.begin();
+    return changed;
+  }
+
+  bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
+    return intersectWithComplement(*RHS);
+  }
+
+
+  //  Three argument version of intersectWithComplement.
+  //  Result of RHS1 & ~RHS2 is stored into this bitmap.
+  void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
+                               const SparseBitVector<ElementSize> &RHS2)
+  {
+    Elements.clear();
+    CurrElementIter = Elements.begin();
+    ElementListConstIter Iter1 = RHS1.Elements.begin();
+    ElementListConstIter Iter2 = RHS2.Elements.begin();
+
+    // If RHS1 is empty, we are done
+    // If RHS2 is empty, we still have to copy RHS1
+    if (RHS1.Elements.empty())
+      return;
+
+    // Loop through, intersecting as we go, erasing elements when necessary.
+    while (Iter2 != RHS2.Elements.end()) {
+      if (Iter1 == RHS1.Elements.end())
+        return;
+
+      if (Iter1->index() > Iter2->index()) {
+        ++Iter2;
+      } else if (Iter1->index() == Iter2->index()) {
+        bool BecameZero = false;
+        SparseBitVectorElement<ElementSize> *NewElement =
+          new SparseBitVectorElement<ElementSize>(Iter1->index());
+        NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
+        if (!BecameZero) {
+          Elements.push_back(NewElement);
+        }
+        else
+          delete NewElement;
+        ++Iter1;
+        ++Iter2;
+      } else {
+        SparseBitVectorElement<ElementSize> *NewElement =
+          new SparseBitVectorElement<ElementSize>(*Iter1);
+        Elements.push_back(NewElement);
+        ++Iter1;
+      }
+    }
+
+    // copy the remaining elements
+    while (Iter1 != RHS1.Elements.end()) {
+        SparseBitVectorElement<ElementSize> *NewElement =
+          new SparseBitVectorElement<ElementSize>(*Iter1);
+        Elements.push_back(NewElement);
+        ++Iter1;
+      }
+
+    return;
+  }
+
+  void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
+                               const SparseBitVector<ElementSize> *RHS2) {
+    intersectWithComplement(*RHS1, *RHS2);
+  }
+
+  bool intersects(const SparseBitVector<ElementSize> *RHS) const {
+    return intersects(*RHS);
+  }
+
+  // Return true if we share any bits in common with RHS
+  bool intersects(const SparseBitVector<ElementSize> &RHS) const {
+    ElementListConstIter Iter1 = Elements.begin();
+    ElementListConstIter Iter2 = RHS.Elements.begin();
+
+    // Check if both bitmaps are empty.
+    if (Elements.empty() && RHS.Elements.empty())
+      return false;
+
+    // Loop through, intersecting stopping when we hit bits in common.
+    while (Iter2 != RHS.Elements.end()) {
+      if (Iter1 == Elements.end())
+        return false;
+
+      if (Iter1->index() > Iter2->index()) {
+        ++Iter2;
+      } else if (Iter1->index() == Iter2->index()) {
+        if (Iter1->intersects(*Iter2))
+          return true;
+        ++Iter1;
+        ++Iter2;
+      } else {
+        ++Iter1;
+      }
+    }
+    return false;
+  }
+
+  // Return true iff all bits set in this SparseBitVector are
+  // also set in RHS.
+  bool contains(const SparseBitVector<ElementSize> &RHS) const {
+    SparseBitVector<ElementSize> Result(*this);
+    Result &= RHS;
+    return (Result == RHS);
+  }
+
+  // Return the first set bit in the bitmap.  Return -1 if no bits are set.
+  int find_first() const {
+    if (Elements.empty())
+      return -1;
+    const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
+    return (First.index() * ElementSize) + First.find_first();
+  }
+
+  // Return true if the SparseBitVector is empty
+  bool empty() const {
+    return Elements.empty();
+  }
+
+  unsigned count() const {
+    unsigned BitCount = 0;
+    for (ElementListConstIter Iter = Elements.begin();
+         Iter != Elements.end();
+         ++Iter)
+      BitCount += Iter->count();
+
+    return BitCount;
+  }
+  iterator begin() const {
+    return iterator(this);
+  }
+
+  iterator end() const {
+    return iterator(this, true);
+  }
+};
+
+// Convenience functions to allow Or and And without dereferencing in the user
+// code.
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> &LHS,
+                        const SparseBitVector<ElementSize> *RHS) {
+  return LHS |= *RHS;
+}
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> *LHS,
+                        const SparseBitVector<ElementSize> &RHS) {
+  return LHS->operator|=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> *LHS,
+                        const SparseBitVector<ElementSize> &RHS) {
+  return LHS->operator&=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> &LHS,
+                        const SparseBitVector<ElementSize> *RHS) {
+  return LHS &= *RHS;
+}
+
+// Convenience functions for infix union, intersection, difference operators.
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator|(const SparseBitVector<ElementSize> &LHS,
+          const SparseBitVector<ElementSize> &RHS) {
+  SparseBitVector<ElementSize> Result(LHS);
+  Result |= RHS;
+  return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator&(const SparseBitVector<ElementSize> &LHS,
+          const SparseBitVector<ElementSize> &RHS) {
+  SparseBitVector<ElementSize> Result(LHS);
+  Result &= RHS;
+  return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator-(const SparseBitVector<ElementSize> &LHS,
+          const SparseBitVector<ElementSize> &RHS) {
+  SparseBitVector<ElementSize> Result;
+  Result.intersectWithComplement(LHS, RHS);
+  return Result;
+}
+
+
+
+
+// Dump a SparseBitVector to a stream
+template <unsigned ElementSize>
+void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
+  out << "[";
+
+  typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
+    be = LHS.end();
+  if (bi != be) {
+    out << *bi;
+    for (++bi; bi != be; ++bi) {
+      out << " " << *bi;
+    }
+  }
+  out << "]\n";
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
new file mode 100644
index 0000000..dc1273e
--- /dev/null
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -0,0 +1,518 @@
+//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- 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 SparseMultiSet class, which adds multiset behavior to
+// the SparseSet.
+//
+// A sparse multiset holds a small number of objects identified by integer keys
+// from a moderately sized universe. The sparse multiset uses more memory than
+// other containers in order to provide faster operations. Any key can map to
+// multiple values. A SparseMultiSetNode class is provided, which serves as a
+// convenient base class for the contents of a SparseMultiSet.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEMULTISET_H
+#define LLVM_ADT_SPARSEMULTISET_H
+
+#include "llvm/ADT/SparseSet.h"
+
+namespace llvm {
+
+/// Fast multiset implementation for objects that can be identified by small
+/// unsigned keys.
+///
+/// SparseMultiSet allocates memory proportional to the size of the key
+/// universe, so it is not recommended for building composite data structures.
+/// It is useful for algorithms that require a single set with fast operations.
+///
+/// Compared to DenseSet and DenseMap, SparseMultiSet provides constant-time
+/// fast clear() as fast as a vector.  The find(), insert(), and erase()
+/// operations are all constant time, and typically faster than a hash table.
+/// The iteration order doesn't depend on numerical key values, it only depends
+/// on the order of insert() and erase() operations.  Iteration order is the
+/// insertion order. Iteration is only provided over elements of equivalent
+/// keys, but iterators are bidirectional.
+///
+/// Compared to BitVector, SparseMultiSet<unsigned> uses 8x-40x more memory, but
+/// offers constant-time clear() and size() operations as well as fast iteration
+/// independent on the size of the universe.
+///
+/// SparseMultiSet contains a dense vector holding all the objects and a sparse
+/// array holding indexes into the dense vector.  Most of the memory is used by
+/// the sparse array which is the size of the key universe. The SparseT template
+/// parameter provides a space/speed tradeoff for sets holding many elements.
+///
+/// When SparseT is uint32_t, find() only touches up to 3 cache lines, but the
+/// sparse array uses 4 x Universe bytes.
+///
+/// When SparseT is uint8_t (the default), find() touches up to 3+[N/256] cache
+/// lines, but the sparse array is 4x smaller.  N is the number of elements in
+/// the set.
+///
+/// For sets that may grow to thousands of elements, SparseT should be set to
+/// uint16_t or uint32_t.
+///
+/// Multiset behavior is provided by providing doubly linked lists for values
+/// that are inlined in the dense vector. SparseMultiSet is a good choice when
+/// one desires a growable number of entries per key, as it will retain the
+/// SparseSet algorithmic properties despite being growable. Thus, it is often a
+/// better choice than a SparseSet of growable containers or a vector of
+/// vectors. SparseMultiSet also keeps iterators valid after erasure (provided
+/// the iterators don't point to the element erased), allowing for more
+/// intuitive and fast removal.
+///
+/// @tparam ValueT      The type of objects in the set.
+/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
+/// @tparam SparseT     An unsigned integer type. See above.
+///
+template<typename ValueT,
+         typename KeyFunctorT = llvm::identity<unsigned>,
+         typename SparseT = uint8_t>
+class SparseMultiSet {
+  static_assert(std::numeric_limits<SparseT>::is_integer &&
+                !std::numeric_limits<SparseT>::is_signed,
+                "SparseT must be an unsigned integer type");
+
+  /// The actual data that's stored, as a doubly-linked list implemented via
+  /// indices into the DenseVector.  The doubly linked list is implemented
+  /// circular in Prev indices, and INVALID-terminated in Next indices. This
+  /// provides efficient access to list tails. These nodes can also be
+  /// tombstones, in which case they are actually nodes in a single-linked
+  /// freelist of recyclable slots.
+  struct SMSNode {
+    static const unsigned INVALID = ~0U;
+
+    ValueT Data;
+    unsigned Prev;
+    unsigned Next;
+
+    SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { }
+
+    /// List tails have invalid Nexts.
+    bool isTail() const {
+      return Next == INVALID;
+    }
+
+    /// Whether this node is a tombstone node, and thus is in our freelist.
+    bool isTombstone() const {
+      return Prev == INVALID;
+    }
+
+    /// Since the list is circular in Prev, all non-tombstone nodes have a valid
+    /// Prev.
+    bool isValid() const { return Prev != INVALID; }
+  };
+
+  typedef typename KeyFunctorT::argument_type KeyT;
+  typedef SmallVector<SMSNode, 8> DenseT;
+  DenseT Dense;
+  SparseT *Sparse;
+  unsigned Universe;
+  KeyFunctorT KeyIndexOf;
+  SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
+
+  /// We have a built-in recycler for reusing tombstone slots. This recycler
+  /// puts a singly-linked free list into tombstone slots, allowing us quick
+  /// erasure, iterator preservation, and dense size.
+  unsigned FreelistIdx;
+  unsigned NumFree;
+
+  unsigned sparseIndex(const ValueT &Val) const {
+    assert(ValIndexOf(Val) < Universe &&
+           "Invalid key in set. Did object mutate?");
+    return ValIndexOf(Val);
+  }
+  unsigned sparseIndex(const SMSNode &N) const { return sparseIndex(N.Data); }
+
+  // Disable copy construction and assignment.
+  // This data structure is not meant to be used that way.
+  SparseMultiSet(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
+  SparseMultiSet &operator=(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
+
+  /// Whether the given entry is the head of the list. List heads's previous
+  /// pointers are to the tail of the list, allowing for efficient access to the
+  /// list tail. D must be a valid entry node.
+  bool isHead(const SMSNode &D) const {
+    assert(D.isValid() && "Invalid node for head");
+    return Dense[D.Prev].isTail();
+  }
+
+  /// Whether the given entry is a singleton entry, i.e. the only entry with
+  /// that key.
+  bool isSingleton(const SMSNode &N) const {
+    assert(N.isValid() && "Invalid node for singleton");
+    // Is N its own predecessor?
+    return &Dense[N.Prev] == &N;
+  }
+
+  /// Add in the given SMSNode. Uses a free entry in our freelist if
+  /// available. Returns the index of the added node.
+  unsigned addValue(const ValueT& V, unsigned Prev, unsigned Next) {
+    if (NumFree == 0) {
+      Dense.push_back(SMSNode(V, Prev, Next));
+      return Dense.size() - 1;
+    }
+
+    // Peel off a free slot
+    unsigned Idx = FreelistIdx;
+    unsigned NextFree = Dense[Idx].Next;
+    assert(Dense[Idx].isTombstone() && "Non-tombstone free?");
+
+    Dense[Idx] = SMSNode(V, Prev, Next);
+    FreelistIdx = NextFree;
+    --NumFree;
+    return Idx;
+  }
+
+  /// Make the current index a new tombstone. Pushes it onto the freelist.
+  void makeTombstone(unsigned Idx) {
+    Dense[Idx].Prev = SMSNode::INVALID;
+    Dense[Idx].Next = FreelistIdx;
+    FreelistIdx = Idx;
+    ++NumFree;
+  }
+
+public:
+  typedef ValueT value_type;
+  typedef ValueT &reference;
+  typedef const ValueT &const_reference;
+  typedef ValueT *pointer;
+  typedef const ValueT *const_pointer;
+  typedef unsigned size_type;

+
+  SparseMultiSet()
+    : Sparse(nullptr), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) {}
+
+  ~SparseMultiSet() { free(Sparse); }
+
+  /// Set the universe size which determines the largest key the set can hold.
+  /// The universe must be sized before any elements can be added.
+  ///
+  /// @param U Universe size. All object keys must be less than U.
+  ///
+  void setUniverse(unsigned U) {
+    // It's not hard to resize the universe on a non-empty set, but it doesn't
+    // seem like a likely use case, so we can add that code when we need it.
+    assert(empty() && "Can only resize universe on an empty map");
+    // Hysteresis prevents needless reallocations.
+    if (U >= Universe/4 && U <= Universe)
+      return;
+    free(Sparse);
+    // The Sparse array doesn't actually need to be initialized, so malloc
+    // would be enough here, but that will cause tools like valgrind to
+    // complain about branching on uninitialized data.
+    Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+    Universe = U;
+  }
+
+  /// Our iterators are iterators over the collection of objects that share a
+  /// key.
+  template<typename SMSPtrTy>
+  class iterator_base : public std::iterator<std::bidirectional_iterator_tag,
+                                             ValueT> {
+    friend class SparseMultiSet;
+    SMSPtrTy SMS;
+    unsigned Idx;
+    unsigned SparseIdx;
+
+    iterator_base(SMSPtrTy P, unsigned I, unsigned SI)
+      : SMS(P), Idx(I), SparseIdx(SI) { }
+
+    /// Whether our iterator has fallen outside our dense vector.
+    bool isEnd() const {
+      if (Idx == SMSNode::INVALID)
+        return true;
+
+      assert(Idx < SMS->Dense.size() && "Out of range, non-INVALID Idx?");
+      return false;
+    }
+
+    /// Whether our iterator is properly keyed, i.e. the SparseIdx is valid
+    bool isKeyed() const { return SparseIdx < SMS->Universe; }
+
+    unsigned Prev() const { return SMS->Dense[Idx].Prev; }
+    unsigned Next() const { return SMS->Dense[Idx].Next; }
+
+    void setPrev(unsigned P) { SMS->Dense[Idx].Prev = P; }
+    void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
+
+  public:
+    typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super;
+    typedef typename super::value_type value_type;
+    typedef typename super::difference_type difference_type;
+    typedef typename super::pointer pointer;
+    typedef typename super::reference reference;
+
+    reference operator*() const {
+      assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
+             "Dereferencing iterator of invalid key or index");
+
+      return SMS->Dense[Idx].Data;
+    }
+    pointer operator->() const { return &operator*(); }
+
+    /// Comparison operators
+    bool operator==(const iterator_base &RHS) const {
+      // end compares equal
+      if (SMS == RHS.SMS && Idx == RHS.Idx) {
+        assert((isEnd() || SparseIdx == RHS.SparseIdx) &&
+               "Same dense entry, but different keys?");
+        return true;
+      }
+
+      return false;
+    }
+
+    bool operator!=(const iterator_base &RHS) const {
+      return !operator==(RHS);
+    }
+
+    /// Increment and decrement operators
+    iterator_base &operator--() { // predecrement - Back up
+      assert(isKeyed() && "Decrementing an invalid iterator");
+      assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) &&
+             "Decrementing head of list");
+
+      // If we're at the end, then issue a new find()
+      if (isEnd())
+        Idx = SMS->findIndex(SparseIdx).Prev();
+      else
+        Idx = Prev();
+
+      return *this;
+    }
+    iterator_base &operator++() { // preincrement - Advance
+      assert(!isEnd() && isKeyed() && "Incrementing an invalid/end iterator");
+      Idx = Next();
+      return *this;
+    }
+    iterator_base operator--(int) { // postdecrement
+      iterator_base I(*this);
+      --*this;
+      return I;
+    }
+    iterator_base operator++(int) { // postincrement
+      iterator_base I(*this);
+      ++*this;
+      return I;
+    }
+  };
+  typedef iterator_base<SparseMultiSet *> iterator;
+  typedef iterator_base<const SparseMultiSet *> const_iterator;
+
+  // Convenience types
+  typedef std::pair<iterator, iterator> RangePair;
+
+  /// Returns an iterator past this container. Note that such an iterator cannot
+  /// be decremented, but will compare equal to other end iterators.
+  iterator end() { return iterator(this, SMSNode::INVALID, SMSNode::INVALID); }
+  const_iterator end() const {
+    return const_iterator(this, SMSNode::INVALID, SMSNode::INVALID);
+  }
+
+  /// Returns true if the set is empty.
+  ///
+  /// This is not the same as BitVector::empty().
+  ///
+  bool empty() const { return size() == 0; }
+
+  /// Returns the number of elements in the set.
+  ///
+  /// This is not the same as BitVector::size() which returns the size of the
+  /// universe.
+  ///
+  size_type size() const {
+    assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
+    return Dense.size() - NumFree;
+  }
+
+  /// Clears the set.  This is a very fast constant time operation.
+  ///
+  void clear() {
+    // Sparse does not need to be cleared, see find().
+    Dense.clear();
+    NumFree = 0;
+    FreelistIdx = SMSNode::INVALID;
+  }
+
+  /// Find an element by its index.
+  ///
+  /// @param   Idx A valid index to find.
+  /// @returns An iterator to the element identified by key, or end().
+  ///
+  iterator findIndex(unsigned Idx) {
+    assert(Idx < Universe && "Key out of range");
+    const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
+    for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
+      const unsigned FoundIdx = sparseIndex(Dense[i]);
+      // Check that we're pointing at the correct entry and that it is the head
+      // of a valid list.
+      if (Idx == FoundIdx && Dense[i].isValid() && isHead(Dense[i]))
+        return iterator(this, i, Idx);
+      // Stride is 0 when SparseT >= unsigned.  We don't need to loop.
+      if (!Stride)
+        break;
+    }
+    return end();
+  }
+
+  /// Find an element by its key.
+  ///
+  /// @param   Key A valid key to find.
+  /// @returns An iterator to the element identified by key, or end().
+  ///
+  iterator find(const KeyT &Key) {
+    return findIndex(KeyIndexOf(Key));
+  }
+
+  const_iterator find(const KeyT &Key) const {
+    iterator I = const_cast<SparseMultiSet*>(this)->findIndex(KeyIndexOf(Key));
+    return const_iterator(I.SMS, I.Idx, KeyIndexOf(Key));
+  }
+
+  /// Returns the number of elements identified by Key. This will be linear in
+  /// the number of elements of that key.
+  size_type count(const KeyT &Key) const {
+    unsigned Ret = 0;
+    for (const_iterator It = find(Key); It != end(); ++It)
+      ++Ret;
+
+    return Ret;
+  }
+
+  /// Returns true if this set contains an element identified by Key.
+  bool contains(const KeyT &Key) const {
+    return find(Key) != end();
+  }
+
+  /// Return the head and tail of the subset's list, otherwise returns end().
+  iterator getHead(const KeyT &Key) { return find(Key); }
+  iterator getTail(const KeyT &Key) {
+    iterator I = find(Key);
+    if (I != end())
+      I = iterator(this, I.Prev(), KeyIndexOf(Key));
+    return I;
+  }
+
+  /// The bounds of the range of items sharing Key K. First member is the head
+  /// of the list, and the second member is a decrementable end iterator for
+  /// that key.
+  RangePair equal_range(const KeyT &K) {
+    iterator B = find(K);
+    iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
+    return make_pair(B, E);
+  }
+
+  /// Insert a new element at the tail of the subset list. Returns an iterator
+  /// to the newly added entry.
+  iterator insert(const ValueT &Val) {
+    unsigned Idx = sparseIndex(Val);
+    iterator I = findIndex(Idx);
+
+    unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID);
+
+    if (I == end()) {
+      // Make a singleton list
+      Sparse[Idx] = NodeIdx;
+      Dense[NodeIdx].Prev = NodeIdx;
+      return iterator(this, NodeIdx, Idx);
+    }
+
+    // Stick it at the end.
+    unsigned HeadIdx = I.Idx;
+    unsigned TailIdx = I.Prev();
+    Dense[TailIdx].Next = NodeIdx;
+    Dense[HeadIdx].Prev = NodeIdx;
+    Dense[NodeIdx].Prev = TailIdx;
+
+    return iterator(this, NodeIdx, Idx);
+  }
+
+  /// Erases an existing element identified by a valid iterator.
+  ///
+  /// This invalidates iterators pointing at the same entry, but erase() returns
+  /// an iterator pointing to the next element in the subset's list. This makes
+  /// it possible to erase selected elements while iterating over the subset:
+  ///
+  ///   tie(I, E) = Set.equal_range(Key);
+  ///   while (I != E)
+  ///     if (test(*I))
+  ///       I = Set.erase(I);
+  ///     else
+  ///       ++I;
+  ///
+  /// Note that if the last element in the subset list is erased, this will
+  /// return an end iterator which can be decremented to get the new tail (if it
+  /// exists):
+  ///
+  ///  tie(B, I) = Set.equal_range(Key);
+  ///  for (bool isBegin = B == I; !isBegin; /* empty */) {
+  ///    isBegin = (--I) == B;
+  ///    if (test(I))
+  ///      break;
+  ///    I = erase(I);
+  ///  }
+  iterator erase(iterator I) {
+    assert(I.isKeyed() && !I.isEnd() && !Dense[I.Idx].isTombstone() &&
+           "erasing invalid/end/tombstone iterator");
+
+    // First, unlink the node from its list. Then swap the node out with the
+    // dense vector's last entry
+    iterator NextI = unlink(Dense[I.Idx]);
+
+    // Put in a tombstone.
+    makeTombstone(I.Idx);
+
+    return NextI;
+  }
+
+  /// Erase all elements with the given key. This invalidates all
+  /// iterators of that key.
+  void eraseAll(const KeyT &K) {
+    for (iterator I = find(K); I != end(); /* empty */)
+      I = erase(I);
+  }
+
+private:
+  /// Unlink the node from its list. Returns the next node in the list.
+  iterator unlink(const SMSNode &N) {
+    if (isSingleton(N)) {
+      // Singleton is already unlinked
+      assert(N.Next == SMSNode::INVALID && "Singleton has next?");
+      return iterator(this, SMSNode::INVALID, ValIndexOf(N.Data));
+    }
+
+    if (isHead(N)) {
+      // If we're the head, then update the sparse array and our next.
+      Sparse[sparseIndex(N)] = N.Next;
+      Dense[N.Next].Prev = N.Prev;
+      return iterator(this, N.Next, ValIndexOf(N.Data));
+    }
+
+    if (N.isTail()) {
+      // If we're the tail, then update our head and our previous.
+      findIndex(sparseIndex(N)).setPrev(N.Prev);
+      Dense[N.Prev].Next = N.Next;
+
+      // Give back an end iterator that can be decremented
+      iterator I(this, N.Prev, ValIndexOf(N.Data));
+      return ++I;
+    }
+
+    // Otherwise, just drop us
+    Dense[N.Next].Prev = N.Prev;
+    Dense[N.Prev].Next = N.Next;
+    return iterator(this, N.Next, ValIndexOf(N.Data));
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
new file mode 100644
index 0000000..632d52a
--- /dev/null
+++ b/include/llvm/ADT/SparseSet.h
@@ -0,0 +1,311 @@
+//===--- llvm/ADT/SparseSet.h - Sparse set ----------------------*- 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 SparseSet class derived from the version described in
+// Briggs, Torczon, "An efficient representation for sparse sets", ACM Letters
+// on Programming Languages and Systems, Volume 2 Issue 1-4, March-Dec.  1993.
+//
+// A sparse set holds a small number of objects identified by integer keys from
+// a moderately sized universe. The sparse set uses more memory than other
+// containers in order to provide faster operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSESET_H
+#define LLVM_ADT_SPARSESET_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <limits>
+
+namespace llvm {
+
+/// SparseSetValTraits - Objects in a SparseSet are identified by keys that can
+/// be uniquely converted to a small integer less than the set's universe. This
+/// class allows the set to hold values that differ from the set's key type as
+/// long as an index can still be derived from the value. SparseSet never
+/// directly compares ValueT, only their indices, so it can map keys to
+/// arbitrary values. SparseSetValTraits computes the index from the value
+/// object. To compute the index from a key, SparseSet uses a separate
+/// KeyFunctorT template argument.
+///
+/// A simple type declaration, SparseSet<Type>, handles these cases:
+/// - unsigned key, identity index, identity value
+/// - unsigned key, identity index, fat value providing getSparseSetIndex()
+///
+/// The type declaration SparseSet<Type, UnaryFunction> handles:
+/// - unsigned key, remapped index, identity value (virtual registers)
+/// - pointer key, pointer-derived index, identity value (node+ID)
+/// - pointer key, pointer-derived index, fat value with getSparseSetIndex()
+///
+/// Only other, unexpected cases require specializing SparseSetValTraits.
+///
+/// For best results, ValueT should not require a destructor.
+///
+template<typename ValueT>
+struct SparseSetValTraits {
+  static unsigned getValIndex(const ValueT &Val) {
+    return Val.getSparseSetIndex();
+  }
+};
+
+/// SparseSetValFunctor - Helper class for selecting SparseSetValTraits. The
+/// generic implementation handles ValueT classes which either provide
+/// getSparseSetIndex() or specialize SparseSetValTraits<>.
+///
+template<typename KeyT, typename ValueT, typename KeyFunctorT>
+struct SparseSetValFunctor {
+  unsigned operator()(const ValueT &Val) const {
+    return SparseSetValTraits<ValueT>::getValIndex(Val);
+  }
+};
+
+/// SparseSetValFunctor<KeyT, KeyT> - Helper class for the common case of
+/// identity key/value sets.
+template<typename KeyT, typename KeyFunctorT>
+struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
+  unsigned operator()(const KeyT &Key) const {
+    return KeyFunctorT()(Key);
+  }
+};
+
+/// SparseSet - Fast set implmentation for objects that can be identified by
+/// small unsigned keys.
+///
+/// SparseSet allocates memory proportional to the size of the key universe, so
+/// it is not recommended for building composite data structures.  It is useful
+/// for algorithms that require a single set with fast operations.
+///
+/// Compared to DenseSet and DenseMap, SparseSet provides constant-time fast
+/// clear() and iteration as fast as a vector.  The find(), insert(), and
+/// erase() operations are all constant time, and typically faster than a hash
+/// table.  The iteration order doesn't depend on numerical key values, it only
+/// depends on the order of insert() and erase() operations.  When no elements
+/// have been erased, the iteration order is the insertion order.
+///
+/// Compared to BitVector, SparseSet<unsigned> uses 8x-40x more memory, but
+/// offers constant-time clear() and size() operations as well as fast
+/// iteration independent on the size of the universe.
+///
+/// SparseSet contains a dense vector holding all the objects and a sparse
+/// array holding indexes into the dense vector.  Most of the memory is used by
+/// the sparse array which is the size of the key universe.  The SparseT
+/// template parameter provides a space/speed tradeoff for sets holding many
+/// elements.
+///
+/// When SparseT is uint32_t, find() only touches 2 cache lines, but the sparse
+/// array uses 4 x Universe bytes.
+///
+/// When SparseT is uint8_t (the default), find() touches up to 2+[N/256] cache
+/// lines, but the sparse array is 4x smaller.  N is the number of elements in
+/// the set.
+///
+/// For sets that may grow to thousands of elements, SparseT should be set to
+/// uint16_t or uint32_t.
+///
+/// @tparam ValueT      The type of objects in the set.
+/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
+/// @tparam SparseT     An unsigned integer type. See above.
+///
+template<typename ValueT,
+         typename KeyFunctorT = llvm::identity<unsigned>,
+         typename SparseT = uint8_t>
+class SparseSet {
+  static_assert(std::numeric_limits<SparseT>::is_integer &&
+                !std::numeric_limits<SparseT>::is_signed,
+                "SparseT must be an unsigned integer type");
+
+  typedef typename KeyFunctorT::argument_type KeyT;
+  typedef SmallVector<ValueT, 8> DenseT;
+  typedef unsigned size_type;

+  DenseT Dense;
+  SparseT *Sparse;
+  unsigned Universe;
+  KeyFunctorT KeyIndexOf;
+  SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
+
+  // Disable copy construction and assignment.
+  // This data structure is not meant to be used that way.
+  SparseSet(const SparseSet&) LLVM_DELETED_FUNCTION;
+  SparseSet &operator=(const SparseSet&) LLVM_DELETED_FUNCTION;
+
+public:
+  typedef ValueT value_type;
+  typedef ValueT &reference;
+  typedef const ValueT &const_reference;
+  typedef ValueT *pointer;
+  typedef const ValueT *const_pointer;
+
+  SparseSet() : Sparse(nullptr), Universe(0) {}
+  ~SparseSet() { free(Sparse); }
+
+  /// setUniverse - Set the universe size which determines the largest key the
+  /// set can hold.  The universe must be sized before any elements can be
+  /// added.
+  ///
+  /// @param U Universe size. All object keys must be less than U.
+  ///
+  void setUniverse(unsigned U) {
+    // It's not hard to resize the universe on a non-empty set, but it doesn't
+    // seem like a likely use case, so we can add that code when we need it.
+    assert(empty() && "Can only resize universe on an empty map");
+    // Hysteresis prevents needless reallocations.
+    if (U >= Universe/4 && U <= Universe)
+      return;
+    free(Sparse);
+    // The Sparse array doesn't actually need to be initialized, so malloc
+    // would be enough here, but that will cause tools like valgrind to
+    // complain about branching on uninitialized data.
+    Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+    Universe = U;
+  }
+
+  // Import trivial vector stuff from DenseT.
+  typedef typename DenseT::iterator iterator;
+  typedef typename DenseT::const_iterator const_iterator;
+
+  const_iterator begin() const { return Dense.begin(); }
+  const_iterator end() const { return Dense.end(); }
+  iterator begin() { return Dense.begin(); }
+  iterator end() { return Dense.end(); }
+
+  /// empty - Returns true if the set is empty.
+  ///
+  /// This is not the same as BitVector::empty().
+  ///
+  bool empty() const { return Dense.empty(); }
+
+  /// size - Returns the number of elements in the set.
+  ///
+  /// This is not the same as BitVector::size() which returns the size of the
+  /// universe.
+  ///
+  size_type size() const { return Dense.size(); }
+
+  /// clear - Clears the set.  This is a very fast constant time operation.
+  ///
+  void clear() {
+    // Sparse does not need to be cleared, see find().
+    Dense.clear();
+  }
+
+  /// findIndex - Find an element by its index.
+  ///
+  /// @param   Idx A valid index to find.
+  /// @returns An iterator to the element identified by key, or end().
+  ///
+  iterator findIndex(unsigned Idx) {
+    assert(Idx < Universe && "Key out of range");
+    const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
+    for (unsigned i = Sparse[Idx], e = size(); i < e; i += Stride) {
+      const unsigned FoundIdx = ValIndexOf(Dense[i]);
+      assert(FoundIdx < Universe && "Invalid key in set. Did object mutate?");
+      if (Idx == FoundIdx)
+        return begin() + i;
+      // Stride is 0 when SparseT >= unsigned.  We don't need to loop.
+      if (!Stride)
+        break;
+    }
+    return end();
+  }
+
+  /// find - Find an element by its key.
+  ///
+  /// @param   Key A valid key to find.
+  /// @returns An iterator to the element identified by key, or end().
+  ///
+  iterator find(const KeyT &Key) {
+    return findIndex(KeyIndexOf(Key));
+  }
+
+  const_iterator find(const KeyT &Key) const {
+    return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
+  }
+
+  /// count - Returns 1 if this set contains an element identified by Key,
+  /// 0 otherwise.
+  ///
+  size_type count(const KeyT &Key) const {
+    return find(Key) == end() ? 0 : 1;
+  }
+
+  /// insert - Attempts to insert a new element.
+  ///
+  /// If Val is successfully inserted, return (I, true), where I is an iterator
+  /// pointing to the newly inserted element.
+  ///
+  /// If the set already contains an element with the same key as Val, return
+  /// (I, false), where I is an iterator pointing to the existing element.
+  ///
+  /// Insertion invalidates all iterators.
+  ///
+  std::pair<iterator, bool> insert(const ValueT &Val) {
+    unsigned Idx = ValIndexOf(Val);
+    iterator I = findIndex(Idx);
+    if (I != end())
+      return std::make_pair(I, false);
+    Sparse[Idx] = size();
+    Dense.push_back(Val);
+    return std::make_pair(end() - 1, true);
+  }
+
+  /// array subscript - If an element already exists with this key, return it.
+  /// Otherwise, automatically construct a new value from Key, insert it,
+  /// and return the newly inserted element.
+  ValueT &operator[](const KeyT &Key) {
+    return *insert(ValueT(Key)).first;
+  }
+
+  /// erase - Erases an existing element identified by a valid iterator.
+  ///
+  /// This invalidates all iterators, but erase() returns an iterator pointing
+  /// to the next element.  This makes it possible to erase selected elements
+  /// while iterating over the set:
+  ///
+  ///   for (SparseSet::iterator I = Set.begin(); I != Set.end();)
+  ///     if (test(*I))
+  ///       I = Set.erase(I);
+  ///     else
+  ///       ++I;
+  ///
+  /// Note that end() changes when elements are erased, unlike std::list.
+  ///
+  iterator erase(iterator I) {
+    assert(unsigned(I - begin()) < size() && "Invalid iterator");
+    if (I != end() - 1) {
+      *I = Dense.back();
+      unsigned BackIdx = ValIndexOf(Dense.back());
+      assert(BackIdx < Universe && "Invalid key in set. Did object mutate?");
+      Sparse[BackIdx] = I - begin();
+    }
+    // This depends on SmallVector::pop_back() not invalidating iterators.
+    // std::vector::pop_back() doesn't give that guarantee.
+    Dense.pop_back();
+    return I;
+  }
+
+  /// erase - Erases an element identified by Key, if it exists.
+  ///
+  /// @param   Key The key identifying the element to erase.
+  /// @returns True when an element was erased, false if no element was found.
+  ///
+  bool erase(const KeyT &Key) {
+    iterator I = find(Key);
+    if (I == end())
+      return false;
+    erase(I);
+    return true;
+  }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
new file mode 100644
index 0000000..d98abc3
--- /dev/null
+++ b/include/llvm/ADT/Statistic.h
@@ -0,0 +1,181 @@
+//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- 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 'Statistic' class, which is designed to be an easy way
+// to expose various metrics from passes.  These statistics are printed at the
+// end of a run (from llvm_shutdown), when the -stats command line option is
+// passed on the command line.
+//
+// This is useful for reporting information like the number of instructions
+// simplified, optimized or removed by various transformations, like this:
+//
+// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstsKilled;
+//
+// NOTE: Statistics *must* be declared as global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STATISTIC_H
+#define LLVM_ADT_STATISTIC_H
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Valgrind.h"
+
+namespace llvm {
+class raw_ostream;
+
+class Statistic {
+public:
+  const char *Name;
+  const char *Desc;
+  volatile llvm::sys::cas_flag Value;
+  bool Initialized;
+
+  llvm::sys::cas_flag getValue() const { return Value; }
+  const char *getName() const { return Name; }
+  const char *getDesc() const { return Desc; }
+
+  /// construct - This should only be called for non-global statistics.
+  void construct(const char *name, const char *desc) {
+    Name = name; Desc = desc;
+    Value = 0; Initialized = false;
+  }
+
+  // Allow use of this class as the value itself.
+  operator unsigned() const { return Value; }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
+   const Statistic &operator=(unsigned Val) {
+    Value = Val;
+    return init();
+  }
+
+  const Statistic &operator++() {
+    // FIXME: This function and all those that follow carefully use an
+    // atomic operation to update the value safely in the presence of
+    // concurrent accesses, but not to read the return value, so the
+    // return value is not thread safe.
+    sys::AtomicIncrement(&Value);
+    return init();
+  }
+
+  unsigned operator++(int) {
+    init();
+    unsigned OldValue = Value;
+    sys::AtomicIncrement(&Value);
+    return OldValue;
+  }
+
+  const Statistic &operator--() {
+    sys::AtomicDecrement(&Value);
+    return init();
+  }
+
+  unsigned operator--(int) {
+    init();
+    unsigned OldValue = Value;
+    sys::AtomicDecrement(&Value);
+    return OldValue;
+  }
+
+  const Statistic &operator+=(const unsigned &V) {
+    if (!V) return *this;
+    sys::AtomicAdd(&Value, V);
+    return init();
+  }
+
+  const Statistic &operator-=(const unsigned &V) {
+    if (!V) return *this;
+    sys::AtomicAdd(&Value, -V);
+    return init();
+  }
+
+  const Statistic &operator*=(const unsigned &V) {
+    sys::AtomicMul(&Value, V);
+    return init();
+  }
+
+  const Statistic &operator/=(const unsigned &V) {
+    sys::AtomicDiv(&Value, V);
+    return init();
+  }
+
+#else  // Statistics are disabled in release builds.
+
+  const Statistic &operator=(unsigned Val) {
+    return *this;
+  }
+
+  const Statistic &operator++() {
+    return *this;
+  }
+
+  unsigned operator++(int) {
+    return 0;
+  }
+
+  const Statistic &operator--() {
+    return *this;
+  }
+
+  unsigned operator--(int) {
+    return 0;
+  }
+
+  const Statistic &operator+=(const unsigned &V) {
+    return *this;
+  }
+
+  const Statistic &operator-=(const unsigned &V) {
+    return *this;
+  }
+
+  const Statistic &operator*=(const unsigned &V) {
+    return *this;
+  }
+
+  const Statistic &operator/=(const unsigned &V) {
+    return *this;
+  }
+
+#endif  // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
+
+protected:
+  Statistic &init() {
+    bool tmp = Initialized;
+    sys::MemoryFence();
+    if (!tmp) RegisterStatistic();
+    TsanHappensAfter(this);
+    return *this;
+  }
+  void RegisterStatistic();
+};
+
+// STATISTIC - A macro to make definition of statistics really simple.  This
+// automatically passes the DEBUG_TYPE of the file into the statistic.
+#define STATISTIC(VARNAME, DESC) \
+  static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
+
+/// \brief Enable the collection and printing of statistics.
+void EnableStatistics();
+
+/// \brief Check if statistics are enabled.
+bool AreStatisticsEnabled();
+
+/// \brief Print statistics to the file returned by CreateInfoOutputFile().
+void PrintStatistics();
+
+/// \brief Print statistics to the given output stream.
+void PrintStatistics(raw_ostream &OS);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
new file mode 100644
index 0000000..0992f5d
--- /dev/null
+++ b/include/llvm/ADT/StringExtras.h
@@ -0,0 +1,212 @@
+//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful when dealing with strings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGEXTRAS_H
+#define LLVM_ADT_STRINGEXTRAS_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include <iterator>
+
+namespace llvm {
+template<typename T> class SmallVectorImpl;
+
+/// hexdigit - Return the hexadecimal character for the
+/// given number \p X (which should be less than 16).
+static inline char hexdigit(unsigned X, bool LowerCase = false) {
+  const char HexChar = LowerCase ? 'a' : 'A';
+  return X < 10 ? '0' + X : HexChar + X - 10;
+}
+
+/// Construct a string ref from a boolean.
+static inline StringRef toStringRef(bool B) {
+  return StringRef(B ? "true" : "false");
+}
+
+/// Interpret the given character \p C as a hexadecimal digit and return its
+/// value.
+///
+/// If \p C is not a valid hex digit, -1U is returned.
+static inline unsigned hexDigitValue(char C) {
+  if (C >= '0' && C <= '9') return C-'0';
+  if (C >= 'a' && C <= 'f') return C-'a'+10U;
+  if (C >= 'A' && C <= 'F') return C-'A'+10U;
+  return -1U;
+}
+
+/// utohex_buffer - Emit the specified number into the buffer specified by
+/// BufferEnd, returning a pointer to the start of the string.  This can be used
+/// like this: (note that the buffer must be large enough to handle any number):
+///    char Buffer[40];
+///    printf("0x%s", utohex_buffer(X, Buffer+40));
+///
+/// This should only be used with unsigned types.
+///
+template<typename IntTy>
+static inline char *utohex_buffer(IntTy X, char *BufferEnd, bool LowerCase = false) {
+  char *BufPtr = BufferEnd;
+  *--BufPtr = 0;      // Null terminate buffer.
+  if (X == 0) {
+    *--BufPtr = '0';  // Handle special case.
+    return BufPtr;
+  }
+
+  while (X) {
+    unsigned char Mod = static_cast<unsigned char>(X) & 15;
+    *--BufPtr = hexdigit(Mod, LowerCase);
+    X >>= 4;
+  }
+  return BufPtr;
+}
+
+static inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
+  char Buffer[17];
+  return utohex_buffer(X, Buffer+17, LowerCase);
+}
+
+static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
+  char Buffer[11];
+  char *BufPtr = Buffer+11;
+
+  if (X == 0) *--BufPtr = '0';  // Handle special case...
+
+  while (X) {
+    *--BufPtr = '0' + char(X % 10);
+    X /= 10;
+  }
+
+  if (isNeg) *--BufPtr = '-';   // Add negative sign...
+
+  return std::string(BufPtr, Buffer+11);
+}
+
+static inline std::string utostr(uint64_t X, bool isNeg = false) {
+  char Buffer[21];
+  char *BufPtr = Buffer+21;
+
+  if (X == 0) *--BufPtr = '0';  // Handle special case...
+
+  while (X) {
+    *--BufPtr = '0' + char(X % 10);
+    X /= 10;
+  }
+
+  if (isNeg) *--BufPtr = '-';   // Add negative sign...
+  return std::string(BufPtr, Buffer+21);
+}
+
+
+static inline std::string itostr(int64_t X) {
+  if (X < 0)
+    return utostr(static_cast<uint64_t>(-X), true);
+  else
+    return utostr(static_cast<uint64_t>(X));
+}
+
+/// StrInStrNoCase - Portable version of strcasestr.  Locates the first
+/// occurrence of string 's1' in string 's2', ignoring case.  Returns
+/// the offset of s2 in s1 or npos if s2 cannot be found.
+StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
+
+/// getToken - This function extracts one token from source, ignoring any
+/// leading characters that appear in the Delimiters string, and ending the
+/// token at any of the characters that appear in the Delimiters string.  If
+/// there are no tokens in the source string, an empty string is returned.
+/// The function returns a pair containing the extracted token and the
+/// remaining tail string.
+std::pair<StringRef, StringRef> getToken(StringRef Source,
+                                         StringRef Delimiters = " \t\n\v\f\r");
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void SplitString(StringRef Source,
+                 SmallVectorImpl<StringRef> &OutFragments,
+                 StringRef Delimiters = " \t\n\v\f\r");
+
+/// HashString - Hash function for strings.
+///
+/// This is the Bernstein hash function.
+//
+// FIXME: Investigate whether a modified bernstein hash function performs
+// better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
+//   X*33+c -> X*33^c
+static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
+  for (StringRef::size_type i = 0, e = Str.size(); i != e; ++i)
+    Result = Result * 33 + (unsigned char)Str[i];
+  return Result;
+}
+
+/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
+static inline StringRef getOrdinalSuffix(unsigned Val) {
+  // It is critically important that we do this perfectly for
+  // user-written sequences with over 100 elements.
+  switch (Val % 100) {
+  case 11:
+  case 12:
+  case 13:
+    return "th";
+  default:
+    switch (Val % 10) {
+      case 1: return "st";
+      case 2: return "nd";
+      case 3: return "rd";
+      default: return "th";
+    }
+  }
+}
+
+template <typename IteratorT>
+inline std::string join_impl(IteratorT Begin, IteratorT End,
+                             StringRef Separator, std::input_iterator_tag) {
+  std::string S;
+  if (Begin == End)
+    return S;
+
+  S += (*Begin);
+  while (++Begin != End) {
+    S += Separator;
+    S += (*Begin);
+  }
+  return S;
+}
+
+template <typename IteratorT>
+inline std::string join_impl(IteratorT Begin, IteratorT End,
+                             StringRef Separator, std::forward_iterator_tag) {
+  std::string S;
+  if (Begin == End)
+    return S;
+
+  size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
+  for (IteratorT I = Begin; I != End; ++I)
+    Len += (*Begin).size();
+  S.reserve(Len);
+  S += (*Begin);
+  while (++Begin != End) {
+    S += Separator;
+    S += (*Begin);
+  }
+  return S;
+}
+
+/// Joins the strings in the range [Begin, End), adding Separator between
+/// the elements.
+template <typename IteratorT>
+inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) {
+  typedef typename std::iterator_traits<IteratorT>::iterator_category tag;
+  return join_impl(Begin, End, Separator, tag());
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
new file mode 100644
index 0000000..c40e5e2
--- /dev/null
+++ b/include/llvm/ADT/StringMap.h
@@ -0,0 +1,477 @@
+//===--- StringMap.h - String Hash table map interface ----------*- 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 StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAP_H
+#define LLVM_ADT_STRINGMAP_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <cstring>
+#include <utility>
+
+namespace llvm {
+  template<typename ValueT>
+  class StringMapConstIterator;
+  template<typename ValueT>
+  class StringMapIterator;
+  template<typename ValueTy>
+  class StringMapEntry;
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+  unsigned StrLen;
+public:
+  explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+
+  unsigned getKeyLength() const { return StrLen; }
+};
+
+/// StringMapImpl - This is the base class of StringMap that is shared among
+/// all of its instantiations.
+class StringMapImpl {
+protected:
+  // Array of NumBuckets pointers to entries, null pointers are holes.
+  // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
+  // by an array of the actual hash values as unsigned integers.
+  StringMapEntryBase **TheTable;
+  unsigned NumBuckets;
+  unsigned NumItems;
+  unsigned NumTombstones;
+  unsigned ItemSize;
+protected:
+  explicit StringMapImpl(unsigned itemSize)
+      : TheTable(nullptr),
+        // Initialize the map with zero buckets to allocation.
+        NumBuckets(0), NumItems(0), NumTombstones(0), ItemSize(itemSize) {}
+  StringMapImpl(StringMapImpl &&RHS)
+      : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
+        NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
+        ItemSize(RHS.ItemSize) {
+    RHS.TheTable = nullptr;
+    RHS.NumBuckets = 0;
+    RHS.NumItems = 0;
+    RHS.NumTombstones = 0;
+  }
+
+  StringMapImpl(unsigned InitSize, unsigned ItemSize);
+  unsigned RehashTable(unsigned BucketNo = 0);
+
+  /// LookupBucketFor - Look up the bucket that the specified string should end
+  /// up in.  If it already exists as a key in the map, the Item pointer for the
+  /// specified bucket will be non-null.  Otherwise, it will be null.  In either
+  /// case, the FullHashValue field of the bucket will be set to the hash value
+  /// of the string.
+  unsigned LookupBucketFor(StringRef Key);
+
+  /// FindKey - Look up the bucket that contains the specified key. If it exists
+  /// in the map, return the bucket number of the key.  Otherwise return -1.
+  /// This does not modify the map.
+  int FindKey(StringRef Key) const;
+
+  /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+  /// delete it.  This aborts if the value isn't in the table.
+  void RemoveKey(StringMapEntryBase *V);
+
+  /// RemoveKey - Remove the StringMapEntry for the specified key from the
+  /// table, returning it.  If the key is not in the table, this returns null.
+  StringMapEntryBase *RemoveKey(StringRef Key);
+private:
+  void init(unsigned Size);
+public:
+  static StringMapEntryBase *getTombstoneVal() {
+    return (StringMapEntryBase*)-1;
+  }
+
+  unsigned getNumBuckets() const { return NumBuckets; }
+  unsigned getNumItems() const { return NumItems; }
+
+  bool empty() const { return NumItems == 0; }
+  unsigned size() const { return NumItems; }
+
+  void swap(StringMapImpl &Other) {
+    std::swap(TheTable, Other.TheTable);
+    std::swap(NumBuckets, Other.NumBuckets);
+    std::swap(NumItems, Other.NumItems);
+    std::swap(NumTombstones, Other.NumTombstones);
+  }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap.  It contains the Value itself and the key: the string length
+/// and data.
+template<typename ValueTy>
+class StringMapEntry : public StringMapEntryBase {
+  StringMapEntry(StringMapEntry &E) LLVM_DELETED_FUNCTION;
+public:
+  ValueTy second;
+
+  explicit StringMapEntry(unsigned strLen)
+    : StringMapEntryBase(strLen), second() {}
+  StringMapEntry(unsigned strLen, ValueTy V)
+      : StringMapEntryBase(strLen), second(std::move(V)) {}
+
+  StringRef getKey() const {
+    return StringRef(getKeyData(), getKeyLength());
+  }
+
+  const ValueTy &getValue() const { return second; }
+  ValueTy &getValue() { return second; }
+
+  void setValue(const ValueTy &V) { second = V; }
+
+  /// getKeyData - Return the start of the string data that is the key for this
+  /// value.  The string data is always stored immediately after the
+  /// StringMapEntry object.
+  const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
+
+  StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
+
+  /// Create - Create a StringMapEntry for the specified key and default
+  /// construct the value.
+  template<typename AllocatorTy, typename InitType>
+  static StringMapEntry *Create(StringRef Key,
+                                AllocatorTy &Allocator,
+                                InitType InitVal) {
+    unsigned KeyLength = Key.size();
+
+    // Allocate a new item with space for the string at the end and a null
+    // terminator.
+    unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
+      KeyLength+1;
+    unsigned Alignment = alignOf<StringMapEntry>();
+
+    StringMapEntry *NewItem =
+      static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
+
+    // Default construct the value.
+    new (NewItem) StringMapEntry(KeyLength, std::move(InitVal));
+
+    // Copy the string information.
+    char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
+    memcpy(StrBuffer, Key.data(), KeyLength);
+    StrBuffer[KeyLength] = 0;  // Null terminate for convenience of clients.
+    return NewItem;
+  }
+
+  template<typename AllocatorTy>
+  static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator) {
+    return Create(Key, Allocator, ValueTy());
+  }
+
+  /// Create - Create a StringMapEntry with normal malloc/free.
+  template<typename InitType>
+  static StringMapEntry *Create(StringRef Key, InitType InitVal) {
+    MallocAllocator A;
+    return Create(Key, A, std::move(InitVal));
+  }
+
+  static StringMapEntry *Create(StringRef Key) {
+    return Create(Key, ValueTy());
+  }
+
+  /// GetStringMapEntryFromValue - Given a value that is known to be embedded
+  /// into a StringMapEntry, return the StringMapEntry itself.
+  static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
+    StringMapEntry *EPtr = 0;
+    char *Ptr = reinterpret_cast<char*>(&V) -
+                  (reinterpret_cast<char*>(&EPtr->second) -
+                   reinterpret_cast<char*>(EPtr));
+    return *reinterpret_cast<StringMapEntry*>(Ptr);
+  }
+  static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
+    return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
+  }
+
+  /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
+  /// into a StringMapEntry, return the StringMapEntry itself.
+  static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
+    char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
+    return *reinterpret_cast<StringMapEntry*>(Ptr);
+  }
+
+  /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+  /// specified allocator.
+  template<typename AllocatorTy>
+  void Destroy(AllocatorTy &Allocator) {
+    // Free memory referenced by the item.
+    unsigned AllocSize =
+        static_cast<unsigned>(sizeof(StringMapEntry)) + getKeyLength() + 1;
+    this->~StringMapEntry();
+    Allocator.Deallocate(static_cast<void *>(this), AllocSize);
+  }
+
+  /// Destroy this object, releasing memory back to the malloc allocator.
+  void Destroy() {
+    MallocAllocator A;
+    Destroy(A);
+  }
+};
+
+
+/// StringMap - This is an unconventional map that is specialized for handling
+/// keys that are "strings", which are basically ranges of bytes. This does some
+/// funky memory allocation and hashing things to make it extremely efficient,
+/// storing the string data *after* the value in the map.
+template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+class StringMap : public StringMapImpl {
+  AllocatorTy Allocator;
+public:
+  typedef StringMapEntry<ValueTy> MapEntryTy;
+  
+  StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
+  explicit StringMap(unsigned InitialSize)
+    : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
+
+  explicit StringMap(AllocatorTy A)
+    : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
+
+  StringMap(unsigned InitialSize, AllocatorTy A)
+    : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
+      Allocator(A) {}
+
+  StringMap(StringMap &&RHS)
+      : StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {}
+
+  StringMap &operator=(StringMap RHS) {
+    StringMapImpl::swap(RHS);
+    std::swap(Allocator, RHS.Allocator);
+    return *this;
+  }
+
+  // FIXME: Implement copy operations if/when they're needed.
+
+  AllocatorTy &getAllocator() { return Allocator; }
+  const AllocatorTy &getAllocator() const { return Allocator; }
+
+  typedef const char* key_type;
+  typedef ValueTy mapped_type;
+  typedef StringMapEntry<ValueTy> value_type;
+  typedef size_t size_type;
+
+  typedef StringMapConstIterator<ValueTy> const_iterator;
+  typedef StringMapIterator<ValueTy> iterator;
+
+  iterator begin() {
+    return iterator(TheTable, NumBuckets == 0);
+  }
+  iterator end() {
+    return iterator(TheTable+NumBuckets, true);
+  }
+  const_iterator begin() const {
+    return const_iterator(TheTable, NumBuckets == 0);
+  }
+  const_iterator end() const {
+    return const_iterator(TheTable+NumBuckets, true);
+  }
+
+  iterator find(StringRef Key) {
+    int Bucket = FindKey(Key);
+    if (Bucket == -1) return end();
+    return iterator(TheTable+Bucket, true);
+  }
+
+  const_iterator find(StringRef Key) const {
+    int Bucket = FindKey(Key);
+    if (Bucket == -1) return end();
+    return const_iterator(TheTable+Bucket, true);
+  }
+
+  /// lookup - Return the entry for the specified key, or a default
+  /// constructed value if no such entry exists.
+  ValueTy lookup(StringRef Key) const {
+    const_iterator it = find(Key);
+    if (it != end())
+      return it->second;
+    return ValueTy();
+  }
+
+  ValueTy &operator[](StringRef Key) {
+    return GetOrCreateValue(Key).getValue();
+  }
+
+  /// count - Return 1 if the element is in the map, 0 otherwise.
+  size_type count(StringRef Key) const {
+    return find(Key) == end() ? 0 : 1;
+  }
+
+  /// insert - Insert the specified key/value pair into the map.  If the key
+  /// already exists in the map, return false and ignore the request, otherwise
+  /// insert it and return true.
+  bool insert(MapEntryTy *KeyValue) {
+    unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
+    StringMapEntryBase *&Bucket = TheTable[BucketNo];
+    if (Bucket && Bucket != getTombstoneVal())
+      return false;  // Already exists in map.
+
+    if (Bucket == getTombstoneVal())
+      --NumTombstones;
+    Bucket = KeyValue;
+    ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
+
+    RehashTable();
+    return true;
+  }
+
+  /// insert - Inserts the specified key/value pair into the map if the key
+  /// isn't already in the map. The bool component of the returned pair is true
+  /// if and only if the insertion takes place, and the iterator component of
+  /// the pair points to the element with key equivalent to the key of the pair.
+  std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
+    unsigned BucketNo = LookupBucketFor(KV.first);
+    StringMapEntryBase *&Bucket = TheTable[BucketNo];
+    if (Bucket && Bucket != getTombstoneVal())
+      return std::make_pair(iterator(TheTable + BucketNo, false),
+                            false); // Already exists in map.
+
+    if (Bucket == getTombstoneVal())
+      --NumTombstones;
+    Bucket =
+        MapEntryTy::Create(KV.first, Allocator, std::move(KV.second));
+    ++NumItems;
+    assert(NumItems + NumTombstones <= NumBuckets);
+
+    BucketNo = RehashTable(BucketNo);
+    return std::make_pair(iterator(TheTable + BucketNo, false), true);
+  }
+
+  // clear - Empties out the StringMap
+  void clear() {
+    if (empty()) return;
+
+    // Zap all values, resetting the keys back to non-present (not tombstone),
+    // which is safe because we're removing all elements.
+    for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+      StringMapEntryBase *&Bucket = TheTable[I];
+      if (Bucket && Bucket != getTombstoneVal()) {
+        static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+      }
+      Bucket = nullptr;
+    }
+
+    NumItems = 0;
+    NumTombstones = 0;
+  }
+
+  /// GetOrCreateValue - Look up the specified key in the table.  If a value
+  /// exists, return it.  Otherwise, default construct a value, insert it, and
+  /// return.
+  template <typename InitTy>
+  MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
+    return *insert(std::make_pair(Key, std::move(Val))).first;
+  }
+
+  MapEntryTy &GetOrCreateValue(StringRef Key) {
+    return GetOrCreateValue(Key, ValueTy());
+  }
+
+  /// remove - Remove the specified key/value pair from the map, but do not
+  /// erase it.  This aborts if the key is not in the map.
+  void remove(MapEntryTy *KeyValue) {
+    RemoveKey(KeyValue);
+  }
+
+  void erase(iterator I) {
+    MapEntryTy &V = *I;
+    remove(&V);
+    V.Destroy(Allocator);
+  }
+
+  bool erase(StringRef Key) {
+    iterator I = find(Key);
+    if (I == end()) return false;
+    erase(I);
+    return true;
+  }
+
+  ~StringMap() {
+    // Delete all the elements in the map, but don't reset the elements
+    // to default values.  This is a copy of clear(), but avoids unnecessary
+    // work not required in the destructor.
+    if (!empty()) {
+      for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+        StringMapEntryBase *Bucket = TheTable[I];
+        if (Bucket && Bucket != getTombstoneVal()) {
+          static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+        }
+      }
+    }
+    free(TheTable);
+  }
+};
+
+
+template<typename ValueTy>
+class StringMapConstIterator {
+protected:
+  StringMapEntryBase **Ptr;
+public:
+  typedef StringMapEntry<ValueTy> value_type;
+
+  StringMapConstIterator() : Ptr(nullptr) { }
+
+  explicit StringMapConstIterator(StringMapEntryBase **Bucket,
+                                  bool NoAdvance = false)
+  : Ptr(Bucket) {
+    if (!NoAdvance) AdvancePastEmptyBuckets();
+  }
+
+  const value_type &operator*() const {
+    return *static_cast<StringMapEntry<ValueTy>*>(*Ptr);
+  }
+  const value_type *operator->() const {
+    return static_cast<StringMapEntry<ValueTy>*>(*Ptr);
+  }
+
+  bool operator==(const StringMapConstIterator &RHS) const {
+    return Ptr == RHS.Ptr;
+  }
+  bool operator!=(const StringMapConstIterator &RHS) const {
+    return Ptr != RHS.Ptr;
+  }
+
+  inline StringMapConstIterator& operator++() {   // Preincrement
+    ++Ptr;
+    AdvancePastEmptyBuckets();
+    return *this;
+  }
+  StringMapConstIterator operator++(int) {        // Postincrement
+    StringMapConstIterator tmp = *this; ++*this; return tmp;
+  }
+
+private:
+  void AdvancePastEmptyBuckets() {
+    while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
+      ++Ptr;
+  }
+};
+
+template<typename ValueTy>
+class StringMapIterator : public StringMapConstIterator<ValueTy> {
+public:
+  StringMapIterator() {}
+  explicit StringMapIterator(StringMapEntryBase **Bucket,
+                             bool NoAdvance = false)
+    : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
+  }
+  StringMapEntry<ValueTy> &operator*() const {
+    return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+  }
+  StringMapEntry<ValueTy> *operator->() const {
+    return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
new file mode 100644
index 0000000..1f413e8
--- /dev/null
+++ b/include/llvm/ADT/StringRef.h
@@ -0,0 +1,564 @@
+//===--- StringRef.h - Constant String Reference Wrapper --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGREF_H
+#define LLVM_ADT_STRINGREF_H
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <utility>
+
+namespace llvm {
+  template <typename T>
+  class SmallVectorImpl;
+  class APInt;
+  class hash_code;
+  class StringRef;
+
+  /// Helper functions for StringRef::getAsInteger.
+  bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
+                            unsigned long long &Result);
+
+  bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
+
+  /// StringRef - Represent a constant reference to a string, i.e. a character
+  /// array and a length, which need not be null terminated.
+  ///
+  /// This class does not own the string data, it is expected to be used in
+  /// situations where the character data resides in some other buffer, whose
+  /// lifetime extends past that of the StringRef. For this reason, it is not in
+  /// general safe to store a StringRef.
+  class StringRef {
+  public:
+    typedef const char *iterator;
+    typedef const char *const_iterator;
+    static const size_t npos = ~size_t(0);
+    typedef size_t size_type;
+
+  private:
+    /// The start of the string, in an external buffer.
+    const char *Data;
+
+    /// The length of the string.
+    size_t Length;
+
+    // Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min()
+    // Changing the arg of min to be an integer, instead of a reference to an
+    // integer works around this bug.
+    static size_t min(size_t a, size_t b) { return a < b ? a : b; }
+    static size_t max(size_t a, size_t b) { return a > b ? a : b; }
+
+    // Workaround memcmp issue with null pointers (undefined behavior)
+    // by providing a specialized version
+    static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
+      if (Length == 0) { return 0; }
+      return ::memcmp(Lhs,Rhs,Length);
+    }
+
+  public:
+    /// @name Constructors
+    /// @{
+
+    /// Construct an empty string ref.
+    /*implicit*/ StringRef() : Data(nullptr), Length(0) {}
+
+    /// Construct a string ref from a cstring.
+    /*implicit*/ StringRef(const char *Str)
+      : Data(Str) {
+        assert(Str && "StringRef cannot be built from a NULL argument");
+        Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior
+      }
+
+    /// Construct a string ref from a pointer and length.
+    /*implicit*/ StringRef(const char *data, size_t length)
+      : Data(data), Length(length) {
+        assert((data || length == 0) &&
+        "StringRef cannot be built from a NULL argument with non-null length");
+      }
+
+    /// Construct a string ref from an std::string.
+    /*implicit*/ StringRef(const std::string &Str)
+      : Data(Str.data()), Length(Str.length()) {}
+
+    /// @}
+    /// @name Iterators
+    /// @{
+
+    iterator begin() const { return Data; }
+
+    iterator end() const { return Data + Length; }
+
+    /// @}
+    /// @name String Operations
+    /// @{
+
+    /// data - Get a pointer to the start of the string (which may not be null
+    /// terminated).
+    const char *data() const { return Data; }
+
+    /// empty - Check if the string is empty.
+    bool empty() const { return Length == 0; }
+
+    /// size - Get the string size.
+    size_t size() const { return Length; }
+
+    /// front - Get the first character in the string.
+    char front() const {
+      assert(!empty());
+      return Data[0];
+    }
+
+    /// back - Get the last character in the string.
+    char back() const {
+      assert(!empty());
+      return Data[Length-1];
+    }
+
+    // copy - Allocate copy in Allocator and return StringRef to it.
+    template <typename Allocator> StringRef copy(Allocator &A) {
+      char *S = A.template Allocate<char>(Length);
+      std::copy(begin(), end(), S);
+      return StringRef(S, Length);
+    }
+
+    /// equals - Check for string equality, this is more efficient than
+    /// compare() when the relative ordering of inequal strings isn't needed.
+    bool equals(StringRef RHS) const {
+      return (Length == RHS.Length &&
+              compareMemory(Data, RHS.Data, RHS.Length) == 0);
+    }
+
+    /// equals_lower - Check for string equality, ignoring case.
+    bool equals_lower(StringRef RHS) const {
+      return Length == RHS.Length && compare_lower(RHS) == 0;
+    }
+
+    /// compare - Compare two strings; the result is -1, 0, or 1 if this string
+    /// is lexicographically less than, equal to, or greater than the \p RHS.
+    int compare(StringRef RHS) const {
+      // Check the prefix for a mismatch.
+      if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
+        return Res < 0 ? -1 : 1;
+
+      // Otherwise the prefixes match, so we only need to check the lengths.
+      if (Length == RHS.Length)
+        return 0;
+      return Length < RHS.Length ? -1 : 1;
+    }
+
+    /// compare_lower - Compare two strings, ignoring case.
+    int compare_lower(StringRef RHS) const;
+
+    /// compare_numeric - Compare two strings, treating sequences of digits as
+    /// numbers.
+    int compare_numeric(StringRef RHS) const;
+
+    /// \brief Determine the edit distance between this string and another
+    /// string.
+    ///
+    /// \param Other the string to compare this string against.
+    ///
+    /// \param AllowReplacements whether to allow character
+    /// replacements (change one character into another) as a single
+    /// operation, rather than as two operations (an insertion and a
+    /// removal).
+    ///
+    /// \param MaxEditDistance If non-zero, the maximum edit distance that
+    /// this routine is allowed to compute. If the edit distance will exceed
+    /// that maximum, returns \c MaxEditDistance+1.
+    ///
+    /// \returns the minimum number of character insertions, removals,
+    /// or (if \p AllowReplacements is \c true) replacements needed to
+    /// transform one of the given strings into the other. If zero,
+    /// the strings are identical.
+    unsigned edit_distance(StringRef Other, bool AllowReplacements = true,
+                           unsigned MaxEditDistance = 0) const;
+
+    /// str - Get the contents as an std::string.
+    std::string str() const {
+      if (!Data) return std::string();
+      return std::string(Data, Length);
+    }
+
+    /// @}
+    /// @name Operator Overloads
+    /// @{
+
+    char operator[](size_t Index) const {
+      assert(Index < Length && "Invalid index!");
+      return Data[Index];
+    }
+
+    /// @}
+    /// @name Type Conversions
+    /// @{
+
+    operator std::string() const {
+      return str();
+    }
+
+    /// @}
+    /// @name String Predicates
+    /// @{
+
+    /// Check if this string starts with the given \p Prefix.
+    bool startswith(StringRef Prefix) const {
+      return Length >= Prefix.Length &&
+             compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
+    }
+
+    /// Check if this string starts with the given \p Prefix, ignoring case.
+    bool startswith_lower(StringRef Prefix) const;
+
+    /// Check if this string ends with the given \p Suffix.
+    bool endswith(StringRef Suffix) const {
+      return Length >= Suffix.Length &&
+        compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
+    }
+
+    /// Check if this string ends with the given \p Suffix, ignoring case.
+    bool endswith_lower(StringRef Suffix) const;
+
+    /// @}
+    /// @name String Searching
+    /// @{
+
+    /// Search for the first character \p C in the string.
+    ///
+    /// \returns The index of the first occurrence of \p C, or npos if not
+    /// found.
+    size_t find(char C, size_t From = 0) const {
+      for (size_t i = min(From, Length), e = Length; i != e; ++i)
+        if (Data[i] == C)
+          return i;
+      return npos;
+    }
+
+    /// Search for the first string \p Str in the string.
+    ///
+    /// \returns The index of the first occurrence of \p Str, or npos if not
+    /// found.
+    size_t find(StringRef Str, size_t From = 0) const;
+
+    /// Search for the last character \p C in the string.
+    ///
+    /// \returns The index of the last occurrence of \p C, or npos if not
+    /// found.
+    size_t rfind(char C, size_t From = npos) const {
+      From = min(From, Length);
+      size_t i = From;
+      while (i != 0) {
+        --i;
+        if (Data[i] == C)
+          return i;
+      }
+      return npos;
+    }
+
+    /// Search for the last string \p Str in the string.
+    ///
+    /// \returns The index of the last occurrence of \p Str, or npos if not
+    /// found.
+    size_t rfind(StringRef Str) const;
+
+    /// Find the first character in the string that is \p C, or npos if not
+    /// found. Same as find.
+    size_t find_first_of(char C, size_t From = 0) const {
+      return find(C, From);
+    }
+
+    /// Find the first character in the string that is in \p Chars, or npos if
+    /// not found.
+    ///
+    /// Complexity: O(size() + Chars.size())
+    size_t find_first_of(StringRef Chars, size_t From = 0) const;
+
+    /// Find the first character in the string that is not \p C or npos if not
+    /// found.
+    size_t find_first_not_of(char C, size_t From = 0) const;
+
+    /// Find the first character in the string that is not in the string
+    /// \p Chars, or npos if not found.
+    ///
+    /// Complexity: O(size() + Chars.size())
+    size_t find_first_not_of(StringRef Chars, size_t From = 0) const;
+
+    /// Find the last character in the string that is \p C, or npos if not
+    /// found.
+    size_t find_last_of(char C, size_t From = npos) const {
+      return rfind(C, From);
+    }
+
+    /// Find the last character in the string that is in \p C, or npos if not
+    /// found.
+    ///
+    /// Complexity: O(size() + Chars.size())
+    size_t find_last_of(StringRef Chars, size_t From = npos) const;
+
+    /// Find the last character in the string that is not \p C, or npos if not
+    /// found.
+    size_t find_last_not_of(char C, size_t From = npos) const;
+
+    /// Find the last character in the string that is not in \p Chars, or
+    /// npos if not found.
+    ///
+    /// Complexity: O(size() + Chars.size())
+    size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
+
+    /// @}
+    /// @name Helpful Algorithms
+    /// @{
+
+    /// Return the number of occurrences of \p C in the string.
+    size_t count(char C) const {
+      size_t Count = 0;
+      for (size_t i = 0, e = Length; i != e; ++i)
+        if (Data[i] == C)
+          ++Count;
+      return Count;
+    }
+
+    /// Return the number of non-overlapped occurrences of \p Str in
+    /// the string.
+    size_t count(StringRef Str) const;
+
+    /// Parse the current string as an integer of the specified radix.  If
+    /// \p Radix is specified as zero, this does radix autosensing using
+    /// extended C rules: 0 is octal, 0x is hex, 0b is binary.
+    ///
+    /// If the string is invalid or if only a subset of the string is valid,
+    /// this returns true to signify the error.  The string is considered
+    /// erroneous if empty or if it overflows T.
+    template <typename T>
+    typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
+    getAsInteger(unsigned Radix, T &Result) const {
+      long long LLVal;
+      if (getAsSignedInteger(*this, Radix, LLVal) ||
+            static_cast<T>(LLVal) != LLVal)
+        return true;
+      Result = LLVal;
+      return false;
+    }
+
+    template <typename T>
+    typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
+    getAsInteger(unsigned Radix, T &Result) const {
+      unsigned long long ULLVal;
+      if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
+            static_cast<T>(ULLVal) != ULLVal)
+        return true;
+      Result = ULLVal;
+      return false;
+    }
+
+    /// Parse the current string as an integer of the specified \p Radix, or of
+    /// an autosensed radix if the \p Radix given is 0.  The current value in
+    /// \p Result is discarded, and the storage is changed to be wide enough to
+    /// store the parsed integer.
+    ///
+    /// \returns true if the string does not solely consist of a valid
+    /// non-empty number in the appropriate base.
+    ///
+    /// APInt::fromString is superficially similar but assumes the
+    /// string is well-formed in the given radix.
+    bool getAsInteger(unsigned Radix, APInt &Result) const;
+
+    /// @}
+    /// @name String Operations
+    /// @{
+
+    // Convert the given ASCII string to lowercase.
+    std::string lower() const;
+
+    /// Convert the given ASCII string to uppercase.
+    std::string upper() const;
+
+    /// @}
+    /// @name Substring Operations
+    /// @{
+
+    /// Return a reference to the substring from [Start, Start + N).
+    ///
+    /// \param Start The index of the starting character in the substring; if
+    /// the index is npos or greater than the length of the string then the
+    /// empty substring will be returned.
+    ///
+    /// \param N The number of characters to included in the substring. If N
+    /// exceeds the number of characters remaining in the string, the string
+    /// suffix (starting with \p Start) will be returned.
+    StringRef substr(size_t Start, size_t N = npos) const {
+      Start = min(Start, Length);
+      return StringRef(Data + Start, min(N, Length - Start));
+    }
+
+    /// Return a StringRef equal to 'this' but with the first \p N elements
+    /// dropped.
+    StringRef drop_front(size_t N = 1) const {
+      assert(size() >= N && "Dropping more elements than exist");
+      return substr(N);
+    }
+
+    /// Return a StringRef equal to 'this' but with the last \p N elements
+    /// dropped.
+    StringRef drop_back(size_t N = 1) const {
+      assert(size() >= N && "Dropping more elements than exist");
+      return substr(0, size()-N);
+    }
+
+    /// Return a reference to the substring from [Start, End).
+    ///
+    /// \param Start The index of the starting character in the substring; if
+    /// the index is npos or greater than the length of the string then the
+    /// empty substring will be returned.
+    ///
+    /// \param End The index following the last character to include in the
+    /// substring. If this is npos, or less than \p Start, or exceeds the
+    /// number of characters remaining in the string, the string suffix
+    /// (starting with \p Start) will be returned.
+    StringRef slice(size_t Start, size_t End) const {
+      Start = min(Start, Length);
+      End = min(max(Start, End), Length);
+      return StringRef(Data + Start, End - Start);
+    }
+
+    /// Split into two substrings around the first occurrence of a separator
+    /// character.
+    ///
+    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
+    /// such that (*this == LHS + Separator + RHS) is true and RHS is
+    /// maximal. If \p Separator is not in the string, then the result is a
+    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+    ///
+    /// \param Separator The character to split on.
+    /// \returns The split substrings.
+    std::pair<StringRef, StringRef> split(char Separator) const {
+      size_t Idx = find(Separator);
+      if (Idx == npos)
+        return std::make_pair(*this, StringRef());
+      return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+    }
+
+    /// Split into two substrings around the first occurrence of a separator
+    /// string.
+    ///
+    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
+    /// such that (*this == LHS + Separator + RHS) is true and RHS is
+    /// maximal. If \p Separator is not in the string, then the result is a
+    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+    ///
+    /// \param Separator - The string to split on.
+    /// \return - The split substrings.
+    std::pair<StringRef, StringRef> split(StringRef Separator) const {
+      size_t Idx = find(Separator);
+      if (Idx == npos)
+        return std::make_pair(*this, StringRef());
+      return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
+    }
+
+    /// Split into substrings around the occurrences of a separator string.
+    ///
+    /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
+    /// \p MaxSplit splits are done and consequently <= \p MaxSplit
+    /// elements are added to A.
+    /// If \p KeepEmpty is false, empty strings are not added to \p A. They
+    /// still count when considering \p MaxSplit
+    /// An useful invariant is that
+    /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
+    ///
+    /// \param A - Where to put the substrings.
+    /// \param Separator - The string to split on.
+    /// \param MaxSplit - The maximum number of times the string is split.
+    /// \param KeepEmpty - True if empty substring should be added.
+    void split(SmallVectorImpl<StringRef> &A,
+               StringRef Separator, int MaxSplit = -1,
+               bool KeepEmpty = true) const;
+
+    /// Split into two substrings around the last occurrence of a separator
+    /// character.
+    ///
+    /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
+    /// such that (*this == LHS + Separator + RHS) is true and RHS is
+    /// minimal. If \p Separator is not in the string, then the result is a
+    /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+    ///
+    /// \param Separator - The character to split on.
+    /// \return - The split substrings.
+    std::pair<StringRef, StringRef> rsplit(char Separator) const {
+      size_t Idx = rfind(Separator);
+      if (Idx == npos)
+        return std::make_pair(*this, StringRef());
+      return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+    }
+
+    /// Return string with consecutive characters in \p Chars starting from
+    /// the left removed.
+    StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
+      return drop_front(std::min(Length, find_first_not_of(Chars)));
+    }
+
+    /// Return string with consecutive characters in \p Chars starting from
+    /// the right removed.
+    StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
+      return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
+    }
+
+    /// Return string with consecutive characters in \p Chars starting from
+    /// the left and right removed.
+    StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
+      return ltrim(Chars).rtrim(Chars);
+    }
+
+    /// @}
+  };
+
+  /// @name StringRef Comparison Operators
+  /// @{
+
+  inline bool operator==(StringRef LHS, StringRef RHS) {
+    return LHS.equals(RHS);
+  }
+
+  inline bool operator!=(StringRef LHS, StringRef RHS) {
+    return !(LHS == RHS);
+  }
+
+  inline bool operator<(StringRef LHS, StringRef RHS) {
+    return LHS.compare(RHS) == -1;
+  }
+
+  inline bool operator<=(StringRef LHS, StringRef RHS) {
+    return LHS.compare(RHS) != 1;
+  }
+
+  inline bool operator>(StringRef LHS, StringRef RHS) {
+    return LHS.compare(RHS) == 1;
+  }
+
+  inline bool operator>=(StringRef LHS, StringRef RHS) {
+    return LHS.compare(RHS) != -1;
+  }
+
+  inline std::string &operator+=(std::string &buffer, StringRef string) {
+    return buffer.append(string.data(), string.size());
+  }
+
+  /// @}
+
+  /// \brief Compute a hash_code for a StringRef.
+  hash_code hash_value(StringRef S);
+
+  // StringRefs can be treated like a POD type.
+  template <typename T> struct isPodLike;
+  template <> struct isPodLike<StringRef> { static const bool value = true; };
+}
+
+#endif
diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h
new file mode 100644
index 0000000..7bea577
--- /dev/null
+++ b/include/llvm/ADT/StringSet.h
@@ -0,0 +1,45 @@
+//===--- StringSet.h - The LLVM Compiler Driver -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  StringSet - A set-like wrapper for the StringMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGSET_H
+#define LLVM_ADT_STRINGSET_H
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+
+  /// StringSet - A wrapper for StringMap that provides set-like functionality.
+  template <class AllocatorTy = llvm::MallocAllocator>
+  class StringSet : public llvm::StringMap<char, AllocatorTy> {
+    typedef llvm::StringMap<char, AllocatorTy> base;
+  public:
+
+    /// insert - Insert the specified key into the set.  If the key already
+    /// exists in the set, return false and ignore the request, otherwise insert
+    /// it and return true.
+    bool insert(StringRef Key) {
+      // Get or create the map entry for the key; if it doesn't exist the value
+      // type will be default constructed which we use to detect insert.
+      //
+      // We use '+' as the sentinel value in the map.
+      assert(!Key.empty());
+      StringMapEntry<char> &Entry = this->GetOrCreateValue(Key);
+      if (Entry.getValue() == '+')
+        return false;
+      Entry.setValue('+');
+      return true;
+    }
+  };
+}
+
+#endif // LLVM_ADT_STRINGSET_H
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h
new file mode 100644
index 0000000..0393a0c
--- /dev/null
+++ b/include/llvm/ADT/StringSwitch.h
@@ -0,0 +1,126 @@
+//===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
+//
+//                     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 StringSwitch template, which mimics a switch()
+//  statement whose cases are string literals.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_ADT_STRINGSWITCH_H
+#define LLVM_ADT_STRINGSWITCH_H
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+
+/// \brief A switch()-like statement whose cases are string literals.
+///
+/// The StringSwitch class is a simple form of a switch() statement that
+/// determines whether the given string matches one of the given string
+/// literals. The template type parameter \p T is the type of the value that
+/// will be returned from the string-switch expression. For example,
+/// the following code switches on the name of a color in \c argv[i]:
+///
+/// \code
+/// Color color = StringSwitch<Color>(argv[i])
+///   .Case("red", Red)
+///   .Case("orange", Orange)
+///   .Case("yellow", Yellow)
+///   .Case("green", Green)
+///   .Case("blue", Blue)
+///   .Case("indigo", Indigo)
+///   .Cases("violet", "purple", Violet)
+///   .Default(UnknownColor);
+/// \endcode
+template<typename T, typename R = T>
+class StringSwitch {
+  /// \brief The string we are matching.
+  StringRef Str;
+
+  /// \brief The pointer to the result of this switch statement, once known,
+  /// null before that.
+  const T *Result;
+
+public:
+  explicit StringSwitch(StringRef S)
+  : Str(S), Result(nullptr) { }
+
+  template<unsigned N>
+  StringSwitch& Case(const char (&S)[N], const T& Value) {
+    if (!Result && N-1 == Str.size() &&
+        (std::memcmp(S, Str.data(), N-1) == 0)) {
+      Result = &Value;
+    }
+
+    return *this;
+  }
+
+  template<unsigned N>
+  StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
+    if (!Result && Str.size() >= N-1 &&
+        std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
+      Result = &Value;
+    }
+
+    return *this;
+  }
+
+  template<unsigned N>
+  StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
+    if (!Result && Str.size() >= N-1 &&
+        std::memcmp(S, Str.data(), N-1) == 0) {
+      Result = &Value;
+    }
+
+    return *this;
+  }
+
+  template<unsigned N0, unsigned N1>
+  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+                      const T& Value) {
+    return Case(S0, Value).Case(S1, Value);
+  }
+
+  template<unsigned N0, unsigned N1, unsigned N2>
+  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+                      const char (&S2)[N2], const T& Value) {
+    return Case(S0, Value).Case(S1, Value).Case(S2, Value);
+  }
+
+  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
+  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+                      const char (&S2)[N2], const char (&S3)[N3],
+                      const T& Value) {
+    return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
+  }
+
+  template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
+  StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+                      const char (&S2)[N2], const char (&S3)[N3],
+                      const char (&S4)[N4], const T& Value) {
+    return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
+      .Case(S4, Value);
+  }
+
+  R Default(const T& Value) const {
+    if (Result)
+      return *Result;
+
+    return Value;
+  }
+
+  operator R() const {
+    assert(Result && "Fell off the end of a string-switch");
+    return *Result;
+  }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_STRINGSWITCH_H
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
new file mode 100644
index 0000000..5669b2a
--- /dev/null
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -0,0 +1,287 @@
+//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TINYPTRVECTOR_H
+#define LLVM_ADT_TINYPTRVECTOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+  
+/// TinyPtrVector - This class is specialized for cases where there are
+/// normally 0 or 1 element in a vector, but is general enough to go beyond that
+/// when required.
+///
+/// NOTE: This container doesn't allow you to store a null pointer into it.
+///
+template <typename EltTy>
+class TinyPtrVector {
+public:
+  typedef llvm::SmallVector<EltTy, 4> VecTy;
+  typedef typename VecTy::value_type value_type;
+
+  llvm::PointerUnion<EltTy, VecTy*> Val;
+
+  TinyPtrVector() {}
+  ~TinyPtrVector() {
+    if (VecTy *V = Val.template dyn_cast<VecTy*>())
+      delete V;
+  }
+
+  TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
+    if (VecTy *V = Val.template dyn_cast<VecTy*>())
+      Val = new VecTy(*V);
+  }
+  TinyPtrVector &operator=(const TinyPtrVector &RHS) {
+    if (this == &RHS)
+      return *this;
+    if (RHS.empty()) {
+      this->clear();
+      return *this;
+    }
+
+    // Try to squeeze into the single slot. If it won't fit, allocate a copied
+    // vector.
+    if (Val.template is<EltTy>()) {
+      if (RHS.size() == 1)
+        Val = RHS.front();
+      else
+        Val = new VecTy(*RHS.Val.template get<VecTy*>());
+      return *this;
+    }
+
+    // If we have a full vector allocated, try to re-use it.
+    if (RHS.Val.template is<EltTy>()) {
+      Val.template get<VecTy*>()->clear();
+      Val.template get<VecTy*>()->push_back(RHS.front());
+    } else {
+      *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>();
+    }
+    return *this;
+  }
+
+  TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
+    RHS.Val = (EltTy)nullptr;
+  }
+  TinyPtrVector &operator=(TinyPtrVector &&RHS) {
+    if (this == &RHS)
+      return *this;
+    if (RHS.empty()) {
+      this->clear();
+      return *this;
+    }
+
+    // If this vector has been allocated on the heap, re-use it if cheap. If it
+    // would require more copying, just delete it and we'll steal the other
+    // side.
+    if (VecTy *V = Val.template dyn_cast<VecTy*>()) {
+      if (RHS.Val.template is<EltTy>()) {
+        V->clear();
+        V->push_back(RHS.front());
+        return *this;
+      }
+      delete V;
+    }
+
+    Val = RHS.Val;
+    RHS.Val = (EltTy)nullptr;
+    return *this;
+  }
+
+  // implicit conversion operator to ArrayRef.
+  operator ArrayRef<EltTy>() const {
+    if (Val.isNull())
+      return ArrayRef<EltTy>();
+    if (Val.template is<EltTy>())
+      return *Val.getAddrOfPtr1();
+    return *Val.template get<VecTy*>();
+  }
+
+  bool empty() const {
+    // This vector can be empty if it contains no element, or if it
+    // contains a pointer to an empty vector.
+    if (Val.isNull()) return true;
+    if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
+      return Vec->empty();
+    return false;
+  }
+
+  unsigned size() const {
+    if (empty())
+      return 0;
+    if (Val.template is<EltTy>())
+      return 1;
+    return Val.template get<VecTy*>()->size();
+  }
+
+  typedef const EltTy *const_iterator;
+  typedef EltTy *iterator;
+
+  iterator begin() {
+    if (Val.template is<EltTy>())
+      return Val.getAddrOfPtr1();
+
+    return Val.template get<VecTy *>()->begin();
+
+  }
+  iterator end() {
+    if (Val.template is<EltTy>())
+      return begin() + (Val.isNull() ? 0 : 1);
+
+    return Val.template get<VecTy *>()->end();
+  }
+
+  const_iterator begin() const {
+    return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
+  }
+
+  const_iterator end() const {
+    return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
+  }
+
+  EltTy operator[](unsigned i) const {
+    assert(!Val.isNull() && "can't index into an empty vector");
+    if (EltTy V = Val.template dyn_cast<EltTy>()) {
+      assert(i == 0 && "tinyvector index out of range");
+      return V;
+    }
+
+    assert(i < Val.template get<VecTy*>()->size() &&
+           "tinyvector index out of range");
+    return (*Val.template get<VecTy*>())[i];
+  }
+
+  EltTy front() const {
+    assert(!empty() && "vector empty");
+    if (EltTy V = Val.template dyn_cast<EltTy>())
+      return V;
+    return Val.template get<VecTy*>()->front();
+  }
+
+  EltTy back() const {
+    assert(!empty() && "vector empty");
+    if (EltTy V = Val.template dyn_cast<EltTy>())
+      return V;
+    return Val.template get<VecTy*>()->back();
+  }
+
+  void push_back(EltTy NewVal) {
+    assert(NewVal && "Can't add a null value");
+
+    // If we have nothing, add something.
+    if (Val.isNull()) {
+      Val = NewVal;
+      return;
+    }
+
+    // If we have a single value, convert to a vector.
+    if (EltTy V = Val.template dyn_cast<EltTy>()) {
+      Val = new VecTy();
+      Val.template get<VecTy*>()->push_back(V);
+    }
+
+    // Add the new value, we know we have a vector.
+    Val.template get<VecTy*>()->push_back(NewVal);
+  }
+
+  void pop_back() {
+    // If we have a single value, convert to empty.
+    if (Val.template is<EltTy>())
+      Val = (EltTy)nullptr;
+    else if (VecTy *Vec = Val.template get<VecTy*>())
+      Vec->pop_back();
+  }
+
+  void clear() {
+    // If we have a single value, convert to empty.
+    if (Val.template is<EltTy>()) {
+      Val = (EltTy)nullptr;
+    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+      // If we have a vector form, just clear it.
+      Vec->clear();
+    }
+    // Otherwise, we're already empty.
+  }
+
+  iterator erase(iterator I) {
+    assert(I >= begin() && "Iterator to erase is out of bounds.");
+    assert(I < end() && "Erasing at past-the-end iterator.");
+
+    // If we have a single value, convert to empty.
+    if (Val.template is<EltTy>()) {
+      if (I == begin())
+        Val = (EltTy)nullptr;
+    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+      // multiple items in a vector; just do the erase, there is no
+      // benefit to collapsing back to a pointer
+      return Vec->erase(I);
+    }
+    return end();
+  }
+
+  iterator erase(iterator S, iterator E) {
+    assert(S >= begin() && "Range to erase is out of bounds.");
+    assert(S <= E && "Trying to erase invalid range.");
+    assert(E <= end() && "Trying to erase past the end.");
+
+    if (Val.template is<EltTy>()) {
+      if (S == begin() && S != E)
+        Val = (EltTy)nullptr;
+    } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+      return Vec->erase(S, E);
+    }
+    return end();
+  }
+
+  iterator insert(iterator I, const EltTy &Elt) {
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+    if (I == end()) {
+      push_back(Elt);
+      return std::prev(end());
+    }
+    assert(!Val.isNull() && "Null value with non-end insert iterator.");
+    if (EltTy V = Val.template dyn_cast<EltTy>()) {
+      assert(I == begin());
+      Val = Elt;
+      push_back(V);
+      return begin();
+    }
+
+    return Val.template get<VecTy*>()->insert(I, Elt);
+  }
+
+  template<typename ItTy>
+  iterator insert(iterator I, ItTy From, ItTy To) {
+    assert(I >= this->begin() && "Insertion iterator is out of bounds.");
+    assert(I <= this->end() && "Inserting past the end of the vector.");
+    if (From == To)
+      return I;
+
+    // If we have a single value, convert to a vector.
+    ptrdiff_t Offset = I - begin();
+    if (Val.isNull()) {
+      if (std::next(From) == To) {
+        Val = *From;
+        return begin();
+      }
+
+      Val = new VecTy();
+    } else if (EltTy V = Val.template dyn_cast<EltTy>()) {
+      Val = new VecTy();
+      Val.template get<VecTy*>()->push_back(V);
+    }
+    return Val.template get<VecTy*>()->insert(begin() + Offset, From, To);
+  }
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
new file mode 100644
index 0000000..b96f114
--- /dev/null
+++ b/include/llvm/ADT/Triple.h
@@ -0,0 +1,547 @@
+//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TRIPLE_H
+#define LLVM_ADT_TRIPLE_H
+
+#include "llvm/ADT/Twine.h"
+
+// Some system headers or GCC predefined macros conflict with identifiers in
+// this file.  Undefine them here.
+#undef NetBSD
+#undef mips
+#undef sparc
+
+namespace llvm {
+
+/// Triple - Helper class for working with autoconf configuration names. For
+/// historical reasons, we also call these 'triples' (they used to contain
+/// exactly three fields).
+///
+/// Configuration names are strings in the canonical form:
+///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM
+/// or
+///   ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
+///
+/// This class is used for clients which want to support arbitrary
+/// configuration names, but also want to implement certain special
+/// behavior for particular configurations. This class isolates the mapping
+/// from the components of the configuration name to well known IDs.
+///
+/// At its core the Triple class is designed to be a wrapper for a triple
+/// string; the constructor does not change or normalize the triple string.
+/// Clients that need to handle the non-canonical triples that users often
+/// specify should use the normalize method.
+///
+/// See autoconf/config.guess for a glimpse into what configuration names
+/// look like in practice.
+class Triple {
+public:
+  enum ArchType {
+    UnknownArch,
+
+    arm,        // ARM (little endian): arm, armv.*, xscale
+    armeb,      // ARM (big endian): armeb
+    arm64,      // ARM64 (little endian): arm64
+    arm64_be,   // ARM64 (big endian): arm64_be
+    aarch64,    // AArch64 (little endian): aarch64
+    aarch64_be, // AArch64 (big endian): aarch64_be
+    hexagon,    // Hexagon: hexagon
+    mips,       // MIPS: mips, mipsallegrex
+    mipsel,     // MIPSEL: mipsel, mipsallegrexel
+    mips64,     // MIPS64: mips64
+    mips64el,   // MIPS64EL: mips64el
+    msp430,     // MSP430: msp430
+    ppc,        // PPC: powerpc
+    ppc64,      // PPC64: powerpc64, ppu
+    ppc64le,    // PPC64LE: powerpc64le
+    r600,       // R600: AMD GPUs HD2XXX - HD6XXX
+    sparc,      // Sparc: sparc
+    sparcv9,    // Sparcv9: Sparcv9
+    systemz,    // SystemZ: s390x
+    tce,        // TCE (http://tce.cs.tut.fi/): tce
+    thumb,      // Thumb (little endian): thumb, thumbv.*
+    thumbeb,    // Thumb (big endian): thumbeb
+    x86,        // X86: i[3-9]86
+    x86_64,     // X86-64: amd64, x86_64
+    xcore,      // XCore: xcore
+    nvptx,      // NVPTX: 32-bit
+    nvptx64,    // NVPTX: 64-bit
+    le32,       // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
+    amdil,      // amdil: amd IL
+    spir,       // SPIR: standard portable IR for OpenCL 32-bit version
+    spir64,     // SPIR: standard portable IR for OpenCL 64-bit version
+    kalimba     // Kalimba: generic kalimba
+  };
+  enum SubArchType {
+    NoSubArch,
+
+    ARMSubArch_v8,
+    ARMSubArch_v7,
+    ARMSubArch_v7em,
+    ARMSubArch_v7m,
+    ARMSubArch_v7s,
+    ARMSubArch_v6,
+    ARMSubArch_v6m,
+    ARMSubArch_v6t2,
+    ARMSubArch_v5,
+    ARMSubArch_v5te,
+    ARMSubArch_v4t
+  };
+  enum VendorType {
+    UnknownVendor,
+
+    Apple,
+    PC,
+    SCEI,
+    BGP,
+    BGQ,
+    Freescale,
+    IBM,
+    ImaginationTechnologies,
+    MipsTechnologies,
+    NVIDIA,
+    CSR
+  };
+  enum OSType {
+    UnknownOS,
+
+    AuroraUX,
+    Cygwin,
+    Darwin,
+    DragonFly,
+    FreeBSD,
+    IOS,
+    KFreeBSD,
+    Linux,
+    Lv2,        // PS3
+    MacOSX,
+    MinGW32,    // i*86-pc-mingw32, *-w64-mingw32
+    NetBSD,
+    OpenBSD,
+    Solaris,
+    Win32,
+    Haiku,
+    Minix,
+    RTEMS,
+    NaCl,       // Native Client
+    CNK,        // BG/P Compute-Node Kernel
+    Bitrig,
+    AIX,
+    CUDA,       // NVIDIA CUDA
+    NVCL        // NVIDIA OpenCL
+  };
+  enum EnvironmentType {
+    UnknownEnvironment,
+
+    GNU,
+    GNUEABI,
+    GNUEABIHF,
+    GNUX32,
+    CODE16,
+    EABI,
+    EABIHF,
+    Android,
+
+    MSVC,
+    Itanium,
+    Cygnus,
+  };
+  enum ObjectFormatType {
+    UnknownObjectFormat,
+
+    COFF,
+    ELF,
+    MachO,
+  };
+
+private:
+  std::string Data;
+
+  /// The parsed arch type.
+  ArchType Arch;
+
+  /// The parsed subarchitecture type.
+  SubArchType SubArch;
+
+  /// The parsed vendor type.
+  VendorType Vendor;
+
+  /// The parsed OS type.
+  OSType OS;
+
+  /// The parsed Environment type.
+  EnvironmentType Environment;
+
+  /// The object format type.
+  ObjectFormatType ObjectFormat;
+
+public:
+  /// @name Constructors
+  /// @{
+
+  /// \brief Default constructor is the same as an empty string and leaves all
+  /// triple fields unknown.
+  Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
+
+  explicit Triple(const Twine &Str);
+  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
+  Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
+         const Twine &EnvironmentStr);
+
+  /// @}
+  /// @name Normalization
+  /// @{
+
+  /// normalize - Turn an arbitrary machine specification into the canonical
+  /// triple form (or something sensible that the Triple class understands if
+  /// nothing better can reasonably be done).  In particular, it handles the
+  /// common case in which otherwise valid components are in the wrong order.
+  static std::string normalize(StringRef Str);
+
+  /// @}
+  /// @name Typed Component Access
+  /// @{
+
+  /// getArch - Get the parsed architecture type of this triple.
+  ArchType getArch() const { return Arch; }
+
+  /// getSubArch - get the parsed subarchitecture type for this triple.
+  SubArchType getSubArch() const { return SubArch; }
+
+  /// getVendor - Get the parsed vendor type of this triple.
+  VendorType getVendor() const { return Vendor; }
+
+  /// getOS - Get the parsed operating system type of this triple.
+  OSType getOS() const { return OS; }
+
+  /// hasEnvironment - Does this triple have the optional environment
+  /// (fourth) component?
+  bool hasEnvironment() const {
+    return getEnvironmentName() != "";
+  }
+
+  /// getEnvironment - Get the parsed environment type of this triple.
+  EnvironmentType getEnvironment() const { return Environment; }
+
+  /// getFormat - Get the object format for this triple.
+  ObjectFormatType getObjectFormat() const { return ObjectFormat; }
+
+  /// getOSVersion - Parse the version number from the OS name component of the
+  /// triple, if present.
+  ///
+  /// For example, "fooos1.2.3" would return (1, 2, 3).
+  ///
+  /// If an entry is not defined, it will be returned as 0.
+  void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
+
+  /// getOSMajorVersion - Return just the major version number, this is
+  /// specialized because it is a common query.
+  unsigned getOSMajorVersion() const {
+    unsigned Maj, Min, Micro;
+    getOSVersion(Maj, Min, Micro);
+    return Maj;
+  }
+
+  /// getMacOSXVersion - Parse the version number as with getOSVersion and then
+  /// translate generic "darwin" versions to the corresponding OS X versions.
+  /// This may also be called with IOS triples but the OS X version number is
+  /// just set to a constant 10.4.0 in that case.  Returns true if successful.
+  bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
+                        unsigned &Micro) const;
+
+  /// getiOSVersion - Parse the version number as with getOSVersion.  This should
+  /// only be called with IOS triples.
+  void getiOSVersion(unsigned &Major, unsigned &Minor,
+                     unsigned &Micro) const;
+
+  /// @}
+  /// @name Direct Component Access
+  /// @{
+
+  const std::string &str() const { return Data; }
+
+  const std::string &getTriple() const { return Data; }
+
+  /// getArchName - Get the architecture (first) component of the
+  /// triple.
+  StringRef getArchName() const;
+
+  /// getVendorName - Get the vendor (second) component of the triple.
+  StringRef getVendorName() const;
+
+  /// getOSName - Get the operating system (third) component of the
+  /// triple.
+  StringRef getOSName() const;
+
+  /// getEnvironmentName - Get the optional environment (fourth)
+  /// component of the triple, or "" if empty.
+  StringRef getEnvironmentName() const;
+
+  /// getOSAndEnvironmentName - Get the operating system and optional
+  /// environment components as a single string (separated by a '-'
+  /// if the environment component is present).
+  StringRef getOSAndEnvironmentName() const;
+
+  /// @}
+  /// @name Convenience Predicates
+  /// @{
+
+  /// \brief Test whether the architecture is 64-bit
+  ///
+  /// Note that this tests for 64-bit pointer width, and nothing else. Note
+  /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
+  /// 16-bit. The inner details of pointer width for particular architectures
+  /// is not summed up in the triple, and so only a coarse grained predicate
+  /// system is provided.
+  bool isArch64Bit() const;
+
+  /// \brief Test whether the architecture is 32-bit
+  ///
+  /// Note that this tests for 32-bit pointer width, and nothing else.
+  bool isArch32Bit() const;
+
+  /// \brief Test whether the architecture is 16-bit
+  ///
+  /// Note that this tests for 16-bit pointer width, and nothing else.
+  bool isArch16Bit() const;
+
+  /// isOSVersionLT - Helper function for doing comparisons against version
+  /// numbers included in the target triple.
+  bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
+                     unsigned Micro = 0) const {
+    unsigned LHS[3];
+    getOSVersion(LHS[0], LHS[1], LHS[2]);
+
+    if (LHS[0] != Major)
+      return LHS[0] < Major;
+    if (LHS[1] != Minor)
+      return LHS[1] < Minor;
+    if (LHS[2] != Micro)
+      return LHS[1] < Micro;
+
+    return false;
+  }
+
+  /// isMacOSXVersionLT - Comparison function for checking OS X version
+  /// compatibility, which handles supporting skewed version numbering schemes
+  /// used by the "darwin" triples.
+  unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
+                             unsigned Micro = 0) const {
+    assert(isMacOSX() && "Not an OS X triple!");
+
+    // If this is OS X, expect a sane version number.
+    if (getOS() == Triple::MacOSX)
+      return isOSVersionLT(Major, Minor, Micro);
+
+    // Otherwise, compare to the "Darwin" number.
+    assert(Major == 10 && "Unexpected major version");
+    return isOSVersionLT(Minor + 4, Micro, 0);
+  }
+
+  /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
+  /// "darwin" and "osx" as OS X triples.
+  bool isMacOSX() const {
+    return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
+  }
+
+  /// Is this an iOS triple.
+  bool isiOS() const {
+    return getOS() == Triple::IOS;
+  }
+
+  /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
+  bool isOSDarwin() const {
+    return isMacOSX() || isiOS();
+  }
+
+  bool isOSFreeBSD() const {
+    return getOS() == Triple::FreeBSD;
+  }
+
+  bool isWindowsMSVCEnvironment() const {
+    return getOS() == Triple::Win32 &&
+           (getEnvironment() == Triple::UnknownEnvironment ||
+            getEnvironment() == Triple::MSVC);
+  }
+
+  bool isKnownWindowsMSVCEnvironment() const {
+    return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
+  }
+
+  bool isWindowsItaniumEnvironment() const {
+    return getOS() == Triple::Win32 && getEnvironment() == Triple::Itanium;
+  }
+
+  bool isWindowsCygwinEnvironment() const {
+    return getOS() == Triple::Cygwin ||
+           (getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus);
+  }
+
+  bool isWindowsGNUEnvironment() const {
+    return getOS() == Triple::MinGW32 ||
+           (getOS() == Triple::Win32 && getEnvironment() == Triple::GNU);
+  }
+
+  /// \brief Tests for either Cygwin or MinGW OS
+  bool isOSCygMing() const {
+    return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
+  }
+
+  /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
+  bool isOSMSVCRT() const {
+    return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment();
+  }
+
+  /// \brief Tests whether the OS is Windows.
+  bool isOSWindows() const {
+    return getOS() == Triple::Win32 || isOSCygMing();
+  }
+
+  /// \brief Tests whether the OS is NaCl (Native Client)
+  bool isOSNaCl() const {
+    return getOS() == Triple::NaCl;
+  }
+
+  /// \brief Tests whether the OS is Linux.
+  bool isOSLinux() const {
+    return getOS() == Triple::Linux;
+  }
+
+  /// \brief Tests whether the OS uses the ELF binary format.
+  bool isOSBinFormatELF() const {
+    return getObjectFormat() == Triple::ELF;
+  }
+
+  /// \brief Tests whether the OS uses the COFF binary format.
+  bool isOSBinFormatCOFF() const {
+    return getObjectFormat() == Triple::COFF;
+  }
+
+  /// \brief Tests whether the environment is MachO.
+  bool isOSBinFormatMachO() const {
+    return getObjectFormat() == Triple::MachO;
+  }
+
+  /// @}
+  /// @name Mutators
+  /// @{
+
+  /// setArch - Set the architecture (first) component of the triple
+  /// to a known type.
+  void setArch(ArchType Kind);
+
+  /// setVendor - Set the vendor (second) component of the triple to a
+  /// known type.
+  void setVendor(VendorType Kind);
+
+  /// setOS - Set the operating system (third) component of the triple
+  /// to a known type.
+  void setOS(OSType Kind);
+
+  /// setEnvironment - Set the environment (fourth) component of the triple
+  /// to a known type.
+  void setEnvironment(EnvironmentType Kind);
+
+  /// setObjectFormat - Set the object file format
+  void setObjectFormat(ObjectFormatType Kind);
+
+  /// setTriple - Set all components to the new triple \p Str.
+  void setTriple(const Twine &Str);
+
+  /// setArchName - Set the architecture (first) component of the
+  /// triple by name.
+  void setArchName(StringRef Str);
+
+  /// setVendorName - Set the vendor (second) component of the triple
+  /// by name.
+  void setVendorName(StringRef Str);
+
+  /// setOSName - Set the operating system (third) component of the
+  /// triple by name.
+  void setOSName(StringRef Str);
+
+  /// setEnvironmentName - Set the optional environment (fourth)
+  /// component of the triple by name.
+  void setEnvironmentName(StringRef Str);
+
+  /// setOSAndEnvironmentName - Set the operating system and optional
+  /// environment components with a single string.
+  void setOSAndEnvironmentName(StringRef Str);
+
+  /// getArchNameForAssembler - Get an architecture name that is understood by
+  /// the target assembler.
+  const char *getArchNameForAssembler();
+
+  /// @}
+  /// @name Helpers to build variants of a particular triple.
+  /// @{
+
+  /// \brief Form a triple with a 32-bit variant of the current architecture.
+  ///
+  /// This can be used to move across "families" of architectures where useful.
+  ///
+  /// \returns A new triple with a 32-bit architecture or an unknown
+  ///          architecture if no such variant can be found.
+  llvm::Triple get32BitArchVariant() const;
+
+  /// \brief Form a triple with a 64-bit variant of the current architecture.
+  ///
+  /// This can be used to move across "families" of architectures where useful.
+  ///
+  /// \returns A new triple with a 64-bit architecture or an unknown
+  ///          architecture if no such variant can be found.
+  llvm::Triple get64BitArchVariant() const;
+
+  /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+  ///
+  /// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
+  /// string then the triple's arch name is used.
+  const char* getARMCPUForArch(StringRef Arch = StringRef()) const;
+
+  /// @}
+  /// @name Static helpers for IDs.
+  /// @{
+
+  /// getArchTypeName - Get the canonical name for the \p Kind architecture.
+  static const char *getArchTypeName(ArchType Kind);
+
+  /// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
+  /// architecture. This is the prefix used by the architecture specific
+  /// builtins, and is suitable for passing to \see
+  /// Intrinsic::getIntrinsicForGCCBuiltin().
+  ///
+  /// \return - The architecture prefix, or 0 if none is defined.
+  static const char *getArchTypePrefix(ArchType Kind);
+
+  /// getVendorTypeName - Get the canonical name for the \p Kind vendor.
+  static const char *getVendorTypeName(VendorType Kind);
+
+  /// getOSTypeName - Get the canonical name for the \p Kind operating system.
+  static const char *getOSTypeName(OSType Kind);
+
+  /// getEnvironmentTypeName - Get the canonical name for the \p Kind
+  /// environment.
+  static const char *getEnvironmentTypeName(EnvironmentType Kind);
+
+  /// @}
+  /// @name Static helpers for converting alternate architecture names.
+  /// @{
+
+  /// getArchTypeForLLVMName - The canonical type for the given LLVM
+  /// architecture name (e.g., "x86").
+  static ArchType getArchTypeForLLVMName(StringRef Str);
+
+  /// @}
+};
+
+} // End llvm namespace
+
+
+#endif
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
new file mode 100644
index 0000000..4be3ee6
--- /dev/null
+++ b/include/llvm/ADT/Twine.h
@@ -0,0 +1,528 @@
+//===-- Twine.h - Fast Temporary String Concatenation -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TWINE_H
+#define LLVM_ADT_TWINE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+  template <typename T>
+  class SmallVectorImpl;
+  class StringRef;
+  class raw_ostream;
+
+  /// Twine - A lightweight data structure for efficiently representing the
+  /// concatenation of temporary values as strings.
+  ///
+  /// A Twine is a kind of rope, it represents a concatenated string using a
+  /// binary-tree, where the string is the preorder of the nodes. Since the
+  /// Twine can be efficiently rendered into a buffer when its result is used,
+  /// it avoids the cost of generating temporary values for intermediate string
+  /// results -- particularly in cases when the Twine result is never
+  /// required. By explicitly tracking the type of leaf nodes, we can also avoid
+  /// the creation of temporary strings for conversions operations (such as
+  /// appending an integer to a string).
+  ///
+  /// A Twine is not intended for use directly and should not be stored, its
+  /// implementation relies on the ability to store pointers to temporary stack
+  /// objects which may be deallocated at the end of a statement. Twines should
+  /// only be used accepted as const references in arguments, when an API wishes
+  /// to accept possibly-concatenated strings.
+  ///
+  /// Twines support a special 'null' value, which always concatenates to form
+  /// itself, and renders as an empty string. This can be returned from APIs to
+  /// effectively nullify any concatenations performed on the result.
+  ///
+  /// \b Implementation
+  ///
+  /// Given the nature of a Twine, it is not possible for the Twine's
+  /// concatenation method to construct interior nodes; the result must be
+  /// represented inside the returned value. For this reason a Twine object
+  /// actually holds two values, the left- and right-hand sides of a
+  /// concatenation. We also have nullary Twine objects, which are effectively
+  /// sentinel values that represent empty strings.
+  ///
+  /// Thus, a Twine can effectively have zero, one, or two children. The \see
+  /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
+  /// testing the number of children.
+  ///
+  /// We maintain a number of invariants on Twine objects (FIXME: Why):
+  ///  - Nullary twines are always represented with their Kind on the left-hand
+  ///    side, and the Empty kind on the right-hand side.
+  ///  - Unary twines are always represented with the value on the left-hand
+  ///    side, and the Empty kind on the right-hand side.
+  ///  - If a Twine has another Twine as a child, that child should always be
+  ///    binary (otherwise it could have been folded into the parent).
+  ///
+  /// These invariants are check by \see isValid().
+  ///
+  /// \b Efficiency Considerations
+  ///
+  /// The Twine is designed to yield efficient and small code for common
+  /// situations. For this reason, the concat() method is inlined so that
+  /// concatenations of leaf nodes can be optimized into stores directly into a
+  /// single stack allocated object.
+  ///
+  /// In practice, not all compilers can be trusted to optimize concat() fully,
+  /// so we provide two additional methods (and accompanying operator+
+  /// overloads) to guarantee that particularly important cases (cstring plus
+  /// StringRef) codegen as desired.
+  class Twine {
+    /// NodeKind - Represent the type of an argument.
+    enum NodeKind {
+      /// An empty string; the result of concatenating anything with it is also
+      /// empty.
+      NullKind,
+
+      /// The empty string.
+      EmptyKind,
+
+      /// A pointer to a Twine instance.
+      TwineKind,
+
+      /// A pointer to a C string instance.
+      CStringKind,
+
+      /// A pointer to an std::string instance.
+      StdStringKind,
+
+      /// A pointer to a StringRef instance.
+      StringRefKind,
+
+      /// A char value reinterpreted as a pointer, to render as a character.
+      CharKind,
+
+      /// An unsigned int value reinterpreted as a pointer, to render as an
+      /// unsigned decimal integer.
+      DecUIKind,
+
+      /// An int value reinterpreted as a pointer, to render as a signed
+      /// decimal integer.
+      DecIKind,
+
+      /// A pointer to an unsigned long value, to render as an unsigned decimal
+      /// integer.
+      DecULKind,
+
+      /// A pointer to a long value, to render as a signed decimal integer.
+      DecLKind,
+
+      /// A pointer to an unsigned long long value, to render as an unsigned
+      /// decimal integer.
+      DecULLKind,
+
+      /// A pointer to a long long value, to render as a signed decimal integer.
+      DecLLKind,
+
+      /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
+      /// integer.
+      UHexKind
+    };
+
+    union Child
+    {
+      const Twine *twine;
+      const char *cString;
+      const std::string *stdString;
+      const StringRef *stringRef;
+      char character;
+      unsigned int decUI;
+      int decI;
+      const unsigned long *decUL;
+      const long *decL;
+      const unsigned long long *decULL;
+      const long long *decLL;
+      const uint64_t *uHex;
+    };
+
+  private:
+    /// LHS - The prefix in the concatenation, which may be uninitialized for
+    /// Null or Empty kinds.
+    Child LHS;
+    /// RHS - The suffix in the concatenation, which may be uninitialized for
+    /// Null or Empty kinds.
+    Child RHS;
+    // enums stored as unsigned chars to save on space while some compilers
+    // don't support specifying the backing type for an enum
+    /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
+    unsigned char LHSKind;
+    /// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
+    unsigned char RHSKind;
+
+  private:
+    /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
+    explicit Twine(NodeKind Kind)
+      : LHSKind(Kind), RHSKind(EmptyKind) {
+      assert(isNullary() && "Invalid kind!");
+    }
+
+    /// Construct a binary twine.
+    explicit Twine(const Twine &_LHS, const Twine &_RHS)
+      : LHSKind(TwineKind), RHSKind(TwineKind) {
+      LHS.twine = &_LHS;
+      RHS.twine = &_RHS;
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct a twine from explicit values.
+    explicit Twine(Child _LHS, NodeKind _LHSKind,
+                   Child _RHS, NodeKind _RHSKind)
+      : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Since the intended use of twines is as temporary objects, assignments
+    /// when concatenating might cause undefined behavior or stack corruptions
+    Twine &operator=(const Twine &Other) LLVM_DELETED_FUNCTION;
+
+    /// isNull - Check for the null twine.
+    bool isNull() const {
+      return getLHSKind() == NullKind;
+    }
+
+    /// isEmpty - Check for the empty twine.
+    bool isEmpty() const {
+      return getLHSKind() == EmptyKind;
+    }
+
+    /// isNullary - Check if this is a nullary twine (null or empty).
+    bool isNullary() const {
+      return isNull() || isEmpty();
+    }
+
+    /// isUnary - Check if this is a unary twine.
+    bool isUnary() const {
+      return getRHSKind() == EmptyKind && !isNullary();
+    }
+
+    /// isBinary - Check if this is a binary twine.
+    bool isBinary() const {
+      return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
+    }
+
+    /// isValid - Check if this is a valid twine (satisfying the invariants on
+    /// order and number of arguments).
+    bool isValid() const {
+      // Nullary twines always have Empty on the RHS.
+      if (isNullary() && getRHSKind() != EmptyKind)
+        return false;
+
+      // Null should never appear on the RHS.
+      if (getRHSKind() == NullKind)
+        return false;
+
+      // The RHS cannot be non-empty if the LHS is empty.
+      if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
+        return false;
+
+      // A twine child should always be binary.
+      if (getLHSKind() == TwineKind &&
+          !LHS.twine->isBinary())
+        return false;
+      if (getRHSKind() == TwineKind &&
+          !RHS.twine->isBinary())
+        return false;
+
+      return true;
+    }
+
+    /// getLHSKind - Get the NodeKind of the left-hand side.
+    NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
+
+    /// getRHSKind - Get the NodeKind of the right-hand side.
+    NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
+
+    /// printOneChild - Print one child from a twine.
+    void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
+
+    /// printOneChildRepr - Print the representation of one child from a twine.
+    void printOneChildRepr(raw_ostream &OS, Child Ptr,
+                           NodeKind Kind) const;
+
+  public:
+    /// @name Constructors
+    /// @{
+
+    /// Construct from an empty string.
+    /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct from a C string.
+    ///
+    /// We take care here to optimize "" into the empty twine -- this will be
+    /// optimized out for string constants. This allows Twine arguments have
+    /// default "" values, without introducing unnecessary string constants.
+    /*implicit*/ Twine(const char *Str)
+      : RHSKind(EmptyKind) {
+      if (Str[0] != '\0') {
+        LHS.cString = Str;
+        LHSKind = CStringKind;
+      } else
+        LHSKind = EmptyKind;
+
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct from an std::string.
+    /*implicit*/ Twine(const std::string &Str)
+      : LHSKind(StdStringKind), RHSKind(EmptyKind) {
+      LHS.stdString = &Str;
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct from a StringRef.
+    /*implicit*/ Twine(const StringRef &Str)
+      : LHSKind(StringRefKind), RHSKind(EmptyKind) {
+      LHS.stringRef = &Str;
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct from a char.
+    explicit Twine(char Val)
+      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      LHS.character = Val;
+    }
+
+    /// Construct from a signed char.
+    explicit Twine(signed char Val)
+      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      LHS.character = static_cast<char>(Val);
+    }
+
+    /// Construct from an unsigned char.
+    explicit Twine(unsigned char Val)
+      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      LHS.character = static_cast<char>(Val);
+    }
+
+    /// Construct a twine to print \p Val as an unsigned decimal integer.
+    explicit Twine(unsigned Val)
+      : LHSKind(DecUIKind), RHSKind(EmptyKind) {
+      LHS.decUI = Val;
+    }
+
+    /// Construct a twine to print \p Val as a signed decimal integer.
+    explicit Twine(int Val)
+      : LHSKind(DecIKind), RHSKind(EmptyKind) {
+      LHS.decI = Val;
+    }
+
+    /// Construct a twine to print \p Val as an unsigned decimal integer.
+    explicit Twine(const unsigned long &Val)
+      : LHSKind(DecULKind), RHSKind(EmptyKind) {
+      LHS.decUL = &Val;
+    }
+
+    /// Construct a twine to print \p Val as a signed decimal integer.
+    explicit Twine(const long &Val)
+      : LHSKind(DecLKind), RHSKind(EmptyKind) {
+      LHS.decL = &Val;
+    }
+
+    /// Construct a twine to print \p Val as an unsigned decimal integer.
+    explicit Twine(const unsigned long long &Val)
+      : LHSKind(DecULLKind), RHSKind(EmptyKind) {
+      LHS.decULL = &Val;
+    }
+
+    /// Construct a twine to print \p Val as a signed decimal integer.
+    explicit Twine(const long long &Val)
+      : LHSKind(DecLLKind), RHSKind(EmptyKind) {
+      LHS.decLL = &Val;
+    }
+
+    // FIXME: Unfortunately, to make sure this is as efficient as possible we
+    // need extra binary constructors from particular types. We can't rely on
+    // the compiler to be smart enough to fold operator+()/concat() down to the
+    // right thing. Yet.
+
+    /// Construct as the concatenation of a C string and a StringRef.
+    /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
+      : LHSKind(CStringKind), RHSKind(StringRefKind) {
+      LHS.cString = _LHS;
+      RHS.stringRef = &_RHS;
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Construct as the concatenation of a StringRef and a C string.
+    /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
+      : LHSKind(StringRefKind), RHSKind(CStringKind) {
+      LHS.stringRef = &_LHS;
+      RHS.cString = _RHS;
+      assert(isValid() && "Invalid twine!");
+    }
+
+    /// Create a 'null' string, which is an empty string that always
+    /// concatenates to form another empty string.
+    static Twine createNull() {
+      return Twine(NullKind);
+    }
+
+    /// @}
+    /// @name Numeric Conversions
+    /// @{
+
+    // Construct a twine to print \p Val as an unsigned hexadecimal integer.
+    static Twine utohexstr(const uint64_t &Val) {
+      Child LHS, RHS;
+      LHS.uHex = &Val;
+      RHS.twine = nullptr;
+      return Twine(LHS, UHexKind, RHS, EmptyKind);
+    }
+
+    /// @}
+    /// @name Predicate Operations
+    /// @{
+
+    /// isTriviallyEmpty - Check if this twine is trivially empty; a false
+    /// return value does not necessarily mean the twine is empty.
+    bool isTriviallyEmpty() const {
+      return isNullary();
+    }
+
+    /// isSingleStringRef - Return true if this twine can be dynamically
+    /// accessed as a single StringRef value with getSingleStringRef().
+    bool isSingleStringRef() const {
+      if (getRHSKind() != EmptyKind) return false;
+
+      switch (getLHSKind()) {
+      case EmptyKind:
+      case CStringKind:
+      case StdStringKind:
+      case StringRefKind:
+        return true;
+      default:
+        return false;
+      }
+    }
+
+    /// @}
+    /// @name String Operations
+    /// @{
+
+    Twine concat(const Twine &Suffix) const;
+
+    /// @}
+    /// @name Output & Conversion.
+    /// @{
+
+    /// str - Return the twine contents as a std::string.
+    std::string str() const;
+
+    /// toVector - Write the concatenated string into the given SmallString or
+    /// SmallVector.
+    void toVector(SmallVectorImpl<char> &Out) const;
+
+    /// getSingleStringRef - This returns the twine as a single StringRef.  This
+    /// method is only valid if isSingleStringRef() is true.
+    StringRef getSingleStringRef() const {
+      assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
+      switch (getLHSKind()) {
+      default: llvm_unreachable("Out of sync with isSingleStringRef");
+      case EmptyKind:      return StringRef();
+      case CStringKind:    return StringRef(LHS.cString);
+      case StdStringKind:  return StringRef(*LHS.stdString);
+      case StringRefKind:  return *LHS.stringRef;
+      }
+    }
+
+    /// toStringRef - This returns the twine as a single StringRef if it can be
+    /// represented as such. Otherwise the twine is written into the given
+    /// SmallVector and a StringRef to the SmallVector's data is returned.
+    StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+
+    /// toNullTerminatedStringRef - This returns the twine as a single null
+    /// terminated StringRef if it can be represented as such. Otherwise the
+    /// twine is written into the given SmallVector and a StringRef to the
+    /// SmallVector's data is returned.
+    ///
+    /// The returned StringRef's size does not include the null terminator.
+    StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+
+    /// Write the concatenated string represented by this twine to the
+    /// stream \p OS.
+    void print(raw_ostream &OS) const;
+
+    /// Dump the concatenated string represented by this twine to stderr.
+    void dump() const;
+
+    /// Write the representation of this twine to the stream \p OS.
+    void printRepr(raw_ostream &OS) const;
+
+    /// Dump the representation of this twine to stderr.
+    void dumpRepr() const;
+
+    /// @}
+  };
+
+  /// @name Twine Inline Implementations
+  /// @{
+
+  inline Twine Twine::concat(const Twine &Suffix) const {
+    // Concatenation with null is null.
+    if (isNull() || Suffix.isNull())
+      return Twine(NullKind);
+
+    // Concatenation with empty yields the other side.
+    if (isEmpty())
+      return Suffix;
+    if (Suffix.isEmpty())
+      return *this;
+
+    // Otherwise we need to create a new node, taking care to fold in unary
+    // twines.
+    Child NewLHS, NewRHS;
+    NewLHS.twine = this;
+    NewRHS.twine = &Suffix;
+    NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
+    if (isUnary()) {
+      NewLHS = LHS;
+      NewLHSKind = getLHSKind();
+    }
+    if (Suffix.isUnary()) {
+      NewRHS = Suffix.LHS;
+      NewRHSKind = Suffix.getLHSKind();
+    }
+
+    return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
+  }
+
+  inline Twine operator+(const Twine &LHS, const Twine &RHS) {
+    return LHS.concat(RHS);
+  }
+
+  /// Additional overload to guarantee simplified codegen; this is equivalent to
+  /// concat().
+
+  inline Twine operator+(const char *LHS, const StringRef &RHS) {
+    return Twine(LHS, RHS);
+  }
+
+  /// Additional overload to guarantee simplified codegen; this is equivalent to
+  /// concat().
+
+  inline Twine operator+(const StringRef &LHS, const char *RHS) {
+    return Twine(LHS, RHS);
+  }
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
+    RHS.print(OS);
+    return OS;
+  }
+
+  /// @}
+}
+
+#endif
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
new file mode 100644
index 0000000..a9cb2f5
--- /dev/null
+++ b/include/llvm/ADT/UniqueVector.h
@@ -0,0 +1,106 @@
+//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_UNIQUEVECTOR_H
+#define LLVM_ADT_UNIQUEVECTOR_H
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// UniqueVector - This class produces a sequential ID number (base 1) for each
+/// unique entry that is added.  T is the type of entries in the vector. This
+/// class should have an implementation of operator== and of operator<.
+/// Entries can be fetched using operator[] with the entry ID.
+template<class T> class UniqueVector {
+public:
+  typedef typename std::vector<T> VectorType;
+  typedef typename VectorType::iterator iterator;
+  typedef typename VectorType::const_iterator const_iterator;
+
+private:
+  // Map - Used to handle the correspondence of entry to ID.
+  std::map<T, unsigned> Map;
+
+  // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
+  //
+  VectorType Vector;
+
+public:
+  /// insert - Append entry to the vector if it doesn't already exist.  Returns
+  /// the entry's index + 1 to be used as a unique ID.
+  unsigned insert(const T &Entry) {
+    // Check if the entry is already in the map.
+    unsigned &Val = Map[Entry];
+
+    // See if entry exists, if so return prior ID.
+    if (Val) return Val;
+
+    // Compute ID for entry.
+    Val = static_cast<unsigned>(Vector.size()) + 1;
+
+    // Insert in vector.
+    Vector.push_back(Entry);
+    return Val;
+  }
+
+  /// idFor - return the ID for an existing entry.  Returns 0 if the entry is
+  /// not found.
+  unsigned idFor(const T &Entry) const {
+    // Search for entry in the map.
+    typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
+
+    // See if entry exists, if so return ID.
+    if (MI != Map.end()) return MI->second;
+
+    // No luck.
+    return 0;
+  }
+
+  /// operator[] - Returns a reference to the entry with the specified ID.
+  ///
+  const T &operator[](unsigned ID) const {
+    assert(ID-1 < size() && "ID is 0 or out of range!");
+    return Vector[ID - 1];
+  }
+
+  /// \brief Return an iterator to the start of the vector.
+  iterator begin() { return Vector.begin(); }
+
+  /// \brief Return an iterator to the start of the vector.
+  const_iterator begin() const { return Vector.begin(); }
+
+  /// \brief Return an iterator to the end of the vector.
+  iterator end() { return Vector.end(); }
+
+  /// \brief Return an iterator to the end of the vector.
+  const_iterator end() const { return Vector.end(); }
+
+  /// size - Returns the number of entries in the vector.
+  ///
+  size_t size() const { return Vector.size(); }
+
+  /// empty - Returns true if the vector is empty.
+  ///
+  bool empty() const { return Vector.empty(); }
+
+  /// reset - Clears all the entries.
+  ///
+  void reset() {
+    Map.clear();
+    Vector.resize(0, 0);
+  }
+};
+
+} // End of namespace llvm
+
+#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h
new file mode 100644
index 0000000..0497aa7
--- /dev/null
+++ b/include/llvm/ADT/VariadicFunction.h
@@ -0,0 +1,331 @@
+//===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements compile-time type-safe variadic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VARIADICFUNCTION_H
+#define LLVM_ADT_VARIADICFUNCTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+
+// Define macros to aid in expanding a comma separated series with the index of
+// the series pasted onto the last token.
+#define LLVM_COMMA_JOIN1(x) x ## 0
+#define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
+#define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
+#define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
+#define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
+#define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
+#define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
+#define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
+#define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
+#define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
+#define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
+#define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
+#define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
+#define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
+#define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
+#define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
+#define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
+#define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
+#define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
+#define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
+#define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
+#define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
+#define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
+#define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
+#define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
+#define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
+#define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
+#define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
+#define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
+#define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
+#define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
+#define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
+
+/// \brief Class which can simulate a type-safe variadic function.
+///
+/// The VariadicFunction class template makes it easy to define
+/// type-safe variadic functions where all arguments have the same
+/// type.
+///
+/// Suppose we need a variadic function like this:
+///
+///   ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
+///
+/// Instead of many overloads of Foo(), we only need to define a helper
+/// function that takes an array of arguments:
+///
+///   ResultT FooImpl(ArrayRef<const ArgT *> Args) {
+///     // 'Args[i]' is a pointer to the i-th argument passed to Foo().
+///     ...
+///   }
+///
+/// and then define Foo() like this:
+///
+///   const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
+///
+/// VariadicFunction takes care of defining the overloads of Foo().
+///
+/// Actually, Foo is a function object (i.e. functor) instead of a plain
+/// function.  This object is stateless and its constructor/destructor
+/// does nothing, so it's safe to create global objects and call Foo(...) at
+/// any time.
+///
+/// Sometimes we need a variadic function to have some fixed leading
+/// arguments whose types may be different from that of the optional
+/// arguments.  For example:
+///
+///   bool FullMatch(const StringRef &S, const RE &Regex,
+///                  const ArgT &A_0, ..., const ArgT &A_N);
+///
+/// VariadicFunctionN is for such cases, where N is the number of fixed
+/// arguments.  It is like VariadicFunction, except that it takes N more
+/// template arguments for the types of the fixed arguments:
+///
+///   bool FullMatchImpl(const StringRef &S, const RE &Regex,
+///                      ArrayRef<const ArgT *> Args) { ... }
+///   const VariadicFunction2<bool, const StringRef&,
+///                           const RE&, ArgT, FullMatchImpl>
+///       FullMatch;
+///
+/// Currently VariadicFunction and friends support up-to 3
+/// fixed leading arguments and up-to 32 optional arguments.
+template <typename ResultT, typename ArgT,
+          ResultT (*Func)(ArrayRef<const ArgT *>)>
+struct VariadicFunction {
+  ResultT operator()() const {
+    return Func(ArrayRef<const ArgT *>());
+  }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+  ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+    const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+    return Func(makeArrayRef(Args)); \
+  }
+  LLVM_DEFINE_OVERLOAD(1)
+  LLVM_DEFINE_OVERLOAD(2)
+  LLVM_DEFINE_OVERLOAD(3)
+  LLVM_DEFINE_OVERLOAD(4)
+  LLVM_DEFINE_OVERLOAD(5)
+  LLVM_DEFINE_OVERLOAD(6)
+  LLVM_DEFINE_OVERLOAD(7)
+  LLVM_DEFINE_OVERLOAD(8)
+  LLVM_DEFINE_OVERLOAD(9)
+  LLVM_DEFINE_OVERLOAD(10)
+  LLVM_DEFINE_OVERLOAD(11)
+  LLVM_DEFINE_OVERLOAD(12)
+  LLVM_DEFINE_OVERLOAD(13)
+  LLVM_DEFINE_OVERLOAD(14)
+  LLVM_DEFINE_OVERLOAD(15)
+  LLVM_DEFINE_OVERLOAD(16)
+  LLVM_DEFINE_OVERLOAD(17)
+  LLVM_DEFINE_OVERLOAD(18)
+  LLVM_DEFINE_OVERLOAD(19)
+  LLVM_DEFINE_OVERLOAD(20)
+  LLVM_DEFINE_OVERLOAD(21)
+  LLVM_DEFINE_OVERLOAD(22)
+  LLVM_DEFINE_OVERLOAD(23)
+  LLVM_DEFINE_OVERLOAD(24)
+  LLVM_DEFINE_OVERLOAD(25)
+  LLVM_DEFINE_OVERLOAD(26)
+  LLVM_DEFINE_OVERLOAD(27)
+  LLVM_DEFINE_OVERLOAD(28)
+  LLVM_DEFINE_OVERLOAD(29)
+  LLVM_DEFINE_OVERLOAD(30)
+  LLVM_DEFINE_OVERLOAD(31)
+  LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename ArgT,
+          ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
+struct VariadicFunction1 {
+  ResultT operator()(Param0T P0) const {
+    return Func(P0, ArrayRef<const ArgT *>());
+  }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+  ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+    const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+    return Func(P0, makeArrayRef(Args)); \
+  }
+  LLVM_DEFINE_OVERLOAD(1)
+  LLVM_DEFINE_OVERLOAD(2)
+  LLVM_DEFINE_OVERLOAD(3)
+  LLVM_DEFINE_OVERLOAD(4)
+  LLVM_DEFINE_OVERLOAD(5)
+  LLVM_DEFINE_OVERLOAD(6)
+  LLVM_DEFINE_OVERLOAD(7)
+  LLVM_DEFINE_OVERLOAD(8)
+  LLVM_DEFINE_OVERLOAD(9)
+  LLVM_DEFINE_OVERLOAD(10)
+  LLVM_DEFINE_OVERLOAD(11)
+  LLVM_DEFINE_OVERLOAD(12)
+  LLVM_DEFINE_OVERLOAD(13)
+  LLVM_DEFINE_OVERLOAD(14)
+  LLVM_DEFINE_OVERLOAD(15)
+  LLVM_DEFINE_OVERLOAD(16)
+  LLVM_DEFINE_OVERLOAD(17)
+  LLVM_DEFINE_OVERLOAD(18)
+  LLVM_DEFINE_OVERLOAD(19)
+  LLVM_DEFINE_OVERLOAD(20)
+  LLVM_DEFINE_OVERLOAD(21)
+  LLVM_DEFINE_OVERLOAD(22)
+  LLVM_DEFINE_OVERLOAD(23)
+  LLVM_DEFINE_OVERLOAD(24)
+  LLVM_DEFINE_OVERLOAD(25)
+  LLVM_DEFINE_OVERLOAD(26)
+  LLVM_DEFINE_OVERLOAD(27)
+  LLVM_DEFINE_OVERLOAD(28)
+  LLVM_DEFINE_OVERLOAD(29)
+  LLVM_DEFINE_OVERLOAD(30)
+  LLVM_DEFINE_OVERLOAD(31)
+  LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
+          ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
+struct VariadicFunction2 {
+  ResultT operator()(Param0T P0, Param1T P1) const {
+    return Func(P0, P1, ArrayRef<const ArgT *>());
+  }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+  ResultT operator()(Param0T P0, Param1T P1, \
+                     LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+    const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+    return Func(P0, P1, makeArrayRef(Args)); \
+  }
+  LLVM_DEFINE_OVERLOAD(1)
+  LLVM_DEFINE_OVERLOAD(2)
+  LLVM_DEFINE_OVERLOAD(3)
+  LLVM_DEFINE_OVERLOAD(4)
+  LLVM_DEFINE_OVERLOAD(5)
+  LLVM_DEFINE_OVERLOAD(6)
+  LLVM_DEFINE_OVERLOAD(7)
+  LLVM_DEFINE_OVERLOAD(8)
+  LLVM_DEFINE_OVERLOAD(9)
+  LLVM_DEFINE_OVERLOAD(10)
+  LLVM_DEFINE_OVERLOAD(11)
+  LLVM_DEFINE_OVERLOAD(12)
+  LLVM_DEFINE_OVERLOAD(13)
+  LLVM_DEFINE_OVERLOAD(14)
+  LLVM_DEFINE_OVERLOAD(15)
+  LLVM_DEFINE_OVERLOAD(16)
+  LLVM_DEFINE_OVERLOAD(17)
+  LLVM_DEFINE_OVERLOAD(18)
+  LLVM_DEFINE_OVERLOAD(19)
+  LLVM_DEFINE_OVERLOAD(20)
+  LLVM_DEFINE_OVERLOAD(21)
+  LLVM_DEFINE_OVERLOAD(22)
+  LLVM_DEFINE_OVERLOAD(23)
+  LLVM_DEFINE_OVERLOAD(24)
+  LLVM_DEFINE_OVERLOAD(25)
+  LLVM_DEFINE_OVERLOAD(26)
+  LLVM_DEFINE_OVERLOAD(27)
+  LLVM_DEFINE_OVERLOAD(28)
+  LLVM_DEFINE_OVERLOAD(29)
+  LLVM_DEFINE_OVERLOAD(30)
+  LLVM_DEFINE_OVERLOAD(31)
+  LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename Param1T,
+          typename Param2T, typename ArgT,
+          ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
+struct VariadicFunction3 {
+  ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
+    return Func(P0, P1, P2, ArrayRef<const ArgT *>());
+  }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+  ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
+                     LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+    const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+    return Func(P0, P1, P2, makeArrayRef(Args)); \
+  }
+  LLVM_DEFINE_OVERLOAD(1)
+  LLVM_DEFINE_OVERLOAD(2)
+  LLVM_DEFINE_OVERLOAD(3)
+  LLVM_DEFINE_OVERLOAD(4)
+  LLVM_DEFINE_OVERLOAD(5)
+  LLVM_DEFINE_OVERLOAD(6)
+  LLVM_DEFINE_OVERLOAD(7)
+  LLVM_DEFINE_OVERLOAD(8)
+  LLVM_DEFINE_OVERLOAD(9)
+  LLVM_DEFINE_OVERLOAD(10)
+  LLVM_DEFINE_OVERLOAD(11)
+  LLVM_DEFINE_OVERLOAD(12)
+  LLVM_DEFINE_OVERLOAD(13)
+  LLVM_DEFINE_OVERLOAD(14)
+  LLVM_DEFINE_OVERLOAD(15)
+  LLVM_DEFINE_OVERLOAD(16)
+  LLVM_DEFINE_OVERLOAD(17)
+  LLVM_DEFINE_OVERLOAD(18)
+  LLVM_DEFINE_OVERLOAD(19)
+  LLVM_DEFINE_OVERLOAD(20)
+  LLVM_DEFINE_OVERLOAD(21)
+  LLVM_DEFINE_OVERLOAD(22)
+  LLVM_DEFINE_OVERLOAD(23)
+  LLVM_DEFINE_OVERLOAD(24)
+  LLVM_DEFINE_OVERLOAD(25)
+  LLVM_DEFINE_OVERLOAD(26)
+  LLVM_DEFINE_OVERLOAD(27)
+  LLVM_DEFINE_OVERLOAD(28)
+  LLVM_DEFINE_OVERLOAD(29)
+  LLVM_DEFINE_OVERLOAD(30)
+  LLVM_DEFINE_OVERLOAD(31)
+  LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+// Cleanup the macro namespace.
+#undef LLVM_COMMA_JOIN1
+#undef LLVM_COMMA_JOIN2
+#undef LLVM_COMMA_JOIN3
+#undef LLVM_COMMA_JOIN4
+#undef LLVM_COMMA_JOIN5
+#undef LLVM_COMMA_JOIN6
+#undef LLVM_COMMA_JOIN7
+#undef LLVM_COMMA_JOIN8
+#undef LLVM_COMMA_JOIN9
+#undef LLVM_COMMA_JOIN10
+#undef LLVM_COMMA_JOIN11
+#undef LLVM_COMMA_JOIN12
+#undef LLVM_COMMA_JOIN13
+#undef LLVM_COMMA_JOIN14
+#undef LLVM_COMMA_JOIN15
+#undef LLVM_COMMA_JOIN16
+#undef LLVM_COMMA_JOIN17
+#undef LLVM_COMMA_JOIN18
+#undef LLVM_COMMA_JOIN19
+#undef LLVM_COMMA_JOIN20
+#undef LLVM_COMMA_JOIN21
+#undef LLVM_COMMA_JOIN22
+#undef LLVM_COMMA_JOIN23
+#undef LLVM_COMMA_JOIN24
+#undef LLVM_COMMA_JOIN25
+#undef LLVM_COMMA_JOIN26
+#undef LLVM_COMMA_JOIN27
+#undef LLVM_COMMA_JOIN28
+#undef LLVM_COMMA_JOIN29
+#undef LLVM_COMMA_JOIN30
+#undef LLVM_COMMA_JOIN31
+#undef LLVM_COMMA_JOIN32
+
+} // end namespace llvm
+
+#endif  // LLVM_ADT_VARIADICFUNCTION_H
diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h
new file mode 100644
index 0000000..9ee1edc
--- /dev/null
+++ b/include/llvm/ADT/edit_distance.h
@@ -0,0 +1,102 @@
+//===-- llvm/ADT/edit_distance.h - Array edit distance function --- 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 Levenshtein distance function that works for any two
+// sequences, with each element of each sequence being analogous to a character
+// in a string.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EDIT_DISTANCE_H
+#define LLVM_ADT_EDIT_DISTANCE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include <algorithm>
+#include <memory>
+
+namespace llvm {
+
+/// \brief Determine the edit distance between two sequences.
+///
+/// \param FromArray the first sequence to compare.
+///
+/// \param ToArray the second sequence to compare.
+///
+/// \param AllowReplacements whether to allow element replacements (change one
+/// element into another) as a single operation, rather than as two operations
+/// (an insertion and a removal).
+///
+/// \param MaxEditDistance If non-zero, the maximum edit distance that this
+/// routine is allowed to compute. If the edit distance will exceed that
+/// maximum, returns \c MaxEditDistance+1.
+///
+/// \returns the minimum number of element insertions, removals, or (if
+/// \p AllowReplacements is \c true) replacements needed to transform one of
+/// the given sequences into the other. If zero, the sequences are identical.
+template<typename T>
+unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
+                             bool AllowReplacements = true,
+                             unsigned MaxEditDistance = 0) {
+  // The algorithm implemented below is the "classic"
+  // dynamic-programming algorithm for computing the Levenshtein
+  // distance, which is described here:
+  //
+  //   http://en.wikipedia.org/wiki/Levenshtein_distance
+  //
+  // Although the algorithm is typically described using an m x n
+  // array, only two rows are used at a time, so this implemenation
+  // just keeps two separate vectors for those two rows.
+  typename ArrayRef<T>::size_type m = FromArray.size();
+  typename ArrayRef<T>::size_type n = ToArray.size();
+
+  const unsigned SmallBufferSize = 64;
+  unsigned SmallBuffer[SmallBufferSize];
+  std::unique_ptr<unsigned[]> Allocated;
+  unsigned *Previous = SmallBuffer;
+  if (2*(n + 1) > SmallBufferSize) {
+    Previous = new unsigned [2*(n+1)];
+    Allocated.reset(Previous);
+  }
+  unsigned *Current = Previous + (n + 1);
+
+  for (unsigned i = 0; i <= n; ++i)
+    Previous[i] = i;
+
+  for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
+    Current[0] = y;
+    unsigned BestThisRow = Current[0];
+
+    for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
+      if (AllowReplacements) {
+        Current[x] = std::min(
+            Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
+            std::min(Current[x-1], Previous[x])+1);
+      }
+      else {
+        if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1];
+        else Current[x] = std::min(Current[x-1], Previous[x]) + 1;
+      }
+      BestThisRow = std::min(BestThisRow, Current[x]);
+    }
+
+    if (MaxEditDistance && BestThisRow > MaxEditDistance)
+      return MaxEditDistance + 1;
+
+    unsigned *tmp = Current;
+    Current = Previous;
+    Previous = tmp;
+  }
+
+  unsigned Result = Previous[n];
+  return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
new file mode 100644
index 0000000..bc14845
--- /dev/null
+++ b/include/llvm/ADT/ilist.h
@@ -0,0 +1,722 @@
+//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- 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 classes to implement an intrusive doubly linked list class
+// (i.e. each node of the list must contain a next and previous field for the
+// list.
+//
+// The ilist_traits trait class is used to gain access to the next and previous
+// fields of the node type that the list is instantiated with.  If it is not
+// specialized, the list defaults to using the getPrev(), getNext() method calls
+// to get the next and previous pointers.
+//
+// The ilist class itself, should be a plug in replacement for list, assuming
+// that the nodes contain next/prev pointers.  This list replacement does not
+// provide a constant time size() method, so be careful to use empty() when you
+// really want to know if it's empty.
+//
+// The ilist class is implemented by allocating a 'tail' node when the list is
+// created (using ilist_traits<>::createSentinel()).  This tail node is
+// absolutely required because the user must be able to compute end()-1. Because
+// of this, users of the direct next/prev links will see an extra link on the
+// end of the list, which should be ignored.
+//
+// Requirements for a user of this list:
+//
+//   1. The user must provide {g|s}et{Next|Prev} methods, or specialize
+//      ilist_traits to provide an alternate way of getting and setting next and
+//      prev links.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST_H
+#define LLVM_ADT_ILIST_H
+
+#include "llvm/Support/Compiler.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+
+namespace llvm {
+
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+/// ilist_nextprev_traits - A fragment for template traits for intrusive list
+/// that provides default next/prev implementations for common operations.
+///
+template<typename NodeTy>
+struct ilist_nextprev_traits {
+  static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+  static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+  static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+  static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+  static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+  static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+};
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_sentinel_traits - A fragment for template traits for intrusive list
+/// that provides default sentinel implementations for common operations.
+///
+/// ilist_sentinel_traits implements a lazy dynamic sentinel allocation
+/// strategy. The sentinel is stored in the prev field of ilist's Head.
+///
+template<typename NodeTy>
+struct ilist_sentinel_traits {
+  /// createSentinel - create the dynamic sentinel
+  static NodeTy *createSentinel() { return new NodeTy(); }
+
+  /// destroySentinel - deallocate the dynamic sentinel
+  static void destroySentinel(NodeTy *N) { delete N; }
+
+  /// provideInitialHead - when constructing an ilist, provide a starting
+  /// value for its Head
+  /// @return null node to indicate that it needs to be allocated later
+  static NodeTy *provideInitialHead() { return nullptr; }
+
+  /// ensureHead - make sure that Head is either already
+  /// initialized or assigned a fresh sentinel
+  /// @return the sentinel
+  static NodeTy *ensureHead(NodeTy *&Head) {
+    if (!Head) {
+      Head = ilist_traits<NodeTy>::createSentinel();
+      ilist_traits<NodeTy>::noteHead(Head, Head);
+      ilist_traits<NodeTy>::setNext(Head, nullptr);
+      return Head;
+    }
+    return ilist_traits<NodeTy>::getPrev(Head);
+  }
+
+  /// noteHead - stash the sentinel into its default location
+  static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
+    ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
+  }
+};
+
+/// ilist_node_traits - A fragment for template traits for intrusive list
+/// that provides default node related operations.
+///
+template<typename NodeTy>
+struct ilist_node_traits {
+  static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+  static void deleteNode(NodeTy *V) { delete V; }
+
+  void addNodeToList(NodeTy *) {}
+  void removeNodeFromList(NodeTy *) {}
+  void transferNodesFromList(ilist_node_traits &    /*SrcTraits*/,
+                             ilist_iterator<NodeTy> /*first*/,
+                             ilist_iterator<NodeTy> /*last*/) {}
+};
+
+/// ilist_default_traits - Default template traits for intrusive list.
+/// By inheriting from this, you can easily use default implementations
+/// for all common operations.
+///
+template<typename NodeTy>
+struct ilist_default_traits : public ilist_nextprev_traits<NodeTy>,
+                              public ilist_sentinel_traits<NodeTy>,
+                              public ilist_node_traits<NodeTy> {
+};
+
+// Template traits for intrusive list.  By specializing this template class, you
+// can change what next/prev fields are used to store the links...
+template<typename NodeTy>
+struct ilist_traits : public ilist_default_traits<NodeTy> {};
+
+// Const traits are the same as nonconst traits...
+template<typename Ty>
+struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
+
+//===----------------------------------------------------------------------===//
+// ilist_iterator<Node> - Iterator for intrusive list.
+//
+template<typename NodeTy>
+class ilist_iterator
+  : public std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t> {
+
+public:
+  typedef ilist_traits<NodeTy> Traits;
+  typedef std::iterator<std::bidirectional_iterator_tag,
+                        NodeTy, ptrdiff_t> super;
+
+  typedef typename super::value_type value_type;
+  typedef typename super::difference_type difference_type;
+  typedef typename super::pointer pointer;
+  typedef typename super::reference reference;
+private:
+  pointer NodePtr;
+
+  // ilist_iterator is not a random-access iterator, but it has an
+  // implicit conversion to pointer-type, which is. Declare (but
+  // don't define) these functions as private to help catch
+  // accidental misuse.
+  void operator[](difference_type) const;
+  void operator+(difference_type) const;
+  void operator-(difference_type) const;
+  void operator+=(difference_type) const;
+  void operator-=(difference_type) const;
+  template<class T> void operator<(T) const;
+  template<class T> void operator<=(T) const;
+  template<class T> void operator>(T) const;
+  template<class T> void operator>=(T) const;
+  template<class T> void operator-(T) const;
+public:
+
+  ilist_iterator(pointer NP) : NodePtr(NP) {}
+  ilist_iterator(reference NR) : NodePtr(&NR) {}
+  ilist_iterator() : NodePtr(nullptr) {}
+
+  // This is templated so that we can allow constructing a const iterator from
+  // a nonconst iterator...
+  template<class node_ty>
+  ilist_iterator(const ilist_iterator<node_ty> &RHS)
+    : NodePtr(RHS.getNodePtrUnchecked()) {}
+
+  // This is templated so that we can allow assigning to a const iterator from
+  // a nonconst iterator...
+  template<class node_ty>
+  const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
+    NodePtr = RHS.getNodePtrUnchecked();
+    return *this;
+  }
+
+  // Accessors...
+  operator pointer() const {
+    return NodePtr;
+  }
+
+  reference operator*() const {
+    return *NodePtr;
+  }
+  pointer operator->() const { return &operator*(); }
+
+  // Comparison operators
+  bool operator==(const ilist_iterator &RHS) const {
+    return NodePtr == RHS.NodePtr;
+  }
+  bool operator!=(const ilist_iterator &RHS) const {
+    return NodePtr != RHS.NodePtr;
+  }
+
+  // Increment and decrement operators...
+  ilist_iterator &operator--() {      // predecrement - Back up
+    NodePtr = Traits::getPrev(NodePtr);
+    assert(NodePtr && "--'d off the beginning of an ilist!");
+    return *this;
+  }
+  ilist_iterator &operator++() {      // preincrement - Advance
+    NodePtr = Traits::getNext(NodePtr);
+    return *this;
+  }
+  ilist_iterator operator--(int) {    // postdecrement operators...
+    ilist_iterator tmp = *this;
+    --*this;
+    return tmp;
+  }
+  ilist_iterator operator++(int) {    // postincrement operators...
+    ilist_iterator tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  // Internal interface, do not use...
+  pointer getNodePtrUnchecked() const { return NodePtr; }
+};
+
+// These are to catch errors when people try to use them as random access
+// iterators.
+template<typename T>
+void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
+template<typename T>
+void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
+
+template<typename T>
+void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
+template<typename T>
+void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+  return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+  return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+  return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+  return LHS == RHS.getNodePtrUnchecked();
+}
+
+
+// Allow ilist_iterators to convert into pointers to a node automatically when
+// used by the dyn_cast, cast, isa mechanisms...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+  typedef NodeTy* SimpleType;
+
+  static SimpleType getSimplifiedValue(ilist_iterator<NodeTy> &Node) {
+    return &*Node;
+  }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+  typedef /*const*/ NodeTy* SimpleType;
+
+  static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+    return &*Node;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+/// iplist - The subset of list functionality that can safely be used on nodes
+/// of polymorphic types, i.e. a heterogeneous list with a common base class that
+/// holds the next/prev pointers.  The only state of the list itself is a single
+/// pointer to the head of the list.
+///
+/// This list can be in one of three interesting states:
+/// 1. The list may be completely unconstructed.  In this case, the head
+///    pointer is null.  When in this form, any query for an iterator (e.g.
+///    begin() or end()) causes the list to transparently change to state #2.
+/// 2. The list may be empty, but contain a sentinel for the end iterator. This
+///    sentinel is created by the Traits::createSentinel method and is a link
+///    in the list.  When the list is empty, the pointer in the iplist points
+///    to the sentinel.  Once the sentinel is constructed, it
+///    is not destroyed until the list is.
+/// 3. The list may contain actual objects in it, which are stored as a doubly
+///    linked list of nodes.  One invariant of the list is that the predecessor
+///    of the first node in the list always points to the last node in the list,
+///    and the successor pointer for the sentinel (which always stays at the
+///    end of the list) is always null.
+///
+template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
+class iplist : public Traits {
+  mutable NodeTy *Head;
+
+  // Use the prev node pointer of 'head' as the tail pointer.  This is really a
+  // circularly linked list where we snip the 'next' link from the sentinel node
+  // back to the first node in the list (to preserve assertions about going off
+  // the end of the list).
+  NodeTy *getTail() { return this->ensureHead(Head); }
+  const NodeTy *getTail() const { return this->ensureHead(Head); }
+  void setTail(NodeTy *N) const { this->noteHead(Head, N); }
+
+  /// CreateLazySentinel - This method verifies whether the sentinel for the
+  /// list has been created and lazily makes it if not.
+  void CreateLazySentinel() const {
+    this->ensureHead(Head);
+  }
+
+  static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
+  static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
+
+  // No fundamental reason why iplist can't be copyable, but the default
+  // copy/copy-assign won't do.
+  iplist(const iplist &) LLVM_DELETED_FUNCTION;
+  void operator=(const iplist &) LLVM_DELETED_FUNCTION;
+
+public:
+  typedef NodeTy *pointer;
+  typedef const NodeTy *const_pointer;
+  typedef NodeTy &reference;
+  typedef const NodeTy &const_reference;
+  typedef NodeTy value_type;
+  typedef ilist_iterator<NodeTy> iterator;
+  typedef ilist_iterator<const NodeTy> const_iterator;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>  reverse_iterator;
+
+  iplist() : Head(this->provideInitialHead()) {}
+  ~iplist() {
+    if (!Head) return;
+    clear();
+    Traits::destroySentinel(getTail());
+  }
+
+  // Iterator creation methods.
+  iterator begin() {
+    CreateLazySentinel();
+    return iterator(Head);
+  }
+  const_iterator begin() const {
+    CreateLazySentinel();
+    return const_iterator(Head);
+  }
+  iterator end() {
+    CreateLazySentinel();
+    return iterator(getTail());
+  }
+  const_iterator end() const {
+    CreateLazySentinel();
+    return const_iterator(getTail());
+  }
+
+  // reverse iterator creation methods.
+  reverse_iterator rbegin()            { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+  reverse_iterator rend()              { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+  // Miscellaneous inspection routines.
+  size_type max_size() const { return size_type(-1); }
+  bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
+    return !Head || Head == getTail();
+  }
+
+  // Front and back accessor functions...
+  reference front() {
+    assert(!empty() && "Called front() on empty list!");
+    return *Head;
+  }
+  const_reference front() const {
+    assert(!empty() && "Called front() on empty list!");
+    return *Head;
+  }
+  reference back() {
+    assert(!empty() && "Called back() on empty list!");
+    return *this->getPrev(getTail());
+  }
+  const_reference back() const {
+    assert(!empty() && "Called back() on empty list!");
+    return *this->getPrev(getTail());
+  }
+
+  void swap(iplist &RHS) {
+    assert(0 && "Swap does not use list traits callback correctly yet!");
+    std::swap(Head, RHS.Head);
+  }
+
+  iterator insert(iterator where, NodeTy *New) {
+    NodeTy *CurNode = where.getNodePtrUnchecked();
+    NodeTy *PrevNode = this->getPrev(CurNode);
+    this->setNext(New, CurNode);
+    this->setPrev(New, PrevNode);
+
+    if (CurNode != Head)  // Is PrevNode off the beginning of the list?
+      this->setNext(PrevNode, New);
+    else
+      Head = New;
+    this->setPrev(CurNode, New);
+
+    this->addNodeToList(New);  // Notify traits that we added a node...
+    return New;
+  }
+
+  iterator insertAfter(iterator where, NodeTy *New) {
+    if (empty())
+      return insert(begin(), New);
+    else
+      return insert(++where, New);
+  }
+
+  NodeTy *remove(iterator &IT) {
+    assert(IT != end() && "Cannot remove end of list!");
+    NodeTy *Node = &*IT;
+    NodeTy *NextNode = this->getNext(Node);
+    NodeTy *PrevNode = this->getPrev(Node);
+
+    if (Node != Head)  // Is PrevNode off the beginning of the list?
+      this->setNext(PrevNode, NextNode);
+    else
+      Head = NextNode;
+    this->setPrev(NextNode, PrevNode);
+    IT = NextNode;
+    this->removeNodeFromList(Node);  // Notify traits that we removed a node...
+
+    // Set the next/prev pointers of the current node to null.  This isn't
+    // strictly required, but this catches errors where a node is removed from
+    // an ilist (and potentially deleted) with iterators still pointing at it.
+    // When those iterators are incremented or decremented, they will assert on
+    // the null next/prev pointer instead of "usually working".
+    this->setNext(Node, nullptr);
+    this->setPrev(Node, nullptr);
+    return Node;
+  }
+
+  NodeTy *remove(const iterator &IT) {
+    iterator MutIt = IT;
+    return remove(MutIt);
+  }
+
+  // erase - remove a node from the controlled sequence... and delete it.
+  iterator erase(iterator where) {
+    this->deleteNode(remove(where));
+    return where;
+  }
+
+  /// Remove all nodes from the list like clear(), but do not call
+  /// removeNodeFromList() or deleteNode().
+  ///
+  /// This should only be used immediately before freeing nodes in bulk to
+  /// avoid traversing the list and bringing all the nodes into cache.
+  void clearAndLeakNodesUnsafely() {
+    if (Head) {
+      Head = getTail();
+      this->setPrev(Head, Head);
+    }
+  }
+
+private:
+  // transfer - The heart of the splice function.  Move linked list nodes from
+  // [first, last) into position.
+  //
+  void transfer(iterator position, iplist &L2, iterator first, iterator last) {
+    assert(first != last && "Should be checked by callers");
+    // Position cannot be contained in the range to be transferred.
+    // Check for the most common mistake.
+    assert(position != first &&
+           "Insertion point can't be one of the transferred nodes");
+
+    if (position != last) {
+      // Note: we have to be careful about the case when we move the first node
+      // in the list.  This node is the list sentinel node and we can't move it.
+      NodeTy *ThisSentinel = getTail();
+      setTail(nullptr);
+      NodeTy *L2Sentinel = L2.getTail();
+      L2.setTail(nullptr);
+
+      // Remove [first, last) from its old position.
+      NodeTy *First = &*first, *Prev = this->getPrev(First);
+      NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
+      if (Prev)
+        this->setNext(Prev, Next);
+      else
+        L2.Head = Next;
+      this->setPrev(Next, Prev);
+
+      // Splice [first, last) into its new position.
+      NodeTy *PosNext = position.getNodePtrUnchecked();
+      NodeTy *PosPrev = this->getPrev(PosNext);
+
+      // Fix head of list...
+      if (PosPrev)
+        this->setNext(PosPrev, First);
+      else
+        Head = First;
+      this->setPrev(First, PosPrev);
+
+      // Fix end of list...
+      this->setNext(Last, PosNext);
+      this->setPrev(PosNext, Last);
+
+      this->transferNodesFromList(L2, First, PosNext);
+
+      // Now that everything is set, restore the pointers to the list sentinels.
+      L2.setTail(L2Sentinel);
+      setTail(ThisSentinel);
+    }
+  }
+
+public:
+
+  //===----------------------------------------------------------------------===
+  // Functionality derived from other functions defined above...
+  //
+
+  size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const {
+    if (!Head) return 0; // Don't require construction of sentinel if empty.
+    return std::distance(begin(), end());
+  }
+
+  iterator erase(iterator first, iterator last) {
+    while (first != last)
+      first = erase(first);
+    return last;
+  }
+
+  void clear() { if (Head) erase(begin(), end()); }
+
+  // Front and back inserters...
+  void push_front(NodeTy *val) { insert(begin(), val); }
+  void push_back(NodeTy *val) { insert(end(), val); }
+  void pop_front() {
+    assert(!empty() && "pop_front() on empty list!");
+    erase(begin());
+  }
+  void pop_back() {
+    assert(!empty() && "pop_back() on empty list!");
+    iterator t = end(); erase(--t);
+  }
+
+  // Special forms of insert...
+  template<class InIt> void insert(iterator where, InIt first, InIt last) {
+    for (; first != last; ++first) insert(where, *first);
+  }
+
+  // Splice members - defined in terms of transfer...
+  void splice(iterator where, iplist &L2) {
+    if (!L2.empty())
+      transfer(where, L2, L2.begin(), L2.end());
+  }
+  void splice(iterator where, iplist &L2, iterator first) {
+    iterator last = first; ++last;
+    if (where == first || where == last) return; // No change
+    transfer(where, L2, first, last);
+  }
+  void splice(iterator where, iplist &L2, iterator first, iterator last) {
+    if (first != last) transfer(where, L2, first, last);
+  }
+
+
+
+  //===----------------------------------------------------------------------===
+  // High-Level Functionality that shouldn't really be here, but is part of list
+  //
+
+  // These two functions are actually called remove/remove_if in list<>, but
+  // they actually do the job of erase, rename them accordingly.
+  //
+  void erase(const NodeTy &val) {
+    for (iterator I = begin(), E = end(); I != E; ) {
+      iterator next = I; ++next;
+      if (*I == val) erase(I);
+      I = next;
+    }
+  }
+  template<class Pr1> void erase_if(Pr1 pred) {
+    for (iterator I = begin(), E = end(); I != E; ) {
+      iterator next = I; ++next;
+      if (pred(*I)) erase(I);
+      I = next;
+    }
+  }
+
+  template<class Pr2> void unique(Pr2 pred) {
+    if (empty()) return;
+    for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
+      if (pred(*I))
+        erase(Next);
+      else
+        I = Next;
+      Next = I;
+    }
+  }
+  void unique() { unique(op_equal); }
+
+  template<class Pr3> void merge(iplist &right, Pr3 pred) {
+    iterator first1 = begin(), last1 = end();
+    iterator first2 = right.begin(), last2 = right.end();
+    while (first1 != last1 && first2 != last2)
+      if (pred(*first2, *first1)) {
+        iterator next = first2;
+        transfer(first1, right, first2, ++next);
+        first2 = next;
+      } else {
+        ++first1;
+      }
+    if (first2 != last2) transfer(last1, right, first2, last2);
+  }
+  void merge(iplist &right) { return merge(right, op_less); }
+
+  template<class Pr3> void sort(Pr3 pred);
+  void sort() { sort(op_less); }
+};
+
+
+template<typename NodeTy>
+struct ilist : public iplist<NodeTy> {
+  typedef typename iplist<NodeTy>::size_type size_type;
+  typedef typename iplist<NodeTy>::iterator iterator;
+
+  ilist() {}
+  ilist(const ilist &right) {
+    insert(this->begin(), right.begin(), right.end());
+  }
+  explicit ilist(size_type count) {
+    insert(this->begin(), count, NodeTy());
+  }
+  ilist(size_type count, const NodeTy &val) {
+    insert(this->begin(), count, val);
+  }
+  template<class InIt> ilist(InIt first, InIt last) {
+    insert(this->begin(), first, last);
+  }
+
+  // bring hidden functions into scope
+  using iplist<NodeTy>::insert;
+  using iplist<NodeTy>::push_front;
+  using iplist<NodeTy>::push_back;
+
+  // Main implementation here - Insert for a node passed by value...
+  iterator insert(iterator where, const NodeTy &val) {
+    return insert(where, this->createNode(val));
+  }
+
+
+  // Front and back inserters...
+  void push_front(const NodeTy &val) { insert(this->begin(), val); }
+  void push_back(const NodeTy &val) { insert(this->end(), val); }
+
+  void insert(iterator where, size_type count, const NodeTy &val) {
+    for (; count != 0; --count) insert(where, val);
+  }
+
+  // Assign special forms...
+  void assign(size_type count, const NodeTy &val) {
+    iterator I = this->begin();
+    for (; I != this->end() && count != 0; ++I, --count)
+      *I = val;
+    if (count != 0)
+      insert(this->end(), val, val);
+    else
+      erase(I, this->end());
+  }
+  template<class InIt> void assign(InIt first1, InIt last1) {
+    iterator first2 = this->begin(), last2 = this->end();
+    for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+      *first1 = *first2;
+    if (first2 == last2)
+      erase(first1, last1);
+    else
+      insert(last1, first2, last2);
+  }
+
+
+  // Resize members...
+  void resize(size_type newsize, NodeTy val) {
+    iterator i = this->begin();
+    size_type len = 0;
+    for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
+
+    if (len == newsize)
+      erase(i, this->end());
+    else                                          // i == end()
+      insert(this->end(), newsize - len, val);
+  }
+  void resize(size_type newsize) { resize(newsize, NodeTy()); }
+};
+
+} // End llvm namespace
+
+namespace std {
+  // Ensure that swap uses the fast list swap...
+  template<class Ty>
+  void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
+    Left.swap(Right);
+  }
+}  // End 'std' extensions...
+
+#endif // LLVM_ADT_ILIST_H
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
new file mode 100644
index 0000000..85aa7a4
--- /dev/null
+++ b/include/llvm/ADT/ilist_node.h
@@ -0,0 +1,106 @@
+//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- 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 ilist_node class template, which is a convenient
+// base class for creating classes that can be used with ilists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILISTNODE_H
+#define LLVM_ADT_ILISTNODE_H
+
+namespace llvm {
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_half_node - Base class that provides prev services for sentinels.
+///
+template<typename NodeTy>
+class ilist_half_node {
+  friend struct ilist_traits<NodeTy>;
+  NodeTy *Prev;
+protected:
+  NodeTy *getPrev() { return Prev; }
+  const NodeTy *getPrev() const { return Prev; }
+  void setPrev(NodeTy *P) { Prev = P; }
+  ilist_half_node() : Prev(nullptr) {}
+};
+
+template<typename NodeTy>
+struct ilist_nextprev_traits;
+
+/// ilist_node - Base class that provides next/prev services for nodes
+/// that use ilist_nextprev_traits or ilist_default_traits.
+///
+template<typename NodeTy>
+class ilist_node : private ilist_half_node<NodeTy> {
+  friend struct ilist_nextprev_traits<NodeTy>;
+  friend struct ilist_traits<NodeTy>;
+  NodeTy *Next;
+  NodeTy *getNext() { return Next; }
+  const NodeTy *getNext() const { return Next; }
+  void setNext(NodeTy *N) { Next = N; }
+protected:
+  ilist_node() : Next(nullptr) {}
+
+public:
+  /// @name Adjacent Node Accessors
+  /// @{
+
+  /// \brief Get the previous node, or 0 for the list head.
+  NodeTy *getPrevNode() {
+    NodeTy *Prev = this->getPrev();
+
+    // Check for sentinel.
+    if (!Prev->getNext())
+      return nullptr;
+
+    return Prev;
+  }
+
+  /// \brief Get the previous node, or 0 for the list head.
+  const NodeTy *getPrevNode() const {
+    const NodeTy *Prev = this->getPrev();
+
+    // Check for sentinel.
+    if (!Prev->getNext())
+      return nullptr;
+
+    return Prev;
+  }
+
+  /// \brief Get the next node, or 0 for the list tail.
+  NodeTy *getNextNode() {
+    NodeTy *Next = getNext();
+
+    // Check for sentinel.
+    if (!Next->getNext())
+      return nullptr;
+
+    return Next;
+  }
+
+  /// \brief Get the next node, or 0 for the list tail.
+  const NodeTy *getNextNode() const {
+    const NodeTy *Next = getNext();
+
+    // Check for sentinel.
+    if (!Next->getNext())
+      return nullptr;
+
+    return Next;
+  }
+
+  /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h
new file mode 100644
index 0000000..56041db
--- /dev/null
+++ b/include/llvm/ADT/iterator.h
@@ -0,0 +1,244 @@
+//===- iterator.h - Utilities for using and defining iterators --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_H
+#define LLVM_ADT_ITERATOR_H
+
+#include <iterator>
+#include <cstddef>
+
+namespace llvm {
+
+/// \brief CRTP base class which implements the entire standard iterator facade
+/// in terms of a minimal subset of the interface.
+///
+/// Use this when it is reasonable to implement most of the iterator
+/// functionality in terms of a core subset. If you need special behavior or
+/// there are performance implications for this, you may want to override the
+/// relevant members instead.
+///
+/// Note, one abstraction that this does *not* provide is implementing
+/// subtraction in terms of addition by negating the difference. Negation isn't
+/// always information preserving, and I can see very reasonable iterator
+/// designs where this doesn't work well. It doesn't really force much added
+/// boilerplate anyways.
+///
+/// Another abstraction that this doesn't provide is implementing increment in
+/// terms of addition of one. These aren't equivalent for all iterator
+/// categories, and respecting that adds a lot of complexity for little gain.
+template <typename DerivedT, typename IteratorCategoryT, typename T,
+          typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T *,
+          typename ReferenceT = T &>
+class iterator_facade_base
+    : public std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT,
+                           ReferenceT> {
+protected:
+  enum {
+    IsRandomAccess =
+        std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value,
+    IsBidirectional =
+        std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value,
+  };
+
+public:
+  DerivedT operator+(DifferenceTypeT n) const {
+    static_assert(
+        IsRandomAccess,
+        "The '+' operator is only defined for random access iterators.");
+    DerivedT tmp = *static_cast<const DerivedT *>(this);
+    tmp += n;
+    return tmp;
+  }
+  friend DerivedT operator+(DifferenceTypeT n, const DerivedT &i) {
+    static_assert(
+        IsRandomAccess,
+        "The '+' operator is only defined for random access iterators.");
+    return i + n;
+  }
+  DerivedT operator-(DifferenceTypeT n) const {
+    static_assert(
+        IsRandomAccess,
+        "The '-' operator is only defined for random access iterators.");
+    DerivedT tmp = *static_cast<const DerivedT *>(this);
+    tmp -= n;
+    return tmp;
+  }
+
+  DerivedT &operator++() {
+    return static_cast<DerivedT *>(this)->operator+=(1);
+  }
+  DerivedT operator++(int) {
+    DerivedT tmp = *static_cast<DerivedT *>(this);
+    ++*static_cast<DerivedT *>(this);
+    return tmp;
+  }
+  DerivedT &operator--() {
+    static_assert(
+        IsBidirectional,
+        "The decrement operator is only defined for bidirectional iterators.");
+    return static_cast<DerivedT *>(this)->operator-=(1);
+  }
+  DerivedT operator--(int) {
+    static_assert(
+        IsBidirectional,
+        "The decrement operator is only defined for bidirectional iterators.");
+    DerivedT tmp = *static_cast<DerivedT *>(this);
+    --*static_cast<DerivedT *>(this);
+    return tmp;
+  }
+
+  bool operator!=(const DerivedT &RHS) const {
+    return !static_cast<const DerivedT *>(this)->operator==(RHS);
+  }
+
+  bool operator>(const DerivedT &RHS) const {
+    static_assert(
+        IsRandomAccess,
+        "Relational operators are only defined for random access iterators.");
+    return !static_cast<const DerivedT *>(this)->operator<(RHS) &&
+           !static_cast<const DerivedT *>(this)->operator==(RHS);
+  }
+  bool operator<=(const DerivedT &RHS) const {
+    static_assert(
+        IsRandomAccess,
+        "Relational operators are only defined for random access iterators.");
+    return !static_cast<const DerivedT *>(this)->operator>(RHS);
+  }
+  bool operator>=(const DerivedT &RHS) const {
+    static_assert(
+        IsRandomAccess,
+        "Relational operators are only defined for random access iterators.");
+    return !static_cast<const DerivedT *>(this)->operator<(RHS);
+  }
+
+  PointerT operator->() const {
+    return &static_cast<const DerivedT *>(this)->operator*();
+  }
+  ReferenceT operator[](DifferenceTypeT n) const {
+    static_assert(IsRandomAccess,
+                  "Subscripting is only defined for random access iterators.");
+    return *static_cast<const DerivedT *>(this)->operator+(n);
+  }
+};
+
+/// \brief CRTP base class for adapting an iterator to a different type.
+///
+/// This class can be used through CRTP to adapt one iterator into another.
+/// Typically this is done through providing in the derived class a custom \c
+/// operator* implementation. Other methods can be overridden as well.
+template <
+    typename DerivedT, typename WrappedIteratorT,
+    typename IteratorCategoryT =
+        typename std::iterator_traits<WrappedIteratorT>::iterator_category,
+    typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
+    typename DifferenceTypeT =
+        typename std::iterator_traits<WrappedIteratorT>::difference_type,
+    typename PointerT = T *, typename ReferenceT = T &,
+    // Don't provide these, they are mostly to act as aliases below.
+    typename WrappedTraitsT = std::iterator_traits<WrappedIteratorT>>
+class iterator_adaptor_base
+    : public iterator_facade_base<DerivedT, IteratorCategoryT, T,
+                                  DifferenceTypeT, PointerT, ReferenceT> {
+  typedef typename iterator_adaptor_base::iterator_facade_base BaseT;
+
+protected:
+  WrappedIteratorT I;
+
+  iterator_adaptor_base() {}
+
+  template <typename U>
+  explicit iterator_adaptor_base(
+      U &&u,
+      typename std::enable_if<
+          !std::is_base_of<typename std::remove_cv<
+                               typename std::remove_reference<U>::type>::type,
+                           DerivedT>::value,
+          int>::type = 0)
+      : I(std::forward<U &&>(u)) {}
+
+public:
+  typedef DifferenceTypeT difference_type;
+
+  DerivedT &operator+=(difference_type n) {
+    static_assert(
+        BaseT::IsRandomAccess,
+        "The '+=' operator is only defined for random access iterators.");
+    I += n;
+    return *static_cast<DerivedT *>(this);
+  }
+  DerivedT &operator-=(difference_type n) {
+    static_assert(
+        BaseT::IsRandomAccess,
+        "The '-=' operator is only defined for random access iterators.");
+    I -= n;
+    return *static_cast<DerivedT *>(this);
+  }
+  using BaseT::operator-;
+  difference_type operator-(const DerivedT &RHS) const {
+    static_assert(
+        BaseT::IsRandomAccess,
+        "The '-' operator is only defined for random access iterators.");
+    return I - RHS.I;
+  }
+
+  // We have to explicitly provide ++ and -- rather than letting the facade
+  // forward to += because WrappedIteratorT might not support +=.
+  using BaseT::operator++;
+  DerivedT &operator++() {
+    ++I;
+    return *static_cast<DerivedT *>(this);
+  }
+  using BaseT::operator--;
+  DerivedT &operator--() {
+    static_assert(
+        BaseT::IsBidirectional,
+        "The decrement operator is only defined for bidirectional iterators.");
+    --I;
+    return *static_cast<DerivedT *>(this);
+  }
+
+  bool operator==(const DerivedT &RHS) const { return I == RHS.I; }
+  bool operator<(const DerivedT &RHS) const {
+    static_assert(
+        BaseT::IsRandomAccess,
+        "Relational operators are only defined for random access iterators.");
+    return I < RHS.I;
+  }
+
+  ReferenceT operator*() const { return *I; }
+};
+
+/// \brief An iterator type that allows iterating over the pointees via some
+/// other iterator.
+///
+/// The typical usage of this is to expose a type that iterates over Ts, but
+/// which is implemented with some iterator over T*s:
+///
+/// \code
+///   typedef pointee_iterator<SmallVectorImpl<T *>::iterator> iterator;
+/// \endcode
+template <typename WrappedIteratorT,
+          typename T = typename std::remove_reference<
+              decltype(**std::declval<WrappedIteratorT>())>::type>
+struct pointee_iterator
+    : iterator_adaptor_base<
+          pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
+          typename std::iterator_traits<WrappedIteratorT>::iterator_category,
+          T> {
+  pointee_iterator() {}
+  template <typename U>
+  pointee_iterator(U &&u)
+      : pointee_iterator::iterator_adaptor_base(std::forward<U &&>(u)) {}
+
+  T &operator*() const { return **this->I; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h
new file mode 100644
index 0000000..dd17d6c
--- /dev/null
+++ b/include/llvm/ADT/iterator_range.h
@@ -0,0 +1,53 @@
+//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This provides a very simple, boring adaptor for a begin and end iterator
+/// into a range type. This should be used to build range views that work well
+/// with range based for loops and range based constructors.
+///
+/// Note that code here follows more standards-based coding conventions as it
+/// is mirroring proposed interfaces for standardization.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_RANGE_H
+#define LLVM_ADT_ITERATOR_RANGE_H
+
+#include <utility>
+
+namespace llvm {
+
+/// \brief A range adaptor for a pair of iterators.
+///
+/// This just wraps two iterators into a range-compatible interface. Nothing
+/// fancy at all.
+template <typename IteratorT>
+class iterator_range {
+  IteratorT begin_iterator, end_iterator;
+
+public:
+  iterator_range() {}
+  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
+      : begin_iterator(std::move(begin_iterator)),
+        end_iterator(std::move(end_iterator)) {}
+
+  IteratorT begin() const { return begin_iterator; }
+  IteratorT end() const { return end_iterator; }
+};
+
+/// \brief Convenience function for iterating over sub-ranges.
+///
+/// This provides a bit of syntactic sugar to make using sub-ranges
+/// in for loops a bit easier. Analogous to std::make_pair().
+template <class T> iterator_range<T> make_range(T x, T y) {
+  return iterator_range<T>(std::move(x), std::move(y));
+}
+}
+
+#endif
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
new file mode 100644
index 0000000..6897664
--- /dev/null
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -0,0 +1,617 @@
+//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- 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 generic AliasAnalysis interface, which is used as the
+// common interface used by all clients of alias analysis information, and
+// implemented by all alias analysis implementations.  Mod/Ref information is
+// also captured by this interface.
+//
+// Implementations of this interface must implement the various virtual methods,
+// which automatically provides functionality for the entire suite of client
+// APIs.
+//
+// This API identifies memory regions with the Location class. The pointer
+// component specifies the base memory address of the region. The Size specifies
+// the maximum size (in address units) of the memory region, or UnknownSize if
+// the size is not known. The TBAA tag identifies the "type" of the memory
+// reference; see the TypeBasedAliasAnalysis class for details.
+//
+// Some non-obvious details include:
+//  - Pointers that point to two completely different objects in memory never
+//    alias, regardless of the value of the Size component.
+//  - NoAlias doesn't imply inequal pointers. The most obvious example of this
+//    is two pointers to constant memory. Even if they are equal, constant
+//    memory is never stored to, so there will never be any dependencies.
+//    In this and other situations, the pointers may be both NoAlias and
+//    MustAlias at the same time. The current API can only return one result,
+//    though this is rarely a problem in practice.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
+#define LLVM_ANALYSIS_ALIASANALYSIS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/CallSite.h"
+
+namespace llvm {
+
+class LoadInst;
+class StoreInst;
+class VAArgInst;
+class DataLayout;
+class TargetLibraryInfo;
+class Pass;
+class AnalysisUsage;
+class MemTransferInst;
+class MemIntrinsic;
+class DominatorTree;
+
+class AliasAnalysis {
+protected:
+  const DataLayout *DL;
+  const TargetLibraryInfo *TLI;
+
+private:
+  AliasAnalysis *AA;       // Previous Alias Analysis to chain to.
+
+protected:
+  /// InitializeAliasAnalysis - Subclasses must call this method to initialize
+  /// the AliasAnalysis interface before any other methods are called.  This is
+  /// typically called by the run* methods of these subclasses.  This may be
+  /// called multiple times.
+  ///
+  void InitializeAliasAnalysis(Pass *P);
+
+  /// getAnalysisUsage - All alias analysis implementations should invoke this
+  /// directly (using AliasAnalysis::getAnalysisUsage(AU)).
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+  static char ID; // Class identification, replacement for typeinfo
+  AliasAnalysis() : DL(nullptr), TLI(nullptr), AA(nullptr) {}
+  virtual ~AliasAnalysis();  // We want to be subclassed
+
+  /// UnknownSize - This is a special value which can be used with the
+  /// size arguments in alias queries to indicate that the caller does not
+  /// know the sizes of the potential memory references.
+  static uint64_t const UnknownSize = ~UINT64_C(0);
+
+  /// getDataLayout - Return a pointer to the current DataLayout object, or
+  /// null if no DataLayout object is available.
+  ///
+  const DataLayout *getDataLayout() const { return DL; }
+
+  /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
+  /// object, or null if no TargetLibraryInfo object is available.
+  ///
+  const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
+
+  /// getTypeStoreSize - Return the DataLayout store size for the given type,
+  /// if known, or a conservative value otherwise.
+  ///
+  uint64_t getTypeStoreSize(Type *Ty);
+
+  //===--------------------------------------------------------------------===//
+  /// Alias Queries...
+  ///
+
+  /// Location - A description of a memory location.
+  struct Location {
+    /// Ptr - The address of the start of the location.
+    const Value *Ptr;
+    /// Size - The maximum size of the location, in address-units, or
+    /// UnknownSize if the size is not known.  Note that an unknown size does
+    /// not mean the pointer aliases the entire virtual address space, because
+    /// there are restrictions on stepping out of one object and into another.
+    /// See http://llvm.org/docs/LangRef.html#pointeraliasing
+    uint64_t Size;
+    /// TBAATag - The metadata node which describes the TBAA type of
+    /// the location, or null if there is no known unique tag.
+    const MDNode *TBAATag;
+
+    explicit Location(const Value *P = nullptr, uint64_t S = UnknownSize,
+                      const MDNode *N = nullptr)
+      : Ptr(P), Size(S), TBAATag(N) {}
+
+    Location getWithNewPtr(const Value *NewPtr) const {
+      Location Copy(*this);
+      Copy.Ptr = NewPtr;
+      return Copy;
+    }
+
+    Location getWithNewSize(uint64_t NewSize) const {
+      Location Copy(*this);
+      Copy.Size = NewSize;
+      return Copy;
+    }
+
+    Location getWithoutTBAATag() const {
+      Location Copy(*this);
+      Copy.TBAATag = nullptr;
+      return Copy;
+    }
+  };
+
+  /// getLocation - Fill in Loc with information about the memory reference by
+  /// the given instruction.
+  Location getLocation(const LoadInst *LI);
+  Location getLocation(const StoreInst *SI);
+  Location getLocation(const VAArgInst *VI);
+  Location getLocation(const AtomicCmpXchgInst *CXI);
+  Location getLocation(const AtomicRMWInst *RMWI);
+  static Location getLocationForSource(const MemTransferInst *MTI);
+  static Location getLocationForDest(const MemIntrinsic *MI);
+
+  /// Alias analysis result - Either we know for sure that it does not alias, we
+  /// know for sure it must alias, or we don't know anything: The two pointers
+  /// _might_ alias.  This enum is designed so you can do things like:
+  ///     if (AA.alias(P1, P2)) { ... }
+  /// to check to see if two pointers might alias.
+  ///
+  /// See docs/AliasAnalysis.html for more information on the specific meanings
+  /// of these values.
+  ///
+  enum AliasResult {
+    NoAlias = 0,        ///< No dependencies.
+    MayAlias,           ///< Anything goes.
+    PartialAlias,       ///< Pointers differ, but pointees overlap.
+    MustAlias           ///< Pointers are equal.
+  };
+
+  /// alias - The main low level interface to the alias analysis implementation.
+  /// Returns an AliasResult indicating whether the two pointers are aliased to
+  /// each other.  This is the interface that must be implemented by specific
+  /// alias analysis implementations.
+  virtual AliasResult alias(const Location &LocA, const Location &LocB);
+
+  /// alias - A convenience wrapper.
+  AliasResult alias(const Value *V1, uint64_t V1Size,
+                    const Value *V2, uint64_t V2Size) {
+    return alias(Location(V1, V1Size), Location(V2, V2Size));
+  }
+
+  /// alias - A convenience wrapper.
+  AliasResult alias(const Value *V1, const Value *V2) {
+    return alias(V1, UnknownSize, V2, UnknownSize);
+  }
+
+  /// isNoAlias - A trivial helper function to check to see if the specified
+  /// pointers are no-alias.
+  bool isNoAlias(const Location &LocA, const Location &LocB) {
+    return alias(LocA, LocB) == NoAlias;
+  }
+
+  /// isNoAlias - A convenience wrapper.
+  bool isNoAlias(const Value *V1, uint64_t V1Size,
+                 const Value *V2, uint64_t V2Size) {
+    return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
+  }
+  
+  /// isNoAlias - A convenience wrapper.
+  bool isNoAlias(const Value *V1, const Value *V2) {
+    return isNoAlias(Location(V1), Location(V2));
+  }
+  
+  /// isMustAlias - A convenience wrapper.
+  bool isMustAlias(const Location &LocA, const Location &LocB) {
+    return alias(LocA, LocB) == MustAlias;
+  }
+
+  /// isMustAlias - A convenience wrapper.
+  bool isMustAlias(const Value *V1, const Value *V2) {
+    return alias(V1, 1, V2, 1) == MustAlias;
+  }
+  
+  /// pointsToConstantMemory - If the specified memory location is
+  /// known to be constant, return true. If OrLocal is true and the
+  /// specified memory location is known to be "local" (derived from
+  /// an alloca), return true. Otherwise return false.
+  virtual bool pointsToConstantMemory(const Location &Loc,
+                                      bool OrLocal = false);
+
+  /// pointsToConstantMemory - A convenient wrapper.
+  bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
+    return pointsToConstantMemory(Location(P), OrLocal);
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// Simple mod/ref information...
+  ///
+
+  /// ModRefResult - Represent the result of a mod/ref query.  Mod and Ref are
+  /// bits which may be or'd together.
+  ///
+  enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
+
+  /// These values define additional bits used to define the
+  /// ModRefBehavior values.
+  enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees };
+
+  /// ModRefBehavior - Summary of how a function affects memory in the program.
+  /// Loads from constant globals are not considered memory accesses for this
+  /// interface.  Also, functions may freely modify stack space local to their
+  /// invocation without having to report it through these interfaces.
+  enum ModRefBehavior {
+    /// DoesNotAccessMemory - This function does not perform any non-local loads
+    /// or stores to memory.
+    ///
+    /// This property corresponds to the GCC 'const' attribute.
+    /// This property corresponds to the LLVM IR 'readnone' attribute.
+    /// This property corresponds to the IntrNoMem LLVM intrinsic flag.
+    DoesNotAccessMemory = Nowhere | NoModRef,
+
+    /// OnlyReadsArgumentPointees - The only memory references in this function
+    /// (if it has any) are non-volatile loads from objects pointed to by its
+    /// pointer-typed arguments, with arbitrary offsets.
+    ///
+    /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
+    OnlyReadsArgumentPointees = ArgumentPointees | Ref,
+
+    /// OnlyAccessesArgumentPointees - The only memory references in this
+    /// function (if it has any) are non-volatile loads and stores from objects
+    /// pointed to by its pointer-typed arguments, with arbitrary offsets.
+    ///
+    /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
+    OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
+
+    /// OnlyReadsMemory - This function does not perform any non-local stores or
+    /// volatile loads, but may read from any memory location.
+    ///
+    /// This property corresponds to the GCC 'pure' attribute.
+    /// This property corresponds to the LLVM IR 'readonly' attribute.
+    /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
+    OnlyReadsMemory = Anywhere | Ref,
+
+    /// UnknownModRefBehavior - This indicates that the function could not be
+    /// classified into one of the behaviors above.
+    UnknownModRefBehavior = Anywhere | ModRef
+  };
+
+  /// Get the location associated with a pointer argument of a callsite.
+  /// The mask bits are set to indicate the allowed aliasing ModRef kinds.
+  /// Note that these mask bits do not necessarily account for the overall
+  /// behavior of the function, but rather only provide additional
+  /// per-argument information.
+  virtual Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
+                                  ModRefResult &Mask);
+
+  /// getModRefBehavior - Return the behavior when calling the given call site.
+  virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
+
+  /// getModRefBehavior - Return the behavior when calling the given function.
+  /// For use when the call site is not known.
+  virtual ModRefBehavior getModRefBehavior(const Function *F);
+
+  /// doesNotAccessMemory - If the specified call is known to never read or
+  /// write memory, return true.  If the call only reads from known-constant
+  /// memory, it is also legal to return true.  Calls that unwind the stack
+  /// are legal for this predicate.
+  ///
+  /// Many optimizations (such as CSE and LICM) can be performed on such calls
+  /// without worrying about aliasing properties, and many calls have this
+  /// property (e.g. calls to 'sin' and 'cos').
+  ///
+  /// This property corresponds to the GCC 'const' attribute.
+  ///
+  bool doesNotAccessMemory(ImmutableCallSite CS) {
+    return getModRefBehavior(CS) == DoesNotAccessMemory;
+  }
+
+  /// doesNotAccessMemory - If the specified function is known to never read or
+  /// write memory, return true.  For use when the call site is not known.
+  ///
+  bool doesNotAccessMemory(const Function *F) {
+    return getModRefBehavior(F) == DoesNotAccessMemory;
+  }
+
+  /// onlyReadsMemory - If the specified call is known to only read from
+  /// non-volatile memory (or not access memory at all), return true.  Calls
+  /// that unwind the stack are legal for this predicate.
+  ///
+  /// This property allows many common optimizations to be performed in the
+  /// absence of interfering store instructions, such as CSE of strlen calls.
+  ///
+  /// This property corresponds to the GCC 'pure' attribute.
+  ///
+  bool onlyReadsMemory(ImmutableCallSite CS) {
+    return onlyReadsMemory(getModRefBehavior(CS));
+  }
+
+  /// onlyReadsMemory - If the specified function is known to only read from
+  /// non-volatile memory (or not access memory at all), return true.  For use
+  /// when the call site is not known.
+  ///
+  bool onlyReadsMemory(const Function *F) {
+    return onlyReadsMemory(getModRefBehavior(F));
+  }
+
+  /// onlyReadsMemory - Return true if functions with the specified behavior are
+  /// known to only read from non-volatile memory (or not access memory at all).
+  ///
+  static bool onlyReadsMemory(ModRefBehavior MRB) {
+    return !(MRB & Mod);
+  }
+
+  /// onlyAccessesArgPointees - Return true if functions with the specified
+  /// behavior are known to read and write at most from objects pointed to by
+  /// their pointer-typed arguments (with arbitrary offsets).
+  ///
+  static bool onlyAccessesArgPointees(ModRefBehavior MRB) {
+    return !(MRB & Anywhere & ~ArgumentPointees);
+  }
+
+  /// doesAccessArgPointees - Return true if functions with the specified
+  /// behavior are known to potentially read or write from objects pointed
+  /// to be their pointer-typed arguments (with arbitrary offsets).
+  ///
+  static bool doesAccessArgPointees(ModRefBehavior MRB) {
+    return (MRB & ModRef) && (MRB & ArgumentPointees);
+  }
+
+  /// getModRefInfo - Return information about whether or not an instruction may
+  /// read or write the specified memory location.  An instruction
+  /// that doesn't read or write memory may be trivially LICM'd for example.
+  ModRefResult getModRefInfo(const Instruction *I,
+                             const Location &Loc) {
+    switch (I->getOpcode()) {
+    case Instruction::VAArg:  return getModRefInfo((const VAArgInst*)I, Loc);
+    case Instruction::Load:   return getModRefInfo((const LoadInst*)I,  Loc);
+    case Instruction::Store:  return getModRefInfo((const StoreInst*)I, Loc);
+    case Instruction::Fence:  return getModRefInfo((const FenceInst*)I, Loc);
+    case Instruction::AtomicCmpXchg:
+      return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
+    case Instruction::AtomicRMW:
+      return getModRefInfo((const AtomicRMWInst*)I, Loc);
+    case Instruction::Call:   return getModRefInfo((const CallInst*)I,  Loc);
+    case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
+    default:                  return NoModRef;
+    }
+  }
+
+  /// getModRefInfo - A convenience wrapper.
+  ModRefResult getModRefInfo(const Instruction *I,
+                             const Value *P, uint64_t Size) {
+    return getModRefInfo(I, Location(P, Size));
+  }
+
+  /// getModRefInfo (for call sites) - Return information about whether
+  /// a particular call site modifies or reads the specified memory location.
+  virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
+                                     const Location &Loc);
+
+  /// getModRefInfo (for call sites) - A convenience wrapper.
+  ModRefResult getModRefInfo(ImmutableCallSite CS,
+                             const Value *P, uint64_t Size) {
+    return getModRefInfo(CS, Location(P, Size));
+  }
+
+  /// getModRefInfo (for calls) - Return information about whether
+  /// a particular call modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
+    return getModRefInfo(ImmutableCallSite(C), Loc);
+  }
+
+  /// getModRefInfo (for calls) - A convenience wrapper.
+  ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
+    return getModRefInfo(C, Location(P, Size));
+  }
+
+  /// getModRefInfo (for invokes) - Return information about whether
+  /// a particular invoke modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const InvokeInst *I,
+                             const Location &Loc) {
+    return getModRefInfo(ImmutableCallSite(I), Loc);
+  }
+
+  /// getModRefInfo (for invokes) - A convenience wrapper.
+  ModRefResult getModRefInfo(const InvokeInst *I,
+                             const Value *P, uint64_t Size) {
+    return getModRefInfo(I, Location(P, Size));
+  }
+
+  /// getModRefInfo (for loads) - Return information about whether
+  /// a particular load modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
+
+  /// getModRefInfo (for loads) - A convenience wrapper.
+  ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
+    return getModRefInfo(L, Location(P, Size));
+  }
+
+  /// getModRefInfo (for stores) - Return information about whether
+  /// a particular store modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
+
+  /// getModRefInfo (for stores) - A convenience wrapper.
+  ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
+    return getModRefInfo(S, Location(P, Size));
+  }
+
+  /// getModRefInfo (for fences) - Return information about whether
+  /// a particular store modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
+    // Conservatively correct.  (We could possibly be a bit smarter if
+    // Loc is a alloca that doesn't escape.)
+    return ModRef;
+  }
+
+  /// getModRefInfo (for fences) - A convenience wrapper.
+  ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
+    return getModRefInfo(S, Location(P, Size));
+  }
+
+  /// getModRefInfo (for cmpxchges) - Return information about whether
+  /// a particular cmpxchg modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
+
+  /// getModRefInfo (for cmpxchges) - A convenience wrapper.
+  ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
+                             const Value *P, unsigned Size) {
+    return getModRefInfo(CX, Location(P, Size));
+  }
+
+  /// getModRefInfo (for atomicrmws) - Return information about whether
+  /// a particular atomicrmw modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
+
+  /// getModRefInfo (for atomicrmws) - A convenience wrapper.
+  ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
+                             const Value *P, unsigned Size) {
+    return getModRefInfo(RMW, Location(P, Size));
+  }
+
+  /// getModRefInfo (for va_args) - Return information about whether
+  /// a particular va_arg modifies or reads the specified memory location.
+  ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
+
+  /// getModRefInfo (for va_args) - A convenience wrapper.
+  ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
+    return getModRefInfo(I, Location(P, Size));
+  }
+
+  /// getModRefInfo - Return information about whether two call sites may refer
+  /// to the same set of memory locations.  See 
+  ///   http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
+  /// for details.
+  virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
+                                     ImmutableCallSite CS2);
+
+  /// callCapturesBefore - Return information about whether a particular call 
+  /// site modifies or reads the specified memory location.
+  ModRefResult callCapturesBefore(const Instruction *I,
+                                  const AliasAnalysis::Location &MemLoc,
+                                  DominatorTree *DT);
+
+  /// callCapturesBefore - A convenience wrapper.
+  ModRefResult callCapturesBefore(const Instruction *I, const Value *P,
+                                  uint64_t Size, DominatorTree *DT) {
+    return callCapturesBefore(I, Location(P, Size), DT);
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// Higher level methods for querying mod/ref information.
+  ///
+
+  /// canBasicBlockModify - Return true if it is possible for execution of the
+  /// specified basic block to modify the value pointed to by Ptr.
+  bool canBasicBlockModify(const BasicBlock &BB, const Location &Loc);
+
+  /// canBasicBlockModify - A convenience wrapper.
+  bool canBasicBlockModify(const BasicBlock &BB, const Value *P, uint64_t Size){
+    return canBasicBlockModify(BB, Location(P, Size));
+  }
+
+  /// canInstructionRangeModify - Return true if it is possible for the
+  /// execution of the specified instructions to modify the value pointed to by
+  /// Ptr.  The instructions to consider are all of the instructions in the
+  /// range of [I1,I2] INCLUSIVE.  I1 and I2 must be in the same basic block.
+  bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
+                                 const Location &Loc);
+
+  /// canInstructionRangeModify - A convenience wrapper.
+  bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
+                                 const Value *Ptr, uint64_t Size) {
+    return canInstructionRangeModify(I1, I2, Location(Ptr, Size));
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// Methods that clients should call when they transform the program to allow
+  /// alias analyses to update their internal data structures.  Note that these
+  /// methods may be called on any instruction, regardless of whether or not
+  /// they have pointer-analysis implications.
+  ///
+
+  /// deleteValue - This method should be called whenever an LLVM Value is
+  /// deleted from the program, for example when an instruction is found to be
+  /// redundant and is eliminated.
+  ///
+  virtual void deleteValue(Value *V);
+
+  /// copyValue - This method should be used whenever a preexisting value in the
+  /// program is copied or cloned, introducing a new value.  Note that analysis
+  /// implementations should tolerate clients that use this method to introduce
+  /// the same value multiple times: if the analysis already knows about a
+  /// value, it should ignore the request.
+  ///
+  virtual void copyValue(Value *From, Value *To);
+
+  /// addEscapingUse - This method should be used whenever an escaping use is
+  /// added to a pointer value.  Analysis implementations may either return
+  /// conservative responses for that value in the future, or may recompute
+  /// some or all internal state to continue providing precise responses.
+  ///
+  /// Escaping uses are considered by anything _except_ the following:
+  ///  - GEPs or bitcasts of the pointer
+  ///  - Loads through the pointer
+  ///  - Stores through (but not of) the pointer
+  virtual void addEscapingUse(Use &U);
+
+  /// replaceWithNewValue - This method is the obvious combination of the two
+  /// above, and it provided as a helper to simplify client code.
+  ///
+  void replaceWithNewValue(Value *Old, Value *New) {
+    copyValue(Old, New);
+    deleteValue(Old);
+  }
+};
+
+// Specialize DenseMapInfo for Location.
+template<>
+struct DenseMapInfo<AliasAnalysis::Location> {
+  static inline AliasAnalysis::Location getEmptyKey() {
+    return
+      AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
+                              0, nullptr);
+  }
+  static inline AliasAnalysis::Location getTombstoneKey() {
+    return
+      AliasAnalysis::Location(DenseMapInfo<const Value *>::getTombstoneKey(),
+                              0, nullptr);
+  }
+  static unsigned getHashValue(const AliasAnalysis::Location &Val) {
+    return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
+           DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
+           DenseMapInfo<const MDNode *>::getHashValue(Val.TBAATag);
+  }
+  static bool isEqual(const AliasAnalysis::Location &LHS,
+                      const AliasAnalysis::Location &RHS) {
+    return LHS.Ptr == RHS.Ptr &&
+           LHS.Size == RHS.Size &&
+           LHS.TBAATag == RHS.TBAATag;
+  }
+};
+
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+bool isNoAliasCall(const Value *V);
+
+/// isNoAliasArgument - Return true if this is an argument with the noalias
+/// attribute.
+bool isNoAliasArgument(const Value *V);
+
+/// isIdentifiedObject - Return true if this pointer refers to a distinct and
+/// identifiable object.  This returns true for:
+///    Global Variables and Functions (but not Global Aliases)
+///    Allocas
+///    ByVal and NoAlias Arguments
+///    NoAlias returns (e.g. calls to malloc)
+///
+bool isIdentifiedObject(const Value *V);
+
+/// isIdentifiedFunctionLocal - Return true if V is umabigously identified
+/// at the function-level. Different IdentifiedFunctionLocals can't alias.
+/// Further, an IdentifiedFunctionLocal can not alias with any function
+/// arguments other than itself, which is not necessarily true for
+/// IdentifiedObjects.
+bool isIdentifiedFunctionLocal(const Value *V);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
new file mode 100644
index 0000000..e32b6d6
--- /dev/null
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -0,0 +1,441 @@
+//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- 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 two classes: AliasSetTracker and AliasSet.  These interface
+// are used to classify a collection of pointer references into a maximal number
+// of disjoint sets.  Each AliasSet object constructed by the AliasSetTracker
+// object refers to memory disjoint from the other sets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
+#define LLVM_ANALYSIS_ALIASSETTRACKER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/ValueHandle.h"
+#include <vector>
+
+namespace llvm {
+
+class AliasAnalysis;
+class LoadInst;
+class StoreInst;
+class VAArgInst;
+class AliasSetTracker;
+class AliasSet;
+
+class AliasSet : public ilist_node<AliasSet> {
+  friend class AliasSetTracker;
+
+  class PointerRec {
+    Value *Val;  // The pointer this record corresponds to.
+    PointerRec **PrevInList, *NextInList;
+    AliasSet *AS;
+    uint64_t Size;
+    const MDNode *TBAAInfo;
+  public:
+    PointerRec(Value *V)
+      : Val(V), PrevInList(nullptr), NextInList(nullptr), AS(nullptr), Size(0),
+        TBAAInfo(DenseMapInfo<const MDNode *>::getEmptyKey()) {}
+
+    Value *getValue() const { return Val; }
+    
+    PointerRec *getNext() const { return NextInList; }
+    bool hasAliasSet() const { return AS != nullptr; }
+
+    PointerRec** setPrevInList(PointerRec **PIL) {
+      PrevInList = PIL;
+      return &NextInList;
+    }
+
+    void updateSizeAndTBAAInfo(uint64_t NewSize, const MDNode *NewTBAAInfo) {
+      if (NewSize > Size) Size = NewSize;
+
+      if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey())
+        // We don't have a TBAAInfo yet. Set it to NewTBAAInfo.
+        TBAAInfo = NewTBAAInfo;
+      else if (TBAAInfo != NewTBAAInfo)
+        // NewTBAAInfo conflicts with TBAAInfo.
+        TBAAInfo = DenseMapInfo<const MDNode *>::getTombstoneKey();
+    }
+
+    uint64_t getSize() const { return Size; }
+
+    /// getTBAAInfo - Return the TBAAInfo, or null if there is no
+    /// information or conflicting information.
+    const MDNode *getTBAAInfo() const {
+      // If we have missing or conflicting TBAAInfo, return null.
+      if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey() ||
+          TBAAInfo == DenseMapInfo<const MDNode *>::getTombstoneKey())
+        return nullptr;
+      return TBAAInfo;
+    }
+
+    AliasSet *getAliasSet(AliasSetTracker &AST) {
+      assert(AS && "No AliasSet yet!");
+      if (AS->Forward) {
+        AliasSet *OldAS = AS;
+        AS = OldAS->getForwardedTarget(AST);
+        AS->addRef();
+        OldAS->dropRef(AST);
+      }
+      return AS;
+    }
+
+    void setAliasSet(AliasSet *as) {
+      assert(!AS && "Already have an alias set!");
+      AS = as;
+    }
+
+    void eraseFromList() {
+      if (NextInList) NextInList->PrevInList = PrevInList;
+      *PrevInList = NextInList;
+      if (AS->PtrListEnd == &NextInList) {
+        AS->PtrListEnd = PrevInList;
+        assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
+      }
+      delete this;
+    }
+  };
+
+  PointerRec *PtrList, **PtrListEnd;  // Doubly linked list of nodes.
+  AliasSet *Forward;             // Forwarding pointer.
+
+  // All instructions without a specific address in this alias set.
+  std::vector<AssertingVH<Instruction> > UnknownInsts;
+
+  // RefCount - Number of nodes pointing to this AliasSet plus the number of
+  // AliasSets forwarding to it.
+  unsigned RefCount : 28;
+
+  /// AccessType - Keep track of whether this alias set merely refers to the
+  /// locations of memory, whether it modifies the memory, or whether it does
+  /// both.  The lattice goes from "NoModRef" to either Refs or Mods, then to
+  /// ModRef as necessary.
+  ///
+  enum AccessType {
+    NoModRef = 0, Refs = 1,         // Ref = bit 1
+    Mods     = 2, ModRef = 3        // Mod = bit 2
+  };
+  unsigned AccessTy : 2;
+
+  /// AliasType - Keep track the relationships between the pointers in the set.
+  /// Lattice goes from MustAlias to MayAlias.
+  ///
+  enum AliasType {
+    MustAlias = 0, MayAlias = 1
+  };
+  unsigned AliasTy : 1;
+
+  // Volatile - True if this alias set contains volatile loads or stores.
+  bool Volatile : 1;
+
+  void addRef() { ++RefCount; }
+  void dropRef(AliasSetTracker &AST) {
+    assert(RefCount >= 1 && "Invalid reference count detected!");
+    if (--RefCount == 0)
+      removeFromTracker(AST);
+  }
+
+  Instruction *getUnknownInst(unsigned i) const {
+    assert(i < UnknownInsts.size());
+    return UnknownInsts[i];
+  }
+  
+public:
+  /// Accessors...
+  bool isRef() const { return AccessTy & Refs; }
+  bool isMod() const { return AccessTy & Mods; }
+  bool isMustAlias() const { return AliasTy == MustAlias; }
+  bool isMayAlias()  const { return AliasTy == MayAlias; }
+
+  // isVolatile - Return true if this alias set contains volatile loads or
+  // stores.
+  bool isVolatile() const { return Volatile; }
+
+  /// isForwardingAliasSet - Return true if this alias set should be ignored as
+  /// part of the AliasSetTracker object.
+  bool isForwardingAliasSet() const { return Forward; }
+
+  /// mergeSetIn - Merge the specified alias set into this alias set...
+  ///
+  void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
+
+  // Alias Set iteration - Allow access to all of the pointer which are part of
+  // this alias set...
+  class iterator;
+  iterator begin() const { return iterator(PtrList); }
+  iterator end()   const { return iterator(); }
+  bool empty() const { return PtrList == nullptr; }
+
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+  /// Define an iterator for alias sets... this is just a forward iterator.
+  class iterator : public std::iterator<std::forward_iterator_tag,
+                                        PointerRec, ptrdiff_t> {
+    PointerRec *CurNode;
+  public:
+    explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
+
+    bool operator==(const iterator& x) const {
+      return CurNode == x.CurNode;
+    }
+    bool operator!=(const iterator& x) const { return !operator==(x); }
+
+    const iterator &operator=(const iterator &I) {
+      CurNode = I.CurNode;
+      return *this;
+    }
+
+    value_type &operator*() const {
+      assert(CurNode && "Dereferencing AliasSet.end()!");
+      return *CurNode;
+    }
+    value_type *operator->() const { return &operator*(); }
+
+    Value *getPointer() const { return CurNode->getValue(); }
+    uint64_t getSize() const { return CurNode->getSize(); }
+    const MDNode *getTBAAInfo() const { return CurNode->getTBAAInfo(); }
+
+    iterator& operator++() {                // Preincrement
+      assert(CurNode && "Advancing past AliasSet.end()!");
+      CurNode = CurNode->getNext();
+      return *this;
+    }
+    iterator operator++(int) { // Postincrement
+      iterator tmp = *this; ++*this; return tmp;
+    }
+  };
+
+private:
+  // Can only be created by AliasSetTracker. Also, ilist creates one
+  // to serve as a sentinel.
+  friend struct ilist_sentinel_traits<AliasSet>;
+  AliasSet()
+    : PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr), RefCount(0),
+      AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
+  }
+
+  AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
+  void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
+
+  PointerRec *getSomePointer() const {
+    return PtrList;
+  }
+
+  /// getForwardedTarget - Return the real alias set this represents.  If this
+  /// has been merged with another set and is forwarding, return the ultimate
+  /// destination set.  This also implements the union-find collapsing as well.
+  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
+    if (!Forward) return this;
+
+    AliasSet *Dest = Forward->getForwardedTarget(AST);
+    if (Dest != Forward) {
+      Dest->addRef();
+      Forward->dropRef(AST);
+      Forward = Dest;
+    }
+    return Dest;
+  }
+
+  void removeFromTracker(AliasSetTracker &AST);
+
+  void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
+                  const MDNode *TBAAInfo,
+                  bool KnownMustAlias = false);
+  void addUnknownInst(Instruction *I, AliasAnalysis &AA);
+  void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
+    bool WasEmpty = UnknownInsts.empty();
+    for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
+      if (UnknownInsts[i] == I) {
+        UnknownInsts[i] = UnknownInsts.back();
+        UnknownInsts.pop_back();
+        --i; --e;  // Revisit the moved entry.
+      }
+    if (!WasEmpty && UnknownInsts.empty())
+      dropRef(AST);
+  }
+  void setVolatile() { Volatile = true; }
+
+public:
+  /// aliasesPointer - Return true if the specified pointer "may" (or must)
+  /// alias one of the members in the set.
+  ///
+  bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
+                      AliasAnalysis &AA) const;
+  bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
+  AS.print(OS);
+  return OS;
+}
+
+
+class AliasSetTracker {
+  /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
+  /// notified whenever a Value is deleted.
+  class ASTCallbackVH : public CallbackVH {
+    AliasSetTracker *AST;
+    void deleted() override;
+    void allUsesReplacedWith(Value *) override;
+  public:
+    ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr);
+    ASTCallbackVH &operator=(Value *V);
+  };
+  /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
+  /// compare and hash the value handle.
+  struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
+
+  AliasAnalysis &AA;
+  ilist<AliasSet> AliasSets;
+
+  typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
+                   ASTCallbackVHDenseMapInfo>
+    PointerMapType;
+
+  // Map from pointers to their node
+  PointerMapType PointerMap;
+
+public:
+  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
+  /// the specified alias analysis object to disambiguate load and store
+  /// addresses.
+  explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
+  ~AliasSetTracker() { clear(); }
+
+  /// add methods - These methods are used to add different types of
+  /// instructions to the alias sets.  Adding a new instruction can result in
+  /// one of three actions happening:
+  ///
+  ///   1. If the instruction doesn't alias any other sets, create a new set.
+  ///   2. If the instruction aliases exactly one set, add it to the set
+  ///   3. If the instruction aliases multiple sets, merge the sets, and add
+  ///      the instruction to the result.
+  ///
+  /// These methods return true if inserting the instruction resulted in the
+  /// addition of a new alias set (i.e., the pointer did not alias anything).
+  ///
+  bool add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); // Add a location
+  bool add(LoadInst *LI);
+  bool add(StoreInst *SI);
+  bool add(VAArgInst *VAAI);
+  bool add(Instruction *I);       // Dispatch to one of the other add methods...
+  void add(BasicBlock &BB);       // Add all instructions in basic block
+  void add(const AliasSetTracker &AST); // Add alias relations from another AST
+  bool addUnknown(Instruction *I);
+
+  /// remove methods - These methods are used to remove all entries that might
+  /// be aliased by the specified instruction.  These methods return true if any
+  /// alias sets were eliminated.
+  // Remove a location
+  bool remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo);
+  bool remove(LoadInst *LI);
+  bool remove(StoreInst *SI);
+  bool remove(VAArgInst *VAAI);
+  bool remove(Instruction *I);
+  void remove(AliasSet &AS);
+  bool removeUnknown(Instruction *I);
+  
+  void clear();
+
+  /// getAliasSets - Return the alias sets that are active.
+  ///
+  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
+
+  /// getAliasSetForPointer - Return the alias set that the specified pointer
+  /// lives in.  If the New argument is non-null, this method sets the value to
+  /// true if a new alias set is created to contain the pointer (because the
+  /// pointer didn't alias anything).
+  AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
+                                  const MDNode *TBAAInfo,
+                                  bool *New = nullptr);
+
+  /// getAliasSetForPointerIfExists - Return the alias set containing the
+  /// location specified if one exists, otherwise return null.
+  AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
+                                          const MDNode *TBAAInfo) {
+    return findAliasSetForPointer(P, Size, TBAAInfo);
+  }
+
+  /// containsPointer - Return true if the specified location is represented by
+  /// this alias set, false otherwise.  This does not modify the AST object or
+  /// alias sets.
+  bool containsPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo) const;
+
+  /// getAliasAnalysis - Return the underlying alias analysis object used by
+  /// this tracker.
+  AliasAnalysis &getAliasAnalysis() const { return AA; }
+
+  /// deleteValue method - This method is used to remove a pointer value from
+  /// the AliasSetTracker entirely.  It should be used when an instruction is
+  /// deleted from the program to update the AST.  If you don't use this, you
+  /// would have dangling pointers to deleted instructions.
+  ///
+  void deleteValue(Value *PtrVal);
+
+  /// copyValue - This method should be used whenever a preexisting value in the
+  /// program is copied or cloned, introducing a new value.  Note that it is ok
+  /// for clients that use this method to introduce the same value multiple
+  /// times: if the tracker already knows about a value, it will ignore the
+  /// request.
+  ///
+  void copyValue(Value *From, Value *To);
+
+
+  typedef ilist<AliasSet>::iterator iterator;
+  typedef ilist<AliasSet>::const_iterator const_iterator;
+
+  const_iterator begin() const { return AliasSets.begin(); }
+  const_iterator end()   const { return AliasSets.end(); }
+
+  iterator begin() { return AliasSets.begin(); }
+  iterator end()   { return AliasSets.end(); }
+
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+private:
+  friend class AliasSet;
+  void removeAliasSet(AliasSet *AS);
+
+  // getEntryFor - Just like operator[] on the map, except that it creates an
+  // entry for the pointer if it doesn't already exist.
+  AliasSet::PointerRec &getEntryFor(Value *V) {
+    AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
+    if (!Entry)
+      Entry = new AliasSet::PointerRec(V);
+    return *Entry;
+  }
+
+  AliasSet &addPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo,
+                       AliasSet::AccessType E,
+                       bool &NewSet) {
+    NewSet = false;
+    AliasSet &AS = getAliasSetForPointer(P, Size, TBAAInfo, &NewSet);
+    AS.AccessTy |= E;
+    return AS;
+  }
+  AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
+                                   const MDNode *TBAAInfo);
+
+  AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
+  AST.print(OS);
+  return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h
new file mode 100644
index 0000000..3289a28
--- /dev/null
+++ b/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -0,0 +1,68 @@
+//===- BlockFrequencyInfo.h - Block Frequency Analysis ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Loops should be simplified before this analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
+#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/BlockFrequency.h"
+#include <climits>
+
+namespace llvm {
+
+class BranchProbabilityInfo;
+template <class BlockT> class BlockFrequencyInfoImpl;
+
+/// BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to
+/// estimate IR basic block frequencies.
+class BlockFrequencyInfo : public FunctionPass {
+  typedef BlockFrequencyInfoImpl<BasicBlock> ImplType;
+  std::unique_ptr<ImplType> BFI;
+
+public:
+  static char ID;
+
+  BlockFrequencyInfo();
+
+  ~BlockFrequencyInfo();
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  bool runOnFunction(Function &F) override;
+  void releaseMemory() override;
+  void print(raw_ostream &O, const Module *M) const override;
+  const Function *getFunction() const;
+  void view() const;
+
+  /// getblockFreq - Return block frequency. Return 0 if we don't have the
+  /// information. Please note that initial frequency is equal to ENTRY_FREQ. It
+  /// means that we should not rely on the value itself, but only on the
+  /// comparison to the other block frequencies. We do this to avoid using of
+  /// floating points.
+  BlockFrequency getBlockFreq(const BasicBlock *BB) const;
+
+  // Print the block frequency Freq to OS using the current functions entry
+  // frequency to convert freq into a relative decimal form.
+  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;
+
+  // Convenience method that attempts to look up the frequency associated with
+  // BB and print it to OS.
+  raw_ostream &printBlockFreq(raw_ostream &OS, const BasicBlock *BB) const;
+
+  uint64_t getEntryFreq() const;
+
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
new file mode 100644
index 0000000..bb256c7
--- /dev/null
+++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -0,0 +1,1181 @@
+//==- BlockFrequencyInfoImpl.h - Block Frequency Implementation -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared implementation of BlockFrequency for IR and Machine Instructions.
+// See the documentation below for BlockFrequencyInfoImpl for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
+#define LLVM_ANALYSIS_BLOCKFREQUENCYINFOIMPL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ScaledNumber.h"
+#include "llvm/Support/raw_ostream.h"
+#include <deque>
+#include <list>
+#include <string>
+#include <vector>
+
+#define DEBUG_TYPE "block-freq"
+
+namespace llvm {
+
+class BasicBlock;
+class BranchProbabilityInfo;
+class Function;
+class Loop;
+class LoopInfo;
+class MachineBasicBlock;
+class MachineBranchProbabilityInfo;
+class MachineFunction;
+class MachineLoop;
+class MachineLoopInfo;
+
+namespace bfi_detail {
+
+struct IrreducibleGraph;
+
+// This is part of a workaround for a GCC 4.7 crash on lambdas.
+template <class BT> struct BlockEdgesAdder;
+
+/// \brief Mass of a block.
+///
+/// This class implements a sort of fixed-point fraction always between 0.0 and
+/// 1.0.  getMass() == UINT64_MAX indicates a value of 1.0.
+///
+/// Masses can be added and subtracted.  Simple saturation arithmetic is used,
+/// so arithmetic operations never overflow or underflow.
+///
+/// Masses can be multiplied.  Multiplication treats full mass as 1.0 and uses
+/// an inexpensive floating-point algorithm that's off-by-one (almost, but not
+/// quite, maximum precision).
+///
+/// Masses can be scaled by \a BranchProbability at maximum precision.
+class BlockMass {
+  uint64_t Mass;
+
+public:
+  BlockMass() : Mass(0) {}
+  explicit BlockMass(uint64_t Mass) : Mass(Mass) {}
+
+  static BlockMass getEmpty() { return BlockMass(); }
+  static BlockMass getFull() { return BlockMass(UINT64_MAX); }
+
+  uint64_t getMass() const { return Mass; }
+
+  bool isFull() const { return Mass == UINT64_MAX; }
+  bool isEmpty() const { return !Mass; }
+
+  bool operator!() const { return isEmpty(); }
+
+  /// \brief Add another mass.
+  ///
+  /// Adds another mass, saturating at \a isFull() rather than overflowing.
+  BlockMass &operator+=(const BlockMass &X) {
+    uint64_t Sum = Mass + X.Mass;
+    Mass = Sum < Mass ? UINT64_MAX : Sum;
+    return *this;
+  }
+
+  /// \brief Subtract another mass.
+  ///
+  /// Subtracts another mass, saturating at \a isEmpty() rather than
+  /// undeflowing.
+  BlockMass &operator-=(const BlockMass &X) {
+    uint64_t Diff = Mass - X.Mass;
+    Mass = Diff > Mass ? 0 : Diff;
+    return *this;
+  }
+
+  BlockMass &operator*=(const BranchProbability &P) {
+    Mass = P.scale(Mass);
+    return *this;
+  }
+
+  bool operator==(const BlockMass &X) const { return Mass == X.Mass; }
+  bool operator!=(const BlockMass &X) const { return Mass != X.Mass; }
+  bool operator<=(const BlockMass &X) const { return Mass <= X.Mass; }
+  bool operator>=(const BlockMass &X) const { return Mass >= X.Mass; }
+  bool operator<(const BlockMass &X) const { return Mass < X.Mass; }
+  bool operator>(const BlockMass &X) const { return Mass > X.Mass; }
+
+  /// \brief Convert to scaled number.
+  ///
+  /// Convert to \a ScaledNumber.  \a isFull() gives 1.0, while \a isEmpty()
+  /// gives slightly above 0.0.
+  ScaledNumber<uint64_t> toScaled() const;
+
+  void dump() const;
+  raw_ostream &print(raw_ostream &OS) const;
+};
+
+inline BlockMass operator+(const BlockMass &L, const BlockMass &R) {
+  return BlockMass(L) += R;
+}
+inline BlockMass operator-(const BlockMass &L, const BlockMass &R) {
+  return BlockMass(L) -= R;
+}
+inline BlockMass operator*(const BlockMass &L, const BranchProbability &R) {
+  return BlockMass(L) *= R;
+}
+inline BlockMass operator*(const BranchProbability &L, const BlockMass &R) {
+  return BlockMass(R) *= L;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const BlockMass &X) {
+  return X.print(OS);
+}
+
+} // end namespace bfi_detail
+
+template <> struct isPodLike<bfi_detail::BlockMass> {
+  static const bool value = true;
+};
+
+/// \brief Base class for BlockFrequencyInfoImpl
+///
+/// BlockFrequencyInfoImplBase has supporting data structures and some
+/// algorithms for BlockFrequencyInfoImplBase.  Only algorithms that depend on
+/// the block type (or that call such algorithms) are skipped here.
+///
+/// Nevertheless, the majority of the overall algorithm documention lives with
+/// BlockFrequencyInfoImpl.  See there for details.
+class BlockFrequencyInfoImplBase {
+public:
+  typedef ScaledNumber<uint64_t> Scaled64;
+  typedef bfi_detail::BlockMass BlockMass;
+
+  /// \brief Representative of a block.
+  ///
+  /// This is a simple wrapper around an index into the reverse-post-order
+  /// traversal of the blocks.
+  ///
+  /// Unlike a block pointer, its order has meaning (location in the
+  /// topological sort) and it's class is the same regardless of block type.
+  struct BlockNode {
+    typedef uint32_t IndexType;
+    IndexType Index;
+
+    bool operator==(const BlockNode &X) const { return Index == X.Index; }
+    bool operator!=(const BlockNode &X) const { return Index != X.Index; }
+    bool operator<=(const BlockNode &X) const { return Index <= X.Index; }
+    bool operator>=(const BlockNode &X) const { return Index >= X.Index; }
+    bool operator<(const BlockNode &X) const { return Index < X.Index; }
+    bool operator>(const BlockNode &X) const { return Index > X.Index; }
+
+    BlockNode() : Index(UINT32_MAX) {}
+    BlockNode(IndexType Index) : Index(Index) {}
+
+    bool isValid() const { return Index <= getMaxIndex(); }
+    static size_t getMaxIndex() { return UINT32_MAX - 1; }
+  };
+
+  /// \brief Stats about a block itself.
+  struct FrequencyData {
+    Scaled64 Scaled;
+    uint64_t Integer;
+  };
+
+  /// \brief Data about a loop.
+  ///
+  /// Contains the data necessary to represent represent a loop as a
+  /// pseudo-node once it's packaged.
+  struct LoopData {
+    typedef SmallVector<std::pair<BlockNode, BlockMass>, 4> ExitMap;
+    typedef SmallVector<BlockNode, 4> NodeList;
+    LoopData *Parent;       ///< The parent loop.
+    bool IsPackaged;        ///< Whether this has been packaged.
+    uint32_t NumHeaders;    ///< Number of headers.
+    ExitMap Exits;          ///< Successor edges (and weights).
+    NodeList Nodes;         ///< Header and the members of the loop.
+    BlockMass BackedgeMass; ///< Mass returned to loop header.
+    BlockMass Mass;
+    Scaled64 Scale;
+
+    LoopData(LoopData *Parent, const BlockNode &Header)
+        : Parent(Parent), IsPackaged(false), NumHeaders(1), Nodes(1, Header) {}
+    template <class It1, class It2>
+    LoopData(LoopData *Parent, It1 FirstHeader, It1 LastHeader, It2 FirstOther,
+             It2 LastOther)
+        : Parent(Parent), IsPackaged(false), Nodes(FirstHeader, LastHeader) {
+      NumHeaders = Nodes.size();
+      Nodes.insert(Nodes.end(), FirstOther, LastOther);
+    }
+    bool isHeader(const BlockNode &Node) const {
+      if (isIrreducible())
+        return std::binary_search(Nodes.begin(), Nodes.begin() + NumHeaders,
+                                  Node);
+      return Node == Nodes[0];
+    }
+    BlockNode getHeader() const { return Nodes[0]; }
+    bool isIrreducible() const { return NumHeaders > 1; }
+
+    NodeList::const_iterator members_begin() const {
+      return Nodes.begin() + NumHeaders;
+    }
+    NodeList::const_iterator members_end() const { return Nodes.end(); }
+    iterator_range<NodeList::const_iterator> members() const {
+      return make_range(members_begin(), members_end());
+    }
+  };
+
+  /// \brief Index of loop information.
+  struct WorkingData {
+    BlockNode Node; ///< This node.
+    LoopData *Loop; ///< The loop this block is inside.
+    BlockMass Mass; ///< Mass distribution from the entry block.
+
+    WorkingData(const BlockNode &Node) : Node(Node), Loop(nullptr) {}
+
+    bool isLoopHeader() const { return Loop && Loop->isHeader(Node); }
+    bool isDoubleLoopHeader() const {
+      return isLoopHeader() && Loop->Parent && Loop->Parent->isIrreducible() &&
+             Loop->Parent->isHeader(Node);
+    }
+
+    LoopData *getContainingLoop() const {
+      if (!isLoopHeader())
+        return Loop;
+      if (!isDoubleLoopHeader())
+        return Loop->Parent;
+      return Loop->Parent->Parent;
+    }
+
+    /// \brief Resolve a node to its representative.
+    ///
+    /// Get the node currently representing Node, which could be a containing
+    /// loop.
+    ///
+    /// This function should only be called when distributing mass.  As long as
+    /// there are no irreducilbe edges to Node, then it will have complexity
+    /// O(1) in this context.
+    ///
+    /// In general, the complexity is O(L), where L is the number of loop
+    /// headers Node has been packaged into.  Since this method is called in
+    /// the context of distributing mass, L will be the number of loop headers
+    /// an early exit edge jumps out of.
+    BlockNode getResolvedNode() const {
+      auto L = getPackagedLoop();
+      return L ? L->getHeader() : Node;
+    }
+    LoopData *getPackagedLoop() const {
+      if (!Loop || !Loop->IsPackaged)
+        return nullptr;
+      auto L = Loop;
+      while (L->Parent && L->Parent->IsPackaged)
+        L = L->Parent;
+      return L;
+    }
+
+    /// \brief Get the appropriate mass for a node.
+    ///
+    /// Get appropriate mass for Node.  If Node is a loop-header (whose loop
+    /// has been packaged), returns the mass of its pseudo-node.  If it's a
+    /// node inside a packaged loop, it returns the loop's mass.
+    BlockMass &getMass() {
+      if (!isAPackage())
+        return Mass;
+      if (!isADoublePackage())
+        return Loop->Mass;
+      return Loop->Parent->Mass;
+    }
+
+    /// \brief Has ContainingLoop been packaged up?
+    bool isPackaged() const { return getResolvedNode() != Node; }
+    /// \brief Has Loop been packaged up?
+    bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; }
+    /// \brief Has Loop been packaged up twice?
+    bool isADoublePackage() const {
+      return isDoubleLoopHeader() && Loop->Parent->IsPackaged;
+    }
+  };
+
+  /// \brief Unscaled probability weight.
+  ///
+  /// Probability weight for an edge in the graph (including the
+  /// successor/target node).
+  ///
+  /// All edges in the original function are 32-bit.  However, exit edges from
+  /// loop packages are taken from 64-bit exit masses, so we need 64-bits of
+  /// space in general.
+  ///
+  /// In addition to the raw weight amount, Weight stores the type of the edge
+  /// in the current context (i.e., the context of the loop being processed).
+  /// Is this a local edge within the loop, an exit from the loop, or a
+  /// backedge to the loop header?
+  struct Weight {
+    enum DistType { Local, Exit, Backedge };
+    DistType Type;
+    BlockNode TargetNode;
+    uint64_t Amount;
+    Weight() : Type(Local), Amount(0) {}
+    Weight(DistType Type, BlockNode TargetNode, uint64_t Amount)
+        : Type(Type), TargetNode(TargetNode), Amount(Amount) {}
+  };
+
+  /// \brief Distribution of unscaled probability weight.
+  ///
+  /// Distribution of unscaled probability weight to a set of successors.
+  ///
+  /// This class collates the successor edge weights for later processing.
+  ///
+  /// \a DidOverflow indicates whether \a Total did overflow while adding to
+  /// the distribution.  It should never overflow twice.
+  struct Distribution {
+    typedef SmallVector<Weight, 4> WeightList;
+    WeightList Weights;    ///< Individual successor weights.
+    uint64_t Total;        ///< Sum of all weights.
+    bool DidOverflow;      ///< Whether \a Total did overflow.
+
+    Distribution() : Total(0), DidOverflow(false) {}
+    void addLocal(const BlockNode &Node, uint64_t Amount) {
+      add(Node, Amount, Weight::Local);
+    }
+    void addExit(const BlockNode &Node, uint64_t Amount) {
+      add(Node, Amount, Weight::Exit);
+    }
+    void addBackedge(const BlockNode &Node, uint64_t Amount) {
+      add(Node, Amount, Weight::Backedge);
+    }
+
+    /// \brief Normalize the distribution.
+    ///
+    /// Combines multiple edges to the same \a Weight::TargetNode and scales
+    /// down so that \a Total fits into 32-bits.
+    ///
+    /// This is linear in the size of \a Weights.  For the vast majority of
+    /// cases, adjacent edge weights are combined by sorting WeightList and
+    /// combining adjacent weights.  However, for very large edge lists an
+    /// auxiliary hash table is used.
+    void normalize();
+
+  private:
+    void add(const BlockNode &Node, uint64_t Amount, Weight::DistType Type);
+  };
+
+  /// \brief Data about each block.  This is used downstream.
+  std::vector<FrequencyData> Freqs;
+
+  /// \brief Loop data: see initializeLoops().
+  std::vector<WorkingData> Working;
+
+  /// \brief Indexed information about loops.
+  std::list<LoopData> Loops;
+
+  /// \brief Add all edges out of a packaged loop to the distribution.
+  ///
+  /// Adds all edges from LocalLoopHead to Dist.  Calls addToDist() to add each
+  /// successor edge.
+  ///
+  /// \return \c true unless there's an irreducible backedge.
+  bool addLoopSuccessorsToDist(const LoopData *OuterLoop, LoopData &Loop,
+                               Distribution &Dist);
+
+  /// \brief Add an edge to the distribution.
+  ///
+  /// Adds an edge to Succ to Dist.  If \c LoopHead.isValid(), then whether the
+  /// edge is local/exit/backedge is in the context of LoopHead.  Otherwise,
+  /// every edge should be a local edge (since all the loops are packaged up).
+  ///
+  /// \return \c true unless aborted due to an irreducible backedge.
+  bool addToDist(Distribution &Dist, const LoopData *OuterLoop,
+                 const BlockNode &Pred, const BlockNode &Succ, uint64_t Weight);
+
+  LoopData &getLoopPackage(const BlockNode &Head) {
+    assert(Head.Index < Working.size());
+    assert(Working[Head.Index].isLoopHeader());
+    return *Working[Head.Index].Loop;
+  }
+
+  /// \brief Analyze irreducible SCCs.
+  ///
+  /// Separate irreducible SCCs from \c G, which is an explict graph of \c
+  /// OuterLoop (or the top-level function, if \c OuterLoop is \c nullptr).
+  /// Insert them into \a Loops before \c Insert.
+  ///
+  /// \return the \c LoopData nodes representing the irreducible SCCs.
+  iterator_range<std::list<LoopData>::iterator>
+  analyzeIrreducible(const bfi_detail::IrreducibleGraph &G, LoopData *OuterLoop,
+                     std::list<LoopData>::iterator Insert);
+
+  /// \brief Update a loop after packaging irreducible SCCs inside of it.
+  ///
+  /// Update \c OuterLoop.  Before finding irreducible control flow, it was
+  /// partway through \a computeMassInLoop(), so \a LoopData::Exits and \a
+  /// LoopData::BackedgeMass need to be reset.  Also, nodes that were packaged
+  /// up need to be removed from \a OuterLoop::Nodes.
+  void updateLoopWithIrreducible(LoopData &OuterLoop);
+
+  /// \brief Distribute mass according to a distribution.
+  ///
+  /// Distributes the mass in Source according to Dist.  If LoopHead.isValid(),
+  /// backedges and exits are stored in its entry in Loops.
+  ///
+  /// Mass is distributed in parallel from two copies of the source mass.
+  void distributeMass(const BlockNode &Source, LoopData *OuterLoop,
+                      Distribution &Dist);
+
+  /// \brief Compute the loop scale for a loop.
+  void computeLoopScale(LoopData &Loop);
+
+  /// \brief Package up a loop.
+  void packageLoop(LoopData &Loop);
+
+  /// \brief Unwrap loops.
+  void unwrapLoops();
+
+  /// \brief Finalize frequency metrics.
+  ///
+  /// Calculates final frequencies and cleans up no-longer-needed data
+  /// structures.
+  void finalizeMetrics();
+
+  /// \brief Clear all memory.
+  void clear();
+
+  virtual std::string getBlockName(const BlockNode &Node) const;
+  std::string getLoopName(const LoopData &Loop) const;
+
+  virtual raw_ostream &print(raw_ostream &OS) const { return OS; }
+  void dump() const { print(dbgs()); }
+
+  Scaled64 getFloatingBlockFreq(const BlockNode &Node) const;
+
+  BlockFrequency getBlockFreq(const BlockNode &Node) const;
+
+  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockNode &Node) const;
+  raw_ostream &printBlockFreq(raw_ostream &OS,
+                              const BlockFrequency &Freq) const;
+
+  uint64_t getEntryFreq() const {
+    assert(!Freqs.empty());
+    return Freqs[0].Integer;
+  }
+  /// \brief Virtual destructor.
+  ///
+  /// Need a virtual destructor to mask the compiler warning about
+  /// getBlockName().
+  virtual ~BlockFrequencyInfoImplBase() {}
+};
+
+namespace bfi_detail {
+template <class BlockT> struct TypeMap {};
+template <> struct TypeMap<BasicBlock> {
+  typedef BasicBlock BlockT;
+  typedef Function FunctionT;
+  typedef BranchProbabilityInfo BranchProbabilityInfoT;
+  typedef Loop LoopT;
+  typedef LoopInfo LoopInfoT;
+};
+template <> struct TypeMap<MachineBasicBlock> {
+  typedef MachineBasicBlock BlockT;
+  typedef MachineFunction FunctionT;
+  typedef MachineBranchProbabilityInfo BranchProbabilityInfoT;
+  typedef MachineLoop LoopT;
+  typedef MachineLoopInfo LoopInfoT;
+};
+
+/// \brief Get the name of a MachineBasicBlock.
+///
+/// Get the name of a MachineBasicBlock.  It's templated so that including from
+/// CodeGen is unnecessary (that would be a layering issue).
+///
+/// This is used mainly for debug output.  The name is similar to
+/// MachineBasicBlock::getFullName(), but skips the name of the function.
+template <class BlockT> std::string getBlockName(const BlockT *BB) {
+  assert(BB && "Unexpected nullptr");
+  auto MachineName = "BB" + Twine(BB->getNumber());
+  if (BB->getBasicBlock())
+    return (MachineName + "[" + BB->getName() + "]").str();
+  return MachineName.str();
+}
+/// \brief Get the name of a BasicBlock.
+template <> inline std::string getBlockName(const BasicBlock *BB) {
+  assert(BB && "Unexpected nullptr");
+  return BB->getName().str();
+}
+
+/// \brief Graph of irreducible control flow.
+///
+/// This graph is used for determining the SCCs in a loop (or top-level
+/// function) that has irreducible control flow.
+///
+/// During the block frequency algorithm, the local graphs are defined in a
+/// light-weight way, deferring to the \a BasicBlock or \a MachineBasicBlock
+/// graphs for most edges, but getting others from \a LoopData::ExitMap.  The
+/// latter only has successor information.
+///
+/// \a IrreducibleGraph makes this graph explicit.  It's in a form that can use
+/// \a GraphTraits (so that \a analyzeIrreducible() can use \a scc_iterator),
+/// and it explicitly lists predecessors and successors.  The initialization
+/// that relies on \c MachineBasicBlock is defined in the header.
+struct IrreducibleGraph {
+  typedef BlockFrequencyInfoImplBase BFIBase;
+
+  BFIBase &BFI;
+
+  typedef BFIBase::BlockNode BlockNode;
+  struct IrrNode {
+    BlockNode Node;
+    unsigned NumIn;
+    std::deque<const IrrNode *> Edges;
+    IrrNode(const BlockNode &Node) : Node(Node), NumIn(0) {}
+
+    typedef std::deque<const IrrNode *>::const_iterator iterator;
+    iterator pred_begin() const { return Edges.begin(); }
+    iterator succ_begin() const { return Edges.begin() + NumIn; }
+    iterator pred_end() const { return succ_begin(); }
+    iterator succ_end() const { return Edges.end(); }
+  };
+  BlockNode Start;
+  const IrrNode *StartIrr;
+  std::vector<IrrNode> Nodes;
+  SmallDenseMap<uint32_t, IrrNode *, 4> Lookup;
+
+  /// \brief Construct an explicit graph containing irreducible control flow.
+  ///
+  /// Construct an explicit graph of the control flow in \c OuterLoop (or the
+  /// top-level function, if \c OuterLoop is \c nullptr).  Uses \c
+  /// addBlockEdges to add block successors that have not been packaged into
+  /// loops.
+  ///
+  /// \a BlockFrequencyInfoImpl::computeIrreducibleMass() is the only expected
+  /// user of this.
+  template <class BlockEdgesAdder>
+  IrreducibleGraph(BFIBase &BFI, const BFIBase::LoopData *OuterLoop,
+                   BlockEdgesAdder addBlockEdges)
+      : BFI(BFI), StartIrr(nullptr) {
+    initialize(OuterLoop, addBlockEdges);
+  }
+
+  template <class BlockEdgesAdder>
+  void initialize(const BFIBase::LoopData *OuterLoop,
+                  BlockEdgesAdder addBlockEdges);
+  void addNodesInLoop(const BFIBase::LoopData &OuterLoop);
+  void addNodesInFunction();
+  void addNode(const BlockNode &Node) {
+    Nodes.emplace_back(Node);
+    BFI.Working[Node.Index].getMass() = BlockMass::getEmpty();
+  }
+  void indexNodes();
+  template <class BlockEdgesAdder>
+  void addEdges(const BlockNode &Node, const BFIBase::LoopData *OuterLoop,
+                BlockEdgesAdder addBlockEdges);
+  void addEdge(IrrNode &Irr, const BlockNode &Succ,
+               const BFIBase::LoopData *OuterLoop);
+};
+template <class BlockEdgesAdder>
+void IrreducibleGraph::initialize(const BFIBase::LoopData *OuterLoop,
+                                  BlockEdgesAdder addBlockEdges) {
+  if (OuterLoop) {
+    addNodesInLoop(*OuterLoop);
+    for (auto N : OuterLoop->Nodes)
+      addEdges(N, OuterLoop, addBlockEdges);
+  } else {
+    addNodesInFunction();
+    for (uint32_t Index = 0; Index < BFI.Working.size(); ++Index)
+      addEdges(Index, OuterLoop, addBlockEdges);
+  }
+  StartIrr = Lookup[Start.Index];
+}
+template <class BlockEdgesAdder>
+void IrreducibleGraph::addEdges(const BlockNode &Node,
+                                const BFIBase::LoopData *OuterLoop,
+                                BlockEdgesAdder addBlockEdges) {
+  auto L = Lookup.find(Node.Index);
+  if (L == Lookup.end())
+    return;
+  IrrNode &Irr = *L->second;
+  const auto &Working = BFI.Working[Node.Index];
+
+  if (Working.isAPackage())
+    for (const auto &I : Working.Loop->Exits)
+      addEdge(Irr, I.first, OuterLoop);
+  else
+    addBlockEdges(*this, Irr, OuterLoop);
+}
+}
+
+/// \brief Shared implementation for block frequency analysis.
+///
+/// This is a shared implementation of BlockFrequencyInfo and
+/// MachineBlockFrequencyInfo, and calculates the relative frequencies of
+/// blocks.
+///
+/// LoopInfo defines a loop as a "non-trivial" SCC dominated by a single block,
+/// which is called the header.  A given loop, L, can have sub-loops, which are
+/// loops within the subgraph of L that exclude its header.  (A "trivial" SCC
+/// consists of a single block that does not have a self-edge.)
+///
+/// In addition to loops, this algorithm has limited support for irreducible
+/// SCCs, which are SCCs with multiple entry blocks.  Irreducible SCCs are
+/// discovered on they fly, and modelled as loops with multiple headers.
+///
+/// The headers of irreducible sub-SCCs consist of its entry blocks and all
+/// nodes that are targets of a backedge within it (excluding backedges within
+/// true sub-loops).  Block frequency calculations act as if a block is
+/// inserted that intercepts all the edges to the headers.  All backedges and
+/// entries point to this block.  Its successors are the headers, which split
+/// the frequency evenly.
+///
+/// This algorithm leverages BlockMass and ScaledNumber to maintain precision,
+/// separates mass distribution from loop scaling, and dithers to eliminate
+/// probability mass loss.
+///
+/// The implementation is split between BlockFrequencyInfoImpl, which knows the
+/// type of graph being modelled (BasicBlock vs. MachineBasicBlock), and
+/// BlockFrequencyInfoImplBase, which doesn't.  The base class uses \a
+/// BlockNode, a wrapper around a uint32_t.  BlockNode is numbered from 0 in
+/// reverse-post order.  This gives two advantages:  it's easy to compare the
+/// relative ordering of two nodes, and maps keyed on BlockT can be represented
+/// by vectors.
+///
+/// This algorithm is O(V+E), unless there is irreducible control flow, in
+/// which case it's O(V*E) in the worst case.
+///
+/// These are the main stages:
+///
+///  0. Reverse post-order traversal (\a initializeRPOT()).
+///
+///     Run a single post-order traversal and save it (in reverse) in RPOT.
+///     All other stages make use of this ordering.  Save a lookup from BlockT
+///     to BlockNode (the index into RPOT) in Nodes.
+///
+///  1. Loop initialization (\a initializeLoops()).
+///
+///     Translate LoopInfo/MachineLoopInfo into a form suitable for the rest of
+///     the algorithm.  In particular, store the immediate members of each loop
+///     in reverse post-order.
+///
+///  2. Calculate mass and scale in loops (\a computeMassInLoops()).
+///
+///     For each loop (bottom-up), distribute mass through the DAG resulting
+///     from ignoring backedges and treating sub-loops as a single pseudo-node.
+///     Track the backedge mass distributed to the loop header, and use it to
+///     calculate the loop scale (number of loop iterations).  Immediate
+///     members that represent sub-loops will already have been visited and
+///     packaged into a pseudo-node.
+///
+///     Distributing mass in a loop is a reverse-post-order traversal through
+///     the loop.  Start by assigning full mass to the Loop header.  For each
+///     node in the loop:
+///
+///         - Fetch and categorize the weight distribution for its successors.
+///           If this is a packaged-subloop, the weight distribution is stored
+///           in \a LoopData::Exits.  Otherwise, fetch it from
+///           BranchProbabilityInfo.
+///
+///         - Each successor is categorized as \a Weight::Local, a local edge
+///           within the current loop, \a Weight::Backedge, a backedge to the
+///           loop header, or \a Weight::Exit, any successor outside the loop.
+///           The weight, the successor, and its category are stored in \a
+///           Distribution.  There can be multiple edges to each successor.
+///
+///         - If there's a backedge to a non-header, there's an irreducible SCC.
+///           The usual flow is temporarily aborted.  \a
+///           computeIrreducibleMass() finds the irreducible SCCs within the
+///           loop, packages them up, and restarts the flow.
+///
+///         - Normalize the distribution:  scale weights down so that their sum
+///           is 32-bits, and coalesce multiple edges to the same node.
+///
+///         - Distribute the mass accordingly, dithering to minimize mass loss,
+///           as described in \a distributeMass().
+///
+///     Finally, calculate the loop scale from the accumulated backedge mass.
+///
+///  3. Distribute mass in the function (\a computeMassInFunction()).
+///
+///     Finally, distribute mass through the DAG resulting from packaging all
+///     loops in the function.  This uses the same algorithm as distributing
+///     mass in a loop, except that there are no exit or backedge edges.
+///
+///  4. Unpackage loops (\a unwrapLoops()).
+///
+///     Initialize each block's frequency to a floating point representation of
+///     its mass.
+///
+///     Visit loops top-down, scaling the frequencies of its immediate members
+///     by the loop's pseudo-node's frequency.
+///
+///  5. Convert frequencies to a 64-bit range (\a finalizeMetrics()).
+///
+///     Using the min and max frequencies as a guide, translate floating point
+///     frequencies to an appropriate range in uint64_t.
+///
+/// It has some known flaws.
+///
+///   - Loop scale is limited to 4096 per loop (2^12) to avoid exhausting
+///     BlockFrequency's 64-bit integer precision.
+///
+///   - The model of irreducible control flow is a rough approximation.
+///
+///     Modelling irreducible control flow exactly involves setting up and
+///     solving a group of infinite geometric series.  Such precision is
+///     unlikely to be worthwhile, since most of our algorithms give up on
+///     irreducible control flow anyway.
+///
+///     Nevertheless, we might find that we need to get closer.  Here's a sort
+///     of TODO list for the model with diminishing returns, to be completed as
+///     necessary.
+///
+///       - The headers for the \a LoopData representing an irreducible SCC
+///         include non-entry blocks.  When these extra blocks exist, they
+///         indicate a self-contained irreducible sub-SCC.  We could treat them
+///         as sub-loops, rather than arbitrarily shoving the problematic
+///         blocks into the headers of the main irreducible SCC.
+///
+///       - Backedge frequencies are assumed to be evenly split between the
+///         headers of a given irreducible SCC.  Instead, we could track the
+///         backedge mass separately for each header, and adjust their relative
+///         frequencies.
+///
+///       - Entry frequencies are assumed to be evenly split between the
+///         headers of a given irreducible SCC, which is the only option if we
+///         need to compute mass in the SCC before its parent loop.  Instead,
+///         we could partially compute mass in the parent loop, and stop when
+///         we get to the SCC.  Here, we have the correct ratio of entry
+///         masses, which we can use to adjust their relative frequencies.
+///         Compute mass in the SCC, and then continue propagation in the
+///         parent.
+///
+///       - We can propagate mass iteratively through the SCC, for some fixed
+///         number of iterations.  Each iteration starts by assigning the entry
+///         blocks their backedge mass from the prior iteration.  The final
+///         mass for each block (and each exit, and the total backedge mass
+///         used for computing loop scale) is the sum of all iterations.
+///         (Running this until fixed point would "solve" the geometric
+///         series by simulation.)
+template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
+  typedef typename bfi_detail::TypeMap<BT>::BlockT BlockT;
+  typedef typename bfi_detail::TypeMap<BT>::FunctionT FunctionT;
+  typedef typename bfi_detail::TypeMap<BT>::BranchProbabilityInfoT
+  BranchProbabilityInfoT;
+  typedef typename bfi_detail::TypeMap<BT>::LoopT LoopT;
+  typedef typename bfi_detail::TypeMap<BT>::LoopInfoT LoopInfoT;
+
+  // This is part of a workaround for a GCC 4.7 crash on lambdas.
+  friend struct bfi_detail::BlockEdgesAdder<BT>;
+
+  typedef GraphTraits<const BlockT *> Successor;
+  typedef GraphTraits<Inverse<const BlockT *>> Predecessor;
+
+  const BranchProbabilityInfoT *BPI;
+  const LoopInfoT *LI;
+  const FunctionT *F;
+
+  // All blocks in reverse postorder.
+  std::vector<const BlockT *> RPOT;
+  DenseMap<const BlockT *, BlockNode> Nodes;
+
+  typedef typename std::vector<const BlockT *>::const_iterator rpot_iterator;
+
+  rpot_iterator rpot_begin() const { return RPOT.begin(); }
+  rpot_iterator rpot_end() const { return RPOT.end(); }
+
+  size_t getIndex(const rpot_iterator &I) const { return I - rpot_begin(); }
+
+  BlockNode getNode(const rpot_iterator &I) const {
+    return BlockNode(getIndex(I));
+  }
+  BlockNode getNode(const BlockT *BB) const { return Nodes.lookup(BB); }
+
+  const BlockT *getBlock(const BlockNode &Node) const {
+    assert(Node.Index < RPOT.size());
+    return RPOT[Node.Index];
+  }
+
+  /// \brief Run (and save) a post-order traversal.
+  ///
+  /// Saves a reverse post-order traversal of all the nodes in \a F.
+  void initializeRPOT();
+
+  /// \brief Initialize loop data.
+  ///
+  /// Build up \a Loops using \a LoopInfo.  \a LoopInfo gives us a mapping from
+  /// each block to the deepest loop it's in, but we need the inverse.  For each
+  /// loop, we store in reverse post-order its "immediate" members, defined as
+  /// the header, the headers of immediate sub-loops, and all other blocks in
+  /// the loop that are not in sub-loops.
+  void initializeLoops();
+
+  /// \brief Propagate to a block's successors.
+  ///
+  /// In the context of distributing mass through \c OuterLoop, divide the mass
+  /// currently assigned to \c Node between its successors.
+  ///
+  /// \return \c true unless there's an irreducible backedge.
+  bool propagateMassToSuccessors(LoopData *OuterLoop, const BlockNode &Node);
+
+  /// \brief Compute mass in a particular loop.
+  ///
+  /// Assign mass to \c Loop's header, and then for each block in \c Loop in
+  /// reverse post-order, distribute mass to its successors.  Only visits nodes
+  /// that have not been packaged into sub-loops.
+  ///
+  /// \pre \a computeMassInLoop() has been called for each subloop of \c Loop.
+  /// \return \c true unless there's an irreducible backedge.
+  bool computeMassInLoop(LoopData &Loop);
+
+  /// \brief Try to compute mass in the top-level function.
+  ///
+  /// Assign mass to the entry block, and then for each block in reverse
+  /// post-order, distribute mass to its successors.  Skips nodes that have
+  /// been packaged into loops.
+  ///
+  /// \pre \a computeMassInLoops() has been called.
+  /// \return \c true unless there's an irreducible backedge.
+  bool tryToComputeMassInFunction();
+
+  /// \brief Compute mass in (and package up) irreducible SCCs.
+  ///
+  /// Find the irreducible SCCs in \c OuterLoop, add them to \a Loops (in front
+  /// of \c Insert), and call \a computeMassInLoop() on each of them.
+  ///
+  /// If \c OuterLoop is \c nullptr, it refers to the top-level function.
+  ///
+  /// \pre \a computeMassInLoop() has been called for each subloop of \c
+  /// OuterLoop.
+  /// \pre \c Insert points at the the last loop successfully processed by \a
+  /// computeMassInLoop().
+  /// \pre \c OuterLoop has irreducible SCCs.
+  void computeIrreducibleMass(LoopData *OuterLoop,
+                              std::list<LoopData>::iterator Insert);
+
+  /// \brief Compute mass in all loops.
+  ///
+  /// For each loop bottom-up, call \a computeMassInLoop().
+  ///
+  /// \a computeMassInLoop() aborts (and returns \c false) on loops that
+  /// contain a irreducible sub-SCCs.  Use \a computeIrreducibleMass() and then
+  /// re-enter \a computeMassInLoop().
+  ///
+  /// \post \a computeMassInLoop() has returned \c true for every loop.
+  void computeMassInLoops();
+
+  /// \brief Compute mass in the top-level function.
+  ///
+  /// Uses \a tryToComputeMassInFunction() and \a computeIrreducibleMass() to
+  /// compute mass in the top-level function.
+  ///
+  /// \post \a tryToComputeMassInFunction() has returned \c true.
+  void computeMassInFunction();
+
+  std::string getBlockName(const BlockNode &Node) const override {
+    return bfi_detail::getBlockName(getBlock(Node));
+  }
+
+public:
+  const FunctionT *getFunction() const { return F; }
+
+  void doFunction(const FunctionT *F, const BranchProbabilityInfoT *BPI,
+                  const LoopInfoT *LI);
+  BlockFrequencyInfoImpl() : BPI(nullptr), LI(nullptr), F(nullptr) {}
+
+  using BlockFrequencyInfoImplBase::getEntryFreq;
+  BlockFrequency getBlockFreq(const BlockT *BB) const {
+    return BlockFrequencyInfoImplBase::getBlockFreq(getNode(BB));
+  }
+  Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
+    return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB));
+  }
+
+  /// \brief Print the frequencies for the current function.
+  ///
+  /// Prints the frequencies for the blocks in the current function.
+  ///
+  /// Blocks are printed in the natural iteration order of the function, rather
+  /// than reverse post-order.  This provides two advantages:  writing -analyze
+  /// tests is easier (since blocks come out in source order), and even
+  /// unreachable blocks are printed.
+  ///
+  /// \a BlockFrequencyInfoImplBase::print() only knows reverse post-order, so
+  /// we need to override it here.
+  raw_ostream &print(raw_ostream &OS) const override;
+  using BlockFrequencyInfoImplBase::dump;
+
+  using BlockFrequencyInfoImplBase::printBlockFreq;
+  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockT *BB) const {
+    return BlockFrequencyInfoImplBase::printBlockFreq(OS, getNode(BB));
+  }
+};
+
+template <class BT>
+void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F,
+                                            const BranchProbabilityInfoT *BPI,
+                                            const LoopInfoT *LI) {
+  // Save the parameters.
+  this->BPI = BPI;
+  this->LI = LI;
+  this->F = F;
+
+  // Clean up left-over data structures.
+  BlockFrequencyInfoImplBase::clear();
+  RPOT.clear();
+  Nodes.clear();
+
+  // Initialize.
+  DEBUG(dbgs() << "\nblock-frequency: " << F->getName() << "\n================="
+               << std::string(F->getName().size(), '=') << "\n");
+  initializeRPOT();
+  initializeLoops();
+
+  // Visit loops in post-order to find thelocal mass distribution, and then do
+  // the full function.
+  computeMassInLoops();
+  computeMassInFunction();
+  unwrapLoops();
+  finalizeMetrics();
+}
+
+template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
+  const BlockT *Entry = F->begin();
+  RPOT.reserve(F->size());
+  std::copy(po_begin(Entry), po_end(Entry), std::back_inserter(RPOT));
+  std::reverse(RPOT.begin(), RPOT.end());
+
+  assert(RPOT.size() - 1 <= BlockNode::getMaxIndex() &&
+         "More nodes in function than Block Frequency Info supports");
+
+  DEBUG(dbgs() << "reverse-post-order-traversal\n");
+  for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
+    BlockNode Node = getNode(I);
+    DEBUG(dbgs() << " - " << getIndex(I) << ": " << getBlockName(Node) << "\n");
+    Nodes[*I] = Node;
+  }
+
+  Working.reserve(RPOT.size());
+  for (size_t Index = 0; Index < RPOT.size(); ++Index)
+    Working.emplace_back(Index);
+  Freqs.resize(RPOT.size());
+}
+
+template <class BT> void BlockFrequencyInfoImpl<BT>::initializeLoops() {
+  DEBUG(dbgs() << "loop-detection\n");
+  if (LI->empty())
+    return;
+
+  // Visit loops top down and assign them an index.
+  std::deque<std::pair<const LoopT *, LoopData *>> Q;
+  for (const LoopT *L : *LI)
+    Q.emplace_back(L, nullptr);
+  while (!Q.empty()) {
+    const LoopT *Loop = Q.front().first;
+    LoopData *Parent = Q.front().second;
+    Q.pop_front();
+
+    BlockNode Header = getNode(Loop->getHeader());
+    assert(Header.isValid());
+
+    Loops.emplace_back(Parent, Header);
+    Working[Header.Index].Loop = &Loops.back();
+    DEBUG(dbgs() << " - loop = " << getBlockName(Header) << "\n");
+
+    for (const LoopT *L : *Loop)
+      Q.emplace_back(L, &Loops.back());
+  }
+
+  // Visit nodes in reverse post-order and add them to their deepest containing
+  // loop.
+  for (size_t Index = 0; Index < RPOT.size(); ++Index) {
+    // Loop headers have already been mostly mapped.
+    if (Working[Index].isLoopHeader()) {
+      LoopData *ContainingLoop = Working[Index].getContainingLoop();
+      if (ContainingLoop)
+        ContainingLoop->Nodes.push_back(Index);
+      continue;
+    }
+
+    const LoopT *Loop = LI->getLoopFor(RPOT[Index]);
+    if (!Loop)
+      continue;
+
+    // Add this node to its containing loop's member list.
+    BlockNode Header = getNode(Loop->getHeader());
+    assert(Header.isValid());
+    const auto &HeaderData = Working[Header.Index];
+    assert(HeaderData.isLoopHeader());
+
+    Working[Index].Loop = HeaderData.Loop;
+    HeaderData.Loop->Nodes.push_back(Index);
+    DEBUG(dbgs() << " - loop = " << getBlockName(Header)
+                 << ": member = " << getBlockName(Index) << "\n");
+  }
+}
+
+template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
+  // Visit loops with the deepest first, and the top-level loops last.
+  for (auto L = Loops.rbegin(), E = Loops.rend(); L != E; ++L) {
+    if (computeMassInLoop(*L))
+      continue;
+    auto Next = std::next(L);
+    computeIrreducibleMass(&*L, L.base());
+    L = std::prev(Next);
+    if (computeMassInLoop(*L))
+      continue;
+    llvm_unreachable("unhandled irreducible control flow");
+  }
+}
+
+template <class BT>
+bool BlockFrequencyInfoImpl<BT>::computeMassInLoop(LoopData &Loop) {
+  // Compute mass in loop.
+  DEBUG(dbgs() << "compute-mass-in-loop: " << getLoopName(Loop) << "\n");
+
+  if (Loop.isIrreducible()) {
+    BlockMass Remaining = BlockMass::getFull();
+    for (uint32_t H = 0; H < Loop.NumHeaders; ++H) {
+      auto &Mass = Working[Loop.Nodes[H].Index].getMass();
+      Mass = Remaining * BranchProbability(1, Loop.NumHeaders - H);
+      Remaining -= Mass;
+    }
+    for (const BlockNode &M : Loop.Nodes)
+      if (!propagateMassToSuccessors(&Loop, M))
+        llvm_unreachable("unhandled irreducible control flow");
+  } else {
+    Working[Loop.getHeader().Index].getMass() = BlockMass::getFull();
+    if (!propagateMassToSuccessors(&Loop, Loop.getHeader()))
+      llvm_unreachable("irreducible control flow to loop header!?");
+    for (const BlockNode &M : Loop.members())
+      if (!propagateMassToSuccessors(&Loop, M))
+        // Irreducible backedge.
+        return false;
+  }
+
+  computeLoopScale(Loop);
+  packageLoop(Loop);
+  return true;
+}
+
+template <class BT>
+bool BlockFrequencyInfoImpl<BT>::tryToComputeMassInFunction() {
+  // Compute mass in function.
+  DEBUG(dbgs() << "compute-mass-in-function\n");
+  assert(!Working.empty() && "no blocks in function");
+  assert(!Working[0].isLoopHeader() && "entry block is a loop header");
+
+  Working[0].getMass() = BlockMass::getFull();
+  for (rpot_iterator I = rpot_begin(), IE = rpot_end(); I != IE; ++I) {
+    // Check for nodes that have been packaged.
+    BlockNode Node = getNode(I);
+    if (Working[Node.Index].isPackaged())
+      continue;
+
+    if (!propagateMassToSuccessors(nullptr, Node))
+      return false;
+  }
+  return true;
+}
+
+template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInFunction() {
+  if (tryToComputeMassInFunction())
+    return;
+  computeIrreducibleMass(nullptr, Loops.begin());
+  if (tryToComputeMassInFunction())
+    return;
+  llvm_unreachable("unhandled irreducible control flow");
+}
+
+/// \note This should be a lambda, but that crashes GCC 4.7.
+namespace bfi_detail {
+template <class BT> struct BlockEdgesAdder {
+  typedef BT BlockT;
+  typedef BlockFrequencyInfoImplBase::LoopData LoopData;
+  typedef GraphTraits<const BlockT *> Successor;
+
+  const BlockFrequencyInfoImpl<BT> &BFI;
+  explicit BlockEdgesAdder(const BlockFrequencyInfoImpl<BT> &BFI)
+      : BFI(BFI) {}
+  void operator()(IrreducibleGraph &G, IrreducibleGraph::IrrNode &Irr,
+                  const LoopData *OuterLoop) {
+    const BlockT *BB = BFI.RPOT[Irr.Node.Index];
+    for (auto I = Successor::child_begin(BB), E = Successor::child_end(BB);
+         I != E; ++I)
+      G.addEdge(Irr, BFI.getNode(*I), OuterLoop);
+  }
+};
+}
+template <class BT>
+void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass(
+    LoopData *OuterLoop, std::list<LoopData>::iterator Insert) {
+  DEBUG(dbgs() << "analyze-irreducible-in-";
+        if (OuterLoop) dbgs() << "loop: " << getLoopName(*OuterLoop) << "\n";
+        else dbgs() << "function\n");
+
+  using namespace bfi_detail;
+  // Ideally, addBlockEdges() would be declared here as a lambda, but that
+  // crashes GCC 4.7.
+  BlockEdgesAdder<BT> addBlockEdges(*this);
+  IrreducibleGraph G(*this, OuterLoop, addBlockEdges);
+
+  for (auto &L : analyzeIrreducible(G, OuterLoop, Insert))
+    computeMassInLoop(L);
+
+  if (!OuterLoop)
+    return;
+  updateLoopWithIrreducible(*OuterLoop);
+}
+
+template <class BT>
+bool
+BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop,
+                                                      const BlockNode &Node) {
+  DEBUG(dbgs() << " - node: " << getBlockName(Node) << "\n");
+  // Calculate probability for successors.
+  Distribution Dist;
+  if (auto *Loop = Working[Node.Index].getPackagedLoop()) {
+    assert(Loop != OuterLoop && "Cannot propagate mass in a packaged loop");
+    if (!addLoopSuccessorsToDist(OuterLoop, *Loop, Dist))
+      // Irreducible backedge.
+      return false;
+  } else {
+    const BlockT *BB = getBlock(Node);
+    for (auto SI = Successor::child_begin(BB), SE = Successor::child_end(BB);
+         SI != SE; ++SI)
+      // Do not dereference SI, or getEdgeWeight() is linear in the number of
+      // successors.
+      if (!addToDist(Dist, OuterLoop, Node, getNode(*SI),
+                     BPI->getEdgeWeight(BB, SI)))
+        // Irreducible backedge.
+        return false;
+  }
+
+  // Distribute mass to successors, saving exit and backedge data in the
+  // loop header.
+  distributeMass(Node, OuterLoop, Dist);
+  return true;
+}
+
+template <class BT>
+raw_ostream &BlockFrequencyInfoImpl<BT>::print(raw_ostream &OS) const {
+  if (!F)
+    return OS;
+  OS << "block-frequency-info: " << F->getName() << "\n";
+  for (const BlockT &BB : *F)
+    OS << " - " << bfi_detail::getBlockName(&BB)
+       << ": float = " << getFloatingBlockFreq(&BB)
+       << ", int = " << getBlockFreq(&BB).getFrequency() << "\n";
+
+  // Add an extra newline for readability.
+  OS << "\n";
+  return OS;
+}
+
+} // end namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h
new file mode 100644
index 0000000..4414c84
--- /dev/null
+++ b/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -0,0 +1,156 @@
+//===--- BranchProbabilityInfo.h - Branch Probability Analysis --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to evaluate branch probabilties.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
+#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/BranchProbability.h"
+
+namespace llvm {
+class LoopInfo;
+class raw_ostream;
+
+/// \brief Analysis pass providing branch probability information.
+///
+/// This is a function analysis pass which provides information on the relative
+/// probabilities of each "edge" in the function's CFG where such an edge is
+/// defined by a pair (PredBlock and an index in the successors). The
+/// probability of an edge from one block is always relative to the
+/// probabilities of other edges from the block. The probabilites of all edges
+/// from a block sum to exactly one (100%).
+/// We use a pair (PredBlock and an index in the successors) to uniquely
+/// identify an edge, since we can have multiple edges from Src to Dst.
+/// As an example, we can have a switch which jumps to Dst with value 0 and
+/// value 10.
+class BranchProbabilityInfo : public FunctionPass {
+public:
+  static char ID;
+
+  BranchProbabilityInfo() : FunctionPass(ID) {
+    initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  bool runOnFunction(Function &F) override;
+  void print(raw_ostream &OS, const Module *M = nullptr) const override;
+
+  /// \brief Get an edge's probability, relative to other out-edges of the Src.
+  ///
+  /// This routine provides access to the fractional probability between zero
+  /// (0%) and one (100%) of this edge executing, relative to other edges
+  /// leaving the 'Src' block. The returned probability is never zero, and can
+  /// only be one if the source block has only one successor.
+  BranchProbability getEdgeProbability(const BasicBlock *Src,
+                                       unsigned IndexInSuccessors) const;
+
+  /// \brief Get the probability of going from Src to Dst.
+  ///
+  /// It returns the sum of all probabilities for edges from Src to Dst.
+  BranchProbability getEdgeProbability(const BasicBlock *Src,
+                                       const BasicBlock *Dst) const;
+
+  /// \brief Test if an edge is hot relative to other out-edges of the Src.
+  ///
+  /// Check whether this edge out of the source block is 'hot'. We define hot
+  /// as having a relative probability >= 80%.
+  bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const;
+
+  /// \brief Retrieve the hot successor of a block if one exists.
+  ///
+  /// Given a basic block, look through its successors and if one exists for
+  /// which \see isEdgeHot would return true, return that successor block.
+  BasicBlock *getHotSucc(BasicBlock *BB) const;
+
+  /// \brief Print an edge's probability.
+  ///
+  /// Retrieves an edge's probability similarly to \see getEdgeProbability, but
+  /// then prints that probability to the provided stream. That stream is then
+  /// returned.
+  raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
+                                    const BasicBlock *Dst) const;
+
+  /// \brief Get the raw edge weight calculated for the edge.
+  ///
+  /// This returns the raw edge weight. It is guaranteed to fall between 1 and
+  /// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
+  /// This interface should be very carefully, and primarily by routines that
+  /// are updating the analysis by later calling setEdgeWeight.
+  uint32_t getEdgeWeight(const BasicBlock *Src,
+                         unsigned IndexInSuccessors) const;
+
+  /// \brief Get the raw edge weight calculated for the block pair.
+  ///
+  /// This returns the sum of all raw edge weights from Src to Dst.
+  /// It is guaranteed to fall between 1 and UINT32_MAX.
+  uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
+
+  uint32_t getEdgeWeight(const BasicBlock *Src,
+                         succ_const_iterator Dst) const;
+
+  /// \brief Set the raw edge weight for a given edge.
+  ///
+  /// This allows a pass to explicitly set the edge weight for an edge. It can
+  /// be used when updating the CFG to update and preserve the branch
+  /// probability information. Read the implementation of how these edge
+  /// weights are calculated carefully before using!
+  void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors,
+                     uint32_t Weight);
+
+private:
+  // Since we allow duplicate edges from one basic block to another, we use
+  // a pair (PredBlock and an index in the successors) to specify an edge.
+  typedef std::pair<const BasicBlock *, unsigned> Edge;
+
+  // Default weight value. Used when we don't have information about the edge.
+  // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
+  // the successors have a weight yet. But it doesn't make sense when providing
+  // weight to an edge that may have siblings with non-zero weights. This can
+  // be handled various ways, but it's probably fine for an edge with unknown
+  // weight to just "inherit" the non-zero weight of an adjacent successor.
+  static const uint32_t DEFAULT_WEIGHT = 16;
+
+  DenseMap<Edge, uint32_t> Weights;
+
+  /// \brief Handle to the LoopInfo analysis.
+  LoopInfo *LI;
+
+  /// \brief Track the last function we run over for printing.
+  Function *LastF;
+
+  /// \brief Track the set of blocks directly succeeded by a returning block.
+  SmallPtrSet<BasicBlock *, 16> PostDominatedByUnreachable;
+
+  /// \brief Track the set of blocks that always lead to a cold call.
+  SmallPtrSet<BasicBlock *, 16> PostDominatedByColdCall;
+
+  /// \brief Get sum of the block successors' weights.
+  uint32_t getSumForBlock(const BasicBlock *BB) const;
+
+  bool calcUnreachableHeuristics(BasicBlock *BB);
+  bool calcMetadataWeights(BasicBlock *BB);
+  bool calcColdCallHeuristics(BasicBlock *BB);
+  bool calcPointerHeuristics(BasicBlock *BB);
+  bool calcLoopBranchHeuristics(BasicBlock *BB);
+  bool calcZeroHeuristics(BasicBlock *BB);
+  bool calcFloatingPointHeuristics(BasicBlock *BB);
+  bool calcInvokeHeuristics(BasicBlock *BB);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h
new file mode 100644
index 0000000..7f92eda
--- /dev/null
+++ b/include/llvm/Analysis/CFG.h
@@ -0,0 +1,83 @@
+//===-- Analysis/CFG.h - BasicBlock Analyses --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions performs analyses on basic blocks, and instructions
+// contained within basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CFG_H
+#define LLVM_ANALYSIS_CFG_H
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+
+namespace llvm {
+
+class BasicBlock;
+class DominatorTree;
+class Function;
+class Instruction;
+class LoopInfo;
+class TerminatorInst;
+
+/// Analyze the specified function to find all of the loop backedges in the
+/// function and return them.  This is a relatively cheap (compared to
+/// computing dominators and loop info) analysis.
+///
+/// The output is added to Result, as pairs of <from,to> edge info.
+void FindFunctionBackedges(
+    const Function &F,
+    SmallVectorImpl<std::pair<const BasicBlock *, const BasicBlock *> > &
+        Result);
+
+/// Search for the specified successor of basic block BB and return its position
+/// in the terminator instruction's list of successors.  It is an error to call
+/// this with a block that is not a successor.
+unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
+
+/// Return true if the specified edge is a critical edge. Critical edges are
+/// edges from a block with multiple successors to a block with multiple
+/// predecessors.
+///
+bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
+                    bool AllowIdenticalEdges = false);
+
+/// \brief Determine whether instruction 'To' is reachable from 'From',
+/// returning true if uncertain.
+///
+/// Determine whether there is a path from From to To within a single function.
+/// Returns false only if we can prove that once 'From' has been executed then
+/// 'To' can not be executed. Conservatively returns true.
+///
+/// This function is linear with respect to the number of blocks in the CFG,
+/// walking down successors from From to reach To, with a fixed threshold.
+/// Using DT or LI allows us to answer more quickly. LI reduces the cost of
+/// an entire loop of any number of blocsk to be the same as the cost of a
+/// single block. DT reduces the cost by allowing the search to terminate when
+/// we find a block that dominates the block containing 'To'. DT is most useful
+/// on branchy code but not loops, and LI is most useful on code with loops but
+/// does not help on branchy code outside loops.
+bool isPotentiallyReachable(const Instruction *From, const Instruction *To,
+                            const DominatorTree *DT = nullptr,
+                            const LoopInfo *LI = nullptr);
+
+/// \brief Determine whether block 'To' is reachable from 'From', returning
+/// true if uncertain.
+///
+/// Determine whether there is a path from From to To within a single function.
+/// Returns false only if we can prove that once 'From' has been reached then
+/// 'To' can not be executed. Conservatively returns true.
+bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To,
+                            const DominatorTree *DT = nullptr,
+                            const LoopInfo *LI = nullptr);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h
new file mode 100644
index 0000000..e6d2ed1
--- /dev/null
+++ b/include/llvm/Analysis/CFGPrinter.h
@@ -0,0 +1,130 @@
+//===-- CFGPrinter.h - CFG printer external interface -----------*- 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 external functions that can be called to explicitly
+// instantiate the CFG printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CFGPRINTER_H
+#define LLVM_ANALYSIS_CFGPRINTER_H
+
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/GraphWriter.h"
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
+
+  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+  static std::string getGraphName(const Function *F) {
+    return "CFG for '" + F->getName().str() + "' function";
+  }
+
+  static std::string getSimpleNodeLabel(const BasicBlock *Node,
+                                        const Function *) {
+    if (!Node->getName().empty())
+      return Node->getName().str();
+
+    std::string Str;
+    raw_string_ostream OS(Str);
+
+    Node->printAsOperand(OS, false);
+    return OS.str();
+  }
+
+  static std::string getCompleteNodeLabel(const BasicBlock *Node,
+                                          const Function *) {
+    enum { MaxColumns = 80 };
+    std::string Str;
+    raw_string_ostream OS(Str);
+
+    if (Node->getName().empty()) {
+      Node->printAsOperand(OS, false);
+      OS << ":";
+    }
+
+    OS << *Node;
+    std::string OutStr = OS.str();
+    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+
+    // Process string output to make it nicer...
+    unsigned ColNum = 0;
+    unsigned LastSpace = 0;
+    for (unsigned i = 0; i != OutStr.length(); ++i) {
+      if (OutStr[i] == '\n') {                            // Left justify
+        OutStr[i] = '\\';
+        OutStr.insert(OutStr.begin()+i+1, 'l');
+        ColNum = 0;
+        LastSpace = 0;
+      } else if (OutStr[i] == ';') {                      // Delete comments!
+        unsigned Idx = OutStr.find('\n', i+1);            // Find end of line
+        OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
+        --i;
+      } else if (ColNum == MaxColumns) {                  // Wrap lines.
+        if (LastSpace) {
+          OutStr.insert(LastSpace, "\\l...");
+          ColNum = i - LastSpace;
+          LastSpace = 0;
+          i += 3; // The loop will advance 'i' again.
+        }
+        // Else keep trying to find a space.
+      }
+      else
+        ++ColNum;
+      if (OutStr[i] == ' ')
+        LastSpace = i;
+    }
+    return OutStr;
+  }
+
+  std::string getNodeLabel(const BasicBlock *Node,
+                           const Function *Graph) {
+    if (isSimple())
+      return getSimpleNodeLabel(Node, Graph);
+    else
+      return getCompleteNodeLabel(Node, Graph);
+  }
+
+  static std::string getEdgeSourceLabel(const BasicBlock *Node,
+                                        succ_const_iterator I) {
+    // Label source of conditional branches with "T" or "F"
+    if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
+      if (BI->isConditional())
+        return (I == succ_begin(Node)) ? "T" : "F";
+
+    // Label source of switch edges with the associated value.
+    if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
+      unsigned SuccNo = I.getSuccessorIndex();
+
+      if (SuccNo == 0) return "def";
+
+      std::string Str;
+      raw_string_ostream OS(Str);
+      SwitchInst::ConstCaseIt Case =
+          SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
+      OS << Case.getCaseValue()->getValue();
+      return OS.str();
+    }
+    return "";
+  }
+};
+} // End llvm namespace
+
+namespace llvm {
+  class FunctionPass;
+  FunctionPass *createCFGPrinterPass ();
+  FunctionPass *createCFGOnlyPrinterPass ();
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h
new file mode 100644
index 0000000..09101ae
--- /dev/null
+++ b/include/llvm/Analysis/CGSCCPassManager.h
@@ -0,0 +1,591 @@
+//===- CGSCCPassManager.h - Call graph pass management ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header provides classes for managing passes over SCCs of the call
+/// graph. These passes form an important component of LLVM's interprocedural
+/// optimizations. Because they operate on the SCCs of the call graph, and they
+/// wtraverse the graph in post order, they can effectively do pair-wise
+/// interprocedural optimizations for all call edges in the program. At each
+/// call site edge, the callee has already been optimized as much as is
+/// possible. This in turn allows very accurate analysis of it for IPO.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CGSCC_PASS_MANAGER_H
+#define LLVM_ANALYSIS_CGSCC_PASS_MANAGER_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+
+namespace llvm {
+
+class CGSCCAnalysisManager;
+
+class CGSCCPassManager {
+public:
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  CGSCCPassManager() {}
+  CGSCCPassManager(CGSCCPassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
+  CGSCCPassManager &operator=(CGSCCPassManager &&RHS) {
+    Passes = std::move(RHS.Passes);
+    return *this;
+  }
+
+  /// \brief Run all of the CGSCC passes in this pass manager over a SCC.
+  PreservedAnalyses run(LazyCallGraph::SCC *C,
+                        CGSCCAnalysisManager *AM = nullptr);
+
+  template <typename CGSCCPassT> void addPass(CGSCCPassT Pass) {
+    Passes.emplace_back(new CGSCCPassModel<CGSCCPassT>(std::move(Pass)));
+  }
+
+  static StringRef name() { return "CGSCCPassManager"; }
+
+private:
+  // Pull in the concept type and model template specialized for SCCs.
+  typedef detail::PassConcept<LazyCallGraph::SCC *, CGSCCAnalysisManager>
+  CGSCCPassConcept;
+  template <typename PassT>
+  struct CGSCCPassModel
+      : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT> {
+    CGSCCPassModel(PassT Pass)
+        : detail::PassModel<LazyCallGraph::SCC *, CGSCCAnalysisManager, PassT>(
+              std::move(Pass)) {}
+  };
+
+  CGSCCPassManager(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
+  CGSCCPassManager &operator=(const CGSCCPassManager &) LLVM_DELETED_FUNCTION;
+
+  std::vector<std::unique_ptr<CGSCCPassConcept>> Passes;
+};
+
+/// \brief A function analysis manager to coordinate and cache analyses run over
+/// a module.
+class CGSCCAnalysisManager : public detail::AnalysisManagerBase<
+                                 CGSCCAnalysisManager, LazyCallGraph::SCC *> {
+  friend class detail::AnalysisManagerBase<CGSCCAnalysisManager,
+                                           LazyCallGraph::SCC *>;
+  typedef detail::AnalysisManagerBase<CGSCCAnalysisManager,
+                                      LazyCallGraph::SCC *> BaseT;
+  typedef BaseT::ResultConceptT ResultConceptT;
+  typedef BaseT::PassConceptT PassConceptT;
+
+public:
+  // Most public APIs are inherited from the CRTP base class.
+
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  CGSCCAnalysisManager() {}
+  CGSCCAnalysisManager(CGSCCAnalysisManager &&Arg)
+      : BaseT(std::move(static_cast<BaseT &>(Arg))),
+        CGSCCAnalysisResults(std::move(Arg.CGSCCAnalysisResults)) {}
+  CGSCCAnalysisManager &operator=(CGSCCAnalysisManager &&RHS) {
+    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+    CGSCCAnalysisResults = std::move(RHS.CGSCCAnalysisResults);
+    return *this;
+  }
+
+  /// \brief Returns true if the analysis manager has an empty results cache.
+  bool empty() const;
+
+  /// \brief Clear the function analysis result cache.
+  ///
+  /// This routine allows cleaning up when the set of functions itself has
+  /// potentially changed, and thus we can't even look up a a result and
+  /// invalidate it directly. Notably, this does *not* call invalidate
+  /// functions as there is nothing to be done for them.
+  void clear();
+
+private:
+  CGSCCAnalysisManager(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
+  CGSCCAnalysisManager &
+  operator=(const CGSCCAnalysisManager &) LLVM_DELETED_FUNCTION;
+
+  /// \brief Get a function pass result, running the pass if necessary.
+  ResultConceptT &getResultImpl(void *PassID, LazyCallGraph::SCC *C);
+
+  /// \brief Get a cached function pass result or return null.
+  ResultConceptT *getCachedResultImpl(void *PassID,
+                                      LazyCallGraph::SCC *C) const;
+
+  /// \brief Invalidate a function pass result.
+  void invalidateImpl(void *PassID, LazyCallGraph::SCC *C);
+
+  /// \brief Invalidate the results for a function..
+  void invalidateImpl(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
+
+  /// \brief List of function analysis pass IDs and associated concept pointers.
+  ///
+  /// Requires iterators to be valid across appending new entries and arbitrary
+  /// erases. Provides both the pass ID and concept pointer such that it is
+  /// half of a bijection and provides storage for the actual result concept.
+  typedef std::list<
+      std::pair<void *, std::unique_ptr<detail::AnalysisResultConcept<
+                            LazyCallGraph::SCC *>>>> CGSCCAnalysisResultListT;
+
+  /// \brief Map type from function pointer to our custom list type.
+  typedef DenseMap<LazyCallGraph::SCC *, CGSCCAnalysisResultListT>
+  CGSCCAnalysisResultListMapT;
+
+  /// \brief Map from function to a list of function analysis results.
+  ///
+  /// Provides linear time removal of all analysis results for a function and
+  /// the ultimate storage for a particular cached analysis result.
+  CGSCCAnalysisResultListMapT CGSCCAnalysisResultLists;
+
+  /// \brief Map type from a pair of analysis ID and function pointer to an
+  /// iterator into a particular result list.
+  typedef DenseMap<std::pair<void *, LazyCallGraph::SCC *>,
+                   CGSCCAnalysisResultListT::iterator> CGSCCAnalysisResultMapT;
+
+  /// \brief Map from an analysis ID and function to a particular cached
+  /// analysis result.
+  CGSCCAnalysisResultMapT CGSCCAnalysisResults;
+};
+
+/// \brief A module analysis which acts as a proxy for a CGSCC analysis
+/// manager.
+///
+/// This primarily proxies invalidation information from the module analysis
+/// manager and module pass manager to a CGSCC analysis manager. You should
+/// never use a CGSCC analysis manager from within (transitively) a module
+/// pass manager unless your parent module pass has received a proxy result
+/// object for it.
+class CGSCCAnalysisManagerModuleProxy {
+public:
+  class Result {
+  public:
+    explicit Result(CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
+    // We have to explicitly define all the special member functions because
+    // MSVC refuses to generate them.
+    Result(const Result &Arg) : CGAM(Arg.CGAM) {}
+    Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
+    Result &operator=(Result RHS) {
+      std::swap(CGAM, RHS.CGAM);
+      return *this;
+    }
+    ~Result();
+
+    /// \brief Accessor for the \c CGSCCAnalysisManager.
+    CGSCCAnalysisManager &getManager() { return *CGAM; }
+
+    /// \brief Handler for invalidation of the module.
+    ///
+    /// If this analysis itself is preserved, then we assume that the call
+    /// graph of the module hasn't changed and thus we don't need to invalidate
+    /// *all* cached data associated with a \c SCC* in the \c
+    /// CGSCCAnalysisManager.
+    ///
+    /// Regardless of whether this analysis is marked as preserved, all of the
+    /// analyses in the \c CGSCCAnalysisManager are potentially invalidated
+    /// based on the set of preserved analyses.
+    bool invalidate(Module *M, const PreservedAnalyses &PA);
+
+  private:
+    CGSCCAnalysisManager *CGAM;
+  };
+
+  static void *ID() { return (void *)&PassID; }
+
+  explicit CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManager &CGAM)
+      : CGAM(&CGAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  CGSCCAnalysisManagerModuleProxy(
+      const CGSCCAnalysisManagerModuleProxy &Arg)
+      : CGAM(Arg.CGAM) {}
+  CGSCCAnalysisManagerModuleProxy(CGSCCAnalysisManagerModuleProxy &&Arg)
+      : CGAM(std::move(Arg.CGAM)) {}
+  CGSCCAnalysisManagerModuleProxy &
+  operator=(CGSCCAnalysisManagerModuleProxy RHS) {
+    std::swap(CGAM, RHS.CGAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  ///
+  /// This doesn't do any interesting work, it is primarily used to insert our
+  /// proxy result object into the module analysis cache so that we can proxy
+  /// invalidation to the CGSCC analysis manager.
+  ///
+  /// In debug builds, it will also assert that the analysis manager is empty
+  /// as no queries should arrive at the CGSCC analysis manager prior to
+  /// this analysis being requested.
+  Result run(Module *M);
+
+private:
+  static char PassID;
+
+  CGSCCAnalysisManager *CGAM;
+};
+
+/// \brief A CGSCC analysis which acts as a proxy for a module analysis
+/// manager.
+///
+/// This primarily provides an accessor to a parent module analysis manager to
+/// CGSCC passes. Only the const interface of the module analysis manager is
+/// provided to indicate that once inside of a CGSCC analysis pass you
+/// cannot request a module analysis to actually run. Instead, the user must
+/// rely on the \c getCachedResult API.
+///
+/// This proxy *doesn't* manage the invalidation in any way. That is handled by
+/// the recursive return path of each layer of the pass manager and the
+/// returned PreservedAnalysis set.
+class ModuleAnalysisManagerCGSCCProxy {
+public:
+  /// \brief Result proxy object for \c ModuleAnalysisManagerCGSCCProxy.
+  class Result {
+  public:
+    explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+    // We have to explicitly define all the special member functions because
+    // MSVC refuses to generate them.
+    Result(const Result &Arg) : MAM(Arg.MAM) {}
+    Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
+    Result &operator=(Result RHS) {
+      std::swap(MAM, RHS.MAM);
+      return *this;
+    }
+
+    const ModuleAnalysisManager &getManager() const { return *MAM; }
+
+    /// \brief Handle invalidation by ignoring it, this pass is immutable.
+    bool invalidate(LazyCallGraph::SCC *) { return false; }
+
+  private:
+    const ModuleAnalysisManager *MAM;
+  };
+
+  static void *ID() { return (void *)&PassID; }
+
+  ModuleAnalysisManagerCGSCCProxy(const ModuleAnalysisManager &MAM)
+      : MAM(&MAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModuleAnalysisManagerCGSCCProxy(
+      const ModuleAnalysisManagerCGSCCProxy &Arg)
+      : MAM(Arg.MAM) {}
+  ModuleAnalysisManagerCGSCCProxy(ModuleAnalysisManagerCGSCCProxy &&Arg)
+      : MAM(std::move(Arg.MAM)) {}
+  ModuleAnalysisManagerCGSCCProxy &
+  operator=(ModuleAnalysisManagerCGSCCProxy RHS) {
+    std::swap(MAM, RHS.MAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  /// Nothing to see here, it just forwards the \c MAM reference into the
+  /// result.
+  Result run(LazyCallGraph::SCC *) { return Result(*MAM); }
+
+private:
+  static char PassID;
+
+  const ModuleAnalysisManager *MAM;
+};
+
+/// \brief The core module pass which does a post-order walk of the SCCs and
+/// runs a CGSCC pass over each one.
+///
+/// Designed to allow composition of a CGSCCPass(Manager) and
+/// a ModulePassManager. Note that this pass must be run with a module analysis
+/// manager as it uses the LazyCallGraph analysis. It will also run the
+/// \c CGSCCAnalysisManagerModuleProxy analysis prior to running the CGSCC
+/// pass over the module to enable a \c FunctionAnalysisManager to be used
+/// within this run safely.
+template <typename CGSCCPassT> class ModuleToPostOrderCGSCCPassAdaptor {
+public:
+  explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
+      : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModuleToPostOrderCGSCCPassAdaptor(
+      const ModuleToPostOrderCGSCCPassAdaptor &Arg)
+      : Pass(Arg.Pass) {}
+  ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
+      : Pass(std::move(Arg.Pass)) {}
+  friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
+                   ModuleToPostOrderCGSCCPassAdaptor &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  ModuleToPostOrderCGSCCPassAdaptor &
+  operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief Runs the CGSCC pass across every SCC in the module.
+  PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
+    assert(AM && "We need analyses to compute the call graph!");
+
+    // Setup the CGSCC analysis manager from its proxy.
+    CGSCCAnalysisManager &CGAM =
+        AM->getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
+
+    // Get the call graph for this module.
+    LazyCallGraph &CG = AM->getResult<LazyCallGraphAnalysis>(M);
+
+    PreservedAnalyses PA = PreservedAnalyses::all();
+    for (LazyCallGraph::SCC &C : CG.postorder_sccs()) {
+      PreservedAnalyses PassPA = Pass.run(&C, &CGAM);
+
+      // We know that the CGSCC pass couldn't have invalidated any other
+      // SCC's analyses (that's the contract of a CGSCC pass), so
+      // directly handle the CGSCC analysis manager's invalidation here.
+      // FIXME: This isn't quite correct. We need to handle the case where the
+      // pass updated the CG, particularly some child of the current SCC, and
+      // invalidate its analyses.
+      CGAM.invalidate(&C, PassPA);
+
+      // Then intersect the preserved set so that invalidation of module
+      // analyses will eventually occur when the module pass completes.
+      PA.intersect(std::move(PassPA));
+    }
+
+    // By definition we preserve the proxy. This precludes *any* invalidation
+    // of CGSCC analyses by the proxy, but that's OK because we've taken
+    // care to invalidate analyses in the CGSCC analysis manager
+    // incrementally above.
+    PA.preserve<CGSCCAnalysisManagerModuleProxy>();
+    return PA;
+  }
+
+  static StringRef name() { return "ModuleToPostOrderCGSCCPassAdaptor"; }
+
+private:
+  CGSCCPassT Pass;
+};
+
+/// \brief A function to deduce a function pass type and wrap it in the
+/// templated adaptor.
+template <typename CGSCCPassT>
+ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
+createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
+  return std::move(
+      ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass)));
+}
+
+/// \brief A CGSCC analysis which acts as a proxy for a function analysis
+/// manager.
+///
+/// This primarily proxies invalidation information from the CGSCC analysis
+/// manager and CGSCC pass manager to a function analysis manager. You should
+/// never use a function analysis manager from within (transitively) a CGSCC
+/// pass manager unless your parent CGSCC pass has received a proxy result
+/// object for it.
+class FunctionAnalysisManagerCGSCCProxy {
+public:
+  class Result {
+  public:
+    explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
+    // We have to explicitly define all the special member functions because
+    // MSVC refuses to generate them.
+    Result(const Result &Arg) : FAM(Arg.FAM) {}
+    Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
+    Result &operator=(Result RHS) {
+      std::swap(FAM, RHS.FAM);
+      return *this;
+    }
+    ~Result();
+
+    /// \brief Accessor for the \c FunctionAnalysisManager.
+    FunctionAnalysisManager &getManager() { return *FAM; }
+
+    /// \brief Handler for invalidation of the SCC.
+    ///
+    /// If this analysis itself is preserved, then we assume that the set of \c
+    /// Function objects in the \c SCC hasn't changed and thus we don't need
+    /// to invalidate *all* cached data associated with a \c Function* in the \c
+    /// FunctionAnalysisManager.
+    ///
+    /// Regardless of whether this analysis is marked as preserved, all of the
+    /// analyses in the \c FunctionAnalysisManager are potentially invalidated
+    /// based on the set of preserved analyses.
+    bool invalidate(LazyCallGraph::SCC *C, const PreservedAnalyses &PA);
+
+  private:
+    FunctionAnalysisManager *FAM;
+  };
+
+  static void *ID() { return (void *)&PassID; }
+
+  explicit FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManager &FAM)
+      : FAM(&FAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  FunctionAnalysisManagerCGSCCProxy(
+      const FunctionAnalysisManagerCGSCCProxy &Arg)
+      : FAM(Arg.FAM) {}
+  FunctionAnalysisManagerCGSCCProxy(FunctionAnalysisManagerCGSCCProxy &&Arg)
+      : FAM(std::move(Arg.FAM)) {}
+  FunctionAnalysisManagerCGSCCProxy &
+  operator=(FunctionAnalysisManagerCGSCCProxy RHS) {
+    std::swap(FAM, RHS.FAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  ///
+  /// This doesn't do any interesting work, it is primarily used to insert our
+  /// proxy result object into the module analysis cache so that we can proxy
+  /// invalidation to the function analysis manager.
+  ///
+  /// In debug builds, it will also assert that the analysis manager is empty
+  /// as no queries should arrive at the function analysis manager prior to
+  /// this analysis being requested.
+  Result run(LazyCallGraph::SCC *C);
+
+private:
+  static char PassID;
+
+  FunctionAnalysisManager *FAM;
+};
+
+/// \brief A function analysis which acts as a proxy for a CGSCC analysis
+/// manager.
+///
+/// This primarily provides an accessor to a parent CGSCC analysis manager to
+/// function passes. Only the const interface of the CGSCC analysis manager is
+/// provided to indicate that once inside of a function analysis pass you
+/// cannot request a CGSCC analysis to actually run. Instead, the user must
+/// rely on the \c getCachedResult API.
+///
+/// This proxy *doesn't* manage the invalidation in any way. That is handled by
+/// the recursive return path of each layer of the pass manager and the
+/// returned PreservedAnalysis set.
+class CGSCCAnalysisManagerFunctionProxy {
+public:
+  /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+  class Result {
+  public:
+    explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
+    // We have to explicitly define all the special member functions because
+    // MSVC refuses to generate them.
+    Result(const Result &Arg) : CGAM(Arg.CGAM) {}
+    Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
+    Result &operator=(Result RHS) {
+      std::swap(CGAM, RHS.CGAM);
+      return *this;
+    }
+
+    const CGSCCAnalysisManager &getManager() const { return *CGAM; }
+
+    /// \brief Handle invalidation by ignoring it, this pass is immutable.
+    bool invalidate(Function *) { return false; }
+
+  private:
+    const CGSCCAnalysisManager *CGAM;
+  };
+
+  static void *ID() { return (void *)&PassID; }
+
+  CGSCCAnalysisManagerFunctionProxy(const CGSCCAnalysisManager &CGAM)
+      : CGAM(&CGAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  CGSCCAnalysisManagerFunctionProxy(
+      const CGSCCAnalysisManagerFunctionProxy &Arg)
+      : CGAM(Arg.CGAM) {}
+  CGSCCAnalysisManagerFunctionProxy(CGSCCAnalysisManagerFunctionProxy &&Arg)
+      : CGAM(std::move(Arg.CGAM)) {}
+  CGSCCAnalysisManagerFunctionProxy &
+  operator=(CGSCCAnalysisManagerFunctionProxy RHS) {
+    std::swap(CGAM, RHS.CGAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  /// Nothing to see here, it just forwards the \c CGAM reference into the
+  /// result.
+  Result run(Function *) { return Result(*CGAM); }
+
+private:
+  static char PassID;
+
+  const CGSCCAnalysisManager *CGAM;
+};
+
+/// \brief Adaptor that maps from a SCC to its functions.
+///
+/// Designed to allow composition of a FunctionPass(Manager) and
+/// a CGSCCPassManager. Note that if this pass is constructed with a pointer
+/// to a \c CGSCCAnalysisManager it will run the
+/// \c FunctionAnalysisManagerCGSCCProxy analysis prior to running the function
+/// pass over the SCC to enable a \c FunctionAnalysisManager to be used
+/// within this run safely.
+template <typename FunctionPassT> class CGSCCToFunctionPassAdaptor {
+public:
+  explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
+      : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
+      : Pass(Arg.Pass) {}
+  CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
+      : Pass(std::move(Arg.Pass)) {}
+  friend void swap(CGSCCToFunctionPassAdaptor &LHS, CGSCCToFunctionPassAdaptor &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief Runs the function pass across every function in the module.
+  PreservedAnalyses run(LazyCallGraph::SCC *C, CGSCCAnalysisManager *AM) {
+    FunctionAnalysisManager *FAM = nullptr;
+    if (AM)
+      // Setup the function analysis manager from its proxy.
+      FAM = &AM->getResult<FunctionAnalysisManagerCGSCCProxy>(C).getManager();
+
+    PreservedAnalyses PA = PreservedAnalyses::all();
+    for (LazyCallGraph::Node *N : *C) {
+      PreservedAnalyses PassPA = Pass.run(&N->getFunction(), FAM);
+
+      // We know that the function pass couldn't have invalidated any other
+      // function's analyses (that's the contract of a function pass), so
+      // directly handle the function analysis manager's invalidation here.
+      if (FAM)
+        FAM->invalidate(&N->getFunction(), PassPA);
+
+      // Then intersect the preserved set so that invalidation of module
+      // analyses will eventually occur when the module pass completes.
+      PA.intersect(std::move(PassPA));
+    }
+
+    // By definition we preserve the proxy. This precludes *any* invalidation
+    // of function analyses by the proxy, but that's OK because we've taken
+    // care to invalidate analyses in the function analysis manager
+    // incrementally above.
+    // FIXME: We need to update the call graph here to account for any deleted
+    // edges!
+    PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
+    return PA;
+  }
+
+  static StringRef name() { return "CGSCCToFunctionPassAdaptor"; }
+
+private:
+  FunctionPassT Pass;
+};
+
+/// \brief A function to deduce a function pass type and wrap it in the
+/// templated adaptor.
+template <typename FunctionPassT>
+CGSCCToFunctionPassAdaptor<FunctionPassT>
+createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
+  return std::move(CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
+}
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
new file mode 100644
index 0000000..9a6a4a7
--- /dev/null
+++ b/include/llvm/Analysis/CallGraph.h
@@ -0,0 +1,467 @@
+//===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides interfaces used to build and manipulate a call graph,
+/// which is a very useful tool for interprocedural optimization.
+///
+/// Every function in a module is represented as a node in the call graph.  The
+/// callgraph node keeps track of which functions are called by the function
+/// corresponding to the node.
+///
+/// A call graph may contain nodes where the function that they correspond to
+/// is null.  These 'external' nodes are used to represent control flow that is
+/// not represented (or analyzable) in the module.  In particular, this
+/// analysis builds one external node such that:
+///   1. All functions in the module without internal linkage will have edges
+///      from this external node, indicating that they could be called by
+///      functions outside of the module.
+///   2. All functions whose address is used for something more than a direct
+///      call, for example being stored into a memory location will also have
+///      an edge from this external node.  Since they may be called by an
+///      unknown caller later, they must be tracked as such.
+///
+/// There is a second external node added for calls that leave this module.
+/// Functions have a call edge to the external node iff:
+///   1. The function is external, reflecting the fact that they could call
+///      anything without internal linkage or that has its address taken.
+///   2. The function contains an indirect function call.
+///
+/// As an extension in the future, there may be multiple nodes with a null
+/// function.  These will be used when we can prove (through pointer analysis)
+/// that an indirect call site can call only a specific set of functions.
+///
+/// Because of these properties, the CallGraph captures a conservative superset
+/// of all of the caller-callee relationships, which is useful for
+/// transformations.
+///
+/// The CallGraph class also attempts to figure out what the root of the
+/// CallGraph is, which it currently does by looking for a function named
+/// 'main'. If no function named 'main' is found, the external node is used as
+/// the entry node, reflecting the fact that any function without internal
+/// linkage could be called into (which is common for libraries).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CALLGRAPH_H
+#define LLVM_ANALYSIS_CALLGRAPH_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/IncludeFile.h"
+#include <map>
+
+namespace llvm {
+
+class Function;
+class Module;
+class CallGraphNode;
+
+/// \brief The basic data container for the call graph of a \c Module of IR.
+///
+/// This class exposes both the interface to the call graph for a module of IR.
+///
+/// The core call graph itself can also be updated to reflect changes to the IR.
+class CallGraph {
+  Module &M;
+
+  typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
+
+  /// \brief A map from \c Function* to \c CallGraphNode*.
+  FunctionMapTy FunctionMap;
+
+  /// \brief Root is root of the call graph, or the external node if a 'main'
+  /// function couldn't be found.
+  CallGraphNode *Root;
+
+  /// \brief This node has edges to all external functions and those internal
+  /// functions that have their address taken.
+  CallGraphNode *ExternalCallingNode;
+
+  /// \brief This node has edges to it from all functions making indirect calls
+  /// or calling an external function.
+  CallGraphNode *CallsExternalNode;
+
+  /// \brief Replace the function represented by this node by another.
+  ///
+  /// This does not rescan the body of the function, so it is suitable when
+  /// splicing the body of one function to another while also updating all
+  /// callers from the old function to the new.
+  void spliceFunction(const Function *From, const Function *To);
+
+  /// \brief Add a function to the call graph, and link the node to all of the
+  /// functions that it calls.
+  void addToCallGraph(Function *F);
+
+public:
+  CallGraph(Module &M);
+  ~CallGraph();
+
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+  typedef FunctionMapTy::iterator iterator;
+  typedef FunctionMapTy::const_iterator const_iterator;
+
+  /// \brief Returns the module the call graph corresponds to.
+  Module &getModule() const { return M; }
+
+  inline iterator begin() { return FunctionMap.begin(); }
+  inline iterator end() { return FunctionMap.end(); }
+  inline const_iterator begin() const { return FunctionMap.begin(); }
+  inline const_iterator end() const { return FunctionMap.end(); }
+
+  /// \brief Returns the call graph node for the provided function.
+  inline const CallGraphNode *operator[](const Function *F) const {
+    const_iterator I = FunctionMap.find(F);
+    assert(I != FunctionMap.end() && "Function not in callgraph!");
+    return I->second;
+  }
+
+  /// \brief Returns the call graph node for the provided function.
+  inline CallGraphNode *operator[](const Function *F) {
+    const_iterator I = FunctionMap.find(F);
+    assert(I != FunctionMap.end() && "Function not in callgraph!");
+    return I->second;
+  }
+
+  /// \brief Returns the \c CallGraphNode which is used to represent
+  /// undetermined calls into the callgraph.
+  CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; }
+
+  CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; }
+
+  //===---------------------------------------------------------------------
+  // Functions to keep a call graph up to date with a function that has been
+  // modified.
+  //
+
+  /// \brief Unlink the function from this module, returning it.
+  ///
+  /// Because this removes the function from the module, the call graph node is
+  /// destroyed.  This is only valid if the function does not call any other
+  /// functions (ie, there are no edges in it's CGN).  The easiest way to do
+  /// this is to dropAllReferences before calling this.
+  Function *removeFunctionFromModule(CallGraphNode *CGN);
+
+  /// \brief Similar to operator[], but this will insert a new CallGraphNode for
+  /// \c F if one does not already exist.
+  CallGraphNode *getOrInsertFunction(const Function *F);
+};
+
+/// \brief A node in the call graph for a module.
+///
+/// Typically represents a function in the call graph. There are also special
+/// "null" nodes used to represent theoretical entries in the call graph.
+class CallGraphNode {
+public:
+  /// \brief A pair of the calling instruction (a call or invoke)
+  /// and the call graph node being called.
+  typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
+
+public:
+  typedef std::vector<CallRecord> CalledFunctionsVector;
+
+  /// \brief Creates a node for the specified function.
+  inline CallGraphNode(Function *F) : F(F), NumReferences(0) {}
+
+  ~CallGraphNode() {
+    assert(NumReferences == 0 && "Node deleted while references remain");
+  }
+
+  typedef std::vector<CallRecord>::iterator iterator;
+  typedef std::vector<CallRecord>::const_iterator const_iterator;
+
+  /// \brief Returns the function that this call graph node represents.
+  Function *getFunction() const { return F; }
+
+  inline iterator begin() { return CalledFunctions.begin(); }
+  inline iterator end() { return CalledFunctions.end(); }
+  inline const_iterator begin() const { return CalledFunctions.begin(); }
+  inline const_iterator end() const { return CalledFunctions.end(); }
+  inline bool empty() const { return CalledFunctions.empty(); }
+  inline unsigned size() const { return (unsigned)CalledFunctions.size(); }
+
+  /// \brief Returns the number of other CallGraphNodes in this CallGraph that
+  /// reference this node in their callee list.
+  unsigned getNumReferences() const { return NumReferences; }
+
+  /// \brief Returns the i'th called function.
+  CallGraphNode *operator[](unsigned i) const {
+    assert(i < CalledFunctions.size() && "Invalid index");
+    return CalledFunctions[i].second;
+  }
+
+  /// \brief Print out this call graph node.
+  void dump() const;
+  void print(raw_ostream &OS) const;
+
+  //===---------------------------------------------------------------------
+  // Methods to keep a call graph up to date with a function that has been
+  // modified
+  //
+
+  /// \brief Removes all edges from this CallGraphNode to any functions it
+  /// calls.
+  void removeAllCalledFunctions() {
+    while (!CalledFunctions.empty()) {
+      CalledFunctions.back().second->DropRef();
+      CalledFunctions.pop_back();
+    }
+  }
+
+  /// \brief Moves all the callee information from N to this node.
+  void stealCalledFunctionsFrom(CallGraphNode *N) {
+    assert(CalledFunctions.empty() &&
+           "Cannot steal callsite information if I already have some");
+    std::swap(CalledFunctions, N->CalledFunctions);
+  }
+
+  /// \brief Adds a function to the list of functions called by this one.
+  void addCalledFunction(CallSite CS, CallGraphNode *M) {
+    assert(!CS.getInstruction() || !CS.getCalledFunction() ||
+           !CS.getCalledFunction()->isIntrinsic());
+    CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
+    M->AddRef();
+  }
+
+  void removeCallEdge(iterator I) {
+    I->second->DropRef();
+    *I = CalledFunctions.back();
+    CalledFunctions.pop_back();
+  }
+
+  /// \brief Removes the edge in the node for the specified call site.
+  ///
+  /// Note that this method takes linear time, so it should be used sparingly.
+  void removeCallEdgeFor(CallSite CS);
+
+  /// \brief Removes all call edges from this node to the specified callee
+  /// function.
+  ///
+  /// This takes more time to execute than removeCallEdgeTo, so it should not
+  /// be used unless necessary.
+  void removeAnyCallEdgeTo(CallGraphNode *Callee);
+
+  /// \brief Removes one edge associated with a null callsite from this node to
+  /// the specified callee function.
+  void removeOneAbstractEdgeTo(CallGraphNode *Callee);
+
+  /// \brief Replaces the edge in the node for the specified call site with a
+  /// new one.
+  ///
+  /// Note that this method takes linear time, so it should be used sparingly.
+  void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
+
+private:
+  friend class CallGraph;
+
+  AssertingVH<Function> F;
+
+  std::vector<CallRecord> CalledFunctions;
+
+  /// \brief The number of times that this CallGraphNode occurs in the
+  /// CalledFunctions array of this or other CallGraphNodes.
+  unsigned NumReferences;
+
+  CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+  void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+
+  void DropRef() { --NumReferences; }
+  void AddRef() { ++NumReferences; }
+
+  /// \brief A special function that should only be used by the CallGraph class.
+  void allReferencesDropped() { NumReferences = 0; }
+};
+
+/// \brief An analysis pass to compute the \c CallGraph for a \c Module.
+///
+/// This class implements the concept of an analysis pass used by the \c
+/// ModuleAnalysisManager to run an analysis over a module and cache the
+/// resulting data.
+class CallGraphAnalysis {
+public:
+  /// \brief A formulaic typedef to inform clients of the result type.
+  typedef CallGraph Result;
+
+  static void *ID() { return (void *)&PassID; }
+
+  /// \brief Compute the \c CallGraph for the module \c M.
+  ///
+  /// The real work here is done in the \c CallGraph constructor.
+  CallGraph run(Module *M) { return CallGraph(*M); }
+
+private:
+  static char PassID;
+};
+
+/// \brief The \c ModulePass which wraps up a \c CallGraph and the logic to
+/// build it.
+///
+/// This class exposes both the interface to the call graph container and the
+/// module pass which runs over a module of IR and produces the call graph. The
+/// call graph interface is entirelly a wrapper around a \c CallGraph object
+/// which is stored internally for each module.
+class CallGraphWrapperPass : public ModulePass {
+  std::unique_ptr<CallGraph> G;
+
+public:
+  static char ID; // Class identification, replacement for typeinfo
+
+  CallGraphWrapperPass();
+  virtual ~CallGraphWrapperPass();
+
+  /// \brief The internal \c CallGraph around which the rest of this interface
+  /// is wrapped.
+  const CallGraph &getCallGraph() const { return *G; }
+  CallGraph &getCallGraph() { return *G; }
+
+  typedef CallGraph::iterator iterator;
+  typedef CallGraph::const_iterator const_iterator;
+
+  /// \brief Returns the module the call graph corresponds to.
+  Module &getModule() const { return G->getModule(); }
+
+  inline iterator begin() { return G->begin(); }
+  inline iterator end() { return G->end(); }
+  inline const_iterator begin() const { return G->begin(); }
+  inline const_iterator end() const { return G->end(); }
+
+  /// \brief Returns the call graph node for the provided function.
+  inline const CallGraphNode *operator[](const Function *F) const {
+    return (*G)[F];
+  }
+
+  /// \brief Returns the call graph node for the provided function.
+  inline CallGraphNode *operator[](const Function *F) { return (*G)[F]; }
+
+  /// \brief Returns the \c CallGraphNode which is used to represent
+  /// undetermined calls into the callgraph.
+  CallGraphNode *getExternalCallingNode() const {
+    return G->getExternalCallingNode();
+  }
+
+  CallGraphNode *getCallsExternalNode() const {
+    return G->getCallsExternalNode();
+  }
+
+  //===---------------------------------------------------------------------
+  // Functions to keep a call graph up to date with a function that has been
+  // modified.
+  //
+
+  /// \brief Unlink the function from this module, returning it.
+  ///
+  /// Because this removes the function from the module, the call graph node is
+  /// destroyed.  This is only valid if the function does not call any other
+  /// functions (ie, there are no edges in it's CGN).  The easiest way to do
+  /// this is to dropAllReferences before calling this.
+  Function *removeFunctionFromModule(CallGraphNode *CGN) {
+    return G->removeFunctionFromModule(CGN);
+  }
+
+  /// \brief Similar to operator[], but this will insert a new CallGraphNode for
+  /// \c F if one does not already exist.
+  CallGraphNode *getOrInsertFunction(const Function *F) {
+    return G->getOrInsertFunction(F);
+  }
+
+  //===---------------------------------------------------------------------
+  // Implementation of the ModulePass interface needed here.
+  //
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  bool runOnModule(Module &M) override;
+  void releaseMemory() override;
+
+  void print(raw_ostream &o, const Module *) const override;
+  void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for call graphs so that they can be treated as
+// graphs by the generic graph algorithms.
+//
+
+// Provide graph traits for tranversing call graphs using standard graph
+// traversals.
+template <> struct GraphTraits<CallGraphNode *> {
+  typedef CallGraphNode NodeType;
+
+  typedef CallGraphNode::CallRecord CGNPairTy;
+  typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode *>
+  CGNDerefFun;
+
+  static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
+
+  typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+  }
+
+  static CallGraphNode *CGNDeref(CGNPairTy P) { return P.second; }
+};
+
+template <> struct GraphTraits<const CallGraphNode *> {
+  typedef const CallGraphNode NodeType;
+  typedef NodeType::const_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const CallGraphNode *CGN) { return CGN; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+
+template <>
+struct GraphTraits<CallGraph *> : public GraphTraits<CallGraphNode *> {
+  static NodeType *getEntryNode(CallGraph *CGN) {
+    return CGN->getExternalCallingNode(); // Start at the external node!
+  }
+  typedef std::pair<const Function *, CallGraphNode *> PairTy;
+  typedef std::pointer_to_unary_function<PairTy, CallGraphNode &> DerefFun;
+
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef mapped_iterator<CallGraph::iterator, DerefFun> nodes_iterator;
+  static nodes_iterator nodes_begin(CallGraph *CG) {
+    return map_iterator(CG->begin(), DerefFun(CGdereference));
+  }
+  static nodes_iterator nodes_end(CallGraph *CG) {
+    return map_iterator(CG->end(), DerefFun(CGdereference));
+  }
+
+  static CallGraphNode &CGdereference(PairTy P) { return *P.second; }
+};
+
+template <>
+struct GraphTraits<const CallGraph *> : public GraphTraits<
+                                            const CallGraphNode *> {
+  static NodeType *getEntryNode(const CallGraph *CGN) {
+    return CGN->getExternalCallingNode();
+  }
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef CallGraph::const_iterator nodes_iterator;
+  static nodes_iterator nodes_begin(const CallGraph *CG) { return CG->begin(); }
+  static nodes_iterator nodes_end(const CallGraph *CG) { return CG->end(); }
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in CallGraph.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(CallGraph)
+
+#endif
diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h
new file mode 100644
index 0000000..667e171
--- /dev/null
+++ b/include/llvm/Analysis/CallGraphSCCPass.h
@@ -0,0 +1,107 @@
+//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- 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 CallGraphSCCPass class, which is used for passes which
+// are implemented as bottom-up traversals on the call graph.  Because there may
+// be cycles in the call graph, passes of this type operate on the call-graph in
+// SCC order: that is, they process function bottom-up, except for recursive
+// functions, which they process all at once.
+//
+// These passes are inherently interprocedural, and are required to keep the
+// call graph up-to-date if they do anything which could modify it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
+#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class CallGraphNode;
+class CallGraph;
+class PMStack;
+class CallGraphSCC;
+  
+class CallGraphSCCPass : public Pass {
+public:
+  explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
+
+  /// createPrinterPass - Get a pass that prints the Module
+  /// corresponding to a CallGraph.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  using llvm::Pass::doInitialization;
+  using llvm::Pass::doFinalization;
+
+  /// doInitialization - This method is called before the SCC's of the program
+  /// has been processed, allowing the pass to do initialization as necessary.
+  virtual bool doInitialization(CallGraph &CG) {
+    return false;
+  }
+
+  /// runOnSCC - This method should be implemented by the subclass to perform
+  /// whatever action is necessary for the specified SCC.  Note that
+  /// non-recursive (or only self-recursive) functions will have an SCC size of
+  /// 1, where recursive portions of the call graph will have SCC size > 1.
+  ///
+  /// SCC passes that add or delete functions to the SCC are required to update
+  /// the SCC list, otherwise stale pointers may be dereferenced.
+  ///
+  virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
+
+  /// doFinalization - This method is called after the SCC's of the program has
+  /// been processed, allowing the pass to do final cleanup as necessary.
+  virtual bool doFinalization(CallGraph &CG) {
+    return false;
+  }
+
+  /// Assign pass manager to manager this pass
+  void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  PassManagerType getPotentialPassManagerType() const override {
+    return PMT_CallGraphPassManager;
+  }
+
+  /// getAnalysisUsage - For this class, we declare that we require and preserve
+  /// the call graph.  If the derived class implements this method, it should
+  /// always explicitly call the implementation here.
+  void getAnalysisUsage(AnalysisUsage &Info) const override;
+};
+
+/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. 
+class CallGraphSCC {
+  void *Context; // The CGPassManager object that is vending this.
+  std::vector<CallGraphNode*> Nodes;
+public:
+  CallGraphSCC(void *context) : Context(context) {}
+  
+  void initialize(CallGraphNode*const*I, CallGraphNode*const*E) {
+    Nodes.assign(I, E);
+  }
+  
+  bool isSingular() const { return Nodes.size() == 1; }
+  unsigned size() const { return Nodes.size(); }
+  
+  /// ReplaceNode - This informs the SCC and the pass manager that the specified
+  /// Old node has been deleted, and New is to be used in its place.
+  void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
+  
+  typedef std::vector<CallGraphNode*>::const_iterator iterator;
+  iterator begin() const { return Nodes.begin(); }
+  iterator end() const { return Nodes.end(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/CallPrinter.h b/include/llvm/Analysis/CallPrinter.h
new file mode 100644
index 0000000..5f5d160
--- /dev/null
+++ b/include/llvm/Analysis/CallPrinter.h
@@ -0,0 +1,27 @@
+//===-- CallPrinter.h - Call graph printer external interface ----*- 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 external functions that can be called to explicitly
+// instantiate the call graph printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CALLPRINTER_H
+#define LLVM_ANALYSIS_CALLPRINTER_H
+
+namespace llvm {
+
+  class ModulePass;
+
+  ModulePass *createCallGraphViewerPass();
+  ModulePass *createCallGraphPrinterPass();
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
new file mode 100644
index 0000000..8b7c7a9
--- /dev/null
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -0,0 +1,78 @@
+//===----- llvm/Analysis/CaptureTracking.h - Pointer capture ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains routines that help determine which pointers are captured.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
+#define LLVM_ANALYSIS_CAPTURETRACKING_H
+
+namespace llvm {
+
+  class Value;
+  class Use;
+  class Instruction;
+  class DominatorTree;
+
+  /// PointerMayBeCaptured - Return true if this pointer value may be captured
+  /// by the enclosing function (which is required to exist).  This routine can
+  /// be expensive, so consider caching the results.  The boolean ReturnCaptures
+  /// specifies whether returning the value (or part of it) from the function
+  /// counts as capturing it or not.  The boolean StoreCaptures specified
+  /// whether storing the value (or part of it) into memory anywhere
+  /// automatically counts as capturing it or not.
+  bool PointerMayBeCaptured(const Value *V,
+                            bool ReturnCaptures,
+                            bool StoreCaptures);
+
+  /// PointerMayBeCapturedBefore - Return true if this pointer value may be
+  /// captured by the enclosing function (which is required to exist). If a
+  /// DominatorTree is provided, only captures which happen before the given
+  /// instruction are considered. This routine can be expensive, so consider
+  /// caching the results.  The boolean ReturnCaptures specifies whether
+  /// returning the value (or part of it) from the function counts as capturing
+  /// it or not.  The boolean StoreCaptures specified whether storing the value
+  /// (or part of it) into memory anywhere automatically counts as capturing it
+  /// or not. Captures by the provided instruction are considered if the
+  /// final parameter is true.
+  bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
+                                  bool StoreCaptures, const Instruction *I,
+                                  DominatorTree *DT, bool IncludeI = false);
+
+  /// This callback is used in conjunction with PointerMayBeCaptured. In
+  /// addition to the interface here, you'll need to provide your own getters
+  /// to see whether anything was captured.
+  struct CaptureTracker {
+    virtual ~CaptureTracker();
+
+    /// tooManyUses - The depth of traversal has breached a limit. There may be
+    /// capturing instructions that will not be passed into captured().
+    virtual void tooManyUses() = 0;
+
+    /// shouldExplore - This is the use of a value derived from the pointer.
+    /// To prune the search (ie., assume that none of its users could possibly
+    /// capture) return false. To search it, return true.
+    ///
+    /// U->getUser() is always an Instruction.
+    virtual bool shouldExplore(const Use *U);
+
+    /// captured - Information about the pointer was captured by the user of
+    /// use U. Return true to stop the traversal or false to continue looking
+    /// for more capturing instructions.
+    virtual bool captured(const Use *U) = 0;
+  };
+
+  /// PointerMayBeCaptured - Visit the value and the values derived from it and
+  /// find values which appear to be capturing the pointer value. This feeds
+  /// results into and is controlled by the CaptureTracker object.
+  void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker);
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
new file mode 100644
index 0000000..04b39c1
--- /dev/null
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -0,0 +1,93 @@
+//===- CodeMetrics.h - Code cost measurements -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements various weight measurements for code, helping
+// the Inliner and other passes decide whether to duplicate its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CODEMETRICS_H
+#define LLVM_ANALYSIS_CODEMETRICS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/CallSite.h"
+
+namespace llvm {
+class BasicBlock;
+class Function;
+class Instruction;
+class DataLayout;
+class TargetTransformInfo;
+class Value;
+
+/// \brief Check whether a call will lower to something small.
+///
+/// This tests checks whether this callsite will lower to something
+/// significantly cheaper than a traditional call, often a single
+/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
+/// return true, so will this function.
+bool callIsSmall(ImmutableCallSite CS);
+
+/// \brief Utility to calculate the size and a few similar metrics for a set
+/// of basic blocks.
+struct CodeMetrics {
+  /// \brief True if this function contains a call to setjmp or other functions
+  /// with attribute "returns twice" without having the attribute itself.
+  bool exposesReturnsTwice;
+
+  /// \brief True if this function calls itself.
+  bool isRecursive;
+
+  /// \brief True if this function cannot be duplicated.
+  ///
+  /// True if this function contains one or more indirect branches, or it contains
+  /// one or more 'noduplicate' instructions.
+  bool notDuplicatable;
+
+  /// \brief True if this function calls alloca (in the C sense).
+  bool usesDynamicAlloca;
+
+  /// \brief Number of instructions in the analyzed blocks.
+  unsigned NumInsts;
+
+  /// \brief Number of analyzed blocks.
+  unsigned NumBlocks;
+
+  /// \brief Keeps track of basic block code size estimates.
+  DenseMap<const BasicBlock *, unsigned> NumBBInsts;
+
+  /// \brief Keep track of the number of calls to 'big' functions.
+  unsigned NumCalls;
+
+  /// \brief The number of calls to internal functions with a single caller.
+  ///
+  /// These are likely targets for future inlining, likely exposed by
+  /// interleaved devirtualization.
+  unsigned NumInlineCandidates;
+
+  /// \brief How many instructions produce vector values.
+  ///
+  /// The inliner is more aggressive with inlining vector kernels.
+  unsigned NumVectorInsts;
+
+  /// \brief How many 'ret' instructions the blocks contain.
+  unsigned NumRets;
+
+  CodeMetrics()
+      : exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
+        usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
+        NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
+
+  /// \brief Add information about a block to the current state.
+  void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
new file mode 100644
index 0000000..09d45ca
--- /dev/null
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -0,0 +1,104 @@
+//===-- ConstantFolding.h - Fold instructions into constants ----*- 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 routines for folding instructions into constants when all
+// operands are constants, for example "sub i32 1, 0" -> "1".
+//
+// Also, to supplement the basic VMCore ConstantExpr simplifications,
+// this file declares some additional folding routines that can make use of
+// DataLayout information. These functions cannot go in VMCore due to library
+// dependency issues.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTANTFOLDING_H
+#define LLVM_ANALYSIS_CONSTANTFOLDING_H
+
+namespace llvm {
+  class Constant;
+  class ConstantExpr;
+  class Instruction;
+  class DataLayout;
+  class TargetLibraryInfo;
+  class Function;
+  class Type;
+  template<typename T>
+  class ArrayRef;
+
+/// ConstantFoldInstruction - Try to constant fold the specified instruction.
+/// If successful, the constant result is returned, if not, null is returned.
+/// Note that this fails if not all of the operands are constant.  Otherwise,
+/// this function can only fail when attempting to fold instructions like loads
+/// and stores, which have no constant expression form.
+Constant *ConstantFoldInstruction(Instruction *I,
+                                  const DataLayout *TD = nullptr,
+                                  const TargetLibraryInfo *TLI = nullptr);
+
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified DataLayout.  If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
+                                         const DataLayout *TD = nullptr,
+                                         const TargetLibraryInfo *TLI =nullptr);
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified operands.  If successful, the constant result is returned, if not,
+/// null is returned.  Note that this function can fail when attempting to
+/// fold instructions like loads and stores, which have no constant expression
+/// form.
+///
+Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
+                                   ArrayRef<Constant *> Ops,
+                                   const DataLayout *TD = nullptr,
+                                   const TargetLibraryInfo *TLI = nullptr);
+
+/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
+/// instruction (icmp/fcmp) with the specified operands.  If it fails, it
+/// returns a constant expression of the specified operands.
+///
+Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
+                                          Constant *LHS, Constant *RHS,
+                                          const DataLayout *TD = nullptr,
+                                          const TargetLibraryInfo *TLI=nullptr);
+
+/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
+/// instruction with the specified operands and indices.  The constant result is
+/// returned if successful; if not, null is returned.
+Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
+                                             ArrayRef<unsigned> Idxs);
+
+/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
+/// produce if it is constant and determinable.  If this is not determinable,
+/// return null.
+Constant *ConstantFoldLoadFromConstPtr(Constant *C,
+                                       const DataLayout *TD = nullptr);
+
+/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
+/// getelementptr constantexpr, return the constant value being addressed by the
+/// constant expression, or null if something is funny and we can't decide.
+Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE);
+
+/// ConstantFoldLoadThroughGEPIndices - Given a constant and getelementptr
+/// indices (with an *implied* zero pointer index that is not in the list),
+/// return the constant value being addressed by a virtual load, or null if
+/// something is funny and we can't decide.
+Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
+                                            ArrayRef<Constant*> Indices);
+
+/// canConstantFoldCallTo - Return true if its even possible to fold a call to
+/// the specified function.
+bool canConstantFoldCallTo(const Function *F);
+
+/// ConstantFoldCall - Attempt to constant fold a call to the specified function
+/// with the specified arguments, returning null if unsuccessful.
+Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
+                           const TargetLibraryInfo *TLI = nullptr);
+}
+
+#endif
diff --git a/include/llvm/Analysis/ConstantsScanner.h b/include/llvm/Analysis/ConstantsScanner.h
new file mode 100644
index 0000000..d3d0a44
--- /dev/null
+++ b/include/llvm/Analysis/ConstantsScanner.h
@@ -0,0 +1,93 @@
+//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements an iterator to walk through the constants referenced by
+// a method.  This is used by the Bitcode & Assembly writers to build constant
+// pools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
+#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
+
+#include "llvm/IR/InstIterator.h"
+
+namespace llvm {
+
+class Constant;
+
+class constant_iterator : public std::iterator<std::forward_iterator_tag,
+                                               const Constant, ptrdiff_t> {
+  const_inst_iterator InstI;                // Method instruction iterator
+  unsigned OpIdx;                           // Operand index
+
+  typedef constant_iterator _Self;
+
+  inline bool isAtConstant() const {
+    assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
+           "isAtConstant called with invalid arguments!");
+    return isa<Constant>(InstI->getOperand(OpIdx));
+  }
+
+public:
+  inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
+    // Advance to first constant... if we are not already at constant or end
+    if (InstI != inst_end(F) &&                            // InstI is valid?
+        (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
+      operator++();
+  }
+
+  inline constant_iterator(const Function *F, bool)   // end ctor
+    : InstI(inst_end(F)), OpIdx(0) {
+  }
+
+  inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
+                                                        InstI == x.InstI; }
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  inline pointer operator*() const {
+    assert(isAtConstant() && "Dereferenced an iterator at the end!");
+    return cast<Constant>(InstI->getOperand(OpIdx));
+  }
+  inline pointer operator->() const { return operator*(); }
+
+  inline _Self& operator++() {   // Preincrement implementation
+    ++OpIdx;
+    do {
+      unsigned NumOperands = InstI->getNumOperands();
+      while (OpIdx < NumOperands && !isAtConstant()) {
+        ++OpIdx;
+      }
+
+      if (OpIdx < NumOperands) return *this;  // Found a constant!
+      ++InstI;
+      OpIdx = 0;
+    } while (!InstI.atEnd());
+
+    return *this;  // At the end of the method
+  }
+
+  inline _Self operator++(int) { // Postincrement
+    _Self tmp = *this; ++*this; return tmp;
+  }
+
+  inline bool atEnd() const { return InstI.atEnd(); }
+};
+
+inline constant_iterator constant_begin(const Function *F) {
+  return constant_iterator(F);
+}
+
+inline constant_iterator constant_end(const Function *F) {
+  return constant_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
new file mode 100644
index 0000000..53c832c
--- /dev/null
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -0,0 +1,159 @@
+//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Templates to create dotty viewer and printer passes for GraphTraits graphs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
+#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
+
+#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+
+/// \brief Default traits class for extracting a graph from an analysis pass.
+///
+/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
+template <typename AnalysisT, typename GraphT = AnalysisT *>
+struct DefaultAnalysisGraphTraits {
+  static GraphT getGraph(AnalysisT *A) { return A; }
+};
+
+template <
+    typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+    typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsViewer : public FunctionPass {
+public:
+  DOTGraphTraitsViewer(StringRef GraphName, char &ID)
+      : FunctionPass(ID), Name(GraphName) {}
+
+  bool runOnFunction(Function &F) override {
+    GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+    std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
+    std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
+    ViewGraph(Graph, Name, IsSimple, Title);
+
+    return false;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    AU.addRequired<AnalysisT>();
+  }
+
+private:
+  std::string Name;
+};
+
+template <
+    typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+    typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsPrinter : public FunctionPass {
+public:
+  DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
+      : FunctionPass(ID), Name(GraphName) {}
+
+  bool runOnFunction(Function &F) override {
+    GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+    std::string Filename = Name + "." + F.getName().str() + ".dot";
+    std::string ErrorInfo;
+
+    errs() << "Writing '" << Filename << "'...";
+
+    raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+    std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
+    std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
+    if (ErrorInfo.empty())
+      WriteGraph(File, Graph, IsSimple, Title);
+    else
+      errs() << "  error opening file for writing!";
+    errs() << "\n";
+
+    return false;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    AU.addRequired<AnalysisT>();
+  }
+
+private:
+  std::string Name;
+};
+
+template <
+    typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+    typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsModuleViewer : public ModulePass {
+public:
+  DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
+      : ModulePass(ID), Name(GraphName) {}
+
+  bool runOnModule(Module &M) override {
+    GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+    std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
+
+    ViewGraph(Graph, Name, IsSimple, Title);
+
+    return false;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    AU.addRequired<AnalysisT>();
+  }
+
+private:
+  std::string Name;
+};
+
+template <
+    typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+    typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
+class DOTGraphTraitsModulePrinter : public ModulePass {
+public:
+  DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
+      : ModulePass(ID), Name(GraphName) {}
+
+  bool runOnModule(Module &M) override {
+    GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+    std::string Filename = Name + ".dot";
+    std::string ErrorInfo;
+
+    errs() << "Writing '" << Filename << "'...";
+
+    raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+    std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
+
+    if (ErrorInfo.empty())
+      WriteGraph(File, Graph, IsSimple, Title);
+    else
+      errs() << "  error opening file for writing!";
+    errs() << "\n";
+
+    return false;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    AU.addRequired<AnalysisT>();
+  }
+
+private:
+  std::string Name;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
new file mode 100644
index 0000000..279755e
--- /dev/null
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -0,0 +1,934 @@
+//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DependenceAnalysis is an LLVM pass that analyses dependences between memory
+// accesses. Currently, it is an implementation of the approach described in
+//
+//            Practical Dependence Testing
+//            Goff, Kennedy, Tseng
+//            PLDI 1991
+//
+// There's a single entry point that analyzes the dependence between a pair
+// of memory references in a function, returning either NULL, for no dependence,
+// or a more-or-less detailed description of the dependence between them.
+//
+// This pass exists to support the DependenceGraph pass. There are two separate
+// passes because there's a useful separation of concerns. A dependence exists
+// if two conditions are met:
+//
+//    1) Two instructions reference the same memory location, and
+//    2) There is a flow of control leading from one instruction to the other.
+//
+// DependenceAnalysis attacks the first condition; DependenceGraph will attack
+// the second (it's not yet ready).
+//
+// Please note that this is work in progress and the interface is subject to
+// change.
+//
+// Plausible changes:
+//    Return a set of more precise dependences instead of just one dependence
+//    summarizing all.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
+#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
+
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class AliasAnalysis;
+  class Loop;
+  class LoopInfo;
+  class ScalarEvolution;
+  class SCEV;
+  class SCEVConstant;
+  class raw_ostream;
+
+  /// Dependence - This class represents a dependence between two memory
+  /// memory references in a function. It contains minimal information and
+  /// is used in the very common situation where the compiler is unable to
+  /// determine anything beyond the existence of a dependence; that is, it
+  /// represents a confused dependence (see also FullDependence). In most
+  /// cases (for output, flow, and anti dependences), the dependence implies
+  /// an ordering, where the source must precede the destination; in contrast,
+  /// input dependences are unordered.
+  ///
+  /// When a dependence graph is built, each Dependence will be a member of
+  /// the set of predecessor edges for its destination instruction and a set
+  /// if successor edges for its source instruction. These sets are represented
+  /// as singly-linked lists, with the "next" fields stored in the dependence
+  /// itelf.
+  class Dependence {
+  public:
+    Dependence(Instruction *Source,
+               Instruction *Destination) :
+      Src(Source),
+      Dst(Destination),
+      NextPredecessor(nullptr),
+      NextSuccessor(nullptr) {}
+    virtual ~Dependence() {}
+
+    /// Dependence::DVEntry - Each level in the distance/direction vector
+    /// has a direction (or perhaps a union of several directions), and
+    /// perhaps a distance.
+    struct DVEntry {
+      enum { NONE = 0,
+             LT = 1,
+             EQ = 2,
+             LE = 3,
+             GT = 4,
+             NE = 5,
+             GE = 6,
+             ALL = 7 };
+      unsigned char Direction : 3; // Init to ALL, then refine.
+      bool Scalar    : 1; // Init to true.
+      bool PeelFirst : 1; // Peeling the first iteration will break dependence.
+      bool PeelLast  : 1; // Peeling the last iteration will break the dependence.
+      bool Splitable : 1; // Splitting the loop will break dependence.
+      const SCEV *Distance; // NULL implies no distance available.
+      DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false),
+                  PeelLast(false), Splitable(false), Distance(nullptr) { }
+    };
+
+    /// getSrc - Returns the source instruction for this dependence.
+    ///
+    Instruction *getSrc() const { return Src; }
+
+    /// getDst - Returns the destination instruction for this dependence.
+    ///
+    Instruction *getDst() const { return Dst; }
+
+    /// isInput - Returns true if this is an input dependence.
+    ///
+    bool isInput() const;
+
+    /// isOutput - Returns true if this is an output dependence.
+    ///
+    bool isOutput() const;
+
+    /// isFlow - Returns true if this is a flow (aka true) dependence.
+    ///
+    bool isFlow() const;
+
+    /// isAnti - Returns true if this is an anti dependence.
+    ///
+    bool isAnti() const;
+
+    /// isOrdered - Returns true if dependence is Output, Flow, or Anti
+    ///
+    bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
+
+    /// isUnordered - Returns true if dependence is Input
+    ///
+    bool isUnordered() const { return isInput(); }
+
+    /// isLoopIndependent - Returns true if this is a loop-independent
+    /// dependence.
+    virtual bool isLoopIndependent() const { return true; }
+
+    /// isConfused - Returns true if this dependence is confused
+    /// (the compiler understands nothing and makes worst-case
+    /// assumptions).
+    virtual bool isConfused() const { return true; }
+
+    /// isConsistent - Returns true if this dependence is consistent
+    /// (occurs every time the source and destination are executed).
+    virtual bool isConsistent() const { return false; }
+
+    /// getLevels - Returns the number of common loops surrounding the
+    /// source and destination of the dependence.
+    virtual unsigned getLevels() const { return 0; }
+
+    /// getDirection - Returns the direction associated with a particular
+    /// level.
+    virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
+
+    /// getDistance - Returns the distance (or NULL) associated with a
+    /// particular level.
+    virtual const SCEV *getDistance(unsigned Level) const { return nullptr; }
+
+    /// isPeelFirst - Returns true if peeling the first iteration from
+    /// this loop will break this dependence.
+    virtual bool isPeelFirst(unsigned Level) const { return false; }
+
+    /// isPeelLast - Returns true if peeling the last iteration from
+    /// this loop will break this dependence.
+    virtual bool isPeelLast(unsigned Level) const { return false; }
+
+    /// isSplitable - Returns true if splitting this loop will break
+    /// the dependence.
+    virtual bool isSplitable(unsigned Level) const { return false; }
+
+    /// isScalar - Returns true if a particular level is scalar; that is,
+    /// if no subscript in the source or destination mention the induction
+    /// variable associated with the loop at this level.
+    virtual bool isScalar(unsigned Level) const;
+
+    /// getNextPredecessor - Returns the value of the NextPredecessor
+    /// field.
+    const Dependence *getNextPredecessor() const {
+      return NextPredecessor;
+    }
+    
+    /// getNextSuccessor - Returns the value of the NextSuccessor
+    /// field.
+    const Dependence *getNextSuccessor() const {
+      return NextSuccessor;
+    }
+    
+    /// setNextPredecessor - Sets the value of the NextPredecessor
+    /// field.
+    void setNextPredecessor(const Dependence *pred) {
+      NextPredecessor = pred;
+    }
+    
+    /// setNextSuccessor - Sets the value of the NextSuccessor
+    /// field.
+    void setNextSuccessor(const Dependence *succ) {
+      NextSuccessor = succ;
+    }
+    
+    /// dump - For debugging purposes, dumps a dependence to OS.
+    ///
+    void dump(raw_ostream &OS) const;
+  private:
+    Instruction *Src, *Dst;
+    const Dependence *NextPredecessor, *NextSuccessor;
+    friend class DependenceAnalysis;
+  };
+
+
+  /// FullDependence - This class represents a dependence between two memory
+  /// references in a function. It contains detailed information about the
+  /// dependence (direction vectors, etc.) and is used when the compiler is
+  /// able to accurately analyze the interaction of the references; that is,
+  /// it is not a confused dependence (see Dependence). In most cases
+  /// (for output, flow, and anti dependences), the dependence implies an
+  /// ordering, where the source must precede the destination; in contrast,
+  /// input dependences are unordered.
+  class FullDependence : public Dependence {
+  public:
+    FullDependence(Instruction *Src,
+                   Instruction *Dst,
+                   bool LoopIndependent,
+                   unsigned Levels);
+    ~FullDependence() {
+      delete[] DV;
+    }
+
+    /// isLoopIndependent - Returns true if this is a loop-independent
+    /// dependence.
+    bool isLoopIndependent() const override { return LoopIndependent; }
+
+    /// isConfused - Returns true if this dependence is confused
+    /// (the compiler understands nothing and makes worst-case
+    /// assumptions).
+    bool isConfused() const override { return false; }
+
+    /// isConsistent - Returns true if this dependence is consistent
+    /// (occurs every time the source and destination are executed).
+    bool isConsistent() const override { return Consistent; }
+
+    /// getLevels - Returns the number of common loops surrounding the
+    /// source and destination of the dependence.
+    unsigned getLevels() const override { return Levels; }
+
+    /// getDirection - Returns the direction associated with a particular
+    /// level.
+    unsigned getDirection(unsigned Level) const override;
+
+    /// getDistance - Returns the distance (or NULL) associated with a
+    /// particular level.
+    const SCEV *getDistance(unsigned Level) const override;
+
+    /// isPeelFirst - Returns true if peeling the first iteration from
+    /// this loop will break this dependence.
+    bool isPeelFirst(unsigned Level) const override;
+
+    /// isPeelLast - Returns true if peeling the last iteration from
+    /// this loop will break this dependence.
+    bool isPeelLast(unsigned Level) const override;
+
+    /// isSplitable - Returns true if splitting the loop will break
+    /// the dependence.
+    bool isSplitable(unsigned Level) const override;
+
+    /// isScalar - Returns true if a particular level is scalar; that is,
+    /// if no subscript in the source or destination mention the induction
+    /// variable associated with the loop at this level.
+    bool isScalar(unsigned Level) const override;
+  private:
+    unsigned short Levels;
+    bool LoopIndependent;
+    bool Consistent; // Init to true, then refine.
+    DVEntry *DV;
+    friend class DependenceAnalysis;
+  };
+
+
+  /// DependenceAnalysis - This class is the main dependence-analysis driver.
+  ///
+  class DependenceAnalysis : public FunctionPass {
+    void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
+    DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
+  public:
+    /// depends - Tests for a dependence between the Src and Dst instructions.
+    /// Returns NULL if no dependence; otherwise, returns a Dependence (or a
+    /// FullDependence) with as much information as can be gleaned.
+    /// The flag PossiblyLoopIndependent should be set by the caller
+    /// if it appears that control flow can reach from Src to Dst
+    /// without traversing a loop back edge.
+    Dependence *depends(Instruction *Src,
+                        Instruction *Dst,
+                        bool PossiblyLoopIndependent);
+
+    /// getSplitIteration - Give a dependence that's splittable at some
+    /// particular level, return the iteration that should be used to split
+    /// the loop.
+    ///
+    /// Generally, the dependence analyzer will be used to build
+    /// a dependence graph for a function (basically a map from instructions
+    /// to dependences). Looking for cycles in the graph shows us loops
+    /// that cannot be trivially vectorized/parallelized.
+    ///
+    /// We can try to improve the situation by examining all the dependences
+    /// that make up the cycle, looking for ones we can break.
+    /// Sometimes, peeling the first or last iteration of a loop will break
+    /// dependences, and there are flags for those possibilities.
+    /// Sometimes, splitting a loop at some other iteration will do the trick,
+    /// and we've got a flag for that case. Rather than waste the space to
+    /// record the exact iteration (since we rarely know), we provide
+    /// a method that calculates the iteration. It's a drag that it must work
+    /// from scratch, but wonderful in that it's possible.
+    ///
+    /// Here's an example:
+    ///
+    ///    for (i = 0; i < 10; i++)
+    ///        A[i] = ...
+    ///        ... = A[11 - i]
+    ///
+    /// There's a loop-carried flow dependence from the store to the load,
+    /// found by the weak-crossing SIV test. The dependence will have a flag,
+    /// indicating that the dependence can be broken by splitting the loop.
+    /// Calling getSplitIteration will return 5.
+    /// Splitting the loop breaks the dependence, like so:
+    ///
+    ///    for (i = 0; i <= 5; i++)
+    ///        A[i] = ...
+    ///        ... = A[11 - i]
+    ///    for (i = 6; i < 10; i++)
+    ///        A[i] = ...
+    ///        ... = A[11 - i]
+    ///
+    /// breaks the dependence and allows us to vectorize/parallelize
+    /// both loops.
+    const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level);
+
+  private:
+    AliasAnalysis *AA;
+    ScalarEvolution *SE;
+    LoopInfo *LI;
+    Function *F;
+
+    /// Subscript - This private struct represents a pair of subscripts from
+    /// a pair of potentially multi-dimensional array references. We use a
+    /// vector of them to guide subscript partitioning.
+    struct Subscript {
+      const SCEV *Src;
+      const SCEV *Dst;
+      enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
+      SmallBitVector Loops;
+      SmallBitVector GroupLoops;
+      SmallBitVector Group;
+    };
+
+    struct CoefficientInfo {
+      const SCEV *Coeff;
+      const SCEV *PosPart;
+      const SCEV *NegPart;
+      const SCEV *Iterations;
+    };
+
+    struct BoundInfo {
+      const SCEV *Iterations;
+      const SCEV *Upper[8];
+      const SCEV *Lower[8];
+      unsigned char Direction;
+      unsigned char DirSet;
+    };
+
+    /// Constraint - This private class represents a constraint, as defined
+    /// in the paper
+    ///
+    ///           Practical Dependence Testing
+    ///           Goff, Kennedy, Tseng
+    ///           PLDI 1991
+    ///
+    /// There are 5 kinds of constraint, in a hierarchy.
+    ///   1) Any - indicates no constraint, any dependence is possible.
+    ///   2) Line - A line ax + by = c, where a, b, and c are parameters,
+    ///             representing the dependence equation.
+    ///   3) Distance - The value d of the dependence distance;
+    ///   4) Point - A point <x, y> representing the dependence from
+    ///              iteration x to iteration y.
+    ///   5) Empty - No dependence is possible.
+    class Constraint {
+    private:
+      enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
+      ScalarEvolution *SE;
+      const SCEV *A;
+      const SCEV *B;
+      const SCEV *C;
+      const Loop *AssociatedLoop;
+    public:
+      /// isEmpty - Return true if the constraint is of kind Empty.
+      bool isEmpty() const { return Kind == Empty; }
+
+      /// isPoint - Return true if the constraint is of kind Point.
+      bool isPoint() const { return Kind == Point; }
+
+      /// isDistance - Return true if the constraint is of kind Distance.
+      bool isDistance() const { return Kind == Distance; }
+
+      /// isLine - Return true if the constraint is of kind Line.
+      /// Since Distance's can also be represented as Lines, we also return
+      /// true if the constraint is of kind Distance.
+      bool isLine() const { return Kind == Line || Kind == Distance; }
+
+      /// isAny - Return true if the constraint is of kind Any;
+      bool isAny() const { return Kind == Any; }
+
+      /// getX - If constraint is a point <X, Y>, returns X.
+      /// Otherwise assert.
+      const SCEV *getX() const;
+
+      /// getY - If constraint is a point <X, Y>, returns Y.
+      /// Otherwise assert.
+      const SCEV *getY() const;
+
+      /// getA - If constraint is a line AX + BY = C, returns A.
+      /// Otherwise assert.
+      const SCEV *getA() const;
+
+      /// getB - If constraint is a line AX + BY = C, returns B.
+      /// Otherwise assert.
+      const SCEV *getB() const;
+
+      /// getC - If constraint is a line AX + BY = C, returns C.
+      /// Otherwise assert.
+      const SCEV *getC() const;
+
+      /// getD - If constraint is a distance, returns D.
+      /// Otherwise assert.
+      const SCEV *getD() const;
+
+      /// getAssociatedLoop - Returns the loop associated with this constraint.
+      const Loop *getAssociatedLoop() const;
+
+      /// setPoint - Change a constraint to Point.
+      void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
+
+      /// setLine - Change a constraint to Line.
+      void setLine(const SCEV *A, const SCEV *B,
+                   const SCEV *C, const Loop *CurrentLoop);
+
+      /// setDistance - Change a constraint to Distance.
+      void setDistance(const SCEV *D, const Loop *CurrentLoop);
+
+      /// setEmpty - Change a constraint to Empty.
+      void setEmpty();
+
+      /// setAny - Change a constraint to Any.
+      void setAny(ScalarEvolution *SE);
+
+      /// dump - For debugging purposes. Dumps the constraint
+      /// out to OS.
+      void dump(raw_ostream &OS) const;
+    };
+
+
+    /// establishNestingLevels - Examines the loop nesting of the Src and Dst
+    /// instructions and establishes their shared loops. Sets the variables
+    /// CommonLevels, SrcLevels, and MaxLevels.
+    /// The source and destination instructions needn't be contained in the same
+    /// loop. The routine establishNestingLevels finds the level of most deeply
+    /// nested loop that contains them both, CommonLevels. An instruction that's
+    /// not contained in a loop is at level = 0. MaxLevels is equal to the level
+    /// of the source plus the level of the destination, minus CommonLevels.
+    /// This lets us allocate vectors MaxLevels in length, with room for every
+    /// distinct loop referenced in both the source and destination subscripts.
+    /// The variable SrcLevels is the nesting depth of the source instruction.
+    /// It's used to help calculate distinct loops referenced by the destination.
+    /// Here's the map from loops to levels:
+    ///            0 - unused
+    ///            1 - outermost common loop
+    ///          ... - other common loops
+    /// CommonLevels - innermost common loop
+    ///          ... - loops containing Src but not Dst
+    ///    SrcLevels - innermost loop containing Src but not Dst
+    ///          ... - loops containing Dst but not Src
+    ///    MaxLevels - innermost loop containing Dst but not Src
+    /// Consider the follow code fragment:
+    ///    for (a = ...) {
+    ///      for (b = ...) {
+    ///        for (c = ...) {
+    ///          for (d = ...) {
+    ///            A[] = ...;
+    ///          }
+    ///        }
+    ///        for (e = ...) {
+    ///          for (f = ...) {
+    ///            for (g = ...) {
+    ///              ... = A[];
+    ///            }
+    ///          }
+    ///        }
+    ///      }
+    ///    }
+    /// If we're looking at the possibility of a dependence between the store
+    /// to A (the Src) and the load from A (the Dst), we'll note that they
+    /// have 2 loops in common, so CommonLevels will equal 2 and the direction
+    /// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
+    /// A map from loop names to level indices would look like
+    ///     a - 1
+    ///     b - 2 = CommonLevels
+    ///     c - 3
+    ///     d - 4 = SrcLevels
+    ///     e - 5
+    ///     f - 6
+    ///     g - 7 = MaxLevels
+    void establishNestingLevels(const Instruction *Src,
+                                const Instruction *Dst);
+
+    unsigned CommonLevels, SrcLevels, MaxLevels;
+
+    /// mapSrcLoop - Given one of the loops containing the source, return
+    /// its level index in our numbering scheme.
+    unsigned mapSrcLoop(const Loop *SrcLoop) const;
+
+    /// mapDstLoop - Given one of the loops containing the destination,
+    /// return its level index in our numbering scheme.
+    unsigned mapDstLoop(const Loop *DstLoop) const;
+
+    /// isLoopInvariant - Returns true if Expression is loop invariant
+    /// in LoopNest.
+    bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
+
+    /// removeMatchingExtensions - Examines a subscript pair.
+    /// If the source and destination are identically sign (or zero)
+    /// extended, it strips off the extension in an effort to
+    /// simplify the actual analysis.
+    void removeMatchingExtensions(Subscript *Pair);
+
+    /// collectCommonLoops - Finds the set of loops from the LoopNest that
+    /// have a level <= CommonLevels and are referred to by the SCEV Expression.
+    void collectCommonLoops(const SCEV *Expression,
+                            const Loop *LoopNest,
+                            SmallBitVector &Loops) const;
+
+    /// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
+    /// linear. Collect the set of loops mentioned by Src.
+    bool checkSrcSubscript(const SCEV *Src,
+                           const Loop *LoopNest,
+                           SmallBitVector &Loops);
+
+    /// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
+    /// linear. Collect the set of loops mentioned by Dst.
+    bool checkDstSubscript(const SCEV *Dst,
+                           const Loop *LoopNest,
+                           SmallBitVector &Loops);
+
+    /// isKnownPredicate - Compare X and Y using the predicate Pred.
+    /// Basically a wrapper for SCEV::isKnownPredicate,
+    /// but tries harder, especially in the presence of sign and zero
+    /// extensions and symbolics.
+    bool isKnownPredicate(ICmpInst::Predicate Pred,
+                          const SCEV *X,
+                          const SCEV *Y) const;
+
+    /// collectUpperBound - All subscripts are the same type (on my machine,
+    /// an i64). The loop bound may be a smaller type. collectUpperBound
+    /// find the bound, if available, and zero extends it to the Type T.
+    /// (I zero extend since the bound should always be >= 0.)
+    /// If no upper bound is available, return NULL.
+    const SCEV *collectUpperBound(const Loop *l, Type *T) const;
+
+    /// collectConstantUpperBound - Calls collectUpperBound(), then
+    /// attempts to cast it to SCEVConstant. If the cast fails,
+    /// returns NULL.
+    const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;
+
+    /// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
+    /// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
+    /// Collects the associated loops in a set.
+    Subscript::ClassificationKind classifyPair(const SCEV *Src,
+                                           const Loop *SrcLoopNest,
+                                           const SCEV *Dst,
+                                           const Loop *DstLoopNest,
+                                           SmallBitVector &Loops);
+
+    /// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// If the dependence isn't proven to exist,
+    /// marks the Result as inconsistent.
+    bool testZIV(const SCEV *Src,
+                 const SCEV *Dst,
+                 FullDependence &Result) const;
+
+    /// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
+    /// Things of the form [c1 + a1*i] and [c2 + a2*j], where
+    /// i and j are induction variables, c1 and c2 are loop invariant,
+    /// and a1 and a2 are constant.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction vector entry and, when possible,
+    /// the distance vector entry.
+    /// If the dependence isn't proven to exist,
+    /// marks the Result as inconsistent.
+    bool testSIV(const SCEV *Src,
+                 const SCEV *Dst,
+                 unsigned &Level,
+                 FullDependence &Result,
+                 Constraint &NewConstraint,
+                 const SCEV *&SplitIter) const;
+
+    /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
+    /// Things of the form [c1 + a1*i] and [c2 + a2*j]
+    /// where i and j are induction variables, c1 and c2 are loop invariant,
+    /// and a1 and a2 are constant.
+    /// With minor algebra, this test can also be used for things like
+    /// [c1 + a1*i + a2*j][c2].
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Marks the Result as inconsistent.
+    bool testRDIV(const SCEV *Src,
+                  const SCEV *Dst,
+                  FullDependence &Result) const;
+
+    /// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
+    /// Returns true if dependence disproved.
+    /// Can sometimes refine direction vectors.
+    bool testMIV(const SCEV *Src,
+                 const SCEV *Dst,
+                 const SmallBitVector &Loops,
+                 FullDependence &Result) const;
+
+    /// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
+    /// for dependence.
+    /// Things of the form [c1 + a*i] and [c2 + a*i],
+    /// where i is an induction variable, c1 and c2 are loop invariant,
+    /// and a is a constant
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction and distance.
+    bool strongSIVtest(const SCEV *Coeff,
+                       const SCEV *SrcConst,
+                       const SCEV *DstConst,
+                       const Loop *CurrentLoop,
+                       unsigned Level,
+                       FullDependence &Result,
+                       Constraint &NewConstraint) const;
+
+    /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
+    /// (Src and Dst) for dependence.
+    /// Things of the form [c1 + a*i] and [c2 - a*i],
+    /// where i is an induction variable, c1 and c2 are loop invariant,
+    /// and a is a constant.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction entry.
+    /// Set consistent to false.
+    /// Marks the dependence as splitable.
+    bool weakCrossingSIVtest(const SCEV *SrcCoeff,
+                             const SCEV *SrcConst,
+                             const SCEV *DstConst,
+                             const Loop *CurrentLoop,
+                             unsigned Level,
+                             FullDependence &Result,
+                             Constraint &NewConstraint,
+                             const SCEV *&SplitIter) const;
+
+    /// ExactSIVtest - Tests the SIV subscript pair
+    /// (Src and Dst) for dependence.
+    /// Things of the form [c1 + a1*i] and [c2 + a2*i],
+    /// where i is an induction variable, c1 and c2 are loop invariant,
+    /// and a1 and a2 are constant.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction entry.
+    /// Set consistent to false.
+    bool exactSIVtest(const SCEV *SrcCoeff,
+                      const SCEV *DstCoeff,
+                      const SCEV *SrcConst,
+                      const SCEV *DstConst,
+                      const Loop *CurrentLoop,
+                      unsigned Level,
+                      FullDependence &Result,
+                      Constraint &NewConstraint) const;
+
+    /// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
+    /// (Src and Dst) for dependence.
+    /// Things of the form [c1] and [c2 + a*i],
+    /// where i is an induction variable, c1 and c2 are loop invariant,
+    /// and a is a constant. See also weakZeroDstSIVtest.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction entry.
+    /// Set consistent to false.
+    /// If loop peeling will break the dependence, mark appropriately.
+    bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
+                            const SCEV *SrcConst,
+                            const SCEV *DstConst,
+                            const Loop *CurrentLoop,
+                            unsigned Level,
+                            FullDependence &Result,
+                            Constraint &NewConstraint) const;
+
+    /// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
+    /// (Src and Dst) for dependence.
+    /// Things of the form [c1 + a*i] and [c2],
+    /// where i is an induction variable, c1 and c2 are loop invariant,
+    /// and a is a constant. See also weakZeroSrcSIVtest.
+    /// Returns true if any possible dependence is disproved.
+    /// If there might be a dependence, returns false.
+    /// Sets appropriate direction entry.
+    /// Set consistent to false.
+    /// If loop peeling will break the dependence, mark appropriately.
+    bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
+                            const SCEV *SrcConst,
+                            const SCEV *DstConst,
+                            const Loop *CurrentLoop,
+                            unsigned Level,
+                            FullDependence &Result,
+                            Constraint &NewConstraint) const;
+
+    /// exactRDIVtest - Tests the RDIV subscript pair for dependence.
+    /// Things of the form [c1 + a*i] and [c2 + b*j],
+    /// where i and j are induction variable, c1 and c2 are loop invariant,
+    /// and a and b are constants.
+    /// Returns true if any possible dependence is disproved.
+    /// Marks the result as inconsistent.
+    /// Works in some cases that symbolicRDIVtest doesn't,
+    /// and vice versa.
+    bool exactRDIVtest(const SCEV *SrcCoeff,
+                       const SCEV *DstCoeff,
+                       const SCEV *SrcConst,
+                       const SCEV *DstConst,
+                       const Loop *SrcLoop,
+                       const Loop *DstLoop,
+                       FullDependence &Result) const;
+
+    /// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
+    /// Things of the form [c1 + a*i] and [c2 + b*j],
+    /// where i and j are induction variable, c1 and c2 are loop invariant,
+    /// and a and b are constants.
+    /// Returns true if any possible dependence is disproved.
+    /// Marks the result as inconsistent.
+    /// Works in some cases that exactRDIVtest doesn't,
+    /// and vice versa. Can also be used as a backup for
+    /// ordinary SIV tests.
+    bool symbolicRDIVtest(const SCEV *SrcCoeff,
+                          const SCEV *DstCoeff,
+                          const SCEV *SrcConst,
+                          const SCEV *DstConst,
+                          const Loop *SrcLoop,
+                          const Loop *DstLoop) const;
+
+    /// gcdMIVtest - Tests an MIV subscript pair for dependence.
+    /// Returns true if any possible dependence is disproved.
+    /// Marks the result as inconsistent.
+    /// Can sometimes disprove the equal direction for 1 or more loops.
+    //  Can handle some symbolics that even the SIV tests don't get,
+    /// so we use it as a backup for everything.
+    bool gcdMIVtest(const SCEV *Src,
+                    const SCEV *Dst,
+                    FullDependence &Result) const;
+
+    /// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
+    /// Returns true if any possible dependence is disproved.
+    /// Marks the result as inconsistent.
+    /// Computes directions.
+    bool banerjeeMIVtest(const SCEV *Src,
+                         const SCEV *Dst,
+                         const SmallBitVector &Loops,
+                         FullDependence &Result) const;
+
+    /// collectCoefficientInfo - Walks through the subscript,
+    /// collecting each coefficient, the associated loop bounds,
+    /// and recording its positive and negative parts for later use.
+    CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
+                                      bool SrcFlag,
+                                      const SCEV *&Constant) const;
+
+    /// getPositivePart - X^+ = max(X, 0).
+    ///
+    const SCEV *getPositivePart(const SCEV *X) const;
+
+    /// getNegativePart - X^- = min(X, 0).
+    ///
+    const SCEV *getNegativePart(const SCEV *X) const;
+
+    /// getLowerBound - Looks through all the bounds info and
+    /// computes the lower bound given the current direction settings
+    /// at each level.
+    const SCEV *getLowerBound(BoundInfo *Bound) const;
+
+    /// getUpperBound - Looks through all the bounds info and
+    /// computes the upper bound given the current direction settings
+    /// at each level.
+    const SCEV *getUpperBound(BoundInfo *Bound) const;
+
+    /// exploreDirections - Hierarchically expands the direction vector
+    /// search space, combining the directions of discovered dependences
+    /// in the DirSet field of Bound. Returns the number of distinct
+    /// dependences discovered. If the dependence is disproved,
+    /// it will return 0.
+    unsigned exploreDirections(unsigned Level,
+                               CoefficientInfo *A,
+                               CoefficientInfo *B,
+                               BoundInfo *Bound,
+                               const SmallBitVector &Loops,
+                               unsigned &DepthExpanded,
+                               const SCEV *Delta) const;
+
+    /// testBounds - Returns true iff the current bounds are plausible.
+    ///
+    bool testBounds(unsigned char DirKind,
+                    unsigned Level,
+                    BoundInfo *Bound,
+                    const SCEV *Delta) const;
+
+    /// findBoundsALL - Computes the upper and lower bounds for level K
+    /// using the * direction. Records them in Bound.
+    void findBoundsALL(CoefficientInfo *A,
+                       CoefficientInfo *B,
+                       BoundInfo *Bound,
+                       unsigned K) const;
+
+    /// findBoundsLT - Computes the upper and lower bounds for level K
+    /// using the < direction. Records them in Bound.
+    void findBoundsLT(CoefficientInfo *A,
+                      CoefficientInfo *B,
+                      BoundInfo *Bound,
+                      unsigned K) const;
+
+    /// findBoundsGT - Computes the upper and lower bounds for level K
+    /// using the > direction. Records them in Bound.
+    void findBoundsGT(CoefficientInfo *A,
+                      CoefficientInfo *B,
+                      BoundInfo *Bound,
+                      unsigned K) const;
+
+    /// findBoundsEQ - Computes the upper and lower bounds for level K
+    /// using the = direction. Records them in Bound.
+    void findBoundsEQ(CoefficientInfo *A,
+                      CoefficientInfo *B,
+                      BoundInfo *Bound,
+                      unsigned K) const;
+
+    /// intersectConstraints - Updates X with the intersection
+    /// of the Constraints X and Y. Returns true if X has changed.
+    bool intersectConstraints(Constraint *X,
+                              const Constraint *Y);
+
+    /// propagate - Review the constraints, looking for opportunities
+    /// to simplify a subscript pair (Src and Dst).
+    /// Return true if some simplification occurs.
+    /// If the simplification isn't exact (that is, if it is conservative
+    /// in terms of dependence), set consistent to false.
+    bool propagate(const SCEV *&Src,
+                   const SCEV *&Dst,
+                   SmallBitVector &Loops,
+                   SmallVectorImpl<Constraint> &Constraints,
+                   bool &Consistent);
+
+    /// propagateDistance - Attempt to propagate a distance
+    /// constraint into a subscript pair (Src and Dst).
+    /// Return true if some simplification occurs.
+    /// If the simplification isn't exact (that is, if it is conservative
+    /// in terms of dependence), set consistent to false.
+    bool propagateDistance(const SCEV *&Src,
+                           const SCEV *&Dst,
+                           Constraint &CurConstraint,
+                           bool &Consistent);
+
+    /// propagatePoint - Attempt to propagate a point
+    /// constraint into a subscript pair (Src and Dst).
+    /// Return true if some simplification occurs.
+    bool propagatePoint(const SCEV *&Src,
+                        const SCEV *&Dst,
+                        Constraint &CurConstraint);
+
+    /// propagateLine - Attempt to propagate a line
+    /// constraint into a subscript pair (Src and Dst).
+    /// Return true if some simplification occurs.
+    /// If the simplification isn't exact (that is, if it is conservative
+    /// in terms of dependence), set consistent to false.
+    bool propagateLine(const SCEV *&Src,
+                       const SCEV *&Dst,
+                       Constraint &CurConstraint,
+                       bool &Consistent);
+
+    /// findCoefficient - Given a linear SCEV,
+    /// return the coefficient corresponding to specified loop.
+    /// If there isn't one, return the SCEV constant 0.
+    /// For example, given a*i + b*j + c*k, returning the coefficient
+    /// corresponding to the j loop would yield b.
+    const SCEV *findCoefficient(const SCEV *Expr,
+                                const Loop *TargetLoop) const;
+
+    /// zeroCoefficient - Given a linear SCEV,
+    /// return the SCEV given by zeroing out the coefficient
+    /// corresponding to the specified loop.
+    /// For example, given a*i + b*j + c*k, zeroing the coefficient
+    /// corresponding to the j loop would yield a*i + c*k.
+    const SCEV *zeroCoefficient(const SCEV *Expr,
+                                const Loop *TargetLoop) const;
+
+    /// addToCoefficient - Given a linear SCEV Expr,
+    /// return the SCEV given by adding some Value to the
+    /// coefficient corresponding to the specified TargetLoop.
+    /// For example, given a*i + b*j + c*k, adding 1 to the coefficient
+    /// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
+    const SCEV *addToCoefficient(const SCEV *Expr,
+                                 const Loop *TargetLoop,
+                                 const SCEV *Value)  const;
+
+    /// updateDirection - Update direction vector entry
+    /// based on the current constraint.
+    void updateDirection(Dependence::DVEntry &Level,
+                         const Constraint &CurConstraint) const;
+
+    bool tryDelinearize(const SCEV *SrcSCEV, const SCEV *DstSCEV,
+                        SmallVectorImpl<Subscript> &Pair,
+                        const SCEV *ElementSize) const;
+
+  public:
+    static char ID; // Class identification, replacement for typeinfo
+    DependenceAnalysis() : FunctionPass(ID) {
+      initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
+    }
+
+    bool runOnFunction(Function &F) override;
+    void releaseMemory() override;
+    void getAnalysisUsage(AnalysisUsage &) const override;
+    void print(raw_ostream &, const Module * = nullptr) const override;
+  }; // class DependenceAnalysis
+
+  /// createDependenceAnalysisPass - This creates an instance of the
+  /// DependenceAnalysis pass.
+  FunctionPass *createDependenceAnalysisPass();
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/DomPrinter.h b/include/llvm/Analysis/DomPrinter.h
new file mode 100644
index 0000000..0ed2899
--- /dev/null
+++ b/include/llvm/Analysis/DomPrinter.h
@@ -0,0 +1,30 @@
+//===-- DomPrinter.h - Dom printer external interface ------------*- 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 external functions that can be called to explicitly
+// instantiate the dominance tree printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMPRINTER_H
+#define LLVM_ANALYSIS_DOMPRINTER_H
+
+namespace llvm {
+  class FunctionPass;
+  FunctionPass *createDomPrinterPass();
+  FunctionPass *createDomOnlyPrinterPass();
+  FunctionPass *createDomViewerPass();
+  FunctionPass *createDomOnlyViewerPass();
+  FunctionPass *createPostDomPrinterPass();
+  FunctionPass *createPostDomOnlyPrinterPass();
+  FunctionPass *createPostDomViewerPass();
+  FunctionPass *createPostDomOnlyViewerPass();
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
new file mode 100644
index 0000000..f42b9cb
--- /dev/null
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -0,0 +1,208 @@
+//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- 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 DominanceFrontier class, which calculate and holds the
+// dominance frontier for a function.
+//
+// This should be considered deprecated, don't add any more uses of this data
+// structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+
+#include "llvm/IR/Dominators.h"
+#include <map>
+#include <set>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominanceFrontierBase - Common base class for computing forward and inverse
+/// dominance frontiers for a function.
+///
+template <class BlockT>
+class DominanceFrontierBase {
+public:
+  typedef std::set<BlockT *> DomSetType;                // Dom set for a bb
+  typedef std::map<BlockT *, DomSetType> DomSetMapType; // Dom set map
+
+protected:
+  typedef GraphTraits<BlockT *> BlockTraits;
+
+  DomSetMapType Frontiers;
+  std::vector<BlockT *> Roots;
+  const bool IsPostDominators;
+
+public:
+  DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {}
+
+  /// getRoots - Return the root blocks of the current CFG.  This may include
+  /// multiple blocks if we are computing post dominators.  For forward
+  /// dominators, this will always be a single block (the entry node).
+  ///
+  inline const std::vector<BlockT *> &getRoots() const {
+    return Roots;
+  }
+
+  BlockT *getRoot() const {
+    assert(Roots.size() == 1 && "Should always have entry node!");
+    return Roots[0];
+  }
+
+  /// isPostDominator - Returns true if analysis based of postdoms
+  ///
+  bool isPostDominator() const {
+    return IsPostDominators;
+  }
+
+  void releaseMemory() {
+    Frontiers.clear();
+  }
+
+  // Accessor interface:
+  typedef typename DomSetMapType::iterator iterator;
+  typedef typename DomSetMapType::const_iterator const_iterator;
+  iterator begin() { return Frontiers.begin(); }
+  const_iterator begin() const { return Frontiers.begin(); }
+  iterator end() { return Frontiers.end(); }
+  const_iterator end() const { return Frontiers.end(); }
+  iterator find(BlockT *B) { return Frontiers.find(B); }
+  const_iterator find(BlockT *B) const { return Frontiers.find(B); }
+
+  iterator addBasicBlock(BlockT *BB, const DomSetType &frontier) {
+    assert(find(BB) == end() && "Block already in DominanceFrontier!");
+    return Frontiers.insert(std::make_pair(BB, frontier)).first;
+  }
+
+  /// removeBlock - Remove basic block BB's frontier.
+  void removeBlock(BlockT *BB);
+
+  void addToFrontier(iterator I, BlockT *Node);
+
+  void removeFromFrontier(iterator I, BlockT *Node);
+
+  /// compareDomSet - Return false if two domsets match. Otherwise
+  /// return true;
+  bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const;
+
+  /// compare - Return true if the other dominance frontier base matches
+  /// this dominance frontier base. Otherwise return false.
+  bool compare(DominanceFrontierBase<BlockT> &Other) const;
+
+  /// print - Convert to human readable form
+  ///
+  void print(raw_ostream &OS) const;
+
+  /// dump - Dump the dominance frontier to dbgs().
+  void dump() const;
+};
+
+//===-------------------------------------
+/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
+/// used to compute a forward dominator frontiers.
+///
+template <class BlockT>
+class ForwardDominanceFrontierBase : public DominanceFrontierBase<BlockT> {
+private:
+  typedef GraphTraits<BlockT *> BlockTraits;
+
+public:
+  typedef DominatorTreeBase<BlockT> DomTreeT;
+  typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
+  typedef typename DominanceFrontierBase<BlockT>::DomSetType DomSetType;
+
+  ForwardDominanceFrontierBase() : DominanceFrontierBase<BlockT>(false) {}
+
+  void analyze(DomTreeT &DT) {
+    this->Roots = DT.getRoots();
+    assert(this->Roots.size() == 1 &&
+           "Only one entry block for forward domfronts!");
+    calculate(DT, DT[this->Roots[0]]);
+  }
+
+  const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
+};
+
+class DominanceFrontier : public FunctionPass {
+  ForwardDominanceFrontierBase<BasicBlock> Base;
+
+public:
+  typedef DominatorTreeBase<BasicBlock> DomTreeT;
+  typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
+  typedef DominanceFrontierBase<BasicBlock>::DomSetType DomSetType;
+  typedef DominanceFrontierBase<BasicBlock>::iterator iterator;
+  typedef DominanceFrontierBase<BasicBlock>::const_iterator const_iterator;
+
+  static char ID; // Pass ID, replacement for typeid
+
+  DominanceFrontier();
+
+  ForwardDominanceFrontierBase<BasicBlock> &getBase() { return Base; }
+
+  inline const std::vector<BasicBlock *> &getRoots() const {
+    return Base.getRoots();
+  }
+
+  BasicBlock *getRoot() const { return Base.getRoot(); }
+
+  bool isPostDominator() const { return Base.isPostDominator(); }
+
+  iterator begin() { return Base.begin(); }
+
+  const_iterator begin() const { return Base.begin(); }
+
+  iterator end() { return Base.end(); }
+
+  const_iterator end() const { return Base.end(); }
+
+  iterator find(BasicBlock *B) { return Base.find(B); }
+
+  const_iterator find(BasicBlock *B) const { return Base.find(B); }
+
+  iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+    return Base.addBasicBlock(BB, frontier);
+  }
+
+  void removeBlock(BasicBlock *BB) { return Base.removeBlock(BB); }
+
+  void addToFrontier(iterator I, BasicBlock *Node) {
+    return Base.addToFrontier(I, Node);
+  }
+
+  void removeFromFrontier(iterator I, BasicBlock *Node) {
+    return Base.removeFromFrontier(I, Node);
+  }
+
+  bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
+    return Base.compareDomSet(DS1, DS2);
+  }
+
+  bool compare(DominanceFrontierBase<BasicBlock> &Other) const {
+    return Base.compare(Other);
+  }
+
+  void releaseMemory() override;
+
+  bool runOnFunction(Function &) override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  void print(raw_ostream &OS, const Module * = nullptr) const override;
+
+  void dump() const;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h
new file mode 100644
index 0000000..04df2cc
--- /dev/null
+++ b/include/llvm/Analysis/DominanceFrontierImpl.h
@@ -0,0 +1,228 @@
+//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the generic implementation of the DominanceFrontier class, which
+// calculate and holds the dominance frontier for a function for.
+//
+// This should be considered deprecated, don't add any more uses of this data
+// structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
+#define LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm {
+
+namespace {
+template <class BlockT>
+class DFCalculateWorkObject {
+public:
+  typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
+
+  DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
+                        const DomTreeNodeT *PN)
+      : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
+  BlockT *currentBB;
+  BlockT *parentBB;
+  const DomTreeNodeT *Node;
+  const DomTreeNodeT *parentNode;
+};
+}
+
+template <class BlockT>
+void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
+  assert(find(BB) != end() && "Block is not in DominanceFrontier!");
+  for (iterator I = begin(), E = end(); I != E; ++I)
+    I->second.erase(BB);
+  Frontiers.erase(BB);
+}
+
+template <class BlockT>
+void DominanceFrontierBase<BlockT>::addToFrontier(iterator I,
+                                                  BlockT *Node) {
+  assert(I != end() && "BB is not in DominanceFrontier!");
+  assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+  I->second.erase(Node);
+}
+
+template <class BlockT>
+void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I,
+                                                       BlockT *Node) {
+  assert(I != end() && "BB is not in DominanceFrontier!");
+  assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+  I->second.erase(Node);
+}
+
+template <class BlockT>
+bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
+                                                  const DomSetType &DS2) const {
+  std::set<BlockT *> tmpSet;
+  for (BlockT *BB : DS2)
+    tmpSet.insert(BB);
+
+  for (typename DomSetType::const_iterator I = DS1.begin(), E = DS1.end();
+       I != E;) {
+    BlockT *Node = *I++;
+
+    if (tmpSet.erase(Node) == 0)
+      // Node is in DS1 but tnot in DS2.
+      return true;
+  }
+
+  if (!tmpSet.empty()) {
+    // There are nodes that are in DS2 but not in DS1.
+    return true;
+  }
+
+  // DS1 and DS2 matches.
+  return false;
+}
+
+template <class BlockT>
+bool DominanceFrontierBase<BlockT>::compare(
+    DominanceFrontierBase<BlockT> &Other) const {
+  DomSetMapType tmpFrontiers;
+  for (typename DomSetMapType::const_iterator I = Other.begin(),
+                                              E = Other.end();
+       I != E; ++I)
+    tmpFrontiers.insert(std::make_pair(I->first, I->second));
+
+  for (typename DomSetMapType::iterator I = tmpFrontiers.begin(),
+                                        E = tmpFrontiers.end();
+       I != E;) {
+    BlockT *Node = I->first;
+    const_iterator DFI = find(Node);
+    if (DFI == end())
+      return true;
+
+    if (compareDomSet(I->second, DFI->second))
+      return true;
+
+    ++I;
+    tmpFrontiers.erase(Node);
+  }
+
+  if (!tmpFrontiers.empty())
+    return true;
+
+  return false;
+}
+
+template <class BlockT>
+void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
+  for (const_iterator I = begin(), E = end(); I != E; ++I) {
+    OS << "  DomFrontier for BB ";
+    if (I->first)
+      I->first->printAsOperand(OS, false);
+    else
+      OS << " <<exit node>>";
+    OS << " is:\t";
+
+    const std::set<BlockT *> &BBs = I->second;
+
+    for (const BlockT *BB : BBs) {
+      OS << ' ';
+      if (BB)
+        BB->printAsOperand(OS, false);
+      else
+        OS << "<<exit node>>";
+    }
+    OS << '\n';
+  }
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <class BlockT>
+void DominanceFrontierBase<BlockT>::dump() const {
+  print(dbgs());
+}
+#endif
+
+template <class BlockT>
+const typename ForwardDominanceFrontierBase<BlockT>::DomSetType &
+ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT,
+                                                const DomTreeNodeT *Node) {
+  BlockT *BB = Node->getBlock();
+  DomSetType *Result = nullptr;
+
+  std::vector<DFCalculateWorkObject<BlockT>> workList;
+  SmallPtrSet<BlockT *, 32> visited;
+
+  workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr));
+  do {
+    DFCalculateWorkObject<BlockT> *currentW = &workList.back();
+    assert(currentW && "Missing work object.");
+
+    BlockT *currentBB = currentW->currentBB;
+    BlockT *parentBB = currentW->parentBB;
+    const DomTreeNodeT *currentNode = currentW->Node;
+    const DomTreeNodeT *parentNode = currentW->parentNode;
+    assert(currentBB && "Invalid work object. Missing current Basic Block");
+    assert(currentNode && "Invalid work object. Missing current Node");
+    DomSetType &S = this->Frontiers[currentBB];
+
+    // Visit each block only once.
+    if (visited.count(currentBB) == 0) {
+      visited.insert(currentBB);
+
+      // Loop over CFG successors to calculate DFlocal[currentNode]
+      for (auto SI = BlockTraits::child_begin(currentBB),
+                SE = BlockTraits::child_end(currentBB);
+           SI != SE; ++SI) {
+        // Does Node immediately dominate this successor?
+        if (DT[*SI]->getIDom() != currentNode)
+          S.insert(*SI);
+      }
+    }
+
+    // At this point, S is DFlocal.  Now we union in DFup's of our children...
+    // Loop through and visit the nodes that Node immediately dominates (Node's
+    // children in the IDomTree)
+    bool visitChild = false;
+    for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
+                                               NE = currentNode->end();
+         NI != NE; ++NI) {
+      DomTreeNodeT *IDominee = *NI;
+      BlockT *childBB = IDominee->getBlock();
+      if (visited.count(childBB) == 0) {
+        workList.push_back(DFCalculateWorkObject<BlockT>(
+            childBB, currentBB, IDominee, currentNode));
+        visitChild = true;
+      }
+    }
+
+    // If all children are visited or there is any child then pop this block
+    // from the workList.
+    if (!visitChild) {
+      if (!parentBB) {
+        Result = &S;
+        break;
+      }
+
+      typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
+      DomSetType &parentSet = this->Frontiers[parentBB];
+      for (; CDFI != CDFE; ++CDFI) {
+        if (!DT.properlyDominates(parentNode, DT[*CDFI]))
+          parentSet.insert(*CDFI);
+      }
+      workList.pop_back();
+    }
+
+  } while (!workList.empty());
+
+  return *Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h
new file mode 100644
index 0000000..574c947
--- /dev/null
+++ b/include/llvm/Analysis/FindUsedTypes.h
@@ -0,0 +1,66 @@
+//===- llvm/Analysis/FindUsedTypes.h - Find all Types in use ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to seek out all of the types in use by the program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_FINDUSEDTYPES_H
+#define LLVM_ANALYSIS_FINDUSEDTYPES_H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class Type;
+class Value;
+
+class FindUsedTypes : public ModulePass {
+  SetVector<Type *> UsedTypes;
+public:
+  static char ID; // Pass identification, replacement for typeid
+  FindUsedTypes() : ModulePass(ID) {
+    initializeFindUsedTypesPass(*PassRegistry::getPassRegistry());
+  }
+
+  /// getTypes - After the pass has been run, return the set containing all of
+  /// the types used in the module.
+  ///
+  const SetVector<Type *> &getTypes() const { return UsedTypes; }
+
+  /// Print the types found in the module.  If the optional Module parameter is
+  /// passed in, then the types are printed symbolically if possible, using the
+  /// symbol table from the module.
+  ///
+  void print(raw_ostream &o, const Module *M) const override;
+
+private:
+  /// IncorporateType - Incorporate one type and all of its subtypes into the
+  /// collection of used types.
+  ///
+  void IncorporateType(Type *Ty);
+
+  /// IncorporateValue - Incorporate all of the types used by this value.
+  ///
+  void IncorporateValue(const Value *V);
+
+public:
+  /// run - This incorporates all types used by the specified module
+  bool runOnModule(Module &M) override;
+
+  /// getAnalysisUsage - We do not modify anything.
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
new file mode 100644
index 0000000..6038872
--- /dev/null
+++ b/include/llvm/Analysis/IVUsers.h
@@ -0,0 +1,184 @@
+//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements bookkeeping for "interesting" users of expressions
+// computed from induction variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_IVUSERS_H
+#define LLVM_ANALYSIS_IVUSERS_H
+
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/IR/ValueHandle.h"
+
+namespace llvm {
+
+class DominatorTree;
+class Instruction;
+class Value;
+class ScalarEvolution;
+class SCEV;
+class IVUsers;
+class DataLayout;
+
+/// IVStrideUse - Keep track of one use of a strided induction variable.
+/// The Expr member keeps track of the expression, User is the actual user
+/// instruction of the operand, and 'OperandValToReplace' is the operand of
+/// the User that is the use.
+class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
+  friend class IVUsers;
+public:
+  IVStrideUse(IVUsers *P, Instruction* U, Value *O)
+    : CallbackVH(U), Parent(P), OperandValToReplace(O) {
+  }
+
+  /// getUser - Return the user instruction for this use.
+  Instruction *getUser() const {
+    return cast<Instruction>(getValPtr());
+  }
+
+  /// setUser - Assign a new user instruction for this use.
+  void setUser(Instruction *NewUser) {
+    setValPtr(NewUser);
+  }
+
+  /// getOperandValToReplace - Return the Value of the operand in the user
+  /// instruction that this IVStrideUse is representing.
+  Value *getOperandValToReplace() const {
+    return OperandValToReplace;
+  }
+
+  /// setOperandValToReplace - Assign a new Value as the operand value
+  /// to replace.
+  void setOperandValToReplace(Value *Op) {
+    OperandValToReplace = Op;
+  }
+
+  /// getPostIncLoops - Return the set of loops for which the expression has
+  /// been adjusted to use post-inc mode.
+  const PostIncLoopSet &getPostIncLoops() const {
+    return PostIncLoops;
+  }
+
+  /// transformToPostInc - Transform the expression to post-inc form for the
+  /// given loop.
+  void transformToPostInc(const Loop *L);
+
+private:
+  /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
+  IVUsers *Parent;
+
+  /// OperandValToReplace - The Value of the operand in the user instruction
+  /// that this IVStrideUse is representing.
+  WeakVH OperandValToReplace;
+
+  /// PostIncLoops - The set of loops for which Expr has been adjusted to
+  /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
+  PostIncLoopSet PostIncLoops;
+
+  /// Deleted - Implementation of CallbackVH virtual function to
+  /// receive notification when the User is deleted.
+  void deleted() override;
+};
+
+template<> struct ilist_traits<IVStrideUse>
+  : public ilist_default_traits<IVStrideUse> {
+  // createSentinel is used to get hold of a node that marks the end of
+  // the list...
+  // The sentinel is relative to this instance, so we use a non-static
+  // method.
+  IVStrideUse *createSentinel() const {
+    // since i(p)lists always publicly derive from the corresponding
+    // traits, placing a data member in this class will augment i(p)list.
+    // But since the NodeTy is expected to publicly derive from
+    // ilist_node<NodeTy>, there is a legal viable downcast from it
+    // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
+    // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
+    // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
+    // the superposition.
+    return static_cast<IVStrideUse*>(&Sentinel);
+  }
+  static void destroySentinel(IVStrideUse*) {}
+
+  IVStrideUse *provideInitialHead() const { return createSentinel(); }
+  IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
+  static void noteHead(IVStrideUse*, IVStrideUse*) {}
+
+private:
+  mutable ilist_node<IVStrideUse> Sentinel;
+};
+
+class IVUsers : public LoopPass {
+  friend class IVStrideUse;
+  Loop *L;
+  LoopInfo *LI;
+  DominatorTree *DT;
+  ScalarEvolution *SE;
+  const DataLayout *DL;
+  SmallPtrSet<Instruction*,16> Processed;
+
+  /// IVUses - A list of all tracked IV uses of induction variable expressions
+  /// we are interested in.
+  ilist<IVStrideUse> IVUses;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  bool runOnLoop(Loop *L, LPPassManager &LPM) override;
+
+  void releaseMemory() override;
+
+public:
+  static char ID; // Pass ID, replacement for typeid
+  IVUsers();
+
+  Loop *getLoop() const { return L; }
+
+  /// AddUsersIfInteresting - Inspect the specified Instruction.  If it is a
+  /// reducible SCEV, recursively add its users to the IVUsesByStride set and
+  /// return true.  Otherwise, return false.
+  bool AddUsersIfInteresting(Instruction *I);
+
+  IVStrideUse &AddUser(Instruction *User, Value *Operand);
+
+  /// getReplacementExpr - Return a SCEV expression which computes the
+  /// value of the OperandValToReplace of the given IVStrideUse.
+  const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
+
+  /// getExpr - Return the expression for the use.
+  const SCEV *getExpr(const IVStrideUse &IU) const;
+
+  const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
+
+  typedef ilist<IVStrideUse>::iterator iterator;
+  typedef ilist<IVStrideUse>::const_iterator const_iterator;
+  iterator begin() { return IVUses.begin(); }
+  iterator end()   { return IVUses.end(); }
+  const_iterator begin() const { return IVUses.begin(); }
+  const_iterator end() const   { return IVUses.end(); }
+  bool empty() const { return IVUses.empty(); }
+
+  bool isIVUserOrOperand(Instruction *Inst) const {
+    return Processed.count(Inst);
+  }
+
+  void print(raw_ostream &OS, const Module* = nullptr) const override;
+
+  /// dump - This method is used for debugging.
+  void dump() const;
+protected:
+  bool AddUsersImpl(Instruction *I, SmallPtrSet<Loop*,16> &SimpleLoopNests);
+};
+
+Pass *createIVUsersPass();
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
new file mode 100644
index 0000000..aaed716
--- /dev/null
+++ b/include/llvm/Analysis/InlineCost.h
@@ -0,0 +1,141 @@
+//===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements heuristics for inlining decisions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INLINECOST_H
+#define LLVM_ANALYSIS_INLINECOST_H
+
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+class CallSite;
+class DataLayout;
+class Function;
+class TargetTransformInfo;
+
+namespace InlineConstants {
+  // Various magic constants used to adjust heuristics.
+  const int InstrCost = 5;
+  const int IndirectCallThreshold = 100;
+  const int CallPenalty = 25;
+  const int LastCallToStaticBonus = -15000;
+  const int ColdccPenalty = 2000;
+  const int NoreturnPenalty = 10000;
+  /// Do not inline functions which allocate this many bytes on the stack
+  /// when the caller is recursive.
+  const unsigned TotalAllocaSizeRecursiveCaller = 1024;
+}
+
+/// \brief Represents the cost of inlining a function.
+///
+/// This supports special values for functions which should "always" or
+/// "never" be inlined. Otherwise, the cost represents a unitless amount;
+/// smaller values increase the likelihood of the function being inlined.
+///
+/// Objects of this type also provide the adjusted threshold for inlining
+/// based on the information available for a particular callsite. They can be
+/// directly tested to determine if inlining should occur given the cost and
+/// threshold for this cost metric.
+class InlineCost {
+  enum SentinelValues {
+    AlwaysInlineCost = INT_MIN,
+    NeverInlineCost = INT_MAX
+  };
+
+  /// \brief The estimated cost of inlining this callsite.
+  const int Cost;
+
+  /// \brief The adjusted threshold against which this cost was computed.
+  const int Threshold;
+
+  // Trivial constructor, interesting logic in the factory functions below.
+  InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {}
+
+public:
+  static InlineCost get(int Cost, int Threshold) {
+    assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
+    assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
+    return InlineCost(Cost, Threshold);
+  }
+  static InlineCost getAlways() {
+    return InlineCost(AlwaysInlineCost, 0);
+  }
+  static InlineCost getNever() {
+    return InlineCost(NeverInlineCost, 0);
+  }
+
+  /// \brief Test whether the inline cost is low enough for inlining.
+  LLVM_EXPLICIT operator bool() const {
+    return Cost < Threshold;
+  }
+
+  bool isAlways() const { return Cost == AlwaysInlineCost; }
+  bool isNever() const { return Cost == NeverInlineCost; }
+  bool isVariable() const { return !isAlways() && !isNever(); }
+
+  /// \brief Get the inline cost estimate.
+  /// It is an error to call this on an "always" or "never" InlineCost.
+  int getCost() const {
+    assert(isVariable() && "Invalid access of InlineCost");
+    return Cost;
+  }
+
+  /// \brief Get the cost delta from the threshold for inlining.
+  /// Only valid if the cost is of the variable kind. Returns a negative
+  /// value if the cost is too high to inline.
+  int getCostDelta() const { return Threshold - getCost(); }
+};
+
+/// \brief Cost analyzer used by inliner.
+class InlineCostAnalysis : public CallGraphSCCPass {
+  const TargetTransformInfo *TTI;
+
+public:
+  static char ID;
+
+  InlineCostAnalysis();
+  ~InlineCostAnalysis();
+
+  // Pass interface implementation.
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  bool runOnSCC(CallGraphSCC &SCC) override;
+
+  /// \brief Get an InlineCost object representing the cost of inlining this
+  /// callsite.
+  ///
+  /// Note that threshold is passed into this function. Only costs below the
+  /// threshold are computed with any accuracy. The threshold can be used to
+  /// bound the computation necessary to determine whether the cost is
+  /// sufficiently low to warrant inlining.
+  ///
+  /// Also note that calling this function *dynamically* computes the cost of
+  /// inlining the callsite. It is an expensive, heavyweight call.
+  InlineCost getInlineCost(CallSite CS, int Threshold);
+
+  /// \brief Get an InlineCost with the callee explicitly specified.
+  /// This allows you to calculate the cost of inlining a function via a
+  /// pointer. This behaves exactly as the version with no explicit callee
+  /// parameter in all other respects.
+  //
+  //  Note: This is used by out-of-tree passes, please do not remove without
+  //  adding a replacement API.
+  InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
+
+  /// \brief Minimal filter to detect invalid constructs for inlining.
+  bool isInlineViable(Function &Callee);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
new file mode 100644
index 0000000..2367c0b
--- /dev/null
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -0,0 +1,280 @@
+//===-- InstructionSimplify.h - Fold instrs into simpler forms --*- 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 routines for folding instructions into simpler forms
+// that do not require creating new instructions.  This does constant folding
+// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
+// returning a constant ("and i32 %x, 0" -> "0") or an already existing value
+// ("and i32 %x, %x" -> "%x").  If the simplification is also an instruction
+// then it dominates the original instruction.
+//
+// These routines implicitly resolve undef uses. The easiest way to be safe when
+// using these routines to obtain simplified values for existing instructions is
+// to always replace all uses of the instructions with the resulting simplified
+// values. This will prevent other code from seeing the same undef uses and
+// resolving them to different values.
+//
+// These routines are designed to tolerate moderately incomplete IR, such as
+// instructions that are not connected to basic blocks yet. However, they do
+// require that all the IR that they encounter be valid. In particular, they
+// require that all non-constant values be defined in the same function, and the
+// same call context of that function (and not split between caller and callee
+// contexts of a directly recursive call, for example).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+
+#include "llvm/IR/User.h"
+
+namespace llvm {
+  template<typename T>
+  class ArrayRef;
+  class DominatorTree;
+  class Instruction;
+  class DataLayout;
+  class FastMathFlags;
+  class TargetLibraryInfo;
+  class Type;
+  class Value;
+
+  /// SimplifyAddInst - Given operands for an Add, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifySubInst - Given operands for a Sub, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// Given operands for an FAdd, see if we can fold the result.  If not, this
+  /// returns null.
+  Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// Given operands for an FSub, see if we can fold the result.  If not, this
+  /// returns null.
+  Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// Given operands for an FMul, see if we can fold the result.  If not, this
+  /// returns null.
+  Value *SimplifyFMulInst(Value *LHS, Value *RHS,
+                          FastMathFlags FMF,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyMulInst - Given operands for a Mul, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifySDivInst - Given operands for an SDiv, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifySDivInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyUDivInst - Given operands for a UDiv, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyUDivInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyFDivInst - Given operands for an FDiv, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyFDivInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifySRemInst - Given operands for an SRem, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifySRemInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyURemInst - Given operands for a URem, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyURemInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyFRemInst - Given operands for an FRem, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyFRemInst(Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyShlInst - Given operands for a Shl, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifyLShrInst - Given operands for a LShr, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyAShrInst - Given operands for a AShr, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyAndInst - Given operands for an And, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifyOrInst - Given operands for an Or, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+                        const TargetLibraryInfo *TLI = nullptr,
+                        const DominatorTree *DT = nullptr);
+
+  /// SimplifyXorInst - Given operands for a Xor, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+                          const DataLayout *TD = nullptr,
+                          const TargetLibraryInfo *TLI = nullptr,
+                          const DominatorTree *DT = nullptr);
+
+  /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
+  /// the result.  If not, this returns null.
+  Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
+                            const DataLayout *TD = nullptr,
+                            const TargetLibraryInfo *TLI = nullptr,
+                            const DominatorTree *DT = nullptr);
+
+  /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
+  /// can fold the result.  If not, this returns null.
+  Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
+                                 ArrayRef<unsigned> Idxs,
+                                 const DataLayout *TD = nullptr,
+                                 const TargetLibraryInfo *TLI = nullptr,
+                                 const DominatorTree *DT = nullptr);
+
+  /// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
+  /// the result.  If not, this returns null.
+  Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = nullptr,
+                           const TargetLibraryInfo *TLI = nullptr,
+                           const DominatorTree *DT = nullptr);
+
+  //=== Helper functions for higher up the class hierarchy.
+
+
+  /// SimplifyCmpInst - Given operands for a CmpInst, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
+                         const DataLayout *TD = nullptr,
+                         const TargetLibraryInfo *TLI = nullptr,
+                         const DominatorTree *DT = nullptr);
+
+  /// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
+  /// fold the result.  If not, this returns null.
+  Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
+                       const DataLayout *TD = nullptr,
+                       const TargetLibraryInfo *TLI = nullptr,
+                       const DominatorTree *DT = nullptr);
+
+  /// \brief Given a function and iterators over arguments, see if we can fold
+  /// the result.
+  ///
+  /// If this call could not be simplified returns null.
+  Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
+                      User::op_iterator ArgEnd, const DataLayout *TD = nullptr,
+                      const TargetLibraryInfo *TLI = nullptr,
+                      const DominatorTree *DT = nullptr);
+
+  /// \brief Given a function and set of arguments, see if we can fold the
+  /// result.
+  ///
+  /// If this call could not be simplified returns null.
+  Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
+                      const DataLayout *TD = nullptr,
+                      const TargetLibraryInfo *TLI = nullptr,
+                      const DominatorTree *DT = nullptr);
+
+  /// SimplifyInstruction - See if we can compute a simplified version of this
+  /// instruction.  If not, this returns null.
+  Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = nullptr,
+                             const TargetLibraryInfo *TLI = nullptr,
+                             const DominatorTree *DT = nullptr);
+
+
+  /// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses
+  /// recursively.
+  ///
+  /// This first performs a normal RAUW of I with SimpleV. It then recursively
+  /// attempts to simplify those users updated by the operation. The 'I'
+  /// instruction must not be equal to the simplified value 'SimpleV'.
+  ///
+  /// The function returns true if any simplifications were performed.
+  bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
+                                     const DataLayout *TD = nullptr,
+                                     const TargetLibraryInfo *TLI = nullptr,
+                                     const DominatorTree *DT = nullptr);
+
+  /// \brief Recursively attempt to simplify an instruction.
+  ///
+  /// This routine uses SimplifyInstruction to simplify 'I', and if successful
+  /// replaces uses of 'I' with the simplified value. It then recurses on each
+  /// of the users impacted. It returns true if any simplifications were
+  /// performed.
+  bool recursivelySimplifyInstruction(Instruction *I,
+                                      const DataLayout *TD = nullptr,
+                                      const TargetLibraryInfo *TLI = nullptr,
+                                      const DominatorTree *DT = nullptr);
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h
new file mode 100644
index 0000000..01eba3f
--- /dev/null
+++ b/include/llvm/Analysis/Interval.h
@@ -0,0 +1,150 @@
+//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Interval class, which
+// represents a set of CFG nodes and is a portion of an interval partition.
+//
+// Intervals have some interesting and useful properties, including the
+// following:
+//    1. The header node of an interval dominates all of the elements of the
+//       interval
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INTERVAL_H
+#define LLVM_ANALYSIS_INTERVAL_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include <vector>
+
+namespace llvm {
+
+class BasicBlock;
+class raw_ostream;
+
+//===----------------------------------------------------------------------===//
+//
+/// Interval Class - An Interval is a set of nodes defined such that every node
+/// in the interval has all of its predecessors in the interval (except for the
+/// header)
+///
+class Interval {
+  /// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
+  /// interval.  Also, any loops in this interval must go through the HeaderNode.
+  ///
+  BasicBlock *HeaderNode;
+public:
+  typedef std::vector<BasicBlock*>::iterator succ_iterator;
+  typedef std::vector<BasicBlock*>::iterator pred_iterator;
+  typedef std::vector<BasicBlock*>::iterator node_iterator;
+
+  inline Interval(BasicBlock *Header) : HeaderNode(Header) {
+    Nodes.push_back(Header);
+  }
+
+  inline BasicBlock *getHeaderNode() const { return HeaderNode; }
+
+  /// Nodes - The basic blocks in this interval.
+  ///
+  std::vector<BasicBlock*> Nodes;
+
+  /// Successors - List of BasicBlocks that are reachable directly from nodes in
+  /// this interval, but are not in the interval themselves.
+  /// These nodes necessarily must be header nodes for other intervals.
+  ///
+  std::vector<BasicBlock*> Successors;
+
+  /// Predecessors - List of BasicBlocks that have this Interval's header block
+  /// as one of their successors.
+  ///
+  std::vector<BasicBlock*> Predecessors;
+
+  /// contains - Find out if a basic block is in this interval
+  inline bool contains(BasicBlock *BB) const {
+    for (unsigned i = 0; i < Nodes.size(); ++i)
+      if (Nodes[i] == BB) return true;
+    return false;
+    // I don't want the dependency on <algorithm>
+    //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
+  }
+
+  /// isSuccessor - find out if a basic block is a successor of this Interval
+  inline bool isSuccessor(BasicBlock *BB) const {
+    for (unsigned i = 0; i < Successors.size(); ++i)
+      if (Successors[i] == BB) return true;
+    return false;
+    // I don't want the dependency on <algorithm>
+    //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
+  }
+
+  /// Equality operator.  It is only valid to compare two intervals from the
+  /// same partition, because of this, all we have to check is the header node
+  /// for equality.
+  ///
+  inline bool operator==(const Interval &I) const {
+    return HeaderNode == I.HeaderNode;
+  }
+
+  /// isLoop - Find out if there is a back edge in this interval...
+  bool isLoop() const;
+
+  /// print - Show contents in human readable format...
+  void print(raw_ostream &O) const;
+};
+
+/// succ_begin/succ_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
+///
+inline Interval::succ_iterator succ_begin(Interval *I) {
+  return I->Successors.begin();
+}
+inline Interval::succ_iterator succ_end(Interval *I)   {
+  return I->Successors.end();
+}
+
+/// pred_begin/pred_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
+///
+inline Interval::pred_iterator pred_begin(Interval *I) {
+  return I->Predecessors.begin();
+}
+inline Interval::pred_iterator pred_end(Interval *I)   {
+  return I->Predecessors.end();
+}
+
+template <> struct GraphTraits<Interval*> {
+  typedef Interval NodeType;
+  typedef Interval::succ_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Interval *I) { return I; }
+
+  /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return succ_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return succ_end(N);
+  }
+};
+
+template <> struct GraphTraits<Inverse<Interval*> > {
+  typedef Interval NodeType;
+  typedef Interval::pred_iterator ChildIteratorType;
+  static NodeType *getEntryNode(Inverse<Interval *> G) { return G.Graph; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return pred_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return pred_end(N);
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
new file mode 100644
index 0000000..73aff76
--- /dev/null
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -0,0 +1,259 @@
+//===- IntervalIterator.h - Interval Iterator Declaration -------*- 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 an iterator that enumerates the intervals in a control flow
+// graph of some sort.  This iterator is parametric, allowing iterator over the
+// following types of graphs:
+//
+//  1. A Function* object, composed of BasicBlock nodes.
+//  2. An IntervalPartition& object, composed of Interval nodes.
+//
+// This iterator is defined to walk the control flow graph, returning intervals
+// in depth first order.  These intervals are completely filled in except for
+// the predecessor fields (the successor information is filled in however).
+//
+// By default, the intervals created by this iterator are deleted after they
+// are no longer any use to the iterator.  This behavior can be changed by
+// passing a false value into the intervals_begin() function. This causes the
+// IOwnMem member to be set, and the intervals to not be deleted.
+//
+// It is only safe to use this if all of the intervals are deleted by the caller
+// and all of the intervals are processed.  However, the user of the iterator is
+// not allowed to modify or delete the intervals until after the iterator has
+// been used completely.  The IntervalPartition class uses this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
+#define LLVM_ANALYSIS_INTERVALITERATOR_H
+
+#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Function.h"
+#include <algorithm>
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// getNodeHeader - Given a source graph node and the source graph, return the
+// BasicBlock that is the header node.  This is the opposite of
+// getSourceGraphNode.
+//
+inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
+inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }
+
+// getSourceGraphNode - Given a BasicBlock and the source graph, return the
+// source graph node that corresponds to the BasicBlock.  This is the opposite
+// of getNodeHeader.
+//
+inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
+  return BB;
+}
+inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
+  return IP->getBlockInterval(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node.  In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval.
+//
+inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
+  Int->Nodes.push_back(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node.  In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval.  In the case of
+// an IntervalPartition source graph (Interval case), all of the member
+// BasicBlocks are added to the interval.
+//
+inline void addNodeToInterval(Interval *Int, Interval *I) {
+  // Add all of the nodes in I as new nodes in Int.
+  copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes));
+}
+
+
+
+
+
+template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy*>,
+         class IGT = GraphTraits<Inverse<NodeTy*> > >
+class IntervalIterator {
+  std::vector<std::pair<Interval*, typename Interval::succ_iterator> > IntStack;
+  std::set<BasicBlock*> Visited;
+  OrigContainer_t *OrigContainer;
+  bool IOwnMem;     // If True, delete intervals when done with them
+                    // See file header for conditions of use
+public:
+  typedef IntervalIterator<NodeTy, OrigContainer_t> _Self;
+  typedef std::forward_iterator_tag iterator_category;
+
+  IntervalIterator() {} // End iterator, empty stack
+  IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
+    OrigContainer = M;
+    if (!ProcessInterval(&M->front())) {
+      llvm_unreachable("ProcessInterval should never fail for first interval!");
+    }
+  }
+
+  IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
+    OrigContainer = &IP;
+    if (!ProcessInterval(IP.getRootInterval())) {
+      llvm_unreachable("ProcessInterval should never fail for first interval!");
+    }
+  }
+
+  inline ~IntervalIterator() {
+    if (IOwnMem)
+      while (!IntStack.empty()) {
+        delete operator*();
+        IntStack.pop_back();
+      }
+  }
+
+  inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+  inline const Interval *operator*() const { return IntStack.back().first; }
+  inline       Interval *operator*()       { return IntStack.back().first; }
+  inline const Interval *operator->() const { return operator*(); }
+  inline       Interval *operator->()       { return operator*(); }
+
+  _Self& operator++() {  // Preincrement
+    assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
+    do {
+      // All of the intervals on the stack have been visited.  Try visiting
+      // their successors now.
+      Interval::succ_iterator &SuccIt = IntStack.back().second,
+                                EndIt = succ_end(IntStack.back().first);
+      while (SuccIt != EndIt) {                 // Loop over all interval succs
+        bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
+        ++SuccIt;                               // Increment iterator
+        if (Done) return *this;                 // Found a new interval! Use it!
+      }
+
+      // Free interval memory... if necessary
+      if (IOwnMem) delete IntStack.back().first;
+
+      // We ran out of successors for this interval... pop off the stack
+      IntStack.pop_back();
+    } while (!IntStack.empty());
+
+    return *this;
+  }
+  inline _Self operator++(int) { // Postincrement
+    _Self tmp = *this; ++*this; return tmp;
+  }
+
+private:
+  // ProcessInterval - This method is used during the construction of the
+  // interval graph.  It walks through the source graph, recursively creating
+  // an interval per invocation until the entire graph is covered.  This uses
+  // the ProcessNode method to add all of the nodes to the interval.
+  //
+  // This method is templated because it may operate on two different source
+  // graphs: a basic block graph, or a preexisting interval graph.
+  //
+  bool ProcessInterval(NodeTy *Node) {
+    BasicBlock *Header = getNodeHeader(Node);
+    if (Visited.count(Header)) return false;
+
+    Interval *Int = new Interval(Header);
+    Visited.insert(Header);   // The header has now been visited!
+
+    // Check all of our successors to see if they are in the interval...
+    for (typename GT::ChildIteratorType I = GT::child_begin(Node),
+           E = GT::child_end(Node); I != E; ++I)
+      ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));
+
+    IntStack.push_back(std::make_pair(Int, succ_begin(Int)));
+    return true;
+  }
+
+  // ProcessNode - This method is called by ProcessInterval to add nodes to the
+  // interval being constructed, and it is also called recursively as it walks
+  // the source graph.  A node is added to the current interval only if all of
+  // its predecessors are already in the graph.  This also takes care of keeping
+  // the successor set of an interval up to date.
+  //
+  // This method is templated because it may operate on two different source
+  // graphs: a basic block graph, or a preexisting interval graph.
+  //
+  void ProcessNode(Interval *Int, NodeTy *Node) {
+    assert(Int && "Null interval == bad!");
+    assert(Node && "Null Node == bad!");
+
+    BasicBlock *NodeHeader = getNodeHeader(Node);
+
+    if (Visited.count(NodeHeader)) {     // Node already been visited?
+      if (Int->contains(NodeHeader)) {   // Already in this interval...
+        return;
+      } else {                           // In other interval, add as successor
+        if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+          Int->Successors.push_back(NodeHeader);
+      }
+    } else {                             // Otherwise, not in interval yet
+      for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
+             E = IGT::child_end(Node); I != E; ++I) {
+        if (!Int->contains(*I)) {        // If pred not in interval, we can't be
+          if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+            Int->Successors.push_back(NodeHeader);
+          return;                        // See you later
+        }
+      }
+
+      // If we get here, then all of the predecessors of BB are in the interval
+      // already.  In this case, we must add BB to the interval!
+      addNodeToInterval(Int, Node);
+      Visited.insert(NodeHeader);     // The node has now been visited!
+
+      if (Int->isSuccessor(NodeHeader)) {
+        // If we were in the successor list from before... remove from succ list
+        Int->Successors.erase(std::remove(Int->Successors.begin(),
+                                          Int->Successors.end(), NodeHeader),
+                              Int->Successors.end());
+      }
+
+      // Now that we have discovered that Node is in the interval, perhaps some
+      // of its successors are as well?
+      for (typename GT::ChildIteratorType It = GT::child_begin(Node),
+             End = GT::child_end(Node); It != End; ++It)
+        ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
+    }
+  }
+};
+
+typedef IntervalIterator<BasicBlock, Function> function_interval_iterator;
+typedef IntervalIterator<Interval, IntervalPartition>
+                                          interval_part_interval_iterator;
+
+
+inline function_interval_iterator intervals_begin(Function *F,
+                                                  bool DeleteInts = true) {
+  return function_interval_iterator(F, DeleteInts);
+}
+inline function_interval_iterator intervals_end(Function *) {
+  return function_interval_iterator();
+}
+
+inline interval_part_interval_iterator
+   intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
+  return interval_part_interval_iterator(IP, DeleteIntervals);
+}
+
+inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
+  return interval_part_interval_iterator();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
new file mode 100644
index 0000000..274be2b
--- /dev/null
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -0,0 +1,111 @@
+//===- IntervalPartition.h - Interval partition Calculation -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the IntervalPartition class, which
+// calculates and represents the interval partition of a function, or a
+// preexisting interval partition.
+//
+// In this way, the interval partition may be used to reduce a flow graph down
+// to its degenerate single node interval partition (unless it is irreducible).
+//
+// TODO: The IntervalPartition class should take a bool parameter that tells
+// whether it should add the "tails" of an interval to an interval itself or if
+// they should be represented as distinct intervals.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
+#define LLVM_ANALYSIS_INTERVALPARTITION_H
+
+#include "llvm/Analysis/Interval.h"
+#include "llvm/Pass.h"
+#include <map>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//
+// IntervalPartition - This class builds and holds an "interval partition" for
+// a function.  This partition divides the control flow graph into a set of
+// maximal intervals, as defined with the properties above.  Intuitively, an
+// interval is a (possibly nonexistent) loop with a "tail" of non-looping
+// nodes following it.
+//
+class IntervalPartition : public FunctionPass {
+  typedef std::map<BasicBlock*, Interval*> IntervalMapTy;
+  IntervalMapTy IntervalMap;
+
+  typedef std::vector<Interval*> IntervalListTy;
+  Interval *RootInterval;
+  std::vector<Interval*> Intervals;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  IntervalPartition() : FunctionPass(ID), RootInterval(nullptr) {
+    initializeIntervalPartitionPass(*PassRegistry::getPassRegistry());
+  }
+
+  // run - Calculate the interval partition for this function
+  bool runOnFunction(Function &F) override;
+
+  // IntervalPartition ctor - Build a reduced interval partition from an
+  // existing interval graph.  This takes an additional boolean parameter to
+  // distinguish it from a copy constructor.  Always pass in false for now.
+  //
+  IntervalPartition(IntervalPartition &I, bool);
+
+  // print - Show contents in human readable format...
+  void print(raw_ostream &O, const Module* = nullptr) const override;
+
+  // getRootInterval() - Return the root interval that contains the starting
+  // block of the function.
+  inline Interval *getRootInterval() { return RootInterval; }
+
+  // isDegeneratePartition() - Returns true if the interval partition contains
+  // a single interval, and thus cannot be simplified anymore.
+  bool isDegeneratePartition() { return Intervals.size() == 1; }
+
+  // TODO: isIrreducible - look for triangle graph.
+
+  // getBlockInterval - Return the interval that a basic block exists in.
+  inline Interval *getBlockInterval(BasicBlock *BB) {
+    IntervalMapTy::iterator I = IntervalMap.find(BB);
+    return I != IntervalMap.end() ? I->second : nullptr;
+  }
+
+  // getAnalysisUsage - Implement the Pass API
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  // Interface to Intervals vector...
+  const std::vector<Interval*> &getIntervals() const { return Intervals; }
+
+  // releaseMemory - Reset state back to before function was analyzed
+  void releaseMemory() override;
+
+private:
+  // addIntervalToPartition - Add an interval to the internal list of intervals,
+  // and then add mappings from all of the basic blocks in the interval to the
+  // interval itself (in the IntervalMap).
+  //
+  void addIntervalToPartition(Interval *I);
+
+  // updatePredecessors - Interval generation only sets the successor fields of
+  // the interval data structures.  After interval generation is complete,
+  // run through all of the intervals and propagate successor info as
+  // predecessor info.
+  //
+  void updatePredecessors(Interval *Int);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/JumpInstrTableInfo.h b/include/llvm/Analysis/JumpInstrTableInfo.h
new file mode 100644
index 0000000..54760aa
--- /dev/null
+++ b/include/llvm/Analysis/JumpInstrTableInfo.h
@@ -0,0 +1,60 @@
+//===-- JumpInstrTableInfo.h: Info for Jump-Instruction Tables --*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Information about jump-instruction tables that have been created by
+/// JumpInstrTables pass.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
+#define LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
+
+#include <vector>
+
+namespace llvm {
+class Function;
+class FunctionType;
+
+/// This class stores information about jump-instruction tables created by the
+/// JumpInstrTables pass (in lib/CodeGen/JumpInstrTables.cpp). Each table is a
+/// map from a function type to a vector of pairs. The first element of each
+/// pair is the function that has the jumptable annotation. The second element
+/// is a function that was declared by JumpInstrTables and used to replace all
+/// address-taking sites for the original function.
+///
+/// The information in this pass is used in AsmPrinter
+/// (lib/CodeGen/AsmPrinter/AsmPrinter.cpp) to generate the required assembly
+/// for the jump-instruction tables.
+class JumpInstrTableInfo : public ImmutablePass {
+public:
+  static char ID;
+
+  JumpInstrTableInfo();
+  virtual ~JumpInstrTableInfo();
+  const char *getPassName() const override {
+    return "Jump-Instruction Table Info";
+  }
+
+  typedef std::pair<Function *, Function *> JumpPair;
+  typedef DenseMap<FunctionType *, std::vector<JumpPair> > JumpTables;
+
+  /// Inserts an entry in a table, adding the table if it doesn't exist.
+  void insertEntry(FunctionType *TableFunTy, Function *Target, Function *Jump);
+
+  /// Gets the tables.
+  const JumpTables &getTables() const { return Tables; }
+
+private:
+  JumpTables Tables;
+};
+}
+
+#endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */
diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h
new file mode 100644
index 0000000..70a4df5
--- /dev/null
+++ b/include/llvm/Analysis/LazyCallGraph.h
@@ -0,0 +1,566 @@
+//===- LazyCallGraph.h - Analysis of a Module's call graph ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Implements a lazy call graph analysis and related passes for the new pass
+/// manager.
+///
+/// NB: This is *not* a traditional call graph! It is a graph which models both
+/// the current calls and potential calls. As a consequence there are many
+/// edges in this call graph that do not correspond to a 'call' or 'invoke'
+/// instruction.
+///
+/// The primary use cases of this graph analysis is to facilitate iterating
+/// across the functions of a module in ways that ensure all callees are
+/// visited prior to a caller (given any SCC constraints), or vice versa. As
+/// such is it particularly well suited to organizing CGSCC optimizations such
+/// as inlining, outlining, argument promotion, etc. That is its primary use
+/// case and motivates the design. It may not be appropriate for other
+/// purposes. The use graph of functions or some other conservative analysis of
+/// call instructions may be interesting for optimizations and subsequent
+/// analyses which don't work in the context of an overly specified
+/// potential-call-edge graph.
+///
+/// To understand the specific rules and nature of this call graph analysis,
+/// see the documentation of the \c LazyCallGraph below.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZY_CALL_GRAPH
+#define LLVM_ANALYSIS_LAZY_CALL_GRAPH
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Allocator.h"
+#include <iterator>
+
+namespace llvm {
+class ModuleAnalysisManager;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief A lazily constructed view of the call graph of a module.
+///
+/// With the edges of this graph, the motivating constraint that we are
+/// attempting to maintain is that function-local optimization, CGSCC-local
+/// optimizations, and optimizations transforming a pair of functions connected
+/// by an edge in the graph, do not invalidate a bottom-up traversal of the SCC
+/// DAG. That is, no optimizations will delete, remove, or add an edge such
+/// that functions already visited in a bottom-up order of the SCC DAG are no
+/// longer valid to have visited, or such that functions not yet visited in
+/// a bottom-up order of the SCC DAG are not required to have already been
+/// visited.
+///
+/// Within this constraint, the desire is to minimize the merge points of the
+/// SCC DAG. The greater the fanout of the SCC DAG and the fewer merge points
+/// in the SCC DAG, the more independence there is in optimizing within it.
+/// There is a strong desire to enable parallelization of optimizations over
+/// the call graph, and both limited fanout and merge points will (artificially
+/// in some cases) limit the scaling of such an effort.
+///
+/// To this end, graph represents both direct and any potential resolution to
+/// an indirect call edge. Another way to think about it is that it represents
+/// both the direct call edges and any direct call edges that might be formed
+/// through static optimizations. Specifically, it considers taking the address
+/// of a function to be an edge in the call graph because this might be
+/// forwarded to become a direct call by some subsequent function-local
+/// optimization. The result is that the graph closely follows the use-def
+/// edges for functions. Walking "up" the graph can be done by looking at all
+/// of the uses of a function.
+///
+/// The roots of the call graph are the external functions and functions
+/// escaped into global variables. Those functions can be called from outside
+/// of the module or via unknowable means in the IR -- we may not be able to
+/// form even a potential call edge from a function body which may dynamically
+/// load the function and call it.
+///
+/// This analysis still requires updates to remain valid after optimizations
+/// which could potentially change the set of potential callees. The
+/// constraints it operates under only make the traversal order remain valid.
+///
+/// The entire analysis must be re-computed if full interprocedural
+/// optimizations run at any point. For example, globalopt completely
+/// invalidates the information in this analysis.
+///
+/// FIXME: This class is named LazyCallGraph in a lame attempt to distinguish
+/// it from the existing CallGraph. At some point, it is expected that this
+/// will be the only call graph and it will be renamed accordingly.
+class LazyCallGraph {
+public:
+  class Node;
+  class SCC;
+  typedef SmallVector<PointerUnion<Function *, Node *>, 4> NodeVectorT;
+  typedef SmallVectorImpl<PointerUnion<Function *, Node *>> NodeVectorImplT;
+
+  /// \brief A lazy iterator used for both the entry nodes and child nodes.
+  ///
+  /// When this iterator is dereferenced, if not yet available, a function will
+  /// be scanned for "calls" or uses of functions and its child information
+  /// will be constructed. All of these results are accumulated and cached in
+  /// the graph.
+  class iterator
+      : public iterator_adaptor_base<iterator, NodeVectorImplT::iterator,
+                                     std::forward_iterator_tag, Node> {
+    friend class LazyCallGraph;
+    friend class LazyCallGraph::Node;
+
+    LazyCallGraph *G;
+    NodeVectorImplT::iterator E;
+
+    // Build the iterator for a specific position in a node list.
+    iterator(LazyCallGraph &G, NodeVectorImplT::iterator NI,
+             NodeVectorImplT::iterator E)
+        : iterator_adaptor_base(NI), G(&G), E(E) {
+      while (I != E && I->isNull())
+        ++I;
+    }
+
+  public:
+    iterator() {}
+
+    using iterator_adaptor_base::operator++;
+    iterator &operator++() {
+      do {
+        ++I;
+      } while (I != E && I->isNull());
+      return *this;
+    }
+
+    reference operator*() const {
+      if (I->is<Node *>())
+        return *I->get<Node *>();
+
+      Function *F = I->get<Function *>();
+      Node &ChildN = G->get(*F);
+      *I = &ChildN;
+      return ChildN;
+    }
+  };
+
+  /// \brief A node in the call graph.
+  ///
+  /// This represents a single node. It's primary roles are to cache the list of
+  /// callees, de-duplicate and provide fast testing of whether a function is
+  /// a callee, and facilitate iteration of child nodes in the graph.
+  class Node {
+    friend class LazyCallGraph;
+    friend class LazyCallGraph::SCC;
+
+    LazyCallGraph *G;
+    Function &F;
+
+    // We provide for the DFS numbering and Tarjan walk lowlink numbers to be
+    // stored directly within the node.
+    int DFSNumber;
+    int LowLink;
+
+    mutable NodeVectorT Callees;
+    DenseMap<Function *, size_t> CalleeIndexMap;
+
+    /// \brief Basic constructor implements the scanning of F into Callees and
+    /// CalleeIndexMap.
+    Node(LazyCallGraph &G, Function &F);
+
+    /// \brief Internal helper to insert a callee.
+    void insertEdgeInternal(Function &Callee);
+
+    /// \brief Internal helper to insert a callee.
+    void insertEdgeInternal(Node &CalleeN);
+
+    /// \brief Internal helper to remove a callee from this node.
+    void removeEdgeInternal(Function &Callee);
+
+  public:
+    typedef LazyCallGraph::iterator iterator;
+
+    Function &getFunction() const {
+      return F;
+    };
+
+    iterator begin() const {
+      return iterator(*G, Callees.begin(), Callees.end());
+    }
+    iterator end() const { return iterator(*G, Callees.end(), Callees.end()); }
+
+    /// Equality is defined as address equality.
+    bool operator==(const Node &N) const { return this == &N; }
+    bool operator!=(const Node &N) const { return !operator==(N); }
+  };
+
+  /// \brief An SCC of the call graph.
+  ///
+  /// This represents a Strongly Connected Component of the call graph as
+  /// a collection of call graph nodes. While the order of nodes in the SCC is
+  /// stable, it is not any particular order.
+  class SCC {
+    friend class LazyCallGraph;
+    friend class LazyCallGraph::Node;
+
+    LazyCallGraph *G;
+    SmallPtrSet<SCC *, 1> ParentSCCs;
+    SmallVector<Node *, 1> Nodes;
+
+    SCC(LazyCallGraph &G) : G(&G) {}
+
+    void insert(Node &N);
+
+    void
+    internalDFS(SmallVectorImpl<std::pair<Node *, Node::iterator>> &DFSStack,
+                SmallVectorImpl<Node *> &PendingSCCStack, Node *N,
+                SmallVectorImpl<SCC *> &ResultSCCs);
+
+  public:
+    typedef SmallVectorImpl<Node *>::const_iterator iterator;
+    typedef pointee_iterator<SmallPtrSet<SCC *, 1>::const_iterator> parent_iterator;
+
+    iterator begin() const { return Nodes.begin(); }
+    iterator end() const { return Nodes.end(); }
+
+    parent_iterator parent_begin() const { return ParentSCCs.begin(); }
+    parent_iterator parent_end() const { return ParentSCCs.end(); }
+
+    iterator_range<parent_iterator> parents() const {
+      return iterator_range<parent_iterator>(parent_begin(), parent_end());
+    }
+
+    /// \brief Test if this SCC is a parent of \a C.
+    bool isParentOf(const SCC &C) const { return C.isChildOf(*this); }
+
+    /// \brief Test if this SCC is an ancestor of \a C.
+    bool isAncestorOf(const SCC &C) const { return C.isDescendantOf(*this); }
+
+    /// \brief Test if this SCC is a child of \a C.
+    bool isChildOf(const SCC &C) const {
+      return ParentSCCs.count(const_cast<SCC *>(&C));
+    }
+
+    /// \brief Test if this SCC is a descendant of \a C.
+    bool isDescendantOf(const SCC &C) const;
+
+    ///@{
+    /// \name Mutation API
+    ///
+    /// These methods provide the core API for updating the call graph in the
+    /// presence of a (potentially still in-flight) DFS-found SCCs.
+    ///
+    /// Note that these methods sometimes have complex runtimes, so be careful
+    /// how you call them.
+
+    /// \brief Insert an edge from one node in this SCC to another in this SCC.
+    ///
+    /// By the definition of an SCC, this does not change the nature or make-up
+    /// of any SCCs.
+    void insertIntraSCCEdge(Node &CallerN, Node &CalleeN);
+
+    /// \brief Insert an edge whose tail is in this SCC and head is in some
+    /// child SCC.
+    ///
+    /// There must be an existing path from the caller to the callee. This
+    /// operation is inexpensive and does not change the set of SCCs in the
+    /// graph.
+    void insertOutgoingEdge(Node &CallerN, Node &CalleeN);
+
+    /// \brief Insert an edge whose tail is in a descendant SCC and head is in
+    /// this SCC.
+    ///
+    /// There must be an existing path from the callee to the caller in this
+    /// case. NB! This is has the potential to be a very expensive function. It
+    /// inherently forms a cycle in the prior SCC DAG and we have to merge SCCs
+    /// to resolve that cycle. But finding all of the SCCs which participate in
+    /// the cycle can in the worst case require traversing every SCC in the
+    /// graph. Every attempt is made to avoid that, but passes must still
+    /// exercise caution calling this routine repeatedly.
+    ///
+    /// FIXME: We could possibly optimize this quite a bit for cases where the
+    /// caller and callee are very nearby in the graph. See comments in the
+    /// implementation for details, but that use case might impact users.
+    SmallVector<SCC *, 1> insertIncomingEdge(Node &CallerN, Node &CalleeN);
+
+    /// \brief Remove an edge whose source is in this SCC and target is *not*.
+    ///
+    /// This removes an inter-SCC edge. All inter-SCC edges originating from
+    /// this SCC have been fully explored by any in-flight DFS SCC formation,
+    /// so this is always safe to call once you have the source SCC.
+    ///
+    /// This operation does not change the set of SCCs or the members of the
+    /// SCCs and so is very inexpensive. It may change the connectivity graph
+    /// of the SCCs though, so be careful calling this while iterating over
+    /// them.
+    void removeInterSCCEdge(Node &CallerN, Node &CalleeN);
+
+    /// \brief Remove an edge which is entirely within this SCC.
+    ///
+    /// Both the \a Caller and the \a Callee must be within this SCC. Removing
+    /// such an edge make break cycles that form this SCC and thus this
+    /// operation may change the SCC graph significantly. In particular, this
+    /// operation will re-form new SCCs based on the remaining connectivity of
+    /// the graph. The following invariants are guaranteed to hold after
+    /// calling this method:
+    ///
+    /// 1) This SCC is still an SCC in the graph.
+    /// 2) This SCC will be the parent of any new SCCs. Thus, this SCC is
+    ///    preserved as the root of any new SCC directed graph formed.
+    /// 3) No SCC other than this SCC has its member set changed (this is
+    ///    inherent in the definition of removing such an edge).
+    /// 4) All of the parent links of the SCC graph will be updated to reflect
+    ///    the new SCC structure.
+    /// 5) All SCCs formed out of this SCC, excluding this SCC, will be
+    ///    returned in a vector.
+    /// 6) The order of the SCCs in the vector will be a valid postorder
+    ///    traversal of the new SCCs.
+    ///
+    /// These invariants are very important to ensure that we can build
+    /// optimization pipeliens on top of the CGSCC pass manager which
+    /// intelligently update the SCC graph without invalidating other parts of
+    /// the SCC graph.
+    ///
+    /// The runtime complexity of this method is, in the worst case, O(V+E)
+    /// where V is the number of nodes in this SCC and E is the number of edges
+    /// leaving the nodes in this SCC. Note that E includes both edges within
+    /// this SCC and edges from this SCC to child SCCs. Some effort has been
+    /// made to minimize the overhead of common cases such as self-edges and
+    /// edge removals which result in a spanning tree with no more cycles.
+    SmallVector<SCC *, 1> removeIntraSCCEdge(Node &CallerN, Node &CalleeN);
+
+    ///@}
+  };
+
+  /// \brief A post-order depth-first SCC iterator over the call graph.
+  ///
+  /// This iterator triggers the Tarjan DFS-based formation of the SCC DAG for
+  /// the call graph, walking it lazily in depth-first post-order. That is, it
+  /// always visits SCCs for a callee prior to visiting the SCC for a caller
+  /// (when they are in different SCCs).
+  class postorder_scc_iterator
+      : public iterator_facade_base<postorder_scc_iterator,
+                                    std::forward_iterator_tag, SCC> {
+    friend class LazyCallGraph;
+    friend class LazyCallGraph::Node;
+
+    /// \brief Nonce type to select the constructor for the end iterator.
+    struct IsAtEndT {};
+
+    LazyCallGraph *G;
+    SCC *C;
+
+    // Build the begin iterator for a node.
+    postorder_scc_iterator(LazyCallGraph &G) : G(&G) {
+      C = G.getNextSCCInPostOrder();
+    }
+
+    // Build the end iterator for a node. This is selected purely by overload.
+    postorder_scc_iterator(LazyCallGraph &G, IsAtEndT /*Nonce*/)
+        : G(&G), C(nullptr) {}
+
+  public:
+    bool operator==(const postorder_scc_iterator &Arg) const {
+      return G == Arg.G && C == Arg.C;
+    }
+
+    reference operator*() const { return *C; }
+
+    using iterator_facade_base::operator++;
+    postorder_scc_iterator &operator++() {
+      C = G->getNextSCCInPostOrder();
+      return *this;
+    }
+  };
+
+  /// \brief Construct a graph for the given module.
+  ///
+  /// This sets up the graph and computes all of the entry points of the graph.
+  /// No function definitions are scanned until their nodes in the graph are
+  /// requested during traversal.
+  LazyCallGraph(Module &M);
+
+  LazyCallGraph(LazyCallGraph &&G);
+  LazyCallGraph &operator=(LazyCallGraph &&RHS);
+
+  iterator begin() {
+    return iterator(*this, EntryNodes.begin(), EntryNodes.end());
+  }
+  iterator end() { return iterator(*this, EntryNodes.end(), EntryNodes.end()); }
+
+  postorder_scc_iterator postorder_scc_begin() {
+    return postorder_scc_iterator(*this);
+  }
+  postorder_scc_iterator postorder_scc_end() {
+    return postorder_scc_iterator(*this, postorder_scc_iterator::IsAtEndT());
+  }
+
+  iterator_range<postorder_scc_iterator> postorder_sccs() {
+    return iterator_range<postorder_scc_iterator>(postorder_scc_begin(),
+                                                  postorder_scc_end());
+  }
+
+  /// \brief Lookup a function in the graph which has already been scanned and
+  /// added.
+  Node *lookup(const Function &F) const { return NodeMap.lookup(&F); }
+
+  /// \brief Lookup a function's SCC in the graph.
+  ///
+  /// \returns null if the function hasn't been assigned an SCC via the SCC
+  /// iterator walk.
+  SCC *lookupSCC(Node &N) const { return SCCMap.lookup(&N); }
+
+  /// \brief Get a graph node for a given function, scanning it to populate the
+  /// graph data as necessary.
+  Node &get(Function &F) {
+    Node *&N = NodeMap[&F];
+    if (N)
+      return *N;
+
+    return insertInto(F, N);
+  }
+
+  ///@{
+  /// \name Pre-SCC Mutation API
+  ///
+  /// These methods are only valid to call prior to forming any SCCs for this
+  /// call graph. They can be used to update the core node-graph during
+  /// a node-based inorder traversal that precedes any SCC-based traversal.
+  ///
+  /// Once you begin manipulating a call graph's SCCs, you must perform all
+  /// mutation of the graph via the SCC methods.
+
+  /// \brief Update the call graph after inserting a new edge.
+  void insertEdge(Node &Caller, Function &Callee);
+
+  /// \brief Update the call graph after inserting a new edge.
+  void insertEdge(Function &Caller, Function &Callee) {
+    return insertEdge(get(Caller), Callee);
+  }
+
+  /// \brief Update the call graph after deleting an edge.
+  void removeEdge(Node &Caller, Function &Callee);
+
+  /// \brief Update the call graph after deleting an edge.
+  void removeEdge(Function &Caller, Function &Callee) {
+    return removeEdge(get(Caller), Callee);
+  }
+
+  ///@}
+
+private:
+  /// \brief Allocator that holds all the call graph nodes.
+  SpecificBumpPtrAllocator<Node> BPA;
+
+  /// \brief Maps function->node for fast lookup.
+  DenseMap<const Function *, Node *> NodeMap;
+
+  /// \brief The entry nodes to the graph.
+  ///
+  /// These nodes are reachable through "external" means. Put another way, they
+  /// escape at the module scope.
+  NodeVectorT EntryNodes;
+
+  /// \brief Map of the entry nodes in the graph to their indices in
+  /// \c EntryNodes.
+  DenseMap<Function *, size_t> EntryIndexMap;
+
+  /// \brief Allocator that holds all the call graph SCCs.
+  SpecificBumpPtrAllocator<SCC> SCCBPA;
+
+  /// \brief Maps Function -> SCC for fast lookup.
+  DenseMap<Node *, SCC *> SCCMap;
+
+  /// \brief The leaf SCCs of the graph.
+  ///
+  /// These are all of the SCCs which have no children.
+  SmallVector<SCC *, 4> LeafSCCs;
+
+  /// \brief Stack of nodes in the DFS walk.
+  SmallVector<std::pair<Node *, iterator>, 4> DFSStack;
+
+  /// \brief Set of entry nodes not-yet-processed into SCCs.
+  SmallVector<Function *, 4> SCCEntryNodes;
+
+  /// \brief Stack of nodes the DFS has walked but not yet put into a SCC.
+  SmallVector<Node *, 4> PendingSCCStack;
+
+  /// \brief Counter for the next DFS number to assign.
+  int NextDFSNumber;
+
+  /// \brief Helper to insert a new function, with an already looked-up entry in
+  /// the NodeMap.
+  Node &insertInto(Function &F, Node *&MappedN);
+
+  /// \brief Helper to update pointers back to the graph object during moves.
+  void updateGraphPtrs();
+
+  /// \brief Helper to form a new SCC out of the top of a DFSStack-like
+  /// structure.
+  SCC *formSCC(Node *RootN, SmallVectorImpl<Node *> &NodeStack);
+
+  /// \brief Retrieve the next node in the post-order SCC walk of the call graph.
+  SCC *getNextSCCInPostOrder();
+};
+
+// Provide GraphTraits specializations for call graphs.
+template <> struct GraphTraits<LazyCallGraph::Node *> {
+  typedef LazyCallGraph::Node NodeType;
+  typedef LazyCallGraph::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) { return N; }
+  static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
+  static ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+template <> struct GraphTraits<LazyCallGraph *> {
+  typedef LazyCallGraph::Node NodeType;
+  typedef LazyCallGraph::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) { return N; }
+  static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
+  static ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+
+/// \brief An analysis pass which computes the call graph for a module.
+class LazyCallGraphAnalysis {
+public:
+  /// \brief Inform generic clients of the result type.
+  typedef LazyCallGraph Result;
+
+  static void *ID() { return (void *)&PassID; }
+
+  /// \brief Compute the \c LazyCallGraph for a the module \c M.
+  ///
+  /// This just builds the set of entry points to the call graph. The rest is
+  /// built lazily as it is walked.
+  LazyCallGraph run(Module *M) { return LazyCallGraph(*M); }
+
+private:
+  static char PassID;
+};
+
+/// \brief A pass which prints the call graph to a \c raw_ostream.
+///
+/// This is primarily useful for testing the analysis.
+class LazyCallGraphPrinterPass {
+  raw_ostream &OS;
+
+public:
+  explicit LazyCallGraphPrinterPass(raw_ostream &OS);
+
+  PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM);
+
+  static StringRef name() { return "LazyCallGraphPrinterPass"; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
new file mode 100644
index 0000000..2fe7386
--- /dev/null
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -0,0 +1,81 @@
+//===- LazyValueInfo.h - Value constraint analysis --------------*- 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 interface for lazy computation of value constraint
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
+#define LLVM_ANALYSIS_LAZYVALUEINFO_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class Constant;
+  class DataLayout;
+  class TargetLibraryInfo;
+  class Value;
+  
+/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
+/// information.
+class LazyValueInfo : public FunctionPass {
+  const DataLayout *DL;
+  class TargetLibraryInfo *TLI;
+  void *PImpl;
+  LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
+  void operator=(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
+public:
+  static char ID;
+  LazyValueInfo() : FunctionPass(ID), PImpl(nullptr) {
+    initializeLazyValueInfoPass(*PassRegistry::getPassRegistry());
+  }
+  ~LazyValueInfo() { assert(!PImpl && "releaseMemory not called"); }
+
+  /// Tristate - This is used to return true/false/dunno results.
+  enum Tristate {
+    Unknown = -1, False = 0, True = 1
+  };
+  
+  
+  // Public query interface.
+  
+  /// getPredicateOnEdge - Determine whether the specified value comparison
+  /// with a constant is known to be true or false on the specified CFG edge.
+  /// Pred is a CmpInst predicate.
+  Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
+                              BasicBlock *FromBB, BasicBlock *ToBB);
+  
+  
+  /// getConstant - Determine whether the specified value is known to be a
+  /// constant at the end of the specified block.  Return null if not.
+  Constant *getConstant(Value *V, BasicBlock *BB);
+
+  /// getConstantOnEdge - Determine whether the specified value is known to be a
+  /// constant on the specified edge.  Return null if not.
+  Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB);
+  
+  /// threadEdge - Inform the analysis cache that we have threaded an edge from
+  /// PredBB to OldSucc to be from PredBB to NewSucc instead.
+  void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
+  
+  /// eraseBlock - Inform the analysis cache that we have erased a block.
+  void eraseBlock(BasicBlock *BB);
+  
+  // Implementation boilerplate.
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void releaseMemory() override;
+  bool runOnFunction(Function &F) override;
+};
+
+}  // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h
new file mode 100644
index 0000000..4c03c92
--- /dev/null
+++ b/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -0,0 +1,73 @@
+//===- LibCallAliasAnalysis.h - Implement AliasAnalysis for libcalls ------===//
+//
+//                     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 LibCallAliasAnalysis class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
+#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class LibCallInfo;
+  struct LibCallFunctionInfo;
+  
+  /// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo.
+  struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis {
+    static char ID; // Class identification
+    
+    LibCallInfo *LCI;
+    
+    explicit LibCallAliasAnalysis(LibCallInfo *LC = nullptr)
+        : FunctionPass(ID), LCI(LC) {
+      initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
+    }
+    explicit LibCallAliasAnalysis(char &ID, LibCallInfo *LC)
+        : FunctionPass(ID), LCI(LC) {
+      initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
+    }
+    ~LibCallAliasAnalysis();
+    
+    ModRefResult getModRefInfo(ImmutableCallSite CS,
+                               const Location &Loc) override;
+ 
+    ModRefResult getModRefInfo(ImmutableCallSite CS1,
+                               ImmutableCallSite CS2) override {
+      // TODO: Could compare two direct calls against each other if we cared to.
+      return AliasAnalysis::getModRefInfo(CS1, CS2);
+    }
+
+    void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+    bool runOnFunction(Function &F) override {
+      InitializeAliasAnalysis(this);                 // set up super class
+      return false;
+    }
+    
+    /// getAdjustedAnalysisPointer - This method is used when a pass implements
+    /// an analysis interface through multiple inheritance.  If needed, it
+    /// should override this to adjust the this pointer as needed for the
+    /// specified pass info.
+    void *getAdjustedAnalysisPointer(const void *PI) override {
+      if (PI == &AliasAnalysis::ID)
+        return (AliasAnalysis*)this;
+      return this;
+    }
+    
+  private:
+    ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
+                                       ImmutableCallSite CS,
+                                       const Location &Loc);
+  };
+}  // End of llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h
new file mode 100644
index 0000000..8bd747f
--- /dev/null
+++ b/include/llvm/Analysis/LibCallSemantics.h
@@ -0,0 +1,167 @@
+//===- LibCallSemantics.h - Describe library semantics --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces that can be used to describe language specific
+// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
+#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H
+
+#include "llvm/Analysis/AliasAnalysis.h"
+
+namespace llvm {
+
+  /// LibCallLocationInfo - This struct describes a set of memory locations that
+  /// are accessed by libcalls.  Identification of a location is doing with a
+  /// simple callback function.
+  ///
+  /// For example, the LibCallInfo may be set up to model the behavior of
+  /// standard libm functions.  The location that they may be interested in is
+  /// an abstract location that represents errno for the current target.  In
+  /// this case, a location for errno is anything such that the predicate
+  /// returns true.  On Mac OS X, this predicate would return true if the
+  /// pointer is the result of a call to "__error()".
+  ///
+  /// Locations can also be defined in a constant-sensitive way.  For example,
+  /// it is possible to define a location that returns true iff it is passed
+  /// into the call as a specific argument.  This is useful for modeling things
+  /// like "printf", which can store to memory, but only through pointers passed
+  /// with a '%n' constraint.
+  ///
+  struct LibCallLocationInfo {
+    // TODO: Flags: isContextSensitive etc.
+    
+    /// isLocation - Return a LocResult if the specified pointer refers to this
+    /// location for the specified call site.  This returns "Yes" if we can tell
+    /// that the pointer *does definitely* refer to the location, "No" if we can
+    /// tell that the location *definitely does not* refer to the location, and
+    /// returns "Unknown" if we cannot tell for certain.
+    enum LocResult {
+      Yes, No, Unknown
+    };
+    LocResult (*isLocation)(ImmutableCallSite CS,
+                            const AliasAnalysis::Location &Loc);
+  };
+  
+  /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
+  /// records the behavior of one libcall that is known by the optimizer.  This
+  /// captures things like the side effects of the call.  Side effects are
+  /// modeled both universally (in the readnone/readonly) sense, but also
+  /// potentially against a set of abstract locations defined by the optimizer.
+  /// This allows an optimizer to define that some libcall (e.g. sqrt) is
+  /// side-effect free except that it might modify errno (thus, the call is
+  /// *not* universally readonly).  Or it might say that the side effects
+  /// are unknown other than to say that errno is not modified.
+  ///
+  struct LibCallFunctionInfo {
+    /// Name - This is the name of the libcall this describes.
+    const char *Name;
+    
+    /// TODO: Constant folding function: Constant* vector -> Constant*.
+    
+    /// UniversalBehavior - This captures the absolute mod/ref behavior without
+    /// any specific context knowledge.  For example, if the function is known
+    /// to be readonly, this would be set to 'ref'.  If known to be readnone,
+    /// this is set to NoModRef.
+    AliasAnalysis::ModRefResult UniversalBehavior;
+    
+    /// LocationMRInfo - This pair captures info about whether a specific
+    /// location is modified or referenced by a libcall.
+    struct LocationMRInfo {
+      /// LocationID - ID # of the accessed location or ~0U for array end.
+      unsigned LocationID;
+      /// MRInfo - Mod/Ref info for this location.
+      AliasAnalysis::ModRefResult MRInfo;
+    };
+    
+    /// DetailsType - Indicate the sense of the LocationDetails array.  This
+    /// controls how the LocationDetails array is interpreted.
+    enum {
+      /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
+      /// *only* mod/ref behavior of this function is captured by the
+      /// LocationDetails array.  If we are trying to say that 'sqrt' can only
+      /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
+      /// array and have DetailsType set to DoesOnly.
+      DoesOnly,
+      
+      /// DoesNot - If DetailsType is set to DoesNot, then the sense of the
+      /// LocationDetails array is completely inverted.  This means that we *do
+      /// not* know everything about the side effects of this libcall, but we do
+      /// know things that the libcall cannot do.  This is useful for complex
+      /// functions like 'ctime' which have crazy mod/ref behavior, but are
+      /// known to never read or write errno.  In this case, we'd have
+      /// {errnoloc,modref} in the LocationDetails array and DetailsType would
+      /// be set to DoesNot, indicating that ctime does not read or write the
+      /// errno location.
+      DoesNot
+    } DetailsType;
+    
+    /// LocationDetails - This is a pointer to an array of LocationMRInfo
+    /// structs which indicates the behavior of the libcall w.r.t. specific
+    /// locations.  For example, if this libcall is known to only modify
+    /// 'errno', it would have a LocationDetails array with the errno ID and
+    /// 'mod' in it.  See the DetailsType field for how this is interpreted.
+    ///
+    /// In the "DoesOnly" case, this information is 'may' information for: there
+    /// is no guarantee that the specified side effect actually does happen,
+    /// just that it could.  In the "DoesNot" case, this is 'must not' info.
+    ///
+    /// If this pointer is null, no details are known.
+    ///
+    const LocationMRInfo *LocationDetails;
+  };
+  
+  
+  /// LibCallInfo - Abstract interface to query about library call information.
+  /// Instances of this class return known information about some set of
+  /// libcalls.
+  /// 
+  class LibCallInfo {
+    // Implementation details of this object, private.
+    mutable void *Impl;
+    mutable const LibCallLocationInfo *Locations;
+    mutable unsigned NumLocations;
+  public:
+    LibCallInfo() : Impl(nullptr), Locations(nullptr), NumLocations(0) {}
+    virtual ~LibCallInfo();
+    
+    //===------------------------------------------------------------------===//
+    //  Accessor Methods: Efficient access to contained data.
+    //===------------------------------------------------------------------===//
+    
+    /// getLocationInfo - Return information about the specified LocationID.
+    const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
+    
+    
+    /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
+    /// the specified function if we have it.  If not, return null.
+    const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
+    
+    
+    //===------------------------------------------------------------------===//
+    //  Implementation Methods: Subclasses should implement these.
+    //===------------------------------------------------------------------===//
+    
+    /// getLocationInfo - Return descriptors for the locations referenced by
+    /// this set of libcalls.
+    virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
+      return 0;
+    }
+    
+    /// getFunctionInfoArray - Return an array of descriptors that describe the
+    /// set of libcalls represented by this LibCallInfo object.  This array is
+    /// terminated by an entry with a NULL name.
+    virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h
new file mode 100644
index 0000000..7c88b13
--- /dev/null
+++ b/include/llvm/Analysis/Lint.h
@@ -0,0 +1,49 @@
+//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- 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 lint interfaces that can be used for some sanity checking
+// of input to the system, and for checking that transformations
+// haven't done something bad. In contrast to the Verifier, the Lint checker
+// checks for undefined behavior or constructions with likely unintended
+// behavior.
+//
+// To see what specifically is checked, look at Lint.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LINT_H
+#define LLVM_ANALYSIS_LINT_H
+
+namespace llvm {
+
+class FunctionPass;
+class Module;
+class Function;
+
+/// @brief Create a lint pass.
+///
+/// Check a module or function.
+FunctionPass *createLintPass();
+
+/// @brief Check a module.
+///
+/// This should only be used for debugging, because it plays games with
+/// PassManagers and stuff.
+void lintModule(
+  const Module &M    ///< The module to be checked
+);
+
+// lintFunction - Check a function.
+void lintFunction(
+  const Function &F  ///< The function to be checked
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
new file mode 100644
index 0000000..25c5928
--- /dev/null
+++ b/include/llvm/Analysis/Loads.h
@@ -0,0 +1,58 @@
+//===- Loads.h - Local load analysis --------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares simple local analyses for load instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOADS_H
+#define LLVM_ANALYSIS_LOADS_H
+
+#include "llvm/IR/BasicBlock.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class DataLayout;
+class MDNode;
+
+/// isSafeToLoadUnconditionally - Return true if we know that executing a load
+/// from this value cannot trap.  If it is not obviously safe to load from the
+/// specified pointer, we do a quick local scan of the basic block containing
+/// ScanFrom, to determine if the address is already accessed.
+bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
+                                 unsigned Align,
+                                 const DataLayout *TD = nullptr);
+
+/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
+/// the instruction before ScanFrom) checking to see if we have the value at
+/// the memory address *Ptr locally available within a small number of
+///  instructions. If the value is available, return it.
+///
+/// If not, return the iterator for the last validated instruction that the 
+/// value would be live through.  If we scanned the entire block and didn't
+/// find something that invalidates *Ptr or provides it, ScanFrom would be
+/// left at begin() and this returns null.  ScanFrom could also be left 
+///
+/// MaxInstsToScan specifies the maximum instructions to scan in the block.
+/// If it is set to 0, it will scan the whole block. You can also optionally
+/// specify an alias analysis implementation, which makes this more precise.
+///
+/// If TBAATag is non-null and a load or store is found, the TBAA tag from the
+/// load or store is recorded there.  If there is no TBAA tag or if no access
+/// is found, it is left unmodified.
+Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
+                                BasicBlock::iterator &ScanFrom,
+                                unsigned MaxInstsToScan = 6,
+                                AliasAnalysis *AA = nullptr,
+                                MDNode **TBAATag = nullptr);
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
new file mode 100644
index 0000000..bef03e9
--- /dev/null
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -0,0 +1,781 @@
+//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator -------*- 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 LoopInfo class that is used to identify natural loops
+// and determine the loop depth of various nodes of the CFG.  A natural loop
+// has exactly one entry-point, which is called the header. Note that natural
+// loops may actually be several loops that share the same header node.
+//
+// This analysis calculates the nesting structure of loops in a function.  For
+// each natural loop identified, this analysis identifies natural loops
+// contained entirely within the loop and the basic blocks the make up the loop.
+//
+// It can calculate on the fly various bits of information, for example:
+//
+//  * whether there is a preheader for the loop
+//  * the number of back edges to the header
+//  * whether or not a particular block branches out of the loop
+//  * the successor blocks of the loop
+//  * the loop depth
+//  * etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPINFO_H
+#define LLVM_ANALYSIS_LOOPINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+
+namespace llvm {
+
+template<typename T>
+inline void RemoveFromVector(std::vector<T*> &V, T *N) {
+  typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
+  assert(I != V.end() && "N is not in this list!");
+  V.erase(I);
+}
+
+class DominatorTree;
+class LoopInfo;
+class Loop;
+class MDNode;
+class PHINode;
+class raw_ostream;
+template<class N> class DominatorTreeBase;
+template<class N, class M> class LoopInfoBase;
+template<class N, class M> class LoopBase;
+
+//===----------------------------------------------------------------------===//
+/// LoopBase class - Instances of this class are used to represent loops that
+/// are detected in the flow graph
+///
+template<class BlockT, class LoopT>
+class LoopBase {
+  LoopT *ParentLoop;
+  // SubLoops - Loops contained entirely within this one.
+  std::vector<LoopT *> SubLoops;
+
+  // Blocks - The list of blocks in this loop.  First entry is the header node.
+  std::vector<BlockT*> Blocks;
+
+  SmallPtrSet<const BlockT*, 8> DenseBlockSet;
+
+  LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
+  const LoopBase<BlockT, LoopT>&
+    operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
+public:
+  /// Loop ctor - This creates an empty loop.
+  LoopBase() : ParentLoop(nullptr) {}
+  ~LoopBase() {
+    for (size_t i = 0, e = SubLoops.size(); i != e; ++i)
+      delete SubLoops[i];
+  }
+
+  /// getLoopDepth - Return the nesting level of this loop.  An outer-most
+  /// loop has depth 1, for consistency with loop depth values used for basic
+  /// blocks, where depth 0 is used for blocks not inside any loops.
+  unsigned getLoopDepth() const {
+    unsigned D = 1;
+    for (const LoopT *CurLoop = ParentLoop; CurLoop;
+         CurLoop = CurLoop->ParentLoop)
+      ++D;
+    return D;
+  }
+  BlockT *getHeader() const { return Blocks.front(); }
+  LoopT *getParentLoop() const { return ParentLoop; }
+
+  /// setParentLoop is a raw interface for bypassing addChildLoop.
+  void setParentLoop(LoopT *L) { ParentLoop = L; }
+
+  /// contains - Return true if the specified loop is contained within in
+  /// this loop.
+  ///
+  bool contains(const LoopT *L) const {
+    if (L == this) return true;
+    if (!L)        return false;
+    return contains(L->getParentLoop());
+  }
+
+  /// contains - Return true if the specified basic block is in this loop.
+  ///
+  bool contains(const BlockT *BB) const {
+    return DenseBlockSet.count(BB);
+  }
+
+  /// contains - Return true if the specified instruction is in this loop.
+  ///
+  template<class InstT>
+  bool contains(const InstT *Inst) const {
+    return contains(Inst->getParent());
+  }
+
+  /// iterator/begin/end - Return the loops contained entirely within this loop.
+  ///
+  const std::vector<LoopT *> &getSubLoops() const { return SubLoops; }
+  std::vector<LoopT *> &getSubLoopsVector() { return SubLoops; }
+  typedef typename std::vector<LoopT *>::const_iterator iterator;
+  typedef typename std::vector<LoopT *>::const_reverse_iterator
+    reverse_iterator;
+  iterator begin() const { return SubLoops.begin(); }
+  iterator end() const { return SubLoops.end(); }
+  reverse_iterator rbegin() const { return SubLoops.rbegin(); }
+  reverse_iterator rend() const { return SubLoops.rend(); }
+  bool empty() const { return SubLoops.empty(); }
+
+  /// getBlocks - Get a list of the basic blocks which make up this loop.
+  ///
+  const std::vector<BlockT*> &getBlocks() const { return Blocks; }
+  typedef typename std::vector<BlockT*>::const_iterator block_iterator;
+  block_iterator block_begin() const { return Blocks.begin(); }
+  block_iterator block_end() const { return Blocks.end(); }
+
+  /// getNumBlocks - Get the number of blocks in this loop in constant time.
+  unsigned getNumBlocks() const {
+    return Blocks.size();
+  }
+
+  /// isLoopExiting - True if terminator in the block can branch to another
+  /// block that is outside of the current loop.
+  ///
+  bool isLoopExiting(const BlockT *BB) const {
+    typedef GraphTraits<const BlockT*> BlockTraits;
+    for (typename BlockTraits::ChildIteratorType SI =
+         BlockTraits::child_begin(BB),
+         SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
+      if (!contains(*SI))
+        return true;
+    }
+    return false;
+  }
+
+  /// getNumBackEdges - Calculate the number of back edges to the loop header
+  ///
+  unsigned getNumBackEdges() const {
+    unsigned NumBackEdges = 0;
+    BlockT *H = getHeader();
+
+    typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+    for (typename InvBlockTraits::ChildIteratorType I =
+         InvBlockTraits::child_begin(H),
+         E = InvBlockTraits::child_end(H); I != E; ++I)
+      if (contains(*I))
+        ++NumBackEdges;
+
+    return NumBackEdges;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // APIs for simple analysis of the loop.
+  //
+  // Note that all of these methods can fail on general loops (ie, there may not
+  // be a preheader, etc).  For best success, the loop simplification and
+  // induction variable canonicalization pass should be used to normalize loops
+  // for easy analysis.  These methods assume canonical loops.
+
+  /// getExitingBlocks - Return all blocks inside the loop that have successors
+  /// outside of the loop.  These are the blocks _inside of the current loop_
+  /// which branch out.  The returned list is always unique.
+  ///
+  void getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const;
+
+  /// getExitingBlock - If getExitingBlocks would return exactly one block,
+  /// return that block. Otherwise return null.
+  BlockT *getExitingBlock() const;
+
+  /// getExitBlocks - Return all of the successor blocks of this loop.  These
+  /// are the blocks _outside of the current loop_ which are branched to.
+  ///
+  void getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const;
+
+  /// getExitBlock - If getExitBlocks would return exactly one block,
+  /// return that block. Otherwise return null.
+  BlockT *getExitBlock() const;
+
+  /// Edge type.
+  typedef std::pair<const BlockT*, const BlockT*> Edge;
+
+  /// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
+  void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const;
+
+  /// getLoopPreheader - If there is a preheader for this loop, return it.  A
+  /// loop has a preheader if there is only one edge to the header of the loop
+  /// from outside of the loop.  If this is the case, the block branching to the
+  /// header of the loop is the preheader node.
+  ///
+  /// This method returns null if there is no preheader for the loop.
+  ///
+  BlockT *getLoopPreheader() const;
+
+  /// getLoopPredecessor - If the given loop's header has exactly one unique
+  /// predecessor outside the loop, return it. Otherwise return null.
+  /// This is less strict that the loop "preheader" concept, which requires
+  /// the predecessor to have exactly one successor.
+  ///
+  BlockT *getLoopPredecessor() const;
+
+  /// getLoopLatch - If there is a single latch block for this loop, return it.
+  /// A latch block is a block that contains a branch back to the header.
+  BlockT *getLoopLatch() const;
+
+  /// getLoopLatches - Return all loop latch blocks of this loop. A latch block
+  /// is a block that contains a branch back to the header.
+  void getLoopLatches(SmallVectorImpl<BlockT *> &LoopLatches) const {
+    BlockT *H = getHeader();
+    typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+    for (typename InvBlockTraits::ChildIteratorType I =
+         InvBlockTraits::child_begin(H),
+         E = InvBlockTraits::child_end(H); I != E; ++I)
+      if (contains(*I))
+        LoopLatches.push_back(*I);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // APIs for updating loop information after changing the CFG
+  //
+
+  /// addBasicBlockToLoop - This method is used by other analyses to update loop
+  /// information.  NewBB is set to be a new member of the current loop.
+  /// Because of this, it is added as a member of all parent loops, and is added
+  /// to the specified LoopInfo object as being in the current basic block.  It
+  /// is not valid to replace the loop header with this method.
+  ///
+  void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LI);
+
+  /// replaceChildLoopWith - This is used when splitting loops up.  It replaces
+  /// the OldChild entry in our children list with NewChild, and updates the
+  /// parent pointer of OldChild to be null and the NewChild to be this loop.
+  /// This updates the loop depth of the new child.
+  void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild);
+
+  /// addChildLoop - Add the specified loop to be a child of this loop.  This
+  /// updates the loop depth of the new child.
+  ///
+  void addChildLoop(LoopT *NewChild) {
+    assert(!NewChild->ParentLoop && "NewChild already has a parent!");
+    NewChild->ParentLoop = static_cast<LoopT *>(this);
+    SubLoops.push_back(NewChild);
+  }
+
+  /// removeChildLoop - This removes the specified child from being a subloop of
+  /// this loop.  The loop is not deleted, as it will presumably be inserted
+  /// into another loop.
+  LoopT *removeChildLoop(iterator I) {
+    assert(I != SubLoops.end() && "Cannot remove end iterator!");
+    LoopT *Child = *I;
+    assert(Child->ParentLoop == this && "Child is not a child of this loop!");
+    SubLoops.erase(SubLoops.begin()+(I-begin()));
+    Child->ParentLoop = nullptr;
+    return Child;
+  }
+
+  /// addBlockEntry - This adds a basic block directly to the basic block list.
+  /// This should only be used by transformations that create new loops.  Other
+  /// transformations should use addBasicBlockToLoop.
+  void addBlockEntry(BlockT *BB) {
+    Blocks.push_back(BB);
+    DenseBlockSet.insert(BB);
+  }
+
+  /// reverseBlocks - interface to reverse Blocks[from, end of loop] in this loop
+  void reverseBlock(unsigned from) {
+    std::reverse(Blocks.begin() + from, Blocks.end());
+  }
+
+  /// reserveBlocks- interface to do reserve() for Blocks
+  void reserveBlocks(unsigned size) {
+    Blocks.reserve(size);
+  }
+
+  /// moveToHeader - This method is used to move BB (which must be part of this
+  /// loop) to be the loop header of the loop (the block that dominates all
+  /// others).
+  void moveToHeader(BlockT *BB) {
+    if (Blocks[0] == BB) return;
+    for (unsigned i = 0; ; ++i) {
+      assert(i != Blocks.size() && "Loop does not contain BB!");
+      if (Blocks[i] == BB) {
+        Blocks[i] = Blocks[0];
+        Blocks[0] = BB;
+        return;
+      }
+    }
+  }
+
+  /// removeBlockFromLoop - This removes the specified basic block from the
+  /// current loop, updating the Blocks as appropriate.  This does not update
+  /// the mapping in the LoopInfo class.
+  void removeBlockFromLoop(BlockT *BB) {
+    RemoveFromVector(Blocks, BB);
+    DenseBlockSet.erase(BB);
+  }
+
+  /// verifyLoop - Verify loop structure
+  void verifyLoop() const;
+
+  /// verifyLoop - Verify loop structure of this loop and all nested loops.
+  void verifyLoopNest(DenseSet<const LoopT*> *Loops) const;
+
+  void print(raw_ostream &OS, unsigned Depth = 0) const;
+
+protected:
+  friend class LoopInfoBase<BlockT, LoopT>;
+  explicit LoopBase(BlockT *BB) : ParentLoop(nullptr) {
+    Blocks.push_back(BB);
+    DenseBlockSet.insert(BB);
+  }
+};
+
+template<class BlockT, class LoopT>
+raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
+  Loop.print(OS);
+  return OS;
+}
+
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template class LoopBase<BasicBlock, Loop>;
+#endif
+
+class Loop : public LoopBase<BasicBlock, Loop> {
+public:
+  Loop() {}
+
+  /// isLoopInvariant - Return true if the specified value is loop invariant
+  ///
+  bool isLoopInvariant(Value *V) const;
+
+  /// hasLoopInvariantOperands - Return true if all the operands of the
+  /// specified instruction are loop invariant.
+  bool hasLoopInvariantOperands(Instruction *I) const;
+
+  /// makeLoopInvariant - If the given value is an instruction inside of the
+  /// loop and it can be hoisted, do so to make it trivially loop-invariant.
+  /// Return true if the value after any hoisting is loop invariant. This
+  /// function can be used as a slightly more aggressive replacement for
+  /// isLoopInvariant.
+  ///
+  /// If InsertPt is specified, it is the point to hoist instructions to.
+  /// If null, the terminator of the loop preheader is used.
+  ///
+  bool makeLoopInvariant(Value *V, bool &Changed,
+                         Instruction *InsertPt = nullptr) const;
+
+  /// makeLoopInvariant - If the given instruction is inside of the
+  /// loop and it can be hoisted, do so to make it trivially loop-invariant.
+  /// Return true if the instruction after any hoisting is loop invariant. This
+  /// function can be used as a slightly more aggressive replacement for
+  /// isLoopInvariant.
+  ///
+  /// If InsertPt is specified, it is the point to hoist instructions to.
+  /// If null, the terminator of the loop preheader is used.
+  ///
+  bool makeLoopInvariant(Instruction *I, bool &Changed,
+                         Instruction *InsertPt = nullptr) const;
+
+  /// getCanonicalInductionVariable - Check to see if the loop has a canonical
+  /// induction variable: an integer recurrence that starts at 0 and increments
+  /// by one each time through the loop.  If so, return the phi node that
+  /// corresponds to it.
+  ///
+  /// The IndVarSimplify pass transforms loops to have a canonical induction
+  /// variable.
+  ///
+  PHINode *getCanonicalInductionVariable() const;
+
+  /// isLCSSAForm - Return true if the Loop is in LCSSA form
+  bool isLCSSAForm(DominatorTree &DT) const;
+
+  /// isLoopSimplifyForm - Return true if the Loop is in the form that
+  /// the LoopSimplify form transforms loops to, which is sometimes called
+  /// normal form.
+  bool isLoopSimplifyForm() const;
+
+  /// isSafeToClone - Return true if the loop body is safe to clone in practice.
+  bool isSafeToClone() const;
+
+  /// Returns true if the loop is annotated parallel.
+  ///
+  /// A parallel loop can be assumed to not contain any dependencies between
+  /// iterations by the compiler. That is, any loop-carried dependency checking
+  /// can be skipped completely when parallelizing the loop on the target
+  /// machine. Thus, if the parallel loop information originates from the
+  /// programmer, e.g. via the OpenMP parallel for pragma, it is the
+  /// programmer's responsibility to ensure there are no loop-carried
+  /// dependencies. The final execution order of the instructions across
+  /// iterations is not guaranteed, thus, the end result might or might not
+  /// implement actual concurrent execution of instructions across multiple
+  /// iterations.
+  bool isAnnotatedParallel() const;
+
+  /// Return the llvm.loop loop id metadata node for this loop if it is present.
+  ///
+  /// If this loop contains the same llvm.loop metadata on each branch to the
+  /// header then the node is returned. If any latch instruction does not
+  /// contain llvm.loop or or if multiple latches contain different nodes then
+  /// 0 is returned.
+  MDNode *getLoopID() const;
+  /// Set the llvm.loop loop id metadata for this loop.
+  ///
+  /// The LoopID metadata node will be added to each terminator instruction in
+  /// the loop that branches to the loop header.
+  ///
+  /// The LoopID metadata node should have one or more operands and the first
+  /// operand should should be the node itself.
+  void setLoopID(MDNode *LoopID) const;
+
+  /// hasDedicatedExits - Return true if no exit block for the loop
+  /// has a predecessor that is outside the loop.
+  bool hasDedicatedExits() const;
+
+  /// getUniqueExitBlocks - Return all unique successor blocks of this loop.
+  /// These are the blocks _outside of the current loop_ which are branched to.
+  /// This assumes that loop exits are in canonical form.
+  ///
+  void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
+
+  /// getUniqueExitBlock - If getUniqueExitBlocks would return exactly one
+  /// block, return that block. Otherwise return null.
+  BasicBlock *getUniqueExitBlock() const;
+
+  void dump() const;
+
+  /// \brief Return the debug location of the start of this loop.
+  /// This looks for a BB terminating instruction with a known debug
+  /// location by looking at the preheader and header blocks. If it
+  /// cannot find a terminating instruction with location information,
+  /// it returns an unknown location.
+  DebugLoc getStartLoc() const {
+    DebugLoc StartLoc;
+    BasicBlock *HeadBB;
+
+    // Try the pre-header first.
+    if ((HeadBB = getLoopPreheader()) != nullptr) {
+      StartLoc = HeadBB->getTerminator()->getDebugLoc();
+      if (!StartLoc.isUnknown())
+        return StartLoc;
+    }
+
+    // If we have no pre-header or there are no instructions with debug
+    // info in it, try the header.
+    HeadBB = getHeader();
+    if (HeadBB)
+      StartLoc = HeadBB->getTerminator()->getDebugLoc();
+
+    return StartLoc;
+  }
+
+private:
+  friend class LoopInfoBase<BasicBlock, Loop>;
+  explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
+};
+
+//===----------------------------------------------------------------------===//
+/// LoopInfo - This class builds and contains all of the top level loop
+/// structures in the specified function.
+///
+
+template<class BlockT, class LoopT>
+class LoopInfoBase {
+  // BBMap - Mapping of basic blocks to the inner most loop they occur in
+  DenseMap<BlockT *, LoopT *> BBMap;
+  std::vector<LoopT *> TopLevelLoops;
+  friend class LoopBase<BlockT, LoopT>;
+  friend class LoopInfo;
+
+  void operator=(const LoopInfoBase &) LLVM_DELETED_FUNCTION;
+  LoopInfoBase(const LoopInfo &) LLVM_DELETED_FUNCTION;
+public:
+  LoopInfoBase() { }
+  ~LoopInfoBase() { releaseMemory(); }
+
+  void releaseMemory() {
+    for (typename std::vector<LoopT *>::iterator I =
+         TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I)
+      delete *I;   // Delete all of the loops...
+
+    BBMap.clear();                           // Reset internal state of analysis
+    TopLevelLoops.clear();
+  }
+
+  /// iterator/begin/end - The interface to the top-level loops in the current
+  /// function.
+  ///
+  typedef typename std::vector<LoopT *>::const_iterator iterator;
+  typedef typename std::vector<LoopT *>::const_reverse_iterator
+    reverse_iterator;
+  iterator begin() const { return TopLevelLoops.begin(); }
+  iterator end() const { return TopLevelLoops.end(); }
+  reverse_iterator rbegin() const { return TopLevelLoops.rbegin(); }
+  reverse_iterator rend() const { return TopLevelLoops.rend(); }
+  bool empty() const { return TopLevelLoops.empty(); }
+
+  /// getLoopFor - Return the inner most loop that BB lives in.  If a basic
+  /// block is in no loop (for example the entry node), null is returned.
+  ///
+  LoopT *getLoopFor(const BlockT *BB) const {
+    return BBMap.lookup(const_cast<BlockT*>(BB));
+  }
+
+  /// operator[] - same as getLoopFor...
+  ///
+  const LoopT *operator[](const BlockT *BB) const {
+    return getLoopFor(BB);
+  }
+
+  /// getLoopDepth - Return the loop nesting level of the specified block.  A
+  /// depth of 0 means the block is not inside any loop.
+  ///
+  unsigned getLoopDepth(const BlockT *BB) const {
+    const LoopT *L = getLoopFor(BB);
+    return L ? L->getLoopDepth() : 0;
+  }
+
+  // isLoopHeader - True if the block is a loop header node
+  bool isLoopHeader(BlockT *BB) const {
+    const LoopT *L = getLoopFor(BB);
+    return L && L->getHeader() == BB;
+  }
+
+  /// removeLoop - This removes the specified top-level loop from this loop info
+  /// object.  The loop is not deleted, as it will presumably be inserted into
+  /// another loop.
+  LoopT *removeLoop(iterator I) {
+    assert(I != end() && "Cannot remove end iterator!");
+    LoopT *L = *I;
+    assert(!L->getParentLoop() && "Not a top-level loop!");
+    TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin()));
+    return L;
+  }
+
+  /// changeLoopFor - Change the top-level loop that contains BB to the
+  /// specified loop.  This should be used by transformations that restructure
+  /// the loop hierarchy tree.
+  void changeLoopFor(BlockT *BB, LoopT *L) {
+    if (!L) {
+      BBMap.erase(BB);
+      return;
+    }
+    BBMap[BB] = L;
+  }
+
+  /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+  /// list with the indicated loop.
+  void changeTopLevelLoop(LoopT *OldLoop,
+                          LoopT *NewLoop) {
+    typename std::vector<LoopT *>::iterator I =
+                 std::find(TopLevelLoops.begin(), TopLevelLoops.end(), OldLoop);
+    assert(I != TopLevelLoops.end() && "Old loop not at top level!");
+    *I = NewLoop;
+    assert(!NewLoop->ParentLoop && !OldLoop->ParentLoop &&
+           "Loops already embedded into a subloop!");
+  }
+
+  /// addTopLevelLoop - This adds the specified loop to the collection of
+  /// top-level loops.
+  void addTopLevelLoop(LoopT *New) {
+    assert(!New->getParentLoop() && "Loop already in subloop!");
+    TopLevelLoops.push_back(New);
+  }
+
+  /// removeBlock - This method completely removes BB from all data structures,
+  /// including all of the Loop objects it is nested in and our mapping from
+  /// BasicBlocks to loops.
+  void removeBlock(BlockT *BB) {
+    typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
+    if (I != BBMap.end()) {
+      for (LoopT *L = I->second; L; L = L->getParentLoop())
+        L->removeBlockFromLoop(BB);
+
+      BBMap.erase(I);
+    }
+  }
+
+  // Internals
+
+  static bool isNotAlreadyContainedIn(const LoopT *SubLoop,
+                                      const LoopT *ParentLoop) {
+    if (!SubLoop) return true;
+    if (SubLoop == ParentLoop) return false;
+    return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
+  }
+
+  /// Create the loop forest using a stable algorithm.
+  void Analyze(DominatorTreeBase<BlockT> &DomTree);
+
+  // Debugging
+
+  void print(raw_ostream &OS) const;
+};
+
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template class LoopInfoBase<BasicBlock, Loop>;
+#endif
+
+class LoopInfo : public FunctionPass {
+  LoopInfoBase<BasicBlock, Loop> LI;
+  friend class LoopBase<BasicBlock, Loop>;
+
+  void operator=(const LoopInfo &) LLVM_DELETED_FUNCTION;
+  LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  LoopInfo() : FunctionPass(ID) {
+    initializeLoopInfoPass(*PassRegistry::getPassRegistry());
+  }
+
+  LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; }
+
+  /// iterator/begin/end - The interface to the top-level loops in the current
+  /// function.
+  ///
+  typedef LoopInfoBase<BasicBlock, Loop>::iterator iterator;
+  typedef LoopInfoBase<BasicBlock, Loop>::reverse_iterator reverse_iterator;
+  inline iterator begin() const { return LI.begin(); }
+  inline iterator end() const { return LI.end(); }
+  inline reverse_iterator rbegin() const { return LI.rbegin(); }
+  inline reverse_iterator rend() const { return LI.rend(); }
+  bool empty() const { return LI.empty(); }
+
+  /// getLoopFor - Return the inner most loop that BB lives in.  If a basic
+  /// block is in no loop (for example the entry node), null is returned.
+  ///
+  inline Loop *getLoopFor(const BasicBlock *BB) const {
+    return LI.getLoopFor(BB);
+  }
+
+  /// operator[] - same as getLoopFor...
+  ///
+  inline const Loop *operator[](const BasicBlock *BB) const {
+    return LI.getLoopFor(BB);
+  }
+
+  /// getLoopDepth - Return the loop nesting level of the specified block.  A
+  /// depth of 0 means the block is not inside any loop.
+  ///
+  inline unsigned getLoopDepth(const BasicBlock *BB) const {
+    return LI.getLoopDepth(BB);
+  }
+
+  // isLoopHeader - True if the block is a loop header node
+  inline bool isLoopHeader(BasicBlock *BB) const {
+    return LI.isLoopHeader(BB);
+  }
+
+  /// runOnFunction - Calculate the natural loop information.
+  ///
+  bool runOnFunction(Function &F) override;
+
+  void verifyAnalysis() const override;
+
+  void releaseMemory() override { LI.releaseMemory(); }
+
+  void print(raw_ostream &O, const Module* M = nullptr) const override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// removeLoop - This removes the specified top-level loop from this loop info
+  /// object.  The loop is not deleted, as it will presumably be inserted into
+  /// another loop.
+  inline Loop *removeLoop(iterator I) { return LI.removeLoop(I); }
+
+  /// changeLoopFor - Change the top-level loop that contains BB to the
+  /// specified loop.  This should be used by transformations that restructure
+  /// the loop hierarchy tree.
+  inline void changeLoopFor(BasicBlock *BB, Loop *L) {
+    LI.changeLoopFor(BB, L);
+  }
+
+  /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+  /// list with the indicated loop.
+  inline void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) {
+    LI.changeTopLevelLoop(OldLoop, NewLoop);
+  }
+
+  /// addTopLevelLoop - This adds the specified loop to the collection of
+  /// top-level loops.
+  inline void addTopLevelLoop(Loop *New) {
+    LI.addTopLevelLoop(New);
+  }
+
+  /// removeBlock - This method completely removes BB from all data structures,
+  /// including all of the Loop objects it is nested in and our mapping from
+  /// BasicBlocks to loops.
+  void removeBlock(BasicBlock *BB) {
+    LI.removeBlock(BB);
+  }
+
+  /// updateUnloop - Update LoopInfo after removing the last backedge from a
+  /// loop--now the "unloop". This updates the loop forest and parent loops for
+  /// each block so that Unloop is no longer referenced, but the caller must
+  /// actually delete the Unloop object.
+  void updateUnloop(Loop *Unloop);
+
+  /// replacementPreservesLCSSAForm - Returns true if replacing From with To
+  /// everywhere is guaranteed to preserve LCSSA form.
+  bool replacementPreservesLCSSAForm(Instruction *From, Value *To) {
+    // Preserving LCSSA form is only problematic if the replacing value is an
+    // instruction.
+    Instruction *I = dyn_cast<Instruction>(To);
+    if (!I) return true;
+    // If both instructions are defined in the same basic block then replacement
+    // cannot break LCSSA form.
+    if (I->getParent() == From->getParent())
+      return true;
+    // If the instruction is not defined in a loop then it can safely replace
+    // anything.
+    Loop *ToLoop = getLoopFor(I->getParent());
+    if (!ToLoop) return true;
+    // If the replacing instruction is defined in the same loop as the original
+    // instruction, or in a loop that contains it as an inner loop, then using
+    // it as a replacement will not break LCSSA form.
+    return ToLoop->contains(getLoopFor(From->getParent()));
+  }
+};
+
+
+// Allow clients to walk the list of nested loops...
+template <> struct GraphTraits<const Loop*> {
+  typedef const Loop NodeType;
+  typedef LoopInfo::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const Loop *L) { return L; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+};
+
+template <> struct GraphTraits<Loop*> {
+  typedef Loop NodeType;
+  typedef LoopInfo::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Loop *L) { return L; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
new file mode 100644
index 0000000..948be0f
--- /dev/null
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -0,0 +1,550 @@
+//===- llvm/Analysis/LoopInfoImpl.h - Natural Loop Calculator ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the generic implementation of LoopInfo used for both Loops and
+// MachineLoops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
+#define LLVM_ANALYSIS_LOOPINFOIMPL_H
+
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Dominators.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// APIs for simple analysis of the loop. See header notes.
+
+/// getExitingBlocks - Return all blocks inside the loop that have successors
+/// outside of the loop.  These are the blocks _inside of the current loop_
+/// which branch out.  The returned list is always unique.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
+  typedef GraphTraits<BlockT*> BlockTraits;
+  for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+    for (typename BlockTraits::ChildIteratorType I =
+           BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+         I != E; ++I)
+      if (!contains(*I)) {
+        // Not in current loop? It must be an exit block.
+        ExitingBlocks.push_back(*BI);
+        break;
+      }
+}
+
+/// getExitingBlock - If getExitingBlocks would return exactly one block,
+/// return that block. Otherwise return null.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const {
+  SmallVector<BlockT*, 8> ExitingBlocks;
+  getExitingBlocks(ExitingBlocks);
+  if (ExitingBlocks.size() == 1)
+    return ExitingBlocks[0];
+  return nullptr;
+}
+
+/// getExitBlocks - Return all of the successor blocks of this loop.  These
+/// are the blocks _outside of the current loop_ which are branched to.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
+  typedef GraphTraits<BlockT*> BlockTraits;
+  for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+    for (typename BlockTraits::ChildIteratorType I =
+           BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+         I != E; ++I)
+      if (!contains(*I))
+        // Not in current loop? It must be an exit block.
+        ExitBlocks.push_back(*I);
+}
+
+/// getExitBlock - If getExitBlocks would return exactly one block,
+/// return that block. Otherwise return null.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const {
+  SmallVector<BlockT*, 8> ExitBlocks;
+  getExitBlocks(ExitBlocks);
+  if (ExitBlocks.size() == 1)
+    return ExitBlocks[0];
+  return nullptr;
+}
+
+/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
+  typedef GraphTraits<BlockT*> BlockTraits;
+  for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+    for (typename BlockTraits::ChildIteratorType I =
+           BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+         I != E; ++I)
+      if (!contains(*I))
+        // Not in current loop? It must be an exit block.
+        ExitEdges.push_back(Edge(*BI, *I));
+}
+
+/// getLoopPreheader - If there is a preheader for this loop, return it.  A
+/// loop has a preheader if there is only one edge to the header of the loop
+/// from outside of the loop.  If this is the case, the block branching to the
+/// header of the loop is the preheader node.
+///
+/// This method returns null if there is no preheader for the loop.
+///
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const {
+  // Keep track of nodes outside the loop branching to the header...
+  BlockT *Out = getLoopPredecessor();
+  if (!Out) return nullptr;
+
+  // Make sure there is only one exit out of the preheader.
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
+  ++SI;
+  if (SI != BlockTraits::child_end(Out))
+    return nullptr;  // Multiple exits from the block, must not be a preheader.
+
+  // The predecessor has exactly one successor, so it is a preheader.
+  return Out;
+}
+
+/// getLoopPredecessor - If the given loop's header has exactly one unique
+/// predecessor outside the loop, return it. Otherwise return null.
+/// This is less strict that the loop "preheader" concept, which requires
+/// the predecessor to have exactly one successor.
+///
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
+  // Keep track of nodes outside the loop branching to the header...
+  BlockT *Out = nullptr;
+
+  // Loop over the predecessors of the header node...
+  BlockT *Header = getHeader();
+  typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+  for (typename InvBlockTraits::ChildIteratorType PI =
+         InvBlockTraits::child_begin(Header),
+         PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
+    typename InvBlockTraits::NodeType *N = *PI;
+    if (!contains(N)) {     // If the block is not in the loop...
+      if (Out && Out != N)
+        return nullptr;     // Multiple predecessors outside the loop
+      Out = N;
+    }
+  }
+
+  // Make sure there is only one exit out of the preheader.
+  assert(Out && "Header of loop has no predecessors from outside loop?");
+  return Out;
+}
+
+/// getLoopLatch - If there is a single latch block for this loop, return it.
+/// A latch block is a block that contains a branch back to the header.
+template<class BlockT, class LoopT>
+BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const {
+  BlockT *Header = getHeader();
+  typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+  typename InvBlockTraits::ChildIteratorType PI =
+    InvBlockTraits::child_begin(Header);
+  typename InvBlockTraits::ChildIteratorType PE =
+    InvBlockTraits::child_end(Header);
+  BlockT *Latch = nullptr;
+  for (; PI != PE; ++PI) {
+    typename InvBlockTraits::NodeType *N = *PI;
+    if (contains(N)) {
+      if (Latch) return nullptr;
+      Latch = N;
+    }
+  }
+
+  return Latch;
+}
+
+//===----------------------------------------------------------------------===//
+// APIs for updating loop information after changing the CFG
+//
+
+/// addBasicBlockToLoop - This method is used by other analyses to update loop
+/// information.  NewBB is set to be a new member of the current loop.
+/// Because of this, it is added as a member of all parent loops, and is added
+/// to the specified LoopInfo object as being in the current basic block.  It
+/// is not valid to replace the loop header with this method.
+///
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) {
+  assert((Blocks.empty() || LIB[getHeader()] == this) &&
+         "Incorrect LI specified for this loop!");
+  assert(NewBB && "Cannot add a null basic block to the loop!");
+  assert(!LIB[NewBB] && "BasicBlock already in the loop!");
+
+  LoopT *L = static_cast<LoopT *>(this);
+
+  // Add the loop mapping to the LoopInfo object...
+  LIB.BBMap[NewBB] = L;
+
+  // Add the basic block to this loop and all parent loops...
+  while (L) {
+    L->addBlockEntry(NewBB);
+    L = L->getParentLoop();
+  }
+}
+
+/// replaceChildLoopWith - This is used when splitting loops up.  It replaces
+/// the OldChild entry in our children list with NewChild, and updates the
+/// parent pointer of OldChild to be null and the NewChild to be this loop.
+/// This updates the loop depth of the new child.
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::
+replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild) {
+  assert(OldChild->ParentLoop == this && "This loop is already broken!");
+  assert(!NewChild->ParentLoop && "NewChild already has a parent!");
+  typename std::vector<LoopT *>::iterator I =
+    std::find(SubLoops.begin(), SubLoops.end(), OldChild);
+  assert(I != SubLoops.end() && "OldChild not in loop!");
+  *I = NewChild;
+  OldChild->ParentLoop = nullptr;
+  NewChild->ParentLoop = static_cast<LoopT *>(this);
+}
+
+/// verifyLoop - Verify loop structure
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::verifyLoop() const {
+#ifndef NDEBUG
+  assert(!Blocks.empty() && "Loop header is missing");
+
+  // Setup for using a depth-first iterator to visit every block in the loop.
+  SmallVector<BlockT*, 8> ExitBBs;
+  getExitBlocks(ExitBBs);
+  llvm::SmallPtrSet<BlockT*, 8> VisitSet;
+  VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
+  df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
+    BI = df_ext_begin(getHeader(), VisitSet),
+    BE = df_ext_end(getHeader(), VisitSet);
+
+  // Keep track of the number of BBs visited.
+  unsigned NumVisited = 0;
+
+  // Check the individual blocks.
+  for ( ; BI != BE; ++BI) {
+    BlockT *BB = *BI;
+    bool HasInsideLoopSuccs = false;
+    bool HasInsideLoopPreds = false;
+    SmallVector<BlockT *, 2> OutsideLoopPreds;
+
+    typedef GraphTraits<BlockT*> BlockTraits;
+    for (typename BlockTraits::ChildIteratorType SI =
+           BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
+         SI != SE; ++SI)
+      if (contains(*SI)) {
+        HasInsideLoopSuccs = true;
+        break;
+      }
+    typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+    for (typename InvBlockTraits::ChildIteratorType PI =
+           InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
+         PI != PE; ++PI) {
+      BlockT *N = *PI;
+      if (contains(N))
+        HasInsideLoopPreds = true;
+      else
+        OutsideLoopPreds.push_back(N);
+    }
+
+    if (BB == getHeader()) {
+        assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
+    } else if (!OutsideLoopPreds.empty()) {
+      // A non-header loop shouldn't be reachable from outside the loop,
+      // though it is permitted if the predecessor is not itself actually
+      // reachable.
+      BlockT *EntryBB = BB->getParent()->begin();
+      for (BlockT *CB : depth_first(EntryBB))
+        for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
+          assert(CB != OutsideLoopPreds[i] &&
+                 "Loop has multiple entry points!");
+    }
+    assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!");
+    assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
+    assert(BB != getHeader()->getParent()->begin() &&
+           "Loop contains function entry block!");
+
+    NumVisited++;
+  }
+
+  assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
+
+  // Check the subloops.
+  for (iterator I = begin(), E = end(); I != E; ++I)
+    // Each block in each subloop should be contained within this loop.
+    for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
+         BI != BE; ++BI) {
+        assert(contains(*BI) &&
+               "Loop does not contain all the blocks of a subloop!");
+    }
+
+  // Check the parent loop pointer.
+  if (ParentLoop) {
+    assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) !=
+           ParentLoop->end() &&
+           "Loop is not a subloop of its parent!");
+  }
+#endif
+}
+
+/// verifyLoop - Verify loop structure of this loop and all nested loops.
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::verifyLoopNest(
+  DenseSet<const LoopT*> *Loops) const {
+  Loops->insert(static_cast<const LoopT *>(this));
+  // Verify this loop.
+  verifyLoop();
+  // Verify the subloops.
+  for (iterator I = begin(), E = end(); I != E; ++I)
+    (*I)->verifyLoopNest(Loops);
+}
+
+template<class BlockT, class LoopT>
+void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const {
+  OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
+       << " containing: ";
+
+  for (unsigned i = 0; i < getBlocks().size(); ++i) {
+    if (i) OS << ",";
+    BlockT *BB = getBlocks()[i];
+    BB->printAsOperand(OS, false);
+    if (BB == getHeader())    OS << "<header>";
+    if (BB == getLoopLatch()) OS << "<latch>";
+    if (isLoopExiting(BB))    OS << "<exiting>";
+  }
+  OS << "\n";
+
+  for (iterator I = begin(), E = end(); I != E; ++I)
+    (*I)->print(OS, Depth+2);
+}
+
+//===----------------------------------------------------------------------===//
+/// Stable LoopInfo Analysis - Build a loop tree using stable iterators so the
+/// result does / not depend on use list (block predecessor) order.
+///
+
+/// Discover a subloop with the specified backedges such that: All blocks within
+/// this loop are mapped to this loop or a subloop. And all subloops within this
+/// loop have their parent loop set to this loop or a subloop.
+template<class BlockT, class LoopT>
+static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
+                                  LoopInfoBase<BlockT, LoopT> *LI,
+                                  DominatorTreeBase<BlockT> &DomTree) {
+  typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+
+  unsigned NumBlocks = 0;
+  unsigned NumSubloops = 0;
+
+  // Perform a backward CFG traversal using a worklist.
+  std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end());
+  while (!ReverseCFGWorklist.empty()) {
+    BlockT *PredBB = ReverseCFGWorklist.back();
+    ReverseCFGWorklist.pop_back();
+
+    LoopT *Subloop = LI->getLoopFor(PredBB);
+    if (!Subloop) {
+      if (!DomTree.isReachableFromEntry(PredBB))
+        continue;
+
+      // This is an undiscovered block. Map it to the current loop.
+      LI->changeLoopFor(PredBB, L);
+      ++NumBlocks;
+      if (PredBB == L->getHeader())
+          continue;
+      // Push all block predecessors on the worklist.
+      ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
+                                InvBlockTraits::child_begin(PredBB),
+                                InvBlockTraits::child_end(PredBB));
+    }
+    else {
+      // This is a discovered block. Find its outermost discovered loop.
+      while (LoopT *Parent = Subloop->getParentLoop())
+        Subloop = Parent;
+
+      // If it is already discovered to be a subloop of this loop, continue.
+      if (Subloop == L)
+        continue;
+
+      // Discover a subloop of this loop.
+      Subloop->setParentLoop(L);
+      ++NumSubloops;
+      NumBlocks += Subloop->getBlocks().capacity();
+      PredBB = Subloop->getHeader();
+      // Continue traversal along predecessors that are not loop-back edges from
+      // within this subloop tree itself. Note that a predecessor may directly
+      // reach another subloop that is not yet discovered to be a subloop of
+      // this loop, which we must traverse.
+      for (typename InvBlockTraits::ChildIteratorType PI =
+             InvBlockTraits::child_begin(PredBB),
+             PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) {
+        if (LI->getLoopFor(*PI) != Subloop)
+          ReverseCFGWorklist.push_back(*PI);
+      }
+    }
+  }
+  L->getSubLoopsVector().reserve(NumSubloops);
+  L->reserveBlocks(NumBlocks);
+}
+
+namespace {
+/// Populate all loop data in a stable order during a single forward DFS.
+template<class BlockT, class LoopT>
+class PopulateLoopsDFS {
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
+  LoopInfoBase<BlockT, LoopT> *LI;
+  DenseSet<const BlockT *> VisitedBlocks;
+  std::vector<std::pair<BlockT*, SuccIterTy> > DFSStack;
+
+public:
+  PopulateLoopsDFS(LoopInfoBase<BlockT, LoopT> *li):
+    LI(li) {}
+
+  void traverse(BlockT *EntryBlock);
+
+protected:
+  void insertIntoLoop(BlockT *Block);
+
+  BlockT *dfsSource() { return DFSStack.back().first; }
+  SuccIterTy &dfsSucc() { return DFSStack.back().second; }
+  SuccIterTy dfsSuccEnd() { return BlockTraits::child_end(dfsSource()); }
+
+  void pushBlock(BlockT *Block) {
+    DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block)));
+  }
+};
+} // anonymous
+
+/// Top-level driver for the forward DFS within the loop.
+template<class BlockT, class LoopT>
+void PopulateLoopsDFS<BlockT, LoopT>::traverse(BlockT *EntryBlock) {
+  pushBlock(EntryBlock);
+  VisitedBlocks.insert(EntryBlock);
+  while (!DFSStack.empty()) {
+    // Traverse the leftmost path as far as possible.
+    while (dfsSucc() != dfsSuccEnd()) {
+      BlockT *BB = *dfsSucc();
+      ++dfsSucc();
+      if (!VisitedBlocks.insert(BB).second)
+        continue;
+
+      // Push the next DFS successor onto the stack.
+      pushBlock(BB);
+    }
+    // Visit the top of the stack in postorder and backtrack.
+    insertIntoLoop(dfsSource());
+    DFSStack.pop_back();
+  }
+}
+
+/// Add a single Block to its ancestor loops in PostOrder. If the block is a
+/// subloop header, add the subloop to its parent in PostOrder, then reverse the
+/// Block and Subloop vectors of the now complete subloop to achieve RPO.
+template<class BlockT, class LoopT>
+void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
+  LoopT *Subloop = LI->getLoopFor(Block);
+  if (Subloop && Block == Subloop->getHeader()) {
+    // We reach this point once per subloop after processing all the blocks in
+    // the subloop.
+    if (Subloop->getParentLoop())
+      Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
+    else
+      LI->addTopLevelLoop(Subloop);
+
+    // For convenience, Blocks and Subloops are inserted in postorder. Reverse
+    // the lists, except for the loop header, which is always at the beginning.
+    Subloop->reverseBlock(1);
+    std::reverse(Subloop->getSubLoopsVector().begin(),
+                 Subloop->getSubLoopsVector().end());
+
+    Subloop = Subloop->getParentLoop();
+  }
+  for (; Subloop; Subloop = Subloop->getParentLoop())
+    Subloop->addBlockEntry(Block);
+}
+
+/// Analyze LoopInfo discovers loops during a postorder DominatorTree traversal
+/// interleaved with backward CFG traversals within each subloop
+/// (discoverAndMapSubloop). The backward traversal skips inner subloops, so
+/// this part of the algorithm is linear in the number of CFG edges. Subloop and
+/// Block vectors are then populated during a single forward CFG traversal
+/// (PopulateLoopDFS).
+///
+/// During the two CFG traversals each block is seen three times:
+/// 1) Discovered and mapped by a reverse CFG traversal.
+/// 2) Visited during a forward DFS CFG traversal.
+/// 3) Reverse-inserted in the loop in postorder following forward DFS.
+///
+/// The Block vectors are inclusive, so step 3 requires loop-depth number of
+/// insertions per block.
+template<class BlockT, class LoopT>
+void LoopInfoBase<BlockT, LoopT>::
+Analyze(DominatorTreeBase<BlockT> &DomTree) {
+
+  // Postorder traversal of the dominator tree.
+  DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode();
+  for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot),
+         DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) {
+
+    BlockT *Header = DomIter->getBlock();
+    SmallVector<BlockT *, 4> Backedges;
+
+    // Check each predecessor of the potential loop header.
+    typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+    for (typename InvBlockTraits::ChildIteratorType PI =
+           InvBlockTraits::child_begin(Header),
+           PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
+
+      BlockT *Backedge = *PI;
+
+      // If Header dominates predBB, this is a new loop. Collect the backedges.
+      if (DomTree.dominates(Header, Backedge)
+          && DomTree.isReachableFromEntry(Backedge)) {
+        Backedges.push_back(Backedge);
+      }
+    }
+    // Perform a backward CFG traversal to discover and map blocks in this loop.
+    if (!Backedges.empty()) {
+      LoopT *L = new LoopT(Header);
+      discoverAndMapSubloop(L, ArrayRef<BlockT*>(Backedges), this, DomTree);
+    }
+  }
+  // Perform a single forward CFG traversal to populate block and subloop
+  // vectors for all loops.
+  PopulateLoopsDFS<BlockT, LoopT> DFS(this);
+  DFS.traverse(DomRoot->getBlock());
+}
+
+// Debugging
+template<class BlockT, class LoopT>
+void LoopInfoBase<BlockT, LoopT>::print(raw_ostream &OS) const {
+  for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
+    TopLevelLoops[i]->print(OS);
+#if 0
+  for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
+         E = BBMap.end(); I != E; ++I)
+    OS << "BB '" << I->first->getName() << "' level = "
+       << I->second->getLoopDepth() << "\n";
+#endif
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h
new file mode 100644
index 0000000..e3dd963
--- /dev/null
+++ b/include/llvm/Analysis/LoopIterator.h
@@ -0,0 +1,181 @@
+//===--------- LoopIterator.h - Iterate over loop blocks --------*- 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 iterators to visit the basic blocks within a loop.
+//
+// These iterators currently visit blocks within subloops as well.
+// Unfortunately we have no efficient way of summarizing loop exits which would
+// allow skipping subloops during traversal.
+//
+// If you want to visit all blocks in a loop and don't need an ordered traveral,
+// use Loop::block_begin() instead.
+//
+// This is intentionally designed to work with ill-formed loops in which the
+// backedge has been deleted. The only prerequisite is that all blocks
+// contained within the loop according to the most recent LoopInfo analysis are
+// reachable from the loop header.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
+#define LLVM_ANALYSIS_LOOPITERATOR_H
+
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/LoopInfo.h"
+
+namespace llvm {
+
+class LoopBlocksTraversal;
+
+/// Store the result of a depth first search within basic blocks contained by a
+/// single loop.
+///
+/// TODO: This could be generalized for any CFG region, or the entire CFG.
+class LoopBlocksDFS {
+public:
+  /// Postorder list iterators.
+  typedef std::vector<BasicBlock*>::const_iterator POIterator;
+  typedef std::vector<BasicBlock*>::const_reverse_iterator RPOIterator;
+
+  friend class LoopBlocksTraversal;
+
+private:
+  Loop *L;
+
+  /// Map each block to its postorder number. A block is only mapped after it is
+  /// preorder visited by DFS. It's postorder number is initially zero and set
+  /// to nonzero after it is finished by postorder traversal.
+  DenseMap<BasicBlock*, unsigned> PostNumbers;
+  std::vector<BasicBlock*> PostBlocks;
+
+public:
+  LoopBlocksDFS(Loop *Container) :
+    L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) {
+    PostBlocks.reserve(Container->getNumBlocks());
+  }
+
+  Loop *getLoop() const { return L; }
+
+  /// Traverse the loop blocks and store the DFS result.
+  void perform(LoopInfo *LI);
+
+  /// Return true if postorder numbers are assigned to all loop blocks.
+  bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); }
+
+  /// Iterate over the cached postorder blocks.
+  POIterator beginPostorder() const {
+    assert(isComplete() && "bad loop DFS");
+    return PostBlocks.begin();
+  }
+  POIterator endPostorder() const { return PostBlocks.end(); }
+
+  /// Reverse iterate over the cached postorder blocks.
+  RPOIterator beginRPO() const {
+    assert(isComplete() && "bad loop DFS");
+    return PostBlocks.rbegin();
+  }
+  RPOIterator endRPO() const { return PostBlocks.rend(); }
+
+  /// Return true if this block has been preorder visited.
+  bool hasPreorder(BasicBlock *BB) const { return PostNumbers.count(BB); }
+
+  /// Return true if this block has a postorder number.
+  bool hasPostorder(BasicBlock *BB) const {
+    DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
+    return I != PostNumbers.end() && I->second;
+  }
+
+  /// Get a block's postorder number.
+  unsigned getPostorder(BasicBlock *BB) const {
+    DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
+    assert(I != PostNumbers.end() && "block not visited by DFS");
+    assert(I->second && "block not finished by DFS");
+    return I->second;
+  }
+
+  /// Get a block's reverse postorder number.
+  unsigned getRPO(BasicBlock *BB) const {
+    return 1 + PostBlocks.size() - getPostorder(BB);
+  }
+
+  void clear() {
+    PostNumbers.clear();
+    PostBlocks.clear();
+  }
+};
+
+/// Specialize po_iterator_storage to record postorder numbers.
+template<> class po_iterator_storage<LoopBlocksTraversal, true> {
+  LoopBlocksTraversal &LBT;
+public:
+  po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {}
+  // These functions are defined below.
+  bool insertEdge(BasicBlock *From, BasicBlock *To);
+  void finishPostorder(BasicBlock *BB);
+};
+
+/// Traverse the blocks in a loop using a depth-first search.
+class LoopBlocksTraversal {
+public:
+  /// Graph traversal iterator.
+  typedef po_iterator<BasicBlock*, LoopBlocksTraversal, true> POTIterator;
+
+private:
+  LoopBlocksDFS &DFS;
+  LoopInfo *LI;
+
+public:
+  LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo) :
+    DFS(Storage), LI(LInfo) {}
+
+  /// Postorder traversal over the graph. This only needs to be done once.
+  /// po_iterator "automatically" calls back to visitPreorder and
+  /// finishPostorder to record the DFS result.
+  POTIterator begin() {
+    assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing");
+    assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph");
+    return po_ext_begin(DFS.L->getHeader(), *this);
+  }
+  POTIterator end() {
+    // po_ext_end interface requires a basic block, but ignores its value.
+    return po_ext_end(DFS.L->getHeader(), *this);
+  }
+
+  /// Called by po_iterator upon reaching a block via a CFG edge. If this block
+  /// is contained in the loop and has not been visited, then mark it preorder
+  /// visited and return true.
+  ///
+  /// TODO: If anyone is interested, we could record preorder numbers here.
+  bool visitPreorder(BasicBlock *BB) {
+    if (!DFS.L->contains(LI->getLoopFor(BB)))
+      return false;
+
+    return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
+  }
+
+  /// Called by po_iterator each time it advances, indicating a block's
+  /// postorder.
+  void finishPostorder(BasicBlock *BB) {
+    assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder");
+    DFS.PostBlocks.push_back(BB);
+    DFS.PostNumbers[BB] = DFS.PostBlocks.size();
+  }
+};
+
+inline bool po_iterator_storage<LoopBlocksTraversal, true>::
+insertEdge(BasicBlock *From, BasicBlock *To) {
+  return LBT.visitPreorder(To);
+}
+
+inline void po_iterator_storage<LoopBlocksTraversal, true>::
+finishPostorder(BasicBlock *BB) {
+  LBT.finishPostorder(BB);
+}
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
new file mode 100644
index 0000000..726e286
--- /dev/null
+++ b/include/llvm/Analysis/LoopPass.h
@@ -0,0 +1,165 @@
+//===- LoopPass.h - LoopPass class ----------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines LoopPass class. All loop optimization
+// and transformation passes are derived from LoopPass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPPASS_H
+#define LLVM_ANALYSIS_LOOPPASS_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/LegacyPassManagers.h"
+#include "llvm/Pass.h"
+#include <deque>
+
+namespace llvm {
+
+class LPPassManager;
+class Function;
+class PMStack;
+
+class LoopPass : public Pass {
+public:
+  explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {}
+
+  /// getPrinterPass - Get a pass to print the function corresponding
+  /// to a Loop.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  // runOnLoop - This method should be implemented by the subclass to perform
+  // whatever action is necessary for the specified Loop.
+  virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
+
+  using llvm::Pass::doInitialization;
+  using llvm::Pass::doFinalization;
+
+  // Initialization and finalization hooks.
+  virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
+    return false;
+  }
+
+  // Finalization hook does not supply Loop because at this time
+  // loop nest is completely different.
+  virtual bool doFinalization() { return false; }
+
+  // Check if this pass is suitable for the current LPPassManager, if
+  // available. This pass P is not suitable for a LPPassManager if P
+  // is not preserving higher level analysis info used by other
+  // LPPassManager passes. In such case, pop LPPassManager from the
+  // stack. This will force assignPassManager() to create new
+  // LPPassManger as expected.
+  void preparePassManager(PMStack &PMS) override;
+
+  /// Assign pass manager to manage this pass
+  void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  PassManagerType getPotentialPassManagerType() const override {
+    return PMT_LoopPassManager;
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// SimpleAnalysis - Provides simple interface to update analysis info
+  /// maintained by various passes. Note, if required this interface can
+  /// be extracted into a separate abstract class but it would require
+  /// additional use of multiple inheritance in Pass class hierarchy, something
+  /// we are trying to avoid.
+
+  /// Each loop pass can override these simple analysis hooks to update
+  /// desired analysis information.
+  /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block.
+  virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {}
+
+  /// deleteAnalysisValue - Delete analysis info associated with value V.
+  virtual void deleteAnalysisValue(Value *V, Loop *L) {}
+
+protected:
+  /// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
+  /// and most transformation passes should skip it.
+  bool skipOptnoneFunction(const Loop *L) const;
+};
+
+class LPPassManager : public FunctionPass, public PMDataManager {
+public:
+  static char ID;
+  explicit LPPassManager();
+
+  /// run - Execute all of the passes scheduled for execution.  Keep track of
+  /// whether any of the passes modifies the module, and if so, return true.
+  bool runOnFunction(Function &F) override;
+
+  /// Pass Manager itself does not invalidate any analysis info.
+  // LPPassManager needs LoopInfo.
+  void getAnalysisUsage(AnalysisUsage &Info) const override;
+
+  const char *getPassName() const override {
+    return "Loop Pass Manager";
+  }
+
+  PMDataManager *getAsPMDataManager() override { return this; }
+  Pass *getAsPass() override { return this; }
+
+  /// Print passes managed by this manager
+  void dumpPassStructure(unsigned Offset) override;
+
+  LoopPass *getContainedPass(unsigned N) {
+    assert(N < PassVector.size() && "Pass number out of range!");
+    LoopPass *LP = static_cast<LoopPass *>(PassVector[N]);
+    return LP;
+  }
+
+  PassManagerType getPassManagerType() const override {
+    return PMT_LoopPassManager;
+  }
+
+public:
+  // Delete loop from the loop queue and loop nest (LoopInfo).
+  void deleteLoopFromQueue(Loop *L);
+
+  // Insert loop into the loop queue and add it as a child of the
+  // given parent.
+  void insertLoop(Loop *L, Loop *ParentLoop);
+
+  // Insert a loop into the loop queue.
+  void insertLoopIntoQueue(Loop *L);
+
+  // Reoptimize this loop. LPPassManager will re-insert this loop into the
+  // queue. This allows LoopPass to change loop nest for the loop. This
+  // utility may send LPPassManager into infinite loops so use caution.
+  void redoLoop(Loop *L);
+
+  //===--------------------------------------------------------------------===//
+  /// SimpleAnalysis - Provides simple interface to update analysis info
+  /// maintained by various passes. Note, if required this interface can
+  /// be extracted into a separate abstract class but it would require
+  /// additional use of multiple inheritance in Pass class hierarchy, something
+  /// we are trying to avoid.
+
+  /// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for
+  /// all passes that implement simple analysis interface.
+  void cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L);
+
+  /// deleteSimpleAnalysisValue - Invoke deleteAnalysisValue hook for all passes
+  /// that implement simple analysis interface.
+  void deleteSimpleAnalysisValue(Value *V, Loop *L);
+
+private:
+  std::deque<Loop *> LQ;
+  bool skipThisLoop;
+  bool redoThisLoop;
+  LoopInfo *LI;
+  Loop *CurrentLoop;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
new file mode 100644
index 0000000..d414680
--- /dev/null
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -0,0 +1,276 @@
+//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions identifies calls to builtin functions that allocate
+// or free memory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
+#define LLVM_ANALYSIS_MEMORYBUILTINS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class CallInst;
+class PointerType;
+class DataLayout;
+class TargetLibraryInfo;
+class Type;
+class Value;
+
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
+/// like).
+bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
+                    bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a function that returns a
+/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
+bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
+                 bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates uninitialized memory (such as malloc).
+bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                    bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates zero-filled memory (such as calloc).
+bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                    bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates memory (either malloc, calloc, or strdup like).
+bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                   bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// reallocates memory (such as realloc).
+bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                     bool LookThroughBitCast = false);
+
+/// \brief Tests if a value is a call or invoke to a library function that
+/// allocates memory and never returns null (such as operator new).
+bool isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+                         bool LookThroughBitCast = false);
+
+//===----------------------------------------------------------------------===//
+//  malloc Call Utility Functions.
+//
+
+/// extractMallocCall - Returns the corresponding CallInst if the instruction
+/// is a malloc call.  Since CallInst::CreateMalloc() only creates calls, we
+/// ignore InvokeInst here.
+const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI);
+static inline CallInst *extractMallocCall(Value *I,
+                                          const TargetLibraryInfo *TLI) {
+  return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
+}
+
+/// isArrayMalloc - Returns the corresponding CallInst if the instruction
+/// is a call to malloc whose array size can be determined and the array size
+/// is not constant 1.  Otherwise, return NULL.
+const CallInst *isArrayMalloc(const Value *I, const DataLayout *DL,
+                              const TargetLibraryInfo *TLI);
+
+/// getMallocType - Returns the PointerType resulting from the malloc call.
+/// The PointerType depends on the number of bitcast uses of the malloc call:
+///   0: PointerType is the malloc calls' return type.
+///   1: PointerType is the bitcast's result type.
+///  >1: Unique PointerType cannot be determined, return NULL.
+PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
+
+/// getMallocAllocatedType - Returns the Type allocated by malloc call.
+/// The Type depends on the number of bitcast uses of the malloc call:
+///   0: PointerType is the malloc calls' return type.
+///   1: PointerType is the bitcast's result type.
+///  >1: Unique PointerType cannot be determined, return NULL.
+Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
+
+/// getMallocArraySize - Returns the array size of a malloc call.  If the
+/// argument passed to malloc is a multiple of the size of the malloced type,
+/// then return that multiple.  For non-array mallocs, the multiple is
+/// constant 1.  Otherwise, return NULL for mallocs whose array size cannot be
+/// determined.
+Value *getMallocArraySize(CallInst *CI, const DataLayout *DL,
+                          const TargetLibraryInfo *TLI,
+                          bool LookThroughSExt = false);
+
+
+//===----------------------------------------------------------------------===//
+//  calloc Call Utility Functions.
+//
+
+/// extractCallocCall - Returns the corresponding CallInst if the instruction
+/// is a calloc call.
+const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI);
+static inline CallInst *extractCallocCall(Value *I,
+                                          const TargetLibraryInfo *TLI) {
+  return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  free Call Utility Functions.
+//
+
+/// isFreeCall - Returns non-null if the value is a call to the builtin free()
+const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
+
+static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
+  return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Utility functions to compute size of objects.
+//
+
+/// \brief Compute the size of the object pointed by Ptr. Returns true and the
+/// object size in Size if successful, and false otherwise. In this context, by
+/// object we mean the region of memory starting at Ptr to the end of the
+/// underlying object pointed to by Ptr.
+/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
+/// byval arguments, and global variables.
+bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL,
+                   const TargetLibraryInfo *TLI, bool RoundToAlign = false);
+
+
+
+typedef std::pair<APInt, APInt> SizeOffsetType;
+
+/// \brief Evaluate the size and offset of an object pointed to by a Value*
+/// statically. Fails if size or offset are not known at compile time.
+class ObjectSizeOffsetVisitor
+  : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
+
+  const DataLayout *DL;
+  const TargetLibraryInfo *TLI;
+  bool RoundToAlign;
+  unsigned IntTyBits;
+  APInt Zero;
+  SmallPtrSet<Instruction *, 8> SeenInsts;
+
+  APInt align(APInt Size, uint64_t Align);
+
+  SizeOffsetType unknown() {
+    return std::make_pair(APInt(), APInt());
+  }
+
+public:
+  ObjectSizeOffsetVisitor(const DataLayout *DL, const TargetLibraryInfo *TLI,
+                          LLVMContext &Context, bool RoundToAlign = false);
+
+  SizeOffsetType compute(Value *V);
+
+  bool knownSize(SizeOffsetType &SizeOffset) {
+    return SizeOffset.first.getBitWidth() > 1;
+  }
+
+  bool knownOffset(SizeOffsetType &SizeOffset) {
+    return SizeOffset.second.getBitWidth() > 1;
+  }
+
+  bool bothKnown(SizeOffsetType &SizeOffset) {
+    return knownSize(SizeOffset) && knownOffset(SizeOffset);
+  }
+
+  // These are "private", except they can't actually be made private. Only
+  // compute() should be used by external users.
+  SizeOffsetType visitAllocaInst(AllocaInst &I);
+  SizeOffsetType visitArgument(Argument &A);
+  SizeOffsetType visitCallSite(CallSite CS);
+  SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
+  SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
+  SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
+  SizeOffsetType visitGEPOperator(GEPOperator &GEP);
+  SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
+  SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
+  SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
+  SizeOffsetType visitLoadInst(LoadInst &I);
+  SizeOffsetType visitPHINode(PHINode&);
+  SizeOffsetType visitSelectInst(SelectInst &I);
+  SizeOffsetType visitUndefValue(UndefValue&);
+  SizeOffsetType visitInstruction(Instruction &I);
+};
+
+typedef std::pair<Value*, Value*> SizeOffsetEvalType;
+
+
+/// \brief Evaluate the size and offset of an object pointed to by a Value*.
+/// May create code to compute the result at run-time.
+class ObjectSizeOffsetEvaluator
+  : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
+
+  typedef IRBuilder<true, TargetFolder> BuilderTy;
+  typedef std::pair<WeakVH, WeakVH> WeakEvalType;
+  typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
+  typedef SmallPtrSet<const Value*, 8> PtrSetTy;
+
+  const DataLayout *DL;
+  const TargetLibraryInfo *TLI;
+  LLVMContext &Context;
+  BuilderTy Builder;
+  IntegerType *IntTy;
+  Value *Zero;
+  CacheMapTy CacheMap;
+  PtrSetTy SeenVals;
+  bool RoundToAlign;
+
+  SizeOffsetEvalType unknown() {
+    return std::make_pair(nullptr, nullptr);
+  }
+  SizeOffsetEvalType compute_(Value *V);
+
+public:
+  ObjectSizeOffsetEvaluator(const DataLayout *DL, const TargetLibraryInfo *TLI,
+                            LLVMContext &Context, bool RoundToAlign = false);
+  SizeOffsetEvalType compute(Value *V);
+
+  bool knownSize(SizeOffsetEvalType SizeOffset) {
+    return SizeOffset.first;
+  }
+
+  bool knownOffset(SizeOffsetEvalType SizeOffset) {
+    return SizeOffset.second;
+  }
+
+  bool anyKnown(SizeOffsetEvalType SizeOffset) {
+    return knownSize(SizeOffset) || knownOffset(SizeOffset);
+  }
+
+  bool bothKnown(SizeOffsetEvalType SizeOffset) {
+    return knownSize(SizeOffset) && knownOffset(SizeOffset);
+  }
+
+  // The individual instruction visitors should be treated as private.
+  SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
+  SizeOffsetEvalType visitCallSite(CallSite CS);
+  SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
+  SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
+  SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
+  SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
+  SizeOffsetEvalType visitLoadInst(LoadInst &I);
+  SizeOffsetEvalType visitPHINode(PHINode &PHI);
+  SizeOffsetEvalType visitSelectInst(SelectInst &I);
+  SizeOffsetEvalType visitInstruction(Instruction &I);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
new file mode 100644
index 0000000..1c4441b
--- /dev/null
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -0,0 +1,446 @@
+//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps  --*- 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 MemoryDependenceAnalysis analysis pass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
+#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class Function;
+  class FunctionPass;
+  class Instruction;
+  class CallSite;
+  class AliasAnalysis;
+  class DataLayout;
+  class MemoryDependenceAnalysis;
+  class PredIteratorCache;
+  class DominatorTree;
+  class PHITransAddr;
+
+  /// MemDepResult - A memory dependence query can return one of three different
+  /// answers, described below.
+  class MemDepResult {
+    enum DepType {
+      /// Invalid - Clients of MemDep never see this.
+      Invalid = 0,
+
+      /// Clobber - This is a dependence on the specified instruction which
+      /// clobbers the desired value.  The pointer member of the MemDepResult
+      /// pair holds the instruction that clobbers the memory.  For example,
+      /// this occurs when we see a may-aliased store to the memory location we
+      /// care about.
+      ///
+      /// There are several cases that may be interesting here:
+      ///   1. Loads are clobbered by may-alias stores.
+      ///   2. Loads are considered clobbered by partially-aliased loads.  The
+      ///      client may choose to analyze deeper into these cases.
+      Clobber,
+
+      /// Def - This is a dependence on the specified instruction which
+      /// defines/produces the desired memory location.  The pointer member of
+      /// the MemDepResult pair holds the instruction that defines the memory.
+      /// Cases of interest:
+      ///   1. This could be a load or store for dependence queries on
+      ///      load/store.  The value loaded or stored is the produced value.
+      ///      Note that the pointer operand may be different than that of the
+      ///      queried pointer due to must aliases and phi translation.  Note
+      ///      that the def may not be the same type as the query, the pointers
+      ///      may just be must aliases.
+      ///   2. For loads and stores, this could be an allocation instruction. In
+      ///      this case, the load is loading an undef value or a store is the
+      ///      first store to (that part of) the allocation.
+      ///   3. Dependence queries on calls return Def only when they are
+      ///      readonly calls or memory use intrinsics with identical callees
+      ///      and no intervening clobbers.  No validation is done that the
+      ///      operands to the calls are the same.
+      Def,
+
+      /// Other - This marker indicates that the query has no known dependency
+      /// in the specified block.  More detailed state info is encoded in the
+      /// upper part of the pair (i.e. the Instruction*)
+      Other
+    };
+    /// If DepType is "Other", the upper part of the pair
+    /// (i.e. the Instruction* part) is instead used to encode more detailed
+    /// type information as follows
+    enum OtherType {
+      /// NonLocal - This marker indicates that the query has no dependency in
+      /// the specified block.  To find out more, the client should query other
+      /// predecessor blocks.
+      NonLocal = 0x4,
+      /// NonFuncLocal - This marker indicates that the query has no
+      /// dependency in the specified function.
+      NonFuncLocal = 0x8,
+      /// Unknown - This marker indicates that the query dependency
+      /// is unknown.
+      Unknown = 0xc
+    };
+
+    typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
+    PairTy Value;
+    explicit MemDepResult(PairTy V) : Value(V) {}
+  public:
+    MemDepResult() : Value(nullptr, Invalid) {}
+
+    /// get methods: These are static ctor methods for creating various
+    /// MemDepResult kinds.
+    static MemDepResult getDef(Instruction *Inst) {
+      assert(Inst && "Def requires inst");
+      return MemDepResult(PairTy(Inst, Def));
+    }
+    static MemDepResult getClobber(Instruction *Inst) {
+      assert(Inst && "Clobber requires inst");
+      return MemDepResult(PairTy(Inst, Clobber));
+    }
+    static MemDepResult getNonLocal() {
+      return MemDepResult(
+        PairTy(reinterpret_cast<Instruction*>(NonLocal), Other));
+    }
+    static MemDepResult getNonFuncLocal() {
+      return MemDepResult(
+        PairTy(reinterpret_cast<Instruction*>(NonFuncLocal), Other));
+    }
+    static MemDepResult getUnknown() {
+      return MemDepResult(
+        PairTy(reinterpret_cast<Instruction*>(Unknown), Other));
+    }
+
+    /// isClobber - Return true if this MemDepResult represents a query that is
+    /// an instruction clobber dependency.
+    bool isClobber() const { return Value.getInt() == Clobber; }
+
+    /// isDef - Return true if this MemDepResult represents a query that is
+    /// an instruction definition dependency.
+    bool isDef() const { return Value.getInt() == Def; }
+
+    /// isNonLocal - Return true if this MemDepResult represents a query that
+    /// is transparent to the start of the block, but where a non-local hasn't
+    /// been done.
+    bool isNonLocal() const {
+      return Value.getInt() == Other
+        && Value.getPointer() == reinterpret_cast<Instruction*>(NonLocal);
+    }
+
+    /// isNonFuncLocal - Return true if this MemDepResult represents a query
+    /// that is transparent to the start of the function.
+    bool isNonFuncLocal() const {
+      return Value.getInt() == Other
+        && Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
+    }
+
+    /// isUnknown - Return true if this MemDepResult represents a query which
+    /// cannot and/or will not be computed.
+    bool isUnknown() const {
+      return Value.getInt() == Other
+        && Value.getPointer() == reinterpret_cast<Instruction*>(Unknown);
+    }
+
+    /// getInst() - If this is a normal dependency, return the instruction that
+    /// is depended on.  Otherwise, return null.
+    Instruction *getInst() const {
+      if (Value.getInt() == Other) return nullptr;
+      return Value.getPointer();
+    }
+
+    bool operator==(const MemDepResult &M) const { return Value == M.Value; }
+    bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
+    bool operator<(const MemDepResult &M) const { return Value < M.Value; }
+    bool operator>(const MemDepResult &M) const { return Value > M.Value; }
+  private:
+    friend class MemoryDependenceAnalysis;
+    /// Dirty - Entries with this marker occur in a LocalDeps map or
+    /// NonLocalDeps map when the instruction they previously referenced was
+    /// removed from MemDep.  In either case, the entry may include an
+    /// instruction pointer.  If so, the pointer is an instruction in the
+    /// block where scanning can start from, saving some work.
+    ///
+    /// In a default-constructed MemDepResult object, the type will be Dirty
+    /// and the instruction pointer will be null.
+    ///
+
+    /// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
+    /// state.
+    bool isDirty() const { return Value.getInt() == Invalid; }
+
+    static MemDepResult getDirty(Instruction *Inst) {
+      return MemDepResult(PairTy(Inst, Invalid));
+    }
+  };
+
+  /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache.  For
+  /// each BasicBlock (the BB entry) it keeps a MemDepResult.
+  class NonLocalDepEntry {
+    BasicBlock *BB;
+    MemDepResult Result;
+  public:
+    NonLocalDepEntry(BasicBlock *bb, MemDepResult result)
+      : BB(bb), Result(result) {}
+
+    // This is used for searches.
+    NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}
+
+    // BB is the sort key, it can't be changed.
+    BasicBlock *getBB() const { return BB; }
+
+    void setResult(const MemDepResult &R) { Result = R; }
+
+    const MemDepResult &getResult() const { return Result; }
+
+    bool operator<(const NonLocalDepEntry &RHS) const {
+      return BB < RHS.BB;
+    }
+  };
+
+  /// NonLocalDepResult - This is a result from a NonLocal dependence query.
+  /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
+  /// (potentially phi translated) address that was live in the block.
+  class NonLocalDepResult {
+    NonLocalDepEntry Entry;
+    Value *Address;
+  public:
+    NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
+      : Entry(bb, result), Address(address) {}
+
+    // BB is the sort key, it can't be changed.
+    BasicBlock *getBB() const { return Entry.getBB(); }
+
+    void setResult(const MemDepResult &R, Value *Addr) {
+      Entry.setResult(R);
+      Address = Addr;
+    }
+
+    const MemDepResult &getResult() const { return Entry.getResult(); }
+
+    /// getAddress - Return the address of this pointer in this block.  This can
+    /// be different than the address queried for the non-local result because
+    /// of phi translation.  This returns null if the address was not available
+    /// in a block (i.e. because phi translation failed) or if this is a cached
+    /// result and that address was deleted.
+    ///
+    /// The address is always null for a non-local 'call' dependence.
+    Value *getAddress() const { return Address; }
+  };
+
+  /// MemoryDependenceAnalysis - This is an analysis that determines, for a
+  /// given memory operation, what preceding memory operations it depends on.
+  /// It builds on alias analysis information, and tries to provide a lazy,
+  /// caching interface to a common kind of alias information query.
+  ///
+  /// The dependency information returned is somewhat unusual, but is pragmatic.
+  /// If queried about a store or call that might modify memory, the analysis
+  /// will return the instruction[s] that may either load from that memory or
+  /// store to it.  If queried with a load or call that can never modify memory,
+  /// the analysis will return calls and stores that might modify the pointer,
+  /// but generally does not return loads unless a) they are volatile, or
+  /// b) they load from *must-aliased* pointers.  Returning a dependence on
+  /// must-alias'd pointers instead of all pointers interacts well with the
+  /// internal caching mechanism.
+  ///
+  class MemoryDependenceAnalysis : public FunctionPass {
+    // A map from instructions to their dependency.
+    typedef DenseMap<Instruction*, MemDepResult> LocalDepMapType;
+    LocalDepMapType LocalDeps;
+
+  public:
+    typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
+  private:
+    /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if
+    /// the dependence is a read only dependence, false if read/write.
+    typedef PointerIntPair<const Value*, 1, bool> ValueIsLoadPair;
+
+    /// BBSkipFirstBlockPair - This pair is used when caching information for a
+    /// block.  If the pointer is null, the cache value is not a full query that
+    /// starts at the specified block.  If non-null, the bool indicates whether
+    /// or not the contents of the block was skipped.
+    typedef PointerIntPair<BasicBlock*, 1, bool> BBSkipFirstBlockPair;
+
+    /// NonLocalPointerInfo - This record is the information kept for each
+    /// (value, is load) pair.
+    struct NonLocalPointerInfo {
+      /// Pair - The pair of the block and the skip-first-block flag.
+      BBSkipFirstBlockPair Pair;
+      /// NonLocalDeps - The results of the query for each relevant block.
+      NonLocalDepInfo NonLocalDeps;
+      /// Size - The maximum size of the dereferences of the
+      /// pointer. May be UnknownSize if the sizes are unknown.
+      uint64_t Size;
+      /// TBAATag - The TBAA tag associated with dereferences of the
+      /// pointer. May be null if there are no tags or conflicting tags.
+      const MDNode *TBAATag;
+
+      NonLocalPointerInfo()
+        : Size(AliasAnalysis::UnknownSize), TBAATag(nullptr) {}
+    };
+
+    /// CachedNonLocalPointerInfo - This map stores the cached results of doing
+    /// a pointer lookup at the bottom of a block.  The key of this map is the
+    /// pointer+isload bit, the value is a list of <bb->result> mappings.
+    typedef DenseMap<ValueIsLoadPair,
+                     NonLocalPointerInfo> CachedNonLocalPointerInfo;
+    CachedNonLocalPointerInfo NonLocalPointerDeps;
+
+    // A map from instructions to their non-local pointer dependencies.
+    typedef DenseMap<Instruction*,
+                     SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
+    ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
+
+
+    /// PerInstNLInfo - This is the instruction we keep for each cached access
+    /// that we have for an instruction.  The pointer is an owning pointer and
+    /// the bool indicates whether we have any dirty bits in the set.
+    typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
+
+    // A map from instructions to their non-local dependencies.
+    typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
+
+    NonLocalDepMapType NonLocalDeps;
+
+    // A reverse mapping from dependencies to the dependees.  This is
+    // used when removing instructions to keep the cache coherent.
+    typedef DenseMap<Instruction*,
+                     SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
+    ReverseDepMapType ReverseLocalDeps;
+
+    // A reverse mapping from dependencies to the non-local dependees.
+    ReverseDepMapType ReverseNonLocalDeps;
+
+    /// Current AA implementation, just a cache.
+    AliasAnalysis *AA;
+    const DataLayout *DL;
+    DominatorTree *DT;
+    std::unique_ptr<PredIteratorCache> PredCache;
+
+  public:
+    MemoryDependenceAnalysis();
+    ~MemoryDependenceAnalysis();
+    static char ID;
+
+    /// Pass Implementation stuff.  This doesn't do any analysis eagerly.
+    bool runOnFunction(Function &) override;
+
+    /// Clean up memory in between runs
+    void releaseMemory() override;
+
+    /// getAnalysisUsage - Does not modify anything.  It uses Value Numbering
+    /// and Alias Analysis.
+    ///
+    void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+    /// getDependency - Return the instruction on which a memory operation
+    /// depends.  See the class comment for more details.  It is illegal to call
+    /// this on non-memory instructions.
+    MemDepResult getDependency(Instruction *QueryInst);
+
+    /// getNonLocalCallDependency - Perform a full dependency query for the
+    /// specified call, returning the set of blocks that the value is
+    /// potentially live across.  The returned set of results will include a
+    /// "NonLocal" result for all blocks where the value is live across.
+    ///
+    /// This method assumes the instruction returns a "NonLocal" dependency
+    /// within its own block.
+    ///
+    /// This returns a reference to an internal data structure that may be
+    /// invalidated on the next non-local query or when an instruction is
+    /// removed.  Clients must copy this data if they want it around longer than
+    /// that.
+    const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
+
+
+    /// getNonLocalPointerDependency - Perform a full dependency query for an
+    /// access to the specified (non-volatile) memory location, returning the
+    /// set of instructions that either define or clobber the value.
+    ///
+    /// This method assumes the pointer has a "NonLocal" dependency within BB.
+    void getNonLocalPointerDependency(const AliasAnalysis::Location &Loc,
+                                      bool isLoad, BasicBlock *BB,
+                                    SmallVectorImpl<NonLocalDepResult> &Result);
+
+    /// removeInstruction - Remove an instruction from the dependence analysis,
+    /// updating the dependence of instructions that previously depended on it.
+    void removeInstruction(Instruction *InstToRemove);
+
+    /// invalidateCachedPointerInfo - This method is used to invalidate cached
+    /// information about the specified pointer, because it may be too
+    /// conservative in memdep.  This is an optional call that can be used when
+    /// the client detects an equivalence between the pointer and some other
+    /// value and replaces the other value with ptr. This can make Ptr available
+    /// in more places that cached info does not necessarily keep.
+    void invalidateCachedPointerInfo(Value *Ptr);
+
+    /// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+    /// This needs to be done when the CFG changes, e.g., due to splitting
+    /// critical edges.
+    void invalidateCachedPredecessors();
+
+    /// getPointerDependencyFrom - Return the instruction on which a memory
+    /// location depends.  If isLoad is true, this routine ignores may-aliases
+    /// with read-only operations.  If isLoad is false, this routine ignores
+    /// may-aliases with reads from read-only locations. If possible, pass
+    /// the query instruction as well; this function may take advantage of 
+    /// the metadata annotated to the query instruction to refine the result.
+    ///
+    /// Note that this is an uncached query, and thus may be inefficient.
+    ///
+    MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
+                                          bool isLoad,
+                                          BasicBlock::iterator ScanIt,
+                                          BasicBlock *BB,
+                                          Instruction *QueryInst = nullptr);
+
+
+    /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
+    /// looks at a memory location for a load (specified by MemLocBase, Offs,
+    /// and Size) and compares it against a load.  If the specified load could
+    /// be safely widened to a larger integer load that is 1) still efficient,
+    /// 2) safe for the target, and 3) would provide the specified memory
+    /// location value, then this function returns the size in bytes of the
+    /// load width to use.  If not, this returns zero.
+    static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
+                                                    int64_t MemLocOffs,
+                                                    unsigned MemLocSize,
+                                                    const LoadInst *LI,
+                                                    const DataLayout &DL);
+
+  private:
+    MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
+                                           BasicBlock::iterator ScanIt,
+                                           BasicBlock *BB);
+    bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer,
+                                     const AliasAnalysis::Location &Loc,
+                                     bool isLoad, BasicBlock *BB,
+                                     SmallVectorImpl<NonLocalDepResult> &Result,
+                                     DenseMap<BasicBlock*, Value*> &Visited,
+                                     bool SkipFirstBlock = false);
+    MemDepResult GetNonLocalInfoForBlock(const AliasAnalysis::Location &Loc,
+                                         bool isLoad, BasicBlock *BB,
+                                         NonLocalDepInfo *Cache,
+                                         unsigned NumSortedEntries);
+
+    void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
+
+    /// verifyRemoved - Verify that the specified instruction does not occur
+    /// in our internal data structures.
+    void verifyRemoved(Instruction *Inst) const;
+
+  };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
new file mode 100644
index 0000000..69f5907
--- /dev/null
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -0,0 +1,122 @@
+//===- PHITransAddr.h - PHI Translation for Addresses -----------*- 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 PHITransAddr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
+#define LLVM_ANALYSIS_PHITRANSADDR_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Instruction.h"
+
+namespace llvm {
+  class DominatorTree;
+  class DataLayout;
+  class TargetLibraryInfo;
+
+/// PHITransAddr - An address value which tracks and handles phi translation.
+/// As we walk "up" the CFG through predecessors, we need to ensure that the
+/// address we're tracking is kept up to date.  For example, if we're analyzing
+/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI
+/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an
+/// incorrect pointer in the predecessor block.
+///
+/// This is designed to be a relatively small object that lives on the stack and
+/// is copyable.
+///
+class PHITransAddr {
+  /// Addr - The actual address we're analyzing.
+  Value *Addr;
+  
+  /// The DataLayout we are playing with if known, otherwise null.
+  const DataLayout *DL;
+
+  /// TLI - The target library info if known, otherwise null.
+  const TargetLibraryInfo *TLI;
+  
+  /// InstInputs - The inputs for our symbolic address.
+  SmallVector<Instruction*, 4> InstInputs;
+public:
+  PHITransAddr(Value *addr, const DataLayout *DL)
+      : Addr(addr), DL(DL), TLI(nullptr) {
+    // If the address is an instruction, the whole thing is considered an input.
+    if (Instruction *I = dyn_cast<Instruction>(Addr))
+      InstInputs.push_back(I);
+  }
+  
+  Value *getAddr() const { return Addr; }
+  
+  /// NeedsPHITranslationFromBlock - Return true if moving from the specified
+  /// BasicBlock to its predecessors requires PHI translation.
+  bool NeedsPHITranslationFromBlock(BasicBlock *BB) const {
+    // We do need translation if one of our input instructions is defined in
+    // this block.
+    for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
+      if (InstInputs[i]->getParent() == BB)
+        return true;
+    return false;
+  }
+  
+  /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
+  /// if we have some hope of doing it.  This should be used as a filter to
+  /// avoid calling PHITranslateValue in hopeless situations.
+  bool IsPotentiallyPHITranslatable() const;
+  
+  /// PHITranslateValue - PHI translate the current address up the CFG from
+  /// CurBB to Pred, updating our state to reflect any needed changes.  If the
+  /// dominator tree DT is non-null, the translated value must dominate
+  /// PredBB.  This returns true on failure and sets Addr to null.
+  bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
+                         const DominatorTree *DT);
+  
+  /// PHITranslateWithInsertion - PHI translate this value into the specified
+  /// predecessor block, inserting a computation of the value if it is
+  /// unavailable.
+  ///
+  /// All newly created instructions are added to the NewInsts list.  This
+  /// returns null on failure.
+  ///
+  Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
+                                   const DominatorTree &DT,
+                                   SmallVectorImpl<Instruction*> &NewInsts);
+  
+  void dump() const;
+  
+  /// Verify - Check internal consistency of this data structure.  If the
+  /// structure is valid, it returns true.  If invalid, it prints errors and
+  /// returns false.
+  bool Verify() const;
+private:
+  Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB,
+                             const DominatorTree *DT);
+  
+  /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
+  /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
+  /// block.  All newly created instructions are added to the NewInsts list.
+  /// This returns null on failure.
+  ///
+  Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
+                                    BasicBlock *PredBB, const DominatorTree &DT,
+                                    SmallVectorImpl<Instruction*> &NewInsts);
+  
+  /// AddAsInput - If the specified value is an instruction, add it as an input.
+  Value *AddAsInput(Value *V) {
+    // If V is an instruction, it is now an input.
+    if (Instruction *VI = dyn_cast<Instruction>(V))
+      InstInputs.push_back(VI);
+    return V;
+  }
+  
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
new file mode 100644
index 0000000..fd65ae5
--- /dev/null
+++ b/include/llvm/Analysis/Passes.h
@@ -0,0 +1,151 @@
+//===-- llvm/Analysis/Passes.h - Constructors for analyses ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the analysis libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PASSES_H
+#define LLVM_ANALYSIS_PASSES_H
+
+namespace llvm {
+  class FunctionPass;
+  class ImmutablePass;
+  class LoopPass;
+  class ModulePass;
+  class Pass;
+  class PassInfo;
+  class LibCallInfo;
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createGlobalsModRefPass - This pass provides alias and mod/ref info for
+  // global values that do not have their addresses taken.
+  //
+  Pass *createGlobalsModRefPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createAliasDebugger - This pass helps debug clients of AA
+  //
+  Pass *createAliasDebugger();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createAliasAnalysisCounterPass - This pass counts alias queries and how the
+  // alias analysis implementation responds.
+  //
+  ModulePass *createAliasAnalysisCounterPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createAAEvalPass - This pass implements a simple N^2 alias analysis
+  // accuracy evaluator.
+  //
+  FunctionPass *createAAEvalPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createNoAAPass - This pass implements a "I don't know" alias analysis.
+  //
+  ImmutablePass *createNoAAPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createBasicAliasAnalysisPass - This pass implements the stateless alias
+  // analysis.
+  //
+  ImmutablePass *createBasicAliasAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  /// createLibCallAliasAnalysisPass - Create an alias analysis pass that knows
+  /// about the semantics of a set of libcalls specified by LCI.  The newly
+  /// constructed pass takes ownership of the pointer that is provided.
+  ///
+  FunctionPass *createLibCallAliasAnalysisPass(LibCallInfo *LCI);
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createScalarEvolutionAliasAnalysisPass - This pass implements a simple
+  // alias analysis using ScalarEvolution queries.
+  //
+  FunctionPass *createScalarEvolutionAliasAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createTypeBasedAliasAnalysisPass - This pass implements metadata-based
+  // type-based alias analysis.
+  //
+  ImmutablePass *createTypeBasedAliasAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
+  // alias analysis.
+  //
+  ImmutablePass *createObjCARCAliasAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  /// createLazyValueInfoPass - This creates an instance of the LazyValueInfo
+  /// pass.
+  FunctionPass *createLazyValueInfoPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createDependenceAnalysisPass - This creates an instance of the
+  // DependenceAnalysis pass.
+  //
+  FunctionPass *createDependenceAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createCostModelAnalysisPass - This creates an instance of the
+  // CostModelAnalysis pass.
+  //
+  FunctionPass *createCostModelAnalysisPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createDelinearizationPass - This pass implements attempts to restore
+  // multidimensional array indices from linearized expressions.
+  //
+  FunctionPass *createDelinearizationPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // Minor pass prototypes, allowing us to expose them through bugpoint and
+  // analyze.
+  FunctionPass *createInstCountPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createRegionInfoPass - This pass finds all single entry single exit regions
+  // in a function and builds the region hierarchy.
+  //
+  FunctionPass *createRegionInfoPass();
+
+  // Print module-level debug info metadata in human-readable form.
+  ModulePass *createModuleDebugInfoPrinterPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createMemDepPrinter - This pass exhaustively collects all memdep
+  // information and prints it with -analyze.
+  //
+  FunctionPass *createMemDepPrinter();
+
+  // createJumpInstrTableInfoPass - This creates a pass that stores information
+  // about the jump tables created by JumpInstrTables
+  ImmutablePass *createJumpInstrTableInfoPass();
+}
+
+#endif
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
new file mode 100644
index 0000000..d330755
--- /dev/null
+++ b/include/llvm/Analysis/PostDominators.h
@@ -0,0 +1,117 @@
+//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation-*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes interfaces to post dominance information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
+#define LLVM_ANALYSIS_POSTDOMINATORS_H
+
+#include "llvm/IR/Dominators.h"
+
+namespace llvm {
+
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
+/// compute the a post-dominator tree.
+///
+struct PostDominatorTree : public FunctionPass {
+  static char ID; // Pass identification, replacement for typeid
+  DominatorTreeBase<BasicBlock>* DT;
+
+  PostDominatorTree() : FunctionPass(ID) {
+    initializePostDominatorTreePass(*PassRegistry::getPassRegistry());
+    DT = new DominatorTreeBase<BasicBlock>(true);
+  }
+
+  ~PostDominatorTree();
+
+  bool runOnFunction(Function &F) override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  inline const std::vector<BasicBlock*> &getRoots() const {
+    return DT->getRoots();
+  }
+
+  inline DomTreeNode *getRootNode() const {
+    return DT->getRootNode();
+  }
+
+  inline DomTreeNode *operator[](BasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  inline DomTreeNode *getNode(BasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  inline bool dominates(DomTreeNode* A, DomTreeNode* B) const {
+    return DT->dominates(A, B);
+  }
+
+  inline bool dominates(const BasicBlock* A, const BasicBlock* B) const {
+    return DT->dominates(A, B);
+  }
+
+  inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  inline const BasicBlock *findNearestCommonDominator(const BasicBlock *A,
+                                                      const BasicBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  /// Get all nodes post-dominated by R, including R itself.
+  void getDescendants(BasicBlock *R,
+                      SmallVectorImpl<BasicBlock *> &Result) const {
+    DT->getDescendants(R, Result);
+  }
+
+  void releaseMemory() override {
+    DT->releaseMemory();
+  }
+
+  void print(raw_ostream &OS, const Module*) const override;
+};
+
+FunctionPass* createPostDomTree();
+
+template <> struct GraphTraits<PostDominatorTree*>
+  : public GraphTraits<DomTreeNode*> {
+  static NodeType *getEntryNode(PostDominatorTree *DT) {
+    return DT->getRootNode();
+  }
+
+  static nodes_iterator nodes_begin(PostDominatorTree *N) {
+    if (getEntryNode(N))
+      return df_begin(getEntryNode(N));
+    else
+      return df_end(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(PostDominatorTree *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h
new file mode 100644
index 0000000..6e61fc3
--- /dev/null
+++ b/include/llvm/Analysis/PtrUseVisitor.h
@@ -0,0 +1,285 @@
+//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file provides a collection of visitors which walk the (instruction)
+/// uses of a pointer. These visitors all provide the same essential behavior
+/// as an InstVisitor with similar template-based flexibility and
+/// implementation strategies.
+///
+/// These can be used, for example, to quickly analyze the uses of an alloca,
+/// global variable, or function argument.
+///
+/// FIXME: Provide a variant which doesn't track offsets and is cheaper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
+#define LLVM_ANALYSIS_PTRUSEVISITOR_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstVisitor.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+namespace detail {
+/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
+///
+/// See \c PtrUseVisitor for the public interface and detailed comments about
+/// usage. This class is just a helper base class which is not templated and
+/// contains all common code to be shared between different instantiations of
+/// PtrUseVisitor.
+class PtrUseVisitorBase {
+public:
+  /// \brief This class provides information about the result of a visit.
+  ///
+  /// After walking all the users (recursively) of a pointer, the basic
+  /// infrastructure records some commonly useful information such as escape
+  /// analysis and whether the visit completed or aborted early.
+  class PtrInfo {
+  public:
+    PtrInfo() : AbortedInfo(nullptr, false), EscapedInfo(nullptr, false) {}
+
+    /// \brief Reset the pointer info, clearing all state.
+    void reset() {
+      AbortedInfo.setPointer(nullptr);
+      AbortedInfo.setInt(false);
+      EscapedInfo.setPointer(nullptr);
+      EscapedInfo.setInt(false);
+    }
+
+    /// \brief Did we abort the visit early?
+    bool isAborted() const { return AbortedInfo.getInt(); }
+
+    /// \brief Is the pointer escaped at some point?
+    bool isEscaped() const { return EscapedInfo.getInt(); }
+
+    /// \brief Get the instruction causing the visit to abort.
+    /// \returns a pointer to the instruction causing the abort if one is
+    /// available; otherwise returns null.
+    Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); }
+
+    /// \brief Get the instruction causing the pointer to escape.
+    /// \returns a pointer to the instruction which escapes the pointer if one
+    /// is available; otherwise returns null.
+    Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); }
+
+    /// \brief Mark the visit as aborted. Intended for use in a void return.
+    /// \param I The instruction which caused the visit to abort, if available.
+    void setAborted(Instruction *I = nullptr) {
+      AbortedInfo.setInt(true);
+      AbortedInfo.setPointer(I);
+    }
+
+    /// \brief Mark the pointer as escaped. Intended for use in a void return.
+    /// \param I The instruction which escapes the pointer, if available.
+    void setEscaped(Instruction *I = nullptr) {
+      EscapedInfo.setInt(true);
+      EscapedInfo.setPointer(I);
+    }
+
+    /// \brief Mark the pointer as escaped, and the visit as aborted. Intended
+    /// for use in a void return.
+    /// \param I The instruction which both escapes the pointer and aborts the
+    /// visit, if available.
+    void setEscapedAndAborted(Instruction *I = nullptr) {
+      setEscaped(I);
+      setAborted(I);
+    }
+
+  private:
+    PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo;
+  };
+
+protected:
+  const DataLayout &DL;
+
+  /// \name Visitation infrastructure
+  /// @{
+
+  /// \brief The info collected about the pointer being visited thus far.
+  PtrInfo PI;
+
+  /// \brief A struct of the data needed to visit a particular use.
+  ///
+  /// This is used to maintain a worklist fo to-visit uses. This is used to
+  /// make the visit be iterative rather than recursive.
+  struct UseToVisit {
+    typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair;
+    UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
+    APInt Offset;
+  };
+
+  /// \brief The worklist of to-visit uses.
+  SmallVector<UseToVisit, 8> Worklist;
+
+  /// \brief A set of visited uses to break cycles in unreachable code.
+  SmallPtrSet<Use *, 8> VisitedUses;
+
+  /// @}
+
+
+  /// \name Per-visit state
+  /// This state is reset for each instruction visited.
+  /// @{
+
+  /// \brief The use currently being visited.
+  Use *U;
+
+  /// \brief True if we have a known constant offset for the use currently
+  /// being visited.
+  bool IsOffsetKnown;
+
+  /// \brief The constant offset of the use if that is known.
+  APInt Offset;
+
+  /// @}
+
+
+  /// Note that the constructor is protected because this class must be a base
+  /// class, we can't create instances directly of this class.
+  PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
+
+  /// \brief Enqueue the users of this instruction in the visit worklist.
+  ///
+  /// This will visit the users with the same offset of the current visit
+  /// (including an unknown offset if that is the current state).
+  void enqueueUsers(Instruction &I);
+
+  /// \brief Walk the operands of a GEP and adjust the offset as appropriate.
+  ///
+  /// This routine does the heavy lifting of the pointer walk by computing
+  /// offsets and looking through GEPs.
+  bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
+};
+} // end namespace detail
+
+/// \brief A base class for visitors over the uses of a pointer value.
+///
+/// Once constructed, a user can call \c visit on a pointer value, and this
+/// will walk its uses and visit each instruction using an InstVisitor. It also
+/// provides visit methods which will recurse through any pointer-to-pointer
+/// transformations such as GEPs and bitcasts.
+///
+/// During the visit, the current Use* being visited is available to the
+/// subclass, as well as the current offset from the original base pointer if
+/// known.
+///
+/// The recursive visit of uses is accomplished with a worklist, so the only
+/// ordering guarantee is that an instruction is visited before any uses of it
+/// are visited. Note that this does *not* mean before any of its users are
+/// visited! This is because users can be visited multiple times due to
+/// multiple, different uses of pointers derived from the same base.
+///
+/// A particular Use will only be visited once, but a User may be visited
+/// multiple times, once per Use. This visits may notably have different
+/// offsets.
+///
+/// All visit methods on the underlying InstVisitor return a boolean. This
+/// return short-circuits the visit, stopping it immediately.
+///
+/// FIXME: Generalize this for all values rather than just instructions.
+template <typename DerivedT>
+class PtrUseVisitor : protected InstVisitor<DerivedT>,
+                      public detail::PtrUseVisitorBase {
+  friend class InstVisitor<DerivedT>;
+  typedef InstVisitor<DerivedT> Base;
+
+public:
+  PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
+
+  /// \brief Recursively visit the uses of the given pointer.
+  /// \returns An info struct about the pointer. See \c PtrInfo for details.
+  PtrInfo visitPtr(Instruction &I) {
+    // This must be a pointer type. Get an integer type suitable to hold
+    // offsets on this pointer.
+    // FIXME: Support a vector of pointers.
+    assert(I.getType()->isPointerTy());
+    IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType()));
+    IsOffsetKnown = true;
+    Offset = APInt(IntPtrTy->getBitWidth(), 0);
+    PI.reset();
+
+    // Enqueue the uses of this pointer.
+    enqueueUsers(I);
+
+    // Visit all the uses off the worklist until it is empty.
+    while (!Worklist.empty()) {
+      UseToVisit ToVisit = Worklist.pop_back_val();
+      U = ToVisit.UseAndIsOffsetKnown.getPointer();
+      IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
+      if (IsOffsetKnown)
+        Offset = std::move(ToVisit.Offset);
+
+      Instruction *I = cast<Instruction>(U->getUser());
+      static_cast<DerivedT*>(this)->visit(I);
+      if (PI.isAborted())
+        break;
+    }
+    return PI;
+  }
+
+protected:
+  void visitStoreInst(StoreInst &SI) {
+    if (SI.getValueOperand() == U->get())
+      PI.setEscaped(&SI);
+  }
+
+  void visitBitCastInst(BitCastInst &BC) {
+    enqueueUsers(BC);
+  }
+
+  void visitPtrToIntInst(PtrToIntInst &I) {
+    PI.setEscaped(&I);
+  }
+
+  void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
+    if (GEPI.use_empty())
+      return;
+
+    // If we can't walk the GEP, clear the offset.
+    if (!adjustOffsetForGEP(GEPI)) {
+      IsOffsetKnown = false;
+      Offset = APInt();
+    }
+
+    // Enqueue the users now that the offset has been adjusted.
+    enqueueUsers(GEPI);
+  }
+
+  // No-op intrinsics which we know don't escape the pointer to to logic in
+  // some other function.
+  void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {}
+  void visitMemIntrinsic(MemIntrinsic &I) {}
+  void visitIntrinsicInst(IntrinsicInst &II) {
+    switch (II.getIntrinsicID()) {
+    default:
+      return Base::visitIntrinsicInst(II);
+
+    case Intrinsic::lifetime_start:
+    case Intrinsic::lifetime_end:
+      return; // No-op intrinsics.
+    }
+  }
+
+  // Generically, arguments to calls and invokes escape the pointer to some
+  // other function. Mark that.
+  void visitCallSite(CallSite CS) {
+    PI.setEscaped(CS.getInstruction());
+    Base::visitCallSite(CS);
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
new file mode 100644
index 0000000..49c88fd
--- /dev/null
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -0,0 +1,908 @@
+//===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate a program structure tree built out of single entry single exit
+// regions.
+// The basic ideas are taken from "The Program Structure Tree - Richard Johnson,
+// David Pearson, Keshav Pingali - 1994", however enriched with ideas from "The
+// Refined Process Structure Tree - Jussi Vanhatalo, Hagen Voelyer, Jana
+// Koehler - 2009".
+// The algorithm to calculate these data structures however is completely
+// different, as it takes advantage of existing information already available
+// in (Post)dominace tree and dominance frontier passes. This leads to a simpler
+// and in practice hopefully better performing algorithm. The runtime of the
+// algorithms described in the papers above are both linear in graph size,
+// O(V+E), whereas this algorithm is not, as the dominance frontier information
+// itself is not, but in practice runtime seems to be in the order of magnitude
+// of dominance tree calculation.
+//
+// WARNING: LLVM is generally very concerned about compile time such that
+//          the use of additional analysis passes in the default
+//          optimization sequence is avoided as much as possible.
+//          Specifically, if you do not need the RegionInfo, but dominance
+//          information could be sufficient please base your work only on
+//          the dominator tree. Most passes maintain it, such that using
+//          it has often near zero cost. In contrast RegionInfo is by
+//          default not available, is not maintained by existing
+//          transformations and there is no intention to do so.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONINFO_H
+#define LLVM_ANALYSIS_REGIONINFO_H
+
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Dominators.h"
+#include <map>
+#include <memory>
+#include <set>
+
+namespace llvm {
+
+// RegionTraits - Class to be specialized for different users of RegionInfo
+// (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to
+// pass around an unreasonable number of template parameters.
+template <class FuncT_>
+struct RegionTraits {
+  // FuncT
+  // BlockT
+  // RegionT
+  // RegionNodeT
+  // RegionInfoT
+  typedef typename FuncT_::UnknownRegionTypeError BrokenT;
+};
+
+class DominatorTree;
+class DominanceFrontier;
+class Loop;
+class LoopInfo;
+struct PostDominatorTree;
+class raw_ostream;
+class Region;
+template <class RegionTr>
+class RegionBase;
+class RegionNode;
+class RegionInfo;
+template <class RegionTr>
+class RegionInfoBase;
+
+template <>
+struct RegionTraits<Function> {
+  typedef Function FuncT;
+  typedef BasicBlock BlockT;
+  typedef Region RegionT;
+  typedef RegionNode RegionNodeT;
+  typedef RegionInfo RegionInfoT;
+  typedef DominatorTree DomTreeT;
+  typedef DomTreeNode DomTreeNodeT;
+  typedef DominanceFrontier DomFrontierT;
+  typedef PostDominatorTree PostDomTreeT;
+  typedef Instruction InstT;
+  typedef Loop LoopT;
+  typedef LoopInfo LoopInfoT;
+
+  static unsigned getNumSuccessors(BasicBlock *BB) {
+    return BB->getTerminator()->getNumSuccessors();
+  }
+};
+
+/// @brief Marker class to iterate over the elements of a Region in flat mode.
+///
+/// The class is used to either iterate in Flat mode or by not using it to not
+/// iterate in Flat mode.  During a Flat mode iteration all Regions are entered
+/// and the iteration returns every BasicBlock.  If the Flat mode is not
+/// selected for SubRegions just one RegionNode containing the subregion is
+/// returned.
+template <class GraphType>
+class FlatIt {};
+
+/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
+/// Region.
+template <class Tr>
+class RegionNodeBase {
+  friend class RegionBase<Tr>;
+
+public:
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionT RegionT;
+
+private:
+  RegionNodeBase(const RegionNodeBase &) LLVM_DELETED_FUNCTION;
+  const RegionNodeBase &operator=(const RegionNodeBase &) LLVM_DELETED_FUNCTION;
+
+  /// This is the entry basic block that starts this region node.  If this is a
+  /// BasicBlock RegionNode, then entry is just the basic block, that this
+  /// RegionNode represents.  Otherwise it is the entry of this (Sub)RegionNode.
+  ///
+  /// In the BBtoRegionNode map of the parent of this node, BB will always map
+  /// to this node no matter which kind of node this one is.
+  ///
+  /// The node can hold either a Region or a BasicBlock.
+  /// Use one bit to save, if this RegionNode is a subregion or BasicBlock
+  /// RegionNode.
+  PointerIntPair<BlockT *, 1, bool> entry;
+
+  /// @brief The parent Region of this RegionNode.
+  /// @see getParent()
+  RegionT *parent;
+
+protected:
+  /// @brief Create a RegionNode.
+  ///
+  /// @param Parent      The parent of this RegionNode.
+  /// @param Entry       The entry BasicBlock of the RegionNode.  If this
+  ///                    RegionNode represents a BasicBlock, this is the
+  ///                    BasicBlock itself.  If it represents a subregion, this
+  ///                    is the entry BasicBlock of the subregion.
+  /// @param isSubRegion If this RegionNode represents a SubRegion.
+  inline RegionNodeBase(RegionT *Parent, BlockT *Entry,
+                        bool isSubRegion = false)
+      : entry(Entry, isSubRegion), parent(Parent) {}
+
+public:
+  /// @brief Get the parent Region of this RegionNode.
+  ///
+  /// The parent Region is the Region this RegionNode belongs to. If for
+  /// example a BasicBlock is element of two Regions, there exist two
+  /// RegionNodes for this BasicBlock. Each with the getParent() function
+  /// pointing to the Region this RegionNode belongs to.
+  ///
+  /// @return Get the parent Region of this RegionNode.
+  inline RegionT *getParent() const { return parent; }
+
+  /// @brief Get the entry BasicBlock of this RegionNode.
+  ///
+  /// If this RegionNode represents a BasicBlock this is just the BasicBlock
+  /// itself, otherwise we return the entry BasicBlock of the Subregion
+  ///
+  /// @return The entry BasicBlock of this RegionNode.
+  inline BlockT *getEntry() const { return entry.getPointer(); }
+
+  /// @brief Get the content of this RegionNode.
+  ///
+  /// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
+  /// check the type of the content with the isSubRegion() function call.
+  ///
+  /// @return The content of this RegionNode.
+  template <class T> inline T *getNodeAs() const;
+
+  /// @brief Is this RegionNode a subregion?
+  ///
+  /// @return True if it contains a subregion. False if it contains a
+  ///         BasicBlock.
+  inline bool isSubRegion() const { return entry.getInt(); }
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief A single entry single exit Region.
+///
+/// A Region is a connected subgraph of a control flow graph that has exactly
+/// two connections to the remaining graph. It can be used to analyze or
+/// optimize parts of the control flow graph.
+///
+/// A <em> simple Region </em> is connected to the remaining graph by just two
+/// edges. One edge entering the Region and another one leaving the Region.
+///
+/// An <em> extended Region </em> (or just Region) is a subgraph that can be
+/// transform into a simple Region. The transformation is done by adding
+/// BasicBlocks that merge several entry or exit edges so that after the merge
+/// just one entry and one exit edge exists.
+///
+/// The \e Entry of a Region is the first BasicBlock that is passed after
+/// entering the Region. It is an element of the Region. The entry BasicBlock
+/// dominates all BasicBlocks in the Region.
+///
+/// The \e Exit of a Region is the first BasicBlock that is passed after
+/// leaving the Region. It is not an element of the Region. The exit BasicBlock,
+/// postdominates all BasicBlocks in the Region.
+///
+/// A <em> canonical Region </em> cannot be constructed by combining smaller
+/// Regions.
+///
+/// Region A is the \e parent of Region B, if B is completely contained in A.
+///
+/// Two canonical Regions either do not intersect at all or one is
+/// the parent of the other.
+///
+/// The <em> Program Structure Tree</em> is a graph (V, E) where V is the set of
+/// Regions in the control flow graph and E is the \e parent relation of these
+/// Regions.
+///
+/// Example:
+///
+/// \verbatim
+/// A simple control flow graph, that contains two regions.
+///
+///        1
+///       / |
+///      2   |
+///     / \   3
+///    4   5  |
+///    |   |  |
+///    6   7  8
+///     \  | /
+///      \ |/       Region A: 1 -> 9 {1,2,3,4,5,6,7,8}
+///        9        Region B: 2 -> 9 {2,4,5,6,7}
+/// \endverbatim
+///
+/// You can obtain more examples by either calling
+///
+/// <tt> "opt -regions -analyze anyprogram.ll" </tt>
+/// or
+/// <tt> "opt -view-regions-only anyprogram.ll" </tt>
+///
+/// on any LLVM file you are interested in.
+///
+/// The first call returns a textual representation of the program structure
+/// tree, the second one creates a graphical representation using graphviz.
+template <class Tr>
+class RegionBase : public RegionNodeBase<Tr> {
+  typedef typename Tr::FuncT FuncT;
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionInfoT RegionInfoT;
+  typedef typename Tr::RegionT RegionT;
+  typedef typename Tr::RegionNodeT RegionNodeT;
+  typedef typename Tr::DomTreeT DomTreeT;
+  typedef typename Tr::LoopT LoopT;
+  typedef typename Tr::LoopInfoT LoopInfoT;
+  typedef typename Tr::InstT InstT;
+
+  typedef GraphTraits<BlockT *> BlockTraits;
+  typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+  typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
+
+  friend class RegionInfoBase<Tr>;
+  RegionBase(const RegionBase &) LLVM_DELETED_FUNCTION;
+  const RegionBase &operator=(const RegionBase &) LLVM_DELETED_FUNCTION;
+
+  // Information necessary to manage this Region.
+  RegionInfoT *RI;
+  DomTreeT *DT;
+
+  // The exit BasicBlock of this region.
+  // (The entry BasicBlock is part of RegionNode)
+  BlockT *exit;
+
+  typedef std::vector<std::unique_ptr<RegionT>> RegionSet;
+
+  // The subregions of this region.
+  RegionSet children;
+
+  typedef std::map<BlockT *, RegionNodeT *> BBNodeMapT;
+
+  // Save the BasicBlock RegionNodes that are element of this Region.
+  mutable BBNodeMapT BBNodeMap;
+
+  /// verifyBBInRegion - Check if a BB is in this Region. This check also works
+  /// if the region is incorrectly built. (EXPENSIVE!)
+  void verifyBBInRegion(BlockT *BB) const;
+
+  /// verifyWalk - Walk over all the BBs of the region starting from BB and
+  /// verify that all reachable basic blocks are elements of the region.
+  /// (EXPENSIVE!)
+  void verifyWalk(BlockT *BB, std::set<BlockT *> *visitedBB) const;
+
+  /// verifyRegionNest - Verify if the region and its children are valid
+  /// regions (EXPENSIVE!)
+  void verifyRegionNest() const;
+
+public:
+  /// @brief Create a new region.
+  ///
+  /// @param Entry  The entry basic block of the region.
+  /// @param Exit   The exit basic block of the region.
+  /// @param RI     The region info object that is managing this region.
+  /// @param DT     The dominator tree of the current function.
+  /// @param Parent The surrounding region or NULL if this is a top level
+  ///               region.
+  RegionBase(BlockT *Entry, BlockT *Exit, RegionInfoT *RI, DomTreeT *DT,
+             RegionT *Parent = nullptr);
+
+  /// Delete the Region and all its subregions.
+  ~RegionBase();
+
+  /// @brief Get the entry BasicBlock of the Region.
+  /// @return The entry BasicBlock of the region.
+  BlockT *getEntry() const {
+    return RegionNodeBase<Tr>::getEntry();
+  }
+
+  /// @brief Replace the entry basic block of the region with the new basic
+  ///        block.
+  ///
+  /// @param BB  The new entry basic block of the region.
+  void replaceEntry(BlockT *BB);
+
+  /// @brief Replace the exit basic block of the region with the new basic
+  ///        block.
+  ///
+  /// @param BB  The new exit basic block of the region.
+  void replaceExit(BlockT *BB);
+
+  /// @brief Recursively replace the entry basic block of the region.
+  ///
+  /// This function replaces the entry basic block with a new basic block. It
+  /// also updates all child regions that have the same entry basic block as
+  /// this region.
+  ///
+  /// @param NewEntry The new entry basic block.
+  void replaceEntryRecursive(BlockT *NewEntry);
+
+  /// @brief Recursively replace the exit basic block of the region.
+  ///
+  /// This function replaces the exit basic block with a new basic block. It
+  /// also updates all child regions that have the same exit basic block as
+  /// this region.
+  ///
+  /// @param NewExit The new exit basic block.
+  void replaceExitRecursive(BlockT *NewExit);
+
+  /// @brief Get the exit BasicBlock of the Region.
+  /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
+  ///         Region.
+  BlockT *getExit() const { return exit; }
+
+  /// @brief Get the parent of the Region.
+  /// @return The parent of the Region or NULL if this is a top level
+  ///         Region.
+  RegionT *getParent() const {
+    return RegionNodeBase<Tr>::getParent();
+  }
+
+  /// @brief Get the RegionNode representing the current Region.
+  /// @return The RegionNode representing the current Region.
+  RegionNodeT *getNode() const {
+    return const_cast<RegionNodeT *>(
+        reinterpret_cast<const RegionNodeT *>(this));
+  }
+
+  /// @brief Get the nesting level of this Region.
+  ///
+  /// An toplevel Region has depth 0.
+  ///
+  /// @return The depth of the region.
+  unsigned getDepth() const;
+
+  /// @brief Check if a Region is the TopLevel region.
+  ///
+  /// The toplevel region represents the whole function.
+  bool isTopLevelRegion() const { return exit == nullptr; }
+
+  /// @brief Return a new (non-canonical) region, that is obtained by joining
+  ///        this region with its predecessors.
+  ///
+  /// @return A region also starting at getEntry(), but reaching to the next
+  ///         basic block that forms with getEntry() a (non-canonical) region.
+  ///         NULL if such a basic block does not exist.
+  RegionT *getExpandedRegion() const;
+
+  /// @brief Return the first block of this region's single entry edge,
+  ///        if existing.
+  ///
+  /// @return The BasicBlock starting this region's single entry edge,
+  ///         else NULL.
+  BlockT *getEnteringBlock() const;
+
+  /// @brief Return the first block of this region's single exit edge,
+  ///        if existing.
+  ///
+  /// @return The BasicBlock starting this region's single exit edge,
+  ///         else NULL.
+  BlockT *getExitingBlock() const;
+
+  /// @brief Is this a simple region?
+  ///
+  /// A region is simple if it has exactly one exit and one entry edge.
+  ///
+  /// @return True if the Region is simple.
+  bool isSimple() const;
+
+  /// @brief Returns the name of the Region.
+  /// @return The Name of the Region.
+  std::string getNameStr() const;
+
+  /// @brief Return the RegionInfo object, that belongs to this Region.
+  RegionInfoT *getRegionInfo() const { return RI; }
+
+  /// PrintStyle - Print region in difference ways.
+  enum PrintStyle { PrintNone, PrintBB, PrintRN };
+
+  /// @brief Print the region.
+  ///
+  /// @param OS The output stream the Region is printed to.
+  /// @param printTree Print also the tree of subregions.
+  /// @param level The indentation level used for printing.
+  void print(raw_ostream &OS, bool printTree = true, unsigned level = 0,
+             PrintStyle Style = PrintNone) const;
+
+  /// @brief Print the region to stderr.
+  void dump() const;
+
+  /// @brief Check if the region contains a BasicBlock.
+  ///
+  /// @param BB The BasicBlock that might be contained in this Region.
+  /// @return True if the block is contained in the region otherwise false.
+  bool contains(const BlockT *BB) const;
+
+  /// @brief Check if the region contains another region.
+  ///
+  /// @param SubRegion The region that might be contained in this Region.
+  /// @return True if SubRegion is contained in the region otherwise false.
+  bool contains(const RegionT *SubRegion) const {
+    // Toplevel Region.
+    if (!getExit())
+      return true;
+
+    return contains(SubRegion->getEntry()) &&
+           (contains(SubRegion->getExit()) ||
+            SubRegion->getExit() == getExit());
+  }
+
+  /// @brief Check if the region contains an Instruction.
+  ///
+  /// @param Inst The Instruction that might be contained in this region.
+  /// @return True if the Instruction is contained in the region otherwise
+  /// false.
+  bool contains(const InstT *Inst) const { return contains(Inst->getParent()); }
+
+  /// @brief Check if the region contains a loop.
+  ///
+  /// @param L The loop that might be contained in this region.
+  /// @return True if the loop is contained in the region otherwise false.
+  ///         In case a NULL pointer is passed to this function the result
+  ///         is false, except for the region that describes the whole function.
+  ///         In that case true is returned.
+  bool contains(const LoopT *L) const;
+
+  /// @brief Get the outermost loop in the region that contains a loop.
+  ///
+  /// Find for a Loop L the outermost loop OuterL that is a parent loop of L
+  /// and is itself contained in the region.
+  ///
+  /// @param L The loop the lookup is started.
+  /// @return The outermost loop in the region, NULL if such a loop does not
+  ///         exist or if the region describes the whole function.
+  LoopT *outermostLoopInRegion(LoopT *L) const;
+
+  /// @brief Get the outermost loop in the region that contains a basic block.
+  ///
+  /// Find for a basic block BB the outermost loop L that contains BB and is
+  /// itself contained in the region.
+  ///
+  /// @param LI A pointer to a LoopInfo analysis.
+  /// @param BB The basic block surrounded by the loop.
+  /// @return The outermost loop in the region, NULL if such a loop does not
+  ///         exist or if the region describes the whole function.
+  LoopT *outermostLoopInRegion(LoopInfoT *LI, BlockT *BB) const;
+
+  /// @brief Get the subregion that starts at a BasicBlock
+  ///
+  /// @param BB The BasicBlock the subregion should start.
+  /// @return The Subregion if available, otherwise NULL.
+  RegionT *getSubRegionNode(BlockT *BB) const;
+
+  /// @brief Get the RegionNode for a BasicBlock
+  ///
+  /// @param BB The BasicBlock at which the RegionNode should start.
+  /// @return If available, the RegionNode that represents the subregion
+  ///         starting at BB. If no subregion starts at BB, the RegionNode
+  ///         representing BB.
+  RegionNodeT *getNode(BlockT *BB) const;
+
+  /// @brief Get the BasicBlock RegionNode for a BasicBlock
+  ///
+  /// @param BB The BasicBlock for which the RegionNode is requested.
+  /// @return The RegionNode representing the BB.
+  RegionNodeT *getBBNode(BlockT *BB) const;
+
+  /// @brief Add a new subregion to this Region.
+  ///
+  /// @param SubRegion The new subregion that will be added.
+  /// @param moveChildren Move the children of this region, that are also
+  ///                     contained in SubRegion into SubRegion.
+  void addSubRegion(RegionT *SubRegion, bool moveChildren = false);
+
+  /// @brief Remove a subregion from this Region.
+  ///
+  /// The subregion is not deleted, as it will probably be inserted into another
+  /// region.
+  /// @param SubRegion The SubRegion that will be removed.
+  RegionT *removeSubRegion(RegionT *SubRegion);
+
+  /// @brief Move all direct child nodes of this Region to another Region.
+  ///
+  /// @param To The Region the child nodes will be transferred to.
+  void transferChildrenTo(RegionT *To);
+
+  /// @brief Verify if the region is a correct region.
+  ///
+  /// Check if this is a correctly build Region. This is an expensive check, as
+  /// the complete CFG of the Region will be walked.
+  void verifyRegion() const;
+
+  /// @brief Clear the cache for BB RegionNodes.
+  ///
+  /// After calling this function the BasicBlock RegionNodes will be stored at
+  /// different memory locations. RegionNodes obtained before this function is
+  /// called are therefore not comparable to RegionNodes abtained afterwords.
+  void clearNodeCache();
+
+  /// @name Subregion Iterators
+  ///
+  /// These iterators iterator over all subregions of this Region.
+  //@{
+  typedef typename RegionSet::iterator iterator;
+  typedef typename RegionSet::const_iterator const_iterator;
+
+  iterator begin() { return children.begin(); }
+  iterator end() { return children.end(); }
+
+  const_iterator begin() const { return children.begin(); }
+  const_iterator end() const { return children.end(); }
+  //@}
+
+  /// @name BasicBlock Iterators
+  ///
+  /// These iterators iterate over all BasicBlocks that are contained in this
+  /// Region. The iterator also iterates over BasicBlocks that are elements of
+  /// a subregion of this Region. It is therefore called a flat iterator.
+  //@{
+  template <bool IsConst>
+  class block_iterator_wrapper
+      : public df_iterator<
+            typename std::conditional<IsConst, const BlockT, BlockT>::type *> {
+    typedef df_iterator<
+        typename std::conditional<IsConst, const BlockT, BlockT>::type *> super;
+
+  public:
+    typedef block_iterator_wrapper<IsConst> Self;
+    typedef typename super::pointer pointer;
+
+    // Construct the begin iterator.
+    block_iterator_wrapper(pointer Entry, pointer Exit)
+        : super(df_begin(Entry)) {
+      // Mark the exit of the region as visited, so that the children of the
+      // exit and the exit itself, i.e. the block outside the region will never
+      // be visited.
+      super::Visited.insert(Exit);
+    }
+
+    // Construct the end iterator.
+    block_iterator_wrapper() : super(df_end<pointer>((BlockT *)nullptr)) {}
+
+    /*implicit*/ block_iterator_wrapper(super I) : super(I) {}
+
+    // FIXME: Even a const_iterator returns a non-const BasicBlock pointer.
+    //        This was introduced for backwards compatibility, but should
+    //        be removed as soon as all users are fixed.
+    BlockT *operator*() const {
+      return const_cast<BlockT *>(super::operator*());
+    }
+  };
+
+  typedef block_iterator_wrapper<false> block_iterator;
+  typedef block_iterator_wrapper<true> const_block_iterator;
+
+  block_iterator block_begin() { return block_iterator(getEntry(), getExit()); }
+
+  block_iterator block_end() { return block_iterator(); }
+
+  const_block_iterator block_begin() const {
+    return const_block_iterator(getEntry(), getExit());
+  }
+  const_block_iterator block_end() const { return const_block_iterator(); }
+
+  typedef iterator_range<block_iterator> block_range;
+  typedef iterator_range<const_block_iterator> const_block_range;
+
+  /// @brief Returns a range view of the basic blocks in the region.
+  inline block_range blocks() {
+    return block_range(block_begin(), block_end());
+  }
+
+  /// @brief Returns a range view of the basic blocks in the region.
+  ///
+  /// This is the 'const' version of the range view.
+  inline const_block_range blocks() const {
+    return const_block_range(block_begin(), block_end());
+  }
+  //@}
+
+  /// @name Element Iterators
+  ///
+  /// These iterators iterate over all BasicBlock and subregion RegionNodes that
+  /// are direct children of this Region. It does not iterate over any
+  /// RegionNodes that are also element of a subregion of this Region.
+  //@{
+  typedef df_iterator<RegionNodeT *, SmallPtrSet<RegionNodeT *, 8>, false,
+                      GraphTraits<RegionNodeT *>> element_iterator;
+
+  typedef df_iterator<const RegionNodeT *, SmallPtrSet<const RegionNodeT *, 8>,
+                      false,
+                      GraphTraits<const RegionNodeT *>> const_element_iterator;
+
+  element_iterator element_begin();
+  element_iterator element_end();
+
+  const_element_iterator element_begin() const;
+  const_element_iterator element_end() const;
+  //@}
+};
+
+/// Print a RegionNode.
+template <class Tr>
+inline raw_ostream &operator<<(raw_ostream &OS, const RegionNodeBase<Tr> &Node);
+
+//===----------------------------------------------------------------------===//
+/// @brief Analysis that detects all canonical Regions.
+///
+/// The RegionInfo pass detects all canonical regions in a function. The Regions
+/// are connected using the parent relation. This builds a Program Structure
+/// Tree.
+template <class Tr>
+class RegionInfoBase {
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::FuncT FuncT;
+  typedef typename Tr::RegionT RegionT;
+  typedef typename Tr::RegionInfoT RegionInfoT;
+  typedef typename Tr::DomTreeT DomTreeT;
+  typedef typename Tr::DomTreeNodeT DomTreeNodeT;
+  typedef typename Tr::PostDomTreeT PostDomTreeT;
+  typedef typename Tr::DomFrontierT DomFrontierT;
+  typedef GraphTraits<BlockT *> BlockTraits;
+  typedef GraphTraits<Inverse<BlockT *>> InvBlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+  typedef typename InvBlockTraits::ChildIteratorType PredIterTy;
+
+  friend class RegionInfo;
+  friend class MachineRegionInfo;
+  typedef DenseMap<BlockT *, BlockT *> BBtoBBMap;
+  typedef DenseMap<BlockT *, RegionT *> BBtoRegionMap;
+  typedef SmallPtrSet<RegionT *, 4> RegionSet;
+
+  RegionInfoBase();
+  virtual ~RegionInfoBase();
+
+  RegionInfoBase(const RegionInfoBase &) LLVM_DELETED_FUNCTION;
+  const RegionInfoBase &operator=(const RegionInfoBase &) LLVM_DELETED_FUNCTION;
+
+  DomTreeT *DT;
+  PostDomTreeT *PDT;
+  DomFrontierT *DF;
+
+  /// The top level region.
+  RegionT *TopLevelRegion;
+
+private:
+  /// Map every BB to the smallest region, that contains BB.
+  BBtoRegionMap BBtoRegion;
+
+  // isCommonDomFrontier - Returns true if BB is in the dominance frontier of
+  // entry, because it was inherited from exit. In the other case there is an
+  // edge going from entry to BB without passing exit.
+  bool isCommonDomFrontier(BlockT *BB, BlockT *entry, BlockT *exit) const;
+
+  // isRegion - Check if entry and exit surround a valid region, based on
+  // dominance tree and dominance frontier.
+  bool isRegion(BlockT *entry, BlockT *exit) const;
+
+  // insertShortCut - Saves a shortcut pointing from entry to exit.
+  // This function may extend this shortcut if possible.
+  void insertShortCut(BlockT *entry, BlockT *exit, BBtoBBMap *ShortCut) const;
+
+  // getNextPostDom - Returns the next BB that postdominates N, while skipping
+  // all post dominators that cannot finish a canonical region.
+  DomTreeNodeT *getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const;
+
+  // isTrivialRegion - A region is trivial, if it contains only one BB.
+  bool isTrivialRegion(BlockT *entry, BlockT *exit) const;
+
+  // createRegion - Creates a single entry single exit region.
+  RegionT *createRegion(BlockT *entry, BlockT *exit);
+
+  // findRegionsWithEntry - Detect all regions starting with bb 'entry'.
+  void findRegionsWithEntry(BlockT *entry, BBtoBBMap *ShortCut);
+
+  // scanForRegions - Detects regions in F.
+  void scanForRegions(FuncT &F, BBtoBBMap *ShortCut);
+
+  // getTopMostParent - Get the top most parent with the same entry block.
+  RegionT *getTopMostParent(RegionT *region);
+
+  // buildRegionsTree - build the region hierarchy after all region detected.
+  void buildRegionsTree(DomTreeNodeT *N, RegionT *region);
+
+  // updateStatistics - Update statistic about created regions.
+  virtual void updateStatistics(RegionT *R) = 0;
+
+  // calculate - detect all regions in function and build the region tree.
+  void calculate(FuncT &F);
+
+public:
+  static bool VerifyRegionInfo;
+  static typename RegionT::PrintStyle printStyle;
+
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+  void releaseMemory();
+
+  /// @brief Get the smallest region that contains a BasicBlock.
+  ///
+  /// @param BB The basic block.
+  /// @return The smallest region, that contains BB or NULL, if there is no
+  /// region containing BB.
+  RegionT *getRegionFor(BlockT *BB) const;
+
+  /// @brief  Set the smallest region that surrounds a basic block.
+  ///
+  /// @param BB The basic block surrounded by a region.
+  /// @param R The smallest region that surrounds BB.
+  void setRegionFor(BlockT *BB, RegionT *R);
+
+  /// @brief A shortcut for getRegionFor().
+  ///
+  /// @param BB The basic block.
+  /// @return The smallest region, that contains BB or NULL, if there is no
+  /// region containing BB.
+  RegionT *operator[](BlockT *BB) const;
+
+  /// @brief Return the exit of the maximal refined region, that starts at a
+  /// BasicBlock.
+  ///
+  /// @param BB The BasicBlock the refined region starts.
+  BlockT *getMaxRegionExit(BlockT *BB) const;
+
+  /// @brief Find the smallest region that contains two regions.
+  ///
+  /// @param A The first region.
+  /// @param B The second region.
+  /// @return The smallest region containing A and B.
+  RegionT *getCommonRegion(RegionT *A, RegionT *B) const;
+
+  /// @brief Find the smallest region that contains two basic blocks.
+  ///
+  /// @param A The first basic block.
+  /// @param B The second basic block.
+  /// @return The smallest region that contains A and B.
+  RegionT *getCommonRegion(BlockT *A, BlockT *B) const {
+    return getCommonRegion(getRegionFor(A), getRegionFor(B));
+  }
+
+  /// @brief Find the smallest region that contains a set of regions.
+  ///
+  /// @param Regions A vector of regions.
+  /// @return The smallest region that contains all regions in Regions.
+  RegionT *getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const;
+
+  /// @brief Find the smallest region that contains a set of basic blocks.
+  ///
+  /// @param BBs A vector of basic blocks.
+  /// @return The smallest region that contains all basic blocks in BBS.
+  RegionT *getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const;
+
+  RegionT *getTopLevelRegion() const { return TopLevelRegion; }
+
+  /// @brief Update RegionInfo after a basic block was split.
+  ///
+  /// @param NewBB The basic block that was created before OldBB.
+  /// @param OldBB The old basic block.
+  void splitBlock(BlockT *NewBB, BlockT *OldBB);
+
+  /// @brief Clear the Node Cache for all Regions.
+  ///
+  /// @see Region::clearNodeCache()
+  void clearNodeCache() {
+    if (TopLevelRegion)
+      TopLevelRegion->clearNodeCache();
+  }
+
+  void verifyAnalysis() const;
+};
+
+class Region;
+
+class RegionNode : public RegionNodeBase<RegionTraits<Function>> {
+public:
+  inline RegionNode(Region *Parent, BasicBlock *Entry, bool isSubRegion = false)
+      : RegionNodeBase<RegionTraits<Function>>(Parent, Entry, isSubRegion) {}
+
+  ~RegionNode() {}
+
+  bool operator==(const Region &RN) const {
+    return this == reinterpret_cast<const RegionNode *>(&RN);
+  }
+};
+
+class Region : public RegionBase<RegionTraits<Function>> {
+public:
+  Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo *RI, DominatorTree *DT,
+         Region *Parent = nullptr);
+  ~Region();
+
+  bool operator==(const RegionNode &RN) const {
+    return &RN == reinterpret_cast<const RegionNode *>(this);
+  }
+};
+
+class RegionInfo : public RegionInfoBase<RegionTraits<Function>> {
+public:
+  explicit RegionInfo();
+
+  virtual ~RegionInfo();
+
+  // updateStatistics - Update statistic about created regions.
+  void updateStatistics(Region *R) final;
+
+  void recalculate(Function &F, DominatorTree *DT, PostDominatorTree *PDT,
+                   DominanceFrontier *DF);
+};
+
+class RegionInfoPass : public FunctionPass {
+  RegionInfo RI;
+
+public:
+  static char ID;
+  explicit RegionInfoPass();
+
+  ~RegionInfoPass();
+
+  RegionInfo &getRegionInfo() { return RI; }
+
+  const RegionInfo &getRegionInfo() const { return RI; }
+
+  /// @name FunctionPass interface
+  //@{
+  bool runOnFunction(Function &F) override;
+  void releaseMemory() override;
+  void verifyAnalysis() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void print(raw_ostream &OS, const Module *) const override;
+  void dump() const;
+  //@}
+};
+
+template <>
+template <>
+inline BasicBlock *
+RegionNodeBase<RegionTraits<Function>>::getNodeAs<BasicBlock>() const {
+  assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
+  return getEntry();
+}
+
+template <>
+template <>
+inline Region *
+RegionNodeBase<RegionTraits<Function>>::getNodeAs<Region>() const {
+  assert(isSubRegion() && "This is not a subregion RegionNode!");
+  auto Unconst = const_cast<RegionNodeBase<RegionTraits<Function>> *>(this);
+  return reinterpret_cast<Region *>(Unconst);
+}
+
+template <class Tr>
+inline raw_ostream &operator<<(raw_ostream &OS,
+                               const RegionNodeBase<Tr> &Node) {
+  typedef typename Tr::BlockT BlockT;
+  typedef typename Tr::RegionT RegionT;
+
+  if (Node.isSubRegion())
+    return OS << Node.template getNodeAs<RegionT>()->getNameStr();
+  else
+    return OS << Node.template getNodeAs<BlockT>()->getName();
+}
+
+EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>);
+
+} // End llvm namespace
+#endif
diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h
new file mode 100644
index 0000000..4266b84
--- /dev/null
+++ b/include/llvm/Analysis/RegionInfoImpl.h
@@ -0,0 +1,919 @@
+//===- RegionInfoImpl.h - SESE region detection analysis --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Detects single entry single exit regions in the control flow graph.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONINFOIMPL_H
+#define LLVM_ANALYSIS_REGIONINFOIMPL_H
+
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "region"
+
+//===----------------------------------------------------------------------===//
+/// RegionBase Implementation
+template <class Tr>
+RegionBase<Tr>::RegionBase(BlockT *Entry, BlockT *Exit,
+                           typename Tr::RegionInfoT *RInfo, DomTreeT *dt,
+                           RegionT *Parent)
+    : RegionNodeBase<Tr>(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
+
+template <class Tr>
+RegionBase<Tr>::~RegionBase() {
+  // Free the cached nodes.
+  for (typename BBNodeMapT::iterator it = BBNodeMap.begin(),
+                                     ie = BBNodeMap.end();
+       it != ie; ++it)
+    delete it->second;
+
+  // Only clean the cache for this Region. Caches of child Regions will be
+  // cleaned when the child Regions are deleted.
+  BBNodeMap.clear();
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceEntry(BlockT *BB) {
+  this->entry.setPointer(BB);
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceExit(BlockT *BB) {
+  assert(exit && "No exit to replace!");
+  exit = BB;
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceEntryRecursive(BlockT *NewEntry) {
+  std::vector<RegionT *> RegionQueue;
+  BlockT *OldEntry = getEntry();
+
+  RegionQueue.push_back(static_cast<RegionT *>(this));
+  while (!RegionQueue.empty()) {
+    RegionT *R = RegionQueue.back();
+    RegionQueue.pop_back();
+
+    R->replaceEntry(NewEntry);
+    for (typename RegionT::const_iterator RI = R->begin(), RE = R->end();
+         RI != RE; ++RI) {
+      if ((*RI)->getEntry() == OldEntry)
+        RegionQueue.push_back(RI->get());
+    }
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::replaceExitRecursive(BlockT *NewExit) {
+  std::vector<RegionT *> RegionQueue;
+  BlockT *OldExit = getExit();
+
+  RegionQueue.push_back(static_cast<RegionT *>(this));
+  while (!RegionQueue.empty()) {
+    RegionT *R = RegionQueue.back();
+    RegionQueue.pop_back();
+
+    R->replaceExit(NewExit);
+    for (typename RegionT::const_iterator RI = R->begin(), RE = R->end();
+         RI != RE; ++RI) {
+      if ((*RI)->getExit() == OldExit)
+        RegionQueue.push_back(RI->get());
+    }
+  }
+}
+
+template <class Tr>
+bool RegionBase<Tr>::contains(const BlockT *B) const {
+  BlockT *BB = const_cast<BlockT *>(B);
+
+  if (!DT->getNode(BB))
+    return false;
+
+  BlockT *entry = getEntry(), *exit = getExit();
+
+  // Toplevel region.
+  if (!exit)
+    return true;
+
+  return (DT->dominates(entry, BB) &&
+          !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
+}
+
+template <class Tr>
+bool RegionBase<Tr>::contains(const LoopT *L) const {
+  // BBs that are not part of any loop are element of the Loop
+  // described by the NULL pointer. This loop is not part of any region,
+  // except if the region describes the whole function.
+  if (!L)
+    return getExit() == nullptr;
+
+  if (!contains(L->getHeader()))
+    return false;
+
+  SmallVector<BlockT *, 8> ExitingBlocks;
+  L->getExitingBlocks(ExitingBlocks);
+
+  for (BlockT *BB : ExitingBlocks) {
+    if (!contains(BB))
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopT *L) const {
+  if (!contains(L))
+    return nullptr;
+
+  while (L && contains(L->getParentLoop())) {
+    L = L->getParentLoop();
+  }
+
+  return L;
+}
+
+template <class Tr>
+typename Tr::LoopT *RegionBase<Tr>::outermostLoopInRegion(LoopInfoT *LI,
+                                                          BlockT *BB) const {
+  assert(LI && BB && "LI and BB cannot be null!");
+  LoopT *L = LI->getLoopFor(BB);
+  return outermostLoopInRegion(L);
+}
+
+template <class Tr>
+typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getEnteringBlock() const {
+  BlockT *entry = getEntry();
+  BlockT *Pred;
+  BlockT *enteringBlock = nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(entry),
+                  PE = InvBlockTraits::child_end(entry);
+       PI != PE; ++PI) {
+    Pred = *PI;
+    if (DT->getNode(Pred) && !contains(Pred)) {
+      if (enteringBlock)
+        return nullptr;
+
+      enteringBlock = Pred;
+    }
+  }
+
+  return enteringBlock;
+}
+
+template <class Tr>
+typename RegionBase<Tr>::BlockT *RegionBase<Tr>::getExitingBlock() const {
+  BlockT *exit = getExit();
+  BlockT *Pred;
+  BlockT *exitingBlock = nullptr;
+
+  if (!exit)
+    return nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(exit),
+                  PE = InvBlockTraits::child_end(exit);
+       PI != PE; ++PI) {
+    Pred = *PI;
+    if (contains(Pred)) {
+      if (exitingBlock)
+        return nullptr;
+
+      exitingBlock = Pred;
+    }
+  }
+
+  return exitingBlock;
+}
+
+template <class Tr>
+bool RegionBase<Tr>::isSimple() const {
+  return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock();
+}
+
+template <class Tr>
+std::string RegionBase<Tr>::getNameStr() const {
+  std::string exitName;
+  std::string entryName;
+
+  if (getEntry()->getName().empty()) {
+    raw_string_ostream OS(entryName);
+
+    getEntry()->printAsOperand(OS, false);
+  } else
+    entryName = getEntry()->getName();
+
+  if (getExit()) {
+    if (getExit()->getName().empty()) {
+      raw_string_ostream OS(exitName);
+
+      getExit()->printAsOperand(OS, false);
+    } else
+      exitName = getExit()->getName();
+  } else
+    exitName = "<Function Return>";
+
+  return entryName + " => " + exitName;
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const {
+  if (!contains(BB))
+    llvm_unreachable("Broken region found!");
+
+  BlockT *entry = getEntry(), *exit = getExit();
+
+  for (SuccIterTy SI = BlockTraits::child_begin(BB),
+                  SE = BlockTraits::child_end(BB);
+       SI != SE; ++SI) {
+    if (!contains(*SI) && exit != *SI)
+      llvm_unreachable("Broken region found!");
+  }
+
+  if (entry != BB) {
+    for (PredIterTy SI = InvBlockTraits::child_begin(BB),
+                    SE = InvBlockTraits::child_end(BB);
+         SI != SE; ++SI) {
+      if (!contains(*SI))
+        llvm_unreachable("Broken region found!");
+    }
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyWalk(BlockT *BB, std::set<BlockT *> *visited) const {
+  BlockT *exit = getExit();
+
+  visited->insert(BB);
+
+  verifyBBInRegion(BB);
+
+  for (SuccIterTy SI = BlockTraits::child_begin(BB),
+                  SE = BlockTraits::child_end(BB);
+       SI != SE; ++SI) {
+    if (*SI != exit && visited->find(*SI) == visited->end())
+      verifyWalk(*SI, visited);
+  }
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyRegion() const {
+  // Only do verification when user wants to, otherwise this expensive check
+  // will be invoked by PMDataManager::verifyPreservedAnalysis when
+  // a regionpass (marked PreservedAll) finish.
+  if (!RegionInfoBase<Tr>::VerifyRegionInfo)
+    return;
+
+  std::set<BlockT *> visited;
+  verifyWalk(getEntry(), &visited);
+}
+
+template <class Tr>
+void RegionBase<Tr>::verifyRegionNest() const {
+  for (typename RegionT::const_iterator RI = begin(), RE = end(); RI != RE;
+       ++RI)
+    (*RI)->verifyRegionNest();
+
+  verifyRegion();
+}
+
+template <class Tr>
+typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_begin() {
+  return GraphTraits<RegionT *>::nodes_begin(static_cast<RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::element_iterator RegionBase<Tr>::element_end() {
+  return GraphTraits<RegionT *>::nodes_end(static_cast<RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::const_element_iterator
+RegionBase<Tr>::element_begin() const {
+  return GraphTraits<const RegionT *>::nodes_begin(
+      static_cast<const RegionT *>(this));
+}
+
+template <class Tr>
+typename RegionBase<Tr>::const_element_iterator
+RegionBase<Tr>::element_end() const {
+  return GraphTraits<const RegionT *>::nodes_end(
+      static_cast<const RegionT *>(this));
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::getSubRegionNode(BlockT *BB) const {
+  typedef typename Tr::RegionT RegionT;
+  RegionT *R = RI->getRegionFor(BB);
+
+  if (!R || R == this)
+    return nullptr;
+
+  // If we pass the BB out of this region, that means our code is broken.
+  assert(contains(R) && "BB not in current region!");
+
+  while (contains(R->getParent()) && R->getParent() != this)
+    R = R->getParent();
+
+  if (R->getEntry() != BB)
+    return nullptr;
+
+  return R;
+}
+
+template <class Tr>
+typename Tr::RegionNodeT *RegionBase<Tr>::getBBNode(BlockT *BB) const {
+  assert(contains(BB) && "Can get BB node out of this region!");
+
+  typename BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
+
+  if (at != BBNodeMap.end())
+    return at->second;
+
+  auto Deconst = const_cast<RegionBase<Tr> *>(this);
+  RegionNodeT *NewNode = new RegionNodeT(static_cast<RegionT *>(Deconst), BB);
+  BBNodeMap.insert(std::make_pair(BB, NewNode));
+  return NewNode;
+}
+
+template <class Tr>
+typename Tr::RegionNodeT *RegionBase<Tr>::getNode(BlockT *BB) const {
+  assert(contains(BB) && "Can get BB node out of this region!");
+  if (RegionT *Child = getSubRegionNode(BB))
+    return Child->getNode();
+
+  return getBBNode(BB);
+}
+
+template <class Tr>
+void RegionBase<Tr>::transferChildrenTo(RegionT *To) {
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    (*I)->parent = To;
+    To->children.push_back(std::move(*I));
+  }
+  children.clear();
+}
+
+template <class Tr>
+void RegionBase<Tr>::addSubRegion(RegionT *SubRegion, bool moveChildren) {
+  assert(!SubRegion->parent && "SubRegion already has a parent!");
+  assert(std::find_if(begin(), end(), [&](const std::unique_ptr<RegionT> &R) {
+           return R.get() == SubRegion;
+         }) == children.end() &&
+         "Subregion already exists!");
+
+  SubRegion->parent = static_cast<RegionT *>(this);
+  children.push_back(std::unique_ptr<RegionT>(SubRegion));
+
+  if (!moveChildren)
+    return;
+
+  assert(SubRegion->children.empty() &&
+         "SubRegions that contain children are not supported");
+
+  for (element_iterator I = element_begin(), E = element_end(); I != E; ++I) {
+    if (!(*I)->isSubRegion()) {
+      BlockT *BB = (*I)->template getNodeAs<BlockT>();
+
+      if (SubRegion->contains(BB))
+        RI->setRegionFor(BB, SubRegion);
+    }
+  }
+
+  std::vector<std::unique_ptr<RegionT>> Keep;
+  for (iterator I = begin(), E = end(); I != E; ++I) {
+    if (SubRegion->contains(I->get()) && I->get() != SubRegion) {
+      (*I)->parent = SubRegion;
+      SubRegion->children.push_back(std::move(*I));
+    } else
+      Keep.push_back(std::move(*I));
+  }
+
+  children.clear();
+  children.insert(
+      children.begin(),
+      std::move_iterator<typename RegionSet::iterator>(Keep.begin()),
+      std::move_iterator<typename RegionSet::iterator>(Keep.end()));
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::removeSubRegion(RegionT *Child) {
+  assert(Child->parent == this && "Child is not a child of this region!");
+  Child->parent = nullptr;
+  typename RegionSet::iterator I = std::find_if(
+      children.begin(), children.end(),
+      [&](const std::unique_ptr<RegionT> &R) { return R.get() == Child; });
+  assert(I != children.end() && "Region does not exit. Unable to remove.");
+  children.erase(children.begin() + (I - begin()));
+  return Child;
+}
+
+template <class Tr>
+unsigned RegionBase<Tr>::getDepth() const {
+  unsigned Depth = 0;
+
+  for (RegionT *R = getParent(); R != nullptr; R = R->getParent())
+    ++Depth;
+
+  return Depth;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const {
+  unsigned NumSuccessors = Tr::getNumSuccessors(exit);
+
+  if (NumSuccessors == 0)
+    return nullptr;
+
+  for (PredIterTy PI = InvBlockTraits::child_begin(getExit()),
+                  PE = InvBlockTraits::child_end(getExit());
+       PI != PE; ++PI) {
+    if (!DT->dominates(getEntry(), *PI))
+      return nullptr;
+  }
+
+  RegionT *R = RI->getRegionFor(exit);
+
+  if (R->getEntry() != exit) {
+    if (Tr::getNumSuccessors(exit) == 1)
+      return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT);
+    return nullptr;
+  }
+
+  while (R->getParent() && R->getParent()->getEntry() == exit)
+    R = R->getParent();
+
+  if (!DT->dominates(getEntry(), R->getExit())) {
+    for (PredIterTy PI = InvBlockTraits::child_begin(getExit()),
+                    PE = InvBlockTraits::child_end(getExit());
+         PI != PE; ++PI) {
+      if (!DT->dominates(R->getExit(), *PI))
+        return nullptr;
+    }
+  }
+
+  return new RegionT(getEntry(), R->getExit(), RI, DT);
+}
+
+template <class Tr>
+void RegionBase<Tr>::print(raw_ostream &OS, bool print_tree, unsigned level,
+                           PrintStyle Style) const {
+  if (print_tree)
+    OS.indent(level * 2) << '[' << level << "] " << getNameStr();
+  else
+    OS.indent(level * 2) << getNameStr();
+
+  OS << '\n';
+
+  if (Style != PrintNone) {
+    OS.indent(level * 2) << "{\n";
+    OS.indent(level * 2 + 2);
+
+    if (Style == PrintBB) {
+      for (const auto &BB : blocks())
+        OS << BB->getName() << ", "; // TODO: remove the last ","
+    } else if (Style == PrintRN) {
+      for (const_element_iterator I = element_begin(), E = element_end();
+           I != E; ++I) {
+        OS << **I << ", "; // TODO: remove the last ",
+      }
+    }
+
+    OS << '\n';
+  }
+
+  if (print_tree) {
+    for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
+      (*RI)->print(OS, print_tree, level + 1, Style);
+  }
+
+  if (Style != PrintNone)
+    OS.indent(level * 2) << "} \n";
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <class Tr>
+void RegionBase<Tr>::dump() const {
+  print(dbgs(), true, getDepth(), RegionInfoBase<Tr>::printStyle);
+}
+#endif
+
+template <class Tr>
+void RegionBase<Tr>::clearNodeCache() {
+  // Free the cached nodes.
+  for (typename BBNodeMapT::iterator I = BBNodeMap.begin(),
+                                     IE = BBNodeMap.end();
+       I != IE; ++I)
+    delete I->second;
+
+  BBNodeMap.clear();
+  for (typename RegionT::iterator RI = begin(), RE = end(); RI != RE; ++RI)
+    (*RI)->clearNodeCache();
+}
+
+//===----------------------------------------------------------------------===//
+// RegionInfoBase implementation
+//
+
+template <class Tr>
+RegionInfoBase<Tr>::RegionInfoBase()
+    : TopLevelRegion(nullptr) {}
+
+template <class Tr>
+RegionInfoBase<Tr>::~RegionInfoBase() {
+  releaseMemory();
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry,
+                                             BlockT *exit) const {
+  for (PredIterTy PI = InvBlockTraits::child_begin(BB),
+                  PE = InvBlockTraits::child_end(BB);
+       PI != PE; ++PI) {
+    BlockT *P = *PI;
+    if (DT->dominates(entry, P) && !DT->dominates(exit, P))
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isRegion(BlockT *entry, BlockT *exit) const {
+  assert(entry && exit && "entry and exit must not be null!");
+  typedef typename DomFrontierT::DomSetType DST;
+
+  DST *entrySuccs = &DF->find(entry)->second;
+
+  // Exit is the header of a loop that contains the entry. In this case,
+  // the dominance frontier must only contain the exit.
+  if (!DT->dominates(entry, exit)) {
+    for (typename DST::iterator SI = entrySuccs->begin(),
+                                SE = entrySuccs->end();
+         SI != SE; ++SI) {
+      if (*SI != exit && *SI != entry)
+        return false;
+    }
+
+    return true;
+  }
+
+  DST *exitSuccs = &DF->find(exit)->second;
+
+  // Do not allow edges leaving the region.
+  for (typename DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
+       SI != SE; ++SI) {
+    if (*SI == exit || *SI == entry)
+      continue;
+    if (exitSuccs->find(*SI) == exitSuccs->end())
+      return false;
+    if (!isCommonDomFrontier(*SI, entry, exit))
+      return false;
+  }
+
+  // Do not allow edges pointing into the region.
+  for (typename DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
+       SI != SE; ++SI) {
+    if (DT->properlyDominates(entry, *SI) && *SI != exit)
+      return false;
+  }
+
+  return true;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::insertShortCut(BlockT *entry, BlockT *exit,
+                                        BBtoBBMap *ShortCut) const {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  typename BBtoBBMap::iterator e = ShortCut->find(exit);
+
+  if (e == ShortCut->end())
+    // No further region at exit available.
+    (*ShortCut)[entry] = exit;
+  else {
+    // We found a region e that starts at exit. Therefore (entry, e->second)
+    // is also a region, that is larger than (entry, exit). Insert the
+    // larger one.
+    BlockT *BB = e->second;
+    (*ShortCut)[entry] = BB;
+  }
+}
+
+template <class Tr>
+typename Tr::DomTreeNodeT *
+RegionInfoBase<Tr>::getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const {
+  typename BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
+
+  if (e == ShortCut->end())
+    return N->getIDom();
+
+  return PDT->getNode(e->second)->getIDom();
+}
+
+template <class Tr>
+bool RegionInfoBase<Tr>::isTrivialRegion(BlockT *entry, BlockT *exit) const {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  unsigned num_successors =
+      BlockTraits::child_end(entry) - BlockTraits::child_begin(entry);
+
+  if (num_successors <= 1 && exit == *(BlockTraits::child_begin(entry)))
+    return true;
+
+  return false;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::createRegion(BlockT *entry,
+                                                       BlockT *exit) {
+  assert(entry && exit && "entry and exit must not be null!");
+
+  if (isTrivialRegion(entry, exit))
+    return nullptr;
+
+  RegionT *region =
+      new RegionT(entry, exit, static_cast<RegionInfoT *>(this), DT);
+  BBtoRegion.insert(std::make_pair(entry, region));
+
+#ifdef XDEBUG
+  region->verifyRegion();
+#else
+  DEBUG(region->verifyRegion());
+#endif
+
+  updateStatistics(region);
+  return region;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry,
+                                              BBtoBBMap *ShortCut) {
+  assert(entry);
+
+  DomTreeNodeT *N = PDT->getNode(entry);
+  if (!N)
+    return;
+
+  RegionT *lastRegion = nullptr;
+  BlockT *lastExit = entry;
+
+  // As only a BasicBlock that postdominates entry can finish a region, walk the
+  // post dominance tree upwards.
+  while ((N = getNextPostDom(N, ShortCut))) {
+    BlockT *exit = N->getBlock();
+
+    if (!exit)
+      break;
+
+    if (isRegion(entry, exit)) {
+      RegionT *newRegion = createRegion(entry, exit);
+
+      if (lastRegion)
+        newRegion->addSubRegion(lastRegion);
+
+      lastRegion = newRegion;
+      lastExit = exit;
+    }
+
+    // This can never be a region, so stop the search.
+    if (!DT->dominates(entry, exit))
+      break;
+  }
+
+  // Tried to create regions from entry to lastExit.  Next time take a
+  // shortcut from entry to lastExit.
+  if (lastExit != entry)
+    insertShortCut(entry, lastExit, ShortCut);
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
+  typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+  BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F);
+  DomTreeNodeT *N = DT->getNode(entry);
+
+  // Iterate over the dominance tree in post order to start with the small
+  // regions from the bottom of the dominance tree.  If the small regions are
+  // detected first, detection of bigger regions is faster, as we can jump
+  // over the small regions.
+  for (po_iterator<DomTreeNodeT *> FI = po_begin(N), FE = po_end(N); FI != FE;
+       ++FI) {
+    findRegionsWithEntry(FI->getBlock(), ShortCut);
+  }
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getTopMostParent(RegionT *region) {
+  while (region->getParent())
+    region = region->getParent();
+
+  return region;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::buildRegionsTree(DomTreeNodeT *N, RegionT *region) {
+  BlockT *BB = N->getBlock();
+
+  // Passed region exit
+  while (BB == region->getExit())
+    region = region->getParent();
+
+  typename BBtoRegionMap::iterator it = BBtoRegion.find(BB);
+
+  // This basic block is a start block of a region. It is already in the
+  // BBtoRegion relation. Only the child basic blocks have to be updated.
+  if (it != BBtoRegion.end()) {
+    RegionT *newRegion = it->second;
+    region->addSubRegion(getTopMostParent(newRegion));
+    region = newRegion;
+  } else {
+    BBtoRegion[BB] = region;
+  }
+
+  for (typename DomTreeNodeT::iterator CI = N->begin(), CE = N->end(); CI != CE;
+       ++CI) {
+    buildRegionsTree(*CI, region);
+  }
+}
+
+#ifdef XDEBUG
+template <class Tr>
+bool RegionInfoBase<Tr>::VerifyRegionInfo = true;
+#else
+template <class Tr>
+bool RegionInfoBase<Tr>::VerifyRegionInfo = false;
+#endif
+
+template <class Tr>
+typename Tr::RegionT::PrintStyle RegionInfoBase<Tr>::printStyle =
+    RegionBase<Tr>::PrintNone;
+
+template <class Tr>
+void RegionInfoBase<Tr>::print(raw_ostream &OS) const {
+  OS << "Region tree:\n";
+  TopLevelRegion->print(OS, true, 0, printStyle);
+  OS << "End region tree\n";
+}
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <class Tr>
+void RegionInfoBase<Tr>::dump() const { print(dbgs()); }
+#endif
+
+template <class Tr>
+void RegionInfoBase<Tr>::releaseMemory() {
+  BBtoRegion.clear();
+  if (TopLevelRegion)
+    delete TopLevelRegion;
+  TopLevelRegion = nullptr;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::verifyAnalysis() const {
+  TopLevelRegion->verifyRegionNest();
+}
+
+// Region pass manager support.
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getRegionFor(BlockT *BB) const {
+  typename BBtoRegionMap::const_iterator I = BBtoRegion.find(BB);
+  return I != BBtoRegion.end() ? I->second : nullptr;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::setRegionFor(BlockT *BB, RegionT *R) {
+  BBtoRegion[BB] = R;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::operator[](BlockT *BB) const {
+  return getRegionFor(BB);
+}
+
+template <class Tr>
+typename RegionInfoBase<Tr>::BlockT *
+RegionInfoBase<Tr>::getMaxRegionExit(BlockT *BB) const {
+  BlockT *Exit = nullptr;
+
+  while (true) {
+    // Get largest region that starts at BB.
+    RegionT *R = getRegionFor(BB);
+    while (R && R->getParent() && R->getParent()->getEntry() == BB)
+      R = R->getParent();
+
+    // Get the single exit of BB.
+    if (R && R->getEntry() == BB)
+      Exit = R->getExit();
+    else if (++BlockTraits::child_begin(BB) == BlockTraits::child_end(BB))
+      Exit = *BlockTraits::child_begin(BB);
+    else // No single exit exists.
+      return Exit;
+
+    // Get largest region that starts at Exit.
+    RegionT *ExitR = getRegionFor(Exit);
+    while (ExitR && ExitR->getParent() &&
+           ExitR->getParent()->getEntry() == Exit)
+      ExitR = ExitR->getParent();
+
+    for (PredIterTy PI = InvBlockTraits::child_begin(Exit),
+                    PE = InvBlockTraits::child_end(Exit);
+         PI != PE; ++PI) {
+      if (!R->contains(*PI) && !ExitR->contains(*PI))
+        break;
+    }
+
+    // This stops infinite cycles.
+    if (DT->dominates(Exit, BB))
+      break;
+
+    BB = Exit;
+  }
+
+  return Exit;
+}
+
+template <class Tr>
+typename Tr::RegionT *RegionInfoBase<Tr>::getCommonRegion(RegionT *A,
+                                                          RegionT *B) const {
+  assert(A && B && "One of the Regions is NULL");
+
+  if (A->contains(B))
+    return A;
+
+  while (!B->contains(A))
+    B = B->getParent();
+
+  return B;
+}
+
+template <class Tr>
+typename Tr::RegionT *
+RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<RegionT *> &Regions) const {
+  RegionT *ret = Regions.back();
+  Regions.pop_back();
+
+  for (RegionT *R : Regions)
+    ret = getCommonRegion(ret, R);
+
+  return ret;
+}
+
+template <class Tr>
+typename Tr::RegionT *
+RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const {
+  RegionT *ret = getRegionFor(BBs.back());
+  BBs.pop_back();
+
+  for (BlockT *BB : BBs)
+    ret = getCommonRegion(ret, getRegionFor(BB));
+
+  return ret;
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::splitBlock(BlockT *NewBB, BlockT *OldBB) {
+  RegionT *R = getRegionFor(OldBB);
+
+  setRegionFor(NewBB, R);
+
+  while (R->getEntry() == OldBB && !R->isTopLevelRegion()) {
+    R->replaceEntry(NewBB);
+    R = R->getParent();
+  }
+
+  setRegionFor(OldBB, R);
+}
+
+template <class Tr>
+void RegionInfoBase<Tr>::calculate(FuncT &F) {
+  typedef typename std::add_pointer<FuncT>::type FuncPtrT;
+
+  // ShortCut a function where for every BB the exit of the largest region
+  // starting with BB is stored. These regions can be threated as single BBS.
+  // This improves performance on linear CFGs.
+  BBtoBBMap ShortCut;
+
+  scanForRegions(F, &ShortCut);
+  BlockT *BB = GraphTraits<FuncPtrT>::getEntryNode(&F);
+  buildRegionsTree(DT->getNode(BB), TopLevelRegion);
+}
+
+#endif
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
new file mode 100644
index 0000000..0daff58
--- /dev/null
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -0,0 +1,365 @@
+//===- RegionIterator.h - Iterators to iteratate over Regions ---*- 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 iterators to iterate over the elements of a Region.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
+#define LLVM_ANALYSIS_REGIONITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+//===----------------------------------------------------------------------===//
+/// @brief Hierarchical RegionNode successor iterator.
+///
+/// This iterator iterates over all successors of a RegionNode.
+///
+/// For a BasicBlock RegionNode it skips all BasicBlocks that are not part of
+/// the parent Region.  Furthermore for BasicBlocks that start a subregion, a
+/// RegionNode representing the subregion is returned.
+///
+/// For a subregion RegionNode there is just one successor. The RegionNode
+/// representing the exit of the subregion.
+template<class NodeType, class BlockT, class RegionT>
+class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
+                                           NodeType, ptrdiff_t> {
+  typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
+  // The iterator works in two modes, bb mode or region mode.
+  enum ItMode {
+    // In BB mode it returns all successors of this BasicBlock as its
+    // successors.
+    ItBB,
+    // In region mode there is only one successor, thats the regionnode mapping
+    // to the exit block of the regionnode
+    ItRgBegin, // At the beginning of the regionnode successor.
+    ItRgEnd    // At the end of the regionnode successor.
+  };
+
+  // Use two bit to represent the mode iterator.
+  PointerIntPair<NodeType*, 2, ItMode> Node;
+
+  // The block successor iterator.
+  SuccIterTy BItor;
+
+  // advanceRegionSucc - A region node has only one successor. It reaches end
+  // once we advance it.
+  void advanceRegionSucc() {
+    assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");
+    Node.setInt(ItRgEnd);
+  }
+
+  NodeType* getNode() const{ return Node.getPointer(); }
+
+  // isRegionMode - Is the current iterator in region mode?
+  bool isRegionMode() const { return Node.getInt() != ItBB; }
+
+  // Get the immediate successor. This function may return a Basic Block
+  // RegionNode or a subregion RegionNode.
+  NodeType* getISucc(BlockT* BB) const {
+    NodeType *succ;
+    succ = getNode()->getParent()->getNode(BB);
+    assert(succ && "BB not in Region or entered subregion!");
+    return succ;
+  }
+
+  // getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
+  inline BlockT* getRegionSucc() const {
+    assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
+    return getNode()->template getNodeAs<RegionT>()->getExit();
+  }
+
+  // isExit - Is this the exit BB of the Region?
+  inline bool isExit(BlockT* BB) const {
+    return getNode()->getParent()->getExit() == BB;
+  }
+public:
+  typedef RNSuccIterator<NodeType, BlockT, RegionT> Self;
+
+  typedef typename super::pointer pointer;
+
+  /// @brief Create begin iterator of a RegionNode.
+  inline RNSuccIterator(NodeType* node)
+    : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
+      BItor(BlockTraits::child_begin(node->getEntry())) {
+
+    // Skip the exit block
+    if (!isRegionMode())
+      while (BlockTraits::child_end(node->getEntry()) != BItor && isExit(*BItor))
+        ++BItor;
+
+    if (isRegionMode() && isExit(getRegionSucc()))
+      advanceRegionSucc();
+  }
+
+  /// @brief Create an end iterator.
+  inline RNSuccIterator(NodeType* node, bool)
+    : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
+      BItor(BlockTraits::child_end(node->getEntry())) {}
+
+  inline bool operator==(const Self& x) const {
+    assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
+    if (isRegionMode())
+      return Node.getInt() == x.Node.getInt();
+    else
+      return BItor == x.BItor;
+  }
+
+  inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+  inline pointer operator*() const {
+    BlockT *BB = isRegionMode() ? getRegionSucc() : *BItor;
+    assert(!isExit(BB) && "Iterator out of range!");
+    return getISucc(BB);
+  }
+
+  inline Self& operator++() {
+    if(isRegionMode()) {
+      // The Region only has 1 successor.
+      advanceRegionSucc();
+    } else {
+      // Skip the exit.
+      do
+        ++BItor;
+      while (BItor != BlockTraits::child_end(getNode()->getEntry())
+          && isExit(*BItor));
+    }
+    return *this;
+  }
+
+  inline Self operator++(int) {
+    Self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  inline const Self &operator=(const Self &I) {
+    if (this != &I) {
+      assert(getNode()->getParent() == I.getNode()->getParent()
+             && "Cannot assign iterators of two different regions!");
+      Node = I.Node;
+      BItor = I.BItor;
+    }
+    return *this;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// @brief Flat RegionNode iterator.
+///
+/// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
+/// are contained in the Region and its subregions. This is close to a virtual
+/// control flow graph of the Region.
+template<class NodeType, class BlockT, class RegionT>
+class RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>
+  : public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> {
+  typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+  typedef GraphTraits<BlockT*> BlockTraits;
+  typedef typename BlockTraits::ChildIteratorType SuccIterTy;
+
+  NodeType* Node;
+  SuccIterTy Itor;
+
+public:
+  typedef RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT> Self;
+  typedef typename super::pointer pointer;
+
+  /// @brief Create the iterator from a RegionNode.
+  ///
+  /// Note that the incoming node must be a bb node, otherwise it will trigger
+  /// an assertion when we try to get a BasicBlock.
+  inline RNSuccIterator(NodeType* node) :
+    Node(node),
+    Itor(BlockTraits::child_begin(node->getEntry())) {
+      assert(!Node->isSubRegion()
+             && "Subregion node not allowed in flat iterating mode!");
+      assert(Node->getParent() && "A BB node must have a parent!");
+
+      // Skip the exit block of the iterating region.
+      while (BlockTraits::child_end(Node->getEntry()) != Itor
+          && Node->getParent()->getExit() == *Itor)
+        ++Itor;
+  }
+
+  /// @brief Create an end iterator
+  inline RNSuccIterator(NodeType* node, bool) :
+    Node(node),
+    Itor(BlockTraits::child_end(node->getEntry())) {
+      assert(!Node->isSubRegion()
+             && "Subregion node not allowed in flat iterating mode!");
+  }
+
+  inline bool operator==(const Self& x) const {
+    assert(Node->getParent() == x.Node->getParent()
+           && "Cannot compare iterators of different regions!");
+
+    return Itor == x.Itor && Node == x.Node;
+  }
+
+  inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+  inline pointer operator*() const {
+    BlockT *BB = *Itor;
+
+    // Get the iterating region.
+    RegionT *Parent = Node->getParent();
+
+    // The only case that the successor reaches out of the region is it reaches
+    // the exit of the region.
+    assert(Parent->getExit() != BB && "iterator out of range!");
+
+    return Parent->getBBNode(BB);
+  }
+
+  inline Self& operator++() {
+    // Skip the exit block of the iterating region.
+    do
+      ++Itor;
+    while (Itor != succ_end(Node->getEntry())
+        && Node->getParent()->getExit() == *Itor);
+
+    return *this;
+  }
+
+  inline Self operator++(int) {
+    Self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  inline const Self &operator=(const Self &I) {
+    if (this != &I) {
+      assert(Node->getParent() == I.Node->getParent()
+             && "Cannot assign iterators to two different regions!");
+      Node = I.Node;
+      Itor = I.Itor;
+    }
+    return *this;
+  }
+};
+
+template<class NodeType, class BlockT, class RegionT>
+inline RNSuccIterator<NodeType, BlockT, RegionT> succ_begin(NodeType* Node) {
+  return RNSuccIterator<NodeType, BlockT, RegionT>(Node);
+}
+
+template<class NodeType, class BlockT, class RegionT>
+inline RNSuccIterator<NodeType, BlockT, RegionT> succ_end(NodeType* Node) {
+  return RNSuccIterator<NodeType, BlockT, RegionT>(Node, true);
+}
+
+//===--------------------------------------------------------------------===//
+// RegionNode GraphTraits specialization so the bbs in the region can be
+// iterate by generic graph iterators.
+//
+// NodeT can either be region node or const region node, otherwise child_begin
+// and child_end fail.
+
+#define RegionNodeGraphTraits(NodeT, BlockT, RegionT)   \
+  template<> struct GraphTraits<NodeT*> {      \
+  typedef NodeT NodeType; \
+  typedef RNSuccIterator<NodeType, BlockT, RegionT> ChildIteratorType;  \
+  static NodeType *getEntryNode(NodeType* N) { return N; } \
+  static inline ChildIteratorType child_begin(NodeType *N) { \
+    return RNSuccIterator<NodeType, BlockT, RegionT>(N);             \
+  } \
+  static inline ChildIteratorType child_end(NodeType *N) { \
+    return RNSuccIterator<NodeType, BlockT, RegionT>(N, true);     \
+  } \
+}; \
+template<> struct GraphTraits<FlatIt<NodeT*>> {  \
+  typedef NodeT NodeType; \
+  typedef RNSuccIterator<FlatIt<NodeT>, BlockT, RegionT > ChildIteratorType;    \
+  static NodeType *getEntryNode(NodeType* N) { return N; } \
+  static inline ChildIteratorType child_begin(NodeType *N) { \
+    return RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>(N); \
+  } \
+  static inline ChildIteratorType child_end(NodeType *N) { \
+    return RNSuccIterator<FlatIt<NodeType>, BlockT, RegionT>(N, true); \
+  } \
+}
+
+#define RegionGraphTraits(RegionT, NodeT) \
+template<> struct GraphTraits<RegionT*> \
+  : public GraphTraits<NodeT*> { \
+  typedef df_iterator<NodeType*> nodes_iterator; \
+  static NodeType *getEntryNode(RegionT* R) { \
+    return R->getNode(R->getEntry()); \
+  } \
+  static nodes_iterator nodes_begin(RegionT* R) { \
+    return nodes_iterator::begin(getEntryNode(R)); \
+  } \
+  static nodes_iterator nodes_end(RegionT* R) { \
+    return nodes_iterator::end(getEntryNode(R)); \
+  } \
+}; \
+template<> struct GraphTraits<FlatIt<RegionT*> > \
+  : public GraphTraits<FlatIt<NodeT*> > { \
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, \
+  GraphTraits<FlatIt<NodeType*> > > nodes_iterator; \
+  static NodeType *getEntryNode(RegionT* R) { \
+    return R->getBBNode(R->getEntry()); \
+  } \
+  static nodes_iterator nodes_begin(RegionT* R) { \
+    return nodes_iterator::begin(getEntryNode(R)); \
+  } \
+  static nodes_iterator nodes_end(RegionT* R) { \
+    return nodes_iterator::end(getEntryNode(R)); \
+  } \
+}
+
+RegionNodeGraphTraits(RegionNode, BasicBlock, Region);
+RegionNodeGraphTraits(const RegionNode, BasicBlock, Region);
+
+RegionGraphTraits(Region, RegionNode);
+RegionGraphTraits(const Region, const RegionNode);
+
+template <> struct GraphTraits<RegionInfo*>
+  : public GraphTraits<FlatIt<RegionNode*> > {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(RegionInfo *RI) {
+    return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion());
+  }
+  static nodes_iterator nodes_begin(RegionInfo* RI) {
+    return nodes_iterator::begin(getEntryNode(RI));
+  }
+  static nodes_iterator nodes_end(RegionInfo *RI) {
+    return nodes_iterator::end(getEntryNode(RI));
+  }
+};
+
+template <> struct GraphTraits<RegionInfoPass*>
+  : public GraphTraits<RegionInfo *> {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(RegionInfoPass *RI) {
+    return GraphTraits<RegionInfo*>::getEntryNode(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_begin(RegionInfoPass* RI) {
+    return GraphTraits<RegionInfo*>::nodes_begin(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_end(RegionInfoPass *RI) {
+    return GraphTraits<RegionInfo*>::nodes_end(&RI->getRegionInfo());
+  }
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h
new file mode 100644
index 0000000..bd51c49
--- /dev/null
+++ b/include/llvm/Analysis/RegionPass.h
@@ -0,0 +1,128 @@
+//===- RegionPass.h - RegionPass class --------------------------*- 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 RegionPass class. All region based analysis,
+// optimization and transformation passes are derived from RegionPass.
+// This class is implemented following the some ideas of the LoopPass.h class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONPASS_H
+#define LLVM_ANALYSIS_REGIONPASS_H
+
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LegacyPassManagers.h"
+#include "llvm/Pass.h"
+#include <deque>
+
+namespace llvm {
+
+class RGPassManager;
+class Function;
+
+//===----------------------------------------------------------------------===//
+/// @brief A pass that runs on each Region in a function.
+///
+/// RegionPass is managed by RGPassManager.
+class RegionPass : public Pass {
+public:
+  explicit RegionPass(char &pid) : Pass(PT_Region, pid) {}
+
+  //===--------------------------------------------------------------------===//
+  /// @name To be implemented by every RegionPass
+  ///
+  //@{
+  /// @brief Run the pass on a specific Region
+  ///
+  /// Accessing regions not contained in the current region is not allowed.
+  ///
+  /// @param R The region this pass is run on.
+  /// @param RGM The RegionPassManager that manages this Pass.
+  ///
+  /// @return True if the pass modifies this Region.
+  virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0;
+
+  /// @brief Get a pass to print the LLVM IR in the region.
+  ///
+  /// @param O      The output stream to print the Region.
+  /// @param Banner The banner to separate different printed passes.
+  ///
+  /// @return The pass to print the LLVM IR in the region.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  using llvm::Pass::doInitialization;
+  using llvm::Pass::doFinalization;
+
+  virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
+  virtual bool doFinalization() { return false; }
+  //@}
+
+  //===--------------------------------------------------------------------===//
+  /// @name PassManager API
+  ///
+  //@{
+  void preparePassManager(PMStack &PMS) override;
+
+  void assignPassManager(PMStack &PMS,
+                         PassManagerType PMT = PMT_RegionPassManager) override;
+
+  PassManagerType getPotentialPassManagerType() const override {
+    return PMT_RegionPassManager;
+  }
+  //@}
+};
+
+/// @brief The pass manager to schedule RegionPasses.
+class RGPassManager : public FunctionPass, public PMDataManager {
+  std::deque<Region*> RQ;
+  bool skipThisRegion;
+  bool redoThisRegion;
+  RegionInfo *RI;
+  Region *CurrentRegion;
+
+public:
+  static char ID;
+  explicit RGPassManager();
+
+  /// @brief Execute all of the passes scheduled for execution.
+  ///
+  /// @return True if any of the passes modifies the function.
+  bool runOnFunction(Function &F) override;
+
+  /// Pass Manager itself does not invalidate any analysis info.
+  /// RGPassManager needs RegionInfo.
+  void getAnalysisUsage(AnalysisUsage &Info) const override;
+
+  const char *getPassName() const override {
+    return "Region Pass Manager";
+  }
+
+  PMDataManager *getAsPMDataManager() override { return this; }
+  Pass *getAsPass() override { return this; }
+
+  /// @brief Print passes managed by this manager.
+  void dumpPassStructure(unsigned Offset) override;
+
+  /// @brief Get passes contained by this manager.
+  Pass *getContainedPass(unsigned N) {
+    assert(N < PassVector.size() && "Pass number out of range!");
+    Pass *FP = static_cast<Pass *>(PassVector[N]);
+    return FP;
+  }
+
+  PassManagerType getPassManagerType() const override {
+    return PMT_RegionPassManager;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/RegionPrinter.h b/include/llvm/Analysis/RegionPrinter.h
new file mode 100644
index 0000000..758748a
--- /dev/null
+++ b/include/llvm/Analysis/RegionPrinter.h
@@ -0,0 +1,26 @@
+//===-- RegionPrinter.h - Region printer external interface -----*- 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 external functions that can be called to explicitly
+// instantiate the region printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONPRINTER_H
+#define LLVM_ANALYSIS_REGIONPRINTER_H
+
+namespace llvm {
+  class FunctionPass;
+  FunctionPass *createRegionViewerPass();
+  FunctionPass *createRegionOnlyViewerPass();
+  FunctionPass *createRegionPrinterPass();
+  FunctionPass *createRegionOnlyPrinterPass();
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
new file mode 100644
index 0000000..617e545
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -0,0 +1,942 @@
+//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ScalarEvolution class is an LLVM pass which can be used to analyze and
+// categorize scalar expressions in loops.  It specializes in recognizing
+// general induction variables, representing them with the abstract and opaque
+// SCEV class.  Given this analysis, trip counts of loops and other important
+// properties can be obtained.
+//
+// This analysis is primarily useful for induction variable substitution and
+// strength reduction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_H
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/IR/ConstantRange.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+#include <map>
+
+namespace llvm {
+  class APInt;
+  class Constant;
+  class ConstantInt;
+  class DominatorTree;
+  class Type;
+  class ScalarEvolution;
+  class DataLayout;
+  class TargetLibraryInfo;
+  class LLVMContext;
+  class Loop;
+  class LoopInfo;
+  class Operator;
+  class SCEVUnknown;
+  class SCEV;
+  template<> struct FoldingSetTrait<SCEV>;
+
+  /// SCEV - This class represents an analyzed expression in the program.  These
+  /// are opaque objects that the client is not allowed to do much with
+  /// directly.
+  ///
+  class SCEV : public FoldingSetNode {
+    friend struct FoldingSetTrait<SCEV>;
+
+    /// FastID - A reference to an Interned FoldingSetNodeID for this node.
+    /// The ScalarEvolution's BumpPtrAllocator holds the data.
+    FoldingSetNodeIDRef FastID;
+
+    // The SCEV baseclass this node corresponds to
+    const unsigned short SCEVType;
+
+  protected:
+    /// SubclassData - This field is initialized to zero and may be used in
+    /// subclasses to store miscellaneous information.
+    unsigned short SubclassData;
+
+  private:
+    SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
+    void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
+
+  public:
+    /// NoWrapFlags are bitfield indices into SubclassData.
+    ///
+    /// Add and Mul expressions may have no-unsigned-wrap <NUW> or
+    /// no-signed-wrap <NSW> properties, which are derived from the IR
+    /// operator. NSW is a misnomer that we use to mean no signed overflow or
+    /// underflow.
+    ///
+    /// AddRec expression may have a no-self-wraparound <NW> property if the
+    /// result can never reach the start value. This property is independent of
+    /// the actual start value and step direction. Self-wraparound is defined
+    /// purely in terms of the recurrence's loop, step size, and
+    /// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
+    /// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
+    ///
+    /// Note that NUW and NSW are also valid properties of a recurrence, and
+    /// either implies NW. For convenience, NW will be set for a recurrence
+    /// whenever either NUW or NSW are set.
+    enum NoWrapFlags { FlagAnyWrap = 0,          // No guarantee.
+                       FlagNW      = (1 << 0),   // No self-wrap.
+                       FlagNUW     = (1 << 1),   // No unsigned wrap.
+                       FlagNSW     = (1 << 2),   // No signed wrap.
+                       NoWrapMask  = (1 << 3) -1 };
+
+    explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
+      FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
+
+    unsigned getSCEVType() const { return SCEVType; }
+
+    /// getType - Return the LLVM type of this SCEV expression.
+    ///
+    Type *getType() const;
+
+    /// isZero - Return true if the expression is a constant zero.
+    ///
+    bool isZero() const;
+
+    /// isOne - Return true if the expression is a constant one.
+    ///
+    bool isOne() const;
+
+    /// isAllOnesValue - Return true if the expression is a constant
+    /// all-ones value.
+    ///
+    bool isAllOnesValue() const;
+
+    /// isNonConstantNegative - Return true if the specified scev is negated,
+    /// but not a constant.
+    bool isNonConstantNegative() const;
+
+    /// print - Print out the internal representation of this scalar to the
+    /// specified stream.  This should really only be used for debugging
+    /// purposes.
+    void print(raw_ostream &OS) const;
+
+    /// dump - This method is used for debugging.
+    ///
+    void dump() const;
+  };
+
+  // Specialize FoldingSetTrait for SCEV to avoid needing to compute
+  // temporary FoldingSetNodeID values.
+  template<> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> {
+    static void Profile(const SCEV &X, FoldingSetNodeID& ID) {
+      ID = X.FastID;
+    }
+    static bool Equals(const SCEV &X, const FoldingSetNodeID &ID,
+                       unsigned IDHash, FoldingSetNodeID &TempID) {
+      return ID == X.FastID;
+    }
+    static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
+      return X.FastID.ComputeHash();
+    }
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) {
+    S.print(OS);
+    return OS;
+  }
+
+  /// SCEVCouldNotCompute - An object of this class is returned by queries that
+  /// could not be answered.  For example, if you ask for the number of
+  /// iterations of a linked-list traversal loop, you will get one of these.
+  /// None of the standard SCEV operations are valid on this class, it is just a
+  /// marker.
+  struct SCEVCouldNotCompute : public SCEV {
+    SCEVCouldNotCompute();
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static bool classof(const SCEV *S);
+  };
+
+  /// ScalarEvolution - This class is the main scalar evolution driver.  Because
+  /// client code (intentionally) can't do much with the SCEV objects directly,
+  /// they must ask this class for services.
+  ///
+  class ScalarEvolution : public FunctionPass {
+  public:
+    /// LoopDisposition - An enum describing the relationship between a
+    /// SCEV and a loop.
+    enum LoopDisposition {
+      LoopVariant,    ///< The SCEV is loop-variant (unknown).
+      LoopInvariant,  ///< The SCEV is loop-invariant.
+      LoopComputable  ///< The SCEV varies predictably with the loop.
+    };
+
+    /// BlockDisposition - An enum describing the relationship between a
+    /// SCEV and a basic block.
+    enum BlockDisposition {
+      DoesNotDominateBlock,  ///< The SCEV does not dominate the block.
+      DominatesBlock,        ///< The SCEV dominates the block.
+      ProperlyDominatesBlock ///< The SCEV properly dominates the block.
+    };
+
+    /// Convenient NoWrapFlags manipulation that hides enum casts and is
+    /// visible in the ScalarEvolution name space.
+    static SCEV::NoWrapFlags LLVM_ATTRIBUTE_UNUSED_RESULT
+    maskFlags(SCEV::NoWrapFlags Flags, int Mask) {
+      return (SCEV::NoWrapFlags)(Flags & Mask);
+    }
+    static SCEV::NoWrapFlags LLVM_ATTRIBUTE_UNUSED_RESULT
+    setFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags OnFlags) {
+      return (SCEV::NoWrapFlags)(Flags | OnFlags);
+    }
+    static SCEV::NoWrapFlags LLVM_ATTRIBUTE_UNUSED_RESULT
+    clearFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags OffFlags) {
+      return (SCEV::NoWrapFlags)(Flags & ~OffFlags);
+    }
+
+  private:
+    /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
+    /// notified whenever a Value is deleted.
+    class SCEVCallbackVH : public CallbackVH {
+      ScalarEvolution *SE;
+      void deleted() override;
+      void allUsesReplacedWith(Value *New) override;
+    public:
+      SCEVCallbackVH(Value *V, ScalarEvolution *SE = nullptr);
+    };
+
+    friend class SCEVCallbackVH;
+    friend class SCEVExpander;
+    friend class SCEVUnknown;
+
+    /// F - The function we are analyzing.
+    ///
+    Function *F;
+
+    /// LI - The loop information for the function we are currently analyzing.
+    ///
+    LoopInfo *LI;
+
+    /// The DataLayout information for the target we are targeting.
+    ///
+    const DataLayout *DL;
+
+    /// TLI - The target library information for the target we are targeting.
+    ///
+    TargetLibraryInfo *TLI;
+
+    /// DT - The dominator tree.
+    ///
+    DominatorTree *DT;
+
+    /// CouldNotCompute - This SCEV is used to represent unknown trip
+    /// counts and things.
+    SCEVCouldNotCompute CouldNotCompute;
+
+    /// ValueExprMapType - The typedef for ValueExprMap.
+    ///
+    typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *> >
+      ValueExprMapType;
+
+    /// ValueExprMap - This is a cache of the values we have analyzed so far.
+    ///
+    ValueExprMapType ValueExprMap;
+
+    /// Mark predicate values currently being processed by isImpliedCond.
+    DenseSet<Value*> PendingLoopPredicates;
+
+    /// ExitLimit - Information about the number of loop iterations for which a
+    /// loop exit's branch condition evaluates to the not-taken path.  This is a
+    /// temporary pair of exact and max expressions that are eventually
+    /// summarized in ExitNotTakenInfo and BackedgeTakenInfo.
+    ///
+    /// If MustExit is true, then the exit must be taken when the BECount
+    /// reaches Exact (and before surpassing Max). If MustExit is false, then
+    /// BECount may exceed Exact or Max if the loop exits via another branch. In
+    /// either case, the loop may exit early via another branch.
+    ///
+    /// MustExit is true for most cases. However, an exit guarded by an
+    /// (in)equality on a nonunit stride may be skipped.
+    struct ExitLimit {
+      const SCEV *Exact;
+      const SCEV *Max;
+      bool MustExit;
+
+      /*implicit*/ ExitLimit(const SCEV *E)
+        : Exact(E), Max(E), MustExit(true) {}
+
+      ExitLimit(const SCEV *E, const SCEV *M, bool MustExit)
+        : Exact(E), Max(M), MustExit(MustExit) {}
+
+      /// hasAnyInfo - Test whether this ExitLimit contains any computed
+      /// information, or whether it's all SCEVCouldNotCompute values.
+      bool hasAnyInfo() const {
+        return !isa<SCEVCouldNotCompute>(Exact) ||
+          !isa<SCEVCouldNotCompute>(Max);
+      }
+    };
+
+    /// ExitNotTakenInfo - Information about the number of times a particular
+    /// loop exit may be reached before exiting the loop.
+    struct ExitNotTakenInfo {
+      AssertingVH<BasicBlock> ExitingBlock;
+      const SCEV *ExactNotTaken;
+      PointerIntPair<ExitNotTakenInfo*, 1> NextExit;
+
+      ExitNotTakenInfo() : ExitingBlock(nullptr), ExactNotTaken(nullptr) {}
+
+      /// isCompleteList - Return true if all loop exits are computable.
+      bool isCompleteList() const {
+        return NextExit.getInt() == 0;
+      }
+
+      void setIncomplete() { NextExit.setInt(1); }
+
+      /// getNextExit - Return a pointer to the next exit's not-taken info.
+      ExitNotTakenInfo *getNextExit() const {
+        return NextExit.getPointer();
+      }
+
+      void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); }
+    };
+
+    /// BackedgeTakenInfo - Information about the backedge-taken count
+    /// of a loop. This currently includes an exact count and a maximum count.
+    ///
+    class BackedgeTakenInfo {
+      /// ExitNotTaken - A list of computable exits and their not-taken counts.
+      /// Loops almost never have more than one computable exit.
+      ExitNotTakenInfo ExitNotTaken;
+
+      /// Max - An expression indicating the least maximum backedge-taken
+      /// count of the loop that is known, or a SCEVCouldNotCompute.
+      const SCEV *Max;
+
+    public:
+      BackedgeTakenInfo() : Max(nullptr) {}
+
+      /// Initialize BackedgeTakenInfo from a list of exact exit counts.
+      BackedgeTakenInfo(
+        SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts,
+        bool Complete, const SCEV *MaxCount);
+
+      /// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
+      /// computed information, or whether it's all SCEVCouldNotCompute
+      /// values.
+      bool hasAnyInfo() const {
+        return ExitNotTaken.ExitingBlock || !isa<SCEVCouldNotCompute>(Max);
+      }
+
+      /// getExact - Return an expression indicating the exact backedge-taken
+      /// count of the loop if it is known, or SCEVCouldNotCompute
+      /// otherwise. This is the number of times the loop header can be
+      /// guaranteed to execute, minus one.
+      const SCEV *getExact(ScalarEvolution *SE) const;
+
+      /// getExact - Return the number of times this loop exit may fall through
+      /// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not
+      /// to exit via this block before this number of iterations, but may exit
+      /// via another block.
+      const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const;
+
+      /// getMax - Get the max backedge taken count for the loop.
+      const SCEV *getMax(ScalarEvolution *SE) const;
+
+      /// Return true if any backedge taken count expressions refer to the given
+      /// subexpression.
+      bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
+
+      /// clear - Invalidate this result and free associated memory.
+      void clear();
+    };
+
+    /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for
+    /// this function as they are computed.
+    DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts;
+
+    /// ConstantEvolutionLoopExitValue - This map contains entries for all of
+    /// the PHI instructions that we attempt to compute constant evolutions for.
+    /// This allows us to avoid potentially expensive recomputation of these
+    /// properties.  An instruction maps to null if we are unable to compute its
+    /// exit value.
+    DenseMap<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
+
+    /// ValuesAtScopes - This map contains entries for all the expressions
+    /// that we attempt to compute getSCEVAtScope information for, which can
+    /// be expensive in extreme cases.
+    DenseMap<const SCEV *,
+             SmallVector<std::pair<const Loop *, const SCEV *>, 2> > ValuesAtScopes;
+
+    /// LoopDispositions - Memoized computeLoopDisposition results.
+    DenseMap<const SCEV *,
+             SmallVector<std::pair<const Loop *, LoopDisposition>, 2> > LoopDispositions;
+
+    /// computeLoopDisposition - Compute a LoopDisposition value.
+    LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);
+
+    /// BlockDispositions - Memoized computeBlockDisposition results.
+    DenseMap<const SCEV *,
+             SmallVector<std::pair<const BasicBlock *, BlockDisposition>, 2> > BlockDispositions;
+
+    /// computeBlockDisposition - Compute a BlockDisposition value.
+    BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+    /// UnsignedRanges - Memoized results from getUnsignedRange
+    DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
+
+    /// SignedRanges - Memoized results from getSignedRange
+    DenseMap<const SCEV *, ConstantRange> SignedRanges;
+
+    /// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
+    const ConstantRange &setUnsignedRange(const SCEV *S,
+                                          const ConstantRange &CR) {
+      std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+        UnsignedRanges.insert(std::make_pair(S, CR));
+      if (!Pair.second)
+        Pair.first->second = CR;
+      return Pair.first->second;
+    }
+
+    /// setUnsignedRange - Set the memoized signed range for the given SCEV.
+    const ConstantRange &setSignedRange(const SCEV *S,
+                                        const ConstantRange &CR) {
+      std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+        SignedRanges.insert(std::make_pair(S, CR));
+      if (!Pair.second)
+        Pair.first->second = CR;
+      return Pair.first->second;
+    }
+
+    /// createSCEV - We know that there is no SCEV for the specified value.
+    /// Analyze the expression.
+    const SCEV *createSCEV(Value *V);
+
+    /// createNodeForPHI - Provide the special handling we need to analyze PHI
+    /// SCEVs.
+    const SCEV *createNodeForPHI(PHINode *PN);
+
+    /// createNodeForGEP - Provide the special handling we need to analyze GEP
+    /// SCEVs.
+    const SCEV *createNodeForGEP(GEPOperator *GEP);
+
+    /// computeSCEVAtScope - Implementation code for getSCEVAtScope; called
+    /// at most once for each SCEV+Loop pair.
+    ///
+    const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L);
+
+    /// ForgetSymbolicValue - This looks up computed SCEV values for all
+    /// instructions that depend on the given instruction and removes them from
+    /// the ValueExprMap map if they reference SymName. This is used during PHI
+    /// resolution.
+    void ForgetSymbolicName(Instruction *I, const SCEV *SymName);
+
+    /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
+    /// loop, lazily computing new values if the loop hasn't been analyzed
+    /// yet.
+    const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
+
+    /// ComputeBackedgeTakenCount - Compute the number of times the specified
+    /// loop will iterate.
+    BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
+
+    /// ComputeExitLimit - Compute the number of times the backedge of the
+    /// specified loop will execute if it exits via the specified block.
+    ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock);
+
+    /// ComputeExitLimitFromCond - Compute the number of times the backedge of
+    /// the specified loop will execute if its exit condition were a conditional
+    /// branch of ExitCond, TBB, and FBB.
+    ExitLimit ComputeExitLimitFromCond(const Loop *L,
+                                       Value *ExitCond,
+                                       BasicBlock *TBB,
+                                       BasicBlock *FBB,
+                                       bool IsSubExpr);
+
+    /// ComputeExitLimitFromICmp - Compute the number of times the backedge of
+    /// the specified loop will execute if its exit condition were a conditional
+    /// branch of the ICmpInst ExitCond, TBB, and FBB.
+    ExitLimit ComputeExitLimitFromICmp(const Loop *L,
+                                       ICmpInst *ExitCond,
+                                       BasicBlock *TBB,
+                                       BasicBlock *FBB,
+                                       bool IsSubExpr);
+
+    /// ComputeExitLimitFromSingleExitSwitch - Compute the number of times the
+    /// backedge of the specified loop will execute if its exit condition were a
+    /// switch with a single exiting case to ExitingBB.
+    ExitLimit
+    ComputeExitLimitFromSingleExitSwitch(const Loop *L, SwitchInst *Switch,
+                               BasicBlock *ExitingBB, bool IsSubExpr);
+
+    /// ComputeLoadConstantCompareExitLimit - Given an exit condition
+    /// of 'icmp op load X, cst', try to see if we can compute the
+    /// backedge-taken count.
+    ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI,
+                                                  Constant *RHS,
+                                                  const Loop *L,
+                                                  ICmpInst::Predicate p);
+
+    /// ComputeExitCountExhaustively - If the loop is known to execute a
+    /// constant number of times (the condition evolves only from constants),
+    /// try to evaluate a few iterations of the loop until we get the exit
+    /// condition gets a value of ExitWhen (true or false).  If we cannot
+    /// evaluate the exit count of the loop, return CouldNotCompute.
+    const SCEV *ComputeExitCountExhaustively(const Loop *L,
+                                             Value *Cond,
+                                             bool ExitWhen);
+
+    /// HowFarToZero - Return the number of times an exit condition comparing
+    /// the specified value to zero will execute.  If not computable, return
+    /// CouldNotCompute.
+    ExitLimit HowFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr);
+
+    /// HowFarToNonZero - Return the number of times an exit condition checking
+    /// the specified value for nonzero will execute.  If not computable, return
+    /// CouldNotCompute.
+    ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L);
+
+    /// HowManyLessThans - Return the number of times an exit condition
+    /// containing the specified less-than comparison will execute.  If not
+    /// computable, return CouldNotCompute. isSigned specifies whether the
+    /// less-than is signed.
+    ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
+                               const Loop *L, bool isSigned, bool IsSubExpr);
+    ExitLimit HowManyGreaterThans(const SCEV *LHS, const SCEV *RHS,
+                                  const Loop *L, bool isSigned, bool IsSubExpr);
+
+    /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB
+    /// (which may not be an immediate predecessor) which has exactly one
+    /// successor from which BB is reachable, or null if no such block is
+    /// found.
+    std::pair<BasicBlock *, BasicBlock *>
+    getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
+
+    /// isImpliedCond - Test whether the condition described by Pred, LHS, and
+    /// RHS is true whenever the given FoundCondValue value evaluates to true.
+    bool isImpliedCond(ICmpInst::Predicate Pred,
+                       const SCEV *LHS, const SCEV *RHS,
+                       Value *FoundCondValue,
+                       bool Inverse);
+
+    /// isImpliedCondOperands - Test whether the condition described by Pred,
+    /// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
+    /// and FoundRHS is true.
+    bool isImpliedCondOperands(ICmpInst::Predicate Pred,
+                               const SCEV *LHS, const SCEV *RHS,
+                               const SCEV *FoundLHS, const SCEV *FoundRHS);
+
+    /// isImpliedCondOperandsHelper - Test whether the condition described by
+    /// Pred, LHS, and RHS is true whenever the condition described by Pred,
+    /// FoundLHS, and FoundRHS is true.
+    bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
+                                     const SCEV *LHS, const SCEV *RHS,
+                                     const SCEV *FoundLHS,
+                                     const SCEV *FoundRHS);
+
+    /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
+    /// in the header of its containing loop, we know the loop executes a
+    /// constant number of times, and the PHI node is just a recurrence
+    /// involving constants, fold it.
+    Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
+                                                const Loop *L);
+
+    /// isKnownPredicateWithRanges - Test if the given expression is known to
+    /// satisfy the condition described by Pred and the known constant ranges
+    /// of LHS and RHS.
+    ///
+    bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
+                                    const SCEV *LHS, const SCEV *RHS);
+
+    /// forgetMemoizedResults - Drop memoized information computed for S.
+    void forgetMemoizedResults(const SCEV *S);
+
+    /// Return false iff given SCEV contains a SCEVUnknown with NULL value-
+    /// pointer.
+    bool checkValidity(const SCEV *S) const;
+
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    ScalarEvolution();
+
+    LLVMContext &getContext() const { return F->getContext(); }
+
+    /// isSCEVable - Test if values of the given type are analyzable within
+    /// the SCEV framework. This primarily includes integer types, and it
+    /// can optionally include pointer types if the ScalarEvolution class
+    /// has access to target-specific information.
+    bool isSCEVable(Type *Ty) const;
+
+    /// getTypeSizeInBits - Return the size in bits of the specified type,
+    /// for which isSCEVable must return true.
+    uint64_t getTypeSizeInBits(Type *Ty) const;
+
+    /// getEffectiveSCEVType - Return a type with the same bitwidth as
+    /// the given type and which represents how SCEV will treat the given
+    /// type, for which isSCEVable must return true. For pointer types,
+    /// this is the pointer-sized integer type.
+    Type *getEffectiveSCEVType(Type *Ty) const;
+
+    /// getSCEV - Return a SCEV expression for the full generality of the
+    /// specified expression.
+    const SCEV *getSCEV(Value *V);
+
+    const SCEV *getConstant(ConstantInt *V);
+    const SCEV *getConstant(const APInt& Val);
+    const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
+    const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
+    const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
+    const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
+    const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
+    const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+    const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+      SmallVector<const SCEV *, 2> Ops;
+      Ops.push_back(LHS);
+      Ops.push_back(RHS);
+      return getAddExpr(Ops, Flags);
+    }
+    const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+      SmallVector<const SCEV *, 3> Ops;
+      Ops.push_back(Op0);
+      Ops.push_back(Op1);
+      Ops.push_back(Op2);
+      return getAddExpr(Ops, Flags);
+    }
+    const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+    const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap)
+    {
+      SmallVector<const SCEV *, 2> Ops;
+      Ops.push_back(LHS);
+      Ops.push_back(RHS);
+      return getMulExpr(Ops, Flags);
+    }
+    const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
+                           SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+      SmallVector<const SCEV *, 3> Ops;
+      Ops.push_back(Op0);
+      Ops.push_back(Op1);
+      Ops.push_back(Op2);
+      return getMulExpr(Ops, Flags);
+    }
+    const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
+                              const Loop *L, SCEV::NoWrapFlags Flags);
+    const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
+                              const Loop *L, SCEV::NoWrapFlags Flags);
+    const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands,
+                              const Loop *L, SCEV::NoWrapFlags Flags) {
+      SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
+      return getAddRecExpr(NewOp, L, Flags);
+    }
+    const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
+    const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
+    const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
+    const SCEV *getUnknown(Value *V);
+    const SCEV *getCouldNotCompute();
+
+    /// getSizeOfExpr - Return an expression for sizeof AllocTy that is type
+    /// IntTy
+    ///
+    const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy);
+
+    /// getOffsetOfExpr - Return an expression for offsetof on the given field
+    /// with type IntTy
+    ///
+    const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo);
+
+    /// getNegativeSCEV - Return the SCEV object corresponding to -V.
+    ///
+    const SCEV *getNegativeSCEV(const SCEV *V);
+
+    /// getNotSCEV - Return the SCEV object corresponding to ~V.
+    ///
+    const SCEV *getNotSCEV(const SCEV *V);
+
+    /// getMinusSCEV - Return LHS-RHS.  Minus is represented in SCEV as A+B*-1.
+    const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
+                             SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+
+    /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
+    /// of the input value to the specified type.  If the type must be
+    /// extended, it is zero extended.
+    const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty);
+
+    /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
+    /// of the input value to the specified type.  If the type must be
+    /// extended, it is sign extended.
+    const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty);
+
+    /// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
+    /// the input value to the specified type.  If the type must be extended,
+    /// it is zero extended.  The conversion must not be narrowing.
+    const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty);
+
+    /// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
+    /// the input value to the specified type.  If the type must be extended,
+    /// it is sign extended.  The conversion must not be narrowing.
+    const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty);
+
+    /// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
+    /// the input value to the specified type. If the type must be extended,
+    /// it is extended with unspecified bits. The conversion must not be
+    /// narrowing.
+    const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty);
+
+    /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
+    /// input value to the specified type.  The conversion must not be
+    /// widening.
+    const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty);
+
+    /// getUMaxFromMismatchedTypes - Promote the operands to the wider of
+    /// the types using zero-extension, and then perform a umax operation
+    /// with them.
+    const SCEV *getUMaxFromMismatchedTypes(const SCEV *LHS,
+                                           const SCEV *RHS);
+
+    /// getUMinFromMismatchedTypes - Promote the operands to the wider of
+    /// the types using zero-extension, and then perform a umin operation
+    /// with them.
+    const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS,
+                                           const SCEV *RHS);
+
+    /// getPointerBase - Transitively follow the chain of pointer-type operands
+    /// until reaching a SCEV that does not have a single pointer operand. This
+    /// returns a SCEVUnknown pointer for well-formed pointer-type expressions,
+    /// but corner cases do exist.
+    const SCEV *getPointerBase(const SCEV *V);
+
+    /// getSCEVAtScope - Return a SCEV expression for the specified value
+    /// at the specified scope in the program.  The L value specifies a loop
+    /// nest to evaluate the expression at, where null is the top-level or a
+    /// specified loop is immediately inside of the loop.
+    ///
+    /// This method can be used to compute the exit value for a variable defined
+    /// in a loop by querying what the value will hold in the parent loop.
+    ///
+    /// In the case that a relevant loop exit value cannot be computed, the
+    /// original value V is returned.
+    const SCEV *getSCEVAtScope(const SCEV *S, const Loop *L);
+
+    /// getSCEVAtScope - This is a convenience function which does
+    /// getSCEVAtScope(getSCEV(V), L).
+    const SCEV *getSCEVAtScope(Value *V, const Loop *L);
+
+    /// isLoopEntryGuardedByCond - Test whether entry to the loop is protected
+    /// by a conditional between LHS and RHS.  This is used to help avoid max
+    /// expressions in loop trip counts, and to eliminate casts.
+    bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
+                                  const SCEV *LHS, const SCEV *RHS);
+
+    /// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is
+    /// protected by a conditional between LHS and RHS.  This is used to
+    /// to eliminate casts.
+    bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
+                                     const SCEV *LHS, const SCEV *RHS);
+
+    /// getSmallConstantTripCount - Returns the maximum trip count of this loop
+    /// as a normal unsigned value. Returns 0 if the trip count is unknown or
+    /// not constant. This "trip count" assumes that control exits via
+    /// ExitingBlock. More precisely, it is the number of times that control may
+    /// reach ExitingBlock before taking the branch. For loops with multiple
+    /// exits, it may not be the number times that the loop header executes if
+    /// the loop exits prematurely via another branch.
+    unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock);
+
+    /// getSmallConstantTripMultiple - Returns the largest constant divisor of
+    /// the trip count of this loop as a normal unsigned value, if
+    /// possible. This means that the actual trip count is always a multiple of
+    /// the returned value (don't forget the trip count could very well be zero
+    /// as well!). As explained in the comments for getSmallConstantTripCount,
+    /// this assumes that control exits the loop via ExitingBlock.
+    unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock);
+
+    // getExitCount - Get the expression for the number of loop iterations for
+    // which this loop is guaranteed not to exit via ExitingBlock. Otherwise
+    // return SCEVCouldNotCompute.
+    const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock);
+
+    /// getBackedgeTakenCount - If the specified loop has a predictable
+    /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute
+    /// object. The backedge-taken count is the number of times the loop header
+    /// will be branched to from within the loop. This is one less than the
+    /// trip count of the loop, since it doesn't count the first iteration,
+    /// when the header is branched to from outside the loop.
+    ///
+    /// Note that it is not valid to call this method on a loop without a
+    /// loop-invariant backedge-taken count (see
+    /// hasLoopInvariantBackedgeTakenCount).
+    ///
+    const SCEV *getBackedgeTakenCount(const Loop *L);
+
+    /// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except
+    /// return the least SCEV value that is known never to be less than the
+    /// actual backedge taken count.
+    const SCEV *getMaxBackedgeTakenCount(const Loop *L);
+
+    /// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop
+    /// has an analyzable loop-invariant backedge-taken count.
+    bool hasLoopInvariantBackedgeTakenCount(const Loop *L);
+
+    /// forgetLoop - This method should be called by the client when it has
+    /// changed a loop in a way that may effect ScalarEvolution's ability to
+    /// compute a trip count, or if the loop is deleted.  This call is
+    /// potentially expensive for large loop bodies.
+    void forgetLoop(const Loop *L);
+
+    /// forgetValue - This method should be called by the client when it has
+    /// changed a value in a way that may effect its value, or which may
+    /// disconnect it from a def-use chain linking it to a loop.
+    void forgetValue(Value *V);
+
+    /// \brief Called when the client has changed the disposition of values in
+    /// this loop.
+    ///
+    /// We don't have a way to invalidate per-loop dispositions. Clear and
+    /// recompute is simpler.
+    void forgetLoopDispositions(const Loop *L) { LoopDispositions.clear(); }
+
+    /// GetMinTrailingZeros - Determine the minimum number of zero bits that S
+    /// is guaranteed to end in (at every loop iteration).  It is, at the same
+    /// time, the minimum number of times S is divisible by 2.  For example,
+    /// given {4,+,8} it returns 2.  If S is guaranteed to be 0, it returns the
+    /// bitwidth of S.
+    uint32_t GetMinTrailingZeros(const SCEV *S);
+
+    /// getUnsignedRange - Determine the unsigned range for a particular SCEV.
+    ///
+    ConstantRange getUnsignedRange(const SCEV *S);
+
+    /// getSignedRange - Determine the signed range for a particular SCEV.
+    ///
+    ConstantRange getSignedRange(const SCEV *S);
+
+    /// isKnownNegative - Test if the given expression is known to be negative.
+    ///
+    bool isKnownNegative(const SCEV *S);
+
+    /// isKnownPositive - Test if the given expression is known to be positive.
+    ///
+    bool isKnownPositive(const SCEV *S);
+
+    /// isKnownNonNegative - Test if the given expression is known to be
+    /// non-negative.
+    ///
+    bool isKnownNonNegative(const SCEV *S);
+
+    /// isKnownNonPositive - Test if the given expression is known to be
+    /// non-positive.
+    ///
+    bool isKnownNonPositive(const SCEV *S);
+
+    /// isKnownNonZero - Test if the given expression is known to be
+    /// non-zero.
+    ///
+    bool isKnownNonZero(const SCEV *S);
+
+    /// isKnownPredicate - Test if the given expression is known to satisfy
+    /// the condition described by Pred, LHS, and RHS.
+    ///
+    bool isKnownPredicate(ICmpInst::Predicate Pred,
+                          const SCEV *LHS, const SCEV *RHS);
+
+    /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
+    /// predicate Pred. Return true iff any changes were made. If the
+    /// operands are provably equal or unequal, LHS and RHS are set to
+    /// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
+    ///
+    bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
+                              const SCEV *&LHS,
+                              const SCEV *&RHS,
+                              unsigned Depth = 0);
+
+    /// getLoopDisposition - Return the "disposition" of the given SCEV with
+    /// respect to the given loop.
+    LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L);
+
+    /// isLoopInvariant - Return true if the value of the given SCEV is
+    /// unchanging in the specified loop.
+    bool isLoopInvariant(const SCEV *S, const Loop *L);
+
+    /// hasComputableLoopEvolution - Return true if the given SCEV changes value
+    /// in a known way in the specified loop.  This property being true implies
+    /// that the value is variant in the loop AND that we can emit an expression
+    /// to compute the value of the expression at any particular loop iteration.
+    bool hasComputableLoopEvolution(const SCEV *S, const Loop *L);
+
+    /// getLoopDisposition - Return the "disposition" of the given SCEV with
+    /// respect to the given block.
+    BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+    /// dominates - Return true if elements that makes up the given SCEV
+    /// dominate the specified basic block.
+    bool dominates(const SCEV *S, const BasicBlock *BB);
+
+    /// properlyDominates - Return true if elements that makes up the given SCEV
+    /// properly dominate the specified basic block.
+    bool properlyDominates(const SCEV *S, const BasicBlock *BB);
+
+    /// hasOperand - Test whether the given SCEV has Op as a direct or
+    /// indirect operand.
+    bool hasOperand(const SCEV *S, const SCEV *Op) const;
+
+    /// Return the size of an element read or written by Inst.
+    const SCEV *getElementSize(Instruction *Inst);
+
+    /// Compute the array dimensions Sizes from the set of Terms extracted from
+    /// the memory access function of this SCEVAddRecExpr.
+    void findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms,
+                             SmallVectorImpl<const SCEV *> &Sizes,
+                             const SCEV *ElementSize) const;
+
+    bool runOnFunction(Function &F) override;
+    void releaseMemory() override;
+    void getAnalysisUsage(AnalysisUsage &AU) const override;
+    void print(raw_ostream &OS, const Module* = nullptr) const override;
+    void verifyAnalysis() const override;
+
+  private:
+    /// Compute the backedge taken count knowing the interval difference, the
+    /// stride and presence of the equality in the comparison.
+    const SCEV *computeBECount(const SCEV *Delta, const SCEV *Stride,
+                               bool Equality);
+
+    /// Verify if an linear IV with positive stride can overflow when in a
+    /// less-than comparison, knowing the invariant term of the comparison,
+    /// the stride and the knowledge of NSW/NUW flags on the recurrence.
+    bool doesIVOverflowOnLT(const SCEV *RHS, const SCEV *Stride,
+                            bool IsSigned, bool NoWrap);
+
+    /// Verify if an linear IV with negative stride can overflow when in a
+    /// greater-than comparison, knowing the invariant term of the comparison,
+    /// the stride and the knowledge of NSW/NUW flags on the recurrence.
+    bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride,
+                            bool IsSigned, bool NoWrap);
+
+  private:
+    FoldingSet<SCEV> UniqueSCEVs;
+    BumpPtrAllocator SCEVAllocator;
+
+    /// FirstUnknown - The head of a linked list of all SCEVUnknown
+    /// values that have been allocated. This is used by releaseMemory
+    /// to locate them all and call their destructors.
+    SCEVUnknown *FirstUnknown;
+  };
+}
+
+#endif
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
new file mode 100644
index 0000000..b9bef97
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -0,0 +1,271 @@
+//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- 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 classes used to generate code from scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
+
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/ValueHandle.h"
+#include <set>
+
+namespace llvm {
+  class TargetTransformInfo;
+
+  /// Return true if the given expression is safe to expand in the sense that
+  /// all materialized values are safe to speculate.
+  bool isSafeToExpand(const SCEV *S, ScalarEvolution &SE);
+
+  /// SCEVExpander - This class uses information about analyze scalars to
+  /// rewrite expressions in canonical form.
+  ///
+  /// Clients should create an instance of this class when rewriting is needed,
+  /// and destroy it when finished to allow the release of the associated
+  /// memory.
+  class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
+    ScalarEvolution &SE;
+
+    // New instructions receive a name to identifies them with the current pass.
+    const char* IVName;
+
+    // InsertedExpressions caches Values for reuse, so must track RAUW.
+    std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
+      InsertedExpressions;
+    // InsertedValues only flags inserted instructions so needs no RAUW.
+    std::set<AssertingVH<Value> > InsertedValues;
+    std::set<AssertingVH<Value> > InsertedPostIncValues;
+
+    /// RelevantLoops - A memoization of the "relevant" loop for a given SCEV.
+    DenseMap<const SCEV *, const Loop *> RelevantLoops;
+
+    /// PostIncLoops - Addrecs referring to any of the given loops are expanded
+    /// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
+    /// returns the add instruction that adds one to the phi for {0,+,1}<L>,
+    /// as opposed to a new phi starting at 1. This is only supported in
+    /// non-canonical mode.
+    PostIncLoopSet PostIncLoops;
+
+    /// IVIncInsertPos - When this is non-null, addrecs expanded in the
+    /// loop it indicates should be inserted with increments at
+    /// IVIncInsertPos.
+    const Loop *IVIncInsertLoop;
+
+    /// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop,
+    /// insert the IV increment at this position.
+    Instruction *IVIncInsertPos;
+
+    /// Phis that complete an IV chain. Reuse
+    std::set<AssertingVH<PHINode> > ChainedPhis;
+
+    /// CanonicalMode - When true, expressions are expanded in "canonical"
+    /// form. In particular, addrecs are expanded as arithmetic based on
+    /// a canonical induction variable. When false, expression are expanded
+    /// in a more literal form.
+    bool CanonicalMode;
+
+    /// When invoked from LSR, the expander is in "strength reduction" mode. The
+    /// only difference is that phi's are only reused if they are already in
+    /// "expanded" form.
+    bool LSRMode;
+
+    typedef IRBuilder<true, TargetFolder> BuilderType;
+    BuilderType Builder;
+
+#ifndef NDEBUG
+    const char *DebugType;
+#endif
+
+    friend struct SCEVVisitor<SCEVExpander, Value*>;
+
+  public:
+    /// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
+    explicit SCEVExpander(ScalarEvolution &se, const char *name)
+      : SE(se), IVName(name), IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr),
+        CanonicalMode(true), LSRMode(false),
+        Builder(se.getContext(), TargetFolder(se.DL)) {
+#ifndef NDEBUG
+      DebugType = "";
+#endif
+    }
+
+#ifndef NDEBUG
+    void setDebugType(const char* s) { DebugType = s; }
+#endif
+
+    /// clear - Erase the contents of the InsertedExpressions map so that users
+    /// trying to expand the same expression into multiple BasicBlocks or
+    /// different places within the same BasicBlock can do so.
+    void clear() {
+      InsertedExpressions.clear();
+      InsertedValues.clear();
+      InsertedPostIncValues.clear();
+      ChainedPhis.clear();
+    }
+
+    /// getOrInsertCanonicalInductionVariable - This method returns the
+    /// canonical induction variable of the specified type for the specified
+    /// loop (inserting one if there is none).  A canonical induction variable
+    /// starts at zero and steps by one on each iteration.
+    PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
+
+    /// getIVIncOperand - Return the induction variable increment's IV operand.
+    Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
+                                 bool allowScale);
+
+    /// hoistIVInc - Utility for hoisting an IV increment.
+    bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
+
+    /// replaceCongruentIVs - replace congruent phis with their most canonical
+    /// representative. Return the number of phis eliminated.
+    unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
+                                 SmallVectorImpl<WeakVH> &DeadInsts,
+                                 const TargetTransformInfo *TTI = nullptr);
+
+    /// expandCodeFor - Insert code to directly compute the specified SCEV
+    /// expression into the program.  The inserted code is inserted into the
+    /// specified block.
+    Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
+
+    /// setIVIncInsertPos - Set the current IV increment loop and position.
+    void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
+      assert(!CanonicalMode &&
+             "IV increment positions are not supported in CanonicalMode");
+      IVIncInsertLoop = L;
+      IVIncInsertPos = Pos;
+    }
+
+    /// setPostInc - Enable post-inc expansion for addrecs referring to the
+    /// given loops. Post-inc expansion is only supported in non-canonical
+    /// mode.
+    void setPostInc(const PostIncLoopSet &L) {
+      assert(!CanonicalMode &&
+             "Post-inc expansion is not supported in CanonicalMode");
+      PostIncLoops = L;
+    }
+
+    /// clearPostInc - Disable all post-inc expansion.
+    void clearPostInc() {
+      PostIncLoops.clear();
+
+      // When we change the post-inc loop set, cached expansions may no
+      // longer be valid.
+      InsertedPostIncValues.clear();
+    }
+
+    /// disableCanonicalMode - Disable the behavior of expanding expressions in
+    /// canonical form rather than in a more literal form. Non-canonical mode
+    /// is useful for late optimization passes.
+    void disableCanonicalMode() { CanonicalMode = false; }
+
+    void enableLSRMode() { LSRMode = true; }
+
+    /// clearInsertPoint - Clear the current insertion point. This is useful
+    /// if the instruction that had been serving as the insertion point may
+    /// have been deleted.
+    void clearInsertPoint() {
+      Builder.ClearInsertionPoint();
+    }
+
+    /// isInsertedInstruction - Return true if the specified instruction was
+    /// inserted by the code rewriter.  If so, the client should not modify the
+    /// instruction.
+    bool isInsertedInstruction(Instruction *I) const {
+      return InsertedValues.count(I) || InsertedPostIncValues.count(I);
+    }
+
+    void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
+
+  private:
+    LLVMContext &getContext() const { return SE.getContext(); }
+
+    /// InsertBinop - Insert the specified binary operator, doing a small amount
+    /// of work to avoid inserting an obviously redundant operation.
+    Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
+
+    /// ReuseOrCreateCast - Arange for there to be a cast of V to Ty at IP,
+    /// reusing an existing cast if a suitable one exists, moving an existing
+    /// cast if a suitable one exists but isn't in the right place, or
+    /// or creating a new one.
+    Value *ReuseOrCreateCast(Value *V, Type *Ty,
+                             Instruction::CastOps Op,
+                             BasicBlock::iterator IP);
+
+    /// InsertNoopCastOfTo - Insert a cast of V to the specified type,
+    /// which must be possible with a noop cast, doing what we can to
+    /// share the casts.
+    Value *InsertNoopCastOfTo(Value *V, Type *Ty);
+
+    /// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
+    /// instead of using ptrtoint+arithmetic+inttoptr.
+    Value *expandAddToGEP(const SCEV *const *op_begin,
+                          const SCEV *const *op_end,
+                          PointerType *PTy, Type *Ty, Value *V);
+
+    Value *expand(const SCEV *S);
+
+    /// expandCodeFor - Insert code to directly compute the specified SCEV
+    /// expression into the program.  The inserted code is inserted into the
+    /// SCEVExpander's current insertion point. If a type is specified, the
+    /// result will be expanded to have that type, with a cast if necessary.
+    Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
+
+    /// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
+    const Loop *getRelevantLoop(const SCEV *);
+
+    Value *visitConstant(const SCEVConstant *S) {
+      return S->getValue();
+    }
+
+    Value *visitTruncateExpr(const SCEVTruncateExpr *S);
+
+    Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
+
+    Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
+
+    Value *visitAddExpr(const SCEVAddExpr *S);
+
+    Value *visitMulExpr(const SCEVMulExpr *S);
+
+    Value *visitUDivExpr(const SCEVUDivExpr *S);
+
+    Value *visitAddRecExpr(const SCEVAddRecExpr *S);
+
+    Value *visitSMaxExpr(const SCEVSMaxExpr *S);
+
+    Value *visitUMaxExpr(const SCEVUMaxExpr *S);
+
+    Value *visitUnknown(const SCEVUnknown *S) {
+      return S->getValue();
+    }
+
+    void rememberInstruction(Value *I);
+
+    bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+    bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+    Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
+    PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
+                                       const Loop *L,
+                                       Type *ExpandTy,
+                                       Type *IntTy,
+                                       Type *&TruncTy,
+                                       bool &InvertStep);
+    Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
+                       Type *ExpandTy, Type *IntTy, bool useSubtract);
+  };
+}
+
+#endif
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
new file mode 100644
index 0000000..2f1b1c3
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -0,0 +1,834 @@
+//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- 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 classes used to represent and build scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+  class ConstantInt;
+  class ConstantRange;
+  class DominatorTree;
+
+  enum SCEVTypes {
+    // These should be ordered in terms of increasing complexity to make the
+    // folders simpler.
+    scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
+    scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
+    scUnknown, scCouldNotCompute
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVConstant - This class represents a constant integer value.
+  ///
+  class SCEVConstant : public SCEV {
+    friend class ScalarEvolution;
+
+    ConstantInt *V;
+    SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
+      SCEV(ID, scConstant), V(v) {}
+  public:
+    ConstantInt *getValue() const { return V; }
+
+    Type *getType() const { return V->getType(); }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scConstant;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVCastExpr - This is the base class for unary cast operator classes.
+  ///
+  class SCEVCastExpr : public SCEV {
+  protected:
+    const SCEV *Op;
+    Type *Ty;
+
+    SCEVCastExpr(const FoldingSetNodeIDRef ID,
+                 unsigned SCEVTy, const SCEV *op, Type *ty);
+
+  public:
+    const SCEV *getOperand() const { return Op; }
+    Type *getType() const { return Ty; }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scTruncate ||
+             S->getSCEVType() == scZeroExtend ||
+             S->getSCEVType() == scSignExtend;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVTruncateExpr - This class represents a truncation of an integer value
+  /// to a smaller integer value.
+  ///
+  class SCEVTruncateExpr : public SCEVCastExpr {
+    friend class ScalarEvolution;
+
+    SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
+                     const SCEV *op, Type *ty);
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scTruncate;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVZeroExtendExpr - This class represents a zero extension of a small
+  /// integer value to a larger integer value.
+  ///
+  class SCEVZeroExtendExpr : public SCEVCastExpr {
+    friend class ScalarEvolution;
+
+    SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
+                       const SCEV *op, Type *ty);
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scZeroExtend;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVSignExtendExpr - This class represents a sign extension of a small
+  /// integer value to a larger integer value.
+  ///
+  class SCEVSignExtendExpr : public SCEVCastExpr {
+    friend class ScalarEvolution;
+
+    SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
+                       const SCEV *op, Type *ty);
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scSignExtend;
+    }
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVNAryExpr - This node is a base class providing common
+  /// functionality for n'ary operators.
+  ///
+  class SCEVNAryExpr : public SCEV {
+  protected:
+    // Since SCEVs are immutable, ScalarEvolution allocates operand
+    // arrays with its SCEVAllocator, so this class just needs a simple
+    // pointer rather than a more elaborate vector-like data structure.
+    // This also avoids the need for a non-trivial destructor.
+    const SCEV *const *Operands;
+    size_t NumOperands;
+
+    SCEVNAryExpr(const FoldingSetNodeIDRef ID,
+                 enum SCEVTypes T, const SCEV *const *O, size_t N)
+      : SCEV(ID, T), Operands(O), NumOperands(N) {}
+
+  public:
+    size_t getNumOperands() const { return NumOperands; }
+    const SCEV *getOperand(unsigned i) const {
+      assert(i < NumOperands && "Operand index out of range!");
+      return Operands[i];
+    }
+
+    typedef const SCEV *const *op_iterator;
+    typedef iterator_range<op_iterator> op_range;
+    op_iterator op_begin() const { return Operands; }
+    op_iterator op_end() const { return Operands + NumOperands; }
+    op_range operands() const {
+      return make_range(op_begin(), op_end());
+    }
+
+    Type *getType() const { return getOperand(0)->getType(); }
+
+    NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
+      return (NoWrapFlags)(SubclassData & Mask);
+    }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scAddExpr ||
+             S->getSCEVType() == scMulExpr ||
+             S->getSCEVType() == scSMaxExpr ||
+             S->getSCEVType() == scUMaxExpr ||
+             S->getSCEVType() == scAddRecExpr;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
+  /// operators.
+  ///
+  class SCEVCommutativeExpr : public SCEVNAryExpr {
+  protected:
+    SCEVCommutativeExpr(const FoldingSetNodeIDRef ID,
+                        enum SCEVTypes T, const SCEV *const *O, size_t N)
+      : SCEVNAryExpr(ID, T, O, N) {}
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scAddExpr ||
+             S->getSCEVType() == scMulExpr ||
+             S->getSCEVType() == scSMaxExpr ||
+             S->getSCEVType() == scUMaxExpr;
+    }
+
+    /// Set flags for a non-recurrence without clearing previously set flags.
+    void setNoWrapFlags(NoWrapFlags Flags) {
+      SubclassData |= Flags;
+    }
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
+  ///
+  class SCEVAddExpr : public SCEVCommutativeExpr {
+    friend class ScalarEvolution;
+
+    SCEVAddExpr(const FoldingSetNodeIDRef ID,
+                const SCEV *const *O, size_t N)
+      : SCEVCommutativeExpr(ID, scAddExpr, O, N) {
+    }
+
+  public:
+    Type *getType() const {
+      // Use the type of the last operand, which is likely to be a pointer
+      // type, if there is one. This doesn't usually matter, but it can help
+      // reduce casts when the expressions are expanded.
+      return getOperand(getNumOperands() - 1)->getType();
+    }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scAddExpr;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
+  ///
+  class SCEVMulExpr : public SCEVCommutativeExpr {
+    friend class ScalarEvolution;
+
+    SCEVMulExpr(const FoldingSetNodeIDRef ID,
+                const SCEV *const *O, size_t N)
+      : SCEVCommutativeExpr(ID, scMulExpr, O, N) {
+    }
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scMulExpr;
+    }
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVUDivExpr - This class represents a binary unsigned division operation.
+  ///
+  class SCEVUDivExpr : public SCEV {
+    friend class ScalarEvolution;
+
+    const SCEV *LHS;
+    const SCEV *RHS;
+    SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
+      : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
+
+  public:
+    const SCEV *getLHS() const { return LHS; }
+    const SCEV *getRHS() const { return RHS; }
+
+    Type *getType() const {
+      // In most cases the types of LHS and RHS will be the same, but in some
+      // crazy cases one or the other may be a pointer. ScalarEvolution doesn't
+      // depend on the type for correctness, but handling types carefully can
+      // avoid extra casts in the SCEVExpander. The LHS is more likely to be
+      // a pointer type than the RHS, so use the RHS' type here.
+      return getRHS()->getType();
+    }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scUDivExpr;
+    }
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
+  /// count of the specified loop.  This is the primary focus of the
+  /// ScalarEvolution framework; all the other SCEV subclasses are mostly just
+  /// supporting infrastructure to allow SCEVAddRecExpr expressions to be
+  /// created and analyzed.
+  ///
+  /// All operands of an AddRec are required to be loop invariant.
+  ///
+  class SCEVAddRecExpr : public SCEVNAryExpr {
+    friend class ScalarEvolution;
+
+    const Loop *L;
+
+    SCEVAddRecExpr(const FoldingSetNodeIDRef ID,
+                   const SCEV *const *O, size_t N, const Loop *l)
+      : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {}
+
+  public:
+    const SCEV *getStart() const { return Operands[0]; }
+    const Loop *getLoop() const { return L; }
+
+    /// getStepRecurrence - This method constructs and returns the recurrence
+    /// indicating how much this expression steps by.  If this is a polynomial
+    /// of degree N, it returns a chrec of degree N-1.
+    /// We cannot determine whether the step recurrence has self-wraparound.
+    const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
+      if (isAffine()) return getOperand(1);
+      return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
+                                                           op_end()),
+                              getLoop(), FlagAnyWrap);
+    }
+
+    /// isAffine - Return true if this represents an expression
+    /// A + B*x where A and B are loop invariant values.
+    bool isAffine() const {
+      // We know that the start value is invariant.  This expression is thus
+      // affine iff the step is also invariant.
+      return getNumOperands() == 2;
+    }
+
+    /// isQuadratic - Return true if this represents an expression
+    /// A + B*x + C*x^2 where A, B and C are loop invariant values.
+    /// This corresponds to an addrec of the form {L,+,M,+,N}
+    bool isQuadratic() const {
+      return getNumOperands() == 3;
+    }
+
+    /// Set flags for a recurrence without clearing any previously set flags.
+    /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
+    /// to make it easier to propagate flags.
+    void setNoWrapFlags(NoWrapFlags Flags) {
+      if (Flags & (FlagNUW | FlagNSW))
+        Flags = ScalarEvolution::setFlags(Flags, FlagNW);
+      SubclassData |= Flags;
+    }
+
+    /// evaluateAtIteration - Return the value of this chain of recurrences at
+    /// the specified iteration number.
+    const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
+
+    /// getNumIterationsInRange - Return the number of iterations of this loop
+    /// that produce values in the specified constant range.  Another way of
+    /// looking at this is that it returns the first iteration number where the
+    /// value is not in the condition, thus computing the exit count.  If the
+    /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
+    /// returned.
+    const SCEV *getNumIterationsInRange(ConstantRange Range,
+                                       ScalarEvolution &SE) const;
+
+    /// getPostIncExpr - Return an expression representing the value of
+    /// this expression one iteration of the loop ahead.
+    const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const {
+      return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
+    }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scAddRecExpr;
+    }
+
+    /// Collect parametric terms occurring in step expressions.
+    void collectParametricTerms(ScalarEvolution &SE,
+                                SmallVectorImpl<const SCEV *> &Terms) const;
+
+    /// Return in Subscripts the access functions for each dimension in Sizes.
+    void computeAccessFunctions(ScalarEvolution &SE,
+                                SmallVectorImpl<const SCEV *> &Subscripts,
+                                SmallVectorImpl<const SCEV *> &Sizes) const;
+
+    /// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
+    /// subscripts and sizes of an array access.
+    ///
+    /// The delinearization is a 3 step process: the first two steps compute the
+    /// sizes of each subscript and the third step computes the access functions
+    /// for the delinearized array:
+    ///
+    /// 1. Find the terms in the step functions
+    /// 2. Compute the array size
+    /// 3. Compute the access function: divide the SCEV by the array size
+    ///    starting with the innermost dimensions found in step 2. The Quotient
+    ///    is the SCEV to be divided in the next step of the recursion. The
+    ///    Remainder is the subscript of the innermost dimension. Loop over all
+    ///    array dimensions computed in step 2.
+    ///
+    /// To compute a uniform array size for several memory accesses to the same
+    /// object, one can collect in step 1 all the step terms for all the memory
+    /// accesses, and compute in step 2 a unique array shape. This guarantees
+    /// that the array shape will be the same across all memory accesses.
+    ///
+    /// FIXME: We could derive the result of steps 1 and 2 from a description of
+    /// the array shape given in metadata.
+    ///
+    /// Example:
+    ///
+    /// A[][n][m]
+    ///
+    /// for i
+    ///   for j
+    ///     for k
+    ///       A[j+k][2i][5i] =
+    ///
+    /// The initial SCEV:
+    ///
+    /// A[{{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k]
+    ///
+    /// 1. Find the different terms in the step functions:
+    /// -> [2*m, 5, n*m, n*m]
+    ///
+    /// 2. Compute the array size: sort and unique them
+    /// -> [n*m, 2*m, 5]
+    /// find the GCD of all the terms = 1
+    /// divide by the GCD and erase constant terms
+    /// -> [n*m, 2*m]
+    /// GCD = m
+    /// divide by GCD -> [n, 2]
+    /// remove constant terms
+    /// -> [n]
+    /// size of the array is A[unknown][n][m]
+    ///
+    /// 3. Compute the access function
+    /// a. Divide {{{0,+,2*m+5}_i, +, n*m}_j, +, n*m}_k by the innermost size m
+    /// Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k
+    /// Remainder: {{{0,+,5}_i, +, 0}_j, +, 0}_k
+    /// The remainder is the subscript of the innermost array dimension: [5i].
+    ///
+    /// b. Divide Quotient: {{{0,+,2}_i, +, n}_j, +, n}_k by next outer size n
+    /// Quotient: {{{0,+,0}_i, +, 1}_j, +, 1}_k
+    /// Remainder: {{{0,+,2}_i, +, 0}_j, +, 0}_k
+    /// The Remainder is the subscript of the next array dimension: [2i].
+    ///
+    /// The subscript of the outermost dimension is the Quotient: [j+k].
+    ///
+    /// Overall, we have: A[][n][m], and the access function: A[j+k][2i][5i].
+    void delinearize(ScalarEvolution &SE,
+                     SmallVectorImpl<const SCEV *> &Subscripts,
+                     SmallVectorImpl<const SCEV *> &Sizes,
+                     const SCEV *ElementSize) const;
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVSMaxExpr - This class represents a signed maximum selection.
+  ///
+  class SCEVSMaxExpr : public SCEVCommutativeExpr {
+    friend class ScalarEvolution;
+
+    SCEVSMaxExpr(const FoldingSetNodeIDRef ID,
+                 const SCEV *const *O, size_t N)
+      : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
+      // Max never overflows.
+      setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
+    }
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scSMaxExpr;
+    }
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
+  ///
+  class SCEVUMaxExpr : public SCEVCommutativeExpr {
+    friend class ScalarEvolution;
+
+    SCEVUMaxExpr(const FoldingSetNodeIDRef ID,
+                 const SCEV *const *O, size_t N)
+      : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
+      // Max never overflows.
+      setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
+    }
+
+  public:
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scUMaxExpr;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
+  /// value, and only represent it as its LLVM Value.  This is the "bottom"
+  /// value for the analysis.
+  ///
+  class SCEVUnknown : public SCEV, private CallbackVH {
+    friend class ScalarEvolution;
+
+    // Implement CallbackVH.
+    void deleted() override;
+    void allUsesReplacedWith(Value *New) override;
+
+    /// SE - The parent ScalarEvolution value. This is used to update
+    /// the parent's maps when the value associated with a SCEVUnknown
+    /// is deleted or RAUW'd.
+    ScalarEvolution *SE;
+
+    /// Next - The next pointer in the linked list of all
+    /// SCEVUnknown instances owned by a ScalarEvolution.
+    SCEVUnknown *Next;
+
+    SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V,
+                ScalarEvolution *se, SCEVUnknown *next) :
+      SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
+
+  public:
+    Value *getValue() const { return getValPtr(); }
+
+    /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
+    /// constant representing a type size, alignment, or field offset in
+    /// a target-independent manner, and hasn't happened to have been
+    /// folded with other operations into something unrecognizable. This
+    /// is mainly only useful for pretty-printing and other situations
+    /// where it isn't absolutely required for these to succeed.
+    bool isSizeOf(Type *&AllocTy) const;
+    bool isAlignOf(Type *&AllocTy) const;
+    bool isOffsetOf(Type *&STy, Constant *&FieldNo) const;
+
+    Type *getType() const { return getValPtr()->getType(); }
+
+    /// Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const SCEV *S) {
+      return S->getSCEVType() == scUnknown;
+    }
+  };
+
+  /// SCEVVisitor - This class defines a simple visitor class that may be used
+  /// for various SCEV analysis purposes.
+  template<typename SC, typename RetVal=void>
+  struct SCEVVisitor {
+    RetVal visit(const SCEV *S) {
+      switch (S->getSCEVType()) {
+      case scConstant:
+        return ((SC*)this)->visitConstant((const SCEVConstant*)S);
+      case scTruncate:
+        return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
+      case scZeroExtend:
+        return ((SC*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr*)S);
+      case scSignExtend:
+        return ((SC*)this)->visitSignExtendExpr((const SCEVSignExtendExpr*)S);
+      case scAddExpr:
+        return ((SC*)this)->visitAddExpr((const SCEVAddExpr*)S);
+      case scMulExpr:
+        return ((SC*)this)->visitMulExpr((const SCEVMulExpr*)S);
+      case scUDivExpr:
+        return ((SC*)this)->visitUDivExpr((const SCEVUDivExpr*)S);
+      case scAddRecExpr:
+        return ((SC*)this)->visitAddRecExpr((const SCEVAddRecExpr*)S);
+      case scSMaxExpr:
+        return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
+      case scUMaxExpr:
+        return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
+      case scUnknown:
+        return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
+      case scCouldNotCompute:
+        return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
+      default:
+        llvm_unreachable("Unknown SCEV type!");
+      }
+    }
+
+    RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
+      llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
+    }
+  };
+
+  /// Visit all nodes in the expression tree using worklist traversal.
+  ///
+  /// Visitor implements:
+  ///   // return true to follow this node.
+  ///   bool follow(const SCEV *S);
+  ///   // return true to terminate the search.
+  ///   bool isDone();
+  template<typename SV>
+  class SCEVTraversal {
+    SV &Visitor;
+    SmallVector<const SCEV *, 8> Worklist;
+    SmallPtrSet<const SCEV *, 8> Visited;
+
+    void push(const SCEV *S) {
+      if (Visited.insert(S) && Visitor.follow(S))
+        Worklist.push_back(S);
+    }
+  public:
+    SCEVTraversal(SV& V): Visitor(V) {}
+
+    void visitAll(const SCEV *Root) {
+      push(Root);
+      while (!Worklist.empty() && !Visitor.isDone()) {
+        const SCEV *S = Worklist.pop_back_val();
+
+        switch (S->getSCEVType()) {
+        case scConstant:
+        case scUnknown:
+          break;
+        case scTruncate:
+        case scZeroExtend:
+        case scSignExtend:
+          push(cast<SCEVCastExpr>(S)->getOperand());
+          break;
+        case scAddExpr:
+        case scMulExpr:
+        case scSMaxExpr:
+        case scUMaxExpr:
+        case scAddRecExpr: {
+          const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
+          for (SCEVNAryExpr::op_iterator I = NAry->op_begin(),
+                 E = NAry->op_end(); I != E; ++I) {
+            push(*I);
+          }
+          break;
+        }
+        case scUDivExpr: {
+          const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
+          push(UDiv->getLHS());
+          push(UDiv->getRHS());
+          break;
+        }
+        case scCouldNotCompute:
+          llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
+        default:
+          llvm_unreachable("Unknown SCEV kind!");
+        }
+      }
+    }
+  };
+
+  /// Use SCEVTraversal to visit all nodes in the givien expression tree.
+  template<typename SV>
+  void visitAll(const SCEV *Root, SV& Visitor) {
+    SCEVTraversal<SV> T(Visitor);
+    T.visitAll(Root);
+  }
+
+  typedef DenseMap<const Value*, Value*> ValueToValueMap;
+
+  /// The SCEVParameterRewriter takes a scalar evolution expression and updates
+  /// the SCEVUnknown components following the Map (Value -> Value).
+  struct SCEVParameterRewriter
+    : public SCEVVisitor<SCEVParameterRewriter, const SCEV*> {
+  public:
+    static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
+                               ValueToValueMap &Map,
+                               bool InterpretConsts = false) {
+      SCEVParameterRewriter Rewriter(SE, Map, InterpretConsts);
+      return Rewriter.visit(Scev);
+    }
+
+    SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M, bool C)
+      : SE(S), Map(M), InterpretConsts(C) {}
+
+    const SCEV *visitConstant(const SCEVConstant *Constant) {
+      return Constant;
+    }
+
+    const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getTruncateExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getZeroExtendExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getSignExtendExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getAddExpr(Operands);
+    }
+
+    const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getMulExpr(Operands);
+    }
+
+    const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
+      return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
+    }
+
+    const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getAddRecExpr(Operands, Expr->getLoop(),
+                              Expr->getNoWrapFlags());
+    }
+
+    const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getSMaxExpr(Operands);
+    }
+
+    const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getUMaxExpr(Operands);
+    }
+
+    const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+      Value *V = Expr->getValue();
+      if (Map.count(V)) {
+        Value *NV = Map[V];
+        if (InterpretConsts && isa<ConstantInt>(NV))
+          return SE.getConstant(cast<ConstantInt>(NV));
+        return SE.getUnknown(NV);
+      }
+      return Expr;
+    }
+
+    const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
+      return Expr;
+    }
+
+  private:
+    ScalarEvolution &SE;
+    ValueToValueMap &Map;
+    bool InterpretConsts;
+  };
+
+  typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT;
+
+  /// The SCEVApplyRewriter takes a scalar evolution expression and applies
+  /// the Map (Loop -> SCEV) to all AddRecExprs.
+  struct SCEVApplyRewriter
+    : public SCEVVisitor<SCEVApplyRewriter, const SCEV*> {
+  public:
+    static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
+                               ScalarEvolution &SE) {
+      SCEVApplyRewriter Rewriter(SE, Map);
+      return Rewriter.visit(Scev);
+    }
+
+    SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M)
+      : SE(S), Map(M) {}
+
+    const SCEV *visitConstant(const SCEVConstant *Constant) {
+      return Constant;
+    }
+
+    const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getTruncateExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getZeroExtendExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+      const SCEV *Operand = visit(Expr->getOperand());
+      return SE.getSignExtendExpr(Operand, Expr->getType());
+    }
+
+    const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getAddExpr(Operands);
+    }
+
+    const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getMulExpr(Operands);
+    }
+
+    const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
+      return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
+    }
+
+    const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+
+      const Loop *L = Expr->getLoop();
+      const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
+
+      if (0 == Map.count(L))
+        return Res;
+
+      const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res;
+      return Rec->evaluateAtIteration(Map[L], SE);
+    }
+
+    const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getSMaxExpr(Operands);
+    }
+
+    const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+      SmallVector<const SCEV *, 2> Operands;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+        Operands.push_back(visit(Expr->getOperand(i)));
+      return SE.getUMaxExpr(Operands);
+    }
+
+    const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+      return Expr;
+    }
+
+    const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
+      return Expr;
+    }
+
+  private:
+    ScalarEvolution &SE;
+    LoopToScevMapT &Map;
+  };
+
+/// Applies the Map (Loop -> SCEV) to the given Scev.
+static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map,
+                                ScalarEvolution &SE) {
+  return SCEVApplyRewriter::rewrite(Scev, Map, SE);
+}
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/ScalarEvolutionNormalization.h b/include/llvm/Analysis/ScalarEvolutionNormalization.h
new file mode 100644
index 0000000..7c6423a
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -0,0 +1,78 @@
+//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- 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 utilities for working with "normalized" ScalarEvolution
+// expressions.
+//
+// The following example illustrates post-increment uses and how normalized
+// expressions help.
+//
+//   for (i=0; i!=n; ++i) {
+//     ...
+//   }
+//   use(i);
+//
+// While the expression for most uses of i inside the loop is {0,+,1}<%L>, the
+// expression for the use of i outside the loop is {1,+,1}<%L>, since i is
+// incremented at the end of the loop body. This is inconveient, since it
+// suggests that we need two different induction variables, one that starts
+// at 0 and one that starts at 1. We'd prefer to be able to think of these as
+// the same induction variable, with uses inside the loop using the
+// "pre-incremented" value, and uses after the loop using the
+// "post-incremented" value.
+//
+// Expressions for post-incremented uses are represented as an expression
+// paired with a set of loops for which the expression is in "post-increment"
+// mode (there may be multiple loops).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace llvm {
+
+class Instruction;
+class DominatorTree;
+class Loop;
+class ScalarEvolution;
+class SCEV;
+class Value;
+
+/// TransformKind - Different types of transformations that
+/// TransformForPostIncUse can do.
+enum TransformKind {
+  /// Normalize - Normalize according to the given loops.
+  Normalize,
+  /// NormalizeAutodetect - Detect post-inc opportunities on new expressions,
+  /// update the given loop set, and normalize.
+  NormalizeAutodetect,
+  /// Denormalize - Perform the inverse transform on the expression with the
+  /// given loop set.
+  Denormalize
+};
+
+/// PostIncLoopSet - A set of loops.
+typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
+
+/// TransformForPostIncUse - Transform the given expression according to the
+/// given transformation kind.
+const SCEV *TransformForPostIncUse(TransformKind Kind,
+                                   const SCEV *S,
+                                   Instruction *User,
+                                   Value *OperandValToReplace,
+                                   PostIncLoopSet &Loops,
+                                   ScalarEvolution &SE,
+                                   DominatorTree &DT);
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h
new file mode 100644
index 0000000..65ff2f6
--- /dev/null
+++ b/include/llvm/Analysis/SparsePropagation.h
@@ -0,0 +1,206 @@
+//===- SparsePropagation.h - Sparse Conditional Property Propagation ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an abstract sparse conditional propagation algorithm,
+// modeled after SCCP, but with a customizable lattice function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H
+#define LLVM_ANALYSIS_SPARSEPROPAGATION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+  class Value;
+  class Constant;
+  class Argument;
+  class Instruction;
+  class PHINode;
+  class TerminatorInst;
+  class BasicBlock;
+  class Function;
+  class SparseSolver;
+  class raw_ostream;
+
+  template<typename T> class SmallVectorImpl;
+  
+/// AbstractLatticeFunction - This class is implemented by the dataflow instance
+/// to specify what the lattice values are and how they handle merges etc.
+/// This gives the client the power to compute lattice values from instructions,
+/// constants, etc.  The requirement is that lattice values must all fit into
+/// a void*.  If a void* is not sufficient, the implementation should use this
+/// pointer to be a pointer into a uniquing set or something.
+///
+class AbstractLatticeFunction {
+public:
+  typedef void *LatticeVal;
+private:
+  LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
+public:
+  AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal,
+                          LatticeVal untrackedVal) {
+    UndefVal = undefVal;
+    OverdefinedVal = overdefinedVal;
+    UntrackedVal = untrackedVal;
+  }
+  virtual ~AbstractLatticeFunction();
+  
+  LatticeVal getUndefVal()       const { return UndefVal; }
+  LatticeVal getOverdefinedVal() const { return OverdefinedVal; }
+  LatticeVal getUntrackedVal()   const { return UntrackedVal; }
+  
+  /// IsUntrackedValue - If the specified Value is something that is obviously
+  /// uninteresting to the analysis (and would always return UntrackedVal),
+  /// this function can return true to avoid pointless work.
+  virtual bool IsUntrackedValue(Value *V) {
+    return false;
+  }
+  
+  /// ComputeConstant - Given a constant value, compute and return a lattice
+  /// value corresponding to the specified constant.
+  virtual LatticeVal ComputeConstant(Constant *C) {
+    return getOverdefinedVal(); // always safe
+  }
+
+  /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is
+  /// one that the we want to handle through ComputeInstructionState.
+  virtual bool IsSpecialCasedPHI(PHINode *PN) {
+    return false;
+  }
+  
+  /// GetConstant - If the specified lattice value is representable as an LLVM
+  /// constant value, return it.  Otherwise return null.  The returned value
+  /// must be in the same LLVM type as Val.
+  virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) {
+    return nullptr;
+  }
+
+  /// ComputeArgument - Given a formal argument value, compute and return a
+  /// lattice value corresponding to the specified argument.
+  virtual LatticeVal ComputeArgument(Argument *I) {
+    return getOverdefinedVal(); // always safe
+  }
+  
+  /// MergeValues - Compute and return the merge of the two specified lattice
+  /// values.  Merging should only move one direction down the lattice to
+  /// guarantee convergence (toward overdefined).
+  virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) {
+    return getOverdefinedVal(); // always safe, never useful.
+  }
+  
+  /// ComputeInstructionState - Given an instruction and a vector of its operand
+  /// values, compute the result value of the instruction.
+  virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) {
+    return getOverdefinedVal(); // always safe, never useful.
+  }
+  
+  /// PrintValue - Render the specified lattice value to the specified stream.
+  virtual void PrintValue(LatticeVal V, raw_ostream &OS);
+};
+
+  
+/// SparseSolver - This class is a general purpose solver for Sparse Conditional
+/// Propagation with a programmable lattice function.
+///
+class SparseSolver {
+  typedef AbstractLatticeFunction::LatticeVal LatticeVal;
+  
+  /// LatticeFunc - This is the object that knows the lattice and how to do
+  /// compute transfer functions.
+  AbstractLatticeFunction *LatticeFunc;
+  
+  DenseMap<Value*, LatticeVal> ValueState;  // The state each value is in.
+  SmallPtrSet<BasicBlock*, 16> BBExecutable;   // The bbs that are executable.
+  
+  std::vector<Instruction*> InstWorkList;   // Worklist of insts to process.
+  
+  std::vector<BasicBlock*> BBWorkList;  // The BasicBlock work list
+  
+  /// KnownFeasibleEdges - Entries in this set are edges which have already had
+  /// PHI nodes retriggered.
+  typedef std::pair<BasicBlock*,BasicBlock*> Edge;
+  std::set<Edge> KnownFeasibleEdges;
+
+  SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
+  void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
+public:
+  explicit SparseSolver(AbstractLatticeFunction *Lattice)
+    : LatticeFunc(Lattice) {}
+  ~SparseSolver() {
+    delete LatticeFunc;
+  }
+  
+  /// Solve - Solve for constants and executable blocks.
+  ///
+  void Solve(Function &F);
+  
+  void Print(Function &F, raw_ostream &OS) const;
+
+  /// getLatticeState - Return the LatticeVal object that corresponds to the
+  /// value.  If an value is not in the map, it is returned as untracked,
+  /// unlike the getOrInitValueState method.
+  LatticeVal getLatticeState(Value *V) const {
+    DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V);
+    return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
+  }
+  
+  /// getOrInitValueState - Return the LatticeVal object that corresponds to the
+  /// value, initializing the value's state if it hasn't been entered into the
+  /// map yet.   This function is necessary because not all values should start
+  /// out in the underdefined state... Arguments should be overdefined, and
+  /// constants should be marked as constants.
+  ///
+  LatticeVal getOrInitValueState(Value *V);
+  
+  /// isEdgeFeasible - Return true if the control flow edge from the 'From'
+  /// basic block to the 'To' basic block is currently feasible.  If
+  /// AggressiveUndef is true, then this treats values with unknown lattice
+  /// values as undefined.  This is generally only useful when solving the
+  /// lattice, not when querying it.
+  bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
+                      bool AggressiveUndef = false);
+
+  /// isBlockExecutable - Return true if there are any known feasible
+  /// edges into the basic block.  This is generally only useful when
+  /// querying the lattice.
+  bool isBlockExecutable(BasicBlock *BB) const {
+    return BBExecutable.count(BB);
+  }
+  
+private:
+  /// UpdateState - When the state for some instruction is potentially updated,
+  /// this function notices and adds I to the worklist if needed.
+  void UpdateState(Instruction &Inst, LatticeVal V);
+  
+  /// MarkBlockExecutable - This method can be used by clients to mark all of
+  /// the blocks that are known to be intrinsically live in the processed unit.
+  void MarkBlockExecutable(BasicBlock *BB);
+  
+  /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
+  /// work list if it is not already executable.
+  void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
+  
+  /// getFeasibleSuccessors - Return a vector of booleans to indicate which
+  /// successors are reachable from a given terminator instruction.
+  void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
+                             bool AggressiveUndef);
+  
+  void visitInst(Instruction &I);
+  void visitPHINode(PHINode &I);
+  void visitTerminatorInst(TerminatorInst &TI);
+
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H
diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h
new file mode 100644
index 0000000..587a7ef
--- /dev/null
+++ b/include/llvm/Analysis/TargetFolder.h
@@ -0,0 +1,269 @@
+//====- TargetFolder.h - Constant folding helper ---------------*- 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 TargetFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants with
+// target dependent folding, in addition to the same target-independent
+// folding that the ConstantFolder class provides.  For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TARGETFOLDER_H
+#define LLVM_ANALYSIS_TARGETFOLDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
+
+namespace llvm {
+
+class DataLayout;
+
+/// TargetFolder - Create constants with target dependent folding.
+class TargetFolder {
+  const DataLayout *DL;
+
+  /// Fold - Fold the constant using target specific information.
+  Constant *Fold(Constant *C) const {
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+      if (Constant *CF = ConstantFoldConstantExpression(CE, DL))
+        return CF;
+    return C;
+  }
+
+public:
+  explicit TargetFolder(const DataLayout *DL) : DL(DL) {}
+
+  //===--------------------------------------------------------------------===//
+  // Binary Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateAdd(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
+  }
+  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getFAdd(LHS, RHS));
+  }
+  Constant *CreateSub(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
+  }
+  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getFSub(LHS, RHS));
+  }
+  Constant *CreateMul(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
+  }
+  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getFMul(LHS, RHS));
+  }
+  Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+    return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
+  }
+  Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+    return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
+  }
+  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getFDiv(LHS, RHS));
+  }
+  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getURem(LHS, RHS));
+  }
+  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getSRem(LHS, RHS));
+  }
+  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getFRem(LHS, RHS));
+  }
+  Constant *CreateShl(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
+  }
+  Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+    return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
+  }
+  Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+    return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
+  }
+  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getAnd(LHS, RHS));
+  }
+  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getOr(LHS, RHS));
+  }
+  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::getXor(LHS, RHS));
+  }
+
+  Constant *CreateBinOp(Instruction::BinaryOps Opc,
+                        Constant *LHS, Constant *RHS) const {
+    return Fold(ConstantExpr::get(Opc, LHS, RHS));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Unary Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateNeg(Constant *C,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
+  }
+  Constant *CreateFNeg(Constant *C) const {
+    return Fold(ConstantExpr::getFNeg(C));
+  }
+  Constant *CreateNot(Constant *C) const {
+    return Fold(ConstantExpr::getNot(C));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Memory Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateGetElementPtr(Constant *C,
+                                ArrayRef<Constant *> IdxList) const {
+    return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+  }
+  Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return Fold(ConstantExpr::getGetElementPtr(C, Idx));
+  }
+  Constant *CreateGetElementPtr(Constant *C,
+                                ArrayRef<Value *> IdxList) const {
+    return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+  }
+
+  Constant *CreateInBoundsGetElementPtr(Constant *C,
+                                        ArrayRef<Constant *> IdxList) const {
+    return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+  }
+  Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx));
+  }
+  Constant *CreateInBoundsGetElementPtr(Constant *C,
+                                        ArrayRef<Value *> IdxList) const {
+    return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Cast/Conversion Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+                       Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getCast(Op, C, DestTy));
+  }
+  Constant *CreateIntCast(Constant *C, Type *DestTy,
+                          bool isSigned) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
+  }
+  Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getPointerCast(C, DestTy));
+  }
+  Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getFPCast(C, DestTy));
+  }
+  Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::BitCast, C, DestTy);
+  }
+  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::IntToPtr, C, DestTy);
+  }
+  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::PtrToInt, C, DestTy);
+  }
+  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
+  }
+  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
+  }
+  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
+  }
+
+  Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
+                                                Type *DestTy) const {
+    if (C->getType() == DestTy)
+      return C; // avoid calling Fold
+    return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Compare Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+  }
+  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Other Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+    return Fold(ConstantExpr::getSelect(C, True, False));
+  }
+
+  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+    return Fold(ConstantExpr::getExtractElement(Vec, Idx));
+  }
+
+  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+                                Constant *Idx) const {
+    return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
+  }
+
+  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+                                Constant *Mask) const {
+    return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
+  }
+
+  Constant *CreateExtractValue(Constant *Agg,
+                               ArrayRef<unsigned> IdxList) const {
+    return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
+  }
+
+  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+                              ArrayRef<unsigned> IdxList) const {
+    return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
new file mode 100644
index 0000000..f57f3eb
--- /dev/null
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -0,0 +1,434 @@
+//===- llvm/Analysis/TargetTransformInfo.h ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass exposes codegen information to IR-level passes. Every
+// transformation that uses codegen information is broken into three parts:
+// 1. The IR-level analysis pass.
+// 2. The IR-level transformation interface which provides the needed
+//    information.
+// 3. Codegen-level implementation which uses target-specific hooks.
+//
+// This file defines #2, which is the interface that IR-level transformations
+// use for querying the codegen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
+#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class GlobalValue;
+class Loop;
+class Type;
+class User;
+class Value;
+
+/// TargetTransformInfo - This pass provides access to the codegen
+/// interfaces that are needed for IR-level transformations.
+class TargetTransformInfo {
+protected:
+  /// \brief The TTI instance one level down the stack.
+  ///
+  /// This is used to implement the default behavior all of the methods which
+  /// is to delegate up through the stack of TTIs until one can answer the
+  /// query.
+  TargetTransformInfo *PrevTTI;
+
+  /// \brief The top of the stack of TTI analyses available.
+  ///
+  /// This is a convenience routine maintained as TTI analyses become available
+  /// that complements the PrevTTI delegation chain. When one part of an
+  /// analysis pass wants to query another part of the analysis pass it can use
+  /// this to start back at the top of the stack.
+  TargetTransformInfo *TopTTI;
+
+  /// All pass subclasses must in their initializePass routine call
+  /// pushTTIStack with themselves to update the pointers tracking the previous
+  /// TTI instance in the analysis group's stack, and the top of the analysis
+  /// group's stack.
+  void pushTTIStack(Pass *P);
+
+  /// All pass subclasses must call TargetTransformInfo::getAnalysisUsage.
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+  /// This class is intended to be subclassed by real implementations.
+  virtual ~TargetTransformInfo() = 0;
+
+  /// \name Generic Target Information
+  /// @{
+
+  /// \brief Underlying constants for 'cost' values in this interface.
+  ///
+  /// Many APIs in this interface return a cost. This enum defines the
+  /// fundamental values that should be used to interpret (and produce) those
+  /// costs. The costs are returned as an unsigned rather than a member of this
+  /// enumeration because it is expected that the cost of one IR instruction
+  /// may have a multiplicative factor to it or otherwise won't fit directly
+  /// into the enum. Moreover, it is common to sum or average costs which works
+  /// better as simple integral values. Thus this enum only provides constants.
+  ///
+  /// Note that these costs should usually reflect the intersection of code-size
+  /// cost and execution cost. A free instruction is typically one that folds
+  /// into another instruction. For example, reg-to-reg moves can often be
+  /// skipped by renaming the registers in the CPU, but they still are encoded
+  /// and thus wouldn't be considered 'free' here.
+  enum TargetCostConstants {
+    TCC_Free = 0,       ///< Expected to fold away in lowering.
+    TCC_Basic = 1,      ///< The cost of a typical 'add' instruction.
+    TCC_Expensive = 4   ///< The cost of a 'div' instruction on x86.
+  };
+
+  /// \brief Estimate the cost of a specific operation when lowered.
+  ///
+  /// Note that this is designed to work on an arbitrary synthetic opcode, and
+  /// thus work for hypothetical queries before an instruction has even been
+  /// formed. However, this does *not* work for GEPs, and must not be called
+  /// for a GEP instruction. Instead, use the dedicated getGEPCost interface as
+  /// analyzing a GEP's cost required more information.
+  ///
+  /// Typically only the result type is required, and the operand type can be
+  /// omitted. However, if the opcode is one of the cast instructions, the
+  /// operand type is required.
+  ///
+  /// The returned cost is defined in terms of \c TargetCostConstants, see its
+  /// comments for a detailed explanation of the cost values.
+  virtual unsigned getOperationCost(unsigned Opcode, Type *Ty,
+                                    Type *OpTy = nullptr) const;
+
+  /// \brief Estimate the cost of a GEP operation when lowered.
+  ///
+  /// The contract for this function is the same as \c getOperationCost except
+  /// that it supports an interface that provides extra information specific to
+  /// the GEP operation.
+  virtual unsigned getGEPCost(const Value *Ptr,
+                              ArrayRef<const Value *> Operands) const;
+
+  /// \brief Estimate the cost of a function call when lowered.
+  ///
+  /// The contract for this is the same as \c getOperationCost except that it
+  /// supports an interface that provides extra information specific to call
+  /// instructions.
+  ///
+  /// This is the most basic query for estimating call cost: it only knows the
+  /// function type and (potentially) the number of arguments at the call site.
+  /// The latter is only interesting for varargs function types.
+  virtual unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const;
+
+  /// \brief Estimate the cost of calling a specific function when lowered.
+  ///
+  /// This overload adds the ability to reason about the particular function
+  /// being called in the event it is a library call with special lowering.
+  virtual unsigned getCallCost(const Function *F, int NumArgs = -1) const;
+
+  /// \brief Estimate the cost of calling a specific function when lowered.
+  ///
+  /// This overload allows specifying a set of candidate argument values.
+  virtual unsigned getCallCost(const Function *F,
+                               ArrayRef<const Value *> Arguments) const;
+
+  /// \brief Estimate the cost of an intrinsic when lowered.
+  ///
+  /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
+  virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+                                    ArrayRef<Type *> ParamTys) const;
+
+  /// \brief Estimate the cost of an intrinsic when lowered.
+  ///
+  /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
+  virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+                                    ArrayRef<const Value *> Arguments) const;
+
+  /// \brief Estimate the cost of a given IR user when lowered.
+  ///
+  /// This can estimate the cost of either a ConstantExpr or Instruction when
+  /// lowered. It has two primary advantages over the \c getOperationCost and
+  /// \c getGEPCost above, and one significant disadvantage: it can only be
+  /// used when the IR construct has already been formed.
+  ///
+  /// The advantages are that it can inspect the SSA use graph to reason more
+  /// accurately about the cost. For example, all-constant-GEPs can often be
+  /// folded into a load or other instruction, but if they are used in some
+  /// other context they may not be folded. This routine can distinguish such
+  /// cases.
+  ///
+  /// The returned cost is defined in terms of \c TargetCostConstants, see its
+  /// comments for a detailed explanation of the cost values.
+  virtual unsigned getUserCost(const User *U) const;
+
+  /// \brief hasBranchDivergence - Return true if branch divergence exists.
+  /// Branch divergence has a significantly negative impact on GPU performance
+  /// when threads in the same wavefront take different paths due to conditional
+  /// branches.
+  virtual bool hasBranchDivergence() const;
+
+  /// \brief Test whether calls to a function lower to actual program function
+  /// calls.
+  ///
+  /// The idea is to test whether the program is likely to require a 'call'
+  /// instruction or equivalent in order to call the given function.
+  ///
+  /// FIXME: It's not clear that this is a good or useful query API. Client's
+  /// should probably move to simpler cost metrics using the above.
+  /// Alternatively, we could split the cost interface into distinct code-size
+  /// and execution-speed costs. This would allow modelling the core of this
+  /// query more accurately as the a call is a single small instruction, but
+  /// incurs significant execution cost.
+  virtual bool isLoweredToCall(const Function *F) const;
+
+  /// Parameters that control the generic loop unrolling transformation.
+  struct UnrollingPreferences {
+    /// The cost threshold for the unrolled loop, compared to
+    /// CodeMetrics.NumInsts aggregated over all basic blocks in the loop body.
+    /// The unrolling factor is set such that the unrolled loop body does not
+    /// exceed this cost. Set this to UINT_MAX to disable the loop body cost
+    /// restriction.
+    unsigned Threshold;
+    /// The cost threshold for the unrolled loop when optimizing for size (set
+    /// to UINT_MAX to disable).
+    unsigned OptSizeThreshold;
+    /// The cost threshold for the unrolled loop, like Threshold, but used
+    /// for partial/runtime unrolling (set to UINT_MAX to disable).
+    unsigned PartialThreshold;
+    /// The cost threshold for the unrolled loop when optimizing for size, like
+    /// OptSizeThreshold, but used for partial/runtime unrolling (set to UINT_MAX
+    /// to disable).
+    unsigned PartialOptSizeThreshold;
+    /// A forced unrolling factor (the number of concatenated bodies of the
+    /// original loop in the unrolled loop body). When set to 0, the unrolling
+    /// transformation will select an unrolling factor based on the current cost
+    /// threshold and other factors.
+    unsigned Count;
+    // Set the maximum unrolling factor. The unrolling factor may be selected
+    // using the appropriate cost threshold, but may not exceed this number
+    // (set to UINT_MAX to disable). This does not apply in cases where the
+    // loop is being fully unrolled.
+    unsigned MaxCount;
+    /// Allow partial unrolling (unrolling of loops to expand the size of the
+    /// loop body, not only to eliminate small constant-trip-count loops).
+    bool     Partial;
+    /// Allow runtime unrolling (unrolling of loops to expand the size of the
+    /// loop body even when the number of loop iterations is not known at compile
+    /// time).
+    bool     Runtime;
+  };
+
+  /// \brief Get target-customized preferences for the generic loop unrolling
+  /// transformation. The caller will initialize UP with the current
+  /// target-independent defaults.
+  virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const;
+
+  /// @}
+
+  /// \name Scalar Target Information
+  /// @{
+
+  /// \brief Flags indicating the kind of support for population count.
+  ///
+  /// Compared to the SW implementation, HW support is supposed to
+  /// significantly boost the performance when the population is dense, and it
+  /// may or may not degrade performance if the population is sparse. A HW
+  /// support is considered as "Fast" if it can outperform, or is on a par
+  /// with, SW implementation when the population is sparse; otherwise, it is
+  /// considered as "Slow".
+  enum PopcntSupportKind {
+    PSK_Software,
+    PSK_SlowHardware,
+    PSK_FastHardware
+  };
+
+  /// \brief Return true if the specified immediate is legal add immediate, that
+  /// is the target has add instructions which can add a register with the
+  /// immediate without having to materialize the immediate into a register.
+  virtual bool isLegalAddImmediate(int64_t Imm) const;
+
+  /// \brief Return true if the specified immediate is legal icmp immediate,
+  /// that is the target has icmp instructions which can compare a register
+  /// against the immediate without having to materialize the immediate into a
+  /// register.
+  virtual bool isLegalICmpImmediate(int64_t Imm) const;
+
+  /// \brief Return true if the addressing mode represented by AM is legal for
+  /// this target, for a load/store of the specified type.
+  /// The type may be VoidTy, in which case only return true if the addressing
+  /// mode is legal for a load/store of any legal type.
+  /// TODO: Handle pre/postinc as well.
+  virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
+                                     int64_t BaseOffset, bool HasBaseReg,
+                                     int64_t Scale) const;
+
+  /// \brief Return the cost of the scaling factor used in the addressing
+  /// mode represented by AM for this target, for a load/store
+  /// of the specified type.
+  /// If the AM is supported, the return value must be >= 0.
+  /// If the AM is not supported, it returns a negative value.
+  /// TODO: Handle pre/postinc as well.
+  virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
+                                   int64_t BaseOffset, bool HasBaseReg,
+                                   int64_t Scale) const;
+
+  /// \brief Return true if it's free to truncate a value of type Ty1 to type
+  /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
+  /// by referencing its sub-register AX.
+  virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
+
+  /// \brief Return true if this type is legal.
+  virtual bool isTypeLegal(Type *Ty) const;
+
+  /// \brief Returns the target's jmp_buf alignment in bytes.
+  virtual unsigned getJumpBufAlignment() const;
+
+  /// \brief Returns the target's jmp_buf size in bytes.
+  virtual unsigned getJumpBufSize() const;
+
+  /// \brief Return true if switches should be turned into lookup tables for the
+  /// target.
+  virtual bool shouldBuildLookupTables() const;
+
+  /// \brief Return hardware support for population count.
+  virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
+
+  /// \brief Return true if the hardware has a fast square-root instruction.
+  virtual bool haveFastSqrt(Type *Ty) const;
+
+  /// \brief Return the expected cost of materializing for the given integer
+  /// immediate of the specified type.
+  virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
+
+  /// \brief Return the expected cost of materialization for the given integer
+  /// immediate of the specified type for a given instruction. The cost can be
+  /// zero if the immediate can be folded into the specified instruction.
+  virtual unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
+                                 Type *Ty) const;
+  virtual unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx,
+                                 const APInt &Imm, Type *Ty) const;
+  /// @}
+
+  /// \name Vector Target Information
+  /// @{
+
+  /// \brief The various kinds of shuffle patterns for vector queries.
+  enum ShuffleKind {
+    SK_Broadcast,       ///< Broadcast element 0 to all other elements.
+    SK_Reverse,         ///< Reverse the order of the vector.
+    SK_Alternate,       ///< Choose alternate elements from vector.
+    SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
+    SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
+  };
+
+  /// \brief Additional information about an operand's possible values.
+  enum OperandValueKind {
+    OK_AnyValue,                 // Operand can have any value.
+    OK_UniformValue,             // Operand is uniform (splat of a value).
+    OK_UniformConstantValue,     // Operand is uniform constant.
+    OK_NonUniformConstantValue   // Operand is a non uniform constant value.
+  };
+
+  /// \return The number of scalar or vector registers that the target has.
+  /// If 'Vectors' is true, it returns the number of vector registers. If it is
+  /// set to false, it returns the number of scalar registers.
+  virtual unsigned getNumberOfRegisters(bool Vector) const;
+
+  /// \return The width of the largest scalar or vector register type.
+  virtual unsigned getRegisterBitWidth(bool Vector) const;
+
+  /// \return The maximum unroll factor that the vectorizer should try to
+  /// perform for this target. This number depends on the level of parallelism
+  /// and the number of execution units in the CPU.
+  virtual unsigned getMaximumUnrollFactor() const;
+
+  /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
+  virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
+                                  OperandValueKind Opd1Info = OK_AnyValue,
+                                  OperandValueKind Opd2Info = OK_AnyValue) const;
+
+  /// \return The cost of a shuffle instruction of kind Kind and of type Tp.
+  /// The index and subtype parameters are used by the subvector insertion and
+  /// extraction shuffle kinds.
+  virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
+                                  Type *SubTp = nullptr) const;
+
+  /// \return The expected cost of cast instructions, such as bitcast, trunc,
+  /// zext, etc.
+  virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
+                                    Type *Src) const;
+
+  /// \return The expected cost of control-flow related instructions such as
+  /// Phi, Ret, Br.
+  virtual unsigned getCFInstrCost(unsigned Opcode) const;
+
+  /// \returns The expected cost of compare and select instructions.
+  virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+                                      Type *CondTy = nullptr) const;
+
+  /// \return The expected cost of vector Insert and Extract.
+  /// Use -1 to indicate that there is no information on the index value.
+  virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
+                                      unsigned Index = -1) const;
+
+  /// \return The cost of Load and Store instructions.
+  virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
+                                   unsigned Alignment,
+                                   unsigned AddressSpace) const;
+
+  /// \brief Calculate the cost of performing a vector reduction.
+  ///
+  /// This is the cost of reducing the vector value of type \p Ty to a scalar
+  /// value using the operation denoted by \p Opcode. The form of the reduction
+  /// can either be a pairwise reduction or a reduction that splits the vector
+  /// at every reduction level.
+  ///
+  /// Pairwise:
+  ///  (v0, v1, v2, v3)
+  ///  ((v0+v1), (v2, v3), undef, undef)
+  /// Split:
+  ///  (v0, v1, v2, v3)
+  ///  ((v0+v2), (v1+v3), undef, undef)
+  virtual unsigned getReductionCost(unsigned Opcode, Type *Ty,
+                                    bool IsPairwiseForm) const;
+
+  /// \returns The cost of Intrinsic instructions.
+  virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+                                         ArrayRef<Type *> Tys) const;
+
+  /// \returns The number of pieces into which the provided type must be
+  /// split during legalization. Zero is returned when the answer is unknown.
+  virtual unsigned getNumberOfParts(Type *Tp) const;
+
+  /// \returns The cost of the address computation. For most targets this can be
+  /// merged into the instruction indexing mode. Some targets might want to
+  /// distinguish between address computation for memory operations on vector
+  /// types and scalar types. Such targets should override this function.
+  /// The 'IsComplex' parameter is a hint that the address computation is likely
+  /// to involve multiple instructions and as such unlikely to be merged into
+  /// the address indexing mode.
+  virtual unsigned getAddressComputationCost(Type *Ty,
+                                             bool IsComplex = false) const;
+
+  /// @}
+
+  /// Analysis group identification.
+  static char ID;
+};
+
+/// \brief Create the base case instance of a pass in the TTI analysis group.
+///
+/// This class provides the base case for the stack of TTI analyzes. It doesn't
+/// delegate to anything and uses the STTI and VTTI objects passed in to
+/// satisfy the queries.
+ImmutablePass *createNoTargetTransformInfoPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h
new file mode 100644
index 0000000..bedd654
--- /dev/null
+++ b/include/llvm/Analysis/Trace.h
@@ -0,0 +1,119 @@
+//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- 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 a single trace of LLVM basic blocks.  A trace is a
+// single entry, multiple exit, region of code that is often hot.  Trace-based
+// optimizations treat traces almost like they are a large, strange, basic
+// block: because the trace path is assumed to be hot, optimizations for the
+// fall-through path are made at the expense of the non-fall-through paths.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TRACE_H
+#define LLVM_ANALYSIS_TRACE_H
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+  class BasicBlock;
+  class Function;
+  class Module;
+  class raw_ostream;
+
+class Trace {
+  typedef std::vector<BasicBlock *> BasicBlockListType;
+  BasicBlockListType BasicBlocks;
+
+public:
+  /// Trace ctor - Make a new trace from a vector of basic blocks,
+  /// residing in the function which is the parent of the first
+  /// basic block in the vector.
+  ///
+  Trace(const std::vector<BasicBlock *> &vBB) : BasicBlocks (vBB) {}
+
+  /// getEntryBasicBlock - Return the entry basic block (first block)
+  /// of the trace.
+  ///
+  BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; }
+
+  /// operator[]/getBlock - Return basic block N in the trace.
+  ///
+  BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; }
+  BasicBlock *getBlock(unsigned i)   const { return BasicBlocks[i]; }
+
+  /// getFunction - Return this trace's parent function.
+  ///
+  Function *getFunction () const;
+
+  /// getModule - Return this Module that contains this trace's parent
+  /// function.
+  ///
+  Module *getModule () const;
+
+  /// getBlockIndex - Return the index of the specified basic block in the
+  /// trace, or -1 if it is not in the trace.
+  int getBlockIndex(const BasicBlock *X) const {
+    for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+      if (BasicBlocks[i] == X)
+        return i;
+    return -1;
+  }
+
+  /// contains - Returns true if this trace contains the given basic
+  /// block.
+  ///
+  bool contains(const BasicBlock *X) const {
+    return getBlockIndex(X) != -1;
+  }
+
+  /// Returns true if B1 occurs before B2 in the trace, or if it is the same
+  /// block as B2..  Both blocks must be in the trace.
+  ///
+  bool dominates(const BasicBlock *B1, const BasicBlock *B2) const {
+    int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2);
+    assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!");
+    return B1Idx <= B2Idx;
+  }
+
+  // BasicBlock iterators...
+  typedef BasicBlockListType::iterator iterator;
+  typedef BasicBlockListType::const_iterator const_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+
+  iterator                begin()       { return BasicBlocks.begin(); }
+  const_iterator          begin() const { return BasicBlocks.begin(); }
+  iterator                end  ()       { return BasicBlocks.end();   }
+  const_iterator          end  () const { return BasicBlocks.end();   }
+
+  reverse_iterator       rbegin()       { return BasicBlocks.rbegin(); }
+  const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+  reverse_iterator       rend  ()       { return BasicBlocks.rend();   }
+  const_reverse_iterator rend  () const { return BasicBlocks.rend();   }
+
+  unsigned                 size() const { return BasicBlocks.size(); }
+  bool                    empty() const { return BasicBlocks.empty(); }
+
+  iterator erase(iterator q)               { return BasicBlocks.erase (q); }
+  iterator erase(iterator q1, iterator q2) { return BasicBlocks.erase (q1, q2); }
+
+  /// print - Write trace to output stream.
+  ///
+  void print(raw_ostream &O) const;
+
+  /// dump - Debugger convenience method; writes trace to standard error
+  /// output stream.
+  ///
+  void dump() const;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_TRACE_H
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
new file mode 100644
index 0000000..83b5408
--- /dev/null
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -0,0 +1,196 @@
+//===- llvm/Analysis/ValueTracking.h - Walk computations --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains routines that help analyze properties that chains of
+// computations have.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_VALUETRACKING_H
+#define LLVM_ANALYSIS_VALUETRACKING_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class Value;
+  class Instruction;
+  class APInt;
+  class DataLayout;
+  class StringRef;
+  class MDNode;
+  class TargetLibraryInfo;
+
+  /// Determine which bits of V are known to be either zero or one and return
+  /// them in the KnownZero/KnownOne bit sets.
+  ///
+  /// This function is defined on values with integer type, values with pointer
+  /// type (but only if TD is non-null), and vectors of integers.  In the case
+  /// where V is a vector, the known zero and known one values are the
+  /// same width as the vector element, and the bit is set only if it is true
+  /// for all of the elements in the vector.
+  void computeKnownBits(Value *V,  APInt &KnownZero, APInt &KnownOne,
+                        const DataLayout *TD = nullptr, unsigned Depth = 0);
+  /// Compute known bits from the range metadata.
+  /// \p KnownZero the set of bits that are known to be zero
+  void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
+                                         APInt &KnownZero);
+
+  /// ComputeSignBit - Determine whether the sign bit is known to be zero or
+  /// one.  Convenience wrapper around computeKnownBits.
+  void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
+                      const DataLayout *TD = nullptr, unsigned Depth = 0);
+
+  /// isKnownToBeAPowerOfTwo - Return true if the given value is known to have
+  /// exactly one bit set when defined. For vectors return true if every
+  /// element is known to be a power of two when defined.  Supports values with
+  /// integer or pointer type and vectors of integers.  If 'OrZero' is set then
+  /// returns true if the given value is either a power of two or zero.
+  bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0);
+
+  /// isKnownNonZero - Return true if the given value is known to be non-zero
+  /// when defined.  For vectors return true if every element is known to be
+  /// non-zero when defined.  Supports values with integer or pointer type and
+  /// vectors of integers.
+  bool isKnownNonZero(Value *V, const DataLayout *TD = nullptr,
+                      unsigned Depth = 0);
+
+  /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.  We use
+  /// this predicate to simplify operations downstream.  Mask is known to be
+  /// zero for bits that V cannot have.
+  ///
+  /// This function is defined on values with integer type, values with pointer
+  /// type (but only if TD is non-null), and vectors of integers.  In the case
+  /// where V is a vector, the mask, known zero, and known one values are the
+  /// same width as the vector element, and the bit is set only if it is true
+  /// for all of the elements in the vector.
+  bool MaskedValueIsZero(Value *V, const APInt &Mask, 
+                         const DataLayout *TD = nullptr, unsigned Depth = 0);
+
+  
+  /// ComputeNumSignBits - Return the number of times the sign bit of the
+  /// register is replicated into the other bits.  We know that at least 1 bit
+  /// is always equal to the sign bit (itself), but other cases can give us
+  /// information.  For example, immediately after an "ashr X, 2", we know that
+  /// the top 3 bits are all equal to each other, so we return 3.
+  ///
+  /// 'Op' must have a scalar integer type.
+  ///
+  unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = nullptr,
+                              unsigned Depth = 0);
+
+  /// ComputeMultiple - This function computes the integer multiple of Base that
+  /// equals V.  If successful, it returns true and returns the multiple in
+  /// Multiple.  If unsuccessful, it returns false.  Also, if V can be
+  /// simplified to an integer, then the simplified V is returned in Val.  Look
+  /// through sext only if LookThroughSExt=true.
+  bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
+                       bool LookThroughSExt = false,
+                       unsigned Depth = 0);
+
+  /// CannotBeNegativeZero - Return true if we can prove that the specified FP 
+  /// value is never equal to -0.0.
+  ///
+  bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
+
+  /// isBytewiseValue - If the specified value can be set by repeating the same
+  /// byte in memory, return the i8 value that it is represented with.  This is
+  /// true for all i8 values obviously, but is also true for i32 0, i32 -1,
+  /// i16 0xF0F0, double 0.0 etc.  If the value can't be handled with a repeated
+  /// byte store (e.g. i16 0x1234), return null.
+  Value *isBytewiseValue(Value *V);
+    
+  /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
+  /// the scalar value indexed is already around as a register, for example if
+  /// it were inserted directly into the aggregrate.
+  ///
+  /// If InsertBefore is not null, this function will duplicate (modified)
+  /// insertvalues when a part of a nested struct is extracted.
+  Value *FindInsertedValue(Value *V,
+                           ArrayRef<unsigned> idx_range,
+                           Instruction *InsertBefore = nullptr);
+
+  /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
+  /// it can be expressed as a base pointer plus a constant offset.  Return the
+  /// base and offset to the caller.
+  Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
+                                          const DataLayout *TD);
+  static inline const Value *
+  GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
+                                   const DataLayout *TD) {
+    return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
+  }
+  
+  /// getConstantStringInfo - This function computes the length of a
+  /// null-terminated C string pointed to by V.  If successful, it returns true
+  /// and returns the string in Str.  If unsuccessful, it returns false.  This
+  /// does not include the trailing nul character by default.  If TrimAtNul is
+  /// set to false, then this returns any trailing nul characters as well as any
+  /// other characters that come after it.
+  bool getConstantStringInfo(const Value *V, StringRef &Str,
+                             uint64_t Offset = 0, bool TrimAtNul = true);
+
+  /// GetStringLength - If we can compute the length of the string pointed to by
+  /// the specified pointer, return 'len+1'.  If we can't, return 0.
+  uint64_t GetStringLength(Value *V);
+
+  /// GetUnderlyingObject - This method strips off any GEP address adjustments
+  /// and pointer casts from the specified value, returning the original object
+  /// being addressed.  Note that the returned value has pointer type if the
+  /// specified value does.  If the MaxLookup value is non-zero, it limits the
+  /// number of instructions to be stripped off.
+  Value *GetUnderlyingObject(Value *V, const DataLayout *TD = nullptr,
+                             unsigned MaxLookup = 6);
+  static inline const Value *
+  GetUnderlyingObject(const Value *V, const DataLayout *TD = nullptr,
+                      unsigned MaxLookup = 6) {
+    return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
+  }
+
+  /// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
+  /// except that it can look through phi and select instructions and return
+  /// multiple objects.
+  void GetUnderlyingObjects(Value *V,
+                            SmallVectorImpl<Value *> &Objects,
+                            const DataLayout *TD = nullptr,
+                            unsigned MaxLookup = 6);
+
+  /// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
+  /// are lifetime markers.
+  bool onlyUsedByLifetimeMarkers(const Value *V);
+
+  /// isSafeToSpeculativelyExecute - Return true if the instruction does not
+  /// have any effects besides calculating the result and does not have
+  /// undefined behavior.
+  ///
+  /// This method never returns true for an instruction that returns true for
+  /// mayHaveSideEffects; however, this method also does some other checks in
+  /// addition. It checks for undefined behavior, like dividing by zero or
+  /// loading from an invalid pointer (but not for undefined results, like a
+  /// shift with a shift amount larger than the width of the result). It checks
+  /// for malloc and alloca because speculatively executing them might cause a
+  /// memory leak. It also returns false for instructions related to control
+  /// flow, specifically terminators and PHI nodes.
+  ///
+  /// This method only looks at the instruction itself and its operands, so if
+  /// this method returns true, it is safe to move the instruction as long as
+  /// the correct dominance relationships for the operands and users hold.
+  /// However, this method can return true for instructions that read memory;
+  /// for such instructions, moving them may change the resulting value.
+  bool isSafeToSpeculativelyExecute(const Value *V,
+                                    const DataLayout *TD = nullptr);
+
+  /// isKnownNonNull - Return true if this pointer couldn't possibly be null by
+  /// its definition.  This returns true for allocas, non-extern-weak globals
+  /// and byval arguments.
+  bool isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI = nullptr);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/AsmParser/Parser.h b/include/llvm/AsmParser/Parser.h
new file mode 100644
index 0000000..165c46d
--- /dev/null
+++ b/include/llvm/AsmParser/Parser.h
@@ -0,0 +1,64 @@
+//===-- Parser.h - Parser for LLVM IR text assembly files -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  These classes are implemented by the lib/AsmParser library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASMPARSER_PARSER_H
+#define LLVM_ASMPARSER_PARSER_H
+
+#include <string>
+
+namespace llvm {
+
+class Module;
+class MemoryBuffer;
+class SMDiagnostic;
+class LLVMContext;
+
+/// This function is the main interface to the LLVM Assembly Parser. It parses
+/// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a file
+Module *ParseAssemblyFile(
+  const std::string &Filename, ///< The name of the file to parse
+  SMDiagnostic &Error,         ///< Error result info.
+  LLVMContext &Context         ///< Context in which to allocate globals info.
+);
+
+/// The function is a secondary interface to the LLVM Assembly Parser. It parses
+/// an ASCII string that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a string
+Module *ParseAssemblyString(
+  const char *AsmString, ///< The string containing assembly
+  Module *M,             ///< A module to add the assembly too.
+  SMDiagnostic &Error,   ///< Error result info.
+  LLVMContext &Context
+);
+
+/// This function is the low-level interface to the LLVM Assembly Parser.
+/// ParseAssemblyFile and ParseAssemblyString are wrappers around this function.
+/// @brief Parse LLVM Assembly from a MemoryBuffer. This function *always*
+/// takes ownership of the MemoryBuffer.
+Module *ParseAssembly(
+    MemoryBuffer *F,     ///< The MemoryBuffer containing assembly
+    Module *M,           ///< A module to add the assembly too.
+    SMDiagnostic &Err,   ///< Error result info.
+    LLVMContext &Context
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
new file mode 100644
index 0000000..b510daf
--- /dev/null
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -0,0 +1,187 @@
+//===- BitCodes.h - Enum values for the bitcode format ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header Bitcode enum values.
+//
+// The enum values defined in this file should be considered permanent.  If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODES_H
+#define LLVM_BITCODE_BITCODES_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+namespace bitc {
+  enum StandardWidths {
+    BlockIDWidth   = 8,  // We use VBR-8 for block IDs.
+    CodeLenWidth   = 4,  // Codelen are VBR-4.
+    BlockSizeWidth = 32  // BlockSize up to 2^32 32-bit words = 16GB per block.
+  };
+
+  // The standard abbrev namespace always has a way to exit a block, enter a
+  // nested block, define abbrevs, and define an unabbreviated record.
+  enum FixedAbbrevIDs {
+    END_BLOCK = 0,  // Must be zero to guarantee termination for broken bitcode.
+    ENTER_SUBBLOCK = 1,
+
+    /// DEFINE_ABBREV - Defines an abbrev for the current block.  It consists
+    /// of a vbr5 for # operand infos.  Each operand info is emitted with a
+    /// single bit to indicate if it is a literal encoding.  If so, the value is
+    /// emitted with a vbr8.  If not, the encoding is emitted as 3 bits followed
+    /// by the info value as a vbr5 if needed.
+    DEFINE_ABBREV = 2,
+
+    // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by
+    // a vbr6 for the # operands, followed by vbr6's for each operand.
+    UNABBREV_RECORD = 3,
+
+    // This is not a code, this is a marker for the first abbrev assignment.
+    FIRST_APPLICATION_ABBREV = 4
+  };
+
+  /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO
+  /// block, which contains metadata about other blocks in the file.
+  enum StandardBlockIDs {
+    /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example,
+    /// standard abbrevs that should be available to all blocks of a specified
+    /// ID.
+    BLOCKINFO_BLOCK_ID = 0,
+
+    // Block IDs 1-7 are reserved for future expansion.
+    FIRST_APPLICATION_BLOCKID = 8
+  };
+
+  /// BlockInfoCodes - The blockinfo block contains metadata about user-defined
+  /// blocks.
+  enum BlockInfoCodes {
+    // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd
+    // block, instead of the BlockInfo block.
+
+    BLOCKINFO_CODE_SETBID        = 1, // SETBID: [blockid#]
+    BLOCKINFO_CODE_BLOCKNAME     = 2, // BLOCKNAME: [name]
+    BLOCKINFO_CODE_SETRECORDNAME = 3  // BLOCKINFO_CODE_SETRECORDNAME:
+                                      //                             [id, name]
+  };
+
+} // End bitc namespace
+
+/// BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
+/// This is actually a union of two different things:
+///   1. It could be a literal integer value ("the operand is always 17").
+///   2. It could be an encoding specification ("this operand encoded like so").
+///
+class BitCodeAbbrevOp {
+  uint64_t Val;           // A literal value or data for an encoding.
+  bool IsLiteral : 1;     // Indicate whether this is a literal value or not.
+  unsigned Enc   : 3;     // The encoding to use.
+public:
+  enum Encoding {
+    Fixed = 1,  // A fixed width field, Val specifies number of bits.
+    VBR   = 2,  // A VBR field where Val specifies the width of each chunk.
+    Array = 3,  // A sequence of fields, next field species elt encoding.
+    Char6 = 4,  // A 6-bit fixed field which maps to [a-zA-Z0-9._].
+    Blob  = 5   // 32-bit aligned array of 8-bit characters.
+  };
+
+  explicit BitCodeAbbrevOp(uint64_t V) :  Val(V), IsLiteral(true) {}
+  explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0)
+    : Val(Data), IsLiteral(false), Enc(E) {}
+
+  bool isLiteral() const  { return IsLiteral; }
+  bool isEncoding() const { return !IsLiteral; }
+
+  // Accessors for literals.
+  uint64_t getLiteralValue() const { assert(isLiteral()); return Val; }
+
+  // Accessors for encoding info.
+  Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; }
+  uint64_t getEncodingData() const {
+    assert(isEncoding() && hasEncodingData());
+    return Val;
+  }
+
+  bool hasEncodingData() const { return hasEncodingData(getEncoding()); }
+  static bool hasEncodingData(Encoding E) {
+    switch (E) {
+    case Fixed:
+    case VBR:
+      return true;
+    case Array:
+    case Char6:
+    case Blob:
+      return false;
+    }
+    llvm_unreachable("Invalid encoding");
+  }
+
+  /// isChar6 - Return true if this character is legal in the Char6 encoding.
+  static bool isChar6(char C) {
+    if (C >= 'a' && C <= 'z') return true;
+    if (C >= 'A' && C <= 'Z') return true;
+    if (C >= '0' && C <= '9') return true;
+    if (C == '.' || C == '_') return true;
+    return false;
+  }
+  static unsigned EncodeChar6(char C) {
+    if (C >= 'a' && C <= 'z') return C-'a';
+    if (C >= 'A' && C <= 'Z') return C-'A'+26;
+    if (C >= '0' && C <= '9') return C-'0'+26+26;
+    if (C == '.')             return 62;
+    if (C == '_')             return 63;
+    llvm_unreachable("Not a value Char6 character!");
+  }
+
+  static char DecodeChar6(unsigned V) {
+    assert((V & ~63) == 0 && "Not a Char6 encoded character!");
+    if (V < 26)       return V+'a';
+    if (V < 26+26)    return V-26+'A';
+    if (V < 26+26+10) return V-26-26+'0';
+    if (V == 62)      return '.';
+    if (V == 63)      return '_';
+    llvm_unreachable("Not a value Char6 character!");
+  }
+
+};
+
+template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=true; };
+
+/// BitCodeAbbrev - This class represents an abbreviation record.  An
+/// abbreviation allows a complex record that has redundancy to be stored in a
+/// specialized format instead of the fully-general, fully-vbr, format.
+class BitCodeAbbrev {
+  SmallVector<BitCodeAbbrevOp, 32> OperandList;
+  unsigned char RefCount; // Number of things using this.
+  ~BitCodeAbbrev() {}
+public:
+  BitCodeAbbrev() : RefCount(1) {}
+
+  void addRef() { ++RefCount; }
+  void dropRef() { if (--RefCount == 0) delete this; }
+
+  unsigned getNumOperandInfos() const {
+    return static_cast<unsigned>(OperandList.size());
+  }
+  const BitCodeAbbrevOp &getOperandInfo(unsigned N) const {
+    return OperandList[N];
+  }
+
+  void Add(const BitCodeAbbrevOp &OpInfo) {
+    OperandList.push_back(OpInfo);
+  }
+};
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h
new file mode 100644
index 0000000..898cd52
--- /dev/null
+++ b/include/llvm/Bitcode/BitcodeWriterPass.h
@@ -0,0 +1,51 @@
+//===-- BitcodeWriterPass.h - Bitcode writing pass --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides a bitcode writing pass.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODE_WRITER_PASS_H
+#define LLVM_BITCODE_BITCODE_WRITER_PASS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+class Module;
+class ModulePass;
+class raw_ostream;
+class PreservedAnalyses;
+
+/// \brief Create and return a pass that writes the module to the specified
+/// ostream. Note that this pass is designed for use with the legacy pass
+/// manager.
+ModulePass *createBitcodeWriterPass(raw_ostream &Str);
+
+/// \brief Pass for writing a module of IR out to a bitcode file.
+///
+/// Note that this is intended for use with the new pass manager. To construct
+/// a pass for the legacy pass manager, use the function above.
+class BitcodeWriterPass {
+  raw_ostream &OS;
+
+public:
+  /// \brief Construct a bitcode writer pass around a particular output stream.
+  explicit BitcodeWriterPass(raw_ostream &OS) : OS(OS) {}
+
+  /// \brief Run the bitcode writer pass, and output the module to the selected
+  /// output stream.
+  PreservedAnalyses run(Module *M);
+
+  static StringRef name() { return "BitcodeWriterPass"; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
new file mode 100644
index 0000000..6f478b7
--- /dev/null
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -0,0 +1,556 @@
+//===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitstreamReader class.  This class can be used to
+// read an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITSTREAMREADER_H
+#define LLVM_BITCODE_BITSTREAMREADER_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/StreamableMemoryObject.h"
+#include <climits>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+  class Deserializer;
+
+/// BitstreamReader - This class is used to read from an LLVM bitcode stream,
+/// maintaining information that is global to decoding the entire file.  While
+/// a file is being read, multiple cursors can be independently advanced or
+/// skipped around within the file.  These are represented by the
+/// BitstreamCursor class.
+class BitstreamReader {
+public:
+  /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+  /// These describe abbreviations that all blocks of the specified ID inherit.
+  struct BlockInfo {
+    unsigned BlockID;
+    std::vector<BitCodeAbbrev*> Abbrevs;
+    std::string Name;
+
+    std::vector<std::pair<unsigned, std::string> > RecordNames;
+  };
+private:
+  std::unique_ptr<StreamableMemoryObject> BitcodeBytes;
+
+  std::vector<BlockInfo> BlockInfoRecords;
+
+  /// IgnoreBlockInfoNames - This is set to true if we don't care about the
+  /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer
+  /// uses this.
+  bool IgnoreBlockInfoNames;
+
+  BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION;
+  void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION;
+public:
+  BitstreamReader() : IgnoreBlockInfoNames(true) {
+  }
+
+  BitstreamReader(const unsigned char *Start, const unsigned char *End) {
+    IgnoreBlockInfoNames = true;
+    init(Start, End);
+  }
+
+  BitstreamReader(StreamableMemoryObject *bytes) {
+    BitcodeBytes.reset(bytes);
+  }
+
+  void init(const unsigned char *Start, const unsigned char *End) {
+    assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
+    BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
+  }
+
+  StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
+
+  ~BitstreamReader() {
+    // Free the BlockInfoRecords.
+    while (!BlockInfoRecords.empty()) {
+      BlockInfo &Info = BlockInfoRecords.back();
+      // Free blockinfo abbrev info.
+      for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
+           i != e; ++i)
+        Info.Abbrevs[i]->dropRef();
+      BlockInfoRecords.pop_back();
+    }
+  }
+
+  /// CollectBlockInfoNames - This is called by clients that want block/record
+  /// name information.
+  void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
+  bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; }
+
+  //===--------------------------------------------------------------------===//
+  // Block Manipulation
+  //===--------------------------------------------------------------------===//
+
+  /// hasBlockInfoRecords - Return true if we've already read and processed the
+  /// block info block for this Bitstream.  We only process it for the first
+  /// cursor that walks over it.
+  bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); }
+
+  /// getBlockInfo - If there is block info for the specified ID, return it,
+  /// otherwise return null.
+  const BlockInfo *getBlockInfo(unsigned BlockID) const {
+    // Common case, the most recent entry matches BlockID.
+    if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+      return &BlockInfoRecords.back();
+
+    for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
+         i != e; ++i)
+      if (BlockInfoRecords[i].BlockID == BlockID)
+        return &BlockInfoRecords[i];
+    return nullptr;
+  }
+
+  BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+    if (const BlockInfo *BI = getBlockInfo(BlockID))
+      return *const_cast<BlockInfo*>(BI);
+
+    // Otherwise, add a new record.
+    BlockInfoRecords.push_back(BlockInfo());
+    BlockInfoRecords.back().BlockID = BlockID;
+    return BlockInfoRecords.back();
+  }
+};
+
+
+/// BitstreamEntry - When advancing through a bitstream cursor, each advance can
+/// discover a few different kinds of entries:
+///   Error    - Malformed bitcode was found.
+///   EndBlock - We've reached the end of the current block, (or the end of the
+///              file, which is treated like a series of EndBlock records.
+///   SubBlock - This is the start of a new subblock of a specific ID.
+///   Record   - This is a record with a specific AbbrevID.
+///
+struct BitstreamEntry {
+  enum {
+    Error,
+    EndBlock,
+    SubBlock,
+    Record
+  } Kind;
+
+  unsigned ID;
+
+  static BitstreamEntry getError() {
+    BitstreamEntry E; E.Kind = Error; return E;
+  }
+  static BitstreamEntry getEndBlock() {
+    BitstreamEntry E; E.Kind = EndBlock; return E;
+  }
+  static BitstreamEntry getSubBlock(unsigned ID) {
+    BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
+  }
+  static BitstreamEntry getRecord(unsigned AbbrevID) {
+    BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
+  }
+};
+
+/// BitstreamCursor - This represents a position within a bitcode file.  There
+/// may be multiple independent cursors reading within one bitstream, each
+/// maintaining their own local state.
+///
+/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not
+/// be passed by value.
+class BitstreamCursor {
+  friend class Deserializer;
+  BitstreamReader *BitStream;
+  size_t NextChar;
+
+
+  /// CurWord/word_t - This is the current data we have pulled from the stream
+  /// but have not returned to the client.  This is specifically and
+  /// intentionally defined to follow the word size of the host machine for
+  /// efficiency.  We use word_t in places that are aware of this to make it
+  /// perfectly explicit what is going on.
+  typedef uint32_t word_t;
+  word_t CurWord;
+
+  /// BitsInCurWord - This is the number of bits in CurWord that are valid. This
+  /// is always from [0...31/63] inclusive (depending on word size).
+  unsigned BitsInCurWord;
+
+  // CurCodeSize - This is the declared size of code values used for the current
+  // block, in bits.
+  unsigned CurCodeSize;
+
+  /// CurAbbrevs - Abbrevs installed at in this block.
+  std::vector<BitCodeAbbrev*> CurAbbrevs;
+
+  struct Block {
+    unsigned PrevCodeSize;
+    std::vector<BitCodeAbbrev*> PrevAbbrevs;
+    explicit Block(unsigned PCS) : PrevCodeSize(PCS) {}
+  };
+
+  /// BlockScope - This tracks the codesize of parent blocks.
+  SmallVector<Block, 8> BlockScope;
+
+
+public:
+  BitstreamCursor() : BitStream(nullptr), NextChar(0) {}
+  BitstreamCursor(const BitstreamCursor &RHS)
+      : BitStream(nullptr), NextChar(0) {
+    operator=(RHS);
+  }
+
+  explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) {
+    NextChar = 0;
+    CurWord = 0;
+    BitsInCurWord = 0;
+    CurCodeSize = 2;
+  }
+
+  void init(BitstreamReader &R) {
+    freeState();
+
+    BitStream = &R;
+    NextChar = 0;
+    CurWord = 0;
+    BitsInCurWord = 0;
+    CurCodeSize = 2;
+  }
+
+  ~BitstreamCursor() {
+    freeState();
+  }
+
+  void operator=(const BitstreamCursor &RHS);
+
+  void freeState();
+
+  bool isEndPos(size_t pos) {
+    return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
+  }
+
+  bool canSkipToPos(size_t pos) const {
+    // pos can be skipped to if it is a valid address or one byte past the end.
+    return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
+        static_cast<uint64_t>(pos - 1));
+  }
+
+  uint32_t getWord(size_t pos) {
+    uint8_t buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
+    BitStream->getBitcodeBytes().readBytes(pos, sizeof(buf), buf);
+    return *reinterpret_cast<support::ulittle32_t *>(buf);
+  }
+
+  bool AtEndOfStream() {
+    return BitsInCurWord == 0 && isEndPos(NextChar);
+  }
+
+  /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
+  unsigned getAbbrevIDWidth() const { return CurCodeSize; }
+
+  /// GetCurrentBitNo - Return the bit # of the bit we are reading.
+  uint64_t GetCurrentBitNo() const {
+    return NextChar*CHAR_BIT - BitsInCurWord;
+  }
+
+  BitstreamReader *getBitStreamReader() {
+    return BitStream;
+  }
+  const BitstreamReader *getBitStreamReader() const {
+    return BitStream;
+  }
+
+  /// Flags that modify the behavior of advance().
+  enum {
+    /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does
+    /// not automatically pop the block scope when the end of a block is
+    /// reached.
+    AF_DontPopBlockAtEnd = 1,
+
+    /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are
+    /// returned just like normal records.
+    AF_DontAutoprocessAbbrevs = 2
+  };
+
+  /// advance - Advance the current bitstream, returning the next entry in the
+  /// stream.
+  BitstreamEntry advance(unsigned Flags = 0) {
+    while (1) {
+      unsigned Code = ReadCode();
+      if (Code == bitc::END_BLOCK) {
+        // Pop the end of the block unless Flags tells us not to.
+        if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd())
+          return BitstreamEntry::getError();
+        return BitstreamEntry::getEndBlock();
+      }
+
+      if (Code == bitc::ENTER_SUBBLOCK)
+        return BitstreamEntry::getSubBlock(ReadSubBlockID());
+
+      if (Code == bitc::DEFINE_ABBREV &&
+          !(Flags & AF_DontAutoprocessAbbrevs)) {
+        // We read and accumulate abbrev's, the client can't do anything with
+        // them anyway.
+        ReadAbbrevRecord();
+        continue;
+      }
+
+      return BitstreamEntry::getRecord(Code);
+    }
+  }
+
+  /// advanceSkippingSubblocks - This is a convenience function for clients that
+  /// don't expect any subblocks.  This just skips over them automatically.
+  BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) {
+    while (1) {
+      // If we found a normal entry, return it.
+      BitstreamEntry Entry = advance(Flags);
+      if (Entry.Kind != BitstreamEntry::SubBlock)
+        return Entry;
+
+      // If we found a sub-block, just skip over it and check the next entry.
+      if (SkipBlock())
+        return BitstreamEntry::getError();
+    }
+  }
+
+  /// JumpToBit - Reset the stream to the specified bit number.
+  void JumpToBit(uint64_t BitNo) {
+    uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
+    unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
+    assert(canSkipToPos(ByteNo) && "Invalid location");
+
+    // Move the cursor to the right word.
+    NextChar = ByteNo;
+    BitsInCurWord = 0;
+    CurWord = 0;
+
+    // Skip over any bits that are already consumed.
+    if (WordBitNo) {
+      if (sizeof(word_t) > 4)
+        Read64(WordBitNo);
+      else
+        Read(WordBitNo);
+    }
+  }
+
+
+  uint32_t Read(unsigned NumBits) {
+    assert(NumBits && NumBits <= 32 &&
+           "Cannot return zero or more than 32 bits!");
+
+    // If the field is fully contained by CurWord, return it quickly.
+    if (BitsInCurWord >= NumBits) {
+      uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
+      CurWord >>= NumBits;
+      BitsInCurWord -= NumBits;
+      return R;
+    }
+
+    // If we run out of data, stop at the end of the stream.
+    if (isEndPos(NextChar)) {
+      CurWord = 0;
+      BitsInCurWord = 0;
+      return 0;
+    }
+
+    uint32_t R = uint32_t(CurWord);
+
+    // Read the next word from the stream.
+    uint8_t Array[sizeof(word_t)] = {0};
+
+    BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), Array);
+
+    // Handle big-endian byte-swapping if necessary.
+    support::detail::packed_endian_specific_integral
+      <word_t, support::little, support::unaligned> EndianValue;
+    memcpy(&EndianValue, Array, sizeof(Array));
+
+    CurWord = EndianValue;
+
+    NextChar += sizeof(word_t);
+
+    // Extract NumBits-BitsInCurWord from what we just read.
+    unsigned BitsLeft = NumBits-BitsInCurWord;
+
+    // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive.
+    R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)))
+                    << BitsInCurWord);
+
+    // BitsLeft bits have just been used up from CurWord.  BitsLeft is in the
+    // range [1..32]/[1..64] so be careful how we shift.
+    if (BitsLeft != sizeof(word_t)*8)
+      CurWord >>= BitsLeft;
+    else
+      CurWord = 0;
+    BitsInCurWord = sizeof(word_t)*8-BitsLeft;
+    return R;
+  }
+
+  uint64_t Read64(unsigned NumBits) {
+    if (NumBits <= 32) return Read(NumBits);
+
+    uint64_t V = Read(32);
+    return V | (uint64_t)Read(NumBits-32) << 32;
+  }
+
+  uint32_t ReadVBR(unsigned NumBits) {
+    uint32_t Piece = Read(NumBits);
+    if ((Piece & (1U << (NumBits-1))) == 0)
+      return Piece;
+
+    uint32_t Result = 0;
+    unsigned NextBit = 0;
+    while (1) {
+      Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+      if ((Piece & (1U << (NumBits-1))) == 0)
+        return Result;
+
+      NextBit += NumBits-1;
+      Piece = Read(NumBits);
+    }
+  }
+
+  // ReadVBR64 - Read a VBR that may have a value up to 64-bits in size.  The
+  // chunk size of the VBR must still be <= 32 bits though.
+  uint64_t ReadVBR64(unsigned NumBits) {
+    uint32_t Piece = Read(NumBits);
+    if ((Piece & (1U << (NumBits-1))) == 0)
+      return uint64_t(Piece);
+
+    uint64_t Result = 0;
+    unsigned NextBit = 0;
+    while (1) {
+      Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+      if ((Piece & (1U << (NumBits-1))) == 0)
+        return Result;
+
+      NextBit += NumBits-1;
+      Piece = Read(NumBits);
+    }
+  }
+
+private:
+  void SkipToFourByteBoundary() {
+    // If word_t is 64-bits and if we've read less than 32 bits, just dump
+    // the bits we have up to the next 32-bit boundary.
+    if (sizeof(word_t) > 4 &&
+        BitsInCurWord >= 32) {
+      CurWord >>= BitsInCurWord-32;
+      BitsInCurWord = 32;
+      return;
+    }
+
+    BitsInCurWord = 0;
+    CurWord = 0;
+  }
+public:
+
+  unsigned ReadCode() {
+    return Read(CurCodeSize);
+  }
+
+
+  // Block header:
+  //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+
+  /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockID for
+  /// the block.
+  unsigned ReadSubBlockID() {
+    return ReadVBR(bitc::BlockIDWidth);
+  }
+
+  /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip
+  /// over the body of this block.  If the block record is malformed, return
+  /// true.
+  bool SkipBlock() {
+    // Read and ignore the codelen value.  Since we are skipping this block, we
+    // don't care what code widths are used inside of it.
+    ReadVBR(bitc::CodeLenWidth);
+    SkipToFourByteBoundary();
+    unsigned NumFourBytes = Read(bitc::BlockSizeWidth);
+
+    // Check that the block wasn't partially defined, and that the offset isn't
+    // bogus.
+    size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8;
+    if (AtEndOfStream() || !canSkipToPos(SkipTo/8))
+      return true;
+
+    JumpToBit(SkipTo);
+    return false;
+  }
+
+  /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
+  /// the block, and return true if the block has an error.
+  bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr);
+
+  bool ReadBlockEnd() {
+    if (BlockScope.empty()) return true;
+
+    // Block tail:
+    //    [END_BLOCK, <align4bytes>]
+    SkipToFourByteBoundary();
+
+    popBlockScope();
+    return false;
+  }
+
+private:
+
+  void popBlockScope() {
+    CurCodeSize = BlockScope.back().PrevCodeSize;
+
+    // Delete abbrevs from popped scope.
+    for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
+         i != e; ++i)
+      CurAbbrevs[i]->dropRef();
+
+    BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+    BlockScope.pop_back();
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Record Processing
+  //===--------------------------------------------------------------------===//
+
+private:
+  void readAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
+                              SmallVectorImpl<uint64_t> &Vals);
+  void readAbbreviatedField(const BitCodeAbbrevOp &Op,
+                            SmallVectorImpl<uint64_t> &Vals);
+  void skipAbbreviatedField(const BitCodeAbbrevOp &Op);
+
+public:
+
+  /// getAbbrev - Return the abbreviation for the specified AbbrevId.
+  const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) {
+    unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV;
+    assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+    return CurAbbrevs[AbbrevNo];
+  }
+
+  /// skipRecord - Read the current record and discard it.
+  void skipRecord(unsigned AbbrevID);
+
+  unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
+                      StringRef *Blob = nullptr);
+
+  //===--------------------------------------------------------------------===//
+  // Abbrev Processing
+  //===--------------------------------------------------------------------===//
+  void ReadAbbrevRecord();
+
+  bool ReadBlockInfoBlock();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
new file mode 100644
index 0000000..dcfebd9
--- /dev/null
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -0,0 +1,549 @@
+//===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitstreamWriter class.  This class can be used to
+// write an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITSTREAMWRITER_H
+#define LLVM_BITCODE_BITSTREAMWRITER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include <vector>
+
+namespace llvm {
+
+class BitstreamWriter {
+  SmallVectorImpl<char> &Out;
+
+  /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
+  unsigned CurBit;
+
+  /// CurValue - The current value.  Only bits < CurBit are valid.
+  uint32_t CurValue;
+
+  /// CurCodeSize - This is the declared size of code values used for the
+  /// current block, in bits.
+  unsigned CurCodeSize;
+
+  /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
+  /// selected BLOCK ID.
+  unsigned BlockInfoCurBID;
+
+  /// CurAbbrevs - Abbrevs installed at in this block.
+  std::vector<BitCodeAbbrev*> CurAbbrevs;
+
+  struct Block {
+    unsigned PrevCodeSize;
+    unsigned StartSizeWord;
+    std::vector<BitCodeAbbrev*> PrevAbbrevs;
+    Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
+  };
+
+  /// BlockScope - This tracks the current blocks that we have entered.
+  std::vector<Block> BlockScope;
+
+  /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+  /// These describe abbreviations that all blocks of the specified ID inherit.
+  struct BlockInfo {
+    unsigned BlockID;
+    std::vector<BitCodeAbbrev*> Abbrevs;
+  };
+  std::vector<BlockInfo> BlockInfoRecords;
+
+  // BackpatchWord - Backpatch a 32-bit word in the output with the specified
+  // value.
+  void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
+    Out[ByteNo++] = (unsigned char)(NewWord >>  0);
+    Out[ByteNo++] = (unsigned char)(NewWord >>  8);
+    Out[ByteNo++] = (unsigned char)(NewWord >> 16);
+    Out[ByteNo  ] = (unsigned char)(NewWord >> 24);
+  }
+
+  void WriteByte(unsigned char Value) {
+    Out.push_back(Value);
+  }
+
+  void WriteWord(unsigned Value) {
+    unsigned char Bytes[4] = {
+      (unsigned char)(Value >>  0),
+      (unsigned char)(Value >>  8),
+      (unsigned char)(Value >> 16),
+      (unsigned char)(Value >> 24) };
+    Out.append(&Bytes[0], &Bytes[4]);
+  }
+
+  unsigned GetBufferOffset() const {
+    return Out.size();
+  }
+
+  unsigned GetWordIndex() const {
+    unsigned Offset = GetBufferOffset();
+    assert((Offset & 3) == 0 && "Not 32-bit aligned");
+    return Offset / 4;
+  }
+
+public:
+  explicit BitstreamWriter(SmallVectorImpl<char> &O)
+    : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
+
+  ~BitstreamWriter() {
+    assert(CurBit == 0 && "Unflushed data remaining");
+    assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
+
+    // Free the BlockInfoRecords.
+    while (!BlockInfoRecords.empty()) {
+      BlockInfo &Info = BlockInfoRecords.back();
+      // Free blockinfo abbrev info.
+      for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
+           i != e; ++i)
+        Info.Abbrevs[i]->dropRef();
+      BlockInfoRecords.pop_back();
+    }
+  }
+
+  /// \brief Retrieve the current position in the stream, in bits.
+  uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
+
+  //===--------------------------------------------------------------------===//
+  // Basic Primitives for emitting bits to the stream.
+  //===--------------------------------------------------------------------===//
+
+  void Emit(uint32_t Val, unsigned NumBits) {
+    assert(NumBits && NumBits <= 32 && "Invalid value size!");
+    assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
+    CurValue |= Val << CurBit;
+    if (CurBit + NumBits < 32) {
+      CurBit += NumBits;
+      return;
+    }
+
+    // Add the current word.
+    WriteWord(CurValue);
+
+    if (CurBit)
+      CurValue = Val >> (32-CurBit);
+    else
+      CurValue = 0;
+    CurBit = (CurBit+NumBits) & 31;
+  }
+
+  void Emit64(uint64_t Val, unsigned NumBits) {
+    if (NumBits <= 32)
+      Emit((uint32_t)Val, NumBits);
+    else {
+      Emit((uint32_t)Val, 32);
+      Emit((uint32_t)(Val >> 32), NumBits-32);
+    }
+  }
+
+  void FlushToWord() {
+    if (CurBit) {
+      WriteWord(CurValue);
+      CurBit = 0;
+      CurValue = 0;
+    }
+  }
+
+  void EmitVBR(uint32_t Val, unsigned NumBits) {
+    assert(NumBits <= 32 && "Too many bits to emit!");
+    uint32_t Threshold = 1U << (NumBits-1);
+
+    // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+    while (Val >= Threshold) {
+      Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
+      Val >>= NumBits-1;
+    }
+
+    Emit(Val, NumBits);
+  }
+
+  void EmitVBR64(uint64_t Val, unsigned NumBits) {
+    assert(NumBits <= 32 && "Too many bits to emit!");
+    if ((uint32_t)Val == Val)
+      return EmitVBR((uint32_t)Val, NumBits);
+
+    uint32_t Threshold = 1U << (NumBits-1);
+
+    // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+    while (Val >= Threshold) {
+      Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
+           (1 << (NumBits-1)), NumBits);
+      Val >>= NumBits-1;
+    }
+
+    Emit((uint32_t)Val, NumBits);
+  }
+
+  /// EmitCode - Emit the specified code.
+  void EmitCode(unsigned Val) {
+    Emit(Val, CurCodeSize);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Block Manipulation
+  //===--------------------------------------------------------------------===//
+
+  /// getBlockInfo - If there is block info for the specified ID, return it,
+  /// otherwise return null.
+  BlockInfo *getBlockInfo(unsigned BlockID) {
+    // Common case, the most recent entry matches BlockID.
+    if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+      return &BlockInfoRecords.back();
+
+    for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
+         i != e; ++i)
+      if (BlockInfoRecords[i].BlockID == BlockID)
+        return &BlockInfoRecords[i];
+    return nullptr;
+  }
+
+  void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
+    // Block header:
+    //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+    EmitCode(bitc::ENTER_SUBBLOCK);
+    EmitVBR(BlockID, bitc::BlockIDWidth);
+    EmitVBR(CodeLen, bitc::CodeLenWidth);
+    FlushToWord();
+
+    unsigned BlockSizeWordIndex = GetWordIndex();
+    unsigned OldCodeSize = CurCodeSize;
+
+    // Emit a placeholder, which will be replaced when the block is popped.
+    Emit(0, bitc::BlockSizeWidth);
+
+    CurCodeSize = CodeLen;
+
+    // Push the outer block's abbrev set onto the stack, start out with an
+    // empty abbrev set.
+    BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
+    BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+    // If there is a blockinfo for this BlockID, add all the predefined abbrevs
+    // to the abbrev list.
+    if (BlockInfo *Info = getBlockInfo(BlockID)) {
+      for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
+           i != e; ++i) {
+        CurAbbrevs.push_back(Info->Abbrevs[i]);
+        Info->Abbrevs[i]->addRef();
+      }
+    }
+  }
+
+  void ExitBlock() {
+    assert(!BlockScope.empty() && "Block scope imbalance!");
+
+    // Delete all abbrevs.
+    for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
+         i != e; ++i)
+      CurAbbrevs[i]->dropRef();
+
+    const Block &B = BlockScope.back();
+
+    // Block tail:
+    //    [END_BLOCK, <align4bytes>]
+    EmitCode(bitc::END_BLOCK);
+    FlushToWord();
+
+    // Compute the size of the block, in words, not counting the size field.
+    unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
+    unsigned ByteNo = B.StartSizeWord*4;
+
+    // Update the block size field in the header of this sub-block.
+    BackpatchWord(ByteNo, SizeInWords);
+
+    // Restore the inner block's code size and abbrev table.
+    CurCodeSize = B.PrevCodeSize;
+    BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+    BlockScope.pop_back();
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Record Emission
+  //===--------------------------------------------------------------------===//
+
+private:
+  /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
+  /// record.  This is a no-op, since the abbrev specifies the literal to use.
+  template<typename uintty>
+  void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
+    assert(Op.isLiteral() && "Not a literal");
+    // If the abbrev specifies the literal value to use, don't emit
+    // anything.
+    assert(V == Op.getLiteralValue() &&
+           "Invalid abbrev for record!");
+  }
+
+  /// EmitAbbreviatedField - Emit a single scalar field value with the specified
+  /// encoding.
+  template<typename uintty>
+  void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
+    assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
+
+    // Encode the value as we are commanded.
+    switch (Op.getEncoding()) {
+    default: llvm_unreachable("Unknown encoding!");
+    case BitCodeAbbrevOp::Fixed:
+      if (Op.getEncodingData())
+        Emit((unsigned)V, (unsigned)Op.getEncodingData());
+      break;
+    case BitCodeAbbrevOp::VBR:
+      if (Op.getEncodingData())
+        EmitVBR64(V, (unsigned)Op.getEncodingData());
+      break;
+    case BitCodeAbbrevOp::Char6:
+      Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
+      break;
+    }
+  }
+
+  /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
+  /// emission code.  If BlobData is non-null, then it specifies an array of
+  /// data that should be emitted as part of the Blob or Array operand that is
+  /// known to exist at the end of the record.
+  template<typename uintty>
+  void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+                                StringRef Blob) {
+    const char *BlobData = Blob.data();
+    unsigned BlobLen = (unsigned) Blob.size();
+    unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
+    assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+    BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
+
+    EmitCode(Abbrev);
+
+    unsigned RecordIdx = 0;
+    for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
+         i != e; ++i) {
+      const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+      if (Op.isLiteral()) {
+        assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+        EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
+        ++RecordIdx;
+      } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
+        // Array case.
+        assert(i+2 == e && "array op not second to last?");
+        const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+        // If this record has blob data, emit it, otherwise we must have record
+        // entries to encode this way.
+        if (BlobData) {
+          assert(RecordIdx == Vals.size() &&
+                 "Blob data and record entries specified for array!");
+          // Emit a vbr6 to indicate the number of elements present.
+          EmitVBR(static_cast<uint32_t>(BlobLen), 6);
+
+          // Emit each field.
+          for (unsigned i = 0; i != BlobLen; ++i)
+            EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
+
+          // Know that blob data is consumed for assertion below.
+          BlobData = nullptr;
+        } else {
+          // Emit a vbr6 to indicate the number of elements present.
+          EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
+
+          // Emit each field.
+          for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
+            EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
+        }
+      } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
+        // If this record has blob data, emit it, otherwise we must have record
+        // entries to encode this way.
+
+        // Emit a vbr6 to indicate the number of elements present.
+        if (BlobData) {
+          EmitVBR(static_cast<uint32_t>(BlobLen), 6);
+          assert(RecordIdx == Vals.size() &&
+                 "Blob data and record entries specified for blob operand!");
+        } else {
+          EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
+        }
+
+        // Flush to a 32-bit alignment boundary.
+        FlushToWord();
+
+        // Emit each field as a literal byte.
+        if (BlobData) {
+          for (unsigned i = 0; i != BlobLen; ++i)
+            WriteByte((unsigned char)BlobData[i]);
+
+          // Know that blob data is consumed for assertion below.
+          BlobData = nullptr;
+        } else {
+          for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
+            assert(isUInt<8>(Vals[RecordIdx]) &&
+                   "Value too large to emit as blob");
+            WriteByte((unsigned char)Vals[RecordIdx]);
+          }
+        }
+
+        // Align end to 32-bits.
+        while (GetBufferOffset() & 3)
+          WriteByte(0);
+      } else {  // Single scalar field.
+        assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+        EmitAbbreviatedField(Op, Vals[RecordIdx]);
+        ++RecordIdx;
+      }
+    }
+    assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
+    assert(BlobData == nullptr &&
+           "Blob data specified for record that doesn't use it!");
+  }
+
+public:
+
+  /// EmitRecord - Emit the specified record to the stream, using an abbrev if
+  /// we have one to compress the output.
+  template<typename uintty>
+  void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals,
+                  unsigned Abbrev = 0) {
+    if (!Abbrev) {
+      // If we don't have an abbrev to use, emit this in its fully unabbreviated
+      // form.
+      EmitCode(bitc::UNABBREV_RECORD);
+      EmitVBR(Code, 6);
+      EmitVBR(static_cast<uint32_t>(Vals.size()), 6);
+      for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i)
+        EmitVBR64(Vals[i], 6);
+      return;
+    }
+
+    // Insert the code into Vals to treat it uniformly.
+    Vals.insert(Vals.begin(), Code);
+
+    EmitRecordWithAbbrev(Abbrev, Vals);
+  }
+
+  /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
+  /// Unlike EmitRecord, the code for the record should be included in Vals as
+  /// the first entry.
+  template<typename uintty>
+  void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) {
+    EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef());
+  }
+
+  /// EmitRecordWithBlob - Emit the specified record to the stream, using an
+  /// abbrev that includes a blob at the end.  The blob data to emit is
+  /// specified by the pointer and length specified at the end.  In contrast to
+  /// EmitRecord, this routine expects that the first entry in Vals is the code
+  /// of the record.
+  template<typename uintty>
+  void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+                          StringRef Blob) {
+    EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob);
+  }
+  template<typename uintty>
+  void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+                          const char *BlobData, unsigned BlobLen) {
+    return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen));
+  }
+
+  /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
+  /// that end with an array.
+  template<typename uintty>
+  void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+                          StringRef Array) {
+    EmitRecordWithAbbrevImpl(Abbrev, Vals, Array);
+  }
+  template<typename uintty>
+  void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+                          const char *ArrayData, unsigned ArrayLen) {
+    return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
+                                                            ArrayLen));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Abbrev Emission
+  //===--------------------------------------------------------------------===//
+
+private:
+  // Emit the abbreviation as a DEFINE_ABBREV record.
+  void EncodeAbbrev(BitCodeAbbrev *Abbv) {
+    EmitCode(bitc::DEFINE_ABBREV);
+    EmitVBR(Abbv->getNumOperandInfos(), 5);
+    for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
+         i != e; ++i) {
+      const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+      Emit(Op.isLiteral(), 1);
+      if (Op.isLiteral()) {
+        EmitVBR64(Op.getLiteralValue(), 8);
+      } else {
+        Emit(Op.getEncoding(), 3);
+        if (Op.hasEncodingData())
+          EmitVBR64(Op.getEncodingData(), 5);
+      }
+    }
+  }
+public:
+
+  /// EmitAbbrev - This emits an abbreviation to the stream.  Note that this
+  /// method takes ownership of the specified abbrev.
+  unsigned EmitAbbrev(BitCodeAbbrev *Abbv) {
+    // Emit the abbreviation as a record.
+    EncodeAbbrev(Abbv);
+    CurAbbrevs.push_back(Abbv);
+    return static_cast<unsigned>(CurAbbrevs.size())-1 +
+      bitc::FIRST_APPLICATION_ABBREV;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // BlockInfo Block Emission
+  //===--------------------------------------------------------------------===//
+
+  /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
+  void EnterBlockInfoBlock(unsigned CodeWidth) {
+    EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
+    BlockInfoCurBID = ~0U;
+  }
+private:
+  /// SwitchToBlockID - If we aren't already talking about the specified block
+  /// ID, emit a BLOCKINFO_CODE_SETBID record.
+  void SwitchToBlockID(unsigned BlockID) {
+    if (BlockInfoCurBID == BlockID) return;
+    SmallVector<unsigned, 2> V;
+    V.push_back(BlockID);
+    EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
+    BlockInfoCurBID = BlockID;
+  }
+
+  BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+    if (BlockInfo *BI = getBlockInfo(BlockID))
+      return *BI;
+
+    // Otherwise, add a new record.
+    BlockInfoRecords.push_back(BlockInfo());
+    BlockInfoRecords.back().BlockID = BlockID;
+    return BlockInfoRecords.back();
+  }
+
+public:
+
+  /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
+  /// BlockID.
+  unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) {
+    SwitchToBlockID(BlockID);
+    EncodeAbbrev(Abbv);
+
+    // Add the abbrev to the specified block record.
+    BlockInfo &Info = getOrCreateBlockInfo(BlockID);
+    Info.Abbrevs.push_back(Abbv);
+
+    return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
+  }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
new file mode 100644
index 0000000..ee2efa2
--- /dev/null
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -0,0 +1,392 @@
+//===- LLVMBitCodes.h - Enum values for the LLVM bitcode format -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for LLVM IR bitcode files.
+//
+// The enum values defined in this file should be considered permanent.  If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_LLVMBITCODES_H
+#define LLVM_BITCODE_LLVMBITCODES_H
+
+#include "llvm/Bitcode/BitCodes.h"
+
+namespace llvm {
+namespace bitc {
+  // The only top-level block type defined is for a module.
+  enum BlockIDs {
+    // Blocks
+    MODULE_BLOCK_ID          = FIRST_APPLICATION_BLOCKID,
+
+    // Module sub-block id's.
+    PARAMATTR_BLOCK_ID,
+    PARAMATTR_GROUP_BLOCK_ID,
+
+    CONSTANTS_BLOCK_ID,
+    FUNCTION_BLOCK_ID,
+
+    UNUSED_ID1,
+
+    VALUE_SYMTAB_BLOCK_ID,
+    METADATA_BLOCK_ID,
+    METADATA_ATTACHMENT_ID,
+
+    TYPE_BLOCK_ID_NEW,
+
+    USELIST_BLOCK_ID
+  };
+
+
+  /// MODULE blocks have a number of optional fields and subblocks.
+  enum ModuleCodes {
+    MODULE_CODE_VERSION     = 1,    // VERSION:     [version#]
+    MODULE_CODE_TRIPLE      = 2,    // TRIPLE:      [strchr x N]
+    MODULE_CODE_DATALAYOUT  = 3,    // DATALAYOUT:  [strchr x N]
+    MODULE_CODE_ASM         = 4,    // ASM:         [strchr x N]
+    MODULE_CODE_SECTIONNAME = 5,    // SECTIONNAME: [strchr x N]
+
+    // FIXME: Remove DEPLIB in 4.0.
+    MODULE_CODE_DEPLIB      = 6,    // DEPLIB:      [strchr x N]
+
+    // GLOBALVAR: [pointer type, isconst, initid,
+    //             linkage, alignment, section, visibility, threadlocal]
+    MODULE_CODE_GLOBALVAR   = 7,
+
+    // FUNCTION:  [type, callingconv, isproto, linkage, paramattrs, alignment,
+    //             section, visibility, gc, unnamed_addr]
+    MODULE_CODE_FUNCTION    = 8,
+
+    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    MODULE_CODE_ALIAS       = 9,
+
+    // MODULE_CODE_PURGEVALS: [numvals]
+    MODULE_CODE_PURGEVALS   = 10,
+
+    MODULE_CODE_GCNAME      = 11,  // GCNAME: [strchr x N]
+    MODULE_CODE_COMDAT      = 12,  // COMDAT: [selection_kind, name]
+  };
+
+  /// PARAMATTR blocks have code for defining a parameter attribute set.
+  enum AttributeCodes {
+    // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0
+    PARAMATTR_CODE_ENTRY_OLD  = 1, // ENTRY: [paramidx0, attr0,
+                                   //         paramidx1, attr1...]
+    PARAMATTR_CODE_ENTRY      = 2, // ENTRY: [paramidx0, attrgrp0,
+                                   //         paramidx1, attrgrp1, ...]
+    PARAMATTR_GRP_CODE_ENTRY  = 3  // ENTRY: [id, attr0, att1, ...]
+  };
+
+  /// TYPE blocks have codes for each type primitive they use.
+  enum TypeCodes {
+    TYPE_CODE_NUMENTRY =  1,    // NUMENTRY: [numentries]
+
+    // Type Codes
+    TYPE_CODE_VOID     =  2,    // VOID
+    TYPE_CODE_FLOAT    =  3,    // FLOAT
+    TYPE_CODE_DOUBLE   =  4,    // DOUBLE
+    TYPE_CODE_LABEL    =  5,    // LABEL
+    TYPE_CODE_OPAQUE   =  6,    // OPAQUE
+    TYPE_CODE_INTEGER  =  7,    // INTEGER: [width]
+    TYPE_CODE_POINTER  =  8,    // POINTER: [pointee type]
+
+    TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty,
+                                //            paramty x N]
+
+    TYPE_CODE_HALF     =  10,   // HALF
+
+    TYPE_CODE_ARRAY    = 11,    // ARRAY: [numelts, eltty]
+    TYPE_CODE_VECTOR   = 12,    // VECTOR: [numelts, eltty]
+
+    // These are not with the other floating point types because they're
+    // a late addition, and putting them in the right place breaks
+    // binary compatibility.
+    TYPE_CODE_X86_FP80 = 13,    // X86 LONG DOUBLE
+    TYPE_CODE_FP128    = 14,    // LONG DOUBLE (112 bit mantissa)
+    TYPE_CODE_PPC_FP128= 15,    // PPC LONG DOUBLE (2 doubles)
+
+    TYPE_CODE_METADATA = 16,    // METADATA
+
+    TYPE_CODE_X86_MMX = 17,     // X86 MMX
+
+    TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N]
+    TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N]
+    TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N]
+
+    TYPE_CODE_FUNCTION = 21     // FUNCTION: [vararg, retty, paramty x N]
+  };
+
+  // The type symbol table only has one code (TST_ENTRY_CODE).
+  enum TypeSymtabCodes {
+    TST_CODE_ENTRY = 1     // TST_ENTRY: [typeid, namechar x N]
+  };
+
+  // The value symbol table only has one code (VST_ENTRY_CODE).
+  enum ValueSymtabCodes {
+    VST_CODE_ENTRY   = 1,  // VST_ENTRY: [valid, namechar x N]
+    VST_CODE_BBENTRY = 2   // VST_BBENTRY: [bbid, namechar x N]
+  };
+
+  enum MetadataCodes {
+    METADATA_STRING        = 1,   // MDSTRING:      [values]
+    // 2 is unused.
+    // 3 is unused.
+    METADATA_NAME          = 4,   // STRING:        [values]
+    // 5 is unused.
+    METADATA_KIND          = 6,   // [n x [id, name]]
+    // 7 is unused.
+    METADATA_NODE          = 8,   // NODE:          [n x (type num, value num)]
+    METADATA_FN_NODE       = 9,   // FN_NODE:       [n x (type num, value num)]
+    METADATA_NAMED_NODE    = 10,  // NAMED_NODE:    [n x mdnodes]
+    METADATA_ATTACHMENT    = 11   // [m x [value, [n x [id, mdnode]]]
+  };
+
+  // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
+  // constant and maintains an implicit current type value.
+  enum ConstantsCodes {
+    CST_CODE_SETTYPE       =  1,  // SETTYPE:       [typeid]
+    CST_CODE_NULL          =  2,  // NULL
+    CST_CODE_UNDEF         =  3,  // UNDEF
+    CST_CODE_INTEGER       =  4,  // INTEGER:       [intval]
+    CST_CODE_WIDE_INTEGER  =  5,  // WIDE_INTEGER:  [n x intval]
+    CST_CODE_FLOAT         =  6,  // FLOAT:         [fpval]
+    CST_CODE_AGGREGATE     =  7,  // AGGREGATE:     [n x value number]
+    CST_CODE_STRING        =  8,  // STRING:        [values]
+    CST_CODE_CSTRING       =  9,  // CSTRING:       [values]
+    CST_CODE_CE_BINOP      = 10,  // CE_BINOP:      [opcode, opval, opval]
+    CST_CODE_CE_CAST       = 11,  // CE_CAST:       [opcode, opty, opval]
+    CST_CODE_CE_GEP        = 12,  // CE_GEP:        [n x operands]
+    CST_CODE_CE_SELECT     = 13,  // CE_SELECT:     [opval, opval, opval]
+    CST_CODE_CE_EXTRACTELT = 14,  // CE_EXTRACTELT: [opty, opval, opval]
+    CST_CODE_CE_INSERTELT  = 15,  // CE_INSERTELT:  [opval, opval, opval]
+    CST_CODE_CE_SHUFFLEVEC = 16,  // CE_SHUFFLEVEC: [opval, opval, opval]
+    CST_CODE_CE_CMP        = 17,  // CE_CMP:        [opty, opval, opval, pred]
+    CST_CODE_INLINEASM_OLD = 18,  // INLINEASM:     [sideeffect|alignstack,
+                                  //                 asmstr,conststr]
+    CST_CODE_CE_SHUFVEC_EX = 19,  // SHUFVEC_EX:    [opty, opval, opval, opval]
+    CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP:  [n x operands]
+    CST_CODE_BLOCKADDRESS  = 21,  // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
+    CST_CODE_DATA          = 22,  // DATA:          [n x elements]
+    CST_CODE_INLINEASM     = 23   // INLINEASM:     [sideeffect|alignstack|
+                                  //                 asmdialect,asmstr,conststr]
+  };
+
+  /// CastOpcodes - These are values used in the bitcode files to encode which
+  /// cast a CST_CODE_CE_CAST or a XXX refers to.  The values of these enums
+  /// have no fixed relation to the LLVM IR enum values.  Changing these will
+  /// break compatibility with old files.
+  enum CastOpcodes {
+    CAST_TRUNC    =  0,
+    CAST_ZEXT     =  1,
+    CAST_SEXT     =  2,
+    CAST_FPTOUI   =  3,
+    CAST_FPTOSI   =  4,
+    CAST_UITOFP   =  5,
+    CAST_SITOFP   =  6,
+    CAST_FPTRUNC  =  7,
+    CAST_FPEXT    =  8,
+    CAST_PTRTOINT =  9,
+    CAST_INTTOPTR = 10,
+    CAST_BITCAST  = 11,
+    CAST_ADDRSPACECAST = 12
+  };
+
+  /// BinaryOpcodes - These are values used in the bitcode files to encode which
+  /// binop a CST_CODE_CE_BINOP or a XXX refers to.  The values of these enums
+  /// have no fixed relation to the LLVM IR enum values.  Changing these will
+  /// break compatibility with old files.
+  enum BinaryOpcodes {
+    BINOP_ADD  =  0,
+    BINOP_SUB  =  1,
+    BINOP_MUL  =  2,
+    BINOP_UDIV =  3,
+    BINOP_SDIV =  4,    // overloaded for FP
+    BINOP_UREM =  5,
+    BINOP_SREM =  6,    // overloaded for FP
+    BINOP_SHL  =  7,
+    BINOP_LSHR =  8,
+    BINOP_ASHR =  9,
+    BINOP_AND  = 10,
+    BINOP_OR   = 11,
+    BINOP_XOR  = 12
+  };
+
+  /// These are values used in the bitcode files to encode AtomicRMW operations.
+  /// The values of these enums have no fixed relation to the LLVM IR enum
+  /// values.  Changing these will break compatibility with old files.
+  enum RMWOperations {
+    RMW_XCHG = 0,
+    RMW_ADD = 1,
+    RMW_SUB = 2,
+    RMW_AND = 3,
+    RMW_NAND = 4,
+    RMW_OR = 5,
+    RMW_XOR = 6,
+    RMW_MAX = 7,
+    RMW_MIN = 8,
+    RMW_UMAX = 9,
+    RMW_UMIN = 10
+  };
+
+  /// OverflowingBinaryOperatorOptionalFlags - Flags for serializing
+  /// OverflowingBinaryOperator's SubclassOptionalData contents.
+  enum OverflowingBinaryOperatorOptionalFlags {
+    OBO_NO_UNSIGNED_WRAP = 0,
+    OBO_NO_SIGNED_WRAP = 1
+  };
+
+  /// PossiblyExactOperatorOptionalFlags - Flags for serializing
+  /// PossiblyExactOperator's SubclassOptionalData contents.
+  enum PossiblyExactOperatorOptionalFlags {
+    PEO_EXACT = 0
+  };
+
+  /// Encoded AtomicOrdering values.
+  enum AtomicOrderingCodes {
+    ORDERING_NOTATOMIC = 0,
+    ORDERING_UNORDERED = 1,
+    ORDERING_MONOTONIC = 2,
+    ORDERING_ACQUIRE = 3,
+    ORDERING_RELEASE = 4,
+    ORDERING_ACQREL = 5,
+    ORDERING_SEQCST = 6
+  };
+
+  /// Encoded SynchronizationScope values.
+  enum AtomicSynchScopeCodes {
+    SYNCHSCOPE_SINGLETHREAD = 0,
+    SYNCHSCOPE_CROSSTHREAD = 1
+  };
+
+  // The function body block (FUNCTION_BLOCK_ID) describes function bodies.  It
+  // can contain a constant block (CONSTANTS_BLOCK_ID).
+  enum FunctionCodes {
+    FUNC_CODE_DECLAREBLOCKS    =  1, // DECLAREBLOCKS: [n]
+
+    FUNC_CODE_INST_BINOP       =  2, // BINOP:      [opcode, ty, opval, opval]
+    FUNC_CODE_INST_CAST        =  3, // CAST:       [opcode, ty, opty, opval]
+    FUNC_CODE_INST_GEP         =  4, // GEP:        [n x operands]
+    FUNC_CODE_INST_SELECT      =  5, // SELECT:     [ty, opval, opval, opval]
+    FUNC_CODE_INST_EXTRACTELT  =  6, // EXTRACTELT: [opty, opval, opval]
+    FUNC_CODE_INST_INSERTELT   =  7, // INSERTELT:  [ty, opval, opval, opval]
+    FUNC_CODE_INST_SHUFFLEVEC  =  8, // SHUFFLEVEC: [ty, opval, opval, opval]
+    FUNC_CODE_INST_CMP         =  9, // CMP:        [opty, opval, opval, pred]
+
+    FUNC_CODE_INST_RET         = 10, // RET:        [opty,opval<both optional>]
+    FUNC_CODE_INST_BR          = 11, // BR:         [bb#, bb#, cond] or [bb#]
+    FUNC_CODE_INST_SWITCH      = 12, // SWITCH:     [opty, op0, op1, ...]
+    FUNC_CODE_INST_INVOKE      = 13, // INVOKE:     [attr, fnty, op0,op1, ...]
+    // 14 is unused.
+    FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
+
+    FUNC_CODE_INST_PHI         = 16, // PHI:        [ty, val0,bb0, ...]
+    // 17 is unused.
+    // 18 is unused.
+    FUNC_CODE_INST_ALLOCA      = 19, // ALLOCA:     [instty, opty, op, align]
+    FUNC_CODE_INST_LOAD        = 20, // LOAD:       [opty, op, align, vol]
+    // 21 is unused.
+    // 22 is unused.
+    FUNC_CODE_INST_VAARG       = 23, // VAARG:      [valistty, valist, instty]
+    // This store code encodes the pointer type, rather than the value type
+    // this is so information only available in the pointer type (e.g. address
+    // spaces) is retained.
+    FUNC_CODE_INST_STORE       = 24, // STORE:      [ptrty,ptr,val, align, vol]
+    // 25 is unused.
+    FUNC_CODE_INST_EXTRACTVAL  = 26, // EXTRACTVAL: [n x operands]
+    FUNC_CODE_INST_INSERTVAL   = 27, // INSERTVAL:  [n x operands]
+    // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to
+    // support legacy vicmp/vfcmp instructions.
+    FUNC_CODE_INST_CMP2        = 28, // CMP2:       [opty, opval, opval, pred]
+    // new select on i1 or [N x i1]
+    FUNC_CODE_INST_VSELECT     = 29, // VSELECT:    [ty,opval,opval,predty,pred]
+    FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
+    FUNC_CODE_INST_INDIRECTBR  = 31, // INDIRECTBR: [opty, op0, op1, ...]
+    // 32 is unused.
+    FUNC_CODE_DEBUG_LOC_AGAIN  = 33, // DEBUG_LOC_AGAIN
+
+    FUNC_CODE_INST_CALL        = 34, // CALL:    [attr, cc, fnty, fnid, args...]
+
+    FUNC_CODE_DEBUG_LOC        = 35, // DEBUG_LOC:  [Line,Col,ScopeVal, IAVal]
+    FUNC_CODE_INST_FENCE       = 36, // FENCE: [ordering, synchscope]
+    FUNC_CODE_INST_CMPXCHG     = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
+                                     //           ordering, synchscope]
+    FUNC_CODE_INST_ATOMICRMW   = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
+                                     //             align, vol,
+                                     //             ordering, synchscope]
+    FUNC_CODE_INST_RESUME      = 39, // RESUME:     [opval]
+    FUNC_CODE_INST_LANDINGPAD  = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
+    FUNC_CODE_INST_LOADATOMIC  = 41, // LOAD: [opty, op, align, vol,
+                                     //        ordering, synchscope]
+    FUNC_CODE_INST_STOREATOMIC = 42  // STORE: [ptrty,ptr,val, align, vol
+                                     //         ordering, synchscope]
+  };
+
+  enum UseListCodes {
+    USELIST_CODE_ENTRY = 1   // USELIST_CODE_ENTRY: TBD.
+  };
+
+  enum AttributeKindCodes {
+    // = 0 is unused
+    ATTR_KIND_ALIGNMENT = 1,
+    ATTR_KIND_ALWAYS_INLINE = 2,
+    ATTR_KIND_BY_VAL = 3,
+    ATTR_KIND_INLINE_HINT = 4,
+    ATTR_KIND_IN_REG = 5,
+    ATTR_KIND_MIN_SIZE = 6,
+    ATTR_KIND_NAKED = 7,
+    ATTR_KIND_NEST = 8,
+    ATTR_KIND_NO_ALIAS = 9,
+    ATTR_KIND_NO_BUILTIN = 10,
+    ATTR_KIND_NO_CAPTURE = 11,
+    ATTR_KIND_NO_DUPLICATE = 12,
+    ATTR_KIND_NO_IMPLICIT_FLOAT = 13,
+    ATTR_KIND_NO_INLINE = 14,
+    ATTR_KIND_NON_LAZY_BIND = 15,
+    ATTR_KIND_NO_RED_ZONE = 16,
+    ATTR_KIND_NO_RETURN = 17,
+    ATTR_KIND_NO_UNWIND = 18,
+    ATTR_KIND_OPTIMIZE_FOR_SIZE = 19,
+    ATTR_KIND_READ_NONE = 20,
+    ATTR_KIND_READ_ONLY = 21,
+    ATTR_KIND_RETURNED = 22,
+    ATTR_KIND_RETURNS_TWICE = 23,
+    ATTR_KIND_S_EXT = 24,
+    ATTR_KIND_STACK_ALIGNMENT = 25,
+    ATTR_KIND_STACK_PROTECT = 26,
+    ATTR_KIND_STACK_PROTECT_REQ = 27,
+    ATTR_KIND_STACK_PROTECT_STRONG = 28,
+    ATTR_KIND_STRUCT_RET = 29,
+    ATTR_KIND_SANITIZE_ADDRESS = 30,
+    ATTR_KIND_SANITIZE_THREAD = 31,
+    ATTR_KIND_SANITIZE_MEMORY = 32,
+    ATTR_KIND_UW_TABLE = 33,
+    ATTR_KIND_Z_EXT = 34,
+    ATTR_KIND_BUILTIN = 35,
+    ATTR_KIND_COLD = 36,
+    ATTR_KIND_OPTIMIZE_NONE = 37,
+    ATTR_KIND_IN_ALLOCA = 38,
+    ATTR_KIND_NON_NULL = 39,
+    ATTR_KIND_JUMP_TABLE = 40,
+    ATTR_KIND_DEREFERENCEABLE = 41
+  };
+
+  enum ComdatSelectionKindCodes {
+    COMDAT_SELECTION_KIND_ANY = 1,
+    COMDAT_SELECTION_KIND_EXACT_MATCH = 2,
+    COMDAT_SELECTION_KIND_LARGEST = 3,
+    COMDAT_SELECTION_KIND_NO_DUPLICATES = 4,
+    COMDAT_SELECTION_KIND_SAME_SIZE = 5,
+  };
+
+} // End bitc namespace
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
new file mode 100644
index 0000000..8cf5735
--- /dev/null
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -0,0 +1,144 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_READERWRITER_H
+#define LLVM_BITCODE_READERWRITER_H
+
+#include "llvm/Support/ErrorOr.h"
+#include <string>
+
+namespace llvm {
+  class BitstreamWriter;
+  class MemoryBuffer;
+  class DataStreamer;
+  class LLVMContext;
+  class Module;
+  class ModulePass;
+  class raw_ostream;
+
+  /// Read the header of the specified bitcode buffer and prepare for lazy
+  /// deserialization of function bodies.  If successful, this takes ownership
+  /// of 'buffer. On error, this *does not* take ownership of Buffer.
+  ErrorOr<Module *> getLazyBitcodeModule(MemoryBuffer *Buffer,
+                                         LLVMContext &Context);
+
+  /// getStreamedBitcodeModule - Read the header of the specified stream
+  /// and prepare for lazy deserialization and streaming of function bodies.
+  /// On error, this returns null, and fills in *ErrMsg with an error
+  /// description if ErrMsg is non-null.
+  Module *getStreamedBitcodeModule(const std::string &name,
+                                   DataStreamer *streamer,
+                                   LLVMContext &Context,
+                                   std::string *ErrMsg = nullptr);
+
+  /// Read the header of the specified bitcode buffer and extract just the
+  /// triple information. If successful, this returns a string and *does not*
+  /// take ownership of 'buffer'. On error, this returns "".
+  std::string getBitcodeTargetTriple(MemoryBuffer *Buffer,
+                                     LLVMContext &Context);
+
+  /// Read the specified bitcode file, returning the module.
+  /// This method *never* takes ownership of Buffer.
+  ErrorOr<Module *> parseBitcodeFile(MemoryBuffer *Buffer,
+                                     LLVMContext &Context);
+
+  /// WriteBitcodeToFile - Write the specified module to the specified
+  /// raw output stream.  For streams where it matters, the given stream
+  /// should be in "binary" mode.
+  void WriteBitcodeToFile(const Module *M, raw_ostream &Out);
+
+
+  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
+  /// for an LLVM IR bitcode wrapper.
+  ///
+  inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+                               const unsigned char *BufEnd) {
+    // See if you can find the hidden message in the magic bytes :-).
+    // (Hint: it's a little-endian encoding.)
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 0xDE &&
+           BufPtr[1] == 0xC0 &&
+           BufPtr[2] == 0x17 &&
+           BufPtr[3] == 0x0B;
+  }
+
+  /// isRawBitcode - Return true if the given bytes are the magic bytes for
+  /// raw LLVM IR bitcode (without a wrapper).
+  ///
+  inline bool isRawBitcode(const unsigned char *BufPtr,
+                           const unsigned char *BufEnd) {
+    // These bytes sort of have a hidden message, but it's not in
+    // little-endian this time, and it's a little redundant.
+    return BufPtr != BufEnd &&
+           BufPtr[0] == 'B' &&
+           BufPtr[1] == 'C' &&
+           BufPtr[2] == 0xc0 &&
+           BufPtr[3] == 0xde;
+  }
+
+  /// isBitcode - Return true if the given bytes are the magic bytes for
+  /// LLVM IR bitcode, either with or without a wrapper.
+  ///
+  inline bool isBitcode(const unsigned char *BufPtr,
+                        const unsigned char *BufEnd) {
+    return isBitcodeWrapper(BufPtr, BufEnd) ||
+           isRawBitcode(BufPtr, BufEnd);
+  }
+
+  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
+  /// header for padding or other reasons.  The format of this header is:
+  ///
+  /// struct bc_header {
+  ///   uint32_t Magic;         // 0x0B17C0DE
+  ///   uint32_t Version;       // Version, currently always 0.
+  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
+  ///   ... potentially other gunk ...
+  /// };
+  ///
+  /// This function is called when we find a file with a matching magic number.
+  /// In this case, skip down to the subsection of the file that is actually a
+  /// BC file.
+  /// If 'VerifyBufferSize' is true, check that the buffer is large enough to
+  /// contain the whole bitcode file.
+  inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
+                                       const unsigned char *&BufEnd,
+                                       bool VerifyBufferSize) {
+    enum {
+      KnownHeaderSize = 4*4,  // Size of header we read.
+      OffsetField = 2*4,      // Offset in bytes to Offset field.
+      SizeField = 3*4         // Offset in bytes to Size field.
+    };
+
+    // Must contain the header!
+    if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+    unsigned Offset = ( BufPtr[OffsetField  ]        |
+                       (BufPtr[OffsetField+1] << 8)  |
+                       (BufPtr[OffsetField+2] << 16) |
+                       (BufPtr[OffsetField+3] << 24));
+    unsigned Size   = ( BufPtr[SizeField    ]        |
+                       (BufPtr[SizeField  +1] << 8)  |
+                       (BufPtr[SizeField  +2] << 16) |
+                       (BufPtr[SizeField  +3] << 24));
+
+    // Verify that Offset+Size fits in the file.
+    if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
+      return true;
+    BufPtr += Offset;
+    BufEnd = BufPtr+Size;
+    return false;
+  }
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
new file mode 100644
index 0000000..b791ba0
--- /dev/null
+++ b/include/llvm/CodeGen/Analysis.h
@@ -0,0 +1,102 @@
+//===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- 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 several CodeGen-specific LLVM IR analysis utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ANALYSIS_H
+#define LLVM_CODEGEN_ANALYSIS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+
+namespace llvm {
+class GlobalVariable;
+class TargetLoweringBase;
+class TargetLowering;
+class TargetMachine;
+class SDNode;
+class SDValue;
+class SelectionDAG;
+struct EVT;
+
+/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
+/// of insertvalue or extractvalue indices that identify a member, return
+/// the linearized index of the start of the member.
+///
+unsigned ComputeLinearIndex(Type *Ty,
+                            const unsigned *Indices,
+                            const unsigned *IndicesEnd,
+                            unsigned CurIndex = 0);
+
+inline unsigned ComputeLinearIndex(Type *Ty,
+                                   ArrayRef<unsigned> Indices,
+                                   unsigned CurIndex = 0) {
+  return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
+}
+
+/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
+/// EVTs that represent all the individual underlying
+/// non-aggregate types that comprise it.
+///
+/// If Offsets is non-null, it points to a vector to be filled in
+/// with the in-memory offsets of each of the individual values.
+///
+void ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
+                     SmallVectorImpl<EVT> &ValueVTs,
+                     SmallVectorImpl<uint64_t> *Offsets = nullptr,
+                     uint64_t StartingOffset = 0);
+
+/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
+GlobalVariable *ExtractTypeInfo(Value *V);
+
+/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being
+/// processed uses a memory 'm' constraint.
+bool hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos,
+                               const TargetLowering &TLI);
+
+/// getFCmpCondCode - Return the ISD condition code corresponding to
+/// the given LLVM IR floating-point condition code.  This includes
+/// consideration of global floating-point math flags.
+///
+ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred);
+
+/// getFCmpCodeWithoutNaN - Given an ISD condition code comparing floats,
+/// return the equivalent code if we're allowed to assume that NaNs won't occur.
+ISD::CondCode getFCmpCodeWithoutNaN(ISD::CondCode CC);
+
+/// getICmpCondCode - Return the ISD condition code corresponding to
+/// the given LLVM IR integer condition code.
+///
+ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
+
+/// Test if the given instruction is in a position to be optimized
+/// with a tail-call. This roughly means that it's in a block with
+/// a return and there's nothing that needs to be scheduled
+/// between it and the return.
+///
+/// This function only tests target-independent requirements.
+bool isInTailCallPosition(ImmutableCallSite CS, const TargetMachine &TM);
+
+/// Test if given that the input instruction is in the tail call position if the
+/// return type or any attributes of the function will inhibit tail call
+/// optimization.
+bool returnTypeIsEligibleForTailCall(const Function *F,
+                                     const Instruction *I,
+                                     const ReturnInst *Ret,
+                                     const TargetLoweringBase &TLI);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
new file mode 100644
index 0000000..de14c1a
--- /dev/null
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -0,0 +1,515 @@
+//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the base class for target specific
+// asm writers.  This class primarily handles common functionality used by
+// all asm writers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTER_H
+#define LLVM_CODEGEN_ASMPRINTER_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+class AsmPrinterHandler;
+class BlockAddress;
+class ByteStreamer;
+class GCStrategy;
+class Constant;
+class ConstantArray;
+class GCMetadataPrinter;
+class GlobalValue;
+class GlobalVariable;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineInstr;
+class MachineLocation;
+class MachineLoopInfo;
+class MachineLoop;
+class MachineConstantPoolValue;
+class MachineJumpTableInfo;
+class MachineModuleInfo;
+class MCAsmInfo;
+class MCCFIInstruction;
+class MCContext;
+class MCInst;
+class MCInstrInfo;
+class MCSection;
+class MCStreamer;
+class MCSubtargetInfo;
+class MCSymbol;
+class MDNode;
+class DwarfDebug;
+class Mangler;
+class TargetLoweringObjectFile;
+class DataLayout;
+class TargetMachine;
+
+/// This class is intended to be used as a driving class for all asm writers.
+class AsmPrinter : public MachineFunctionPass {
+public:
+  /// Target machine description.
+  ///
+  TargetMachine &TM;
+
+  /// Target Asm Printer information.
+  ///
+  const MCAsmInfo *MAI;
+
+  const MCInstrInfo *MII;
+  /// This is the context for the output file that we are streaming. This owns
+  /// all of the global MC-related objects for the generated translation unit.
+  MCContext &OutContext;
+
+  /// This is the MCStreamer object for the file we are generating. This
+  /// contains the transient state for the current translation unit that we are
+  /// generating (such as the current section etc).
+  MCStreamer &OutStreamer;
+
+  /// The current machine function.
+  const MachineFunction *MF;
+
+  /// This is a pointer to the current MachineModuleInfo.
+  MachineModuleInfo *MMI;
+
+  /// Name-mangler for global names.
+  ///
+  Mangler *Mang;
+
+  /// The symbol for the current function. This is recalculated at the beginning
+  /// of each call to runOnMachineFunction().
+  ///
+  MCSymbol *CurrentFnSym;
+
+  /// The symbol used to represent the start of the current function for the
+  /// purpose of calculating its size (e.g. using the .size directive). By
+  /// default, this is equal to CurrentFnSym.
+  MCSymbol *CurrentFnSymForSize;
+
+private:
+  // The garbage collection metadata printer table.
+  void *GCMetadataPrinters; // Really a DenseMap.
+
+  /// Emit comments in assembly output if this is true.
+  ///
+  bool VerboseAsm;
+  static char ID;
+
+  /// If VerboseAsm is set, a pointer to the loop info for this function.
+  MachineLoopInfo *LI;
+
+  struct HandlerInfo {
+    AsmPrinterHandler *Handler;
+    const char *TimerName, *TimerGroupName;
+    HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
+                const char *TimerGroupName)
+        : Handler(Handler), TimerName(TimerName),
+          TimerGroupName(TimerGroupName) {}
+  };
+  /// A vector of all debug/EH info emitters we should use. This vector
+  /// maintains ownership of the emitters.
+  SmallVector<HandlerInfo, 1> Handlers;
+
+  /// If the target supports dwarf debug info, this pointer is non-null.
+  DwarfDebug *DD;
+
+protected:
+  explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
+
+public:
+  virtual ~AsmPrinter();
+
+  DwarfDebug *getDwarfDebug() { return DD; }
+
+  /// Return true if assembly output should contain comments.
+  ///
+  bool isVerbose() const { return VerboseAsm; }
+
+  /// Return a unique ID for the current function.
+  ///
+  unsigned getFunctionNumber() const;
+
+  /// Return information about object file lowering.
+  const TargetLoweringObjectFile &getObjFileLowering() const;
+
+  /// Return information about data layout.
+  const DataLayout &getDataLayout() const;
+
+  /// Return information about subtarget.
+  const MCSubtargetInfo &getSubtargetInfo() const;
+
+  void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
+
+  /// Return the target triple string.
+  StringRef getTargetTriple() const;
+
+  /// Return the current section we are emitting to.
+  const MCSection *getCurrentSection() const;
+
+  void getNameWithPrefix(SmallVectorImpl<char> &Name,
+                         const GlobalValue *GV) const;
+
+  MCSymbol *getSymbol(const GlobalValue *GV) const;
+
+  //===------------------------------------------------------------------===//
+  // MachineFunctionPass Implementation.
+  //===------------------------------------------------------------------===//
+
+  /// Record analysis usage.
+  ///
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// Set up the AsmPrinter when we are working on a new module. If your pass
+  /// overrides this, it must make sure to explicitly call this implementation.
+  bool doInitialization(Module &M) override;
+
+  /// Shut down the asmprinter. If you override this in your pass, you must make
+  /// sure to call it explicitly.
+  bool doFinalization(Module &M) override;
+
+  /// Emit the specified function out to the OutStreamer.
+  bool runOnMachineFunction(MachineFunction &MF) override {
+    SetupMachineFunction(MF);
+    EmitFunctionHeader();
+    EmitFunctionBody();
+    return false;
+  }
+
+  //===------------------------------------------------------------------===//
+  // Coarse grained IR lowering routines.
+  //===------------------------------------------------------------------===//
+
+  /// This should be called when a new MachineFunction is being processed from
+  /// runOnMachineFunction.
+  void SetupMachineFunction(MachineFunction &MF);
+
+  /// This method emits the header for the current function.
+  void EmitFunctionHeader();
+
+  /// This method emits the body and trailer for a function.
+  void EmitFunctionBody();
+
+  void emitCFIInstruction(const MachineInstr &MI);
+
+  enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
+  CFIMoveType needsCFIMoves();
+
+  bool needsSEHMoves();
+
+  /// Print to the current output stream assembly representations of the
+  /// constants in the constant pool MCP. This is used to print out constants
+  /// which have been "spilled to memory" by the code generator.
+  ///
+  virtual void EmitConstantPool();
+
+  /// Print assembly representations of the jump tables used by the current
+  /// function to the current output stream.
+  ///
+  void EmitJumpTableInfo();
+
+  /// Emit the specified global variable to the .s file.
+  virtual void EmitGlobalVariable(const GlobalVariable *GV);
+
+  /// Check to see if the specified global is a special global used by LLVM. If
+  /// so, emit it and return true, otherwise do nothing and return false.
+  bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
+
+  /// Emit an alignment directive to the specified power of two boundary. For
+  /// example, if you pass in 3 here, you will get an 8 byte alignment. If a
+  /// global value is specified, and if that global has an explicit alignment
+  /// requested, it will override the alignment request if required for
+  /// correctness.
+  ///
+  void EmitAlignment(unsigned NumBits, const GlobalObject *GO = nullptr) const;
+
+  /// This method prints the label for the specified MachineBasicBlock, an
+  /// alignment (if present) and a comment describing it if appropriate.
+  void EmitBasicBlockStart(const MachineBasicBlock &MBB) const;
+
+  /// \brief Print a general LLVM constant to the .s file.
+  void EmitGlobalConstant(const Constant *CV);
+
+  //===------------------------------------------------------------------===//
+  // Overridable Hooks
+  //===------------------------------------------------------------------===//
+
+  // Targets can, or in the case of EmitInstruction, must implement these to
+  // customize output.
+
+  /// This virtual method can be overridden by targets that want to emit
+  /// something at the start of their file.
+  virtual void EmitStartOfAsmFile(Module &) {}
+
+  /// This virtual method can be overridden by targets that want to emit
+  /// something at the end of their file.
+  virtual void EmitEndOfAsmFile(Module &) {}
+
+  /// Targets can override this to emit stuff before the first basic block in
+  /// the function.
+  virtual void EmitFunctionBodyStart() {}
+
+  /// Targets can override this to emit stuff after the last basic block in the
+  /// function.
+  virtual void EmitFunctionBodyEnd() {}
+
+  /// Targets should implement this to emit instructions.
+  virtual void EmitInstruction(const MachineInstr *) {
+    llvm_unreachable("EmitInstruction not implemented");
+  }
+
+  /// Return the symbol for the specified constant pool entry.
+  virtual MCSymbol *GetCPISymbol(unsigned CPID) const;
+
+  virtual void EmitFunctionEntryLabel();
+
+  virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+
+  /// Targets can override this to change how global constants that are part of
+  /// a C++ static/global constructor list are emitted.
+  virtual void EmitXXStructor(const Constant *CV) { EmitGlobalConstant(CV); }
+
+  /// Return true if the basic block has exactly one predecessor and the control
+  /// transfer mechanism between the predecessor and this block is a
+  /// fall-through.
+  virtual bool
+  isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
+
+  /// Targets can override this to customize the output of IMPLICIT_DEF
+  /// instructions in verbose mode.
+  virtual void emitImplicitDef(const MachineInstr *MI) const;
+
+  //===------------------------------------------------------------------===//
+  // Symbol Lowering Routines.
+  //===------------------------------------------------------------------===//
+public:
+  /// Return the MCSymbol corresponding to the assembler temporary label with
+  /// the specified stem and unique ID.
+  MCSymbol *GetTempSymbol(Twine Name, unsigned ID) const;
+
+  /// Return an assembler temporary label with the specified stem.
+  MCSymbol *GetTempSymbol(Twine Name) const;
+
+  /// Return the MCSymbol for a private symbol with global value name as its
+  /// base, with the specified suffix.
+  MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
+                                         StringRef Suffix) const;
+
+  /// Return the MCSymbol for the specified ExternalSymbol.
+  MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
+
+  /// Return the symbol for the specified jump table entry.
+  MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
+
+  /// Return the symbol for the specified jump table .set
+  /// FIXME: privatize to AsmPrinter.
+  MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const;
+
+  /// Return the MCSymbol used to satisfy BlockAddress uses of the specified
+  /// basic block.
+  MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
+  MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const;
+
+  //===------------------------------------------------------------------===//
+  // Emission Helper Routines.
+  //===------------------------------------------------------------------===//
+public:
+  /// This is just convenient handler for printing offsets.
+  void printOffset(int64_t Offset, raw_ostream &OS) const;
+
+  /// Emit a byte directive and value.
+  ///
+  void EmitInt8(int Value) const;
+
+  /// Emit a short directive and value.
+  ///
+  void EmitInt16(int Value) const;
+
+  /// Emit a long directive and value.
+  ///
+  void EmitInt32(int Value) const;
+
+  /// Emit something like ".long Hi-Lo" where the size in bytes of the directive
+  /// is specified by Size and Hi/Lo specify the labels.  This implicitly uses
+  /// .set if it is available.
+  void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
+                           unsigned Size) const;
+
+  /// Emit something like ".long Hi+Offset-Lo" where the size in bytes of the
+  /// directive is specified by Size and Hi/Lo specify the labels.  This
+  /// implicitly uses .set if it is available.
+  void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
+                                 const MCSymbol *Lo, unsigned Size) const;
+
+  /// Emit something like ".long Label+Offset" where the size in bytes of the
+  /// directive is specified by Size and Label specifies the label.  This
+  /// implicitly uses .set if it is available.
+  void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
+                           unsigned Size, bool IsSectionRelative = false) const;
+
+  /// Emit something like ".long Label" where the size in bytes of the directive
+  /// is specified by Size and Label specifies the label.
+  void EmitLabelReference(const MCSymbol *Label, unsigned Size,
+                          bool IsSectionRelative = false) const {
+    EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative);
+  }
+
+  //===------------------------------------------------------------------===//
+  // Dwarf Emission Helper Routines
+  //===------------------------------------------------------------------===//
+
+  /// Emit the specified signed leb128 value.
+  void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const;
+
+  /// Emit the specified unsigned leb128 value.
+  void EmitULEB128(uint64_t Value, const char *Desc = nullptr,
+                   unsigned PadTo = 0) const;
+
+  /// Emit a .byte 42 directive for a DW_CFA_xxx value.
+  void EmitCFAByte(unsigned Val) const;
+
+  /// Emit a .byte 42 directive that corresponds to an encoding.  If verbose
+  /// assembly output is enabled, we output comments describing the encoding.
+  /// Desc is a string saying what the encoding is specifying (e.g. "LSDA").
+  void EmitEncodingByte(unsigned Val, const char *Desc = nullptr) const;
+
+  /// Return the size of the encoding in bytes.
+  unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
+
+  /// Emit reference to a ttype global with a specified encoding.
+  void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
+
+  /// Emit the 4-byte offset of Label from the start of its section.  This can
+  /// be done with a special directive if the target supports it (e.g. cygwin)
+  /// or by emitting it as an offset from a label at the start of the section.
+  ///
+  /// SectionLabel is a temporary label emitted at the start of the section
+  /// that Label lives in.
+  void EmitSectionOffset(const MCSymbol *Label,
+                         const MCSymbol *SectionLabel) const;
+
+  /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
+  virtual unsigned getISAEncoding() { return 0; }
+
+  /// \brief Emit a partial DWARF register operation.
+  /// \param MLoc             the register
+  /// \param PieceSize        size and
+  /// \param PieceOffset      offset of the piece in bits, if this is one
+  ///                         piece of an aggregate value.
+  ///
+  /// If size and offset is zero an operation for the entire
+  /// register is emitted: Some targets do not provide a DWARF
+  /// register number for every register.  If this is the case, this
+  /// function will attempt to emit a DWARF register by emitting a
+  /// piece of a super-register or by piecing together multiple
+  /// subregisters that alias the register.
+  void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc,
+                           unsigned PieceSize = 0,
+                           unsigned PieceOffset = 0) const;
+
+  /// Emit dwarf register operation.
+  /// \param Indirect   whether this is a register-indirect address
+  virtual void EmitDwarfRegOp(ByteStreamer &BS, const MachineLocation &MLoc,
+                              bool Indirect) const;
+
+  //===------------------------------------------------------------------===//
+  // Dwarf Lowering Routines
+  //===------------------------------------------------------------------===//
+
+  /// \brief Emit frame instruction to describe the layout of the frame.
+  void emitCFIInstruction(const MCCFIInstruction &Inst) const;
+
+  //===------------------------------------------------------------------===//
+  // Inline Asm Support
+  //===------------------------------------------------------------------===//
+public:
+  // These are hooks that targets can override to implement inline asm
+  // support.  These should probably be moved out of AsmPrinter someday.
+
+  /// Print information related to the specified machine instr that is
+  /// independent of the operand, and may be independent of the instr itself.
+  /// This can be useful for portably encoding the comment character or other
+  /// bits of target-specific knowledge into the asmstrings.  The syntax used is
+  /// ${:comment}.  Targets can override this to add support for their own
+  /// strange codes.
+  virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
+                            const char *Code) const;
+
+  /// Print the specified operand of MI, an INLINEASM instruction, using the
+  /// specified assembler variant.  Targets should override this to format as
+  /// appropriate.  This method can return true if the operand is erroneous.
+  virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+                               unsigned AsmVariant, const char *ExtraCode,
+                               raw_ostream &OS);
+
+  /// Print the specified operand of MI, an INLINEASM instruction, using the
+  /// specified assembler variant as an address. Targets should override this to
+  /// format as appropriate.  This method can return true if the operand is
+  /// erroneous.
+  virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+                                     unsigned AsmVariant, const char *ExtraCode,
+                                     raw_ostream &OS);
+
+  /// Let the target do anything it needs to do after emitting inlineasm.
+  /// This callback can be used restore the original mode in case the
+  /// inlineasm contains directives to switch modes.
+  /// \p StartInfo - the original subtarget info before inline asm
+  /// \p EndInfo   - the final subtarget info after parsing the inline asm,
+  ///                or NULL if the value is unknown.
+  virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
+                                const MCSubtargetInfo *EndInfo) const;
+
+  /// Let the target do anything it needs to do before emitting inlineasm.
+  /// \p StartInfo - the subtarget info before parsing inline asm
+  virtual void emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const;
+
+private:
+  /// Private state for PrintSpecial()
+  // Assign a unique ID to this machine instruction.
+  mutable const MachineInstr *LastMI;
+  mutable unsigned LastFn;
+  mutable unsigned Counter;
+  mutable unsigned SetCounter;
+
+  /// Emit a blob of inline asm to the output streamer.
+  void
+  EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr,
+                InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
+
+  /// This method formats and emits the specified machine instruction that is an
+  /// inline asm.
+  void EmitInlineAsm(const MachineInstr *MI) const;
+
+  //===------------------------------------------------------------------===//
+  // Internal Implementation Details
+  //===------------------------------------------------------------------===//
+
+  /// This emits visibility information about symbol, if this is suported by the
+  /// target.
+  void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+                      bool IsDefinition = true) const;
+
+  void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
+
+  void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+                          const MachineBasicBlock *MBB, unsigned uid) const;
+  void EmitLLVMUsedList(const ConstantArray *InitList);
+  /// Emit llvm.ident metadata in an '.ident' directive.
+  void EmitModuleIdents(Module &M);
+  void EmitXXStructorList(const Constant *List, bool isCtor);
+  GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C);
+};
+}
+
+#endif
diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h
new file mode 100644
index 0000000..0d79b1d
--- /dev/null
+++ b/include/llvm/CodeGen/CalcSpillWeights.h
@@ -0,0 +1,77 @@
+//===---------------- lib/CodeGen/CalcSpillWeights.h ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H
+#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+
+namespace llvm {
+
+  class LiveInterval;
+  class LiveIntervals;
+  class MachineBlockFrequencyInfo;
+  class MachineLoopInfo;
+
+  /// \brief Normalize the spill weight of a live interval
+  ///
+  /// The spill weight of a live interval is computed as:
+  ///
+  ///   (sum(use freq) + sum(def freq)) / (K + size)
+  ///
+  /// @param UseDefFreq Expected number of executed use and def instructions
+  ///                   per function call. Derived from block frequencies.
+  /// @param Size       Size of live interval as returnexd by getSize()
+  ///
+  static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) {
+    // The constant 25 instructions is added to avoid depending too much on
+    // accidental SlotIndex gaps for small intervals. The effect is that small
+    // intervals have a spill weight that is mostly proportional to the number
+    // of uses, while large intervals get a spill weight that is closer to a use
+    // density.
+    return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
+  }
+
+  /// \brief Calculate auxiliary information for a virtual register such as its
+  /// spill weight and allocation hint.
+  class VirtRegAuxInfo {
+  public:
+    typedef float (*NormalizingFn)(float, unsigned);
+
+  private:
+    MachineFunction &MF;
+    LiveIntervals &LIS;
+    const MachineLoopInfo &Loops;
+    const MachineBlockFrequencyInfo &MBFI;
+    DenseMap<unsigned, float> Hint;
+    NormalizingFn normalize;
+
+  public:
+    VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
+                   const MachineLoopInfo &loops,
+                   const MachineBlockFrequencyInfo &mbfi,
+                   NormalizingFn norm = normalizeSpillWeight)
+        : MF(mf), LIS(lis), Loops(loops), MBFI(mbfi), normalize(norm) {}
+
+    /// \brief (re)compute li's spill weight and allocation hint.
+    void calculateSpillWeightAndHint(LiveInterval &li);
+  };
+
+  /// \brief Compute spill weights and allocation hints for all virtual register
+  /// live intervals.
+  void calculateSpillWeightsAndHints(LiveIntervals &LIS, MachineFunction &MF,
+                                     const MachineLoopInfo &MLI,
+                                     const MachineBlockFrequencyInfo &MBFI,
+                                     VirtRegAuxInfo::NormalizingFn norm =
+                                         normalizeSpillWeight);
+}
+
+#endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
new file mode 100644
index 0000000..abe00a1
--- /dev/null
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -0,0 +1,481 @@
+//===-- llvm/CallingConvLower.h - 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 file declares the CCState and CCValAssign classes, used for lowering
+// and implementing calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H
+#define LLVM_CODEGEN_CALLINGCONVLOWER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/Target/TargetCallingConv.h"
+
+namespace llvm {
+class CCState;
+class MVT;
+class TargetMachine;
+class TargetRegisterInfo;
+
+/// CCValAssign - Represent assignment of one arg/retval to a location.
+class CCValAssign {
+public:
+  enum LocInfo {
+    Full,      // The value fills the full location.
+    SExt,      // The value is sign extended in the location.
+    ZExt,      // The value is zero extended in the location.
+    AExt,      // The value is extended with undefined upper bits.
+    BCvt,      // The value is bit-converted in the location.
+    VExt,      // The value is vector-widened in the location.
+               // FIXME: Not implemented yet. Code that uses AExt to mean
+               // vector-widen should be fixed to use VExt instead.
+    FPExt,     // The floating-point value is fp-extended in the location.
+    Indirect,  // The location contains pointer to the value.
+    SExtUpper, // The value is in the upper bits of the location and should be
+               // sign extended when retrieved.
+    ZExtUpper, // The value is in the upper bits of the location and should be
+               // zero extended when retrieved.
+    AExtUpper  // The value is in the upper bits of the location and should be
+               // extended with undefined upper bits when retrieved.
+    // TODO: a subset of the value is in the location.
+  };
+
+private:
+  /// ValNo - This is the value number begin assigned (e.g. an argument number).
+  unsigned ValNo;
+
+  /// Loc is either a stack offset or a register number.
+  unsigned Loc;
+
+  /// isMem - True if this is a memory loc, false if it is a register loc.
+  unsigned isMem : 1;
+
+  /// isCustom - True if this arg/retval requires special handling.
+  unsigned isCustom : 1;
+
+  /// Information about how the value is assigned.
+  LocInfo HTP : 6;
+
+  /// ValVT - The type of the value being assigned.
+  MVT ValVT;
+
+  /// LocVT - The type of the location being assigned to.
+  MVT LocVT;
+public:
+
+  static CCValAssign getReg(unsigned ValNo, MVT ValVT,
+                            unsigned RegNo, MVT LocVT,
+                            LocInfo HTP) {
+    CCValAssign Ret;
+    Ret.ValNo = ValNo;
+    Ret.Loc = RegNo;
+    Ret.isMem = false;
+    Ret.isCustom = false;
+    Ret.HTP = HTP;
+    Ret.ValVT = ValVT;
+    Ret.LocVT = LocVT;
+    return Ret;
+  }
+
+  static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT,
+                                  unsigned RegNo, MVT LocVT,
+                                  LocInfo HTP) {
+    CCValAssign Ret;
+    Ret = getReg(ValNo, ValVT, RegNo, LocVT, HTP);
+    Ret.isCustom = true;
+    return Ret;
+  }
+
+  static CCValAssign getMem(unsigned ValNo, MVT ValVT,
+                            unsigned Offset, MVT LocVT,
+                            LocInfo HTP) {
+    CCValAssign Ret;
+    Ret.ValNo = ValNo;
+    Ret.Loc = Offset;
+    Ret.isMem = true;
+    Ret.isCustom = false;
+    Ret.HTP = HTP;
+    Ret.ValVT = ValVT;
+    Ret.LocVT = LocVT;
+    return Ret;
+  }
+
+  static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT,
+                                  unsigned Offset, MVT LocVT,
+                                  LocInfo HTP) {
+    CCValAssign Ret;
+    Ret = getMem(ValNo, ValVT, Offset, LocVT, HTP);
+    Ret.isCustom = true;
+    return Ret;
+  }
+
+  // There is no need to differentiate between a pending CCValAssign and other
+  // kinds, as they are stored in a different list.
+  static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT,
+                                LocInfo HTP) {
+    return getReg(ValNo, ValVT, 0, LocVT, HTP);
+  }
+
+  void convertToReg(unsigned RegNo) {
+    Loc = RegNo;
+    isMem = false;
+  }
+
+  void convertToMem(unsigned Offset) {
+    Loc = Offset;
+    isMem = true;
+  }
+
+  unsigned getValNo() const { return ValNo; }
+  MVT getValVT() const { return ValVT; }
+
+  bool isRegLoc() const { return !isMem; }
+  bool isMemLoc() const { return isMem; }
+
+  bool needsCustom() const { return isCustom; }
+
+  unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+  unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
+  MVT getLocVT() const { return LocVT; }
+
+  LocInfo getLocInfo() const { return HTP; }
+  bool isExtInLoc() const {
+    return (HTP == AExt || HTP == SExt || HTP == ZExt);
+  }
+
+  bool isUpperBitsInLoc() const {
+    return HTP == AExtUpper || HTP == SExtUpper || HTP == ZExtUpper;
+  }
+};
+
+/// CCAssignFn - This function assigns a location for Val, updating State to
+/// reflect the change.  It returns 'true' if it failed to handle Val.
+typedef bool CCAssignFn(unsigned ValNo, MVT ValVT,
+                        MVT LocVT, CCValAssign::LocInfo LocInfo,
+                        ISD::ArgFlagsTy ArgFlags, CCState &State);
+
+/// CCCustomFn - This function assigns a location for Val, possibly updating
+/// all args to reflect changes and indicates if it handled it. It must set
+/// isCustom if it handles the arg and returns true.
+typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT,
+                        MVT &LocVT, CCValAssign::LocInfo &LocInfo,
+                        ISD::ArgFlagsTy &ArgFlags, CCState &State);
+
+/// ParmContext - This enum tracks whether calling convention lowering is in
+/// the context of prologue or call generation. Not all backends make use of
+/// this information.
+typedef enum { Unknown, Prologue, Call } ParmContext;
+
+/// CCState - This class holds information needed while lowering arguments and
+/// return values.  It captures which registers are already assigned and which
+/// stack slots are used.  It provides accessors to allocate these values.
+class CCState {
+private:
+  CallingConv::ID CallingConv;
+  bool IsVarArg;
+  MachineFunction &MF;
+  const TargetMachine &TM;
+  const TargetRegisterInfo &TRI;
+  SmallVectorImpl<CCValAssign> &Locs;
+  LLVMContext &Context;
+
+  unsigned StackOffset;
+  SmallVector<uint32_t, 16> UsedRegs;
+  SmallVector<CCValAssign, 4> PendingLocs;
+
+  // ByValInfo and SmallVector<ByValInfo, 4> ByValRegs:
+  //
+  // Vector of ByValInfo instances (ByValRegs) is introduced for byval registers
+  // tracking.
+  // Or, in another words it tracks byval parameters that are stored in
+  // general purpose registers.
+  //
+  // For 4 byte stack alignment,
+  // instance index means byval parameter number in formal
+  // arguments set. Assume, we have some "struct_type" with size = 4 bytes,
+  // then, for function "foo":
+  //
+  // i32 foo(i32 %p, %struct_type* %r, i32 %s, %struct_type* %t)
+  //
+  // ByValRegs[0] describes how "%r" is stored (Begin == r1, End == r2)
+  // ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4).
+  //
+  // In case of 8 bytes stack alignment,
+  // ByValRegs may also contain information about wasted registers.
+  // In function shown above, r3 would be wasted according to AAPCS rules.
+  // And in that case ByValRegs[1].Waste would be "true".
+  // ByValRegs vector size still would be 2,
+  // while "%t" goes to the stack: it wouldn't be described in ByValRegs.
+  //
+  // Supposed use-case for this collection:
+  // 1. Initially ByValRegs is empty, InRegsParamsProcessed is 0.
+  // 2. HandleByVal fillups ByValRegs.
+  // 3. Argument analysis (LowerFormatArguments, for example). After
+  // some byval argument was analyzed, InRegsParamsProcessed is increased.
+  struct ByValInfo {
+    ByValInfo(unsigned B, unsigned E, bool IsWaste = false) :
+      Begin(B), End(E), Waste(IsWaste) {}
+    // First register allocated for current parameter.
+    unsigned Begin;
+
+    // First after last register allocated for current parameter.
+    unsigned End;
+
+    // Means that current range of registers doesn't belong to any
+    // parameters. It was wasted due to stack alignment rules.
+    // For more information see:
+    // AAPCS, 5.5 Parameter Passing, Stage C, C.3.
+    bool Waste;
+  };
+  SmallVector<ByValInfo, 4 > ByValRegs;
+
+  // InRegsParamsProcessed - shows how many instances of ByValRegs was proceed
+  // during argument analysis.
+  unsigned InRegsParamsProcessed;
+
+protected:
+  ParmContext CallOrPrologue;
+
+public:
+  CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
+          const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs,
+          LLVMContext &C);
+
+  void addLoc(const CCValAssign &V) {
+    Locs.push_back(V);
+  }
+
+  LLVMContext &getContext() const { return Context; }
+  const TargetMachine &getTarget() const { return TM; }
+  MachineFunction &getMachineFunction() const { return MF; }
+  CallingConv::ID getCallingConv() const { return CallingConv; }
+  bool isVarArg() const { return IsVarArg; }
+
+  unsigned getNextStackOffset() const { return StackOffset; }
+
+  /// isAllocated - Return true if the specified register (or an alias) is
+  /// allocated.
+  bool isAllocated(unsigned Reg) const {
+    return UsedRegs[Reg/32] & (1 << (Reg&31));
+  }
+
+  /// AnalyzeFormalArguments - Analyze an array of argument values,
+  /// incorporating info about the formals into this state.
+  void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
+                              CCAssignFn Fn);
+
+  /// AnalyzeReturn - Analyze the returned values of a return,
+  /// incorporating info about the result values into this state.
+  void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
+                     CCAssignFn Fn);
+
+  /// CheckReturn - Analyze the return values of a function, returning
+  /// true if the return can be performed without sret-demotion, and
+  /// false otherwise.
+  bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+                   CCAssignFn Fn);
+
+  /// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
+  /// incorporating info about the passed values into this state.
+  void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
+                           CCAssignFn Fn);
+
+  /// AnalyzeCallOperands - Same as above except it takes vectors of types
+  /// and argument flags.
+  void AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
+                           SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
+                           CCAssignFn Fn);
+
+  /// AnalyzeCallResult - Analyze the return values of a call,
+  /// incorporating info about the passed values into this state.
+  void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
+                         CCAssignFn Fn);
+
+  /// AnalyzeCallResult - Same as above except it's specialized for calls which
+  /// produce a single value.
+  void AnalyzeCallResult(MVT VT, CCAssignFn Fn);
+
+  /// getFirstUnallocated - Return the first unallocated register in the set, or
+  /// NumRegs if they are all allocated.
+  unsigned getFirstUnallocated(const MCPhysReg *Regs, unsigned NumRegs) const {
+    for (unsigned i = 0; i != NumRegs; ++i)
+      if (!isAllocated(Regs[i]))
+        return i;
+    return NumRegs;
+  }
+
+  /// AllocateReg - Attempt to allocate one register.  If it is not available,
+  /// return zero.  Otherwise, return the register, marking it and any aliases
+  /// as allocated.
+  unsigned AllocateReg(unsigned Reg) {
+    if (isAllocated(Reg)) return 0;
+    MarkAllocated(Reg);
+    return Reg;
+  }
+
+  /// Version of AllocateReg with extra register to be shadowed.
+  unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
+    if (isAllocated(Reg)) return 0;
+    MarkAllocated(Reg);
+    MarkAllocated(ShadowReg);
+    return Reg;
+  }
+
+  /// AllocateReg - Attempt to allocate one of the specified registers.  If none
+  /// are available, return zero.  Otherwise, return the first one available,
+  /// marking it and any aliases as allocated.
+  unsigned AllocateReg(const MCPhysReg *Regs, unsigned NumRegs) {
+    unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+    if (FirstUnalloc == NumRegs)
+      return 0;    // Didn't find the reg.
+
+    // Mark the register and any aliases as allocated.
+    unsigned Reg = Regs[FirstUnalloc];
+    MarkAllocated(Reg);
+    return Reg;
+  }
+
+  /// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive
+  /// registers. If this is not possible, return zero. Otherwise, return the first
+  /// register of the block that were allocated, marking the entire block as allocated.
+  unsigned AllocateRegBlock(const uint16_t *Regs, unsigned NumRegs, unsigned RegsRequired) {
+    for (unsigned StartIdx = 0; StartIdx <= NumRegs - RegsRequired; ++StartIdx) {
+      bool BlockAvailable = true;
+      // Check for already-allocated regs in this block
+      for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {
+        if (isAllocated(Regs[StartIdx + BlockIdx])) {
+          BlockAvailable = false;
+          break;
+        }
+      }
+      if (BlockAvailable) {
+        // Mark the entire block as allocated
+        for (unsigned BlockIdx = 0; BlockIdx < RegsRequired; ++BlockIdx) {
+          MarkAllocated(Regs[StartIdx + BlockIdx]);
+        }
+        return Regs[StartIdx];
+      }
+    }
+    // No block was available
+    return 0;
+  }
+
+  /// Version of AllocateReg with list of registers to be shadowed.
+  unsigned AllocateReg(const MCPhysReg *Regs, const MCPhysReg *ShadowRegs,
+                       unsigned NumRegs) {
+    unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+    if (FirstUnalloc == NumRegs)
+      return 0;    // Didn't find the reg.
+
+    // Mark the register and any aliases as allocated.
+    unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
+    MarkAllocated(Reg);
+    MarkAllocated(ShadowReg);
+    return Reg;
+  }
+
+  /// AllocateStack - Allocate a chunk of stack space with the specified size
+  /// and alignment.
+  unsigned AllocateStack(unsigned Size, unsigned Align) {
+    assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
+    StackOffset = ((StackOffset + Align-1) & ~(Align-1));
+    unsigned Result = StackOffset;
+    StackOffset += Size;
+    MF.getFrameInfo()->ensureMaxAlignment(Align);
+    return Result;
+  }
+
+  /// Version of AllocateStack with extra register to be shadowed.
+  unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) {
+    MarkAllocated(ShadowReg);
+    return AllocateStack(Size, Align);
+  }
+
+  /// Version of AllocateStack with list of extra registers to be shadowed.
+  /// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
+  unsigned AllocateStack(unsigned Size, unsigned Align,
+                         const MCPhysReg *ShadowRegs, unsigned NumShadowRegs) {
+    for (unsigned i = 0; i < NumShadowRegs; ++i)
+      MarkAllocated(ShadowRegs[i]);
+    return AllocateStack(Size, Align);
+  }
+
+  // HandleByVal - Allocate a stack slot large enough to pass an argument by
+  // value. The size and alignment information of the argument is encoded in its
+  // parameter attribute.
+  void HandleByVal(unsigned ValNo, MVT ValVT,
+                   MVT LocVT, CCValAssign::LocInfo LocInfo,
+                   int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
+
+  // Returns count of byval arguments that are to be stored (even partly)
+  // in registers.
+  unsigned getInRegsParamsCount() const { return ByValRegs.size(); }
+
+  // Returns count of byval in-regs arguments proceed.
+  unsigned getInRegsParamsProcessed() const { return InRegsParamsProcessed; }
+
+  // Get information about N-th byval parameter that is stored in registers.
+  // Here "ByValParamIndex" is N.
+  void getInRegsParamInfo(unsigned InRegsParamRecordIndex,
+                          unsigned& BeginReg, unsigned& EndReg) const {
+    assert(InRegsParamRecordIndex < ByValRegs.size() &&
+           "Wrong ByVal parameter index");
+
+    const ByValInfo& info = ByValRegs[InRegsParamRecordIndex];
+    BeginReg = info.Begin;
+    EndReg = info.End;
+  }
+
+  // Add information about parameter that is kept in registers.
+  void addInRegsParamInfo(unsigned RegBegin, unsigned RegEnd) {
+    ByValRegs.push_back(ByValInfo(RegBegin, RegEnd));
+  }
+
+  // Goes either to next byval parameter (excluding "waste" record), or
+  // to the end of collection.
+  // Returns false, if end is reached.
+  bool nextInRegsParam() {
+    unsigned e = ByValRegs.size();
+    if (InRegsParamsProcessed < e)
+      ++InRegsParamsProcessed;
+    return InRegsParamsProcessed < e;
+  }
+
+  // Clear byval registers tracking info.
+  void clearByValRegsInfo() {
+    InRegsParamsProcessed = 0;
+    ByValRegs.clear();
+  }
+
+  // Rewind byval registers tracking info.
+  void rewindByValRegsInfo() {
+    InRegsParamsProcessed = 0;
+  }
+
+  ParmContext getCallOrPrologue() const { return CallOrPrologue; }
+
+  // Get list of pending assignments
+  SmallVectorImpl<llvm::CCValAssign> &getPendingLocs() {
+    return PendingLocs;
+  }
+
+private:
+  /// MarkAllocated - Mark a register and all of its aliases as allocated.
+  void MarkAllocated(unsigned Reg);
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
new file mode 100644
index 0000000..449d934
--- /dev/null
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -0,0 +1,251 @@
+//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains codegen-specific flags that are shared between different
+// command line tools. The tools "llc" and "opt" both use this file to prevent
+// flag duplication.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_COMMANDFLAGS_H
+#define LLVM_CODEGEN_COMMANDFLAGS_H
+
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <string>
+using namespace llvm;
+
+cl::opt<std::string>
+MArch("march", cl::desc("Architecture to generate code for (see --version)"));
+
+cl::opt<std::string>
+MCPU("mcpu",
+     cl::desc("Target a specific cpu type (-mcpu=help for details)"),
+     cl::value_desc("cpu-name"),
+     cl::init(""));
+
+cl::list<std::string>
+MAttrs("mattr",
+       cl::CommaSeparated,
+       cl::desc("Target specific attributes (-mattr=help for details)"),
+       cl::value_desc("a1,+a2,-a3,..."));
+
+cl::opt<Reloc::Model>
+RelocModel("relocation-model",
+           cl::desc("Choose relocation model"),
+           cl::init(Reloc::Default),
+           cl::values(
+              clEnumValN(Reloc::Default, "default",
+                      "Target default relocation model"),
+              clEnumValN(Reloc::Static, "static",
+                      "Non-relocatable code"),
+              clEnumValN(Reloc::PIC_, "pic",
+                      "Fully relocatable, position independent code"),
+              clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
+                      "Relocatable external references, non-relocatable code"),
+              clEnumValEnd));
+
+cl::opt<llvm::CodeModel::Model>
+CMModel("code-model",
+        cl::desc("Choose code model"),
+        cl::init(CodeModel::Default),
+        cl::values(clEnumValN(CodeModel::Default, "default",
+                              "Target default code model"),
+                   clEnumValN(CodeModel::Small, "small",
+                              "Small code model"),
+                   clEnumValN(CodeModel::Kernel, "kernel",
+                              "Kernel code model"),
+                   clEnumValN(CodeModel::Medium, "medium",
+                              "Medium code model"),
+                   clEnumValN(CodeModel::Large, "large",
+                              "Large code model"),
+                   clEnumValEnd));
+
+cl::opt<TargetMachine::CodeGenFileType>
+FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
+  cl::desc("Choose a file type (not all types are supported by all targets):"),
+  cl::values(
+             clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
+                        "Emit an assembly ('.s') file"),
+             clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
+                        "Emit a native object ('.o') file"),
+             clEnumValN(TargetMachine::CGFT_Null, "null",
+                        "Emit nothing, for performance testing"),
+             clEnumValEnd));
+
+cl::opt<bool>
+DisableRedZone("disable-red-zone",
+               cl::desc("Do not emit code that uses the red zone."),
+               cl::init(false));
+
+cl::opt<bool>
+EnableFPMAD("enable-fp-mad",
+            cl::desc("Enable less precise MAD instructions to be generated"),
+            cl::init(false));
+
+cl::opt<bool>
+DisableFPElim("disable-fp-elim",
+              cl::desc("Disable frame pointer elimination optimization"),
+              cl::init(false));
+
+cl::opt<bool>
+EnableUnsafeFPMath("enable-unsafe-fp-math",
+                cl::desc("Enable optimizations that may decrease FP precision"),
+                cl::init(false));
+
+cl::opt<bool>
+EnableNoInfsFPMath("enable-no-infs-fp-math",
+                cl::desc("Enable FP math optimizations that assume no +-Infs"),
+                cl::init(false));
+
+cl::opt<bool>
+EnableNoNaNsFPMath("enable-no-nans-fp-math",
+                   cl::desc("Enable FP math optimizations that assume no NaNs"),
+                   cl::init(false));
+
+cl::opt<bool>
+EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
+      cl::Hidden,
+      cl::desc("Force codegen to assume rounding mode can change dynamically"),
+      cl::init(false));
+
+cl::opt<bool>
+GenerateSoftFloatCalls("soft-float",
+                    cl::desc("Generate software floating point library calls"),
+                    cl::init(false));
+
+cl::opt<llvm::FloatABI::ABIType>
+FloatABIForCalls("float-abi",
+                 cl::desc("Choose float ABI type"),
+                 cl::init(FloatABI::Default),
+                 cl::values(
+                     clEnumValN(FloatABI::Default, "default",
+                                "Target default float ABI type"),
+                     clEnumValN(FloatABI::Soft, "soft",
+                                "Soft float ABI (implied by -soft-float)"),
+                     clEnumValN(FloatABI::Hard, "hard",
+                                "Hard float ABI (uses FP registers)"),
+                     clEnumValEnd));
+
+cl::opt<llvm::FPOpFusion::FPOpFusionMode>
+FuseFPOps("fp-contract",
+          cl::desc("Enable aggressive formation of fused FP ops"),
+          cl::init(FPOpFusion::Standard),
+          cl::values(
+              clEnumValN(FPOpFusion::Fast, "fast",
+                         "Fuse FP ops whenever profitable"),
+              clEnumValN(FPOpFusion::Standard, "on",
+                         "Only fuse 'blessed' FP ops."),
+              clEnumValN(FPOpFusion::Strict, "off",
+                         "Only fuse FP ops when the result won't be effected."),
+              clEnumValEnd));
+
+cl::opt<bool>
+DontPlaceZerosInBSS("nozero-initialized-in-bss",
+              cl::desc("Don't place zero-initialized symbols into bss section"),
+              cl::init(false));
+
+cl::opt<bool>
+EnableGuaranteedTailCallOpt("tailcallopt",
+  cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
+  cl::init(false));
+
+cl::opt<bool>
+DisableTailCalls("disable-tail-calls",
+                 cl::desc("Never emit tail calls"),
+                 cl::init(false));
+
+cl::opt<unsigned>
+OverrideStackAlignment("stack-alignment",
+                       cl::desc("Override default stack alignment"),
+                       cl::init(0));
+
+cl::opt<std::string>
+TrapFuncName("trap-func", cl::Hidden,
+        cl::desc("Emit a call to trap function rather than a trap instruction"),
+        cl::init(""));
+
+cl::opt<bool>
+EnablePIE("enable-pie",
+          cl::desc("Assume the creation of a position independent executable."),
+          cl::init(false));
+
+cl::opt<bool>
+UseInitArray("use-init-array",
+             cl::desc("Use .init_array instead of .ctors."),
+             cl::init(false));
+
+cl::opt<std::string> StopAfter("stop-after",
+                            cl::desc("Stop compilation after a specific pass"),
+                            cl::value_desc("pass-name"),
+                                      cl::init(""));
+cl::opt<std::string> StartAfter("start-after",
+                          cl::desc("Resume compilation after a specific pass"),
+                          cl::value_desc("pass-name"),
+                          cl::init(""));
+
+cl::opt<bool> DataSections("data-sections",
+                           cl::desc("Emit data into separate sections"),
+                           cl::init(false));
+
+cl::opt<bool>
+FunctionSections("function-sections",
+                 cl::desc("Emit functions into separate sections"),
+                 cl::init(false));
+
+cl::opt<llvm::JumpTable::JumpTableType>
+JTableType("jump-table-type",
+          cl::desc("Choose the type of Jump-Instruction Table for jumptable."),
+          cl::init(JumpTable::Single),
+          cl::values(
+              clEnumValN(JumpTable::Single, "single",
+                         "Create a single table for all jumptable functions"),
+              clEnumValN(JumpTable::Arity, "arity",
+                         "Create one table per number of parameters."),
+              clEnumValN(JumpTable::Simplified, "simplified",
+                         "Create one table per simplified function type."),
+              clEnumValN(JumpTable::Full, "full",
+                         "Create one table per unique function type."),
+              clEnumValEnd));
+
+// Common utility function tightly tied to the options listed here. Initializes
+// a TargetOptions object with CodeGen flags and returns it.
+static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
+  TargetOptions Options;
+  Options.LessPreciseFPMADOption = EnableFPMAD;
+  Options.NoFramePointerElim = DisableFPElim;
+  Options.AllowFPOpFusion = FuseFPOps;
+  Options.UnsafeFPMath = EnableUnsafeFPMath;
+  Options.NoInfsFPMath = EnableNoInfsFPMath;
+  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+  Options.HonorSignDependentRoundingFPMathOption =
+      EnableHonorSignDependentRoundingFPMath;
+  Options.UseSoftFloat = GenerateSoftFloatCalls;
+  if (FloatABIForCalls != FloatABI::Default)
+    Options.FloatABIType = FloatABIForCalls;
+  Options.NoZerosInBSS = DontPlaceZerosInBSS;
+  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+  Options.DisableTailCalls = DisableTailCalls;
+  Options.StackAlignmentOverride = OverrideStackAlignment;
+  Options.TrapFuncName = TrapFuncName;
+  Options.PositionIndependentExecutable = EnablePIE;
+  Options.UseInitArray = UseInitArray;
+  Options.DataSections = DataSections;
+  Options.FunctionSections = FunctionSections;
+
+  Options.MCOptions = InitMCTargetOptionsFromFlags();
+  Options.JTType = JTableType;
+
+  return Options;
+}
+
+#endif
diff --git a/include/llvm/CodeGen/DAGCombine.h b/include/llvm/CodeGen/DAGCombine.h
new file mode 100644
index 0000000..8b59190
--- /dev/null
+++ b/include/llvm/CodeGen/DAGCombine.h
@@ -0,0 +1,25 @@
+//===-- llvm/CodeGen/DAGCombine.h  ------- SelectionDAG Nodes ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_CODEGEN_DAGCOMBINE_H
+#define LLVM_CODEGEN_DAGCOMBINE_H
+
+namespace llvm {
+
+enum CombineLevel {
+  BeforeLegalizeTypes,
+  AfterLegalizeTypes,
+  AfterLegalizeVectorOps,
+  AfterLegalizeDAG
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/DFAPacketizer.h b/include/llvm/CodeGen/DFAPacketizer.h
new file mode 100644
index 0000000..9d25fd3
--- /dev/null
+++ b/include/llvm/CodeGen/DFAPacketizer.h
@@ -0,0 +1,167 @@
+//=- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-=====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This class implements a deterministic finite automaton (DFA) based
+// packetizing mechanism for VLIW architectures. It provides APIs to
+// determine whether there exists a legal mapping of instructions to
+// functional unit assignments in a packet. The DFA is auto-generated from
+// the target's Schedule.td file.
+//
+// A DFA consists of 3 major elements: states, inputs, and transitions. For
+// the packetizing mechanism, the input is the set of instruction classes for
+// a target. The state models all possible combinations of functional unit
+// consumption for a given set of instructions in a packet. A transition
+// models the addition of an instruction to a packet. In the DFA constructed
+// by this class, if an instruction can be added to a packet, then a valid
+// transition exists from the corresponding state. Invalid transitions
+// indicate that the instruction cannot be added to the current packet.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DFAPACKETIZER_H
+#define LLVM_CODEGEN_DFAPACKETIZER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include <map>
+
+namespace llvm {
+
+class MCInstrDesc;
+class MachineInstr;
+class MachineLoopInfo;
+class MachineDominatorTree;
+class InstrItineraryData;
+class DefaultVLIWScheduler;
+class SUnit;
+
+class DFAPacketizer {
+private:
+  typedef std::pair<unsigned, unsigned> UnsignPair;
+  const InstrItineraryData *InstrItins;
+  int CurrentState;
+  const int (*DFAStateInputTable)[2];
+  const unsigned *DFAStateEntryTable;
+
+  // CachedTable is a map from <FromState, Input> to ToState.
+  DenseMap<UnsignPair, unsigned> CachedTable;
+
+  // ReadTable - Read the DFA transition table and update CachedTable.
+  void ReadTable(unsigned int state);
+
+public:
+  DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
+                const unsigned *SET);
+
+  // Reset the current state to make all resources available.
+  void clearResources() {
+    CurrentState = 0;
+  }
+
+  // canReserveResources - Check if the resources occupied by a MCInstrDesc
+  // are available in the current state.
+  bool canReserveResources(const llvm::MCInstrDesc *MID);
+
+  // reserveResources - Reserve the resources occupied by a MCInstrDesc and
+  // change the current state to reflect that change.
+  void reserveResources(const llvm::MCInstrDesc *MID);
+
+  // canReserveResources - Check if the resources occupied by a machine
+  // instruction are available in the current state.
+  bool canReserveResources(llvm::MachineInstr *MI);
+
+  // reserveResources - Reserve the resources occupied by a machine
+  // instruction and change the current state to reflect that change.
+  void reserveResources(llvm::MachineInstr *MI);
+
+  const InstrItineraryData *getInstrItins() const { return InstrItins; }
+};
+
+// VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
+// packetizer works on machine basic blocks. For each instruction I in BB, the
+// packetizer consults the DFA to see if machine resources are available to
+// execute I. If so, the packetizer checks if I depends on any instruction J in
+// the current packet. If no dependency is found, I is added to current packet
+// and machine resource is marked as taken. If any dependency is found, a target
+// API call is made to prune the dependence.
+class VLIWPacketizerList {
+protected:
+  const TargetMachine &TM;
+  const MachineFunction &MF;
+  const TargetInstrInfo *TII;
+
+  // The VLIW Scheduler.
+  DefaultVLIWScheduler *VLIWScheduler;
+
+  // Vector of instructions assigned to the current packet.
+  std::vector<MachineInstr*> CurrentPacketMIs;
+  // DFA resource tracker.
+  DFAPacketizer *ResourceTracker;
+
+  // Generate MI -> SU map.
+  std::map<MachineInstr*, SUnit*> MIToSUnit;
+
+public:
+  VLIWPacketizerList(
+    MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
+    bool IsPostRA);
+
+  virtual ~VLIWPacketizerList();
+
+  // PacketizeMIs - Implement this API in the backend to bundle instructions.
+  void PacketizeMIs(MachineBasicBlock *MBB,
+                    MachineBasicBlock::iterator BeginItr,
+                    MachineBasicBlock::iterator EndItr);
+
+  // getResourceTracker - return ResourceTracker
+  DFAPacketizer *getResourceTracker() {return ResourceTracker;}
+
+  // addToPacket - Add MI to the current packet.
+  virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) {
+    MachineBasicBlock::iterator MII = MI;
+    CurrentPacketMIs.push_back(MI);
+    ResourceTracker->reserveResources(MI);
+    return MII;
+  }
+
+  // endPacket - End the current packet.
+  void endPacket(MachineBasicBlock *MBB, MachineInstr *MI);
+
+  // initPacketizerState - perform initialization before packetizing
+  // an instruction. This function is supposed to be overrided by
+  // the target dependent packetizer.
+  virtual void initPacketizerState() { return; }
+
+  // ignorePseudoInstruction - Ignore bundling of pseudo instructions.
+  virtual bool ignorePseudoInstruction(MachineInstr *I,
+                                       MachineBasicBlock *MBB) {
+    return false;
+  }
+
+  // isSoloInstruction - return true if instruction MI can not be packetized
+  // with any other instruction, which means that MI itself is a packet.
+  virtual bool isSoloInstruction(MachineInstr *MI) {
+    return true;
+  }
+
+  // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
+  // together.
+  virtual bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
+    return false;
+  }
+
+  // isLegalToPruneDependencies - Is it legal to prune dependece between SUI
+  // and SUJ.
+  virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
+    return false;
+  }
+
+};
+}
+
+#endif
diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h
new file mode 100644
index 0000000..c31fad2
--- /dev/null
+++ b/include/llvm/CodeGen/EdgeBundles.h
@@ -0,0 +1,64 @@
+//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The EdgeBundles analysis forms equivalence classes of CFG edges such that all
+// edges leaving a machine basic block are in the same bundle, and all edges
+// leaving a basic block are in the same bundle.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EDGEBUNDLES_H
+#define LLVM_CODEGEN_EDGEBUNDLES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntEqClasses.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+class EdgeBundles : public MachineFunctionPass {
+  const MachineFunction *MF;
+
+  /// EC - Each edge bundle is an equivalence class. The keys are:
+  ///   2*BB->getNumber()   -> Ingoing bundle.
+  ///   2*BB->getNumber()+1 -> Outgoing bundle.
+  IntEqClasses EC;
+
+  /// Blocks - Map each bundle to a list of basic block numbers.
+  SmallVector<SmallVector<unsigned, 8>, 4> Blocks;
+
+public:
+  static char ID;
+  EdgeBundles() : MachineFunctionPass(ID) {}
+
+  /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true)
+  /// bundle number for basic block #N
+  unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; }
+
+  /// getNumBundles - Return the total number of bundles in the CFG.
+  unsigned getNumBundles() const { return EC.getNumClasses(); }
+
+  /// getBlocks - Return an array of blocks that are connected to Bundle.
+  ArrayRef<unsigned> getBlocks(unsigned Bundle) const { return Blocks[Bundle]; }
+
+  /// getMachineFunction - Return the last machine function computed.
+  const MachineFunction *getMachineFunction() const { return MF; }
+
+  /// view - Visualize the annotated bipartite CFG with Graphviz.
+  void view() const;
+
+private:
+  bool runOnMachineFunction(MachineFunction&) override;
+  void getAnalysisUsage(AnalysisUsage&) const override;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
new file mode 100644
index 0000000..0d1b1dc
--- /dev/null
+++ b/include/llvm/CodeGen/FastISel.h
@@ -0,0 +1,585 @@
+//===-- FastISel.h - Definition of the FastISel class ---*- C++ -*---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the FastISel class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_FASTISEL_H
+#define LLVM_CODEGEN_FASTISEL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/IR/CallingConv.h"
+
+namespace llvm {
+
+class AllocaInst;
+class Constant;
+class ConstantFP;
+class CallInst;
+class DataLayout;
+class FunctionLoweringInfo;
+class Instruction;
+class IntrinsicInst;
+class LoadInst;
+class MVT;
+class MachineConstantPool;
+class MachineFrameInfo;
+class MachineFunction;
+class MachineInstr;
+class MachineRegisterInfo;
+class TargetInstrInfo;
+class TargetLibraryInfo;
+class TargetLowering;
+class TargetMachine;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class User;
+class Value;
+
+/// This is a fast-path instruction selection class that generates poor code and
+/// doesn't support illegal types or non-trivial lowering, but runs quickly.
+class FastISel {
+  public:
+  struct ArgListEntry {
+    Value *Val;
+    Type *Ty;
+    bool isSExt     : 1;
+    bool isZExt     : 1;
+    bool isInReg    : 1;
+    bool isSRet     : 1;
+    bool isNest     : 1;
+    bool isByVal    : 1;
+    bool isInAlloca : 1;
+    bool isReturned : 1;
+    uint16_t Alignment;
+
+    ArgListEntry()
+      : Val(nullptr), Ty(nullptr), isSExt(false), isZExt(false), isInReg(false),
+        isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
+        isReturned(false), Alignment(0) { }
+
+    void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
+  };
+  typedef std::vector<ArgListEntry> ArgListTy;
+
+  struct CallLoweringInfo {
+    Type *RetTy;
+    bool RetSExt           : 1;
+    bool RetZExt           : 1;
+    bool IsVarArg          : 1;
+    bool IsInReg           : 1;
+    bool DoesNotReturn     : 1;
+    bool IsReturnValueUsed : 1;
+
+    // IsTailCall should be modified by implementations of
+    // FastLowerCall that perform tail call conversions.
+    bool IsTailCall;
+
+    unsigned NumFixedArgs;
+    CallingConv::ID CallConv;
+    const Value *Callee;
+    const char *SymName;
+    ArgListTy Args;
+    ImmutableCallSite *CS;
+    MachineInstr *Call;
+    unsigned ResultReg;
+    unsigned NumResultRegs;
+
+    SmallVector<Value *, 16> OutVals;
+    SmallVector<ISD::ArgFlagsTy, 16> OutFlags;
+    SmallVector<unsigned, 16> OutRegs;
+    SmallVector<ISD::InputArg, 4> Ins;
+    SmallVector<unsigned, 4> InRegs;
+
+    CallLoweringInfo()
+      : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
+        IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
+        IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
+        Callee(nullptr), SymName(nullptr), CS(nullptr), Call(nullptr),
+        ResultReg(0), NumResultRegs(0)
+    {}
+
+    CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
+                                const Value *Target, ArgListTy &&ArgsList,
+                                ImmutableCallSite &Call) {
+      RetTy = ResultTy;
+      Callee = Target;
+
+      IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+      DoesNotReturn = Call.doesNotReturn();
+      IsVarArg = FuncTy->isVarArg();
+      IsReturnValueUsed = !Call.getInstruction()->use_empty();
+      RetSExt = Call.paramHasAttr(0, Attribute::SExt);
+      RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+
+      CallConv = Call.getCallingConv();
+      NumFixedArgs = FuncTy->getNumParams();
+      Args = std::move(ArgsList);
+
+      CS = &Call;
+
+      return *this;
+    }
+
+    CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
+                                const char *Target, ArgListTy &&ArgsList,
+                                ImmutableCallSite &Call,
+                                unsigned FixedArgs = ~0U) {
+      RetTy = ResultTy;
+      Callee = Call.getCalledValue();
+      SymName = Target;
+
+      IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+      DoesNotReturn = Call.doesNotReturn();
+      IsVarArg = FuncTy->isVarArg();
+      IsReturnValueUsed = !Call.getInstruction()->use_empty();
+      RetSExt = Call.paramHasAttr(0, Attribute::SExt);
+      RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+
+      CallConv = Call.getCallingConv();
+      NumFixedArgs = (FixedArgs == ~0U) ? FuncTy->getNumParams() : FixedArgs;
+      Args = std::move(ArgsList);
+
+      CS = &Call;
+
+      return *this;
+    }
+
+    CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
+                                const Value *Target, ArgListTy &&ArgsList,
+                                unsigned FixedArgs = ~0U) {
+      RetTy = ResultTy;
+      Callee = Target;
+      CallConv = CC;
+      NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
+      Args = std::move(ArgsList);
+      return *this;
+    }
+
+    CallLoweringInfo &setTailCall(bool Value = true) {
+      IsTailCall = Value;
+      return *this;
+    }
+
+    ArgListTy &getArgs() {
+      return Args;
+    }
+
+    void clearOuts() {
+      OutVals.clear();
+      OutFlags.clear();
+      OutRegs.clear();
+    }
+
+    void clearIns() {
+      Ins.clear();
+      InRegs.clear();
+    }
+  };
+
+protected:
+  DenseMap<const Value *, unsigned> LocalValueMap;
+  FunctionLoweringInfo &FuncInfo;
+  MachineFunction *MF;
+  MachineRegisterInfo &MRI;
+  MachineFrameInfo &MFI;
+  MachineConstantPool &MCP;
+  DebugLoc DbgLoc;
+  const TargetMachine &TM;
+  const DataLayout &DL;
+  const TargetInstrInfo &TII;
+  const TargetLowering &TLI;
+  const TargetRegisterInfo &TRI;
+  const TargetLibraryInfo *LibInfo;
+
+  /// The position of the last instruction for materializing constants for use
+  /// in the current block. It resets to EmitStartPt when it makes sense (for
+  /// example, it's usually profitable to avoid function calls between the
+  /// definition and the use)
+  MachineInstr *LastLocalValue;
+
+  /// The top most instruction in the current block that is allowed for emitting
+  /// local variables. LastLocalValue resets to EmitStartPt when it makes sense
+  /// (for example, on function calls)
+  MachineInstr *EmitStartPt;
+
+public:
+  /// Return the position of the last instruction emitted for materializing
+  /// constants for use in the current block.
+  MachineInstr *getLastLocalValue() { return LastLocalValue; }
+
+  /// Update the position of the last instruction emitted for materializing
+  /// constants for use in the current block.
+  void setLastLocalValue(MachineInstr *I) {
+    EmitStartPt = I;
+    LastLocalValue = I;
+  }
+
+  /// Set the current block to which generated machine instructions will be
+  /// appended, and clear the local CSE map.
+  void startNewBlock();
+
+  /// Return current debug location information.
+  DebugLoc getCurDebugLoc() const { return DbgLoc; }
+  
+  /// Do "fast" instruction selection for function arguments and append machine
+  /// instructions to the current block. Return true if it is successful.
+  bool LowerArguments();
+
+  /// Do "fast" instruction selection for the given LLVM IR instruction, and
+  /// append generated machine instructions to the current block. Return true if
+  /// selection was successful.
+  bool SelectInstruction(const Instruction *I);
+
+  /// Do "fast" instruction selection for the given LLVM IR operator
+  /// (Instruction or ConstantExpr), and append generated machine instructions
+  /// to the current block. Return true if selection was successful.
+  bool SelectOperator(const User *I, unsigned Opcode);
+
+  /// Create a virtual register and arrange for it to be assigned the value for
+  /// the given LLVM value.
+  unsigned getRegForValue(const Value *V);
+
+  /// Look up the value to see if its value is already cached in a register. It
+  /// may be defined by instructions across blocks or defined locally.
+  unsigned lookUpRegForValue(const Value *V);
+
+  /// This is a wrapper around getRegForValue that also takes care of truncating
+  /// or sign-extending the given getelementptr index value.
+  std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
+
+  /// \brief We're checking to see if we can fold \p LI into \p FoldInst. Note
+  /// that we could have a sequence where multiple LLVM IR instructions are
+  /// folded into the same machineinstr.  For example we could have:
+  ///
+  ///   A: x = load i32 *P
+  ///   B: y = icmp A, 42
+  ///   C: br y, ...
+  ///
+  /// In this scenario, \p LI is "A", and \p FoldInst is "C".  We know about "B"
+  /// (and any other folded instructions) because it is between A and C.
+  ///
+  /// If we succeed folding, return true.
+  bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst);
+
+  /// \brief The specified machine instr operand is a vreg, and that vreg is
+  /// being provided by the specified load instruction.  If possible, try to
+  /// fold the load as an operand to the instruction, returning true if
+  /// possible.
+  ///
+  /// This method should be implemented by targets.
+  virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/,
+                                   const LoadInst * /*LI*/) {
+    return false;
+  }
+
+  /// Reset InsertPt to prepare for inserting instructions into the current
+  /// block.
+  void recomputeInsertPt();
+
+  /// Remove all dead instructions between the I and E.
+  void removeDeadCode(MachineBasicBlock::iterator I,
+                      MachineBasicBlock::iterator E);
+
+  struct SavePoint {
+    MachineBasicBlock::iterator InsertPt;
+    DebugLoc DL;
+  };
+
+  /// Prepare InsertPt to begin inserting instructions into the local value area
+  /// and return the old insert position.
+  SavePoint enterLocalValueArea();
+
+  /// Reset InsertPt to the given old insert position.
+  void leaveLocalValueArea(SavePoint Old);
+
+  virtual ~FastISel();
+
+protected:
+  explicit FastISel(FunctionLoweringInfo &funcInfo,
+                    const TargetLibraryInfo *libInfo);
+
+  /// This method is called by target-independent code when the normal FastISel
+  /// process fails to select an instruction.  This gives targets a chance to
+  /// emit code for anything that doesn't fit into FastISel's framework. It
+  /// returns true if it was successful.
+  virtual bool TargetSelectInstruction(const Instruction *I) = 0;
+  
+  /// This method is called by target-independent code to do target specific
+  /// argument lowering. It returns true if it was successful.
+  virtual bool FastLowerArguments();
+
+  /// \brief This method is called by target-independent code to do target
+  /// specific call lowering. It returns true if it was successful.
+  virtual bool FastLowerCall(CallLoweringInfo &CLI);
+
+  /// \brief This method is called by target-independent code to do target
+  /// specific intrinsic lowering. It returns true if it was successful.
+  virtual bool FastLowerIntrinsicCall(const IntrinsicInst *II);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type and opcode be emitted.
+  virtual unsigned FastEmit_(MVT VT,
+                             MVT RetVT,
+                             unsigned Opcode);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and register operand be emitted.
+  virtual unsigned FastEmit_r(MVT VT,
+                              MVT RetVT,
+                              unsigned Opcode,
+                              unsigned Op0, bool Op0IsKill);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and register operands be emitted.
+  virtual unsigned FastEmit_rr(MVT VT,
+                               MVT RetVT,
+                               unsigned Opcode,
+                               unsigned Op0, bool Op0IsKill,
+                               unsigned Op1, bool Op1IsKill);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and register and immediate
+  /// operands be emitted.
+  virtual unsigned FastEmit_ri(MVT VT,
+                               MVT RetVT,
+                               unsigned Opcode,
+                               unsigned Op0, bool Op0IsKill,
+                               uint64_t Imm);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and register and floating-point
+  /// immediate operands be emitted.
+  virtual unsigned FastEmit_rf(MVT VT,
+                               MVT RetVT,
+                               unsigned Opcode,
+                               unsigned Op0, bool Op0IsKill,
+                               const ConstantFP *FPImm);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and register and immediate
+  /// operands be emitted.
+  virtual unsigned FastEmit_rri(MVT VT,
+                                MVT RetVT,
+                                unsigned Opcode,
+                                unsigned Op0, bool Op0IsKill,
+                                unsigned Op1, bool Op1IsKill,
+                                uint64_t Imm);
+
+  /// \brief This method is a wrapper of FastEmit_ri.
+  /// 
+  /// It first tries to emit an instruction with an immediate operand using
+  /// FastEmit_ri.  If that fails, it materializes the immediate into a register
+  /// and try FastEmit_rr instead.
+  unsigned FastEmit_ri_(MVT VT,
+                        unsigned Opcode,
+                        unsigned Op0, bool Op0IsKill,
+                        uint64_t Imm, MVT ImmType);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and immediate operand be emitted.
+  virtual unsigned FastEmit_i(MVT VT,
+                              MVT RetVT,
+                              unsigned Opcode,
+                              uint64_t Imm);
+
+  /// This method is called by target-independent code to request that an
+  /// instruction with the given type, opcode, and floating-point immediate
+  /// operand be emitted.
+  virtual unsigned FastEmit_f(MVT VT,
+                              MVT RetVT,
+                              unsigned Opcode,
+                              const ConstantFP *FPImm);
+
+  /// Emit a MachineInstr with no operands and a result register in the given
+  /// register class.
+  unsigned FastEmitInst_(unsigned MachineInstOpcode,
+                         const TargetRegisterClass *RC);
+
+  /// Emit a MachineInstr with one register operand and a result register in the
+  /// given register class.
+  unsigned FastEmitInst_r(unsigned MachineInstOpcode,
+                          const TargetRegisterClass *RC,
+                          unsigned Op0, bool Op0IsKill);
+
+  /// Emit a MachineInstr with two register operands and a result register in
+  /// the given register class.
+  unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
+                           const TargetRegisterClass *RC,
+                           unsigned Op0, bool Op0IsKill,
+                           unsigned Op1, bool Op1IsKill);
+
+  /// Emit a MachineInstr with three register operands and a result register in
+  /// the given register class.
+  unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
+                           const TargetRegisterClass *RC,
+                           unsigned Op0, bool Op0IsKill,
+                           unsigned Op1, bool Op1IsKill,
+                           unsigned Op2, bool Op2IsKill);
+
+  /// Emit a MachineInstr with a register operand, an immediate, and a result
+  /// register in the given register class.
+  unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
+                           const TargetRegisterClass *RC,
+                           unsigned Op0, bool Op0IsKill,
+                           uint64_t Imm);
+
+  /// Emit a MachineInstr with one register operand and two immediate operands.
+  unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
+                           const TargetRegisterClass *RC,
+                           unsigned Op0, bool Op0IsKill,
+                           uint64_t Imm1, uint64_t Imm2);
+
+  /// Emit a MachineInstr with two register operands and a result register in
+  /// the given register class.
+  unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
+                           const TargetRegisterClass *RC,
+                           unsigned Op0, bool Op0IsKill,
+                           const ConstantFP *FPImm);
+
+  /// Emit a MachineInstr with two register operands, an immediate, and a result
+  /// register in the given register class.
+  unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
+                            const TargetRegisterClass *RC,
+                            unsigned Op0, bool Op0IsKill,
+                            unsigned Op1, bool Op1IsKill,
+                            uint64_t Imm);
+
+  /// Emit a MachineInstr with two register operands, two immediates operands,
+  /// and a result register in the given register class.
+  unsigned FastEmitInst_rrii(unsigned MachineInstOpcode,
+                             const TargetRegisterClass *RC,
+                             unsigned Op0, bool Op0IsKill,
+                             unsigned Op1, bool Op1IsKill,
+                             uint64_t Imm1, uint64_t Imm2);
+
+  /// Emit a MachineInstr with a single immediate operand, and a result register
+  /// in the given register class.
+  unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
+                          const TargetRegisterClass *RC,
+                          uint64_t Imm);
+
+  /// Emit a MachineInstr with a two immediate operands.
+  unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
+                          const TargetRegisterClass *RC,
+                          uint64_t Imm1, uint64_t Imm2);
+
+  /// Emit a MachineInstr for an extract_subreg from a specified index of a
+  /// superregister to a specified type.
+  unsigned FastEmitInst_extractsubreg(MVT RetVT,
+                                      unsigned Op0, bool Op0IsKill,
+                                      uint32_t Idx);
+
+  /// Emit MachineInstrs to compute the value of Op with all but the least
+  /// significant bit set to zero.
+  unsigned FastEmitZExtFromI1(MVT VT,
+                              unsigned Op0, bool Op0IsKill);
+
+  /// Emit an unconditional branch to the given block, unless it is the
+  /// immediate (fall-through) successor, and update the CFG.
+  void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
+
+  void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1);
+
+  unsigned createResultReg(const TargetRegisterClass *RC);
+
+  /// Try to constrain Op so that it is usable by argument OpNum of the provided
+  /// MCInstrDesc. If this fails, create a new virtual register in the correct
+  /// class and COPY the value there.
+  unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned Op,
+                                    unsigned OpNum);
+
+  /// Emit a constant in a register using target-specific logic, such as
+  /// constant pool loads.
+  virtual unsigned TargetMaterializeConstant(const Constant* C) {
+    return 0;
+  }
+
+  /// Emit an alloca address in a register using target-specific logic.
+  virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
+    return 0;
+  }
+
+  virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) {
+    return 0;
+  }
+
+  /// \brief Check if \c Add is an add that can be safely folded into \c GEP.
+  ///
+  /// \c Add can be folded into \c GEP if:
+  /// - \c Add is an add,
+  /// - \c Add's size matches \c GEP's,
+  /// - \c Add is in the same basic block as \c GEP, and
+  /// - \c Add has a constant operand.
+  bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
+
+  /// Test whether the given value has exactly one use.
+  bool hasTrivialKill(const Value *V) const;
+
+  /// \brief Create a machine mem operand from the given instruction.
+  MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
+
+  bool LowerCallTo(const CallInst *CI, const char *SymName, unsigned NumArgs);
+  bool LowerCallTo(CallLoweringInfo &CLI);
+
+private:
+  bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
+
+  bool SelectFNeg(const User *I);
+
+  bool SelectGetElementPtr(const User *I);
+
+  bool SelectStackmap(const CallInst *I);
+  bool SelectPatchpoint(const CallInst *I);
+  bool LowerCall(const CallInst *I);
+  bool SelectCall(const User *Call);
+  bool SelectIntrinsicCall(const IntrinsicInst *II);
+
+  bool SelectBitCast(const User *I);
+
+  bool SelectCast(const User *I, unsigned Opcode);
+
+  bool SelectExtractValue(const User *I);
+
+  bool SelectInsertValue(const User *I);
+
+  /// \brief Handle PHI nodes in successor blocks.
+  ///
+  /// Emit code to ensure constants are copied into registers when needed.
+  /// Remember the virtual registers that need to be added to the Machine PHI
+  /// nodes as input.  We cannot just directly add them, because expansion might
+  /// result in multiple MBB's for one BB.  As such, the start of the BB might
+  /// correspond to a different MBB than the end.
+  bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
+
+  /// Helper for getRegForVale. This function is called when the value isn't
+  /// already available in a register and must be materialized with new
+  /// instructions.
+  unsigned materializeRegForValue(const Value *V, MVT VT);
+
+  /// Clears LocalValueMap and moves the area for the new local variables to the
+  /// beginning of the block. It helps to avoid spilling cached variables across
+  /// heavy instructions like calls.
+  void flushLocalValueMap();
+
+  bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
+                           const CallInst *CI, unsigned StartIdx);
+  bool lowerCallOperands(const CallInst *CI, unsigned ArgIdx, unsigned NumArgs,
+                         const Value *Callee, bool ForceRetVoidTy,
+                         CallLoweringInfo &CLI);
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
new file mode 100644
index 0000000..9636b51
--- /dev/null
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -0,0 +1,234 @@
+//===-- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements routines for translating functions from LLVM IR into
+// Machine IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
+#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <vector>
+
+namespace llvm {
+
+class AllocaInst;
+class BasicBlock;
+class BranchProbabilityInfo;
+class CallInst;
+class Function;
+class GlobalVariable;
+class Instruction;
+class MachineInstr;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRegisterInfo;
+class SelectionDAG;
+class MVT;
+class TargetLowering;
+class Value;
+
+//===--------------------------------------------------------------------===//
+/// FunctionLoweringInfo - This contains information that is global to a
+/// function that is used when lowering a region of the function.
+///
+class FunctionLoweringInfo {
+  const TargetMachine &TM;
+public:
+  const Function *Fn;
+  MachineFunction *MF;
+  MachineRegisterInfo *RegInfo;
+  BranchProbabilityInfo *BPI;
+  /// CanLowerReturn - true iff the function's return value can be lowered to
+  /// registers.
+  bool CanLowerReturn;
+
+  /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg
+  /// allocated to hold a pointer to the hidden sret parameter.
+  unsigned DemoteRegister;
+
+  /// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
+  DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
+
+  /// ValueMap - Since we emit code for the function a basic block at a time,
+  /// we must remember which virtual registers hold the values for
+  /// cross-basic-block values.
+  DenseMap<const Value*, unsigned> ValueMap;
+
+  /// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
+  /// the entry block.  This allows the allocas to be efficiently referenced
+  /// anywhere in the function.
+  DenseMap<const AllocaInst*, int> StaticAllocaMap;
+
+  /// ByValArgFrameIndexMap - Keep track of frame indices for byval arguments.
+  DenseMap<const Argument*, int> ByValArgFrameIndexMap;
+
+  /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for
+  /// function arguments that are inserted after scheduling is completed.
+  SmallVector<MachineInstr*, 8> ArgDbgValues;
+
+  /// RegFixups - Registers which need to be replaced after isel is done.
+  DenseMap<unsigned, unsigned> RegFixups;
+
+  /// MBB - The current block.
+  MachineBasicBlock *MBB;
+
+  /// MBB - The current insert position inside the current block.
+  MachineBasicBlock::iterator InsertPt;
+
+#ifndef NDEBUG
+  SmallPtrSet<const Instruction *, 8> CatchInfoLost;
+  SmallPtrSet<const Instruction *, 8> CatchInfoFound;
+#endif
+
+  struct LiveOutInfo {
+    unsigned NumSignBits : 31;
+    bool IsValid : 1;
+    APInt KnownOne, KnownZero;
+    LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
+                    KnownZero(1, 0) {}
+  };
+
+  /// VisitedBBs - The set of basic blocks visited thus far by instruction
+  /// selection.
+  SmallPtrSet<const BasicBlock*, 4> VisitedBBs;
+
+  /// PHINodesToUpdate - A list of phi instructions whose operand list will
+  /// be updated after processing the current basic block.
+  /// TODO: This isn't per-function state, it's per-basic-block state. But
+  /// there's no other convenient place for it to live right now.
+  std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
+
+  /// If the current MBB is a landing pad, the exception pointer and exception
+  /// selector registers are copied into these virtual registers by
+  /// SelectionDAGISel::PrepareEHLandingPad().
+  unsigned ExceptionPointerVirtReg, ExceptionSelectorVirtReg;
+
+  explicit FunctionLoweringInfo(const TargetMachine &TM) : TM(TM) {}
+
+  /// set - Initialize this FunctionLoweringInfo with the given Function
+  /// and its associated MachineFunction.
+  ///
+  void set(const Function &Fn, MachineFunction &MF, SelectionDAG *DAG);
+
+  /// clear - Clear out all the function-specific state. This returns this
+  /// FunctionLoweringInfo to an empty state, ready to be used for a
+  /// different function.
+  void clear();
+
+  /// isExportedInst - Return true if the specified value is an instruction
+  /// exported from its block.
+  bool isExportedInst(const Value *V) {
+    return ValueMap.count(V);
+  }
+
+  unsigned CreateReg(MVT VT);
+  
+  unsigned CreateRegs(Type *Ty);
+  
+  unsigned InitializeRegForValue(const Value *V) {
+    unsigned &R = ValueMap[V];
+    assert(R == 0 && "Already initialized this value register!");
+    return R = CreateRegs(V->getType());
+  }
+
+  /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+  /// register is a PHI destination and the PHI's LiveOutInfo is not valid.
+  const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg) {
+    if (!LiveOutRegInfo.inBounds(Reg))
+      return nullptr;
+
+    const LiveOutInfo *LOI = &LiveOutRegInfo[Reg];
+    if (!LOI->IsValid)
+      return nullptr;
+
+    return LOI;
+  }
+
+  /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+  /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If
+  /// the register's LiveOutInfo is for a smaller bit width, it is extended to
+  /// the larger bit width by zero extension. The bit width must be no smaller
+  /// than the LiveOutInfo's existing bit width.
+  const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth);
+
+  /// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
+  void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
+                         const APInt &KnownZero, const APInt &KnownOne) {
+    // Only install this information if it tells us something.
+    if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
+      return;
+
+    LiveOutRegInfo.grow(Reg);
+    LiveOutInfo &LOI = LiveOutRegInfo[Reg];
+    LOI.NumSignBits = NumSignBits;
+    LOI.KnownOne = KnownOne;
+    LOI.KnownZero = KnownZero;
+  }
+
+  /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
+  /// register based on the LiveOutInfo of its operands.
+  void ComputePHILiveOutRegInfo(const PHINode*);
+
+  /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be
+  /// called when a block is visited before all of its predecessors.
+  void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
+    // PHIs with no uses have no ValueMap entry.
+    DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN);
+    if (It == ValueMap.end())
+      return;
+
+    unsigned Reg = It->second;
+    LiveOutRegInfo.grow(Reg);
+    LiveOutRegInfo[Reg].IsValid = false;
+  }
+
+  /// setArgumentFrameIndex - Record frame index for the byval
+  /// argument.
+  void setArgumentFrameIndex(const Argument *A, int FI);
+
+  /// getArgumentFrameIndex - Get frame index for the byval argument.
+  int getArgumentFrameIndex(const Argument *A);
+
+private:
+  /// LiveOutRegInfo - Information about live out vregs.
+  IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
+};
+
+/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
+/// being passed to this variadic function, and set the MachineModuleInfo's
+/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
+/// reference to _fltused on Windows, which will link in MSVCRT's
+/// floating-point support.
+void ComputeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo *MMI);
+
+/// AddCatchInfo - Extract the personality and type infos from an eh.selector
+/// call, and add them to the specified machine basic block.
+void AddCatchInfo(const CallInst &I,
+                  MachineModuleInfo *MMI, MachineBasicBlock *MBB);
+
+/// AddLandingPadInfo - Extract the exception handling information from the
+/// landingpad instruction and add them to the specified machine module info.
+void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
+                       MachineBasicBlock *MBB);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
new file mode 100644
index 0000000..ddcc823
--- /dev/null
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -0,0 +1,201 @@
+//===-- GCMetadata.h - Garbage collector metadata ---------------*- 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 GCFunctionInfo and GCModuleInfo classes, which are
+// used as a communication channel from the target code generator to the target
+// garbage collectors. This interface allows code generators and garbage
+// collectors to be developed independently.
+//
+// The GCFunctionInfo class logs the data necessary to build a type accurate
+// stack map. The code generator outputs:
+//
+//   - Safe points as specified by the GCStrategy's NeededSafePoints.
+//   - Stack offsets for GC roots, as specified by calls to llvm.gcroot
+//
+// As a refinement, liveness analysis calculates the set of live roots at each
+// safe point. Liveness analysis is not presently performed by the code
+// generator, so all roots are assumed live.
+//
+// GCModuleInfo simply collects GCFunctionInfo instances for each Function as
+// they are compiled. This accretion is necessary for collectors which must emit
+// a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo
+// outlives the MachineFunction from which it is derived and must not refer to
+// any code generator data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCMETADATA_H
+#define LLVM_CODEGEN_GCMETADATA_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Pass.h"
+
+#include <memory>
+
+namespace llvm {
+  class AsmPrinter;
+  class GCStrategy;
+  class Constant;
+  class MCSymbol;
+
+  namespace GC {
+    /// PointKind - The type of a collector-safe point.
+    ///
+    enum PointKind {
+      Loop,    ///< Instr is a loop (backwards branch).
+      Return,  ///< Instr is a return instruction.
+      PreCall, ///< Instr is a call instruction.
+      PostCall ///< Instr is the return address of a call.
+    };
+  }
+
+  /// GCPoint - Metadata for a collector-safe point in machine code.
+  ///
+  struct GCPoint {
+    GC::PointKind Kind; ///< The kind of the safe point.
+    MCSymbol *Label;    ///< A label.
+    DebugLoc Loc;
+
+    GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
+        : Kind(K), Label(L), Loc(DL) {}
+  };
+
+  /// GCRoot - Metadata for a pointer to an object managed by the garbage
+  /// collector.
+  struct GCRoot {
+    int Num;            ///< Usually a frame index.
+    int StackOffset;    ///< Offset from the stack pointer.
+    const Constant *Metadata; ///< Metadata straight from the call
+                              ///< to llvm.gcroot.
+
+    GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
+  };
+
+
+  /// GCFunctionInfo - Garbage collection metadata for a single function.
+  ///
+  class GCFunctionInfo {
+  public:
+    typedef std::vector<GCPoint>::iterator iterator;
+    typedef std::vector<GCRoot>::iterator roots_iterator;
+    typedef std::vector<GCRoot>::const_iterator live_iterator;
+
+  private:
+    const Function &F;
+    GCStrategy &S;
+    uint64_t FrameSize;
+    std::vector<GCRoot> Roots;
+    std::vector<GCPoint> SafePoints;
+
+    // FIXME: Liveness. A 2D BitVector, perhaps?
+    //
+    //   BitVector Liveness;
+    //
+    //   bool islive(int point, int root) =
+    //     Liveness[point * SafePoints.size() + root]
+    //
+    // The bit vector is the more compact representation where >3.2% of roots
+    // are live per safe point (1.5% on 64-bit hosts).
+
+  public:
+    GCFunctionInfo(const Function &F, GCStrategy &S);
+    ~GCFunctionInfo();
+
+    /// getFunction - Return the function to which this metadata applies.
+    ///
+    const Function &getFunction() const { return F; }
+
+    /// getStrategy - Return the GC strategy for the function.
+    ///
+    GCStrategy &getStrategy() { return S; }
+
+    /// addStackRoot - Registers a root that lives on the stack. Num is the
+    ///                stack object ID for the alloca (if the code generator is
+    //                 using  MachineFrameInfo).
+    void addStackRoot(int Num, const Constant *Metadata) {
+      Roots.push_back(GCRoot(Num, Metadata));
+    }
+
+    /// removeStackRoot - Removes a root.
+    roots_iterator removeStackRoot(roots_iterator position) {
+      return Roots.erase(position);
+    }
+
+    /// addSafePoint - Notes the existence of a safe point. Num is the ID of the
+    /// label just prior to the safe point (if the code generator is using
+    /// MachineModuleInfo).
+    void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
+      SafePoints.push_back(GCPoint(Kind, Label, DL));
+    }
+
+    /// getFrameSize/setFrameSize - Records the function's frame size.
+    ///
+    uint64_t getFrameSize() const { return FrameSize; }
+    void setFrameSize(uint64_t S) { FrameSize = S; }
+
+    /// begin/end - Iterators for safe points.
+    ///
+    iterator begin() { return SafePoints.begin(); }
+    iterator end()   { return SafePoints.end();   }
+    size_t size() const { return SafePoints.size(); }
+
+    /// roots_begin/roots_end - Iterators for all roots in the function.
+    ///
+    roots_iterator roots_begin() { return Roots.begin(); }
+    roots_iterator roots_end  () { return Roots.end();   }
+    size_t roots_size() const { return Roots.size(); }
+
+    /// live_begin/live_end - Iterators for live roots at a given safe point.
+    ///
+    live_iterator live_begin(const iterator &p) { return roots_begin(); }
+    live_iterator live_end  (const iterator &p) { return roots_end();   }
+    size_t live_size(const iterator &p) const { return roots_size(); }
+  };
+
+
+  /// GCModuleInfo - Garbage collection metadata for a whole module.
+  ///
+  class GCModuleInfo : public ImmutablePass {
+    typedef StringMap<GCStrategy*> strategy_map_type;
+    typedef std::vector<std::unique_ptr<GCStrategy>> list_type;
+    typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
+
+    strategy_map_type StrategyMap;
+    list_type StrategyList;
+    finfo_map_type FInfoMap;
+
+    GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);
+
+  public:
+    typedef list_type::const_iterator iterator;
+
+    static char ID;
+
+    GCModuleInfo();
+
+    /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should
+    /// call it in doFinalization().
+    ///
+    void clear();
+
+    /// begin/end - Iterators for used strategies.
+    ///
+    iterator begin() const { return StrategyList.begin(); }
+    iterator end()   const { return StrategyList.end();   }
+
+    /// get - Look up function metadata.
+    ///
+    GCFunctionInfo &getFunctionInfo(const Function &F);
+  };
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/GCMetadataPrinter.h b/include/llvm/CodeGen/GCMetadataPrinter.h
new file mode 100644
index 0000000..4a6b5ac
--- /dev/null
+++ b/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -0,0 +1,74 @@
+//===-- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The abstract base class GCMetadataPrinter supports writing GC metadata tables
+// as assembly code. This is a separate class from GCStrategy in order to allow
+// users of the LLVM JIT to avoid linking with the AsmWriter.
+//
+// Subclasses of GCMetadataPrinter must be registered using the
+// GCMetadataPrinterRegistry. This is separate from the GCStrategy itself
+// because these subclasses are logically plugins for the AsmWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCMETADATAPRINTER_H
+#define LLVM_CODEGEN_GCMETADATAPRINTER_H
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/Support/Registry.h"
+
+namespace llvm {
+
+  class GCMetadataPrinter;
+
+  /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
+  /// defaults from Registry.
+  typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
+
+  /// GCMetadataPrinter - Emits GC metadata as assembly code.
+  ///
+  class GCMetadataPrinter {
+  public:
+    typedef GCStrategy::list_type list_type;
+    typedef GCStrategy::iterator iterator;
+
+  private:
+    GCStrategy *S;
+
+    friend class AsmPrinter;
+
+  protected:
+    // May only be subclassed.
+    GCMetadataPrinter();
+
+  private:
+    GCMetadataPrinter(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
+    GCMetadataPrinter &
+      operator=(const GCMetadataPrinter &) LLVM_DELETED_FUNCTION;
+
+  public:
+    GCStrategy &getStrategy() { return *S; }
+    const Module &getModule() const { return S->getModule(); }
+
+    /// begin/end - Iterate over the collected function metadata.
+    iterator begin() { return S->begin(); }
+    iterator end()   { return S->end();   }
+
+    /// beginAssembly/finishAssembly - Emit module metadata as assembly code.
+    virtual void beginAssembly(AsmPrinter &AP);
+
+    virtual void finishAssembly(AsmPrinter &AP);
+
+    virtual ~GCMetadataPrinter();
+  };
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/GCStrategy.h b/include/llvm/CodeGen/GCStrategy.h
new file mode 100644
index 0000000..81e1f85
--- /dev/null
+++ b/include/llvm/CodeGen/GCStrategy.h
@@ -0,0 +1,153 @@
+//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// GCStrategy coordinates code generation algorithms and implements some itself
+// in order to generate code compatible with a target code generator as
+// specified in a function's 'gc' attribute. Algorithms are enabled by setting
+// flags in a subclass's constructor, and some virtual methods can be
+// overridden.
+// 
+// When requested, the GCStrategy will be populated with data about each
+// function which uses it. Specifically:
+// 
+// - Safe points
+//   Garbage collection is generally only possible at certain points in code.
+//   GCStrategy can request that the collector insert such points:
+//
+//     - At and after any call to a subroutine
+//     - Before returning from the current function
+//     - Before backwards branches (loops)
+// 
+// - Roots
+//   When a reference to a GC-allocated object exists on the stack, it must be
+//   stored in an alloca registered with llvm.gcoot.
+//
+// This information can used to emit the metadata tables which are required by
+// the target garbage collector runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCSTRATEGY_H
+#define LLVM_CODEGEN_GCSTRATEGY_H
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/Registry.h"
+#include <string>
+
+namespace llvm {
+  
+  class GCStrategy;
+  
+  /// The GC strategy registry uses all the defaults from Registry.
+  /// 
+  typedef Registry<GCStrategy> GCRegistry;
+  
+  /// GCStrategy describes a garbage collector algorithm's code generation
+  /// requirements, and provides overridable hooks for those needs which cannot
+  /// be abstractly described.
+  class GCStrategy {
+  public:
+    typedef std::vector<std::unique_ptr<GCFunctionInfo>> list_type;
+    typedef list_type::iterator iterator;
+    
+  private:
+    friend class GCModuleInfo;
+    const Module *M;
+    std::string Name;
+    
+    list_type Functions;
+    
+  protected:
+    unsigned NeededSafePoints; ///< Bitmask of required safe points.
+    bool CustomReadBarriers;   ///< Default is to insert loads.
+    bool CustomWriteBarriers;  ///< Default is to insert stores.
+    bool CustomRoots;          ///< Default is to pass through to backend.
+    bool CustomSafePoints;     ///< Default is to use NeededSafePoints
+                               ///< to find safe points.
+    bool InitRoots;            ///< If set, roots are nulled during lowering.
+    bool UsesMetadata;         ///< If set, backend must emit metadata tables.
+    
+  public:
+    GCStrategy();
+    
+    virtual ~GCStrategy() {}
+    
+    
+    /// getName - The name of the GC strategy, for debugging.
+    /// 
+    const std::string &getName() const { return Name; }
+
+    /// getModule - The module within which the GC strategy is operating.
+    /// 
+    const Module &getModule() const { return *M; }
+
+    /// needsSafePoitns - True if safe points of any kind are required. By
+    //                    default, none are recorded.
+    bool needsSafePoints() const {
+      return CustomSafePoints || NeededSafePoints != 0;
+    }
+    
+    /// needsSafePoint(Kind) - True if the given kind of safe point is
+    //                          required. By default, none are recorded.
+    bool needsSafePoint(GC::PointKind Kind) const {
+      return (NeededSafePoints & 1 << Kind) != 0;
+    }
+    
+    /// customWriteBarrier - By default, write barriers are replaced with simple
+    ///                      store instructions. If true, then
+    ///                      performCustomLowering must instead lower them.
+    bool customWriteBarrier() const { return CustomWriteBarriers; }
+    
+    /// customReadBarrier - By default, read barriers are replaced with simple
+    ///                     load instructions. If true, then
+    ///                     performCustomLowering must instead lower them.
+    bool customReadBarrier() const { return CustomReadBarriers; }
+    
+    /// customRoots - By default, roots are left for the code generator so it
+    ///               can generate a stack map. If true, then
+    //                performCustomLowering must delete them.
+    bool customRoots() const { return CustomRoots; }
+
+    /// customSafePoints - By default, the GC analysis will find safe
+    ///                    points according to NeededSafePoints. If true,
+    ///                    then findCustomSafePoints must create them.
+    bool customSafePoints() const { return CustomSafePoints; }
+    
+    /// initializeRoots - If set, gcroot intrinsics should initialize their
+    //                    allocas to null before the first use. This is
+    //                    necessary for most GCs and is enabled by default.
+    bool initializeRoots() const { return InitRoots; }
+    
+    /// usesMetadata - If set, appropriate metadata tables must be emitted by
+    ///                the back-end (assembler, JIT, or otherwise).
+    bool usesMetadata() const { return UsesMetadata; }
+    
+    /// begin/end - Iterators for function metadata.
+    /// 
+    iterator begin() { return Functions.begin(); }
+    iterator end()   { return Functions.end();   }
+
+    /// insertFunctionMetadata - Creates metadata for a function.
+    /// 
+    GCFunctionInfo *insertFunctionInfo(const Function &F);
+
+    /// initializeCustomLowering/performCustomLowering - If any of the actions
+    /// are set to custom, performCustomLowering must be overriden to transform
+    /// the corresponding actions to LLVM IR. initializeCustomLowering is
+    /// optional to override. These are the only GCStrategy methods through
+    /// which the LLVM IR can be modified.
+    virtual bool initializeCustomLowering(Module &F);
+    virtual bool performCustomLowering(Function &F);
+    virtual bool findCustomSafePoints(GCFunctionInfo& FI, MachineFunction& MF);
+  };
+  
+}
+
+#endif
diff --git a/include/llvm/CodeGen/GCs.h b/include/llvm/CodeGen/GCs.h
new file mode 100644
index 0000000..bb170c8
--- /dev/null
+++ b/include/llvm/CodeGen/GCs.h
@@ -0,0 +1,41 @@
+//===-- GCs.h - Garbage collector linkage hacks ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains hack functions to force linking in the GC components.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCS_H
+#define LLVM_CODEGEN_GCS_H
+
+namespace llvm {
+  class GCStrategy;
+  class GCMetadataPrinter;
+
+  /// FIXME: Collector instances are not useful on their own. These no longer
+  ///        serve any purpose except to link in the plugins.
+
+  /// Creates an ocaml-compatible garbage collector.
+  void linkOcamlGC();
+
+  /// Creates an ocaml-compatible metadata printer.
+  void linkOcamlGCPrinter();
+
+  /// Creates an erlang-compatible garbage collector.
+  void linkErlangGC();
+
+  /// Creates an erlang-compatible metadata printer.
+  void linkErlangGCPrinter();
+
+  /// Creates a shadow stack garbage collector. This collector requires no code
+  /// generator support.
+  void linkShadowStackGC();
+}
+
+#endif
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
new file mode 100644
index 0000000..8444761
--- /dev/null
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -0,0 +1,861 @@
+//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- 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 codegen opcodes and related utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ISDOPCODES_H
+#define LLVM_CODEGEN_ISDOPCODES_H
+
+namespace llvm {
+
+/// ISD namespace - This namespace contains an enum which represents all of the
+/// SelectionDAG node types and value types.
+///
+namespace ISD {
+
+  //===--------------------------------------------------------------------===//
+  /// ISD::NodeType enum - This enum defines the target-independent operators
+  /// for a SelectionDAG.
+  ///
+  /// Targets may also define target-dependent operator codes for SDNodes. For
+  /// example, on x86, these are the enum values in the X86ISD namespace.
+  /// Targets should aim to use target-independent operators to model their
+  /// instruction sets as much as possible, and only use target-dependent
+  /// operators when they have special requirements.
+  ///
+  /// Finally, during and after selection proper, SNodes may use special
+  /// operator codes that correspond directly with MachineInstr opcodes. These
+  /// are used to represent selected instructions. See the isMachineOpcode()
+  /// and getMachineOpcode() member functions of SDNode.
+  ///
+  enum NodeType {
+    /// DELETED_NODE - This is an illegal value that is used to catch
+    /// errors.  This opcode is not a legal opcode for any node.
+    DELETED_NODE,
+
+    /// EntryToken - This is the marker used to indicate the start of a region.
+    EntryToken,
+
+    /// TokenFactor - This node takes multiple tokens as input and produces a
+    /// single token result. This is used to represent the fact that the operand
+    /// operators are independent of each other.
+    TokenFactor,
+
+    /// AssertSext, AssertZext - These nodes record if a register contains a
+    /// value that has already been zero or sign extended from a narrower type.
+    /// These nodes take two operands.  The first is the node that has already
+    /// been extended, and the second is a value type node indicating the width
+    /// of the extension
+    AssertSext, AssertZext,
+
+    /// Various leaf nodes.
+    BasicBlock, VALUETYPE, CONDCODE, Register, RegisterMask,
+    Constant, ConstantFP,
+    GlobalAddress, GlobalTLSAddress, FrameIndex,
+    JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
+
+    /// The address of the GOT
+    GLOBAL_OFFSET_TABLE,
+
+    /// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+    /// llvm.returnaddress on the DAG.  These nodes take one operand, the index
+    /// of the frame or return address to return.  An index of zero corresponds
+    /// to the current function's frame or return address, an index of one to
+    /// the parent's frame or return address, and so on.
+    FRAMEADDR, RETURNADDR,
+
+    /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
+    /// the DAG, which implements the named register global variables extension.
+    READ_REGISTER,
+    WRITE_REGISTER,
+
+    /// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+    /// first (possible) on-stack argument. This is needed for correct stack
+    /// adjustment during unwind.
+    FRAME_TO_ARGS_OFFSET,
+
+    /// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+    /// 'eh_return' gcc dwarf builtin, which is used to return from
+    /// exception. The general meaning is: adjust stack by OFFSET and pass
+    /// execution to HANDLER. Many platform-related details also :)
+    EH_RETURN,
+
+    /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
+    /// This corresponds to the eh.sjlj.setjmp intrinsic.
+    /// It takes an input chain and a pointer to the jump buffer as inputs
+    /// and returns an outchain.
+    EH_SJLJ_SETJMP,
+
+    /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
+    /// This corresponds to the eh.sjlj.longjmp intrinsic.
+    /// It takes an input chain and a pointer to the jump buffer as inputs
+    /// and returns an outchain.
+    EH_SJLJ_LONGJMP,
+
+    /// TargetConstant* - Like Constant*, but the DAG does not do any folding,
+    /// simplification, or lowering of the constant. They are used for constants
+    /// which are known to fit in the immediate fields of their users, or for
+    /// carrying magic numbers which are not values which need to be
+    /// materialized in registers.
+    TargetConstant,
+    TargetConstantFP,
+
+    /// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+    /// anything else with this node, and this is valid in the target-specific
+    /// dag, turning into a GlobalAddress operand.
+    TargetGlobalAddress,
+    TargetGlobalTLSAddress,
+    TargetFrameIndex,
+    TargetJumpTable,
+    TargetConstantPool,
+    TargetExternalSymbol,
+    TargetBlockAddress,
+
+    /// TargetIndex - Like a constant pool entry, but with completely
+    /// target-dependent semantics. Holds target flags, a 32-bit index, and a
+    /// 64-bit index. Targets can use this however they like.
+    TargetIndex,
+
+    /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+    /// This node represents a target intrinsic function with no side effects.
+    /// The first operand is the ID number of the intrinsic from the
+    /// llvm::Intrinsic namespace.  The operands to the intrinsic follow.  The
+    /// node returns the result of the intrinsic.
+    INTRINSIC_WO_CHAIN,
+
+    /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+    /// This node represents a target intrinsic function with side effects that
+    /// returns a result.  The first operand is a chain pointer.  The second is
+    /// the ID number of the intrinsic from the llvm::Intrinsic namespace.  The
+    /// operands to the intrinsic follow.  The node has two results, the result
+    /// of the intrinsic and an output chain.
+    INTRINSIC_W_CHAIN,
+
+    /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+    /// This node represents a target intrinsic function with side effects that
+    /// does not return a result.  The first operand is a chain pointer.  The
+    /// second is the ID number of the intrinsic from the llvm::Intrinsic
+    /// namespace.  The operands to the intrinsic follow.
+    INTRINSIC_VOID,
+
+    /// CopyToReg - This node has three operands: a chain, a register number to
+    /// set to this value, and a value.
+    CopyToReg,
+
+    /// CopyFromReg - This node indicates that the input value is a virtual or
+    /// physical register that is defined outside of the scope of this
+    /// SelectionDAG.  The register is available from the RegisterSDNode object.
+    CopyFromReg,
+
+    /// UNDEF - An undefined node.
+    UNDEF,
+
+    /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
+    /// a Constant, which is required to be operand #1) half of the integer or
+    /// float value specified as operand #0.  This is only for use before
+    /// legalization, for values that will be broken into multiple registers.
+    EXTRACT_ELEMENT,
+
+    /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
+    /// Given two values of the same integer value type, this produces a value
+    /// twice as big.  Like EXTRACT_ELEMENT, this can only be used before
+    /// legalization.
+    BUILD_PAIR,
+
+    /// MERGE_VALUES - This node takes multiple discrete operands and returns
+    /// them all as its individual results.  This nodes has exactly the same
+    /// number of inputs and outputs. This node is useful for some pieces of the
+    /// code generator that want to think about a single node with multiple
+    /// results, not multiple nodes.
+    MERGE_VALUES,
+
+    /// Simple integer binary arithmetic operators.
+    ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
+
+    /// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
+    /// a signed/unsigned value of type i[2*N], and return the full value as
+    /// two results, each of type iN.
+    SMUL_LOHI, UMUL_LOHI,
+
+    /// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
+    /// remainder result.
+    SDIVREM, UDIVREM,
+
+    /// CARRY_FALSE - This node is used when folding other nodes,
+    /// like ADDC/SUBC, which indicate the carry result is always false.
+    CARRY_FALSE,
+
+    /// Carry-setting nodes for multiple precision addition and subtraction.
+    /// These nodes take two operands of the same value type, and produce two
+    /// results.  The first result is the normal add or sub result, the second
+    /// result is the carry flag result.
+    ADDC, SUBC,
+
+    /// Carry-using nodes for multiple precision addition and subtraction. These
+    /// nodes take three operands: The first two are the normal lhs and rhs to
+    /// the add or sub, and the third is the input carry flag.  These nodes
+    /// produce two results; the normal result of the add or sub, and the output
+    /// carry flag.  These nodes both read and write a carry flag to allow them
+    /// to them to be chained together for add and sub of arbitrarily large
+    /// values.
+    ADDE, SUBE,
+
+    /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
+    /// These nodes take two operands: the normal LHS and RHS to the add. They
+    /// produce two results: the normal result of the add, and a boolean that
+    /// indicates if an overflow occurred (*not* a flag, because it may be store
+    /// to memory, etc.).  If the type of the boolean is not i1 then the high
+    /// bits conform to getBooleanContents.
+    /// These nodes are generated from llvm.[su]add.with.overflow intrinsics.
+    SADDO, UADDO,
+
+    /// Same for subtraction.
+    SSUBO, USUBO,
+
+    /// Same for multiplication.
+    SMULO, UMULO,
+
+    /// Simple binary floating point operators.
+    FADD, FSUB, FMUL, FMA, FDIV, FREM,
+
+    /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.  NOTE: This
+    /// DAG node does not require that X and Y have the same type, just that the
+    /// are both floating point.  X and the result must have the same type.
+    /// FCOPYSIGN(f32, f64) is allowed.
+    FCOPYSIGN,
+
+    /// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
+    /// value as an integer 0/1 value.
+    FGETSIGN,
+
+    /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
+    /// specified, possibly variable, elements.  The number of elements is
+    /// required to be a power of two.  The types of the operands must all be
+    /// the same and must match the vector element type, except that integer
+    /// types are allowed to be larger than the element type, in which case
+    /// the operands are implicitly truncated.
+    BUILD_VECTOR,
+
+    /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
+    /// at IDX replaced with VAL.  If the type of VAL is larger than the vector
+    /// element type then VAL is truncated before replacement.
+    INSERT_VECTOR_ELT,
+
+    /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+    /// identified by the (potentially variable) element number IDX.  If the
+    /// return type is an integer type larger than the element type of the
+    /// vector, the result is extended to the width of the return type.
+    EXTRACT_VECTOR_ELT,
+
+    /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
+    /// vector type with the same length and element type, this produces a
+    /// concatenated vector result value, with length equal to the sum of the
+    /// lengths of the input vectors.
+    CONCAT_VECTORS,
+
+    /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector
+    /// with VECTOR2 inserted into VECTOR1 at the (potentially
+    /// variable) element number IDX, which must be a multiple of the
+    /// VECTOR2 vector length.  The elements of VECTOR1 starting at
+    /// IDX are overwritten with VECTOR2.  Elements IDX through
+    /// vector_length(VECTOR2) must be valid VECTOR1 indices.
+    INSERT_SUBVECTOR,
+
+    /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
+    /// vector value) starting with the element number IDX, which must be a
+    /// constant multiple of the result vector length.
+    EXTRACT_SUBVECTOR,
+
+    /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
+    /// VEC1/VEC2.  A VECTOR_SHUFFLE node also contains an array of constant int
+    /// values that indicate which value (or undef) each result element will
+    /// get.  These constant ints are accessible through the
+    /// ShuffleVectorSDNode class.  This is quite similar to the Altivec
+    /// 'vperm' instruction, except that the indices must be constants and are
+    /// in terms of the element size of VEC1/VEC2, not in terms of bytes.
+    VECTOR_SHUFFLE,
+
+    /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+    /// scalar value into element 0 of the resultant vector type.  The top
+    /// elements 1 to N-1 of the N-element vector are undefined.  The type
+    /// of the operand must match the vector element type, except when they
+    /// are integer types.  In this case the operand is allowed to be wider
+    /// than the vector element type, and is implicitly truncated to it.
+    SCALAR_TO_VECTOR,
+
+    /// MULHU/MULHS - Multiply high - Multiply two integers of type iN,
+    /// producing an unsigned/signed value of type i[2*N], then return the top
+    /// part.
+    MULHU, MULHS,
+
+    /// Bitwise operators - logical and, logical or, logical xor.
+    AND, OR, XOR,
+
+    /// Shift and rotation operations.  After legalization, the type of the
+    /// shift amount is known to be TLI.getShiftAmountTy().  Before legalization
+    /// the shift amount can be any type, but care must be taken to ensure it is
+    /// large enough.  TLI.getShiftAmountTy() is i8 on some targets, but before
+    /// legalization, types like i1024 can occur and i8 doesn't have enough bits
+    /// to represent the shift amount.
+    /// When the 1st operand is a vector, the shift amount must be in the same
+    /// type. (TLI.getShiftAmountTy() will return the same type when the input
+    /// type is a vector.)
+    SHL, SRA, SRL, ROTL, ROTR,
+
+    /// Byte Swap and Counting operators.
+    BSWAP, CTTZ, CTLZ, CTPOP,
+
+    /// Bit counting operators with an undefined result for zero inputs.
+    CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF,
+
+    /// Select(COND, TRUEVAL, FALSEVAL).  If the type of the boolean COND is not
+    /// i1 then the high bits must conform to getBooleanContents.
+    SELECT,
+
+    /// Select with a vector condition (op #0) and two vector operands (ops #1
+    /// and #2), returning a vector result.  All vectors have the same length.
+    /// Much like the scalar select and setcc, each bit in the condition selects
+    /// whether the corresponding result element is taken from op #1 or op #2.
+    /// At first, the VSELECT condition is of vXi1 type. Later, targets may
+    /// change the condition type in order to match the VSELECT node using a
+    /// pattern. The condition follows the BooleanContent format of the target.
+    VSELECT,
+
+    /// Select with condition operator - This selects between a true value and
+    /// a false value (ops #2 and #3) based on the boolean result of comparing
+    /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
+    /// condition code in op #4, a CondCodeSDNode.
+    SELECT_CC,
+
+    /// SetCC operator - This evaluates to a true value iff the condition is
+    /// true.  If the result value type is not i1 then the high bits conform
+    /// to getBooleanContents.  The operands to this are the left and right
+    /// operands to compare (ops #0, and #1) and the condition code to compare
+    /// them with (op #2) as a CondCodeSDNode. If the operands are vector types
+    /// then the result type must also be a vector type.
+    SETCC,
+
+    /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+    /// integer shift operations, just like ADD/SUB_PARTS.  The operation
+    /// ordering is:
+    ///       [Lo,Hi] = op [LoLHS,HiLHS], Amt
+    SHL_PARTS, SRA_PARTS, SRL_PARTS,
+
+    /// Conversion operators.  These are all single input single output
+    /// operations.  For all of these, the result type must be strictly
+    /// wider or narrower (depending on the operation) than the source
+    /// type.
+
+    /// SIGN_EXTEND - Used for integer types, replicating the sign bit
+    /// into new bits.
+    SIGN_EXTEND,
+
+    /// ZERO_EXTEND - Used for integer types, zeroing the new bits.
+    ZERO_EXTEND,
+
+    /// ANY_EXTEND - Used for integer types.  The high bits are undefined.
+    ANY_EXTEND,
+
+    /// TRUNCATE - Completely drop the high bits.
+    TRUNCATE,
+
+    /// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+    /// depends on the first letter) to floating point.
+    SINT_TO_FP,
+    UINT_TO_FP,
+
+    /// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+    /// sign extend a small value in a large integer register (e.g. sign
+    /// extending the low 8 bits of a 32-bit register to fill the top 24 bits
+    /// with the 7th bit).  The size of the smaller type is indicated by the 1th
+    /// operand, a ValueType node.
+    SIGN_EXTEND_INREG,
+
+    /// ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+    /// in-register any-extension of the low lanes of an integer vector. The
+    /// result type must have fewer elements than the operand type, and those
+    /// elements must be larger integer types such that the total size of the
+    /// operand type and the result type match. Each of the low operand
+    /// elements is any-extended into the corresponding, wider result
+    /// elements with the high bits becoming undef.
+    ANY_EXTEND_VECTOR_INREG,
+
+    /// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+    /// in-register sign-extension of the low lanes of an integer vector. The
+    /// result type must have fewer elements than the operand type, and those
+    /// elements must be larger integer types such that the total size of the
+    /// operand type and the result type match. Each of the low operand
+    /// elements is sign-extended into the corresponding, wider result
+    /// elements.
+    // FIXME: The SIGN_EXTEND_INREG node isn't specifically limited to
+    // scalars, but it also doesn't handle vectors well. Either it should be
+    // restricted to scalars or this node (and its handling) should be merged
+    // into it.
+    SIGN_EXTEND_VECTOR_INREG,
+
+    /// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+    /// in-register zero-extension of the low lanes of an integer vector. The
+    /// result type must have fewer elements than the operand type, and those
+    /// elements must be larger integer types such that the total size of the
+    /// operand type and the result type match. Each of the low operand
+    /// elements is zero-extended into the corresponding, wider result
+    /// elements.
+    ZERO_EXTEND_VECTOR_INREG,
+
+    /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
+    /// integer.
+    FP_TO_SINT,
+    FP_TO_UINT,
+
+    /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
+    /// down to the precision of the destination VT.  TRUNC is a flag, which is
+    /// always an integer that is zero or one.  If TRUNC is 0, this is a
+    /// normal rounding, if it is 1, this FP_ROUND is known to not change the
+    /// value of Y.
+    ///
+    /// The TRUNC = 1 case is used in cases where we know that the value will
+    /// not be modified by the node, because Y is not using any of the extra
+    /// precision of source type.  This allows certain transformations like
+    /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
+    /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
+    FP_ROUND,
+
+    /// FLT_ROUNDS_ - Returns current rounding mode:
+    /// -1 Undefined
+    ///  0 Round to 0
+    ///  1 Round to nearest
+    ///  2 Round to +inf
+    ///  3 Round to -inf
+    FLT_ROUNDS_,
+
+    /// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and
+    /// rounds it to a floating point value.  It then promotes it and returns it
+    /// in a register of the same size.  This operation effectively just
+    /// discards excess precision.  The type to round down to is specified by
+    /// the VT operand, a VTSDNode.
+    FP_ROUND_INREG,
+
+    /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
+    FP_EXTEND,
+
+    /// BITCAST - This operator converts between integer, vector and FP
+    /// values, as if the value was stored to memory with one type and loaded
+    /// from the same address with the other type (or equivalently for vector
+    /// format conversions, etc).  The source and result are required to have
+    /// the same bit size (e.g.  f32 <-> i32).  This can also be used for
+    /// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
+    /// getNode().
+    BITCAST,
+
+    /// ADDRSPACECAST - This operator converts between pointers of different
+    /// address spaces.
+    ADDRSPACECAST,
+
+    /// CONVERT_RNDSAT - This operator is used to support various conversions
+    /// between various types (float, signed, unsigned and vectors of those
+    /// types) with rounding and saturation. NOTE: Avoid using this operator as
+    /// most target don't support it and the operator might be removed in the
+    /// future. It takes the following arguments:
+    ///   0) value
+    ///   1) dest type (type to convert to)
+    ///   2) src type (type to convert from)
+    ///   3) rounding imm
+    ///   4) saturation imm
+    ///   5) ISD::CvtCode indicating the type of conversion to do
+    CONVERT_RNDSAT,
+
+    /// FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions
+    /// and truncation for half-precision (16 bit) floating numbers. These nodes
+    /// form a semi-softened interface for dealing with f16 (as an i16), which
+    /// is often a storage-only type but has native conversions.
+    FP16_TO_FP, FP_TO_FP16,
+
+    /// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
+    /// FLOG, FLOG2, FLOG10, FEXP, FEXP2,
+    /// FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR - Perform various unary
+    /// floating point operations. These are inspired by libm.
+    FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
+    FLOG, FLOG2, FLOG10, FEXP, FEXP2,
+    FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR,
+    
+    /// FSINCOS - Compute both fsin and fcos as a single operation.
+    FSINCOS,
+
+    /// LOAD and STORE have token chains as their first operand, then the same
+    /// operands as an LLVM load/store instruction, then an offset node that
+    /// is added / subtracted from the base pointer to form the address (for
+    /// indexed memory ops).
+    LOAD, STORE,
+
+    /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+    /// to a specified boundary.  This node always has two return values: a new
+    /// stack pointer value and a chain. The first operand is the token chain,
+    /// the second is the number of bytes to allocate, and the third is the
+    /// alignment boundary.  The size is guaranteed to be a multiple of the
+    /// stack alignment, and the alignment is guaranteed to be bigger than the
+    /// stack alignment (if required) or 0 to get standard stack alignment.
+    DYNAMIC_STACKALLOC,
+
+    /// Control flow instructions.  These all have token chains.
+
+    /// BR - Unconditional branch.  The first operand is the chain
+    /// operand, the second is the MBB to branch to.
+    BR,
+
+    /// BRIND - Indirect branch.  The first operand is the chain, the second
+    /// is the value to branch to, which must be of the same type as the
+    /// target's pointer type.
+    BRIND,
+
+    /// BR_JT - Jumptable branch. The first operand is the chain, the second
+    /// is the jumptable index, the last one is the jumptable entry index.
+    BR_JT,
+
+    /// BRCOND - Conditional branch.  The first operand is the chain, the
+    /// second is the condition, the third is the block to branch to if the
+    /// condition is true.  If the type of the condition is not i1, then the
+    /// high bits must conform to getBooleanContents.
+    BRCOND,
+
+    /// BR_CC - Conditional branch.  The behavior is like that of SELECT_CC, in
+    /// that the condition is represented as condition code, and two nodes to
+    /// compare, rather than as a combined SetCC node.  The operands in order
+    /// are chain, cc, lhs, rhs, block to branch to if condition is true.
+    BR_CC,
+
+    /// INLINEASM - Represents an inline asm block.  This node always has two
+    /// return values: a chain and a flag result.  The inputs are as follows:
+    ///   Operand #0  : Input chain.
+    ///   Operand #1  : a ExternalSymbolSDNode with a pointer to the asm string.
+    ///   Operand #2  : a MDNodeSDNode with the !srcloc metadata.
+    ///   Operand #3  : HasSideEffect, IsAlignStack bits.
+    ///   After this, it is followed by a list of operands with this format:
+    ///     ConstantSDNode: Flags that encode whether it is a mem or not, the
+    ///                     of operands that follow, etc.  See InlineAsm.h.
+    ///     ... however many operands ...
+    ///   Operand #last: Optional, an incoming flag.
+    ///
+    /// The variable width operands are required to represent target addressing
+    /// modes as a single "operand", even though they may have multiple
+    /// SDOperands.
+    INLINEASM,
+
+    /// EH_LABEL - Represents a label in mid basic block used to track
+    /// locations needed for debug and exception handling tables.  These nodes
+    /// take a chain as input and return a chain.
+    EH_LABEL,
+
+    /// STACKSAVE - STACKSAVE has one operand, an input chain.  It produces a
+    /// value, the same type as the pointer type for the system, and an output
+    /// chain.
+    STACKSAVE,
+
+    /// STACKRESTORE has two operands, an input chain and a pointer to restore
+    /// to it returns an output chain.
+    STACKRESTORE,
+
+    /// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end
+    /// of a call sequence, and carry arbitrary information that target might
+    /// want to know.  The first operand is a chain, the rest are specified by
+    /// the target and not touched by the DAG optimizers.
+    /// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
+    CALLSEQ_START,  // Beginning of a call sequence
+    CALLSEQ_END,    // End of a call sequence
+
+    /// VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
+    /// and the alignment. It returns a pair of values: the vaarg value and a
+    /// new chain.
+    VAARG,
+
+    /// VACOPY - VACOPY has 5 operands: an input chain, a destination pointer,
+    /// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+    /// source.
+    VACOPY,
+
+    /// VAEND, VASTART - VAEND and VASTART have three operands: an input chain,
+    /// pointer, and a SRCVALUE.
+    VAEND, VASTART,
+
+    /// SRCVALUE - This is a node type that holds a Value* that is used to
+    /// make reference to a value in the LLVM IR.
+    SRCVALUE,
+
+    /// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
+    /// reference metadata in the IR.
+    MDNODE_SDNODE,
+
+    /// PCMARKER - This corresponds to the pcmarker intrinsic.
+    PCMARKER,
+
+    /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+    /// The only operand is a chain and a value and a chain are produced.  The
+    /// value is the contents of the architecture specific cycle counter like
+    /// register (or other high accuracy low latency clock source)
+    READCYCLECOUNTER,
+
+    /// HANDLENODE node - Used as a handle for various purposes.
+    HANDLENODE,
+
+    /// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.  It
+    /// takes as input a token chain, the pointer to the trampoline, the pointer
+    /// to the nested function, the pointer to pass for the 'nest' parameter, a
+    /// SRCVALUE for the trampoline and another for the nested function
+    /// (allowing targets to access the original Function*).
+    /// It produces a token chain as output.
+    INIT_TRAMPOLINE,
+
+    /// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
+    /// It takes a pointer to the trampoline and produces a (possibly) new
+    /// pointer to the same trampoline with platform-specific adjustments
+    /// applied.  The pointer it returns points to an executable block of code.
+    ADJUST_TRAMPOLINE,
+
+    /// TRAP - Trapping instruction
+    TRAP,
+
+    /// DEBUGTRAP - Trap intended to get the attention of a debugger.
+    DEBUGTRAP,
+
+    /// PREFETCH - This corresponds to a prefetch intrinsic. The first operand
+    /// is the chain.  The other operands are the address to prefetch,
+    /// read / write specifier, locality specifier and instruction / data cache
+    /// specifier.
+    PREFETCH,
+
+    /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
+    /// This corresponds to the fence instruction. It takes an input chain, and
+    /// two integer constants: an AtomicOrdering and a SynchronizationScope.
+    ATOMIC_FENCE,
+
+    /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
+    /// This corresponds to "load atomic" instruction.
+    ATOMIC_LOAD,
+
+    /// OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val)
+    /// This corresponds to "store atomic" instruction.
+    ATOMIC_STORE,
+
+    /// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
+    /// For double-word atomic operations:
+    /// ValLo, ValHi, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmpLo, cmpHi,
+    ///                                          swapLo, swapHi)
+    /// This corresponds to the cmpxchg instruction.
+    ATOMIC_CMP_SWAP,
+
+    /// Val, Success, OUTCHAIN
+    ///     = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap)
+    /// N.b. this is still a strong cmpxchg operation, so
+    /// Success == "Val == cmp".
+    ATOMIC_CMP_SWAP_WITH_SUCCESS,
+
+    /// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
+    /// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
+    /// For double-word atomic operations:
+    /// ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi)
+    /// ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi)
+    /// These correspond to the atomicrmw instruction.
+    ATOMIC_SWAP,
+    ATOMIC_LOAD_ADD,
+    ATOMIC_LOAD_SUB,
+    ATOMIC_LOAD_AND,
+    ATOMIC_LOAD_OR,
+    ATOMIC_LOAD_XOR,
+    ATOMIC_LOAD_NAND,
+    ATOMIC_LOAD_MIN,
+    ATOMIC_LOAD_MAX,
+    ATOMIC_LOAD_UMIN,
+    ATOMIC_LOAD_UMAX,
+
+    /// This corresponds to the llvm.lifetime.* intrinsics. The first operand
+    /// is the chain and the second operand is the alloca pointer.
+    LIFETIME_START, LIFETIME_END,
+
+    /// BUILTIN_OP_END - This must be the last enum value in this list.
+    /// The target-specific pre-isel opcode values start here.
+    BUILTIN_OP_END
+  };
+
+  /// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
+  /// which do not reference a specific memory location should be less than
+  /// this value. Those that do must not be less than this value, and can
+  /// be used with SelectionDAG::getMemIntrinsicNode.
+  static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+180;
+
+  //===--------------------------------------------------------------------===//
+  /// MemIndexedMode enum - This enum defines the load / store indexed
+  /// addressing modes.
+  ///
+  /// UNINDEXED    "Normal" load / store. The effective address is already
+  ///              computed and is available in the base pointer. The offset
+  ///              operand is always undefined. In addition to producing a
+  ///              chain, an unindexed load produces one value (result of the
+  ///              load); an unindexed store does not produce a value.
+  ///
+  /// PRE_INC      Similar to the unindexed mode where the effective address is
+  /// PRE_DEC      the value of the base pointer add / subtract the offset.
+  ///              It considers the computation as being folded into the load /
+  ///              store operation (i.e. the load / store does the address
+  ///              computation as well as performing the memory transaction).
+  ///              The base operand is always undefined. In addition to
+  ///              producing a chain, pre-indexed load produces two values
+  ///              (result of the load and the result of the address
+  ///              computation); a pre-indexed store produces one value (result
+  ///              of the address computation).
+  ///
+  /// POST_INC     The effective address is the value of the base pointer. The
+  /// POST_DEC     value of the offset operand is then added to / subtracted
+  ///              from the base after memory transaction. In addition to
+  ///              producing a chain, post-indexed load produces two values
+  ///              (the result of the load and the result of the base +/- offset
+  ///              computation); a post-indexed store produces one value (the
+  ///              the result of the base +/- offset computation).
+  enum MemIndexedMode {
+    UNINDEXED = 0,
+    PRE_INC,
+    PRE_DEC,
+    POST_INC,
+    POST_DEC,
+    LAST_INDEXED_MODE
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// LoadExtType enum - This enum defines the three variants of LOADEXT
+  /// (load with extension).
+  ///
+  /// SEXTLOAD loads the integer operand and sign extends it to a larger
+  ///          integer result type.
+  /// ZEXTLOAD loads the integer operand and zero extends it to a larger
+  ///          integer result type.
+  /// EXTLOAD  is used for two things: floating point extending loads and
+  ///          integer extending loads [the top bits are undefined].
+  enum LoadExtType {
+    NON_EXTLOAD = 0,
+    EXTLOAD,
+    SEXTLOAD,
+    ZEXTLOAD,
+    LAST_LOADEXT_TYPE
+  };
+
+  NodeType getExtForLoadExtType(LoadExtType);
+
+  //===--------------------------------------------------------------------===//
+  /// ISD::CondCode enum - These are ordered carefully to make the bitfields
+  /// below work out, when considering SETFALSE (something that never exists
+  /// dynamically) as 0.  "U" -> Unsigned (for integer operands) or Unordered
+  /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
+  /// to.  If the "N" column is 1, the result of the comparison is undefined if
+  /// the input is a NAN.
+  ///
+  /// All of these (except for the 'always folded ops') should be handled for
+  /// floating point.  For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
+  /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+  ///
+  /// Note that these are laid out in a specific order to allow bit-twiddling
+  /// to transform conditions.
+  enum CondCode {
+    // Opcode          N U L G E       Intuitive operation
+    SETFALSE,      //    0 0 0 0       Always false (always folded)
+    SETOEQ,        //    0 0 0 1       True if ordered and equal
+    SETOGT,        //    0 0 1 0       True if ordered and greater than
+    SETOGE,        //    0 0 1 1       True if ordered and greater than or equal
+    SETOLT,        //    0 1 0 0       True if ordered and less than
+    SETOLE,        //    0 1 0 1       True if ordered and less than or equal
+    SETONE,        //    0 1 1 0       True if ordered and operands are unequal
+    SETO,          //    0 1 1 1       True if ordered (no nans)
+    SETUO,         //    1 0 0 0       True if unordered: isnan(X) | isnan(Y)
+    SETUEQ,        //    1 0 0 1       True if unordered or equal
+    SETUGT,        //    1 0 1 0       True if unordered or greater than
+    SETUGE,        //    1 0 1 1       True if unordered, greater than, or equal
+    SETULT,        //    1 1 0 0       True if unordered or less than
+    SETULE,        //    1 1 0 1       True if unordered, less than, or equal
+    SETUNE,        //    1 1 1 0       True if unordered or not equal
+    SETTRUE,       //    1 1 1 1       Always true (always folded)
+    // Don't care operations: undefined if the input is a nan.
+    SETFALSE2,     //  1 X 0 0 0       Always false (always folded)
+    SETEQ,         //  1 X 0 0 1       True if equal
+    SETGT,         //  1 X 0 1 0       True if greater than
+    SETGE,         //  1 X 0 1 1       True if greater than or equal
+    SETLT,         //  1 X 1 0 0       True if less than
+    SETLE,         //  1 X 1 0 1       True if less than or equal
+    SETNE,         //  1 X 1 1 0       True if not equal
+    SETTRUE2,      //  1 X 1 1 1       Always true (always folded)
+
+    SETCC_INVALID       // Marker value.
+  };
+
+  /// isSignedIntSetCC - Return true if this is a setcc instruction that
+  /// performs a signed comparison when used with integer operands.
+  inline bool isSignedIntSetCC(CondCode Code) {
+    return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
+  }
+
+  /// isUnsignedIntSetCC - Return true if this is a setcc instruction that
+  /// performs an unsigned comparison when used with integer operands.
+  inline bool isUnsignedIntSetCC(CondCode Code) {
+    return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
+  }
+
+  /// isTrueWhenEqual - Return true if the specified condition returns true if
+  /// the two operands to the condition are equal.  Note that if one of the two
+  /// operands is a NaN, this value is meaningless.
+  inline bool isTrueWhenEqual(CondCode Cond) {
+    return ((int)Cond & 1) != 0;
+  }
+
+  /// getUnorderedFlavor - This function returns 0 if the condition is always
+  /// false if an operand is a NaN, 1 if the condition is always true if the
+  /// operand is a NaN, and 2 if the condition is undefined if the operand is a
+  /// NaN.
+  inline unsigned getUnorderedFlavor(CondCode Cond) {
+    return ((int)Cond >> 3) & 3;
+  }
+
+  /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
+  /// 'op' is a valid SetCC operation.
+  CondCode getSetCCInverse(CondCode Operation, bool isInteger);
+
+  /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
+  /// when given the operation for (X op Y).
+  CondCode getSetCCSwappedOperands(CondCode Operation);
+
+  /// getSetCCOrOperation - Return the result of a logical OR between different
+  /// comparisons of identical values: ((X op1 Y) | (X op2 Y)).  This
+  /// function returns SETCC_INVALID if it is not possible to represent the
+  /// resultant comparison.
+  CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+  /// getSetCCAndOperation - Return the result of a logical AND between
+  /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)).  This
+  /// function returns SETCC_INVALID if it is not possible to represent the
+  /// resultant comparison.
+  CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+  //===--------------------------------------------------------------------===//
+  /// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
+  /// supports.
+  enum CvtCode {
+    CVT_FF,     /// Float from Float
+    CVT_FS,     /// Float from Signed
+    CVT_FU,     /// Float from Unsigned
+    CVT_SF,     /// Signed from Float
+    CVT_UF,     /// Unsigned from Float
+    CVT_SS,     /// Signed from Signed
+    CVT_SU,     /// Signed from Unsigned
+    CVT_US,     /// Unsigned from Signed
+    CVT_UU,     /// Unsigned from Unsigned
+    CVT_INVALID /// Marker - Invalid opcode
+  };
+
+} // end llvm::ISD namespace
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
new file mode 100644
index 0000000..9e6ab7d
--- /dev/null
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -0,0 +1,59 @@
+//===-- IntrinsicLowering.h - Intrinsic Function Lowering -------*- 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 IntrinsicLowering interface.  This interface allows
+// addition of domain-specific or front-end specific intrinsics to LLVM without
+// having to modify all of the C backend or interpreter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H
+#define LLVM_CODEGEN_INTRINSICLOWERING_H
+
+#include "llvm/IR/Intrinsics.h"
+
+namespace llvm {
+  class CallInst;
+  class Module;
+  class DataLayout;
+
+  class IntrinsicLowering {
+    const DataLayout& DL;
+
+    
+    bool Warned;
+  public:
+    explicit IntrinsicLowering(const DataLayout &DL) :
+      DL(DL), Warned(false) {}
+
+    /// AddPrototypes - This method, if called, causes all of the prototypes
+    /// that might be needed by an intrinsic lowering implementation to be
+    /// inserted into the module specified.
+    void AddPrototypes(Module &M);
+
+    /// LowerIntrinsicCall - This method replaces a call with the LLVM function
+    /// which should be used to implement the specified intrinsic function call.
+    /// If an intrinsic function must be implemented by the code generator 
+    /// (such as va_start), this function should print a message and abort.
+    ///
+    /// Otherwise, if an intrinsic function call can be lowered, the code to
+    /// implement it (often a call to a non-intrinsic function) is inserted
+    /// _after_ the call instruction and the call is deleted.  The caller must
+    /// be capable of handling this kind of change.
+    ///
+    void LowerIntrinsicCall(CallInst *CI);
+
+    /// LowerToByteSwap - Replace a call instruction into a call to bswap
+    /// intrinsic. Return false if it has determined the call is not a
+    /// simple integer bswap.
+    static bool LowerToByteSwap(CallInst *CI);
+  };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
new file mode 100644
index 0000000..dc2a027
--- /dev/null
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -0,0 +1,344 @@
+//===-- llvm/CodeGen/JITCodeEmitter.h - Code emission ----------*- 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 an abstract interface that is used by the machine code
+// emission framework to output the code.  This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_JITCODEEMITTER_H
+#define LLVM_CODEGEN_JITCODEEMITTER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <string>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+  
+/// JITCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxiliary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it.  As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer.  As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit.  In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores.  Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+/// 
+class JITCodeEmitter : public MachineCodeEmitter {
+  void anchor() override;
+public:
+  virtual ~JITCodeEmitter() {}
+
+  /// startFunction - This callback is invoked when the specified function is
+  /// about to be code generated.  This initializes the BufferBegin/End/Ptr
+  /// fields.
+  ///
+  void startFunction(MachineFunction &F) override = 0;
+
+  /// finishFunction - This callback is invoked when the specified function has
+  /// finished code generation.  If a buffer overflow has occurred, this method
+  /// returns true (the callee is required to try again), otherwise it returns
+  /// false.
+  ///
+  bool finishFunction(MachineFunction &F) override = 0;
+
+  /// allocIndirectGV - Allocates and fills storage for an indirect
+  /// GlobalValue, and returns the address.
+  virtual void *allocIndirectGV(const GlobalValue *GV,
+                                const uint8_t *Buffer, size_t Size,
+                                unsigned Alignment) = 0;
+
+  /// emitByte - This callback is invoked when a byte needs to be written to the
+  /// output stream.
+  ///
+  void emitByte(uint8_t B) {
+    if (CurBufferPtr != BufferEnd)
+      *CurBufferPtr++ = B;
+  }
+
+  /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+  /// written to the output stream in little-endian format.
+  ///
+  void emitWordLE(uint32_t W) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+  /// written to the output stream in big-endian format.
+  ///
+  void emitWordBE(uint32_t W) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in little-endian format.
+  ///
+  void emitDWordLE(uint64_t W) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 32);
+      *CurBufferPtr++ = (uint8_t)(W >> 40);
+      *CurBufferPtr++ = (uint8_t)(W >> 48);
+      *CurBufferPtr++ = (uint8_t)(W >> 56);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in big-endian format.
+  ///
+  void emitDWordBE(uint64_t W) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >> 56);
+      *CurBufferPtr++ = (uint8_t)(W >> 48);
+      *CurBufferPtr++ = (uint8_t)(W >> 40);
+      *CurBufferPtr++ = (uint8_t)(W >> 32);
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitAlignment - Move the CurBufferPtr pointer up to the specified
+  /// alignment (saturated to BufferEnd of course).
+  void emitAlignment(unsigned Alignment) {
+    if (Alignment == 0) Alignment = 1;
+    uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
+                                                   Alignment);
+    CurBufferPtr = std::min(NewPtr, BufferEnd);
+  }
+
+  /// emitAlignmentWithFill - Similar to emitAlignment, except that the
+  /// extra bytes are filled with the provided byte.
+  void emitAlignmentWithFill(unsigned Alignment, uint8_t Fill) {
+    if (Alignment == 0) Alignment = 1;
+    uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
+                                                   Alignment);
+    // Fail if we don't have room.
+    if (NewPtr > BufferEnd) {
+      CurBufferPtr = BufferEnd;
+      return;
+    }
+    while (CurBufferPtr < NewPtr) {
+      *CurBufferPtr++ = Fill;
+    }
+  }
+
+  /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+  /// written to the output stream.
+  void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) {
+    do {
+      uint8_t Byte = Value & 0x7f;
+      Value >>= 7;
+      if (Value || PadTo != 0) Byte |= 0x80;
+      emitByte(Byte);
+    } while (Value);
+
+    if (PadTo) {
+      do {
+        uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0;
+        emitByte(Byte);
+      } while (--PadTo);
+    }
+  }
+  
+  /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+  /// written to the output stream.
+  void emitSLEB128Bytes(int64_t Value) {
+    int32_t Sign = Value >> (8 * sizeof(Value) - 1);
+    bool IsMore;
+  
+    do {
+      uint8_t Byte = Value & 0x7f;
+      Value >>= 7;
+      IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+      if (IsMore) Byte |= 0x80;
+      emitByte(Byte);
+    } while (IsMore);
+  }
+
+  /// emitString - This callback is invoked when a String needs to be
+  /// written to the output stream.
+  void emitString(const std::string &String) {
+    for (size_t i = 0, N = String.size(); i < N; ++i) {
+      uint8_t C = String[i];
+      emitByte(C);
+    }
+    emitByte(0);
+  }
+  
+  /// emitInt32 - Emit a int32 directive.
+  void emitInt32(uint32_t Value) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      *((uint32_t*)CurBufferPtr) = Value;
+      CurBufferPtr += 4;
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitInt64 - Emit a int64 directive.
+  void emitInt64(uint64_t Value) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *((uint64_t*)CurBufferPtr) = Value;
+      CurBufferPtr += 8;
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitInt32At - Emit the Int32 Value in Addr.
+  void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
+    if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+      (*(uint32_t*)Addr) = (uint32_t)Value;
+  }
+  
+  /// emitInt64At - Emit the Int64 Value in Addr.
+  void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
+    if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+      (*(uint64_t*)Addr) = (uint64_t)Value;
+  }
+  
+  
+  /// emitLabel - Emits a label
+  void emitLabel(MCSymbol *Label) override = 0;
+
+  /// allocateSpace - Allocate a block of space in the current output buffer,
+  /// returning null (and setting conditions to indicate buffer overflow) on
+  /// failure.  Alignment is the alignment in bytes of the buffer desired.
+  void *allocateSpace(uintptr_t Size, unsigned Alignment) override {
+    emitAlignment(Alignment);
+    void *Result;
+    
+    // Check for buffer overflow.
+    if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+      CurBufferPtr = BufferEnd;
+      Result = nullptr;
+    } else {
+      // Allocate the space.
+      Result = CurBufferPtr;
+      CurBufferPtr += Size;
+    }
+    
+    return Result;
+  }
+
+  /// allocateGlobal - Allocate memory for a global.  Unlike allocateSpace,
+  /// this method does not allocate memory in the current output buffer,
+  /// because a global may live longer than the current function.
+  virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
+
+  /// StartMachineBasicBlock - This should be called by the target when a new
+  /// basic block is about to be emitted.  This way the MCE knows where the
+  /// start of the block is, and can implement getMachineBasicBlockAddress.
+  void StartMachineBasicBlock(MachineBasicBlock *MBB) override = 0;
+
+  /// getCurrentPCValue - This returns the address that the next emitted byte
+  /// will be output to.
+  ///
+  uintptr_t getCurrentPCValue() const override {
+    return (uintptr_t)CurBufferPtr;
+  }
+
+  /// getCurrentPCOffset - Return the offset from the start of the emitted
+  /// buffer that we are currently writing to.
+  uintptr_t getCurrentPCOffset() const override {
+    return CurBufferPtr-BufferBegin;
+  }
+
+  /// earlyResolveAddresses - True if the code emitter can use symbol addresses 
+  /// during code emission time. The JIT is capable of doing this because it
+  /// creates jump tables or constant pools in memory on the fly while the
+  /// object code emitters rely on a linker to have real addresses and should
+  /// use relocations instead.
+  bool earlyResolveAddresses() const override { return true; }
+
+  /// addRelocation - Whenever a relocatable address is needed, it should be
+  /// noted with this interface.
+  void addRelocation(const MachineRelocation &MR) override = 0;
+
+  /// FIXME: These should all be handled with relocations!
+  
+  /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+  /// the constant pool that was last emitted with the emitConstantPool method.
+  ///
+  uintptr_t getConstantPoolEntryAddress(unsigned Index) const override = 0;
+
+  /// getJumpTableEntryAddress - Return the address of the jump table with index
+  /// 'Index' in the function that last called initJumpTableInfo.
+  ///
+  uintptr_t getJumpTableEntryAddress(unsigned Index) const override = 0;
+
+  /// getMachineBasicBlockAddress - Return the address of the specified
+  /// MachineBasicBlock, only usable after the label for the MBB has been
+  /// emitted.
+  ///
+  uintptr_t
+    getMachineBasicBlockAddress(MachineBasicBlock *MBB) const override = 0;
+
+  /// getLabelAddress - Return the address of the specified Label, only usable
+  /// after the Label has been emitted.
+  ///
+  uintptr_t getLabelAddress(MCSymbol *Label) const override = 0;
+
+  /// Specifies the MachineModuleInfo object. This is used for exception handling
+  /// purposes.
+  void setModuleInfo(MachineModuleInfo* Info) override = 0;
+
+  /// getLabelLocations - Return the label locations map of the label IDs to
+  /// their address.
+  virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() {
+    return nullptr;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/JumpInstrTables.h b/include/llvm/CodeGen/JumpInstrTables.h
new file mode 100644
index 0000000..6ca3d7d
--- /dev/null
+++ b/include/llvm/CodeGen/JumpInstrTables.h
@@ -0,0 +1,104 @@
+//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief An implementation of tables consisting of jump instructions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H
+#define LLVM_CODEGEN_JUMPINSTRTABLES_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetOptions.h"
+
+namespace llvm {
+class Constant;
+class Function;
+class FunctionType;
+class JumpInstrTableInfo;
+class Module;
+
+/// A class to manage a set of jump tables indexed on function type. It looks at
+/// each function in the module to find all the functions that have the
+/// jumptable attribute set. For each such function, it creates a new
+/// jump-instruction-table function and stores the mapping in the ImmutablePass
+/// JumpInstrTableInfo.
+///
+/// These special functions get lowered in AsmPrinter to assembly of the form:
+/// \verbatim
+///   .globl f
+///   .type f,@function
+///   .align 8,0x90
+/// f:
+///   jmp f_orig@PLT
+/// \endverbatim
+///
+/// Support for an architecture depends on two functions in TargetInstrInfo:
+/// getUnconditionalBranch, and getTrap. AsmPrinter uses these to generate the
+/// appropriate instructions for the jump statement (an unconditional branch)
+/// and for padding to make the table have a size that is a power of two. This
+/// padding uses a trap instruction to ensure that calls to this area halt the
+/// program. The default implementations of these functions call
+/// llvm_unreachable.
+class JumpInstrTables : public ModulePass {
+public:
+  static char ID;
+
+  JumpInstrTables();
+  JumpInstrTables(JumpTable::JumpTableType JTT);
+  virtual ~JumpInstrTables();
+  bool runOnModule(Module &M) override;
+  const char *getPassName() const override { return "Jump-Instruction Tables"; }
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// Creates a jump-instruction table function for the Target and adds it to
+  /// the tables.
+  Function *insertEntry(Module &M, Function *Target);
+
+  /// Checks to see if there is already a table for the given FunctionType.
+  bool hasTable(FunctionType *FunTy);
+
+private:
+  /// The metadata used while a jump table is being built
+  struct TableMeta {
+    /// The number of this table
+    unsigned TableNum;
+
+    /// The current number of jump entries in the table.
+    unsigned Count;
+  };
+
+  typedef DenseMap<FunctionType *, struct TableMeta> JumpMap;
+
+  /// Maps the function into a subset of function types, depending on the
+  /// jump-instruction table style selected from JumpTableTypes in
+  /// JumpInstrTables.cpp. The choice of mapping determines the number of
+  /// jump-instruction tables generated by this pass. E.g., the simplest mapping
+  /// converts every function type into void f(); so, all functions end up in a
+  /// single table.
+  FunctionType *transformType(FunctionType *FunTy);
+
+  /// The current state of functions and jump entries in the table(s).
+  JumpMap Metadata;
+
+  /// The ImmutablePass that stores information about the generated tables.
+  JumpInstrTableInfo *JITI;
+
+  /// The total number of tables.
+  unsigned TableCount;
+
+  /// The type of tables to build.
+  JumpTable::JumpTableType JTType;
+};
+
+/// Creates a JumpInstrTables pass for the given type of jump table.
+ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT);
+}
+
+#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
new file mode 100644
index 0000000..cf601ae
--- /dev/null
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -0,0 +1,100 @@
+//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
+//
+//                     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 LatencyPriorityQueue class, which is a
+// SchedulingPriorityQueue that schedules using latency information to
+// reduce the length of the critical path through the basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
+#define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+
+namespace llvm {
+  class LatencyPriorityQueue;
+
+  /// Sorting functions for the Available queue.
+  struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+    LatencyPriorityQueue *PQ;
+    explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
+
+    bool operator()(const SUnit* left, const SUnit* right) const;
+  };
+
+  class LatencyPriorityQueue : public SchedulingPriorityQueue {
+    // SUnits - The SUnits for the current graph.
+    std::vector<SUnit> *SUnits;
+
+    /// NumNodesSolelyBlocking - This vector contains, for every node in the
+    /// Queue, the number of nodes that the node is the sole unscheduled
+    /// predecessor for.  This is used as a tie-breaker heuristic for better
+    /// mobility.
+    std::vector<unsigned> NumNodesSolelyBlocking;
+
+    /// Queue - The queue.
+    std::vector<SUnit*> Queue;
+    latency_sort Picker;
+
+  public:
+    LatencyPriorityQueue() : Picker(this) {
+    }
+
+    bool isBottomUp() const override { return false; }
+
+    void initNodes(std::vector<SUnit> &sunits) override {
+      SUnits = &sunits;
+      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+    }
+
+    void addNode(const SUnit *SU) override {
+      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+    }
+
+    void updateNode(const SUnit *SU) override {
+    }
+
+    void releaseState() override {
+      SUnits = nullptr;
+    }
+
+    unsigned getLatency(unsigned NodeNum) const {
+      assert(NodeNum < (*SUnits).size());
+      return (*SUnits)[NodeNum].getHeight();
+    }
+
+    unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
+      assert(NodeNum < NumNodesSolelyBlocking.size());
+      return NumNodesSolelyBlocking[NodeNum];
+    }
+
+    bool empty() const override { return Queue.empty(); }
+
+    void push(SUnit *U) override;
+
+    SUnit *pop() override;
+
+    void remove(SUnit *SU) override;
+
+    void dump(ScheduleDAG* DAG) const override;
+
+    // scheduledNode - As nodes are scheduled, we look to see if there are any
+    // successor nodes that have a single unscheduled predecessor.  If so, that
+    // single predecessor has a higher priority, since scheduling it will make
+    // the node available.
+    void scheduledNode(SUnit *Node) override;
+
+private:
+    void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
+    SUnit *getSingleUnscheduledPred(SUnit *SU);
+  };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
new file mode 100644
index 0000000..036aea3
--- /dev/null
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -0,0 +1,251 @@
+//===- LexicalScopes.cpp - Collecting lexical scope 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 implements LexicalScopes analysis.
+//
+// This pass collects lexical scope information and maps machine instructions
+// to respective lexical scopes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LEXICALSCOPES_H
+#define LLVM_CODEGEN_LEXICALSCOPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
+#include <utility>
+#include <unordered_map>
+namespace llvm {
+
+class MachineInstr;
+class MachineBasicBlock;
+class MachineFunction;
+
+//===----------------------------------------------------------------------===//
+/// InsnRange - This is used to track range of instructions with identical
+/// lexical scope.
+///
+typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
+
+//===----------------------------------------------------------------------===//
+/// LexicalScope - This class is used to track scope information.
+///
+class LexicalScope {
+
+public:
+  LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
+      : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
+        LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) {
+    if (Parent)
+      Parent->addChild(this);
+  }
+
+  // Accessors.
+  LexicalScope *getParent() const { return Parent; }
+  const MDNode *getDesc() const { return Desc; }
+  const MDNode *getInlinedAt() const { return InlinedAtLocation; }
+  const MDNode *getScopeNode() const { return Desc; }
+  bool isAbstractScope() const { return AbstractScope; }
+  SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
+  SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
+
+  /// addChild - Add a child scope.
+  void addChild(LexicalScope *S) { Children.push_back(S); }
+
+  /// openInsnRange - This scope covers instruction range starting from MI.
+  void openInsnRange(const MachineInstr *MI) {
+    if (!FirstInsn)
+      FirstInsn = MI;
+
+    if (Parent)
+      Parent->openInsnRange(MI);
+  }
+
+  /// extendInsnRange - Extend the current instruction range covered by
+  /// this scope.
+  void extendInsnRange(const MachineInstr *MI) {
+    assert(FirstInsn && "MI Range is not open!");
+    LastInsn = MI;
+    if (Parent)
+      Parent->extendInsnRange(MI);
+  }
+
+  /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
+  /// until now. This is used when a new scope is encountered while walking
+  /// machine instructions.
+  void closeInsnRange(LexicalScope *NewScope = nullptr) {
+    assert(LastInsn && "Last insn missing!");
+    Ranges.push_back(InsnRange(FirstInsn, LastInsn));
+    FirstInsn = nullptr;
+    LastInsn = nullptr;
+    // If Parent dominates NewScope then do not close Parent's instruction
+    // range.
+    if (Parent && (!NewScope || !Parent->dominates(NewScope)))
+      Parent->closeInsnRange(NewScope);
+  }
+
+  /// dominates - Return true if current scope dominates given lexical scope.
+  bool dominates(const LexicalScope *S) const {
+    if (S == this)
+      return true;
+    if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
+      return true;
+    return false;
+  }
+
+  // Depth First Search support to walk and manipulate LexicalScope hierarchy.
+  unsigned getDFSOut() const { return DFSOut; }
+  void setDFSOut(unsigned O) { DFSOut = O; }
+  unsigned getDFSIn() const { return DFSIn; }
+  void setDFSIn(unsigned I) { DFSIn = I; }
+
+  /// dump - print lexical scope.
+  void dump(unsigned Indent = 0) const;
+
+private:
+  LexicalScope *Parent;                        // Parent to this scope.
+  AssertingVH<const MDNode> Desc;              // Debug info descriptor.
+  AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
+                                               // scope is inlined.
+  bool AbstractScope;                          // Abstract Scope
+  SmallVector<LexicalScope *, 4> Children;     // Scopes defined in scope.
+                                               // Contents not owned.
+  SmallVector<InsnRange, 4> Ranges;
+
+  const MachineInstr *LastInsn;  // Last instruction of this scope.
+  const MachineInstr *FirstInsn; // First instruction of this scope.
+  unsigned DFSIn, DFSOut;        // In & Out Depth use to determine
+                                 // scope nesting.
+};
+
+//===----------------------------------------------------------------------===//
+/// LexicalScopes -  This class provides interface to collect and use lexical
+/// scoping information from machine instruction.
+///
+class LexicalScopes {
+public:
+  LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {}
+
+  /// initialize - Scan machine function and constuct lexical scope nest, resets
+  /// the instance if necessary.
+  void initialize(const MachineFunction &);
+
+  /// releaseMemory - release memory.
+  void reset();
+
+  /// empty - Return true if there is any lexical scope information available.
+  bool empty() { return CurrentFnLexicalScope == nullptr; }
+
+  /// isCurrentFunctionScope - Return true if given lexical scope represents
+  /// current function.
+  bool isCurrentFunctionScope(const LexicalScope *LS) {
+    return LS == CurrentFnLexicalScope;
+  }
+
+  /// getCurrentFunctionScope - Return lexical scope for the current function.
+  LexicalScope *getCurrentFunctionScope() const {
+    return CurrentFnLexicalScope;
+  }
+
+  /// getMachineBasicBlocks - Populate given set using machine basic blocks
+  /// which have machine instructions that belong to lexical scope identified by
+  /// DebugLoc.
+  void getMachineBasicBlocks(DebugLoc DL,
+                             SmallPtrSet<const MachineBasicBlock *, 4> &MBBs);
+
+  /// dominates - Return true if DebugLoc's lexical scope dominates at least one
+  /// machine instruction's lexical scope in a given machine basic block.
+  bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
+
+  /// findLexicalScope - Find lexical scope, either regular or inlined, for the
+  /// given DebugLoc. Return NULL if not found.
+  LexicalScope *findLexicalScope(DebugLoc DL);
+
+  /// getAbstractScopesList - Return a reference to list of abstract scopes.
+  ArrayRef<LexicalScope *> getAbstractScopesList() const {
+    return AbstractScopesList;
+  }
+
+  /// findAbstractScope - Find an abstract scope or return null.
+  LexicalScope *findAbstractScope(const MDNode *N) {
+    auto I = AbstractScopeMap.find(N);
+    return I != AbstractScopeMap.end() ? &I->second : nullptr;
+  }
+
+  /// findInlinedScope - Find an inlined scope for the given DebugLoc or return
+  /// NULL.
+  LexicalScope *findInlinedScope(DebugLoc DL);
+
+  /// findLexicalScope - Find regular lexical scope or return null.
+  LexicalScope *findLexicalScope(const MDNode *N) {
+    auto I = LexicalScopeMap.find(N);
+    return I != LexicalScopeMap.end() ? &I->second : nullptr;
+  }
+
+  /// dump - Print data structures to dbgs().
+  void dump();
+
+  /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
+  LexicalScope *getOrCreateAbstractScope(const MDNode *N);
+
+private:
+  /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
+  /// not available then create new lexical scope.
+  LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
+
+  /// getOrCreateRegularScope - Find or create a regular lexical scope.
+  LexicalScope *getOrCreateRegularScope(MDNode *Scope);
+
+  /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
+  LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
+
+  /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
+  /// for the given machine function.
+  void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
+                            DenseMap<const MachineInstr *, LexicalScope *> &M);
+  void constructScopeNest(LexicalScope *Scope);
+  void
+  assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
+                          DenseMap<const MachineInstr *, LexicalScope *> &M);
+
+private:
+  const MachineFunction *MF;
+
+  /// LexicalScopeMap - Tracks the scopes in the current function.
+  // Use an unordered_map to ensure value pointer validity over insertion.
+  std::unordered_map<const MDNode *, LexicalScope> LexicalScopeMap;
+
+  /// InlinedLexicalScopeMap - Tracks inlined function scopes in current
+  /// function.
+  std::unordered_map<std::pair<const MDNode *, const MDNode *>, LexicalScope,
+                     pair_hash<const MDNode *, const MDNode *>>
+  InlinedLexicalScopeMap;
+
+  /// AbstractScopeMap - These scopes are  not included LexicalScopeMap.
+  // Use an unordered_map to ensure value pointer validity over insertion.
+  std::unordered_map<const MDNode *, LexicalScope> AbstractScopeMap;
+
+  /// AbstractScopesList - Tracks abstract scopes constructed while processing
+  /// a function.
+  SmallVector<LexicalScope *, 4> AbstractScopesList;
+
+  /// CurrentFnLexicalScope - Top level scope for the current function.
+  ///
+  LexicalScope *CurrentFnLexicalScope;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
new file mode 100644
index 0000000..c3046da
--- /dev/null
+++ b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -0,0 +1,38 @@
+//===- llvm/Codegen/LinkAllAsmWriterComponents.h ----------------*- C++ -*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all assembler writer related passes for tools like
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
+
+#include "llvm/CodeGen/GCs.h"
+#include <cstdlib>
+
+namespace {
+  struct ForceAsmWriterLinking {
+    ForceAsmWriterLinking() {
+      // We must reference the plug-ins in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      llvm::linkOcamlGCPrinter();
+      llvm::linkErlangGCPrinter();
+
+    }
+  } ForceAsmWriterLinking; // Force link by creating a global definition.
+}
+
+#endif // LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
new file mode 100644
index 0000000..372c294
--- /dev/null
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -0,0 +1,57 @@
+//===- llvm/Codegen/LinkAllCodegenComponents.h ------------------*- C++ -*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all codegen related passes for tools like lli and
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+
+#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cstdlib>
+
+namespace {
+  struct ForceCodegenLinking {
+    ForceCodegenLinking() {
+      // We must reference the passes in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      (void) llvm::createFastRegisterAllocator();
+      (void) llvm::createBasicRegisterAllocator();
+      (void) llvm::createGreedyRegisterAllocator();
+      (void) llvm::createDefaultPBQPRegisterAllocator();
+
+      llvm::linkOcamlGC();
+      llvm::linkErlangGC();
+      llvm::linkShadowStackGC();
+
+      (void) llvm::createBURRListDAGScheduler(nullptr,
+                                              llvm::CodeGenOpt::Default);
+      (void) llvm::createSourceListDAGScheduler(nullptr,
+                                                llvm::CodeGenOpt::Default);
+      (void) llvm::createHybridListDAGScheduler(nullptr,
+                                                llvm::CodeGenOpt::Default);
+      (void) llvm::createFastDAGScheduler(nullptr, llvm::CodeGenOpt::Default);
+      (void) llvm::createDefaultScheduler(nullptr, llvm::CodeGenOpt::Default);
+      (void) llvm::createVLIWDAGScheduler(nullptr, llvm::CodeGenOpt::Default);
+
+    }
+  } ForceCodegenLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
new file mode 100644
index 0000000..6629e60
--- /dev/null
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -0,0 +1,682 @@
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+//                     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 LiveRange and LiveInterval classes.  Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live range for register v if there is no instruction with number j' >= j
+// such that v is live at j' and there is no instruction with number i' < i such
+// that v is live at i'. In this implementation ranges can have holes,
+// i.e. a range might look like [1,20), [50,65), [1000,1001).  Each
+// individual segment is represented as an instance of LiveRange::Segment,
+// and the whole range is represented as an instance of LiveRange.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#define LLVM_CODEGEN_LIVEINTERVAL_H
+
+#include "llvm/ADT/IntEqClasses.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+  class CoalescerPair;
+  class LiveIntervals;
+  class MachineInstr;
+  class MachineRegisterInfo;
+  class TargetRegisterInfo;
+  class raw_ostream;
+  template <typename T, unsigned Small> class SmallPtrSet;
+
+  /// VNInfo - Value Number Information.
+  /// This class holds information about a machine level values, including
+  /// definition and use points.
+  ///
+  class VNInfo {
+  public:
+    typedef BumpPtrAllocator Allocator;
+
+    /// The ID number of this value.
+    unsigned id;
+
+    /// The index of the defining instruction.
+    SlotIndex def;
+
+    /// VNInfo constructor.
+    VNInfo(unsigned i, SlotIndex d)
+      : id(i), def(d)
+    { }
+
+    /// VNInfo construtor, copies values from orig, except for the value number.
+    VNInfo(unsigned i, const VNInfo &orig)
+      : id(i), def(orig.def)
+    { }
+
+    /// Copy from the parameter into this VNInfo.
+    void copyFrom(VNInfo &src) {
+      def = src.def;
+    }
+
+    /// Returns true if this value is defined by a PHI instruction (or was,
+    /// PHI instructions may have been eliminated).
+    /// PHI-defs begin at a block boundary, all other defs begin at register or
+    /// EC slots.
+    bool isPHIDef() const { return def.isBlock(); }
+
+    /// Returns true if this value is unused.
+    bool isUnused() const { return !def.isValid(); }
+
+    /// Mark this value as unused.
+    void markUnused() { def = SlotIndex(); }
+  };
+
+  /// Result of a LiveRange query. This class hides the implementation details
+  /// of live ranges, and it should be used as the primary interface for
+  /// examining live ranges around instructions.
+  class LiveQueryResult {
+    VNInfo *const EarlyVal;
+    VNInfo *const LateVal;
+    const SlotIndex EndPoint;
+    const bool Kill;
+
+  public:
+    LiveQueryResult(VNInfo *EarlyVal, VNInfo *LateVal, SlotIndex EndPoint,
+                    bool Kill)
+      : EarlyVal(EarlyVal), LateVal(LateVal), EndPoint(EndPoint), Kill(Kill)
+    {}
+
+    /// Return the value that is live-in to the instruction. This is the value
+    /// that will be read by the instruction's use operands. Return NULL if no
+    /// value is live-in.
+    VNInfo *valueIn() const {
+      return EarlyVal;
+    }
+
+    /// Return true if the live-in value is killed by this instruction. This
+    /// means that either the live range ends at the instruction, or it changes
+    /// value.
+    bool isKill() const {
+      return Kill;
+    }
+
+    /// Return true if this instruction has a dead def.
+    bool isDeadDef() const {
+      return EndPoint.isDead();
+    }
+
+    /// Return the value leaving the instruction, if any. This can be a
+    /// live-through value, or a live def. A dead def returns NULL.
+    VNInfo *valueOut() const {
+      return isDeadDef() ? nullptr : LateVal;
+    }
+
+    /// Return the value defined by this instruction, if any. This includes
+    /// dead defs, it is the value created by the instruction's def operands.
+    VNInfo *valueDefined() const {
+      return EarlyVal == LateVal ? nullptr : LateVal;
+    }
+
+    /// Return the end point of the last live range segment to interact with
+    /// the instruction, if any.
+    ///
+    /// The end point is an invalid SlotIndex only if the live range doesn't
+    /// intersect the instruction at all.
+    ///
+    /// The end point may be at or past the end of the instruction's basic
+    /// block. That means the value was live out of the block.
+    SlotIndex endPoint() const {
+      return EndPoint;
+    }
+  };
+
+  /// This class represents the liveness of a register, stack slot, etc.
+  /// It manages an ordered list of Segment objects.
+  /// The Segments are organized in a static single assignment form: At places
+  /// where a new value is defined or different values reach a CFG join a new
+  /// segment with a new value number is used.
+  class LiveRange {
+  public:
+
+    /// This represents a simple continuous liveness interval for a value.
+    /// The start point is inclusive, the end point exclusive. These intervals
+    /// are rendered as [start,end).
+    struct Segment {
+      SlotIndex start;  // Start point of the interval (inclusive)
+      SlotIndex end;    // End point of the interval (exclusive)
+      VNInfo *valno;    // identifier for the value contained in this segment.
+
+      Segment() : valno(nullptr) {}
+
+      Segment(SlotIndex S, SlotIndex E, VNInfo *V)
+        : start(S), end(E), valno(V) {
+        assert(S < E && "Cannot create empty or backwards segment");
+      }
+
+      /// Return true if the index is covered by this segment.
+      bool contains(SlotIndex I) const {
+        return start <= I && I < end;
+      }
+
+      /// Return true if the given interval, [S, E), is covered by this segment.
+      bool containsInterval(SlotIndex S, SlotIndex E) const {
+        assert((S < E) && "Backwards interval?");
+        return (start <= S && S < end) && (start < E && E <= end);
+      }
+
+      bool operator<(const Segment &Other) const {
+        return std::tie(start, end) < std::tie(Other.start, Other.end);
+      }
+      bool operator==(const Segment &Other) const {
+        return start == Other.start && end == Other.end;
+      }
+
+      void dump() const;
+    };
+
+    typedef SmallVector<Segment,4> Segments;
+    typedef SmallVector<VNInfo*,4> VNInfoList;
+
+    Segments segments;   // the liveness segments
+    VNInfoList valnos;   // value#'s
+
+    typedef Segments::iterator iterator;
+    iterator begin() { return segments.begin(); }
+    iterator end()   { return segments.end(); }
+
+    typedef Segments::const_iterator const_iterator;
+    const_iterator begin() const { return segments.begin(); }
+    const_iterator end() const  { return segments.end(); }
+
+    typedef VNInfoList::iterator vni_iterator;
+    vni_iterator vni_begin() { return valnos.begin(); }
+    vni_iterator vni_end()   { return valnos.end(); }
+
+    typedef VNInfoList::const_iterator const_vni_iterator;
+    const_vni_iterator vni_begin() const { return valnos.begin(); }
+    const_vni_iterator vni_end() const   { return valnos.end(); }
+
+    /// advanceTo - Advance the specified iterator to point to the Segment
+    /// containing the specified position, or end() if the position is past the
+    /// end of the range.  If no Segment contains this position, but the
+    /// position is in a hole, this method returns an iterator pointing to the
+    /// Segment immediately after the hole.
+    iterator advanceTo(iterator I, SlotIndex Pos) {
+      assert(I != end());
+      if (Pos >= endIndex())
+        return end();
+      while (I->end <= Pos) ++I;
+      return I;
+    }
+
+    /// find - Return an iterator pointing to the first segment that ends after
+    /// Pos, or end(). This is the same as advanceTo(begin(), Pos), but faster
+    /// when searching large ranges.
+    ///
+    /// If Pos is contained in a Segment, that segment is returned.
+    /// If Pos is in a hole, the following Segment is returned.
+    /// If Pos is beyond endIndex, end() is returned.
+    iterator find(SlotIndex Pos);
+
+    const_iterator find(SlotIndex Pos) const {
+      return const_cast<LiveRange*>(this)->find(Pos);
+    }
+
+    void clear() {
+      valnos.clear();
+      segments.clear();
+    }
+
+    size_t size() const {
+      return segments.size();
+    }
+
+    bool hasAtLeastOneValue() const { return !valnos.empty(); }
+
+    bool containsOneValue() const { return valnos.size() == 1; }
+
+    unsigned getNumValNums() const { return (unsigned)valnos.size(); }
+
+    /// getValNumInfo - Returns pointer to the specified val#.
+    ///
+    inline VNInfo *getValNumInfo(unsigned ValNo) {
+      return valnos[ValNo];
+    }
+    inline const VNInfo *getValNumInfo(unsigned ValNo) const {
+      return valnos[ValNo];
+    }
+
+    /// containsValue - Returns true if VNI belongs to this range.
+    bool containsValue(const VNInfo *VNI) const {
+      return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id);
+    }
+
+    /// getNextValue - Create a new value number and return it.  MIIdx specifies
+    /// the instruction that defines the value number.
+    VNInfo *getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator) {
+      VNInfo *VNI =
+        new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def);
+      valnos.push_back(VNI);
+      return VNI;
+    }
+
+    /// createDeadDef - Make sure the range has a value defined at Def.
+    /// If one already exists, return it. Otherwise allocate a new value and
+    /// add liveness for a dead def.
+    VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator);
+
+    /// Create a copy of the given value. The new value will be identical except
+    /// for the Value number.
+    VNInfo *createValueCopy(const VNInfo *orig,
+                            VNInfo::Allocator &VNInfoAllocator) {
+      VNInfo *VNI =
+        new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig);
+      valnos.push_back(VNI);
+      return VNI;
+    }
+
+    /// RenumberValues - Renumber all values in order of appearance and remove
+    /// unused values.
+    void RenumberValues();
+
+    /// MergeValueNumberInto - This method is called when two value numbers
+    /// are found to be equivalent.  This eliminates V1, replacing all
+    /// segments with the V1 value number with the V2 value number.  This can
+    /// cause merging of V1/V2 values numbers and compaction of the value space.
+    VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
+
+    /// Merge all of the live segments of a specific val# in RHS into this live
+    /// range as the specified value number. The segments in RHS are allowed
+    /// to overlap with segments in the current range, it will replace the
+    /// value numbers of the overlaped live segments with the specified value
+    /// number.
+    void MergeSegmentsInAsValue(const LiveRange &RHS, VNInfo *LHSValNo);
+
+    /// MergeValueInAsValue - Merge all of the segments of a specific val#
+    /// in RHS into this live range as the specified value number.
+    /// The segments in RHS are allowed to overlap with segments in the
+    /// current range, but only if the overlapping segments have the
+    /// specified value number.
+    void MergeValueInAsValue(const LiveRange &RHS,
+                             const VNInfo *RHSValNo, VNInfo *LHSValNo);
+
+    bool empty() const { return segments.empty(); }
+
+    /// beginIndex - Return the lowest numbered slot covered.
+    SlotIndex beginIndex() const {
+      assert(!empty() && "Call to beginIndex() on empty range.");
+      return segments.front().start;
+    }
+
+    /// endNumber - return the maximum point of the range of the whole,
+    /// exclusive.
+    SlotIndex endIndex() const {
+      assert(!empty() && "Call to endIndex() on empty range.");
+      return segments.back().end;
+    }
+
+    bool expiredAt(SlotIndex index) const {
+      return index >= endIndex();
+    }
+
+    bool liveAt(SlotIndex index) const {
+      const_iterator r = find(index);
+      return r != end() && r->start <= index;
+    }
+
+    /// Return the segment that contains the specified index, or null if there
+    /// is none.
+    const Segment *getSegmentContaining(SlotIndex Idx) const {
+      const_iterator I = FindSegmentContaining(Idx);
+      return I == end() ? nullptr : &*I;
+    }
+
+    /// Return the live segment that contains the specified index, or null if
+    /// there is none.
+    Segment *getSegmentContaining(SlotIndex Idx) {
+      iterator I = FindSegmentContaining(Idx);
+      return I == end() ? nullptr : &*I;
+    }
+
+    /// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
+    VNInfo *getVNInfoAt(SlotIndex Idx) const {
+      const_iterator I = FindSegmentContaining(Idx);
+      return I == end() ? nullptr : I->valno;
+    }
+
+    /// getVNInfoBefore - Return the VNInfo that is live up to but not
+    /// necessarilly including Idx, or NULL. Use this to find the reaching def
+    /// used by an instruction at this SlotIndex position.
+    VNInfo *getVNInfoBefore(SlotIndex Idx) const {
+      const_iterator I = FindSegmentContaining(Idx.getPrevSlot());
+      return I == end() ? nullptr : I->valno;
+    }
+
+    /// Return an iterator to the segment that contains the specified index, or
+    /// end() if there is none.
+    iterator FindSegmentContaining(SlotIndex Idx) {
+      iterator I = find(Idx);
+      return I != end() && I->start <= Idx ? I : end();
+    }
+
+    const_iterator FindSegmentContaining(SlotIndex Idx) const {
+      const_iterator I = find(Idx);
+      return I != end() && I->start <= Idx ? I : end();
+    }
+
+    /// overlaps - Return true if the intersection of the two live ranges is
+    /// not empty.
+    bool overlaps(const LiveRange &other) const {
+      if (other.empty())
+        return false;
+      return overlapsFrom(other, other.begin());
+    }
+
+    /// overlaps - Return true if the two ranges have overlapping segments
+    /// that are not coalescable according to CP.
+    ///
+    /// Overlapping segments where one range is defined by a coalescable
+    /// copy are allowed.
+    bool overlaps(const LiveRange &Other, const CoalescerPair &CP,
+                  const SlotIndexes&) const;
+
+    /// overlaps - Return true if the live range overlaps an interval specified
+    /// by [Start, End).
+    bool overlaps(SlotIndex Start, SlotIndex End) const;
+
+    /// overlapsFrom - Return true if the intersection of the two live ranges
+    /// is not empty.  The specified iterator is a hint that we can begin
+    /// scanning the Other range starting at I.
+    bool overlapsFrom(const LiveRange &Other, const_iterator I) const;
+
+    /// Add the specified Segment to this range, merging segments as
+    /// appropriate.  This returns an iterator to the inserted segment (which
+    /// may have grown since it was inserted).
+    iterator addSegment(Segment S) {
+      return addSegmentFrom(S, segments.begin());
+    }
+
+    /// extendInBlock - If this range is live before Kill in the basic block
+    /// that starts at StartIdx, extend it to be live up to Kill, and return
+    /// the value. If there is no segment before Kill, return NULL.
+    VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill);
+
+    /// join - Join two live ranges (this, and other) together.  This applies
+    /// mappings to the value numbers in the LHS/RHS ranges as specified.  If
+    /// the ranges are not joinable, this aborts.
+    void join(LiveRange &Other,
+              const int *ValNoAssignments,
+              const int *RHSValNoAssignments,
+              SmallVectorImpl<VNInfo *> &NewVNInfo);
+
+    /// True iff this segment is a single segment that lies between the
+    /// specified boundaries, exclusively. Vregs live across a backedge are not
+    /// considered local. The boundaries are expected to lie within an extended
+    /// basic block, so vregs that are not live out should contain no holes.
+    bool isLocal(SlotIndex Start, SlotIndex End) const {
+      return beginIndex() > Start.getBaseIndex() &&
+        endIndex() < End.getBoundaryIndex();
+    }
+
+    /// Remove the specified segment from this range.  Note that the segment
+    /// must be a single Segment in its entirety.
+    void removeSegment(SlotIndex Start, SlotIndex End,
+                       bool RemoveDeadValNo = false);
+
+    void removeSegment(Segment S, bool RemoveDeadValNo = false) {
+      removeSegment(S.start, S.end, RemoveDeadValNo);
+    }
+
+    /// Query Liveness at Idx.
+    /// The sub-instruction slot of Idx doesn't matter, only the instruction
+    /// it refers to is considered.
+    LiveQueryResult Query(SlotIndex Idx) const {
+      // Find the segment that enters the instruction.
+      const_iterator I = find(Idx.getBaseIndex());
+      const_iterator E = end();
+      if (I == E)
+        return LiveQueryResult(nullptr, nullptr, SlotIndex(), false);
+
+      // Is this an instruction live-in segment?
+      // If Idx is the start index of a basic block, include live-in segments
+      // that start at Idx.getBaseIndex().
+      VNInfo *EarlyVal = nullptr;
+      VNInfo *LateVal  = nullptr;
+      SlotIndex EndPoint;
+      bool Kill = false;
+      if (I->start <= Idx.getBaseIndex()) {
+        EarlyVal = I->valno;
+        EndPoint = I->end;
+        // Move to the potentially live-out segment.
+        if (SlotIndex::isSameInstr(Idx, I->end)) {
+          Kill = true;
+          if (++I == E)
+            return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
+        }
+        // Special case: A PHIDef value can have its def in the middle of a
+        // segment if the value happens to be live out of the layout
+        // predecessor.
+        // Such a value is not live-in.
+        if (EarlyVal->def == Idx.getBaseIndex())
+          EarlyVal = nullptr;
+      }
+      // I now points to the segment that may be live-through, or defined by
+      // this instr. Ignore segments starting after the current instr.
+      if (!SlotIndex::isEarlierInstr(Idx, I->start)) {
+        LateVal = I->valno;
+        EndPoint = I->end;
+      }
+      return LiveQueryResult(EarlyVal, LateVal, EndPoint, Kill);
+    }
+
+    /// removeValNo - Remove all the segments defined by the specified value#.
+    /// Also remove the value# from value# list.
+    void removeValNo(VNInfo *ValNo);
+
+    /// Returns true if the live range is zero length, i.e. no live segments
+    /// span instructions. It doesn't pay to spill such a range.
+    bool isZeroLength(SlotIndexes *Indexes) const {
+      for (const_iterator i = begin(), e = end(); i != e; ++i)
+        if (Indexes->getNextNonNullIndex(i->start).getBaseIndex() <
+            i->end.getBaseIndex())
+          return false;
+      return true;
+    }
+
+    bool operator<(const LiveRange& other) const {
+      const SlotIndex &thisIndex = beginIndex();
+      const SlotIndex &otherIndex = other.beginIndex();
+      return thisIndex < otherIndex;
+    }
+
+    void print(raw_ostream &OS) const;
+    void dump() const;
+
+    /// \brief Walk the range and assert if any invariants fail to hold.
+    ///
+    /// Note that this is a no-op when asserts are disabled.
+#ifdef NDEBUG
+    void verify() const {}
+#else
+    void verify() const;
+#endif
+
+  private:
+
+    iterator addSegmentFrom(Segment S, iterator From);
+    void extendSegmentEndTo(iterator I, SlotIndex NewEnd);
+    iterator extendSegmentStartTo(iterator I, SlotIndex NewStr);
+    void markValNoForDeletion(VNInfo *V);
+
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const LiveRange &LR) {
+    LR.print(OS);
+    return OS;
+  }
+
+  /// LiveInterval - This class represents the liveness of a register,
+  /// or stack slot.
+  class LiveInterval : public LiveRange {
+  public:
+    typedef LiveRange super;
+
+    const unsigned reg;  // the register or stack slot of this interval.
+    float weight;        // weight of this interval
+
+    LiveInterval(unsigned Reg, float Weight)
+      : reg(Reg), weight(Weight) {}
+
+    /// getSize - Returns the sum of sizes of all the LiveRange's.
+    ///
+    unsigned getSize() const;
+
+    /// isSpillable - Can this interval be spilled?
+    bool isSpillable() const {
+      return weight != llvm::huge_valf;
+    }
+
+    /// markNotSpillable - Mark interval as not spillable
+    void markNotSpillable() {
+      weight = llvm::huge_valf;
+    }
+
+    bool operator<(const LiveInterval& other) const {
+      const SlotIndex &thisIndex = beginIndex();
+      const SlotIndex &otherIndex = other.beginIndex();
+      return std::tie(thisIndex, reg) < std::tie(otherIndex, other.reg);
+    }
+
+    void print(raw_ostream &OS) const;
+    void dump() const;
+
+  private:
+    LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
+
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const LiveInterval &LI) {
+    LI.print(OS);
+    return OS;
+  }
+
+  raw_ostream &operator<<(raw_ostream &OS, const LiveRange::Segment &S);
+
+  inline bool operator<(SlotIndex V, const LiveRange::Segment &S) {
+    return V < S.start;
+  }
+
+  inline bool operator<(const LiveRange::Segment &S, SlotIndex V) {
+    return S.start < V;
+  }
+
+  /// Helper class for performant LiveRange bulk updates.
+  ///
+  /// Calling LiveRange::addSegment() repeatedly can be expensive on large
+  /// live ranges because segments after the insertion point may need to be
+  /// shifted. The LiveRangeUpdater class can defer the shifting when adding
+  /// many segments in order.
+  ///
+  /// The LiveRange will be in an invalid state until flush() is called.
+  class LiveRangeUpdater {
+    LiveRange *LR;
+    SlotIndex LastStart;
+    LiveRange::iterator WriteI;
+    LiveRange::iterator ReadI;
+    SmallVector<LiveRange::Segment, 16> Spills;
+    void mergeSpills();
+
+  public:
+    /// Create a LiveRangeUpdater for adding segments to LR.
+    /// LR will temporarily be in an invalid state until flush() is called.
+    LiveRangeUpdater(LiveRange *lr = nullptr) : LR(lr) {}
+
+    ~LiveRangeUpdater() { flush(); }
+
+    /// Add a segment to LR and coalesce when possible, just like
+    /// LR.addSegment(). Segments should be added in increasing start order for
+    /// best performance.
+    void add(LiveRange::Segment);
+
+    void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
+      add(LiveRange::Segment(Start, End, VNI));
+    }
+
+    /// Return true if the LR is currently in an invalid state, and flush()
+    /// needs to be called.
+    bool isDirty() const { return LastStart.isValid(); }
+
+    /// Flush the updater state to LR so it is valid and contains all added
+    /// segments.
+    void flush();
+
+    /// Select a different destination live range.
+    void setDest(LiveRange *lr) {
+      if (LR != lr && isDirty())
+        flush();
+      LR = lr;
+    }
+
+    /// Get the current destination live range.
+    LiveRange *getDest() const { return LR; }
+
+    void dump() const;
+    void print(raw_ostream&) const;
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) {
+    X.print(OS);
+    return OS;
+  }
+
+  /// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
+  /// LiveInterval into equivalence clases of connected components. A
+  /// LiveInterval that has multiple connected components can be broken into
+  /// multiple LiveIntervals.
+  ///
+  /// Given a LiveInterval that may have multiple connected components, run:
+  ///
+  ///   unsigned numComps = ConEQ.Classify(LI);
+  ///   if (numComps > 1) {
+  ///     // allocate numComps-1 new LiveIntervals into LIS[1..]
+  ///     ConEQ.Distribute(LIS);
+  /// }
+
+  class ConnectedVNInfoEqClasses {
+    LiveIntervals &LIS;
+    IntEqClasses EqClass;
+
+    // Note that values a and b are connected.
+    void Connect(unsigned a, unsigned b);
+
+    unsigned Renumber();
+
+  public:
+    explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {}
+
+    /// Classify - Classify the values in LI into connected components.
+    /// Return the number of connected components.
+    unsigned Classify(const LiveInterval *LI);
+
+    /// getEqClass - Classify creates equivalence classes numbered 0..N. Return
+    /// the equivalence class assigned the VNI.
+    unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; }
+
+    /// Distribute - Distribute values in LIV[0] into a separate LiveInterval
+    /// for each connected component. LIV must have a LiveInterval for each
+    /// connected component. The LiveIntervals in Liv[1..] must be empty.
+    /// Instructions using LIV[0] are rewritten.
+    void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI);
+
+  };
+
+}
+#endif
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
new file mode 100644
index 0000000..176665b
--- /dev/null
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -0,0 +1,421 @@
+//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
+//
+//                     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 LiveInterval analysis pass.  Given some numbering of
+// each the machine instructions (in this implemention depth-first order) an
+// interval [i, j) is said to be a live interval for register v if there is no
+// instruction with number j' > j such that v is live at j' and there is no
+// instruction with number i' < i such that v is live at i'. In this
+// implementation intervals can have holes, i.e. an interval might look like
+// [1,20), [50,65), [1000,1001).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cmath>
+#include <iterator>
+
+namespace llvm {
+
+  class AliasAnalysis;
+  class BitVector;
+  class BlockFrequency;
+  class LiveRangeCalc;
+  class LiveVariables;
+  class MachineDominatorTree;
+  class MachineLoopInfo;
+  class TargetRegisterInfo;
+  class MachineRegisterInfo;
+  class TargetInstrInfo;
+  class TargetRegisterClass;
+  class VirtRegMap;
+  class MachineBlockFrequencyInfo;
+
+  class LiveIntervals : public MachineFunctionPass {
+    MachineFunction* MF;
+    MachineRegisterInfo* MRI;
+    const TargetMachine* TM;
+    const TargetRegisterInfo* TRI;
+    const TargetInstrInfo* TII;
+    AliasAnalysis *AA;
+    SlotIndexes* Indexes;
+    MachineDominatorTree *DomTree;
+    LiveRangeCalc *LRCalc;
+
+    /// Special pool allocator for VNInfo's (LiveInterval val#).
+    ///
+    VNInfo::Allocator VNInfoAllocator;
+
+    /// Live interval pointers for all the virtual registers.
+    IndexedMap<LiveInterval*, VirtReg2IndexFunctor> VirtRegIntervals;
+
+    /// RegMaskSlots - Sorted list of instructions with register mask operands.
+    /// Always use the 'r' slot, RegMasks are normal clobbers, not early
+    /// clobbers.
+    SmallVector<SlotIndex, 8> RegMaskSlots;
+
+    /// RegMaskBits - This vector is parallel to RegMaskSlots, it holds a
+    /// pointer to the corresponding register mask.  This pointer can be
+    /// recomputed as:
+    ///
+    ///   MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
+    ///   unsigned OpNum = findRegMaskOperand(MI);
+    ///   RegMaskBits[N] = MI->getOperand(OpNum).getRegMask();
+    ///
+    /// This is kept in a separate vector partly because some standard
+    /// libraries don't support lower_bound() with mixed objects, partly to
+    /// improve locality when searching in RegMaskSlots.
+    /// Also see the comment in LiveInterval::find().
+    SmallVector<const uint32_t*, 8> RegMaskBits;
+
+    /// For each basic block number, keep (begin, size) pairs indexing into the
+    /// RegMaskSlots and RegMaskBits arrays.
+    /// Note that basic block numbers may not be layout contiguous, that's why
+    /// we can't just keep track of the first register mask in each basic
+    /// block.
+    SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
+
+    /// Keeps a live range set for each register unit to track fixed physreg
+    /// interference.
+    SmallVector<LiveRange*, 0> RegUnitRanges;
+
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    LiveIntervals();
+    virtual ~LiveIntervals();
+
+    // Calculate the spill weight to assign to a single instruction.
+    static float getSpillWeight(bool isDef, bool isUse,
+                                const MachineBlockFrequencyInfo *MBFI,
+                                const MachineInstr *Instr);
+
+    LiveInterval &getInterval(unsigned Reg) {
+      if (hasInterval(Reg))
+        return *VirtRegIntervals[Reg];
+      else
+        return createAndComputeVirtRegInterval(Reg);
+    }
+
+    const LiveInterval &getInterval(unsigned Reg) const {
+      return const_cast<LiveIntervals*>(this)->getInterval(Reg);
+    }
+
+    bool hasInterval(unsigned Reg) const {
+      return VirtRegIntervals.inBounds(Reg) && VirtRegIntervals[Reg];
+    }
+
+    // Interval creation.
+    LiveInterval &createEmptyInterval(unsigned Reg) {
+      assert(!hasInterval(Reg) && "Interval already exists!");
+      VirtRegIntervals.grow(Reg);
+      VirtRegIntervals[Reg] = createInterval(Reg);
+      return *VirtRegIntervals[Reg];
+    }
+
+    LiveInterval &createAndComputeVirtRegInterval(unsigned Reg) {
+      LiveInterval &LI = createEmptyInterval(Reg);
+      computeVirtRegInterval(LI);
+      return LI;
+    }
+
+    // Interval removal.
+    void removeInterval(unsigned Reg) {
+      delete VirtRegIntervals[Reg];
+      VirtRegIntervals[Reg] = nullptr;
+    }
+
+    /// Given a register and an instruction, adds a live segment from that
+    /// instruction to the end of its MBB.
+    LiveInterval::Segment addSegmentToEndOfBlock(unsigned reg,
+                                                 MachineInstr* startInst);
+
+    /// shrinkToUses - After removing some uses of a register, shrink its live
+    /// range to just the remaining uses. This method does not compute reaching
+    /// defs for new uses, and it doesn't remove dead defs.
+    /// Dead PHIDef values are marked as unused.
+    /// New dead machine instructions are added to the dead vector.
+    /// Return true if the interval may have been separated into multiple
+    /// connected components.
+    bool shrinkToUses(LiveInterval *li,
+                      SmallVectorImpl<MachineInstr*> *dead = nullptr);
+
+    /// \brief Walk the values in the given interval and compute which ones
+    /// are dead.  Dead values are not deleted, however:
+    /// - Dead PHIDef values are marked as unused.
+    /// - New dead machine instructions are added to the dead vector.
+    /// - CanSeparate is set to true if the interval may have been separated
+    ///   into multiple connected components.
+    void computeDeadValues(LiveInterval *li,
+                           LiveRange &LR,
+                           bool *CanSeparate,
+                           SmallVectorImpl<MachineInstr*> *dead);
+
+    /// extendToIndices - Extend the live range of LI to reach all points in
+    /// Indices. The points in the Indices array must be jointly dominated by
+    /// existing defs in LI. PHI-defs are added as needed to maintain SSA form.
+    ///
+    /// If a SlotIndex in Indices is the end index of a basic block, LI will be
+    /// extended to be live out of the basic block.
+    ///
+    /// See also LiveRangeCalc::extend().
+    void extendToIndices(LiveRange &LR, ArrayRef<SlotIndex> Indices);
+
+    /// pruneValue - If an LI value is live at Kill, prune its live range by
+    /// removing any liveness reachable from Kill. Add live range end points to
+    /// EndPoints such that extendToIndices(LI, EndPoints) will reconstruct the
+    /// value's live range.
+    ///
+    /// Calling pruneValue() and extendToIndices() can be used to reconstruct
+    /// SSA form after adding defs to a virtual register.
+    void pruneValue(LiveInterval *LI, SlotIndex Kill,
+                    SmallVectorImpl<SlotIndex> *EndPoints);
+
+    SlotIndexes *getSlotIndexes() const {
+      return Indexes;
+    }
+
+    AliasAnalysis *getAliasAnalysis() const {
+      return AA;
+    }
+
+    /// isNotInMIMap - returns true if the specified machine instr has been
+    /// removed or was never entered in the map.
+    bool isNotInMIMap(const MachineInstr* Instr) const {
+      return !Indexes->hasIndex(Instr);
+    }
+
+    /// Returns the base index of the given instruction.
+    SlotIndex getInstructionIndex(const MachineInstr *instr) const {
+      return Indexes->getInstructionIndex(instr);
+    }
+
+    /// Returns the instruction associated with the given index.
+    MachineInstr* getInstructionFromIndex(SlotIndex index) const {
+      return Indexes->getInstructionFromIndex(index);
+    }
+
+    /// Return the first index in the given basic block.
+    SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+      return Indexes->getMBBStartIdx(mbb);
+    }
+
+    /// Return the last index in the given basic block.
+    SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+      return Indexes->getMBBEndIdx(mbb);
+    }
+
+    bool isLiveInToMBB(const LiveRange &LR,
+                       const MachineBasicBlock *mbb) const {
+      return LR.liveAt(getMBBStartIdx(mbb));
+    }
+
+    bool isLiveOutOfMBB(const LiveRange &LR,
+                        const MachineBasicBlock *mbb) const {
+      return LR.liveAt(getMBBEndIdx(mbb).getPrevSlot());
+    }
+
+    MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
+      return Indexes->getMBBFromIndex(index);
+    }
+
+    void insertMBBInMaps(MachineBasicBlock *MBB) {
+      Indexes->insertMBBInMaps(MBB);
+      assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
+             "Blocks must be added in order.");
+      RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
+    }
+
+    SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
+      return Indexes->insertMachineInstrInMaps(MI);
+    }
+
+    void InsertMachineInstrRangeInMaps(MachineBasicBlock::iterator B,
+                                       MachineBasicBlock::iterator E) {
+      for (MachineBasicBlock::iterator I = B; I != E; ++I)
+        Indexes->insertMachineInstrInMaps(I);
+    }
+
+    void RemoveMachineInstrFromMaps(MachineInstr *MI) {
+      Indexes->removeMachineInstrFromMaps(MI);
+    }
+
+    void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
+      Indexes->replaceMachineInstrInMaps(MI, NewMI);
+    }
+
+    bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
+                        SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
+      return Indexes->findLiveInMBBs(Start, End, MBBs);
+    }
+
+    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
+
+    void getAnalysisUsage(AnalysisUsage &AU) const override;
+    void releaseMemory() override;
+
+    /// runOnMachineFunction - pass entry point
+    bool runOnMachineFunction(MachineFunction&) override;
+
+    /// print - Implement the dump method.
+    void print(raw_ostream &O, const Module* = nullptr) const override;
+
+    /// intervalIsInOneMBB - If LI is confined to a single basic block, return
+    /// a pointer to that block.  If LI is live in to or out of any block,
+    /// return NULL.
+    MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
+
+    /// Returns true if VNI is killed by any PHI-def values in LI.
+    /// This may conservatively return true to avoid expensive computations.
+    bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const;
+
+    /// addKillFlags - Add kill flags to any instruction that kills a virtual
+    /// register.
+    void addKillFlags(const VirtRegMap*);
+
+    /// handleMove - call this method to notify LiveIntervals that
+    /// instruction 'mi' has been moved within a basic block. This will update
+    /// the live intervals for all operands of mi. Moves between basic blocks
+    /// are not supported.
+    ///
+    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+    void handleMove(MachineInstr* MI, bool UpdateFlags = false);
+
+    /// moveIntoBundle - Update intervals for operands of MI so that they
+    /// begin/end on the SlotIndex for BundleStart.
+    ///
+    /// \param UpdateFlags Update live intervals for nonallocatable physregs.
+    ///
+    /// Requires MI and BundleStart to have SlotIndexes, and assumes
+    /// existing liveness is accurate. BundleStart should be the first
+    /// instruction in the Bundle.
+    void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
+                              bool UpdateFlags = false);
+
+    /// repairIntervalsInRange - Update live intervals for instructions in a
+    /// range of iterators. It is intended for use after target hooks that may
+    /// insert or remove instructions, and is only efficient for a small number
+    /// of instructions.
+    ///
+    /// OrigRegs is a vector of registers that were originally used by the
+    /// instructions in the range between the two iterators.
+    ///
+    /// Currently, the only only changes that are supported are simple removal
+    /// and addition of uses.
+    void repairIntervalsInRange(MachineBasicBlock *MBB,
+                                MachineBasicBlock::iterator Begin,
+                                MachineBasicBlock::iterator End,
+                                ArrayRef<unsigned> OrigRegs);
+
+    // Register mask functions.
+    //
+    // Machine instructions may use a register mask operand to indicate that a
+    // large number of registers are clobbered by the instruction.  This is
+    // typically used for calls.
+    //
+    // For compile time performance reasons, these clobbers are not recorded in
+    // the live intervals for individual physical registers.  Instead,
+    // LiveIntervalAnalysis maintains a sorted list of instructions with
+    // register mask operands.
+
+    /// getRegMaskSlots - Returns a sorted array of slot indices of all
+    /// instructions with register mask operands.
+    ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
+
+    /// getRegMaskSlotsInBlock - Returns a sorted array of slot indices of all
+    /// instructions with register mask operands in the basic block numbered
+    /// MBBNum.
+    ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
+      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+      return getRegMaskSlots().slice(P.first, P.second);
+    }
+
+    /// getRegMaskBits() - Returns an array of register mask pointers
+    /// corresponding to getRegMaskSlots().
+    ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }
+
+    /// getRegMaskBitsInBlock - Returns an array of mask pointers corresponding
+    /// to getRegMaskSlotsInBlock(MBBNum).
+    ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
+      std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+      return getRegMaskBits().slice(P.first, P.second);
+    }
+
+    /// checkRegMaskInterference - Test if LI is live across any register mask
+    /// instructions, and compute a bit mask of physical registers that are not
+    /// clobbered by any of them.
+    ///
+    /// Returns false if LI doesn't cross any register mask instructions. In
+    /// that case, the bit vector is not filled in.
+    bool checkRegMaskInterference(LiveInterval &LI,
+                                  BitVector &UsableRegs);
+
+    // Register unit functions.
+    //
+    // Fixed interference occurs when MachineInstrs use physregs directly
+    // instead of virtual registers. This typically happens when passing
+    // arguments to a function call, or when instructions require operands in
+    // fixed registers.
+    //
+    // Each physreg has one or more register units, see MCRegisterInfo. We
+    // track liveness per register unit to handle aliasing registers more
+    // efficiently.
+
+    /// getRegUnit - Return the live range for Unit.
+    /// It will be computed if it doesn't exist.
+    LiveRange &getRegUnit(unsigned Unit) {
+      LiveRange *LR = RegUnitRanges[Unit];
+      if (!LR) {
+        // Compute missing ranges on demand.
+        RegUnitRanges[Unit] = LR = new LiveRange();
+        computeRegUnitRange(*LR, Unit);
+      }
+      return *LR;
+    }
+
+    /// getCachedRegUnit - Return the live range for Unit if it has already
+    /// been computed, or NULL if it hasn't been computed yet.
+    LiveRange *getCachedRegUnit(unsigned Unit) {
+      return RegUnitRanges[Unit];
+    }
+
+    const LiveRange *getCachedRegUnit(unsigned Unit) const {
+      return RegUnitRanges[Unit];
+    }
+
+  private:
+    /// Compute live intervals for all virtual registers.
+    void computeVirtRegs();
+
+    /// Compute RegMaskSlots and RegMaskBits.
+    void computeRegMasks();
+
+    static LiveInterval* createInterval(unsigned Reg);
+
+    void printInstrs(raw_ostream &O) const;
+    void dumpInstrs() const;
+
+    void computeLiveInRegUnits();
+    void computeRegUnitRange(LiveRange&, unsigned Unit);
+    void computeVirtRegInterval(LiveInterval&);
+
+    class HMEditor;
+  };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h
new file mode 100644
index 0000000..2f40509
--- /dev/null
+++ b/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -0,0 +1,205 @@
+//===-- LiveIntervalUnion.h - Live interval union data struct --*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// LiveIntervalUnion is a union of live segments across multiple live virtual
+// registers. This may be used during coalescing to represent a congruence
+// class, or during register allocation to model liveness of a physical
+// register.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H
+#define LLVM_CODEGEN_LIVEINTERVALUNION_H
+
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/CodeGen/LiveInterval.h"
+
+namespace llvm {
+
+class TargetRegisterInfo;
+
+#ifndef NDEBUG
+// forward declaration
+template <unsigned Element> class SparseBitVector;
+typedef SparseBitVector<128> LiveVirtRegBitSet;
+#endif
+
+/// Compare a live virtual register segment to a LiveIntervalUnion segment.
+inline bool
+overlap(const LiveInterval::Segment &VRSeg,
+        const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
+  return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
+}
+
+/// Union of live intervals that are strong candidates for coalescing into a
+/// single register (either physical or virtual depending on the context).  We
+/// expect the constituent live intervals to be disjoint, although we may
+/// eventually make exceptions to handle value-based interference.
+class LiveIntervalUnion {
+  // A set of live virtual register segments that supports fast insertion,
+  // intersection, and removal.
+  // Mapping SlotIndex intervals to virtual register numbers.
+  typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments;
+
+public:
+  // SegmentIter can advance to the next segment ordered by starting position
+  // which may belong to a different live virtual register. We also must be able
+  // to reach the current segment's containing virtual register.
+  typedef LiveSegments::iterator SegmentIter;
+
+  // LiveIntervalUnions share an external allocator.
+  typedef LiveSegments::Allocator Allocator;
+
+  class Query;
+
+private:
+  unsigned Tag;           // unique tag for current contents.
+  LiveSegments Segments;  // union of virtual reg segments
+
+public:
+  explicit LiveIntervalUnion(Allocator &a) : Tag(0), Segments(a) {}
+
+  // Iterate over all segments in the union of live virtual registers ordered
+  // by their starting position.
+  SegmentIter begin() { return Segments.begin(); }
+  SegmentIter end() { return Segments.end(); }
+  SegmentIter find(SlotIndex x) { return Segments.find(x); }
+  bool empty() const { return Segments.empty(); }
+  SlotIndex startIndex() const { return Segments.start(); }
+
+  // Provide public access to the underlying map to allow overlap iteration.
+  typedef LiveSegments Map;
+  const Map &getMap() { return Segments; }
+
+  /// getTag - Return an opaque tag representing the current state of the union.
+  unsigned getTag() const { return Tag; }
+
+  /// changedSince - Return true if the union change since getTag returned tag.
+  bool changedSince(unsigned tag) const { return tag != Tag; }
+
+  // Add a live virtual register to this union and merge its segments.
+  void unify(LiveInterval &VirtReg);
+
+  // Remove a live virtual register's segments from this union.
+  void extract(LiveInterval &VirtReg);
+
+  // Remove all inserted virtual registers.
+  void clear() { Segments.clear(); ++Tag; }
+
+  // Print union, using TRI to translate register names
+  void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const;
+
+#ifndef NDEBUG
+  // Verify the live intervals in this union and add them to the visited set.
+  void verify(LiveVirtRegBitSet& VisitedVRegs);
+#endif
+
+  /// Query interferences between a single live virtual register and a live
+  /// interval union.
+  class Query {
+    LiveIntervalUnion *LiveUnion;
+    LiveInterval *VirtReg;
+    LiveInterval::iterator VirtRegI; // current position in VirtReg
+    SegmentIter LiveUnionI;          // current position in LiveUnion
+    SmallVector<LiveInterval*,4> InterferingVRegs;
+    bool CheckedFirstInterference;
+    bool SeenAllInterferences;
+    bool SeenUnspillableVReg;
+    unsigned Tag, UserTag;
+
+  public:
+    Query(): LiveUnion(), VirtReg(), Tag(0), UserTag(0) {}
+
+    Query(LiveInterval *VReg, LiveIntervalUnion *LIU):
+      LiveUnion(LIU), VirtReg(VReg), CheckedFirstInterference(false),
+      SeenAllInterferences(false), SeenUnspillableVReg(false)
+    {}
+
+    void clear() {
+      LiveUnion = nullptr;
+      VirtReg = nullptr;
+      InterferingVRegs.clear();
+      CheckedFirstInterference = false;
+      SeenAllInterferences = false;
+      SeenUnspillableVReg = false;
+      Tag = 0;
+      UserTag = 0;
+    }
+
+    void init(unsigned UTag, LiveInterval *VReg, LiveIntervalUnion *LIU) {
+      assert(VReg && LIU && "Invalid arguments");
+      if (UserTag == UTag && VirtReg == VReg &&
+          LiveUnion == LIU && !LIU->changedSince(Tag)) {
+        // Retain cached results, e.g. firstInterference.
+        return;
+      }
+      clear();
+      LiveUnion = LIU;
+      VirtReg = VReg;
+      Tag = LIU->getTag();
+      UserTag = UTag;
+    }
+
+    LiveInterval &virtReg() const {
+      assert(VirtReg && "uninitialized");
+      return *VirtReg;
+    }
+
+    // Does this live virtual register interfere with the union?
+    bool checkInterference() { return collectInterferingVRegs(1); }
+
+    // Count the virtual registers in this union that interfere with this
+    // query's live virtual register, up to maxInterferingRegs.
+    unsigned collectInterferingVRegs(unsigned MaxInterferingRegs = UINT_MAX);
+
+    // Was this virtual register visited during collectInterferingVRegs?
+    bool isSeenInterference(LiveInterval *VReg) const;
+
+    // Did collectInterferingVRegs collect all interferences?
+    bool seenAllInterferences() const { return SeenAllInterferences; }
+
+    // Did collectInterferingVRegs encounter an unspillable vreg?
+    bool seenUnspillableVReg() const { return SeenUnspillableVReg; }
+
+    // Vector generated by collectInterferingVRegs.
+    const SmallVectorImpl<LiveInterval*> &interferingVRegs() const {
+      return InterferingVRegs;
+    }
+
+  private:
+    Query(const Query&) LLVM_DELETED_FUNCTION;
+    void operator=(const Query&) LLVM_DELETED_FUNCTION;
+  };
+
+  // Array of LiveIntervalUnions.
+  class Array {
+    unsigned Size;
+    LiveIntervalUnion *LIUs;
+  public:
+    Array() : Size(0), LIUs(nullptr) {}
+    ~Array() { clear(); }
+
+    // Initialize the array to have Size entries.
+    // Reuse an existing allocation if the size matches.
+    void init(LiveIntervalUnion::Allocator&, unsigned Size);
+
+    unsigned size() const { return Size; }
+
+    void clear();
+
+    LiveIntervalUnion& operator[](unsigned idx) {
+      assert(idx <  Size && "idx out of bounds");
+      return LIUs[idx];
+    }
+  };
+};
+
+} // end namespace llvm
+
+#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION_H)
diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h
new file mode 100644
index 0000000..847092b
--- /dev/null
+++ b/include/llvm/CodeGen/LivePhysRegs.h
@@ -0,0 +1,146 @@
+//===- llvm/CodeGen/LivePhysRegs.h - Live Physical Register Set -*- C++ -*-===//
+//
+//                     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 LivePhysRegs utility for tracking liveness of
+// physical registers. This can be used for ad-hoc liveness tracking after
+// register allocation. You can start with the live-ins/live-outs at the
+// beginning/end of a block and update the information while walking the
+// instructions inside the block. This implementation tracks the liveness on a
+// sub-register granularity.
+//
+// We assume that the high bits of a physical super-register are not preserved
+// unless the instruction has an implicit-use operand reading the super-
+// register.
+//
+// X86 Example:
+// %YMM0<def> = ...
+// %XMM0<def> = ... (Kills %XMM0, all %XMM0s sub-registers, and %YMM0)
+//
+// %YMM0<def> = ...
+// %XMM0<def> = ..., %YMM0<imp-use> (%YMM0 and all its sub-registers are alive)
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVE_PHYS_REGS_H
+#define LLVM_CODEGEN_LIVE_PHYS_REGS_H
+
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+
+namespace llvm {
+
+class MachineInstr;
+
+/// \brief A set of live physical registers with functions to track liveness
+/// when walking backward/forward through a basic block.
+class LivePhysRegs {
+  const TargetRegisterInfo *TRI;
+  SparseSet<unsigned> LiveRegs;
+
+  LivePhysRegs(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
+  LivePhysRegs &operator=(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
+public:
+  /// \brief Constructs a new empty LivePhysRegs set.
+  LivePhysRegs() : TRI(nullptr), LiveRegs() {}
+
+  /// \brief Constructs and initialize an empty LivePhysRegs set.
+  LivePhysRegs(const TargetRegisterInfo *TRI) : TRI(TRI) {
+    assert(TRI && "Invalid TargetRegisterInfo pointer.");
+    LiveRegs.setUniverse(TRI->getNumRegs());
+  }
+
+  /// \brief Clear and initialize the LivePhysRegs set.
+  void init(const TargetRegisterInfo *_TRI) {
+    assert(_TRI && "Invalid TargetRegisterInfo pointer.");
+    TRI = _TRI;
+    LiveRegs.clear();
+    LiveRegs.setUniverse(TRI->getNumRegs());
+  }
+
+  /// \brief Clears the LivePhysRegs set.
+  void clear() { LiveRegs.clear(); }
+
+  /// \brief Returns true if the set is empty.
+  bool empty() const { return LiveRegs.empty(); }
+
+  /// \brief Adds a physical register and all its sub-registers to the set.
+  void addReg(unsigned Reg) {
+    assert(TRI && "LivePhysRegs is not initialized.");
+    assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
+    for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
+         SubRegs.isValid(); ++SubRegs)
+      LiveRegs.insert(*SubRegs);
+  }
+
+  /// \brief Removes a physical register, all its sub-registers, and all its
+  /// super-registers from the set.
+  void removeReg(unsigned Reg) {
+    assert(TRI && "LivePhysRegs is not initialized.");
+    assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
+    for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
+         SubRegs.isValid(); ++SubRegs)
+      LiveRegs.erase(*SubRegs);
+    for (MCSuperRegIterator SuperRegs(Reg, TRI, /*IncludeSelf=*/false);
+         SuperRegs.isValid(); ++SuperRegs)
+      LiveRegs.erase(*SuperRegs);
+  }
+
+  /// \brief Removes physical registers clobbered by the regmask operand @p MO.
+  void removeRegsInMask(const MachineOperand &MO);
+
+  /// \brief Returns true if register @p Reg is contained in the set. This also
+  /// works if only the super register of @p Reg has been defined, because we
+  /// always add also all sub-registers to the set.
+  bool contains(unsigned Reg) const { return LiveRegs.count(Reg); }
+
+  /// \brief Simulates liveness when stepping backwards over an
+  /// instruction(bundle): Remove Defs, add uses. This is the recommended way of
+  /// calculating liveness.
+  void stepBackward(const MachineInstr &MI);
+
+  /// \brief Simulates liveness when stepping forward over an
+  /// instruction(bundle): Remove killed-uses, add defs. This is the not
+  /// recommended way, because it depends on accurate kill flags. If possible
+  /// use stepBackwards() instead of this function.
+  void stepForward(const MachineInstr &MI);
+
+  /// \brief Adds all live-in registers of basic block @p MBB.
+  void addLiveIns(const MachineBasicBlock *MBB) {
+    for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(),
+         LE = MBB->livein_end(); LI != LE; ++LI)
+      addReg(*LI);
+  }
+
+  /// \brief Adds all live-out registers of basic block @p MBB.
+  void addLiveOuts(const MachineBasicBlock *MBB) {
+    for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
+         SE = MBB->succ_end(); SI != SE; ++SI)
+      addLiveIns(*SI);
+  }
+
+  typedef SparseSet<unsigned>::const_iterator const_iterator;
+  const_iterator begin() const { return LiveRegs.begin(); }
+  const_iterator end() const { return LiveRegs.end(); }
+
+  /// \brief Prints the currently live registers to @p OS.
+  void print(raw_ostream &OS) const;
+
+  /// \brief Dumps the currently live registers to the debug output.
+  void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const LivePhysRegs& LR) {
+  LR.print(OS);
+  return OS;
+}
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_LIVE_PHYS_REGS_H
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
new file mode 100644
index 0000000..5767cab
--- /dev/null
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -0,0 +1,231 @@
+//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The LiveRangeEdit class represents changes done to a virtual register when it
+// is spilled or split.
+//
+// The parent register is never changed. Instead, a number of new virtual
+// registers are created and added to the newRegs vector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H
+#define LLVM_CODEGEN_LIVERANGEEDIT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class LiveIntervals;
+class MachineBlockFrequencyInfo;
+class MachineLoopInfo;
+class VirtRegMap;
+
+class LiveRangeEdit : private MachineRegisterInfo::Delegate {
+public:
+  /// Callback methods for LiveRangeEdit owners.
+  class Delegate {
+    virtual void anchor();
+  public:
+    /// Called immediately before erasing a dead machine instruction.
+    virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
+
+    /// Called when a virtual register is no longer used. Return false to defer
+    /// its deletion from LiveIntervals.
+    virtual bool LRE_CanEraseVirtReg(unsigned) { return true; }
+
+    /// Called before shrinking the live range of a virtual register.
+    virtual void LRE_WillShrinkVirtReg(unsigned) {}
+
+    /// Called after cloning a virtual register.
+    /// This is used for new registers representing connected components of Old.
+    virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
+
+    virtual ~Delegate() {}
+  };
+
+private:
+  LiveInterval *Parent;
+  SmallVectorImpl<unsigned> &NewRegs;
+  MachineRegisterInfo &MRI;
+  LiveIntervals &LIS;
+  VirtRegMap *VRM;
+  const TargetInstrInfo &TII;
+  Delegate *const TheDelegate;
+
+  /// FirstNew - Index of the first register added to NewRegs.
+  const unsigned FirstNew;
+
+  /// ScannedRemattable - true when remattable values have been identified.
+  bool ScannedRemattable;
+
+  /// Remattable - Values defined by remattable instructions as identified by
+  /// tii.isTriviallyReMaterializable().
+  SmallPtrSet<const VNInfo*,4> Remattable;
+
+  /// Rematted - Values that were actually rematted, and so need to have their
+  /// live range trimmed or entirely removed.
+  SmallPtrSet<const VNInfo*,4> Rematted;
+
+  /// scanRemattable - Identify the Parent values that may rematerialize.
+  void scanRemattable(AliasAnalysis *aa);
+
+  /// allUsesAvailableAt - Return true if all registers used by OrigMI at
+  /// OrigIdx are also available with the same value at UseIdx.
+  bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
+                          SlotIndex UseIdx) const;
+
+  /// foldAsLoad - If LI has a single use and a single def that can be folded as
+  /// a load, eliminate the register by folding the def into the use.
+  bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead);
+
+  typedef SetVector<LiveInterval*,
+                    SmallVector<LiveInterval*, 8>,
+                    SmallPtrSet<LiveInterval*, 8> > ToShrinkSet;
+  /// Helper for eliminateDeadDefs.
+  void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink);
+
+  /// MachineRegisterInfo callback to notify when new virtual
+  /// registers are created.
+  void MRI_NoteNewVirtualRegister(unsigned VReg) override;
+
+public:
+  /// Create a LiveRangeEdit for breaking down parent into smaller pieces.
+  /// @param parent The register being spilled or split.
+  /// @param newRegs List to receive any new registers created. This needn't be
+  ///                empty initially, any existing registers are ignored.
+  /// @param MF The MachineFunction the live range edit is taking place in.
+  /// @param lis The collection of all live intervals in this function.
+  /// @param vrm Map of virtual registers to physical registers for this
+  ///            function.  If NULL, no virtual register map updates will
+  ///            be done.  This could be the case if called before Regalloc.
+  LiveRangeEdit(LiveInterval *parent,
+                SmallVectorImpl<unsigned> &newRegs,
+                MachineFunction &MF,
+                LiveIntervals &lis,
+                VirtRegMap *vrm,
+                Delegate *delegate = nullptr)
+    : Parent(parent), NewRegs(newRegs),
+      MRI(MF.getRegInfo()), LIS(lis), VRM(vrm),
+      TII(*MF.getTarget().getInstrInfo()),
+      TheDelegate(delegate),
+      FirstNew(newRegs.size()),
+      ScannedRemattable(false) { MRI.setDelegate(this); }
+
+  ~LiveRangeEdit() { MRI.resetDelegate(this); }
+
+  LiveInterval &getParent() const {
+   assert(Parent && "No parent LiveInterval");
+   return *Parent;
+  }
+  unsigned getReg() const { return getParent().reg; }
+
+  /// Iterator for accessing the new registers added by this edit.
+  typedef SmallVectorImpl<unsigned>::const_iterator iterator;
+  iterator begin() const { return NewRegs.begin()+FirstNew; }
+  iterator end() const { return NewRegs.end(); }
+  unsigned size() const { return NewRegs.size()-FirstNew; }
+  bool empty() const { return size() == 0; }
+  unsigned get(unsigned idx) const { return NewRegs[idx+FirstNew]; }
+
+  ArrayRef<unsigned> regs() const {
+    return makeArrayRef(NewRegs).slice(FirstNew);
+  }
+
+  /// createEmptyIntervalFrom - Create a new empty interval based on OldReg.
+  LiveInterval &createEmptyIntervalFrom(unsigned OldReg);
+
+  /// createFrom - Create a new virtual register based on OldReg.
+  unsigned createFrom(unsigned OldReg);
+
+  /// create - Create a new register with the same class and original slot as
+  /// parent.
+  LiveInterval &createEmptyInterval() {
+    return createEmptyIntervalFrom(getReg());
+  }
+
+  unsigned create() {
+    return createFrom(getReg());
+  }
+
+  /// anyRematerializable - Return true if any parent values may be
+  /// rematerializable.
+  /// This function must be called before any rematerialization is attempted.
+  bool anyRematerializable(AliasAnalysis*);
+
+  /// checkRematerializable - Manually add VNI to the list of rematerializable
+  /// values if DefMI may be rematerializable.
+  bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
+                             AliasAnalysis*);
+
+  /// Remat - Information needed to rematerialize at a specific location.
+  struct Remat {
+    VNInfo *ParentVNI;      // parent_'s value at the remat location.
+    MachineInstr *OrigMI;   // Instruction defining ParentVNI.
+    explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(nullptr) {}
+  };
+
+  /// canRematerializeAt - Determine if ParentVNI can be rematerialized at
+  /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI.
+  /// When cheapAsAMove is set, only cheap remats are allowed.
+  bool canRematerializeAt(Remat &RM,
+                          SlotIndex UseIdx,
+                          bool cheapAsAMove);
+
+  /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
+  /// instruction into MBB before MI. The new instruction is mapped, but
+  /// liveness is not updated.
+  /// Return the SlotIndex of the new instruction.
+  SlotIndex rematerializeAt(MachineBasicBlock &MBB,
+                            MachineBasicBlock::iterator MI,
+                            unsigned DestReg,
+                            const Remat &RM,
+                            const TargetRegisterInfo&,
+                            bool Late = false);
+
+  /// markRematerialized - explicitly mark a value as rematerialized after doing
+  /// it manually.
+  void markRematerialized(const VNInfo *ParentVNI) {
+    Rematted.insert(ParentVNI);
+  }
+
+  /// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
+  bool didRematerialize(const VNInfo *ParentVNI) const {
+    return Rematted.count(ParentVNI);
+  }
+
+  /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
+  /// to erase it from LIS.
+  void eraseVirtReg(unsigned Reg);
+
+  /// eliminateDeadDefs - Try to delete machine instructions that are now dead
+  /// (allDefsAreDead returns true). This may cause live intervals to be trimmed
+  /// and further dead efs to be eliminated.
+  /// RegsBeingSpilled lists registers currently being spilled by the register
+  /// allocator.  These registers should not be split into new intervals
+  /// as currently those new intervals are not guaranteed to spill.
+  void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
+                         ArrayRef<unsigned> RegsBeingSpilled = None);
+
+  /// calculateRegClassAndHint - Recompute register class and hint for each new
+  /// register.
+  void calculateRegClassAndHint(MachineFunction&,
+                                const MachineLoopInfo&,
+                                const MachineBlockFrequencyInfo&);
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h
new file mode 100644
index 0000000..878b4d9
--- /dev/null
+++ b/include/llvm/CodeGen/LiveRegMatrix.h
@@ -0,0 +1,147 @@
+//===-- LiveRegMatrix.h - Track register interference ---------*- C++ -*---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The LiveRegMatrix analysis pass keeps track of virtual register interference
+// along two dimensions: Slot indexes and register units. The matrix is used by
+// register allocators to ensure that no interfering virtual registers get
+// assigned to overlapping physical registers.
+//
+// Register units are defined in MCRegisterInfo.h, they represent the smallest
+// unit of interference when dealing with overlapping physical registers. The
+// LiveRegMatrix is represented as a LiveIntervalUnion per register unit. When
+// a virtual register is assigned to a physical register, the live range for
+// the virtual register is inserted into the LiveIntervalUnion for each regunit
+// in the physreg.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEREGMATRIX_H
+#define LLVM_CODEGEN_LIVEREGMATRIX_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/LiveIntervalUnion.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+class LiveInterval;
+class LiveIntervalAnalysis;
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+class VirtRegMap;
+
+class LiveRegMatrix : public MachineFunctionPass {
+  const TargetRegisterInfo *TRI;
+  MachineRegisterInfo *MRI;
+  LiveIntervals *LIS;
+  VirtRegMap *VRM;
+
+  // UserTag changes whenever virtual registers have been modified.
+  unsigned UserTag;
+
+  // The matrix is represented as a LiveIntervalUnion per register unit.
+  LiveIntervalUnion::Allocator LIUAlloc;
+  LiveIntervalUnion::Array Matrix;
+
+  // Cached queries per register unit.
+  std::unique_ptr<LiveIntervalUnion::Query[]> Queries;
+
+  // Cached register mask interference info.
+  unsigned RegMaskTag;
+  unsigned RegMaskVirtReg;
+  BitVector RegMaskUsable;
+
+  // MachineFunctionPass boilerplate.
+  void getAnalysisUsage(AnalysisUsage&) const override;
+  bool runOnMachineFunction(MachineFunction&) override;
+  void releaseMemory() override;
+public:
+  static char ID;
+  LiveRegMatrix();
+
+  //===--------------------------------------------------------------------===//
+  // High-level interface.
+  //===--------------------------------------------------------------------===//
+  //
+  // Check for interference before assigning virtual registers to physical
+  // registers.
+  //
+
+  /// Invalidate cached interference queries after modifying virtual register
+  /// live ranges. Interference checks may return stale information unless
+  /// caches are invalidated.
+  void invalidateVirtRegs() { ++UserTag; }
+
+  enum InterferenceKind {
+    /// No interference, go ahead and assign.
+    IK_Free = 0,
+
+    /// Virtual register interference. There are interfering virtual registers
+    /// assigned to PhysReg or its aliases. This interference could be resolved
+    /// by unassigning those other virtual registers.
+    IK_VirtReg,
+
+    /// Register unit interference. A fixed live range is in the way, typically
+    /// argument registers for a call. This can't be resolved by unassigning
+    /// other virtual registers.
+    IK_RegUnit,
+
+    /// RegMask interference. The live range is crossing an instruction with a
+    /// regmask operand that doesn't preserve PhysReg. This typically means
+    /// VirtReg is live across a call, and PhysReg isn't call-preserved.
+    IK_RegMask
+  };
+
+  /// Check for interference before assigning VirtReg to PhysReg.
+  /// If this function returns IK_Free, it is legal to assign(VirtReg, PhysReg).
+  /// When there is more than one kind of interference, the InterferenceKind
+  /// with the highest enum value is returned.
+  InterferenceKind checkInterference(LiveInterval &VirtReg, unsigned PhysReg);
+
+  /// Assign VirtReg to PhysReg.
+  /// This will mark VirtReg's live range as occupied in the LiveRegMatrix and
+  /// update VirtRegMap. The live range is expected to be available in PhysReg.
+  void assign(LiveInterval &VirtReg, unsigned PhysReg);
+
+  /// Unassign VirtReg from its PhysReg.
+  /// Assuming that VirtReg was previously assigned to a PhysReg, this undoes
+  /// the assignment and updates VirtRegMap accordingly.
+  void unassign(LiveInterval &VirtReg);
+
+  //===--------------------------------------------------------------------===//
+  // Low-level interface.
+  //===--------------------------------------------------------------------===//
+  //
+  // Provide access to the underlying LiveIntervalUnions.
+  //
+
+  /// Check for regmask interference only.
+  /// Return true if VirtReg crosses a regmask operand that clobbers PhysReg.
+  /// If PhysReg is null, check if VirtReg crosses any regmask operands.
+  bool checkRegMaskInterference(LiveInterval &VirtReg, unsigned PhysReg = 0);
+
+  /// Check for regunit interference only.
+  /// Return true if VirtReg overlaps a fixed assignment of one of PhysRegs's
+  /// register units.
+  bool checkRegUnitInterference(LiveInterval &VirtReg, unsigned PhysReg);
+
+  /// Query a line of the assigned virtual register matrix directly.
+  /// Use MCRegUnitIterator to enumerate all regunits in the desired PhysReg.
+  /// This returns a reference to an internal Query data structure that is only
+  /// valid until the next query() call.
+  LiveIntervalUnion::Query &query(LiveInterval &VirtReg, unsigned RegUnit);
+
+  /// Directly access the live interval unions per regunit.
+  /// This returns an array indexed by the regunit number.
+  LiveIntervalUnion *getLiveUnions() { return &Matrix[0]; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_LIVEREGMATRIX_H
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
new file mode 100644
index 0000000..df68398
--- /dev/null
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -0,0 +1,99 @@
+//===-- LiveStackAnalysis.h - Live Stack Slot Analysis ----------*- C++ -*-===//
+//
+//                     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 live stack slot analysis pass. It is analogous to
+// live interval analysis except it's analyzing liveness of stack slots rather
+// than registers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVESTACKANALYSIS_H
+#define LLVM_CODEGEN_LIVESTACKANALYSIS_H
+
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <map>
+
+namespace llvm {
+
+  class LiveStacks : public MachineFunctionPass {
+    const TargetRegisterInfo *TRI;
+
+    /// Special pool allocator for VNInfo's (LiveInterval val#).
+    ///
+    VNInfo::Allocator VNInfoAllocator;
+
+    /// S2IMap - Stack slot indices to live interval mapping.
+    ///
+    typedef std::map<int, LiveInterval> SS2IntervalMap;
+    SS2IntervalMap S2IMap;
+
+    /// S2RCMap - Stack slot indices to register class mapping.
+    std::map<int, const TargetRegisterClass*> S2RCMap;
+    
+  public:
+    static char ID; // Pass identification, replacement for typeid
+    LiveStacks() : MachineFunctionPass(ID) {
+      initializeLiveStacksPass(*PassRegistry::getPassRegistry());
+    }
+
+    typedef SS2IntervalMap::iterator iterator;
+    typedef SS2IntervalMap::const_iterator const_iterator;
+    const_iterator begin() const { return S2IMap.begin(); }
+    const_iterator end() const { return S2IMap.end(); }
+    iterator begin() { return S2IMap.begin(); }
+    iterator end() { return S2IMap.end(); }
+
+    unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
+
+    LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
+
+    LiveInterval &getInterval(int Slot) {
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      SS2IntervalMap::iterator I = S2IMap.find(Slot);
+      assert(I != S2IMap.end() && "Interval does not exist for stack slot");
+      return I->second;
+    }
+
+    const LiveInterval &getInterval(int Slot) const {
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
+      assert(I != S2IMap.end() && "Interval does not exist for stack slot");
+      return I->second;
+    }
+
+    bool hasInterval(int Slot) const {
+      return S2IMap.count(Slot);
+    }
+
+    const TargetRegisterClass *getIntervalRegClass(int Slot) const {
+      assert(Slot >= 0 && "Spill slot indice must be >= 0");
+      std::map<int, const TargetRegisterClass*>::const_iterator
+        I = S2RCMap.find(Slot);
+      assert(I != S2RCMap.end() &&
+             "Register class info does not exist for stack slot");
+      return I->second;
+    }
+
+    VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
+
+    void getAnalysisUsage(AnalysisUsage &AU) const override;
+    void releaseMemory() override;
+
+    /// runOnMachineFunction - pass entry point
+    bool runOnMachineFunction(MachineFunction&) override;
+
+    /// print - Implement the dump method.
+    void print(raw_ostream &O, const Module* = nullptr) const override;
+  };
+}
+
+#endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
new file mode 100644
index 0000000..a4a5fcc
--- /dev/null
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -0,0 +1,307 @@
+//===-- llvm/CodeGen/LiveVariables.h - Live Variable Analysis ---*- C++ -*-===//
+//
+//                     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 LiveVariables analysis pass.  For each machine
+// instruction in the function, this pass calculates the set of registers that
+// are immediately dead after the instruction (i.e., the instruction calculates
+// the value, but it is never used) and the set of registers that are used by
+// the instruction, but are never used after the instruction (i.e., they are
+// killed).
+//
+// This class computes live variables using a sparse implementation based on
+// the machine code SSA form.  This class computes live variable information for
+// each virtual and _register allocatable_ physical register in a function.  It
+// uses the dominance properties of SSA form to efficiently compute live
+// variables for virtual registers, and assumes that physical registers are only
+// live within a single basic block (allowing it to do a single local analysis
+// to resolve physical register lifetimes in each basic block).  If a physical
+// register is not register allocatable, it is not tracked.  This is useful for
+// things like the stack pointer and condition codes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEVARIABLES_H
+#define LLVM_CODEGEN_LIVEVARIABLES_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SparseBitVector.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineRegisterInfo;
+
+class LiveVariables : public MachineFunctionPass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+  LiveVariables() : MachineFunctionPass(ID) {
+    initializeLiveVariablesPass(*PassRegistry::getPassRegistry());
+  }
+
+  /// VarInfo - This represents the regions where a virtual register is live in
+  /// the program.  We represent this with three different pieces of
+  /// information: the set of blocks in which the instruction is live
+  /// throughout, the set of blocks in which the instruction is actually used,
+  /// and the set of non-phi instructions that are the last users of the value.
+  ///
+  /// In the common case where a value is defined and killed in the same block,
+  /// There is one killing instruction, and AliveBlocks is empty.
+  ///
+  /// Otherwise, the value is live out of the block.  If the value is live
+  /// throughout any blocks, these blocks are listed in AliveBlocks.  Blocks
+  /// where the liveness range ends are not included in AliveBlocks, instead
+  /// being captured by the Kills set.  In these blocks, the value is live into
+  /// the block (unless the value is defined and killed in the same block) and
+  /// lives until the specified instruction.  Note that there cannot ever be a
+  /// value whose Kills set contains two instructions from the same basic block.
+  ///
+  /// PHI nodes complicate things a bit.  If a PHI node is the last user of a
+  /// value in one of its predecessor blocks, it is not listed in the kills set,
+  /// but does include the predecessor block in the AliveBlocks set (unless that
+  /// block also defines the value).  This leads to the (perfectly sensical)
+  /// situation where a value is defined in a block, and the last use is a phi
+  /// node in the successor.  In this case, AliveBlocks is empty (the value is
+  /// not live across any  blocks) and Kills is empty (phi nodes are not
+  /// included). This is sensical because the value must be live to the end of
+  /// the block, but is not live in any successor blocks.
+  struct VarInfo {
+    /// AliveBlocks - Set of blocks in which this value is alive completely
+    /// through.  This is a bit set which uses the basic block number as an
+    /// index.
+    ///
+    SparseBitVector<> AliveBlocks;
+
+    /// Kills - List of MachineInstruction's which are the last use of this
+    /// virtual register (kill it) in their basic block.
+    ///
+    std::vector<MachineInstr*> Kills;
+
+    /// removeKill - Delete a kill corresponding to the specified
+    /// machine instruction. Returns true if there was a kill
+    /// corresponding to this instruction, false otherwise.
+    bool removeKill(MachineInstr *MI) {
+      std::vector<MachineInstr*>::iterator
+        I = std::find(Kills.begin(), Kills.end(), MI);
+      if (I == Kills.end())
+        return false;
+      Kills.erase(I);
+      return true;
+    }
+
+    /// findKill - Find a kill instruction in MBB. Return NULL if none is found.
+    MachineInstr *findKill(const MachineBasicBlock *MBB) const;
+
+    /// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
+    /// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
+    /// MBB, it is not considered live in.
+    bool isLiveIn(const MachineBasicBlock &MBB,
+                  unsigned Reg,
+                  MachineRegisterInfo &MRI);
+
+    void dump() const;
+  };
+
+private:
+  /// VirtRegInfo - This list is a mapping from virtual register number to
+  /// variable information.
+  ///
+  IndexedMap<VarInfo, VirtReg2IndexFunctor> VirtRegInfo;
+
+  /// PHIJoins - list of virtual registers that are PHI joins. These registers
+  /// may have multiple definitions, and they require special handling when
+  /// building live intervals.
+  SparseBitVector<> PHIJoins;
+
+private:   // Intermediate data structures
+  MachineFunction *MF;
+
+  MachineRegisterInfo* MRI;
+
+  const TargetRegisterInfo *TRI;
+
+  // PhysRegInfo - Keep track of which instruction was the last def of a
+  // physical register. This is a purely local property, because all physical
+  // register references are presumed dead across basic blocks.
+  MachineInstr **PhysRegDef;
+
+  // PhysRegInfo - Keep track of which instruction was the last use of a
+  // physical register. This is a purely local property, because all physical
+  // register references are presumed dead across basic blocks.
+  MachineInstr **PhysRegUse;
+
+  SmallVector<unsigned, 4> *PHIVarInfo;
+
+  // DistanceMap - Keep track the distance of a MI from the start of the
+  // current basic block.
+  DenseMap<MachineInstr*, unsigned> DistanceMap;
+
+  /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+  /// uses. Pay special attention to the sub-register uses which may come below
+  /// the last use of the whole register.
+  bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
+
+  /// HandleRegMask - Call HandlePhysRegKill for all registers clobbered by Mask.
+  void HandleRegMask(const MachineOperand&);
+
+  void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
+  void HandlePhysRegDef(unsigned Reg, MachineInstr *MI,
+                        SmallVectorImpl<unsigned> &Defs);
+  void UpdatePhysRegDefs(MachineInstr *MI, SmallVectorImpl<unsigned> &Defs);
+
+  /// FindLastRefOrPartRef - Return the last reference or partial reference of
+  /// the specified register.
+  MachineInstr *FindLastRefOrPartRef(unsigned Reg);
+
+  /// FindLastPartialDef - Return the last partial def of the specified
+  /// register. Also returns the sub-registers that're defined by the
+  /// instruction.
+  MachineInstr *FindLastPartialDef(unsigned Reg,
+                                   SmallSet<unsigned,4> &PartDefRegs);
+
+  /// analyzePHINodes - Gather information about the PHI nodes in here. In
+  /// particular, we want to map the variable information of a virtual
+  /// register which is used in a PHI node. We map that to the BB the vreg
+  /// is coming from.
+  void analyzePHINodes(const MachineFunction& Fn);
+public:
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  /// RegisterDefIsDead - Return true if the specified instruction defines the
+  /// specified register, but that definition is dead.
+  bool RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const;
+
+  //===--------------------------------------------------------------------===//
+  //  API to update live variable information
+
+  /// replaceKillInstruction - Update register kill info by replacing a kill
+  /// instruction with a new one.
+  void replaceKillInstruction(unsigned Reg, MachineInstr *OldMI,
+                              MachineInstr *NewMI);
+
+  /// addVirtualRegisterKilled - Add information about the fact that the
+  /// specified register is killed after being used by the specified
+  /// instruction. If AddIfNotFound is true, add a implicit operand if it's
+  /// not found.
+  void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+                                bool AddIfNotFound = false) {
+    if (MI->addRegisterKilled(IncomingReg, TRI, AddIfNotFound))
+      getVarInfo(IncomingReg).Kills.push_back(MI); 
+  }
+
+  /// removeVirtualRegisterKilled - Remove the specified kill of the virtual
+  /// register from the live variable information. Returns true if the
+  /// variable was marked as killed by the specified instruction,
+  /// false otherwise.
+  bool removeVirtualRegisterKilled(unsigned reg, MachineInstr *MI) {
+    if (!getVarInfo(reg).removeKill(MI))
+      return false;
+
+    bool Removed = false;
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = MI->getOperand(i);
+      if (MO.isReg() && MO.isKill() && MO.getReg() == reg) {
+        MO.setIsKill(false);
+        Removed = true;
+        break;
+      }
+    }
+
+    assert(Removed && "Register is not used by this instruction!");
+    (void)Removed;
+    return true;
+  }
+
+  /// removeVirtualRegistersKilled - Remove all killed info for the specified
+  /// instruction.
+  void removeVirtualRegistersKilled(MachineInstr *MI);
+
+  /// addVirtualRegisterDead - Add information about the fact that the specified
+  /// register is dead after being used by the specified instruction. If
+  /// AddIfNotFound is true, add a implicit operand if it's not found.
+  void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+                              bool AddIfNotFound = false) {
+    if (MI->addRegisterDead(IncomingReg, TRI, AddIfNotFound))
+      getVarInfo(IncomingReg).Kills.push_back(MI);
+  }
+
+  /// removeVirtualRegisterDead - Remove the specified kill of the virtual
+  /// register from the live variable information. Returns true if the
+  /// variable was marked dead at the specified instruction, false
+  /// otherwise.
+  bool removeVirtualRegisterDead(unsigned reg, MachineInstr *MI) {
+    if (!getVarInfo(reg).removeKill(MI))
+      return false;
+
+    bool Removed = false;
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      MachineOperand &MO = MI->getOperand(i);
+      if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
+        MO.setIsDead(false);
+        Removed = true;
+        break;
+      }
+    }
+    assert(Removed && "Register is not defined by this instruction!");
+    (void)Removed;
+    return true;
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  void releaseMemory() override {
+    VirtRegInfo.clear();
+  }
+
+  /// getVarInfo - Return the VarInfo structure for the specified VIRTUAL
+  /// register.
+  VarInfo &getVarInfo(unsigned RegIdx);
+
+  void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+                               MachineBasicBlock *BB);
+  void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+                               MachineBasicBlock *BB,
+                               std::vector<MachineBasicBlock*> &WorkList);
+  void HandleVirtRegDef(unsigned reg, MachineInstr *MI);
+  void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
+                        MachineInstr *MI);
+
+  bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
+    return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
+  }
+
+  /// isLiveOut - Determine if Reg is live out from MBB, when not considering
+  /// PHI nodes. This means that Reg is either killed by a successor block or
+  /// passed through one.
+  bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB);
+
+  /// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
+  /// variables that are live out of DomBB and live into SuccBB will be marked
+  /// as passing live through BB. This method assumes that the machine code is
+  /// still in SSA form.
+  void addNewBlock(MachineBasicBlock *BB,
+                   MachineBasicBlock *DomBB,
+                   MachineBasicBlock *SuccBB);
+
+  /// isPHIJoin - Return true if Reg is a phi join register.
+  bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); }
+
+  /// setPHIJoin - Mark Reg as a phi join register.
+  void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
new file mode 100644
index 0000000..8c9b7a8
--- /dev/null
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -0,0 +1,56 @@
+//=== MachORelocation.h - Mach-O Relocation 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 the MachORelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHORELOCATION_H
+#define LLVM_CODEGEN_MACHORELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+  /// MachORelocation - This struct contains information about each relocation
+  /// that needs to be emitted to the file.
+  /// see <mach-o/reloc.h>
+  class MachORelocation {
+    uint32_t r_address;   // offset in the section to what is being  relocated
+    uint32_t r_symbolnum; // symbol index if r_extern == 1 else section index
+    bool     r_pcrel;     // was relocated pc-relative already
+    uint8_t  r_length;    // length = 2 ^ r_length
+    bool     r_extern;    // 
+    uint8_t  r_type;      // if not 0, machine-specific relocation type.
+    bool     r_scattered; // 1 = scattered, 0 = non-scattered
+    int32_t  r_value;     // the value the item to be relocated is referring
+                          // to.
+  public:      
+    uint32_t getPackedFields() const {
+      if (r_scattered)
+        return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) | 
+          ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
+      else
+        return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
+          (r_extern << 4) | (r_type & 15);
+    }
+    uint32_t getAddress() const { return r_scattered ? r_value : r_address; }
+    uint32_t getRawAddress() const { return r_address; }
+
+    MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
+                    bool ext, uint8_t type, bool scattered = false, 
+                    int32_t value = 0) : 
+      r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
+      r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
+  };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_MACHORELOCATION_H
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
new file mode 100644
index 0000000..a08cc2e
--- /dev/null
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -0,0 +1,790 @@
+//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the sequence of machine instructions for a basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
+#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/DataTypes.h"
+#include <functional>
+
+namespace llvm {
+
+class Pass;
+class BasicBlock;
+class MachineFunction;
+class MCSymbol;
+class SlotIndexes;
+class StringRef;
+class raw_ostream;
+class MachineBranchProbabilityInfo;
+
+template <>
+struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
+private:
+  mutable ilist_half_node<MachineInstr> Sentinel;
+
+  // this is only set by the MachineBasicBlock owning the LiveList
+  friend class MachineBasicBlock;
+  MachineBasicBlock* Parent;
+
+public:
+  MachineInstr *createSentinel() const {
+    return static_cast<MachineInstr*>(&Sentinel);
+  }
+  void destroySentinel(MachineInstr *) const {}
+
+  MachineInstr *provideInitialHead() const { return createSentinel(); }
+  MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); }
+  static void noteHead(MachineInstr*, MachineInstr*) {}
+
+  void addNodeToList(MachineInstr* N);
+  void removeNodeFromList(MachineInstr* N);
+  void transferNodesFromList(ilist_traits &SrcTraits,
+                             ilist_iterator<MachineInstr> first,
+                             ilist_iterator<MachineInstr> last);
+  void deleteNode(MachineInstr *N);
+private:
+  void createNode(const MachineInstr &);
+};
+
+class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
+  typedef ilist<MachineInstr> Instructions;
+  Instructions Insts;
+  const BasicBlock *BB;
+  int Number;
+  MachineFunction *xParent;
+
+  /// Predecessors/Successors - Keep track of the predecessor / successor
+  /// basicblocks.
+  std::vector<MachineBasicBlock *> Predecessors;
+  std::vector<MachineBasicBlock *> Successors;
+
+  /// Weights - Keep track of the weights to the successors. This vector
+  /// has the same order as Successors, or it is empty if we don't use it
+  /// (disable optimization).
+  std::vector<uint32_t> Weights;
+  typedef std::vector<uint32_t>::iterator weight_iterator;
+  typedef std::vector<uint32_t>::const_iterator const_weight_iterator;
+
+  /// LiveIns - Keep track of the physical registers that are livein of
+  /// the basicblock.
+  std::vector<unsigned> LiveIns;
+
+  /// Alignment - Alignment of the basic block. Zero if the basic block does
+  /// not need to be aligned.
+  /// The alignment is specified as log2(bytes).
+  unsigned Alignment;
+
+  /// IsLandingPad - Indicate that this basic block is entered via an
+  /// exception handler.
+  bool IsLandingPad;
+
+  /// AddressTaken - Indicate that this basic block is potentially the
+  /// target of an indirect branch.
+  bool AddressTaken;
+
+  /// \brief since getSymbol is a relatively heavy-weight operation, the symbol
+  /// is only computed once and is cached.
+  mutable MCSymbol *CachedMCSymbol;
+
+  // Intrusive list support
+  MachineBasicBlock() {}
+
+  explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb);
+
+  ~MachineBasicBlock();
+
+  // MachineBasicBlocks are allocated and owned by MachineFunction.
+  friend class MachineFunction;
+
+public:
+  /// getBasicBlock - Return the LLVM basic block that this instance
+  /// corresponded to originally. Note that this may be NULL if this instance
+  /// does not correspond directly to an LLVM basic block.
+  ///
+  const BasicBlock *getBasicBlock() const { return BB; }
+
+  /// getName - Return the name of the corresponding LLVM basic block, or
+  /// "(null)".
+  StringRef getName() const;
+
+  /// getFullName - Return a formatted string to identify this block and its
+  /// parent function.
+  std::string getFullName() const;
+
+  /// hasAddressTaken - Test whether this block is potentially the target
+  /// of an indirect branch.
+  bool hasAddressTaken() const { return AddressTaken; }
+
+  /// setHasAddressTaken - Set this block to reflect that it potentially
+  /// is the target of an indirect branch.
+  void setHasAddressTaken() { AddressTaken = true; }
+
+  /// getParent - Return the MachineFunction containing this basic block.
+  ///
+  const MachineFunction *getParent() const { return xParent; }
+  MachineFunction *getParent() { return xParent; }
+
+
+  /// bundle_iterator - MachineBasicBlock iterator that automatically skips over
+  /// MIs that are inside bundles (i.e. walk top level MIs only).
+  template<typename Ty, typename IterTy>
+  class bundle_iterator
+    : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> {
+    IterTy MII;
+
+  public:
+    bundle_iterator(IterTy mii) : MII(mii) {}
+
+    bundle_iterator(Ty &mi) : MII(mi) {
+      assert(!mi.isBundledWithPred() &&
+             "It's not legal to initialize bundle_iterator with a bundled MI");
+    }
+    bundle_iterator(Ty *mi) : MII(mi) {
+      assert((!mi || !mi->isBundledWithPred()) &&
+             "It's not legal to initialize bundle_iterator with a bundled MI");
+    }
+    // Template allows conversion from const to nonconst.
+    template<class OtherTy, class OtherIterTy>
+    bundle_iterator(const bundle_iterator<OtherTy, OtherIterTy> &I)
+      : MII(I.getInstrIterator()) {}
+    bundle_iterator() : MII(nullptr) {}
+
+    Ty &operator*() const { return *MII; }
+    Ty *operator->() const { return &operator*(); }
+
+    operator Ty*() const { return MII; }
+
+    bool operator==(const bundle_iterator &x) const {
+      return MII == x.MII;
+    }
+    bool operator!=(const bundle_iterator &x) const {
+      return !operator==(x);
+    }
+
+    // Increment and decrement operators...
+    bundle_iterator &operator--() {      // predecrement - Back up
+      do --MII;
+      while (MII->isBundledWithPred());
+      return *this;
+    }
+    bundle_iterator &operator++() {      // preincrement - Advance
+      while (MII->isBundledWithSucc())
+        ++MII;
+      ++MII;
+      return *this;
+    }
+    bundle_iterator operator--(int) {    // postdecrement operators...
+      bundle_iterator tmp = *this;
+      --*this;
+      return tmp;
+    }
+    bundle_iterator operator++(int) {    // postincrement operators...
+      bundle_iterator tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    IterTy getInstrIterator() const {
+      return MII;
+    }
+  };
+
+  typedef Instructions::iterator                                 instr_iterator;
+  typedef Instructions::const_iterator                     const_instr_iterator;
+  typedef std::reverse_iterator<instr_iterator>          reverse_instr_iterator;
+  typedef
+  std::reverse_iterator<const_instr_iterator>      const_reverse_instr_iterator;
+
+  typedef
+  bundle_iterator<MachineInstr,instr_iterator>                         iterator;
+  typedef
+  bundle_iterator<const MachineInstr,const_instr_iterator>       const_iterator;
+  typedef std::reverse_iterator<const_iterator>          const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>                      reverse_iterator;
+
+
+  unsigned size() const { return (unsigned)Insts.size(); }
+  bool empty() const { return Insts.empty(); }
+
+  MachineInstr       &instr_front()       { return Insts.front(); }
+  MachineInstr       &instr_back()        { return Insts.back();  }
+  const MachineInstr &instr_front() const { return Insts.front(); }
+  const MachineInstr &instr_back()  const { return Insts.back();  }
+
+  MachineInstr       &front()             { return Insts.front(); }
+  MachineInstr       &back()              { return *--end();      }
+  const MachineInstr &front()       const { return Insts.front(); }
+  const MachineInstr &back()        const { return *--end();      }
+
+  instr_iterator                instr_begin()       { return Insts.begin();  }
+  const_instr_iterator          instr_begin() const { return Insts.begin();  }
+  instr_iterator                  instr_end()       { return Insts.end();    }
+  const_instr_iterator            instr_end() const { return Insts.end();    }
+  reverse_instr_iterator       instr_rbegin()       { return Insts.rbegin(); }
+  const_reverse_instr_iterator instr_rbegin() const { return Insts.rbegin(); }
+  reverse_instr_iterator       instr_rend  ()       { return Insts.rend();   }
+  const_reverse_instr_iterator instr_rend  () const { return Insts.rend();   }
+
+  iterator                begin()       { return instr_begin();  }
+  const_iterator          begin() const { return instr_begin();  }
+  iterator                end  ()       { return instr_end();    }
+  const_iterator          end  () const { return instr_end();    }
+  reverse_iterator       rbegin()       { return instr_rbegin(); }
+  const_reverse_iterator rbegin() const { return instr_rbegin(); }
+  reverse_iterator       rend  ()       { return instr_rend();   }
+  const_reverse_iterator rend  () const { return instr_rend();   }
+
+  inline iterator_range<iterator> terminators() {
+    return iterator_range<iterator>(getFirstTerminator(), end());
+  }
+  inline iterator_range<const_iterator> terminators() const {
+    return iterator_range<const_iterator>(getFirstTerminator(), end());
+  }
+
+  // Machine-CFG iterators
+  typedef std::vector<MachineBasicBlock *>::iterator       pred_iterator;
+  typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
+  typedef std::vector<MachineBasicBlock *>::iterator       succ_iterator;
+  typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
+  typedef std::vector<MachineBasicBlock *>::reverse_iterator
+                                                         pred_reverse_iterator;
+  typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+                                                   const_pred_reverse_iterator;
+  typedef std::vector<MachineBasicBlock *>::reverse_iterator
+                                                         succ_reverse_iterator;
+  typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+                                                   const_succ_reverse_iterator;
+  pred_iterator        pred_begin()       { return Predecessors.begin(); }
+  const_pred_iterator  pred_begin() const { return Predecessors.begin(); }
+  pred_iterator        pred_end()         { return Predecessors.end();   }
+  const_pred_iterator  pred_end()   const { return Predecessors.end();   }
+  pred_reverse_iterator        pred_rbegin()
+                                          { return Predecessors.rbegin();}
+  const_pred_reverse_iterator  pred_rbegin() const
+                                          { return Predecessors.rbegin();}
+  pred_reverse_iterator        pred_rend()
+                                          { return Predecessors.rend();  }
+  const_pred_reverse_iterator  pred_rend()   const
+                                          { return Predecessors.rend();  }
+  unsigned             pred_size()  const {
+    return (unsigned)Predecessors.size();
+  }
+  bool                 pred_empty() const { return Predecessors.empty(); }
+  succ_iterator        succ_begin()       { return Successors.begin();   }
+  const_succ_iterator  succ_begin() const { return Successors.begin();   }
+  succ_iterator        succ_end()         { return Successors.end();     }
+  const_succ_iterator  succ_end()   const { return Successors.end();     }
+  succ_reverse_iterator        succ_rbegin()
+                                          { return Successors.rbegin();  }
+  const_succ_reverse_iterator  succ_rbegin() const
+                                          { return Successors.rbegin();  }
+  succ_reverse_iterator        succ_rend()
+                                          { return Successors.rend();    }
+  const_succ_reverse_iterator  succ_rend()   const
+                                          { return Successors.rend();    }
+  unsigned             succ_size()  const {
+    return (unsigned)Successors.size();
+  }
+  bool                 succ_empty() const { return Successors.empty();   }
+
+  inline iterator_range<pred_iterator> predecessors() {
+    return iterator_range<pred_iterator>(pred_begin(), pred_end());
+  }
+  inline iterator_range<const_pred_iterator> predecessors() const {
+    return iterator_range<const_pred_iterator>(pred_begin(), pred_end());
+  }
+  inline iterator_range<succ_iterator> successors() {
+    return iterator_range<succ_iterator>(succ_begin(), succ_end());
+  }
+  inline iterator_range<const_succ_iterator> successors() const {
+    return iterator_range<const_succ_iterator>(succ_begin(), succ_end());
+  }
+
+  // LiveIn management methods.
+
+  /// addLiveIn - Add the specified register as a live in.  Note that it
+  /// is an error to add the same register to the same set more than once.
+  void addLiveIn(unsigned Reg)  { LiveIns.push_back(Reg); }
+
+  /// Add PhysReg as live in to this block, and ensure that there is a copy of
+  /// PhysReg to a virtual register of class RC. Return the virtual register
+  /// that is a copy of the live in PhysReg.
+  unsigned addLiveIn(unsigned PhysReg, const TargetRegisterClass *RC);
+
+  /// removeLiveIn - Remove the specified register from the live in set.
+  ///
+  void removeLiveIn(unsigned Reg);
+
+  /// isLiveIn - Return true if the specified register is in the live in set.
+  ///
+  bool isLiveIn(unsigned Reg) const;
+
+  // Iteration support for live in sets.  These sets are kept in sorted
+  // order by their register number.
+  typedef std::vector<unsigned>::const_iterator livein_iterator;
+  livein_iterator livein_begin() const { return LiveIns.begin(); }
+  livein_iterator livein_end()   const { return LiveIns.end(); }
+  bool            livein_empty() const { return LiveIns.empty(); }
+
+  /// getAlignment - Return alignment of the basic block.
+  /// The alignment is specified as log2(bytes).
+  ///
+  unsigned getAlignment() const { return Alignment; }
+
+  /// setAlignment - Set alignment of the basic block.
+  /// The alignment is specified as log2(bytes).
+  ///
+  void setAlignment(unsigned Align) { Alignment = Align; }
+
+  /// isLandingPad - Returns true if the block is a landing pad. That is
+  /// this basic block is entered via an exception handler.
+  bool isLandingPad() const { return IsLandingPad; }
+
+  /// setIsLandingPad - Indicates the block is a landing pad.  That is
+  /// this basic block is entered via an exception handler.
+  void setIsLandingPad(bool V = true) { IsLandingPad = V; }
+
+  /// getLandingPadSuccessor - If this block has a successor that is a landing
+  /// pad, return it. Otherwise return NULL.
+  const MachineBasicBlock *getLandingPadSuccessor() const;
+
+  // Code Layout methods.
+
+  /// moveBefore/moveAfter - move 'this' block before or after the specified
+  /// block.  This only moves the block, it does not modify the CFG or adjust
+  /// potential fall-throughs at the end of the block.
+  void moveBefore(MachineBasicBlock *NewAfter);
+  void moveAfter(MachineBasicBlock *NewBefore);
+
+  /// updateTerminator - Update the terminator instructions in block to account
+  /// for changes to the layout. If the block previously used a fallthrough,
+  /// it may now need a branch, and if it previously used branching it may now
+  /// be able to use a fallthrough.
+  void updateTerminator();
+
+  // Machine-CFG mutators
+
+  /// addSuccessor - Add succ as a successor of this MachineBasicBlock.
+  /// The Predecessors list of succ is automatically updated. WEIGHT
+  /// parameter is stored in Weights list and it may be used by
+  /// MachineBranchProbabilityInfo analysis to calculate branch probability.
+  ///
+  /// Note that duplicate Machine CFG edges are not allowed.
+  ///
+  void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
+
+  /// Set successor weight of a given iterator.
+  void setSuccWeight(succ_iterator I, uint32_t weight);
+
+  /// removeSuccessor - Remove successor from the successors list of this
+  /// MachineBasicBlock. The Predecessors list of succ is automatically updated.
+  ///
+  void removeSuccessor(MachineBasicBlock *succ);
+
+  /// removeSuccessor - Remove specified successor from the successors list of
+  /// this MachineBasicBlock. The Predecessors list of succ is automatically
+  /// updated.  Return the iterator to the element after the one removed.
+  ///
+  succ_iterator removeSuccessor(succ_iterator I);
+
+  /// replaceSuccessor - Replace successor OLD with NEW and update weight info.
+  ///
+  void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+
+  /// transferSuccessors - Transfers all the successors from MBB to this
+  /// machine basic block (i.e., copies all the successors fromMBB and
+  /// remove all the successors from fromMBB).
+  void transferSuccessors(MachineBasicBlock *fromMBB);
+
+  /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as
+  /// in transferSuccessors, and update PHI operands in the successor blocks
+  /// which refer to fromMBB to refer to this.
+  void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB);
+
+  /// isPredecessor - Return true if the specified MBB is a predecessor of this
+  /// block.
+  bool isPredecessor(const MachineBasicBlock *MBB) const;
+
+  /// isSuccessor - Return true if the specified MBB is a successor of this
+  /// block.
+  bool isSuccessor(const MachineBasicBlock *MBB) const;
+
+  /// isLayoutSuccessor - Return true if the specified MBB will be emitted
+  /// immediately after this block, such that if this block exits by
+  /// falling through, control will transfer to the specified MBB. Note
+  /// that MBB need not be a successor at all, for example if this block
+  /// ends with an unconditional branch to some other block.
+  bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
+
+  /// canFallThrough - Return true if the block can implicitly transfer
+  /// control to the block after it by falling off the end of it.  This should
+  /// return false if it can reach the block after it, but it uses an explicit
+  /// branch to do so (e.g., a table jump).  True is a conservative answer.
+  bool canFallThrough();
+
+  /// Returns a pointer to the first instruction in this block that is not a
+  /// PHINode instruction. When adding instructions to the beginning of the
+  /// basic block, they should be added before the returned value, not before
+  /// the first instruction, which might be PHI.
+  /// Returns end() is there's no non-PHI instruction.
+  iterator getFirstNonPHI();
+
+  /// SkipPHIsAndLabels - Return the first instruction in MBB after I that is
+  /// not a PHI or a label. This is the correct point to insert copies at the
+  /// beginning of a basic block.
+  iterator SkipPHIsAndLabels(iterator I);
+
+  /// getFirstTerminator - returns an iterator to the first terminator
+  /// instruction of this basic block. If a terminator does not exist,
+  /// it returns end()
+  iterator getFirstTerminator();
+  const_iterator getFirstTerminator() const;
+
+  /// getFirstInstrTerminator - Same getFirstTerminator but it ignores bundles
+  /// and return an instr_iterator instead.
+  instr_iterator getFirstInstrTerminator();
+
+  /// getLastNonDebugInstr - returns an iterator to the last non-debug
+  /// instruction in the basic block, or end()
+  iterator getLastNonDebugInstr();
+  const_iterator getLastNonDebugInstr() const;
+
+  /// SplitCriticalEdge - Split the critical edge from this block to the
+  /// given successor block, and return the newly created block, or null
+  /// if splitting is not possible.
+  ///
+  /// This function updates LiveVariables, MachineDominatorTree, and
+  /// MachineLoopInfo, as applicable.
+  MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P);
+
+  void pop_front() { Insts.pop_front(); }
+  void pop_back() { Insts.pop_back(); }
+  void push_back(MachineInstr *MI) { Insts.push_back(MI); }
+
+  /// Insert MI into the instruction list before I, possibly inside a bundle.
+  ///
+  /// If the insertion point is inside a bundle, MI will be added to the bundle,
+  /// otherwise MI will not be added to any bundle. That means this function
+  /// alone can't be used to prepend or append instructions to bundles. See
+  /// MIBundleBuilder::insert() for a more reliable way of doing that.
+  instr_iterator insert(instr_iterator I, MachineInstr *M);
+
+  /// Insert a range of instructions into the instruction list before I.
+  template<typename IT>
+  void insert(iterator I, IT S, IT E) {
+    Insts.insert(I.getInstrIterator(), S, E);
+  }
+
+  /// Insert MI into the instruction list before I.
+  iterator insert(iterator I, MachineInstr *MI) {
+    assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
+           "Cannot insert instruction with bundle flags");
+    return Insts.insert(I.getInstrIterator(), MI);
+  }
+
+  /// Insert MI into the instruction list after I.
+  iterator insertAfter(iterator I, MachineInstr *MI) {
+    assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
+           "Cannot insert instruction with bundle flags");
+    return Insts.insertAfter(I.getInstrIterator(), MI);
+  }
+
+  /// Remove an instruction from the instruction list and delete it.
+  ///
+  /// If the instruction is part of a bundle, the other instructions in the
+  /// bundle will still be bundled after removing the single instruction.
+  instr_iterator erase(instr_iterator I);
+
+  /// Remove an instruction from the instruction list and delete it.
+  ///
+  /// If the instruction is part of a bundle, the other instructions in the
+  /// bundle will still be bundled after removing the single instruction.
+  instr_iterator erase_instr(MachineInstr *I) {
+    return erase(instr_iterator(I));
+  }
+
+  /// Remove a range of instructions from the instruction list and delete them.
+  iterator erase(iterator I, iterator E) {
+    return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
+  }
+
+  /// Remove an instruction or bundle from the instruction list and delete it.
+  ///
+  /// If I points to a bundle of instructions, they are all erased.
+  iterator erase(iterator I) {
+    return erase(I, std::next(I));
+  }
+
+  /// Remove an instruction from the instruction list and delete it.
+  ///
+  /// If I is the head of a bundle of instructions, the whole bundle will be
+  /// erased.
+  iterator erase(MachineInstr *I) {
+    return erase(iterator(I));
+  }
+
+  /// Remove the unbundled instruction from the instruction list without
+  /// deleting it.
+  ///
+  /// This function can not be used to remove bundled instructions, use
+  /// remove_instr to remove individual instructions from a bundle.
+  MachineInstr *remove(MachineInstr *I) {
+    assert(!I->isBundled() && "Cannot remove bundled instructions");
+    return Insts.remove(I);
+  }
+
+  /// Remove the possibly bundled instruction from the instruction list
+  /// without deleting it.
+  ///
+  /// If the instruction is part of a bundle, the other instructions in the
+  /// bundle will still be bundled after removing the single instruction.
+  MachineInstr *remove_instr(MachineInstr *I);
+
+  void clear() {
+    Insts.clear();
+  }
+
+  /// Take an instruction from MBB 'Other' at the position From, and insert it
+  /// into this MBB right before 'Where'.
+  ///
+  /// If From points to a bundle of instructions, the whole bundle is moved.
+  void splice(iterator Where, MachineBasicBlock *Other, iterator From) {
+    // The range splice() doesn't allow noop moves, but this one does.
+    if (Where != From)
+      splice(Where, Other, From, std::next(From));
+  }
+
+  /// Take a block of instructions from MBB 'Other' in the range [From, To),
+  /// and insert them into this MBB right before 'Where'.
+  ///
+  /// The instruction at 'Where' must not be included in the range of
+  /// instructions to move.
+  void splice(iterator Where, MachineBasicBlock *Other,
+              iterator From, iterator To) {
+    Insts.splice(Where.getInstrIterator(), Other->Insts,
+                 From.getInstrIterator(), To.getInstrIterator());
+  }
+
+  /// removeFromParent - This method unlinks 'this' from the containing
+  /// function, and returns it, but does not delete it.
+  MachineBasicBlock *removeFromParent();
+
+  /// eraseFromParent - This method unlinks 'this' from the containing
+  /// function and deletes it.
+  void eraseFromParent();
+
+  /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to
+  /// 'Old', change the code and CFG so that it branches to 'New' instead.
+  void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+  /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in
+  /// the CFG to be inserted.  If we have proven that MBB can only branch to
+  /// DestA and DestB, remove any other MBB successors from the CFG. DestA and
+  /// DestB can be null. Besides DestA and DestB, retain other edges leading
+  /// to LandingPads (currently there can be only one; we don't check or require
+  /// that here). Note it is possible that DestA and/or DestB are LandingPads.
+  bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
+                            MachineBasicBlock *DestB,
+                            bool isCond);
+
+  /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
+  /// any DBG_VALUE instructions.  Return UnknownLoc if there is none.
+  DebugLoc findDebugLoc(instr_iterator MBBI);
+  DebugLoc findDebugLoc(iterator MBBI) {
+    return findDebugLoc(MBBI.getInstrIterator());
+  }
+
+  /// Possible outcome of a register liveness query to computeRegisterLiveness()
+  enum LivenessQueryResult {
+    LQR_Live,            ///< Register is known to be live.
+    LQR_OverlappingLive, ///< Register itself is not live, but some overlapping
+                         ///< register is.
+    LQR_Dead,            ///< Register is known to be dead.
+    LQR_Unknown          ///< Register liveness not decidable from local
+                         ///< neighborhood.
+  };
+
+  /// computeRegisterLiveness - Return whether (physical) register \c Reg
+  /// has been <def>ined and not <kill>ed as of just before \c MI.
+  ///
+  /// Search is localised to a neighborhood of
+  /// \c Neighborhood instructions before (searching for defs or kills) and
+  /// Neighborhood instructions after (searching just for defs) MI.
+  ///
+  /// \c Reg must be a physical register.
+  LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
+                                              unsigned Reg, MachineInstr *MI,
+                                              unsigned Neighborhood=10);
+
+  // Debugging methods.
+  void dump() const;
+  void print(raw_ostream &OS, SlotIndexes* = nullptr) const;
+
+  // Printing method used by LoopInfo.
+  void printAsOperand(raw_ostream &OS, bool PrintType = true) const;
+
+  /// getNumber - MachineBasicBlocks are uniquely numbered at the function
+  /// level, unless they're not in a MachineFunction yet, in which case this
+  /// will return -1.
+  ///
+  int getNumber() const { return Number; }
+  void setNumber(int N) { Number = N; }
+
+  /// getSymbol - Return the MCSymbol for this basic block.
+  ///
+  MCSymbol *getSymbol() const;
+
+
+private:
+  /// getWeightIterator - Return weight iterator corresponding to the I
+  /// successor iterator.
+  weight_iterator getWeightIterator(succ_iterator I);
+  const_weight_iterator getWeightIterator(const_succ_iterator I) const;
+
+  friend class MachineBranchProbabilityInfo;
+
+  /// getSuccWeight - Return weight of the edge from this block to MBB. This
+  /// method should NOT be called directly, but by using getEdgeWeight method
+  /// from MachineBranchProbabilityInfo class.
+  uint32_t getSuccWeight(const_succ_iterator Succ) const;
+
+
+  // Methods used to maintain doubly linked list of blocks...
+  friend struct ilist_traits<MachineBasicBlock>;
+
+  // Machine-CFG mutators
+
+  /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock.
+  /// Don't do this unless you know what you're doing, because it doesn't
+  /// update pred's successors list. Use pred->addSuccessor instead.
+  ///
+  void addPredecessor(MachineBasicBlock *pred);
+
+  /// removePredecessor - Remove pred as a predecessor of this
+  /// MachineBasicBlock. Don't do this unless you know what you're
+  /// doing, because it doesn't update pred's successors list. Use
+  /// pred->removeSuccessor instead.
+  ///
+  void removePredecessor(MachineBasicBlock *pred);
+};
+
+raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
+
+// This is useful when building IndexedMaps keyed on basic block pointers.
+struct MBB2NumberFunctor :
+  public std::unary_function<const MachineBasicBlock*, unsigned> {
+  unsigned operator()(const MachineBasicBlock *MBB) const {
+    return MBB->getNumber();
+  }
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for machine basic block graphs (machine-CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks...
+//
+
+template <> struct GraphTraits<MachineBasicBlock *> {
+  typedef MachineBasicBlock NodeType;
+  typedef MachineBasicBlock::succ_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->succ_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->succ_end();
+  }
+};
+
+template <> struct GraphTraits<const MachineBasicBlock *> {
+  typedef const MachineBasicBlock NodeType;
+  typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->succ_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->succ_end();
+  }
+};
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks... and to walk it
+// in inverse order.  Inverse order for a function is considered
+// to be when traversing the predecessor edges of a MBB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
+  typedef MachineBasicBlock NodeType;
+  typedef MachineBasicBlock::pred_iterator ChildIteratorType;
+  static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) {
+    return G.Graph;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->pred_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->pred_end();
+  }
+};
+
+template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
+  typedef const MachineBasicBlock NodeType;
+  typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
+  static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) {
+    return G.Graph;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->pred_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->pred_end();
+  }
+};
+
+
+
+/// MachineInstrSpan provides an interface to get an iteration range
+/// containing the instruction it was initialized with, along with all
+/// those instructions inserted prior to or following that instruction
+/// at some point after the MachineInstrSpan is constructed.
+class MachineInstrSpan {
+  MachineBasicBlock &MBB;
+  MachineBasicBlock::iterator I, B, E;
+public:
+  MachineInstrSpan(MachineBasicBlock::iterator I)
+    : MBB(*I->getParent()),
+      I(I),
+      B(I == MBB.begin() ? MBB.end() : std::prev(I)),
+      E(std::next(I)) {}
+
+  MachineBasicBlock::iterator begin() {
+    return B == MBB.end() ? MBB.begin() : std::next(B);
+  }
+  MachineBasicBlock::iterator end() { return E; }
+  bool empty() { return begin() == end(); }
+
+  MachineBasicBlock::iterator getInitial() { return I; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
new file mode 100644
index 0000000..1aef689
--- /dev/null
+++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -0,0 +1,71 @@
+//===- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -*- C++ -*-----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Loops should be simplified before this analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
+#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/BlockFrequency.h"
+#include <climits>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineBranchProbabilityInfo;
+template <class BlockT> class BlockFrequencyInfoImpl;
+
+/// MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation
+/// to estimate machine basic block frequencies.
+class MachineBlockFrequencyInfo : public MachineFunctionPass {
+  typedef BlockFrequencyInfoImpl<MachineBasicBlock> ImplType;
+  std::unique_ptr<ImplType> MBFI;
+
+public:
+  static char ID;
+
+  MachineBlockFrequencyInfo();
+
+  ~MachineBlockFrequencyInfo();
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  bool runOnMachineFunction(MachineFunction &F) override;
+
+  void releaseMemory() override;
+
+  /// getblockFreq - Return block frequency. Return 0 if we don't have the
+  /// information. Please note that initial frequency is equal to 1024. It means
+  /// that we should not rely on the value itself, but only on the comparison to
+  /// the other block frequencies. We do this to avoid using of floating points.
+  ///
+  BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
+
+  const MachineFunction *getFunction() const;
+  void view() const;
+
+  // Print the block frequency Freq to OS using the current functions entry
+  // frequency to convert freq into a relative decimal form.
+  raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;
+
+  // Convenience method that attempts to look up the frequency associated with
+  // BB and print it to OS.
+  raw_ostream &printBlockFreq(raw_ostream &OS,
+                              const MachineBasicBlock *MBB) const;
+
+  uint64_t getEntryFreq() const;
+
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
new file mode 100644
index 0000000..7ba7495
--- /dev/null
+++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -0,0 +1,90 @@
+//=- MachineBranchProbabilityInfo.h - Branch Probability Analysis -*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to evaluate branch probabilties on machine basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
+#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/BranchProbability.h"
+#include <climits>
+
+namespace llvm {
+
+class MachineBranchProbabilityInfo : public ImmutablePass {
+  virtual void anchor();
+
+  // Default weight value. Used when we don't have information about the edge.
+  // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
+  // the successors have a weight yet. But it doesn't make sense when providing
+  // weight to an edge that may have siblings with non-zero weights. This can
+  // be handled various ways, but it's probably fine for an edge with unknown
+  // weight to just "inherit" the non-zero weight of an adjacent successor.
+  static const uint32_t DEFAULT_WEIGHT = 16;
+
+public:
+  static char ID;
+
+  MachineBranchProbabilityInfo() : ImmutablePass(ID) {
+    PassRegistry &Registry = *PassRegistry::getPassRegistry();
+    initializeMachineBranchProbabilityInfoPass(Registry);
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  // Return edge weight. If we don't have any informations about it - return
+  // DEFAULT_WEIGHT.
+  uint32_t getEdgeWeight(const MachineBasicBlock *Src,
+                         const MachineBasicBlock *Dst) const;
+
+  // Same thing, but using a const_succ_iterator from Src. This is faster when
+  // the iterator is already available.
+  uint32_t getEdgeWeight(const MachineBasicBlock *Src,
+                         MachineBasicBlock::const_succ_iterator Dst) const;
+
+  // Get sum of the block successors' weights, potentially scaling them to fit
+  // within 32-bits. If scaling is required, sets Scale based on the necessary
+  // adjustment. Any edge weights used with the sum should be divided by Scale.
+  uint32_t getSumForBlock(const MachineBasicBlock *MBB, uint32_t &Scale) const;
+
+  // A 'Hot' edge is an edge which probability is >= 80%.
+  bool isEdgeHot(const MachineBasicBlock *Src,
+                 const MachineBasicBlock *Dst) const;
+
+  // Return a hot successor for the block BB or null if there isn't one.
+  // NB: This routine's complexity is linear on the number of successors.
+  MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
+
+  // Return a probability as a fraction between 0 (0% probability) and
+  // 1 (100% probability), however the value is never equal to 0, and can be 1
+  // only iff SRC block has only one successor.
+  // NB: This routine's complexity is linear on the number of successors of
+  // Src. Querying sequentially for each successor's probability is a quadratic
+  // query pattern.
+  BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
+                                       const MachineBasicBlock *Dst) const;
+
+  // Print value between 0 (0% probability) and 1 (100% probability),
+  // however the value is never equal to 0, and can be 1 only iff SRC block
+  // has only one successor.
+  raw_ostream &printEdgeProbability(raw_ostream &OS,
+                                    const MachineBasicBlock *Src,
+                                    const MachineBasicBlock *Dst) const;
+};
+
+}
+
+
+#endif
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
new file mode 100644
index 0000000..81b0ba1
--- /dev/null
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -0,0 +1,334 @@
+//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- 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 an abstract interface that is used by the machine code
+// emission framework to output the code.  This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
+#define LLVM_CODEGEN_MACHINECODEEMITTER_H
+
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+class MCSymbol;
+
+/// MachineCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxiliary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it.  As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer.  As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit.  In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores.  Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+/// 
+class MachineCodeEmitter {
+  virtual void anchor();
+protected:
+  /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+  /// allocated for this code buffer.
+  uint8_t *BufferBegin, *BufferEnd;
+  /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+  /// code.  This is guaranteed to be in the range [BufferBegin,BufferEnd].  If
+  /// this pointer is at BufferEnd, it will never move due to code emission, and
+  /// all code emission requests will be ignored (this is the buffer overflow
+  /// condition).
+  uint8_t *CurBufferPtr;
+
+public:
+  virtual ~MachineCodeEmitter() {}
+
+  /// startFunction - This callback is invoked when the specified function is
+  /// about to be code generated.  This initializes the BufferBegin/End/Ptr
+  /// fields.
+  ///
+  virtual void startFunction(MachineFunction &F) = 0;
+
+  /// finishFunction - This callback is invoked when the specified function has
+  /// finished code generation.  If a buffer overflow has occurred, this method
+  /// returns true (the callee is required to try again), otherwise it returns
+  /// false.
+  ///
+  virtual bool finishFunction(MachineFunction &F) = 0;
+
+  /// emitByte - This callback is invoked when a byte needs to be written to the
+  /// output stream.
+  ///
+  void emitByte(uint8_t B) {
+    if (CurBufferPtr != BufferEnd)
+      *CurBufferPtr++ = B;
+  }
+
+  /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+  /// written to the output stream in little-endian format.
+  ///
+  void emitWordLE(uint32_t W) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      emitWordLEInto(CurBufferPtr, W);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
+  /// written to an arbitrary buffer in little-endian format.  Buf must have at
+  /// least 4 bytes of available space.
+  ///
+  static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
+    *Buf++ = (uint8_t)(W >>  0);
+    *Buf++ = (uint8_t)(W >>  8);
+    *Buf++ = (uint8_t)(W >> 16);
+    *Buf++ = (uint8_t)(W >> 24);
+  }
+
+  /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+  /// written to the output stream in big-endian format.
+  ///
+  void emitWordBE(uint32_t W) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in little-endian format.
+  ///
+  void emitDWordLE(uint64_t W) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 32);
+      *CurBufferPtr++ = (uint8_t)(W >> 40);
+      *CurBufferPtr++ = (uint8_t)(W >> 48);
+      *CurBufferPtr++ = (uint8_t)(W >> 56);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in big-endian format.
+  ///
+  void emitDWordBE(uint64_t W) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *CurBufferPtr++ = (uint8_t)(W >> 56);
+      *CurBufferPtr++ = (uint8_t)(W >> 48);
+      *CurBufferPtr++ = (uint8_t)(W >> 40);
+      *CurBufferPtr++ = (uint8_t)(W >> 32);
+      *CurBufferPtr++ = (uint8_t)(W >> 24);
+      *CurBufferPtr++ = (uint8_t)(W >> 16);
+      *CurBufferPtr++ = (uint8_t)(W >>  8);
+      *CurBufferPtr++ = (uint8_t)(W >>  0);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitAlignment - Move the CurBufferPtr pointer up to the specified
+  /// alignment (saturated to BufferEnd of course).
+  void emitAlignment(unsigned Alignment) {
+    if (Alignment == 0) Alignment = 1;
+
+    if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+      // Move the current buffer ptr up to the specified alignment.
+      CurBufferPtr =
+        (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) &
+                   ~(uintptr_t)(Alignment-1));
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+
+  /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+  /// written to the output stream.
+  void emitULEB128Bytes(uint64_t Value) {
+    do {
+      uint8_t Byte = Value & 0x7f;
+      Value >>= 7;
+      if (Value) Byte |= 0x80;
+      emitByte(Byte);
+    } while (Value);
+  }
+  
+  /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+  /// written to the output stream.
+  void emitSLEB128Bytes(uint64_t Value) {
+    uint64_t Sign = Value >> (8 * sizeof(Value) - 1);
+    bool IsMore;
+  
+    do {
+      uint8_t Byte = Value & 0x7f;
+      Value >>= 7;
+      IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+      if (IsMore) Byte |= 0x80;
+      emitByte(Byte);
+    } while (IsMore);
+  }
+
+  /// emitString - This callback is invoked when a String needs to be
+  /// written to the output stream.
+  void emitString(const std::string &String) {
+    for (unsigned i = 0, N = static_cast<unsigned>(String.size());
+         i < N; ++i) {
+      uint8_t C = String[i];
+      emitByte(C);
+    }
+    emitByte(0);
+  }
+  
+  /// emitInt32 - Emit a int32 directive.
+  void emitInt32(int32_t Value) {
+    if (4 <= BufferEnd-CurBufferPtr) {
+      *((uint32_t*)CurBufferPtr) = Value;
+      CurBufferPtr += 4;
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
+  /// emitInt64 - Emit a int64 directive.
+  void emitInt64(uint64_t Value) {
+    if (8 <= BufferEnd-CurBufferPtr) {
+      *((uint64_t*)CurBufferPtr) = Value;
+      CurBufferPtr += 8;
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitInt32At - Emit the Int32 Value in Addr.
+  void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
+    if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+      (*(uint32_t*)Addr) = (uint32_t)Value;
+  }
+  
+  /// emitInt64At - Emit the Int64 Value in Addr.
+  void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
+    if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+      (*(uint64_t*)Addr) = (uint64_t)Value;
+  }
+  
+  /// processDebugLoc - Records debug location information about a
+  /// MachineInstruction.  This is called before emitting any bytes associated
+  /// with the instruction.  Even if successive instructions have the same debug
+  /// location, this method will be called for each one.
+  virtual void processDebugLoc(DebugLoc DL, bool BeforePrintintInsn) {}
+
+  /// emitLabel - Emits a label
+  virtual void emitLabel(MCSymbol *Label) = 0;
+
+  /// allocateSpace - Allocate a block of space in the current output buffer,
+  /// returning null (and setting conditions to indicate buffer overflow) on
+  /// failure.  Alignment is the alignment in bytes of the buffer desired.
+  virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) {
+    emitAlignment(Alignment);
+    void *Result;
+    
+    // Check for buffer overflow.
+    if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+      CurBufferPtr = BufferEnd;
+      Result = nullptr;
+    } else {
+      // Allocate the space.
+      Result = CurBufferPtr;
+      CurBufferPtr += Size;
+    }
+    
+    return Result;
+  }
+
+  /// StartMachineBasicBlock - This should be called by the target when a new
+  /// basic block is about to be emitted.  This way the MCE knows where the
+  /// start of the block is, and can implement getMachineBasicBlockAddress.
+  virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
+  
+  /// getCurrentPCValue - This returns the address that the next emitted byte
+  /// will be output to.
+  ///
+  virtual uintptr_t getCurrentPCValue() const {
+    return (uintptr_t)CurBufferPtr;
+  }
+
+  /// getCurrentPCOffset - Return the offset from the start of the emitted
+  /// buffer that we are currently writing to.
+  virtual uintptr_t getCurrentPCOffset() const {
+    return CurBufferPtr-BufferBegin;
+  }
+
+  /// earlyResolveAddresses - True if the code emitter can use symbol addresses 
+  /// during code emission time. The JIT is capable of doing this because it
+  /// creates jump tables or constant pools in memory on the fly while the
+  /// object code emitters rely on a linker to have real addresses and should
+  /// use relocations instead.
+  virtual bool earlyResolveAddresses() const = 0;
+
+  /// addRelocation - Whenever a relocatable address is needed, it should be
+  /// noted with this interface.
+  virtual void addRelocation(const MachineRelocation &MR) = 0;
+  
+  /// FIXME: These should all be handled with relocations!
+  
+  /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+  /// the constant pool that was last emitted with the emitConstantPool method.
+  ///
+  virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
+
+  /// getJumpTableEntryAddress - Return the address of the jump table with index
+  /// 'Index' in the function that last called initJumpTableInfo.
+  ///
+  virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
+  
+  /// getMachineBasicBlockAddress - Return the address of the specified
+  /// MachineBasicBlock, only usable after the label for the MBB has been
+  /// emitted.
+  ///
+  virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+
+  /// getLabelAddress - Return the address of the specified Label, only usable
+  /// after the LabelID has been emitted.
+  ///
+  virtual uintptr_t getLabelAddress(MCSymbol *Label) const = 0;
+  
+  /// Specifies the MachineModuleInfo object. This is used for exception handling
+  /// purposes.
+  virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineCodeInfo.h b/include/llvm/CodeGen/MachineCodeInfo.h
new file mode 100644
index 0000000..820bc87
--- /dev/null
+++ b/include/llvm/CodeGen/MachineCodeInfo.h
@@ -0,0 +1,53 @@
+//===-- MachineCodeInfo.h - Class used to report JIT 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 MachineCodeInfo, a class used by the JIT ExecutionEngine
+// to report information about the generated machine code.
+//
+// See JIT::runJITOnFunction for usage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECODEINFO_H
+#define LLVM_CODEGEN_MACHINECODEINFO_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MachineCodeInfo {
+private:
+  size_t Size;   // Number of bytes in memory used
+  void *Address; // The address of the function in memory
+
+public:
+  MachineCodeInfo() : Size(0), Address(nullptr) {}
+
+  void setSize(size_t s) {
+    Size = s;
+  }
+
+  void setAddress(void *a) {
+    Address = a;
+  }
+
+  size_t size() const {
+    return Size;
+  }
+
+  void *address() const {
+    return Address;
+  }
+
+};
+
+}
+
+#endif
+
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
new file mode 100644
index 0000000..c619afb
--- /dev/null
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -0,0 +1,179 @@
+//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file declares the MachineConstantPool class which is an abstract
+/// constant pool to keep track of constants referenced by a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/MC/SectionKind.h"
+#include <cassert>
+#include <climits>
+#include <vector>
+
+namespace llvm {
+
+class Constant;
+class FoldingSetNodeID;
+class DataLayout;
+class TargetMachine;
+class Type;
+class MachineConstantPool;
+class raw_ostream;
+
+/// Abstract base class for all machine specific constantpool value subclasses.
+///
+class MachineConstantPoolValue {
+  virtual void anchor();
+  Type *Ty;
+
+public:
+  explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {}
+  virtual ~MachineConstantPoolValue() {}
+
+  /// getType - get type of this MachineConstantPoolValue.
+  ///
+  Type *getType() const { return Ty; }
+
+  
+  /// getRelocationInfo - This method classifies the entry according to
+  /// whether or not it may generate a relocation entry.  This must be
+  /// conservative, so if it might codegen to a relocatable entry, it should say
+  /// so.  The return values are the same as Constant::getRelocationInfo().
+  virtual unsigned getRelocationInfo() const = 0;
+  
+  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
+                                        unsigned Alignment) = 0;
+
+  virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
+
+  /// print - Implement operator<<
+  virtual void print(raw_ostream &O) const = 0;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+                               const MachineConstantPoolValue &V) {
+  V.print(OS);
+  return OS;
+}
+  
+
+/// This class is a data container for one entry in a MachineConstantPool.
+/// It contains a pointer to the value and an offset from the start of
+/// the constant pool.
+/// @brief An entry in a MachineConstantPool
+class MachineConstantPoolEntry {
+public:
+  /// The constant itself.
+  union {
+    const Constant *ConstVal;
+    MachineConstantPoolValue *MachineCPVal;
+  } Val;
+
+  /// The required alignment for this entry. The top bit is set when Val is
+  /// a target specific MachineConstantPoolValue.
+  unsigned Alignment;
+
+  MachineConstantPoolEntry(const Constant *V, unsigned A)
+    : Alignment(A) {
+    Val.ConstVal = V;
+  }
+  MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned A)
+    : Alignment(A) {
+    Val.MachineCPVal = V; 
+    Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1);
+  }
+
+  /// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry
+  /// is indeed a target specific constantpool entry, not a wrapper over a
+  /// Constant.
+  bool isMachineConstantPoolEntry() const {
+    return (int)Alignment < 0;
+  }
+
+  int getAlignment() const { 
+    return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
+  }
+
+  Type *getType() const;
+  
+  /// getRelocationInfo - This method classifies the entry according to
+  /// whether or not it may generate a relocation entry.  This must be
+  /// conservative, so if it might codegen to a relocatable entry, it should say
+  /// so.  The return values are:
+  /// 
+  ///  0: This constant pool entry is guaranteed to never have a relocation
+  ///     applied to it (because it holds a simple constant like '4').
+  ///  1: This entry has relocations, but the entries are guaranteed to be
+  ///     resolvable by the static linker, so the dynamic linker will never see
+  ///     them.
+  ///  2: This entry may have arbitrary relocations. 
+  unsigned getRelocationInfo() const;
+
+  SectionKind getSectionKind(const DataLayout *DL) const;
+};
+  
+/// The MachineConstantPool class keeps track of constants referenced by a
+/// function which must be spilled to memory.  This is used for constants which
+/// are unable to be used directly as operands to instructions, which typically
+/// include floating point and large integer constants.
+///
+/// Instructions reference the address of these constant pool constants through
+/// the use of MO_ConstantPoolIndex values.  When emitting assembly or machine
+/// code, these virtual address references are converted to refer to the
+/// address of the function constant pool values.
+/// @brief The machine constant pool.
+class MachineConstantPool {
+  const TargetMachine &TM;      ///< The target machine.
+  unsigned PoolAlignment;       ///< The alignment for the pool.
+  std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
+  /// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
+  DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
+
+  const DataLayout *getDataLayout() const;
+public:
+  /// @brief The only constructor.
+  explicit MachineConstantPool(const TargetMachine &TM)
+    : TM(TM), PoolAlignment(1) {}
+  ~MachineConstantPool();
+    
+  /// getConstantPoolAlignment - Return the alignment required by
+  /// the whole constant pool, of which the first element must be aligned.
+  unsigned getConstantPoolAlignment() const { return PoolAlignment; }
+  
+  /// getConstantPoolIndex - Create a new entry in the constant pool or return
+  /// an existing one.  User must specify the minimum required alignment for
+  /// the object.
+  unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment);
+  unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
+  
+  /// isEmpty - Return true if this constant pool contains no constants.
+  bool isEmpty() const { return Constants.empty(); }
+
+  const std::vector<MachineConstantPoolEntry> &getConstants() const {
+    return Constants;
+  }
+
+  /// print - Used by the MachineFunction printer to print information about
+  /// constant pool objects.  Implemented in MachineFunction.cpp
+  ///
+  void print(raw_ostream &OS) const;
+
+  /// dump - Call print(cerr) to be called from the debugger.
+  void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineDominanceFrontier.h b/include/llvm/CodeGen/MachineDominanceFrontier.h
new file mode 100644
index 0000000..e099e71
--- /dev/null
+++ b/include/llvm/CodeGen/MachineDominanceFrontier.h
@@ -0,0 +1,109 @@
+//===- llvm/CodeGen/MachineDominanceFrontier.h ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
+#define LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
+
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+
+namespace llvm {
+
+class MachineDominanceFrontier : public MachineFunctionPass {
+  ForwardDominanceFrontierBase<MachineBasicBlock> Base;
+public:
+  typedef DominatorTreeBase<MachineBasicBlock> DomTreeT;
+  typedef DomTreeNodeBase<MachineBasicBlock> DomTreeNodeT;
+  typedef DominanceFrontierBase<MachineBasicBlock>::DomSetType DomSetType;
+  typedef DominanceFrontierBase<MachineBasicBlock>::iterator iterator;
+  typedef DominanceFrontierBase<MachineBasicBlock>::const_iterator const_iterator;
+
+  void operator=(const MachineDominanceFrontier &) LLVM_DELETED_FUNCTION;
+  MachineDominanceFrontier(const MachineDominanceFrontier &) LLVM_DELETED_FUNCTION;
+
+  static char ID;
+
+  MachineDominanceFrontier();
+
+  DominanceFrontierBase<MachineBasicBlock> &getBase() {
+    return Base;
+  }
+
+  inline const std::vector<MachineBasicBlock*> &getRoots() const {
+    return Base.getRoots();
+  }
+
+  MachineBasicBlock *getRoot() const {
+    return Base.getRoot();
+  }
+
+  bool isPostDominator() const {
+    return Base.isPostDominator();
+  }
+
+  iterator begin() {
+    return Base.begin();
+  }
+
+  const_iterator begin() const {
+    return Base.begin();
+  }
+
+  iterator end() {
+    return Base.end();
+  }
+
+  const_iterator end() const {
+    return Base.end();
+  }
+
+  iterator find(MachineBasicBlock *B) {
+    return Base.find(B);
+  }
+
+  const_iterator find(MachineBasicBlock *B) const {
+    return Base.find(B);
+  }
+
+  iterator addBasicBlock(MachineBasicBlock *BB, const DomSetType &frontier) {
+    return Base.addBasicBlock(BB, frontier);
+  }
+
+  void removeBlock(MachineBasicBlock *BB) {
+    return Base.removeBlock(BB);
+  }
+
+  void addToFrontier(iterator I, MachineBasicBlock *Node) {
+    return Base.addToFrontier(I, Node);
+  }
+
+  void removeFromFrontier(iterator I, MachineBasicBlock *Node) {
+    return Base.removeFromFrontier(I, Node);
+  }
+
+  bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
+    return Base.compareDomSet(DS1, DS2);
+  }
+
+  bool compare(DominanceFrontierBase<MachineBasicBlock> &Other) const {
+    return Base.compare(Other);
+  }
+
+  bool runOnMachineFunction(MachineFunction &F) override;
+
+  void releaseMemory() override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
new file mode 100644
index 0000000..f1ae0bf
--- /dev/null
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -0,0 +1,205 @@
+//=- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation --*- 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 classes mirroring those in llvm/Analysis/Dominators.h,
+// but for target-specific code rather than target-independent IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
+#define LLVM_CODEGEN_MACHINEDOMINATORS_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+
+namespace llvm {
+
+template<>
+inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB) {
+  this->Roots.push_back(MBB);
+}
+
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>);
+
+typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
+
+//===-------------------------------------
+/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
+/// compute a normal dominator tree.
+///
+class MachineDominatorTree : public MachineFunctionPass {
+public:
+  static char ID; // Pass ID, replacement for typeid
+  DominatorTreeBase<MachineBasicBlock>* DT;
+
+  MachineDominatorTree();
+
+  ~MachineDominatorTree();
+
+  DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// getRoots -  Return the root blocks of the current CFG.  This may include
+  /// multiple blocks if we are computing post dominators.  For forward
+  /// dominators, this will always be a single block (the entry node).
+  ///
+  inline const std::vector<MachineBasicBlock*> &getRoots() const {
+    return DT->getRoots();
+  }
+
+  inline MachineBasicBlock *getRoot() const {
+    return DT->getRoot();
+  }
+
+  inline MachineDomTreeNode *getRootNode() const {
+    return DT->getRootNode();
+  }
+
+  bool runOnMachineFunction(MachineFunction &F) override;
+
+  inline bool dominates(const MachineDomTreeNode* A,
+                        const MachineDomTreeNode* B) const {
+    return DT->dominates(A, B);
+  }
+
+  inline bool dominates(const MachineBasicBlock* A,
+                        const MachineBasicBlock* B) const {
+    return DT->dominates(A, B);
+  }
+
+  // dominates - Return true if A dominates B. This performs the
+  // special checks necessary if A and B are in the same basic block.
+  bool dominates(const MachineInstr *A, const MachineInstr *B) const {
+    const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
+    if (BBA != BBB) return DT->dominates(BBA, BBB);
+
+    // Loop through the basic block until we find A or B.
+    MachineBasicBlock::const_iterator I = BBA->begin();
+    for (; &*I != A && &*I != B; ++I)
+      /*empty*/ ;
+
+    //if(!DT.IsPostDominators) {
+      // A dominates B if it is found first in the basic block.
+      return &*I == A;
+    //} else {
+    //  // A post-dominates B if B is found first in the basic block.
+    //  return &*I == B;
+    //}
+  }
+
+  inline bool properlyDominates(const MachineDomTreeNode* A,
+                                const MachineDomTreeNode* B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  inline bool properlyDominates(const MachineBasicBlock* A,
+                                const MachineBasicBlock* B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  /// findNearestCommonDominator - Find nearest common dominator basic block
+  /// for basic block A and B. If there is no such block then return NULL.
+  inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
+                                                       MachineBasicBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  /// getNode - return the (Post)DominatorTree node for the specified basic
+  /// block.  This is the same as using operator[] on this class.
+  ///
+  inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  /// addNewBlock - Add a new node to the dominator tree information.  This
+  /// creates a new node as a child of DomBB dominator node,linking it into
+  /// the children list of the immediate dominator.
+  inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
+                                         MachineBasicBlock *DomBB) {
+    return DT->addNewBlock(BB, DomBB);
+  }
+
+  /// changeImmediateDominator - This method is used to update the dominator
+  /// tree information when a node's immediate dominator changes.
+  ///
+  inline void changeImmediateDominator(MachineBasicBlock *N,
+                                       MachineBasicBlock* NewIDom) {
+    DT->changeImmediateDominator(N, NewIDom);
+  }
+
+  inline void changeImmediateDominator(MachineDomTreeNode *N,
+                                       MachineDomTreeNode* NewIDom) {
+    DT->changeImmediateDominator(N, NewIDom);
+  }
+
+  /// eraseNode - Removes a node from  the dominator tree. Block must not
+  /// dominate any other blocks. Removes node from its immediate dominator's
+  /// children list. Deletes dominator node associated with basic block BB.
+  inline void eraseNode(MachineBasicBlock *BB) {
+    DT->eraseNode(BB);
+  }
+
+  /// splitBlock - BB is split and now it has one successor. Update dominator
+  /// tree to reflect this change.
+  inline void splitBlock(MachineBasicBlock* NewBB) {
+    DT->splitBlock(NewBB);
+  }
+
+  /// isReachableFromEntry - Return true if A is dominated by the entry
+  /// block of the function containing it.
+  bool isReachableFromEntry(const MachineBasicBlock *A) {
+    return DT->isReachableFromEntry(A);
+  }
+
+  void releaseMemory() override;
+
+  void print(raw_ostream &OS, const Module*) const override;
+};
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+
+template<class T> struct GraphTraits;
+
+template <> struct GraphTraits<MachineDomTreeNode *> {
+  typedef MachineDomTreeNode NodeType;
+  typedef NodeType::iterator  ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) {
+    return N;
+  }
+  static inline ChildIteratorType child_begin(NodeType* N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType* N) {
+    return N->end();
+  }
+};
+
+template <> struct GraphTraits<MachineDominatorTree*>
+  : public GraphTraits<MachineDomTreeNode *> {
+  static NodeType *getEntryNode(MachineDominatorTree *DT) {
+    return DT->getRootNode();
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
new file mode 100644
index 0000000..c51f8fe
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -0,0 +1,586 @@
+//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The file defines the MachineFrameInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
+#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+class raw_ostream;
+class DataLayout;
+class TargetRegisterClass;
+class Type;
+class MachineFunction;
+class MachineBasicBlock;
+class TargetFrameLowering;
+class TargetMachine;
+class BitVector;
+class Value;
+class AllocaInst;
+
+/// The CalleeSavedInfo class tracks the information need to locate where a
+/// callee saved register is in the current frame.
+class CalleeSavedInfo {
+  unsigned Reg;
+  int FrameIdx;
+
+public:
+  explicit CalleeSavedInfo(unsigned R, int FI = 0)
+  : Reg(R), FrameIdx(FI) {}
+
+  // Accessors.
+  unsigned getReg()                        const { return Reg; }
+  int getFrameIdx()                        const { return FrameIdx; }
+  void setFrameIdx(int FI)                       { FrameIdx = FI; }
+};
+
+/// The MachineFrameInfo class represents an abstract stack frame until
+/// prolog/epilog code is inserted.  This class is key to allowing stack frame
+/// representation optimizations, such as frame pointer elimination.  It also
+/// allows more mundane (but still important) optimizations, such as reordering
+/// of abstract objects on the stack frame.
+///
+/// To support this, the class assigns unique integer identifiers to stack
+/// objects requested clients.  These identifiers are negative integers for
+/// fixed stack objects (such as arguments passed on the stack) or nonnegative
+/// for objects that may be reordered.  Instructions which refer to stack
+/// objects use a special MO_FrameIndex operand to represent these frame
+/// indexes.
+///
+/// Because this class keeps track of all references to the stack frame, it
+/// knows when a variable sized object is allocated on the stack.  This is the
+/// sole condition which prevents frame pointer elimination, which is an
+/// important optimization on register-poor architectures.  Because original
+/// variable sized alloca's in the source program are the only source of
+/// variable sized stack objects, it is safe to decide whether there will be
+/// any variable sized objects before all stack objects are known (for
+/// example, register allocator spill code never needs variable sized
+/// objects).
+///
+/// When prolog/epilog code emission is performed, the final stack frame is
+/// built and the machine instructions are modified to refer to the actual
+/// stack offsets of the object, eliminating all MO_FrameIndex operands from
+/// the program.
+///
+/// @brief Abstract Stack Frame Information
+class MachineFrameInfo {
+
+  // StackObject - Represent a single object allocated on the stack.
+  struct StackObject {
+    // SPOffset - The offset of this object from the stack pointer on entry to
+    // the function.  This field has no meaning for a variable sized element.
+    int64_t SPOffset;
+
+    // The size of this object on the stack. 0 means a variable sized object,
+    // ~0ULL means a dead object.
+    uint64_t Size;
+
+    // Alignment - The required alignment of this stack slot.
+    unsigned Alignment;
+
+    // isImmutable - If true, the value of the stack object is set before
+    // entering the function and is not modified inside the function. By
+    // default, fixed objects are immutable unless marked otherwise.
+    bool isImmutable;
+
+    // isSpillSlot - If true the stack object is used as spill slot. It
+    // cannot alias any other memory objects.
+    bool isSpillSlot;
+
+    /// Alloca - If this stack object is originated from an Alloca instruction
+    /// this value saves the original IR allocation. Can be NULL.
+    const AllocaInst *Alloca;
+
+    // PreAllocated - If true, the object was mapped into the local frame
+    // block and doesn't need additional handling for allocation beyond that.
+    bool PreAllocated;
+
+    StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
+                bool isSS, const AllocaInst *Val)
+      : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
+        isSpillSlot(isSS), Alloca(Val), PreAllocated(false) {}
+  };
+
+  const TargetMachine &TM;
+
+  /// Objects - The list of stack objects allocated...
+  ///
+  std::vector<StackObject> Objects;
+
+  /// NumFixedObjects - This contains the number of fixed objects contained on
+  /// the stack.  Because fixed objects are stored at a negative index in the
+  /// Objects list, this is also the index to the 0th object in the list.
+  ///
+  unsigned NumFixedObjects;
+
+  /// HasVarSizedObjects - This boolean keeps track of whether any variable
+  /// sized objects have been allocated yet.
+  ///
+  bool HasVarSizedObjects;
+
+  /// FrameAddressTaken - This boolean keeps track of whether there is a call
+  /// to builtin \@llvm.frameaddress.
+  bool FrameAddressTaken;
+
+  /// ReturnAddressTaken - This boolean keeps track of whether there is a call
+  /// to builtin \@llvm.returnaddress.
+  bool ReturnAddressTaken;
+
+  /// HasStackMap - This boolean keeps track of whether there is a call
+  /// to builtin \@llvm.experimental.stackmap.
+  bool HasStackMap;
+
+  /// HasPatchPoint - This boolean keeps track of whether there is a call
+  /// to builtin \@llvm.experimental.patchpoint.
+  bool HasPatchPoint;
+
+  /// StackSize - The prolog/epilog code inserter calculates the final stack
+  /// offsets for all of the fixed size objects, updating the Objects list
+  /// above.  It then updates StackSize to contain the number of bytes that need
+  /// to be allocated on entry to the function.
+  ///
+  uint64_t StackSize;
+
+  /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
+  /// have the actual offset from the stack/frame pointer.  The exact usage of
+  /// this is target-dependent, but it is typically used to adjust between
+  /// SP-relative and FP-relative offsets.  E.G., if objects are accessed via
+  /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set
+  /// to the distance between the initial SP and the value in FP.  For many
+  /// targets, this value is only used when generating debug info (via
+  /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the
+  /// corresponding adjustments are performed directly.
+  int OffsetAdjustment;
+
+  /// MaxAlignment - The prolog/epilog code inserter may process objects
+  /// that require greater alignment than the default alignment the target
+  /// provides. To handle this, MaxAlignment is set to the maximum alignment
+  /// needed by the objects on the current frame.  If this is greater than the
+  /// native alignment maintained by the compiler, dynamic alignment code will
+  /// be needed.
+  ///
+  unsigned MaxAlignment;
+
+  /// AdjustsStack - Set to true if this function adjusts the stack -- e.g.,
+  /// when calling another function. This is only valid during and after
+  /// prolog/epilog code insertion.
+  bool AdjustsStack;
+
+  /// HasCalls - Set to true if this function has any function calls.
+  bool HasCalls;
+
+  /// StackProtectorIdx - The frame index for the stack protector.
+  int StackProtectorIdx;
+
+  /// FunctionContextIdx - The frame index for the function context. Used for
+  /// SjLj exceptions.
+  int FunctionContextIdx;
+
+  /// MaxCallFrameSize - This contains the size of the largest call frame if the
+  /// target uses frame setup/destroy pseudo instructions (as defined in the
+  /// TargetFrameInfo class).  This information is important for frame pointer
+  /// elimination.  If is only valid during and after prolog/epilog code
+  /// insertion.
+  ///
+  unsigned MaxCallFrameSize;
+
+  /// CSInfo - The prolog/epilog code inserter fills in this vector with each
+  /// callee saved register saved in the frame.  Beyond its use by the prolog/
+  /// epilog code inserter, this data used for debug info and exception
+  /// handling.
+  std::vector<CalleeSavedInfo> CSInfo;
+
+  /// CSIValid - Has CSInfo been set yet?
+  bool CSIValid;
+
+  /// LocalFrameObjects - References to frame indices which are mapped
+  /// into the local frame allocation block. <FrameIdx, LocalOffset>
+  SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
+
+  /// LocalFrameSize - Size of the pre-allocated local frame block.
+  int64_t LocalFrameSize;
+
+  /// Required alignment of the local object blob, which is the strictest
+  /// alignment of any object in it.
+  unsigned LocalFrameMaxAlign;
+
+  /// Whether the local object blob needs to be allocated together. If not,
+  /// PEI should ignore the isPreAllocated flags on the stack objects and
+  /// just allocate them normally.
+  bool UseLocalStackAllocationBlock;
+
+  /// Whether the "realign-stack" option is on.
+  bool RealignOption;
+
+  /// True if the function includes inline assembly that adjusts the stack
+  /// pointer.
+  bool HasInlineAsmWithSPAdjust;
+
+  const TargetFrameLowering *getFrameLowering() const;
+public:
+    explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
+    : TM(TM), RealignOption(RealignOpt) {
+    StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
+    HasVarSizedObjects = false;
+    FrameAddressTaken = false;
+    ReturnAddressTaken = false;
+    HasStackMap = false;
+    HasPatchPoint = false;
+    AdjustsStack = false;
+    HasCalls = false;
+    StackProtectorIdx = -1;
+    FunctionContextIdx = -1;
+    MaxCallFrameSize = 0;
+    CSIValid = false;
+    LocalFrameSize = 0;
+    LocalFrameMaxAlign = 0;
+    UseLocalStackAllocationBlock = false;
+    HasInlineAsmWithSPAdjust = false;
+  }
+
+  /// hasStackObjects - Return true if there are any stack objects in this
+  /// function.
+  ///
+  bool hasStackObjects() const { return !Objects.empty(); }
+
+  /// hasVarSizedObjects - This method may be called any time after instruction
+  /// selection is complete to determine if the stack frame for this function
+  /// contains any variable sized objects.
+  ///
+  bool hasVarSizedObjects() const { return HasVarSizedObjects; }
+
+  /// getStackProtectorIndex/setStackProtectorIndex - Return the index for the
+  /// stack protector object.
+  ///
+  int getStackProtectorIndex() const { return StackProtectorIdx; }
+  void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
+
+  /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the
+  /// function context object. This object is used for SjLj exceptions.
+  int getFunctionContextIndex() const { return FunctionContextIdx; }
+  void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
+
+  /// isFrameAddressTaken - This method may be called any time after instruction
+  /// selection is complete to determine if there is a call to
+  /// \@llvm.frameaddress in this function.
+  bool isFrameAddressTaken() const { return FrameAddressTaken; }
+  void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
+
+  /// isReturnAddressTaken - This method may be called any time after
+  /// instruction selection is complete to determine if there is a call to
+  /// \@llvm.returnaddress in this function.
+  bool isReturnAddressTaken() const { return ReturnAddressTaken; }
+  void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
+
+  /// hasStackMap - This method may be called any time after instruction
+  /// selection is complete to determine if there is a call to builtin
+  /// \@llvm.experimental.stackmap.
+  bool hasStackMap() const { return HasStackMap; }
+  void setHasStackMap(bool s = true) { HasStackMap = s; }
+
+  /// hasPatchPoint - This method may be called any time after instruction
+  /// selection is complete to determine if there is a call to builtin
+  /// \@llvm.experimental.patchpoint.
+  bool hasPatchPoint() const { return HasPatchPoint; }
+  void setHasPatchPoint(bool s = true) { HasPatchPoint = s; }
+
+  /// getObjectIndexBegin - Return the minimum frame object index.
+  ///
+  int getObjectIndexBegin() const { return -NumFixedObjects; }
+
+  /// getObjectIndexEnd - Return one past the maximum frame object index.
+  ///
+  int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
+
+  /// getNumFixedObjects - Return the number of fixed objects.
+  unsigned getNumFixedObjects() const { return NumFixedObjects; }
+
+  /// getNumObjects - Return the number of objects.
+  ///
+  unsigned getNumObjects() const { return Objects.size(); }
+
+  /// mapLocalFrameObject - Map a frame index into the local object block
+  void mapLocalFrameObject(int ObjectIndex, int64_t Offset) {
+    LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset));
+    Objects[ObjectIndex + NumFixedObjects].PreAllocated = true;
+  }
+
+  /// getLocalFrameObjectMap - Get the local offset mapping for a for an object
+  std::pair<int, int64_t> getLocalFrameObjectMap(int i) {
+    assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() &&
+            "Invalid local object reference!");
+    return LocalFrameObjects[i];
+  }
+
+  /// getLocalFrameObjectCount - Return the number of objects allocated into
+  /// the local object block.
+  int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); }
+
+  /// setLocalFrameSize - Set the size of the local object blob.
+  void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; }
+
+  /// getLocalFrameSize - Get the size of the local object blob.
+  int64_t getLocalFrameSize() const { return LocalFrameSize; }
+
+  /// setLocalFrameMaxAlign - Required alignment of the local object blob,
+  /// which is the strictest alignment of any object in it.
+  void setLocalFrameMaxAlign(unsigned Align) { LocalFrameMaxAlign = Align; }
+
+  /// getLocalFrameMaxAlign - Return the required alignment of the local
+  /// object blob.
+  unsigned getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; }
+
+  /// getUseLocalStackAllocationBlock - Get whether the local allocation blob
+  /// should be allocated together or let PEI allocate the locals in it
+  /// directly.
+  bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;}
+
+  /// setUseLocalStackAllocationBlock - Set whether the local allocation blob
+  /// should be allocated together or let PEI allocate the locals in it
+  /// directly.
+  void setUseLocalStackAllocationBlock(bool v) {
+    UseLocalStackAllocationBlock = v;
+  }
+
+  /// isObjectPreAllocated - Return true if the object was pre-allocated into
+  /// the local block.
+  bool isObjectPreAllocated(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
+  }
+
+  /// getObjectSize - Return the size of the specified object.
+  ///
+  int64_t getObjectSize(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].Size;
+  }
+
+  /// setObjectSize - Change the size of the specified stack object.
+  void setObjectSize(int ObjectIdx, int64_t Size) {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    Objects[ObjectIdx+NumFixedObjects].Size = Size;
+  }
+
+  /// getObjectAlignment - Return the alignment of the specified stack object.
+  unsigned getObjectAlignment(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].Alignment;
+  }
+
+  /// setObjectAlignment - Change the alignment of the specified stack object.
+  void setObjectAlignment(int ObjectIdx, unsigned Align) {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
+    ensureMaxAlignment(Align);
+  }
+
+  /// getObjectAllocation - Return the underlying Alloca of the specified
+  /// stack object if it exists. Returns 0 if none exists.
+  const AllocaInst* getObjectAllocation(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].Alloca;
+  }
+
+  /// getObjectOffset - Return the assigned stack offset of the specified object
+  /// from the incoming stack pointer.
+  ///
+  int64_t getObjectOffset(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    assert(!isDeadObjectIndex(ObjectIdx) &&
+           "Getting frame offset for a dead object?");
+    return Objects[ObjectIdx+NumFixedObjects].SPOffset;
+  }
+
+  /// setObjectOffset - Set the stack frame offset of the specified object.  The
+  /// offset is relative to the stack pointer on entry to the function.
+  ///
+  void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    assert(!isDeadObjectIndex(ObjectIdx) &&
+           "Setting frame offset for a dead object?");
+    Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
+  }
+
+  /// getStackSize - Return the number of bytes that must be allocated to hold
+  /// all of the fixed size frame objects.  This is only valid after
+  /// Prolog/Epilog code insertion has finalized the stack frame layout.
+  ///
+  uint64_t getStackSize() const { return StackSize; }
+
+  /// setStackSize - Set the size of the stack...
+  ///
+  void setStackSize(uint64_t Size) { StackSize = Size; }
+
+  /// Estimate and return the size of the stack frame.
+  unsigned estimateStackSize(const MachineFunction &MF) const;
+
+  /// getOffsetAdjustment - Return the correction for frame offsets.
+  ///
+  int getOffsetAdjustment() const { return OffsetAdjustment; }
+
+  /// setOffsetAdjustment - Set the correction for frame offsets.
+  ///
+  void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
+
+  /// getMaxAlignment - Return the alignment in bytes that this function must be
+  /// aligned to, which is greater than the default stack alignment provided by
+  /// the target.
+  ///
+  unsigned getMaxAlignment() const { return MaxAlignment; }
+
+  /// ensureMaxAlignment - Make sure the function is at least Align bytes
+  /// aligned.
+  void ensureMaxAlignment(unsigned Align);
+
+  /// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
+  /// when calling another function. This is only valid during and after
+  /// prolog/epilog code insertion.
+  bool adjustsStack() const { return AdjustsStack; }
+  void setAdjustsStack(bool V) { AdjustsStack = V; }
+
+  /// hasCalls - Return true if the current function has any function calls.
+  bool hasCalls() const { return HasCalls; }
+  void setHasCalls(bool V) { HasCalls = V; }
+
+  /// Returns true if the function contains any stack-adjusting inline assembly.
+  bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
+  void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
+
+  /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
+  /// allocated for an outgoing function call.  This is only available if
+  /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
+  /// then only during or after prolog/epilog code insertion.
+  ///
+  unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
+  void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
+
+  /// CreateFixedObject - Create a new object at a fixed location on the stack.
+  /// All fixed objects should be created before other objects are created for
+  /// efficiency. By default, fixed objects are immutable. This returns an
+  /// index with a negative value.
+  ///
+  int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
+
+  /// CreateFixedSpillStackObject - Create a spill slot at a fixed location
+  /// on the stack.  Returns an index with a negative value.
+  int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset);
+
+  /// isFixedObjectIndex - Returns true if the specified index corresponds to a
+  /// fixed stack object.
+  bool isFixedObjectIndex(int ObjectIdx) const {
+    return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
+  }
+
+  /// isImmutableObjectIndex - Returns true if the specified index corresponds
+  /// to an immutable object.
+  bool isImmutableObjectIndex(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].isImmutable;
+  }
+
+  /// isSpillSlotObjectIndex - Returns true if the specified index corresponds
+  /// to a spill slot..
+  bool isSpillSlotObjectIndex(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].isSpillSlot;
+  }
+
+  /// isDeadObjectIndex - Returns true if the specified index corresponds to
+  /// a dead object.
+  bool isDeadObjectIndex(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
+  }
+
+  /// CreateStackObject - Create a new statically sized stack object, returning
+  /// a nonnegative identifier to represent it.
+  ///
+  int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
+                        const AllocaInst *Alloca = nullptr);
+
+  /// CreateSpillStackObject - Create a new statically sized stack object that
+  /// represents a spill slot, returning a nonnegative identifier to represent
+  /// it.
+  ///
+  int CreateSpillStackObject(uint64_t Size, unsigned Alignment);
+
+  /// RemoveStackObject - Remove or mark dead a statically sized stack object.
+  ///
+  void RemoveStackObject(int ObjectIdx) {
+    // Mark it dead.
+    Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
+  }
+
+  /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
+  /// variable sized object has been created.  This must be created whenever a
+  /// variable sized object is created, whether or not the index returned is
+  /// actually used.
+  ///
+  int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
+
+  /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
+  /// current function.
+  const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const {
+    return CSInfo;
+  }
+
+  /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
+  /// callee saved information.
+  void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
+    CSInfo = CSI;
+  }
+
+  /// isCalleeSavedInfoValid - Has the callee saved info been calculated yet?
+  bool isCalleeSavedInfoValid() const { return CSIValid; }
+
+  void setCalleeSavedInfoValid(bool v) { CSIValid = v; }
+
+  /// getPristineRegs - Return a set of physical registers that are pristine on
+  /// entry to the MBB.
+  ///
+  /// Pristine registers hold a value that is useless to the current function,
+  /// but that must be preserved - they are callee saved registers that have not
+  /// been saved yet.
+  ///
+  /// Before the PrologueEpilogueInserter has placed the CSR spill code, this
+  /// method always returns an empty set.
+  BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
+
+  /// print - Used by the MachineFunction printer to print information about
+  /// stack objects. Implemented in MachineFunction.cpp
+  ///
+  void print(const MachineFunction &MF, raw_ostream &OS) const;
+
+  /// dump - Print the function to stderr.
+  void dump(const MachineFunction &MF) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
new file mode 100644
index 0000000..042c62b
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -0,0 +1,530 @@
+//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect native machine code for a function.  This class contains a list of
+// MachineBasicBlock instances that make up the current compiled function.
+//
+// This class also contains pointers to various classes which hold
+// target-specific information about the generated code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
+#define LLVM_CODEGEN_MACHINEFUNCTION_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ArrayRecycler.h"
+#include "llvm/Support/Recycler.h"
+
+namespace llvm {
+
+class Value;
+class Function;
+class GCModuleInfo;
+class MachineRegisterInfo;
+class MachineFrameInfo;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineModuleInfo;
+class MCContext;
+class Pass;
+class TargetMachine;
+class TargetRegisterClass;
+struct MachinePointerInfo;
+
+template <>
+struct ilist_traits<MachineBasicBlock>
+    : public ilist_default_traits<MachineBasicBlock> {
+  mutable ilist_half_node<MachineBasicBlock> Sentinel;
+public:
+  MachineBasicBlock *createSentinel() const {
+    return static_cast<MachineBasicBlock*>(&Sentinel);
+  }
+  void destroySentinel(MachineBasicBlock *) const {}
+
+  MachineBasicBlock *provideInitialHead() const { return createSentinel(); }
+  MachineBasicBlock *ensureHead(MachineBasicBlock*) const {
+    return createSentinel();
+  }
+  static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {}
+
+  void addNodeToList(MachineBasicBlock* MBB);
+  void removeNodeFromList(MachineBasicBlock* MBB);
+  void deleteNode(MachineBasicBlock *MBB);
+private:
+  void createNode(const MachineBasicBlock &);
+};
+
+/// MachineFunctionInfo - This class can be derived from and used by targets to
+/// hold private target-specific information for each MachineFunction.  Objects
+/// of type are accessed/created with MF::getInfo and destroyed when the
+/// MachineFunction is destroyed.
+struct MachineFunctionInfo {
+  virtual ~MachineFunctionInfo();
+};
+
+class MachineFunction {
+  const Function *Fn;
+  const TargetMachine &Target;
+  MCContext &Ctx;
+  MachineModuleInfo &MMI;
+  GCModuleInfo *GMI;
+  
+  // RegInfo - Information about each register in use in the function.
+  MachineRegisterInfo *RegInfo;
+
+  // Used to keep track of target-specific per-machine function information for
+  // the target implementation.
+  MachineFunctionInfo *MFInfo;
+
+  // Keep track of objects allocated on the stack.
+  MachineFrameInfo *FrameInfo;
+
+  // Keep track of constants which are spilled to memory
+  MachineConstantPool *ConstantPool;
+  
+  // Keep track of jump tables for switch instructions
+  MachineJumpTableInfo *JumpTableInfo;
+
+  // Function-level unique numbering for MachineBasicBlocks.  When a
+  // MachineBasicBlock is inserted into a MachineFunction is it automatically
+  // numbered and this vector keeps track of the mapping from ID's to MBB's.
+  std::vector<MachineBasicBlock*> MBBNumbering;
+
+  // Pool-allocate MachineFunction-lifetime and IR objects.
+  BumpPtrAllocator Allocator;
+
+  // Allocation management for instructions in function.
+  Recycler<MachineInstr> InstructionRecycler;
+
+  // Allocation management for operand arrays on instructions.
+  ArrayRecycler<MachineOperand> OperandRecycler;
+
+  // Allocation management for basic blocks in function.
+  Recycler<MachineBasicBlock> BasicBlockRecycler;
+
+  // List of machine basic blocks in function
+  typedef ilist<MachineBasicBlock> BasicBlockListType;
+  BasicBlockListType BasicBlocks;
+
+  /// FunctionNumber - This provides a unique ID for each function emitted in
+  /// this translation unit.
+  ///
+  unsigned FunctionNumber;
+  
+  /// Alignment - The alignment of the function.
+  unsigned Alignment;
+
+  /// ExposesReturnsTwice - True if the function calls setjmp or related
+  /// functions with attribute "returns twice", but doesn't have
+  /// the attribute itself.
+  /// This is used to limit optimizations which cannot reason
+  /// about the control flow of such functions.
+  bool ExposesReturnsTwice;
+
+  /// True if the function includes any inline assembly.
+  bool HasInlineAsm;
+
+  MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
+  void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
+public:
+  MachineFunction(const Function *Fn, const TargetMachine &TM,
+                  unsigned FunctionNum, MachineModuleInfo &MMI,
+                  GCModuleInfo* GMI);
+  ~MachineFunction();
+
+  MachineModuleInfo &getMMI() const { return MMI; }
+  GCModuleInfo *getGMI() const { return GMI; }
+  MCContext &getContext() const { return Ctx; }
+
+  /// getFunction - Return the LLVM function that this machine code represents
+  ///
+  const Function *getFunction() const { return Fn; }
+
+  /// getName - Return the name of the corresponding LLVM function.
+  ///
+  StringRef getName() const;
+
+  /// getFunctionNumber - Return a unique ID for the current function.
+  ///
+  unsigned getFunctionNumber() const { return FunctionNumber; }
+
+  /// getTarget - Return the target machine this machine code is compiled with
+  ///
+  const TargetMachine &getTarget() const { return Target; }
+
+  /// getRegInfo - Return information about the registers currently in use.
+  ///
+  MachineRegisterInfo &getRegInfo() { return *RegInfo; }
+  const MachineRegisterInfo &getRegInfo() const { return *RegInfo; }
+
+  /// getFrameInfo - Return the frame info object for the current function.
+  /// This object contains information about objects allocated on the stack
+  /// frame of the current function in an abstract way.
+  ///
+  MachineFrameInfo *getFrameInfo() { return FrameInfo; }
+  const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
+
+  /// getJumpTableInfo - Return the jump table info object for the current 
+  /// function.  This object contains information about jump tables in the
+  /// current function.  If the current function has no jump tables, this will
+  /// return null.
+  const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
+  MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
+
+  /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
+  /// does already exist, allocate one.
+  MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
+
+  
+  /// getConstantPool - Return the constant pool object for the current
+  /// function.
+  ///
+  MachineConstantPool *getConstantPool() { return ConstantPool; }
+  const MachineConstantPool *getConstantPool() const { return ConstantPool; }
+
+  /// getAlignment - Return the alignment (log2, not bytes) of the function.
+  ///
+  unsigned getAlignment() const { return Alignment; }
+
+  /// setAlignment - Set the alignment (log2, not bytes) of the function.
+  ///
+  void setAlignment(unsigned A) { Alignment = A; }
+
+  /// ensureAlignment - Make sure the function is at least 1 << A bytes aligned.
+  void ensureAlignment(unsigned A) {
+    if (Alignment < A) Alignment = A;
+  }
+
+  /// exposesReturnsTwice - Returns true if the function calls setjmp or
+  /// any other similar functions with attribute "returns twice" without
+  /// having the attribute itself.
+  bool exposesReturnsTwice() const {
+    return ExposesReturnsTwice;
+  }
+
+  /// setCallsSetJmp - Set a flag that indicates if there's a call to
+  /// a "returns twice" function.
+  void setExposesReturnsTwice(bool B) {
+    ExposesReturnsTwice = B;
+  }
+
+  /// Returns true if the function contains any inline assembly.
+  bool hasInlineAsm() const {
+    return HasInlineAsm;
+  }
+
+  /// Set a flag that indicates that the function contains inline assembly.
+  void setHasInlineAsm(bool B) {
+    HasInlineAsm = B;
+  }
+
+  /// getInfo - Keep track of various per-function pieces of information for
+  /// backends that would like to do so.
+  ///
+  template<typename Ty>
+  Ty *getInfo() {
+    if (!MFInfo)
+      MFInfo = new (Allocator.Allocate<Ty>()) Ty(*this);
+    return static_cast<Ty*>(MFInfo);
+  }
+
+  template<typename Ty>
+  const Ty *getInfo() const {
+     return const_cast<MachineFunction*>(this)->getInfo<Ty>();
+  }
+
+  /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they
+  /// are inserted into the machine function.  The block number for a machine
+  /// basic block can be found by using the MBB::getBlockNumber method, this
+  /// method provides the inverse mapping.
+  ///
+  MachineBasicBlock *getBlockNumbered(unsigned N) const {
+    assert(N < MBBNumbering.size() && "Illegal block number");
+    assert(MBBNumbering[N] && "Block was removed from the machine function!");
+    return MBBNumbering[N];
+  }
+
+  /// Should we be emitting segmented stack stuff for the function
+  bool shouldSplitStack();
+
+  /// getNumBlockIDs - Return the number of MBB ID's allocated.
+  ///
+  unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
+  
+  /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
+  /// recomputes them.  This guarantees that the MBB numbers are sequential,
+  /// dense, and match the ordering of the blocks within the function.  If a
+  /// specific MachineBasicBlock is specified, only that block and those after
+  /// it are renumbered.
+  void RenumberBlocks(MachineBasicBlock *MBBFrom = nullptr);
+  
+  /// print - Print out the MachineFunction in a format suitable for debugging
+  /// to the specified stream.
+  ///
+  void print(raw_ostream &OS, SlotIndexes* = nullptr) const;
+
+  /// viewCFG - This function is meant for use from the debugger.  You can just
+  /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+  /// program, displaying the CFG of the current function with the code for each
+  /// basic block inside.  This depends on there being a 'dot' and 'gv' program
+  /// in your path.
+  ///
+  void viewCFG() const;
+
+  /// viewCFGOnly - This function is meant for use from the debugger.  It works
+  /// just like viewCFG, but it does not include the contents of basic blocks
+  /// into the nodes, just the label.  If you are only interested in the CFG
+  /// this can make the graph smaller.
+  ///
+  void viewCFGOnly() const;
+
+  /// dump - Print the current MachineFunction to cerr, useful for debugger use.
+  ///
+  void dump() const;
+
+  /// verify - Run the current MachineFunction through the machine code
+  /// verifier, useful for debugger use.
+  void verify(Pass *p = nullptr, const char *Banner = nullptr) const;
+
+  // Provide accessors for the MachineBasicBlock list...
+  typedef BasicBlockListType::iterator iterator;
+  typedef BasicBlockListType::const_iterator const_iterator;
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef std::reverse_iterator<iterator>             reverse_iterator;
+
+  /// addLiveIn - Add the specified physical register as a live-in value and
+  /// create a corresponding virtual register for it.
+  unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC);
+
+  //===--------------------------------------------------------------------===//
+  // BasicBlock accessor functions.
+  //
+  iterator                 begin()       { return BasicBlocks.begin(); }
+  const_iterator           begin() const { return BasicBlocks.begin(); }
+  iterator                 end  ()       { return BasicBlocks.end();   }
+  const_iterator           end  () const { return BasicBlocks.end();   }
+
+  reverse_iterator        rbegin()       { return BasicBlocks.rbegin(); }
+  const_reverse_iterator  rbegin() const { return BasicBlocks.rbegin(); }
+  reverse_iterator        rend  ()       { return BasicBlocks.rend();   }
+  const_reverse_iterator  rend  () const { return BasicBlocks.rend();   }
+
+  unsigned                  size() const { return (unsigned)BasicBlocks.size();}
+  bool                     empty() const { return BasicBlocks.empty(); }
+  const MachineBasicBlock &front() const { return BasicBlocks.front(); }
+        MachineBasicBlock &front()       { return BasicBlocks.front(); }
+  const MachineBasicBlock & back() const { return BasicBlocks.back(); }
+        MachineBasicBlock & back()       { return BasicBlocks.back(); }
+
+  void push_back (MachineBasicBlock *MBB) { BasicBlocks.push_back (MBB); }
+  void push_front(MachineBasicBlock *MBB) { BasicBlocks.push_front(MBB); }
+  void insert(iterator MBBI, MachineBasicBlock *MBB) {
+    BasicBlocks.insert(MBBI, MBB);
+  }
+  void splice(iterator InsertPt, iterator MBBI) {
+    BasicBlocks.splice(InsertPt, BasicBlocks, MBBI);
+  }
+  void splice(iterator InsertPt, iterator MBBI, iterator MBBE) {
+    BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE);
+  }
+
+  void remove(iterator MBBI) {
+    BasicBlocks.remove(MBBI);
+  }
+  void erase(iterator MBBI) {
+    BasicBlocks.erase(MBBI);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Internal functions used to automatically number MachineBasicBlocks
+  //
+
+  /// \brief Adds the MBB to the internal numbering. Returns the unique number
+  /// assigned to the MBB.
+  ///
+  unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
+    MBBNumbering.push_back(MBB);
+    return (unsigned)MBBNumbering.size()-1;
+  }
+
+  /// removeFromMBBNumbering - Remove the specific machine basic block from our
+  /// tracker, this is only really to be used by the MachineBasicBlock
+  /// implementation.
+  void removeFromMBBNumbering(unsigned N) {
+    assert(N < MBBNumbering.size() && "Illegal basic block #");
+    MBBNumbering[N] = nullptr;
+  }
+
+  /// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
+  /// of `new MachineInstr'.
+  ///
+  MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
+                                   DebugLoc DL,
+                                   bool NoImp = false);
+
+  /// CloneMachineInstr - Create a new MachineInstr which is a copy of the
+  /// 'Orig' instruction, identical in all ways except the instruction
+  /// has no parent, prev, or next.
+  ///
+  /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned
+  /// instructions.
+  MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
+
+  /// DeleteMachineInstr - Delete the given MachineInstr.
+  ///
+  void DeleteMachineInstr(MachineInstr *MI);
+
+  /// CreateMachineBasicBlock - Allocate a new MachineBasicBlock. Use this
+  /// instead of `new MachineBasicBlock'.
+  ///
+  MachineBasicBlock *CreateMachineBasicBlock(const BasicBlock *bb = nullptr);
+
+  /// DeleteMachineBasicBlock - Delete the given MachineBasicBlock.
+  ///
+  void DeleteMachineBasicBlock(MachineBasicBlock *MBB);
+
+  /// getMachineMemOperand - Allocate a new MachineMemOperand.
+  /// MachineMemOperands are owned by the MachineFunction and need not be
+  /// explicitly deallocated.
+  MachineMemOperand *getMachineMemOperand(MachinePointerInfo PtrInfo,
+                                          unsigned f, uint64_t s,
+                                          unsigned base_alignment,
+                                          const MDNode *TBAAInfo = nullptr,
+                                          const MDNode *Ranges = nullptr);
+  
+  /// getMachineMemOperand - Allocate a new MachineMemOperand by copying
+  /// an existing one, adjusting by an offset and using the given size.
+  /// MachineMemOperands are owned by the MachineFunction and need not be
+  /// explicitly deallocated.
+  MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
+                                          int64_t Offset, uint64_t Size);
+
+  typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+
+  /// Allocate an array of MachineOperands. This is only intended for use by
+  /// internal MachineInstr functions.
+  MachineOperand *allocateOperandArray(OperandCapacity Cap) {
+    return OperandRecycler.allocate(Cap, Allocator);
+  }
+
+  /// Dellocate an array of MachineOperands and recycle the memory. This is
+  /// only intended for use by internal MachineInstr functions.
+  /// Cap must be the same capacity that was used to allocate the array.
+  void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) {
+    OperandRecycler.deallocate(Cap, Array);
+  }
+
+  /// \brief Allocate and initialize a register mask with @p NumRegister bits.
+  uint32_t *allocateRegisterMask(unsigned NumRegister) {
+    unsigned Size = (NumRegister + 31) / 32;
+    uint32_t *Mask = Allocator.Allocate<uint32_t>(Size);
+    for (unsigned i = 0; i != Size; ++i)
+      Mask[i] = 0;
+    return Mask;
+  }
+
+  /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
+  /// pointers.  This array is owned by the MachineFunction.
+  MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
+
+  /// extractLoadMemRefs - Allocate an array and populate it with just the
+  /// load information from the given MachineMemOperand sequence.
+  std::pair<MachineInstr::mmo_iterator,
+            MachineInstr::mmo_iterator>
+    extractLoadMemRefs(MachineInstr::mmo_iterator Begin,
+                       MachineInstr::mmo_iterator End);
+
+  /// extractStoreMemRefs - Allocate an array and populate it with just the
+  /// store information from the given MachineMemOperand sequence.
+  std::pair<MachineInstr::mmo_iterator,
+            MachineInstr::mmo_iterator>
+    extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
+                        MachineInstr::mmo_iterator End);
+
+  //===--------------------------------------------------------------------===//
+  // Label Manipulation.
+  //
+  
+  /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
+  /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
+  /// normal 'L' label is returned.
+  MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx, 
+                         bool isLinkerPrivate = false) const;
+  
+  /// getPICBaseSymbol - Return a function-local symbol to represent the PIC
+  /// base.
+  MCSymbol *getPICBaseSymbol() const;
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// machine function as a graph of machine basic blocks... these are
+// the same as the machine basic block iterators, except that the root
+// node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<MachineFunction*> :
+  public GraphTraits<MachineBasicBlock*> {
+  static NodeType *getEntryNode(MachineFunction *F) {
+    return &F->front();
+  }
+
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef MachineFunction::iterator nodes_iterator;
+  static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); }
+  static nodes_iterator nodes_end  (MachineFunction *F) { return F->end(); }
+  static unsigned       size       (MachineFunction *F) { return F->size(); }
+};
+template <> struct GraphTraits<const MachineFunction*> :
+  public GraphTraits<const MachineBasicBlock*> {
+  static NodeType *getEntryNode(const MachineFunction *F) {
+    return &F->front();
+  }
+
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef MachineFunction::const_iterator nodes_iterator;
+  static nodes_iterator nodes_begin(const MachineFunction *F) {
+    return F->begin();
+  }
+  static nodes_iterator nodes_end  (const MachineFunction *F) {
+    return F->end();
+  }
+  static unsigned       size       (const MachineFunction *F)  {
+    return F->size();
+  }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order.  Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineFunction*> > :
+  public GraphTraits<Inverse<MachineBasicBlock*> > {
+  static NodeType *getEntryNode(Inverse<MachineFunction*> G) {
+    return &G.Graph->front();
+  }
+};
+template <> struct GraphTraits<Inverse<const MachineFunction*> > :
+  public GraphTraits<Inverse<const MachineBasicBlock*> > {
+  static NodeType *getEntryNode(Inverse<const MachineFunction *> G) {
+    return &G.Graph->front();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
new file mode 100644
index 0000000..36f1c66
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -0,0 +1,51 @@
+//===-- MachineFunctionAnalysis.h - Owner of MachineFunctions ----*-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 MachineFunctionAnalysis class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H
+#define LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class MachineFunction;
+class TargetMachine;
+
+/// MachineFunctionAnalysis - This class is a Pass that manages a
+/// MachineFunction object.
+struct MachineFunctionAnalysis : public FunctionPass {
+private:
+  const TargetMachine &TM;
+  MachineFunction *MF;
+  unsigned NextFnNum;
+public:
+  static char ID;
+  explicit MachineFunctionAnalysis(const TargetMachine &tm);
+  ~MachineFunctionAnalysis();
+
+  MachineFunction &getMF() const { return *MF; }
+
+  const char* getPassName() const override {
+    return "Machine Function Analysis";
+  }
+
+private:
+  bool doInitialization(Module &M) override;
+  bool runOnFunction(Function &F) override;
+  void releaseMemory() override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
new file mode 100644
index 0000000..50a1f6e
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -0,0 +1,59 @@
+//===-- MachineFunctionPass.h - Pass for MachineFunctions --------*-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 MachineFunctionPass class.  MachineFunctionPass's are
+// just FunctionPass's, except they operate on machine code as part of a code
+// generator.  Because they operate on machine code, not the LLVM
+// representation, MachineFunctionPass's are not allowed to modify the LLVM
+// representation.  Due to this limitation, the MachineFunctionPass class takes
+// care of declaring that no LLVM passes are invalidated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
+#define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class MachineFunction;
+
+/// MachineFunctionPass - This class adapts the FunctionPass interface to
+/// allow convenient creation of passes that operate on the MachineFunction
+/// representation. Instead of overriding runOnFunction, subclasses
+/// override runOnMachineFunction.
+class MachineFunctionPass : public FunctionPass {
+protected:
+  explicit MachineFunctionPass(char &ID) : FunctionPass(ID) {}
+
+  /// runOnMachineFunction - This method must be overloaded to perform the
+  /// desired machine code transformation or analysis.
+  ///
+  virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+
+  /// getAnalysisUsage - Subclasses that override getAnalysisUsage
+  /// must call this.
+  ///
+  /// For MachineFunctionPasses, calling AU.preservesCFG() indicates that
+  /// the pass does not modify the MachineBasicBlock CFG.
+  ///
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+  /// createPrinterPass - Get a machine function printer pass.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  bool runOnFunction(Function &F) override;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
new file mode 100644
index 0000000..3c82811
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -0,0 +1,1179 @@
+//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineInstr class, which is the
+// basic representation for all target dependent machine instructions used by
+// the back end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTR_H
+#define LLVM_CODEGEN_MACHINEINSTR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Support/ArrayRecycler.h"
+#include "llvm/Target/TargetOpcodes.h"
+
+namespace llvm {
+
+template <typename T> class SmallVectorImpl;
+class AliasAnalysis;
+class TargetInstrInfo;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class MachineFunction;
+class MachineMemOperand;
+
+//===----------------------------------------------------------------------===//
+/// MachineInstr - Representation of each machine instruction.
+///
+/// This class isn't a POD type, but it must have a trivial destructor. When a
+/// MachineFunction is deleted, all the contained MachineInstrs are deallocated
+/// without having their destructor called.
+///
+class MachineInstr : public ilist_node<MachineInstr> {
+public:
+  typedef MachineMemOperand **mmo_iterator;
+
+  /// Flags to specify different kinds of comments to output in
+  /// assembly code.  These flags carry semantic information not
+  /// otherwise easily derivable from the IR text.
+  ///
+  enum CommentFlag {
+    ReloadReuse = 0x1
+  };
+
+  enum MIFlag {
+    NoFlags      = 0,
+    FrameSetup   = 1 << 0,              // Instruction is used as a part of
+                                        // function frame setup code.
+    BundledPred  = 1 << 1,              // Instruction has bundled predecessors.
+    BundledSucc  = 1 << 2               // Instruction has bundled successors.
+  };
+private:
+  const MCInstrDesc *MCID;              // Instruction descriptor.
+  MachineBasicBlock *Parent;            // Pointer to the owning basic block.
+
+  // Operands are allocated by an ArrayRecycler.
+  MachineOperand *Operands;             // Pointer to the first operand.
+  unsigned NumOperands;                 // Number of operands on instruction.
+  typedef ArrayRecycler<MachineOperand>::Capacity OperandCapacity;
+  OperandCapacity CapOperands;          // Capacity of the Operands array.
+
+  uint8_t Flags;                        // Various bits of additional
+                                        // information about machine
+                                        // instruction.
+
+  uint8_t AsmPrinterFlags;              // Various bits of information used by
+                                        // the AsmPrinter to emit helpful
+                                        // comments.  This is *not* semantic
+                                        // information.  Do not use this for
+                                        // anything other than to convey comment
+                                        // information to AsmPrinter.
+
+  uint8_t NumMemRefs;                   // Information on memory references.
+  mmo_iterator MemRefs;
+
+  DebugLoc debugLoc;                    // Source line information.
+
+  MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION;
+  void operator=(const MachineInstr&) LLVM_DELETED_FUNCTION;
+  // Use MachineFunction::DeleteMachineInstr() instead.
+  ~MachineInstr() LLVM_DELETED_FUNCTION;
+
+  // Intrusive list support
+  friend struct ilist_traits<MachineInstr>;
+  friend struct ilist_traits<MachineBasicBlock>;
+  void setParent(MachineBasicBlock *P) { Parent = P; }
+
+  /// MachineInstr ctor - This constructor creates a copy of the given
+  /// MachineInstr in the given MachineFunction.
+  MachineInstr(MachineFunction &, const MachineInstr &);
+
+  /// MachineInstr ctor - This constructor create a MachineInstr and add the
+  /// implicit operands.  It reserves space for number of operands specified by
+  /// MCInstrDesc.  An explicit DebugLoc is supplied.
+  MachineInstr(MachineFunction&, const MCInstrDesc &MCID,
+               const DebugLoc dl, bool NoImp = false);
+
+  // MachineInstrs are pool-allocated and owned by MachineFunction.
+  friend class MachineFunction;
+
+public:
+  const MachineBasicBlock* getParent() const { return Parent; }
+  MachineBasicBlock* getParent() { return Parent; }
+
+  /// getAsmPrinterFlags - Return the asm printer flags bitvector.
+  ///
+  uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; }
+
+  /// clearAsmPrinterFlags - clear the AsmPrinter bitvector
+  ///
+  void clearAsmPrinterFlags() { AsmPrinterFlags = 0; }
+
+  /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
+  ///
+  bool getAsmPrinterFlag(CommentFlag Flag) const {
+    return AsmPrinterFlags & Flag;
+  }
+
+  /// setAsmPrinterFlag - Set a flag for the AsmPrinter.
+  ///
+  void setAsmPrinterFlag(CommentFlag Flag) {
+    AsmPrinterFlags |= (uint8_t)Flag;
+  }
+
+  /// clearAsmPrinterFlag - clear specific AsmPrinter flags
+  ///
+  void clearAsmPrinterFlag(CommentFlag Flag) {
+    AsmPrinterFlags &= ~Flag;
+  }
+
+  /// getFlags - Return the MI flags bitvector.
+  uint8_t getFlags() const {
+    return Flags;
+  }
+
+  /// getFlag - Return whether an MI flag is set.
+  bool getFlag(MIFlag Flag) const {
+    return Flags & Flag;
+  }
+
+  /// setFlag - Set a MI flag.
+  void setFlag(MIFlag Flag) {
+    Flags |= (uint8_t)Flag;
+  }
+
+  void setFlags(unsigned flags) {
+    // Filter out the automatically maintained flags.
+    unsigned Mask = BundledPred | BundledSucc;
+    Flags = (Flags & Mask) | (flags & ~Mask);
+  }
+
+  /// clearFlag - Clear a MI flag.
+  void clearFlag(MIFlag Flag) {
+    Flags &= ~((uint8_t)Flag);
+  }
+
+  /// isInsideBundle - Return true if MI is in a bundle (but not the first MI
+  /// in a bundle).
+  ///
+  /// A bundle looks like this before it's finalized:
+  ///   ----------------
+  ///   |      MI      |
+  ///   ----------------
+  ///          |
+  ///   ----------------
+  ///   |      MI    * |
+  ///   ----------------
+  ///          |
+  ///   ----------------
+  ///   |      MI    * |
+  ///   ----------------
+  /// In this case, the first MI starts a bundle but is not inside a bundle, the
+  /// next 2 MIs are considered "inside" the bundle.
+  ///
+  /// After a bundle is finalized, it looks like this:
+  ///   ----------------
+  ///   |    Bundle    |
+  ///   ----------------
+  ///          |
+  ///   ----------------
+  ///   |      MI    * |
+  ///   ----------------
+  ///          |
+  ///   ----------------
+  ///   |      MI    * |
+  ///   ----------------
+  ///          |
+  ///   ----------------
+  ///   |      MI    * |
+  ///   ----------------
+  /// The first instruction has the special opcode "BUNDLE". It's not "inside"
+  /// a bundle, but the next three MIs are.
+  bool isInsideBundle() const {
+    return getFlag(BundledPred);
+  }
+
+  /// isBundled - Return true if this instruction part of a bundle. This is true
+  /// if either itself or its following instruction is marked "InsideBundle".
+  bool isBundled() const {
+    return isBundledWithPred() || isBundledWithSucc();
+  }
+
+  /// Return true if this instruction is part of a bundle, and it is not the
+  /// first instruction in the bundle.
+  bool isBundledWithPred() const { return getFlag(BundledPred); }
+
+  /// Return true if this instruction is part of a bundle, and it is not the
+  /// last instruction in the bundle.
+  bool isBundledWithSucc() const { return getFlag(BundledSucc); }
+
+  /// Bundle this instruction with its predecessor. This can be an unbundled
+  /// instruction, or it can be the first instruction in a bundle.
+  void bundleWithPred();
+
+  /// Bundle this instruction with its successor. This can be an unbundled
+  /// instruction, or it can be the last instruction in a bundle.
+  void bundleWithSucc();
+
+  /// Break bundle above this instruction.
+  void unbundleFromPred();
+
+  /// Break bundle below this instruction.
+  void unbundleFromSucc();
+
+  /// getDebugLoc - Returns the debug location id of this MachineInstr.
+  ///
+  DebugLoc getDebugLoc() const { return debugLoc; }
+
+  /// getDebugVariable() - Return the debug variable referenced by
+  /// this DBG_VALUE instruction.
+  DIVariable getDebugVariable() const {
+    assert(isDebugValue() && "not a DBG_VALUE");
+    const MDNode *Var = getOperand(getNumOperands() - 1).getMetadata();
+    return DIVariable(Var);
+  }
+
+  /// emitError - Emit an error referring to the source location of this
+  /// instruction. This should only be used for inline assembly that is somehow
+  /// impossible to compile. Other errors should have been handled much
+  /// earlier.
+  ///
+  /// If this method returns, the caller should try to recover from the error.
+  ///
+  void emitError(StringRef Msg) const;
+
+  /// getDesc - Returns the target instruction descriptor of this
+  /// MachineInstr.
+  const MCInstrDesc &getDesc() const { return *MCID; }
+
+  /// getOpcode - Returns the opcode of this MachineInstr.
+  ///
+  int getOpcode() const { return MCID->Opcode; }
+
+  /// Access to explicit operands of the instruction.
+  ///
+  unsigned getNumOperands() const { return NumOperands; }
+
+  const MachineOperand& getOperand(unsigned i) const {
+    assert(i < getNumOperands() && "getOperand() out of range!");
+    return Operands[i];
+  }
+  MachineOperand& getOperand(unsigned i) {
+    assert(i < getNumOperands() && "getOperand() out of range!");
+    return Operands[i];
+  }
+
+  /// getNumExplicitOperands - Returns the number of non-implicit operands.
+  ///
+  unsigned getNumExplicitOperands() const;
+
+  /// iterator/begin/end - Iterate over all operands of a machine instruction.
+  typedef MachineOperand *mop_iterator;
+  typedef const MachineOperand *const_mop_iterator;
+
+  mop_iterator operands_begin() { return Operands; }
+  mop_iterator operands_end() { return Operands + NumOperands; }
+
+  const_mop_iterator operands_begin() const { return Operands; }
+  const_mop_iterator operands_end() const { return Operands + NumOperands; }
+
+  iterator_range<mop_iterator> operands() {
+    return iterator_range<mop_iterator>(operands_begin(), operands_end());
+  }
+  iterator_range<const_mop_iterator> operands() const {
+    return iterator_range<const_mop_iterator>(operands_begin(), operands_end());
+  }
+  iterator_range<mop_iterator> explicit_operands() {
+    return iterator_range<mop_iterator>(
+        operands_begin(), operands_begin() + getNumExplicitOperands());
+  }
+  iterator_range<const_mop_iterator> explicit_operands() const {
+    return iterator_range<const_mop_iterator>(
+        operands_begin(), operands_begin() + getNumExplicitOperands());
+  }
+  iterator_range<mop_iterator> implicit_operands() {
+    return iterator_range<mop_iterator>(explicit_operands().end(),
+                                        operands_end());
+  }
+  iterator_range<const_mop_iterator> implicit_operands() const {
+    return iterator_range<const_mop_iterator>(explicit_operands().end(),
+                                              operands_end());
+  }
+  iterator_range<mop_iterator> defs() {
+    return iterator_range<mop_iterator>(
+        operands_begin(), operands_begin() + getDesc().getNumDefs());
+  }
+  iterator_range<const_mop_iterator> defs() const {
+    return iterator_range<const_mop_iterator>(
+        operands_begin(), operands_begin() + getDesc().getNumDefs());
+  }
+  iterator_range<mop_iterator> uses() {
+    return iterator_range<mop_iterator>(
+        operands_begin() + getDesc().getNumDefs(), operands_end());
+  }
+  iterator_range<const_mop_iterator> uses() const {
+    return iterator_range<const_mop_iterator>(
+        operands_begin() + getDesc().getNumDefs(), operands_end());
+  }
+
+  /// Access to memory operands of the instruction
+  mmo_iterator memoperands_begin() const { return MemRefs; }
+  mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; }
+  bool memoperands_empty() const { return NumMemRefs == 0; }
+
+  iterator_range<mmo_iterator>  memoperands() {
+    return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end());
+  }
+  iterator_range<mmo_iterator> memoperands() const {
+    return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end());
+  }
+
+  /// hasOneMemOperand - Return true if this instruction has exactly one
+  /// MachineMemOperand.
+  bool hasOneMemOperand() const {
+    return NumMemRefs == 1;
+  }
+
+  /// API for querying MachineInstr properties. They are the same as MCInstrDesc
+  /// queries but they are bundle aware.
+
+  enum QueryType {
+    IgnoreBundle,    // Ignore bundles
+    AnyInBundle,     // Return true if any instruction in bundle has property
+    AllInBundle      // Return true if all instructions in bundle have property
+  };
+
+  /// hasProperty - Return true if the instruction (or in the case of a bundle,
+  /// the instructions inside the bundle) has the specified property.
+  /// The first argument is the property being queried.
+  /// The second argument indicates whether the query should look inside
+  /// instruction bundles.
+  bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const {
+    // Inline the fast path for unbundled or bundle-internal instructions.
+    if (Type == IgnoreBundle || !isBundled() || isBundledWithPred())
+      return getDesc().getFlags() & (1 << MCFlag);
+
+    // If this is the first instruction in a bundle, take the slow path.
+    return hasPropertyInBundle(1 << MCFlag, Type);
+  }
+
+  /// isVariadic - Return true if this instruction can have a variable number of
+  /// operands.  In this case, the variable operands will be after the normal
+  /// operands but before the implicit definitions and uses (if any are
+  /// present).
+  bool isVariadic(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Variadic, Type);
+  }
+
+  /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+  /// ARM instructions which can set condition code if 's' bit is set.
+  bool hasOptionalDef(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::HasOptionalDef, Type);
+  }
+
+  /// isPseudo - Return true if this is a pseudo instruction that doesn't
+  /// correspond to a real machine instruction.
+  ///
+  bool isPseudo(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Pseudo, Type);
+  }
+
+  bool isReturn(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::Return, Type);
+  }
+
+  bool isCall(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::Call, Type);
+  }
+
+  /// isBarrier - Returns true if the specified instruction stops control flow
+  /// from executing the instruction immediately following it.  Examples include
+  /// unconditional branches and return instructions.
+  bool isBarrier(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::Barrier, Type);
+  }
+
+  /// isTerminator - Returns true if this instruction part of the terminator for
+  /// a basic block.  Typically this is things like return and branch
+  /// instructions.
+  ///
+  /// Various passes use this to insert code into the bottom of a basic block,
+  /// but before control flow occurs.
+  bool isTerminator(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::Terminator, Type);
+  }
+
+  /// isBranch - Returns true if this is a conditional, unconditional, or
+  /// indirect branch.  Predicates below can be used to discriminate between
+  /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+  /// get more information.
+  bool isBranch(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::Branch, Type);
+  }
+
+  /// isIndirectBranch - Return true if this is an indirect branch, such as a
+  /// branch through a register.
+  bool isIndirectBranch(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::IndirectBranch, Type);
+  }
+
+  /// isConditionalBranch - Return true if this is a branch which may fall
+  /// through to the next instruction or may transfer control flow to some other
+  /// block.  The TargetInstrInfo::AnalyzeBranch method can be used to get more
+  /// information about this branch.
+  bool isConditionalBranch(QueryType Type = AnyInBundle) const {
+    return isBranch(Type) & !isBarrier(Type) & !isIndirectBranch(Type);
+  }
+
+  /// isUnconditionalBranch - Return true if this is a branch which always
+  /// transfers control flow to some other block.  The
+  /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+  /// about this branch.
+  bool isUnconditionalBranch(QueryType Type = AnyInBundle) const {
+    return isBranch(Type) & isBarrier(Type) & !isIndirectBranch(Type);
+  }
+
+  /// Return true if this instruction has a predicate operand that
+  /// controls execution.  It may be set to 'always', or may be set to other
+  /// values.   There are various methods in TargetInstrInfo that can be used to
+  /// control and modify the predicate in this instruction.
+  bool isPredicable(QueryType Type = AllInBundle) const {
+    // If it's a bundle than all bundled instructions must be predicable for this
+    // to return true.
+    return hasProperty(MCID::Predicable, Type);
+  }
+
+  /// isCompare - Return true if this instruction is a comparison.
+  bool isCompare(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Compare, Type);
+  }
+
+  /// isMoveImmediate - Return true if this instruction is a move immediate
+  /// (including conditional moves) instruction.
+  bool isMoveImmediate(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::MoveImm, Type);
+  }
+
+  /// isBitcast - Return true if this instruction is a bitcast instruction.
+  ///
+  bool isBitcast(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Bitcast, Type);
+  }
+
+  /// isSelect - Return true if this instruction is a select instruction.
+  ///
+  bool isSelect(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Select, Type);
+  }
+
+  /// isNotDuplicable - Return true if this instruction cannot be safely
+  /// duplicated.  For example, if the instruction has a unique labels attached
+  /// to it, duplicating it would cause multiple definition errors.
+  bool isNotDuplicable(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::NotDuplicable, Type);
+  }
+
+  /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+  /// which must be filled by the code generator.
+  bool hasDelaySlot(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::DelaySlot, Type);
+  }
+
+  /// canFoldAsLoad - Return true for instructions that can be folded as
+  /// memory operands in other instructions. The most common use for this
+  /// is instructions that are simple loads from memory that don't modify
+  /// the loaded value in any way, but it can also be used for instructions
+  /// that can be expressed as constant-pool loads, such as V_SETALLONES
+  /// on x86, to allow them to be folded when it is beneficial.
+  /// This should only be set on instructions that return a value in their
+  /// only virtual register definition.
+  bool canFoldAsLoad(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::FoldableAsLoad, Type);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Side Effect Analysis
+  //===--------------------------------------------------------------------===//
+
+  /// mayLoad - Return true if this instruction could possibly read memory.
+  /// Instructions with this flag set are not necessarily simple load
+  /// instructions, they may load a value and modify it, for example.
+  bool mayLoad(QueryType Type = AnyInBundle) const {
+    if (isInlineAsm()) {
+      unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
+      if (ExtraInfo & InlineAsm::Extra_MayLoad)
+        return true;
+    }
+    return hasProperty(MCID::MayLoad, Type);
+  }
+
+
+  /// mayStore - Return true if this instruction could possibly modify memory.
+  /// Instructions with this flag set are not necessarily simple store
+  /// instructions, they may store a modified value based on their operands, or
+  /// may not actually modify anything, for example.
+  bool mayStore(QueryType Type = AnyInBundle) const {
+    if (isInlineAsm()) {
+      unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
+      if (ExtraInfo & InlineAsm::Extra_MayStore)
+        return true;
+    }
+    return hasProperty(MCID::MayStore, Type);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Flags that indicate whether an instruction can be modified by a method.
+  //===--------------------------------------------------------------------===//
+
+  /// isCommutable - Return true if this may be a 2- or 3-address
+  /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+  /// result if Y and Z are exchanged.  If this flag is set, then the
+  /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+  /// instruction.
+  ///
+  /// Note that this flag may be set on instructions that are only commutable
+  /// sometimes.  In these cases, the call to commuteInstruction will fail.
+  /// Also note that some instructions require non-trivial modification to
+  /// commute them.
+  bool isCommutable(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::Commutable, Type);
+  }
+
+  /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+  /// which can be changed into a 3-address instruction if needed.  Doing this
+  /// transformation can be profitable in the register allocator, because it
+  /// means that the instruction can use a 2-address form if possible, but
+  /// degrade into a less efficient form if the source and dest register cannot
+  /// be assigned to the same register.  For example, this allows the x86
+  /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+  /// is the same speed as the shift but has bigger code size.
+  ///
+  /// If this returns true, then the target must implement the
+  /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+  /// is allowed to fail if the transformation isn't valid for this specific
+  /// instruction (e.g. shl reg, 4 on x86).
+  ///
+  bool isConvertibleTo3Addr(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::ConvertibleTo3Addr, Type);
+  }
+
+  /// usesCustomInsertionHook - Return true if this instruction requires
+  /// custom insertion support when the DAG scheduler is inserting it into a
+  /// machine basic block.  If this is true for the instruction, it basically
+  /// means that it is a pseudo instruction used at SelectionDAG time that is
+  /// expanded out into magic code by the target when MachineInstrs are formed.
+  ///
+  /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+  /// is used to insert this into the MachineBasicBlock.
+  bool usesCustomInsertionHook(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::UsesCustomInserter, Type);
+  }
+
+  /// hasPostISelHook - Return true if this instruction requires *adjustment*
+  /// after instruction selection by calling a target hook. For example, this
+  /// can be used to fill in ARM 's' optional operand depending on whether
+  /// the conditional flag register is used.
+  bool hasPostISelHook(QueryType Type = IgnoreBundle) const {
+    return hasProperty(MCID::HasPostISelHook, Type);
+  }
+
+  /// isRematerializable - Returns true if this instruction is a candidate for
+  /// remat.  This flag is deprecated, please don't use it anymore.  If this
+  /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+  /// verify the instruction is really rematable.
+  bool isRematerializable(QueryType Type = AllInBundle) const {
+    // It's only possible to re-mat a bundle if all bundled instructions are
+    // re-materializable.
+    return hasProperty(MCID::Rematerializable, Type);
+  }
+
+  /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+  /// less) than a move instruction. This is useful during certain types of
+  /// optimizations (e.g., remat during two-address conversion or machine licm)
+  /// where we would like to remat or hoist the instruction, but not if it costs
+  /// more than moving the instruction into the appropriate register. Note, we
+  /// are not marking copies from and to the same register class with this flag.
+  bool isAsCheapAsAMove(QueryType Type = AllInBundle) const {
+    // Only returns true for a bundle if all bundled instructions are cheap.
+    // FIXME: This probably requires a target hook.
+    return hasProperty(MCID::CheapAsAMove, Type);
+  }
+
+  /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+  /// have special register allocation requirements that are not captured by the
+  /// operand register classes. e.g. ARM::STRD's two source registers must be an
+  /// even / odd pair, ARM::STM registers have to be in ascending order.
+  /// Post-register allocation passes should not attempt to change allocations
+  /// for sources of instructions with this flag.
+  bool hasExtraSrcRegAllocReq(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::ExtraSrcRegAllocReq, Type);
+  }
+
+  /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+  /// have special register allocation requirements that are not captured by the
+  /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+  /// even / odd pair, ARM::LDM registers have to be in ascending order.
+  /// Post-register allocation passes should not attempt to change allocations
+  /// for definitions of instructions with this flag.
+  bool hasExtraDefRegAllocReq(QueryType Type = AnyInBundle) const {
+    return hasProperty(MCID::ExtraDefRegAllocReq, Type);
+  }
+
+
+  enum MICheckType {
+    CheckDefs,      // Check all operands for equality
+    CheckKillDead,  // Check all operands including kill / dead markers
+    IgnoreDefs,     // Ignore all definitions
+    IgnoreVRegDefs  // Ignore virtual register definitions
+  };
+
+  /// isIdenticalTo - Return true if this instruction is identical to (same
+  /// opcode and same operands as) the specified instruction.
+  bool isIdenticalTo(const MachineInstr *Other,
+                     MICheckType Check = CheckDefs) const;
+
+  /// Unlink 'this' from the containing basic block, and return it without
+  /// deleting it.
+  ///
+  /// This function can not be used on bundled instructions, use
+  /// removeFromBundle() to remove individual instructions from a bundle.
+  MachineInstr *removeFromParent();
+
+  /// Unlink this instruction from its basic block and return it without
+  /// deleting it.
+  ///
+  /// If the instruction is part of a bundle, the other instructions in the
+  /// bundle remain bundled.
+  MachineInstr *removeFromBundle();
+
+  /// Unlink 'this' from the containing basic block and delete it.
+  ///
+  /// If this instruction is the header of a bundle, the whole bundle is erased.
+  /// This function can not be used for instructions inside a bundle, use
+  /// eraseFromBundle() to erase individual bundled instructions.
+  void eraseFromParent();
+
+  /// Unlink 'this' form its basic block and delete it.
+  ///
+  /// If the instruction is part of a bundle, the other instructions in the
+  /// bundle remain bundled.
+  void eraseFromBundle();
+
+  bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
+  bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
+
+  /// isLabel - Returns true if the MachineInstr represents a label.
+  ///
+  bool isLabel() const { return isEHLabel() || isGCLabel(); }
+  bool isCFIInstruction() const {
+    return getOpcode() == TargetOpcode::CFI_INSTRUCTION;
+  }
+
+  // True if the instruction represents a position in the function.
+  bool isPosition() const { return isLabel() || isCFIInstruction(); }
+
+  bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
+  /// A DBG_VALUE is indirect iff the first operand is a register and
+  /// the second operand is an immediate.
+  bool isIndirectDebugValue() const {
+    return isDebugValue()
+      && getOperand(0).isReg()
+      && getOperand(1).isImm();
+  }
+
+  bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
+  bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
+  bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
+  bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+  bool isMSInlineAsm() const { 
+    return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
+  }
+  bool isStackAligningInlineAsm() const;
+  InlineAsm::AsmDialect getInlineAsmDialect() const;
+  bool isInsertSubreg() const {
+    return getOpcode() == TargetOpcode::INSERT_SUBREG;
+  }
+  bool isSubregToReg() const {
+    return getOpcode() == TargetOpcode::SUBREG_TO_REG;
+  }
+  bool isRegSequence() const {
+    return getOpcode() == TargetOpcode::REG_SEQUENCE;
+  }
+  bool isBundle() const {
+    return getOpcode() == TargetOpcode::BUNDLE;
+  }
+  bool isCopy() const {
+    return getOpcode() == TargetOpcode::COPY;
+  }
+  bool isFullCopy() const {
+    return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
+  }
+  bool isExtractSubreg() const {
+    return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
+  }
+
+  /// isCopyLike - Return true if the instruction behaves like a copy.
+  /// This does not include native copy instructions.
+  bool isCopyLike() const {
+    return isCopy() || isSubregToReg();
+  }
+
+  /// isIdentityCopy - Return true is the instruction is an identity copy.
+  bool isIdentityCopy() const {
+    return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() &&
+      getOperand(0).getSubReg() == getOperand(1).getSubReg();
+  }
+
+  /// isTransient - Return true if this is a transient instruction that is
+  /// either very likely to be eliminated during register allocation (such as
+  /// copy-like instructions), or if this instruction doesn't have an
+  /// execution-time cost.
+  bool isTransient() const {
+    switch(getOpcode()) {
+    default: return false;
+    // Copy-like instructions are usually eliminated during register allocation.
+    case TargetOpcode::PHI:
+    case TargetOpcode::COPY:
+    case TargetOpcode::INSERT_SUBREG:
+    case TargetOpcode::SUBREG_TO_REG:
+    case TargetOpcode::REG_SEQUENCE:
+    // Pseudo-instructions that don't produce any real output.
+    case TargetOpcode::IMPLICIT_DEF:
+    case TargetOpcode::KILL:
+    case TargetOpcode::CFI_INSTRUCTION:
+    case TargetOpcode::EH_LABEL:
+    case TargetOpcode::GC_LABEL:
+    case TargetOpcode::DBG_VALUE:
+      return true;
+    }
+  }
+
+  /// Return the number of instructions inside the MI bundle, excluding the
+  /// bundle header.
+  ///
+  /// This is the number of instructions that MachineBasicBlock::iterator
+  /// skips, 0 for unbundled instructions.
+  unsigned getBundleSize() const;
+
+  /// readsRegister - Return true if the MachineInstr reads the specified
+  /// register. If TargetRegisterInfo is passed, then it also checks if there
+  /// is a read of a super-register.
+  /// This does not count partial redefines of virtual registers as reads:
+  ///   %reg1024:6 = OP.
+  bool readsRegister(unsigned Reg,
+                     const TargetRegisterInfo *TRI = nullptr) const {
+    return findRegisterUseOperandIdx(Reg, false, TRI) != -1;
+  }
+
+  /// readsVirtualRegister - Return true if the MachineInstr reads the specified
+  /// virtual register. Take into account that a partial define is a
+  /// read-modify-write operation.
+  bool readsVirtualRegister(unsigned Reg) const {
+    return readsWritesVirtualRegister(Reg).first;
+  }
+
+  /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
+  /// indicating if this instruction reads or writes Reg. This also considers
+  /// partial defines.
+  /// If Ops is not null, all operand indices for Reg are added.
+  std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg,
+                                SmallVectorImpl<unsigned> *Ops = nullptr) const;
+
+  /// killsRegister - Return true if the MachineInstr kills the specified
+  /// register. If TargetRegisterInfo is passed, then it also checks if there is
+  /// a kill of a super-register.
+  bool killsRegister(unsigned Reg,
+                     const TargetRegisterInfo *TRI = nullptr) const {
+    return findRegisterUseOperandIdx(Reg, true, TRI) != -1;
+  }
+
+  /// definesRegister - Return true if the MachineInstr fully defines the
+  /// specified register. If TargetRegisterInfo is passed, then it also checks
+  /// if there is a def of a super-register.
+  /// NOTE: It's ignoring subreg indices on virtual registers.
+  bool definesRegister(unsigned Reg,
+                       const TargetRegisterInfo *TRI = nullptr) const {
+    return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1;
+  }
+
+  /// modifiesRegister - Return true if the MachineInstr modifies (fully define
+  /// or partially define) the specified register.
+  /// NOTE: It's ignoring subreg indices on virtual registers.
+  bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const {
+    return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1;
+  }
+
+  /// registerDefIsDead - Returns true if the register is dead in this machine
+  /// instruction. If TargetRegisterInfo is passed, then it also checks
+  /// if there is a dead def of a super-register.
+  bool registerDefIsDead(unsigned Reg,
+                         const TargetRegisterInfo *TRI = nullptr) const {
+    return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1;
+  }
+
+  /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+  /// the specific register or -1 if it is not found. It further tightens
+  /// the search criteria to a use that kills the register if isKill is true.
+  int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false,
+                                const TargetRegisterInfo *TRI = nullptr) const;
+
+  /// findRegisterUseOperand - Wrapper for findRegisterUseOperandIdx, it returns
+  /// a pointer to the MachineOperand rather than an index.
+  MachineOperand *findRegisterUseOperand(unsigned Reg, bool isKill = false,
+                                      const TargetRegisterInfo *TRI = nullptr) {
+    int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI);
+    return (Idx == -1) ? nullptr : &getOperand(Idx);
+  }
+
+  /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
+  /// the specified register or -1 if it is not found. If isDead is true, defs
+  /// that are not dead are skipped. If Overlap is true, then it also looks for
+  /// defs that merely overlap the specified register. If TargetRegisterInfo is
+  /// non-null, then it also checks if there is a def of a super-register.
+  /// This may also return a register mask operand when Overlap is true.
+  int findRegisterDefOperandIdx(unsigned Reg,
+                                bool isDead = false, bool Overlap = false,
+                                const TargetRegisterInfo *TRI = nullptr) const;
+
+  /// findRegisterDefOperand - Wrapper for findRegisterDefOperandIdx, it returns
+  /// a pointer to the MachineOperand rather than an index.
+  MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false,
+                                      const TargetRegisterInfo *TRI = nullptr) {
+    int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI);
+    return (Idx == -1) ? nullptr : &getOperand(Idx);
+  }
+
+  /// findFirstPredOperandIdx() - Find the index of the first operand in the
+  /// operand list that is used to represent the predicate. It returns -1 if
+  /// none is found.
+  int findFirstPredOperandIdx() const;
+
+  /// findInlineAsmFlagIdx() - Find the index of the flag word operand that
+  /// corresponds to operand OpIdx on an inline asm instruction.  Returns -1 if
+  /// getOperand(OpIdx) does not belong to an inline asm operand group.
+  ///
+  /// If GroupNo is not NULL, it will receive the number of the operand group
+  /// containing OpIdx.
+  ///
+  /// The flag operand is an immediate that can be decoded with methods like
+  /// InlineAsm::hasRegClassConstraint().
+  ///
+  int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = nullptr) const;
+
+  /// getRegClassConstraint - Compute the static register class constraint for
+  /// operand OpIdx.  For normal instructions, this is derived from the
+  /// MCInstrDesc.  For inline assembly it is derived from the flag words.
+  ///
+  /// Returns NULL if the static register classs constraint cannot be
+  /// determined.
+  ///
+  const TargetRegisterClass*
+  getRegClassConstraint(unsigned OpIdx,
+                        const TargetInstrInfo *TII,
+                        const TargetRegisterInfo *TRI) const;
+
+  /// \brief Applies the constraints (def/use) implied by this MI on \p Reg to
+  /// the given \p CurRC.
+  /// If \p ExploreBundle is set and MI is part of a bundle, all the
+  /// instructions inside the bundle will be taken into account. In other words,
+  /// this method accumulates all the constrains of the operand of this MI and
+  /// the related bundle if MI is a bundle or inside a bundle.
+  ///
+  /// Returns the register class that statisfies both \p CurRC and the
+  /// constraints set by MI. Returns NULL if such a register class does not
+  /// exist.
+  ///
+  /// \pre CurRC must not be NULL.
+  const TargetRegisterClass *getRegClassConstraintEffectForVReg(
+      unsigned Reg, const TargetRegisterClass *CurRC,
+      const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+      bool ExploreBundle = false) const;
+
+  /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand
+  /// to the given \p CurRC.
+  ///
+  /// Returns the register class that statisfies both \p CurRC and the
+  /// constraints set by \p OpIdx MI. Returns NULL if such a register class
+  /// does not exist.
+  ///
+  /// \pre CurRC must not be NULL.
+  /// \pre The operand at \p OpIdx must be a register.
+  const TargetRegisterClass *
+  getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
+                              const TargetInstrInfo *TII,
+                              const TargetRegisterInfo *TRI) const;
+
+  /// tieOperands - Add a tie between the register operands at DefIdx and
+  /// UseIdx. The tie will cause the register allocator to ensure that the two
+  /// operands are assigned the same physical register.
+  ///
+  /// Tied operands are managed automatically for explicit operands in the
+  /// MCInstrDesc. This method is for exceptional cases like inline asm.
+  void tieOperands(unsigned DefIdx, unsigned UseIdx);
+
+  /// findTiedOperandIdx - Given the index of a tied register operand, find the
+  /// operand it is tied to. Defs are tied to uses and vice versa. Returns the
+  /// index of the tied operand which must exist.
+  unsigned findTiedOperandIdx(unsigned OpIdx) const;
+
+  /// isRegTiedToUseOperand - Given the index of a register def operand,
+  /// check if the register def is tied to a source operand, due to either
+  /// two-address elimination or inline assembly constraints. Returns the
+  /// first tied use operand index by reference if UseOpIdx is not null.
+  bool isRegTiedToUseOperand(unsigned DefOpIdx,
+                             unsigned *UseOpIdx = nullptr) const {
+    const MachineOperand &MO = getOperand(DefOpIdx);
+    if (!MO.isReg() || !MO.isDef() || !MO.isTied())
+      return false;
+    if (UseOpIdx)
+      *UseOpIdx = findTiedOperandIdx(DefOpIdx);
+    return true;
+  }
+
+  /// isRegTiedToDefOperand - Return true if the use operand of the specified
+  /// index is tied to a def operand. It also returns the def operand index by
+  /// reference if DefOpIdx is not null.
+  bool isRegTiedToDefOperand(unsigned UseOpIdx,
+                             unsigned *DefOpIdx = nullptr) const {
+    const MachineOperand &MO = getOperand(UseOpIdx);
+    if (!MO.isReg() || !MO.isUse() || !MO.isTied())
+      return false;
+    if (DefOpIdx)
+      *DefOpIdx = findTiedOperandIdx(UseOpIdx);
+    return true;
+  }
+
+  /// clearKillInfo - Clears kill flags on all operands.
+  ///
+  void clearKillInfo();
+
+  /// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx,
+  /// properly composing subreg indices where necessary.
+  void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx,
+                          const TargetRegisterInfo &RegInfo);
+
+  /// addRegisterKilled - We have determined MI kills a register. Look for the
+  /// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
+  /// add a implicit operand if it's not found. Returns true if the operand
+  /// exists / is added.
+  bool addRegisterKilled(unsigned IncomingReg,
+                         const TargetRegisterInfo *RegInfo,
+                         bool AddIfNotFound = false);
+
+  /// clearRegisterKills - Clear all kill flags affecting Reg.  If RegInfo is
+  /// provided, this includes super-register kills.
+  void clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo);
+
+  /// addRegisterDead - We have determined MI defined a register without a use.
+  /// Look for the operand that defines it and mark it as IsDead. If
+  /// AddIfNotFound is true, add a implicit operand if it's not found. Returns
+  /// true if the operand exists / is added.
+  bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
+                       bool AddIfNotFound = false);
+
+  /// addRegisterDefined - We have determined MI defines a register. Make sure
+  /// there is an operand defining Reg.
+  void addRegisterDefined(unsigned Reg,
+                          const TargetRegisterInfo *RegInfo = nullptr);
+
+  /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as
+  /// dead except those in the UsedRegs list.
+  ///
+  /// On instructions with register mask operands, also add implicit-def
+  /// operands for all registers in UsedRegs.
+  void setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,
+                             const TargetRegisterInfo &TRI);
+
+  /// isSafeToMove - Return true if it is safe to move this instruction. If
+  /// SawStore is set to true, it means that there is a store (or call) between
+  /// the instruction's location and its intended destination.
+  bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA,
+                    bool &SawStore) const;
+
+  /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
+  /// or volatile memory reference, or if the information describing the memory
+  /// reference is not available. Return false if it is known to have no
+  /// ordered or volatile memory references.
+  bool hasOrderedMemoryRef() const;
+
+  /// isInvariantLoad - Return true if this instruction is loading from a
+  /// location whose value is invariant across the function.  For example,
+  /// loading a value from the constant pool or from the argument area of
+  /// a function if it does not change.  This should only return true of *all*
+  /// loads the instruction does are invariant (if it does multiple loads).
+  bool isInvariantLoad(AliasAnalysis *AA) const;
+
+  /// isConstantValuePHI - If the specified instruction is a PHI that always
+  /// merges together the same virtual register, return the register, otherwise
+  /// return 0.
+  unsigned isConstantValuePHI() const;
+
+  /// hasUnmodeledSideEffects - Return true if this instruction has side
+  /// effects that are not modeled by mayLoad / mayStore, etc.
+  /// For all instructions, the property is encoded in MCInstrDesc::Flags
+  /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is
+  /// INLINEASM instruction, in which case the side effect property is encoded
+  /// in one of its operands (see InlineAsm::Extra_HasSideEffect).
+  ///
+  bool hasUnmodeledSideEffects() const;
+
+  /// allDefsAreDead - Return true if all the defs of this instruction are dead.
+  ///
+  bool allDefsAreDead() const;
+
+  /// copyImplicitOps - Copy implicit register operands from specified
+  /// instruction to this instruction.
+  void copyImplicitOps(MachineFunction &MF, const MachineInstr *MI);
+
+  //
+  // Debugging support
+  //
+  void print(raw_ostream &OS, const TargetMachine *TM = nullptr,
+             bool SkipOpers = false) const;
+  void dump() const;
+
+  //===--------------------------------------------------------------------===//
+  // Accessors used to build up machine instructions.
+
+  /// Add the specified operand to the instruction.  If it is an implicit
+  /// operand, it is added to the end of the operand list.  If it is an
+  /// explicit operand it is added at the end of the explicit operand list
+  /// (before the first implicit operand).
+  ///
+  /// MF must be the machine function that was used to allocate this
+  /// instruction.
+  ///
+  /// MachineInstrBuilder provides a more convenient interface for creating
+  /// instructions and adding operands.
+  void addOperand(MachineFunction &MF, const MachineOperand &Op);
+
+  /// Add an operand without providing an MF reference. This only works for
+  /// instructions that are inserted in a basic block.
+  ///
+  /// MachineInstrBuilder and the two-argument addOperand(MF, MO) should be
+  /// preferred.
+  void addOperand(const MachineOperand &Op);
+
+  /// setDesc - Replace the instruction descriptor (thus opcode) of
+  /// the current instruction with a new one.
+  ///
+  void setDesc(const MCInstrDesc &tid) { MCID = &tid; }
+
+  /// setDebugLoc - Replace current source information with new such.
+  /// Avoid using this, the constructor argument is preferable.
+  ///
+  void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
+  /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
+  /// fewer operand than it started with.
+  ///
+  void RemoveOperand(unsigned i);
+
+  /// addMemOperand - Add a MachineMemOperand to the machine instruction.
+  /// This function should be used only occasionally. The setMemRefs function
+  /// is the primary method for setting up a MachineInstr's MemRefs list.
+  void addMemOperand(MachineFunction &MF, MachineMemOperand *MO);
+
+  /// setMemRefs - Assign this MachineInstr's memory reference descriptor
+  /// list. This does not transfer ownership.
+  void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
+    MemRefs = NewMemRefs;
+    NumMemRefs = uint8_t(NewMemRefsEnd - NewMemRefs);
+    assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs");
+  }
+
+private:
+  /// getRegInfo - If this instruction is embedded into a MachineFunction,
+  /// return the MachineRegisterInfo object for the current function, otherwise
+  /// return null.
+  MachineRegisterInfo *getRegInfo();
+
+  /// untieRegOperand - Break any tie involving OpIdx.
+  void untieRegOperand(unsigned OpIdx) {
+    MachineOperand &MO = getOperand(OpIdx);
+    if (MO.isReg() && MO.isTied()) {
+      getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0;
+      MO.TiedTo = 0;
+    }
+  }
+
+  /// addImplicitDefUseOperands - Add all implicit def and use operands to
+  /// this instruction.
+  void addImplicitDefUseOperands(MachineFunction &MF);
+
+  /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
+  /// this instruction from their respective use lists.  This requires that the
+  /// operands already be on their use lists.
+  void RemoveRegOperandsFromUseLists(MachineRegisterInfo&);
+
+  /// AddRegOperandsToUseLists - Add all of the register operands in
+  /// this instruction from their respective use lists.  This requires that the
+  /// operands not be on their use lists yet.
+  void AddRegOperandsToUseLists(MachineRegisterInfo&);
+
+  /// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a
+  /// bundle.
+  bool hasPropertyInBundle(unsigned Mask, QueryType Type) const;
+
+  /// \brief Implements the logic of getRegClassConstraintEffectForVReg for the
+  /// this MI and the given operand index \p OpIdx.
+  /// If the related operand does not constrained Reg, this returns CurRC.
+  const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
+      unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC,
+      const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+};
+
+/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare
+/// MachineInstr* by *value* of the instruction rather than by pointer value.
+/// The hashing and equality testing functions ignore definitions so this is
+/// useful for CSE, etc.
+struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
+  static inline MachineInstr *getEmptyKey() {
+    return nullptr;
+  }
+
+  static inline MachineInstr *getTombstoneKey() {
+    return reinterpret_cast<MachineInstr*>(-1);
+  }
+
+  static unsigned getHashValue(const MachineInstr* const &MI);
+
+  static bool isEqual(const MachineInstr* const &LHS,
+                      const MachineInstr* const &RHS) {
+    if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+        LHS == getEmptyKey() || LHS == getTombstoneKey())
+      return LHS == RHS;
+    return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) {
+  MI.print(OS);
+  return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
new file mode 100644
index 0000000..21a482c
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -0,0 +1,497 @@
+//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes a function named BuildMI, which is useful for dramatically
+// simplifying how MachineInstr's are created.  It allows use of code like this:
+//
+//   M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class MCInstrDesc;
+class MDNode;
+
+namespace RegState {
+  enum {
+    Define         = 0x2,
+    Implicit       = 0x4,
+    Kill           = 0x8,
+    Dead           = 0x10,
+    Undef          = 0x20,
+    EarlyClobber   = 0x40,
+    Debug          = 0x80,
+    InternalRead   = 0x100,
+    DefineNoRead   = Define | Undef,
+    ImplicitDefine = Implicit | Define,
+    ImplicitKill   = Implicit | Kill
+  };
+}
+
+class MachineInstrBuilder {
+  MachineFunction *MF;
+  MachineInstr *MI;
+public:
+  MachineInstrBuilder() : MF(nullptr), MI(nullptr) {}
+
+  /// Create a MachineInstrBuilder for manipulating an existing instruction.
+  /// F must be the machine function  that was used to allocate I.
+  MachineInstrBuilder(MachineFunction &F, MachineInstr *I) : MF(&F), MI(I) {}
+
+  /// Allow automatic conversion to the machine instruction we are working on.
+  ///
+  operator MachineInstr*() const { return MI; }
+  MachineInstr *operator->() const { return MI; }
+  operator MachineBasicBlock::iterator() const { return MI; }
+
+  /// addReg - Add a new virtual register operand...
+  ///
+  const
+  MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
+                              unsigned SubReg = 0) const {
+    assert((flags & 0x1) == 0 &&
+           "Passing in 'true' to addReg is forbidden! Use enums instead.");
+    MI->addOperand(*MF, MachineOperand::CreateReg(RegNo,
+                                               flags & RegState::Define,
+                                               flags & RegState::Implicit,
+                                               flags & RegState::Kill,
+                                               flags & RegState::Dead,
+                                               flags & RegState::Undef,
+                                               flags & RegState::EarlyClobber,
+                                               SubReg,
+                                               flags & RegState::Debug,
+                                               flags & RegState::InternalRead));
+    return *this;
+  }
+
+  /// addImm - Add a new immediate operand.
+  ///
+  const MachineInstrBuilder &addImm(int64_t Val) const {
+    MI->addOperand(*MF, MachineOperand::CreateImm(Val));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
+    MI->addOperand(*MF, MachineOperand::CreateCImm(Val));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
+    MI->addOperand(*MF, MachineOperand::CreateFPImm(Val));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
+                                    unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateMBB(MBB, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addFrameIndex(int Idx) const {
+    MI->addOperand(*MF, MachineOperand::CreateFI(Idx));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
+                                                  int Offset = 0,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateTargetIndex(Idx, Offset,
+                                                          TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateJTI(Idx, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
+                                              int64_t Offset = 0,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateGA(GV, Offset, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addExternalSymbol(const char *FnName,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateES(FnName, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addBlockAddress(const BlockAddress *BA,
+                                             int64_t Offset = 0,
+                                          unsigned char TargetFlags = 0) const {
+    MI->addOperand(*MF, MachineOperand::CreateBA(BA, Offset, TargetFlags));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
+    MI->addOperand(*MF, MachineOperand::CreateRegMask(Mask));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
+    MI->addMemOperand(*MF, MMO);
+    return *this;
+  }
+
+  const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b,
+                                        MachineInstr::mmo_iterator e) const {
+    MI->setMemRefs(b, e);
+    return *this;
+  }
+
+
+  const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
+    MI->addOperand(*MF, MO);
+    return *this;
+  }
+
+  const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
+    MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addCFIIndex(unsigned CFIIndex) const {
+    MI->addOperand(*MF, MachineOperand::CreateCFIIndex(CFIIndex));
+    return *this;
+  }
+
+  const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
+    MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym));
+    return *this;
+  }
+
+  const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
+    MI->setFlags(Flags);
+    return *this;
+  }
+
+  const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
+    MI->setFlag(Flag);
+    return *this;
+  }
+
+  // Add a displacement from an existing MachineOperand with an added offset.
+  const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off,
+                                     unsigned char TargetFlags = 0) const {
+    switch (Disp.getType()) {
+      default:
+        llvm_unreachable("Unhandled operand type in addDisp()");
+      case MachineOperand::MO_Immediate:
+        return addImm(Disp.getImm() + off);
+      case MachineOperand::MO_GlobalAddress: {
+        // If caller specifies new TargetFlags then use it, otherwise the
+        // default behavior is to copy the target flags from the existing
+        // MachineOperand. This means if the caller wants to clear the
+        // target flags it needs to do so explicitly.
+        if (TargetFlags)
+          return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+                                  TargetFlags);
+        return addGlobalAddress(Disp.getGlobal(), Disp.getOffset() + off,
+                                Disp.getTargetFlags());
+      }
+    }
+  }
+
+  /// Copy all the implicit operands from OtherMI onto this one.
+  const MachineInstrBuilder &copyImplicitOps(const MachineInstr *OtherMI) {
+    MI->copyImplicitOps(*MF, OtherMI);
+    return *this;
+  }
+};
+
+/// BuildMI - Builder interface.  Specify how to create the initial instruction
+/// itself.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID) {
+  return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL));
+}
+
+/// BuildMI - This version of the builder sets up the first operand as a
+/// destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   unsigned DestReg) {
+  return MachineInstrBuilder(MF, MF.CreateMachineInstr(MCID, DL))
+           .addReg(DestReg, RegState::Define);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// sets up the first operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineBasicBlock::iterator I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   unsigned DestReg) {
+  MachineFunction &MF = *BB.getParent();
+  MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
+  BB.insert(I, MI);
+  return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineBasicBlock::instr_iterator I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   unsigned DestReg) {
+  MachineFunction &MF = *BB.getParent();
+  MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
+  BB.insert(I, MI);
+  return MachineInstrBuilder(MF, MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineInstr *I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   unsigned DestReg) {
+  if (I->isInsideBundle()) {
+    MachineBasicBlock::instr_iterator MII = I;
+    return BuildMI(BB, MII, DL, MCID, DestReg);
+  }
+
+  MachineBasicBlock::iterator MII = I;
+  return BuildMI(BB, MII, DL, MCID, DestReg);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// does NOT take a destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineBasicBlock::iterator I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID) {
+  MachineFunction &MF = *BB.getParent();
+  MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
+  BB.insert(I, MI);
+  return MachineInstrBuilder(MF, MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineBasicBlock::instr_iterator I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID) {
+  MachineFunction &MF = *BB.getParent();
+  MachineInstr *MI = MF.CreateMachineInstr(MCID, DL);
+  BB.insert(I, MI);
+  return MachineInstrBuilder(MF, MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineInstr *I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID) {
+  if (I->isInsideBundle()) {
+    MachineBasicBlock::instr_iterator MII = I;
+    return BuildMI(BB, MII, DL, MCID);
+  }
+
+  MachineBasicBlock::iterator MII = I;
+  return BuildMI(BB, MII, DL, MCID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and does NOT take a
+/// destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID) {
+  return BuildMI(*BB, BB->end(), DL, MCID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and sets up the first
+/// operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   unsigned DestReg) {
+  return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
+}
+
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address.  The convention is that a DBG_VALUE is indirect iff the
+/// second operand is an immediate.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   bool IsIndirect,
+                                   unsigned Reg,
+                                   unsigned Offset,
+                                   const MDNode *MD) {
+  if (IsIndirect)
+    return BuildMI(MF, DL, MCID)
+      .addReg(Reg, RegState::Debug)
+      .addImm(Offset)
+      .addMetadata(MD);
+  else {
+    assert(Offset == 0 && "A direct address cannot have an offset.");
+    return BuildMI(MF, DL, MCID)
+      .addReg(Reg, RegState::Debug)
+      .addReg(0U, RegState::Debug)
+      .addMetadata(MD);
+  }
+}
+
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address and inserts it at position I.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+                                   MachineBasicBlock::iterator I,
+                                   DebugLoc DL,
+                                   const MCInstrDesc &MCID,
+                                   bool IsIndirect,
+                                   unsigned Reg,
+                                   unsigned Offset,
+                                   const MDNode *MD) {
+  MachineFunction &MF = *BB.getParent();
+  MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, MD);
+  BB.insert(I, MI);
+  return MachineInstrBuilder(MF, MI);
+}
+
+
+inline unsigned getDefRegState(bool B) {
+  return B ? RegState::Define : 0;
+}
+inline unsigned getImplRegState(bool B) {
+  return B ? RegState::Implicit : 0;
+}
+inline unsigned getKillRegState(bool B) {
+  return B ? RegState::Kill : 0;
+}
+inline unsigned getDeadRegState(bool B) {
+  return B ? RegState::Dead : 0;
+}
+inline unsigned getUndefRegState(bool B) {
+  return B ? RegState::Undef : 0;
+}
+inline unsigned getInternalReadRegState(bool B) {
+  return B ? RegState::InternalRead : 0;
+}
+inline unsigned getDebugRegState(bool B) {
+  return B ? RegState::Debug : 0;
+}
+
+
+/// Helper class for constructing bundles of MachineInstrs.
+///
+/// MIBundleBuilder can create a bundle from scratch by inserting new
+/// MachineInstrs one at a time, or it can create a bundle from a sequence of
+/// existing MachineInstrs in a basic block.
+class MIBundleBuilder {
+  MachineBasicBlock &MBB;
+  MachineBasicBlock::instr_iterator Begin;
+  MachineBasicBlock::instr_iterator End;
+
+public:
+  /// Create an MIBundleBuilder that inserts instructions into a new bundle in
+  /// BB above the bundle or instruction at Pos.
+  MIBundleBuilder(MachineBasicBlock &BB,
+                  MachineBasicBlock::iterator Pos)
+    : MBB(BB), Begin(Pos.getInstrIterator()), End(Begin) {}
+
+  /// Create a bundle from the sequence of instructions between B and E.
+  MIBundleBuilder(MachineBasicBlock &BB,
+                  MachineBasicBlock::iterator B,
+                  MachineBasicBlock::iterator E)
+    : MBB(BB), Begin(B.getInstrIterator()), End(E.getInstrIterator()) {
+    assert(B != E && "No instructions to bundle");
+    ++B;
+    while (B != E) {
+      MachineInstr *MI = B;
+      ++B;
+      MI->bundleWithPred();
+    }
+  }
+
+  /// Create an MIBundleBuilder representing an existing instruction or bundle
+  /// that has MI as its head.
+  explicit MIBundleBuilder(MachineInstr *MI)
+    : MBB(*MI->getParent()), Begin(MI), End(getBundleEnd(MI)) {}
+
+  /// Return a reference to the basic block containing this bundle.
+  MachineBasicBlock &getMBB() const { return MBB; }
+
+  /// Return true if no instructions have been inserted in this bundle yet.
+  /// Empty bundles aren't representable in a MachineBasicBlock.
+  bool empty() const { return Begin == End; }
+
+  /// Return an iterator to the first bundled instruction.
+  MachineBasicBlock::instr_iterator begin() const { return Begin; }
+
+  /// Return an iterator beyond the last bundled instruction.
+  MachineBasicBlock::instr_iterator end() const { return End; }
+
+  /// Insert MI into this bundle before I which must point to an instruction in
+  /// the bundle, or end().
+  MIBundleBuilder &insert(MachineBasicBlock::instr_iterator I,
+                          MachineInstr *MI) {
+    MBB.insert(I, MI);
+    if (I == Begin) {
+      if (!empty())
+        MI->bundleWithSucc();
+      Begin = MI;
+      return *this;
+    }
+    if (I == End) {
+      MI->bundleWithPred();
+      return *this;
+    }
+    // MI was inserted in the middle of the bundle, so its neighbors' flags are
+    // already fine. Update MI's bundle flags manually.
+    MI->setFlag(MachineInstr::BundledPred);
+    MI->setFlag(MachineInstr::BundledSucc);
+    return *this;
+  }
+
+  /// Insert MI into MBB by prepending it to the instructions in the bundle.
+  /// MI will become the first instruction in the bundle.
+  MIBundleBuilder &prepend(MachineInstr *MI) {
+    return insert(begin(), MI);
+  }
+
+  /// Insert MI into MBB by appending it to the instructions in the bundle.
+  /// MI will become the last instruction in the bundle.
+  MIBundleBuilder &append(MachineInstr *MI) {
+    return insert(end(), MI);
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
new file mode 100644
index 0000000..1220224
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -0,0 +1,252 @@
+//===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provide utility functions to manipulate machine instruction
+// bundles.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+#define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+namespace llvm {
+
+/// finalizeBundle - Finalize a machine instruction bundle which includes
+/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
+/// This routine adds a BUNDLE instruction to represent the bundle, it adds
+/// IsInternalRead markers to MachineOperands which are defined inside the
+/// bundle, and it copies externally visible defs and uses to the BUNDLE
+/// instruction.
+void finalizeBundle(MachineBasicBlock &MBB,
+                    MachineBasicBlock::instr_iterator FirstMI,
+                    MachineBasicBlock::instr_iterator LastMI);
+  
+/// finalizeBundle - Same functionality as the previous finalizeBundle except
+/// the last instruction in the bundle is not provided as an input. This is
+/// used in cases where bundles are pre-determined by marking instructions
+/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
+/// points to the end of the bundle.
+MachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB,
+                    MachineBasicBlock::instr_iterator FirstMI);
+
+/// finalizeBundles - Finalize instruction bundles in the specified
+/// MachineFunction. Return true if any bundles are finalized.
+bool finalizeBundles(MachineFunction &MF);
+
+/// getBundleStart - Returns the first instruction in the bundle containing MI.
+///
+inline MachineInstr *getBundleStart(MachineInstr *MI) {
+  MachineBasicBlock::instr_iterator I = MI;
+  while (I->isBundledWithPred())
+    --I;
+  return I;
+}
+
+inline const MachineInstr *getBundleStart(const MachineInstr *MI) {
+  MachineBasicBlock::const_instr_iterator I = MI;
+  while (I->isBundledWithPred())
+    --I;
+  return I;
+}
+
+/// Return an iterator pointing beyond the bundle containing MI.
+inline MachineBasicBlock::instr_iterator
+getBundleEnd(MachineInstr *MI) {
+  MachineBasicBlock::instr_iterator I = MI;
+  while (I->isBundledWithSucc())
+    ++I;
+  return ++I;
+}
+
+/// Return an iterator pointing beyond the bundle containing MI.
+inline MachineBasicBlock::const_instr_iterator
+getBundleEnd(const MachineInstr *MI) {
+  MachineBasicBlock::const_instr_iterator I = MI;
+  while (I->isBundledWithSucc())
+    ++I;
+  return ++I;
+}
+
+//===----------------------------------------------------------------------===//
+// MachineOperand iterator
+//
+
+/// MachineOperandIteratorBase - Iterator that can visit all operands on a
+/// MachineInstr, or all operands on a bundle of MachineInstrs.  This class is
+/// not intended to be used directly, use one of the sub-classes instead.
+///
+/// Intended use:
+///
+///   for (MIBundleOperands MIO(MI); MIO.isValid(); ++MIO) {
+///     if (!MIO->isReg())
+///       continue;
+///     ...
+///   }
+///
+class MachineOperandIteratorBase {
+  MachineBasicBlock::instr_iterator InstrI, InstrE;
+  MachineInstr::mop_iterator OpI, OpE;
+
+  // If the operands on InstrI are exhausted, advance InstrI to the next
+  // bundled instruction with operands.
+  void advance() {
+    while (OpI == OpE) {
+      // Don't advance off the basic block, or into a new bundle.
+      if (++InstrI == InstrE || !InstrI->isInsideBundle())
+        break;
+      OpI = InstrI->operands_begin();
+      OpE = InstrI->operands_end();
+    }
+  }
+
+protected:
+  /// MachineOperandIteratorBase - Create an iterator that visits all operands
+  /// on MI, or all operands on every instruction in the bundle containing MI.
+  ///
+  /// @param MI The instruction to examine.
+  /// @param WholeBundle When true, visit all operands on the entire bundle.
+  ///
+  explicit MachineOperandIteratorBase(MachineInstr *MI, bool WholeBundle) {
+    if (WholeBundle) {
+      InstrI = getBundleStart(MI);
+      InstrE = MI->getParent()->instr_end();
+    } else {
+      InstrI = InstrE = MI;
+      ++InstrE;
+    }
+    OpI = InstrI->operands_begin();
+    OpE = InstrI->operands_end();
+    if (WholeBundle)
+      advance();
+  }
+
+  MachineOperand &deref() const { return *OpI; }
+
+public:
+  /// isValid - Returns true until all the operands have been visited.
+  bool isValid() const { return OpI != OpE; }
+
+  /// Preincrement.  Move to the next operand.
+  void operator++() {
+    assert(isValid() && "Cannot advance MIOperands beyond the last operand");
+    ++OpI;
+    advance();
+  }
+
+  /// getOperandNo - Returns the number of the current operand relative to its
+  /// instruction.
+  ///
+  unsigned getOperandNo() const {
+    return OpI - InstrI->operands_begin();
+  }
+
+  /// VirtRegInfo - Information about a virtual register used by a set of operands.
+  ///
+  struct VirtRegInfo {
+    /// Reads - One of the operands read the virtual register.  This does not
+    /// include <undef> or <internal> use operands, see MO::readsReg().
+    bool Reads;
+
+    /// Writes - One of the operands writes the virtual register.
+    bool Writes;
+
+    /// Tied - Uses and defs must use the same register. This can be because of
+    /// a two-address constraint, or there may be a partial redefinition of a
+    /// sub-register.
+    bool Tied;
+  };
+
+  /// PhysRegInfo - Information about a physical register used by a set of
+  /// operands.
+  struct PhysRegInfo {
+    /// Clobbers - Reg or an overlapping register is defined, or a regmask
+    /// clobbers Reg.
+    bool Clobbers;
+
+    /// Defines - Reg or a super-register is defined.
+    bool Defines;
+
+    /// Reads - Read or a super-register is read.
+    bool Reads;
+
+    /// ReadsOverlap - Reg or an overlapping register is read.
+    bool ReadsOverlap;
+
+    /// DefinesDead - All defs of a Reg or a super-register are dead.
+    bool DefinesDead;
+
+    /// There is a kill of Reg or a super-register.
+    bool Kills;
+  };
+
+  /// analyzeVirtReg - Analyze how the current instruction or bundle uses a
+  /// virtual register.  This function should not be called after operator++(),
+  /// it expects a fresh iterator.
+  ///
+  /// @param Reg The virtual register to analyze.
+  /// @param Ops When set, this vector will receive an (MI, OpNum) entry for
+  ///            each operand referring to Reg.
+  /// @returns A filled-in RegInfo struct.
+  VirtRegInfo analyzeVirtReg(unsigned Reg,
+           SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = nullptr);
+
+  /// analyzePhysReg - Analyze how the current instruction or bundle uses a
+  /// physical register.  This function should not be called after operator++(),
+  /// it expects a fresh iterator.
+  ///
+  /// @param Reg The physical register to analyze.
+  /// @returns A filled-in PhysRegInfo struct.
+  PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI);
+};
+
+/// MIOperands - Iterate over operands of a single instruction.
+///
+class MIOperands : public MachineOperandIteratorBase {
+public:
+  MIOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, false) {}
+  MachineOperand &operator* () const { return deref(); }
+  MachineOperand *operator->() const { return &deref(); }
+};
+
+/// ConstMIOperands - Iterate over operands of a single const instruction.
+///
+class ConstMIOperands : public MachineOperandIteratorBase {
+public:
+  ConstMIOperands(const MachineInstr *MI)
+    : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), false) {}
+  const MachineOperand &operator* () const { return deref(); }
+  const MachineOperand *operator->() const { return &deref(); }
+};
+
+/// MIBundleOperands - Iterate over all operands in a bundle of machine
+/// instructions.
+///
+class MIBundleOperands : public MachineOperandIteratorBase {
+public:
+  MIBundleOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, true) {}
+  MachineOperand &operator* () const { return deref(); }
+  MachineOperand *operator->() const { return &deref(); }
+};
+
+/// ConstMIBundleOperands - Iterate over all operands in a const bundle of
+/// machine instructions.
+///
+class ConstMIBundleOperands : public MachineOperandIteratorBase {
+public:
+  ConstMIBundleOperands(const MachineInstr *MI)
+    : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), true) {}
+  const MachineOperand &operator* () const { return deref(); }
+  const MachineOperand *operator->() const { return &deref(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
new file mode 100644
index 0000000..adcd1d0
--- /dev/null
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -0,0 +1,130 @@
+//===-- CodeGen/MachineJumpTableInfo.h - Abstract Jump Tables  --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MachineJumpTableInfo class keeps track of jump tables referenced by
+// lowered switch instructions in the MachineFunction.
+//
+// Instructions reference the address of these jump tables through the use of
+// MO_JumpTableIndex values.  When emitting assembly or machine code, these
+// virtual address references are converted to refer to the address of the
+// function jump tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class DataLayout;
+class raw_ostream;
+
+/// MachineJumpTableEntry - One jump table in the jump table info.
+///
+struct MachineJumpTableEntry {
+  /// MBBs - The vector of basic blocks from which to create the jump table.
+  std::vector<MachineBasicBlock*> MBBs;
+
+  explicit MachineJumpTableEntry(const std::vector<MachineBasicBlock*> &M)
+  : MBBs(M) {}
+};
+
+class MachineJumpTableInfo {
+public:
+  /// JTEntryKind - This enum indicates how each entry of the jump table is
+  /// represented and emitted.
+  enum JTEntryKind {
+    /// EK_BlockAddress - Each entry is a plain address of block, e.g.:
+    ///     .word LBB123
+    EK_BlockAddress,
+
+    /// EK_GPRel64BlockAddress - Each entry is an address of block, encoded
+    /// with a relocation as gp-relative, e.g.:
+    ///     .gpdword LBB123
+    EK_GPRel64BlockAddress,
+
+    /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
+    /// with a relocation as gp-relative, e.g.:
+    ///     .gprel32 LBB123
+    EK_GPRel32BlockAddress,
+
+    /// EK_LabelDifference32 - Each entry is the address of the block minus
+    /// the address of the jump table.  This is used for PIC jump tables where
+    /// gprel32 is not supported.  e.g.:
+    ///      .word LBB123 - LJTI1_2
+    /// If the .set directive is supported, this is emitted as:
+    ///      .set L4_5_set_123, LBB123 - LJTI1_2
+    ///      .word L4_5_set_123
+    EK_LabelDifference32,
+
+    /// EK_Inline - Jump table entries are emitted inline at their point of
+    /// use. It is the responsibility of the target to emit the entries.
+    EK_Inline,
+
+    /// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the
+    /// TargetLowering::LowerCustomJumpTableEntry hook.
+    EK_Custom32
+  };
+private:
+  JTEntryKind EntryKind;
+  std::vector<MachineJumpTableEntry> JumpTables;
+public:
+  explicit MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
+
+  JTEntryKind getEntryKind() const { return EntryKind; }
+
+  /// getEntrySize - Return the size of each entry in the jump table.
+  unsigned getEntrySize(const DataLayout &TD) const;
+  /// getEntryAlignment - Return the alignment of each entry in the jump table.
+  unsigned getEntryAlignment(const DataLayout &TD) const;
+
+  /// createJumpTableIndex - Create a new jump table.
+  ///
+  unsigned createJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
+
+  /// isEmpty - Return true if there are no jump tables.
+  ///
+  bool isEmpty() const { return JumpTables.empty(); }
+
+  const std::vector<MachineJumpTableEntry> &getJumpTables() const {
+    return JumpTables;
+  }
+
+  /// RemoveJumpTable - Mark the specific index as being dead.  This will
+  /// prevent it from being emitted.
+  void RemoveJumpTable(unsigned Idx) {
+    JumpTables[Idx].MBBs.clear();
+  }
+
+  /// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
+  /// the jump tables to branch to New instead.
+  bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+  /// ReplaceMBBInJumpTable - If Old is a target of the jump tables, update
+  /// the jump table to branch to New instead.
+  bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old,
+                             MachineBasicBlock *New);
+
+  /// print - Used by the MachineFunction printer to print information about
+  /// jump tables.  Implemented in MachineFunction.cpp
+  ///
+  void print(raw_ostream &OS) const;
+
+  /// dump - Call to stderr.
+  ///
+  void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
new file mode 100644
index 0000000..4fbd46b
--- /dev/null
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -0,0 +1,191 @@
+//===- llvm/CodeGen/MachineLoopInfo.h - Natural Loop Calculator -*- 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 MachineLoopInfo class that is used to identify natural
+// loops and determine the loop depth of various nodes of the CFG.  Note that
+// natural loops may actually be several loops that share the same header node.
+//
+// This analysis calculates the nesting structure of loops in a function.  For
+// each natural loop identified, this analysis identifies natural loops
+// contained entirely within the loop and the basic blocks the make up the loop.
+//
+// It can calculate on the fly various bits of information, for example:
+//
+//  * whether there is a preheader for the loop
+//  * the number of back edges to the header
+//  * whether or not a particular block branches out of the loop
+//  * the successor blocks of the loop
+//  * the loop depth
+//  * the trip count
+//  * etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINELOOPINFO_H
+#define LLVM_CODEGEN_MACHINELOOPINFO_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+class MachineLoop;
+__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop>;
+#endif
+
+class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
+public:
+  MachineLoop();
+
+  /// getTopBlock - Return the "top" block in the loop, which is the first
+  /// block in the linear layout, ignoring any parts of the loop not
+  /// contiguous with the part the contains the header.
+  MachineBasicBlock *getTopBlock();
+
+  /// getBottomBlock - Return the "bottom" block in the loop, which is the last
+  /// block in the linear layout, ignoring any parts of the loop not
+  /// contiguous with the part the contains the header.
+  MachineBasicBlock *getBottomBlock();
+
+  void dump() const;
+
+private:
+  friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+  explicit MachineLoop(MachineBasicBlock *MBB)
+    : LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}
+};
+
+// Implementation in LoopInfoImpl.h
+#ifdef __GNUC__
+__extension__ extern template
+class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+#endif
+
+class MachineLoopInfo : public MachineFunctionPass {
+  LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
+  friend class LoopBase<MachineBasicBlock, MachineLoop>;
+
+  void operator=(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
+  MachineLoopInfo(const MachineLoopInfo &) LLVM_DELETED_FUNCTION;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  MachineLoopInfo() : MachineFunctionPass(ID) {
+    initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
+  }
+
+  LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
+
+  /// iterator/begin/end - The interface to the top-level loops in the current
+  /// function.
+  ///
+  typedef LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator iterator;
+  inline iterator begin() const { return LI.begin(); }
+  inline iterator end() const { return LI.end(); }
+  bool empty() const { return LI.empty(); }
+
+  /// getLoopFor - Return the inner most loop that BB lives in.  If a basic
+  /// block is in no loop (for example the entry node), null is returned.
+  ///
+  inline MachineLoop *getLoopFor(const MachineBasicBlock *BB) const {
+    return LI.getLoopFor(BB);
+  }
+
+  /// operator[] - same as getLoopFor...
+  ///
+  inline const MachineLoop *operator[](const MachineBasicBlock *BB) const {
+    return LI.getLoopFor(BB);
+  }
+
+  /// getLoopDepth - Return the loop nesting level of the specified block...
+  ///
+  inline unsigned getLoopDepth(const MachineBasicBlock *BB) const {
+    return LI.getLoopDepth(BB);
+  }
+
+  // isLoopHeader - True if the block is a loop header node
+  inline bool isLoopHeader(MachineBasicBlock *BB) const {
+    return LI.isLoopHeader(BB);
+  }
+
+  /// runOnFunction - Calculate the natural loop information.
+  ///
+  bool runOnMachineFunction(MachineFunction &F) override;
+
+  void releaseMemory() override { LI.releaseMemory(); }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// removeLoop - This removes the specified top-level loop from this loop info
+  /// object.  The loop is not deleted, as it will presumably be inserted into
+  /// another loop.
+  inline MachineLoop *removeLoop(iterator I) { return LI.removeLoop(I); }
+
+  /// changeLoopFor - Change the top-level loop that contains BB to the
+  /// specified loop.  This should be used by transformations that restructure
+  /// the loop hierarchy tree.
+  inline void changeLoopFor(MachineBasicBlock *BB, MachineLoop *L) {
+    LI.changeLoopFor(BB, L);
+  }
+
+  /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+  /// list with the indicated loop.
+  inline void changeTopLevelLoop(MachineLoop *OldLoop, MachineLoop *NewLoop) {
+    LI.changeTopLevelLoop(OldLoop, NewLoop);
+  }
+
+  /// addTopLevelLoop - This adds the specified loop to the collection of
+  /// top-level loops.
+  inline void addTopLevelLoop(MachineLoop *New) {
+    LI.addTopLevelLoop(New);
+  }
+
+  /// removeBlock - This method completely removes BB from all data structures,
+  /// including all of the Loop objects it is nested in and our mapping from
+  /// MachineBasicBlocks to loops.
+  void removeBlock(MachineBasicBlock *BB) {
+    LI.removeBlock(BB);
+  }
+};
+
+
+// Allow clients to walk the list of nested loops...
+template <> struct GraphTraits<const MachineLoop*> {
+  typedef const MachineLoop NodeType;
+  typedef MachineLoopInfo::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const MachineLoop *L) { return L; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+};
+
+template <> struct GraphTraits<MachineLoop*> {
+  typedef MachineLoop NodeType;
+  typedef MachineLoopInfo::iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(MachineLoop *L) { return L; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
new file mode 100644
index 0000000..2532c16
--- /dev/null
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -0,0 +1,206 @@
+//==- llvm/CodeGen/MachineMemOperand.h - MachineMemOperand class -*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineMemOperand class, which is a
+// description of a memory reference. It is used to help track dependencies
+// in the backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
+#define LLVM_CODEGEN_MACHINEMEMOPERAND_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/IR/Value.h"  // PointerLikeTypeTraits<Value*>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class FoldingSetNodeID;
+class MDNode;
+class raw_ostream;
+
+/// MachinePointerInfo - This class contains a discriminated union of
+/// information about pointers in memory operands, relating them back to LLVM IR
+/// or to virtual locations (such as frame indices) that are exposed during
+/// codegen.
+struct MachinePointerInfo {
+  /// V - This is the IR pointer value for the access, or it is null if unknown.
+  /// If this is null, then the access is to a pointer in the default address
+  /// space.
+  PointerUnion<const Value *, const PseudoSourceValue *> V;
+
+  /// Offset - This is an offset from the base Value*.
+  int64_t Offset;
+
+  explicit MachinePointerInfo(const Value *v = nullptr, int64_t offset = 0)
+    : V(v), Offset(offset) {}
+
+  explicit MachinePointerInfo(const PseudoSourceValue *v,
+                              int64_t offset = 0)
+    : V(v), Offset(offset) {}
+
+  MachinePointerInfo getWithOffset(int64_t O) const {
+    if (V.isNull()) return MachinePointerInfo();
+    if (V.is<const Value*>())
+      return MachinePointerInfo(V.get<const Value*>(), Offset+O);
+    return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O);
+  }
+
+  /// getAddrSpace - Return the LLVM IR address space number that this pointer
+  /// points into.
+  unsigned getAddrSpace() const;
+
+  /// getConstantPool - Return a MachinePointerInfo record that refers to the
+  /// constant pool.
+  static MachinePointerInfo getConstantPool();
+
+  /// getFixedStack - Return a MachinePointerInfo record that refers to the
+  /// the specified FrameIndex.
+  static MachinePointerInfo getFixedStack(int FI, int64_t offset = 0);
+
+  /// getJumpTable - Return a MachinePointerInfo record that refers to a
+  /// jump table entry.
+  static MachinePointerInfo getJumpTable();
+
+  /// getGOT - Return a MachinePointerInfo record that refers to a
+  /// GOT entry.
+  static MachinePointerInfo getGOT();
+
+  /// getStack - stack pointer relative access.
+  static MachinePointerInfo getStack(int64_t Offset);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// MachineMemOperand - A description of a memory reference used in the backend.
+/// Instead of holding a StoreInst or LoadInst, this class holds the address
+/// Value of the reference along with a byte size and offset. This allows it
+/// to describe lowered loads and stores. Also, the special PseudoSourceValue
+/// objects can be used to represent loads and stores to memory locations
+/// that aren't explicit in the regular LLVM IR.
+///
+class MachineMemOperand {
+  MachinePointerInfo PtrInfo;
+  uint64_t Size;
+  unsigned Flags;
+  const MDNode *TBAAInfo;
+  const MDNode *Ranges;
+
+public:
+  /// Flags values. These may be or'd together.
+  enum MemOperandFlags {
+    /// The memory access reads data.
+    MOLoad = 1,
+    /// The memory access writes data.
+    MOStore = 2,
+    /// The memory access is volatile.
+    MOVolatile = 4,
+    /// The memory access is non-temporal.
+    MONonTemporal = 8,
+    /// The memory access is invariant.
+    MOInvariant = 16,
+    // Target hints allow target passes to annotate memory operations.
+    MOTargetStartBit = 5,
+    MOTargetNumBits = 3,
+    // This is the number of bits we need to represent flags.
+    MOMaxBits = 8
+  };
+
+  /// MachineMemOperand - Construct an MachineMemOperand object with the
+  /// specified PtrInfo, flags, size, and base alignment.
+  MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s,
+                    unsigned base_alignment, const MDNode *TBAAInfo = nullptr,
+                    const MDNode *Ranges = nullptr);
+
+  const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
+
+  /// getValue - Return the base address of the memory access. This may either
+  /// be a normal LLVM IR Value, or one of the special values used in CodeGen.
+  /// Special values are those obtained via
+  /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, and
+  /// other PseudoSourceValue member functions which return objects which stand
+  /// for frame/stack pointer relative references and other special references
+  /// which are not representable in the high-level IR.
+  const Value *getValue() const { return PtrInfo.V.dyn_cast<const Value*>(); }
+
+  const PseudoSourceValue *getPseudoValue() const {
+    return PtrInfo.V.dyn_cast<const PseudoSourceValue*>();
+  }
+
+  const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); }
+
+  /// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
+  unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
+
+  /// Bitwise OR the current flags with the given flags.
+  void setFlags(unsigned f) { Flags |= (f & ((1 << MOMaxBits) - 1)); }
+
+  /// getOffset - For normal values, this is a byte offset added to the base
+  /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
+  /// number.
+  int64_t getOffset() const { return PtrInfo.Offset; }
+
+  unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
+
+  /// getSize - Return the size in bytes of the memory reference.
+  uint64_t getSize() const { return Size; }
+
+  /// getAlignment - Return the minimum known alignment in bytes of the
+  /// actual memory reference.
+  uint64_t getAlignment() const;
+
+  /// getBaseAlignment - Return the minimum known alignment in bytes of the
+  /// base address, without the offset.
+  uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; }
+
+  /// getTBAAInfo - Return the TBAA tag for the memory reference.
+  const MDNode *getTBAAInfo() const { return TBAAInfo; }
+
+  /// getRanges - Return the range tag for the memory reference.
+  const MDNode *getRanges() const { return Ranges; }
+
+  bool isLoad() const { return Flags & MOLoad; }
+  bool isStore() const { return Flags & MOStore; }
+  bool isVolatile() const { return Flags & MOVolatile; }
+  bool isNonTemporal() const { return Flags & MONonTemporal; }
+  bool isInvariant() const { return Flags & MOInvariant; }
+
+  /// isUnordered - Returns true if this memory operation doesn't have any
+  /// ordering constraints other than normal aliasing. Volatile and atomic
+  /// memory operations can't be reordered.
+  ///
+  /// Currently, we don't model the difference between volatile and atomic
+  /// operations. They should retain their ordering relative to all memory
+  /// operations.
+  bool isUnordered() const { return !isVolatile(); }
+
+  /// refineAlignment - Update this MachineMemOperand to reflect the alignment
+  /// of MMO, if it has a greater alignment. This must only be used when the
+  /// new alignment applies to all users of this MachineMemOperand.
+  void refineAlignment(const MachineMemOperand *MMO);
+
+  /// setValue - Change the SourceValue for this MachineMemOperand. This
+  /// should only be used when an object is being relocated and all references
+  /// to it are being updated.
+  void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
+  void setValue(const PseudoSourceValue *NewSV) { PtrInfo.V = NewSV; }
+  void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
+
+  /// Profile - Gather unique data for the object.
+  ///
+  void Profile(FoldingSetNodeID &ID) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
new file mode 100644
index 0000000..6d8d056
--- /dev/null
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -0,0 +1,417 @@
+//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect meta information for a module.  This information should be in a
+// neutral form that can be used by different debugging and exception handling
+// schemes.
+//
+// The organization of information is primarily clustered around the source
+// compile units.  The main exception is source line correspondence where
+// inlining may interleave code from various compile units.
+//
+// The following information can be retrieved from the MachineModuleInfo.
+//
+//  -- Source directories - Directories are uniqued based on their canonical
+//     string and assigned a sequential numeric ID (base 1.)
+//  -- Source files - Files are also uniqued based on their name and directory
+//     ID.  A file ID is sequential number (base 1.)
+//  -- Source line correspondence - A vector of file ID, line#, column# triples.
+//     A DEBUG_LOCATION instruction is generated  by the DAG Legalizer
+//     corresponding to each entry in the source line list.  This allows a debug
+//     emitter to generate labels referenced by debug information tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H
+#define LLVM_CODEGEN_MACHINEMODULEINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Dwarf.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+class Constant;
+class GlobalVariable;
+class MDNode;
+class MMIAddrLabelMap;
+class MachineBasicBlock;
+class MachineFunction;
+class Module;
+class PointerType;
+class StructType;
+
+//===----------------------------------------------------------------------===//
+/// LandingPadInfo - This structure is used to retain landing pad info for
+/// the current function.
+///
+struct LandingPadInfo {
+  MachineBasicBlock *LandingPadBlock;    // Landing pad block.
+  SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke.
+  SmallVector<MCSymbol*, 1> EndLabels;   // Labels after invoke.
+  MCSymbol *LandingPadLabel;             // Label at beginning of landing pad.
+  const Function *Personality;           // Personality function.
+  std::vector<int> TypeIds;              // List of type ids (filters negative)
+
+  explicit LandingPadInfo(MachineBasicBlock *MBB)
+    : LandingPadBlock(MBB), LandingPadLabel(nullptr), Personality(nullptr) {}
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfoImpl - This class can be derived from and used by targets
+/// to hold private target-specific information for each Module.  Objects of
+/// type are accessed/created with MMI::getInfo and destroyed when the
+/// MachineModuleInfo is destroyed.
+/// 
+class MachineModuleInfoImpl {
+public:
+  typedef PointerIntPair<MCSymbol*, 1, bool> StubValueTy;
+  virtual ~MachineModuleInfoImpl();
+  typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy;
+protected:
+  static SymbolListTy GetSortedStubs(const DenseMap<MCSymbol*, StubValueTy>&);
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfo - This class contains meta information specific to a
+/// module.  Queries can be made by different debugging and exception handling
+/// schemes and reformated for specific use.
+///
+class MachineModuleInfo : public ImmutablePass {
+  /// Context - This is the MCContext used for the entire code generator.
+  MCContext Context;
+
+  /// TheModule - This is the LLVM Module being worked on.
+  const Module *TheModule;
+
+  /// ObjFileMMI - This is the object-file-format-specific implementation of
+  /// MachineModuleInfoImpl, which lets targets accumulate whatever info they
+  /// want.
+  MachineModuleInfoImpl *ObjFileMMI;
+
+  /// List of moves done by a function's prolog.  Used to construct frame maps
+  /// by debug and exception handling consumers.
+  std::vector<MCCFIInstruction> FrameInstructions;
+
+  /// CompactUnwindEncoding - If the target supports it, this is the compact
+  /// unwind encoding. It replaces a function's CIE and FDE.
+  uint32_t CompactUnwindEncoding;
+
+  /// LandingPads - List of LandingPadInfo describing the landing pad
+  /// information in the current function.
+  std::vector<LandingPadInfo> LandingPads;
+
+  /// LPadToCallSiteMap - Map a landing pad's EH symbol to the call site
+  /// indexes.
+  DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
+
+  /// CallSiteMap - Map of invoke call site index values to associated begin
+  /// EH_LABEL for the current function.
+  DenseMap<MCSymbol*, unsigned> CallSiteMap;
+
+  /// CurCallSite - The current call site index being processed, if any. 0 if
+  /// none.
+  unsigned CurCallSite;
+
+  /// TypeInfos - List of C++ TypeInfo used in the current function.
+  std::vector<const GlobalVariable *> TypeInfos;
+
+  /// FilterIds - List of typeids encoding filters used in the current function.
+  std::vector<unsigned> FilterIds;
+
+  /// FilterEnds - List of the indices in FilterIds corresponding to filter
+  /// terminators.
+  std::vector<unsigned> FilterEnds;
+
+  /// Personalities - Vector of all personality functions ever seen. Used to
+  /// emit common EH frames.
+  std::vector<const Function *> Personalities;
+
+  /// UsedFunctions - The functions in the @llvm.used list in a more easily
+  /// searchable format.  This does not include the functions in
+  /// llvm.compiler.used.
+  SmallPtrSet<const Function *, 32> UsedFunctions;
+
+  /// AddrLabelSymbols - This map keeps track of which symbol is being used for
+  /// the specified basic block's address of label.
+  MMIAddrLabelMap *AddrLabelSymbols;
+
+  bool CallsEHReturn;
+  bool CallsUnwindInit;
+
+  /// DbgInfoAvailable - True if debugging information is available
+  /// in this module.
+  bool DbgInfoAvailable;
+
+  /// UsesVAFloatArgument - True if this module calls VarArg function with
+  /// floating-point arguments.  This is used to emit an undefined reference
+  /// to _fltused on Windows targets.
+  bool UsesVAFloatArgument;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  struct VariableDbgInfo {
+    TrackingVH<MDNode> Var;
+    unsigned Slot;
+    DebugLoc Loc;
+  };
+  typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy;
+  VariableDbgInfoMapTy VariableDbgInfos;
+
+  MachineModuleInfo();  // DUMMY CONSTRUCTOR, DO NOT CALL.
+  // Real constructor.
+  MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
+                    const MCObjectFileInfo *MOFI);
+  ~MachineModuleInfo();
+
+  // Initialization and Finalization
+  bool doInitialization(Module &) override;
+  bool doFinalization(Module &) override;
+
+  /// EndFunction - Discard function meta information.
+  ///
+  void EndFunction();
+
+  const MCContext &getContext() const { return Context; }
+  MCContext &getContext() { return Context; }
+
+  void setModule(const Module *M) { TheModule = M; }
+  const Module *getModule() const { return TheModule; }
+
+  /// getInfo - Keep track of various per-function pieces of information for
+  /// backends that would like to do so.
+  ///
+  template<typename Ty>
+  Ty &getObjFileInfo() {
+    if (ObjFileMMI == nullptr)
+      ObjFileMMI = new Ty(*this);
+    return *static_cast<Ty*>(ObjFileMMI);
+  }
+
+  template<typename Ty>
+  const Ty &getObjFileInfo() const {
+    return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
+  }
+
+  /// AnalyzeModule - Scan the module for global debug information.
+  ///
+  void AnalyzeModule(const Module &M);
+
+  /// hasDebugInfo - Returns true if valid debug info is present.
+  ///
+  bool hasDebugInfo() const { return DbgInfoAvailable; }
+  void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
+
+  bool callsEHReturn() const { return CallsEHReturn; }
+  void setCallsEHReturn(bool b) { CallsEHReturn = b; }
+
+  bool callsUnwindInit() const { return CallsUnwindInit; }
+  void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
+
+  bool usesVAFloatArgument() const {
+    return UsesVAFloatArgument;
+  }
+
+  void setUsesVAFloatArgument(bool b) {
+    UsesVAFloatArgument = b;
+  }
+
+  /// \brief Returns a reference to a list of cfi instructions in the current
+  /// function's prologue.  Used to construct frame maps for debug and exception
+  /// handling comsumers.
+  const std::vector<MCCFIInstruction> &getFrameInstructions() const {
+    return FrameInstructions;
+  }
+
+  unsigned LLVM_ATTRIBUTE_UNUSED_RESULT
+  addFrameInst(const MCCFIInstruction &Inst) {
+    FrameInstructions.push_back(Inst);
+    return FrameInstructions.size() - 1;
+  }
+
+  /// getCompactUnwindEncoding - Returns the compact unwind encoding for a
+  /// function if the target supports the encoding. This encoding replaces a
+  /// function's CIE and FDE.
+  uint32_t getCompactUnwindEncoding() const { return CompactUnwindEncoding; }
+
+  /// setCompactUnwindEncoding - Set the compact unwind encoding for a function
+  /// if the target supports the encoding.
+  void setCompactUnwindEncoding(uint32_t Enc) { CompactUnwindEncoding = Enc; }
+
+  /// getAddrLabelSymbol - Return the symbol to be used for the specified basic
+  /// block when its address is taken.  This cannot be its normal LBB label
+  /// because the block may be accessed outside its containing function.
+  MCSymbol *getAddrLabelSymbol(const BasicBlock *BB);
+
+  /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
+  /// basic block when its address is taken.  If other blocks were RAUW'd to
+  /// this one, we may have to emit them as well, return the whole set.
+  std::vector<MCSymbol*> getAddrLabelSymbolToEmit(const BasicBlock *BB);
+
+  /// takeDeletedSymbolsForFunction - If the specified function has had any
+  /// references to address-taken blocks generated, but the block got deleted,
+  /// return the symbol now so we can emit it.  This prevents emitting a
+  /// reference to a symbol that has no definition.
+  void takeDeletedSymbolsForFunction(const Function *F,
+                                     std::vector<MCSymbol*> &Result);
+
+
+  //===- EH ---------------------------------------------------------------===//
+
+  /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
+  /// specified MachineBasicBlock.
+  LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
+
+  /// addInvoke - Provide the begin and end labels of an invoke style call and
+  /// associate it with a try landing pad block.
+  void addInvoke(MachineBasicBlock *LandingPad,
+                 MCSymbol *BeginLabel, MCSymbol *EndLabel);
+
+  /// addLandingPad - Add a new panding pad.  Returns the label ID for the
+  /// landing pad entry.
+  MCSymbol *addLandingPad(MachineBasicBlock *LandingPad);
+
+  /// addPersonality - Provide the personality function for the exception
+  /// information.
+  void addPersonality(MachineBasicBlock *LandingPad,
+                      const Function *Personality);
+
+  /// getPersonalityIndex - Get index of the current personality function inside
+  /// Personalitites array
+  unsigned getPersonalityIndex() const;
+
+  /// getPersonalities - Return array of personality functions ever seen.
+  const std::vector<const Function *>& getPersonalities() const {
+    return Personalities;
+  }
+
+  /// isUsedFunction - Return true if the functions in the llvm.used list.  This
+  /// does not return true for things in llvm.compiler.used unless they are also
+  /// in llvm.used.
+  bool isUsedFunction(const Function *F) const {
+    return UsedFunctions.count(F);
+  }
+
+  /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
+  ///
+  void addCatchTypeInfo(MachineBasicBlock *LandingPad,
+                        ArrayRef<const GlobalVariable *> TyInfo);
+
+  /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+  ///
+  void addFilterTypeInfo(MachineBasicBlock *LandingPad,
+                         ArrayRef<const GlobalVariable *> TyInfo);
+
+  /// addCleanup - Add a cleanup action for a landing pad.
+  ///
+  void addCleanup(MachineBasicBlock *LandingPad);
+
+  /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
+  /// function wide.
+  unsigned getTypeIDFor(const GlobalVariable *TI);
+
+  /// getFilterIDFor - Return the id of the filter encoded by TyIds.  This is
+  /// function wide.
+  int getFilterIDFor(std::vector<unsigned> &TyIds);
+
+  /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
+  /// pads.
+  void TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = nullptr);
+
+  /// getLandingPads - Return a reference to the landing pad info for the
+  /// current function.
+  const std::vector<LandingPadInfo> &getLandingPads() const {
+    return LandingPads;
+  }
+
+  /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call
+  /// site indexes.
+  void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
+
+  /// getCallSiteLandingPad - Get the call site indexes for a landing pad EH
+  /// symbol.
+  SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
+    assert(hasCallSiteLandingPad(Sym) &&
+           "missing call site number for landing pad!");
+    return LPadToCallSiteMap[Sym];
+  }
+
+  /// hasCallSiteLandingPad - Return true if the landing pad Eh symbol has an
+  /// associated call site.
+  bool hasCallSiteLandingPad(MCSymbol *Sym) {
+    return !LPadToCallSiteMap[Sym].empty();
+  }
+
+  /// setCallSiteBeginLabel - Map the begin label for a call site.
+  void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
+    CallSiteMap[BeginLabel] = Site;
+  }
+
+  /// getCallSiteBeginLabel - Get the call site number for a begin label.
+  unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) {
+    assert(hasCallSiteBeginLabel(BeginLabel) &&
+           "Missing call site number for EH_LABEL!");
+    return CallSiteMap[BeginLabel];
+  }
+
+  /// hasCallSiteBeginLabel - Return true if the begin label has a call site
+  /// number associated with it.
+  bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) {
+    return CallSiteMap[BeginLabel] != 0;
+  }
+
+  /// setCurrentCallSite - Set the call site currently being processed.
+  void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
+
+  /// getCurrentCallSite - Get the call site currently being processed, if any.
+  /// return zero if none.
+  unsigned getCurrentCallSite() { return CurCallSite; }
+
+  /// getTypeInfos - Return a reference to the C++ typeinfo for the current
+  /// function.
+  const std::vector<const GlobalVariable *> &getTypeInfos() const {
+    return TypeInfos;
+  }
+
+  /// getFilterIds - Return a reference to the typeids encoding filters used in
+  /// the current function.
+  const std::vector<unsigned> &getFilterIds() const {
+    return FilterIds;
+  }
+
+  /// getPersonality - Return a personality function if available.  The presence
+  /// of one is required to emit exception handling info.
+  const Function *getPersonality() const;
+
+  /// setVariableDbgInfo - Collect information used to emit debugging
+  /// information of a variable.
+  void setVariableDbgInfo(MDNode *N, unsigned Slot, DebugLoc Loc) {
+    VariableDbgInfo Info = { N, Slot, Loc };
+    VariableDbgInfos.push_back(std::move(Info));
+  }
+
+  VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; }
+
+}; // End class MachineModuleInfo
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h
new file mode 100644
index 0000000..7afc7eb
--- /dev/null
+++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -0,0 +1,97 @@
+//===-- llvm/CodeGen/MachineModuleInfoImpls.h -------------------*- 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 object-file format specific implementations of
+// MachineModuleInfoImpl.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
+#define LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+
+namespace llvm {
+  class MCSymbol;
+
+  /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
+  /// for MachO targets.
+  class MachineModuleInfoMachO : public MachineModuleInfoImpl {
+    /// FnStubs - Darwin '$stub' stubs.  The key is something like "Lfoo$stub",
+    /// the value is something like "_foo".
+    DenseMap<MCSymbol*, StubValueTy> FnStubs;
+    
+    /// GVStubs - Darwin '$non_lazy_ptr' stubs.  The key is something like
+    /// "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra bit
+    /// is true if this GV is external.
+    DenseMap<MCSymbol*, StubValueTy> GVStubs;
+    
+    /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs.  The key is something like
+    /// "Lfoo$non_lazy_ptr", the value is something like "_foo".  Unlike GVStubs
+    /// these are for things with hidden visibility. The extra bit is true if
+    /// this GV is external.
+    DenseMap<MCSymbol*, StubValueTy> HiddenGVStubs;
+    
+    virtual void anchor();  // Out of line virtual method.
+  public:
+    MachineModuleInfoMachO(const MachineModuleInfo &) {}
+    
+    StubValueTy &getFnStubEntry(MCSymbol *Sym) {
+      assert(Sym && "Key cannot be null");
+      return FnStubs[Sym];
+    }
+
+    StubValueTy &getGVStubEntry(MCSymbol *Sym) {
+      assert(Sym && "Key cannot be null");
+      return GVStubs[Sym];
+    }
+
+    StubValueTy &getHiddenGVStubEntry(MCSymbol *Sym) {
+      assert(Sym && "Key cannot be null");
+      return HiddenGVStubs[Sym];
+    }
+
+    /// Accessor methods to return the set of stubs in sorted order.
+    SymbolListTy GetFnStubList() const {
+      return GetSortedStubs(FnStubs);
+    }
+    SymbolListTy GetGVStubList() const {
+      return GetSortedStubs(GVStubs);
+    }
+    SymbolListTy GetHiddenGVStubList() const {
+      return GetSortedStubs(HiddenGVStubs);
+    }
+  };
+
+  /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
+  /// for ELF targets.
+  class MachineModuleInfoELF : public MachineModuleInfoImpl {
+    /// GVStubs - These stubs are used to materialize global addresses in PIC
+    /// mode.
+    DenseMap<MCSymbol*, StubValueTy> GVStubs;
+
+    virtual void anchor();  // Out of line virtual method.
+  public:
+    MachineModuleInfoELF(const MachineModuleInfo &) {}
+
+    StubValueTy &getGVStubEntry(MCSymbol *Sym) {
+      assert(Sym && "Key cannot be null");
+      return GVStubs[Sym];
+    }
+
+    /// Accessor methods to return the set of stubs in sorted order.
+
+    SymbolListTy GetGVStubList() const {
+      return GetSortedStubs(GVStubs);
+    }
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
new file mode 100644
index 0000000..22969bc
--- /dev/null
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -0,0 +1,728 @@
+//===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineOperand class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
+#define LLVM_CODEGEN_MACHINEOPERAND_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class BlockAddress;
+class ConstantFP;
+class ConstantInt;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineInstr;
+class MachineRegisterInfo;
+class MDNode;
+class TargetMachine;
+class TargetRegisterInfo;
+class hash_code;
+class raw_ostream;
+class MCSymbol;
+
+/// MachineOperand class - Representation of each machine instruction operand.
+///
+/// This class isn't a POD type because it has a private constructor, but its
+/// destructor must be trivial. Functions like MachineInstr::addOperand(),
+/// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depend on
+/// not having to call the MachineOperand destructor.
+///
+class MachineOperand {
+public:
+  enum MachineOperandType : unsigned char {
+    MO_Register,          ///< Register operand.
+    MO_Immediate,         ///< Immediate operand
+    MO_CImmediate,        ///< Immediate >64bit operand
+    MO_FPImmediate,       ///< Floating-point immediate operand
+    MO_MachineBasicBlock, ///< MachineBasicBlock reference
+    MO_FrameIndex,        ///< Abstract Stack Frame Index
+    MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
+    MO_TargetIndex,       ///< Target-dependent index+offset operand.
+    MO_JumpTableIndex,    ///< Address of indexed Jump Table for switch
+    MO_ExternalSymbol,    ///< Name of external global symbol
+    MO_GlobalAddress,     ///< Address of a global value
+    MO_BlockAddress,      ///< Address of a basic block
+    MO_RegisterMask,      ///< Mask of preserved registers.
+    MO_RegisterLiveOut,   ///< Mask of live-out registers.
+    MO_Metadata,          ///< Metadata reference (for debug info)
+    MO_MCSymbol,          ///< MCSymbol reference (for debug/eh info)
+    MO_CFIIndex           ///< MCCFIInstruction index.
+  };
+
+private:
+  /// OpKind - Specify what kind of operand this is.  This discriminates the
+  /// union.
+  MachineOperandType OpKind;
+
+  /// Subregister number for MO_Register.  A value of 0 indicates the
+  /// MO_Register has no subReg.
+  ///
+  /// For all other kinds of operands, this field holds target-specific flags.
+  unsigned SubReg_TargetFlags : 12;
+
+  /// TiedTo - Non-zero when this register operand is tied to another register
+  /// operand. The encoding of this field is described in the block comment
+  /// before MachineInstr::tieOperands().
+  unsigned char TiedTo : 4;
+
+  /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
+  /// operands.
+
+  /// IsDef - True if this is a def, false if this is a use of the register.
+  ///
+  bool IsDef : 1;
+
+  /// IsImp - True if this is an implicit def or use, false if it is explicit.
+  ///
+  bool IsImp : 1;
+
+  /// IsKill - True if this instruction is the last use of the register on this
+  /// path through the function.  This is only valid on uses of registers.
+  bool IsKill : 1;
+
+  /// IsDead - True if this register is never used by a subsequent instruction.
+  /// This is only valid on definitions of registers.
+  bool IsDead : 1;
+
+  /// IsUndef - True if this register operand reads an "undef" value, i.e. the
+  /// read value doesn't matter.  This flag can be set on both use and def
+  /// operands.  On a sub-register def operand, it refers to the part of the
+  /// register that isn't written.  On a full-register def operand, it is a
+  /// noop.  See readsReg().
+  ///
+  /// This is only valid on registers.
+  ///
+  /// Note that an instruction may have multiple <undef> operands referring to
+  /// the same register.  In that case, the instruction may depend on those
+  /// operands reading the same dont-care value.  For example:
+  ///
+  ///   %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef>
+  ///
+  /// Any register can be used for %vreg2, and its value doesn't matter, but
+  /// the two operands must be the same register.
+  ///
+  bool IsUndef : 1;
+
+  /// IsInternalRead - True if this operand reads a value that was defined
+  /// inside the same instruction or bundle.  This flag can be set on both use
+  /// and def operands.  On a sub-register def operand, it refers to the part
+  /// of the register that isn't written.  On a full-register def operand, it
+  /// is a noop.
+  ///
+  /// When this flag is set, the instruction bundle must contain at least one
+  /// other def of the register.  If multiple instructions in the bundle define
+  /// the register, the meaning is target-defined.
+  bool IsInternalRead : 1;
+
+  /// IsEarlyClobber - True if this MO_Register 'def' operand is written to
+  /// by the MachineInstr before all input registers are read.  This is used to
+  /// model the GCC inline asm '&' constraint modifier.
+  bool IsEarlyClobber : 1;
+
+  /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
+  /// not a real instruction.  Such uses should be ignored during codegen.
+  bool IsDebug : 1;
+
+  /// SmallContents - This really should be part of the Contents union, but
+  /// lives out here so we can get a better packed struct.
+  /// MO_Register: Register number.
+  /// OffsetedInfo: Low bits of offset.
+  union {
+    unsigned RegNo;           // For MO_Register.
+    unsigned OffsetLo;        // Matches Contents.OffsetedInfo.OffsetHi.
+  } SmallContents;
+
+  /// ParentMI - This is the instruction that this operand is embedded into.
+  /// This is valid for all operand types, when the operand is in an instr.
+  MachineInstr *ParentMI;
+
+  /// Contents union - This contains the payload for the various operand types.
+  union {
+    MachineBasicBlock *MBB;  // For MO_MachineBasicBlock.
+    const ConstantFP *CFP;   // For MO_FPImmediate.
+    const ConstantInt *CI;   // For MO_CImmediate. Integers > 64bit.
+    int64_t ImmVal;          // For MO_Immediate.
+    const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
+    const MDNode *MD;        // For MO_Metadata.
+    MCSymbol *Sym;           // For MO_MCSymbol.
+    unsigned CFIIndex;       // For MO_CFI.
+
+    struct {                  // For MO_Register.
+      // Register number is in SmallContents.RegNo.
+      MachineOperand *Prev;   // Access list for register. See MRI.
+      MachineOperand *Next;
+    } Reg;
+
+    /// OffsetedInfo - This struct contains the offset and an object identifier.
+    /// this represent the object as with an optional offset from it.
+    struct {
+      union {
+        int Index;                // For MO_*Index - The index itself.
+        const char *SymbolName;   // For MO_ExternalSymbol.
+        const GlobalValue *GV;    // For MO_GlobalAddress.
+        const BlockAddress *BA;   // For MO_BlockAddress.
+      } Val;
+      // Low bits of offset are in SmallContents.OffsetLo.
+      int OffsetHi;               // An offset from the object, high 32 bits.
+    } OffsetedInfo;
+  } Contents;
+
+  explicit MachineOperand(MachineOperandType K)
+    : OpKind(K), SubReg_TargetFlags(0), ParentMI(nullptr) {}
+public:
+  /// getType - Returns the MachineOperandType for this operand.
+  ///
+  MachineOperandType getType() const { return (MachineOperandType)OpKind; }
+
+  unsigned getTargetFlags() const {
+    return isReg() ? 0 : SubReg_TargetFlags;
+  }
+  void setTargetFlags(unsigned F) {
+    assert(!isReg() && "Register operands can't have target flags");
+    SubReg_TargetFlags = F;
+    assert(SubReg_TargetFlags == F && "Target flags out of range");
+  }
+  void addTargetFlag(unsigned F) {
+    assert(!isReg() && "Register operands can't have target flags");
+    SubReg_TargetFlags |= F;
+    assert((SubReg_TargetFlags & F) && "Target flags out of range");
+  }
+
+
+  /// getParent - Return the instruction that this operand belongs to.
+  ///
+  MachineInstr *getParent() { return ParentMI; }
+  const MachineInstr *getParent() const { return ParentMI; }
+
+  /// clearParent - Reset the parent pointer.
+  ///
+  /// The MachineOperand copy constructor also copies ParentMI, expecting the
+  /// original to be deleted. If a MachineOperand is ever stored outside a
+  /// MachineInstr, the parent pointer must be cleared.
+  ///
+  /// Never call clearParent() on an operand in a MachineInstr.
+  ///
+  void clearParent() { ParentMI = nullptr; }
+
+  void print(raw_ostream &os, const TargetMachine *TM = nullptr) const;
+
+  //===--------------------------------------------------------------------===//
+  // Accessors that tell you what kind of MachineOperand you're looking at.
+  //===--------------------------------------------------------------------===//
+
+  /// isReg - Tests if this is a MO_Register operand.
+  bool isReg() const { return OpKind == MO_Register; }
+  /// isImm - Tests if this is a MO_Immediate operand.
+  bool isImm() const { return OpKind == MO_Immediate; }
+  /// isCImm - Test if this is a MO_CImmediate operand.
+  bool isCImm() const { return OpKind == MO_CImmediate; }
+  /// isFPImm - Tests if this is a MO_FPImmediate operand.
+  bool isFPImm() const { return OpKind == MO_FPImmediate; }
+  /// isMBB - Tests if this is a MO_MachineBasicBlock operand.
+  bool isMBB() const { return OpKind == MO_MachineBasicBlock; }
+  /// isFI - Tests if this is a MO_FrameIndex operand.
+  bool isFI() const { return OpKind == MO_FrameIndex; }
+  /// isCPI - Tests if this is a MO_ConstantPoolIndex operand.
+  bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
+  /// isTargetIndex - Tests if this is a MO_TargetIndex operand.
+  bool isTargetIndex() const { return OpKind == MO_TargetIndex; }
+  /// isJTI - Tests if this is a MO_JumpTableIndex operand.
+  bool isJTI() const { return OpKind == MO_JumpTableIndex; }
+  /// isGlobal - Tests if this is a MO_GlobalAddress operand.
+  bool isGlobal() const { return OpKind == MO_GlobalAddress; }
+  /// isSymbol - Tests if this is a MO_ExternalSymbol operand.
+  bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
+  /// isBlockAddress - Tests if this is a MO_BlockAddress operand.
+  bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
+  /// isRegMask - Tests if this is a MO_RegisterMask operand.
+  bool isRegMask() const { return OpKind == MO_RegisterMask; }
+  /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
+  bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
+  /// isMetadata - Tests if this is a MO_Metadata operand.
+  bool isMetadata() const { return OpKind == MO_Metadata; }
+  bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
+  bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
+
+  //===--------------------------------------------------------------------===//
+  // Accessors for Register Operands
+  //===--------------------------------------------------------------------===//
+
+  /// getReg - Returns the register number.
+  unsigned getReg() const {
+    assert(isReg() && "This is not a register operand!");
+    return SmallContents.RegNo;
+  }
+
+  unsigned getSubReg() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return SubReg_TargetFlags;
+  }
+
+  bool isUse() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return !IsDef;
+  }
+
+  bool isDef() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsDef;
+  }
+
+  bool isImplicit() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsImp;
+  }
+
+  bool isDead() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsDead;
+  }
+
+  bool isKill() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsKill;
+  }
+
+  bool isUndef() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsUndef;
+  }
+
+  bool isInternalRead() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsInternalRead;
+  }
+
+  bool isEarlyClobber() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsEarlyClobber;
+  }
+
+  bool isTied() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return TiedTo;
+  }
+
+  bool isDebug() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return IsDebug;
+  }
+
+  /// readsReg - Returns true if this operand reads the previous value of its
+  /// register.  A use operand with the <undef> flag set doesn't read its
+  /// register.  A sub-register def implicitly reads the other parts of the
+  /// register being redefined unless the <undef> flag is set.
+  ///
+  /// This refers to reading the register value from before the current
+  /// instruction or bundle. Internal bundle reads are not included.
+  bool readsReg() const {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Mutators for Register Operands
+  //===--------------------------------------------------------------------===//
+
+  /// Change the register this operand corresponds to.
+  ///
+  void setReg(unsigned Reg);
+
+  void setSubReg(unsigned subReg) {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    SubReg_TargetFlags = subReg;
+    assert(SubReg_TargetFlags == subReg && "SubReg out of range");
+  }
+
+  /// substVirtReg - Substitute the current register with the virtual
+  /// subregister Reg:SubReg. Take any existing SubReg index into account,
+  /// using TargetRegisterInfo to compose the subreg indices if necessary.
+  /// Reg must be a virtual register, SubIdx can be 0.
+  ///
+  void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&);
+
+  /// substPhysReg - Substitute the current register with the physical register
+  /// Reg, taking any existing SubReg into account. For instance,
+  /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL.
+  ///
+  void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
+
+  void setIsUse(bool Val = true) { setIsDef(!Val); }
+
+  void setIsDef(bool Val = true);
+
+  void setImplicit(bool Val = true) {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    IsImp = Val;
+  }
+
+  void setIsKill(bool Val = true) {
+    assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+    assert((!Val || !isDebug()) && "Marking a debug operation as kill");
+    IsKill = Val;
+  }
+
+  void setIsDead(bool Val = true) {
+    assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+    IsDead = Val;
+  }
+
+  void setIsUndef(bool Val = true) {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    IsUndef = Val;
+  }
+
+  void setIsInternalRead(bool Val = true) {
+    assert(isReg() && "Wrong MachineOperand accessor");
+    IsInternalRead = Val;
+  }
+
+  void setIsEarlyClobber(bool Val = true) {
+    assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+    IsEarlyClobber = Val;
+  }
+
+  void setIsDebug(bool Val = true) {
+    assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+    IsDebug = Val;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Accessors for various operand types.
+  //===--------------------------------------------------------------------===//
+
+  int64_t getImm() const {
+    assert(isImm() && "Wrong MachineOperand accessor");
+    return Contents.ImmVal;
+  }
+
+  const ConstantInt *getCImm() const {
+    assert(isCImm() && "Wrong MachineOperand accessor");
+    return Contents.CI;
+  }
+
+  const ConstantFP *getFPImm() const {
+    assert(isFPImm() && "Wrong MachineOperand accessor");
+    return Contents.CFP;
+  }
+
+  MachineBasicBlock *getMBB() const {
+    assert(isMBB() && "Wrong MachineOperand accessor");
+    return Contents.MBB;
+  }
+
+  int getIndex() const {
+    assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
+           "Wrong MachineOperand accessor");
+    return Contents.OffsetedInfo.Val.Index;
+  }
+
+  const GlobalValue *getGlobal() const {
+    assert(isGlobal() && "Wrong MachineOperand accessor");
+    return Contents.OffsetedInfo.Val.GV;
+  }
+
+  const BlockAddress *getBlockAddress() const {
+    assert(isBlockAddress() && "Wrong MachineOperand accessor");
+    return Contents.OffsetedInfo.Val.BA;
+  }
+
+  MCSymbol *getMCSymbol() const {
+    assert(isMCSymbol() && "Wrong MachineOperand accessor");
+    return Contents.Sym;
+  }
+
+  unsigned getCFIIndex() const {
+    assert(isCFIIndex() && "Wrong MachineOperand accessor");
+    return Contents.CFIIndex;
+  }
+
+  /// getOffset - Return the offset from the symbol in this operand. This always
+  /// returns 0 for ExternalSymbol operands.
+  int64_t getOffset() const {
+    assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
+            isBlockAddress()) && "Wrong MachineOperand accessor");
+    return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
+           SmallContents.OffsetLo;
+  }
+
+  const char *getSymbolName() const {
+    assert(isSymbol() && "Wrong MachineOperand accessor");
+    return Contents.OffsetedInfo.Val.SymbolName;
+  }
+
+  /// clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
+  /// It is sometimes necessary to detach the register mask pointer from its
+  /// machine operand. This static method can be used for such detached bit
+  /// mask pointers.
+  static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg) {
+    // See TargetRegisterInfo.h.
+    assert(PhysReg < (1u << 30) && "Not a physical register");
+    return !(RegMask[PhysReg / 32] & (1u << PhysReg % 32));
+  }
+
+  /// clobbersPhysReg - Returns true if this RegMask operand clobbers PhysReg.
+  bool clobbersPhysReg(unsigned PhysReg) const {
+     return clobbersPhysReg(getRegMask(), PhysReg);
+  }
+
+  /// getRegMask - Returns a bit mask of registers preserved by this RegMask
+  /// operand.
+  const uint32_t *getRegMask() const {
+    assert(isRegMask() && "Wrong MachineOperand accessor");
+    return Contents.RegMask;
+  }
+
+  /// getRegLiveOut - Returns a bit mask of live-out registers.
+  const uint32_t *getRegLiveOut() const {
+    assert(isRegLiveOut() && "Wrong MachineOperand accessor");
+    return Contents.RegMask;
+  }
+
+  const MDNode *getMetadata() const {
+    assert(isMetadata() && "Wrong MachineOperand accessor");
+    return Contents.MD;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Mutators for various operand types.
+  //===--------------------------------------------------------------------===//
+
+  void setImm(int64_t immVal) {
+    assert(isImm() && "Wrong MachineOperand mutator");
+    Contents.ImmVal = immVal;
+  }
+
+  void setOffset(int64_t Offset) {
+    assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() ||
+            isBlockAddress()) && "Wrong MachineOperand accessor");
+    SmallContents.OffsetLo = unsigned(Offset);
+    Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
+  }
+
+  void setIndex(int Idx) {
+    assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
+           "Wrong MachineOperand accessor");
+    Contents.OffsetedInfo.Val.Index = Idx;
+  }
+
+  void setMBB(MachineBasicBlock *MBB) {
+    assert(isMBB() && "Wrong MachineOperand accessor");
+    Contents.MBB = MBB;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Other methods.
+  //===--------------------------------------------------------------------===//
+
+  /// isIdenticalTo - Return true if this operand is identical to the specified
+  /// operand. Note: This method ignores isKill and isDead properties.
+  bool isIdenticalTo(const MachineOperand &Other) const;
+
+  /// \brief MachineOperand hash_value overload.
+  ///
+  /// Note that this includes the same information in the hash that
+  /// isIdenticalTo uses for comparison. It is thus suited for use in hash
+  /// tables which use that function for equality comparisons only.
+  friend hash_code hash_value(const MachineOperand &MO);
+
+  /// ChangeToImmediate - Replace this operand with a new immediate operand of
+  /// the specified value.  If an operand is known to be an immediate already,
+  /// the setImm method should be used.
+  void ChangeToImmediate(int64_t ImmVal);
+
+  /// ChangeToRegister - Replace this operand with a new register operand of
+  /// the specified value.  If an operand is known to be an register already,
+  /// the setReg method should be used.
+  void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+                        bool isKill = false, bool isDead = false,
+                        bool isUndef = false, bool isDebug = false);
+
+  //===--------------------------------------------------------------------===//
+  // Construction methods.
+  //===--------------------------------------------------------------------===//
+
+  static MachineOperand CreateImm(int64_t Val) {
+    MachineOperand Op(MachineOperand::MO_Immediate);
+    Op.setImm(Val);
+    return Op;
+  }
+
+  static MachineOperand CreateCImm(const ConstantInt *CI) {
+    MachineOperand Op(MachineOperand::MO_CImmediate);
+    Op.Contents.CI = CI;
+    return Op;
+  }
+
+  static MachineOperand CreateFPImm(const ConstantFP *CFP) {
+    MachineOperand Op(MachineOperand::MO_FPImmediate);
+    Op.Contents.CFP = CFP;
+    return Op;
+  }
+
+  static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
+                                  bool isKill = false, bool isDead = false,
+                                  bool isUndef = false,
+                                  bool isEarlyClobber = false,
+                                  unsigned SubReg = 0,
+                                  bool isDebug = false,
+                                  bool isInternalRead = false) {
+    assert(!(isDead && !isDef) && "Dead flag on non-def");
+    assert(!(isKill && isDef) && "Kill flag on def");
+    MachineOperand Op(MachineOperand::MO_Register);
+    Op.IsDef = isDef;
+    Op.IsImp = isImp;
+    Op.IsKill = isKill;
+    Op.IsDead = isDead;
+    Op.IsUndef = isUndef;
+    Op.IsInternalRead = isInternalRead;
+    Op.IsEarlyClobber = isEarlyClobber;
+    Op.TiedTo = 0;
+    Op.IsDebug = isDebug;
+    Op.SmallContents.RegNo = Reg;
+    Op.Contents.Reg.Prev = nullptr;
+    Op.Contents.Reg.Next = nullptr;
+    Op.setSubReg(SubReg);
+    return Op;
+  }
+  static MachineOperand CreateMBB(MachineBasicBlock *MBB,
+                                  unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
+    Op.setMBB(MBB);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateFI(int Idx) {
+    MachineOperand Op(MachineOperand::MO_FrameIndex);
+    Op.setIndex(Idx);
+    return Op;
+  }
+  static MachineOperand CreateCPI(unsigned Idx, int Offset,
+                                  unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
+    Op.setIndex(Idx);
+    Op.setOffset(Offset);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateTargetIndex(unsigned Idx, int64_t Offset,
+                                          unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_TargetIndex);
+    Op.setIndex(Idx);
+    Op.setOffset(Offset);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateJTI(unsigned Idx,
+                                  unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_JumpTableIndex);
+    Op.setIndex(Idx);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset,
+                                 unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_GlobalAddress);
+    Op.Contents.OffsetedInfo.Val.GV = GV;
+    Op.setOffset(Offset);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateES(const char *SymName,
+                                 unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_ExternalSymbol);
+    Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
+    Op.setOffset(0); // Offset is always 0.
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset,
+                                 unsigned char TargetFlags = 0) {
+    MachineOperand Op(MachineOperand::MO_BlockAddress);
+    Op.Contents.OffsetedInfo.Val.BA = BA;
+    Op.setOffset(Offset);
+    Op.setTargetFlags(TargetFlags);
+    return Op;
+  }
+  /// CreateRegMask - Creates a register mask operand referencing Mask.  The
+  /// operand does not take ownership of the memory referenced by Mask, it must
+  /// remain valid for the lifetime of the operand.
+  ///
+  /// A RegMask operand represents a set of non-clobbered physical registers on
+  /// an instruction that clobbers many registers, typically a call.  The bit
+  /// mask has a bit set for each physreg that is preserved by this
+  /// instruction, as described in the documentation for
+  /// TargetRegisterInfo::getCallPreservedMask().
+  ///
+  /// Any physreg with a 0 bit in the mask is clobbered by the instruction.
+  ///
+  static MachineOperand CreateRegMask(const uint32_t *Mask) {
+    assert(Mask && "Missing register mask");
+    MachineOperand Op(MachineOperand::MO_RegisterMask);
+    Op.Contents.RegMask = Mask;
+    return Op;
+  }
+  static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
+    assert(Mask && "Missing live-out register mask");
+    MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
+    Op.Contents.RegMask = Mask;
+    return Op;
+  }
+  static MachineOperand CreateMetadata(const MDNode *Meta) {
+    MachineOperand Op(MachineOperand::MO_Metadata);
+    Op.Contents.MD = Meta;
+    return Op;
+  }
+
+  static MachineOperand CreateMCSymbol(MCSymbol *Sym) {
+    MachineOperand Op(MachineOperand::MO_MCSymbol);
+    Op.Contents.Sym = Sym;
+    return Op;
+  }
+
+  static MachineOperand CreateCFIIndex(unsigned CFIIndex) {
+    MachineOperand Op(MachineOperand::MO_CFIIndex);
+    Op.Contents.CFIIndex = CFIIndex;
+    return Op;
+  }
+
+  friend class MachineInstr;
+  friend class MachineRegisterInfo;
+private:
+  //===--------------------------------------------------------------------===//
+  // Methods for handling register use/def lists.
+  //===--------------------------------------------------------------------===//
+
+  /// isOnRegUseList - Return true if this operand is on a register use/def list
+  /// or false if not.  This can only be called for register operands that are
+  /// part of a machine instruction.
+  bool isOnRegUseList() const {
+    assert(isReg() && "Can only add reg operand to use lists");
+    return Contents.Reg.Prev != nullptr;
+  }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
+  MO.print(OS, nullptr);
+  return OS;
+}
+
+  // See friend declaration above. This additional declaration is required in
+  // order to compile LLVM with IBM xlC compiler.
+  hash_code hash_value(const MachineOperand &MO);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
new file mode 100644
index 0000000..c962e68
--- /dev/null
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -0,0 +1,156 @@
+//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the mechanics for machine function pass registries.  A
+// function pass registry (MachinePassRegistry) is auto filled by the static
+// constructors of MachinePassRegistryNode.  Further there is a command line
+// parser (RegisterPassParser) which listens to each registry for additions
+// and deletions, so that the appropriate command option is updated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+#define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+typedef void *(*MachinePassCtor)();
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryListener - Listener to adds and removals of nodes in
+/// registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryListener {
+  virtual void anchor();
+public:
+  MachinePassRegistryListener() {}
+  virtual ~MachinePassRegistryListener() {}
+  virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0;
+  virtual void NotifyRemove(const char *N) = 0;
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryNode - Machine pass node stored in registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryNode {
+
+private:
+
+  MachinePassRegistryNode *Next;        // Next function pass in list.
+  const char *Name;                     // Name of function pass.
+  const char *Description;              // Description string.
+  MachinePassCtor Ctor;                 // Function pass creator.
+
+public:
+
+  MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
+  : Next(nullptr)
+  , Name(N)
+  , Description(D)
+  , Ctor(C)
+  {}
+
+  // Accessors
+  MachinePassRegistryNode *getNext()      const { return Next; }
+  MachinePassRegistryNode **getNextAddress()    { return &Next; }
+  const char *getName()                   const { return Name; }
+  const char *getDescription()            const { return Description; }
+  MachinePassCtor getCtor()               const { return Ctor; }
+  void setNext(MachinePassRegistryNode *N)      { Next = N; }
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistry - Track the registration of machine passes.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistry {
+
+private:
+
+  MachinePassRegistryNode *List;        // List of registry nodes.
+  MachinePassCtor Default;              // Default function pass creator.
+  MachinePassRegistryListener* Listener;// Listener for list adds are removes.
+
+public:
+
+  // NO CONSTRUCTOR - we don't want static constructor ordering to mess
+  // with the registry.
+
+  // Accessors.
+  //
+  MachinePassRegistryNode *getList()                    { return List; }
+  MachinePassCtor getDefault()                          { return Default; }
+  void setDefault(MachinePassCtor C)                    { Default = C; }
+  void setDefault(StringRef Name);
+  void setListener(MachinePassRegistryListener *L)      { Listener = L; }
+
+  /// Add - Adds a function pass to the registration list.
+  ///
+  void Add(MachinePassRegistryNode *Node);
+
+  /// Remove - Removes a function pass from the registration list.
+  ///
+  void Remove(MachinePassRegistryNode *Node);
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterPassParser class - Handle the addition of new machine passes.
+///
+//===----------------------------------------------------------------------===//
+template<class RegistryClass>
+class RegisterPassParser : public MachinePassRegistryListener,
+                   public cl::parser<typename RegistryClass::FunctionPassCtor> {
+public:
+  RegisterPassParser() {}
+  ~RegisterPassParser() { RegistryClass::setListener(nullptr); }
+
+  void initialize(cl::Option &O) {
+    cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O);
+
+    // Add existing passes to option.
+    for (RegistryClass *Node = RegistryClass::getList();
+         Node; Node = Node->getNext()) {
+      this->addLiteralOption(Node->getName(),
+                      (typename RegistryClass::FunctionPassCtor)Node->getCtor(),
+                             Node->getDescription());
+    }
+
+    // Make sure we listen for list changes.
+    RegistryClass::setListener(this);
+  }
+
+  // Implement the MachinePassRegistryListener callbacks.
+  //
+  void NotifyAdd(const char *N, MachinePassCtor C, const char *D) override {
+    this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
+  }
+  void NotifyRemove(const char *N) override {
+    this->removeLiteralOption(N);
+  }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h
new file mode 100644
index 0000000..beb2c4f
--- /dev/null
+++ b/include/llvm/CodeGen/MachinePostDominators.h
@@ -0,0 +1,86 @@
+//=- llvm/CodeGen/MachineDominators.h ----------------------------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes interfaces to post dominance information for
+// target-specific code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
+#define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
+
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+///
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used
+/// to compute the a post-dominator tree.
+///
+struct MachinePostDominatorTree : public MachineFunctionPass {
+private:
+  DominatorTreeBase<MachineBasicBlock> *DT;
+
+public:
+  static char ID;
+
+  MachinePostDominatorTree();
+
+  ~MachinePostDominatorTree();
+
+  FunctionPass *createMachinePostDominatorTreePass();
+
+  const std::vector<MachineBasicBlock *> &getRoots() const {
+    return DT->getRoots();
+  }
+
+  MachineDomTreeNode *getRootNode() const {
+    return DT->getRootNode();
+  }
+
+  MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
+    return DT->getNode(BB);
+  }
+
+  bool dominates(const MachineDomTreeNode *A,
+                 const MachineDomTreeNode *B) const {
+    return DT->dominates(A, B);
+  }
+
+  bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) const {
+    return DT->dominates(A, B);
+  }
+
+  bool properlyDominates(const MachineDomTreeNode *A,
+                         const MachineDomTreeNode *B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  bool properlyDominates(const MachineBasicBlock *A,
+                         const MachineBasicBlock *B) const {
+    return DT->properlyDominates(A, B);
+  }
+
+  MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
+                                                MachineBasicBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void print(llvm::raw_ostream &OS, const Module *M = nullptr) const override;
+};
+} //end of namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRegionInfo.h b/include/llvm/CodeGen/MachineRegionInfo.h
new file mode 100644
index 0000000..43499db
--- /dev/null
+++ b/include/llvm/CodeGen/MachineRegionInfo.h
@@ -0,0 +1,183 @@
+//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
+#define LLVM_CODEGEN_MACHINEREGIONINFO_H
+
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/CodeGen/MachineDominanceFrontier.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+
+
+namespace llvm {
+
+class MachineDominatorTree;
+struct MachinePostDominatorTree;
+class MachineRegion;
+class MachineRegionNode;
+class MachineRegionInfo;
+
+template<>
+struct RegionTraits<MachineFunction> {
+  typedef MachineFunction FuncT;
+  typedef MachineBasicBlock BlockT;
+  typedef MachineRegion RegionT;
+  typedef MachineRegionNode RegionNodeT;
+  typedef MachineRegionInfo RegionInfoT;
+  typedef MachineDominatorTree DomTreeT;
+  typedef MachineDomTreeNode DomTreeNodeT;
+  typedef MachinePostDominatorTree PostDomTreeT;
+  typedef MachineDominanceFrontier DomFrontierT;
+  typedef MachineInstr InstT;
+  typedef MachineLoop LoopT;
+  typedef MachineLoopInfo LoopInfoT;
+
+  static unsigned getNumSuccessors(MachineBasicBlock *BB) {
+    return BB->succ_size();
+  }
+};
+
+
+class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
+public:
+  inline MachineRegionNode(MachineRegion *Parent,
+                           MachineBasicBlock *Entry,
+                           bool isSubRegion = false)
+    : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, isSubRegion) {
+
+  }
+
+  ~MachineRegionNode() { }
+
+  bool operator==(const MachineRegion &RN) const {
+    return this == reinterpret_cast<const MachineRegionNode*>(&RN);
+  }
+};
+
+class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
+public:
+  MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
+                MachineRegionInfo* RI,
+                MachineDominatorTree *DT, MachineRegion *Parent = nullptr);
+  ~MachineRegion();
+
+  bool operator==(const MachineRegionNode &RN) const {
+    return &RN == reinterpret_cast<const MachineRegionNode*>(this);
+  }
+};
+
+class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
+public:
+  explicit MachineRegionInfo();
+
+  virtual ~MachineRegionInfo();
+
+  // updateStatistics - Update statistic about created regions.
+  void updateStatistics(MachineRegion *R) final;
+
+  void recalculate(MachineFunction &F,
+                   MachineDominatorTree *DT,
+                   MachinePostDominatorTree *PDT,
+                   MachineDominanceFrontier *DF);
+};
+
+class MachineRegionInfoPass : public MachineFunctionPass {
+  MachineRegionInfo RI;
+
+public:
+  static char ID;
+  explicit MachineRegionInfoPass();
+
+  ~MachineRegionInfoPass();
+
+  MachineRegionInfo &getRegionInfo() {
+    return RI;
+  }
+
+  const MachineRegionInfo &getRegionInfo() const {
+    return RI;
+  }
+
+  /// @name MachineFunctionPass interface
+  //@{
+  bool runOnMachineFunction(MachineFunction &F) override;
+  void releaseMemory() override;
+  void verifyAnalysis() const override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  void print(raw_ostream &OS, const Module *) const override;
+  void dump() const;
+  //@}
+};
+
+
+template <>
+template <>
+inline MachineBasicBlock* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() const {
+  assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
+  return getEntry();
+}
+
+template<>
+template<>
+inline MachineRegion* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() const {
+  assert(isSubRegion() && "This is not a subregion RegionNode!");
+  auto Unconst = const_cast<RegionNodeBase<RegionTraits<MachineFunction>>*>(this);
+  return reinterpret_cast<MachineRegion*>(Unconst);
+}
+
+
+RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
+RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, MachineRegion);
+
+RegionGraphTraits(MachineRegion, MachineRegionNode);
+RegionGraphTraits(const MachineRegion, const MachineRegionNode);
+
+template <> struct GraphTraits<MachineRegionInfo*>
+  : public GraphTraits<FlatIt<MachineRegionNode*> > {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(MachineRegionInfo *RI) {
+    return GraphTraits<FlatIt<MachineRegion*> >::getEntryNode(RI->getTopLevelRegion());
+  }
+  static nodes_iterator nodes_begin(MachineRegionInfo* RI) {
+    return nodes_iterator::begin(getEntryNode(RI));
+  }
+  static nodes_iterator nodes_end(MachineRegionInfo *RI) {
+    return nodes_iterator::end(getEntryNode(RI));
+  }
+};
+
+template <> struct GraphTraits<MachineRegionInfoPass*>
+  : public GraphTraits<MachineRegionInfo *> {
+  typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+                      GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+  static NodeType *getEntryNode(MachineRegionInfoPass *RI) {
+    return GraphTraits<MachineRegionInfo*>::getEntryNode(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_begin(MachineRegionInfoPass* RI) {
+    return GraphTraits<MachineRegionInfo*>::nodes_begin(&RI->getRegionInfo());
+  }
+  static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
+    return GraphTraits<MachineRegionInfo*>::nodes_end(&RI->getRegionInfo());
+  }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>);
+EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>);
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
new file mode 100644
index 0000000..51139f7
--- /dev/null
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -0,0 +1,1012 @@
+//===-- llvm/CodeGen/MachineRegisterInfo.h ----------------------*- 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 MachineRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEREGISTERINFO_H
+#define LLVM_CODEGEN_MACHINEREGISTERINFO_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <vector>
+
+namespace llvm {
+class PSetIterator;
+
+/// MachineRegisterInfo - Keep track of information for virtual and physical
+/// registers, including vreg register classes, use/def chains for registers,
+/// etc.
+class MachineRegisterInfo {
+public:
+  class Delegate {
+    virtual void anchor();
+  public:
+    virtual void MRI_NoteNewVirtualRegister(unsigned Reg) = 0;
+
+    virtual ~Delegate() {}
+  };
+
+private:
+  const TargetMachine &TM;
+  Delegate *TheDelegate;
+
+  /// IsSSA - True when the machine function is in SSA form and virtual
+  /// registers have a single def.
+  bool IsSSA;
+
+  /// TracksLiveness - True while register liveness is being tracked accurately.
+  /// Basic block live-in lists, kill flags, and implicit defs may not be
+  /// accurate when after this flag is cleared.
+  bool TracksLiveness;
+
+  /// VRegInfo - Information we keep for each virtual register.
+  ///
+  /// Each element in this list contains the register class of the vreg and the
+  /// start of the use/def list for the register.
+  IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
+             VirtReg2IndexFunctor> VRegInfo;
+
+  /// RegAllocHints - This vector records register allocation hints for virtual
+  /// registers. For each virtual register, it keeps a register and hint type
+  /// pair making up the allocation hint. Hint type is target specific except
+  /// for the value 0 which means the second value of the pair is the preferred
+  /// register for allocation. For example, if the hint is <0, 1024>, it means
+  /// the allocator should prefer the physical register allocated to the virtual
+  /// register of the hint.
+  IndexedMap<std::pair<unsigned, unsigned>, VirtReg2IndexFunctor> RegAllocHints;
+
+  /// PhysRegUseDefLists - This is an array of the head of the use/def list for
+  /// physical registers.
+  MachineOperand **PhysRegUseDefLists;
+
+  /// getRegUseDefListHead - Return the head pointer for the register use/def
+  /// list for the specified virtual or physical register.
+  MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
+    if (TargetRegisterInfo::isVirtualRegister(RegNo))
+      return VRegInfo[RegNo].second;
+    return PhysRegUseDefLists[RegNo];
+  }
+
+  MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
+    if (TargetRegisterInfo::isVirtualRegister(RegNo))
+      return VRegInfo[RegNo].second;
+    return PhysRegUseDefLists[RegNo];
+  }
+
+  /// Get the next element in the use-def chain.
+  static MachineOperand *getNextOperandForReg(const MachineOperand *MO) {
+    assert(MO && MO->isReg() && "This is not a register operand!");
+    return MO->Contents.Reg.Next;
+  }
+
+  /// UsedRegUnits - This is a bit vector that is computed and set by the
+  /// register allocator, and must be kept up to date by passes that run after
+  /// register allocation (though most don't modify this).  This is used
+  /// so that the code generator knows which callee save registers to save and
+  /// for other target specific uses.
+  /// This vector has bits set for register units that are modified in the
+  /// current function. It doesn't include registers clobbered by function
+  /// calls with register mask operands.
+  BitVector UsedRegUnits;
+
+  /// UsedPhysRegMask - Additional used physregs including aliases.
+  /// This bit vector represents all the registers clobbered by function calls.
+  /// It can model things that UsedRegUnits can't, such as function calls that
+  /// clobber ymm7 but preserve the low half in xmm7.
+  BitVector UsedPhysRegMask;
+
+  /// ReservedRegs - This is a bit vector of reserved registers.  The target
+  /// may change its mind about which registers should be reserved.  This
+  /// vector is the frozen set of reserved registers when register allocation
+  /// started.
+  BitVector ReservedRegs;
+
+  /// Keep track of the physical registers that are live in to the function.
+  /// Live in values are typically arguments in registers.  LiveIn values are
+  /// allowed to have virtual registers associated with them, stored in the
+  /// second element.
+  std::vector<std::pair<unsigned, unsigned> > LiveIns;
+
+  MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
+  void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
+public:
+  explicit MachineRegisterInfo(const TargetMachine &TM);
+  ~MachineRegisterInfo();
+
+  const TargetRegisterInfo *getTargetRegisterInfo() const {
+    return TM.getRegisterInfo();
+  }
+
+  void resetDelegate(Delegate *delegate) {
+    // Ensure another delegate does not take over unless the current
+    // delegate first unattaches itself. If we ever need to multicast
+    // notifications, we will need to change to using a list.
+    assert(TheDelegate == delegate &&
+           "Only the current delegate can perform reset!");
+    TheDelegate = nullptr;
+  }
+
+  void setDelegate(Delegate *delegate) {
+    assert(delegate && !TheDelegate &&
+           "Attempted to set delegate to null, or to change it without "
+           "first resetting it!");
+
+    TheDelegate = delegate;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Function State
+  //===--------------------------------------------------------------------===//
+
+  // isSSA - Returns true when the machine function is in SSA form. Early
+  // passes require the machine function to be in SSA form where every virtual
+  // register has a single defining instruction.
+  //
+  // The TwoAddressInstructionPass and PHIElimination passes take the machine
+  // function out of SSA form when they introduce multiple defs per virtual
+  // register.
+  bool isSSA() const { return IsSSA; }
+
+  // leaveSSA - Indicates that the machine function is no longer in SSA form.
+  void leaveSSA() { IsSSA = false; }
+
+  /// tracksLiveness - Returns true when tracking register liveness accurately.
+  ///
+  /// While this flag is true, register liveness information in basic block
+  /// live-in lists and machine instruction operands is accurate. This means it
+  /// can be used to change the code in ways that affect the values in
+  /// registers, for example by the register scavenger.
+  ///
+  /// When this flag is false, liveness is no longer reliable.
+  bool tracksLiveness() const { return TracksLiveness; }
+
+  /// invalidateLiveness - Indicates that register liveness is no longer being
+  /// tracked accurately.
+  ///
+  /// This should be called by late passes that invalidate the liveness
+  /// information.
+  void invalidateLiveness() { TracksLiveness = false; }
+
+  //===--------------------------------------------------------------------===//
+  // Register Info
+  //===--------------------------------------------------------------------===//
+
+  // Strictly for use by MachineInstr.cpp.
+  void addRegOperandToUseList(MachineOperand *MO);
+
+  // Strictly for use by MachineInstr.cpp.
+  void removeRegOperandFromUseList(MachineOperand *MO);
+
+  // Strictly for use by MachineInstr.cpp.
+  void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps);
+
+  /// Verify the sanity of the use list for Reg.
+  void verifyUseList(unsigned Reg) const;
+
+  /// Verify the use list of all registers.
+  void verifyUseLists() const;
+
+  /// reg_begin/reg_end - Provide iteration support to walk over all definitions
+  /// and uses of a register within the MachineFunction that corresponds to this
+  /// MachineRegisterInfo object.
+  template<bool Uses, bool Defs, bool SkipDebug,
+           bool ByOperand, bool ByInstr, bool ByBundle>
+  class defusechain_iterator;
+  template<bool Uses, bool Defs, bool SkipDebug,
+           bool ByOperand, bool ByInstr, bool ByBundle>
+  class defusechain_instr_iterator;
+
+  // Make it a friend so it can access getNextOperandForReg().
+  template<bool, bool, bool, bool, bool, bool>
+    friend class defusechain_iterator;
+  template<bool, bool, bool, bool, bool, bool>
+    friend class defusechain_instr_iterator;
+
+
+
+  /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
+  /// register.
+  typedef defusechain_iterator<true,true,false,true,false,false>
+          reg_iterator;
+  reg_iterator reg_begin(unsigned RegNo) const {
+    return reg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_iterator reg_end() { return reg_iterator(nullptr); }
+
+  inline iterator_range<reg_iterator>  reg_operands(unsigned Reg) const {
+    return iterator_range<reg_iterator>(reg_begin(Reg), reg_end());
+  }
+
+  /// reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses
+  /// of the specified register, stepping by MachineInstr.
+  typedef defusechain_instr_iterator<true,true,false,false,true,false>
+          reg_instr_iterator;
+  reg_instr_iterator reg_instr_begin(unsigned RegNo) const {
+    return reg_instr_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_instr_iterator reg_instr_end() {
+    return reg_instr_iterator(nullptr);
+  }
+
+  inline iterator_range<reg_instr_iterator>
+  reg_instructions(unsigned Reg) const {
+    return iterator_range<reg_instr_iterator>(reg_instr_begin(Reg),
+                                              reg_instr_end());
+  }
+
+  /// reg_bundle_iterator/reg_bundle_begin/reg_bundle_end - Walk all defs and uses
+  /// of the specified register, stepping by bundle.
+  typedef defusechain_instr_iterator<true,true,false,false,false,true>
+          reg_bundle_iterator;
+  reg_bundle_iterator reg_bundle_begin(unsigned RegNo) const {
+    return reg_bundle_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_bundle_iterator reg_bundle_end() {
+    return reg_bundle_iterator(nullptr);
+  }
+
+  inline iterator_range<reg_bundle_iterator> reg_bundles(unsigned Reg) const {
+    return iterator_range<reg_bundle_iterator>(reg_bundle_begin(Reg),
+                                               reg_bundle_end());
+  }
+
+  /// reg_empty - Return true if there are no instructions using or defining the
+  /// specified register (it may be live-in).
+  bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
+
+  /// reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses
+  /// of the specified register, skipping those marked as Debug.
+  typedef defusechain_iterator<true,true,true,true,false,false>
+          reg_nodbg_iterator;
+  reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const {
+    return reg_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_nodbg_iterator reg_nodbg_end() {
+    return reg_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<reg_nodbg_iterator>
+  reg_nodbg_operands(unsigned Reg) const {
+    return iterator_range<reg_nodbg_iterator>(reg_nodbg_begin(Reg),
+                                              reg_nodbg_end());
+  }
+
+  /// reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk
+  /// all defs and uses of the specified register, stepping by MachineInstr,
+  /// skipping those marked as Debug.
+  typedef defusechain_instr_iterator<true,true,true,false,true,false>
+          reg_instr_nodbg_iterator;
+  reg_instr_nodbg_iterator reg_instr_nodbg_begin(unsigned RegNo) const {
+    return reg_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_instr_nodbg_iterator reg_instr_nodbg_end() {
+    return reg_instr_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<reg_instr_nodbg_iterator>
+  reg_nodbg_instructions(unsigned Reg) const {
+    return iterator_range<reg_instr_nodbg_iterator>(reg_instr_nodbg_begin(Reg),
+                                                    reg_instr_nodbg_end());
+  }
+
+  /// reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk
+  /// all defs and uses of the specified register, stepping by bundle,
+  /// skipping those marked as Debug.
+  typedef defusechain_instr_iterator<true,true,true,false,false,true>
+          reg_bundle_nodbg_iterator;
+  reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(unsigned RegNo) const {
+    return reg_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static reg_bundle_nodbg_iterator reg_bundle_nodbg_end() {
+    return reg_bundle_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<reg_bundle_nodbg_iterator> 
+  reg_nodbg_bundles(unsigned Reg) const {
+    return iterator_range<reg_bundle_nodbg_iterator>(reg_bundle_nodbg_begin(Reg),
+                                                     reg_bundle_nodbg_end());
+  }
+
+  /// reg_nodbg_empty - Return true if the only instructions using or defining
+  /// Reg are Debug instructions.
+  bool reg_nodbg_empty(unsigned RegNo) const {
+    return reg_nodbg_begin(RegNo) == reg_nodbg_end();
+  }
+
+  /// def_iterator/def_begin/def_end - Walk all defs of the specified register.
+  typedef defusechain_iterator<false,true,false,true,false,false>
+          def_iterator;
+  def_iterator def_begin(unsigned RegNo) const {
+    return def_iterator(getRegUseDefListHead(RegNo));
+  }
+  static def_iterator def_end() { return def_iterator(nullptr); }
+
+  inline iterator_range<def_iterator> def_operands(unsigned Reg) const {
+    return iterator_range<def_iterator>(def_begin(Reg), def_end());
+  }
+
+  /// def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the
+  /// specified register, stepping by MachineInst.
+  typedef defusechain_instr_iterator<false,true,false,false,true,false>
+          def_instr_iterator;
+  def_instr_iterator def_instr_begin(unsigned RegNo) const {
+    return def_instr_iterator(getRegUseDefListHead(RegNo));
+  }
+  static def_instr_iterator def_instr_end() {
+    return def_instr_iterator(nullptr);
+  }
+
+  inline iterator_range<def_instr_iterator>
+  def_instructions(unsigned Reg) const {
+    return iterator_range<def_instr_iterator>(def_instr_begin(Reg),
+                                              def_instr_end());
+  }
+
+  /// def_bundle_iterator/def_bundle_begin/def_bundle_end - Walk all defs of the
+  /// specified register, stepping by bundle.
+  typedef defusechain_instr_iterator<false,true,false,false,false,true>
+          def_bundle_iterator;
+  def_bundle_iterator def_bundle_begin(unsigned RegNo) const {
+    return def_bundle_iterator(getRegUseDefListHead(RegNo));
+  }
+  static def_bundle_iterator def_bundle_end() {
+    return def_bundle_iterator(nullptr);
+  }
+
+  inline iterator_range<def_bundle_iterator> def_bundles(unsigned Reg) const {
+    return iterator_range<def_bundle_iterator>(def_bundle_begin(Reg),
+                                               def_bundle_end());
+  }
+
+  /// def_empty - Return true if there are no instructions defining the
+  /// specified register (it may be live-in).
+  bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
+
+  /// hasOneDef - Return true if there is exactly one instruction defining the
+  /// specified register.
+  bool hasOneDef(unsigned RegNo) const {
+    def_iterator DI = def_begin(RegNo);
+    if (DI == def_end())
+      return false;
+    return ++DI == def_end();
+  }
+
+  /// use_iterator/use_begin/use_end - Walk all uses of the specified register.
+  typedef defusechain_iterator<true,false,false,true,false,false>
+          use_iterator;
+  use_iterator use_begin(unsigned RegNo) const {
+    return use_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_iterator use_end() { return use_iterator(nullptr); }
+
+  inline iterator_range<use_iterator> use_operands(unsigned Reg) const {
+    return iterator_range<use_iterator>(use_begin(Reg), use_end());
+  }
+
+  /// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the
+  /// specified register, stepping by MachineInstr.
+  typedef defusechain_instr_iterator<true,false,false,false,true,false>
+          use_instr_iterator;
+  use_instr_iterator use_instr_begin(unsigned RegNo) const {
+    return use_instr_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_instr_iterator use_instr_end() {
+    return use_instr_iterator(nullptr);
+  }
+
+  inline iterator_range<use_instr_iterator>
+  use_instructions(unsigned Reg) const {
+    return iterator_range<use_instr_iterator>(use_instr_begin(Reg),
+                                              use_instr_end());
+  }
+
+  /// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the
+  /// specified register, stepping by bundle.
+  typedef defusechain_instr_iterator<true,false,false,false,false,true>
+          use_bundle_iterator;
+  use_bundle_iterator use_bundle_begin(unsigned RegNo) const {
+    return use_bundle_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_bundle_iterator use_bundle_end() {
+    return use_bundle_iterator(nullptr);
+  }
+
+  inline iterator_range<use_bundle_iterator> use_bundles(unsigned Reg) const {
+    return iterator_range<use_bundle_iterator>(use_bundle_begin(Reg),
+                                               use_bundle_end());
+  }
+
+  /// use_empty - Return true if there are no instructions using the specified
+  /// register.
+  bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+
+  /// hasOneUse - Return true if there is exactly one instruction using the
+  /// specified register.
+  bool hasOneUse(unsigned RegNo) const {
+    use_iterator UI = use_begin(RegNo);
+    if (UI == use_end())
+      return false;
+    return ++UI == use_end();
+  }
+
+  /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
+  /// specified register, skipping those marked as Debug.
+  typedef defusechain_iterator<true,false,true,true,false,false>
+          use_nodbg_iterator;
+  use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
+    return use_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_nodbg_iterator use_nodbg_end() {
+    return use_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<use_nodbg_iterator>
+  use_nodbg_operands(unsigned Reg) const {
+    return iterator_range<use_nodbg_iterator>(use_nodbg_begin(Reg),
+                                              use_nodbg_end());
+  }
+
+  /// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk
+  /// all uses of the specified register, stepping by MachineInstr, skipping
+  /// those marked as Debug.
+  typedef defusechain_instr_iterator<true,false,true,false,true,false>
+          use_instr_nodbg_iterator;
+  use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const {
+    return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_instr_nodbg_iterator use_instr_nodbg_end() {
+    return use_instr_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<use_instr_nodbg_iterator>
+  use_nodbg_instructions(unsigned Reg) const {
+    return iterator_range<use_instr_nodbg_iterator>(use_instr_nodbg_begin(Reg),
+                                                    use_instr_nodbg_end());
+  }
+
+  /// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk
+  /// all uses of the specified register, stepping by bundle, skipping
+  /// those marked as Debug.
+  typedef defusechain_instr_iterator<true,false,true,false,false,true>
+          use_bundle_nodbg_iterator;
+  use_bundle_nodbg_iterator use_bundle_nodbg_begin(unsigned RegNo) const {
+    return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
+  }
+  static use_bundle_nodbg_iterator use_bundle_nodbg_end() {
+    return use_bundle_nodbg_iterator(nullptr);
+  }
+
+  inline iterator_range<use_bundle_nodbg_iterator>
+  use_nodbg_bundles(unsigned Reg) const {
+    return iterator_range<use_bundle_nodbg_iterator>(use_bundle_nodbg_begin(Reg),
+                                                     use_bundle_nodbg_end());
+  }
+
+  /// use_nodbg_empty - Return true if there are no non-Debug instructions
+  /// using the specified register.
+  bool use_nodbg_empty(unsigned RegNo) const {
+    return use_nodbg_begin(RegNo) == use_nodbg_end();
+  }
+
+  /// hasOneNonDBGUse - Return true if there is exactly one non-Debug
+  /// instruction using the specified register.
+  bool hasOneNonDBGUse(unsigned RegNo) const;
+
+  /// replaceRegWith - Replace all instances of FromReg with ToReg in the
+  /// machine function.  This is like llvm-level X->replaceAllUsesWith(Y),
+  /// except that it also changes any definitions of the register as well.
+  ///
+  /// Note that it is usually necessary to first constrain ToReg's register
+  /// class to match the FromReg constraints using:
+  ///
+  ///   constrainRegClass(ToReg, getRegClass(FromReg))
+  ///
+  /// That function will return NULL if the virtual registers have incompatible
+  /// constraints.
+  void replaceRegWith(unsigned FromReg, unsigned ToReg);
+
+  /// getVRegDef - Return the machine instr that defines the specified virtual
+  /// register or null if none is found.  This assumes that the code is in SSA
+  /// form, so there should only be one definition.
+  MachineInstr *getVRegDef(unsigned Reg) const;
+
+  /// getUniqueVRegDef - Return the unique machine instr that defines the
+  /// specified virtual register or null if none is found.  If there are
+  /// multiple definitions or no definition, return null.
+  MachineInstr *getUniqueVRegDef(unsigned Reg) const;
+
+  /// clearKillFlags - Iterate over all the uses of the given register and
+  /// clear the kill flag from the MachineOperand. This function is used by
+  /// optimization passes which extend register lifetimes and need only
+  /// preserve conservative kill flag information.
+  void clearKillFlags(unsigned Reg) const;
+
+#ifndef NDEBUG
+  void dumpUses(unsigned RegNo) const;
+#endif
+
+  /// isConstantPhysReg - Returns true if PhysReg is unallocatable and constant
+  /// throughout the function.  It is safe to move instructions that read such
+  /// a physreg.
+  bool isConstantPhysReg(unsigned PhysReg, const MachineFunction &MF) const;
+
+  /// Get an iterator over the pressure sets affected by the given physical or
+  /// virtual register. If RegUnit is physical, it must be a register unit (from
+  /// MCRegUnitIterator).
+  PSetIterator getPressureSets(unsigned RegUnit) const;
+
+  //===--------------------------------------------------------------------===//
+  // Virtual Register Info
+  //===--------------------------------------------------------------------===//
+
+  /// getRegClass - Return the register class of the specified virtual register.
+  ///
+  const TargetRegisterClass *getRegClass(unsigned Reg) const {
+    return VRegInfo[Reg].first;
+  }
+
+  /// setRegClass - Set the register class of the specified virtual register.
+  ///
+  void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
+
+  /// constrainRegClass - Constrain the register class of the specified virtual
+  /// register to be a common subclass of RC and the current register class,
+  /// but only if the new class has at least MinNumRegs registers.  Return the
+  /// new register class, or NULL if no such class exists.
+  /// This should only be used when the constraint is known to be trivial, like
+  /// GR32 -> GR32_NOSP. Beware of increasing register pressure.
+  ///
+  const TargetRegisterClass *constrainRegClass(unsigned Reg,
+                                               const TargetRegisterClass *RC,
+                                               unsigned MinNumRegs = 0);
+
+  /// recomputeRegClass - Try to find a legal super-class of Reg's register
+  /// class that still satisfies the constraints from the instructions using
+  /// Reg.  Returns true if Reg was upgraded.
+  ///
+  /// This method can be used after constraints have been removed from a
+  /// virtual register, for example after removing instructions or splitting
+  /// the live range.
+  ///
+  bool recomputeRegClass(unsigned Reg, const TargetMachine&);
+
+  /// createVirtualRegister - Create and return a new virtual register in the
+  /// function with the specified register class.
+  ///
+  unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
+
+  /// getNumVirtRegs - Return the number of virtual registers created.
+  ///
+  unsigned getNumVirtRegs() const { return VRegInfo.size(); }
+
+  /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
+  void clearVirtRegs();
+
+  /// setRegAllocationHint - Specify a register allocation hint for the
+  /// specified virtual register.
+  void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
+    RegAllocHints[Reg].first  = Type;
+    RegAllocHints[Reg].second = PrefReg;
+  }
+
+  /// getRegAllocationHint - Return the register allocation hint for the
+  /// specified virtual register.
+  std::pair<unsigned, unsigned>
+  getRegAllocationHint(unsigned Reg) const {
+    return RegAllocHints[Reg];
+  }
+
+  /// getSimpleHint - Return the preferred register allocation hint, or 0 if a
+  /// standard simple hint (Type == 0) is not set.
+  unsigned getSimpleHint(unsigned Reg) const {
+    std::pair<unsigned, unsigned> Hint = getRegAllocationHint(Reg);
+    return Hint.first ? 0 : Hint.second;
+  }
+
+  /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
+  /// specified register as undefined which causes the DBG_VALUE to be
+  /// deleted during LiveDebugVariables analysis.
+  void markUsesInDebugValueAsUndef(unsigned Reg) const;
+
+  //===--------------------------------------------------------------------===//
+  // Physical Register Use Info
+  //===--------------------------------------------------------------------===//
+
+  /// isPhysRegUsed - Return true if the specified register is used in this
+  /// function. Also check for clobbered aliases and registers clobbered by
+  /// function calls with register mask operands.
+  ///
+  /// This only works after register allocation. It is primarily used by
+  /// PrologEpilogInserter to determine which callee-saved registers need
+  /// spilling.
+  bool isPhysRegUsed(unsigned Reg) const {
+    if (UsedPhysRegMask.test(Reg))
+      return true;
+    for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+         Units.isValid(); ++Units)
+      if (UsedRegUnits.test(*Units))
+        return true;
+    return false;
+  }
+
+  /// Mark the specified register unit as used in this function.
+  /// This should only be called during and after register allocation.
+  void setRegUnitUsed(unsigned RegUnit) {
+    UsedRegUnits.set(RegUnit);
+  }
+
+  /// setPhysRegUsed - Mark the specified register used in this function.
+  /// This should only be called during and after register allocation.
+  void setPhysRegUsed(unsigned Reg) {
+    for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+         Units.isValid(); ++Units)
+      UsedRegUnits.set(*Units);
+  }
+
+  /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
+  /// This corresponds to the bit mask attached to register mask operands.
+  void addPhysRegsUsedFromRegMask(const uint32_t *RegMask) {
+    UsedPhysRegMask.setBitsNotInMask(RegMask);
+  }
+
+  /// setPhysRegUnused - Mark the specified register unused in this function.
+  /// This should only be called during and after register allocation.
+  void setPhysRegUnused(unsigned Reg) {
+    UsedPhysRegMask.reset(Reg);
+    for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
+         Units.isValid(); ++Units)
+      UsedRegUnits.reset(*Units);
+  }
+
+
+  //===--------------------------------------------------------------------===//
+  // Reserved Register Info
+  //===--------------------------------------------------------------------===//
+  //
+  // The set of reserved registers must be invariant during register
+  // allocation.  For example, the target cannot suddenly decide it needs a
+  // frame pointer when the register allocator has already used the frame
+  // pointer register for something else.
+  //
+  // These methods can be used by target hooks like hasFP() to avoid changing
+  // the reserved register set during register allocation.
+
+  /// freezeReservedRegs - Called by the register allocator to freeze the set
+  /// of reserved registers before allocation begins.
+  void freezeReservedRegs(const MachineFunction&);
+
+  /// reservedRegsFrozen - Returns true after freezeReservedRegs() was called
+  /// to ensure the set of reserved registers stays constant.
+  bool reservedRegsFrozen() const {
+    return !ReservedRegs.empty();
+  }
+
+  /// canReserveReg - Returns true if PhysReg can be used as a reserved
+  /// register.  Any register can be reserved before freezeReservedRegs() is
+  /// called.
+  bool canReserveReg(unsigned PhysReg) const {
+    return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
+  }
+
+  /// getReservedRegs - Returns a reference to the frozen set of reserved
+  /// registers. This method should always be preferred to calling
+  /// TRI::getReservedRegs() when possible.
+  const BitVector &getReservedRegs() const {
+    assert(reservedRegsFrozen() &&
+           "Reserved registers haven't been frozen yet. "
+           "Use TRI::getReservedRegs().");
+    return ReservedRegs;
+  }
+
+  /// isReserved - Returns true when PhysReg is a reserved register.
+  ///
+  /// Reserved registers may belong to an allocatable register class, but the
+  /// target has explicitly requested that they are not used.
+  ///
+  bool isReserved(unsigned PhysReg) const {
+    return getReservedRegs().test(PhysReg);
+  }
+
+  /// isAllocatable - Returns true when PhysReg belongs to an allocatable
+  /// register class and it hasn't been reserved.
+  ///
+  /// Allocatable registers may show up in the allocation order of some virtual
+  /// register, so a register allocator needs to track its liveness and
+  /// availability.
+  bool isAllocatable(unsigned PhysReg) const {
+    return getTargetRegisterInfo()->isInAllocatableClass(PhysReg) &&
+      !isReserved(PhysReg);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // LiveIn Management
+  //===--------------------------------------------------------------------===//
+
+  /// addLiveIn - Add the specified register as a live-in.  Note that it
+  /// is an error to add the same register to the same set more than once.
+  void addLiveIn(unsigned Reg, unsigned vreg = 0) {
+    LiveIns.push_back(std::make_pair(Reg, vreg));
+  }
+
+  // Iteration support for the live-ins set.  It's kept in sorted order
+  // by register number.
+  typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator
+  livein_iterator;
+  livein_iterator livein_begin() const { return LiveIns.begin(); }
+  livein_iterator livein_end()   const { return LiveIns.end(); }
+  bool            livein_empty() const { return LiveIns.empty(); }
+
+  bool isLiveIn(unsigned Reg) const;
+
+  /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
+  /// corresponding live-in physical register.
+  unsigned getLiveInPhysReg(unsigned VReg) const;
+
+  /// getLiveInVirtReg - If PReg is a live-in physical register, return the
+  /// corresponding live-in physical register.
+  unsigned getLiveInVirtReg(unsigned PReg) const;
+
+  /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
+  /// into the given entry block.
+  void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
+                        const TargetRegisterInfo &TRI,
+                        const TargetInstrInfo &TII);
+
+  /// defusechain_iterator - This class provides iterator support for machine
+  /// operands in the function that use or define a specific register.  If
+  /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
+  /// returns defs.  If neither are true then you are silly and it always
+  /// returns end().  If SkipDebug is true it skips uses marked Debug
+  /// when incrementing.
+  template<bool ReturnUses, bool ReturnDefs, bool SkipDebug,
+           bool ByOperand, bool ByInstr, bool ByBundle>
+  class defusechain_iterator
+    : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
+    MachineOperand *Op;
+    explicit defusechain_iterator(MachineOperand *op) : Op(op) {
+      // If the first node isn't one we're interested in, advance to one that
+      // we are interested in.
+      if (op) {
+        if ((!ReturnUses && op->isUse()) ||
+            (!ReturnDefs && op->isDef()) ||
+            (SkipDebug && op->isDebug()))
+          advance();
+      }
+    }
+    friend class MachineRegisterInfo;
+
+    void advance() {
+      assert(Op && "Cannot increment end iterator!");
+      Op = getNextOperandForReg(Op);
+
+      // All defs come before the uses, so stop def_iterator early.
+      if (!ReturnUses) {
+        if (Op) {
+          if (Op->isUse())
+            Op = nullptr;
+          else
+            assert(!Op->isDebug() && "Can't have debug defs");
+        }
+      } else {
+        // If this is an operand we don't care about, skip it.
+        while (Op && ((!ReturnDefs && Op->isDef()) ||
+                      (SkipDebug && Op->isDebug())))
+          Op = getNextOperandForReg(Op);
+      }
+    }
+  public:
+    typedef std::iterator<std::forward_iterator_tag,
+                          MachineInstr, ptrdiff_t>::reference reference;
+    typedef std::iterator<std::forward_iterator_tag,
+                          MachineInstr, ptrdiff_t>::pointer pointer;
+
+    defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {}
+    defusechain_iterator() : Op(nullptr) {}
+
+    bool operator==(const defusechain_iterator &x) const {
+      return Op == x.Op;
+    }
+    bool operator!=(const defusechain_iterator &x) const {
+      return !operator==(x);
+    }
+
+    /// atEnd - return true if this iterator is equal to reg_end() on the value.
+    bool atEnd() const { return Op == nullptr; }
+
+    // Iterator traversal: forward iteration only
+    defusechain_iterator &operator++() {          // Preincrement
+      assert(Op && "Cannot increment end iterator!");
+      if (ByOperand)
+        advance();
+      else if (ByInstr) {
+        MachineInstr *P = Op->getParent();
+        do {
+          advance();
+        } while (Op && Op->getParent() == P);
+      } else if (ByBundle) {
+        MachineInstr *P = getBundleStart(Op->getParent());
+        do {
+          advance();
+        } while (Op && getBundleStart(Op->getParent()) == P);
+      }
+
+      return *this;
+    }
+    defusechain_iterator operator++(int) {        // Postincrement
+      defusechain_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    /// getOperandNo - Return the operand # of this MachineOperand in its
+    /// MachineInstr.
+    unsigned getOperandNo() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op - &Op->getParent()->getOperand(0);
+    }
+
+    // Retrieve a reference to the current operand.
+    MachineOperand &operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return *Op;
+    }
+
+    MachineOperand *operator->() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op;
+    }
+  };
+
+  /// defusechain_iterator - This class provides iterator support for machine
+  /// operands in the function that use or define a specific register.  If
+  /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
+  /// returns defs.  If neither are true then you are silly and it always
+  /// returns end().  If SkipDebug is true it skips uses marked Debug
+  /// when incrementing.
+  template<bool ReturnUses, bool ReturnDefs, bool SkipDebug,
+           bool ByOperand, bool ByInstr, bool ByBundle>
+  class defusechain_instr_iterator
+    : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
+    MachineOperand *Op;
+    explicit defusechain_instr_iterator(MachineOperand *op) : Op(op) {
+      // If the first node isn't one we're interested in, advance to one that
+      // we are interested in.
+      if (op) {
+        if ((!ReturnUses && op->isUse()) ||
+            (!ReturnDefs && op->isDef()) ||
+            (SkipDebug && op->isDebug()))
+          advance();
+      }
+    }
+    friend class MachineRegisterInfo;
+
+    void advance() {
+      assert(Op && "Cannot increment end iterator!");
+      Op = getNextOperandForReg(Op);
+
+      // All defs come before the uses, so stop def_iterator early.
+      if (!ReturnUses) {
+        if (Op) {
+          if (Op->isUse())
+            Op = nullptr;
+          else
+            assert(!Op->isDebug() && "Can't have debug defs");
+        }
+      } else {
+        // If this is an operand we don't care about, skip it.
+        while (Op && ((!ReturnDefs && Op->isDef()) ||
+                      (SkipDebug && Op->isDebug())))
+          Op = getNextOperandForReg(Op);
+      }
+    }
+  public:
+    typedef std::iterator<std::forward_iterator_tag,
+                          MachineInstr, ptrdiff_t>::reference reference;
+    typedef std::iterator<std::forward_iterator_tag,
+                          MachineInstr, ptrdiff_t>::pointer pointer;
+
+    defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){}
+    defusechain_instr_iterator() : Op(nullptr) {}
+
+    bool operator==(const defusechain_instr_iterator &x) const {
+      return Op == x.Op;
+    }
+    bool operator!=(const defusechain_instr_iterator &x) const {
+      return !operator==(x);
+    }
+
+    /// atEnd - return true if this iterator is equal to reg_end() on the value.
+    bool atEnd() const { return Op == nullptr; }
+
+    // Iterator traversal: forward iteration only
+    defusechain_instr_iterator &operator++() {          // Preincrement
+      assert(Op && "Cannot increment end iterator!");
+      if (ByOperand)
+        advance();
+      else if (ByInstr) {
+        MachineInstr *P = Op->getParent();
+        do {
+          advance();
+        } while (Op && Op->getParent() == P);
+      } else if (ByBundle) {
+        MachineInstr *P = getBundleStart(Op->getParent());
+        do {
+          advance();
+        } while (Op && getBundleStart(Op->getParent()) == P);
+      }
+
+      return *this;
+    }
+    defusechain_instr_iterator operator++(int) {        // Postincrement
+      defusechain_instr_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    // Retrieve a reference to the current operand.
+    MachineInstr &operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      if (ByBundle) return *(getBundleStart(Op->getParent()));
+      return *Op->getParent();
+    }
+
+    MachineInstr *operator->() const {
+      assert(Op && "Cannot dereference end iterator!");
+      if (ByBundle) return getBundleStart(Op->getParent());
+      return Op->getParent();
+    }
+  };
+};
+
+/// Iterate over the pressure sets affected by the given physical or virtual
+/// register. If Reg is physical, it must be a register unit (from
+/// MCRegUnitIterator).
+class PSetIterator {
+  const int *PSet;
+  unsigned Weight;
+public:
+  PSetIterator(): PSet(nullptr), Weight(0) {}
+  PSetIterator(unsigned RegUnit, const MachineRegisterInfo *MRI) {
+    const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
+    if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
+      const TargetRegisterClass *RC = MRI->getRegClass(RegUnit);
+      PSet = TRI->getRegClassPressureSets(RC);
+      Weight = TRI->getRegClassWeight(RC).RegWeight;
+    }
+    else {
+      PSet = TRI->getRegUnitPressureSets(RegUnit);
+      Weight = TRI->getRegUnitWeight(RegUnit);
+    }
+    if (*PSet == -1)
+      PSet = nullptr;
+  }
+  bool isValid() const { return PSet; }
+
+  unsigned getWeight() const { return Weight; }
+
+  unsigned operator*() const { return *PSet; }
+
+  void operator++() {
+    assert(isValid() && "Invalid PSetIterator.");
+    ++PSet;
+    if (*PSet == -1)
+      PSet = nullptr;
+  }
+};
+
+inline PSetIterator MachineRegisterInfo::
+getPressureSets(unsigned RegUnit) const {
+  return PSetIterator(RegUnit, this);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h
new file mode 100644
index 0000000..e778457
--- /dev/null
+++ b/include/llvm/CodeGen/MachineRelocation.h
@@ -0,0 +1,342 @@
+//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- 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 MachineRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
+#define LLVM_CODEGEN_MACHINERELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class GlobalValue;
+class MachineBasicBlock;
+
+/// MachineRelocation - This represents a target-specific relocation value,
+/// produced by the code emitter.  This relocation is resolved after the has
+/// been emitted, either to an object file or to memory, when the target of the
+/// relocation can be resolved.
+///
+/// A relocation is made up of the following logical portions:
+///   1. An offset in the machine code buffer, the location to modify.
+///   2. A target specific relocation type (a number from 0 to 63).
+///   3. A symbol being referenced, either as a GlobalValue* or as a string.
+///   4. An optional constant value to be added to the reference.
+///   5. A bit, CanRewrite, which indicates to the JIT that a function stub is
+///      not needed for the relocation.
+///   6. An index into the GOT, if the target uses a GOT
+///
+class MachineRelocation {
+  enum AddressType {
+    isResult,         // Relocation has be transformed into its result pointer.
+    isGV,             // The Target.GV field is valid.
+    isIndirectSym,    // Relocation of an indirect symbol.
+    isBB,             // Relocation of BB address.
+    isExtSym,         // The Target.ExtSym field is valid.
+    isConstPool,      // Relocation of constant pool address.
+    isJumpTable,      // Relocation of jump table address.
+    isGOTIndex        // The Target.GOTIndex field is valid.
+  };
+  
+  /// Offset - This is the offset from the start of the code buffer of the
+  /// relocation to perform.
+  uintptr_t Offset;
+  
+  /// ConstantVal - A field that may be used by the target relocation type.
+  intptr_t ConstantVal;
+
+  union {
+    void *Result;           // If this has been resolved to a resolved pointer
+    GlobalValue *GV;        // If this is a pointer to a GV or an indirect ref.
+    MachineBasicBlock *MBB; // If this is a pointer to an LLVM BB
+    const char *ExtSym;     // If this is a pointer to a named symbol
+    unsigned Index;         // Constant pool / jump table index
+    unsigned GOTIndex;      // Index in the GOT of this symbol/global
+  } Target;
+
+  unsigned TargetReloType : 6; // The target relocation ID
+  AddressType AddrType    : 4; // The field of Target to use
+  bool MayNeedFarStub     : 1; // True if this relocation may require a far-stub
+  bool GOTRelative        : 1; // Should this relocation be relative to the GOT?
+  bool TargetResolve      : 1; // True if target should resolve the address
+
+public:
+ // Relocation types used in a generic implementation.  Currently, relocation
+ // entries for all things use the generic VANILLA type until they are refined
+ // into target relocation types.
+  enum RelocationType {
+    VANILLA
+  };
+  
+  /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
+  ///
+  static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType, 
+                                 GlobalValue *GV, intptr_t cst = 0,
+                                 bool MayNeedFarStub = 0,
+                                 bool GOTrelative = 0) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isGV;
+    Result.MayNeedFarStub = MayNeedFarStub;
+    Result.GOTRelative = GOTrelative;
+    Result.TargetResolve = false;
+    Result.Target.GV = GV;
+    return Result;
+  }
+
+  /// MachineRelocation::getIndirectSymbol - Return a relocation entry for an
+  /// indirect symbol.
+  static MachineRelocation getIndirectSymbol(uintptr_t offset,
+                                             unsigned RelocationType, 
+                                             GlobalValue *GV, intptr_t cst = 0,
+                                             bool MayNeedFarStub = 0,
+                                             bool GOTrelative = 0) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isIndirectSym;
+    Result.MayNeedFarStub = MayNeedFarStub;
+    Result.GOTRelative = GOTrelative;
+    Result.TargetResolve = false;
+    Result.Target.GV = GV;
+    return Result;
+  }
+
+  /// MachineRelocation::getBB - Return a relocation entry for a BB.
+  ///
+  static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType,
+                                 MachineBasicBlock *MBB, intptr_t cst = 0) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isBB;
+    Result.MayNeedFarStub = false;
+    Result.GOTRelative = false;
+    Result.TargetResolve = false;
+    Result.Target.MBB = MBB;
+    return Result;
+  }
+
+  /// MachineRelocation::getExtSym - Return a relocation entry for an external
+  /// symbol, like "free".
+  ///
+  static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, 
+                                     const char *ES, intptr_t cst = 0,
+                                     bool GOTrelative = 0,
+                                     bool NeedStub = true) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isExtSym;
+    Result.MayNeedFarStub = NeedStub;
+    Result.GOTRelative = GOTrelative;
+    Result.TargetResolve = false;
+    Result.Target.ExtSym = ES;
+    return Result;
+  }
+
+  /// MachineRelocation::getConstPool - Return a relocation entry for a constant
+  /// pool entry.
+  ///
+  static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType,
+                                        unsigned CPI, intptr_t cst = 0,
+                                        bool letTargetResolve = false) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isConstPool;
+    Result.MayNeedFarStub = false;
+    Result.GOTRelative = false;
+    Result.TargetResolve = letTargetResolve;
+    Result.Target.Index = CPI;
+    return Result;
+  }
+
+  /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
+  /// table entry.
+  ///
+  static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType,
+                                        unsigned JTI, intptr_t cst = 0,
+                                        bool letTargetResolve = false) {
+    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+    MachineRelocation Result;
+    Result.Offset = offset;
+    Result.ConstantVal = cst;
+    Result.TargetReloType = RelocationType;
+    Result.AddrType = isJumpTable;
+    Result.MayNeedFarStub = false;
+    Result.GOTRelative = false;
+    Result.TargetResolve = letTargetResolve;
+    Result.Target.Index = JTI;
+    return Result;
+  }
+
+  /// getMachineCodeOffset - Return the offset into the code buffer that the
+  /// relocation should be performed.
+  intptr_t getMachineCodeOffset() const {
+    return Offset;
+  }
+
+  /// getRelocationType - Return the target-specific relocation ID for this
+  /// relocation.
+  unsigned getRelocationType() const {
+    return TargetReloType;
+  }
+
+  /// getConstantVal - Get the constant value associated with this relocation.
+  /// This is often an offset from the symbol.
+  ///
+  intptr_t getConstantVal() const {
+    return ConstantVal;
+  }
+
+  /// setConstantVal - Set the constant value associated with this relocation.
+  /// This is often an offset from the symbol.
+  ///
+  void setConstantVal(intptr_t val) {
+    ConstantVal = val;
+  }
+
+  /// isGlobalValue - Return true if this relocation is a GlobalValue, as
+  /// opposed to a constant string.
+  bool isGlobalValue() const {
+    return AddrType == isGV;
+  }
+
+  /// isIndirectSymbol - Return true if this relocation is the address an
+  /// indirect symbol
+  bool isIndirectSymbol() const {
+    return AddrType == isIndirectSym;
+  }
+
+  /// isBasicBlock - Return true if this relocation is a basic block reference.
+  ///
+  bool isBasicBlock() const {
+    return AddrType == isBB;
+  }
+
+  /// isExternalSymbol - Return true if this is a constant string.
+  ///
+  bool isExternalSymbol() const {
+    return AddrType == isExtSym;
+  }
+
+  /// isConstantPoolIndex - Return true if this is a constant pool reference.
+  ///
+  bool isConstantPoolIndex() const {
+    return AddrType == isConstPool;
+  }
+
+  /// isJumpTableIndex - Return true if this is a jump table reference.
+  ///
+  bool isJumpTableIndex() const {
+    return AddrType == isJumpTable;
+  }
+
+  /// isGOTRelative - Return true the target wants the index into the GOT of
+  /// the symbol rather than the address of the symbol.
+  bool isGOTRelative() const {
+    return GOTRelative;
+  }
+
+  /// mayNeedFarStub - This function returns true if the JIT for this target may
+  /// need either a stub function or an indirect global-variable load to handle
+  /// the relocated GlobalValue reference.  For example, the x86-64 call
+  /// instruction can only call functions within +/-2GB of the call site.
+  /// Anything farther away needs a longer mov+call sequence, which can't just
+  /// be written on top of the existing call.
+  bool mayNeedFarStub() const {
+    return MayNeedFarStub;
+  }
+
+  /// letTargetResolve - Return true if the target JITInfo is usually
+  /// responsible for resolving the address of this relocation.
+  bool letTargetResolve() const {
+    return TargetResolve;
+  }
+
+  /// getGlobalValue - If this is a global value reference, return the
+  /// referenced global.
+  GlobalValue *getGlobalValue() const {
+    assert((isGlobalValue() || isIndirectSymbol()) &&
+           "This is not a global value reference!");
+    return Target.GV;
+  }
+
+  MachineBasicBlock *getBasicBlock() const {
+    assert(isBasicBlock() && "This is not a basic block reference!");
+    return Target.MBB;
+  }
+
+  /// getString - If this is a string value, return the string reference.
+  ///
+  const char *getExternalSymbol() const {
+    assert(isExternalSymbol() && "This is not an external symbol reference!");
+    return Target.ExtSym;
+  }
+
+  /// getConstantPoolIndex - If this is a const pool reference, return
+  /// the index into the constant pool.
+  unsigned getConstantPoolIndex() const {
+    assert(isConstantPoolIndex() && "This is not a constant pool reference!");
+    return Target.Index;
+  }
+
+  /// getJumpTableIndex - If this is a jump table reference, return
+  /// the index into the jump table.
+  unsigned getJumpTableIndex() const {
+    assert(isJumpTableIndex() && "This is not a jump table reference!");
+    return Target.Index;
+  }
+
+  /// getResultPointer - Once this has been resolved to point to an actual
+  /// address, this returns the pointer.
+  void *getResultPointer() const {
+    assert(AddrType == isResult && "Result pointer isn't set yet!");
+    return Target.Result;
+  }
+
+  /// setResultPointer - Set the result to the specified pointer value.
+  ///
+  void setResultPointer(void *Ptr) {
+    Target.Result = Ptr;
+    AddrType = isResult;
+  }
+
+  /// setGOTIndex - Set the GOT index to a specific value.
+  void setGOTIndex(unsigned idx) {
+    AddrType = isGOTIndex;
+    Target.GOTIndex = idx;
+  }
+
+  /// getGOTIndex - Once this has been resolved to an entry in the GOT,
+  /// this returns that index.  The index is from the lowest address entry
+  /// in the GOT.
+  unsigned getGOTIndex() const {
+    assert(AddrType == isGOTIndex);
+    return Target.GOTIndex;
+  }
+};
+}
+
+#endif
diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h
new file mode 100644
index 0000000..486a26e
--- /dev/null
+++ b/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -0,0 +1,116 @@
+//===-- MachineSSAUpdater.h - Unstructured SSA Update Tool ------*- 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 MachineSSAUpdater class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
+#define LLVM_CODEGEN_MACHINESSAUPDATER_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MachineBasicBlock;
+  class MachineFunction;
+  class MachineInstr;
+  class MachineOperand;
+  class MachineRegisterInfo;
+  class TargetInstrInfo;
+  class TargetRegisterClass;
+  template<typename T> class SmallVectorImpl;
+  template<typename T> class SSAUpdaterTraits;
+
+/// MachineSSAUpdater - This class updates SSA form for a set of virtual
+/// registers defined in multiple blocks.  This is used when code duplication
+/// or another unstructured transformation wants to rewrite a set of uses of one
+/// vreg with uses of a set of vregs.
+class MachineSSAUpdater {
+  friend class SSAUpdaterTraits<MachineSSAUpdater>;
+
+private:
+  /// AvailableVals - This keeps track of which value to use on a per-block
+  /// basis.  When we insert PHI nodes, we keep track of them here.
+  //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
+  void *AV;
+
+  /// VR - Current virtual register whose uses are being updated.
+  unsigned VR;
+
+  /// VRC - Register class of the current virtual register.
+  const TargetRegisterClass *VRC;
+
+  /// InsertedPHIs - If this is non-null, the MachineSSAUpdater adds all PHI
+  /// nodes that it creates to the vector.
+  SmallVectorImpl<MachineInstr*> *InsertedPHIs;
+
+  const TargetInstrInfo *TII;
+  MachineRegisterInfo *MRI;
+public:
+  /// MachineSSAUpdater constructor.  If InsertedPHIs is specified, it will be
+  /// filled in with all PHI Nodes created by rewriting.
+  explicit MachineSSAUpdater(MachineFunction &MF,
+                        SmallVectorImpl<MachineInstr*> *InsertedPHIs = nullptr);
+  ~MachineSSAUpdater();
+
+  /// Initialize - Reset this object to get ready for a new set of SSA
+  /// updates.
+  void Initialize(unsigned V);
+
+  /// AddAvailableValue - Indicate that a rewritten value is available at the
+  /// end of the specified block with the specified value.
+  void AddAvailableValue(MachineBasicBlock *BB, unsigned V);
+
+  /// HasValueForBlock - Return true if the MachineSSAUpdater already has a
+  /// value for the specified block.
+  bool HasValueForBlock(MachineBasicBlock *BB) const;
+
+  /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
+  /// live at the end of the specified block.
+  unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB);
+
+  /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
+  /// is live in the middle of the specified block.
+  ///
+  /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
+  /// important case: if there is a definition of the rewritten value after the
+  /// 'use' in BB.  Consider code like this:
+  ///
+  ///      X1 = ...
+  ///   SomeBB:
+  ///      use(X)
+  ///      X2 = ...
+  ///      br Cond, SomeBB, OutBB
+  ///
+  /// In this case, there are two values (X1 and X2) added to the AvailableVals
+  /// set by the client of the rewriter, and those values are both live out of
+  /// their respective blocks.  However, the use of X happens in the *middle* of
+  /// a block.  Because of this, we need to insert a new PHI node in SomeBB to
+  /// merge the appropriate values, and this value isn't live out of the block.
+  ///
+  unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB);
+
+  /// RewriteUse - Rewrite a use of the symbolic value.  This handles PHI nodes,
+  /// which use their value in the corresponding predecessor.  Note that this
+  /// will not work if the use is supposed to be rewritten to a value defined in
+  /// the same block as the use, but above it.  Any 'AddAvailableValue's added
+  /// for the use's block will be considered to be below it.
+  void RewriteUse(MachineOperand &U);
+
+private:
+  unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
+
+  void operator=(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION;
+  MachineSSAUpdater(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
new file mode 100644
index 0000000..7d85432
--- /dev/null
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -0,0 +1,953 @@
+//==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- 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 an interface for customizing the standard MachineScheduler
+// pass. Note that the entire pass may be replaced as follows:
+//
+// <Target>TargetMachine::createPassConfig(PassManagerBase &PM) {
+//   PM.substitutePass(&MachineSchedulerID, &CustomSchedulerPassID);
+//   ...}
+//
+// The MachineScheduler pass is only responsible for choosing the regions to be
+// scheduled. Targets can override the DAG builder and scheduler without
+// replacing the pass as follows:
+//
+// ScheduleDAGInstrs *<Target>PassConfig::
+// createMachineScheduler(MachineSchedContext *C) {
+//   return new CustomMachineScheduler(C);
+// }
+//
+// The default scheduler, ScheduleDAGMILive, builds the DAG and drives list
+// scheduling while updating the instruction stream, register pressure, and live
+// intervals. Most targets don't need to override the DAG builder and list
+// schedulier, but subtargets that require custom scheduling heuristics may
+// plugin an alternate MachineSchedStrategy. The strategy is responsible for
+// selecting the highest priority node from the list:
+//
+// ScheduleDAGInstrs *<Target>PassConfig::
+// createMachineScheduler(MachineSchedContext *C) {
+//   return new ScheduleDAGMI(C, CustomStrategy(C));
+// }
+//
+// The DAG builder can also be customized in a sense by adding DAG mutations
+// that will run after DAG building and before list scheduling. DAG mutations
+// can adjust dependencies based on target-specific knowledge or add weak edges
+// to aid heuristics:
+//
+// ScheduleDAGInstrs *<Target>PassConfig::
+// createMachineScheduler(MachineSchedContext *C) {
+//   ScheduleDAGMI *DAG = new ScheduleDAGMI(C, CustomStrategy(C));
+//   DAG->addMutation(new CustomDependencies(DAG->TII, DAG->TRI));
+//   return DAG;
+// }
+//
+// A target that supports alternative schedulers can use the
+// MachineSchedRegistry to allow command line selection. This can be done by
+// implementing the following boilerplate:
+//
+// static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) {
+//  return new CustomMachineScheduler(C);
+// }
+// static MachineSchedRegistry
+// SchedCustomRegistry("custom", "Run my target's custom scheduler",
+//                     createCustomMachineSched);
+//
+//
+// Finally, subtargets that don't need to implement custom heuristics but would
+// like to configure the GenericScheduler's policy for a given scheduler region,
+// including scheduling direction and register pressure tracking policy, can do
+// this:
+//
+// void <SubTarget>Subtarget::
+// overrideSchedPolicy(MachineSchedPolicy &Policy,
+//                     MachineInstr *begin,
+//                     MachineInstr *end,
+//                     unsigned NumRegionInstrs) const {
+//   Policy.<Flag> = true;
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINESCHEDULER_H
+#define LLVM_CODEGEN_MACHINESCHEDULER_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/ScheduleDAGInstrs.h"
+
+#include <memory>
+
+namespace llvm {
+
+extern cl::opt<bool> ForceTopDown;
+extern cl::opt<bool> ForceBottomUp;
+
+class AliasAnalysis;
+class LiveIntervals;
+class MachineDominatorTree;
+class MachineLoopInfo;
+class RegisterClassInfo;
+class ScheduleDAGInstrs;
+class SchedDFSResult;
+class ScheduleHazardRecognizer;
+
+/// MachineSchedContext provides enough context from the MachineScheduler pass
+/// for the target to instantiate a scheduler.
+struct MachineSchedContext {
+  MachineFunction *MF;
+  const MachineLoopInfo *MLI;
+  const MachineDominatorTree *MDT;
+  const TargetPassConfig *PassConfig;
+  AliasAnalysis *AA;
+  LiveIntervals *LIS;
+
+  RegisterClassInfo *RegClassInfo;
+
+  MachineSchedContext();
+  virtual ~MachineSchedContext();
+};
+
+/// MachineSchedRegistry provides a selection of available machine instruction
+/// schedulers.
+class MachineSchedRegistry : public MachinePassRegistryNode {
+public:
+  typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
+
+  // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
+  typedef ScheduleDAGCtor FunctionPassCtor;
+
+  static MachinePassRegistry Registry;
+
+  MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
+    : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
+    Registry.Add(this);
+  }
+  ~MachineSchedRegistry() { Registry.Remove(this); }
+
+  // Accessors.
+  //
+  MachineSchedRegistry *getNext() const {
+    return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
+  }
+  static MachineSchedRegistry *getList() {
+    return (MachineSchedRegistry *)Registry.getList();
+  }
+  static void setListener(MachinePassRegistryListener *L) {
+    Registry.setListener(L);
+  }
+};
+
+class ScheduleDAGMI;
+
+/// Define a generic scheduling policy for targets that don't provide their own
+/// MachineSchedStrategy. This can be overriden for each scheduling region
+/// before building the DAG.
+struct MachineSchedPolicy {
+  // Allow the scheduler to disable register pressure tracking.
+  bool ShouldTrackPressure;
+
+  // Allow the scheduler to force top-down or bottom-up scheduling. If neither
+  // is true, the scheduler runs in both directions and converges.
+  bool OnlyTopDown;
+  bool OnlyBottomUp;
+
+  MachineSchedPolicy(): ShouldTrackPressure(false), OnlyTopDown(false),
+    OnlyBottomUp(false) {}
+};
+
+/// MachineSchedStrategy - Interface to the scheduling algorithm used by
+/// ScheduleDAGMI.
+///
+/// Initialization sequence:
+///   initPolicy -> shouldTrackPressure -> initialize(DAG) -> registerRoots
+class MachineSchedStrategy {
+  virtual void anchor();
+public:
+  virtual ~MachineSchedStrategy() {}
+
+  /// Optionally override the per-region scheduling policy.
+  virtual void initPolicy(MachineBasicBlock::iterator Begin,
+                          MachineBasicBlock::iterator End,
+                          unsigned NumRegionInstrs) {}
+
+  /// Check if pressure tracking is needed before building the DAG and
+  /// initializing this strategy. Called after initPolicy.
+  virtual bool shouldTrackPressure() const { return true; }
+
+  /// Initialize the strategy after building the DAG for a new region.
+  virtual void initialize(ScheduleDAGMI *DAG) = 0;
+
+  /// Notify this strategy that all roots have been released (including those
+  /// that depend on EntrySU or ExitSU).
+  virtual void registerRoots() {}
+
+  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
+  /// schedule the node at the top of the unscheduled region. Otherwise it will
+  /// be scheduled at the bottom.
+  virtual SUnit *pickNode(bool &IsTopNode) = 0;
+
+  /// \brief Scheduler callback to notify that a new subtree is scheduled.
+  virtual void scheduleTree(unsigned SubtreeID) {}
+
+  /// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
+  /// instruction and updated scheduled/remaining flags in the DAG nodes.
+  virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
+
+  /// When all predecessor dependencies have been resolved, free this node for
+  /// top-down scheduling.
+  virtual void releaseTopNode(SUnit *SU) = 0;
+  /// When all successor dependencies have been resolved, free this node for
+  /// bottom-up scheduling.
+  virtual void releaseBottomNode(SUnit *SU) = 0;
+};
+
+/// Mutate the DAG as a postpass after normal DAG building.
+class ScheduleDAGMutation {
+  virtual void anchor();
+public:
+  virtual ~ScheduleDAGMutation() {}
+
+  virtual void apply(ScheduleDAGMI *DAG) = 0;
+};
+
+/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
+/// schedules machine instructions according to the given MachineSchedStrategy
+/// without much extra book-keeping. This is the common functionality between
+/// PreRA and PostRA MachineScheduler.
+class ScheduleDAGMI : public ScheduleDAGInstrs {
+protected:
+  AliasAnalysis *AA;
+  std::unique_ptr<MachineSchedStrategy> SchedImpl;
+
+  /// Topo - A topological ordering for SUnits which permits fast IsReachable
+  /// and similar queries.
+  ScheduleDAGTopologicalSort Topo;
+
+  /// Ordered list of DAG postprocessing steps.
+  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
+
+  /// The top of the unscheduled zone.
+  MachineBasicBlock::iterator CurrentTop;
+
+  /// The bottom of the unscheduled zone.
+  MachineBasicBlock::iterator CurrentBottom;
+
+  /// Record the next node in a scheduled cluster.
+  const SUnit *NextClusterPred;
+  const SUnit *NextClusterSucc;
+
+#ifndef NDEBUG
+  /// The number of instructions scheduled so far. Used to cut off the
+  /// scheduler at the point determined by misched-cutoff.
+  unsigned NumInstrsScheduled;
+#endif
+public:
+  ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr<MachineSchedStrategy> S,
+                bool IsPostRA)
+      : ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, IsPostRA,
+                          /*RemoveKillFlags=*/IsPostRA, C->LIS),
+        AA(C->AA), SchedImpl(std::move(S)), Topo(SUnits, &ExitSU), CurrentTop(),
+        CurrentBottom(), NextClusterPred(nullptr), NextClusterSucc(nullptr) {
+#ifndef NDEBUG
+    NumInstrsScheduled = 0;
+#endif
+  }
+
+  // Provide a vtable anchor
+  ~ScheduleDAGMI() override;
+
+  /// Return true if this DAG supports VReg liveness and RegPressure.
+  virtual bool hasVRegLiveness() const { return false; }
+
+  /// Add a postprocessing step to the DAG builder.
+  /// Mutations are applied in the order that they are added after normal DAG
+  /// building and before MachineSchedStrategy initialization.
+  ///
+  /// ScheduleDAGMI takes ownership of the Mutation object.
+  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
+    Mutations.push_back(std::move(Mutation));
+  }
+
+  /// \brief True if an edge can be added from PredSU to SuccSU without creating
+  /// a cycle.
+  bool canAddEdge(SUnit *SuccSU, SUnit *PredSU);
+
+  /// \brief Add a DAG edge to the given SU with the given predecessor
+  /// dependence data.
+  ///
+  /// \returns true if the edge may be added without creating a cycle OR if an
+  /// equivalent edge already existed (false indicates failure).
+  bool addEdge(SUnit *SuccSU, const SDep &PredDep);
+
+  MachineBasicBlock::iterator top() const { return CurrentTop; }
+  MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
+
+  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
+  /// region. This covers all instructions in a block, while schedule() may only
+  /// cover a subset.
+  void enterRegion(MachineBasicBlock *bb,
+                   MachineBasicBlock::iterator begin,
+                   MachineBasicBlock::iterator end,
+                   unsigned regioninstrs) override;
+
+  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
+  /// reorderable instructions.
+  void schedule() override;
+
+  /// Change the position of an instruction within the basic block and update
+  /// live ranges and region boundary iterators.
+  void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
+
+  const SUnit *getNextClusterPred() const { return NextClusterPred; }
+
+  const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
+
+  void viewGraph(const Twine &Name, const Twine &Title) override;
+  void viewGraph() override;
+
+protected:
+  // Top-Level entry points for the schedule() driver...
+
+  /// Apply each ScheduleDAGMutation step in order. This allows different
+  /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
+  void postprocessDAG();
+
+  /// Release ExitSU predecessors and setup scheduler queues.
+  void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
+
+  /// Update scheduler DAG and queues after scheduling an instruction.
+  void updateQueues(SUnit *SU, bool IsTopNode);
+
+  /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
+  void placeDebugValues();
+
+  /// \brief dump the scheduled Sequence.
+  void dumpSchedule() const;
+
+  // Lesser helpers...
+  bool checkSchedLimit();
+
+  void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
+                             SmallVectorImpl<SUnit*> &BotRoots);
+
+  void releaseSucc(SUnit *SU, SDep *SuccEdge);
+  void releaseSuccessors(SUnit *SU);
+  void releasePred(SUnit *SU, SDep *PredEdge);
+  void releasePredecessors(SUnit *SU);
+};
+
+/// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
+/// machine instructions while updating LiveIntervals and tracking regpressure.
+class ScheduleDAGMILive : public ScheduleDAGMI {
+protected:
+  RegisterClassInfo *RegClassInfo;
+
+  /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
+  /// will be empty.
+  SchedDFSResult *DFSResult;
+  BitVector ScheduledTrees;
+
+  MachineBasicBlock::iterator LiveRegionEnd;
+
+  // Map each SU to its summary of pressure changes. This array is updated for
+  // liveness during bottom-up scheduling. Top-down scheduling may proceed but
+  // has no affect on the pressure diffs.
+  PressureDiffs SUPressureDiffs;
+
+  /// Register pressure in this region computed by initRegPressure.
+  bool ShouldTrackPressure;
+  IntervalPressure RegPressure;
+  RegPressureTracker RPTracker;
+
+  /// List of pressure sets that exceed the target's pressure limit before
+  /// scheduling, listed in increasing set ID order. Each pressure set is paired
+  /// with its max pressure in the currently scheduled regions.
+  std::vector<PressureChange> RegionCriticalPSets;
+
+  /// The top of the unscheduled zone.
+  IntervalPressure TopPressure;
+  RegPressureTracker TopRPTracker;
+
+  /// The bottom of the unscheduled zone.
+  IntervalPressure BotPressure;
+  RegPressureTracker BotRPTracker;
+
+public:
+  ScheduleDAGMILive(MachineSchedContext *C,
+                    std::unique_ptr<MachineSchedStrategy> S)
+      : ScheduleDAGMI(C, std::move(S), /*IsPostRA=*/false),
+        RegClassInfo(C->RegClassInfo), DFSResult(nullptr),
+        ShouldTrackPressure(false), RPTracker(RegPressure),
+        TopRPTracker(TopPressure), BotRPTracker(BotPressure) {}
+
+  virtual ~ScheduleDAGMILive();
+
+  /// Return true if this DAG supports VReg liveness and RegPressure.
+  bool hasVRegLiveness() const override { return true; }
+
+  /// \brief Return true if register pressure tracking is enabled.
+  bool isTrackingPressure() const { return ShouldTrackPressure; }
+
+  /// Get current register pressure for the top scheduled instructions.
+  const IntervalPressure &getTopPressure() const { return TopPressure; }
+  const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
+
+  /// Get current register pressure for the bottom scheduled instructions.
+  const IntervalPressure &getBotPressure() const { return BotPressure; }
+  const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
+
+  /// Get register pressure for the entire scheduling region before scheduling.
+  const IntervalPressure &getRegPressure() const { return RegPressure; }
+
+  const std::vector<PressureChange> &getRegionCriticalPSets() const {
+    return RegionCriticalPSets;
+  }
+
+  PressureDiff &getPressureDiff(const SUnit *SU) {
+    return SUPressureDiffs[SU->NodeNum];
+  }
+
+  /// Compute a DFSResult after DAG building is complete, and before any
+  /// queue comparisons.
+  void computeDFSResult();
+
+  /// Return a non-null DFS result if the scheduling strategy initialized it.
+  const SchedDFSResult *getDFSResult() const { return DFSResult; }
+
+  BitVector &getScheduledTrees() { return ScheduledTrees; }
+
+  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
+  /// region. This covers all instructions in a block, while schedule() may only
+  /// cover a subset.
+  void enterRegion(MachineBasicBlock *bb,
+                   MachineBasicBlock::iterator begin,
+                   MachineBasicBlock::iterator end,
+                   unsigned regioninstrs) override;
+
+  /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
+  /// reorderable instructions.
+  void schedule() override;
+
+  /// Compute the cyclic critical path through the DAG.
+  unsigned computeCyclicCriticalPath();
+
+protected:
+  // Top-Level entry points for the schedule() driver...
+
+  /// Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking
+  /// enabled. This sets up three trackers. RPTracker will cover the entire DAG
+  /// region, TopTracker and BottomTracker will be initialized to the top and
+  /// bottom of the DAG region without covereing any unscheduled instruction.
+  void buildDAGWithRegPressure();
+
+  /// Move an instruction and update register pressure.
+  void scheduleMI(SUnit *SU, bool IsTopNode);
+
+  // Lesser helpers...
+
+  void initRegPressure();
+
+  void updatePressureDiffs(ArrayRef<unsigned> LiveUses);
+
+  void updateScheduledPressure(const SUnit *SU,
+                               const std::vector<unsigned> &NewMaxPressure);
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// Helpers for implementing custom MachineSchedStrategy classes. These take
+/// care of the book-keeping associated with list scheduling heuristics.
+///
+//===----------------------------------------------------------------------===//
+
+/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
+/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
+/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
+///
+/// This is a convenience class that may be used by implementations of
+/// MachineSchedStrategy.
+class ReadyQueue {
+  unsigned ID;
+  std::string Name;
+  std::vector<SUnit*> Queue;
+
+public:
+  ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
+
+  unsigned getID() const { return ID; }
+
+  StringRef getName() const { return Name; }
+
+  // SU is in this queue if it's NodeQueueID is a superset of this ID.
+  bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
+
+  bool empty() const { return Queue.empty(); }
+
+  void clear() { Queue.clear(); }
+
+  unsigned size() const { return Queue.size(); }
+
+  typedef std::vector<SUnit*>::iterator iterator;
+
+  iterator begin() { return Queue.begin(); }
+
+  iterator end() { return Queue.end(); }
+
+  ArrayRef<SUnit*> elements() { return Queue; }
+
+  iterator find(SUnit *SU) {
+    return std::find(Queue.begin(), Queue.end(), SU);
+  }
+
+  void push(SUnit *SU) {
+    Queue.push_back(SU);
+    SU->NodeQueueId |= ID;
+  }
+
+  iterator remove(iterator I) {
+    (*I)->NodeQueueId &= ~ID;
+    *I = Queue.back();
+    unsigned idx = I - Queue.begin();
+    Queue.pop_back();
+    return Queue.begin() + idx;
+  }
+
+  void dump();
+};
+
+/// Summarize the unscheduled region.
+struct SchedRemainder {
+  // Critical path through the DAG in expected latency.
+  unsigned CriticalPath;
+  unsigned CyclicCritPath;
+
+  // Scaled count of micro-ops left to schedule.
+  unsigned RemIssueCount;
+
+  bool IsAcyclicLatencyLimited;
+
+  // Unscheduled resources
+  SmallVector<unsigned, 16> RemainingCounts;
+
+  void reset() {
+    CriticalPath = 0;
+    CyclicCritPath = 0;
+    RemIssueCount = 0;
+    IsAcyclicLatencyLimited = false;
+    RemainingCounts.clear();
+  }
+
+  SchedRemainder() { reset(); }
+
+  void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
+};
+
+/// Each Scheduling boundary is associated with ready queues. It tracks the
+/// current cycle in the direction of movement, and maintains the state
+/// of "hazards" and other interlocks at the current cycle.
+class SchedBoundary {
+public:
+  /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
+  enum {
+    TopQID = 1,
+    BotQID = 2,
+    LogMaxQID = 2
+  };
+
+  ScheduleDAGMI *DAG;
+  const TargetSchedModel *SchedModel;
+  SchedRemainder *Rem;
+
+  ReadyQueue Available;
+  ReadyQueue Pending;
+
+  ScheduleHazardRecognizer *HazardRec;
+
+private:
+  /// True if the pending Q should be checked/updated before scheduling another
+  /// instruction.
+  bool CheckPending;
+
+  // For heuristics, keep a list of the nodes that immediately depend on the
+  // most recently scheduled node.
+  SmallPtrSet<const SUnit*, 8> NextSUs;
+
+  /// Number of cycles it takes to issue the instructions scheduled in this
+  /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
+  /// See getStalls().
+  unsigned CurrCycle;
+
+  /// Micro-ops issued in the current cycle
+  unsigned CurrMOps;
+
+  /// MinReadyCycle - Cycle of the soonest available instruction.
+  unsigned MinReadyCycle;
+
+  // The expected latency of the critical path in this scheduled zone.
+  unsigned ExpectedLatency;
+
+  // The latency of dependence chains leading into this zone.
+  // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
+  // For each cycle scheduled: DLat -= 1.
+  unsigned DependentLatency;
+
+  /// Count the scheduled (issued) micro-ops that can be retired by
+  /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
+  unsigned RetiredMOps;
+
+  // Count scheduled resources that have been executed. Resources are
+  // considered executed if they become ready in the time that it takes to
+  // saturate any resource including the one in question. Counts are scaled
+  // for direct comparison with other resources. Counts can be compared with
+  // MOps * getMicroOpFactor and Latency * getLatencyFactor.
+  SmallVector<unsigned, 16> ExecutedResCounts;
+
+  /// Cache the max count for a single resource.
+  unsigned MaxExecutedResCount;
+
+  // Cache the critical resources ID in this scheduled zone.
+  unsigned ZoneCritResIdx;
+
+  // Is the scheduled region resource limited vs. latency limited.
+  bool IsResourceLimited;
+
+  // Record the highest cycle at which each resource has been reserved by a
+  // scheduled instruction.
+  SmallVector<unsigned, 16> ReservedCycles;
+
+#ifndef NDEBUG
+  // Remember the greatest possible stall as an upper bound on the number of
+  // times we should retry the pending queue because of a hazard.
+  unsigned MaxObservedStall;
+#endif
+
+public:
+  /// Pending queues extend the ready queues with the same ID and the
+  /// PendingFlag set.
+  SchedBoundary(unsigned ID, const Twine &Name):
+    DAG(nullptr), SchedModel(nullptr), Rem(nullptr), Available(ID, Name+".A"),
+    Pending(ID << LogMaxQID, Name+".P"),
+    HazardRec(nullptr) {
+    reset();
+  }
+
+  ~SchedBoundary();
+
+  void reset();
+
+  void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
+            SchedRemainder *rem);
+
+  bool isTop() const {
+    return Available.getID() == TopQID;
+  }
+
+  /// Number of cycles to issue the instructions scheduled in this zone.
+  unsigned getCurrCycle() const { return CurrCycle; }
+
+  /// Micro-ops issued in the current cycle
+  unsigned getCurrMOps() const { return CurrMOps; }
+
+  /// Return true if the given SU is used by the most recently scheduled
+  /// instruction.
+  bool isNextSU(const SUnit *SU) const { return NextSUs.count(SU); }
+
+  // The latency of dependence chains leading into this zone.
+  unsigned getDependentLatency() const { return DependentLatency; }
+
+  /// Get the number of latency cycles "covered" by the scheduled
+  /// instructions. This is the larger of the critical path within the zone
+  /// and the number of cycles required to issue the instructions.
+  unsigned getScheduledLatency() const {
+    return std::max(ExpectedLatency, CurrCycle);
+  }
+
+  unsigned getUnscheduledLatency(SUnit *SU) const {
+    return isTop() ? SU->getHeight() : SU->getDepth();
+  }
+
+  unsigned getResourceCount(unsigned ResIdx) const {
+    return ExecutedResCounts[ResIdx];
+  }
+
+  /// Get the scaled count of scheduled micro-ops and resources, including
+  /// executed resources.
+  unsigned getCriticalCount() const {
+    if (!ZoneCritResIdx)
+      return RetiredMOps * SchedModel->getMicroOpFactor();
+    return getResourceCount(ZoneCritResIdx);
+  }
+
+  /// Get a scaled count for the minimum execution time of the scheduled
+  /// micro-ops that are ready to execute by getExecutedCount. Notice the
+  /// feedback loop.
+  unsigned getExecutedCount() const {
+    return std::max(CurrCycle * SchedModel->getLatencyFactor(),
+                    MaxExecutedResCount);
+  }
+
+  unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
+
+  // Is the scheduled region resource limited vs. latency limited.
+  bool isResourceLimited() const { return IsResourceLimited; }
+
+  /// Get the difference between the given SUnit's ready time and the current
+  /// cycle.
+  unsigned getLatencyStallCycles(SUnit *SU);
+
+  unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
+
+  bool checkHazard(SUnit *SU);
+
+  unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
+
+  unsigned getOtherResourceCount(unsigned &OtherCritIdx);
+
+  void releaseNode(SUnit *SU, unsigned ReadyCycle);
+
+  void releaseTopNode(SUnit *SU);
+
+  void releaseBottomNode(SUnit *SU);
+
+  void bumpCycle(unsigned NextCycle);
+
+  void incExecutedResources(unsigned PIdx, unsigned Count);
+
+  unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
+
+  void bumpNode(SUnit *SU);
+
+  void releasePending();
+
+  void removeReady(SUnit *SU);
+
+  /// Call this before applying any other heuristics to the Available queue.
+  /// Updates the Available/Pending Q's if necessary and returns the single
+  /// available instruction, or NULL if there are multiple candidates.
+  SUnit *pickOnlyChoice();
+
+#ifndef NDEBUG
+  void dumpScheduledState();
+#endif
+};
+
+/// Base class for GenericScheduler. This class maintains information about
+/// scheduling candidates based on TargetSchedModel making it easy to implement
+/// heuristics for either preRA or postRA scheduling.
+class GenericSchedulerBase : public MachineSchedStrategy {
+public:
+  /// Represent the type of SchedCandidate found within a single queue.
+  /// pickNodeBidirectional depends on these listed by decreasing priority.
+  enum CandReason {
+    NoCand, PhysRegCopy, RegExcess, RegCritical, Stall, Cluster, Weak, RegMax,
+    ResourceReduce, ResourceDemand, BotHeightReduce, BotPathReduce,
+    TopDepthReduce, TopPathReduce, NextDefUse, NodeOrder};
+
+#ifndef NDEBUG
+  static const char *getReasonStr(GenericSchedulerBase::CandReason Reason);
+#endif
+
+  /// Policy for scheduling the next instruction in the candidate's zone.
+  struct CandPolicy {
+    bool ReduceLatency;
+    unsigned ReduceResIdx;
+    unsigned DemandResIdx;
+
+    CandPolicy(): ReduceLatency(false), ReduceResIdx(0), DemandResIdx(0) {}
+  };
+
+  /// Status of an instruction's critical resource consumption.
+  struct SchedResourceDelta {
+    // Count critical resources in the scheduled region required by SU.
+    unsigned CritResources;
+
+    // Count critical resources from another region consumed by SU.
+    unsigned DemandedResources;
+
+    SchedResourceDelta(): CritResources(0), DemandedResources(0) {}
+
+    bool operator==(const SchedResourceDelta &RHS) const {
+      return CritResources == RHS.CritResources
+        && DemandedResources == RHS.DemandedResources;
+    }
+    bool operator!=(const SchedResourceDelta &RHS) const {
+      return !operator==(RHS);
+    }
+  };
+
+  /// Store the state used by GenericScheduler heuristics, required for the
+  /// lifetime of one invocation of pickNode().
+  struct SchedCandidate {
+    CandPolicy Policy;
+
+    // The best SUnit candidate.
+    SUnit *SU;
+
+    // The reason for this candidate.
+    CandReason Reason;
+
+    // Set of reasons that apply to multiple candidates.
+    uint32_t RepeatReasonSet;
+
+    // Register pressure values for the best candidate.
+    RegPressureDelta RPDelta;
+
+    // Critical resource consumption of the best candidate.
+    SchedResourceDelta ResDelta;
+
+    SchedCandidate(const CandPolicy &policy)
+      : Policy(policy), SU(nullptr), Reason(NoCand), RepeatReasonSet(0) {}
+
+    bool isValid() const { return SU; }
+
+    // Copy the status of another candidate without changing policy.
+    void setBest(SchedCandidate &Best) {
+      assert(Best.Reason != NoCand && "uninitialized Sched candidate");
+      SU = Best.SU;
+      Reason = Best.Reason;
+      RPDelta = Best.RPDelta;
+      ResDelta = Best.ResDelta;
+    }
+
+    bool isRepeat(CandReason R) { return RepeatReasonSet & (1 << R); }
+    void setRepeat(CandReason R) { RepeatReasonSet |= (1 << R); }
+
+    void initResourceDelta(const ScheduleDAGMI *DAG,
+                           const TargetSchedModel *SchedModel);
+  };
+
+protected:
+  const MachineSchedContext *Context;
+  const TargetSchedModel *SchedModel;
+  const TargetRegisterInfo *TRI;
+
+  SchedRemainder Rem;
+protected:
+  GenericSchedulerBase(const MachineSchedContext *C):
+    Context(C), SchedModel(nullptr), TRI(nullptr) {}
+
+  void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone,
+                 SchedBoundary *OtherZone);
+
+#ifndef NDEBUG
+  void traceCandidate(const SchedCandidate &Cand);
+#endif
+};
+
+/// GenericScheduler shrinks the unscheduled zone using heuristics to balance
+/// the schedule.
+class GenericScheduler : public GenericSchedulerBase {
+  ScheduleDAGMILive *DAG;
+
+  // State of the top and bottom scheduled instruction boundaries.
+  SchedBoundary Top;
+  SchedBoundary Bot;
+
+  MachineSchedPolicy RegionPolicy;
+public:
+  GenericScheduler(const MachineSchedContext *C):
+    GenericSchedulerBase(C), DAG(nullptr), Top(SchedBoundary::TopQID, "TopQ"),
+    Bot(SchedBoundary::BotQID, "BotQ") {}
+
+  void initPolicy(MachineBasicBlock::iterator Begin,
+                  MachineBasicBlock::iterator End,
+                  unsigned NumRegionInstrs) override;
+
+  bool shouldTrackPressure() const override {
+    return RegionPolicy.ShouldTrackPressure;
+  }
+
+  void initialize(ScheduleDAGMI *dag) override;
+
+  SUnit *pickNode(bool &IsTopNode) override;
+
+  void schedNode(SUnit *SU, bool IsTopNode) override;
+
+  void releaseTopNode(SUnit *SU) override {
+    Top.releaseTopNode(SU);
+  }
+
+  void releaseBottomNode(SUnit *SU) override {
+    Bot.releaseBottomNode(SU);
+  }
+
+  void registerRoots() override;
+
+protected:
+  void checkAcyclicLatency();
+
+  void tryCandidate(SchedCandidate &Cand,
+                    SchedCandidate &TryCand,
+                    SchedBoundary &Zone,
+                    const RegPressureTracker &RPTracker,
+                    RegPressureTracker &TempTracker);
+
+  SUnit *pickNodeBidirectional(bool &IsTopNode);
+
+  void pickNodeFromQueue(SchedBoundary &Zone,
+                         const RegPressureTracker &RPTracker,
+                         SchedCandidate &Candidate);
+
+  void reschedulePhysRegCopies(SUnit *SU, bool isTop);
+};
+
+/// PostGenericScheduler - Interface to the scheduling algorithm used by
+/// ScheduleDAGMI.
+///
+/// Callbacks from ScheduleDAGMI:
+///   initPolicy -> initialize(DAG) -> registerRoots -> pickNode ...
+class PostGenericScheduler : public GenericSchedulerBase {
+  ScheduleDAGMI *DAG;
+  SchedBoundary Top;
+  SmallVector<SUnit*, 8> BotRoots;
+public:
+  PostGenericScheduler(const MachineSchedContext *C):
+    GenericSchedulerBase(C), Top(SchedBoundary::TopQID, "TopQ") {}
+
+  virtual ~PostGenericScheduler() {}
+
+  void initPolicy(MachineBasicBlock::iterator Begin,
+                  MachineBasicBlock::iterator End,
+                  unsigned NumRegionInstrs) override {
+    /* no configurable policy */
+  };
+
+  /// PostRA scheduling does not track pressure.
+  bool shouldTrackPressure() const override { return false; }
+
+  void initialize(ScheduleDAGMI *Dag) override;
+
+  void registerRoots() override;
+
+  SUnit *pickNode(bool &IsTopNode) override;
+
+  void scheduleTree(unsigned SubtreeID) override {
+    llvm_unreachable("PostRA scheduler does not support subtree analysis.");
+  }
+
+  void schedNode(SUnit *SU, bool IsTopNode) override;
+
+  void releaseTopNode(SUnit *SU) override {
+    Top.releaseTopNode(SU);
+  }
+
+  // Only called for roots.
+  void releaseBottomNode(SUnit *SU) override {
+    BotRoots.push_back(SU);
+  }
+
+protected:
+  void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
+
+  void pickNodeFromQueue(SchedCandidate &Cand);
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h
new file mode 100644
index 0000000..323b694
--- /dev/null
+++ b/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -0,0 +1,391 @@
+//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- 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 interface for the MachineTraceMetrics analysis pass
+// that estimates CPU resource usage and critical data dependency paths through
+// preferred traces. This is useful for super-scalar CPUs where execution speed
+// can be limited both by data dependencies and by limited execution resources.
+//
+// Out-of-order CPUs will often be executing instructions from multiple basic
+// blocks at the same time. This makes it difficult to estimate the resource
+// usage accurately in a single basic block. Resources can be estimated better
+// by looking at a trace through the current basic block.
+//
+// For every block, the MachineTraceMetrics pass will pick a preferred trace
+// that passes through the block. The trace is chosen based on loop structure,
+// branch probabilities, and resource usage. The intention is to pick likely
+// traces that would be the most affected by code transformations.
+//
+// It is expensive to compute a full arbitrary trace for every block, so to
+// save some computations, traces are chosen to be convergent. This means that
+// if the traces through basic blocks A and B ever cross when moving away from
+// A and B, they never diverge again. This applies in both directions - If the
+// traces meet above A and B, they won't diverge when going further back.
+//
+// Traces tend to align with loops. The trace through a block in an inner loop
+// will begin at the loop entry block and end at a back edge. If there are
+// nested loops, the trace may begin and end at those instead.
+//
+// For each trace, we compute the critical path length, which is the number of
+// cycles required to execute the trace when execution is limited by data
+// dependencies only. We also compute the resource height, which is the number
+// of cycles required to execute all instructions in the trace when ignoring
+// data dependencies.
+//
+// Every instruction in the current block has a slack - the number of cycles
+// execution of the instruction can be delayed without extending the critical
+// path.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_TRACE_METRICS_H
+#define LLVM_CODEGEN_MACHINE_TRACE_METRICS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/TargetSchedule.h"
+
+namespace llvm {
+
+class InstrItineraryData;
+class MachineBasicBlock;
+class MachineInstr;
+class MachineLoop;
+class MachineLoopInfo;
+class MachineRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterInfo;
+class raw_ostream;
+
+class MachineTraceMetrics : public MachineFunctionPass {
+  const MachineFunction *MF;
+  const TargetInstrInfo *TII;
+  const TargetRegisterInfo *TRI;
+  const MachineRegisterInfo *MRI;
+  const MachineLoopInfo *Loops;
+  TargetSchedModel SchedModel;
+
+public:
+  class Ensemble;
+  class Trace;
+  static char ID;
+  MachineTraceMetrics();
+  void getAnalysisUsage(AnalysisUsage&) const override;
+  bool runOnMachineFunction(MachineFunction&) override;
+  void releaseMemory() override;
+  void verifyAnalysis() const override;
+
+  friend class Ensemble;
+  friend class Trace;
+
+  /// Per-basic block information that doesn't depend on the trace through the
+  /// block.
+  struct FixedBlockInfo {
+    /// The number of non-trivial instructions in the block.
+    /// Doesn't count PHI and COPY instructions that are likely to be removed.
+    unsigned InstrCount;
+
+    /// True when the block contains calls.
+    bool HasCalls;
+
+    FixedBlockInfo() : InstrCount(~0u), HasCalls(false) {}
+
+    /// Returns true when resource information for this block has been computed.
+    bool hasResources() const { return InstrCount != ~0u; }
+
+    /// Invalidate resource information.
+    void invalidate() { InstrCount = ~0u; }
+  };
+
+  /// Get the fixed resource information about MBB. Compute it on demand.
+  const FixedBlockInfo *getResources(const MachineBasicBlock*);
+
+  /// Get the scaled number of cycles used per processor resource in MBB.
+  /// This is an array with SchedModel.getNumProcResourceKinds() entries.
+  /// The getResources() function above must have been called first.
+  ///
+  /// These numbers have already been scaled by SchedModel.getResourceFactor().
+  ArrayRef<unsigned> getProcResourceCycles(unsigned MBBNum) const;
+
+  /// A virtual register or regunit required by a basic block or its trace
+  /// successors.
+  struct LiveInReg {
+    /// The virtual register required, or a register unit.
+    unsigned Reg;
+
+    /// For virtual registers: Minimum height of the defining instruction.
+    /// For regunits: Height of the highest user in the trace.
+    unsigned Height;
+
+    LiveInReg(unsigned Reg, unsigned Height = 0) : Reg(Reg), Height(Height) {}
+  };
+
+  /// Per-basic block information that relates to a specific trace through the
+  /// block. Convergent traces means that only one of these is required per
+  /// block in a trace ensemble.
+  struct TraceBlockInfo {
+    /// Trace predecessor, or NULL for the first block in the trace.
+    /// Valid when hasValidDepth().
+    const MachineBasicBlock *Pred;
+
+    /// Trace successor, or NULL for the last block in the trace.
+    /// Valid when hasValidHeight().
+    const MachineBasicBlock *Succ;
+
+    /// The block number of the head of the trace. (When hasValidDepth()).
+    unsigned Head;
+
+    /// The block number of the tail of the trace. (When hasValidHeight()).
+    unsigned Tail;
+
+    /// Accumulated number of instructions in the trace above this block.
+    /// Does not include instructions in this block.
+    unsigned InstrDepth;
+
+    /// Accumulated number of instructions in the trace below this block.
+    /// Includes instructions in this block.
+    unsigned InstrHeight;
+
+    TraceBlockInfo() :
+      Pred(nullptr), Succ(nullptr),
+      InstrDepth(~0u), InstrHeight(~0u),
+      HasValidInstrDepths(false), HasValidInstrHeights(false) {}
+
+    /// Returns true if the depth resources have been computed from the trace
+    /// above this block.
+    bool hasValidDepth() const { return InstrDepth != ~0u; }
+
+    /// Returns true if the height resources have been computed from the trace
+    /// below this block.
+    bool hasValidHeight() const { return InstrHeight != ~0u; }
+
+    /// Invalidate depth resources when some block above this one has changed.
+    void invalidateDepth() { InstrDepth = ~0u; HasValidInstrDepths = false; }
+
+    /// Invalidate height resources when a block below this one has changed.
+    void invalidateHeight() { InstrHeight = ~0u; HasValidInstrHeights = false; }
+
+    /// Assuming that this is a dominator of TBI, determine if it contains
+    /// useful instruction depths. A dominating block can be above the current
+    /// trace head, and any dependencies from such a far away dominator are not
+    /// expected to affect the critical path.
+    ///
+    /// Also returns true when TBI == this.
+    bool isUsefulDominator(const TraceBlockInfo &TBI) const {
+      // The trace for TBI may not even be calculated yet.
+      if (!hasValidDepth() || !TBI.hasValidDepth())
+        return false;
+      // Instruction depths are only comparable if the traces share a head.
+      if (Head != TBI.Head)
+        return false;
+      // It is almost always the case that TBI belongs to the same trace as
+      // this block, but rare convoluted cases involving irreducible control
+      // flow, a dominator may share a trace head without actually being on the
+      // same trace as TBI. This is not a big problem as long as it doesn't
+      // increase the instruction depth.
+      return HasValidInstrDepths && InstrDepth <= TBI.InstrDepth;
+    }
+
+    // Data-dependency-related information. Per-instruction depth and height
+    // are computed from data dependencies in the current trace, using
+    // itinerary data.
+
+    /// Instruction depths have been computed. This implies hasValidDepth().
+    bool HasValidInstrDepths;
+
+    /// Instruction heights have been computed. This implies hasValidHeight().
+    bool HasValidInstrHeights;
+
+    /// Critical path length. This is the number of cycles in the longest data
+    /// dependency chain through the trace. This is only valid when both
+    /// HasValidInstrDepths and HasValidInstrHeights are set.
+    unsigned CriticalPath;
+
+    /// Live-in registers. These registers are defined above the current block
+    /// and used by this block or a block below it.
+    /// This does not include PHI uses in the current block, but it does
+    /// include PHI uses in deeper blocks.
+    SmallVector<LiveInReg, 4> LiveIns;
+
+    void print(raw_ostream&) const;
+  };
+
+  /// InstrCycles represents the cycle height and depth of an instruction in a
+  /// trace.
+  struct InstrCycles {
+    /// Earliest issue cycle as determined by data dependencies and instruction
+    /// latencies from the beginning of the trace. Data dependencies from
+    /// before the trace are not included.
+    unsigned Depth;
+
+    /// Minimum number of cycles from this instruction is issued to the of the
+    /// trace, as determined by data dependencies and instruction latencies.
+    unsigned Height;
+  };
+
+  /// A trace represents a plausible sequence of executed basic blocks that
+  /// passes through the current basic block one. The Trace class serves as a
+  /// handle to internal cached data structures.
+  class Trace {
+    Ensemble &TE;
+    TraceBlockInfo &TBI;
+
+    unsigned getBlockNum() const { return &TBI - &TE.BlockInfo[0]; }
+
+  public:
+    explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
+    void print(raw_ostream&) const;
+
+    /// Compute the total number of instructions in the trace.
+    unsigned getInstrCount() const {
+      return TBI.InstrDepth + TBI.InstrHeight;
+    }
+
+    /// Return the resource depth of the top/bottom of the trace center block.
+    /// This is the number of cycles required to execute all instructions from
+    /// the trace head to the trace center block. The resource depth only
+    /// considers execution resources, it ignores data dependencies.
+    /// When Bottom is set, instructions in the trace center block are included.
+    unsigned getResourceDepth(bool Bottom) const;
+
+    /// Return the resource length of the trace. This is the number of cycles
+    /// required to execute the instructions in the trace if they were all
+    /// independent, exposing the maximum instruction-level parallelism.
+    ///
+    /// Any blocks in Extrablocks are included as if they were part of the
+    /// trace. Likewise, extra resources required by the specified scheduling
+    /// classes are included. For the caller to account for extra machine
+    /// instructions, it must first resolve each instruction's scheduling class.
+    unsigned getResourceLength(
+                ArrayRef<const MachineBasicBlock*> Extrablocks = None,
+                ArrayRef<const MCSchedClassDesc*> ExtraInstrs = None) const;
+
+    /// Return the length of the (data dependency) critical path through the
+    /// trace.
+    unsigned getCriticalPath() const { return TBI.CriticalPath; }
+
+    /// Return the depth and height of MI. The depth is only valid for
+    /// instructions in or above the trace center block. The height is only
+    /// valid for instructions in or below the trace center block.
+    InstrCycles getInstrCycles(const MachineInstr *MI) const {
+      return TE.Cycles.lookup(MI);
+    }
+
+    /// Return the slack of MI. This is the number of cycles MI can be delayed
+    /// before the critical path becomes longer.
+    /// MI must be an instruction in the trace center block.
+    unsigned getInstrSlack(const MachineInstr *MI) const;
+
+    /// Return the Depth of a PHI instruction in a trace center block successor.
+    /// The PHI does not have to be part of the trace.
+    unsigned getPHIDepth(const MachineInstr *PHI) const;
+  };
+
+  /// A trace ensemble is a collection of traces selected using the same
+  /// strategy, for example 'minimum resource height'. There is one trace for
+  /// every block in the function.
+  class Ensemble {
+    SmallVector<TraceBlockInfo, 4> BlockInfo;
+    DenseMap<const MachineInstr*, InstrCycles> Cycles;
+    SmallVector<unsigned, 0> ProcResourceDepths;
+    SmallVector<unsigned, 0> ProcResourceHeights;
+    friend class Trace;
+
+    void computeTrace(const MachineBasicBlock*);
+    void computeDepthResources(const MachineBasicBlock*);
+    void computeHeightResources(const MachineBasicBlock*);
+    unsigned computeCrossBlockCriticalPath(const TraceBlockInfo&);
+    void computeInstrDepths(const MachineBasicBlock*);
+    void computeInstrHeights(const MachineBasicBlock*);
+    void addLiveIns(const MachineInstr *DefMI, unsigned DefOp,
+                    ArrayRef<const MachineBasicBlock*> Trace);
+
+  protected:
+    MachineTraceMetrics &MTM;
+    virtual const MachineBasicBlock *pickTracePred(const MachineBasicBlock*) =0;
+    virtual const MachineBasicBlock *pickTraceSucc(const MachineBasicBlock*) =0;
+    explicit Ensemble(MachineTraceMetrics*);
+    const MachineLoop *getLoopFor(const MachineBasicBlock*) const;
+    const TraceBlockInfo *getDepthResources(const MachineBasicBlock*) const;
+    const TraceBlockInfo *getHeightResources(const MachineBasicBlock*) const;
+    ArrayRef<unsigned> getProcResourceDepths(unsigned MBBNum) const;
+    ArrayRef<unsigned> getProcResourceHeights(unsigned MBBNum) const;
+
+  public:
+    virtual ~Ensemble();
+    virtual const char *getName() const =0;
+    void print(raw_ostream&) const;
+    void invalidate(const MachineBasicBlock *MBB);
+    void verify() const;
+
+    /// Get the trace that passes through MBB.
+    /// The trace is computed on demand.
+    Trace getTrace(const MachineBasicBlock *MBB);
+  };
+
+  /// Strategies for selecting traces.
+  enum Strategy {
+    /// Select the trace through a block that has the fewest instructions.
+    TS_MinInstrCount,
+
+    TS_NumStrategies
+  };
+
+  /// Get the trace ensemble representing the given trace selection strategy.
+  /// The returned Ensemble object is owned by the MachineTraceMetrics analysis,
+  /// and valid for the lifetime of the analysis pass.
+  Ensemble *getEnsemble(Strategy);
+
+  /// Invalidate cached information about MBB. This must be called *before* MBB
+  /// is erased, or the CFG is otherwise changed.
+  ///
+  /// This invalidates per-block information about resource usage for MBB only,
+  /// and it invalidates per-trace information for any trace that passes
+  /// through MBB.
+  ///
+  /// Call Ensemble::getTrace() again to update any trace handles.
+  void invalidate(const MachineBasicBlock *MBB);
+
+private:
+  // One entry per basic block, indexed by block number.
+  SmallVector<FixedBlockInfo, 4> BlockInfo;
+
+  // Cycles consumed on each processor resource per block.
+  // The number of processor resource kinds is constant for a given subtarget,
+  // but it is not known at compile time. The number of cycles consumed by
+  // block B on processor resource R is at ProcResourceCycles[B*Kinds + R]
+  // where Kinds = SchedModel.getNumProcResourceKinds().
+  SmallVector<unsigned, 0> ProcResourceCycles;
+
+  // One ensemble per strategy.
+  Ensemble* Ensembles[TS_NumStrategies];
+
+  // Convert scaled resource usage to a cycle count that can be compared with
+  // latencies.
+  unsigned getCycles(unsigned Scaled) {
+    unsigned Factor = SchedModel.getLatencyFactor();
+    return (Scaled + Factor - 1) / Factor;
+  }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+                               const MachineTraceMetrics::Trace &Tr) {
+  Tr.print(OS);
+  return OS;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+                               const MachineTraceMetrics::Ensemble &En) {
+  En.print(OS);
+  return OS;
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h
new file mode 100644
index 0000000..ad215ec
--- /dev/null
+++ b/include/llvm/CodeGen/MachineValueType.h
@@ -0,0 +1,579 @@
+//===- CodeGen/MachineValueType.h - Machine-Level types ---------*- 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 set of machine-level target independent types which
+// legal values in the code generator use.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEVALUETYPE_H
+#define LLVM_CODEGEN_MACHINEVALUETYPE_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+
+namespace llvm {
+
+  class Type;
+
+  /// MVT - Machine Value Type. Every type that is supported natively by some
+  /// processor targeted by LLVM occurs here. This means that any legal value
+  /// type can be represented by an MVT.
+  class MVT {
+  public:
+    enum SimpleValueType {
+      // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are
+      // considered extended value types.
+      INVALID_SIMPLE_VALUE_TYPE = -1,
+
+      // If you change this numbering, you must change the values in
+      // ValueTypes.td as well!
+      Other          =   0,   // This is a non-standard value
+      i1             =   1,   // This is a 1 bit integer value
+      i8             =   2,   // This is an 8 bit integer value
+      i16            =   3,   // This is a 16 bit integer value
+      i32            =   4,   // This is a 32 bit integer value
+      i64            =   5,   // This is a 64 bit integer value
+      i128           =   6,   // This is a 128 bit integer value
+
+      FIRST_INTEGER_VALUETYPE = i1,
+      LAST_INTEGER_VALUETYPE  = i128,
+
+      f16            =   7,   // This is a 16 bit floating point value
+      f32            =   8,   // This is a 32 bit floating point value
+      f64            =   9,   // This is a 64 bit floating point value
+      f80            =  10,   // This is a 80 bit floating point value
+      f128           =  11,   // This is a 128 bit floating point value
+      ppcf128        =  12,   // This is a PPC 128-bit floating point value
+
+      FIRST_FP_VALUETYPE = f16,
+      LAST_FP_VALUETYPE  = ppcf128,
+
+      v2i1           =  13,   //  2 x i1
+      v4i1           =  14,   //  4 x i1
+      v8i1           =  15,   //  8 x i1
+      v16i1          =  16,   // 16 x i1
+      v32i1          =  17,   // 32 x i1
+      v64i1          =  18,   // 64 x i1
+
+      v1i8           =  19,   //  1 x i8
+      v2i8           =  20,   //  2 x i8
+      v4i8           =  21,   //  4 x i8
+      v8i8           =  22,   //  8 x i8
+      v16i8          =  23,   // 16 x i8
+      v32i8          =  24,   // 32 x i8
+      v64i8          =  25,   // 64 x i8
+      v1i16          =  26,   //  1 x i16
+      v2i16          =  27,   //  2 x i16
+      v4i16          =  28,   //  4 x i16
+      v8i16          =  29,   //  8 x i16
+      v16i16         =  30,   // 16 x i16
+      v32i16         =  31,   // 32 x i16
+      v1i32          =  32,   //  1 x i32
+      v2i32          =  33,   //  2 x i32
+      v4i32          =  34,   //  4 x i32
+      v8i32          =  35,   //  8 x i32
+      v16i32         =  36,   // 16 x i32
+      v1i64          =  37,   //  1 x i64
+      v2i64          =  38,   //  2 x i64
+      v4i64          =  39,   //  4 x i64
+      v8i64          =  40,   //  8 x i64
+      v16i64         =  41,   // 16 x i64
+
+      FIRST_INTEGER_VECTOR_VALUETYPE = v2i1,
+      LAST_INTEGER_VECTOR_VALUETYPE = v16i64,
+
+      v2f16          =  42,   //  2 x f16
+      v4f16          =  43,   //  4 x f16
+      v8f16          =  44,   //  8 x f16
+      v1f32          =  45,   //  1 x f32
+      v2f32          =  46,   //  2 x f32
+      v4f32          =  47,   //  4 x f32
+      v8f32          =  48,   //  8 x f32
+      v16f32         =  49,   // 16 x f32
+      v1f64          =  50,   //  1 x f64
+      v2f64          =  51,   //  2 x f64
+      v4f64          =  52,   //  4 x f64
+      v8f64          =  53,   //  8 x f64
+
+      FIRST_FP_VECTOR_VALUETYPE = v2f16,
+      LAST_FP_VECTOR_VALUETYPE = v8f64,
+
+      FIRST_VECTOR_VALUETYPE = v2i1,
+      LAST_VECTOR_VALUETYPE  = v8f64,
+
+      x86mmx         =  54,   // This is an X86 MMX value
+
+      Glue           =  55,   // This glues nodes together during pre-RA sched
+
+      isVoid         =  56,   // This has no value
+
+      Untyped        =  57,   // This value takes a register, but has
+                              // unspecified type.  The register class
+                              // will be determined by the opcode.
+
+      LAST_VALUETYPE =  58,   // This always remains at the end of the list.
+
+      // This is the current maximum for LAST_VALUETYPE.
+      // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
+      // This value must be a multiple of 32.
+      MAX_ALLOWED_VALUETYPE = 64,
+
+      // Metadata - This is MDNode or MDString.
+      Metadata       = 250,
+
+      // iPTRAny - An int value the size of the pointer of the current
+      // target to any address space. This must only be used internal to
+      // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR.
+      iPTRAny        = 251,
+
+      // vAny - A vector with any length and element size. This is used
+      // for intrinsics that have overloadings based on vector types.
+      // This is only for tblgen's consumption!
+      vAny           = 252,
+
+      // fAny - Any floating-point or vector floating-point value. This is used
+      // for intrinsics that have overloadings based on floating-point types.
+      // This is only for tblgen's consumption!
+      fAny           = 253,
+
+      // iAny - An integer or vector integer value of any bit width. This is
+      // used for intrinsics that have overloadings based on integer bit widths.
+      // This is only for tblgen's consumption!
+      iAny           = 254,
+
+      // iPTR - An int value the size of the pointer of the current
+      // target.  This should only be used internal to tblgen!
+      iPTR           = 255
+    };
+
+    SimpleValueType SimpleTy;
+
+    MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {}
+    MVT(SimpleValueType SVT) : SimpleTy(SVT) { }
+
+    bool operator>(const MVT& S)  const { return SimpleTy >  S.SimpleTy; }
+    bool operator<(const MVT& S)  const { return SimpleTy <  S.SimpleTy; }
+    bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; }
+    bool operator!=(const MVT& S) const { return SimpleTy != S.SimpleTy; }
+    bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
+    bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
+
+    /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+    bool isFloatingPoint() const {
+      return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
+               SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
+              (SimpleTy >= MVT::FIRST_FP_VECTOR_VALUETYPE &&
+               SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE));
+    }
+
+    /// isInteger - Return true if this is an integer, or a vector integer type.
+    bool isInteger() const {
+      return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
+               SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
+              (SimpleTy >= MVT::FIRST_INTEGER_VECTOR_VALUETYPE &&
+               SimpleTy <= MVT::LAST_INTEGER_VECTOR_VALUETYPE));
+    }
+
+    /// isVector - Return true if this is a vector value type.
+    bool isVector() const {
+      return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
+              SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
+    }
+
+    /// is16BitVector - Return true if this is a 16-bit vector type.
+    bool is16BitVector() const {
+      return (SimpleTy == MVT::v2i8  || SimpleTy == MVT::v1i16 ||
+              SimpleTy == MVT::v16i1);
+    }
+
+    /// is32BitVector - Return true if this is a 32-bit vector type.
+    bool is32BitVector() const {
+      return (SimpleTy == MVT::v4i8  || SimpleTy == MVT::v2i16 ||
+              SimpleTy == MVT::v1i32);
+    }
+
+    /// is64BitVector - Return true if this is a 64-bit vector type.
+    bool is64BitVector() const {
+      return (SimpleTy == MVT::v8i8  || SimpleTy == MVT::v4i16 ||
+              SimpleTy == MVT::v2i32 || SimpleTy == MVT::v1i64 ||
+              SimpleTy == MVT::v1f64 || SimpleTy == MVT::v2f32);
+    }
+
+    /// is128BitVector - Return true if this is a 128-bit vector type.
+    bool is128BitVector() const {
+      return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 ||
+              SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 ||
+              SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
+    }
+
+    /// is256BitVector - Return true if this is a 256-bit vector type.
+    bool is256BitVector() const {
+      return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64  ||
+              SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
+              SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64);
+    }
+
+    /// is512BitVector - Return true if this is a 512-bit vector type.
+    bool is512BitVector() const {
+      return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 ||
+              SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 ||
+              SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
+    }
+
+    /// is1024BitVector - Return true if this is a 1024-bit vector type.
+    bool is1024BitVector() const {
+      return (SimpleTy == MVT::v16i64);
+    }
+
+    /// isOverloaded - Return true if this is an overloaded type for TableGen.
+    bool isOverloaded() const {
+      return (SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
+              SimpleTy==MVT::vAny || SimpleTy==MVT::iPTRAny);
+    }
+
+    /// isPow2VectorType - Returns true if the given vector is a power of 2.
+    bool isPow2VectorType() const {
+      unsigned NElts = getVectorNumElements();
+      return !(NElts & (NElts - 1));
+    }
+
+    /// getPow2VectorType - Widens the length of the given vector MVT up to
+    /// the nearest power of 2 and returns that type.
+    MVT getPow2VectorType() const {
+      if (isPow2VectorType())
+        return *this;
+
+      unsigned NElts = getVectorNumElements();
+      unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
+      return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
+    }
+
+    /// getScalarType - If this is a vector type, return the element type,
+    /// otherwise return this.
+    MVT getScalarType() const {
+      return isVector() ? getVectorElementType() : *this;
+    }
+
+    MVT getVectorElementType() const {
+      switch (SimpleTy) {
+      default:
+        llvm_unreachable("Not a vector MVT!");
+      case v2i1 :
+      case v4i1 :
+      case v8i1 :
+      case v16i1 :
+      case v32i1 :
+      case v64i1: return i1;
+      case v1i8 :
+      case v2i8 :
+      case v4i8 :
+      case v8i8 :
+      case v16i8:
+      case v32i8:
+      case v64i8: return i8;
+      case v1i16:
+      case v2i16:
+      case v4i16:
+      case v8i16:
+      case v16i16:
+      case v32i16: return i16;
+      case v1i32:
+      case v2i32:
+      case v4i32:
+      case v8i32:
+      case v16i32: return i32;
+      case v1i64:
+      case v2i64:
+      case v4i64:
+      case v8i64:
+      case v16i64: return i64;
+      case v2f16:
+      case v4f16:
+      case v8f16: return f16;
+      case v1f32:
+      case v2f32:
+      case v4f32:
+      case v8f32:
+      case v16f32: return f32;
+      case v1f64:
+      case v2f64:
+      case v4f64:
+      case v8f64: return f64;
+      }
+    }
+
+    unsigned getVectorNumElements() const {
+      switch (SimpleTy) {
+      default:
+        llvm_unreachable("Not a vector MVT!");
+      case v32i1:
+      case v32i8:
+      case v32i16: return 32;
+      case v64i1:
+      case v64i8: return 64;
+      case v16i1:
+      case v16i8:
+      case v16i16:
+      case v16i32:
+      case v16i64:
+      case v16f32: return 16;
+      case v8i1 :
+      case v8i8 :
+      case v8i16:
+      case v8i32:
+      case v8i64:
+      case v8f16:
+      case v8f32:
+      case v8f64: return 8;
+      case v4i1:
+      case v4i8:
+      case v4i16:
+      case v4i32:
+      case v4i64:
+      case v4f16:
+      case v4f32:
+      case v4f64: return 4;
+      case v2i1:
+      case v2i8:
+      case v2i16:
+      case v2i32:
+      case v2i64:
+      case v2f16:
+      case v2f32:
+      case v2f64: return 2;
+      case v1i8:
+      case v1i16:
+      case v1i32:
+      case v1i64:
+      case v1f32:
+      case v1f64: return 1;
+      }
+    }
+
+    unsigned getSizeInBits() const {
+      switch (SimpleTy) {
+      default:
+        llvm_unreachable("getSizeInBits called on extended MVT.");
+      case Other:
+        llvm_unreachable("Value type is non-standard value, Other.");
+      case iPTR:
+        llvm_unreachable("Value type size is target-dependent. Ask TLI.");
+      case iPTRAny:
+      case iAny:
+      case fAny:
+      case vAny:
+        llvm_unreachable("Value type is overloaded.");
+      case Metadata:
+        llvm_unreachable("Value type is metadata.");
+      case i1  :  return 1;
+      case v2i1:  return 2;
+      case v4i1:  return 4;
+      case i8  :
+      case v1i8:
+      case v8i1: return 8;
+      case i16 :
+      case f16:
+      case v16i1:
+      case v2i8:
+      case v1i16: return 16;
+      case f32 :
+      case i32 :
+      case v32i1:
+      case v4i8:
+      case v2i16:
+      case v2f16:
+      case v1f32:
+      case v1i32: return 32;
+      case x86mmx:
+      case f64 :
+      case i64 :
+      case v64i1:
+      case v8i8:
+      case v4i16:
+      case v2i32:
+      case v1i64:
+      case v4f16:
+      case v2f32:
+      case v1f64: return 64;
+      case f80 :  return 80;
+      case f128:
+      case ppcf128:
+      case i128:
+      case v16i8:
+      case v8i16:
+      case v4i32:
+      case v2i64:
+      case v8f16:
+      case v4f32:
+      case v2f64: return 128;
+      case v32i8:
+      case v16i16:
+      case v8i32:
+      case v4i64:
+      case v8f32:
+      case v4f64: return 256;
+      case v64i8:
+      case v32i16:
+      case v16i32:
+      case v8i64:
+      case v16f32:
+      case v8f64: return 512;
+      case v16i64:return 1024;
+      }
+    }
+
+    unsigned getScalarSizeInBits() const {
+      return getScalarType().getSizeInBits();
+    }
+
+    /// getStoreSize - Return the number of bytes overwritten by a store
+    /// of the specified value type.
+    unsigned getStoreSize() const {
+      return (getSizeInBits() + 7) / 8;
+    }
+
+    /// getStoreSizeInBits - Return the number of bits overwritten by a store
+    /// of the specified value type.
+    unsigned getStoreSizeInBits() const {
+      return getStoreSize() * 8;
+    }
+
+    /// Return true if this has more bits than VT.
+    bool bitsGT(MVT VT) const {
+      return getSizeInBits() > VT.getSizeInBits();
+    }
+
+    /// Return true if this has no less bits than VT.
+    bool bitsGE(MVT VT) const {
+      return getSizeInBits() >= VT.getSizeInBits();
+    }
+
+    /// Return true if this has less bits than VT.
+    bool bitsLT(MVT VT) const {
+      return getSizeInBits() < VT.getSizeInBits();
+    }
+
+    /// Return true if this has no more bits than VT.
+    bool bitsLE(MVT VT) const {
+      return getSizeInBits() <= VT.getSizeInBits();
+    }
+
+
+    static MVT getFloatingPointVT(unsigned BitWidth) {
+      switch (BitWidth) {
+      default:
+        llvm_unreachable("Bad bit width!");
+      case 16:
+        return MVT::f16;
+      case 32:
+        return MVT::f32;
+      case 64:
+        return MVT::f64;
+      case 80:
+        return MVT::f80;
+      case 128:
+        return MVT::f128;
+      }
+    }
+
+    static MVT getIntegerVT(unsigned BitWidth) {
+      switch (BitWidth) {
+      default:
+        return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+      case 1:
+        return MVT::i1;
+      case 8:
+        return MVT::i8;
+      case 16:
+        return MVT::i16;
+      case 32:
+        return MVT::i32;
+      case 64:
+        return MVT::i64;
+      case 128:
+        return MVT::i128;
+      }
+    }
+
+    static MVT getVectorVT(MVT VT, unsigned NumElements) {
+      switch (VT.SimpleTy) {
+      default:
+        break;
+      case MVT::i1:
+        if (NumElements == 2)  return MVT::v2i1;
+        if (NumElements == 4)  return MVT::v4i1;
+        if (NumElements == 8)  return MVT::v8i1;
+        if (NumElements == 16) return MVT::v16i1;
+        if (NumElements == 32) return MVT::v32i1;
+        if (NumElements == 64) return MVT::v64i1;
+        break;
+      case MVT::i8:
+        if (NumElements == 1)  return MVT::v1i8;
+        if (NumElements == 2)  return MVT::v2i8;
+        if (NumElements == 4)  return MVT::v4i8;
+        if (NumElements == 8)  return MVT::v8i8;
+        if (NumElements == 16) return MVT::v16i8;
+        if (NumElements == 32) return MVT::v32i8;
+        if (NumElements == 64) return MVT::v64i8;
+        break;
+      case MVT::i16:
+        if (NumElements == 1)  return MVT::v1i16;
+        if (NumElements == 2)  return MVT::v2i16;
+        if (NumElements == 4)  return MVT::v4i16;
+        if (NumElements == 8)  return MVT::v8i16;
+        if (NumElements == 16) return MVT::v16i16;
+        if (NumElements == 32) return MVT::v32i16;
+        break;
+      case MVT::i32:
+        if (NumElements == 1)  return MVT::v1i32;
+        if (NumElements == 2)  return MVT::v2i32;
+        if (NumElements == 4)  return MVT::v4i32;
+        if (NumElements == 8)  return MVT::v8i32;
+        if (NumElements == 16) return MVT::v16i32;
+        break;
+      case MVT::i64:
+        if (NumElements == 1)  return MVT::v1i64;
+        if (NumElements == 2)  return MVT::v2i64;
+        if (NumElements == 4)  return MVT::v4i64;
+        if (NumElements == 8)  return MVT::v8i64;
+        if (NumElements == 16) return MVT::v16i64;
+        break;
+      case MVT::f16:
+        if (NumElements == 2)  return MVT::v2f16;
+        if (NumElements == 4)  return MVT::v4f16;
+        if (NumElements == 8)  return MVT::v8f16;
+        break;
+      case MVT::f32:
+        if (NumElements == 1)  return MVT::v1f32;
+        if (NumElements == 2)  return MVT::v2f32;
+        if (NumElements == 4)  return MVT::v4f32;
+        if (NumElements == 8)  return MVT::v8f32;
+        if (NumElements == 16) return MVT::v16f32;
+        break;
+      case MVT::f64:
+        if (NumElements == 1)  return MVT::v1f64;
+        if (NumElements == 2)  return MVT::v2f64;
+        if (NumElements == 4)  return MVT::v4f64;
+        if (NumElements == 8)  return MVT::v8f64;
+        break;
+      }
+      return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+    }
+
+    /// Return the value type corresponding to the specified type.  This returns
+    /// all pointers as iPTR.  If HandleUnknown is true, unknown types are
+    /// returned as Other, otherwise they are invalid.
+    static MVT getVT(Type *Ty, bool HandleUnknown = false);
+
+  };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/PBQP/CostAllocator.h b/include/llvm/CodeGen/PBQP/CostAllocator.h
new file mode 100644
index 0000000..ff62c09
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/CostAllocator.h
@@ -0,0 +1,147 @@
+//===---------- CostAllocator.h - PBQP Cost Allocator -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines classes conforming to the PBQP cost value manager concept.
+//
+// Cost value managers are memory managers for PBQP cost values (vectors and
+// matrices). Since PBQP graphs can grow very large (E.g. hundreds of thousands
+// of edges on the largest function in SPEC2006).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_COSTALLOCATOR_H
+#define LLVM_COSTALLOCATOR_H
+
+#include <set>
+#include <type_traits>
+
+namespace PBQP {
+
+template <typename CostT,
+          typename CostKeyTComparator>
+class CostPool {
+public:
+
+  class PoolEntry {
+  public:
+    template <typename CostKeyT>
+    PoolEntry(CostPool &pool, CostKeyT cost)
+      : pool(pool), cost(std::move(cost)), refCount(0) {}
+    ~PoolEntry() { pool.removeEntry(this); }
+    void incRef() { ++refCount; }
+    bool decRef() { --refCount; return (refCount == 0); }
+    CostT& getCost() { return cost; }
+    const CostT& getCost() const { return cost; }
+  private:
+    CostPool &pool;
+    CostT cost;
+    std::size_t refCount;
+  };
+
+  class PoolRef {
+  public:
+    PoolRef(PoolEntry *entry) : entry(entry) {
+      this->entry->incRef();
+    }
+    PoolRef(const PoolRef &r) {
+      entry = r.entry;
+      entry->incRef();
+    }
+    PoolRef& operator=(const PoolRef &r) {
+      assert(entry != nullptr && "entry should not be null.");
+      PoolEntry *temp = r.entry;
+      temp->incRef();
+      entry->decRef();
+      entry = temp;
+      return *this;
+    }
+
+    ~PoolRef() {
+      if (entry->decRef())
+        delete entry;
+    }
+    void reset(PoolEntry *entry) {
+      entry->incRef();
+      this->entry->decRef();
+      this->entry = entry;
+    }
+    CostT& operator*() { return entry->getCost(); }
+    const CostT& operator*() const { return entry->getCost(); }
+    CostT* operator->() { return &entry->getCost(); }
+    const CostT* operator->() const { return &entry->getCost(); }
+  private:
+    PoolEntry *entry;
+  };
+
+private:
+  class EntryComparator {
+  public:
+    template <typename CostKeyT>
+    typename std::enable_if<
+               !std::is_same<PoolEntry*,
+                             typename std::remove_const<CostKeyT>::type>::value,
+               bool>::type
+    operator()(const PoolEntry* a, const CostKeyT &b) {
+      return compare(a->getCost(), b);
+    }
+    bool operator()(const PoolEntry* a, const PoolEntry* b) {
+      return compare(a->getCost(), b->getCost());
+    }
+  private:
+    CostKeyTComparator compare;
+  };
+
+  typedef std::set<PoolEntry*, EntryComparator> EntrySet;
+
+  EntrySet entrySet;
+
+  void removeEntry(PoolEntry *p) { entrySet.erase(p); }
+
+public:
+
+  template <typename CostKeyT>
+  PoolRef getCost(CostKeyT costKey) {
+    typename EntrySet::iterator itr =
+      std::lower_bound(entrySet.begin(), entrySet.end(), costKey,
+                       EntryComparator());
+
+    if (itr != entrySet.end() && costKey == (*itr)->getCost())
+      return PoolRef(*itr);
+
+    PoolEntry *p = new PoolEntry(*this, std::move(costKey));
+    entrySet.insert(itr, p);
+    return PoolRef(p);
+  }
+};
+
+template <typename VectorT, typename VectorTComparator,
+          typename MatrixT, typename MatrixTComparator>
+class PoolCostAllocator {
+private:
+  typedef CostPool<VectorT, VectorTComparator> VectorCostPool;
+  typedef CostPool<MatrixT, MatrixTComparator> MatrixCostPool;
+public:
+  typedef VectorT Vector;
+  typedef MatrixT Matrix;
+  typedef typename VectorCostPool::PoolRef VectorPtr;
+  typedef typename MatrixCostPool::PoolRef MatrixPtr;
+
+  template <typename VectorKeyT>
+  VectorPtr getVector(VectorKeyT v) { return vectorPool.getCost(std::move(v)); }
+
+  template <typename MatrixKeyT>
+  MatrixPtr getMatrix(MatrixKeyT m) { return matrixPool.getCost(std::move(m)); }
+private:
+  VectorCostPool vectorPool;
+  MatrixCostPool matrixPool;
+};
+
+}
+
+#endif // LLVM_COSTALLOCATOR_H
diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h
new file mode 100644
index 0000000..a55f0ea
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/Graph.h
@@ -0,0 +1,642 @@
+//===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PBQP Graph class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
+#define LLVM_CODEGEN_PBQP_GRAPH_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/Compiler.h"
+#include <list>
+#include <map>
+#include <set>
+
+namespace PBQP {
+
+  class GraphBase {
+  public:
+    typedef unsigned NodeId;
+    typedef unsigned EdgeId;
+
+    /// \brief Returns a value representing an invalid (non-existent) node.
+    static NodeId invalidNodeId() {
+      return std::numeric_limits<NodeId>::max();
+    }
+
+    /// \brief Returns a value representing an invalid (non-existent) edge.
+    static EdgeId invalidEdgeId() {
+      return std::numeric_limits<EdgeId>::max();
+    }
+  };
+
+  /// PBQP Graph class.
+  /// Instances of this class describe PBQP problems.
+  ///
+  template <typename SolverT>
+  class Graph : public GraphBase {
+  private:
+    typedef typename SolverT::CostAllocator CostAllocator;
+  public:
+    typedef typename SolverT::RawVector RawVector;
+    typedef typename SolverT::RawMatrix RawMatrix;
+    typedef typename SolverT::Vector Vector;
+    typedef typename SolverT::Matrix Matrix;
+    typedef typename CostAllocator::VectorPtr VectorPtr;
+    typedef typename CostAllocator::MatrixPtr MatrixPtr;
+    typedef typename SolverT::NodeMetadata NodeMetadata;
+    typedef typename SolverT::EdgeMetadata EdgeMetadata;
+
+  private:
+
+    class NodeEntry {
+    public:
+      typedef std::vector<EdgeId> AdjEdgeList;
+      typedef AdjEdgeList::size_type AdjEdgeIdx;
+      typedef AdjEdgeList::const_iterator AdjEdgeItr;
+
+      static AdjEdgeIdx getInvalidAdjEdgeIdx() {
+        return std::numeric_limits<AdjEdgeIdx>::max();
+      }
+
+      NodeEntry(VectorPtr Costs) : Costs(Costs) {}
+
+      AdjEdgeIdx addAdjEdgeId(EdgeId EId) {
+        AdjEdgeIdx Idx = AdjEdgeIds.size();
+        AdjEdgeIds.push_back(EId);
+        return Idx;
+      }
+
+      void removeAdjEdgeId(Graph &G, NodeId ThisNId, AdjEdgeIdx Idx) {
+        // Swap-and-pop for fast removal.
+        //   1) Update the adj index of the edge currently at back().
+        //   2) Move last Edge down to Idx.
+        //   3) pop_back()
+        // If Idx == size() - 1 then the setAdjEdgeIdx and swap are
+        // redundant, but both operations are cheap.
+        G.getEdge(AdjEdgeIds.back()).setAdjEdgeIdx(ThisNId, Idx);
+        AdjEdgeIds[Idx] = AdjEdgeIds.back();
+        AdjEdgeIds.pop_back();
+      }
+
+      const AdjEdgeList& getAdjEdgeIds() const { return AdjEdgeIds; }
+
+      VectorPtr Costs;
+      NodeMetadata Metadata;
+    private:
+      AdjEdgeList AdjEdgeIds;
+    };
+
+    class EdgeEntry {
+    public:
+      EdgeEntry(NodeId N1Id, NodeId N2Id, MatrixPtr Costs)
+        : Costs(Costs) {
+        NIds[0] = N1Id;
+        NIds[1] = N2Id;
+        ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
+        ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
+      }
+
+      void invalidate() {
+        NIds[0] = NIds[1] = Graph::invalidNodeId();
+        ThisEdgeAdjIdxs[0] = ThisEdgeAdjIdxs[1] =
+          NodeEntry::getInvalidAdjEdgeIdx();
+        Costs = nullptr;
+      }
+
+      void connectToN(Graph &G, EdgeId ThisEdgeId, unsigned NIdx) {
+        assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
+               "Edge already connected to NIds[NIdx].");
+        NodeEntry &N = G.getNode(NIds[NIdx]);
+        ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
+      }
+
+      void connectTo(Graph &G, EdgeId ThisEdgeId, NodeId NId) {
+        if (NId == NIds[0])
+          connectToN(G, ThisEdgeId, 0);
+        else {
+          assert(NId == NIds[1] && "Edge does not connect NId.");
+          connectToN(G, ThisEdgeId, 1);
+        }
+      }
+
+      void connect(Graph &G, EdgeId ThisEdgeId) {
+        connectToN(G, ThisEdgeId, 0);
+        connectToN(G, ThisEdgeId, 1);
+      }
+
+      void setAdjEdgeIdx(NodeId NId, typename NodeEntry::AdjEdgeIdx NewIdx) {
+        if (NId == NIds[0])
+          ThisEdgeAdjIdxs[0] = NewIdx;
+        else {
+          assert(NId == NIds[1] && "Edge not connected to NId");
+          ThisEdgeAdjIdxs[1] = NewIdx;
+        }
+      }
+
+      void disconnectFromN(Graph &G, unsigned NIdx) {
+        assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
+               "Edge not connected to NIds[NIdx].");
+        NodeEntry &N = G.getNode(NIds[NIdx]);
+        N.removeAdjEdgeId(G, NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
+        ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
+      }
+
+      void disconnectFrom(Graph &G, NodeId NId) {
+        if (NId == NIds[0])
+          disconnectFromN(G, 0);
+        else {
+          assert(NId == NIds[1] && "Edge does not connect NId");
+          disconnectFromN(G, 1);
+        }
+      }
+
+      NodeId getN1Id() const { return NIds[0]; }
+      NodeId getN2Id() const { return NIds[1]; }
+      MatrixPtr Costs;
+      EdgeMetadata Metadata;
+    private:
+      NodeId NIds[2];
+      typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
+    };
+
+    // ----- MEMBERS -----
+
+    CostAllocator CostAlloc;
+    SolverT *Solver;
+
+    typedef std::vector<NodeEntry> NodeVector;
+    typedef std::vector<NodeId> FreeNodeVector;
+    NodeVector Nodes;
+    FreeNodeVector FreeNodeIds;
+
+    typedef std::vector<EdgeEntry> EdgeVector;
+    typedef std::vector<EdgeId> FreeEdgeVector;
+    EdgeVector Edges;
+    FreeEdgeVector FreeEdgeIds;
+
+    // ----- INTERNAL METHODS -----
+
+    NodeEntry& getNode(NodeId NId) { return Nodes[NId]; }
+    const NodeEntry& getNode(NodeId NId) const { return Nodes[NId]; }
+
+    EdgeEntry& getEdge(EdgeId EId) { return Edges[EId]; }
+    const EdgeEntry& getEdge(EdgeId EId) const { return Edges[EId]; }
+
+    NodeId addConstructedNode(const NodeEntry &N) {
+      NodeId NId = 0;
+      if (!FreeNodeIds.empty()) {
+        NId = FreeNodeIds.back();
+        FreeNodeIds.pop_back();
+        Nodes[NId] = std::move(N);
+      } else {
+        NId = Nodes.size();
+        Nodes.push_back(std::move(N));
+      }
+      return NId;
+    }
+
+    EdgeId addConstructedEdge(const EdgeEntry &E) {
+      assert(findEdge(E.getN1Id(), E.getN2Id()) == invalidEdgeId() &&
+             "Attempt to add duplicate edge.");
+      EdgeId EId = 0;
+      if (!FreeEdgeIds.empty()) {
+        EId = FreeEdgeIds.back();
+        FreeEdgeIds.pop_back();
+        Edges[EId] = std::move(E);
+      } else {
+        EId = Edges.size();
+        Edges.push_back(std::move(E));
+      }
+
+      EdgeEntry &NE = getEdge(EId);
+
+      // Add the edge to the adjacency sets of its nodes.
+      NE.connect(*this, EId);
+      return EId;
+    }
+
+    Graph(const Graph &Other) {}
+    void operator=(const Graph &Other) {}
+
+  public:
+
+    typedef typename NodeEntry::AdjEdgeItr AdjEdgeItr;
+
+    class NodeItr {
+    public:
+      NodeItr(NodeId CurNId, const Graph &G)
+        : CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {
+        this->CurNId = findNextInUse(CurNId); // Move to first in-use node id
+      }
+
+      bool operator==(const NodeItr &O) const { return CurNId == O.CurNId; }
+      bool operator!=(const NodeItr &O) const { return !(*this == O); }
+      NodeItr& operator++() { CurNId = findNextInUse(++CurNId); return *this; }
+      NodeId operator*() const { return CurNId; }
+
+    private:
+      NodeId findNextInUse(NodeId NId) const {
+        while (NId < EndNId &&
+               std::find(FreeNodeIds.begin(), FreeNodeIds.end(), NId) !=
+                 FreeNodeIds.end()) {
+          ++NId;
+        }
+        return NId;
+      }
+
+      NodeId CurNId, EndNId;
+      const FreeNodeVector &FreeNodeIds;
+    };
+
+    class EdgeItr {
+    public:
+      EdgeItr(EdgeId CurEId, const Graph &G)
+        : CurEId(CurEId), EndEId(G.Edges.size()), FreeEdgeIds(G.FreeEdgeIds) {
+        this->CurEId = findNextInUse(CurEId); // Move to first in-use edge id
+      }
+
+      bool operator==(const EdgeItr &O) const { return CurEId == O.CurEId; }
+      bool operator!=(const EdgeItr &O) const { return !(*this == O); }
+      EdgeItr& operator++() { CurEId = findNextInUse(++CurEId); return *this; }
+      EdgeId operator*() const { return CurEId; }
+
+    private:
+      EdgeId findNextInUse(EdgeId EId) const {
+        while (EId < EndEId &&
+               std::find(FreeEdgeIds.begin(), FreeEdgeIds.end(), EId) !=
+               FreeEdgeIds.end()) {
+          ++EId;
+        }
+        return EId;
+      }
+
+      EdgeId CurEId, EndEId;
+      const FreeEdgeVector &FreeEdgeIds;
+    };
+
+    class NodeIdSet {
+    public:
+      NodeIdSet(const Graph &G) : G(G) { }
+      NodeItr begin() const { return NodeItr(0, G); }
+      NodeItr end() const { return NodeItr(G.Nodes.size(), G); }
+      bool empty() const { return G.Nodes.empty(); }
+      typename NodeVector::size_type size() const {
+        return G.Nodes.size() - G.FreeNodeIds.size();
+      }
+    private:
+      const Graph& G;
+    };
+
+    class EdgeIdSet {
+    public:
+      EdgeIdSet(const Graph &G) : G(G) { }
+      EdgeItr begin() const { return EdgeItr(0, G); }
+      EdgeItr end() const { return EdgeItr(G.Edges.size(), G); }
+      bool empty() const { return G.Edges.empty(); }
+      typename NodeVector::size_type size() const {
+        return G.Edges.size() - G.FreeEdgeIds.size();
+      }
+    private:
+      const Graph& G;
+    };
+
+    class AdjEdgeIdSet {
+    public:
+      AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) { }
+      typename NodeEntry::AdjEdgeItr begin() const {
+        return NE.getAdjEdgeIds().begin();
+      }
+      typename NodeEntry::AdjEdgeItr end() const {
+        return NE.getAdjEdgeIds().end();
+      }
+      bool empty() const { return NE.getAdjEdgeIds().empty(); }
+      typename NodeEntry::AdjEdgeList::size_type size() const {
+        return NE.getAdjEdgeIds().size();
+      }
+    private:
+      const NodeEntry &NE;
+    };
+
+    /// \brief Construct an empty PBQP graph.
+    Graph() : Solver(nullptr) { }
+
+    /// \brief Lock this graph to the given solver instance in preparation
+    /// for running the solver. This method will call solver.handleAddNode for
+    /// each node in the graph, and handleAddEdge for each edge, to give the
+    /// solver an opportunity to set up any requried metadata.
+    void setSolver(SolverT &S) {
+      assert(!Solver && "Solver already set. Call unsetSolver().");
+      Solver = &S;
+      for (auto NId : nodeIds())
+        Solver->handleAddNode(NId);
+      for (auto EId : edgeIds())
+        Solver->handleAddEdge(EId);
+    }
+
+    /// \brief Release from solver instance.
+    void unsetSolver() {
+      assert(Solver && "Solver not set.");
+      Solver = nullptr;
+    }
+
+    /// \brief Add a node with the given costs.
+    /// @param Costs Cost vector for the new node.
+    /// @return Node iterator for the added node.
+    template <typename OtherVectorT>
+    NodeId addNode(OtherVectorT Costs) {
+      // Get cost vector from the problem domain
+      VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
+      NodeId NId = addConstructedNode(NodeEntry(AllocatedCosts));
+      if (Solver)
+        Solver->handleAddNode(NId);
+      return NId;
+    }
+
+    /// \brief Add an edge between the given nodes with the given costs.
+    /// @param N1Id First node.
+    /// @param N2Id Second node.
+    /// @return Edge iterator for the added edge.
+    template <typename OtherVectorT>
+    EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs) {
+      assert(getNodeCosts(N1Id).getLength() == Costs.getRows() &&
+             getNodeCosts(N2Id).getLength() == Costs.getCols() &&
+             "Matrix dimensions mismatch.");
+      // Get cost matrix from the problem domain.
+      MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
+      EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, AllocatedCosts));
+      if (Solver)
+        Solver->handleAddEdge(EId);
+      return EId;
+    }
+
+    /// \brief Returns true if the graph is empty.
+    bool empty() const { return NodeIdSet(*this).empty(); }
+
+    NodeIdSet nodeIds() const { return NodeIdSet(*this); }
+    EdgeIdSet edgeIds() const { return EdgeIdSet(*this); }
+
+    AdjEdgeIdSet adjEdgeIds(NodeId NId) { return AdjEdgeIdSet(getNode(NId)); }
+
+    /// \brief Get the number of nodes in the graph.
+    /// @return Number of nodes in the graph.
+    unsigned getNumNodes() const { return NodeIdSet(*this).size(); }
+
+    /// \brief Get the number of edges in the graph.
+    /// @return Number of edges in the graph.
+    unsigned getNumEdges() const { return EdgeIdSet(*this).size(); }
+
+    /// \brief Set a node's cost vector.
+    /// @param NId Node to update.
+    /// @param Costs New costs to set.
+    template <typename OtherVectorT>
+    void setNodeCosts(NodeId NId, OtherVectorT Costs) {
+      VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
+      if (Solver)
+        Solver->handleSetNodeCosts(NId, *AllocatedCosts);
+      getNode(NId).Costs = AllocatedCosts;
+    }
+
+    /// \brief Get a node's cost vector (const version).
+    /// @param NId Node id.
+    /// @return Node cost vector.
+    const Vector& getNodeCosts(NodeId NId) const {
+      return *getNode(NId).Costs;
+    }
+
+    NodeMetadata& getNodeMetadata(NodeId NId) {
+      return getNode(NId).Metadata;
+    }
+
+    const NodeMetadata& getNodeMetadata(NodeId NId) const {
+      return getNode(NId).Metadata;
+    }
+
+    typename NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const {
+      return getNode(NId).getAdjEdgeIds().size();
+    }
+
+    /// \brief Set an edge's cost matrix.
+    /// @param EId Edge id.
+    /// @param Costs New cost matrix.
+    template <typename OtherMatrixT>
+    void setEdgeCosts(EdgeId EId, OtherMatrixT Costs) {
+      MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
+      if (Solver)
+        Solver->handleSetEdgeCosts(EId, *AllocatedCosts);
+      getEdge(EId).Costs = AllocatedCosts;
+    }
+
+    /// \brief Get an edge's cost matrix (const version).
+    /// @param EId Edge id.
+    /// @return Edge cost matrix.
+    const Matrix& getEdgeCosts(EdgeId EId) const { return *getEdge(EId).Costs; }
+
+    EdgeMetadata& getEdgeMetadata(EdgeId NId) {
+      return getEdge(NId).Metadata;
+    }
+
+    const EdgeMetadata& getEdgeMetadata(EdgeId NId) const {
+      return getEdge(NId).Metadata;
+    }
+
+    /// \brief Get the first node connected to this edge.
+    /// @param EId Edge id.
+    /// @return The first node connected to the given edge.
+    NodeId getEdgeNode1Id(EdgeId EId) {
+      return getEdge(EId).getN1Id();
+    }
+
+    /// \brief Get the second node connected to this edge.
+    /// @param EId Edge id.
+    /// @return The second node connected to the given edge.
+    NodeId getEdgeNode2Id(EdgeId EId) {
+      return getEdge(EId).getN2Id();
+    }
+
+    /// \brief Get the "other" node connected to this edge.
+    /// @param EId Edge id.
+    /// @param NId Node id for the "given" node.
+    /// @return The iterator for the "other" node connected to this edge.
+    NodeId getEdgeOtherNodeId(EdgeId EId, NodeId NId) {
+      EdgeEntry &E = getEdge(EId);
+      if (E.getN1Id() == NId) {
+        return E.getN2Id();
+      } // else
+      return E.getN1Id();
+    }
+
+    /// \brief Get the edge connecting two nodes.
+    /// @param N1Id First node id.
+    /// @param N2Id Second node id.
+    /// @return An id for edge (N1Id, N2Id) if such an edge exists,
+    ///         otherwise returns an invalid edge id.
+    EdgeId findEdge(NodeId N1Id, NodeId N2Id) {
+      for (auto AEId : adjEdgeIds(N1Id)) {
+        if ((getEdgeNode1Id(AEId) == N2Id) ||
+            (getEdgeNode2Id(AEId) == N2Id)) {
+          return AEId;
+        }
+      }
+      return invalidEdgeId();
+    }
+
+    /// \brief Remove a node from the graph.
+    /// @param NId Node id.
+    void removeNode(NodeId NId) {
+      if (Solver)
+        Solver->handleRemoveNode(NId);
+      NodeEntry &N = getNode(NId);
+      // TODO: Can this be for-each'd?
+      for (AdjEdgeItr AEItr = N.adjEdgesBegin(),
+                      AEEnd = N.adjEdgesEnd();
+           AEItr != AEEnd;) {
+        EdgeId EId = *AEItr;
+        ++AEItr;
+        removeEdge(EId);
+      }
+      FreeNodeIds.push_back(NId);
+    }
+
+    /// \brief Disconnect an edge from the given node.
+    ///
+    /// Removes the given edge from the adjacency list of the given node.
+    /// This operation leaves the edge in an 'asymmetric' state: It will no
+    /// longer appear in an iteration over the given node's (NId's) edges, but
+    /// will appear in an iteration over the 'other', unnamed node's edges.
+    ///
+    /// This does not correspond to any normal graph operation, but exists to
+    /// support efficient PBQP graph-reduction based solvers. It is used to
+    /// 'effectively' remove the unnamed node from the graph while the solver
+    /// is performing the reduction. The solver will later call reconnectNode
+    /// to restore the edge in the named node's adjacency list.
+    ///
+    /// Since the degree of a node is the number of connected edges,
+    /// disconnecting an edge from a node 'u' will cause the degree of 'u' to
+    /// drop by 1.
+    ///
+    /// A disconnected edge WILL still appear in an iteration over the graph
+    /// edges.
+    ///
+    /// A disconnected edge should not be removed from the graph, it should be
+    /// reconnected first.
+    ///
+    /// A disconnected edge can be reconnected by calling the reconnectEdge
+    /// method.
+    void disconnectEdge(EdgeId EId, NodeId NId) {
+      if (Solver)
+        Solver->handleDisconnectEdge(EId, NId);
+
+      EdgeEntry &E = getEdge(EId);
+      E.disconnectFrom(*this, NId);
+    }
+
+    /// \brief Convenience method to disconnect all neighbours from the given
+    ///        node.
+    void disconnectAllNeighborsFromNode(NodeId NId) {
+      for (auto AEId : adjEdgeIds(NId))
+        disconnectEdge(AEId, getEdgeOtherNodeId(AEId, NId));
+    }
+
+    /// \brief Re-attach an edge to its nodes.
+    ///
+    /// Adds an edge that had been previously disconnected back into the
+    /// adjacency set of the nodes that the edge connects.
+    void reconnectEdge(EdgeId EId, NodeId NId) {
+      EdgeEntry &E = getEdge(EId);
+      E.connectTo(*this, EId, NId);
+      if (Solver)
+        Solver->handleReconnectEdge(EId, NId);
+    }
+
+    /// \brief Remove an edge from the graph.
+    /// @param EId Edge id.
+    void removeEdge(EdgeId EId) {
+      if (Solver)
+        Solver->handleRemoveEdge(EId);
+      EdgeEntry &E = getEdge(EId);
+      E.disconnect();
+      FreeEdgeIds.push_back(EId);
+      Edges[EId].invalidate();
+    }
+
+    /// \brief Remove all nodes and edges from the graph.
+    void clear() {
+      Nodes.clear();
+      FreeNodeIds.clear();
+      Edges.clear();
+      FreeEdgeIds.clear();
+    }
+
+    /// \brief Dump a graph to an output stream.
+    template <typename OStream>
+    void dump(OStream &OS) {
+      OS << nodeIds().size() << " " << edgeIds().size() << "\n";
+
+      for (auto NId : nodeIds()) {
+        const Vector& V = getNodeCosts(NId);
+        OS << "\n" << V.getLength() << "\n";
+        assert(V.getLength() != 0 && "Empty vector in graph.");
+        OS << V[0];
+        for (unsigned i = 1; i < V.getLength(); ++i) {
+          OS << " " << V[i];
+        }
+        OS << "\n";
+      }
+
+      for (auto EId : edgeIds()) {
+        NodeId N1Id = getEdgeNode1Id(EId);
+        NodeId N2Id = getEdgeNode2Id(EId);
+        assert(N1Id != N2Id && "PBQP graphs shound not have self-edges.");
+        const Matrix& M = getEdgeCosts(EId);
+        OS << "\n" << N1Id << " " << N2Id << "\n"
+           << M.getRows() << " " << M.getCols() << "\n";
+        assert(M.getRows() != 0 && "No rows in matrix.");
+        assert(M.getCols() != 0 && "No cols in matrix.");
+        for (unsigned i = 0; i < M.getRows(); ++i) {
+          OS << M[i][0];
+          for (unsigned j = 1; j < M.getCols(); ++j) {
+            OS << " " << M[i][j];
+          }
+          OS << "\n";
+        }
+      }
+    }
+
+    /// \brief Print a representation of this graph in DOT format.
+    /// @param OS Output stream to print on.
+    template <typename OStream>
+    void printDot(OStream &OS) {
+      OS << "graph {\n";
+      for (auto NId : nodeIds()) {
+        OS << "  node" << NId << " [ label=\""
+           << NId << ": " << getNodeCosts(NId) << "\" ]\n";
+      }
+      OS << "  edge [ len=" << nodeIds().size() << " ]\n";
+      for (auto EId : edgeIds()) {
+        OS << "  node" << getEdgeNode1Id(EId)
+           << " -- node" << getEdgeNode2Id(EId)
+           << " [ label=\"";
+        const Matrix &EdgeCosts = getEdgeCosts(EId);
+        for (unsigned i = 0; i < EdgeCosts.getRows(); ++i) {
+          OS << EdgeCosts.getRowAsVector(i) << "\\n";
+        }
+        OS << "\" ]\n";
+      }
+      OS << "}\n";
+    }
+  };
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h
new file mode 100644
index 0000000..69a9d83
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/Math.h
@@ -0,0 +1,438 @@
+//===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_MATH_H
+#define LLVM_CODEGEN_PBQP_MATH_H
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+
+namespace PBQP {
+
+typedef float PBQPNum;
+
+/// \brief PBQP Vector class.
+class Vector {
+  friend class VectorComparator;
+public:
+
+  /// \brief Construct a PBQP vector of the given size.
+  explicit Vector(unsigned Length)
+    : Length(Length), Data(new PBQPNum[Length]) {
+    // llvm::dbgs() << "Constructing PBQP::Vector "
+    //              << this << " (length " << Length << ")\n";
+  }
+
+  /// \brief Construct a PBQP vector with initializer.
+  Vector(unsigned Length, PBQPNum InitVal)
+    : Length(Length), Data(new PBQPNum[Length]) {
+    // llvm::dbgs() << "Constructing PBQP::Vector "
+    //              << this << " (length " << Length << ", fill "
+    //              << InitVal << ")\n";
+    std::fill(Data, Data + Length, InitVal);
+  }
+
+  /// \brief Copy construct a PBQP vector.
+  Vector(const Vector &V)
+    : Length(V.Length), Data(new PBQPNum[Length]) {
+    // llvm::dbgs() << "Copy-constructing PBQP::Vector " << this
+    //              << " from PBQP::Vector " << &V << "\n";
+    std::copy(V.Data, V.Data + Length, Data);
+  }
+
+  /// \brief Move construct a PBQP vector.
+  Vector(Vector &&V)
+    : Length(V.Length), Data(V.Data) {
+    V.Length = 0;
+    V.Data = nullptr;
+  }
+
+  /// \brief Destroy this vector, return its memory.
+  ~Vector() {
+    // llvm::dbgs() << "Deleting PBQP::Vector " << this << "\n";
+    delete[] Data;
+  }
+
+  /// \brief Copy-assignment operator.
+  Vector& operator=(const Vector &V) {
+    // llvm::dbgs() << "Assigning to PBQP::Vector " << this
+    //              << " from PBQP::Vector " << &V << "\n";
+    delete[] Data;
+    Length = V.Length;
+    Data = new PBQPNum[Length];
+    std::copy(V.Data, V.Data + Length, Data);
+    return *this;
+  }
+
+  /// \brief Move-assignment operator.
+  Vector& operator=(Vector &&V) {
+    delete[] Data;
+    Length = V.Length;
+    Data = V.Data;
+    V.Length = 0;
+    V.Data = nullptr;
+    return *this;
+  }
+
+  /// \brief Comparison operator.
+  bool operator==(const Vector &V) const {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    if (Length != V.Length)
+      return false;
+    return std::equal(Data, Data + Length, V.Data);
+  }
+
+  /// \brief Return the length of the vector
+  unsigned getLength() const {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    return Length;
+  }
+
+  /// \brief Element access.
+  PBQPNum& operator[](unsigned Index) {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    assert(Index < Length && "Vector element access out of bounds.");
+    return Data[Index];
+  }
+
+  /// \brief Const element access.
+  const PBQPNum& operator[](unsigned Index) const {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    assert(Index < Length && "Vector element access out of bounds.");
+    return Data[Index];
+  }
+
+  /// \brief Add another vector to this one.
+  Vector& operator+=(const Vector &V) {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    assert(Length == V.Length && "Vector length mismatch.");
+    std::transform(Data, Data + Length, V.Data, Data, std::plus<PBQPNum>());
+    return *this;
+  }
+
+  /// \brief Subtract another vector from this one.
+  Vector& operator-=(const Vector &V) {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    assert(Length == V.Length && "Vector length mismatch.");
+    std::transform(Data, Data + Length, V.Data, Data, std::minus<PBQPNum>());
+    return *this;
+  }
+
+  /// \brief Returns the index of the minimum value in this vector
+  unsigned minIndex() const {
+    assert(Length != 0 && Data != nullptr && "Invalid vector");
+    return std::min_element(Data, Data + Length) - Data;
+  }
+
+private:
+  unsigned Length;
+  PBQPNum *Data;
+};
+
+class VectorComparator {
+public:
+  bool operator()(const Vector &A, const Vector &B) {
+    if (A.Length < B.Length)
+      return true;
+    if (B.Length < A.Length)
+      return false;
+    char *AData = reinterpret_cast<char*>(A.Data);
+    char *BData = reinterpret_cast<char*>(B.Data);
+    return std::lexicographical_compare(AData,
+                                        AData + A.Length * sizeof(PBQPNum),
+                                        BData,
+                                        BData + A.Length * sizeof(PBQPNum));
+  }
+};
+
+/// \brief Output a textual representation of the given vector on the given
+///        output stream.
+template <typename OStream>
+OStream& operator<<(OStream &OS, const Vector &V) {
+  assert((V.getLength() != 0) && "Zero-length vector badness.");
+
+  OS << "[ " << V[0];
+  for (unsigned i = 1; i < V.getLength(); ++i)
+    OS << ", " << V[i];
+  OS << " ]";
+
+  return OS;
+}
+
+
+/// \brief PBQP Matrix class
+class Matrix {
+private:
+  friend class MatrixComparator;
+public:
+
+  /// \brief Construct a PBQP Matrix with the given dimensions.
+  Matrix(unsigned Rows, unsigned Cols) :
+    Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) {
+  }
+
+  /// \brief Construct a PBQP Matrix with the given dimensions and initial
+  /// value.
+  Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
+    : Rows(Rows), Cols(Cols), Data(new PBQPNum[Rows * Cols]) {
+    std::fill(Data, Data + (Rows * Cols), InitVal);
+  }
+
+  /// \brief Copy construct a PBQP matrix.
+  Matrix(const Matrix &M)
+    : Rows(M.Rows), Cols(M.Cols), Data(new PBQPNum[Rows * Cols]) {
+    std::copy(M.Data, M.Data + (Rows * Cols), Data);
+  }
+
+  /// \brief Move construct a PBQP matrix.
+  Matrix(Matrix &&M)
+    : Rows(M.Rows), Cols(M.Cols), Data(M.Data) {
+    M.Rows = M.Cols = 0;
+    M.Data = nullptr;
+  }
+
+  /// \brief Destroy this matrix, return its memory.
+  ~Matrix() { delete[] Data; }
+
+  /// \brief Copy-assignment operator.
+  Matrix& operator=(const Matrix &M) {
+    delete[] Data;
+    Rows = M.Rows; Cols = M.Cols;
+    Data = new PBQPNum[Rows * Cols];
+    std::copy(M.Data, M.Data + (Rows * Cols), Data);
+    return *this;
+  }
+
+  /// \brief Move-assignment operator.
+  Matrix& operator=(Matrix &&M) {
+    delete[] Data;
+    Rows = M.Rows;
+    Cols = M.Cols;
+    Data = M.Data;
+    M.Rows = M.Cols = 0;
+    M.Data = nullptr;
+    return *this;
+  }
+
+  /// \brief Comparison operator.
+  bool operator==(const Matrix &M) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    if (Rows != M.Rows || Cols != M.Cols)
+      return false;
+    return std::equal(Data, Data + (Rows * Cols), M.Data);
+  }
+
+  /// \brief Return the number of rows in this matrix.
+  unsigned getRows() const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    return Rows;
+  }
+
+  /// \brief Return the number of cols in this matrix.
+  unsigned getCols() const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    return Cols;
+  }
+
+  /// \brief Matrix element access.
+  PBQPNum* operator[](unsigned R) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(R < Rows && "Row out of bounds.");
+    return Data + (R * Cols);
+  }
+
+  /// \brief Matrix element access.
+  const PBQPNum* operator[](unsigned R) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(R < Rows && "Row out of bounds.");
+    return Data + (R * Cols);
+  }
+
+  /// \brief Returns the given row as a vector.
+  Vector getRowAsVector(unsigned R) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    Vector V(Cols);
+    for (unsigned C = 0; C < Cols; ++C)
+      V[C] = (*this)[R][C];
+    return V;
+  }
+
+  /// \brief Returns the given column as a vector.
+  Vector getColAsVector(unsigned C) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    Vector V(Rows);
+    for (unsigned R = 0; R < Rows; ++R)
+      V[R] = (*this)[R][C];
+    return V;
+  }
+
+  /// \brief Reset the matrix to the given value.
+  Matrix& reset(PBQPNum Val = 0) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    std::fill(Data, Data + (Rows * Cols), Val);
+    return *this;
+  }
+
+  /// \brief Set a single row of this matrix to the given value.
+  Matrix& setRow(unsigned R, PBQPNum Val) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(R < Rows && "Row out of bounds.");
+    std::fill(Data + (R * Cols), Data + ((R + 1) * Cols), Val);
+    return *this;
+  }
+
+  /// \brief Set a single column of this matrix to the given value.
+  Matrix& setCol(unsigned C, PBQPNum Val) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(C < Cols && "Column out of bounds.");
+    for (unsigned R = 0; R < Rows; ++R)
+      (*this)[R][C] = Val;
+    return *this;
+  }
+
+  /// \brief Matrix transpose.
+  Matrix transpose() const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    Matrix M(Cols, Rows);
+    for (unsigned r = 0; r < Rows; ++r)
+      for (unsigned c = 0; c < Cols; ++c)
+        M[c][r] = (*this)[r][c];
+    return M;
+  }
+
+  /// \brief Returns the diagonal of the matrix as a vector.
+  ///
+  /// Matrix must be square.
+  Vector diagonalize() const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(Rows == Cols && "Attempt to diagonalize non-square matrix.");
+    Vector V(Rows);
+    for (unsigned r = 0; r < Rows; ++r)
+      V[r] = (*this)[r][r];
+    return V;
+  }
+
+  /// \brief Add the given matrix to this one.
+  Matrix& operator+=(const Matrix &M) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(Rows == M.Rows && Cols == M.Cols &&
+           "Matrix dimensions mismatch.");
+    std::transform(Data, Data + (Rows * Cols), M.Data, Data,
+                   std::plus<PBQPNum>());
+    return *this;
+  }
+
+  Matrix operator+(const Matrix &M) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    Matrix Tmp(*this);
+    Tmp += M;
+    return Tmp;
+  }
+
+  /// \brief Returns the minimum of the given row
+  PBQPNum getRowMin(unsigned R) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(R < Rows && "Row out of bounds");
+    return *std::min_element(Data + (R * Cols), Data + ((R + 1) * Cols));
+  }
+
+  /// \brief Returns the minimum of the given column
+  PBQPNum getColMin(unsigned C) const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    PBQPNum MinElem = (*this)[0][C];
+    for (unsigned R = 1; R < Rows; ++R)
+      if ((*this)[R][C] < MinElem)
+        MinElem = (*this)[R][C];
+    return MinElem;
+  }
+
+  /// \brief Subtracts the given scalar from the elements of the given row.
+  Matrix& subFromRow(unsigned R, PBQPNum Val) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    assert(R < Rows && "Row out of bounds");
+    std::transform(Data + (R * Cols), Data + ((R + 1) * Cols),
+                   Data + (R * Cols),
+                   std::bind2nd(std::minus<PBQPNum>(), Val));
+    return *this;
+  }
+
+  /// \brief Subtracts the given scalar from the elements of the given column.
+  Matrix& subFromCol(unsigned C, PBQPNum Val) {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    for (unsigned R = 0; R < Rows; ++R)
+      (*this)[R][C] -= Val;
+    return *this;
+  }
+
+  /// \brief Returns true if this is a zero matrix.
+  bool isZero() const {
+    assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+    return find_if(Data, Data + (Rows * Cols),
+                   std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
+      Data + (Rows * Cols);
+  }
+
+private:
+  unsigned Rows, Cols;
+  PBQPNum *Data;
+};
+
+class MatrixComparator {
+public:
+  bool operator()(const Matrix &A, const Matrix &B) {
+    if (A.Rows < B.Rows)
+      return true;
+    if (B.Rows < A.Rows)
+      return false;
+    if (A.Cols < B.Cols)
+      return true;
+    if (B.Cols < A.Cols)
+      return false;
+    char *AData = reinterpret_cast<char*>(A.Data);
+    char *BData = reinterpret_cast<char*>(B.Data);
+    return std::lexicographical_compare(
+             AData, AData + (A.Rows * A.Cols * sizeof(PBQPNum)),
+             BData, BData + (A.Rows * A.Cols * sizeof(PBQPNum)));
+  }
+};
+
+/// \brief Output a textual representation of the given matrix on the given
+///        output stream.
+template <typename OStream>
+OStream& operator<<(OStream &OS, const Matrix &M) {
+  assert((M.getRows() != 0) && "Zero-row matrix badness.");
+  for (unsigned i = 0; i < M.getRows(); ++i)
+    OS << M.getRowAsVector(i);
+  return OS;
+}
+
+template <typename Metadata>
+class MDVector : public Vector {
+public:
+  MDVector(const Vector &v) : Vector(v), md(*this) { }
+  MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
+  const Metadata& getMetadata() const { return md; }
+private:
+  Metadata md;
+};
+
+template <typename Metadata>
+class MDMatrix : public Matrix {
+public:
+  MDMatrix(const Matrix &m) : Matrix(m), md(*this) { }
+  MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
+  const Metadata& getMetadata() const { return md; }
+private:
+  Metadata md;
+};
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_MATH_H
diff --git a/include/llvm/CodeGen/PBQP/ReductionRules.h b/include/llvm/CodeGen/PBQP/ReductionRules.h
new file mode 100644
index 0000000..a55a060
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/ReductionRules.h
@@ -0,0 +1,191 @@
+//===----------- ReductionRules.h - Reduction Rules -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Reduction Rules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REDUCTIONRULES_H
+#define LLVM_REDUCTIONRULES_H
+
+#include "Graph.h"
+#include "Math.h"
+#include "Solution.h"
+
+namespace PBQP {
+
+  /// \brief Reduce a node of degree one.
+  ///
+  /// Propagate costs from the given node, which must be of degree one, to its
+  /// neighbor. Notify the problem domain.
+  template <typename GraphT>
+  void applyR1(GraphT &G, typename GraphT::NodeId NId) {
+    typedef typename GraphT::NodeId NodeId;
+    typedef typename GraphT::EdgeId EdgeId;
+    typedef typename GraphT::Vector Vector;
+    typedef typename GraphT::Matrix Matrix;
+    typedef typename GraphT::RawVector RawVector;
+
+    assert(G.getNodeDegree(NId) == 1 &&
+           "R1 applied to node with degree != 1.");
+
+    EdgeId EId = *G.adjEdgeIds(NId).begin();
+    NodeId MId = G.getEdgeOtherNodeId(EId, NId);
+
+    const Matrix &ECosts = G.getEdgeCosts(EId);
+    const Vector &XCosts = G.getNodeCosts(NId);
+    RawVector YCosts = G.getNodeCosts(MId);
+
+    // Duplicate a little to avoid transposing matrices.
+    if (NId == G.getEdgeNode1Id(EId)) {
+      for (unsigned j = 0; j < YCosts.getLength(); ++j) {
+        PBQPNum Min = ECosts[0][j] + XCosts[0];
+        for (unsigned i = 1; i < XCosts.getLength(); ++i) {
+          PBQPNum C = ECosts[i][j] + XCosts[i];
+          if (C < Min)
+            Min = C;
+        }
+        YCosts[j] += Min;
+      }
+    } else {
+      for (unsigned i = 0; i < YCosts.getLength(); ++i) {
+        PBQPNum Min = ECosts[i][0] + XCosts[0];
+        for (unsigned j = 1; j < XCosts.getLength(); ++j) {
+          PBQPNum C = ECosts[i][j] + XCosts[j];
+          if (C < Min)
+            Min = C;
+        }
+        YCosts[i] += Min;
+      }
+    }
+    G.setNodeCosts(MId, YCosts);
+    G.disconnectEdge(EId, MId);
+  }
+
+  template <typename GraphT>
+  void applyR2(GraphT &G, typename GraphT::NodeId NId) {
+    typedef typename GraphT::NodeId NodeId;
+    typedef typename GraphT::EdgeId EdgeId;
+    typedef typename GraphT::Vector Vector;
+    typedef typename GraphT::Matrix Matrix;
+    typedef typename GraphT::RawMatrix RawMatrix;
+
+    assert(G.getNodeDegree(NId) == 2 &&
+           "R2 applied to node with degree != 2.");
+
+    const Vector &XCosts = G.getNodeCosts(NId);
+
+    typename GraphT::AdjEdgeItr AEItr = G.adjEdgeIds(NId).begin();
+    EdgeId YXEId = *AEItr,
+           ZXEId = *(++AEItr);
+
+    NodeId YNId = G.getEdgeOtherNodeId(YXEId, NId),
+           ZNId = G.getEdgeOtherNodeId(ZXEId, NId);
+
+    bool FlipEdge1 = (G.getEdgeNode1Id(YXEId) == NId),
+         FlipEdge2 = (G.getEdgeNode1Id(ZXEId) == NId);
+
+    const Matrix *YXECosts = FlipEdge1 ?
+      new Matrix(G.getEdgeCosts(YXEId).transpose()) :
+      &G.getEdgeCosts(YXEId);
+
+    const Matrix *ZXECosts = FlipEdge2 ?
+      new Matrix(G.getEdgeCosts(ZXEId).transpose()) :
+      &G.getEdgeCosts(ZXEId);
+
+    unsigned XLen = XCosts.getLength(),
+      YLen = YXECosts->getRows(),
+      ZLen = ZXECosts->getRows();
+
+    RawMatrix Delta(YLen, ZLen);
+
+    for (unsigned i = 0; i < YLen; ++i) {
+      for (unsigned j = 0; j < ZLen; ++j) {
+        PBQPNum Min = (*YXECosts)[i][0] + (*ZXECosts)[j][0] + XCosts[0];
+        for (unsigned k = 1; k < XLen; ++k) {
+          PBQPNum C = (*YXECosts)[i][k] + (*ZXECosts)[j][k] + XCosts[k];
+          if (C < Min) {
+            Min = C;
+          }
+        }
+        Delta[i][j] = Min;
+      }
+    }
+
+    if (FlipEdge1)
+      delete YXECosts;
+
+    if (FlipEdge2)
+      delete ZXECosts;
+
+    EdgeId YZEId = G.findEdge(YNId, ZNId);
+
+    if (YZEId == G.invalidEdgeId()) {
+      YZEId = G.addEdge(YNId, ZNId, Delta);
+    } else {
+      const Matrix &YZECosts = G.getEdgeCosts(YZEId);
+      if (YNId == G.getEdgeNode1Id(YZEId)) {
+        G.setEdgeCosts(YZEId, Delta + YZECosts);
+      } else {
+        G.setEdgeCosts(YZEId, Delta.transpose() + YZECosts);
+      }
+    }
+
+    G.disconnectEdge(YXEId, YNId);
+    G.disconnectEdge(ZXEId, ZNId);
+
+    // TODO: Try to normalize newly added/modified edge.
+  }
+
+
+  // \brief Find a solution to a fully reduced graph by backpropagation.
+  //
+  // Given a graph and a reduction order, pop each node from the reduction
+  // order and greedily compute a minimum solution based on the node costs, and
+  // the dependent costs due to previously solved nodes.
+  //
+  // Note - This does not return the graph to its original (pre-reduction)
+  //        state: the existing solvers destructively alter the node and edge
+  //        costs. Given that, the backpropagate function doesn't attempt to
+  //        replace the edges either, but leaves the graph in its reduced
+  //        state.
+  template <typename GraphT, typename StackT>
+  Solution backpropagate(GraphT& G, StackT stack) {
+    typedef GraphBase::NodeId NodeId;
+    typedef typename GraphT::Matrix Matrix;
+    typedef typename GraphT::RawVector RawVector;
+
+    Solution s;
+
+    while (!stack.empty()) {
+      NodeId NId = stack.back();
+      stack.pop_back();
+
+      RawVector v = G.getNodeCosts(NId);
+
+      for (auto EId : G.adjEdgeIds(NId)) {
+        const Matrix& edgeCosts = G.getEdgeCosts(EId);
+        if (NId == G.getEdgeNode1Id(EId)) {
+          NodeId mId = G.getEdgeNode2Id(EId);
+          v += edgeCosts.getColAsVector(s.getSelection(mId));
+        } else {
+          NodeId mId = G.getEdgeNode1Id(EId);
+          v += edgeCosts.getRowAsVector(s.getSelection(mId));
+        }
+      }
+
+      s.setSelection(NId, v.minIndex());
+    }
+
+    return s;
+  }
+
+}
+
+#endif // LLVM_REDUCTIONRULES_H
diff --git a/include/llvm/CodeGen/PBQP/RegAllocSolver.h b/include/llvm/CodeGen/PBQP/RegAllocSolver.h
new file mode 100644
index 0000000..977c348
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/RegAllocSolver.h
@@ -0,0 +1,359 @@
+//===-- RegAllocSolver.h - Heuristic PBQP Solver for reg alloc --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Heuristic PBQP solver for register allocation problems. This solver uses a
+// graph reduction approach. Nodes of degree 0, 1 and 2 are eliminated with
+// optimality-preserving rules (see ReductionRules.h). When no low-degree (<3)
+// nodes are present, a heuristic derived from Brigg's graph coloring approach
+// is used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
+#define LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
+
+#include "CostAllocator.h"
+#include "Graph.h"
+#include "ReductionRules.h"
+#include "Solution.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <limits>
+#include <vector>
+
+namespace PBQP {
+
+  namespace RegAlloc {
+
+    /// \brief Metadata to speed allocatability test.
+    ///
+    /// Keeps track of the number of infinities in each row and column.
+    class MatrixMetadata {
+    private:
+      MatrixMetadata(const MatrixMetadata&);
+      void operator=(const MatrixMetadata&);
+    public:
+      MatrixMetadata(const PBQP::Matrix& M)
+        : WorstRow(0), WorstCol(0),
+          UnsafeRows(new bool[M.getRows() - 1]()),
+          UnsafeCols(new bool[M.getCols() - 1]()) {
+
+        unsigned* ColCounts = new unsigned[M.getCols() - 1]();
+
+        for (unsigned i = 1; i < M.getRows(); ++i) {
+          unsigned RowCount = 0;
+          for (unsigned j = 1; j < M.getCols(); ++j) {
+            if (M[i][j] == std::numeric_limits<PBQP::PBQPNum>::infinity()) {
+              ++RowCount;
+              ++ColCounts[j - 1];
+              UnsafeRows[i - 1] = true;
+              UnsafeCols[j - 1] = true;
+            }
+          }
+          WorstRow = std::max(WorstRow, RowCount);
+        }
+        unsigned WorstColCountForCurRow =
+          *std::max_element(ColCounts, ColCounts + M.getCols() - 1);
+        WorstCol = std::max(WorstCol, WorstColCountForCurRow);
+        delete[] ColCounts;
+      }
+
+      ~MatrixMetadata() {
+        delete[] UnsafeRows;
+        delete[] UnsafeCols;
+      }
+
+      unsigned getWorstRow() const { return WorstRow; }
+      unsigned getWorstCol() const { return WorstCol; }
+      const bool* getUnsafeRows() const { return UnsafeRows; }
+      const bool* getUnsafeCols() const { return UnsafeCols; }
+
+    private:
+      unsigned WorstRow, WorstCol;
+      bool* UnsafeRows;
+      bool* UnsafeCols;
+    };
+
+    class NodeMetadata {
+    public:
+      typedef enum { Unprocessed,
+                     OptimallyReducible,
+                     ConservativelyAllocatable,
+                     NotProvablyAllocatable } ReductionState;
+
+      NodeMetadata() : RS(Unprocessed), DeniedOpts(0), OptUnsafeEdges(nullptr){}
+      ~NodeMetadata() { delete[] OptUnsafeEdges; }
+
+      void setup(const Vector& Costs) {
+        NumOpts = Costs.getLength() - 1;
+        OptUnsafeEdges = new unsigned[NumOpts]();
+      }
+
+      ReductionState getReductionState() const { return RS; }
+      void setReductionState(ReductionState RS) { this->RS = RS; }
+
+      void handleAddEdge(const MatrixMetadata& MD, bool Transpose) {
+        DeniedOpts += Transpose ? MD.getWorstCol() : MD.getWorstRow();
+        const bool* UnsafeOpts =
+          Transpose ? MD.getUnsafeCols() : MD.getUnsafeRows();
+        for (unsigned i = 0; i < NumOpts; ++i)
+          OptUnsafeEdges[i] += UnsafeOpts[i];
+      }
+
+      void handleRemoveEdge(const MatrixMetadata& MD, bool Transpose) {
+        DeniedOpts -= Transpose ? MD.getWorstCol() : MD.getWorstRow();
+        const bool* UnsafeOpts =
+          Transpose ? MD.getUnsafeCols() : MD.getUnsafeRows();
+        for (unsigned i = 0; i < NumOpts; ++i)
+          OptUnsafeEdges[i] -= UnsafeOpts[i];
+      }
+
+      bool isConservativelyAllocatable() const {
+        return (DeniedOpts < NumOpts) ||
+               (std::find(OptUnsafeEdges, OptUnsafeEdges + NumOpts, 0) !=
+                  OptUnsafeEdges + NumOpts);
+      }
+
+    private:
+      ReductionState RS;
+      unsigned NumOpts;
+      unsigned DeniedOpts;
+      unsigned* OptUnsafeEdges;
+    };
+
+    class RegAllocSolverImpl {
+    private:
+      typedef PBQP::MDMatrix<MatrixMetadata> RAMatrix;
+    public:
+      typedef PBQP::Vector RawVector;
+      typedef PBQP::Matrix RawMatrix;
+      typedef PBQP::Vector Vector;
+      typedef RAMatrix     Matrix;
+      typedef PBQP::PoolCostAllocator<
+                Vector, PBQP::VectorComparator,
+                Matrix, PBQP::MatrixComparator> CostAllocator;
+
+      typedef PBQP::GraphBase::NodeId NodeId;
+      typedef PBQP::GraphBase::EdgeId EdgeId;
+
+      typedef RegAlloc::NodeMetadata NodeMetadata;
+
+      struct EdgeMetadata { };
+
+      typedef PBQP::Graph<RegAllocSolverImpl> Graph;
+
+      RegAllocSolverImpl(Graph &G) : G(G) {}
+
+      Solution solve() {
+        G.setSolver(*this);
+        Solution S;
+        setup();
+        S = backpropagate(G, reduce());
+        G.unsetSolver();
+        return S;
+      }
+
+      void handleAddNode(NodeId NId) {
+        G.getNodeMetadata(NId).setup(G.getNodeCosts(NId));
+      }
+      void handleRemoveNode(NodeId NId) {}
+      void handleSetNodeCosts(NodeId NId, const Vector& newCosts) {}
+
+      void handleAddEdge(EdgeId EId) {
+        handleReconnectEdge(EId, G.getEdgeNode1Id(EId));
+        handleReconnectEdge(EId, G.getEdgeNode2Id(EId));
+      }
+
+      void handleRemoveEdge(EdgeId EId) {
+        handleDisconnectEdge(EId, G.getEdgeNode1Id(EId));
+        handleDisconnectEdge(EId, G.getEdgeNode2Id(EId));
+      }
+
+      void handleDisconnectEdge(EdgeId EId, NodeId NId) {
+        NodeMetadata& NMd = G.getNodeMetadata(NId);
+        const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+        NMd.handleRemoveEdge(MMd, NId == G.getEdgeNode2Id(EId));
+        if (G.getNodeDegree(NId) == 3) {
+          // This node is becoming optimally reducible.
+          moveToOptimallyReducibleNodes(NId);
+        } else if (NMd.getReductionState() ==
+                     NodeMetadata::NotProvablyAllocatable &&
+                   NMd.isConservativelyAllocatable()) {
+          // This node just became conservatively allocatable.
+          moveToConservativelyAllocatableNodes(NId);
+        }
+      }
+
+      void handleReconnectEdge(EdgeId EId, NodeId NId) {
+        NodeMetadata& NMd = G.getNodeMetadata(NId);
+        const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+        NMd.handleAddEdge(MMd, NId == G.getEdgeNode2Id(EId));
+      }
+
+      void handleSetEdgeCosts(EdgeId EId, const Matrix& NewCosts) {
+        handleRemoveEdge(EId);
+
+        NodeId N1Id = G.getEdgeNode1Id(EId);
+        NodeId N2Id = G.getEdgeNode2Id(EId);
+        NodeMetadata& N1Md = G.getNodeMetadata(N1Id);
+        NodeMetadata& N2Md = G.getNodeMetadata(N2Id);
+        const MatrixMetadata& MMd = NewCosts.getMetadata();
+        N1Md.handleAddEdge(MMd, N1Id != G.getEdgeNode1Id(EId));
+        N2Md.handleAddEdge(MMd, N2Id != G.getEdgeNode1Id(EId));
+      }
+
+    private:
+
+      void removeFromCurrentSet(NodeId NId) {
+        switch (G.getNodeMetadata(NId).getReductionState()) {
+          case NodeMetadata::Unprocessed: break;
+          case NodeMetadata::OptimallyReducible:
+            assert(OptimallyReducibleNodes.find(NId) !=
+                     OptimallyReducibleNodes.end() &&
+                   "Node not in optimally reducible set.");
+            OptimallyReducibleNodes.erase(NId);
+            break;
+          case NodeMetadata::ConservativelyAllocatable:
+            assert(ConservativelyAllocatableNodes.find(NId) !=
+                     ConservativelyAllocatableNodes.end() &&
+                   "Node not in conservatively allocatable set.");
+            ConservativelyAllocatableNodes.erase(NId);
+            break;
+          case NodeMetadata::NotProvablyAllocatable:
+            assert(NotProvablyAllocatableNodes.find(NId) !=
+                     NotProvablyAllocatableNodes.end() &&
+                   "Node not in not-provably-allocatable set.");
+            NotProvablyAllocatableNodes.erase(NId);
+            break;
+        }
+      }
+
+      void moveToOptimallyReducibleNodes(NodeId NId) {
+        removeFromCurrentSet(NId);
+        OptimallyReducibleNodes.insert(NId);
+        G.getNodeMetadata(NId).setReductionState(
+          NodeMetadata::OptimallyReducible);
+      }
+
+      void moveToConservativelyAllocatableNodes(NodeId NId) {
+        removeFromCurrentSet(NId);
+        ConservativelyAllocatableNodes.insert(NId);
+        G.getNodeMetadata(NId).setReductionState(
+          NodeMetadata::ConservativelyAllocatable);
+      }
+
+      void moveToNotProvablyAllocatableNodes(NodeId NId) {
+        removeFromCurrentSet(NId);
+        NotProvablyAllocatableNodes.insert(NId);
+        G.getNodeMetadata(NId).setReductionState(
+          NodeMetadata::NotProvablyAllocatable);
+      }
+
+      void setup() {
+        // Set up worklists.
+        for (auto NId : G.nodeIds()) {
+          if (G.getNodeDegree(NId) < 3)
+            moveToOptimallyReducibleNodes(NId);
+          else if (G.getNodeMetadata(NId).isConservativelyAllocatable())
+            moveToConservativelyAllocatableNodes(NId);
+          else
+            moveToNotProvablyAllocatableNodes(NId);
+        }
+      }
+
+      // Compute a reduction order for the graph by iteratively applying PBQP
+      // reduction rules. Locally optimal rules are applied whenever possible (R0,
+      // R1, R2). If no locally-optimal rules apply then any conservatively
+      // allocatable node is reduced. Finally, if no conservatively allocatable
+      // node exists then the node with the lowest spill-cost:degree ratio is
+      // selected.
+      std::vector<GraphBase::NodeId> reduce() {
+        assert(!G.empty() && "Cannot reduce empty graph.");
+
+        typedef GraphBase::NodeId NodeId;
+        std::vector<NodeId> NodeStack;
+
+        // Consume worklists.
+        while (true) {
+          if (!OptimallyReducibleNodes.empty()) {
+            NodeSet::iterator NItr = OptimallyReducibleNodes.begin();
+            NodeId NId = *NItr;
+            OptimallyReducibleNodes.erase(NItr);
+            NodeStack.push_back(NId);
+            switch (G.getNodeDegree(NId)) {
+              case 0:
+                break;
+              case 1:
+                applyR1(G, NId);
+                break;
+              case 2:
+                applyR2(G, NId);
+                break;
+              default: llvm_unreachable("Not an optimally reducible node.");
+            }
+          } else if (!ConservativelyAllocatableNodes.empty()) {
+            // Conservatively allocatable nodes will never spill. For now just
+            // take the first node in the set and push it on the stack. When we
+            // start optimizing more heavily for register preferencing, it may
+            // would be better to push nodes with lower 'expected' or worst-case
+            // register costs first (since early nodes are the most
+            // constrained).
+            NodeSet::iterator NItr = ConservativelyAllocatableNodes.begin();
+            NodeId NId = *NItr;
+            ConservativelyAllocatableNodes.erase(NItr);
+            NodeStack.push_back(NId);
+            G.disconnectAllNeighborsFromNode(NId);
+
+          } else if (!NotProvablyAllocatableNodes.empty()) {
+            NodeSet::iterator NItr =
+              std::min_element(NotProvablyAllocatableNodes.begin(),
+                               NotProvablyAllocatableNodes.end(),
+                               SpillCostComparator(G));
+            NodeId NId = *NItr;
+            NotProvablyAllocatableNodes.erase(NItr);
+            NodeStack.push_back(NId);
+            G.disconnectAllNeighborsFromNode(NId);
+          } else
+            break;
+        }
+
+        return NodeStack;
+      }
+
+      class SpillCostComparator {
+      public:
+        SpillCostComparator(const Graph& G) : G(G) {}
+        bool operator()(NodeId N1Id, NodeId N2Id) {
+          PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id);
+          PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id);
+          return N1SC < N2SC;
+        }
+      private:
+        const Graph& G;
+      };
+
+      Graph& G;
+      typedef std::set<NodeId> NodeSet;
+      NodeSet OptimallyReducibleNodes;
+      NodeSet ConservativelyAllocatableNodes;
+      NodeSet NotProvablyAllocatableNodes;
+    };
+
+    typedef Graph<RegAllocSolverImpl> Graph;
+
+    inline Solution solve(Graph& G) {
+      if (G.empty())
+        return Solution();
+      RegAllocSolverImpl RegAllocSolver(G);
+      return RegAllocSolver.solve();
+    }
+
+  }
+}
+
+#endif // LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h
new file mode 100644
index 0000000..3556e60
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/Solution.h
@@ -0,0 +1,92 @@
+//===-- Solution.h ------- PBQP Solution ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PBQP Solution class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H
+#define LLVM_CODEGEN_PBQP_SOLUTION_H
+
+#include "Graph.h"
+#include "Math.h"
+#include <map>
+
+namespace PBQP {
+
+  /// \brief Represents a solution to a PBQP problem.
+  ///
+  /// To get the selection for each node in the problem use the getSelection method.
+  class Solution {
+  private:
+
+    typedef std::map<GraphBase::NodeId, unsigned> SelectionsMap;
+    SelectionsMap selections;
+
+    unsigned r0Reductions, r1Reductions, r2Reductions, rNReductions;
+
+  public:
+
+    /// \brief Initialise an empty solution.
+    Solution()
+      : r0Reductions(0), r1Reductions(0), r2Reductions(0), rNReductions(0) {}
+
+    /// \brief Number of nodes for which selections have been made.
+    /// @return Number of nodes for which selections have been made.
+    unsigned numNodes() const { return selections.size(); }
+
+    /// \brief Records a reduction via the R0 rule. Should be called from the
+    ///        solver only.
+    void recordR0() { ++r0Reductions; }
+
+    /// \brief Returns the number of R0 reductions applied to solve the problem.
+    unsigned numR0Reductions() const { return r0Reductions; }
+
+    /// \brief Records a reduction via the R1 rule. Should be called from the
+    ///        solver only.
+    void recordR1() { ++r1Reductions; }
+
+    /// \brief Returns the number of R1 reductions applied to solve the problem.
+    unsigned numR1Reductions() const { return r1Reductions; }
+
+    /// \brief Records a reduction via the R2 rule. Should be called from the
+    ///        solver only.
+    void recordR2() { ++r2Reductions; }
+
+    /// \brief Returns the number of R2 reductions applied to solve the problem.
+    unsigned numR2Reductions() const { return r2Reductions; }
+
+    /// \brief Records a reduction via the RN rule. Should be called from the
+    ///        solver only.
+    void recordRN() { ++ rNReductions; }
+
+    /// \brief Returns the number of RN reductions applied to solve the problem.
+    unsigned numRNReductions() const { return rNReductions; }
+
+    /// \brief Set the selection for a given node.
+    /// @param nodeId Node id.
+    /// @param selection Selection for nodeId.
+    void setSelection(GraphBase::NodeId nodeId, unsigned selection) {
+      selections[nodeId] = selection;
+    }
+
+    /// \brief Get a node's selection.
+    /// @param nodeId Node id.
+    /// @return The selection for nodeId;
+    unsigned getSelection(GraphBase::NodeId nodeId) const {
+      SelectionsMap::const_iterator sItr = selections.find(nodeId);
+      assert(sItr != selections.end() && "No selection for node.");
+      return sItr->second;
+    }
+
+  };
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_SOLUTION_H
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
new file mode 100644
index 0000000..87f55e8
--- /dev/null
+++ b/include/llvm/CodeGen/Passes.h
@@ -0,0 +1,615 @@
+//===-- Passes.h - Target independent code generation passes ----*- 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 interfaces to access the target independent code generation
+// passes provided by the LLVM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PASSES_H
+#define LLVM_CODEGEN_PASSES_H
+
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetMachine.h"
+#include <string>
+
+namespace llvm {
+
+class FunctionPass;
+class MachineFunctionPass;
+class PassConfigImpl;
+class PassInfo;
+class ScheduleDAGInstrs;
+class TargetLowering;
+class TargetLoweringBase;
+class TargetRegisterClass;
+class raw_ostream;
+struct MachineSchedContext;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+}
+using legacy::PassManagerBase;
+
+/// Discriminated union of Pass ID types.
+///
+/// The PassConfig API prefers dealing with IDs because they are safer and more
+/// efficient. IDs decouple configuration from instantiation. This way, when a
+/// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to
+/// refer to a Pass pointer after adding it to a pass manager, which deletes
+/// redundant pass instances.
+///
+/// However, it is convient to directly instantiate target passes with
+/// non-default ctors. These often don't have a registered PassInfo. Rather than
+/// force all target passes to implement the pass registry boilerplate, allow
+/// the PassConfig API to handle either type.
+///
+/// AnalysisID is sadly char*, so PointerIntPair won't work.
+class IdentifyingPassPtr {
+  union {
+    AnalysisID ID;
+    Pass *P;
+  };
+  bool IsInstance;
+public:
+  IdentifyingPassPtr() : P(nullptr), IsInstance(false) {}
+  IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {}
+  IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {}
+
+  bool isValid() const { return P; }
+  bool isInstance() const { return IsInstance; }
+
+  AnalysisID getID() const {
+    assert(!IsInstance && "Not a Pass ID");
+    return ID;
+  }
+  Pass *getInstance() const {
+    assert(IsInstance && "Not a Pass Instance");
+    return P;
+  }
+};
+
+template <> struct isPodLike<IdentifyingPassPtr> {
+  static const bool value = true;
+};
+
+/// Target-Independent Code Generator Pass Configuration Options.
+///
+/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
+/// to the internals of other CodeGen passes.
+class TargetPassConfig : public ImmutablePass {
+public:
+  /// Pseudo Pass IDs. These are defined within TargetPassConfig because they
+  /// are unregistered pass IDs. They are only useful for use with
+  /// TargetPassConfig APIs to identify multiple occurrences of the same pass.
+  ///
+
+  /// EarlyTailDuplicate - A clone of the TailDuplicate pass that runs early
+  /// during codegen, on SSA form.
+  static char EarlyTailDuplicateID;
+
+  /// PostRAMachineLICM - A clone of the LICM pass that runs during late machine
+  /// optimization after regalloc.
+  static char PostRAMachineLICMID;
+
+private:
+  PassManagerBase *PM;
+  AnalysisID StartAfter;
+  AnalysisID StopAfter;
+  bool Started;
+  bool Stopped;
+
+protected:
+  TargetMachine *TM;
+  PassConfigImpl *Impl; // Internal data structures
+  bool Initialized;     // Flagged after all passes are configured.
+
+  // Target Pass Options
+  // Targets provide a default setting, user flags override.
+  //
+  bool DisableVerify;
+
+  /// Default setting for -enable-tail-merge on this target.
+  bool EnableTailMerge;
+
+public:
+  TargetPassConfig(TargetMachine *tm, PassManagerBase &pm);
+  // Dummy constructor.
+  TargetPassConfig();
+
+  virtual ~TargetPassConfig();
+
+  static char ID;
+
+  /// Get the right type of TargetMachine for this target.
+  template<typename TMC> TMC &getTM() const {
+    return *static_cast<TMC*>(TM);
+  }
+
+  //
+  void setInitialized() { Initialized = true; }
+
+  CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
+
+  /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
+  /// running only a portion of the normal code-gen pass sequence.  If the
+  /// Start pass ID is zero, then compilation will begin at the normal point;
+  /// otherwise, clear the Started flag to indicate that passes should not be
+  /// added until the starting pass is seen.  If the Stop pass ID is zero,
+  /// then compilation will continue to the end.
+  void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
+    StartAfter = Start;
+    StopAfter = Stop;
+    Started = (StartAfter == nullptr);
+  }
+
+  void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
+
+  bool getEnableTailMerge() const { return EnableTailMerge; }
+  void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
+
+  /// Allow the target to override a specific pass without overriding the pass
+  /// pipeline. When passes are added to the standard pipeline at the
+  /// point where StandardID is expected, add TargetID in its place.
+  void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID);
+
+  /// Insert InsertedPassID pass after TargetPassID pass.
+  void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID);
+
+  /// Allow the target to enable a specific standard pass by default.
+  void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
+
+  /// Allow the target to disable a specific standard pass by default.
+  void disablePass(AnalysisID PassID) {
+    substitutePass(PassID, IdentifyingPassPtr());
+  }
+
+  /// Return the pass substituted for StandardID by the target.
+  /// If no substitution exists, return StandardID.
+  IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;
+
+  /// Return true if the optimized regalloc pipeline is enabled.
+  bool getOptimizeRegAlloc() const;
+
+  /// Add common target configurable passes that perform LLVM IR to IR
+  /// transforms following machine independent optimization.
+  virtual void addIRPasses();
+
+  /// Add passes to lower exception handling for the code generator.
+  void addPassesToHandleExceptions();
+
+  /// Add pass to prepare the LLVM IR for code generation. This should be done
+  /// before exception handling preparation passes.
+  virtual void addCodeGenPrepare();
+
+  /// Add common passes that perform LLVM IR to IR transforms in preparation for
+  /// instruction selection.
+  virtual void addISelPrepare();
+
+  /// addInstSelector - This method should install an instruction selector pass,
+  /// which converts from LLVM code to machine instructions.
+  virtual bool addInstSelector() {
+    return true;
+  }
+
+  /// Add the complete, standard set of LLVM CodeGen passes.
+  /// Fully developed targets will not generally override this.
+  virtual void addMachinePasses();
+
+  /// Create an instance of ScheduleDAGInstrs to be run within the standard
+  /// MachineScheduler pass for this function and target at the current
+  /// optimization level.
+  ///
+  /// This can also be used to plug a new MachineSchedStrategy into an instance
+  /// of the standard ScheduleDAGMI:
+  ///   return new ScheduleDAGMI(C, new MyStrategy(C))
+  ///
+  /// Return NULL to select the default (generic) machine scheduler.
+  virtual ScheduleDAGInstrs *
+  createMachineScheduler(MachineSchedContext *C) const {
+    return nullptr;
+  }
+
+  /// Similar to createMachineScheduler but used when postRA machine scheduling
+  /// is enabled.
+  virtual ScheduleDAGInstrs *
+  createPostMachineScheduler(MachineSchedContext *C) const {
+    return nullptr;
+  }
+
+protected:
+  // Helper to verify the analysis is really immutable.
+  void setOpt(bool &Opt, bool Val);
+
+  /// Methods with trivial inline returns are convenient points in the common
+  /// codegen pass pipeline where targets may insert passes. Methods with
+  /// out-of-line standard implementations are major CodeGen stages called by
+  /// addMachinePasses. Some targets may override major stages when inserting
+  /// passes is insufficient, but maintaining overriden stages is more work.
+  ///
+
+  /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
+  /// passes (which are run just before instruction selector).
+  virtual bool addPreISel() {
+    return true;
+  }
+
+  /// addMachineSSAOptimization - Add standard passes that optimize machine
+  /// instructions in SSA form.
+  virtual void addMachineSSAOptimization();
+
+  /// Add passes that optimize instruction level parallelism for out-of-order
+  /// targets. These passes are run while the machine code is still in SSA
+  /// form, so they can use MachineTraceMetrics to control their heuristics.
+  ///
+  /// All passes added here should preserve the MachineDominatorTree,
+  /// MachineLoopInfo, and MachineTraceMetrics analyses.
+  virtual bool addILPOpts() {
+    return false;
+  }
+
+  /// addPreRegAlloc - This method may be implemented by targets that want to
+  /// run passes immediately before register allocation. This should return
+  /// true if -print-machineinstrs should print after these passes.
+  virtual bool addPreRegAlloc() {
+    return false;
+  }
+
+  /// createTargetRegisterAllocator - Create the register allocator pass for
+  /// this target at the current optimization level.
+  virtual FunctionPass *createTargetRegisterAllocator(bool Optimized);
+
+  /// addFastRegAlloc - Add the minimum set of target-independent passes that
+  /// are required for fast register allocation.
+  virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
+
+  /// addOptimizedRegAlloc - Add passes related to register allocation.
+  /// LLVMTargetMachine provides standard regalloc passes for most targets.
+  virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
+
+  /// addPreRewrite - Add passes to the optimized register allocation pipeline
+  /// after register allocation is complete, but before virtual registers are
+  /// rewritten to physical registers.
+  ///
+  /// These passes must preserve VirtRegMap and LiveIntervals, and when running
+  /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
+  /// When these passes run, VirtRegMap contains legal physreg assignments for
+  /// all virtual registers.
+  virtual bool addPreRewrite() {
+    return false;
+  }
+
+  /// addPostRegAlloc - This method may be implemented by targets that want to
+  /// run passes after register allocation pass pipeline but before
+  /// prolog-epilog insertion.  This should return true if -print-machineinstrs
+  /// should print after these passes.
+  virtual bool addPostRegAlloc() {
+    return false;
+  }
+
+  /// Add passes that optimize machine instructions after register allocation.
+  virtual void addMachineLateOptimization();
+
+  /// addPreSched2 - This method may be implemented by targets that want to
+  /// run passes after prolog-epilog insertion and before the second instruction
+  /// scheduling pass.  This should return true if -print-machineinstrs should
+  /// print after these passes.
+  virtual bool addPreSched2() {
+    return false;
+  }
+
+  /// addGCPasses - Add late codegen passes that analyze code for garbage
+  /// collection. This should return true if GC info should be printed after
+  /// these passes.
+  virtual bool addGCPasses();
+
+  /// Add standard basic block placement passes.
+  virtual void addBlockPlacement();
+
+  /// addPreEmitPass - This pass may be implemented by targets that want to run
+  /// passes immediately before machine code is emitted.  This should return
+  /// true if -print-machineinstrs should print out the code after the passes.
+  virtual bool addPreEmitPass() {
+    return false;
+  }
+
+  /// Utilities for targets to add passes to the pass manager.
+  ///
+
+  /// Add a CodeGen pass at this point in the pipeline after checking overrides.
+  /// Return the pass that was added, or zero if no pass was added.
+  AnalysisID addPass(AnalysisID PassID);
+
+  /// Add a pass to the PassManager if that pass is supposed to be run, as
+  /// determined by the StartAfter and StopAfter options. Takes ownership of the
+  /// pass.
+  void addPass(Pass *P);
+
+  /// addMachinePasses helper to create the target-selected or overriden
+  /// regalloc pass.
+  FunctionPass *createRegAllocPass(bool Optimized);
+
+  /// printAndVerify - Add a pass to dump then verify the machine function, if
+  /// those steps are enabled.
+  ///
+  void printAndVerify(const char *Banner);
+};
+} // namespace llvm
+
+/// List of target independent CodeGen pass IDs.
+namespace llvm {
+  FunctionPass *createAtomicExpandLoadLinkedPass(const TargetMachine *TM);
+
+  /// \brief Create a basic TargetTransformInfo analysis pass.
+  ///
+  /// This pass implements the target transform info analysis using the target
+  /// independent information available to the LLVM code generator.
+  ImmutablePass *
+  createBasicTargetTransformInfoPass(const TargetMachine *TM);
+
+  /// createUnreachableBlockEliminationPass - The LLVM code generator does not
+  /// work well with unreachable basic blocks (what live ranges make sense for a
+  /// block that cannot be reached?).  As such, a code generator should either
+  /// not instruction select unreachable blocks, or run this pass as its
+  /// last LLVM modifying pass to clean up blocks that are not reachable from
+  /// the entry block.
+  FunctionPass *createUnreachableBlockEliminationPass();
+
+  /// MachineFunctionPrinter pass - This pass prints out the machine function to
+  /// the given stream as a debugging tool.
+  MachineFunctionPass *
+  createMachineFunctionPrinterPass(raw_ostream &OS,
+                                   const std::string &Banner ="");
+
+  /// createCodeGenPreparePass - Transform the code to expose more pattern
+  /// matching during instruction selection.
+  FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
+
+  /// AtomicExpandLoadLinkedID -- FIXME
+  extern char &AtomicExpandLoadLinkedID;
+
+  /// MachineLoopInfo - This pass is a loop analysis pass.
+  extern char &MachineLoopInfoID;
+
+  /// MachineDominators - This pass is a machine dominators analysis pass.
+  extern char &MachineDominatorsID;
+
+/// MachineDominanaceFrontier - This pass is a machine dominators analysis pass.
+  extern char &MachineDominanceFrontierID;
+
+  /// EdgeBundles analysis - Bundle machine CFG edges.
+  extern char &EdgeBundlesID;
+
+  /// LiveVariables pass - This pass computes the set of blocks in which each
+  /// variable is life and sets machine operand kill flags.
+  extern char &LiveVariablesID;
+
+  /// PHIElimination - This pass eliminates machine instruction PHI nodes
+  /// by inserting copy instructions.  This destroys SSA information, but is the
+  /// desired input for some register allocators.  This pass is "required" by
+  /// these register allocator like this: AU.addRequiredID(PHIEliminationID);
+  extern char &PHIEliminationID;
+
+  /// LiveIntervals - This analysis keeps track of the live ranges of virtual
+  /// and physical registers.
+  extern char &LiveIntervalsID;
+
+  /// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
+  extern char &LiveStacksID;
+
+  /// TwoAddressInstruction - This pass reduces two-address instructions to
+  /// use two operands. This destroys SSA information but it is desired by
+  /// register allocators.
+  extern char &TwoAddressInstructionPassID;
+
+  /// ProcessImpicitDefs pass - This pass removes IMPLICIT_DEFs.
+  extern char &ProcessImplicitDefsID;
+
+  /// RegisterCoalescer - This pass merges live ranges to eliminate copies.
+  extern char &RegisterCoalescerID;
+
+  /// MachineScheduler - This pass schedules machine instructions.
+  extern char &MachineSchedulerID;
+
+  /// PostMachineScheduler - This pass schedules machine instructions postRA.
+  extern char &PostMachineSchedulerID;
+
+  /// SpillPlacement analysis. Suggest optimal placement of spill code between
+  /// basic blocks.
+  extern char &SpillPlacementID;
+
+  /// VirtRegRewriter pass. Rewrite virtual registers to physical registers as
+  /// assigned in VirtRegMap.
+  extern char &VirtRegRewriterID;
+
+  /// UnreachableMachineBlockElimination - This pass removes unreachable
+  /// machine basic blocks.
+  extern char &UnreachableMachineBlockElimID;
+
+  /// DeadMachineInstructionElim - This pass removes dead machine instructions.
+  extern char &DeadMachineInstructionElimID;
+
+  /// FastRegisterAllocation Pass - This pass register allocates as fast as
+  /// possible. It is best suited for debug code where live ranges are short.
+  ///
+  FunctionPass *createFastRegisterAllocator();
+
+  /// BasicRegisterAllocation Pass - This pass implements a degenerate global
+  /// register allocator using the basic regalloc framework.
+  ///
+  FunctionPass *createBasicRegisterAllocator();
+
+  /// Greedy register allocation pass - This pass implements a global register
+  /// allocator for optimized builds.
+  ///
+  FunctionPass *createGreedyRegisterAllocator();
+
+  /// PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean
+  /// Quadratic Prograaming (PBQP) based register allocator.
+  ///
+  FunctionPass *createDefaultPBQPRegisterAllocator();
+
+  /// PrologEpilogCodeInserter - This pass inserts prolog and epilog code,
+  /// and eliminates abstract frame references.
+  extern char &PrologEpilogCodeInserterID;
+
+  /// ExpandPostRAPseudos - This pass expands pseudo instructions after
+  /// register allocation.
+  extern char &ExpandPostRAPseudosID;
+
+  /// createPostRAScheduler - This pass performs post register allocation
+  /// scheduling.
+  extern char &PostRASchedulerID;
+
+  /// BranchFolding - This pass performs machine code CFG based
+  /// optimizations to delete branches to branches, eliminate branches to
+  /// successor blocks (creating fall throughs), and eliminating branches over
+  /// branches.
+  extern char &BranchFolderPassID;
+
+  /// MachineFunctionPrinterPass - This pass prints out MachineInstr's.
+  extern char &MachineFunctionPrinterPassID;
+
+  /// TailDuplicate - Duplicate blocks with unconditional branches
+  /// into tails of their predecessors.
+  extern char &TailDuplicateID;
+
+  /// MachineTraceMetrics - This pass computes critical path and CPU resource
+  /// usage in an ensemble of traces.
+  extern char &MachineTraceMetricsID;
+
+  /// EarlyIfConverter - This pass performs if-conversion on SSA form by
+  /// inserting cmov instructions.
+  extern char &EarlyIfConverterID;
+
+  /// StackSlotColoring - This pass performs stack coloring and merging.
+  /// It merges disjoint allocas to reduce the stack size.
+  extern char &StackColoringID;
+
+  /// IfConverter - This pass performs machine code if conversion.
+  extern char &IfConverterID;
+
+  /// MachineBlockPlacement - This pass places basic blocks based on branch
+  /// probabilities.
+  extern char &MachineBlockPlacementID;
+
+  /// MachineBlockPlacementStats - This pass collects statistics about the
+  /// basic block placement using branch probabilities and block frequency
+  /// information.
+  extern char &MachineBlockPlacementStatsID;
+
+  /// GCLowering Pass - Performs target-independent LLVM IR transformations for
+  /// highly portable strategies.
+  ///
+  FunctionPass *createGCLoweringPass();
+
+  /// GCMachineCodeAnalysis - Target-independent pass to mark safe points
+  /// in machine code. Must be added very late during code generation, just
+  /// prior to output, and importantly after all CFG transformations (such as
+  /// branch folding).
+  extern char &GCMachineCodeAnalysisID;
+
+  /// Creates a pass to print GC metadata.
+  ///
+  FunctionPass *createGCInfoPrinter(raw_ostream &OS);
+
+  /// MachineCSE - This pass performs global CSE on machine instructions.
+  extern char &MachineCSEID;
+
+  /// MachineLICM - This pass performs LICM on machine instructions.
+  extern char &MachineLICMID;
+
+  /// MachineSinking - This pass performs sinking on machine instructions.
+  extern char &MachineSinkingID;
+
+  /// MachineCopyPropagation - This pass performs copy propagation on
+  /// machine instructions.
+  extern char &MachineCopyPropagationID;
+
+  /// PeepholeOptimizer - This pass performs peephole optimizations -
+  /// like extension and comparison eliminations.
+  extern char &PeepholeOptimizerID;
+
+  /// OptimizePHIs - This pass optimizes machine instruction PHIs
+  /// to take advantage of opportunities created during DAG legalization.
+  extern char &OptimizePHIsID;
+
+  /// StackSlotColoring - This pass performs stack slot coloring.
+  extern char &StackSlotColoringID;
+
+  /// createStackProtectorPass - This pass adds stack protectors to functions.
+  ///
+  FunctionPass *createStackProtectorPass(const TargetMachine *TM);
+
+  /// createMachineVerifierPass - This pass verifies cenerated machine code
+  /// instructions for correctness.
+  ///
+  FunctionPass *createMachineVerifierPass(const char *Banner = nullptr);
+
+  /// createDwarfEHPass - This pass mulches exception handling code into a form
+  /// adapted to code generation.  Required if using dwarf exception handling.
+  FunctionPass *createDwarfEHPass(const TargetMachine *TM);
+
+  /// createSjLjEHPreparePass - This pass adapts exception handling code to use
+  /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
+  ///
+  FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
+
+  /// LocalStackSlotAllocation - This pass assigns local frame indices to stack
+  /// slots relative to one another and allocates base registers to access them
+  /// when it is estimated by the target to be out of range of normal frame
+  /// pointer or stack pointer index addressing.
+  extern char &LocalStackSlotAllocationID;
+
+  /// ExpandISelPseudos - This pass expands pseudo-instructions.
+  extern char &ExpandISelPseudosID;
+
+  /// createExecutionDependencyFixPass - This pass fixes execution time
+  /// problems with dependent instructions, such as switching execution
+  /// domains to match.
+  ///
+  /// The pass will examine instructions using and defining registers in RC.
+  ///
+  FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
+
+  /// UnpackMachineBundles - This pass unpack machine instruction bundles.
+  extern char &UnpackMachineBundlesID;
+
+  /// FinalizeMachineBundles - This pass finalize machine instruction
+  /// bundles (created earlier, e.g. during pre-RA scheduling).
+  extern char &FinalizeMachineBundlesID;
+
+  /// StackMapLiveness - This pass analyses the register live-out set of
+  /// stackmap/patchpoint intrinsics and attaches the calculated information to
+  /// the intrinsic for later emission to the StackMap.
+  extern char &StackMapLivenessID;
+
+  /// createJumpInstrTables - This pass creates jump-instruction tables.
+  ModulePass *createJumpInstrTablesPass();
+} // End llvm namespace
+
+/// This initializer registers TargetMachine constructor, so the pass being
+/// initialized can use target dependent interfaces. Please do not move this
+/// macro to be together with INITIALIZE_PASS, which is a complete target
+/// independent initializer, and we don't want to make libScalarOpts depend
+/// on libCodeGen.
+#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
+  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \
+      PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \
+    Registry.registerPass(*PI, true); \
+    return PI; \
+  } \
+  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+  }
+
+#endif
diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h
new file mode 100644
index 0000000..cc3e25a
--- /dev/null
+++ b/include/llvm/CodeGen/PseudoSourceValue.h
@@ -0,0 +1,111 @@
+//===-- llvm/CodeGen/PseudoSourceValue.h ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the PseudoSourceValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
+#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
+
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+  class MachineFrameInfo;
+  class MachineMemOperand;
+  class raw_ostream;
+
+  raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MMO);
+
+  /// PseudoSourceValue - Special value supplied for machine level alias
+  /// analysis. It indicates that a memory access references the functions
+  /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument
+  /// space), or constant pool.
+  class PseudoSourceValue {
+  private:
+    friend raw_ostream &llvm::operator<<(raw_ostream &OS,
+                                         const MachineMemOperand &MMO);
+
+    /// printCustom - Implement printing for PseudoSourceValue. This is called
+    /// from Value::print or Value's operator<<.
+    ///
+    virtual void printCustom(raw_ostream &O) const;
+
+  public:
+    /// isFixed - Whether this is a FixedStackPseudoSourceValue.
+    bool isFixed;
+
+    explicit PseudoSourceValue(bool isFixed = false);
+
+    virtual ~PseudoSourceValue();
+
+    /// isConstant - Test whether the memory pointed to by this
+    /// PseudoSourceValue has a constant value.
+    ///
+    virtual bool isConstant(const MachineFrameInfo *) const;
+
+    /// isAliased - Test whether the memory pointed to by this
+    /// PseudoSourceValue may also be pointed to by an LLVM IR Value.
+    virtual bool isAliased(const MachineFrameInfo *) const;
+
+    /// mayAlias - Return true if the memory pointed to by this
+    /// PseudoSourceValue can ever alias an LLVM IR Value.
+    virtual bool mayAlias(const MachineFrameInfo *) const;
+
+    /// A pseudo source value referencing a fixed stack frame entry,
+    /// e.g., a spill slot.
+    static const PseudoSourceValue *getFixedStack(int FI);
+
+    /// A pseudo source value referencing the area below the stack frame of
+    /// a function, e.g., the argument space.
+    static const PseudoSourceValue *getStack();
+
+    /// A pseudo source value referencing the global offset table
+    /// (or something the like).
+    static const PseudoSourceValue *getGOT();
+
+    /// A pseudo source value referencing the constant pool. Since constant
+    /// pools are constant, this doesn't need to identify a specific constant
+    /// pool entry.
+    static const PseudoSourceValue *getConstantPool();
+
+    /// A pseudo source value referencing a jump table. Since jump tables are
+    /// constant, this doesn't need to identify a specific jump table.
+    static const PseudoSourceValue *getJumpTable();
+  };
+
+  /// FixedStackPseudoSourceValue - A specialized PseudoSourceValue
+  /// for holding FixedStack values, which must include a frame
+  /// index.
+  class FixedStackPseudoSourceValue : public PseudoSourceValue {
+    const int FI;
+  public:
+    explicit FixedStackPseudoSourceValue(int fi) :
+        PseudoSourceValue(true), FI(fi) {}
+
+    /// classof - Methods for support type inquiry through isa, cast, and
+    /// dyn_cast:
+    ///
+    static inline bool classof(const PseudoSourceValue *V) {
+      return V->isFixed == true;
+    }
+
+    bool isConstant(const MachineFrameInfo *MFI) const override;
+
+    bool isAliased(const MachineFrameInfo *MFI) const override;
+
+    bool mayAlias(const MachineFrameInfo *) const override;
+
+    void printCustom(raw_ostream &OS) const override;
+
+    int getFrameIndex() const { return FI; }
+  };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
new file mode 100644
index 0000000..441b0f0
--- /dev/null
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -0,0 +1,165 @@
+//===-- RegAllocPBQP.h ------------------------------------------*- 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 PBQPBuilder interface, for classes which build PBQP
+// instances to represent register allocation problems, and the RegAllocPBQP
+// interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGALLOCPBQP_H
+#define LLVM_CODEGEN_REGALLOCPBQP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/PBQP/RegAllocSolver.h"
+#include <map>
+#include <set>
+
+namespace llvm {
+
+  class LiveIntervals;
+  class MachineBlockFrequencyInfo;
+  class MachineFunction;
+  class TargetRegisterInfo;
+
+  typedef PBQP::RegAlloc::Graph PBQPRAGraph;
+
+  /// This class wraps up a PBQP instance representing a register allocation
+  /// problem, plus the structures necessary to map back from the PBQP solution
+  /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map,
+  /// and the PBQP option <--> storage location map).
+  class PBQPRAProblem {
+  public:
+
+    typedef SmallVector<unsigned, 16> AllowedSet;
+
+    PBQPRAGraph& getGraph() { return graph; }
+
+    const PBQPRAGraph& getGraph() const { return graph; }
+
+    /// Record the mapping between the given virtual register and PBQP node,
+    /// and the set of allowed pregs for the vreg.
+    ///
+    /// If you are extending
+    /// PBQPBuilder you are unlikely to need this: Nodes and options for all
+    /// vregs will already have been set up for you by the base class.
+    template <typename AllowedRegsItr>
+    void recordVReg(unsigned vreg, PBQPRAGraph::NodeId nodeId,
+                    AllowedRegsItr arBegin, AllowedRegsItr arEnd) {
+      assert(node2VReg.find(nodeId) == node2VReg.end() && "Re-mapping node.");
+      assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg.");
+      assert(allowedSets[vreg].empty() && "vreg already has pregs.");
+
+      node2VReg[nodeId] = vreg;
+      vreg2Node[vreg] = nodeId;
+      std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg]));
+    }
+
+    /// Get the virtual register corresponding to the given PBQP node.
+    unsigned getVRegForNode(PBQPRAGraph::NodeId nodeId) const;
+
+    /// Get the PBQP node corresponding to the given virtual register.
+    PBQPRAGraph::NodeId getNodeForVReg(unsigned vreg) const;
+
+    /// Returns true if the given PBQP option represents a physical register,
+    /// false otherwise.
+    bool isPRegOption(unsigned vreg, unsigned option) const {
+      // At present we only have spills or pregs, so anything that's not a
+      // spill is a preg. (This might be extended one day to support remat).
+      return !isSpillOption(vreg, option);
+    }
+
+    /// Returns true if the given PBQP option represents spilling, false
+    /// otherwise.
+    bool isSpillOption(unsigned vreg, unsigned option) const {
+      // We hardcode option zero as the spill option.
+      return option == 0;
+    }
+
+    /// Returns the allowed set for the given virtual register.
+    const AllowedSet& getAllowedSet(unsigned vreg) const;
+
+    /// Get PReg for option.
+    unsigned getPRegForOption(unsigned vreg, unsigned option) const;
+
+  private:
+
+    typedef std::map<PBQPRAGraph::NodeId, unsigned>  Node2VReg;
+    typedef DenseMap<unsigned, PBQPRAGraph::NodeId> VReg2Node;
+    typedef DenseMap<unsigned, AllowedSet> AllowedSetMap;
+
+    PBQPRAGraph graph;
+    Node2VReg node2VReg;
+    VReg2Node vreg2Node;
+
+    AllowedSetMap allowedSets;
+
+  };
+
+  /// Builds PBQP instances to represent register allocation problems. Includes
+  /// spill, interference and coalescing costs by default. You can extend this
+  /// class to support additional constraints for your architecture.
+  class PBQPBuilder {
+  private:
+    PBQPBuilder(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
+    void operator=(const PBQPBuilder&) LLVM_DELETED_FUNCTION;
+  public:
+
+    typedef std::set<unsigned> RegSet;
+
+    /// Default constructor.
+    PBQPBuilder() {}
+
+    /// Clean up a PBQPBuilder.
+    virtual ~PBQPBuilder() {}
+
+    /// Build a PBQP instance to represent the register allocation problem for
+    /// the given MachineFunction.
+    virtual PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
+                                 const MachineBlockFrequencyInfo *mbfi,
+                                 const RegSet &vregs);
+  private:
+
+    void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost);
+
+    void addInterferenceCosts(PBQP::Matrix &costMat,
+                              const PBQPRAProblem::AllowedSet &vr1Allowed,
+                              const PBQPRAProblem::AllowedSet &vr2Allowed,
+                              const TargetRegisterInfo *tri);
+  };
+
+  /// Extended builder which adds coalescing constraints to a problem.
+  class PBQPBuilderWithCoalescing : public PBQPBuilder {
+  public:
+
+    /// Build a PBQP instance to represent the register allocation problem for
+    /// the given MachineFunction.
+    PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
+                         const MachineBlockFrequencyInfo *mbfi,
+                         const RegSet &vregs) override;
+
+  private:
+
+    void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption,
+                            PBQP::PBQPNum benefit);
+
+    void addVirtRegCoalesce(PBQP::Matrix &costMat,
+                            const PBQPRAProblem::AllowedSet &vr1Allowed,
+                            const PBQPRAProblem::AllowedSet &vr2Allowed,
+                            PBQP::PBQPNum benefit);
+  };
+
+  FunctionPass *
+  createPBQPRegisterAllocator(std::unique_ptr<PBQPBuilder> builder,
+                              char *customPassID = nullptr);
+}
+
+#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */
diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h
new file mode 100644
index 0000000..ca49577
--- /dev/null
+++ b/include/llvm/CodeGen/RegAllocRegistry.h
@@ -0,0 +1,66 @@
+//===-- llvm/CodeGen/RegAllocRegistry.h -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for register allocator function
+// pass registry (RegisterRegAlloc).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGALLOCREGISTRY_H
+#define LLVM_CODEGEN_REGALLOCREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterRegAlloc class - Track the registration of register allocators.
+///
+//===----------------------------------------------------------------------===//
+class RegisterRegAlloc : public MachinePassRegistryNode {
+
+public:
+
+  typedef FunctionPass *(*FunctionPassCtor)();
+
+  static MachinePassRegistry Registry;
+
+  RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+  : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+  { 
+     Registry.Add(this); 
+  }
+  ~RegisterRegAlloc() { Registry.Remove(this); }
+  
+
+  // Accessors.
+  //
+  RegisterRegAlloc *getNext() const {
+    return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
+  }
+  static RegisterRegAlloc *getList() {
+    return (RegisterRegAlloc *)Registry.getList();
+  }
+  static FunctionPassCtor getDefault() {
+    return (FunctionPassCtor)Registry.getDefault();
+  }
+  static void setDefault(FunctionPassCtor C) {
+    Registry.setDefault((MachinePassCtor)C);
+  }
+  static void setListener(MachinePassRegistryListener *L) {
+    Registry.setListener(L);
+  }
+  
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
new file mode 100644
index 0000000..d784dfb
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -0,0 +1,145 @@
+//===-- RegisterClassInfo.h - Dynamic Register Class 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 implements the RegisterClassInfo class which provides dynamic
+// information about target register classes. Callee saved and reserved
+// registers depends on calling conventions and other dynamic information, so
+// some things cannot be determined statically.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTERCLASSINFO_H
+#define LLVM_CODEGEN_REGISTERCLASSINFO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+
+class RegisterClassInfo {
+  struct RCInfo {
+    unsigned Tag;
+    unsigned NumRegs;
+    bool ProperSubClass;
+    uint8_t MinCost;
+    uint16_t LastCostChange;
+    std::unique_ptr<MCPhysReg[]> Order;
+
+    RCInfo()
+      : Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0),
+        LastCostChange(0) {}
+
+    operator ArrayRef<MCPhysReg>() const {
+      return makeArrayRef(Order.get(), NumRegs);
+    }
+  };
+
+  // Brief cached information for each register class.
+  std::unique_ptr<RCInfo[]> RegClass;
+
+  // Tag changes whenever cached information needs to be recomputed. An RCInfo
+  // entry is valid when its tag matches.
+  unsigned Tag;
+
+  const MachineFunction *MF;
+  const TargetRegisterInfo *TRI;
+
+  // Callee saved registers of last MF. Assumed to be valid until the next
+  // runOnFunction() call.
+  const MCPhysReg *CalleeSaved;
+
+  // Map register number to CalleeSaved index + 1;
+  SmallVector<uint8_t, 4> CSRNum;
+
+  // Reserved registers in the current MF.
+  BitVector Reserved;
+
+  std::unique_ptr<unsigned[]> PSetLimits;
+
+  // Compute all information about RC.
+  void compute(const TargetRegisterClass *RC) const;
+
+  // Return an up-to-date RCInfo for RC.
+  const RCInfo &get(const TargetRegisterClass *RC) const {
+    const RCInfo &RCI = RegClass[RC->getID()];
+    if (Tag != RCI.Tag)
+      compute(RC);
+    return RCI;
+  }
+
+public:
+  RegisterClassInfo();
+
+  /// runOnFunction - Prepare to answer questions about MF. This must be called
+  /// before any other methods are used.
+  void runOnMachineFunction(const MachineFunction &MF);
+
+  /// getNumAllocatableRegs - Returns the number of actually allocatable
+  /// registers in RC in the current function.
+  unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const {
+    return get(RC).NumRegs;
+  }
+
+  /// getOrder - Returns the preferred allocation order for RC. The order
+  /// contains no reserved registers, and registers that alias callee saved
+  /// registers come last.
+  ArrayRef<MCPhysReg> getOrder(const TargetRegisterClass *RC) const {
+    return get(RC);
+  }
+
+  /// isProperSubClass - Returns true if RC has a legal super-class with more
+  /// allocatable registers.
+  ///
+  /// Register classes like GR32_NOSP are not proper sub-classes because %esp
+  /// is not allocatable.  Similarly, tGPR is not a proper sub-class in Thumb
+  /// mode because the GPR super-class is not legal.
+  bool isProperSubClass(const TargetRegisterClass *RC) const {
+    return get(RC).ProperSubClass;
+  }
+
+  /// getLastCalleeSavedAlias - Returns the last callee saved register that
+  /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR.
+  unsigned getLastCalleeSavedAlias(unsigned PhysReg) const {
+    assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
+    if (unsigned N = CSRNum[PhysReg])
+      return CalleeSaved[N-1];
+    return 0;
+  }
+
+  /// Get the minimum register cost in RC's allocation order.
+  /// This is the smallest value returned by TRI->getCostPerUse(Reg) for all
+  /// the registers in getOrder(RC).
+  unsigned getMinCost(const TargetRegisterClass *RC) {
+    return get(RC).MinCost;
+  }
+
+  /// Get the position of the last cost change in getOrder(RC).
+  ///
+  /// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have the
+  /// same cost according to TRI->getCostPerUse().
+  unsigned getLastCostChange(const TargetRegisterClass *RC) {
+    return get(RC).LastCostChange;
+  }
+
+  /// Get the register unit limit for the given pressure set index.
+  ///
+  /// RegisterClassInfo adjusts this limit for reserved registers.
+  unsigned getRegPressureSetLimit(unsigned Idx) const {
+    if (!PSetLimits[Idx])
+      PSetLimits[Idx] = computePSetLimit(Idx);
+    return PSetLimits[Idx];
+  }
+
+protected:
+  unsigned computePSetLimit(unsigned Idx) const;
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h
new file mode 100644
index 0000000..cc9e000
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterPressure.h
@@ -0,0 +1,441 @@
+//===-- RegisterPressure.h - Dynamic Register Pressure -*- 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 RegisterPressure class which can be used to track
+// MachineInstr level register pressure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
+#define LLVM_CODEGEN_REGISTERPRESSURE_H
+
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+
+class LiveIntervals;
+class LiveRange;
+class RegisterClassInfo;
+class MachineInstr;
+
+/// Base class for register pressure results.
+struct RegisterPressure {
+  /// Map of max reg pressure indexed by pressure set ID, not class ID.
+  std::vector<unsigned> MaxSetPressure;
+
+  /// List of live in virtual registers or physical register units.
+  SmallVector<unsigned,8> LiveInRegs;
+  SmallVector<unsigned,8> LiveOutRegs;
+
+  /// Increase register pressure for each pressure set impacted by this register
+  /// class. Normally called by RegPressureTracker, but may be called manually
+  /// to account for live through (global liveness).
+  ///
+  /// \param Reg is either a virtual register number or register unit number.
+  void increase(unsigned Reg, const TargetRegisterInfo *TRI,
+                const MachineRegisterInfo *MRI);
+
+  /// Decrease register pressure for each pressure set impacted by this register
+  /// class. This is only useful to account for spilling or rematerialization.
+  ///
+  /// \param Reg is either a virtual register number or register unit number.
+  void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
+                const MachineRegisterInfo *MRI);
+
+  void dump(const TargetRegisterInfo *TRI) const;
+};
+
+/// RegisterPressure computed within a region of instructions delimited by
+/// TopIdx and BottomIdx.  During pressure computation, the maximum pressure per
+/// register pressure set is increased. Once pressure within a region is fully
+/// computed, the live-in and live-out sets are recorded.
+///
+/// This is preferable to RegionPressure when LiveIntervals are available,
+/// because delimiting regions by SlotIndex is more robust and convenient than
+/// holding block iterators. The block contents can change without invalidating
+/// the pressure result.
+struct IntervalPressure : RegisterPressure {
+  /// Record the boundary of the region being tracked.
+  SlotIndex TopIdx;
+  SlotIndex BottomIdx;
+
+  void reset();
+
+  void openTop(SlotIndex NextTop);
+
+  void openBottom(SlotIndex PrevBottom);
+};
+
+/// RegisterPressure computed within a region of instructions delimited by
+/// TopPos and BottomPos. This is a less precise version of IntervalPressure for
+/// use when LiveIntervals are unavailable.
+struct RegionPressure : RegisterPressure {
+  /// Record the boundary of the region being tracked.
+  MachineBasicBlock::const_iterator TopPos;
+  MachineBasicBlock::const_iterator BottomPos;
+
+  void reset();
+
+  void openTop(MachineBasicBlock::const_iterator PrevTop);
+
+  void openBottom(MachineBasicBlock::const_iterator PrevBottom);
+};
+
+/// Capture a change in pressure for a single pressure set. UnitInc may be
+/// expressed in terms of upward or downward pressure depending on the client
+/// and will be dynamically adjusted for current liveness.
+///
+/// Pressure increments are tiny, typically 1-2 units, and this is only for
+/// heuristics, so we don't check UnitInc overflow. Instead, we may have a
+/// higher level assert that pressure is consistent within a region. We also
+/// effectively ignore dead defs which don't affect heuristics much.
+class PressureChange {
+  uint16_t PSetID; // ID+1. 0=Invalid.
+  int16_t  UnitInc;
+public:
+  PressureChange(): PSetID(0), UnitInc(0) {}
+  PressureChange(unsigned id): PSetID(id+1), UnitInc(0) {
+    assert(id < UINT16_MAX && "PSetID overflow.");
+  }
+
+  bool isValid() const { return PSetID > 0; }
+
+  unsigned getPSet() const {
+    assert(isValid() && "invalid PressureChange");
+    return PSetID - 1;
+  }
+  // If PSetID is invalid, return UINT16_MAX to give it lowest priority.
+  unsigned getPSetOrMax() const { return (PSetID - 1) & UINT16_MAX; }
+
+  int getUnitInc() const { return UnitInc; }
+
+  void setUnitInc(int Inc) { UnitInc = Inc; }
+
+  bool operator==(const PressureChange &RHS) const {
+    return PSetID == RHS.PSetID && UnitInc == RHS.UnitInc;
+  }
+};
+
+template <> struct isPodLike<PressureChange> {
+   static const bool value = true;
+};
+
+/// List of PressureChanges in order of increasing, unique PSetID.
+///
+/// Use a small fixed number, because we can fit more PressureChanges in an
+/// empty SmallVector than ever need to be tracked per register class. If more
+/// PSets are affected, then we only track the most constrained.
+class PressureDiff {
+  // The initial design was for MaxPSets=4, but that requires PSet partitions,
+  // which are not yet implemented. (PSet partitions are equivalent PSets given
+  // the register classes actually in use within the scheduling region.)
+  enum { MaxPSets = 16 };
+
+  PressureChange PressureChanges[MaxPSets];
+public:
+  typedef PressureChange* iterator;
+  typedef const PressureChange* const_iterator;
+  iterator begin() { return &PressureChanges[0]; }
+  iterator end() { return &PressureChanges[MaxPSets]; }
+  const_iterator begin() const { return &PressureChanges[0]; }
+  const_iterator end() const { return &PressureChanges[MaxPSets]; }
+
+  void addPressureChange(unsigned RegUnit, bool IsDec,
+                         const MachineRegisterInfo *MRI);
+};
+
+/// Array of PressureDiffs.
+class PressureDiffs {
+  PressureDiff *PDiffArray;
+  unsigned Size;
+  unsigned Max;
+public:
+  PressureDiffs(): PDiffArray(nullptr), Size(0), Max(0) {}
+  ~PressureDiffs() { free(PDiffArray); }
+
+  void clear() { Size = 0; }
+
+  void init(unsigned N);
+
+  PressureDiff &operator[](unsigned Idx) {
+    assert(Idx < Size && "PressureDiff index out of bounds");
+    return PDiffArray[Idx];
+  }
+  const PressureDiff &operator[](unsigned Idx) const {
+    return const_cast<PressureDiffs*>(this)->operator[](Idx);
+  }
+};
+
+/// Store the effects of a change in pressure on things that MI scheduler cares
+/// about.
+///
+/// Excess records the value of the largest difference in register units beyond
+/// the target's pressure limits across the affected pressure sets, where
+/// largest is defined as the absolute value of the difference. Negative
+/// ExcessUnits indicates a reduction in pressure that had already exceeded the
+/// target's limits.
+///
+/// CriticalMax records the largest increase in the tracker's max pressure that
+/// exceeds the critical limit for some pressure set determined by the client.
+///
+/// CurrentMax records the largest increase in the tracker's max pressure that
+/// exceeds the current limit for some pressure set determined by the client.
+struct RegPressureDelta {
+  PressureChange Excess;
+  PressureChange CriticalMax;
+  PressureChange CurrentMax;
+
+  RegPressureDelta() {}
+
+  bool operator==(const RegPressureDelta &RHS) const {
+    return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax
+      && CurrentMax == RHS.CurrentMax;
+  }
+  bool operator!=(const RegPressureDelta &RHS) const {
+    return !operator==(RHS);
+  }
+};
+
+/// \brief A set of live virtual registers and physical register units.
+///
+/// Virtual and physical register numbers require separate sparse sets, but most
+/// of the RegisterPressureTracker handles them uniformly.
+struct LiveRegSet {
+  SparseSet<unsigned> PhysRegs;
+  SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs;
+
+  bool contains(unsigned Reg) const {
+    if (TargetRegisterInfo::isVirtualRegister(Reg))
+      return VirtRegs.count(Reg);
+    return PhysRegs.count(Reg);
+  }
+
+  bool insert(unsigned Reg) {
+    if (TargetRegisterInfo::isVirtualRegister(Reg))
+      return VirtRegs.insert(Reg).second;
+    return PhysRegs.insert(Reg).second;
+  }
+
+  bool erase(unsigned Reg) {
+    if (TargetRegisterInfo::isVirtualRegister(Reg))
+      return VirtRegs.erase(Reg);
+    return PhysRegs.erase(Reg);
+  }
+};
+
+/// Track the current register pressure at some position in the instruction
+/// stream, and remember the high water mark within the region traversed. This
+/// does not automatically consider live-through ranges. The client may
+/// independently adjust for global liveness.
+///
+/// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
+/// be tracked across a larger region by storing a RegisterPressure result at
+/// each block boundary and explicitly adjusting pressure to account for block
+/// live-in and live-out register sets.
+///
+/// RegPressureTracker holds a reference to a RegisterPressure result that it
+/// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
+/// is invalid until it reaches the end of the block or closeRegion() is
+/// explicitly called. Similarly, P.TopIdx is invalid during upward
+/// tracking. Changing direction has the side effect of closing region, and
+/// traversing past TopIdx or BottomIdx reopens it.
+class RegPressureTracker {
+  const MachineFunction     *MF;
+  const TargetRegisterInfo  *TRI;
+  const RegisterClassInfo   *RCI;
+  const MachineRegisterInfo *MRI;
+  const LiveIntervals       *LIS;
+
+  /// We currently only allow pressure tracking within a block.
+  const MachineBasicBlock *MBB;
+
+  /// Track the max pressure within the region traversed so far.
+  RegisterPressure &P;
+
+  /// Run in two modes dependending on whether constructed with IntervalPressure
+  /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
+  bool RequireIntervals;
+
+  /// True if UntiedDefs will be populated.
+  bool TrackUntiedDefs;
+
+  /// Register pressure corresponds to liveness before this instruction
+  /// iterator. It may point to the end of the block or a DebugValue rather than
+  /// an instruction.
+  MachineBasicBlock::const_iterator CurrPos;
+
+  /// Pressure map indexed by pressure set ID, not class ID.
+  std::vector<unsigned> CurrSetPressure;
+
+  /// Set of live registers.
+  LiveRegSet LiveRegs;
+
+  /// Set of vreg defs that start a live range.
+  SparseSet<unsigned, VirtReg2IndexFunctor> UntiedDefs;
+  /// Live-through pressure.
+  std::vector<unsigned> LiveThruPressure;
+
+public:
+  RegPressureTracker(IntervalPressure &rp) :
+    MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
+    RequireIntervals(true), TrackUntiedDefs(false) {}
+
+  RegPressureTracker(RegionPressure &rp) :
+    MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
+    RequireIntervals(false), TrackUntiedDefs(false) {}
+
+  void reset();
+
+  void init(const MachineFunction *mf, const RegisterClassInfo *rci,
+            const LiveIntervals *lis, const MachineBasicBlock *mbb,
+            MachineBasicBlock::const_iterator pos,
+            bool ShouldTrackUntiedDefs = false);
+
+  /// Force liveness of virtual registers or physical register
+  /// units. Particularly useful to initialize the livein/out state of the
+  /// tracker before the first call to advance/recede.
+  void addLiveRegs(ArrayRef<unsigned> Regs);
+
+  /// Get the MI position corresponding to this register pressure.
+  MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
+
+  // Reset the MI position corresponding to the register pressure. This allows
+  // schedulers to move instructions above the RegPressureTracker's
+  // CurrPos. Since the pressure is computed before CurrPos, the iterator
+  // position changes while pressure does not.
+  void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
+
+  /// \brief Get the SlotIndex for the first nondebug instruction including or
+  /// after the current position.
+  SlotIndex getCurrSlot() const;
+
+  /// Recede across the previous instruction.
+  bool recede(SmallVectorImpl<unsigned> *LiveUses = nullptr,
+              PressureDiff *PDiff = nullptr);
+
+  /// Advance across the current instruction.
+  bool advance();
+
+  /// Finalize the region boundaries and recored live ins and live outs.
+  void closeRegion();
+
+  /// Initialize the LiveThru pressure set based on the untied defs found in
+  /// RPTracker.
+  void initLiveThru(const RegPressureTracker &RPTracker);
+
+  /// Copy an existing live thru pressure result.
+  void initLiveThru(ArrayRef<unsigned> PressureSet) {
+    LiveThruPressure.assign(PressureSet.begin(), PressureSet.end());
+  }
+
+  ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
+
+  /// Get the resulting register pressure over the traversed region.
+  /// This result is complete if either advance() or recede() has returned true,
+  /// or if closeRegion() was explicitly invoked.
+  RegisterPressure &getPressure() { return P; }
+  const RegisterPressure &getPressure() const { return P; }
+
+  /// Get the register set pressure at the current position, which may be less
+  /// than the pressure across the traversed region.
+  std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
+
+  void discoverLiveOut(unsigned Reg);
+  void discoverLiveIn(unsigned Reg);
+
+  bool isTopClosed() const;
+  bool isBottomClosed() const;
+
+  void closeTop();
+  void closeBottom();
+
+  /// Consider the pressure increase caused by traversing this instruction
+  /// bottom-up. Find the pressure set with the most change beyond its pressure
+  /// limit based on the tracker's current pressure, and record the number of
+  /// excess register units of that pressure set introduced by this instruction.
+  void getMaxUpwardPressureDelta(const MachineInstr *MI,
+                                 PressureDiff *PDiff,
+                                 RegPressureDelta &Delta,
+                                 ArrayRef<PressureChange> CriticalPSets,
+                                 ArrayRef<unsigned> MaxPressureLimit);
+
+  void getUpwardPressureDelta(const MachineInstr *MI,
+                              /*const*/ PressureDiff &PDiff,
+                              RegPressureDelta &Delta,
+                              ArrayRef<PressureChange> CriticalPSets,
+                              ArrayRef<unsigned> MaxPressureLimit) const;
+
+  /// Consider the pressure increase caused by traversing this instruction
+  /// top-down. Find the pressure set with the most change beyond its pressure
+  /// limit based on the tracker's current pressure, and record the number of
+  /// excess register units of that pressure set introduced by this instruction.
+  void getMaxDownwardPressureDelta(const MachineInstr *MI,
+                                   RegPressureDelta &Delta,
+                                   ArrayRef<PressureChange> CriticalPSets,
+                                   ArrayRef<unsigned> MaxPressureLimit);
+
+  /// Find the pressure set with the most change beyond its pressure limit after
+  /// traversing this instruction either upward or downward depending on the
+  /// closed end of the current region.
+  void getMaxPressureDelta(const MachineInstr *MI,
+                           RegPressureDelta &Delta,
+                           ArrayRef<PressureChange> CriticalPSets,
+                           ArrayRef<unsigned> MaxPressureLimit) {
+    if (isTopClosed())
+      return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
+                                         MaxPressureLimit);
+
+    assert(isBottomClosed() && "Uninitialized pressure tracker");
+    return getMaxUpwardPressureDelta(MI, nullptr, Delta, CriticalPSets,
+                                     MaxPressureLimit);
+  }
+
+  /// Get the pressure of each PSet after traversing this instruction bottom-up.
+  void getUpwardPressure(const MachineInstr *MI,
+                         std::vector<unsigned> &PressureResult,
+                         std::vector<unsigned> &MaxPressureResult);
+
+  /// Get the pressure of each PSet after traversing this instruction top-down.
+  void getDownwardPressure(const MachineInstr *MI,
+                           std::vector<unsigned> &PressureResult,
+                           std::vector<unsigned> &MaxPressureResult);
+
+  void getPressureAfterInst(const MachineInstr *MI,
+                            std::vector<unsigned> &PressureResult,
+                            std::vector<unsigned> &MaxPressureResult) {
+    if (isTopClosed())
+      return getUpwardPressure(MI, PressureResult, MaxPressureResult);
+
+    assert(isBottomClosed() && "Uninitialized pressure tracker");
+    return getDownwardPressure(MI, PressureResult, MaxPressureResult);
+  }
+
+  bool hasUntiedDef(unsigned VirtReg) const {
+    return UntiedDefs.count(VirtReg);
+  }
+
+  void dump() const;
+
+protected:
+  const LiveRange *getLiveRange(unsigned Reg) const;
+
+  void increaseRegPressure(ArrayRef<unsigned> Regs);
+  void decreaseRegPressure(ArrayRef<unsigned> Regs);
+
+  void bumpUpwardPressure(const MachineInstr *MI);
+  void bumpDownwardPressure(const MachineInstr *MI);
+};
+
+void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
+                        const TargetRegisterInfo *TRI);
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
new file mode 100644
index 0000000..335dd7f
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -0,0 +1,208 @@
+//===-- RegisterScavenging.h - Machine register scavenging ------*- 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 machine register scavenger class. It can provide
+// information such as unused register at any point in a machine basic block.
+// It also provides a mechanism to make registers availbale by evicting them
+// to spill slots.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H
+#define LLVM_CODEGEN_REGISTERSCAVENGING_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+
+namespace llvm {
+
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterClass;
+
+class RegScavenger {
+  const TargetRegisterInfo *TRI;
+  const TargetInstrInfo *TII;
+  MachineRegisterInfo* MRI;
+  MachineBasicBlock *MBB;
+  MachineBasicBlock::iterator MBBI;
+  unsigned NumPhysRegs;
+
+  /// Tracking - True if RegScavenger is currently tracking the liveness of 
+  /// registers.
+  bool Tracking;
+
+  /// Information on scavenged registers (held in a spill slot).
+  struct ScavengedInfo {
+    ScavengedInfo(int FI = -1) : FrameIndex(FI), Reg(0), Restore(nullptr) {}
+
+    /// A spill slot used for scavenging a register post register allocation.
+    int FrameIndex;
+
+    /// If non-zero, the specific register is currently being
+    /// scavenged. That is, it is spilled to this scavenging stack slot.
+    unsigned Reg;
+
+    /// The instruction that restores the scavenged register from stack.
+    const MachineInstr *Restore;
+  };
+
+  /// A vector of information on scavenged registers.
+  SmallVector<ScavengedInfo, 2> Scavenged;
+
+  /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+  ///
+  BitVector CalleeSavedRegs;
+
+  /// RegsAvailable - The current state of all the physical registers immediately
+  /// before MBBI. One bit per physical register. If bit is set that means it's
+  /// available, unset means the register is currently being used.
+  BitVector RegsAvailable;
+
+  // These BitVectors are only used internally to forward(). They are members
+  // to avoid frequent reallocations.
+  BitVector KillRegs, DefRegs;
+
+public:
+  RegScavenger()
+    : MBB(nullptr), NumPhysRegs(0), Tracking(false) {}
+
+  /// enterBasicBlock - Start tracking liveness from the begin of the specific
+  /// basic block.
+  void enterBasicBlock(MachineBasicBlock *mbb);
+
+  /// initRegState - allow resetting register state info for multiple
+  /// passes over/within the same function.
+  void initRegState();
+
+  /// forward - Move the internal MBB iterator and update register states.
+  void forward();
+
+  /// forward - Move the internal MBB iterator and update register states until
+  /// it has processed the specific iterator.
+  void forward(MachineBasicBlock::iterator I) {
+    if (!Tracking && MBB->begin() != I) forward();
+    while (MBBI != I) forward();
+  }
+
+  /// Invert the behavior of forward() on the current instruction (undo the
+  /// changes to the available registers made by forward()).
+  void unprocess();
+
+  /// Unprocess instructions until you reach the provided iterator.
+  void unprocess(MachineBasicBlock::iterator I) {
+    while (MBBI != I) unprocess();
+  }
+
+  /// skipTo - Move the internal MBB iterator but do not update register states.
+  void skipTo(MachineBasicBlock::iterator I) {
+    if (I == MachineBasicBlock::iterator(nullptr))
+      Tracking = false;
+    MBBI = I;
+  }
+
+  MachineBasicBlock::iterator getCurrentPosition() const {
+    return MBBI;
+  }
+
+  /// getRegsUsed - return all registers currently in use in used.
+  void getRegsUsed(BitVector &used, bool includeReserved);
+
+  /// getRegsAvailable - Return all available registers in the register class
+  /// in Mask.
+  BitVector getRegsAvailable(const TargetRegisterClass *RC);
+
+  /// FindUnusedReg - Find a unused register of the specified register class.
+  /// Return 0 if none is found.
+  unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
+
+  /// Add a scavenging frame index.
+  void addScavengingFrameIndex(int FI) {
+    Scavenged.push_back(ScavengedInfo(FI));
+  }
+
+  /// Query whether a frame index is a scavenging frame index.
+  bool isScavengingFrameIndex(int FI) const {
+    for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(),
+         IE = Scavenged.end(); I != IE; ++I)
+      if (I->FrameIndex == FI)
+        return true;
+
+    return false;
+  }
+
+  /// Get an array of scavenging frame indices.
+  void getScavengingFrameIndices(SmallVectorImpl<int> &A) const {
+    for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(),
+         IE = Scavenged.end(); I != IE; ++I)
+      if (I->FrameIndex >= 0)
+        A.push_back(I->FrameIndex);
+  }
+
+  /// scavengeRegister - Make a register of the specific register class
+  /// available and do the appropriate bookkeeping. SPAdj is the stack
+  /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
+  /// Returns the scavenged register.
+  unsigned scavengeRegister(const TargetRegisterClass *RegClass,
+                            MachineBasicBlock::iterator I, int SPAdj);
+  unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
+    return scavengeRegister(RegClass, MBBI, SPAdj);
+  }
+
+  /// setUsed - Tell the scavenger a register is used.
+  ///
+  void setUsed(unsigned Reg);
+private:
+  /// isReserved - Returns true if a register is reserved. It is never "unused".
+  bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
+
+  /// isUsed - Test if a register is currently being used.  When called by the
+  /// isAliasUsed function, we only check isReserved if this is the original
+  /// register, not an alias register.
+  ///
+  bool isUsed(unsigned Reg, bool CheckReserved = true) const   {
+    return !RegsAvailable.test(Reg) || (CheckReserved && isReserved(Reg));
+  }
+
+  /// isAliasUsed - Is Reg or an alias currently in use?
+  bool isAliasUsed(unsigned Reg) const;
+
+  /// setUsed / setUnused - Mark the state of one or a number of registers.
+  ///
+  void setUsed(BitVector &Regs) {
+    RegsAvailable.reset(Regs);
+  }
+  void setUnused(BitVector &Regs) {
+    RegsAvailable |= Regs;
+  }
+
+  /// Processes the current instruction and fill the KillRegs and DefRegs bit
+  /// vectors.
+  void determineKillsAndDefs();
+
+  /// Add Reg and all its sub-registers to BV.
+  void addRegWithSubRegs(BitVector &BV, unsigned Reg);
+
+  /// findSurvivorReg - Return the candidate register that is unused for the
+  /// longest after StartMI. UseMI is set to the instruction where the search
+  /// stopped.
+  ///
+  /// No more than InstrLimit instructions are inspected.
+  unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI,
+                           BitVector &Candidates,
+                           unsigned InstrLimit,
+                           MachineBasicBlock::iterator &UseMI);
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
new file mode 100644
index 0000000..114fe7c
--- /dev/null
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -0,0 +1,142 @@
+//===----- ResourcePriorityQueue.h - A DFA-oriented priority queue -------===//
+//
+//                     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 ResourcePriorityQueue class, which is a
+// SchedulingPriorityQueue that schedules using DFA state to
+// reduce the length of the critical path through the basic block
+// on VLIW platforms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
+#define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
+
+#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+  class ResourcePriorityQueue;
+
+  /// Sorting functions for the Available queue.
+  struct resource_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+    ResourcePriorityQueue *PQ;
+    explicit resource_sort(ResourcePriorityQueue *pq) : PQ(pq) {}
+
+    bool operator()(const SUnit* left, const SUnit* right) const;
+  };
+
+  class ResourcePriorityQueue : public SchedulingPriorityQueue {
+    /// SUnits - The SUnits for the current graph.
+    std::vector<SUnit> *SUnits;
+
+    /// NumNodesSolelyBlocking - This vector contains, for every node in the
+    /// Queue, the number of nodes that the node is the sole unscheduled
+    /// predecessor for.  This is used as a tie-breaker heuristic for better
+    /// mobility.
+    std::vector<unsigned> NumNodesSolelyBlocking;
+
+    /// Queue - The queue.
+    std::vector<SUnit*> Queue;
+
+    /// RegPressure - Tracking current reg pressure per register class.
+    ///
+    std::vector<unsigned> RegPressure;
+
+    /// RegLimit - Tracking the number of allocatable registers per register
+    /// class.
+    std::vector<unsigned> RegLimit;
+
+    resource_sort Picker;
+    const TargetRegisterInfo *TRI;
+    const TargetLowering *TLI;
+    const TargetInstrInfo *TII;
+    const InstrItineraryData* InstrItins;
+    /// ResourcesModel - Represents VLIW state.
+    /// Not limited to VLIW targets per say, but assumes
+    /// definition of DFA by a target.
+    DFAPacketizer *ResourcesModel;
+
+    /// Resource model - packet/bundle model. Purely
+    /// internal at the time.
+    std::vector<SUnit*> Packet;
+
+    /// Heuristics for estimating register pressure.
+    unsigned ParallelLiveRanges;
+    signed HorizontalVerticalBalance;
+
+  public:
+    ResourcePriorityQueue(SelectionDAGISel *IS);
+
+    ~ResourcePriorityQueue() {
+      delete ResourcesModel;
+    }
+
+    bool isBottomUp() const override { return false; }
+
+    void initNodes(std::vector<SUnit> &sunits) override;
+
+    void addNode(const SUnit *SU) override {
+      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+    }
+
+    void updateNode(const SUnit *SU) override {}
+
+    void releaseState() override {
+      SUnits = nullptr;
+    }
+
+    unsigned getLatency(unsigned NodeNum) const {
+      assert(NodeNum < (*SUnits).size());
+      return (*SUnits)[NodeNum].getHeight();
+    }
+
+    unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
+      assert(NodeNum < NumNodesSolelyBlocking.size());
+      return NumNodesSolelyBlocking[NodeNum];
+    }
+
+    /// Single cost function reflecting benefit of scheduling SU
+    /// in the current cycle.
+    signed SUSchedulingCost (SUnit *SU);
+
+    /// InitNumRegDefsLeft - Determine the # of regs defined by this node.
+    ///
+    void initNumRegDefsLeft(SUnit *SU);
+    void updateNumRegDefsLeft(SUnit *SU);
+    signed regPressureDelta(SUnit *SU, bool RawPressure = false);
+    signed rawRegPressureDelta (SUnit *SU, unsigned RCId);
+
+    bool empty() const override { return Queue.empty(); }
+
+    void push(SUnit *U) override;
+
+    SUnit *pop() override;
+
+    void remove(SUnit *SU) override;
+
+    void dump(ScheduleDAG* DAG) const override;
+
+    /// scheduledNode - Main resource tracking point.
+    void scheduledNode(SUnit *Node) override;
+    bool isResourceAvailable(SUnit *SU);
+    void reserveResources(SUnit *SU);
+
+private:
+    void adjustPriorityOfUnscheduledPreds(SUnit *SU);
+    SUnit *getSingleUnscheduledPred(SUnit *SU);
+    unsigned numberRCValPredInSU (SUnit *SU, unsigned RCId);
+    unsigned numberRCValSuccInSU (SUnit *SU, unsigned RCId);
+  };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
new file mode 100644
index 0000000..81db8a2
--- /dev/null
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -0,0 +1,421 @@
+//===-- CodeGen/RuntimeLibcalls.h - Runtime Library Calls -------*- 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 enum representing the list of runtime library calls
+// the backend may emit during code generation, and also some helper functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_RUNTIMELIBCALLS_H
+#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+namespace RTLIB {
+  /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
+  /// the backend can emit.  The various long double types cannot be merged,
+  /// because 80-bit library functions use "xf" and 128-bit use "tf".
+  ///
+  /// When adding PPCF128 functions here, note that their names generally need
+  /// to be overridden for Darwin with the xxx$LDBL128 form.  See
+  /// PPCISelLowering.cpp.
+  ///
+  enum Libcall {
+    // Integer
+    SHL_I16,
+    SHL_I32,
+    SHL_I64,
+    SHL_I128,
+    SRL_I16,
+    SRL_I32,
+    SRL_I64,
+    SRL_I128,
+    SRA_I16,
+    SRA_I32,
+    SRA_I64,
+    SRA_I128,
+    MUL_I8,
+    MUL_I16,
+    MUL_I32,
+    MUL_I64,
+    MUL_I128,
+    MULO_I32,
+    MULO_I64,
+    MULO_I128,
+    SDIV_I8,
+    SDIV_I16,
+    SDIV_I32,
+    SDIV_I64,
+    SDIV_I128,
+    UDIV_I8,
+    UDIV_I16,
+    UDIV_I32,
+    UDIV_I64,
+    UDIV_I128,
+    SREM_I8,
+    SREM_I16,
+    SREM_I32,
+    SREM_I64,
+    SREM_I128,
+    UREM_I8,
+    UREM_I16,
+    UREM_I32,
+    UREM_I64,
+    UREM_I128,
+    SDIVREM_I8,
+    SDIVREM_I16,
+    SDIVREM_I32,
+    SDIVREM_I64,
+    SDIVREM_I128,
+    UDIVREM_I8,
+    UDIVREM_I16,
+    UDIVREM_I32,
+    UDIVREM_I64,
+    UDIVREM_I128,
+    NEG_I32,
+    NEG_I64,
+
+    // FLOATING POINT
+    ADD_F32,
+    ADD_F64,
+    ADD_F80,
+    ADD_F128,
+    ADD_PPCF128,
+    SUB_F32,
+    SUB_F64,
+    SUB_F80,
+    SUB_F128,
+    SUB_PPCF128,
+    MUL_F32,
+    MUL_F64,
+    MUL_F80,
+    MUL_F128,
+    MUL_PPCF128,
+    DIV_F32,
+    DIV_F64,
+    DIV_F80,
+    DIV_F128,
+    DIV_PPCF128,
+    REM_F32,
+    REM_F64,
+    REM_F80,
+    REM_F128,
+    REM_PPCF128,
+    FMA_F32,
+    FMA_F64,
+    FMA_F80,
+    FMA_F128,
+    FMA_PPCF128,
+    POWI_F32,
+    POWI_F64,
+    POWI_F80,
+    POWI_F128,
+    POWI_PPCF128,
+    SQRT_F32,
+    SQRT_F64,
+    SQRT_F80,
+    SQRT_F128,
+    SQRT_PPCF128,
+    LOG_F32,
+    LOG_F64,
+    LOG_F80,
+    LOG_F128,
+    LOG_PPCF128,
+    LOG2_F32,
+    LOG2_F64,
+    LOG2_F80,
+    LOG2_F128,
+    LOG2_PPCF128,
+    LOG10_F32,
+    LOG10_F64,
+    LOG10_F80,
+    LOG10_F128,
+    LOG10_PPCF128,
+    EXP_F32,
+    EXP_F64,
+    EXP_F80,
+    EXP_F128,
+    EXP_PPCF128,
+    EXP2_F32,
+    EXP2_F64,
+    EXP2_F80,
+    EXP2_F128,
+    EXP2_PPCF128,
+    SIN_F32,
+    SIN_F64,
+    SIN_F80,
+    SIN_F128,
+    SIN_PPCF128,
+    COS_F32,
+    COS_F64,
+    COS_F80,
+    COS_F128,
+    COS_PPCF128,
+    SINCOS_F32,
+    SINCOS_F64,
+    SINCOS_F80,
+    SINCOS_F128,
+    SINCOS_PPCF128,
+    POW_F32,
+    POW_F64,
+    POW_F80,
+    POW_F128,
+    POW_PPCF128,
+    CEIL_F32,
+    CEIL_F64,
+    CEIL_F80,
+    CEIL_F128,
+    CEIL_PPCF128,
+    TRUNC_F32,
+    TRUNC_F64,
+    TRUNC_F80,
+    TRUNC_F128,
+    TRUNC_PPCF128,
+    RINT_F32,
+    RINT_F64,
+    RINT_F80,
+    RINT_F128,
+    RINT_PPCF128,
+    NEARBYINT_F32,
+    NEARBYINT_F64,
+    NEARBYINT_F80,
+    NEARBYINT_F128,
+    NEARBYINT_PPCF128,
+    ROUND_F32,
+    ROUND_F64,
+    ROUND_F80,
+    ROUND_F128,
+    ROUND_PPCF128,
+    FLOOR_F32,
+    FLOOR_F64,
+    FLOOR_F80,
+    FLOOR_F128,
+    FLOOR_PPCF128,
+    COPYSIGN_F32,
+    COPYSIGN_F64,
+    COPYSIGN_F80,
+    COPYSIGN_F128,
+    COPYSIGN_PPCF128,
+
+    // CONVERSION
+    FPEXT_F64_F128,
+    FPEXT_F32_F128,
+    FPEXT_F32_F64,
+    FPEXT_F16_F32,
+    FPROUND_F32_F16,
+    FPROUND_F64_F16,
+    FPROUND_F80_F16,
+    FPROUND_F128_F16,
+    FPROUND_PPCF128_F16,
+    FPROUND_F64_F32,
+    FPROUND_F80_F32,
+    FPROUND_F128_F32,
+    FPROUND_PPCF128_F32,
+    FPROUND_F80_F64,
+    FPROUND_F128_F64,
+    FPROUND_PPCF128_F64,
+    FPTOSINT_F32_I8,
+    FPTOSINT_F32_I16,
+    FPTOSINT_F32_I32,
+    FPTOSINT_F32_I64,
+    FPTOSINT_F32_I128,
+    FPTOSINT_F64_I8,
+    FPTOSINT_F64_I16,
+    FPTOSINT_F64_I32,
+    FPTOSINT_F64_I64,
+    FPTOSINT_F64_I128,
+    FPTOSINT_F80_I32,
+    FPTOSINT_F80_I64,
+    FPTOSINT_F80_I128,
+    FPTOSINT_F128_I32,
+    FPTOSINT_F128_I64,
+    FPTOSINT_F128_I128,
+    FPTOSINT_PPCF128_I32,
+    FPTOSINT_PPCF128_I64,
+    FPTOSINT_PPCF128_I128,
+    FPTOUINT_F32_I8,
+    FPTOUINT_F32_I16,
+    FPTOUINT_F32_I32,
+    FPTOUINT_F32_I64,
+    FPTOUINT_F32_I128,
+    FPTOUINT_F64_I8,
+    FPTOUINT_F64_I16,
+    FPTOUINT_F64_I32,
+    FPTOUINT_F64_I64,
+    FPTOUINT_F64_I128,
+    FPTOUINT_F80_I32,
+    FPTOUINT_F80_I64,
+    FPTOUINT_F80_I128,
+    FPTOUINT_F128_I32,
+    FPTOUINT_F128_I64,
+    FPTOUINT_F128_I128,
+    FPTOUINT_PPCF128_I32,
+    FPTOUINT_PPCF128_I64,
+    FPTOUINT_PPCF128_I128,
+    SINTTOFP_I32_F32,
+    SINTTOFP_I32_F64,
+    SINTTOFP_I32_F80,
+    SINTTOFP_I32_F128,
+    SINTTOFP_I32_PPCF128,
+    SINTTOFP_I64_F32,
+    SINTTOFP_I64_F64,
+    SINTTOFP_I64_F80,
+    SINTTOFP_I64_F128,
+    SINTTOFP_I64_PPCF128,
+    SINTTOFP_I128_F32,
+    SINTTOFP_I128_F64,
+    SINTTOFP_I128_F80,
+    SINTTOFP_I128_F128,
+    SINTTOFP_I128_PPCF128,
+    UINTTOFP_I32_F32,
+    UINTTOFP_I32_F64,
+    UINTTOFP_I32_F80,
+    UINTTOFP_I32_F128,
+    UINTTOFP_I32_PPCF128,
+    UINTTOFP_I64_F32,
+    UINTTOFP_I64_F64,
+    UINTTOFP_I64_F80,
+    UINTTOFP_I64_F128,
+    UINTTOFP_I64_PPCF128,
+    UINTTOFP_I128_F32,
+    UINTTOFP_I128_F64,
+    UINTTOFP_I128_F80,
+    UINTTOFP_I128_F128,
+    UINTTOFP_I128_PPCF128,
+
+    // COMPARISON
+    OEQ_F32,
+    OEQ_F64,
+    OEQ_F128,
+    UNE_F32,
+    UNE_F64,
+    UNE_F128,
+    OGE_F32,
+    OGE_F64,
+    OGE_F128,
+    OLT_F32,
+    OLT_F64,
+    OLT_F128,
+    OLE_F32,
+    OLE_F64,
+    OLE_F128,
+    OGT_F32,
+    OGT_F64,
+    OGT_F128,
+    UO_F32,
+    UO_F64,
+    UO_F128,
+    O_F32,
+    O_F64,
+    O_F128,
+
+    // MEMORY
+    MEMCPY,
+    MEMSET,
+    MEMMOVE,
+
+    // EXCEPTION HANDLING
+    UNWIND_RESUME,
+
+    // Family ATOMICs
+    SYNC_VAL_COMPARE_AND_SWAP_1,
+    SYNC_VAL_COMPARE_AND_SWAP_2,
+    SYNC_VAL_COMPARE_AND_SWAP_4,
+    SYNC_VAL_COMPARE_AND_SWAP_8,
+    SYNC_VAL_COMPARE_AND_SWAP_16,
+    SYNC_LOCK_TEST_AND_SET_1,
+    SYNC_LOCK_TEST_AND_SET_2,
+    SYNC_LOCK_TEST_AND_SET_4,
+    SYNC_LOCK_TEST_AND_SET_8,
+    SYNC_LOCK_TEST_AND_SET_16,
+    SYNC_FETCH_AND_ADD_1,
+    SYNC_FETCH_AND_ADD_2,
+    SYNC_FETCH_AND_ADD_4,
+    SYNC_FETCH_AND_ADD_8,
+    SYNC_FETCH_AND_ADD_16,
+    SYNC_FETCH_AND_SUB_1,
+    SYNC_FETCH_AND_SUB_2,
+    SYNC_FETCH_AND_SUB_4,
+    SYNC_FETCH_AND_SUB_8,
+    SYNC_FETCH_AND_SUB_16,
+    SYNC_FETCH_AND_AND_1,
+    SYNC_FETCH_AND_AND_2,
+    SYNC_FETCH_AND_AND_4,
+    SYNC_FETCH_AND_AND_8,
+    SYNC_FETCH_AND_AND_16,
+    SYNC_FETCH_AND_OR_1,
+    SYNC_FETCH_AND_OR_2,
+    SYNC_FETCH_AND_OR_4,
+    SYNC_FETCH_AND_OR_8,
+    SYNC_FETCH_AND_OR_16,
+    SYNC_FETCH_AND_XOR_1,
+    SYNC_FETCH_AND_XOR_2,
+    SYNC_FETCH_AND_XOR_4,
+    SYNC_FETCH_AND_XOR_8,
+    SYNC_FETCH_AND_XOR_16,
+    SYNC_FETCH_AND_NAND_1,
+    SYNC_FETCH_AND_NAND_2,
+    SYNC_FETCH_AND_NAND_4,
+    SYNC_FETCH_AND_NAND_8,
+    SYNC_FETCH_AND_NAND_16,
+    SYNC_FETCH_AND_MAX_1,
+    SYNC_FETCH_AND_MAX_2,
+    SYNC_FETCH_AND_MAX_4,
+    SYNC_FETCH_AND_MAX_8,
+    SYNC_FETCH_AND_MAX_16,
+    SYNC_FETCH_AND_UMAX_1,
+    SYNC_FETCH_AND_UMAX_2,
+    SYNC_FETCH_AND_UMAX_4,
+    SYNC_FETCH_AND_UMAX_8,
+    SYNC_FETCH_AND_UMAX_16,
+    SYNC_FETCH_AND_MIN_1,
+    SYNC_FETCH_AND_MIN_2,
+    SYNC_FETCH_AND_MIN_4,
+    SYNC_FETCH_AND_MIN_8,
+    SYNC_FETCH_AND_MIN_16,
+    SYNC_FETCH_AND_UMIN_1,
+    SYNC_FETCH_AND_UMIN_2,
+    SYNC_FETCH_AND_UMIN_4,
+    SYNC_FETCH_AND_UMIN_8,
+    SYNC_FETCH_AND_UMIN_16,
+
+    // Stack Protector Fail.
+    STACKPROTECTOR_CHECK_FAIL,
+
+    UNKNOWN_LIBCALL
+  };
+
+  /// getFPEXT - Return the FPEXT_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getFPEXT(EVT OpVT, EVT RetVT);
+
+  /// getFPROUND - Return the FPROUND_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getFPROUND(EVT OpVT, EVT RetVT);
+
+  /// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getFPTOSINT(EVT OpVT, EVT RetVT);
+
+  /// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getFPTOUINT(EVT OpVT, EVT RetVT);
+
+  /// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getSINTTOFP(EVT OpVT, EVT RetVT);
+
+  /// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
+  /// UNKNOWN_LIBCALL if there is none.
+  Libcall getUINTTOFP(EVT OpVT, EVT RetVT);
+}
+}
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
new file mode 100644
index 0000000..5a65d59
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -0,0 +1,753 @@
+//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//
+//                     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 ScheduleDAG class, which is used as the common
+// base class for instruction schedulers. This encapsulates the scheduling DAG,
+// which is shared between SelectionDAG and MachineInstr scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
+#define LLVM_CODEGEN_SCHEDULEDAG_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetLowering.h"
+
+namespace llvm {
+  class AliasAnalysis;
+  class SUnit;
+  class MachineConstantPool;
+  class MachineFunction;
+  class MachineRegisterInfo;
+  class MachineInstr;
+  struct MCSchedClassDesc;
+  class TargetRegisterInfo;
+  class ScheduleDAG;
+  class SDNode;
+  class TargetInstrInfo;
+  class MCInstrDesc;
+  class TargetMachine;
+  class TargetRegisterClass;
+  template<class Graph> class GraphWriter;
+
+  /// SDep - Scheduling dependency. This represents one direction of an
+  /// edge in the scheduling DAG.
+  class SDep {
+  public:
+    /// Kind - These are the different kinds of scheduling dependencies.
+    enum Kind {
+      Data,        ///< Regular data dependence (aka true-dependence).
+      Anti,        ///< A register anti-dependedence (aka WAR).
+      Output,      ///< A register output-dependence (aka WAW).
+      Order        ///< Any other ordering dependency.
+    };
+
+    // Strong dependencies must be respected by the scheduler. Artificial
+    // dependencies may be removed only if they are redundant with another
+    // strong depedence.
+    //
+    // Weak dependencies may be violated by the scheduling strategy, but only if
+    // the strategy can prove it is correct to do so.
+    //
+    // Strong OrderKinds must occur before "Weak".
+    // Weak OrderKinds must occur after "Weak".
+    enum OrderKind {
+      Barrier,      ///< An unknown scheduling barrier.
+      MayAliasMem,  ///< Nonvolatile load/Store instructions that may alias.
+      MustAliasMem, ///< Nonvolatile load/Store instructions that must alias.
+      Artificial,   ///< Arbitrary strong DAG edge (no real dependence).
+      Weak,         ///< Arbitrary weak DAG edge.
+      Cluster       ///< Weak DAG edge linking a chain of clustered instrs.
+    };
+
+  private:
+    /// Dep - A pointer to the depending/depended-on SUnit, and an enum
+    /// indicating the kind of the dependency.
+    PointerIntPair<SUnit *, 2, Kind> Dep;
+
+    /// Contents - A union discriminated by the dependence kind.
+    union {
+      /// Reg - For Data, Anti, and Output dependencies, the associated
+      /// register. For Data dependencies that don't currently have a register
+      /// assigned, this is set to zero.
+      unsigned Reg;
+
+      /// Order - Additional information about Order dependencies.
+      unsigned OrdKind; // enum OrderKind
+    } Contents;
+
+    /// Latency - The time associated with this edge. Often this is just
+    /// the value of the Latency field of the predecessor, however advanced
+    /// models may provide additional information about specific edges.
+    unsigned Latency;
+
+  public:
+    /// SDep - Construct a null SDep. This is only for use by container
+    /// classes which require default constructors. SUnits may not
+    /// have null SDep edges.
+    SDep() : Dep(nullptr, Data) {}
+
+    /// SDep - Construct an SDep with the specified values.
+    SDep(SUnit *S, Kind kind, unsigned Reg)
+      : Dep(S, kind), Contents() {
+      switch (kind) {
+      default:
+        llvm_unreachable("Reg given for non-register dependence!");
+      case Anti:
+      case Output:
+        assert(Reg != 0 &&
+               "SDep::Anti and SDep::Output must use a non-zero Reg!");
+        Contents.Reg = Reg;
+        Latency = 0;
+        break;
+      case Data:
+        Contents.Reg = Reg;
+        Latency = 1;
+        break;
+      }
+    }
+    SDep(SUnit *S, OrderKind kind)
+      : Dep(S, Order), Contents(), Latency(0) {
+      Contents.OrdKind = kind;
+    }
+
+    /// Return true if the specified SDep is equivalent except for latency.
+    bool overlaps(const SDep &Other) const {
+      if (Dep != Other.Dep) return false;
+      switch (Dep.getInt()) {
+      case Data:
+      case Anti:
+      case Output:
+        return Contents.Reg == Other.Contents.Reg;
+      case Order:
+        return Contents.OrdKind == Other.Contents.OrdKind;
+      }
+      llvm_unreachable("Invalid dependency kind!");
+    }
+
+    bool operator==(const SDep &Other) const {
+      return overlaps(Other) && Latency == Other.Latency;
+    }
+
+    bool operator!=(const SDep &Other) const {
+      return !operator==(Other);
+    }
+
+    /// getLatency - Return the latency value for this edge, which roughly
+    /// means the minimum number of cycles that must elapse between the
+    /// predecessor and the successor, given that they have this edge
+    /// between them.
+    unsigned getLatency() const {
+      return Latency;
+    }
+
+    /// setLatency - Set the latency for this edge.
+    void setLatency(unsigned Lat) {
+      Latency = Lat;
+    }
+
+    //// getSUnit - Return the SUnit to which this edge points.
+    SUnit *getSUnit() const {
+      return Dep.getPointer();
+    }
+
+    //// setSUnit - Assign the SUnit to which this edge points.
+    void setSUnit(SUnit *SU) {
+      Dep.setPointer(SU);
+    }
+
+    /// getKind - Return an enum value representing the kind of the dependence.
+    Kind getKind() const {
+      return Dep.getInt();
+    }
+
+    /// isCtrl - Shorthand for getKind() != SDep::Data.
+    bool isCtrl() const {
+      return getKind() != Data;
+    }
+
+    /// isNormalMemory - Test if this is an Order dependence between two
+    /// memory accesses where both sides of the dependence access memory
+    /// in non-volatile and fully modeled ways.
+    bool isNormalMemory() const {
+      return getKind() == Order && (Contents.OrdKind == MayAliasMem
+                                    || Contents.OrdKind == MustAliasMem);
+    }
+
+    /// isBarrier - Test if this is an Order dependence that is marked
+    /// as a barrier.
+    bool isBarrier() const {
+      return getKind() == Order && Contents.OrdKind == Barrier;
+    }
+
+    /// isMustAlias - Test if this is an Order dependence that is marked
+    /// as "must alias", meaning that the SUnits at either end of the edge
+    /// have a memory dependence on a known memory location.
+    bool isMustAlias() const {
+      return getKind() == Order && Contents.OrdKind == MustAliasMem;
+    }
+
+    /// isWeak - Test if this a weak dependence. Weak dependencies are
+    /// considered DAG edges for height computation and other heuristics, but do
+    /// not force ordering. Breaking a weak edge may require the scheduler to
+    /// compensate, for example by inserting a copy.
+    bool isWeak() const {
+      return getKind() == Order && Contents.OrdKind >= Weak;
+    }
+
+    /// isArtificial - Test if this is an Order dependence that is marked
+    /// as "artificial", meaning it isn't necessary for correctness.
+    bool isArtificial() const {
+      return getKind() == Order && Contents.OrdKind == Artificial;
+    }
+
+    /// isCluster - Test if this is an Order dependence that is marked
+    /// as "cluster", meaning it is artificial and wants to be adjacent.
+    bool isCluster() const {
+      return getKind() == Order && Contents.OrdKind == Cluster;
+    }
+
+    /// isAssignedRegDep - Test if this is a Data dependence that is
+    /// associated with a register.
+    bool isAssignedRegDep() const {
+      return getKind() == Data && Contents.Reg != 0;
+    }
+
+    /// getReg - Return the register associated with this edge. This is
+    /// only valid on Data, Anti, and Output edges. On Data edges, this
+    /// value may be zero, meaning there is no associated register.
+    unsigned getReg() const {
+      assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
+             "getReg called on non-register dependence edge!");
+      return Contents.Reg;
+    }
+
+    /// setReg - Assign the associated register for this edge. This is
+    /// only valid on Data, Anti, and Output edges. On Anti and Output
+    /// edges, this value must not be zero. On Data edges, the value may
+    /// be zero, which would mean that no specific register is associated
+    /// with this edge.
+    void setReg(unsigned Reg) {
+      assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
+             "setReg called on non-register dependence edge!");
+      assert((getKind() != Anti || Reg != 0) &&
+             "SDep::Anti edge cannot use the zero register!");
+      assert((getKind() != Output || Reg != 0) &&
+             "SDep::Output edge cannot use the zero register!");
+      Contents.Reg = Reg;
+    }
+  };
+
+  template <>
+  struct isPodLike<SDep> { static const bool value = true; };
+
+  /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
+  class SUnit {
+  private:
+    enum : unsigned { BoundaryID = ~0u };
+
+    SDNode *Node;                       // Representative node.
+    MachineInstr *Instr;                // Alternatively, a MachineInstr.
+  public:
+    SUnit *OrigNode;                    // If not this, the node from which
+                                        // this node was cloned.
+                                        // (SD scheduling only)
+
+    const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
+
+    // Preds/Succs - The SUnits before/after us in the graph.
+    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
+    SmallVector<SDep, 4> Succs;  // All sunit successors.
+
+    typedef SmallVectorImpl<SDep>::iterator pred_iterator;
+    typedef SmallVectorImpl<SDep>::iterator succ_iterator;
+    typedef SmallVectorImpl<SDep>::const_iterator const_pred_iterator;
+    typedef SmallVectorImpl<SDep>::const_iterator const_succ_iterator;
+
+    unsigned NodeNum;                   // Entry # of node in the node vector.
+    unsigned NodeQueueId;               // Queue id of node.
+    unsigned NumPreds;                  // # of SDep::Data preds.
+    unsigned NumSuccs;                  // # of SDep::Data sucss.
+    unsigned NumPredsLeft;              // # of preds not scheduled.
+    unsigned NumSuccsLeft;              // # of succs not scheduled.
+    unsigned WeakPredsLeft;             // # of weak preds not scheduled.
+    unsigned WeakSuccsLeft;             // # of weak succs not scheduled.
+    unsigned short NumRegDefsLeft;      // # of reg defs with no scheduled use.
+    unsigned short Latency;             // Node latency.
+    bool isVRegCycle      : 1;          // May use and def the same vreg.
+    bool isCall           : 1;          // Is a function call.
+    bool isCallOp         : 1;          // Is a function call operand.
+    bool isTwoAddress     : 1;          // Is a two-address instruction.
+    bool isCommutable     : 1;          // Is a commutable instruction.
+    bool hasPhysRegUses   : 1;          // Has physreg uses.
+    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
+    bool hasPhysRegClobbers : 1;        // Has any physreg defs, used or not.
+    bool isPending        : 1;          // True once pending.
+    bool isAvailable      : 1;          // True once available.
+    bool isScheduled      : 1;          // True once scheduled.
+    bool isScheduleHigh   : 1;          // True if preferable to schedule high.
+    bool isScheduleLow    : 1;          // True if preferable to schedule low.
+    bool isCloned         : 1;          // True if this node has been cloned.
+    bool isUnbuffered     : 1;          // Uses an unbuffered resource.
+    bool hasReservedResource : 1;       // Uses a reserved resource.
+    Sched::Preference SchedulingPref;   // Scheduling preference.
+
+  private:
+    bool isDepthCurrent   : 1;          // True if Depth is current.
+    bool isHeightCurrent  : 1;          // True if Height is current.
+    unsigned Depth;                     // Node depth.
+    unsigned Height;                    // Node height.
+  public:
+    unsigned TopReadyCycle; // Cycle relative to start when node is ready.
+    unsigned BotReadyCycle; // Cycle relative to end when node is ready.
+
+    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
+    const TargetRegisterClass *CopySrcRC;
+
+    /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
+    /// an SDNode and any nodes flagged to it.
+    SUnit(SDNode *node, unsigned nodenum)
+      : Node(node), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
+        NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
+        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
+        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
+        isCallOp(false), isTwoAddress(false), isCommutable(false),
+        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
+        isPending(false), isAvailable(false), isScheduled(false),
+        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
+        isUnbuffered(false), hasReservedResource(false),
+        SchedulingPref(Sched::None), isDepthCurrent(false),
+        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
+        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+
+    /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
+    /// a MachineInstr.
+    SUnit(MachineInstr *instr, unsigned nodenum)
+      : Node(nullptr), Instr(instr), OrigNode(nullptr), SchedClass(nullptr),
+        NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0),
+        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
+        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
+        isCallOp(false), isTwoAddress(false), isCommutable(false),
+        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
+        isPending(false), isAvailable(false), isScheduled(false),
+        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
+        isUnbuffered(false), hasReservedResource(false),
+        SchedulingPref(Sched::None), isDepthCurrent(false),
+        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
+        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+
+    /// SUnit - Construct a placeholder SUnit.
+    SUnit()
+      : Node(nullptr), Instr(nullptr), OrigNode(nullptr), SchedClass(nullptr),
+        NodeNum(BoundaryID), NodeQueueId(0), NumPreds(0), NumSuccs(0),
+        NumPredsLeft(0), NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0),
+        NumRegDefsLeft(0), Latency(0), isVRegCycle(false), isCall(false),
+        isCallOp(false), isTwoAddress(false), isCommutable(false),
+        hasPhysRegUses(false), hasPhysRegDefs(false), hasPhysRegClobbers(false),
+        isPending(false), isAvailable(false), isScheduled(false),
+        isScheduleHigh(false), isScheduleLow(false), isCloned(false),
+        isUnbuffered(false), hasReservedResource(false),
+        SchedulingPref(Sched::None), isDepthCurrent(false),
+        isHeightCurrent(false), Depth(0), Height(0), TopReadyCycle(0),
+        BotReadyCycle(0), CopyDstRC(nullptr), CopySrcRC(nullptr) {}
+
+    /// \brief Boundary nodes are placeholders for the boundary of the
+    /// scheduling region.
+    ///
+    /// BoundaryNodes can have DAG edges, including Data edges, but they do not
+    /// correspond to schedulable entities (e.g. instructions) and do not have a
+    /// valid ID. Consequently, always check for boundary nodes before accessing
+    /// an assoicative data structure keyed on node ID.
+    bool isBoundaryNode() const { return NodeNum == BoundaryID; };
+
+    /// setNode - Assign the representative SDNode for this SUnit.
+    /// This may be used during pre-regalloc scheduling.
+    void setNode(SDNode *N) {
+      assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
+      Node = N;
+    }
+
+    /// getNode - Return the representative SDNode for this SUnit.
+    /// This may be used during pre-regalloc scheduling.
+    SDNode *getNode() const {
+      assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
+      return Node;
+    }
+
+    /// isInstr - Return true if this SUnit refers to a machine instruction as
+    /// opposed to an SDNode.
+    bool isInstr() const { return Instr; }
+
+    /// setInstr - Assign the instruction for the SUnit.
+    /// This may be used during post-regalloc scheduling.
+    void setInstr(MachineInstr *MI) {
+      assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
+      Instr = MI;
+    }
+
+    /// getInstr - Return the representative MachineInstr for this SUnit.
+    /// This may be used during post-regalloc scheduling.
+    MachineInstr *getInstr() const {
+      assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
+      return Instr;
+    }
+
+    /// addPred - This adds the specified edge as a pred of the current node if
+    /// not already.  It also adds the current node as a successor of the
+    /// specified node.
+    bool addPred(const SDep &D, bool Required = true);
+
+    /// removePred - This removes the specified edge as a pred of the current
+    /// node if it exists.  It also removes the current node as a successor of
+    /// the specified node.
+    void removePred(const SDep &D);
+
+    /// getDepth - Return the depth of this node, which is the length of the
+    /// maximum path up to any node which has no predecessors.
+    unsigned getDepth() const {
+      if (!isDepthCurrent)
+        const_cast<SUnit *>(this)->ComputeDepth();
+      return Depth;
+    }
+
+    /// getHeight - Return the height of this node, which is the length of the
+    /// maximum path down to any node which has no successors.
+    unsigned getHeight() const {
+      if (!isHeightCurrent)
+        const_cast<SUnit *>(this)->ComputeHeight();
+      return Height;
+    }
+
+    /// setDepthToAtLeast - If NewDepth is greater than this node's
+    /// depth value, set it to be the new depth value. This also
+    /// recursively marks successor nodes dirty.
+    void setDepthToAtLeast(unsigned NewDepth);
+
+    /// setDepthToAtLeast - If NewDepth is greater than this node's
+    /// depth value, set it to be the new height value. This also
+    /// recursively marks predecessor nodes dirty.
+    void setHeightToAtLeast(unsigned NewHeight);
+
+    /// setDepthDirty - Set a flag in this node to indicate that its
+    /// stored Depth value will require recomputation the next time
+    /// getDepth() is called.
+    void setDepthDirty();
+
+    /// setHeightDirty - Set a flag in this node to indicate that its
+    /// stored Height value will require recomputation the next time
+    /// getHeight() is called.
+    void setHeightDirty();
+
+    /// isPred - Test if node N is a predecessor of this node.
+    bool isPred(SUnit *N) {
+      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
+        if (Preds[i].getSUnit() == N)
+          return true;
+      return false;
+    }
+
+    /// isSucc - Test if node N is a successor of this node.
+    bool isSucc(SUnit *N) {
+      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
+        if (Succs[i].getSUnit() == N)
+          return true;
+      return false;
+    }
+
+    bool isTopReady() const {
+      return NumPredsLeft == 0;
+    }
+    bool isBottomReady() const {
+      return NumSuccsLeft == 0;
+    }
+
+    /// \brief Order this node's predecessor edges such that the critical path
+    /// edge occurs first.
+    void biasCriticalPath();
+
+    void dump(const ScheduleDAG *G) const;
+    void dumpAll(const ScheduleDAG *G) const;
+    void print(raw_ostream &O, const ScheduleDAG *G) const;
+
+  private:
+    void ComputeDepth();
+    void ComputeHeight();
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// SchedulingPriorityQueue - This interface is used to plug different
+  /// priorities computation algorithms into the list scheduler. It implements
+  /// the interface of a standard priority queue, where nodes are inserted in
+  /// arbitrary order and returned in priority order.  The computation of the
+  /// priority and the representation of the queue are totally up to the
+  /// implementation to decide.
+  ///
+  class SchedulingPriorityQueue {
+    virtual void anchor();
+    unsigned CurCycle;
+    bool HasReadyFilter;
+  public:
+    SchedulingPriorityQueue(bool rf = false):
+      CurCycle(0), HasReadyFilter(rf) {}
+    virtual ~SchedulingPriorityQueue() {}
+
+    virtual bool isBottomUp() const = 0;
+
+    virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
+    virtual void addNode(const SUnit *SU) = 0;
+    virtual void updateNode(const SUnit *SU) = 0;
+    virtual void releaseState() = 0;
+
+    virtual bool empty() const = 0;
+
+    bool hasReadyFilter() const { return HasReadyFilter; }
+
+    virtual bool tracksRegPressure() const { return false; }
+
+    virtual bool isReady(SUnit *) const {
+      assert(!HasReadyFilter && "The ready filter must override isReady()");
+      return true;
+    }
+    virtual void push(SUnit *U) = 0;
+
+    void push_all(const std::vector<SUnit *> &Nodes) {
+      for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
+           E = Nodes.end(); I != E; ++I)
+        push(*I);
+    }
+
+    virtual SUnit *pop() = 0;
+
+    virtual void remove(SUnit *SU) = 0;
+
+    virtual void dump(ScheduleDAG *) const {}
+
+    /// scheduledNode - As each node is scheduled, this method is invoked.  This
+    /// allows the priority function to adjust the priority of related
+    /// unscheduled nodes, for example.
+    ///
+    virtual void scheduledNode(SUnit *) {}
+
+    virtual void unscheduledNode(SUnit *) {}
+
+    void setCurCycle(unsigned Cycle) {
+      CurCycle = Cycle;
+    }
+
+    unsigned getCurCycle() const {
+      return CurCycle;
+    }
+  };
+
+  class ScheduleDAG {
+  public:
+    const TargetMachine &TM;              // Target processor
+    const TargetInstrInfo *TII;           // Target instruction information
+    const TargetRegisterInfo *TRI;        // Target processor register info
+    MachineFunction &MF;                  // Machine function
+    MachineRegisterInfo &MRI;             // Virtual/real register map
+    std::vector<SUnit> SUnits;            // The scheduling units.
+    SUnit EntrySU;                        // Special node for the region entry.
+    SUnit ExitSU;                         // Special node for the region exit.
+
+#ifdef NDEBUG
+    static const bool StressSched = false;
+#else
+    bool StressSched;
+#endif
+
+    explicit ScheduleDAG(MachineFunction &mf);
+
+    virtual ~ScheduleDAG();
+
+    /// clearDAG - clear the DAG state (between regions).
+    void clearDAG();
+
+    /// getInstrDesc - Return the MCInstrDesc of this SUnit.
+    /// Return NULL for SDNodes without a machine opcode.
+    const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
+      if (SU->isInstr()) return &SU->getInstr()->getDesc();
+      return getNodeDesc(SU->getNode());
+    }
+
+    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
+    /// using 'dot'.
+    ///
+    virtual void viewGraph(const Twine &Name, const Twine &Title);
+    virtual void viewGraph();
+
+    virtual void dumpNode(const SUnit *SU) const = 0;
+
+    /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
+    /// of the ScheduleDAG.
+    virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
+
+    /// getDAGLabel - Return a label for the region of code covered by the DAG.
+    virtual std::string getDAGName() const = 0;
+
+    /// addCustomGraphFeatures - Add custom features for a visualization of
+    /// the ScheduleDAG.
+    virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
+
+#ifndef NDEBUG
+    /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
+    /// their state is consistent. Return the number of scheduled SUnits.
+    unsigned VerifyScheduledDAG(bool isBottomUp);
+#endif
+
+  private:
+    // Return the MCInstrDesc of this SDNode or NULL.
+    const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
+  };
+
+  class SUnitIterator : public std::iterator<std::forward_iterator_tag,
+                                             SUnit, ptrdiff_t> {
+    SUnit *Node;
+    unsigned Operand;
+
+    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
+  public:
+    bool operator==(const SUnitIterator& x) const {
+      return Operand == x.Operand;
+    }
+    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
+
+    const SUnitIterator &operator=(const SUnitIterator &I) {
+      assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
+      Operand = I.Operand;
+      return *this;
+    }
+
+    pointer operator*() const {
+      return Node->Preds[Operand].getSUnit();
+    }
+    pointer operator->() const { return operator*(); }
+
+    SUnitIterator& operator++() {                // Preincrement
+      ++Operand;
+      return *this;
+    }
+    SUnitIterator operator++(int) { // Postincrement
+      SUnitIterator tmp = *this; ++*this; return tmp;
+    }
+
+    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
+    static SUnitIterator end  (SUnit *N) {
+      return SUnitIterator(N, (unsigned)N->Preds.size());
+    }
+
+    unsigned getOperand() const { return Operand; }
+    const SUnit *getNode() const { return Node; }
+    /// isCtrlDep - Test if this is not an SDep::Data dependence.
+    bool isCtrlDep() const {
+      return getSDep().isCtrl();
+    }
+    bool isArtificialDep() const {
+      return getSDep().isArtificial();
+    }
+    const SDep &getSDep() const {
+      return Node->Preds[Operand];
+    }
+  };
+
+  template <> struct GraphTraits<SUnit*> {
+    typedef SUnit NodeType;
+    typedef SUnitIterator ChildIteratorType;
+    static inline NodeType *getEntryNode(SUnit *N) { return N; }
+    static inline ChildIteratorType child_begin(NodeType *N) {
+      return SUnitIterator::begin(N);
+    }
+    static inline ChildIteratorType child_end(NodeType *N) {
+      return SUnitIterator::end(N);
+    }
+  };
+
+  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
+    typedef std::vector<SUnit>::iterator nodes_iterator;
+    static nodes_iterator nodes_begin(ScheduleDAG *G) {
+      return G->SUnits.begin();
+    }
+    static nodes_iterator nodes_end(ScheduleDAG *G) {
+      return G->SUnits.end();
+    }
+  };
+
+  /// ScheduleDAGTopologicalSort is a class that computes a topological
+  /// ordering for SUnits and provides methods for dynamically updating
+  /// the ordering as new edges are added.
+  ///
+  /// This allows a very fast implementation of IsReachable, for example.
+  ///
+  class ScheduleDAGTopologicalSort {
+    /// SUnits - A reference to the ScheduleDAG's SUnits.
+    std::vector<SUnit> &SUnits;
+    SUnit *ExitSU;
+
+    /// Index2Node - Maps topological index to the node number.
+    std::vector<int> Index2Node;
+    /// Node2Index - Maps the node number to its topological index.
+    std::vector<int> Node2Index;
+    /// Visited - a set of nodes visited during a DFS traversal.
+    BitVector Visited;
+
+    /// DFS - make a DFS traversal and mark all nodes affected by the
+    /// edge insertion. These nodes will later get new topological indexes
+    /// by means of the Shift method.
+    void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
+
+    /// Shift - reassign topological indexes for the nodes in the DAG
+    /// to preserve the topological ordering.
+    void Shift(BitVector& Visited, int LowerBound, int UpperBound);
+
+    /// Allocate - assign the topological index to the node n.
+    void Allocate(int n, int index);
+
+  public:
+    ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
+
+    /// InitDAGTopologicalSorting - create the initial topological
+    /// ordering from the DAG to be scheduled.
+    void InitDAGTopologicalSorting();
+
+    /// IsReachable - Checks if SU is reachable from TargetSU.
+    bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
+
+    /// WillCreateCycle - Return true if addPred(TargetSU, SU) creates a cycle.
+    bool WillCreateCycle(SUnit *TargetSU, SUnit *SU);
+
+    /// AddPred - Updates the topological ordering to accommodate an edge
+    /// to be added from SUnit X to SUnit Y.
+    void AddPred(SUnit *Y, SUnit *X);
+
+    /// RemovePred - Updates the topological ordering to accommodate an
+    /// an edge to be removed from the specified node N from the predecessors
+    /// of the current node M.
+    void RemovePred(SUnit *M, SUnit *N);
+
+    typedef std::vector<int>::iterator iterator;
+    typedef std::vector<int>::const_iterator const_iterator;
+    iterator begin() { return Index2Node.begin(); }
+    const_iterator begin() const { return Index2Node.begin(); }
+    iterator end() { return Index2Node.end(); }
+    const_iterator end() const { return Index2Node.end(); }
+
+    typedef std::vector<int>::reverse_iterator reverse_iterator;
+    typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
+    reverse_iterator rbegin() { return Index2Node.rbegin(); }
+    const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
+    reverse_iterator rend() { return Index2Node.rend(); }
+    const_reverse_iterator rend() const { return Index2Node.rend(); }
+  };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
new file mode 100644
index 0000000..e6754a2
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -0,0 +1,281 @@
+//==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==//
+//
+//                     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 ScheduleDAGInstrs class, which implements
+// scheduling for a MachineInstr-based dependency graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+
+#include "llvm/ADT/SparseMultiSet.h"
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/TargetSchedule.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+  class MachineFrameInfo;
+  class MachineLoopInfo;
+  class MachineDominatorTree;
+  class LiveIntervals;
+  class RegPressureTracker;
+  class PressureDiffs;
+
+  /// An individual mapping from virtual register number to SUnit.
+  struct VReg2SUnit {
+    unsigned VirtReg;
+    SUnit *SU;
+
+    VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
+
+    unsigned getSparseSetIndex() const {
+      return TargetRegisterInfo::virtReg2Index(VirtReg);
+    }
+  };
+
+  /// Record a physical register access.
+  /// For non-data-dependent uses, OpIdx == -1.
+  struct PhysRegSUOper {
+    SUnit *SU;
+    int OpIdx;
+    unsigned Reg;
+
+    PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {}
+
+    unsigned getSparseSetIndex() const { return Reg; }
+  };
+
+  /// Use a SparseMultiSet to track physical registers. Storage is only
+  /// allocated once for the pass. It can be cleared in constant time and reused
+  /// without any frees.
+  typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t>
+  Reg2SUnitsMap;
+
+  /// Use SparseSet as a SparseMap by relying on the fact that it never
+  /// compares ValueT's, only unsigned keys. This allows the set to be cleared
+  /// between scheduling regions in constant time as long as ValueT does not
+  /// require a destructor.
+  typedef SparseSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2SUnitMap;
+
+  /// Track local uses of virtual registers. These uses are gathered by the DAG
+  /// builder and may be consulted by the scheduler to avoid iterating an entire
+  /// vreg use list.
+  typedef SparseMultiSet<VReg2SUnit, VirtReg2IndexFunctor> VReg2UseMap;
+
+  /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
+  /// MachineInstrs.
+  class ScheduleDAGInstrs : public ScheduleDAG {
+  protected:
+    const MachineLoopInfo &MLI;
+    const MachineDominatorTree &MDT;
+    const MachineFrameInfo *MFI;
+
+    /// Live Intervals provides reaching defs in preRA scheduling.
+    LiveIntervals *LIS;
+
+    /// TargetSchedModel provides an interface to the machine model.
+    TargetSchedModel SchedModel;
+
+    /// isPostRA flag indicates vregs cannot be present.
+    bool IsPostRA;
+
+    /// True if the DAG builder should remove kill flags (in preparation for
+    /// rescheduling).
+    bool RemoveKillFlags;
+
+    /// The standard DAG builder does not normally include terminators as DAG
+    /// nodes because it does not create the necessary dependencies to prevent
+    /// reordering. A specialized scheduler can override
+    /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
+    /// it has taken responsibility for scheduling the terminator correctly.
+    bool CanHandleTerminators;
+
+    /// State specific to the current scheduling region.
+    /// ------------------------------------------------
+
+    /// The block in which to insert instructions
+    MachineBasicBlock *BB;
+
+    /// The beginning of the range to be scheduled.
+    MachineBasicBlock::iterator RegionBegin;
+
+    /// The end of the range to be scheduled.
+    MachineBasicBlock::iterator RegionEnd;
+
+    /// Instructions in this region (distance(RegionBegin, RegionEnd)).
+    unsigned NumRegionInstrs;
+
+    /// After calling BuildSchedGraph, each machine instruction in the current
+    /// scheduling region is mapped to an SUnit.
+    DenseMap<MachineInstr*, SUnit*> MISUnitMap;
+
+    /// After calling BuildSchedGraph, each vreg used in the scheduling region
+    /// is mapped to a set of SUnits. These include all local vreg uses, not
+    /// just the uses for a singly defined vreg.
+    VReg2UseMap VRegUses;
+
+    /// State internal to DAG building.
+    /// -------------------------------
+
+    /// Defs, Uses - Remember where defs and uses of each register are as we
+    /// iterate upward through the instructions. This is allocated here instead
+    /// of inside BuildSchedGraph to avoid the need for it to be initialized and
+    /// destructed for each block.
+    Reg2SUnitsMap Defs;
+    Reg2SUnitsMap Uses;
+
+    /// Track the last instruction in this region defining each virtual register.
+    VReg2SUnitMap VRegDefs;
+
+    /// PendingLoads - Remember where unknown loads are after the most recent
+    /// unknown store, as we iterate. As with Defs and Uses, this is here
+    /// to minimize construction/destruction.
+    std::vector<SUnit *> PendingLoads;
+
+    /// DbgValues - Remember instruction that precedes DBG_VALUE.
+    /// These are generated by buildSchedGraph but persist so they can be
+    /// referenced when emitting the final schedule.
+    typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
+      DbgValueVector;
+    DbgValueVector DbgValues;
+    MachineInstr *FirstDbgValue;
+
+    /// Set of live physical registers for updating kill flags.
+    BitVector LiveRegs;
+
+  public:
+    explicit ScheduleDAGInstrs(MachineFunction &mf,
+                               const MachineLoopInfo &mli,
+                               const MachineDominatorTree &mdt,
+                               bool IsPostRAFlag,
+                               bool RemoveKillFlags = false,
+                               LiveIntervals *LIS = nullptr);
+
+    virtual ~ScheduleDAGInstrs() {}
+
+    bool isPostRA() const { return IsPostRA; }
+
+    /// \brief Expose LiveIntervals for use in DAG mutators and such.
+    LiveIntervals *getLIS() const { return LIS; }
+
+    /// \brief Get the machine model for instruction scheduling.
+    const TargetSchedModel *getSchedModel() const { return &SchedModel; }
+
+    /// \brief Resolve and cache a resolved scheduling class for an SUnit.
+    const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
+      if (!SU->SchedClass && SchedModel.hasInstrSchedModel())
+        SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
+      return SU->SchedClass;
+    }
+
+    /// begin - Return an iterator to the top of the current scheduling region.
+    MachineBasicBlock::iterator begin() const { return RegionBegin; }
+
+    /// end - Return an iterator to the bottom of the current scheduling region.
+    MachineBasicBlock::iterator end() const { return RegionEnd; }
+
+    /// newSUnit - Creates a new SUnit and return a ptr to it.
+    SUnit *newSUnit(MachineInstr *MI);
+
+    /// getSUnit - Return an existing SUnit for this MI, or NULL.
+    SUnit *getSUnit(MachineInstr *MI) const;
+
+    /// startBlock - Prepare to perform scheduling in the given block.
+    virtual void startBlock(MachineBasicBlock *BB);
+
+    /// finishBlock - Clean up after scheduling in the given block.
+    virtual void finishBlock();
+
+    /// Initialize the scheduler state for the next scheduling region.
+    virtual void enterRegion(MachineBasicBlock *bb,
+                             MachineBasicBlock::iterator begin,
+                             MachineBasicBlock::iterator end,
+                             unsigned regioninstrs);
+
+    /// Notify that the scheduler has finished scheduling the current region.
+    virtual void exitRegion();
+
+    /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
+    /// input.
+    void buildSchedGraph(AliasAnalysis *AA,
+                         RegPressureTracker *RPTracker = nullptr,
+                         PressureDiffs *PDiffs = nullptr);
+
+    /// addSchedBarrierDeps - Add dependencies from instructions in the current
+    /// list of instructions being scheduled to scheduling barrier. We want to
+    /// make sure instructions which define registers that are either used by
+    /// the terminator or are live-out are properly scheduled. This is
+    /// especially important when the definition latency of the return value(s)
+    /// are too high to be hidden by the branch or when the liveout registers
+    /// used by instructions in the fallthrough block.
+    void addSchedBarrierDeps();
+
+    /// schedule - Order nodes according to selected style, filling
+    /// in the Sequence member.
+    ///
+    /// Typically, a scheduling algorithm will implement schedule() without
+    /// overriding enterRegion() or exitRegion().
+    virtual void schedule() = 0;
+
+    /// finalizeSchedule - Allow targets to perform final scheduling actions at
+    /// the level of the whole MachineFunction. By default does nothing.
+    virtual void finalizeSchedule() {}
+
+    void dumpNode(const SUnit *SU) const override;
+
+    /// Return a label for a DAG node that points to an instruction.
+    std::string getGraphNodeLabel(const SUnit *SU) const override;
+
+    /// Return a label for the region of code covered by the DAG.
+    std::string getDAGName() const override;
+
+    /// \brief Fix register kill flags that scheduling has made invalid.
+    void fixupKills(MachineBasicBlock *MBB);
+  protected:
+    void initSUnits();
+    void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
+    void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
+    void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
+    void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
+
+    /// \brief PostRA helper for rewriting kill flags.
+    void startBlockForKills(MachineBasicBlock *BB);
+
+    /// \brief Toggle a register operand kill flag.
+    ///
+    /// Other adjustments may be made to the instruction if necessary. Return
+    /// true if the operand has been deleted, false if not.
+    bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO);
+  };
+
+  /// newSUnit - Creates a new SUnit and return a ptr to it.
+  inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
+#ifndef NDEBUG
+    const SUnit *Addr = SUnits.empty() ? nullptr : &SUnits[0];
+#endif
+    SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
+    assert((Addr == nullptr || Addr == &SUnits[0]) &&
+           "SUnits std::vector reallocated on the fly!");
+    SUnits.back().OrigNode = &SUnits.back();
+    return &SUnits.back();
+  }
+
+  /// getSUnit - Return an existing SUnit for this MI, or NULL.
+  inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
+    DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
+    if (I == MISUnitMap.end())
+      return nullptr;
+    return I->second;
+  }
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h
new file mode 100644
index 0000000..b2108ad
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDFS.h
@@ -0,0 +1,194 @@
+//===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Definition of an ILP metric for machine level instruction scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDFS_H
+#define LLVM_CODEGEN_SCHEDULEDFS_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class raw_ostream;
+class IntEqClasses;
+class ScheduleDAGInstrs;
+class SUnit;
+
+/// \brief Represent the ILP of the subDAG rooted at a DAG node.
+///
+/// ILPValues summarize the DAG subtree rooted at each node. ILPValues are
+/// valid for all nodes regardless of their subtree membership.
+///
+/// When computed using bottom-up DFS, this metric assumes that the DAG is a
+/// forest of trees with roots at the bottom of the schedule branching upward.
+struct ILPValue {
+  unsigned InstrCount;
+  /// Length may either correspond to depth or height, depending on direction,
+  /// and cycles or nodes depending on context.
+  unsigned Length;
+
+  ILPValue(unsigned count, unsigned length):
+    InstrCount(count), Length(length) {}
+
+  // Order by the ILP metric's value.
+  bool operator<(ILPValue RHS) const {
+    return (uint64_t)InstrCount * RHS.Length
+      < (uint64_t)Length * RHS.InstrCount;
+  }
+  bool operator>(ILPValue RHS) const {
+    return RHS < *this;
+  }
+  bool operator<=(ILPValue RHS) const {
+    return (uint64_t)InstrCount * RHS.Length
+      <= (uint64_t)Length * RHS.InstrCount;
+  }
+  bool operator>=(ILPValue RHS) const {
+    return RHS <= *this;
+  }
+
+  void print(raw_ostream &OS) const;
+
+  void dump() const;
+};
+
+/// \brief Compute the values of each DAG node for various metrics during DFS.
+class SchedDFSResult {
+  friend class SchedDFSImpl;
+
+  static const unsigned InvalidSubtreeID = ~0u;
+
+  /// \brief Per-SUnit data computed during DFS for various metrics.
+  ///
+  /// A node's SubtreeID is set to itself when it is visited to indicate that it
+  /// is the root of a subtree. Later it is set to its parent to indicate an
+  /// interior node. Finally, it is set to a representative subtree ID during
+  /// finalization.
+  struct NodeData {
+    unsigned InstrCount;
+    unsigned SubtreeID;
+
+    NodeData(): InstrCount(0), SubtreeID(InvalidSubtreeID) {}
+  };
+
+  /// \brief Per-Subtree data computed during DFS.
+  struct TreeData {
+    unsigned ParentTreeID;
+    unsigned SubInstrCount;
+
+    TreeData(): ParentTreeID(InvalidSubtreeID), SubInstrCount(0) {}
+  };
+
+  /// \brief Record a connection between subtrees and the connection level.
+  struct Connection {
+    unsigned TreeID;
+    unsigned Level;
+
+    Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {}
+  };
+
+  bool IsBottomUp;
+  unsigned SubtreeLimit;
+  /// DFS results for each SUnit in this DAG.
+  std::vector<NodeData> DFSNodeData;
+
+  // Store per-tree data indexed on tree ID,
+  SmallVector<TreeData, 16> DFSTreeData;
+
+  // For each subtree discovered during DFS, record its connections to other
+  // subtrees.
+  std::vector<SmallVector<Connection, 4> > SubtreeConnections;
+
+  /// Cache the current connection level of each subtree.
+  /// This mutable array is updated during scheduling.
+  std::vector<unsigned> SubtreeConnectLevels;
+
+public:
+  SchedDFSResult(bool IsBU, unsigned lim)
+    : IsBottomUp(IsBU), SubtreeLimit(lim) {}
+
+  /// \brief Get the node cutoff before subtrees are considered significant.
+  unsigned getSubtreeLimit() const { return SubtreeLimit; }
+
+  /// \brief Return true if this DFSResult is uninitialized.
+  ///
+  /// resize() initializes DFSResult, while compute() populates it.
+  bool empty() const { return DFSNodeData.empty(); }
+
+  /// \brief Clear the results.
+  void clear() {
+    DFSNodeData.clear();
+    DFSTreeData.clear();
+    SubtreeConnections.clear();
+    SubtreeConnectLevels.clear();
+  }
+
+  /// \brief Initialize the result data with the size of the DAG.
+  void resize(unsigned NumSUnits) {
+    DFSNodeData.resize(NumSUnits);
+  }
+
+  /// \brief Compute various metrics for the DAG with given roots.
+  void compute(ArrayRef<SUnit> SUnits);
+
+  /// \brief Get the number of instructions in the given subtree and its
+  /// children.
+  unsigned getNumInstrs(const SUnit *SU) const {
+    return DFSNodeData[SU->NodeNum].InstrCount;
+  }
+
+  /// \brief Get the number of instructions in the given subtree not including
+  /// children.
+  unsigned getNumSubInstrs(unsigned SubtreeID) const {
+    return DFSTreeData[SubtreeID].SubInstrCount;
+  }
+
+  /// \brief Get the ILP value for a DAG node.
+  ///
+  /// A leaf node has an ILP of 1/1.
+  ILPValue getILP(const SUnit *SU) const {
+    return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
+  }
+
+  /// \brief The number of subtrees detected in this DAG.
+  unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); }
+
+  /// \brief Get the ID of the subtree the given DAG node belongs to.
+  ///
+  /// For convenience, if DFSResults have not been computed yet, give everything
+  /// tree ID 0.
+  unsigned getSubtreeID(const SUnit *SU) const {
+    if (empty())
+      return 0;
+    assert(SU->NodeNum < DFSNodeData.size() &&  "New Node");
+    return DFSNodeData[SU->NodeNum].SubtreeID;
+  }
+
+  /// \brief Get the connection level of a subtree.
+  ///
+  /// For bottom-up trees, the connection level is the latency depth (in cycles)
+  /// of the deepest connection to another subtree.
+  unsigned getSubtreeLevel(unsigned SubtreeID) const {
+    return SubtreeConnectLevels[SubtreeID];
+  }
+
+  /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is
+  /// initially scheduled.
+  void scheduleTree(unsigned SubtreeID);
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
new file mode 100644
index 0000000..8a40e72
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -0,0 +1,111 @@
+//=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
+//
+//                     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 ScheduleHazardRecognizer class, which implements
+// hazard-avoidance heuristics for scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
+
+namespace llvm {
+
+class SUnit;
+
+/// HazardRecognizer - This determines whether or not an instruction can be
+/// issued this cycle, and whether or not a noop needs to be inserted to handle
+/// the hazard.
+class ScheduleHazardRecognizer {
+protected:
+  /// MaxLookAhead - Indicate the number of cycles in the scoreboard
+  /// state. Important to restore the state after backtracking. Additionally,
+  /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
+  /// bypass virtual calls. Currently the PostRA scheduler ignores it.
+  unsigned MaxLookAhead;
+
+public:
+  ScheduleHazardRecognizer(): MaxLookAhead(0) {}
+  virtual ~ScheduleHazardRecognizer();
+
+  enum HazardType {
+    NoHazard,      // This instruction can be emitted at this cycle.
+    Hazard,        // This instruction can't be emitted at this cycle.
+    NoopHazard     // This instruction can't be emitted, and needs noops.
+  };
+
+  unsigned getMaxLookAhead() const { return MaxLookAhead; }
+
+  bool isEnabled() const { return MaxLookAhead != 0; }
+
+  /// atIssueLimit - Return true if no more instructions may be issued in this
+  /// cycle.
+  ///
+  /// FIXME: remove this once MachineScheduler is the only client.
+  virtual bool atIssueLimit() const { return false; }
+
+  /// getHazardType - Return the hazard type of emitting this node.  There are
+  /// three possible results.  Either:
+  ///  * NoHazard: it is legal to issue this instruction on this cycle.
+  ///  * Hazard: issuing this instruction would stall the machine.  If some
+  ///     other instruction is available, issue it first.
+  ///  * NoopHazard: issuing this instruction would break the program.  If
+  ///     some other instruction can be issued, do so, otherwise issue a noop.
+  virtual HazardType getHazardType(SUnit *m, int Stalls = 0) {
+    return NoHazard;
+  }
+
+  /// Reset - This callback is invoked when a new block of
+  /// instructions is about to be schedule. The hazard state should be
+  /// set to an initialized state.
+  virtual void Reset() {}
+
+  /// EmitInstruction - This callback is invoked when an instruction is
+  /// emitted, to advance the hazard state.
+  virtual void EmitInstruction(SUnit *) {}
+
+  /// PreEmitNoops - This callback is invoked prior to emitting an instruction.
+  /// It should return the number of noops to emit prior to the provided
+  /// instruction.
+  /// Note: This is only used during PostRA scheduling. EmitNoop is not called
+  /// for these noops.
+  virtual unsigned PreEmitNoops(SUnit *) {
+    return 0;
+  }
+
+  /// ShouldPreferAnother - This callback may be invoked if getHazardType
+  /// returns NoHazard. If, even though there is no hazard, it would be better to
+  /// schedule another available instruction, this callback should return true.
+  virtual bool ShouldPreferAnother(SUnit *) {
+    return false;
+  }
+
+  /// AdvanceCycle - This callback is invoked whenever the next top-down
+  /// instruction to be scheduled cannot issue in the current cycle, either
+  /// because of latency or resource conflicts.  This should increment the
+  /// internal state of the hazard recognizer so that previously "Hazard"
+  /// instructions will now not be hazards.
+  virtual void AdvanceCycle() {}
+
+  /// RecedeCycle - This callback is invoked whenever the next bottom-up
+  /// instruction to be scheduled cannot issue in the current cycle, either
+  /// because of latency or resource conflicts.
+  virtual void RecedeCycle() {}
+
+  /// EmitNoop - This callback is invoked when a noop was added to the
+  /// instruction stream.
+  virtual void EmitNoop() {
+    // Default implementation: count it as a cycle.
+    AdvanceCycle();
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
new file mode 100644
index 0000000..51ac7f2
--- /dev/null
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -0,0 +1,112 @@
+//===-- llvm/CodeGen/SchedulerRegistry.h ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for instruction scheduler function
+// pass registry (RegisterScheduler).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULERREGISTRY_H
+#define LLVM_CODEGEN_SCHEDULERREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterScheduler class - Track the registration of instruction schedulers.
+///
+//===----------------------------------------------------------------------===//
+
+class SelectionDAGISel;
+class ScheduleDAGSDNodes;
+class SelectionDAG;
+class MachineBasicBlock;
+
+class RegisterScheduler : public MachinePassRegistryNode {
+public:
+  typedef ScheduleDAGSDNodes *(*FunctionPassCtor)(SelectionDAGISel*,
+                                                  CodeGenOpt::Level);
+
+  static MachinePassRegistry Registry;
+
+  RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
+  : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+  { Registry.Add(this); }
+  ~RegisterScheduler() { Registry.Remove(this); }
+
+
+  // Accessors.
+  //
+  RegisterScheduler *getNext() const {
+    return (RegisterScheduler *)MachinePassRegistryNode::getNext();
+  }
+  static RegisterScheduler *getList() {
+    return (RegisterScheduler *)Registry.getList();
+  }
+  static FunctionPassCtor getDefault() {
+    return (FunctionPassCtor)Registry.getDefault();
+  }
+  static void setDefault(FunctionPassCtor C) {
+    Registry.setDefault((MachinePassCtor)C);
+  }
+  static void setListener(MachinePassRegistryListener *L) {
+    Registry.setListener(L);
+  }
+};
+
+/// createBURRListDAGScheduler - This creates a bottom up register usage
+/// reduction list scheduler.
+ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS,
+                                               CodeGenOpt::Level OptLevel);
+
+/// createBURRListDAGScheduler - This creates a bottom up list scheduler that
+/// schedules nodes in source code order when possible.
+ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
+                                                 CodeGenOpt::Level OptLevel);
+
+/// createHybridListDAGScheduler - This creates a bottom up register pressure
+/// aware list scheduler that make use of latency information to avoid stalls
+/// for long latency instructions in low register pressure mode. In high
+/// register pressure mode it schedules to reduce register pressure.
+ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS,
+                                                 CodeGenOpt::Level);
+
+/// createILPListDAGScheduler - This creates a bottom up register pressure
+/// aware list scheduler that tries to increase instruction level parallelism
+/// in low register pressure mode. In high register pressure mode it schedules
+/// to reduce register pressure.
+ScheduleDAGSDNodes *createILPListDAGScheduler(SelectionDAGISel *IS,
+                                              CodeGenOpt::Level);
+
+/// createFastDAGScheduler - This creates a "fast" scheduler.
+///
+ScheduleDAGSDNodes *createFastDAGScheduler(SelectionDAGISel *IS,
+                                           CodeGenOpt::Level OptLevel);
+
+/// createVLIWDAGScheduler - Scheduler for VLIW targets. This creates top down
+/// DFA driven list scheduler with clustering heuristic to control
+/// register pressure.
+ScheduleDAGSDNodes *createVLIWDAGScheduler(SelectionDAGISel *IS,
+                                           CodeGenOpt::Level OptLevel);
+/// createDefaultScheduler - This creates an instruction scheduler appropriate
+/// for the target.
+ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
+                                           CodeGenOpt::Level OptLevel);
+
+/// createDAGLinearizer - This creates a "no-scheduling" scheduler which
+/// linearize the DAG using topological order.
+ScheduleDAGSDNodes *createDAGLinearizer(SelectionDAGISel *IS,
+                                        CodeGenOpt::Level OptLevel);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
new file mode 100644
index 0000000..ab14c2d
--- /dev/null
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -0,0 +1,126 @@
+//=- llvm/CodeGen/ScoreboardHazardRecognizer.h - Schedule Support -*- 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 ScoreboardHazardRecognizer class, which
+// encapsulates hazard-avoidance heuristics for scheduling, based on the
+// scheduling itineraries specified for the target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+
+class InstrItineraryData;
+class ScheduleDAG;
+class SUnit;
+
+class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
+  // Scoreboard to track function unit usage. Scoreboard[0] is a
+  // mask of the FUs in use in the cycle currently being
+  // schedule. Scoreboard[1] is a mask for the next cycle. The
+  // Scoreboard is used as a circular buffer with the current cycle
+  // indicated by Head.
+  //
+  // Scoreboard always counts cycles in forward execution order. If used by a
+  // bottom-up scheduler, then the scoreboard cycles are the inverse of the
+  // scheduler's cycles.
+  class Scoreboard {
+    unsigned *Data;
+
+    // The maximum number of cycles monitored by the Scoreboard. This
+    // value is determined based on the target itineraries to ensure
+    // that all hazards can be tracked.
+    size_t Depth;
+    // Indices into the Scoreboard that represent the current cycle.
+    size_t Head;
+  public:
+    Scoreboard():Data(nullptr), Depth(0), Head(0) { }
+    ~Scoreboard() {
+      delete[] Data;
+    }
+
+    size_t getDepth() const { return Depth; }
+    unsigned& operator[](size_t idx) const {
+      // Depth is expected to be a power-of-2.
+      assert(Depth && !(Depth & (Depth - 1)) &&
+             "Scoreboard was not initialized properly!");
+
+      return Data[(Head + idx) & (Depth-1)];
+    }
+
+    void reset(size_t d = 1) {
+      if (!Data) {
+        Depth = d;
+        Data = new unsigned[Depth];
+      }
+
+      memset(Data, 0, Depth * sizeof(Data[0]));
+      Head = 0;
+    }
+
+    void advance() {
+      Head = (Head + 1) & (Depth-1);
+    }
+
+    void recede() {
+      Head = (Head - 1) & (Depth-1);
+    }
+
+    // Print the scoreboard.
+    void dump() const;
+  };
+
+#ifndef NDEBUG
+  // Support for tracing ScoreboardHazardRecognizer as a component within
+  // another module. Follows the current thread-unsafe model of tracing.
+  static const char *DebugType;
+#endif
+
+  // Itinerary data for the target.
+  const InstrItineraryData *ItinData;
+
+  const ScheduleDAG *DAG;
+
+  /// IssueWidth - Max issue per cycle. 0=Unknown.
+  unsigned IssueWidth;
+
+  /// IssueCount - Count instructions issued in this cycle.
+  unsigned IssueCount;
+
+  Scoreboard ReservedScoreboard;
+  Scoreboard RequiredScoreboard;
+
+public:
+  ScoreboardHazardRecognizer(const InstrItineraryData *ItinData,
+                             const ScheduleDAG *DAG,
+                             const char *ParentDebugType = "");
+
+  /// atIssueLimit - Return true if no more instructions may be issued in this
+  /// cycle.
+  bool atIssueLimit() const override;
+
+  // Stalls provides an cycle offset at which SU will be scheduled. It will be
+  // negative for bottom-up scheduling.
+  HazardType getHazardType(SUnit *SU, int Stalls) override;
+  void Reset() override;
+  void EmitInstruction(SUnit *SU) override;
+  void AdvanceCycle() override;
+  void RecedeCycle() override;
+};
+
+}
+
+#endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
new file mode 100644
index 0000000..bb87f82
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -0,0 +1,1244 @@
+//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ---------*- 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 SelectionDAG class, and transitively defines the
+// SDNode class and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_H
+#define LLVM_CODEGEN_SELECTIONDAG_H
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/DAGCombine.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cassert>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class AliasAnalysis;
+class MachineConstantPoolValue;
+class MachineFunction;
+class MDNode;
+class SDDbgValue;
+class TargetLowering;
+class TargetSelectionDAGInfo;
+
+class SDVTListNode : public FoldingSetNode {
+  friend struct FoldingSetTrait<SDVTListNode>;
+  /// FastID - A reference to an Interned FoldingSetNodeID for this node.
+  /// The Allocator in SelectionDAG holds the data.
+  /// SDVTList contains all types which are frequently accessed in SelectionDAG.
+  /// The size of this list is not expected big so it won't introduce memory penalty.
+  FoldingSetNodeIDRef FastID;
+  const EVT *VTs;
+  unsigned int NumVTs;
+  /// The hash value for SDVTList is fixed so cache it to avoid hash calculation
+  unsigned HashValue;
+public:
+  SDVTListNode(const FoldingSetNodeIDRef ID, const EVT *VT, unsigned int Num) :
+      FastID(ID), VTs(VT), NumVTs(Num) {
+    HashValue = ID.ComputeHash();
+  }
+  SDVTList getSDVTList() {
+    SDVTList result = {VTs, NumVTs};
+    return result;
+  }
+};
+
+// Specialize FoldingSetTrait for SDVTListNode
+// To avoid computing temp FoldingSetNodeID and hash value.
+template<> struct FoldingSetTrait<SDVTListNode> : DefaultFoldingSetTrait<SDVTListNode> {
+  static void Profile(const SDVTListNode &X, FoldingSetNodeID& ID) {
+    ID = X.FastID;
+  }
+  static bool Equals(const SDVTListNode &X, const FoldingSetNodeID &ID,
+                     unsigned IDHash, FoldingSetNodeID &TempID) {
+    if (X.HashValue != IDHash)
+      return false;
+    return ID == X.FastID;
+  }
+  static unsigned ComputeHash(const SDVTListNode &X, FoldingSetNodeID &TempID) {
+    return X.HashValue;
+  }
+};
+
+template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
+private:
+  mutable ilist_half_node<SDNode> Sentinel;
+public:
+  SDNode *createSentinel() const {
+    return static_cast<SDNode*>(&Sentinel);
+  }
+  static void destroySentinel(SDNode *) {}
+
+  SDNode *provideInitialHead() const { return createSentinel(); }
+  SDNode *ensureHead(SDNode*) const { return createSentinel(); }
+  static void noteHead(SDNode*, SDNode*) {}
+
+  static void deleteNode(SDNode *) {
+    llvm_unreachable("ilist_traits<SDNode> shouldn't see a deleteNode call!");
+  }
+private:
+  static void createNode(const SDNode &);
+};
+
+/// SDDbgInfo - Keeps track of dbg_value information through SDISel.  We do
+/// not build SDNodes for these so as not to perturb the generated code;
+/// instead the info is kept off to the side in this structure. Each SDNode may
+/// have one or more associated dbg_value entries. This information is kept in
+/// DbgValMap.
+/// Byval parameters are handled separately because they don't use alloca's,
+/// which busts the normal mechanism.  There is good reason for handling all
+/// parameters separately:  they may not have code generated for them, they
+/// should always go at the beginning of the function regardless of other code
+/// motion, and debug info for them is potentially useful even if the parameter
+/// is unused.  Right now only byval parameters are handled separately.
+class SDDbgInfo {
+  SmallVector<SDDbgValue*, 32> DbgValues;
+  SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
+  typedef DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMapType;
+  DbgValMapType DbgValMap;
+
+  void operator=(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
+  SDDbgInfo(const SDDbgInfo&) LLVM_DELETED_FUNCTION;
+public:
+  SDDbgInfo() {}
+
+  void add(SDDbgValue *V, const SDNode *Node, bool isParameter) {
+    if (isParameter) {
+      ByvalParmDbgValues.push_back(V);
+    } else     DbgValues.push_back(V);
+    if (Node)
+      DbgValMap[Node].push_back(V);
+  }
+
+  void clear() {
+    DbgValMap.clear();
+    DbgValues.clear();
+    ByvalParmDbgValues.clear();
+  }
+
+  bool empty() const {
+    return DbgValues.empty() && ByvalParmDbgValues.empty();
+  }
+
+  ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
+    DbgValMapType::iterator I = DbgValMap.find(Node);
+    if (I != DbgValMap.end())
+      return I->second;
+    return ArrayRef<SDDbgValue*>();
+  }
+
+  typedef SmallVectorImpl<SDDbgValue*>::iterator DbgIterator;
+  DbgIterator DbgBegin() { return DbgValues.begin(); }
+  DbgIterator DbgEnd()   { return DbgValues.end(); }
+  DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
+  DbgIterator ByvalParmDbgEnd()   { return ByvalParmDbgValues.end(); }
+};
+
+class SelectionDAG;
+void checkForCycles(const SelectionDAG *DAG, bool force = false);
+
+/// SelectionDAG class - This is used to represent a portion of an LLVM function
+/// in a low-level Data Dependence DAG representation suitable for instruction
+/// selection.  This DAG is constructed as the first step of instruction
+/// selection in order to allow implementation of machine specific optimizations
+/// and code simplifications.
+///
+/// The representation used by the SelectionDAG is a target-independent
+/// representation, which has some similarities to the GCC RTL representation,
+/// but is significantly more simple, powerful, and is a graph form instead of a
+/// linear form.
+///
+class SelectionDAG {
+  const TargetMachine &TM;
+  const TargetSelectionDAGInfo &TSI;
+  const TargetLowering *TLI;
+  MachineFunction *MF;
+  LLVMContext *Context;
+  CodeGenOpt::Level OptLevel;
+
+  /// EntryNode - The starting token.
+  SDNode EntryNode;
+
+  /// Root - The root of the entire DAG.
+  SDValue Root;
+
+  /// AllNodes - A linked list of nodes in the current DAG.
+  ilist<SDNode> AllNodes;
+
+  /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use
+  /// pool allocation with recycling.
+  typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
+                             AlignOf<MostAlignedSDNode>::Alignment>
+    NodeAllocatorType;
+
+  /// NodeAllocator - Pool allocation for nodes.
+  NodeAllocatorType NodeAllocator;
+
+  /// CSEMap - This structure is used to memoize nodes, automatically performing
+  /// CSE with existing nodes when a duplicate is requested.
+  FoldingSet<SDNode> CSEMap;
+
+  /// OperandAllocator - Pool allocation for machine-opcode SDNode operands.
+  BumpPtrAllocator OperandAllocator;
+
+  /// Allocator - Pool allocation for misc. objects that are created once per
+  /// SelectionDAG.
+  BumpPtrAllocator Allocator;
+
+  /// DbgInfo - Tracks dbg_value information through SDISel.
+  SDDbgInfo *DbgInfo;
+
+public:
+  /// DAGUpdateListener - Clients of various APIs that cause global effects on
+  /// the DAG can optionally implement this interface.  This allows the clients
+  /// to handle the various sorts of updates that happen.
+  ///
+  /// A DAGUpdateListener automatically registers itself with DAG when it is
+  /// constructed, and removes itself when destroyed in RAII fashion.
+  struct DAGUpdateListener {
+    DAGUpdateListener *const Next;
+    SelectionDAG &DAG;
+
+    explicit DAGUpdateListener(SelectionDAG &D)
+      : Next(D.UpdateListeners), DAG(D) {
+      DAG.UpdateListeners = this;
+    }
+
+    virtual ~DAGUpdateListener() {
+      assert(DAG.UpdateListeners == this &&
+             "DAGUpdateListeners must be destroyed in LIFO order");
+      DAG.UpdateListeners = Next;
+    }
+
+    /// NodeDeleted - The node N that was deleted and, if E is not null, an
+    /// equivalent node E that replaced it.
+    virtual void NodeDeleted(SDNode *N, SDNode *E);
+
+    /// NodeUpdated - The node N that was updated.
+    virtual void NodeUpdated(SDNode *N);
+  };
+
+  /// NewNodesMustHaveLegalTypes - When true, additional steps are taken to
+  /// ensure that getConstant() and similar functions return DAG nodes that
+  /// have legal types. This is important after type legalization since
+  /// any illegally typed nodes generated after this point will not experience
+  /// type legalization.
+  bool NewNodesMustHaveLegalTypes;
+
+private:
+  /// DAGUpdateListener is a friend so it can manipulate the listener stack.
+  friend struct DAGUpdateListener;
+
+  /// UpdateListeners - Linked list of registered DAGUpdateListener instances.
+  /// This stack is maintained by DAGUpdateListener RAII.
+  DAGUpdateListener *UpdateListeners;
+
+  /// setGraphColorHelper - Implementation of setSubgraphColor.
+  /// Return whether we had to truncate the search.
+  ///
+  bool setSubgraphColorHelper(SDNode *N, const char *Color,
+                              DenseSet<SDNode *> &visited,
+                              int level, bool &printed);
+
+  void operator=(const SelectionDAG&) LLVM_DELETED_FUNCTION;
+  SelectionDAG(const SelectionDAG&) LLVM_DELETED_FUNCTION;
+
+public:
+  explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
+  ~SelectionDAG();
+
+  /// init - Prepare this SelectionDAG to process code in the given
+  /// MachineFunction.
+  ///
+  void init(MachineFunction &mf, const TargetLowering *TLI);
+
+  /// clear - Clear state and free memory necessary to make this
+  /// SelectionDAG ready to process a new block.
+  ///
+  void clear();
+
+  MachineFunction &getMachineFunction() const { return *MF; }
+  const TargetMachine &getTarget() const { return TM; }
+  const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
+  const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
+  LLVMContext *getContext() const {return Context; }
+
+  /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
+  ///
+  void viewGraph(const std::string &Title);
+  void viewGraph();
+
+#ifndef NDEBUG
+  std::map<const SDNode *, std::string> NodeGraphAttrs;
+#endif
+
+  /// clearGraphAttrs - Clear all previously defined node graph attributes.
+  /// Intended to be used from a debugging tool (eg. gdb).
+  void clearGraphAttrs();
+
+  /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
+  ///
+  void setGraphAttrs(const SDNode *N, const char *Attrs);
+
+  /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
+  /// Used from getNodeAttributes.
+  const std::string getGraphAttrs(const SDNode *N) const;
+
+  /// setGraphColor - Convenience for setting node color attribute.
+  ///
+  void setGraphColor(const SDNode *N, const char *Color);
+
+  /// setGraphColor - Convenience for setting subgraph color attribute.
+  ///
+  void setSubgraphColor(SDNode *N, const char *Color);
+
+  typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
+  allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
+  allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
+  typedef ilist<SDNode>::iterator allnodes_iterator;
+  allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
+  allnodes_iterator allnodes_end() { return AllNodes.end(); }
+  ilist<SDNode>::size_type allnodes_size() const {
+    return AllNodes.size();
+  }
+
+  /// getRoot - Return the root tag of the SelectionDAG.
+  ///
+  const SDValue &getRoot() const { return Root; }
+
+  /// getEntryNode - Return the token chain corresponding to the entry of the
+  /// function.
+  SDValue getEntryNode() const {
+    return SDValue(const_cast<SDNode *>(&EntryNode), 0);
+  }
+
+  /// setRoot - Set the current root tag of the SelectionDAG.
+  ///
+  const SDValue &setRoot(SDValue N) {
+    assert((!N.getNode() || N.getValueType() == MVT::Other) &&
+           "DAG root value is not a chain!");
+    if (N.getNode())
+      checkForCycles(N.getNode(), this);
+    Root = N;
+    if (N.getNode())
+      checkForCycles(this);
+    return Root;
+  }
+
+  /// Combine - This iterates over the nodes in the SelectionDAG, folding
+  /// certain types of nodes together, or eliminating superfluous nodes.  The
+  /// Level argument controls whether Combine is allowed to produce nodes and
+  /// types that are illegal on the target.
+  void Combine(CombineLevel Level, AliasAnalysis &AA,
+               CodeGenOpt::Level OptLevel);
+
+  /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
+  /// only uses types natively supported by the target.  Returns "true" if it
+  /// made any changes.
+  ///
+  /// Note that this is an involved process that may invalidate pointers into
+  /// the graph.
+  bool LegalizeTypes();
+
+  /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
+  /// compatible with the target instruction selector, as indicated by the
+  /// TargetLowering object.
+  ///
+  /// Note that this is an involved process that may invalidate pointers into
+  /// the graph.
+  void Legalize();
+
+  /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
+  /// that only uses vector math operations supported by the target.  This is
+  /// necessary as a separate step from Legalize because unrolling a vector
+  /// operation can introduce illegal types, which requires running
+  /// LegalizeTypes again.
+  ///
+  /// This returns true if it made any changes; in that case, LegalizeTypes
+  /// is called again before Legalize.
+  ///
+  /// Note that this is an involved process that may invalidate pointers into
+  /// the graph.
+  bool LegalizeVectors();
+
+  /// RemoveDeadNodes - This method deletes all unreachable nodes in the
+  /// SelectionDAG.
+  void RemoveDeadNodes();
+
+  /// DeleteNode - Remove the specified node from the system.  This node must
+  /// have no referrers.
+  void DeleteNode(SDNode *N);
+
+  /// getVTList - Return an SDVTList that represents the list of values
+  /// specified.
+  SDVTList getVTList(EVT VT);
+  SDVTList getVTList(EVT VT1, EVT VT2);
+  SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3);
+  SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4);
+  SDVTList getVTList(ArrayRef<EVT> VTs);
+
+  //===--------------------------------------------------------------------===//
+  // Node creation methods.
+  //
+  SDValue getConstant(uint64_t Val, EVT VT, bool isTarget = false,
+                      bool isOpaque = false);
+  SDValue getConstant(const APInt &Val, EVT VT, bool isTarget = false,
+                      bool isOpaque = false);
+  SDValue getConstant(const ConstantInt &Val, EVT VT, bool isTarget = false,
+                      bool isOpaque = false);
+  SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false);
+  SDValue getTargetConstant(uint64_t Val, EVT VT, bool isOpaque = false) {
+    return getConstant(Val, VT, true, isOpaque);
+  }
+  SDValue getTargetConstant(const APInt &Val, EVT VT, bool isOpaque = false) {
+    return getConstant(Val, VT, true, isOpaque);
+  }
+  SDValue getTargetConstant(const ConstantInt &Val, EVT VT,
+                            bool isOpaque = false) {
+    return getConstant(Val, VT, true, isOpaque);
+  }
+  // The forms below that take a double should only be used for simple
+  // constants that can be exactly represented in VT.  No checks are made.
+  SDValue getConstantFP(double Val, EVT VT, bool isTarget = false);
+  SDValue getConstantFP(const APFloat& Val, EVT VT, bool isTarget = false);
+  SDValue getConstantFP(const ConstantFP &CF, EVT VT, bool isTarget = false);
+  SDValue getTargetConstantFP(double Val, EVT VT) {
+    return getConstantFP(Val, VT, true);
+  }
+  SDValue getTargetConstantFP(const APFloat& Val, EVT VT) {
+    return getConstantFP(Val, VT, true);
+  }
+  SDValue getTargetConstantFP(const ConstantFP &Val, EVT VT) {
+    return getConstantFP(Val, VT, true);
+  }
+  SDValue getGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT,
+                           int64_t offset = 0, bool isTargetGA = false,
+                           unsigned char TargetFlags = 0);
+  SDValue getTargetGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT,
+                                 int64_t offset = 0,
+                                 unsigned char TargetFlags = 0) {
+    return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
+  }
+  SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
+  SDValue getTargetFrameIndex(int FI, EVT VT) {
+    return getFrameIndex(FI, VT, true);
+  }
+  SDValue getJumpTable(int JTI, EVT VT, bool isTarget = false,
+                       unsigned char TargetFlags = 0);
+  SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags = 0) {
+    return getJumpTable(JTI, VT, true, TargetFlags);
+  }
+  SDValue getConstantPool(const Constant *C, EVT VT,
+                          unsigned Align = 0, int Offs = 0, bool isT=false,
+                          unsigned char TargetFlags = 0);
+  SDValue getTargetConstantPool(const Constant *C, EVT VT,
+                                unsigned Align = 0, int Offset = 0,
+                                unsigned char TargetFlags = 0) {
+    return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
+  }
+  SDValue getConstantPool(MachineConstantPoolValue *C, EVT VT,
+                          unsigned Align = 0, int Offs = 0, bool isT=false,
+                          unsigned char TargetFlags = 0);
+  SDValue getTargetConstantPool(MachineConstantPoolValue *C,
+                                  EVT VT, unsigned Align = 0,
+                                  int Offset = 0, unsigned char TargetFlags=0) {
+    return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
+  }
+  SDValue getTargetIndex(int Index, EVT VT, int64_t Offset = 0,
+                         unsigned char TargetFlags = 0);
+  // When generating a branch to a BB, we don't in general know enough
+  // to provide debug info for the BB at that time, so keep this one around.
+  SDValue getBasicBlock(MachineBasicBlock *MBB);
+  SDValue getBasicBlock(MachineBasicBlock *MBB, SDLoc dl);
+  SDValue getExternalSymbol(const char *Sym, EVT VT);
+  SDValue getExternalSymbol(const char *Sym, SDLoc dl, EVT VT);
+  SDValue getTargetExternalSymbol(const char *Sym, EVT VT,
+                                  unsigned char TargetFlags = 0);
+  SDValue getValueType(EVT);
+  SDValue getRegister(unsigned Reg, EVT VT);
+  SDValue getRegisterMask(const uint32_t *RegMask);
+  SDValue getEHLabel(SDLoc dl, SDValue Root, MCSymbol *Label);
+  SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
+                          int64_t Offset = 0, bool isTarget = false,
+                          unsigned char TargetFlags = 0);
+  SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT,
+                                int64_t Offset = 0,
+                                unsigned char TargetFlags = 0) {
+    return getBlockAddress(BA, VT, Offset, true, TargetFlags);
+  }
+
+  SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N) {
+    return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
+                   getRegister(Reg, N.getValueType()), N);
+  }
+
+  // This version of the getCopyToReg method takes an extra operand, which
+  // indicates that there is potentially an incoming glue value (if Glue is not
+  // null) and that there should be a glue result.
+  SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N,
+                       SDValue Glue) {
+    SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+    SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue };
+    return getNode(ISD::CopyToReg, dl, VTs,
+                   ArrayRef<SDValue>(Ops, Glue.getNode() ? 4 : 3));
+  }
+
+  // Similar to last getCopyToReg() except parameter Reg is a SDValue
+  SDValue getCopyToReg(SDValue Chain, SDLoc dl, SDValue Reg, SDValue N,
+                         SDValue Glue) {
+    SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+    SDValue Ops[] = { Chain, Reg, N, Glue };
+    return getNode(ISD::CopyToReg, dl, VTs,
+                   ArrayRef<SDValue>(Ops, Glue.getNode() ? 4 : 3));
+  }
+
+  SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT) {
+    SDVTList VTs = getVTList(VT, MVT::Other);
+    SDValue Ops[] = { Chain, getRegister(Reg, VT) };
+    return getNode(ISD::CopyFromReg, dl, VTs, Ops);
+  }
+
+  // This version of the getCopyFromReg method takes an extra operand, which
+  // indicates that there is potentially an incoming glue value (if Glue is not
+  // null) and that there should be a glue result.
+  SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT,
+                           SDValue Glue) {
+    SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue);
+    SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue };
+    return getNode(ISD::CopyFromReg, dl, VTs,
+                   ArrayRef<SDValue>(Ops, Glue.getNode() ? 3 : 2));
+  }
+
+  SDValue getCondCode(ISD::CondCode Cond);
+
+  /// Returns the ConvertRndSat Note: Avoid using this node because it may
+  /// disappear in the future and most targets don't support it.
+  SDValue getConvertRndSat(EVT VT, SDLoc dl, SDValue Val, SDValue DTy,
+                           SDValue STy,
+                           SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
+
+  /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node.  The number of
+  /// elements in VT, which must be a vector type, must match the number of
+  /// mask elements NumElts.  A integer mask element equal to -1 is treated as
+  /// undefined.
+  SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
+                           const int *MaskElts);
+  SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2,
+                           ArrayRef<int> MaskElts) {
+    assert(VT.getVectorNumElements() == MaskElts.size() &&
+           "Must have the same number of vector elements as mask elements!");
+    return getVectorShuffle(VT, dl, N1, N2, MaskElts.data());
+  }
+
+  /// \brief Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to
+  /// the shuffle node in input but with swapped operands.
+  ///
+  /// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3>
+  SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV);
+
+  /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
+  /// integer type VT, by either any-extending or truncating it.
+  SDValue getAnyExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getSExtOrTrunc - Convert Op, which must be of integer type, to the
+  /// integer type VT, by either sign-extending or truncating it.
+  SDValue getSExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getZExtOrTrunc - Convert Op, which must be of integer type, to the
+  /// integer type VT, by either zero-extending or truncating it.
+  SDValue getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getZeroExtendInReg - Return the expression required to zero extend the Op
+  /// value assuming it was the smaller SrcTy value.
+  SDValue getZeroExtendInReg(SDValue Op, SDLoc DL, EVT SrcTy);
+
+  /// getAnyExtendVectorInReg - Return an operation which will any-extend the
+  /// low lanes of the operand into the specified vector type. For example,
+  /// this can convert a v16i8 into a v4i32 by any-extending the low four
+  /// lanes of the operand from i8 to i32.
+  SDValue getAnyExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getSignExtendVectorInReg - Return an operation which will sign extend the
+  /// low lanes of the operand into the specified vector type. For example,
+  /// this can convert a v16i8 into a v4i32 by sign extending the low four
+  /// lanes of the operand from i8 to i32.
+  SDValue getSignExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getZeroExtendVectorInReg - Return an operation which will zero extend the
+  /// low lanes of the operand into the specified vector type. For example,
+  /// this can convert a v16i8 into a v4i32 by zero extending the low four
+  /// lanes of the operand from i8 to i32.
+  SDValue getZeroExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT);
+
+  /// getBoolExtOrTrunc - Convert Op, which must be of integer type, to the
+  /// integer type VT, by using an extension appropriate for the target's
+  /// BooleanContent for type OpVT or truncating it.
+  SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT, EVT OpVT);
+
+  /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
+  SDValue getNOT(SDLoc DL, SDValue Val, EVT VT);
+
+  /// \brief Create a logical NOT operation as (XOR Val, BooleanOne).
+  SDValue getLogicalNOT(SDLoc DL, SDValue Val, EVT VT);
+
+  /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
+  /// a glue result (to ensure it's not CSE'd).  CALLSEQ_START does not have a
+  /// useful SDLoc.
+  SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, SDLoc DL) {
+    SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+    SDValue Ops[] = { Chain,  Op };
+    return getNode(ISD::CALLSEQ_START, DL, VTs, Ops);
+  }
+
+  /// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
+  /// glue result (to ensure it's not CSE'd).  CALLSEQ_END does not have
+  /// a useful SDLoc.
+  SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
+                           SDValue InGlue, SDLoc DL) {
+    SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue);
+    SmallVector<SDValue, 4> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(Op1);
+    Ops.push_back(Op2);
+    if (InGlue.getNode())
+      Ops.push_back(InGlue);
+    return getNode(ISD::CALLSEQ_END, DL, NodeTys, Ops);
+  }
+
+  /// getUNDEF - Return an UNDEF node.  UNDEF does not have a useful SDLoc.
+  SDValue getUNDEF(EVT VT) {
+    return getNode(ISD::UNDEF, SDLoc(), VT);
+  }
+
+  /// getGLOBAL_OFFSET_TABLE - Return a GLOBAL_OFFSET_TABLE node.  This does
+  /// not have a useful SDLoc.
+  SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
+    return getNode(ISD::GLOBAL_OFFSET_TABLE, SDLoc(), VT);
+  }
+
+  /// getNode - Gets or creates the specified node.
+  ///
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+                  bool nuw = false, bool nsw = false, bool exact = false);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+                  SDValue N3);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+                  SDValue N3, SDValue N4);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2,
+                  SDValue N3, SDValue N4, SDValue N5);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, ArrayRef<SDUse> Ops);
+  SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT,
+                  ArrayRef<SDValue> Ops);
+  SDValue getNode(unsigned Opcode, SDLoc DL,
+                  ArrayRef<EVT> ResultTys,
+                  ArrayRef<SDValue> Ops);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                  ArrayRef<SDValue> Ops);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                  SDValue N1, SDValue N2);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                  SDValue N1, SDValue N2, SDValue N3);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                  SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+  SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                  SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+                  SDValue N5);
+
+  /// getStackArgumentTokenFactor - Compute a TokenFactor to force all
+  /// the incoming stack arguments to be loaded from the stack. This is
+  /// used in tail call lowering to protect stack arguments from being
+  /// clobbered.
+  SDValue getStackArgumentTokenFactor(SDValue Chain);
+
+  SDValue getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
+                    SDValue Size, unsigned Align, bool isVol, bool AlwaysInline,
+                    MachinePointerInfo DstPtrInfo,
+                    MachinePointerInfo SrcPtrInfo);
+
+  SDValue getMemmove(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
+                     SDValue Size, unsigned Align, bool isVol,
+                     MachinePointerInfo DstPtrInfo,
+                     MachinePointerInfo SrcPtrInfo);
+
+  SDValue getMemset(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src,
+                    SDValue Size, unsigned Align, bool isVol,
+                    MachinePointerInfo DstPtrInfo);
+
+  /// getSetCC - Helper function to make it easier to build SetCC's if you just
+  /// have an ISD::CondCode instead of an SDValue.
+  ///
+  SDValue getSetCC(SDLoc DL, EVT VT, SDValue LHS, SDValue RHS,
+                   ISD::CondCode Cond) {
+    assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
+      "Cannot compare scalars to vectors");
+    assert(LHS.getValueType().isVector() == VT.isVector() &&
+      "Cannot compare scalars to vectors");
+    assert(Cond != ISD::SETCC_INVALID &&
+        "Cannot create a setCC of an invalid node.");
+    return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
+  }
+
+  // getSelect - Helper function to make it easier to build Select's if you just
+  // have operands and don't want to check for vector.
+  SDValue getSelect(SDLoc DL, EVT VT, SDValue Cond,
+                    SDValue LHS, SDValue RHS) {
+    assert(LHS.getValueType() == RHS.getValueType() &&
+           "Cannot use select on differing types");
+    assert(VT.isVector() == LHS.getValueType().isVector() &&
+           "Cannot mix vectors and scalars");
+    return getNode(Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT, DL, VT,
+                   Cond, LHS, RHS);
+  }
+
+  /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+  /// just have an ISD::CondCode instead of an SDValue.
+  ///
+  SDValue getSelectCC(SDLoc DL, SDValue LHS, SDValue RHS,
+                      SDValue True, SDValue False, ISD::CondCode Cond) {
+    return getNode(ISD::SELECT_CC, DL, True.getValueType(),
+                   LHS, RHS, True, False, getCondCode(Cond));
+  }
+
+  /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+  /// and a source value as input.
+  SDValue getVAArg(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
+                   SDValue SV, unsigned Align);
+
+  /// getAtomicCmpSwap - Gets a node for an atomic cmpxchg op. There are two
+  /// valid Opcodes. ISD::ATOMIC_CMO_SWAP produces a the value loaded and a
+  /// chain result. ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS produces the value loaded,
+  /// a success flag (initially i1), and a chain.
+  SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs,
+                           SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+                           MachinePointerInfo PtrInfo, unsigned Alignment,
+                           AtomicOrdering SuccessOrdering,
+                           AtomicOrdering FailureOrdering,
+                           SynchronizationScope SynchScope);
+  SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs,
+                           SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+                           MachineMemOperand *MMO,
+                           AtomicOrdering SuccessOrdering,
+                           AtomicOrdering FailureOrdering,
+                           SynchronizationScope SynchScope);
+
+  /// getAtomic - Gets a node for an atomic op, produces result (if relevant)
+  /// and chain and takes 2 operands.
+  SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
+                    SDValue Ptr, SDValue Val, const Value *PtrVal,
+                    unsigned Alignment, AtomicOrdering Ordering,
+                    SynchronizationScope SynchScope);
+  SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
+                    SDValue Ptr, SDValue Val, MachineMemOperand *MMO,
+                    AtomicOrdering Ordering,
+                    SynchronizationScope SynchScope);
+
+  /// getAtomic - Gets a node for an atomic op, produces result and chain and
+  /// takes 1 operand.
+  SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, EVT VT,
+                    SDValue Chain, SDValue Ptr, MachineMemOperand *MMO,
+                    AtomicOrdering Ordering,
+                    SynchronizationScope SynchScope);
+
+  /// getAtomic - Gets a node for an atomic op, produces result and chain and
+  /// takes N operands.
+  SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
+                    ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
+                    AtomicOrdering SuccessOrdering,
+                    AtomicOrdering FailureOrdering,
+                    SynchronizationScope SynchScope);
+  SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
+                    ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
+                    AtomicOrdering Ordering, SynchronizationScope SynchScope);
+
+  /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
+  /// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
+  /// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
+  /// less than FIRST_TARGET_MEMORY_OPCODE.
+  SDValue getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList,
+                              ArrayRef<SDValue> Ops,
+                              EVT MemVT, MachinePointerInfo PtrInfo,
+                              unsigned Align = 0, bool Vol = false,
+                              bool ReadMem = true, bool WriteMem = true);
+
+  SDValue getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList,
+                              ArrayRef<SDValue> Ops,
+                              EVT MemVT, MachineMemOperand *MMO);
+
+  /// getMergeValues - Create a MERGE_VALUES node from the given operands.
+  SDValue getMergeValues(ArrayRef<SDValue> Ops, SDLoc dl);
+
+  /// getLoad - Loads are not normal binary operators: their result type is not
+  /// determined by their operands, and they produce a value AND a token chain.
+  ///
+  SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
+                  MachinePointerInfo PtrInfo, bool isVolatile,
+                  bool isNonTemporal, bool isInvariant, unsigned Alignment,
+                  const MDNode *TBAAInfo = nullptr,
+                  const MDNode *Ranges = nullptr);
+  SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
+                  MachineMemOperand *MMO);
+  SDValue getExtLoad(ISD::LoadExtType ExtType, SDLoc dl, EVT VT,
+                     SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo,
+                     EVT MemVT, bool isVolatile,
+                     bool isNonTemporal, unsigned Alignment,
+                     const MDNode *TBAAInfo = nullptr);
+  SDValue getExtLoad(ISD::LoadExtType ExtType, SDLoc dl, EVT VT,
+                     SDValue Chain, SDValue Ptr, EVT MemVT,
+                     MachineMemOperand *MMO);
+  SDValue getIndexedLoad(SDValue OrigLoad, SDLoc dl, SDValue Base,
+                         SDValue Offset, ISD::MemIndexedMode AM);
+  SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+                  EVT VT, SDLoc dl,
+                  SDValue Chain, SDValue Ptr, SDValue Offset,
+                  MachinePointerInfo PtrInfo, EVT MemVT,
+                  bool isVolatile, bool isNonTemporal, bool isInvariant,
+                  unsigned Alignment, const MDNode *TBAAInfo = nullptr,
+                  const MDNode *Ranges = nullptr);
+  SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+                  EVT VT, SDLoc dl,
+                  SDValue Chain, SDValue Ptr, SDValue Offset,
+                  EVT MemVT, MachineMemOperand *MMO);
+
+  /// getStore - Helper function to build ISD::STORE nodes.
+  ///
+  SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr,
+                   MachinePointerInfo PtrInfo, bool isVolatile,
+                   bool isNonTemporal, unsigned Alignment,
+                   const MDNode *TBAAInfo = nullptr);
+  SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr,
+                   MachineMemOperand *MMO);
+  SDValue getTruncStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr,
+                        MachinePointerInfo PtrInfo, EVT TVT,
+                        bool isNonTemporal, bool isVolatile,
+                        unsigned Alignment,
+                        const MDNode *TBAAInfo = nullptr);
+  SDValue getTruncStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr,
+                        EVT TVT, MachineMemOperand *MMO);
+  SDValue getIndexedStore(SDValue OrigStoe, SDLoc dl, SDValue Base,
+                           SDValue Offset, ISD::MemIndexedMode AM);
+
+  /// getSrcValue - Construct a node to track a Value* through the backend.
+  SDValue getSrcValue(const Value *v);
+
+  /// getMDNode - Return an MDNodeSDNode which holds an MDNode.
+  SDValue getMDNode(const MDNode *MD);
+
+  /// getAddrSpaceCast - Return an AddrSpaceCastSDNode.
+  SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,
+                           unsigned SrcAS, unsigned DestAS);
+
+  /// getShiftAmountOperand - Return the specified value casted to
+  /// the target's desired shift amount type.
+  SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
+
+  /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+  /// specified operands.  If the resultant node already exists in the DAG,
+  /// this does not modify the specified node, instead it returns the node that
+  /// already exists.  If the resultant node does not exist in the DAG, the
+  /// input node is returned.  As a degenerate case, if you specify the same
+  /// input operands as the node already has, the input node is returned.
+  SDNode *UpdateNodeOperands(SDNode *N, SDValue Op);
+  SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2);
+  SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+                               SDValue Op3);
+  SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+                               SDValue Op3, SDValue Op4);
+  SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+                               SDValue Op3, SDValue Op4, SDValue Op5);
+  SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
+
+  /// SelectNodeTo - These are used for target selectors to *mutate* the
+  /// specified node to have the specified return type, Target opcode, and
+  /// operands.  Note that target opcodes are stored as
+  /// ~TargetOpcode in the node opcode field.  The resultant node is returned.
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT, SDValue Op1);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+                       SDValue Op1, SDValue Op2);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+                       SDValue Op1, SDValue Op2, SDValue Op3);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+                       ArrayRef<SDValue> Ops);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1, EVT VT2);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, ArrayRef<SDValue> Ops);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, EVT VT3, ArrayRef<SDValue> Ops);
+  SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1,
+                       EVT VT2, EVT VT3, EVT VT4, ArrayRef<SDValue> Ops);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, SDValue Op1);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, SDValue Op1, SDValue Op2);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+                       EVT VT2, EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3);
+  SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs,
+                       ArrayRef<SDValue> Ops);
+
+  /// MorphNodeTo - This *mutates* the specified node to have the specified
+  /// return type, opcode, and operands.
+  SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
+                      ArrayRef<SDValue> Ops);
+
+  /// getMachineNode - These are used for target selectors to create a new node
+  /// with specified return type(s), MachineInstr opcode, and operands.
+  ///
+  /// Note that getMachineNode returns the resultant node.  If there is already
+  /// a node of the specified opcode and operands, it returns that node instead
+  /// of the current one.
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT,
+                                SDValue Op1);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT,
+                                SDValue Op1, SDValue Op2);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT,
+                                SDValue Op1, SDValue Op2, SDValue Op3);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT,
+                                ArrayRef<SDValue> Ops);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                SDValue Op1);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                SDValue Op1, SDValue Op2);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                SDValue Op1, SDValue Op2, SDValue Op3);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                ArrayRef<SDValue> Ops);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                EVT VT3, SDValue Op1, SDValue Op2);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                EVT VT3, SDValue Op1, SDValue Op2,
+                                SDValue Op3);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                EVT VT3, ArrayRef<SDValue> Ops);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2,
+                                EVT VT3, EVT VT4, ArrayRef<SDValue> Ops);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl,
+                                ArrayRef<EVT> ResultTys,
+                                ArrayRef<SDValue> Ops);
+  MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, SDVTList VTs,
+                                ArrayRef<SDValue> Ops);
+
+  /// getTargetExtractSubreg - A convenience function for creating
+  /// TargetInstrInfo::EXTRACT_SUBREG nodes.
+  SDValue getTargetExtractSubreg(int SRIdx, SDLoc DL, EVT VT,
+                                 SDValue Operand);
+
+  /// getTargetInsertSubreg - A convenience function for creating
+  /// TargetInstrInfo::INSERT_SUBREG nodes.
+  SDValue getTargetInsertSubreg(int SRIdx, SDLoc DL, EVT VT,
+                                SDValue Operand, SDValue Subreg);
+
+  /// getNodeIfExists - Get the specified node if it's already available, or
+  /// else return NULL.
+  SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
+                          bool nuw = false, bool nsw = false,
+                          bool exact = false);
+
+  /// getDbgValue - Creates a SDDbgValue node.
+  ///
+  SDDbgValue *getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R,
+			  bool IsIndirect, uint64_t Off,
+                          DebugLoc DL, unsigned O);
+  /// Constant.
+  SDDbgValue *getConstantDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off,
+				  DebugLoc DL, unsigned O);
+  /// Frame index.
+  SDDbgValue *getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
+				    DebugLoc DL, unsigned O);
+
+  /// RemoveDeadNode - Remove the specified node from the system. If any of its
+  /// operands then becomes dead, remove them as well. Inform UpdateListener
+  /// for each node deleted.
+  void RemoveDeadNode(SDNode *N);
+
+  /// RemoveDeadNodes - This method deletes the unreachable nodes in the
+  /// given list, and any nodes that become unreachable as a result.
+  void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes);
+
+  /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+  /// This can cause recursive merging of nodes in the DAG.  Use the first
+  /// version if 'From' is known to have a single result, use the second
+  /// if you have two nodes with identical results (or if 'To' has a superset
+  /// of the results of 'From'), use the third otherwise.
+  ///
+  /// These methods all take an optional UpdateListener, which (if not null) is
+  /// informed about nodes that are deleted and modified due to recursive
+  /// changes in the dag.
+  ///
+  /// These functions only replace all existing uses. It's possible that as
+  /// these replacements are being performed, CSE may cause the From node
+  /// to be given new uses. These new uses of From are left in place, and
+  /// not automatically transferred to To.
+  ///
+  void ReplaceAllUsesWith(SDValue From, SDValue Op);
+  void ReplaceAllUsesWith(SDNode *From, SDNode *To);
+  void ReplaceAllUsesWith(SDNode *From, const SDValue *To);
+
+  /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
+  /// uses of other values produced by From.Val alone.
+  void ReplaceAllUsesOfValueWith(SDValue From, SDValue To);
+
+  /// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but
+  /// for multiple values at once. This correctly handles the case where
+  /// there is an overlap between the From values and the To values.
+  void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
+                                  unsigned Num);
+
+  /// AssignTopologicalOrder - Topological-sort the AllNodes list and a
+  /// assign a unique node id for each node in the DAG based on their
+  /// topological order. Returns the number of nodes.
+  unsigned AssignTopologicalOrder();
+
+  /// RepositionNode - Move node N in the AllNodes list to be immediately
+  /// before the given iterator Position. This may be used to update the
+  /// topological ordering when the list of nodes is modified.
+  void RepositionNode(allnodes_iterator Position, SDNode *N) {
+    AllNodes.insert(Position, AllNodes.remove(N));
+  }
+
+  /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
+  /// operation.
+  static bool isCommutativeBinOp(unsigned Opcode) {
+    // FIXME: This should get its info from the td file, so that we can include
+    // target info.
+    switch (Opcode) {
+    case ISD::ADD:
+    case ISD::MUL:
+    case ISD::MULHU:
+    case ISD::MULHS:
+    case ISD::SMUL_LOHI:
+    case ISD::UMUL_LOHI:
+    case ISD::FADD:
+    case ISD::FMUL:
+    case ISD::AND:
+    case ISD::OR:
+    case ISD::XOR:
+    case ISD::SADDO:
+    case ISD::UADDO:
+    case ISD::ADDC:
+    case ISD::ADDE: return true;
+    default: return false;
+    }
+  }
+
+  /// Returns an APFloat semantics tag appropriate for the given type. If VT is
+  /// a vector type, the element semantics are returned.
+  static const fltSemantics &EVTToAPFloatSemantics(EVT VT) {
+    switch (VT.getScalarType().getSimpleVT().SimpleTy) {
+    default: llvm_unreachable("Unknown FP format");
+    case MVT::f16:     return APFloat::IEEEhalf;
+    case MVT::f32:     return APFloat::IEEEsingle;
+    case MVT::f64:     return APFloat::IEEEdouble;
+    case MVT::f80:     return APFloat::x87DoubleExtended;
+    case MVT::f128:    return APFloat::IEEEquad;
+    case MVT::ppcf128: return APFloat::PPCDoubleDouble;
+    }
+  }
+
+  /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
+  /// value is produced by SD.
+  void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
+
+  /// GetDbgValues - Get the debug values which reference the given SDNode.
+  ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
+    return DbgInfo->getSDDbgValues(SD);
+  }
+
+  /// TransferDbgValues - Transfer SDDbgValues.
+  void TransferDbgValues(SDValue From, SDValue To);
+
+  /// hasDebugValues - Return true if there are any SDDbgValue nodes associated
+  /// with this SelectionDAG.
+  bool hasDebugValues() const { return !DbgInfo->empty(); }
+
+  SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
+  SDDbgInfo::DbgIterator DbgEnd()   { return DbgInfo->DbgEnd(); }
+  SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
+    return DbgInfo->ByvalParmDbgBegin();
+  }
+  SDDbgInfo::DbgIterator ByvalParmDbgEnd()   {
+    return DbgInfo->ByvalParmDbgEnd();
+  }
+
+  void dump() const;
+
+  /// CreateStackTemporary - Create a stack temporary, suitable for holding the
+  /// specified value type.  If minAlign is specified, the slot size will have
+  /// at least that alignment.
+  SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1);
+
+  /// CreateStackTemporary - Create a stack temporary suitable for holding
+  /// either of the specified value types.
+  SDValue CreateStackTemporary(EVT VT1, EVT VT2);
+
+  /// FoldConstantArithmetic -
+  SDValue FoldConstantArithmetic(unsigned Opcode, EVT VT,
+                                 SDNode *Cst1, SDNode *Cst2);
+
+  /// FoldSetCC - Constant fold a setcc to true or false.
+  SDValue FoldSetCC(EVT VT, SDValue N1,
+                    SDValue N2, ISD::CondCode Cond, SDLoc dl);
+
+  /// SignBitIsZero - Return true if the sign bit of Op is known to be zero.  We
+  /// use this predicate to simplify operations downstream.
+  bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
+
+  /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero.  We
+  /// use this predicate to simplify operations downstream.  Op and Mask are
+  /// known to be the same type.
+  bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0)
+    const;
+
+  /// Determine which bits of Op are known to be either zero or one and return
+  /// them in the KnownZero/KnownOne bitsets.  Targets can implement the
+  /// computeKnownBitsForTargetNode method in the TargetLowering class to allow
+  /// target nodes to be understood.
+  void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
+                        unsigned Depth = 0) const;
+
+  /// ComputeNumSignBits - Return the number of times the sign bit of the
+  /// register is replicated into the other bits.  We know that at least 1 bit
+  /// is always equal to the sign bit (itself), but other cases can give us
+  /// information.  For example, immediately after an "SRA X, 2", we know that
+  /// the top 3 bits are all equal to each other, so we return 3.  Targets can
+  /// implement the ComputeNumSignBitsForTarget method in the TargetLowering
+  /// class to allow target nodes to be understood.
+  unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
+
+  /// isBaseWithConstantOffset - Return true if the specified operand is an
+  /// ISD::ADD with a ConstantSDNode on the right-hand side, or if it is an
+  /// ISD::OR with a ConstantSDNode that is guaranteed to have the same
+  /// semantics as an ADD.  This handles the equivalence:
+  ///     X|Cst == X+Cst iff X&Cst = 0.
+  bool isBaseWithConstantOffset(SDValue Op) const;
+
+  /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
+  bool isKnownNeverNaN(SDValue Op) const;
+
+  /// isKnownNeverZero - Test whether the given SDValue is known to never be
+  /// positive or negative Zero.
+  bool isKnownNeverZero(SDValue Op) const;
+
+  /// isEqualTo - Test whether two SDValues are known to compare equal. This
+  /// is true if they are the same value, or if one is negative zero and the
+  /// other positive zero.
+  bool isEqualTo(SDValue A, SDValue B) const;
+
+  /// UnrollVectorOp - Utility function used by legalize and lowering to
+  /// "unroll" a vector operation by splitting out the scalars and operating
+  /// on each element individually.  If the ResNE is 0, fully unroll the vector
+  /// op. If ResNE is less than the width of the vector op, unroll up to ResNE.
+  /// If the  ResNE is greater than the width of the vector op, unroll the
+  /// vector op and fill the end of the resulting vector with UNDEFS.
+  SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
+
+  /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
+  /// location that is 'Dist' units away from the location that the 'Base' load
+  /// is loading from.
+  bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,
+                         unsigned Bytes, int Dist) const;
+
+  /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if
+  /// it cannot be inferred.
+  unsigned InferPtrAlignment(SDValue Ptr) const;
+
+  /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
+  /// which is split (or expanded) into two not necessarily identical pieces.
+  std::pair<EVT, EVT> GetSplitDestVTs(const EVT &VT) const;
+
+  /// SplitVector - Split the vector with EXTRACT_SUBVECTOR using the provides
+  /// VTs and return the low/high part.
+  std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL,
+                                          const EVT &LoVT, const EVT &HiVT);
+
+  /// SplitVector - Split the vector with EXTRACT_SUBVECTOR and return the
+  /// low/high part.
+  std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL) {
+    EVT LoVT, HiVT;
+    std::tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
+    return SplitVector(N, DL, LoVT, HiVT);
+  }
+
+  /// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
+  /// return the low/high part.
+  std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
+  {
+    return SplitVector(N->getOperand(OpNo), SDLoc(N));
+  }
+
+  /// ExtractVectorElements - Append the extracted elements from Start to Count
+  /// out of the vector Op in Args. If Count is 0, all of the elements will be
+  /// extracted.
+  void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args,
+                             unsigned Start = 0, unsigned Count = 0);
+
+  unsigned getEVTAlignment(EVT MemoryVT) const;
+
+private:
+  bool RemoveNodeFromCSEMaps(SDNode *N);
+  void AddModifiedNodeToCSEMaps(SDNode *N);
+  SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
+  SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
+                               void *&InsertPos);
+  SDNode *FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops,
+                               void *&InsertPos);
+  SDNode *UpdadeSDLocOnMergedSDNode(SDNode *N, SDLoc loc);
+
+  void DeleteNodeNotInCSEMaps(SDNode *N);
+  void DeallocateNode(SDNode *N);
+
+  void allnodes_clear();
+
+  BinarySDNode *GetBinarySDNode(unsigned Opcode, SDLoc DL, SDVTList VTs,
+                                SDValue N1, SDValue N2, bool nuw, bool nsw,
+                                bool exact);
+
+  /// VTList - List of non-single value types.
+  FoldingSet<SDVTListNode> VTListMap;
+
+  /// CondCodeNodes - Maps to auto-CSE operations.
+  std::vector<CondCodeSDNode*> CondCodeNodes;
+
+  std::vector<SDNode*> ValueTypeNodes;
+  std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes;
+  StringMap<SDNode*> ExternalSymbols;
+
+  std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
+};
+
+template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
+  typedef SelectionDAG::allnodes_iterator nodes_iterator;
+  static nodes_iterator nodes_begin(SelectionDAG *G) {
+    return G->allnodes_begin();
+  }
+  static nodes_iterator nodes_end(SelectionDAG *G) {
+    return G->allnodes_end();
+  }
+};
+
+}  // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
new file mode 100644
index 0000000..520be40
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -0,0 +1,295 @@
+//===-- llvm/CodeGen/SelectionDAGISel.h - Common Base Class------*- C++ -*-===//
+//
+//                     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 SelectionDAGISel class, which is used as the common
+// base class for SelectionDAG-based instruction selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H
+#define LLVM_CODEGEN_SELECTIONDAGISEL_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class FastISel;
+  class SelectionDAGBuilder;
+  class SDValue;
+  class MachineRegisterInfo;
+  class MachineBasicBlock;
+  class MachineFunction;
+  class MachineInstr;
+  class TargetLowering;
+  class TargetLibraryInfo;
+  class FunctionLoweringInfo;
+  class ScheduleHazardRecognizer;
+  class GCFunctionInfo;
+  class ScheduleDAGSDNodes;
+  class LoadInst;
+
+/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
+/// pattern-matching instruction selectors.
+class SelectionDAGISel : public MachineFunctionPass {
+public:
+  TargetMachine &TM;
+  const TargetLibraryInfo *LibInfo;
+  FunctionLoweringInfo *FuncInfo;
+  MachineFunction *MF;
+  MachineRegisterInfo *RegInfo;
+  SelectionDAG *CurDAG;
+  SelectionDAGBuilder *SDB;
+  AliasAnalysis *AA;
+  GCFunctionInfo *GFI;
+  CodeGenOpt::Level OptLevel;
+  static char ID;
+
+  explicit SelectionDAGISel(TargetMachine &tm,
+                            CodeGenOpt::Level OL = CodeGenOpt::Default);
+  virtual ~SelectionDAGISel();
+
+  const TargetLowering *getTargetLowering() const {
+    return TM.getTargetLowering();
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  virtual void EmitFunctionEntryCode() {}
+
+  /// PreprocessISelDAG - This hook allows targets to hack on the graph before
+  /// instruction selection starts.
+  virtual void PreprocessISelDAG() {}
+
+  /// PostprocessISelDAG() - This hook allows the target to hack on the graph
+  /// right after selection.
+  virtual void PostprocessISelDAG() {}
+
+  /// Select - Main hook targets implement to select a node.
+  virtual SDNode *Select(SDNode *N) = 0;
+
+  /// SelectInlineAsmMemoryOperand - Select the specified address as a target
+  /// addressing mode, according to the specified constraint code.  If this does
+  /// not match or is not implemented, return true.  The resultant operands
+  /// (which will appear in the machine instruction) should be added to the
+  /// OutOps vector.
+  virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
+                                            char ConstraintCode,
+                                            std::vector<SDValue> &OutOps) {
+    return true;
+  }
+
+  /// IsProfitableToFold - Returns true if it's profitable to fold the specific
+  /// operand node N of U during instruction selection that starts at Root.
+  virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+  /// IsLegalToFold - Returns true if the specific operand node N of
+  /// U can be folded during instruction selection that starts at Root.
+  /// FIXME: This is a static member function because the MSP430/X86
+  /// targets, which uses it during isel.  This could become a proper member.
+  static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
+                            CodeGenOpt::Level OptLevel,
+                            bool IgnoreChains = false);
+
+  // Opcodes used by the DAG state machine:
+  enum BuiltinOpcodes {
+    OPC_Scope,
+    OPC_RecordNode,
+    OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
+    OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
+    OPC_RecordMemRef,
+    OPC_CaptureGlueInput,
+    OPC_MoveChild,
+    OPC_MoveParent,
+    OPC_CheckSame,
+    OPC_CheckChild0Same, OPC_CheckChild1Same,
+    OPC_CheckChild2Same, OPC_CheckChild3Same,
+    OPC_CheckPatternPredicate,
+    OPC_CheckPredicate,
+    OPC_CheckOpcode,
+    OPC_SwitchOpcode,
+    OPC_CheckType,
+    OPC_SwitchType,
+    OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
+    OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
+    OPC_CheckChild6Type, OPC_CheckChild7Type,
+    OPC_CheckInteger,
+    OPC_CheckChild0Integer, OPC_CheckChild1Integer, OPC_CheckChild2Integer,
+    OPC_CheckChild3Integer, OPC_CheckChild4Integer,
+    OPC_CheckCondCode,
+    OPC_CheckValueType,
+    OPC_CheckComplexPat,
+    OPC_CheckAndImm, OPC_CheckOrImm,
+    OPC_CheckFoldableChainNode,
+
+    OPC_EmitInteger,
+    OPC_EmitRegister,
+    OPC_EmitRegister2,
+    OPC_EmitConvertToTarget,
+    OPC_EmitMergeInputChains,
+    OPC_EmitMergeInputChains1_0,
+    OPC_EmitMergeInputChains1_1,
+    OPC_EmitCopyToReg,
+    OPC_EmitNodeXForm,
+    OPC_EmitNode,
+    OPC_MorphNodeTo,
+    OPC_MarkGlueResults,
+    OPC_CompleteMatch
+  };
+
+  enum {
+    OPFL_None       = 0,  // Node has no chain or glue input and isn't variadic.
+    OPFL_Chain      = 1,     // Node has a chain input.
+    OPFL_GlueInput  = 2,     // Node has a glue input.
+    OPFL_GlueOutput = 4,     // Node has a glue output.
+    OPFL_MemRefs    = 8,     // Node gets accumulated MemRefs.
+    OPFL_Variadic0  = 1<<4,  // Node is variadic, root has 0 fixed inputs.
+    OPFL_Variadic1  = 2<<4,  // Node is variadic, root has 1 fixed inputs.
+    OPFL_Variadic2  = 3<<4,  // Node is variadic, root has 2 fixed inputs.
+    OPFL_Variadic3  = 4<<4,  // Node is variadic, root has 3 fixed inputs.
+    OPFL_Variadic4  = 5<<4,  // Node is variadic, root has 4 fixed inputs.
+    OPFL_Variadic5  = 6<<4,  // Node is variadic, root has 5 fixed inputs.
+    OPFL_Variadic6  = 7<<4,  // Node is variadic, root has 6 fixed inputs.
+
+    OPFL_VariadicInfo = OPFL_Variadic6
+  };
+
+  /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
+  /// number of fixed arity values that should be skipped when copying from the
+  /// root.
+  static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
+    return ((Flags&OPFL_VariadicInfo) >> 4)-1;
+  }
+
+
+protected:
+  /// DAGSize - Size of DAG being instruction selected.
+  ///
+  unsigned DAGSize;
+
+  /// ReplaceUses - replace all uses of the old node F with the use
+  /// of the new node T.
+  void ReplaceUses(SDValue F, SDValue T) {
+    CurDAG->ReplaceAllUsesOfValueWith(F, T);
+  }
+
+  /// ReplaceUses - replace all uses of the old nodes F with the use
+  /// of the new nodes T.
+  void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
+    CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num);
+  }
+
+  /// ReplaceUses - replace all uses of the old node F with the use
+  /// of the new node T.
+  void ReplaceUses(SDNode *F, SDNode *T) {
+    CurDAG->ReplaceAllUsesWith(F, T);
+  }
+
+
+  /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
+  /// by tblgen.  Others should not call it.
+  void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
+
+
+public:
+  // Calls to these predicates are generated by tblgen.
+  bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
+                    int64_t DesiredMaskS) const;
+  bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
+                    int64_t DesiredMaskS) const;
+
+
+  /// CheckPatternPredicate - This function is generated by tblgen in the
+  /// target.  It runs the specified pattern predicate and returns true if it
+  /// succeeds or false if it fails.  The number is a private implementation
+  /// detail to the code tblgen produces.
+  virtual bool CheckPatternPredicate(unsigned PredNo) const {
+    llvm_unreachable("Tblgen should generate the implementation of this!");
+  }
+
+  /// CheckNodePredicate - This function is generated by tblgen in the target.
+  /// It runs node predicate number PredNo and returns true if it succeeds or
+  /// false if it fails.  The number is a private implementation
+  /// detail to the code tblgen produces.
+  virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
+    llvm_unreachable("Tblgen should generate the implementation of this!");
+  }
+
+  virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,
+                                   unsigned PatternNo,
+                        SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {
+    llvm_unreachable("Tblgen should generate the implementation of this!");
+  }
+
+  virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
+    llvm_unreachable("Tblgen should generate this!");
+  }
+
+  SDNode *SelectCodeCommon(SDNode *NodeToMatch,
+                           const unsigned char *MatcherTable,
+                           unsigned TableSize);
+
+private:
+
+  // Calls to these functions are generated by tblgen.
+  SDNode *Select_INLINEASM(SDNode *N);
+  SDNode *Select_READ_REGISTER(SDNode *N);
+  SDNode *Select_WRITE_REGISTER(SDNode *N);
+  SDNode *Select_UNDEF(SDNode *N);
+  void CannotYetSelect(SDNode *N);
+
+private:
+  void DoInstructionSelection();
+  SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
+                    ArrayRef<SDValue> Ops, unsigned EmitNodeInfo);
+
+  void PrepareEHLandingPad();
+
+  /// \brief Perform instruction selection on all basic blocks in the function.
+  void SelectAllBasicBlocks(const Function &Fn);
+
+  /// \brief Perform instruction selection on a single basic block, for
+  /// instructions between \p Begin and \p End.  \p HadTailCall will be set
+  /// to true if a call in the block was translated as a tail call.
+  void SelectBasicBlock(BasicBlock::const_iterator Begin,
+                        BasicBlock::const_iterator End,
+                        bool &HadTailCall);
+  void FinishBasicBlock();
+
+  void CodeGenAndEmitDAG();
+
+  /// \brief Generate instructions for lowering the incoming arguments of the
+  /// given function.
+  void LowerArguments(const Function &F);
+
+  void ComputeLiveOutVRegInfo();
+
+  /// Create the scheduler. If a specific scheduler was specified
+  /// via the SchedulerRegistry, use it, otherwise select the
+  /// one preferred by the target.
+  ///
+  ScheduleDAGSDNodes *CreateScheduler();
+
+  /// OpcodeOffset - This is a cache used to dispatch efficiently into isel
+  /// state machines that start with a OPC_SwitchOpcode node.
+  std::vector<unsigned> OpcodeOffset;
+
+  void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain,
+                           const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+                           SDValue InputGlue, const SmallVectorImpl<SDNode*> &F,
+                           bool isMorphNodeTo);
+
+};
+
+}
+
+#endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
new file mode 100644
index 0000000..2231511
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -0,0 +1,2076 @@
+//===-- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ---*- 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 SDNode class and derived classes, which are used to
+// represent the nodes and operations present in a SelectionDAG.  These nodes
+// and operations are machine code level operations, with some similarities to
+// the GCC RTL representation.
+//
+// Clients should include the SelectionDAG.h file instead of this file directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
+#define LLVM_CODEGEN_SELECTIONDAGNODES_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+
+namespace llvm {
+
+class SelectionDAG;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineConstantPoolValue;
+class SDNode;
+class Value;
+class MCSymbol;
+template <typename T> struct DenseMapInfo;
+template <typename T> struct simplify_type;
+template <typename T> struct ilist_traits;
+
+/// isBinOpWithFlags - Returns true if the opcode is a binary operation
+/// with flags.
+static bool isBinOpWithFlags(unsigned Opcode) {
+  switch (Opcode) {
+  case ISD::SDIV:
+  case ISD::UDIV:
+  case ISD::SRA:
+  case ISD::SRL:
+  case ISD::MUL:
+  case ISD::ADD:
+  case ISD::SUB:
+  case ISD::SHL:
+    return true;
+  default:
+    return false;
+  }
+}
+
+void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
+                    bool force = false);
+
+/// SDVTList - This represents a list of ValueType's that has been intern'd by
+/// a SelectionDAG.  Instances of this simple value class are returned by
+/// SelectionDAG::getVTList(...).
+///
+struct SDVTList {
+  const EVT *VTs;
+  unsigned int NumVTs;
+};
+
+namespace ISD {
+  /// Node predicates
+
+  /// isBuildVectorAllOnes - Return true if the specified node is a
+  /// BUILD_VECTOR where all of the elements are ~0 or undef.
+  bool isBuildVectorAllOnes(const SDNode *N);
+
+  /// isBuildVectorAllZeros - Return true if the specified node is a
+  /// BUILD_VECTOR where all of the elements are 0 or undef.
+  bool isBuildVectorAllZeros(const SDNode *N);
+
+  /// \brief Return true if the specified node is a BUILD_VECTOR node of
+  /// all ConstantSDNode or undef.
+  bool isBuildVectorOfConstantSDNodes(const SDNode *N);
+
+  /// isScalarToVector - Return true if the specified node is a
+  /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
+  /// element is not an undef.
+  bool isScalarToVector(const SDNode *N);
+
+  /// allOperandsUndef - Return true if the node has at least one operand
+  /// and all operands of the specified node are ISD::UNDEF.
+  bool allOperandsUndef(const SDNode *N);
+}  // end llvm:ISD namespace
+
+//===----------------------------------------------------------------------===//
+/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple
+/// values as the result of a computation.  Many nodes return multiple values,
+/// from loads (which define a token and a return value) to ADDC (which returns
+/// a result and a carry value), to calls (which may return an arbitrary number
+/// of values).
+///
+/// As such, each use of a SelectionDAG computation must indicate the node that
+/// computes it as well as which return value to use from that node.  This pair
+/// of information is represented with the SDValue value type.
+///
+class SDValue {
+  SDNode *Node;       // The node defining the value we are using.
+  unsigned ResNo;     // Which return value of the node we are using.
+public:
+  SDValue() : Node(nullptr), ResNo(0) {}
+  SDValue(SDNode *node, unsigned resno) : Node(node), ResNo(resno) {}
+
+  /// get the index which selects a specific result in the SDNode
+  unsigned getResNo() const { return ResNo; }
+
+  /// get the SDNode which holds the desired result
+  SDNode *getNode() const { return Node; }
+
+  /// set the SDNode
+  void setNode(SDNode *N) { Node = N; }
+
+  inline SDNode *operator->() const { return Node; }
+
+  bool operator==(const SDValue &O) const {
+    return Node == O.Node && ResNo == O.ResNo;
+  }
+  bool operator!=(const SDValue &O) const {
+    return !operator==(O);
+  }
+  bool operator<(const SDValue &O) const {
+    return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
+  }
+  LLVM_EXPLICIT operator bool() const {
+    return Node != nullptr;
+  }
+
+  SDValue getValue(unsigned R) const {
+    return SDValue(Node, R);
+  }
+
+  // isOperandOf - Return true if this node is an operand of N.
+  bool isOperandOf(SDNode *N) const;
+
+  /// getValueType - Return the ValueType of the referenced return value.
+  ///
+  inline EVT getValueType() const;
+
+  /// Return the simple ValueType of the referenced return value.
+  MVT getSimpleValueType() const {
+    return getValueType().getSimpleVT();
+  }
+
+  /// getValueSizeInBits - Returns the size of the value in bits.
+  ///
+  unsigned getValueSizeInBits() const {
+    return getValueType().getSizeInBits();
+  }
+
+  unsigned getScalarValueSizeInBits() const {
+    return getValueType().getScalarType().getSizeInBits();
+  }
+
+  // Forwarding methods - These forward to the corresponding methods in SDNode.
+  inline unsigned getOpcode() const;
+  inline unsigned getNumOperands() const;
+  inline const SDValue &getOperand(unsigned i) const;
+  inline uint64_t getConstantOperandVal(unsigned i) const;
+  inline bool isTargetMemoryOpcode() const;
+  inline bool isTargetOpcode() const;
+  inline bool isMachineOpcode() const;
+  inline unsigned getMachineOpcode() const;
+  inline const DebugLoc getDebugLoc() const;
+  inline void dump() const;
+  inline void dumpr() const;
+
+  /// reachesChainWithoutSideEffects - Return true if this operand (which must
+  /// be a chain) reaches the specified operand without crossing any
+  /// side-effecting instructions.  In practice, this looks through token
+  /// factors and non-volatile loads.  In order to remain efficient, this only
+  /// looks a couple of nodes in, it does not do an exhaustive search.
+  bool reachesChainWithoutSideEffects(SDValue Dest,
+                                      unsigned Depth = 2) const;
+
+  /// use_empty - Return true if there are no nodes using value ResNo
+  /// of Node.
+  ///
+  inline bool use_empty() const;
+
+  /// hasOneUse - Return true if there is exactly one node using value
+  /// ResNo of Node.
+  ///
+  inline bool hasOneUse() const;
+};
+
+
+template<> struct DenseMapInfo<SDValue> {
+  static inline SDValue getEmptyKey() {
+    return SDValue((SDNode*)-1, -1U);
+  }
+  static inline SDValue getTombstoneKey() {
+    return SDValue((SDNode*)-1, 0);
+  }
+  static unsigned getHashValue(const SDValue &Val) {
+    return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^
+            (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo();
+  }
+  static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
+    return LHS == RHS;
+  }
+};
+template <> struct isPodLike<SDValue> { static const bool value = true; };
+
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDValues as if they were SDNode*'s.
+template<> struct simplify_type<SDValue> {
+  typedef SDNode* SimpleType;
+  static SimpleType getSimplifiedValue(SDValue &Val) {
+    return Val.getNode();
+  }
+};
+template<> struct simplify_type<const SDValue> {
+  typedef /*const*/ SDNode* SimpleType;
+  static SimpleType getSimplifiedValue(const SDValue &Val) {
+    return Val.getNode();
+  }
+};
+
+/// SDUse - Represents a use of a SDNode. This class holds an SDValue,
+/// which records the SDNode being used and the result number, a
+/// pointer to the SDNode using the value, and Next and Prev pointers,
+/// which link together all the uses of an SDNode.
+///
+class SDUse {
+  /// Val - The value being used.
+  SDValue Val;
+  /// User - The user of this value.
+  SDNode *User;
+  /// Prev, Next - Pointers to the uses list of the SDNode referred by
+  /// this operand.
+  SDUse **Prev, *Next;
+
+  SDUse(const SDUse &U) LLVM_DELETED_FUNCTION;
+  void operator=(const SDUse &U) LLVM_DELETED_FUNCTION;
+
+public:
+  SDUse() : Val(), User(nullptr), Prev(nullptr), Next(nullptr) {}
+
+  /// Normally SDUse will just implicitly convert to an SDValue that it holds.
+  operator const SDValue&() const { return Val; }
+
+  /// If implicit conversion to SDValue doesn't work, the get() method returns
+  /// the SDValue.
+  const SDValue &get() const { return Val; }
+
+  /// getUser - This returns the SDNode that contains this Use.
+  SDNode *getUser() { return User; }
+
+  /// getNext - Get the next SDUse in the use list.
+  SDUse *getNext() const { return Next; }
+
+  /// getNode - Convenience function for get().getNode().
+  SDNode *getNode() const { return Val.getNode(); }
+  /// getResNo - Convenience function for get().getResNo().
+  unsigned getResNo() const { return Val.getResNo(); }
+  /// getValueType - Convenience function for get().getValueType().
+  EVT getValueType() const { return Val.getValueType(); }
+
+  /// operator== - Convenience function for get().operator==
+  bool operator==(const SDValue &V) const {
+    return Val == V;
+  }
+
+  /// operator!= - Convenience function for get().operator!=
+  bool operator!=(const SDValue &V) const {
+    return Val != V;
+  }
+
+  /// operator< - Convenience function for get().operator<
+  bool operator<(const SDValue &V) const {
+    return Val < V;
+  }
+
+private:
+  friend class SelectionDAG;
+  friend class SDNode;
+
+  void setUser(SDNode *p) { User = p; }
+
+  /// set - Remove this use from its existing use list, assign it the
+  /// given value, and add it to the new value's node's use list.
+  inline void set(const SDValue &V);
+  /// setInitial - like set, but only supports initializing a newly-allocated
+  /// SDUse with a non-null value.
+  inline void setInitial(const SDValue &V);
+  /// setNode - like set, but only sets the Node portion of the value,
+  /// leaving the ResNo portion unmodified.
+  inline void setNode(SDNode *N);
+
+  void addToList(SDUse **List) {
+    Next = *List;
+    if (Next) Next->Prev = &Next;
+    Prev = List;
+    *List = this;
+  }
+
+  void removeFromList() {
+    *Prev = Next;
+    if (Next) Next->Prev = Prev;
+  }
+};
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDValues as if they were SDNode*'s.
+template<> struct simplify_type<SDUse> {
+  typedef SDNode* SimpleType;
+  static SimpleType getSimplifiedValue(SDUse &Val) {
+    return Val.getNode();
+  }
+};
+
+
+/// SDNode - Represents one node in the SelectionDAG.
+///
+class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
+private:
+  /// NodeType - The operation that this node performs.
+  ///
+  int16_t NodeType;
+
+  /// OperandsNeedDelete - This is true if OperandList was new[]'d.  If true,
+  /// then they will be delete[]'d when the node is destroyed.
+  uint16_t OperandsNeedDelete : 1;
+
+  /// HasDebugValue - This tracks whether this node has one or more dbg_value
+  /// nodes corresponding to it.
+  uint16_t HasDebugValue : 1;
+
+protected:
+  /// SubclassData - This member is defined by this class, but is not used for
+  /// anything.  Subclasses can use it to hold whatever state they find useful.
+  /// This field is initialized to zero by the ctor.
+  uint16_t SubclassData : 14;
+
+private:
+  /// NodeId - Unique id per SDNode in the DAG.
+  int NodeId;
+
+  /// OperandList - The values that are used by this operation.
+  ///
+  SDUse *OperandList;
+
+  /// ValueList - The types of the values this node defines.  SDNode's may
+  /// define multiple values simultaneously.
+  const EVT *ValueList;
+
+  /// UseList - List of uses for this SDNode.
+  SDUse *UseList;
+
+  /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+  unsigned short NumOperands, NumValues;
+
+  /// debugLoc - source line information.
+  DebugLoc debugLoc;
+
+  // The ordering of the SDNodes. It roughly corresponds to the ordering of the
+  // original LLVM instructions.
+  // This is used for turning off scheduling, because we'll forgo
+  // the normal scheduling algorithms and output the instructions according to
+  // this ordering.
+  unsigned IROrder;
+
+  /// getValueTypeList - Return a pointer to the specified value type.
+  static const EVT *getValueTypeList(EVT VT);
+
+  friend class SelectionDAG;
+  friend struct ilist_traits<SDNode>;
+
+public:
+  //===--------------------------------------------------------------------===//
+  //  Accessors
+  //
+
+  /// getOpcode - Return the SelectionDAG opcode value for this node. For
+  /// pre-isel nodes (those for which isMachineOpcode returns false), these
+  /// are the opcode values in the ISD and <target>ISD namespaces. For
+  /// post-isel opcodes, see getMachineOpcode.
+  unsigned getOpcode()  const { return (unsigned short)NodeType; }
+
+  /// isTargetOpcode - Test if this node has a target-specific opcode (in the
+  /// \<target\>ISD namespace).
+  bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
+
+  /// isTargetMemoryOpcode - Test if this node has a target-specific
+  /// memory-referencing opcode (in the \<target\>ISD namespace and
+  /// greater than FIRST_TARGET_MEMORY_OPCODE).
+  bool isTargetMemoryOpcode() const {
+    return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
+  }
+
+  /// isMachineOpcode - Test if this node has a post-isel opcode, directly
+  /// corresponding to a MachineInstr opcode.
+  bool isMachineOpcode() const { return NodeType < 0; }
+
+  /// getMachineOpcode - This may only be called if isMachineOpcode returns
+  /// true. It returns the MachineInstr opcode value that the node's opcode
+  /// corresponds to.
+  unsigned getMachineOpcode() const {
+    assert(isMachineOpcode() && "Not a MachineInstr opcode!");
+    return ~NodeType;
+  }
+
+  /// getHasDebugValue - get this bit.
+  bool getHasDebugValue() const { return HasDebugValue; }
+
+  /// setHasDebugValue - set this bit.
+  void setHasDebugValue(bool b) { HasDebugValue = b; }
+
+  /// use_empty - Return true if there are no uses of this node.
+  ///
+  bool use_empty() const { return UseList == nullptr; }
+
+  /// hasOneUse - Return true if there is exactly one use of this node.
+  ///
+  bool hasOneUse() const {
+    return !use_empty() && std::next(use_begin()) == use_end();
+  }
+
+  /// use_size - Return the number of uses of this node. This method takes
+  /// time proportional to the number of uses.
+  ///
+  size_t use_size() const { return std::distance(use_begin(), use_end()); }
+
+  /// getNodeId - Return the unique node id.
+  ///
+  int getNodeId() const { return NodeId; }
+
+  /// setNodeId - Set unique node id.
+  void setNodeId(int Id) { NodeId = Id; }
+
+  /// getIROrder - Return the node ordering.
+  ///
+  unsigned getIROrder() const { return IROrder; }
+
+  /// setIROrder - Set the node ordering.
+  ///
+  void setIROrder(unsigned Order) { IROrder = Order; }
+
+  /// getDebugLoc - Return the source location info.
+  const DebugLoc getDebugLoc() const { return debugLoc; }
+
+  /// setDebugLoc - Set source location info.  Try to avoid this, putting
+  /// it in the constructor is preferable.
+  void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
+  /// use_iterator - This class provides iterator support for SDUse
+  /// operands that use a specific SDNode.
+  class use_iterator
+    : public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> {
+    SDUse *Op;
+    explicit use_iterator(SDUse *op) : Op(op) {
+    }
+    friend class SDNode;
+  public:
+    typedef std::iterator<std::forward_iterator_tag,
+                          SDUse, ptrdiff_t>::reference reference;
+    typedef std::iterator<std::forward_iterator_tag,
+                          SDUse, ptrdiff_t>::pointer pointer;
+
+    use_iterator(const use_iterator &I) : Op(I.Op) {}
+    use_iterator() : Op(nullptr) {}
+
+    bool operator==(const use_iterator &x) const {
+      return Op == x.Op;
+    }
+    bool operator!=(const use_iterator &x) const {
+      return !operator==(x);
+    }
+
+    /// atEnd - return true if this iterator is at the end of uses list.
+    bool atEnd() const { return Op == nullptr; }
+
+    // Iterator traversal: forward iteration only.
+    use_iterator &operator++() {          // Preincrement
+      assert(Op && "Cannot increment end iterator!");
+      Op = Op->getNext();
+      return *this;
+    }
+
+    use_iterator operator++(int) {        // Postincrement
+      use_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    /// Retrieve a pointer to the current user node.
+    SDNode *operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op->getUser();
+    }
+
+    SDNode *operator->() const { return operator*(); }
+
+    SDUse &getUse() const { return *Op; }
+
+    /// getOperandNo - Retrieve the operand # of this use in its user.
+    ///
+    unsigned getOperandNo() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return (unsigned)(Op - Op->getUser()->OperandList);
+    }
+  };
+
+  /// use_begin/use_end - Provide iteration support to walk over all uses
+  /// of an SDNode.
+
+  use_iterator use_begin() const {
+    return use_iterator(UseList);
+  }
+
+  static use_iterator use_end() { return use_iterator(nullptr); }
+
+  inline iterator_range<use_iterator> uses() {
+    return iterator_range<use_iterator>(use_begin(), use_end());
+  }
+  inline iterator_range<use_iterator> uses() const {
+    return iterator_range<use_iterator>(use_begin(), use_end());
+  }
+
+  /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
+  /// indicated value.  This method ignores uses of other values defined by this
+  /// operation.
+  bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
+
+  /// hasAnyUseOfValue - Return true if there are any use of the indicated
+  /// value. This method ignores uses of other values defined by this operation.
+  bool hasAnyUseOfValue(unsigned Value) const;
+
+  /// isOnlyUserOf - Return true if this node is the only use of N.
+  ///
+  bool isOnlyUserOf(SDNode *N) const;
+
+  /// isOperandOf - Return true if this node is an operand of N.
+  ///
+  bool isOperandOf(SDNode *N) const;
+
+  /// isPredecessorOf - Return true if this node is a predecessor of N.
+  /// NOTE: Implemented on top of hasPredecessor and every bit as
+  /// expensive. Use carefully.
+  bool isPredecessorOf(const SDNode *N) const {
+    return N->hasPredecessor(this);
+  }
+
+  /// hasPredecessor - Return true if N is a predecessor of this node.
+  /// N is either an operand of this node, or can be reached by recursively
+  /// traversing up the operands.
+  /// NOTE: This is an expensive method. Use it carefully.
+  bool hasPredecessor(const SDNode *N) const;
+
+  /// hasPredecesorHelper - Return true if N is a predecessor of this node.
+  /// N is either an operand of this node, or can be reached by recursively
+  /// traversing up the operands.
+  /// In this helper the Visited and worklist sets are held externally to
+  /// cache predecessors over multiple invocations. If you want to test for
+  /// multiple predecessors this method is preferable to multiple calls to
+  /// hasPredecessor. Be sure to clear Visited and Worklist if the DAG
+  /// changes.
+  /// NOTE: This is still very expensive. Use carefully.
+  bool hasPredecessorHelper(const SDNode *N,
+                            SmallPtrSet<const SDNode *, 32> &Visited,
+                            SmallVectorImpl<const SDNode *> &Worklist) const;
+
+  /// getNumOperands - Return the number of values used by this operation.
+  ///
+  unsigned getNumOperands() const { return NumOperands; }
+
+  /// getConstantOperandVal - Helper method returns the integer value of a
+  /// ConstantSDNode operand.
+  uint64_t getConstantOperandVal(unsigned Num) const;
+
+  const SDValue &getOperand(unsigned Num) const {
+    assert(Num < NumOperands && "Invalid child # of SDNode!");
+    return OperandList[Num];
+  }
+
+  typedef SDUse* op_iterator;
+  op_iterator op_begin() const { return OperandList; }
+  op_iterator op_end() const { return OperandList+NumOperands; }
+  ArrayRef<SDUse> ops() const { return makeArrayRef(op_begin(), op_end()); }
+
+  SDVTList getVTList() const {
+    SDVTList X = { ValueList, NumValues };
+    return X;
+  }
+
+  /// getGluedNode - If this node has a glue operand, return the node
+  /// to which the glue operand points. Otherwise return NULL.
+  SDNode *getGluedNode() const {
+    if (getNumOperands() != 0 &&
+      getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
+      return getOperand(getNumOperands()-1).getNode();
+    return nullptr;
+  }
+
+  // If this is a pseudo op, like copyfromreg, look to see if there is a
+  // real target node glued to it.  If so, return the target node.
+  const SDNode *getGluedMachineNode() const {
+    const SDNode *FoundNode = this;
+
+    // Climb up glue edges until a machine-opcode node is found, or the
+    // end of the chain is reached.
+    while (!FoundNode->isMachineOpcode()) {
+      const SDNode *N = FoundNode->getGluedNode();
+      if (!N) break;
+      FoundNode = N;
+    }
+
+    return FoundNode;
+  }
+
+  /// getGluedUser - If this node has a glue value with a user, return
+  /// the user (there is at most one). Otherwise return NULL.
+  SDNode *getGluedUser() const {
+    for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
+      if (UI.getUse().get().getValueType() == MVT::Glue)
+        return *UI;
+    return nullptr;
+  }
+
+  /// getNumValues - Return the number of values defined/returned by this
+  /// operator.
+  ///
+  unsigned getNumValues() const { return NumValues; }
+
+  /// getValueType - Return the type of a specified result.
+  ///
+  EVT getValueType(unsigned ResNo) const {
+    assert(ResNo < NumValues && "Illegal result number!");
+    return ValueList[ResNo];
+  }
+
+  /// Return the type of a specified result as a simple type.
+  ///
+  MVT getSimpleValueType(unsigned ResNo) const {
+    return getValueType(ResNo).getSimpleVT();
+  }
+
+  /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)).
+  ///
+  unsigned getValueSizeInBits(unsigned ResNo) const {
+    return getValueType(ResNo).getSizeInBits();
+  }
+
+  typedef const EVT* value_iterator;
+  value_iterator value_begin() const { return ValueList; }
+  value_iterator value_end() const { return ValueList+NumValues; }
+
+  /// getOperationName - Return the opcode of this operation for printing.
+  ///
+  std::string getOperationName(const SelectionDAG *G = nullptr) const;
+  static const char* getIndexedModeName(ISD::MemIndexedMode AM);
+  void print_types(raw_ostream &OS, const SelectionDAG *G) const;
+  void print_details(raw_ostream &OS, const SelectionDAG *G) const;
+  void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
+  void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
+
+  /// printrFull - Print a SelectionDAG node and all children down to
+  /// the leaves.  The given SelectionDAG allows target-specific nodes
+  /// to be printed in human-readable form.  Unlike printr, this will
+  /// print the whole DAG, including children that appear multiple
+  /// times.
+  ///
+  void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const;
+
+  /// printrWithDepth - Print a SelectionDAG node and children up to
+  /// depth "depth."  The given SelectionDAG allows target-specific
+  /// nodes to be printed in human-readable form.  Unlike printr, this
+  /// will print children that appear multiple times wherever they are
+  /// used.
+  ///
+  void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
+                       unsigned depth = 100) const;
+
+
+  /// dump - Dump this node, for debugging.
+  void dump() const;
+
+  /// dumpr - Dump (recursively) this node and its use-def subgraph.
+  void dumpr() const;
+
+  /// dump - Dump this node, for debugging.
+  /// The given SelectionDAG allows target-specific nodes to be printed
+  /// in human-readable form.
+  void dump(const SelectionDAG *G) const;
+
+  /// dumpr - Dump (recursively) this node and its use-def subgraph.
+  /// The given SelectionDAG allows target-specific nodes to be printed
+  /// in human-readable form.
+  void dumpr(const SelectionDAG *G) const;
+
+  /// dumprFull - printrFull to dbgs().  The given SelectionDAG allows
+  /// target-specific nodes to be printed in human-readable form.
+  /// Unlike dumpr, this will print the whole DAG, including children
+  /// that appear multiple times.
+  ///
+  void dumprFull(const SelectionDAG *G = nullptr) const;
+
+  /// dumprWithDepth - printrWithDepth to dbgs().  The given
+  /// SelectionDAG allows target-specific nodes to be printed in
+  /// human-readable form.  Unlike dumpr, this will print children
+  /// that appear multiple times wherever they are used.
+  ///
+  void dumprWithDepth(const SelectionDAG *G = nullptr,
+                      unsigned depth = 100) const;
+
+  /// Profile - Gather unique data for the node.
+  ///
+  void Profile(FoldingSetNodeID &ID) const;
+
+  /// addUse - This method should only be used by the SDUse class.
+  ///
+  void addUse(SDUse &U) { U.addToList(&UseList); }
+
+protected:
+  static SDVTList getSDVTList(EVT VT) {
+    SDVTList Ret = { getValueTypeList(VT), 1 };
+    return Ret;
+  }
+
+  SDNode(unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs,
+         ArrayRef<SDValue> Ops)
+    : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false),
+      SubclassData(0), NodeId(-1),
+      OperandList(Ops.size() ? new SDUse[Ops.size()] : nullptr),
+      ValueList(VTs.VTs), UseList(nullptr),
+      NumOperands(Ops.size()), NumValues(VTs.NumVTs),
+      debugLoc(dl), IROrder(Order) {
+    for (unsigned i = 0; i != Ops.size(); ++i) {
+      OperandList[i].setUser(this);
+      OperandList[i].setInitial(Ops[i]);
+    }
+    checkForCycles(this);
+  }
+
+  /// This constructor adds no operands itself; operands can be
+  /// set later with InitOperands.
+  SDNode(unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs)
+    : NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false),
+      SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs),
+      UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs), debugLoc(dl),
+      IROrder(Order) {}
+
+  /// InitOperands - Initialize the operands list of this with 1 operand.
+  void InitOperands(SDUse *Ops, const SDValue &Op0) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    NumOperands = 1;
+    OperandList = Ops;
+    checkForCycles(this);
+  }
+
+  /// InitOperands - Initialize the operands list of this with 2 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    NumOperands = 2;
+    OperandList = Ops;
+    checkForCycles(this);
+  }
+
+  /// InitOperands - Initialize the operands list of this with 3 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+                    const SDValue &Op2) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    Ops[2].setUser(this);
+    Ops[2].setInitial(Op2);
+    NumOperands = 3;
+    OperandList = Ops;
+    checkForCycles(this);
+  }
+
+  /// InitOperands - Initialize the operands list of this with 4 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+                    const SDValue &Op2, const SDValue &Op3) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    Ops[2].setUser(this);
+    Ops[2].setInitial(Op2);
+    Ops[3].setUser(this);
+    Ops[3].setInitial(Op3);
+    NumOperands = 4;
+    OperandList = Ops;
+    checkForCycles(this);
+  }
+
+  /// InitOperands - Initialize the operands list of this with N operands.
+  void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) {
+    for (unsigned i = 0; i != N; ++i) {
+      Ops[i].setUser(this);
+      Ops[i].setInitial(Vals[i]);
+    }
+    NumOperands = N;
+    OperandList = Ops;
+    checkForCycles(this);
+  }
+
+  /// DropOperands - Release the operands and set this node to have
+  /// zero operands.
+  void DropOperands();
+};
+
+/// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed
+/// into SDNode creation functions.
+/// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted
+/// from the original Instruction, and IROrder is the ordinal position of
+/// the instruction.
+/// When an SDNode is created after the DAG is being built, both DebugLoc and
+/// the IROrder are propagated from the original SDNode.
+/// So SDLoc class provides two constructors besides the default one, one to
+/// be used by the DAGBuilder, the other to be used by others.
+class SDLoc {
+private:
+  // Ptr could be used for either Instruction* or SDNode*. It is used for
+  // Instruction* if IROrder is not -1.
+  const void *Ptr;
+  int IROrder;
+
+public:
+  SDLoc() : Ptr(nullptr), IROrder(0) {}
+  SDLoc(const SDNode *N) : Ptr(N), IROrder(-1) {
+    assert(N && "null SDNode");
+  }
+  SDLoc(const SDValue V) : Ptr(V.getNode()), IROrder(-1) {
+    assert(Ptr && "null SDNode");
+  }
+  SDLoc(const Instruction *I, int Order) : Ptr(I), IROrder(Order) {
+    assert(Order >= 0 && "bad IROrder");
+  }
+  unsigned getIROrder() {
+    if (IROrder >= 0 || Ptr == nullptr) {
+      return (unsigned)IROrder;
+    }
+    const SDNode *N = (const SDNode*)(Ptr);
+    return N->getIROrder();
+  }
+  DebugLoc getDebugLoc() {
+    if (!Ptr) {
+      return DebugLoc();
+    }
+    if (IROrder >= 0) {
+      const Instruction *I = (const Instruction*)(Ptr);
+      return I->getDebugLoc();
+    }
+    const SDNode *N = (const SDNode*)(Ptr);
+    return N->getDebugLoc();
+  }
+};
+
+
+// Define inline functions from the SDValue class.
+
+inline unsigned SDValue::getOpcode() const {
+  return Node->getOpcode();
+}
+inline EVT SDValue::getValueType() const {
+  return Node->getValueType(ResNo);
+}
+inline unsigned SDValue::getNumOperands() const {
+  return Node->getNumOperands();
+}
+inline const SDValue &SDValue::getOperand(unsigned i) const {
+  return Node->getOperand(i);
+}
+inline uint64_t SDValue::getConstantOperandVal(unsigned i) const {
+  return Node->getConstantOperandVal(i);
+}
+inline bool SDValue::isTargetOpcode() const {
+  return Node->isTargetOpcode();
+}
+inline bool SDValue::isTargetMemoryOpcode() const {
+  return Node->isTargetMemoryOpcode();
+}
+inline bool SDValue::isMachineOpcode() const {
+  return Node->isMachineOpcode();
+}
+inline unsigned SDValue::getMachineOpcode() const {
+  return Node->getMachineOpcode();
+}
+inline bool SDValue::use_empty() const {
+  return !Node->hasAnyUseOfValue(ResNo);
+}
+inline bool SDValue::hasOneUse() const {
+  return Node->hasNUsesOfValue(1, ResNo);
+}
+inline const DebugLoc SDValue::getDebugLoc() const {
+  return Node->getDebugLoc();
+}
+inline void SDValue::dump() const {
+  return Node->dump();
+}
+inline void SDValue::dumpr() const {
+  return Node->dumpr();
+}
+// Define inline functions from the SDUse class.
+
+inline void SDUse::set(const SDValue &V) {
+  if (Val.getNode()) removeFromList();
+  Val = V;
+  if (V.getNode()) V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setInitial(const SDValue &V) {
+  Val = V;
+  V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setNode(SDNode *N) {
+  if (Val.getNode()) removeFromList();
+  Val.setNode(N);
+  if (N) N->addUse(*this);
+}
+
+/// UnarySDNode - This class is used for single-operand SDNodes.  This is solely
+/// to allow co-allocation of node operands with the node itself.
+class UnarySDNode : public SDNode {
+  SDUse Op;
+public:
+  UnarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+              SDValue X)
+    : SDNode(Opc, Order, dl, VTs) {
+    InitOperands(&Op, X);
+  }
+};
+
+/// BinarySDNode - This class is used for two-operand SDNodes.  This is solely
+/// to allow co-allocation of node operands with the node itself.
+class BinarySDNode : public SDNode {
+  SDUse Ops[2];
+public:
+  BinarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+               SDValue X, SDValue Y)
+    : SDNode(Opc, Order, dl, VTs) {
+    InitOperands(Ops, X, Y);
+  }
+};
+
+/// BinaryWithFlagsSDNode - This class is an extension of BinarySDNode
+/// used from those opcodes that have associated extra flags.
+class BinaryWithFlagsSDNode : public BinarySDNode {
+  enum { NUW = (1 << 0), NSW = (1 << 1), EXACT = (1 << 2) };
+
+public:
+  BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+                        SDValue X, SDValue Y)
+      : BinarySDNode(Opc, Order, dl, VTs, X, Y) {}
+  /// getRawSubclassData - Return the SubclassData value, which contains an
+  /// encoding of the flags.
+  /// This function should be used to add subclass data to the NodeID value.
+  unsigned getRawSubclassData() const { return SubclassData; }
+  void setHasNoUnsignedWrap(bool b) {
+    SubclassData = (SubclassData & ~NUW) | (b ? NUW : 0);
+  }
+  void setHasNoSignedWrap(bool b) {
+    SubclassData = (SubclassData & ~NSW) | (b ? NSW : 0);
+  }
+  void setIsExact(bool b) {
+    SubclassData = (SubclassData & ~EXACT) | (b ? EXACT : 0);
+  }
+  bool hasNoUnsignedWrap() const { return SubclassData & NUW; }
+  bool hasNoSignedWrap() const { return SubclassData & NSW; }
+  bool isExact() const { return SubclassData & EXACT; }
+  static bool classof(const SDNode *N) {
+    return isBinOpWithFlags(N->getOpcode());
+  }
+};
+
+/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class TernarySDNode : public SDNode {
+  SDUse Ops[3];
+public:
+  TernarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+                SDValue X, SDValue Y, SDValue Z)
+    : SDNode(Opc, Order, dl, VTs) {
+    InitOperands(Ops, X, Y, Z);
+  }
+};
+
+
+/// HandleSDNode - This class is used to form a handle around another node that
+/// is persistent and is updated across invocations of replaceAllUsesWith on its
+/// operand.  This node should be directly created by end-users and not added to
+/// the AllNodes list.
+class HandleSDNode : public SDNode {
+  SDUse Op;
+public:
+  explicit HandleSDNode(SDValue X)
+    : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
+    InitOperands(&Op, X);
+  }
+  ~HandleSDNode();
+  const SDValue &getValue() const { return Op; }
+};
+
+class AddrSpaceCastSDNode : public UnarySDNode {
+private:
+  unsigned SrcAddrSpace;
+  unsigned DestAddrSpace;
+
+public:
+  AddrSpaceCastSDNode(unsigned Order, DebugLoc dl, EVT VT, SDValue X,
+                      unsigned SrcAS, unsigned DestAS);
+
+  unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
+  unsigned getDestAddressSpace() const { return DestAddrSpace; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::ADDRSPACECAST;
+  }
+};
+
+/// Abstact virtual class for operations for memory operations
+class MemSDNode : public SDNode {
+private:
+  // MemoryVT - VT of in-memory value.
+  EVT MemoryVT;
+
+protected:
+  /// MMO - Memory reference information.
+  MachineMemOperand *MMO;
+
+public:
+  MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+            EVT MemoryVT, MachineMemOperand *MMO);
+
+  MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+            ArrayRef<SDValue> Ops, EVT MemoryVT, MachineMemOperand *MMO);
+
+  bool readMem() const { return MMO->isLoad(); }
+  bool writeMem() const { return MMO->isStore(); }
+
+  /// Returns alignment and volatility of the memory access
+  unsigned getOriginalAlignment() const {
+    return MMO->getBaseAlignment();
+  }
+  unsigned getAlignment() const {
+    return MMO->getAlignment();
+  }
+
+  /// getRawSubclassData - Return the SubclassData value, which contains an
+  /// encoding of the volatile flag, as well as bits used by subclasses. This
+  /// function should only be used to compute a FoldingSetNodeID value.
+  unsigned getRawSubclassData() const {
+    return SubclassData;
+  }
+
+  // We access subclass data here so that we can check consistency
+  // with MachineMemOperand information.
+  bool isVolatile() const { return (SubclassData >> 5) & 1; }
+  bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
+  bool isInvariant() const { return (SubclassData >> 7) & 1; }
+
+  AtomicOrdering getOrdering() const {
+    return AtomicOrdering((SubclassData >> 8) & 15);
+  }
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope((SubclassData >> 12) & 1);
+  }
+
+  // Returns the offset from the location of the access.
+  int64_t getSrcValueOffset() const { return MMO->getOffset(); }
+
+  /// Returns the TBAAInfo that describes the dereference.
+  const MDNode *getTBAAInfo() const { return MMO->getTBAAInfo(); }
+
+  /// Returns the Ranges that describes the dereference.
+  const MDNode *getRanges() const { return MMO->getRanges(); }
+
+  /// getMemoryVT - Return the type of the in-memory value.
+  EVT getMemoryVT() const { return MemoryVT; }
+
+  /// getMemOperand - Return a MachineMemOperand object describing the memory
+  /// reference performed by operation.
+  MachineMemOperand *getMemOperand() const { return MMO; }
+
+  const MachinePointerInfo &getPointerInfo() const {
+    return MMO->getPointerInfo();
+  }
+
+  /// getAddressSpace - Return the address space for the associated pointer
+  unsigned getAddressSpace() const {
+    return getPointerInfo().getAddrSpace();
+  }
+
+  /// refineAlignment - Update this MemSDNode's MachineMemOperand information
+  /// to reflect the alignment of NewMMO, if it has a greater alignment.
+  /// This must only be used when the new alignment applies to all users of
+  /// this MachineMemOperand.
+  void refineAlignment(const MachineMemOperand *NewMMO) {
+    MMO->refineAlignment(NewMMO);
+  }
+
+  const SDValue &getChain() const { return getOperand(0); }
+  const SDValue &getBasePtr() const {
+    return getOperand(getOpcode() == ISD::STORE ? 2 : 1);
+  }
+
+  // Methods to support isa and dyn_cast
+  static bool classof(const SDNode *N) {
+    // For some targets, we lower some target intrinsics to a MemIntrinsicNode
+    // with either an intrinsic or a target opcode.
+    return N->getOpcode() == ISD::LOAD                ||
+           N->getOpcode() == ISD::STORE               ||
+           N->getOpcode() == ISD::PREFETCH            ||
+           N->getOpcode() == ISD::ATOMIC_CMP_SWAP     ||
+           N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
+           N->getOpcode() == ISD::ATOMIC_SWAP         ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_ADD     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_SUB     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_AND     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_OR      ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_XOR     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_NAND    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_MIN     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_MAX     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_UMIN    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_UMAX    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD         ||
+           N->getOpcode() == ISD::ATOMIC_STORE        ||
+           N->isTargetMemoryOpcode();
+  }
+};
+
+/// AtomicSDNode - A SDNode reprenting atomic operations.
+///
+class AtomicSDNode : public MemSDNode {
+  SDUse Ops[4];
+
+  /// For cmpxchg instructions, the ordering requirements when a store does not
+  /// occur.
+  AtomicOrdering FailureOrdering;
+
+  void InitAtomic(AtomicOrdering SuccessOrdering,
+                  AtomicOrdering FailureOrdering,
+                  SynchronizationScope SynchScope) {
+    // This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
+    assert((SuccessOrdering & 15) == SuccessOrdering &&
+           "Ordering may not require more than 4 bits!");
+    assert((FailureOrdering & 15) == FailureOrdering &&
+           "Ordering may not require more than 4 bits!");
+    assert((SynchScope & 1) == SynchScope &&
+           "SynchScope may not require more than 1 bit!");
+    SubclassData |= SuccessOrdering << 8;
+    SubclassData |= SynchScope << 12;
+    this->FailureOrdering = FailureOrdering;
+    assert(getSuccessOrdering() == SuccessOrdering &&
+           "Ordering encoding error!");
+    assert(getFailureOrdering() == FailureOrdering &&
+           "Ordering encoding error!");
+    assert(getSynchScope() == SynchScope && "Synch-scope encoding error!");
+  }
+
+public:
+  // Opc:   opcode for atomic
+  // VTL:    value type list
+  // Chain:  memory chain for operaand
+  // Ptr:    address to update as a SDValue
+  // Cmp:    compare value
+  // Swp:    swap value
+  // SrcVal: address to update as a Value (used for MemOperand)
+  // Align:  alignment of memory
+  AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
+               EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+               MachineMemOperand *MMO, AtomicOrdering Ordering,
+               SynchronizationScope SynchScope)
+      : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+    InitAtomic(Ordering, Ordering, SynchScope);
+    InitOperands(Ops, Chain, Ptr, Cmp, Swp);
+  }
+  AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
+               EVT MemVT,
+               SDValue Chain, SDValue Ptr,
+               SDValue Val, MachineMemOperand *MMO,
+               AtomicOrdering Ordering, SynchronizationScope SynchScope)
+    : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+    InitAtomic(Ordering, Ordering, SynchScope);
+    InitOperands(Ops, Chain, Ptr, Val);
+  }
+  AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
+               EVT MemVT,
+               SDValue Chain, SDValue Ptr,
+               MachineMemOperand *MMO,
+               AtomicOrdering Ordering, SynchronizationScope SynchScope)
+    : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+    InitAtomic(Ordering, Ordering, SynchScope);
+    InitOperands(Ops, Chain, Ptr);
+  }
+  AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT,
+               const SDValue* AllOps, SDUse *DynOps, unsigned NumOps,
+               MachineMemOperand *MMO,
+               AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
+               SynchronizationScope SynchScope)
+    : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+    InitAtomic(SuccessOrdering, FailureOrdering, SynchScope);
+    assert((DynOps || NumOps <= array_lengthof(Ops)) &&
+           "Too many ops for internal storage!");
+    InitOperands(DynOps ? DynOps : Ops, AllOps, NumOps);
+  }
+
+  const SDValue &getBasePtr() const { return getOperand(1); }
+  const SDValue &getVal() const { return getOperand(2); }
+
+  AtomicOrdering getSuccessOrdering() const {
+    return getOrdering();
+  }
+
+  // Not quite enough room in SubclassData for everything, so failure gets its
+  // own field.
+  AtomicOrdering getFailureOrdering() const {
+    return FailureOrdering;
+  }
+
+  bool isCompareAndSwap() const {
+    unsigned Op = getOpcode();
+    return Op == ISD::ATOMIC_CMP_SWAP || Op == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS;
+  }
+
+  // Methods to support isa and dyn_cast
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::ATOMIC_CMP_SWAP     ||
+           N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
+           N->getOpcode() == ISD::ATOMIC_SWAP         ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_ADD     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_SUB     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_AND     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_OR      ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_XOR     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_NAND    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_MIN     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_MAX     ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_UMIN    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD_UMAX    ||
+           N->getOpcode() == ISD::ATOMIC_LOAD         ||
+           N->getOpcode() == ISD::ATOMIC_STORE;
+  }
+};
+
+/// MemIntrinsicSDNode - This SDNode is used for target intrinsics that touch
+/// memory and need an associated MachineMemOperand. Its opcode may be
+/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
+/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
+class MemIntrinsicSDNode : public MemSDNode {
+public:
+  MemIntrinsicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
+                     ArrayRef<SDValue> Ops, EVT MemoryVT,
+                     MachineMemOperand *MMO)
+    : MemSDNode(Opc, Order, dl, VTs, Ops, MemoryVT, MMO) {
+  }
+
+  // Methods to support isa and dyn_cast
+  static bool classof(const SDNode *N) {
+    // We lower some target intrinsics to their target opcode
+    // early a node with a target opcode can be of this class
+    return N->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
+           N->getOpcode() == ISD::INTRINSIC_VOID ||
+           N->getOpcode() == ISD::PREFETCH ||
+           N->isTargetMemoryOpcode();
+  }
+};
+
+/// ShuffleVectorSDNode - This SDNode is used to implement the code generator
+/// support for the llvm IR shufflevector instruction.  It combines elements
+/// from two input vectors into a new input vector, with the selection and
+/// ordering of elements determined by an array of integers, referred to as
+/// the shuffle mask.  For input vectors of width N, mask indices of 0..N-1
+/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
+/// An index of -1 is treated as undef, such that the code generator may put
+/// any value in the corresponding element of the result.
+class ShuffleVectorSDNode : public SDNode {
+  SDUse Ops[2];
+
+  // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
+  // is freed when the SelectionDAG object is destroyed.
+  const int *Mask;
+protected:
+  friend class SelectionDAG;
+  ShuffleVectorSDNode(EVT VT, unsigned Order, DebugLoc dl, SDValue N1,
+                      SDValue N2, const int *M)
+    : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) {
+    InitOperands(Ops, N1, N2);
+  }
+public:
+
+  ArrayRef<int> getMask() const {
+    EVT VT = getValueType(0);
+    return makeArrayRef(Mask, VT.getVectorNumElements());
+  }
+  int getMaskElt(unsigned Idx) const {
+    assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
+    return Mask[Idx];
+  }
+
+  bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
+  int  getSplatIndex() const {
+    assert(isSplat() && "Cannot get splat index for non-splat!");
+    EVT VT = getValueType(0);
+    for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+      if (Mask[i] >= 0)
+        return Mask[i];
+    }
+    llvm_unreachable("Splat with all undef indices?");
+  }
+  static bool isSplatMask(const int *Mask, EVT VT);
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::VECTOR_SHUFFLE;
+  }
+};
+
+class ConstantSDNode : public SDNode {
+  const ConstantInt *Value;
+  friend class SelectionDAG;
+  ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, EVT VT)
+    : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
+             0, DebugLoc(), getSDVTList(VT)), Value(val) {
+    SubclassData |= (uint16_t)isOpaque;
+  }
+public:
+
+  const ConstantInt *getConstantIntValue() const { return Value; }
+  const APInt &getAPIntValue() const { return Value->getValue(); }
+  uint64_t getZExtValue() const { return Value->getZExtValue(); }
+  int64_t getSExtValue() const { return Value->getSExtValue(); }
+
+  bool isOne() const { return Value->isOne(); }
+  bool isNullValue() const { return Value->isNullValue(); }
+  bool isAllOnesValue() const { return Value->isAllOnesValue(); }
+
+  bool isOpaque() const { return SubclassData & 1; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::Constant ||
+           N->getOpcode() == ISD::TargetConstant;
+  }
+};
+
+class ConstantFPSDNode : public SDNode {
+  const ConstantFP *Value;
+  friend class SelectionDAG;
+  ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT)
+    : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
+             0, DebugLoc(), getSDVTList(VT)), Value(val) {
+  }
+public:
+
+  const APFloat& getValueAPF() const { return Value->getValueAPF(); }
+  const ConstantFP *getConstantFPValue() const { return Value; }
+
+  /// isZero - Return true if the value is positive or negative zero.
+  bool isZero() const { return Value->isZero(); }
+
+  /// isNaN - Return true if the value is a NaN.
+  bool isNaN() const { return Value->isNaN(); }
+
+  /// isExactlyValue - We don't rely on operator== working on double values, as
+  /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
+  /// As such, this method can be used to do an exact bit-for-bit comparison of
+  /// two floating point values.
+
+  /// We leave the version with the double argument here because it's just so
+  /// convenient to write "2.0" and the like.  Without this function we'd
+  /// have to duplicate its logic everywhere it's called.
+  bool isExactlyValue(double V) const {
+    bool ignored;
+    APFloat Tmp(V);
+    Tmp.convert(Value->getValueAPF().getSemantics(),
+                APFloat::rmNearestTiesToEven, &ignored);
+    return isExactlyValue(Tmp);
+  }
+  bool isExactlyValue(const APFloat& V) const;
+
+  static bool isValueValidForType(EVT VT, const APFloat& Val);
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::ConstantFP ||
+           N->getOpcode() == ISD::TargetConstantFP;
+  }
+};
+
+class GlobalAddressSDNode : public SDNode {
+  const GlobalValue *TheGlobal;
+  int64_t Offset;
+  unsigned char TargetFlags;
+  friend class SelectionDAG;
+  GlobalAddressSDNode(unsigned Opc, unsigned Order, DebugLoc DL,
+                      const GlobalValue *GA, EVT VT, int64_t o,
+                      unsigned char TargetFlags);
+public:
+
+  const GlobalValue *getGlobal() const { return TheGlobal; }
+  int64_t getOffset() const { return Offset; }
+  unsigned char getTargetFlags() const { return TargetFlags; }
+  // Return the address space this GlobalAddress belongs to.
+  unsigned getAddressSpace() const;
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::GlobalAddress ||
+           N->getOpcode() == ISD::TargetGlobalAddress ||
+           N->getOpcode() == ISD::GlobalTLSAddress ||
+           N->getOpcode() == ISD::TargetGlobalTLSAddress;
+  }
+};
+
+class FrameIndexSDNode : public SDNode {
+  int FI;
+  friend class SelectionDAG;
+  FrameIndexSDNode(int fi, EVT VT, bool isTarg)
+    : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
+      0, DebugLoc(), getSDVTList(VT)), FI(fi) {
+  }
+public:
+
+  int getIndex() const { return FI; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::FrameIndex ||
+           N->getOpcode() == ISD::TargetFrameIndex;
+  }
+};
+
+class JumpTableSDNode : public SDNode {
+  int JTI;
+  unsigned char TargetFlags;
+  friend class SelectionDAG;
+  JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF)
+    : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
+      0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
+  }
+public:
+
+  int getIndex() const { return JTI; }
+  unsigned char getTargetFlags() const { return TargetFlags; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::JumpTable ||
+           N->getOpcode() == ISD::TargetJumpTable;
+  }
+};
+
+class ConstantPoolSDNode : public SDNode {
+  union {
+    const Constant *ConstVal;
+    MachineConstantPoolValue *MachineCPVal;
+  } Val;
+  int Offset;  // It's a MachineConstantPoolValue if top bit is set.
+  unsigned Alignment;  // Minimum alignment requirement of CP (not log2 value).
+  unsigned char TargetFlags;
+  friend class SelectionDAG;
+  ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
+                     unsigned Align, unsigned char TF)
+    : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
+             DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align),
+             TargetFlags(TF) {
+    assert(Offset >= 0 && "Offset is too large");
+    Val.ConstVal = c;
+  }
+  ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+                     EVT VT, int o, unsigned Align, unsigned char TF)
+    : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
+             DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align),
+             TargetFlags(TF) {
+    assert(Offset >= 0 && "Offset is too large");
+    Val.MachineCPVal = v;
+    Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
+  }
+public:
+
+  bool isMachineConstantPoolEntry() const {
+    return Offset < 0;
+  }
+
+  const Constant *getConstVal() const {
+    assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
+    return Val.ConstVal;
+  }
+
+  MachineConstantPoolValue *getMachineCPVal() const {
+    assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
+    return Val.MachineCPVal;
+  }
+
+  int getOffset() const {
+    return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
+  }
+
+  // Return the alignment of this constant pool object, which is either 0 (for
+  // default alignment) or the desired value.
+  unsigned getAlignment() const { return Alignment; }
+  unsigned char getTargetFlags() const { return TargetFlags; }
+
+  Type *getType() const;
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::ConstantPool ||
+           N->getOpcode() == ISD::TargetConstantPool;
+  }
+};
+
+/// Completely target-dependent object reference.
+class TargetIndexSDNode : public SDNode {
+  unsigned char TargetFlags;
+  int Index;
+  int64_t Offset;
+  friend class SelectionDAG;
+public:
+
+  TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned char TF)
+    : SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)),
+      TargetFlags(TF), Index(Idx), Offset(Ofs) {}
+public:
+
+  unsigned char getTargetFlags() const { return TargetFlags; }
+  int getIndex() const { return Index; }
+  int64_t getOffset() const { return Offset; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::TargetIndex;
+  }
+};
+
+class BasicBlockSDNode : public SDNode {
+  MachineBasicBlock *MBB;
+  friend class SelectionDAG;
+  /// Debug info is meaningful and potentially useful here, but we create
+  /// blocks out of order when they're jumped to, which makes it a bit
+  /// harder.  Let's see if we need it first.
+  explicit BasicBlockSDNode(MachineBasicBlock *mbb)
+    : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
+  {}
+public:
+
+  MachineBasicBlock *getBasicBlock() const { return MBB; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::BasicBlock;
+  }
+};
+
+/// BuildVectorSDNode - A "pseudo-class" with methods for operating on
+/// BUILD_VECTORs.
+class BuildVectorSDNode : public SDNode {
+  // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
+  explicit BuildVectorSDNode() LLVM_DELETED_FUNCTION;
+public:
+  /// isConstantSplat - Check if this is a constant splat, and if so, find the
+  /// smallest element size that splats the vector.  If MinSplatBits is
+  /// nonzero, the element size must be at least that large.  Note that the
+  /// splat element may be the entire vector (i.e., a one element vector).
+  /// Returns the splat element value in SplatValue.  Any undefined bits in
+  /// that value are zero, and the corresponding bits in the SplatUndef mask
+  /// are set.  The SplatBitSize value is set to the splat element size in
+  /// bits.  HasAnyUndefs is set to true if any bits in the vector are
+  /// undefined.  isBigEndian describes the endianness of the target.
+  bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
+                       unsigned &SplatBitSize, bool &HasAnyUndefs,
+                       unsigned MinSplatBits = 0,
+                       bool isBigEndian = false) const;
+
+  /// \brief Returns the splatted value or a null value if this is not a splat.
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
+
+  /// \brief Returns the splatted constant or null if this is not a constant
+  /// splat.
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  ConstantSDNode *
+  getConstantSplatNode(BitVector *UndefElements = nullptr) const;
+
+  /// \brief Returns the splatted constant FP or null if this is not a constant
+  /// FP splat.
+  ///
+  /// If passed a non-null UndefElements bitvector, it will resize it to match
+  /// the vector width and set the bits where elements are undef.
+  ConstantFPSDNode *
+  getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
+
+  bool isConstant() const;
+
+  static inline bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::BUILD_VECTOR;
+  }
+};
+
+/// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is
+/// used when the SelectionDAG needs to make a simple reference to something
+/// in the LLVM IR representation.
+///
+class SrcValueSDNode : public SDNode {
+  const Value *V;
+  friend class SelectionDAG;
+  /// Create a SrcValue for a general value.
+  explicit SrcValueSDNode(const Value *v)
+    : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
+
+public:
+  /// getValue - return the contained Value.
+  const Value *getValue() const { return V; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::SRCVALUE;
+  }
+};
+
+class MDNodeSDNode : public SDNode {
+  const MDNode *MD;
+  friend class SelectionDAG;
+  explicit MDNodeSDNode(const MDNode *md)
+  : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
+  {}
+public:
+
+  const MDNode *getMD() const { return MD; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::MDNODE_SDNODE;
+  }
+};
+
+class RegisterSDNode : public SDNode {
+  unsigned Reg;
+  friend class SelectionDAG;
+  RegisterSDNode(unsigned reg, EVT VT)
+    : SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {
+  }
+public:
+
+  unsigned getReg() const { return Reg; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::Register;
+  }
+};
+
+class RegisterMaskSDNode : public SDNode {
+  // The memory for RegMask is not owned by the node.
+  const uint32_t *RegMask;
+  friend class SelectionDAG;
+  RegisterMaskSDNode(const uint32_t *mask)
+    : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
+      RegMask(mask) {}
+public:
+
+  const uint32_t *getRegMask() const { return RegMask; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::RegisterMask;
+  }
+};
+
+class BlockAddressSDNode : public SDNode {
+  const BlockAddress *BA;
+  int64_t Offset;
+  unsigned char TargetFlags;
+  friend class SelectionDAG;
+  BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
+                     int64_t o, unsigned char Flags)
+    : SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)),
+             BA(ba), Offset(o), TargetFlags(Flags) {
+  }
+public:
+  const BlockAddress *getBlockAddress() const { return BA; }
+  int64_t getOffset() const { return Offset; }
+  unsigned char getTargetFlags() const { return TargetFlags; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::BlockAddress ||
+           N->getOpcode() == ISD::TargetBlockAddress;
+  }
+};
+
+class EHLabelSDNode : public SDNode {
+  SDUse Chain;
+  MCSymbol *Label;
+  friend class SelectionDAG;
+  EHLabelSDNode(unsigned Order, DebugLoc dl, SDValue ch, MCSymbol *L)
+    : SDNode(ISD::EH_LABEL, Order, dl, getSDVTList(MVT::Other)), Label(L) {
+    InitOperands(&Chain, ch);
+  }
+public:
+  MCSymbol *getLabel() const { return Label; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::EH_LABEL;
+  }
+};
+
+class ExternalSymbolSDNode : public SDNode {
+  const char *Symbol;
+  unsigned char TargetFlags;
+
+  friend class SelectionDAG;
+  ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT)
+    : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
+             0, DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
+  }
+public:
+
+  const char *getSymbol() const { return Symbol; }
+  unsigned char getTargetFlags() const { return TargetFlags; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::ExternalSymbol ||
+           N->getOpcode() == ISD::TargetExternalSymbol;
+  }
+};
+
+class CondCodeSDNode : public SDNode {
+  ISD::CondCode Condition;
+  friend class SelectionDAG;
+  explicit CondCodeSDNode(ISD::CondCode Cond)
+    : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
+      Condition(Cond) {
+  }
+public:
+
+  ISD::CondCode get() const { return Condition; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::CONDCODE;
+  }
+};
+
+/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the
+/// future and most targets don't support it.
+class CvtRndSatSDNode : public SDNode {
+  ISD::CvtCode CvtCode;
+  friend class SelectionDAG;
+  explicit CvtRndSatSDNode(EVT VT, unsigned Order, DebugLoc dl,
+                           ArrayRef<SDValue> Ops, ISD::CvtCode Code)
+    : SDNode(ISD::CONVERT_RNDSAT, Order, dl, getSDVTList(VT), Ops),
+      CvtCode(Code) {
+    assert(Ops.size() == 5 && "wrong number of operations");
+  }
+public:
+  ISD::CvtCode getCvtCode() const { return CvtCode; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::CONVERT_RNDSAT;
+  }
+};
+
+/// VTSDNode - This class is used to represent EVT's, which are used
+/// to parameterize some operations.
+class VTSDNode : public SDNode {
+  EVT ValueType;
+  friend class SelectionDAG;
+  explicit VTSDNode(EVT VT)
+    : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
+      ValueType(VT) {
+  }
+public:
+
+  EVT getVT() const { return ValueType; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::VALUETYPE;
+  }
+};
+
+/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
+///
+class LSBaseSDNode : public MemSDNode {
+  //! Operand array for load and store
+  /*!
+    \note Moving this array to the base class captures more
+    common functionality shared between LoadSDNode and
+    StoreSDNode
+   */
+  SDUse Ops[4];
+public:
+  LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, DebugLoc dl,
+               SDValue *Operands, unsigned numOperands,
+               SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
+               MachineMemOperand *MMO)
+    : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
+    SubclassData |= AM << 2;
+    assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+    InitOperands(Ops, Operands, numOperands);
+    assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
+           "Only indexed loads and stores have a non-undef offset operand");
+  }
+
+  const SDValue &getOffset() const {
+    return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
+  }
+
+  /// getAddressingMode - Return the addressing mode for this load or store:
+  /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
+  ISD::MemIndexedMode getAddressingMode() const {
+    return ISD::MemIndexedMode((SubclassData >> 2) & 7);
+  }
+
+  /// isIndexed - Return true if this is a pre/post inc/dec load/store.
+  bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
+
+  /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store.
+  bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::LOAD ||
+           N->getOpcode() == ISD::STORE;
+  }
+};
+
+/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
+///
+class LoadSDNode : public LSBaseSDNode {
+  friend class SelectionDAG;
+  LoadSDNode(SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs,
+             ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT,
+             MachineMemOperand *MMO)
+    : LSBaseSDNode(ISD::LOAD, Order, dl, ChainPtrOff, 3, VTs, AM, MemVT, MMO) {
+    SubclassData |= (unsigned short)ETy;
+    assert(getExtensionType() == ETy && "LoadExtType encoding error!");
+    assert(readMem() && "Load MachineMemOperand is not a load!");
+    assert(!writeMem() && "Load MachineMemOperand is a store!");
+  }
+public:
+
+  /// getExtensionType - Return whether this is a plain node,
+  /// or one of the varieties of value-extending loads.
+  ISD::LoadExtType getExtensionType() const {
+    return ISD::LoadExtType(SubclassData & 3);
+  }
+
+  const SDValue &getBasePtr() const { return getOperand(1); }
+  const SDValue &getOffset() const { return getOperand(2); }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::LOAD;
+  }
+};
+
+/// StoreSDNode - This class is used to represent ISD::STORE nodes.
+///
+class StoreSDNode : public LSBaseSDNode {
+  friend class SelectionDAG;
+  StoreSDNode(SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl,
+              SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
+              MachineMemOperand *MMO)
+    : LSBaseSDNode(ISD::STORE, Order, dl, ChainValuePtrOff, 4,
+                   VTs, AM, MemVT, MMO) {
+    SubclassData |= (unsigned short)isTrunc;
+    assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
+    assert(!readMem() && "Store MachineMemOperand is a load!");
+    assert(writeMem() && "Store MachineMemOperand is not a store!");
+  }
+public:
+
+  /// isTruncatingStore - Return true if the op does a truncation before store.
+  /// For integers this is the same as doing a TRUNCATE and storing the result.
+  /// For floats, it is the same as doing an FP_ROUND and storing the result.
+  bool isTruncatingStore() const { return SubclassData & 1; }
+
+  const SDValue &getValue() const { return getOperand(1); }
+  const SDValue &getBasePtr() const { return getOperand(2); }
+  const SDValue &getOffset() const { return getOperand(3); }
+
+  static bool classof(const SDNode *N) {
+    return N->getOpcode() == ISD::STORE;
+  }
+};
+
+/// MachineSDNode - An SDNode that represents everything that will be needed
+/// to construct a MachineInstr. These nodes are created during the
+/// instruction selection proper phase.
+///
+class MachineSDNode : public SDNode {
+public:
+  typedef MachineMemOperand **mmo_iterator;
+
+private:
+  friend class SelectionDAG;
+  MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs)
+    : SDNode(Opc, Order, DL, VTs), MemRefs(nullptr), MemRefsEnd(nullptr) {}
+
+  /// LocalOperands - Operands for this instruction, if they fit here. If
+  /// they don't, this field is unused.
+  SDUse LocalOperands[4];
+
+  /// MemRefs - Memory reference descriptions for this instruction.
+  mmo_iterator MemRefs;
+  mmo_iterator MemRefsEnd;
+
+public:
+  mmo_iterator memoperands_begin() const { return MemRefs; }
+  mmo_iterator memoperands_end() const { return MemRefsEnd; }
+  bool memoperands_empty() const { return MemRefsEnd == MemRefs; }
+
+  /// setMemRefs - Assign this MachineSDNodes's memory reference descriptor
+  /// list. This does not transfer ownership.
+  void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
+    for (mmo_iterator MMI = NewMemRefs, MME = NewMemRefsEnd; MMI != MME; ++MMI)
+      assert(*MMI && "Null mem ref detected!");
+    MemRefs = NewMemRefs;
+    MemRefsEnd = NewMemRefsEnd;
+  }
+
+  static bool classof(const SDNode *N) {
+    return N->isMachineOpcode();
+  }
+};
+
+class SDNodeIterator : public std::iterator<std::forward_iterator_tag,
+                                            SDNode, ptrdiff_t> {
+  const SDNode *Node;
+  unsigned Operand;
+
+  SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
+public:
+  bool operator==(const SDNodeIterator& x) const {
+    return Operand == x.Operand;
+  }
+  bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
+
+  const SDNodeIterator &operator=(const SDNodeIterator &I) {
+    assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
+    Operand = I.Operand;
+    return *this;
+  }
+
+  pointer operator*() const {
+    return Node->getOperand(Operand).getNode();
+  }
+  pointer operator->() const { return operator*(); }
+
+  SDNodeIterator& operator++() {                // Preincrement
+    ++Operand;
+    return *this;
+  }
+  SDNodeIterator operator++(int) { // Postincrement
+    SDNodeIterator tmp = *this; ++*this; return tmp;
+  }
+  size_t operator-(SDNodeIterator Other) const {
+    assert(Node == Other.Node &&
+           "Cannot compare iterators of two different nodes!");
+    return Operand - Other.Operand;
+  }
+
+  static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
+  static SDNodeIterator end  (const SDNode *N) {
+    return SDNodeIterator(N, N->getNumOperands());
+  }
+
+  unsigned getOperand() const { return Operand; }
+  const SDNode *getNode() const { return Node; }
+};
+
+template <> struct GraphTraits<SDNode*> {
+  typedef SDNode NodeType;
+  typedef SDNodeIterator ChildIteratorType;
+  static inline NodeType *getEntryNode(SDNode *N) { return N; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return SDNodeIterator::begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return SDNodeIterator::end(N);
+  }
+};
+
+/// LargestSDNode - The largest SDNode class.
+///
+typedef AtomicSDNode LargestSDNode;
+
+/// MostAlignedSDNode - The SDNode class with the greatest alignment
+/// requirement.
+///
+typedef GlobalAddressSDNode MostAlignedSDNode;
+
+namespace ISD {
+  /// isNormalLoad - Returns true if the specified node is a non-extending
+  /// and unindexed load.
+  inline bool isNormalLoad(const SDNode *N) {
+    const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N);
+    return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
+      Ld->getAddressingMode() == ISD::UNINDEXED;
+  }
+
+  /// isNON_EXTLoad - Returns true if the specified node is a non-extending
+  /// load.
+  inline bool isNON_EXTLoad(const SDNode *N) {
+    return isa<LoadSDNode>(N) &&
+      cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+  }
+
+  /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
+  ///
+  inline bool isEXTLoad(const SDNode *N) {
+    return isa<LoadSDNode>(N) &&
+      cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+  }
+
+  /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
+  ///
+  inline bool isSEXTLoad(const SDNode *N) {
+    return isa<LoadSDNode>(N) &&
+      cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+  }
+
+  /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
+  ///
+  inline bool isZEXTLoad(const SDNode *N) {
+    return isa<LoadSDNode>(N) &&
+      cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+  }
+
+  /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load.
+  ///
+  inline bool isUNINDEXEDLoad(const SDNode *N) {
+    return isa<LoadSDNode>(N) &&
+      cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+  }
+
+  /// isNormalStore - Returns true if the specified node is a non-truncating
+  /// and unindexed store.
+  inline bool isNormalStore(const SDNode *N) {
+    const StoreSDNode *St = dyn_cast<StoreSDNode>(N);
+    return St && !St->isTruncatingStore() &&
+      St->getAddressingMode() == ISD::UNINDEXED;
+  }
+
+  /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
+  /// store.
+  inline bool isNON_TRUNCStore(const SDNode *N) {
+    return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore();
+  }
+
+  /// isTRUNCStore - Returns true if the specified node is a truncating
+  /// store.
+  inline bool isTRUNCStore(const SDNode *N) {
+    return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore();
+  }
+
+  /// isUNINDEXEDStore - Returns true if the specified node is an
+  /// unindexed store.
+  inline bool isUNINDEXEDStore(const SDNode *N) {
+    return isa<StoreSDNode>(N) &&
+      cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+  }
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
new file mode 100644
index 0000000..00bb22b
--- /dev/null
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -0,0 +1,710 @@
+//===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements SlotIndex and related classes. The purpose of SlotIndex
+// is to describe a position at which a register can become live, or cease to
+// be live.
+//
+// SlotIndex is mostly a proxy for entries of the SlotIndexList, a class which
+// is held is LiveIntervals and provides the real numbering. This allows
+// LiveIntervals to perform largely transparent renumbering.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SLOTINDEXES_H
+#define LLVM_CODEGEN_SLOTINDEXES_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+  /// This class represents an entry in the slot index list held in the
+  /// SlotIndexes pass. It should not be used directly. See the
+  /// SlotIndex & SlotIndexes classes for the public interface to this
+  /// information.
+  class IndexListEntry : public ilist_node<IndexListEntry> {
+    MachineInstr *mi;
+    unsigned index;
+
+  public:
+
+    IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
+
+    MachineInstr* getInstr() const { return mi; }
+    void setInstr(MachineInstr *mi) {
+      this->mi = mi;
+    }
+
+    unsigned getIndex() const { return index; }
+    void setIndex(unsigned index) {
+      this->index = index;
+    }
+
+#ifdef EXPENSIVE_CHECKS
+    // When EXPENSIVE_CHECKS is defined, "erased" index list entries will
+    // actually be moved to a "graveyard" list, and have their pointers
+    // poisoned, so that dangling SlotIndex access can be reliably detected.
+    void setPoison() {
+      intptr_t tmp = reinterpret_cast<intptr_t>(mi);
+      assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?");
+      tmp |= 0x1;
+      mi = reinterpret_cast<MachineInstr*>(tmp);
+    }
+
+    bool isPoisoned() const { return (reinterpret_cast<intptr_t>(mi) & 0x1) == 0x1; }
+#endif // EXPENSIVE_CHECKS
+
+  };
+
+  template <>
+  struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> {
+  private:
+    mutable ilist_half_node<IndexListEntry> Sentinel;
+  public:
+    IndexListEntry *createSentinel() const {
+      return static_cast<IndexListEntry*>(&Sentinel);
+    }
+    void destroySentinel(IndexListEntry *) const {}
+
+    IndexListEntry *provideInitialHead() const { return createSentinel(); }
+    IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); }
+    static void noteHead(IndexListEntry*, IndexListEntry*) {}
+    void deleteNode(IndexListEntry *N) {}
+
+  private:
+    void createNode(const IndexListEntry &);
+  };
+
+  /// SlotIndex - An opaque wrapper around machine indexes.
+  class SlotIndex {
+    friend class SlotIndexes;
+
+    enum Slot {
+      /// Basic block boundary.  Used for live ranges entering and leaving a
+      /// block without being live in the layout neighbor.  Also used as the
+      /// def slot of PHI-defs.
+      Slot_Block,
+
+      /// Early-clobber register use/def slot.  A live range defined at
+      /// Slot_EarlyCLobber interferes with normal live ranges killed at
+      /// Slot_Register.  Also used as the kill slot for live ranges tied to an
+      /// early-clobber def.
+      Slot_EarlyClobber,
+
+      /// Normal register use/def slot.  Normal instructions kill and define
+      /// register live ranges at this slot.
+      Slot_Register,
+
+      /// Dead def kill point.  Kill slot for a live range that is defined by
+      /// the same instruction (Slot_Register or Slot_EarlyClobber), but isn't
+      /// used anywhere.
+      Slot_Dead,
+
+      Slot_Count
+    };
+
+    PointerIntPair<IndexListEntry*, 2, unsigned> lie;
+
+    SlotIndex(IndexListEntry *entry, unsigned slot)
+      : lie(entry, slot) {}
+
+    IndexListEntry* listEntry() const {
+      assert(isValid() && "Attempt to compare reserved index.");
+#ifdef EXPENSIVE_CHECKS
+      assert(!lie.getPointer()->isPoisoned() &&
+             "Attempt to access deleted list-entry.");
+#endif // EXPENSIVE_CHECKS
+      return lie.getPointer();
+    }
+
+    unsigned getIndex() const {
+      return listEntry()->getIndex() | getSlot();
+    }
+
+    /// Returns the slot for this SlotIndex.
+    Slot getSlot() const {
+      return static_cast<Slot>(lie.getInt());
+    }
+
+  public:
+    enum {
+      /// The default distance between instructions as returned by distance().
+      /// This may vary as instructions are inserted and removed.
+      InstrDist = 4 * Slot_Count
+    };
+
+    /// Construct an invalid index.
+    SlotIndex() : lie(nullptr, 0) {}
+
+    // Construct a new slot index from the given one, and set the slot.
+    SlotIndex(const SlotIndex &li, Slot s) : lie(li.listEntry(), unsigned(s)) {
+      assert(lie.getPointer() != nullptr &&
+             "Attempt to construct index with 0 pointer.");
+    }
+
+    /// Returns true if this is a valid index. Invalid indicies do
+    /// not point into an index table, and cannot be compared.
+    bool isValid() const {
+      return lie.getPointer();
+    }
+
+    /// Return true for a valid index.
+    LLVM_EXPLICIT operator bool() const { return isValid(); }
+
+    /// Print this index to the given raw_ostream.
+    void print(raw_ostream &os) const;
+
+    /// Dump this index to stderr.
+    void dump() const;
+
+    /// Compare two SlotIndex objects for equality.
+    bool operator==(SlotIndex other) const {
+      return lie == other.lie;
+    }
+    /// Compare two SlotIndex objects for inequality.
+    bool operator!=(SlotIndex other) const {
+      return lie != other.lie;
+    }
+
+    /// Compare two SlotIndex objects. Return true if the first index
+    /// is strictly lower than the second.
+    bool operator<(SlotIndex other) const {
+      return getIndex() < other.getIndex();
+    }
+    /// Compare two SlotIndex objects. Return true if the first index
+    /// is lower than, or equal to, the second.
+    bool operator<=(SlotIndex other) const {
+      return getIndex() <= other.getIndex();
+    }
+
+    /// Compare two SlotIndex objects. Return true if the first index
+    /// is greater than the second.
+    bool operator>(SlotIndex other) const {
+      return getIndex() > other.getIndex();
+    }
+
+    /// Compare two SlotIndex objects. Return true if the first index
+    /// is greater than, or equal to, the second.
+    bool operator>=(SlotIndex other) const {
+      return getIndex() >= other.getIndex();
+    }
+
+    /// isSameInstr - Return true if A and B refer to the same instruction.
+    static bool isSameInstr(SlotIndex A, SlotIndex B) {
+      return A.lie.getPointer() == B.lie.getPointer();
+    }
+
+    /// isEarlierInstr - Return true if A refers to an instruction earlier than
+    /// B. This is equivalent to A < B && !isSameInstr(A, B).
+    static bool isEarlierInstr(SlotIndex A, SlotIndex B) {
+      return A.listEntry()->getIndex() < B.listEntry()->getIndex();
+    }
+
+    /// Return the distance from this index to the given one.
+    int distance(SlotIndex other) const {
+      return other.getIndex() - getIndex();
+    }
+
+    /// Return the scaled distance from this index to the given one, where all
+    /// slots on the same instruction have zero distance.
+    int getInstrDistance(SlotIndex other) const {
+      return (other.listEntry()->getIndex() - listEntry()->getIndex())
+        / Slot_Count;
+    }
+
+    /// isBlock - Returns true if this is a block boundary slot.
+    bool isBlock() const { return getSlot() == Slot_Block; }
+
+    /// isEarlyClobber - Returns true if this is an early-clobber slot.
+    bool isEarlyClobber() const { return getSlot() == Slot_EarlyClobber; }
+
+    /// isRegister - Returns true if this is a normal register use/def slot.
+    /// Note that early-clobber slots may also be used for uses and defs.
+    bool isRegister() const { return getSlot() == Slot_Register; }
+
+    /// isDead - Returns true if this is a dead def kill slot.
+    bool isDead() const { return getSlot() == Slot_Dead; }
+
+    /// Returns the base index for associated with this index. The base index
+    /// is the one associated with the Slot_Block slot for the instruction
+    /// pointed to by this index.
+    SlotIndex getBaseIndex() const {
+      return SlotIndex(listEntry(), Slot_Block);
+    }
+
+    /// Returns the boundary index for associated with this index. The boundary
+    /// index is the one associated with the Slot_Block slot for the instruction
+    /// pointed to by this index.
+    SlotIndex getBoundaryIndex() const {
+      return SlotIndex(listEntry(), Slot_Dead);
+    }
+
+    /// Returns the register use/def slot in the current instruction for a
+    /// normal or early-clobber def.
+    SlotIndex getRegSlot(bool EC = false) const {
+      return SlotIndex(listEntry(), EC ? Slot_EarlyClobber : Slot_Register);
+    }
+
+    /// Returns the dead def kill slot for the current instruction.
+    SlotIndex getDeadSlot() const {
+      return SlotIndex(listEntry(), Slot_Dead);
+    }
+
+    /// Returns the next slot in the index list. This could be either the
+    /// next slot for the instruction pointed to by this index or, if this
+    /// index is a STORE, the first slot for the next instruction.
+    /// WARNING: This method is considerably more expensive than the methods
+    /// that return specific slots (getUseIndex(), etc). If you can - please
+    /// use one of those methods.
+    SlotIndex getNextSlot() const {
+      Slot s = getSlot();
+      if (s == Slot_Dead) {
+        return SlotIndex(listEntry()->getNextNode(), Slot_Block);
+      }
+      return SlotIndex(listEntry(), s + 1);
+    }
+
+    /// Returns the next index. This is the index corresponding to the this
+    /// index's slot, but for the next instruction.
+    SlotIndex getNextIndex() const {
+      return SlotIndex(listEntry()->getNextNode(), getSlot());
+    }
+
+    /// Returns the previous slot in the index list. This could be either the
+    /// previous slot for the instruction pointed to by this index or, if this
+    /// index is a Slot_Block, the last slot for the previous instruction.
+    /// WARNING: This method is considerably more expensive than the methods
+    /// that return specific slots (getUseIndex(), etc). If you can - please
+    /// use one of those methods.
+    SlotIndex getPrevSlot() const {
+      Slot s = getSlot();
+      if (s == Slot_Block) {
+        return SlotIndex(listEntry()->getPrevNode(), Slot_Dead);
+      }
+      return SlotIndex(listEntry(), s - 1);
+    }
+
+    /// Returns the previous index. This is the index corresponding to this
+    /// index's slot, but for the previous instruction.
+    SlotIndex getPrevIndex() const {
+      return SlotIndex(listEntry()->getPrevNode(), getSlot());
+    }
+
+  };
+
+  template <> struct isPodLike<SlotIndex> { static const bool value = true; };
+
+  inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
+    li.print(os);
+    return os;
+  }
+
+  typedef std::pair<SlotIndex, MachineBasicBlock*> IdxMBBPair;
+
+  inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
+    return V < IM.first;
+  }
+
+  inline bool operator<(const IdxMBBPair &IM, SlotIndex V) {
+    return IM.first < V;
+  }
+
+  struct Idx2MBBCompare {
+    bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
+      return LHS.first < RHS.first;
+    }
+  };
+
+  /// SlotIndexes pass.
+  ///
+  /// This pass assigns indexes to each instruction.
+  class SlotIndexes : public MachineFunctionPass {
+  private:
+
+    typedef ilist<IndexListEntry> IndexList;
+    IndexList indexList;
+
+#ifdef EXPENSIVE_CHECKS
+    IndexList graveyardList;
+#endif // EXPENSIVE_CHECKS
+
+    MachineFunction *mf;
+
+    typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
+    Mi2IndexMap mi2iMap;
+
+    /// MBBRanges - Map MBB number to (start, stop) indexes.
+    SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges;
+
+    /// Idx2MBBMap - Sorted list of pairs of index of first instruction
+    /// and MBB id.
+    SmallVector<IdxMBBPair, 8> idx2MBBMap;
+
+    // IndexListEntry allocator.
+    BumpPtrAllocator ileAllocator;
+
+    IndexListEntry* createEntry(MachineInstr *mi, unsigned index) {
+      IndexListEntry *entry =
+        static_cast<IndexListEntry*>(
+          ileAllocator.Allocate(sizeof(IndexListEntry),
+          alignOf<IndexListEntry>()));
+
+      new (entry) IndexListEntry(mi, index);
+
+      return entry;
+    }
+
+    /// Renumber locally after inserting curItr.
+    void renumberIndexes(IndexList::iterator curItr);
+
+  public:
+    static char ID;
+
+    SlotIndexes() : MachineFunctionPass(ID) {
+      initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
+    }
+
+    void getAnalysisUsage(AnalysisUsage &au) const override;
+    void releaseMemory() override;
+
+    bool runOnMachineFunction(MachineFunction &fn) override;
+
+    /// Dump the indexes.
+    void dump() const;
+
+    /// Renumber the index list, providing space for new instructions.
+    void renumberIndexes();
+
+    /// Repair indexes after adding and removing instructions.
+    void repairIndexesInRange(MachineBasicBlock *MBB,
+                              MachineBasicBlock::iterator Begin,
+                              MachineBasicBlock::iterator End);
+
+    /// Returns the zero index for this analysis.
+    SlotIndex getZeroIndex() {
+      assert(indexList.front().getIndex() == 0 && "First index is not 0?");
+      return SlotIndex(&indexList.front(), 0);
+    }
+
+    /// Returns the base index of the last slot in this analysis.
+    SlotIndex getLastIndex() {
+      return SlotIndex(&indexList.back(), 0);
+    }
+
+    /// Returns true if the given machine instr is mapped to an index,
+    /// otherwise returns false.
+    bool hasIndex(const MachineInstr *instr) const {
+      return mi2iMap.count(instr);
+    }
+
+    /// Returns the base index for the given instruction.
+    SlotIndex getInstructionIndex(const MachineInstr *MI) const {
+      // Instructions inside a bundle have the same number as the bundle itself.
+      Mi2IndexMap::const_iterator itr = mi2iMap.find(getBundleStart(MI));
+      assert(itr != mi2iMap.end() && "Instruction not found in maps.");
+      return itr->second;
+    }
+
+    /// Returns the instruction for the given index, or null if the given
+    /// index has no instruction associated with it.
+    MachineInstr* getInstructionFromIndex(SlotIndex index) const {
+      return index.isValid() ? index.listEntry()->getInstr() : nullptr;
+    }
+
+    /// Returns the next non-null index, if one exists.
+    /// Otherwise returns getLastIndex().
+    SlotIndex getNextNonNullIndex(SlotIndex Index) {
+      IndexList::iterator I = Index.listEntry();
+      IndexList::iterator E = indexList.end();
+      while (++I != E)
+        if (I->getInstr())
+          return SlotIndex(I, Index.getSlot());
+      // We reached the end of the function.
+      return getLastIndex();
+    }
+
+    /// getIndexBefore - Returns the index of the last indexed instruction
+    /// before MI, or the start index of its basic block.
+    /// MI is not required to have an index.
+    SlotIndex getIndexBefore(const MachineInstr *MI) const {
+      const MachineBasicBlock *MBB = MI->getParent();
+      assert(MBB && "MI must be inserted inna basic block");
+      MachineBasicBlock::const_iterator I = MI, B = MBB->begin();
+      for (;;) {
+        if (I == B)
+          return getMBBStartIdx(MBB);
+        --I;
+        Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
+        if (MapItr != mi2iMap.end())
+          return MapItr->second;
+      }
+    }
+
+    /// getIndexAfter - Returns the index of the first indexed instruction
+    /// after MI, or the end index of its basic block.
+    /// MI is not required to have an index.
+    SlotIndex getIndexAfter(const MachineInstr *MI) const {
+      const MachineBasicBlock *MBB = MI->getParent();
+      assert(MBB && "MI must be inserted inna basic block");
+      MachineBasicBlock::const_iterator I = MI, E = MBB->end();
+      for (;;) {
+        ++I;
+        if (I == E)
+          return getMBBEndIdx(MBB);
+        Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
+        if (MapItr != mi2iMap.end())
+          return MapItr->second;
+      }
+    }
+
+    /// Return the (start,end) range of the given basic block number.
+    const std::pair<SlotIndex, SlotIndex> &
+    getMBBRange(unsigned Num) const {
+      return MBBRanges[Num];
+    }
+
+    /// Return the (start,end) range of the given basic block.
+    const std::pair<SlotIndex, SlotIndex> &
+    getMBBRange(const MachineBasicBlock *MBB) const {
+      return getMBBRange(MBB->getNumber());
+    }
+
+    /// Returns the first index in the given basic block number.
+    SlotIndex getMBBStartIdx(unsigned Num) const {
+      return getMBBRange(Num).first;
+    }
+
+    /// Returns the first index in the given basic block.
+    SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+      return getMBBRange(mbb).first;
+    }
+
+    /// Returns the last index in the given basic block number.
+    SlotIndex getMBBEndIdx(unsigned Num) const {
+      return getMBBRange(Num).second;
+    }
+
+    /// Returns the last index in the given basic block.
+    SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+      return getMBBRange(mbb).second;
+    }
+
+    /// Returns the basic block which the given index falls in.
+    MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
+      if (MachineInstr *MI = getInstructionFromIndex(index))
+        return MI->getParent();
+      SmallVectorImpl<IdxMBBPair>::const_iterator I =
+        std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index);
+      // Take the pair containing the index
+      SmallVectorImpl<IdxMBBPair>::const_iterator J =
+        ((I != idx2MBBMap.end() && I->first > index) ||
+         (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I;
+
+      assert(J != idx2MBBMap.end() && J->first <= index &&
+             index < getMBBEndIdx(J->second) &&
+             "index does not correspond to an MBB");
+      return J->second;
+    }
+
+    bool findLiveInMBBs(SlotIndex start, SlotIndex end,
+                        SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
+      SmallVectorImpl<IdxMBBPair>::const_iterator itr =
+        std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
+      bool resVal = false;
+
+      while (itr != idx2MBBMap.end()) {
+        if (itr->first >= end)
+          break;
+        mbbs.push_back(itr->second);
+        resVal = true;
+        ++itr;
+      }
+      return resVal;
+    }
+
+    /// Returns the MBB covering the given range, or null if the range covers
+    /// more than one basic block.
+    MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const {
+
+      assert(start < end && "Backwards ranges not allowed.");
+
+      SmallVectorImpl<IdxMBBPair>::const_iterator itr =
+        std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
+
+      if (itr == idx2MBBMap.end()) {
+        itr = std::prev(itr);
+        return itr->second;
+      }
+
+      // Check that we don't cross the boundary into this block.
+      if (itr->first < end)
+        return nullptr;
+
+      itr = std::prev(itr);
+
+      if (itr->first <= start)
+        return itr->second;
+
+      return nullptr;
+    }
+
+    /// Insert the given machine instruction into the mapping. Returns the
+    /// assigned index.
+    /// If Late is set and there are null indexes between mi's neighboring
+    /// instructions, create the new index after the null indexes instead of
+    /// before them.
+    SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late = false) {
+      assert(!mi->isInsideBundle() &&
+             "Instructions inside bundles should use bundle start's slot.");
+      assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed.");
+      // Numbering DBG_VALUE instructions could cause code generation to be
+      // affected by debug information.
+      assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions.");
+
+      assert(mi->getParent() != nullptr && "Instr must be added to function.");
+
+      // Get the entries where mi should be inserted.
+      IndexList::iterator prevItr, nextItr;
+      if (Late) {
+        // Insert mi's index immediately before the following instruction.
+        nextItr = getIndexAfter(mi).listEntry();
+        prevItr = std::prev(nextItr);
+      } else {
+        // Insert mi's index immediately after the preceding instruction.
+        prevItr = getIndexBefore(mi).listEntry();
+        nextItr = std::next(prevItr);
+      }
+
+      // Get a number for the new instr, or 0 if there's no room currently.
+      // In the latter case we'll force a renumber later.
+      unsigned dist = ((nextItr->getIndex() - prevItr->getIndex())/2) & ~3u;
+      unsigned newNumber = prevItr->getIndex() + dist;
+
+      // Insert a new list entry for mi.
+      IndexList::iterator newItr =
+        indexList.insert(nextItr, createEntry(mi, newNumber));
+
+      // Renumber locally if we need to.
+      if (dist == 0)
+        renumberIndexes(newItr);
+
+      SlotIndex newIndex(&*newItr, SlotIndex::Slot_Block);
+      mi2iMap.insert(std::make_pair(mi, newIndex));
+      return newIndex;
+    }
+
+    /// Remove the given machine instruction from the mapping.
+    void removeMachineInstrFromMaps(MachineInstr *mi) {
+      // remove index -> MachineInstr and
+      // MachineInstr -> index mappings
+      Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
+      if (mi2iItr != mi2iMap.end()) {
+        IndexListEntry *miEntry(mi2iItr->second.listEntry());
+        assert(miEntry->getInstr() == mi && "Instruction indexes broken.");
+        // FIXME: Eventually we want to actually delete these indexes.
+        miEntry->setInstr(nullptr);
+        mi2iMap.erase(mi2iItr);
+      }
+    }
+
+    /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
+    /// maps used by register allocator.
+    void replaceMachineInstrInMaps(MachineInstr *mi, MachineInstr *newMI) {
+      Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
+      if (mi2iItr == mi2iMap.end())
+        return;
+      SlotIndex replaceBaseIndex = mi2iItr->second;
+      IndexListEntry *miEntry(replaceBaseIndex.listEntry());
+      assert(miEntry->getInstr() == mi &&
+             "Mismatched instruction in index tables.");
+      miEntry->setInstr(newMI);
+      mi2iMap.erase(mi2iItr);
+      mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex));
+    }
+
+    /// Add the given MachineBasicBlock into the maps.
+    void insertMBBInMaps(MachineBasicBlock *mbb) {
+      MachineFunction::iterator nextMBB =
+        std::next(MachineFunction::iterator(mbb));
+
+      IndexListEntry *startEntry = nullptr;
+      IndexListEntry *endEntry = nullptr;
+      IndexList::iterator newItr;
+      if (nextMBB == mbb->getParent()->end()) {
+        startEntry = &indexList.back();
+        endEntry = createEntry(nullptr, 0);
+        newItr = indexList.insertAfter(startEntry, endEntry);
+      } else {
+        startEntry = createEntry(nullptr, 0);
+        endEntry = getMBBStartIdx(nextMBB).listEntry();
+        newItr = indexList.insert(endEntry, startEntry);
+      }
+
+      SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
+      SlotIndex endIdx(endEntry, SlotIndex::Slot_Block);
+
+      MachineFunction::iterator prevMBB(mbb);
+      assert(prevMBB != mbb->getParent()->end() &&
+             "Can't insert a new block at the beginning of a function.");
+      --prevMBB;
+      MBBRanges[prevMBB->getNumber()].second = startIdx;
+
+      assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&
+             "Blocks must be added in order");
+      MBBRanges.push_back(std::make_pair(startIdx, endIdx));
+      idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
+
+      renumberIndexes(newItr);
+      std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
+    }
+
+    /// \brief Free the resources that were required to maintain a SlotIndex.
+    ///
+    /// Once an index is no longer needed (for instance because the instruction
+    /// at that index has been moved), the resources required to maintain the
+    /// index can be relinquished to reduce memory use and improve renumbering
+    /// performance. Any remaining SlotIndex objects that point to the same
+    /// index are left 'dangling' (much the same as a dangling pointer to a
+    /// freed object) and should not be accessed, except to destruct them.
+    ///
+    /// Like dangling pointers, access to dangling SlotIndexes can cause
+    /// painful-to-track-down bugs, especially if the memory for the index
+    /// previously pointed to has been re-used. To detect dangling SlotIndex
+    /// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" indexes to
+    /// be retained in a graveyard instead of being freed. Operations on indexes
+    /// in the graveyard will trigger an assertion.
+    void eraseIndex(SlotIndex index) {
+      IndexListEntry *entry = index.listEntry();
+#ifdef EXPENSIVE_CHECKS
+      indexList.remove(entry);
+      graveyardList.push_back(entry);
+      entry->setPoison();
+#else
+      indexList.erase(entry);
+#endif
+    }
+
+  };
+
+
+  // Specialize IntervalMapInfo for half-open slot index intervals.
+  template <>
+  struct IntervalMapInfo<SlotIndex> : IntervalMapHalfOpenInfo<SlotIndex> {
+  };
+
+}
+
+#endif // LLVM_CODEGEN_SLOTINDEXES_H
diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
new file mode 100644
index 0000000..6f07546
--- /dev/null
+++ b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
@@ -0,0 +1,64 @@
+//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass calculates the liveness for each basic block in a function and
+// attaches the register live-out information to a patchpoint intrinsic (if
+// present).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+#define LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+
+namespace llvm {
+
+/// \brief This pass calculates the liveness information for each basic block in
+/// a function and attaches the register live-out information to a patchpoint
+/// intrinsic if present.
+///
+/// This pass can be disabled via the -enable-patchpoint-liveness=false flag.
+/// The pass skips functions that don't have any patchpoint intrinsics. The
+/// information provided by this pass is optional and not required by the
+/// aformentioned intrinsic to function.
+class StackMapLiveness : public MachineFunctionPass {
+  MachineFunction *MF;
+  const TargetRegisterInfo *TRI;
+  LivePhysRegs LiveRegs;
+public:
+  static char ID;
+
+  /// \brief Default construct and initialize the pass.
+  StackMapLiveness();
+
+  /// \brief Tell the pass manager which passes we depend on and what
+  /// information we preserve.
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// \brief Calculate the liveness information for the given machine function.
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+  /// \brief Performs the actual liveness calculation for the function.
+  bool calculateLiveness();
+
+  /// \brief Add the current register live set to the instruction.
+  void addLiveOutSetToMI(MachineInstr &MI);
+
+  /// \brief Create a register mask and initialize it with the registers from
+  /// the register live set.
+  uint32_t *createRegisterMask() const;
+};
+
+} // llvm namespace
+
+#endif // LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
new file mode 100644
index 0000000..5eddbb6
--- /dev/null
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -0,0 +1,199 @@
+//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
+
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_STACKMAPS
+#define LLVM_STACKMAPS
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class AsmPrinter;
+class MCExpr;
+class MCStreamer;
+
+/// \brief MI-level patchpoint operands.
+///
+/// MI patchpoint operations take the form:
+/// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
+///
+/// IR patchpoint intrinsics do not have the <cc> operand because calling
+/// convention is part of the subclass data.
+///
+/// SD patchpoint nodes do not have a def operand because it is part of the
+/// SDValue.
+///
+/// Patchpoints following the anyregcc convention are handled specially. For
+/// these, the stack map also records the location of the return value and
+/// arguments.
+class PatchPointOpers {
+public:
+  /// Enumerate the meta operands.
+  enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd };
+private:
+  const MachineInstr *MI;
+  bool HasDef;
+  bool IsAnyReg;
+public:
+  explicit PatchPointOpers(const MachineInstr *MI);
+
+  bool isAnyReg() const { return IsAnyReg; }
+  bool hasDef() const { return HasDef; }
+
+  unsigned getMetaIdx(unsigned Pos = 0) const {
+    assert(Pos < MetaEnd && "Meta operand index out of range.");
+    return (HasDef ? 1 : 0) + Pos;
+  }
+
+  const MachineOperand &getMetaOper(unsigned Pos) {
+    return MI->getOperand(getMetaIdx(Pos));
+  }
+
+  unsigned getArgIdx() const { return getMetaIdx() + MetaEnd; }
+
+  /// Get the operand index of the variable list of non-argument operands.
+  /// These hold the "live state".
+  unsigned getVarIdx() const {
+    return getMetaIdx() + MetaEnd
+      + MI->getOperand(getMetaIdx(NArgPos)).getImm();
+  }
+
+  /// Get the index at which stack map locations will be recorded.
+  /// Arguments are not recorded unless the anyregcc convention is used.
+  unsigned getStackMapStartIdx() const {
+    if (IsAnyReg)
+      return getArgIdx();
+    return getVarIdx();
+  }
+
+  /// \brief Get the next scratch register operand index.
+  unsigned getNextScratchIdx(unsigned StartIdx = 0) const;
+};
+
+class StackMaps {
+public:
+  struct Location {
+    enum LocationType { Unprocessed, Register, Direct, Indirect, Constant,
+                        ConstantIndex };
+    LocationType LocType;
+    unsigned Size;
+    unsigned Reg;
+    int64_t Offset;
+    Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {}
+    Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset)
+      : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
+  };
+
+  struct LiveOutReg {
+    unsigned short Reg;
+    unsigned short RegNo;
+    unsigned short Size;
+
+    LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
+    LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
+      : Reg(Reg), RegNo(RegNo), Size(Size) {}
+
+    void MarkInvalid() { Reg = 0; }
+
+    // Only sort by the dwarf register number.
+    bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
+    static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
+  };
+
+  // OpTypes are used to encode information about the following logical
+  // operand (which may consist of several MachineOperands) for the
+  // OpParser.
+  typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType;
+
+  StackMaps(AsmPrinter &AP);
+
+  /// \brief Generate a stackmap record for a stackmap instruction.
+  ///
+  /// MI must be a raw STACKMAP, not a PATCHPOINT.
+  void recordStackMap(const MachineInstr &MI);
+
+  /// \brief Generate a stackmap record for a patchpoint instruction.
+  void recordPatchPoint(const MachineInstr &MI);
+
+  /// If there is any stack map data, create a stack map section and serialize
+  /// the map info into it. This clears the stack map data structures
+  /// afterwards.
+  void serializeToStackMapSection();
+
+private:
+  static const char *WSMP;
+
+  typedef SmallVector<Location, 8> LocationVec;
+  typedef SmallVector<LiveOutReg, 8> LiveOutVec;
+  typedef MapVector<int64_t, int64_t> ConstantPool;
+  typedef MapVector<const MCSymbol *, uint64_t> FnStackSizeMap;
+
+  struct CallsiteInfo {
+    const MCExpr *CSOffsetExpr;
+    uint64_t ID;
+    LocationVec Locations;
+    LiveOutVec LiveOuts;
+    CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {}
+    CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
+                 LocationVec &Locations, LiveOutVec &LiveOuts)
+      : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations),
+        LiveOuts(LiveOuts) {}
+  };
+
+  typedef std::vector<CallsiteInfo> CallsiteInfoList;
+
+  AsmPrinter &AP;
+  CallsiteInfoList CSInfos;
+  ConstantPool ConstPool;
+  FnStackSizeMap FnStackSize;
+
+  MachineInstr::const_mop_iterator
+  parseOperand(MachineInstr::const_mop_iterator MOI,
+               MachineInstr::const_mop_iterator MOE,
+               LocationVec &Locs, LiveOutVec &LiveOuts) const;
+
+  /// \brief Create a live-out register record for the given register @p Reg.
+  LiveOutReg createLiveOutReg(unsigned Reg,
+                              const TargetRegisterInfo *TRI) const;
+
+  /// \brief Parse the register live-out mask and return a vector of live-out
+  /// registers that need to be recorded in the stackmap.
+  LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
+
+  /// This should be called by the MC lowering code _immediately_ before
+  /// lowering the MI to an MCInst. It records where the operands for the
+  /// instruction are stored, and outputs a label to record the offset of
+  /// the call from the start of the text section. In special cases (e.g. AnyReg
+  /// calling convention) the return register is also recorded if requested.
+  void recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
+                           MachineInstr::const_mop_iterator MOI,
+                           MachineInstr::const_mop_iterator MOE,
+                           bool recordResult = false);
+
+  /// \brief Emit the stackmap header.
+  void emitStackmapHeader(MCStreamer &OS);
+
+  /// \brief Emit the function frame record for each function.
+  void emitFunctionFrameRecords(MCStreamer &OS);
+
+  /// \brief Emit the constant pool.
+  void emitConstantPoolEntries(MCStreamer &OS);
+
+  /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call.
+  void emitCallsiteEntries(MCStreamer &OS, const TargetRegisterInfo *TRI);
+};
+
+}
+
+#endif // LLVM_STACKMAPS
diff --git a/include/llvm/CodeGen/StackProtector.h b/include/llvm/CodeGen/StackProtector.h
new file mode 100644
index 0000000..8cef85c
--- /dev/null
+++ b/include/llvm/CodeGen/StackProtector.h
@@ -0,0 +1,129 @@
+//===-- StackProtector.h - Stack Protector Insertion ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass inserts stack protectors into functions which need them. A variable
+// with a random value in it is stored onto the stack before the local variables
+// are allocated. Upon exiting the block, the stored value is checked. If it's
+// changed, then there was some sort of violation and the program aborts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKPROTECTOR_H
+#define LLVM_CODEGEN_STACKPROTECTOR_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/ValueMap.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetLowering.h"
+
+namespace llvm {
+class Function;
+class Module;
+class PHINode;
+
+class StackProtector : public FunctionPass {
+public:
+  /// SSPLayoutKind.  Stack Smashing Protection (SSP) rules require that
+  /// vulnerable stack allocations are located close the stack protector.
+  enum SSPLayoutKind {
+    SSPLK_None,       ///< Did not trigger a stack protector.  No effect on data
+                      ///< layout.
+    SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size.  Closest
+                      ///< to the stack protector.
+    SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest
+                      ///< to the stack protector.
+    SSPLK_AddrOf      ///< The address of this allocation is exposed and
+                      ///< triggered protection.  3rd closest to the protector.
+  };
+
+  /// A mapping of AllocaInsts to their required SSP layout.
+  typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap;
+
+private:
+  const TargetMachine *TM;
+
+  /// TLI - Keep a pointer of a TargetLowering to consult for determining
+  /// target type sizes.
+  const TargetLoweringBase *TLI;
+  const Triple Trip;
+
+  Function *F;
+  Module *M;
+
+  DominatorTree *DT;
+
+  /// Layout - Mapping of allocations to the required SSPLayoutKind.
+  /// StackProtector analysis will update this map when determining if an
+  /// AllocaInst triggers a stack protector.
+  SSPLayoutMap Layout;
+
+  /// \brief The minimum size of buffers that will receive stack smashing
+  /// protection when -fstack-protection is used.
+  unsigned SSPBufferSize;
+
+  /// VisitedPHIs - The set of PHI nodes visited when determining
+  /// if a variable's reference has been taken.  This set
+  /// is maintained to ensure we don't visit the same PHI node multiple
+  /// times.
+  SmallPtrSet<const PHINode *, 16> VisitedPHIs;
+
+  /// InsertStackProtectors - Insert code into the prologue and epilogue of
+  /// the function.
+  ///
+  ///  - The prologue code loads and stores the stack guard onto the stack.
+  ///  - The epilogue checks the value stored in the prologue against the
+  ///    original value. It calls __stack_chk_fail if they differ.
+  bool InsertStackProtectors();
+
+  /// CreateFailBB - Create a basic block to jump to when the stack protector
+  /// check fails.
+  BasicBlock *CreateFailBB();
+
+  /// ContainsProtectableArray - Check whether the type either is an array or
+  /// contains an array of sufficient size so that we need stack protectors
+  /// for it.
+  /// \param [out] IsLarge is set to true if a protectable array is found and
+  /// it is "large" ( >= ssp-buffer-size).  In the case of a structure with
+  /// multiple arrays, this gets set if any of them is large.
+  bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
+                                bool InStruct = false) const;
+
+  /// \brief Check whether a stack allocation has its address taken.
+  bool HasAddressTaken(const Instruction *AI);
+
+  /// RequiresStackProtector - Check whether or not this function needs a
+  /// stack protector based upon the stack protector level.
+  bool RequiresStackProtector();
+
+public:
+  static char ID; // Pass identification, replacement for typeid.
+  StackProtector()
+      : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) {
+    initializeStackProtectorPass(*PassRegistry::getPassRegistry());
+  }
+  StackProtector(const TargetMachine *TM)
+      : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()),
+        SSPBufferSize(8) {
+    initializeStackProtectorPass(*PassRegistry::getPassRegistry());
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addPreserved<DominatorTreeWrapperPass>();
+  }
+
+  SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
+  void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
+
+  bool runOnFunction(Function &Fn) override;
+};
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_STACKPROTECTOR_H
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
new file mode 100644
index 0000000..87f1401
--- /dev/null
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -0,0 +1,154 @@
+//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object 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 implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+namespace llvm {
+  class MachineModuleInfo;
+  class Mangler;
+  class MCAsmInfo;
+  class MCExpr;
+  class MCSection;
+  class MCSectionMachO;
+  class MCSymbol;
+  class MCContext;
+  class GlobalValue;
+  class TargetMachine;
+
+
+class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+  bool UseInitArray;
+
+public:
+  virtual ~TargetLoweringObjectFileELF() {}
+
+  void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM,
+                            const MCSymbol *Sym) const override;
+
+  /// Given a constant with the SectionKind, return a section that it should be
+  /// placed in.
+  const MCSection *getSectionForConstant(SectionKind Kind,
+                                         const Constant *C) const override;
+
+  const MCSection *getExplicitSectionGlobal(const GlobalValue *GV,
+                                        SectionKind Kind, Mangler &Mang,
+                                        const TargetMachine &TM) const override;
+
+  const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
+                                        SectionKind Kind, Mangler &Mang,
+                                        const TargetMachine &TM) const override;
+
+  /// Return an MCExpr to use for a reference to the specified type info global
+  /// variable from exception handling information.
+  const MCExpr *
+  getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+                          Mangler &Mang, const TargetMachine &TM,
+                          MachineModuleInfo *MMI,
+                          MCStreamer &Streamer) const override;
+
+  // The symbol that gets passed to .cfi_personality.
+  MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+                                    const TargetMachine &TM,
+                                    MachineModuleInfo *MMI) const override;
+
+  void InitializeELF(bool UseInitArray_);
+  const MCSection *getStaticCtorSection(unsigned Priority,
+                                        const MCSymbol *KeySym) const override;
+  const MCSection *getStaticDtorSection(unsigned Priority,
+                                        const MCSymbol *KeySym) const override;
+};
+
+
+
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+public:
+  virtual ~TargetLoweringObjectFileMachO() {}
+
+  /// Extract the dependent library name from a linker option string. Returns
+  /// StringRef() if the option does not specify a library.
+  StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
+
+  /// Emit the module flags that specify the garbage collection information.
+  void emitModuleFlags(MCStreamer &Streamer,
+                       ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
+                       Mangler &Mang, const TargetMachine &TM) const override;
+
+  bool isSectionAtomizableBySymbols(const MCSection &Section) const override;
+
+  const MCSection *
+    SelectSectionForGlobal(const GlobalValue *GV,
+                           SectionKind Kind, Mangler &Mang,
+                           const TargetMachine &TM) const override;
+
+  const MCSection *
+    getExplicitSectionGlobal(const GlobalValue *GV,
+                             SectionKind Kind, Mangler &Mang,
+                             const TargetMachine &TM) const override;
+
+  const MCSection *getSectionForConstant(SectionKind Kind,
+                                         const Constant *C) const override;
+
+  /// The mach-o version of this method defaults to returning a stub reference.
+  const MCExpr *
+  getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+                          Mangler &Mang, const TargetMachine &TM,
+                          MachineModuleInfo *MMI,
+                          MCStreamer &Streamer) const override;
+
+  // The symbol that gets passed to .cfi_personality.
+  MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+                                    const TargetMachine &TM,
+                                    MachineModuleInfo *MMI) const override;
+};
+
+
+
+class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+public:
+  virtual ~TargetLoweringObjectFileCOFF() {}
+
+  const MCSection *
+    getExplicitSectionGlobal(const GlobalValue *GV,
+                             SectionKind Kind, Mangler &Mang,
+                             const TargetMachine &TM) const override;
+
+  const MCSection *
+    SelectSectionForGlobal(const GlobalValue *GV,
+                           SectionKind Kind, Mangler &Mang,
+                           const TargetMachine &TM) const override;
+
+  /// Extract the dependent library name from a linker option string. Returns
+  /// StringRef() if the option does not specify a library.
+  StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
+
+  /// Emit Obj-C garbage collection and linker options. Only linker option
+  /// emission is implemented for COFF.
+  void emitModuleFlags(MCStreamer &Streamer,
+                       ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
+                       Mangler &Mang, const TargetMachine &TM) const override;
+
+  const MCSection *getStaticCtorSection(unsigned Priority,
+                                        const MCSymbol *KeySym) const override;
+  const MCSection *getStaticDtorSection(unsigned Priority,
+                                        const MCSymbol *KeySym) const override;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
new file mode 100644
index 0000000..690b70f
--- /dev/null
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -0,0 +1,180 @@
+//===-- llvm/CodeGen/TargetSchedule.h - Sched Machine Model -----*- 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 around MCSchedModel that allows the interface to
+// benefit from information currently only available in TargetInstrInfo.
+// Ideally, the scheduling interface would be fully defined in the MC layer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TARGETSCHEDULE_H
+#define LLVM_CODEGEN_TARGETSCHEDULE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+
+namespace llvm {
+
+class TargetRegisterInfo;
+class TargetSubtargetInfo;
+class TargetInstrInfo;
+class MachineInstr;
+
+/// Provide an instruction scheduling machine model to CodeGen passes.
+class TargetSchedModel {
+  // For efficiency, hold a copy of the statically defined MCSchedModel for this
+  // processor.
+  MCSchedModel SchedModel;
+  InstrItineraryData InstrItins;
+  const TargetSubtargetInfo *STI;
+  const TargetInstrInfo *TII;
+
+  SmallVector<unsigned, 16> ResourceFactors;
+  unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
+  unsigned ResourceLCM;   // Resource units per cycle. Latency normalization factor.
+public:
+  TargetSchedModel(): STI(nullptr), TII(nullptr) {}
+
+  /// \brief Initialize the machine model for instruction scheduling.
+  ///
+  /// The machine model API keeps a copy of the top-level MCSchedModel table
+  /// indices and may query TargetSubtargetInfo and TargetInstrInfo to resolve
+  /// dynamic properties.
+  void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti,
+            const TargetInstrInfo *tii);
+
+  /// Return the MCSchedClassDesc for this instruction.
+  const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
+
+  /// \brief TargetInstrInfo getter.
+  const TargetInstrInfo *getInstrInfo() const { return TII; }
+
+  /// \brief Return true if this machine model includes an instruction-level
+  /// scheduling model.
+  ///
+  /// This is more detailed than the course grain IssueWidth and default
+  /// latency properties, but separate from the per-cycle itinerary data.
+  bool hasInstrSchedModel() const;
+
+  const MCSchedModel *getMCSchedModel() const { return &SchedModel; }
+
+  /// \brief Return true if this machine model includes cycle-to-cycle itinerary
+  /// data.
+  ///
+  /// This models scheduling at each stage in the processor pipeline.
+  bool hasInstrItineraries() const;
+
+  const InstrItineraryData *getInstrItineraries() const {
+    if (hasInstrItineraries())
+      return &InstrItins;
+    return nullptr;
+  }
+
+  /// \brief Identify the processor corresponding to the current subtarget.
+  unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
+
+  /// \brief Maximum number of micro-ops that may be scheduled per cycle.
+  unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
+
+  /// \brief Return the number of issue slots required for this MI.
+  unsigned getNumMicroOps(const MachineInstr *MI,
+                          const MCSchedClassDesc *SC = nullptr) const;
+
+  /// \brief Get the number of kinds of resources for this target.
+  unsigned getNumProcResourceKinds() const {
+    return SchedModel.getNumProcResourceKinds();
+  }
+
+  /// \brief Get a processor resource by ID for convenience.
+  const MCProcResourceDesc *getProcResource(unsigned PIdx) const {
+    return SchedModel.getProcResource(PIdx);
+  }
+
+#ifndef NDEBUG
+  const char *getResourceName(unsigned PIdx) const {
+    if (!PIdx)
+      return "MOps";
+    return SchedModel.getProcResource(PIdx)->Name;
+  }
+#endif
+
+  typedef const MCWriteProcResEntry *ProcResIter;
+
+  // \brief Get an iterator into the processor resources consumed by this
+  // scheduling class.
+  ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const {
+    // The subtarget holds a single resource table for all processors.
+    return STI->getWriteProcResBegin(SC);
+  }
+  ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const {
+    return STI->getWriteProcResEnd(SC);
+  }
+
+  /// \brief Multiply the number of units consumed for a resource by this factor
+  /// to normalize it relative to other resources.
+  unsigned getResourceFactor(unsigned ResIdx) const {
+    return ResourceFactors[ResIdx];
+  }
+
+  /// \brief Multiply number of micro-ops by this factor to normalize it
+  /// relative to other resources.
+  unsigned getMicroOpFactor() const {
+    return MicroOpFactor;
+  }
+
+  /// \brief Multiply cycle count by this factor to normalize it relative to
+  /// other resources. This is the number of resource units per cycle.
+  unsigned getLatencyFactor() const {
+    return ResourceLCM;
+  }
+
+  /// \brief Number of micro-ops that may be buffered for OOO execution.
+  unsigned getMicroOpBufferSize() const { return SchedModel.MicroOpBufferSize; }
+
+  /// \brief Number of resource units that may be buffered for OOO execution.
+  /// \return The buffer size in resource units or -1 for unlimited.
+  int getResourceBufferSize(unsigned PIdx) const {
+    return SchedModel.getProcResource(PIdx)->BufferSize;
+  }
+
+  /// \brief Compute operand latency based on the available machine model.
+  ///
+  /// Compute and return the latency of the given data dependent def and use
+  /// when the operand indices are already known. UseMI may be NULL for an
+  /// unknown user.
+  unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
+                                 const MachineInstr *UseMI, unsigned UseOperIdx)
+    const;
+
+  /// \brief Compute the instruction latency based on the available machine
+  /// model.
+  ///
+  /// Compute and return the expected latency of this instruction independent of
+  /// a particular use. computeOperandLatency is the preferred API, but this is
+  /// occasionally useful to help estimate instruction cost.
+  ///
+  /// If UseDefaultDefLatency is false and no new machine sched model is
+  /// present this method falls back to TII->getInstrLatency with an empty
+  /// instruction itinerary (this is so we preserve the previous behavior of the
+  /// if converter after moving it to TargetSchedModel).
+  unsigned computeInstrLatency(const MachineInstr *MI,
+                               bool UseDefaultDefLatency = true) const;
+
+  /// \brief Output dependency latency of a pair of defs of the same register.
+  ///
+  /// This is typically one cycle.
+  unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
+                                const MachineInstr *DepMI) const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
new file mode 100644
index 0000000..4e93940
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -0,0 +1,367 @@
+//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- 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 set of low-level target independent types which various
+// values in the code generator are.  This allows the target specific behavior
+// of instructions to be described to target independent passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VALUETYPES_H
+#define LLVM_CODEGEN_VALUETYPES_H
+
+#include "llvm/CodeGen/MachineValueType.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+  class LLVMContext;
+  class Type;
+
+  /// EVT - Extended Value Type.  Capable of holding value types which are not
+  /// native for any processor (such as the i12345 type), as well as the types
+  /// a MVT can represent.
+  struct EVT {
+  private:
+    MVT V;
+    Type *LLVMTy;
+
+  public:
+    EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
+            LLVMTy(nullptr) {}
+    EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) { }
+    EVT(MVT S) : V(S), LLVMTy(nullptr) {}
+
+    bool operator==(EVT VT) const {
+      return !(*this != VT);
+    }
+    bool operator!=(EVT VT) const {
+      if (V.SimpleTy != VT.V.SimpleTy)
+        return true;
+      if (V.SimpleTy < 0)
+        return LLVMTy != VT.LLVMTy;
+      return false;
+    }
+
+    /// getFloatingPointVT - Returns the EVT that represents a floating point
+    /// type with the given number of bits.  There are two floating point types
+    /// with 128 bits - this returns f128 rather than ppcf128.
+    static EVT getFloatingPointVT(unsigned BitWidth) {
+      return MVT::getFloatingPointVT(BitWidth);
+    }
+
+    /// getIntegerVT - Returns the EVT that represents an integer with the given
+    /// number of bits.
+    static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
+      MVT M = MVT::getIntegerVT(BitWidth);
+      if (M.SimpleTy >= 0)
+        return M;
+      return getExtendedIntegerVT(Context, BitWidth);
+    }
+
+    /// getVectorVT - Returns the EVT that represents a vector NumElements in
+    /// length, where each element is of type VT.
+    static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
+      MVT M = MVT::getVectorVT(VT.V, NumElements);
+      if (M.SimpleTy >= 0)
+        return M;
+      return getExtendedVectorVT(Context, VT, NumElements);
+    }
+
+    /// changeVectorElementTypeToInteger - Return a vector with the same number
+    /// of elements as this vector, but with the element type converted to an
+    /// integer type with the same bitwidth.
+    EVT changeVectorElementTypeToInteger() const {
+      if (!isSimple())
+        return changeExtendedVectorElementTypeToInteger();
+      MVT EltTy = getSimpleVT().getVectorElementType();
+      unsigned BitWidth = EltTy.getSizeInBits();
+      MVT IntTy = MVT::getIntegerVT(BitWidth);
+      MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
+      assert(VecTy.SimpleTy >= 0 &&
+             "Simple vector VT not representable by simple integer vector VT!");
+      return VecTy;
+    }
+
+    /// isSimple - Test if the given EVT is simple (as opposed to being
+    /// extended).
+    bool isSimple() const {
+      return V.SimpleTy >= 0;
+    }
+
+    /// isExtended - Test if the given EVT is extended (as opposed to
+    /// being simple).
+    bool isExtended() const {
+      return !isSimple();
+    }
+
+    /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+    bool isFloatingPoint() const {
+      return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
+    }
+
+    /// isInteger - Return true if this is an integer, or a vector integer type.
+    bool isInteger() const {
+      return isSimple() ? V.isInteger() : isExtendedInteger();
+    }
+
+    /// isVector - Return true if this is a vector value type.
+    bool isVector() const {
+      return isSimple() ? V.isVector() : isExtendedVector();
+    }
+
+    /// is16BitVector - Return true if this is a 16-bit vector type.
+    bool is16BitVector() const {
+      return isSimple() ? V.is16BitVector() : isExtended16BitVector();
+    }
+
+    /// is32BitVector - Return true if this is a 32-bit vector type.
+    bool is32BitVector() const {
+      return isSimple() ? V.is32BitVector() : isExtended32BitVector();
+    }
+
+    /// is64BitVector - Return true if this is a 64-bit vector type.
+    bool is64BitVector() const {
+      return isSimple() ? V.is64BitVector() : isExtended64BitVector();
+    }
+
+    /// is128BitVector - Return true if this is a 128-bit vector type.
+    bool is128BitVector() const {
+      return isSimple() ? V.is128BitVector() : isExtended128BitVector();
+    }
+
+    /// is256BitVector - Return true if this is a 256-bit vector type.
+    bool is256BitVector() const {
+      return isSimple() ? V.is256BitVector() : isExtended256BitVector();
+    }
+
+    /// is512BitVector - Return true if this is a 512-bit vector type.
+    bool is512BitVector() const {
+      return isSimple() ? V.is512BitVector() : isExtended512BitVector();
+    }
+
+    /// is1024BitVector - Return true if this is a 1024-bit vector type.
+    bool is1024BitVector() const {
+      return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
+    }
+
+    /// isOverloaded - Return true if this is an overloaded type for TableGen.
+    bool isOverloaded() const {
+      return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
+    }
+
+    /// isByteSized - Return true if the bit size is a multiple of 8.
+    bool isByteSized() const {
+      return (getSizeInBits() & 7) == 0;
+    }
+
+    /// isRound - Return true if the size is a power-of-two number of bytes.
+    bool isRound() const {
+      unsigned BitSize = getSizeInBits();
+      return BitSize >= 8 && !(BitSize & (BitSize - 1));
+    }
+
+    /// bitsEq - Return true if this has the same number of bits as VT.
+    bool bitsEq(EVT VT) const {
+      if (EVT::operator==(VT)) return true;
+      return getSizeInBits() == VT.getSizeInBits();
+    }
+
+    /// bitsGT - Return true if this has more bits than VT.
+    bool bitsGT(EVT VT) const {
+      if (EVT::operator==(VT)) return false;
+      return getSizeInBits() > VT.getSizeInBits();
+    }
+
+    /// bitsGE - Return true if this has no less bits than VT.
+    bool bitsGE(EVT VT) const {
+      if (EVT::operator==(VT)) return true;
+      return getSizeInBits() >= VT.getSizeInBits();
+    }
+
+    /// bitsLT - Return true if this has less bits than VT.
+    bool bitsLT(EVT VT) const {
+      if (EVT::operator==(VT)) return false;
+      return getSizeInBits() < VT.getSizeInBits();
+    }
+
+    /// bitsLE - Return true if this has no more bits than VT.
+    bool bitsLE(EVT VT) const {
+      if (EVT::operator==(VT)) return true;
+      return getSizeInBits() <= VT.getSizeInBits();
+    }
+
+
+    /// getSimpleVT - Return the SimpleValueType held in the specified
+    /// simple EVT.
+    MVT getSimpleVT() const {
+      assert(isSimple() && "Expected a SimpleValueType!");
+      return V;
+    }
+
+    /// getScalarType - If this is a vector type, return the element type,
+    /// otherwise return this.
+    EVT getScalarType() const {
+      return isVector() ? getVectorElementType() : *this;
+    }
+
+    /// getVectorElementType - Given a vector type, return the type of
+    /// each element.
+    EVT getVectorElementType() const {
+      assert(isVector() && "Invalid vector type!");
+      if (isSimple())
+        return V.getVectorElementType();
+      return getExtendedVectorElementType();
+    }
+
+    /// getVectorNumElements - Given a vector type, return the number of
+    /// elements it contains.
+    unsigned getVectorNumElements() const {
+      assert(isVector() && "Invalid vector type!");
+      if (isSimple())
+        return V.getVectorNumElements();
+      return getExtendedVectorNumElements();
+    }
+
+    /// getSizeInBits - Return the size of the specified value type in bits.
+    unsigned getSizeInBits() const {
+      if (isSimple())
+        return V.getSizeInBits();
+      return getExtendedSizeInBits();
+    }
+
+    unsigned getScalarSizeInBits() const {
+      return getScalarType().getSizeInBits();
+    }
+
+    /// getStoreSize - Return the number of bytes overwritten by a store
+    /// of the specified value type.
+    unsigned getStoreSize() const {
+      return (getSizeInBits() + 7) / 8;
+    }
+
+    /// getStoreSizeInBits - Return the number of bits overwritten by a store
+    /// of the specified value type.
+    unsigned getStoreSizeInBits() const {
+      return getStoreSize() * 8;
+    }
+
+    /// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
+    /// to the nearest power of two (and at least to eight), and returns the
+    /// integer EVT with that number of bits.
+    EVT getRoundIntegerType(LLVMContext &Context) const {
+      assert(isInteger() && !isVector() && "Invalid integer type!");
+      unsigned BitWidth = getSizeInBits();
+      if (BitWidth <= 8)
+        return EVT(MVT::i8);
+      return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
+    }
+
+    /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
+    /// greater than or equal to half the width of this EVT. If no simple
+    /// value type can be found, an extended integer value type of half the
+    /// size (rounded up) is returned.
+    EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
+      assert(isInteger() && !isVector() && "Invalid integer type!");
+      unsigned EVTSize = getSizeInBits();
+      for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
+          IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
+        EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
+        if (HalfVT.getSizeInBits() * 2 >= EVTSize)
+          return HalfVT;
+      }
+      return getIntegerVT(Context, (EVTSize + 1) / 2);
+    }
+
+    /// \brief Return a VT for an integer vector type with the size of the
+    /// elements doubled. The typed returned may be an extended type.
+    EVT widenIntegerVectorElementType(LLVMContext &Context) const {
+      EVT EltVT = getVectorElementType();
+      EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
+      return EVT::getVectorVT(Context, EltVT, getVectorNumElements());
+    }
+
+    /// isPow2VectorType - Returns true if the given vector is a power of 2.
+    bool isPow2VectorType() const {
+      unsigned NElts = getVectorNumElements();
+      return !(NElts & (NElts - 1));
+    }
+
+    /// getPow2VectorType - Widens the length of the given vector EVT up to
+    /// the nearest power of 2 and returns that type.
+    EVT getPow2VectorType(LLVMContext &Context) const {
+      if (!isPow2VectorType()) {
+        unsigned NElts = getVectorNumElements();
+        unsigned Pow2NElts = 1 <<  Log2_32_Ceil(NElts);
+        return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts);
+      }
+      else {
+        return *this;
+      }
+    }
+
+    /// getEVTString - This function returns value type as a string,
+    /// e.g. "i32".
+    std::string getEVTString() const;
+
+    /// getTypeForEVT - This method returns an LLVM type corresponding to the
+    /// specified EVT.  For integer types, this returns an unsigned type.  Note
+    /// that this will abort for types that cannot be represented.
+    Type *getTypeForEVT(LLVMContext &Context) const;
+
+    /// getEVT - Return the value type corresponding to the specified type.
+    /// This returns all pointers as iPTR.  If HandleUnknown is true, unknown
+    /// types are returned as Other, otherwise they are invalid.
+    static EVT getEVT(Type *Ty, bool HandleUnknown = false);
+
+    intptr_t getRawBits() const {
+      if (isSimple())
+        return V.SimpleTy;
+      else
+        return (intptr_t)(LLVMTy);
+    }
+
+    /// compareRawBits - A meaningless but well-behaved order, useful for
+    /// constructing containers.
+    struct compareRawBits {
+      bool operator()(EVT L, EVT R) const {
+        if (L.V.SimpleTy == R.V.SimpleTy)
+          return L.LLVMTy < R.LLVMTy;
+        else
+          return L.V.SimpleTy < R.V.SimpleTy;
+      }
+    };
+
+  private:
+    // Methods for handling the Extended-type case in functions above.
+    // These are all out-of-line to prevent users of this header file
+    // from having a dependency on Type.h.
+    EVT changeExtendedVectorElementTypeToInteger() const;
+    static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
+    static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
+                                   unsigned NumElements);
+    bool isExtendedFloatingPoint() const LLVM_READONLY;
+    bool isExtendedInteger() const LLVM_READONLY;
+    bool isExtendedVector() const LLVM_READONLY;
+    bool isExtended16BitVector() const LLVM_READONLY;
+    bool isExtended32BitVector() const LLVM_READONLY;
+    bool isExtended64BitVector() const LLVM_READONLY;
+    bool isExtended128BitVector() const LLVM_READONLY;
+    bool isExtended256BitVector() const LLVM_READONLY;
+    bool isExtended512BitVector() const LLVM_READONLY;
+    bool isExtended1024BitVector() const LLVM_READONLY;
+    EVT getExtendedVectorElementType() const;
+    unsigned getExtendedVectorNumElements() const LLVM_READONLY;
+    unsigned getExtendedSizeInBits() const;
+  };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
new file mode 100644
index 0000000..b5fa0e8
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -0,0 +1,100 @@
+//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Value types - These values correspond to the register types defined in the
+// ValueTypes.h file.  If you update anything here, you must update it there as
+// well!
+//
+//===----------------------------------------------------------------------===//
+
+class ValueType<int size, int value> {
+  string Namespace = "MVT";
+  int Size = size;
+  int Value = value;
+}
+
+def OtherVT: ValueType<0  ,  0>;   // "Other" value
+def i1     : ValueType<1  ,  1>;   // One bit boolean value
+def i8     : ValueType<8  ,  2>;   // 8-bit integer value
+def i16    : ValueType<16 ,  3>;   // 16-bit integer value
+def i32    : ValueType<32 ,  4>;   // 32-bit integer value
+def i64    : ValueType<64 ,  5>;   // 64-bit integer value
+def i128   : ValueType<128,  6>;   // 128-bit integer value
+def f16    : ValueType<16 ,  7>;   // 16-bit floating point value
+def f32    : ValueType<32 ,  8>;   // 32-bit floating point value
+def f64    : ValueType<64 ,  9>;   // 64-bit floating point value
+def f80    : ValueType<80 , 10>;   // 80-bit floating point value
+def f128   : ValueType<128, 11>;   // 128-bit floating point value
+def ppcf128: ValueType<128, 12>;   // PPC 128-bit floating point value
+
+def v2i1   : ValueType<2 ,  13>;   //  2 x i1  vector value
+def v4i1   : ValueType<4 ,  14>;   //  4 x i1  vector value
+def v8i1   : ValueType<8 ,  15>;   //  8 x i1  vector value
+def v16i1  : ValueType<16,  16>;   // 16 x i1  vector value
+def v32i1  : ValueType<32 , 17>;   // 32 x i1  vector value
+def v64i1  : ValueType<64 , 18>;   // 64 x i1  vector value
+def v1i8   : ValueType<16, 19>;    //  1 x i8  vector value
+def v2i8   : ValueType<16 , 20>;   //  2 x i8  vector value
+def v4i8   : ValueType<32 , 21>;   //  4 x i8  vector value
+def v8i8   : ValueType<64 , 22>;   //  8 x i8  vector value
+def v16i8  : ValueType<128, 23>;   // 16 x i8  vector value
+def v32i8  : ValueType<256, 24>;   // 32 x i8 vector value
+def v64i8  : ValueType<512, 25>;   // 64 x i8 vector value
+def v1i16  : ValueType<16 , 26>;   //  1 x i16 vector value
+def v2i16  : ValueType<32 , 27>;   //  2 x i16 vector value
+def v4i16  : ValueType<64 , 28>;   //  4 x i16 vector value
+def v8i16  : ValueType<128, 29>;   //  8 x i16 vector value
+def v16i16 : ValueType<256, 30>;   // 16 x i16 vector value
+def v32i16 : ValueType<512, 31>;   // 32 x i16 vector value
+def v1i32  : ValueType<32 , 32>;   //  1 x i32 vector value
+def v2i32  : ValueType<64 , 33>;   //  2 x i32 vector value
+def v4i32  : ValueType<128, 34>;   //  4 x i32 vector value
+def v8i32  : ValueType<256, 35>;   //  8 x i32 vector value
+def v16i32 : ValueType<512, 36>;   // 16 x i32 vector value
+def v1i64  : ValueType<64 , 37>;   //  1 x i64 vector value
+def v2i64  : ValueType<128, 38>;   //  2 x i64 vector value
+def v4i64  : ValueType<256, 39>;   //  4 x i64 vector value
+def v8i64  : ValueType<512, 40>;   //  8 x i64 vector value
+def v16i64 : ValueType<1024,41>;   // 16 x i64 vector value
+
+def v2f16  : ValueType<32 , 42>;   //  2 x f16 vector value
+def v4f16  : ValueType<64 , 43>;   //  4 x f16 vector value
+def v8f16  : ValueType<128, 44>;   //  8 x f16 vector value
+def v1f32  : ValueType<32 , 45>;   //  1 x f32 vector value
+def v2f32  : ValueType<64 , 46>;   //  2 x f32 vector value
+def v4f32  : ValueType<128, 47>;   //  4 x f32 vector value
+def v8f32  : ValueType<256, 48>;   //  8 x f32 vector value
+def v16f32 : ValueType<512, 49>;   // 16 x f32 vector value
+def v1f64  : ValueType<64, 50>;    //  1 x f64 vector value
+def v2f64  : ValueType<128, 51>;   //  2 x f64 vector value
+def v4f64  : ValueType<256, 52>;   //  4 x f64 vector value
+def v8f64  : ValueType<512, 53>;   //  8 x f64 vector value
+
+
+def x86mmx : ValueType<64 , 54>;   // X86 MMX value
+def FlagVT : ValueType<0  , 55>;   // Pre-RA sched glue
+def isVoid : ValueType<0  , 56>;   // Produces no value
+def untyped: ValueType<8  , 57>;   // Produces an untyped value
+def MetadataVT: ValueType<0, 250>; // Metadata
+
+// Pseudo valuetype mapped to the current pointer size to any address space.
+// Should only be used in TableGen.
+def iPTRAny   : ValueType<0, 251>;
+
+// Pseudo valuetype to represent "vector of any size"
+def vAny   : ValueType<0  , 252>;
+
+// Pseudo valuetype to represent "float of any format"
+def fAny   : ValueType<0  , 253>;
+
+// Pseudo valuetype to represent "integer of any bit width"
+def iAny   : ValueType<0  , 254>;
+
+// Pseudo valuetype mapped to the current pointer size.
+def iPTR   : ValueType<0  , 255>;
diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h
new file mode 100644
index 0000000..eceb875
--- /dev/null
+++ b/include/llvm/CodeGen/VirtRegMap.h
@@ -0,0 +1,190 @@
+//===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a virtual register map. This maps virtual registers to
+// physical registers and virtual registers to stack slots. It is created and
+// updated by a register allocator and then used by a machine code rewriter that
+// adds spill code and rewrites virtual into physical register references.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VIRTREGMAP_H
+#define LLVM_CODEGEN_VIRTREGMAP_H
+
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+  class MachineInstr;
+  class MachineFunction;
+  class MachineRegisterInfo;
+  class TargetInstrInfo;
+  class raw_ostream;
+  class SlotIndexes;
+
+  class VirtRegMap : public MachineFunctionPass {
+  public:
+    enum {
+      NO_PHYS_REG = 0,
+      NO_STACK_SLOT = (1L << 30)-1,
+      MAX_STACK_SLOT = (1L << 18)-1
+    };
+
+  private:
+    MachineRegisterInfo *MRI;
+    const TargetInstrInfo *TII;
+    const TargetRegisterInfo *TRI;
+    MachineFunction *MF;
+
+    /// Virt2PhysMap - This is a virtual to physical register
+    /// mapping. Each virtual register is required to have an entry in
+    /// it; even spilled virtual registers (the register mapped to a
+    /// spilled register is the temporary used to load it from the
+    /// stack).
+    IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
+
+    /// Virt2StackSlotMap - This is virtual register to stack slot
+    /// mapping. Each spilled virtual register has an entry in it
+    /// which corresponds to the stack slot this register is spilled
+    /// at.
+    IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
+
+    /// Virt2SplitMap - This is virtual register to splitted virtual register
+    /// mapping.
+    IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2SplitMap;
+
+    /// createSpillSlot - Allocate a spill slot for RC from MFI.
+    unsigned createSpillSlot(const TargetRegisterClass *RC);
+
+    VirtRegMap(const VirtRegMap&) LLVM_DELETED_FUNCTION;
+    void operator=(const VirtRegMap&) LLVM_DELETED_FUNCTION;
+
+  public:
+    static char ID;
+    VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG),
+                   Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { }
+    bool runOnMachineFunction(MachineFunction &MF) override;
+
+    void getAnalysisUsage(AnalysisUsage &AU) const override {
+      AU.setPreservesAll();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
+    MachineFunction &getMachineFunction() const {
+      assert(MF && "getMachineFunction called before runOnMachineFunction");
+      return *MF;
+    }
+
+    MachineRegisterInfo &getRegInfo() const { return *MRI; }
+    const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
+
+    void grow();
+
+    /// @brief returns true if the specified virtual register is
+    /// mapped to a physical register
+    bool hasPhys(unsigned virtReg) const {
+      return getPhys(virtReg) != NO_PHYS_REG;
+    }
+
+    /// @brief returns the physical register mapped to the specified
+    /// virtual register
+    unsigned getPhys(unsigned virtReg) const {
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+      return Virt2PhysMap[virtReg];
+    }
+
+    /// @brief creates a mapping for the specified virtual register to
+    /// the specified physical register
+    void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg) &&
+             TargetRegisterInfo::isPhysicalRegister(physReg));
+      assert(Virt2PhysMap[virtReg] == NO_PHYS_REG &&
+             "attempt to assign physical register to already mapped "
+             "virtual register");
+      Virt2PhysMap[virtReg] = physReg;
+    }
+
+    /// @brief clears the specified virtual register's, physical
+    /// register mapping
+    void clearVirt(unsigned virtReg) {
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+      assert(Virt2PhysMap[virtReg] != NO_PHYS_REG &&
+             "attempt to clear a not assigned virtual register");
+      Virt2PhysMap[virtReg] = NO_PHYS_REG;
+    }
+
+    /// @brief clears all virtual to physical register mappings
+    void clearAllVirt() {
+      Virt2PhysMap.clear();
+      grow();
+    }
+
+    /// @brief returns true if VirtReg is assigned to its preferred physreg.
+    bool hasPreferredPhys(unsigned VirtReg);
+
+    /// @brief returns true if VirtReg has a known preferred register.
+    /// This returns false if VirtReg has a preference that is a virtual
+    /// register that hasn't been assigned yet.
+    bool hasKnownPreference(unsigned VirtReg);
+
+    /// @brief records virtReg is a split live interval from SReg.
+    void setIsSplitFromReg(unsigned virtReg, unsigned SReg) {
+      Virt2SplitMap[virtReg] = SReg;
+    }
+
+    /// @brief returns the live interval virtReg is split from.
+    unsigned getPreSplitReg(unsigned virtReg) const {
+      return Virt2SplitMap[virtReg];
+    }
+
+    /// getOriginal - Return the original virtual register that VirtReg descends
+    /// from through splitting.
+    /// A register that was not created by splitting is its own original.
+    /// This operation is idempotent.
+    unsigned getOriginal(unsigned VirtReg) const {
+      unsigned Orig = getPreSplitReg(VirtReg);
+      return Orig ? Orig : VirtReg;
+    }
+
+    /// @brief returns true if the specified virtual register is not
+    /// mapped to a stack slot or rematerialized.
+    bool isAssignedReg(unsigned virtReg) const {
+      if (getStackSlot(virtReg) == NO_STACK_SLOT)
+        return true;
+      // Split register can be assigned a physical register as well as a
+      // stack slot or remat id.
+      return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg] != NO_PHYS_REG);
+    }
+
+    /// @brief returns the stack slot mapped to the specified virtual
+    /// register
+    int getStackSlot(unsigned virtReg) const {
+      assert(TargetRegisterInfo::isVirtualRegister(virtReg));
+      return Virt2StackSlotMap[virtReg];
+    }
+
+    /// @brief create a mapping for the specifed virtual register to
+    /// the next available stack slot
+    int assignVirt2StackSlot(unsigned virtReg);
+    /// @brief create a mapping for the specified virtual register to
+    /// the specified stack slot
+    void assignVirt2StackSlot(unsigned virtReg, int frameIndex);
+
+    void print(raw_ostream &OS, const Module* M = nullptr) const override;
+    void dump() const;
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
+    VRM.print(OS);
+    return OS;
+  }
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Config/AsmParsers.def b/include/llvm/Config/AsmParsers.def
new file mode 100644
index 0000000..069d10b
--- /dev/null
+++ b/include/llvm/Config/AsmParsers.def
@@ -0,0 +1,30 @@
+/*===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the assembly-language parsers                  *|
+|* supported by this build of LLVM. Clients of this file should define        *|
+|* the LLVM_ASM_PARSER macro to be a function-like macro with a               *|
+|* single parameter (the name of the target whose assembly can be             *|
+|* generated); including this file will then enumerate all of the             *|
+|* targets with assembly parsers.                                             *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_ASM_PARSER
+#  error Please define the macro LLVM_ASM_PARSER(TargetName)
+#endif
+
+LLVM_ASM_PARSER(X86)
+
+
+#undef LLVM_ASM_PARSER
diff --git a/include/llvm/Config/AsmPrinters.def b/include/llvm/Config/AsmPrinters.def
new file mode 100644
index 0000000..69f61cd
--- /dev/null
+++ b/include/llvm/Config/AsmPrinters.def
@@ -0,0 +1,30 @@
+/*===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the assembly-language printers                 *|
+|* supported by this build of LLVM. Clients of this file should define        *|
+|* the LLVM_ASM_PRINTER macro to be a function-like macro with a              *|
+|* single parameter (the name of the target whose assembly can be             *|
+|* generated); including this file will then enumerate all of the             *|
+|* targets with assembly printers.                                            *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_ASM_PRINTER
+#  error Please define the macro LLVM_ASM_PRINTER(TargetName)
+#endif
+
+LLVM_ASM_PRINTER(X86)
+
+
+#undef LLVM_ASM_PRINTER
diff --git a/include/llvm/Config/Disassemblers.def b/include/llvm/Config/Disassemblers.def
new file mode 100644
index 0000000..ce900ca
--- /dev/null
+++ b/include/llvm/Config/Disassemblers.def
@@ -0,0 +1,30 @@
+/*===- llvm/Config/Disassemblers.def - LLVM Assembly Parsers ----*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the assembly-language parsers                  *|
+|* supported by this build of LLVM. Clients of this file should define        *|
+|* the LLVM_DISASSEMBLER macro to be a function-like macro with a             *|
+|* single parameter (the name of the target whose assembly can be             *|
+|* generated); including this file will then enumerate all of the             *|
+|* targets with assembly parsers.                                             *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_DISASSEMBLER
+#  error Please define the macro LLVM_DISASSEMBLER(TargetName)
+#endif
+
+LLVM_DISASSEMBLER(X86)
+
+
+#undef LLVM_DISASSEMBLER
diff --git a/include/llvm/Config/Targets.def b/include/llvm/Config/Targets.def
new file mode 100644
index 0000000..6d02a94
--- /dev/null
+++ b/include/llvm/Config/Targets.def
@@ -0,0 +1,29 @@
+/*===- llvm/Config/Targets.def - LLVM Target Architectures ------*- C++ -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file enumerates all of the target architectures supported by          *|
+|* this build of LLVM. Clients of this file should define the                 *|
+|* LLVM_TARGET macro to be a function-like macro with a single                *|
+|* parameter (the name of the target); including this file will then          *|
+|* enumerate all of the targets.                                              *|
+|*                                                                            *|
+|* The set of targets supported by LLVM is generated at configuration         *|
+|* time, at which point this header is generated. Do not modify this          *|
+|* header directly.                                                           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_TARGET
+#  error Please define the macro LLVM_TARGET(TargetName)
+#endif
+
+LLVM_TARGET(X86)
+
+
+#undef LLVM_TARGET
diff --git a/include/llvm/Config/llvm-config.h b/include/llvm/Config/llvm-config.h
new file mode 100644
index 0000000..5c59eae
--- /dev/null
+++ b/include/llvm/Config/llvm-config.h
@@ -0,0 +1,98 @@
+/*===------- llvm/Config/llvm-config.h - llvm configuration -------*- C -*-===*/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is distributed under the University of Illinois Open Source      */
+/* License. See LICENSE.TXT for details.                                      */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+
+/* This file enumerates variables from the LLVM configuration so that they
+   can be in exported headers and won't override package specific directives.
+   This is a C header that can be included in the llvm-c headers. */
+
+#ifndef LLVM_CONFIG_H
+#define LLVM_CONFIG_H
+
+/* Installation directory for binary executables */
+/* #undef LLVM_BINDIR */
+
+/* Time at which LLVM was configured */
+/* #undef LLVM_CONFIGTIME */
+
+/* Installation directory for data files */
+/* #undef LLVM_DATADIR */
+
+/* Target triple LLVM will generate code for by default */
+#define LLVM_DEFAULT_TARGET_TRIPLE "x86_64-apple-darwin13.4.0"
+
+/* Installation directory for documentation */
+/* #undef LLVM_DOCSDIR */
+
+/* Define if threads enabled */
+#define LLVM_ENABLE_THREADS 1
+
+/* Installation directory for config files */
+/* #undef LLVM_ETCDIR */
+
+/* Has gcc/MSVC atomic intrinsics */
+#define LLVM_HAS_ATOMICS 1
+
+/* Host triple LLVM will be executed on */
+#define LLVM_HOST_TRIPLE "x86_64-apple-darwin13.4.0"
+
+/* Installation directory for include files */
+/* #undef LLVM_INCLUDEDIR */
+
+/* Installation directory for .info files */
+/* #undef LLVM_INFODIR */
+
+/* Installation directory for man pages */
+/* #undef LLVM_MANDIR */
+
+/* LLVM architecture name for the native architecture, if available */
+#define LLVM_NATIVE_ARCH X86
+
+/* LLVM name for the native AsmParser init function, if available */
+#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser
+
+/* LLVM name for the native AsmPrinter init function, if available */
+#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
+
+/* LLVM name for the native Disassembler init function, if available */
+#define LLVM_NATIVE_DISASSEMBLER LLVMInitializeX86Disassembler
+
+/* LLVM name for the native Target init function, if available */
+#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
+
+/* LLVM name for the native TargetInfo init function, if available */
+#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
+
+/* LLVM name for the native target MC init function, if available */
+#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
+
+/* Define if this is Unixish platform */
+#define LLVM_ON_UNIX 1
+
+/* Define if this is Win32ish platform */
+/* #undef LLVM_ON_WIN32 */
+
+/* Installation prefix directory */
+#define LLVM_PREFIX "/tmp/darwin-x86_64-clang-3.5"
+
+/* Define if we have the Intel JIT API runtime support library */
+/* #undef LLVM_USE_INTEL_JITEVENTS */
+
+/* Define if we have the oprofile JIT-support library */
+/* #undef LLVM_USE_OPROFILE */
+
+/* Major version of the LLVM API */
+#define LLVM_VERSION_MAJOR 3
+
+/* Minor version of the LLVM API */
+#define LLVM_VERSION_MINOR 5
+
+/* Define if we link Polly to the tools */
+/* #undef LINK_POLLY_INTO_TOOLS */
+
+#endif
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
new file mode 100644
index 0000000..c1aba01
--- /dev/null
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -0,0 +1,143 @@
+//===-- DIContext.h ---------------------------------------------*- 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 DIContext, an abstract data structure that holds
+// debug information data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DICONTEXT_H
+#define LLVM_DEBUGINFO_DICONTEXT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/RelocVisitor.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+
+#include <string>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// DILineInfo - a format-neutral container for source line information.
+struct DILineInfo {
+  std::string FileName;
+  std::string FunctionName;
+  uint32_t Line;
+  uint32_t Column;
+
+  DILineInfo()
+      : FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0) {}
+
+  bool operator==(const DILineInfo &RHS) const {
+    return Line == RHS.Line && Column == RHS.Column &&
+           FileName == RHS.FileName && FunctionName == RHS.FunctionName;
+  }
+  bool operator!=(const DILineInfo &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
+
+/// DIInliningInfo - a format-neutral container for inlined code description.
+class DIInliningInfo {
+  SmallVector<DILineInfo, 4> Frames;
+ public:
+  DIInliningInfo() {}
+  DILineInfo getFrame(unsigned Index) const {
+    assert(Index < Frames.size());
+    return Frames[Index];
+  }
+  uint32_t getNumberOfFrames() const {
+    return Frames.size();
+  }
+  void addFrame(const DILineInfo &Frame) {
+    Frames.push_back(Frame);
+  }
+};
+
+/// DILineInfoSpecifier - controls which fields of DILineInfo container
+/// should be filled with data.
+struct DILineInfoSpecifier {
+  enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
+  enum class FunctionNameKind { None, ShortName, LinkageName };
+
+  FileLineInfoKind FLIKind;
+  FunctionNameKind FNKind;
+
+  DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
+                      FunctionNameKind FNKind = FunctionNameKind::None)
+      : FLIKind(FLIKind), FNKind(FNKind) {}
+};
+
+/// Selects which debug sections get dumped.
+enum DIDumpType {
+  DIDT_Null,
+  DIDT_All,
+  DIDT_Abbrev,
+  DIDT_AbbrevDwo,
+  DIDT_Aranges,
+  DIDT_Frames,
+  DIDT_Info,
+  DIDT_InfoDwo,
+  DIDT_Types,
+  DIDT_TypesDwo,
+  DIDT_Line,
+  DIDT_LineDwo,
+  DIDT_Loc,
+  DIDT_LocDwo,
+  DIDT_Ranges,
+  DIDT_Pubnames,
+  DIDT_Pubtypes,
+  DIDT_GnuPubnames,
+  DIDT_GnuPubtypes,
+  DIDT_Str,
+  DIDT_StrDwo,
+  DIDT_StrOffsetsDwo
+};
+
+// In place of applying the relocations to the data we've read from disk we use
+// a separate mapping table to the side and checking that at locations in the
+// dwarf where we expect relocated values. This adds a bit of complexity to the
+// dwarf parsing/extraction at the benefit of not allocating memory for the
+// entire size of the debug info sections.
+typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
+
+class DIContext {
+public:
+  enum DIContextKind {
+    CK_DWARF
+  };
+  DIContextKind getKind() const { return Kind; }
+
+  DIContext(DIContextKind K) : Kind(K) {}
+  virtual ~DIContext();
+
+  /// getDWARFContext - get a context for binary DWARF data.
+  static DIContext *getDWARFContext(object::ObjectFile *);
+
+  virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
+
+  virtual DILineInfo getLineInfoForAddress(uint64_t Address,
+      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+  virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
+      uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+  virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
+      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+private:
+  const DIContextKind Kind;
+};
+
+}
+
+#endif
diff --git a/include/llvm/DebugInfo/DWARFFormValue.h b/include/llvm/DebugInfo/DWARFFormValue.h
new file mode 100644
index 0000000..d517a72
--- /dev/null
+++ b/include/llvm/DebugInfo/DWARFFormValue.h
@@ -0,0 +1,85 @@
+//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
+#define LLVM_DEBUGINFO_DWARFFORMVALUE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/DataExtractor.h"
+
+namespace llvm {
+
+class DWARFUnit;
+class raw_ostream;
+
+class DWARFFormValue {
+public:
+  enum FormClass {
+    FC_Unknown,
+    FC_Address,
+    FC_Block,
+    FC_Constant,
+    FC_String,
+    FC_Flag,
+    FC_Reference,
+    FC_Indirect,
+    FC_SectionOffset,
+    FC_Exprloc
+  };
+
+private:
+  struct ValueType {
+    ValueType() : data(nullptr) {
+      uval = 0;
+    }
+
+    union {
+      uint64_t uval;
+      int64_t sval;
+      const char* cstr;
+    };
+    const uint8_t* data;
+  };
+
+  uint16_t Form;   // Form for this value.
+  ValueType Value; // Contains all data for the form.
+
+public:
+  DWARFFormValue(uint16_t Form = 0) : Form(Form) {}
+  uint16_t getForm() const { return Form; }
+  bool isFormClass(FormClass FC) const;
+
+  void dump(raw_ostream &OS, const DWARFUnit *U) const;
+  bool extractValue(DataExtractor data, uint32_t *offset_ptr,
+                    const DWARFUnit *u);
+  bool isInlinedCStr() const {
+    return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr;
+  }
+
+  /// getAsFoo functions below return the extracted value as Foo if only
+  /// DWARFFormValue has form class is suitable for representing Foo.
+  Optional<uint64_t> getAsReference(const DWARFUnit *U) const;
+  Optional<uint64_t> getAsUnsignedConstant() const;
+  Optional<const char *> getAsCString(const DWARFUnit *U) const;
+  Optional<uint64_t> getAsAddress(const DWARFUnit *U) const;
+  Optional<uint64_t> getAsSectionOffset() const;
+
+  bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
+                 const DWARFUnit *u) const;
+  static bool skipValue(uint16_t form, DataExtractor debug_info_data,
+                        uint32_t *offset_ptr, const DWARFUnit *u);
+
+  static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize,
+                                             uint16_t Version);
+};
+
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
new file mode 100644
index 0000000..e5dab61
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -0,0 +1,734 @@
+//===- ExecutionEngine.h - Abstract Execution Engine Interface --*- 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 abstract interface that implements execution support
+// for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
+#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
+
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueMap.h"
+#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <map>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+struct GenericValue;
+class Constant;
+class DataLayout;
+class ExecutionEngine;
+class Function;
+class GlobalVariable;
+class GlobalValue;
+class JITEventListener;
+class JITMemoryManager;
+class MachineCodeInfo;
+class Module;
+class MutexGuard;
+class ObjectCache;
+class RTDyldMemoryManager;
+class Triple;
+class Type;
+
+namespace object {
+  class Archive;
+  class ObjectFile;
+}
+
+/// \brief Helper class for helping synchronize access to the global address map
+/// table.  Access to this class should be serialized under a mutex.
+class ExecutionEngineState {
+public:
+  struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> {
+    typedef ExecutionEngineState *ExtraData;
+    static sys::Mutex *getMutex(ExecutionEngineState *EES);
+    static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old);
+    static void onRAUW(ExecutionEngineState *, const GlobalValue *,
+                       const GlobalValue *);
+  };
+
+  typedef ValueMap<const GlobalValue *, void *, AddressMapConfig>
+      GlobalAddressMapTy;
+
+private:
+  ExecutionEngine &EE;
+
+  /// GlobalAddressMap - A mapping between LLVM global values and their
+  /// actualized version...
+  GlobalAddressMapTy GlobalAddressMap;
+
+  /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
+  /// used to convert raw addresses into the LLVM global value that is emitted
+  /// at the address.  This map is not computed unless getGlobalValueAtAddress
+  /// is called at some point.
+  std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap;
+
+public:
+  ExecutionEngineState(ExecutionEngine &EE);
+
+  GlobalAddressMapTy &getGlobalAddressMap() {
+    return GlobalAddressMap;
+  }
+
+  std::map<void*, AssertingVH<const GlobalValue> > &
+  getGlobalAddressReverseMap() {
+    return GlobalAddressReverseMap;
+  }
+
+  /// \brief Erase an entry from the mapping table.
+  ///
+  /// \returns The address that \p ToUnmap was happed to.
+  void *RemoveMapping(const GlobalValue *ToUnmap);
+};
+
+/// \brief Abstract interface for implementation execution of LLVM modules,
+/// designed to support both interpreter and just-in-time (JIT) compiler
+/// implementations.
+class ExecutionEngine {
+  /// The state object holding the global address mapping, which must be
+  /// accessed synchronously.
+  //
+  // FIXME: There is no particular need the entire map needs to be
+  // synchronized.  Wouldn't a reader-writer design be better here?
+  ExecutionEngineState EEState;
+
+  /// The target data for the platform for which execution is being performed.
+  const DataLayout *DL;
+
+  /// Whether lazy JIT compilation is enabled.
+  bool CompilingLazily;
+
+  /// Whether JIT compilation of external global variables is allowed.
+  bool GVCompilationDisabled;
+
+  /// Whether the JIT should perform lookups of external symbols (e.g.,
+  /// using dlsym).
+  bool SymbolSearchingDisabled;
+
+  /// Whether the JIT should verify IR modules during compilation.
+  bool VerifyModules;
+
+  friend class EngineBuilder;  // To allow access to JITCtor and InterpCtor.
+
+protected:
+  /// The list of Modules that we are JIT'ing from.  We use a SmallVector to
+  /// optimize for the case where there is only one module.
+  SmallVector<Module*, 1> Modules;
+
+  void setDataLayout(const DataLayout *Val) { DL = Val; }
+
+  /// getMemoryforGV - Allocate memory for a global variable.
+  virtual char *getMemoryForGV(const GlobalVariable *GV);
+
+  // To avoid having libexecutionengine depend on the JIT and interpreter
+  // libraries, the execution engine implementations set these functions to ctor
+  // pointers at startup time if they are linked in.
+  static ExecutionEngine *(*JITCtor)(
+    Module *M,
+    std::string *ErrorStr,
+    JITMemoryManager *JMM,
+    bool GVsWithCode,
+    TargetMachine *TM);
+  static ExecutionEngine *(*MCJITCtor)(
+    Module *M,
+    std::string *ErrorStr,
+    RTDyldMemoryManager *MCJMM,
+    bool GVsWithCode,
+    TargetMachine *TM);
+  static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
+
+  /// LazyFunctionCreator - If an unknown function is needed, this function
+  /// pointer is invoked to create it.  If this returns null, the JIT will
+  /// abort.
+  void *(*LazyFunctionCreator)(const std::string &);
+
+public:
+  /// lock - This lock protects the ExecutionEngine, MCJIT, JIT, JITResolver and
+  /// JITEmitter classes.  It must be held while changing the internal state of
+  /// any of those classes.
+  sys::Mutex lock;
+
+  //===--------------------------------------------------------------------===//
+  //  ExecutionEngine Startup
+  //===--------------------------------------------------------------------===//
+
+  virtual ~ExecutionEngine();
+
+  /// create - This is the factory method for creating an execution engine which
+  /// is appropriate for the current machine.  This takes ownership of the
+  /// module.
+  ///
+  /// \param GVsWithCode - Allocating globals with code breaks
+  /// freeMachineCodeForFunction and is probably unsafe and bad for performance.
+  /// However, we have clients who depend on this behavior, so we must support
+  /// it.  Eventually, when we're willing to break some backwards compatibility,
+  /// this flag should be flipped to false, so that by default
+  /// freeMachineCodeForFunction works.
+  static ExecutionEngine *create(Module *M,
+                                 bool ForceInterpreter = false,
+                                 std::string *ErrorStr = nullptr,
+                                 CodeGenOpt::Level OptLevel =
+                                 CodeGenOpt::Default,
+                                 bool GVsWithCode = true);
+
+  /// createJIT - This is the factory method for creating a JIT for the current
+  /// machine, it does not fall back to the interpreter.  This takes ownership
+  /// of the Module and JITMemoryManager if successful.
+  ///
+  /// Clients should make sure to initialize targets prior to calling this
+  /// function.
+  static ExecutionEngine *createJIT(Module *M,
+                                    std::string *ErrorStr = nullptr,
+                                    JITMemoryManager *JMM = nullptr,
+                                    CodeGenOpt::Level OptLevel =
+                                    CodeGenOpt::Default,
+                                    bool GVsWithCode = true,
+                                    Reloc::Model RM = Reloc::Default,
+                                    CodeModel::Model CMM =
+                                    CodeModel::JITDefault);
+
+  /// addModule - Add a Module to the list of modules that we can JIT from.
+  /// Note that this takes ownership of the Module: when the ExecutionEngine is
+  /// destroyed, it destroys the Module as well.
+  virtual void addModule(Module *M) {
+    Modules.push_back(M);
+  }
+
+  /// addObjectFile - Add an ObjectFile to the execution engine.
+  ///
+  /// This method is only supported by MCJIT.  MCJIT will immediately load the
+  /// object into memory and adds its symbols to the list used to resolve
+  /// external symbols while preparing other objects for execution.
+  ///
+  /// Objects added using this function will not be made executable until
+  /// needed by another object.
+  ///
+  /// MCJIT will take ownership of the ObjectFile.
+  virtual void addObjectFile(std::unique_ptr<object::ObjectFile> O);
+
+  /// addArchive - Add an Archive to the execution engine.
+  ///
+  /// This method is only supported by MCJIT.  MCJIT will use the archive to
+  /// resolve external symbols in objects it is loading.  If a symbol is found
+  /// in the Archive the contained object file will be extracted (in memory)
+  /// and loaded for possible execution.
+  ///
+  /// MCJIT will take ownership of the Archive.
+  virtual void addArchive(object::Archive *A) {
+    llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive.");
+  }
+
+  //===--------------------------------------------------------------------===//
+
+  const DataLayout *getDataLayout() const { return DL; }
+
+  /// removeModule - Remove a Module from the list of modules.  Returns true if
+  /// M is found.
+  virtual bool removeModule(Module *M);
+
+  /// FindFunctionNamed - Search all of the active modules to find the one that
+  /// defines FnName.  This is very slow operation and shouldn't be used for
+  /// general code.
+  virtual Function *FindFunctionNamed(const char *FnName);
+
+  /// runFunction - Execute the specified function with the specified arguments,
+  /// and return the result.
+  virtual GenericValue runFunction(Function *F,
+                                const std::vector<GenericValue> &ArgValues) = 0;
+
+  /// getPointerToNamedFunction - This method returns the address of the
+  /// specified function by using the dlsym function call.  As such it is only
+  /// useful for resolving library symbols, not code generated symbols.
+  ///
+  /// If AbortOnFailure is false and no function with the given name is
+  /// found, this function silently returns a null pointer. Otherwise,
+  /// it prints a message to stderr and aborts.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.
+  ///
+  /// FIXME: the JIT and MCJIT interfaces should be disentangled or united
+  /// again, if possible.
+  ///
+  virtual void *getPointerToNamedFunction(const std::string &Name,
+                                          bool AbortOnFailure = true) = 0;
+
+  /// mapSectionAddress - map a section to its target address space value.
+  /// Map the address of a JIT section as returned from the memory manager
+  /// to the address in the target process as the running code will see it.
+  /// This is the address which will be used for relocation resolution.
+  virtual void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress) {
+    llvm_unreachable("Re-mapping of section addresses not supported with this "
+                     "EE!");
+  }
+
+  /// generateCodeForModule - Run code generationen for the specified module and
+  /// load it into memory.
+  ///
+  /// When this function has completed, all code and data for the specified
+  /// module, and any module on which this module depends, will be generated
+  /// and loaded into memory, but relocations will not yet have been applied
+  /// and all memory will be readable and writable but not executable.
+  ///
+  /// This function is primarily useful when generating code for an external
+  /// target, allowing the client an opportunity to remap section addresses
+  /// before relocations are applied.  Clients that intend to execute code
+  /// locally can use the getFunctionAddress call, which will generate code
+  /// and apply final preparations all in one step.
+  ///
+  /// This method has no effect for the legacy JIT engine or the interpeter.
+  virtual void generateCodeForModule(Module *M) {}
+
+  /// finalizeObject - ensure the module is fully processed and is usable.
+  ///
+  /// It is the user-level function for completing the process of making the
+  /// object usable for execution.  It should be called after sections within an
+  /// object have been relocated using mapSectionAddress.  When this method is
+  /// called the MCJIT execution engine will reapply relocations for a loaded
+  /// object.  This method has no effect for the legacy JIT engine or the
+  /// interpeter.
+  virtual void finalizeObject() {}
+
+  /// runStaticConstructorsDestructors - This method is used to execute all of
+  /// the static constructors or destructors for a program.
+  ///
+  /// \param isDtors - Run the destructors instead of constructors.
+  virtual void runStaticConstructorsDestructors(bool isDtors);
+
+  /// runStaticConstructorsDestructors - This method is used to execute all of
+  /// the static constructors or destructors for a particular module.
+  ///
+  /// \param isDtors - Run the destructors instead of constructors.
+  void runStaticConstructorsDestructors(Module *module, bool isDtors);
+
+
+  /// runFunctionAsMain - This is a helper function which wraps runFunction to
+  /// handle the common task of starting up main with the specified argc, argv,
+  /// and envp parameters.
+  int runFunctionAsMain(Function *Fn, const std::vector<std::string> &argv,
+                        const char * const * envp);
+
+
+  /// addGlobalMapping - Tell the execution engine that the specified global is
+  /// at the specified location.  This is used internally as functions are JIT'd
+  /// and as global variables are laid out in memory.  It can and should also be
+  /// used by clients of the EE that want to have an LLVM global overlay
+  /// existing data in memory.  Mappings are automatically removed when their
+  /// GlobalValue is destroyed.
+  void addGlobalMapping(const GlobalValue *GV, void *Addr);
+
+  /// clearAllGlobalMappings - Clear all global mappings and start over again,
+  /// for use in dynamic compilation scenarios to move globals.
+  void clearAllGlobalMappings();
+
+  /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
+  /// particular module, because it has been removed from the JIT.
+  void clearGlobalMappingsFromModule(Module *M);
+
+  /// updateGlobalMapping - Replace an existing mapping for GV with a new
+  /// address.  This updates both maps as required.  If "Addr" is null, the
+  /// entry for the global is removed from the mappings.  This returns the old
+  /// value of the pointer, or null if it was not in the map.
+  void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
+
+  /// getPointerToGlobalIfAvailable - This returns the address of the specified
+  /// global value if it is has already been codegen'd, otherwise it returns
+  /// null.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.  It doesn't
+  /// seem to be needed in that case, but an equivalent can be added if it is.
+  void *getPointerToGlobalIfAvailable(const GlobalValue *GV);
+
+  /// getPointerToGlobal - This returns the address of the specified global
+  /// value. This may involve code generation if it's a function.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.  Use
+  /// getGlobalValueAddress instead.
+  void *getPointerToGlobal(const GlobalValue *GV);
+
+  /// getPointerToFunction - The different EE's represent function bodies in
+  /// different ways.  They should each implement this to say what a function
+  /// pointer should look like.  When F is destroyed, the ExecutionEngine will
+  /// remove its global mapping and free any machine code.  Be sure no threads
+  /// are running inside F when that happens.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.  Use
+  /// getFunctionAddress instead.
+  virtual void *getPointerToFunction(Function *F) = 0;
+
+  /// getPointerToBasicBlock - The different EE's represent basic blocks in
+  /// different ways.  Return the representation for a blockaddress of the
+  /// specified block.
+  ///
+  /// This function will not be implemented for the MCJIT execution engine.
+  virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
+
+  /// getPointerToFunctionOrStub - If the specified function has been
+  /// code-gen'd, return a pointer to the function.  If not, compile it, or use
+  /// a stub to implement lazy compilation if available.  See
+  /// getPointerToFunction for the requirements on destroying F.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.  Use
+  /// getFunctionAddress instead.
+  virtual void *getPointerToFunctionOrStub(Function *F) {
+    // Default implementation, just codegen the function.
+    return getPointerToFunction(F);
+  }
+
+  /// getGlobalValueAddress - Return the address of the specified global
+  /// value. This may involve code generation.
+  ///
+  /// This function should not be called with the JIT or interpreter engines.
+  virtual uint64_t getGlobalValueAddress(const std::string &Name) {
+    // Default implementation for JIT and interpreter.  MCJIT will override this.
+    // JIT and interpreter clients should use getPointerToGlobal instead.
+    return 0;
+  }
+
+  /// getFunctionAddress - Return the address of the specified function.
+  /// This may involve code generation.
+  virtual uint64_t getFunctionAddress(const std::string &Name) {
+    // Default implementation for JIT and interpreter.  MCJIT will override this.
+    // JIT and interpreter clients should use getPointerToFunction instead.
+    return 0;
+  }
+
+  // The JIT overrides a version that actually does this.
+  virtual void runJITOnFunction(Function *, MachineCodeInfo * = nullptr) { }
+
+  /// getGlobalValueAtAddress - Return the LLVM global value object that starts
+  /// at the specified address.
+  ///
+  const GlobalValue *getGlobalValueAtAddress(void *Addr);
+
+  /// StoreValueToMemory - Stores the data in Val of type Ty at address Ptr.
+  /// Ptr is the address of the memory at which to store Val, cast to
+  /// GenericValue *.  It is not a pointer to a GenericValue containing the
+  /// address at which to store Val.
+  void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr,
+                          Type *Ty);
+
+  void InitializeMemory(const Constant *Init, void *Addr);
+
+  /// recompileAndRelinkFunction - This method is used to force a function which
+  /// has already been compiled to be compiled again, possibly after it has been
+  /// modified.  Then the entry to the old copy is overwritten with a branch to
+  /// the new copy.  If there was no old copy, this acts just like
+  /// VM::getPointerToFunction().
+  virtual void *recompileAndRelinkFunction(Function *F) = 0;
+
+  /// freeMachineCodeForFunction - Release memory in the ExecutionEngine
+  /// corresponding to the machine code emitted to execute this function, useful
+  /// for garbage-collecting generated code.
+  virtual void freeMachineCodeForFunction(Function *F) = 0;
+
+  /// getOrEmitGlobalVariable - Return the address of the specified global
+  /// variable, possibly emitting it to memory if needed.  This is used by the
+  /// Emitter.
+  ///
+  /// This function is deprecated for the MCJIT execution engine.  Use
+  /// getGlobalValueAddress instead.
+  virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
+    return getPointerToGlobal((const GlobalValue *)GV);
+  }
+
+  /// Registers a listener to be called back on various events within
+  /// the JIT.  See JITEventListener.h for more details.  Does not
+  /// take ownership of the argument.  The argument may be NULL, in
+  /// which case these functions do nothing.
+  virtual void RegisterJITEventListener(JITEventListener *) {}
+  virtual void UnregisterJITEventListener(JITEventListener *) {}
+
+  /// Sets the pre-compiled object cache.  The ownership of the ObjectCache is
+  /// not changed.  Supported by MCJIT but not JIT.
+  virtual void setObjectCache(ObjectCache *) {
+    llvm_unreachable("No support for an object cache");
+  }
+
+  /// setProcessAllSections (MCJIT Only): By default, only sections that are
+  /// "required for execution" are passed to the RTDyldMemoryManager, and other
+  /// sections are discarded. Passing 'true' to this method will cause
+  /// RuntimeDyld to pass all sections to its RTDyldMemoryManager regardless
+  /// of whether they are "required to execute" in the usual sense.
+  ///
+  /// Rationale: Some MCJIT clients want to be able to inspect metadata
+  /// sections (e.g. Dwarf, Stack-maps) to enable functionality or analyze
+  /// performance. Passing these sections to the memory manager allows the
+  /// client to make policy about the relevant sections, rather than having
+  /// MCJIT do it.
+  virtual void setProcessAllSections(bool ProcessAllSections) {
+    llvm_unreachable("No support for ProcessAllSections option");
+  }
+
+  /// Return the target machine (if available).
+  virtual TargetMachine *getTargetMachine() { return nullptr; }
+
+  /// DisableLazyCompilation - When lazy compilation is off (the default), the
+  /// JIT will eagerly compile every function reachable from the argument to
+  /// getPointerToFunction.  If lazy compilation is turned on, the JIT will only
+  /// compile the one function and emit stubs to compile the rest when they're
+  /// first called.  If lazy compilation is turned off again while some lazy
+  /// stubs are still around, and one of those stubs is called, the program will
+  /// abort.
+  ///
+  /// In order to safely compile lazily in a threaded program, the user must
+  /// ensure that 1) only one thread at a time can call any particular lazy
+  /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock
+  /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a
+  /// lazy stub.  See http://llvm.org/PR5184 for details.
+  void DisableLazyCompilation(bool Disabled = true) {
+    CompilingLazily = !Disabled;
+  }
+  bool isCompilingLazily() const {
+    return CompilingLazily;
+  }
+  // Deprecated in favor of isCompilingLazily (to reduce double-negatives).
+  // Remove this in LLVM 2.8.
+  bool isLazyCompilationDisabled() const {
+    return !CompilingLazily;
+  }
+
+  /// DisableGVCompilation - If called, the JIT will abort if it's asked to
+  /// allocate space and populate a GlobalVariable that is not internal to
+  /// the module.
+  void DisableGVCompilation(bool Disabled = true) {
+    GVCompilationDisabled = Disabled;
+  }
+  bool isGVCompilationDisabled() const {
+    return GVCompilationDisabled;
+  }
+
+  /// DisableSymbolSearching - If called, the JIT will not try to lookup unknown
+  /// symbols with dlsym.  A client can still use InstallLazyFunctionCreator to
+  /// resolve symbols in a custom way.
+  void DisableSymbolSearching(bool Disabled = true) {
+    SymbolSearchingDisabled = Disabled;
+  }
+  bool isSymbolSearchingDisabled() const {
+    return SymbolSearchingDisabled;
+  }
+
+  /// Enable/Disable IR module verification.
+  ///
+  /// Note: Module verification is enabled by default in Debug builds, and
+  /// disabled by default in Release. Use this method to override the default.
+  void setVerifyModules(bool Verify) {
+    VerifyModules = Verify;
+  }
+  bool getVerifyModules() const {
+    return VerifyModules;
+  }
+
+  /// InstallLazyFunctionCreator - If an unknown function is needed, the
+  /// specified function pointer is invoked to create it.  If it returns null,
+  /// the JIT will abort.
+  void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
+    LazyFunctionCreator = P;
+  }
+
+protected:
+  explicit ExecutionEngine(Module *M);
+
+  void emitGlobals();
+
+  void EmitGlobalVariable(const GlobalVariable *GV);
+
+  GenericValue getConstantValue(const Constant *C);
+  void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
+                           Type *Ty);
+};
+
+namespace EngineKind {
+  // These are actually bitmasks that get or-ed together.
+  enum Kind {
+    JIT         = 0x1,
+    Interpreter = 0x2
+  };
+  const static Kind Either = (Kind)(JIT | Interpreter);
+}
+
+/// EngineBuilder - Builder class for ExecutionEngines.  Use this by
+/// stack-allocating a builder, chaining the various set* methods, and
+/// terminating it with a .create() call.
+class EngineBuilder {
+private:
+  Module *M;
+  EngineKind::Kind WhichEngine;
+  std::string *ErrorStr;
+  CodeGenOpt::Level OptLevel;
+  RTDyldMemoryManager *MCJMM;
+  JITMemoryManager *JMM;
+  bool AllocateGVsWithCode;
+  TargetOptions Options;
+  Reloc::Model RelocModel;
+  CodeModel::Model CMModel;
+  std::string MArch;
+  std::string MCPU;
+  SmallVector<std::string, 4> MAttrs;
+  bool UseMCJIT;
+  bool VerifyModules;
+
+  /// InitEngine - Does the common initialization of default options.
+  void InitEngine();
+
+public:
+  /// EngineBuilder - Constructor for EngineBuilder.  If create() is called and
+  /// is successful, the created engine takes ownership of the module.
+  EngineBuilder(Module *m) : M(m) {
+    InitEngine();
+  }
+
+  /// setEngineKind - Controls whether the user wants the interpreter, the JIT,
+  /// or whichever engine works.  This option defaults to EngineKind::Either.
+  EngineBuilder &setEngineKind(EngineKind::Kind w) {
+    WhichEngine = w;
+    return *this;
+  }
+
+  /// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows
+  /// clients to customize their memory allocation policies for the MCJIT. This
+  /// is only appropriate for the MCJIT; setting this and configuring the builder
+  /// to create anything other than MCJIT will cause a runtime error. If create()
+  /// is called and is successful, the created engine takes ownership of the
+  /// memory manager. This option defaults to NULL. Using this option nullifies
+  /// the setJITMemoryManager() option.
+  EngineBuilder &setMCJITMemoryManager(RTDyldMemoryManager *mcjmm) {
+    MCJMM = mcjmm;
+    JMM = nullptr;
+    return *this;
+  }
+
+  /// setJITMemoryManager - Sets the JIT memory manager to use.  This allows
+  /// clients to customize their memory allocation policies.  This is only
+  /// appropriate for either JIT or MCJIT; setting this and configuring the
+  /// builder to create an interpreter will cause a runtime error. If create()
+  /// is called and is successful, the created engine takes ownership of the
+  /// memory manager.  This option defaults to NULL. This option overrides
+  /// setMCJITMemoryManager() as well.
+  EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
+    MCJMM = nullptr;
+    JMM = jmm;
+    return *this;
+  }
+
+  /// setErrorStr - Set the error string to write to on error.  This option
+  /// defaults to NULL.
+  EngineBuilder &setErrorStr(std::string *e) {
+    ErrorStr = e;
+    return *this;
+  }
+
+  /// setOptLevel - Set the optimization level for the JIT.  This option
+  /// defaults to CodeGenOpt::Default.
+  EngineBuilder &setOptLevel(CodeGenOpt::Level l) {
+    OptLevel = l;
+    return *this;
+  }
+
+  /// setTargetOptions - Set the target options that the ExecutionEngine
+  /// target is using. Defaults to TargetOptions().
+  EngineBuilder &setTargetOptions(const TargetOptions &Opts) {
+    Options = Opts;
+    return *this;
+  }
+
+  /// setRelocationModel - Set the relocation model that the ExecutionEngine
+  /// target is using. Defaults to target specific default "Reloc::Default".
+  EngineBuilder &setRelocationModel(Reloc::Model RM) {
+    RelocModel = RM;
+    return *this;
+  }
+
+  /// setCodeModel - Set the CodeModel that the ExecutionEngine target
+  /// data is using. Defaults to target specific default
+  /// "CodeModel::JITDefault".
+  EngineBuilder &setCodeModel(CodeModel::Model M) {
+    CMModel = M;
+    return *this;
+  }
+
+  /// setAllocateGVsWithCode - Sets whether global values should be allocated
+  /// into the same buffer as code.  For most applications this should be set
+  /// to false.  Allocating globals with code breaks freeMachineCodeForFunction
+  /// and is probably unsafe and bad for performance.  However, we have clients
+  /// who depend on this behavior, so we must support it.  This option defaults
+  /// to false so that users of the new API can safely use the new memory
+  /// manager and free machine code.
+  EngineBuilder &setAllocateGVsWithCode(bool a) {
+    AllocateGVsWithCode = a;
+    return *this;
+  }
+
+  /// setMArch - Override the architecture set by the Module's triple.
+  EngineBuilder &setMArch(StringRef march) {
+    MArch.assign(march.begin(), march.end());
+    return *this;
+  }
+
+  /// setMCPU - Target a specific cpu type.
+  EngineBuilder &setMCPU(StringRef mcpu) {
+    MCPU.assign(mcpu.begin(), mcpu.end());
+    return *this;
+  }
+
+  /// setUseMCJIT - Set whether the MC-JIT implementation should be used
+  /// (experimental).
+  EngineBuilder &setUseMCJIT(bool Value) {
+    UseMCJIT = Value;
+    return *this;
+  }
+
+  /// setVerifyModules - Set whether the JIT implementation should verify
+  /// IR modules during compilation.
+  EngineBuilder &setVerifyModules(bool Verify) {
+    VerifyModules = Verify;
+    return *this;
+  }
+
+  /// setMAttrs - Set cpu-specific attributes.
+  template<typename StringSequence>
+  EngineBuilder &setMAttrs(const StringSequence &mattrs) {
+    MAttrs.clear();
+    MAttrs.append(mattrs.begin(), mattrs.end());
+    return *this;
+  }
+
+  TargetMachine *selectTarget();
+
+  /// selectTarget - Pick a target either via -march or by guessing the native
+  /// arch.  Add any CPU features specified via -mcpu or -mattr.
+  TargetMachine *selectTarget(const Triple &TargetTriple,
+                              StringRef MArch,
+                              StringRef MCPU,
+                              const SmallVectorImpl<std::string>& MAttrs);
+
+  ExecutionEngine *create() {
+    return create(selectTarget());
+  }
+
+  ExecutionEngine *create(TargetMachine *TM);
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h
new file mode 100644
index 0000000..0e92f79
--- /dev/null
+++ b/include/llvm/ExecutionEngine/GenericValue.h
@@ -0,0 +1,53 @@
+//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The GenericValue class is used to represent an LLVM value of arbitrary type.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H
+#define LLVM_EXECUTIONENGINE_GENERICVALUE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+typedef void* PointerTy;
+class APInt;
+
+struct GenericValue {
+  struct IntPair {
+    unsigned int first;
+    unsigned int second;
+  };
+  union {
+    double          DoubleVal;
+    float           FloatVal;
+    PointerTy       PointerVal;
+    struct IntPair  UIntPairVal;
+    unsigned char   Untyped[8];
+  };
+  APInt IntVal;   // also used for long doubles.
+  // For aggregate data types.
+  std::vector<GenericValue> AggregateVal;
+
+  // to make code faster, set GenericValue to zero could be omitted, but it is
+  // potentially can cause problems, since GenericValue to store garbage
+  // instead of zero.
+  GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;}
+  explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
+};
+
+inline GenericValue PTOGV(void *P) { return GenericValue(P); }
+inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
+
+} // End llvm namespace.
+#endif
diff --git a/include/llvm/ExecutionEngine/Interpreter.h b/include/llvm/ExecutionEngine/Interpreter.h
new file mode 100644
index 0000000..f49d0c4
--- /dev/null
+++ b/include/llvm/ExecutionEngine/Interpreter.h
@@ -0,0 +1,38 @@
+//===-- Interpreter.h - Abstract Execution Engine Interface -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the interpreter to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_INTERPRETER_H
+#define LLVM_EXECUTIONENGINE_INTERPRETER_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInInterpreter();
+
+namespace {
+  struct ForceInterpreterLinking {
+    ForceInterpreterLinking() {
+      // We must reference the interpreter in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      LLVMLinkInInterpreter();
+    }
+  } ForceInterpreterLinking;
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h
new file mode 100644
index 0000000..581d6e6
--- /dev/null
+++ b/include/llvm/ExecutionEngine/JIT.h
@@ -0,0 +1,38 @@
+//===-- JIT.h - Abstract Execution Engine Interface -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the JIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JIT_H
+#define LLVM_EXECUTIONENGINE_JIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInJIT();
+
+namespace {
+  struct ForceJITLinking {
+    ForceJITLinking() {
+      // We must reference JIT in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      LLVMLinkInJIT();
+    }
+  } ForceJITLinking;
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h
new file mode 100644
index 0000000..99fe36c
--- /dev/null
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -0,0 +1,130 @@
+//===- JITEventListener.h - Exposes events from JIT compilation -*- 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 JITEventListener interface, which lets users get
+// callbacks when significant events happen during the JIT compilation process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
+#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
+
+#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+class Function;
+class MachineFunction;
+class OProfileWrapper;
+class IntelJITEventsWrapper;
+class ObjectImage;
+
+/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
+/// about a generated machine code function.
+struct JITEvent_EmittedFunctionDetails {
+  struct LineStart {
+    /// The address at which the current line changes.
+    uintptr_t Address;
+
+    /// The new location information.  These can be translated to DebugLocTuples
+    /// using MF->getDebugLocTuple().
+    DebugLoc Loc;
+  };
+
+  /// The machine function the struct contains information for.
+  const MachineFunction *MF;
+
+  /// The list of line boundary information, sorted by address.
+  std::vector<LineStart> LineStarts;
+};
+
+/// JITEventListener - Abstract interface for use by the JIT to notify clients
+/// about significant events during compilation. For example, to notify
+/// profilers and debuggers that need to know where functions have been emitted.
+///
+/// The default implementation of each method does nothing.
+class JITEventListener {
+public:
+  typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
+
+public:
+  JITEventListener() {}
+  virtual ~JITEventListener();
+
+  /// NotifyFunctionEmitted - Called after a function has been successfully
+  /// emitted to memory.  The function still has its MachineFunction attached,
+  /// if you should happen to need that.
+  virtual void NotifyFunctionEmitted(const Function &,
+                                     void *, size_t,
+                                     const EmittedFunctionDetails &) {}
+
+  /// NotifyFreeingMachineCode - Called from freeMachineCodeForFunction(), after
+  /// the global mapping is removed, but before the machine code is returned to
+  /// the allocator.
+  ///
+  /// OldPtr is the address of the machine code and will be the same as the Code
+  /// parameter to a previous NotifyFunctionEmitted call.  The Function passed
+  /// to NotifyFunctionEmitted may have been destroyed by the time of the
+  /// matching NotifyFreeingMachineCode call.
+  virtual void NotifyFreeingMachineCode(void *) {}
+
+  /// NotifyObjectEmitted - Called after an object has been successfully
+  /// emitted to memory.  NotifyFunctionEmitted will not be called for
+  /// individual functions in the object.
+  ///
+  /// ELF-specific information
+  /// The ObjectImage contains the generated object image
+  /// with section headers updated to reflect the address at which sections
+  /// were loaded and with relocations performed in-place on debug sections.
+  virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
+
+  /// NotifyFreeingObject - Called just before the memory associated with
+  /// a previously emitted object is released.
+  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
+
+#if LLVM_USE_INTEL_JITEVENTS
+  // Construct an IntelJITEventListener
+  static JITEventListener *createIntelJITEventListener();
+
+  // Construct an IntelJITEventListener with a test Intel JIT API implementation
+  static JITEventListener *createIntelJITEventListener(
+                                      IntelJITEventsWrapper* AlternativeImpl);
+#else
+  static JITEventListener *createIntelJITEventListener() { return nullptr; }
+
+  static JITEventListener *createIntelJITEventListener(
+                                      IntelJITEventsWrapper* AlternativeImpl) {
+    return nullptr;
+  }
+#endif // USE_INTEL_JITEVENTS
+
+#if LLVM_USE_OPROFILE
+  // Construct an OProfileJITEventListener
+  static JITEventListener *createOProfileJITEventListener();
+
+  // Construct an OProfileJITEventListener with a test opagent implementation
+  static JITEventListener *createOProfileJITEventListener(
+                                      OProfileWrapper* AlternativeImpl);
+#else
+
+  static JITEventListener *createOProfileJITEventListener() { return nullptr; }
+
+  static JITEventListener *createOProfileJITEventListener(
+                                      OProfileWrapper* AlternativeImpl) {
+    return nullptr;
+  }
+#endif // USE_OPROFILE
+
+};
+
+} // end namespace llvm.
+
+#endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
new file mode 100644
index 0000000..b22d899
--- /dev/null
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -0,0 +1,164 @@
+//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H
+
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+  class Function;
+  class GlobalValue;
+
+/// JITMemoryManager - This interface is used by the JIT to allocate and manage
+/// memory for the code generated by the JIT.  This can be reimplemented by
+/// clients that have a strong desire to control how the layout of JIT'd memory
+/// works.
+class JITMemoryManager : public RTDyldMemoryManager {
+protected:
+  bool HasGOT;
+
+public:
+  JITMemoryManager() : HasGOT(false) {}
+  virtual ~JITMemoryManager();
+
+  /// CreateDefaultMemManager - This is used to create the default
+  /// JIT Memory Manager if the client does not provide one to the JIT.
+  static JITMemoryManager *CreateDefaultMemManager();
+
+  /// setMemoryWritable - When code generation is in progress,
+  /// the code pages may need permissions changed.
+  virtual void setMemoryWritable() = 0;
+
+  /// setMemoryExecutable - When code generation is done and we're ready to
+  /// start execution, the code pages may need permissions changed.
+  virtual void setMemoryExecutable() = 0;
+
+  /// setPoisonMemory - Setting this flag to true makes the memory manager
+  /// garbage values over freed memory.  This is useful for testing and
+  /// debugging, and may be turned on by default in debug mode.
+  virtual void setPoisonMemory(bool poison) = 0;
+
+  //===--------------------------------------------------------------------===//
+  // Global Offset Table Management
+  //===--------------------------------------------------------------------===//
+
+  /// AllocateGOT - If the current table requires a Global Offset Table, this
+  /// method is invoked to allocate it.  This method is required to set HasGOT
+  /// to true.
+  virtual void AllocateGOT() = 0;
+
+  /// isManagingGOT - Return true if the AllocateGOT method is called.
+  bool isManagingGOT() const {
+    return HasGOT;
+  }
+
+  /// getGOTBase - If this is managing a Global Offset Table, this method should
+  /// return a pointer to its base.
+  virtual uint8_t *getGOTBase() const = 0;
+
+  //===--------------------------------------------------------------------===//
+  // Main Allocation Functions
+  //===--------------------------------------------------------------------===//
+
+  /// startFunctionBody - When we start JITing a function, the JIT calls this
+  /// method to allocate a block of free RWX memory, which returns a pointer to
+  /// it.  If the JIT wants to request a block of memory of at least a certain
+  /// size, it passes that value as ActualSize, and this method returns a block
+  /// with at least that much space.  If the JIT doesn't know ahead of time how
+  /// much space it will need to emit the function, it passes 0 for the
+  /// ActualSize.  In either case, this method is required to pass back the size
+  /// of the allocated block through ActualSize.  The JIT will be careful to
+  /// not write more than the returned ActualSize bytes of memory.
+  virtual uint8_t *startFunctionBody(const Function *F,
+                                     uintptr_t &ActualSize) = 0;
+
+  /// allocateStub - This method is called by the JIT to allocate space for a
+  /// function stub (used to handle limited branch displacements) while it is
+  /// JIT compiling a function.  For example, if foo calls bar, and if bar
+  /// either needs to be lazily compiled or is a native function that exists too
+  /// far away from the call site to work, this method will be used to make a
+  /// thunk for it.  The stub should be "close" to the current function body,
+  /// but should not be included in the 'actualsize' returned by
+  /// startFunctionBody.
+  virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
+                                unsigned Alignment) = 0;
+
+  /// endFunctionBody - This method is called when the JIT is done codegen'ing
+  /// the specified function.  At this point we know the size of the JIT
+  /// compiled function.  This passes in FunctionStart (which was returned by
+  /// the startFunctionBody method) and FunctionEnd which is a pointer to the
+  /// actual end of the function.  This method should mark the space allocated
+  /// and remember where it is in case the client wants to deallocate it.
+  virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
+                               uint8_t *FunctionEnd) = 0;
+
+  /// allocateSpace - Allocate a memory block of the given size.  This method
+  /// cannot be called between calls to startFunctionBody and endFunctionBody.
+  virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) = 0;
+
+  /// allocateGlobal - Allocate memory for a global.
+  virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
+
+  /// deallocateFunctionBody - Free the specified function body.  The argument
+  /// must be the return value from a call to startFunctionBody() that hasn't
+  /// been deallocated yet.  This is never called when the JIT is currently
+  /// emitting a function.
+  virtual void deallocateFunctionBody(void *Body) = 0;
+
+  /// CheckInvariants - For testing only.  Return true if all internal
+  /// invariants are preserved, or return false and set ErrorStr to a helpful
+  /// error message.
+  virtual bool CheckInvariants(std::string &) {
+    return true;
+  }
+
+  /// GetDefaultCodeSlabSize - For testing only.  Returns DefaultCodeSlabSize
+  /// from DefaultJITMemoryManager.
+  virtual size_t GetDefaultCodeSlabSize() {
+    return 0;
+  }
+
+  /// GetDefaultDataSlabSize - For testing only.  Returns DefaultCodeSlabSize
+  /// from DefaultJITMemoryManager.
+  virtual size_t GetDefaultDataSlabSize() {
+    return 0;
+  }
+
+  /// GetDefaultStubSlabSize - For testing only.  Returns DefaultCodeSlabSize
+  /// from DefaultJITMemoryManager.
+  virtual size_t GetDefaultStubSlabSize() {
+    return 0;
+  }
+
+  /// GetNumCodeSlabs - For testing only.  Returns the number of MemoryBlocks
+  /// allocated for code.
+  virtual unsigned GetNumCodeSlabs() {
+    return 0;
+  }
+
+  /// GetNumDataSlabs - For testing only.  Returns the number of MemoryBlocks
+  /// allocated for data.
+  virtual unsigned GetNumDataSlabs() {
+    return 0;
+  }
+
+  /// GetNumStubSlabs - For testing only.  Returns the number of MemoryBlocks
+  /// allocated for function stubs.
+  virtual unsigned GetNumStubSlabs() {
+    return 0;
+  }
+};
+
+} // end namespace llvm.
+
+#endif
diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h
new file mode 100644
index 0000000..66ddb7c
--- /dev/null
+++ b/include/llvm/ExecutionEngine/MCJIT.h
@@ -0,0 +1,38 @@
+//===-- MCJIT.h - MC-Based Just-In-Time Execution Engine --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the MCJIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_MCJIT_H
+#define LLVM_EXECUTIONENGINE_MCJIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInMCJIT();
+
+namespace {
+  struct ForceMCJITLinking {
+    ForceMCJITLinking() {
+      // We must reference MCJIT in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      LLVMLinkInMCJIT();
+    }
+  } ForceMCJITLinking;
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/OProfileWrapper.h b/include/llvm/ExecutionEngine/OProfileWrapper.h
new file mode 100644
index 0000000..05da594
--- /dev/null
+++ b/include/llvm/ExecutionEngine/OProfileWrapper.h
@@ -0,0 +1,124 @@
+//===-- OProfileWrapper.h - OProfile JIT API 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 OProfileWrapper object that detects if the oprofile
+// daemon is running, and provides wrappers for opagent functions used to
+// communicate with the oprofile JIT interface. The dynamic library libopagent
+// does not need to be linked directly as this object lazily loads the library
+// when the first op_ function is called.
+//
+// See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the
+// definition of the interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
+#define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <opagent.h>
+
+namespace llvm {
+
+
+class OProfileWrapper {
+  typedef  op_agent_t    (*op_open_agent_ptr_t)();
+  typedef  int           (*op_close_agent_ptr_t)(op_agent_t);
+  typedef  int           (*op_write_native_code_ptr_t)(op_agent_t,
+                                                const char*,
+                                                uint64_t,
+                                                void const*,
+                                                const unsigned int);
+  typedef  int           (*op_write_debug_line_info_ptr_t)(op_agent_t,
+                                                void const*,
+                                                size_t,
+                                                struct debug_line_info const*);
+  typedef  int           (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t);
+
+  // Also used for op_minor_version function which has the same signature
+  typedef  int           (*op_major_version_ptr_t)();
+
+  // This is not a part of the opagent API, but is useful nonetheless
+  typedef  bool          (*IsOProfileRunningPtrT)();
+
+
+  op_agent_t                      Agent;
+  op_open_agent_ptr_t             OpenAgentFunc;
+  op_close_agent_ptr_t            CloseAgentFunc;
+  op_write_native_code_ptr_t      WriteNativeCodeFunc;
+  op_write_debug_line_info_ptr_t  WriteDebugLineInfoFunc;
+  op_unload_native_code_ptr_t     UnloadNativeCodeFunc;
+  op_major_version_ptr_t          MajorVersionFunc;
+  op_major_version_ptr_t          MinorVersionFunc;
+  IsOProfileRunningPtrT           IsOProfileRunningFunc;
+
+  bool Initialized;
+
+public:
+  OProfileWrapper();
+
+  // For testing with a mock opagent implementation, skips the dynamic load and
+  // the function resolution.
+  OProfileWrapper(op_open_agent_ptr_t OpenAgentImpl,
+                  op_close_agent_ptr_t CloseAgentImpl,
+                  op_write_native_code_ptr_t WriteNativeCodeImpl,
+                  op_write_debug_line_info_ptr_t WriteDebugLineInfoImpl,
+                  op_unload_native_code_ptr_t UnloadNativeCodeImpl,
+                  op_major_version_ptr_t MajorVersionImpl,
+                  op_major_version_ptr_t MinorVersionImpl,
+                  IsOProfileRunningPtrT MockIsOProfileRunningImpl = 0)
+  : OpenAgentFunc(OpenAgentImpl),
+    CloseAgentFunc(CloseAgentImpl),
+    WriteNativeCodeFunc(WriteNativeCodeImpl),
+    WriteDebugLineInfoFunc(WriteDebugLineInfoImpl),
+    UnloadNativeCodeFunc(UnloadNativeCodeImpl),
+    MajorVersionFunc(MajorVersionImpl),
+    MinorVersionFunc(MinorVersionImpl),
+    IsOProfileRunningFunc(MockIsOProfileRunningImpl),
+    Initialized(true)
+  {
+  }
+
+  // Calls op_open_agent in the oprofile JIT library and saves the returned
+  // op_agent_t handle internally so it can be used when calling all the other
+  // op_* functions. Callers of this class do not need to keep track of
+  // op_agent_t objects.
+  bool op_open_agent();
+
+  int op_close_agent();
+  int op_write_native_code(const char* name,
+                           uint64_t addr,
+                           void const* code,
+                           const unsigned int size);
+  int op_write_debug_line_info(void const* code,
+                               size_t num_entries,
+                               struct debug_line_info const* info);
+  int op_unload_native_code(uint64_t addr);
+  int op_major_version();
+  int op_minor_version();
+
+  // Returns true if the oprofiled process is running, the opagent library is
+  // loaded and a connection to the agent has been established, and false
+  // otherwise.
+  bool isAgentAvailable();
+
+private:
+  // Loads the libopagent library and initializes this wrapper if the oprofile
+  // daemon is running
+  bool initialize();
+
+  // Searches /proc for the oprofile daemon and returns true if the process if
+  // found, or false otherwise.
+  bool checkForOProfileProcEntry();
+
+  bool isOProfileRunning();
+};
+
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644
index 0000000..6221d3b
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -0,0 +1,83 @@
+//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a wrapper class to hold the memory into which an
+// object will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// ObjectBuffer - This class acts as a container for the memory buffer used during
+/// generation and loading of executable objects using MCJIT and RuntimeDyld.  The
+/// underlying memory for the object will be owned by the ObjectBuffer instance
+/// throughout its lifetime.  The getMemBuffer() method provides a way to create a
+/// MemoryBuffer wrapper object instance to be owned by other classes (such as
+/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
+/// actual memory it points to.
+class ObjectBuffer {
+  virtual void anchor();
+public:
+  ObjectBuffer() {}
+  ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
+  virtual ~ObjectBuffer() {}
+
+  /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
+  /// returns a pointer to an object that is owned by the caller. However,
+  /// the caller does not take ownership of the underlying memory.
+  MemoryBuffer *getMemBuffer() const {
+    return MemoryBuffer::getMemBuffer(Buffer->getBuffer(),
+                                      Buffer->getBufferIdentifier(), false);
+  }
+
+  const char *getBufferStart() const { return Buffer->getBufferStart(); }
+  size_t getBufferSize() const { return Buffer->getBufferSize(); }
+  StringRef getBuffer() const { return Buffer->getBuffer(); }
+
+protected:
+  // The memory contained in an ObjectBuffer
+  std::unique_ptr<MemoryBuffer> Buffer;
+};
+
+/// ObjectBufferStream - This class encapsulates the SmallVector and
+/// raw_svector_ostream needed to generate an object using MC code emission
+/// while providing a common ObjectBuffer interface for access to the
+/// memory once the object has been generated.
+class ObjectBufferStream : public ObjectBuffer {
+  void anchor() override;
+public:
+  ObjectBufferStream() : OS(SV) {}
+  virtual ~ObjectBufferStream() {}
+
+  raw_ostream &getOStream() { return OS; }
+  void flush()
+  {
+    OS.flush();
+
+    // Make the data accessible via the ObjectBuffer::Buffer
+    Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
+                                            "",
+                                            false));
+  }
+
+protected:
+  SmallVector<char, 4096> SV; // Working buffer into which we JIT.
+  raw_svector_ostream     OS; // streaming wrapper
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h
new file mode 100644
index 0000000..d1849df
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectCache.h
@@ -0,0 +1,41 @@
+//===-- ObjectCache.h - Class definition for the ObjectCache -----C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTCACHE_H
+#define LLVM_EXECUTIONENGINE_OBJECTCACHE_H
+
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+
+class Module;
+
+/// This is the base ObjectCache type which can be provided to an
+/// ExecutionEngine for the purpose of avoiding compilation for Modules that
+/// have already been compiled and an object file is available.
+class ObjectCache {
+  virtual void anchor();
+public:
+  ObjectCache() { }
+
+  virtual ~ObjectCache() { }
+
+  /// notifyObjectCompiled - Provides a pointer to compiled code for Module M.
+  virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) = 0;
+
+  /// getObjectCopy - Returns a pointer to a newly allocated MemoryBuffer that
+  /// contains the object which corresponds with Module M, or 0 if an object is
+  /// not available. The caller owns both the MemoryBuffer returned by this
+  /// and the memory it references.
+  virtual MemoryBuffer* getObject(const Module* M) = 0;
+};
+
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
new file mode 100644
index 0000000..1fcedd8
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -0,0 +1,71 @@
+//===---- ObjectImage.h - Format independent executuable object image -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+
+
+/// ObjectImage - A container class that represents an ObjectFile that has been
+/// or is in the process of being loaded into memory for execution.
+class ObjectImage {
+  ObjectImage() LLVM_DELETED_FUNCTION;
+  ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
+  virtual void anchor();
+
+protected:
+  std::unique_ptr<ObjectBuffer> Buffer;
+
+public:
+  ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
+  virtual ~ObjectImage() {}
+
+  virtual object::symbol_iterator begin_symbols() const = 0;
+  virtual object::symbol_iterator end_symbols() const = 0;
+  iterator_range<object::symbol_iterator> symbols() const {
+    return iterator_range<object::symbol_iterator>(begin_symbols(),
+                                                   end_symbols());
+  }
+
+  virtual object::section_iterator begin_sections() const = 0;
+  virtual object::section_iterator end_sections() const  = 0;
+  iterator_range<object::section_iterator> sections() const {
+    return iterator_range<object::section_iterator>(begin_sections(),
+                                                    end_sections());
+  }
+
+  virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+  // Subclasses can override these methods to update the image with loaded
+  // addresses for sections and common symbols
+  virtual void updateSectionAddress(const object::SectionRef &Sec,
+                                    uint64_t Addr) = 0;
+  virtual void updateSymbolAddress(const object::SymbolRef &Sym,
+                                   uint64_t Addr) = 0;
+
+  virtual StringRef getData() const = 0;
+
+  virtual object::ObjectFile* getObjectFile() const = 0;
+
+  // Subclasses can override these methods to provide JIT debugging support
+  virtual void registerWithDebugger() = 0;
+  virtual void deregisterWithDebugger() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
new file mode 100644
index 0000000..b1d6810
--- /dev/null
+++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -0,0 +1,126 @@
+//===-- RTDyldMemoryManager.cpp - Memory manager for MC-JIT -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface of the runtime dynamic memory manager base class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H
+#define LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H
+
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+
+class ExecutionEngine;
+class ObjectImage;
+
+// RuntimeDyld clients often want to handle the memory management of
+// what gets placed where. For JIT clients, this is the subset of
+// JITMemoryManager required for dynamic loading of binaries.
+//
+// FIXME: As the RuntimeDyld fills out, additional routines will be needed
+//        for the varying types of objects to be allocated.
+class RTDyldMemoryManager {
+  RTDyldMemoryManager(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION;
+  void operator=(const RTDyldMemoryManager&) LLVM_DELETED_FUNCTION;
+public:
+  RTDyldMemoryManager() {}
+  virtual ~RTDyldMemoryManager();
+
+  /// Allocate a memory block of (at least) the given size suitable for
+  /// executable code. The SectionID is a unique identifier assigned by the JIT
+  /// engine, and optionally recorded by the memory manager to access a loaded
+  /// section.
+  virtual uint8_t *allocateCodeSection(
+    uintptr_t Size, unsigned Alignment, unsigned SectionID,
+    StringRef SectionName) = 0;
+
+  /// Allocate a memory block of (at least) the given size suitable for data.
+  /// The SectionID is a unique identifier assigned by the JIT engine, and
+  /// optionally recorded by the memory manager to access a loaded section.
+  virtual uint8_t *allocateDataSection(
+    uintptr_t Size, unsigned Alignment, unsigned SectionID,
+    StringRef SectionName, bool IsReadOnly) = 0;
+
+  /// Inform the memory manager about the total amount of memory required to
+  /// allocate all sections to be loaded:
+  /// \p CodeSize - the total size of all code sections
+  /// \p DataSizeRO - the total size of all read-only data sections
+  /// \p DataSizeRW - the total size of all read-write data sections
+  /// 
+  /// Note that by default the callback is disabled. To enable it
+  /// redefine the method needsToReserveAllocationSpace to return true.
+  virtual void reserveAllocationSpace(
+    uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) { }
+  
+  /// Override to return true to enable the reserveAllocationSpace callback.
+  virtual bool needsToReserveAllocationSpace() { return false; }
+
+  /// Register the EH frames with the runtime so that c++ exceptions work.
+  ///
+  /// \p Addr parameter provides the local address of the EH frame section
+  /// data, while \p LoadAddr provides the address of the data in the target
+  /// address space.  If the section has not been remapped (which will usually
+  /// be the case for local execution) these two values will be the same.
+  virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
+
+  virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size);
+
+  /// This method returns the address of the specified function or variable.
+  /// It is used to resolve symbols during module linking.
+  virtual uint64_t getSymbolAddress(const std::string &Name);
+
+  /// This method returns the address of the specified function. As such it is
+  /// only useful for resolving library symbols, not code generated symbols.
+  ///
+  /// If \p AbortOnFailure is false and no function with the given name is
+  /// found, this function returns a null pointer. Otherwise, it prints a
+  /// message to stderr and aborts.
+  ///
+  /// This function is deprecated for memory managers to be used with
+  /// MCJIT or RuntimeDyld.  Use getSymbolAddress instead.
+  virtual void *getPointerToNamedFunction(const std::string &Name,
+                                          bool AbortOnFailure = true);
+
+  /// This method is called after an object has been loaded into memory but
+  /// before relocations are applied to the loaded sections.  The object load
+  /// may have been initiated by MCJIT to resolve an external symbol for another
+  /// object that is being finalized.  In that case, the object about which
+  /// the memory manager is being notified will be finalized immediately after
+  /// the memory manager returns from this call.
+  ///
+  /// Memory managers which are preparing code for execution in an external
+  /// address space can use this call to remap the section addresses for the
+  /// newly loaded object.
+  virtual void notifyObjectLoaded(ExecutionEngine *EE,
+                                  const ObjectImage *) {}
+
+  /// This method is called when object loading is complete and section page
+  /// permissions can be applied.  It is up to the memory manager implementation
+  /// to decide whether or not to act on this method.  The memory manager will
+  /// typically allocate all sections as read-write and then apply specific
+  /// permissions when this method is called.  Code sections cannot be executed
+  /// until this function has been called.  In addition, any cache coherency
+  /// operations needed to reliably use the memory are also performed.
+  ///
+  /// Returns true if an error occurred, false otherwise.
+  virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0;
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(
+    RTDyldMemoryManager, LLVMMCJITMemoryManagerRef)
+
+} // namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
new file mode 100644
index 0000000..f123ffb
--- /dev/null
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -0,0 +1,108 @@
+//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface for the runtime dynamic linker facilities of the MC-JIT.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
+#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+
+namespace object {
+  class ObjectFile;
+}
+
+class RuntimeDyldImpl;
+class ObjectImage;
+
+class RuntimeDyld {
+  friend class RuntimeDyldChecker;
+
+  RuntimeDyld(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
+  void operator=(const RuntimeDyld &) LLVM_DELETED_FUNCTION;
+
+  // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
+  // interface.
+  RuntimeDyldImpl *Dyld;
+  RTDyldMemoryManager *MM;
+  bool ProcessAllSections;
+protected:
+  // Change the address associated with a section when resolving relocations.
+  // Any relocations already associated with the symbol will be re-resolved.
+  void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
+public:
+  RuntimeDyld(RTDyldMemoryManager *);
+  ~RuntimeDyld();
+
+  /// Prepare the object contained in the input buffer for execution.
+  /// Ownership of the input buffer is transferred to the ObjectImage
+  /// instance returned from this function if successful. In the case of load
+  /// failure, the input buffer will be deleted.
+  ObjectImage *loadObject(ObjectBuffer *InputBuffer);
+
+  /// Prepare the referenced object file for execution.
+  /// Ownership of the input object is transferred to the ObjectImage
+  /// instance returned from this function if successful. In the case of load
+  /// failure, the input object will be deleted.
+  ObjectImage *loadObject(std::unique_ptr<object::ObjectFile> InputObject);
+
+  /// Get the address of our local copy of the symbol. This may or may not
+  /// be the address used for relocation (clients can copy the data around
+  /// and resolve relocatons based on where they put it).
+  void *getSymbolAddress(StringRef Name);
+
+  /// Get the address of the target copy of the symbol. This is the address
+  /// used for relocation.
+  uint64_t getSymbolLoadAddress(StringRef Name);
+
+  /// Resolve the relocations for all symbols we currently know about.
+  void resolveRelocations();
+
+  /// Map a section to its target address space value.
+  /// Map the address of a JIT section as returned from the memory manager
+  /// to the address in the target process as the running code will see it.
+  /// This is the address which will be used for relocation resolution.
+  void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
+
+  /// Register any EH frame sections that have been loaded but not previously
+  /// registered with the memory manager.  Note, RuntimeDyld is responsible
+  /// for identifying the EH frame and calling the memory manager with the
+  /// EH frame section data.  However, the memory manager itself will handle
+  /// the actual target-specific EH frame registration.
+  void registerEHFrames();
+
+  void deregisterEHFrames();
+
+  bool hasError();
+  StringRef getErrorString();
+
+  /// By default, only sections that are "required for execution" are passed to
+  /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true'
+  /// to this method will cause RuntimeDyld to pass all sections to its
+  /// memory manager regardless of whether they are "required to execute" in the
+  /// usual sense. This is useful for inspecting metadata sections that may not
+  /// contain relocations, E.g. Debug info, stackmaps.
+  ///
+  /// Must be called before the first object file is loaded.
+  void setProcessAllSections(bool ProcessAllSections) {
+    assert(!Dyld && "setProcessAllSections must be called before loadObject.");
+    this->ProcessAllSections = ProcessAllSections;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
new file mode 100644
index 0000000..8dd891e
--- /dev/null
+++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -0,0 +1,98 @@
+//===---- RuntimeDyldChecker.h - RuntimeDyld tester framework -----*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIMEDYLDCHECKER_H
+#define LLVM_RUNTIMEDYLDCHECKER_H
+
+#include "RuntimeDyld.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+
+namespace llvm {
+
+class MCDisassembler;
+class MCInstPrinter;
+
+/// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has
+///        correctly applied relocations.
+///
+/// The RuntimeDyldChecker class evaluates expressions against an attached
+/// RuntimeDyld instance to verify that relocations have been applied
+/// correctly.
+///
+/// The expression language supports basic pointer arithmetic and bit-masking,
+/// and has limited disassembler integration for accessing instruction
+/// operands and the next PC (program counter) address for each instruction.
+///
+/// The language syntax is:
+///
+/// check = expr '=' expr
+///
+/// expr = binary_expr
+///      | sliceable_expr
+///
+/// sliceable_expr = '*{' number '}' load_addr_expr [slice]
+///                | '(' expr ')' [slice]
+///                | ident_expr [slice]
+///                | number [slice]
+///
+/// slice = '[' high-bit-index ':' low-bit-index ']'
+///
+/// load_addr_expr = symbol
+///                | '(' symbol '+' number ')'
+///                | '(' symbol '-' number ')'
+///
+/// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')'
+///            | 'next_pc'        '(' symbol ')'
+///            | symbol
+///
+/// binary_expr = expr '+' expr
+///             | expr '-' expr
+///             | expr '&' expr
+///             | expr '|' expr
+///             | expr '<<' expr
+///             | expr '>>' expr
+///
+class RuntimeDyldChecker {
+  friend class RuntimeDyldCheckerExprEval;
+public:
+  RuntimeDyldChecker(RuntimeDyld &RTDyld,
+                     MCDisassembler *Disassembler,
+                     MCInstPrinter *InstPrinter,
+                     llvm::raw_ostream &ErrStream)
+    : RTDyld(*RTDyld.Dyld), Disassembler(Disassembler),
+      InstPrinter(InstPrinter), ErrStream(ErrStream) {}
+
+  /// \brief Check a single expression against the attached RuntimeDyld
+  ///        instance.
+  bool check(StringRef CheckExpr) const;
+
+  /// \brief Scan the given memory buffer for lines beginning with the string
+  ///        in RulePrefix. The remainder of the line is passed to the check
+  ///        method to be evaluated as an expression.
+  bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
+
+private:
+
+  bool isSymbolValid(StringRef Symbol) const;
+  uint64_t getSymbolAddress(StringRef Symbol) const;
+  uint64_t readMemoryAtSymbol(StringRef Symbol, int64_t Offset,
+                              unsigned Size) const;
+  StringRef getSubsectionStartingAt(StringRef Name) const;
+
+  RuntimeDyldImpl &RTDyld;
+  MCDisassembler *Disassembler;
+  MCInstPrinter *InstPrinter;
+  llvm::raw_ostream &ErrStream;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLDCHECKER_H
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
new file mode 100644
index 0000000..1368563
--- /dev/null
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -0,0 +1,106 @@
+//===- SectionMemoryManager.h - Memory manager for MCJIT/RtDyld -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of a section-based memory manager used by
+// the MCJIT execution engine and RuntimeDyld.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+/// This is a simple memory manager which implements the methods called by
+/// the RuntimeDyld class to allocate memory for section-based loading of
+/// objects, usually those generated by the MCJIT execution engine.
+///
+/// This memory manager allocates all section memory as read-write.  The
+/// RuntimeDyld will copy JITed section memory into these allocated blocks
+/// and perform any necessary linking and relocations.
+///
+/// Any client using this memory manager MUST ensure that section-specific
+/// page permissions have been applied before attempting to execute functions
+/// in the JITed object.  Permissions can be applied either by calling
+/// MCJIT::finalizeObject or by calling SectionMemoryManager::finalizeMemory
+/// directly.  Clients of MCJIT should call MCJIT::finalizeObject.
+class SectionMemoryManager : public RTDyldMemoryManager {
+  SectionMemoryManager(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
+  void operator=(const SectionMemoryManager&) LLVM_DELETED_FUNCTION;
+
+public:
+  SectionMemoryManager() { }
+  virtual ~SectionMemoryManager();
+
+  /// \brief Allocates a memory block of (at least) the given size suitable for
+  /// executable code.
+  ///
+  /// The value of \p Alignment must be a power of two.  If \p Alignment is zero
+  /// a default alignment of 16 will be used.
+  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+                               unsigned SectionID,
+                               StringRef SectionName) override;
+
+  /// \brief Allocates a memory block of (at least) the given size suitable for
+  /// executable code.
+  ///
+  /// The value of \p Alignment must be a power of two.  If \p Alignment is zero
+  /// a default alignment of 16 will be used.
+  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+                               unsigned SectionID, StringRef SectionName,
+                               bool isReadOnly) override;
+
+  /// \brief Update section-specific memory permissions and other attributes.
+  ///
+  /// This method is called when object loading is complete and section page
+  /// permissions can be applied.  It is up to the memory manager implementation
+  /// to decide whether or not to act on this method.  The memory manager will
+  /// typically allocate all sections as read-write and then apply specific
+  /// permissions when this method is called.  Code sections cannot be executed
+  /// until this function has been called.  In addition, any cache coherency
+  /// operations needed to reliably use the memory are also performed.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool finalizeMemory(std::string *ErrMsg = nullptr) override;
+
+  /// \brief Invalidate instruction cache for code sections.
+  ///
+  /// Some platforms with separate data cache and instruction cache require
+  /// explicit cache flush, otherwise JIT code manipulations (like resolved
+  /// relocations) will get to the data cache but not to the instruction cache.
+  ///
+  /// This method is called from finalizeMemory.
+  virtual void invalidateInstructionCache();
+
+private:
+  struct MemoryGroup {
+      SmallVector<sys::MemoryBlock, 16> AllocatedMem;
+      SmallVector<sys::MemoryBlock, 16> FreeMem;
+      sys::MemoryBlock Near;
+  };
+
+  uint8_t *allocateSection(MemoryGroup &MemGroup, uintptr_t Size,
+                           unsigned Alignment);
+
+  std::error_code applyMemoryGroupPermissions(MemoryGroup &MemGroup,
+                                              unsigned Permissions);
+
+  MemoryGroup CodeMem;
+  MemoryGroup RWDataMem;
+  MemoryGroup RODataMem;
+};
+
+}
+
+#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
new file mode 100644
index 0000000..7c398a5
--- /dev/null
+++ b/include/llvm/IR/Argument.h
@@ -0,0 +1,123 @@
+//===-- llvm/Argument.h - Definition of the Argument class ------*- 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 Argument class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_ARGUMENT_H
+#define LLVM_IR_ARGUMENT_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+/// \brief LLVM Argument representation
+///
+/// This class represents an incoming formal argument to a Function. A formal
+/// argument, since it is ``formal'', does not contain an actual value but
+/// instead represents the type, argument number, and attributes of an argument
+/// for a specific function. When used in the body of said function, the
+/// argument of course represents the value of the actual argument that the
+/// function was called with.
+class Argument : public Value, public ilist_node<Argument> {
+  virtual void anchor();
+  Function *Parent;
+
+  friend class SymbolTableListTraits<Argument, Function>;
+  void setParent(Function *parent);
+
+public:
+  /// \brief Constructor.
+  ///
+  /// If \p F is specified, the argument is inserted at the end of the argument
+  /// list for \p F.
+  explicit Argument(Type *Ty, const Twine &Name = "", Function *F = nullptr);
+
+  inline const Function *getParent() const { return Parent; }
+  inline       Function *getParent()       { return Parent; }
+
+  /// \brief Return the index of this formal argument in its containing
+  /// function.
+  ///
+  /// For example in "void foo(int a, float b)" a is 0 and b is 1.
+  unsigned getArgNo() const;
+
+  /// \brief Return true if this argument has the nonnull attribute on it in
+  /// its containing function. Also returns true if at least one byte is known
+  /// to be dereferenceable and the pointer is in addrspace(0).
+  bool hasNonNullAttr() const;
+
+  /// \brief If this argument has the dereferenceable attribute on it in its
+  /// containing function, return the number of bytes known to be
+  /// dereferenceable. Otherwise, zero is returned.
+  uint64_t getDereferenceableBytes() const;
+
+  /// \brief Return true if this argument has the byval attribute on it in its
+  /// containing function.
+  bool hasByValAttr() const;
+
+  /// \brief Return true if this argument has the byval attribute or inalloca
+  /// attribute on it in its containing function.  These attributes both
+  /// represent arguments being passed by value.
+  bool hasByValOrInAllocaAttr() const;
+
+  /// \brief If this is a byval or inalloca argument, return its alignment.
+  unsigned getParamAlignment() const;
+
+  /// \brief Return true if this argument has the nest attribute on it in its
+  /// containing function.
+  bool hasNestAttr() const;
+
+  /// \brief Return true if this argument has the noalias attribute on it in its
+  /// containing function.
+  bool hasNoAliasAttr() const;
+
+  /// \brief Return true if this argument has the nocapture attribute on it in
+  /// its containing function.
+  bool hasNoCaptureAttr() const;
+
+  /// \brief Return true if this argument has the sret attribute on it in its
+  /// containing function.
+  bool hasStructRetAttr() const;
+
+  /// \brief Return true if this argument has the returned attribute on it in
+  /// its containing function.
+  bool hasReturnedAttr() const;
+
+  /// \brief Return true if this argument has the readonly or readnone attribute
+  /// on it in its containing function.
+  bool onlyReadsMemory() const;
+
+  /// \brief Return true if this argument has the inalloca attribute on it in
+  /// its containing function.
+  bool hasInAllocaAttr() const;
+
+  /// \brief Add a Attribute to an argument.
+  void addAttr(AttributeSet AS);
+
+  /// \brief Remove a Attribute from an argument.
+  void removeAttr(AttributeSet AS);
+
+  /// \brief Method for support type inquiry through isa, cast, and
+  /// dyn_cast.
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == ArgumentVal;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/AssemblyAnnotationWriter.h b/include/llvm/IR/AssemblyAnnotationWriter.h
new file mode 100644
index 0000000..a8d52f6
--- /dev/null
+++ b/include/llvm/IR/AssemblyAnnotationWriter.h
@@ -0,0 +1,63 @@
+//===-- AssemblyAnnotationWriter.h - Annotation .ll files -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Clients of the assembly writer can use this interface to add their own
+// special-purpose annotations to LLVM assembly language printouts.  Note that
+// the assembly parser won't be able to parse these, in general, so
+// implementations are advised to print stuff as LLVM comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_ASMANNOTATIONWRITER_H
+#define LLVM_IR_ASMANNOTATIONWRITER_H
+
+namespace llvm {
+
+class Function;
+class BasicBlock;
+class Instruction;
+class Value;
+class formatted_raw_ostream;
+
+class AssemblyAnnotationWriter {
+public:
+
+  virtual ~AssemblyAnnotationWriter();
+
+  /// emitFunctionAnnot - This may be implemented to emit a string right before
+  /// the start of a function.
+  virtual void emitFunctionAnnot(const Function *,
+                                 formatted_raw_ostream &) {}
+
+  /// emitBasicBlockStartAnnot - This may be implemented to emit a string right
+  /// after the basic block label, but before the first instruction in the
+  /// block.
+  virtual void emitBasicBlockStartAnnot(const BasicBlock *,
+                                        formatted_raw_ostream &) {
+  }
+
+  /// emitBasicBlockEndAnnot - This may be implemented to emit a string right
+  /// after the basic block.
+  virtual void emitBasicBlockEndAnnot(const BasicBlock *,
+                                      formatted_raw_ostream &) {
+  }
+
+  /// emitInstructionAnnot - This may be implemented to emit a string right
+  /// before an instruction is emitted.
+  virtual void emitInstructionAnnot(const Instruction *, 
+                                    formatted_raw_ostream &) {}
+
+  /// printInfoComment - This may be implemented to emit a comment to the
+  /// right of an instruction or global value.
+  virtual void printInfoComment(const Value &, formatted_raw_ostream &) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
new file mode 100644
index 0000000..5ff48d6
--- /dev/null
+++ b/include/llvm/IR/Attributes.h
@@ -0,0 +1,530 @@
+//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file contains the simple types necessary to represent the
+/// attributes associated with functions and their calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_ATTRIBUTES_H
+#define LLVM_IR_ATTRIBUTES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <bitset>
+#include <cassert>
+#include <map>
+#include <string>
+
+namespace llvm {
+
+class AttrBuilder;
+class AttributeImpl;
+class AttributeSetImpl;
+class AttributeSetNode;
+class Constant;
+template<typename T> struct DenseMapInfo;
+class LLVMContext;
+class Type;
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Functions, function parameters, and return types can have attributes
+/// to indicate how they should be treated by optimizations and code
+/// generation. This class represents one of those attributes. It's light-weight
+/// and should be passed around by-value.
+class Attribute {
+public:
+  /// This enumeration lists the attributes that can be associated with
+  /// parameters, function results, or the function itself.
+  ///
+  /// Note: The `uwtable' attribute is about the ABI or the user mandating an
+  /// entry in the unwind table. The `nounwind' attribute is about an exception
+  /// passing by the function.
+  ///
+  /// In a theoretical system that uses tables for profiling and SjLj for
+  /// exceptions, they would be fully independent. In a normal system that uses
+  /// tables for both, the semantics are:
+  ///
+  /// nil                = Needs an entry because an exception might pass by.
+  /// nounwind           = No need for an entry
+  /// uwtable            = Needs an entry because the ABI says so and because
+  ///                      an exception might pass by.
+  /// uwtable + nounwind = Needs an entry because the ABI says so.
+
+  enum AttrKind {
+    // IR-Level Attributes
+    None,                  ///< No attributes have been set
+    Alignment,             ///< Alignment of parameter (5 bits)
+                           ///< stored as log2 of alignment with +1 bias
+                           ///< 0 means unaligned (different from align(1))
+    AlwaysInline,          ///< inline=always
+    Builtin,               ///< Callee is recognized as a builtin, despite
+                           ///< nobuiltin attribute on its declaration.
+    ByVal,                 ///< Pass structure by value
+    InAlloca,              ///< Pass structure in an alloca
+    Cold,                  ///< Marks function as being in a cold path.
+    InlineHint,            ///< Source said inlining was desirable
+    InReg,                 ///< Force argument to be passed in register
+    JumpTable,             ///< Build jump-instruction tables and replace refs.
+    MinSize,               ///< Function must be optimized for size first
+    Naked,                 ///< Naked function
+    Nest,                  ///< Nested function static chain
+    NoAlias,               ///< Considered to not alias after call
+    NoBuiltin,             ///< Callee isn't recognized as a builtin
+    NoCapture,             ///< Function creates no aliases of pointer
+    NoDuplicate,           ///< Call cannot be duplicated
+    NoImplicitFloat,       ///< Disable implicit floating point insts
+    NoInline,              ///< inline=never
+    NonLazyBind,           ///< Function is called early and/or
+                           ///< often, so lazy binding isn't worthwhile
+    NonNull,               ///< Pointer is known to be not null
+    Dereferenceable,       ///< Pointer is known to be dereferenceable
+    NoRedZone,             ///< Disable redzone
+    NoReturn,              ///< Mark the function as not returning
+    NoUnwind,              ///< Function doesn't unwind stack
+    OptimizeForSize,       ///< opt_size
+    OptimizeNone,          ///< Function must not be optimized.
+    ReadNone,              ///< Function does not access memory
+    ReadOnly,              ///< Function only reads from memory
+    Returned,              ///< Return value is always equal to this argument
+    ReturnsTwice,          ///< Function can return twice
+    SExt,                  ///< Sign extended before/after call
+    StackAlignment,        ///< Alignment of stack for function (3 bits)
+                           ///< stored as log2 of alignment with +1 bias 0
+                           ///< means unaligned (different from
+                           ///< alignstack=(1))
+    StackProtect,          ///< Stack protection.
+    StackProtectReq,       ///< Stack protection required.
+    StackProtectStrong,    ///< Strong Stack protection.
+    StructRet,             ///< Hidden pointer to structure to return
+    SanitizeAddress,       ///< AddressSanitizer is on.
+    SanitizeThread,        ///< ThreadSanitizer is on.
+    SanitizeMemory,        ///< MemorySanitizer is on.
+    UWTable,               ///< Function must be in a unwind table
+    ZExt,                  ///< Zero extended before/after call
+
+    EndAttrKinds           ///< Sentinal value useful for loops
+  };
+private:
+  AttributeImpl *pImpl;
+  Attribute(AttributeImpl *A) : pImpl(A) {}
+public:
+  Attribute() : pImpl(nullptr) {}
+
+  //===--------------------------------------------------------------------===//
+  // Attribute Construction
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return a uniquified Attribute object.
+  static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
+  static Attribute get(LLVMContext &Context, StringRef Kind,
+                       StringRef Val = StringRef());
+
+  /// \brief Return a uniquified Attribute object that has the specific
+  /// alignment set.
+  static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align);
+  static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
+  static Attribute getWithDereferenceableBytes(LLVMContext &Context,
+                                              uint64_t Bytes);
+
+  //===--------------------------------------------------------------------===//
+  // Attribute Accessors
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return true if the attribute is an Attribute::AttrKind type.
+  bool isEnumAttribute() const;
+
+  /// \brief Return true if the attribute is an integer attribute.
+  bool isIntAttribute() const;
+
+  /// \brief Return true if the attribute is a string (target-dependent)
+  /// attribute.
+  bool isStringAttribute() const;
+
+  /// \brief Return true if the attribute is present.
+  bool hasAttribute(AttrKind Val) const;
+
+  /// \brief Return true if the target-dependent attribute is present.
+  bool hasAttribute(StringRef Val) const;
+
+  /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). This
+  /// requires the attribute to be an enum or alignment attribute.
+  Attribute::AttrKind getKindAsEnum() const;
+
+  /// \brief Return the attribute's value as an integer. This requires that the
+  /// attribute be an alignment attribute.
+  uint64_t getValueAsInt() const;
+
+  /// \brief Return the attribute's kind as a string. This requires the
+  /// attribute to be a string attribute.
+  StringRef getKindAsString() const;
+
+  /// \brief Return the attribute's value as a string. This requires the
+  /// attribute to be a string attribute.
+  StringRef getValueAsString() const;
+
+  /// \brief Returns the alignment field of an attribute as a byte alignment
+  /// value.
+  unsigned getAlignment() const;
+
+  /// \brief Returns the stack alignment field of an attribute as a byte
+  /// alignment value.
+  unsigned getStackAlignment() const;
+
+  /// \brief Returns the number of dereferenceable bytes from the
+  /// dereferenceable attribute (or zero if unknown).
+  uint64_t getDereferenceableBytes() const;
+
+  /// \brief The Attribute is converted to a string of equivalent mnemonic. This
+  /// is, presumably, for writing out the mnemonics for the assembly writer.
+  std::string getAsString(bool InAttrGrp = false) const;
+
+  /// \brief Equality and non-equality operators.
+  bool operator==(Attribute A) const { return pImpl == A.pImpl; }
+  bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
+
+  /// \brief Less-than operator. Useful for sorting the attributes list.
+  bool operator<(Attribute A) const;
+
+  void Profile(FoldingSetNodeID &ID) const {
+    ID.AddPointer(pImpl);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class holds the attributes for a function, its return value, and
+/// its parameters. You access the attributes for each of them via an index into
+/// the AttributeSet object. The function attributes are at index
+/// `AttributeSet::FunctionIndex', the return value is at index
+/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at
+/// index `1'.
+class AttributeSet {
+public:
+  enum AttrIndex : unsigned {
+    ReturnIndex = 0U,
+    FunctionIndex = ~0U
+  };
+private:
+  friend class AttrBuilder;
+  friend class AttributeSetImpl;
+  template <typename Ty> friend struct DenseMapInfo;
+
+  /// \brief The attributes that we are managing. This can be null to represent
+  /// the empty attributes list.
+  AttributeSetImpl *pImpl;
+
+  /// \brief The attributes for the specified index are returned.
+  AttributeSetNode *getAttributes(unsigned Index) const;
+
+  /// \brief Create an AttributeSet with the specified parameters in it.
+  static AttributeSet get(LLVMContext &C,
+                          ArrayRef<std::pair<unsigned, Attribute> > Attrs);
+  static AttributeSet get(LLVMContext &C,
+                          ArrayRef<std::pair<unsigned,
+                                             AttributeSetNode*> > Attrs);
+
+  static AttributeSet getImpl(LLVMContext &C,
+                              ArrayRef<std::pair<unsigned,
+                                                 AttributeSetNode*> > Attrs);
+
+
+  explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {}
+public:
+  AttributeSet() : pImpl(nullptr) {}
+
+  //===--------------------------------------------------------------------===//
+  // AttributeSet Construction and Mutation
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return an AttributeSet with the specified parameters in it.
+  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
+  static AttributeSet get(LLVMContext &C, unsigned Index,
+                          ArrayRef<Attribute::AttrKind> Kind);
+  static AttributeSet get(LLVMContext &C, unsigned Index, const AttrBuilder &B);
+
+  /// \brief Add an attribute to the attribute set at the given index. Since
+  /// attribute sets are immutable, this returns a new set.
+  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
+                            Attribute::AttrKind Attr) const;
+
+  /// \brief Add an attribute to the attribute set at the given index. Since
+  /// attribute sets are immutable, this returns a new set.
+  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
+                            StringRef Kind) const;
+  AttributeSet addAttribute(LLVMContext &C, unsigned Index,
+                            StringRef Kind, StringRef Value) const;
+
+  /// \brief Add attributes to the attribute set at the given index. Since
+  /// attribute sets are immutable, this returns a new set.
+  AttributeSet addAttributes(LLVMContext &C, unsigned Index,
+                             AttributeSet Attrs) const;
+
+  /// \brief Remove the specified attribute at the specified index from this
+  /// attribute list. Since attribute lists are immutable, this returns the new
+  /// list.
+  AttributeSet removeAttribute(LLVMContext &C, unsigned Index, 
+                               Attribute::AttrKind Attr) const;
+
+  /// \brief Remove the specified attributes at the specified index from this
+  /// attribute list. Since attribute lists are immutable, this returns the new
+  /// list.
+  AttributeSet removeAttributes(LLVMContext &C, unsigned Index, 
+                                AttributeSet Attrs) const;
+
+  //===--------------------------------------------------------------------===//
+  // AttributeSet Accessors
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Retrieve the LLVM context.
+  LLVMContext &getContext() const;
+
+  /// \brief The attributes for the specified index are returned.
+  AttributeSet getParamAttributes(unsigned Index) const;
+
+  /// \brief The attributes for the ret value are returned.
+  AttributeSet getRetAttributes() const;
+
+  /// \brief The function attributes are returned.
+  AttributeSet getFnAttributes() const;
+
+  /// \brief Return true if the attribute exists at the given index.
+  bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+
+  /// \brief Return true if the attribute exists at the given index.
+  bool hasAttribute(unsigned Index, StringRef Kind) const;
+
+  /// \brief Return true if attribute exists at the given index.
+  bool hasAttributes(unsigned Index) const;
+
+  /// \brief Return true if the specified attribute is set for at least one
+  /// parameter or for the return value.
+  bool hasAttrSomewhere(Attribute::AttrKind Attr) const;
+
+  /// \brief Return the attribute object that exists at the given index.
+  Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+
+  /// \brief Return the attribute object that exists at the given index.
+  Attribute getAttribute(unsigned Index, StringRef Kind) const;
+
+  /// \brief Return the alignment for the specified function parameter.
+  unsigned getParamAlignment(unsigned Index) const;
+
+  /// \brief Get the stack alignment.
+  unsigned getStackAlignment(unsigned Index) const;
+
+  /// \brief Get the number of dereferenceable bytes (or zero if unknown).
+  uint64_t getDereferenceableBytes(unsigned Index) const;
+
+  /// \brief Return the attributes at the index as a string.
+  std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
+
+  typedef ArrayRef<Attribute>::iterator iterator;
+
+  iterator begin(unsigned Slot) const;
+  iterator end(unsigned Slot) const;
+
+  /// operator==/!= - Provide equality predicates.
+  bool operator==(const AttributeSet &RHS) const {
+    return pImpl == RHS.pImpl;
+  }
+  bool operator!=(const AttributeSet &RHS) const {
+    return pImpl != RHS.pImpl;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // AttributeSet Introspection
+  //===--------------------------------------------------------------------===//
+
+  // FIXME: Remove this.
+  uint64_t Raw(unsigned Index) const;
+
+  /// \brief Return a raw pointer that uniquely identifies this attribute list.
+  void *getRawPointer() const {
+    return pImpl;
+  }
+
+  /// \brief Return true if there are no attributes.
+  bool isEmpty() const {
+    return getNumSlots() == 0;
+  }
+
+  /// \brief Return the number of slots used in this attribute list.  This is
+  /// the number of arguments that have an attribute set on them (including the
+  /// function itself).
+  unsigned getNumSlots() const;
+
+  /// \brief Return the index for the given slot.
+  unsigned getSlotIndex(unsigned Slot) const;
+
+  /// \brief Return the attributes at the given slot.
+  AttributeSet getSlotAttributes(unsigned Slot) const;
+
+  void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Provide DenseMapInfo for AttributeSet.
+template<> struct DenseMapInfo<AttributeSet> {
+  static inline AttributeSet getEmptyKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-1);
+    Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
+    return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+  }
+  static inline AttributeSet getTombstoneKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-2);
+    Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
+    return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+  }
+  static unsigned getHashValue(AttributeSet AS) {
+    return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
+           (unsigned((uintptr_t)AS.pImpl) >> 9);
+  }
+  static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class is used in conjunction with the Attribute::get method to
+/// create an Attribute object. The object itself is uniquified. The Builder's
+/// value, however, is not. So this can be used as a quick way to test for
+/// equality, presence of attributes, etc.
+class AttrBuilder {
+  std::bitset<Attribute::EndAttrKinds> Attrs;
+  std::map<std::string, std::string> TargetDepAttrs;
+  uint64_t Alignment;
+  uint64_t StackAlignment;
+  uint64_t DerefBytes;
+public:
+  AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {}
+  explicit AttrBuilder(uint64_t Val)
+    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+    addRawValue(Val);
+  }
+  AttrBuilder(const Attribute &A)
+    : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+    addAttribute(A);
+  }
+  AttrBuilder(AttributeSet AS, unsigned Idx);
+
+  void clear();
+
+  /// \brief Add an attribute to the builder.
+  AttrBuilder &addAttribute(Attribute::AttrKind Val);
+
+  /// \brief Add the Attribute object to the builder.
+  AttrBuilder &addAttribute(Attribute A);
+
+  /// \brief Add the target-dependent attribute to the builder.
+  AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
+
+  /// \brief Remove an attribute from the builder.
+  AttrBuilder &removeAttribute(Attribute::AttrKind Val);
+
+  /// \brief Remove the attributes from the builder.
+  AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index);
+
+  /// \brief Remove the target-dependent attribute to the builder.
+  AttrBuilder &removeAttribute(StringRef A);
+
+  /// \brief Add the attributes from the builder.
+  AttrBuilder &merge(const AttrBuilder &B);
+
+  /// \brief Return true if the builder has the specified attribute.
+  bool contains(Attribute::AttrKind A) const {
+    assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
+    return Attrs[A];
+  }
+
+  /// \brief Return true if the builder has the specified target-dependent
+  /// attribute.
+  bool contains(StringRef A) const;
+
+  /// \brief Return true if the builder has IR-level attributes.
+  bool hasAttributes() const;
+
+  /// \brief Return true if the builder has any attribute that's in the
+  /// specified attribute.
+  bool hasAttributes(AttributeSet A, uint64_t Index) const;
+
+  /// \brief Return true if the builder has an alignment attribute.
+  bool hasAlignmentAttr() const;
+
+  /// \brief Retrieve the alignment attribute, if it exists.
+  uint64_t getAlignment() const { return Alignment; }
+
+  /// \brief Retrieve the stack alignment attribute, if it exists.
+  uint64_t getStackAlignment() const { return StackAlignment; }
+
+  /// \brief Retrieve the number of dereferenceable bytes, if the dereferenceable
+  /// attribute exists (zero is returned otherwise).
+  uint64_t getDereferenceableBytes() const { return DerefBytes; }
+
+  /// \brief This turns an int alignment (which must be a power of 2) into the
+  /// form used internally in Attribute.
+  AttrBuilder &addAlignmentAttr(unsigned Align);
+
+  /// \brief This turns an int stack alignment (which must be a power of 2) into
+  /// the form used internally in Attribute.
+  AttrBuilder &addStackAlignmentAttr(unsigned Align);
+
+  /// \brief This turns the number of dereferenceable bytes into the form used
+  /// internally in Attribute.
+  AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
+
+  /// \brief Return true if the builder contains no target-independent
+  /// attributes.
+  bool empty() const { return Attrs.none(); }
+
+  // Iterators for target-dependent attributes.
+  typedef std::pair<std::string, std::string>                td_type;
+  typedef std::map<std::string, std::string>::iterator       td_iterator;
+  typedef std::map<std::string, std::string>::const_iterator td_const_iterator;
+  typedef llvm::iterator_range<td_iterator>                  td_range;
+  typedef llvm::iterator_range<td_const_iterator>            td_const_range;
+
+  td_iterator td_begin()             { return TargetDepAttrs.begin(); }
+  td_iterator td_end()               { return TargetDepAttrs.end(); }
+
+  td_const_iterator td_begin() const { return TargetDepAttrs.begin(); }
+  td_const_iterator td_end() const   { return TargetDepAttrs.end(); }
+
+  td_range td_attrs() { return td_range(td_begin(), td_end()); }
+  td_const_range td_attrs() const {
+    return td_const_range(td_begin(), td_end());
+  }
+
+  bool td_empty() const              { return TargetDepAttrs.empty(); }
+
+  bool operator==(const AttrBuilder &B);
+  bool operator!=(const AttrBuilder &B) {
+    return !(*this == B);
+  }
+
+  // FIXME: Remove this in 4.0.
+
+  /// \brief Add the raw value to the internal representation.
+  AttrBuilder &addRawValue(uint64_t Val);
+};
+
+namespace AttributeFuncs {
+
+/// \brief Which attributes cannot be applied to a type.
+AttributeSet typeIncompatible(Type *Ty, uint64_t Index);
+
+} // end AttributeFuncs namespace
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h
new file mode 100644
index 0000000..a4b3c41
--- /dev/null
+++ b/include/llvm/IR/AutoUpgrade.h
@@ -0,0 +1,71 @@
+//===- AutoUpgrade.h - AutoUpgrade Helpers ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  These functions are implemented by lib/IR/AutoUpgrade.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_AUTOUPGRADE_H
+#define LLVM_IR_AUTOUPGRADE_H
+
+#include <string>
+
+namespace llvm {
+  class CallInst;
+  class Constant;
+  class Function;
+  class Instruction;
+  class Module;
+  class GlobalVariable;
+  class Type;
+  class Value;
+
+  /// This is a more granular function that simply checks an intrinsic function
+  /// for upgrading, and returns true if it requires upgrading. It may return
+  /// null in NewFn if the all calls to the original intrinsic function
+  /// should be transformed to non-function-call instructions.
+  bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn);
+
+  /// This is the complement to the above, replacing a specific call to an
+  /// intrinsic function with a call to the specified new function.
+  void UpgradeIntrinsicCall(CallInst *CI, Function *NewFn);
+
+  /// This is an auto-upgrade hook for any old intrinsic function syntaxes
+  /// which need to have both the function updated as well as all calls updated
+  /// to the new function. This should only be run in a post-processing fashion
+  /// so that it can update all calls to the old function.
+  void UpgradeCallsToIntrinsic(Function* F);
+
+  /// This checks for global variables which should be upgraded. It returns true
+  /// if it requires upgrading.
+  bool UpgradeGlobalVariable(GlobalVariable *GV);
+
+  /// If the TBAA tag for the given instruction uses the scalar TBAA format,
+  /// we upgrade it to the struct-path aware TBAA format.
+  void UpgradeInstWithTBAATag(Instruction *I);
+
+  /// This is an auto-upgrade for bitcast between pointers with different
+  /// address spaces: the instruction is replaced by a pair ptrtoint+inttoptr.
+  Instruction *UpgradeBitCastInst(unsigned Opc, Value *V, Type *DestTy,
+                                  Instruction *&Temp);
+
+  /// This is an auto-upgrade for bitcast constant expression between pointers
+  /// with different address spaces: the instruction is replaced by a pair
+  /// ptrtoint+inttoptr.
+  Value *UpgradeBitCastExpr(unsigned Opc, Constant *C, Type *DestTy);
+
+  /// Check the debug info version number, if it is out-dated, drop the debug
+  /// info. Return true if module is modified.
+  bool UpgradeDebugInfo(Module &M);
+
+  /// Upgrade a metadata string constant in place.
+  void UpgradeMDStringConstant(std::string &String);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
new file mode 100644
index 0000000..a19489a
--- /dev/null
+++ b/include/llvm/IR/BasicBlock.h
@@ -0,0 +1,312 @@
+//===-- llvm/BasicBlock.h - Represent a basic block in the VM ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the BasicBlock class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_BASICBLOCK_H
+#define LLVM_IR_BASICBLOCK_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/SymbolTableListTraits.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class LandingPadInst;
+class TerminatorInst;
+class LLVMContext;
+class BlockAddress;
+
+template<> struct ilist_traits<Instruction>
+  : public SymbolTableListTraits<Instruction, BasicBlock> {
+
+  /// \brief Return a node that marks the end of a list.
+  ///
+  /// The sentinel is relative to this instance, so we use a non-static
+  /// method.
+  Instruction *createSentinel() const {
+    // Since i(p)lists always publicly derive from their corresponding traits,
+    // placing a data member in this class will augment the i(p)list.  But since
+    // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+    // there is a legal viable downcast from it to NodeTy. We use this trick to
+    // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+    // sentinel. Dereferencing the sentinel is forbidden (save the
+    // ilist_node<NodeTy>), so no one will ever notice the superposition.
+    return static_cast<Instruction*>(&Sentinel);
+  }
+  static void destroySentinel(Instruction*) {}
+
+  Instruction *provideInitialHead() const { return createSentinel(); }
+  Instruction *ensureHead(Instruction*) const { return createSentinel(); }
+  static void noteHead(Instruction*, Instruction*) {}
+private:
+  mutable ilist_half_node<Instruction> Sentinel;
+};
+
+/// \brief LLVM Basic Block Representation
+///
+/// This represents a single basic block in LLVM. A basic block is simply a
+/// container of instructions that execute sequentially. Basic blocks are Values
+/// because they are referenced by instructions such as branches and switch
+/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
+/// represents a label to which a branch can jump.
+///
+/// A well formed basic block is formed of a list of non-terminating
+/// instructions followed by a single TerminatorInst instruction.
+/// TerminatorInst's may not occur in the middle of basic blocks, and must
+/// terminate the blocks. The BasicBlock class allows malformed basic blocks to
+/// occur because it may be useful in the intermediate stage of constructing or
+/// modifying a program. However, the verifier will ensure that basic blocks
+/// are "well formed".
+class BasicBlock : public Value, // Basic blocks are data objects also
+                   public ilist_node<BasicBlock> {
+  friend class BlockAddress;
+public:
+  typedef iplist<Instruction> InstListType;
+private:
+  InstListType InstList;
+  Function *Parent;
+
+  void setParent(Function *parent);
+  friend class SymbolTableListTraits<BasicBlock, Function>;
+
+  BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
+  void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
+
+  /// \brief Constructor.
+  ///
+  /// If the function parameter is specified, the basic block is automatically
+  /// inserted at either the end of the function (if InsertBefore is null), or
+  /// before the specified basic block.
+  explicit BasicBlock(LLVMContext &C, const Twine &Name = "",
+                      Function *Parent = nullptr,
+                      BasicBlock *InsertBefore = nullptr);
+public:
+  /// \brief Get the context in which this basic block lives.
+  LLVMContext &getContext() const;
+
+  /// Instruction iterators...
+  typedef InstListType::iterator iterator;
+  typedef InstListType::const_iterator const_iterator;
+  typedef InstListType::reverse_iterator reverse_iterator;
+  typedef InstListType::const_reverse_iterator const_reverse_iterator;
+
+  /// \brief Creates a new BasicBlock.
+  ///
+  /// If the Parent parameter is specified, the basic block is automatically
+  /// inserted at either the end of the function (if InsertBefore is 0), or
+  /// before the specified basic block.
+  static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
+                            Function *Parent = nullptr,
+                            BasicBlock *InsertBefore = nullptr) {
+    return new BasicBlock(Context, Name, Parent, InsertBefore);
+  }
+  ~BasicBlock();
+
+  /// \brief Return the enclosing method, or null if none.
+  const Function *getParent() const { return Parent; }
+        Function *getParent()       { return Parent; }
+
+  const DataLayout *getDataLayout() const;
+
+  /// \brief Returns the terminator instruction if the block is well formed or
+  /// null if the block is not well formed.
+  TerminatorInst *getTerminator();
+  const TerminatorInst *getTerminator() const;
+
+  /// \brief Returns a pointer to the first instruction in this block that is
+  /// not a PHINode instruction.
+  ///
+  /// When adding instructions to the beginning of the basic block, they should
+  /// be added before the returned value, not before the first instruction,
+  /// which might be PHI. Returns 0 is there's no non-PHI instruction.
+  Instruction* getFirstNonPHI();
+  const Instruction* getFirstNonPHI() const {
+    return const_cast<BasicBlock*>(this)->getFirstNonPHI();
+  }
+
+  /// \brief Returns a pointer to the first instruction in this block that is not
+  /// a PHINode or a debug intrinsic.
+  Instruction* getFirstNonPHIOrDbg();
+  const Instruction* getFirstNonPHIOrDbg() const {
+    return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
+  }
+
+  /// \brief Returns a pointer to the first instruction in this block that is not
+  /// a PHINode, a debug intrinsic, or a lifetime intrinsic.
+  Instruction* getFirstNonPHIOrDbgOrLifetime();
+  const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
+    return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
+  }
+
+  /// \brief Returns an iterator to the first instruction in this block that is
+  /// suitable for inserting a non-PHI instruction.
+  ///
+  /// In particular, it skips all PHIs and LandingPad instructions.
+  iterator getFirstInsertionPt();
+  const_iterator getFirstInsertionPt() const {
+    return const_cast<BasicBlock*>(this)->getFirstInsertionPt();
+  }
+
+  /// \brief Unlink 'this' from the containing function, but do not delete it.
+  void removeFromParent();
+
+  /// \brief Unlink 'this' from the containing function and delete it.
+  void eraseFromParent();
+
+  /// \brief Unlink this basic block from its current function and insert it
+  /// into the function that \p MovePos lives in, right before \p MovePos.
+  void moveBefore(BasicBlock *MovePos);
+
+  /// \brief Unlink this basic block from its current function and insert it
+  /// right after \p MovePos in the function \p MovePos lives in.
+  void moveAfter(BasicBlock *MovePos);
+
+
+  /// \brief Return the predecessor of this block if it has a single predecessor
+  /// block. Otherwise return a null pointer.
+  BasicBlock *getSinglePredecessor();
+  const BasicBlock *getSinglePredecessor() const {
+    return const_cast<BasicBlock*>(this)->getSinglePredecessor();
+  }
+
+  /// \brief Return the predecessor of this block if it has a unique predecessor
+  /// block. Otherwise return a null pointer.
+  ///
+  /// Note that unique predecessor doesn't mean single edge, there can be
+  /// multiple edges from the unique predecessor to this block (for example a
+  /// switch statement with multiple cases having the same destination).
+  BasicBlock *getUniquePredecessor();
+  const BasicBlock *getUniquePredecessor() const {
+    return const_cast<BasicBlock*>(this)->getUniquePredecessor();
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// Instruction iterator methods
+  ///
+  inline iterator                begin()       { return InstList.begin(); }
+  inline const_iterator          begin() const { return InstList.begin(); }
+  inline iterator                end  ()       { return InstList.end();   }
+  inline const_iterator          end  () const { return InstList.end();   }
+
+  inline reverse_iterator        rbegin()       { return InstList.rbegin(); }
+  inline const_reverse_iterator  rbegin() const { return InstList.rbegin(); }
+  inline reverse_iterator        rend  ()       { return InstList.rend();   }
+  inline const_reverse_iterator  rend  () const { return InstList.rend();   }
+
+  inline size_t                   size() const { return InstList.size();  }
+  inline bool                    empty() const { return InstList.empty(); }
+  inline const Instruction      &front() const { return InstList.front(); }
+  inline       Instruction      &front()       { return InstList.front(); }
+  inline const Instruction       &back() const { return InstList.back();  }
+  inline       Instruction       &back()       { return InstList.back();  }
+
+  /// \brief Return the underlying instruction list container.
+  ///
+  /// Currently you need to access the underlying instruction list container
+  /// directly if you want to modify it.
+  const InstListType &getInstList() const { return InstList; }
+        InstListType &getInstList()       { return InstList; }
+
+  /// \brief Returns a pointer to a member of the instruction list.
+  static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) {
+    return &BasicBlock::InstList;
+  }
+
+  /// \brief Returns a pointer to the symbol table if one exists.
+  ValueSymbolTable *getValueSymbolTable();
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::BasicBlockVal;
+  }
+
+  /// \brief Cause all subinstructions to "let go" of all the references that
+  /// said subinstructions are maintaining.
+  ///
+  /// This allows one to 'delete' a whole class at a time, even though there may
+  /// be circular references... first all references are dropped, and all use
+  /// counts go to zero.  Then everything is delete'd for real.  Note that no
+  /// operations are valid on an object that has "dropped all references",
+  /// except operator delete.
+  void dropAllReferences();
+
+  /// \brief Notify the BasicBlock that the predecessor \p Pred is no longer
+  /// able to reach it.
+  ///
+  /// This is actually not used to update the Predecessor list, but is actually
+  /// used to update the PHI nodes that reside in the block.  Note that this
+  /// should be called while the predecessor still refers to this block.
+  void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false);
+
+  /// \brief Split the basic block into two basic blocks at the specified
+  /// instruction.
+  ///
+  /// Note that all instructions BEFORE the specified iterator stay as part of
+  /// the original basic block, an unconditional branch is added to the original
+  /// BB, and the rest of the instructions in the BB are moved to the new BB,
+  /// including the old terminator.  The newly formed BasicBlock is returned.
+  /// This function invalidates the specified iterator.
+  ///
+  /// Note that this only works on well formed basic blocks (must have a
+  /// terminator), and 'I' must not be the end of instruction list (which would
+  /// cause a degenerate basic block to be formed, having a terminator inside of
+  /// the basic block).
+  ///
+  /// Also note that this doesn't preserve any passes. To split blocks while
+  /// keeping loop information consistent, use the SplitBlock utility function.
+  BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "");
+
+  /// \brief Returns true if there are any uses of this basic block other than
+  /// direct branches, switches, etc. to it.
+  bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
+
+  /// \brief Update all phi nodes in this basic block's successors to refer to
+  /// basic block \p New instead of to it.
+  void replaceSuccessorsPhiUsesWith(BasicBlock *New);
+
+  /// \brief Return true if this basic block is a landing pad.
+  ///
+  /// Being a ``landing pad'' means that the basic block is the destination of
+  /// the 'unwind' edge of an invoke instruction.
+  bool isLandingPad() const;
+
+  /// \brief Return the landingpad instruction associated with the landing pad.
+  LandingPadInst *getLandingPadInst();
+  const LandingPadInst *getLandingPadInst() const;
+
+private:
+  /// \brief Increment the internal refcount of the number of BlockAddresses
+  /// referencing this BasicBlock by \p Amt.
+  ///
+  /// This is almost always 0, sometimes one possibly, but almost never 2, and
+  /// inconceivably 3 or more.
+  void AdjustBlockAddressRefCount(int Amt) {
+    setValueSubclassData(getSubclassDataFromValue()+Amt);
+    assert((int)(signed char)getSubclassDataFromValue() >= 0 &&
+           "Refcount wrap-around");
+  }
+  /// \brief Shadow Value::setValueSubclassData with a private forwarding method
+  /// so that any future subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h
new file mode 100644
index 0000000..c8be8bd
--- /dev/null
+++ b/include/llvm/IR/CFG.h
@@ -0,0 +1,383 @@
+//===- CFG.h - Process LLVM structures as graphs ----------------*- 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 specializations of GraphTraits that allow Function and
+// BasicBlock graphs to be treated as proper graphs for generic algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CFG_H
+#define LLVM_IR_CFG_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// BasicBlock pred_iterator definition
+//===----------------------------------------------------------------------===//
+
+template <class Ptr, class USE_iterator> // Predecessor Iterator
+class PredIterator : public std::iterator<std::forward_iterator_tag,
+                                          Ptr, ptrdiff_t, Ptr*, Ptr*> {
+  typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
+                                                                    Ptr*> super;
+  typedef PredIterator<Ptr, USE_iterator> Self;
+  USE_iterator It;
+
+  inline void advancePastNonTerminators() {
+    // Loop to ignore non-terminator uses (for example BlockAddresses).
+    while (!It.atEnd() && !isa<TerminatorInst>(*It))
+      ++It;
+  }
+
+public:
+  typedef typename super::pointer pointer;
+  typedef typename super::reference reference;
+
+  PredIterator() {}
+  explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
+    advancePastNonTerminators();
+  }
+  inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}
+
+  inline bool operator==(const Self& x) const { return It == x.It; }
+  inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+  inline reference operator*() const {
+    assert(!It.atEnd() && "pred_iterator out of range!");
+    return cast<TerminatorInst>(*It)->getParent();
+  }
+  inline pointer *operator->() const { return &operator*(); }
+
+  inline Self& operator++() {   // Preincrement
+    assert(!It.atEnd() && "pred_iterator out of range!");
+    ++It; advancePastNonTerminators();
+    return *this;
+  }
+
+  inline Self operator++(int) { // Postincrement
+    Self tmp = *this; ++*this; return tmp;
+  }
+
+  /// getOperandNo - Return the operand number in the predecessor's
+  /// terminator of the successor.
+  unsigned getOperandNo() const {
+    return It.getOperandNo();
+  }
+
+  /// getUse - Return the operand Use in the predecessor's terminator
+  /// of the successor.
+  Use &getUse() const {
+    return It.getUse();
+  }
+};
+
+typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
+typedef PredIterator<const BasicBlock,
+                     Value::const_user_iterator> const_pred_iterator;
+
+inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
+inline const_pred_iterator pred_begin(const BasicBlock *BB) {
+  return const_pred_iterator(BB);
+}
+inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
+inline const_pred_iterator pred_end(const BasicBlock *BB) {
+  return const_pred_iterator(BB, true);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// BasicBlock succ_iterator definition
+//===----------------------------------------------------------------------===//
+
+template <class Term_, class BB_>           // Successor Iterator
+class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB_,
+                                          int, BB_ *, BB_ *> {
+  typedef std::iterator<std::random_access_iterator_tag, BB_, int, BB_ *, BB_ *>
+  super;
+
+public:
+  typedef typename super::pointer pointer;
+  typedef typename super::reference reference;
+
+private:
+  const Term_ Term;
+  unsigned idx;
+  typedef SuccIterator<Term_, BB_> Self;
+
+  inline bool index_is_valid(int idx) {
+    return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
+  }
+
+  /// \brief Proxy object to allow write access in operator[]
+  class SuccessorProxy {
+    Self it;
+
+  public:
+    explicit SuccessorProxy(const Self &it) : it(it) {}
+
+    SuccessorProxy &operator=(SuccessorProxy r) {
+      *this = reference(r);
+      return *this;
+    }
+
+    SuccessorProxy &operator=(reference r) {
+      it.Term->setSuccessor(it.idx, r);
+      return *this;
+    }
+
+    operator reference() const { return *it; }
+  };
+
+public:
+  explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
+  }
+  inline SuccIterator(Term_ T, bool)                       // end iterator
+    : Term(T) {
+    if (Term)
+      idx = Term->getNumSuccessors();
+    else
+      // Term == NULL happens, if a basic block is not fully constructed and
+      // consequently getTerminator() returns NULL. In this case we construct a
+      // SuccIterator which describes a basic block that has zero successors.
+      // Defining SuccIterator for incomplete and malformed CFGs is especially
+      // useful for debugging.
+      idx = 0;
+  }
+
+  inline const Self &operator=(const Self &I) {
+    assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
+    idx = I.idx;
+    return *this;
+  }
+
+  /// getSuccessorIndex - This is used to interface between code that wants to
+  /// operate on terminator instructions directly.
+  unsigned getSuccessorIndex() const { return idx; }
+
+  inline bool operator==(const Self& x) const { return idx == x.idx; }
+  inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+  inline reference operator*() const { return Term->getSuccessor(idx); }
+  inline pointer operator->() const { return operator*(); }
+
+  inline Self& operator++() { ++idx; return *this; } // Preincrement
+
+  inline Self operator++(int) { // Postincrement
+    Self tmp = *this; ++*this; return tmp;
+  }
+
+  inline Self& operator--() { --idx; return *this; }  // Predecrement
+  inline Self operator--(int) { // Postdecrement
+    Self tmp = *this; --*this; return tmp;
+  }
+
+  inline bool operator<(const Self& x) const {
+    assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+    return idx < x.idx;
+  }
+
+  inline bool operator<=(const Self& x) const {
+    assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+    return idx <= x.idx;
+  }
+  inline bool operator>=(const Self& x) const {
+    assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+    return idx >= x.idx;
+  }
+
+  inline bool operator>(const Self& x) const {
+    assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+    return idx > x.idx;
+  }
+
+  inline Self& operator+=(int Right) {
+    unsigned new_idx = idx + Right;
+    assert(index_is_valid(new_idx) && "Iterator index out of bound");
+    idx = new_idx;
+    return *this;
+  }
+
+  inline Self operator+(int Right) const {
+    Self tmp = *this;
+    tmp += Right;
+    return tmp;
+  }
+
+  inline Self& operator-=(int Right) {
+    return operator+=(-Right);
+  }
+
+  inline Self operator-(int Right) const {
+    return operator+(-Right);
+  }
+
+  inline int operator-(const Self& x) const {
+    assert(Term == x.Term && "Cannot work on iterators of different blocks!");
+    int distance = idx - x.idx;
+    return distance;
+  }
+
+  inline SuccessorProxy operator[](int offset) {
+   Self tmp = *this;
+   tmp += offset;
+   return SuccessorProxy(tmp);
+  }
+
+  /// Get the source BB of this iterator.
+  inline BB_ *getSource() {
+    assert(Term && "Source not available, if basic block was malformed");
+    return Term->getParent();
+  }
+};
+
+typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
+typedef SuccIterator<const TerminatorInst*,
+                     const BasicBlock> succ_const_iterator;
+
+inline succ_iterator succ_begin(BasicBlock *BB) {
+  return succ_iterator(BB->getTerminator());
+}
+inline succ_const_iterator succ_begin(const BasicBlock *BB) {
+  return succ_const_iterator(BB->getTerminator());
+}
+inline succ_iterator succ_end(BasicBlock *BB) {
+  return succ_iterator(BB->getTerminator(), true);
+}
+inline succ_const_iterator succ_end(const BasicBlock *BB) {
+  return succ_const_iterator(BB->getTerminator(), true);
+}
+
+template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > {
+  static const bool value = isPodLike<T>::value;
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks...
+
+template <> struct GraphTraits<BasicBlock*> {
+  typedef BasicBlock NodeType;
+  typedef succ_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return succ_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return succ_end(N);
+  }
+};
+
+template <> struct GraphTraits<const BasicBlock*> {
+  typedef const BasicBlock NodeType;
+  typedef succ_const_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
+
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return succ_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return succ_end(N);
+  }
+};
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order.  Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<BasicBlock*> > {
+  typedef BasicBlock NodeType;
+  typedef pred_iterator ChildIteratorType;
+  static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return pred_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return pred_end(N);
+  }
+};
+
+template <> struct GraphTraits<Inverse<const BasicBlock*> > {
+  typedef const BasicBlock NodeType;
+  typedef const_pred_iterator ChildIteratorType;
+  static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
+    return G.Graph;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return pred_begin(N);
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return pred_end(N);
+  }
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... these are the same as the basic block iterators,
+// except that the root node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
+  static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
+
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef Function::iterator nodes_iterator;
+  static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
+  static nodes_iterator nodes_end  (Function *F) { return F->end(); }
+  static size_t         size       (Function *F) { return F->size(); }
+};
+template <> struct GraphTraits<const Function*> :
+  public GraphTraits<const BasicBlock*> {
+  static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
+
+  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+  typedef Function::const_iterator nodes_iterator;
+  static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
+  static nodes_iterator nodes_end  (const Function *F) { return F->end(); }
+  static size_t         size       (const Function *F) { return F->size(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order.  Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<Function*> > :
+  public GraphTraits<Inverse<BasicBlock*> > {
+  static NodeType *getEntryNode(Inverse<Function*> G) {
+    return &G.Graph->getEntryBlock();
+  }
+};
+template <> struct GraphTraits<Inverse<const Function*> > :
+  public GraphTraits<Inverse<const BasicBlock*> > {
+  static NodeType *getEntryNode(Inverse<const Function *> G) {
+    return &G.Graph->getEntryBlock();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
new file mode 100644
index 0000000..df08257
--- /dev/null
+++ b/include/llvm/IR/CallSite.h
@@ -0,0 +1,385 @@
+//===- CallSite.h - Abstract Call & Invoke instrs ---------------*- 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 CallSite class, which is a handy wrapper for code that
+// wants to treat Call and Invoke instructions in a generic way. When in non-
+// mutation context (e.g. an analysis) ImmutableCallSite should be used.
+// Finally, when some degree of customization is necessary between these two
+// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
+//
+// NOTE: These classes are supposed to have "value semantics". So they should be
+// passed by value, not by reference; they should not be "new"ed or "delete"d.
+// They are efficiently copyable, assignable and constructable, with cost
+// equivalent to copying a pointer (notice that they have only a single data
+// member). The internal representation carries a flag which indicates which of
+// the two variants is enclosed. This allows for cheaper checks when various
+// accessors of CallSite are employed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CALLSITE_H
+#define LLVM_IR_CALLSITE_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Instructions.h"
+
+namespace llvm {
+
+class CallInst;
+class InvokeInst;
+
+template <typename FunTy = const Function,
+          typename ValTy = const Value,
+          typename UserTy = const User,
+          typename InstrTy = const Instruction,
+          typename CallTy = const CallInst,
+          typename InvokeTy = const InvokeInst,
+          typename IterTy = User::const_op_iterator>
+class CallSiteBase {
+protected:
+  PointerIntPair<InstrTy*, 1, bool> I;
+public:
+  CallSiteBase() : I(nullptr, false) {}
+  CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
+  CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
+  CallSiteBase(ValTy *II) { *this = get(II); }
+protected:
+  /// CallSiteBase::get - This static method is sort of like a constructor.  It
+  /// will create an appropriate call site for a Call or Invoke instruction, but
+  /// it can also create a null initialized CallSiteBase object for something
+  /// which is NOT a call site.
+  ///
+  static CallSiteBase get(ValTy *V) {
+    if (InstrTy *II = dyn_cast<InstrTy>(V)) {
+      if (II->getOpcode() == Instruction::Call)
+        return CallSiteBase(static_cast<CallTy*>(II));
+      else if (II->getOpcode() == Instruction::Invoke)
+        return CallSiteBase(static_cast<InvokeTy*>(II));
+    }
+    return CallSiteBase();
+  }
+public:
+  /// isCall - true if a CallInst is enclosed.
+  /// Note that !isCall() does not mean it is an InvokeInst enclosed,
+  /// it also could signify a NULL Instruction pointer.
+  bool isCall() const { return I.getInt(); }
+
+  /// isInvoke - true if a InvokeInst is enclosed.
+  ///
+  bool isInvoke() const { return getInstruction() && !I.getInt(); }
+
+  InstrTy *getInstruction() const { return I.getPointer(); }
+  InstrTy *operator->() const { return I.getPointer(); }
+  LLVM_EXPLICIT operator bool() const { return I.getPointer(); }
+
+  /// getCalledValue - Return the pointer to function that is being called.
+  ///
+  ValTy *getCalledValue() const {
+    assert(getInstruction() && "Not a call or invoke instruction!");
+    return *getCallee();
+  }
+
+  /// getCalledFunction - Return the function being called if this is a direct
+  /// call, otherwise return null (if it's an indirect call).
+  ///
+  FunTy *getCalledFunction() const {
+    return dyn_cast<FunTy>(getCalledValue());
+  }
+
+  /// setCalledFunction - Set the callee to the specified value.
+  ///
+  void setCalledFunction(Value *V) {
+    assert(getInstruction() && "Not a call or invoke instruction!");
+    *getCallee() = V;
+  }
+
+  /// isCallee - Determine whether the passed iterator points to the
+  /// callee operand's Use.
+  bool isCallee(Value::const_user_iterator UI) const {
+    return isCallee(&UI.getUse());
+  }
+
+  /// Determine whether this Use is the callee operand's Use.
+  bool isCallee(const Use *U) const { return getCallee() == U; }
+
+  ValTy *getArgument(unsigned ArgNo) const {
+    assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+    return *(arg_begin() + ArgNo);
+  }
+
+  void setArgument(unsigned ArgNo, Value* newVal) {
+    assert(getInstruction() && "Not a call or invoke instruction!");
+    assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+    getInstruction()->setOperand(ArgNo, newVal);
+  }
+
+  /// Given a value use iterator, returns the argument that corresponds to it.
+  /// Iterator must actually correspond to an argument.
+  unsigned getArgumentNo(Value::const_user_iterator I) const {
+    return getArgumentNo(&I.getUse());
+  }
+
+  /// Given a use for an argument, get the argument number that corresponds to
+  /// it.
+  unsigned getArgumentNo(const Use *U) const {
+    assert(getInstruction() && "Not a call or invoke instruction!");
+    assert(arg_begin() <= U && U < arg_end()
+           && "Argument # out of range!");
+    return U - arg_begin();
+  }
+
+  /// arg_iterator - The type of iterator to use when looping over actual
+  /// arguments at this call site.
+  typedef IterTy arg_iterator;
+
+  /// arg_begin/arg_end - Return iterators corresponding to the actual argument
+  /// list for a call site.
+  IterTy arg_begin() const {
+    assert(getInstruction() && "Not a call or invoke instruction!");
+    // Skip non-arguments
+    return (*this)->op_begin();
+  }
+
+  IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
+  bool arg_empty() const { return arg_end() == arg_begin(); }
+  unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+  
+  /// getType - Return the type of the instruction that generated this call site
+  ///
+  Type *getType() const { return (*this)->getType(); }
+
+  /// getCaller - Return the caller function for this call site
+  ///
+  FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
+
+  /// \brief Tests if this call site must be tail call optimized.  Only a
+  /// CallInst can be tail call optimized.
+  bool isMustTailCall() const {
+    return isCall() && cast<CallInst>(getInstruction())->isMustTailCall();
+  }
+
+  /// \brief Tests if this call site is marked as a tail call.
+  bool isTailCall() const {
+    return isCall() && cast<CallInst>(getInstruction())->isTailCall();
+  }
+
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+  InstrTy *II = getInstruction();    \
+  return isCall()                        \
+    ? cast<CallInst>(II)->METHOD         \
+    : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+  InstrTy *II = getInstruction();    \
+  if (isCall())                          \
+    cast<CallInst>(II)->METHOD;          \
+  else                                   \
+    cast<InvokeInst>(II)->METHOD
+
+  /// getCallingConv/setCallingConv - get or set the calling convention of the
+  /// call.
+  CallingConv::ID getCallingConv() const {
+    CALLSITE_DELEGATE_GETTER(getCallingConv());
+  }
+  void setCallingConv(CallingConv::ID CC) {
+    CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
+  }
+
+  /// getAttributes/setAttributes - get or set the parameter attributes of
+  /// the call.
+  const AttributeSet &getAttributes() const {
+    CALLSITE_DELEGATE_GETTER(getAttributes());
+  }
+  void setAttributes(const AttributeSet &PAL) {
+    CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
+  }
+
+  /// \brief Return true if this function has the given attribute.
+  bool hasFnAttr(Attribute::AttrKind A) const {
+    CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
+  }
+
+  /// \brief Return true if the call or the callee has the given attribute.
+  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
+    CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
+  }
+
+  /// @brief Extract the alignment for a call or parameter (0=unknown).
+  uint16_t getParamAlignment(uint16_t i) const {
+    CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
+  }
+
+  /// @brief Extract the number of dereferenceable bytes for a call or
+  /// parameter (0=unknown).
+  uint64_t getDereferenceableBytes(uint16_t i) const {
+    CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
+  }
+
+  /// \brief Return true if the call should not be treated as a call to a
+  /// builtin.
+  bool isNoBuiltin() const {
+    CALLSITE_DELEGATE_GETTER(isNoBuiltin());
+  }
+
+  /// @brief Return true if the call should not be inlined.
+  bool isNoInline() const {
+    CALLSITE_DELEGATE_GETTER(isNoInline());
+  }
+  void setIsNoInline(bool Value = true) {
+    CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
+  }
+
+  /// @brief Determine if the call does not access memory.
+  bool doesNotAccessMemory() const {
+    CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
+  }
+  void setDoesNotAccessMemory() {
+    CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
+  }
+
+  /// @brief Determine if the call does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
+  }
+  void setOnlyReadsMemory() {
+    CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
+  }
+
+  /// @brief Determine if the call cannot return.
+  bool doesNotReturn() const {
+    CALLSITE_DELEGATE_GETTER(doesNotReturn());
+  }
+  void setDoesNotReturn() {
+    CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
+  }
+
+  /// @brief Determine if the call cannot unwind.
+  bool doesNotThrow() const {
+    CALLSITE_DELEGATE_GETTER(doesNotThrow());
+  }
+  void setDoesNotThrow() {
+    CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
+  }
+
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
+  /// @brief Determine whether this argument is not captured.
+  bool doesNotCapture(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
+  }
+
+  /// @brief Determine whether this argument is passed by value.
+  bool isByValArgument(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::ByVal);
+  }
+
+  /// @brief Determine whether this argument is passed in an alloca.
+  bool isInAllocaArgument(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+  }
+
+  /// @brief Determine whether this argument is passed by value or in an alloca.
+  bool isByValOrInAllocaArgument(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
+           paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+  }
+
+  /// @brief Determine if there are is an inalloca argument.  Only the last
+  /// argument can have the inalloca attribute.
+  bool hasInAllocaArgument() const {
+    return paramHasAttr(arg_size(), Attribute::InAlloca);
+  }
+
+  bool doesNotAccessMemory(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+  }
+
+  bool onlyReadsMemory(unsigned ArgNo) const {
+    return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) ||
+           paramHasAttr(ArgNo + 1, Attribute::ReadNone);
+  }
+
+  /// @brief Return true if the return value is known to be not null.
+  /// This may be because it has the nonnull attribute, or because at least
+  /// one byte is dereferenceable and the pointer is in addrspace(0).
+  bool isReturnNonNull() const {
+    if (paramHasAttr(0, Attribute::NonNull))
+      return true;
+    else if (getDereferenceableBytes(0) > 0 &&
+             getType()->getPointerAddressSpace() == 0)
+      return true;
+
+    return false;
+  }
+
+  /// hasArgument - Returns true if this CallSite passes the given Value* as an
+  /// argument to the called function.
+  bool hasArgument(const Value *Arg) const {
+    for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
+         ++AI)
+      if (AI->get() == Arg)
+        return true;
+    return false;
+  }
+
+private:
+  unsigned getArgumentEndOffset() const {
+    if (isCall())
+      return 1; // Skip Callee
+    else
+      return 3; // Skip BB, BB, Callee
+  }
+
+  IterTy getCallee() const {
+    if (isCall()) // Skip Callee
+      return cast<CallInst>(getInstruction())->op_end() - 1;
+    else // Skip BB, BB, Callee
+      return cast<InvokeInst>(getInstruction())->op_end() - 3;
+  }
+};
+
+class CallSite : public CallSiteBase<Function, Value, User, Instruction,
+                                     CallInst, InvokeInst, User::op_iterator> {
+  typedef CallSiteBase<Function, Value, User, Instruction,
+                       CallInst, InvokeInst, User::op_iterator> Base;
+public:
+  CallSite() {}
+  CallSite(Base B) : Base(B) {}
+  CallSite(Value* V) : Base(V) {}
+  CallSite(CallInst *CI) : Base(CI) {}
+  CallSite(InvokeInst *II) : Base(II) {}
+  CallSite(Instruction *II) : Base(II) {}
+
+  bool operator==(const CallSite &CS) const { return I == CS.I; }
+  bool operator!=(const CallSite &CS) const { return I != CS.I; }
+  bool operator<(const CallSite &CS) const {
+    return getInstruction() < CS.getInstruction();
+  }
+
+private:
+  User::op_iterator getCallee() const;
+};
+
+/// ImmutableCallSite - establish a view to a call site for examination
+class ImmutableCallSite : public CallSiteBase<> {
+  typedef CallSiteBase<> Base;
+public:
+  ImmutableCallSite(const Value* V) : Base(V) {}
+  ImmutableCallSite(const CallInst *CI) : Base(CI) {}
+  ImmutableCallSite(const InvokeInst *II) : Base(II) {}
+  ImmutableCallSite(const Instruction *II) : Base(II) {}
+  ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h
new file mode 100644
index 0000000..1eaf4f7
--- /dev/null
+++ b/include/llvm/IR/CallingConv.h
@@ -0,0 +1,146 @@
+//===-- llvm/CallingConv.h - LLVM 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 file defines LLVM's set of calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CALLINGCONV_H
+#define LLVM_IR_CALLINGCONV_H
+
+namespace llvm {
+
+/// CallingConv Namespace - This namespace contains an enum with a value for
+/// the well-known calling conventions.
+///
+namespace CallingConv {
+  /// A set of enums which specify the assigned numeric values for known llvm
+  /// calling conventions.
+  /// @brief LLVM Calling Convention Representation
+  enum ID {
+    /// C - The default llvm calling convention, compatible with C.  This
+    /// convention is the only calling convention that supports varargs calls.
+    /// As with typical C calling conventions, the callee/caller have to
+    /// tolerate certain amounts of prototype mismatch.
+    C = 0,
+
+    // Generic LLVM calling conventions.  None of these calling conventions
+    // support varargs calls, and all assume that the caller and callee
+    // prototype exactly match.
+
+    /// Fast - This calling convention attempts to make calls as fast as
+    /// possible (e.g. by passing things in registers).
+    Fast = 8,
+
+    // Cold - This calling convention attempts to make code in the caller as
+    // efficient as possible under the assumption that the call is not commonly
+    // executed.  As such, these calls often preserve all registers so that the
+    // call does not break any live ranges in the caller side.
+    Cold = 9,
+
+    // GHC - Calling convention used by the Glasgow Haskell Compiler (GHC).
+    GHC = 10,
+
+    // HiPE - Calling convention used by the High-Performance Erlang Compiler
+    // (HiPE).
+    HiPE = 11,
+
+    // WebKit JS - Calling convention for stack based JavaScript calls
+    WebKit_JS = 12,
+
+    // AnyReg - Calling convention for dynamic register based calls (e.g.
+    // stackmap and patchpoint intrinsics).
+    AnyReg = 13,
+
+    // PreserveMost - Calling convention for runtime calls that preserves most
+    // registers.
+    PreserveMost = 14,
+
+    // PreserveAll - Calling convention for runtime calls that preserves
+    // (almost) all registers.
+    PreserveAll = 15,
+
+    // Target - This is the start of the target-specific calling conventions,
+    // e.g. fastcall and thiscall on X86.
+    FirstTargetCC = 64,
+
+    /// X86_StdCall - stdcall is the calling conventions mostly used by the
+    /// Win32 API. It is basically the same as the C convention with the
+    /// difference in that the callee is responsible for popping the arguments
+    /// from the stack.
+    X86_StdCall = 64,
+
+    /// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
+    /// in ECX:EDX registers, others - via stack. Callee is responsible for
+    /// stack cleaning.
+    X86_FastCall = 65,
+
+    /// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
+    /// but still used on some targets).
+    ARM_APCS = 66,
+
+    /// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
+    /// convention (aka EABI). Soft float variant.
+    ARM_AAPCS = 67,
+
+    /// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
+    ARM_AAPCS_VFP = 68,
+
+    /// MSP430_INTR - Calling convention used for MSP430 interrupt routines.
+    MSP430_INTR = 69,
+
+    /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
+    /// others via stack. Callee is responsible for stack cleaning. MSVC uses
+    /// this by default for methods in its ABI.
+    X86_ThisCall = 70,
+
+    /// PTX_Kernel - Call to a PTX kernel.
+    /// Passes all arguments in parameter space.
+    PTX_Kernel = 71,
+
+    /// PTX_Device - Call to a PTX device function.
+    /// Passes all arguments in register or parameter space.
+    PTX_Device = 72,
+
+    /// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
+    /// No lowering or expansion of arguments.
+    /// Structures are passed as a pointer to a struct with the byval attribute.
+    /// Functions can only call SPIR_FUNC and SPIR_KERNEL functions.
+    /// Functions can only have zero or one return values.
+    /// Variable arguments are not allowed, except for printf.
+    /// How arguments/return values are lowered are not specified.
+    /// Functions are only visible to the devices.
+    SPIR_FUNC = 75,
+
+    /// SPIR_KERNEL - Calling convention for SPIR kernel functions.
+    /// Inherits the restrictions of SPIR_FUNC, except
+    /// Cannot have non-void return values.
+    /// Cannot have variable arguments.
+    /// Can also be called by the host.
+    /// Is externally visible.
+    SPIR_KERNEL = 76,
+
+    /// Intel_OCL_BI - Calling conventions for Intel OpenCL built-ins
+    Intel_OCL_BI = 77,
+
+    /// \brief The C convention as specified in the x86-64 supplement to the
+    /// System V ABI, used on most non-Windows systems.
+    X86_64_SysV = 78,
+
+    /// \brief The C convention as implemented on Windows/x86-64. This
+    /// convention differs from the more common \c X86_64_SysV convention
+    /// in a number of ways, most notably in that XMM registers used to pass
+    /// arguments are shadowed by GPRs, and vice versa.
+    X86_64_Win64 = 79
+  };
+} // End CallingConv namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h
new file mode 100644
index 0000000..3e77a77
--- /dev/null
+++ b/include/llvm/IR/Comdat.h
@@ -0,0 +1,66 @@
+//===-- llvm/IR/Comdat.h - Comdat definitions -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declaration of the Comdat class, which represents a
+/// single COMDAT in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_COMDAT_H
+#define LLVM_IR_COMDAT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class raw_ostream;
+template <typename ValueTy> class StringMapEntry;
+
+// This is a Name X SelectionKind pair. The reason for having this be an
+// independent object instead of just adding the name and the SelectionKind
+// to a GlobalObject is that it is invalid to have two Comdats with the same
+// name but different SelectionKind. This structure makes that unrepresentable.
+class Comdat {
+public:
+  enum SelectionKind {
+    Any,          ///< The linker may choose any COMDAT.
+    ExactMatch,   ///< The data referenced by the COMDAT must be the same.
+    Largest,      ///< The linker will choose the largest COMDAT.
+    NoDuplicates, ///< No other Module may specify this COMDAT.
+    SameSize,     ///< The data referenced by the COMDAT must be the same size.
+  };
+
+  Comdat(Comdat &&C);
+  SelectionKind getSelectionKind() const { return SK; }
+  void setSelectionKind(SelectionKind Val) { SK = Val; }
+  StringRef getName() const;
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+private:
+  friend class Module;
+  Comdat();
+  Comdat(SelectionKind SK, StringMapEntry<Comdat> *Name);
+  Comdat(const Comdat &) LLVM_DELETED_FUNCTION;
+
+  // Points to the map in Module.
+  StringMapEntry<Comdat> *Name;
+  SelectionKind SK;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Comdat &C) {
+  C.print(OS);
+  return OS;
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h
new file mode 100644
index 0000000..82ad9fc
--- /dev/null
+++ b/include/llvm/IR/Constant.h
@@ -0,0 +1,184 @@
+//===-- llvm/Constant.h - Constant class definition -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Constant class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CONSTANT_H
+#define LLVM_IR_CONSTANT_H
+
+#include "llvm/IR/User.h"
+
+namespace llvm {
+  class APInt;
+
+  template<typename T> class SmallVectorImpl;
+
+/// This is an important base class in LLVM. It provides the common facilities
+/// of all constant values in an LLVM program. A constant is a value that is
+/// immutable at runtime. Functions are constants because their address is
+/// immutable. Same with global variables. 
+/// 
+/// All constants share the capabilities provided in this class. All constants
+/// can have a null value. They can have an operand list. Constants can be
+/// simple (integer and floating point values), complex (arrays and structures),
+/// or expression based (computations yielding a constant value composed of 
+/// only certain operators and other constant values).
+/// 
+/// Note that Constants are immutable (once created they never change) 
+/// and are fully shared by structural equivalence.  This means that two 
+/// structurally equivalent constants will always have the same address.  
+/// Constants are created on demand as needed and never deleted: thus clients 
+/// don't have to worry about the lifetime of the objects.
+/// @brief LLVM Constant Representation
+class Constant : public User {
+  void operator=(const Constant &) LLVM_DELETED_FUNCTION;
+  Constant(const Constant &) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+
+protected:
+  Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
+    : User(ty, vty, Ops, NumOps) {}
+
+  void destroyConstantImpl();
+public:
+  /// isNullValue - Return true if this is the value that would be returned by
+  /// getNullValue.
+  bool isNullValue() const;
+
+  /// isAllOnesValue - Return true if this is the value that would be returned by
+  /// getAllOnesValue.
+  bool isAllOnesValue() const;
+
+  /// isNegativeZeroValue - Return true if the value is what would be returned 
+  /// by getZeroValueForNegation.
+  bool isNegativeZeroValue() const;
+
+  /// Return true if the value is negative zero or null value.
+  bool isZeroValue() const;
+
+  /// \brief Return true if the value is the smallest signed value.
+  bool isMinSignedValue() const;
+
+  /// canTrap - Return true if evaluation of this constant could trap.  This is
+  /// true for things like constant expressions that could divide by zero.
+  bool canTrap() const;
+
+  /// isThreadDependent - Return true if the value can vary between threads.
+  bool isThreadDependent() const;
+
+  /// Return true if the value is dependent on a dllimport variable.
+  bool isDLLImportDependent() const;
+
+  /// isConstantUsed - Return true if the constant has users other than constant
+  /// exprs and other dangling things.
+  bool isConstantUsed() const;
+  
+  enum PossibleRelocationsTy {
+    NoRelocation = 0,
+    LocalRelocation = 1,
+    GlobalRelocations = 2
+  };
+  
+  /// getRelocationInfo - This method classifies the entry according to
+  /// whether or not it may generate a relocation entry.  This must be
+  /// conservative, so if it might codegen to a relocatable entry, it should say
+  /// so.  The return values are:
+  /// 
+  ///  NoRelocation: This constant pool entry is guaranteed to never have a
+  ///     relocation applied to it (because it holds a simple constant like
+  ///     '4').
+  ///  LocalRelocation: This entry has relocations, but the entries are
+  ///     guaranteed to be resolvable by the static linker, so the dynamic
+  ///     linker will never see them.
+  ///  GlobalRelocations: This entry may have arbitrary relocations.
+  ///
+  /// FIXME: This really should not be in VMCore.
+  PossibleRelocationsTy getRelocationInfo() const;
+  
+  /// getAggregateElement - For aggregates (struct/array/vector) return the
+  /// constant that corresponds to the specified element if possible, or null if
+  /// not.  This can return null if the element index is a ConstantExpr, or if
+  /// 'this' is a constant expr.
+  Constant *getAggregateElement(unsigned Elt) const;
+  Constant *getAggregateElement(Constant *Elt) const;
+
+  /// getSplatValue - If this is a splat vector constant, meaning that all of
+  /// the elements have the same value, return that value. Otherwise return 0.
+  Constant *getSplatValue() const;
+
+  /// If C is a constant integer then return its value, otherwise C must be a
+  /// vector of constant integers, all equal, and the common value is returned.
+  const APInt &getUniqueInteger() const;
+
+  /// destroyConstant - Called if some element of this constant is no longer
+  /// valid.  At this point only other constants may be on the use_list for this
+  /// constant.  Any constants on our Use list must also be destroy'd.  The
+  /// implementation must be sure to remove the constant from the list of
+  /// available cached constants.  Implementations should call
+  /// destroyConstantImpl as the last thing they do, to destroy all users and
+  /// delete this.
+  virtual void destroyConstant() { llvm_unreachable("Not reached!"); }
+
+  //// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() >= ConstantFirstVal &&
+           V->getValueID() <= ConstantLastVal;
+  }
+
+  /// replaceUsesOfWithOnConstant - This method is a special form of
+  /// User::replaceUsesOfWith (which does not work on constants) that does work
+  /// on constants.  Basically this method goes through the trouble of building
+  /// a new constant that is equivalent to the current one, with all uses of
+  /// From replaced with uses of To.  After this construction is completed, all
+  /// of the users of 'this' are replaced to use the new constant, and then
+  /// 'this' is deleted.  In general, you should not call this method, instead,
+  /// use Value::replaceAllUsesWith, which automatically dispatches to this
+  /// method as needed.
+  ///
+  virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) {
+    // Provide a default implementation for constants (like integers) that
+    // cannot use any other values.  This cannot be called at runtime, but needs
+    // to be here to avoid link errors.
+    assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be "
+           "implemented for all constants that have operands!");
+    llvm_unreachable("Constants that do not have operands cannot be using "
+                     "'From'!");
+  }
+
+  static Constant *getNullValue(Type* Ty);
+
+  /// @returns the value for an integer or vector of integer constant of the
+  /// given type that has all its bits set to true.
+  /// @brief Get the all ones value
+  static Constant *getAllOnesValue(Type* Ty);
+
+  /// getIntegerValue - Return the value for an integer or pointer constant,
+  /// or a vector thereof, with the given scalar value.
+  static Constant *getIntegerValue(Type* Ty, const APInt &V);
+  
+  /// removeDeadConstantUsers - If there are any dead constant users dangling
+  /// off of this constant, remove them.  This method is useful for clients
+  /// that want to check to see if a global is unused, but don't want to deal
+  /// with potentially dead constants hanging off of the globals.
+  void removeDeadConstantUsers() const;
+
+  Constant *stripPointerCasts() {
+    return cast<Constant>(Value::stripPointerCasts());
+  }
+
+  const Constant *stripPointerCasts() const {
+    return const_cast<Constant*>(this)->stripPointerCasts();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h
new file mode 100644
index 0000000..e271a14
--- /dev/null
+++ b/include/llvm/IR/ConstantFolder.h
@@ -0,0 +1,244 @@
+//===- ConstantFolder.h - Constant folding helper ---------------*- 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 ConstantFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants
+// with minimal folding.  For general constant creation and folding,
+// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CONSTANTFOLDER_H
+#define LLVM_IR_CONSTANTFOLDER_H
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
+
+namespace llvm {
+
+/// ConstantFolder - Create constants with minimum, target independent, folding.
+class ConstantFolder {
+public:
+  explicit ConstantFolder() {}
+
+  //===--------------------------------------------------------------------===//
+  // Binary Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateAdd(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
+  }
+  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFAdd(LHS, RHS);
+  }
+  Constant *CreateSub(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
+  }
+  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFSub(LHS, RHS);
+  }
+  Constant *CreateMul(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
+  }
+  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFMul(LHS, RHS);
+  }
+  Constant *CreateUDiv(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getUDiv(LHS, RHS, isExact);
+  }
+  Constant *CreateSDiv(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getSDiv(LHS, RHS, isExact);
+  }
+  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFDiv(LHS, RHS);
+  }
+  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getURem(LHS, RHS);
+  }
+  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getSRem(LHS, RHS);
+  }
+  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getFRem(LHS, RHS);
+  }
+  Constant *CreateShl(Constant *LHS, Constant *RHS,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
+  }
+  Constant *CreateLShr(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getLShr(LHS, RHS, isExact);
+  }
+  Constant *CreateAShr(Constant *LHS, Constant *RHS,
+                       bool isExact = false) const {
+    return ConstantExpr::getAShr(LHS, RHS, isExact);
+  }
+  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getAnd(LHS, RHS);
+  }
+  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getOr(LHS, RHS);
+  }
+  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::getXor(LHS, RHS);
+  }
+
+  Constant *CreateBinOp(Instruction::BinaryOps Opc,
+                        Constant *LHS, Constant *RHS) const {
+    return ConstantExpr::get(Opc, LHS, RHS);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Unary Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateNeg(Constant *C,
+                      bool HasNUW = false, bool HasNSW = false) const {
+    return ConstantExpr::getNeg(C, HasNUW, HasNSW);
+  }
+  Constant *CreateFNeg(Constant *C) const {
+    return ConstantExpr::getFNeg(C);
+  }
+  Constant *CreateNot(Constant *C) const {
+    return ConstantExpr::getNot(C);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Memory Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateGetElementPtr(Constant *C,
+                                ArrayRef<Constant *> IdxList) const {
+    return ConstantExpr::getGetElementPtr(C, IdxList);
+  }
+  Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return ConstantExpr::getGetElementPtr(C, Idx);
+  }
+  Constant *CreateGetElementPtr(Constant *C,
+                                ArrayRef<Value *> IdxList) const {
+    return ConstantExpr::getGetElementPtr(C, IdxList);
+  }
+
+  Constant *CreateInBoundsGetElementPtr(Constant *C,
+                                        ArrayRef<Constant *> IdxList) const {
+    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+  }
+  Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+  }
+  Constant *CreateInBoundsGetElementPtr(Constant *C,
+                                        ArrayRef<Value *> IdxList) const {
+    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Cast/Conversion Operators
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+                       Type *DestTy) const {
+    return ConstantExpr::getCast(Op, C, DestTy);
+  }
+  Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+    return ConstantExpr::getPointerCast(C, DestTy);
+  }
+
+  Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
+                                                Type *DestTy) const {
+    return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
+  }
+
+  Constant *CreateIntCast(Constant *C, Type *DestTy,
+                          bool isSigned) const {
+    return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
+  }
+  Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+    return ConstantExpr::getFPCast(C, DestTy);
+  }
+
+  Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::BitCast, C, DestTy);
+  }
+  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::IntToPtr, C, DestTy);
+  }
+  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::PtrToInt, C, DestTy);
+  }
+  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+    return ConstantExpr::getZExtOrBitCast(C, DestTy);
+  }
+  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+    return ConstantExpr::getSExtOrBitCast(C, DestTy);
+  }
+
+  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+    return ConstantExpr::getTruncOrBitCast(C, DestTy);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Compare Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return ConstantExpr::getCompare(P, LHS, RHS);
+  }
+  Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+                       Constant *RHS) const {
+    return ConstantExpr::getCompare(P, LHS, RHS);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Other Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+    return ConstantExpr::getSelect(C, True, False);
+  }
+
+  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+    return ConstantExpr::getExtractElement(Vec, Idx);
+  }
+
+  Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+                                Constant *Idx) const {
+    return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
+  }
+
+  Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+                                Constant *Mask) const {
+    return ConstantExpr::getShuffleVector(V1, V2, Mask);
+  }
+
+  Constant *CreateExtractValue(Constant *Agg,
+                               ArrayRef<unsigned> IdxList) const {
+    return ConstantExpr::getExtractValue(Agg, IdxList);
+  }
+
+  Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+                              ArrayRef<unsigned> IdxList) const {
+    return ConstantExpr::getInsertValue(Agg, Val, IdxList);
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h
new file mode 100644
index 0000000..342422c
--- /dev/null
+++ b/include/llvm/IR/ConstantRange.h
@@ -0,0 +1,272 @@
+//===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Represent a range of possible values that may occur when the program is run
+// for an integral value.  This keeps track of a lower and upper bound for the
+// constant, which MAY wrap around the end of the numeric range.  To do this, it
+// keeps track of a [lower, upper) bound, which specifies an interval just like
+// STL iterators.  When used with boolean values, the following are important
+// ranges: :
+//
+//  [F, F) = {}     = Empty set
+//  [T, F) = {T}
+//  [F, T) = {F}
+//  [T, T) = {F, T} = Full set
+//
+// The other integral ranges use min/max values for special range values. For
+// example, for 8-bit types, it uses:
+// [0, 0)     = {}       = Empty set
+// [255, 255) = {0..255} = Full Set
+//
+// Note that ConstantRange can be used to represent either signed or
+// unsigned ranges.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANTRANGE_H
+#define LLVM_SUPPORT_CONSTANTRANGE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// ConstantRange - This class represents an range of values.
+///
+class ConstantRange {
+  APInt Lower, Upper;
+
+  // If we have move semantics, pass APInts by value and move them into place.
+  typedef APInt APIntMoveTy;
+
+public:
+  /// Initialize a full (the default) or empty set for the specified bit width.
+  ///
+  explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
+
+  /// Initialize a range to hold the single specified value.
+  ///
+  ConstantRange(APIntMoveTy Value);
+
+  /// @brief Initialize a range of values explicitly. This will assert out if
+  /// Lower==Upper and Lower != Min or Max value for its type. It will also
+  /// assert out if the two APInt's are not the same bit width.
+  ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
+
+  /// makeICmpRegion - Produce the smallest range that contains all values that
+  /// might satisfy the comparison specified by Pred when compared to any value
+  /// contained within Other.
+  ///
+  /// Solves for range X in 'for all x in X, there exists a y in Y such that
+  /// icmp op x, y is true'. Every value that might make the comparison true
+  /// is included in the resulting range.
+  static ConstantRange makeICmpRegion(unsigned Pred,
+                                      const ConstantRange &Other);
+
+  /// getLower - Return the lower value for this range...
+  ///
+  const APInt &getLower() const { return Lower; }
+
+  /// getUpper - Return the upper value for this range...
+  ///
+  const APInt &getUpper() const { return Upper; }
+
+  /// getBitWidth - get the bit width of this ConstantRange
+  ///
+  uint32_t getBitWidth() const { return Lower.getBitWidth(); }
+
+  /// isFullSet - Return true if this set contains all of the elements possible
+  /// for this data-type
+  ///
+  bool isFullSet() const;
+
+  /// isEmptySet - Return true if this set contains no members.
+  ///
+  bool isEmptySet() const;
+
+  /// isWrappedSet - Return true if this set wraps around the top of the range,
+  /// for example: [100, 8)
+  ///
+  bool isWrappedSet() const;
+
+  /// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
+  /// its bitwidth, for example: i8 [120, 140).
+  ///
+  bool isSignWrappedSet() const;
+
+  /// contains - Return true if the specified value is in the set.
+  ///
+  bool contains(const APInt &Val) const;
+
+  /// contains - Return true if the other range is a subset of this one.
+  ///
+  bool contains(const ConstantRange &CR) const;
+
+  /// getSingleElement - If this set contains a single element, return it,
+  /// otherwise return null.
+  ///
+  const APInt *getSingleElement() const {
+    if (Upper == Lower + 1)
+      return &Lower;
+    return nullptr;
+  }
+
+  /// isSingleElement - Return true if this set contains exactly one member.
+  ///
+  bool isSingleElement() const { return getSingleElement() != nullptr; }
+
+  /// getSetSize - Return the number of elements in this set.
+  ///
+  APInt getSetSize() const;
+
+  /// getUnsignedMax - Return the largest unsigned value contained in the
+  /// ConstantRange.
+  ///
+  APInt getUnsignedMax() const;
+
+  /// getUnsignedMin - Return the smallest unsigned value contained in the
+  /// ConstantRange.
+  ///
+  APInt getUnsignedMin() const;
+
+  /// getSignedMax - Return the largest signed value contained in the
+  /// ConstantRange.
+  ///
+  APInt getSignedMax() const;
+
+  /// getSignedMin - Return the smallest signed value contained in the
+  /// ConstantRange.
+  ///
+  APInt getSignedMin() const;
+
+  /// operator== - Return true if this range is equal to another range.
+  ///
+  bool operator==(const ConstantRange &CR) const {
+    return Lower == CR.Lower && Upper == CR.Upper;
+  }
+  bool operator!=(const ConstantRange &CR) const {
+    return !operator==(CR);
+  }
+
+  /// subtract - Subtract the specified constant from the endpoints of this
+  /// constant range.
+  ConstantRange subtract(const APInt &CI) const;
+
+  /// \brief Subtract the specified range from this range (aka relative
+  /// complement of the sets).
+  ConstantRange difference(const ConstantRange &CR) const;
+
+  /// intersectWith - Return the range that results from the intersection of
+  /// this range with another range.  The resultant range is guaranteed to
+  /// include all elements contained in both input ranges, and to have the
+  /// smallest possible set size that does so.  Because there may be two
+  /// intersections with the same set size, A.intersectWith(B) might not
+  /// be equal to B.intersectWith(A).
+  ///
+  ConstantRange intersectWith(const ConstantRange &CR) const;
+
+  /// unionWith - Return the range that results from the union of this range
+  /// with another range.  The resultant range is guaranteed to include the
+  /// elements of both sets, but may contain more.  For example, [3, 9) union
+  /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
+  /// in either set before.
+  ///
+  ConstantRange unionWith(const ConstantRange &CR) const;
+
+  /// zeroExtend - Return a new range in the specified integer type, which must
+  /// be strictly larger than the current type.  The returned range will
+  /// correspond to the possible range of values if the source range had been
+  /// zero extended to BitWidth.
+  ConstantRange zeroExtend(uint32_t BitWidth) const;
+
+  /// signExtend - Return a new range in the specified integer type, which must
+  /// be strictly larger than the current type.  The returned range will
+  /// correspond to the possible range of values if the source range had been
+  /// sign extended to BitWidth.
+  ConstantRange signExtend(uint32_t BitWidth) const;
+
+  /// truncate - Return a new range in the specified integer type, which must be
+  /// strictly smaller than the current type.  The returned range will
+  /// correspond to the possible range of values if the source range had been
+  /// truncated to the specified type.
+  ConstantRange truncate(uint32_t BitWidth) const;
+
+  /// zextOrTrunc - make this range have the bit width given by \p BitWidth. The
+  /// value is zero extended, truncated, or left alone to make it that width.
+  ConstantRange zextOrTrunc(uint32_t BitWidth) const;
+  
+  /// sextOrTrunc - make this range have the bit width given by \p BitWidth. The
+  /// value is sign extended, truncated, or left alone to make it that width.
+  ConstantRange sextOrTrunc(uint32_t BitWidth) const;
+
+  /// add - Return a new range representing the possible values resulting
+  /// from an addition of a value in this range and a value in \p Other.
+  ConstantRange add(const ConstantRange &Other) const;
+
+  /// sub - Return a new range representing the possible values resulting
+  /// from a subtraction of a value in this range and a value in \p Other.
+  ConstantRange sub(const ConstantRange &Other) const;
+
+  /// multiply - Return a new range representing the possible values resulting
+  /// from a multiplication of a value in this range and a value in \p Other.
+  /// TODO: This isn't fully implemented yet.
+  ConstantRange multiply(const ConstantRange &Other) const;
+
+  /// smax - Return a new range representing the possible values resulting
+  /// from a signed maximum of a value in this range and a value in \p Other.
+  ConstantRange smax(const ConstantRange &Other) const;
+
+  /// umax - Return a new range representing the possible values resulting
+  /// from an unsigned maximum of a value in this range and a value in \p Other.
+  ConstantRange umax(const ConstantRange &Other) const;
+
+  /// udiv - Return a new range representing the possible values resulting
+  /// from an unsigned division of a value in this range and a value in
+  /// \p Other.
+  ConstantRange udiv(const ConstantRange &Other) const;
+
+  /// binaryAnd - return a new range representing the possible values resulting
+  /// from a binary-and of a value in this range by a value in \p Other.
+  ConstantRange binaryAnd(const ConstantRange &Other) const;
+
+  /// binaryOr - return a new range representing the possible values resulting
+  /// from a binary-or of a value in this range by a value in \p Other.
+  ConstantRange binaryOr(const ConstantRange &Other) const;
+
+  /// shl - Return a new range representing the possible values resulting
+  /// from a left shift of a value in this range by a value in \p Other.
+  /// TODO: This isn't fully implemented yet.
+  ConstantRange shl(const ConstantRange &Other) const;
+
+  /// lshr - Return a new range representing the possible values resulting
+  /// from a logical right shift of a value in this range and a value in
+  /// \p Other.
+  ConstantRange lshr(const ConstantRange &Other) const;
+
+  /// inverse - Return a new range that is the logical not of the current set.
+  ///
+  ConstantRange inverse() const;
+  
+  /// print - Print out the bounds to a stream...
+  ///
+  void print(raw_ostream &OS) const;
+
+  /// dump - Allow printing from a debugger easily...
+  ///
+  void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
+  CR.print(OS);
+  return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
new file mode 100644
index 0000000..3cf31c4
--- /dev/null
+++ b/include/llvm/IR/Constants.h
@@ -0,0 +1,1183 @@
+//===-- llvm/Constants.h - Constant class subclass definitions --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declarations for the subclasses of Constant,
+/// which represent the different flavors of constant values that live in LLVM.
+/// Note that Constants are immutable (once created they never change) and are
+/// fully shared by structural equivalence.  This means that two structurally
+/// equivalent constants will always have the same address.  Constant's are
+/// created on demand as needed and never deleted: thus clients don't have to
+/// worry about the lifetime of the objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_CONSTANTS_H
+#define LLVM_IR_CONSTANTS_H
+
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/OperandTraits.h"
+
+namespace llvm {
+
+class ArrayType;
+class IntegerType;
+class StructType;
+class PointerType;
+class VectorType;
+class SequentialType;
+
+template<class ConstantClass, class TypeClass, class ValType>
+struct ConstantCreator;
+template<class ConstantClass, class TypeClass>
+struct ConstantArrayCreator;
+template<class ConstantClass, class TypeClass>
+struct ConvertConstantType;
+
+//===----------------------------------------------------------------------===//
+/// This is the shared class of boolean and integer constants. This class
+/// represents both boolean and integral constants.
+/// @brief Class for constant integers.
+class ConstantInt : public Constant {
+  void anchor() override;
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION;
+  ConstantInt(IntegerType *Ty, const APInt& V);
+  APInt Val;
+protected:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  static ConstantInt *getTrue(LLVMContext &Context);
+  static ConstantInt *getFalse(LLVMContext &Context);
+  static Constant *getTrue(Type *Ty);
+  static Constant *getFalse(Type *Ty);
+
+  /// If Ty is a vector type, return a Constant with a splat of the given
+  /// value. Otherwise return a ConstantInt for the given value.
+  static Constant *get(Type *Ty, uint64_t V, bool isSigned = false);
+
+  /// Return a ConstantInt with the specified integer value for the specified
+  /// type. If the type is wider than 64 bits, the value will be zero-extended
+  /// to fit the type, unless isSigned is true, in which case the value will
+  /// be interpreted as a 64-bit signed integer and sign-extended to fit
+  /// the type.
+  /// @brief Get a ConstantInt for a specific value.
+  static ConstantInt *get(IntegerType *Ty, uint64_t V,
+                          bool isSigned = false);
+
+  /// Return a ConstantInt with the specified value for the specified type. The
+  /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+  /// either getSExtValue() or getZExtValue() will yield a correctly sized and
+  /// signed value for the type Ty.
+  /// @brief Get a ConstantInt for a specific signed value.
+  static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
+  static Constant *getSigned(Type *Ty, int64_t V);
+
+  /// Return a ConstantInt with the specified value and an implied Type. The
+  /// type is the integer type that corresponds to the bit width of the value.
+  static ConstantInt *get(LLVMContext &Context, const APInt &V);
+
+  /// Return a ConstantInt constructed from the string strStart with the given
+  /// radix.
+  static ConstantInt *get(IntegerType *Ty, StringRef Str,
+                          uint8_t radix);
+
+  /// If Ty is a vector type, return a Constant with a splat of the given
+  /// value. Otherwise return a ConstantInt for the given value.
+  static Constant *get(Type* Ty, const APInt& V);
+
+  /// Return the constant as an APInt value reference. This allows clients to
+  /// obtain a copy of the value, with all its precision in tact.
+  /// @brief Return the constant's value.
+  inline const APInt &getValue() const {
+    return Val;
+  }
+
+  /// getBitWidth - Return the bitwidth of this constant.
+  unsigned getBitWidth() const { return Val.getBitWidth(); }
+
+  /// Return the constant as a 64-bit unsigned integer value after it
+  /// has been zero extended as appropriate for the type of this constant. Note
+  /// that this method can assert if the value does not fit in 64 bits.
+  /// @brief Return the zero extended value.
+  inline uint64_t getZExtValue() const {
+    return Val.getZExtValue();
+  }
+
+  /// Return the constant as a 64-bit integer value after it has been sign
+  /// extended as appropriate for the type of this constant. Note that
+  /// this method can assert if the value does not fit in 64 bits.
+  /// @brief Return the sign extended value.
+  inline int64_t getSExtValue() const {
+    return Val.getSExtValue();
+  }
+
+  /// A helper method that can be used to determine if the constant contained
+  /// within is equal to a constant.  This only works for very small values,
+  /// because this is all that can be represented with all types.
+  /// @brief Determine if this constant's value is same as an unsigned char.
+  bool equalsInt(uint64_t V) const {
+    return Val == V;
+  }
+
+  /// getType - Specialize the getType() method to always return an IntegerType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline IntegerType *getType() const {
+    return cast<IntegerType>(Value::getType());
+  }
+
+  /// This static method returns true if the type Ty is big enough to
+  /// represent the value V. This can be used to avoid having the get method
+  /// assert when V is larger than Ty can represent. Note that there are two
+  /// versions of this method, one for unsigned and one for signed integers.
+  /// Although ConstantInt canonicalizes everything to an unsigned integer,
+  /// the signed version avoids callers having to convert a signed quantity
+  /// to the appropriate unsigned type before calling the method.
+  /// @returns true if V is a valid value for type Ty
+  /// @brief Determine if the value is in range for the given type.
+  static bool isValueValidForType(Type *Ty, uint64_t V);
+  static bool isValueValidForType(Type *Ty, int64_t V);
+
+  bool isNegative() const { return Val.isNegative(); }
+
+  /// This is just a convenience method to make client code smaller for a
+  /// common code. It also correctly performs the comparison without the
+  /// potential for an assertion from getZExtValue().
+  bool isZero() const {
+    return Val == 0;
+  }
+
+  /// This is just a convenience method to make client code smaller for a
+  /// common case. It also correctly performs the comparison without the
+  /// potential for an assertion from getZExtValue().
+  /// @brief Determine if the value is one.
+  bool isOne() const {
+    return Val == 1;
+  }
+
+  /// This function will return true iff every bit in this constant is set
+  /// to true.
+  /// @returns true iff this constant's bits are all set to true.
+  /// @brief Determine if the value is all ones.
+  bool isMinusOne() const {
+    return Val.isAllOnesValue();
+  }
+
+  /// This function will return true iff this constant represents the largest
+  /// value that may be represented by the constant's type.
+  /// @returns true iff this is the largest value that may be represented
+  /// by this type.
+  /// @brief Determine if the value is maximal.
+  bool isMaxValue(bool isSigned) const {
+    if (isSigned)
+      return Val.isMaxSignedValue();
+    else
+      return Val.isMaxValue();
+  }
+
+  /// This function will return true iff this constant represents the smallest
+  /// value that may be represented by this constant's type.
+  /// @returns true if this is the smallest value that may be represented by
+  /// this type.
+  /// @brief Determine if the value is minimal.
+  bool isMinValue(bool isSigned) const {
+    if (isSigned)
+      return Val.isMinSignedValue();
+    else
+      return Val.isMinValue();
+  }
+
+  /// This function will return true iff this constant represents a value with
+  /// active bits bigger than 64 bits or a value greater than the given uint64_t
+  /// value.
+  /// @returns true iff this constant is greater or equal to the given number.
+  /// @brief Determine if the value is greater or equal to the given number.
+  bool uge(uint64_t Num) const {
+    return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
+  }
+
+  /// getLimitedValue - If the value is smaller than the specified limit,
+  /// return it, otherwise return the limit value.  This causes the value
+  /// to saturate to the limit.
+  /// @returns the min of the value of the constant and the specified value
+  /// @brief Get the constant's value with a saturation limit
+  uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+    return Val.getLimitedValue(Limit);
+  }
+
+  /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantIntVal;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantFP - Floating Point Values [float, double]
+///
+class ConstantFP : public Constant {
+  APFloat Val;
+  void anchor() override;
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION;
+  friend class LLVMContextImpl;
+protected:
+  ConstantFP(Type *Ty, const APFloat& V);
+protected:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  /// Floating point negation must be implemented with f(x) = -0.0 - x. This
+  /// method returns the negative zero constant for floating point or vector
+  /// floating point types; for all other types, it returns the null value.
+  static Constant *getZeroValueForNegation(Type *Ty);
+
+  /// get() - This returns a ConstantFP, or a vector containing a splat of a
+  /// ConstantFP, for the specified value in the specified type.  This should
+  /// only be used for simple constant values like 2.0/1.0 etc, that are
+  /// known-valid both as host double and as the target format.
+  static Constant *get(Type* Ty, double V);
+  static Constant *get(Type* Ty, StringRef Str);
+  static ConstantFP *get(LLVMContext &Context, const APFloat &V);
+  static Constant *getNegativeZero(Type *Ty);
+  static Constant *getInfinity(Type *Ty, bool Negative = false);
+
+  /// isValueValidForType - return true if Ty is big enough to represent V.
+  static bool isValueValidForType(Type *Ty, const APFloat &V);
+  inline const APFloat &getValueAPF() const { return Val; }
+
+  /// isZero - Return true if the value is positive or negative zero.
+  bool isZero() const { return Val.isZero(); }
+
+  /// isNegative - Return true if the sign bit is set.
+  bool isNegative() const { return Val.isNegative(); }
+
+  /// isNaN - Return true if the value is a NaN.
+  bool isNaN() const { return Val.isNaN(); }
+
+  /// isExactlyValue - We don't rely on operator== working on double values, as
+  /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
+  /// As such, this method can be used to do an exact bit-for-bit comparison of
+  /// two floating point values.  The version with a double operand is retained
+  /// because it's so convenient to write isExactlyValue(2.0), but please use
+  /// it only for simple constants.
+  bool isExactlyValue(const APFloat &V) const;
+
+  bool isExactlyValue(double V) const {
+    bool ignored;
+    APFloat FV(V);
+    FV.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
+    return isExactlyValue(FV);
+  }
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantFPVal;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantAggregateZero - All zero aggregate value
+///
+class ConstantAggregateZero : public Constant {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantAggregateZero(const ConstantAggregateZero &) LLVM_DELETED_FUNCTION;
+protected:
+  explicit ConstantAggregateZero(Type *ty)
+    : Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
+protected:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  static ConstantAggregateZero *get(Type *Ty);
+
+  void destroyConstant() override;
+
+  /// getSequentialElement - If this CAZ has array or vector type, return a zero
+  /// with the right element type.
+  Constant *getSequentialElement() const;
+
+  /// getStructElement - If this CAZ has struct type, return a zero with the
+  /// right element type for the specified element.
+  Constant *getStructElement(unsigned Elt) const;
+
+  /// getElementValue - Return a zero of the right value for the specified GEP
+  /// index.
+  Constant *getElementValue(Constant *C) const;
+
+  /// getElementValue - Return a zero of the right value for the specified GEP
+  /// index.
+  Constant *getElementValue(unsigned Idx) const;
+
+  /// \brief Return the number of elements in the array, vector, or struct.
+  unsigned getNumElements() const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantAggregateZeroVal;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantArray - Constant Array Declarations
+///
+class ConstantArray : public Constant {
+  friend struct ConstantArrayCreator<ConstantArray, ArrayType>;
+  ConstantArray(const ConstantArray &) LLVM_DELETED_FUNCTION;
+protected:
+  ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
+public:
+  // ConstantArray accessors
+  static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+  /// getType - Specialize the getType() method to always return an ArrayType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline ArrayType *getType() const {
+    return cast<ArrayType>(Value::getType());
+  }
+
+  void destroyConstant() override;
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantArrayVal;
+  }
+};
+
+template <>
+struct OperandTraits<ConstantArray> :
+  public VariadicOperandTraits<ConstantArray> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
+
+//===----------------------------------------------------------------------===//
+// ConstantStruct - Constant Struct Declarations
+//
+class ConstantStruct : public Constant {
+  friend struct ConstantArrayCreator<ConstantStruct, StructType>;
+  ConstantStruct(const ConstantStruct &) LLVM_DELETED_FUNCTION;
+protected:
+  ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
+public:
+  // ConstantStruct accessors
+  static Constant *get(StructType *T, ArrayRef<Constant*> V);
+  static Constant *get(StructType *T, ...) END_WITH_NULL;
+
+  /// getAnon - Return an anonymous struct that has the specified
+  /// elements.  If the struct is possibly empty, then you must specify a
+  /// context.
+  static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) {
+    return get(getTypeForElements(V, Packed), V);
+  }
+  static Constant *getAnon(LLVMContext &Ctx,
+                           ArrayRef<Constant*> V, bool Packed = false) {
+    return get(getTypeForElements(Ctx, V, Packed), V);
+  }
+
+  /// getTypeForElements - Return an anonymous struct type to use for a constant
+  /// with the specified set of elements.  The list must not be empty.
+  static StructType *getTypeForElements(ArrayRef<Constant*> V,
+                                        bool Packed = false);
+  /// getTypeForElements - This version of the method allows an empty list.
+  static StructType *getTypeForElements(LLVMContext &Ctx,
+                                        ArrayRef<Constant*> V,
+                                        bool Packed = false);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+  /// getType() specialization - Reduce amount of casting...
+  ///
+  inline StructType *getType() const {
+    return cast<StructType>(Value::getType());
+  }
+
+  void destroyConstant() override;
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantStructVal;
+  }
+};
+
+template <>
+struct OperandTraits<ConstantStruct> :
+  public VariadicOperandTraits<ConstantStruct> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantVector - Constant Vector Declarations
+///
+class ConstantVector : public Constant {
+  friend struct ConstantArrayCreator<ConstantVector, VectorType>;
+  ConstantVector(const ConstantVector &) LLVM_DELETED_FUNCTION;
+protected:
+  ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
+public:
+  // ConstantVector accessors
+  static Constant *get(ArrayRef<Constant*> V);
+
+  /// getSplat - Return a ConstantVector with the specified constant in each
+  /// element.
+  static Constant *getSplat(unsigned NumElts, Constant *Elt);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+  /// getType - Specialize the getType() method to always return a VectorType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline VectorType *getType() const {
+    return cast<VectorType>(Value::getType());
+  }
+
+  /// getSplatValue - If this is a splat constant, meaning that all of the
+  /// elements have the same value, return that value. Otherwise return NULL.
+  Constant *getSplatValue() const;
+
+  void destroyConstant() override;
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantVectorVal;
+  }
+};
+
+template <>
+struct OperandTraits<ConstantVector> :
+  public VariadicOperandTraits<ConstantVector> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
+
+//===----------------------------------------------------------------------===//
+/// ConstantPointerNull - a constant pointer value that points to null
+///
+class ConstantPointerNull : public Constant {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION;
+protected:
+  explicit ConstantPointerNull(PointerType *T)
+    : Constant(T,
+               Value::ConstantPointerNullVal, nullptr, 0) {}
+
+protected:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  /// get() - Static factory methods - Return objects of the specified value
+  static ConstantPointerNull *get(PointerType *T);
+
+  void destroyConstant() override;
+
+  /// getType - Specialize the getType() method to always return an PointerType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline PointerType *getType() const {
+    return cast<PointerType>(Value::getType());
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantPointerNullVal;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantDataSequential - A vector or array constant whose element type is a
+/// simple 1/2/4/8-byte integer or float/double, and whose elements are just
+/// simple data values (i.e. ConstantInt/ConstantFP).  This Constant node has no
+/// operands because it stores all of the elements of the constant as densely
+/// packed data, instead of as Value*'s.
+///
+/// This is the common base class of ConstantDataArray and ConstantDataVector.
+///
+class ConstantDataSequential : public Constant {
+  friend class LLVMContextImpl;
+  /// DataElements - A pointer to the bytes underlying this constant (which is
+  /// owned by the uniquing StringMap).
+  const char *DataElements;
+
+  /// Next - This forms a link list of ConstantDataSequential nodes that have
+  /// the same value but different type.  For example, 0,0,0,1 could be a 4
+  /// element array of i8, or a 1-element array of i32.  They'll both end up in
+  /// the same StringMap bucket, linked up.
+  ConstantDataSequential *Next;
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantDataSequential(const ConstantDataSequential &) LLVM_DELETED_FUNCTION;
+protected:
+  explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
+    : Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
+  ~ConstantDataSequential() { delete Next; }
+
+  static Constant *getImpl(StringRef Bytes, Type *Ty);
+
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+
+  /// isElementTypeCompatible - Return true if a ConstantDataSequential can be
+  /// formed with a vector or array of the specified element type.
+  /// ConstantDataArray only works with normal float and int types that are
+  /// stored densely in memory, not with things like i42 or x86_f80.
+  static bool isElementTypeCompatible(const Type *Ty);
+
+  /// getElementAsInteger - If this is a sequential container of integers (of
+  /// any size), return the specified element in the low bits of a uint64_t.
+  uint64_t getElementAsInteger(unsigned i) const;
+
+  /// getElementAsAPFloat - If this is a sequential container of floating point
+  /// type, return the specified element as an APFloat.
+  APFloat getElementAsAPFloat(unsigned i) const;
+
+  /// getElementAsFloat - If this is an sequential container of floats, return
+  /// the specified element as a float.
+  float getElementAsFloat(unsigned i) const;
+
+  /// getElementAsDouble - If this is an sequential container of doubles, return
+  /// the specified element as a double.
+  double getElementAsDouble(unsigned i) const;
+
+  /// getElementAsConstant - Return a Constant for a specified index's element.
+  /// Note that this has to compute a new constant to return, so it isn't as
+  /// efficient as getElementAsInteger/Float/Double.
+  Constant *getElementAsConstant(unsigned i) const;
+
+  /// getType - Specialize the getType() method to always return a
+  /// SequentialType, which reduces the amount of casting needed in parts of the
+  /// compiler.
+  inline SequentialType *getType() const {
+    return cast<SequentialType>(Value::getType());
+  }
+
+  /// getElementType - Return the element type of the array/vector.
+  Type *getElementType() const;
+
+  /// getNumElements - Return the number of elements in the array or vector.
+  unsigned getNumElements() const;
+
+  /// getElementByteSize - Return the size (in bytes) of each element in the
+  /// array/vector.  The size of the elements is known to be a multiple of one
+  /// byte.
+  uint64_t getElementByteSize() const;
+
+
+  /// isString - This method returns true if this is an array of i8.
+  bool isString() const;
+
+  /// isCString - This method returns true if the array "isString", ends with a
+  /// nul byte, and does not contains any other nul bytes.
+  bool isCString() const;
+
+  /// getAsString - If this array is isString(), then this method returns the
+  /// array as a StringRef.  Otherwise, it asserts out.
+  ///
+  StringRef getAsString() const {
+    assert(isString() && "Not a string");
+    return getRawDataValues();
+  }
+
+  /// getAsCString - If this array is isCString(), then this method returns the
+  /// array (without the trailing null byte) as a StringRef. Otherwise, it
+  /// asserts out.
+  ///
+  StringRef getAsCString() const {
+    assert(isCString() && "Isn't a C string");
+    StringRef Str = getAsString();
+    return Str.substr(0, Str.size()-1);
+  }
+
+  /// getRawDataValues - Return the raw, underlying, bytes of this data.  Note
+  /// that this is an extremely tricky thing to work with, as it exposes the
+  /// host endianness of the data elements.
+  StringRef getRawDataValues() const;
+
+  void destroyConstant() override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataArrayVal ||
+           V->getValueID() == ConstantDataVectorVal;
+  }
+private:
+  const char *getElementPointer(unsigned Elt) const;
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantDataArray - An array constant whose element type is a simple
+/// 1/2/4/8-byte integer or float/double, and whose elements are just simple
+/// data values (i.e. ConstantInt/ConstantFP).  This Constant node has no
+/// operands because it stores all of the elements of the constant as densely
+/// packed data, instead of as Value*'s.
+class ConstantDataArray : public ConstantDataSequential {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+  friend class ConstantDataSequential;
+  explicit ConstantDataArray(Type *ty, const char *Data)
+    : ConstantDataSequential(ty, ConstantDataArrayVal, Data) {}
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+
+  /// get() constructors - Return a constant with array type with an element
+  /// count and element type matching the ArrayRef passed in.  Note that this
+  /// can return a ConstantAggregateZero object.
+  static Constant *get(LLVMContext &Context, ArrayRef<uint8_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+
+  /// getString - This method constructs a CDS and initializes it with a text
+  /// string. The default behavior (AddNull==true) causes a null terminator to
+  /// be placed at the end of the array (increasing the length of the string by
+  /// one more than the StringRef would normally indicate.  Pass AddNull=false
+  /// to disable this behavior.
+  static Constant *getString(LLVMContext &Context, StringRef Initializer,
+                             bool AddNull = true);
+
+  /// getType - Specialize the getType() method to always return an ArrayType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline ArrayType *getType() const {
+    return cast<ArrayType>(Value::getType());
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataArrayVal;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantDataVector - A vector constant whose element type is a simple
+/// 1/2/4/8-byte integer or float/double, and whose elements are just simple
+/// data values (i.e. ConstantInt/ConstantFP).  This Constant node has no
+/// operands because it stores all of the elements of the constant as densely
+/// packed data, instead of as Value*'s.
+class ConstantDataVector : public ConstantDataSequential {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+  friend class ConstantDataSequential;
+  explicit ConstantDataVector(Type *ty, const char *Data)
+  : ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+
+  /// get() constructors - Return a constant with vector type with an element
+  /// count and element type matching the ArrayRef passed in.  Note that this
+  /// can return a ConstantAggregateZero object.
+  static Constant *get(LLVMContext &Context, ArrayRef<uint8_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
+  static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+
+  /// getSplat - Return a ConstantVector with the specified constant in each
+  /// element.  The specified constant has to be a of a compatible type (i8/i16/
+  /// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
+  static Constant *getSplat(unsigned NumElts, Constant *Elt);
+
+  /// getSplatValue - If this is a splat constant, meaning that all of the
+  /// elements have the same value, return that value. Otherwise return NULL.
+  Constant *getSplatValue() const;
+
+  /// getType - Specialize the getType() method to always return a VectorType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline VectorType *getType() const {
+    return cast<VectorType>(Value::getType());
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataVectorVal;
+  }
+};
+
+
+
+/// BlockAddress - The address of a basic block.
+///
+class BlockAddress : public Constant {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void *operator new(size_t s) { return User::operator new(s, 2); }
+  BlockAddress(Function *F, BasicBlock *BB);
+public:
+  /// get - Return a BlockAddress for the specified function and basic block.
+  static BlockAddress *get(Function *F, BasicBlock *BB);
+
+  /// get - Return a BlockAddress for the specified basic block.  The basic
+  /// block must be embedded into a function.
+  static BlockAddress *get(BasicBlock *BB);
+
+  /// \brief Lookup an existing \c BlockAddress constant for the given
+  /// BasicBlock.
+  ///
+  /// \returns 0 if \c !BB->hasAddressTaken(), otherwise the \c BlockAddress.
+  static BlockAddress *lookup(const BasicBlock *BB);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  Function *getFunction() const { return (Function*)Op<0>().get(); }
+  BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); }
+
+  void destroyConstant() override;
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == BlockAddressVal;
+  }
+};
+
+template <>
+struct OperandTraits<BlockAddress> :
+  public FixedNumOperandTraits<BlockAddress, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantExpr - a constant value that is initialized with an expression using
+/// other constant values.
+///
+/// This class uses the standard Instruction opcodes to define the various
+/// constant expressions.  The Opcode field for the ConstantExpr class is
+/// maintained in the Value::SubclassData field.
+class ConstantExpr : public Constant {
+  friend struct ConstantCreator<ConstantExpr,Type,
+                            std::pair<unsigned, std::vector<Constant*> > >;
+  friend struct ConvertConstantType<ConstantExpr, Type>;
+
+protected:
+  ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
+    : Constant(ty, ConstantExprVal, Ops, NumOps) {
+    // Operation type (an Instruction opcode) is stored as the SubclassData.
+    setValueSubclassData(Opcode);
+  }
+
+public:
+  // Static methods to construct a ConstantExpr of different kinds.  Note that
+  // these methods may return a object that is not an instance of the
+  // ConstantExpr class, because they will attempt to fold the constant
+  // expression into something simpler if possible.
+
+  /// getAlignOf constant expr - computes the alignment of a type in a target
+  /// independent way (Note: the return type is an i64).
+  static Constant *getAlignOf(Type *Ty);
+
+  /// getSizeOf constant expr - computes the (alloc) size of a type (in
+  /// address-units, not bits) in a target independent way (Note: the return
+  /// type is an i64).
+  ///
+  static Constant *getSizeOf(Type *Ty);
+
+  /// getOffsetOf constant expr - computes the offset of a struct field in a
+  /// target independent way (Note: the return type is an i64).
+  ///
+  static Constant *getOffsetOf(StructType *STy, unsigned FieldNo);
+
+  /// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
+  /// which supports any aggregate type, and any Constant index.
+  ///
+  static Constant *getOffsetOf(Type *Ty, Constant *FieldNo);
+
+  static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false);
+  static Constant *getFNeg(Constant *C);
+  static Constant *getNot(Constant *C);
+  static Constant *getAdd(Constant *C1, Constant *C2,
+                          bool HasNUW = false, bool HasNSW = false);
+  static Constant *getFAdd(Constant *C1, Constant *C2);
+  static Constant *getSub(Constant *C1, Constant *C2,
+                          bool HasNUW = false, bool HasNSW = false);
+  static Constant *getFSub(Constant *C1, Constant *C2);
+  static Constant *getMul(Constant *C1, Constant *C2,
+                          bool HasNUW = false, bool HasNSW = false);
+  static Constant *getFMul(Constant *C1, Constant *C2);
+  static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
+  static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
+  static Constant *getFDiv(Constant *C1, Constant *C2);
+  static Constant *getURem(Constant *C1, Constant *C2);
+  static Constant *getSRem(Constant *C1, Constant *C2);
+  static Constant *getFRem(Constant *C1, Constant *C2);
+  static Constant *getAnd(Constant *C1, Constant *C2);
+  static Constant *getOr(Constant *C1, Constant *C2);
+  static Constant *getXor(Constant *C1, Constant *C2);
+  static Constant *getShl(Constant *C1, Constant *C2,
+                          bool HasNUW = false, bool HasNSW = false);
+  static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
+  static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
+  static Constant *getTrunc   (Constant *C, Type *Ty);
+  static Constant *getSExt    (Constant *C, Type *Ty);
+  static Constant *getZExt    (Constant *C, Type *Ty);
+  static Constant *getFPTrunc (Constant *C, Type *Ty);
+  static Constant *getFPExtend(Constant *C, Type *Ty);
+  static Constant *getUIToFP  (Constant *C, Type *Ty);
+  static Constant *getSIToFP  (Constant *C, Type *Ty);
+  static Constant *getFPToUI  (Constant *C, Type *Ty);
+  static Constant *getFPToSI  (Constant *C, Type *Ty);
+  static Constant *getPtrToInt(Constant *C, Type *Ty);
+  static Constant *getIntToPtr(Constant *C, Type *Ty);
+  static Constant *getBitCast (Constant *C, Type *Ty);
+  static Constant *getAddrSpaceCast(Constant *C, Type *Ty);
+
+  static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
+  static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
+  static Constant *getNSWAdd(Constant *C1, Constant *C2) {
+    return getAdd(C1, C2, false, true);
+  }
+  static Constant *getNUWAdd(Constant *C1, Constant *C2) {
+    return getAdd(C1, C2, true, false);
+  }
+  static Constant *getNSWSub(Constant *C1, Constant *C2) {
+    return getSub(C1, C2, false, true);
+  }
+  static Constant *getNUWSub(Constant *C1, Constant *C2) {
+    return getSub(C1, C2, true, false);
+  }
+  static Constant *getNSWMul(Constant *C1, Constant *C2) {
+    return getMul(C1, C2, false, true);
+  }
+  static Constant *getNUWMul(Constant *C1, Constant *C2) {
+    return getMul(C1, C2, true, false);
+  }
+  static Constant *getNSWShl(Constant *C1, Constant *C2) {
+    return getShl(C1, C2, false, true);
+  }
+  static Constant *getNUWShl(Constant *C1, Constant *C2) {
+    return getShl(C1, C2, true, false);
+  }
+  static Constant *getExactSDiv(Constant *C1, Constant *C2) {
+    return getSDiv(C1, C2, true);
+  }
+  static Constant *getExactUDiv(Constant *C1, Constant *C2) {
+    return getUDiv(C1, C2, true);
+  }
+  static Constant *getExactAShr(Constant *C1, Constant *C2) {
+    return getAShr(C1, C2, true);
+  }
+  static Constant *getExactLShr(Constant *C1, Constant *C2) {
+    return getLShr(C1, C2, true);
+  }
+
+  /// getBinOpIdentity - Return the identity for the given binary operation,
+  /// i.e. a constant C such that X op C = X and C op X = X for every X.  It
+  /// returns null if the operator doesn't have an identity.
+  static Constant *getBinOpIdentity(unsigned Opcode, Type *Ty);
+
+  /// getBinOpAbsorber - Return the absorbing element for the given binary
+  /// operation, i.e. a constant C such that X op C = C and C op X = C for
+  /// every X.  For example, this returns zero for integer multiplication.
+  /// It returns null if the operator doesn't have an absorbing element.
+  static Constant *getBinOpAbsorber(unsigned Opcode, Type *Ty);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+  // @brief Convenience function for getting one of the casting operations
+  // using a CastOps opcode.
+  static Constant *getCast(
+    unsigned ops,  ///< The opcode for the conversion
+    Constant *C,   ///< The constant to be converted
+    Type *Ty ///< The type to which the constant is converted
+  );
+
+  // @brief Create a ZExt or BitCast cast constant expression
+  static Constant *getZExtOrBitCast(
+    Constant *C,   ///< The constant to zext or bitcast
+    Type *Ty ///< The type to zext or bitcast C to
+  );
+
+  // @brief Create a SExt or BitCast cast constant expression
+  static Constant *getSExtOrBitCast(
+    Constant *C,   ///< The constant to sext or bitcast
+    Type *Ty ///< The type to sext or bitcast C to
+  );
+
+  // @brief Create a Trunc or BitCast cast constant expression
+  static Constant *getTruncOrBitCast(
+    Constant *C,   ///< The constant to trunc or bitcast
+    Type *Ty ///< The type to trunc or bitcast C to
+  );
+
+  /// @brief Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
+  /// expression.
+  static Constant *getPointerCast(
+    Constant *C,   ///< The pointer value to be casted (operand 0)
+    Type *Ty ///< The type to which cast should be made
+  );
+
+  /// @brief Create a BitCast or AddrSpaceCast for a pointer type depending on
+  /// the address space.
+  static Constant *getPointerBitCastOrAddrSpaceCast(
+    Constant *C,   ///< The constant to addrspacecast or bitcast
+    Type *Ty ///< The type to bitcast or addrspacecast C to
+  );
+
+  /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
+  static Constant *getIntegerCast(
+    Constant *C,    ///< The integer constant to be casted
+    Type *Ty, ///< The integer type to cast to
+    bool isSigned   ///< Whether C should be treated as signed or not
+  );
+
+  /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
+  static Constant *getFPCast(
+    Constant *C,    ///< The integer constant to be casted
+    Type *Ty ///< The integer type to cast to
+  );
+
+  /// @brief Return true if this is a convert constant expression
+  bool isCast() const;
+
+  /// @brief Return true if this is a compare constant expression
+  bool isCompare() const;
+
+  /// @brief Return true if this is an insertvalue or extractvalue expression,
+  /// and the getIndices() method may be used.
+  bool hasIndices() const;
+
+  /// @brief Return true if this is a getelementptr expression and all
+  /// the index operands are compile-time known integers within the
+  /// corresponding notional static array extents. Note that this is
+  /// not equivalant to, a subset of, or a superset of the "inbounds"
+  /// property.
+  bool isGEPWithNoNotionalOverIndexing() const;
+
+  /// Select constant expr
+  ///
+  static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
+
+  /// get - Return a binary or shift operator constant expression,
+  /// folding if possible.
+  ///
+  static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
+                       unsigned Flags = 0);
+
+  /// @brief Return an ICmp or FCmp comparison operator constant expression.
+  static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
+
+  /// get* - Return some common constants without having to
+  /// specify the full Instruction::OPCODE identifier.
+  ///
+  static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
+  static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
+
+  /// Getelementptr form.  Value* is only accepted for convenience;
+  /// all elements must be Constant's.
+  ///
+  static Constant *getGetElementPtr(Constant *C,
+                                    ArrayRef<Constant *> IdxList,
+                                    bool InBounds = false) {
+    return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(),
+                                            IdxList.size()),
+                            InBounds);
+  }
+  static Constant *getGetElementPtr(Constant *C,
+                                    Constant *Idx,
+                                    bool InBounds = false) {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return getGetElementPtr(C, cast<Value>(Idx), InBounds);
+  }
+  static Constant *getGetElementPtr(Constant *C,
+                                    ArrayRef<Value *> IdxList,
+                                    bool InBounds = false);
+
+  /// Create an "inbounds" getelementptr. See the documentation for the
+  /// "inbounds" flag in LangRef.html for details.
+  static Constant *getInBoundsGetElementPtr(Constant *C,
+                                            ArrayRef<Constant *> IdxList) {
+    return getGetElementPtr(C, IdxList, true);
+  }
+  static Constant *getInBoundsGetElementPtr(Constant *C,
+                                            Constant *Idx) {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return getGetElementPtr(C, Idx, true);
+  }
+  static Constant *getInBoundsGetElementPtr(Constant *C,
+                                            ArrayRef<Value *> IdxList) {
+    return getGetElementPtr(C, IdxList, true);
+  }
+
+  static Constant *getExtractElement(Constant *Vec, Constant *Idx);
+  static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
+  static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
+  static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
+  static Constant *getInsertValue(Constant *Agg, Constant *Val,
+                                  ArrayRef<unsigned> Idxs);
+
+  /// getOpcode - Return the opcode at the root of this constant expression
+  unsigned getOpcode() const { return getSubclassDataFromValue(); }
+
+  /// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is
+  /// not an ICMP or FCMP constant expression.
+  unsigned getPredicate() const;
+
+  /// getIndices - Assert that this is an insertvalue or exactvalue
+  /// expression and return the list of indices.
+  ArrayRef<unsigned> getIndices() const;
+
+  /// getOpcodeName - Return a string representation for an opcode.
+  const char *getOpcodeName() const;
+
+  /// getWithOperandReplaced - Return a constant expression identical to this
+  /// one, but with the specified operand set to the specified value.
+  Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
+
+  /// getWithOperands - This returns the current constant expression with the
+  /// operands replaced with the specified values.  The specified array must
+  /// have the same number of operands as our current one.
+  Constant *getWithOperands(ArrayRef<Constant*> Ops) const {
+    return getWithOperands(Ops, getType());
+  }
+
+  /// getWithOperands - This returns the current constant expression with the
+  /// operands replaced with the specified values and with the specified result
+  /// type.  The specified array must have the same number of operands as our
+  /// current one.
+  Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
+
+  /// getAsInstruction - Returns an Instruction which implements the same operation
+  /// as this ConstantExpr. The instruction is not linked to any basic block.
+  ///
+  /// A better approach to this could be to have a constructor for Instruction
+  /// which would take a ConstantExpr parameter, but that would have spread
+  /// implementation details of ConstantExpr outside of Constants.cpp, which
+  /// would make it harder to remove ConstantExprs altogether.
+  Instruction *getAsInstruction();
+
+  void destroyConstant() override;
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == ConstantExprVal;
+  }
+
+private:
+  // Shadow Value::setValueSubclassData with a private forwarding method so that
+  // subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<ConstantExpr> :
+  public VariadicOperandTraits<ConstantExpr, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
+
+//===----------------------------------------------------------------------===//
+/// UndefValue - 'undef' values are things that do not have specified contents.
+/// These are used for a variety of purposes, including global variable
+/// initializers and operands to instructions.  'undef' values can occur with
+/// any first-class type.
+///
+/// Undef values aren't exactly constants; if they have multiple uses, they
+/// can appear to have different bit patterns at each use. See
+/// LangRef.html#undefvalues for details.
+///
+class UndefValue : public Constant {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  UndefValue(const UndefValue &) LLVM_DELETED_FUNCTION;
+protected:
+  explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
+protected:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  /// get() - Static factory methods - Return an 'undef' object of the specified
+  /// type.
+  ///
+  static UndefValue *get(Type *T);
+
+  /// getSequentialElement - If this Undef has array or vector type, return a
+  /// undef with the right element type.
+  UndefValue *getSequentialElement() const;
+
+  /// getStructElement - If this undef has struct type, return a undef with the
+  /// right element type for the specified element.
+  UndefValue *getStructElement(unsigned Elt) const;
+
+  /// getElementValue - Return an undef of the right value for the specified GEP
+  /// index.
+  UndefValue *getElementValue(Constant *C) const;
+
+  /// getElementValue - Return an undef of the right value for the specified GEP
+  /// index.
+  UndefValue *getElementValue(unsigned Idx) const;
+
+  /// \brief Return the number of elements in the array, vector, or struct.
+  unsigned getNumElements() const;
+
+  void destroyConstant() override;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == UndefValueVal;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
new file mode 100644
index 0000000..2673504
--- /dev/null
+++ b/include/llvm/IR/DIBuilder.h
@@ -0,0 +1,726 @@
+//===- DIBuilder.h - Debug Information Builder ------------------*- 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 DIBuilder that is useful for creating debugging
+// information entries in LLVM IR form.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DIBUILDER_H
+#define LLVM_IR_DIBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class BasicBlock;
+  class Instruction;
+  class Function;
+  class Module;
+  class Value;
+  class LLVMContext;
+  class MDNode;
+  class StringRef;
+  class DIBasicType;
+  class DICompileUnit;
+  class DICompositeType;
+  class DIDerivedType;
+  class DIDescriptor;
+  class DIFile;
+  class DIEnumerator;
+  class DIType;
+  class DIArray;
+  class DIGlobalVariable;
+  class DIImportedEntity;
+  class DINameSpace;
+  class DIVariable;
+  class DISubrange;
+  class DILexicalBlockFile;
+  class DILexicalBlock;
+  class DIScope;
+  class DISubprogram;
+  class DITemplateTypeParameter;
+  class DITemplateValueParameter;
+  class DIObjCProperty;
+
+  class DIBuilder {
+    private:
+    Module &M;
+    LLVMContext &VMContext;
+
+    MDNode *TempEnumTypes;
+    MDNode *TempRetainTypes;
+    MDNode *TempSubprograms;
+    MDNode *TempGVs;
+    MDNode *TempImportedModules;
+
+    Function *DeclareFn;     // llvm.dbg.declare
+    Function *ValueFn;       // llvm.dbg.value
+
+    SmallVector<Value *, 4> AllEnumTypes;
+    /// Use TrackingVH to collect RetainTypes, since they can be updated
+    /// later on.
+    SmallVector<TrackingVH<MDNode>, 4> AllRetainTypes;
+    SmallVector<Value *, 4> AllSubprograms;
+    SmallVector<Value *, 4> AllGVs;
+    SmallVector<TrackingVH<MDNode>, 4> AllImportedModules;
+
+    // Private use for multiple types of template parameters.
+    DITemplateValueParameter
+    createTemplateValueParameter(unsigned Tag, DIDescriptor Scope,
+                                 StringRef Name, DIType Ty, Value *Val,
+                                 MDNode *File = nullptr, unsigned LineNo = 0,
+                                 unsigned ColumnNo = 0);
+
+    DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;
+    void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;
+
+    public:
+    explicit DIBuilder(Module &M);
+    enum ComplexAddrKind { OpPlus=1, OpDeref };
+    enum DebugEmissionKind { FullDebug=1, LineTablesOnly };
+
+    /// finalize - Construct any deferred debug info descriptors.
+    void finalize();
+
+    /// createCompileUnit - A CompileUnit provides an anchor for all debugging
+    /// information generated during this instance of compilation.
+    /// @param Lang     Source programming language, eg. dwarf::DW_LANG_C99
+    /// @param File     File name
+    /// @param Dir      Directory
+    /// @param Producer Identify the producer of debugging information and code.
+    ///                 Usually this is a compiler version string.
+    /// @param isOptimized A boolean flag which indicates whether optimization
+    ///                    is ON or not.
+    /// @param Flags    This string lists command line options. This string is
+    ///                 directly embedded in debug info output which may be used
+    ///                 by a tool analyzing generated debugging information.
+    /// @param RV       This indicates runtime version for languages like
+    ///                 Objective-C.
+    /// @param SplitName The name of the file that we'll split debug info out
+    ///                  into.
+    /// @param Kind     The kind of debug information to generate.
+    /// @param EmitDebugInfo   A boolean flag which indicates whether debug
+    ///                        information should be written to the final
+    ///                        output or not. When this is false, debug
+    ///                        information annotations will be present in
+    ///                        the IL but they are not written to the final
+    ///                        assembly or object file. This supports tracking
+    ///                        source location information in the back end
+    ///                        without actually changing the output (e.g.,
+    ///                        when using optimization remarks).
+    DICompileUnit createCompileUnit(unsigned Lang, StringRef File,
+                                    StringRef Dir, StringRef Producer,
+                                    bool isOptimized, StringRef Flags,
+                                    unsigned RV,
+                                    StringRef SplitName = StringRef(),
+                                    DebugEmissionKind Kind = FullDebug,
+                                    bool EmitDebugInfo = true);
+
+    /// createFile - Create a file descriptor to hold debugging information
+    /// for a file.
+    DIFile createFile(StringRef Filename, StringRef Directory);
+
+    /// createEnumerator - Create a single enumerator value.
+    DIEnumerator createEnumerator(StringRef Name, int64_t Val);
+
+    /// \brief Create a DWARF unspecified type.
+    DIBasicType createUnspecifiedType(StringRef Name);
+
+    /// \brief Create C++11 nullptr type.
+    DIBasicType createNullPtrType();
+
+    /// createBasicType - Create debugging information entry for a basic
+    /// type.
+    /// @param Name        Type name.
+    /// @param SizeInBits  Size of the type.
+    /// @param AlignInBits Type alignment.
+    /// @param Encoding    DWARF encoding code, e.g. dwarf::DW_ATE_float.
+    DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits,
+                                uint64_t AlignInBits, unsigned Encoding);
+
+    /// createQualifiedType - Create debugging information entry for a qualified
+    /// type, e.g. 'const int'.
+    /// @param Tag         Tag identifing type, e.g. dwarf::TAG_volatile_type
+    /// @param FromTy      Base Type.
+    DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy);
+
+    /// createPointerType - Create debugging information entry for a pointer.
+    /// @param PointeeTy   Type pointed by this pointer.
+    /// @param SizeInBits  Size.
+    /// @param AlignInBits Alignment. (optional)
+    /// @param Name        Pointer type name. (optional)
+    DIDerivedType
+    createPointerType(DIType PointeeTy, uint64_t SizeInBits,
+                      uint64_t AlignInBits = 0, StringRef Name = StringRef());
+
+    /// \brief Create debugging information entry for a pointer to member.
+    /// @param PointeeTy Type pointed to by this pointer.
+    /// @param Class Type for which this pointer points to members of.
+    DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class);
+
+    /// createReferenceType - Create debugging information entry for a c++
+    /// style reference or rvalue reference type.
+    DIDerivedType createReferenceType(unsigned Tag, DIType RTy);
+
+    /// createTypedef - Create debugging information entry for a typedef.
+    /// @param Ty          Original type.
+    /// @param Name        Typedef name.
+    /// @param File        File where this type is defined.
+    /// @param LineNo      Line number.
+    /// @param Context     The surrounding context for the typedef.
+    DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File,
+                                unsigned LineNo, DIDescriptor Context);
+
+    /// createFriend - Create debugging information entry for a 'friend'.
+    DIDerivedType createFriend(DIType Ty, DIType FriendTy);
+
+    /// createInheritance - Create debugging information entry to establish
+    /// inheritance relationship between two types.
+    /// @param Ty           Original type.
+    /// @param BaseTy       Base type. Ty is inherits from base.
+    /// @param BaseOffset   Base offset.
+    /// @param Flags        Flags to describe inheritance attribute,
+    ///                     e.g. private
+    DIDerivedType createInheritance(DIType Ty, DIType BaseTy,
+                                    uint64_t BaseOffset, unsigned Flags);
+
+    /// createMemberType - Create debugging information entry for a member.
+    /// @param Scope        Member scope.
+    /// @param Name         Member name.
+    /// @param File         File where this member is defined.
+    /// @param LineNo       Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param OffsetInBits Member offset.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Ty           Parent type.
+    DIDerivedType
+    createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
+                     unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits,
+                     uint64_t OffsetInBits, unsigned Flags, DIType Ty);
+
+    /// createStaticMemberType - Create debugging information entry for a
+    /// C++ static data member.
+    /// @param Scope      Member scope.
+    /// @param Name       Member name.
+    /// @param File       File where this member is declared.
+    /// @param LineNo     Line number.
+    /// @param Ty         Type of the static member.
+    /// @param Flags      Flags to encode member attribute, e.g. private.
+    /// @param Val        Const initializer of the member.
+    DIDerivedType
+    createStaticMemberType(DIDescriptor Scope, StringRef Name,
+                           DIFile File, unsigned LineNo, DIType Ty,
+                           unsigned Flags, llvm::Value *Val);
+
+    /// createObjCIVar - Create debugging information entry for Objective-C
+    /// instance variable.
+    /// @param Name         Member name.
+    /// @param File         File where this member is defined.
+    /// @param LineNo       Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param OffsetInBits Member offset.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Ty           Parent type.
+    /// @param PropertyName Name of the Objective C property associated with
+    ///                     this ivar.
+    /// @param PropertyGetterName Name of the Objective C property getter
+    ///                           selector.
+    /// @param PropertySetterName Name of the Objective C property setter
+    ///                           selector.
+    /// @param PropertyAttributes Objective C property attributes.
+    DIDerivedType createObjCIVar(StringRef Name, DIFile File,
+                                 unsigned LineNo, uint64_t SizeInBits,
+                                 uint64_t AlignInBits, uint64_t OffsetInBits,
+                                 unsigned Flags, DIType Ty,
+                                 StringRef PropertyName = StringRef(),
+                                 StringRef PropertyGetterName = StringRef(),
+                                 StringRef PropertySetterName = StringRef(),
+                                 unsigned PropertyAttributes = 0);
+
+    /// createObjCIVar - Create debugging information entry for Objective-C
+    /// instance variable.
+    /// @param Name         Member name.
+    /// @param File         File where this member is defined.
+    /// @param LineNo       Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param OffsetInBits Member offset.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Ty           Parent type.
+    /// @param PropertyNode Property associated with this ivar.
+    DIDerivedType createObjCIVar(StringRef Name, DIFile File,
+                                 unsigned LineNo, uint64_t SizeInBits,
+                                 uint64_t AlignInBits, uint64_t OffsetInBits,
+                                 unsigned Flags, DIType Ty,
+                                 MDNode *PropertyNode);
+
+    /// createObjCProperty - Create debugging information entry for Objective-C
+    /// property.
+    /// @param Name         Property name.
+    /// @param File         File where this property is defined.
+    /// @param LineNumber   Line number.
+    /// @param GetterName   Name of the Objective C property getter selector.
+    /// @param SetterName   Name of the Objective C property setter selector.
+    /// @param PropertyAttributes Objective C property attributes.
+    /// @param Ty           Type.
+    DIObjCProperty createObjCProperty(StringRef Name,
+                                      DIFile File, unsigned LineNumber,
+                                      StringRef GetterName,
+                                      StringRef SetterName,
+                                      unsigned PropertyAttributes,
+                                      DIType Ty);
+
+    /// createClassType - Create debugging information entry for a class.
+    /// @param Scope        Scope in which this class is defined.
+    /// @param Name         class name.
+    /// @param File         File where this member is defined.
+    /// @param LineNumber   Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param OffsetInBits Member offset.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Elements     class members.
+    /// @param VTableHolder Debug info of the base class that contains vtable
+    ///                     for this type. This is used in
+    ///                     DW_AT_containing_type. See DWARF documentation
+    ///                     for more info.
+    /// @param TemplateParms Template type parameters.
+    /// @param UniqueIdentifier A unique identifier for the class.
+    DICompositeType createClassType(DIDescriptor Scope, StringRef Name,
+                                    DIFile File, unsigned LineNumber,
+                                    uint64_t SizeInBits, uint64_t AlignInBits,
+                                    uint64_t OffsetInBits, unsigned Flags,
+                                    DIType DerivedFrom, DIArray Elements,
+                                    DIType VTableHolder = DIType(),
+                                    MDNode *TemplateParms = nullptr,
+                                    StringRef UniqueIdentifier = StringRef());
+
+    /// createStructType - Create debugging information entry for a struct.
+    /// @param Scope        Scope in which this struct is defined.
+    /// @param Name         Struct name.
+    /// @param File         File where this member is defined.
+    /// @param LineNumber   Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Elements     Struct elements.
+    /// @param RunTimeLang  Optional parameter, Objective-C runtime version.
+    /// @param UniqueIdentifier A unique identifier for the struct.
+    DICompositeType createStructType(DIDescriptor Scope, StringRef Name,
+                                     DIFile File, unsigned LineNumber,
+                                     uint64_t SizeInBits, uint64_t AlignInBits,
+                                     unsigned Flags, DIType DerivedFrom,
+                                     DIArray Elements, unsigned RunTimeLang = 0,
+                                     DIType VTableHolder = DIType(),
+                                     StringRef UniqueIdentifier = StringRef());
+
+    /// createUnionType - Create debugging information entry for an union.
+    /// @param Scope        Scope in which this union is defined.
+    /// @param Name         Union name.
+    /// @param File         File where this member is defined.
+    /// @param LineNumber   Line number.
+    /// @param SizeInBits   Member size.
+    /// @param AlignInBits  Member alignment.
+    /// @param Flags        Flags to encode member attribute, e.g. private
+    /// @param Elements     Union elements.
+    /// @param RunTimeLang  Optional parameter, Objective-C runtime version.
+    /// @param UniqueIdentifier A unique identifier for the union.
+    DICompositeType createUnionType(
+        DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
+        uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+        DIArray Elements, unsigned RunTimeLang = 0,
+        StringRef UniqueIdentifier = StringRef());
+
+    /// createTemplateTypeParameter - Create debugging information for template
+    /// type parameter.
+    /// @param Scope        Scope in which this type is defined.
+    /// @param Name         Type parameter name.
+    /// @param Ty           Parameter type.
+    /// @param File         File where this type parameter is defined.
+    /// @param LineNo       Line number.
+    /// @param ColumnNo     Column Number.
+    DITemplateTypeParameter
+    createTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
+                                MDNode *File = nullptr, unsigned LineNo = 0,
+                                unsigned ColumnNo = 0);
+
+    /// createTemplateValueParameter - Create debugging information for template
+    /// value parameter.
+    /// @param Scope        Scope in which this type is defined.
+    /// @param Name         Value parameter name.
+    /// @param Ty           Parameter type.
+    /// @param Val          Constant parameter value.
+    /// @param File         File where this type parameter is defined.
+    /// @param LineNo       Line number.
+    /// @param ColumnNo     Column Number.
+    DITemplateValueParameter
+    createTemplateValueParameter(DIDescriptor Scope, StringRef Name,
+                                 DIType Ty, Value *Val, MDNode *File = nullptr,
+                                 unsigned LineNo = 0, unsigned ColumnNo = 0);
+
+    /// \brief Create debugging information for a template template parameter.
+    /// @param Scope        Scope in which this type is defined.
+    /// @param Name         Value parameter name.
+    /// @param Ty           Parameter type.
+    /// @param Val          The fully qualified name of the template.
+    /// @param File         File where this type parameter is defined.
+    /// @param LineNo       Line number.
+    /// @param ColumnNo     Column Number.
+    DITemplateValueParameter
+    createTemplateTemplateParameter(DIDescriptor Scope, StringRef Name,
+                                    DIType Ty, StringRef Val,
+                                    MDNode *File = nullptr, unsigned LineNo = 0,
+                                    unsigned ColumnNo = 0);
+
+    /// \brief Create debugging information for a template parameter pack.
+    /// @param Scope        Scope in which this type is defined.
+    /// @param Name         Value parameter name.
+    /// @param Ty           Parameter type.
+    /// @param Val          An array of types in the pack.
+    /// @param File         File where this type parameter is defined.
+    /// @param LineNo       Line number.
+    /// @param ColumnNo     Column Number.
+    DITemplateValueParameter
+    createTemplateParameterPack(DIDescriptor Scope, StringRef Name,
+                                DIType Ty, DIArray Val, MDNode *File = nullptr,
+                                unsigned LineNo = 0, unsigned ColumnNo = 0);
+
+    /// createArrayType - Create debugging information entry for an array.
+    /// @param Size         Array size.
+    /// @param AlignInBits  Alignment.
+    /// @param Ty           Element type.
+    /// @param Subscripts   Subscripts.
+    DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits,
+                                    DIType Ty, DIArray Subscripts);
+
+    /// createVectorType - Create debugging information entry for a vector type.
+    /// @param Size         Array size.
+    /// @param AlignInBits  Alignment.
+    /// @param Ty           Element type.
+    /// @param Subscripts   Subscripts.
+    DICompositeType createVectorType(uint64_t Size, uint64_t AlignInBits,
+                                     DIType Ty, DIArray Subscripts);
+
+    /// createEnumerationType - Create debugging information entry for an
+    /// enumeration.
+    /// @param Scope          Scope in which this enumeration is defined.
+    /// @param Name           Union name.
+    /// @param File           File where this member is defined.
+    /// @param LineNumber     Line number.
+    /// @param SizeInBits     Member size.
+    /// @param AlignInBits    Member alignment.
+    /// @param Elements       Enumeration elements.
+    /// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
+    /// @param UniqueIdentifier A unique identifier for the enum.
+    DICompositeType createEnumerationType(DIDescriptor Scope, StringRef Name,
+        DIFile File, unsigned LineNumber, uint64_t SizeInBits,
+        uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType,
+        StringRef UniqueIdentifier = StringRef());
+
+    /// createSubroutineType - Create subroutine type.
+    /// @param File            File in which this subroutine is defined.
+    /// @param ParameterTypes  An array of subroutine parameter types. This
+    ///                        includes return type at 0th index.
+    /// @param Flags           E.g.: LValueReference.
+    ///                        These flags are used to emit dwarf attributes.
+    DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes,
+                                         unsigned Flags = 0);
+
+    /// createArtificialType - Create a new DIType with "artificial" flag set.
+    DIType createArtificialType(DIType Ty);
+
+    /// createObjectPointerType - Create a new DIType with the "object pointer"
+    /// flag set.
+    DIType createObjectPointerType(DIType Ty);
+
+    /// \brief Create a permanent forward-declared type.
+    DICompositeType createForwardDecl(unsigned Tag, StringRef Name,
+                                      DIDescriptor Scope, DIFile F,
+                                      unsigned Line, unsigned RuntimeLang = 0,
+                                      uint64_t SizeInBits = 0,
+                                      uint64_t AlignInBits = 0,
+                                      StringRef UniqueIdentifier = StringRef());
+
+    /// \brief Create a temporary forward-declared type.
+    DICompositeType createReplaceableForwardDecl(
+        unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F,
+        unsigned Line, unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
+        uint64_t AlignInBits = 0, StringRef UniqueIdentifier = StringRef());
+
+    /// retainType - Retain DIType in a module even if it is not referenced
+    /// through debug info anchors.
+    void retainType(DIType T);
+
+    /// createUnspecifiedParameter - Create unspecified type descriptor
+    /// for a subroutine type.
+    DIDescriptor createUnspecifiedParameter();
+
+    /// getOrCreateArray - Get a DIArray, create one if required.
+    DIArray getOrCreateArray(ArrayRef<Value *> Elements);
+
+    /// getOrCreateSubrange - Create a descriptor for a value range.  This
+    /// implicitly uniques the values returned.
+    DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count);
+
+    /// createGlobalVariable - Create a new descriptor for the specified global.
+    /// @param Name        Name of the variable.
+    /// @param File        File where this variable is defined.
+    /// @param LineNo      Line number.
+    /// @param Ty          Variable Type.
+    /// @param isLocalToUnit Boolean flag indicate whether this variable is
+    ///                      externally visible or not.
+    /// @param Val         llvm::Value of the variable.
+    DIGlobalVariable
+    createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
+                         DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val);
+
+    /// \brief Create a new descriptor for the specified global.
+    /// @param Name        Name of the variable.
+    /// @param LinkageName Mangled variable name.
+    /// @param File        File where this variable is defined.
+    /// @param LineNo      Line number.
+    /// @param Ty          Variable Type.
+    /// @param isLocalToUnit Boolean flag indicate whether this variable is
+    ///                      externally visible or not.
+    /// @param Val         llvm::Value of the variable.
+    DIGlobalVariable
+    createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File,
+                         unsigned LineNo, DITypeRef Ty, bool isLocalToUnit,
+                         llvm::Value *Val);
+
+    /// createStaticVariable - Create a new descriptor for the specified
+    /// variable.
+    /// @param Context     Variable scope.
+    /// @param Name        Name of the variable.
+    /// @param LinkageName Mangled  name of the variable.
+    /// @param File        File where this variable is defined.
+    /// @param LineNo      Line number.
+    /// @param Ty          Variable Type.
+    /// @param isLocalToUnit Boolean flag indicate whether this variable is
+    ///                      externally visible or not.
+    /// @param Val         llvm::Value of the variable.
+    /// @param Decl        Reference to the corresponding declaration.
+    DIGlobalVariable
+    createStaticVariable(DIDescriptor Context, StringRef Name,
+                         StringRef LinkageName, DIFile File, unsigned LineNo,
+                         DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val,
+                         MDNode *Decl = nullptr);
+
+
+    /// createLocalVariable - Create a new descriptor for the specified
+    /// local variable.
+    /// @param Tag         Dwarf TAG. Usually DW_TAG_auto_variable or
+    ///                    DW_TAG_arg_variable.
+    /// @param Scope       Variable scope.
+    /// @param Name        Variable name.
+    /// @param File        File where this variable is defined.
+    /// @param LineNo      Line number.
+    /// @param Ty          Variable Type
+    /// @param AlwaysPreserve Boolean. Set to true if debug info for this
+    ///                       variable should be preserved in optimized build.
+    /// @param Flags       Flags, e.g. artificial variable.
+    /// @param ArgNo       If this variable is an argument then this argument's
+    ///                    number. 1 indicates 1st argument.
+    DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
+                                   StringRef Name,
+                                   DIFile File, unsigned LineNo,
+                                   DITypeRef Ty, bool AlwaysPreserve = false,
+                                   unsigned Flags = 0,
+                                   unsigned ArgNo = 0);
+
+
+    /// createComplexVariable - Create a new descriptor for the specified
+    /// variable which has a complex address expression for its address.
+    /// @param Tag         Dwarf TAG. Usually DW_TAG_auto_variable or
+    ///                    DW_TAG_arg_variable.
+    /// @param Scope       Variable scope.
+    /// @param Name        Variable name.
+    /// @param F           File where this variable is defined.
+    /// @param LineNo      Line number.
+    /// @param Ty          Variable Type
+    /// @param Addr        An array of complex address operations.
+    /// @param ArgNo       If this variable is an argument then this argument's
+    ///                    number. 1 indicates 1st argument.
+    DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
+                                     StringRef Name, DIFile F, unsigned LineNo,
+                                     DITypeRef Ty, ArrayRef<Value *> Addr,
+                                     unsigned ArgNo = 0);
+
+    /// createFunction - Create a new descriptor for the specified subprogram.
+    /// See comments in DISubprogram for descriptions of these fields.
+    /// @param Scope         Function scope.
+    /// @param Name          Function name.
+    /// @param LinkageName   Mangled function name.
+    /// @param File          File where this variable is defined.
+    /// @param LineNo        Line number.
+    /// @param Ty            Function type.
+    /// @param isLocalToUnit True if this function is not externally visible.
+    /// @param isDefinition  True if this is a function definition.
+    /// @param ScopeLine     Set to the beginning of the scope this starts
+    /// @param Flags         e.g. is this function prototyped or not.
+    ///                      These flags are used to emit dwarf attributes.
+    /// @param isOptimized   True if optimization is ON.
+    /// @param Fn            llvm::Function pointer.
+    /// @param TParam        Function template parameters.
+    DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
+                                StringRef LinkageName,
+                                DIFile File, unsigned LineNo,
+                                DICompositeType Ty, bool isLocalToUnit,
+                                bool isDefinition,
+                                unsigned ScopeLine,
+                                unsigned Flags = 0,
+                                bool isOptimized = false,
+                                Function *Fn = nullptr,
+                                MDNode *TParam = nullptr,
+                                MDNode *Decl = nullptr);
+
+    /// FIXME: this is added for dragonegg. Once we update dragonegg
+    /// to call resolve function, this will be removed.
+    DISubprogram createFunction(DIScopeRef Scope, StringRef Name,
+                                StringRef LinkageName,
+                                DIFile File, unsigned LineNo,
+                                DICompositeType Ty, bool isLocalToUnit,
+                                bool isDefinition,
+                                unsigned ScopeLine,
+                                unsigned Flags = 0,
+                                bool isOptimized = false,
+                                Function *Fn = nullptr,
+                                MDNode *TParam = nullptr,
+                                MDNode *Decl = nullptr);
+
+    /// createMethod - Create a new descriptor for the specified C++ method.
+    /// See comments in DISubprogram for descriptions of these fields.
+    /// @param Scope         Function scope.
+    /// @param Name          Function name.
+    /// @param LinkageName   Mangled function name.
+    /// @param File          File where this variable is defined.
+    /// @param LineNo        Line number.
+    /// @param Ty            Function type.
+    /// @param isLocalToUnit True if this function is not externally visible..
+    /// @param isDefinition  True if this is a function definition.
+    /// @param Virtuality    Attributes describing virtualness. e.g. pure
+    ///                      virtual function.
+    /// @param VTableIndex   Index no of this method in virtual table.
+    /// @param VTableHolder  Type that holds vtable.
+    /// @param Flags         e.g. is this function prototyped or not.
+    ///                      This flags are used to emit dwarf attributes.
+    /// @param isOptimized   True if optimization is ON.
+    /// @param Fn            llvm::Function pointer.
+    /// @param TParam        Function template parameters.
+    DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
+                              StringRef LinkageName,
+                              DIFile File, unsigned LineNo,
+                              DICompositeType Ty, bool isLocalToUnit,
+                              bool isDefinition,
+                              unsigned Virtuality = 0, unsigned VTableIndex = 0,
+                              DIType VTableHolder = DIType(),
+                              unsigned Flags = 0,
+                              bool isOptimized = false,
+                              Function *Fn = nullptr,
+                              MDNode *TParam = nullptr);
+
+    /// createNameSpace - This creates new descriptor for a namespace
+    /// with the specified parent scope.
+    /// @param Scope       Namespace scope
+    /// @param Name        Name of this namespace
+    /// @param File        Source file
+    /// @param LineNo      Line number
+    DINameSpace createNameSpace(DIDescriptor Scope, StringRef Name,
+                                DIFile File, unsigned LineNo);
+
+
+    /// createLexicalBlockFile - This creates a descriptor for a lexical
+    /// block with a new file attached. This merely extends the existing
+    /// lexical block as it crosses a file.
+    /// @param Scope       Lexical block.
+    /// @param File        Source file.
+    DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
+                                              DIFile File);
+
+    /// createLexicalBlock - This creates a descriptor for a lexical block
+    /// with the specified parent context.
+    /// @param Scope         Parent lexical scope.
+    /// @param File          Source file.
+    /// @param Line          Line number.
+    /// @param Col           Column number.
+    /// @param Discriminator DWARF path discriminator value.
+    DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
+                                      unsigned Line, unsigned Col,
+                                      unsigned Discriminator);
+
+    /// \brief Create a descriptor for an imported module.
+    /// @param Context The scope this module is imported into
+    /// @param NS The namespace being imported here
+    /// @param Line Line number
+    DIImportedEntity createImportedModule(DIScope Context, DINameSpace NS,
+                                          unsigned Line);
+
+    /// \brief Create a descriptor for an imported module.
+    /// @param Context The scope this module is imported into
+    /// @param NS An aliased namespace
+    /// @param Line Line number
+    DIImportedEntity createImportedModule(DIScope Context, DIImportedEntity NS,
+                                          unsigned Line);
+
+    /// \brief Create a descriptor for an imported function.
+    /// @param Context The scope this module is imported into
+    /// @param Decl The declaration (or definition) of a function, type, or
+    ///             variable
+    /// @param Line Line number
+    DIImportedEntity createImportedDeclaration(DIScope Context, DIScope Decl,
+                                               unsigned Line,
+                                               StringRef Name = StringRef());
+    DIImportedEntity createImportedDeclaration(DIScope Context,
+                                               DIImportedEntity NS,
+                                               unsigned Line,
+                                               StringRef Name = StringRef());
+
+    /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+    /// @param Storage     llvm::Value of the variable
+    /// @param VarInfo     Variable's debug info descriptor.
+    /// @param InsertAtEnd Location for the new intrinsic.
+    Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+                               BasicBlock *InsertAtEnd);
+
+    /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+    /// @param Storage      llvm::Value of the variable
+    /// @param VarInfo      Variable's debug info descriptor.
+    /// @param InsertBefore Location for the new intrinsic.
+    Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+                               Instruction *InsertBefore);
+
+
+    /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+    /// @param Val          llvm::Value of the variable
+    /// @param Offset       Offset
+    /// @param VarInfo      Variable's debug info descriptor.
+    /// @param InsertAtEnd Location for the new intrinsic.
+    Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+                                         DIVariable VarInfo,
+                                         BasicBlock *InsertAtEnd);
+
+    /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+    /// @param Val          llvm::Value of the variable
+    /// @param Offset       Offset
+    /// @param VarInfo      Variable's debug info descriptor.
+    /// @param InsertBefore Location for the new intrinsic.
+    Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+                                         DIVariable VarInfo,
+                                         Instruction *InsertBefore);
+
+  };
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
new file mode 100644
index 0000000..877029f
--- /dev/null
+++ b/include/llvm/IR/DataLayout.h
@@ -0,0 +1,564 @@
+//===--------- llvm/DataLayout.h - Data size & alignment 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 layout properties related to datatype size/offset/alignment
+// information.  It uses lazy annotations to cache information about how
+// structure types are laid out and used.
+//
+// This structure should be created once, filled in if the defaults are not
+// correct and then passed around by const&.  None of the members functions
+// require modification to the object.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DATALAYOUT_H
+#define LLVM_IR_DATALAYOUT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+
+// this needs to be outside of the namespace, to avoid conflict with llvm-c decl
+typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
+
+namespace llvm {
+
+class Value;
+class Type;
+class IntegerType;
+class StructType;
+class StructLayout;
+class Triple;
+class GlobalVariable;
+class LLVMContext;
+template<typename T>
+class ArrayRef;
+
+/// Enum used to categorize the alignment types stored by LayoutAlignElem
+enum AlignTypeEnum {
+  INVALID_ALIGN = 0,                 ///< An invalid alignment
+  INTEGER_ALIGN = 'i',               ///< Integer type alignment
+  VECTOR_ALIGN = 'v',                ///< Vector type alignment
+  FLOAT_ALIGN = 'f',                 ///< Floating point type alignment
+  AGGREGATE_ALIGN = 'a'              ///< Aggregate alignment
+};
+
+/// Layout alignment element.
+///
+/// Stores the alignment data associated with a given alignment type (integer,
+/// vector, float) and type bit width.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct LayoutAlignElem {
+  unsigned AlignType    : 8;  ///< Alignment type (AlignTypeEnum)
+  unsigned TypeBitWidth : 24; ///< Type bit width
+  unsigned ABIAlign     : 16; ///< ABI alignment for this type/bitw
+  unsigned PrefAlign    : 16; ///< Pref. alignment for this type/bitw
+
+  /// Initializer
+  static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
+                             unsigned pref_align, uint32_t bit_width);
+  /// Equality predicate
+  bool operator==(const LayoutAlignElem &rhs) const;
+};
+
+/// Layout pointer alignment element.
+///
+/// Stores the alignment data associated with a given pointer and address space.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct PointerAlignElem {
+  unsigned            ABIAlign;       ///< ABI alignment for this type/bitw
+  unsigned            PrefAlign;      ///< Pref. alignment for this type/bitw
+  uint32_t            TypeByteWidth;  ///< Type byte width
+  uint32_t            AddressSpace;   ///< Address space for the pointer type
+
+  /// Initializer
+  static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
+                             unsigned PrefAlign, uint32_t TypeByteWidth);
+  /// Equality predicate
+  bool operator==(const PointerAlignElem &rhs) const;
+};
+
+/// This class holds a parsed version of the target data layout string in a
+/// module and provides methods for querying it. The target data layout string
+/// is specified *by the target* - a frontend generating LLVM IR is required to
+/// generate the right target data for the target being codegen'd to.
+class DataLayout {
+private:
+  bool          LittleEndian;          ///< Defaults to false
+  unsigned      StackNaturalAlign;     ///< Stack natural alignment
+
+  enum ManglingModeT {
+    MM_None,
+    MM_ELF,
+    MM_MachO,
+    MM_WINCOFF,
+    MM_Mips
+  };
+  ManglingModeT ManglingMode;
+
+  SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
+
+  /// Alignments - Where the primitive type alignment data is stored.
+  ///
+  /// @sa reset().
+  /// @note Could support multiple size pointer alignments, e.g., 32-bit
+  /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
+  /// we don't.
+  SmallVector<LayoutAlignElem, 16> Alignments;
+  typedef SmallVector<PointerAlignElem, 8> PointersTy;
+  PointersTy Pointers;
+
+  PointersTy::const_iterator
+  findPointerLowerBound(uint32_t AddressSpace) const {
+    return const_cast<DataLayout *>(this)->findPointerLowerBound(AddressSpace);
+  }
+
+  PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace);
+
+  /// InvalidAlignmentElem - This member is a signal that a requested alignment
+  /// type and bit width were not found in the SmallVector.
+  static const LayoutAlignElem InvalidAlignmentElem;
+
+  /// InvalidPointerElem - This member is a signal that a requested pointer
+  /// type and bit width were not found in the DenseSet.
+  static const PointerAlignElem InvalidPointerElem;
+
+  // The StructType -> StructLayout map.
+  mutable void *LayoutMap;
+
+  //! Set/initialize target alignments
+  void setAlignment(AlignTypeEnum align_type, unsigned abi_align,
+                    unsigned pref_align, uint32_t bit_width);
+  unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
+                            bool ABIAlign, Type *Ty) const;
+
+  //! Set/initialize pointer alignments
+  void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
+                           unsigned PrefAlign, uint32_t TypeByteWidth);
+
+  //! Internal helper method that returns requested alignment for type.
+  unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
+
+  /// Valid alignment predicate.
+  ///
+  /// Predicate that tests a LayoutAlignElem reference returned by get() against
+  /// InvalidAlignmentElem.
+  bool validAlignment(const LayoutAlignElem &align) const {
+    return &align != &InvalidAlignmentElem;
+  }
+
+  /// Valid pointer predicate.
+  ///
+  /// Predicate that tests a PointerAlignElem reference returned by get() against
+  /// InvalidPointerElem.
+  bool validPointer(const PointerAlignElem &align) const {
+    return &align != &InvalidPointerElem;
+  }
+
+  /// Parses a target data specification string. Assert if the string is
+  /// malformed.
+  void parseSpecifier(StringRef LayoutDescription);
+
+  // Free all internal data structures.
+  void clear();
+
+public:
+  /// Constructs a DataLayout from a specification string. See reset().
+  explicit DataLayout(StringRef LayoutDescription) : LayoutMap(nullptr) {
+    reset(LayoutDescription);
+  }
+
+  /// Initialize target data from properties stored in the module.
+  explicit DataLayout(const Module *M);
+
+  DataLayout(const DataLayout &DL) : LayoutMap(nullptr) { *this = DL; }
+
+  DataLayout &operator=(const DataLayout &DL) {
+    clear();
+    LittleEndian = DL.isLittleEndian();
+    StackNaturalAlign = DL.StackNaturalAlign;
+    ManglingMode = DL.ManglingMode;
+    LegalIntWidths = DL.LegalIntWidths;
+    Alignments = DL.Alignments;
+    Pointers = DL.Pointers;
+    return *this;
+  }
+
+  bool operator==(const DataLayout &Other) const;
+  bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
+
+  ~DataLayout();  // Not virtual, do not subclass this class
+
+  /// Parse a data layout string (with fallback to default values).
+  void reset(StringRef LayoutDescription);
+
+  /// Layout endianness...
+  bool isLittleEndian() const { return LittleEndian; }
+  bool isBigEndian() const { return !LittleEndian; }
+
+  /// getStringRepresentation - Return the string representation of the
+  /// DataLayout.  This representation is in the same format accepted by the
+  /// string constructor above.
+  std::string getStringRepresentation() const;
+
+  /// isLegalInteger - This function returns true if the specified type is
+  /// known to be a native integer type supported by the CPU.  For example,
+  /// i64 is not native on most 32-bit CPUs and i37 is not native on any known
+  /// one.  This returns false if the integer width is not legal.
+  ///
+  /// The width is specified in bits.
+  ///
+  bool isLegalInteger(unsigned Width) const {
+    for (unsigned LegalIntWidth : LegalIntWidths)
+      if (LegalIntWidth == Width)
+        return true;
+    return false;
+  }
+
+  bool isIllegalInteger(unsigned Width) const {
+    return !isLegalInteger(Width);
+  }
+
+  /// Returns true if the given alignment exceeds the natural stack alignment.
+  bool exceedsNaturalStackAlignment(unsigned Align) const {
+    return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
+  }
+
+  bool hasMicrosoftFastStdCallMangling() const {
+    return ManglingMode == MM_WINCOFF;
+  }
+
+  bool hasLinkerPrivateGlobalPrefix() const {
+    return ManglingMode == MM_MachO;
+  }
+
+  const char *getLinkerPrivateGlobalPrefix() const {
+    if (ManglingMode == MM_MachO)
+      return "l";
+    return getPrivateGlobalPrefix();
+  }
+
+  char getGlobalPrefix() const {
+    switch (ManglingMode) {
+    case MM_None:
+    case MM_ELF:
+    case MM_Mips:
+      return '\0';
+    case MM_MachO:
+    case MM_WINCOFF:
+      return '_';
+    }
+    llvm_unreachable("invalid mangling mode");
+  }
+
+  const char *getPrivateGlobalPrefix() const {
+    switch (ManglingMode) {
+    case MM_None:
+      return "";
+    case MM_ELF:
+      return ".L";
+    case MM_Mips:
+      return "$";
+    case MM_MachO:
+    case MM_WINCOFF:
+      return "L";
+    }
+    llvm_unreachable("invalid mangling mode");
+  }
+
+  static const char *getManglingComponent(const Triple &T);
+
+  /// fitsInLegalInteger - This function returns true if the specified type fits
+  /// in a native integer type supported by the CPU.  For example, if the CPU
+  /// only supports i32 as a native integer type, then i27 fits in a legal
+  /// integer type but i45 does not.
+  bool fitsInLegalInteger(unsigned Width) const {
+    for (unsigned LegalIntWidth : LegalIntWidths)
+      if (Width <= LegalIntWidth)
+        return true;
+    return false;
+  }
+
+  /// Layout pointer alignment
+  /// FIXME: The defaults need to be removed once all of
+  /// the backends/clients are updated.
+  unsigned getPointerABIAlignment(unsigned AS = 0) const;
+
+  /// Return target's alignment for stack-based pointers
+  /// FIXME: The defaults need to be removed once all of
+  /// the backends/clients are updated.
+  unsigned getPointerPrefAlignment(unsigned AS = 0) const;
+
+  /// Layout pointer size
+  /// FIXME: The defaults need to be removed once all of
+  /// the backends/clients are updated.
+  unsigned getPointerSize(unsigned AS = 0) const;
+
+  /// Layout pointer size, in bits
+  /// FIXME: The defaults need to be removed once all of
+  /// the backends/clients are updated.
+  unsigned getPointerSizeInBits(unsigned AS = 0) const {
+    return getPointerSize(AS) * 8;
+  }
+
+  /// Layout pointer size, in bits, based on the type.  If this function is
+  /// called with a pointer type, then the type size of the pointer is returned.
+  /// If this function is called with a vector of pointers, then the type size
+  /// of the pointer is returned.  This should only be called with a pointer or
+  /// vector of pointers.
+  unsigned getPointerTypeSizeInBits(Type *) const;
+
+  unsigned getPointerTypeSize(Type *Ty) const {
+    return getPointerTypeSizeInBits(Ty) / 8;
+  }
+
+  /// Size examples:
+  ///
+  /// Type        SizeInBits  StoreSizeInBits  AllocSizeInBits[*]
+  /// ----        ----------  ---------------  ---------------
+  ///  i1            1           8                8
+  ///  i8            8           8                8
+  ///  i19          19          24               32
+  ///  i32          32          32               32
+  ///  i100        100         104              128
+  ///  i128        128         128              128
+  ///  Float        32          32               32
+  ///  Double       64          64               64
+  ///  X86_FP80     80          80               96
+  ///
+  /// [*] The alloc size depends on the alignment, and thus on the target.
+  ///     These values are for x86-32 linux.
+
+  /// getTypeSizeInBits - Return the number of bits necessary to hold the
+  /// specified type.  For example, returns 36 for i36 and 80 for x86_fp80.
+  /// The type passed must have a size (Type::isSized() must return true).
+  uint64_t getTypeSizeInBits(Type *Ty) const;
+
+  /// getTypeStoreSize - Return the maximum number of bytes that may be
+  /// overwritten by storing the specified type.  For example, returns 5
+  /// for i36 and 10 for x86_fp80.
+  uint64_t getTypeStoreSize(Type *Ty) const {
+    return (getTypeSizeInBits(Ty)+7)/8;
+  }
+
+  /// getTypeStoreSizeInBits - Return the maximum number of bits that may be
+  /// overwritten by storing the specified type; always a multiple of 8.  For
+  /// example, returns 40 for i36 and 80 for x86_fp80.
+  uint64_t getTypeStoreSizeInBits(Type *Ty) const {
+    return 8*getTypeStoreSize(Ty);
+  }
+
+  /// getTypeAllocSize - Return the offset in bytes between successive objects
+  /// of the specified type, including alignment padding.  This is the amount
+  /// that alloca reserves for this type.  For example, returns 12 or 16 for
+  /// x86_fp80, depending on alignment.
+  uint64_t getTypeAllocSize(Type *Ty) const {
+    // Round up to the next alignment boundary.
+    return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty));
+  }
+
+  /// getTypeAllocSizeInBits - Return the offset in bits between successive
+  /// objects of the specified type, including alignment padding; always a
+  /// multiple of 8.  This is the amount that alloca reserves for this type.
+  /// For example, returns 96 or 128 for x86_fp80, depending on alignment.
+  uint64_t getTypeAllocSizeInBits(Type *Ty) const {
+    return 8*getTypeAllocSize(Ty);
+  }
+
+  /// getABITypeAlignment - Return the minimum ABI-required alignment for the
+  /// specified type.
+  unsigned getABITypeAlignment(Type *Ty) const;
+
+  /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
+  /// an integer type of the specified bitwidth.
+  unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
+
+  /// getPrefTypeAlignment - Return the preferred stack/global alignment for
+  /// the specified type.  This is always at least as good as the ABI alignment.
+  unsigned getPrefTypeAlignment(Type *Ty) const;
+
+  /// getPreferredTypeAlignmentShift - Return the preferred alignment for the
+  /// specified type, returned as log2 of the value (a shift amount).
+  unsigned getPreferredTypeAlignmentShift(Type *Ty) const;
+
+  /// getIntPtrType - Return an integer type with size at least as big as that
+  /// of a pointer in the given address space.
+  IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
+
+  /// getIntPtrType - Return an integer (vector of integer) type with size at
+  /// least as big as that of a pointer of the given pointer (vector of pointer)
+  /// type.
+  Type *getIntPtrType(Type *) const;
+
+  /// getSmallestLegalIntType - Return the smallest integer type with size at
+  /// least as big as Width bits.
+  Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const;
+
+  /// getLargestLegalIntType - Return the largest legal integer type, or null if
+  /// none are set.
+  Type *getLargestLegalIntType(LLVMContext &C) const {
+    unsigned LargestSize = getLargestLegalIntTypeSize();
+    return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize);
+  }
+
+  /// getLargestLegalIntTypeSize - Return the size of largest legal integer
+  /// type size, or 0 if none are set.
+  unsigned getLargestLegalIntTypeSize() const;
+
+  /// getIndexedOffset - return the offset from the beginning of the type for
+  /// the specified indices.  This is used to implement getelementptr.
+  uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const;
+
+  /// getStructLayout - Return a StructLayout object, indicating the alignment
+  /// of the struct, its size, and the offsets of its fields.  Note that this
+  /// information is lazily cached.
+  const StructLayout *getStructLayout(StructType *Ty) const;
+
+  /// getPreferredAlignment - Return the preferred alignment of the specified
+  /// global.  This includes an explicitly requested alignment (if the global
+  /// has one).
+  unsigned getPreferredAlignment(const GlobalVariable *GV) const;
+
+  /// getPreferredAlignmentLog - Return the preferred alignment of the
+  /// specified global, returned in log form.  This includes an explicitly
+  /// requested alignment (if the global has one).
+  unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const;
+
+  /// RoundUpAlignment - Round the specified value up to the next alignment
+  /// boundary specified by Alignment.  For example, 7 rounded up to an
+  /// alignment boundary of 4 is 8.  8 rounded up to the alignment boundary of 4
+  /// is 8 because it is already aligned.
+  template <typename UIntTy>
+  static UIntTy RoundUpAlignment(UIntTy Val, unsigned Alignment) {
+    assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!");
+    return (Val + (Alignment-1)) & ~UIntTy(Alignment-1);
+  }
+};
+
+inline DataLayout *unwrap(LLVMTargetDataRef P) {
+   return reinterpret_cast<DataLayout*>(P);
+}
+
+inline LLVMTargetDataRef wrap(const DataLayout *P) {
+   return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
+}
+
+class DataLayoutPass : public ImmutablePass {
+  DataLayout DL;
+
+public:
+  /// This has to exist, because this is a pass, but it should never be used.
+  DataLayoutPass();
+  ~DataLayoutPass();
+
+  const DataLayout &getDataLayout() const { return DL; }
+
+  // For use with the C API. C++ code should always use the constructor that
+  // takes a module.
+  explicit DataLayoutPass(const DataLayout &DL);
+
+  explicit DataLayoutPass(const Module *M);
+
+  static char ID; // Pass identification, replacement for typeid
+};
+
+/// StructLayout - used to lazily calculate structure layout information for a
+/// target machine, based on the DataLayout structure.
+///
+class StructLayout {
+  uint64_t StructSize;
+  unsigned StructAlignment;
+  unsigned NumElements;
+  uint64_t MemberOffsets[1];  // variable sized array!
+public:
+
+  uint64_t getSizeInBytes() const {
+    return StructSize;
+  }
+
+  uint64_t getSizeInBits() const {
+    return 8*StructSize;
+  }
+
+  unsigned getAlignment() const {
+    return StructAlignment;
+  }
+
+  /// getElementContainingOffset - Given a valid byte offset into the structure,
+  /// return the structure index that contains it.
+  ///
+  unsigned getElementContainingOffset(uint64_t Offset) const;
+
+  uint64_t getElementOffset(unsigned Idx) const {
+    assert(Idx < NumElements && "Invalid element idx!");
+    return MemberOffsets[Idx];
+  }
+
+  uint64_t getElementOffsetInBits(unsigned Idx) const {
+    return getElementOffset(Idx)*8;
+  }
+
+private:
+  friend class DataLayout;   // Only DataLayout can create this class
+  StructLayout(StructType *ST, const DataLayout &DL);
+};
+
+
+// The implementation of this method is provided inline as it is particularly
+// well suited to constant folding when called on a specific Type subclass.
+inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
+  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
+  switch (Ty->getTypeID()) {
+  case Type::LabelTyID:
+    return getPointerSizeInBits(0);
+  case Type::PointerTyID:
+    return getPointerSizeInBits(Ty->getPointerAddressSpace());
+  case Type::ArrayTyID: {
+    ArrayType *ATy = cast<ArrayType>(Ty);
+    return ATy->getNumElements() *
+           getTypeAllocSizeInBits(ATy->getElementType());
+  }
+  case Type::StructTyID:
+    // Get the layout annotation... which is lazily created on demand.
+    return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
+  case Type::IntegerTyID:
+    return Ty->getIntegerBitWidth();
+  case Type::HalfTyID:
+    return 16;
+  case Type::FloatTyID:
+    return 32;
+  case Type::DoubleTyID:
+  case Type::X86_MMXTyID:
+    return 64;
+  case Type::PPC_FP128TyID:
+  case Type::FP128TyID:
+    return 128;
+    // In memory objects this is always aligned to a higher boundary, but
+  // only 80 bits contain information.
+  case Type::X86_FP80TyID:
+    return 80;
+  case Type::VectorTyID: {
+    VectorType *VTy = cast<VectorType>(Ty);
+    return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType());
+  }
+  default:
+    llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
+  }
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h
new file mode 100644
index 0000000..088eb9f
--- /dev/null
+++ b/include/llvm/IR/DebugInfo.h
@@ -0,0 +1,942 @@
+//===- DebugInfo.h - Debug Information Helpers ------------------*- 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 bunch of datatypes that are useful for creating and
+// walking debug info in LLVM IR form. They essentially provide wrappers around
+// the information in the global variables that's needed when constructing the
+// DWARF information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DEBUGINFO_H
+#define LLVM_IR_DEBUGINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Dwarf.h"
+
+namespace llvm {
+class BasicBlock;
+class Constant;
+class Function;
+class GlobalVariable;
+class Module;
+class Type;
+class Value;
+class DbgDeclareInst;
+class DbgValueInst;
+class Instruction;
+class MDNode;
+class MDString;
+class NamedMDNode;
+class LLVMContext;
+class raw_ostream;
+
+class DIFile;
+class DISubprogram;
+class DILexicalBlock;
+class DILexicalBlockFile;
+class DIVariable;
+class DIType;
+class DIScope;
+class DIObjCProperty;
+
+/// Maps from type identifier to the actual MDNode.
+typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
+
+/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
+/// This should not be stored in a container, because the underlying MDNode
+/// may change in certain situations.
+class DIDescriptor {
+  // Befriends DIRef so DIRef can befriend the protected member
+  // function: getFieldAs<DIRef>.
+  template <typename T> friend class DIRef;
+
+public:
+  enum {
+    FlagPrivate           = 1 << 0,
+    FlagProtected         = 1 << 1,
+    FlagFwdDecl           = 1 << 2,
+    FlagAppleBlock        = 1 << 3,
+    FlagBlockByrefStruct  = 1 << 4,
+    FlagVirtual           = 1 << 5,
+    FlagArtificial        = 1 << 6,
+    FlagExplicit          = 1 << 7,
+    FlagPrototyped        = 1 << 8,
+    FlagObjcClassComplete = 1 << 9,
+    FlagObjectPointer     = 1 << 10,
+    FlagVector            = 1 << 11,
+    FlagStaticMember      = 1 << 12,
+    FlagIndirectVariable  = 1 << 13,
+    FlagLValueReference   = 1 << 14,
+    FlagRValueReference   = 1 << 15
+  };
+
+protected:
+  const MDNode *DbgNode;
+
+  StringRef getStringField(unsigned Elt) const;
+  unsigned getUnsignedField(unsigned Elt) const {
+    return (unsigned)getUInt64Field(Elt);
+  }
+  uint64_t getUInt64Field(unsigned Elt) const;
+  int64_t getInt64Field(unsigned Elt) const;
+  DIDescriptor getDescriptorField(unsigned Elt) const;
+
+  template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
+    return DescTy(getDescriptorField(Elt));
+  }
+
+  GlobalVariable *getGlobalVariableField(unsigned Elt) const;
+  Constant *getConstantField(unsigned Elt) const;
+  Function *getFunctionField(unsigned Elt) const;
+  void replaceFunctionField(unsigned Elt, Function *F);
+
+public:
+  explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {}
+
+  bool Verify() const;
+
+  operator MDNode *() const { return const_cast<MDNode *>(DbgNode); }
+  MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); }
+
+  // An explicit operator bool so that we can do testing of DI values
+  // easily.
+  // FIXME: This operator bool isn't actually protecting anything at the
+  // moment due to the conversion operator above making DIDescriptor nodes
+  // implicitly convertable to bool.
+  LLVM_EXPLICIT operator bool() const { return DbgNode != nullptr; }
+
+  bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; }
+  bool operator!=(DIDescriptor Other) const { return !operator==(Other); }
+
+  uint16_t getTag() const {
+    return getUnsignedField(0) & ~LLVMDebugVersionMask;
+  }
+
+  bool isDerivedType() const;
+  bool isCompositeType() const;
+  bool isBasicType() const;
+  bool isVariable() const;
+  bool isSubprogram() const;
+  bool isGlobalVariable() const;
+  bool isScope() const;
+  bool isFile() const;
+  bool isCompileUnit() const;
+  bool isNameSpace() const;
+  bool isLexicalBlockFile() const;
+  bool isLexicalBlock() const;
+  bool isSubrange() const;
+  bool isEnumerator() const;
+  bool isType() const;
+  bool isUnspecifiedParameter() const;
+  bool isTemplateTypeParameter() const;
+  bool isTemplateValueParameter() const;
+  bool isObjCProperty() const;
+  bool isImportedEntity() const;
+
+  /// print - print descriptor.
+  void print(raw_ostream &OS) const;
+
+  /// dump - print descriptor to dbgs() with a newline.
+  void dump() const;
+};
+
+/// DISubrange - This is used to represent ranges, for array bounds.
+class DISubrange : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  int64_t getLo() const { return getInt64Field(1); }
+  int64_t getCount() const { return getInt64Field(2); }
+  bool Verify() const;
+};
+
+/// DIArray - This descriptor holds an array of descriptors.
+class DIArray : public DIDescriptor {
+public:
+  explicit DIArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  unsigned getNumElements() const;
+  DIDescriptor getElement(unsigned Idx) const {
+    return getDescriptorField(Idx);
+  }
+};
+
+/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
+/// FIXME: it seems strange that this doesn't have either a reference to the
+/// type/precision or a file/line pair for location info.
+class DIEnumerator : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  StringRef getName() const { return getStringField(1); }
+  int64_t getEnumValue() const { return getInt64Field(2); }
+  bool Verify() const;
+};
+
+template <typename T> class DIRef;
+typedef DIRef<DIScope> DIScopeRef;
+typedef DIRef<DIType> DITypeRef;
+
+/// DIScope - A base class for various scopes.
+///
+/// Although, implementation-wise, DIScope is the parent class of most
+/// other DIxxx classes, including DIType and its descendants, most of
+/// DIScope's descendants are not a substitutable subtype of
+/// DIScope. The DIDescriptor::isScope() method only is true for
+/// DIScopes that are scopes in the strict lexical scope sense
+/// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType.
+class DIScope : public DIDescriptor {
+protected:
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  /// Gets the parent scope for this scope node or returns a
+  /// default constructed scope.
+  DIScopeRef getContext() const;
+  /// If the scope node has a name, return that, else return an empty string.
+  StringRef getName() const;
+  StringRef getFilename() const;
+  StringRef getDirectory() const;
+
+  /// Generate a reference to this DIScope. Uses the type identifier instead
+  /// of the actual MDNode if possible, to help type uniquing.
+  DIScopeRef getRef() const;
+};
+
+/// Represents reference to a DIDescriptor, abstracts over direct and
+/// identifier-based metadata references.
+template <typename T> class DIRef {
+  template <typename DescTy>
+  friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
+  friend DIScopeRef DIScope::getContext() const;
+  friend DIScopeRef DIScope::getRef() const;
+  friend class DIType;
+
+  /// Val can be either a MDNode or a MDString, in the latter,
+  /// MDString specifies the type identifier.
+  const Value *Val;
+  explicit DIRef(const Value *V);
+
+public:
+  T resolve(const DITypeIdentifierMap &Map) const;
+  StringRef getName() const;
+  operator Value *() const { return const_cast<Value *>(Val); }
+};
+
+template <typename T>
+T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
+  if (!Val)
+    return T();
+
+  if (const MDNode *MD = dyn_cast<MDNode>(Val))
+    return T(MD);
+
+  const MDString *MS = cast<MDString>(Val);
+  // Find the corresponding MDNode.
+  DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
+  assert(Iter != Map.end() && "Identifier not in the type map?");
+  assert(DIDescriptor(Iter->second).isType() &&
+         "MDNode in DITypeIdentifierMap should be a DIType.");
+  return T(Iter->second);
+}
+
+template <typename T> StringRef DIRef<T>::getName() const {
+  if (!Val)
+    return StringRef();
+
+  if (const MDNode *MD = dyn_cast<MDNode>(Val))
+    return T(MD).getName();
+
+  const MDString *MS = cast<MDString>(Val);
+  return MS->getString();
+}
+
+/// Specialize getFieldAs to handle fields that are references to DIScopes.
+template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
+/// Specialize DIRef constructor for DIScopeRef.
+template <> DIRef<DIScope>::DIRef(const Value *V);
+
+/// Specialize getFieldAs to handle fields that are references to DITypes.
+template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
+/// Specialize DIRef constructor for DITypeRef.
+template <> DIRef<DIType>::DIRef(const Value *V);
+
+/// DIType - This is a wrapper for a type.
+/// FIXME: Types should be factored much better so that CV qualifiers and
+/// others do not require a huge and empty descriptor full of zeros.
+class DIType : public DIScope {
+protected:
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIType(const MDNode *N = nullptr) : DIScope(N) {}
+  operator DITypeRef () const {
+    assert(isType() &&
+           "constructing DITypeRef from an MDNode that is not a type");
+    return DITypeRef(&*getRef());
+  }
+
+  /// Verify - Verify that a type descriptor is well formed.
+  bool Verify() const;
+
+  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
+  StringRef getName() const { return getStringField(3); }
+  unsigned getLineNumber() const { return getUnsignedField(4); }
+  uint64_t getSizeInBits() const { return getUInt64Field(5); }
+  uint64_t getAlignInBits() const { return getUInt64Field(6); }
+  // FIXME: Offset is only used for DW_TAG_member nodes.  Making every type
+  // carry this is just plain insane.
+  uint64_t getOffsetInBits() const { return getUInt64Field(7); }
+  unsigned getFlags() const { return getUnsignedField(8); }
+  bool isPrivate() const { return (getFlags() & FlagPrivate) != 0; }
+  bool isProtected() const { return (getFlags() & FlagProtected) != 0; }
+  bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
+  // isAppleBlock - Return true if this is the Apple Blocks extension.
+  bool isAppleBlockExtension() const {
+    return (getFlags() & FlagAppleBlock) != 0;
+  }
+  bool isBlockByrefStruct() const {
+    return (getFlags() & FlagBlockByrefStruct) != 0;
+  }
+  bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
+  bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
+  bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
+  bool isObjcClassComplete() const {
+    return (getFlags() & FlagObjcClassComplete) != 0;
+  }
+  bool isVector() const { return (getFlags() & FlagVector) != 0; }
+  bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
+  bool isLValueReference() const {
+    return (getFlags() & FlagLValueReference) != 0;
+  }
+  bool isRValueReference() const {
+    return (getFlags() & FlagRValueReference) != 0;
+  }
+  bool isValid() const { return DbgNode && isType(); }
+
+  /// replaceAllUsesWith - Replace all uses of debug info referenced by
+  /// this descriptor.
+  void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D);
+  void replaceAllUsesWith(MDNode *D);
+};
+
+/// DIBasicType - A basic type, like 'int' or 'float'.
+class DIBasicType : public DIType {
+public:
+  explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {}
+
+  unsigned getEncoding() const { return getUnsignedField(9); }
+
+  /// Verify - Verify that a basic type descriptor is well formed.
+  bool Verify() const;
+};
+
+/// DIDerivedType - A simple derived type, like a const qualified type,
+/// a typedef, a pointer or reference, et cetera.  Or, a data member of
+/// a class/struct/union.
+class DIDerivedType : public DIType {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {}
+
+  DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); }
+
+  /// getObjCProperty - Return property node, if this ivar is
+  /// associated with one.
+  MDNode *getObjCProperty() const;
+
+  DITypeRef getClassType() const {
+    assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+    return getFieldAs<DITypeRef>(10);
+  }
+
+  Constant *getConstant() const {
+    assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
+    return getConstantField(10);
+  }
+
+  /// Verify - Verify that a derived type descriptor is well formed.
+  bool Verify() const;
+};
+
+/// DICompositeType - This descriptor holds a type that can refer to multiple
+/// other types, like a function or struct.
+/// DICompositeType is derived from DIDerivedType because some
+/// composite types (such as enums) can be derived from basic types
+// FIXME: Make this derive from DIType directly & just store the
+// base type in a single DIType field.
+class DICompositeType : public DIDerivedType {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {}
+
+  DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
+  void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
+  unsigned getRunTimeLang() const { return getUnsignedField(11); }
+  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
+  void setContainingType(DICompositeType ContainingType);
+  DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
+  MDString *getIdentifier() const;
+
+  /// Verify - Verify that a composite type descriptor is well formed.
+  bool Verify() const;
+};
+
+/// DIFile - This is a wrapper for a file.
+class DIFile : public DIScope {
+  friend class DIDescriptor;
+
+public:
+  explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {}
+  MDNode *getFileNode() const;
+  bool Verify() const;
+};
+
+/// DICompileUnit - A wrapper for a compile unit.
+class DICompileUnit : public DIScope {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {}
+
+  dwarf::SourceLanguage getLanguage() const {
+    return static_cast<dwarf::SourceLanguage>(getUnsignedField(2));
+  }
+  StringRef getProducer() const { return getStringField(3); }
+
+  bool isOptimized() const { return getUnsignedField(4) != 0; }
+  StringRef getFlags() const { return getStringField(5); }
+  unsigned getRunTimeVersion() const { return getUnsignedField(6); }
+
+  DIArray getEnumTypes() const;
+  DIArray getRetainedTypes() const;
+  DIArray getSubprograms() const;
+  DIArray getGlobalVariables() const;
+  DIArray getImportedEntities() const;
+
+  StringRef getSplitDebugFilename() const { return getStringField(12); }
+  unsigned getEmissionKind() const { return getUnsignedField(13); }
+
+  /// Verify - Verify that a compile unit is well formed.
+  bool Verify() const;
+};
+
+/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
+class DISubprogram : public DIScope {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {}
+
+  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
+  StringRef getName() const { return getStringField(3); }
+  StringRef getDisplayName() const { return getStringField(4); }
+  StringRef getLinkageName() const { return getStringField(5); }
+  unsigned getLineNumber() const { return getUnsignedField(6); }
+  DICompositeType getType() const { return getFieldAs<DICompositeType>(7); }
+
+  /// isLocalToUnit - Return true if this subprogram is local to the current
+  /// compile unit, like 'static' in C.
+  unsigned isLocalToUnit() const { return getUnsignedField(8); }
+  unsigned isDefinition() const { return getUnsignedField(9); }
+
+  unsigned getVirtuality() const { return getUnsignedField(10); }
+  unsigned getVirtualIndex() const { return getUnsignedField(11); }
+
+  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
+
+  unsigned getFlags() const { return getUnsignedField(13); }
+
+  unsigned isArtificial() const {
+    return (getUnsignedField(13) & FlagArtificial) != 0;
+  }
+  /// isPrivate - Return true if this subprogram has "private"
+  /// access specifier.
+  bool isPrivate() const { return (getUnsignedField(13) & FlagPrivate) != 0; }
+  /// isProtected - Return true if this subprogram has "protected"
+  /// access specifier.
+  bool isProtected() const {
+    return (getUnsignedField(13) & FlagProtected) != 0;
+  }
+  /// isExplicit - Return true if this subprogram is marked as explicit.
+  bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; }
+  /// isPrototyped - Return true if this subprogram is prototyped.
+  bool isPrototyped() const {
+    return (getUnsignedField(13) & FlagPrototyped) != 0;
+  }
+
+  /// Return true if this subprogram is a C++11 reference-qualified
+  /// non-static member function (void foo() &).
+  unsigned isLValueReference() const {
+    return (getUnsignedField(13) & FlagLValueReference) != 0;
+  }
+
+  /// Return true if this subprogram is a C++11
+  /// rvalue-reference-qualified non-static member function
+  /// (void foo() &&).
+  unsigned isRValueReference() const {
+    return (getUnsignedField(13) & FlagRValueReference) != 0;
+  }
+
+  unsigned isOptimized() const;
+
+  /// Verify - Verify that a subprogram descriptor is well formed.
+  bool Verify() const;
+
+  /// describes - Return true if this subprogram provides debugging
+  /// information for the function F.
+  bool describes(const Function *F);
+
+  Function *getFunction() const { return getFunctionField(15); }
+  void replaceFunction(Function *F) { replaceFunctionField(15, F); }
+  DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); }
+  DISubprogram getFunctionDeclaration() const {
+    return getFieldAs<DISubprogram>(17);
+  }
+  MDNode *getVariablesNodes() const;
+  DIArray getVariables() const;
+
+  /// getScopeLineNumber - Get the beginning of the scope of the
+  /// function, not necessarily where the name of the program
+  /// starts.
+  unsigned getScopeLineNumber() const { return getUnsignedField(19); }
+};
+
+/// DILexicalBlock - This is a wrapper for a lexical block.
+class DILexicalBlock : public DIScope {
+public:
+  explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {}
+  DIScope getContext() const { return getFieldAs<DIScope>(2); }
+  unsigned getLineNumber() const { return getUnsignedField(3); }
+  unsigned getColumnNumber() const { return getUnsignedField(4); }
+  unsigned getDiscriminator() const { return getUnsignedField(5); }
+  bool Verify() const;
+};
+
+/// DILexicalBlockFile - This is a wrapper for a lexical block with
+/// a filename change.
+class DILexicalBlockFile : public DIScope {
+public:
+  explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {}
+  DIScope getContext() const {
+    if (getScope().isSubprogram())
+      return getScope();
+    return getScope().getContext();
+  }
+  unsigned getLineNumber() const { return getScope().getLineNumber(); }
+  unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
+  DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
+  bool Verify() const;
+};
+
+/// DINameSpace - A wrapper for a C++ style name space.
+class DINameSpace : public DIScope {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {}
+  DIScope getContext() const { return getFieldAs<DIScope>(2); }
+  StringRef getName() const { return getStringField(3); }
+  unsigned getLineNumber() const { return getUnsignedField(4); }
+  bool Verify() const;
+};
+
+/// DIUnspecifiedParameter - This is a wrapper for unspecified parameters.
+class DIUnspecifiedParameter : public DIDescriptor {
+public:
+  explicit DIUnspecifiedParameter(const MDNode *N = nullptr)
+    : DIDescriptor(N) {}
+  bool Verify() const;
+};
+
+/// DITemplateTypeParameter - This is a wrapper for template type parameter.
+class DITemplateTypeParameter : public DIDescriptor {
+public:
+  explicit DITemplateTypeParameter(const MDNode *N = nullptr)
+    : DIDescriptor(N) {}
+
+  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
+  StringRef getName() const { return getStringField(2); }
+  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
+  StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); }
+  StringRef getDirectory() const {
+    return getFieldAs<DIFile>(4).getDirectory();
+  }
+  unsigned getLineNumber() const { return getUnsignedField(5); }
+  unsigned getColumnNumber() const { return getUnsignedField(6); }
+  bool Verify() const;
+};
+
+/// DITemplateValueParameter - This is a wrapper for template value parameter.
+class DITemplateValueParameter : public DIDescriptor {
+public:
+  explicit DITemplateValueParameter(const MDNode *N = nullptr)
+    : DIDescriptor(N) {}
+
+  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
+  StringRef getName() const { return getStringField(2); }
+  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
+  Value *getValue() const;
+  StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); }
+  StringRef getDirectory() const {
+    return getFieldAs<DIFile>(5).getDirectory();
+  }
+  unsigned getLineNumber() const { return getUnsignedField(6); }
+  unsigned getColumnNumber() const { return getUnsignedField(7); }
+  bool Verify() const;
+};
+
+/// DIGlobalVariable - This is a wrapper for a global variable.
+class DIGlobalVariable : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  DIScope getContext() const { return getFieldAs<DIScope>(2); }
+  StringRef getName() const { return getStringField(3); }
+  StringRef getDisplayName() const { return getStringField(4); }
+  StringRef getLinkageName() const { return getStringField(5); }
+  StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); }
+  StringRef getDirectory() const {
+    return getFieldAs<DIFile>(6).getDirectory();
+  }
+
+  unsigned getLineNumber() const { return getUnsignedField(7); }
+  DITypeRef getType() const { return getFieldAs<DITypeRef>(8); }
+  unsigned isLocalToUnit() const { return getUnsignedField(9); }
+  unsigned isDefinition() const { return getUnsignedField(10); }
+
+  GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
+  Constant *getConstant() const { return getConstantField(11); }
+  DIDerivedType getStaticDataMemberDeclaration() const {
+    return getFieldAs<DIDerivedType>(12);
+  }
+
+  /// Verify - Verify that a global variable descriptor is well formed.
+  bool Verify() const;
+};
+
+/// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
+/// global etc).
+class DIVariable : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+
+  DIScope getContext() const { return getFieldAs<DIScope>(1); }
+  StringRef getName() const { return getStringField(2); }
+  DIFile getFile() const { return getFieldAs<DIFile>(3); }
+  unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; }
+  unsigned getArgNumber() const {
+    unsigned L = getUnsignedField(4);
+    return L >> 24;
+  }
+  DITypeRef getType() const { return getFieldAs<DITypeRef>(5); }
+
+  /// isArtificial - Return true if this variable is marked as "artificial".
+  bool isArtificial() const {
+    return (getUnsignedField(6) & FlagArtificial) != 0;
+  }
+
+  bool isObjectPointer() const {
+    return (getUnsignedField(6) & FlagObjectPointer) != 0;
+  }
+
+  /// \brief Return true if this variable is represented as a pointer.
+  bool isIndirect() const {
+    return (getUnsignedField(6) & FlagIndirectVariable) != 0;
+  }
+
+  /// getInlinedAt - If this variable is inlined then return inline location.
+  MDNode *getInlinedAt() const;
+
+  /// Verify - Verify that a variable descriptor is well formed.
+  bool Verify() const;
+
+  /// HasComplexAddr - Return true if the variable has a complex address.
+  bool hasComplexAddress() const { return getNumAddrElements() > 0; }
+
+  /// \brief Return the size of this variable's complex address or
+  /// zero if there is none.
+  unsigned getNumAddrElements() const {
+    if (DbgNode->getNumOperands() < 9)
+      return 0;
+    return getDescriptorField(8)->getNumOperands();
+  }
+
+  /// \brief return the Idx'th complex address element.
+  uint64_t getAddrElement(unsigned Idx) const;
+
+  /// isBlockByrefVariable - Return true if the variable was declared as
+  /// a "__block" variable (Apple Blocks).
+  bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
+    return (getType().resolve(Map)).isBlockByrefStruct();
+  }
+
+  /// isInlinedFnArgument - Return true if this variable provides debugging
+  /// information for an inlined function arguments.
+  bool isInlinedFnArgument(const Function *CurFn);
+
+  void printExtendedName(raw_ostream &OS) const;
+};
+
+/// DILocation - This object holds location information. This object
+/// is not associated with any DWARF tag.
+class DILocation : public DIDescriptor {
+public:
+  explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
+
+  unsigned getLineNumber() const { return getUnsignedField(0); }
+  unsigned getColumnNumber() const { return getUnsignedField(1); }
+  DIScope getScope() const { return getFieldAs<DIScope>(2); }
+  DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
+  StringRef getFilename() const { return getScope().getFilename(); }
+  StringRef getDirectory() const { return getScope().getDirectory(); }
+  bool Verify() const;
+  bool atSameLineAs(const DILocation &Other) const {
+    return (getLineNumber() == Other.getLineNumber() &&
+            getFilename() == Other.getFilename());
+  }
+  /// getDiscriminator - DWARF discriminators are used to distinguish
+  /// identical file locations for instructions that are on different
+  /// basic blocks. If two instructions are inside the same lexical block
+  /// and are in different basic blocks, we create a new lexical block
+  /// with identical location as the original but with a different
+  /// discriminator value (lib/Transforms/Util/AddDiscriminators.cpp
+  /// for details).
+  unsigned getDiscriminator() const {
+    // Since discriminators are associated with lexical blocks, make
+    // sure this location is a lexical block before retrieving its
+    // value.
+    return getScope().isLexicalBlock()
+               ? getFieldAs<DILexicalBlock>(2).getDiscriminator()
+               : 0;
+  }
+  unsigned computeNewDiscriminator(LLVMContext &Ctx);
+  DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlock NewScope);
+};
+
+class DIObjCProperty : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
+
+  StringRef getObjCPropertyName() const { return getStringField(1); }
+  DIFile getFile() const { return getFieldAs<DIFile>(2); }
+  unsigned getLineNumber() const { return getUnsignedField(3); }
+
+  StringRef getObjCPropertyGetterName() const { return getStringField(4); }
+  StringRef getObjCPropertySetterName() const { return getStringField(5); }
+  bool isReadOnlyObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
+  }
+  bool isReadWriteObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
+  }
+  bool isAssignObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
+  }
+  bool isRetainObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
+  }
+  bool isCopyObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
+  }
+  bool isNonAtomicObjCProperty() const {
+    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
+  }
+
+  /// Objective-C doesn't have an ODR, so there is no benefit in storing
+  /// the type as a DITypeRef here.
+  DIType getType() const { return getFieldAs<DIType>(7); }
+
+  /// Verify - Verify that a derived type descriptor is well formed.
+  bool Verify() const;
+};
+
+/// \brief An imported module (C++ using directive or similar).
+class DIImportedEntity : public DIDescriptor {
+  friend class DIDescriptor;
+  void printInternal(raw_ostream &OS) const;
+
+public:
+  explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
+  DIScope getContext() const { return getFieldAs<DIScope>(1); }
+  DIScopeRef getEntity() const { return getFieldAs<DIScopeRef>(2); }
+  unsigned getLineNumber() const { return getUnsignedField(3); }
+  StringRef getName() const { return getStringField(4); }
+  bool Verify() const;
+};
+
+/// getDISubprogram - Find subprogram that is enclosing this scope.
+DISubprogram getDISubprogram(const MDNode *Scope);
+
+/// getDICompositeType - Find underlying composite type.
+DICompositeType getDICompositeType(DIType T);
+
+/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
+/// to hold function specific information.
+NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
+
+/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
+/// suitable to hold function specific information.
+NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
+
+/// createInlinedVariable - Create a new inlined variable based on current
+/// variable.
+/// @param DV            Current Variable.
+/// @param InlinedScope  Location at current variable is inlined.
+DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
+                                 LLVMContext &VMContext);
+
+/// cleanseInlinedVariable - Remove inlined scope from the variable.
+DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
+
+/// Construct DITypeIdentifierMap by going through retained types of each CU.
+DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
+
+/// Strip debug info in the module if it exists.
+/// To do this, we remove all calls to the debugger intrinsics and any named
+/// metadata for debugging. We also remove debug locations for instructions.
+/// Return true if module is modified.
+bool StripDebugInfo(Module &M);
+
+/// Return Debug Info Metadata Version by checking module flags.
+unsigned getDebugMetadataVersionFromModule(const Module &M);
+
+/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
+/// list debug info MDNodes used by an instruction, DebugInfoFinder uses
+/// processDeclare, processValue and processLocation to handle DbgDeclareInst,
+/// DbgValueInst and DbgLoc attached to instructions. processModule will go
+/// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes
+/// used by the CUs.
+class DebugInfoFinder {
+public:
+  DebugInfoFinder() : TypeMapInitialized(false) {}
+
+  /// processModule - Process entire module and collect debug info
+  /// anchors.
+  void processModule(const Module &M);
+
+  /// processDeclare - Process DbgDeclareInst.
+  void processDeclare(const Module &M, const DbgDeclareInst *DDI);
+  /// Process DbgValueInst.
+  void processValue(const Module &M, const DbgValueInst *DVI);
+  /// processLocation - Process DILocation.
+  void processLocation(const Module &M, DILocation Loc);
+
+  /// Clear all lists.
+  void reset();
+
+private:
+  /// Initialize TypeIdentifierMap.
+  void InitializeTypeMap(const Module &M);
+
+  /// processType - Process DIType.
+  void processType(DIType DT);
+
+  /// processSubprogram - Process DISubprogram.
+  void processSubprogram(DISubprogram SP);
+
+  void processScope(DIScope Scope);
+
+  /// addCompileUnit - Add compile unit into CUs.
+  bool addCompileUnit(DICompileUnit CU);
+
+  /// addGlobalVariable - Add global variable into GVs.
+  bool addGlobalVariable(DIGlobalVariable DIG);
+
+  // addSubprogram - Add subprogram into SPs.
+  bool addSubprogram(DISubprogram SP);
+
+  /// addType - Add type into Tys.
+  bool addType(DIType DT);
+
+  bool addScope(DIScope Scope);
+
+public:
+  typedef SmallVectorImpl<DICompileUnit>::const_iterator compile_unit_iterator;
+  typedef SmallVectorImpl<DISubprogram>::const_iterator subprogram_iterator;
+  typedef SmallVectorImpl<DIGlobalVariable>::const_iterator global_variable_iterator;
+  typedef SmallVectorImpl<DIType>::const_iterator type_iterator;
+  typedef SmallVectorImpl<DIScope>::const_iterator scope_iterator;
+
+  iterator_range<compile_unit_iterator> compile_units() const {
+    return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end());
+  }
+
+  iterator_range<subprogram_iterator> subprograms() const {
+    return iterator_range<subprogram_iterator>(SPs.begin(), SPs.end());
+  }
+
+  iterator_range<global_variable_iterator> global_variables() const {
+    return iterator_range<global_variable_iterator>(GVs.begin(), GVs.end());
+  }
+
+  iterator_range<type_iterator> types() const {
+    return iterator_range<type_iterator>(TYs.begin(), TYs.end());
+  }
+
+  iterator_range<scope_iterator> scopes() const {
+    return iterator_range<scope_iterator>(Scopes.begin(), Scopes.end());
+  }
+
+  unsigned compile_unit_count() const { return CUs.size(); }
+  unsigned global_variable_count() const { return GVs.size(); }
+  unsigned subprogram_count() const { return SPs.size(); }
+  unsigned type_count() const { return TYs.size(); }
+  unsigned scope_count() const { return Scopes.size(); }
+
+private:
+  SmallVector<DICompileUnit, 8> CUs;    // Compile Units
+  SmallVector<DISubprogram, 8> SPs;    // Subprograms
+  SmallVector<DIGlobalVariable, 8> GVs;    // Global Variables;
+  SmallVector<DIType, 8> TYs;    // Types
+  SmallVector<DIScope, 8> Scopes; // Scopes
+  SmallPtrSet<MDNode *, 64> NodesSeen;
+  DITypeIdentifierMap TypeIdentifierMap;
+  /// Specify if TypeIdentifierMap is initialized.
+  bool TypeMapInitialized;
+};
+
+DenseMap<const Function *, DISubprogram> makeSubprogramMap(const Module &M);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
new file mode 100644
index 0000000..3d969a8
--- /dev/null
+++ b/include/llvm/IR/DebugLoc.h
@@ -0,0 +1,123 @@
+//===- DebugLoc.h - Debug Location Information ------------------*- 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 number of light weight data structures used
+// to describe and track debug location information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DEBUGLOC_H
+#define LLVM_IR_DEBUGLOC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  template <typename T> struct DenseMapInfo;
+  class MDNode;
+  class LLVMContext;
+  class raw_ostream;
+
+  /// DebugLoc - Debug location id.  This is carried by Instruction, SDNode,
+  /// and MachineInstr to compactly encode file/line/scope information for an
+  /// operation.
+  class DebugLoc {
+    friend struct DenseMapInfo<DebugLoc>;
+
+    /// getEmptyKey() - A private constructor that returns an unknown that is
+    /// not equal to the tombstone key or DebugLoc().
+    static DebugLoc getEmptyKey() {
+      DebugLoc DL;
+      DL.LineCol = 1;
+      return DL;
+    }
+
+    /// getTombstoneKey() - A private constructor that returns an unknown that
+    /// is not equal to the empty key or DebugLoc().
+    static DebugLoc getTombstoneKey() {
+      DebugLoc DL;
+      DL.LineCol = 2;
+      return DL;
+    }
+
+    /// LineCol - This 32-bit value encodes the line and column number for the
+    /// location, encoded as 24-bits for line and 8 bits for col.  A value of 0
+    /// for either means unknown.
+    uint32_t LineCol;
+
+    /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
+    /// decoded by LLVMContext.  0 is unknown.
+    int ScopeIdx;
+  public:
+    DebugLoc() : LineCol(0), ScopeIdx(0) {}  // Defaults to unknown.
+
+    /// get - Get a new DebugLoc that corresponds to the specified line/col
+    /// scope/inline location.
+    static DebugLoc get(unsigned Line, unsigned Col,
+                        MDNode *Scope, MDNode *InlinedAt = nullptr);
+
+    /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
+    static DebugLoc getFromDILocation(MDNode *N);
+
+    /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
+    static DebugLoc getFromDILexicalBlock(MDNode *N);
+
+    /// isUnknown - Return true if this is an unknown location.
+    bool isUnknown() const { return ScopeIdx == 0; }
+
+    unsigned getLine() const {
+      return (LineCol << 8) >> 8;  // Mask out column.
+    }
+
+    unsigned getCol() const {
+      return LineCol >> 24;
+    }
+
+    /// getScope - This returns the scope pointer for this DebugLoc, or null if
+    /// invalid.
+    MDNode *getScope(const LLVMContext &Ctx) const;
+
+    /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
+    /// null if invalid or not present.
+    MDNode *getInlinedAt(const LLVMContext &Ctx) const;
+
+    /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
+    void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
+                              const LLVMContext &Ctx) const;
+
+    /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
+    MDNode *getScopeNode(const LLVMContext &Ctx) const;
+
+    // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
+    // number info for the function.
+    DebugLoc getFnDebugLoc(const LLVMContext &Ctx) const;
+
+    /// getAsMDNode - This method converts the compressed DebugLoc node into a
+    /// DILocation compatible MDNode.
+    MDNode *getAsMDNode(const LLVMContext &Ctx) const;
+
+    bool operator==(const DebugLoc &DL) const {
+      return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
+    }
+    bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
+
+    void dump(const LLVMContext &Ctx) const;
+    /// \brief prints source location /path/to/file.exe:line:col @[inlined at]
+    void print(const LLVMContext &Ctx, raw_ostream &OS) const;
+  };
+
+  template <>
+  struct DenseMapInfo<DebugLoc> {
+    static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
+    static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
+    static unsigned getHashValue(const DebugLoc &Key);
+    static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
+  };
+} // end namespace llvm
+
+#endif /* LLVM_SUPPORT_DEBUGLOC_H */
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
new file mode 100644
index 0000000..ff15087
--- /dev/null
+++ b/include/llvm/IR/DerivedTypes.h
@@ -0,0 +1,475 @@
+//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of classes that represent "derived
+// types".  These are things like "arrays of x" or "structure of x, y, z" or
+// "function returning x taking (y,z) as parameters", etc...
+//
+// The implementations of these classes live in the Type.cpp file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DERIVEDTYPES_H
+#define LLVM_IR_DERIVEDTYPES_H
+
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class Value;
+class APInt;
+class LLVMContext;
+template<typename T> class ArrayRef;
+class StringRef;
+
+/// Class to represent integer types. Note that this class is also used to
+/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
+/// Int64Ty.
+/// @brief Integer representation type
+class IntegerType : public Type {
+  friend class LLVMContextImpl;
+  
+protected:
+  explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){
+    setSubclassData(NumBits);
+  }
+public:
+  /// This enum is just used to hold constants we need for IntegerType.
+  enum {
+    MIN_INT_BITS = 1,        ///< Minimum number of bits that can be specified
+    MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
+      ///< Note that bit width is stored in the Type classes SubclassData field
+      ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
+  };
+
+  /// This static method is the primary way of constructing an IntegerType.
+  /// If an IntegerType with the same NumBits value was previously instantiated,
+  /// that instance will be returned. Otherwise a new one will be created. Only
+  /// one instance with a given NumBits value is ever created.
+  /// @brief Get or create an IntegerType instance.
+  static IntegerType *get(LLVMContext &C, unsigned NumBits);
+
+  /// @brief Get the number of bits in this IntegerType
+  unsigned getBitWidth() const { return getSubclassData(); }
+
+  /// getBitMask - Return a bitmask with ones set for all of the bits
+  /// that can be set by an unsigned version of this type.  This is 0xFF for
+  /// i8, 0xFFFF for i16, etc.
+  uint64_t getBitMask() const {
+    return ~uint64_t(0UL) >> (64-getBitWidth());
+  }
+
+  /// getSignBit - Return a uint64_t with just the most significant bit set (the
+  /// sign bit, if the value is treated as a signed number).
+  uint64_t getSignBit() const {
+    return 1ULL << (getBitWidth()-1);
+  }
+
+  /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
+  /// @returns a bit mask with ones set for all the bits of this type.
+  /// @brief Get a bit mask for this type.
+  APInt getMask() const;
+
+  /// This method determines if the width of this IntegerType is a power-of-2
+  /// in terms of 8 bit bytes.
+  /// @returns true if this is a power-of-2 byte width.
+  /// @brief Is this a power-of-2 byte-width IntegerType ?
+  bool isPowerOf2ByteWidth() const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == IntegerTyID;
+  }
+};
+
+
+/// FunctionType - Class to represent function types
+///
+class FunctionType : public Type {
+  FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION;
+  const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION;
+  FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
+
+public:
+  /// FunctionType::get - This static method is the primary way of constructing
+  /// a FunctionType.
+  ///
+  static FunctionType *get(Type *Result,
+                           ArrayRef<Type*> Params, bool isVarArg);
+
+  /// FunctionType::get - Create a FunctionType taking no parameters.
+  ///
+  static FunctionType *get(Type *Result, bool isVarArg);
+  
+  /// isValidReturnType - Return true if the specified type is valid as a return
+  /// type.
+  static bool isValidReturnType(Type *RetTy);
+
+  /// isValidArgumentType - Return true if the specified type is valid as an
+  /// argument type.
+  static bool isValidArgumentType(Type *ArgTy);
+
+  bool isVarArg() const { return getSubclassData()!=0; }
+  Type *getReturnType() const { return ContainedTys[0]; }
+
+  typedef Type::subtype_iterator param_iterator;
+  param_iterator param_begin() const { return ContainedTys + 1; }
+  param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
+
+  /// Parameter type accessors.
+  Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
+
+  /// getNumParams - Return the number of fixed parameters this function type
+  /// requires.  This does not consider varargs.
+  ///
+  unsigned getNumParams() const { return NumContainedTys - 1; }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == FunctionTyID;
+  }
+};
+
+
+/// CompositeType - Common super class of ArrayType, StructType, PointerType
+/// and VectorType.
+class CompositeType : public Type {
+protected:
+  explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { }
+public:
+
+  /// getTypeAtIndex - Given an index value into the type, return the type of
+  /// the element.
+  ///
+  Type *getTypeAtIndex(const Value *V);
+  Type *getTypeAtIndex(unsigned Idx);
+  bool indexValid(const Value *V) const;
+  bool indexValid(unsigned Idx) const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == ArrayTyID ||
+           T->getTypeID() == StructTyID ||
+           T->getTypeID() == PointerTyID ||
+           T->getTypeID() == VectorTyID;
+  }
+};
+
+
+/// StructType - Class to represent struct types.  There are two different kinds
+/// of struct types: Literal structs and Identified structs.
+///
+/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must
+/// always have a body when created.  You can get one of these by using one of
+/// the StructType::get() forms.
+///  
+/// Identified structs (e.g. %foo or %42) may optionally have a name and are not
+/// uniqued.  The names for identified structs are managed at the LLVMContext
+/// level, so there can only be a single identified struct with a given name in
+/// a particular LLVMContext.  Identified structs may also optionally be opaque
+/// (have no body specified).  You get one of these by using one of the
+/// StructType::create() forms.
+///
+/// Independent of what kind of struct you have, the body of a struct type are
+/// laid out in memory consequtively with the elements directly one after the
+/// other (if the struct is packed) or (if not packed) with padding between the
+/// elements as defined by DataLayout (which is required to match what the code
+/// generator for a target expects).
+///
+class StructType : public CompositeType {
+  StructType(const StructType &) LLVM_DELETED_FUNCTION;
+  const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION;
+  StructType(LLVMContext &C)
+    : CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {}
+  enum {
+    /// This is the contents of the SubClassData field.
+    SCDB_HasBody = 1,
+    SCDB_Packed = 2,
+    SCDB_IsLiteral = 4,
+    SCDB_IsSized = 8
+  };
+
+  /// SymbolTableEntry - For a named struct that actually has a name, this is a
+  /// pointer to the symbol table entry (maintained by LLVMContext) for the
+  /// struct.  This is null if the type is an literal struct or if it is
+  /// a identified type that has an empty name.
+  /// 
+  void *SymbolTableEntry;
+public:
+  ~StructType() {
+    delete [] ContainedTys; // Delete the body.
+  }
+
+  /// StructType::create - This creates an identified struct.
+  static StructType *create(LLVMContext &Context, StringRef Name);
+  static StructType *create(LLVMContext &Context);
+  
+  static StructType *create(ArrayRef<Type*> Elements,
+                            StringRef Name,
+                            bool isPacked = false);
+  static StructType *create(ArrayRef<Type*> Elements);
+  static StructType *create(LLVMContext &Context,
+                            ArrayRef<Type*> Elements,
+                            StringRef Name,
+                            bool isPacked = false);
+  static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements);
+  static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL;
+
+  /// StructType::get - This static method is the primary way to create a
+  /// literal StructType.
+  static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
+                         bool isPacked = false);
+
+  /// StructType::get - Create an empty structure type.
+  ///
+  static StructType *get(LLVMContext &Context, bool isPacked = false);
+  
+  /// StructType::get - This static method is a convenience method for creating
+  /// structure types by specifying the elements as arguments.  Note that this
+  /// method always returns a non-packed struct, and requires at least one
+  /// element type.
+  static StructType *get(Type *elt1, ...) END_WITH_NULL;
+
+  bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
+  
+  /// isLiteral - Return true if this type is uniqued by structural
+  /// equivalence, false if it is a struct definition.
+  bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; }
+  
+  /// isOpaque - Return true if this is a type with an identity that has no body
+  /// specified yet.  These prints as 'opaque' in .ll files.
+  bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }
+
+  /// isSized - Return true if this is a sized type.
+  bool isSized(SmallPtrSet<const Type*, 4> *Visited = nullptr) const;
+  
+  /// hasName - Return true if this is a named struct that has a non-empty name.
+  bool hasName() const { return SymbolTableEntry != nullptr; }
+  
+  /// getName - Return the name for this struct type if it has an identity.
+  /// This may return an empty string for an unnamed struct type.  Do not call
+  /// this on an literal type.
+  StringRef getName() const;
+  
+  /// setName - Change the name of this type to the specified name, or to a name
+  /// with a suffix if there is a collision.  Do not call this on an literal
+  /// type.
+  void setName(StringRef Name);
+
+  /// setBody - Specify a body for an opaque identified type.
+  void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
+  void setBody(Type *elt1, ...) END_WITH_NULL;
+  
+  /// isValidElementType - Return true if the specified type is valid as a
+  /// element type.
+  static bool isValidElementType(Type *ElemTy);
+  
+
+  // Iterator access to the elements.
+  typedef Type::subtype_iterator element_iterator;
+  element_iterator element_begin() const { return ContainedTys; }
+  element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
+
+  /// isLayoutIdentical - Return true if this is layout identical to the
+  /// specified struct.
+  bool isLayoutIdentical(StructType *Other) const;  
+  
+  /// Random access to the elements
+  unsigned getNumElements() const { return NumContainedTys; }
+  Type *getElementType(unsigned N) const {
+    assert(N < NumContainedTys && "Element number out of range!");
+    return ContainedTys[N];
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == StructTyID;
+  }
+};
+
+/// SequentialType - This is the superclass of the array, pointer and vector
+/// type classes.  All of these represent "arrays" in memory.  The array type
+/// represents a specifically sized array, pointer types are unsized/unknown
+/// size arrays, vector types represent specifically sized arrays that
+/// allow for use of SIMD instructions.  SequentialType holds the common
+/// features of all, which stem from the fact that all three lay their
+/// components out in memory identically.
+///
+class SequentialType : public CompositeType {
+  Type *ContainedType;               ///< Storage for the single contained type.
+  SequentialType(const SequentialType &) LLVM_DELETED_FUNCTION;
+  const SequentialType &operator=(const SequentialType &) LLVM_DELETED_FUNCTION;
+
+protected:
+  SequentialType(TypeID TID, Type *ElType)
+    : CompositeType(ElType->getContext(), TID), ContainedType(ElType) {
+    ContainedTys = &ContainedType;
+    NumContainedTys = 1;
+  }
+
+public:
+  Type *getElementType() const { return ContainedTys[0]; }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == ArrayTyID ||
+           T->getTypeID() == PointerTyID ||
+           T->getTypeID() == VectorTyID;
+  }
+};
+
+
+/// ArrayType - Class to represent array types.
+///
+class ArrayType : public SequentialType {
+  uint64_t NumElements;
+
+  ArrayType(const ArrayType &) LLVM_DELETED_FUNCTION;
+  const ArrayType &operator=(const ArrayType &) LLVM_DELETED_FUNCTION;
+  ArrayType(Type *ElType, uint64_t NumEl);
+public:
+  /// ArrayType::get - This static method is the primary way to construct an
+  /// ArrayType
+  ///
+  static ArrayType *get(Type *ElementType, uint64_t NumElements);
+
+  /// isValidElementType - Return true if the specified type is valid as a
+  /// element type.
+  static bool isValidElementType(Type *ElemTy);
+
+  uint64_t getNumElements() const { return NumElements; }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == ArrayTyID;
+  }
+};
+
+/// VectorType - Class to represent vector types.
+///
+class VectorType : public SequentialType {
+  unsigned NumElements;
+
+  VectorType(const VectorType &) LLVM_DELETED_FUNCTION;
+  const VectorType &operator=(const VectorType &) LLVM_DELETED_FUNCTION;
+  VectorType(Type *ElType, unsigned NumEl);
+public:
+  /// VectorType::get - This static method is the primary way to construct an
+  /// VectorType.
+  ///
+  static VectorType *get(Type *ElementType, unsigned NumElements);
+
+  /// VectorType::getInteger - This static method gets a VectorType with the
+  /// same number of elements as the input type, and the element type is an
+  /// integer type of the same width as the input element type.
+  ///
+  static VectorType *getInteger(VectorType *VTy) {
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    assert(EltBits && "Element size must be of a non-zero size");
+    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
+    return VectorType::get(EltTy, VTy->getNumElements());
+  }
+
+  /// VectorType::getExtendedElementVectorType - This static method is like
+  /// getInteger except that the element types are twice as wide as the
+  /// elements in the input type.
+  ///
+  static VectorType *getExtendedElementVectorType(VectorType *VTy) {
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
+    return VectorType::get(EltTy, VTy->getNumElements());
+  }
+
+  /// VectorType::getTruncatedElementVectorType - This static method is like
+  /// getInteger except that the element types are half as wide as the
+  /// elements in the input type.
+  ///
+  static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    assert((EltBits & 1) == 0 &&
+           "Cannot truncate vector element with odd bit-width");
+    Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
+    return VectorType::get(EltTy, VTy->getNumElements());
+  }
+
+  /// VectorType::getHalfElementsVectorType - This static method returns
+  /// a VectorType with half as many elements as the input type and the
+  /// same element type.
+  ///
+  static VectorType *getHalfElementsVectorType(VectorType *VTy) {
+    unsigned NumElts = VTy->getNumElements();
+    assert ((NumElts & 1) == 0 &&
+            "Cannot halve vector with odd number of elements.");
+    return VectorType::get(VTy->getElementType(), NumElts/2);
+  }
+
+  /// VectorType::getDoubleElementsVectorType - This static method returns
+  /// a VectorType with twice  as many elements as the input type and the
+  /// same element type.
+  ///
+  static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
+    unsigned NumElts = VTy->getNumElements();
+    return VectorType::get(VTy->getElementType(), NumElts*2);
+  }
+
+  /// isValidElementType - Return true if the specified type is valid as a
+  /// element type.
+  static bool isValidElementType(Type *ElemTy);
+
+  /// @brief Return the number of elements in the Vector type.
+  unsigned getNumElements() const { return NumElements; }
+
+  /// @brief Return the number of bits in the Vector type.
+  /// Returns zero when the vector is a vector of pointers.
+  unsigned getBitWidth() const {
+    return NumElements * getElementType()->getPrimitiveSizeInBits();
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == VectorTyID;
+  }
+};
+
+
+/// PointerType - Class to represent pointers.
+///
+class PointerType : public SequentialType {
+  PointerType(const PointerType &) LLVM_DELETED_FUNCTION;
+  const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION;
+  explicit PointerType(Type *ElType, unsigned AddrSpace);
+public:
+  /// PointerType::get - This constructs a pointer to an object of the specified
+  /// type in a numbered address space.
+  static PointerType *get(Type *ElementType, unsigned AddressSpace);
+
+  /// PointerType::getUnqual - This constructs a pointer to an object of the
+  /// specified type in the generic address space (address space zero).
+  static PointerType *getUnqual(Type *ElementType) {
+    return PointerType::get(ElementType, 0);
+  }
+
+  /// isValidElementType - Return true if the specified type is valid as a
+  /// element type.
+  static bool isValidElementType(Type *ElemTy);
+
+  /// @brief Return the address space of the Pointer type.
+  inline unsigned getAddressSpace() const { return getSubclassData(); }
+
+  /// Implement support type inquiry through isa, cast, and dyn_cast.
+  static inline bool classof(const Type *T) {
+    return T->getTypeID() == PointerTyID;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
new file mode 100644
index 0000000..9c9f236
--- /dev/null
+++ b/include/llvm/IR/DiagnosticInfo.h
@@ -0,0 +1,452 @@
+//===- llvm/Support/DiagnosticInfo.h - Diagnostic Declaration ---*- 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 different classes involved in low level diagnostics.
+//
+// Diagnostics reporting is still done as part of the LLVMContext.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DIAGNOSTICINFO_H
+#define LLVM_SUPPORT_DIAGNOSTICINFO_H
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+// Forward declarations.
+class DiagnosticPrinter;
+class Function;
+class Instruction;
+class LLVMContextImpl;
+class Twine;
+class Value;
+class DebugLoc;
+
+/// \brief Defines the different supported severity of a diagnostic.
+enum DiagnosticSeverity {
+  DS_Error,
+  DS_Warning,
+  DS_Remark,
+  // A note attaches additional information to one of the previous diagnostic
+  // types.
+  DS_Note
+};
+
+/// \brief Defines the different supported kind of a diagnostic.
+/// This enum should be extended with a new ID for each added concrete subclass.
+enum DiagnosticKind {
+  DK_InlineAsm,
+  DK_StackSize,
+  DK_DebugMetadataVersion,
+  DK_SampleProfile,
+  DK_OptimizationRemark,
+  DK_OptimizationRemarkMissed,
+  DK_OptimizationRemarkAnalysis,
+  DK_OptimizationFailure,
+  DK_FirstPluginKind
+};
+
+/// \brief Get the next available kind ID for a plugin diagnostic.
+/// Each time this function is called, it returns a different number.
+/// Therefore, a plugin that wants to "identify" its own classes
+/// with a dynamic identifier, just have to use this method to get a new ID
+/// and assign it to each of its classes.
+/// The returned ID will be greater than or equal to DK_FirstPluginKind.
+/// Thus, the plugin identifiers will not conflict with the
+/// DiagnosticKind values.
+int getNextAvailablePluginDiagnosticKind();
+
+/// \brief This is the base abstract class for diagnostic reporting in
+/// the backend.
+/// The print method must be overloaded by the subclasses to print a
+/// user-friendly message in the client of the backend (let us call it a
+/// frontend).
+class DiagnosticInfo {
+private:
+  /// Kind defines the kind of report this is about.
+  const /* DiagnosticKind */ int Kind;
+  /// Severity gives the severity of the diagnostic.
+  const DiagnosticSeverity Severity;
+
+public:
+  DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
+      : Kind(Kind), Severity(Severity) {}
+
+  virtual ~DiagnosticInfo() {}
+
+  /* DiagnosticKind */ int getKind() const { return Kind; }
+  DiagnosticSeverity getSeverity() const { return Severity; }
+
+  /// Print using the given \p DP a user-friendly message.
+  /// This is the default message that will be printed to the user.
+  /// It is used when the frontend does not directly take advantage
+  /// of the information contained in fields of the subclasses.
+  /// The printed message must not end with '.' nor start with a severity
+  /// keyword.
+  virtual void print(DiagnosticPrinter &DP) const = 0;
+};
+
+/// Diagnostic information for inline asm reporting.
+/// This is basically a message and an optional location.
+class DiagnosticInfoInlineAsm : public DiagnosticInfo {
+private:
+  /// Optional line information. 0 if not set.
+  unsigned LocCookie;
+  /// Message to be reported.
+  const Twine &MsgStr;
+  /// Optional origin of the problem.
+  const Instruction *Instr;
+
+public:
+  /// \p MsgStr is the message to be reported to the frontend.
+  /// This class does not copy \p MsgStr, therefore the reference must be valid
+  /// for the whole life time of the Diagnostic.
+  DiagnosticInfoInlineAsm(const Twine &MsgStr,
+                          DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
+        Instr(nullptr) {}
+
+  /// \p LocCookie if non-zero gives the line number for this report.
+  /// \p MsgStr gives the message.
+  /// This class does not copy \p MsgStr, therefore the reference must be valid
+  /// for the whole life time of the Diagnostic.
+  DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
+                          DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
+        MsgStr(MsgStr), Instr(nullptr) {}
+
+  /// \p Instr gives the original instruction that triggered the diagnostic.
+  /// \p MsgStr gives the message.
+  /// This class does not copy \p MsgStr, therefore the reference must be valid
+  /// for the whole life time of the Diagnostic.
+  /// Same for \p I.
+  DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
+                          DiagnosticSeverity Severity = DS_Error);
+
+  unsigned getLocCookie() const { return LocCookie; }
+  const Twine &getMsgStr() const { return MsgStr; }
+  const Instruction *getInstruction() const { return Instr; }
+
+  /// \see DiagnosticInfo::print.
+  void print(DiagnosticPrinter &DP) const override;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_InlineAsm;
+  }
+};
+
+/// Diagnostic information for stack size reporting.
+/// This is basically a function and a size.
+class DiagnosticInfoStackSize : public DiagnosticInfo {
+private:
+  /// The function that is concerned by this stack size diagnostic.
+  const Function &Fn;
+  /// The computed stack size.
+  unsigned StackSize;
+
+public:
+  /// \p The function that is concerned by this stack size diagnostic.
+  /// \p The computed stack size.
+  DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize,
+                          DiagnosticSeverity Severity = DS_Warning)
+      : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {}
+
+  const Function &getFunction() const { return Fn; }
+  unsigned getStackSize() const { return StackSize; }
+
+  /// \see DiagnosticInfo::print.
+  void print(DiagnosticPrinter &DP) const override;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_StackSize;
+  }
+};
+
+/// Diagnostic information for debug metadata version reporting.
+/// This is basically a module and a version.
+class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
+private:
+  /// The module that is concerned by this debug metadata version diagnostic.
+  const Module &M;
+  /// The actual metadata version.
+  unsigned MetadataVersion;
+
+public:
+  /// \p The module that is concerned by this debug metadata version diagnostic.
+  /// \p The actual metadata version.
+  DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
+                          DiagnosticSeverity Severity = DS_Warning)
+      : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
+        MetadataVersion(MetadataVersion) {}
+
+  const Module &getModule() const { return M; }
+  unsigned getMetadataVersion() const { return MetadataVersion; }
+
+  /// \see DiagnosticInfo::print.
+  void print(DiagnosticPrinter &DP) const override;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_DebugMetadataVersion;
+  }
+};
+
+/// Diagnostic information for the sample profiler.
+class DiagnosticInfoSampleProfile : public DiagnosticInfo {
+public:
+  DiagnosticInfoSampleProfile(const char *FileName, unsigned LineNum,
+                              const Twine &Msg,
+                              DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
+        LineNum(LineNum), Msg(Msg) {}
+  DiagnosticInfoSampleProfile(const char *FileName, const Twine &Msg,
+                              DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
+        LineNum(0), Msg(Msg) {}
+  DiagnosticInfoSampleProfile(const Twine &Msg,
+                              DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_SampleProfile, Severity), FileName(nullptr),
+        LineNum(0), Msg(Msg) {}
+
+  /// \see DiagnosticInfo::print.
+  void print(DiagnosticPrinter &DP) const override;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_SampleProfile;
+  }
+
+  const char *getFileName() const { return FileName; }
+  unsigned getLineNum() const { return LineNum; }
+  const Twine &getMsg() const { return Msg; }
+
+private:
+  /// Name of the input file associated with this diagnostic.
+  const char *FileName;
+
+  /// Line number where the diagnostic occurred. If 0, no line number will
+  /// be emitted in the message.
+  unsigned LineNum;
+
+  /// Message to report.
+  const Twine &Msg;
+};
+
+/// Common features for diagnostics dealing with optimization remarks.
+class DiagnosticInfoOptimizationBase : public DiagnosticInfo {
+public:
+  /// \p PassName is the name of the pass emitting this diagnostic.
+  /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
+  /// the location information to use in the diagnostic. If line table
+  /// information is available, the diagnostic will include the source code
+  /// location. \p Msg is the message to show. Note that this class does not
+  /// copy this message, so this reference must be valid for the whole life time
+  /// of the diagnostic.
+  DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
+                                 enum DiagnosticSeverity Severity,
+                                 const char *PassName, const Function &Fn,
+                                 const DebugLoc &DLoc, const Twine &Msg)
+      : DiagnosticInfo(Kind, Severity), PassName(PassName), Fn(Fn), DLoc(DLoc),
+        Msg(Msg) {}
+
+  /// \see DiagnosticInfo::print.
+  void print(DiagnosticPrinter &DP) const override;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_OptimizationRemark;
+  }
+
+  /// Return true if this optimization remark is enabled by one of
+  /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
+  /// or -pass-remarks-analysis). Note that this only handles the LLVM
+  /// flags. We cannot access Clang flags from here (they are handled
+  /// in BackendConsumer::OptimizationRemarkHandler).
+  virtual bool isEnabled() const = 0;
+
+  /// Return true if location information is available for this diagnostic.
+  bool isLocationAvailable() const;
+
+  /// Return a string with the location information for this diagnostic
+  /// in the format "file:line:col". If location information is not available,
+  /// it returns "<unknown>:0:0".
+  const std::string getLocationStr() const;
+
+  /// Return location information for this diagnostic in three parts:
+  /// the source file name, line number and column.
+  void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
+
+  const char *getPassName() const { return PassName; }
+  const Function &getFunction() const { return Fn; }
+  const DebugLoc &getDebugLoc() const { return DLoc; }
+  const Twine &getMsg() const { return Msg; }
+
+private:
+  /// Name of the pass that triggers this report. If this matches the
+  /// regular expression given in -Rpass=regexp, then the remark will
+  /// be emitted.
+  const char *PassName;
+
+  /// Function where this diagnostic is triggered.
+  const Function &Fn;
+
+  /// Debug location where this diagnostic is triggered.
+  DebugLoc DLoc;
+
+  /// Message to report.
+  const Twine &Msg;
+};
+
+/// Diagnostic information for applied optimization remarks.
+class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase {
+public:
+  /// \p PassName is the name of the pass emitting this diagnostic. If
+  /// this name matches the regular expression given in -Rpass=, then the
+  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
+  /// is being emitted. \p DLoc is the location information to use in the
+  /// diagnostic. If line table information is available, the diagnostic
+  /// will include the source code location. \p Msg is the message to show.
+  /// Note that this class does not copy this message, so this reference
+  /// must be valid for the whole life time of the diagnostic.
+  DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn,
+                                   const DebugLoc &DLoc, const Twine &Msg)
+      : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
+                                       PassName, Fn, DLoc, Msg) {}
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_OptimizationRemark;
+  }
+
+  /// \see DiagnosticInfoOptimizationBase::isEnabled.
+  virtual bool isEnabled() const override;
+};
+
+/// Diagnostic information for missed-optimization remarks.
+class DiagnosticInfoOptimizationRemarkMissed
+    : public DiagnosticInfoOptimizationBase {
+public:
+  /// \p PassName is the name of the pass emitting this diagnostic. If
+  /// this name matches the regular expression given in -Rpass-missed=, then the
+  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
+  /// is being emitted. \p DLoc is the location information to use in the
+  /// diagnostic. If line table information is available, the diagnostic
+  /// will include the source code location. \p Msg is the message to show.
+  /// Note that this class does not copy this message, so this reference
+  /// must be valid for the whole life time of the diagnostic.
+  DiagnosticInfoOptimizationRemarkMissed(const char *PassName,
+                                         const Function &Fn,
+                                         const DebugLoc &DLoc, const Twine &Msg)
+      : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
+                                       PassName, Fn, DLoc, Msg) {}
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_OptimizationRemarkMissed;
+  }
+
+  /// \see DiagnosticInfoOptimizationBase::isEnabled.
+  virtual bool isEnabled() const override;
+};
+
+/// Diagnostic information for optimization analysis remarks.
+class DiagnosticInfoOptimizationRemarkAnalysis
+    : public DiagnosticInfoOptimizationBase {
+public:
+  /// \p PassName is the name of the pass emitting this diagnostic. If
+  /// this name matches the regular expression given in -Rpass-analysis=, then
+  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
+  /// is being emitted. \p DLoc is the location information to use in the
+  /// diagnostic. If line table information is available, the diagnostic will
+  /// include the source code location. \p Msg is the message to show. Note that
+  /// this class does not copy this message, so this reference must be valid for
+  /// the whole life time of the diagnostic.
+  DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName,
+                                           const Function &Fn,
+                                           const DebugLoc &DLoc,
+                                           const Twine &Msg)
+      : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
+                                       PassName, Fn, DLoc, Msg) {}
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_OptimizationRemarkAnalysis;
+  }
+
+  /// \see DiagnosticInfoOptimizationBase::isEnabled.
+  virtual bool isEnabled() const override;
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
+
+/// Emit an optimization-applied message. \p PassName is the name of the pass
+/// emitting the message. If -Rpass= is given and \p PassName matches the
+/// regular expression in -Rpass, then the remark will be emitted. \p Fn is
+/// the function triggering the remark, \p DLoc is the debug location where
+/// the diagnostic is generated. \p Msg is the message string to use.
+void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
+                            const Function &Fn, const DebugLoc &DLoc,
+                            const Twine &Msg);
+
+/// Emit an optimization-missed message. \p PassName is the name of the
+/// pass emitting the message. If -Rpass-missed= is given and \p PassName
+/// matches the regular expression in -Rpass, then the remark will be
+/// emitted. \p Fn is the function triggering the remark, \p DLoc is the
+/// debug location where the diagnostic is generated. \p Msg is the
+/// message string to use.
+void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
+                                  const Function &Fn, const DebugLoc &DLoc,
+                                  const Twine &Msg);
+
+/// Emit an optimization analysis remark message. \p PassName is the name of
+/// the pass emitting the message. If -Rpass-analysis= is given and \p
+/// PassName matches the regular expression in -Rpass, then the remark will be
+/// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
+/// location where the diagnostic is generated. \p Msg is the message string
+/// to use.
+void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
+                                    const Function &Fn, const DebugLoc &DLoc,
+                                    const Twine &Msg);
+
+/// Diagnostic information for optimization failures.
+class DiagnosticInfoOptimizationFailure
+    : public DiagnosticInfoOptimizationBase {
+public:
+  /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
+  /// the location information to use in the diagnostic. If line table
+  /// information is available, the diagnostic will include the source code
+  /// location. \p Msg is the message to show. Note that this class does not
+  /// copy this message, so this reference must be valid for the whole life time
+  /// of the diagnostic.
+  DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
+                                    const Twine &Msg)
+      : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
+                                       nullptr, Fn, DLoc, Msg) {}
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_OptimizationFailure;
+  }
+
+  /// \see DiagnosticInfoOptimizationBase::isEnabled.
+  virtual bool isEnabled() const override;
+};
+
+/// Emit a warning when loop vectorization is specified but fails. \p Fn is the
+/// function triggering the warning, \p DLoc is the debug location where the
+/// diagnostic is generated. \p Msg is the message string to use.
+void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
+                              const DebugLoc &DLoc, const Twine &Msg);
+
+/// Emit a warning when loop interleaving is specified but fails. \p Fn is the
+/// function triggering the warning, \p DLoc is the debug location where the
+/// diagnostic is generated. \p Msg is the message string to use.
+void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
+                               const DebugLoc &DLoc, const Twine &Msg);
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/IR/DiagnosticPrinter.h b/include/llvm/IR/DiagnosticPrinter.h
new file mode 100644
index 0000000..411c781
--- /dev/null
+++ b/include/llvm/IR/DiagnosticPrinter.h
@@ -0,0 +1,87 @@
+//===- llvm/Support/DiagnosticPrinter.h - Diagnostic Printer ----*- 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 main interface for printer backend diagnostic.
+//
+// Clients of the backend diagnostics should overload this interface based
+// on their needs.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DIAGNOSTICPRINTER_H
+#define LLVM_SUPPORT_DIAGNOSTICPRINTER_H
+
+#include <string>
+
+namespace llvm {
+// Forward declarations.
+class Module;
+class raw_ostream;
+class StringRef;
+class Twine;
+class Value;
+
+/// \brief Interface for custom diagnostic printing.
+class DiagnosticPrinter {
+public:
+  virtual ~DiagnosticPrinter() {}
+
+  // Simple types.
+  virtual DiagnosticPrinter &operator<<(char C) = 0;
+  virtual DiagnosticPrinter &operator<<(unsigned char C) = 0;
+  virtual DiagnosticPrinter &operator<<(signed char C) = 0;
+  virtual DiagnosticPrinter &operator<<(StringRef Str) = 0;
+  virtual DiagnosticPrinter &operator<<(const char *Str) = 0;
+  virtual DiagnosticPrinter &operator<<(const std::string &Str) = 0;
+  virtual DiagnosticPrinter &operator<<(unsigned long N) = 0;
+  virtual DiagnosticPrinter &operator<<(long N) = 0;
+  virtual DiagnosticPrinter &operator<<(unsigned long long N) = 0;
+  virtual DiagnosticPrinter &operator<<(long long N) = 0;
+  virtual DiagnosticPrinter &operator<<(const void *P) = 0;
+  virtual DiagnosticPrinter &operator<<(unsigned int N) = 0;
+  virtual DiagnosticPrinter &operator<<(int N) = 0;
+  virtual DiagnosticPrinter &operator<<(double N) = 0;
+  virtual DiagnosticPrinter &operator<<(const Twine &Str) = 0;
+
+  // IR related types.
+  virtual DiagnosticPrinter &operator<<(const Value &V) = 0;
+  virtual DiagnosticPrinter &operator<<(const Module &M) = 0;
+};
+
+/// \brief Basic diagnostic printer that uses an underlying raw_ostream.
+class DiagnosticPrinterRawOStream : public DiagnosticPrinter {
+protected:
+  raw_ostream &Stream;
+
+public:
+  DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {};
+
+  // Simple types.
+  DiagnosticPrinter &operator<<(char C) override;
+  DiagnosticPrinter &operator<<(unsigned char C) override;
+  DiagnosticPrinter &operator<<(signed char C) override;
+  DiagnosticPrinter &operator<<(StringRef Str) override;
+  DiagnosticPrinter &operator<<(const char *Str) override;
+  DiagnosticPrinter &operator<<(const std::string &Str) override;
+  DiagnosticPrinter &operator<<(unsigned long N) override;
+  DiagnosticPrinter &operator<<(long N) override;
+  DiagnosticPrinter &operator<<(unsigned long long N) override;
+  DiagnosticPrinter &operator<<(long long N) override;
+  DiagnosticPrinter &operator<<(const void *P) override;
+  DiagnosticPrinter &operator<<(unsigned int N) override;
+  DiagnosticPrinter &operator<<(int N) override;
+  DiagnosticPrinter &operator<<(double N) override;
+  DiagnosticPrinter &operator<<(const Twine &Str) override;
+
+  // IR related types.
+  DiagnosticPrinter &operator<<(const Value &V) override;
+  DiagnosticPrinter &operator<<(const Module &M) override;
+};
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
new file mode 100644
index 0000000..e2d1ccc
--- /dev/null
+++ b/include/llvm/IR/Dominators.h
@@ -0,0 +1,186 @@
+//===- Dominators.h - Dominator Info Calculation ----------------*- 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 DominatorTree class, which provides fast and efficient
+// dominance queries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DOMINATORS_H
+#define LLVM_IR_DOMINATORS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+
+#define LLVM_COMMA ,
+EXTERN_TEMPLATE_INSTANTIATION(void Calculate<Function LLVM_COMMA BasicBlock *>(
+    DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA
+        Function &F));
+EXTERN_TEMPLATE_INSTANTIATION(
+    void Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >(
+        DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT
+            LLVM_COMMA Function &F));
+#undef LLVM_COMMA
+
+typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
+
+class BasicBlockEdge {
+  const BasicBlock *Start;
+  const BasicBlock *End;
+public:
+  BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
+    Start(Start_), End(End_) { }
+  const BasicBlock *getStart() const {
+    return Start;
+  }
+  const BasicBlock *getEnd() const {
+    return End;
+  }
+  bool isSingleEdge() const;
+};
+
+/// \brief Concrete subclass of DominatorTreeBase that is used to compute a
+/// normal dominator tree.
+class DominatorTree : public DominatorTreeBase<BasicBlock> {
+public:
+  typedef DominatorTreeBase<BasicBlock> Base;
+
+  DominatorTree() : DominatorTreeBase<BasicBlock>(false) {}
+
+  /// \brief Returns *false* if the other dominator tree matches this dominator
+  /// tree.
+  inline bool compare(const DominatorTree &Other) const {
+    const DomTreeNode *R = getRootNode();
+    const DomTreeNode *OtherR = Other.getRootNode();
+
+    if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
+      return true;
+
+    if (Base::compare(Other))
+      return true;
+
+    return false;
+  }
+
+  // Ensure base-class overloads are visible.
+  using Base::dominates;
+
+  /// \brief Return true if Def dominates a use in User.
+  ///
+  /// This performs the special checks necessary if Def and User are in the same
+  /// basic block. Note that Def doesn't dominate a use in Def itself!
+  bool dominates(const Instruction *Def, const Use &U) const;
+  bool dominates(const Instruction *Def, const Instruction *User) const;
+  bool dominates(const Instruction *Def, const BasicBlock *BB) const;
+  bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
+  bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
+
+  // Ensure base class overloads are visible.
+  using Base::isReachableFromEntry;
+
+  /// \brief Provide an overload for a Use.
+  bool isReachableFromEntry(const Use &U) const;
+
+  /// \brief Verify the correctness of the domtree by re-computing it.
+  ///
+  /// This should only be used for debugging as it aborts the program if the
+  /// verification fails.
+  void verifyDomTree() const;
+};
+
+//===-------------------------------------
+// DominatorTree GraphTraits specializations so the DominatorTree can be
+// iterable by generic graph iterators.
+
+template <> struct GraphTraits<DomTreeNode*> {
+  typedef DomTreeNode NodeType;
+  typedef NodeType::iterator  ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) {
+    return N;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+
+  typedef df_iterator<DomTreeNode*> nodes_iterator;
+
+  static nodes_iterator nodes_begin(DomTreeNode *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(DomTreeNode *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+
+template <> struct GraphTraits<DominatorTree*>
+  : public GraphTraits<DomTreeNode*> {
+  static NodeType *getEntryNode(DominatorTree *DT) {
+    return DT->getRootNode();
+  }
+
+  static nodes_iterator nodes_begin(DominatorTree *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(DominatorTree *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+
+/// \brief Analysis pass which computes a \c DominatorTree.
+class DominatorTreeWrapperPass : public FunctionPass {
+  DominatorTree DT;
+
+public:
+  static char ID;
+
+  DominatorTreeWrapperPass() : FunctionPass(ID) {
+    initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
+  }
+
+  DominatorTree &getDomTree() { return DT; }
+  const DominatorTree &getDomTree() const { return DT; }
+
+  bool runOnFunction(Function &F) override;
+
+  void verifyAnalysis() const override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  void releaseMemory() override { DT.releaseMemory(); }
+
+  void print(raw_ostream &OS, const Module *M = nullptr) const override;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
new file mode 100644
index 0000000..ad4b139
--- /dev/null
+++ b/include/llvm/IR/Function.h
@@ -0,0 +1,524 @@
+//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Function class, which represents a
+// single function/procedure in LLVM.
+//
+// A function basically consists of a list of basic blocks, a list of arguments,
+// and a symbol table.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_FUNCTION_H
+#define LLVM_IR_FUNCTION_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class FunctionType;
+class LLVMContext;
+
+// Traits for intrusive list of basic blocks...
+template<> struct ilist_traits<BasicBlock>
+  : public SymbolTableListTraits<BasicBlock, Function> {
+
+  // createSentinel is used to get hold of the node that marks the end of the
+  // list... (same trick used here as in ilist_traits<Instruction>)
+  BasicBlock *createSentinel() const {
+    return static_cast<BasicBlock*>(&Sentinel);
+  }
+  static void destroySentinel(BasicBlock*) {}
+
+  BasicBlock *provideInitialHead() const { return createSentinel(); }
+  BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
+  static void noteHead(BasicBlock*, BasicBlock*) {}
+
+  static ValueSymbolTable *getSymTab(Function *ItemParent);
+private:
+  mutable ilist_half_node<BasicBlock> Sentinel;
+};
+
+template<> struct ilist_traits<Argument>
+  : public SymbolTableListTraits<Argument, Function> {
+
+  Argument *createSentinel() const {
+    return static_cast<Argument*>(&Sentinel);
+  }
+  static void destroySentinel(Argument*) {}
+
+  Argument *provideInitialHead() const { return createSentinel(); }
+  Argument *ensureHead(Argument*) const { return createSentinel(); }
+  static void noteHead(Argument*, Argument*) {}
+
+  static ValueSymbolTable *getSymTab(Function *ItemParent);
+private:
+  mutable ilist_half_node<Argument> Sentinel;
+};
+
+class Function : public GlobalObject, public ilist_node<Function> {
+public:
+  typedef iplist<Argument> ArgumentListType;
+  typedef iplist<BasicBlock> BasicBlockListType;
+
+  // BasicBlock iterators...
+  typedef BasicBlockListType::iterator iterator;
+  typedef BasicBlockListType::const_iterator const_iterator;
+
+  typedef ArgumentListType::iterator arg_iterator;
+  typedef ArgumentListType::const_iterator const_arg_iterator;
+
+private:
+  // Important things that make up a function!
+  BasicBlockListType  BasicBlocks;        ///< The basic blocks
+  mutable ArgumentListType ArgumentList;  ///< The formal arguments
+  ValueSymbolTable *SymTab;               ///< Symbol table of args/instructions
+  AttributeSet AttributeSets;             ///< Parameter attributes
+
+  // HasLazyArguments is stored in Value::SubclassData.
+  /*bool HasLazyArguments;*/
+
+  // The Calling Convention is stored in Value::SubclassData.
+  /*CallingConv::ID CallingConvention;*/
+
+  friend class SymbolTableListTraits<Function, Module>;
+
+  void setParent(Module *parent);
+
+  /// hasLazyArguments/CheckLazyArguments - The argument list of a function is
+  /// built on demand, so that the list isn't allocated until the first client
+  /// needs it.  The hasLazyArguments predicate returns true if the arg list
+  /// hasn't been set up yet.
+  bool hasLazyArguments() const {
+    return getSubclassDataFromValue() & 1;
+  }
+  void CheckLazyArguments() const {
+    if (hasLazyArguments())
+      BuildLazyArguments();
+  }
+  void BuildLazyArguments() const;
+
+  Function(const Function&) LLVM_DELETED_FUNCTION;
+  void operator=(const Function&) LLVM_DELETED_FUNCTION;
+
+  /// Do the actual lookup of an intrinsic ID when the query could not be
+  /// answered from the cache.
+  unsigned lookupIntrinsicID() const LLVM_READONLY;
+
+  /// Function ctor - If the (optional) Module argument is specified, the
+  /// function is automatically inserted into the end of the function list for
+  /// the module.
+  ///
+  Function(FunctionType *Ty, LinkageTypes Linkage,
+           const Twine &N = "", Module *M = nullptr);
+
+public:
+  static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
+                          const Twine &N = "", Module *M = nullptr) {
+    return new(0) Function(Ty, Linkage, N, M);
+  }
+
+  ~Function();
+
+  Type *getReturnType() const;           // Return the type of the ret val
+  FunctionType *getFunctionType() const; // Return the FunctionType for me
+
+  /// getContext - Return a pointer to the LLVMContext associated with this
+  /// function, or NULL if this function is not bound to a context yet.
+  LLVMContext &getContext() const;
+
+  /// isVarArg - Return true if this function takes a variable number of
+  /// arguments.
+  bool isVarArg() const;
+
+  /// getIntrinsicID - This method returns the ID number of the specified
+  /// function, or Intrinsic::not_intrinsic if the function is not an
+  /// intrinsic, or if the pointer is null.  This value is always defined to be
+  /// zero to allow easy checking for whether a function is intrinsic or not.
+  /// The particular intrinsic functions which correspond to this value are
+  /// defined in llvm/Intrinsics.h.  Results are cached in the LLVM context,
+  /// subsequent requests for the same ID return results much faster from the
+  /// cache.
+  ///
+  unsigned getIntrinsicID() const LLVM_READONLY;
+  bool isIntrinsic() const { return getName().startswith("llvm."); }
+
+  /// getCallingConv()/setCallingConv(CC) - These method get and set the
+  /// calling convention of this function.  The enum values for the known
+  /// calling conventions are defined in CallingConv.h.
+  CallingConv::ID getCallingConv() const {
+    return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 2);
+  }
+  void setCallingConv(CallingConv::ID CC) {
+    setValueSubclassData((getSubclassDataFromValue() & 3) |
+                         (static_cast<unsigned>(CC) << 2));
+  }
+
+  /// @brief Return the attribute list for this Function.
+  AttributeSet getAttributes() const { return AttributeSets; }
+
+  /// @brief Set the attribute list for this Function.
+  void setAttributes(AttributeSet attrs) { AttributeSets = attrs; }
+
+  /// @brief Add function attributes to this function.
+  void addFnAttr(Attribute::AttrKind N) {
+    setAttributes(AttributeSets.addAttribute(getContext(),
+                                             AttributeSet::FunctionIndex, N));
+  }
+
+  /// @brief Remove function attributes from this function.
+  void removeFnAttr(Attribute::AttrKind N) {
+    setAttributes(AttributeSets.removeAttribute(
+        getContext(), AttributeSet::FunctionIndex, N));
+  }
+
+  /// @brief Add function attributes to this function.
+  void addFnAttr(StringRef Kind) {
+    setAttributes(
+      AttributeSets.addAttribute(getContext(),
+                                 AttributeSet::FunctionIndex, Kind));
+  }
+  void addFnAttr(StringRef Kind, StringRef Value) {
+    setAttributes(
+      AttributeSets.addAttribute(getContext(),
+                                 AttributeSet::FunctionIndex, Kind, Value));
+  }
+
+  /// @brief Return true if the function has the attribute.
+  bool hasFnAttribute(Attribute::AttrKind Kind) const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
+  }
+  bool hasFnAttribute(StringRef Kind) const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
+  }
+
+  /// @brief Return the attribute for the given attribute kind.
+  Attribute getFnAttribute(Attribute::AttrKind Kind) const {
+    return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+  }
+  Attribute getFnAttribute(StringRef Kind) const {
+    return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
+  }
+
+  /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
+  ///                             to use during code generation.
+  bool hasGC() const;
+  const char *getGC() const;
+  void setGC(const char *Str);
+  void clearGC();
+
+  /// @brief adds the attribute to the list of attributes.
+  void addAttribute(unsigned i, Attribute::AttrKind attr);
+
+  /// @brief adds the attributes to the list of attributes.
+  void addAttributes(unsigned i, AttributeSet attrs);
+
+  /// @brief removes the attributes from the list of attributes.
+  void removeAttributes(unsigned i, AttributeSet attr);
+
+  /// @brief Extract the alignment for a call or parameter (0=unknown).
+  unsigned getParamAlignment(unsigned i) const {
+    return AttributeSets.getParamAlignment(i);
+  }
+
+  /// @brief Extract the number of dereferenceable bytes for a call or
+  /// parameter (0=unknown).
+  uint64_t getDereferenceableBytes(unsigned i) const {
+    return AttributeSets.getDereferenceableBytes(i);
+  }
+
+  /// @brief Determine if the function does not access memory.
+  bool doesNotAccessMemory() const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                      Attribute::ReadNone);
+  }
+  void setDoesNotAccessMemory() {
+    addFnAttr(Attribute::ReadNone);
+  }
+
+  /// @brief Determine if the function does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    return doesNotAccessMemory() ||
+      AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                 Attribute::ReadOnly);
+  }
+  void setOnlyReadsMemory() {
+    addFnAttr(Attribute::ReadOnly);
+  }
+
+  /// @brief Determine if the function cannot return.
+  bool doesNotReturn() const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                      Attribute::NoReturn);
+  }
+  void setDoesNotReturn() {
+    addFnAttr(Attribute::NoReturn);
+  }
+
+  /// @brief Determine if the function cannot unwind.
+  bool doesNotThrow() const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                      Attribute::NoUnwind);
+  }
+  void setDoesNotThrow() {
+    addFnAttr(Attribute::NoUnwind);
+  }
+
+  /// @brief Determine if the call cannot be duplicated.
+  bool cannotDuplicate() const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                      Attribute::NoDuplicate);
+  }
+  void setCannotDuplicate() {
+    addFnAttr(Attribute::NoDuplicate);
+  }
+
+  /// @brief True if the ABI mandates (or the user requested) that this
+  /// function be in a unwind table.
+  bool hasUWTable() const {
+    return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+                                      Attribute::UWTable);
+  }
+  void setHasUWTable() {
+    addFnAttr(Attribute::UWTable);
+  }
+
+  /// @brief True if this function needs an unwind table.
+  bool needsUnwindTableEntry() const {
+    return hasUWTable() || !doesNotThrow();
+  }
+
+  /// @brief Determine if the function returns a structure through first
+  /// pointer argument.
+  bool hasStructRetAttr() const {
+    return AttributeSets.hasAttribute(1, Attribute::StructRet) ||
+           AttributeSets.hasAttribute(2, Attribute::StructRet);
+  }
+
+  /// @brief Determine if the parameter does not alias other parameters.
+  /// @param n The parameter to check. 1 is the first parameter, 0 is the return
+  bool doesNotAlias(unsigned n) const {
+    return AttributeSets.hasAttribute(n, Attribute::NoAlias);
+  }
+  void setDoesNotAlias(unsigned n) {
+    addAttribute(n, Attribute::NoAlias);
+  }
+
+  /// @brief Determine if the parameter can be captured.
+  /// @param n The parameter to check. 1 is the first parameter, 0 is the return
+  bool doesNotCapture(unsigned n) const {
+    return AttributeSets.hasAttribute(n, Attribute::NoCapture);
+  }
+  void setDoesNotCapture(unsigned n) {
+    addAttribute(n, Attribute::NoCapture);
+  }
+
+  bool doesNotAccessMemory(unsigned n) const {
+    return AttributeSets.hasAttribute(n, Attribute::ReadNone);
+  }
+  void setDoesNotAccessMemory(unsigned n) {
+    addAttribute(n, Attribute::ReadNone);
+  }
+
+  bool onlyReadsMemory(unsigned n) const {
+    return doesNotAccessMemory(n) ||
+      AttributeSets.hasAttribute(n, Attribute::ReadOnly);
+  }
+  void setOnlyReadsMemory(unsigned n) {
+    addAttribute(n, Attribute::ReadOnly);
+  }
+
+  /// copyAttributesFrom - copy all additional attributes (those not needed to
+  /// create a Function) from the Function Src to this one.
+  void copyAttributesFrom(const GlobalValue *Src) override;
+
+  /// deleteBody - This method deletes the body of the function, and converts
+  /// the linkage to external.
+  ///
+  void deleteBody() {
+    dropAllReferences();
+    setLinkage(ExternalLinkage);
+  }
+
+  /// removeFromParent - This method unlinks 'this' from the containing module,
+  /// but does not delete it.
+  ///
+  void removeFromParent() override;
+
+  /// eraseFromParent - This method unlinks 'this' from the containing module
+  /// and deletes it.
+  ///
+  void eraseFromParent() override;
+
+
+  /// Get the underlying elements of the Function... the basic block list is
+  /// empty for external functions.
+  ///
+  const ArgumentListType &getArgumentList() const {
+    CheckLazyArguments();
+    return ArgumentList;
+  }
+  ArgumentListType &getArgumentList() {
+    CheckLazyArguments();
+    return ArgumentList;
+  }
+  static iplist<Argument> Function::*getSublistAccess(Argument*) {
+    return &Function::ArgumentList;
+  }
+
+  const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
+        BasicBlockListType &getBasicBlockList()       { return BasicBlocks; }
+  static iplist<BasicBlock> Function::*getSublistAccess(BasicBlock*) {
+    return &Function::BasicBlocks;
+  }
+
+  const BasicBlock       &getEntryBlock() const   { return front(); }
+        BasicBlock       &getEntryBlock()         { return front(); }
+
+  //===--------------------------------------------------------------------===//
+  // Symbol Table Accessing functions...
+
+  /// getSymbolTable() - Return the symbol table...
+  ///
+  inline       ValueSymbolTable &getValueSymbolTable()       { return *SymTab; }
+  inline const ValueSymbolTable &getValueSymbolTable() const { return *SymTab; }
+
+
+  //===--------------------------------------------------------------------===//
+  // BasicBlock iterator forwarding functions
+  //
+  iterator                begin()       { return BasicBlocks.begin(); }
+  const_iterator          begin() const { return BasicBlocks.begin(); }
+  iterator                end  ()       { return BasicBlocks.end();   }
+  const_iterator          end  () const { return BasicBlocks.end();   }
+
+  size_t                   size() const { return BasicBlocks.size();  }
+  bool                    empty() const { return BasicBlocks.empty(); }
+  const BasicBlock       &front() const { return BasicBlocks.front(); }
+        BasicBlock       &front()       { return BasicBlocks.front(); }
+  const BasicBlock        &back() const { return BasicBlocks.back();  }
+        BasicBlock        &back()       { return BasicBlocks.back();  }
+
+/// @name Function Argument Iteration
+/// @{
+
+  arg_iterator arg_begin() {
+    CheckLazyArguments();
+    return ArgumentList.begin();
+  }
+  const_arg_iterator arg_begin() const {
+    CheckLazyArguments();
+    return ArgumentList.begin();
+  }
+  arg_iterator arg_end() {
+    CheckLazyArguments();
+    return ArgumentList.end();
+  }
+  const_arg_iterator arg_end() const {
+    CheckLazyArguments();
+    return ArgumentList.end();
+  }
+
+  iterator_range<arg_iterator> args() {
+    return iterator_range<arg_iterator>(arg_begin(), arg_end());
+  }
+
+  iterator_range<const_arg_iterator> args() const {
+    return iterator_range<const_arg_iterator>(arg_begin(), arg_end());
+  }
+
+/// @}
+
+  size_t arg_size() const;
+  bool arg_empty() const;
+
+  bool hasPrefixData() const {
+    return getSubclassDataFromValue() & 2;
+  }
+
+  Constant *getPrefixData() const;
+  void setPrefixData(Constant *PrefixData);
+
+  /// viewCFG - This function is meant for use from the debugger.  You can just
+  /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+  /// program, displaying the CFG of the current function with the code for each
+  /// basic block inside.  This depends on there being a 'dot' and 'gv' program
+  /// in your path.
+  ///
+  void viewCFG() const;
+
+  /// viewCFGOnly - This function is meant for use from the debugger.  It works
+  /// just like viewCFG, but it does not include the contents of basic blocks
+  /// into the nodes, just the label.  If you are only interested in the CFG
+  /// this can make the graph smaller.
+  ///
+  void viewCFGOnly() const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::FunctionVal;
+  }
+
+  /// dropAllReferences() - This method causes all the subinstructions to "let
+  /// go" of all references that they are maintaining.  This allows one to
+  /// 'delete' a whole module at a time, even though there may be circular
+  /// references... first all references are dropped, and all use counts go to
+  /// zero.  Then everything is deleted for real.  Note that no operations are
+  /// valid on an object that has "dropped all references", except operator
+  /// delete.
+  ///
+  /// Since no other object in the module can have references into the body of a
+  /// function, dropping all references deletes the entire body of the function,
+  /// including any contained basic blocks.
+  ///
+  void dropAllReferences();
+
+  /// hasAddressTaken - returns true if there are any uses of this function
+  /// other than direct calls or invokes to it, or blockaddress expressions.
+  /// Optionally passes back an offending user for diagnostic purposes.
+  ///
+  bool hasAddressTaken(const User** = nullptr) const;
+
+  /// isDefTriviallyDead - Return true if it is trivially safe to remove
+  /// this function definition from the module (because it isn't externally
+  /// visible, does not have its address taken, and has no callers).  To make
+  /// this more accurate, call removeDeadConstantUsers first.
+  bool isDefTriviallyDead() const;
+
+  /// callsFunctionThatReturnsTwice - Return true if the function has a call to
+  /// setjmp or other function that gcc recognizes as "returning twice".
+  bool callsFunctionThatReturnsTwice() const;
+
+private:
+  // Shadow Value::setValueSubclassData with a private forwarding method so that
+  // subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+};
+
+inline ValueSymbolTable *
+ilist_traits<BasicBlock>::getSymTab(Function *F) {
+  return F ? &F->getValueSymbolTable() : nullptr;
+}
+
+inline ValueSymbolTable *
+ilist_traits<Argument>::getSymTab(Function *F) {
+  return F ? &F->getValueSymbolTable() : nullptr;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
new file mode 100644
index 0000000..a1216a1
--- /dev/null
+++ b/include/llvm/IR/GVMaterializer.h
@@ -0,0 +1,63 @@
+//===- GVMaterializer.h - Interface for GV materializers --------*- 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 an abstract interface for loading a module from some
+// place.  This interface allows incremental or random access loading of
+// functions from the file.  This is useful for applications like JIT compilers
+// or interprocedural optimizers that do not need the entire program in memory
+// at the same time.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GVMATERIALIZER_H
+#define LLVM_IR_GVMATERIALIZER_H
+
+#include <system_error>
+
+namespace llvm {
+class Function;
+class GlobalValue;
+class Module;
+
+class GVMaterializer {
+protected:
+  GVMaterializer() {}
+
+public:
+  virtual ~GVMaterializer();
+
+  /// True if GV can be materialized from whatever backing store this
+  /// GVMaterializer uses and has not been materialized yet.
+  virtual bool isMaterializable(const GlobalValue *GV) const = 0;
+
+  /// True if GV has been materialized and can be dematerialized back to
+  /// whatever backing store this GVMaterializer uses.
+  virtual bool isDematerializable(const GlobalValue *GV) const = 0;
+
+  /// Make sure the given GlobalValue is fully read.
+  ///
+  virtual std::error_code Materialize(GlobalValue *GV) = 0;
+
+  /// If the given GlobalValue is read in, and if the GVMaterializer supports
+  /// it, release the memory for the GV, and set it up to be materialized
+  /// lazily. If the Materializer doesn't support this capability, this method
+  /// is a noop.
+  ///
+  virtual void Dematerialize(GlobalValue *) {}
+
+  /// Make sure the entire Module has been completely read.
+  ///
+  virtual std::error_code MaterializeModule(Module *M) = 0;
+
+  virtual void releaseBuffer() = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h
new file mode 100644
index 0000000..dcf8e64
--- /dev/null
+++ b/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -0,0 +1,113 @@
+//===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an iterator for walking through the types indexed by
+// getelementptr instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
+#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
+
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/User.h"
+
+namespace llvm {
+  template<typename ItTy = User::const_op_iterator>
+  class generic_gep_type_iterator
+    : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
+    typedef std::iterator<std::forward_iterator_tag,
+                          Type *, ptrdiff_t> super;
+
+    ItTy OpIt;
+    Type *CurTy;
+    generic_gep_type_iterator() {}
+  public:
+
+    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
+      generic_gep_type_iterator I;
+      I.CurTy = Ty;
+      I.OpIt = It;
+      return I;
+    }
+    static generic_gep_type_iterator end(ItTy It) {
+      generic_gep_type_iterator I;
+      I.CurTy = nullptr;
+      I.OpIt = It;
+      return I;
+    }
+
+    bool operator==(const generic_gep_type_iterator& x) const {
+      return OpIt == x.OpIt;
+    }
+    bool operator!=(const generic_gep_type_iterator& x) const {
+      return !operator==(x);
+    }
+
+    Type *operator*() const {
+      return CurTy;
+    }
+
+    Type *getIndexedType() const {
+      CompositeType *CT = cast<CompositeType>(CurTy);
+      return CT->getTypeAtIndex(getOperand());
+    }
+
+    // This is a non-standard operator->.  It allows you to call methods on the
+    // current type directly.
+    Type *operator->() const { return operator*(); }
+
+    Value *getOperand() const { return *OpIt; }
+
+    generic_gep_type_iterator& operator++() {   // Preincrement
+      if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+        CurTy = CT->getTypeAtIndex(getOperand());
+      } else {
+        CurTy = nullptr;
+      }
+      ++OpIt;
+      return *this;
+    }
+
+    generic_gep_type_iterator operator++(int) { // Postincrement
+      generic_gep_type_iterator tmp = *this; ++*this; return tmp;
+    }
+  };
+
+  typedef generic_gep_type_iterator<> gep_type_iterator;
+
+  inline gep_type_iterator gep_type_begin(const User *GEP) {
+    return gep_type_iterator::begin
+      (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
+  }
+  inline gep_type_iterator gep_type_end(const User *GEP) {
+    return gep_type_iterator::end(GEP->op_end());
+  }
+  inline gep_type_iterator gep_type_begin(const User &GEP) {
+    return gep_type_iterator::begin
+      (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
+  }
+  inline gep_type_iterator gep_type_end(const User &GEP) {
+    return gep_type_iterator::end(GEP.op_end());
+  }
+
+  template<typename T>
+  inline generic_gep_type_iterator<const T *>
+  gep_type_begin(Type *Op0, ArrayRef<T> A) {
+    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
+  }
+
+  template<typename T>
+  inline generic_gep_type_iterator<const T *>
+  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
+    return generic_gep_type_iterator<const T *>::end(A.end());
+  }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
new file mode 100644
index 0000000..075b570
--- /dev/null
+++ b/include/llvm/IR/GlobalAlias.h
@@ -0,0 +1,125 @@
+//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalAlias class, which
+// represents a single function or variable alias in the IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GLOBALALIAS_H
+#define LLVM_IR_GLOBALALIAS_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/OperandTraits.h"
+
+namespace llvm {
+
+class Module;
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
+  friend class SymbolTableListTraits<GlobalAlias, Module>;
+  void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION;
+  GlobalAlias(const GlobalAlias &) LLVM_DELETED_FUNCTION;
+
+  void setParent(Module *parent);
+
+  GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
+              const Twine &Name, Constant *Aliasee, Module *Parent);
+
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+
+  /// If a parent module is specified, the alias is automatically inserted into
+  /// the end of the specified module's alias list.
+  static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
+                             LinkageTypes Linkage, const Twine &Name,
+                             Constant *Aliasee, Module *Parent);
+
+  // Without the Aliasee.
+  static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
+                             LinkageTypes Linkage, const Twine &Name,
+                             Module *Parent);
+
+  // The module is taken from the Aliasee.
+  static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
+                             LinkageTypes Linkage, const Twine &Name,
+                             GlobalValue *Aliasee);
+
+  // Type, Parent and AddressSpace taken from the Aliasee.
+  static GlobalAlias *create(LinkageTypes Linkage, const Twine &Name,
+                             GlobalValue *Aliasee);
+
+  // Linkage, Type, Parent and AddressSpace taken from the Aliasee.
+  static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+  /// removeFromParent - This method unlinks 'this' from the containing module,
+  /// but does not delete it.
+  ///
+  void removeFromParent() override;
+
+  /// eraseFromParent - This method unlinks 'this' from the containing module
+  /// and deletes it.
+  ///
+  void eraseFromParent() override;
+
+  /// These methods retrive and set alias target.
+  void setAliasee(Constant *Aliasee);
+  const Constant *getAliasee() const {
+    return const_cast<GlobalAlias *>(this)->getAliasee();
+  }
+  Constant *getAliasee() {
+    return getOperand(0);
+  }
+
+  const GlobalObject *getBaseObject() const {
+    return const_cast<GlobalAlias *>(this)->getBaseObject();
+  }
+  GlobalObject *getBaseObject() {
+    return dyn_cast<GlobalObject>(getAliasee()->stripInBoundsOffsets());
+  }
+
+  const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
+    return const_cast<GlobalAlias *>(this)->getBaseObject(DL, Offset);
+  }
+  GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
+    return dyn_cast<GlobalObject>(
+        getAliasee()->stripAndAccumulateInBoundsConstantOffsets(DL, Offset));
+  }
+
+  static bool isValidLinkage(LinkageTypes L) {
+    return isExternalLinkage(L) || isLocalLinkage(L) ||
+      isWeakLinkage(L) || isLinkOnceLinkage(L);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::GlobalAliasVal;
+  }
+};
+
+template <>
+struct OperandTraits<GlobalAlias> :
+  public FixedNumOperandTraits<GlobalAlias, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
new file mode 100644
index 0000000..2e042f4
--- /dev/null
+++ b/include/llvm/IR/GlobalObject.h
@@ -0,0 +1,64 @@
+//===-- llvm/GlobalObject.h - Class to represent a global object *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This represents an independent object. That is, a function or a global
+// variable, but not an alias.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GLOBALOBJECT_H
+#define LLVM_IR_GLOBALOBJECT_H
+
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
+
+namespace llvm {
+class Comdat;
+class Module;
+
+class GlobalObject : public GlobalValue {
+  GlobalObject(const GlobalObject &) LLVM_DELETED_FUNCTION;
+
+protected:
+  GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+               LinkageTypes Linkage, const Twine &Name)
+      : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) {
+    setGlobalValueSubClassData(0);
+  }
+
+  std::string Section;     // Section to emit this into, empty means default
+  Comdat *ObjComdat;
+public:
+  unsigned getAlignment() const {
+    return (1u << getGlobalValueSubClassData()) >> 1;
+  }
+  void setAlignment(unsigned Align);
+
+  bool hasSection() const { return !StringRef(getSection()).empty(); }
+  const char *getSection() const { return Section.c_str(); }
+  void setSection(StringRef S);
+
+  bool hasComdat() const { return getComdat() != nullptr; }
+  const Comdat *getComdat() const { return ObjComdat; }
+  Comdat *getComdat() { return ObjComdat; }
+  void setComdat(Comdat *C) { ObjComdat = C; }
+
+  void copyAttributesFrom(const GlobalValue *Src) override;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::FunctionVal ||
+           V->getValueID() == Value::GlobalVariableVal;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
new file mode 100644
index 0000000..68e410b
--- /dev/null
+++ b/include/llvm/IR/GlobalValue.h
@@ -0,0 +1,351 @@
+//===-- llvm/GlobalValue.h - Class to represent a global value --*- 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 a common base class of all globally definable objects.  As such,
+// it is subclassed by GlobalVariable, GlobalAlias and by Function.  This is
+// used because you can do certain things with these global objects that you
+// can't do to anything else.  For example, use the address of one as a
+// constant.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GLOBALVALUE_H
+#define LLVM_IR_GLOBALVALUE_H
+
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/DerivedTypes.h"
+
+namespace llvm {
+
+class Comdat;
+class PointerType;
+class Module;
+
+class GlobalValue : public Constant {
+  GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION;
+public:
+  /// @brief An enumeration for the kinds of linkage for global values.
+  enum LinkageTypes {
+    ExternalLinkage = 0,///< Externally visible function
+    AvailableExternallyLinkage, ///< Available for inspection, not emission.
+    LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline)
+    LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent.
+    WeakAnyLinkage,     ///< Keep one copy of named function when linking (weak)
+    WeakODRLinkage,     ///< Same, but only replaced by something equivalent.
+    AppendingLinkage,   ///< Special purpose, only applies to global arrays
+    InternalLinkage,    ///< Rename collisions when linking (static functions).
+    PrivateLinkage,     ///< Like Internal, but omit from symbol table.
+    ExternalWeakLinkage,///< ExternalWeak linkage description.
+    CommonLinkage       ///< Tentative definitions.
+  };
+
+  /// @brief An enumeration for the kinds of visibility of global values.
+  enum VisibilityTypes {
+    DefaultVisibility = 0,  ///< The GV is visible
+    HiddenVisibility,       ///< The GV is hidden
+    ProtectedVisibility     ///< The GV is protected
+  };
+
+  /// @brief Storage classes of global values for PE targets.
+  enum DLLStorageClassTypes {
+    DefaultStorageClass   = 0,
+    DLLImportStorageClass = 1, ///< Function to be imported from DLL
+    DLLExportStorageClass = 2  ///< Function to be accessible from DLL.
+  };
+
+protected:
+  GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+              LinkageTypes Linkage, const Twine &Name)
+      : Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage),
+        Visibility(DefaultVisibility), UnnamedAddr(0),
+        DllStorageClass(DefaultStorageClass),
+        ThreadLocal(NotThreadLocal), Parent(nullptr) {
+    setName(Name);
+  }
+
+  // Note: VC++ treats enums as signed, so an extra bit is required to prevent
+  // Linkage and Visibility from turning into negative values.
+  LinkageTypes Linkage : 5;   // The linkage of this global
+  unsigned Visibility : 2;    // The visibility style of this global
+  unsigned UnnamedAddr : 1;   // This value's address is not significant
+  unsigned DllStorageClass : 2; // DLL storage class
+
+  unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
+                            // the desired model?
+
+private:
+  // Give subclasses access to what otherwise would be wasted padding.
+  // (19 + 3 + 2 + 1 + 2 + 5) == 32.
+  unsigned SubClassData : 19;
+protected:
+  unsigned getGlobalValueSubClassData() const {
+    return SubClassData;
+  }
+  void setGlobalValueSubClassData(unsigned V) {
+    assert(V < (1 << 19) && "It will not fit");
+    SubClassData = V;
+  }
+
+  Module *Parent;             // The containing module.
+public:
+  enum ThreadLocalMode {
+    NotThreadLocal = 0,
+    GeneralDynamicTLSModel,
+    LocalDynamicTLSModel,
+    InitialExecTLSModel,
+    LocalExecTLSModel
+  };
+
+  ~GlobalValue() {
+    removeDeadConstantUsers();   // remove any dead constants using this.
+  }
+
+  unsigned getAlignment() const;
+
+  bool hasUnnamedAddr() const { return UnnamedAddr; }
+  void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+
+  bool hasComdat() const { return getComdat() != nullptr; }
+  Comdat *getComdat();
+  const Comdat *getComdat() const {
+    return const_cast<GlobalValue *>(this)->getComdat();
+  }
+
+  VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
+  bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
+  bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
+  bool hasProtectedVisibility() const {
+    return Visibility == ProtectedVisibility;
+  }
+  void setVisibility(VisibilityTypes V) {
+    assert((!hasLocalLinkage() || V == DefaultVisibility) &&
+           "local linkage requires default visibility");
+    Visibility = V;
+  }
+
+  /// If the value is "Thread Local", its value isn't shared by the threads.
+  bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; }
+  void setThreadLocal(bool Val) {
+    setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal);
+  }
+  void setThreadLocalMode(ThreadLocalMode Val) {
+    assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal);
+    ThreadLocal = Val;
+  }
+  ThreadLocalMode getThreadLocalMode() const {
+    return static_cast<ThreadLocalMode>(ThreadLocal);
+  }
+
+  DLLStorageClassTypes getDLLStorageClass() const {
+    return DLLStorageClassTypes(DllStorageClass);
+  }
+  bool hasDLLImportStorageClass() const {
+    return DllStorageClass == DLLImportStorageClass;
+  }
+  bool hasDLLExportStorageClass() const {
+    return DllStorageClass == DLLExportStorageClass;
+  }
+  void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
+
+  bool hasSection() const { return !StringRef(getSection()).empty(); }
+  // It is unfortunate that we have to use "char *" in here since this is
+  // always non NULL, but:
+  // * The C API expects a null terminated string, so we cannot use StringRef.
+  // * The C API expects us to own it, so we cannot use a std:string.
+  // * For GlobalAliases we can fail to find the section and we have to
+  //   return "", so we cannot use a "const std::string &".
+  const char *getSection() const;
+
+  /// Global values are always pointers.
+  inline PointerType *getType() const {
+    return cast<PointerType>(User::getType());
+  }
+
+  static LinkageTypes getLinkOnceLinkage(bool ODR) {
+    return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
+  }
+  static LinkageTypes getWeakLinkage(bool ODR) {
+    return ODR ? WeakODRLinkage : WeakAnyLinkage;
+  }
+
+  static bool isExternalLinkage(LinkageTypes Linkage) {
+    return Linkage == ExternalLinkage;
+  }
+  static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
+    return Linkage == AvailableExternallyLinkage;
+  }
+  static bool isLinkOnceODRLinkage(LinkageTypes Linkage) {
+    return Linkage == LinkOnceODRLinkage;
+  }
+  static bool isLinkOnceLinkage(LinkageTypes Linkage) {
+    return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
+  }
+  static bool isWeakAnyLinkage(LinkageTypes Linkage) {
+    return Linkage == WeakAnyLinkage;
+  }
+  static bool isWeakODRLinkage(LinkageTypes Linkage) {
+    return Linkage == WeakODRLinkage;
+  }
+  static bool isWeakLinkage(LinkageTypes Linkage) {
+    return isWeakAnyLinkage(Linkage) || isWeakODRLinkage(Linkage);
+  }
+  static bool isAppendingLinkage(LinkageTypes Linkage) {
+    return Linkage == AppendingLinkage;
+  }
+  static bool isInternalLinkage(LinkageTypes Linkage) {
+    return Linkage == InternalLinkage;
+  }
+  static bool isPrivateLinkage(LinkageTypes Linkage) {
+    return Linkage == PrivateLinkage;
+  }
+  static bool isLocalLinkage(LinkageTypes Linkage) {
+    return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage);
+  }
+  static bool isExternalWeakLinkage(LinkageTypes Linkage) {
+    return Linkage == ExternalWeakLinkage;
+  }
+  static bool isCommonLinkage(LinkageTypes Linkage) {
+    return Linkage == CommonLinkage;
+  }
+
+  /// Whether the definition of this global may be discarded if it is not used
+  /// in its compilation unit.
+  static bool isDiscardableIfUnused(LinkageTypes Linkage) {
+    return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage);
+  }
+
+  /// Whether the definition of this global may be replaced by something
+  /// non-equivalent at link time. For example, if a function has weak linkage
+  /// then the code defining it may be replaced by different code.
+  static bool mayBeOverridden(LinkageTypes Linkage) {
+    return Linkage == WeakAnyLinkage || Linkage == LinkOnceAnyLinkage ||
+           Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
+  }
+
+  /// Whether the definition of this global may be replaced at link time.  NB:
+  /// Using this method outside of the code generators is almost always a
+  /// mistake: when working at the IR level use mayBeOverridden instead as it
+  /// knows about ODR semantics.
+  static bool isWeakForLinker(LinkageTypes Linkage)  {
+    return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage ||
+           Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage ||
+           Linkage == LinkOnceODRLinkage || Linkage == CommonLinkage ||
+           Linkage == ExternalWeakLinkage;
+  }
+
+  bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
+  bool hasAvailableExternallyLinkage() const {
+    return isAvailableExternallyLinkage(Linkage);
+  }
+  bool hasLinkOnceLinkage() const {
+    return isLinkOnceLinkage(Linkage);
+  }
+  bool hasWeakLinkage() const {
+    return isWeakLinkage(Linkage);
+  }
+  bool hasWeakAnyLinkage() const {
+    return isWeakAnyLinkage(Linkage);
+  }
+  bool hasWeakODRLinkage() const {
+    return isWeakODRLinkage(Linkage);
+  }
+  bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); }
+  bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
+  bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
+  bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
+  bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); }
+  bool hasCommonLinkage() const { return isCommonLinkage(Linkage); }
+
+  void setLinkage(LinkageTypes LT) {
+    if (isLocalLinkage(LT))
+      Visibility = DefaultVisibility;
+    Linkage = LT;
+  }
+  LinkageTypes getLinkage() const { return Linkage; }
+
+  bool isDiscardableIfUnused() const {
+    return isDiscardableIfUnused(Linkage);
+  }
+
+  bool mayBeOverridden() const { return mayBeOverridden(Linkage); }
+
+  bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
+
+  /// Copy all additional attributes (those not needed to create a GlobalValue)
+  /// from the GlobalValue Src to this one.
+  virtual void copyAttributesFrom(const GlobalValue *Src);
+
+  /// If special LLVM prefix that is used to inform the asm printer to not emit
+  /// usual symbol prefix before the symbol name is used then return linkage
+  /// name after skipping this special LLVM prefix.
+  static StringRef getRealLinkageName(StringRef Name) {
+    if (!Name.empty() && Name[0] == '\1')
+      return Name.substr(1);
+    return Name;
+  }
+
+/// @name Materialization
+/// Materialization is used to construct functions only as they're needed. This
+/// is useful to reduce memory usage in LLVM or parsing work done by the
+/// BitcodeReader to load the Module.
+/// @{
+
+  /// If this function's Module is being lazily streamed in functions from disk
+  /// or some other source, this method can be used to check to see if the
+  /// function has been read in yet or not.
+  bool isMaterializable() const;
+
+  /// Returns true if this function was loaded from a GVMaterializer that's
+  /// still attached to its Module and that knows how to dematerialize the
+  /// function.
+  bool isDematerializable() const;
+
+  /// Make sure this GlobalValue is fully read. If the module is corrupt, this
+  /// returns true and fills in the optional string with information about the
+  /// problem.  If successful, this returns false.
+  bool Materialize(std::string *ErrInfo = nullptr);
+
+  /// If this GlobalValue is read in, and if the GVMaterializer supports it,
+  /// release the memory for the function, and set it up to be materialized
+  /// lazily. If !isDematerializable(), this method is a noop.
+  void Dematerialize();
+
+/// @}
+
+  /// Override from Constant class.
+  void destroyConstant() override;
+
+  /// Return true if the primary definition of this global value is outside of
+  /// the current translation unit.
+  bool isDeclaration() const;
+
+  /// This method unlinks 'this' from the containing module, but does not delete
+  /// it.
+  virtual void removeFromParent() = 0;
+
+  /// This method unlinks 'this' from the containing module and deletes it.
+  virtual void eraseFromParent() = 0;
+
+  /// Get the module that this global value is contained inside of...
+  inline Module *getParent() { return Parent; }
+  inline const Module *getParent() const { return Parent; }
+
+  const DataLayout *getDataLayout() const;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::FunctionVal ||
+           V->getValueID() == Value::GlobalVariableVal ||
+           V->getValueID() == Value::GlobalAliasVal;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
new file mode 100644
index 0000000..4189ccb
--- /dev/null
+++ b/include/llvm/IR/GlobalVariable.h
@@ -0,0 +1,187 @@
+//===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalVariable class, which
+// represents a single global variable (or constant) in the VM.
+//
+// Global variables are constant pointers that refer to hunks of space that are
+// allocated by either the VM, or by the linker in a static compiler.  A global
+// variable may have an initial value, which is copied into the executables .data
+// area.  Global Constants are required to have initializers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_GLOBALVARIABLE_H
+#define LLVM_IR_GLOBALVARIABLE_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/OperandTraits.h"
+
+namespace llvm {
+
+class Module;
+class Constant;
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
+  friend class SymbolTableListTraits<GlobalVariable, Module>;
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION;
+  GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION;
+
+  void setParent(Module *parent);
+
+  bool isConstantGlobal : 1;                   // Is this a global constant?
+  bool isExternallyInitializedConstant : 1;    // Is this a global whose value
+                                               // can change from its initial
+                                               // value before global
+                                               // initializers are run?
+
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+
+  /// GlobalVariable ctor - If a parent module is specified, the global is
+  /// automatically inserted into the end of the specified modules global list.
+  GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
+                 Constant *Initializer = nullptr, const Twine &Name = "",
+                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+                 bool isExternallyInitialized = false);
+  /// GlobalVariable ctor - This creates a global and inserts it before the
+  /// specified other global.
+  GlobalVariable(Module &M, Type *Ty, bool isConstant,
+                 LinkageTypes Linkage, Constant *Initializer,
+                 const Twine &Name = "", GlobalVariable *InsertBefore = nullptr,
+                 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+                 bool isExternallyInitialized = false);
+
+  ~GlobalVariable() {
+    NumOperands = 1; // FIXME: needed by operator delete
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Definitions have initializers, declarations don't.
+  ///
+  inline bool hasInitializer() const { return !isDeclaration(); }
+
+  /// hasDefinitiveInitializer - Whether the global variable has an initializer,
+  /// and any other instances of the global (this can happen due to weak
+  /// linkage) are guaranteed to have the same initializer.
+  ///
+  /// Note that if you want to transform a global, you must use
+  /// hasUniqueInitializer() instead, because of the *_odr linkage type.
+  ///
+  /// Example:
+  ///
+  /// @a = global SomeType* null - Initializer is both definitive and unique.
+  ///
+  /// @b = global weak SomeType* null - Initializer is neither definitive nor
+  /// unique.
+  ///
+  /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
+  /// unique.
+  inline bool hasDefinitiveInitializer() const {
+    return hasInitializer() &&
+      // The initializer of a global variable with weak linkage may change at
+      // link time.
+      !mayBeOverridden() &&
+      // The initializer of a global variable with the externally_initialized
+      // marker may change at runtime before C++ initializers are evaluated.
+      !isExternallyInitialized();
+  }
+
+  /// hasUniqueInitializer - Whether the global variable has an initializer, and
+  /// any changes made to the initializer will turn up in the final executable.
+  inline bool hasUniqueInitializer() const {
+    return hasInitializer() &&
+      // It's not safe to modify initializers of global variables with weak
+      // linkage, because the linker might choose to discard the initializer and
+      // use the initializer from another instance of the global variable
+      // instead. It is wrong to modify the initializer of a global variable
+      // with *_odr linkage because then different instances of the global may
+      // have different initializers, breaking the One Definition Rule.
+      !isWeakForLinker() &&
+      // It is not safe to modify initializers of global variables with the
+      // external_initializer marker since the value may be changed at runtime
+      // before C++ initializers are evaluated.
+      !isExternallyInitialized();
+  }
+
+  /// getInitializer - Return the initializer for this global variable.  It is
+  /// illegal to call this method if the global is external, because we cannot
+  /// tell what the value is initialized to!
+  ///
+  inline const Constant *getInitializer() const {
+    assert(hasInitializer() && "GV doesn't have initializer!");
+    return static_cast<Constant*>(Op<0>().get());
+  }
+  inline Constant *getInitializer() {
+    assert(hasInitializer() && "GV doesn't have initializer!");
+    return static_cast<Constant*>(Op<0>().get());
+  }
+  /// setInitializer - Sets the initializer for this global variable, removing
+  /// any existing initializer if InitVal==NULL.  If this GV has type T*, the
+  /// initializer must have type T.
+  void setInitializer(Constant *InitVal);
+
+  /// If the value is a global constant, its value is immutable throughout the
+  /// runtime execution of the program.  Assigning a value into the constant
+  /// leads to undefined behavior.
+  ///
+  bool isConstant() const { return isConstantGlobal; }
+  void setConstant(bool Val) { isConstantGlobal = Val; }
+
+  bool isExternallyInitialized() const {
+    return isExternallyInitializedConstant;
+  }
+  void setExternallyInitialized(bool Val) {
+    isExternallyInitializedConstant = Val;
+  }
+
+  /// copyAttributesFrom - copy all additional attributes (those not needed to
+  /// create a GlobalVariable) from the GlobalVariable Src to this one.
+  void copyAttributesFrom(const GlobalValue *Src) override;
+
+  /// removeFromParent - This method unlinks 'this' from the containing module,
+  /// but does not delete it.
+  ///
+  void removeFromParent() override;
+
+  /// eraseFromParent - This method unlinks 'this' from the containing module
+  /// and deletes it.
+  ///
+  void eraseFromParent() override;
+
+  /// Override Constant's implementation of this method so we can
+  /// replace constant initializers.
+  void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::GlobalVariableVal;
+  }
+};
+
+template <>
+struct OperandTraits<GlobalVariable> :
+  public OptionalOperandTraits<GlobalVariable> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
new file mode 100644
index 0000000..aed2463
--- /dev/null
+++ b/include/llvm/IR/IRBuilder.h
@@ -0,0 +1,1518 @@
+//===---- llvm/IRBuilder.h - Builder for LLVM Instructions ------*- 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 IRBuilder class, which is used as a convenient way
+// to create LLVM instructions with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_IRBUILDER_H
+#define LLVM_IR_IRBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ConstantFolder.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/CBindingWrapping.h"
+
+namespace llvm {
+  class MDNode;
+
+/// \brief This provides the default implementation of the IRBuilder
+/// 'InsertHelper' method that is called whenever an instruction is created by
+/// IRBuilder and needs to be inserted.
+///
+/// By default, this inserts the instruction at the insertion point.
+template <bool preserveNames = true>
+class IRBuilderDefaultInserter {
+protected:
+  void InsertHelper(Instruction *I, const Twine &Name,
+                    BasicBlock *BB, BasicBlock::iterator InsertPt) const {
+    if (BB) BB->getInstList().insert(InsertPt, I);
+    if (preserveNames)
+      I->setName(Name);
+  }
+};
+
+/// \brief Common base class shared among various IRBuilders.
+class IRBuilderBase {
+  DebugLoc CurDbgLocation;
+protected:
+  BasicBlock *BB;
+  BasicBlock::iterator InsertPt;
+  LLVMContext &Context;
+
+  MDNode *DefaultFPMathTag;
+  FastMathFlags FMF;
+public:
+
+  IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr)
+    : Context(context), DefaultFPMathTag(FPMathTag), FMF() {
+    ClearInsertionPoint();
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Builder configuration methods
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Clear the insertion point: created instructions will not be
+  /// inserted into a block.
+  void ClearInsertionPoint() {
+    BB = nullptr;
+    InsertPt = nullptr;
+  }
+
+  BasicBlock *GetInsertBlock() const { return BB; }
+  BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
+  LLVMContext &getContext() const { return Context; }
+
+  /// \brief This specifies that created instructions should be appended to the
+  /// end of the specified block.
+  void SetInsertPoint(BasicBlock *TheBB) {
+    BB = TheBB;
+    InsertPt = BB->end();
+  }
+
+  /// \brief This specifies that created instructions should be inserted before
+  /// the specified instruction.
+  void SetInsertPoint(Instruction *I) {
+    BB = I->getParent();
+    InsertPt = I;
+    assert(I != BB->end() && "Can't read debug loc from end()");
+    SetCurrentDebugLocation(I->getDebugLoc());
+  }
+
+  /// \brief This specifies that created instructions should be inserted at the
+  /// specified point.
+  void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
+    BB = TheBB;
+    InsertPt = IP;
+  }
+
+  /// \brief Find the nearest point that dominates this use, and specify that
+  /// created instructions should be inserted at this point.
+  void SetInsertPoint(Use &U) {
+    Instruction *UseInst = cast<Instruction>(U.getUser());
+    if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
+      BasicBlock *PredBB = Phi->getIncomingBlock(U);
+      assert(U != PredBB->getTerminator() && "critical edge not split");
+      SetInsertPoint(PredBB, PredBB->getTerminator());
+      return;
+    }
+    SetInsertPoint(UseInst);
+  }
+
+  /// \brief Set location information used by debugging information.
+  void SetCurrentDebugLocation(const DebugLoc &L) {
+    CurDbgLocation = L;
+  }
+
+  /// \brief Get location information used by debugging information.
+  DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
+
+  /// \brief If this builder has a current debug location, set it on the
+  /// specified instruction.
+  void SetInstDebugLocation(Instruction *I) const {
+    if (!CurDbgLocation.isUnknown())
+      I->setDebugLoc(CurDbgLocation);
+  }
+
+  /// \brief Get the return type of the current function that we're emitting
+  /// into.
+  Type *getCurrentFunctionReturnType() const;
+
+  /// InsertPoint - A saved insertion point.
+  class InsertPoint {
+    BasicBlock *Block;
+    BasicBlock::iterator Point;
+
+  public:
+    /// \brief Creates a new insertion point which doesn't point to anything.
+    InsertPoint() : Block(nullptr) {}
+
+    /// \brief Creates a new insertion point at the given location.
+    InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint)
+      : Block(InsertBlock), Point(InsertPoint) {}
+
+    /// \brief Returns true if this insert point is set.
+    bool isSet() const { return (Block != nullptr); }
+
+    llvm::BasicBlock *getBlock() const { return Block; }
+    llvm::BasicBlock::iterator getPoint() const { return Point; }
+  };
+
+  /// \brief Returns the current insert point.
+  InsertPoint saveIP() const {
+    return InsertPoint(GetInsertBlock(), GetInsertPoint());
+  }
+
+  /// \brief Returns the current insert point, clearing it in the process.
+  InsertPoint saveAndClearIP() {
+    InsertPoint IP(GetInsertBlock(), GetInsertPoint());
+    ClearInsertionPoint();
+    return IP;
+  }
+
+  /// \brief Sets the current insert point to a previously-saved location.
+  void restoreIP(InsertPoint IP) {
+    if (IP.isSet())
+      SetInsertPoint(IP.getBlock(), IP.getPoint());
+    else
+      ClearInsertionPoint();
+  }
+
+  /// \brief Get the floating point math metadata being used.
+  MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
+
+  /// \brief Get the flags to be applied to created floating point ops
+  FastMathFlags getFastMathFlags() const { return FMF; }
+
+  /// \brief Clear the fast-math flags.
+  void clearFastMathFlags() { FMF.clear(); }
+
+  /// \brief Set the floating point math metadata to be used.
+  void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
+
+  /// \brief Set the fast-math flags to be used with generated fp-math operators
+  void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
+
+  //===--------------------------------------------------------------------===//
+  // RAII helpers.
+  //===--------------------------------------------------------------------===//
+
+  // \brief RAII object that stores the current insertion point and restores it
+  // when the object is destroyed. This includes the debug location.
+  class InsertPointGuard {
+    IRBuilderBase &Builder;
+    AssertingVH<BasicBlock> Block;
+    BasicBlock::iterator Point;
+    DebugLoc DbgLoc;
+
+    InsertPointGuard(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
+    InsertPointGuard &operator=(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
+
+  public:
+    InsertPointGuard(IRBuilderBase &B)
+        : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()),
+          DbgLoc(B.getCurrentDebugLocation()) {}
+
+    ~InsertPointGuard() {
+      Builder.restoreIP(InsertPoint(Block, Point));
+      Builder.SetCurrentDebugLocation(DbgLoc);
+    }
+  };
+
+  // \brief RAII object that stores the current fast math settings and restores
+  // them when the object is destroyed.
+  class FastMathFlagGuard {
+    IRBuilderBase &Builder;
+    FastMathFlags FMF;
+    MDNode *FPMathTag;
+
+    FastMathFlagGuard(const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+    FastMathFlagGuard &operator=(
+        const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+
+  public:
+    FastMathFlagGuard(IRBuilderBase &B)
+        : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {}
+
+    ~FastMathFlagGuard() {
+      Builder.FMF = FMF;
+      Builder.DefaultFPMathTag = FPMathTag;
+    }
+  };
+
+  //===--------------------------------------------------------------------===//
+  // Miscellaneous creation methods.
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Make a new global variable with initializer type i8*
+  ///
+  /// Make a new global variable with an initializer that has array of i8 type
+  /// filled in with the null terminated string value specified.  The new global
+  /// variable will be marked mergable with any others of the same contents.  If
+  /// Name is specified, it is the name of the global variable created.
+  Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
+
+  /// \brief Get a constant value representing either true or false.
+  ConstantInt *getInt1(bool V) {
+    return ConstantInt::get(getInt1Ty(), V);
+  }
+
+  /// \brief Get the constant value for i1 true.
+  ConstantInt *getTrue() {
+    return ConstantInt::getTrue(Context);
+  }
+
+  /// \brief Get the constant value for i1 false.
+  ConstantInt *getFalse() {
+    return ConstantInt::getFalse(Context);
+  }
+
+  /// \brief Get a constant 8-bit value.
+  ConstantInt *getInt8(uint8_t C) {
+    return ConstantInt::get(getInt8Ty(), C);
+  }
+
+  /// \brief Get a constant 16-bit value.
+  ConstantInt *getInt16(uint16_t C) {
+    return ConstantInt::get(getInt16Ty(), C);
+  }
+
+  /// \brief Get a constant 32-bit value.
+  ConstantInt *getInt32(uint32_t C) {
+    return ConstantInt::get(getInt32Ty(), C);
+  }
+
+  /// \brief Get a constant 64-bit value.
+  ConstantInt *getInt64(uint64_t C) {
+    return ConstantInt::get(getInt64Ty(), C);
+  }
+
+  /// \brief Get a constant N-bit value, zero extended or truncated from
+  /// a 64-bit value.
+  ConstantInt *getIntN(unsigned N, uint64_t C) {
+    return ConstantInt::get(getIntNTy(N), C);
+  }
+
+  /// \brief Get a constant integer value.
+  ConstantInt *getInt(const APInt &AI) {
+    return ConstantInt::get(Context, AI);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Type creation methods
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Fetch the type representing a single bit
+  IntegerType *getInt1Ty() {
+    return Type::getInt1Ty(Context);
+  }
+
+  /// \brief Fetch the type representing an 8-bit integer.
+  IntegerType *getInt8Ty() {
+    return Type::getInt8Ty(Context);
+  }
+
+  /// \brief Fetch the type representing a 16-bit integer.
+  IntegerType *getInt16Ty() {
+    return Type::getInt16Ty(Context);
+  }
+
+  /// \brief Fetch the type representing a 32-bit integer.
+  IntegerType *getInt32Ty() {
+    return Type::getInt32Ty(Context);
+  }
+
+  /// \brief Fetch the type representing a 64-bit integer.
+  IntegerType *getInt64Ty() {
+    return Type::getInt64Ty(Context);
+  }
+
+  /// \brief Fetch the type representing an N-bit integer.
+  IntegerType *getIntNTy(unsigned N) {
+    return Type::getIntNTy(Context, N);
+  }
+
+  /// \brief Fetch the type representing a 16-bit floating point value.
+  Type *getHalfTy() {
+    return Type::getHalfTy(Context);
+  }
+
+  /// \brief Fetch the type representing a 32-bit floating point value.
+  Type *getFloatTy() {
+    return Type::getFloatTy(Context);
+  }
+
+  /// \brief Fetch the type representing a 64-bit floating point value.
+  Type *getDoubleTy() {
+    return Type::getDoubleTy(Context);
+  }
+
+  /// \brief Fetch the type representing void.
+  Type *getVoidTy() {
+    return Type::getVoidTy(Context);
+  }
+
+  /// \brief Fetch the type representing a pointer to an 8-bit integer value.
+  PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
+    return Type::getInt8PtrTy(Context, AddrSpace);
+  }
+
+  /// \brief Fetch the type representing a pointer to an integer value.
+  IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) {
+    return DL->getIntPtrType(Context, AddrSpace);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Intrinsic creation methods
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Create and insert a memset to the specified pointer and the
+  /// specified value.
+  ///
+  /// If the pointer isn't an i8*, it will be converted.  If a TBAA tag is
+  /// specified, it will be added to the instruction.
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
+                         bool isVolatile = false, MDNode *TBAATag = nullptr) {
+    return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
+  }
+
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
+                         bool isVolatile = false, MDNode *TBAATag = nullptr);
+
+  /// \brief Create and insert a memcpy between the specified pointers.
+  ///
+  /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
+  /// specified, it will be added to the instruction.
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+                         bool isVolatile = false, MDNode *TBAATag = nullptr,
+                         MDNode *TBAAStructTag = nullptr) {
+    return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
+                        TBAAStructTag);
+  }
+
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
+                         bool isVolatile = false, MDNode *TBAATag = nullptr,
+                         MDNode *TBAAStructTag = nullptr);
+
+  /// \brief Create and insert a memmove between the specified
+  /// pointers.
+  ///
+  /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
+  /// specified, it will be added to the instruction.
+  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+                          bool isVolatile = false, MDNode *TBAATag = nullptr) {
+    return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+  }
+
+  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
+                          bool isVolatile = false, MDNode *TBAATag = nullptr);
+
+  /// \brief Create a lifetime.start intrinsic.
+  ///
+  /// If the pointer isn't i8* it will be converted.
+  CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = nullptr);
+
+  /// \brief Create a lifetime.end intrinsic.
+  ///
+  /// If the pointer isn't i8* it will be converted.
+  CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = nullptr);
+
+private:
+  Value *getCastedInt8PtrValue(Value *Ptr);
+};
+
+/// \brief This provides a uniform API for creating instructions and inserting
+/// them into a basic block: either at the end of a BasicBlock, or at a specific
+/// iterator location in a block.
+///
+/// Note that the builder does not expose the full generality of LLVM
+/// instructions.  For access to extra instruction properties, use the mutators
+/// (e.g. setVolatile) on the instructions after they have been
+/// created. Convenience state exists to specify fast-math flags and fp-math
+/// tags.
+///
+/// The first template argument handles whether or not to preserve names in the
+/// final instruction output. This defaults to on.  The second template argument
+/// specifies a class to use for creating constants.  This defaults to creating
+/// minimally folded constants.  The fourth template argument allows clients to
+/// specify custom insertion hooks that are called on every newly created
+/// insertion.
+template<bool preserveNames = true, typename T = ConstantFolder,
+         typename Inserter = IRBuilderDefaultInserter<preserveNames> >
+class IRBuilder : public IRBuilderBase, public Inserter {
+  T Folder;
+public:
+  IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
+            MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(C, FPMathTag), Inserter(I), Folder(F) {
+  }
+
+  explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(C, FPMathTag), Folder() {
+  }
+
+  explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder(F) {
+    SetInsertPoint(TheBB);
+  }
+
+  explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder() {
+    SetInsertPoint(TheBB);
+  }
+
+  explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(IP->getContext(), FPMathTag), Folder() {
+    SetInsertPoint(IP);
+    SetCurrentDebugLocation(IP->getDebugLoc());
+  }
+
+  explicit IRBuilder(Use &U, MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(U->getContext(), FPMathTag), Folder() {
+    SetInsertPoint(U);
+    SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
+  }
+
+  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
+            MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder(F) {
+    SetInsertPoint(TheBB, IP);
+  }
+
+  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
+            MDNode *FPMathTag = nullptr)
+    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder() {
+    SetInsertPoint(TheBB, IP);
+  }
+
+  /// \brief Get the constant folder being used.
+  const T &getFolder() { return Folder; }
+
+  /// \brief Return true if this builder is configured to actually add the
+  /// requested names to IR created through it.
+  bool isNamePreserving() const { return preserveNames; }
+
+  /// \brief Insert and return the specified instruction.
+  template<typename InstTy>
+  InstTy *Insert(InstTy *I, const Twine &Name = "") const {
+    this->InsertHelper(I, Name, BB, InsertPt);
+    this->SetInstDebugLocation(I);
+    return I;
+  }
+
+  /// \brief No-op overload to handle constants.
+  Constant *Insert(Constant *C, const Twine& = "") const {
+    return C;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Terminators
+  //===--------------------------------------------------------------------===//
+
+private:
+  /// \brief Helper to add branch weight metadata onto an instruction.
+  /// \returns The annotated instruction.
+  template <typename InstTy>
+  InstTy *addBranchWeights(InstTy *I, MDNode *Weights) {
+    if (Weights)
+      I->setMetadata(LLVMContext::MD_prof, Weights);
+    return I;
+  }
+
+public:
+  /// \brief Create a 'ret void' instruction.
+  ReturnInst *CreateRetVoid() {
+    return Insert(ReturnInst::Create(Context));
+  }
+
+  /// \brief Create a 'ret <val>' instruction.
+  ReturnInst *CreateRet(Value *V) {
+    return Insert(ReturnInst::Create(Context, V));
+  }
+
+  /// \brief Create a sequence of N insertvalue instructions,
+  /// with one Value from the retVals array each, that build a aggregate
+  /// return value one value at a time, and a ret instruction to return
+  /// the resulting aggregate value.
+  ///
+  /// This is a convenience function for code that uses aggregate return values
+  /// as a vehicle for having multiple return values.
+  ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) {
+    Value *V = UndefValue::get(getCurrentFunctionReturnType());
+    for (unsigned i = 0; i != N; ++i)
+      V = CreateInsertValue(V, retVals[i], i, "mrv");
+    return Insert(ReturnInst::Create(Context, V));
+  }
+
+  /// \brief Create an unconditional 'br label X' instruction.
+  BranchInst *CreateBr(BasicBlock *Dest) {
+    return Insert(BranchInst::Create(Dest));
+  }
+
+  /// \brief Create a conditional 'br Cond, TrueDest, FalseDest'
+  /// instruction.
+  BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False,
+                           MDNode *BranchWeights = nullptr) {
+    return Insert(addBranchWeights(BranchInst::Create(True, False, Cond),
+                                   BranchWeights));
+  }
+
+  /// \brief Create a switch instruction with the specified value, default dest,
+  /// and with a hint for the number of cases that will be added (for efficient
+  /// allocation).
+  SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10,
+                           MDNode *BranchWeights = nullptr) {
+    return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases),
+                                   BranchWeights));
+  }
+
+  /// \brief Create an indirect branch instruction with the specified address
+  /// operand, with an optional hint for the number of destinations that will be
+  /// added (for efficient allocation).
+  IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
+    return Insert(IndirectBrInst::Create(Addr, NumDests));
+  }
+
+  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+                           BasicBlock *UnwindDest, const Twine &Name = "") {
+    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
+                                     ArrayRef<Value *>()),
+                  Name);
+  }
+  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+                           BasicBlock *UnwindDest, Value *Arg1,
+                           const Twine &Name = "") {
+    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
+                  Name);
+  }
+  InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
+                            BasicBlock *UnwindDest, Value *Arg1,
+                            Value *Arg2, Value *Arg3,
+                            const Twine &Name = "") {
+    Value *Args[] = { Arg1, Arg2, Arg3 };
+    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
+                  Name);
+  }
+  /// \brief Create an invoke instruction.
+  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+                           BasicBlock *UnwindDest, ArrayRef<Value *> Args,
+                           const Twine &Name = "") {
+    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
+                  Name);
+  }
+
+  ResumeInst *CreateResume(Value *Exn) {
+    return Insert(ResumeInst::Create(Exn));
+  }
+
+  UnreachableInst *CreateUnreachable() {
+    return Insert(new UnreachableInst(Context));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Binary Operators
+  //===--------------------------------------------------------------------===//
+private:
+  BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc,
+                                          Value *LHS, Value *RHS,
+                                          const Twine &Name,
+                                          bool HasNUW, bool HasNSW) {
+    BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+
+  Instruction *AddFPMathAttributes(Instruction *I,
+                                   MDNode *FPMathTag,
+                                   FastMathFlags FMF) const {
+    if (!FPMathTag)
+      FPMathTag = DefaultFPMathTag;
+    if (FPMathTag)
+      I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
+    I->setFastMathFlags(FMF);
+    return I;
+  }
+public:
+  Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name);
+    return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name,
+                                   HasNUW, HasNSW);
+  }
+  Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateAdd(LHS, RHS, Name, false, true);
+  }
+  Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateAdd(LHS, RHS, Name, true, false);
+  }
+  Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFAdd(LC, RC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS),
+                                      FPMathTag, FMF), Name);
+  }
+  Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateSub(LC, RC, HasNUW, HasNSW), Name);
+    return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
+                                   HasNUW, HasNSW);
+  }
+  Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateSub(LHS, RHS, Name, false, true);
+  }
+  Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateSub(LHS, RHS, Name, true, false);
+  }
+  Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFSub(LC, RC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS),
+                                      FPMathTag, FMF), Name);
+  }
+  Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateMul(LC, RC, HasNUW, HasNSW), Name);
+    return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
+                                   HasNUW, HasNSW);
+  }
+  Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateMul(LHS, RHS, Name, false, true);
+  }
+  Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateMul(LHS, RHS, Name, true, false);
+  }
+  Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFMul(LC, RC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS),
+                                      FPMathTag, FMF), Name);
+  }
+  Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
+    if (!isExact)
+      return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+    return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
+  }
+  Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateUDiv(LHS, RHS, Name, true);
+  }
+  Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
+    if (!isExact)
+      return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+    return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
+  }
+  Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateSDiv(LHS, RHS, Name, true);
+  }
+  Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFDiv(LC, RC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS),
+                                      FPMathTag, FMF), Name);
+  }
+  Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateURem(LC, RC), Name);
+    return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
+  }
+  Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateSRem(LC, RC), Name);
+    return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
+  }
+  Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFRem(LC, RC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS),
+                                      FPMathTag, FMF), Name);
+  }
+
+  Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name);
+    return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name,
+                                   HasNUW, HasNSW);
+  }
+  Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+                     HasNUW, HasNSW);
+  }
+  Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+                     HasNUW, HasNSW);
+  }
+
+  Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
+    if (!isExact)
+      return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+    return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
+  }
+  Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+  }
+  Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+  }
+
+  Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
+    if (!isExact)
+      return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+    return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
+  }
+  Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+  }
+  Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+                    bool isExact = false) {
+    return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+  }
+
+  Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
+    if (Constant *RC = dyn_cast<Constant>(RHS)) {
+      if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
+        return LHS;  // LHS & -1 -> LHS
+      if (Constant *LC = dyn_cast<Constant>(LHS))
+        return Insert(Folder.CreateAnd(LC, RC), Name);
+    }
+    return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
+  }
+  Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+    return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+  Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+    return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+
+  Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
+    if (Constant *RC = dyn_cast<Constant>(RHS)) {
+      if (RC->isNullValue())
+        return LHS;  // LHS | 0 -> LHS
+      if (Constant *LC = dyn_cast<Constant>(LHS))
+        return Insert(Folder.CreateOr(LC, RC), Name);
+    }
+    return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
+  }
+  Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+    return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+  Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+    return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+
+  Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateXor(LC, RC), Name);
+    return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
+  }
+  Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+    return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+  Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+    return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+  }
+
+  Value *CreateBinOp(Instruction::BinaryOps Opc,
+                     Value *LHS, Value *RHS, const Twine &Name = "",
+                     MDNode *FPMathTag = nullptr) {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
+    llvm::Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS);
+    if (isa<FPMathOperator>(BinOp))
+      BinOp = AddFPMathAttributes(BinOp, FPMathTag, FMF);
+    return Insert(BinOp, Name);
+  }
+
+  Value *CreateNeg(Value *V, const Twine &Name = "",
+                   bool HasNUW = false, bool HasNSW = false) {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name);
+    BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
+    return CreateNeg(V, Name, false, true);
+  }
+  Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
+    return CreateNeg(V, Name, true, false);
+  }
+  Value *CreateFNeg(Value *V, const Twine &Name = "",
+                    MDNode *FPMathTag = nullptr) {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateFNeg(VC), Name);
+    return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V),
+                                      FPMathTag, FMF), Name);
+  }
+  Value *CreateNot(Value *V, const Twine &Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateNot(VC), Name);
+    return Insert(BinaryOperator::CreateNot(V), Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Memory Instructions
+  //===--------------------------------------------------------------------===//
+
+  AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr,
+                           const Twine &Name = "") {
+    return Insert(new AllocaInst(Ty, ArraySize), Name);
+  }
+  // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
+  // converting the string to 'bool' for the isVolatile parameter.
+  LoadInst *CreateLoad(Value *Ptr, const char *Name) {
+    return Insert(new LoadInst(Ptr), Name);
+  }
+  LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
+    return Insert(new LoadInst(Ptr), Name);
+  }
+  LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
+    return Insert(new LoadInst(Ptr, nullptr, isVolatile), Name);
+  }
+  StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
+    return Insert(new StoreInst(Val, Ptr, isVolatile));
+  }
+  // \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")'
+  // correctly, instead of converting the string to 'bool' for the isVolatile
+  // parameter.
+  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) {
+    LoadInst *LI = CreateLoad(Ptr, Name);
+    LI->setAlignment(Align);
+    return LI;
+  }
+  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align,
+                              const Twine &Name = "") {
+    LoadInst *LI = CreateLoad(Ptr, Name);
+    LI->setAlignment(Align);
+    return LI;
+  }
+  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile,
+                              const Twine &Name = "") {
+    LoadInst *LI = CreateLoad(Ptr, isVolatile, Name);
+    LI->setAlignment(Align);
+    return LI;
+  }
+  StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align,
+                                bool isVolatile = false) {
+    StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
+    SI->setAlignment(Align);
+    return SI;
+  }
+  FenceInst *CreateFence(AtomicOrdering Ordering,
+                         SynchronizationScope SynchScope = CrossThread,
+                         const Twine &Name = "") {
+    return Insert(new FenceInst(Context, Ordering, SynchScope), Name);
+  }
+  AtomicCmpXchgInst *
+  CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
+                      AtomicOrdering SuccessOrdering,
+                      AtomicOrdering FailureOrdering,
+                      SynchronizationScope SynchScope = CrossThread) {
+    return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering,
+                                        FailureOrdering, SynchScope));
+  }
+  AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
+                                 AtomicOrdering Ordering,
+                               SynchronizationScope SynchScope = CrossThread) {
+    return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope));
+  }
+  Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
+                   const Twine &Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+      // Every index must be constant.
+      size_t i, e;
+      for (i = 0, e = IdxList.size(); i != e; ++i)
+        if (!isa<Constant>(IdxList[i]))
+          break;
+      if (i == e)
+        return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
+    }
+    return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
+  }
+  Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
+                           const Twine &Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+      // Every index must be constant.
+      size_t i, e;
+      for (i = 0, e = IdxList.size(); i != e; ++i)
+        if (!isa<Constant>(IdxList[i]))
+          break;
+      if (i == e)
+        return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
+    }
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
+  }
+  Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+        return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
+    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+  }
+  Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+        return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+  }
+  Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+
+    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+  }
+  Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+                                    const Twine &Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+  }
+  Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+                    const Twine &Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+
+    return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+  }
+  Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+                                    const Twine &Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+  }
+  Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+
+    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+  }
+  Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
+                                    const Twine &Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+  }
+  Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+                    const Twine &Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+
+    return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+  }
+  Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+                                    const Twine &Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+  }
+  Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
+    return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
+  }
+
+  /// \brief Same as CreateGlobalString, but return a pointer with "i8*" type
+  /// instead of a pointer to array of i8.
+  Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
+    Value *gv = CreateGlobalString(Str, Name);
+    Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
+    Value *Args[] = { zero, zero };
+    return CreateInBoundsGEP(gv, Args, Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Cast/Conversion Operators
+  //===--------------------------------------------------------------------===//
+
+  Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") {
+    return CreateCast(Instruction::Trunc, V, DestTy, Name);
+  }
+  Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") {
+    return CreateCast(Instruction::ZExt, V, DestTy, Name);
+  }
+  Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
+    return CreateCast(Instruction::SExt, V, DestTy, Name);
+  }
+  /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Return
+  /// the value untouched if the type of V is already DestTy.
+  Value *CreateZExtOrTrunc(Value *V, Type *DestTy,
+                           const Twine &Name = "") {
+    assert(V->getType()->isIntOrIntVectorTy() &&
+           DestTy->isIntOrIntVectorTy() &&
+           "Can only zero extend/truncate integers!");
+    Type *VTy = V->getType();
+    if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
+      return CreateZExt(V, DestTy, Name);
+    if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
+      return CreateTrunc(V, DestTy, Name);
+    return V;
+  }
+  /// \brief Create a SExt or Trunc from the integer value V to DestTy. Return
+  /// the value untouched if the type of V is already DestTy.
+  Value *CreateSExtOrTrunc(Value *V, Type *DestTy,
+                           const Twine &Name = "") {
+    assert(V->getType()->isIntOrIntVectorTy() &&
+           DestTy->isIntOrIntVectorTy() &&
+           "Can only sign extend/truncate integers!");
+    Type *VTy = V->getType();
+    if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
+      return CreateSExt(V, DestTy, Name);
+    if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
+      return CreateTrunc(V, DestTy, Name);
+    return V;
+  }
+  Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){
+    return CreateCast(Instruction::FPToUI, V, DestTy, Name);
+  }
+  Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){
+    return CreateCast(Instruction::FPToSI, V, DestTy, Name);
+  }
+  Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
+    return CreateCast(Instruction::UIToFP, V, DestTy, Name);
+  }
+  Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
+    return CreateCast(Instruction::SIToFP, V, DestTy, Name);
+  }
+  Value *CreateFPTrunc(Value *V, Type *DestTy,
+                       const Twine &Name = "") {
+    return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
+  }
+  Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") {
+    return CreateCast(Instruction::FPExt, V, DestTy, Name);
+  }
+  Value *CreatePtrToInt(Value *V, Type *DestTy,
+                        const Twine &Name = "") {
+    return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
+  }
+  Value *CreateIntToPtr(Value *V, Type *DestTy,
+                        const Twine &Name = "") {
+    return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
+  }
+  Value *CreateBitCast(Value *V, Type *DestTy,
+                       const Twine &Name = "") {
+    return CreateCast(Instruction::BitCast, V, DestTy, Name);
+  }
+  Value *CreateAddrSpaceCast(Value *V, Type *DestTy,
+                             const Twine &Name = "") {
+    return CreateCast(Instruction::AddrSpaceCast, V, DestTy, Name);
+  }
+  Value *CreateZExtOrBitCast(Value *V, Type *DestTy,
+                             const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name);
+    return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
+  }
+  Value *CreateSExtOrBitCast(Value *V, Type *DestTy,
+                             const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name);
+    return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
+  }
+  Value *CreateTruncOrBitCast(Value *V, Type *DestTy,
+                              const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name);
+    return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
+  }
+  Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy,
+                    const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateCast(Op, VC, DestTy), Name);
+    return Insert(CastInst::Create(Op, V, DestTy), Name);
+  }
+  Value *CreatePointerCast(Value *V, Type *DestTy,
+                           const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreatePointerCast(VC, DestTy), Name);
+    return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
+  }
+
+  Value *CreatePointerBitCastOrAddrSpaceCast(Value *V, Type *DestTy,
+                                             const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+
+    if (Constant *VC = dyn_cast<Constant>(V)) {
+      return Insert(Folder.CreatePointerBitCastOrAddrSpaceCast(VC, DestTy),
+                    Name);
+    }
+
+    return Insert(CastInst::CreatePointerBitCastOrAddrSpaceCast(V, DestTy),
+                  Name);
+  }
+
+  Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned,
+                       const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
+    return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
+  }
+private:
+  // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
+  // compile time error, instead of converting the string to bool for the
+  // isSigned parameter.
+  Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION;
+public:
+  Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
+    if (V->getType() == DestTy)
+      return V;
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Insert(Folder.CreateFPCast(VC, DestTy), Name);
+    return Insert(CastInst::CreateFPCast(V, DestTy), Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Compare Instructions
+  //===--------------------------------------------------------------------===//
+
+  Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
+  }
+  Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
+  }
+  Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
+  }
+  Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
+  }
+  Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
+  }
+  Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
+  }
+  Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
+  }
+  Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
+  }
+  Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
+  }
+  Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
+  }
+
+  Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
+  }
+  Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
+  }
+  Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
+  }
+  Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
+  }
+  Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
+  }
+  Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
+  }
+  Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
+  }
+  Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
+  }
+  Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
+  }
+  Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
+  }
+  Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
+  }
+  Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
+  }
+  Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
+  }
+  Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
+    return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
+  }
+
+  Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+                    const Twine &Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateICmp(P, LC, RC), Name);
+    return Insert(new ICmpInst(P, LHS, RHS), Name);
+  }
+  Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+                    const Twine &Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Insert(Folder.CreateFCmp(P, LC, RC), Name);
+    return Insert(new FCmpInst(P, LHS, RHS), Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Instruction creation methods: Other Instructions
+  //===--------------------------------------------------------------------===//
+
+  PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues,
+                     const Twine &Name = "") {
+    return Insert(PHINode::Create(Ty, NumReservedValues), Name);
+  }
+
+  CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
+    return Insert(CallInst::Create(Callee), Name);
+  }
+  CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
+    return Insert(CallInst::Create(Callee, Arg), Name);
+  }
+  CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
+                        const Twine &Name = "") {
+    Value *Args[] = { Arg1, Arg2 };
+    return Insert(CallInst::Create(Callee, Args), Name);
+  }
+  CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+                        const Twine &Name = "") {
+    Value *Args[] = { Arg1, Arg2, Arg3 };
+    return Insert(CallInst::Create(Callee, Args), Name);
+  }
+  CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+                        Value *Arg4, const Twine &Name = "") {
+    Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
+    return Insert(CallInst::Create(Callee, Args), Name);
+  }
+  CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+                        Value *Arg4, Value *Arg5, const Twine &Name = "") {
+    Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
+    return Insert(CallInst::Create(Callee, Args), Name);
+  }
+
+  CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
+                       const Twine &Name = "") {
+    return Insert(CallInst::Create(Callee, Args), Name);
+  }
+
+  Value *CreateSelect(Value *C, Value *True, Value *False,
+                      const Twine &Name = "") {
+    if (Constant *CC = dyn_cast<Constant>(C))
+      if (Constant *TC = dyn_cast<Constant>(True))
+        if (Constant *FC = dyn_cast<Constant>(False))
+          return Insert(Folder.CreateSelect(CC, TC, FC), Name);
+    return Insert(SelectInst::Create(C, True, False), Name);
+  }
+
+  VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
+    return Insert(new VAArgInst(List, Ty), Name);
+  }
+
+  Value *CreateExtractElement(Value *Vec, Value *Idx,
+                              const Twine &Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(Vec))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+        return Insert(Folder.CreateExtractElement(VC, IC), Name);
+    return Insert(ExtractElementInst::Create(Vec, Idx), Name);
+  }
+
+  Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+                             const Twine &Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(Vec))
+      if (Constant *NC = dyn_cast<Constant>(NewElt))
+        if (Constant *IC = dyn_cast<Constant>(Idx))
+          return Insert(Folder.CreateInsertElement(VC, NC, IC), Name);
+    return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
+  }
+
+  Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+                             const Twine &Name = "") {
+    if (Constant *V1C = dyn_cast<Constant>(V1))
+      if (Constant *V2C = dyn_cast<Constant>(V2))
+        if (Constant *MC = dyn_cast<Constant>(Mask))
+          return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
+    return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
+  }
+
+  Value *CreateExtractValue(Value *Agg,
+                            ArrayRef<unsigned> Idxs,
+                            const Twine &Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
+    return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
+  }
+
+  Value *CreateInsertValue(Value *Agg, Value *Val,
+                           ArrayRef<unsigned> Idxs,
+                           const Twine &Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      if (Constant *ValC = dyn_cast<Constant>(Val))
+        return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
+    return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
+  }
+
+  LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
+                                   const Twine &Name = "") {
+    return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses), Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Utility creation methods
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return an i1 value testing if \p Arg is null.
+  Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
+    return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
+                        Name);
+  }
+
+  /// \brief Return an i1 value testing if \p Arg is not null.
+  Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
+    return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
+                        Name);
+  }
+
+  /// \brief Return the i64 difference between two pointer values, dividing out
+  /// the size of the pointed-to objects.
+  ///
+  /// This is intended to implement C-style pointer subtraction. As such, the
+  /// pointers must be appropriately aligned for their element types and
+  /// pointing into the same object.
+  Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
+    assert(LHS->getType() == RHS->getType() &&
+           "Pointer subtraction operand types must match!");
+    PointerType *ArgType = cast<PointerType>(LHS->getType());
+    Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
+    Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
+    Value *Difference = CreateSub(LHS_int, RHS_int);
+    return CreateExactSDiv(Difference,
+                           ConstantExpr::getSizeOf(ArgType->getElementType()),
+                           Name);
+  }
+
+  /// \brief Return a vector value that contains \arg V broadcasted to \p
+  /// NumElts elements.
+  Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") {
+    assert(NumElts > 0 && "Cannot splat to an empty vector!");
+
+    // First insert it into an undef vector so we can shuffle it.
+    Type *I32Ty = getInt32Ty();
+    Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts));
+    V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
+                            Name + ".splatinsert");
+
+    // Shuffle the value across the desired number of elements.
+    Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts));
+    return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
+  }
+
+  /// \brief Return a value that has been extracted from a larger integer type.
+  Value *CreateExtractInteger(const DataLayout &DL, Value *From,
+                              IntegerType *ExtractedTy, uint64_t Offset,
+                              const Twine &Name) {
+    IntegerType *IntTy = cast<IntegerType>(From->getType());
+    assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=
+               DL.getTypeStoreSize(IntTy) &&
+           "Element extends past full value");
+    uint64_t ShAmt = 8 * Offset;
+    Value *V = From;
+    if (DL.isBigEndian())
+      ShAmt = 8 * (DL.getTypeStoreSize(IntTy) -
+                   DL.getTypeStoreSize(ExtractedTy) - Offset);
+    if (ShAmt) {
+      V = CreateLShr(V, ShAmt, Name + ".shift");
+    }
+    assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&
+           "Cannot extract to a larger integer!");
+    if (ExtractedTy != IntTy) {
+      V = CreateTrunc(V, ExtractedTy, Name + ".trunc");
+    }
+    return V;
+  }
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
+
+}
+
+#endif
diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h
new file mode 100644
index 0000000..2f78c83
--- /dev/null
+++ b/include/llvm/IR/IRPrintingPasses.h
@@ -0,0 +1,85 @@
+//===- IRPrintingPasses.h - Passes to print out IR constructs ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines passes to print out IR in various granularities. The
+/// PrintModulePass pass simply prints out the entire module when it is
+/// executed. The PrintFunctionPass class is designed to be pipelined with
+/// other FunctionPass's, and prints out the functions of the module as they
+/// are processed.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_IR_PRINTING_PASSES_H
+#define LLVM_IR_IR_PRINTING_PASSES_H
+
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+class BasicBlockPass;
+class Function;
+class FunctionPass;
+class Module;
+class ModulePass;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief Create and return a pass that writes the module to the specified
+/// \c raw_ostream.
+ModulePass *createPrintModulePass(raw_ostream &OS,
+                                  const std::string &Banner = "");
+
+/// \brief Create and return a pass that prints functions to the specified
+/// \c raw_ostream as they are processed.
+FunctionPass *createPrintFunctionPass(raw_ostream &OS,
+                                      const std::string &Banner = "");
+
+/// \brief Create and return a pass that writes the BB to the specified
+/// \c raw_ostream.
+BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS,
+                                          const std::string &Banner = "");
+
+/// \brief Pass for printing a Module as LLVM's text IR assembly.
+///
+/// Note: This pass is for use with the new pass manager. Use the create...Pass
+/// functions above to create passes for use with the legacy pass manager.
+class PrintModulePass {
+  raw_ostream &OS;
+  std::string Banner;
+
+public:
+  PrintModulePass();
+  PrintModulePass(raw_ostream &OS, const std::string &Banner = "");
+
+  PreservedAnalyses run(Module *M);
+
+  static StringRef name() { return "PrintModulePass"; }
+};
+
+/// \brief Pass for printing a Function as LLVM's text IR assembly.
+///
+/// Note: This pass is for use with the new pass manager. Use the create...Pass
+/// functions above to create passes for use with the legacy pass manager.
+class PrintFunctionPass {
+  raw_ostream &OS;
+  std::string Banner;
+
+public:
+  PrintFunctionPass();
+  PrintFunctionPass(raw_ostream &OS, const std::string &Banner = "");
+
+  PreservedAnalyses run(Function *F);
+
+  static StringRef name() { return "PrintFunctionPass"; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
new file mode 100644
index 0000000..ac19089
--- /dev/null
+++ b/include/llvm/IR/InlineAsm.h
@@ -0,0 +1,306 @@
+//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- 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 inline asm strings, which are Value*'s that are
+// used as the callee operand of call instructions.  InlineAsm's are uniqued
+// like constants, and created via InlineAsm::get(...).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INLINEASM_H
+#define LLVM_IR_INLINEASM_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Value.h"
+#include <vector>
+
+namespace llvm {
+
+class PointerType;
+class FunctionType;
+class Module;
+struct InlineAsmKeyType;
+template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
+         bool HasLargeKey>
+class ConstantUniqueMap;
+template<class ConstantClass, class TypeClass, class ValType>
+struct ConstantCreator;
+
+class InlineAsm : public Value {
+public:
+  enum AsmDialect {
+    AD_ATT,
+    AD_Intel
+  };
+
+private:
+  friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
+  friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
+                                 PointerType, InlineAsm, false>;
+
+  InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION;
+  void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION;
+
+  std::string AsmString, Constraints;
+  bool HasSideEffects;
+  bool IsAlignStack;
+  AsmDialect Dialect;
+
+  InlineAsm(PointerType *Ty, const std::string &AsmString,
+            const std::string &Constraints, bool hasSideEffects,
+            bool isAlignStack, AsmDialect asmDialect);
+  virtual ~InlineAsm();
+
+  /// When the ConstantUniqueMap merges two types and makes two InlineAsms
+  /// identical, it destroys one of them with this method.
+  void destroyConstant();
+public:
+
+  /// InlineAsm::get - Return the specified uniqued inline asm string.
+  ///
+  static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
+                        StringRef Constraints, bool hasSideEffects,
+                        bool isAlignStack = false,
+                        AsmDialect asmDialect = AD_ATT);
+  
+  bool hasSideEffects() const { return HasSideEffects; }
+  bool isAlignStack() const { return IsAlignStack; }
+  AsmDialect getDialect() const { return Dialect; }
+
+  /// getType - InlineAsm's are always pointers.
+  ///
+  PointerType *getType() const {
+    return reinterpret_cast<PointerType*>(Value::getType());
+  }
+  
+  /// getFunctionType - InlineAsm's are always pointers to functions.
+  ///
+  FunctionType *getFunctionType() const;
+  
+  const std::string &getAsmString() const { return AsmString; }
+  const std::string &getConstraintString() const { return Constraints; }
+
+  /// Verify - This static method can be used by the parser to check to see if
+  /// the specified constraint string is legal for the type.  This returns true
+  /// if legal, false if not.
+  ///
+  static bool Verify(FunctionType *Ty, StringRef Constraints);
+
+  // Constraint String Parsing 
+  enum ConstraintPrefix {
+    isInput,            // 'x'
+    isOutput,           // '=x'
+    isClobber           // '~x'
+  };
+  
+  typedef std::vector<std::string> ConstraintCodeVector;
+  
+  struct SubConstraintInfo {
+    /// MatchingInput - If this is not -1, this is an output constraint where an
+    /// input constraint is required to match it (e.g. "0").  The value is the
+    /// constraint number that matches this one (for example, if this is
+    /// constraint #0 and constraint #4 has the value "0", this will be 4).
+    signed char MatchingInput;
+    /// Code - The constraint code, either the register name (in braces) or the
+    /// constraint letter/number.
+    ConstraintCodeVector Codes;
+    /// Default constructor.
+    SubConstraintInfo() : MatchingInput(-1) {}
+  };
+
+  typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
+  struct ConstraintInfo;
+  typedef std::vector<ConstraintInfo> ConstraintInfoVector;
+  
+  struct ConstraintInfo {
+    /// Type - The basic type of the constraint: input/output/clobber
+    ///
+    ConstraintPrefix Type;
+    
+    /// isEarlyClobber - "&": output operand writes result before inputs are all
+    /// read.  This is only ever set for an output operand.
+    bool isEarlyClobber; 
+    
+    /// MatchingInput - If this is not -1, this is an output constraint where an
+    /// input constraint is required to match it (e.g. "0").  The value is the
+    /// constraint number that matches this one (for example, if this is
+    /// constraint #0 and constraint #4 has the value "0", this will be 4).
+    signed char MatchingInput;
+    
+    /// hasMatchingInput - Return true if this is an output constraint that has
+    /// a matching input constraint.
+    bool hasMatchingInput() const { return MatchingInput != -1; }
+    
+    /// isCommutative - This is set to true for a constraint that is commutative
+    /// with the next operand.
+    bool isCommutative;
+    
+    /// isIndirect - True if this operand is an indirect operand.  This means
+    /// that the address of the source or destination is present in the call
+    /// instruction, instead of it being returned or passed in explicitly.  This
+    /// is represented with a '*' in the asm string.
+    bool isIndirect;
+    
+    /// Code - The constraint code, either the register name (in braces) or the
+    /// constraint letter/number.
+    ConstraintCodeVector Codes;
+    
+    /// isMultipleAlternative - '|': has multiple-alternative constraints.
+    bool isMultipleAlternative;
+    
+    /// multipleAlternatives - If there are multiple alternative constraints,
+    /// this array will contain them.  Otherwise it will be empty.
+    SubConstraintInfoVector multipleAlternatives;
+    
+    /// The currently selected alternative constraint index.
+    unsigned currentAlternativeIndex;
+    
+    ///Default constructor.
+    ConstraintInfo();
+    
+    /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
+    /// fields in this structure.  If the constraint string is not understood,
+    /// return true, otherwise return false.
+    bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
+               
+    /// selectAlternative - Point this constraint to the alternative constraint
+    /// indicated by the index.
+    void selectAlternative(unsigned index);
+  };
+  
+  /// ParseConstraints - Split up the constraint string into the specific
+  /// constraints and their prefixes.  If this returns an empty vector, and if
+  /// the constraint string itself isn't empty, there was an error parsing.
+  static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
+  
+  /// ParseConstraints - Parse the constraints of this inlineasm object, 
+  /// returning them the same way that ParseConstraints(str) does.
+  ConstraintInfoVector ParseConstraints() const {
+    return ParseConstraints(Constraints);
+  }
+  
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() == Value::InlineAsmVal;
+  }
+
+  
+  // These are helper methods for dealing with flags in the INLINEASM SDNode
+  // in the backend.
+  
+  enum : uint32_t {
+    // Fixed operands on an INLINEASM SDNode.
+    Op_InputChain = 0,
+    Op_AsmString = 1,
+    Op_MDNode = 2,
+    Op_ExtraInfo = 3,    // HasSideEffects, IsAlignStack, AsmDialect.
+    Op_FirstOperand = 4,
+
+    // Fixed operands on an INLINEASM MachineInstr.
+    MIOp_AsmString = 0,
+    MIOp_ExtraInfo = 1,    // HasSideEffects, IsAlignStack, AsmDialect.
+    MIOp_FirstOperand = 2,
+
+    // Interpretation of the MIOp_ExtraInfo bit field.
+    Extra_HasSideEffects = 1,
+    Extra_IsAlignStack = 2,
+    Extra_AsmDialect = 4,
+    Extra_MayLoad = 8,
+    Extra_MayStore = 16,
+
+    // Inline asm operands map to multiple SDNode / MachineInstr operands.
+    // The first operand is an immediate describing the asm operand, the low
+    // bits is the kind:
+    Kind_RegUse = 1,             // Input register, "r".
+    Kind_RegDef = 2,             // Output register, "=r".
+    Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
+    Kind_Clobber = 4,            // Clobbered register, "~r".
+    Kind_Imm = 5,                // Immediate.
+    Kind_Mem = 6,                // Memory operand, "m".
+
+    Flag_MatchingOperand = 0x80000000
+  };
+  
+  static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
+    assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
+    assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind");
+    return Kind | (NumOps << 3);
+  }
+  
+  /// getFlagWordForMatchingOp - Augment an existing flag word returned by
+  /// getFlagWord with information indicating that this input operand is tied 
+  /// to a previous output operand.
+  static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
+                                           unsigned MatchedOperandNo) {
+    assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
+    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+    return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
+  }
+
+  /// getFlagWordForRegClass - Augment an existing flag word returned by
+  /// getFlagWord with the required register class for the following register
+  /// operands.
+  /// A tied use operand cannot have a register class, use the register class
+  /// from the def operand instead.
+  static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
+    // Store RC + 1, reserve the value 0 to mean 'no register class'.
+    ++RC;
+    assert(RC <= 0x7fff && "Too large register class ID");
+    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+    return InputFlag | (RC << 16);
+  }
+
+  static unsigned getKind(unsigned Flags) {
+    return Flags & 7;
+  }
+
+  static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
+  static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
+  static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
+  static bool isRegDefEarlyClobberKind(unsigned Flag) {
+    return getKind(Flag) == Kind_RegDefEarlyClobber;
+  }
+  static bool isClobberKind(unsigned Flag) {
+    return getKind(Flag) == Kind_Clobber;
+  }
+
+  /// getNumOperandRegisters - Extract the number of registers field from the
+  /// inline asm operand flag.
+  static unsigned getNumOperandRegisters(unsigned Flag) {
+    return (Flag & 0xffff) >> 3;
+  }
+
+  /// isUseOperandTiedToDef - Return true if the flag of the inline asm
+  /// operand indicates it is an use operand that's matched to a def operand.
+  static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
+    if ((Flag & Flag_MatchingOperand) == 0)
+      return false;
+    Idx = (Flag & ~Flag_MatchingOperand) >> 16;
+    return true;
+  }
+
+  /// hasRegClassConstraint - Returns true if the flag contains a register
+  /// class constraint.  Sets RC to the register class ID.
+  static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
+    if (Flag & Flag_MatchingOperand)
+      return false;
+    unsigned High = Flag >> 16;
+    // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
+    // stores RC + 1.
+    if (!High)
+      return false;
+    RC = High - 1;
+    return true;
+  }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h
new file mode 100644
index 0000000..75e93bd
--- /dev/null
+++ b/include/llvm/IR/InstIterator.h
@@ -0,0 +1,147 @@
+//===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions of two iterators for iterating over the
+// instructions in a function.  This is effectively a wrapper around a two level
+// iterator that can probably be genericized later.
+//
+// Note that this iterator gets invalidated any time that basic blocks or
+// instructions are moved around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INSTITERATOR_H
+#define LLVM_IR_INSTITERATOR_H
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+
+namespace llvm {
+
+// This class implements inst_begin() & inst_end() for
+// inst_iterator and const_inst_iterator's.
+//
+template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
+class InstIterator {
+  typedef _BB_t   BBty;
+  typedef _BB_i_t BBIty;
+  typedef _BI_t   BIty;
+  typedef _II_t   IIty;
+  _BB_t  *BBs;      // BasicBlocksType
+  _BB_i_t BB;       // BasicBlocksType::iterator
+  _BI_t   BI;       // BasicBlock::iterator
+public:
+  typedef std::bidirectional_iterator_tag iterator_category;
+  typedef IIty                            value_type;
+  typedef signed                        difference_type;
+  typedef IIty*                           pointer;
+  typedef IIty&                           reference;
+
+  // Default constructor
+  InstIterator() {}
+
+  // Copy constructor...
+  template<typename A, typename B, typename C, typename D>
+  InstIterator(const InstIterator<A,B,C,D> &II)
+    : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+  template<typename A, typename B, typename C, typename D>
+  InstIterator(InstIterator<A,B,C,D> &II)
+    : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+  template<class M> InstIterator(M &m)
+    : BBs(&m.getBasicBlockList()), BB(BBs->begin()) {    // begin ctor
+    if (BB != BBs->end()) {
+      BI = BB->begin();
+      advanceToNextBB();
+    }
+  }
+
+  template<class M> InstIterator(M &m, bool)
+    : BBs(&m.getBasicBlockList()), BB(BBs->end()) {    // end ctor
+  }
+
+  // Accessors to get at the underlying iterators...
+  inline BBIty &getBasicBlockIterator()  { return BB; }
+  inline BIty  &getInstructionIterator() { return BI; }
+
+  inline reference operator*()  const { return *BI; }
+  inline pointer operator->() const { return &operator*(); }
+
+  inline bool operator==(const InstIterator &y) const {
+    return BB == y.BB && (BB == BBs->end() || BI == y.BI);
+  }
+  inline bool operator!=(const InstIterator& y) const {
+    return !operator==(y);
+  }
+
+  InstIterator& operator++() {
+    ++BI;
+    advanceToNextBB();
+    return *this;
+  }
+  inline InstIterator operator++(int) {
+    InstIterator tmp = *this; ++*this; return tmp;
+  }
+
+  InstIterator& operator--() {
+    while (BB == BBs->end() || BI == BB->begin()) {
+      --BB;
+      BI = BB->end();
+    }
+    --BI;
+    return *this;
+  }
+  inline InstIterator  operator--(int) {
+    InstIterator tmp = *this; --*this; return tmp;
+  }
+
+  inline bool atEnd() const { return BB == BBs->end(); }
+
+private:
+  inline void advanceToNextBB() {
+    // The only way that the II could be broken is if it is now pointing to
+    // the end() of the current BasicBlock and there are successor BBs.
+    while (BI == BB->end()) {
+      ++BB;
+      if (BB == BBs->end()) break;
+      BI = BB->begin();
+    }
+  }
+};
+
+
+typedef InstIterator<iplist<BasicBlock>,
+                     Function::iterator, BasicBlock::iterator,
+                     Instruction> inst_iterator;
+typedef InstIterator<const iplist<BasicBlock>,
+                     Function::const_iterator,
+                     BasicBlock::const_iterator,
+                     const Instruction> const_inst_iterator;
+
+inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
+inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
+inline const_inst_iterator inst_begin(const Function *F) {
+  return const_inst_iterator(*F);
+}
+inline const_inst_iterator inst_end(const Function *F) {
+  return const_inst_iterator(*F, true);
+}
+inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
+inline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); }
+inline const_inst_iterator inst_begin(const Function &F) {
+  return const_inst_iterator(F);
+}
+inline const_inst_iterator inst_end(const Function &F) {
+  return const_inst_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h
new file mode 100644
index 0000000..1cdcd55
--- /dev/null
+++ b/include/llvm/IR/InstVisitor.h
@@ -0,0 +1,289 @@
+//===- InstVisitor.h - Instruction visitor templates ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_IR_INSTVISITOR_H
+#define LLVM_IR_INSTVISITOR_H
+
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+// We operate on opaque instruction classes, so forward declare all instruction
+// types now...
+//
+#define HANDLE_INST(NUM, OPCODE, CLASS)   class CLASS;
+#include "llvm/IR/Instruction.def"
+
+#define DELEGATE(CLASS_TO_VISIT) \
+  return static_cast<SubClass*>(this)-> \
+               visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
+
+
+/// @brief Base class for instruction visitors
+///
+/// Instruction visitors are used when you want to perform different actions
+/// for different kinds of instructions without having to use lots of casts
+/// and a big switch statement (in your code, that is).
+///
+/// To define your own visitor, inherit from this class, specifying your
+/// new type for the 'SubClass' template parameter, and "override" visitXXX
+/// functions in your class. I say "override" because this class is defined
+/// in terms of statically resolved overloading, not virtual functions.
+///
+/// For example, here is a visitor that counts the number of malloc
+/// instructions processed:
+///
+///  /// Declare the class.  Note that we derive from InstVisitor instantiated
+///  /// with _our new subclasses_ type.
+///  ///
+///  struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
+///    unsigned Count;
+///    CountAllocaVisitor() : Count(0) {}
+///
+///    void visitAllocaInst(AllocaInst &AI) { ++Count; }
+///  };
+///
+///  And this class would be used like this:
+///    CountAllocaVisitor CAV;
+///    CAV.visit(function);
+///    NumAllocas = CAV.Count;
+///
+/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
+/// Function, and Module, which recursively process all contained instructions.
+///
+/// Note that if you don't implement visitXXX for some instruction type,
+/// the visitXXX method for instruction superclass will be invoked. So
+/// if instructions are added in the future, they will be automatically
+/// supported, if you handle one of their superclasses.
+///
+/// The optional second template argument specifies the type that instruction
+/// visitation functions should return. If you specify this, you *MUST* provide
+/// an implementation of visitInstruction though!.
+///
+/// Note that this class is specifically designed as a template to avoid
+/// virtual function call overhead.  Defining and using an InstVisitor is just
+/// as efficient as having your own switch statement over the instruction
+/// opcode.
+template<typename SubClass, typename RetTy=void>
+class InstVisitor {
+  //===--------------------------------------------------------------------===//
+  // Interface code - This is the public interface of the InstVisitor that you
+  // use to visit instructions...
+  //
+
+public:
+  // Generic visit method - Allow visitation to all instructions in a range
+  template<class Iterator>
+  void visit(Iterator Start, Iterator End) {
+    while (Start != End)
+      static_cast<SubClass*>(this)->visit(*Start++);
+  }
+
+  // Define visitors for functions and basic blocks...
+  //
+  void visit(Module &M) {
+    static_cast<SubClass*>(this)->visitModule(M);
+    visit(M.begin(), M.end());
+  }
+  void visit(Function &F) {
+    static_cast<SubClass*>(this)->visitFunction(F);
+    visit(F.begin(), F.end());
+  }
+  void visit(BasicBlock &BB) {
+    static_cast<SubClass*>(this)->visitBasicBlock(BB);
+    visit(BB.begin(), BB.end());
+  }
+
+  // Forwarding functions so that the user can visit with pointers AND refs.
+  void visit(Module       *M)  { visit(*M); }
+  void visit(Function     *F)  { visit(*F); }
+  void visit(BasicBlock   *BB) { visit(*BB); }
+  RetTy visit(Instruction *I)  { return visit(*I); }
+
+  // visit - Finally, code to visit an instruction...
+  //
+  RetTy visit(Instruction &I) {
+    switch (I.getOpcode()) {
+    default: llvm_unreachable("Unknown instruction type encountered!");
+      // Build the switch statement using the Instruction.def file...
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+    case Instruction::OPCODE: return \
+           static_cast<SubClass*>(this)-> \
+                      visit##OPCODE(static_cast<CLASS&>(I));
+#include "llvm/IR/Instruction.def"
+    }
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Visitation functions... these functions provide default fallbacks in case
+  // the user does not specify what to do for a particular instruction type.
+  // The default behavior is to generalize the instruction type to its subtype
+  // and try visiting the subtype.  All of this should be inlined perfectly,
+  // because there are no virtual functions to get in the way.
+  //
+
+  // When visiting a module, function or basic block directly, these methods get
+  // called to indicate when transitioning into a new unit.
+  //
+  void visitModule    (Module &M) {}
+  void visitFunction  (Function &F) {}
+  void visitBasicBlock(BasicBlock &BB) {}
+
+  // Define instruction specific visitor functions that can be overridden to
+  // handle SPECIFIC instructions.  These functions automatically define
+  // visitMul to proxy to visitBinaryOperator for instance in case the user does
+  // not need this generality.
+  //
+  // These functions can also implement fan-out, when a single opcode and
+  // instruction have multiple more specific Instruction subclasses. The Call
+  // instruction currently supports this. We implement that by redirecting that
+  // instruction to a special delegation helper.
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+    RetTy visit##OPCODE(CLASS &I) { \
+      if (NUM == Instruction::Call) \
+        return delegateCallInst(I); \
+      else \
+        DELEGATE(CLASS); \
+    }
+#include "llvm/IR/Instruction.def"
+
+  // Specific Instruction type classes... note that all of the casts are
+  // necessary because we use the instruction classes as opaque types...
+  //
+  RetTy visitReturnInst(ReturnInst &I)            { DELEGATE(TerminatorInst);}
+  RetTy visitBranchInst(BranchInst &I)            { DELEGATE(TerminatorInst);}
+  RetTy visitSwitchInst(SwitchInst &I)            { DELEGATE(TerminatorInst);}
+  RetTy visitIndirectBrInst(IndirectBrInst &I)    { DELEGATE(TerminatorInst);}
+  RetTy visitResumeInst(ResumeInst &I)            { DELEGATE(TerminatorInst);}
+  RetTy visitUnreachableInst(UnreachableInst &I)  { DELEGATE(TerminatorInst);}
+  RetTy visitICmpInst(ICmpInst &I)                { DELEGATE(CmpInst);}
+  RetTy visitFCmpInst(FCmpInst &I)                { DELEGATE(CmpInst);}
+  RetTy visitAllocaInst(AllocaInst &I)            { DELEGATE(UnaryInstruction);}
+  RetTy visitLoadInst(LoadInst     &I)            { DELEGATE(UnaryInstruction);}
+  RetTy visitStoreInst(StoreInst   &I)            { DELEGATE(Instruction);}
+  RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
+  RetTy visitAtomicRMWInst(AtomicRMWInst &I)      { DELEGATE(Instruction);}
+  RetTy visitFenceInst(FenceInst   &I)            { DELEGATE(Instruction);}
+  RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
+  RetTy visitPHINode(PHINode       &I)            { DELEGATE(Instruction);}
+  RetTy visitTruncInst(TruncInst &I)              { DELEGATE(CastInst);}
+  RetTy visitZExtInst(ZExtInst &I)                { DELEGATE(CastInst);}
+  RetTy visitSExtInst(SExtInst &I)                { DELEGATE(CastInst);}
+  RetTy visitFPTruncInst(FPTruncInst &I)          { DELEGATE(CastInst);}
+  RetTy visitFPExtInst(FPExtInst &I)              { DELEGATE(CastInst);}
+  RetTy visitFPToUIInst(FPToUIInst &I)            { DELEGATE(CastInst);}
+  RetTy visitFPToSIInst(FPToSIInst &I)            { DELEGATE(CastInst);}
+  RetTy visitUIToFPInst(UIToFPInst &I)            { DELEGATE(CastInst);}
+  RetTy visitSIToFPInst(SIToFPInst &I)            { DELEGATE(CastInst);}
+  RetTy visitPtrToIntInst(PtrToIntInst &I)        { DELEGATE(CastInst);}
+  RetTy visitIntToPtrInst(IntToPtrInst &I)        { DELEGATE(CastInst);}
+  RetTy visitBitCastInst(BitCastInst &I)          { DELEGATE(CastInst);}
+  RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
+  RetTy visitSelectInst(SelectInst &I)            { DELEGATE(Instruction);}
+  RetTy visitVAArgInst(VAArgInst   &I)            { DELEGATE(UnaryInstruction);}
+  RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
+  RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
+  RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
+  RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
+  RetTy visitInsertValueInst(InsertValueInst &I)  { DELEGATE(Instruction); }
+  RetTy visitLandingPadInst(LandingPadInst &I)    { DELEGATE(Instruction); }
+
+  // Handle the special instrinsic instruction classes.
+  RetTy visitDbgDeclareInst(DbgDeclareInst &I)    { DELEGATE(DbgInfoIntrinsic);}
+  RetTy visitDbgValueInst(DbgValueInst &I)        { DELEGATE(DbgInfoIntrinsic);}
+  RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
+  RetTy visitMemSetInst(MemSetInst &I)            { DELEGATE(MemIntrinsic); }
+  RetTy visitMemCpyInst(MemCpyInst &I)            { DELEGATE(MemTransferInst); }
+  RetTy visitMemMoveInst(MemMoveInst &I)          { DELEGATE(MemTransferInst); }
+  RetTy visitMemTransferInst(MemTransferInst &I)  { DELEGATE(MemIntrinsic); }
+  RetTy visitMemIntrinsic(MemIntrinsic &I)        { DELEGATE(IntrinsicInst); }
+  RetTy visitVAStartInst(VAStartInst &I)          { DELEGATE(IntrinsicInst); }
+  RetTy visitVAEndInst(VAEndInst &I)              { DELEGATE(IntrinsicInst); }
+  RetTy visitVACopyInst(VACopyInst &I)            { DELEGATE(IntrinsicInst); }
+  RetTy visitIntrinsicInst(IntrinsicInst &I)      { DELEGATE(CallInst); }
+
+  // Call and Invoke are slightly different as they delegate first through
+  // a generic CallSite visitor.
+  RetTy visitCallInst(CallInst &I) {
+    return static_cast<SubClass*>(this)->visitCallSite(&I);
+  }
+  RetTy visitInvokeInst(InvokeInst &I) {
+    return static_cast<SubClass*>(this)->visitCallSite(&I);
+  }
+
+  // Next level propagators: If the user does not overload a specific
+  // instruction type, they can overload one of these to get the whole class
+  // of instructions...
+  //
+  RetTy visitCastInst(CastInst &I)                { DELEGATE(UnaryInstruction);}
+  RetTy visitBinaryOperator(BinaryOperator &I)    { DELEGATE(Instruction);}
+  RetTy visitCmpInst(CmpInst &I)                  { DELEGATE(Instruction);}
+  RetTy visitTerminatorInst(TerminatorInst &I)    { DELEGATE(Instruction);}
+  RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
+
+  // Provide a special visitor for a 'callsite' that visits both calls and
+  // invokes. When unimplemented, properly delegates to either the terminator or
+  // regular instruction visitor.
+  RetTy visitCallSite(CallSite CS) {
+    assert(CS);
+    Instruction &I = *CS.getInstruction();
+    if (CS.isCall())
+      DELEGATE(Instruction);
+
+    assert(CS.isInvoke());
+    DELEGATE(TerminatorInst);
+  }
+
+  // If the user wants a 'default' case, they can choose to override this
+  // function.  If this function is not overloaded in the user's subclass, then
+  // this instruction just gets ignored.
+  //
+  // Note that you MUST override this function if your return type is not void.
+  //
+  void visitInstruction(Instruction &I) {}  // Ignore unhandled instructions
+
+private:
+  // Special helper function to delegate to CallInst subclass visitors.
+  RetTy delegateCallInst(CallInst &I) {
+    if (const Function *F = I.getCalledFunction()) {
+      switch ((Intrinsic::ID)F->getIntrinsicID()) {
+      default:                     DELEGATE(IntrinsicInst);
+      case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
+      case Intrinsic::dbg_value:   DELEGATE(DbgValueInst);
+      case Intrinsic::memcpy:      DELEGATE(MemCpyInst);
+      case Intrinsic::memmove:     DELEGATE(MemMoveInst);
+      case Intrinsic::memset:      DELEGATE(MemSetInst);
+      case Intrinsic::vastart:     DELEGATE(VAStartInst);
+      case Intrinsic::vaend:       DELEGATE(VAEndInst);
+      case Intrinsic::vacopy:      DELEGATE(VACopyInst);
+      case Intrinsic::not_intrinsic: break;
+      }
+    }
+    DELEGATE(CallInst);
+  }
+
+  // An overload that will never actually be called, it is used only from dead
+  // code in the dispatching from opcodes to instruction subclasses.
+  RetTy delegateCallInst(Instruction &I) {
+    llvm_unreachable("delegateCallInst called for non-CallInst");
+  }
+};
+
+#undef DELEGATE
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
new file mode 100644
index 0000000..981aad8
--- /dev/null
+++ b/include/llvm/IR/InstrTypes.h
@@ -0,0 +1,878 @@
+//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- 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 various meta classes of instructions that exist in the VM
+// representation.  Specific concrete subclasses of these may be found in the
+// i*.h files...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INSTRTYPES_H
+#define LLVM_IR_INSTRTYPES_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/OperandTraits.h"
+
+namespace llvm {
+
+class LLVMContext;
+
+//===----------------------------------------------------------------------===//
+//                            TerminatorInst Class
+//===----------------------------------------------------------------------===//
+
+/// TerminatorInst - Subclasses of this class are all able to terminate a basic
+/// block.  Thus, these are all the flow control type of operations.
+///
+class TerminatorInst : public Instruction {
+protected:
+  TerminatorInst(Type *Ty, Instruction::TermOps iType,
+                 Use *Ops, unsigned NumOps,
+                 Instruction *InsertBefore = nullptr)
+    : Instruction(Ty, iType, Ops, NumOps, InsertBefore) {}
+
+  TerminatorInst(Type *Ty, Instruction::TermOps iType,
+                 Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
+    : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
+
+  // Out of line virtual method, so the vtable, etc has a home.
+  ~TerminatorInst();
+
+  /// Virtual methods - Terminators should overload these and provide inline
+  /// overrides of non-V methods.
+  virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
+  virtual unsigned getNumSuccessorsV() const = 0;
+  virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
+  TerminatorInst *clone_impl() const override = 0;
+public:
+
+  /// getNumSuccessors - Return the number of successors that this terminator
+  /// has.
+  unsigned getNumSuccessors() const {
+    return getNumSuccessorsV();
+  }
+
+  /// getSuccessor - Return the specified successor.
+  ///
+  BasicBlock *getSuccessor(unsigned idx) const {
+    return getSuccessorV(idx);
+  }
+
+  /// setSuccessor - Update the specified successor to point at the provided
+  /// block.
+  void setSuccessor(unsigned idx, BasicBlock *B) {
+    setSuccessorV(idx, B);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->isTerminator();
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+//                          UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
+class UnaryInstruction : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+
+protected:
+  UnaryInstruction(Type *Ty, unsigned iType, Value *V,
+                   Instruction *IB = nullptr)
+    : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+    Op<0>() = V;
+  }
+  UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
+    : Instruction(Ty, iType, &Op<0>(), 1, IAE) {
+    Op<0>() = V;
+  }
+public:
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+
+  // Out of line virtual method, so the vtable, etc has a home.
+  ~UnaryInstruction();
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Alloca ||
+           I->getOpcode() == Instruction::Load ||
+           I->getOpcode() == Instruction::VAArg ||
+           I->getOpcode() == Instruction::ExtractValue ||
+           (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<UnaryInstruction> :
+  public FixedNumOperandTraits<UnaryInstruction, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
+
+//===----------------------------------------------------------------------===//
+//                           BinaryOperator Class
+//===----------------------------------------------------------------------===//
+
+class BinaryOperator : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+protected:
+  void init(BinaryOps iType);
+  BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
+                 const Twine &Name, Instruction *InsertBefore);
+  BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
+                 const Twine &Name, BasicBlock *InsertAtEnd);
+  BinaryOperator *clone_impl() const override;
+public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Create() - Construct a binary instruction, given the opcode and the two
+  /// operands.  Optionally (if InstBefore is specified) insert the instruction
+  /// into a BasicBlock right before the specified instruction.  The specified
+  /// Instruction is allowed to be a dereferenced end iterator.
+  ///
+  static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2,
+                                const Twine &Name = Twine(),
+                                Instruction *InsertBefore = nullptr);
+
+  /// Create() - Construct a binary instruction, given the opcode and the two
+  /// operands.  Also automatically insert this instruction to the end of the
+  /// BasicBlock specified.
+  ///
+  static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2,
+                                const Twine &Name, BasicBlock *InsertAtEnd);
+
+  /// Create* - These methods just forward to Create, and are useful when you
+  /// statically know what type of instruction you're going to create.  These
+  /// helpers just save some typing.
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+  static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
+                                     const Twine &Name = "") {\
+    return Create(Instruction::OPC, V1, V2, Name);\
+  }
+#include "llvm/IR/Instruction.def"
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+  static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
+                                     const Twine &Name, BasicBlock *BB) {\
+    return Create(Instruction::OPC, V1, V2, Name, BB);\
+  }
+#include "llvm/IR/Instruction.def"
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+  static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
+                                     const Twine &Name, Instruction *I) {\
+    return Create(Instruction::OPC, V1, V2, Name, I);\
+  }
+#include "llvm/IR/Instruction.def"
+
+  static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name = "") {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name);
+    BO->setHasNoSignedWrap(true);
+    return BO;
+  }
+  static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name, BasicBlock *BB) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+    BO->setHasNoSignedWrap(true);
+    return BO;
+  }
+  static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name, Instruction *I) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+    BO->setHasNoSignedWrap(true);
+    return BO;
+  }
+  
+  static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name = "") {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name);
+    BO->setHasNoUnsignedWrap(true);
+    return BO;
+  }
+  static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name, BasicBlock *BB) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+    BO->setHasNoUnsignedWrap(true);
+    return BO;
+  }
+  static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+                                   const Twine &Name, Instruction *I) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+    BO->setHasNoUnsignedWrap(true);
+    return BO;
+  }
+  
+  static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+                                     const Twine &Name = "") {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name);
+    BO->setIsExact(true);
+    return BO;
+  }
+  static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+                                     const Twine &Name, BasicBlock *BB) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+    BO->setIsExact(true);
+    return BO;
+  }
+  static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+                                     const Twine &Name, Instruction *I) {
+    BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+    BO->setIsExact(true);
+    return BO;
+  }
+  
+#define DEFINE_HELPERS(OPC, NUWNSWEXACT)                                     \
+  static BinaryOperator *Create ## NUWNSWEXACT ## OPC                        \
+           (Value *V1, Value *V2, const Twine &Name = "") {                  \
+    return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name);            \
+  }                                                                          \
+  static BinaryOperator *Create ## NUWNSWEXACT ## OPC                        \
+           (Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) {       \
+    return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB);        \
+  }                                                                          \
+  static BinaryOperator *Create ## NUWNSWEXACT ## OPC                        \
+           (Value *V1, Value *V2, const Twine &Name, Instruction *I) {       \
+    return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I);         \
+  }
+  
+  DEFINE_HELPERS(Add, NSW)  // CreateNSWAdd
+  DEFINE_HELPERS(Add, NUW)  // CreateNUWAdd
+  DEFINE_HELPERS(Sub, NSW)  // CreateNSWSub
+  DEFINE_HELPERS(Sub, NUW)  // CreateNUWSub
+  DEFINE_HELPERS(Mul, NSW)  // CreateNSWMul
+  DEFINE_HELPERS(Mul, NUW)  // CreateNUWMul
+  DEFINE_HELPERS(Shl, NSW)  // CreateNSWShl
+  DEFINE_HELPERS(Shl, NUW)  // CreateNUWShl
+
+  DEFINE_HELPERS(SDiv, Exact)  // CreateExactSDiv
+  DEFINE_HELPERS(UDiv, Exact)  // CreateExactUDiv
+  DEFINE_HELPERS(AShr, Exact)  // CreateExactAShr
+  DEFINE_HELPERS(LShr, Exact)  // CreateExactLShr
+
+#undef DEFINE_HELPERS
+  
+  /// Helper functions to construct and inspect unary operations (NEG and NOT)
+  /// via binary operators SUB and XOR:
+  ///
+  /// CreateNeg, CreateNot - Create the NEG and NOT
+  ///     instructions out of SUB and XOR instructions.
+  ///
+  static BinaryOperator *CreateNeg(Value *Op, const Twine &Name = "",
+                                   Instruction *InsertBefore = nullptr);
+  static BinaryOperator *CreateNeg(Value *Op, const Twine &Name,
+                                   BasicBlock *InsertAtEnd);
+  static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "",
+                                      Instruction *InsertBefore = nullptr);
+  static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name,
+                                      BasicBlock *InsertAtEnd);
+  static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "",
+                                      Instruction *InsertBefore = nullptr);
+  static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
+                                      BasicBlock *InsertAtEnd);
+  static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "",
+                                    Instruction *InsertBefore = nullptr);
+  static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name,
+                                    BasicBlock *InsertAtEnd);
+  static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "",
+                                   Instruction *InsertBefore = nullptr);
+  static BinaryOperator *CreateNot(Value *Op, const Twine &Name,
+                                   BasicBlock *InsertAtEnd);
+
+  /// isNeg, isFNeg, isNot - Check if the given Value is a
+  /// NEG, FNeg, or NOT instruction.
+  ///
+  static bool isNeg(const Value *V);
+  static bool isFNeg(const Value *V, bool IgnoreZeroSign=false);
+  static bool isNot(const Value *V);
+
+  /// getNegArgument, getNotArgument - Helper functions to extract the
+  ///     unary argument of a NEG, FNEG or NOT operation implemented via
+  ///     Sub, FSub, or Xor.
+  ///
+  static const Value *getNegArgument(const Value *BinOp);
+  static       Value *getNegArgument(      Value *BinOp);
+  static const Value *getFNegArgument(const Value *BinOp);
+  static       Value *getFNegArgument(      Value *BinOp);
+  static const Value *getNotArgument(const Value *BinOp);
+  static       Value *getNotArgument(      Value *BinOp);
+
+  BinaryOps getOpcode() const {
+    return static_cast<BinaryOps>(Instruction::getOpcode());
+  }
+
+  /// swapOperands - Exchange the two operands to this instruction.
+  /// This instruction is safe to use on any binary instruction and
+  /// does not modify the semantics of the instruction.  If the instruction
+  /// cannot be reversed (ie, it's a Div), then return true.
+  ///
+  bool swapOperands();
+
+  /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
+  /// which must be an operator which supports this flag. See LangRef.html
+  /// for the meaning of this flag.
+  void setHasNoUnsignedWrap(bool b = true);
+
+  /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
+  /// which must be an operator which supports this flag. See LangRef.html
+  /// for the meaning of this flag.
+  void setHasNoSignedWrap(bool b = true);
+
+  /// setIsExact - Set or clear the exact flag on this instruction,
+  /// which must be an operator which supports this flag. See LangRef.html
+  /// for the meaning of this flag.
+  void setIsExact(bool b = true);
+
+  /// hasNoUnsignedWrap - Determine whether the no unsigned wrap flag is set.
+  bool hasNoUnsignedWrap() const;
+
+  /// hasNoSignedWrap - Determine whether the no signed wrap flag is set.
+  bool hasNoSignedWrap() const;
+
+  /// isExact - Determine whether the exact flag is set.
+  bool isExact() const;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->isBinaryOp();
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<BinaryOperator> :
+  public FixedNumOperandTraits<BinaryOperator, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
+
+//===----------------------------------------------------------------------===//
+//                               CastInst Class
+//===----------------------------------------------------------------------===//
+
+/// CastInst - This is the base class for all instructions that perform data
+/// casts. It is simply provided so that instruction category testing
+/// can be performed with code like:
+///
+/// if (isa<CastInst>(Instr)) { ... }
+/// @brief Base class of casting instructions.
+class CastInst : public UnaryInstruction {
+  void anchor() override;
+protected:
+  /// @brief Constructor with insert-before-instruction semantics for subclasses
+  CastInst(Type *Ty, unsigned iType, Value *S,
+           const Twine &NameStr = "", Instruction *InsertBefore = nullptr)
+    : UnaryInstruction(Ty, iType, S, InsertBefore) {
+    setName(NameStr);
+  }
+  /// @brief Constructor with insert-at-end-of-block semantics for subclasses
+  CastInst(Type *Ty, unsigned iType, Value *S,
+           const Twine &NameStr, BasicBlock *InsertAtEnd)
+    : UnaryInstruction(Ty, iType, S, InsertAtEnd) {
+    setName(NameStr);
+  }
+public:
+  /// Provides a way to construct any of the CastInst subclasses using an
+  /// opcode instead of the subclass's constructor. The opcode must be in the
+  /// CastOps category (Instruction::isCast(opcode) returns true). This
+  /// constructor has insert-before-instruction semantics to automatically
+  /// insert the new CastInst before InsertBefore (if it is non-null).
+  /// @brief Construct any of the CastInst subclasses
+  static CastInst *Create(
+    Instruction::CastOps,    ///< The opcode of the cast instruction
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+  /// Provides a way to construct any of the CastInst subclasses using an
+  /// opcode instead of the subclass's constructor. The opcode must be in the
+  /// CastOps category. This constructor has insert-at-end-of-block semantics
+  /// to automatically insert the new CastInst at the end of InsertAtEnd (if
+  /// its non-null).
+  /// @brief Construct any of the CastInst subclasses
+  static CastInst *Create(
+    Instruction::CastOps,    ///< The opcode for the cast instruction
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a ZExt or BitCast cast instruction
+  static CastInst *CreateZExtOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create a ZExt or BitCast cast instruction
+  static CastInst *CreateZExtOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a SExt or BitCast cast instruction
+  static CastInst *CreateSExtOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create a SExt or BitCast cast instruction
+  static CastInst *CreateSExtOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction.
+  static CastInst *CreatePointerCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction.
+  static CastInst *CreatePointerCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create a BitCast or an AddrSpaceCast cast instruction.
+  static CastInst *CreatePointerBitCastOrAddrSpaceCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a BitCast or an AddrSpaceCast cast instruction.
+  static CastInst *CreatePointerBitCastOrAddrSpaceCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = 0 ///< Place to insert the instruction
+  );
+
+  /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+  static CastInst *CreateIntegerCast(
+    Value *S,                ///< The pointer value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    bool isSigned,           ///< Whether to regard S as signed or not
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+  static CastInst *CreateIntegerCast(
+    Value *S,                ///< The integer value to be casted (operand 0)
+    Type *Ty,          ///< The integer type to which operand is casted
+    bool isSigned,           ///< Whether to regard S as signed or not
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+  static CastInst *CreateFPCast(
+    Value *S,                ///< The floating point value to be casted
+    Type *Ty,          ///< The floating point type to cast to
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+  static CastInst *CreateFPCast(
+    Value *S,                ///< The floating point value to be casted
+    Type *Ty,          ///< The floating point type to cast to
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Create a Trunc or BitCast cast instruction
+  static CastInst *CreateTruncOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which cast should be made
+    const Twine &Name = "", ///< Name for the instruction
+    Instruction *InsertBefore = nullptr ///< Place to insert the instruction
+  );
+
+  /// @brief Create a Trunc or BitCast cast instruction
+  static CastInst *CreateTruncOrBitCast(
+    Value *S,                ///< The value to be casted (operand 0)
+    Type *Ty,          ///< The type to which operand is casted
+    const Twine &Name, ///< The name for the instruction
+    BasicBlock *InsertAtEnd  ///< The block to insert the instruction into
+  );
+
+  /// @brief Check whether it is valid to call getCastOpcode for these types.
+  static bool isCastable(
+    Type *SrcTy, ///< The Type from which the value should be cast.
+    Type *DestTy ///< The Type to which the value should be cast.
+  );
+
+  /// @brief Check whether a bitcast between these types is valid
+  static bool isBitCastable(
+    Type *SrcTy, ///< The Type from which the value should be cast.
+    Type *DestTy ///< The Type to which the value should be cast.
+  );
+
+  /// Returns the opcode necessary to cast Val into Ty using usual casting
+  /// rules.
+  /// @brief Infer the opcode for cast operand and type
+  static Instruction::CastOps getCastOpcode(
+    const Value *Val, ///< The value to cast
+    bool SrcIsSigned, ///< Whether to treat the source as signed
+    Type *Ty,   ///< The Type to which the value should be casted
+    bool DstIsSigned  ///< Whether to treate the dest. as signed
+  );
+
+  /// There are several places where we need to know if a cast instruction
+  /// only deals with integer source and destination types. To simplify that
+  /// logic, this method is provided.
+  /// @returns true iff the cast has only integral typed operand and dest type.
+  /// @brief Determine if this is an integer-only cast.
+  bool isIntegerCast() const;
+
+  /// A lossless cast is one that does not alter the basic value. It implies
+  /// a no-op cast but is more stringent, preventing things like int->float,
+  /// long->double, or int->ptr.
+  /// @returns true iff the cast is lossless.
+  /// @brief Determine if this is a lossless cast.
+  bool isLosslessCast() const;
+
+  /// A no-op cast is one that can be effected without changing any bits.
+  /// It implies that the source and destination types are the same size. The
+  /// IntPtrTy argument is used to make accurate determinations for casts
+  /// involving Integer and Pointer types. They are no-op casts if the integer
+  /// is the same size as the pointer. However, pointer size varies with
+  /// platform. Generally, the result of DataLayout::getIntPtrType() should be
+  /// passed in. If that's not available, use Type::Int64Ty, which will make
+  /// the isNoopCast call conservative.
+  /// @brief Determine if the described cast is a no-op cast.
+  static bool isNoopCast(
+    Instruction::CastOps Opcode,  ///< Opcode of cast
+    Type *SrcTy,   ///< SrcTy of cast
+    Type *DstTy,   ///< DstTy of cast
+    Type *IntPtrTy ///< Integer type corresponding to Ptr types
+  );
+
+  /// @brief Determine if this cast is a no-op cast.
+  bool isNoopCast(
+    Type *IntPtrTy ///< Integer type corresponding to pointer
+  ) const;
+
+  /// @brief Determine if this cast is a no-op cast.
+  bool isNoopCast(
+    const DataLayout *DL ///< DataLayout to get the Int Ptr type from.
+  ) const;
+
+  /// Determine how a pair of casts can be eliminated, if they can be at all.
+  /// This is a helper function for both CastInst and ConstantExpr.
+  /// @returns 0 if the CastInst pair can't be eliminated, otherwise
+  /// returns Instruction::CastOps value for a cast that can replace
+  /// the pair, casting SrcTy to DstTy.
+  /// @brief Determine if a cast pair is eliminable
+  static unsigned isEliminableCastPair(
+    Instruction::CastOps firstOpcode,  ///< Opcode of first cast
+    Instruction::CastOps secondOpcode, ///< Opcode of second cast
+    Type *SrcTy, ///< SrcTy of 1st cast
+    Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
+    Type *DstTy, ///< DstTy of 2nd cast
+    Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null
+    Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null
+    Type *DstIntPtrTy  ///< Integer type corresponding to Ptr DstTy, or null
+  );
+
+  /// @brief Return the opcode of this CastInst
+  Instruction::CastOps getOpcode() const {
+    return Instruction::CastOps(Instruction::getOpcode());
+  }
+
+  /// @brief Return the source type, as a convenience
+  Type* getSrcTy() const { return getOperand(0)->getType(); }
+  /// @brief Return the destination type, as a convenience
+  Type* getDestTy() const { return getType(); }
+
+  /// This method can be used to determine if a cast from S to DstTy using
+  /// Opcode op is valid or not.
+  /// @returns true iff the proposed cast is valid.
+  /// @brief Determine if a cast is valid without creating one.
+  static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy);
+
+  /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->isCast();
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                               CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class is the base class for the comparison instructions.
+/// @brief Abstract base class of comparison instructions.
+class CmpInst : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  CmpInst() LLVM_DELETED_FUNCTION;
+protected:
+  CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
+          Value *LHS, Value *RHS, const Twine &Name = "",
+          Instruction *InsertBefore = nullptr);
+
+  CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
+          Value *LHS, Value *RHS, const Twine &Name,
+          BasicBlock *InsertAtEnd);
+
+  void anchor() override; // Out of line virtual method.
+public:
+  /// This enumeration lists the possible predicates for CmpInst subclasses.
+  /// Values in the range 0-31 are reserved for FCmpInst, while values in the
+  /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+  /// predicate values are not overlapping between the classes.
+  enum Predicate {
+    // Opcode              U L G E    Intuitive operation
+    FCMP_FALSE =  0,  ///< 0 0 0 0    Always false (always folded)
+    FCMP_OEQ   =  1,  ///< 0 0 0 1    True if ordered and equal
+    FCMP_OGT   =  2,  ///< 0 0 1 0    True if ordered and greater than
+    FCMP_OGE   =  3,  ///< 0 0 1 1    True if ordered and greater than or equal
+    FCMP_OLT   =  4,  ///< 0 1 0 0    True if ordered and less than
+    FCMP_OLE   =  5,  ///< 0 1 0 1    True if ordered and less than or equal
+    FCMP_ONE   =  6,  ///< 0 1 1 0    True if ordered and operands are unequal
+    FCMP_ORD   =  7,  ///< 0 1 1 1    True if ordered (no nans)
+    FCMP_UNO   =  8,  ///< 1 0 0 0    True if unordered: isnan(X) | isnan(Y)
+    FCMP_UEQ   =  9,  ///< 1 0 0 1    True if unordered or equal
+    FCMP_UGT   = 10,  ///< 1 0 1 0    True if unordered or greater than
+    FCMP_UGE   = 11,  ///< 1 0 1 1    True if unordered, greater than, or equal
+    FCMP_ULT   = 12,  ///< 1 1 0 0    True if unordered or less than
+    FCMP_ULE   = 13,  ///< 1 1 0 1    True if unordered, less than, or equal
+    FCMP_UNE   = 14,  ///< 1 1 1 0    True if unordered or not equal
+    FCMP_TRUE  = 15,  ///< 1 1 1 1    Always true (always folded)
+    FIRST_FCMP_PREDICATE = FCMP_FALSE,
+    LAST_FCMP_PREDICATE = FCMP_TRUE,
+    BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
+    ICMP_EQ    = 32,  ///< equal
+    ICMP_NE    = 33,  ///< not equal
+    ICMP_UGT   = 34,  ///< unsigned greater than
+    ICMP_UGE   = 35,  ///< unsigned greater or equal
+    ICMP_ULT   = 36,  ///< unsigned less than
+    ICMP_ULE   = 37,  ///< unsigned less or equal
+    ICMP_SGT   = 38,  ///< signed greater than
+    ICMP_SGE   = 39,  ///< signed greater or equal
+    ICMP_SLT   = 40,  ///< signed less than
+    ICMP_SLE   = 41,  ///< signed less or equal
+    FIRST_ICMP_PREDICATE = ICMP_EQ,
+    LAST_ICMP_PREDICATE = ICMP_SLE,
+    BAD_ICMP_PREDICATE = ICMP_SLE + 1
+  };
+
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+  /// Construct a compare instruction, given the opcode, the predicate and
+  /// the two operands.  Optionally (if InstBefore is specified) insert the
+  /// instruction into a BasicBlock right before the specified instruction.
+  /// The specified Instruction is allowed to be a dereferenced end iterator.
+  /// @brief Create a CmpInst
+  static CmpInst *Create(OtherOps Op,
+                         unsigned short predicate, Value *S1,
+                         Value *S2, const Twine &Name = "",
+                         Instruction *InsertBefore = nullptr);
+
+  /// Construct a compare instruction, given the opcode, the predicate and the
+  /// two operands.  Also automatically insert this instruction to the end of
+  /// the BasicBlock specified.
+  /// @brief Create a CmpInst
+  static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1,
+                         Value *S2, const Twine &Name, BasicBlock *InsertAtEnd);
+
+  /// @brief Get the opcode casted to the right type
+  OtherOps getOpcode() const {
+    return static_cast<OtherOps>(Instruction::getOpcode());
+  }
+
+  /// @brief Return the predicate for this instruction.
+  Predicate getPredicate() const {
+    return Predicate(getSubclassDataFromInstruction());
+  }
+
+  /// @brief Set the predicate for this instruction to the specified value.
+  void setPredicate(Predicate P) { setInstructionSubclassData(P); }
+
+  static bool isFPPredicate(Predicate P) {
+    return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE;
+  }
+
+  static bool isIntPredicate(Predicate P) {
+    return P >= FIRST_ICMP_PREDICATE && P <= LAST_ICMP_PREDICATE;
+  }
+
+  bool isFPPredicate() const { return isFPPredicate(getPredicate()); }
+  bool isIntPredicate() const { return isIntPredicate(getPredicate()); }
+
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
+  ///              OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+  /// @returns the inverse predicate for the instruction's current predicate.
+  /// @brief Return the inverse of the instruction's predicate.
+  Predicate getInversePredicate() const {
+    return getInversePredicate(getPredicate());
+  }
+
+  /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
+  ///              OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+  /// @returns the inverse predicate for predicate provided in \p pred.
+  /// @brief Return the inverse of a given predicate
+  static Predicate getInversePredicate(Predicate pred);
+
+  /// For example, EQ->EQ, SLE->SGE, ULT->UGT,
+  ///              OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
+  /// @returns the predicate that would be the result of exchanging the two
+  /// operands of the CmpInst instruction without changing the result
+  /// produced.
+  /// @brief Return the predicate as if the operands were swapped
+  Predicate getSwappedPredicate() const {
+    return getSwappedPredicate(getPredicate());
+  }
+
+  /// This is a static version that you can use without an instruction
+  /// available.
+  /// @brief Return the predicate as if the operands were swapped.
+  static Predicate getSwappedPredicate(Predicate pred);
+
+  /// @brief Provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Swap the operands and adjust predicate accordingly to retain
+  /// the same comparison.
+  void swapOperands();
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Determine if this CmpInst is commutative.
+  bool isCommutative() const;
+
+  /// This is just a convenience that dispatches to the subclasses.
+  /// @brief Determine if this is an equals/not equals predicate.
+  bool isEquality() const;
+
+  /// @returns true if the comparison is signed, false otherwise.
+  /// @brief Determine if this instruction is using a signed comparison.
+  bool isSigned() const {
+    return isSigned(getPredicate());
+  }
+
+  /// @returns true if the comparison is unsigned, false otherwise.
+  /// @brief Determine if this instruction is using an unsigned comparison.
+  bool isUnsigned() const {
+    return isUnsigned(getPredicate());
+  }
+
+  /// This is just a convenience.
+  /// @brief Determine if this is true when both operands are the same.
+  bool isTrueWhenEqual() const {
+    return isTrueWhenEqual(getPredicate());
+  }
+
+  /// This is just a convenience.
+  /// @brief Determine if this is false when both operands are the same.
+  bool isFalseWhenEqual() const {
+    return isFalseWhenEqual(getPredicate());
+  }
+
+  /// @returns true if the predicate is unsigned, false otherwise.
+  /// @brief Determine if the predicate is an unsigned operation.
+  static bool isUnsigned(unsigned short predicate);
+
+  /// @returns true if the predicate is signed, false otherwise.
+  /// @brief Determine if the predicate is an signed operation.
+  static bool isSigned(unsigned short predicate);
+
+  /// @brief Determine if the predicate is an ordered operation.
+  static bool isOrdered(unsigned short predicate);
+
+  /// @brief Determine if the predicate is an unordered operation.
+  static bool isUnordered(unsigned short predicate);
+
+  /// Determine if the predicate is true when comparing a value with itself.
+  static bool isTrueWhenEqual(unsigned short predicate);
+
+  /// Determine if the predicate is false when comparing a value with itself.
+  static bool isFalseWhenEqual(unsigned short predicate);
+
+  /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ICmp ||
+           I->getOpcode() == Instruction::FCmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+
+  /// @brief Create a result type for fcmp/icmp
+  static Type* makeCmpResultType(Type* opnd_type) {
+    if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
+      return VectorType::get(Type::getInt1Ty(opnd_type->getContext()),
+                             vt->getNumElements());
+    }
+    return Type::getInt1Ty(opnd_type->getContext());
+  }
+private:
+  // Shadow Value::setValueSubclassData with a private forwarding method so that
+  // subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+};
+
+
+// FIXME: these are redundant if CmpInst < BinaryOperator
+template <>
+struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Instruction.def b/include/llvm/IR/Instruction.def
new file mode 100644
index 0000000..d46314c
--- /dev/null
+++ b/include/llvm/IR/Instruction.def
@@ -0,0 +1,200 @@
+//===-- llvm/Instruction.def - File that describes Instructions -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains descriptions of the various LLVM instructions.  This is
+// used as a central place for enumerating the different instructions and 
+// should eventually be the place to put comments about the instructions.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+// Provide definitions of macros so that users of this file do not have to 
+// define everything to use it...
+//
+#ifndef FIRST_TERM_INST
+#define FIRST_TERM_INST(num)
+#endif
+#ifndef HANDLE_TERM_INST
+#ifndef HANDLE_INST
+#define HANDLE_TERM_INST(num, opcode, Class)
+#else
+#define HANDLE_TERM_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_TERM_INST
+#define LAST_TERM_INST(num)
+#endif
+
+#ifndef FIRST_BINARY_INST
+#define FIRST_BINARY_INST(num)
+#endif
+#ifndef HANDLE_BINARY_INST
+#ifndef HANDLE_INST
+#define HANDLE_BINARY_INST(num, opcode, instclass)
+#else
+#define HANDLE_BINARY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_BINARY_INST
+#define LAST_BINARY_INST(num)
+#endif
+
+#ifndef FIRST_MEMORY_INST
+#define FIRST_MEMORY_INST(num)
+#endif
+#ifndef HANDLE_MEMORY_INST
+#ifndef HANDLE_INST
+#define HANDLE_MEMORY_INST(num, opcode, Class)
+#else
+#define HANDLE_MEMORY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_MEMORY_INST
+#define LAST_MEMORY_INST(num)
+#endif
+
+#ifndef FIRST_CAST_INST
+#define FIRST_CAST_INST(num)
+#endif
+#ifndef HANDLE_CAST_INST
+#ifndef HANDLE_INST
+#define HANDLE_CAST_INST(num, opcode, Class)
+#else
+#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_CAST_INST
+#define LAST_CAST_INST(num)
+#endif
+
+#ifndef FIRST_OTHER_INST
+#define FIRST_OTHER_INST(num)
+#endif
+#ifndef HANDLE_OTHER_INST
+#ifndef HANDLE_INST
+#define HANDLE_OTHER_INST(num, opcode, Class)
+#else
+#define HANDLE_OTHER_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_OTHER_INST
+#define LAST_OTHER_INST(num)
+#endif
+
+
+// Terminator Instructions - These instructions are used to terminate a basic
+// block of the program.   Every basic block must end with one of these
+// instructions for it to be a well formed basic block.
+//
+ FIRST_TERM_INST  ( 1)
+HANDLE_TERM_INST  ( 1, Ret        , ReturnInst)
+HANDLE_TERM_INST  ( 2, Br         , BranchInst)
+HANDLE_TERM_INST  ( 3, Switch     , SwitchInst)
+HANDLE_TERM_INST  ( 4, IndirectBr , IndirectBrInst)
+HANDLE_TERM_INST  ( 5, Invoke     , InvokeInst)
+HANDLE_TERM_INST  ( 6, Resume     , ResumeInst)
+HANDLE_TERM_INST  ( 7, Unreachable, UnreachableInst)
+  LAST_TERM_INST  ( 7)
+
+// Standard binary operators...
+ FIRST_BINARY_INST( 8)
+HANDLE_BINARY_INST( 8, Add  , BinaryOperator)
+HANDLE_BINARY_INST( 9, FAdd , BinaryOperator)
+HANDLE_BINARY_INST(10, Sub  , BinaryOperator)
+HANDLE_BINARY_INST(11, FSub , BinaryOperator)
+HANDLE_BINARY_INST(12, Mul  , BinaryOperator)
+HANDLE_BINARY_INST(13, FMul , BinaryOperator)
+HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(17, URem , BinaryOperator)
+HANDLE_BINARY_INST(18, SRem , BinaryOperator)
+HANDLE_BINARY_INST(19, FRem , BinaryOperator)
+
+// Logical operators (integer operands)
+HANDLE_BINARY_INST(20, Shl  , BinaryOperator) // Shift left  (logical)
+HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
+HANDLE_BINARY_INST(23, And  , BinaryOperator)
+HANDLE_BINARY_INST(24, Or   , BinaryOperator)
+HANDLE_BINARY_INST(25, Xor  , BinaryOperator)
+  LAST_BINARY_INST(25)
+
+// Memory operators...
+ FIRST_MEMORY_INST(26)
+HANDLE_MEMORY_INST(26, Alloca, AllocaInst)  // Stack management
+HANDLE_MEMORY_INST(27, Load  , LoadInst  )  // Memory manipulation instrs
+HANDLE_MEMORY_INST(28, Store , StoreInst )
+HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst)
+HANDLE_MEMORY_INST(30, Fence , FenceInst )
+HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst )
+HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst )
+  LAST_MEMORY_INST(32)
+
+// Cast operators ...
+// NOTE: The order matters here because CastInst::isEliminableCastPair 
+// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
+ FIRST_CAST_INST(33)
+HANDLE_CAST_INST(33, Trunc   , TruncInst   )  // Truncate integers
+HANDLE_CAST_INST(34, ZExt    , ZExtInst    )  // Zero extend integers
+HANDLE_CAST_INST(35, SExt    , SExtInst    )  // Sign extend integers
+HANDLE_CAST_INST(36, FPToUI  , FPToUIInst  )  // floating point -> UInt
+HANDLE_CAST_INST(37, FPToSI  , FPToSIInst  )  // floating point -> SInt
+HANDLE_CAST_INST(38, UIToFP  , UIToFPInst  )  // UInt -> floating point
+HANDLE_CAST_INST(39, SIToFP  , SIToFPInst  )  // SInt -> floating point
+HANDLE_CAST_INST(40, FPTrunc , FPTruncInst )  // Truncate floating point
+HANDLE_CAST_INST(41, FPExt   , FPExtInst   )  // Extend floating point
+HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst)  // Pointer -> Integer
+HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst)  // Integer -> Pointer
+HANDLE_CAST_INST(44, BitCast , BitCastInst )  // Type cast
+HANDLE_CAST_INST(45, AddrSpaceCast, AddrSpaceCastInst)  // addrspace cast
+  LAST_CAST_INST(45)
+
+// Other operators...
+ FIRST_OTHER_INST(46)
+HANDLE_OTHER_INST(46, ICmp   , ICmpInst   )  // Integer comparison instruction
+HANDLE_OTHER_INST(47, FCmp   , FCmpInst   )  // Floating point comparison instr.
+HANDLE_OTHER_INST(48, PHI    , PHINode    )  // PHI node instruction
+HANDLE_OTHER_INST(49, Call   , CallInst   )  // Call a function
+HANDLE_OTHER_INST(50, Select , SelectInst )  // select instruction
+HANDLE_OTHER_INST(51, UserOp1, Instruction)  // May be used internally in a pass
+HANDLE_OTHER_INST(52, UserOp2, Instruction)  // Internal to passes only
+HANDLE_OTHER_INST(53, VAArg  , VAArgInst  )  // vaarg instruction
+HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
+HANDLE_OTHER_INST(55, InsertElement, InsertElementInst)  // insert into vector
+HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
+HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
+HANDLE_OTHER_INST(58, InsertValue, InsertValueInst)  // insert into aggregate
+HANDLE_OTHER_INST(59, LandingPad, LandingPadInst)  // Landing pad instruction.
+  LAST_OTHER_INST(59)
+
+#undef  FIRST_TERM_INST
+#undef HANDLE_TERM_INST
+#undef   LAST_TERM_INST
+
+#undef  FIRST_BINARY_INST
+#undef HANDLE_BINARY_INST
+#undef   LAST_BINARY_INST
+
+#undef  FIRST_MEMORY_INST
+#undef HANDLE_MEMORY_INST
+#undef   LAST_MEMORY_INST
+
+#undef  FIRST_CAST_INST
+#undef HANDLE_CAST_INST
+#undef   LAST_CAST_INST
+
+#undef  FIRST_OTHER_INST
+#undef HANDLE_OTHER_INST
+#undef   LAST_OTHER_INST
+
+#ifdef HANDLE_INST
+#undef HANDLE_INST
+#endif
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
new file mode 100644
index 0000000..bac6a95
--- /dev/null
+++ b/include/llvm/IR/Instruction.h
@@ -0,0 +1,485 @@
+//===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Instruction class, which is the
+// base class for all of the LLVM instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INSTRUCTION_H
+#define LLVM_IR_INSTRUCTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/User.h"
+
+namespace llvm {
+
+class FastMathFlags;
+class LLVMContext;
+class MDNode;
+
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+class Instruction : public User, public ilist_node<Instruction> {
+  void operator=(const Instruction &) LLVM_DELETED_FUNCTION;
+  Instruction(const Instruction &) LLVM_DELETED_FUNCTION;
+
+  BasicBlock *Parent;
+  DebugLoc DbgLoc;                         // 'dbg' Metadata cache.
+
+  enum {
+    /// HasMetadataBit - This is a bit stored in the SubClassData field which
+    /// indicates whether this instruction has metadata attached to it or not.
+    HasMetadataBit = 1 << 15
+  };
+public:
+  // Out of line virtual method, so the vtable, etc has a home.
+  ~Instruction();
+
+  /// user_back - Specialize the methods defined in Value, as we know that an
+  /// instruction can only be used by other instructions.
+  Instruction       *user_back()       { return cast<Instruction>(*user_begin());}
+  const Instruction *user_back() const { return cast<Instruction>(*user_begin());}
+
+  inline const BasicBlock *getParent() const { return Parent; }
+  inline       BasicBlock *getParent()       { return Parent; }
+
+  const DataLayout *getDataLayout() const;
+
+  /// removeFromParent - This method unlinks 'this' from the containing basic
+  /// block, but does not delete it.
+  ///
+  void removeFromParent();
+
+  /// eraseFromParent - This method unlinks 'this' from the containing basic
+  /// block and deletes it.
+  ///
+  void eraseFromParent();
+
+  /// insertBefore - Insert an unlinked instructions into a basic block
+  /// immediately before the specified instruction.
+  void insertBefore(Instruction *InsertPos);
+
+  /// insertAfter - Insert an unlinked instructions into a basic block
+  /// immediately after the specified instruction.
+  void insertAfter(Instruction *InsertPos);
+
+  /// moveBefore - Unlink this instruction from its current basic block and
+  /// insert it into the basic block that MovePos lives in, right before
+  /// MovePos.
+  void moveBefore(Instruction *MovePos);
+
+  //===--------------------------------------------------------------------===//
+  // Subclass classification.
+  //===--------------------------------------------------------------------===//
+
+  /// getOpcode() returns a member of one of the enums like Instruction::Add.
+  unsigned getOpcode() const { return getValueID() - InstructionVal; }
+
+  const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
+  bool isTerminator() const { return isTerminator(getOpcode()); }
+  bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
+  bool isShift() { return isShift(getOpcode()); }
+  bool isCast() const { return isCast(getOpcode()); }
+
+  static const char* getOpcodeName(unsigned OpCode);
+
+  static inline bool isTerminator(unsigned OpCode) {
+    return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
+  }
+
+  static inline bool isBinaryOp(unsigned Opcode) {
+    return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
+  }
+
+  /// @brief Determine if the Opcode is one of the shift instructions.
+  static inline bool isShift(unsigned Opcode) {
+    return Opcode >= Shl && Opcode <= AShr;
+  }
+
+  /// isLogicalShift - Return true if this is a logical shift left or a logical
+  /// shift right.
+  inline bool isLogicalShift() const {
+    return getOpcode() == Shl || getOpcode() == LShr;
+  }
+
+  /// isArithmeticShift - Return true if this is an arithmetic shift right.
+  inline bool isArithmeticShift() const {
+    return getOpcode() == AShr;
+  }
+
+  /// @brief Determine if the OpCode is one of the CastInst instructions.
+  static inline bool isCast(unsigned OpCode) {
+    return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Metadata manipulation.
+  //===--------------------------------------------------------------------===//
+
+  /// hasMetadata() - Return true if this instruction has any metadata attached
+  /// to it.
+  bool hasMetadata() const {
+    return !DbgLoc.isUnknown() || hasMetadataHashEntry();
+  }
+
+  /// hasMetadataOtherThanDebugLoc - Return true if this instruction has
+  /// metadata attached to it other than a debug location.
+  bool hasMetadataOtherThanDebugLoc() const {
+    return hasMetadataHashEntry();
+  }
+
+  /// getMetadata - Get the metadata of given kind attached to this Instruction.
+  /// If the metadata is not found then return null.
+  MDNode *getMetadata(unsigned KindID) const {
+    if (!hasMetadata()) return nullptr;
+    return getMetadataImpl(KindID);
+  }
+
+  /// getMetadata - Get the metadata of given kind attached to this Instruction.
+  /// If the metadata is not found then return null.
+  MDNode *getMetadata(StringRef Kind) const {
+    if (!hasMetadata()) return nullptr;
+    return getMetadataImpl(Kind);
+  }
+
+  /// getAllMetadata - Get all metadata attached to this Instruction.  The first
+  /// element of each pair returned is the KindID, the second element is the
+  /// metadata value.  This list is returned sorted by the KindID.
+  void getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const{
+    if (hasMetadata())
+      getAllMetadataImpl(MDs);
+  }
+
+  /// getAllMetadataOtherThanDebugLoc - This does the same thing as
+  /// getAllMetadata, except that it filters out the debug location.
+  void getAllMetadataOtherThanDebugLoc(SmallVectorImpl<std::pair<unsigned,
+                                       MDNode*> > &MDs) const {
+    if (hasMetadataOtherThanDebugLoc())
+      getAllMetadataOtherThanDebugLocImpl(MDs);
+  }
+
+  /// setMetadata - Set the metadata of the specified kind to the specified
+  /// node.  This updates/replaces metadata if already present, or removes it if
+  /// Node is null.
+  void setMetadata(unsigned KindID, MDNode *Node);
+  void setMetadata(StringRef Kind, MDNode *Node);
+
+  /// \brief Drop unknown metadata.
+  /// Passes are required to drop metadata they don't understand. This is a
+  /// convenience method for passes to do so.
+  void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
+  void dropUnknownMetadata() {
+    return dropUnknownMetadata(ArrayRef<unsigned>());
+  }
+  void dropUnknownMetadata(unsigned ID1) {
+    return dropUnknownMetadata(makeArrayRef(ID1));
+  }
+  void dropUnknownMetadata(unsigned ID1, unsigned ID2) {
+    unsigned IDs[] = {ID1, ID2};
+    return dropUnknownMetadata(IDs);
+  }
+
+  /// setDebugLoc - Set the debug location information for this instruction.
+  void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
+
+  /// getDebugLoc - Return the debug location for this node as a DebugLoc.
+  const DebugLoc &getDebugLoc() const { return DbgLoc; }
+
+  /// Set or clear the unsafe-algebra flag on this instruction, which must be an
+  /// operator which supports this flag. See LangRef.html for the meaning of
+  /// this flag.
+  void setHasUnsafeAlgebra(bool B);
+
+  /// Set or clear the no-nans flag on this instruction, which must be an
+  /// operator which supports this flag. See LangRef.html for the meaning of
+  /// this flag.
+  void setHasNoNaNs(bool B);
+
+  /// Set or clear the no-infs flag on this instruction, which must be an
+  /// operator which supports this flag. See LangRef.html for the meaning of
+  /// this flag.
+  void setHasNoInfs(bool B);
+
+  /// Set or clear the no-signed-zeros flag on this instruction, which must be
+  /// an operator which supports this flag. See LangRef.html for the meaning of
+  /// this flag.
+  void setHasNoSignedZeros(bool B);
+
+  /// Set or clear the allow-reciprocal flag on this instruction, which must be
+  /// an operator which supports this flag. See LangRef.html for the meaning of
+  /// this flag.
+  void setHasAllowReciprocal(bool B);
+
+  /// Convenience function for setting all the fast-math flags on this
+  /// instruction, which must be an operator which supports these flags. See
+  /// LangRef.html for the meaning of these flats.
+  void setFastMathFlags(FastMathFlags FMF);
+
+  /// Determine whether the unsafe-algebra flag is set.
+  bool hasUnsafeAlgebra() const;
+
+  /// Determine whether the no-NaNs flag is set.
+  bool hasNoNaNs() const;
+
+  /// Determine whether the no-infs flag is set.
+  bool hasNoInfs() const;
+
+  /// Determine whether the no-signed-zeros flag is set.
+  bool hasNoSignedZeros() const;
+
+  /// Determine whether the allow-reciprocal flag is set.
+  bool hasAllowReciprocal() const;
+
+  /// Convenience function for getting all the fast-math flags, which must be an
+  /// operator which supports these flags. See LangRef.html for the meaning of
+  /// these flats.
+  FastMathFlags getFastMathFlags() const;
+
+  /// Copy I's fast-math flags
+  void copyFastMathFlags(const Instruction *I);
+
+private:
+  /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
+  /// metadata hash.
+  bool hasMetadataHashEntry() const {
+    return (getSubclassDataFromValue() & HasMetadataBit) != 0;
+  }
+
+  // These are all implemented in Metadata.cpp.
+  MDNode *getMetadataImpl(unsigned KindID) const;
+  MDNode *getMetadataImpl(StringRef Kind) const;
+  void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode*> > &)const;
+  void getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned,
+                                           MDNode*> > &) const;
+  void clearMetadataHashEntries();
+public:
+  //===--------------------------------------------------------------------===//
+  // Predicates and helper methods.
+  //===--------------------------------------------------------------------===//
+
+
+  /// isAssociative - Return true if the instruction is associative:
+  ///
+  ///   Associative operators satisfy:  x op (y op z) === (x op y) op z
+  ///
+  /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative.
+  ///
+  bool isAssociative() const;
+  static bool isAssociative(unsigned op);
+
+  /// isCommutative - Return true if the instruction is commutative:
+  ///
+  ///   Commutative operators satisfy: (x op y) === (y op x)
+  ///
+  /// In LLVM, these are the associative operators, plus SetEQ and SetNE, when
+  /// applied to any type.
+  ///
+  bool isCommutative() const { return isCommutative(getOpcode()); }
+  static bool isCommutative(unsigned op);
+
+  /// isIdempotent - Return true if the instruction is idempotent:
+  ///
+  ///   Idempotent operators satisfy:  x op x === x
+  ///
+  /// In LLVM, the And and Or operators are idempotent.
+  ///
+  bool isIdempotent() const { return isIdempotent(getOpcode()); }
+  static bool isIdempotent(unsigned op);
+
+  /// isNilpotent - Return true if the instruction is nilpotent:
+  ///
+  ///   Nilpotent operators satisfy:  x op x === Id,
+  ///
+  ///   where Id is the identity for the operator, i.e. a constant such that
+  ///     x op Id === x and Id op x === x for all x.
+  ///
+  /// In LLVM, the Xor operator is nilpotent.
+  ///
+  bool isNilpotent() const { return isNilpotent(getOpcode()); }
+  static bool isNilpotent(unsigned op);
+
+  /// mayWriteToMemory - Return true if this instruction may modify memory.
+  ///
+  bool mayWriteToMemory() const;
+
+  /// mayReadFromMemory - Return true if this instruction may read memory.
+  ///
+  bool mayReadFromMemory() const;
+
+  /// mayReadOrWriteMemory - Return true if this instruction may read or
+  /// write memory.
+  ///
+  bool mayReadOrWriteMemory() const {
+    return mayReadFromMemory() || mayWriteToMemory();
+  }
+
+  /// mayThrow - Return true if this instruction may throw an exception.
+  ///
+  bool mayThrow() const;
+
+  /// mayReturn - Return true if this is a function that may return.
+  /// this is true for all normal instructions. The only exception
+  /// is functions that are marked with the 'noreturn' attribute.
+  ///
+  bool mayReturn() const;
+
+  /// mayHaveSideEffects - Return true if the instruction may have side effects.
+  ///
+  /// Note that this does not consider malloc and alloca to have side
+  /// effects because the newly allocated memory is completely invisible to
+  /// instructions which don't used the returned value.  For cases where this
+  /// matters, isSafeToSpeculativelyExecute may be more appropriate.
+  bool mayHaveSideEffects() const {
+    return mayWriteToMemory() || mayThrow() || !mayReturn();
+  }
+
+  /// clone() - Create a copy of 'this' instruction that is identical in all
+  /// ways except the following:
+  ///   * The instruction has no parent
+  ///   * The instruction has no name
+  ///
+  Instruction *clone() const;
+
+  /// isIdenticalTo - Return true if the specified instruction is exactly
+  /// identical to the current one.  This means that all operands match and any
+  /// extra information (e.g. load is volatile) agree.
+  bool isIdenticalTo(const Instruction *I) const;
+
+  /// isIdenticalToWhenDefined - This is like isIdenticalTo, except that it
+  /// ignores the SubclassOptionalData flags, which specify conditions
+  /// under which the instruction's result is undefined.
+  bool isIdenticalToWhenDefined(const Instruction *I) const;
+
+  /// When checking for operation equivalence (using isSameOperationAs) it is
+  /// sometimes useful to ignore certain attributes.
+  enum OperationEquivalenceFlags {
+    /// Check for equivalence ignoring load/store alignment.
+    CompareIgnoringAlignment = 1<<0,
+    /// Check for equivalence treating a type and a vector of that type
+    /// as equivalent.
+    CompareUsingScalarTypes = 1<<1
+  };
+
+  /// This function determines if the specified instruction executes the same
+  /// operation as the current one. This means that the opcodes, type, operand
+  /// types and any other factors affecting the operation must be the same. This
+  /// is similar to isIdenticalTo except the operands themselves don't have to
+  /// be identical.
+  /// @returns true if the specified instruction is the same operation as
+  /// the current one.
+  /// @brief Determine if one instruction is the same operation as another.
+  bool isSameOperationAs(const Instruction *I, unsigned flags = 0) const;
+
+  /// isUsedOutsideOfBlock - Return true if there are any uses of this
+  /// instruction in blocks other than the specified block.  Note that PHI nodes
+  /// are considered to evaluate their operands in the corresponding predecessor
+  /// block.
+  bool isUsedOutsideOfBlock(const BasicBlock *BB) const;
+
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return V->getValueID() >= Value::InstructionVal;
+  }
+
+  //----------------------------------------------------------------------
+  // Exported enumerations.
+  //
+  enum TermOps {       // These terminate basic blocks
+#define  FIRST_TERM_INST(N)             TermOpsBegin = N,
+#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_TERM_INST(N)             TermOpsEnd = N+1
+#include "llvm/IR/Instruction.def"
+  };
+
+  enum BinaryOps {
+#define  FIRST_BINARY_INST(N)             BinaryOpsBegin = N,
+#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_BINARY_INST(N)             BinaryOpsEnd = N+1
+#include "llvm/IR/Instruction.def"
+  };
+
+  enum MemoryOps {
+#define  FIRST_MEMORY_INST(N)             MemoryOpsBegin = N,
+#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_MEMORY_INST(N)             MemoryOpsEnd = N+1
+#include "llvm/IR/Instruction.def"
+  };
+
+  enum CastOps {
+#define  FIRST_CAST_INST(N)             CastOpsBegin = N,
+#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_CAST_INST(N)             CastOpsEnd = N+1
+#include "llvm/IR/Instruction.def"
+  };
+
+  enum OtherOps {
+#define  FIRST_OTHER_INST(N)             OtherOpsBegin = N,
+#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
+#define   LAST_OTHER_INST(N)             OtherOpsEnd = N+1
+#include "llvm/IR/Instruction.def"
+  };
+private:
+  // Shadow Value::setValueSubclassData with a private forwarding method so that
+  // subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+  unsigned short getSubclassDataFromValue() const {
+    return Value::getSubclassDataFromValue();
+  }
+
+  void setHasMetadataHashEntry(bool V) {
+    setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
+                         (V ? HasMetadataBit : 0));
+  }
+
+  friend class SymbolTableListTraits<Instruction, BasicBlock>;
+  void setParent(BasicBlock *P);
+protected:
+  // Instruction subclasses can stick up to 15 bits of stuff into the
+  // SubclassData field of instruction with these members.
+
+  // Verify that only the low 15 bits are used.
+  void setInstructionSubclassData(unsigned short D) {
+    assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
+    setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
+  }
+
+  unsigned getSubclassDataFromInstruction() const {
+    return getSubclassDataFromValue() & ~HasMetadataBit;
+  }
+
+  Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+              Instruction *InsertBefore = nullptr);
+  Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+              BasicBlock *InsertAtEnd);
+  virtual Instruction *clone_impl() const = 0;
+
+};
+
+// Instruction* is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<Instruction*> {
+  typedef Instruction* PT;
+public:
+  static inline void *getAsVoidPointer(PT P) { return P; }
+  static inline PT getFromVoidPointer(void *P) {
+    return static_cast<PT>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
new file mode 100644
index 0000000..308467f
--- /dev/null
+++ b/include/llvm/IR/Instructions.h
@@ -0,0 +1,3799 @@
+//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes the class definitions of all of the subclasses of the
+// Instruction class.  This is meant to be an easy way to get access to all
+// instruction subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INSTRUCTIONS_H
+#define LLVM_IR_INSTRUCTIONS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <iterator>
+
+namespace llvm {
+
+class APInt;
+class ConstantInt;
+class ConstantRange;
+class DataLayout;
+class LLVMContext;
+
+enum AtomicOrdering {
+  NotAtomic = 0,
+  Unordered = 1,
+  Monotonic = 2,
+  // Consume = 3,  // Not specified yet.
+  Acquire = 4,
+  Release = 5,
+  AcquireRelease = 6,
+  SequentiallyConsistent = 7
+};
+
+enum SynchronizationScope {
+  SingleThread = 0,
+  CrossThread = 1
+};
+
+//===----------------------------------------------------------------------===//
+//                                AllocaInst Class
+//===----------------------------------------------------------------------===//
+
+/// AllocaInst - an instruction to allocate memory on the stack
+///
+class AllocaInst : public UnaryInstruction {
+protected:
+  AllocaInst *clone_impl() const override;
+public:
+  explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr,
+                      const Twine &Name = "",
+                      Instruction *InsertBefore = nullptr);
+  AllocaInst(Type *Ty, Value *ArraySize,
+             const Twine &Name, BasicBlock *InsertAtEnd);
+
+  AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = nullptr);
+  AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd);
+
+  AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+             const Twine &Name = "", Instruction *InsertBefore = nullptr);
+  AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+             const Twine &Name, BasicBlock *InsertAtEnd);
+
+  // Out of line virtual method, so the vtable, etc. has a home.
+  virtual ~AllocaInst();
+
+  /// isArrayAllocation - Return true if there is an allocation size parameter
+  /// to the allocation instruction that is not 1.
+  ///
+  bool isArrayAllocation() const;
+
+  /// getArraySize - Get the number of elements allocated. For a simple
+  /// allocation of a single element, this will return a constant 1 value.
+  ///
+  const Value *getArraySize() const { return getOperand(0); }
+  Value *getArraySize() { return getOperand(0); }
+
+  /// getType - Overload to return most specific pointer type
+  ///
+  PointerType *getType() const {
+    return cast<PointerType>(Instruction::getType());
+  }
+
+  /// getAllocatedType - Return the type that is being allocated by the
+  /// instruction.
+  ///
+  Type *getAllocatedType() const;
+
+  /// getAlignment - Return the alignment of the memory that is being allocated
+  /// by the instruction.
+  ///
+  unsigned getAlignment() const {
+    return (1u << (getSubclassDataFromInstruction() & 31)) >> 1;
+  }
+  void setAlignment(unsigned Align);
+
+  /// isStaticAlloca - Return true if this alloca is in the entry block of the
+  /// function and is a constant size.  If so, the code generator will fold it
+  /// into the prolog/epilog code, so it is basically free.
+  bool isStaticAlloca() const;
+
+  /// \brief Return true if this alloca is used as an inalloca argument to a
+  /// call.  Such allocas are never considered static even if they are in the
+  /// entry block.
+  bool isUsedWithInAlloca() const {
+    return getSubclassDataFromInstruction() & 32;
+  }
+
+  /// \brief Specify whether this alloca is used to represent a the arguments to
+  /// a call.
+  void setUsedWithInAlloca(bool V) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~32) |
+                               (V ? 32 : 0));
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::Alloca);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+//                                LoadInst Class
+//===----------------------------------------------------------------------===//
+
+/// LoadInst - an instruction for reading from memory.  This uses the
+/// SubclassData field in Value to store whether or not the load is volatile.
+///
+class LoadInst : public UnaryInstruction {
+  void AssertOK();
+protected:
+  LoadInst *clone_impl() const override;
+public:
+  LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore);
+  LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false,
+           Instruction *InsertBefore = nullptr);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+           BasicBlock *InsertAtEnd);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+           unsigned Align, Instruction *InsertBefore = nullptr);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+           unsigned Align, BasicBlock *InsertAtEnd);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+           unsigned Align, AtomicOrdering Order,
+           SynchronizationScope SynchScope = CrossThread,
+           Instruction *InsertBefore = nullptr);
+  LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+           unsigned Align, AtomicOrdering Order,
+           SynchronizationScope SynchScope,
+           BasicBlock *InsertAtEnd);
+
+  LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore);
+  LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd);
+  explicit LoadInst(Value *Ptr, const char *NameStr = nullptr,
+                    bool isVolatile = false,
+                    Instruction *InsertBefore = nullptr);
+  LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
+           BasicBlock *InsertAtEnd);
+
+  /// isVolatile - Return true if this is a load from a volatile memory
+  /// location.
+  ///
+  bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+
+  /// setVolatile - Specify whether this is a volatile load or not.
+  ///
+  void setVolatile(bool V) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                               (V ? 1 : 0));
+  }
+
+  /// getAlignment - Return the alignment of the access that is being performed
+  ///
+  unsigned getAlignment() const {
+    return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1;
+  }
+
+  void setAlignment(unsigned Align);
+
+  /// Returns the ordering effect of this fence.
+  AtomicOrdering getOrdering() const {
+    return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+  }
+
+  /// Set the ordering constraint on this load. May not be Release or
+  /// AcquireRelease.
+  void setOrdering(AtomicOrdering Ordering) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
+                               (Ordering << 7));
+  }
+
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+  }
+
+  /// Specify whether this load is ordered with respect to all
+  /// concurrently executing threads, or only with respect to signal handlers
+  /// executing in the same thread.
+  void setSynchScope(SynchronizationScope xthread) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
+                               (xthread << 6));
+  }
+
+  bool isAtomic() const { return getOrdering() != NotAtomic; }
+  void setAtomic(AtomicOrdering Ordering,
+                 SynchronizationScope SynchScope = CrossThread) {
+    setOrdering(Ordering);
+    setSynchScope(SynchScope);
+  }
+
+  bool isSimple() const { return !isAtomic() && !isVolatile(); }
+  bool isUnordered() const {
+    return getOrdering() <= Unordered && !isVolatile();
+  }
+
+  Value *getPointerOperand() { return getOperand(0); }
+  const Value *getPointerOperand() const { return getOperand(0); }
+  static unsigned getPointerOperandIndex() { return 0U; }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperand()->getType()->getPointerAddressSpace();
+  }
+
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Load;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+//                                StoreInst Class
+//===----------------------------------------------------------------------===//
+
+/// StoreInst - an instruction for storing to memory
+///
+class StoreInst : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void AssertOK();
+protected:
+  StoreInst *clone_impl() const override;
+public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+  StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
+  StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
+            Instruction *InsertBefore = nullptr);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+            unsigned Align, Instruction *InsertBefore = nullptr);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+            unsigned Align, BasicBlock *InsertAtEnd);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+            unsigned Align, AtomicOrdering Order,
+            SynchronizationScope SynchScope = CrossThread,
+            Instruction *InsertBefore = nullptr);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+            unsigned Align, AtomicOrdering Order,
+            SynchronizationScope SynchScope,
+            BasicBlock *InsertAtEnd);
+
+
+  /// isVolatile - Return true if this is a store to a volatile memory
+  /// location.
+  ///
+  bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+
+  /// setVolatile - Specify whether this is a volatile store or not.
+  ///
+  void setVolatile(bool V) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                               (V ? 1 : 0));
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// getAlignment - Return the alignment of the access that is being performed
+  ///
+  unsigned getAlignment() const {
+    return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1;
+  }
+
+  void setAlignment(unsigned Align);
+
+  /// Returns the ordering effect of this store.
+  AtomicOrdering getOrdering() const {
+    return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+  }
+
+  /// Set the ordering constraint on this store.  May not be Acquire or
+  /// AcquireRelease.
+  void setOrdering(AtomicOrdering Ordering) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
+                               (Ordering << 7));
+  }
+
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+  }
+
+  /// Specify whether this store instruction is ordered with respect to all
+  /// concurrently executing threads, or only with respect to signal handlers
+  /// executing in the same thread.
+  void setSynchScope(SynchronizationScope xthread) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
+                               (xthread << 6));
+  }
+
+  bool isAtomic() const { return getOrdering() != NotAtomic; }
+  void setAtomic(AtomicOrdering Ordering,
+                 SynchronizationScope SynchScope = CrossThread) {
+    setOrdering(Ordering);
+    setSynchScope(SynchScope);
+  }
+
+  bool isSimple() const { return !isAtomic() && !isVolatile(); }
+  bool isUnordered() const {
+    return getOrdering() <= Unordered && !isVolatile();
+  }
+
+  Value *getValueOperand() { return getOperand(0); }
+  const Value *getValueOperand() const { return getOperand(0); }
+
+  Value *getPointerOperand() { return getOperand(1); }
+  const Value *getPointerOperand() const { return getOperand(1); }
+  static unsigned getPointerOperandIndex() { return 1U; }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperand()->getType()->getPointerAddressSpace();
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Store;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<StoreInst> : public FixedNumOperandTraits<StoreInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                                FenceInst Class
+//===----------------------------------------------------------------------===//
+
+/// FenceInst - an instruction for ordering other memory operations
+///
+class FenceInst : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
+protected:
+  FenceInst *clone_impl() const override;
+public:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+
+  // Ordering may only be Acquire, Release, AcquireRelease, or
+  // SequentiallyConsistent.
+  FenceInst(LLVMContext &C, AtomicOrdering Ordering,
+            SynchronizationScope SynchScope = CrossThread,
+            Instruction *InsertBefore = nullptr);
+  FenceInst(LLVMContext &C, AtomicOrdering Ordering,
+            SynchronizationScope SynchScope,
+            BasicBlock *InsertAtEnd);
+
+  /// Returns the ordering effect of this fence.
+  AtomicOrdering getOrdering() const {
+    return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
+  }
+
+  /// Set the ordering constraint on this fence.  May only be Acquire, Release,
+  /// AcquireRelease, or SequentiallyConsistent.
+  void setOrdering(AtomicOrdering Ordering) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
+                               (Ordering << 1));
+  }
+
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope(getSubclassDataFromInstruction() & 1);
+  }
+
+  /// Specify whether this fence orders other operations with respect to all
+  /// concurrently executing threads, or only with respect to signal handlers
+  /// executing in the same thread.
+  void setSynchScope(SynchronizationScope xthread) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                               xthread);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Fence;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                AtomicCmpXchgInst Class
+//===----------------------------------------------------------------------===//
+
+/// AtomicCmpXchgInst - an instruction that atomically checks whether a
+/// specified value is in a memory location, and, if it is, stores a new value
+/// there.  Returns the value that was loaded.
+///
+class AtomicCmpXchgInst : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void Init(Value *Ptr, Value *Cmp, Value *NewVal,
+            AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
+            SynchronizationScope SynchScope);
+protected:
+  AtomicCmpXchgInst *clone_impl() const override;
+public:
+  // allocate space for exactly three operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 3);
+  }
+  AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+                    AtomicOrdering SuccessOrdering,
+                    AtomicOrdering FailureOrdering,
+                    SynchronizationScope SynchScope,
+                    Instruction *InsertBefore = nullptr);
+  AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+                    AtomicOrdering SuccessOrdering,
+                    AtomicOrdering FailureOrdering,
+                    SynchronizationScope SynchScope,
+                    BasicBlock *InsertAtEnd);
+
+  /// isVolatile - Return true if this is a cmpxchg from a volatile memory
+  /// location.
+  ///
+  bool isVolatile() const {
+    return getSubclassDataFromInstruction() & 1;
+  }
+
+  /// setVolatile - Specify whether this is a volatile cmpxchg.
+  ///
+  void setVolatile(bool V) {
+     setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                                (unsigned)V);
+  }
+
+  /// Return true if this cmpxchg may spuriously fail.
+  bool isWeak() const {
+    return getSubclassDataFromInstruction() & 0x100;
+  }
+
+  void setWeak(bool IsWeak) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x100) |
+                               (IsWeak << 8));
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Set the ordering constraint on this cmpxchg.
+  void setSuccessOrdering(AtomicOrdering Ordering) {
+    assert(Ordering != NotAtomic &&
+           "CmpXchg instructions can only be atomic.");
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x1c) |
+                               (Ordering << 2));
+  }
+
+  void setFailureOrdering(AtomicOrdering Ordering) {
+    assert(Ordering != NotAtomic &&
+           "CmpXchg instructions can only be atomic.");
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~0xe0) |
+                               (Ordering << 5));
+  }
+
+  /// Specify whether this cmpxchg is atomic and orders other operations with
+  /// respect to all concurrently executing threads, or only with respect to
+  /// signal handlers executing in the same thread.
+  void setSynchScope(SynchronizationScope SynchScope) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
+                               (SynchScope << 1));
+  }
+
+  /// Returns the ordering constraint on this cmpxchg.
+  AtomicOrdering getSuccessOrdering() const {
+    return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+  }
+
+  /// Returns the ordering constraint on this cmpxchg.
+  AtomicOrdering getFailureOrdering() const {
+    return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7);
+  }
+
+  /// Returns whether this cmpxchg is atomic between threads or only within a
+  /// single thread.
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+  }
+
+  Value *getPointerOperand() { return getOperand(0); }
+  const Value *getPointerOperand() const { return getOperand(0); }
+  static unsigned getPointerOperandIndex() { return 0U; }
+
+  Value *getCompareOperand() { return getOperand(1); }
+  const Value *getCompareOperand() const { return getOperand(1); }
+
+  Value *getNewValOperand() { return getOperand(2); }
+  const Value *getNewValOperand() const { return getOperand(2); }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperand()->getType()->getPointerAddressSpace();
+  }
+
+  /// \brief Returns the strongest permitted ordering on failure, given the
+  /// desired ordering on success.
+  ///
+  /// If the comparison in a cmpxchg operation fails, there is no atomic store
+  /// so release semantics cannot be provided. So this function drops explicit
+  /// Release requests from the AtomicOrdering. A SequentiallyConsistent
+  /// operation would remain SequentiallyConsistent.
+  static AtomicOrdering
+  getStrongestFailureOrdering(AtomicOrdering SuccessOrdering) {
+    switch (SuccessOrdering) {
+    default: llvm_unreachable("invalid cmpxchg success ordering");
+    case Release:
+    case Monotonic:
+      return Monotonic;
+    case AcquireRelease:
+    case Acquire:
+      return Acquire;
+    case SequentiallyConsistent:
+      return SequentiallyConsistent;
+    }
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::AtomicCmpXchg;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<AtomicCmpXchgInst> :
+    public FixedNumOperandTraits<AtomicCmpXchgInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                                AtomicRMWInst Class
+//===----------------------------------------------------------------------===//
+
+/// AtomicRMWInst - an instruction that atomically reads a memory location,
+/// combines it with another value, and then stores the result back.  Returns
+/// the old value.
+///
+class AtomicRMWInst : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+protected:
+  AtomicRMWInst *clone_impl() const override;
+public:
+  /// This enumeration lists the possible modifications atomicrmw can make.  In
+  /// the descriptions, 'p' is the pointer to the instruction's memory location,
+  /// 'old' is the initial value of *p, and 'v' is the other value passed to the
+  /// instruction.  These instructions always return 'old'.
+  enum BinOp {
+    /// *p = v
+    Xchg,
+    /// *p = old + v
+    Add,
+    /// *p = old - v
+    Sub,
+    /// *p = old & v
+    And,
+    /// *p = ~old & v
+    Nand,
+    /// *p = old | v
+    Or,
+    /// *p = old ^ v
+    Xor,
+    /// *p = old >signed v ? old : v
+    Max,
+    /// *p = old <signed v ? old : v
+    Min,
+    /// *p = old >unsigned v ? old : v
+    UMax,
+    /// *p = old <unsigned v ? old : v
+    UMin,
+
+    FIRST_BINOP = Xchg,
+    LAST_BINOP = UMin,
+    BAD_BINOP
+  };
+
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+  AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+                AtomicOrdering Ordering, SynchronizationScope SynchScope,
+                Instruction *InsertBefore = nullptr);
+  AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+                AtomicOrdering Ordering, SynchronizationScope SynchScope,
+                BasicBlock *InsertAtEnd);
+
+  BinOp getOperation() const {
+    return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
+  }
+
+  void setOperation(BinOp Operation) {
+    unsigned short SubclassData = getSubclassDataFromInstruction();
+    setInstructionSubclassData((SubclassData & 31) |
+                               (Operation << 5));
+  }
+
+  /// isVolatile - Return true if this is a RMW on a volatile memory location.
+  ///
+  bool isVolatile() const {
+    return getSubclassDataFromInstruction() & 1;
+  }
+
+  /// setVolatile - Specify whether this is a volatile RMW or not.
+  ///
+  void setVolatile(bool V) {
+     setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                                (unsigned)V);
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Set the ordering constraint on this RMW.
+  void setOrdering(AtomicOrdering Ordering) {
+    assert(Ordering != NotAtomic &&
+           "atomicrmw instructions can only be atomic.");
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 2)) |
+                               (Ordering << 2));
+  }
+
+  /// Specify whether this RMW orders other operations with respect to all
+  /// concurrently executing threads, or only with respect to signal handlers
+  /// executing in the same thread.
+  void setSynchScope(SynchronizationScope SynchScope) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
+                               (SynchScope << 1));
+  }
+
+  /// Returns the ordering constraint on this RMW.
+  AtomicOrdering getOrdering() const {
+    return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+  }
+
+  /// Returns whether this RMW is atomic between threads or only within a
+  /// single thread.
+  SynchronizationScope getSynchScope() const {
+    return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+  }
+
+  Value *getPointerOperand() { return getOperand(0); }
+  const Value *getPointerOperand() const { return getOperand(0); }
+  static unsigned getPointerOperandIndex() { return 0U; }
+
+  Value *getValOperand() { return getOperand(1); }
+  const Value *getValOperand() const { return getOperand(1); }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperand()->getType()->getPointerAddressSpace();
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::AtomicRMW;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  void Init(BinOp Operation, Value *Ptr, Value *Val,
+            AtomicOrdering Ordering, SynchronizationScope SynchScope);
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<AtomicRMWInst>
+    : public FixedNumOperandTraits<AtomicRMWInst,2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                             GetElementPtrInst Class
+//===----------------------------------------------------------------------===//
+
+// checkGEPType - Simple wrapper function to give a better assertion failure
+// message on bad indexes for a gep instruction.
+//
+inline Type *checkGEPType(Type *Ty) {
+  assert(Ty && "Invalid GetElementPtrInst indices for type!");
+  return Ty;
+}
+
+/// GetElementPtrInst - an instruction for type-safe pointer arithmetic to
+/// access elements of arrays and structs
+///
+class GetElementPtrInst : public Instruction {
+  GetElementPtrInst(const GetElementPtrInst &GEPI);
+  void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
+
+  /// Constructors - Create a getelementptr instruction with a base pointer an
+  /// list of indices. The first ctor can optionally insert before an existing
+  /// instruction, the second appends the new instruction to the specified
+  /// BasicBlock.
+  inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
+                           unsigned Values, const Twine &NameStr,
+                           Instruction *InsertBefore);
+  inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
+                           unsigned Values, const Twine &NameStr,
+                           BasicBlock *InsertAtEnd);
+protected:
+  GetElementPtrInst *clone_impl() const override;
+public:
+  static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+                                   const Twine &NameStr = "",
+                                   Instruction *InsertBefore = nullptr) {
+    unsigned Values = 1 + unsigned(IdxList.size());
+    return new(Values)
+      GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore);
+  }
+  static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+                                   const Twine &NameStr,
+                                   BasicBlock *InsertAtEnd) {
+    unsigned Values = 1 + unsigned(IdxList.size());
+    return new(Values)
+      GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd);
+  }
+
+  /// Create an "inbounds" getelementptr. See the documentation for the
+  /// "inbounds" flag in LangRef.html for details.
+  static GetElementPtrInst *CreateInBounds(Value *Ptr,
+                                           ArrayRef<Value *> IdxList,
+                                           const Twine &NameStr = "",
+                                           Instruction *InsertBefore = nullptr){
+    GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore);
+    GEP->setIsInBounds(true);
+    return GEP;
+  }
+  static GetElementPtrInst *CreateInBounds(Value *Ptr,
+                                           ArrayRef<Value *> IdxList,
+                                           const Twine &NameStr,
+                                           BasicBlock *InsertAtEnd) {
+    GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd);
+    GEP->setIsInBounds(true);
+    return GEP;
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // getType - Overload to return most specific sequential type.
+  SequentialType *getType() const {
+    return cast<SequentialType>(Instruction::getType());
+  }
+
+  /// \brief Returns the address space of this instruction's pointer type.
+  unsigned getAddressSpace() const {
+    // Note that this is always the same as the pointer operand's address space
+    // and that is cheaper to compute, so cheat here.
+    return getPointerAddressSpace();
+  }
+
+  /// getIndexedType - Returns the type of the element that would be loaded with
+  /// a load instruction with the specified parameters.
+  ///
+  /// Null is returned if the indices are invalid for the specified
+  /// pointer type.
+  ///
+  static Type *getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList);
+  static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList);
+  static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList);
+
+  inline op_iterator       idx_begin()       { return op_begin()+1; }
+  inline const_op_iterator idx_begin() const { return op_begin()+1; }
+  inline op_iterator       idx_end()         { return op_end(); }
+  inline const_op_iterator idx_end()   const { return op_end(); }
+
+  Value *getPointerOperand() {
+    return getOperand(0);
+  }
+  const Value *getPointerOperand() const {
+    return getOperand(0);
+  }
+  static unsigned getPointerOperandIndex() {
+    return 0U;    // get index for modifying correct operand.
+  }
+
+  /// getPointerOperandType - Method to return the pointer operand as a
+  /// PointerType.
+  Type *getPointerOperandType() const {
+    return getPointerOperand()->getType();
+  }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperandType()->getPointerAddressSpace();
+  }
+
+  /// GetGEPReturnType - Returns the pointer type returned by the GEP
+  /// instruction, which may be a vector of pointers.
+  static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
+    Type *PtrTy = PointerType::get(checkGEPType(
+                                   getIndexedType(Ptr->getType(), IdxList)),
+                                   Ptr->getType()->getPointerAddressSpace());
+    // Vector GEP
+    if (Ptr->getType()->isVectorTy()) {
+      unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
+      return VectorType::get(PtrTy, NumElem);
+    }
+
+    // Scalar GEP
+    return PtrTy;
+  }
+
+  unsigned getNumIndices() const {  // Note: always non-negative
+    return getNumOperands() - 1;
+  }
+
+  bool hasIndices() const {
+    return getNumOperands() > 1;
+  }
+
+  /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+  /// zeros.  If so, the result pointer and the first operand have the same
+  /// value, just potentially different types.
+  bool hasAllZeroIndices() const;
+
+  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+  /// constant integers.  If so, the result pointer and the first operand have
+  /// a constant offset between them.
+  bool hasAllConstantIndices() const;
+
+  /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
+  /// See LangRef.html for the meaning of inbounds on a getelementptr.
+  void setIsInBounds(bool b = true);
+
+  /// isInBounds - Determine whether the GEP has the inbounds flag.
+  bool isInBounds() const;
+
+  /// \brief Accumulate the constant address offset of this GEP if possible.
+  ///
+  /// This routine accepts an APInt into which it will accumulate the constant
+  /// offset of this GEP if the GEP is in fact constant. If the GEP is not
+  /// all-constant, it returns false and the value of the offset APInt is
+  /// undefined (it is *not* preserved!). The APInt passed into this routine
+  /// must be at least as wide as the IntPtr type for the address space of
+  /// the base GEP pointer.
+  bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::GetElementPtr);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<GetElementPtrInst> :
+  public VariadicOperandTraits<GetElementPtrInst, 1> {
+};
+
+GetElementPtrInst::GetElementPtrInst(Value *Ptr,
+                                     ArrayRef<Value *> IdxList,
+                                     unsigned Values,
+                                     const Twine &NameStr,
+                                     Instruction *InsertBefore)
+  : Instruction(getGEPReturnType(Ptr, IdxList),
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+                Values, InsertBefore) {
+  init(Ptr, IdxList, NameStr);
+}
+GetElementPtrInst::GetElementPtrInst(Value *Ptr,
+                                     ArrayRef<Value *> IdxList,
+                                     unsigned Values,
+                                     const Twine &NameStr,
+                                     BasicBlock *InsertAtEnd)
+  : Instruction(getGEPReturnType(Ptr, IdxList),
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+                Values, InsertAtEnd) {
+  init(Ptr, IdxList, NameStr);
+}
+
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+//                               ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on integers or pointers. The operands
+/// must be identical types.
+/// \brief Represent an integer comparison operator.
+class ICmpInst: public CmpInst {
+  void AssertOK() {
+    assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE &&
+           getPredicate() <= CmpInst::LAST_ICMP_PREDICATE &&
+           "Invalid ICmp predicate value");
+    assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+          "Both operands to ICmp instruction are not of the same type!");
+    // Check that the operands are the right type
+    assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+            getOperand(0)->getType()->isPtrOrPtrVectorTy()) &&
+           "Invalid operand types for ICmp instruction");
+  }
+
+protected:
+  /// \brief Clone an identical ICmpInst
+  ICmpInst *clone_impl() const override;
+public:
+  /// \brief Constructor with insert-before-instruction semantics.
+  ICmpInst(
+    Instruction *InsertBefore,  ///< Where to insert
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const Twine &NameStr = ""  ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::ICmp, pred, LHS, RHS, NameStr,
+              InsertBefore) {
+#ifndef NDEBUG
+  AssertOK();
+#endif
+  }
+
+  /// \brief Constructor with insert-at-end semantics.
+  ICmpInst(
+    BasicBlock &InsertAtEnd, ///< Block to insert into.
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const Twine &NameStr = ""  ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::ICmp, pred, LHS, RHS, NameStr,
+              &InsertAtEnd) {
+#ifndef NDEBUG
+  AssertOK();
+#endif
+  }
+
+  /// \brief Constructor with no-insertion semantics
+  ICmpInst(
+    Predicate pred, ///< The predicate to use for the comparison
+    Value *LHS,     ///< The left-hand-side of the expression
+    Value *RHS,     ///< The right-hand-side of the expression
+    const Twine &NameStr = "" ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::ICmp, pred, LHS, RHS, NameStr) {
+#ifndef NDEBUG
+  AssertOK();
+#endif
+  }
+
+  /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
+  /// @returns the predicate that would be the result if the operand were
+  /// regarded as signed.
+  /// \brief Return the signed version of the predicate
+  Predicate getSignedPredicate() const {
+    return getSignedPredicate(getPredicate());
+  }
+
+  /// This is a static version that you can use without an instruction.
+  /// \brief Return the signed version of the predicate.
+  static Predicate getSignedPredicate(Predicate pred);
+
+  /// For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
+  /// @returns the predicate that would be the result if the operand were
+  /// regarded as unsigned.
+  /// \brief Return the unsigned version of the predicate
+  Predicate getUnsignedPredicate() const {
+    return getUnsignedPredicate(getPredicate());
+  }
+
+  /// This is a static version that you can use without an instruction.
+  /// \brief Return the unsigned version of the predicate.
+  static Predicate getUnsignedPredicate(Predicate pred);
+
+  /// isEquality - Return true if this predicate is either EQ or NE.  This also
+  /// tests for commutativity.
+  static bool isEquality(Predicate P) {
+    return P == ICMP_EQ || P == ICMP_NE;
+  }
+
+  /// isEquality - Return true if this predicate is either EQ or NE.  This also
+  /// tests for commutativity.
+  bool isEquality() const {
+    return isEquality(getPredicate());
+  }
+
+  /// @returns true if the predicate of this ICmpInst is commutative
+  /// \brief Determine if this relation is commutative.
+  bool isCommutative() const { return isEquality(); }
+
+  /// isRelational - Return true if the predicate is relational (not EQ or NE).
+  ///
+  bool isRelational() const {
+    return !isEquality();
+  }
+
+  /// isRelational - Return true if the predicate is relational (not EQ or NE).
+  ///
+  static bool isRelational(Predicate P) {
+    return !isEquality(P);
+  }
+
+  /// Initialize a set of values that all satisfy the predicate with C.
+  /// \brief Make a ConstantRange for a relation with a constant value.
+  static ConstantRange makeConstantRange(Predicate pred, const APInt &C);
+
+  /// Exchange the two operands to this instruction in such a way that it does
+  /// not modify the semantics of the instruction. The predicate value may be
+  /// changed to retain the same result if the predicate is order dependent
+  /// (e.g. ult).
+  /// \brief Swap operands and adjust predicate.
+  void swapOperands() {
+    setPredicate(getSwappedPredicate());
+    Op<0>().swap(Op<1>());
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ICmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+
+};
+
+//===----------------------------------------------------------------------===//
+//                               FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on floating point values or packed
+/// vectors of floating point values. The operands must be identical types.
+/// \brief Represents a floating point comparison operator.
+class FCmpInst: public CmpInst {
+protected:
+  /// \brief Clone an identical FCmpInst
+  FCmpInst *clone_impl() const override;
+public:
+  /// \brief Constructor with insert-before-instruction semantics.
+  FCmpInst(
+    Instruction *InsertBefore, ///< Where to insert
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const Twine &NameStr = ""  ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::FCmp, pred, LHS, RHS, NameStr,
+              InsertBefore) {
+    assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+           "Invalid FCmp predicate value");
+    assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+           "Both operands to FCmp instruction are not of the same type!");
+    // Check that the operands are the right type
+    assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+           "Invalid operand types for FCmp instruction");
+  }
+
+  /// \brief Constructor with insert-at-end semantics.
+  FCmpInst(
+    BasicBlock &InsertAtEnd, ///< Block to insert into.
+    Predicate pred,  ///< The predicate to use for the comparison
+    Value *LHS,      ///< The left-hand-side of the expression
+    Value *RHS,      ///< The right-hand-side of the expression
+    const Twine &NameStr = ""  ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::FCmp, pred, LHS, RHS, NameStr,
+              &InsertAtEnd) {
+    assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+           "Invalid FCmp predicate value");
+    assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+           "Both operands to FCmp instruction are not of the same type!");
+    // Check that the operands are the right type
+    assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+           "Invalid operand types for FCmp instruction");
+  }
+
+  /// \brief Constructor with no-insertion semantics
+  FCmpInst(
+    Predicate pred, ///< The predicate to use for the comparison
+    Value *LHS,     ///< The left-hand-side of the expression
+    Value *RHS,     ///< The right-hand-side of the expression
+    const Twine &NameStr = "" ///< Name of the instruction
+  ) : CmpInst(makeCmpResultType(LHS->getType()),
+              Instruction::FCmp, pred, LHS, RHS, NameStr) {
+    assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+           "Invalid FCmp predicate value");
+    assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+           "Both operands to FCmp instruction are not of the same type!");
+    // Check that the operands are the right type
+    assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+           "Invalid operand types for FCmp instruction");
+  }
+
+  /// @returns true if the predicate of this instruction is EQ or NE.
+  /// \brief Determine if this is an equality predicate.
+  bool isEquality() const {
+    return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
+           getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
+  }
+
+  /// @returns true if the predicate of this instruction is commutative.
+  /// \brief Determine if this is a commutative predicate.
+  bool isCommutative() const {
+    return isEquality() ||
+           getPredicate() == FCMP_FALSE ||
+           getPredicate() == FCMP_TRUE ||
+           getPredicate() == FCMP_ORD ||
+           getPredicate() == FCMP_UNO;
+  }
+
+  /// @returns true if the predicate is relational (not EQ or NE).
+  /// \brief Determine if this a relational predicate.
+  bool isRelational() const { return !isEquality(); }
+
+  /// Exchange the two operands to this instruction in such a way that it does
+  /// not modify the semantics of the instruction. The predicate value may be
+  /// changed to retain the same result if the predicate is order dependent
+  /// (e.g. ult).
+  /// \brief Swap operands and adjust predicate.
+  void swapOperands() {
+    setPredicate(getSwappedPredicate());
+    Op<0>().swap(Op<1>());
+  }
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::FCmp;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// CallInst - This class represents a function call, abstracting a target
+/// machine's calling convention.  This class uses low bit of the SubClassData
+/// field to indicate whether or not this is a tail call.  The rest of the bits
+/// hold the calling convention of the call.
+///
+class CallInst : public Instruction {
+  AttributeSet AttributeList; ///< parameter attributes for call
+  CallInst(const CallInst &CI);
+  void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
+  void init(Value *Func, const Twine &NameStr);
+
+  /// Construct a CallInst given a range of arguments.
+  /// \brief Construct a CallInst from a range of arguments
+  inline CallInst(Value *Func, ArrayRef<Value *> Args,
+                  const Twine &NameStr, Instruction *InsertBefore);
+
+  /// Construct a CallInst given a range of arguments.
+  /// \brief Construct a CallInst from a range of arguments
+  inline CallInst(Value *Func, ArrayRef<Value *> Args,
+                  const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+  explicit CallInst(Value *F, const Twine &NameStr,
+                    Instruction *InsertBefore);
+  CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+  CallInst *clone_impl() const override;
+public:
+  static CallInst *Create(Value *Func,
+                          ArrayRef<Value *> Args,
+                          const Twine &NameStr = "",
+                          Instruction *InsertBefore = nullptr) {
+    return new(unsigned(Args.size() + 1))
+      CallInst(Func, Args, NameStr, InsertBefore);
+  }
+  static CallInst *Create(Value *Func,
+                          ArrayRef<Value *> Args,
+                          const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new(unsigned(Args.size() + 1))
+      CallInst(Func, Args, NameStr, InsertAtEnd);
+  }
+  static CallInst *Create(Value *F, const Twine &NameStr = "",
+                          Instruction *InsertBefore = nullptr) {
+    return new(1) CallInst(F, NameStr, InsertBefore);
+  }
+  static CallInst *Create(Value *F, const Twine &NameStr,
+                          BasicBlock *InsertAtEnd) {
+    return new(1) CallInst(F, NameStr, InsertAtEnd);
+  }
+  /// CreateMalloc - Generate the IR for a call to malloc:
+  /// 1. Compute the malloc call's argument as the specified type's size,
+  ///    possibly multiplied by the array size if the array size is not
+  ///    constant 1.
+  /// 2. Call malloc with that argument.
+  /// 3. Bitcast the result of the malloc call to the specified type.
+  static Instruction *CreateMalloc(Instruction *InsertBefore,
+                                   Type *IntPtrTy, Type *AllocTy,
+                                   Value *AllocSize, Value *ArraySize = nullptr,
+                                   Function* MallocF = nullptr,
+                                   const Twine &Name = "");
+  static Instruction *CreateMalloc(BasicBlock *InsertAtEnd,
+                                   Type *IntPtrTy, Type *AllocTy,
+                                   Value *AllocSize, Value *ArraySize = nullptr,
+                                   Function* MallocF = nullptr,
+                                   const Twine &Name = "");
+  /// CreateFree - Generate the IR for a call to the builtin free function.
+  static Instruction* CreateFree(Value* Source, Instruction *InsertBefore);
+  static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
+
+  ~CallInst();
+
+  // Note that 'musttail' implies 'tail'.
+  enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 };
+  TailCallKind getTailCallKind() const {
+    return TailCallKind(getSubclassDataFromInstruction() & 3);
+  }
+  bool isTailCall() const {
+    return (getSubclassDataFromInstruction() & 3) != TCK_None;
+  }
+  bool isMustTailCall() const {
+    return (getSubclassDataFromInstruction() & 3) == TCK_MustTail;
+  }
+  void setTailCall(bool isTC = true) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) |
+                               unsigned(isTC ? TCK_Tail : TCK_None));
+  }
+  void setTailCallKind(TailCallKind TCK) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) |
+                               unsigned(TCK));
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// getNumArgOperands - Return the number of call arguments.
+  ///
+  unsigned getNumArgOperands() const { return getNumOperands() - 1; }
+
+  /// getArgOperand/setArgOperand - Return/set the i-th call argument.
+  ///
+  Value *getArgOperand(unsigned i) const { return getOperand(i); }
+  void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+  /// arg_operands - iteration adapter for range-for loops.
+  iterator_range<op_iterator> arg_operands() {
+    // The last operand in the op list is the callee - it's not one of the args
+    // so we don't want to iterate over it.
+    return iterator_range<op_iterator>(op_begin(), op_end() - 1);
+  }
+
+  /// arg_operands - iteration adapter for range-for loops.
+  iterator_range<const_op_iterator> arg_operands() const {
+    return iterator_range<const_op_iterator>(op_begin(), op_end() - 1);
+  }
+
+  /// \brief Wrappers for getting the \c Use of a call argument.
+  const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+  Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
+  /// getCallingConv/setCallingConv - Get or set the calling convention of this
+  /// function call.
+  CallingConv::ID getCallingConv() const {
+    return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2);
+  }
+  void setCallingConv(CallingConv::ID CC) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
+                               (static_cast<unsigned>(CC) << 2));
+  }
+
+  /// getAttributes - Return the parameter attributes for this call.
+  ///
+  const AttributeSet &getAttributes() const { return AttributeList; }
+
+  /// setAttributes - Set the parameter attributes for this call.
+  ///
+  void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; }
+
+  /// addAttribute - adds the attribute to the list of attributes.
+  void addAttribute(unsigned i, Attribute::AttrKind attr);
+
+  /// removeAttribute - removes the attribute from the list of attributes.
+  void removeAttribute(unsigned i, Attribute attr);
+
+  /// \brief Determine whether this call has the given attribute.
+  bool hasFnAttr(Attribute::AttrKind A) const {
+    assert(A != Attribute::NoBuiltin &&
+           "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");
+    return hasFnAttrImpl(A);
+  }
+
+  /// \brief Determine whether the call or the callee has the given attributes.
+  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
+
+  /// \brief Extract the alignment for a call or parameter (0=unknown).
+  unsigned getParamAlignment(unsigned i) const {
+    return AttributeList.getParamAlignment(i);
+  }
+
+  /// \brief Extract the number of dereferenceable bytes for a call or
+  /// parameter (0=unknown).
+  uint64_t getDereferenceableBytes(unsigned i) const {
+    return AttributeList.getDereferenceableBytes(i);
+  }
+
+  /// \brief Return true if the call should not be treated as a call to a
+  /// builtin.
+  bool isNoBuiltin() const {
+    return hasFnAttrImpl(Attribute::NoBuiltin) &&
+      !hasFnAttrImpl(Attribute::Builtin);
+  }
+
+  /// \brief Return true if the call should not be inlined.
+  bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
+  void setIsNoInline() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline);
+  }
+
+  /// \brief Return true if the call can return twice
+  bool canReturnTwice() const {
+    return hasFnAttr(Attribute::ReturnsTwice);
+  }
+  void setCanReturnTwice() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ReturnsTwice);
+  }
+
+  /// \brief Determine if the call does not access memory.
+  bool doesNotAccessMemory() const {
+    return hasFnAttr(Attribute::ReadNone);
+  }
+  void setDoesNotAccessMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
+  }
+
+  /// \brief Determine if the call does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+  }
+  void setOnlyReadsMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
+  }
+
+  /// \brief Determine if the call cannot return.
+  bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
+  void setDoesNotReturn() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn);
+  }
+
+  /// \brief Determine if the call cannot unwind.
+  bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
+  void setDoesNotThrow() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
+  }
+
+  /// \brief Determine if the call cannot be duplicated.
+  bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
+  void setCannotDuplicate() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
+  }
+
+  /// \brief Determine if the call returns a structure through first
+  /// pointer argument.
+  bool hasStructRetAttr() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, Attribute::StructRet);
+  }
+
+  /// \brief Determine if any call argument is an aggregate passed by value.
+  bool hasByValArgument() const {
+    return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+  }
+
+  /// getCalledFunction - Return the function called, or null if this is an
+  /// indirect function invocation.
+  ///
+  Function *getCalledFunction() const {
+    return dyn_cast<Function>(Op<-1>());
+  }
+
+  /// getCalledValue - Get a pointer to the function that is invoked by this
+  /// instruction.
+  const Value *getCalledValue() const { return Op<-1>(); }
+        Value *getCalledValue()       { return Op<-1>(); }
+
+  /// setCalledFunction - Set the function called.
+  void setCalledFunction(Value* Fn) {
+    Op<-1>() = Fn;
+  }
+
+  /// isInlineAsm - Check if this call is an inline asm statement.
+  bool isInlineAsm() const {
+    return isa<InlineAsm>(Op<-1>());
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Call;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+
+  bool hasFnAttrImpl(Attribute::AttrKind A) const;
+
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> {
+};
+
+CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+                   const Twine &NameStr, BasicBlock *InsertAtEnd)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+                unsigned(Args.size() + 1), InsertAtEnd) {
+  init(Func, Args, NameStr);
+}
+
+CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+                   const Twine &NameStr, Instruction *InsertBefore)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+                unsigned(Args.size() + 1), InsertBefore) {
+  init(Func, Args, NameStr);
+}
+
+
+// Note: if you get compile errors about private methods then
+//       please update your code to use the high-level operand
+//       interfaces. See line 943 above.
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// SelectInst - This class represents the LLVM 'select' instruction.
+///
+class SelectInst : public Instruction {
+  void init(Value *C, Value *S1, Value *S2) {
+    assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
+    Op<0>() = C;
+    Op<1>() = S1;
+    Op<2>() = S2;
+  }
+
+  SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
+             Instruction *InsertBefore)
+    : Instruction(S1->getType(), Instruction::Select,
+                  &Op<0>(), 3, InsertBefore) {
+    init(C, S1, S2);
+    setName(NameStr);
+  }
+  SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
+             BasicBlock *InsertAtEnd)
+    : Instruction(S1->getType(), Instruction::Select,
+                  &Op<0>(), 3, InsertAtEnd) {
+    init(C, S1, S2);
+    setName(NameStr);
+  }
+protected:
+  SelectInst *clone_impl() const override;
+public:
+  static SelectInst *Create(Value *C, Value *S1, Value *S2,
+                            const Twine &NameStr = "",
+                            Instruction *InsertBefore = nullptr) {
+    return new(3) SelectInst(C, S1, S2, NameStr, InsertBefore);
+  }
+  static SelectInst *Create(Value *C, Value *S1, Value *S2,
+                            const Twine &NameStr,
+                            BasicBlock *InsertAtEnd) {
+    return new(3) SelectInst(C, S1, S2, NameStr, InsertAtEnd);
+  }
+
+  const Value *getCondition() const { return Op<0>(); }
+  const Value *getTrueValue() const { return Op<1>(); }
+  const Value *getFalseValue() const { return Op<2>(); }
+  Value *getCondition() { return Op<0>(); }
+  Value *getTrueValue() { return Op<1>(); }
+  Value *getFalseValue() { return Op<2>(); }
+
+  /// areInvalidOperands - Return a string if the specified operands are invalid
+  /// for a select operation, otherwise return null.
+  static const char *areInvalidOperands(Value *Cond, Value *True, Value *False);
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  OtherOps getOpcode() const {
+    return static_cast<OtherOps>(Instruction::getOpcode());
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Select;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<SelectInst> : public FixedNumOperandTraits<SelectInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                                VAArgInst Class
+//===----------------------------------------------------------------------===//
+
+/// VAArgInst - This class represents the va_arg llvm instruction, which returns
+/// an argument of the specified type given a va_list and increments that list
+///
+class VAArgInst : public UnaryInstruction {
+protected:
+  VAArgInst *clone_impl() const override;
+
+public:
+  VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "",
+             Instruction *InsertBefore = nullptr)
+    : UnaryInstruction(Ty, VAArg, List, InsertBefore) {
+    setName(NameStr);
+  }
+  VAArgInst(Value *List, Type *Ty, const Twine &NameStr,
+            BasicBlock *InsertAtEnd)
+    : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) {
+    setName(NameStr);
+  }
+
+  Value *getPointerOperand() { return getOperand(0); }
+  const Value *getPointerOperand() const { return getOperand(0); }
+  static unsigned getPointerOperandIndex() { return 0U; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == VAArg;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                ExtractElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// ExtractElementInst - This instruction extracts a single (scalar)
+/// element from a VectorType value
+///
+class ExtractElementInst : public Instruction {
+  ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr = "",
+                     Instruction *InsertBefore = nullptr);
+  ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr,
+                     BasicBlock *InsertAtEnd);
+protected:
+  ExtractElementInst *clone_impl() const override;
+
+public:
+  static ExtractElementInst *Create(Value *Vec, Value *Idx,
+                                   const Twine &NameStr = "",
+                                   Instruction *InsertBefore = nullptr) {
+    return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
+  }
+  static ExtractElementInst *Create(Value *Vec, Value *Idx,
+                                   const Twine &NameStr,
+                                   BasicBlock *InsertAtEnd) {
+    return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertAtEnd);
+  }
+
+  /// isValidOperands - Return true if an extractelement instruction can be
+  /// formed with the specified operands.
+  static bool isValidOperands(const Value *Vec, const Value *Idx);
+
+  Value *getVectorOperand() { return Op<0>(); }
+  Value *getIndexOperand() { return Op<1>(); }
+  const Value *getVectorOperand() const { return Op<0>(); }
+  const Value *getIndexOperand() const { return Op<1>(); }
+
+  VectorType *getVectorOperandType() const {
+    return cast<VectorType>(getVectorOperand()->getType());
+  }
+
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ExtractElement;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<ExtractElementInst> :
+  public FixedNumOperandTraits<ExtractElementInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                                InsertElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// InsertElementInst - This instruction inserts a single (scalar)
+/// element into a VectorType value
+///
+class InsertElementInst : public Instruction {
+  InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+                    const Twine &NameStr = "",
+                    Instruction *InsertBefore = nullptr);
+  InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+                    const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+  InsertElementInst *clone_impl() const override;
+
+public:
+  static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
+                                   const Twine &NameStr = "",
+                                   Instruction *InsertBefore = nullptr) {
+    return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
+  }
+  static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
+                                   const Twine &NameStr,
+                                   BasicBlock *InsertAtEnd) {
+    return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertAtEnd);
+  }
+
+  /// isValidOperands - Return true if an insertelement instruction can be
+  /// formed with the specified operands.
+  static bool isValidOperands(const Value *Vec, const Value *NewElt,
+                              const Value *Idx);
+
+  /// getType - Overload to return most specific vector type.
+  ///
+  VectorType *getType() const {
+    return cast<VectorType>(Instruction::getType());
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::InsertElement;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<InsertElementInst> :
+  public FixedNumOperandTraits<InsertElementInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                           ShuffleVectorInst Class
+//===----------------------------------------------------------------------===//
+
+/// ShuffleVectorInst - This instruction constructs a fixed permutation of two
+/// input vectors.
+///
+class ShuffleVectorInst : public Instruction {
+protected:
+  ShuffleVectorInst *clone_impl() const override;
+
+public:
+  // allocate space for exactly three operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 3);
+  }
+  ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+                    const Twine &NameStr = "",
+                    Instruction *InsertBefor = nullptr);
+  ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+                    const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+  /// isValidOperands - Return true if a shufflevector instruction can be
+  /// formed with the specified operands.
+  static bool isValidOperands(const Value *V1, const Value *V2,
+                              const Value *Mask);
+
+  /// getType - Overload to return most specific vector type.
+  ///
+  VectorType *getType() const {
+    return cast<VectorType>(Instruction::getType());
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  Constant *getMask() const {
+    return cast<Constant>(getOperand(2));
+  }
+
+  /// getMaskValue - Return the index from the shuffle mask for the specified
+  /// output result.  This is either -1 if the element is undef or a number less
+  /// than 2*numelements.
+  static int getMaskValue(Constant *Mask, unsigned i);
+
+  int getMaskValue(unsigned i) const {
+    return getMaskValue(getMask(), i);
+  }
+
+  /// getShuffleMask - Return the full mask for this instruction, where each
+  /// element is the element number and undef's are returned as -1.
+  static void getShuffleMask(Constant *Mask, SmallVectorImpl<int> &Result);
+
+  void getShuffleMask(SmallVectorImpl<int> &Result) const {
+    return getShuffleMask(getMask(), Result);
+  }
+
+  SmallVector<int, 16> getShuffleMask() const {
+    SmallVector<int, 16> Mask;
+    getShuffleMask(Mask);
+    return Mask;
+  }
+
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ShuffleVector;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<ShuffleVectorInst> :
+  public FixedNumOperandTraits<ShuffleVectorInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                                ExtractValueInst Class
+//===----------------------------------------------------------------------===//
+
+/// ExtractValueInst - This instruction extracts a struct member or array
+/// element value from an aggregate value.
+///
+class ExtractValueInst : public UnaryInstruction {
+  SmallVector<unsigned, 4> Indices;
+
+  ExtractValueInst(const ExtractValueInst &EVI);
+  void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
+
+  /// Constructors - Create a extractvalue instruction with a base aggregate
+  /// value and a list of indices.  The first ctor can optionally insert before
+  /// an existing instruction, the second appends the new instruction to the
+  /// specified BasicBlock.
+  inline ExtractValueInst(Value *Agg,
+                          ArrayRef<unsigned> Idxs,
+                          const Twine &NameStr,
+                          Instruction *InsertBefore);
+  inline ExtractValueInst(Value *Agg,
+                          ArrayRef<unsigned> Idxs,
+                          const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+  // allocate space for exactly one operand
+  void *operator new(size_t s) {
+    return User::operator new(s, 1);
+  }
+protected:
+  ExtractValueInst *clone_impl() const override;
+
+public:
+  static ExtractValueInst *Create(Value *Agg,
+                                  ArrayRef<unsigned> Idxs,
+                                  const Twine &NameStr = "",
+                                  Instruction *InsertBefore = nullptr) {
+    return new
+      ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
+  }
+  static ExtractValueInst *Create(Value *Agg,
+                                  ArrayRef<unsigned> Idxs,
+                                  const Twine &NameStr,
+                                  BasicBlock *InsertAtEnd) {
+    return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd);
+  }
+
+  /// getIndexedType - Returns the type of the element that would be extracted
+  /// with an extractvalue instruction with the specified parameters.
+  ///
+  /// Null is returned if the indices are invalid for the specified type.
+  static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
+
+  typedef const unsigned* idx_iterator;
+  inline idx_iterator idx_begin() const { return Indices.begin(); }
+  inline idx_iterator idx_end()   const { return Indices.end(); }
+
+  Value *getAggregateOperand() {
+    return getOperand(0);
+  }
+  const Value *getAggregateOperand() const {
+    return getOperand(0);
+  }
+  static unsigned getAggregateOperandIndex() {
+    return 0U;                      // get index for modifying correct operand
+  }
+
+  ArrayRef<unsigned> getIndices() const {
+    return Indices;
+  }
+
+  unsigned getNumIndices() const {
+    return (unsigned)Indices.size();
+  }
+
+  bool hasIndices() const {
+    return true;
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::ExtractValue;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+ExtractValueInst::ExtractValueInst(Value *Agg,
+                                   ArrayRef<unsigned> Idxs,
+                                   const Twine &NameStr,
+                                   Instruction *InsertBefore)
+  : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
+                     ExtractValue, Agg, InsertBefore) {
+  init(Idxs, NameStr);
+}
+ExtractValueInst::ExtractValueInst(Value *Agg,
+                                   ArrayRef<unsigned> Idxs,
+                                   const Twine &NameStr,
+                                   BasicBlock *InsertAtEnd)
+  : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
+                     ExtractValue, Agg, InsertAtEnd) {
+  init(Idxs, NameStr);
+}
+
+
+//===----------------------------------------------------------------------===//
+//                                InsertValueInst Class
+//===----------------------------------------------------------------------===//
+
+/// InsertValueInst - This instruction inserts a struct field of array element
+/// value into an aggregate value.
+///
+class InsertValueInst : public Instruction {
+  SmallVector<unsigned, 4> Indices;
+
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  InsertValueInst(const InsertValueInst &IVI);
+  void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+            const Twine &NameStr);
+
+  /// Constructors - Create a insertvalue instruction with a base aggregate
+  /// value, a value to insert, and a list of indices.  The first ctor can
+  /// optionally insert before an existing instruction, the second appends
+  /// the new instruction to the specified BasicBlock.
+  inline InsertValueInst(Value *Agg, Value *Val,
+                         ArrayRef<unsigned> Idxs,
+                         const Twine &NameStr,
+                         Instruction *InsertBefore);
+  inline InsertValueInst(Value *Agg, Value *Val,
+                         ArrayRef<unsigned> Idxs,
+                         const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+  /// Constructors - These two constructors are convenience methods because one
+  /// and two index insertvalue instructions are so common.
+  InsertValueInst(Value *Agg, Value *Val,
+                  unsigned Idx, const Twine &NameStr = "",
+                  Instruction *InsertBefore = nullptr);
+  InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
+                  const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+  InsertValueInst *clone_impl() const override;
+public:
+  // allocate space for exactly two operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 2);
+  }
+
+  static InsertValueInst *Create(Value *Agg, Value *Val,
+                                 ArrayRef<unsigned> Idxs,
+                                 const Twine &NameStr = "",
+                                 Instruction *InsertBefore = nullptr) {
+    return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
+  }
+  static InsertValueInst *Create(Value *Agg, Value *Val,
+                                 ArrayRef<unsigned> Idxs,
+                                 const Twine &NameStr,
+                                 BasicBlock *InsertAtEnd) {
+    return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd);
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  typedef const unsigned* idx_iterator;
+  inline idx_iterator idx_begin() const { return Indices.begin(); }
+  inline idx_iterator idx_end()   const { return Indices.end(); }
+
+  Value *getAggregateOperand() {
+    return getOperand(0);
+  }
+  const Value *getAggregateOperand() const {
+    return getOperand(0);
+  }
+  static unsigned getAggregateOperandIndex() {
+    return 0U;                      // get index for modifying correct operand
+  }
+
+  Value *getInsertedValueOperand() {
+    return getOperand(1);
+  }
+  const Value *getInsertedValueOperand() const {
+    return getOperand(1);
+  }
+  static unsigned getInsertedValueOperandIndex() {
+    return 1U;                      // get index for modifying correct operand
+  }
+
+  ArrayRef<unsigned> getIndices() const {
+    return Indices;
+  }
+
+  unsigned getNumIndices() const {
+    return (unsigned)Indices.size();
+  }
+
+  bool hasIndices() const {
+    return true;
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::InsertValue;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<InsertValueInst> :
+  public FixedNumOperandTraits<InsertValueInst, 2> {
+};
+
+InsertValueInst::InsertValueInst(Value *Agg,
+                                 Value *Val,
+                                 ArrayRef<unsigned> Idxs,
+                                 const Twine &NameStr,
+                                 Instruction *InsertBefore)
+  : Instruction(Agg->getType(), InsertValue,
+                OperandTraits<InsertValueInst>::op_begin(this),
+                2, InsertBefore) {
+  init(Agg, Val, Idxs, NameStr);
+}
+InsertValueInst::InsertValueInst(Value *Agg,
+                                 Value *Val,
+                                 ArrayRef<unsigned> Idxs,
+                                 const Twine &NameStr,
+                                 BasicBlock *InsertAtEnd)
+  : Instruction(Agg->getType(), InsertValue,
+                OperandTraits<InsertValueInst>::op_begin(this),
+                2, InsertAtEnd) {
+  init(Agg, Val, Idxs, NameStr);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               PHINode Class
+//===----------------------------------------------------------------------===//
+
+// PHINode - The PHINode class is used to represent the magical mystical PHI
+// node, that can not exist in nature, but can be synthesized in a computer
+// scientist's overactive imagination.
+//
+class PHINode : public Instruction {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  /// ReservedSpace - The number of operands actually allocated.  NumOperands is
+  /// the number actually in use.
+  unsigned ReservedSpace;
+  PHINode(const PHINode &PN);
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  explicit PHINode(Type *Ty, unsigned NumReservedValues,
+                   const Twine &NameStr = "",
+                   Instruction *InsertBefore = nullptr)
+    : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertBefore),
+      ReservedSpace(NumReservedValues) {
+    setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
+  }
+
+  PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
+          BasicBlock *InsertAtEnd)
+    : Instruction(Ty, Instruction::PHI, nullptr, 0, InsertAtEnd),
+      ReservedSpace(NumReservedValues) {
+    setName(NameStr);
+    OperandList = allocHungoffUses(ReservedSpace);
+  }
+protected:
+  // allocHungoffUses - this is more complicated than the generic
+  // User::allocHungoffUses, because we have to allocate Uses for the incoming
+  // values and pointers to the incoming blocks, all in one allocation.
+  Use *allocHungoffUses(unsigned) const;
+
+  PHINode *clone_impl() const override;
+public:
+  /// Constructors - NumReservedValues is a hint for the number of incoming
+  /// edges that this phi node will have (use 0 if you really have no idea).
+  static PHINode *Create(Type *Ty, unsigned NumReservedValues,
+                         const Twine &NameStr = "",
+                         Instruction *InsertBefore = nullptr) {
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
+  }
+  static PHINode *Create(Type *Ty, unsigned NumReservedValues,
+                         const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
+  }
+  ~PHINode();
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Block iterator interface. This provides access to the list of incoming
+  // basic blocks, which parallels the list of incoming values.
+
+  typedef BasicBlock **block_iterator;
+  typedef BasicBlock * const *const_block_iterator;
+
+  block_iterator block_begin() {
+    Use::UserRef *ref =
+      reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace);
+    return reinterpret_cast<block_iterator>(ref + 1);
+  }
+
+  const_block_iterator block_begin() const {
+    const Use::UserRef *ref =
+      reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace);
+    return reinterpret_cast<const_block_iterator>(ref + 1);
+  }
+
+  block_iterator block_end() {
+    return block_begin() + getNumOperands();
+  }
+
+  const_block_iterator block_end() const {
+    return block_begin() + getNumOperands();
+  }
+
+  /// getNumIncomingValues - Return the number of incoming edges
+  ///
+  unsigned getNumIncomingValues() const { return getNumOperands(); }
+
+  /// getIncomingValue - Return incoming value number x
+  ///
+  Value *getIncomingValue(unsigned i) const {
+    return getOperand(i);
+  }
+  void setIncomingValue(unsigned i, Value *V) {
+    setOperand(i, V);
+  }
+  static unsigned getOperandNumForIncomingValue(unsigned i) {
+    return i;
+  }
+  static unsigned getIncomingValueNumForOperand(unsigned i) {
+    return i;
+  }
+
+  /// getIncomingBlock - Return incoming basic block number @p i.
+  ///
+  BasicBlock *getIncomingBlock(unsigned i) const {
+    return block_begin()[i];
+  }
+
+  /// getIncomingBlock - Return incoming basic block corresponding
+  /// to an operand of the PHI.
+  ///
+  BasicBlock *getIncomingBlock(const Use &U) const {
+    assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?");
+    return getIncomingBlock(unsigned(&U - op_begin()));
+  }
+
+  /// getIncomingBlock - Return incoming basic block corresponding
+  /// to value use iterator.
+  ///
+  BasicBlock *getIncomingBlock(Value::const_user_iterator I) const {
+    return getIncomingBlock(I.getUse());
+  }
+
+  void setIncomingBlock(unsigned i, BasicBlock *BB) {
+    block_begin()[i] = BB;
+  }
+
+  /// addIncoming - Add an incoming value to the end of the PHI list
+  ///
+  void addIncoming(Value *V, BasicBlock *BB) {
+    assert(V && "PHI node got a null value!");
+    assert(BB && "PHI node got a null basic block!");
+    assert(getType() == V->getType() &&
+           "All operands to PHI node must be the same type as the PHI node!");
+    if (NumOperands == ReservedSpace)
+      growOperands();  // Get more space!
+    // Initialize some new operands.
+    ++NumOperands;
+    setIncomingValue(NumOperands - 1, V);
+    setIncomingBlock(NumOperands - 1, BB);
+  }
+
+  /// removeIncomingValue - Remove an incoming value.  This is useful if a
+  /// predecessor basic block is deleted.  The value removed is returned.
+  ///
+  /// If the last incoming value for a PHI node is removed (and DeletePHIIfEmpty
+  /// is true), the PHI node is destroyed and any uses of it are replaced with
+  /// dummy values.  The only time there should be zero incoming values to a PHI
+  /// node is when the block is dead, so this strategy is sound.
+  ///
+  Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true);
+
+  Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty=true) {
+    int Idx = getBasicBlockIndex(BB);
+    assert(Idx >= 0 && "Invalid basic block argument to remove!");
+    return removeIncomingValue(Idx, DeletePHIIfEmpty);
+  }
+
+  /// getBasicBlockIndex - Return the first index of the specified basic
+  /// block in the value list for this PHI.  Returns -1 if no instance.
+  ///
+  int getBasicBlockIndex(const BasicBlock *BB) const {
+    for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+      if (block_begin()[i] == BB)
+        return i;
+    return -1;
+  }
+
+  Value *getIncomingValueForBlock(const BasicBlock *BB) const {
+    int Idx = getBasicBlockIndex(BB);
+    assert(Idx >= 0 && "Invalid basic block argument!");
+    return getIncomingValue(Idx);
+  }
+
+  /// hasConstantValue - If the specified PHI node always merges together the
+  /// same value, return the value, otherwise return null.
+  Value *hasConstantValue() const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::PHI;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+ private:
+  void growOperands();
+};
+
+template <>
+struct OperandTraits<PHINode> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
+
+//===----------------------------------------------------------------------===//
+//                           LandingPadInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// LandingPadInst - The landingpad instruction holds all of the information
+/// necessary to generate correct exception handling. The landingpad instruction
+/// cannot be moved from the top of a landing pad block, which itself is
+/// accessible only from the 'unwind' edge of an invoke. This uses the
+/// SubclassData field in Value to store whether or not the landingpad is a
+/// cleanup.
+///
+class LandingPadInst : public Instruction {
+  /// ReservedSpace - The number of operands actually allocated.  NumOperands is
+  /// the number actually in use.
+  unsigned ReservedSpace;
+  LandingPadInst(const LandingPadInst &LP);
+public:
+  enum ClauseType { Catch, Filter };
+private:
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  // Allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  void growOperands(unsigned Size);
+  void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr);
+
+  explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+                          unsigned NumReservedValues, const Twine &NameStr,
+                          Instruction *InsertBefore);
+  explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+                          unsigned NumReservedValues, const Twine &NameStr,
+                          BasicBlock *InsertAtEnd);
+protected:
+  LandingPadInst *clone_impl() const override;
+public:
+  /// Constructors - NumReservedClauses is a hint for the number of incoming
+  /// clauses that this landingpad will have (use 0 if you really have no idea).
+  static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+                                unsigned NumReservedClauses,
+                                const Twine &NameStr = "",
+                                Instruction *InsertBefore = nullptr);
+  static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+                                unsigned NumReservedClauses,
+                                const Twine &NameStr, BasicBlock *InsertAtEnd);
+  ~LandingPadInst();
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// getPersonalityFn - Get the personality function associated with this
+  /// landing pad.
+  Value *getPersonalityFn() const { return getOperand(0); }
+
+  /// isCleanup - Return 'true' if this landingpad instruction is a
+  /// cleanup. I.e., it should be run when unwinding even if its landing pad
+  /// doesn't catch the exception.
+  bool isCleanup() const { return getSubclassDataFromInstruction() & 1; }
+
+  /// setCleanup - Indicate that this landingpad instruction is a cleanup.
+  void setCleanup(bool V) {
+    setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+                               (V ? 1 : 0));
+  }
+
+  /// Add a catch or filter clause to the landing pad.
+  void addClause(Constant *ClauseVal);
+
+  /// Get the value of the clause at index Idx. Use isCatch/isFilter to
+  /// determine what type of clause this is.
+  Constant *getClause(unsigned Idx) const {
+    return cast<Constant>(OperandList[Idx + 1]);
+  }
+
+  /// isCatch - Return 'true' if the clause and index Idx is a catch clause.
+  bool isCatch(unsigned Idx) const {
+    return !isa<ArrayType>(OperandList[Idx + 1]->getType());
+  }
+
+  /// isFilter - Return 'true' if the clause and index Idx is a filter clause.
+  bool isFilter(unsigned Idx) const {
+    return isa<ArrayType>(OperandList[Idx + 1]->getType());
+  }
+
+  /// getNumClauses - Get the number of clauses for this landing pad.
+  unsigned getNumClauses() const { return getNumOperands() - 1; }
+
+  /// reserveClauses - Grow the size of the operand list to accommodate the new
+  /// number of clauses.
+  void reserveClauses(unsigned Size) { growOperands(Size); }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::LandingPad;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+template <>
+struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               ReturnInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ReturnInst - Return a value (possibly void), from a function.  Execution
+/// does not continue in this function any longer.
+///
+class ReturnInst : public TerminatorInst {
+  ReturnInst(const ReturnInst &RI);
+
+private:
+  // ReturnInst constructors:
+  // ReturnInst()                  - 'ret void' instruction
+  // ReturnInst(    null)          - 'ret void' instruction
+  // ReturnInst(Value* X)          - 'ret X'    instruction
+  // ReturnInst(    null, Inst *I) - 'ret void' instruction, insert before I
+  // ReturnInst(Value* X, Inst *I) - 'ret X'    instruction, insert before I
+  // ReturnInst(    null, BB *B)   - 'ret void' instruction, insert @ end of B
+  // ReturnInst(Value* X, BB *B)   - 'ret X'    instruction, insert @ end of B
+  //
+  // NOTE: If the Value* passed is of type void then the constructor behaves as
+  // if it was passed NULL.
+  explicit ReturnInst(LLVMContext &C, Value *retVal = nullptr,
+                      Instruction *InsertBefore = nullptr);
+  ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd);
+  explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+protected:
+  ReturnInst *clone_impl() const override;
+public:
+  static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr,
+                            Instruction *InsertBefore = nullptr) {
+    return new(!!retVal) ReturnInst(C, retVal, InsertBefore);
+  }
+  static ReturnInst* Create(LLVMContext &C, Value *retVal,
+                            BasicBlock *InsertAtEnd) {
+    return new(!!retVal) ReturnInst(C, retVal, InsertAtEnd);
+  }
+  static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
+    return new(0) ReturnInst(C, InsertAtEnd);
+  }
+  virtual ~ReturnInst();
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Convenience accessor. Returns null if there is no return value.
+  Value *getReturnValue() const {
+    return getNumOperands() != 0 ? getOperand(0) : nullptr;
+  }
+
+  unsigned getNumSuccessors() const { return 0; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::Ret);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+ private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<ReturnInst> : public VariadicOperandTraits<ReturnInst> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               BranchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// BranchInst - Conditional or Unconditional Branch instruction.
+///
+class BranchInst : public TerminatorInst {
+  /// Ops list - Branches are strange.  The operands are ordered:
+  ///  [Cond, FalseDest,] TrueDest.  This makes some accessors faster because
+  /// they don't have to check for cond/uncond branchness. These are mostly
+  /// accessed relative from op_end().
+  BranchInst(const BranchInst &BI);
+  void AssertOK();
+  // BranchInst constructors (where {B, T, F} are blocks, and C is a condition):
+  // BranchInst(BB *B)                           - 'br B'
+  // BranchInst(BB* T, BB *F, Value *C)          - 'br C, T, F'
+  // BranchInst(BB* B, Inst *I)                  - 'br B'        insert before I
+  // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I
+  // BranchInst(BB* B, BB *I)                    - 'br B'        insert at end
+  // BranchInst(BB* T, BB *F, Value *C, BB *I)   - 'br C, T, F', insert at end
+  explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = nullptr);
+  BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+             Instruction *InsertBefore = nullptr);
+  BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd);
+  BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+             BasicBlock *InsertAtEnd);
+protected:
+  BranchInst *clone_impl() const override;
+public:
+  static BranchInst *Create(BasicBlock *IfTrue,
+                            Instruction *InsertBefore = nullptr) {
+    return new(1) BranchInst(IfTrue, InsertBefore);
+  }
+  static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
+                            Value *Cond, Instruction *InsertBefore = nullptr) {
+    return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore);
+  }
+  static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) {
+    return new(1) BranchInst(IfTrue, InsertAtEnd);
+  }
+  static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
+                            Value *Cond, BasicBlock *InsertAtEnd) {
+    return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd);
+  }
+
+  /// Transparently provide more efficient getOperand methods.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  bool isUnconditional() const { return getNumOperands() == 1; }
+  bool isConditional()   const { return getNumOperands() == 3; }
+
+  Value *getCondition() const {
+    assert(isConditional() && "Cannot get condition of an uncond branch!");
+    return Op<-3>();
+  }
+
+  void setCondition(Value *V) {
+    assert(isConditional() && "Cannot set condition of unconditional branch!");
+    Op<-3>() = V;
+  }
+
+  unsigned getNumSuccessors() const { return 1+isConditional(); }
+
+  BasicBlock *getSuccessor(unsigned i) const {
+    assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
+    return cast_or_null<BasicBlock>((&Op<-1>() - i)->get());
+  }
+
+  void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+    assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
+    *(&Op<-1>() - idx) = (Value*)NewSucc;
+  }
+
+  /// \brief Swap the successors of this branch instruction.
+  ///
+  /// Swaps the successors of the branch instruction. This also swaps any
+  /// branch weight metadata associated with the instruction so that it
+  /// continues to map correctly to each operand.
+  void swapSuccessors();
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::Br);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<BranchInst> : public VariadicOperandTraits<BranchInst, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               SwitchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// SwitchInst - Multiway switch
+///
+class SwitchInst : public TerminatorInst {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  unsigned ReservedSpace;
+  // Operand[0]    = Value to switch on
+  // Operand[1]    = Default basic block destination
+  // Operand[2n  ] = Value to match
+  // Operand[2n+1] = BasicBlock to go to on match
+  SwitchInst(const SwitchInst &SI);
+  void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
+  void growOperands();
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+  /// switch on and a default destination.  The number of additional cases can
+  /// be specified here to make memory allocation more efficient.  This
+  /// constructor can also autoinsert before another instruction.
+  SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+             Instruction *InsertBefore);
+
+  /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+  /// switch on and a default destination.  The number of additional cases can
+  /// be specified here to make memory allocation more efficient.  This
+  /// constructor also autoinserts at the end of the specified BasicBlock.
+  SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+             BasicBlock *InsertAtEnd);
+protected:
+  SwitchInst *clone_impl() const override;
+public:
+
+  // -2
+  static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
+
+  template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
+  class CaseIteratorT {
+  protected:
+
+    SwitchInstTy *SI;
+    unsigned Index;
+
+  public:
+
+    typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
+
+    /// Initializes case iterator for given SwitchInst and for given
+    /// case number.
+    CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
+      this->SI = SI;
+      Index = CaseNum;
+    }
+
+    /// Initializes case iterator for given SwitchInst and for given
+    /// TerminatorInst's successor index.
+    static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
+      assert(SuccessorIndex < SI->getNumSuccessors() &&
+             "Successor index # out of range!");
+      return SuccessorIndex != 0 ?
+             Self(SI, SuccessorIndex - 1) :
+             Self(SI, DefaultPseudoIndex);
+    }
+
+    /// Resolves case value for current case.
+    ConstantIntTy *getCaseValue() {
+      assert(Index < SI->getNumCases() && "Index out the number of cases.");
+      return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
+    }
+
+    /// Resolves successor for current case.
+    BasicBlockTy *getCaseSuccessor() {
+      assert((Index < SI->getNumCases() ||
+              Index == DefaultPseudoIndex) &&
+             "Index out the number of cases.");
+      return SI->getSuccessor(getSuccessorIndex());
+    }
+
+    /// Returns number of current case.
+    unsigned getCaseIndex() const { return Index; }
+
+    /// Returns TerminatorInst's successor index for current case successor.
+    unsigned getSuccessorIndex() const {
+      assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
+             "Index out the number of cases.");
+      return Index != DefaultPseudoIndex ? Index + 1 : 0;
+    }
+
+    Self operator++() {
+      // Check index correctness after increment.
+      // Note: Index == getNumCases() means end().
+      assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
+      ++Index;
+      return *this;
+    }
+    Self operator++(int) {
+      Self tmp = *this;
+      ++(*this);
+      return tmp;
+    }
+    Self operator--() {
+      // Check index correctness after decrement.
+      // Note: Index == getNumCases() means end().
+      // Also allow "-1" iterator here. That will became valid after ++.
+      assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
+             "Index out the number of cases.");
+      --Index;
+      return *this;
+    }
+    Self operator--(int) {
+      Self tmp = *this;
+      --(*this);
+      return tmp;
+    }
+    bool operator==(const Self& RHS) const {
+      assert(RHS.SI == SI && "Incompatible operators.");
+      return RHS.Index == Index;
+    }
+    bool operator!=(const Self& RHS) const {
+      assert(RHS.SI == SI && "Incompatible operators.");
+      return RHS.Index != Index;
+    }
+    Self &operator*() {
+      return *this;
+    }
+  };
+
+  typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
+    ConstCaseIt;
+
+  class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
+
+    typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
+
+  public:
+
+    CaseIt(const ParentTy& Src) : ParentTy(Src) {}
+    CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+
+    /// Sets the new value for current case.
+    void setValue(ConstantInt *V) {
+      assert(Index < SI->getNumCases() && "Index out the number of cases.");
+      SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
+    }
+
+    /// Sets the new successor for current case.
+    void setSuccessor(BasicBlock *S) {
+      SI->setSuccessor(getSuccessorIndex(), S);
+    }
+  };
+
+  static SwitchInst *Create(Value *Value, BasicBlock *Default,
+                            unsigned NumCases,
+                            Instruction *InsertBefore = nullptr) {
+    return new SwitchInst(Value, Default, NumCases, InsertBefore);
+  }
+  static SwitchInst *Create(Value *Value, BasicBlock *Default,
+                            unsigned NumCases, BasicBlock *InsertAtEnd) {
+    return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
+  }
+
+  ~SwitchInst();
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Accessor Methods for Switch stmt
+  Value *getCondition() const { return getOperand(0); }
+  void setCondition(Value *V) { setOperand(0, V); }
+
+  BasicBlock *getDefaultDest() const {
+    return cast<BasicBlock>(getOperand(1));
+  }
+
+  void setDefaultDest(BasicBlock *DefaultCase) {
+    setOperand(1, reinterpret_cast<Value*>(DefaultCase));
+  }
+
+  /// getNumCases - return the number of 'cases' in this switch instruction,
+  /// except the default case
+  unsigned getNumCases() const {
+    return getNumOperands()/2 - 1;
+  }
+
+  /// Returns a read/write iterator that points to the first
+  /// case in SwitchInst.
+  CaseIt case_begin() {
+    return CaseIt(this, 0);
+  }
+  /// Returns a read-only iterator that points to the first
+  /// case in the SwitchInst.
+  ConstCaseIt case_begin() const {
+    return ConstCaseIt(this, 0);
+  }
+
+  /// Returns a read/write iterator that points one past the last
+  /// in the SwitchInst.
+  CaseIt case_end() {
+    return CaseIt(this, getNumCases());
+  }
+  /// Returns a read-only iterator that points one past the last
+  /// in the SwitchInst.
+  ConstCaseIt case_end() const {
+    return ConstCaseIt(this, getNumCases());
+  }
+
+  /// cases - iteration adapter for range-for loops.
+  iterator_range<CaseIt> cases() {
+    return iterator_range<CaseIt>(case_begin(), case_end());
+  }
+
+  /// cases - iteration adapter for range-for loops.
+  iterator_range<ConstCaseIt> cases() const {
+    return iterator_range<ConstCaseIt>(case_begin(), case_end());
+  }
+
+  /// Returns an iterator that points to the default case.
+  /// Note: this iterator allows to resolve successor only. Attempt
+  /// to resolve case value causes an assertion.
+  /// Also note, that increment and decrement also causes an assertion and
+  /// makes iterator invalid.
+  CaseIt case_default() {
+    return CaseIt(this, DefaultPseudoIndex);
+  }
+  ConstCaseIt case_default() const {
+    return ConstCaseIt(this, DefaultPseudoIndex);
+  }
+
+  /// findCaseValue - Search all of the case values for the specified constant.
+  /// If it is explicitly handled, return the case iterator of it, otherwise
+  /// return default case iterator to indicate
+  /// that it is handled by the default handler.
+  CaseIt findCaseValue(const ConstantInt *C) {
+    for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
+      if (i.getCaseValue() == C)
+        return i;
+    return case_default();
+  }
+  ConstCaseIt findCaseValue(const ConstantInt *C) const {
+    for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
+      if (i.getCaseValue() == C)
+        return i;
+    return case_default();
+  }
+
+  /// findCaseDest - Finds the unique case value for a given successor. Returns
+  /// null if the successor is not found, not unique, or is the default case.
+  ConstantInt *findCaseDest(BasicBlock *BB) {
+    if (BB == getDefaultDest()) return nullptr;
+
+    ConstantInt *CI = nullptr;
+    for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
+      if (i.getCaseSuccessor() == BB) {
+        if (CI) return nullptr;   // Multiple cases lead to BB.
+        else CI = i.getCaseValue();
+      }
+    }
+    return CI;
+  }
+
+  /// addCase - Add an entry to the switch instruction...
+  /// Note:
+  /// This action invalidates case_end(). Old case_end() iterator will
+  /// point to the added case.
+  void addCase(ConstantInt *OnVal, BasicBlock *Dest);
+
+  /// removeCase - This method removes the specified case and its successor
+  /// from the switch instruction. Note that this operation may reorder the
+  /// remaining cases at index idx and above.
+  /// Note:
+  /// This action invalidates iterators for all cases following the one removed,
+  /// including the case_end() iterator.
+  void removeCase(CaseIt i);
+
+  unsigned getNumSuccessors() const { return getNumOperands()/2; }
+  BasicBlock *getSuccessor(unsigned idx) const {
+    assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
+    return cast<BasicBlock>(getOperand(idx*2+1));
+  }
+  void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+    assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
+    setOperand(idx*2+1, (Value*)NewSucc);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Switch;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+//                             IndirectBrInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// IndirectBrInst - Indirect Branch Instruction.
+///
+class IndirectBrInst : public TerminatorInst {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  unsigned ReservedSpace;
+  // Operand[0]    = Value to switch on
+  // Operand[1]    = Default basic block destination
+  // Operand[2n  ] = Value to match
+  // Operand[2n+1] = BasicBlock to go to on match
+  IndirectBrInst(const IndirectBrInst &IBI);
+  void init(Value *Address, unsigned NumDests);
+  void growOperands();
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
+  /// Address to jump to.  The number of expected destinations can be specified
+  /// here to make memory allocation more efficient.  This constructor can also
+  /// autoinsert before another instruction.
+  IndirectBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore);
+
+  /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
+  /// Address to jump to.  The number of expected destinations can be specified
+  /// here to make memory allocation more efficient.  This constructor also
+  /// autoinserts at the end of the specified BasicBlock.
+  IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd);
+protected:
+  IndirectBrInst *clone_impl() const override;
+public:
+  static IndirectBrInst *Create(Value *Address, unsigned NumDests,
+                                Instruction *InsertBefore = nullptr) {
+    return new IndirectBrInst(Address, NumDests, InsertBefore);
+  }
+  static IndirectBrInst *Create(Value *Address, unsigned NumDests,
+                                BasicBlock *InsertAtEnd) {
+    return new IndirectBrInst(Address, NumDests, InsertAtEnd);
+  }
+  ~IndirectBrInst();
+
+  /// Provide fast operand accessors.
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  // Accessor Methods for IndirectBrInst instruction.
+  Value *getAddress() { return getOperand(0); }
+  const Value *getAddress() const { return getOperand(0); }
+  void setAddress(Value *V) { setOperand(0, V); }
+
+
+  /// getNumDestinations - return the number of possible destinations in this
+  /// indirectbr instruction.
+  unsigned getNumDestinations() const { return getNumOperands()-1; }
+
+  /// getDestination - Return the specified destination.
+  BasicBlock *getDestination(unsigned i) { return getSuccessor(i); }
+  const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); }
+
+  /// addDestination - Add a destination.
+  ///
+  void addDestination(BasicBlock *Dest);
+
+  /// removeDestination - This method removes the specified successor from the
+  /// indirectbr instruction.
+  void removeDestination(unsigned i);
+
+  unsigned getNumSuccessors() const { return getNumOperands()-1; }
+  BasicBlock *getSuccessor(unsigned i) const {
+    return cast<BasicBlock>(getOperand(i+1));
+  }
+  void setSuccessor(unsigned i, BasicBlock *NewSucc) {
+    setOperand(i+1, (Value*)NewSucc);
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::IndirectBr;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<IndirectBrInst> : public HungoffOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+//                               InvokeInst Class
+//===----------------------------------------------------------------------===//
+
+/// InvokeInst - Invoke instruction.  The SubclassData field is used to hold the
+/// calling convention of the call.
+///
+class InvokeInst : public TerminatorInst {
+  AttributeSet AttributeList;
+  InvokeInst(const InvokeInst &BI);
+  void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+            ArrayRef<Value *> Args, const Twine &NameStr);
+
+  /// Construct an InvokeInst given a range of arguments.
+  ///
+  /// \brief Construct an InvokeInst from a range of arguments
+  inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+                    ArrayRef<Value *> Args, unsigned Values,
+                    const Twine &NameStr, Instruction *InsertBefore);
+
+  /// Construct an InvokeInst given a range of arguments.
+  ///
+  /// \brief Construct an InvokeInst from a range of arguments
+  inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+                    ArrayRef<Value *> Args, unsigned Values,
+                    const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+  InvokeInst *clone_impl() const override;
+public:
+  static InvokeInst *Create(Value *Func,
+                            BasicBlock *IfNormal, BasicBlock *IfException,
+                            ArrayRef<Value *> Args, const Twine &NameStr = "",
+                            Instruction *InsertBefore = nullptr) {
+    unsigned Values = unsigned(Args.size()) + 3;
+    return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
+                                  Values, NameStr, InsertBefore);
+  }
+  static InvokeInst *Create(Value *Func,
+                            BasicBlock *IfNormal, BasicBlock *IfException,
+                            ArrayRef<Value *> Args, const Twine &NameStr,
+                            BasicBlock *InsertAtEnd) {
+    unsigned Values = unsigned(Args.size()) + 3;
+    return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
+                                  Values, NameStr, InsertAtEnd);
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// getNumArgOperands - Return the number of invoke arguments.
+  ///
+  unsigned getNumArgOperands() const { return getNumOperands() - 3; }
+
+  /// getArgOperand/setArgOperand - Return/set the i-th invoke argument.
+  ///
+  Value *getArgOperand(unsigned i) const { return getOperand(i); }
+  void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+  /// arg_operands - iteration adapter for range-for loops.
+  iterator_range<op_iterator> arg_operands() {
+    return iterator_range<op_iterator>(op_begin(), op_end() - 3);
+  }
+
+  /// arg_operands - iteration adapter for range-for loops.
+  iterator_range<const_op_iterator> arg_operands() const {
+    return iterator_range<const_op_iterator>(op_begin(), op_end() - 3);
+  }
+
+  /// \brief Wrappers for getting the \c Use of a invoke argument.
+  const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+  Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
+  /// getCallingConv/setCallingConv - Get or set the calling convention of this
+  /// function call.
+  CallingConv::ID getCallingConv() const {
+    return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
+  }
+  void setCallingConv(CallingConv::ID CC) {
+    setInstructionSubclassData(static_cast<unsigned>(CC));
+  }
+
+  /// getAttributes - Return the parameter attributes for this invoke.
+  ///
+  const AttributeSet &getAttributes() const { return AttributeList; }
+
+  /// setAttributes - Set the parameter attributes for this invoke.
+  ///
+  void setAttributes(const AttributeSet &Attrs) { AttributeList = Attrs; }
+
+  /// addAttribute - adds the attribute to the list of attributes.
+  void addAttribute(unsigned i, Attribute::AttrKind attr);
+
+  /// removeAttribute - removes the attribute from the list of attributes.
+  void removeAttribute(unsigned i, Attribute attr);
+
+  /// \brief Determine whether this call has the given attribute.
+  bool hasFnAttr(Attribute::AttrKind A) const {
+    assert(A != Attribute::NoBuiltin &&
+           "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");
+    return hasFnAttrImpl(A);
+  }
+
+  /// \brief Determine whether the call or the callee has the given attributes.
+  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
+
+  /// \brief Extract the alignment for a call or parameter (0=unknown).
+  unsigned getParamAlignment(unsigned i) const {
+    return AttributeList.getParamAlignment(i);
+  }
+
+  /// \brief Extract the number of dereferenceable bytes for a call or
+  /// parameter (0=unknown).
+  uint64_t getDereferenceableBytes(unsigned i) const {
+    return AttributeList.getDereferenceableBytes(i);
+  }
+
+  /// \brief Return true if the call should not be treated as a call to a
+  /// builtin.
+  bool isNoBuiltin() const {
+    // We assert in hasFnAttr if one passes in Attribute::NoBuiltin, so we have
+    // to check it by hand.
+    return hasFnAttrImpl(Attribute::NoBuiltin) &&
+      !hasFnAttrImpl(Attribute::Builtin);
+  }
+
+  /// \brief Return true if the call should not be inlined.
+  bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
+  void setIsNoInline() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoInline);
+  }
+
+  /// \brief Determine if the call does not access memory.
+  bool doesNotAccessMemory() const {
+    return hasFnAttr(Attribute::ReadNone);
+  }
+  void setDoesNotAccessMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
+  }
+
+  /// \brief Determine if the call does not access or only reads memory.
+  bool onlyReadsMemory() const {
+    return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+  }
+  void setOnlyReadsMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
+  }
+
+  /// \brief Determine if the call cannot return.
+  bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
+  void setDoesNotReturn() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoReturn);
+  }
+
+  /// \brief Determine if the call cannot unwind.
+  bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
+  void setDoesNotThrow() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
+  }
+
+  /// \brief Determine if the invoke cannot be duplicated.
+  bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
+  void setCannotDuplicate() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
+  }
+
+  /// \brief Determine if the call returns a structure through first
+  /// pointer argument.
+  bool hasStructRetAttr() const {
+    // Be friendly and also check the callee.
+    return paramHasAttr(1, Attribute::StructRet);
+  }
+
+  /// \brief Determine if any call argument is an aggregate passed by value.
+  bool hasByValArgument() const {
+    return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+  }
+
+  /// getCalledFunction - Return the function called, or null if this is an
+  /// indirect function invocation.
+  ///
+  Function *getCalledFunction() const {
+    return dyn_cast<Function>(Op<-3>());
+  }
+
+  /// getCalledValue - Get a pointer to the function that is invoked by this
+  /// instruction
+  const Value *getCalledValue() const { return Op<-3>(); }
+        Value *getCalledValue()       { return Op<-3>(); }
+
+  /// setCalledFunction - Set the function called.
+  void setCalledFunction(Value* Fn) {
+    Op<-3>() = Fn;
+  }
+
+  // get*Dest - Return the destination basic blocks...
+  BasicBlock *getNormalDest() const {
+    return cast<BasicBlock>(Op<-2>());
+  }
+  BasicBlock *getUnwindDest() const {
+    return cast<BasicBlock>(Op<-1>());
+  }
+  void setNormalDest(BasicBlock *B) {
+    Op<-2>() = reinterpret_cast<Value*>(B);
+  }
+  void setUnwindDest(BasicBlock *B) {
+    Op<-1>() = reinterpret_cast<Value*>(B);
+  }
+
+  /// getLandingPadInst - Get the landingpad instruction from the landing pad
+  /// block (the unwind destination).
+  LandingPadInst *getLandingPadInst() const;
+
+  BasicBlock *getSuccessor(unsigned i) const {
+    assert(i < 2 && "Successor # out of range for invoke!");
+    return i == 0 ? getNormalDest() : getUnwindDest();
+  }
+
+  void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+    assert(idx < 2 && "Successor # out of range for invoke!");
+    *(&Op<-2>() + idx) = reinterpret_cast<Value*>(NewSucc);
+  }
+
+  unsigned getNumSuccessors() const { return 2; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::Invoke);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+
+  bool hasFnAttrImpl(Attribute::AttrKind A) const;
+
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
+};
+
+InvokeInst::InvokeInst(Value *Func,
+                       BasicBlock *IfNormal, BasicBlock *IfException,
+                       ArrayRef<Value *> Args, unsigned Values,
+                       const Twine &NameStr, Instruction *InsertBefore)
+  : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                      ->getElementType())->getReturnType(),
+                   Instruction::Invoke,
+                   OperandTraits<InvokeInst>::op_end(this) - Values,
+                   Values, InsertBefore) {
+  init(Func, IfNormal, IfException, Args, NameStr);
+}
+InvokeInst::InvokeInst(Value *Func,
+                       BasicBlock *IfNormal, BasicBlock *IfException,
+                       ArrayRef<Value *> Args, unsigned Values,
+                       const Twine &NameStr, BasicBlock *InsertAtEnd)
+  : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                      ->getElementType())->getReturnType(),
+                   Instruction::Invoke,
+                   OperandTraits<InvokeInst>::op_end(this) - Values,
+                   Values, InsertAtEnd) {
+  init(Func, IfNormal, IfException, Args, NameStr);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                              ResumeInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ResumeInst - Resume the propagation of an exception.
+///
+class ResumeInst : public TerminatorInst {
+  ResumeInst(const ResumeInst &RI);
+
+  explicit ResumeInst(Value *Exn, Instruction *InsertBefore=nullptr);
+  ResumeInst(Value *Exn, BasicBlock *InsertAtEnd);
+protected:
+  ResumeInst *clone_impl() const override;
+public:
+  static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = nullptr) {
+    return new(1) ResumeInst(Exn, InsertBefore);
+  }
+  static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) {
+    return new(1) ResumeInst(Exn, InsertAtEnd);
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  /// Convenience accessor.
+  Value *getValue() const { return Op<0>(); }
+
+  unsigned getNumSuccessors() const { return 0; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Resume;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+template <>
+struct OperandTraits<ResumeInst> :
+    public FixedNumOperandTraits<ResumeInst, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                           UnreachableInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// UnreachableInst - This function has undefined behavior.  In particular, the
+/// presence of this instruction indicates some higher level knowledge that the
+/// end of the block cannot be reached.
+///
+class UnreachableInst : public TerminatorInst {
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+protected:
+  UnreachableInst *clone_impl() const override;
+
+public:
+  // allocate space for exactly zero operands
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+  explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = nullptr);
+  explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+
+  unsigned getNumSuccessors() const { return 0; }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Unreachable;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+private:
+  BasicBlock *getSuccessorV(unsigned idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned idx, BasicBlock *B) override;
+};
+
+//===----------------------------------------------------------------------===//
+//                                 TruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a truncation of integer types.
+class TruncInst : public CastInst {
+protected:
+  /// \brief Clone an identical TruncInst
+  TruncInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  TruncInst(
+    Value *S,                           ///< The value to be truncated
+    Type *Ty,                           ///< The (smaller) type to truncate to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  TruncInst(
+    Value *S,                     ///< The value to be truncated
+    Type *Ty,                     ///< The (smaller) type to truncate to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Trunc;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 ZExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents zero extension of integer types.
+class ZExtInst : public CastInst {
+protected:
+  /// \brief Clone an identical ZExtInst
+  ZExtInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  ZExtInst(
+    Value *S,                           ///< The value to be zero extended
+    Type *Ty,                           ///< The type to zero extend to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end semantics.
+  ZExtInst(
+    Value *S,                     ///< The value to be zero extended
+    Type *Ty,                     ///< The type to zero extend to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == ZExt;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 SExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a sign extension of integer types.
+class SExtInst : public CastInst {
+protected:
+  /// \brief Clone an identical SExtInst
+  SExtInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  SExtInst(
+    Value *S,                           ///< The value to be sign extended
+    Type *Ty,                           ///< The type to sign extend to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  SExtInst(
+    Value *S,                     ///< The value to be sign extended
+    Type *Ty,                     ///< The type to sign extend to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == SExt;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 FPTruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a truncation of floating point types.
+class FPTruncInst : public CastInst {
+protected:
+  /// \brief Clone an identical FPTruncInst
+  FPTruncInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  FPTruncInst(
+    Value *S,                           ///< The value to be truncated
+    Type *Ty,                           ///< The type to truncate to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-before-instruction semantics
+  FPTruncInst(
+    Value *S,                     ///< The value to be truncated
+    Type *Ty,                     ///< The type to truncate to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == FPTrunc;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 FPExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents an extension of floating point types.
+class FPExtInst : public CastInst {
+protected:
+  /// \brief Clone an identical FPExtInst
+  FPExtInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  FPExtInst(
+    Value *S,                           ///< The value to be extended
+    Type *Ty,                           ///< The type to extend to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  FPExtInst(
+    Value *S,                     ///< The value to be extended
+    Type *Ty,                     ///< The type to extend to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == FPExt;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 UIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast unsigned integer to floating point.
+class UIToFPInst : public CastInst {
+protected:
+  /// \brief Clone an identical UIToFPInst
+  UIToFPInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  UIToFPInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  UIToFPInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == UIToFP;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 SIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast from signed integer to floating point.
+class SIToFPInst : public CastInst {
+protected:
+  /// \brief Clone an identical SIToFPInst
+  SIToFPInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  SIToFPInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  SIToFPInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == SIToFP;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 FPToUIInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast from floating point to unsigned integer
+class FPToUIInst  : public CastInst {
+protected:
+  /// \brief Clone an identical FPToUIInst
+  FPToUIInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  FPToUIInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  FPToUIInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< Where to insert the new instruction
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == FPToUI;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 FPToSIInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast from floating point to signed integer.
+class FPToSIInst  : public CastInst {
+protected:
+  /// \brief Clone an identical FPToSIInst
+  FPToSIInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  FPToSIInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  FPToSIInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == FPToSI;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 IntToPtrInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast from an integer to a pointer.
+class IntToPtrInst : public CastInst {
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  IntToPtrInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  IntToPtrInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Clone an identical IntToPtrInst
+  IntToPtrInst *clone_impl() const override;
+
+  /// \brief Returns the address space of this instruction's pointer type.
+  unsigned getAddressSpace() const {
+    return getType()->getPointerAddressSpace();
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == IntToPtr;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                                 PtrToIntInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a cast from a pointer to an integer
+class PtrToIntInst : public CastInst {
+protected:
+  /// \brief Clone an identical PtrToIntInst
+  PtrToIntInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  PtrToIntInst(
+    Value *S,                           ///< The value to be converted
+    Type *Ty,                           ///< The type to convert to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  PtrToIntInst(
+    Value *S,                     ///< The value to be converted
+    Type *Ty,                     ///< The type to convert to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  /// \brief Gets the pointer operand.
+  Value *getPointerOperand() { return getOperand(0); }
+  /// \brief Gets the pointer operand.
+  const Value *getPointerOperand() const { return getOperand(0); }
+  /// \brief Gets the operand index of the pointer operand.
+  static unsigned getPointerOperandIndex() { return 0U; }
+
+  /// \brief Returns the address space of the pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return getPointerOperand()->getType()->getPointerAddressSpace();
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == PtrToInt;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                             BitCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a no-op cast from one type to another.
+class BitCastInst : public CastInst {
+protected:
+  /// \brief Clone an identical BitCastInst
+  BitCastInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  BitCastInst(
+    Value *S,                           ///< The value to be casted
+    Type *Ty,                           ///< The type to casted to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  BitCastInst(
+    Value *S,                     ///< The value to be casted
+    Type *Ty,                     ///< The type to casted to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == BitCast;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                          AddrSpaceCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// \brief This class represents a conversion between pointers from
+/// one address space to another.
+class AddrSpaceCastInst : public CastInst {
+protected:
+  /// \brief Clone an identical AddrSpaceCastInst
+  AddrSpaceCastInst *clone_impl() const override;
+
+public:
+  /// \brief Constructor with insert-before-instruction semantics
+  AddrSpaceCastInst(
+    Value *S,                           ///< The value to be casted
+    Type *Ty,                           ///< The type to casted to
+    const Twine &NameStr = "",          ///< A name for the new instruction
+    Instruction *InsertBefore = nullptr ///< Where to insert the new instruction
+  );
+
+  /// \brief Constructor with insert-at-end-of-block semantics
+  AddrSpaceCastInst(
+    Value *S,                     ///< The value to be casted
+    Type *Ty,                     ///< The type to casted to
+    const Twine &NameStr,         ///< A name for the new instruction
+    BasicBlock *InsertAtEnd       ///< The block to insert the instruction into
+  );
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == AddrSpaceCast;
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
new file mode 100644
index 0000000..e053f78
--- /dev/null
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -0,0 +1,325 @@
+//===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- 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 classes that make it really easy to deal with intrinsic
+// functions with the isa/dyncast family of functions.  In particular, this
+// allows you to do things like:
+//
+//     if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
+//        ... MCI->getDest() ... MCI->getSource() ...
+//
+// All intrinsic function calls are instances of the call instruction, so these
+// are all subclasses of the CallInst class.  Note that none of these classes
+// has state or virtual methods, which is an important part of this gross/neat
+// hack working.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INTRINSICINST_H
+#define LLVM_IR_INTRINSICINST_H
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+
+namespace llvm {
+  /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic
+  /// functions.  This allows the standard isa/dyncast/cast functionality to
+  /// work with calls to intrinsic functions.
+  class IntrinsicInst : public CallInst {
+    IntrinsicInst() LLVM_DELETED_FUNCTION;
+    IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
+    void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
+  public:
+    /// getIntrinsicID - Return the intrinsic ID of this intrinsic.
+    ///
+    Intrinsic::ID getIntrinsicID() const {
+      return (Intrinsic::ID)getCalledFunction()->getIntrinsicID();
+    }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const CallInst *I) {
+      if (const Function *CF = I->getCalledFunction())
+        return CF->isIntrinsic();
+      return false;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<CallInst>(V) && classof(cast<CallInst>(V));
+    }
+  };
+
+  /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
+  ///
+  class DbgInfoIntrinsic : public IntrinsicInst {
+  public:
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      switch (I->getIntrinsicID()) {
+      case Intrinsic::dbg_declare:
+      case Intrinsic::dbg_value:
+        return true;
+      default: return false;
+      }
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+
+    static Value *StripCast(Value *C);
+  };
+
+  /// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
+  ///
+  class DbgDeclareInst : public DbgInfoIntrinsic {
+  public:
+    Value *getAddress() const;
+    MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::dbg_declare;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// DbgValueInst - This represents the llvm.dbg.value instruction.
+  ///
+  class DbgValueInst : public DbgInfoIntrinsic {
+  public:
+    const Value *getValue() const;
+    Value *getValue();
+    uint64_t getOffset() const {
+      return cast<ConstantInt>(
+                          const_cast<Value*>(getArgOperand(1)))->getZExtValue();
+    }
+    MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::dbg_value;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
+  ///
+  class MemIntrinsic : public IntrinsicInst {
+  public:
+    Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); }
+    const Use &getRawDestUse() const { return getArgOperandUse(0); }
+    Use &getRawDestUse() { return getArgOperandUse(0); }
+
+    Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); }
+    const Use &getLengthUse() const { return getArgOperandUse(2); }
+    Use &getLengthUse() { return getArgOperandUse(2); }
+
+    ConstantInt *getAlignmentCst() const {
+      return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));
+    }
+
+    unsigned getAlignment() const {
+      return getAlignmentCst()->getZExtValue();
+    }
+
+    ConstantInt *getVolatileCst() const {
+      return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4)));
+    }
+    bool isVolatile() const {
+      return !getVolatileCst()->isZero();
+    }
+
+    unsigned getDestAddressSpace() const {
+      return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+    }
+
+    /// getDest - This is just like getRawDest, but it strips off any cast
+    /// instructions that feed it, giving the original input.  The returned
+    /// value is guaranteed to be a pointer.
+    Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+    /// set* - Set the specified arguments of the instruction.
+    ///
+    void setDest(Value *Ptr) {
+      assert(getRawDest()->getType() == Ptr->getType() &&
+             "setDest called with pointer of wrong type!");
+      setArgOperand(0, Ptr);
+    }
+
+    void setLength(Value *L) {
+      assert(getLength()->getType() == L->getType() &&
+             "setLength called with value of wrong type!");
+      setArgOperand(2, L);
+    }
+
+    void setAlignment(Constant* A) {
+      setArgOperand(3, A);
+    }
+
+    void setVolatile(Constant* V) {
+      setArgOperand(4, V);
+    }
+
+    Type *getAlignmentType() const {
+      return getArgOperand(3)->getType();
+    }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      switch (I->getIntrinsicID()) {
+      case Intrinsic::memcpy:
+      case Intrinsic::memmove:
+      case Intrinsic::memset:
+        return true;
+      default: return false;
+      }
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// MemSetInst - This class wraps the llvm.memset intrinsic.
+  ///
+  class MemSetInst : public MemIntrinsic {
+  public:
+    /// get* - Return the arguments to the instruction.
+    ///
+    Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); }
+    const Use &getValueUse() const { return getArgOperandUse(1); }
+    Use &getValueUse() { return getArgOperandUse(1); }
+
+    void setValue(Value *Val) {
+      assert(getValue()->getType() == Val->getType() &&
+             "setValue called with value of wrong type!");
+      setArgOperand(1, Val);
+    }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::memset;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics.
+  ///
+  class MemTransferInst : public MemIntrinsic {
+  public:
+    /// get* - Return the arguments to the instruction.
+    ///
+    Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); }
+    const Use &getRawSourceUse() const { return getArgOperandUse(1); }
+    Use &getRawSourceUse() { return getArgOperandUse(1); }
+
+    /// getSource - This is just like getRawSource, but it strips off any cast
+    /// instructions that feed it, giving the original input.  The returned
+    /// value is guaranteed to be a pointer.
+    Value *getSource() const { return getRawSource()->stripPointerCasts(); }
+
+    unsigned getSourceAddressSpace() const {
+      return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+    }
+
+    void setSource(Value *Ptr) {
+      assert(getRawSource()->getType() == Ptr->getType() &&
+             "setSource called with pointer of wrong type!");
+      setArgOperand(1, Ptr);
+    }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::memcpy ||
+             I->getIntrinsicID() == Intrinsic::memmove;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+
+  /// MemCpyInst - This class wraps the llvm.memcpy intrinsic.
+  ///
+  class MemCpyInst : public MemTransferInst {
+  public:
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::memcpy;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// MemMoveInst - This class wraps the llvm.memmove intrinsic.
+  ///
+  class MemMoveInst : public MemTransferInst {
+  public:
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::memmove;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
+  /// VAStartInst - This represents the llvm.va_start intrinsic.
+  ///
+  class VAStartInst : public IntrinsicInst {
+  public:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::vastart;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+
+    Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
+  };
+
+  /// VAEndInst - This represents the llvm.va_end intrinsic.
+  ///
+  class VAEndInst : public IntrinsicInst {
+  public:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::vaend;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+
+    Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
+  };
+
+  /// VACopyInst - This represents the llvm.va_copy intrinsic.
+  ///
+  class VACopyInst : public IntrinsicInst {
+  public:
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::vacopy;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+
+    Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
+    Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); }
+  };
+
+}
+
+#endif
diff --git a/include/llvm/IR/Intrinsics.gen b/include/llvm/IR/Intrinsics.gen
new file mode 100644
index 0000000..a99da7a
--- /dev/null
+++ b/include/llvm/IR/Intrinsics.gen
@@ -0,0 +1,66682 @@
+/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
+|*                                                                            *|
+|*Intrinsic Function Source Fragment                                          *|
+|*                                                                            *|
+|* Automatically generated file, do not edit!                                 *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+// VisualStudio defines setjmp as _setjmp
+#if defined(_MSC_VER) && defined(setjmp) && \
+                         !defined(setjmp_undefined_for_msvc)
+#  pragma push_macro("setjmp")
+#  undef setjmp
+#  define setjmp_undefined_for_msvc
+#endif
+
+// Enum values for Intrinsics.h
+#ifdef GET_INTRINSIC_ENUM_VALUES
+    AMDGPU_div_fixup,                          // llvm.AMDGPU.div.fixup
+    AMDGPU_div_fmas,                           // llvm.AMDGPU.div.fmas
+    AMDGPU_div_scale,                          // llvm.AMDGPU.div.scale
+    AMDGPU_rcp,                                // llvm.AMDGPU.rcp
+    AMDGPU_rsq,                                // llvm.AMDGPU.rsq
+    AMDGPU_rsq_clamped,                        // llvm.AMDGPU.rsq.clamped
+    AMDGPU_trig_preop,                         // llvm.AMDGPU.trig.preop
+    aarch64_clrex,                             // llvm.aarch64.clrex
+    aarch64_crc32b,                            // llvm.aarch64.crc32b
+    aarch64_crc32cb,                           // llvm.aarch64.crc32cb
+    aarch64_crc32ch,                           // llvm.aarch64.crc32ch
+    aarch64_crc32cw,                           // llvm.aarch64.crc32cw
+    aarch64_crc32cx,                           // llvm.aarch64.crc32cx
+    aarch64_crc32h,                            // llvm.aarch64.crc32h
+    aarch64_crc32w,                            // llvm.aarch64.crc32w
+    aarch64_crc32x,                            // llvm.aarch64.crc32x
+    aarch64_crypto_aesd,                       // llvm.aarch64.crypto.aesd
+    aarch64_crypto_aese,                       // llvm.aarch64.crypto.aese
+    aarch64_crypto_aesimc,                     // llvm.aarch64.crypto.aesimc
+    aarch64_crypto_aesmc,                      // llvm.aarch64.crypto.aesmc
+    aarch64_crypto_sha1c,                      // llvm.aarch64.crypto.sha1c
+    aarch64_crypto_sha1h,                      // llvm.aarch64.crypto.sha1h
+    aarch64_crypto_sha1m,                      // llvm.aarch64.crypto.sha1m
+    aarch64_crypto_sha1p,                      // llvm.aarch64.crypto.sha1p
+    aarch64_crypto_sha1su0,                    // llvm.aarch64.crypto.sha1su0
+    aarch64_crypto_sha1su1,                    // llvm.aarch64.crypto.sha1su1
+    aarch64_crypto_sha256h,                    // llvm.aarch64.crypto.sha256h
+    aarch64_crypto_sha256h2,                   // llvm.aarch64.crypto.sha256h2
+    aarch64_crypto_sha256su0,                  // llvm.aarch64.crypto.sha256su0
+    aarch64_crypto_sha256su1,                  // llvm.aarch64.crypto.sha256su1
+    aarch64_dmb,                               // llvm.aarch64.dmb
+    aarch64_dsb,                               // llvm.aarch64.dsb
+    aarch64_hint,                              // llvm.aarch64.hint
+    aarch64_isb,                               // llvm.aarch64.isb
+    aarch64_ldaxp,                             // llvm.aarch64.ldaxp
+    aarch64_ldaxr,                             // llvm.aarch64.ldaxr
+    aarch64_ldxp,                              // llvm.aarch64.ldxp
+    aarch64_ldxr,                              // llvm.aarch64.ldxr
+    aarch64_neon_abs,                          // llvm.aarch64.neon.abs
+    aarch64_neon_addhn,                        // llvm.aarch64.neon.addhn
+    aarch64_neon_addp,                         // llvm.aarch64.neon.addp
+    aarch64_neon_cls,                          // llvm.aarch64.neon.cls
+    aarch64_neon_fabd,                         // llvm.aarch64.neon.fabd
+    aarch64_neon_facge,                        // llvm.aarch64.neon.facge
+    aarch64_neon_facgt,                        // llvm.aarch64.neon.facgt
+    aarch64_neon_faddv,                        // llvm.aarch64.neon.faddv
+    aarch64_neon_fcvtas,                       // llvm.aarch64.neon.fcvtas
+    aarch64_neon_fcvtau,                       // llvm.aarch64.neon.fcvtau
+    aarch64_neon_fcvtms,                       // llvm.aarch64.neon.fcvtms
+    aarch64_neon_fcvtmu,                       // llvm.aarch64.neon.fcvtmu
+    aarch64_neon_fcvtns,                       // llvm.aarch64.neon.fcvtns
+    aarch64_neon_fcvtnu,                       // llvm.aarch64.neon.fcvtnu
+    aarch64_neon_fcvtps,                       // llvm.aarch64.neon.fcvtps
+    aarch64_neon_fcvtpu,                       // llvm.aarch64.neon.fcvtpu
+    aarch64_neon_fcvtxn,                       // llvm.aarch64.neon.fcvtxn
+    aarch64_neon_fcvtzs,                       // llvm.aarch64.neon.fcvtzs
+    aarch64_neon_fcvtzu,                       // llvm.aarch64.neon.fcvtzu
+    aarch64_neon_fmax,                         // llvm.aarch64.neon.fmax
+    aarch64_neon_fmaxnm,                       // llvm.aarch64.neon.fmaxnm
+    aarch64_neon_fmaxnmp,                      // llvm.aarch64.neon.fmaxnmp
+    aarch64_neon_fmaxnmv,                      // llvm.aarch64.neon.fmaxnmv
+    aarch64_neon_fmaxp,                        // llvm.aarch64.neon.fmaxp
+    aarch64_neon_fmaxv,                        // llvm.aarch64.neon.fmaxv
+    aarch64_neon_fmin,                         // llvm.aarch64.neon.fmin
+    aarch64_neon_fminnm,                       // llvm.aarch64.neon.fminnm
+    aarch64_neon_fminnmp,                      // llvm.aarch64.neon.fminnmp
+    aarch64_neon_fminnmv,                      // llvm.aarch64.neon.fminnmv
+    aarch64_neon_fminp,                        // llvm.aarch64.neon.fminp
+    aarch64_neon_fminv,                        // llvm.aarch64.neon.fminv
+    aarch64_neon_fmulx,                        // llvm.aarch64.neon.fmulx
+    aarch64_neon_frecpe,                       // llvm.aarch64.neon.frecpe
+    aarch64_neon_frecps,                       // llvm.aarch64.neon.frecps
+    aarch64_neon_frecpx,                       // llvm.aarch64.neon.frecpx
+    aarch64_neon_frintn,                       // llvm.aarch64.neon.frintn
+    aarch64_neon_frsqrte,                      // llvm.aarch64.neon.frsqrte
+    aarch64_neon_frsqrts,                      // llvm.aarch64.neon.frsqrts
+    aarch64_neon_ld1x2,                        // llvm.aarch64.neon.ld1x2
+    aarch64_neon_ld1x3,                        // llvm.aarch64.neon.ld1x3
+    aarch64_neon_ld1x4,                        // llvm.aarch64.neon.ld1x4
+    aarch64_neon_ld2,                          // llvm.aarch64.neon.ld2
+    aarch64_neon_ld2lane,                      // llvm.aarch64.neon.ld2lane
+    aarch64_neon_ld2r,                         // llvm.aarch64.neon.ld2r
+    aarch64_neon_ld3,                          // llvm.aarch64.neon.ld3
+    aarch64_neon_ld3lane,                      // llvm.aarch64.neon.ld3lane
+    aarch64_neon_ld3r,                         // llvm.aarch64.neon.ld3r
+    aarch64_neon_ld4,                          // llvm.aarch64.neon.ld4
+    aarch64_neon_ld4lane,                      // llvm.aarch64.neon.ld4lane
+    aarch64_neon_ld4r,                         // llvm.aarch64.neon.ld4r
+    aarch64_neon_pmul,                         // llvm.aarch64.neon.pmul
+    aarch64_neon_pmull,                        // llvm.aarch64.neon.pmull
+    aarch64_neon_pmull64,                      // llvm.aarch64.neon.pmull64
+    aarch64_neon_raddhn,                       // llvm.aarch64.neon.raddhn
+    aarch64_neon_rbit,                         // llvm.aarch64.neon.rbit
+    aarch64_neon_rshrn,                        // llvm.aarch64.neon.rshrn
+    aarch64_neon_rsubhn,                       // llvm.aarch64.neon.rsubhn
+    aarch64_neon_sabd,                         // llvm.aarch64.neon.sabd
+    aarch64_neon_saddlp,                       // llvm.aarch64.neon.saddlp
+    aarch64_neon_saddlv,                       // llvm.aarch64.neon.saddlv
+    aarch64_neon_saddv,                        // llvm.aarch64.neon.saddv
+    aarch64_neon_scalar_sqxtn,                 // llvm.aarch64.neon.scalar.sqxtn
+    aarch64_neon_scalar_sqxtun,                // llvm.aarch64.neon.scalar.sqxtun
+    aarch64_neon_scalar_uqxtn,                 // llvm.aarch64.neon.scalar.uqxtn
+    aarch64_neon_shadd,                        // llvm.aarch64.neon.shadd
+    aarch64_neon_shll,                         // llvm.aarch64.neon.shll
+    aarch64_neon_shsub,                        // llvm.aarch64.neon.shsub
+    aarch64_neon_smax,                         // llvm.aarch64.neon.smax
+    aarch64_neon_smaxp,                        // llvm.aarch64.neon.smaxp
+    aarch64_neon_smaxv,                        // llvm.aarch64.neon.smaxv
+    aarch64_neon_smin,                         // llvm.aarch64.neon.smin
+    aarch64_neon_sminp,                        // llvm.aarch64.neon.sminp
+    aarch64_neon_sminv,                        // llvm.aarch64.neon.sminv
+    aarch64_neon_smull,                        // llvm.aarch64.neon.smull
+    aarch64_neon_sqabs,                        // llvm.aarch64.neon.sqabs
+    aarch64_neon_sqadd,                        // llvm.aarch64.neon.sqadd
+    aarch64_neon_sqdmulh,                      // llvm.aarch64.neon.sqdmulh
+    aarch64_neon_sqdmull,                      // llvm.aarch64.neon.sqdmull
+    aarch64_neon_sqdmulls_scalar,              // llvm.aarch64.neon.sqdmulls.scalar
+    aarch64_neon_sqneg,                        // llvm.aarch64.neon.sqneg
+    aarch64_neon_sqrdmulh,                     // llvm.aarch64.neon.sqrdmulh
+    aarch64_neon_sqrshl,                       // llvm.aarch64.neon.sqrshl
+    aarch64_neon_sqrshrn,                      // llvm.aarch64.neon.sqrshrn
+    aarch64_neon_sqrshrun,                     // llvm.aarch64.neon.sqrshrun
+    aarch64_neon_sqshl,                        // llvm.aarch64.neon.sqshl
+    aarch64_neon_sqshlu,                       // llvm.aarch64.neon.sqshlu
+    aarch64_neon_sqshrn,                       // llvm.aarch64.neon.sqshrn
+    aarch64_neon_sqshrun,                      // llvm.aarch64.neon.sqshrun
+    aarch64_neon_sqsub,                        // llvm.aarch64.neon.sqsub
+    aarch64_neon_sqxtn,                        // llvm.aarch64.neon.sqxtn
+    aarch64_neon_sqxtun,                       // llvm.aarch64.neon.sqxtun
+    aarch64_neon_srhadd,                       // llvm.aarch64.neon.srhadd
+    aarch64_neon_srshl,                        // llvm.aarch64.neon.srshl
+    aarch64_neon_sshl,                         // llvm.aarch64.neon.sshl
+    aarch64_neon_sshll,                        // llvm.aarch64.neon.sshll
+    aarch64_neon_st1x2,                        // llvm.aarch64.neon.st1x2
+    aarch64_neon_st1x3,                        // llvm.aarch64.neon.st1x3
+    aarch64_neon_st1x4,                        // llvm.aarch64.neon.st1x4
+    aarch64_neon_st2,                          // llvm.aarch64.neon.st2
+    aarch64_neon_st2lane,                      // llvm.aarch64.neon.st2lane
+    aarch64_neon_st3,                          // llvm.aarch64.neon.st3
+    aarch64_neon_st3lane,                      // llvm.aarch64.neon.st3lane
+    aarch64_neon_st4,                          // llvm.aarch64.neon.st4
+    aarch64_neon_st4lane,                      // llvm.aarch64.neon.st4lane
+    aarch64_neon_subhn,                        // llvm.aarch64.neon.subhn
+    aarch64_neon_suqadd,                       // llvm.aarch64.neon.suqadd
+    aarch64_neon_tbl1,                         // llvm.aarch64.neon.tbl1
+    aarch64_neon_tbl2,                         // llvm.aarch64.neon.tbl2
+    aarch64_neon_tbl3,                         // llvm.aarch64.neon.tbl3
+    aarch64_neon_tbl4,                         // llvm.aarch64.neon.tbl4
+    aarch64_neon_tbx1,                         // llvm.aarch64.neon.tbx1
+    aarch64_neon_tbx2,                         // llvm.aarch64.neon.tbx2
+    aarch64_neon_tbx3,                         // llvm.aarch64.neon.tbx3
+    aarch64_neon_tbx4,                         // llvm.aarch64.neon.tbx4
+    aarch64_neon_uabd,                         // llvm.aarch64.neon.uabd
+    aarch64_neon_uaddlp,                       // llvm.aarch64.neon.uaddlp
+    aarch64_neon_uaddlv,                       // llvm.aarch64.neon.uaddlv
+    aarch64_neon_uaddv,                        // llvm.aarch64.neon.uaddv
+    aarch64_neon_uhadd,                        // llvm.aarch64.neon.uhadd
+    aarch64_neon_uhsub,                        // llvm.aarch64.neon.uhsub
+    aarch64_neon_umax,                         // llvm.aarch64.neon.umax
+    aarch64_neon_umaxp,                        // llvm.aarch64.neon.umaxp
+    aarch64_neon_umaxv,                        // llvm.aarch64.neon.umaxv
+    aarch64_neon_umin,                         // llvm.aarch64.neon.umin
+    aarch64_neon_uminp,                        // llvm.aarch64.neon.uminp
+    aarch64_neon_uminv,                        // llvm.aarch64.neon.uminv
+    aarch64_neon_umull,                        // llvm.aarch64.neon.umull
+    aarch64_neon_uqadd,                        // llvm.aarch64.neon.uqadd
+    aarch64_neon_uqrshl,                       // llvm.aarch64.neon.uqrshl
+    aarch64_neon_uqrshrn,                      // llvm.aarch64.neon.uqrshrn
+    aarch64_neon_uqshl,                        // llvm.aarch64.neon.uqshl
+    aarch64_neon_uqshrn,                       // llvm.aarch64.neon.uqshrn
+    aarch64_neon_uqsub,                        // llvm.aarch64.neon.uqsub
+    aarch64_neon_uqxtn,                        // llvm.aarch64.neon.uqxtn
+    aarch64_neon_urecpe,                       // llvm.aarch64.neon.urecpe
+    aarch64_neon_urhadd,                       // llvm.aarch64.neon.urhadd
+    aarch64_neon_urshl,                        // llvm.aarch64.neon.urshl
+    aarch64_neon_ursqrte,                      // llvm.aarch64.neon.ursqrte
+    aarch64_neon_ushl,                         // llvm.aarch64.neon.ushl
+    aarch64_neon_ushll,                        // llvm.aarch64.neon.ushll
+    aarch64_neon_usqadd,                       // llvm.aarch64.neon.usqadd
+    aarch64_neon_vcopy_lane,                   // llvm.aarch64.neon.vcopy.lane
+    aarch64_neon_vcvtfp2fxs,                   // llvm.aarch64.neon.vcvtfp2fxs
+    aarch64_neon_vcvtfp2fxu,                   // llvm.aarch64.neon.vcvtfp2fxu
+    aarch64_neon_vcvtfp2hf,                    // llvm.aarch64.neon.vcvtfp2hf
+    aarch64_neon_vcvtfxs2fp,                   // llvm.aarch64.neon.vcvtfxs2fp
+    aarch64_neon_vcvtfxu2fp,                   // llvm.aarch64.neon.vcvtfxu2fp
+    aarch64_neon_vcvthf2fp,                    // llvm.aarch64.neon.vcvthf2fp
+    aarch64_neon_vsli,                         // llvm.aarch64.neon.vsli
+    aarch64_neon_vsri,                         // llvm.aarch64.neon.vsri
+    aarch64_rbit,                              // llvm.aarch64.rbit
+    aarch64_sdiv,                              // llvm.aarch64.sdiv
+    aarch64_sisd_fabd,                         // llvm.aarch64.sisd.fabd
+    aarch64_sisd_fcvtxn,                       // llvm.aarch64.sisd.fcvtxn
+    aarch64_stlxp,                             // llvm.aarch64.stlxp
+    aarch64_stlxr,                             // llvm.aarch64.stlxr
+    aarch64_stxp,                              // llvm.aarch64.stxp
+    aarch64_stxr,                              // llvm.aarch64.stxr
+    aarch64_udiv,                              // llvm.aarch64.udiv
+    adjust_trampoline,                         // llvm.adjust.trampoline
+    annotation,                                // llvm.annotation
+    arm_cdp,                                   // llvm.arm.cdp
+    arm_cdp2,                                  // llvm.arm.cdp2
+    arm_clrex,                                 // llvm.arm.clrex
+    arm_crc32b,                                // llvm.arm.crc32b
+    arm_crc32cb,                               // llvm.arm.crc32cb
+    arm_crc32ch,                               // llvm.arm.crc32ch
+    arm_crc32cw,                               // llvm.arm.crc32cw
+    arm_crc32h,                                // llvm.arm.crc32h
+    arm_crc32w,                                // llvm.arm.crc32w
+    arm_dmb,                                   // llvm.arm.dmb
+    arm_dsb,                                   // llvm.arm.dsb
+    arm_get_fpscr,                             // llvm.arm.get.fpscr
+    arm_hint,                                  // llvm.arm.hint
+    arm_isb,                                   // llvm.arm.isb
+    arm_ldaex,                                 // llvm.arm.ldaex
+    arm_ldaexd,                                // llvm.arm.ldaexd
+    arm_ldrex,                                 // llvm.arm.ldrex
+    arm_ldrexd,                                // llvm.arm.ldrexd
+    arm_mcr,                                   // llvm.arm.mcr
+    arm_mcr2,                                  // llvm.arm.mcr2
+    arm_mcrr,                                  // llvm.arm.mcrr
+    arm_mcrr2,                                 // llvm.arm.mcrr2
+    arm_mrc,                                   // llvm.arm.mrc
+    arm_mrc2,                                  // llvm.arm.mrc2
+    arm_neon_aesd,                             // llvm.arm.neon.aesd
+    arm_neon_aese,                             // llvm.arm.neon.aese
+    arm_neon_aesimc,                           // llvm.arm.neon.aesimc
+    arm_neon_aesmc,                            // llvm.arm.neon.aesmc
+    arm_neon_sha1c,                            // llvm.arm.neon.sha1c
+    arm_neon_sha1h,                            // llvm.arm.neon.sha1h
+    arm_neon_sha1m,                            // llvm.arm.neon.sha1m
+    arm_neon_sha1p,                            // llvm.arm.neon.sha1p
+    arm_neon_sha1su0,                          // llvm.arm.neon.sha1su0
+    arm_neon_sha1su1,                          // llvm.arm.neon.sha1su1
+    arm_neon_sha256h,                          // llvm.arm.neon.sha256h
+    arm_neon_sha256h2,                         // llvm.arm.neon.sha256h2
+    arm_neon_sha256su0,                        // llvm.arm.neon.sha256su0
+    arm_neon_sha256su1,                        // llvm.arm.neon.sha256su1
+    arm_neon_vabds,                            // llvm.arm.neon.vabds
+    arm_neon_vabdu,                            // llvm.arm.neon.vabdu
+    arm_neon_vabs,                             // llvm.arm.neon.vabs
+    arm_neon_vacge,                            // llvm.arm.neon.vacge
+    arm_neon_vacgt,                            // llvm.arm.neon.vacgt
+    arm_neon_vbsl,                             // llvm.arm.neon.vbsl
+    arm_neon_vcls,                             // llvm.arm.neon.vcls
+    arm_neon_vclz,                             // llvm.arm.neon.vclz
+    arm_neon_vcnt,                             // llvm.arm.neon.vcnt
+    arm_neon_vcvtas,                           // llvm.arm.neon.vcvtas
+    arm_neon_vcvtau,                           // llvm.arm.neon.vcvtau
+    arm_neon_vcvtfp2fxs,                       // llvm.arm.neon.vcvtfp2fxs
+    arm_neon_vcvtfp2fxu,                       // llvm.arm.neon.vcvtfp2fxu
+    arm_neon_vcvtfp2hf,                        // llvm.arm.neon.vcvtfp2hf
+    arm_neon_vcvtfxs2fp,                       // llvm.arm.neon.vcvtfxs2fp
+    arm_neon_vcvtfxu2fp,                       // llvm.arm.neon.vcvtfxu2fp
+    arm_neon_vcvthf2fp,                        // llvm.arm.neon.vcvthf2fp
+    arm_neon_vcvtms,                           // llvm.arm.neon.vcvtms
+    arm_neon_vcvtmu,                           // llvm.arm.neon.vcvtmu
+    arm_neon_vcvtns,                           // llvm.arm.neon.vcvtns
+    arm_neon_vcvtnu,                           // llvm.arm.neon.vcvtnu
+    arm_neon_vcvtps,                           // llvm.arm.neon.vcvtps
+    arm_neon_vcvtpu,                           // llvm.arm.neon.vcvtpu
+    arm_neon_vhadds,                           // llvm.arm.neon.vhadds
+    arm_neon_vhaddu,                           // llvm.arm.neon.vhaddu
+    arm_neon_vhsubs,                           // llvm.arm.neon.vhsubs
+    arm_neon_vhsubu,                           // llvm.arm.neon.vhsubu
+    arm_neon_vld1,                             // llvm.arm.neon.vld1
+    arm_neon_vld2,                             // llvm.arm.neon.vld2
+    arm_neon_vld2lane,                         // llvm.arm.neon.vld2lane
+    arm_neon_vld3,                             // llvm.arm.neon.vld3
+    arm_neon_vld3lane,                         // llvm.arm.neon.vld3lane
+    arm_neon_vld4,                             // llvm.arm.neon.vld4
+    arm_neon_vld4lane,                         // llvm.arm.neon.vld4lane
+    arm_neon_vmaxnm,                           // llvm.arm.neon.vmaxnm
+    arm_neon_vmaxs,                            // llvm.arm.neon.vmaxs
+    arm_neon_vmaxu,                            // llvm.arm.neon.vmaxu
+    arm_neon_vminnm,                           // llvm.arm.neon.vminnm
+    arm_neon_vmins,                            // llvm.arm.neon.vmins
+    arm_neon_vminu,                            // llvm.arm.neon.vminu
+    arm_neon_vmullp,                           // llvm.arm.neon.vmullp
+    arm_neon_vmulls,                           // llvm.arm.neon.vmulls
+    arm_neon_vmullu,                           // llvm.arm.neon.vmullu
+    arm_neon_vmulp,                            // llvm.arm.neon.vmulp
+    arm_neon_vpadals,                          // llvm.arm.neon.vpadals
+    arm_neon_vpadalu,                          // llvm.arm.neon.vpadalu
+    arm_neon_vpadd,                            // llvm.arm.neon.vpadd
+    arm_neon_vpaddls,                          // llvm.arm.neon.vpaddls
+    arm_neon_vpaddlu,                          // llvm.arm.neon.vpaddlu
+    arm_neon_vpmaxs,                           // llvm.arm.neon.vpmaxs
+    arm_neon_vpmaxu,                           // llvm.arm.neon.vpmaxu
+    arm_neon_vpmins,                           // llvm.arm.neon.vpmins
+    arm_neon_vpminu,                           // llvm.arm.neon.vpminu
+    arm_neon_vqabs,                            // llvm.arm.neon.vqabs
+    arm_neon_vqadds,                           // llvm.arm.neon.vqadds
+    arm_neon_vqaddu,                           // llvm.arm.neon.vqaddu
+    arm_neon_vqdmulh,                          // llvm.arm.neon.vqdmulh
+    arm_neon_vqdmull,                          // llvm.arm.neon.vqdmull
+    arm_neon_vqmovns,                          // llvm.arm.neon.vqmovns
+    arm_neon_vqmovnsu,                         // llvm.arm.neon.vqmovnsu
+    arm_neon_vqmovnu,                          // llvm.arm.neon.vqmovnu
+    arm_neon_vqneg,                            // llvm.arm.neon.vqneg
+    arm_neon_vqrdmulh,                         // llvm.arm.neon.vqrdmulh
+    arm_neon_vqrshiftns,                       // llvm.arm.neon.vqrshiftns
+    arm_neon_vqrshiftnsu,                      // llvm.arm.neon.vqrshiftnsu
+    arm_neon_vqrshiftnu,                       // llvm.arm.neon.vqrshiftnu
+    arm_neon_vqrshifts,                        // llvm.arm.neon.vqrshifts
+    arm_neon_vqrshiftu,                        // llvm.arm.neon.vqrshiftu
+    arm_neon_vqshiftns,                        // llvm.arm.neon.vqshiftns
+    arm_neon_vqshiftnsu,                       // llvm.arm.neon.vqshiftnsu
+    arm_neon_vqshiftnu,                        // llvm.arm.neon.vqshiftnu
+    arm_neon_vqshifts,                         // llvm.arm.neon.vqshifts
+    arm_neon_vqshiftsu,                        // llvm.arm.neon.vqshiftsu
+    arm_neon_vqshiftu,                         // llvm.arm.neon.vqshiftu
+    arm_neon_vqsubs,                           // llvm.arm.neon.vqsubs
+    arm_neon_vqsubu,                           // llvm.arm.neon.vqsubu
+    arm_neon_vraddhn,                          // llvm.arm.neon.vraddhn
+    arm_neon_vrecpe,                           // llvm.arm.neon.vrecpe
+    arm_neon_vrecps,                           // llvm.arm.neon.vrecps
+    arm_neon_vrhadds,                          // llvm.arm.neon.vrhadds
+    arm_neon_vrhaddu,                          // llvm.arm.neon.vrhaddu
+    arm_neon_vrinta,                           // llvm.arm.neon.vrinta
+    arm_neon_vrintm,                           // llvm.arm.neon.vrintm
+    arm_neon_vrintn,                           // llvm.arm.neon.vrintn
+    arm_neon_vrintp,                           // llvm.arm.neon.vrintp
+    arm_neon_vrintx,                           // llvm.arm.neon.vrintx
+    arm_neon_vrintz,                           // llvm.arm.neon.vrintz
+    arm_neon_vrshiftn,                         // llvm.arm.neon.vrshiftn
+    arm_neon_vrshifts,                         // llvm.arm.neon.vrshifts
+    arm_neon_vrshiftu,                         // llvm.arm.neon.vrshiftu
+    arm_neon_vrsqrte,                          // llvm.arm.neon.vrsqrte
+    arm_neon_vrsqrts,                          // llvm.arm.neon.vrsqrts
+    arm_neon_vrsubhn,                          // llvm.arm.neon.vrsubhn
+    arm_neon_vshiftins,                        // llvm.arm.neon.vshiftins
+    arm_neon_vshifts,                          // llvm.arm.neon.vshifts
+    arm_neon_vshiftu,                          // llvm.arm.neon.vshiftu
+    arm_neon_vst1,                             // llvm.arm.neon.vst1
+    arm_neon_vst2,                             // llvm.arm.neon.vst2
+    arm_neon_vst2lane,                         // llvm.arm.neon.vst2lane
+    arm_neon_vst3,                             // llvm.arm.neon.vst3
+    arm_neon_vst3lane,                         // llvm.arm.neon.vst3lane
+    arm_neon_vst4,                             // llvm.arm.neon.vst4
+    arm_neon_vst4lane,                         // llvm.arm.neon.vst4lane
+    arm_neon_vtbl1,                            // llvm.arm.neon.vtbl1
+    arm_neon_vtbl2,                            // llvm.arm.neon.vtbl2
+    arm_neon_vtbl3,                            // llvm.arm.neon.vtbl3
+    arm_neon_vtbl4,                            // llvm.arm.neon.vtbl4
+    arm_neon_vtbx1,                            // llvm.arm.neon.vtbx1
+    arm_neon_vtbx2,                            // llvm.arm.neon.vtbx2
+    arm_neon_vtbx3,                            // llvm.arm.neon.vtbx3
+    arm_neon_vtbx4,                            // llvm.arm.neon.vtbx4
+    arm_qadd,                                  // llvm.arm.qadd
+    arm_qsub,                                  // llvm.arm.qsub
+    arm_rbit,                                  // llvm.arm.rbit
+    arm_set_fpscr,                             // llvm.arm.set.fpscr
+    arm_ssat,                                  // llvm.arm.ssat
+    arm_stlex,                                 // llvm.arm.stlex
+    arm_stlexd,                                // llvm.arm.stlexd
+    arm_strex,                                 // llvm.arm.strex
+    arm_strexd,                                // llvm.arm.strexd
+    arm_thread_pointer,                        // llvm.arm.thread.pointer
+    arm_undefined,                             // llvm.arm.undefined
+    arm_usat,                                  // llvm.arm.usat
+    arm_vcvtr,                                 // llvm.arm.vcvtr
+    arm_vcvtru,                                // llvm.arm.vcvtru
+    bswap,                                     // llvm.bswap
+    ceil,                                      // llvm.ceil
+    clear_cache,                               // llvm.clear_cache
+    convert_from_fp16,                         // llvm.convert.from.fp16
+    convert_to_fp16,                           // llvm.convert.to.fp16
+    convertff,                                 // llvm.convertff
+    convertfsi,                                // llvm.convertfsi
+    convertfui,                                // llvm.convertfui
+    convertsif,                                // llvm.convertsif
+    convertss,                                 // llvm.convertss
+    convertsu,                                 // llvm.convertsu
+    convertuif,                                // llvm.convertuif
+    convertus,                                 // llvm.convertus
+    convertuu,                                 // llvm.convertuu
+    copysign,                                  // llvm.copysign
+    cos,                                       // llvm.cos
+    ctlz,                                      // llvm.ctlz
+    ctpop,                                     // llvm.ctpop
+    cttz,                                      // llvm.cttz
+    cuda_syncthreads,                          // llvm.cuda.syncthreads
+    dbg_declare,                               // llvm.dbg.declare
+    dbg_value,                                 // llvm.dbg.value
+    debugtrap,                                 // llvm.debugtrap
+    donothing,                                 // llvm.donothing
+    eh_dwarf_cfa,                              // llvm.eh.dwarf.cfa
+    eh_return_i32,                             // llvm.eh.return.i32
+    eh_return_i64,                             // llvm.eh.return.i64
+    eh_sjlj_callsite,                          // llvm.eh.sjlj.callsite
+    eh_sjlj_functioncontext,                   // llvm.eh.sjlj.functioncontext
+    eh_sjlj_longjmp,                           // llvm.eh.sjlj.longjmp
+    eh_sjlj_lsda,                              // llvm.eh.sjlj.lsda
+    eh_sjlj_setjmp,                            // llvm.eh.sjlj.setjmp
+    eh_typeid_for,                             // llvm.eh.typeid.for
+    eh_unwind_init,                            // llvm.eh.unwind.init
+    exp,                                       // llvm.exp
+    exp2,                                      // llvm.exp2
+    expect,                                    // llvm.expect
+    experimental_patchpoint_i64,               // llvm.experimental.patchpoint.i64
+    experimental_patchpoint_void,              // llvm.experimental.patchpoint.void
+    experimental_stackmap,                     // llvm.experimental.stackmap
+    fabs,                                      // llvm.fabs
+    floor,                                     // llvm.floor
+    flt_rounds,                                // llvm.flt.rounds
+    fma,                                       // llvm.fma
+    fmuladd,                                   // llvm.fmuladd
+    frameaddress,                              // llvm.frameaddress
+    gcread,                                    // llvm.gcread
+    gcroot,                                    // llvm.gcroot
+    gcwrite,                                   // llvm.gcwrite
+    hexagon_A2_abs,                            // llvm.hexagon.A2.abs
+    hexagon_A2_absp,                           // llvm.hexagon.A2.absp
+    hexagon_A2_abssat,                         // llvm.hexagon.A2.abssat
+    hexagon_A2_add,                            // llvm.hexagon.A2.add
+    hexagon_A2_addh_h16_hh,                    // llvm.hexagon.A2.addh.h16.hh
+    hexagon_A2_addh_h16_hl,                    // llvm.hexagon.A2.addh.h16.hl
+    hexagon_A2_addh_h16_lh,                    // llvm.hexagon.A2.addh.h16.lh
+    hexagon_A2_addh_h16_ll,                    // llvm.hexagon.A2.addh.h16.ll
+    hexagon_A2_addh_h16_sat_hh,                // llvm.hexagon.A2.addh.h16.sat.hh
+    hexagon_A2_addh_h16_sat_hl,                // llvm.hexagon.A2.addh.h16.sat.hl
+    hexagon_A2_addh_h16_sat_lh,                // llvm.hexagon.A2.addh.h16.sat.lh
+    hexagon_A2_addh_h16_sat_ll,                // llvm.hexagon.A2.addh.h16.sat.ll
+    hexagon_A2_addh_l16_hl,                    // llvm.hexagon.A2.addh.l16.hl
+    hexagon_A2_addh_l16_ll,                    // llvm.hexagon.A2.addh.l16.ll
+    hexagon_A2_addh_l16_sat_hl,                // llvm.hexagon.A2.addh.l16.sat.hl
+    hexagon_A2_addh_l16_sat_ll,                // llvm.hexagon.A2.addh.l16.sat.ll
+    hexagon_A2_addi,                           // llvm.hexagon.A2.addi
+    hexagon_A2_addp,                           // llvm.hexagon.A2.addp
+    hexagon_A2_addpsat,                        // llvm.hexagon.A2.addpsat
+    hexagon_A2_addsat,                         // llvm.hexagon.A2.addsat
+    hexagon_A2_addsp,                          // llvm.hexagon.A2.addsp
+    hexagon_A2_and,                            // llvm.hexagon.A2.and
+    hexagon_A2_andir,                          // llvm.hexagon.A2.andir
+    hexagon_A2_andp,                           // llvm.hexagon.A2.andp
+    hexagon_A2_aslh,                           // llvm.hexagon.A2.aslh
+    hexagon_A2_asrh,                           // llvm.hexagon.A2.asrh
+    hexagon_A2_combine_hh,                     // llvm.hexagon.A2.combine.hh
+    hexagon_A2_combine_hl,                     // llvm.hexagon.A2.combine.hl
+    hexagon_A2_combine_lh,                     // llvm.hexagon.A2.combine.lh
+    hexagon_A2_combine_ll,                     // llvm.hexagon.A2.combine.ll
+    hexagon_A2_combineii,                      // llvm.hexagon.A2.combineii
+    hexagon_A2_combinew,                       // llvm.hexagon.A2.combinew
+    hexagon_A2_max,                            // llvm.hexagon.A2.max
+    hexagon_A2_maxp,                           // llvm.hexagon.A2.maxp
+    hexagon_A2_maxu,                           // llvm.hexagon.A2.maxu
+    hexagon_A2_maxup,                          // llvm.hexagon.A2.maxup
+    hexagon_A2_min,                            // llvm.hexagon.A2.min
+    hexagon_A2_minp,                           // llvm.hexagon.A2.minp
+    hexagon_A2_minu,                           // llvm.hexagon.A2.minu
+    hexagon_A2_minup,                          // llvm.hexagon.A2.minup
+    hexagon_A2_neg,                            // llvm.hexagon.A2.neg
+    hexagon_A2_negp,                           // llvm.hexagon.A2.negp
+    hexagon_A2_negsat,                         // llvm.hexagon.A2.negsat
+    hexagon_A2_not,                            // llvm.hexagon.A2.not
+    hexagon_A2_notp,                           // llvm.hexagon.A2.notp
+    hexagon_A2_or,                             // llvm.hexagon.A2.or
+    hexagon_A2_orir,                           // llvm.hexagon.A2.orir
+    hexagon_A2_orp,                            // llvm.hexagon.A2.orp
+    hexagon_A2_roundsat,                       // llvm.hexagon.A2.roundsat
+    hexagon_A2_sat,                            // llvm.hexagon.A2.sat
+    hexagon_A2_satb,                           // llvm.hexagon.A2.satb
+    hexagon_A2_sath,                           // llvm.hexagon.A2.sath
+    hexagon_A2_satub,                          // llvm.hexagon.A2.satub
+    hexagon_A2_satuh,                          // llvm.hexagon.A2.satuh
+    hexagon_A2_sub,                            // llvm.hexagon.A2.sub
+    hexagon_A2_subh_h16_hh,                    // llvm.hexagon.A2.subh.h16.hh
+    hexagon_A2_subh_h16_hl,                    // llvm.hexagon.A2.subh.h16.hl
+    hexagon_A2_subh_h16_lh,                    // llvm.hexagon.A2.subh.h16.lh
+    hexagon_A2_subh_h16_ll,                    // llvm.hexagon.A2.subh.h16.ll
+    hexagon_A2_subh_h16_sat_hh,                // llvm.hexagon.A2.subh.h16.sat.hh
+    hexagon_A2_subh_h16_sat_hl,                // llvm.hexagon.A2.subh.h16.sat.hl
+    hexagon_A2_subh_h16_sat_lh,                // llvm.hexagon.A2.subh.h16.sat.lh
+    hexagon_A2_subh_h16_sat_ll,                // llvm.hexagon.A2.subh.h16.sat.ll
+    hexagon_A2_subh_l16_hl,                    // llvm.hexagon.A2.subh.l16.hl
+    hexagon_A2_subh_l16_ll,                    // llvm.hexagon.A2.subh.l16.ll
+    hexagon_A2_subh_l16_sat_hl,                // llvm.hexagon.A2.subh.l16.sat.hl
+    hexagon_A2_subh_l16_sat_ll,                // llvm.hexagon.A2.subh.l16.sat.ll
+    hexagon_A2_subp,                           // llvm.hexagon.A2.subp
+    hexagon_A2_subri,                          // llvm.hexagon.A2.subri
+    hexagon_A2_subsat,                         // llvm.hexagon.A2.subsat
+    hexagon_A2_svaddh,                         // llvm.hexagon.A2.svaddh
+    hexagon_A2_svaddhs,                        // llvm.hexagon.A2.svaddhs
+    hexagon_A2_svadduhs,                       // llvm.hexagon.A2.svadduhs
+    hexagon_A2_svavgh,                         // llvm.hexagon.A2.svavgh
+    hexagon_A2_svavghs,                        // llvm.hexagon.A2.svavghs
+    hexagon_A2_svnavgh,                        // llvm.hexagon.A2.svnavgh
+    hexagon_A2_svsubh,                         // llvm.hexagon.A2.svsubh
+    hexagon_A2_svsubhs,                        // llvm.hexagon.A2.svsubhs
+    hexagon_A2_svsubuhs,                       // llvm.hexagon.A2.svsubuhs
+    hexagon_A2_swiz,                           // llvm.hexagon.A2.swiz
+    hexagon_A2_sxtb,                           // llvm.hexagon.A2.sxtb
+    hexagon_A2_sxth,                           // llvm.hexagon.A2.sxth
+    hexagon_A2_sxtw,                           // llvm.hexagon.A2.sxtw
+    hexagon_A2_tfr,                            // llvm.hexagon.A2.tfr
+    hexagon_A2_tfrih,                          // llvm.hexagon.A2.tfrih
+    hexagon_A2_tfril,                          // llvm.hexagon.A2.tfril
+    hexagon_A2_tfrp,                           // llvm.hexagon.A2.tfrp
+    hexagon_A2_tfrpi,                          // llvm.hexagon.A2.tfrpi
+    hexagon_A2_tfrsi,                          // llvm.hexagon.A2.tfrsi
+    hexagon_A2_vabsh,                          // llvm.hexagon.A2.vabsh
+    hexagon_A2_vabshsat,                       // llvm.hexagon.A2.vabshsat
+    hexagon_A2_vabsw,                          // llvm.hexagon.A2.vabsw
+    hexagon_A2_vabswsat,                       // llvm.hexagon.A2.vabswsat
+    hexagon_A2_vaddb_map,                      // llvm.hexagon.A2.vaddb.map
+    hexagon_A2_vaddh,                          // llvm.hexagon.A2.vaddh
+    hexagon_A2_vaddhs,                         // llvm.hexagon.A2.vaddhs
+    hexagon_A2_vaddub,                         // llvm.hexagon.A2.vaddub
+    hexagon_A2_vaddubs,                        // llvm.hexagon.A2.vaddubs
+    hexagon_A2_vadduhs,                        // llvm.hexagon.A2.vadduhs
+    hexagon_A2_vaddw,                          // llvm.hexagon.A2.vaddw
+    hexagon_A2_vaddws,                         // llvm.hexagon.A2.vaddws
+    hexagon_A2_vavgh,                          // llvm.hexagon.A2.vavgh
+    hexagon_A2_vavghcr,                        // llvm.hexagon.A2.vavghcr
+    hexagon_A2_vavghr,                         // llvm.hexagon.A2.vavghr
+    hexagon_A2_vavgub,                         // llvm.hexagon.A2.vavgub
+    hexagon_A2_vavgubr,                        // llvm.hexagon.A2.vavgubr
+    hexagon_A2_vavguh,                         // llvm.hexagon.A2.vavguh
+    hexagon_A2_vavguhr,                        // llvm.hexagon.A2.vavguhr
+    hexagon_A2_vavguw,                         // llvm.hexagon.A2.vavguw
+    hexagon_A2_vavguwr,                        // llvm.hexagon.A2.vavguwr
+    hexagon_A2_vavgw,                          // llvm.hexagon.A2.vavgw
+    hexagon_A2_vavgwcr,                        // llvm.hexagon.A2.vavgwcr
+    hexagon_A2_vavgwr,                         // llvm.hexagon.A2.vavgwr
+    hexagon_A2_vcmpbeq,                        // llvm.hexagon.A2.vcmpbeq
+    hexagon_A2_vcmpbgtu,                       // llvm.hexagon.A2.vcmpbgtu
+    hexagon_A2_vcmpheq,                        // llvm.hexagon.A2.vcmpheq
+    hexagon_A2_vcmphgt,                        // llvm.hexagon.A2.vcmphgt
+    hexagon_A2_vcmphgtu,                       // llvm.hexagon.A2.vcmphgtu
+    hexagon_A2_vcmpweq,                        // llvm.hexagon.A2.vcmpweq
+    hexagon_A2_vcmpwgt,                        // llvm.hexagon.A2.vcmpwgt
+    hexagon_A2_vcmpwgtu,                       // llvm.hexagon.A2.vcmpwgtu
+    hexagon_A2_vconj,                          // llvm.hexagon.A2.vconj
+    hexagon_A2_vmaxb,                          // llvm.hexagon.A2.vmaxb
+    hexagon_A2_vmaxh,                          // llvm.hexagon.A2.vmaxh
+    hexagon_A2_vmaxub,                         // llvm.hexagon.A2.vmaxub
+    hexagon_A2_vmaxuh,                         // llvm.hexagon.A2.vmaxuh
+    hexagon_A2_vmaxuw,                         // llvm.hexagon.A2.vmaxuw
+    hexagon_A2_vmaxw,                          // llvm.hexagon.A2.vmaxw
+    hexagon_A2_vminb,                          // llvm.hexagon.A2.vminb
+    hexagon_A2_vminh,                          // llvm.hexagon.A2.vminh
+    hexagon_A2_vminub,                         // llvm.hexagon.A2.vminub
+    hexagon_A2_vminuh,                         // llvm.hexagon.A2.vminuh
+    hexagon_A2_vminuw,                         // llvm.hexagon.A2.vminuw
+    hexagon_A2_vminw,                          // llvm.hexagon.A2.vminw
+    hexagon_A2_vnavgh,                         // llvm.hexagon.A2.vnavgh
+    hexagon_A2_vnavghcr,                       // llvm.hexagon.A2.vnavghcr
+    hexagon_A2_vnavghr,                        // llvm.hexagon.A2.vnavghr
+    hexagon_A2_vnavgw,                         // llvm.hexagon.A2.vnavgw
+    hexagon_A2_vnavgwcr,                       // llvm.hexagon.A2.vnavgwcr
+    hexagon_A2_vnavgwr,                        // llvm.hexagon.A2.vnavgwr
+    hexagon_A2_vraddub,                        // llvm.hexagon.A2.vraddub
+    hexagon_A2_vraddub_acc,                    // llvm.hexagon.A2.vraddub.acc
+    hexagon_A2_vrsadub,                        // llvm.hexagon.A2.vrsadub
+    hexagon_A2_vrsadub_acc,                    // llvm.hexagon.A2.vrsadub.acc
+    hexagon_A2_vsubb_map,                      // llvm.hexagon.A2.vsubb.map
+    hexagon_A2_vsubh,                          // llvm.hexagon.A2.vsubh
+    hexagon_A2_vsubhs,                         // llvm.hexagon.A2.vsubhs
+    hexagon_A2_vsubub,                         // llvm.hexagon.A2.vsubub
+    hexagon_A2_vsububs,                        // llvm.hexagon.A2.vsububs
+    hexagon_A2_vsubuhs,                        // llvm.hexagon.A2.vsubuhs
+    hexagon_A2_vsubw,                          // llvm.hexagon.A2.vsubw
+    hexagon_A2_vsubws,                         // llvm.hexagon.A2.vsubws
+    hexagon_A2_xor,                            // llvm.hexagon.A2.xor
+    hexagon_A2_xorp,                           // llvm.hexagon.A2.xorp
+    hexagon_A2_zxtb,                           // llvm.hexagon.A2.zxtb
+    hexagon_A2_zxth,                           // llvm.hexagon.A2.zxth
+    hexagon_A4_andn,                           // llvm.hexagon.A4.andn
+    hexagon_A4_andnp,                          // llvm.hexagon.A4.andnp
+    hexagon_A4_bitsplit,                       // llvm.hexagon.A4.bitsplit
+    hexagon_A4_bitspliti,                      // llvm.hexagon.A4.bitspliti
+    hexagon_A4_boundscheck,                    // llvm.hexagon.A4.boundscheck
+    hexagon_A4_cmpbeq,                         // llvm.hexagon.A4.cmpbeq
+    hexagon_A4_cmpbeqi,                        // llvm.hexagon.A4.cmpbeqi
+    hexagon_A4_cmpbgt,                         // llvm.hexagon.A4.cmpbgt
+    hexagon_A4_cmpbgti,                        // llvm.hexagon.A4.cmpbgti
+    hexagon_A4_cmpbgtu,                        // llvm.hexagon.A4.cmpbgtu
+    hexagon_A4_cmpbgtui,                       // llvm.hexagon.A4.cmpbgtui
+    hexagon_A4_cmpheq,                         // llvm.hexagon.A4.cmpheq
+    hexagon_A4_cmpheqi,                        // llvm.hexagon.A4.cmpheqi
+    hexagon_A4_cmphgt,                         // llvm.hexagon.A4.cmphgt
+    hexagon_A4_cmphgti,                        // llvm.hexagon.A4.cmphgti
+    hexagon_A4_cmphgtu,                        // llvm.hexagon.A4.cmphgtu
+    hexagon_A4_cmphgtui,                       // llvm.hexagon.A4.cmphgtui
+    hexagon_A4_combineir,                      // llvm.hexagon.A4.combineir
+    hexagon_A4_combineri,                      // llvm.hexagon.A4.combineri
+    hexagon_A4_cround_ri,                      // llvm.hexagon.A4.cround.ri
+    hexagon_A4_cround_rr,                      // llvm.hexagon.A4.cround.rr
+    hexagon_A4_modwrapu,                       // llvm.hexagon.A4.modwrapu
+    hexagon_A4_orn,                            // llvm.hexagon.A4.orn
+    hexagon_A4_ornp,                           // llvm.hexagon.A4.ornp
+    hexagon_A4_rcmpeq,                         // llvm.hexagon.A4.rcmpeq
+    hexagon_A4_rcmpeqi,                        // llvm.hexagon.A4.rcmpeqi
+    hexagon_A4_rcmpneq,                        // llvm.hexagon.A4.rcmpneq
+    hexagon_A4_rcmpneqi,                       // llvm.hexagon.A4.rcmpneqi
+    hexagon_A4_round_ri,                       // llvm.hexagon.A4.round.ri
+    hexagon_A4_round_ri_sat,                   // llvm.hexagon.A4.round.ri.sat
+    hexagon_A4_round_rr,                       // llvm.hexagon.A4.round.rr
+    hexagon_A4_round_rr_sat,                   // llvm.hexagon.A4.round.rr.sat
+    hexagon_A4_tlbmatch,                       // llvm.hexagon.A4.tlbmatch
+    hexagon_A4_vcmpbeq_any,                    // llvm.hexagon.A4.vcmpbeq.any
+    hexagon_A4_vcmpbeqi,                       // llvm.hexagon.A4.vcmpbeqi
+    hexagon_A4_vcmpbgt,                        // llvm.hexagon.A4.vcmpbgt
+    hexagon_A4_vcmpbgti,                       // llvm.hexagon.A4.vcmpbgti
+    hexagon_A4_vcmpbgtui,                      // llvm.hexagon.A4.vcmpbgtui
+    hexagon_A4_vcmpheqi,                       // llvm.hexagon.A4.vcmpheqi
+    hexagon_A4_vcmphgti,                       // llvm.hexagon.A4.vcmphgti
+    hexagon_A4_vcmphgtui,                      // llvm.hexagon.A4.vcmphgtui
+    hexagon_A4_vcmpweqi,                       // llvm.hexagon.A4.vcmpweqi
+    hexagon_A4_vcmpwgti,                       // llvm.hexagon.A4.vcmpwgti
+    hexagon_A4_vcmpwgtui,                      // llvm.hexagon.A4.vcmpwgtui
+    hexagon_A4_vrmaxh,                         // llvm.hexagon.A4.vrmaxh
+    hexagon_A4_vrmaxuh,                        // llvm.hexagon.A4.vrmaxuh
+    hexagon_A4_vrmaxuw,                        // llvm.hexagon.A4.vrmaxuw
+    hexagon_A4_vrmaxw,                         // llvm.hexagon.A4.vrmaxw
+    hexagon_A4_vrminh,                         // llvm.hexagon.A4.vrminh
+    hexagon_A4_vrminuh,                        // llvm.hexagon.A4.vrminuh
+    hexagon_A4_vrminuw,                        // llvm.hexagon.A4.vrminuw
+    hexagon_A4_vrminw,                         // llvm.hexagon.A4.vrminw
+    hexagon_A5_vaddhubs,                       // llvm.hexagon.A5.vaddhubs
+    hexagon_C2_all8,                           // llvm.hexagon.C2.all8
+    hexagon_C2_and,                            // llvm.hexagon.C2.and
+    hexagon_C2_andn,                           // llvm.hexagon.C2.andn
+    hexagon_C2_any8,                           // llvm.hexagon.C2.any8
+    hexagon_C2_bitsclr,                        // llvm.hexagon.C2.bitsclr
+    hexagon_C2_bitsclri,                       // llvm.hexagon.C2.bitsclri
+    hexagon_C2_bitsset,                        // llvm.hexagon.C2.bitsset
+    hexagon_C2_cmpeq,                          // llvm.hexagon.C2.cmpeq
+    hexagon_C2_cmpeqi,                         // llvm.hexagon.C2.cmpeqi
+    hexagon_C2_cmpeqp,                         // llvm.hexagon.C2.cmpeqp
+    hexagon_C2_cmpgei,                         // llvm.hexagon.C2.cmpgei
+    hexagon_C2_cmpgeui,                        // llvm.hexagon.C2.cmpgeui
+    hexagon_C2_cmpgt,                          // llvm.hexagon.C2.cmpgt
+    hexagon_C2_cmpgti,                         // llvm.hexagon.C2.cmpgti
+    hexagon_C2_cmpgtp,                         // llvm.hexagon.C2.cmpgtp
+    hexagon_C2_cmpgtu,                         // llvm.hexagon.C2.cmpgtu
+    hexagon_C2_cmpgtui,                        // llvm.hexagon.C2.cmpgtui
+    hexagon_C2_cmpgtup,                        // llvm.hexagon.C2.cmpgtup
+    hexagon_C2_cmplt,                          // llvm.hexagon.C2.cmplt
+    hexagon_C2_cmpltu,                         // llvm.hexagon.C2.cmpltu
+    hexagon_C2_mask,                           // llvm.hexagon.C2.mask
+    hexagon_C2_mux,                            // llvm.hexagon.C2.mux
+    hexagon_C2_muxii,                          // llvm.hexagon.C2.muxii
+    hexagon_C2_muxir,                          // llvm.hexagon.C2.muxir
+    hexagon_C2_muxri,                          // llvm.hexagon.C2.muxri
+    hexagon_C2_not,                            // llvm.hexagon.C2.not
+    hexagon_C2_or,                             // llvm.hexagon.C2.or
+    hexagon_C2_orn,                            // llvm.hexagon.C2.orn
+    hexagon_C2_pxfer_map,                      // llvm.hexagon.C2.pxfer.map
+    hexagon_C2_tfrpr,                          // llvm.hexagon.C2.tfrpr
+    hexagon_C2_tfrrp,                          // llvm.hexagon.C2.tfrrp
+    hexagon_C2_vitpack,                        // llvm.hexagon.C2.vitpack
+    hexagon_C2_vmux,                           // llvm.hexagon.C2.vmux
+    hexagon_C2_xor,                            // llvm.hexagon.C2.xor
+    hexagon_C4_and_and,                        // llvm.hexagon.C4.and.and
+    hexagon_C4_and_andn,                       // llvm.hexagon.C4.and.andn
+    hexagon_C4_and_or,                         // llvm.hexagon.C4.and.or
+    hexagon_C4_and_orn,                        // llvm.hexagon.C4.and.orn
+    hexagon_C4_cmplte,                         // llvm.hexagon.C4.cmplte
+    hexagon_C4_cmpltei,                        // llvm.hexagon.C4.cmpltei
+    hexagon_C4_cmplteu,                        // llvm.hexagon.C4.cmplteu
+    hexagon_C4_cmplteui,                       // llvm.hexagon.C4.cmplteui
+    hexagon_C4_cmpneq,                         // llvm.hexagon.C4.cmpneq
+    hexagon_C4_cmpneqi,                        // llvm.hexagon.C4.cmpneqi
+    hexagon_C4_fastcorner9,                    // llvm.hexagon.C4.fastcorner9
+    hexagon_C4_fastcorner9_not,                // llvm.hexagon.C4.fastcorner9.not
+    hexagon_C4_nbitsclr,                       // llvm.hexagon.C4.nbitsclr
+    hexagon_C4_nbitsclri,                      // llvm.hexagon.C4.nbitsclri
+    hexagon_C4_nbitsset,                       // llvm.hexagon.C4.nbitsset
+    hexagon_C4_or_and,                         // llvm.hexagon.C4.or.and
+    hexagon_C4_or_andn,                        // llvm.hexagon.C4.or.andn
+    hexagon_C4_or_or,                          // llvm.hexagon.C4.or.or
+    hexagon_C4_or_orn,                         // llvm.hexagon.C4.or.orn
+    hexagon_F2_conv_d2df,                      // llvm.hexagon.F2.conv.d2df
+    hexagon_F2_conv_d2sf,                      // llvm.hexagon.F2.conv.d2sf
+    hexagon_F2_conv_df2d,                      // llvm.hexagon.F2.conv.df2d
+    hexagon_F2_conv_df2d_chop,                 // llvm.hexagon.F2.conv.df2d.chop
+    hexagon_F2_conv_df2sf,                     // llvm.hexagon.F2.conv.df2sf
+    hexagon_F2_conv_df2ud,                     // llvm.hexagon.F2.conv.df2ud
+    hexagon_F2_conv_df2ud_chop,                // llvm.hexagon.F2.conv.df2ud.chop
+    hexagon_F2_conv_df2uw,                     // llvm.hexagon.F2.conv.df2uw
+    hexagon_F2_conv_df2uw_chop,                // llvm.hexagon.F2.conv.df2uw.chop
+    hexagon_F2_conv_df2w,                      // llvm.hexagon.F2.conv.df2w
+    hexagon_F2_conv_df2w_chop,                 // llvm.hexagon.F2.conv.df2w.chop
+    hexagon_F2_conv_sf2d,                      // llvm.hexagon.F2.conv.sf2d
+    hexagon_F2_conv_sf2d_chop,                 // llvm.hexagon.F2.conv.sf2d.chop
+    hexagon_F2_conv_sf2df,                     // llvm.hexagon.F2.conv.sf2df
+    hexagon_F2_conv_sf2ud,                     // llvm.hexagon.F2.conv.sf2ud
+    hexagon_F2_conv_sf2ud_chop,                // llvm.hexagon.F2.conv.sf2ud.chop
+    hexagon_F2_conv_sf2uw,                     // llvm.hexagon.F2.conv.sf2uw
+    hexagon_F2_conv_sf2uw_chop,                // llvm.hexagon.F2.conv.sf2uw.chop
+    hexagon_F2_conv_sf2w,                      // llvm.hexagon.F2.conv.sf2w
+    hexagon_F2_conv_sf2w_chop,                 // llvm.hexagon.F2.conv.sf2w.chop
+    hexagon_F2_conv_ud2df,                     // llvm.hexagon.F2.conv.ud2df
+    hexagon_F2_conv_ud2sf,                     // llvm.hexagon.F2.conv.ud2sf
+    hexagon_F2_conv_uw2df,                     // llvm.hexagon.F2.conv.uw2df
+    hexagon_F2_conv_uw2sf,                     // llvm.hexagon.F2.conv.uw2sf
+    hexagon_F2_conv_w2df,                      // llvm.hexagon.F2.conv.w2df
+    hexagon_F2_conv_w2sf,                      // llvm.hexagon.F2.conv.w2sf
+    hexagon_F2_dfadd,                          // llvm.hexagon.F2.dfadd
+    hexagon_F2_dfclass,                        // llvm.hexagon.F2.dfclass
+    hexagon_F2_dfcmpeq,                        // llvm.hexagon.F2.dfcmpeq
+    hexagon_F2_dfcmpge,                        // llvm.hexagon.F2.dfcmpge
+    hexagon_F2_dfcmpgt,                        // llvm.hexagon.F2.dfcmpgt
+    hexagon_F2_dfcmpuo,                        // llvm.hexagon.F2.dfcmpuo
+    hexagon_F2_dffixupd,                       // llvm.hexagon.F2.dffixupd
+    hexagon_F2_dffixupn,                       // llvm.hexagon.F2.dffixupn
+    hexagon_F2_dffixupr,                       // llvm.hexagon.F2.dffixupr
+    hexagon_F2_dffma,                          // llvm.hexagon.F2.dffma
+    hexagon_F2_dffma_lib,                      // llvm.hexagon.F2.dffma.lib
+    hexagon_F2_dffma_sc,                       // llvm.hexagon.F2.dffma.sc
+    hexagon_F2_dffms,                          // llvm.hexagon.F2.dffms
+    hexagon_F2_dffms_lib,                      // llvm.hexagon.F2.dffms.lib
+    hexagon_F2_dfimm_n,                        // llvm.hexagon.F2.dfimm.n
+    hexagon_F2_dfimm_p,                        // llvm.hexagon.F2.dfimm.p
+    hexagon_F2_dfmax,                          // llvm.hexagon.F2.dfmax
+    hexagon_F2_dfmin,                          // llvm.hexagon.F2.dfmin
+    hexagon_F2_dfmpy,                          // llvm.hexagon.F2.dfmpy
+    hexagon_F2_dfsub,                          // llvm.hexagon.F2.dfsub
+    hexagon_F2_sfadd,                          // llvm.hexagon.F2.sfadd
+    hexagon_F2_sfclass,                        // llvm.hexagon.F2.sfclass
+    hexagon_F2_sfcmpeq,                        // llvm.hexagon.F2.sfcmpeq
+    hexagon_F2_sfcmpge,                        // llvm.hexagon.F2.sfcmpge
+    hexagon_F2_sfcmpgt,                        // llvm.hexagon.F2.sfcmpgt
+    hexagon_F2_sfcmpuo,                        // llvm.hexagon.F2.sfcmpuo
+    hexagon_F2_sffixupd,                       // llvm.hexagon.F2.sffixupd
+    hexagon_F2_sffixupn,                       // llvm.hexagon.F2.sffixupn
+    hexagon_F2_sffixupr,                       // llvm.hexagon.F2.sffixupr
+    hexagon_F2_sffma,                          // llvm.hexagon.F2.sffma
+    hexagon_F2_sffma_lib,                      // llvm.hexagon.F2.sffma.lib
+    hexagon_F2_sffma_sc,                       // llvm.hexagon.F2.sffma.sc
+    hexagon_F2_sffms,                          // llvm.hexagon.F2.sffms
+    hexagon_F2_sffms_lib,                      // llvm.hexagon.F2.sffms.lib
+    hexagon_F2_sfimm_n,                        // llvm.hexagon.F2.sfimm.n
+    hexagon_F2_sfimm_p,                        // llvm.hexagon.F2.sfimm.p
+    hexagon_F2_sfmax,                          // llvm.hexagon.F2.sfmax
+    hexagon_F2_sfmin,                          // llvm.hexagon.F2.sfmin
+    hexagon_F2_sfmpy,                          // llvm.hexagon.F2.sfmpy
+    hexagon_F2_sfsub,                          // llvm.hexagon.F2.sfsub
+    hexagon_M2_acci,                           // llvm.hexagon.M2.acci
+    hexagon_M2_accii,                          // llvm.hexagon.M2.accii
+    hexagon_M2_cmaci_s0,                       // llvm.hexagon.M2.cmaci.s0
+    hexagon_M2_cmacr_s0,                       // llvm.hexagon.M2.cmacr.s0
+    hexagon_M2_cmacs_s0,                       // llvm.hexagon.M2.cmacs.s0
+    hexagon_M2_cmacs_s1,                       // llvm.hexagon.M2.cmacs.s1
+    hexagon_M2_cmacsc_s0,                      // llvm.hexagon.M2.cmacsc.s0
+    hexagon_M2_cmacsc_s1,                      // llvm.hexagon.M2.cmacsc.s1
+    hexagon_M2_cmpyi_s0,                       // llvm.hexagon.M2.cmpyi.s0
+    hexagon_M2_cmpyr_s0,                       // llvm.hexagon.M2.cmpyr.s0
+    hexagon_M2_cmpyrs_s0,                      // llvm.hexagon.M2.cmpyrs.s0
+    hexagon_M2_cmpyrs_s1,                      // llvm.hexagon.M2.cmpyrs.s1
+    hexagon_M2_cmpyrsc_s0,                     // llvm.hexagon.M2.cmpyrsc.s0
+    hexagon_M2_cmpyrsc_s1,                     // llvm.hexagon.M2.cmpyrsc.s1
+    hexagon_M2_cmpys_s0,                       // llvm.hexagon.M2.cmpys.s0
+    hexagon_M2_cmpys_s1,                       // llvm.hexagon.M2.cmpys.s1
+    hexagon_M2_cmpysc_s0,                      // llvm.hexagon.M2.cmpysc.s0
+    hexagon_M2_cmpysc_s1,                      // llvm.hexagon.M2.cmpysc.s1
+    hexagon_M2_cnacs_s0,                       // llvm.hexagon.M2.cnacs.s0
+    hexagon_M2_cnacs_s1,                       // llvm.hexagon.M2.cnacs.s1
+    hexagon_M2_cnacsc_s0,                      // llvm.hexagon.M2.cnacsc.s0
+    hexagon_M2_cnacsc_s1,                      // llvm.hexagon.M2.cnacsc.s1
+    hexagon_M2_dpmpyss_acc_s0,                 // llvm.hexagon.M2.dpmpyss.acc.s0
+    hexagon_M2_dpmpyss_nac_s0,                 // llvm.hexagon.M2.dpmpyss.nac.s0
+    hexagon_M2_dpmpyss_rnd_s0,                 // llvm.hexagon.M2.dpmpyss.rnd.s0
+    hexagon_M2_dpmpyss_s0,                     // llvm.hexagon.M2.dpmpyss.s0
+    hexagon_M2_dpmpyuu_acc_s0,                 // llvm.hexagon.M2.dpmpyuu.acc.s0
+    hexagon_M2_dpmpyuu_nac_s0,                 // llvm.hexagon.M2.dpmpyuu.nac.s0
+    hexagon_M2_dpmpyuu_s0,                     // llvm.hexagon.M2.dpmpyuu.s0
+    hexagon_M2_hmmpyh_rs1,                     // llvm.hexagon.M2.hmmpyh.rs1
+    hexagon_M2_hmmpyh_s1,                      // llvm.hexagon.M2.hmmpyh.s1
+    hexagon_M2_hmmpyl_rs1,                     // llvm.hexagon.M2.hmmpyl.rs1
+    hexagon_M2_hmmpyl_s1,                      // llvm.hexagon.M2.hmmpyl.s1
+    hexagon_M2_maci,                           // llvm.hexagon.M2.maci
+    hexagon_M2_macsin,                         // llvm.hexagon.M2.macsin
+    hexagon_M2_macsip,                         // llvm.hexagon.M2.macsip
+    hexagon_M2_mmachs_rs0,                     // llvm.hexagon.M2.mmachs.rs0
+    hexagon_M2_mmachs_rs1,                     // llvm.hexagon.M2.mmachs.rs1
+    hexagon_M2_mmachs_s0,                      // llvm.hexagon.M2.mmachs.s0
+    hexagon_M2_mmachs_s1,                      // llvm.hexagon.M2.mmachs.s1
+    hexagon_M2_mmacls_rs0,                     // llvm.hexagon.M2.mmacls.rs0
+    hexagon_M2_mmacls_rs1,                     // llvm.hexagon.M2.mmacls.rs1
+    hexagon_M2_mmacls_s0,                      // llvm.hexagon.M2.mmacls.s0
+    hexagon_M2_mmacls_s1,                      // llvm.hexagon.M2.mmacls.s1
+    hexagon_M2_mmacuhs_rs0,                    // llvm.hexagon.M2.mmacuhs.rs0
+    hexagon_M2_mmacuhs_rs1,                    // llvm.hexagon.M2.mmacuhs.rs1
+    hexagon_M2_mmacuhs_s0,                     // llvm.hexagon.M2.mmacuhs.s0
+    hexagon_M2_mmacuhs_s1,                     // llvm.hexagon.M2.mmacuhs.s1
+    hexagon_M2_mmaculs_rs0,                    // llvm.hexagon.M2.mmaculs.rs0
+    hexagon_M2_mmaculs_rs1,                    // llvm.hexagon.M2.mmaculs.rs1
+    hexagon_M2_mmaculs_s0,                     // llvm.hexagon.M2.mmaculs.s0
+    hexagon_M2_mmaculs_s1,                     // llvm.hexagon.M2.mmaculs.s1
+    hexagon_M2_mmpyh_rs0,                      // llvm.hexagon.M2.mmpyh.rs0
+    hexagon_M2_mmpyh_rs1,                      // llvm.hexagon.M2.mmpyh.rs1
+    hexagon_M2_mmpyh_s0,                       // llvm.hexagon.M2.mmpyh.s0
+    hexagon_M2_mmpyh_s1,                       // llvm.hexagon.M2.mmpyh.s1
+    hexagon_M2_mmpyl_rs0,                      // llvm.hexagon.M2.mmpyl.rs0
+    hexagon_M2_mmpyl_rs1,                      // llvm.hexagon.M2.mmpyl.rs1
+    hexagon_M2_mmpyl_s0,                       // llvm.hexagon.M2.mmpyl.s0
+    hexagon_M2_mmpyl_s1,                       // llvm.hexagon.M2.mmpyl.s1
+    hexagon_M2_mmpyuh_rs0,                     // llvm.hexagon.M2.mmpyuh.rs0
+    hexagon_M2_mmpyuh_rs1,                     // llvm.hexagon.M2.mmpyuh.rs1
+    hexagon_M2_mmpyuh_s0,                      // llvm.hexagon.M2.mmpyuh.s0
+    hexagon_M2_mmpyuh_s1,                      // llvm.hexagon.M2.mmpyuh.s1
+    hexagon_M2_mmpyul_rs0,                     // llvm.hexagon.M2.mmpyul.rs0
+    hexagon_M2_mmpyul_rs1,                     // llvm.hexagon.M2.mmpyul.rs1
+    hexagon_M2_mmpyul_s0,                      // llvm.hexagon.M2.mmpyul.s0
+    hexagon_M2_mmpyul_s1,                      // llvm.hexagon.M2.mmpyul.s1
+    hexagon_M2_mpy_acc_hh_s0,                  // llvm.hexagon.M2.mpy.acc.hh.s0
+    hexagon_M2_mpy_acc_hh_s1,                  // llvm.hexagon.M2.mpy.acc.hh.s1
+    hexagon_M2_mpy_acc_hl_s0,                  // llvm.hexagon.M2.mpy.acc.hl.s0
+    hexagon_M2_mpy_acc_hl_s1,                  // llvm.hexagon.M2.mpy.acc.hl.s1
+    hexagon_M2_mpy_acc_lh_s0,                  // llvm.hexagon.M2.mpy.acc.lh.s0
+    hexagon_M2_mpy_acc_lh_s1,                  // llvm.hexagon.M2.mpy.acc.lh.s1
+    hexagon_M2_mpy_acc_ll_s0,                  // llvm.hexagon.M2.mpy.acc.ll.s0
+    hexagon_M2_mpy_acc_ll_s1,                  // llvm.hexagon.M2.mpy.acc.ll.s1
+    hexagon_M2_mpy_acc_sat_hh_s0,              // llvm.hexagon.M2.mpy.acc.sat.hh.s0
+    hexagon_M2_mpy_acc_sat_hh_s1,              // llvm.hexagon.M2.mpy.acc.sat.hh.s1
+    hexagon_M2_mpy_acc_sat_hl_s0,              // llvm.hexagon.M2.mpy.acc.sat.hl.s0
+    hexagon_M2_mpy_acc_sat_hl_s1,              // llvm.hexagon.M2.mpy.acc.sat.hl.s1
+    hexagon_M2_mpy_acc_sat_lh_s0,              // llvm.hexagon.M2.mpy.acc.sat.lh.s0
+    hexagon_M2_mpy_acc_sat_lh_s1,              // llvm.hexagon.M2.mpy.acc.sat.lh.s1
+    hexagon_M2_mpy_acc_sat_ll_s0,              // llvm.hexagon.M2.mpy.acc.sat.ll.s0
+    hexagon_M2_mpy_acc_sat_ll_s1,              // llvm.hexagon.M2.mpy.acc.sat.ll.s1
+    hexagon_M2_mpy_hh_s0,                      // llvm.hexagon.M2.mpy.hh.s0
+    hexagon_M2_mpy_hh_s1,                      // llvm.hexagon.M2.mpy.hh.s1
+    hexagon_M2_mpy_hl_s0,                      // llvm.hexagon.M2.mpy.hl.s0
+    hexagon_M2_mpy_hl_s1,                      // llvm.hexagon.M2.mpy.hl.s1
+    hexagon_M2_mpy_lh_s0,                      // llvm.hexagon.M2.mpy.lh.s0
+    hexagon_M2_mpy_lh_s1,                      // llvm.hexagon.M2.mpy.lh.s1
+    hexagon_M2_mpy_ll_s0,                      // llvm.hexagon.M2.mpy.ll.s0
+    hexagon_M2_mpy_ll_s1,                      // llvm.hexagon.M2.mpy.ll.s1
+    hexagon_M2_mpy_nac_hh_s0,                  // llvm.hexagon.M2.mpy.nac.hh.s0
+    hexagon_M2_mpy_nac_hh_s1,                  // llvm.hexagon.M2.mpy.nac.hh.s1
+    hexagon_M2_mpy_nac_hl_s0,                  // llvm.hexagon.M2.mpy.nac.hl.s0
+    hexagon_M2_mpy_nac_hl_s1,                  // llvm.hexagon.M2.mpy.nac.hl.s1
+    hexagon_M2_mpy_nac_lh_s0,                  // llvm.hexagon.M2.mpy.nac.lh.s0
+    hexagon_M2_mpy_nac_lh_s1,                  // llvm.hexagon.M2.mpy.nac.lh.s1
+    hexagon_M2_mpy_nac_ll_s0,                  // llvm.hexagon.M2.mpy.nac.ll.s0
+    hexagon_M2_mpy_nac_ll_s1,                  // llvm.hexagon.M2.mpy.nac.ll.s1
+    hexagon_M2_mpy_nac_sat_hh_s0,              // llvm.hexagon.M2.mpy.nac.sat.hh.s0
+    hexagon_M2_mpy_nac_sat_hh_s1,              // llvm.hexagon.M2.mpy.nac.sat.hh.s1
+    hexagon_M2_mpy_nac_sat_hl_s0,              // llvm.hexagon.M2.mpy.nac.sat.hl.s0
+    hexagon_M2_mpy_nac_sat_hl_s1,              // llvm.hexagon.M2.mpy.nac.sat.hl.s1
+    hexagon_M2_mpy_nac_sat_lh_s0,              // llvm.hexagon.M2.mpy.nac.sat.lh.s0
+    hexagon_M2_mpy_nac_sat_lh_s1,              // llvm.hexagon.M2.mpy.nac.sat.lh.s1
+    hexagon_M2_mpy_nac_sat_ll_s0,              // llvm.hexagon.M2.mpy.nac.sat.ll.s0
+    hexagon_M2_mpy_nac_sat_ll_s1,              // llvm.hexagon.M2.mpy.nac.sat.ll.s1
+    hexagon_M2_mpy_rnd_hh_s0,                  // llvm.hexagon.M2.mpy.rnd.hh.s0
+    hexagon_M2_mpy_rnd_hh_s1,                  // llvm.hexagon.M2.mpy.rnd.hh.s1
+    hexagon_M2_mpy_rnd_hl_s0,                  // llvm.hexagon.M2.mpy.rnd.hl.s0
+    hexagon_M2_mpy_rnd_hl_s1,                  // llvm.hexagon.M2.mpy.rnd.hl.s1
+    hexagon_M2_mpy_rnd_lh_s0,                  // llvm.hexagon.M2.mpy.rnd.lh.s0
+    hexagon_M2_mpy_rnd_lh_s1,                  // llvm.hexagon.M2.mpy.rnd.lh.s1
+    hexagon_M2_mpy_rnd_ll_s0,                  // llvm.hexagon.M2.mpy.rnd.ll.s0
+    hexagon_M2_mpy_rnd_ll_s1,                  // llvm.hexagon.M2.mpy.rnd.ll.s1
+    hexagon_M2_mpy_sat_hh_s0,                  // llvm.hexagon.M2.mpy.sat.hh.s0
+    hexagon_M2_mpy_sat_hh_s1,                  // llvm.hexagon.M2.mpy.sat.hh.s1
+    hexagon_M2_mpy_sat_hl_s0,                  // llvm.hexagon.M2.mpy.sat.hl.s0
+    hexagon_M2_mpy_sat_hl_s1,                  // llvm.hexagon.M2.mpy.sat.hl.s1
+    hexagon_M2_mpy_sat_lh_s0,                  // llvm.hexagon.M2.mpy.sat.lh.s0
+    hexagon_M2_mpy_sat_lh_s1,                  // llvm.hexagon.M2.mpy.sat.lh.s1
+    hexagon_M2_mpy_sat_ll_s0,                  // llvm.hexagon.M2.mpy.sat.ll.s0
+    hexagon_M2_mpy_sat_ll_s1,                  // llvm.hexagon.M2.mpy.sat.ll.s1
+    hexagon_M2_mpy_sat_rnd_hh_s0,              // llvm.hexagon.M2.mpy.sat.rnd.hh.s0
+    hexagon_M2_mpy_sat_rnd_hh_s1,              // llvm.hexagon.M2.mpy.sat.rnd.hh.s1
+    hexagon_M2_mpy_sat_rnd_hl_s0,              // llvm.hexagon.M2.mpy.sat.rnd.hl.s0
+    hexagon_M2_mpy_sat_rnd_hl_s1,              // llvm.hexagon.M2.mpy.sat.rnd.hl.s1
+    hexagon_M2_mpy_sat_rnd_lh_s0,              // llvm.hexagon.M2.mpy.sat.rnd.lh.s0
+    hexagon_M2_mpy_sat_rnd_lh_s1,              // llvm.hexagon.M2.mpy.sat.rnd.lh.s1
+    hexagon_M2_mpy_sat_rnd_ll_s0,              // llvm.hexagon.M2.mpy.sat.rnd.ll.s0
+    hexagon_M2_mpy_sat_rnd_ll_s1,              // llvm.hexagon.M2.mpy.sat.rnd.ll.s1
+    hexagon_M2_mpy_up,                         // llvm.hexagon.M2.mpy.up
+    hexagon_M2_mpy_up_s1,                      // llvm.hexagon.M2.mpy.up.s1
+    hexagon_M2_mpy_up_s1_sat,                  // llvm.hexagon.M2.mpy.up.s1.sat
+    hexagon_M2_mpyd_acc_hh_s0,                 // llvm.hexagon.M2.mpyd.acc.hh.s0
+    hexagon_M2_mpyd_acc_hh_s1,                 // llvm.hexagon.M2.mpyd.acc.hh.s1
+    hexagon_M2_mpyd_acc_hl_s0,                 // llvm.hexagon.M2.mpyd.acc.hl.s0
+    hexagon_M2_mpyd_acc_hl_s1,                 // llvm.hexagon.M2.mpyd.acc.hl.s1
+    hexagon_M2_mpyd_acc_lh_s0,                 // llvm.hexagon.M2.mpyd.acc.lh.s0
+    hexagon_M2_mpyd_acc_lh_s1,                 // llvm.hexagon.M2.mpyd.acc.lh.s1
+    hexagon_M2_mpyd_acc_ll_s0,                 // llvm.hexagon.M2.mpyd.acc.ll.s0
+    hexagon_M2_mpyd_acc_ll_s1,                 // llvm.hexagon.M2.mpyd.acc.ll.s1
+    hexagon_M2_mpyd_hh_s0,                     // llvm.hexagon.M2.mpyd.hh.s0
+    hexagon_M2_mpyd_hh_s1,                     // llvm.hexagon.M2.mpyd.hh.s1
+    hexagon_M2_mpyd_hl_s0,                     // llvm.hexagon.M2.mpyd.hl.s0
+    hexagon_M2_mpyd_hl_s1,                     // llvm.hexagon.M2.mpyd.hl.s1
+    hexagon_M2_mpyd_lh_s0,                     // llvm.hexagon.M2.mpyd.lh.s0
+    hexagon_M2_mpyd_lh_s1,                     // llvm.hexagon.M2.mpyd.lh.s1
+    hexagon_M2_mpyd_ll_s0,                     // llvm.hexagon.M2.mpyd.ll.s0
+    hexagon_M2_mpyd_ll_s1,                     // llvm.hexagon.M2.mpyd.ll.s1
+    hexagon_M2_mpyd_nac_hh_s0,                 // llvm.hexagon.M2.mpyd.nac.hh.s0
+    hexagon_M2_mpyd_nac_hh_s1,                 // llvm.hexagon.M2.mpyd.nac.hh.s1
+    hexagon_M2_mpyd_nac_hl_s0,                 // llvm.hexagon.M2.mpyd.nac.hl.s0
+    hexagon_M2_mpyd_nac_hl_s1,                 // llvm.hexagon.M2.mpyd.nac.hl.s1
+    hexagon_M2_mpyd_nac_lh_s0,                 // llvm.hexagon.M2.mpyd.nac.lh.s0
+    hexagon_M2_mpyd_nac_lh_s1,                 // llvm.hexagon.M2.mpyd.nac.lh.s1
+    hexagon_M2_mpyd_nac_ll_s0,                 // llvm.hexagon.M2.mpyd.nac.ll.s0
+    hexagon_M2_mpyd_nac_ll_s1,                 // llvm.hexagon.M2.mpyd.nac.ll.s1
+    hexagon_M2_mpyd_rnd_hh_s0,                 // llvm.hexagon.M2.mpyd.rnd.hh.s0
+    hexagon_M2_mpyd_rnd_hh_s1,                 // llvm.hexagon.M2.mpyd.rnd.hh.s1
+    hexagon_M2_mpyd_rnd_hl_s0,                 // llvm.hexagon.M2.mpyd.rnd.hl.s0
+    hexagon_M2_mpyd_rnd_hl_s1,                 // llvm.hexagon.M2.mpyd.rnd.hl.s1
+    hexagon_M2_mpyd_rnd_lh_s0,                 // llvm.hexagon.M2.mpyd.rnd.lh.s0
+    hexagon_M2_mpyd_rnd_lh_s1,                 // llvm.hexagon.M2.mpyd.rnd.lh.s1
+    hexagon_M2_mpyd_rnd_ll_s0,                 // llvm.hexagon.M2.mpyd.rnd.ll.s0
+    hexagon_M2_mpyd_rnd_ll_s1,                 // llvm.hexagon.M2.mpyd.rnd.ll.s1
+    hexagon_M2_mpyi,                           // llvm.hexagon.M2.mpyi
+    hexagon_M2_mpysmi,                         // llvm.hexagon.M2.mpysmi
+    hexagon_M2_mpysu_up,                       // llvm.hexagon.M2.mpysu.up
+    hexagon_M2_mpyu_acc_hh_s0,                 // llvm.hexagon.M2.mpyu.acc.hh.s0
+    hexagon_M2_mpyu_acc_hh_s1,                 // llvm.hexagon.M2.mpyu.acc.hh.s1
+    hexagon_M2_mpyu_acc_hl_s0,                 // llvm.hexagon.M2.mpyu.acc.hl.s0
+    hexagon_M2_mpyu_acc_hl_s1,                 // llvm.hexagon.M2.mpyu.acc.hl.s1
+    hexagon_M2_mpyu_acc_lh_s0,                 // llvm.hexagon.M2.mpyu.acc.lh.s0
+    hexagon_M2_mpyu_acc_lh_s1,                 // llvm.hexagon.M2.mpyu.acc.lh.s1
+    hexagon_M2_mpyu_acc_ll_s0,                 // llvm.hexagon.M2.mpyu.acc.ll.s0
+    hexagon_M2_mpyu_acc_ll_s1,                 // llvm.hexagon.M2.mpyu.acc.ll.s1
+    hexagon_M2_mpyu_hh_s0,                     // llvm.hexagon.M2.mpyu.hh.s0
+    hexagon_M2_mpyu_hh_s1,                     // llvm.hexagon.M2.mpyu.hh.s1
+    hexagon_M2_mpyu_hl_s0,                     // llvm.hexagon.M2.mpyu.hl.s0
+    hexagon_M2_mpyu_hl_s1,                     // llvm.hexagon.M2.mpyu.hl.s1
+    hexagon_M2_mpyu_lh_s0,                     // llvm.hexagon.M2.mpyu.lh.s0
+    hexagon_M2_mpyu_lh_s1,                     // llvm.hexagon.M2.mpyu.lh.s1
+    hexagon_M2_mpyu_ll_s0,                     // llvm.hexagon.M2.mpyu.ll.s0
+    hexagon_M2_mpyu_ll_s1,                     // llvm.hexagon.M2.mpyu.ll.s1
+    hexagon_M2_mpyu_nac_hh_s0,                 // llvm.hexagon.M2.mpyu.nac.hh.s0
+    hexagon_M2_mpyu_nac_hh_s1,                 // llvm.hexagon.M2.mpyu.nac.hh.s1
+    hexagon_M2_mpyu_nac_hl_s0,                 // llvm.hexagon.M2.mpyu.nac.hl.s0
+    hexagon_M2_mpyu_nac_hl_s1,                 // llvm.hexagon.M2.mpyu.nac.hl.s1
+    hexagon_M2_mpyu_nac_lh_s0,                 // llvm.hexagon.M2.mpyu.nac.lh.s0
+    hexagon_M2_mpyu_nac_lh_s1,                 // llvm.hexagon.M2.mpyu.nac.lh.s1
+    hexagon_M2_mpyu_nac_ll_s0,                 // llvm.hexagon.M2.mpyu.nac.ll.s0
+    hexagon_M2_mpyu_nac_ll_s1,                 // llvm.hexagon.M2.mpyu.nac.ll.s1
+    hexagon_M2_mpyu_up,                        // llvm.hexagon.M2.mpyu.up
+    hexagon_M2_mpyud_acc_hh_s0,                // llvm.hexagon.M2.mpyud.acc.hh.s0
+    hexagon_M2_mpyud_acc_hh_s1,                // llvm.hexagon.M2.mpyud.acc.hh.s1
+    hexagon_M2_mpyud_acc_hl_s0,                // llvm.hexagon.M2.mpyud.acc.hl.s0
+    hexagon_M2_mpyud_acc_hl_s1,                // llvm.hexagon.M2.mpyud.acc.hl.s1
+    hexagon_M2_mpyud_acc_lh_s0,                // llvm.hexagon.M2.mpyud.acc.lh.s0
+    hexagon_M2_mpyud_acc_lh_s1,                // llvm.hexagon.M2.mpyud.acc.lh.s1
+    hexagon_M2_mpyud_acc_ll_s0,                // llvm.hexagon.M2.mpyud.acc.ll.s0
+    hexagon_M2_mpyud_acc_ll_s1,                // llvm.hexagon.M2.mpyud.acc.ll.s1
+    hexagon_M2_mpyud_hh_s0,                    // llvm.hexagon.M2.mpyud.hh.s0
+    hexagon_M2_mpyud_hh_s1,                    // llvm.hexagon.M2.mpyud.hh.s1
+    hexagon_M2_mpyud_hl_s0,                    // llvm.hexagon.M2.mpyud.hl.s0
+    hexagon_M2_mpyud_hl_s1,                    // llvm.hexagon.M2.mpyud.hl.s1
+    hexagon_M2_mpyud_lh_s0,                    // llvm.hexagon.M2.mpyud.lh.s0
+    hexagon_M2_mpyud_lh_s1,                    // llvm.hexagon.M2.mpyud.lh.s1
+    hexagon_M2_mpyud_ll_s0,                    // llvm.hexagon.M2.mpyud.ll.s0
+    hexagon_M2_mpyud_ll_s1,                    // llvm.hexagon.M2.mpyud.ll.s1
+    hexagon_M2_mpyud_nac_hh_s0,                // llvm.hexagon.M2.mpyud.nac.hh.s0
+    hexagon_M2_mpyud_nac_hh_s1,                // llvm.hexagon.M2.mpyud.nac.hh.s1
+    hexagon_M2_mpyud_nac_hl_s0,                // llvm.hexagon.M2.mpyud.nac.hl.s0
+    hexagon_M2_mpyud_nac_hl_s1,                // llvm.hexagon.M2.mpyud.nac.hl.s1
+    hexagon_M2_mpyud_nac_lh_s0,                // llvm.hexagon.M2.mpyud.nac.lh.s0
+    hexagon_M2_mpyud_nac_lh_s1,                // llvm.hexagon.M2.mpyud.nac.lh.s1
+    hexagon_M2_mpyud_nac_ll_s0,                // llvm.hexagon.M2.mpyud.nac.ll.s0
+    hexagon_M2_mpyud_nac_ll_s1,                // llvm.hexagon.M2.mpyud.nac.ll.s1
+    hexagon_M2_mpyui,                          // llvm.hexagon.M2.mpyui
+    hexagon_M2_nacci,                          // llvm.hexagon.M2.nacci
+    hexagon_M2_naccii,                         // llvm.hexagon.M2.naccii
+    hexagon_M2_subacc,                         // llvm.hexagon.M2.subacc
+    hexagon_M2_vabsdiffh,                      // llvm.hexagon.M2.vabsdiffh
+    hexagon_M2_vabsdiffw,                      // llvm.hexagon.M2.vabsdiffw
+    hexagon_M2_vcmac_s0_sat_i,                 // llvm.hexagon.M2.vcmac.s0.sat.i
+    hexagon_M2_vcmac_s0_sat_r,                 // llvm.hexagon.M2.vcmac.s0.sat.r
+    hexagon_M2_vcmpy_s0_sat_i,                 // llvm.hexagon.M2.vcmpy.s0.sat.i
+    hexagon_M2_vcmpy_s0_sat_r,                 // llvm.hexagon.M2.vcmpy.s0.sat.r
+    hexagon_M2_vcmpy_s1_sat_i,                 // llvm.hexagon.M2.vcmpy.s1.sat.i
+    hexagon_M2_vcmpy_s1_sat_r,                 // llvm.hexagon.M2.vcmpy.s1.sat.r
+    hexagon_M2_vdmacs_s0,                      // llvm.hexagon.M2.vdmacs.s0
+    hexagon_M2_vdmacs_s1,                      // llvm.hexagon.M2.vdmacs.s1
+    hexagon_M2_vdmpyrs_s0,                     // llvm.hexagon.M2.vdmpyrs.s0
+    hexagon_M2_vdmpyrs_s1,                     // llvm.hexagon.M2.vdmpyrs.s1
+    hexagon_M2_vdmpys_s0,                      // llvm.hexagon.M2.vdmpys.s0
+    hexagon_M2_vdmpys_s1,                      // llvm.hexagon.M2.vdmpys.s1
+    hexagon_M2_vmac2,                          // llvm.hexagon.M2.vmac2
+    hexagon_M2_vmac2es,                        // llvm.hexagon.M2.vmac2es
+    hexagon_M2_vmac2es_s0,                     // llvm.hexagon.M2.vmac2es.s0
+    hexagon_M2_vmac2es_s1,                     // llvm.hexagon.M2.vmac2es.s1
+    hexagon_M2_vmac2s_s0,                      // llvm.hexagon.M2.vmac2s.s0
+    hexagon_M2_vmac2s_s1,                      // llvm.hexagon.M2.vmac2s.s1
+    hexagon_M2_vmac2su_s0,                     // llvm.hexagon.M2.vmac2su.s0
+    hexagon_M2_vmac2su_s1,                     // llvm.hexagon.M2.vmac2su.s1
+    hexagon_M2_vmpy2es_s0,                     // llvm.hexagon.M2.vmpy2es.s0
+    hexagon_M2_vmpy2es_s1,                     // llvm.hexagon.M2.vmpy2es.s1
+    hexagon_M2_vmpy2s_s0,                      // llvm.hexagon.M2.vmpy2s.s0
+    hexagon_M2_vmpy2s_s0pack,                  // llvm.hexagon.M2.vmpy2s.s0pack
+    hexagon_M2_vmpy2s_s1,                      // llvm.hexagon.M2.vmpy2s.s1
+    hexagon_M2_vmpy2s_s1pack,                  // llvm.hexagon.M2.vmpy2s.s1pack
+    hexagon_M2_vmpy2su_s0,                     // llvm.hexagon.M2.vmpy2su.s0
+    hexagon_M2_vmpy2su_s1,                     // llvm.hexagon.M2.vmpy2su.s1
+    hexagon_M2_vraddh,                         // llvm.hexagon.M2.vraddh
+    hexagon_M2_vradduh,                        // llvm.hexagon.M2.vradduh
+    hexagon_M2_vrcmaci_s0,                     // llvm.hexagon.M2.vrcmaci.s0
+    hexagon_M2_vrcmaci_s0c,                    // llvm.hexagon.M2.vrcmaci.s0c
+    hexagon_M2_vrcmacr_s0,                     // llvm.hexagon.M2.vrcmacr.s0
+    hexagon_M2_vrcmacr_s0c,                    // llvm.hexagon.M2.vrcmacr.s0c
+    hexagon_M2_vrcmpyi_s0,                     // llvm.hexagon.M2.vrcmpyi.s0
+    hexagon_M2_vrcmpyi_s0c,                    // llvm.hexagon.M2.vrcmpyi.s0c
+    hexagon_M2_vrcmpyr_s0,                     // llvm.hexagon.M2.vrcmpyr.s0
+    hexagon_M2_vrcmpyr_s0c,                    // llvm.hexagon.M2.vrcmpyr.s0c
+    hexagon_M2_vrcmpys_acc_s1,                 // llvm.hexagon.M2.vrcmpys.acc.s1
+    hexagon_M2_vrcmpys_s1,                     // llvm.hexagon.M2.vrcmpys.s1
+    hexagon_M2_vrcmpys_s1rp,                   // llvm.hexagon.M2.vrcmpys.s1rp
+    hexagon_M2_vrmac_s0,                       // llvm.hexagon.M2.vrmac.s0
+    hexagon_M2_vrmpy_s0,                       // llvm.hexagon.M2.vrmpy.s0
+    hexagon_M2_xor_xacc,                       // llvm.hexagon.M2.xor.xacc
+    hexagon_M4_and_and,                        // llvm.hexagon.M4.and.and
+    hexagon_M4_and_andn,                       // llvm.hexagon.M4.and.andn
+    hexagon_M4_and_or,                         // llvm.hexagon.M4.and.or
+    hexagon_M4_and_xor,                        // llvm.hexagon.M4.and.xor
+    hexagon_M4_cmpyi_wh,                       // llvm.hexagon.M4.cmpyi.wh
+    hexagon_M4_cmpyi_whc,                      // llvm.hexagon.M4.cmpyi.whc
+    hexagon_M4_cmpyr_wh,                       // llvm.hexagon.M4.cmpyr.wh
+    hexagon_M4_cmpyr_whc,                      // llvm.hexagon.M4.cmpyr.whc
+    hexagon_M4_mac_up_s1_sat,                  // llvm.hexagon.M4.mac.up.s1.sat
+    hexagon_M4_mpyri_addi,                     // llvm.hexagon.M4.mpyri.addi
+    hexagon_M4_mpyri_addr,                     // llvm.hexagon.M4.mpyri.addr
+    hexagon_M4_mpyri_addr_u2,                  // llvm.hexagon.M4.mpyri.addr.u2
+    hexagon_M4_mpyrr_addi,                     // llvm.hexagon.M4.mpyrr.addi
+    hexagon_M4_mpyrr_addr,                     // llvm.hexagon.M4.mpyrr.addr
+    hexagon_M4_nac_up_s1_sat,                  // llvm.hexagon.M4.nac.up.s1.sat
+    hexagon_M4_or_and,                         // llvm.hexagon.M4.or.and
+    hexagon_M4_or_andn,                        // llvm.hexagon.M4.or.andn
+    hexagon_M4_or_or,                          // llvm.hexagon.M4.or.or
+    hexagon_M4_or_xor,                         // llvm.hexagon.M4.or.xor
+    hexagon_M4_pmpyw,                          // llvm.hexagon.M4.pmpyw
+    hexagon_M4_pmpyw_acc,                      // llvm.hexagon.M4.pmpyw.acc
+    hexagon_M4_vpmpyh,                         // llvm.hexagon.M4.vpmpyh
+    hexagon_M4_vpmpyh_acc,                     // llvm.hexagon.M4.vpmpyh.acc
+    hexagon_M4_vrmpyeh_acc_s0,                 // llvm.hexagon.M4.vrmpyeh.acc.s0
+    hexagon_M4_vrmpyeh_acc_s1,                 // llvm.hexagon.M4.vrmpyeh.acc.s1
+    hexagon_M4_vrmpyeh_s0,                     // llvm.hexagon.M4.vrmpyeh.s0
+    hexagon_M4_vrmpyeh_s1,                     // llvm.hexagon.M4.vrmpyeh.s1
+    hexagon_M4_vrmpyoh_acc_s0,                 // llvm.hexagon.M4.vrmpyoh.acc.s0
+    hexagon_M4_vrmpyoh_acc_s1,                 // llvm.hexagon.M4.vrmpyoh.acc.s1
+    hexagon_M4_vrmpyoh_s0,                     // llvm.hexagon.M4.vrmpyoh.s0
+    hexagon_M4_vrmpyoh_s1,                     // llvm.hexagon.M4.vrmpyoh.s1
+    hexagon_M4_xor_and,                        // llvm.hexagon.M4.xor.and
+    hexagon_M4_xor_andn,                       // llvm.hexagon.M4.xor.andn
+    hexagon_M4_xor_or,                         // llvm.hexagon.M4.xor.or
+    hexagon_M4_xor_xacc,                       // llvm.hexagon.M4.xor.xacc
+    hexagon_M5_vdmacbsu,                       // llvm.hexagon.M5.vdmacbsu
+    hexagon_M5_vdmpybsu,                       // llvm.hexagon.M5.vdmpybsu
+    hexagon_M5_vmacbsu,                        // llvm.hexagon.M5.vmacbsu
+    hexagon_M5_vmacbuu,                        // llvm.hexagon.M5.vmacbuu
+    hexagon_M5_vmpybsu,                        // llvm.hexagon.M5.vmpybsu
+    hexagon_M5_vmpybuu,                        // llvm.hexagon.M5.vmpybuu
+    hexagon_M5_vrmacbsu,                       // llvm.hexagon.M5.vrmacbsu
+    hexagon_M5_vrmacbuu,                       // llvm.hexagon.M5.vrmacbuu
+    hexagon_M5_vrmpybsu,                       // llvm.hexagon.M5.vrmpybsu
+    hexagon_M5_vrmpybuu,                       // llvm.hexagon.M5.vrmpybuu
+    hexagon_S2_addasl_rrri,                    // llvm.hexagon.S2.addasl.rrri
+    hexagon_S2_asl_i_p,                        // llvm.hexagon.S2.asl.i.p
+    hexagon_S2_asl_i_p_acc,                    // llvm.hexagon.S2.asl.i.p.acc
+    hexagon_S2_asl_i_p_and,                    // llvm.hexagon.S2.asl.i.p.and
+    hexagon_S2_asl_i_p_nac,                    // llvm.hexagon.S2.asl.i.p.nac
+    hexagon_S2_asl_i_p_or,                     // llvm.hexagon.S2.asl.i.p.or
+    hexagon_S2_asl_i_p_xacc,                   // llvm.hexagon.S2.asl.i.p.xacc
+    hexagon_S2_asl_i_r,                        // llvm.hexagon.S2.asl.i.r
+    hexagon_S2_asl_i_r_acc,                    // llvm.hexagon.S2.asl.i.r.acc
+    hexagon_S2_asl_i_r_and,                    // llvm.hexagon.S2.asl.i.r.and
+    hexagon_S2_asl_i_r_nac,                    // llvm.hexagon.S2.asl.i.r.nac
+    hexagon_S2_asl_i_r_or,                     // llvm.hexagon.S2.asl.i.r.or
+    hexagon_S2_asl_i_r_sat,                    // llvm.hexagon.S2.asl.i.r.sat
+    hexagon_S2_asl_i_r_xacc,                   // llvm.hexagon.S2.asl.i.r.xacc
+    hexagon_S2_asl_i_vh,                       // llvm.hexagon.S2.asl.i.vh
+    hexagon_S2_asl_i_vw,                       // llvm.hexagon.S2.asl.i.vw
+    hexagon_S2_asl_r_p,                        // llvm.hexagon.S2.asl.r.p
+    hexagon_S2_asl_r_p_acc,                    // llvm.hexagon.S2.asl.r.p.acc
+    hexagon_S2_asl_r_p_and,                    // llvm.hexagon.S2.asl.r.p.and
+    hexagon_S2_asl_r_p_nac,                    // llvm.hexagon.S2.asl.r.p.nac
+    hexagon_S2_asl_r_p_or,                     // llvm.hexagon.S2.asl.r.p.or
+    hexagon_S2_asl_r_p_xor,                    // llvm.hexagon.S2.asl.r.p.xor
+    hexagon_S2_asl_r_r,                        // llvm.hexagon.S2.asl.r.r
+    hexagon_S2_asl_r_r_acc,                    // llvm.hexagon.S2.asl.r.r.acc
+    hexagon_S2_asl_r_r_and,                    // llvm.hexagon.S2.asl.r.r.and
+    hexagon_S2_asl_r_r_nac,                    // llvm.hexagon.S2.asl.r.r.nac
+    hexagon_S2_asl_r_r_or,                     // llvm.hexagon.S2.asl.r.r.or
+    hexagon_S2_asl_r_r_sat,                    // llvm.hexagon.S2.asl.r.r.sat
+    hexagon_S2_asl_r_vh,                       // llvm.hexagon.S2.asl.r.vh
+    hexagon_S2_asl_r_vw,                       // llvm.hexagon.S2.asl.r.vw
+    hexagon_S2_asr_i_p,                        // llvm.hexagon.S2.asr.i.p
+    hexagon_S2_asr_i_p_acc,                    // llvm.hexagon.S2.asr.i.p.acc
+    hexagon_S2_asr_i_p_and,                    // llvm.hexagon.S2.asr.i.p.and
+    hexagon_S2_asr_i_p_nac,                    // llvm.hexagon.S2.asr.i.p.nac
+    hexagon_S2_asr_i_p_or,                     // llvm.hexagon.S2.asr.i.p.or
+    hexagon_S2_asr_i_p_rnd,                    // llvm.hexagon.S2.asr.i.p.rnd
+    hexagon_S2_asr_i_p_rnd_goodsyntax,         // llvm.hexagon.S2.asr.i.p.rnd.goodsyntax
+    hexagon_S2_asr_i_r,                        // llvm.hexagon.S2.asr.i.r
+    hexagon_S2_asr_i_r_acc,                    // llvm.hexagon.S2.asr.i.r.acc
+    hexagon_S2_asr_i_r_and,                    // llvm.hexagon.S2.asr.i.r.and
+    hexagon_S2_asr_i_r_nac,                    // llvm.hexagon.S2.asr.i.r.nac
+    hexagon_S2_asr_i_r_or,                     // llvm.hexagon.S2.asr.i.r.or
+    hexagon_S2_asr_i_r_rnd,                    // llvm.hexagon.S2.asr.i.r.rnd
+    hexagon_S2_asr_i_r_rnd_goodsyntax,         // llvm.hexagon.S2.asr.i.r.rnd.goodsyntax
+    hexagon_S2_asr_i_svw_trun,                 // llvm.hexagon.S2.asr.i.svw.trun
+    hexagon_S2_asr_i_vh,                       // llvm.hexagon.S2.asr.i.vh
+    hexagon_S2_asr_i_vw,                       // llvm.hexagon.S2.asr.i.vw
+    hexagon_S2_asr_r_p,                        // llvm.hexagon.S2.asr.r.p
+    hexagon_S2_asr_r_p_acc,                    // llvm.hexagon.S2.asr.r.p.acc
+    hexagon_S2_asr_r_p_and,                    // llvm.hexagon.S2.asr.r.p.and
+    hexagon_S2_asr_r_p_nac,                    // llvm.hexagon.S2.asr.r.p.nac
+    hexagon_S2_asr_r_p_or,                     // llvm.hexagon.S2.asr.r.p.or
+    hexagon_S2_asr_r_p_xor,                    // llvm.hexagon.S2.asr.r.p.xor
+    hexagon_S2_asr_r_r,                        // llvm.hexagon.S2.asr.r.r
+    hexagon_S2_asr_r_r_acc,                    // llvm.hexagon.S2.asr.r.r.acc
+    hexagon_S2_asr_r_r_and,                    // llvm.hexagon.S2.asr.r.r.and
+    hexagon_S2_asr_r_r_nac,                    // llvm.hexagon.S2.asr.r.r.nac
+    hexagon_S2_asr_r_r_or,                     // llvm.hexagon.S2.asr.r.r.or
+    hexagon_S2_asr_r_r_sat,                    // llvm.hexagon.S2.asr.r.r.sat
+    hexagon_S2_asr_r_svw_trun,                 // llvm.hexagon.S2.asr.r.svw.trun
+    hexagon_S2_asr_r_vh,                       // llvm.hexagon.S2.asr.r.vh
+    hexagon_S2_asr_r_vw,                       // llvm.hexagon.S2.asr.r.vw
+    hexagon_S2_brev,                           // llvm.hexagon.S2.brev
+    hexagon_S2_brevp,                          // llvm.hexagon.S2.brevp
+    hexagon_S2_cl0,                            // llvm.hexagon.S2.cl0
+    hexagon_S2_cl0p,                           // llvm.hexagon.S2.cl0p
+    hexagon_S2_cl1,                            // llvm.hexagon.S2.cl1
+    hexagon_S2_cl1p,                           // llvm.hexagon.S2.cl1p
+    hexagon_S2_clb,                            // llvm.hexagon.S2.clb
+    hexagon_S2_clbnorm,                        // llvm.hexagon.S2.clbnorm
+    hexagon_S2_clbp,                           // llvm.hexagon.S2.clbp
+    hexagon_S2_clrbit_i,                       // llvm.hexagon.S2.clrbit.i
+    hexagon_S2_clrbit_r,                       // llvm.hexagon.S2.clrbit.r
+    hexagon_S2_ct0,                            // llvm.hexagon.S2.ct0
+    hexagon_S2_ct0p,                           // llvm.hexagon.S2.ct0p
+    hexagon_S2_ct1,                            // llvm.hexagon.S2.ct1
+    hexagon_S2_ct1p,                           // llvm.hexagon.S2.ct1p
+    hexagon_S2_deinterleave,                   // llvm.hexagon.S2.deinterleave
+    hexagon_S2_extractu,                       // llvm.hexagon.S2.extractu
+    hexagon_S2_extractu_rp,                    // llvm.hexagon.S2.extractu.rp
+    hexagon_S2_extractup,                      // llvm.hexagon.S2.extractup
+    hexagon_S2_extractup_rp,                   // llvm.hexagon.S2.extractup.rp
+    hexagon_S2_insert,                         // llvm.hexagon.S2.insert
+    hexagon_S2_insert_rp,                      // llvm.hexagon.S2.insert.rp
+    hexagon_S2_insertp,                        // llvm.hexagon.S2.insertp
+    hexagon_S2_insertp_rp,                     // llvm.hexagon.S2.insertp.rp
+    hexagon_S2_interleave,                     // llvm.hexagon.S2.interleave
+    hexagon_S2_lfsp,                           // llvm.hexagon.S2.lfsp
+    hexagon_S2_lsl_r_p,                        // llvm.hexagon.S2.lsl.r.p
+    hexagon_S2_lsl_r_p_acc,                    // llvm.hexagon.S2.lsl.r.p.acc
+    hexagon_S2_lsl_r_p_and,                    // llvm.hexagon.S2.lsl.r.p.and
+    hexagon_S2_lsl_r_p_nac,                    // llvm.hexagon.S2.lsl.r.p.nac
+    hexagon_S2_lsl_r_p_or,                     // llvm.hexagon.S2.lsl.r.p.or
+    hexagon_S2_lsl_r_p_xor,                    // llvm.hexagon.S2.lsl.r.p.xor
+    hexagon_S2_lsl_r_r,                        // llvm.hexagon.S2.lsl.r.r
+    hexagon_S2_lsl_r_r_acc,                    // llvm.hexagon.S2.lsl.r.r.acc
+    hexagon_S2_lsl_r_r_and,                    // llvm.hexagon.S2.lsl.r.r.and
+    hexagon_S2_lsl_r_r_nac,                    // llvm.hexagon.S2.lsl.r.r.nac
+    hexagon_S2_lsl_r_r_or,                     // llvm.hexagon.S2.lsl.r.r.or
+    hexagon_S2_lsl_r_vh,                       // llvm.hexagon.S2.lsl.r.vh
+    hexagon_S2_lsl_r_vw,                       // llvm.hexagon.S2.lsl.r.vw
+    hexagon_S2_lsr_i_p,                        // llvm.hexagon.S2.lsr.i.p
+    hexagon_S2_lsr_i_p_acc,                    // llvm.hexagon.S2.lsr.i.p.acc
+    hexagon_S2_lsr_i_p_and,                    // llvm.hexagon.S2.lsr.i.p.and
+    hexagon_S2_lsr_i_p_nac,                    // llvm.hexagon.S2.lsr.i.p.nac
+    hexagon_S2_lsr_i_p_or,                     // llvm.hexagon.S2.lsr.i.p.or
+    hexagon_S2_lsr_i_p_xacc,                   // llvm.hexagon.S2.lsr.i.p.xacc
+    hexagon_S2_lsr_i_r,                        // llvm.hexagon.S2.lsr.i.r
+    hexagon_S2_lsr_i_r_acc,                    // llvm.hexagon.S2.lsr.i.r.acc
+    hexagon_S2_lsr_i_r_and,                    // llvm.hexagon.S2.lsr.i.r.and
+    hexagon_S2_lsr_i_r_nac,                    // llvm.hexagon.S2.lsr.i.r.nac
+    hexagon_S2_lsr_i_r_or,                     // llvm.hexagon.S2.lsr.i.r.or
+    hexagon_S2_lsr_i_r_xacc,                   // llvm.hexagon.S2.lsr.i.r.xacc
+    hexagon_S2_lsr_i_vh,                       // llvm.hexagon.S2.lsr.i.vh
+    hexagon_S2_lsr_i_vw,                       // llvm.hexagon.S2.lsr.i.vw
+    hexagon_S2_lsr_r_p,                        // llvm.hexagon.S2.lsr.r.p
+    hexagon_S2_lsr_r_p_acc,                    // llvm.hexagon.S2.lsr.r.p.acc
+    hexagon_S2_lsr_r_p_and,                    // llvm.hexagon.S2.lsr.r.p.and
+    hexagon_S2_lsr_r_p_nac,                    // llvm.hexagon.S2.lsr.r.p.nac
+    hexagon_S2_lsr_r_p_or,                     // llvm.hexagon.S2.lsr.r.p.or
+    hexagon_S2_lsr_r_p_xor,                    // llvm.hexagon.S2.lsr.r.p.xor
+    hexagon_S2_lsr_r_r,                        // llvm.hexagon.S2.lsr.r.r
+    hexagon_S2_lsr_r_r_acc,                    // llvm.hexagon.S2.lsr.r.r.acc
+    hexagon_S2_lsr_r_r_and,                    // llvm.hexagon.S2.lsr.r.r.and
+    hexagon_S2_lsr_r_r_nac,                    // llvm.hexagon.S2.lsr.r.r.nac
+    hexagon_S2_lsr_r_r_or,                     // llvm.hexagon.S2.lsr.r.r.or
+    hexagon_S2_lsr_r_vh,                       // llvm.hexagon.S2.lsr.r.vh
+    hexagon_S2_lsr_r_vw,                       // llvm.hexagon.S2.lsr.r.vw
+    hexagon_S2_packhl,                         // llvm.hexagon.S2.packhl
+    hexagon_S2_parityp,                        // llvm.hexagon.S2.parityp
+    hexagon_S2_setbit_i,                       // llvm.hexagon.S2.setbit.i
+    hexagon_S2_setbit_r,                       // llvm.hexagon.S2.setbit.r
+    hexagon_S2_shuffeb,                        // llvm.hexagon.S2.shuffeb
+    hexagon_S2_shuffeh,                        // llvm.hexagon.S2.shuffeh
+    hexagon_S2_shuffob,                        // llvm.hexagon.S2.shuffob
+    hexagon_S2_shuffoh,                        // llvm.hexagon.S2.shuffoh
+    hexagon_S2_svsathb,                        // llvm.hexagon.S2.svsathb
+    hexagon_S2_svsathub,                       // llvm.hexagon.S2.svsathub
+    hexagon_S2_tableidxb_goodsyntax,           // llvm.hexagon.S2.tableidxb.goodsyntax
+    hexagon_S2_tableidxd_goodsyntax,           // llvm.hexagon.S2.tableidxd.goodsyntax
+    hexagon_S2_tableidxh_goodsyntax,           // llvm.hexagon.S2.tableidxh.goodsyntax
+    hexagon_S2_tableidxw_goodsyntax,           // llvm.hexagon.S2.tableidxw.goodsyntax
+    hexagon_S2_togglebit_i,                    // llvm.hexagon.S2.togglebit.i
+    hexagon_S2_togglebit_r,                    // llvm.hexagon.S2.togglebit.r
+    hexagon_S2_tstbit_i,                       // llvm.hexagon.S2.tstbit.i
+    hexagon_S2_tstbit_r,                       // llvm.hexagon.S2.tstbit.r
+    hexagon_S2_valignib,                       // llvm.hexagon.S2.valignib
+    hexagon_S2_valignrb,                       // llvm.hexagon.S2.valignrb
+    hexagon_S2_vcnegh,                         // llvm.hexagon.S2.vcnegh
+    hexagon_S2_vcrotate,                       // llvm.hexagon.S2.vcrotate
+    hexagon_S2_vrcnegh,                        // llvm.hexagon.S2.vrcnegh
+    hexagon_S2_vrndpackwh,                     // llvm.hexagon.S2.vrndpackwh
+    hexagon_S2_vrndpackwhs,                    // llvm.hexagon.S2.vrndpackwhs
+    hexagon_S2_vsathb,                         // llvm.hexagon.S2.vsathb
+    hexagon_S2_vsathb_nopack,                  // llvm.hexagon.S2.vsathb.nopack
+    hexagon_S2_vsathub,                        // llvm.hexagon.S2.vsathub
+    hexagon_S2_vsathub_nopack,                 // llvm.hexagon.S2.vsathub.nopack
+    hexagon_S2_vsatwh,                         // llvm.hexagon.S2.vsatwh
+    hexagon_S2_vsatwh_nopack,                  // llvm.hexagon.S2.vsatwh.nopack
+    hexagon_S2_vsatwuh,                        // llvm.hexagon.S2.vsatwuh
+    hexagon_S2_vsatwuh_nopack,                 // llvm.hexagon.S2.vsatwuh.nopack
+    hexagon_S2_vsplatrb,                       // llvm.hexagon.S2.vsplatrb
+    hexagon_S2_vsplatrh,                       // llvm.hexagon.S2.vsplatrh
+    hexagon_S2_vspliceib,                      // llvm.hexagon.S2.vspliceib
+    hexagon_S2_vsplicerb,                      // llvm.hexagon.S2.vsplicerb
+    hexagon_S2_vsxtbh,                         // llvm.hexagon.S2.vsxtbh
+    hexagon_S2_vsxthw,                         // llvm.hexagon.S2.vsxthw
+    hexagon_S2_vtrunehb,                       // llvm.hexagon.S2.vtrunehb
+    hexagon_S2_vtrunewh,                       // llvm.hexagon.S2.vtrunewh
+    hexagon_S2_vtrunohb,                       // llvm.hexagon.S2.vtrunohb
+    hexagon_S2_vtrunowh,                       // llvm.hexagon.S2.vtrunowh
+    hexagon_S2_vzxtbh,                         // llvm.hexagon.S2.vzxtbh
+    hexagon_S2_vzxthw,                         // llvm.hexagon.S2.vzxthw
+    hexagon_S4_addaddi,                        // llvm.hexagon.S4.addaddi
+    hexagon_S4_addi_asl_ri,                    // llvm.hexagon.S4.addi.asl.ri
+    hexagon_S4_addi_lsr_ri,                    // llvm.hexagon.S4.addi.lsr.ri
+    hexagon_S4_andi_asl_ri,                    // llvm.hexagon.S4.andi.asl.ri
+    hexagon_S4_andi_lsr_ri,                    // llvm.hexagon.S4.andi.lsr.ri
+    hexagon_S4_clbaddi,                        // llvm.hexagon.S4.clbaddi
+    hexagon_S4_clbpaddi,                       // llvm.hexagon.S4.clbpaddi
+    hexagon_S4_clbpnorm,                       // llvm.hexagon.S4.clbpnorm
+    hexagon_S4_extract,                        // llvm.hexagon.S4.extract
+    hexagon_S4_extract_rp,                     // llvm.hexagon.S4.extract.rp
+    hexagon_S4_extractp,                       // llvm.hexagon.S4.extractp
+    hexagon_S4_extractp_rp,                    // llvm.hexagon.S4.extractp.rp
+    hexagon_S4_lsli,                           // llvm.hexagon.S4.lsli
+    hexagon_S4_ntstbit_i,                      // llvm.hexagon.S4.ntstbit.i
+    hexagon_S4_ntstbit_r,                      // llvm.hexagon.S4.ntstbit.r
+    hexagon_S4_or_andi,                        // llvm.hexagon.S4.or.andi
+    hexagon_S4_or_andix,                       // llvm.hexagon.S4.or.andix
+    hexagon_S4_or_ori,                         // llvm.hexagon.S4.or.ori
+    hexagon_S4_ori_asl_ri,                     // llvm.hexagon.S4.ori.asl.ri
+    hexagon_S4_ori_lsr_ri,                     // llvm.hexagon.S4.ori.lsr.ri
+    hexagon_S4_parity,                         // llvm.hexagon.S4.parity
+    hexagon_S4_subaddi,                        // llvm.hexagon.S4.subaddi
+    hexagon_S4_subi_asl_ri,                    // llvm.hexagon.S4.subi.asl.ri
+    hexagon_S4_subi_lsr_ri,                    // llvm.hexagon.S4.subi.lsr.ri
+    hexagon_S4_vrcrotate,                      // llvm.hexagon.S4.vrcrotate
+    hexagon_S4_vrcrotate_acc,                  // llvm.hexagon.S4.vrcrotate.acc
+    hexagon_S4_vxaddsubh,                      // llvm.hexagon.S4.vxaddsubh
+    hexagon_S4_vxaddsubhr,                     // llvm.hexagon.S4.vxaddsubhr
+    hexagon_S4_vxaddsubw,                      // llvm.hexagon.S4.vxaddsubw
+    hexagon_S4_vxsubaddh,                      // llvm.hexagon.S4.vxsubaddh
+    hexagon_S4_vxsubaddhr,                     // llvm.hexagon.S4.vxsubaddhr
+    hexagon_S4_vxsubaddw,                      // llvm.hexagon.S4.vxsubaddw
+    hexagon_S5_asrhub_rnd_sat_goodsyntax,      // llvm.hexagon.S5.asrhub.rnd.sat.goodsyntax
+    hexagon_S5_asrhub_sat,                     // llvm.hexagon.S5.asrhub.sat
+    hexagon_S5_popcountp,                      // llvm.hexagon.S5.popcountp
+    hexagon_S5_vasrhrnd_goodsyntax,            // llvm.hexagon.S5.vasrhrnd.goodsyntax
+    hexagon_SI_to_SXTHI_asrh,                  // llvm.hexagon.SI.to.SXTHI.asrh
+    hexagon_circ_ldd,                          // llvm.hexagon.circ.ldd
+    init_trampoline,                           // llvm.init.trampoline
+    invariant_end,                             // llvm.invariant.end
+    invariant_start,                           // llvm.invariant.start
+    lifetime_end,                              // llvm.lifetime.end
+    lifetime_start,                            // llvm.lifetime.start
+    log,                                       // llvm.log
+    log10,                                     // llvm.log10
+    log2,                                      // llvm.log2
+    longjmp,                                   // llvm.longjmp
+    memcpy,                                    // llvm.memcpy
+    memmove,                                   // llvm.memmove
+    memset,                                    // llvm.memset
+    mips_absq_s_ph,                            // llvm.mips.absq.s.ph
+    mips_absq_s_qb,                            // llvm.mips.absq.s.qb
+    mips_absq_s_w,                             // llvm.mips.absq.s.w
+    mips_add_a_b,                              // llvm.mips.add.a.b
+    mips_add_a_d,                              // llvm.mips.add.a.d
+    mips_add_a_h,                              // llvm.mips.add.a.h
+    mips_add_a_w,                              // llvm.mips.add.a.w
+    mips_addq_ph,                              // llvm.mips.addq.ph
+    mips_addq_s_ph,                            // llvm.mips.addq.s.ph
+    mips_addq_s_w,                             // llvm.mips.addq.s.w
+    mips_addqh_ph,                             // llvm.mips.addqh.ph
+    mips_addqh_r_ph,                           // llvm.mips.addqh.r.ph
+    mips_addqh_r_w,                            // llvm.mips.addqh.r.w
+    mips_addqh_w,                              // llvm.mips.addqh.w
+    mips_adds_a_b,                             // llvm.mips.adds.a.b
+    mips_adds_a_d,                             // llvm.mips.adds.a.d
+    mips_adds_a_h,                             // llvm.mips.adds.a.h
+    mips_adds_a_w,                             // llvm.mips.adds.a.w
+    mips_adds_s_b,                             // llvm.mips.adds.s.b
+    mips_adds_s_d,                             // llvm.mips.adds.s.d
+    mips_adds_s_h,                             // llvm.mips.adds.s.h
+    mips_adds_s_w,                             // llvm.mips.adds.s.w
+    mips_adds_u_b,                             // llvm.mips.adds.u.b
+    mips_adds_u_d,                             // llvm.mips.adds.u.d
+    mips_adds_u_h,                             // llvm.mips.adds.u.h
+    mips_adds_u_w,                             // llvm.mips.adds.u.w
+    mips_addsc,                                // llvm.mips.addsc
+    mips_addu_ph,                              // llvm.mips.addu.ph
+    mips_addu_qb,                              // llvm.mips.addu.qb
+    mips_addu_s_ph,                            // llvm.mips.addu.s.ph
+    mips_addu_s_qb,                            // llvm.mips.addu.s.qb
+    mips_adduh_qb,                             // llvm.mips.adduh.qb
+    mips_adduh_r_qb,                           // llvm.mips.adduh.r.qb
+    mips_addv_b,                               // llvm.mips.addv.b
+    mips_addv_d,                               // llvm.mips.addv.d
+    mips_addv_h,                               // llvm.mips.addv.h
+    mips_addv_w,                               // llvm.mips.addv.w
+    mips_addvi_b,                              // llvm.mips.addvi.b
+    mips_addvi_d,                              // llvm.mips.addvi.d
+    mips_addvi_h,                              // llvm.mips.addvi.h
+    mips_addvi_w,                              // llvm.mips.addvi.w
+    mips_addwc,                                // llvm.mips.addwc
+    mips_and_v,                                // llvm.mips.and.v
+    mips_andi_b,                               // llvm.mips.andi.b
+    mips_append,                               // llvm.mips.append
+    mips_asub_s_b,                             // llvm.mips.asub.s.b
+    mips_asub_s_d,                             // llvm.mips.asub.s.d
+    mips_asub_s_h,                             // llvm.mips.asub.s.h
+    mips_asub_s_w,                             // llvm.mips.asub.s.w
+    mips_asub_u_b,                             // llvm.mips.asub.u.b
+    mips_asub_u_d,                             // llvm.mips.asub.u.d
+    mips_asub_u_h,                             // llvm.mips.asub.u.h
+    mips_asub_u_w,                             // llvm.mips.asub.u.w
+    mips_ave_s_b,                              // llvm.mips.ave.s.b
+    mips_ave_s_d,                              // llvm.mips.ave.s.d
+    mips_ave_s_h,                              // llvm.mips.ave.s.h
+    mips_ave_s_w,                              // llvm.mips.ave.s.w
+    mips_ave_u_b,                              // llvm.mips.ave.u.b
+    mips_ave_u_d,                              // llvm.mips.ave.u.d
+    mips_ave_u_h,                              // llvm.mips.ave.u.h
+    mips_ave_u_w,                              // llvm.mips.ave.u.w
+    mips_aver_s_b,                             // llvm.mips.aver.s.b
+    mips_aver_s_d,                             // llvm.mips.aver.s.d
+    mips_aver_s_h,                             // llvm.mips.aver.s.h
+    mips_aver_s_w,                             // llvm.mips.aver.s.w
+    mips_aver_u_b,                             // llvm.mips.aver.u.b
+    mips_aver_u_d,                             // llvm.mips.aver.u.d
+    mips_aver_u_h,                             // llvm.mips.aver.u.h
+    mips_aver_u_w,                             // llvm.mips.aver.u.w
+    mips_balign,                               // llvm.mips.balign
+    mips_bclr_b,                               // llvm.mips.bclr.b
+    mips_bclr_d,                               // llvm.mips.bclr.d
+    mips_bclr_h,                               // llvm.mips.bclr.h
+    mips_bclr_w,                               // llvm.mips.bclr.w
+    mips_bclri_b,                              // llvm.mips.bclri.b
+    mips_bclri_d,                              // llvm.mips.bclri.d
+    mips_bclri_h,                              // llvm.mips.bclri.h
+    mips_bclri_w,                              // llvm.mips.bclri.w
+    mips_binsl_b,                              // llvm.mips.binsl.b
+    mips_binsl_d,                              // llvm.mips.binsl.d
+    mips_binsl_h,                              // llvm.mips.binsl.h
+    mips_binsl_w,                              // llvm.mips.binsl.w
+    mips_binsli_b,                             // llvm.mips.binsli.b
+    mips_binsli_d,                             // llvm.mips.binsli.d
+    mips_binsli_h,                             // llvm.mips.binsli.h
+    mips_binsli_w,                             // llvm.mips.binsli.w
+    mips_binsr_b,                              // llvm.mips.binsr.b
+    mips_binsr_d,                              // llvm.mips.binsr.d
+    mips_binsr_h,                              // llvm.mips.binsr.h
+    mips_binsr_w,                              // llvm.mips.binsr.w
+    mips_binsri_b,                             // llvm.mips.binsri.b
+    mips_binsri_d,                             // llvm.mips.binsri.d
+    mips_binsri_h,                             // llvm.mips.binsri.h
+    mips_binsri_w,                             // llvm.mips.binsri.w
+    mips_bitrev,                               // llvm.mips.bitrev
+    mips_bmnz_v,                               // llvm.mips.bmnz.v
+    mips_bmnzi_b,                              // llvm.mips.bmnzi.b
+    mips_bmz_v,                                // llvm.mips.bmz.v
+    mips_bmzi_b,                               // llvm.mips.bmzi.b
+    mips_bneg_b,                               // llvm.mips.bneg.b
+    mips_bneg_d,                               // llvm.mips.bneg.d
+    mips_bneg_h,                               // llvm.mips.bneg.h
+    mips_bneg_w,                               // llvm.mips.bneg.w
+    mips_bnegi_b,                              // llvm.mips.bnegi.b
+    mips_bnegi_d,                              // llvm.mips.bnegi.d
+    mips_bnegi_h,                              // llvm.mips.bnegi.h
+    mips_bnegi_w,                              // llvm.mips.bnegi.w
+    mips_bnz_b,                                // llvm.mips.bnz.b
+    mips_bnz_d,                                // llvm.mips.bnz.d
+    mips_bnz_h,                                // llvm.mips.bnz.h
+    mips_bnz_v,                                // llvm.mips.bnz.v
+    mips_bnz_w,                                // llvm.mips.bnz.w
+    mips_bposge32,                             // llvm.mips.bposge32
+    mips_bsel_v,                               // llvm.mips.bsel.v
+    mips_bseli_b,                              // llvm.mips.bseli.b
+    mips_bset_b,                               // llvm.mips.bset.b
+    mips_bset_d,                               // llvm.mips.bset.d
+    mips_bset_h,                               // llvm.mips.bset.h
+    mips_bset_w,                               // llvm.mips.bset.w
+    mips_bseti_b,                              // llvm.mips.bseti.b
+    mips_bseti_d,                              // llvm.mips.bseti.d
+    mips_bseti_h,                              // llvm.mips.bseti.h
+    mips_bseti_w,                              // llvm.mips.bseti.w
+    mips_bz_b,                                 // llvm.mips.bz.b
+    mips_bz_d,                                 // llvm.mips.bz.d
+    mips_bz_h,                                 // llvm.mips.bz.h
+    mips_bz_v,                                 // llvm.mips.bz.v
+    mips_bz_w,                                 // llvm.mips.bz.w
+    mips_ceq_b,                                // llvm.mips.ceq.b
+    mips_ceq_d,                                // llvm.mips.ceq.d
+    mips_ceq_h,                                // llvm.mips.ceq.h
+    mips_ceq_w,                                // llvm.mips.ceq.w
+    mips_ceqi_b,                               // llvm.mips.ceqi.b
+    mips_ceqi_d,                               // llvm.mips.ceqi.d
+    mips_ceqi_h,                               // llvm.mips.ceqi.h
+    mips_ceqi_w,                               // llvm.mips.ceqi.w
+    mips_cfcmsa,                               // llvm.mips.cfcmsa
+    mips_cle_s_b,                              // llvm.mips.cle.s.b
+    mips_cle_s_d,                              // llvm.mips.cle.s.d
+    mips_cle_s_h,                              // llvm.mips.cle.s.h
+    mips_cle_s_w,                              // llvm.mips.cle.s.w
+    mips_cle_u_b,                              // llvm.mips.cle.u.b
+    mips_cle_u_d,                              // llvm.mips.cle.u.d
+    mips_cle_u_h,                              // llvm.mips.cle.u.h
+    mips_cle_u_w,                              // llvm.mips.cle.u.w
+    mips_clei_s_b,                             // llvm.mips.clei.s.b
+    mips_clei_s_d,                             // llvm.mips.clei.s.d
+    mips_clei_s_h,                             // llvm.mips.clei.s.h
+    mips_clei_s_w,                             // llvm.mips.clei.s.w
+    mips_clei_u_b,                             // llvm.mips.clei.u.b
+    mips_clei_u_d,                             // llvm.mips.clei.u.d
+    mips_clei_u_h,                             // llvm.mips.clei.u.h
+    mips_clei_u_w,                             // llvm.mips.clei.u.w
+    mips_clt_s_b,                              // llvm.mips.clt.s.b
+    mips_clt_s_d,                              // llvm.mips.clt.s.d
+    mips_clt_s_h,                              // llvm.mips.clt.s.h
+    mips_clt_s_w,                              // llvm.mips.clt.s.w
+    mips_clt_u_b,                              // llvm.mips.clt.u.b
+    mips_clt_u_d,                              // llvm.mips.clt.u.d
+    mips_clt_u_h,                              // llvm.mips.clt.u.h
+    mips_clt_u_w,                              // llvm.mips.clt.u.w
+    mips_clti_s_b,                             // llvm.mips.clti.s.b
+    mips_clti_s_d,                             // llvm.mips.clti.s.d
+    mips_clti_s_h,                             // llvm.mips.clti.s.h
+    mips_clti_s_w,                             // llvm.mips.clti.s.w
+    mips_clti_u_b,                             // llvm.mips.clti.u.b
+    mips_clti_u_d,                             // llvm.mips.clti.u.d
+    mips_clti_u_h,                             // llvm.mips.clti.u.h
+    mips_clti_u_w,                             // llvm.mips.clti.u.w
+    mips_cmp_eq_ph,                            // llvm.mips.cmp.eq.ph
+    mips_cmp_le_ph,                            // llvm.mips.cmp.le.ph
+    mips_cmp_lt_ph,                            // llvm.mips.cmp.lt.ph
+    mips_cmpgdu_eq_qb,                         // llvm.mips.cmpgdu.eq.qb
+    mips_cmpgdu_le_qb,                         // llvm.mips.cmpgdu.le.qb
+    mips_cmpgdu_lt_qb,                         // llvm.mips.cmpgdu.lt.qb
+    mips_cmpgu_eq_qb,                          // llvm.mips.cmpgu.eq.qb
+    mips_cmpgu_le_qb,                          // llvm.mips.cmpgu.le.qb
+    mips_cmpgu_lt_qb,                          // llvm.mips.cmpgu.lt.qb
+    mips_cmpu_eq_qb,                           // llvm.mips.cmpu.eq.qb
+    mips_cmpu_le_qb,                           // llvm.mips.cmpu.le.qb
+    mips_cmpu_lt_qb,                           // llvm.mips.cmpu.lt.qb
+    mips_copy_s_b,                             // llvm.mips.copy.s.b
+    mips_copy_s_d,                             // llvm.mips.copy.s.d
+    mips_copy_s_h,                             // llvm.mips.copy.s.h
+    mips_copy_s_w,                             // llvm.mips.copy.s.w
+    mips_copy_u_b,                             // llvm.mips.copy.u.b
+    mips_copy_u_d,                             // llvm.mips.copy.u.d
+    mips_copy_u_h,                             // llvm.mips.copy.u.h
+    mips_copy_u_w,                             // llvm.mips.copy.u.w
+    mips_ctcmsa,                               // llvm.mips.ctcmsa
+    mips_div_s_b,                              // llvm.mips.div.s.b
+    mips_div_s_d,                              // llvm.mips.div.s.d
+    mips_div_s_h,                              // llvm.mips.div.s.h
+    mips_div_s_w,                              // llvm.mips.div.s.w
+    mips_div_u_b,                              // llvm.mips.div.u.b
+    mips_div_u_d,                              // llvm.mips.div.u.d
+    mips_div_u_h,                              // llvm.mips.div.u.h
+    mips_div_u_w,                              // llvm.mips.div.u.w
+    mips_dlsa,                                 // llvm.mips.dlsa
+    mips_dotp_s_d,                             // llvm.mips.dotp.s.d
+    mips_dotp_s_h,                             // llvm.mips.dotp.s.h
+    mips_dotp_s_w,                             // llvm.mips.dotp.s.w
+    mips_dotp_u_d,                             // llvm.mips.dotp.u.d
+    mips_dotp_u_h,                             // llvm.mips.dotp.u.h
+    mips_dotp_u_w,                             // llvm.mips.dotp.u.w
+    mips_dpa_w_ph,                             // llvm.mips.dpa.w.ph
+    mips_dpadd_s_d,                            // llvm.mips.dpadd.s.d
+    mips_dpadd_s_h,                            // llvm.mips.dpadd.s.h
+    mips_dpadd_s_w,                            // llvm.mips.dpadd.s.w
+    mips_dpadd_u_d,                            // llvm.mips.dpadd.u.d
+    mips_dpadd_u_h,                            // llvm.mips.dpadd.u.h
+    mips_dpadd_u_w,                            // llvm.mips.dpadd.u.w
+    mips_dpaq_s_w_ph,                          // llvm.mips.dpaq.s.w.ph
+    mips_dpaq_sa_l_w,                          // llvm.mips.dpaq.sa.l.w
+    mips_dpaqx_s_w_ph,                         // llvm.mips.dpaqx.s.w.ph
+    mips_dpaqx_sa_w_ph,                        // llvm.mips.dpaqx.sa.w.ph
+    mips_dpau_h_qbl,                           // llvm.mips.dpau.h.qbl
+    mips_dpau_h_qbr,                           // llvm.mips.dpau.h.qbr
+    mips_dpax_w_ph,                            // llvm.mips.dpax.w.ph
+    mips_dps_w_ph,                             // llvm.mips.dps.w.ph
+    mips_dpsq_s_w_ph,                          // llvm.mips.dpsq.s.w.ph
+    mips_dpsq_sa_l_w,                          // llvm.mips.dpsq.sa.l.w
+    mips_dpsqx_s_w_ph,                         // llvm.mips.dpsqx.s.w.ph
+    mips_dpsqx_sa_w_ph,                        // llvm.mips.dpsqx.sa.w.ph
+    mips_dpsu_h_qbl,                           // llvm.mips.dpsu.h.qbl
+    mips_dpsu_h_qbr,                           // llvm.mips.dpsu.h.qbr
+    mips_dpsub_s_d,                            // llvm.mips.dpsub.s.d
+    mips_dpsub_s_h,                            // llvm.mips.dpsub.s.h
+    mips_dpsub_s_w,                            // llvm.mips.dpsub.s.w
+    mips_dpsub_u_d,                            // llvm.mips.dpsub.u.d
+    mips_dpsub_u_h,                            // llvm.mips.dpsub.u.h
+    mips_dpsub_u_w,                            // llvm.mips.dpsub.u.w
+    mips_dpsx_w_ph,                            // llvm.mips.dpsx.w.ph
+    mips_extp,                                 // llvm.mips.extp
+    mips_extpdp,                               // llvm.mips.extpdp
+    mips_extr_r_w,                             // llvm.mips.extr.r.w
+    mips_extr_rs_w,                            // llvm.mips.extr.rs.w
+    mips_extr_s_h,                             // llvm.mips.extr.s.h
+    mips_extr_w,                               // llvm.mips.extr.w
+    mips_fadd_d,                               // llvm.mips.fadd.d
+    mips_fadd_w,                               // llvm.mips.fadd.w
+    mips_fcaf_d,                               // llvm.mips.fcaf.d
+    mips_fcaf_w,                               // llvm.mips.fcaf.w
+    mips_fceq_d,                               // llvm.mips.fceq.d
+    mips_fceq_w,                               // llvm.mips.fceq.w
+    mips_fclass_d,                             // llvm.mips.fclass.d
+    mips_fclass_w,                             // llvm.mips.fclass.w
+    mips_fcle_d,                               // llvm.mips.fcle.d
+    mips_fcle_w,                               // llvm.mips.fcle.w
+    mips_fclt_d,                               // llvm.mips.fclt.d
+    mips_fclt_w,                               // llvm.mips.fclt.w
+    mips_fcne_d,                               // llvm.mips.fcne.d
+    mips_fcne_w,                               // llvm.mips.fcne.w
+    mips_fcor_d,                               // llvm.mips.fcor.d
+    mips_fcor_w,                               // llvm.mips.fcor.w
+    mips_fcueq_d,                              // llvm.mips.fcueq.d
+    mips_fcueq_w,                              // llvm.mips.fcueq.w
+    mips_fcule_d,                              // llvm.mips.fcule.d
+    mips_fcule_w,                              // llvm.mips.fcule.w
+    mips_fcult_d,                              // llvm.mips.fcult.d
+    mips_fcult_w,                              // llvm.mips.fcult.w
+    mips_fcun_d,                               // llvm.mips.fcun.d
+    mips_fcun_w,                               // llvm.mips.fcun.w
+    mips_fcune_d,                              // llvm.mips.fcune.d
+    mips_fcune_w,                              // llvm.mips.fcune.w
+    mips_fdiv_d,                               // llvm.mips.fdiv.d
+    mips_fdiv_w,                               // llvm.mips.fdiv.w
+    mips_fexdo_h,                              // llvm.mips.fexdo.h
+    mips_fexdo_w,                              // llvm.mips.fexdo.w
+    mips_fexp2_d,                              // llvm.mips.fexp2.d
+    mips_fexp2_w,                              // llvm.mips.fexp2.w
+    mips_fexupl_d,                             // llvm.mips.fexupl.d
+    mips_fexupl_w,                             // llvm.mips.fexupl.w
+    mips_fexupr_d,                             // llvm.mips.fexupr.d
+    mips_fexupr_w,                             // llvm.mips.fexupr.w
+    mips_ffint_s_d,                            // llvm.mips.ffint.s.d
+    mips_ffint_s_w,                            // llvm.mips.ffint.s.w
+    mips_ffint_u_d,                            // llvm.mips.ffint.u.d
+    mips_ffint_u_w,                            // llvm.mips.ffint.u.w
+    mips_ffql_d,                               // llvm.mips.ffql.d
+    mips_ffql_w,                               // llvm.mips.ffql.w
+    mips_ffqr_d,                               // llvm.mips.ffqr.d
+    mips_ffqr_w,                               // llvm.mips.ffqr.w
+    mips_fill_b,                               // llvm.mips.fill.b
+    mips_fill_d,                               // llvm.mips.fill.d
+    mips_fill_h,                               // llvm.mips.fill.h
+    mips_fill_w,                               // llvm.mips.fill.w
+    mips_flog2_d,                              // llvm.mips.flog2.d
+    mips_flog2_w,                              // llvm.mips.flog2.w
+    mips_fmadd_d,                              // llvm.mips.fmadd.d
+    mips_fmadd_w,                              // llvm.mips.fmadd.w
+    mips_fmax_a_d,                             // llvm.mips.fmax.a.d
+    mips_fmax_a_w,                             // llvm.mips.fmax.a.w
+    mips_fmax_d,                               // llvm.mips.fmax.d
+    mips_fmax_w,                               // llvm.mips.fmax.w
+    mips_fmin_a_d,                             // llvm.mips.fmin.a.d
+    mips_fmin_a_w,                             // llvm.mips.fmin.a.w
+    mips_fmin_d,                               // llvm.mips.fmin.d
+    mips_fmin_w,                               // llvm.mips.fmin.w
+    mips_fmsub_d,                              // llvm.mips.fmsub.d
+    mips_fmsub_w,                              // llvm.mips.fmsub.w
+    mips_fmul_d,                               // llvm.mips.fmul.d
+    mips_fmul_w,                               // llvm.mips.fmul.w
+    mips_frcp_d,                               // llvm.mips.frcp.d
+    mips_frcp_w,                               // llvm.mips.frcp.w
+    mips_frint_d,                              // llvm.mips.frint.d
+    mips_frint_w,                              // llvm.mips.frint.w
+    mips_frsqrt_d,                             // llvm.mips.frsqrt.d
+    mips_frsqrt_w,                             // llvm.mips.frsqrt.w
+    mips_fsaf_d,                               // llvm.mips.fsaf.d
+    mips_fsaf_w,                               // llvm.mips.fsaf.w
+    mips_fseq_d,                               // llvm.mips.fseq.d
+    mips_fseq_w,                               // llvm.mips.fseq.w
+    mips_fsle_d,                               // llvm.mips.fsle.d
+    mips_fsle_w,                               // llvm.mips.fsle.w
+    mips_fslt_d,                               // llvm.mips.fslt.d
+    mips_fslt_w,                               // llvm.mips.fslt.w
+    mips_fsne_d,                               // llvm.mips.fsne.d
+    mips_fsne_w,                               // llvm.mips.fsne.w
+    mips_fsor_d,                               // llvm.mips.fsor.d
+    mips_fsor_w,                               // llvm.mips.fsor.w
+    mips_fsqrt_d,                              // llvm.mips.fsqrt.d
+    mips_fsqrt_w,                              // llvm.mips.fsqrt.w
+    mips_fsub_d,                               // llvm.mips.fsub.d
+    mips_fsub_w,                               // llvm.mips.fsub.w
+    mips_fsueq_d,                              // llvm.mips.fsueq.d
+    mips_fsueq_w,                              // llvm.mips.fsueq.w
+    mips_fsule_d,                              // llvm.mips.fsule.d
+    mips_fsule_w,                              // llvm.mips.fsule.w
+    mips_fsult_d,                              // llvm.mips.fsult.d
+    mips_fsult_w,                              // llvm.mips.fsult.w
+    mips_fsun_d,                               // llvm.mips.fsun.d
+    mips_fsun_w,                               // llvm.mips.fsun.w
+    mips_fsune_d,                              // llvm.mips.fsune.d
+    mips_fsune_w,                              // llvm.mips.fsune.w
+    mips_ftint_s_d,                            // llvm.mips.ftint.s.d
+    mips_ftint_s_w,                            // llvm.mips.ftint.s.w
+    mips_ftint_u_d,                            // llvm.mips.ftint.u.d
+    mips_ftint_u_w,                            // llvm.mips.ftint.u.w
+    mips_ftq_h,                                // llvm.mips.ftq.h
+    mips_ftq_w,                                // llvm.mips.ftq.w
+    mips_ftrunc_s_d,                           // llvm.mips.ftrunc.s.d
+    mips_ftrunc_s_w,                           // llvm.mips.ftrunc.s.w
+    mips_ftrunc_u_d,                           // llvm.mips.ftrunc.u.d
+    mips_ftrunc_u_w,                           // llvm.mips.ftrunc.u.w
+    mips_hadd_s_d,                             // llvm.mips.hadd.s.d
+    mips_hadd_s_h,                             // llvm.mips.hadd.s.h
+    mips_hadd_s_w,                             // llvm.mips.hadd.s.w
+    mips_hadd_u_d,                             // llvm.mips.hadd.u.d
+    mips_hadd_u_h,                             // llvm.mips.hadd.u.h
+    mips_hadd_u_w,                             // llvm.mips.hadd.u.w
+    mips_hsub_s_d,                             // llvm.mips.hsub.s.d
+    mips_hsub_s_h,                             // llvm.mips.hsub.s.h
+    mips_hsub_s_w,                             // llvm.mips.hsub.s.w
+    mips_hsub_u_d,                             // llvm.mips.hsub.u.d
+    mips_hsub_u_h,                             // llvm.mips.hsub.u.h
+    mips_hsub_u_w,                             // llvm.mips.hsub.u.w
+    mips_ilvev_b,                              // llvm.mips.ilvev.b
+    mips_ilvev_d,                              // llvm.mips.ilvev.d
+    mips_ilvev_h,                              // llvm.mips.ilvev.h
+    mips_ilvev_w,                              // llvm.mips.ilvev.w
+    mips_ilvl_b,                               // llvm.mips.ilvl.b
+    mips_ilvl_d,                               // llvm.mips.ilvl.d
+    mips_ilvl_h,                               // llvm.mips.ilvl.h
+    mips_ilvl_w,                               // llvm.mips.ilvl.w
+    mips_ilvod_b,                              // llvm.mips.ilvod.b
+    mips_ilvod_d,                              // llvm.mips.ilvod.d
+    mips_ilvod_h,                              // llvm.mips.ilvod.h
+    mips_ilvod_w,                              // llvm.mips.ilvod.w
+    mips_ilvr_b,                               // llvm.mips.ilvr.b
+    mips_ilvr_d,                               // llvm.mips.ilvr.d
+    mips_ilvr_h,                               // llvm.mips.ilvr.h
+    mips_ilvr_w,                               // llvm.mips.ilvr.w
+    mips_insert_b,                             // llvm.mips.insert.b
+    mips_insert_d,                             // llvm.mips.insert.d
+    mips_insert_h,                             // llvm.mips.insert.h
+    mips_insert_w,                             // llvm.mips.insert.w
+    mips_insv,                                 // llvm.mips.insv
+    mips_insve_b,                              // llvm.mips.insve.b
+    mips_insve_d,                              // llvm.mips.insve.d
+    mips_insve_h,                              // llvm.mips.insve.h
+    mips_insve_w,                              // llvm.mips.insve.w
+    mips_lbux,                                 // llvm.mips.lbux
+    mips_ld_b,                                 // llvm.mips.ld.b
+    mips_ld_d,                                 // llvm.mips.ld.d
+    mips_ld_h,                                 // llvm.mips.ld.h
+    mips_ld_w,                                 // llvm.mips.ld.w
+    mips_ldi_b,                                // llvm.mips.ldi.b
+    mips_ldi_d,                                // llvm.mips.ldi.d
+    mips_ldi_h,                                // llvm.mips.ldi.h
+    mips_ldi_w,                                // llvm.mips.ldi.w
+    mips_lhx,                                  // llvm.mips.lhx
+    mips_lsa,                                  // llvm.mips.lsa
+    mips_lwx,                                  // llvm.mips.lwx
+    mips_madd,                                 // llvm.mips.madd
+    mips_madd_q_h,                             // llvm.mips.madd.q.h
+    mips_madd_q_w,                             // llvm.mips.madd.q.w
+    mips_maddr_q_h,                            // llvm.mips.maddr.q.h
+    mips_maddr_q_w,                            // llvm.mips.maddr.q.w
+    mips_maddu,                                // llvm.mips.maddu
+    mips_maddv_b,                              // llvm.mips.maddv.b
+    mips_maddv_d,                              // llvm.mips.maddv.d
+    mips_maddv_h,                              // llvm.mips.maddv.h
+    mips_maddv_w,                              // llvm.mips.maddv.w
+    mips_maq_s_w_phl,                          // llvm.mips.maq.s.w.phl
+    mips_maq_s_w_phr,                          // llvm.mips.maq.s.w.phr
+    mips_maq_sa_w_phl,                         // llvm.mips.maq.sa.w.phl
+    mips_maq_sa_w_phr,                         // llvm.mips.maq.sa.w.phr
+    mips_max_a_b,                              // llvm.mips.max.a.b
+    mips_max_a_d,                              // llvm.mips.max.a.d
+    mips_max_a_h,                              // llvm.mips.max.a.h
+    mips_max_a_w,                              // llvm.mips.max.a.w
+    mips_max_s_b,                              // llvm.mips.max.s.b
+    mips_max_s_d,                              // llvm.mips.max.s.d
+    mips_max_s_h,                              // llvm.mips.max.s.h
+    mips_max_s_w,                              // llvm.mips.max.s.w
+    mips_max_u_b,                              // llvm.mips.max.u.b
+    mips_max_u_d,                              // llvm.mips.max.u.d
+    mips_max_u_h,                              // llvm.mips.max.u.h
+    mips_max_u_w,                              // llvm.mips.max.u.w
+    mips_maxi_s_b,                             // llvm.mips.maxi.s.b
+    mips_maxi_s_d,                             // llvm.mips.maxi.s.d
+    mips_maxi_s_h,                             // llvm.mips.maxi.s.h
+    mips_maxi_s_w,                             // llvm.mips.maxi.s.w
+    mips_maxi_u_b,                             // llvm.mips.maxi.u.b
+    mips_maxi_u_d,                             // llvm.mips.maxi.u.d
+    mips_maxi_u_h,                             // llvm.mips.maxi.u.h
+    mips_maxi_u_w,                             // llvm.mips.maxi.u.w
+    mips_min_a_b,                              // llvm.mips.min.a.b
+    mips_min_a_d,                              // llvm.mips.min.a.d
+    mips_min_a_h,                              // llvm.mips.min.a.h
+    mips_min_a_w,                              // llvm.mips.min.a.w
+    mips_min_s_b,                              // llvm.mips.min.s.b
+    mips_min_s_d,                              // llvm.mips.min.s.d
+    mips_min_s_h,                              // llvm.mips.min.s.h
+    mips_min_s_w,                              // llvm.mips.min.s.w
+    mips_min_u_b,                              // llvm.mips.min.u.b
+    mips_min_u_d,                              // llvm.mips.min.u.d
+    mips_min_u_h,                              // llvm.mips.min.u.h
+    mips_min_u_w,                              // llvm.mips.min.u.w
+    mips_mini_s_b,                             // llvm.mips.mini.s.b
+    mips_mini_s_d,                             // llvm.mips.mini.s.d
+    mips_mini_s_h,                             // llvm.mips.mini.s.h
+    mips_mini_s_w,                             // llvm.mips.mini.s.w
+    mips_mini_u_b,                             // llvm.mips.mini.u.b
+    mips_mini_u_d,                             // llvm.mips.mini.u.d
+    mips_mini_u_h,                             // llvm.mips.mini.u.h
+    mips_mini_u_w,                             // llvm.mips.mini.u.w
+    mips_mod_s_b,                              // llvm.mips.mod.s.b
+    mips_mod_s_d,                              // llvm.mips.mod.s.d
+    mips_mod_s_h,                              // llvm.mips.mod.s.h
+    mips_mod_s_w,                              // llvm.mips.mod.s.w
+    mips_mod_u_b,                              // llvm.mips.mod.u.b
+    mips_mod_u_d,                              // llvm.mips.mod.u.d
+    mips_mod_u_h,                              // llvm.mips.mod.u.h
+    mips_mod_u_w,                              // llvm.mips.mod.u.w
+    mips_modsub,                               // llvm.mips.modsub
+    mips_move_v,                               // llvm.mips.move.v
+    mips_msub,                                 // llvm.mips.msub
+    mips_msub_q_h,                             // llvm.mips.msub.q.h
+    mips_msub_q_w,                             // llvm.mips.msub.q.w
+    mips_msubr_q_h,                            // llvm.mips.msubr.q.h
+    mips_msubr_q_w,                            // llvm.mips.msubr.q.w
+    mips_msubu,                                // llvm.mips.msubu
+    mips_msubv_b,                              // llvm.mips.msubv.b
+    mips_msubv_d,                              // llvm.mips.msubv.d
+    mips_msubv_h,                              // llvm.mips.msubv.h
+    mips_msubv_w,                              // llvm.mips.msubv.w
+    mips_mthlip,                               // llvm.mips.mthlip
+    mips_mul_ph,                               // llvm.mips.mul.ph
+    mips_mul_q_h,                              // llvm.mips.mul.q.h
+    mips_mul_q_w,                              // llvm.mips.mul.q.w
+    mips_mul_s_ph,                             // llvm.mips.mul.s.ph
+    mips_muleq_s_w_phl,                        // llvm.mips.muleq.s.w.phl
+    mips_muleq_s_w_phr,                        // llvm.mips.muleq.s.w.phr
+    mips_muleu_s_ph_qbl,                       // llvm.mips.muleu.s.ph.qbl
+    mips_muleu_s_ph_qbr,                       // llvm.mips.muleu.s.ph.qbr
+    mips_mulq_rs_ph,                           // llvm.mips.mulq.rs.ph
+    mips_mulq_rs_w,                            // llvm.mips.mulq.rs.w
+    mips_mulq_s_ph,                            // llvm.mips.mulq.s.ph
+    mips_mulq_s_w,                             // llvm.mips.mulq.s.w
+    mips_mulr_q_h,                             // llvm.mips.mulr.q.h
+    mips_mulr_q_w,                             // llvm.mips.mulr.q.w
+    mips_mulsa_w_ph,                           // llvm.mips.mulsa.w.ph
+    mips_mulsaq_s_w_ph,                        // llvm.mips.mulsaq.s.w.ph
+    mips_mult,                                 // llvm.mips.mult
+    mips_multu,                                // llvm.mips.multu
+    mips_mulv_b,                               // llvm.mips.mulv.b
+    mips_mulv_d,                               // llvm.mips.mulv.d
+    mips_mulv_h,                               // llvm.mips.mulv.h
+    mips_mulv_w,                               // llvm.mips.mulv.w
+    mips_nloc_b,                               // llvm.mips.nloc.b
+    mips_nloc_d,                               // llvm.mips.nloc.d
+    mips_nloc_h,                               // llvm.mips.nloc.h
+    mips_nloc_w,                               // llvm.mips.nloc.w
+    mips_nlzc_b,                               // llvm.mips.nlzc.b
+    mips_nlzc_d,                               // llvm.mips.nlzc.d
+    mips_nlzc_h,                               // llvm.mips.nlzc.h
+    mips_nlzc_w,                               // llvm.mips.nlzc.w
+    mips_nor_v,                                // llvm.mips.nor.v
+    mips_nori_b,                               // llvm.mips.nori.b
+    mips_or_v,                                 // llvm.mips.or.v
+    mips_ori_b,                                // llvm.mips.ori.b
+    mips_packrl_ph,                            // llvm.mips.packrl.ph
+    mips_pckev_b,                              // llvm.mips.pckev.b
+    mips_pckev_d,                              // llvm.mips.pckev.d
+    mips_pckev_h,                              // llvm.mips.pckev.h
+    mips_pckev_w,                              // llvm.mips.pckev.w
+    mips_pckod_b,                              // llvm.mips.pckod.b
+    mips_pckod_d,                              // llvm.mips.pckod.d
+    mips_pckod_h,                              // llvm.mips.pckod.h
+    mips_pckod_w,                              // llvm.mips.pckod.w
+    mips_pcnt_b,                               // llvm.mips.pcnt.b
+    mips_pcnt_d,                               // llvm.mips.pcnt.d
+    mips_pcnt_h,                               // llvm.mips.pcnt.h
+    mips_pcnt_w,                               // llvm.mips.pcnt.w
+    mips_pick_ph,                              // llvm.mips.pick.ph
+    mips_pick_qb,                              // llvm.mips.pick.qb
+    mips_preceq_w_phl,                         // llvm.mips.preceq.w.phl
+    mips_preceq_w_phr,                         // llvm.mips.preceq.w.phr
+    mips_precequ_ph_qbl,                       // llvm.mips.precequ.ph.qbl
+    mips_precequ_ph_qbla,                      // llvm.mips.precequ.ph.qbla
+    mips_precequ_ph_qbr,                       // llvm.mips.precequ.ph.qbr
+    mips_precequ_ph_qbra,                      // llvm.mips.precequ.ph.qbra
+    mips_preceu_ph_qbl,                        // llvm.mips.preceu.ph.qbl
+    mips_preceu_ph_qbla,                       // llvm.mips.preceu.ph.qbla
+    mips_preceu_ph_qbr,                        // llvm.mips.preceu.ph.qbr
+    mips_preceu_ph_qbra,                       // llvm.mips.preceu.ph.qbra
+    mips_precr_qb_ph,                          // llvm.mips.precr.qb.ph
+    mips_precr_sra_ph_w,                       // llvm.mips.precr.sra.ph.w
+    mips_precr_sra_r_ph_w,                     // llvm.mips.precr.sra.r.ph.w
+    mips_precrq_ph_w,                          // llvm.mips.precrq.ph.w
+    mips_precrq_qb_ph,                         // llvm.mips.precrq.qb.ph
+    mips_precrq_rs_ph_w,                       // llvm.mips.precrq.rs.ph.w
+    mips_precrqu_s_qb_ph,                      // llvm.mips.precrqu.s.qb.ph
+    mips_prepend,                              // llvm.mips.prepend
+    mips_raddu_w_qb,                           // llvm.mips.raddu.w.qb
+    mips_rddsp,                                // llvm.mips.rddsp
+    mips_repl_ph,                              // llvm.mips.repl.ph
+    mips_repl_qb,                              // llvm.mips.repl.qb
+    mips_sat_s_b,                              // llvm.mips.sat.s.b
+    mips_sat_s_d,                              // llvm.mips.sat.s.d
+    mips_sat_s_h,                              // llvm.mips.sat.s.h
+    mips_sat_s_w,                              // llvm.mips.sat.s.w
+    mips_sat_u_b,                              // llvm.mips.sat.u.b
+    mips_sat_u_d,                              // llvm.mips.sat.u.d
+    mips_sat_u_h,                              // llvm.mips.sat.u.h
+    mips_sat_u_w,                              // llvm.mips.sat.u.w
+    mips_shf_b,                                // llvm.mips.shf.b
+    mips_shf_h,                                // llvm.mips.shf.h
+    mips_shf_w,                                // llvm.mips.shf.w
+    mips_shilo,                                // llvm.mips.shilo
+    mips_shll_ph,                              // llvm.mips.shll.ph
+    mips_shll_qb,                              // llvm.mips.shll.qb
+    mips_shll_s_ph,                            // llvm.mips.shll.s.ph
+    mips_shll_s_w,                             // llvm.mips.shll.s.w
+    mips_shra_ph,                              // llvm.mips.shra.ph
+    mips_shra_qb,                              // llvm.mips.shra.qb
+    mips_shra_r_ph,                            // llvm.mips.shra.r.ph
+    mips_shra_r_qb,                            // llvm.mips.shra.r.qb
+    mips_shra_r_w,                             // llvm.mips.shra.r.w
+    mips_shrl_ph,                              // llvm.mips.shrl.ph
+    mips_shrl_qb,                              // llvm.mips.shrl.qb
+    mips_sld_b,                                // llvm.mips.sld.b
+    mips_sld_d,                                // llvm.mips.sld.d
+    mips_sld_h,                                // llvm.mips.sld.h
+    mips_sld_w,                                // llvm.mips.sld.w
+    mips_sldi_b,                               // llvm.mips.sldi.b
+    mips_sldi_d,                               // llvm.mips.sldi.d
+    mips_sldi_h,                               // llvm.mips.sldi.h
+    mips_sldi_w,                               // llvm.mips.sldi.w
+    mips_sll_b,                                // llvm.mips.sll.b
+    mips_sll_d,                                // llvm.mips.sll.d
+    mips_sll_h,                                // llvm.mips.sll.h
+    mips_sll_w,                                // llvm.mips.sll.w
+    mips_slli_b,                               // llvm.mips.slli.b
+    mips_slli_d,                               // llvm.mips.slli.d
+    mips_slli_h,                               // llvm.mips.slli.h
+    mips_slli_w,                               // llvm.mips.slli.w
+    mips_splat_b,                              // llvm.mips.splat.b
+    mips_splat_d,                              // llvm.mips.splat.d
+    mips_splat_h,                              // llvm.mips.splat.h
+    mips_splat_w,                              // llvm.mips.splat.w
+    mips_splati_b,                             // llvm.mips.splati.b
+    mips_splati_d,                             // llvm.mips.splati.d
+    mips_splati_h,                             // llvm.mips.splati.h
+    mips_splati_w,                             // llvm.mips.splati.w
+    mips_sra_b,                                // llvm.mips.sra.b
+    mips_sra_d,                                // llvm.mips.sra.d
+    mips_sra_h,                                // llvm.mips.sra.h
+    mips_sra_w,                                // llvm.mips.sra.w
+    mips_srai_b,                               // llvm.mips.srai.b
+    mips_srai_d,                               // llvm.mips.srai.d
+    mips_srai_h,                               // llvm.mips.srai.h
+    mips_srai_w,                               // llvm.mips.srai.w
+    mips_srar_b,                               // llvm.mips.srar.b
+    mips_srar_d,                               // llvm.mips.srar.d
+    mips_srar_h,                               // llvm.mips.srar.h
+    mips_srar_w,                               // llvm.mips.srar.w
+    mips_srari_b,                              // llvm.mips.srari.b
+    mips_srari_d,                              // llvm.mips.srari.d
+    mips_srari_h,                              // llvm.mips.srari.h
+    mips_srari_w,                              // llvm.mips.srari.w
+    mips_srl_b,                                // llvm.mips.srl.b
+    mips_srl_d,                                // llvm.mips.srl.d
+    mips_srl_h,                                // llvm.mips.srl.h
+    mips_srl_w,                                // llvm.mips.srl.w
+    mips_srli_b,                               // llvm.mips.srli.b
+    mips_srli_d,                               // llvm.mips.srli.d
+    mips_srli_h,                               // llvm.mips.srli.h
+    mips_srli_w,                               // llvm.mips.srli.w
+    mips_srlr_b,                               // llvm.mips.srlr.b
+    mips_srlr_d,                               // llvm.mips.srlr.d
+    mips_srlr_h,                               // llvm.mips.srlr.h
+    mips_srlr_w,                               // llvm.mips.srlr.w
+    mips_srlri_b,                              // llvm.mips.srlri.b
+    mips_srlri_d,                              // llvm.mips.srlri.d
+    mips_srlri_h,                              // llvm.mips.srlri.h
+    mips_srlri_w,                              // llvm.mips.srlri.w
+    mips_st_b,                                 // llvm.mips.st.b
+    mips_st_d,                                 // llvm.mips.st.d
+    mips_st_h,                                 // llvm.mips.st.h
+    mips_st_w,                                 // llvm.mips.st.w
+    mips_subq_ph,                              // llvm.mips.subq.ph
+    mips_subq_s_ph,                            // llvm.mips.subq.s.ph
+    mips_subq_s_w,                             // llvm.mips.subq.s.w
+    mips_subqh_ph,                             // llvm.mips.subqh.ph
+    mips_subqh_r_ph,                           // llvm.mips.subqh.r.ph
+    mips_subqh_r_w,                            // llvm.mips.subqh.r.w
+    mips_subqh_w,                              // llvm.mips.subqh.w
+    mips_subs_s_b,                             // llvm.mips.subs.s.b
+    mips_subs_s_d,                             // llvm.mips.subs.s.d
+    mips_subs_s_h,                             // llvm.mips.subs.s.h
+    mips_subs_s_w,                             // llvm.mips.subs.s.w
+    mips_subs_u_b,                             // llvm.mips.subs.u.b
+    mips_subs_u_d,                             // llvm.mips.subs.u.d
+    mips_subs_u_h,                             // llvm.mips.subs.u.h
+    mips_subs_u_w,                             // llvm.mips.subs.u.w
+    mips_subsus_u_b,                           // llvm.mips.subsus.u.b
+    mips_subsus_u_d,                           // llvm.mips.subsus.u.d
+    mips_subsus_u_h,                           // llvm.mips.subsus.u.h
+    mips_subsus_u_w,                           // llvm.mips.subsus.u.w
+    mips_subsuu_s_b,                           // llvm.mips.subsuu.s.b
+    mips_subsuu_s_d,                           // llvm.mips.subsuu.s.d
+    mips_subsuu_s_h,                           // llvm.mips.subsuu.s.h
+    mips_subsuu_s_w,                           // llvm.mips.subsuu.s.w
+    mips_subu_ph,                              // llvm.mips.subu.ph
+    mips_subu_qb,                              // llvm.mips.subu.qb
+    mips_subu_s_ph,                            // llvm.mips.subu.s.ph
+    mips_subu_s_qb,                            // llvm.mips.subu.s.qb
+    mips_subuh_qb,                             // llvm.mips.subuh.qb
+    mips_subuh_r_qb,                           // llvm.mips.subuh.r.qb
+    mips_subv_b,                               // llvm.mips.subv.b
+    mips_subv_d,                               // llvm.mips.subv.d
+    mips_subv_h,                               // llvm.mips.subv.h
+    mips_subv_w,                               // llvm.mips.subv.w
+    mips_subvi_b,                              // llvm.mips.subvi.b
+    mips_subvi_d,                              // llvm.mips.subvi.d
+    mips_subvi_h,                              // llvm.mips.subvi.h
+    mips_subvi_w,                              // llvm.mips.subvi.w
+    mips_vshf_b,                               // llvm.mips.vshf.b
+    mips_vshf_d,                               // llvm.mips.vshf.d
+    mips_vshf_h,                               // llvm.mips.vshf.h
+    mips_vshf_w,                               // llvm.mips.vshf.w
+    mips_wrdsp,                                // llvm.mips.wrdsp
+    mips_xor_v,                                // llvm.mips.xor.v
+    mips_xori_b,                               // llvm.mips.xori.b
+    nearbyint,                                 // llvm.nearbyint
+    nvvm_abs_i,                                // llvm.nvvm.abs.i
+    nvvm_abs_ll,                               // llvm.nvvm.abs.ll
+    nvvm_add_rm_d,                             // llvm.nvvm.add.rm.d
+    nvvm_add_rm_f,                             // llvm.nvvm.add.rm.f
+    nvvm_add_rm_ftz_f,                         // llvm.nvvm.add.rm.ftz.f
+    nvvm_add_rn_d,                             // llvm.nvvm.add.rn.d
+    nvvm_add_rn_f,                             // llvm.nvvm.add.rn.f
+    nvvm_add_rn_ftz_f,                         // llvm.nvvm.add.rn.ftz.f
+    nvvm_add_rp_d,                             // llvm.nvvm.add.rp.d
+    nvvm_add_rp_f,                             // llvm.nvvm.add.rp.f
+    nvvm_add_rp_ftz_f,                         // llvm.nvvm.add.rp.ftz.f
+    nvvm_add_rz_d,                             // llvm.nvvm.add.rz.d
+    nvvm_add_rz_f,                             // llvm.nvvm.add.rz.f
+    nvvm_add_rz_ftz_f,                         // llvm.nvvm.add.rz.ftz.f
+    nvvm_atomic_load_add_f32,                  // llvm.nvvm.atomic.load.add.f32
+    nvvm_atomic_load_dec_32,                   // llvm.nvvm.atomic.load.dec.32
+    nvvm_atomic_load_inc_32,                   // llvm.nvvm.atomic.load.inc.32
+    nvvm_barrier0,                             // llvm.nvvm.barrier0
+    nvvm_barrier0_and,                         // llvm.nvvm.barrier0.and
+    nvvm_barrier0_or,                          // llvm.nvvm.barrier0.or
+    nvvm_barrier0_popc,                        // llvm.nvvm.barrier0.popc
+    nvvm_bitcast_d2ll,                         // llvm.nvvm.bitcast.d2ll
+    nvvm_bitcast_f2i,                          // llvm.nvvm.bitcast.f2i
+    nvvm_bitcast_i2f,                          // llvm.nvvm.bitcast.i2f
+    nvvm_bitcast_ll2d,                         // llvm.nvvm.bitcast.ll2d
+    nvvm_brev32,                               // llvm.nvvm.brev32
+    nvvm_brev64,                               // llvm.nvvm.brev64
+    nvvm_ceil_d,                               // llvm.nvvm.ceil.d
+    nvvm_ceil_f,                               // llvm.nvvm.ceil.f
+    nvvm_ceil_ftz_f,                           // llvm.nvvm.ceil.ftz.f
+    nvvm_clz_i,                                // llvm.nvvm.clz.i
+    nvvm_clz_ll,                               // llvm.nvvm.clz.ll
+    nvvm_compiler_error,                       // llvm.nvvm.compiler.error
+    nvvm_compiler_warn,                        // llvm.nvvm.compiler.warn
+    nvvm_cos_approx_f,                         // llvm.nvvm.cos.approx.f
+    nvvm_cos_approx_ftz_f,                     // llvm.nvvm.cos.approx.ftz.f
+    nvvm_d2f_rm,                               // llvm.nvvm.d2f.rm
+    nvvm_d2f_rm_ftz,                           // llvm.nvvm.d2f.rm.ftz
+    nvvm_d2f_rn,                               // llvm.nvvm.d2f.rn
+    nvvm_d2f_rn_ftz,                           // llvm.nvvm.d2f.rn.ftz
+    nvvm_d2f_rp,                               // llvm.nvvm.d2f.rp
+    nvvm_d2f_rp_ftz,                           // llvm.nvvm.d2f.rp.ftz
+    nvvm_d2f_rz,                               // llvm.nvvm.d2f.rz
+    nvvm_d2f_rz_ftz,                           // llvm.nvvm.d2f.rz.ftz
+    nvvm_d2i_hi,                               // llvm.nvvm.d2i.hi
+    nvvm_d2i_lo,                               // llvm.nvvm.d2i.lo
+    nvvm_d2i_rm,                               // llvm.nvvm.d2i.rm
+    nvvm_d2i_rn,                               // llvm.nvvm.d2i.rn
+    nvvm_d2i_rp,                               // llvm.nvvm.d2i.rp
+    nvvm_d2i_rz,                               // llvm.nvvm.d2i.rz
+    nvvm_d2ll_rm,                              // llvm.nvvm.d2ll.rm
+    nvvm_d2ll_rn,                              // llvm.nvvm.d2ll.rn
+    nvvm_d2ll_rp,                              // llvm.nvvm.d2ll.rp
+    nvvm_d2ll_rz,                              // llvm.nvvm.d2ll.rz
+    nvvm_d2ui_rm,                              // llvm.nvvm.d2ui.rm
+    nvvm_d2ui_rn,                              // llvm.nvvm.d2ui.rn
+    nvvm_d2ui_rp,                              // llvm.nvvm.d2ui.rp
+    nvvm_d2ui_rz,                              // llvm.nvvm.d2ui.rz
+    nvvm_d2ull_rm,                             // llvm.nvvm.d2ull.rm
+    nvvm_d2ull_rn,                             // llvm.nvvm.d2ull.rn
+    nvvm_d2ull_rp,                             // llvm.nvvm.d2ull.rp
+    nvvm_d2ull_rz,                             // llvm.nvvm.d2ull.rz
+    nvvm_div_approx_f,                         // llvm.nvvm.div.approx.f
+    nvvm_div_approx_ftz_f,                     // llvm.nvvm.div.approx.ftz.f
+    nvvm_div_rm_d,                             // llvm.nvvm.div.rm.d
+    nvvm_div_rm_f,                             // llvm.nvvm.div.rm.f
+    nvvm_div_rm_ftz_f,                         // llvm.nvvm.div.rm.ftz.f
+    nvvm_div_rn_d,                             // llvm.nvvm.div.rn.d
+    nvvm_div_rn_f,                             // llvm.nvvm.div.rn.f
+    nvvm_div_rn_ftz_f,                         // llvm.nvvm.div.rn.ftz.f
+    nvvm_div_rp_d,                             // llvm.nvvm.div.rp.d
+    nvvm_div_rp_f,                             // llvm.nvvm.div.rp.f
+    nvvm_div_rp_ftz_f,                         // llvm.nvvm.div.rp.ftz.f
+    nvvm_div_rz_d,                             // llvm.nvvm.div.rz.d
+    nvvm_div_rz_f,                             // llvm.nvvm.div.rz.f
+    nvvm_div_rz_ftz_f,                         // llvm.nvvm.div.rz.ftz.f
+    nvvm_ex2_approx_d,                         // llvm.nvvm.ex2.approx.d
+    nvvm_ex2_approx_f,                         // llvm.nvvm.ex2.approx.f
+    nvvm_ex2_approx_ftz_f,                     // llvm.nvvm.ex2.approx.ftz.f
+    nvvm_f2h_rn,                               // llvm.nvvm.f2h.rn
+    nvvm_f2h_rn_ftz,                           // llvm.nvvm.f2h.rn.ftz
+    nvvm_f2i_rm,                               // llvm.nvvm.f2i.rm
+    nvvm_f2i_rm_ftz,                           // llvm.nvvm.f2i.rm.ftz
+    nvvm_f2i_rn,                               // llvm.nvvm.f2i.rn
+    nvvm_f2i_rn_ftz,                           // llvm.nvvm.f2i.rn.ftz
+    nvvm_f2i_rp,                               // llvm.nvvm.f2i.rp
+    nvvm_f2i_rp_ftz,                           // llvm.nvvm.f2i.rp.ftz
+    nvvm_f2i_rz,                               // llvm.nvvm.f2i.rz
+    nvvm_f2i_rz_ftz,                           // llvm.nvvm.f2i.rz.ftz
+    nvvm_f2ll_rm,                              // llvm.nvvm.f2ll.rm
+    nvvm_f2ll_rm_ftz,                          // llvm.nvvm.f2ll.rm.ftz
+    nvvm_f2ll_rn,                              // llvm.nvvm.f2ll.rn
+    nvvm_f2ll_rn_ftz,                          // llvm.nvvm.f2ll.rn.ftz
+    nvvm_f2ll_rp,                              // llvm.nvvm.f2ll.rp
+    nvvm_f2ll_rp_ftz,                          // llvm.nvvm.f2ll.rp.ftz
+    nvvm_f2ll_rz,                              // llvm.nvvm.f2ll.rz
+    nvvm_f2ll_rz_ftz,                          // llvm.nvvm.f2ll.rz.ftz
+    nvvm_f2ui_rm,                              // llvm.nvvm.f2ui.rm
+    nvvm_f2ui_rm_ftz,                          // llvm.nvvm.f2ui.rm.ftz
+    nvvm_f2ui_rn,                              // llvm.nvvm.f2ui.rn
+    nvvm_f2ui_rn_ftz,                          // llvm.nvvm.f2ui.rn.ftz
+    nvvm_f2ui_rp,                              // llvm.nvvm.f2ui.rp
+    nvvm_f2ui_rp_ftz,                          // llvm.nvvm.f2ui.rp.ftz
+    nvvm_f2ui_rz,                              // llvm.nvvm.f2ui.rz
+    nvvm_f2ui_rz_ftz,                          // llvm.nvvm.f2ui.rz.ftz
+    nvvm_f2ull_rm,                             // llvm.nvvm.f2ull.rm
+    nvvm_f2ull_rm_ftz,                         // llvm.nvvm.f2ull.rm.ftz
+    nvvm_f2ull_rn,                             // llvm.nvvm.f2ull.rn
+    nvvm_f2ull_rn_ftz,                         // llvm.nvvm.f2ull.rn.ftz
+    nvvm_f2ull_rp,                             // llvm.nvvm.f2ull.rp
+    nvvm_f2ull_rp_ftz,                         // llvm.nvvm.f2ull.rp.ftz
+    nvvm_f2ull_rz,                             // llvm.nvvm.f2ull.rz
+    nvvm_f2ull_rz_ftz,                         // llvm.nvvm.f2ull.rz.ftz
+    nvvm_fabs_d,                               // llvm.nvvm.fabs.d
+    nvvm_fabs_f,                               // llvm.nvvm.fabs.f
+    nvvm_fabs_ftz_f,                           // llvm.nvvm.fabs.ftz.f
+    nvvm_floor_d,                              // llvm.nvvm.floor.d
+    nvvm_floor_f,                              // llvm.nvvm.floor.f
+    nvvm_floor_ftz_f,                          // llvm.nvvm.floor.ftz.f
+    nvvm_fma_rm_d,                             // llvm.nvvm.fma.rm.d
+    nvvm_fma_rm_f,                             // llvm.nvvm.fma.rm.f
+    nvvm_fma_rm_ftz_f,                         // llvm.nvvm.fma.rm.ftz.f
+    nvvm_fma_rn_d,                             // llvm.nvvm.fma.rn.d
+    nvvm_fma_rn_f,                             // llvm.nvvm.fma.rn.f
+    nvvm_fma_rn_ftz_f,                         // llvm.nvvm.fma.rn.ftz.f
+    nvvm_fma_rp_d,                             // llvm.nvvm.fma.rp.d
+    nvvm_fma_rp_f,                             // llvm.nvvm.fma.rp.f
+    nvvm_fma_rp_ftz_f,                         // llvm.nvvm.fma.rp.ftz.f
+    nvvm_fma_rz_d,                             // llvm.nvvm.fma.rz.d
+    nvvm_fma_rz_f,                             // llvm.nvvm.fma.rz.f
+    nvvm_fma_rz_ftz_f,                         // llvm.nvvm.fma.rz.ftz.f
+    nvvm_fmax_d,                               // llvm.nvvm.fmax.d
+    nvvm_fmax_f,                               // llvm.nvvm.fmax.f
+    nvvm_fmax_ftz_f,                           // llvm.nvvm.fmax.ftz.f
+    nvvm_fmin_d,                               // llvm.nvvm.fmin.d
+    nvvm_fmin_f,                               // llvm.nvvm.fmin.f
+    nvvm_fmin_ftz_f,                           // llvm.nvvm.fmin.ftz.f
+    nvvm_h2f,                                  // llvm.nvvm.h2f
+    nvvm_i2d_rm,                               // llvm.nvvm.i2d.rm
+    nvvm_i2d_rn,                               // llvm.nvvm.i2d.rn
+    nvvm_i2d_rp,                               // llvm.nvvm.i2d.rp
+    nvvm_i2d_rz,                               // llvm.nvvm.i2d.rz
+    nvvm_i2f_rm,                               // llvm.nvvm.i2f.rm
+    nvvm_i2f_rn,                               // llvm.nvvm.i2f.rn
+    nvvm_i2f_rp,                               // llvm.nvvm.i2f.rp
+    nvvm_i2f_rz,                               // llvm.nvvm.i2f.rz
+    nvvm_isspacep_const,                       // llvm.nvvm.isspacep.const
+    nvvm_isspacep_global,                      // llvm.nvvm.isspacep.global
+    nvvm_isspacep_local,                       // llvm.nvvm.isspacep.local
+    nvvm_isspacep_shared,                      // llvm.nvvm.isspacep.shared
+    nvvm_istypep_sampler,                      // llvm.nvvm.istypep.sampler
+    nvvm_istypep_surface,                      // llvm.nvvm.istypep.surface
+    nvvm_istypep_texture,                      // llvm.nvvm.istypep.texture
+    nvvm_ldg_global_f,                         // llvm.nvvm.ldg.global.f
+    nvvm_ldg_global_i,                         // llvm.nvvm.ldg.global.i
+    nvvm_ldg_global_p,                         // llvm.nvvm.ldg.global.p
+    nvvm_ldu_global_f,                         // llvm.nvvm.ldu.global.f
+    nvvm_ldu_global_i,                         // llvm.nvvm.ldu.global.i
+    nvvm_ldu_global_p,                         // llvm.nvvm.ldu.global.p
+    nvvm_lg2_approx_d,                         // llvm.nvvm.lg2.approx.d
+    nvvm_lg2_approx_f,                         // llvm.nvvm.lg2.approx.f
+    nvvm_lg2_approx_ftz_f,                     // llvm.nvvm.lg2.approx.ftz.f
+    nvvm_ll2d_rm,                              // llvm.nvvm.ll2d.rm
+    nvvm_ll2d_rn,                              // llvm.nvvm.ll2d.rn
+    nvvm_ll2d_rp,                              // llvm.nvvm.ll2d.rp
+    nvvm_ll2d_rz,                              // llvm.nvvm.ll2d.rz
+    nvvm_ll2f_rm,                              // llvm.nvvm.ll2f.rm
+    nvvm_ll2f_rn,                              // llvm.nvvm.ll2f.rn
+    nvvm_ll2f_rp,                              // llvm.nvvm.ll2f.rp
+    nvvm_ll2f_rz,                              // llvm.nvvm.ll2f.rz
+    nvvm_lohi_i2d,                             // llvm.nvvm.lohi.i2d
+    nvvm_max_i,                                // llvm.nvvm.max.i
+    nvvm_max_ll,                               // llvm.nvvm.max.ll
+    nvvm_max_ui,                               // llvm.nvvm.max.ui
+    nvvm_max_ull,                              // llvm.nvvm.max.ull
+    nvvm_membar_cta,                           // llvm.nvvm.membar.cta
+    nvvm_membar_gl,                            // llvm.nvvm.membar.gl
+    nvvm_membar_sys,                           // llvm.nvvm.membar.sys
+    nvvm_min_i,                                // llvm.nvvm.min.i
+    nvvm_min_ll,                               // llvm.nvvm.min.ll
+    nvvm_min_ui,                               // llvm.nvvm.min.ui
+    nvvm_min_ull,                              // llvm.nvvm.min.ull
+    nvvm_move_double,                          // llvm.nvvm.move.double
+    nvvm_move_float,                           // llvm.nvvm.move.float
+    nvvm_move_i16,                             // llvm.nvvm.move.i16
+    nvvm_move_i32,                             // llvm.nvvm.move.i32
+    nvvm_move_i64,                             // llvm.nvvm.move.i64
+    nvvm_move_ptr,                             // llvm.nvvm.move.ptr
+    nvvm_mul24_i,                              // llvm.nvvm.mul24.i
+    nvvm_mul24_ui,                             // llvm.nvvm.mul24.ui
+    nvvm_mul_rm_d,                             // llvm.nvvm.mul.rm.d
+    nvvm_mul_rm_f,                             // llvm.nvvm.mul.rm.f
+    nvvm_mul_rm_ftz_f,                         // llvm.nvvm.mul.rm.ftz.f
+    nvvm_mul_rn_d,                             // llvm.nvvm.mul.rn.d
+    nvvm_mul_rn_f,                             // llvm.nvvm.mul.rn.f
+    nvvm_mul_rn_ftz_f,                         // llvm.nvvm.mul.rn.ftz.f
+    nvvm_mul_rp_d,                             // llvm.nvvm.mul.rp.d
+    nvvm_mul_rp_f,                             // llvm.nvvm.mul.rp.f
+    nvvm_mul_rp_ftz_f,                         // llvm.nvvm.mul.rp.ftz.f
+    nvvm_mul_rz_d,                             // llvm.nvvm.mul.rz.d
+    nvvm_mul_rz_f,                             // llvm.nvvm.mul.rz.f
+    nvvm_mul_rz_ftz_f,                         // llvm.nvvm.mul.rz.ftz.f
+    nvvm_mulhi_i,                              // llvm.nvvm.mulhi.i
+    nvvm_mulhi_ll,                             // llvm.nvvm.mulhi.ll
+    nvvm_mulhi_ui,                             // llvm.nvvm.mulhi.ui
+    nvvm_mulhi_ull,                            // llvm.nvvm.mulhi.ull
+    nvvm_popc_i,                               // llvm.nvvm.popc.i
+    nvvm_popc_ll,                              // llvm.nvvm.popc.ll
+    nvvm_prmt,                                 // llvm.nvvm.prmt
+    nvvm_ptr_constant_to_gen,                  // llvm.nvvm.ptr.constant.to.gen
+    nvvm_ptr_gen_to_constant,                  // llvm.nvvm.ptr.gen.to.constant
+    nvvm_ptr_gen_to_global,                    // llvm.nvvm.ptr.gen.to.global
+    nvvm_ptr_gen_to_local,                     // llvm.nvvm.ptr.gen.to.local
+    nvvm_ptr_gen_to_param,                     // llvm.nvvm.ptr.gen.to.param
+    nvvm_ptr_gen_to_shared,                    // llvm.nvvm.ptr.gen.to.shared
+    nvvm_ptr_global_to_gen,                    // llvm.nvvm.ptr.global.to.gen
+    nvvm_ptr_local_to_gen,                     // llvm.nvvm.ptr.local.to.gen
+    nvvm_ptr_shared_to_gen,                    // llvm.nvvm.ptr.shared.to.gen
+    nvvm_rcp_approx_ftz_d,                     // llvm.nvvm.rcp.approx.ftz.d
+    nvvm_rcp_rm_d,                             // llvm.nvvm.rcp.rm.d
+    nvvm_rcp_rm_f,                             // llvm.nvvm.rcp.rm.f
+    nvvm_rcp_rm_ftz_f,                         // llvm.nvvm.rcp.rm.ftz.f
+    nvvm_rcp_rn_d,                             // llvm.nvvm.rcp.rn.d
+    nvvm_rcp_rn_f,                             // llvm.nvvm.rcp.rn.f
+    nvvm_rcp_rn_ftz_f,                         // llvm.nvvm.rcp.rn.ftz.f
+    nvvm_rcp_rp_d,                             // llvm.nvvm.rcp.rp.d
+    nvvm_rcp_rp_f,                             // llvm.nvvm.rcp.rp.f
+    nvvm_rcp_rp_ftz_f,                         // llvm.nvvm.rcp.rp.ftz.f
+    nvvm_rcp_rz_d,                             // llvm.nvvm.rcp.rz.d
+    nvvm_rcp_rz_f,                             // llvm.nvvm.rcp.rz.f
+    nvvm_rcp_rz_ftz_f,                         // llvm.nvvm.rcp.rz.ftz.f
+    nvvm_read_ptx_sreg_ctaid_x,                // llvm.nvvm.read.ptx.sreg.ctaid.x
+    nvvm_read_ptx_sreg_ctaid_y,                // llvm.nvvm.read.ptx.sreg.ctaid.y
+    nvvm_read_ptx_sreg_ctaid_z,                // llvm.nvvm.read.ptx.sreg.ctaid.z
+    nvvm_read_ptx_sreg_envreg0,                // llvm.nvvm.read.ptx.sreg.envreg0
+    nvvm_read_ptx_sreg_envreg1,                // llvm.nvvm.read.ptx.sreg.envreg1
+    nvvm_read_ptx_sreg_envreg10,               // llvm.nvvm.read.ptx.sreg.envreg10
+    nvvm_read_ptx_sreg_envreg11,               // llvm.nvvm.read.ptx.sreg.envreg11
+    nvvm_read_ptx_sreg_envreg12,               // llvm.nvvm.read.ptx.sreg.envreg12
+    nvvm_read_ptx_sreg_envreg13,               // llvm.nvvm.read.ptx.sreg.envreg13
+    nvvm_read_ptx_sreg_envreg14,               // llvm.nvvm.read.ptx.sreg.envreg14
+    nvvm_read_ptx_sreg_envreg15,               // llvm.nvvm.read.ptx.sreg.envreg15
+    nvvm_read_ptx_sreg_envreg16,               // llvm.nvvm.read.ptx.sreg.envreg16
+    nvvm_read_ptx_sreg_envreg17,               // llvm.nvvm.read.ptx.sreg.envreg17
+    nvvm_read_ptx_sreg_envreg18,               // llvm.nvvm.read.ptx.sreg.envreg18
+    nvvm_read_ptx_sreg_envreg19,               // llvm.nvvm.read.ptx.sreg.envreg19
+    nvvm_read_ptx_sreg_envreg2,                // llvm.nvvm.read.ptx.sreg.envreg2
+    nvvm_read_ptx_sreg_envreg20,               // llvm.nvvm.read.ptx.sreg.envreg20
+    nvvm_read_ptx_sreg_envreg21,               // llvm.nvvm.read.ptx.sreg.envreg21
+    nvvm_read_ptx_sreg_envreg22,               // llvm.nvvm.read.ptx.sreg.envreg22
+    nvvm_read_ptx_sreg_envreg23,               // llvm.nvvm.read.ptx.sreg.envreg23
+    nvvm_read_ptx_sreg_envreg24,               // llvm.nvvm.read.ptx.sreg.envreg24
+    nvvm_read_ptx_sreg_envreg25,               // llvm.nvvm.read.ptx.sreg.envreg25
+    nvvm_read_ptx_sreg_envreg26,               // llvm.nvvm.read.ptx.sreg.envreg26
+    nvvm_read_ptx_sreg_envreg27,               // llvm.nvvm.read.ptx.sreg.envreg27
+    nvvm_read_ptx_sreg_envreg28,               // llvm.nvvm.read.ptx.sreg.envreg28
+    nvvm_read_ptx_sreg_envreg29,               // llvm.nvvm.read.ptx.sreg.envreg29
+    nvvm_read_ptx_sreg_envreg3,                // llvm.nvvm.read.ptx.sreg.envreg3
+    nvvm_read_ptx_sreg_envreg30,               // llvm.nvvm.read.ptx.sreg.envreg30
+    nvvm_read_ptx_sreg_envreg31,               // llvm.nvvm.read.ptx.sreg.envreg31
+    nvvm_read_ptx_sreg_envreg4,                // llvm.nvvm.read.ptx.sreg.envreg4
+    nvvm_read_ptx_sreg_envreg5,                // llvm.nvvm.read.ptx.sreg.envreg5
+    nvvm_read_ptx_sreg_envreg6,                // llvm.nvvm.read.ptx.sreg.envreg6
+    nvvm_read_ptx_sreg_envreg7,                // llvm.nvvm.read.ptx.sreg.envreg7
+    nvvm_read_ptx_sreg_envreg8,                // llvm.nvvm.read.ptx.sreg.envreg8
+    nvvm_read_ptx_sreg_envreg9,                // llvm.nvvm.read.ptx.sreg.envreg9
+    nvvm_read_ptx_sreg_nctaid_x,               // llvm.nvvm.read.ptx.sreg.nctaid.x
+    nvvm_read_ptx_sreg_nctaid_y,               // llvm.nvvm.read.ptx.sreg.nctaid.y
+    nvvm_read_ptx_sreg_nctaid_z,               // llvm.nvvm.read.ptx.sreg.nctaid.z
+    nvvm_read_ptx_sreg_ntid_x,                 // llvm.nvvm.read.ptx.sreg.ntid.x
+    nvvm_read_ptx_sreg_ntid_y,                 // llvm.nvvm.read.ptx.sreg.ntid.y
+    nvvm_read_ptx_sreg_ntid_z,                 // llvm.nvvm.read.ptx.sreg.ntid.z
+    nvvm_read_ptx_sreg_tid_x,                  // llvm.nvvm.read.ptx.sreg.tid.x
+    nvvm_read_ptx_sreg_tid_y,                  // llvm.nvvm.read.ptx.sreg.tid.y
+    nvvm_read_ptx_sreg_tid_z,                  // llvm.nvvm.read.ptx.sreg.tid.z
+    nvvm_read_ptx_sreg_warpsize,               // llvm.nvvm.read.ptx.sreg.warpsize
+    nvvm_reflect,                              // llvm.nvvm.reflect
+    nvvm_rotate_b32,                           // llvm.nvvm.rotate.b32
+    nvvm_rotate_b64,                           // llvm.nvvm.rotate.b64
+    nvvm_rotate_right_b64,                     // llvm.nvvm.rotate.right.b64
+    nvvm_round_d,                              // llvm.nvvm.round.d
+    nvvm_round_f,                              // llvm.nvvm.round.f
+    nvvm_round_ftz_f,                          // llvm.nvvm.round.ftz.f
+    nvvm_rsqrt_approx_d,                       // llvm.nvvm.rsqrt.approx.d
+    nvvm_rsqrt_approx_f,                       // llvm.nvvm.rsqrt.approx.f
+    nvvm_rsqrt_approx_ftz_f,                   // llvm.nvvm.rsqrt.approx.ftz.f
+    nvvm_sad_i,                                // llvm.nvvm.sad.i
+    nvvm_sad_ui,                               // llvm.nvvm.sad.ui
+    nvvm_saturate_d,                           // llvm.nvvm.saturate.d
+    nvvm_saturate_f,                           // llvm.nvvm.saturate.f
+    nvvm_saturate_ftz_f,                       // llvm.nvvm.saturate.ftz.f
+    nvvm_sin_approx_f,                         // llvm.nvvm.sin.approx.f
+    nvvm_sin_approx_ftz_f,                     // llvm.nvvm.sin.approx.ftz.f
+    nvvm_sqrt_approx_f,                        // llvm.nvvm.sqrt.approx.f
+    nvvm_sqrt_approx_ftz_f,                    // llvm.nvvm.sqrt.approx.ftz.f
+    nvvm_sqrt_f,                               // llvm.nvvm.sqrt.f
+    nvvm_sqrt_rm_d,                            // llvm.nvvm.sqrt.rm.d
+    nvvm_sqrt_rm_f,                            // llvm.nvvm.sqrt.rm.f
+    nvvm_sqrt_rm_ftz_f,                        // llvm.nvvm.sqrt.rm.ftz.f
+    nvvm_sqrt_rn_d,                            // llvm.nvvm.sqrt.rn.d
+    nvvm_sqrt_rn_f,                            // llvm.nvvm.sqrt.rn.f
+    nvvm_sqrt_rn_ftz_f,                        // llvm.nvvm.sqrt.rn.ftz.f
+    nvvm_sqrt_rp_d,                            // llvm.nvvm.sqrt.rp.d
+    nvvm_sqrt_rp_f,                            // llvm.nvvm.sqrt.rp.f
+    nvvm_sqrt_rp_ftz_f,                        // llvm.nvvm.sqrt.rp.ftz.f
+    nvvm_sqrt_rz_d,                            // llvm.nvvm.sqrt.rz.d
+    nvvm_sqrt_rz_f,                            // llvm.nvvm.sqrt.rz.f
+    nvvm_sqrt_rz_ftz_f,                        // llvm.nvvm.sqrt.rz.ftz.f
+    nvvm_suld_1d_array_i16_clamp,              // llvm.nvvm.suld.1d.array.i16.clamp
+    nvvm_suld_1d_array_i16_trap,               // llvm.nvvm.suld.1d.array.i16.trap
+    nvvm_suld_1d_array_i16_zero,               // llvm.nvvm.suld.1d.array.i16.zero
+    nvvm_suld_1d_array_i32_clamp,              // llvm.nvvm.suld.1d.array.i32.clamp
+    nvvm_suld_1d_array_i32_trap,               // llvm.nvvm.suld.1d.array.i32.trap
+    nvvm_suld_1d_array_i32_zero,               // llvm.nvvm.suld.1d.array.i32.zero
+    nvvm_suld_1d_array_i64_clamp,              // llvm.nvvm.suld.1d.array.i64.clamp
+    nvvm_suld_1d_array_i64_trap,               // llvm.nvvm.suld.1d.array.i64.trap
+    nvvm_suld_1d_array_i64_zero,               // llvm.nvvm.suld.1d.array.i64.zero
+    nvvm_suld_1d_array_i8_clamp,               // llvm.nvvm.suld.1d.array.i8.clamp
+    nvvm_suld_1d_array_i8_trap,                // llvm.nvvm.suld.1d.array.i8.trap
+    nvvm_suld_1d_array_i8_zero,                // llvm.nvvm.suld.1d.array.i8.zero
+    nvvm_suld_1d_array_v2i16_clamp,            // llvm.nvvm.suld.1d.array.v2i16.clamp
+    nvvm_suld_1d_array_v2i16_trap,             // llvm.nvvm.suld.1d.array.v2i16.trap
+    nvvm_suld_1d_array_v2i16_zero,             // llvm.nvvm.suld.1d.array.v2i16.zero
+    nvvm_suld_1d_array_v2i32_clamp,            // llvm.nvvm.suld.1d.array.v2i32.clamp
+    nvvm_suld_1d_array_v2i32_trap,             // llvm.nvvm.suld.1d.array.v2i32.trap
+    nvvm_suld_1d_array_v2i32_zero,             // llvm.nvvm.suld.1d.array.v2i32.zero
+    nvvm_suld_1d_array_v2i64_clamp,            // llvm.nvvm.suld.1d.array.v2i64.clamp
+    nvvm_suld_1d_array_v2i64_trap,             // llvm.nvvm.suld.1d.array.v2i64.trap
+    nvvm_suld_1d_array_v2i64_zero,             // llvm.nvvm.suld.1d.array.v2i64.zero
+    nvvm_suld_1d_array_v2i8_clamp,             // llvm.nvvm.suld.1d.array.v2i8.clamp
+    nvvm_suld_1d_array_v2i8_trap,              // llvm.nvvm.suld.1d.array.v2i8.trap
+    nvvm_suld_1d_array_v2i8_zero,              // llvm.nvvm.suld.1d.array.v2i8.zero
+    nvvm_suld_1d_array_v4i16_clamp,            // llvm.nvvm.suld.1d.array.v4i16.clamp
+    nvvm_suld_1d_array_v4i16_trap,             // llvm.nvvm.suld.1d.array.v4i16.trap
+    nvvm_suld_1d_array_v4i16_zero,             // llvm.nvvm.suld.1d.array.v4i16.zero
+    nvvm_suld_1d_array_v4i32_clamp,            // llvm.nvvm.suld.1d.array.v4i32.clamp
+    nvvm_suld_1d_array_v4i32_trap,             // llvm.nvvm.suld.1d.array.v4i32.trap
+    nvvm_suld_1d_array_v4i32_zero,             // llvm.nvvm.suld.1d.array.v4i32.zero
+    nvvm_suld_1d_array_v4i8_clamp,             // llvm.nvvm.suld.1d.array.v4i8.clamp
+    nvvm_suld_1d_array_v4i8_trap,              // llvm.nvvm.suld.1d.array.v4i8.trap
+    nvvm_suld_1d_array_v4i8_zero,              // llvm.nvvm.suld.1d.array.v4i8.zero
+    nvvm_suld_1d_i16_clamp,                    // llvm.nvvm.suld.1d.i16.clamp
+    nvvm_suld_1d_i16_trap,                     // llvm.nvvm.suld.1d.i16.trap
+    nvvm_suld_1d_i16_zero,                     // llvm.nvvm.suld.1d.i16.zero
+    nvvm_suld_1d_i32_clamp,                    // llvm.nvvm.suld.1d.i32.clamp
+    nvvm_suld_1d_i32_trap,                     // llvm.nvvm.suld.1d.i32.trap
+    nvvm_suld_1d_i32_zero,                     // llvm.nvvm.suld.1d.i32.zero
+    nvvm_suld_1d_i64_clamp,                    // llvm.nvvm.suld.1d.i64.clamp
+    nvvm_suld_1d_i64_trap,                     // llvm.nvvm.suld.1d.i64.trap
+    nvvm_suld_1d_i64_zero,                     // llvm.nvvm.suld.1d.i64.zero
+    nvvm_suld_1d_i8_clamp,                     // llvm.nvvm.suld.1d.i8.clamp
+    nvvm_suld_1d_i8_trap,                      // llvm.nvvm.suld.1d.i8.trap
+    nvvm_suld_1d_i8_zero,                      // llvm.nvvm.suld.1d.i8.zero
+    nvvm_suld_1d_v2i16_clamp,                  // llvm.nvvm.suld.1d.v2i16.clamp
+    nvvm_suld_1d_v2i16_trap,                   // llvm.nvvm.suld.1d.v2i16.trap
+    nvvm_suld_1d_v2i16_zero,                   // llvm.nvvm.suld.1d.v2i16.zero
+    nvvm_suld_1d_v2i32_clamp,                  // llvm.nvvm.suld.1d.v2i32.clamp
+    nvvm_suld_1d_v2i32_trap,                   // llvm.nvvm.suld.1d.v2i32.trap
+    nvvm_suld_1d_v2i32_zero,                   // llvm.nvvm.suld.1d.v2i32.zero
+    nvvm_suld_1d_v2i64_clamp,                  // llvm.nvvm.suld.1d.v2i64.clamp
+    nvvm_suld_1d_v2i64_trap,                   // llvm.nvvm.suld.1d.v2i64.trap
+    nvvm_suld_1d_v2i64_zero,                   // llvm.nvvm.suld.1d.v2i64.zero
+    nvvm_suld_1d_v2i8_clamp,                   // llvm.nvvm.suld.1d.v2i8.clamp
+    nvvm_suld_1d_v2i8_trap,                    // llvm.nvvm.suld.1d.v2i8.trap
+    nvvm_suld_1d_v2i8_zero,                    // llvm.nvvm.suld.1d.v2i8.zero
+    nvvm_suld_1d_v4i16_clamp,                  // llvm.nvvm.suld.1d.v4i16.clamp
+    nvvm_suld_1d_v4i16_trap,                   // llvm.nvvm.suld.1d.v4i16.trap
+    nvvm_suld_1d_v4i16_zero,                   // llvm.nvvm.suld.1d.v4i16.zero
+    nvvm_suld_1d_v4i32_clamp,                  // llvm.nvvm.suld.1d.v4i32.clamp
+    nvvm_suld_1d_v4i32_trap,                   // llvm.nvvm.suld.1d.v4i32.trap
+    nvvm_suld_1d_v4i32_zero,                   // llvm.nvvm.suld.1d.v4i32.zero
+    nvvm_suld_1d_v4i8_clamp,                   // llvm.nvvm.suld.1d.v4i8.clamp
+    nvvm_suld_1d_v4i8_trap,                    // llvm.nvvm.suld.1d.v4i8.trap
+    nvvm_suld_1d_v4i8_zero,                    // llvm.nvvm.suld.1d.v4i8.zero
+    nvvm_suld_2d_array_i16_clamp,              // llvm.nvvm.suld.2d.array.i16.clamp
+    nvvm_suld_2d_array_i16_trap,               // llvm.nvvm.suld.2d.array.i16.trap
+    nvvm_suld_2d_array_i16_zero,               // llvm.nvvm.suld.2d.array.i16.zero
+    nvvm_suld_2d_array_i32_clamp,              // llvm.nvvm.suld.2d.array.i32.clamp
+    nvvm_suld_2d_array_i32_trap,               // llvm.nvvm.suld.2d.array.i32.trap
+    nvvm_suld_2d_array_i32_zero,               // llvm.nvvm.suld.2d.array.i32.zero
+    nvvm_suld_2d_array_i64_clamp,              // llvm.nvvm.suld.2d.array.i64.clamp
+    nvvm_suld_2d_array_i64_trap,               // llvm.nvvm.suld.2d.array.i64.trap
+    nvvm_suld_2d_array_i64_zero,               // llvm.nvvm.suld.2d.array.i64.zero
+    nvvm_suld_2d_array_i8_clamp,               // llvm.nvvm.suld.2d.array.i8.clamp
+    nvvm_suld_2d_array_i8_trap,                // llvm.nvvm.suld.2d.array.i8.trap
+    nvvm_suld_2d_array_i8_zero,                // llvm.nvvm.suld.2d.array.i8.zero
+    nvvm_suld_2d_array_v2i16_clamp,            // llvm.nvvm.suld.2d.array.v2i16.clamp
+    nvvm_suld_2d_array_v2i16_trap,             // llvm.nvvm.suld.2d.array.v2i16.trap
+    nvvm_suld_2d_array_v2i16_zero,             // llvm.nvvm.suld.2d.array.v2i16.zero
+    nvvm_suld_2d_array_v2i32_clamp,            // llvm.nvvm.suld.2d.array.v2i32.clamp
+    nvvm_suld_2d_array_v2i32_trap,             // llvm.nvvm.suld.2d.array.v2i32.trap
+    nvvm_suld_2d_array_v2i32_zero,             // llvm.nvvm.suld.2d.array.v2i32.zero
+    nvvm_suld_2d_array_v2i64_clamp,            // llvm.nvvm.suld.2d.array.v2i64.clamp
+    nvvm_suld_2d_array_v2i64_trap,             // llvm.nvvm.suld.2d.array.v2i64.trap
+    nvvm_suld_2d_array_v2i64_zero,             // llvm.nvvm.suld.2d.array.v2i64.zero
+    nvvm_suld_2d_array_v2i8_clamp,             // llvm.nvvm.suld.2d.array.v2i8.clamp
+    nvvm_suld_2d_array_v2i8_trap,              // llvm.nvvm.suld.2d.array.v2i8.trap
+    nvvm_suld_2d_array_v2i8_zero,              // llvm.nvvm.suld.2d.array.v2i8.zero
+    nvvm_suld_2d_array_v4i16_clamp,            // llvm.nvvm.suld.2d.array.v4i16.clamp
+    nvvm_suld_2d_array_v4i16_trap,             // llvm.nvvm.suld.2d.array.v4i16.trap
+    nvvm_suld_2d_array_v4i16_zero,             // llvm.nvvm.suld.2d.array.v4i16.zero
+    nvvm_suld_2d_array_v4i32_clamp,            // llvm.nvvm.suld.2d.array.v4i32.clamp
+    nvvm_suld_2d_array_v4i32_trap,             // llvm.nvvm.suld.2d.array.v4i32.trap
+    nvvm_suld_2d_array_v4i32_zero,             // llvm.nvvm.suld.2d.array.v4i32.zero
+    nvvm_suld_2d_array_v4i8_clamp,             // llvm.nvvm.suld.2d.array.v4i8.clamp
+    nvvm_suld_2d_array_v4i8_trap,              // llvm.nvvm.suld.2d.array.v4i8.trap
+    nvvm_suld_2d_array_v4i8_zero,              // llvm.nvvm.suld.2d.array.v4i8.zero
+    nvvm_suld_2d_i16_clamp,                    // llvm.nvvm.suld.2d.i16.clamp
+    nvvm_suld_2d_i16_trap,                     // llvm.nvvm.suld.2d.i16.trap
+    nvvm_suld_2d_i16_zero,                     // llvm.nvvm.suld.2d.i16.zero
+    nvvm_suld_2d_i32_clamp,                    // llvm.nvvm.suld.2d.i32.clamp
+    nvvm_suld_2d_i32_trap,                     // llvm.nvvm.suld.2d.i32.trap
+    nvvm_suld_2d_i32_zero,                     // llvm.nvvm.suld.2d.i32.zero
+    nvvm_suld_2d_i64_clamp,                    // llvm.nvvm.suld.2d.i64.clamp
+    nvvm_suld_2d_i64_trap,                     // llvm.nvvm.suld.2d.i64.trap
+    nvvm_suld_2d_i64_zero,                     // llvm.nvvm.suld.2d.i64.zero
+    nvvm_suld_2d_i8_clamp,                     // llvm.nvvm.suld.2d.i8.clamp
+    nvvm_suld_2d_i8_trap,                      // llvm.nvvm.suld.2d.i8.trap
+    nvvm_suld_2d_i8_zero,                      // llvm.nvvm.suld.2d.i8.zero
+    nvvm_suld_2d_v2i16_clamp,                  // llvm.nvvm.suld.2d.v2i16.clamp
+    nvvm_suld_2d_v2i16_trap,                   // llvm.nvvm.suld.2d.v2i16.trap
+    nvvm_suld_2d_v2i16_zero,                   // llvm.nvvm.suld.2d.v2i16.zero
+    nvvm_suld_2d_v2i32_clamp,                  // llvm.nvvm.suld.2d.v2i32.clamp
+    nvvm_suld_2d_v2i32_trap,                   // llvm.nvvm.suld.2d.v2i32.trap
+    nvvm_suld_2d_v2i32_zero,                   // llvm.nvvm.suld.2d.v2i32.zero
+    nvvm_suld_2d_v2i64_clamp,                  // llvm.nvvm.suld.2d.v2i64.clamp
+    nvvm_suld_2d_v2i64_trap,                   // llvm.nvvm.suld.2d.v2i64.trap
+    nvvm_suld_2d_v2i64_zero,                   // llvm.nvvm.suld.2d.v2i64.zero
+    nvvm_suld_2d_v2i8_clamp,                   // llvm.nvvm.suld.2d.v2i8.clamp
+    nvvm_suld_2d_v2i8_trap,                    // llvm.nvvm.suld.2d.v2i8.trap
+    nvvm_suld_2d_v2i8_zero,                    // llvm.nvvm.suld.2d.v2i8.zero
+    nvvm_suld_2d_v4i16_clamp,                  // llvm.nvvm.suld.2d.v4i16.clamp
+    nvvm_suld_2d_v4i16_trap,                   // llvm.nvvm.suld.2d.v4i16.trap
+    nvvm_suld_2d_v4i16_zero,                   // llvm.nvvm.suld.2d.v4i16.zero
+    nvvm_suld_2d_v4i32_clamp,                  // llvm.nvvm.suld.2d.v4i32.clamp
+    nvvm_suld_2d_v4i32_trap,                   // llvm.nvvm.suld.2d.v4i32.trap
+    nvvm_suld_2d_v4i32_zero,                   // llvm.nvvm.suld.2d.v4i32.zero
+    nvvm_suld_2d_v4i8_clamp,                   // llvm.nvvm.suld.2d.v4i8.clamp
+    nvvm_suld_2d_v4i8_trap,                    // llvm.nvvm.suld.2d.v4i8.trap
+    nvvm_suld_2d_v4i8_zero,                    // llvm.nvvm.suld.2d.v4i8.zero
+    nvvm_suld_3d_i16_clamp,                    // llvm.nvvm.suld.3d.i16.clamp
+    nvvm_suld_3d_i16_trap,                     // llvm.nvvm.suld.3d.i16.trap
+    nvvm_suld_3d_i16_zero,                     // llvm.nvvm.suld.3d.i16.zero
+    nvvm_suld_3d_i32_clamp,                    // llvm.nvvm.suld.3d.i32.clamp
+    nvvm_suld_3d_i32_trap,                     // llvm.nvvm.suld.3d.i32.trap
+    nvvm_suld_3d_i32_zero,                     // llvm.nvvm.suld.3d.i32.zero
+    nvvm_suld_3d_i64_clamp,                    // llvm.nvvm.suld.3d.i64.clamp
+    nvvm_suld_3d_i64_trap,                     // llvm.nvvm.suld.3d.i64.trap
+    nvvm_suld_3d_i64_zero,                     // llvm.nvvm.suld.3d.i64.zero
+    nvvm_suld_3d_i8_clamp,                     // llvm.nvvm.suld.3d.i8.clamp
+    nvvm_suld_3d_i8_trap,                      // llvm.nvvm.suld.3d.i8.trap
+    nvvm_suld_3d_i8_zero,                      // llvm.nvvm.suld.3d.i8.zero
+    nvvm_suld_3d_v2i16_clamp,                  // llvm.nvvm.suld.3d.v2i16.clamp
+    nvvm_suld_3d_v2i16_trap,                   // llvm.nvvm.suld.3d.v2i16.trap
+    nvvm_suld_3d_v2i16_zero,                   // llvm.nvvm.suld.3d.v2i16.zero
+    nvvm_suld_3d_v2i32_clamp,                  // llvm.nvvm.suld.3d.v2i32.clamp
+    nvvm_suld_3d_v2i32_trap,                   // llvm.nvvm.suld.3d.v2i32.trap
+    nvvm_suld_3d_v2i32_zero,                   // llvm.nvvm.suld.3d.v2i32.zero
+    nvvm_suld_3d_v2i64_clamp,                  // llvm.nvvm.suld.3d.v2i64.clamp
+    nvvm_suld_3d_v2i64_trap,                   // llvm.nvvm.suld.3d.v2i64.trap
+    nvvm_suld_3d_v2i64_zero,                   // llvm.nvvm.suld.3d.v2i64.zero
+    nvvm_suld_3d_v2i8_clamp,                   // llvm.nvvm.suld.3d.v2i8.clamp
+    nvvm_suld_3d_v2i8_trap,                    // llvm.nvvm.suld.3d.v2i8.trap
+    nvvm_suld_3d_v2i8_zero,                    // llvm.nvvm.suld.3d.v2i8.zero
+    nvvm_suld_3d_v4i16_clamp,                  // llvm.nvvm.suld.3d.v4i16.clamp
+    nvvm_suld_3d_v4i16_trap,                   // llvm.nvvm.suld.3d.v4i16.trap
+    nvvm_suld_3d_v4i16_zero,                   // llvm.nvvm.suld.3d.v4i16.zero
+    nvvm_suld_3d_v4i32_clamp,                  // llvm.nvvm.suld.3d.v4i32.clamp
+    nvvm_suld_3d_v4i32_trap,                   // llvm.nvvm.suld.3d.v4i32.trap
+    nvvm_suld_3d_v4i32_zero,                   // llvm.nvvm.suld.3d.v4i32.zero
+    nvvm_suld_3d_v4i8_clamp,                   // llvm.nvvm.suld.3d.v4i8.clamp
+    nvvm_suld_3d_v4i8_trap,                    // llvm.nvvm.suld.3d.v4i8.trap
+    nvvm_suld_3d_v4i8_zero,                    // llvm.nvvm.suld.3d.v4i8.zero
+    nvvm_suq_array_size,                       // llvm.nvvm.suq.array.size
+    nvvm_suq_channel_data_type,                // llvm.nvvm.suq.channel.data.type
+    nvvm_suq_channel_order,                    // llvm.nvvm.suq.channel.order
+    nvvm_suq_depth,                            // llvm.nvvm.suq.depth
+    nvvm_suq_height,                           // llvm.nvvm.suq.height
+    nvvm_suq_width,                            // llvm.nvvm.suq.width
+    nvvm_sust_b_1d_array_i16_clamp,            // llvm.nvvm.sust.b.1d.array.i16.clamp
+    nvvm_sust_b_1d_array_i16_trap,             // llvm.nvvm.sust.b.1d.array.i16.trap
+    nvvm_sust_b_1d_array_i16_zero,             // llvm.nvvm.sust.b.1d.array.i16.zero
+    nvvm_sust_b_1d_array_i32_clamp,            // llvm.nvvm.sust.b.1d.array.i32.clamp
+    nvvm_sust_b_1d_array_i32_trap,             // llvm.nvvm.sust.b.1d.array.i32.trap
+    nvvm_sust_b_1d_array_i32_zero,             // llvm.nvvm.sust.b.1d.array.i32.zero
+    nvvm_sust_b_1d_array_i64_clamp,            // llvm.nvvm.sust.b.1d.array.i64.clamp
+    nvvm_sust_b_1d_array_i64_trap,             // llvm.nvvm.sust.b.1d.array.i64.trap
+    nvvm_sust_b_1d_array_i64_zero,             // llvm.nvvm.sust.b.1d.array.i64.zero
+    nvvm_sust_b_1d_array_i8_clamp,             // llvm.nvvm.sust.b.1d.array.i8.clamp
+    nvvm_sust_b_1d_array_i8_trap,              // llvm.nvvm.sust.b.1d.array.i8.trap
+    nvvm_sust_b_1d_array_i8_zero,              // llvm.nvvm.sust.b.1d.array.i8.zero
+    nvvm_sust_b_1d_array_v2i16_clamp,          // llvm.nvvm.sust.b.1d.array.v2i16.clamp
+    nvvm_sust_b_1d_array_v2i16_trap,           // llvm.nvvm.sust.b.1d.array.v2i16.trap
+    nvvm_sust_b_1d_array_v2i16_zero,           // llvm.nvvm.sust.b.1d.array.v2i16.zero
+    nvvm_sust_b_1d_array_v2i32_clamp,          // llvm.nvvm.sust.b.1d.array.v2i32.clamp
+    nvvm_sust_b_1d_array_v2i32_trap,           // llvm.nvvm.sust.b.1d.array.v2i32.trap
+    nvvm_sust_b_1d_array_v2i32_zero,           // llvm.nvvm.sust.b.1d.array.v2i32.zero
+    nvvm_sust_b_1d_array_v2i64_clamp,          // llvm.nvvm.sust.b.1d.array.v2i64.clamp
+    nvvm_sust_b_1d_array_v2i64_trap,           // llvm.nvvm.sust.b.1d.array.v2i64.trap
+    nvvm_sust_b_1d_array_v2i64_zero,           // llvm.nvvm.sust.b.1d.array.v2i64.zero
+    nvvm_sust_b_1d_array_v2i8_clamp,           // llvm.nvvm.sust.b.1d.array.v2i8.clamp
+    nvvm_sust_b_1d_array_v2i8_trap,            // llvm.nvvm.sust.b.1d.array.v2i8.trap
+    nvvm_sust_b_1d_array_v2i8_zero,            // llvm.nvvm.sust.b.1d.array.v2i8.zero
+    nvvm_sust_b_1d_array_v4i16_clamp,          // llvm.nvvm.sust.b.1d.array.v4i16.clamp
+    nvvm_sust_b_1d_array_v4i16_trap,           // llvm.nvvm.sust.b.1d.array.v4i16.trap
+    nvvm_sust_b_1d_array_v4i16_zero,           // llvm.nvvm.sust.b.1d.array.v4i16.zero
+    nvvm_sust_b_1d_array_v4i32_clamp,          // llvm.nvvm.sust.b.1d.array.v4i32.clamp
+    nvvm_sust_b_1d_array_v4i32_trap,           // llvm.nvvm.sust.b.1d.array.v4i32.trap
+    nvvm_sust_b_1d_array_v4i32_zero,           // llvm.nvvm.sust.b.1d.array.v4i32.zero
+    nvvm_sust_b_1d_array_v4i8_clamp,           // llvm.nvvm.sust.b.1d.array.v4i8.clamp
+    nvvm_sust_b_1d_array_v4i8_trap,            // llvm.nvvm.sust.b.1d.array.v4i8.trap
+    nvvm_sust_b_1d_array_v4i8_zero,            // llvm.nvvm.sust.b.1d.array.v4i8.zero
+    nvvm_sust_b_1d_i16_clamp,                  // llvm.nvvm.sust.b.1d.i16.clamp
+    nvvm_sust_b_1d_i16_trap,                   // llvm.nvvm.sust.b.1d.i16.trap
+    nvvm_sust_b_1d_i16_zero,                   // llvm.nvvm.sust.b.1d.i16.zero
+    nvvm_sust_b_1d_i32_clamp,                  // llvm.nvvm.sust.b.1d.i32.clamp
+    nvvm_sust_b_1d_i32_trap,                   // llvm.nvvm.sust.b.1d.i32.trap
+    nvvm_sust_b_1d_i32_zero,                   // llvm.nvvm.sust.b.1d.i32.zero
+    nvvm_sust_b_1d_i64_clamp,                  // llvm.nvvm.sust.b.1d.i64.clamp
+    nvvm_sust_b_1d_i64_trap,                   // llvm.nvvm.sust.b.1d.i64.trap
+    nvvm_sust_b_1d_i64_zero,                   // llvm.nvvm.sust.b.1d.i64.zero
+    nvvm_sust_b_1d_i8_clamp,                   // llvm.nvvm.sust.b.1d.i8.clamp
+    nvvm_sust_b_1d_i8_trap,                    // llvm.nvvm.sust.b.1d.i8.trap
+    nvvm_sust_b_1d_i8_zero,                    // llvm.nvvm.sust.b.1d.i8.zero
+    nvvm_sust_b_1d_v2i16_clamp,                // llvm.nvvm.sust.b.1d.v2i16.clamp
+    nvvm_sust_b_1d_v2i16_trap,                 // llvm.nvvm.sust.b.1d.v2i16.trap
+    nvvm_sust_b_1d_v2i16_zero,                 // llvm.nvvm.sust.b.1d.v2i16.zero
+    nvvm_sust_b_1d_v2i32_clamp,                // llvm.nvvm.sust.b.1d.v2i32.clamp
+    nvvm_sust_b_1d_v2i32_trap,                 // llvm.nvvm.sust.b.1d.v2i32.trap
+    nvvm_sust_b_1d_v2i32_zero,                 // llvm.nvvm.sust.b.1d.v2i32.zero
+    nvvm_sust_b_1d_v2i64_clamp,                // llvm.nvvm.sust.b.1d.v2i64.clamp
+    nvvm_sust_b_1d_v2i64_trap,                 // llvm.nvvm.sust.b.1d.v2i64.trap
+    nvvm_sust_b_1d_v2i64_zero,                 // llvm.nvvm.sust.b.1d.v2i64.zero
+    nvvm_sust_b_1d_v2i8_clamp,                 // llvm.nvvm.sust.b.1d.v2i8.clamp
+    nvvm_sust_b_1d_v2i8_trap,                  // llvm.nvvm.sust.b.1d.v2i8.trap
+    nvvm_sust_b_1d_v2i8_zero,                  // llvm.nvvm.sust.b.1d.v2i8.zero
+    nvvm_sust_b_1d_v4i16_clamp,                // llvm.nvvm.sust.b.1d.v4i16.clamp
+    nvvm_sust_b_1d_v4i16_trap,                 // llvm.nvvm.sust.b.1d.v4i16.trap
+    nvvm_sust_b_1d_v4i16_zero,                 // llvm.nvvm.sust.b.1d.v4i16.zero
+    nvvm_sust_b_1d_v4i32_clamp,                // llvm.nvvm.sust.b.1d.v4i32.clamp
+    nvvm_sust_b_1d_v4i32_trap,                 // llvm.nvvm.sust.b.1d.v4i32.trap
+    nvvm_sust_b_1d_v4i32_zero,                 // llvm.nvvm.sust.b.1d.v4i32.zero
+    nvvm_sust_b_1d_v4i8_clamp,                 // llvm.nvvm.sust.b.1d.v4i8.clamp
+    nvvm_sust_b_1d_v4i8_trap,                  // llvm.nvvm.sust.b.1d.v4i8.trap
+    nvvm_sust_b_1d_v4i8_zero,                  // llvm.nvvm.sust.b.1d.v4i8.zero
+    nvvm_sust_b_2d_array_i16_clamp,            // llvm.nvvm.sust.b.2d.array.i16.clamp
+    nvvm_sust_b_2d_array_i16_trap,             // llvm.nvvm.sust.b.2d.array.i16.trap
+    nvvm_sust_b_2d_array_i16_zero,             // llvm.nvvm.sust.b.2d.array.i16.zero
+    nvvm_sust_b_2d_array_i32_clamp,            // llvm.nvvm.sust.b.2d.array.i32.clamp
+    nvvm_sust_b_2d_array_i32_trap,             // llvm.nvvm.sust.b.2d.array.i32.trap
+    nvvm_sust_b_2d_array_i32_zero,             // llvm.nvvm.sust.b.2d.array.i32.zero
+    nvvm_sust_b_2d_array_i64_clamp,            // llvm.nvvm.sust.b.2d.array.i64.clamp
+    nvvm_sust_b_2d_array_i64_trap,             // llvm.nvvm.sust.b.2d.array.i64.trap
+    nvvm_sust_b_2d_array_i64_zero,             // llvm.nvvm.sust.b.2d.array.i64.zero
+    nvvm_sust_b_2d_array_i8_clamp,             // llvm.nvvm.sust.b.2d.array.i8.clamp
+    nvvm_sust_b_2d_array_i8_trap,              // llvm.nvvm.sust.b.2d.array.i8.trap
+    nvvm_sust_b_2d_array_i8_zero,              // llvm.nvvm.sust.b.2d.array.i8.zero
+    nvvm_sust_b_2d_array_v2i16_clamp,          // llvm.nvvm.sust.b.2d.array.v2i16.clamp
+    nvvm_sust_b_2d_array_v2i16_trap,           // llvm.nvvm.sust.b.2d.array.v2i16.trap
+    nvvm_sust_b_2d_array_v2i16_zero,           // llvm.nvvm.sust.b.2d.array.v2i16.zero
+    nvvm_sust_b_2d_array_v2i32_clamp,          // llvm.nvvm.sust.b.2d.array.v2i32.clamp
+    nvvm_sust_b_2d_array_v2i32_trap,           // llvm.nvvm.sust.b.2d.array.v2i32.trap
+    nvvm_sust_b_2d_array_v2i32_zero,           // llvm.nvvm.sust.b.2d.array.v2i32.zero
+    nvvm_sust_b_2d_array_v2i64_clamp,          // llvm.nvvm.sust.b.2d.array.v2i64.clamp
+    nvvm_sust_b_2d_array_v2i64_trap,           // llvm.nvvm.sust.b.2d.array.v2i64.trap
+    nvvm_sust_b_2d_array_v2i64_zero,           // llvm.nvvm.sust.b.2d.array.v2i64.zero
+    nvvm_sust_b_2d_array_v2i8_clamp,           // llvm.nvvm.sust.b.2d.array.v2i8.clamp
+    nvvm_sust_b_2d_array_v2i8_trap,            // llvm.nvvm.sust.b.2d.array.v2i8.trap
+    nvvm_sust_b_2d_array_v2i8_zero,            // llvm.nvvm.sust.b.2d.array.v2i8.zero
+    nvvm_sust_b_2d_array_v4i16_clamp,          // llvm.nvvm.sust.b.2d.array.v4i16.clamp
+    nvvm_sust_b_2d_array_v4i16_trap,           // llvm.nvvm.sust.b.2d.array.v4i16.trap
+    nvvm_sust_b_2d_array_v4i16_zero,           // llvm.nvvm.sust.b.2d.array.v4i16.zero
+    nvvm_sust_b_2d_array_v4i32_clamp,          // llvm.nvvm.sust.b.2d.array.v4i32.clamp
+    nvvm_sust_b_2d_array_v4i32_trap,           // llvm.nvvm.sust.b.2d.array.v4i32.trap
+    nvvm_sust_b_2d_array_v4i32_zero,           // llvm.nvvm.sust.b.2d.array.v4i32.zero
+    nvvm_sust_b_2d_array_v4i8_clamp,           // llvm.nvvm.sust.b.2d.array.v4i8.clamp
+    nvvm_sust_b_2d_array_v4i8_trap,            // llvm.nvvm.sust.b.2d.array.v4i8.trap
+    nvvm_sust_b_2d_array_v4i8_zero,            // llvm.nvvm.sust.b.2d.array.v4i8.zero
+    nvvm_sust_b_2d_i16_clamp,                  // llvm.nvvm.sust.b.2d.i16.clamp
+    nvvm_sust_b_2d_i16_trap,                   // llvm.nvvm.sust.b.2d.i16.trap
+    nvvm_sust_b_2d_i16_zero,                   // llvm.nvvm.sust.b.2d.i16.zero
+    nvvm_sust_b_2d_i32_clamp,                  // llvm.nvvm.sust.b.2d.i32.clamp
+    nvvm_sust_b_2d_i32_trap,                   // llvm.nvvm.sust.b.2d.i32.trap
+    nvvm_sust_b_2d_i32_zero,                   // llvm.nvvm.sust.b.2d.i32.zero
+    nvvm_sust_b_2d_i64_clamp,                  // llvm.nvvm.sust.b.2d.i64.clamp
+    nvvm_sust_b_2d_i64_trap,                   // llvm.nvvm.sust.b.2d.i64.trap
+    nvvm_sust_b_2d_i64_zero,                   // llvm.nvvm.sust.b.2d.i64.zero
+    nvvm_sust_b_2d_i8_clamp,                   // llvm.nvvm.sust.b.2d.i8.clamp
+    nvvm_sust_b_2d_i8_trap,                    // llvm.nvvm.sust.b.2d.i8.trap
+    nvvm_sust_b_2d_i8_zero,                    // llvm.nvvm.sust.b.2d.i8.zero
+    nvvm_sust_b_2d_v2i16_clamp,                // llvm.nvvm.sust.b.2d.v2i16.clamp
+    nvvm_sust_b_2d_v2i16_trap,                 // llvm.nvvm.sust.b.2d.v2i16.trap
+    nvvm_sust_b_2d_v2i16_zero,                 // llvm.nvvm.sust.b.2d.v2i16.zero
+    nvvm_sust_b_2d_v2i32_clamp,                // llvm.nvvm.sust.b.2d.v2i32.clamp
+    nvvm_sust_b_2d_v2i32_trap,                 // llvm.nvvm.sust.b.2d.v2i32.trap
+    nvvm_sust_b_2d_v2i32_zero,                 // llvm.nvvm.sust.b.2d.v2i32.zero
+    nvvm_sust_b_2d_v2i64_clamp,                // llvm.nvvm.sust.b.2d.v2i64.clamp
+    nvvm_sust_b_2d_v2i64_trap,                 // llvm.nvvm.sust.b.2d.v2i64.trap
+    nvvm_sust_b_2d_v2i64_zero,                 // llvm.nvvm.sust.b.2d.v2i64.zero
+    nvvm_sust_b_2d_v2i8_clamp,                 // llvm.nvvm.sust.b.2d.v2i8.clamp
+    nvvm_sust_b_2d_v2i8_trap,                  // llvm.nvvm.sust.b.2d.v2i8.trap
+    nvvm_sust_b_2d_v2i8_zero,                  // llvm.nvvm.sust.b.2d.v2i8.zero
+    nvvm_sust_b_2d_v4i16_clamp,                // llvm.nvvm.sust.b.2d.v4i16.clamp
+    nvvm_sust_b_2d_v4i16_trap,                 // llvm.nvvm.sust.b.2d.v4i16.trap
+    nvvm_sust_b_2d_v4i16_zero,                 // llvm.nvvm.sust.b.2d.v4i16.zero
+    nvvm_sust_b_2d_v4i32_clamp,                // llvm.nvvm.sust.b.2d.v4i32.clamp
+    nvvm_sust_b_2d_v4i32_trap,                 // llvm.nvvm.sust.b.2d.v4i32.trap
+    nvvm_sust_b_2d_v4i32_zero,                 // llvm.nvvm.sust.b.2d.v4i32.zero
+    nvvm_sust_b_2d_v4i8_clamp,                 // llvm.nvvm.sust.b.2d.v4i8.clamp
+    nvvm_sust_b_2d_v4i8_trap,                  // llvm.nvvm.sust.b.2d.v4i8.trap
+    nvvm_sust_b_2d_v4i8_zero,                  // llvm.nvvm.sust.b.2d.v4i8.zero
+    nvvm_sust_b_3d_i16_clamp,                  // llvm.nvvm.sust.b.3d.i16.clamp
+    nvvm_sust_b_3d_i16_trap,                   // llvm.nvvm.sust.b.3d.i16.trap
+    nvvm_sust_b_3d_i16_zero,                   // llvm.nvvm.sust.b.3d.i16.zero
+    nvvm_sust_b_3d_i32_clamp,                  // llvm.nvvm.sust.b.3d.i32.clamp
+    nvvm_sust_b_3d_i32_trap,                   // llvm.nvvm.sust.b.3d.i32.trap
+    nvvm_sust_b_3d_i32_zero,                   // llvm.nvvm.sust.b.3d.i32.zero
+    nvvm_sust_b_3d_i64_clamp,                  // llvm.nvvm.sust.b.3d.i64.clamp
+    nvvm_sust_b_3d_i64_trap,                   // llvm.nvvm.sust.b.3d.i64.trap
+    nvvm_sust_b_3d_i64_zero,                   // llvm.nvvm.sust.b.3d.i64.zero
+    nvvm_sust_b_3d_i8_clamp,                   // llvm.nvvm.sust.b.3d.i8.clamp
+    nvvm_sust_b_3d_i8_trap,                    // llvm.nvvm.sust.b.3d.i8.trap
+    nvvm_sust_b_3d_i8_zero,                    // llvm.nvvm.sust.b.3d.i8.zero
+    nvvm_sust_b_3d_v2i16_clamp,                // llvm.nvvm.sust.b.3d.v2i16.clamp
+    nvvm_sust_b_3d_v2i16_trap,                 // llvm.nvvm.sust.b.3d.v2i16.trap
+    nvvm_sust_b_3d_v2i16_zero,                 // llvm.nvvm.sust.b.3d.v2i16.zero
+    nvvm_sust_b_3d_v2i32_clamp,                // llvm.nvvm.sust.b.3d.v2i32.clamp
+    nvvm_sust_b_3d_v2i32_trap,                 // llvm.nvvm.sust.b.3d.v2i32.trap
+    nvvm_sust_b_3d_v2i32_zero,                 // llvm.nvvm.sust.b.3d.v2i32.zero
+    nvvm_sust_b_3d_v2i64_clamp,                // llvm.nvvm.sust.b.3d.v2i64.clamp
+    nvvm_sust_b_3d_v2i64_trap,                 // llvm.nvvm.sust.b.3d.v2i64.trap
+    nvvm_sust_b_3d_v2i64_zero,                 // llvm.nvvm.sust.b.3d.v2i64.zero
+    nvvm_sust_b_3d_v2i8_clamp,                 // llvm.nvvm.sust.b.3d.v2i8.clamp
+    nvvm_sust_b_3d_v2i8_trap,                  // llvm.nvvm.sust.b.3d.v2i8.trap
+    nvvm_sust_b_3d_v2i8_zero,                  // llvm.nvvm.sust.b.3d.v2i8.zero
+    nvvm_sust_b_3d_v4i16_clamp,                // llvm.nvvm.sust.b.3d.v4i16.clamp
+    nvvm_sust_b_3d_v4i16_trap,                 // llvm.nvvm.sust.b.3d.v4i16.trap
+    nvvm_sust_b_3d_v4i16_zero,                 // llvm.nvvm.sust.b.3d.v4i16.zero
+    nvvm_sust_b_3d_v4i32_clamp,                // llvm.nvvm.sust.b.3d.v4i32.clamp
+    nvvm_sust_b_3d_v4i32_trap,                 // llvm.nvvm.sust.b.3d.v4i32.trap
+    nvvm_sust_b_3d_v4i32_zero,                 // llvm.nvvm.sust.b.3d.v4i32.zero
+    nvvm_sust_b_3d_v4i8_clamp,                 // llvm.nvvm.sust.b.3d.v4i8.clamp
+    nvvm_sust_b_3d_v4i8_trap,                  // llvm.nvvm.sust.b.3d.v4i8.trap
+    nvvm_sust_b_3d_v4i8_zero,                  // llvm.nvvm.sust.b.3d.v4i8.zero
+    nvvm_sust_p_1d_array_i16_trap,             // llvm.nvvm.sust.p.1d.array.i16.trap
+    nvvm_sust_p_1d_array_i32_trap,             // llvm.nvvm.sust.p.1d.array.i32.trap
+    nvvm_sust_p_1d_array_i8_trap,              // llvm.nvvm.sust.p.1d.array.i8.trap
+    nvvm_sust_p_1d_array_v2i16_trap,           // llvm.nvvm.sust.p.1d.array.v2i16.trap
+    nvvm_sust_p_1d_array_v2i32_trap,           // llvm.nvvm.sust.p.1d.array.v2i32.trap
+    nvvm_sust_p_1d_array_v2i8_trap,            // llvm.nvvm.sust.p.1d.array.v2i8.trap
+    nvvm_sust_p_1d_array_v4i16_trap,           // llvm.nvvm.sust.p.1d.array.v4i16.trap
+    nvvm_sust_p_1d_array_v4i32_trap,           // llvm.nvvm.sust.p.1d.array.v4i32.trap
+    nvvm_sust_p_1d_array_v4i8_trap,            // llvm.nvvm.sust.p.1d.array.v4i8.trap
+    nvvm_sust_p_1d_i16_trap,                   // llvm.nvvm.sust.p.1d.i16.trap
+    nvvm_sust_p_1d_i32_trap,                   // llvm.nvvm.sust.p.1d.i32.trap
+    nvvm_sust_p_1d_i8_trap,                    // llvm.nvvm.sust.p.1d.i8.trap
+    nvvm_sust_p_1d_v2i16_trap,                 // llvm.nvvm.sust.p.1d.v2i16.trap
+    nvvm_sust_p_1d_v2i32_trap,                 // llvm.nvvm.sust.p.1d.v2i32.trap
+    nvvm_sust_p_1d_v2i8_trap,                  // llvm.nvvm.sust.p.1d.v2i8.trap
+    nvvm_sust_p_1d_v4i16_trap,                 // llvm.nvvm.sust.p.1d.v4i16.trap
+    nvvm_sust_p_1d_v4i32_trap,                 // llvm.nvvm.sust.p.1d.v4i32.trap
+    nvvm_sust_p_1d_v4i8_trap,                  // llvm.nvvm.sust.p.1d.v4i8.trap
+    nvvm_sust_p_2d_array_i16_trap,             // llvm.nvvm.sust.p.2d.array.i16.trap
+    nvvm_sust_p_2d_array_i32_trap,             // llvm.nvvm.sust.p.2d.array.i32.trap
+    nvvm_sust_p_2d_array_i8_trap,              // llvm.nvvm.sust.p.2d.array.i8.trap
+    nvvm_sust_p_2d_array_v2i16_trap,           // llvm.nvvm.sust.p.2d.array.v2i16.trap
+    nvvm_sust_p_2d_array_v2i32_trap,           // llvm.nvvm.sust.p.2d.array.v2i32.trap
+    nvvm_sust_p_2d_array_v2i8_trap,            // llvm.nvvm.sust.p.2d.array.v2i8.trap
+    nvvm_sust_p_2d_array_v4i16_trap,           // llvm.nvvm.sust.p.2d.array.v4i16.trap
+    nvvm_sust_p_2d_array_v4i32_trap,           // llvm.nvvm.sust.p.2d.array.v4i32.trap
+    nvvm_sust_p_2d_array_v4i8_trap,            // llvm.nvvm.sust.p.2d.array.v4i8.trap
+    nvvm_sust_p_2d_i16_trap,                   // llvm.nvvm.sust.p.2d.i16.trap
+    nvvm_sust_p_2d_i32_trap,                   // llvm.nvvm.sust.p.2d.i32.trap
+    nvvm_sust_p_2d_i8_trap,                    // llvm.nvvm.sust.p.2d.i8.trap
+    nvvm_sust_p_2d_v2i16_trap,                 // llvm.nvvm.sust.p.2d.v2i16.trap
+    nvvm_sust_p_2d_v2i32_trap,                 // llvm.nvvm.sust.p.2d.v2i32.trap
+    nvvm_sust_p_2d_v2i8_trap,                  // llvm.nvvm.sust.p.2d.v2i8.trap
+    nvvm_sust_p_2d_v4i16_trap,                 // llvm.nvvm.sust.p.2d.v4i16.trap
+    nvvm_sust_p_2d_v4i32_trap,                 // llvm.nvvm.sust.p.2d.v4i32.trap
+    nvvm_sust_p_2d_v4i8_trap,                  // llvm.nvvm.sust.p.2d.v4i8.trap
+    nvvm_sust_p_3d_i16_trap,                   // llvm.nvvm.sust.p.3d.i16.trap
+    nvvm_sust_p_3d_i32_trap,                   // llvm.nvvm.sust.p.3d.i32.trap
+    nvvm_sust_p_3d_i8_trap,                    // llvm.nvvm.sust.p.3d.i8.trap
+    nvvm_sust_p_3d_v2i16_trap,                 // llvm.nvvm.sust.p.3d.v2i16.trap
+    nvvm_sust_p_3d_v2i32_trap,                 // llvm.nvvm.sust.p.3d.v2i32.trap
+    nvvm_sust_p_3d_v2i8_trap,                  // llvm.nvvm.sust.p.3d.v2i8.trap
+    nvvm_sust_p_3d_v4i16_trap,                 // llvm.nvvm.sust.p.3d.v4i16.trap
+    nvvm_sust_p_3d_v4i32_trap,                 // llvm.nvvm.sust.p.3d.v4i32.trap
+    nvvm_sust_p_3d_v4i8_trap,                  // llvm.nvvm.sust.p.3d.v4i8.trap
+    nvvm_swap_lo_hi_b64,                       // llvm.nvvm.swap.lo.hi.b64
+    nvvm_tex_1d_array_grad_v4f32_f32,          // llvm.nvvm.tex.1d.array.grad.v4f32.f32
+    nvvm_tex_1d_array_grad_v4s32_f32,          // llvm.nvvm.tex.1d.array.grad.v4s32.f32
+    nvvm_tex_1d_array_grad_v4u32_f32,          // llvm.nvvm.tex.1d.array.grad.v4u32.f32
+    nvvm_tex_1d_array_level_v4f32_f32,         // llvm.nvvm.tex.1d.array.level.v4f32.f32
+    nvvm_tex_1d_array_level_v4s32_f32,         // llvm.nvvm.tex.1d.array.level.v4s32.f32
+    nvvm_tex_1d_array_level_v4u32_f32,         // llvm.nvvm.tex.1d.array.level.v4u32.f32
+    nvvm_tex_1d_array_v4f32_f32,               // llvm.nvvm.tex.1d.array.v4f32.f32
+    nvvm_tex_1d_array_v4f32_s32,               // llvm.nvvm.tex.1d.array.v4f32.s32
+    nvvm_tex_1d_array_v4s32_f32,               // llvm.nvvm.tex.1d.array.v4s32.f32
+    nvvm_tex_1d_array_v4s32_s32,               // llvm.nvvm.tex.1d.array.v4s32.s32
+    nvvm_tex_1d_array_v4u32_f32,               // llvm.nvvm.tex.1d.array.v4u32.f32
+    nvvm_tex_1d_array_v4u32_s32,               // llvm.nvvm.tex.1d.array.v4u32.s32
+    nvvm_tex_1d_grad_v4f32_f32,                // llvm.nvvm.tex.1d.grad.v4f32.f32
+    nvvm_tex_1d_grad_v4s32_f32,                // llvm.nvvm.tex.1d.grad.v4s32.f32
+    nvvm_tex_1d_grad_v4u32_f32,                // llvm.nvvm.tex.1d.grad.v4u32.f32
+    nvvm_tex_1d_level_v4f32_f32,               // llvm.nvvm.tex.1d.level.v4f32.f32
+    nvvm_tex_1d_level_v4s32_f32,               // llvm.nvvm.tex.1d.level.v4s32.f32
+    nvvm_tex_1d_level_v4u32_f32,               // llvm.nvvm.tex.1d.level.v4u32.f32
+    nvvm_tex_1d_v4f32_f32,                     // llvm.nvvm.tex.1d.v4f32.f32
+    nvvm_tex_1d_v4f32_s32,                     // llvm.nvvm.tex.1d.v4f32.s32
+    nvvm_tex_1d_v4s32_f32,                     // llvm.nvvm.tex.1d.v4s32.f32
+    nvvm_tex_1d_v4s32_s32,                     // llvm.nvvm.tex.1d.v4s32.s32
+    nvvm_tex_1d_v4u32_f32,                     // llvm.nvvm.tex.1d.v4u32.f32
+    nvvm_tex_1d_v4u32_s32,                     // llvm.nvvm.tex.1d.v4u32.s32
+    nvvm_tex_2d_array_grad_v4f32_f32,          // llvm.nvvm.tex.2d.array.grad.v4f32.f32
+    nvvm_tex_2d_array_grad_v4s32_f32,          // llvm.nvvm.tex.2d.array.grad.v4s32.f32
+    nvvm_tex_2d_array_grad_v4u32_f32,          // llvm.nvvm.tex.2d.array.grad.v4u32.f32
+    nvvm_tex_2d_array_level_v4f32_f32,         // llvm.nvvm.tex.2d.array.level.v4f32.f32
+    nvvm_tex_2d_array_level_v4s32_f32,         // llvm.nvvm.tex.2d.array.level.v4s32.f32
+    nvvm_tex_2d_array_level_v4u32_f32,         // llvm.nvvm.tex.2d.array.level.v4u32.f32
+    nvvm_tex_2d_array_v4f32_f32,               // llvm.nvvm.tex.2d.array.v4f32.f32
+    nvvm_tex_2d_array_v4f32_s32,               // llvm.nvvm.tex.2d.array.v4f32.s32
+    nvvm_tex_2d_array_v4s32_f32,               // llvm.nvvm.tex.2d.array.v4s32.f32
+    nvvm_tex_2d_array_v4s32_s32,               // llvm.nvvm.tex.2d.array.v4s32.s32
+    nvvm_tex_2d_array_v4u32_f32,               // llvm.nvvm.tex.2d.array.v4u32.f32
+    nvvm_tex_2d_array_v4u32_s32,               // llvm.nvvm.tex.2d.array.v4u32.s32
+    nvvm_tex_2d_grad_v4f32_f32,                // llvm.nvvm.tex.2d.grad.v4f32.f32
+    nvvm_tex_2d_grad_v4s32_f32,                // llvm.nvvm.tex.2d.grad.v4s32.f32
+    nvvm_tex_2d_grad_v4u32_f32,                // llvm.nvvm.tex.2d.grad.v4u32.f32
+    nvvm_tex_2d_level_v4f32_f32,               // llvm.nvvm.tex.2d.level.v4f32.f32
+    nvvm_tex_2d_level_v4s32_f32,               // llvm.nvvm.tex.2d.level.v4s32.f32
+    nvvm_tex_2d_level_v4u32_f32,               // llvm.nvvm.tex.2d.level.v4u32.f32
+    nvvm_tex_2d_v4f32_f32,                     // llvm.nvvm.tex.2d.v4f32.f32
+    nvvm_tex_2d_v4f32_s32,                     // llvm.nvvm.tex.2d.v4f32.s32
+    nvvm_tex_2d_v4s32_f32,                     // llvm.nvvm.tex.2d.v4s32.f32
+    nvvm_tex_2d_v4s32_s32,                     // llvm.nvvm.tex.2d.v4s32.s32
+    nvvm_tex_2d_v4u32_f32,                     // llvm.nvvm.tex.2d.v4u32.f32
+    nvvm_tex_2d_v4u32_s32,                     // llvm.nvvm.tex.2d.v4u32.s32
+    nvvm_tex_3d_grad_v4f32_f32,                // llvm.nvvm.tex.3d.grad.v4f32.f32
+    nvvm_tex_3d_grad_v4s32_f32,                // llvm.nvvm.tex.3d.grad.v4s32.f32
+    nvvm_tex_3d_grad_v4u32_f32,                // llvm.nvvm.tex.3d.grad.v4u32.f32
+    nvvm_tex_3d_level_v4f32_f32,               // llvm.nvvm.tex.3d.level.v4f32.f32
+    nvvm_tex_3d_level_v4s32_f32,               // llvm.nvvm.tex.3d.level.v4s32.f32
+    nvvm_tex_3d_level_v4u32_f32,               // llvm.nvvm.tex.3d.level.v4u32.f32
+    nvvm_tex_3d_v4f32_f32,                     // llvm.nvvm.tex.3d.v4f32.f32
+    nvvm_tex_3d_v4f32_s32,                     // llvm.nvvm.tex.3d.v4f32.s32
+    nvvm_tex_3d_v4s32_f32,                     // llvm.nvvm.tex.3d.v4s32.f32
+    nvvm_tex_3d_v4s32_s32,                     // llvm.nvvm.tex.3d.v4s32.s32
+    nvvm_tex_3d_v4u32_f32,                     // llvm.nvvm.tex.3d.v4u32.f32
+    nvvm_tex_3d_v4u32_s32,                     // llvm.nvvm.tex.3d.v4u32.s32
+    nvvm_tex_cube_array_level_v4f32_f32,       // llvm.nvvm.tex.cube.array.level.v4f32.f32
+    nvvm_tex_cube_array_level_v4s32_f32,       // llvm.nvvm.tex.cube.array.level.v4s32.f32
+    nvvm_tex_cube_array_level_v4u32_f32,       // llvm.nvvm.tex.cube.array.level.v4u32.f32
+    nvvm_tex_cube_array_v4f32_f32,             // llvm.nvvm.tex.cube.array.v4f32.f32
+    nvvm_tex_cube_array_v4s32_f32,             // llvm.nvvm.tex.cube.array.v4s32.f32
+    nvvm_tex_cube_array_v4u32_f32,             // llvm.nvvm.tex.cube.array.v4u32.f32
+    nvvm_tex_cube_level_v4f32_f32,             // llvm.nvvm.tex.cube.level.v4f32.f32
+    nvvm_tex_cube_level_v4s32_f32,             // llvm.nvvm.tex.cube.level.v4s32.f32
+    nvvm_tex_cube_level_v4u32_f32,             // llvm.nvvm.tex.cube.level.v4u32.f32
+    nvvm_tex_cube_v4f32_f32,                   // llvm.nvvm.tex.cube.v4f32.f32
+    nvvm_tex_cube_v4s32_f32,                   // llvm.nvvm.tex.cube.v4s32.f32
+    nvvm_tex_cube_v4u32_f32,                   // llvm.nvvm.tex.cube.v4u32.f32
+    nvvm_tex_unified_1d_array_grad_v4f32_f32,  // llvm.nvvm.tex.unified.1d.array.grad.v4f32.f32
+    nvvm_tex_unified_1d_array_grad_v4s32_f32,  // llvm.nvvm.tex.unified.1d.array.grad.v4s32.f32
+    nvvm_tex_unified_1d_array_grad_v4u32_f32,  // llvm.nvvm.tex.unified.1d.array.grad.v4u32.f32
+    nvvm_tex_unified_1d_array_level_v4f32_f32,  // llvm.nvvm.tex.unified.1d.array.level.v4f32.f32
+    nvvm_tex_unified_1d_array_level_v4s32_f32,  // llvm.nvvm.tex.unified.1d.array.level.v4s32.f32
+    nvvm_tex_unified_1d_array_level_v4u32_f32,  // llvm.nvvm.tex.unified.1d.array.level.v4u32.f32
+    nvvm_tex_unified_1d_array_v4f32_f32,       // llvm.nvvm.tex.unified.1d.array.v4f32.f32
+    nvvm_tex_unified_1d_array_v4f32_s32,       // llvm.nvvm.tex.unified.1d.array.v4f32.s32
+    nvvm_tex_unified_1d_array_v4s32_f32,       // llvm.nvvm.tex.unified.1d.array.v4s32.f32
+    nvvm_tex_unified_1d_array_v4s32_s32,       // llvm.nvvm.tex.unified.1d.array.v4s32.s32
+    nvvm_tex_unified_1d_array_v4u32_f32,       // llvm.nvvm.tex.unified.1d.array.v4u32.f32
+    nvvm_tex_unified_1d_array_v4u32_s32,       // llvm.nvvm.tex.unified.1d.array.v4u32.s32
+    nvvm_tex_unified_1d_grad_v4f32_f32,        // llvm.nvvm.tex.unified.1d.grad.v4f32.f32
+    nvvm_tex_unified_1d_grad_v4s32_f32,        // llvm.nvvm.tex.unified.1d.grad.v4s32.f32
+    nvvm_tex_unified_1d_grad_v4u32_f32,        // llvm.nvvm.tex.unified.1d.grad.v4u32.f32
+    nvvm_tex_unified_1d_level_v4f32_f32,       // llvm.nvvm.tex.unified.1d.level.v4f32.f32
+    nvvm_tex_unified_1d_level_v4s32_f32,       // llvm.nvvm.tex.unified.1d.level.v4s32.f32
+    nvvm_tex_unified_1d_level_v4u32_f32,       // llvm.nvvm.tex.unified.1d.level.v4u32.f32
+    nvvm_tex_unified_1d_v4f32_f32,             // llvm.nvvm.tex.unified.1d.v4f32.f32
+    nvvm_tex_unified_1d_v4f32_s32,             // llvm.nvvm.tex.unified.1d.v4f32.s32
+    nvvm_tex_unified_1d_v4s32_f32,             // llvm.nvvm.tex.unified.1d.v4s32.f32
+    nvvm_tex_unified_1d_v4s32_s32,             // llvm.nvvm.tex.unified.1d.v4s32.s32
+    nvvm_tex_unified_1d_v4u32_f32,             // llvm.nvvm.tex.unified.1d.v4u32.f32
+    nvvm_tex_unified_1d_v4u32_s32,             // llvm.nvvm.tex.unified.1d.v4u32.s32
+    nvvm_tex_unified_2d_array_grad_v4f32_f32,  // llvm.nvvm.tex.unified.2d.array.grad.v4f32.f32
+    nvvm_tex_unified_2d_array_grad_v4s32_f32,  // llvm.nvvm.tex.unified.2d.array.grad.v4s32.f32
+    nvvm_tex_unified_2d_array_grad_v4u32_f32,  // llvm.nvvm.tex.unified.2d.array.grad.v4u32.f32
+    nvvm_tex_unified_2d_array_level_v4f32_f32,  // llvm.nvvm.tex.unified.2d.array.level.v4f32.f32
+    nvvm_tex_unified_2d_array_level_v4s32_f32,  // llvm.nvvm.tex.unified.2d.array.level.v4s32.f32
+    nvvm_tex_unified_2d_array_level_v4u32_f32,  // llvm.nvvm.tex.unified.2d.array.level.v4u32.f32
+    nvvm_tex_unified_2d_array_v4f32_f32,       // llvm.nvvm.tex.unified.2d.array.v4f32.f32
+    nvvm_tex_unified_2d_array_v4f32_s32,       // llvm.nvvm.tex.unified.2d.array.v4f32.s32
+    nvvm_tex_unified_2d_array_v4s32_f32,       // llvm.nvvm.tex.unified.2d.array.v4s32.f32
+    nvvm_tex_unified_2d_array_v4s32_s32,       // llvm.nvvm.tex.unified.2d.array.v4s32.s32
+    nvvm_tex_unified_2d_array_v4u32_f32,       // llvm.nvvm.tex.unified.2d.array.v4u32.f32
+    nvvm_tex_unified_2d_array_v4u32_s32,       // llvm.nvvm.tex.unified.2d.array.v4u32.s32
+    nvvm_tex_unified_2d_grad_v4f32_f32,        // llvm.nvvm.tex.unified.2d.grad.v4f32.f32
+    nvvm_tex_unified_2d_grad_v4s32_f32,        // llvm.nvvm.tex.unified.2d.grad.v4s32.f32
+    nvvm_tex_unified_2d_grad_v4u32_f32,        // llvm.nvvm.tex.unified.2d.grad.v4u32.f32
+    nvvm_tex_unified_2d_level_v4f32_f32,       // llvm.nvvm.tex.unified.2d.level.v4f32.f32
+    nvvm_tex_unified_2d_level_v4s32_f32,       // llvm.nvvm.tex.unified.2d.level.v4s32.f32
+    nvvm_tex_unified_2d_level_v4u32_f32,       // llvm.nvvm.tex.unified.2d.level.v4u32.f32
+    nvvm_tex_unified_2d_v4f32_f32,             // llvm.nvvm.tex.unified.2d.v4f32.f32
+    nvvm_tex_unified_2d_v4f32_s32,             // llvm.nvvm.tex.unified.2d.v4f32.s32
+    nvvm_tex_unified_2d_v4s32_f32,             // llvm.nvvm.tex.unified.2d.v4s32.f32
+    nvvm_tex_unified_2d_v4s32_s32,             // llvm.nvvm.tex.unified.2d.v4s32.s32
+    nvvm_tex_unified_2d_v4u32_f32,             // llvm.nvvm.tex.unified.2d.v4u32.f32
+    nvvm_tex_unified_2d_v4u32_s32,             // llvm.nvvm.tex.unified.2d.v4u32.s32
+    nvvm_tex_unified_3d_grad_v4f32_f32,        // llvm.nvvm.tex.unified.3d.grad.v4f32.f32
+    nvvm_tex_unified_3d_grad_v4s32_f32,        // llvm.nvvm.tex.unified.3d.grad.v4s32.f32
+    nvvm_tex_unified_3d_grad_v4u32_f32,        // llvm.nvvm.tex.unified.3d.grad.v4u32.f32
+    nvvm_tex_unified_3d_level_v4f32_f32,       // llvm.nvvm.tex.unified.3d.level.v4f32.f32
+    nvvm_tex_unified_3d_level_v4s32_f32,       // llvm.nvvm.tex.unified.3d.level.v4s32.f32
+    nvvm_tex_unified_3d_level_v4u32_f32,       // llvm.nvvm.tex.unified.3d.level.v4u32.f32
+    nvvm_tex_unified_3d_v4f32_f32,             // llvm.nvvm.tex.unified.3d.v4f32.f32
+    nvvm_tex_unified_3d_v4f32_s32,             // llvm.nvvm.tex.unified.3d.v4f32.s32
+    nvvm_tex_unified_3d_v4s32_f32,             // llvm.nvvm.tex.unified.3d.v4s32.f32
+    nvvm_tex_unified_3d_v4s32_s32,             // llvm.nvvm.tex.unified.3d.v4s32.s32
+    nvvm_tex_unified_3d_v4u32_f32,             // llvm.nvvm.tex.unified.3d.v4u32.f32
+    nvvm_tex_unified_3d_v4u32_s32,             // llvm.nvvm.tex.unified.3d.v4u32.s32
+    nvvm_tex_unified_cube_array_level_v4f32_f32,  // llvm.nvvm.tex.unified.cube.array.level.v4f32.f32
+    nvvm_tex_unified_cube_array_level_v4s32_f32,  // llvm.nvvm.tex.unified.cube.array.level.v4s32.f32
+    nvvm_tex_unified_cube_array_level_v4u32_f32,  // llvm.nvvm.tex.unified.cube.array.level.v4u32.f32
+    nvvm_tex_unified_cube_array_v4f32_f32,     // llvm.nvvm.tex.unified.cube.array.v4f32.f32
+    nvvm_tex_unified_cube_array_v4s32_f32,     // llvm.nvvm.tex.unified.cube.array.v4s32.f32
+    nvvm_tex_unified_cube_array_v4u32_f32,     // llvm.nvvm.tex.unified.cube.array.v4u32.f32
+    nvvm_tex_unified_cube_level_v4f32_f32,     // llvm.nvvm.tex.unified.cube.level.v4f32.f32
+    nvvm_tex_unified_cube_level_v4s32_f32,     // llvm.nvvm.tex.unified.cube.level.v4s32.f32
+    nvvm_tex_unified_cube_level_v4u32_f32,     // llvm.nvvm.tex.unified.cube.level.v4u32.f32
+    nvvm_tex_unified_cube_v4f32_f32,           // llvm.nvvm.tex.unified.cube.v4f32.f32
+    nvvm_tex_unified_cube_v4s32_f32,           // llvm.nvvm.tex.unified.cube.v4s32.f32
+    nvvm_tex_unified_cube_v4u32_f32,           // llvm.nvvm.tex.unified.cube.v4u32.f32
+    nvvm_texsurf_handle,                       // llvm.nvvm.texsurf.handle
+    nvvm_texsurf_handle_internal,              // llvm.nvvm.texsurf.handle.internal
+    nvvm_tld4_a_2d_v4f32_f32,                  // llvm.nvvm.tld4.a.2d.v4f32.f32
+    nvvm_tld4_a_2d_v4s32_f32,                  // llvm.nvvm.tld4.a.2d.v4s32.f32
+    nvvm_tld4_a_2d_v4u32_f32,                  // llvm.nvvm.tld4.a.2d.v4u32.f32
+    nvvm_tld4_b_2d_v4f32_f32,                  // llvm.nvvm.tld4.b.2d.v4f32.f32
+    nvvm_tld4_b_2d_v4s32_f32,                  // llvm.nvvm.tld4.b.2d.v4s32.f32
+    nvvm_tld4_b_2d_v4u32_f32,                  // llvm.nvvm.tld4.b.2d.v4u32.f32
+    nvvm_tld4_g_2d_v4f32_f32,                  // llvm.nvvm.tld4.g.2d.v4f32.f32
+    nvvm_tld4_g_2d_v4s32_f32,                  // llvm.nvvm.tld4.g.2d.v4s32.f32
+    nvvm_tld4_g_2d_v4u32_f32,                  // llvm.nvvm.tld4.g.2d.v4u32.f32
+    nvvm_tld4_r_2d_v4f32_f32,                  // llvm.nvvm.tld4.r.2d.v4f32.f32
+    nvvm_tld4_r_2d_v4s32_f32,                  // llvm.nvvm.tld4.r.2d.v4s32.f32
+    nvvm_tld4_r_2d_v4u32_f32,                  // llvm.nvvm.tld4.r.2d.v4u32.f32
+    nvvm_tld4_unified_a_2d_v4f32_f32,          // llvm.nvvm.tld4.unified.a.2d.v4f32.f32
+    nvvm_tld4_unified_a_2d_v4s32_f32,          // llvm.nvvm.tld4.unified.a.2d.v4s32.f32
+    nvvm_tld4_unified_a_2d_v4u32_f32,          // llvm.nvvm.tld4.unified.a.2d.v4u32.f32
+    nvvm_tld4_unified_b_2d_v4f32_f32,          // llvm.nvvm.tld4.unified.b.2d.v4f32.f32
+    nvvm_tld4_unified_b_2d_v4s32_f32,          // llvm.nvvm.tld4.unified.b.2d.v4s32.f32
+    nvvm_tld4_unified_b_2d_v4u32_f32,          // llvm.nvvm.tld4.unified.b.2d.v4u32.f32
+    nvvm_tld4_unified_g_2d_v4f32_f32,          // llvm.nvvm.tld4.unified.g.2d.v4f32.f32
+    nvvm_tld4_unified_g_2d_v4s32_f32,          // llvm.nvvm.tld4.unified.g.2d.v4s32.f32
+    nvvm_tld4_unified_g_2d_v4u32_f32,          // llvm.nvvm.tld4.unified.g.2d.v4u32.f32
+    nvvm_tld4_unified_r_2d_v4f32_f32,          // llvm.nvvm.tld4.unified.r.2d.v4f32.f32
+    nvvm_tld4_unified_r_2d_v4s32_f32,          // llvm.nvvm.tld4.unified.r.2d.v4s32.f32
+    nvvm_tld4_unified_r_2d_v4u32_f32,          // llvm.nvvm.tld4.unified.r.2d.v4u32.f32
+    nvvm_trunc_d,                              // llvm.nvvm.trunc.d
+    nvvm_trunc_f,                              // llvm.nvvm.trunc.f
+    nvvm_trunc_ftz_f,                          // llvm.nvvm.trunc.ftz.f
+    nvvm_txq_array_size,                       // llvm.nvvm.txq.array.size
+    nvvm_txq_channel_data_type,                // llvm.nvvm.txq.channel.data.type
+    nvvm_txq_channel_order,                    // llvm.nvvm.txq.channel.order
+    nvvm_txq_depth,                            // llvm.nvvm.txq.depth
+    nvvm_txq_height,                           // llvm.nvvm.txq.height
+    nvvm_txq_num_mipmap_levels,                // llvm.nvvm.txq.num.mipmap.levels
+    nvvm_txq_num_samples,                      // llvm.nvvm.txq.num.samples
+    nvvm_txq_width,                            // llvm.nvvm.txq.width
+    nvvm_ui2d_rm,                              // llvm.nvvm.ui2d.rm
+    nvvm_ui2d_rn,                              // llvm.nvvm.ui2d.rn
+    nvvm_ui2d_rp,                              // llvm.nvvm.ui2d.rp
+    nvvm_ui2d_rz,                              // llvm.nvvm.ui2d.rz
+    nvvm_ui2f_rm,                              // llvm.nvvm.ui2f.rm
+    nvvm_ui2f_rn,                              // llvm.nvvm.ui2f.rn
+    nvvm_ui2f_rp,                              // llvm.nvvm.ui2f.rp
+    nvvm_ui2f_rz,                              // llvm.nvvm.ui2f.rz
+    nvvm_ull2d_rm,                             // llvm.nvvm.ull2d.rm
+    nvvm_ull2d_rn,                             // llvm.nvvm.ull2d.rn
+    nvvm_ull2d_rp,                             // llvm.nvvm.ull2d.rp
+    nvvm_ull2d_rz,                             // llvm.nvvm.ull2d.rz
+    nvvm_ull2f_rm,                             // llvm.nvvm.ull2f.rm
+    nvvm_ull2f_rn,                             // llvm.nvvm.ull2f.rn
+    nvvm_ull2f_rp,                             // llvm.nvvm.ull2f.rp
+    nvvm_ull2f_rz,                             // llvm.nvvm.ull2f.rz
+    objectsize,                                // llvm.objectsize
+    pcmarker,                                  // llvm.pcmarker
+    pow,                                       // llvm.pow
+    powi,                                      // llvm.powi
+    ppc_altivec_dss,                           // llvm.ppc.altivec.dss
+    ppc_altivec_dssall,                        // llvm.ppc.altivec.dssall
+    ppc_altivec_dst,                           // llvm.ppc.altivec.dst
+    ppc_altivec_dstst,                         // llvm.ppc.altivec.dstst
+    ppc_altivec_dststt,                        // llvm.ppc.altivec.dststt
+    ppc_altivec_dstt,                          // llvm.ppc.altivec.dstt
+    ppc_altivec_lvebx,                         // llvm.ppc.altivec.lvebx
+    ppc_altivec_lvehx,                         // llvm.ppc.altivec.lvehx
+    ppc_altivec_lvewx,                         // llvm.ppc.altivec.lvewx
+    ppc_altivec_lvsl,                          // llvm.ppc.altivec.lvsl
+    ppc_altivec_lvsr,                          // llvm.ppc.altivec.lvsr
+    ppc_altivec_lvx,                           // llvm.ppc.altivec.lvx
+    ppc_altivec_lvxl,                          // llvm.ppc.altivec.lvxl
+    ppc_altivec_mfvscr,                        // llvm.ppc.altivec.mfvscr
+    ppc_altivec_mtvscr,                        // llvm.ppc.altivec.mtvscr
+    ppc_altivec_stvebx,                        // llvm.ppc.altivec.stvebx
+    ppc_altivec_stvehx,                        // llvm.ppc.altivec.stvehx
+    ppc_altivec_stvewx,                        // llvm.ppc.altivec.stvewx
+    ppc_altivec_stvx,                          // llvm.ppc.altivec.stvx
+    ppc_altivec_stvxl,                         // llvm.ppc.altivec.stvxl
+    ppc_altivec_vaddcuw,                       // llvm.ppc.altivec.vaddcuw
+    ppc_altivec_vaddsbs,                       // llvm.ppc.altivec.vaddsbs
+    ppc_altivec_vaddshs,                       // llvm.ppc.altivec.vaddshs
+    ppc_altivec_vaddsws,                       // llvm.ppc.altivec.vaddsws
+    ppc_altivec_vaddubs,                       // llvm.ppc.altivec.vaddubs
+    ppc_altivec_vadduhs,                       // llvm.ppc.altivec.vadduhs
+    ppc_altivec_vadduws,                       // llvm.ppc.altivec.vadduws
+    ppc_altivec_vavgsb,                        // llvm.ppc.altivec.vavgsb
+    ppc_altivec_vavgsh,                        // llvm.ppc.altivec.vavgsh
+    ppc_altivec_vavgsw,                        // llvm.ppc.altivec.vavgsw
+    ppc_altivec_vavgub,                        // llvm.ppc.altivec.vavgub
+    ppc_altivec_vavguh,                        // llvm.ppc.altivec.vavguh
+    ppc_altivec_vavguw,                        // llvm.ppc.altivec.vavguw
+    ppc_altivec_vcfsx,                         // llvm.ppc.altivec.vcfsx
+    ppc_altivec_vcfux,                         // llvm.ppc.altivec.vcfux
+    ppc_altivec_vcmpbfp,                       // llvm.ppc.altivec.vcmpbfp
+    ppc_altivec_vcmpbfp_p,                     // llvm.ppc.altivec.vcmpbfp.p
+    ppc_altivec_vcmpeqfp,                      // llvm.ppc.altivec.vcmpeqfp
+    ppc_altivec_vcmpeqfp_p,                    // llvm.ppc.altivec.vcmpeqfp.p
+    ppc_altivec_vcmpequb,                      // llvm.ppc.altivec.vcmpequb
+    ppc_altivec_vcmpequb_p,                    // llvm.ppc.altivec.vcmpequb.p
+    ppc_altivec_vcmpequh,                      // llvm.ppc.altivec.vcmpequh
+    ppc_altivec_vcmpequh_p,                    // llvm.ppc.altivec.vcmpequh.p
+    ppc_altivec_vcmpequw,                      // llvm.ppc.altivec.vcmpequw
+    ppc_altivec_vcmpequw_p,                    // llvm.ppc.altivec.vcmpequw.p
+    ppc_altivec_vcmpgefp,                      // llvm.ppc.altivec.vcmpgefp
+    ppc_altivec_vcmpgefp_p,                    // llvm.ppc.altivec.vcmpgefp.p
+    ppc_altivec_vcmpgtfp,                      // llvm.ppc.altivec.vcmpgtfp
+    ppc_altivec_vcmpgtfp_p,                    // llvm.ppc.altivec.vcmpgtfp.p
+    ppc_altivec_vcmpgtsb,                      // llvm.ppc.altivec.vcmpgtsb
+    ppc_altivec_vcmpgtsb_p,                    // llvm.ppc.altivec.vcmpgtsb.p
+    ppc_altivec_vcmpgtsh,                      // llvm.ppc.altivec.vcmpgtsh
+    ppc_altivec_vcmpgtsh_p,                    // llvm.ppc.altivec.vcmpgtsh.p
+    ppc_altivec_vcmpgtsw,                      // llvm.ppc.altivec.vcmpgtsw
+    ppc_altivec_vcmpgtsw_p,                    // llvm.ppc.altivec.vcmpgtsw.p
+    ppc_altivec_vcmpgtub,                      // llvm.ppc.altivec.vcmpgtub
+    ppc_altivec_vcmpgtub_p,                    // llvm.ppc.altivec.vcmpgtub.p
+    ppc_altivec_vcmpgtuh,                      // llvm.ppc.altivec.vcmpgtuh
+    ppc_altivec_vcmpgtuh_p,                    // llvm.ppc.altivec.vcmpgtuh.p
+    ppc_altivec_vcmpgtuw,                      // llvm.ppc.altivec.vcmpgtuw
+    ppc_altivec_vcmpgtuw_p,                    // llvm.ppc.altivec.vcmpgtuw.p
+    ppc_altivec_vctsxs,                        // llvm.ppc.altivec.vctsxs
+    ppc_altivec_vctuxs,                        // llvm.ppc.altivec.vctuxs
+    ppc_altivec_vexptefp,                      // llvm.ppc.altivec.vexptefp
+    ppc_altivec_vlogefp,                       // llvm.ppc.altivec.vlogefp
+    ppc_altivec_vmaddfp,                       // llvm.ppc.altivec.vmaddfp
+    ppc_altivec_vmaxfp,                        // llvm.ppc.altivec.vmaxfp
+    ppc_altivec_vmaxsb,                        // llvm.ppc.altivec.vmaxsb
+    ppc_altivec_vmaxsh,                        // llvm.ppc.altivec.vmaxsh
+    ppc_altivec_vmaxsw,                        // llvm.ppc.altivec.vmaxsw
+    ppc_altivec_vmaxub,                        // llvm.ppc.altivec.vmaxub
+    ppc_altivec_vmaxuh,                        // llvm.ppc.altivec.vmaxuh
+    ppc_altivec_vmaxuw,                        // llvm.ppc.altivec.vmaxuw
+    ppc_altivec_vmhaddshs,                     // llvm.ppc.altivec.vmhaddshs
+    ppc_altivec_vmhraddshs,                    // llvm.ppc.altivec.vmhraddshs
+    ppc_altivec_vminfp,                        // llvm.ppc.altivec.vminfp
+    ppc_altivec_vminsb,                        // llvm.ppc.altivec.vminsb
+    ppc_altivec_vminsh,                        // llvm.ppc.altivec.vminsh
+    ppc_altivec_vminsw,                        // llvm.ppc.altivec.vminsw
+    ppc_altivec_vminub,                        // llvm.ppc.altivec.vminub
+    ppc_altivec_vminuh,                        // llvm.ppc.altivec.vminuh
+    ppc_altivec_vminuw,                        // llvm.ppc.altivec.vminuw
+    ppc_altivec_vmladduhm,                     // llvm.ppc.altivec.vmladduhm
+    ppc_altivec_vmsummbm,                      // llvm.ppc.altivec.vmsummbm
+    ppc_altivec_vmsumshm,                      // llvm.ppc.altivec.vmsumshm
+    ppc_altivec_vmsumshs,                      // llvm.ppc.altivec.vmsumshs
+    ppc_altivec_vmsumubm,                      // llvm.ppc.altivec.vmsumubm
+    ppc_altivec_vmsumuhm,                      // llvm.ppc.altivec.vmsumuhm
+    ppc_altivec_vmsumuhs,                      // llvm.ppc.altivec.vmsumuhs
+    ppc_altivec_vmulesb,                       // llvm.ppc.altivec.vmulesb
+    ppc_altivec_vmulesh,                       // llvm.ppc.altivec.vmulesh
+    ppc_altivec_vmuleub,                       // llvm.ppc.altivec.vmuleub
+    ppc_altivec_vmuleuh,                       // llvm.ppc.altivec.vmuleuh
+    ppc_altivec_vmulosb,                       // llvm.ppc.altivec.vmulosb
+    ppc_altivec_vmulosh,                       // llvm.ppc.altivec.vmulosh
+    ppc_altivec_vmuloub,                       // llvm.ppc.altivec.vmuloub
+    ppc_altivec_vmulouh,                       // llvm.ppc.altivec.vmulouh
+    ppc_altivec_vnmsubfp,                      // llvm.ppc.altivec.vnmsubfp
+    ppc_altivec_vperm,                         // llvm.ppc.altivec.vperm
+    ppc_altivec_vpkpx,                         // llvm.ppc.altivec.vpkpx
+    ppc_altivec_vpkshss,                       // llvm.ppc.altivec.vpkshss
+    ppc_altivec_vpkshus,                       // llvm.ppc.altivec.vpkshus
+    ppc_altivec_vpkswss,                       // llvm.ppc.altivec.vpkswss
+    ppc_altivec_vpkswus,                       // llvm.ppc.altivec.vpkswus
+    ppc_altivec_vpkuhus,                       // llvm.ppc.altivec.vpkuhus
+    ppc_altivec_vpkuwus,                       // llvm.ppc.altivec.vpkuwus
+    ppc_altivec_vrefp,                         // llvm.ppc.altivec.vrefp
+    ppc_altivec_vrfim,                         // llvm.ppc.altivec.vrfim
+    ppc_altivec_vrfin,                         // llvm.ppc.altivec.vrfin
+    ppc_altivec_vrfip,                         // llvm.ppc.altivec.vrfip
+    ppc_altivec_vrfiz,                         // llvm.ppc.altivec.vrfiz
+    ppc_altivec_vrlb,                          // llvm.ppc.altivec.vrlb
+    ppc_altivec_vrlh,                          // llvm.ppc.altivec.vrlh
+    ppc_altivec_vrlw,                          // llvm.ppc.altivec.vrlw
+    ppc_altivec_vrsqrtefp,                     // llvm.ppc.altivec.vrsqrtefp
+    ppc_altivec_vsel,                          // llvm.ppc.altivec.vsel
+    ppc_altivec_vsl,                           // llvm.ppc.altivec.vsl
+    ppc_altivec_vslb,                          // llvm.ppc.altivec.vslb
+    ppc_altivec_vslh,                          // llvm.ppc.altivec.vslh
+    ppc_altivec_vslo,                          // llvm.ppc.altivec.vslo
+    ppc_altivec_vslw,                          // llvm.ppc.altivec.vslw
+    ppc_altivec_vsr,                           // llvm.ppc.altivec.vsr
+    ppc_altivec_vsrab,                         // llvm.ppc.altivec.vsrab
+    ppc_altivec_vsrah,                         // llvm.ppc.altivec.vsrah
+    ppc_altivec_vsraw,                         // llvm.ppc.altivec.vsraw
+    ppc_altivec_vsrb,                          // llvm.ppc.altivec.vsrb
+    ppc_altivec_vsrh,                          // llvm.ppc.altivec.vsrh
+    ppc_altivec_vsro,                          // llvm.ppc.altivec.vsro
+    ppc_altivec_vsrw,                          // llvm.ppc.altivec.vsrw
+    ppc_altivec_vsubcuw,                       // llvm.ppc.altivec.vsubcuw
+    ppc_altivec_vsubsbs,                       // llvm.ppc.altivec.vsubsbs
+    ppc_altivec_vsubshs,                       // llvm.ppc.altivec.vsubshs
+    ppc_altivec_vsubsws,                       // llvm.ppc.altivec.vsubsws
+    ppc_altivec_vsububs,                       // llvm.ppc.altivec.vsububs
+    ppc_altivec_vsubuhs,                       // llvm.ppc.altivec.vsubuhs
+    ppc_altivec_vsubuws,                       // llvm.ppc.altivec.vsubuws
+    ppc_altivec_vsum2sws,                      // llvm.ppc.altivec.vsum2sws
+    ppc_altivec_vsum4sbs,                      // llvm.ppc.altivec.vsum4sbs
+    ppc_altivec_vsum4shs,                      // llvm.ppc.altivec.vsum4shs
+    ppc_altivec_vsum4ubs,                      // llvm.ppc.altivec.vsum4ubs
+    ppc_altivec_vsumsws,                       // llvm.ppc.altivec.vsumsws
+    ppc_altivec_vupkhpx,                       // llvm.ppc.altivec.vupkhpx
+    ppc_altivec_vupkhsb,                       // llvm.ppc.altivec.vupkhsb
+    ppc_altivec_vupkhsh,                       // llvm.ppc.altivec.vupkhsh
+    ppc_altivec_vupklpx,                       // llvm.ppc.altivec.vupklpx
+    ppc_altivec_vupklsb,                       // llvm.ppc.altivec.vupklsb
+    ppc_altivec_vupklsh,                       // llvm.ppc.altivec.vupklsh
+    ppc_dcba,                                  // llvm.ppc.dcba
+    ppc_dcbf,                                  // llvm.ppc.dcbf
+    ppc_dcbi,                                  // llvm.ppc.dcbi
+    ppc_dcbst,                                 // llvm.ppc.dcbst
+    ppc_dcbt,                                  // llvm.ppc.dcbt
+    ppc_dcbtst,                                // llvm.ppc.dcbtst
+    ppc_dcbz,                                  // llvm.ppc.dcbz
+    ppc_dcbzl,                                 // llvm.ppc.dcbzl
+    ppc_is_decremented_ctr_nonzero,            // llvm.ppc.is.decremented.ctr.nonzero
+    ppc_mtctr,                                 // llvm.ppc.mtctr
+    ppc_sync,                                  // llvm.ppc.sync
+    prefetch,                                  // llvm.prefetch
+    ptr_annotation,                            // llvm.ptr.annotation
+    ptx_bar_sync,                              // llvm.ptx.bar.sync
+    ptx_read_clock,                            // llvm.ptx.read.clock
+    ptx_read_clock64,                          // llvm.ptx.read.clock64
+    ptx_read_ctaid_w,                          // llvm.ptx.read.ctaid.w
+    ptx_read_ctaid_x,                          // llvm.ptx.read.ctaid.x
+    ptx_read_ctaid_y,                          // llvm.ptx.read.ctaid.y
+    ptx_read_ctaid_z,                          // llvm.ptx.read.ctaid.z
+    ptx_read_gridid,                           // llvm.ptx.read.gridid
+    ptx_read_laneid,                           // llvm.ptx.read.laneid
+    ptx_read_lanemask_eq,                      // llvm.ptx.read.lanemask.eq
+    ptx_read_lanemask_ge,                      // llvm.ptx.read.lanemask.ge
+    ptx_read_lanemask_gt,                      // llvm.ptx.read.lanemask.gt
+    ptx_read_lanemask_le,                      // llvm.ptx.read.lanemask.le
+    ptx_read_lanemask_lt,                      // llvm.ptx.read.lanemask.lt
+    ptx_read_nctaid_w,                         // llvm.ptx.read.nctaid.w
+    ptx_read_nctaid_x,                         // llvm.ptx.read.nctaid.x
+    ptx_read_nctaid_y,                         // llvm.ptx.read.nctaid.y
+    ptx_read_nctaid_z,                         // llvm.ptx.read.nctaid.z
+    ptx_read_nsmid,                            // llvm.ptx.read.nsmid
+    ptx_read_ntid_w,                           // llvm.ptx.read.ntid.w
+    ptx_read_ntid_x,                           // llvm.ptx.read.ntid.x
+    ptx_read_ntid_y,                           // llvm.ptx.read.ntid.y
+    ptx_read_ntid_z,                           // llvm.ptx.read.ntid.z
+    ptx_read_nwarpid,                          // llvm.ptx.read.nwarpid
+    ptx_read_pm0,                              // llvm.ptx.read.pm0
+    ptx_read_pm1,                              // llvm.ptx.read.pm1
+    ptx_read_pm2,                              // llvm.ptx.read.pm2
+    ptx_read_pm3,                              // llvm.ptx.read.pm3
+    ptx_read_smid,                             // llvm.ptx.read.smid
+    ptx_read_tid_w,                            // llvm.ptx.read.tid.w
+    ptx_read_tid_x,                            // llvm.ptx.read.tid.x
+    ptx_read_tid_y,                            // llvm.ptx.read.tid.y
+    ptx_read_tid_z,                            // llvm.ptx.read.tid.z
+    ptx_read_warpid,                           // llvm.ptx.read.warpid
+    r600_read_global_size_x,                   // llvm.r600.read.global.size.x
+    r600_read_global_size_y,                   // llvm.r600.read.global.size.y
+    r600_read_global_size_z,                   // llvm.r600.read.global.size.z
+    r600_read_local_size_x,                    // llvm.r600.read.local.size.x
+    r600_read_local_size_y,                    // llvm.r600.read.local.size.y
+    r600_read_local_size_z,                    // llvm.r600.read.local.size.z
+    r600_read_ngroups_x,                       // llvm.r600.read.ngroups.x
+    r600_read_ngroups_y,                       // llvm.r600.read.ngroups.y
+    r600_read_ngroups_z,                       // llvm.r600.read.ngroups.z
+    r600_read_tgid_x,                          // llvm.r600.read.tgid.x
+    r600_read_tgid_y,                          // llvm.r600.read.tgid.y
+    r600_read_tgid_z,                          // llvm.r600.read.tgid.z
+    r600_read_tidig_x,                         // llvm.r600.read.tidig.x
+    r600_read_tidig_y,                         // llvm.r600.read.tidig.y
+    r600_read_tidig_z,                         // llvm.r600.read.tidig.z
+    read_register,                             // llvm.read_register
+    readcyclecounter,                          // llvm.readcyclecounter
+    returnaddress,                             // llvm.returnaddress
+    rint,                                      // llvm.rint
+    round,                                     // llvm.round
+    sadd_with_overflow,                        // llvm.sadd.with.overflow
+    setjmp,                                    // llvm.setjmp
+    siglongjmp,                                // llvm.siglongjmp
+    sigsetjmp,                                 // llvm.sigsetjmp
+    sin,                                       // llvm.sin
+    smul_with_overflow,                        // llvm.smul.with.overflow
+    sqrt,                                      // llvm.sqrt
+    ssub_with_overflow,                        // llvm.ssub.with.overflow
+    stackprotector,                            // llvm.stackprotector
+    stackprotectorcheck,                       // llvm.stackprotectorcheck
+    stackrestore,                              // llvm.stackrestore
+    stacksave,                                 // llvm.stacksave
+    trap,                                      // llvm.trap
+    trunc,                                     // llvm.trunc
+    uadd_with_overflow,                        // llvm.uadd.with.overflow
+    umul_with_overflow,                        // llvm.umul.with.overflow
+    usub_with_overflow,                        // llvm.usub.with.overflow
+    vacopy,                                    // llvm.va_copy
+    vaend,                                     // llvm.va_end
+    var_annotation,                            // llvm.var.annotation
+    vastart,                                   // llvm.va_start
+    write_register,                            // llvm.write_register
+    x86_3dnow_pavgusb,                         // llvm.x86.3dnow.pavgusb
+    x86_3dnow_pf2id,                           // llvm.x86.3dnow.pf2id
+    x86_3dnow_pfacc,                           // llvm.x86.3dnow.pfacc
+    x86_3dnow_pfadd,                           // llvm.x86.3dnow.pfadd
+    x86_3dnow_pfcmpeq,                         // llvm.x86.3dnow.pfcmpeq
+    x86_3dnow_pfcmpge,                         // llvm.x86.3dnow.pfcmpge
+    x86_3dnow_pfcmpgt,                         // llvm.x86.3dnow.pfcmpgt
+    x86_3dnow_pfmax,                           // llvm.x86.3dnow.pfmax
+    x86_3dnow_pfmin,                           // llvm.x86.3dnow.pfmin
+    x86_3dnow_pfmul,                           // llvm.x86.3dnow.pfmul
+    x86_3dnow_pfrcp,                           // llvm.x86.3dnow.pfrcp
+    x86_3dnow_pfrcpit1,                        // llvm.x86.3dnow.pfrcpit1
+    x86_3dnow_pfrcpit2,                        // llvm.x86.3dnow.pfrcpit2
+    x86_3dnow_pfrsqit1,                        // llvm.x86.3dnow.pfrsqit1
+    x86_3dnow_pfrsqrt,                         // llvm.x86.3dnow.pfrsqrt
+    x86_3dnow_pfsub,                           // llvm.x86.3dnow.pfsub
+    x86_3dnow_pfsubr,                          // llvm.x86.3dnow.pfsubr
+    x86_3dnow_pi2fd,                           // llvm.x86.3dnow.pi2fd
+    x86_3dnow_pmulhrw,                         // llvm.x86.3dnow.pmulhrw
+    x86_3dnowa_pf2iw,                          // llvm.x86.3dnowa.pf2iw
+    x86_3dnowa_pfnacc,                         // llvm.x86.3dnowa.pfnacc
+    x86_3dnowa_pfpnacc,                        // llvm.x86.3dnowa.pfpnacc
+    x86_3dnowa_pi2fw,                          // llvm.x86.3dnowa.pi2fw
+    x86_3dnowa_pswapd,                         // llvm.x86.3dnowa.pswapd
+    x86_aesni_aesdec,                          // llvm.x86.aesni.aesdec
+    x86_aesni_aesdeclast,                      // llvm.x86.aesni.aesdeclast
+    x86_aesni_aesenc,                          // llvm.x86.aesni.aesenc
+    x86_aesni_aesenclast,                      // llvm.x86.aesni.aesenclast
+    x86_aesni_aesimc,                          // llvm.x86.aesni.aesimc
+    x86_aesni_aeskeygenassist,                 // llvm.x86.aesni.aeskeygenassist
+    x86_avx2_gather_d_d,                       // llvm.x86.avx2.gather.d.d
+    x86_avx2_gather_d_d_256,                   // llvm.x86.avx2.gather.d.d.256
+    x86_avx2_gather_d_pd,                      // llvm.x86.avx2.gather.d.pd
+    x86_avx2_gather_d_pd_256,                  // llvm.x86.avx2.gather.d.pd.256
+    x86_avx2_gather_d_ps,                      // llvm.x86.avx2.gather.d.ps
+    x86_avx2_gather_d_ps_256,                  // llvm.x86.avx2.gather.d.ps.256
+    x86_avx2_gather_d_q,                       // llvm.x86.avx2.gather.d.q
+    x86_avx2_gather_d_q_256,                   // llvm.x86.avx2.gather.d.q.256
+    x86_avx2_gather_q_d,                       // llvm.x86.avx2.gather.q.d
+    x86_avx2_gather_q_d_256,                   // llvm.x86.avx2.gather.q.d.256
+    x86_avx2_gather_q_pd,                      // llvm.x86.avx2.gather.q.pd
+    x86_avx2_gather_q_pd_256,                  // llvm.x86.avx2.gather.q.pd.256
+    x86_avx2_gather_q_ps,                      // llvm.x86.avx2.gather.q.ps
+    x86_avx2_gather_q_ps_256,                  // llvm.x86.avx2.gather.q.ps.256
+    x86_avx2_gather_q_q,                       // llvm.x86.avx2.gather.q.q
+    x86_avx2_gather_q_q_256,                   // llvm.x86.avx2.gather.q.q.256
+    x86_avx2_maskload_d,                       // llvm.x86.avx2.maskload.d
+    x86_avx2_maskload_d_256,                   // llvm.x86.avx2.maskload.d.256
+    x86_avx2_maskload_q,                       // llvm.x86.avx2.maskload.q
+    x86_avx2_maskload_q_256,                   // llvm.x86.avx2.maskload.q.256
+    x86_avx2_maskstore_d,                      // llvm.x86.avx2.maskstore.d
+    x86_avx2_maskstore_d_256,                  // llvm.x86.avx2.maskstore.d.256
+    x86_avx2_maskstore_q,                      // llvm.x86.avx2.maskstore.q
+    x86_avx2_maskstore_q_256,                  // llvm.x86.avx2.maskstore.q.256
+    x86_avx2_movntdqa,                         // llvm.x86.avx2.movntdqa
+    x86_avx2_mpsadbw,                          // llvm.x86.avx2.mpsadbw
+    x86_avx2_pabs_b,                           // llvm.x86.avx2.pabs.b
+    x86_avx2_pabs_d,                           // llvm.x86.avx2.pabs.d
+    x86_avx2_pabs_w,                           // llvm.x86.avx2.pabs.w
+    x86_avx2_packssdw,                         // llvm.x86.avx2.packssdw
+    x86_avx2_packsswb,                         // llvm.x86.avx2.packsswb
+    x86_avx2_packusdw,                         // llvm.x86.avx2.packusdw
+    x86_avx2_packuswb,                         // llvm.x86.avx2.packuswb
+    x86_avx2_padds_b,                          // llvm.x86.avx2.padds.b
+    x86_avx2_padds_w,                          // llvm.x86.avx2.padds.w
+    x86_avx2_paddus_b,                         // llvm.x86.avx2.paddus.b
+    x86_avx2_paddus_w,                         // llvm.x86.avx2.paddus.w
+    x86_avx2_pavg_b,                           // llvm.x86.avx2.pavg.b
+    x86_avx2_pavg_w,                           // llvm.x86.avx2.pavg.w
+    x86_avx2_pblendd_128,                      // llvm.x86.avx2.pblendd.128
+    x86_avx2_pblendd_256,                      // llvm.x86.avx2.pblendd.256
+    x86_avx2_pblendvb,                         // llvm.x86.avx2.pblendvb
+    x86_avx2_pblendw,                          // llvm.x86.avx2.pblendw
+    x86_avx2_pbroadcastb_128,                  // llvm.x86.avx2.pbroadcastb.128
+    x86_avx2_pbroadcastb_256,                  // llvm.x86.avx2.pbroadcastb.256
+    x86_avx2_pbroadcastd_128,                  // llvm.x86.avx2.pbroadcastd.128
+    x86_avx2_pbroadcastd_256,                  // llvm.x86.avx2.pbroadcastd.256
+    x86_avx2_pbroadcastq_128,                  // llvm.x86.avx2.pbroadcastq.128
+    x86_avx2_pbroadcastq_256,                  // llvm.x86.avx2.pbroadcastq.256
+    x86_avx2_pbroadcastw_128,                  // llvm.x86.avx2.pbroadcastw.128
+    x86_avx2_pbroadcastw_256,                  // llvm.x86.avx2.pbroadcastw.256
+    x86_avx2_permd,                            // llvm.x86.avx2.permd
+    x86_avx2_permps,                           // llvm.x86.avx2.permps
+    x86_avx2_phadd_d,                          // llvm.x86.avx2.phadd.d
+    x86_avx2_phadd_sw,                         // llvm.x86.avx2.phadd.sw
+    x86_avx2_phadd_w,                          // llvm.x86.avx2.phadd.w
+    x86_avx2_phsub_d,                          // llvm.x86.avx2.phsub.d
+    x86_avx2_phsub_sw,                         // llvm.x86.avx2.phsub.sw
+    x86_avx2_phsub_w,                          // llvm.x86.avx2.phsub.w
+    x86_avx2_pmadd_ub_sw,                      // llvm.x86.avx2.pmadd.ub.sw
+    x86_avx2_pmadd_wd,                         // llvm.x86.avx2.pmadd.wd
+    x86_avx2_pmaxs_b,                          // llvm.x86.avx2.pmaxs.b
+    x86_avx2_pmaxs_d,                          // llvm.x86.avx2.pmaxs.d
+    x86_avx2_pmaxs_w,                          // llvm.x86.avx2.pmaxs.w
+    x86_avx2_pmaxu_b,                          // llvm.x86.avx2.pmaxu.b
+    x86_avx2_pmaxu_d,                          // llvm.x86.avx2.pmaxu.d
+    x86_avx2_pmaxu_w,                          // llvm.x86.avx2.pmaxu.w
+    x86_avx2_pmins_b,                          // llvm.x86.avx2.pmins.b
+    x86_avx2_pmins_d,                          // llvm.x86.avx2.pmins.d
+    x86_avx2_pmins_w,                          // llvm.x86.avx2.pmins.w
+    x86_avx2_pminu_b,                          // llvm.x86.avx2.pminu.b
+    x86_avx2_pminu_d,                          // llvm.x86.avx2.pminu.d
+    x86_avx2_pminu_w,                          // llvm.x86.avx2.pminu.w
+    x86_avx2_pmovmskb,                         // llvm.x86.avx2.pmovmskb
+    x86_avx2_pmovsxbd,                         // llvm.x86.avx2.pmovsxbd
+    x86_avx2_pmovsxbq,                         // llvm.x86.avx2.pmovsxbq
+    x86_avx2_pmovsxbw,                         // llvm.x86.avx2.pmovsxbw
+    x86_avx2_pmovsxdq,                         // llvm.x86.avx2.pmovsxdq
+    x86_avx2_pmovsxwd,                         // llvm.x86.avx2.pmovsxwd
+    x86_avx2_pmovsxwq,                         // llvm.x86.avx2.pmovsxwq
+    x86_avx2_pmovzxbd,                         // llvm.x86.avx2.pmovzxbd
+    x86_avx2_pmovzxbq,                         // llvm.x86.avx2.pmovzxbq
+    x86_avx2_pmovzxbw,                         // llvm.x86.avx2.pmovzxbw
+    x86_avx2_pmovzxdq,                         // llvm.x86.avx2.pmovzxdq
+    x86_avx2_pmovzxwd,                         // llvm.x86.avx2.pmovzxwd
+    x86_avx2_pmovzxwq,                         // llvm.x86.avx2.pmovzxwq
+    x86_avx2_pmul_dq,                          // llvm.x86.avx2.pmul.dq
+    x86_avx2_pmul_hr_sw,                       // llvm.x86.avx2.pmul.hr.sw
+    x86_avx2_pmulh_w,                          // llvm.x86.avx2.pmulh.w
+    x86_avx2_pmulhu_w,                         // llvm.x86.avx2.pmulhu.w
+    x86_avx2_pmulu_dq,                         // llvm.x86.avx2.pmulu.dq
+    x86_avx2_psad_bw,                          // llvm.x86.avx2.psad.bw
+    x86_avx2_pshuf_b,                          // llvm.x86.avx2.pshuf.b
+    x86_avx2_psign_b,                          // llvm.x86.avx2.psign.b
+    x86_avx2_psign_d,                          // llvm.x86.avx2.psign.d
+    x86_avx2_psign_w,                          // llvm.x86.avx2.psign.w
+    x86_avx2_psll_d,                           // llvm.x86.avx2.psll.d
+    x86_avx2_psll_dq,                          // llvm.x86.avx2.psll.dq
+    x86_avx2_psll_dq_bs,                       // llvm.x86.avx2.psll.dq.bs
+    x86_avx2_psll_q,                           // llvm.x86.avx2.psll.q
+    x86_avx2_psll_w,                           // llvm.x86.avx2.psll.w
+    x86_avx2_pslli_d,                          // llvm.x86.avx2.pslli.d
+    x86_avx2_pslli_q,                          // llvm.x86.avx2.pslli.q
+    x86_avx2_pslli_w,                          // llvm.x86.avx2.pslli.w
+    x86_avx2_psllv_d,                          // llvm.x86.avx2.psllv.d
+    x86_avx2_psllv_d_256,                      // llvm.x86.avx2.psllv.d.256
+    x86_avx2_psllv_q,                          // llvm.x86.avx2.psllv.q
+    x86_avx2_psllv_q_256,                      // llvm.x86.avx2.psllv.q.256
+    x86_avx2_psra_d,                           // llvm.x86.avx2.psra.d
+    x86_avx2_psra_w,                           // llvm.x86.avx2.psra.w
+    x86_avx2_psrai_d,                          // llvm.x86.avx2.psrai.d
+    x86_avx2_psrai_w,                          // llvm.x86.avx2.psrai.w
+    x86_avx2_psrav_d,                          // llvm.x86.avx2.psrav.d
+    x86_avx2_psrav_d_256,                      // llvm.x86.avx2.psrav.d.256
+    x86_avx2_psrl_d,                           // llvm.x86.avx2.psrl.d
+    x86_avx2_psrl_dq,                          // llvm.x86.avx2.psrl.dq
+    x86_avx2_psrl_dq_bs,                       // llvm.x86.avx2.psrl.dq.bs
+    x86_avx2_psrl_q,                           // llvm.x86.avx2.psrl.q
+    x86_avx2_psrl_w,                           // llvm.x86.avx2.psrl.w
+    x86_avx2_psrli_d,                          // llvm.x86.avx2.psrli.d
+    x86_avx2_psrli_q,                          // llvm.x86.avx2.psrli.q
+    x86_avx2_psrli_w,                          // llvm.x86.avx2.psrli.w
+    x86_avx2_psrlv_d,                          // llvm.x86.avx2.psrlv.d
+    x86_avx2_psrlv_d_256,                      // llvm.x86.avx2.psrlv.d.256
+    x86_avx2_psrlv_q,                          // llvm.x86.avx2.psrlv.q
+    x86_avx2_psrlv_q_256,                      // llvm.x86.avx2.psrlv.q.256
+    x86_avx2_psubs_b,                          // llvm.x86.avx2.psubs.b
+    x86_avx2_psubs_w,                          // llvm.x86.avx2.psubs.w
+    x86_avx2_psubus_b,                         // llvm.x86.avx2.psubus.b
+    x86_avx2_psubus_w,                         // llvm.x86.avx2.psubus.w
+    x86_avx2_vbroadcast_sd_pd_256,             // llvm.x86.avx2.vbroadcast.sd.pd.256
+    x86_avx2_vbroadcast_ss_ps,                 // llvm.x86.avx2.vbroadcast.ss.ps
+    x86_avx2_vbroadcast_ss_ps_256,             // llvm.x86.avx2.vbroadcast.ss.ps.256
+    x86_avx2_vbroadcasti128,                   // llvm.x86.avx2.vbroadcasti128
+    x86_avx2_vextracti128,                     // llvm.x86.avx2.vextracti128
+    x86_avx2_vinserti128,                      // llvm.x86.avx2.vinserti128
+    x86_avx2_vperm2i128,                       // llvm.x86.avx2.vperm2i128
+    x86_avx512_cvtsd2usi,                      // llvm.x86.avx512.cvtsd2usi
+    x86_avx512_cvtsd2usi64,                    // llvm.x86.avx512.cvtsd2usi64
+    x86_avx512_cvtss2usi,                      // llvm.x86.avx512.cvtss2usi
+    x86_avx512_cvtss2usi64,                    // llvm.x86.avx512.cvtss2usi64
+    x86_avx512_cvttsd2usi,                     // llvm.x86.avx512.cvttsd2usi
+    x86_avx512_cvttsd2usi64,                   // llvm.x86.avx512.cvttsd2usi64
+    x86_avx512_cvttss2usi,                     // llvm.x86.avx512.cvttss2usi
+    x86_avx512_cvttss2usi64,                   // llvm.x86.avx512.cvttss2usi64
+    x86_avx512_cvtusi2sd,                      // llvm.x86.avx512.cvtusi2sd
+    x86_avx512_cvtusi2ss,                      // llvm.x86.avx512.cvtusi2ss
+    x86_avx512_cvtusi642sd,                    // llvm.x86.avx512.cvtusi642sd
+    x86_avx512_cvtusi642ss,                    // llvm.x86.avx512.cvtusi642ss
+    x86_avx512_gather_dpd_512,                 // llvm.x86.avx512.gather.dpd.512
+    x86_avx512_gather_dpi_512,                 // llvm.x86.avx512.gather.dpi.512
+    x86_avx512_gather_dpq_512,                 // llvm.x86.avx512.gather.dpq.512
+    x86_avx512_gather_dps_512,                 // llvm.x86.avx512.gather.dps.512
+    x86_avx512_gather_qpd_512,                 // llvm.x86.avx512.gather.qpd.512
+    x86_avx512_gather_qpi_512,                 // llvm.x86.avx512.gather.qpi.512
+    x86_avx512_gather_qpq_512,                 // llvm.x86.avx512.gather.qpq.512
+    x86_avx512_gather_qps_512,                 // llvm.x86.avx512.gather.qps.512
+    x86_avx512_gatherpf_dpd_512,               // llvm.x86.avx512.gatherpf.dpd.512
+    x86_avx512_gatherpf_dps_512,               // llvm.x86.avx512.gatherpf.dps.512
+    x86_avx512_gatherpf_qpd_512,               // llvm.x86.avx512.gatherpf.qpd.512
+    x86_avx512_gatherpf_qps_512,               // llvm.x86.avx512.gatherpf.qps.512
+    x86_avx512_kand_w,                         // llvm.x86.avx512.kand.w
+    x86_avx512_kandn_w,                        // llvm.x86.avx512.kandn.w
+    x86_avx512_knot_w,                         // llvm.x86.avx512.knot.w
+    x86_avx512_kor_w,                          // llvm.x86.avx512.kor.w
+    x86_avx512_kortestc_w,                     // llvm.x86.avx512.kortestc.w
+    x86_avx512_kortestz_w,                     // llvm.x86.avx512.kortestz.w
+    x86_avx512_kunpck_bw,                      // llvm.x86.avx512.kunpck.bw
+    x86_avx512_kxnor_w,                        // llvm.x86.avx512.kxnor.w
+    x86_avx512_kxor_w,                         // llvm.x86.avx512.kxor.w
+    x86_avx512_mask_blend_d_512,               // llvm.x86.avx512.mask.blend.d.512
+    x86_avx512_mask_blend_pd_512,              // llvm.x86.avx512.mask.blend.pd.512
+    x86_avx512_mask_blend_ps_512,              // llvm.x86.avx512.mask.blend.ps.512
+    x86_avx512_mask_blend_q_512,               // llvm.x86.avx512.mask.blend.q.512
+    x86_avx512_mask_cmp_pd_512,                // llvm.x86.avx512.mask.cmp.pd.512
+    x86_avx512_mask_cmp_ps_512,                // llvm.x86.avx512.mask.cmp.ps.512
+    x86_avx512_mask_conflict_d_512,            // llvm.x86.avx512.mask.conflict.d.512
+    x86_avx512_mask_conflict_q_512,            // llvm.x86.avx512.mask.conflict.q.512
+    x86_avx512_mask_cvtdq2pd_512,              // llvm.x86.avx512.mask.cvtdq2pd.512
+    x86_avx512_mask_cvtdq2ps_512,              // llvm.x86.avx512.mask.cvtdq2ps.512
+    x86_avx512_mask_cvtpd2dq_512,              // llvm.x86.avx512.mask.cvtpd2dq.512
+    x86_avx512_mask_cvtpd2ps_512,              // llvm.x86.avx512.mask.cvtpd2ps.512
+    x86_avx512_mask_cvtpd2udq_512,             // llvm.x86.avx512.mask.cvtpd2udq.512
+    x86_avx512_mask_cvtps2dq_512,              // llvm.x86.avx512.mask.cvtps2dq.512
+    x86_avx512_mask_cvtps2udq_512,             // llvm.x86.avx512.mask.cvtps2udq.512
+    x86_avx512_mask_cvttpd2dq_512,             // llvm.x86.avx512.mask.cvttpd2dq.512
+    x86_avx512_mask_cvttpd2udq_512,            // llvm.x86.avx512.mask.cvttpd2udq.512
+    x86_avx512_mask_cvttps2dq_512,             // llvm.x86.avx512.mask.cvttps2dq.512
+    x86_avx512_mask_cvttps2udq_512,            // llvm.x86.avx512.mask.cvttps2udq.512
+    x86_avx512_mask_cvtudq2pd_512,             // llvm.x86.avx512.mask.cvtudq2pd.512
+    x86_avx512_mask_cvtudq2ps_512,             // llvm.x86.avx512.mask.cvtudq2ps.512
+    x86_avx512_mask_loadu_d_512,               // llvm.x86.avx512.mask.loadu.d.512
+    x86_avx512_mask_loadu_pd_512,              // llvm.x86.avx512.mask.loadu.pd.512
+    x86_avx512_mask_loadu_ps_512,              // llvm.x86.avx512.mask.loadu.ps.512
+    x86_avx512_mask_loadu_q_512,               // llvm.x86.avx512.mask.loadu.q.512
+    x86_avx512_mask_lzcnt_d_512,               // llvm.x86.avx512.mask.lzcnt.d.512
+    x86_avx512_mask_lzcnt_q_512,               // llvm.x86.avx512.mask.lzcnt.q.512
+    x86_avx512_mask_max_pd_512,                // llvm.x86.avx512.mask.max.pd.512
+    x86_avx512_mask_max_ps_512,                // llvm.x86.avx512.mask.max.ps.512
+    x86_avx512_mask_min_pd_512,                // llvm.x86.avx512.mask.min.pd.512
+    x86_avx512_mask_min_ps_512,                // llvm.x86.avx512.mask.min.ps.512
+    x86_avx512_mask_pabs_d_512,                // llvm.x86.avx512.mask.pabs.d.512
+    x86_avx512_mask_pabs_q_512,                // llvm.x86.avx512.mask.pabs.q.512
+    x86_avx512_mask_pand_d_512,                // llvm.x86.avx512.mask.pand.d.512
+    x86_avx512_mask_pand_q_512,                // llvm.x86.avx512.mask.pand.q.512
+    x86_avx512_mask_pbroadcast_d_gpr_512,      // llvm.x86.avx512.mask.pbroadcast.d.gpr.512
+    x86_avx512_mask_pbroadcast_q_gpr_512,      // llvm.x86.avx512.mask.pbroadcast.q.gpr.512
+    x86_avx512_mask_pbroadcast_q_mem_512,      // llvm.x86.avx512.mask.pbroadcast.q.mem.512
+    x86_avx512_mask_pcmpeq_d_512,              // llvm.x86.avx512.mask.pcmpeq.d.512
+    x86_avx512_mask_pcmpeq_q_512,              // llvm.x86.avx512.mask.pcmpeq.q.512
+    x86_avx512_mask_pmaxs_d_512,               // llvm.x86.avx512.mask.pmaxs.d.512
+    x86_avx512_mask_pmaxs_q_512,               // llvm.x86.avx512.mask.pmaxs.q.512
+    x86_avx512_mask_pmaxu_d_512,               // llvm.x86.avx512.mask.pmaxu.d.512
+    x86_avx512_mask_pmaxu_q_512,               // llvm.x86.avx512.mask.pmaxu.q.512
+    x86_avx512_mask_pmins_d_512,               // llvm.x86.avx512.mask.pmins.d.512
+    x86_avx512_mask_pmins_q_512,               // llvm.x86.avx512.mask.pmins.q.512
+    x86_avx512_mask_pminu_d_512,               // llvm.x86.avx512.mask.pminu.d.512
+    x86_avx512_mask_pminu_q_512,               // llvm.x86.avx512.mask.pminu.q.512
+    x86_avx512_mask_pmul_dq_512,               // llvm.x86.avx512.mask.pmul.dq.512
+    x86_avx512_mask_pmulu_dq_512,              // llvm.x86.avx512.mask.pmulu.dq.512
+    x86_avx512_mask_ptestm_d_512,              // llvm.x86.avx512.mask.ptestm.d.512
+    x86_avx512_mask_ptestm_q_512,              // llvm.x86.avx512.mask.ptestm.q.512
+    x86_avx512_mask_rndscale_pd_512,           // llvm.x86.avx512.mask.rndscale.pd.512
+    x86_avx512_mask_rndscale_ps_512,           // llvm.x86.avx512.mask.rndscale.ps.512
+    x86_avx512_mask_storeu_d_512,              // llvm.x86.avx512.mask.storeu.d.512
+    x86_avx512_mask_storeu_pd_512,             // llvm.x86.avx512.mask.storeu.pd.512
+    x86_avx512_mask_storeu_ps_512,             // llvm.x86.avx512.mask.storeu.ps.512
+    x86_avx512_mask_storeu_q_512,              // llvm.x86.avx512.mask.storeu.q.512
+    x86_avx512_mask_vcvtph2ps_512,             // llvm.x86.avx512.mask.vcvtph2ps.512
+    x86_avx512_mask_vcvtps2ph_512,             // llvm.x86.avx512.mask.vcvtps2ph.512
+    x86_avx512_mask_vpermt_d_512,              // llvm.x86.avx512.mask.vpermt.d.512
+    x86_avx512_mask_vpermt_pd_512,             // llvm.x86.avx512.mask.vpermt.pd.512
+    x86_avx512_mask_vpermt_ps_512,             // llvm.x86.avx512.mask.vpermt.ps.512
+    x86_avx512_mask_vpermt_q_512,              // llvm.x86.avx512.mask.vpermt.q.512
+    x86_avx512_movntdqa,                       // llvm.x86.avx512.movntdqa
+    x86_avx512_pbroadcastd_512,                // llvm.x86.avx512.pbroadcastd.512
+    x86_avx512_pbroadcastd_i32_512,            // llvm.x86.avx512.pbroadcastd.i32.512
+    x86_avx512_pbroadcastq_512,                // llvm.x86.avx512.pbroadcastq.512
+    x86_avx512_pbroadcastq_i64_512,            // llvm.x86.avx512.pbroadcastq.i64.512
+    x86_avx512_pmovzxbd,                       // llvm.x86.avx512.pmovzxbd
+    x86_avx512_pmovzxbq,                       // llvm.x86.avx512.pmovzxbq
+    x86_avx512_pmovzxdq,                       // llvm.x86.avx512.pmovzxdq
+    x86_avx512_pmovzxwd,                       // llvm.x86.avx512.pmovzxwd
+    x86_avx512_pmovzxwq,                       // llvm.x86.avx512.pmovzxwq
+    x86_avx512_psll_dq,                        // llvm.x86.avx512.psll.dq
+    x86_avx512_psll_dq_bs,                     // llvm.x86.avx512.psll.dq.bs
+    x86_avx512_psrl_dq,                        // llvm.x86.avx512.psrl.dq
+    x86_avx512_psrl_dq_bs,                     // llvm.x86.avx512.psrl.dq.bs
+    x86_avx512_rcp14_pd_512,                   // llvm.x86.avx512.rcp14.pd.512
+    x86_avx512_rcp14_ps_512,                   // llvm.x86.avx512.rcp14.ps.512
+    x86_avx512_rcp14_sd,                       // llvm.x86.avx512.rcp14.sd
+    x86_avx512_rcp14_ss,                       // llvm.x86.avx512.rcp14.ss
+    x86_avx512_rcp28_pd,                       // llvm.x86.avx512.rcp28.pd
+    x86_avx512_rcp28_ps,                       // llvm.x86.avx512.rcp28.ps
+    x86_avx512_rcp28_sd,                       // llvm.x86.avx512.rcp28.sd
+    x86_avx512_rcp28_ss,                       // llvm.x86.avx512.rcp28.ss
+    x86_avx512_rndscale_sd,                    // llvm.x86.avx512.rndscale.sd
+    x86_avx512_rndscale_ss,                    // llvm.x86.avx512.rndscale.ss
+    x86_avx512_rsqrt14_pd_512,                 // llvm.x86.avx512.rsqrt14.pd.512
+    x86_avx512_rsqrt14_ps_512,                 // llvm.x86.avx512.rsqrt14.ps.512
+    x86_avx512_rsqrt14_sd,                     // llvm.x86.avx512.rsqrt14.sd
+    x86_avx512_rsqrt14_ss,                     // llvm.x86.avx512.rsqrt14.ss
+    x86_avx512_rsqrt28_pd,                     // llvm.x86.avx512.rsqrt28.pd
+    x86_avx512_rsqrt28_ps,                     // llvm.x86.avx512.rsqrt28.ps
+    x86_avx512_rsqrt28_sd,                     // llvm.x86.avx512.rsqrt28.sd
+    x86_avx512_rsqrt28_ss,                     // llvm.x86.avx512.rsqrt28.ss
+    x86_avx512_scatter_dpd_512,                // llvm.x86.avx512.scatter.dpd.512
+    x86_avx512_scatter_dpi_512,                // llvm.x86.avx512.scatter.dpi.512
+    x86_avx512_scatter_dpq_512,                // llvm.x86.avx512.scatter.dpq.512
+    x86_avx512_scatter_dps_512,                // llvm.x86.avx512.scatter.dps.512
+    x86_avx512_scatter_qpd_512,                // llvm.x86.avx512.scatter.qpd.512
+    x86_avx512_scatter_qpi_512,                // llvm.x86.avx512.scatter.qpi.512
+    x86_avx512_scatter_qpq_512,                // llvm.x86.avx512.scatter.qpq.512
+    x86_avx512_scatter_qps_512,                // llvm.x86.avx512.scatter.qps.512
+    x86_avx512_scatterpf_dpd_512,              // llvm.x86.avx512.scatterpf.dpd.512
+    x86_avx512_scatterpf_dps_512,              // llvm.x86.avx512.scatterpf.dps.512
+    x86_avx512_scatterpf_qpd_512,              // llvm.x86.avx512.scatterpf.qpd.512
+    x86_avx512_scatterpf_qps_512,              // llvm.x86.avx512.scatterpf.qps.512
+    x86_avx512_sqrt_pd_512,                    // llvm.x86.avx512.sqrt.pd.512
+    x86_avx512_sqrt_ps_512,                    // llvm.x86.avx512.sqrt.ps.512
+    x86_avx512_sqrt_sd,                        // llvm.x86.avx512.sqrt.sd
+    x86_avx512_sqrt_ss,                        // llvm.x86.avx512.sqrt.ss
+    x86_avx512_vbroadcast_sd_512,              // llvm.x86.avx512.vbroadcast.sd.512
+    x86_avx512_vbroadcast_sd_pd_512,           // llvm.x86.avx512.vbroadcast.sd.pd.512
+    x86_avx512_vbroadcast_ss_512,              // llvm.x86.avx512.vbroadcast.ss.512
+    x86_avx512_vbroadcast_ss_ps_512,           // llvm.x86.avx512.vbroadcast.ss.ps.512
+    x86_avx_addsub_pd_256,                     // llvm.x86.avx.addsub.pd.256
+    x86_avx_addsub_ps_256,                     // llvm.x86.avx.addsub.ps.256
+    x86_avx_blend_pd_256,                      // llvm.x86.avx.blend.pd.256
+    x86_avx_blend_ps_256,                      // llvm.x86.avx.blend.ps.256
+    x86_avx_blendv_pd_256,                     // llvm.x86.avx.blendv.pd.256
+    x86_avx_blendv_ps_256,                     // llvm.x86.avx.blendv.ps.256
+    x86_avx_cmp_pd_256,                        // llvm.x86.avx.cmp.pd.256
+    x86_avx_cmp_ps_256,                        // llvm.x86.avx.cmp.ps.256
+    x86_avx_cvt_pd2_ps_256,                    // llvm.x86.avx.cvt.pd2.ps.256
+    x86_avx_cvt_pd2dq_256,                     // llvm.x86.avx.cvt.pd2dq.256
+    x86_avx_cvt_ps2_pd_256,                    // llvm.x86.avx.cvt.ps2.pd.256
+    x86_avx_cvt_ps2dq_256,                     // llvm.x86.avx.cvt.ps2dq.256
+    x86_avx_cvtdq2_pd_256,                     // llvm.x86.avx.cvtdq2.pd.256
+    x86_avx_cvtdq2_ps_256,                     // llvm.x86.avx.cvtdq2.ps.256
+    x86_avx_cvtt_pd2dq_256,                    // llvm.x86.avx.cvtt.pd2dq.256
+    x86_avx_cvtt_ps2dq_256,                    // llvm.x86.avx.cvtt.ps2dq.256
+    x86_avx_dp_ps_256,                         // llvm.x86.avx.dp.ps.256
+    x86_avx_hadd_pd_256,                       // llvm.x86.avx.hadd.pd.256
+    x86_avx_hadd_ps_256,                       // llvm.x86.avx.hadd.ps.256
+    x86_avx_hsub_pd_256,                       // llvm.x86.avx.hsub.pd.256
+    x86_avx_hsub_ps_256,                       // llvm.x86.avx.hsub.ps.256
+    x86_avx_ldu_dq_256,                        // llvm.x86.avx.ldu.dq.256
+    x86_avx_maskload_pd,                       // llvm.x86.avx.maskload.pd
+    x86_avx_maskload_pd_256,                   // llvm.x86.avx.maskload.pd.256
+    x86_avx_maskload_ps,                       // llvm.x86.avx.maskload.ps
+    x86_avx_maskload_ps_256,                   // llvm.x86.avx.maskload.ps.256
+    x86_avx_maskstore_pd,                      // llvm.x86.avx.maskstore.pd
+    x86_avx_maskstore_pd_256,                  // llvm.x86.avx.maskstore.pd.256
+    x86_avx_maskstore_ps,                      // llvm.x86.avx.maskstore.ps
+    x86_avx_maskstore_ps_256,                  // llvm.x86.avx.maskstore.ps.256
+    x86_avx_max_pd_256,                        // llvm.x86.avx.max.pd.256
+    x86_avx_max_ps_256,                        // llvm.x86.avx.max.ps.256
+    x86_avx_min_pd_256,                        // llvm.x86.avx.min.pd.256
+    x86_avx_min_ps_256,                        // llvm.x86.avx.min.ps.256
+    x86_avx_movmsk_pd_256,                     // llvm.x86.avx.movmsk.pd.256
+    x86_avx_movmsk_ps_256,                     // llvm.x86.avx.movmsk.ps.256
+    x86_avx_ptestc_256,                        // llvm.x86.avx.ptestc.256
+    x86_avx_ptestnzc_256,                      // llvm.x86.avx.ptestnzc.256
+    x86_avx_ptestz_256,                        // llvm.x86.avx.ptestz.256
+    x86_avx_rcp_ps_256,                        // llvm.x86.avx.rcp.ps.256
+    x86_avx_round_pd_256,                      // llvm.x86.avx.round.pd.256
+    x86_avx_round_ps_256,                      // llvm.x86.avx.round.ps.256
+    x86_avx_rsqrt_ps_256,                      // llvm.x86.avx.rsqrt.ps.256
+    x86_avx_sqrt_pd_256,                       // llvm.x86.avx.sqrt.pd.256
+    x86_avx_sqrt_ps_256,                       // llvm.x86.avx.sqrt.ps.256
+    x86_avx_storeu_dq_256,                     // llvm.x86.avx.storeu.dq.256
+    x86_avx_storeu_pd_256,                     // llvm.x86.avx.storeu.pd.256
+    x86_avx_storeu_ps_256,                     // llvm.x86.avx.storeu.ps.256
+    x86_avx_vbroadcastf128_pd_256,             // llvm.x86.avx.vbroadcastf128.pd.256
+    x86_avx_vbroadcastf128_ps_256,             // llvm.x86.avx.vbroadcastf128.ps.256
+    x86_avx_vextractf128_pd_256,               // llvm.x86.avx.vextractf128.pd.256
+    x86_avx_vextractf128_ps_256,               // llvm.x86.avx.vextractf128.ps.256
+    x86_avx_vextractf128_si_256,               // llvm.x86.avx.vextractf128.si.256
+    x86_avx_vinsertf128_pd_256,                // llvm.x86.avx.vinsertf128.pd.256
+    x86_avx_vinsertf128_ps_256,                // llvm.x86.avx.vinsertf128.ps.256
+    x86_avx_vinsertf128_si_256,                // llvm.x86.avx.vinsertf128.si.256
+    x86_avx_vperm2f128_pd_256,                 // llvm.x86.avx.vperm2f128.pd.256
+    x86_avx_vperm2f128_ps_256,                 // llvm.x86.avx.vperm2f128.ps.256
+    x86_avx_vperm2f128_si_256,                 // llvm.x86.avx.vperm2f128.si.256
+    x86_avx_vpermilvar_pd,                     // llvm.x86.avx.vpermilvar.pd
+    x86_avx_vpermilvar_pd_256,                 // llvm.x86.avx.vpermilvar.pd.256
+    x86_avx_vpermilvar_ps,                     // llvm.x86.avx.vpermilvar.ps
+    x86_avx_vpermilvar_ps_256,                 // llvm.x86.avx.vpermilvar.ps.256
+    x86_avx_vtestc_pd,                         // llvm.x86.avx.vtestc.pd
+    x86_avx_vtestc_pd_256,                     // llvm.x86.avx.vtestc.pd.256
+    x86_avx_vtestc_ps,                         // llvm.x86.avx.vtestc.ps
+    x86_avx_vtestc_ps_256,                     // llvm.x86.avx.vtestc.ps.256
+    x86_avx_vtestnzc_pd,                       // llvm.x86.avx.vtestnzc.pd
+    x86_avx_vtestnzc_pd_256,                   // llvm.x86.avx.vtestnzc.pd.256
+    x86_avx_vtestnzc_ps,                       // llvm.x86.avx.vtestnzc.ps
+    x86_avx_vtestnzc_ps_256,                   // llvm.x86.avx.vtestnzc.ps.256
+    x86_avx_vtestz_pd,                         // llvm.x86.avx.vtestz.pd
+    x86_avx_vtestz_pd_256,                     // llvm.x86.avx.vtestz.pd.256
+    x86_avx_vtestz_ps,                         // llvm.x86.avx.vtestz.ps
+    x86_avx_vtestz_ps_256,                     // llvm.x86.avx.vtestz.ps.256
+    x86_avx_vzeroall,                          // llvm.x86.avx.vzeroall
+    x86_avx_vzeroupper,                        // llvm.x86.avx.vzeroupper
+    x86_bmi_bextr_32,                          // llvm.x86.bmi.bextr.32
+    x86_bmi_bextr_64,                          // llvm.x86.bmi.bextr.64
+    x86_bmi_bzhi_32,                           // llvm.x86.bmi.bzhi.32
+    x86_bmi_bzhi_64,                           // llvm.x86.bmi.bzhi.64
+    x86_bmi_pdep_32,                           // llvm.x86.bmi.pdep.32
+    x86_bmi_pdep_64,                           // llvm.x86.bmi.pdep.64
+    x86_bmi_pext_32,                           // llvm.x86.bmi.pext.32
+    x86_bmi_pext_64,                           // llvm.x86.bmi.pext.64
+    x86_fma_vfmadd_pd,                         // llvm.x86.fma.vfmadd.pd
+    x86_fma_vfmadd_pd_256,                     // llvm.x86.fma.vfmadd.pd.256
+    x86_fma_vfmadd_pd_512,                     // llvm.x86.fma.vfmadd.pd.512
+    x86_fma_vfmadd_ps,                         // llvm.x86.fma.vfmadd.ps
+    x86_fma_vfmadd_ps_256,                     // llvm.x86.fma.vfmadd.ps.256
+    x86_fma_vfmadd_ps_512,                     // llvm.x86.fma.vfmadd.ps.512
+    x86_fma_vfmadd_sd,                         // llvm.x86.fma.vfmadd.sd
+    x86_fma_vfmadd_ss,                         // llvm.x86.fma.vfmadd.ss
+    x86_fma_vfmaddsub_pd,                      // llvm.x86.fma.vfmaddsub.pd
+    x86_fma_vfmaddsub_pd_256,                  // llvm.x86.fma.vfmaddsub.pd.256
+    x86_fma_vfmaddsub_pd_512,                  // llvm.x86.fma.vfmaddsub.pd.512
+    x86_fma_vfmaddsub_ps,                      // llvm.x86.fma.vfmaddsub.ps
+    x86_fma_vfmaddsub_ps_256,                  // llvm.x86.fma.vfmaddsub.ps.256
+    x86_fma_vfmaddsub_ps_512,                  // llvm.x86.fma.vfmaddsub.ps.512
+    x86_fma_vfmsub_pd,                         // llvm.x86.fma.vfmsub.pd
+    x86_fma_vfmsub_pd_256,                     // llvm.x86.fma.vfmsub.pd.256
+    x86_fma_vfmsub_pd_512,                     // llvm.x86.fma.vfmsub.pd.512
+    x86_fma_vfmsub_ps,                         // llvm.x86.fma.vfmsub.ps
+    x86_fma_vfmsub_ps_256,                     // llvm.x86.fma.vfmsub.ps.256
+    x86_fma_vfmsub_ps_512,                     // llvm.x86.fma.vfmsub.ps.512
+    x86_fma_vfmsub_sd,                         // llvm.x86.fma.vfmsub.sd
+    x86_fma_vfmsub_ss,                         // llvm.x86.fma.vfmsub.ss
+    x86_fma_vfmsubadd_pd,                      // llvm.x86.fma.vfmsubadd.pd
+    x86_fma_vfmsubadd_pd_256,                  // llvm.x86.fma.vfmsubadd.pd.256
+    x86_fma_vfmsubadd_pd_512,                  // llvm.x86.fma.vfmsubadd.pd.512
+    x86_fma_vfmsubadd_ps,                      // llvm.x86.fma.vfmsubadd.ps
+    x86_fma_vfmsubadd_ps_256,                  // llvm.x86.fma.vfmsubadd.ps.256
+    x86_fma_vfmsubadd_ps_512,                  // llvm.x86.fma.vfmsubadd.ps.512
+    x86_fma_vfnmadd_pd,                        // llvm.x86.fma.vfnmadd.pd
+    x86_fma_vfnmadd_pd_256,                    // llvm.x86.fma.vfnmadd.pd.256
+    x86_fma_vfnmadd_pd_512,                    // llvm.x86.fma.vfnmadd.pd.512
+    x86_fma_vfnmadd_ps,                        // llvm.x86.fma.vfnmadd.ps
+    x86_fma_vfnmadd_ps_256,                    // llvm.x86.fma.vfnmadd.ps.256
+    x86_fma_vfnmadd_ps_512,                    // llvm.x86.fma.vfnmadd.ps.512
+    x86_fma_vfnmadd_sd,                        // llvm.x86.fma.vfnmadd.sd
+    x86_fma_vfnmadd_ss,                        // llvm.x86.fma.vfnmadd.ss
+    x86_fma_vfnmsub_pd,                        // llvm.x86.fma.vfnmsub.pd
+    x86_fma_vfnmsub_pd_256,                    // llvm.x86.fma.vfnmsub.pd.256
+    x86_fma_vfnmsub_pd_512,                    // llvm.x86.fma.vfnmsub.pd.512
+    x86_fma_vfnmsub_ps,                        // llvm.x86.fma.vfnmsub.ps
+    x86_fma_vfnmsub_ps_256,                    // llvm.x86.fma.vfnmsub.ps.256
+    x86_fma_vfnmsub_ps_512,                    // llvm.x86.fma.vfnmsub.ps.512
+    x86_fma_vfnmsub_sd,                        // llvm.x86.fma.vfnmsub.sd
+    x86_fma_vfnmsub_ss,                        // llvm.x86.fma.vfnmsub.ss
+    x86_int,                                   // llvm.x86.int
+    x86_mmx_emms,                              // llvm.x86.mmx.emms
+    x86_mmx_femms,                             // llvm.x86.mmx.femms
+    x86_mmx_maskmovq,                          // llvm.x86.mmx.maskmovq
+    x86_mmx_movnt_dq,                          // llvm.x86.mmx.movnt.dq
+    x86_mmx_packssdw,                          // llvm.x86.mmx.packssdw
+    x86_mmx_packsswb,                          // llvm.x86.mmx.packsswb
+    x86_mmx_packuswb,                          // llvm.x86.mmx.packuswb
+    x86_mmx_padd_b,                            // llvm.x86.mmx.padd.b
+    x86_mmx_padd_d,                            // llvm.x86.mmx.padd.d
+    x86_mmx_padd_q,                            // llvm.x86.mmx.padd.q
+    x86_mmx_padd_w,                            // llvm.x86.mmx.padd.w
+    x86_mmx_padds_b,                           // llvm.x86.mmx.padds.b
+    x86_mmx_padds_w,                           // llvm.x86.mmx.padds.w
+    x86_mmx_paddus_b,                          // llvm.x86.mmx.paddus.b
+    x86_mmx_paddus_w,                          // llvm.x86.mmx.paddus.w
+    x86_mmx_palignr_b,                         // llvm.x86.mmx.palignr.b
+    x86_mmx_pand,                              // llvm.x86.mmx.pand
+    x86_mmx_pandn,                             // llvm.x86.mmx.pandn
+    x86_mmx_pavg_b,                            // llvm.x86.mmx.pavg.b
+    x86_mmx_pavg_w,                            // llvm.x86.mmx.pavg.w
+    x86_mmx_pcmpeq_b,                          // llvm.x86.mmx.pcmpeq.b
+    x86_mmx_pcmpeq_d,                          // llvm.x86.mmx.pcmpeq.d
+    x86_mmx_pcmpeq_w,                          // llvm.x86.mmx.pcmpeq.w
+    x86_mmx_pcmpgt_b,                          // llvm.x86.mmx.pcmpgt.b
+    x86_mmx_pcmpgt_d,                          // llvm.x86.mmx.pcmpgt.d
+    x86_mmx_pcmpgt_w,                          // llvm.x86.mmx.pcmpgt.w
+    x86_mmx_pextr_w,                           // llvm.x86.mmx.pextr.w
+    x86_mmx_pinsr_w,                           // llvm.x86.mmx.pinsr.w
+    x86_mmx_pmadd_wd,                          // llvm.x86.mmx.pmadd.wd
+    x86_mmx_pmaxs_w,                           // llvm.x86.mmx.pmaxs.w
+    x86_mmx_pmaxu_b,                           // llvm.x86.mmx.pmaxu.b
+    x86_mmx_pmins_w,                           // llvm.x86.mmx.pmins.w
+    x86_mmx_pminu_b,                           // llvm.x86.mmx.pminu.b
+    x86_mmx_pmovmskb,                          // llvm.x86.mmx.pmovmskb
+    x86_mmx_pmulh_w,                           // llvm.x86.mmx.pmulh.w
+    x86_mmx_pmulhu_w,                          // llvm.x86.mmx.pmulhu.w
+    x86_mmx_pmull_w,                           // llvm.x86.mmx.pmull.w
+    x86_mmx_pmulu_dq,                          // llvm.x86.mmx.pmulu.dq
+    x86_mmx_por,                               // llvm.x86.mmx.por
+    x86_mmx_psad_bw,                           // llvm.x86.mmx.psad.bw
+    x86_mmx_psll_d,                            // llvm.x86.mmx.psll.d
+    x86_mmx_psll_q,                            // llvm.x86.mmx.psll.q
+    x86_mmx_psll_w,                            // llvm.x86.mmx.psll.w
+    x86_mmx_pslli_d,                           // llvm.x86.mmx.pslli.d
+    x86_mmx_pslli_q,                           // llvm.x86.mmx.pslli.q
+    x86_mmx_pslli_w,                           // llvm.x86.mmx.pslli.w
+    x86_mmx_psra_d,                            // llvm.x86.mmx.psra.d
+    x86_mmx_psra_w,                            // llvm.x86.mmx.psra.w
+    x86_mmx_psrai_d,                           // llvm.x86.mmx.psrai.d
+    x86_mmx_psrai_w,                           // llvm.x86.mmx.psrai.w
+    x86_mmx_psrl_d,                            // llvm.x86.mmx.psrl.d
+    x86_mmx_psrl_q,                            // llvm.x86.mmx.psrl.q
+    x86_mmx_psrl_w,                            // llvm.x86.mmx.psrl.w
+    x86_mmx_psrli_d,                           // llvm.x86.mmx.psrli.d
+    x86_mmx_psrli_q,                           // llvm.x86.mmx.psrli.q
+    x86_mmx_psrli_w,                           // llvm.x86.mmx.psrli.w
+    x86_mmx_psub_b,                            // llvm.x86.mmx.psub.b
+    x86_mmx_psub_d,                            // llvm.x86.mmx.psub.d
+    x86_mmx_psub_q,                            // llvm.x86.mmx.psub.q
+    x86_mmx_psub_w,                            // llvm.x86.mmx.psub.w
+    x86_mmx_psubs_b,                           // llvm.x86.mmx.psubs.b
+    x86_mmx_psubs_w,                           // llvm.x86.mmx.psubs.w
+    x86_mmx_psubus_b,                          // llvm.x86.mmx.psubus.b
+    x86_mmx_psubus_w,                          // llvm.x86.mmx.psubus.w
+    x86_mmx_punpckhbw,                         // llvm.x86.mmx.punpckhbw
+    x86_mmx_punpckhdq,                         // llvm.x86.mmx.punpckhdq
+    x86_mmx_punpckhwd,                         // llvm.x86.mmx.punpckhwd
+    x86_mmx_punpcklbw,                         // llvm.x86.mmx.punpcklbw
+    x86_mmx_punpckldq,                         // llvm.x86.mmx.punpckldq
+    x86_mmx_punpcklwd,                         // llvm.x86.mmx.punpcklwd
+    x86_mmx_pxor,                              // llvm.x86.mmx.pxor
+    x86_pclmulqdq,                             // llvm.x86.pclmulqdq
+    x86_rdfsbase_32,                           // llvm.x86.rdfsbase.32
+    x86_rdfsbase_64,                           // llvm.x86.rdfsbase.64
+    x86_rdgsbase_32,                           // llvm.x86.rdgsbase.32
+    x86_rdgsbase_64,                           // llvm.x86.rdgsbase.64
+    x86_rdpmc,                                 // llvm.x86.rdpmc
+    x86_rdrand_16,                             // llvm.x86.rdrand.16
+    x86_rdrand_32,                             // llvm.x86.rdrand.32
+    x86_rdrand_64,                             // llvm.x86.rdrand.64
+    x86_rdseed_16,                             // llvm.x86.rdseed.16
+    x86_rdseed_32,                             // llvm.x86.rdseed.32
+    x86_rdseed_64,                             // llvm.x86.rdseed.64
+    x86_rdtsc,                                 // llvm.x86.rdtsc
+    x86_rdtscp,                                // llvm.x86.rdtscp
+    x86_sha1msg1,                              // llvm.x86.sha1msg1
+    x86_sha1msg2,                              // llvm.x86.sha1msg2
+    x86_sha1nexte,                             // llvm.x86.sha1nexte
+    x86_sha1rnds4,                             // llvm.x86.sha1rnds4
+    x86_sha256msg1,                            // llvm.x86.sha256msg1
+    x86_sha256msg2,                            // llvm.x86.sha256msg2
+    x86_sha256rnds2,                           // llvm.x86.sha256rnds2
+    x86_sse2_add_sd,                           // llvm.x86.sse2.add.sd
+    x86_sse2_clflush,                          // llvm.x86.sse2.clflush
+    x86_sse2_cmp_pd,                           // llvm.x86.sse2.cmp.pd
+    x86_sse2_cmp_sd,                           // llvm.x86.sse2.cmp.sd
+    x86_sse2_comieq_sd,                        // llvm.x86.sse2.comieq.sd
+    x86_sse2_comige_sd,                        // llvm.x86.sse2.comige.sd
+    x86_sse2_comigt_sd,                        // llvm.x86.sse2.comigt.sd
+    x86_sse2_comile_sd,                        // llvm.x86.sse2.comile.sd
+    x86_sse2_comilt_sd,                        // llvm.x86.sse2.comilt.sd
+    x86_sse2_comineq_sd,                       // llvm.x86.sse2.comineq.sd
+    x86_sse2_cvtdq2pd,                         // llvm.x86.sse2.cvtdq2pd
+    x86_sse2_cvtdq2ps,                         // llvm.x86.sse2.cvtdq2ps
+    x86_sse2_cvtpd2dq,                         // llvm.x86.sse2.cvtpd2dq
+    x86_sse2_cvtpd2ps,                         // llvm.x86.sse2.cvtpd2ps
+    x86_sse2_cvtps2dq,                         // llvm.x86.sse2.cvtps2dq
+    x86_sse2_cvtps2pd,                         // llvm.x86.sse2.cvtps2pd
+    x86_sse2_cvtsd2si,                         // llvm.x86.sse2.cvtsd2si
+    x86_sse2_cvtsd2si64,                       // llvm.x86.sse2.cvtsd2si64
+    x86_sse2_cvtsd2ss,                         // llvm.x86.sse2.cvtsd2ss
+    x86_sse2_cvtsi2sd,                         // llvm.x86.sse2.cvtsi2sd
+    x86_sse2_cvtsi642sd,                       // llvm.x86.sse2.cvtsi642sd
+    x86_sse2_cvtss2sd,                         // llvm.x86.sse2.cvtss2sd
+    x86_sse2_cvttpd2dq,                        // llvm.x86.sse2.cvttpd2dq
+    x86_sse2_cvttps2dq,                        // llvm.x86.sse2.cvttps2dq
+    x86_sse2_cvttsd2si,                        // llvm.x86.sse2.cvttsd2si
+    x86_sse2_cvttsd2si64,                      // llvm.x86.sse2.cvttsd2si64
+    x86_sse2_div_sd,                           // llvm.x86.sse2.div.sd
+    x86_sse2_lfence,                           // llvm.x86.sse2.lfence
+    x86_sse2_maskmov_dqu,                      // llvm.x86.sse2.maskmov.dqu
+    x86_sse2_max_pd,                           // llvm.x86.sse2.max.pd
+    x86_sse2_max_sd,                           // llvm.x86.sse2.max.sd
+    x86_sse2_mfence,                           // llvm.x86.sse2.mfence
+    x86_sse2_min_pd,                           // llvm.x86.sse2.min.pd
+    x86_sse2_min_sd,                           // llvm.x86.sse2.min.sd
+    x86_sse2_movmsk_pd,                        // llvm.x86.sse2.movmsk.pd
+    x86_sse2_mul_sd,                           // llvm.x86.sse2.mul.sd
+    x86_sse2_packssdw_128,                     // llvm.x86.sse2.packssdw.128
+    x86_sse2_packsswb_128,                     // llvm.x86.sse2.packsswb.128
+    x86_sse2_packuswb_128,                     // llvm.x86.sse2.packuswb.128
+    x86_sse2_padds_b,                          // llvm.x86.sse2.padds.b
+    x86_sse2_padds_w,                          // llvm.x86.sse2.padds.w
+    x86_sse2_paddus_b,                         // llvm.x86.sse2.paddus.b
+    x86_sse2_paddus_w,                         // llvm.x86.sse2.paddus.w
+    x86_sse2_pause,                            // llvm.x86.sse2.pause
+    x86_sse2_pavg_b,                           // llvm.x86.sse2.pavg.b
+    x86_sse2_pavg_w,                           // llvm.x86.sse2.pavg.w
+    x86_sse2_pmadd_wd,                         // llvm.x86.sse2.pmadd.wd
+    x86_sse2_pmaxs_w,                          // llvm.x86.sse2.pmaxs.w
+    x86_sse2_pmaxu_b,                          // llvm.x86.sse2.pmaxu.b
+    x86_sse2_pmins_w,                          // llvm.x86.sse2.pmins.w
+    x86_sse2_pminu_b,                          // llvm.x86.sse2.pminu.b
+    x86_sse2_pmovmskb_128,                     // llvm.x86.sse2.pmovmskb.128
+    x86_sse2_pmulh_w,                          // llvm.x86.sse2.pmulh.w
+    x86_sse2_pmulhu_w,                         // llvm.x86.sse2.pmulhu.w
+    x86_sse2_pmulu_dq,                         // llvm.x86.sse2.pmulu.dq
+    x86_sse2_psad_bw,                          // llvm.x86.sse2.psad.bw
+    x86_sse2_pshuf_d,                          // llvm.x86.sse2.pshuf.d
+    x86_sse2_pshufh_w,                         // llvm.x86.sse2.pshufh.w
+    x86_sse2_pshufl_w,                         // llvm.x86.sse2.pshufl.w
+    x86_sse2_psll_d,                           // llvm.x86.sse2.psll.d
+    x86_sse2_psll_dq,                          // llvm.x86.sse2.psll.dq
+    x86_sse2_psll_dq_bs,                       // llvm.x86.sse2.psll.dq.bs
+    x86_sse2_psll_q,                           // llvm.x86.sse2.psll.q
+    x86_sse2_psll_w,                           // llvm.x86.sse2.psll.w
+    x86_sse2_pslli_d,                          // llvm.x86.sse2.pslli.d
+    x86_sse2_pslli_q,                          // llvm.x86.sse2.pslli.q
+    x86_sse2_pslli_w,                          // llvm.x86.sse2.pslli.w
+    x86_sse2_psra_d,                           // llvm.x86.sse2.psra.d
+    x86_sse2_psra_w,                           // llvm.x86.sse2.psra.w
+    x86_sse2_psrai_d,                          // llvm.x86.sse2.psrai.d
+    x86_sse2_psrai_w,                          // llvm.x86.sse2.psrai.w
+    x86_sse2_psrl_d,                           // llvm.x86.sse2.psrl.d
+    x86_sse2_psrl_dq,                          // llvm.x86.sse2.psrl.dq
+    x86_sse2_psrl_dq_bs,                       // llvm.x86.sse2.psrl.dq.bs
+    x86_sse2_psrl_q,                           // llvm.x86.sse2.psrl.q
+    x86_sse2_psrl_w,                           // llvm.x86.sse2.psrl.w
+    x86_sse2_psrli_d,                          // llvm.x86.sse2.psrli.d
+    x86_sse2_psrli_q,                          // llvm.x86.sse2.psrli.q
+    x86_sse2_psrli_w,                          // llvm.x86.sse2.psrli.w
+    x86_sse2_psubs_b,                          // llvm.x86.sse2.psubs.b
+    x86_sse2_psubs_w,                          // llvm.x86.sse2.psubs.w
+    x86_sse2_psubus_b,                         // llvm.x86.sse2.psubus.b
+    x86_sse2_psubus_w,                         // llvm.x86.sse2.psubus.w
+    x86_sse2_sqrt_pd,                          // llvm.x86.sse2.sqrt.pd
+    x86_sse2_sqrt_sd,                          // llvm.x86.sse2.sqrt.sd
+    x86_sse2_storel_dq,                        // llvm.x86.sse2.storel.dq
+    x86_sse2_storeu_dq,                        // llvm.x86.sse2.storeu.dq
+    x86_sse2_storeu_pd,                        // llvm.x86.sse2.storeu.pd
+    x86_sse2_sub_sd,                           // llvm.x86.sse2.sub.sd
+    x86_sse2_ucomieq_sd,                       // llvm.x86.sse2.ucomieq.sd
+    x86_sse2_ucomige_sd,                       // llvm.x86.sse2.ucomige.sd
+    x86_sse2_ucomigt_sd,                       // llvm.x86.sse2.ucomigt.sd
+    x86_sse2_ucomile_sd,                       // llvm.x86.sse2.ucomile.sd
+    x86_sse2_ucomilt_sd,                       // llvm.x86.sse2.ucomilt.sd
+    x86_sse2_ucomineq_sd,                      // llvm.x86.sse2.ucomineq.sd
+    x86_sse3_addsub_pd,                        // llvm.x86.sse3.addsub.pd
+    x86_sse3_addsub_ps,                        // llvm.x86.sse3.addsub.ps
+    x86_sse3_hadd_pd,                          // llvm.x86.sse3.hadd.pd
+    x86_sse3_hadd_ps,                          // llvm.x86.sse3.hadd.ps
+    x86_sse3_hsub_pd,                          // llvm.x86.sse3.hsub.pd
+    x86_sse3_hsub_ps,                          // llvm.x86.sse3.hsub.ps
+    x86_sse3_ldu_dq,                           // llvm.x86.sse3.ldu.dq
+    x86_sse3_monitor,                          // llvm.x86.sse3.monitor
+    x86_sse3_mwait,                            // llvm.x86.sse3.mwait
+    x86_sse41_blendpd,                         // llvm.x86.sse41.blendpd
+    x86_sse41_blendps,                         // llvm.x86.sse41.blendps
+    x86_sse41_blendvpd,                        // llvm.x86.sse41.blendvpd
+    x86_sse41_blendvps,                        // llvm.x86.sse41.blendvps
+    x86_sse41_dppd,                            // llvm.x86.sse41.dppd
+    x86_sse41_dpps,                            // llvm.x86.sse41.dpps
+    x86_sse41_extractps,                       // llvm.x86.sse41.extractps
+    x86_sse41_insertps,                        // llvm.x86.sse41.insertps
+    x86_sse41_movntdqa,                        // llvm.x86.sse41.movntdqa
+    x86_sse41_mpsadbw,                         // llvm.x86.sse41.mpsadbw
+    x86_sse41_packusdw,                        // llvm.x86.sse41.packusdw
+    x86_sse41_pblendvb,                        // llvm.x86.sse41.pblendvb
+    x86_sse41_pblendw,                         // llvm.x86.sse41.pblendw
+    x86_sse41_pextrb,                          // llvm.x86.sse41.pextrb
+    x86_sse41_pextrd,                          // llvm.x86.sse41.pextrd
+    x86_sse41_pextrq,                          // llvm.x86.sse41.pextrq
+    x86_sse41_phminposuw,                      // llvm.x86.sse41.phminposuw
+    x86_sse41_pmaxsb,                          // llvm.x86.sse41.pmaxsb
+    x86_sse41_pmaxsd,                          // llvm.x86.sse41.pmaxsd
+    x86_sse41_pmaxud,                          // llvm.x86.sse41.pmaxud
+    x86_sse41_pmaxuw,                          // llvm.x86.sse41.pmaxuw
+    x86_sse41_pminsb,                          // llvm.x86.sse41.pminsb
+    x86_sse41_pminsd,                          // llvm.x86.sse41.pminsd
+    x86_sse41_pminud,                          // llvm.x86.sse41.pminud
+    x86_sse41_pminuw,                          // llvm.x86.sse41.pminuw
+    x86_sse41_pmovsxbd,                        // llvm.x86.sse41.pmovsxbd
+    x86_sse41_pmovsxbq,                        // llvm.x86.sse41.pmovsxbq
+    x86_sse41_pmovsxbw,                        // llvm.x86.sse41.pmovsxbw
+    x86_sse41_pmovsxdq,                        // llvm.x86.sse41.pmovsxdq
+    x86_sse41_pmovsxwd,                        // llvm.x86.sse41.pmovsxwd
+    x86_sse41_pmovsxwq,                        // llvm.x86.sse41.pmovsxwq
+    x86_sse41_pmovzxbd,                        // llvm.x86.sse41.pmovzxbd
+    x86_sse41_pmovzxbq,                        // llvm.x86.sse41.pmovzxbq
+    x86_sse41_pmovzxbw,                        // llvm.x86.sse41.pmovzxbw
+    x86_sse41_pmovzxdq,                        // llvm.x86.sse41.pmovzxdq
+    x86_sse41_pmovzxwd,                        // llvm.x86.sse41.pmovzxwd
+    x86_sse41_pmovzxwq,                        // llvm.x86.sse41.pmovzxwq
+    x86_sse41_pmuldq,                          // llvm.x86.sse41.pmuldq
+    x86_sse41_ptestc,                          // llvm.x86.sse41.ptestc
+    x86_sse41_ptestnzc,                        // llvm.x86.sse41.ptestnzc
+    x86_sse41_ptestz,                          // llvm.x86.sse41.ptestz
+    x86_sse41_round_pd,                        // llvm.x86.sse41.round.pd
+    x86_sse41_round_ps,                        // llvm.x86.sse41.round.ps
+    x86_sse41_round_sd,                        // llvm.x86.sse41.round.sd
+    x86_sse41_round_ss,                        // llvm.x86.sse41.round.ss
+    x86_sse42_crc32_32_16,                     // llvm.x86.sse42.crc32.32.16
+    x86_sse42_crc32_32_32,                     // llvm.x86.sse42.crc32.32.32
+    x86_sse42_crc32_32_8,                      // llvm.x86.sse42.crc32.32.8
+    x86_sse42_crc32_64_64,                     // llvm.x86.sse42.crc32.64.64
+    x86_sse42_pcmpestri128,                    // llvm.x86.sse42.pcmpestri128
+    x86_sse42_pcmpestria128,                   // llvm.x86.sse42.pcmpestria128
+    x86_sse42_pcmpestric128,                   // llvm.x86.sse42.pcmpestric128
+    x86_sse42_pcmpestrio128,                   // llvm.x86.sse42.pcmpestrio128
+    x86_sse42_pcmpestris128,                   // llvm.x86.sse42.pcmpestris128
+    x86_sse42_pcmpestriz128,                   // llvm.x86.sse42.pcmpestriz128
+    x86_sse42_pcmpestrm128,                    // llvm.x86.sse42.pcmpestrm128
+    x86_sse42_pcmpistri128,                    // llvm.x86.sse42.pcmpistri128
+    x86_sse42_pcmpistria128,                   // llvm.x86.sse42.pcmpistria128
+    x86_sse42_pcmpistric128,                   // llvm.x86.sse42.pcmpistric128
+    x86_sse42_pcmpistrio128,                   // llvm.x86.sse42.pcmpistrio128
+    x86_sse42_pcmpistris128,                   // llvm.x86.sse42.pcmpistris128
+    x86_sse42_pcmpistriz128,                   // llvm.x86.sse42.pcmpistriz128
+    x86_sse42_pcmpistrm128,                    // llvm.x86.sse42.pcmpistrm128
+    x86_sse4a_extrq,                           // llvm.x86.sse4a.extrq
+    x86_sse4a_extrqi,                          // llvm.x86.sse4a.extrqi
+    x86_sse4a_insertq,                         // llvm.x86.sse4a.insertq
+    x86_sse4a_insertqi,                        // llvm.x86.sse4a.insertqi
+    x86_sse4a_movnt_sd,                        // llvm.x86.sse4a.movnt.sd
+    x86_sse4a_movnt_ss,                        // llvm.x86.sse4a.movnt.ss
+    x86_sse_add_ss,                            // llvm.x86.sse.add.ss
+    x86_sse_cmp_ps,                            // llvm.x86.sse.cmp.ps
+    x86_sse_cmp_ss,                            // llvm.x86.sse.cmp.ss
+    x86_sse_comieq_ss,                         // llvm.x86.sse.comieq.ss
+    x86_sse_comige_ss,                         // llvm.x86.sse.comige.ss
+    x86_sse_comigt_ss,                         // llvm.x86.sse.comigt.ss
+    x86_sse_comile_ss,                         // llvm.x86.sse.comile.ss
+    x86_sse_comilt_ss,                         // llvm.x86.sse.comilt.ss
+    x86_sse_comineq_ss,                        // llvm.x86.sse.comineq.ss
+    x86_sse_cvtpd2pi,                          // llvm.x86.sse.cvtpd2pi
+    x86_sse_cvtpi2pd,                          // llvm.x86.sse.cvtpi2pd
+    x86_sse_cvtpi2ps,                          // llvm.x86.sse.cvtpi2ps
+    x86_sse_cvtps2pi,                          // llvm.x86.sse.cvtps2pi
+    x86_sse_cvtsi2ss,                          // llvm.x86.sse.cvtsi2ss
+    x86_sse_cvtsi642ss,                        // llvm.x86.sse.cvtsi642ss
+    x86_sse_cvtss2si,                          // llvm.x86.sse.cvtss2si
+    x86_sse_cvtss2si64,                        // llvm.x86.sse.cvtss2si64
+    x86_sse_cvttpd2pi,                         // llvm.x86.sse.cvttpd2pi
+    x86_sse_cvttps2pi,                         // llvm.x86.sse.cvttps2pi
+    x86_sse_cvttss2si,                         // llvm.x86.sse.cvttss2si
+    x86_sse_cvttss2si64,                       // llvm.x86.sse.cvttss2si64
+    x86_sse_div_ss,                            // llvm.x86.sse.div.ss
+    x86_sse_ldmxcsr,                           // llvm.x86.sse.ldmxcsr
+    x86_sse_max_ps,                            // llvm.x86.sse.max.ps
+    x86_sse_max_ss,                            // llvm.x86.sse.max.ss
+    x86_sse_min_ps,                            // llvm.x86.sse.min.ps
+    x86_sse_min_ss,                            // llvm.x86.sse.min.ss
+    x86_sse_movmsk_ps,                         // llvm.x86.sse.movmsk.ps
+    x86_sse_mul_ss,                            // llvm.x86.sse.mul.ss
+    x86_sse_pshuf_w,                           // llvm.x86.sse.pshuf.w
+    x86_sse_rcp_ps,                            // llvm.x86.sse.rcp.ps
+    x86_sse_rcp_ss,                            // llvm.x86.sse.rcp.ss
+    x86_sse_rsqrt_ps,                          // llvm.x86.sse.rsqrt.ps
+    x86_sse_rsqrt_ss,                          // llvm.x86.sse.rsqrt.ss
+    x86_sse_sfence,                            // llvm.x86.sse.sfence
+    x86_sse_sqrt_ps,                           // llvm.x86.sse.sqrt.ps
+    x86_sse_sqrt_ss,                           // llvm.x86.sse.sqrt.ss
+    x86_sse_stmxcsr,                           // llvm.x86.sse.stmxcsr
+    x86_sse_storeu_ps,                         // llvm.x86.sse.storeu.ps
+    x86_sse_sub_ss,                            // llvm.x86.sse.sub.ss
+    x86_sse_ucomieq_ss,                        // llvm.x86.sse.ucomieq.ss
+    x86_sse_ucomige_ss,                        // llvm.x86.sse.ucomige.ss
+    x86_sse_ucomigt_ss,                        // llvm.x86.sse.ucomigt.ss
+    x86_sse_ucomile_ss,                        // llvm.x86.sse.ucomile.ss
+    x86_sse_ucomilt_ss,                        // llvm.x86.sse.ucomilt.ss
+    x86_sse_ucomineq_ss,                       // llvm.x86.sse.ucomineq.ss
+    x86_ssse3_pabs_b,                          // llvm.x86.ssse3.pabs.b
+    x86_ssse3_pabs_b_128,                      // llvm.x86.ssse3.pabs.b.128
+    x86_ssse3_pabs_d,                          // llvm.x86.ssse3.pabs.d
+    x86_ssse3_pabs_d_128,                      // llvm.x86.ssse3.pabs.d.128
+    x86_ssse3_pabs_w,                          // llvm.x86.ssse3.pabs.w
+    x86_ssse3_pabs_w_128,                      // llvm.x86.ssse3.pabs.w.128
+    x86_ssse3_phadd_d,                         // llvm.x86.ssse3.phadd.d
+    x86_ssse3_phadd_d_128,                     // llvm.x86.ssse3.phadd.d.128
+    x86_ssse3_phadd_sw,                        // llvm.x86.ssse3.phadd.sw
+    x86_ssse3_phadd_sw_128,                    // llvm.x86.ssse3.phadd.sw.128
+    x86_ssse3_phadd_w,                         // llvm.x86.ssse3.phadd.w
+    x86_ssse3_phadd_w_128,                     // llvm.x86.ssse3.phadd.w.128
+    x86_ssse3_phsub_d,                         // llvm.x86.ssse3.phsub.d
+    x86_ssse3_phsub_d_128,                     // llvm.x86.ssse3.phsub.d.128
+    x86_ssse3_phsub_sw,                        // llvm.x86.ssse3.phsub.sw
+    x86_ssse3_phsub_sw_128,                    // llvm.x86.ssse3.phsub.sw.128
+    x86_ssse3_phsub_w,                         // llvm.x86.ssse3.phsub.w
+    x86_ssse3_phsub_w_128,                     // llvm.x86.ssse3.phsub.w.128
+    x86_ssse3_pmadd_ub_sw,                     // llvm.x86.ssse3.pmadd.ub.sw
+    x86_ssse3_pmadd_ub_sw_128,                 // llvm.x86.ssse3.pmadd.ub.sw.128
+    x86_ssse3_pmul_hr_sw,                      // llvm.x86.ssse3.pmul.hr.sw
+    x86_ssse3_pmul_hr_sw_128,                  // llvm.x86.ssse3.pmul.hr.sw.128
+    x86_ssse3_pshuf_b,                         // llvm.x86.ssse3.pshuf.b
+    x86_ssse3_pshuf_b_128,                     // llvm.x86.ssse3.pshuf.b.128
+    x86_ssse3_psign_b,                         // llvm.x86.ssse3.psign.b
+    x86_ssse3_psign_b_128,                     // llvm.x86.ssse3.psign.b.128
+    x86_ssse3_psign_d,                         // llvm.x86.ssse3.psign.d
+    x86_ssse3_psign_d_128,                     // llvm.x86.ssse3.psign.d.128
+    x86_ssse3_psign_w,                         // llvm.x86.ssse3.psign.w
+    x86_ssse3_psign_w_128,                     // llvm.x86.ssse3.psign.w.128
+    x86_tbm_bextri_u32,                        // llvm.x86.tbm.bextri.u32
+    x86_tbm_bextri_u64,                        // llvm.x86.tbm.bextri.u64
+    x86_vcvtph2ps_128,                         // llvm.x86.vcvtph2ps.128
+    x86_vcvtph2ps_256,                         // llvm.x86.vcvtph2ps.256
+    x86_vcvtps2ph_128,                         // llvm.x86.vcvtps2ph.128
+    x86_vcvtps2ph_256,                         // llvm.x86.vcvtps2ph.256
+    x86_wrfsbase_32,                           // llvm.x86.wrfsbase.32
+    x86_wrfsbase_64,                           // llvm.x86.wrfsbase.64
+    x86_wrgsbase_32,                           // llvm.x86.wrgsbase.32
+    x86_wrgsbase_64,                           // llvm.x86.wrgsbase.64
+    x86_xabort,                                // llvm.x86.xabort
+    x86_xbegin,                                // llvm.x86.xbegin
+    x86_xend,                                  // llvm.x86.xend
+    x86_xop_vfrcz_pd,                          // llvm.x86.xop.vfrcz.pd
+    x86_xop_vfrcz_pd_256,                      // llvm.x86.xop.vfrcz.pd.256
+    x86_xop_vfrcz_ps,                          // llvm.x86.xop.vfrcz.ps
+    x86_xop_vfrcz_ps_256,                      // llvm.x86.xop.vfrcz.ps.256
+    x86_xop_vfrcz_sd,                          // llvm.x86.xop.vfrcz.sd
+    x86_xop_vfrcz_ss,                          // llvm.x86.xop.vfrcz.ss
+    x86_xop_vpcmov,                            // llvm.x86.xop.vpcmov
+    x86_xop_vpcmov_256,                        // llvm.x86.xop.vpcmov.256
+    x86_xop_vpcomb,                            // llvm.x86.xop.vpcomb
+    x86_xop_vpcomd,                            // llvm.x86.xop.vpcomd
+    x86_xop_vpcomq,                            // llvm.x86.xop.vpcomq
+    x86_xop_vpcomub,                           // llvm.x86.xop.vpcomub
+    x86_xop_vpcomud,                           // llvm.x86.xop.vpcomud
+    x86_xop_vpcomuq,                           // llvm.x86.xop.vpcomuq
+    x86_xop_vpcomuw,                           // llvm.x86.xop.vpcomuw
+    x86_xop_vpcomw,                            // llvm.x86.xop.vpcomw
+    x86_xop_vpermil2pd,                        // llvm.x86.xop.vpermil2pd
+    x86_xop_vpermil2pd_256,                    // llvm.x86.xop.vpermil2pd.256
+    x86_xop_vpermil2ps,                        // llvm.x86.xop.vpermil2ps
+    x86_xop_vpermil2ps_256,                    // llvm.x86.xop.vpermil2ps.256
+    x86_xop_vphaddbd,                          // llvm.x86.xop.vphaddbd
+    x86_xop_vphaddbq,                          // llvm.x86.xop.vphaddbq
+    x86_xop_vphaddbw,                          // llvm.x86.xop.vphaddbw
+    x86_xop_vphadddq,                          // llvm.x86.xop.vphadddq
+    x86_xop_vphaddubd,                         // llvm.x86.xop.vphaddubd
+    x86_xop_vphaddubq,                         // llvm.x86.xop.vphaddubq
+    x86_xop_vphaddubw,                         // llvm.x86.xop.vphaddubw
+    x86_xop_vphaddudq,                         // llvm.x86.xop.vphaddudq
+    x86_xop_vphadduwd,                         // llvm.x86.xop.vphadduwd
+    x86_xop_vphadduwq,                         // llvm.x86.xop.vphadduwq
+    x86_xop_vphaddwd,                          // llvm.x86.xop.vphaddwd
+    x86_xop_vphaddwq,                          // llvm.x86.xop.vphaddwq
+    x86_xop_vphsubbw,                          // llvm.x86.xop.vphsubbw
+    x86_xop_vphsubdq,                          // llvm.x86.xop.vphsubdq
+    x86_xop_vphsubwd,                          // llvm.x86.xop.vphsubwd
+    x86_xop_vpmacsdd,                          // llvm.x86.xop.vpmacsdd
+    x86_xop_vpmacsdqh,                         // llvm.x86.xop.vpmacsdqh
+    x86_xop_vpmacsdql,                         // llvm.x86.xop.vpmacsdql
+    x86_xop_vpmacssdd,                         // llvm.x86.xop.vpmacssdd
+    x86_xop_vpmacssdqh,                        // llvm.x86.xop.vpmacssdqh
+    x86_xop_vpmacssdql,                        // llvm.x86.xop.vpmacssdql
+    x86_xop_vpmacsswd,                         // llvm.x86.xop.vpmacsswd
+    x86_xop_vpmacssww,                         // llvm.x86.xop.vpmacssww
+    x86_xop_vpmacswd,                          // llvm.x86.xop.vpmacswd
+    x86_xop_vpmacsww,                          // llvm.x86.xop.vpmacsww
+    x86_xop_vpmadcsswd,                        // llvm.x86.xop.vpmadcsswd
+    x86_xop_vpmadcswd,                         // llvm.x86.xop.vpmadcswd
+    x86_xop_vpperm,                            // llvm.x86.xop.vpperm
+    x86_xop_vprotb,                            // llvm.x86.xop.vprotb
+    x86_xop_vprotbi,                           // llvm.x86.xop.vprotbi
+    x86_xop_vprotd,                            // llvm.x86.xop.vprotd
+    x86_xop_vprotdi,                           // llvm.x86.xop.vprotdi
+    x86_xop_vprotq,                            // llvm.x86.xop.vprotq
+    x86_xop_vprotqi,                           // llvm.x86.xop.vprotqi
+    x86_xop_vprotw,                            // llvm.x86.xop.vprotw
+    x86_xop_vprotwi,                           // llvm.x86.xop.vprotwi
+    x86_xop_vpshab,                            // llvm.x86.xop.vpshab
+    x86_xop_vpshad,                            // llvm.x86.xop.vpshad
+    x86_xop_vpshaq,                            // llvm.x86.xop.vpshaq
+    x86_xop_vpshaw,                            // llvm.x86.xop.vpshaw
+    x86_xop_vpshlb,                            // llvm.x86.xop.vpshlb
+    x86_xop_vpshld,                            // llvm.x86.xop.vpshld
+    x86_xop_vpshlq,                            // llvm.x86.xop.vpshlq
+    x86_xop_vpshlw,                            // llvm.x86.xop.vpshlw
+    x86_xtest,                                 // llvm.x86.xtest
+    xcore_bitrev,                              // llvm.xcore.bitrev
+    xcore_checkevent,                          // llvm.xcore.checkevent
+    xcore_chkct,                               // llvm.xcore.chkct
+    xcore_clre,                                // llvm.xcore.clre
+    xcore_clrpt,                               // llvm.xcore.clrpt
+    xcore_clrsr,                               // llvm.xcore.clrsr
+    xcore_crc32,                               // llvm.xcore.crc32
+    xcore_crc8,                                // llvm.xcore.crc8
+    xcore_edu,                                 // llvm.xcore.edu
+    xcore_eeu,                                 // llvm.xcore.eeu
+    xcore_endin,                               // llvm.xcore.endin
+    xcore_freer,                               // llvm.xcore.freer
+    xcore_geted,                               // llvm.xcore.geted
+    xcore_getet,                               // llvm.xcore.getet
+    xcore_getid,                               // llvm.xcore.getid
+    xcore_getps,                               // llvm.xcore.getps
+    xcore_getr,                                // llvm.xcore.getr
+    xcore_getst,                               // llvm.xcore.getst
+    xcore_getts,                               // llvm.xcore.getts
+    xcore_in,                                  // llvm.xcore.in
+    xcore_inct,                                // llvm.xcore.inct
+    xcore_initcp,                              // llvm.xcore.initcp
+    xcore_initdp,                              // llvm.xcore.initdp
+    xcore_initlr,                              // llvm.xcore.initlr
+    xcore_initpc,                              // llvm.xcore.initpc
+    xcore_initsp,                              // llvm.xcore.initsp
+    xcore_inshr,                               // llvm.xcore.inshr
+    xcore_int,                                 // llvm.xcore.int
+    xcore_mjoin,                               // llvm.xcore.mjoin
+    xcore_msync,                               // llvm.xcore.msync
+    xcore_out,                                 // llvm.xcore.out
+    xcore_outct,                               // llvm.xcore.outct
+    xcore_outshr,                              // llvm.xcore.outshr
+    xcore_outt,                                // llvm.xcore.outt
+    xcore_peek,                                // llvm.xcore.peek
+    xcore_setc,                                // llvm.xcore.setc
+    xcore_setclk,                              // llvm.xcore.setclk
+    xcore_setd,                                // llvm.xcore.setd
+    xcore_setev,                               // llvm.xcore.setev
+    xcore_setps,                               // llvm.xcore.setps
+    xcore_setpsc,                              // llvm.xcore.setpsc
+    xcore_setpt,                               // llvm.xcore.setpt
+    xcore_setrdy,                              // llvm.xcore.setrdy
+    xcore_setsr,                               // llvm.xcore.setsr
+    xcore_settw,                               // llvm.xcore.settw
+    xcore_setv,                                // llvm.xcore.setv
+    xcore_sext,                                // llvm.xcore.sext
+    xcore_ssync,                               // llvm.xcore.ssync
+    xcore_syncr,                               // llvm.xcore.syncr
+    xcore_testct,                              // llvm.xcore.testct
+    xcore_testwct,                             // llvm.xcore.testwct
+    xcore_waitevent,                           // llvm.xcore.waitevent
+    xcore_zext                                 // llvm.xcore.zext
+#endif
+
+// Intrinsic ID to name table
+#ifdef GET_INTRINSIC_NAME_TABLE
+  // Note that entry #0 is the invalid intrinsic!
+  "llvm.AMDGPU.div.fixup",
+  "llvm.AMDGPU.div.fmas",
+  "llvm.AMDGPU.div.scale",
+  "llvm.AMDGPU.rcp",
+  "llvm.AMDGPU.rsq",
+  "llvm.AMDGPU.rsq.clamped",
+  "llvm.AMDGPU.trig.preop",
+  "llvm.aarch64.clrex",
+  "llvm.aarch64.crc32b",
+  "llvm.aarch64.crc32cb",
+  "llvm.aarch64.crc32ch",
+  "llvm.aarch64.crc32cw",
+  "llvm.aarch64.crc32cx",
+  "llvm.aarch64.crc32h",
+  "llvm.aarch64.crc32w",
+  "llvm.aarch64.crc32x",
+  "llvm.aarch64.crypto.aesd",
+  "llvm.aarch64.crypto.aese",
+  "llvm.aarch64.crypto.aesimc",
+  "llvm.aarch64.crypto.aesmc",
+  "llvm.aarch64.crypto.sha1c",
+  "llvm.aarch64.crypto.sha1h",
+  "llvm.aarch64.crypto.sha1m",
+  "llvm.aarch64.crypto.sha1p",
+  "llvm.aarch64.crypto.sha1su0",
+  "llvm.aarch64.crypto.sha1su1",
+  "llvm.aarch64.crypto.sha256h",
+  "llvm.aarch64.crypto.sha256h2",
+  "llvm.aarch64.crypto.sha256su0",
+  "llvm.aarch64.crypto.sha256su1",
+  "llvm.aarch64.dmb",
+  "llvm.aarch64.dsb",
+  "llvm.aarch64.hint",
+  "llvm.aarch64.isb",
+  "llvm.aarch64.ldaxp",
+  "llvm.aarch64.ldaxr",
+  "llvm.aarch64.ldxp",
+  "llvm.aarch64.ldxr",
+  "llvm.aarch64.neon.abs",
+  "llvm.aarch64.neon.addhn",
+  "llvm.aarch64.neon.addp",
+  "llvm.aarch64.neon.cls",
+  "llvm.aarch64.neon.fabd",
+  "llvm.aarch64.neon.facge",
+  "llvm.aarch64.neon.facgt",
+  "llvm.aarch64.neon.faddv",
+  "llvm.aarch64.neon.fcvtas",
+  "llvm.aarch64.neon.fcvtau",
+  "llvm.aarch64.neon.fcvtms",
+  "llvm.aarch64.neon.fcvtmu",
+  "llvm.aarch64.neon.fcvtns",
+  "llvm.aarch64.neon.fcvtnu",
+  "llvm.aarch64.neon.fcvtps",
+  "llvm.aarch64.neon.fcvtpu",
+  "llvm.aarch64.neon.fcvtxn",
+  "llvm.aarch64.neon.fcvtzs",
+  "llvm.aarch64.neon.fcvtzu",
+  "llvm.aarch64.neon.fmax",
+  "llvm.aarch64.neon.fmaxnm",
+  "llvm.aarch64.neon.fmaxnmp",
+  "llvm.aarch64.neon.fmaxnmv",
+  "llvm.aarch64.neon.fmaxp",
+  "llvm.aarch64.neon.fmaxv",
+  "llvm.aarch64.neon.fmin",
+  "llvm.aarch64.neon.fminnm",
+  "llvm.aarch64.neon.fminnmp",
+  "llvm.aarch64.neon.fminnmv",
+  "llvm.aarch64.neon.fminp",
+  "llvm.aarch64.neon.fminv",
+  "llvm.aarch64.neon.fmulx",
+  "llvm.aarch64.neon.frecpe",
+  "llvm.aarch64.neon.frecps",
+  "llvm.aarch64.neon.frecpx",
+  "llvm.aarch64.neon.frintn",
+  "llvm.aarch64.neon.frsqrte",
+  "llvm.aarch64.neon.frsqrts",
+  "llvm.aarch64.neon.ld1x2",
+  "llvm.aarch64.neon.ld1x3",
+  "llvm.aarch64.neon.ld1x4",
+  "llvm.aarch64.neon.ld2",
+  "llvm.aarch64.neon.ld2lane",
+  "llvm.aarch64.neon.ld2r",
+  "llvm.aarch64.neon.ld3",
+  "llvm.aarch64.neon.ld3lane",
+  "llvm.aarch64.neon.ld3r",
+  "llvm.aarch64.neon.ld4",
+  "llvm.aarch64.neon.ld4lane",
+  "llvm.aarch64.neon.ld4r",
+  "llvm.aarch64.neon.pmul",
+  "llvm.aarch64.neon.pmull",
+  "llvm.aarch64.neon.pmull64",
+  "llvm.aarch64.neon.raddhn",
+  "llvm.aarch64.neon.rbit",
+  "llvm.aarch64.neon.rshrn",
+  "llvm.aarch64.neon.rsubhn",
+  "llvm.aarch64.neon.sabd",
+  "llvm.aarch64.neon.saddlp",
+  "llvm.aarch64.neon.saddlv",
+  "llvm.aarch64.neon.saddv",
+  "llvm.aarch64.neon.scalar.sqxtn",
+  "llvm.aarch64.neon.scalar.sqxtun",
+  "llvm.aarch64.neon.scalar.uqxtn",
+  "llvm.aarch64.neon.shadd",
+  "llvm.aarch64.neon.shll",
+  "llvm.aarch64.neon.shsub",
+  "llvm.aarch64.neon.smax",
+  "llvm.aarch64.neon.smaxp",
+  "llvm.aarch64.neon.smaxv",
+  "llvm.aarch64.neon.smin",
+  "llvm.aarch64.neon.sminp",
+  "llvm.aarch64.neon.sminv",
+  "llvm.aarch64.neon.smull",
+  "llvm.aarch64.neon.sqabs",
+  "llvm.aarch64.neon.sqadd",
+  "llvm.aarch64.neon.sqdmulh",
+  "llvm.aarch64.neon.sqdmull",
+  "llvm.aarch64.neon.sqdmulls.scalar",
+  "llvm.aarch64.neon.sqneg",
+  "llvm.aarch64.neon.sqrdmulh",
+  "llvm.aarch64.neon.sqrshl",
+  "llvm.aarch64.neon.sqrshrn",
+  "llvm.aarch64.neon.sqrshrun",
+  "llvm.aarch64.neon.sqshl",
+  "llvm.aarch64.neon.sqshlu",
+  "llvm.aarch64.neon.sqshrn",
+  "llvm.aarch64.neon.sqshrun",
+  "llvm.aarch64.neon.sqsub",
+  "llvm.aarch64.neon.sqxtn",
+  "llvm.aarch64.neon.sqxtun",
+  "llvm.aarch64.neon.srhadd",
+  "llvm.aarch64.neon.srshl",
+  "llvm.aarch64.neon.sshl",
+  "llvm.aarch64.neon.sshll",
+  "llvm.aarch64.neon.st1x2",
+  "llvm.aarch64.neon.st1x3",
+  "llvm.aarch64.neon.st1x4",
+  "llvm.aarch64.neon.st2",
+  "llvm.aarch64.neon.st2lane",
+  "llvm.aarch64.neon.st3",
+  "llvm.aarch64.neon.st3lane",
+  "llvm.aarch64.neon.st4",
+  "llvm.aarch64.neon.st4lane",
+  "llvm.aarch64.neon.subhn",
+  "llvm.aarch64.neon.suqadd",
+  "llvm.aarch64.neon.tbl1",
+  "llvm.aarch64.neon.tbl2",
+  "llvm.aarch64.neon.tbl3",
+  "llvm.aarch64.neon.tbl4",
+  "llvm.aarch64.neon.tbx1",
+  "llvm.aarch64.neon.tbx2",
+  "llvm.aarch64.neon.tbx3",
+  "llvm.aarch64.neon.tbx4",
+  "llvm.aarch64.neon.uabd",
+  "llvm.aarch64.neon.uaddlp",
+  "llvm.aarch64.neon.uaddlv",
+  "llvm.aarch64.neon.uaddv",
+  "llvm.aarch64.neon.uhadd",
+  "llvm.aarch64.neon.uhsub",
+  "llvm.aarch64.neon.umax",
+  "llvm.aarch64.neon.umaxp",
+  "llvm.aarch64.neon.umaxv",
+  "llvm.aarch64.neon.umin",
+  "llvm.aarch64.neon.uminp",
+  "llvm.aarch64.neon.uminv",
+  "llvm.aarch64.neon.umull",
+  "llvm.aarch64.neon.uqadd",
+  "llvm.aarch64.neon.uqrshl",
+  "llvm.aarch64.neon.uqrshrn",
+  "llvm.aarch64.neon.uqshl",
+  "llvm.aarch64.neon.uqshrn",
+  "llvm.aarch64.neon.uqsub",
+  "llvm.aarch64.neon.uqxtn",
+  "llvm.aarch64.neon.urecpe",
+  "llvm.aarch64.neon.urhadd",
+  "llvm.aarch64.neon.urshl",
+  "llvm.aarch64.neon.ursqrte",
+  "llvm.aarch64.neon.ushl",
+  "llvm.aarch64.neon.ushll",
+  "llvm.aarch64.neon.usqadd",
+  "llvm.aarch64.neon.vcopy.lane",
+  "llvm.aarch64.neon.vcvtfp2fxs",
+  "llvm.aarch64.neon.vcvtfp2fxu",
+  "llvm.aarch64.neon.vcvtfp2hf",
+  "llvm.aarch64.neon.vcvtfxs2fp",
+  "llvm.aarch64.neon.vcvtfxu2fp",
+  "llvm.aarch64.neon.vcvthf2fp",
+  "llvm.aarch64.neon.vsli",
+  "llvm.aarch64.neon.vsri",
+  "llvm.aarch64.rbit",
+  "llvm.aarch64.sdiv",
+  "llvm.aarch64.sisd.fabd",
+  "llvm.aarch64.sisd.fcvtxn",
+  "llvm.aarch64.stlxp",
+  "llvm.aarch64.stlxr",
+  "llvm.aarch64.stxp",
+  "llvm.aarch64.stxr",
+  "llvm.aarch64.udiv",
+  "llvm.adjust.trampoline",
+  "llvm.annotation",
+  "llvm.arm.cdp",
+  "llvm.arm.cdp2",
+  "llvm.arm.clrex",
+  "llvm.arm.crc32b",
+  "llvm.arm.crc32cb",
+  "llvm.arm.crc32ch",
+  "llvm.arm.crc32cw",
+  "llvm.arm.crc32h",
+  "llvm.arm.crc32w",
+  "llvm.arm.dmb",
+  "llvm.arm.dsb",
+  "llvm.arm.get.fpscr",
+  "llvm.arm.hint",
+  "llvm.arm.isb",
+  "llvm.arm.ldaex",
+  "llvm.arm.ldaexd",
+  "llvm.arm.ldrex",
+  "llvm.arm.ldrexd",
+  "llvm.arm.mcr",
+  "llvm.arm.mcr2",
+  "llvm.arm.mcrr",
+  "llvm.arm.mcrr2",
+  "llvm.arm.mrc",
+  "llvm.arm.mrc2",
+  "llvm.arm.neon.aesd",
+  "llvm.arm.neon.aese",
+  "llvm.arm.neon.aesimc",
+  "llvm.arm.neon.aesmc",
+  "llvm.arm.neon.sha1c",
+  "llvm.arm.neon.sha1h",
+  "llvm.arm.neon.sha1m",
+  "llvm.arm.neon.sha1p",
+  "llvm.arm.neon.sha1su0",
+  "llvm.arm.neon.sha1su1",
+  "llvm.arm.neon.sha256h",
+  "llvm.arm.neon.sha256h2",
+  "llvm.arm.neon.sha256su0",
+  "llvm.arm.neon.sha256su1",
+  "llvm.arm.neon.vabds",
+  "llvm.arm.neon.vabdu",
+  "llvm.arm.neon.vabs",
+  "llvm.arm.neon.vacge",
+  "llvm.arm.neon.vacgt",
+  "llvm.arm.neon.vbsl",
+  "llvm.arm.neon.vcls",
+  "llvm.arm.neon.vclz",
+  "llvm.arm.neon.vcnt",
+  "llvm.arm.neon.vcvtas",
+  "llvm.arm.neon.vcvtau",
+  "llvm.arm.neon.vcvtfp2fxs",
+  "llvm.arm.neon.vcvtfp2fxu",
+  "llvm.arm.neon.vcvtfp2hf",
+  "llvm.arm.neon.vcvtfxs2fp",
+  "llvm.arm.neon.vcvtfxu2fp",
+  "llvm.arm.neon.vcvthf2fp",
+  "llvm.arm.neon.vcvtms",
+  "llvm.arm.neon.vcvtmu",
+  "llvm.arm.neon.vcvtns",
+  "llvm.arm.neon.vcvtnu",
+  "llvm.arm.neon.vcvtps",
+  "llvm.arm.neon.vcvtpu",
+  "llvm.arm.neon.vhadds",
+  "llvm.arm.neon.vhaddu",
+  "llvm.arm.neon.vhsubs",
+  "llvm.arm.neon.vhsubu",
+  "llvm.arm.neon.vld1",
+  "llvm.arm.neon.vld2",
+  "llvm.arm.neon.vld2lane",
+  "llvm.arm.neon.vld3",
+  "llvm.arm.neon.vld3lane",
+  "llvm.arm.neon.vld4",
+  "llvm.arm.neon.vld4lane",
+  "llvm.arm.neon.vmaxnm",
+  "llvm.arm.neon.vmaxs",
+  "llvm.arm.neon.vmaxu",
+  "llvm.arm.neon.vminnm",
+  "llvm.arm.neon.vmins",
+  "llvm.arm.neon.vminu",
+  "llvm.arm.neon.vmullp",
+  "llvm.arm.neon.vmulls",
+  "llvm.arm.neon.vmullu",
+  "llvm.arm.neon.vmulp",
+  "llvm.arm.neon.vpadals",
+  "llvm.arm.neon.vpadalu",
+  "llvm.arm.neon.vpadd",
+  "llvm.arm.neon.vpaddls",
+  "llvm.arm.neon.vpaddlu",
+  "llvm.arm.neon.vpmaxs",
+  "llvm.arm.neon.vpmaxu",
+  "llvm.arm.neon.vpmins",
+  "llvm.arm.neon.vpminu",
+  "llvm.arm.neon.vqabs",
+  "llvm.arm.neon.vqadds",
+  "llvm.arm.neon.vqaddu",
+  "llvm.arm.neon.vqdmulh",
+  "llvm.arm.neon.vqdmull",
+  "llvm.arm.neon.vqmovns",
+  "llvm.arm.neon.vqmovnsu",
+  "llvm.arm.neon.vqmovnu",
+  "llvm.arm.neon.vqneg",
+  "llvm.arm.neon.vqrdmulh",
+  "llvm.arm.neon.vqrshiftns",
+  "llvm.arm.neon.vqrshiftnsu",
+  "llvm.arm.neon.vqrshiftnu",
+  "llvm.arm.neon.vqrshifts",
+  "llvm.arm.neon.vqrshiftu",
+  "llvm.arm.neon.vqshiftns",
+  "llvm.arm.neon.vqshiftnsu",
+  "llvm.arm.neon.vqshiftnu",
+  "llvm.arm.neon.vqshifts",
+  "llvm.arm.neon.vqshiftsu",
+  "llvm.arm.neon.vqshiftu",
+  "llvm.arm.neon.vqsubs",
+  "llvm.arm.neon.vqsubu",
+  "llvm.arm.neon.vraddhn",
+  "llvm.arm.neon.vrecpe",
+  "llvm.arm.neon.vrecps",
+  "llvm.arm.neon.vrhadds",
+  "llvm.arm.neon.vrhaddu",
+  "llvm.arm.neon.vrinta",
+  "llvm.arm.neon.vrintm",
+  "llvm.arm.neon.vrintn",
+  "llvm.arm.neon.vrintp",
+  "llvm.arm.neon.vrintx",
+  "llvm.arm.neon.vrintz",
+  "llvm.arm.neon.vrshiftn",
+  "llvm.arm.neon.vrshifts",
+  "llvm.arm.neon.vrshiftu",
+  "llvm.arm.neon.vrsqrte",
+  "llvm.arm.neon.vrsqrts",
+  "llvm.arm.neon.vrsubhn",
+  "llvm.arm.neon.vshiftins",
+  "llvm.arm.neon.vshifts",
+  "llvm.arm.neon.vshiftu",
+  "llvm.arm.neon.vst1",
+  "llvm.arm.neon.vst2",
+  "llvm.arm.neon.vst2lane",
+  "llvm.arm.neon.vst3",
+  "llvm.arm.neon.vst3lane",
+  "llvm.arm.neon.vst4",
+  "llvm.arm.neon.vst4lane",
+  "llvm.arm.neon.vtbl1",
+  "llvm.arm.neon.vtbl2",
+  "llvm.arm.neon.vtbl3",
+  "llvm.arm.neon.vtbl4",
+  "llvm.arm.neon.vtbx1",
+  "llvm.arm.neon.vtbx2",
+  "llvm.arm.neon.vtbx3",
+  "llvm.arm.neon.vtbx4",
+  "llvm.arm.qadd",
+  "llvm.arm.qsub",
+  "llvm.arm.rbit",
+  "llvm.arm.set.fpscr",
+  "llvm.arm.ssat",
+  "llvm.arm.stlex",
+  "llvm.arm.stlexd",
+  "llvm.arm.strex",
+  "llvm.arm.strexd",
+  "llvm.arm.thread.pointer",
+  "llvm.arm.undefined",
+  "llvm.arm.usat",
+  "llvm.arm.vcvtr",
+  "llvm.arm.vcvtru",
+  "llvm.bswap",
+  "llvm.ceil",
+  "llvm.clear_cache",
+  "llvm.convert.from.fp16",
+  "llvm.convert.to.fp16",
+  "llvm.convertff",
+  "llvm.convertfsi",
+  "llvm.convertfui",
+  "llvm.convertsif",
+  "llvm.convertss",
+  "llvm.convertsu",
+  "llvm.convertuif",
+  "llvm.convertus",
+  "llvm.convertuu",
+  "llvm.copysign",
+  "llvm.cos",
+  "llvm.ctlz",
+  "llvm.ctpop",
+  "llvm.cttz",
+  "llvm.cuda.syncthreads",
+  "llvm.dbg.declare",
+  "llvm.dbg.value",
+  "llvm.debugtrap",
+  "llvm.donothing",
+  "llvm.eh.dwarf.cfa",
+  "llvm.eh.return.i32",
+  "llvm.eh.return.i64",
+  "llvm.eh.sjlj.callsite",
+  "llvm.eh.sjlj.functioncontext",
+  "llvm.eh.sjlj.longjmp",
+  "llvm.eh.sjlj.lsda",
+  "llvm.eh.sjlj.setjmp",
+  "llvm.eh.typeid.for",
+  "llvm.eh.unwind.init",
+  "llvm.exp",
+  "llvm.exp2",
+  "llvm.expect",
+  "llvm.experimental.patchpoint.i64",
+  "llvm.experimental.patchpoint.void",
+  "llvm.experimental.stackmap",
+  "llvm.fabs",
+  "llvm.floor",
+  "llvm.flt.rounds",
+  "llvm.fma",
+  "llvm.fmuladd",
+  "llvm.frameaddress",
+  "llvm.gcread",
+  "llvm.gcroot",
+  "llvm.gcwrite",
+  "llvm.hexagon.A2.abs",
+  "llvm.hexagon.A2.absp",
+  "llvm.hexagon.A2.abssat",
+  "llvm.hexagon.A2.add",
+  "llvm.hexagon.A2.addh.h16.hh",
+  "llvm.hexagon.A2.addh.h16.hl",
+  "llvm.hexagon.A2.addh.h16.lh",
+  "llvm.hexagon.A2.addh.h16.ll",
+  "llvm.hexagon.A2.addh.h16.sat.hh",
+  "llvm.hexagon.A2.addh.h16.sat.hl",
+  "llvm.hexagon.A2.addh.h16.sat.lh",
+  "llvm.hexagon.A2.addh.h16.sat.ll",
+  "llvm.hexagon.A2.addh.l16.hl",
+  "llvm.hexagon.A2.addh.l16.ll",
+  "llvm.hexagon.A2.addh.l16.sat.hl",
+  "llvm.hexagon.A2.addh.l16.sat.ll",
+  "llvm.hexagon.A2.addi",
+  "llvm.hexagon.A2.addp",
+  "llvm.hexagon.A2.addpsat",
+  "llvm.hexagon.A2.addsat",
+  "llvm.hexagon.A2.addsp",
+  "llvm.hexagon.A2.and",
+  "llvm.hexagon.A2.andir",
+  "llvm.hexagon.A2.andp",
+  "llvm.hexagon.A2.aslh",
+  "llvm.hexagon.A2.asrh",
+  "llvm.hexagon.A2.combine.hh",
+  "llvm.hexagon.A2.combine.hl",
+  "llvm.hexagon.A2.combine.lh",
+  "llvm.hexagon.A2.combine.ll",
+  "llvm.hexagon.A2.combineii",
+  "llvm.hexagon.A2.combinew",
+  "llvm.hexagon.A2.max",
+  "llvm.hexagon.A2.maxp",
+  "llvm.hexagon.A2.maxu",
+  "llvm.hexagon.A2.maxup",
+  "llvm.hexagon.A2.min",
+  "llvm.hexagon.A2.minp",
+  "llvm.hexagon.A2.minu",
+  "llvm.hexagon.A2.minup",
+  "llvm.hexagon.A2.neg",
+  "llvm.hexagon.A2.negp",
+  "llvm.hexagon.A2.negsat",
+  "llvm.hexagon.A2.not",
+  "llvm.hexagon.A2.notp",
+  "llvm.hexagon.A2.or",
+  "llvm.hexagon.A2.orir",
+  "llvm.hexagon.A2.orp",
+  "llvm.hexagon.A2.roundsat",
+  "llvm.hexagon.A2.sat",
+  "llvm.hexagon.A2.satb",
+  "llvm.hexagon.A2.sath",
+  "llvm.hexagon.A2.satub",
+  "llvm.hexagon.A2.satuh",
+  "llvm.hexagon.A2.sub",
+  "llvm.hexagon.A2.subh.h16.hh",
+  "llvm.hexagon.A2.subh.h16.hl",
+  "llvm.hexagon.A2.subh.h16.lh",
+  "llvm.hexagon.A2.subh.h16.ll",
+  "llvm.hexagon.A2.subh.h16.sat.hh",
+  "llvm.hexagon.A2.subh.h16.sat.hl",
+  "llvm.hexagon.A2.subh.h16.sat.lh",
+  "llvm.hexagon.A2.subh.h16.sat.ll",
+  "llvm.hexagon.A2.subh.l16.hl",
+  "llvm.hexagon.A2.subh.l16.ll",
+  "llvm.hexagon.A2.subh.l16.sat.hl",
+  "llvm.hexagon.A2.subh.l16.sat.ll",
+  "llvm.hexagon.A2.subp",
+  "llvm.hexagon.A2.subri",
+  "llvm.hexagon.A2.subsat",
+  "llvm.hexagon.A2.svaddh",
+  "llvm.hexagon.A2.svaddhs",
+  "llvm.hexagon.A2.svadduhs",
+  "llvm.hexagon.A2.svavgh",
+  "llvm.hexagon.A2.svavghs",
+  "llvm.hexagon.A2.svnavgh",
+  "llvm.hexagon.A2.svsubh",
+  "llvm.hexagon.A2.svsubhs",
+  "llvm.hexagon.A2.svsubuhs",
+  "llvm.hexagon.A2.swiz",
+  "llvm.hexagon.A2.sxtb",
+  "llvm.hexagon.A2.sxth",
+  "llvm.hexagon.A2.sxtw",
+  "llvm.hexagon.A2.tfr",
+  "llvm.hexagon.A2.tfrih",
+  "llvm.hexagon.A2.tfril",
+  "llvm.hexagon.A2.tfrp",
+  "llvm.hexagon.A2.tfrpi",
+  "llvm.hexagon.A2.tfrsi",
+  "llvm.hexagon.A2.vabsh",
+  "llvm.hexagon.A2.vabshsat",
+  "llvm.hexagon.A2.vabsw",
+  "llvm.hexagon.A2.vabswsat",
+  "llvm.hexagon.A2.vaddb.map",
+  "llvm.hexagon.A2.vaddh",
+  "llvm.hexagon.A2.vaddhs",
+  "llvm.hexagon.A2.vaddub",
+  "llvm.hexagon.A2.vaddubs",
+  "llvm.hexagon.A2.vadduhs",
+  "llvm.hexagon.A2.vaddw",
+  "llvm.hexagon.A2.vaddws",
+  "llvm.hexagon.A2.vavgh",
+  "llvm.hexagon.A2.vavghcr",
+  "llvm.hexagon.A2.vavghr",
+  "llvm.hexagon.A2.vavgub",
+  "llvm.hexagon.A2.vavgubr",
+  "llvm.hexagon.A2.vavguh",
+  "llvm.hexagon.A2.vavguhr",
+  "llvm.hexagon.A2.vavguw",
+  "llvm.hexagon.A2.vavguwr",
+  "llvm.hexagon.A2.vavgw",
+  "llvm.hexagon.A2.vavgwcr",
+  "llvm.hexagon.A2.vavgwr",
+  "llvm.hexagon.A2.vcmpbeq",
+  "llvm.hexagon.A2.vcmpbgtu",
+  "llvm.hexagon.A2.vcmpheq",
+  "llvm.hexagon.A2.vcmphgt",
+  "llvm.hexagon.A2.vcmphgtu",
+  "llvm.hexagon.A2.vcmpweq",
+  "llvm.hexagon.A2.vcmpwgt",
+  "llvm.hexagon.A2.vcmpwgtu",
+  "llvm.hexagon.A2.vconj",
+  "llvm.hexagon.A2.vmaxb",
+  "llvm.hexagon.A2.vmaxh",
+  "llvm.hexagon.A2.vmaxub",
+  "llvm.hexagon.A2.vmaxuh",
+  "llvm.hexagon.A2.vmaxuw",
+  "llvm.hexagon.A2.vmaxw",
+  "llvm.hexagon.A2.vminb",
+  "llvm.hexagon.A2.vminh",
+  "llvm.hexagon.A2.vminub",
+  "llvm.hexagon.A2.vminuh",
+  "llvm.hexagon.A2.vminuw",
+  "llvm.hexagon.A2.vminw",
+  "llvm.hexagon.A2.vnavgh",
+  "llvm.hexagon.A2.vnavghcr",
+  "llvm.hexagon.A2.vnavghr",
+  "llvm.hexagon.A2.vnavgw",
+  "llvm.hexagon.A2.vnavgwcr",
+  "llvm.hexagon.A2.vnavgwr",
+  "llvm.hexagon.A2.vraddub",
+  "llvm.hexagon.A2.vraddub.acc",
+  "llvm.hexagon.A2.vrsadub",
+  "llvm.hexagon.A2.vrsadub.acc",
+  "llvm.hexagon.A2.vsubb.map",
+  "llvm.hexagon.A2.vsubh",
+  "llvm.hexagon.A2.vsubhs",
+  "llvm.hexagon.A2.vsubub",
+  "llvm.hexagon.A2.vsububs",
+  "llvm.hexagon.A2.vsubuhs",
+  "llvm.hexagon.A2.vsubw",
+  "llvm.hexagon.A2.vsubws",
+  "llvm.hexagon.A2.xor",
+  "llvm.hexagon.A2.xorp",
+  "llvm.hexagon.A2.zxtb",
+  "llvm.hexagon.A2.zxth",
+  "llvm.hexagon.A4.andn",
+  "llvm.hexagon.A4.andnp",
+  "llvm.hexagon.A4.bitsplit",
+  "llvm.hexagon.A4.bitspliti",
+  "llvm.hexagon.A4.boundscheck",
+  "llvm.hexagon.A4.cmpbeq",
+  "llvm.hexagon.A4.cmpbeqi",
+  "llvm.hexagon.A4.cmpbgt",
+  "llvm.hexagon.A4.cmpbgti",
+  "llvm.hexagon.A4.cmpbgtu",
+  "llvm.hexagon.A4.cmpbgtui",
+  "llvm.hexagon.A4.cmpheq",
+  "llvm.hexagon.A4.cmpheqi",
+  "llvm.hexagon.A4.cmphgt",
+  "llvm.hexagon.A4.cmphgti",
+  "llvm.hexagon.A4.cmphgtu",
+  "llvm.hexagon.A4.cmphgtui",
+  "llvm.hexagon.A4.combineir",
+  "llvm.hexagon.A4.combineri",
+  "llvm.hexagon.A4.cround.ri",
+  "llvm.hexagon.A4.cround.rr",
+  "llvm.hexagon.A4.modwrapu",
+  "llvm.hexagon.A4.orn",
+  "llvm.hexagon.A4.ornp",
+  "llvm.hexagon.A4.rcmpeq",
+  "llvm.hexagon.A4.rcmpeqi",
+  "llvm.hexagon.A4.rcmpneq",
+  "llvm.hexagon.A4.rcmpneqi",
+  "llvm.hexagon.A4.round.ri",
+  "llvm.hexagon.A4.round.ri.sat",
+  "llvm.hexagon.A4.round.rr",
+  "llvm.hexagon.A4.round.rr.sat",
+  "llvm.hexagon.A4.tlbmatch",
+  "llvm.hexagon.A4.vcmpbeq.any",
+  "llvm.hexagon.A4.vcmpbeqi",
+  "llvm.hexagon.A4.vcmpbgt",
+  "llvm.hexagon.A4.vcmpbgti",
+  "llvm.hexagon.A4.vcmpbgtui",
+  "llvm.hexagon.A4.vcmpheqi",
+  "llvm.hexagon.A4.vcmphgti",
+  "llvm.hexagon.A4.vcmphgtui",
+  "llvm.hexagon.A4.vcmpweqi",
+  "llvm.hexagon.A4.vcmpwgti",
+  "llvm.hexagon.A4.vcmpwgtui",
+  "llvm.hexagon.A4.vrmaxh",
+  "llvm.hexagon.A4.vrmaxuh",
+  "llvm.hexagon.A4.vrmaxuw",
+  "llvm.hexagon.A4.vrmaxw",
+  "llvm.hexagon.A4.vrminh",
+  "llvm.hexagon.A4.vrminuh",
+  "llvm.hexagon.A4.vrminuw",
+  "llvm.hexagon.A4.vrminw",
+  "llvm.hexagon.A5.vaddhubs",
+  "llvm.hexagon.C2.all8",
+  "llvm.hexagon.C2.and",
+  "llvm.hexagon.C2.andn",
+  "llvm.hexagon.C2.any8",
+  "llvm.hexagon.C2.bitsclr",
+  "llvm.hexagon.C2.bitsclri",
+  "llvm.hexagon.C2.bitsset",
+  "llvm.hexagon.C2.cmpeq",
+  "llvm.hexagon.C2.cmpeqi",
+  "llvm.hexagon.C2.cmpeqp",
+  "llvm.hexagon.C2.cmpgei",
+  "llvm.hexagon.C2.cmpgeui",
+  "llvm.hexagon.C2.cmpgt",
+  "llvm.hexagon.C2.cmpgti",
+  "llvm.hexagon.C2.cmpgtp",
+  "llvm.hexagon.C2.cmpgtu",
+  "llvm.hexagon.C2.cmpgtui",
+  "llvm.hexagon.C2.cmpgtup",
+  "llvm.hexagon.C2.cmplt",
+  "llvm.hexagon.C2.cmpltu",
+  "llvm.hexagon.C2.mask",
+  "llvm.hexagon.C2.mux",
+  "llvm.hexagon.C2.muxii",
+  "llvm.hexagon.C2.muxir",
+  "llvm.hexagon.C2.muxri",
+  "llvm.hexagon.C2.not",
+  "llvm.hexagon.C2.or",
+  "llvm.hexagon.C2.orn",
+  "llvm.hexagon.C2.pxfer.map",
+  "llvm.hexagon.C2.tfrpr",
+  "llvm.hexagon.C2.tfrrp",
+  "llvm.hexagon.C2.vitpack",
+  "llvm.hexagon.C2.vmux",
+  "llvm.hexagon.C2.xor",
+  "llvm.hexagon.C4.and.and",
+  "llvm.hexagon.C4.and.andn",
+  "llvm.hexagon.C4.and.or",
+  "llvm.hexagon.C4.and.orn",
+  "llvm.hexagon.C4.cmplte",
+  "llvm.hexagon.C4.cmpltei",
+  "llvm.hexagon.C4.cmplteu",
+  "llvm.hexagon.C4.cmplteui",
+  "llvm.hexagon.C4.cmpneq",
+  "llvm.hexagon.C4.cmpneqi",
+  "llvm.hexagon.C4.fastcorner9",
+  "llvm.hexagon.C4.fastcorner9.not",
+  "llvm.hexagon.C4.nbitsclr",
+  "llvm.hexagon.C4.nbitsclri",
+  "llvm.hexagon.C4.nbitsset",
+  "llvm.hexagon.C4.or.and",
+  "llvm.hexagon.C4.or.andn",
+  "llvm.hexagon.C4.or.or",
+  "llvm.hexagon.C4.or.orn",
+  "llvm.hexagon.F2.conv.d2df",
+  "llvm.hexagon.F2.conv.d2sf",
+  "llvm.hexagon.F2.conv.df2d",
+  "llvm.hexagon.F2.conv.df2d.chop",
+  "llvm.hexagon.F2.conv.df2sf",
+  "llvm.hexagon.F2.conv.df2ud",
+  "llvm.hexagon.F2.conv.df2ud.chop",
+  "llvm.hexagon.F2.conv.df2uw",
+  "llvm.hexagon.F2.conv.df2uw.chop",
+  "llvm.hexagon.F2.conv.df2w",
+  "llvm.hexagon.F2.conv.df2w.chop",
+  "llvm.hexagon.F2.conv.sf2d",
+  "llvm.hexagon.F2.conv.sf2d.chop",
+  "llvm.hexagon.F2.conv.sf2df",
+  "llvm.hexagon.F2.conv.sf2ud",
+  "llvm.hexagon.F2.conv.sf2ud.chop",
+  "llvm.hexagon.F2.conv.sf2uw",
+  "llvm.hexagon.F2.conv.sf2uw.chop",
+  "llvm.hexagon.F2.conv.sf2w",
+  "llvm.hexagon.F2.conv.sf2w.chop",
+  "llvm.hexagon.F2.conv.ud2df",
+  "llvm.hexagon.F2.conv.ud2sf",
+  "llvm.hexagon.F2.conv.uw2df",
+  "llvm.hexagon.F2.conv.uw2sf",
+  "llvm.hexagon.F2.conv.w2df",
+  "llvm.hexagon.F2.conv.w2sf",
+  "llvm.hexagon.F2.dfadd",
+  "llvm.hexagon.F2.dfclass",
+  "llvm.hexagon.F2.dfcmpeq",
+  "llvm.hexagon.F2.dfcmpge",
+  "llvm.hexagon.F2.dfcmpgt",
+  "llvm.hexagon.F2.dfcmpuo",
+  "llvm.hexagon.F2.dffixupd",
+  "llvm.hexagon.F2.dffixupn",
+  "llvm.hexagon.F2.dffixupr",
+  "llvm.hexagon.F2.dffma",
+  "llvm.hexagon.F2.dffma.lib",
+  "llvm.hexagon.F2.dffma.sc",
+  "llvm.hexagon.F2.dffms",
+  "llvm.hexagon.F2.dffms.lib",
+  "llvm.hexagon.F2.dfimm.n",
+  "llvm.hexagon.F2.dfimm.p",
+  "llvm.hexagon.F2.dfmax",
+  "llvm.hexagon.F2.dfmin",
+  "llvm.hexagon.F2.dfmpy",
+  "llvm.hexagon.F2.dfsub",
+  "llvm.hexagon.F2.sfadd",
+  "llvm.hexagon.F2.sfclass",
+  "llvm.hexagon.F2.sfcmpeq",
+  "llvm.hexagon.F2.sfcmpge",
+  "llvm.hexagon.F2.sfcmpgt",
+  "llvm.hexagon.F2.sfcmpuo",
+  "llvm.hexagon.F2.sffixupd",
+  "llvm.hexagon.F2.sffixupn",
+  "llvm.hexagon.F2.sffixupr",
+  "llvm.hexagon.F2.sffma",
+  "llvm.hexagon.F2.sffma.lib",
+  "llvm.hexagon.F2.sffma.sc",
+  "llvm.hexagon.F2.sffms",
+  "llvm.hexagon.F2.sffms.lib",
+  "llvm.hexagon.F2.sfimm.n",
+  "llvm.hexagon.F2.sfimm.p",
+  "llvm.hexagon.F2.sfmax",
+  "llvm.hexagon.F2.sfmin",
+  "llvm.hexagon.F2.sfmpy",
+  "llvm.hexagon.F2.sfsub",
+  "llvm.hexagon.M2.acci",
+  "llvm.hexagon.M2.accii",
+  "llvm.hexagon.M2.cmaci.s0",
+  "llvm.hexagon.M2.cmacr.s0",
+  "llvm.hexagon.M2.cmacs.s0",
+  "llvm.hexagon.M2.cmacs.s1",
+  "llvm.hexagon.M2.cmacsc.s0",
+  "llvm.hexagon.M2.cmacsc.s1",
+  "llvm.hexagon.M2.cmpyi.s0",
+  "llvm.hexagon.M2.cmpyr.s0",
+  "llvm.hexagon.M2.cmpyrs.s0",
+  "llvm.hexagon.M2.cmpyrs.s1",
+  "llvm.hexagon.M2.cmpyrsc.s0",
+  "llvm.hexagon.M2.cmpyrsc.s1",
+  "llvm.hexagon.M2.cmpys.s0",
+  "llvm.hexagon.M2.cmpys.s1",
+  "llvm.hexagon.M2.cmpysc.s0",
+  "llvm.hexagon.M2.cmpysc.s1",
+  "llvm.hexagon.M2.cnacs.s0",
+  "llvm.hexagon.M2.cnacs.s1",
+  "llvm.hexagon.M2.cnacsc.s0",
+  "llvm.hexagon.M2.cnacsc.s1",
+  "llvm.hexagon.M2.dpmpyss.acc.s0",
+  "llvm.hexagon.M2.dpmpyss.nac.s0",
+  "llvm.hexagon.M2.dpmpyss.rnd.s0",
+  "llvm.hexagon.M2.dpmpyss.s0",
+  "llvm.hexagon.M2.dpmpyuu.acc.s0",
+  "llvm.hexagon.M2.dpmpyuu.nac.s0",
+  "llvm.hexagon.M2.dpmpyuu.s0",
+  "llvm.hexagon.M2.hmmpyh.rs1",
+  "llvm.hexagon.M2.hmmpyh.s1",
+  "llvm.hexagon.M2.hmmpyl.rs1",
+  "llvm.hexagon.M2.hmmpyl.s1",
+  "llvm.hexagon.M2.maci",
+  "llvm.hexagon.M2.macsin",
+  "llvm.hexagon.M2.macsip",
+  "llvm.hexagon.M2.mmachs.rs0",
+  "llvm.hexagon.M2.mmachs.rs1",
+  "llvm.hexagon.M2.mmachs.s0",
+  "llvm.hexagon.M2.mmachs.s1",
+  "llvm.hexagon.M2.mmacls.rs0",
+  "llvm.hexagon.M2.mmacls.rs1",
+  "llvm.hexagon.M2.mmacls.s0",
+  "llvm.hexagon.M2.mmacls.s1",
+  "llvm.hexagon.M2.mmacuhs.rs0",
+  "llvm.hexagon.M2.mmacuhs.rs1",
+  "llvm.hexagon.M2.mmacuhs.s0",
+  "llvm.hexagon.M2.mmacuhs.s1",
+  "llvm.hexagon.M2.mmaculs.rs0",
+  "llvm.hexagon.M2.mmaculs.rs1",
+  "llvm.hexagon.M2.mmaculs.s0",
+  "llvm.hexagon.M2.mmaculs.s1",
+  "llvm.hexagon.M2.mmpyh.rs0",
+  "llvm.hexagon.M2.mmpyh.rs1",
+  "llvm.hexagon.M2.mmpyh.s0",
+  "llvm.hexagon.M2.mmpyh.s1",
+  "llvm.hexagon.M2.mmpyl.rs0",
+  "llvm.hexagon.M2.mmpyl.rs1",
+  "llvm.hexagon.M2.mmpyl.s0",
+  "llvm.hexagon.M2.mmpyl.s1",
+  "llvm.hexagon.M2.mmpyuh.rs0",
+  "llvm.hexagon.M2.mmpyuh.rs1",
+  "llvm.hexagon.M2.mmpyuh.s0",
+  "llvm.hexagon.M2.mmpyuh.s1",
+  "llvm.hexagon.M2.mmpyul.rs0",
+  "llvm.hexagon.M2.mmpyul.rs1",
+  "llvm.hexagon.M2.mmpyul.s0",
+  "llvm.hexagon.M2.mmpyul.s1",
+  "llvm.hexagon.M2.mpy.acc.hh.s0",
+  "llvm.hexagon.M2.mpy.acc.hh.s1",
+  "llvm.hexagon.M2.mpy.acc.hl.s0",
+  "llvm.hexagon.M2.mpy.acc.hl.s1",
+  "llvm.hexagon.M2.mpy.acc.lh.s0",
+  "llvm.hexagon.M2.mpy.acc.lh.s1",
+  "llvm.hexagon.M2.mpy.acc.ll.s0",
+  "llvm.hexagon.M2.mpy.acc.ll.s1",
+  "llvm.hexagon.M2.mpy.acc.sat.hh.s0",
+  "llvm.hexagon.M2.mpy.acc.sat.hh.s1",
+  "llvm.hexagon.M2.mpy.acc.sat.hl.s0",
+  "llvm.hexagon.M2.mpy.acc.sat.hl.s1",
+  "llvm.hexagon.M2.mpy.acc.sat.lh.s0",
+  "llvm.hexagon.M2.mpy.acc.sat.lh.s1",
+  "llvm.hexagon.M2.mpy.acc.sat.ll.s0",
+  "llvm.hexagon.M2.mpy.acc.sat.ll.s1",
+  "llvm.hexagon.M2.mpy.hh.s0",
+  "llvm.hexagon.M2.mpy.hh.s1",
+  "llvm.hexagon.M2.mpy.hl.s0",
+  "llvm.hexagon.M2.mpy.hl.s1",
+  "llvm.hexagon.M2.mpy.lh.s0",
+  "llvm.hexagon.M2.mpy.lh.s1",
+  "llvm.hexagon.M2.mpy.ll.s0",
+  "llvm.hexagon.M2.mpy.ll.s1",
+  "llvm.hexagon.M2.mpy.nac.hh.s0",
+  "llvm.hexagon.M2.mpy.nac.hh.s1",
+  "llvm.hexagon.M2.mpy.nac.hl.s0",
+  "llvm.hexagon.M2.mpy.nac.hl.s1",
+  "llvm.hexagon.M2.mpy.nac.lh.s0",
+  "llvm.hexagon.M2.mpy.nac.lh.s1",
+  "llvm.hexagon.M2.mpy.nac.ll.s0",
+  "llvm.hexagon.M2.mpy.nac.ll.s1",
+  "llvm.hexagon.M2.mpy.nac.sat.hh.s0",
+  "llvm.hexagon.M2.mpy.nac.sat.hh.s1",
+  "llvm.hexagon.M2.mpy.nac.sat.hl.s0",
+  "llvm.hexagon.M2.mpy.nac.sat.hl.s1",
+  "llvm.hexagon.M2.mpy.nac.sat.lh.s0",
+  "llvm.hexagon.M2.mpy.nac.sat.lh.s1",
+  "llvm.hexagon.M2.mpy.nac.sat.ll.s0",
+  "llvm.hexagon.M2.mpy.nac.sat.ll.s1",
+  "llvm.hexagon.M2.mpy.rnd.hh.s0",
+  "llvm.hexagon.M2.mpy.rnd.hh.s1",
+  "llvm.hexagon.M2.mpy.rnd.hl.s0",
+  "llvm.hexagon.M2.mpy.rnd.hl.s1",
+  "llvm.hexagon.M2.mpy.rnd.lh.s0",
+  "llvm.hexagon.M2.mpy.rnd.lh.s1",
+  "llvm.hexagon.M2.mpy.rnd.ll.s0",
+  "llvm.hexagon.M2.mpy.rnd.ll.s1",
+  "llvm.hexagon.M2.mpy.sat.hh.s0",
+  "llvm.hexagon.M2.mpy.sat.hh.s1",
+  "llvm.hexagon.M2.mpy.sat.hl.s0",
+  "llvm.hexagon.M2.mpy.sat.hl.s1",
+  "llvm.hexagon.M2.mpy.sat.lh.s0",
+  "llvm.hexagon.M2.mpy.sat.lh.s1",
+  "llvm.hexagon.M2.mpy.sat.ll.s0",
+  "llvm.hexagon.M2.mpy.sat.ll.s1",
+  "llvm.hexagon.M2.mpy.sat.rnd.hh.s0",
+  "llvm.hexagon.M2.mpy.sat.rnd.hh.s1",
+  "llvm.hexagon.M2.mpy.sat.rnd.hl.s0",
+  "llvm.hexagon.M2.mpy.sat.rnd.hl.s1",
+  "llvm.hexagon.M2.mpy.sat.rnd.lh.s0",
+  "llvm.hexagon.M2.mpy.sat.rnd.lh.s1",
+  "llvm.hexagon.M2.mpy.sat.rnd.ll.s0",
+  "llvm.hexagon.M2.mpy.sat.rnd.ll.s1",
+  "llvm.hexagon.M2.mpy.up",
+  "llvm.hexagon.M2.mpy.up.s1",
+  "llvm.hexagon.M2.mpy.up.s1.sat",
+  "llvm.hexagon.M2.mpyd.acc.hh.s0",
+  "llvm.hexagon.M2.mpyd.acc.hh.s1",
+  "llvm.hexagon.M2.mpyd.acc.hl.s0",
+  "llvm.hexagon.M2.mpyd.acc.hl.s1",
+  "llvm.hexagon.M2.mpyd.acc.lh.s0",
+  "llvm.hexagon.M2.mpyd.acc.lh.s1",
+  "llvm.hexagon.M2.mpyd.acc.ll.s0",
+  "llvm.hexagon.M2.mpyd.acc.ll.s1",
+  "llvm.hexagon.M2.mpyd.hh.s0",
+  "llvm.hexagon.M2.mpyd.hh.s1",
+  "llvm.hexagon.M2.mpyd.hl.s0",
+  "llvm.hexagon.M2.mpyd.hl.s1",
+  "llvm.hexagon.M2.mpyd.lh.s0",
+  "llvm.hexagon.M2.mpyd.lh.s1",
+  "llvm.hexagon.M2.mpyd.ll.s0",
+  "llvm.hexagon.M2.mpyd.ll.s1",
+  "llvm.hexagon.M2.mpyd.nac.hh.s0",
+  "llvm.hexagon.M2.mpyd.nac.hh.s1",
+  "llvm.hexagon.M2.mpyd.nac.hl.s0",
+  "llvm.hexagon.M2.mpyd.nac.hl.s1",
+  "llvm.hexagon.M2.mpyd.nac.lh.s0",
+  "llvm.hexagon.M2.mpyd.nac.lh.s1",
+  "llvm.hexagon.M2.mpyd.nac.ll.s0",
+  "llvm.hexagon.M2.mpyd.nac.ll.s1",
+  "llvm.hexagon.M2.mpyd.rnd.hh.s0",
+  "llvm.hexagon.M2.mpyd.rnd.hh.s1",
+  "llvm.hexagon.M2.mpyd.rnd.hl.s0",
+  "llvm.hexagon.M2.mpyd.rnd.hl.s1",
+  "llvm.hexagon.M2.mpyd.rnd.lh.s0",
+  "llvm.hexagon.M2.mpyd.rnd.lh.s1",
+  "llvm.hexagon.M2.mpyd.rnd.ll.s0",
+  "llvm.hexagon.M2.mpyd.rnd.ll.s1",
+  "llvm.hexagon.M2.mpyi",
+  "llvm.hexagon.M2.mpysmi",
+  "llvm.hexagon.M2.mpysu.up",
+  "llvm.hexagon.M2.mpyu.acc.hh.s0",
+  "llvm.hexagon.M2.mpyu.acc.hh.s1",
+  "llvm.hexagon.M2.mpyu.acc.hl.s0",
+  "llvm.hexagon.M2.mpyu.acc.hl.s1",
+  "llvm.hexagon.M2.mpyu.acc.lh.s0",
+  "llvm.hexagon.M2.mpyu.acc.lh.s1",
+  "llvm.hexagon.M2.mpyu.acc.ll.s0",
+  "llvm.hexagon.M2.mpyu.acc.ll.s1",
+  "llvm.hexagon.M2.mpyu.hh.s0",
+  "llvm.hexagon.M2.mpyu.hh.s1",
+  "llvm.hexagon.M2.mpyu.hl.s0",
+  "llvm.hexagon.M2.mpyu.hl.s1",
+  "llvm.hexagon.M2.mpyu.lh.s0",
+  "llvm.hexagon.M2.mpyu.lh.s1",
+  "llvm.hexagon.M2.mpyu.ll.s0",
+  "llvm.hexagon.M2.mpyu.ll.s1",
+  "llvm.hexagon.M2.mpyu.nac.hh.s0",
+  "llvm.hexagon.M2.mpyu.nac.hh.s1",
+  "llvm.hexagon.M2.mpyu.nac.hl.s0",
+  "llvm.hexagon.M2.mpyu.nac.hl.s1",
+  "llvm.hexagon.M2.mpyu.nac.lh.s0",
+  "llvm.hexagon.M2.mpyu.nac.lh.s1",
+  "llvm.hexagon.M2.mpyu.nac.ll.s0",
+  "llvm.hexagon.M2.mpyu.nac.ll.s1",
+  "llvm.hexagon.M2.mpyu.up",
+  "llvm.hexagon.M2.mpyud.acc.hh.s0",
+  "llvm.hexagon.M2.mpyud.acc.hh.s1",
+  "llvm.hexagon.M2.mpyud.acc.hl.s0",
+  "llvm.hexagon.M2.mpyud.acc.hl.s1",
+  "llvm.hexagon.M2.mpyud.acc.lh.s0",
+  "llvm.hexagon.M2.mpyud.acc.lh.s1",
+  "llvm.hexagon.M2.mpyud.acc.ll.s0",
+  "llvm.hexagon.M2.mpyud.acc.ll.s1",
+  "llvm.hexagon.M2.mpyud.hh.s0",
+  "llvm.hexagon.M2.mpyud.hh.s1",
+  "llvm.hexagon.M2.mpyud.hl.s0",
+  "llvm.hexagon.M2.mpyud.hl.s1",
+  "llvm.hexagon.M2.mpyud.lh.s0",
+  "llvm.hexagon.M2.mpyud.lh.s1",
+  "llvm.hexagon.M2.mpyud.ll.s0",
+  "llvm.hexagon.M2.mpyud.ll.s1",
+  "llvm.hexagon.M2.mpyud.nac.hh.s0",
+  "llvm.hexagon.M2.mpyud.nac.hh.s1",
+  "llvm.hexagon.M2.mpyud.nac.hl.s0",
+  "llvm.hexagon.M2.mpyud.nac.hl.s1",
+  "llvm.hexagon.M2.mpyud.nac.lh.s0",
+  "llvm.hexagon.M2.mpyud.nac.lh.s1",
+  "llvm.hexagon.M2.mpyud.nac.ll.s0",
+  "llvm.hexagon.M2.mpyud.nac.ll.s1",
+  "llvm.hexagon.M2.mpyui",
+  "llvm.hexagon.M2.nacci",
+  "llvm.hexagon.M2.naccii",
+  "llvm.hexagon.M2.subacc",
+  "llvm.hexagon.M2.vabsdiffh",
+  "llvm.hexagon.M2.vabsdiffw",
+  "llvm.hexagon.M2.vcmac.s0.sat.i",
+  "llvm.hexagon.M2.vcmac.s0.sat.r",
+  "llvm.hexagon.M2.vcmpy.s0.sat.i",
+  "llvm.hexagon.M2.vcmpy.s0.sat.r",
+  "llvm.hexagon.M2.vcmpy.s1.sat.i",
+  "llvm.hexagon.M2.vcmpy.s1.sat.r",
+  "llvm.hexagon.M2.vdmacs.s0",
+  "llvm.hexagon.M2.vdmacs.s1",
+  "llvm.hexagon.M2.vdmpyrs.s0",
+  "llvm.hexagon.M2.vdmpyrs.s1",
+  "llvm.hexagon.M2.vdmpys.s0",
+  "llvm.hexagon.M2.vdmpys.s1",
+  "llvm.hexagon.M2.vmac2",
+  "llvm.hexagon.M2.vmac2es",
+  "llvm.hexagon.M2.vmac2es.s0",
+  "llvm.hexagon.M2.vmac2es.s1",
+  "llvm.hexagon.M2.vmac2s.s0",
+  "llvm.hexagon.M2.vmac2s.s1",
+  "llvm.hexagon.M2.vmac2su.s0",
+  "llvm.hexagon.M2.vmac2su.s1",
+  "llvm.hexagon.M2.vmpy2es.s0",
+  "llvm.hexagon.M2.vmpy2es.s1",
+  "llvm.hexagon.M2.vmpy2s.s0",
+  "llvm.hexagon.M2.vmpy2s.s0pack",
+  "llvm.hexagon.M2.vmpy2s.s1",
+  "llvm.hexagon.M2.vmpy2s.s1pack",
+  "llvm.hexagon.M2.vmpy2su.s0",
+  "llvm.hexagon.M2.vmpy2su.s1",
+  "llvm.hexagon.M2.vraddh",
+  "llvm.hexagon.M2.vradduh",
+  "llvm.hexagon.M2.vrcmaci.s0",
+  "llvm.hexagon.M2.vrcmaci.s0c",
+  "llvm.hexagon.M2.vrcmacr.s0",
+  "llvm.hexagon.M2.vrcmacr.s0c",
+  "llvm.hexagon.M2.vrcmpyi.s0",
+  "llvm.hexagon.M2.vrcmpyi.s0c",
+  "llvm.hexagon.M2.vrcmpyr.s0",
+  "llvm.hexagon.M2.vrcmpyr.s0c",
+  "llvm.hexagon.M2.vrcmpys.acc.s1",
+  "llvm.hexagon.M2.vrcmpys.s1",
+  "llvm.hexagon.M2.vrcmpys.s1rp",
+  "llvm.hexagon.M2.vrmac.s0",
+  "llvm.hexagon.M2.vrmpy.s0",
+  "llvm.hexagon.M2.xor.xacc",
+  "llvm.hexagon.M4.and.and",
+  "llvm.hexagon.M4.and.andn",
+  "llvm.hexagon.M4.and.or",
+  "llvm.hexagon.M4.and.xor",
+  "llvm.hexagon.M4.cmpyi.wh",
+  "llvm.hexagon.M4.cmpyi.whc",
+  "llvm.hexagon.M4.cmpyr.wh",
+  "llvm.hexagon.M4.cmpyr.whc",
+  "llvm.hexagon.M4.mac.up.s1.sat",
+  "llvm.hexagon.M4.mpyri.addi",
+  "llvm.hexagon.M4.mpyri.addr",
+  "llvm.hexagon.M4.mpyri.addr.u2",
+  "llvm.hexagon.M4.mpyrr.addi",
+  "llvm.hexagon.M4.mpyrr.addr",
+  "llvm.hexagon.M4.nac.up.s1.sat",
+  "llvm.hexagon.M4.or.and",
+  "llvm.hexagon.M4.or.andn",
+  "llvm.hexagon.M4.or.or",
+  "llvm.hexagon.M4.or.xor",
+  "llvm.hexagon.M4.pmpyw",
+  "llvm.hexagon.M4.pmpyw.acc",
+  "llvm.hexagon.M4.vpmpyh",
+  "llvm.hexagon.M4.vpmpyh.acc",
+  "llvm.hexagon.M4.vrmpyeh.acc.s0",
+  "llvm.hexagon.M4.vrmpyeh.acc.s1",
+  "llvm.hexagon.M4.vrmpyeh.s0",
+  "llvm.hexagon.M4.vrmpyeh.s1",
+  "llvm.hexagon.M4.vrmpyoh.acc.s0",
+  "llvm.hexagon.M4.vrmpyoh.acc.s1",
+  "llvm.hexagon.M4.vrmpyoh.s0",
+  "llvm.hexagon.M4.vrmpyoh.s1",
+  "llvm.hexagon.M4.xor.and",
+  "llvm.hexagon.M4.xor.andn",
+  "llvm.hexagon.M4.xor.or",
+  "llvm.hexagon.M4.xor.xacc",
+  "llvm.hexagon.M5.vdmacbsu",
+  "llvm.hexagon.M5.vdmpybsu",
+  "llvm.hexagon.M5.vmacbsu",
+  "llvm.hexagon.M5.vmacbuu",
+  "llvm.hexagon.M5.vmpybsu",
+  "llvm.hexagon.M5.vmpybuu",
+  "llvm.hexagon.M5.vrmacbsu",
+  "llvm.hexagon.M5.vrmacbuu",
+  "llvm.hexagon.M5.vrmpybsu",
+  "llvm.hexagon.M5.vrmpybuu",
+  "llvm.hexagon.S2.addasl.rrri",
+  "llvm.hexagon.S2.asl.i.p",
+  "llvm.hexagon.S2.asl.i.p.acc",
+  "llvm.hexagon.S2.asl.i.p.and",
+  "llvm.hexagon.S2.asl.i.p.nac",
+  "llvm.hexagon.S2.asl.i.p.or",
+  "llvm.hexagon.S2.asl.i.p.xacc",
+  "llvm.hexagon.S2.asl.i.r",
+  "llvm.hexagon.S2.asl.i.r.acc",
+  "llvm.hexagon.S2.asl.i.r.and",
+  "llvm.hexagon.S2.asl.i.r.nac",
+  "llvm.hexagon.S2.asl.i.r.or",
+  "llvm.hexagon.S2.asl.i.r.sat",
+  "llvm.hexagon.S2.asl.i.r.xacc",
+  "llvm.hexagon.S2.asl.i.vh",
+  "llvm.hexagon.S2.asl.i.vw",
+  "llvm.hexagon.S2.asl.r.p",
+  "llvm.hexagon.S2.asl.r.p.acc",
+  "llvm.hexagon.S2.asl.r.p.and",
+  "llvm.hexagon.S2.asl.r.p.nac",
+  "llvm.hexagon.S2.asl.r.p.or",
+  "llvm.hexagon.S2.asl.r.p.xor",
+  "llvm.hexagon.S2.asl.r.r",
+  "llvm.hexagon.S2.asl.r.r.acc",
+  "llvm.hexagon.S2.asl.r.r.and",
+  "llvm.hexagon.S2.asl.r.r.nac",
+  "llvm.hexagon.S2.asl.r.r.or",
+  "llvm.hexagon.S2.asl.r.r.sat",
+  "llvm.hexagon.S2.asl.r.vh",
+  "llvm.hexagon.S2.asl.r.vw",
+  "llvm.hexagon.S2.asr.i.p",
+  "llvm.hexagon.S2.asr.i.p.acc",
+  "llvm.hexagon.S2.asr.i.p.and",
+  "llvm.hexagon.S2.asr.i.p.nac",
+  "llvm.hexagon.S2.asr.i.p.or",
+  "llvm.hexagon.S2.asr.i.p.rnd",
+  "llvm.hexagon.S2.asr.i.p.rnd.goodsyntax",
+  "llvm.hexagon.S2.asr.i.r",
+  "llvm.hexagon.S2.asr.i.r.acc",
+  "llvm.hexagon.S2.asr.i.r.and",
+  "llvm.hexagon.S2.asr.i.r.nac",
+  "llvm.hexagon.S2.asr.i.r.or",
+  "llvm.hexagon.S2.asr.i.r.rnd",
+  "llvm.hexagon.S2.asr.i.r.rnd.goodsyntax",
+  "llvm.hexagon.S2.asr.i.svw.trun",
+  "llvm.hexagon.S2.asr.i.vh",
+  "llvm.hexagon.S2.asr.i.vw",
+  "llvm.hexagon.S2.asr.r.p",
+  "llvm.hexagon.S2.asr.r.p.acc",
+  "llvm.hexagon.S2.asr.r.p.and",
+  "llvm.hexagon.S2.asr.r.p.nac",
+  "llvm.hexagon.S2.asr.r.p.or",
+  "llvm.hexagon.S2.asr.r.p.xor",
+  "llvm.hexagon.S2.asr.r.r",
+  "llvm.hexagon.S2.asr.r.r.acc",
+  "llvm.hexagon.S2.asr.r.r.and",
+  "llvm.hexagon.S2.asr.r.r.nac",
+  "llvm.hexagon.S2.asr.r.r.or",
+  "llvm.hexagon.S2.asr.r.r.sat",
+  "llvm.hexagon.S2.asr.r.svw.trun",
+  "llvm.hexagon.S2.asr.r.vh",
+  "llvm.hexagon.S2.asr.r.vw",
+  "llvm.hexagon.S2.brev",
+  "llvm.hexagon.S2.brevp",
+  "llvm.hexagon.S2.cl0",
+  "llvm.hexagon.S2.cl0p",
+  "llvm.hexagon.S2.cl1",
+  "llvm.hexagon.S2.cl1p",
+  "llvm.hexagon.S2.clb",
+  "llvm.hexagon.S2.clbnorm",
+  "llvm.hexagon.S2.clbp",
+  "llvm.hexagon.S2.clrbit.i",
+  "llvm.hexagon.S2.clrbit.r",
+  "llvm.hexagon.S2.ct0",
+  "llvm.hexagon.S2.ct0p",
+  "llvm.hexagon.S2.ct1",
+  "llvm.hexagon.S2.ct1p",
+  "llvm.hexagon.S2.deinterleave",
+  "llvm.hexagon.S2.extractu",
+  "llvm.hexagon.S2.extractu.rp",
+  "llvm.hexagon.S2.extractup",
+  "llvm.hexagon.S2.extractup.rp",
+  "llvm.hexagon.S2.insert",
+  "llvm.hexagon.S2.insert.rp",
+  "llvm.hexagon.S2.insertp",
+  "llvm.hexagon.S2.insertp.rp",
+  "llvm.hexagon.S2.interleave",
+  "llvm.hexagon.S2.lfsp",
+  "llvm.hexagon.S2.lsl.r.p",
+  "llvm.hexagon.S2.lsl.r.p.acc",
+  "llvm.hexagon.S2.lsl.r.p.and",
+  "llvm.hexagon.S2.lsl.r.p.nac",
+  "llvm.hexagon.S2.lsl.r.p.or",
+  "llvm.hexagon.S2.lsl.r.p.xor",
+  "llvm.hexagon.S2.lsl.r.r",
+  "llvm.hexagon.S2.lsl.r.r.acc",
+  "llvm.hexagon.S2.lsl.r.r.and",
+  "llvm.hexagon.S2.lsl.r.r.nac",
+  "llvm.hexagon.S2.lsl.r.r.or",
+  "llvm.hexagon.S2.lsl.r.vh",
+  "llvm.hexagon.S2.lsl.r.vw",
+  "llvm.hexagon.S2.lsr.i.p",
+  "llvm.hexagon.S2.lsr.i.p.acc",
+  "llvm.hexagon.S2.lsr.i.p.and",
+  "llvm.hexagon.S2.lsr.i.p.nac",
+  "llvm.hexagon.S2.lsr.i.p.or",
+  "llvm.hexagon.S2.lsr.i.p.xacc",
+  "llvm.hexagon.S2.lsr.i.r",
+  "llvm.hexagon.S2.lsr.i.r.acc",
+  "llvm.hexagon.S2.lsr.i.r.and",
+  "llvm.hexagon.S2.lsr.i.r.nac",
+  "llvm.hexagon.S2.lsr.i.r.or",
+  "llvm.hexagon.S2.lsr.i.r.xacc",
+  "llvm.hexagon.S2.lsr.i.vh",
+  "llvm.hexagon.S2.lsr.i.vw",
+  "llvm.hexagon.S2.lsr.r.p",
+  "llvm.hexagon.S2.lsr.r.p.acc",
+  "llvm.hexagon.S2.lsr.r.p.and",
+  "llvm.hexagon.S2.lsr.r.p.nac",
+  "llvm.hexagon.S2.lsr.r.p.or",
+  "llvm.hexagon.S2.lsr.r.p.xor",
+  "llvm.hexagon.S2.lsr.r.r",
+  "llvm.hexagon.S2.lsr.r.r.acc",
+  "llvm.hexagon.S2.lsr.r.r.and",
+  "llvm.hexagon.S2.lsr.r.r.nac",
+  "llvm.hexagon.S2.lsr.r.r.or",
+  "llvm.hexagon.S2.lsr.r.vh",
+  "llvm.hexagon.S2.lsr.r.vw",
+  "llvm.hexagon.S2.packhl",
+  "llvm.hexagon.S2.parityp",
+  "llvm.hexagon.S2.setbit.i",
+  "llvm.hexagon.S2.setbit.r",
+  "llvm.hexagon.S2.shuffeb",
+  "llvm.hexagon.S2.shuffeh",
+  "llvm.hexagon.S2.shuffob",
+  "llvm.hexagon.S2.shuffoh",
+  "llvm.hexagon.S2.svsathb",
+  "llvm.hexagon.S2.svsathub",
+  "llvm.hexagon.S2.tableidxb.goodsyntax",
+  "llvm.hexagon.S2.tableidxd.goodsyntax",
+  "llvm.hexagon.S2.tableidxh.goodsyntax",
+  "llvm.hexagon.S2.tableidxw.goodsyntax",
+  "llvm.hexagon.S2.togglebit.i",
+  "llvm.hexagon.S2.togglebit.r",
+  "llvm.hexagon.S2.tstbit.i",
+  "llvm.hexagon.S2.tstbit.r",
+  "llvm.hexagon.S2.valignib",
+  "llvm.hexagon.S2.valignrb",
+  "llvm.hexagon.S2.vcnegh",
+  "llvm.hexagon.S2.vcrotate",
+  "llvm.hexagon.S2.vrcnegh",
+  "llvm.hexagon.S2.vrndpackwh",
+  "llvm.hexagon.S2.vrndpackwhs",
+  "llvm.hexagon.S2.vsathb",
+  "llvm.hexagon.S2.vsathb.nopack",
+  "llvm.hexagon.S2.vsathub",
+  "llvm.hexagon.S2.vsathub.nopack",
+  "llvm.hexagon.S2.vsatwh",
+  "llvm.hexagon.S2.vsatwh.nopack",
+  "llvm.hexagon.S2.vsatwuh",
+  "llvm.hexagon.S2.vsatwuh.nopack",
+  "llvm.hexagon.S2.vsplatrb",
+  "llvm.hexagon.S2.vsplatrh",
+  "llvm.hexagon.S2.vspliceib",
+  "llvm.hexagon.S2.vsplicerb",
+  "llvm.hexagon.S2.vsxtbh",
+  "llvm.hexagon.S2.vsxthw",
+  "llvm.hexagon.S2.vtrunehb",
+  "llvm.hexagon.S2.vtrunewh",
+  "llvm.hexagon.S2.vtrunohb",
+  "llvm.hexagon.S2.vtrunowh",
+  "llvm.hexagon.S2.vzxtbh",
+  "llvm.hexagon.S2.vzxthw",
+  "llvm.hexagon.S4.addaddi",
+  "llvm.hexagon.S4.addi.asl.ri",
+  "llvm.hexagon.S4.addi.lsr.ri",
+  "llvm.hexagon.S4.andi.asl.ri",
+  "llvm.hexagon.S4.andi.lsr.ri",
+  "llvm.hexagon.S4.clbaddi",
+  "llvm.hexagon.S4.clbpaddi",
+  "llvm.hexagon.S4.clbpnorm",
+  "llvm.hexagon.S4.extract",
+  "llvm.hexagon.S4.extract.rp",
+  "llvm.hexagon.S4.extractp",
+  "llvm.hexagon.S4.extractp.rp",
+  "llvm.hexagon.S4.lsli",
+  "llvm.hexagon.S4.ntstbit.i",
+  "llvm.hexagon.S4.ntstbit.r",
+  "llvm.hexagon.S4.or.andi",
+  "llvm.hexagon.S4.or.andix",
+  "llvm.hexagon.S4.or.ori",
+  "llvm.hexagon.S4.ori.asl.ri",
+  "llvm.hexagon.S4.ori.lsr.ri",
+  "llvm.hexagon.S4.parity",
+  "llvm.hexagon.S4.subaddi",
+  "llvm.hexagon.S4.subi.asl.ri",
+  "llvm.hexagon.S4.subi.lsr.ri",
+  "llvm.hexagon.S4.vrcrotate",
+  "llvm.hexagon.S4.vrcrotate.acc",
+  "llvm.hexagon.S4.vxaddsubh",
+  "llvm.hexagon.S4.vxaddsubhr",
+  "llvm.hexagon.S4.vxaddsubw",
+  "llvm.hexagon.S4.vxsubaddh",
+  "llvm.hexagon.S4.vxsubaddhr",
+  "llvm.hexagon.S4.vxsubaddw",
+  "llvm.hexagon.S5.asrhub.rnd.sat.goodsyntax",
+  "llvm.hexagon.S5.asrhub.sat",
+  "llvm.hexagon.S5.popcountp",
+  "llvm.hexagon.S5.vasrhrnd.goodsyntax",
+  "llvm.hexagon.SI.to.SXTHI.asrh",
+  "llvm.hexagon.circ.ldd",
+  "llvm.init.trampoline",
+  "llvm.invariant.end",
+  "llvm.invariant.start",
+  "llvm.lifetime.end",
+  "llvm.lifetime.start",
+  "llvm.log",
+  "llvm.log10",
+  "llvm.log2",
+  "llvm.longjmp",
+  "llvm.memcpy",
+  "llvm.memmove",
+  "llvm.memset",
+  "llvm.mips.absq.s.ph",
+  "llvm.mips.absq.s.qb",
+  "llvm.mips.absq.s.w",
+  "llvm.mips.add.a.b",
+  "llvm.mips.add.a.d",
+  "llvm.mips.add.a.h",
+  "llvm.mips.add.a.w",
+  "llvm.mips.addq.ph",
+  "llvm.mips.addq.s.ph",
+  "llvm.mips.addq.s.w",
+  "llvm.mips.addqh.ph",
+  "llvm.mips.addqh.r.ph",
+  "llvm.mips.addqh.r.w",
+  "llvm.mips.addqh.w",
+  "llvm.mips.adds.a.b",
+  "llvm.mips.adds.a.d",
+  "llvm.mips.adds.a.h",
+  "llvm.mips.adds.a.w",
+  "llvm.mips.adds.s.b",
+  "llvm.mips.adds.s.d",
+  "llvm.mips.adds.s.h",
+  "llvm.mips.adds.s.w",
+  "llvm.mips.adds.u.b",
+  "llvm.mips.adds.u.d",
+  "llvm.mips.adds.u.h",
+  "llvm.mips.adds.u.w",
+  "llvm.mips.addsc",
+  "llvm.mips.addu.ph",
+  "llvm.mips.addu.qb",
+  "llvm.mips.addu.s.ph",
+  "llvm.mips.addu.s.qb",
+  "llvm.mips.adduh.qb",
+  "llvm.mips.adduh.r.qb",
+  "llvm.mips.addv.b",
+  "llvm.mips.addv.d",
+  "llvm.mips.addv.h",
+  "llvm.mips.addv.w",
+  "llvm.mips.addvi.b",
+  "llvm.mips.addvi.d",
+  "llvm.mips.addvi.h",
+  "llvm.mips.addvi.w",
+  "llvm.mips.addwc",
+  "llvm.mips.and.v",
+  "llvm.mips.andi.b",
+  "llvm.mips.append",
+  "llvm.mips.asub.s.b",
+  "llvm.mips.asub.s.d",
+  "llvm.mips.asub.s.h",
+  "llvm.mips.asub.s.w",
+  "llvm.mips.asub.u.b",
+  "llvm.mips.asub.u.d",
+  "llvm.mips.asub.u.h",
+  "llvm.mips.asub.u.w",
+  "llvm.mips.ave.s.b",
+  "llvm.mips.ave.s.d",
+  "llvm.mips.ave.s.h",
+  "llvm.mips.ave.s.w",
+  "llvm.mips.ave.u.b",
+  "llvm.mips.ave.u.d",
+  "llvm.mips.ave.u.h",
+  "llvm.mips.ave.u.w",
+  "llvm.mips.aver.s.b",
+  "llvm.mips.aver.s.d",
+  "llvm.mips.aver.s.h",
+  "llvm.mips.aver.s.w",
+  "llvm.mips.aver.u.b",
+  "llvm.mips.aver.u.d",
+  "llvm.mips.aver.u.h",
+  "llvm.mips.aver.u.w",
+  "llvm.mips.balign",
+  "llvm.mips.bclr.b",
+  "llvm.mips.bclr.d",
+  "llvm.mips.bclr.h",
+  "llvm.mips.bclr.w",
+  "llvm.mips.bclri.b",
+  "llvm.mips.bclri.d",
+  "llvm.mips.bclri.h",
+  "llvm.mips.bclri.w",
+  "llvm.mips.binsl.b",
+  "llvm.mips.binsl.d",
+  "llvm.mips.binsl.h",
+  "llvm.mips.binsl.w",
+  "llvm.mips.binsli.b",
+  "llvm.mips.binsli.d",
+  "llvm.mips.binsli.h",
+  "llvm.mips.binsli.w",
+  "llvm.mips.binsr.b",
+  "llvm.mips.binsr.d",
+  "llvm.mips.binsr.h",
+  "llvm.mips.binsr.w",
+  "llvm.mips.binsri.b",
+  "llvm.mips.binsri.d",
+  "llvm.mips.binsri.h",
+  "llvm.mips.binsri.w",
+  "llvm.mips.bitrev",
+  "llvm.mips.bmnz.v",
+  "llvm.mips.bmnzi.b",
+  "llvm.mips.bmz.v",
+  "llvm.mips.bmzi.b",
+  "llvm.mips.bneg.b",
+  "llvm.mips.bneg.d",
+  "llvm.mips.bneg.h",
+  "llvm.mips.bneg.w",
+  "llvm.mips.bnegi.b",
+  "llvm.mips.bnegi.d",
+  "llvm.mips.bnegi.h",
+  "llvm.mips.bnegi.w",
+  "llvm.mips.bnz.b",
+  "llvm.mips.bnz.d",
+  "llvm.mips.bnz.h",
+  "llvm.mips.bnz.v",
+  "llvm.mips.bnz.w",
+  "llvm.mips.bposge32",
+  "llvm.mips.bsel.v",
+  "llvm.mips.bseli.b",
+  "llvm.mips.bset.b",
+  "llvm.mips.bset.d",
+  "llvm.mips.bset.h",
+  "llvm.mips.bset.w",
+  "llvm.mips.bseti.b",
+  "llvm.mips.bseti.d",
+  "llvm.mips.bseti.h",
+  "llvm.mips.bseti.w",
+  "llvm.mips.bz.b",
+  "llvm.mips.bz.d",
+  "llvm.mips.bz.h",
+  "llvm.mips.bz.v",
+  "llvm.mips.bz.w",
+  "llvm.mips.ceq.b",
+  "llvm.mips.ceq.d",
+  "llvm.mips.ceq.h",
+  "llvm.mips.ceq.w",
+  "llvm.mips.ceqi.b",
+  "llvm.mips.ceqi.d",
+  "llvm.mips.ceqi.h",
+  "llvm.mips.ceqi.w",
+  "llvm.mips.cfcmsa",
+  "llvm.mips.cle.s.b",
+  "llvm.mips.cle.s.d",
+  "llvm.mips.cle.s.h",
+  "llvm.mips.cle.s.w",
+  "llvm.mips.cle.u.b",
+  "llvm.mips.cle.u.d",
+  "llvm.mips.cle.u.h",
+  "llvm.mips.cle.u.w",
+  "llvm.mips.clei.s.b",
+  "llvm.mips.clei.s.d",
+  "llvm.mips.clei.s.h",
+  "llvm.mips.clei.s.w",
+  "llvm.mips.clei.u.b",
+  "llvm.mips.clei.u.d",
+  "llvm.mips.clei.u.h",
+  "llvm.mips.clei.u.w",
+  "llvm.mips.clt.s.b",
+  "llvm.mips.clt.s.d",
+  "llvm.mips.clt.s.h",
+  "llvm.mips.clt.s.w",
+  "llvm.mips.clt.u.b",
+  "llvm.mips.clt.u.d",
+  "llvm.mips.clt.u.h",
+  "llvm.mips.clt.u.w",
+  "llvm.mips.clti.s.b",
+  "llvm.mips.clti.s.d",
+  "llvm.mips.clti.s.h",
+  "llvm.mips.clti.s.w",
+  "llvm.mips.clti.u.b",
+  "llvm.mips.clti.u.d",
+  "llvm.mips.clti.u.h",
+  "llvm.mips.clti.u.w",
+  "llvm.mips.cmp.eq.ph",
+  "llvm.mips.cmp.le.ph",
+  "llvm.mips.cmp.lt.ph",
+  "llvm.mips.cmpgdu.eq.qb",
+  "llvm.mips.cmpgdu.le.qb",
+  "llvm.mips.cmpgdu.lt.qb",
+  "llvm.mips.cmpgu.eq.qb",
+  "llvm.mips.cmpgu.le.qb",
+  "llvm.mips.cmpgu.lt.qb",
+  "llvm.mips.cmpu.eq.qb",
+  "llvm.mips.cmpu.le.qb",
+  "llvm.mips.cmpu.lt.qb",
+  "llvm.mips.copy.s.b",
+  "llvm.mips.copy.s.d",
+  "llvm.mips.copy.s.h",
+  "llvm.mips.copy.s.w",
+  "llvm.mips.copy.u.b",
+  "llvm.mips.copy.u.d",
+  "llvm.mips.copy.u.h",
+  "llvm.mips.copy.u.w",
+  "llvm.mips.ctcmsa",
+  "llvm.mips.div.s.b",
+  "llvm.mips.div.s.d",
+  "llvm.mips.div.s.h",
+  "llvm.mips.div.s.w",
+  "llvm.mips.div.u.b",
+  "llvm.mips.div.u.d",
+  "llvm.mips.div.u.h",
+  "llvm.mips.div.u.w",
+  "llvm.mips.dlsa",
+  "llvm.mips.dotp.s.d",
+  "llvm.mips.dotp.s.h",
+  "llvm.mips.dotp.s.w",
+  "llvm.mips.dotp.u.d",
+  "llvm.mips.dotp.u.h",
+  "llvm.mips.dotp.u.w",
+  "llvm.mips.dpa.w.ph",
+  "llvm.mips.dpadd.s.d",
+  "llvm.mips.dpadd.s.h",
+  "llvm.mips.dpadd.s.w",
+  "llvm.mips.dpadd.u.d",
+  "llvm.mips.dpadd.u.h",
+  "llvm.mips.dpadd.u.w",
+  "llvm.mips.dpaq.s.w.ph",
+  "llvm.mips.dpaq.sa.l.w",
+  "llvm.mips.dpaqx.s.w.ph",
+  "llvm.mips.dpaqx.sa.w.ph",
+  "llvm.mips.dpau.h.qbl",
+  "llvm.mips.dpau.h.qbr",
+  "llvm.mips.dpax.w.ph",
+  "llvm.mips.dps.w.ph",
+  "llvm.mips.dpsq.s.w.ph",
+  "llvm.mips.dpsq.sa.l.w",
+  "llvm.mips.dpsqx.s.w.ph",
+  "llvm.mips.dpsqx.sa.w.ph",
+  "llvm.mips.dpsu.h.qbl",
+  "llvm.mips.dpsu.h.qbr",
+  "llvm.mips.dpsub.s.d",
+  "llvm.mips.dpsub.s.h",
+  "llvm.mips.dpsub.s.w",
+  "llvm.mips.dpsub.u.d",
+  "llvm.mips.dpsub.u.h",
+  "llvm.mips.dpsub.u.w",
+  "llvm.mips.dpsx.w.ph",
+  "llvm.mips.extp",
+  "llvm.mips.extpdp",
+  "llvm.mips.extr.r.w",
+  "llvm.mips.extr.rs.w",
+  "llvm.mips.extr.s.h",
+  "llvm.mips.extr.w",
+  "llvm.mips.fadd.d",
+  "llvm.mips.fadd.w",
+  "llvm.mips.fcaf.d",
+  "llvm.mips.fcaf.w",
+  "llvm.mips.fceq.d",
+  "llvm.mips.fceq.w",
+  "llvm.mips.fclass.d",
+  "llvm.mips.fclass.w",
+  "llvm.mips.fcle.d",
+  "llvm.mips.fcle.w",
+  "llvm.mips.fclt.d",
+  "llvm.mips.fclt.w",
+  "llvm.mips.fcne.d",
+  "llvm.mips.fcne.w",
+  "llvm.mips.fcor.d",
+  "llvm.mips.fcor.w",
+  "llvm.mips.fcueq.d",
+  "llvm.mips.fcueq.w",
+  "llvm.mips.fcule.d",
+  "llvm.mips.fcule.w",
+  "llvm.mips.fcult.d",
+  "llvm.mips.fcult.w",
+  "llvm.mips.fcun.d",
+  "llvm.mips.fcun.w",
+  "llvm.mips.fcune.d",
+  "llvm.mips.fcune.w",
+  "llvm.mips.fdiv.d",
+  "llvm.mips.fdiv.w",
+  "llvm.mips.fexdo.h",
+  "llvm.mips.fexdo.w",
+  "llvm.mips.fexp2.d",
+  "llvm.mips.fexp2.w",
+  "llvm.mips.fexupl.d",
+  "llvm.mips.fexupl.w",
+  "llvm.mips.fexupr.d",
+  "llvm.mips.fexupr.w",
+  "llvm.mips.ffint.s.d",
+  "llvm.mips.ffint.s.w",
+  "llvm.mips.ffint.u.d",
+  "llvm.mips.ffint.u.w",
+  "llvm.mips.ffql.d",
+  "llvm.mips.ffql.w",
+  "llvm.mips.ffqr.d",
+  "llvm.mips.ffqr.w",
+  "llvm.mips.fill.b",
+  "llvm.mips.fill.d",
+  "llvm.mips.fill.h",
+  "llvm.mips.fill.w",
+  "llvm.mips.flog2.d",
+  "llvm.mips.flog2.w",
+  "llvm.mips.fmadd.d",
+  "llvm.mips.fmadd.w",
+  "llvm.mips.fmax.a.d",
+  "llvm.mips.fmax.a.w",
+  "llvm.mips.fmax.d",
+  "llvm.mips.fmax.w",
+  "llvm.mips.fmin.a.d",
+  "llvm.mips.fmin.a.w",
+  "llvm.mips.fmin.d",
+  "llvm.mips.fmin.w",
+  "llvm.mips.fmsub.d",
+  "llvm.mips.fmsub.w",
+  "llvm.mips.fmul.d",
+  "llvm.mips.fmul.w",
+  "llvm.mips.frcp.d",
+  "llvm.mips.frcp.w",
+  "llvm.mips.frint.d",
+  "llvm.mips.frint.w",
+  "llvm.mips.frsqrt.d",
+  "llvm.mips.frsqrt.w",
+  "llvm.mips.fsaf.d",
+  "llvm.mips.fsaf.w",
+  "llvm.mips.fseq.d",
+  "llvm.mips.fseq.w",
+  "llvm.mips.fsle.d",
+  "llvm.mips.fsle.w",
+  "llvm.mips.fslt.d",
+  "llvm.mips.fslt.w",
+  "llvm.mips.fsne.d",
+  "llvm.mips.fsne.w",
+  "llvm.mips.fsor.d",
+  "llvm.mips.fsor.w",
+  "llvm.mips.fsqrt.d",
+  "llvm.mips.fsqrt.w",
+  "llvm.mips.fsub.d",
+  "llvm.mips.fsub.w",
+  "llvm.mips.fsueq.d",
+  "llvm.mips.fsueq.w",
+  "llvm.mips.fsule.d",
+  "llvm.mips.fsule.w",
+  "llvm.mips.fsult.d",
+  "llvm.mips.fsult.w",
+  "llvm.mips.fsun.d",
+  "llvm.mips.fsun.w",
+  "llvm.mips.fsune.d",
+  "llvm.mips.fsune.w",
+  "llvm.mips.ftint.s.d",
+  "llvm.mips.ftint.s.w",
+  "llvm.mips.ftint.u.d",
+  "llvm.mips.ftint.u.w",
+  "llvm.mips.ftq.h",
+  "llvm.mips.ftq.w",
+  "llvm.mips.ftrunc.s.d",
+  "llvm.mips.ftrunc.s.w",
+  "llvm.mips.ftrunc.u.d",
+  "llvm.mips.ftrunc.u.w",
+  "llvm.mips.hadd.s.d",
+  "llvm.mips.hadd.s.h",
+  "llvm.mips.hadd.s.w",
+  "llvm.mips.hadd.u.d",
+  "llvm.mips.hadd.u.h",
+  "llvm.mips.hadd.u.w",
+  "llvm.mips.hsub.s.d",
+  "llvm.mips.hsub.s.h",
+  "llvm.mips.hsub.s.w",
+  "llvm.mips.hsub.u.d",
+  "llvm.mips.hsub.u.h",
+  "llvm.mips.hsub.u.w",
+  "llvm.mips.ilvev.b",
+  "llvm.mips.ilvev.d",
+  "llvm.mips.ilvev.h",
+  "llvm.mips.ilvev.w",
+  "llvm.mips.ilvl.b",
+  "llvm.mips.ilvl.d",
+  "llvm.mips.ilvl.h",
+  "llvm.mips.ilvl.w",
+  "llvm.mips.ilvod.b",
+  "llvm.mips.ilvod.d",
+  "llvm.mips.ilvod.h",
+  "llvm.mips.ilvod.w",
+  "llvm.mips.ilvr.b",
+  "llvm.mips.ilvr.d",
+  "llvm.mips.ilvr.h",
+  "llvm.mips.ilvr.w",
+  "llvm.mips.insert.b",
+  "llvm.mips.insert.d",
+  "llvm.mips.insert.h",
+  "llvm.mips.insert.w",
+  "llvm.mips.insv",
+  "llvm.mips.insve.b",
+  "llvm.mips.insve.d",
+  "llvm.mips.insve.h",
+  "llvm.mips.insve.w",
+  "llvm.mips.lbux",
+  "llvm.mips.ld.b",
+  "llvm.mips.ld.d",
+  "llvm.mips.ld.h",
+  "llvm.mips.ld.w",
+  "llvm.mips.ldi.b",
+  "llvm.mips.ldi.d",
+  "llvm.mips.ldi.h",
+  "llvm.mips.ldi.w",
+  "llvm.mips.lhx",
+  "llvm.mips.lsa",
+  "llvm.mips.lwx",
+  "llvm.mips.madd",
+  "llvm.mips.madd.q.h",
+  "llvm.mips.madd.q.w",
+  "llvm.mips.maddr.q.h",
+  "llvm.mips.maddr.q.w",
+  "llvm.mips.maddu",
+  "llvm.mips.maddv.b",
+  "llvm.mips.maddv.d",
+  "llvm.mips.maddv.h",
+  "llvm.mips.maddv.w",
+  "llvm.mips.maq.s.w.phl",
+  "llvm.mips.maq.s.w.phr",
+  "llvm.mips.maq.sa.w.phl",
+  "llvm.mips.maq.sa.w.phr",
+  "llvm.mips.max.a.b",
+  "llvm.mips.max.a.d",
+  "llvm.mips.max.a.h",
+  "llvm.mips.max.a.w",
+  "llvm.mips.max.s.b",
+  "llvm.mips.max.s.d",
+  "llvm.mips.max.s.h",
+  "llvm.mips.max.s.w",
+  "llvm.mips.max.u.b",
+  "llvm.mips.max.u.d",
+  "llvm.mips.max.u.h",
+  "llvm.mips.max.u.w",
+  "llvm.mips.maxi.s.b",
+  "llvm.mips.maxi.s.d",
+  "llvm.mips.maxi.s.h",
+  "llvm.mips.maxi.s.w",
+  "llvm.mips.maxi.u.b",
+  "llvm.mips.maxi.u.d",
+  "llvm.mips.maxi.u.h",
+  "llvm.mips.maxi.u.w",
+  "llvm.mips.min.a.b",
+  "llvm.mips.min.a.d",
+  "llvm.mips.min.a.h",
+  "llvm.mips.min.a.w",
+  "llvm.mips.min.s.b",
+  "llvm.mips.min.s.d",
+  "llvm.mips.min.s.h",
+  "llvm.mips.min.s.w",
+  "llvm.mips.min.u.b",
+  "llvm.mips.min.u.d",
+  "llvm.mips.min.u.h",
+  "llvm.mips.min.u.w",
+  "llvm.mips.mini.s.b",
+  "llvm.mips.mini.s.d",
+  "llvm.mips.mini.s.h",
+  "llvm.mips.mini.s.w",
+  "llvm.mips.mini.u.b",
+  "llvm.mips.mini.u.d",
+  "llvm.mips.mini.u.h",
+  "llvm.mips.mini.u.w",
+  "llvm.mips.mod.s.b",
+  "llvm.mips.mod.s.d",
+  "llvm.mips.mod.s.h",
+  "llvm.mips.mod.s.w",
+  "llvm.mips.mod.u.b",
+  "llvm.mips.mod.u.d",
+  "llvm.mips.mod.u.h",
+  "llvm.mips.mod.u.w",
+  "llvm.mips.modsub",
+  "llvm.mips.move.v",
+  "llvm.mips.msub",
+  "llvm.mips.msub.q.h",
+  "llvm.mips.msub.q.w",
+  "llvm.mips.msubr.q.h",
+  "llvm.mips.msubr.q.w",
+  "llvm.mips.msubu",
+  "llvm.mips.msubv.b",
+  "llvm.mips.msubv.d",
+  "llvm.mips.msubv.h",
+  "llvm.mips.msubv.w",
+  "llvm.mips.mthlip",
+  "llvm.mips.mul.ph",
+  "llvm.mips.mul.q.h",
+  "llvm.mips.mul.q.w",
+  "llvm.mips.mul.s.ph",
+  "llvm.mips.muleq.s.w.phl",
+  "llvm.mips.muleq.s.w.phr",
+  "llvm.mips.muleu.s.ph.qbl",
+  "llvm.mips.muleu.s.ph.qbr",
+  "llvm.mips.mulq.rs.ph",
+  "llvm.mips.mulq.rs.w",
+  "llvm.mips.mulq.s.ph",
+  "llvm.mips.mulq.s.w",
+  "llvm.mips.mulr.q.h",
+  "llvm.mips.mulr.q.w",
+  "llvm.mips.mulsa.w.ph",
+  "llvm.mips.mulsaq.s.w.ph",
+  "llvm.mips.mult",
+  "llvm.mips.multu",
+  "llvm.mips.mulv.b",
+  "llvm.mips.mulv.d",
+  "llvm.mips.mulv.h",
+  "llvm.mips.mulv.w",
+  "llvm.mips.nloc.b",
+  "llvm.mips.nloc.d",
+  "llvm.mips.nloc.h",
+  "llvm.mips.nloc.w",
+  "llvm.mips.nlzc.b",
+  "llvm.mips.nlzc.d",
+  "llvm.mips.nlzc.h",
+  "llvm.mips.nlzc.w",
+  "llvm.mips.nor.v",
+  "llvm.mips.nori.b",
+  "llvm.mips.or.v",
+  "llvm.mips.ori.b",
+  "llvm.mips.packrl.ph",
+  "llvm.mips.pckev.b",
+  "llvm.mips.pckev.d",
+  "llvm.mips.pckev.h",
+  "llvm.mips.pckev.w",
+  "llvm.mips.pckod.b",
+  "llvm.mips.pckod.d",
+  "llvm.mips.pckod.h",
+  "llvm.mips.pckod.w",
+  "llvm.mips.pcnt.b",
+  "llvm.mips.pcnt.d",
+  "llvm.mips.pcnt.h",
+  "llvm.mips.pcnt.w",
+  "llvm.mips.pick.ph",
+  "llvm.mips.pick.qb",
+  "llvm.mips.preceq.w.phl",
+  "llvm.mips.preceq.w.phr",
+  "llvm.mips.precequ.ph.qbl",
+  "llvm.mips.precequ.ph.qbla",
+  "llvm.mips.precequ.ph.qbr",
+  "llvm.mips.precequ.ph.qbra",
+  "llvm.mips.preceu.ph.qbl",
+  "llvm.mips.preceu.ph.qbla",
+  "llvm.mips.preceu.ph.qbr",
+  "llvm.mips.preceu.ph.qbra",
+  "llvm.mips.precr.qb.ph",
+  "llvm.mips.precr.sra.ph.w",
+  "llvm.mips.precr.sra.r.ph.w",
+  "llvm.mips.precrq.ph.w",
+  "llvm.mips.precrq.qb.ph",
+  "llvm.mips.precrq.rs.ph.w",
+  "llvm.mips.precrqu.s.qb.ph",
+  "llvm.mips.prepend",
+  "llvm.mips.raddu.w.qb",
+  "llvm.mips.rddsp",
+  "llvm.mips.repl.ph",
+  "llvm.mips.repl.qb",
+  "llvm.mips.sat.s.b",
+  "llvm.mips.sat.s.d",
+  "llvm.mips.sat.s.h",
+  "llvm.mips.sat.s.w",
+  "llvm.mips.sat.u.b",
+  "llvm.mips.sat.u.d",
+  "llvm.mips.sat.u.h",
+  "llvm.mips.sat.u.w",
+  "llvm.mips.shf.b",
+  "llvm.mips.shf.h",
+  "llvm.mips.shf.w",
+  "llvm.mips.shilo",
+  "llvm.mips.shll.ph",
+  "llvm.mips.shll.qb",
+  "llvm.mips.shll.s.ph",
+  "llvm.mips.shll.s.w",
+  "llvm.mips.shra.ph",
+  "llvm.mips.shra.qb",
+  "llvm.mips.shra.r.ph",
+  "llvm.mips.shra.r.qb",
+  "llvm.mips.shra.r.w",
+  "llvm.mips.shrl.ph",
+  "llvm.mips.shrl.qb",
+  "llvm.mips.sld.b",
+  "llvm.mips.sld.d",
+  "llvm.mips.sld.h",
+  "llvm.mips.sld.w",
+  "llvm.mips.sldi.b",
+  "llvm.mips.sldi.d",
+  "llvm.mips.sldi.h",
+  "llvm.mips.sldi.w",
+  "llvm.mips.sll.b",
+  "llvm.mips.sll.d",
+  "llvm.mips.sll.h",
+  "llvm.mips.sll.w",
+  "llvm.mips.slli.b",
+  "llvm.mips.slli.d",
+  "llvm.mips.slli.h",
+  "llvm.mips.slli.w",
+  "llvm.mips.splat.b",
+  "llvm.mips.splat.d",
+  "llvm.mips.splat.h",
+  "llvm.mips.splat.w",
+  "llvm.mips.splati.b",
+  "llvm.mips.splati.d",
+  "llvm.mips.splati.h",
+  "llvm.mips.splati.w",
+  "llvm.mips.sra.b",
+  "llvm.mips.sra.d",
+  "llvm.mips.sra.h",
+  "llvm.mips.sra.w",
+  "llvm.mips.srai.b",
+  "llvm.mips.srai.d",
+  "llvm.mips.srai.h",
+  "llvm.mips.srai.w",
+  "llvm.mips.srar.b",
+  "llvm.mips.srar.d",
+  "llvm.mips.srar.h",
+  "llvm.mips.srar.w",
+  "llvm.mips.srari.b",
+  "llvm.mips.srari.d",
+  "llvm.mips.srari.h",
+  "llvm.mips.srari.w",
+  "llvm.mips.srl.b",
+  "llvm.mips.srl.d",
+  "llvm.mips.srl.h",
+  "llvm.mips.srl.w",
+  "llvm.mips.srli.b",
+  "llvm.mips.srli.d",
+  "llvm.mips.srli.h",
+  "llvm.mips.srli.w",
+  "llvm.mips.srlr.b",
+  "llvm.mips.srlr.d",
+  "llvm.mips.srlr.h",
+  "llvm.mips.srlr.w",
+  "llvm.mips.srlri.b",
+  "llvm.mips.srlri.d",
+  "llvm.mips.srlri.h",
+  "llvm.mips.srlri.w",
+  "llvm.mips.st.b",
+  "llvm.mips.st.d",
+  "llvm.mips.st.h",
+  "llvm.mips.st.w",
+  "llvm.mips.subq.ph",
+  "llvm.mips.subq.s.ph",
+  "llvm.mips.subq.s.w",
+  "llvm.mips.subqh.ph",
+  "llvm.mips.subqh.r.ph",
+  "llvm.mips.subqh.r.w",
+  "llvm.mips.subqh.w",
+  "llvm.mips.subs.s.b",
+  "llvm.mips.subs.s.d",
+  "llvm.mips.subs.s.h",
+  "llvm.mips.subs.s.w",
+  "llvm.mips.subs.u.b",
+  "llvm.mips.subs.u.d",
+  "llvm.mips.subs.u.h",
+  "llvm.mips.subs.u.w",
+  "llvm.mips.subsus.u.b",
+  "llvm.mips.subsus.u.d",
+  "llvm.mips.subsus.u.h",
+  "llvm.mips.subsus.u.w",
+  "llvm.mips.subsuu.s.b",
+  "llvm.mips.subsuu.s.d",
+  "llvm.mips.subsuu.s.h",
+  "llvm.mips.subsuu.s.w",
+  "llvm.mips.subu.ph",
+  "llvm.mips.subu.qb",
+  "llvm.mips.subu.s.ph",
+  "llvm.mips.subu.s.qb",
+  "llvm.mips.subuh.qb",
+  "llvm.mips.subuh.r.qb",
+  "llvm.mips.subv.b",
+  "llvm.mips.subv.d",
+  "llvm.mips.subv.h",
+  "llvm.mips.subv.w",
+  "llvm.mips.subvi.b",
+  "llvm.mips.subvi.d",
+  "llvm.mips.subvi.h",
+  "llvm.mips.subvi.w",
+  "llvm.mips.vshf.b",
+  "llvm.mips.vshf.d",
+  "llvm.mips.vshf.h",
+  "llvm.mips.vshf.w",
+  "llvm.mips.wrdsp",
+  "llvm.mips.xor.v",
+  "llvm.mips.xori.b",
+  "llvm.nearbyint",
+  "llvm.nvvm.abs.i",
+  "llvm.nvvm.abs.ll",
+  "llvm.nvvm.add.rm.d",
+  "llvm.nvvm.add.rm.f",
+  "llvm.nvvm.add.rm.ftz.f",
+  "llvm.nvvm.add.rn.d",
+  "llvm.nvvm.add.rn.f",
+  "llvm.nvvm.add.rn.ftz.f",
+  "llvm.nvvm.add.rp.d",
+  "llvm.nvvm.add.rp.f",
+  "llvm.nvvm.add.rp.ftz.f",
+  "llvm.nvvm.add.rz.d",
+  "llvm.nvvm.add.rz.f",
+  "llvm.nvvm.add.rz.ftz.f",
+  "llvm.nvvm.atomic.load.add.f32",
+  "llvm.nvvm.atomic.load.dec.32",
+  "llvm.nvvm.atomic.load.inc.32",
+  "llvm.nvvm.barrier0",
+  "llvm.nvvm.barrier0.and",
+  "llvm.nvvm.barrier0.or",
+  "llvm.nvvm.barrier0.popc",
+  "llvm.nvvm.bitcast.d2ll",
+  "llvm.nvvm.bitcast.f2i",
+  "llvm.nvvm.bitcast.i2f",
+  "llvm.nvvm.bitcast.ll2d",
+  "llvm.nvvm.brev32",
+  "llvm.nvvm.brev64",
+  "llvm.nvvm.ceil.d",
+  "llvm.nvvm.ceil.f",
+  "llvm.nvvm.ceil.ftz.f",
+  "llvm.nvvm.clz.i",
+  "llvm.nvvm.clz.ll",
+  "llvm.nvvm.compiler.error",
+  "llvm.nvvm.compiler.warn",
+  "llvm.nvvm.cos.approx.f",
+  "llvm.nvvm.cos.approx.ftz.f",
+  "llvm.nvvm.d2f.rm",
+  "llvm.nvvm.d2f.rm.ftz",
+  "llvm.nvvm.d2f.rn",
+  "llvm.nvvm.d2f.rn.ftz",
+  "llvm.nvvm.d2f.rp",
+  "llvm.nvvm.d2f.rp.ftz",
+  "llvm.nvvm.d2f.rz",
+  "llvm.nvvm.d2f.rz.ftz",
+  "llvm.nvvm.d2i.hi",
+  "llvm.nvvm.d2i.lo",
+  "llvm.nvvm.d2i.rm",
+  "llvm.nvvm.d2i.rn",
+  "llvm.nvvm.d2i.rp",
+  "llvm.nvvm.d2i.rz",
+  "llvm.nvvm.d2ll.rm",
+  "llvm.nvvm.d2ll.rn",
+  "llvm.nvvm.d2ll.rp",
+  "llvm.nvvm.d2ll.rz",
+  "llvm.nvvm.d2ui.rm",
+  "llvm.nvvm.d2ui.rn",
+  "llvm.nvvm.d2ui.rp",
+  "llvm.nvvm.d2ui.rz",
+  "llvm.nvvm.d2ull.rm",
+  "llvm.nvvm.d2ull.rn",
+  "llvm.nvvm.d2ull.rp",
+  "llvm.nvvm.d2ull.rz",
+  "llvm.nvvm.div.approx.f",
+  "llvm.nvvm.div.approx.ftz.f",
+  "llvm.nvvm.div.rm.d",
+  "llvm.nvvm.div.rm.f",
+  "llvm.nvvm.div.rm.ftz.f",
+  "llvm.nvvm.div.rn.d",
+  "llvm.nvvm.div.rn.f",
+  "llvm.nvvm.div.rn.ftz.f",
+  "llvm.nvvm.div.rp.d",
+  "llvm.nvvm.div.rp.f",
+  "llvm.nvvm.div.rp.ftz.f",
+  "llvm.nvvm.div.rz.d",
+  "llvm.nvvm.div.rz.f",
+  "llvm.nvvm.div.rz.ftz.f",
+  "llvm.nvvm.ex2.approx.d",
+  "llvm.nvvm.ex2.approx.f",
+  "llvm.nvvm.ex2.approx.ftz.f",
+  "llvm.nvvm.f2h.rn",
+  "llvm.nvvm.f2h.rn.ftz",
+  "llvm.nvvm.f2i.rm",
+  "llvm.nvvm.f2i.rm.ftz",
+  "llvm.nvvm.f2i.rn",
+  "llvm.nvvm.f2i.rn.ftz",
+  "llvm.nvvm.f2i.rp",
+  "llvm.nvvm.f2i.rp.ftz",
+  "llvm.nvvm.f2i.rz",
+  "llvm.nvvm.f2i.rz.ftz",
+  "llvm.nvvm.f2ll.rm",
+  "llvm.nvvm.f2ll.rm.ftz",
+  "llvm.nvvm.f2ll.rn",
+  "llvm.nvvm.f2ll.rn.ftz",
+  "llvm.nvvm.f2ll.rp",
+  "llvm.nvvm.f2ll.rp.ftz",
+  "llvm.nvvm.f2ll.rz",
+  "llvm.nvvm.f2ll.rz.ftz",
+  "llvm.nvvm.f2ui.rm",
+  "llvm.nvvm.f2ui.rm.ftz",
+  "llvm.nvvm.f2ui.rn",
+  "llvm.nvvm.f2ui.rn.ftz",
+  "llvm.nvvm.f2ui.rp",
+  "llvm.nvvm.f2ui.rp.ftz",
+  "llvm.nvvm.f2ui.rz",
+  "llvm.nvvm.f2ui.rz.ftz",
+  "llvm.nvvm.f2ull.rm",
+  "llvm.nvvm.f2ull.rm.ftz",
+  "llvm.nvvm.f2ull.rn",
+  "llvm.nvvm.f2ull.rn.ftz",
+  "llvm.nvvm.f2ull.rp",
+  "llvm.nvvm.f2ull.rp.ftz",
+  "llvm.nvvm.f2ull.rz",
+  "llvm.nvvm.f2ull.rz.ftz",
+  "llvm.nvvm.fabs.d",
+  "llvm.nvvm.fabs.f",
+  "llvm.nvvm.fabs.ftz.f",
+  "llvm.nvvm.floor.d",
+  "llvm.nvvm.floor.f",
+  "llvm.nvvm.floor.ftz.f",
+  "llvm.nvvm.fma.rm.d",
+  "llvm.nvvm.fma.rm.f",
+  "llvm.nvvm.fma.rm.ftz.f",
+  "llvm.nvvm.fma.rn.d",
+  "llvm.nvvm.fma.rn.f",
+  "llvm.nvvm.fma.rn.ftz.f",
+  "llvm.nvvm.fma.rp.d",
+  "llvm.nvvm.fma.rp.f",
+  "llvm.nvvm.fma.rp.ftz.f",
+  "llvm.nvvm.fma.rz.d",
+  "llvm.nvvm.fma.rz.f",
+  "llvm.nvvm.fma.rz.ftz.f",
+  "llvm.nvvm.fmax.d",
+  "llvm.nvvm.fmax.f",
+  "llvm.nvvm.fmax.ftz.f",
+  "llvm.nvvm.fmin.d",
+  "llvm.nvvm.fmin.f",
+  "llvm.nvvm.fmin.ftz.f",
+  "llvm.nvvm.h2f",
+  "llvm.nvvm.i2d.rm",
+  "llvm.nvvm.i2d.rn",
+  "llvm.nvvm.i2d.rp",
+  "llvm.nvvm.i2d.rz",
+  "llvm.nvvm.i2f.rm",
+  "llvm.nvvm.i2f.rn",
+  "llvm.nvvm.i2f.rp",
+  "llvm.nvvm.i2f.rz",
+  "llvm.nvvm.isspacep.const",
+  "llvm.nvvm.isspacep.global",
+  "llvm.nvvm.isspacep.local",
+  "llvm.nvvm.isspacep.shared",
+  "llvm.nvvm.istypep.sampler",
+  "llvm.nvvm.istypep.surface",
+  "llvm.nvvm.istypep.texture",
+  "llvm.nvvm.ldg.global.f",
+  "llvm.nvvm.ldg.global.i",
+  "llvm.nvvm.ldg.global.p",
+  "llvm.nvvm.ldu.global.f",
+  "llvm.nvvm.ldu.global.i",
+  "llvm.nvvm.ldu.global.p",
+  "llvm.nvvm.lg2.approx.d",
+  "llvm.nvvm.lg2.approx.f",
+  "llvm.nvvm.lg2.approx.ftz.f",
+  "llvm.nvvm.ll2d.rm",
+  "llvm.nvvm.ll2d.rn",
+  "llvm.nvvm.ll2d.rp",
+  "llvm.nvvm.ll2d.rz",
+  "llvm.nvvm.ll2f.rm",
+  "llvm.nvvm.ll2f.rn",
+  "llvm.nvvm.ll2f.rp",
+  "llvm.nvvm.ll2f.rz",
+  "llvm.nvvm.lohi.i2d",
+  "llvm.nvvm.max.i",
+  "llvm.nvvm.max.ll",
+  "llvm.nvvm.max.ui",
+  "llvm.nvvm.max.ull",
+  "llvm.nvvm.membar.cta",
+  "llvm.nvvm.membar.gl",
+  "llvm.nvvm.membar.sys",
+  "llvm.nvvm.min.i",
+  "llvm.nvvm.min.ll",
+  "llvm.nvvm.min.ui",
+  "llvm.nvvm.min.ull",
+  "llvm.nvvm.move.double",
+  "llvm.nvvm.move.float",
+  "llvm.nvvm.move.i16",
+  "llvm.nvvm.move.i32",
+  "llvm.nvvm.move.i64",
+  "llvm.nvvm.move.ptr",
+  "llvm.nvvm.mul24.i",
+  "llvm.nvvm.mul24.ui",
+  "llvm.nvvm.mul.rm.d",
+  "llvm.nvvm.mul.rm.f",
+  "llvm.nvvm.mul.rm.ftz.f",
+  "llvm.nvvm.mul.rn.d",
+  "llvm.nvvm.mul.rn.f",
+  "llvm.nvvm.mul.rn.ftz.f",
+  "llvm.nvvm.mul.rp.d",
+  "llvm.nvvm.mul.rp.f",
+  "llvm.nvvm.mul.rp.ftz.f",
+  "llvm.nvvm.mul.rz.d",
+  "llvm.nvvm.mul.rz.f",
+  "llvm.nvvm.mul.rz.ftz.f",
+  "llvm.nvvm.mulhi.i",
+  "llvm.nvvm.mulhi.ll",
+  "llvm.nvvm.mulhi.ui",
+  "llvm.nvvm.mulhi.ull",
+  "llvm.nvvm.popc.i",
+  "llvm.nvvm.popc.ll",
+  "llvm.nvvm.prmt",
+  "llvm.nvvm.ptr.constant.to.gen",
+  "llvm.nvvm.ptr.gen.to.constant",
+  "llvm.nvvm.ptr.gen.to.global",
+  "llvm.nvvm.ptr.gen.to.local",
+  "llvm.nvvm.ptr.gen.to.param",
+  "llvm.nvvm.ptr.gen.to.shared",
+  "llvm.nvvm.ptr.global.to.gen",
+  "llvm.nvvm.ptr.local.to.gen",
+  "llvm.nvvm.ptr.shared.to.gen",
+  "llvm.nvvm.rcp.approx.ftz.d",
+  "llvm.nvvm.rcp.rm.d",
+  "llvm.nvvm.rcp.rm.f",
+  "llvm.nvvm.rcp.rm.ftz.f",
+  "llvm.nvvm.rcp.rn.d",
+  "llvm.nvvm.rcp.rn.f",
+  "llvm.nvvm.rcp.rn.ftz.f",
+  "llvm.nvvm.rcp.rp.d",
+  "llvm.nvvm.rcp.rp.f",
+  "llvm.nvvm.rcp.rp.ftz.f",
+  "llvm.nvvm.rcp.rz.d",
+  "llvm.nvvm.rcp.rz.f",
+  "llvm.nvvm.rcp.rz.ftz.f",
+  "llvm.nvvm.read.ptx.sreg.ctaid.x",
+  "llvm.nvvm.read.ptx.sreg.ctaid.y",
+  "llvm.nvvm.read.ptx.sreg.ctaid.z",
+  "llvm.nvvm.read.ptx.sreg.envreg0",
+  "llvm.nvvm.read.ptx.sreg.envreg1",
+  "llvm.nvvm.read.ptx.sreg.envreg10",
+  "llvm.nvvm.read.ptx.sreg.envreg11",
+  "llvm.nvvm.read.ptx.sreg.envreg12",
+  "llvm.nvvm.read.ptx.sreg.envreg13",
+  "llvm.nvvm.read.ptx.sreg.envreg14",
+  "llvm.nvvm.read.ptx.sreg.envreg15",
+  "llvm.nvvm.read.ptx.sreg.envreg16",
+  "llvm.nvvm.read.ptx.sreg.envreg17",
+  "llvm.nvvm.read.ptx.sreg.envreg18",
+  "llvm.nvvm.read.ptx.sreg.envreg19",
+  "llvm.nvvm.read.ptx.sreg.envreg2",
+  "llvm.nvvm.read.ptx.sreg.envreg20",
+  "llvm.nvvm.read.ptx.sreg.envreg21",
+  "llvm.nvvm.read.ptx.sreg.envreg22",
+  "llvm.nvvm.read.ptx.sreg.envreg23",
+  "llvm.nvvm.read.ptx.sreg.envreg24",
+  "llvm.nvvm.read.ptx.sreg.envreg25",
+  "llvm.nvvm.read.ptx.sreg.envreg26",
+  "llvm.nvvm.read.ptx.sreg.envreg27",
+  "llvm.nvvm.read.ptx.sreg.envreg28",
+  "llvm.nvvm.read.ptx.sreg.envreg29",
+  "llvm.nvvm.read.ptx.sreg.envreg3",
+  "llvm.nvvm.read.ptx.sreg.envreg30",
+  "llvm.nvvm.read.ptx.sreg.envreg31",
+  "llvm.nvvm.read.ptx.sreg.envreg4",
+  "llvm.nvvm.read.ptx.sreg.envreg5",
+  "llvm.nvvm.read.ptx.sreg.envreg6",
+  "llvm.nvvm.read.ptx.sreg.envreg7",
+  "llvm.nvvm.read.ptx.sreg.envreg8",
+  "llvm.nvvm.read.ptx.sreg.envreg9",
+  "llvm.nvvm.read.ptx.sreg.nctaid.x",
+  "llvm.nvvm.read.ptx.sreg.nctaid.y",
+  "llvm.nvvm.read.ptx.sreg.nctaid.z",
+  "llvm.nvvm.read.ptx.sreg.ntid.x",
+  "llvm.nvvm.read.ptx.sreg.ntid.y",
+  "llvm.nvvm.read.ptx.sreg.ntid.z",
+  "llvm.nvvm.read.ptx.sreg.tid.x",
+  "llvm.nvvm.read.ptx.sreg.tid.y",
+  "llvm.nvvm.read.ptx.sreg.tid.z",
+  "llvm.nvvm.read.ptx.sreg.warpsize",
+  "llvm.nvvm.reflect",
+  "llvm.nvvm.rotate.b32",
+  "llvm.nvvm.rotate.b64",
+  "llvm.nvvm.rotate.right.b64",
+  "llvm.nvvm.round.d",
+  "llvm.nvvm.round.f",
+  "llvm.nvvm.round.ftz.f",
+  "llvm.nvvm.rsqrt.approx.d",
+  "llvm.nvvm.rsqrt.approx.f",
+  "llvm.nvvm.rsqrt.approx.ftz.f",
+  "llvm.nvvm.sad.i",
+  "llvm.nvvm.sad.ui",
+  "llvm.nvvm.saturate.d",
+  "llvm.nvvm.saturate.f",
+  "llvm.nvvm.saturate.ftz.f",
+  "llvm.nvvm.sin.approx.f",
+  "llvm.nvvm.sin.approx.ftz.f",
+  "llvm.nvvm.sqrt.approx.f",
+  "llvm.nvvm.sqrt.approx.ftz.f",
+  "llvm.nvvm.sqrt.f",
+  "llvm.nvvm.sqrt.rm.d",
+  "llvm.nvvm.sqrt.rm.f",
+  "llvm.nvvm.sqrt.rm.ftz.f",
+  "llvm.nvvm.sqrt.rn.d",
+  "llvm.nvvm.sqrt.rn.f",
+  "llvm.nvvm.sqrt.rn.ftz.f",
+  "llvm.nvvm.sqrt.rp.d",
+  "llvm.nvvm.sqrt.rp.f",
+  "llvm.nvvm.sqrt.rp.ftz.f",
+  "llvm.nvvm.sqrt.rz.d",
+  "llvm.nvvm.sqrt.rz.f",
+  "llvm.nvvm.sqrt.rz.ftz.f",
+  "llvm.nvvm.suld.1d.array.i16.clamp",
+  "llvm.nvvm.suld.1d.array.i16.trap",
+  "llvm.nvvm.suld.1d.array.i16.zero",
+  "llvm.nvvm.suld.1d.array.i32.clamp",
+  "llvm.nvvm.suld.1d.array.i32.trap",
+  "llvm.nvvm.suld.1d.array.i32.zero",
+  "llvm.nvvm.suld.1d.array.i64.clamp",
+  "llvm.nvvm.suld.1d.array.i64.trap",
+  "llvm.nvvm.suld.1d.array.i64.zero",
+  "llvm.nvvm.suld.1d.array.i8.clamp",
+  "llvm.nvvm.suld.1d.array.i8.trap",
+  "llvm.nvvm.suld.1d.array.i8.zero",
+  "llvm.nvvm.suld.1d.array.v2i16.clamp",
+  "llvm.nvvm.suld.1d.array.v2i16.trap",
+  "llvm.nvvm.suld.1d.array.v2i16.zero",
+  "llvm.nvvm.suld.1d.array.v2i32.clamp",
+  "llvm.nvvm.suld.1d.array.v2i32.trap",
+  "llvm.nvvm.suld.1d.array.v2i32.zero",
+  "llvm.nvvm.suld.1d.array.v2i64.clamp",
+  "llvm.nvvm.suld.1d.array.v2i64.trap",
+  "llvm.nvvm.suld.1d.array.v2i64.zero",
+  "llvm.nvvm.suld.1d.array.v2i8.clamp",
+  "llvm.nvvm.suld.1d.array.v2i8.trap",
+  "llvm.nvvm.suld.1d.array.v2i8.zero",
+  "llvm.nvvm.suld.1d.array.v4i16.clamp",
+  "llvm.nvvm.suld.1d.array.v4i16.trap",
+  "llvm.nvvm.suld.1d.array.v4i16.zero",
+  "llvm.nvvm.suld.1d.array.v4i32.clamp",
+  "llvm.nvvm.suld.1d.array.v4i32.trap",
+  "llvm.nvvm.suld.1d.array.v4i32.zero",
+  "llvm.nvvm.suld.1d.array.v4i8.clamp",
+  "llvm.nvvm.suld.1d.array.v4i8.trap",
+  "llvm.nvvm.suld.1d.array.v4i8.zero",
+  "llvm.nvvm.suld.1d.i16.clamp",
+  "llvm.nvvm.suld.1d.i16.trap",
+  "llvm.nvvm.suld.1d.i16.zero",
+  "llvm.nvvm.suld.1d.i32.clamp",
+  "llvm.nvvm.suld.1d.i32.trap",
+  "llvm.nvvm.suld.1d.i32.zero",
+  "llvm.nvvm.suld.1d.i64.clamp",
+  "llvm.nvvm.suld.1d.i64.trap",
+  "llvm.nvvm.suld.1d.i64.zero",
+  "llvm.nvvm.suld.1d.i8.clamp",
+  "llvm.nvvm.suld.1d.i8.trap",
+  "llvm.nvvm.suld.1d.i8.zero",
+  "llvm.nvvm.suld.1d.v2i16.clamp",
+  "llvm.nvvm.suld.1d.v2i16.trap",
+  "llvm.nvvm.suld.1d.v2i16.zero",
+  "llvm.nvvm.suld.1d.v2i32.clamp",
+  "llvm.nvvm.suld.1d.v2i32.trap",
+  "llvm.nvvm.suld.1d.v2i32.zero",
+  "llvm.nvvm.suld.1d.v2i64.clamp",
+  "llvm.nvvm.suld.1d.v2i64.trap",
+  "llvm.nvvm.suld.1d.v2i64.zero",
+  "llvm.nvvm.suld.1d.v2i8.clamp",
+  "llvm.nvvm.suld.1d.v2i8.trap",
+  "llvm.nvvm.suld.1d.v2i8.zero",
+  "llvm.nvvm.suld.1d.v4i16.clamp",
+  "llvm.nvvm.suld.1d.v4i16.trap",
+  "llvm.nvvm.suld.1d.v4i16.zero",
+  "llvm.nvvm.suld.1d.v4i32.clamp",
+  "llvm.nvvm.suld.1d.v4i32.trap",
+  "llvm.nvvm.suld.1d.v4i32.zero",
+  "llvm.nvvm.suld.1d.v4i8.clamp",
+  "llvm.nvvm.suld.1d.v4i8.trap",
+  "llvm.nvvm.suld.1d.v4i8.zero",
+  "llvm.nvvm.suld.2d.array.i16.clamp",
+  "llvm.nvvm.suld.2d.array.i16.trap",
+  "llvm.nvvm.suld.2d.array.i16.zero",
+  "llvm.nvvm.suld.2d.array.i32.clamp",
+  "llvm.nvvm.suld.2d.array.i32.trap",
+  "llvm.nvvm.suld.2d.array.i32.zero",
+  "llvm.nvvm.suld.2d.array.i64.clamp",
+  "llvm.nvvm.suld.2d.array.i64.trap",
+  "llvm.nvvm.suld.2d.array.i64.zero",
+  "llvm.nvvm.suld.2d.array.i8.clamp",
+  "llvm.nvvm.suld.2d.array.i8.trap",
+  "llvm.nvvm.suld.2d.array.i8.zero",
+  "llvm.nvvm.suld.2d.array.v2i16.clamp",
+  "llvm.nvvm.suld.2d.array.v2i16.trap",
+  "llvm.nvvm.suld.2d.array.v2i16.zero",
+  "llvm.nvvm.suld.2d.array.v2i32.clamp",
+  "llvm.nvvm.suld.2d.array.v2i32.trap",
+  "llvm.nvvm.suld.2d.array.v2i32.zero",
+  "llvm.nvvm.suld.2d.array.v2i64.clamp",
+  "llvm.nvvm.suld.2d.array.v2i64.trap",
+  "llvm.nvvm.suld.2d.array.v2i64.zero",
+  "llvm.nvvm.suld.2d.array.v2i8.clamp",
+  "llvm.nvvm.suld.2d.array.v2i8.trap",
+  "llvm.nvvm.suld.2d.array.v2i8.zero",
+  "llvm.nvvm.suld.2d.array.v4i16.clamp",
+  "llvm.nvvm.suld.2d.array.v4i16.trap",
+  "llvm.nvvm.suld.2d.array.v4i16.zero",
+  "llvm.nvvm.suld.2d.array.v4i32.clamp",
+  "llvm.nvvm.suld.2d.array.v4i32.trap",
+  "llvm.nvvm.suld.2d.array.v4i32.zero",
+  "llvm.nvvm.suld.2d.array.v4i8.clamp",
+  "llvm.nvvm.suld.2d.array.v4i8.trap",
+  "llvm.nvvm.suld.2d.array.v4i8.zero",
+  "llvm.nvvm.suld.2d.i16.clamp",
+  "llvm.nvvm.suld.2d.i16.trap",
+  "llvm.nvvm.suld.2d.i16.zero",
+  "llvm.nvvm.suld.2d.i32.clamp",
+  "llvm.nvvm.suld.2d.i32.trap",
+  "llvm.nvvm.suld.2d.i32.zero",
+  "llvm.nvvm.suld.2d.i64.clamp",
+  "llvm.nvvm.suld.2d.i64.trap",
+  "llvm.nvvm.suld.2d.i64.zero",
+  "llvm.nvvm.suld.2d.i8.clamp",
+  "llvm.nvvm.suld.2d.i8.trap",
+  "llvm.nvvm.suld.2d.i8.zero",
+  "llvm.nvvm.suld.2d.v2i16.clamp",
+  "llvm.nvvm.suld.2d.v2i16.trap",
+  "llvm.nvvm.suld.2d.v2i16.zero",
+  "llvm.nvvm.suld.2d.v2i32.clamp",
+  "llvm.nvvm.suld.2d.v2i32.trap",
+  "llvm.nvvm.suld.2d.v2i32.zero",
+  "llvm.nvvm.suld.2d.v2i64.clamp",
+  "llvm.nvvm.suld.2d.v2i64.trap",
+  "llvm.nvvm.suld.2d.v2i64.zero",
+  "llvm.nvvm.suld.2d.v2i8.clamp",
+  "llvm.nvvm.suld.2d.v2i8.trap",
+  "llvm.nvvm.suld.2d.v2i8.zero",
+  "llvm.nvvm.suld.2d.v4i16.clamp",
+  "llvm.nvvm.suld.2d.v4i16.trap",
+  "llvm.nvvm.suld.2d.v4i16.zero",
+  "llvm.nvvm.suld.2d.v4i32.clamp",
+  "llvm.nvvm.suld.2d.v4i32.trap",
+  "llvm.nvvm.suld.2d.v4i32.zero",
+  "llvm.nvvm.suld.2d.v4i8.clamp",
+  "llvm.nvvm.suld.2d.v4i8.trap",
+  "llvm.nvvm.suld.2d.v4i8.zero",
+  "llvm.nvvm.suld.3d.i16.clamp",
+  "llvm.nvvm.suld.3d.i16.trap",
+  "llvm.nvvm.suld.3d.i16.zero",
+  "llvm.nvvm.suld.3d.i32.clamp",
+  "llvm.nvvm.suld.3d.i32.trap",
+  "llvm.nvvm.suld.3d.i32.zero",
+  "llvm.nvvm.suld.3d.i64.clamp",
+  "llvm.nvvm.suld.3d.i64.trap",
+  "llvm.nvvm.suld.3d.i64.zero",
+  "llvm.nvvm.suld.3d.i8.clamp",
+  "llvm.nvvm.suld.3d.i8.trap",
+  "llvm.nvvm.suld.3d.i8.zero",
+  "llvm.nvvm.suld.3d.v2i16.clamp",
+  "llvm.nvvm.suld.3d.v2i16.trap",
+  "llvm.nvvm.suld.3d.v2i16.zero",
+  "llvm.nvvm.suld.3d.v2i32.clamp",
+  "llvm.nvvm.suld.3d.v2i32.trap",
+  "llvm.nvvm.suld.3d.v2i32.zero",
+  "llvm.nvvm.suld.3d.v2i64.clamp",
+  "llvm.nvvm.suld.3d.v2i64.trap",
+  "llvm.nvvm.suld.3d.v2i64.zero",
+  "llvm.nvvm.suld.3d.v2i8.clamp",
+  "llvm.nvvm.suld.3d.v2i8.trap",
+  "llvm.nvvm.suld.3d.v2i8.zero",
+  "llvm.nvvm.suld.3d.v4i16.clamp",
+  "llvm.nvvm.suld.3d.v4i16.trap",
+  "llvm.nvvm.suld.3d.v4i16.zero",
+  "llvm.nvvm.suld.3d.v4i32.clamp",
+  "llvm.nvvm.suld.3d.v4i32.trap",
+  "llvm.nvvm.suld.3d.v4i32.zero",
+  "llvm.nvvm.suld.3d.v4i8.clamp",
+  "llvm.nvvm.suld.3d.v4i8.trap",
+  "llvm.nvvm.suld.3d.v4i8.zero",
+  "llvm.nvvm.suq.array.size",
+  "llvm.nvvm.suq.channel.data.type",
+  "llvm.nvvm.suq.channel.order",
+  "llvm.nvvm.suq.depth",
+  "llvm.nvvm.suq.height",
+  "llvm.nvvm.suq.width",
+  "llvm.nvvm.sust.b.1d.array.i16.clamp",
+  "llvm.nvvm.sust.b.1d.array.i16.trap",
+  "llvm.nvvm.sust.b.1d.array.i16.zero",
+  "llvm.nvvm.sust.b.1d.array.i32.clamp",
+  "llvm.nvvm.sust.b.1d.array.i32.trap",
+  "llvm.nvvm.sust.b.1d.array.i32.zero",
+  "llvm.nvvm.sust.b.1d.array.i64.clamp",
+  "llvm.nvvm.sust.b.1d.array.i64.trap",
+  "llvm.nvvm.sust.b.1d.array.i64.zero",
+  "llvm.nvvm.sust.b.1d.array.i8.clamp",
+  "llvm.nvvm.sust.b.1d.array.i8.trap",
+  "llvm.nvvm.sust.b.1d.array.i8.zero",
+  "llvm.nvvm.sust.b.1d.array.v2i16.clamp",
+  "llvm.nvvm.sust.b.1d.array.v2i16.trap",
+  "llvm.nvvm.sust.b.1d.array.v2i16.zero",
+  "llvm.nvvm.sust.b.1d.array.v2i32.clamp",
+  "llvm.nvvm.sust.b.1d.array.v2i32.trap",
+  "llvm.nvvm.sust.b.1d.array.v2i32.zero",
+  "llvm.nvvm.sust.b.1d.array.v2i64.clamp",
+  "llvm.nvvm.sust.b.1d.array.v2i64.trap",
+  "llvm.nvvm.sust.b.1d.array.v2i64.zero",
+  "llvm.nvvm.sust.b.1d.array.v2i8.clamp",
+  "llvm.nvvm.sust.b.1d.array.v2i8.trap",
+  "llvm.nvvm.sust.b.1d.array.v2i8.zero",
+  "llvm.nvvm.sust.b.1d.array.v4i16.clamp",
+  "llvm.nvvm.sust.b.1d.array.v4i16.trap",
+  "llvm.nvvm.sust.b.1d.array.v4i16.zero",
+  "llvm.nvvm.sust.b.1d.array.v4i32.clamp",
+  "llvm.nvvm.sust.b.1d.array.v4i32.trap",
+  "llvm.nvvm.sust.b.1d.array.v4i32.zero",
+  "llvm.nvvm.sust.b.1d.array.v4i8.clamp",
+  "llvm.nvvm.sust.b.1d.array.v4i8.trap",
+  "llvm.nvvm.sust.b.1d.array.v4i8.zero",
+  "llvm.nvvm.sust.b.1d.i16.clamp",
+  "llvm.nvvm.sust.b.1d.i16.trap",
+  "llvm.nvvm.sust.b.1d.i16.zero",
+  "llvm.nvvm.sust.b.1d.i32.clamp",
+  "llvm.nvvm.sust.b.1d.i32.trap",
+  "llvm.nvvm.sust.b.1d.i32.zero",
+  "llvm.nvvm.sust.b.1d.i64.clamp",
+  "llvm.nvvm.sust.b.1d.i64.trap",
+  "llvm.nvvm.sust.b.1d.i64.zero",
+  "llvm.nvvm.sust.b.1d.i8.clamp",
+  "llvm.nvvm.sust.b.1d.i8.trap",
+  "llvm.nvvm.sust.b.1d.i8.zero",
+  "llvm.nvvm.sust.b.1d.v2i16.clamp",
+  "llvm.nvvm.sust.b.1d.v2i16.trap",
+  "llvm.nvvm.sust.b.1d.v2i16.zero",
+  "llvm.nvvm.sust.b.1d.v2i32.clamp",
+  "llvm.nvvm.sust.b.1d.v2i32.trap",
+  "llvm.nvvm.sust.b.1d.v2i32.zero",
+  "llvm.nvvm.sust.b.1d.v2i64.clamp",
+  "llvm.nvvm.sust.b.1d.v2i64.trap",
+  "llvm.nvvm.sust.b.1d.v2i64.zero",
+  "llvm.nvvm.sust.b.1d.v2i8.clamp",
+  "llvm.nvvm.sust.b.1d.v2i8.trap",
+  "llvm.nvvm.sust.b.1d.v2i8.zero",
+  "llvm.nvvm.sust.b.1d.v4i16.clamp",
+  "llvm.nvvm.sust.b.1d.v4i16.trap",
+  "llvm.nvvm.sust.b.1d.v4i16.zero",
+  "llvm.nvvm.sust.b.1d.v4i32.clamp",
+  "llvm.nvvm.sust.b.1d.v4i32.trap",
+  "llvm.nvvm.sust.b.1d.v4i32.zero",
+  "llvm.nvvm.sust.b.1d.v4i8.clamp",
+  "llvm.nvvm.sust.b.1d.v4i8.trap",
+  "llvm.nvvm.sust.b.1d.v4i8.zero",
+  "llvm.nvvm.sust.b.2d.array.i16.clamp",
+  "llvm.nvvm.sust.b.2d.array.i16.trap",
+  "llvm.nvvm.sust.b.2d.array.i16.zero",
+  "llvm.nvvm.sust.b.2d.array.i32.clamp",
+  "llvm.nvvm.sust.b.2d.array.i32.trap",
+  "llvm.nvvm.sust.b.2d.array.i32.zero",
+  "llvm.nvvm.sust.b.2d.array.i64.clamp",
+  "llvm.nvvm.sust.b.2d.array.i64.trap",
+  "llvm.nvvm.sust.b.2d.array.i64.zero",
+  "llvm.nvvm.sust.b.2d.array.i8.clamp",
+  "llvm.nvvm.sust.b.2d.array.i8.trap",
+  "llvm.nvvm.sust.b.2d.array.i8.zero",
+  "llvm.nvvm.sust.b.2d.array.v2i16.clamp",
+  "llvm.nvvm.sust.b.2d.array.v2i16.trap",
+  "llvm.nvvm.sust.b.2d.array.v2i16.zero",
+  "llvm.nvvm.sust.b.2d.array.v2i32.clamp",
+  "llvm.nvvm.sust.b.2d.array.v2i32.trap",
+  "llvm.nvvm.sust.b.2d.array.v2i32.zero",
+  "llvm.nvvm.sust.b.2d.array.v2i64.clamp",
+  "llvm.nvvm.sust.b.2d.array.v2i64.trap",
+  "llvm.nvvm.sust.b.2d.array.v2i64.zero",
+  "llvm.nvvm.sust.b.2d.array.v2i8.clamp",
+  "llvm.nvvm.sust.b.2d.array.v2i8.trap",
+  "llvm.nvvm.sust.b.2d.array.v2i8.zero",
+  "llvm.nvvm.sust.b.2d.array.v4i16.clamp",
+  "llvm.nvvm.sust.b.2d.array.v4i16.trap",
+  "llvm.nvvm.sust.b.2d.array.v4i16.zero",
+  "llvm.nvvm.sust.b.2d.array.v4i32.clamp",
+  "llvm.nvvm.sust.b.2d.array.v4i32.trap",
+  "llvm.nvvm.sust.b.2d.array.v4i32.zero",
+  "llvm.nvvm.sust.b.2d.array.v4i8.clamp",
+  "llvm.nvvm.sust.b.2d.array.v4i8.trap",
+  "llvm.nvvm.sust.b.2d.array.v4i8.zero",
+  "llvm.nvvm.sust.b.2d.i16.clamp",
+  "llvm.nvvm.sust.b.2d.i16.trap",
+  "llvm.nvvm.sust.b.2d.i16.zero",
+  "llvm.nvvm.sust.b.2d.i32.clamp",
+  "llvm.nvvm.sust.b.2d.i32.trap",
+  "llvm.nvvm.sust.b.2d.i32.zero",
+  "llvm.nvvm.sust.b.2d.i64.clamp",
+  "llvm.nvvm.sust.b.2d.i64.trap",
+  "llvm.nvvm.sust.b.2d.i64.zero",
+  "llvm.nvvm.sust.b.2d.i8.clamp",
+  "llvm.nvvm.sust.b.2d.i8.trap",
+  "llvm.nvvm.sust.b.2d.i8.zero",
+  "llvm.nvvm.sust.b.2d.v2i16.clamp",
+  "llvm.nvvm.sust.b.2d.v2i16.trap",
+  "llvm.nvvm.sust.b.2d.v2i16.zero",
+  "llvm.nvvm.sust.b.2d.v2i32.clamp",
+  "llvm.nvvm.sust.b.2d.v2i32.trap",
+  "llvm.nvvm.sust.b.2d.v2i32.zero",
+  "llvm.nvvm.sust.b.2d.v2i64.clamp",
+  "llvm.nvvm.sust.b.2d.v2i64.trap",
+  "llvm.nvvm.sust.b.2d.v2i64.zero",
+  "llvm.nvvm.sust.b.2d.v2i8.clamp",
+  "llvm.nvvm.sust.b.2d.v2i8.trap",
+  "llvm.nvvm.sust.b.2d.v2i8.zero",
+  "llvm.nvvm.sust.b.2d.v4i16.clamp",
+  "llvm.nvvm.sust.b.2d.v4i16.trap",
+  "llvm.nvvm.sust.b.2d.v4i16.zero",
+  "llvm.nvvm.sust.b.2d.v4i32.clamp",
+  "llvm.nvvm.sust.b.2d.v4i32.trap",
+  "llvm.nvvm.sust.b.2d.v4i32.zero",
+  "llvm.nvvm.sust.b.2d.v4i8.clamp",
+  "llvm.nvvm.sust.b.2d.v4i8.trap",
+  "llvm.nvvm.sust.b.2d.v4i8.zero",
+  "llvm.nvvm.sust.b.3d.i16.clamp",
+  "llvm.nvvm.sust.b.3d.i16.trap",
+  "llvm.nvvm.sust.b.3d.i16.zero",
+  "llvm.nvvm.sust.b.3d.i32.clamp",
+  "llvm.nvvm.sust.b.3d.i32.trap",
+  "llvm.nvvm.sust.b.3d.i32.zero",
+  "llvm.nvvm.sust.b.3d.i64.clamp",
+  "llvm.nvvm.sust.b.3d.i64.trap",
+  "llvm.nvvm.sust.b.3d.i64.zero",
+  "llvm.nvvm.sust.b.3d.i8.clamp",
+  "llvm.nvvm.sust.b.3d.i8.trap",
+  "llvm.nvvm.sust.b.3d.i8.zero",
+  "llvm.nvvm.sust.b.3d.v2i16.clamp",
+  "llvm.nvvm.sust.b.3d.v2i16.trap",
+  "llvm.nvvm.sust.b.3d.v2i16.zero",
+  "llvm.nvvm.sust.b.3d.v2i32.clamp",
+  "llvm.nvvm.sust.b.3d.v2i32.trap",
+  "llvm.nvvm.sust.b.3d.v2i32.zero",
+  "llvm.nvvm.sust.b.3d.v2i64.clamp",
+  "llvm.nvvm.sust.b.3d.v2i64.trap",
+  "llvm.nvvm.sust.b.3d.v2i64.zero",
+  "llvm.nvvm.sust.b.3d.v2i8.clamp",
+  "llvm.nvvm.sust.b.3d.v2i8.trap",
+  "llvm.nvvm.sust.b.3d.v2i8.zero",
+  "llvm.nvvm.sust.b.3d.v4i16.clamp",
+  "llvm.nvvm.sust.b.3d.v4i16.trap",
+  "llvm.nvvm.sust.b.3d.v4i16.zero",
+  "llvm.nvvm.sust.b.3d.v4i32.clamp",
+  "llvm.nvvm.sust.b.3d.v4i32.trap",
+  "llvm.nvvm.sust.b.3d.v4i32.zero",
+  "llvm.nvvm.sust.b.3d.v4i8.clamp",
+  "llvm.nvvm.sust.b.3d.v4i8.trap",
+  "llvm.nvvm.sust.b.3d.v4i8.zero",
+  "llvm.nvvm.sust.p.1d.array.i16.trap",
+  "llvm.nvvm.sust.p.1d.array.i32.trap",
+  "llvm.nvvm.sust.p.1d.array.i8.trap",
+  "llvm.nvvm.sust.p.1d.array.v2i16.trap",
+  "llvm.nvvm.sust.p.1d.array.v2i32.trap",
+  "llvm.nvvm.sust.p.1d.array.v2i8.trap",
+  "llvm.nvvm.sust.p.1d.array.v4i16.trap",
+  "llvm.nvvm.sust.p.1d.array.v4i32.trap",
+  "llvm.nvvm.sust.p.1d.array.v4i8.trap",
+  "llvm.nvvm.sust.p.1d.i16.trap",
+  "llvm.nvvm.sust.p.1d.i32.trap",
+  "llvm.nvvm.sust.p.1d.i8.trap",
+  "llvm.nvvm.sust.p.1d.v2i16.trap",
+  "llvm.nvvm.sust.p.1d.v2i32.trap",
+  "llvm.nvvm.sust.p.1d.v2i8.trap",
+  "llvm.nvvm.sust.p.1d.v4i16.trap",
+  "llvm.nvvm.sust.p.1d.v4i32.trap",
+  "llvm.nvvm.sust.p.1d.v4i8.trap",
+  "llvm.nvvm.sust.p.2d.array.i16.trap",
+  "llvm.nvvm.sust.p.2d.array.i32.trap",
+  "llvm.nvvm.sust.p.2d.array.i8.trap",
+  "llvm.nvvm.sust.p.2d.array.v2i16.trap",
+  "llvm.nvvm.sust.p.2d.array.v2i32.trap",
+  "llvm.nvvm.sust.p.2d.array.v2i8.trap",
+  "llvm.nvvm.sust.p.2d.array.v4i16.trap",
+  "llvm.nvvm.sust.p.2d.array.v4i32.trap",
+  "llvm.nvvm.sust.p.2d.array.v4i8.trap",
+  "llvm.nvvm.sust.p.2d.i16.trap",
+  "llvm.nvvm.sust.p.2d.i32.trap",
+  "llvm.nvvm.sust.p.2d.i8.trap",
+  "llvm.nvvm.sust.p.2d.v2i16.trap",
+  "llvm.nvvm.sust.p.2d.v2i32.trap",
+  "llvm.nvvm.sust.p.2d.v2i8.trap",
+  "llvm.nvvm.sust.p.2d.v4i16.trap",
+  "llvm.nvvm.sust.p.2d.v4i32.trap",
+  "llvm.nvvm.sust.p.2d.v4i8.trap",
+  "llvm.nvvm.sust.p.3d.i16.trap",
+  "llvm.nvvm.sust.p.3d.i32.trap",
+  "llvm.nvvm.sust.p.3d.i8.trap",
+  "llvm.nvvm.sust.p.3d.v2i16.trap",
+  "llvm.nvvm.sust.p.3d.v2i32.trap",
+  "llvm.nvvm.sust.p.3d.v2i8.trap",
+  "llvm.nvvm.sust.p.3d.v4i16.trap",
+  "llvm.nvvm.sust.p.3d.v4i32.trap",
+  "llvm.nvvm.sust.p.3d.v4i8.trap",
+  "llvm.nvvm.swap.lo.hi.b64",
+  "llvm.nvvm.tex.1d.array.grad.v4f32.f32",
+  "llvm.nvvm.tex.1d.array.grad.v4s32.f32",
+  "llvm.nvvm.tex.1d.array.grad.v4u32.f32",
+  "llvm.nvvm.tex.1d.array.level.v4f32.f32",
+  "llvm.nvvm.tex.1d.array.level.v4s32.f32",
+  "llvm.nvvm.tex.1d.array.level.v4u32.f32",
+  "llvm.nvvm.tex.1d.array.v4f32.f32",
+  "llvm.nvvm.tex.1d.array.v4f32.s32",
+  "llvm.nvvm.tex.1d.array.v4s32.f32",
+  "llvm.nvvm.tex.1d.array.v4s32.s32",
+  "llvm.nvvm.tex.1d.array.v4u32.f32",
+  "llvm.nvvm.tex.1d.array.v4u32.s32",
+  "llvm.nvvm.tex.1d.grad.v4f32.f32",
+  "llvm.nvvm.tex.1d.grad.v4s32.f32",
+  "llvm.nvvm.tex.1d.grad.v4u32.f32",
+  "llvm.nvvm.tex.1d.level.v4f32.f32",
+  "llvm.nvvm.tex.1d.level.v4s32.f32",
+  "llvm.nvvm.tex.1d.level.v4u32.f32",
+  "llvm.nvvm.tex.1d.v4f32.f32",
+  "llvm.nvvm.tex.1d.v4f32.s32",
+  "llvm.nvvm.tex.1d.v4s32.f32",
+  "llvm.nvvm.tex.1d.v4s32.s32",
+  "llvm.nvvm.tex.1d.v4u32.f32",
+  "llvm.nvvm.tex.1d.v4u32.s32",
+  "llvm.nvvm.tex.2d.array.grad.v4f32.f32",
+  "llvm.nvvm.tex.2d.array.grad.v4s32.f32",
+  "llvm.nvvm.tex.2d.array.grad.v4u32.f32",
+  "llvm.nvvm.tex.2d.array.level.v4f32.f32",
+  "llvm.nvvm.tex.2d.array.level.v4s32.f32",
+  "llvm.nvvm.tex.2d.array.level.v4u32.f32",
+  "llvm.nvvm.tex.2d.array.v4f32.f32",
+  "llvm.nvvm.tex.2d.array.v4f32.s32",
+  "llvm.nvvm.tex.2d.array.v4s32.f32",
+  "llvm.nvvm.tex.2d.array.v4s32.s32",
+  "llvm.nvvm.tex.2d.array.v4u32.f32",
+  "llvm.nvvm.tex.2d.array.v4u32.s32",
+  "llvm.nvvm.tex.2d.grad.v4f32.f32",
+  "llvm.nvvm.tex.2d.grad.v4s32.f32",
+  "llvm.nvvm.tex.2d.grad.v4u32.f32",
+  "llvm.nvvm.tex.2d.level.v4f32.f32",
+  "llvm.nvvm.tex.2d.level.v4s32.f32",
+  "llvm.nvvm.tex.2d.level.v4u32.f32",
+  "llvm.nvvm.tex.2d.v4f32.f32",
+  "llvm.nvvm.tex.2d.v4f32.s32",
+  "llvm.nvvm.tex.2d.v4s32.f32",
+  "llvm.nvvm.tex.2d.v4s32.s32",
+  "llvm.nvvm.tex.2d.v4u32.f32",
+  "llvm.nvvm.tex.2d.v4u32.s32",
+  "llvm.nvvm.tex.3d.grad.v4f32.f32",
+  "llvm.nvvm.tex.3d.grad.v4s32.f32",
+  "llvm.nvvm.tex.3d.grad.v4u32.f32",
+  "llvm.nvvm.tex.3d.level.v4f32.f32",
+  "llvm.nvvm.tex.3d.level.v4s32.f32",
+  "llvm.nvvm.tex.3d.level.v4u32.f32",
+  "llvm.nvvm.tex.3d.v4f32.f32",
+  "llvm.nvvm.tex.3d.v4f32.s32",
+  "llvm.nvvm.tex.3d.v4s32.f32",
+  "llvm.nvvm.tex.3d.v4s32.s32",
+  "llvm.nvvm.tex.3d.v4u32.f32",
+  "llvm.nvvm.tex.3d.v4u32.s32",
+  "llvm.nvvm.tex.cube.array.level.v4f32.f32",
+  "llvm.nvvm.tex.cube.array.level.v4s32.f32",
+  "llvm.nvvm.tex.cube.array.level.v4u32.f32",
+  "llvm.nvvm.tex.cube.array.v4f32.f32",
+  "llvm.nvvm.tex.cube.array.v4s32.f32",
+  "llvm.nvvm.tex.cube.array.v4u32.f32",
+  "llvm.nvvm.tex.cube.level.v4f32.f32",
+  "llvm.nvvm.tex.cube.level.v4s32.f32",
+  "llvm.nvvm.tex.cube.level.v4u32.f32",
+  "llvm.nvvm.tex.cube.v4f32.f32",
+  "llvm.nvvm.tex.cube.v4s32.f32",
+  "llvm.nvvm.tex.cube.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.array.grad.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.array.grad.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.array.grad.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.array.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.array.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.array.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.array.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.array.v4f32.s32",
+  "llvm.nvvm.tex.unified.1d.array.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.array.v4s32.s32",
+  "llvm.nvvm.tex.unified.1d.array.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.array.v4u32.s32",
+  "llvm.nvvm.tex.unified.1d.grad.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.grad.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.grad.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.v4f32.f32",
+  "llvm.nvvm.tex.unified.1d.v4f32.s32",
+  "llvm.nvvm.tex.unified.1d.v4s32.f32",
+  "llvm.nvvm.tex.unified.1d.v4s32.s32",
+  "llvm.nvvm.tex.unified.1d.v4u32.f32",
+  "llvm.nvvm.tex.unified.1d.v4u32.s32",
+  "llvm.nvvm.tex.unified.2d.array.grad.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.array.grad.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.array.grad.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.array.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.array.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.array.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.array.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.array.v4f32.s32",
+  "llvm.nvvm.tex.unified.2d.array.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.array.v4s32.s32",
+  "llvm.nvvm.tex.unified.2d.array.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.array.v4u32.s32",
+  "llvm.nvvm.tex.unified.2d.grad.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.grad.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.grad.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.v4f32.f32",
+  "llvm.nvvm.tex.unified.2d.v4f32.s32",
+  "llvm.nvvm.tex.unified.2d.v4s32.f32",
+  "llvm.nvvm.tex.unified.2d.v4s32.s32",
+  "llvm.nvvm.tex.unified.2d.v4u32.f32",
+  "llvm.nvvm.tex.unified.2d.v4u32.s32",
+  "llvm.nvvm.tex.unified.3d.grad.v4f32.f32",
+  "llvm.nvvm.tex.unified.3d.grad.v4s32.f32",
+  "llvm.nvvm.tex.unified.3d.grad.v4u32.f32",
+  "llvm.nvvm.tex.unified.3d.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.3d.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.3d.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.3d.v4f32.f32",
+  "llvm.nvvm.tex.unified.3d.v4f32.s32",
+  "llvm.nvvm.tex.unified.3d.v4s32.f32",
+  "llvm.nvvm.tex.unified.3d.v4s32.s32",
+  "llvm.nvvm.tex.unified.3d.v4u32.f32",
+  "llvm.nvvm.tex.unified.3d.v4u32.s32",
+  "llvm.nvvm.tex.unified.cube.array.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.cube.array.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.cube.array.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.cube.array.v4f32.f32",
+  "llvm.nvvm.tex.unified.cube.array.v4s32.f32",
+  "llvm.nvvm.tex.unified.cube.array.v4u32.f32",
+  "llvm.nvvm.tex.unified.cube.level.v4f32.f32",
+  "llvm.nvvm.tex.unified.cube.level.v4s32.f32",
+  "llvm.nvvm.tex.unified.cube.level.v4u32.f32",
+  "llvm.nvvm.tex.unified.cube.v4f32.f32",
+  "llvm.nvvm.tex.unified.cube.v4s32.f32",
+  "llvm.nvvm.tex.unified.cube.v4u32.f32",
+  "llvm.nvvm.texsurf.handle",
+  "llvm.nvvm.texsurf.handle.internal",
+  "llvm.nvvm.tld4.a.2d.v4f32.f32",
+  "llvm.nvvm.tld4.a.2d.v4s32.f32",
+  "llvm.nvvm.tld4.a.2d.v4u32.f32",
+  "llvm.nvvm.tld4.b.2d.v4f32.f32",
+  "llvm.nvvm.tld4.b.2d.v4s32.f32",
+  "llvm.nvvm.tld4.b.2d.v4u32.f32",
+  "llvm.nvvm.tld4.g.2d.v4f32.f32",
+  "llvm.nvvm.tld4.g.2d.v4s32.f32",
+  "llvm.nvvm.tld4.g.2d.v4u32.f32",
+  "llvm.nvvm.tld4.r.2d.v4f32.f32",
+  "llvm.nvvm.tld4.r.2d.v4s32.f32",
+  "llvm.nvvm.tld4.r.2d.v4u32.f32",
+  "llvm.nvvm.tld4.unified.a.2d.v4f32.f32",
+  "llvm.nvvm.tld4.unified.a.2d.v4s32.f32",
+  "llvm.nvvm.tld4.unified.a.2d.v4u32.f32",
+  "llvm.nvvm.tld4.unified.b.2d.v4f32.f32",
+  "llvm.nvvm.tld4.unified.b.2d.v4s32.f32",
+  "llvm.nvvm.tld4.unified.b.2d.v4u32.f32",
+  "llvm.nvvm.tld4.unified.g.2d.v4f32.f32",
+  "llvm.nvvm.tld4.unified.g.2d.v4s32.f32",
+  "llvm.nvvm.tld4.unified.g.2d.v4u32.f32",
+  "llvm.nvvm.tld4.unified.r.2d.v4f32.f32",
+  "llvm.nvvm.tld4.unified.r.2d.v4s32.f32",
+  "llvm.nvvm.tld4.unified.r.2d.v4u32.f32",
+  "llvm.nvvm.trunc.d",
+  "llvm.nvvm.trunc.f",
+  "llvm.nvvm.trunc.ftz.f",
+  "llvm.nvvm.txq.array.size",
+  "llvm.nvvm.txq.channel.data.type",
+  "llvm.nvvm.txq.channel.order",
+  "llvm.nvvm.txq.depth",
+  "llvm.nvvm.txq.height",
+  "llvm.nvvm.txq.num.mipmap.levels",
+  "llvm.nvvm.txq.num.samples",
+  "llvm.nvvm.txq.width",
+  "llvm.nvvm.ui2d.rm",
+  "llvm.nvvm.ui2d.rn",
+  "llvm.nvvm.ui2d.rp",
+  "llvm.nvvm.ui2d.rz",
+  "llvm.nvvm.ui2f.rm",
+  "llvm.nvvm.ui2f.rn",
+  "llvm.nvvm.ui2f.rp",
+  "llvm.nvvm.ui2f.rz",
+  "llvm.nvvm.ull2d.rm",
+  "llvm.nvvm.ull2d.rn",
+  "llvm.nvvm.ull2d.rp",
+  "llvm.nvvm.ull2d.rz",
+  "llvm.nvvm.ull2f.rm",
+  "llvm.nvvm.ull2f.rn",
+  "llvm.nvvm.ull2f.rp",
+  "llvm.nvvm.ull2f.rz",
+  "llvm.objectsize",
+  "llvm.pcmarker",
+  "llvm.pow",
+  "llvm.powi",
+  "llvm.ppc.altivec.dss",
+  "llvm.ppc.altivec.dssall",
+  "llvm.ppc.altivec.dst",
+  "llvm.ppc.altivec.dstst",
+  "llvm.ppc.altivec.dststt",
+  "llvm.ppc.altivec.dstt",
+  "llvm.ppc.altivec.lvebx",
+  "llvm.ppc.altivec.lvehx",
+  "llvm.ppc.altivec.lvewx",
+  "llvm.ppc.altivec.lvsl",
+  "llvm.ppc.altivec.lvsr",
+  "llvm.ppc.altivec.lvx",
+  "llvm.ppc.altivec.lvxl",
+  "llvm.ppc.altivec.mfvscr",
+  "llvm.ppc.altivec.mtvscr",
+  "llvm.ppc.altivec.stvebx",
+  "llvm.ppc.altivec.stvehx",
+  "llvm.ppc.altivec.stvewx",
+  "llvm.ppc.altivec.stvx",
+  "llvm.ppc.altivec.stvxl",
+  "llvm.ppc.altivec.vaddcuw",
+  "llvm.ppc.altivec.vaddsbs",
+  "llvm.ppc.altivec.vaddshs",
+  "llvm.ppc.altivec.vaddsws",
+  "llvm.ppc.altivec.vaddubs",
+  "llvm.ppc.altivec.vadduhs",
+  "llvm.ppc.altivec.vadduws",
+  "llvm.ppc.altivec.vavgsb",
+  "llvm.ppc.altivec.vavgsh",
+  "llvm.ppc.altivec.vavgsw",
+  "llvm.ppc.altivec.vavgub",
+  "llvm.ppc.altivec.vavguh",
+  "llvm.ppc.altivec.vavguw",
+  "llvm.ppc.altivec.vcfsx",
+  "llvm.ppc.altivec.vcfux",
+  "llvm.ppc.altivec.vcmpbfp",
+  "llvm.ppc.altivec.vcmpbfp.p",
+  "llvm.ppc.altivec.vcmpeqfp",
+  "llvm.ppc.altivec.vcmpeqfp.p",
+  "llvm.ppc.altivec.vcmpequb",
+  "llvm.ppc.altivec.vcmpequb.p",
+  "llvm.ppc.altivec.vcmpequh",
+  "llvm.ppc.altivec.vcmpequh.p",
+  "llvm.ppc.altivec.vcmpequw",
+  "llvm.ppc.altivec.vcmpequw.p",
+  "llvm.ppc.altivec.vcmpgefp",
+  "llvm.ppc.altivec.vcmpgefp.p",
+  "llvm.ppc.altivec.vcmpgtfp",
+  "llvm.ppc.altivec.vcmpgtfp.p",
+  "llvm.ppc.altivec.vcmpgtsb",
+  "llvm.ppc.altivec.vcmpgtsb.p",
+  "llvm.ppc.altivec.vcmpgtsh",
+  "llvm.ppc.altivec.vcmpgtsh.p",
+  "llvm.ppc.altivec.vcmpgtsw",
+  "llvm.ppc.altivec.vcmpgtsw.p",
+  "llvm.ppc.altivec.vcmpgtub",
+  "llvm.ppc.altivec.vcmpgtub.p",
+  "llvm.ppc.altivec.vcmpgtuh",
+  "llvm.ppc.altivec.vcmpgtuh.p",
+  "llvm.ppc.altivec.vcmpgtuw",
+  "llvm.ppc.altivec.vcmpgtuw.p",
+  "llvm.ppc.altivec.vctsxs",
+  "llvm.ppc.altivec.vctuxs",
+  "llvm.ppc.altivec.vexptefp",
+  "llvm.ppc.altivec.vlogefp",
+  "llvm.ppc.altivec.vmaddfp",
+  "llvm.ppc.altivec.vmaxfp",
+  "llvm.ppc.altivec.vmaxsb",
+  "llvm.ppc.altivec.vmaxsh",
+  "llvm.ppc.altivec.vmaxsw",
+  "llvm.ppc.altivec.vmaxub",
+  "llvm.ppc.altivec.vmaxuh",
+  "llvm.ppc.altivec.vmaxuw",
+  "llvm.ppc.altivec.vmhaddshs",
+  "llvm.ppc.altivec.vmhraddshs",
+  "llvm.ppc.altivec.vminfp",
+  "llvm.ppc.altivec.vminsb",
+  "llvm.ppc.altivec.vminsh",
+  "llvm.ppc.altivec.vminsw",
+  "llvm.ppc.altivec.vminub",
+  "llvm.ppc.altivec.vminuh",
+  "llvm.ppc.altivec.vminuw",
+  "llvm.ppc.altivec.vmladduhm",
+  "llvm.ppc.altivec.vmsummbm",
+  "llvm.ppc.altivec.vmsumshm",
+  "llvm.ppc.altivec.vmsumshs",
+  "llvm.ppc.altivec.vmsumubm",
+  "llvm.ppc.altivec.vmsumuhm",
+  "llvm.ppc.altivec.vmsumuhs",
+  "llvm.ppc.altivec.vmulesb",
+  "llvm.ppc.altivec.vmulesh",
+  "llvm.ppc.altivec.vmuleub",
+  "llvm.ppc.altivec.vmuleuh",
+  "llvm.ppc.altivec.vmulosb",
+  "llvm.ppc.altivec.vmulosh",
+  "llvm.ppc.altivec.vmuloub",
+  "llvm.ppc.altivec.vmulouh",
+  "llvm.ppc.altivec.vnmsubfp",
+  "llvm.ppc.altivec.vperm",
+  "llvm.ppc.altivec.vpkpx",
+  "llvm.ppc.altivec.vpkshss",
+  "llvm.ppc.altivec.vpkshus",
+  "llvm.ppc.altivec.vpkswss",
+  "llvm.ppc.altivec.vpkswus",
+  "llvm.ppc.altivec.vpkuhus",
+  "llvm.ppc.altivec.vpkuwus",
+  "llvm.ppc.altivec.vrefp",
+  "llvm.ppc.altivec.vrfim",
+  "llvm.ppc.altivec.vrfin",
+  "llvm.ppc.altivec.vrfip",
+  "llvm.ppc.altivec.vrfiz",
+  "llvm.ppc.altivec.vrlb",
+  "llvm.ppc.altivec.vrlh",
+  "llvm.ppc.altivec.vrlw",
+  "llvm.ppc.altivec.vrsqrtefp",
+  "llvm.ppc.altivec.vsel",
+  "llvm.ppc.altivec.vsl",
+  "llvm.ppc.altivec.vslb",
+  "llvm.ppc.altivec.vslh",
+  "llvm.ppc.altivec.vslo",
+  "llvm.ppc.altivec.vslw",
+  "llvm.ppc.altivec.vsr",
+  "llvm.ppc.altivec.vsrab",
+  "llvm.ppc.altivec.vsrah",
+  "llvm.ppc.altivec.vsraw",
+  "llvm.ppc.altivec.vsrb",
+  "llvm.ppc.altivec.vsrh",
+  "llvm.ppc.altivec.vsro",
+  "llvm.ppc.altivec.vsrw",
+  "llvm.ppc.altivec.vsubcuw",
+  "llvm.ppc.altivec.vsubsbs",
+  "llvm.ppc.altivec.vsubshs",
+  "llvm.ppc.altivec.vsubsws",
+  "llvm.ppc.altivec.vsububs",
+  "llvm.ppc.altivec.vsubuhs",
+  "llvm.ppc.altivec.vsubuws",
+  "llvm.ppc.altivec.vsum2sws",
+  "llvm.ppc.altivec.vsum4sbs",
+  "llvm.ppc.altivec.vsum4shs",
+  "llvm.ppc.altivec.vsum4ubs",
+  "llvm.ppc.altivec.vsumsws",
+  "llvm.ppc.altivec.vupkhpx",
+  "llvm.ppc.altivec.vupkhsb",
+  "llvm.ppc.altivec.vupkhsh",
+  "llvm.ppc.altivec.vupklpx",
+  "llvm.ppc.altivec.vupklsb",
+  "llvm.ppc.altivec.vupklsh",
+  "llvm.ppc.dcba",
+  "llvm.ppc.dcbf",
+  "llvm.ppc.dcbi",
+  "llvm.ppc.dcbst",
+  "llvm.ppc.dcbt",
+  "llvm.ppc.dcbtst",
+  "llvm.ppc.dcbz",
+  "llvm.ppc.dcbzl",
+  "llvm.ppc.is.decremented.ctr.nonzero",
+  "llvm.ppc.mtctr",
+  "llvm.ppc.sync",
+  "llvm.prefetch",
+  "llvm.ptr.annotation",
+  "llvm.ptx.bar.sync",
+  "llvm.ptx.read.clock",
+  "llvm.ptx.read.clock64",
+  "llvm.ptx.read.ctaid.w",
+  "llvm.ptx.read.ctaid.x",
+  "llvm.ptx.read.ctaid.y",
+  "llvm.ptx.read.ctaid.z",
+  "llvm.ptx.read.gridid",
+  "llvm.ptx.read.laneid",
+  "llvm.ptx.read.lanemask.eq",
+  "llvm.ptx.read.lanemask.ge",
+  "llvm.ptx.read.lanemask.gt",
+  "llvm.ptx.read.lanemask.le",
+  "llvm.ptx.read.lanemask.lt",
+  "llvm.ptx.read.nctaid.w",
+  "llvm.ptx.read.nctaid.x",
+  "llvm.ptx.read.nctaid.y",
+  "llvm.ptx.read.nctaid.z",
+  "llvm.ptx.read.nsmid",
+  "llvm.ptx.read.ntid.w",
+  "llvm.ptx.read.ntid.x",
+  "llvm.ptx.read.ntid.y",
+  "llvm.ptx.read.ntid.z",
+  "llvm.ptx.read.nwarpid",
+  "llvm.ptx.read.pm0",
+  "llvm.ptx.read.pm1",
+  "llvm.ptx.read.pm2",
+  "llvm.ptx.read.pm3",
+  "llvm.ptx.read.smid",
+  "llvm.ptx.read.tid.w",
+  "llvm.ptx.read.tid.x",
+  "llvm.ptx.read.tid.y",
+  "llvm.ptx.read.tid.z",
+  "llvm.ptx.read.warpid",
+  "llvm.r600.read.global.size.x",
+  "llvm.r600.read.global.size.y",
+  "llvm.r600.read.global.size.z",
+  "llvm.r600.read.local.size.x",
+  "llvm.r600.read.local.size.y",
+  "llvm.r600.read.local.size.z",
+  "llvm.r600.read.ngroups.x",
+  "llvm.r600.read.ngroups.y",
+  "llvm.r600.read.ngroups.z",
+  "llvm.r600.read.tgid.x",
+  "llvm.r600.read.tgid.y",
+  "llvm.r600.read.tgid.z",
+  "llvm.r600.read.tidig.x",
+  "llvm.r600.read.tidig.y",
+  "llvm.r600.read.tidig.z",
+  "llvm.read_register",
+  "llvm.readcyclecounter",
+  "llvm.returnaddress",
+  "llvm.rint",
+  "llvm.round",
+  "llvm.sadd.with.overflow",
+  "llvm.setjmp",
+  "llvm.siglongjmp",
+  "llvm.sigsetjmp",
+  "llvm.sin",
+  "llvm.smul.with.overflow",
+  "llvm.sqrt",
+  "llvm.ssub.with.overflow",
+  "llvm.stackprotector",
+  "llvm.stackprotectorcheck",
+  "llvm.stackrestore",
+  "llvm.stacksave",
+  "llvm.trap",
+  "llvm.trunc",
+  "llvm.uadd.with.overflow",
+  "llvm.umul.with.overflow",
+  "llvm.usub.with.overflow",
+  "llvm.va_copy",
+  "llvm.va_end",
+  "llvm.var.annotation",
+  "llvm.va_start",
+  "llvm.write_register",
+  "llvm.x86.3dnow.pavgusb",
+  "llvm.x86.3dnow.pf2id",
+  "llvm.x86.3dnow.pfacc",
+  "llvm.x86.3dnow.pfadd",
+  "llvm.x86.3dnow.pfcmpeq",
+  "llvm.x86.3dnow.pfcmpge",
+  "llvm.x86.3dnow.pfcmpgt",
+  "llvm.x86.3dnow.pfmax",
+  "llvm.x86.3dnow.pfmin",
+  "llvm.x86.3dnow.pfmul",
+  "llvm.x86.3dnow.pfrcp",
+  "llvm.x86.3dnow.pfrcpit1",
+  "llvm.x86.3dnow.pfrcpit2",
+  "llvm.x86.3dnow.pfrsqit1",
+  "llvm.x86.3dnow.pfrsqrt",
+  "llvm.x86.3dnow.pfsub",
+  "llvm.x86.3dnow.pfsubr",
+  "llvm.x86.3dnow.pi2fd",
+  "llvm.x86.3dnow.pmulhrw",
+  "llvm.x86.3dnowa.pf2iw",
+  "llvm.x86.3dnowa.pfnacc",
+  "llvm.x86.3dnowa.pfpnacc",
+  "llvm.x86.3dnowa.pi2fw",
+  "llvm.x86.3dnowa.pswapd",
+  "llvm.x86.aesni.aesdec",
+  "llvm.x86.aesni.aesdeclast",
+  "llvm.x86.aesni.aesenc",
+  "llvm.x86.aesni.aesenclast",
+  "llvm.x86.aesni.aesimc",
+  "llvm.x86.aesni.aeskeygenassist",
+  "llvm.x86.avx2.gather.d.d",
+  "llvm.x86.avx2.gather.d.d.256",
+  "llvm.x86.avx2.gather.d.pd",
+  "llvm.x86.avx2.gather.d.pd.256",
+  "llvm.x86.avx2.gather.d.ps",
+  "llvm.x86.avx2.gather.d.ps.256",
+  "llvm.x86.avx2.gather.d.q",
+  "llvm.x86.avx2.gather.d.q.256",
+  "llvm.x86.avx2.gather.q.d",
+  "llvm.x86.avx2.gather.q.d.256",
+  "llvm.x86.avx2.gather.q.pd",
+  "llvm.x86.avx2.gather.q.pd.256",
+  "llvm.x86.avx2.gather.q.ps",
+  "llvm.x86.avx2.gather.q.ps.256",
+  "llvm.x86.avx2.gather.q.q",
+  "llvm.x86.avx2.gather.q.q.256",
+  "llvm.x86.avx2.maskload.d",
+  "llvm.x86.avx2.maskload.d.256",
+  "llvm.x86.avx2.maskload.q",
+  "llvm.x86.avx2.maskload.q.256",
+  "llvm.x86.avx2.maskstore.d",
+  "llvm.x86.avx2.maskstore.d.256",
+  "llvm.x86.avx2.maskstore.q",
+  "llvm.x86.avx2.maskstore.q.256",
+  "llvm.x86.avx2.movntdqa",
+  "llvm.x86.avx2.mpsadbw",
+  "llvm.x86.avx2.pabs.b",
+  "llvm.x86.avx2.pabs.d",
+  "llvm.x86.avx2.pabs.w",
+  "llvm.x86.avx2.packssdw",
+  "llvm.x86.avx2.packsswb",
+  "llvm.x86.avx2.packusdw",
+  "llvm.x86.avx2.packuswb",
+  "llvm.x86.avx2.padds.b",
+  "llvm.x86.avx2.padds.w",
+  "llvm.x86.avx2.paddus.b",
+  "llvm.x86.avx2.paddus.w",
+  "llvm.x86.avx2.pavg.b",
+  "llvm.x86.avx2.pavg.w",
+  "llvm.x86.avx2.pblendd.128",
+  "llvm.x86.avx2.pblendd.256",
+  "llvm.x86.avx2.pblendvb",
+  "llvm.x86.avx2.pblendw",
+  "llvm.x86.avx2.pbroadcastb.128",
+  "llvm.x86.avx2.pbroadcastb.256",
+  "llvm.x86.avx2.pbroadcastd.128",
+  "llvm.x86.avx2.pbroadcastd.256",
+  "llvm.x86.avx2.pbroadcastq.128",
+  "llvm.x86.avx2.pbroadcastq.256",
+  "llvm.x86.avx2.pbroadcastw.128",
+  "llvm.x86.avx2.pbroadcastw.256",
+  "llvm.x86.avx2.permd",
+  "llvm.x86.avx2.permps",
+  "llvm.x86.avx2.phadd.d",
+  "llvm.x86.avx2.phadd.sw",
+  "llvm.x86.avx2.phadd.w",
+  "llvm.x86.avx2.phsub.d",
+  "llvm.x86.avx2.phsub.sw",
+  "llvm.x86.avx2.phsub.w",
+  "llvm.x86.avx2.pmadd.ub.sw",
+  "llvm.x86.avx2.pmadd.wd",
+  "llvm.x86.avx2.pmaxs.b",
+  "llvm.x86.avx2.pmaxs.d",
+  "llvm.x86.avx2.pmaxs.w",
+  "llvm.x86.avx2.pmaxu.b",
+  "llvm.x86.avx2.pmaxu.d",
+  "llvm.x86.avx2.pmaxu.w",
+  "llvm.x86.avx2.pmins.b",
+  "llvm.x86.avx2.pmins.d",
+  "llvm.x86.avx2.pmins.w",
+  "llvm.x86.avx2.pminu.b",
+  "llvm.x86.avx2.pminu.d",
+  "llvm.x86.avx2.pminu.w",
+  "llvm.x86.avx2.pmovmskb",
+  "llvm.x86.avx2.pmovsxbd",
+  "llvm.x86.avx2.pmovsxbq",
+  "llvm.x86.avx2.pmovsxbw",
+  "llvm.x86.avx2.pmovsxdq",
+  "llvm.x86.avx2.pmovsxwd",
+  "llvm.x86.avx2.pmovsxwq",
+  "llvm.x86.avx2.pmovzxbd",
+  "llvm.x86.avx2.pmovzxbq",
+  "llvm.x86.avx2.pmovzxbw",
+  "llvm.x86.avx2.pmovzxdq",
+  "llvm.x86.avx2.pmovzxwd",
+  "llvm.x86.avx2.pmovzxwq",
+  "llvm.x86.avx2.pmul.dq",
+  "llvm.x86.avx2.pmul.hr.sw",
+  "llvm.x86.avx2.pmulh.w",
+  "llvm.x86.avx2.pmulhu.w",
+  "llvm.x86.avx2.pmulu.dq",
+  "llvm.x86.avx2.psad.bw",
+  "llvm.x86.avx2.pshuf.b",
+  "llvm.x86.avx2.psign.b",
+  "llvm.x86.avx2.psign.d",
+  "llvm.x86.avx2.psign.w",
+  "llvm.x86.avx2.psll.d",
+  "llvm.x86.avx2.psll.dq",
+  "llvm.x86.avx2.psll.dq.bs",
+  "llvm.x86.avx2.psll.q",
+  "llvm.x86.avx2.psll.w",
+  "llvm.x86.avx2.pslli.d",
+  "llvm.x86.avx2.pslli.q",
+  "llvm.x86.avx2.pslli.w",
+  "llvm.x86.avx2.psllv.d",
+  "llvm.x86.avx2.psllv.d.256",
+  "llvm.x86.avx2.psllv.q",
+  "llvm.x86.avx2.psllv.q.256",
+  "llvm.x86.avx2.psra.d",
+  "llvm.x86.avx2.psra.w",
+  "llvm.x86.avx2.psrai.d",
+  "llvm.x86.avx2.psrai.w",
+  "llvm.x86.avx2.psrav.d",
+  "llvm.x86.avx2.psrav.d.256",
+  "llvm.x86.avx2.psrl.d",
+  "llvm.x86.avx2.psrl.dq",
+  "llvm.x86.avx2.psrl.dq.bs",
+  "llvm.x86.avx2.psrl.q",
+  "llvm.x86.avx2.psrl.w",
+  "llvm.x86.avx2.psrli.d",
+  "llvm.x86.avx2.psrli.q",
+  "llvm.x86.avx2.psrli.w",
+  "llvm.x86.avx2.psrlv.d",
+  "llvm.x86.avx2.psrlv.d.256",
+  "llvm.x86.avx2.psrlv.q",
+  "llvm.x86.avx2.psrlv.q.256",
+  "llvm.x86.avx2.psubs.b",
+  "llvm.x86.avx2.psubs.w",
+  "llvm.x86.avx2.psubus.b",
+  "llvm.x86.avx2.psubus.w",
+  "llvm.x86.avx2.vbroadcast.sd.pd.256",
+  "llvm.x86.avx2.vbroadcast.ss.ps",
+  "llvm.x86.avx2.vbroadcast.ss.ps.256",
+  "llvm.x86.avx2.vbroadcasti128",
+  "llvm.x86.avx2.vextracti128",
+  "llvm.x86.avx2.vinserti128",
+  "llvm.x86.avx2.vperm2i128",
+  "llvm.x86.avx512.cvtsd2usi",
+  "llvm.x86.avx512.cvtsd2usi64",
+  "llvm.x86.avx512.cvtss2usi",
+  "llvm.x86.avx512.cvtss2usi64",
+  "llvm.x86.avx512.cvttsd2usi",
+  "llvm.x86.avx512.cvttsd2usi64",
+  "llvm.x86.avx512.cvttss2usi",
+  "llvm.x86.avx512.cvttss2usi64",
+  "llvm.x86.avx512.cvtusi2sd",
+  "llvm.x86.avx512.cvtusi2ss",
+  "llvm.x86.avx512.cvtusi642sd",
+  "llvm.x86.avx512.cvtusi642ss",
+  "llvm.x86.avx512.gather.dpd.512",
+  "llvm.x86.avx512.gather.dpi.512",
+  "llvm.x86.avx512.gather.dpq.512",
+  "llvm.x86.avx512.gather.dps.512",
+  "llvm.x86.avx512.gather.qpd.512",
+  "llvm.x86.avx512.gather.qpi.512",
+  "llvm.x86.avx512.gather.qpq.512",
+  "llvm.x86.avx512.gather.qps.512",
+  "llvm.x86.avx512.gatherpf.dpd.512",
+  "llvm.x86.avx512.gatherpf.dps.512",
+  "llvm.x86.avx512.gatherpf.qpd.512",
+  "llvm.x86.avx512.gatherpf.qps.512",
+  "llvm.x86.avx512.kand.w",
+  "llvm.x86.avx512.kandn.w",
+  "llvm.x86.avx512.knot.w",
+  "llvm.x86.avx512.kor.w",
+  "llvm.x86.avx512.kortestc.w",
+  "llvm.x86.avx512.kortestz.w",
+  "llvm.x86.avx512.kunpck.bw",
+  "llvm.x86.avx512.kxnor.w",
+  "llvm.x86.avx512.kxor.w",
+  "llvm.x86.avx512.mask.blend.d.512",
+  "llvm.x86.avx512.mask.blend.pd.512",
+  "llvm.x86.avx512.mask.blend.ps.512",
+  "llvm.x86.avx512.mask.blend.q.512",
+  "llvm.x86.avx512.mask.cmp.pd.512",
+  "llvm.x86.avx512.mask.cmp.ps.512",
+  "llvm.x86.avx512.mask.conflict.d.512",
+  "llvm.x86.avx512.mask.conflict.q.512",
+  "llvm.x86.avx512.mask.cvtdq2pd.512",
+  "llvm.x86.avx512.mask.cvtdq2ps.512",
+  "llvm.x86.avx512.mask.cvtpd2dq.512",
+  "llvm.x86.avx512.mask.cvtpd2ps.512",
+  "llvm.x86.avx512.mask.cvtpd2udq.512",
+  "llvm.x86.avx512.mask.cvtps2dq.512",
+  "llvm.x86.avx512.mask.cvtps2udq.512",
+  "llvm.x86.avx512.mask.cvttpd2dq.512",
+  "llvm.x86.avx512.mask.cvttpd2udq.512",
+  "llvm.x86.avx512.mask.cvttps2dq.512",
+  "llvm.x86.avx512.mask.cvttps2udq.512",
+  "llvm.x86.avx512.mask.cvtudq2pd.512",
+  "llvm.x86.avx512.mask.cvtudq2ps.512",
+  "llvm.x86.avx512.mask.loadu.d.512",
+  "llvm.x86.avx512.mask.loadu.pd.512",
+  "llvm.x86.avx512.mask.loadu.ps.512",
+  "llvm.x86.avx512.mask.loadu.q.512",
+  "llvm.x86.avx512.mask.lzcnt.d.512",
+  "llvm.x86.avx512.mask.lzcnt.q.512",
+  "llvm.x86.avx512.mask.max.pd.512",
+  "llvm.x86.avx512.mask.max.ps.512",
+  "llvm.x86.avx512.mask.min.pd.512",
+  "llvm.x86.avx512.mask.min.ps.512",
+  "llvm.x86.avx512.mask.pabs.d.512",
+  "llvm.x86.avx512.mask.pabs.q.512",
+  "llvm.x86.avx512.mask.pand.d.512",
+  "llvm.x86.avx512.mask.pand.q.512",
+  "llvm.x86.avx512.mask.pbroadcast.d.gpr.512",
+  "llvm.x86.avx512.mask.pbroadcast.q.gpr.512",
+  "llvm.x86.avx512.mask.pbroadcast.q.mem.512",
+  "llvm.x86.avx512.mask.pcmpeq.d.512",
+  "llvm.x86.avx512.mask.pcmpeq.q.512",
+  "llvm.x86.avx512.mask.pmaxs.d.512",
+  "llvm.x86.avx512.mask.pmaxs.q.512",
+  "llvm.x86.avx512.mask.pmaxu.d.512",
+  "llvm.x86.avx512.mask.pmaxu.q.512",
+  "llvm.x86.avx512.mask.pmins.d.512",
+  "llvm.x86.avx512.mask.pmins.q.512",
+  "llvm.x86.avx512.mask.pminu.d.512",
+  "llvm.x86.avx512.mask.pminu.q.512",
+  "llvm.x86.avx512.mask.pmul.dq.512",
+  "llvm.x86.avx512.mask.pmulu.dq.512",
+  "llvm.x86.avx512.mask.ptestm.d.512",
+  "llvm.x86.avx512.mask.ptestm.q.512",
+  "llvm.x86.avx512.mask.rndscale.pd.512",
+  "llvm.x86.avx512.mask.rndscale.ps.512",
+  "llvm.x86.avx512.mask.storeu.d.512",
+  "llvm.x86.avx512.mask.storeu.pd.512",
+  "llvm.x86.avx512.mask.storeu.ps.512",
+  "llvm.x86.avx512.mask.storeu.q.512",
+  "llvm.x86.avx512.mask.vcvtph2ps.512",
+  "llvm.x86.avx512.mask.vcvtps2ph.512",
+  "llvm.x86.avx512.mask.vpermt.d.512",
+  "llvm.x86.avx512.mask.vpermt.pd.512",
+  "llvm.x86.avx512.mask.vpermt.ps.512",
+  "llvm.x86.avx512.mask.vpermt.q.512",
+  "llvm.x86.avx512.movntdqa",
+  "llvm.x86.avx512.pbroadcastd.512",
+  "llvm.x86.avx512.pbroadcastd.i32.512",
+  "llvm.x86.avx512.pbroadcastq.512",
+  "llvm.x86.avx512.pbroadcastq.i64.512",
+  "llvm.x86.avx512.pmovzxbd",
+  "llvm.x86.avx512.pmovzxbq",
+  "llvm.x86.avx512.pmovzxdq",
+  "llvm.x86.avx512.pmovzxwd",
+  "llvm.x86.avx512.pmovzxwq",
+  "llvm.x86.avx512.psll.dq",
+  "llvm.x86.avx512.psll.dq.bs",
+  "llvm.x86.avx512.psrl.dq",
+  "llvm.x86.avx512.psrl.dq.bs",
+  "llvm.x86.avx512.rcp14.pd.512",
+  "llvm.x86.avx512.rcp14.ps.512",
+  "llvm.x86.avx512.rcp14.sd",
+  "llvm.x86.avx512.rcp14.ss",
+  "llvm.x86.avx512.rcp28.pd",
+  "llvm.x86.avx512.rcp28.ps",
+  "llvm.x86.avx512.rcp28.sd",
+  "llvm.x86.avx512.rcp28.ss",
+  "llvm.x86.avx512.rndscale.sd",
+  "llvm.x86.avx512.rndscale.ss",
+  "llvm.x86.avx512.rsqrt14.pd.512",
+  "llvm.x86.avx512.rsqrt14.ps.512",
+  "llvm.x86.avx512.rsqrt14.sd",
+  "llvm.x86.avx512.rsqrt14.ss",
+  "llvm.x86.avx512.rsqrt28.pd",
+  "llvm.x86.avx512.rsqrt28.ps",
+  "llvm.x86.avx512.rsqrt28.sd",
+  "llvm.x86.avx512.rsqrt28.ss",
+  "llvm.x86.avx512.scatter.dpd.512",
+  "llvm.x86.avx512.scatter.dpi.512",
+  "llvm.x86.avx512.scatter.dpq.512",
+  "llvm.x86.avx512.scatter.dps.512",
+  "llvm.x86.avx512.scatter.qpd.512",
+  "llvm.x86.avx512.scatter.qpi.512",
+  "llvm.x86.avx512.scatter.qpq.512",
+  "llvm.x86.avx512.scatter.qps.512",
+  "llvm.x86.avx512.scatterpf.dpd.512",
+  "llvm.x86.avx512.scatterpf.dps.512",
+  "llvm.x86.avx512.scatterpf.qpd.512",
+  "llvm.x86.avx512.scatterpf.qps.512",
+  "llvm.x86.avx512.sqrt.pd.512",
+  "llvm.x86.avx512.sqrt.ps.512",
+  "llvm.x86.avx512.sqrt.sd",
+  "llvm.x86.avx512.sqrt.ss",
+  "llvm.x86.avx512.vbroadcast.sd.512",
+  "llvm.x86.avx512.vbroadcast.sd.pd.512",
+  "llvm.x86.avx512.vbroadcast.ss.512",
+  "llvm.x86.avx512.vbroadcast.ss.ps.512",
+  "llvm.x86.avx.addsub.pd.256",
+  "llvm.x86.avx.addsub.ps.256",
+  "llvm.x86.avx.blend.pd.256",
+  "llvm.x86.avx.blend.ps.256",
+  "llvm.x86.avx.blendv.pd.256",
+  "llvm.x86.avx.blendv.ps.256",
+  "llvm.x86.avx.cmp.pd.256",
+  "llvm.x86.avx.cmp.ps.256",
+  "llvm.x86.avx.cvt.pd2.ps.256",
+  "llvm.x86.avx.cvt.pd2dq.256",
+  "llvm.x86.avx.cvt.ps2.pd.256",
+  "llvm.x86.avx.cvt.ps2dq.256",
+  "llvm.x86.avx.cvtdq2.pd.256",
+  "llvm.x86.avx.cvtdq2.ps.256",
+  "llvm.x86.avx.cvtt.pd2dq.256",
+  "llvm.x86.avx.cvtt.ps2dq.256",
+  "llvm.x86.avx.dp.ps.256",
+  "llvm.x86.avx.hadd.pd.256",
+  "llvm.x86.avx.hadd.ps.256",
+  "llvm.x86.avx.hsub.pd.256",
+  "llvm.x86.avx.hsub.ps.256",
+  "llvm.x86.avx.ldu.dq.256",
+  "llvm.x86.avx.maskload.pd",
+  "llvm.x86.avx.maskload.pd.256",
+  "llvm.x86.avx.maskload.ps",
+  "llvm.x86.avx.maskload.ps.256",
+  "llvm.x86.avx.maskstore.pd",
+  "llvm.x86.avx.maskstore.pd.256",
+  "llvm.x86.avx.maskstore.ps",
+  "llvm.x86.avx.maskstore.ps.256",
+  "llvm.x86.avx.max.pd.256",
+  "llvm.x86.avx.max.ps.256",
+  "llvm.x86.avx.min.pd.256",
+  "llvm.x86.avx.min.ps.256",
+  "llvm.x86.avx.movmsk.pd.256",
+  "llvm.x86.avx.movmsk.ps.256",
+  "llvm.x86.avx.ptestc.256",
+  "llvm.x86.avx.ptestnzc.256",
+  "llvm.x86.avx.ptestz.256",
+  "llvm.x86.avx.rcp.ps.256",
+  "llvm.x86.avx.round.pd.256",
+  "llvm.x86.avx.round.ps.256",
+  "llvm.x86.avx.rsqrt.ps.256",
+  "llvm.x86.avx.sqrt.pd.256",
+  "llvm.x86.avx.sqrt.ps.256",
+  "llvm.x86.avx.storeu.dq.256",
+  "llvm.x86.avx.storeu.pd.256",
+  "llvm.x86.avx.storeu.ps.256",
+  "llvm.x86.avx.vbroadcastf128.pd.256",
+  "llvm.x86.avx.vbroadcastf128.ps.256",
+  "llvm.x86.avx.vextractf128.pd.256",
+  "llvm.x86.avx.vextractf128.ps.256",
+  "llvm.x86.avx.vextractf128.si.256",
+  "llvm.x86.avx.vinsertf128.pd.256",
+  "llvm.x86.avx.vinsertf128.ps.256",
+  "llvm.x86.avx.vinsertf128.si.256",
+  "llvm.x86.avx.vperm2f128.pd.256",
+  "llvm.x86.avx.vperm2f128.ps.256",
+  "llvm.x86.avx.vperm2f128.si.256",
+  "llvm.x86.avx.vpermilvar.pd",
+  "llvm.x86.avx.vpermilvar.pd.256",
+  "llvm.x86.avx.vpermilvar.ps",
+  "llvm.x86.avx.vpermilvar.ps.256",
+  "llvm.x86.avx.vtestc.pd",
+  "llvm.x86.avx.vtestc.pd.256",
+  "llvm.x86.avx.vtestc.ps",
+  "llvm.x86.avx.vtestc.ps.256",
+  "llvm.x86.avx.vtestnzc.pd",
+  "llvm.x86.avx.vtestnzc.pd.256",
+  "llvm.x86.avx.vtestnzc.ps",
+  "llvm.x86.avx.vtestnzc.ps.256",
+  "llvm.x86.avx.vtestz.pd",
+  "llvm.x86.avx.vtestz.pd.256",
+  "llvm.x86.avx.vtestz.ps",
+  "llvm.x86.avx.vtestz.ps.256",
+  "llvm.x86.avx.vzeroall",
+  "llvm.x86.avx.vzeroupper",
+  "llvm.x86.bmi.bextr.32",
+  "llvm.x86.bmi.bextr.64",
+  "llvm.x86.bmi.bzhi.32",
+  "llvm.x86.bmi.bzhi.64",
+  "llvm.x86.bmi.pdep.32",
+  "llvm.x86.bmi.pdep.64",
+  "llvm.x86.bmi.pext.32",
+  "llvm.x86.bmi.pext.64",
+  "llvm.x86.fma.vfmadd.pd",
+  "llvm.x86.fma.vfmadd.pd.256",
+  "llvm.x86.fma.vfmadd.pd.512",
+  "llvm.x86.fma.vfmadd.ps",
+  "llvm.x86.fma.vfmadd.ps.256",
+  "llvm.x86.fma.vfmadd.ps.512",
+  "llvm.x86.fma.vfmadd.sd",
+  "llvm.x86.fma.vfmadd.ss",
+  "llvm.x86.fma.vfmaddsub.pd",
+  "llvm.x86.fma.vfmaddsub.pd.256",
+  "llvm.x86.fma.vfmaddsub.pd.512",
+  "llvm.x86.fma.vfmaddsub.ps",
+  "llvm.x86.fma.vfmaddsub.ps.256",
+  "llvm.x86.fma.vfmaddsub.ps.512",
+  "llvm.x86.fma.vfmsub.pd",
+  "llvm.x86.fma.vfmsub.pd.256",
+  "llvm.x86.fma.vfmsub.pd.512",
+  "llvm.x86.fma.vfmsub.ps",
+  "llvm.x86.fma.vfmsub.ps.256",
+  "llvm.x86.fma.vfmsub.ps.512",
+  "llvm.x86.fma.vfmsub.sd",
+  "llvm.x86.fma.vfmsub.ss",
+  "llvm.x86.fma.vfmsubadd.pd",
+  "llvm.x86.fma.vfmsubadd.pd.256",
+  "llvm.x86.fma.vfmsubadd.pd.512",
+  "llvm.x86.fma.vfmsubadd.ps",
+  "llvm.x86.fma.vfmsubadd.ps.256",
+  "llvm.x86.fma.vfmsubadd.ps.512",
+  "llvm.x86.fma.vfnmadd.pd",
+  "llvm.x86.fma.vfnmadd.pd.256",
+  "llvm.x86.fma.vfnmadd.pd.512",
+  "llvm.x86.fma.vfnmadd.ps",
+  "llvm.x86.fma.vfnmadd.ps.256",
+  "llvm.x86.fma.vfnmadd.ps.512",
+  "llvm.x86.fma.vfnmadd.sd",
+  "llvm.x86.fma.vfnmadd.ss",
+  "llvm.x86.fma.vfnmsub.pd",
+  "llvm.x86.fma.vfnmsub.pd.256",
+  "llvm.x86.fma.vfnmsub.pd.512",
+  "llvm.x86.fma.vfnmsub.ps",
+  "llvm.x86.fma.vfnmsub.ps.256",
+  "llvm.x86.fma.vfnmsub.ps.512",
+  "llvm.x86.fma.vfnmsub.sd",
+  "llvm.x86.fma.vfnmsub.ss",
+  "llvm.x86.int",
+  "llvm.x86.mmx.emms",
+  "llvm.x86.mmx.femms",
+  "llvm.x86.mmx.maskmovq",
+  "llvm.x86.mmx.movnt.dq",
+  "llvm.x86.mmx.packssdw",
+  "llvm.x86.mmx.packsswb",
+  "llvm.x86.mmx.packuswb",
+  "llvm.x86.mmx.padd.b",
+  "llvm.x86.mmx.padd.d",
+  "llvm.x86.mmx.padd.q",
+  "llvm.x86.mmx.padd.w",
+  "llvm.x86.mmx.padds.b",
+  "llvm.x86.mmx.padds.w",
+  "llvm.x86.mmx.paddus.b",
+  "llvm.x86.mmx.paddus.w",
+  "llvm.x86.mmx.palignr.b",
+  "llvm.x86.mmx.pand",
+  "llvm.x86.mmx.pandn",
+  "llvm.x86.mmx.pavg.b",
+  "llvm.x86.mmx.pavg.w",
+  "llvm.x86.mmx.pcmpeq.b",
+  "llvm.x86.mmx.pcmpeq.d",
+  "llvm.x86.mmx.pcmpeq.w",
+  "llvm.x86.mmx.pcmpgt.b",
+  "llvm.x86.mmx.pcmpgt.d",
+  "llvm.x86.mmx.pcmpgt.w",
+  "llvm.x86.mmx.pextr.w",
+  "llvm.x86.mmx.pinsr.w",
+  "llvm.x86.mmx.pmadd.wd",
+  "llvm.x86.mmx.pmaxs.w",
+  "llvm.x86.mmx.pmaxu.b",
+  "llvm.x86.mmx.pmins.w",
+  "llvm.x86.mmx.pminu.b",
+  "llvm.x86.mmx.pmovmskb",
+  "llvm.x86.mmx.pmulh.w",
+  "llvm.x86.mmx.pmulhu.w",
+  "llvm.x86.mmx.pmull.w",
+  "llvm.x86.mmx.pmulu.dq",
+  "llvm.x86.mmx.por",
+  "llvm.x86.mmx.psad.bw",
+  "llvm.x86.mmx.psll.d",
+  "llvm.x86.mmx.psll.q",
+  "llvm.x86.mmx.psll.w",
+  "llvm.x86.mmx.pslli.d",
+  "llvm.x86.mmx.pslli.q",
+  "llvm.x86.mmx.pslli.w",
+  "llvm.x86.mmx.psra.d",
+  "llvm.x86.mmx.psra.w",
+  "llvm.x86.mmx.psrai.d",
+  "llvm.x86.mmx.psrai.w",
+  "llvm.x86.mmx.psrl.d",
+  "llvm.x86.mmx.psrl.q",
+  "llvm.x86.mmx.psrl.w",
+  "llvm.x86.mmx.psrli.d",
+  "llvm.x86.mmx.psrli.q",
+  "llvm.x86.mmx.psrli.w",
+  "llvm.x86.mmx.psub.b",
+  "llvm.x86.mmx.psub.d",
+  "llvm.x86.mmx.psub.q",
+  "llvm.x86.mmx.psub.w",
+  "llvm.x86.mmx.psubs.b",
+  "llvm.x86.mmx.psubs.w",
+  "llvm.x86.mmx.psubus.b",
+  "llvm.x86.mmx.psubus.w",
+  "llvm.x86.mmx.punpckhbw",
+  "llvm.x86.mmx.punpckhdq",
+  "llvm.x86.mmx.punpckhwd",
+  "llvm.x86.mmx.punpcklbw",
+  "llvm.x86.mmx.punpckldq",
+  "llvm.x86.mmx.punpcklwd",
+  "llvm.x86.mmx.pxor",
+  "llvm.x86.pclmulqdq",
+  "llvm.x86.rdfsbase.32",
+  "llvm.x86.rdfsbase.64",
+  "llvm.x86.rdgsbase.32",
+  "llvm.x86.rdgsbase.64",
+  "llvm.x86.rdpmc",
+  "llvm.x86.rdrand.16",
+  "llvm.x86.rdrand.32",
+  "llvm.x86.rdrand.64",
+  "llvm.x86.rdseed.16",
+  "llvm.x86.rdseed.32",
+  "llvm.x86.rdseed.64",
+  "llvm.x86.rdtsc",
+  "llvm.x86.rdtscp",
+  "llvm.x86.sha1msg1",
+  "llvm.x86.sha1msg2",
+  "llvm.x86.sha1nexte",
+  "llvm.x86.sha1rnds4",
+  "llvm.x86.sha256msg1",
+  "llvm.x86.sha256msg2",
+  "llvm.x86.sha256rnds2",
+  "llvm.x86.sse2.add.sd",
+  "llvm.x86.sse2.clflush",
+  "llvm.x86.sse2.cmp.pd",
+  "llvm.x86.sse2.cmp.sd",
+  "llvm.x86.sse2.comieq.sd",
+  "llvm.x86.sse2.comige.sd",
+  "llvm.x86.sse2.comigt.sd",
+  "llvm.x86.sse2.comile.sd",
+  "llvm.x86.sse2.comilt.sd",
+  "llvm.x86.sse2.comineq.sd",
+  "llvm.x86.sse2.cvtdq2pd",
+  "llvm.x86.sse2.cvtdq2ps",
+  "llvm.x86.sse2.cvtpd2dq",
+  "llvm.x86.sse2.cvtpd2ps",
+  "llvm.x86.sse2.cvtps2dq",
+  "llvm.x86.sse2.cvtps2pd",
+  "llvm.x86.sse2.cvtsd2si",
+  "llvm.x86.sse2.cvtsd2si64",
+  "llvm.x86.sse2.cvtsd2ss",
+  "llvm.x86.sse2.cvtsi2sd",
+  "llvm.x86.sse2.cvtsi642sd",
+  "llvm.x86.sse2.cvtss2sd",
+  "llvm.x86.sse2.cvttpd2dq",
+  "llvm.x86.sse2.cvttps2dq",
+  "llvm.x86.sse2.cvttsd2si",
+  "llvm.x86.sse2.cvttsd2si64",
+  "llvm.x86.sse2.div.sd",
+  "llvm.x86.sse2.lfence",
+  "llvm.x86.sse2.maskmov.dqu",
+  "llvm.x86.sse2.max.pd",
+  "llvm.x86.sse2.max.sd",
+  "llvm.x86.sse2.mfence",
+  "llvm.x86.sse2.min.pd",
+  "llvm.x86.sse2.min.sd",
+  "llvm.x86.sse2.movmsk.pd",
+  "llvm.x86.sse2.mul.sd",
+  "llvm.x86.sse2.packssdw.128",
+  "llvm.x86.sse2.packsswb.128",
+  "llvm.x86.sse2.packuswb.128",
+  "llvm.x86.sse2.padds.b",
+  "llvm.x86.sse2.padds.w",
+  "llvm.x86.sse2.paddus.b",
+  "llvm.x86.sse2.paddus.w",
+  "llvm.x86.sse2.pause",
+  "llvm.x86.sse2.pavg.b",
+  "llvm.x86.sse2.pavg.w",
+  "llvm.x86.sse2.pmadd.wd",
+  "llvm.x86.sse2.pmaxs.w",
+  "llvm.x86.sse2.pmaxu.b",
+  "llvm.x86.sse2.pmins.w",
+  "llvm.x86.sse2.pminu.b",
+  "llvm.x86.sse2.pmovmskb.128",
+  "llvm.x86.sse2.pmulh.w",
+  "llvm.x86.sse2.pmulhu.w",
+  "llvm.x86.sse2.pmulu.dq",
+  "llvm.x86.sse2.psad.bw",
+  "llvm.x86.sse2.pshuf.d",
+  "llvm.x86.sse2.pshufh.w",
+  "llvm.x86.sse2.pshufl.w",
+  "llvm.x86.sse2.psll.d",
+  "llvm.x86.sse2.psll.dq",
+  "llvm.x86.sse2.psll.dq.bs",
+  "llvm.x86.sse2.psll.q",
+  "llvm.x86.sse2.psll.w",
+  "llvm.x86.sse2.pslli.d",
+  "llvm.x86.sse2.pslli.q",
+  "llvm.x86.sse2.pslli.w",
+  "llvm.x86.sse2.psra.d",
+  "llvm.x86.sse2.psra.w",
+  "llvm.x86.sse2.psrai.d",
+  "llvm.x86.sse2.psrai.w",
+  "llvm.x86.sse2.psrl.d",
+  "llvm.x86.sse2.psrl.dq",
+  "llvm.x86.sse2.psrl.dq.bs",
+  "llvm.x86.sse2.psrl.q",
+  "llvm.x86.sse2.psrl.w",
+  "llvm.x86.sse2.psrli.d",
+  "llvm.x86.sse2.psrli.q",
+  "llvm.x86.sse2.psrli.w",
+  "llvm.x86.sse2.psubs.b",
+  "llvm.x86.sse2.psubs.w",
+  "llvm.x86.sse2.psubus.b",
+  "llvm.x86.sse2.psubus.w",
+  "llvm.x86.sse2.sqrt.pd",
+  "llvm.x86.sse2.sqrt.sd",
+  "llvm.x86.sse2.storel.dq",
+  "llvm.x86.sse2.storeu.dq",
+  "llvm.x86.sse2.storeu.pd",
+  "llvm.x86.sse2.sub.sd",
+  "llvm.x86.sse2.ucomieq.sd",
+  "llvm.x86.sse2.ucomige.sd",
+  "llvm.x86.sse2.ucomigt.sd",
+  "llvm.x86.sse2.ucomile.sd",
+  "llvm.x86.sse2.ucomilt.sd",
+  "llvm.x86.sse2.ucomineq.sd",
+  "llvm.x86.sse3.addsub.pd",
+  "llvm.x86.sse3.addsub.ps",
+  "llvm.x86.sse3.hadd.pd",
+  "llvm.x86.sse3.hadd.ps",
+  "llvm.x86.sse3.hsub.pd",
+  "llvm.x86.sse3.hsub.ps",
+  "llvm.x86.sse3.ldu.dq",
+  "llvm.x86.sse3.monitor",
+  "llvm.x86.sse3.mwait",
+  "llvm.x86.sse41.blendpd",
+  "llvm.x86.sse41.blendps",
+  "llvm.x86.sse41.blendvpd",
+  "llvm.x86.sse41.blendvps",
+  "llvm.x86.sse41.dppd",
+  "llvm.x86.sse41.dpps",
+  "llvm.x86.sse41.extractps",
+  "llvm.x86.sse41.insertps",
+  "llvm.x86.sse41.movntdqa",
+  "llvm.x86.sse41.mpsadbw",
+  "llvm.x86.sse41.packusdw",
+  "llvm.x86.sse41.pblendvb",
+  "llvm.x86.sse41.pblendw",
+  "llvm.x86.sse41.pextrb",
+  "llvm.x86.sse41.pextrd",
+  "llvm.x86.sse41.pextrq",
+  "llvm.x86.sse41.phminposuw",
+  "llvm.x86.sse41.pmaxsb",
+  "llvm.x86.sse41.pmaxsd",
+  "llvm.x86.sse41.pmaxud",
+  "llvm.x86.sse41.pmaxuw",
+  "llvm.x86.sse41.pminsb",
+  "llvm.x86.sse41.pminsd",
+  "llvm.x86.sse41.pminud",
+  "llvm.x86.sse41.pminuw",
+  "llvm.x86.sse41.pmovsxbd",
+  "llvm.x86.sse41.pmovsxbq",
+  "llvm.x86.sse41.pmovsxbw",
+  "llvm.x86.sse41.pmovsxdq",
+  "llvm.x86.sse41.pmovsxwd",
+  "llvm.x86.sse41.pmovsxwq",
+  "llvm.x86.sse41.pmovzxbd",
+  "llvm.x86.sse41.pmovzxbq",
+  "llvm.x86.sse41.pmovzxbw",
+  "llvm.x86.sse41.pmovzxdq",
+  "llvm.x86.sse41.pmovzxwd",
+  "llvm.x86.sse41.pmovzxwq",
+  "llvm.x86.sse41.pmuldq",
+  "llvm.x86.sse41.ptestc",
+  "llvm.x86.sse41.ptestnzc",
+  "llvm.x86.sse41.ptestz",
+  "llvm.x86.sse41.round.pd",
+  "llvm.x86.sse41.round.ps",
+  "llvm.x86.sse41.round.sd",
+  "llvm.x86.sse41.round.ss",
+  "llvm.x86.sse42.crc32.32.16",
+  "llvm.x86.sse42.crc32.32.32",
+  "llvm.x86.sse42.crc32.32.8",
+  "llvm.x86.sse42.crc32.64.64",
+  "llvm.x86.sse42.pcmpestri128",
+  "llvm.x86.sse42.pcmpestria128",
+  "llvm.x86.sse42.pcmpestric128",
+  "llvm.x86.sse42.pcmpestrio128",
+  "llvm.x86.sse42.pcmpestris128",
+  "llvm.x86.sse42.pcmpestriz128",
+  "llvm.x86.sse42.pcmpestrm128",
+  "llvm.x86.sse42.pcmpistri128",
+  "llvm.x86.sse42.pcmpistria128",
+  "llvm.x86.sse42.pcmpistric128",
+  "llvm.x86.sse42.pcmpistrio128",
+  "llvm.x86.sse42.pcmpistris128",
+  "llvm.x86.sse42.pcmpistriz128",
+  "llvm.x86.sse42.pcmpistrm128",
+  "llvm.x86.sse4a.extrq",
+  "llvm.x86.sse4a.extrqi",
+  "llvm.x86.sse4a.insertq",
+  "llvm.x86.sse4a.insertqi",
+  "llvm.x86.sse4a.movnt.sd",
+  "llvm.x86.sse4a.movnt.ss",
+  "llvm.x86.sse.add.ss",
+  "llvm.x86.sse.cmp.ps",
+  "llvm.x86.sse.cmp.ss",
+  "llvm.x86.sse.comieq.ss",
+  "llvm.x86.sse.comige.ss",
+  "llvm.x86.sse.comigt.ss",
+  "llvm.x86.sse.comile.ss",
+  "llvm.x86.sse.comilt.ss",
+  "llvm.x86.sse.comineq.ss",
+  "llvm.x86.sse.cvtpd2pi",
+  "llvm.x86.sse.cvtpi2pd",
+  "llvm.x86.sse.cvtpi2ps",
+  "llvm.x86.sse.cvtps2pi",
+  "llvm.x86.sse.cvtsi2ss",
+  "llvm.x86.sse.cvtsi642ss",
+  "llvm.x86.sse.cvtss2si",
+  "llvm.x86.sse.cvtss2si64",
+  "llvm.x86.sse.cvttpd2pi",
+  "llvm.x86.sse.cvttps2pi",
+  "llvm.x86.sse.cvttss2si",
+  "llvm.x86.sse.cvttss2si64",
+  "llvm.x86.sse.div.ss",
+  "llvm.x86.sse.ldmxcsr",
+  "llvm.x86.sse.max.ps",
+  "llvm.x86.sse.max.ss",
+  "llvm.x86.sse.min.ps",
+  "llvm.x86.sse.min.ss",
+  "llvm.x86.sse.movmsk.ps",
+  "llvm.x86.sse.mul.ss",
+  "llvm.x86.sse.pshuf.w",
+  "llvm.x86.sse.rcp.ps",
+  "llvm.x86.sse.rcp.ss",
+  "llvm.x86.sse.rsqrt.ps",
+  "llvm.x86.sse.rsqrt.ss",
+  "llvm.x86.sse.sfence",
+  "llvm.x86.sse.sqrt.ps",
+  "llvm.x86.sse.sqrt.ss",
+  "llvm.x86.sse.stmxcsr",
+  "llvm.x86.sse.storeu.ps",
+  "llvm.x86.sse.sub.ss",
+  "llvm.x86.sse.ucomieq.ss",
+  "llvm.x86.sse.ucomige.ss",
+  "llvm.x86.sse.ucomigt.ss",
+  "llvm.x86.sse.ucomile.ss",
+  "llvm.x86.sse.ucomilt.ss",
+  "llvm.x86.sse.ucomineq.ss",
+  "llvm.x86.ssse3.pabs.b",
+  "llvm.x86.ssse3.pabs.b.128",
+  "llvm.x86.ssse3.pabs.d",
+  "llvm.x86.ssse3.pabs.d.128",
+  "llvm.x86.ssse3.pabs.w",
+  "llvm.x86.ssse3.pabs.w.128",
+  "llvm.x86.ssse3.phadd.d",
+  "llvm.x86.ssse3.phadd.d.128",
+  "llvm.x86.ssse3.phadd.sw",
+  "llvm.x86.ssse3.phadd.sw.128",
+  "llvm.x86.ssse3.phadd.w",
+  "llvm.x86.ssse3.phadd.w.128",
+  "llvm.x86.ssse3.phsub.d",
+  "llvm.x86.ssse3.phsub.d.128",
+  "llvm.x86.ssse3.phsub.sw",
+  "llvm.x86.ssse3.phsub.sw.128",
+  "llvm.x86.ssse3.phsub.w",
+  "llvm.x86.ssse3.phsub.w.128",
+  "llvm.x86.ssse3.pmadd.ub.sw",
+  "llvm.x86.ssse3.pmadd.ub.sw.128",
+  "llvm.x86.ssse3.pmul.hr.sw",
+  "llvm.x86.ssse3.pmul.hr.sw.128",
+  "llvm.x86.ssse3.pshuf.b",
+  "llvm.x86.ssse3.pshuf.b.128",
+  "llvm.x86.ssse3.psign.b",
+  "llvm.x86.ssse3.psign.b.128",
+  "llvm.x86.ssse3.psign.d",
+  "llvm.x86.ssse3.psign.d.128",
+  "llvm.x86.ssse3.psign.w",
+  "llvm.x86.ssse3.psign.w.128",
+  "llvm.x86.tbm.bextri.u32",
+  "llvm.x86.tbm.bextri.u64",
+  "llvm.x86.vcvtph2ps.128",
+  "llvm.x86.vcvtph2ps.256",
+  "llvm.x86.vcvtps2ph.128",
+  "llvm.x86.vcvtps2ph.256",
+  "llvm.x86.wrfsbase.32",
+  "llvm.x86.wrfsbase.64",
+  "llvm.x86.wrgsbase.32",
+  "llvm.x86.wrgsbase.64",
+  "llvm.x86.xabort",
+  "llvm.x86.xbegin",
+  "llvm.x86.xend",
+  "llvm.x86.xop.vfrcz.pd",
+  "llvm.x86.xop.vfrcz.pd.256",
+  "llvm.x86.xop.vfrcz.ps",
+  "llvm.x86.xop.vfrcz.ps.256",
+  "llvm.x86.xop.vfrcz.sd",
+  "llvm.x86.xop.vfrcz.ss",
+  "llvm.x86.xop.vpcmov",
+  "llvm.x86.xop.vpcmov.256",
+  "llvm.x86.xop.vpcomb",
+  "llvm.x86.xop.vpcomd",
+  "llvm.x86.xop.vpcomq",
+  "llvm.x86.xop.vpcomub",
+  "llvm.x86.xop.vpcomud",
+  "llvm.x86.xop.vpcomuq",
+  "llvm.x86.xop.vpcomuw",
+  "llvm.x86.xop.vpcomw",
+  "llvm.x86.xop.vpermil2pd",
+  "llvm.x86.xop.vpermil2pd.256",
+  "llvm.x86.xop.vpermil2ps",
+  "llvm.x86.xop.vpermil2ps.256",
+  "llvm.x86.xop.vphaddbd",
+  "llvm.x86.xop.vphaddbq",
+  "llvm.x86.xop.vphaddbw",
+  "llvm.x86.xop.vphadddq",
+  "llvm.x86.xop.vphaddubd",
+  "llvm.x86.xop.vphaddubq",
+  "llvm.x86.xop.vphaddubw",
+  "llvm.x86.xop.vphaddudq",
+  "llvm.x86.xop.vphadduwd",
+  "llvm.x86.xop.vphadduwq",
+  "llvm.x86.xop.vphaddwd",
+  "llvm.x86.xop.vphaddwq",
+  "llvm.x86.xop.vphsubbw",
+  "llvm.x86.xop.vphsubdq",
+  "llvm.x86.xop.vphsubwd",
+  "llvm.x86.xop.vpmacsdd",
+  "llvm.x86.xop.vpmacsdqh",
+  "llvm.x86.xop.vpmacsdql",
+  "llvm.x86.xop.vpmacssdd",
+  "llvm.x86.xop.vpmacssdqh",
+  "llvm.x86.xop.vpmacssdql",
+  "llvm.x86.xop.vpmacsswd",
+  "llvm.x86.xop.vpmacssww",
+  "llvm.x86.xop.vpmacswd",
+  "llvm.x86.xop.vpmacsww",
+  "llvm.x86.xop.vpmadcsswd",
+  "llvm.x86.xop.vpmadcswd",
+  "llvm.x86.xop.vpperm",
+  "llvm.x86.xop.vprotb",
+  "llvm.x86.xop.vprotbi",
+  "llvm.x86.xop.vprotd",
+  "llvm.x86.xop.vprotdi",
+  "llvm.x86.xop.vprotq",
+  "llvm.x86.xop.vprotqi",
+  "llvm.x86.xop.vprotw",
+  "llvm.x86.xop.vprotwi",
+  "llvm.x86.xop.vpshab",
+  "llvm.x86.xop.vpshad",
+  "llvm.x86.xop.vpshaq",
+  "llvm.x86.xop.vpshaw",
+  "llvm.x86.xop.vpshlb",
+  "llvm.x86.xop.vpshld",
+  "llvm.x86.xop.vpshlq",
+  "llvm.x86.xop.vpshlw",
+  "llvm.x86.xtest",
+  "llvm.xcore.bitrev",
+  "llvm.xcore.checkevent",
+  "llvm.xcore.chkct",
+  "llvm.xcore.clre",
+  "llvm.xcore.clrpt",
+  "llvm.xcore.clrsr",
+  "llvm.xcore.crc32",
+  "llvm.xcore.crc8",
+  "llvm.xcore.edu",
+  "llvm.xcore.eeu",
+  "llvm.xcore.endin",
+  "llvm.xcore.freer",
+  "llvm.xcore.geted",
+  "llvm.xcore.getet",
+  "llvm.xcore.getid",
+  "llvm.xcore.getps",
+  "llvm.xcore.getr",
+  "llvm.xcore.getst",
+  "llvm.xcore.getts",
+  "llvm.xcore.in",
+  "llvm.xcore.inct",
+  "llvm.xcore.initcp",
+  "llvm.xcore.initdp",
+  "llvm.xcore.initlr",
+  "llvm.xcore.initpc",
+  "llvm.xcore.initsp",
+  "llvm.xcore.inshr",
+  "llvm.xcore.int",
+  "llvm.xcore.mjoin",
+  "llvm.xcore.msync",
+  "llvm.xcore.out",
+  "llvm.xcore.outct",
+  "llvm.xcore.outshr",
+  "llvm.xcore.outt",
+  "llvm.xcore.peek",
+  "llvm.xcore.setc",
+  "llvm.xcore.setclk",
+  "llvm.xcore.setd",
+  "llvm.xcore.setev",
+  "llvm.xcore.setps",
+  "llvm.xcore.setpsc",
+  "llvm.xcore.setpt",
+  "llvm.xcore.setrdy",
+  "llvm.xcore.setsr",
+  "llvm.xcore.settw",
+  "llvm.xcore.setv",
+  "llvm.xcore.sext",
+  "llvm.xcore.ssync",
+  "llvm.xcore.syncr",
+  "llvm.xcore.testct",
+  "llvm.xcore.testwct",
+  "llvm.xcore.waitevent",
+  "llvm.xcore.zext",
+#endif
+
+// Intrinsic ID to overload bitset
+#ifdef GET_INTRINSIC_OVERLOAD_TABLE
+static const uint8_t OTable[] = {
+  0 | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0,
+  0,
+  0,
+  0 | (1<<4) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6),
+  0 | (1<<0) | (1<<1) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<2) | (1<<4) | (1<<5) | (1<<7),
+  0,
+  0 | (1<<6),
+  0 | (1<<0),
+  0,
+  0 | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<4) | (1<<5) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4),
+  0,
+  0 | (1<<2) | (1<<4),
+  0 | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5),
+  0,
+  0 | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<3) | (1<<4) | (1<<6) | (1<<7),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<2) | (1<<3) | (1<<4),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<0),
+  0 | (1<<7),
+  0 | (1<<0) | (1<<1),
+  0,
+  0 | (1<<1) | (1<<2),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0,
+  0,
+  0,
+  0 | (1<<4),
+  0,
+  0,
+  0 | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<5),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<3) | (1<<4),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<0) | (1<<2) | (1<<3),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<0) | (1<<3),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<5),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<7),
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0 | (1<<3) | (1<<5),
+  0 | (1<<1) | (1<<2) | (1<<3) | (1<<4),
+  0 | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6) | (1<<7),
+  0 | (1<<1) | (1<<2) | (1<<3) | (1<<5) | (1<<6),
+  0 | (1<<1) | (1<<2) | (1<<3)
+};
+
+return (OTable[id/8] & (1 << (id%8))) != 0;
+#endif
+
+// Function name -> enum value recognizer code.
+#ifdef GET_FUNCTION_RECOGNIZER
+  StringRef NameR(Name+6, Len-6);   // Skip over 'llvm.'
+  switch (Name[5]) {                  // Dispatch on first letter.
+  default: break;
+  case 'A':
+    if (NameR.startswith("MDGPU.trig.preop.")) return Intrinsic::AMDGPU_trig_preop;
+    if (NameR.startswith("MDGPU.rsq.clamped.")) return Intrinsic::AMDGPU_rsq_clamped;
+    if (NameR.startswith("MDGPU.rsq.")) return Intrinsic::AMDGPU_rsq;
+    if (NameR.startswith("MDGPU.rcp.")) return Intrinsic::AMDGPU_rcp;
+    if (NameR.startswith("MDGPU.div.scale.")) return Intrinsic::AMDGPU_div_scale;
+    if (NameR.startswith("MDGPU.div.fmas.")) return Intrinsic::AMDGPU_div_fmas;
+    if (NameR.startswith("MDGPU.div.fixup.")) return Intrinsic::AMDGPU_div_fixup;
+    break;  // end of 'A' case.
+  case 'a':
+    if (NameR.startswith("rm.vcvtru.")) return Intrinsic::arm_vcvtru;
+    if (NameR.startswith("rm.vcvtr.")) return Intrinsic::arm_vcvtr;
+    if (NameR.startswith("rm.strex.")) return Intrinsic::arm_strex;
+    if (NameR.startswith("rm.stlex.")) return Intrinsic::arm_stlex;
+    if (NameR.startswith("rm.neon.vst4lane.")) return Intrinsic::arm_neon_vst4lane;
+    if (NameR.startswith("rm.neon.vst4.")) return Intrinsic::arm_neon_vst4;
+    if (NameR.startswith("rm.neon.vst3lane.")) return Intrinsic::arm_neon_vst3lane;
+    if (NameR.startswith("rm.neon.vst3.")) return Intrinsic::arm_neon_vst3;
+    if (NameR.startswith("rm.neon.vst2lane.")) return Intrinsic::arm_neon_vst2lane;
+    if (NameR.startswith("rm.neon.vst2.")) return Intrinsic::arm_neon_vst2;
+    if (NameR.startswith("rm.neon.vst1.")) return Intrinsic::arm_neon_vst1;
+    if (NameR.startswith("rm.neon.vshiftu.")) return Intrinsic::arm_neon_vshiftu;
+    if (NameR.startswith("rm.neon.vshifts.")) return Intrinsic::arm_neon_vshifts;
+    if (NameR.startswith("rm.neon.vshiftins.")) return Intrinsic::arm_neon_vshiftins;
+    if (NameR.startswith("rm.neon.vrsubhn.")) return Intrinsic::arm_neon_vrsubhn;
+    if (NameR.startswith("rm.neon.vrsqrts.")) return Intrinsic::arm_neon_vrsqrts;
+    if (NameR.startswith("rm.neon.vrsqrte.")) return Intrinsic::arm_neon_vrsqrte;
+    if (NameR.startswith("rm.neon.vrshiftu.")) return Intrinsic::arm_neon_vrshiftu;
+    if (NameR.startswith("rm.neon.vrshifts.")) return Intrinsic::arm_neon_vrshifts;
+    if (NameR.startswith("rm.neon.vrshiftn.")) return Intrinsic::arm_neon_vrshiftn;
+    if (NameR.startswith("rm.neon.vrintz.")) return Intrinsic::arm_neon_vrintz;
+    if (NameR.startswith("rm.neon.vrintx.")) return Intrinsic::arm_neon_vrintx;
+    if (NameR.startswith("rm.neon.vrintp.")) return Intrinsic::arm_neon_vrintp;
+    if (NameR.startswith("rm.neon.vrintn.")) return Intrinsic::arm_neon_vrintn;
+    if (NameR.startswith("rm.neon.vrintm.")) return Intrinsic::arm_neon_vrintm;
+    if (NameR.startswith("rm.neon.vrinta.")) return Intrinsic::arm_neon_vrinta;
+    if (NameR.startswith("rm.neon.vrhaddu.")) return Intrinsic::arm_neon_vrhaddu;
+    if (NameR.startswith("rm.neon.vrhadds.")) return Intrinsic::arm_neon_vrhadds;
+    if (NameR.startswith("rm.neon.vrecps.")) return Intrinsic::arm_neon_vrecps;
+    if (NameR.startswith("rm.neon.vrecpe.")) return Intrinsic::arm_neon_vrecpe;
+    if (NameR.startswith("rm.neon.vraddhn.")) return Intrinsic::arm_neon_vraddhn;
+    if (NameR.startswith("rm.neon.vqsubu.")) return Intrinsic::arm_neon_vqsubu;
+    if (NameR.startswith("rm.neon.vqsubs.")) return Intrinsic::arm_neon_vqsubs;
+    if (NameR.startswith("rm.neon.vqshiftu.")) return Intrinsic::arm_neon_vqshiftu;
+    if (NameR.startswith("rm.neon.vqshiftsu.")) return Intrinsic::arm_neon_vqshiftsu;
+    if (NameR.startswith("rm.neon.vqshifts.")) return Intrinsic::arm_neon_vqshifts;
+    if (NameR.startswith("rm.neon.vqshiftnu.")) return Intrinsic::arm_neon_vqshiftnu;
+    if (NameR.startswith("rm.neon.vqshiftnsu.")) return Intrinsic::arm_neon_vqshiftnsu;
+    if (NameR.startswith("rm.neon.vqshiftns.")) return Intrinsic::arm_neon_vqshiftns;
+    if (NameR.startswith("rm.neon.vqrshiftu.")) return Intrinsic::arm_neon_vqrshiftu;
+    if (NameR.startswith("rm.neon.vqrshifts.")) return Intrinsic::arm_neon_vqrshifts;
+    if (NameR.startswith("rm.neon.vqrshiftnu.")) return Intrinsic::arm_neon_vqrshiftnu;
+    if (NameR.startswith("rm.neon.vqrshiftnsu.")) return Intrinsic::arm_neon_vqrshiftnsu;
+    if (NameR.startswith("rm.neon.vqrshiftns.")) return Intrinsic::arm_neon_vqrshiftns;
+    if (NameR.startswith("rm.neon.vqrdmulh.")) return Intrinsic::arm_neon_vqrdmulh;
+    if (NameR.startswith("rm.neon.vqneg.")) return Intrinsic::arm_neon_vqneg;
+    if (NameR.startswith("rm.neon.vqmovnu.")) return Intrinsic::arm_neon_vqmovnu;
+    if (NameR.startswith("rm.neon.vqmovnsu.")) return Intrinsic::arm_neon_vqmovnsu;
+    if (NameR.startswith("rm.neon.vqmovns.")) return Intrinsic::arm_neon_vqmovns;
+    if (NameR.startswith("rm.neon.vqdmull.")) return Intrinsic::arm_neon_vqdmull;
+    if (NameR.startswith("rm.neon.vqdmulh.")) return Intrinsic::arm_neon_vqdmulh;
+    if (NameR.startswith("rm.neon.vqaddu.")) return Intrinsic::arm_neon_vqaddu;
+    if (NameR.startswith("rm.neon.vqadds.")) return Intrinsic::arm_neon_vqadds;
+    if (NameR.startswith("rm.neon.vqabs.")) return Intrinsic::arm_neon_vqabs;
+    if (NameR.startswith("rm.neon.vpminu.")) return Intrinsic::arm_neon_vpminu;
+    if (NameR.startswith("rm.neon.vpmins.")) return Intrinsic::arm_neon_vpmins;
+    if (NameR.startswith("rm.neon.vpmaxu.")) return Intrinsic::arm_neon_vpmaxu;
+    if (NameR.startswith("rm.neon.vpmaxs.")) return Intrinsic::arm_neon_vpmaxs;
+    if (NameR.startswith("rm.neon.vpaddlu.")) return Intrinsic::arm_neon_vpaddlu;
+    if (NameR.startswith("rm.neon.vpaddls.")) return Intrinsic::arm_neon_vpaddls;
+    if (NameR.startswith("rm.neon.vpadd.")) return Intrinsic::arm_neon_vpadd;
+    if (NameR.startswith("rm.neon.vpadalu.")) return Intrinsic::arm_neon_vpadalu;
+    if (NameR.startswith("rm.neon.vpadals.")) return Intrinsic::arm_neon_vpadals;
+    if (NameR.startswith("rm.neon.vmulp.")) return Intrinsic::arm_neon_vmulp;
+    if (NameR.startswith("rm.neon.vmullu.")) return Intrinsic::arm_neon_vmullu;
+    if (NameR.startswith("rm.neon.vmulls.")) return Intrinsic::arm_neon_vmulls;
+    if (NameR.startswith("rm.neon.vmullp.")) return Intrinsic::arm_neon_vmullp;
+    if (NameR.startswith("rm.neon.vminu.")) return Intrinsic::arm_neon_vminu;
+    if (NameR.startswith("rm.neon.vmins.")) return Intrinsic::arm_neon_vmins;
+    if (NameR.startswith("rm.neon.vminnm.")) return Intrinsic::arm_neon_vminnm;
+    if (NameR.startswith("rm.neon.vmaxu.")) return Intrinsic::arm_neon_vmaxu;
+    if (NameR.startswith("rm.neon.vmaxs.")) return Intrinsic::arm_neon_vmaxs;
+    if (NameR.startswith("rm.neon.vmaxnm.")) return Intrinsic::arm_neon_vmaxnm;
+    if (NameR.startswith("rm.neon.vld4lane.")) return Intrinsic::arm_neon_vld4lane;
+    if (NameR.startswith("rm.neon.vld4.")) return Intrinsic::arm_neon_vld4;
+    if (NameR.startswith("rm.neon.vld3lane.")) return Intrinsic::arm_neon_vld3lane;
+    if (NameR.startswith("rm.neon.vld3.")) return Intrinsic::arm_neon_vld3;
+    if (NameR.startswith("rm.neon.vld2lane.")) return Intrinsic::arm_neon_vld2lane;
+    if (NameR.startswith("rm.neon.vld2.")) return Intrinsic::arm_neon_vld2;
+    if (NameR.startswith("rm.neon.vld1.")) return Intrinsic::arm_neon_vld1;
+    if (NameR.startswith("rm.neon.vhsubu.")) return Intrinsic::arm_neon_vhsubu;
+    if (NameR.startswith("rm.neon.vhsubs.")) return Intrinsic::arm_neon_vhsubs;
+    if (NameR.startswith("rm.neon.vhaddu.")) return Intrinsic::arm_neon_vhaddu;
+    if (NameR.startswith("rm.neon.vhadds.")) return Intrinsic::arm_neon_vhadds;
+    if (NameR.startswith("rm.neon.vcvtpu.")) return Intrinsic::arm_neon_vcvtpu;
+    if (NameR.startswith("rm.neon.vcvtps.")) return Intrinsic::arm_neon_vcvtps;
+    if (NameR.startswith("rm.neon.vcvtnu.")) return Intrinsic::arm_neon_vcvtnu;
+    if (NameR.startswith("rm.neon.vcvtns.")) return Intrinsic::arm_neon_vcvtns;
+    if (NameR.startswith("rm.neon.vcvtmu.")) return Intrinsic::arm_neon_vcvtmu;
+    if (NameR.startswith("rm.neon.vcvtms.")) return Intrinsic::arm_neon_vcvtms;
+    if (NameR.startswith("rm.neon.vcvtfxu2fp.")) return Intrinsic::arm_neon_vcvtfxu2fp;
+    if (NameR.startswith("rm.neon.vcvtfxs2fp.")) return Intrinsic::arm_neon_vcvtfxs2fp;
+    if (NameR.startswith("rm.neon.vcvtfp2fxu.")) return Intrinsic::arm_neon_vcvtfp2fxu;
+    if (NameR.startswith("rm.neon.vcvtfp2fxs.")) return Intrinsic::arm_neon_vcvtfp2fxs;
+    if (NameR.startswith("rm.neon.vcvtau.")) return Intrinsic::arm_neon_vcvtau;
+    if (NameR.startswith("rm.neon.vcvtas.")) return Intrinsic::arm_neon_vcvtas;
+    if (NameR.startswith("rm.neon.vcnt.")) return Intrinsic::arm_neon_vcnt;
+    if (NameR.startswith("rm.neon.vclz.")) return Intrinsic::arm_neon_vclz;
+    if (NameR.startswith("rm.neon.vcls.")) return Intrinsic::arm_neon_vcls;
+    if (NameR.startswith("rm.neon.vbsl.")) return Intrinsic::arm_neon_vbsl;
+    if (NameR.startswith("rm.neon.vacgt.")) return Intrinsic::arm_neon_vacgt;
+    if (NameR.startswith("rm.neon.vacge.")) return Intrinsic::arm_neon_vacge;
+    if (NameR.startswith("rm.neon.vabs.")) return Intrinsic::arm_neon_vabs;
+    if (NameR.startswith("rm.neon.vabdu.")) return Intrinsic::arm_neon_vabdu;
+    if (NameR.startswith("rm.neon.vabds.")) return Intrinsic::arm_neon_vabds;
+    if (NameR.startswith("rm.ldrex.")) return Intrinsic::arm_ldrex;
+    if (NameR.startswith("rm.ldaex.")) return Intrinsic::arm_ldaex;
+    if (NameR.startswith("nnotation.")) return Intrinsic::annotation;
+    if (NameR.startswith("arch64.udiv.")) return Intrinsic::aarch64_udiv;
+    if (NameR.startswith("arch64.stxr.")) return Intrinsic::aarch64_stxr;
+    if (NameR.startswith("arch64.stlxr.")) return Intrinsic::aarch64_stlxr;
+    if (NameR.startswith("arch64.sisd.fabd.")) return Intrinsic::aarch64_sisd_fabd;
+    if (NameR.startswith("arch64.sdiv.")) return Intrinsic::aarch64_sdiv;
+    if (NameR.startswith("arch64.rbit.")) return Intrinsic::aarch64_rbit;
+    if (NameR.startswith("arch64.neon.vsri.")) return Intrinsic::aarch64_neon_vsri;
+    if (NameR.startswith("arch64.neon.vsli.")) return Intrinsic::aarch64_neon_vsli;
+    if (NameR.startswith("arch64.neon.vcvtfxu2fp.")) return Intrinsic::aarch64_neon_vcvtfxu2fp;
+    if (NameR.startswith("arch64.neon.vcvtfxs2fp.")) return Intrinsic::aarch64_neon_vcvtfxs2fp;
+    if (NameR.startswith("arch64.neon.vcvtfp2fxu.")) return Intrinsic::aarch64_neon_vcvtfp2fxu;
+    if (NameR.startswith("arch64.neon.vcvtfp2fxs.")) return Intrinsic::aarch64_neon_vcvtfp2fxs;
+    if (NameR.startswith("arch64.neon.vcopy.lane.")) return Intrinsic::aarch64_neon_vcopy_lane;
+    if (NameR.startswith("arch64.neon.usqadd.")) return Intrinsic::aarch64_neon_usqadd;
+    if (NameR.startswith("arch64.neon.ushll.")) return Intrinsic::aarch64_neon_ushll;
+    if (NameR.startswith("arch64.neon.ushl.")) return Intrinsic::aarch64_neon_ushl;
+    if (NameR.startswith("arch64.neon.ursqrte.")) return Intrinsic::aarch64_neon_ursqrte;
+    if (NameR.startswith("arch64.neon.urshl.")) return Intrinsic::aarch64_neon_urshl;
+    if (NameR.startswith("arch64.neon.urhadd.")) return Intrinsic::aarch64_neon_urhadd;
+    if (NameR.startswith("arch64.neon.urecpe.")) return Intrinsic::aarch64_neon_urecpe;
+    if (NameR.startswith("arch64.neon.uqxtn.")) return Intrinsic::aarch64_neon_uqxtn;
+    if (NameR.startswith("arch64.neon.uqsub.")) return Intrinsic::aarch64_neon_uqsub;
+    if (NameR.startswith("arch64.neon.uqshrn.")) return Intrinsic::aarch64_neon_uqshrn;
+    if (NameR.startswith("arch64.neon.uqshl.")) return Intrinsic::aarch64_neon_uqshl;
+    if (NameR.startswith("arch64.neon.uqrshrn.")) return Intrinsic::aarch64_neon_uqrshrn;
+    if (NameR.startswith("arch64.neon.uqrshl.")) return Intrinsic::aarch64_neon_uqrshl;
+    if (NameR.startswith("arch64.neon.uqadd.")) return Intrinsic::aarch64_neon_uqadd;
+    if (NameR.startswith("arch64.neon.umull.")) return Intrinsic::aarch64_neon_umull;
+    if (NameR.startswith("arch64.neon.uminv.")) return Intrinsic::aarch64_neon_uminv;
+    if (NameR.startswith("arch64.neon.uminp.")) return Intrinsic::aarch64_neon_uminp;
+    if (NameR.startswith("arch64.neon.umin.")) return Intrinsic::aarch64_neon_umin;
+    if (NameR.startswith("arch64.neon.umaxv.")) return Intrinsic::aarch64_neon_umaxv;
+    if (NameR.startswith("arch64.neon.umaxp.")) return Intrinsic::aarch64_neon_umaxp;
+    if (NameR.startswith("arch64.neon.umax.")) return Intrinsic::aarch64_neon_umax;
+    if (NameR.startswith("arch64.neon.uhsub.")) return Intrinsic::aarch64_neon_uhsub;
+    if (NameR.startswith("arch64.neon.uhadd.")) return Intrinsic::aarch64_neon_uhadd;
+    if (NameR.startswith("arch64.neon.uaddv.")) return Intrinsic::aarch64_neon_uaddv;
+    if (NameR.startswith("arch64.neon.uaddlv.")) return Intrinsic::aarch64_neon_uaddlv;
+    if (NameR.startswith("arch64.neon.uaddlp.")) return Intrinsic::aarch64_neon_uaddlp;
+    if (NameR.startswith("arch64.neon.uabd.")) return Intrinsic::aarch64_neon_uabd;
+    if (NameR.startswith("arch64.neon.tbx4.")) return Intrinsic::aarch64_neon_tbx4;
+    if (NameR.startswith("arch64.neon.tbx3.")) return Intrinsic::aarch64_neon_tbx3;
+    if (NameR.startswith("arch64.neon.tbx2.")) return Intrinsic::aarch64_neon_tbx2;
+    if (NameR.startswith("arch64.neon.tbx1.")) return Intrinsic::aarch64_neon_tbx1;
+    if (NameR.startswith("arch64.neon.tbl4.")) return Intrinsic::aarch64_neon_tbl4;
+    if (NameR.startswith("arch64.neon.tbl3.")) return Intrinsic::aarch64_neon_tbl3;
+    if (NameR.startswith("arch64.neon.tbl2.")) return Intrinsic::aarch64_neon_tbl2;
+    if (NameR.startswith("arch64.neon.tbl1.")) return Intrinsic::aarch64_neon_tbl1;
+    if (NameR.startswith("arch64.neon.suqadd.")) return Intrinsic::aarch64_neon_suqadd;
+    if (NameR.startswith("arch64.neon.subhn.")) return Intrinsic::aarch64_neon_subhn;
+    if (NameR.startswith("arch64.neon.st4lane.")) return Intrinsic::aarch64_neon_st4lane;
+    if (NameR.startswith("arch64.neon.st4.")) return Intrinsic::aarch64_neon_st4;
+    if (NameR.startswith("arch64.neon.st3lane.")) return Intrinsic::aarch64_neon_st3lane;
+    if (NameR.startswith("arch64.neon.st3.")) return Intrinsic::aarch64_neon_st3;
+    if (NameR.startswith("arch64.neon.st2lane.")) return Intrinsic::aarch64_neon_st2lane;
+    if (NameR.startswith("arch64.neon.st2.")) return Intrinsic::aarch64_neon_st2;
+    if (NameR.startswith("arch64.neon.st1x4.")) return Intrinsic::aarch64_neon_st1x4;
+    if (NameR.startswith("arch64.neon.st1x3.")) return Intrinsic::aarch64_neon_st1x3;
+    if (NameR.startswith("arch64.neon.st1x2.")) return Intrinsic::aarch64_neon_st1x2;
+    if (NameR.startswith("arch64.neon.sshll.")) return Intrinsic::aarch64_neon_sshll;
+    if (NameR.startswith("arch64.neon.sshl.")) return Intrinsic::aarch64_neon_sshl;
+    if (NameR.startswith("arch64.neon.srshl.")) return Intrinsic::aarch64_neon_srshl;
+    if (NameR.startswith("arch64.neon.srhadd.")) return Intrinsic::aarch64_neon_srhadd;
+    if (NameR.startswith("arch64.neon.sqxtun.")) return Intrinsic::aarch64_neon_sqxtun;
+    if (NameR.startswith("arch64.neon.sqxtn.")) return Intrinsic::aarch64_neon_sqxtn;
+    if (NameR.startswith("arch64.neon.sqsub.")) return Intrinsic::aarch64_neon_sqsub;
+    if (NameR.startswith("arch64.neon.sqshrun.")) return Intrinsic::aarch64_neon_sqshrun;
+    if (NameR.startswith("arch64.neon.sqshrn.")) return Intrinsic::aarch64_neon_sqshrn;
+    if (NameR.startswith("arch64.neon.sqshlu.")) return Intrinsic::aarch64_neon_sqshlu;
+    if (NameR.startswith("arch64.neon.sqshl.")) return Intrinsic::aarch64_neon_sqshl;
+    if (NameR.startswith("arch64.neon.sqrshrun.")) return Intrinsic::aarch64_neon_sqrshrun;
+    if (NameR.startswith("arch64.neon.sqrshrn.")) return Intrinsic::aarch64_neon_sqrshrn;
+    if (NameR.startswith("arch64.neon.sqrshl.")) return Intrinsic::aarch64_neon_sqrshl;
+    if (NameR.startswith("arch64.neon.sqrdmulh.")) return Intrinsic::aarch64_neon_sqrdmulh;
+    if (NameR.startswith("arch64.neon.sqneg.")) return Intrinsic::aarch64_neon_sqneg;
+    if (NameR.startswith("arch64.neon.sqdmull.")) return Intrinsic::aarch64_neon_sqdmull;
+    if (NameR.startswith("arch64.neon.sqdmulh.")) return Intrinsic::aarch64_neon_sqdmulh;
+    if (NameR.startswith("arch64.neon.sqadd.")) return Intrinsic::aarch64_neon_sqadd;
+    if (NameR.startswith("arch64.neon.sqabs.")) return Intrinsic::aarch64_neon_sqabs;
+    if (NameR.startswith("arch64.neon.smull.")) return Intrinsic::aarch64_neon_smull;
+    if (NameR.startswith("arch64.neon.sminv.")) return Intrinsic::aarch64_neon_sminv;
+    if (NameR.startswith("arch64.neon.sminp.")) return Intrinsic::aarch64_neon_sminp;
+    if (NameR.startswith("arch64.neon.smin.")) return Intrinsic::aarch64_neon_smin;
+    if (NameR.startswith("arch64.neon.smaxv.")) return Intrinsic::aarch64_neon_smaxv;
+    if (NameR.startswith("arch64.neon.smaxp.")) return Intrinsic::aarch64_neon_smaxp;
+    if (NameR.startswith("arch64.neon.smax.")) return Intrinsic::aarch64_neon_smax;
+    if (NameR.startswith("arch64.neon.shsub.")) return Intrinsic::aarch64_neon_shsub;
+    if (NameR.startswith("arch64.neon.shll.")) return Intrinsic::aarch64_neon_shll;
+    if (NameR.startswith("arch64.neon.shadd.")) return Intrinsic::aarch64_neon_shadd;
+    if (NameR.startswith("arch64.neon.scalar.uqxtn.")) return Intrinsic::aarch64_neon_scalar_uqxtn;
+    if (NameR.startswith("arch64.neon.scalar.sqxtun.")) return Intrinsic::aarch64_neon_scalar_sqxtun;
+    if (NameR.startswith("arch64.neon.scalar.sqxtn.")) return Intrinsic::aarch64_neon_scalar_sqxtn;
+    if (NameR.startswith("arch64.neon.saddv.")) return Intrinsic::aarch64_neon_saddv;
+    if (NameR.startswith("arch64.neon.saddlv.")) return Intrinsic::aarch64_neon_saddlv;
+    if (NameR.startswith("arch64.neon.saddlp.")) return Intrinsic::aarch64_neon_saddlp;
+    if (NameR.startswith("arch64.neon.sabd.")) return Intrinsic::aarch64_neon_sabd;
+    if (NameR.startswith("arch64.neon.rsubhn.")) return Intrinsic::aarch64_neon_rsubhn;
+    if (NameR.startswith("arch64.neon.rshrn.")) return Intrinsic::aarch64_neon_rshrn;
+    if (NameR.startswith("arch64.neon.rbit.")) return Intrinsic::aarch64_neon_rbit;
+    if (NameR.startswith("arch64.neon.raddhn.")) return Intrinsic::aarch64_neon_raddhn;
+    if (NameR.startswith("arch64.neon.pmull.")) return Intrinsic::aarch64_neon_pmull;
+    if (NameR.startswith("arch64.neon.pmul.")) return Intrinsic::aarch64_neon_pmul;
+    if (NameR.startswith("arch64.neon.ld4r.")) return Intrinsic::aarch64_neon_ld4r;
+    if (NameR.startswith("arch64.neon.ld4lane.")) return Intrinsic::aarch64_neon_ld4lane;
+    if (NameR.startswith("arch64.neon.ld4.")) return Intrinsic::aarch64_neon_ld4;
+    if (NameR.startswith("arch64.neon.ld3r.")) return Intrinsic::aarch64_neon_ld3r;
+    if (NameR.startswith("arch64.neon.ld3lane.")) return Intrinsic::aarch64_neon_ld3lane;
+    if (NameR.startswith("arch64.neon.ld3.")) return Intrinsic::aarch64_neon_ld3;
+    if (NameR.startswith("arch64.neon.ld2r.")) return Intrinsic::aarch64_neon_ld2r;
+    if (NameR.startswith("arch64.neon.ld2lane.")) return Intrinsic::aarch64_neon_ld2lane;
+    if (NameR.startswith("arch64.neon.ld2.")) return Intrinsic::aarch64_neon_ld2;
+    if (NameR.startswith("arch64.neon.ld1x4.")) return Intrinsic::aarch64_neon_ld1x4;
+    if (NameR.startswith("arch64.neon.ld1x3.")) return Intrinsic::aarch64_neon_ld1x3;
+    if (NameR.startswith("arch64.neon.ld1x2.")) return Intrinsic::aarch64_neon_ld1x2;
+    if (NameR.startswith("arch64.neon.frsqrts.")) return Intrinsic::aarch64_neon_frsqrts;
+    if (NameR.startswith("arch64.neon.frsqrte.")) return Intrinsic::aarch64_neon_frsqrte;
+    if (NameR.startswith("arch64.neon.frintn.")) return Intrinsic::aarch64_neon_frintn;
+    if (NameR.startswith("arch64.neon.frecpx.")) return Intrinsic::aarch64_neon_frecpx;
+    if (NameR.startswith("arch64.neon.frecps.")) return Intrinsic::aarch64_neon_frecps;
+    if (NameR.startswith("arch64.neon.frecpe.")) return Intrinsic::aarch64_neon_frecpe;
+    if (NameR.startswith("arch64.neon.fmulx.")) return Intrinsic::aarch64_neon_fmulx;
+    if (NameR.startswith("arch64.neon.fminv.")) return Intrinsic::aarch64_neon_fminv;
+    if (NameR.startswith("arch64.neon.fminp.")) return Intrinsic::aarch64_neon_fminp;
+    if (NameR.startswith("arch64.neon.fminnmv.")) return Intrinsic::aarch64_neon_fminnmv;
+    if (NameR.startswith("arch64.neon.fminnmp.")) return Intrinsic::aarch64_neon_fminnmp;
+    if (NameR.startswith("arch64.neon.fminnm.")) return Intrinsic::aarch64_neon_fminnm;
+    if (NameR.startswith("arch64.neon.fmin.")) return Intrinsic::aarch64_neon_fmin;
+    if (NameR.startswith("arch64.neon.fmaxv.")) return Intrinsic::aarch64_neon_fmaxv;
+    if (NameR.startswith("arch64.neon.fmaxp.")) return Intrinsic::aarch64_neon_fmaxp;
+    if (NameR.startswith("arch64.neon.fmaxnmv.")) return Intrinsic::aarch64_neon_fmaxnmv;
+    if (NameR.startswith("arch64.neon.fmaxnmp.")) return Intrinsic::aarch64_neon_fmaxnmp;
+    if (NameR.startswith("arch64.neon.fmaxnm.")) return Intrinsic::aarch64_neon_fmaxnm;
+    if (NameR.startswith("arch64.neon.fmax.")) return Intrinsic::aarch64_neon_fmax;
+    if (NameR.startswith("arch64.neon.fcvtzu.")) return Intrinsic::aarch64_neon_fcvtzu;
+    if (NameR.startswith("arch64.neon.fcvtzs.")) return Intrinsic::aarch64_neon_fcvtzs;
+    if (NameR.startswith("arch64.neon.fcvtxn.")) return Intrinsic::aarch64_neon_fcvtxn;
+    if (NameR.startswith("arch64.neon.fcvtpu.")) return Intrinsic::aarch64_neon_fcvtpu;
+    if (NameR.startswith("arch64.neon.fcvtps.")) return Intrinsic::aarch64_neon_fcvtps;
+    if (NameR.startswith("arch64.neon.fcvtnu.")) return Intrinsic::aarch64_neon_fcvtnu;
+    if (NameR.startswith("arch64.neon.fcvtns.")) return Intrinsic::aarch64_neon_fcvtns;
+    if (NameR.startswith("arch64.neon.fcvtmu.")) return Intrinsic::aarch64_neon_fcvtmu;
+    if (NameR.startswith("arch64.neon.fcvtms.")) return Intrinsic::aarch64_neon_fcvtms;
+    if (NameR.startswith("arch64.neon.fcvtau.")) return Intrinsic::aarch64_neon_fcvtau;
+    if (NameR.startswith("arch64.neon.fcvtas.")) return Intrinsic::aarch64_neon_fcvtas;
+    if (NameR.startswith("arch64.neon.faddv.")) return Intrinsic::aarch64_neon_faddv;
+    if (NameR.startswith("arch64.neon.facgt.")) return Intrinsic::aarch64_neon_facgt;
+    if (NameR.startswith("arch64.neon.facge.")) return Intrinsic::aarch64_neon_facge;
+    if (NameR.startswith("arch64.neon.fabd.")) return Intrinsic::aarch64_neon_fabd;
+    if (NameR.startswith("arch64.neon.cls.")) return Intrinsic::aarch64_neon_cls;
+    if (NameR.startswith("arch64.neon.addp.")) return Intrinsic::aarch64_neon_addp;
+    if (NameR.startswith("arch64.neon.addhn.")) return Intrinsic::aarch64_neon_addhn;
+    if (NameR.startswith("arch64.neon.abs.")) return Intrinsic::aarch64_neon_abs;
+    if (NameR.startswith("arch64.ldxr.")) return Intrinsic::aarch64_ldxr;
+    if (NameR.startswith("arch64.ldaxr.")) return Intrinsic::aarch64_ldaxr;
+    switch (NameR.size()) {
+    default: break;
+    case 6:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "rm.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "dp", 2))
+          break;
+        return Intrinsic::arm_cdp;	 // "rm.cdp"
+      case 'd':	 // 2 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (NameR[5] != 'b')
+            break;
+          return Intrinsic::arm_dmb;	 // "rm.dmb"
+        case 's':	 // 1 string to match.
+          if (NameR[5] != 'b')
+            break;
+          return Intrinsic::arm_dsb;	 // "rm.dsb"
+        }
+        break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "sb", 2))
+          break;
+        return Intrinsic::arm_isb;	 // "rm.isb"
+      case 'm':	 // 2 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (NameR[5] != 'r')
+            break;
+          return Intrinsic::arm_mcr;	 // "rm.mcr"
+        case 'r':	 // 1 string to match.
+          if (NameR[5] != 'c')
+            break;
+          return Intrinsic::arm_mrc;	 // "rm.mrc"
+        }
+        break;
+      }
+      break;
+    case 7:	 // 10 strings to match.
+      if (memcmp(NameR.data()+0, "rm.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "dp2", 3))
+          break;
+        return Intrinsic::arm_cdp2;	 // "rm.cdp2"
+      case 'h':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "int", 3))
+          break;
+        return Intrinsic::arm_hint;	 // "rm.hint"
+      case 'm':	 // 3 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (NameR[5] != 'r')
+            break;
+          switch (NameR[6]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            return Intrinsic::arm_mcr2;	 // "rm.mcr2"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::arm_mcrr;	 // "rm.mcrr"
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+5, "c2", 2))
+            break;
+          return Intrinsic::arm_mrc2;	 // "rm.mrc2"
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+5, "dd", 2))
+            break;
+          return Intrinsic::arm_qadd;	 // "rm.qadd"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+5, "ub", 2))
+            break;
+          return Intrinsic::arm_qsub;	 // "rm.qsub"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "bit", 3))
+          break;
+        return Intrinsic::arm_rbit;	 // "rm.rbit"
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "sat", 3))
+          break;
+        return Intrinsic::arm_ssat;	 // "rm.ssat"
+      case 'u':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "sat", 3))
+          break;
+        return Intrinsic::arm_usat;	 // "rm.usat"
+      }
+      break;
+    case 8:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "rm.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "lrex", 4))
+          break;
+        return Intrinsic::arm_clrex;	 // "rm.clrex"
+      case 'm':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "crr2", 4))
+          break;
+        return Intrinsic::arm_mcrr2;	 // "rm.mcrr2"
+      }
+      break;
+    case 9:	 // 7 strings to match.
+      if (memcmp(NameR.data()+0, "rm.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+4, "rc32", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::arm_crc32b;	 // "rm.crc32b"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::arm_crc32h;	 // "rm.crc32h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::arm_crc32w;	 // "rm.crc32w"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        if (NameR[4] != 'd')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "exd", 3))
+            break;
+          return Intrinsic::arm_ldaexd;	 // "rm.ldaexd"
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "exd", 3))
+            break;
+          return Intrinsic::arm_ldrexd;	 // "rm.ldrexd"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (NameR[4] != 't')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "exd", 3))
+            break;
+          return Intrinsic::arm_stlexd;	 // "rm.stlexd"
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "exd", 3))
+            break;
+          return Intrinsic::arm_strexd;	 // "rm.strexd"
+        }
+        break;
+      }
+      break;
+    case 10:	 // 6 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        if (memcmp(NameR.data()+1, "rch64.", 6))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          switch (NameR[8]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (NameR[9] != 'b')
+              break;
+            return Intrinsic::aarch64_dmb;	 // "arch64.dmb"
+          case 's':	 // 1 string to match.
+            if (NameR[9] != 'b')
+              break;
+            return Intrinsic::aarch64_dsb;	 // "arch64.dsb"
+          }
+          break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "sb", 2))
+            break;
+          return Intrinsic::aarch64_isb;	 // "arch64.isb"
+        }
+        break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(NameR.data()+1, "m.crc32c", 8))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::arm_crc32cb;	 // "rm.crc32cb"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::arm_crc32ch;	 // "rm.crc32ch"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::arm_crc32cw;	 // "rm.crc32cw"
+        }
+        break;
+      }
+      break;
+    case 11:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "arch64.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "int", 3))
+          break;
+        return Intrinsic::aarch64_hint;	 // "arch64.hint"
+      case 'l':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "dxp", 3))
+          break;
+        return Intrinsic::aarch64_ldxp;	 // "arch64.ldxp"
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "txp", 3))
+          break;
+        return Intrinsic::aarch64_stxp;	 // "arch64.stxp"
+      }
+      break;
+    case 12:	 // 8 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        if (memcmp(NameR.data()+1, "rch64.", 6))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "lrex", 4))
+            break;
+          return Intrinsic::aarch64_clrex;	 // "arch64.clrex"
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "daxp", 4))
+            break;
+          return Intrinsic::aarch64_ldaxp;	 // "arch64.ldaxp"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "tlxp", 4))
+            break;
+          return Intrinsic::aarch64_stlxp;	 // "arch64.stlxp"
+        }
+        break;
+      case 'r':	 // 5 strings to match.
+        if (memcmp(NameR.data()+1, "m.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case 'g':	 // 1 string to match.
+          if (memcmp(NameR.data()+4, "et.fpscr", 8))
+            break;
+          return Intrinsic::arm_get_fpscr;	 // "rm.get.fpscr"
+        case 'n':	 // 2 strings to match.
+          if (memcmp(NameR.data()+4, "eon.aes", 7))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::arm_neon_aesd;	 // "rm.neon.aesd"
+          case 'e':	 // 1 string to match.
+            return Intrinsic::arm_neon_aese;	 // "rm.neon.aese"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+4, "et.fpscr", 8))
+            break;
+          return Intrinsic::arm_set_fpscr;	 // "rm.set.fpscr"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+4, "ndefined", 8))
+            break;
+          return Intrinsic::arm_undefined;	 // "rm.undefined"
+        }
+        break;
+      }
+      break;
+    case 13:	 // 17 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(NameR.data()+1, "rch64.crc32", 11))
+          break;
+        switch (NameR[12]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32b;	 // "arch64.crc32b"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32h;	 // "arch64.crc32h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32w;	 // "arch64.crc32w"
+        case 'x':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32x;	 // "arch64.crc32x"
+        }
+        break;
+      case 'r':	 // 13 strings to match.
+        if (memcmp(NameR.data()+1, "m.neon.", 7))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "esmc", 4))
+            break;
+          return Intrinsic::arm_neon_aesmc;	 // "rm.neon.aesmc"
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, "ha1", 3))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha1c;	 // "rm.neon.sha1c"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha1h;	 // "rm.neon.sha1h"
+          case 'm':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha1m;	 // "rm.neon.sha1m"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha1p;	 // "rm.neon.sha1p"
+          }
+          break;
+        case 'v':	 // 8 strings to match.
+          if (memcmp(NameR.data()+9, "tb", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[12]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbl1;	 // "rm.neon.vtbl1"
+            case '2':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbl2;	 // "rm.neon.vtbl2"
+            case '3':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbl3;	 // "rm.neon.vtbl3"
+            case '4':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbl4;	 // "rm.neon.vtbl4"
+            }
+            break;
+          case 'x':	 // 4 strings to match.
+            switch (NameR[12]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbx1;	 // "rm.neon.vtbx1"
+            case '2':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbx2;	 // "rm.neon.vtbx2"
+            case '3':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbx3;	 // "rm.neon.vtbx3"
+            case '4':	 // 1 string to match.
+              return Intrinsic::arm_neon_vtbx4;	 // "rm.neon.vtbx4"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 14:	 // 5 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(NameR.data()+1, "rch64.crc32c", 12))
+          break;
+        switch (NameR[13]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32cb;	 // "arch64.crc32cb"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32ch;	 // "arch64.crc32ch"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32cw;	 // "arch64.crc32cw"
+        case 'x':	 // 1 string to match.
+          return Intrinsic::aarch64_crc32cx;	 // "arch64.crc32cx"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "m.neon.aesimc", 13))
+          break;
+        return Intrinsic::arm_neon_aesimc;	 // "rm.neon.aesimc"
+      }
+      break;
+    case 15:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "rm.neon.sha", 11))
+        break;
+      switch (NameR[11]) {
+      default: break;
+      case '1':	 // 2 strings to match.
+        if (memcmp(NameR.data()+12, "su", 2))
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::arm_neon_sha1su0;	 // "rm.neon.sha1su0"
+        case '1':	 // 1 string to match.
+          return Intrinsic::arm_neon_sha1su1;	 // "rm.neon.sha1su1"
+        }
+        break;
+      case '2':	 // 1 string to match.
+        if (memcmp(NameR.data()+12, "56h", 3))
+          break;
+        return Intrinsic::arm_neon_sha256h;	 // "rm.neon.sha256h"
+      }
+      break;
+    case 16:	 // 2 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "just.trampoline", 15))
+          break;
+        return Intrinsic::adjust_trampoline;	 // "djust.trampoline"
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "m.neon.sha256h2", 15))
+          break;
+        return Intrinsic::arm_neon_sha256h2;	 // "rm.neon.sha256h2"
+      }
+      break;
+    case 17:	 // 5 strings to match.
+      if (memcmp(NameR.data()+0, "rm.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'n':	 // 4 strings to match.
+        if (memcmp(NameR.data()+4, "eon.", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, "ha256su", 7))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha256su0;	 // "rm.neon.sha256su0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::arm_neon_sha256su1;	 // "rm.neon.sha256su1"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, "cvt", 3))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "p2hf", 4))
+              break;
+            return Intrinsic::arm_neon_vcvtfp2hf;	 // "rm.neon.vcvtfp2hf"
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "f2fp", 4))
+              break;
+            return Intrinsic::arm_neon_vcvthf2fp;	 // "rm.neon.vcvthf2fp"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "hread.pointer", 13))
+          break;
+        return Intrinsic::arm_thread_pointer;	 // "rm.thread.pointer"
+      }
+      break;
+    case 18:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "arch64.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(NameR.data()+8, "rypto.aes", 9))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::aarch64_crypto_aesd;	 // "arch64.crypto.aesd"
+        case 'e':	 // 1 string to match.
+          return Intrinsic::aarch64_crypto_aese;	 // "arch64.crypto.aese"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "isd.fcvtxn", 10))
+          break;
+        return Intrinsic::aarch64_sisd_fcvtxn;	 // "arch64.sisd.fcvtxn"
+      }
+      break;
+    case 19:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "arch64.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'c':	 // 5 strings to match.
+        if (memcmp(NameR.data()+8, "rypto.", 6))
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+15, "esmc", 4))
+            break;
+          return Intrinsic::aarch64_crypto_aesmc;	 // "arch64.crypto.aesmc"
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+15, "ha1", 3))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1c;	 // "arch64.crypto.sha1c"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1h;	 // "arch64.crypto.sha1h"
+          case 'm':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1m;	 // "arch64.crypto.sha1m"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1p;	 // "arch64.crypto.sha1p"
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "eon.pmull64", 11))
+          break;
+        return Intrinsic::aarch64_neon_pmull64;	 // "arch64.neon.pmull64"
+      }
+      break;
+    case 20:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "arch64.crypto.aesimc", 20))
+        break;
+      return Intrinsic::aarch64_crypto_aesimc;	 // "arch64.crypto.aesimc"
+    case 21:	 // 5 strings to match.
+      if (memcmp(NameR.data()+0, "arch64.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+8, "rypto.sha", 9))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case '1':	 // 2 strings to match.
+          if (memcmp(NameR.data()+18, "su", 2))
+            break;
+          switch (NameR[20]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1su0;	 // "arch64.crypto.sha1su0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::aarch64_crypto_sha1su1;	 // "arch64.crypto.sha1su1"
+          }
+          break;
+        case '2':	 // 1 string to match.
+          if (memcmp(NameR.data()+18, "56h", 3))
+            break;
+          return Intrinsic::aarch64_crypto_sha256h;	 // "arch64.crypto.sha256h"
+        }
+        break;
+      case 'n':	 // 2 strings to match.
+        if (memcmp(NameR.data()+8, "eon.vcvt", 8))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+17, "p2hf", 4))
+            break;
+          return Intrinsic::aarch64_neon_vcvtfp2hf;	 // "arch64.neon.vcvtfp2hf"
+        case 'h':	 // 1 string to match.
+          if (memcmp(NameR.data()+17, "f2fp", 4))
+            break;
+          return Intrinsic::aarch64_neon_vcvthf2fp;	 // "arch64.neon.vcvthf2fp"
+        }
+        break;
+      }
+      break;
+    case 22:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "arch64.crypto.sha256h2", 22))
+        break;
+      return Intrinsic::aarch64_crypto_sha256h2;	 // "arch64.crypto.sha256h2"
+    case 23:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "arch64.crypto.sha256su", 22))
+        break;
+      switch (NameR[22]) {
+      default: break;
+      case '0':	 // 1 string to match.
+        return Intrinsic::aarch64_crypto_sha256su0;	 // "arch64.crypto.sha256su0"
+      case '1':	 // 1 string to match.
+        return Intrinsic::aarch64_crypto_sha256su1;	 // "arch64.crypto.sha256su1"
+      }
+      break;
+    case 27:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "arch64.neon.sqdmulls.scalar", 27))
+        break;
+      return Intrinsic::aarch64_neon_sqdmulls_scalar;	 // "arch64.neon.sqdmulls.scalar"
+    }
+    break;  // end of 'a' case.
+  case 'b':
+    if (NameR.startswith("swap.")) return Intrinsic::bswap;
+    break;  // end of 'b' case.
+  case 'c':
+    if (NameR.startswith("ttz.")) return Intrinsic::cttz;
+    if (NameR.startswith("tpop.")) return Intrinsic::ctpop;
+    if (NameR.startswith("tlz.")) return Intrinsic::ctlz;
+    if (NameR.startswith("os.")) return Intrinsic::cos;
+    if (NameR.startswith("opysign.")) return Intrinsic::copysign;
+    if (NameR.startswith("onvertuu.")) return Intrinsic::convertuu;
+    if (NameR.startswith("onvertus.")) return Intrinsic::convertus;
+    if (NameR.startswith("onvertuif.")) return Intrinsic::convertuif;
+    if (NameR.startswith("onvertsu.")) return Intrinsic::convertsu;
+    if (NameR.startswith("onvertss.")) return Intrinsic::convertss;
+    if (NameR.startswith("onvertsif.")) return Intrinsic::convertsif;
+    if (NameR.startswith("onvertfui.")) return Intrinsic::convertfui;
+    if (NameR.startswith("onvertfsi.")) return Intrinsic::convertfsi;
+    if (NameR.startswith("onvertff.")) return Intrinsic::convertff;
+    if (NameR.startswith("onvert.to.fp16.")) return Intrinsic::convert_to_fp16;
+    if (NameR.startswith("onvert.from.fp16.")) return Intrinsic::convert_from_fp16;
+    if (NameR.startswith("eil.")) return Intrinsic::ceil;
+    switch (NameR.size()) {
+    default: break;
+    case 10:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "lear_cache", 10))
+        break;
+      return Intrinsic::clear_cache;	 // "lear_cache"
+    case 15:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "uda.syncthreads", 15))
+        break;
+      return Intrinsic::cuda_syncthreads;	 // "uda.syncthreads"
+    }
+    break;  // end of 'c' case.
+  case 'd':
+    switch (NameR.size()) {
+    default: break;
+    case 8:	 // 3 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "g.value", 7))
+          break;
+        return Intrinsic::dbg_value;	 // "bg.value"
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "bugtrap", 7))
+          break;
+        return Intrinsic::debugtrap;	 // "ebugtrap"
+      case 'o':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "nothing", 7))
+          break;
+        return Intrinsic::donothing;	 // "onothing"
+      }
+      break;
+    case 10:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "bg.declare", 10))
+        break;
+      return Intrinsic::dbg_declare;	 // "bg.declare"
+    }
+    break;  // end of 'd' case.
+  case 'e':
+    if (NameR.startswith("xpect.")) return Intrinsic::expect;
+    if (NameR.startswith("xp2.")) return Intrinsic::exp2;
+    if (NameR.startswith("xp.")) return Intrinsic::exp;
+    switch (NameR.size()) {
+    default: break;
+    case 11:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "h.", 2))
+        break;
+      switch (NameR[2]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "warf.cfa", 8))
+          break;
+        return Intrinsic::eh_dwarf_cfa;	 // "h.dwarf.cfa"
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "jlj.lsda", 8))
+          break;
+        return Intrinsic::eh_sjlj_lsda;	 // "h.sjlj.lsda"
+      }
+      break;
+    case 12:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "h.", 2))
+        break;
+      switch (NameR[2]) {
+      default: break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(NameR.data()+3, "eturn.i", 7))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (NameR[11] != '2')
+            break;
+          return Intrinsic::eh_return_i32;	 // "h.return.i32"
+        case '6':	 // 1 string to match.
+          if (NameR[11] != '4')
+            break;
+          return Intrinsic::eh_return_i64;	 // "h.return.i64"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "ypeid.for", 9))
+          break;
+        return Intrinsic::eh_typeid_for;	 // "h.typeid.for"
+      }
+      break;
+    case 13:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "h.", 2))
+        break;
+      switch (NameR[2]) {
+      default: break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "jlj.setjmp", 10))
+          break;
+        return Intrinsic::eh_sjlj_setjmp;	 // "h.sjlj.setjmp"
+      case 'u':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "nwind.init", 10))
+          break;
+        return Intrinsic::eh_unwind_init;	 // "h.unwind.init"
+      }
+      break;
+    case 14:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "h.sjlj.longjmp", 14))
+        break;
+      return Intrinsic::eh_sjlj_longjmp;	 // "h.sjlj.longjmp"
+    case 15:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "h.sjlj.callsite", 15))
+        break;
+      return Intrinsic::eh_sjlj_callsite;	 // "h.sjlj.callsite"
+    case 20:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "xperimental.stackmap", 20))
+        break;
+      return Intrinsic::experimental_stackmap;	 // "xperimental.stackmap"
+    case 22:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "h.sjlj.functioncontext", 22))
+        break;
+      return Intrinsic::eh_sjlj_functioncontext;	 // "h.sjlj.functioncontext"
+    case 26:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "xperimental.patchpoint.i64", 26))
+        break;
+      return Intrinsic::experimental_patchpoint_i64;	 // "xperimental.patchpoint.i64"
+    case 27:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "xperimental.patchpoint.void", 27))
+        break;
+      return Intrinsic::experimental_patchpoint_void;	 // "xperimental.patchpoint.void"
+    }
+    break;  // end of 'e' case.
+  case 'f':
+    if (NameR.startswith("muladd.")) return Intrinsic::fmuladd;
+    if (NameR.startswith("ma.")) return Intrinsic::fma;
+    if (NameR.startswith("loor.")) return Intrinsic::floor;
+    if (NameR.startswith("abs.")) return Intrinsic::fabs;
+    switch (NameR.size()) {
+    default: break;
+    case 9:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "lt.rounds", 9))
+        break;
+      return Intrinsic::flt_rounds;	 // "lt.rounds"
+    case 11:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "rameaddress", 11))
+        break;
+      return Intrinsic::frameaddress;	 // "rameaddress"
+    }
+    break;  // end of 'f' case.
+  case 'g':
+    switch (NameR.size()) {
+    default: break;
+    case 5:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "cr", 2))
+        break;
+      switch (NameR[2]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "ad", 2))
+          break;
+        return Intrinsic::gcread;	 // "cread"
+      case 'o':	 // 1 string to match.
+        if (memcmp(NameR.data()+3, "ot", 2))
+          break;
+        return Intrinsic::gcroot;	 // "croot"
+      }
+      break;
+    case 6:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "cwrite", 6))
+        break;
+      return Intrinsic::gcwrite;	 // "cwrite"
+    }
+    break;  // end of 'g' case.
+  case 'h':
+    switch (NameR.size()) {
+    default: break;
+    case 12:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "2.or", 4))
+          break;
+        return Intrinsic::hexagon_A2_or;	 // "exagon.A2.or"
+      case 'C':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "2.or", 4))
+          break;
+        return Intrinsic::hexagon_C2_or;	 // "exagon.C2.or"
+      }
+      break;
+    case 13:	 // 23 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 13 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 12 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 3 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[12] != 's')
+                break;
+              return Intrinsic::hexagon_A2_abs;	 // "exagon.A2.abs"
+            case 'd':	 // 1 string to match.
+              if (NameR[12] != 'd')
+                break;
+              return Intrinsic::hexagon_A2_add;	 // "exagon.A2.add"
+            case 'n':	 // 1 string to match.
+              if (NameR[12] != 'd')
+                break;
+              return Intrinsic::hexagon_A2_and;	 // "exagon.A2.and"
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (NameR[12] != 'x')
+                break;
+              return Intrinsic::hexagon_A2_max;	 // "exagon.A2.max"
+            case 'i':	 // 1 string to match.
+              if (NameR[12] != 'n')
+                break;
+              return Intrinsic::hexagon_A2_min;	 // "exagon.A2.min"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (NameR[12] != 'g')
+                break;
+              return Intrinsic::hexagon_A2_neg;	 // "exagon.A2.neg"
+            case 'o':	 // 1 string to match.
+              if (NameR[12] != 't')
+                break;
+              return Intrinsic::hexagon_A2_not;	 // "exagon.A2.not"
+            }
+            break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rp", 2))
+              break;
+            return Intrinsic::hexagon_A2_orp;	 // "exagon.A2.orp"
+          case 's':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (NameR[12] != 't')
+                break;
+              return Intrinsic::hexagon_A2_sat;	 // "exagon.A2.sat"
+            case 'u':	 // 1 string to match.
+              if (NameR[12] != 'b')
+                break;
+              return Intrinsic::hexagon_A2_sub;	 // "exagon.A2.sub"
+            }
+            break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "fr", 2))
+              break;
+            return Intrinsic::hexagon_A2_tfr;	 // "exagon.A2.tfr"
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "or", 2))
+              break;
+            return Intrinsic::hexagon_A2_xor;	 // "exagon.A2.xor"
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".orn", 4))
+            break;
+          return Intrinsic::hexagon_A4_orn;	 // "exagon.A4.orn"
+        }
+        break;
+      case 'C':	 // 5 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "nd", 2))
+            break;
+          return Intrinsic::hexagon_C2_and;	 // "exagon.C2.and"
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "ux", 2))
+            break;
+          return Intrinsic::hexagon_C2_mux;	 // "exagon.C2.mux"
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "ot", 2))
+            break;
+          return Intrinsic::hexagon_C2_not;	 // "exagon.C2.not"
+        case 'o':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "rn", 2))
+            break;
+          return Intrinsic::hexagon_C2_orn;	 // "exagon.C2.orn"
+        case 'x':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "or", 2))
+            break;
+          return Intrinsic::hexagon_C2_xor;	 // "exagon.C2.xor"
+        }
+        break;
+      case 'S':	 // 5 strings to match.
+        if (memcmp(NameR.data()+8, "2.c", 3))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'l':	 // 3 strings to match.
+          switch (NameR[12]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_cl0;	 // "exagon.S2.cl0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_cl1;	 // "exagon.S2.cl1"
+          case 'b':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_clb;	 // "exagon.S2.clb"
+          }
+          break;
+        case 't':	 // 2 strings to match.
+          switch (NameR[12]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_ct0;	 // "exagon.S2.ct0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_ct1;	 // "exagon.S2.ct1"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 14:	 // 42 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 26 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 24 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "sp", 2))
+                break;
+              return Intrinsic::hexagon_A2_absp;	 // "exagon.A2.absp"
+            case 'd':	 // 2 strings to match.
+              if (NameR[12] != 'd')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addi;	 // "exagon.A2.addi"
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addp;	 // "exagon.A2.addp"
+              }
+              break;
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "dp", 2))
+                break;
+              return Intrinsic::hexagon_A2_andp;	 // "exagon.A2.andp"
+            case 's':	 // 2 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'l':	 // 1 string to match.
+                if (NameR[13] != 'h')
+                  break;
+                return Intrinsic::hexagon_A2_aslh;	 // "exagon.A2.aslh"
+              case 'r':	 // 1 string to match.
+                if (NameR[13] != 'h')
+                  break;
+                return Intrinsic::hexagon_A2_asrh;	 // "exagon.A2.asrh"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[12] != 'x')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_maxp;	 // "exagon.A2.maxp"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_maxu;	 // "exagon.A2.maxu"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (NameR[12] != 'n')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_minp;	 // "exagon.A2.minp"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_minu;	 // "exagon.A2.minu"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "gp", 2))
+                break;
+              return Intrinsic::hexagon_A2_negp;	 // "exagon.A2.negp"
+            case 'o':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "tp", 2))
+                break;
+              return Intrinsic::hexagon_A2_notp;	 // "exagon.A2.notp"
+            }
+            break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rir", 3))
+              break;
+            return Intrinsic::hexagon_A2_orir;	 // "exagon.A2.orir"
+          case 's':	 // 7 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[12] != 't')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_satb;	 // "exagon.A2.satb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_sath;	 // "exagon.A2.sath"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "bp", 2))
+                break;
+              return Intrinsic::hexagon_A2_subp;	 // "exagon.A2.subp"
+            case 'w':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "iz", 2))
+                break;
+              return Intrinsic::hexagon_A2_swiz;	 // "exagon.A2.swiz"
+            case 'x':	 // 3 strings to match.
+              if (NameR[12] != 't')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_sxtb;	 // "exagon.A2.sxtb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_sxth;	 // "exagon.A2.sxth"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_sxtw;	 // "exagon.A2.sxtw"
+              }
+              break;
+            }
+            break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "frp", 3))
+              break;
+            return Intrinsic::hexagon_A2_tfrp;	 // "exagon.A2.tfrp"
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "orp", 3))
+              break;
+            return Intrinsic::hexagon_A2_xorp;	 // "exagon.A2.xorp"
+          case 'z':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "xt", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_zxtb;	 // "exagon.A2.zxtb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_zxth;	 // "exagon.A2.zxth"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ndn", 3))
+              break;
+            return Intrinsic::hexagon_A4_andn;	 // "exagon.A4.andn"
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rnp", 3))
+              break;
+            return Intrinsic::hexagon_A4_ornp;	 // "exagon.A4.ornp"
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 5 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 3 strings to match.
+          switch (NameR[11]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "l8", 2))
+              break;
+            return Intrinsic::hexagon_C2_all8;	 // "exagon.C2.all8"
+          case 'n':	 // 2 strings to match.
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (NameR[13] != 'n')
+                break;
+              return Intrinsic::hexagon_C2_andn;	 // "exagon.C2.andn"
+            case 'y':	 // 1 string to match.
+              if (NameR[13] != '8')
+                break;
+              return Intrinsic::hexagon_C2_any8;	 // "exagon.C2.any8"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "ask", 3))
+            break;
+          return Intrinsic::hexagon_C2_mask;	 // "exagon.C2.mask"
+        case 'v':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "mux", 3))
+            break;
+          return Intrinsic::hexagon_C2_vmux;	 // "exagon.C2.vmux"
+        }
+        break;
+      case 'M':	 // 3 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "cci", 3))
+            break;
+          return Intrinsic::hexagon_M2_acci;	 // "exagon.M2.acci"
+        case 'm':	 // 2 strings to match.
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ci", 2))
+              break;
+            return Intrinsic::hexagon_M2_maci;	 // "exagon.M2.maci"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "yi", 2))
+              break;
+            return Intrinsic::hexagon_M2_mpyi;	 // "exagon.M2.mpyi"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 8 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 7 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rev", 3))
+              break;
+            return Intrinsic::hexagon_S2_brev;	 // "exagon.S2.brev"
+          case 'c':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'l':	 // 3 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                if (NameR[13] != 'p')
+                  break;
+                return Intrinsic::hexagon_S2_cl0p;	 // "exagon.S2.cl0p"
+              case '1':	 // 1 string to match.
+                if (NameR[13] != 'p')
+                  break;
+                return Intrinsic::hexagon_S2_cl1p;	 // "exagon.S2.cl1p"
+              case 'b':	 // 1 string to match.
+                if (NameR[13] != 'p')
+                  break;
+                return Intrinsic::hexagon_S2_clbp;	 // "exagon.S2.clbp"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                if (NameR[13] != 'p')
+                  break;
+                return Intrinsic::hexagon_S2_ct0p;	 // "exagon.S2.ct0p"
+              case '1':	 // 1 string to match.
+                if (NameR[13] != 'p')
+                  break;
+                return Intrinsic::hexagon_S2_ct1p;	 // "exagon.S2.ct1p"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "fsp", 3))
+              break;
+            return Intrinsic::hexagon_S2_lfsp;	 // "exagon.S2.lfsp"
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".lsli", 5))
+            break;
+          return Intrinsic::hexagon_S4_lsli;	 // "exagon.S4.lsli"
+        }
+        break;
+      }
+      break;
+    case 15:	 // 58 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 27 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 26 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "dsp", 3))
+                break;
+              return Intrinsic::hexagon_A2_addsp;	 // "exagon.A2.addsp"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "dir", 3))
+                break;
+              return Intrinsic::hexagon_A2_andir;	 // "exagon.A2.andir"
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "xup", 3))
+                break;
+              return Intrinsic::hexagon_A2_maxup;	 // "exagon.A2.maxup"
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "nup", 3))
+                break;
+              return Intrinsic::hexagon_A2_minup;	 // "exagon.A2.minup"
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "tu", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_satub;	 // "exagon.A2.satub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_satuh;	 // "exagon.A2.satuh"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "bri", 3))
+                break;
+              return Intrinsic::hexagon_A2_subri;	 // "exagon.A2.subri"
+            }
+            break;
+          case 't':	 // 4 strings to match.
+            if (memcmp(NameR.data()+11, "fr", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_tfrih;	 // "exagon.A2.tfrih"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_tfril;	 // "exagon.A2.tfril"
+              }
+              break;
+            case 'p':	 // 1 string to match.
+              if (NameR[14] != 'i')
+                break;
+              return Intrinsic::hexagon_A2_tfrpi;	 // "exagon.A2.tfrpi"
+            case 's':	 // 1 string to match.
+              if (NameR[14] != 'i')
+                break;
+              return Intrinsic::hexagon_A2_tfrsi;	 // "exagon.A2.tfrsi"
+            }
+            break;
+          case 'v':	 // 15 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 6 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                if (NameR[13] != 's')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vabsh;	 // "exagon.A2.vabsh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vabsw;	 // "exagon.A2.vabsw"
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                if (NameR[13] != 'd')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vaddh;	 // "exagon.A2.vaddh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vaddw;	 // "exagon.A2.vaddw"
+                }
+                break;
+              case 'v':	 // 2 strings to match.
+                if (NameR[13] != 'g')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavgh;	 // "exagon.A2.vavgh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavgw;	 // "exagon.A2.vavgw"
+                }
+                break;
+              }
+              break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "onj", 3))
+                break;
+              return Intrinsic::hexagon_A2_vconj;	 // "exagon.A2.vconj"
+            case 'm':	 // 6 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 3 strings to match.
+                if (NameR[13] != 'x')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxb;	 // "exagon.A2.vmaxb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxh;	 // "exagon.A2.vmaxh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxw;	 // "exagon.A2.vmaxw"
+                }
+                break;
+              case 'i':	 // 3 strings to match.
+                if (NameR[13] != 'n')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminb;	 // "exagon.A2.vminb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminh;	 // "exagon.A2.vminh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminw;	 // "exagon.A2.vminw"
+                }
+                break;
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "ub", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vsubh;	 // "exagon.A2.vsubh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vsubw;	 // "exagon.A2.vsubw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".andnp", 6))
+            break;
+          return Intrinsic::hexagon_A4_andnp;	 // "exagon.A4.andnp"
+        }
+        break;
+      case 'C':	 // 9 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 8 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (NameR[14] != 'q')
+                break;
+              return Intrinsic::hexagon_C2_cmpeq;	 // "exagon.C2.cmpeq"
+            case 'g':	 // 1 string to match.
+              if (NameR[14] != 't')
+                break;
+              return Intrinsic::hexagon_C2_cmpgt;	 // "exagon.C2.cmpgt"
+            case 'l':	 // 1 string to match.
+              if (NameR[14] != 't')
+                break;
+              return Intrinsic::hexagon_C2_cmplt;	 // "exagon.C2.cmplt"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "ux", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_muxii;	 // "exagon.C2.muxii"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_muxir;	 // "exagon.C2.muxir"
+              }
+              break;
+            case 'r':	 // 1 string to match.
+              if (NameR[14] != 'i')
+                break;
+              return Intrinsic::hexagon_C2_muxri;	 // "exagon.C2.muxri"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "fr", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[14] != 'r')
+                break;
+              return Intrinsic::hexagon_C2_tfrpr;	 // "exagon.C2.tfrpr"
+            case 'r':	 // 1 string to match.
+              if (NameR[14] != 'p')
+                break;
+              return Intrinsic::hexagon_C2_tfrrp;	 // "exagon.C2.tfrrp"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".or.or", 6))
+            break;
+          return Intrinsic::hexagon_C4_or_or;	 // "exagon.C4.or.or"
+        }
+        break;
+      case 'F':	 // 14 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'd':	 // 7 strings to match.
+          if (NameR[11] != 'f')
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "dd", 2))
+              break;
+            return Intrinsic::hexagon_F2_dfadd;	 // "exagon.F2.dfadd"
+          case 'f':	 // 2 strings to match.
+            if (NameR[13] != 'm')
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffma;	 // "exagon.F2.dffma"
+            case 's':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffms;	 // "exagon.F2.dffms"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (NameR[14] != 'x')
+                break;
+              return Intrinsic::hexagon_F2_dfmax;	 // "exagon.F2.dfmax"
+            case 'i':	 // 1 string to match.
+              if (NameR[14] != 'n')
+                break;
+              return Intrinsic::hexagon_F2_dfmin;	 // "exagon.F2.dfmin"
+            case 'p':	 // 1 string to match.
+              if (NameR[14] != 'y')
+                break;
+              return Intrinsic::hexagon_F2_dfmpy;	 // "exagon.F2.dfmpy"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "ub", 2))
+              break;
+            return Intrinsic::hexagon_F2_dfsub;	 // "exagon.F2.dfsub"
+          }
+          break;
+        case 's':	 // 7 strings to match.
+          if (NameR[11] != 'f')
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "dd", 2))
+              break;
+            return Intrinsic::hexagon_F2_sfadd;	 // "exagon.F2.sfadd"
+          case 'f':	 // 2 strings to match.
+            if (NameR[13] != 'm')
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffma;	 // "exagon.F2.sffma"
+            case 's':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffms;	 // "exagon.F2.sffms"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (NameR[14] != 'x')
+                break;
+              return Intrinsic::hexagon_F2_sfmax;	 // "exagon.F2.sfmax"
+            case 'i':	 // 1 string to match.
+              if (NameR[14] != 'n')
+                break;
+              return Intrinsic::hexagon_F2_sfmin;	 // "exagon.F2.sfmin"
+            case 'p':	 // 1 string to match.
+              if (NameR[14] != 'y')
+                break;
+              return Intrinsic::hexagon_F2_sfmpy;	 // "exagon.F2.sfmpy"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "ub", 2))
+              break;
+            return Intrinsic::hexagon_F2_sfsub;	 // "exagon.F2.sfsub"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 6 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ccii", 4))
+              break;
+            return Intrinsic::hexagon_M2_accii;	 // "exagon.M2.accii"
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "pyui", 4))
+              break;
+            return Intrinsic::hexagon_M2_mpyui;	 // "exagon.M2.mpyui"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "acci", 4))
+              break;
+            return Intrinsic::hexagon_M2_nacci;	 // "exagon.M2.nacci"
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "mac2", 4))
+              break;
+            return Intrinsic::hexagon_M2_vmac2;	 // "exagon.M2.vmac2"
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.or", 4))
+              break;
+            return Intrinsic::hexagon_M4_or_or;	 // "exagon.M4.or.or"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "mpyw", 4))
+              break;
+            return Intrinsic::hexagon_M4_pmpyw;	 // "exagon.M4.pmpyw"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "2.brevp", 7))
+          break;
+        return Intrinsic::hexagon_S2_brevp;	 // "exagon.S2.brevp"
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "irc.ldd", 7))
+          break;
+        return Intrinsic::hexagon_circ_ldd;	 // "exagon.circ.ldd"
+      }
+      break;
+    case 16:	 // 70 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 35 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 26 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ssat", 4))
+                break;
+              return Intrinsic::hexagon_A2_abssat;	 // "exagon.A2.abssat"
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "dsat", 4))
+                break;
+              return Intrinsic::hexagon_A2_addsat;	 // "exagon.A2.addsat"
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "egsat", 5))
+              break;
+            return Intrinsic::hexagon_A2_negsat;	 // "exagon.A2.negsat"
+          case 's':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "bsat", 4))
+                break;
+              return Intrinsic::hexagon_A2_subsat;	 // "exagon.A2.subsat"
+            case 'v':	 // 3 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "dh", 2))
+                    break;
+                  return Intrinsic::hexagon_A2_svaddh;	 // "exagon.A2.svaddh"
+                case 'v':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "gh", 2))
+                    break;
+                  return Intrinsic::hexagon_A2_svavgh;	 // "exagon.A2.svavgh"
+                }
+                break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "ubh", 3))
+                  break;
+                return Intrinsic::hexagon_A2_svsubh;	 // "exagon.A2.svsubh"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 19 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 8 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 3 strings to match.
+                if (NameR[13] != 'd')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (NameR[15] != 's')
+                    break;
+                  return Intrinsic::hexagon_A2_vaddhs;	 // "exagon.A2.vaddhs"
+                case 'u':	 // 1 string to match.
+                  if (NameR[15] != 'b')
+                    break;
+                  return Intrinsic::hexagon_A2_vaddub;	 // "exagon.A2.vaddub"
+                case 'w':	 // 1 string to match.
+                  if (NameR[15] != 's')
+                    break;
+                  return Intrinsic::hexagon_A2_vaddws;	 // "exagon.A2.vaddws"
+                }
+                break;
+              case 'v':	 // 5 strings to match.
+                if (NameR[13] != 'g')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (NameR[15] != 'r')
+                    break;
+                  return Intrinsic::hexagon_A2_vavghr;	 // "exagon.A2.vavghr"
+                case 'u':	 // 3 strings to match.
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::hexagon_A2_vavgub;	 // "exagon.A2.vavgub"
+                  case 'h':	 // 1 string to match.
+                    return Intrinsic::hexagon_A2_vavguh;	 // "exagon.A2.vavguh"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::hexagon_A2_vavguw;	 // "exagon.A2.vavguw"
+                  }
+                  break;
+                case 'w':	 // 1 string to match.
+                  if (NameR[15] != 'r')
+                    break;
+                  return Intrinsic::hexagon_A2_vavgwr;	 // "exagon.A2.vavgwr"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 6 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 3 strings to match.
+                if (memcmp(NameR.data()+13, "xu", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxub;	 // "exagon.A2.vmaxub"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxuh;	 // "exagon.A2.vmaxuh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxuw;	 // "exagon.A2.vmaxuw"
+                }
+                break;
+              case 'i':	 // 3 strings to match.
+                if (memcmp(NameR.data()+13, "nu", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminub;	 // "exagon.A2.vminub"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminuh;	 // "exagon.A2.vminuh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminuw;	 // "exagon.A2.vminuw"
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "avg", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vnavgh;	 // "exagon.A2.vnavgh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vnavgw;	 // "exagon.A2.vnavgw"
+              }
+              break;
+            case 's':	 // 3 strings to match.
+              if (memcmp(NameR.data()+12, "ub", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (NameR[15] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vsubhs;	 // "exagon.A2.vsubhs"
+              case 'u':	 // 1 string to match.
+                if (NameR[15] != 'b')
+                  break;
+                return Intrinsic::hexagon_A2_vsubub;	 // "exagon.A2.vsubub"
+              case 'w':	 // 1 string to match.
+                if (NameR[15] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vsubws;	 // "exagon.A2.vsubws"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 9 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 4 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (NameR[15] != 'q')
+                  break;
+                return Intrinsic::hexagon_A4_cmpbeq;	 // "exagon.A4.cmpbeq"
+              case 'g':	 // 1 string to match.
+                if (NameR[15] != 't')
+                  break;
+                return Intrinsic::hexagon_A4_cmpbgt;	 // "exagon.A4.cmpbgt"
+              }
+              break;
+            case 'h':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (NameR[15] != 'q')
+                  break;
+                return Intrinsic::hexagon_A4_cmpheq;	 // "exagon.A4.cmpheq"
+              case 'g':	 // 1 string to match.
+                if (NameR[15] != 't')
+                  break;
+                return Intrinsic::hexagon_A4_cmphgt;	 // "exagon.A4.cmphgt"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "cmpeq", 5))
+              break;
+            return Intrinsic::hexagon_A4_rcmpeq;	 // "exagon.A4.rcmpeq"
+          case 'v':	 // 4 strings to match.
+            if (memcmp(NameR.data()+11, "rm", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[14] != 'x')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrmaxh;	 // "exagon.A4.vrmaxh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrmaxw;	 // "exagon.A4.vrmaxw"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (NameR[14] != 'n')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrminh;	 // "exagon.A4.vrminh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrminw;	 // "exagon.A4.vrminw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 12 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 7 strings to match.
+          if (memcmp(NameR.data()+9, ".cmp", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (NameR[14] != 'q')
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpeqi;	 // "exagon.C2.cmpeqi"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpeqp;	 // "exagon.C2.cmpeqp"
+            }
+            break;
+          case 'g':	 // 4 strings to match.
+            switch (NameR[14]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (NameR[15] != 'i')
+                break;
+              return Intrinsic::hexagon_C2_cmpgei;	 // "exagon.C2.cmpgei"
+            case 't':	 // 3 strings to match.
+              switch (NameR[15]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_cmpgti;	 // "exagon.C2.cmpgti"
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_cmpgtp;	 // "exagon.C2.cmpgtp"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_cmpgtu;	 // "exagon.C2.cmpgtu"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "tu", 2))
+              break;
+            return Intrinsic::hexagon_C2_cmpltu;	 // "exagon.C2.cmpltu"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nd.or", 5))
+              break;
+            return Intrinsic::hexagon_C4_and_or;	 // "exagon.C4.and.or"
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "te", 2))
+                break;
+              return Intrinsic::hexagon_C4_cmplte;	 // "exagon.C4.cmplte"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "eq", 2))
+                break;
+              return Intrinsic::hexagon_C4_cmpneq;	 // "exagon.C4.cmpneq"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "r.", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "nd", 2))
+                break;
+              return Intrinsic::hexagon_C4_or_and;	 // "exagon.C4.or.and"
+            case 'o':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "rn", 2))
+                break;
+              return Intrinsic::hexagon_C4_or_orn;	 // "exagon.C4.or.orn"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 12 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 7 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "csi", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'n':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_macsin;	 // "exagon.M2.macsin"
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_macsip;	 // "exagon.M2.macsip"
+              }
+              break;
+            case 'p':	 // 2 strings to match.
+              if (NameR[12] != 'y')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case '.':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, "up", 2))
+                  break;
+                return Intrinsic::hexagon_M2_mpy_up;	 // "exagon.M2.mpy.up"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, "mi", 2))
+                  break;
+                return Intrinsic::hexagon_M2_mpysmi;	 // "exagon.M2.mpysmi"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "accii", 5))
+              break;
+            return Intrinsic::hexagon_M2_naccii;	 // "exagon.M2.naccii"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ubacc", 5))
+              break;
+            return Intrinsic::hexagon_M2_subacc;	 // "exagon.M2.subacc"
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "raddh", 5))
+              break;
+            return Intrinsic::hexagon_M2_vraddh;	 // "exagon.M2.vraddh"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nd.or", 5))
+              break;
+            return Intrinsic::hexagon_M4_and_or;	 // "exagon.M4.and.or"
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "r.", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "nd", 2))
+                break;
+              return Intrinsic::hexagon_M4_or_and;	 // "exagon.M4.or.and"
+            case 'x':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "or", 2))
+                break;
+              return Intrinsic::hexagon_M4_or_xor;	 // "exagon.M4.or.xor"
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "pmpyh", 5))
+              break;
+            return Intrinsic::hexagon_M4_vpmpyh;	 // "exagon.M4.vpmpyh"
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "or.or", 5))
+              break;
+            return Intrinsic::hexagon_M4_xor_or;	 // "exagon.M4.xor.or"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 11 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 9 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nsert", 5))
+              break;
+            return Intrinsic::hexagon_S2_insert;	 // "exagon.S2.insert"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ackhl", 5))
+              break;
+            return Intrinsic::hexagon_S2_packhl;	 // "exagon.S2.packhl"
+          case 'v':	 // 7 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "negh", 4))
+                break;
+              return Intrinsic::hexagon_S2_vcnegh;	 // "exagon.S2.vcnegh"
+            case 's':	 // 4 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (NameR[13] != 't')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (NameR[15] != 'b')
+                    break;
+                  return Intrinsic::hexagon_S2_vsathb;	 // "exagon.S2.vsathb"
+                case 'w':	 // 1 string to match.
+                  if (NameR[15] != 'h')
+                    break;
+                  return Intrinsic::hexagon_S2_vsatwh;	 // "exagon.S2.vsatwh"
+                }
+                break;
+              case 'x':	 // 2 strings to match.
+                if (NameR[13] != 't')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  if (NameR[15] != 'h')
+                    break;
+                  return Intrinsic::hexagon_S2_vsxtbh;	 // "exagon.S2.vsxtbh"
+                case 'h':	 // 1 string to match.
+                  if (NameR[15] != 'w')
+                    break;
+                  return Intrinsic::hexagon_S2_vsxthw;	 // "exagon.S2.vsxthw"
+                }
+                break;
+              }
+              break;
+            case 'z':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "xt", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (NameR[15] != 'h')
+                  break;
+                return Intrinsic::hexagon_S2_vzxtbh;	 // "exagon.S2.vzxtbh"
+              case 'h':	 // 1 string to match.
+                if (NameR[15] != 'w')
+                  break;
+                return Intrinsic::hexagon_S2_vzxthw;	 // "exagon.S2.vzxthw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.ori", 5))
+              break;
+            return Intrinsic::hexagon_S4_or_ori;	 // "exagon.S4.or.ori"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "arity", 5))
+              break;
+            return Intrinsic::hexagon_S4_parity;	 // "exagon.S4.parity"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 17:	 // 103 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 36 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 23 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ddpsat", 6))
+              break;
+            return Intrinsic::hexagon_A2_addpsat;	 // "exagon.A2.addpsat"
+          case 's':	 // 4 strings to match.
+            if (NameR[11] != 'v')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, "dhs", 3))
+                  break;
+                return Intrinsic::hexagon_A2_svaddhs;	 // "exagon.A2.svaddhs"
+              case 'v':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, "ghs", 3))
+                  break;
+                return Intrinsic::hexagon_A2_svavghs;	 // "exagon.A2.svavghs"
+              }
+              break;
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "avgh", 4))
+                break;
+              return Intrinsic::hexagon_A2_svnavgh;	 // "exagon.A2.svnavgh"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ubhs", 4))
+                break;
+              return Intrinsic::hexagon_A2_svsubhs;	 // "exagon.A2.svsubhs"
+            }
+            break;
+          case 'v':	 // 18 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 7 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "du", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  if (NameR[16] != 's')
+                    break;
+                  return Intrinsic::hexagon_A2_vaddubs;	 // "exagon.A2.vaddubs"
+                case 'h':	 // 1 string to match.
+                  if (NameR[16] != 's')
+                    break;
+                  return Intrinsic::hexagon_A2_vadduhs;	 // "exagon.A2.vadduhs"
+                }
+                break;
+              case 'v':	 // 5 strings to match.
+                if (NameR[13] != 'g')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "cr", 2))
+                    break;
+                  return Intrinsic::hexagon_A2_vavghcr;	 // "exagon.A2.vavghcr"
+                case 'u':	 // 3 strings to match.
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    if (NameR[16] != 'r')
+                      break;
+                    return Intrinsic::hexagon_A2_vavgubr;	 // "exagon.A2.vavgubr"
+                  case 'h':	 // 1 string to match.
+                    if (NameR[16] != 'r')
+                      break;
+                    return Intrinsic::hexagon_A2_vavguhr;	 // "exagon.A2.vavguhr"
+                  case 'w':	 // 1 string to match.
+                    if (NameR[16] != 'r')
+                      break;
+                    return Intrinsic::hexagon_A2_vavguwr;	 // "exagon.A2.vavguwr"
+                  }
+                  break;
+                case 'w':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "cr", 2))
+                    break;
+                  return Intrinsic::hexagon_A2_vavgwcr;	 // "exagon.A2.vavgwcr"
+                }
+                break;
+              }
+              break;
+            case 'c':	 // 5 strings to match.
+              if (memcmp(NameR.data()+12, "mp", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "eq", 2))
+                  break;
+                return Intrinsic::hexagon_A2_vcmpbeq;	 // "exagon.A2.vcmpbeq"
+              case 'h':	 // 2 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (NameR[16] != 'q')
+                    break;
+                  return Intrinsic::hexagon_A2_vcmpheq;	 // "exagon.A2.vcmpheq"
+                case 'g':	 // 1 string to match.
+                  if (NameR[16] != 't')
+                    break;
+                  return Intrinsic::hexagon_A2_vcmphgt;	 // "exagon.A2.vcmphgt"
+                }
+                break;
+              case 'w':	 // 2 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (NameR[16] != 'q')
+                    break;
+                  return Intrinsic::hexagon_A2_vcmpweq;	 // "exagon.A2.vcmpweq"
+                case 'g':	 // 1 string to match.
+                  if (NameR[16] != 't')
+                    break;
+                  return Intrinsic::hexagon_A2_vcmpwgt;	 // "exagon.A2.vcmpwgt"
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "avg", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (NameR[16] != 'r')
+                  break;
+                return Intrinsic::hexagon_A2_vnavghr;	 // "exagon.A2.vnavghr"
+              case 'w':	 // 1 string to match.
+                if (NameR[16] != 'r')
+                  break;
+                return Intrinsic::hexagon_A2_vnavgwr;	 // "exagon.A2.vnavgwr"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "ddub", 4))
+                  break;
+                return Intrinsic::hexagon_A2_vraddub;	 // "exagon.A2.vraddub"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "adub", 4))
+                  break;
+                return Intrinsic::hexagon_A2_vrsadub;	 // "exagon.A2.vrsadub"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "ubu", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (NameR[16] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vsububs;	 // "exagon.A2.vsububs"
+              case 'h':	 // 1 string to match.
+                if (NameR[16] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vsubuhs;	 // "exagon.A2.vsubuhs"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 13 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 3 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "qi", 2))
+                  break;
+                return Intrinsic::hexagon_A4_cmpbeqi;	 // "exagon.A4.cmpbeqi"
+              case 'g':	 // 2 strings to match.
+                if (NameR[15] != 't')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_cmpbgti;	 // "exagon.A4.cmpbgti"
+                case 'u':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_cmpbgtu;	 // "exagon.A4.cmpbgtu"
+                }
+                break;
+              }
+              break;
+            case 'h':	 // 3 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "qi", 2))
+                  break;
+                return Intrinsic::hexagon_A4_cmpheqi;	 // "exagon.A4.cmpheqi"
+              case 'g':	 // 2 strings to match.
+                if (NameR[15] != 't')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_cmphgti;	 // "exagon.A4.cmphgti"
+                case 'u':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_cmphgtu;	 // "exagon.A4.cmphgtu"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "cmp", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_rcmpeqi;	 // "exagon.A4.rcmpeqi"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "eq", 2))
+                break;
+              return Intrinsic::hexagon_A4_rcmpneq;	 // "exagon.A4.rcmpneq"
+            }
+            break;
+          case 'v':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "mpbgt", 5))
+                break;
+              return Intrinsic::hexagon_A4_vcmpbgt;	 // "exagon.A4.vcmpbgt"
+            case 'r':	 // 4 strings to match.
+              if (NameR[12] != 'm')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "xu", 2))
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_vrmaxuh;	 // "exagon.A4.vrmaxuh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_vrmaxuw;	 // "exagon.A4.vrmaxuw"
+                }
+                break;
+              case 'i':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "nu", 2))
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_vrminuh;	 // "exagon.A4.vrminuh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A4_vrminuw;	 // "exagon.A4.vrminuw"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 12 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 6 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "its", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "lr", 2))
+                break;
+              return Intrinsic::hexagon_C2_bitsclr;	 // "exagon.C2.bitsclr"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "et", 2))
+                break;
+              return Intrinsic::hexagon_C2_bitsset;	 // "exagon.C2.bitsset"
+            }
+            break;
+          case 'c':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "mpg", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "ui", 2))
+                break;
+              return Intrinsic::hexagon_C2_cmpgeui;	 // "exagon.C2.cmpgeui"
+            case 't':	 // 2 strings to match.
+              if (NameR[15] != 'u')
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_cmpgtui;	 // "exagon.C2.cmpgtui"
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_cmpgtup;	 // "exagon.C2.cmpgtup"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "itpack", 6))
+              break;
+            return Intrinsic::hexagon_C2_vitpack;	 // "exagon.C2.vitpack"
+          }
+          break;
+        case '4':	 // 6 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "nd.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "nd", 2))
+                break;
+              return Intrinsic::hexagon_C4_and_and;	 // "exagon.C4.and.and"
+            case 'o':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "rn", 2))
+                break;
+              return Intrinsic::hexagon_C4_and_orn;	 // "exagon.C4.and.orn"
+            }
+            break;
+          case 'c':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "te", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_C4_cmpltei;	 // "exagon.C4.cmpltei"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_C4_cmplteu;	 // "exagon.C4.cmplteu"
+              }
+              break;
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "eqi", 3))
+                break;
+              return Intrinsic::hexagon_C4_cmpneqi;	 // "exagon.C4.cmpneqi"
+            }
+            break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.andn", 6))
+              break;
+            return Intrinsic::hexagon_C4_or_andn;	 // "exagon.C4.or.andn"
+          }
+          break;
+        }
+        break;
+      case 'F':	 // 14 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'd':	 // 7 strings to match.
+          if (NameR[11] != 'f')
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'c':	 // 5 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "ass", 3))
+                break;
+              return Intrinsic::hexagon_F2_dfclass;	 // "exagon.F2.dfclass"
+            case 'm':	 // 4 strings to match.
+              if (NameR[14] != 'p')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (NameR[16] != 'q')
+                  break;
+                return Intrinsic::hexagon_F2_dfcmpeq;	 // "exagon.F2.dfcmpeq"
+              case 'g':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  return Intrinsic::hexagon_F2_dfcmpge;	 // "exagon.F2.dfcmpge"
+                case 't':	 // 1 string to match.
+                  return Intrinsic::hexagon_F2_dfcmpgt;	 // "exagon.F2.dfcmpgt"
+                }
+                break;
+              case 'u':	 // 1 string to match.
+                if (NameR[16] != 'o')
+                  break;
+                return Intrinsic::hexagon_F2_dfcmpuo;	 // "exagon.F2.dfcmpuo"
+              }
+              break;
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+13, "mm.", 3))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'n':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dfimm_n;	 // "exagon.F2.dfimm.n"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dfimm_p;	 // "exagon.F2.dfimm.p"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 7 strings to match.
+          if (NameR[11] != 'f')
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'c':	 // 5 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "ass", 3))
+                break;
+              return Intrinsic::hexagon_F2_sfclass;	 // "exagon.F2.sfclass"
+            case 'm':	 // 4 strings to match.
+              if (NameR[14] != 'p')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (NameR[16] != 'q')
+                  break;
+                return Intrinsic::hexagon_F2_sfcmpeq;	 // "exagon.F2.sfcmpeq"
+              case 'g':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  return Intrinsic::hexagon_F2_sfcmpge;	 // "exagon.F2.sfcmpge"
+                case 't':	 // 1 string to match.
+                  return Intrinsic::hexagon_F2_sfcmpgt;	 // "exagon.F2.sfcmpgt"
+                }
+                break;
+              case 'u':	 // 1 string to match.
+                if (NameR[16] != 'o')
+                  break;
+                return Intrinsic::hexagon_F2_sfcmpuo;	 // "exagon.F2.sfcmpuo"
+              }
+              break;
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+13, "mm.", 3))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'n':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sfimm_n;	 // "exagon.F2.sfimm.n"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sfimm_p;	 // "exagon.F2.sfimm.p"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 11 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 3 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "pyu.up", 6))
+              break;
+            return Intrinsic::hexagon_M2_mpyu_up;	 // "exagon.M2.mpyu.up"
+          case 'v':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ac2es", 5))
+                break;
+              return Intrinsic::hexagon_M2_vmac2es;	 // "exagon.M2.vmac2es"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "adduh", 5))
+                break;
+              return Intrinsic::hexagon_M2_vradduh;	 // "exagon.M2.vradduh"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "nd.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "nd", 2))
+                break;
+              return Intrinsic::hexagon_M4_and_and;	 // "exagon.M4.and.and"
+            case 'x':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "or", 2))
+                break;
+              return Intrinsic::hexagon_M4_and_xor;	 // "exagon.M4.and.xor"
+            }
+            break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.andn", 6))
+              break;
+            return Intrinsic::hexagon_M4_or_andn;	 // "exagon.M4.or.andn"
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "or.and", 6))
+              break;
+            return Intrinsic::hexagon_M4_xor_and;	 // "exagon.M4.xor.and"
+          }
+          break;
+        case '5':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, ".vm", 3))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+13, "cb", 2))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (NameR[16] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vmacbsu;	 // "exagon.M5.vmacbsu"
+            case 'u':	 // 1 string to match.
+              if (NameR[16] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vmacbuu;	 // "exagon.M5.vmacbuu"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(NameR.data()+13, "yb", 2))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (NameR[16] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vmpybsu;	 // "exagon.M5.vmpybsu"
+            case 'u':	 // 1 string to match.
+              if (NameR[16] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vmpybuu;	 // "exagon.M5.vmpybuu"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 30 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 25 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_i_p;	 // "exagon.S2.asl.i.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_i_r;	 // "exagon.S2.asl.i.r"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_r_p;	 // "exagon.S2.asl.r.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_r_r;	 // "exagon.S2.asl.r.r"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_i_p;	 // "exagon.S2.asr.i.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_i_r;	 // "exagon.S2.asr.i.r"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_r_p;	 // "exagon.S2.asr.r.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_r_r;	 // "exagon.S2.asr.r.r"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "lbnorm", 6))
+              break;
+            return Intrinsic::hexagon_S2_clbnorm;	 // "exagon.S2.clbnorm"
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nsertp", 6))
+              break;
+            return Intrinsic::hexagon_S2_insertp;	 // "exagon.S2.insertp"
+          case 'l':	 // 6 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, ".r.", 3))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsl_r_p;	 // "exagon.S2.lsl.r.p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsl_r_r;	 // "exagon.S2.lsl.r.r"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_i_p;	 // "exagon.S2.lsr.i.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_i_r;	 // "exagon.S2.lsr.i.r"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_r_p;	 // "exagon.S2.lsr.r.p"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_r_r;	 // "exagon.S2.lsr.r.r"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "arityp", 6))
+              break;
+            return Intrinsic::hexagon_S2_parityp;	 // "exagon.S2.parityp"
+          case 's':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              if (memcmp(NameR.data()+12, "uff", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_shuffeb;	 // "exagon.S2.shuffeb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_shuffeh;	 // "exagon.S2.shuffeh"
+                }
+                break;
+              case 'o':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_shuffob;	 // "exagon.S2.shuffob"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_shuffoh;	 // "exagon.S2.shuffoh"
+                }
+                break;
+              }
+              break;
+            case 'v':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "sathb", 5))
+                break;
+              return Intrinsic::hexagon_S2_svsathb;	 // "exagon.S2.svsathb"
+            }
+            break;
+          case 'v':	 // 3 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "cnegh", 5))
+                break;
+              return Intrinsic::hexagon_S2_vrcnegh;	 // "exagon.S2.vrcnegh"
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "at", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "ub", 2))
+                  break;
+                return Intrinsic::hexagon_S2_vsathub;	 // "exagon.S2.vsathub"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "uh", 2))
+                  break;
+                return Intrinsic::hexagon_S2_vsatwuh;	 // "exagon.S2.vsatwuh"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ddaddi", 6))
+              break;
+            return Intrinsic::hexagon_S4_addaddi;	 // "exagon.S4.addaddi"
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "lbaddi", 6))
+              break;
+            return Intrinsic::hexagon_S4_clbaddi;	 // "exagon.S4.clbaddi"
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtract", 6))
+              break;
+            return Intrinsic::hexagon_S4_extract;	 // "exagon.S4.extract"
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.andi", 6))
+              break;
+            return Intrinsic::hexagon_S4_or_andi;	 // "exagon.S4.or.andi"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ubaddi", 6))
+              break;
+            return Intrinsic::hexagon_S4_subaddi;	 // "exagon.S4.subaddi"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 18:	 // 103 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 26 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 11 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ombinew", 7))
+              break;
+            return Intrinsic::hexagon_A2_combinew;	 // "exagon.A2.combinew"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "oundsat", 7))
+              break;
+            return Intrinsic::hexagon_A2_roundsat;	 // "exagon.A2.roundsat"
+          case 's':	 // 2 strings to match.
+            if (NameR[11] != 'v')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "dduhs", 5))
+                break;
+              return Intrinsic::hexagon_A2_svadduhs;	 // "exagon.A2.svadduhs"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ubuhs", 5))
+                break;
+              return Intrinsic::hexagon_A2_svsubuhs;	 // "exagon.A2.svsubuhs"
+            }
+            break;
+          case 'v':	 // 7 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "bs", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "sat", 3))
+                  break;
+                return Intrinsic::hexagon_A2_vabshsat;	 // "exagon.A2.vabshsat"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "sat", 3))
+                  break;
+                return Intrinsic::hexagon_A2_vabswsat;	 // "exagon.A2.vabswsat"
+              }
+              break;
+            case 'c':	 // 3 strings to match.
+              if (memcmp(NameR.data()+12, "mp", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "gtu", 3))
+                  break;
+                return Intrinsic::hexagon_A2_vcmpbgtu;	 // "exagon.A2.vcmpbgtu"
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "gtu", 3))
+                  break;
+                return Intrinsic::hexagon_A2_vcmphgtu;	 // "exagon.A2.vcmphgtu"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "gtu", 3))
+                  break;
+                return Intrinsic::hexagon_A2_vcmpwgtu;	 // "exagon.A2.vcmpwgtu"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "avg", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "cr", 2))
+                  break;
+                return Intrinsic::hexagon_A2_vnavghcr;	 // "exagon.A2.vnavghcr"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "cr", 2))
+                  break;
+                return Intrinsic::hexagon_A2_vnavgwcr;	 // "exagon.A2.vnavgwcr"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 14 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "itsplit", 7))
+              break;
+            return Intrinsic::hexagon_A4_bitsplit;	 // "exagon.A4.bitsplit"
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "gtui", 4))
+                break;
+              return Intrinsic::hexagon_A4_cmpbgtui;	 // "exagon.A4.cmpbgtui"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "gtui", 4))
+                break;
+              return Intrinsic::hexagon_A4_cmphgtui;	 // "exagon.A4.cmphgtui"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "odwrapu", 7))
+              break;
+            return Intrinsic::hexagon_A4_modwrapu;	 // "exagon.A4.modwrapu"
+          case 'r':	 // 3 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "mpneqi", 6))
+                break;
+              return Intrinsic::hexagon_A4_rcmpneqi;	 // "exagon.A4.rcmpneqi"
+            case 'o':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "und.r", 5))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_round_ri;	 // "exagon.A4.round.ri"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_round_rr;	 // "exagon.A4.round.rr"
+              }
+              break;
+            }
+            break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "lbmatch", 7))
+              break;
+            return Intrinsic::hexagon_A4_tlbmatch;	 // "exagon.A4.tlbmatch"
+          case 'v':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "cmp", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "qi", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmpbeqi;	 // "exagon.A4.vcmpbeqi"
+              case 'g':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "ti", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmpbgti;	 // "exagon.A4.vcmpbgti"
+              }
+              break;
+            case 'h':	 // 2 strings to match.
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "qi", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmpheqi;	 // "exagon.A4.vcmpheqi"
+              case 'g':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "ti", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmphgti;	 // "exagon.A4.vcmphgti"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "qi", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmpweqi;	 // "exagon.A4.vcmpweqi"
+              case 'g':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "ti", 2))
+                  break;
+                return Intrinsic::hexagon_A4_vcmpwgti;	 // "exagon.A4.vcmpwgti"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '5':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".vaddhubs", 9))
+            break;
+          return Intrinsic::hexagon_A5_vaddhubs;	 // "exagon.A5.vaddhubs"
+        }
+        break;
+      case 'C':	 // 5 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".bitsclri", 9))
+            break;
+          return Intrinsic::hexagon_C2_bitsclri;	 // "exagon.C2.bitsclri"
+        case '4':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nd.andn", 7))
+              break;
+            return Intrinsic::hexagon_C4_and_andn;	 // "exagon.C4.and.andn"
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "mplteui", 7))
+              break;
+            return Intrinsic::hexagon_C4_cmplteui;	 // "exagon.C4.cmplteui"
+          case 'n':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "bits", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "lr", 2))
+                break;
+              return Intrinsic::hexagon_C4_nbitsclr;	 // "exagon.C4.nbitsclr"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "et", 2))
+                break;
+              return Intrinsic::hexagon_C4_nbitsset;	 // "exagon.C4.nbitsset"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'F':	 // 8 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ff", 2))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'i':	 // 3 strings to match.
+            if (memcmp(NameR.data()+14, "xup", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffixupd;	 // "exagon.F2.dffixupd"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffixupn;	 // "exagon.F2.dffixupn"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffixupr;	 // "exagon.F2.dffixupr"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "a.sc", 4))
+              break;
+            return Intrinsic::hexagon_F2_dffma_sc;	 // "exagon.F2.dffma.sc"
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ff", 2))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'i':	 // 3 strings to match.
+            if (memcmp(NameR.data()+14, "xup", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffixupd;	 // "exagon.F2.sffixupd"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffixupn;	 // "exagon.F2.sffixupn"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffixupr;	 // "exagon.F2.sffixupr"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "a.sc", 4))
+              break;
+            return Intrinsic::hexagon_F2_sffma_sc;	 // "exagon.F2.sffma.sc"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 29 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 18 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 10 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 8 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 4 strings to match.
+                if (NameR[13] != 'c')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_cmaci_s0;	 // "exagon.M2.cmaci.s0"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_cmacr_s0;	 // "exagon.M2.cmacr.s0"
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, ".s", 2))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmacs_s0;	 // "exagon.M2.cmacs.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmacs_s1;	 // "exagon.M2.cmacs.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                if (NameR[13] != 'y')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_cmpyi_s0;	 // "exagon.M2.cmpyi.s0"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_cmpyr_s0;	 // "exagon.M2.cmpyr.s0"
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, ".s", 2))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpys_s0;	 // "exagon.M2.cmpys.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpys_s1;	 // "exagon.M2.cmpys.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "acs.s", 5))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cnacs_s0;	 // "exagon.M2.cnacs.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cnacs_s1;	 // "exagon.M2.cnacs.s1"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 4 strings to match.
+              if (memcmp(NameR.data()+12, "py", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".s", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyh_s0;	 // "exagon.M2.mmpyh.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyh_s1;	 // "exagon.M2.mmpyh.s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".s", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyl_s0;	 // "exagon.M2.mmpyl.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyl_s1;	 // "exagon.M2.mmpyl.s1"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ysu.up", 6))
+                break;
+              return Intrinsic::hexagon_M2_mpysu_up;	 // "exagon.M2.mpysu.up"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "rm", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "c.s0", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrmac_s0;	 // "exagon.M2.vrmac.s0"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "y.s0", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrmpy_s0;	 // "exagon.M2.vrmpy.s0"
+            }
+            break;
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "or.xacc", 7))
+              break;
+            return Intrinsic::hexagon_M2_xor_xacc;	 // "exagon.M2.xor.xacc"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nd.andn", 7))
+              break;
+            return Intrinsic::hexagon_M4_and_andn;	 // "exagon.M4.and.andn"
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mpy", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".wh", 3))
+                break;
+              return Intrinsic::hexagon_M4_cmpyi_wh;	 // "exagon.M4.cmpyi.wh"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".wh", 3))
+                break;
+              return Intrinsic::hexagon_M4_cmpyr_wh;	 // "exagon.M4.cmpyr.wh"
+            }
+            break;
+          case 'x':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "or.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "ndn", 3))
+                break;
+              return Intrinsic::hexagon_M4_xor_andn;	 // "exagon.M4.xor.andn"
+            case 'x':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "acc", 3))
+                break;
+              return Intrinsic::hexagon_M4_xor_xacc;	 // "exagon.M4.xor.xacc"
+            }
+            break;
+          }
+          break;
+        case '5':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, ".v", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[12] != 'm')
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "cbsu", 4))
+                break;
+              return Intrinsic::hexagon_M5_vdmacbsu;	 // "exagon.M5.vdmacbsu"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "ybsu", 4))
+                break;
+              return Intrinsic::hexagon_M5_vdmpybsu;	 // "exagon.M5.vdmpybsu"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (NameR[12] != 'm')
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "cb", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 's':	 // 1 string to match.
+                if (NameR[17] != 'u')
+                  break;
+                return Intrinsic::hexagon_M5_vrmacbsu;	 // "exagon.M5.vrmacbsu"
+              case 'u':	 // 1 string to match.
+                if (NameR[17] != 'u')
+                  break;
+                return Intrinsic::hexagon_M5_vrmacbuu;	 // "exagon.M5.vrmacbuu"
+              }
+              break;
+            case 'p':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "yb", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 's':	 // 1 string to match.
+                if (NameR[17] != 'u')
+                  break;
+                return Intrinsic::hexagon_M5_vrmpybsu;	 // "exagon.M5.vrmpybsu"
+              case 'u':	 // 1 string to match.
+                if (NameR[17] != 'u')
+                  break;
+                return Intrinsic::hexagon_M5_vrmpybuu;	 // "exagon.M5.vrmpybuu"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 35 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 31 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_i_vh;	 // "exagon.S2.asl.i.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_i_vw;	 // "exagon.S2.asl.i.vw"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_r_vh;	 // "exagon.S2.asl.r.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asl_r_vw;	 // "exagon.S2.asl.r.vw"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_i_vh;	 // "exagon.S2.asr.i.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_i_vw;	 // "exagon.S2.asr.i.vw"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_r_vh;	 // "exagon.S2.asr.r.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_asr_r_vw;	 // "exagon.S2.asr.r.vw"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "lrbit.", 6))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_clrbit_i;	 // "exagon.S2.clrbit.i"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_clrbit_r;	 // "exagon.S2.clrbit.r"
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtractu", 7))
+              break;
+            return Intrinsic::hexagon_S2_extractu;	 // "exagon.S2.extractu"
+          case 'l':	 // 6 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, ".r.v", 4))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsl_r_vh;	 // "exagon.S2.lsl.r.vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsl_r_vw;	 // "exagon.S2.lsl.r.vw"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_i_vh;	 // "exagon.S2.lsr.i.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_i_vw;	 // "exagon.S2.lsr.i.vw"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (memcmp(NameR.data()+15, ".v", 2))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_r_vh;	 // "exagon.S2.lsr.r.vh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S2_lsr_r_vw;	 // "exagon.S2.lsr.r.vw"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "tbit.", 5))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_setbit_i;	 // "exagon.S2.setbit.i"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_setbit_r;	 // "exagon.S2.setbit.r"
+              }
+              break;
+            case 'v':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "sathub", 6))
+                break;
+              return Intrinsic::hexagon_S2_svsathub;	 // "exagon.S2.svsathub"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "stbit.", 6))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_tstbit_i;	 // "exagon.S2.tstbit.i"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_tstbit_r;	 // "exagon.S2.tstbit.r"
+            }
+            break;
+          case 'v':	 // 9 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "lign", 4))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (NameR[17] != 'b')
+                  break;
+                return Intrinsic::hexagon_S2_valignib;	 // "exagon.S2.valignib"
+              case 'r':	 // 1 string to match.
+                if (NameR[17] != 'b')
+                  break;
+                return Intrinsic::hexagon_S2_valignrb;	 // "exagon.S2.valignrb"
+              }
+              break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "rotate", 6))
+                break;
+              return Intrinsic::hexagon_S2_vcrotate;	 // "exagon.S2.vcrotate"
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "platr", 5))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_vsplatrb;	 // "exagon.S2.vsplatrb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_vsplatrh;	 // "exagon.S2.vsplatrh"
+              }
+              break;
+            case 't':	 // 4 strings to match.
+              if (memcmp(NameR.data()+12, "run", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (NameR[17] != 'b')
+                    break;
+                  return Intrinsic::hexagon_S2_vtrunehb;	 // "exagon.S2.vtrunehb"
+                case 'w':	 // 1 string to match.
+                  if (NameR[17] != 'h')
+                    break;
+                  return Intrinsic::hexagon_S2_vtrunewh;	 // "exagon.S2.vtrunewh"
+                }
+                break;
+              case 'o':	 // 2 strings to match.
+                switch (NameR[16]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (NameR[17] != 'b')
+                    break;
+                  return Intrinsic::hexagon_S2_vtrunohb;	 // "exagon.S2.vtrunohb"
+                case 'w':	 // 1 string to match.
+                  if (NameR[17] != 'h')
+                    break;
+                  return Intrinsic::hexagon_S2_vtrunowh;	 // "exagon.S2.vtrunowh"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "lbp", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "ddi", 3))
+                break;
+              return Intrinsic::hexagon_S4_clbpaddi;	 // "exagon.S4.clbpaddi"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "orm", 3))
+                break;
+              return Intrinsic::hexagon_S4_clbpnorm;	 // "exagon.S4.clbpnorm"
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtractp", 7))
+              break;
+            return Intrinsic::hexagon_S4_extractp;	 // "exagon.S4.extractp"
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "r.andix", 7))
+              break;
+            return Intrinsic::hexagon_S4_or_andix;	 // "exagon.S4.or.andix"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 19:	 // 81 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 11 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 3 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ombineii", 8))
+              break;
+            return Intrinsic::hexagon_A2_combineii;	 // "exagon.A2.combineii"
+          case 'v':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ddb.map", 7))
+                break;
+              return Intrinsic::hexagon_A2_vaddb_map;	 // "exagon.A2.vaddb.map"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ubb.map", 7))
+                break;
+              return Intrinsic::hexagon_A2_vsubb_map;	 // "exagon.A2.vsubb.map"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 8 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "itspliti", 8))
+              break;
+            return Intrinsic::hexagon_A4_bitspliti;	 // "exagon.A4.bitspliti"
+          case 'c':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'o':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "mbine", 5))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (NameR[18] != 'r')
+                  break;
+                return Intrinsic::hexagon_A4_combineir;	 // "exagon.A4.combineir"
+              case 'r':	 // 1 string to match.
+                if (NameR[18] != 'i')
+                  break;
+                return Intrinsic::hexagon_A4_combineri;	 // "exagon.A4.combineri"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "ound.r", 6))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cround_ri;	 // "exagon.A4.cround.ri"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cround_rr;	 // "exagon.A4.cround.rr"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "cmp", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "gtui", 4))
+                break;
+              return Intrinsic::hexagon_A4_vcmpbgtui;	 // "exagon.A4.vcmpbgtui"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "gtui", 4))
+                break;
+              return Intrinsic::hexagon_A4_vcmphgtui;	 // "exagon.A4.vcmphgtui"
+            case 'w':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "gtui", 4))
+                break;
+              return Intrinsic::hexagon_A4_vcmpwgtui;	 // "exagon.A4.vcmpwgtui"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 2 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".pxfer.map", 10))
+            break;
+          return Intrinsic::hexagon_C2_pxfer_map;	 // "exagon.C2.pxfer.map"
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".nbitsclri", 10))
+            break;
+          return Intrinsic::hexagon_C4_nbitsclri;	 // "exagon.C4.nbitsclri"
+        }
+        break;
+      case 'F':	 // 12 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'c':	 // 8 strings to match.
+          if (memcmp(NameR.data()+11, "onv.", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (NameR[18] != 'f')
+                  break;
+                return Intrinsic::hexagon_F2_conv_d2df;	 // "exagon.F2.conv.d2df"
+              case 's':	 // 1 string to match.
+                if (NameR[18] != 'f')
+                  break;
+                return Intrinsic::hexagon_F2_conv_d2sf;	 // "exagon.F2.conv.d2sf"
+              }
+              break;
+            case 'f':	 // 2 strings to match.
+              if (NameR[17] != '2')
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_conv_df2d;	 // "exagon.F2.conv.df2d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_conv_df2w;	 // "exagon.F2.conv.df2w"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "f2", 2))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_sf2d;	 // "exagon.F2.conv.sf2d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_sf2w;	 // "exagon.F2.conv.sf2w"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            if (NameR[16] != '2')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (NameR[18] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_w2df;	 // "exagon.F2.conv.w2df"
+            case 's':	 // 1 string to match.
+              if (NameR[18] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_w2sf;	 // "exagon.F2.conv.w2sf"
+            }
+            break;
+          }
+          break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "ffm", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".lib", 4))
+              break;
+            return Intrinsic::hexagon_F2_dffma_lib;	 // "exagon.F2.dffma.lib"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".lib", 4))
+              break;
+            return Intrinsic::hexagon_F2_dffms_lib;	 // "exagon.F2.dffms.lib"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "ffm", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".lib", 4))
+              break;
+            return Intrinsic::hexagon_F2_sffma_lib;	 // "exagon.F2.sffma.lib"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".lib", 4))
+              break;
+            return Intrinsic::hexagon_F2_sffms_lib;	 // "exagon.F2.sffms.lib"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 44 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 41 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 8 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 6 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "csc.s", 5))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmacsc_s0;	 // "exagon.M2.cmacsc.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmacsc_s1;	 // "exagon.M2.cmacsc.s1"
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                if (NameR[13] != 'y')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'r':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "s.s", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpyrs_s0;	 // "exagon.M2.cmpyrs.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpyrs_s1;	 // "exagon.M2.cmpyrs.s1"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "c.s", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpysc_s0;	 // "exagon.M2.cmpysc.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_cmpysc_s1;	 // "exagon.M2.cmpysc.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "acsc.s", 6))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cnacsc_s0;	 // "exagon.M2.cnacsc.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cnacsc_s1;	 // "exagon.M2.cnacsc.s1"
+              }
+              break;
+            }
+            break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mmpy", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".s1", 3))
+                break;
+              return Intrinsic::hexagon_M2_hmmpyh_s1;	 // "exagon.M2.hmmpyh.s1"
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".s1", 3))
+                break;
+              return Intrinsic::hexagon_M2_hmmpyl_s1;	 // "exagon.M2.hmmpyl.s1"
+            }
+            break;
+          case 'm':	 // 21 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 12 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 4 strings to match.
+                if (NameR[13] != 'c')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "s.s", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmachs_s0;	 // "exagon.M2.mmachs.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmachs_s1;	 // "exagon.M2.mmachs.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "s.s", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacls_s0;	 // "exagon.M2.mmacls.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacls_s1;	 // "exagon.M2.mmacls.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'p':	 // 8 strings to match.
+                if (NameR[13] != 'y')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, ".rs", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyh_rs0;	 // "exagon.M2.mmpyh.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyh_rs1;	 // "exagon.M2.mmpyh.rs1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, ".rs", 3))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyl_rs0;	 // "exagon.M2.mmpyl.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyl_rs1;	 // "exagon.M2.mmpyl.rs1"
+                  }
+                  break;
+                case 'u':	 // 4 strings to match.
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+16, ".s", 2))
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmpyuh_s0;	 // "exagon.M2.mmpyuh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmpyuh_s1;	 // "exagon.M2.mmpyuh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+16, ".s", 2))
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmpyul_s0;	 // "exagon.M2.mmpyul.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmpyul_s1;	 // "exagon.M2.mmpyul.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 9 strings to match.
+              if (memcmp(NameR.data()+12, "y.", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".s", 2))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_hh_s0;	 // "exagon.M2.mpy.hh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_hh_s1;	 // "exagon.M2.mpy.hh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".s", 2))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_hl_s0;	 // "exagon.M2.mpy.hl.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_hl_s1;	 // "exagon.M2.mpy.hl.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".s", 2))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_lh_s0;	 // "exagon.M2.mpy.lh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_lh_s1;	 // "exagon.M2.mpy.lh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".s", 2))
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_ll_s0;	 // "exagon.M2.mpy.ll.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_ll_s1;	 // "exagon.M2.mpy.ll.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "p.s1", 4))
+                  break;
+                return Intrinsic::hexagon_M2_mpy_up_s1;	 // "exagon.M2.mpy.up.s1"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 10 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "bsdiff", 6))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vabsdiffh;	 // "exagon.M2.vabsdiffh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vabsdiffw;	 // "exagon.M2.vabsdiffw"
+              }
+              break;
+            case 'd':	 // 4 strings to match.
+              if (NameR[12] != 'm')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "cs.s", 4))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vdmacs_s0;	 // "exagon.M2.vdmacs.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vdmacs_s1;	 // "exagon.M2.vdmacs.s1"
+                }
+                break;
+              case 'p':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "ys.s", 4))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vdmpys_s0;	 // "exagon.M2.vdmpys.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vdmpys_s1;	 // "exagon.M2.vdmpys.s1"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 4 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "c2s.s", 5))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2s_s0;	 // "exagon.M2.vmac2s.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2s_s1;	 // "exagon.M2.vmac2s.s1"
+                }
+                break;
+              case 'p':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "y2s.s", 5))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2s_s0;	 // "exagon.M2.vmpy2s.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2s_s1;	 // "exagon.M2.vmpy2s.s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 3 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mpy", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".whc", 4))
+                break;
+              return Intrinsic::hexagon_M4_cmpyi_whc;	 // "exagon.M4.cmpyi.whc"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".whc", 4))
+                break;
+              return Intrinsic::hexagon_M4_cmpyr_whc;	 // "exagon.M4.cmpyr.whc"
+            }
+            break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "mpyw.acc", 8))
+              break;
+            return Intrinsic::hexagon_M4_pmpyw_acc;	 // "exagon.M4.pmpyw.acc"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 12 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtractup", 8))
+              break;
+            return Intrinsic::hexagon_S2_extractup;	 // "exagon.S2.extractup"
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "nsert.rp", 8))
+              break;
+            return Intrinsic::hexagon_S2_insert_rp;	 // "exagon.S2.insert.rp"
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "splice", 6))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (NameR[18] != 'b')
+                break;
+              return Intrinsic::hexagon_S2_vspliceib;	 // "exagon.S2.vspliceib"
+            case 'r':	 // 1 string to match.
+              if (NameR[18] != 'b')
+                break;
+              return Intrinsic::hexagon_S2_vsplicerb;	 // "exagon.S2.vsplicerb"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 7 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "tstbit.", 7))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_S4_ntstbit_i;	 // "exagon.S4.ntstbit.i"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S4_ntstbit_r;	 // "exagon.S4.ntstbit.r"
+            }
+            break;
+          case 'v':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "crotate", 7))
+                break;
+              return Intrinsic::hexagon_S4_vrcrotate;	 // "exagon.S4.vrcrotate"
+            case 'x':	 // 4 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "ddsub", 5))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S4_vxaddsubh;	 // "exagon.S4.vxaddsubh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S4_vxaddsubw;	 // "exagon.S4.vxaddsubw"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, "ubadd", 5))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_S4_vxsubaddh;	 // "exagon.S4.vxsubaddh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_S4_vxsubaddw;	 // "exagon.S4.vxsubaddw"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '5':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".popcountp", 10))
+            break;
+          return Intrinsic::hexagon_S5_popcountp;	 // "exagon.S5.popcountp"
+        }
+        break;
+      }
+      break;
+    case 20:	 // 95 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 4 strings to match.
+        if (memcmp(NameR.data()+8, "2.combine.", 10))
+          break;
+        switch (NameR[18]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          switch (NameR[19]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_combine_hh;	 // "exagon.A2.combine.hh"
+          case 'l':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_combine_hl;	 // "exagon.A2.combine.hl"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          switch (NameR[19]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_combine_lh;	 // "exagon.A2.combine.lh"
+          case 'l':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_combine_ll;	 // "exagon.A2.combine.ll"
+          }
+          break;
+        }
+        break;
+      case 'F':	 // 10 strings to match.
+        if (memcmp(NameR.data()+8, "2.conv.", 7))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'd':	 // 3 strings to match.
+          if (memcmp(NameR.data()+16, "f2", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (NameR[19] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_df2sf;	 // "exagon.F2.conv.df2sf"
+          case 'u':	 // 2 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_df2ud;	 // "exagon.F2.conv.df2ud"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_df2uw;	 // "exagon.F2.conv.df2uw"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 3 strings to match.
+          if (memcmp(NameR.data()+16, "f2", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (NameR[19] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_sf2df;	 // "exagon.F2.conv.sf2df"
+          case 'u':	 // 2 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_sf2ud;	 // "exagon.F2.conv.sf2ud"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_sf2uw;	 // "exagon.F2.conv.sf2uw"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[17] != '2')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (NameR[19] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_ud2df;	 // "exagon.F2.conv.ud2df"
+            case 's':	 // 1 string to match.
+              if (NameR[19] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_ud2sf;	 // "exagon.F2.conv.ud2sf"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            if (NameR[17] != '2')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (NameR[19] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_uw2df;	 // "exagon.F2.conv.uw2df"
+            case 's':	 // 1 string to match.
+              if (NameR[19] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_uw2sf;	 // "exagon.F2.conv.uw2sf"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 58 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 49 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mpyrsc.s", 8))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cmpyrsc_s0;	 // "exagon.M2.cmpyrsc.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cmpyrsc_s1;	 // "exagon.M2.cmpyrsc.s1"
+            }
+            break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "pmpy", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "s.s0", 4))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyss_s0;	 // "exagon.M2.dpmpyss.s0"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "u.s0", 4))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyuu_s0;	 // "exagon.M2.dpmpyuu.s0"
+            }
+            break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mmpy", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".rs1", 4))
+                break;
+              return Intrinsic::hexagon_M2_hmmpyh_rs1;	 // "exagon.M2.hmmpyh.rs1"
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".rs1", 4))
+                break;
+              return Intrinsic::hexagon_M2_hmmpyl_rs1;	 // "exagon.M2.hmmpyl.rs1"
+            }
+            break;
+          case 'm':	 // 28 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'm':	 // 12 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 8 strings to match.
+                if (NameR[13] != 'c')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "s.rs", 4))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmachs_rs0;	 // "exagon.M2.mmachs.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmachs_rs1;	 // "exagon.M2.mmachs.rs1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+15, "s.rs", 4))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacls_rs0;	 // "exagon.M2.mmacls.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacls_rs1;	 // "exagon.M2.mmacls.rs1"
+                  }
+                  break;
+                case 'u':	 // 4 strings to match.
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+16, "s.s", 3))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmacuhs_s0;	 // "exagon.M2.mmacuhs.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmacuhs_s1;	 // "exagon.M2.mmacuhs.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+16, "s.s", 3))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmaculs_s0;	 // "exagon.M2.mmaculs.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mmaculs_s1;	 // "exagon.M2.mmaculs.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                if (memcmp(NameR.data()+13, "yu", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".rs", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyuh_rs0;	 // "exagon.M2.mmpyuh.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyuh_rs1;	 // "exagon.M2.mmpyuh.rs1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, ".rs", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyul_rs0;	 // "exagon.M2.mmpyul.rs0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyul_rs1;	 // "exagon.M2.mmpyul.rs1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 16 strings to match.
+              if (NameR[12] != 'y')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 8 strings to match.
+                if (NameR[14] != '.')
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_hh_s0;	 // "exagon.M2.mpyd.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_hh_s1;	 // "exagon.M2.mpyd.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_hl_s0;	 // "exagon.M2.mpyd.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_hl_s1;	 // "exagon.M2.mpyd.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_lh_s0;	 // "exagon.M2.mpyd.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_lh_s1;	 // "exagon.M2.mpyd.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_ll_s0;	 // "exagon.M2.mpyd.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_ll_s1;	 // "exagon.M2.mpyd.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'u':	 // 8 strings to match.
+                if (NameR[14] != '.')
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_hh_s0;	 // "exagon.M2.mpyu.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_hh_s1;	 // "exagon.M2.mpyu.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_hl_s0;	 // "exagon.M2.mpyu.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_hl_s1;	 // "exagon.M2.mpyu.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_lh_s0;	 // "exagon.M2.mpyu.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_lh_s1;	 // "exagon.M2.mpyu.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+17, ".s", 2))
+                      break;
+                    switch (NameR[19]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_ll_s0;	 // "exagon.M2.mpyu.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_ll_s1;	 // "exagon.M2.mpyu.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 15 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "mpyrs.s", 7))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmpyrs_s0;	 // "exagon.M2.vdmpyrs.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmpyrs_s1;	 // "exagon.M2.vdmpyrs.s1"
+              }
+              break;
+            case 'm':	 // 8 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 4 strings to match.
+                if (memcmp(NameR.data()+13, "c2", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'e':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "s.s", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmac2es_s0;	 // "exagon.M2.vmac2es.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmac2es_s1;	 // "exagon.M2.vmac2es.s1"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "u.s", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmac2su_s0;	 // "exagon.M2.vmac2su.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmac2su_s1;	 // "exagon.M2.vmac2su.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                if (memcmp(NameR.data()+13, "y2", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'e':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "s.s", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmpy2es_s0;	 // "exagon.M2.vmpy2es.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmpy2es_s1;	 // "exagon.M2.vmpy2es.s1"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "u.s", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmpy2su_s0;	 // "exagon.M2.vmpy2su.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vmpy2su_s1;	 // "exagon.M2.vmpy2su.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 5 strings to match.
+              if (memcmp(NameR.data()+12, "cm", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (NameR[15] != 'c')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_vrcmaci_s0;	 // "exagon.M2.vrcmaci.s0"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_vrcmacr_s0;	 // "exagon.M2.vrcmacr.s0"
+                }
+                break;
+              case 'p':	 // 3 strings to match.
+                if (NameR[15] != 'y')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_vrcmpyi_s0;	 // "exagon.M2.vrcmpyi.s0"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".s0", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_vrcmpyr_s0;	 // "exagon.M2.vrcmpyr.s0"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".s1", 3))
+                    break;
+                  return Intrinsic::hexagon_M2_vrcmpys_s1;	 // "exagon.M2.vrcmpys.s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 9 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 4 strings to match.
+            if (memcmp(NameR.data()+11, "pyr", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(NameR.data()+15, ".add", 4))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_mpyri_addi;	 // "exagon.M4.mpyri.addi"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_mpyri_addr;	 // "exagon.M4.mpyri.addr"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(NameR.data()+15, ".add", 4))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_mpyrr_addi;	 // "exagon.M4.mpyrr.addi"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_mpyrr_addr;	 // "exagon.M4.mpyrr.addr"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 5 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "mpyh.acc", 8))
+                break;
+              return Intrinsic::hexagon_M4_vpmpyh_acc;	 // "exagon.M4.vpmpyh.acc"
+            case 'r':	 // 4 strings to match.
+              if (memcmp(NameR.data()+12, "mpy", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "h.s", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M4_vrmpyeh_s0;	 // "exagon.M4.vrmpyeh.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M4_vrmpyeh_s1;	 // "exagon.M4.vrmpyeh.s1"
+                }
+                break;
+              case 'o':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "h.s", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M4_vrmpyoh_s0;	 // "exagon.M4.vrmpyoh.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M4_vrmpyoh_s1;	 // "exagon.M4.vrmpyoh.s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 23 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 17 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asl_i_p_or;	 // "exagon.S2.asl.i.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asl_i_r_or;	 // "exagon.S2.asl.i.r.or"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asl_r_p_or;	 // "exagon.S2.asl.r.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asl_r_r_or;	 // "exagon.S2.asl.r.r.or"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asr_i_p_or;	 // "exagon.S2.asr.i.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asr_i_r_or;	 // "exagon.S2.asr.i.r.or"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asr_r_p_or;	 // "exagon.S2.asr.r.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_asr_r_r_or;	 // "exagon.S2.asr.r.r.or"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (NameR[11] != 'n')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ertp.rp", 7))
+                break;
+              return Intrinsic::hexagon_S2_insertp_rp;	 // "exagon.S2.insertp.rp"
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "erleave", 7))
+                break;
+              return Intrinsic::hexagon_S2_interleave;	 // "exagon.S2.interleave"
+            }
+            break;
+          case 'l':	 // 6 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, ".r.", 3))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, ".or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsl_r_p_or;	 // "exagon.S2.lsl.r.p.or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, ".or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsl_r_r_or;	 // "exagon.S2.lsl.r.r.or"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_i_p_or;	 // "exagon.S2.lsr.i.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_i_r_or;	 // "exagon.S2.lsr.i.r.or"
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_r_p_or;	 // "exagon.S2.lsr.r.p.or"
+                case 'r':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, ".or", 3))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_r_r_or;	 // "exagon.S2.lsr.r.r.or"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rndpackwh", 9))
+              break;
+            return Intrinsic::hexagon_S2_vrndpackwh;	 // "exagon.S2.vrndpackwh"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtract.rp", 9))
+              break;
+            return Intrinsic::hexagon_S4_extract_rp;	 // "exagon.S4.extract.rp"
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "ri.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "sl.ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_ori_asl_ri;	 // "exagon.S4.ori.asl.ri"
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "sr.ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_ori_lsr_ri;	 // "exagon.S4.ori.lsr.ri"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (NameR[11] != 'x')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ddsubhr", 7))
+                break;
+              return Intrinsic::hexagon_S4_vxaddsubhr;	 // "exagon.S4.vxaddsubhr"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ubaddhr", 7))
+                break;
+              return Intrinsic::hexagon_S4_vxsubaddhr;	 // "exagon.S4.vxsubaddhr"
+            }
+            break;
+          }
+          break;
+        case '5':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".asrhub.sat", 11))
+            break;
+          return Intrinsic::hexagon_S5_asrhub_sat;	 // "exagon.S5.asrhub.sat"
+        }
+        break;
+      }
+      break;
+    case 21:	 // 96 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 16 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 14 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "ddh.", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              if (memcmp(NameR.data()+16, "16.", 3))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                switch (NameR[20]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_addh_h16_hh;	 // "exagon.A2.addh.h16.hh"
+                case 'l':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_addh_h16_hl;	 // "exagon.A2.addh.h16.hl"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                switch (NameR[20]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_addh_h16_lh;	 // "exagon.A2.addh.h16.lh"
+                case 'l':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_addh_h16_ll;	 // "exagon.A2.addh.h16.ll"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "16.", 3))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (NameR[20] != 'l')
+                  break;
+                return Intrinsic::hexagon_A2_addh_l16_hl;	 // "exagon.A2.addh.l16.hl"
+              case 'l':	 // 1 string to match.
+                if (NameR[20] != 'l')
+                  break;
+                return Intrinsic::hexagon_A2_addh_l16_ll;	 // "exagon.A2.addh.l16.ll"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "ubh.", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              if (memcmp(NameR.data()+16, "16.", 3))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                switch (NameR[20]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_subh_h16_hh;	 // "exagon.A2.subh.h16.hh"
+                case 'l':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_subh_h16_hl;	 // "exagon.A2.subh.h16.hl"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                switch (NameR[20]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_subh_h16_lh;	 // "exagon.A2.subh.h16.lh"
+                case 'l':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_subh_h16_ll;	 // "exagon.A2.subh.h16.ll"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "16.", 3))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (NameR[20] != 'l')
+                  break;
+                return Intrinsic::hexagon_A2_subh_l16_hl;	 // "exagon.A2.subh.l16.hl"
+              case 'l':	 // 1 string to match.
+                if (NameR[20] != 'l')
+                  break;
+                return Intrinsic::hexagon_A2_subh_l16_ll;	 // "exagon.A2.subh.l16.ll"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (NameR[11] != 'r')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ddub.acc", 8))
+                break;
+              return Intrinsic::hexagon_A2_vraddub_acc;	 // "exagon.A2.vraddub.acc"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "adub.acc", 8))
+                break;
+              return Intrinsic::hexagon_A2_vrsadub_acc;	 // "exagon.A2.vrsadub.acc"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "oundscheck", 10))
+              break;
+            return Intrinsic::hexagon_A4_boundscheck;	 // "exagon.A4.boundscheck"
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "cmpbeq.any", 10))
+              break;
+            return Intrinsic::hexagon_A4_vcmpbeq_any;	 // "exagon.A4.vcmpbeq.any"
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "4.fastcorner9", 13))
+          break;
+        return Intrinsic::hexagon_C4_fastcorner9;	 // "exagon.C4.fastcorner9"
+      case 'M':	 // 16 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'm':	 // 12 strings to match.
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "acu", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "s.rs", 4))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmacuhs_rs0;	 // "exagon.M2.mmacuhs.rs0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmacuhs_rs1;	 // "exagon.M2.mmacuhs.rs1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "s.rs", 4))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmaculs_rs0;	 // "exagon.M2.mmaculs.rs0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmaculs_rs1;	 // "exagon.M2.mmaculs.rs1"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 8 strings to match.
+            if (memcmp(NameR.data()+12, "yud.", 4))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, ".s", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_hh_s0;	 // "exagon.M2.mpyud.hh.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_hh_s1;	 // "exagon.M2.mpyud.hh.s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, ".s", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_hl_s0;	 // "exagon.M2.mpyud.hl.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_hl_s1;	 // "exagon.M2.mpyud.hl.s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, ".s", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_lh_s0;	 // "exagon.M2.mpyud.lh.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_lh_s1;	 // "exagon.M2.mpyud.lh.s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, ".s", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_ll_s0;	 // "exagon.M2.mpyud.ll.s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpyud_ll_s1;	 // "exagon.M2.mpyud.ll.s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "rcm", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (NameR[15] != 'c')
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".s0c", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrcmaci_s0c;	 // "exagon.M2.vrcmaci.s0c"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".s0c", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrcmacr_s0c;	 // "exagon.M2.vrcmacr.s0c"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[15] != 'y')
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".s0c", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrcmpyi_s0c;	 // "exagon.M2.vrcmpyi.s0c"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".s0c", 4))
+                break;
+              return Intrinsic::hexagon_M2_vrcmpyr_s0c;	 // "exagon.M2.vrcmpyr.s0c"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 63 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 56 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 32 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "dasl.rrri", 9))
+                break;
+              return Intrinsic::hexagon_S2_addasl_rrri;	 // "exagon.S2.addasl.rrri"
+            case 's':	 // 31 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'l':	 // 15 strings to match.
+                if (NameR[13] != '.')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'i':	 // 7 strings to match.
+                  if (NameR[15] != '.')
+                    break;
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'p':	 // 3 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_i_p_acc;	 // "exagon.S2.asl.i.p.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_i_p_and;	 // "exagon.S2.asl.i.p.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_p_nac;	 // "exagon.S2.asl.i.p.nac"
+                    }
+                    break;
+                  case 'r':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_i_r_acc;	 // "exagon.S2.asl.i.r.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_i_r_and;	 // "exagon.S2.asl.i.r.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_r_nac;	 // "exagon.S2.asl.i.r.nac"
+                    case 's':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "at", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_r_sat;	 // "exagon.S2.asl.i.r.sat"
+                    }
+                    break;
+                  }
+                  break;
+                case 'r':	 // 8 strings to match.
+                  if (NameR[15] != '.')
+                    break;
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'p':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_r_p_acc;	 // "exagon.S2.asl.r.p.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_r_p_and;	 // "exagon.S2.asl.r.p.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_p_nac;	 // "exagon.S2.asl.r.p.nac"
+                    case 'x':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "or", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_p_xor;	 // "exagon.S2.asl.r.p.xor"
+                    }
+                    break;
+                  case 'r':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_r_r_acc;	 // "exagon.S2.asl.r.r.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asl_r_r_and;	 // "exagon.S2.asl.r.r.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_r_nac;	 // "exagon.S2.asl.r.r.nac"
+                    case 's':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "at", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_r_sat;	 // "exagon.S2.asl.r.r.sat"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 16 strings to match.
+                if (NameR[13] != '.')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'i':	 // 8 strings to match.
+                  if (NameR[15] != '.')
+                    break;
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'p':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_i_p_acc;	 // "exagon.S2.asr.i.p.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_i_p_and;	 // "exagon.S2.asr.i.p.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_p_nac;	 // "exagon.S2.asr.i.p.nac"
+                    case 'r':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "nd", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_p_rnd;	 // "exagon.S2.asr.i.p.rnd"
+                    }
+                    break;
+                  case 'r':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_i_r_acc;	 // "exagon.S2.asr.i.r.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_i_r_and;	 // "exagon.S2.asr.i.r.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_r_nac;	 // "exagon.S2.asr.i.r.nac"
+                    case 'r':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "nd", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_r_rnd;	 // "exagon.S2.asr.i.r.rnd"
+                    }
+                    break;
+                  }
+                  break;
+                case 'r':	 // 8 strings to match.
+                  if (NameR[15] != '.')
+                    break;
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'p':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_r_p_acc;	 // "exagon.S2.asr.r.p.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_r_p_and;	 // "exagon.S2.asr.r.p.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_p_nac;	 // "exagon.S2.asr.r.p.nac"
+                    case 'x':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "or", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_p_xor;	 // "exagon.S2.asr.r.p.xor"
+                    }
+                    break;
+                  case 'r':	 // 4 strings to match.
+                    if (NameR[17] != '.')
+                      break;
+                    switch (NameR[18]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      switch (NameR[19]) {
+                      default: break;
+                      case 'c':	 // 1 string to match.
+                        if (NameR[20] != 'c')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_r_r_acc;	 // "exagon.S2.asr.r.r.acc"
+                      case 'n':	 // 1 string to match.
+                        if (NameR[20] != 'd')
+                          break;
+                        return Intrinsic::hexagon_S2_asr_r_r_and;	 // "exagon.S2.asr.r.r.and"
+                      }
+                      break;
+                    case 'n':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "ac", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_r_nac;	 // "exagon.S2.asr.r.r.nac"
+                    case 's':	 // 1 string to match.
+                      if (memcmp(NameR.data()+19, "at", 2))
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_r_sat;	 // "exagon.S2.asr.r.r.sat"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtractu.rp", 10))
+              break;
+            return Intrinsic::hexagon_S2_extractu_rp;	 // "exagon.S2.extractu.rp"
+          case 'l':	 // 20 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 7 strings to match.
+              if (memcmp(NameR.data()+13, ".r.", 3))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'p':	 // 4 strings to match.
+                if (NameR[17] != '.')
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (NameR[19]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (NameR[20] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsl_r_p_acc;	 // "exagon.S2.lsl.r.p.acc"
+                  case 'n':	 // 1 string to match.
+                    if (NameR[20] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsl_r_p_and;	 // "exagon.S2.lsl.r.p.and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_p_nac;	 // "exagon.S2.lsl.r.p.nac"
+                case 'x':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "or", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_p_xor;	 // "exagon.S2.lsl.r.p.xor"
+                }
+                break;
+              case 'r':	 // 3 strings to match.
+                if (NameR[17] != '.')
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (NameR[19]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (NameR[20] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsl_r_r_acc;	 // "exagon.S2.lsl.r.r.acc"
+                  case 'n':	 // 1 string to match.
+                    if (NameR[20] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsl_r_r_and;	 // "exagon.S2.lsl.r.r.and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_r_nac;	 // "exagon.S2.lsl.r.r.nac"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 13 strings to match.
+              if (NameR[13] != '.')
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 6 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 3 strings to match.
+                  if (NameR[17] != '.')
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (NameR[19]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (NameR[20] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_i_p_acc;	 // "exagon.S2.lsr.i.p.acc"
+                    case 'n':	 // 1 string to match.
+                      if (NameR[20] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_i_p_and;	 // "exagon.S2.lsr.i.p.and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(NameR.data()+19, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_p_nac;	 // "exagon.S2.lsr.i.p.nac"
+                  }
+                  break;
+                case 'r':	 // 3 strings to match.
+                  if (NameR[17] != '.')
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (NameR[19]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (NameR[20] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_i_r_acc;	 // "exagon.S2.lsr.i.r.acc"
+                    case 'n':	 // 1 string to match.
+                      if (NameR[20] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_i_r_and;	 // "exagon.S2.lsr.i.r.and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(NameR.data()+19, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_r_nac;	 // "exagon.S2.lsr.i.r.nac"
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 7 strings to match.
+                if (NameR[15] != '.')
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'p':	 // 4 strings to match.
+                  if (NameR[17] != '.')
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (NameR[19]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (NameR[20] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_r_p_acc;	 // "exagon.S2.lsr.r.p.acc"
+                    case 'n':	 // 1 string to match.
+                      if (NameR[20] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_r_p_and;	 // "exagon.S2.lsr.r.p.and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(NameR.data()+19, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_p_nac;	 // "exagon.S2.lsr.r.p.nac"
+                  case 'x':	 // 1 string to match.
+                    if (memcmp(NameR.data()+19, "or", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_p_xor;	 // "exagon.S2.lsr.r.p.xor"
+                  }
+                  break;
+                case 'r':	 // 3 strings to match.
+                  if (NameR[17] != '.')
+                    break;
+                  switch (NameR[18]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (NameR[19]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (NameR[20] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_r_r_acc;	 // "exagon.S2.lsr.r.r.acc"
+                    case 'n':	 // 1 string to match.
+                      if (NameR[20] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_lsr_r_r_and;	 // "exagon.S2.lsr.r.r.and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(NameR.data()+19, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_r_nac;	 // "exagon.S2.lsr.r.r.nac"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "ogglebit.", 9))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_togglebit_i;	 // "exagon.S2.togglebit.i"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_togglebit_r;	 // "exagon.S2.togglebit.r"
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "rndpackwhs", 10))
+              break;
+            return Intrinsic::hexagon_S2_vrndpackwhs;	 // "exagon.S2.vrndpackwhs"
+          }
+          break;
+        case '4':	 // 7 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "di.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "sl.ri", 5))
+                  break;
+                return Intrinsic::hexagon_S4_addi_asl_ri;	 // "exagon.S4.addi.asl.ri"
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "sr.ri", 5))
+                  break;
+                return Intrinsic::hexagon_S4_addi_lsr_ri;	 // "exagon.S4.addi.lsr.ri"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "di.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "sl.ri", 5))
+                  break;
+                return Intrinsic::hexagon_S4_andi_asl_ri;	 // "exagon.S4.andi.asl.ri"
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "sr.ri", 5))
+                  break;
+                return Intrinsic::hexagon_S4_andi_lsr_ri;	 // "exagon.S4.andi.lsr.ri"
+              }
+              break;
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "xtractp.rp", 10))
+              break;
+            return Intrinsic::hexagon_S4_extractp_rp;	 // "exagon.S4.extractp.rp"
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "ubi.", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "sl.ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_subi_asl_ri;	 // "exagon.S4.subi.asl.ri"
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "sr.ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_subi_lsr_ri;	 // "exagon.S4.subi.lsr.ri"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 22:	 // 9 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 2 strings to match.
+        if (memcmp(NameR.data()+8, "4.round.r", 9))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+18, ".sat", 4))
+            break;
+          return Intrinsic::hexagon_A4_round_ri_sat;	 // "exagon.A4.round.ri.sat"
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+18, ".sat", 4))
+            break;
+          return Intrinsic::hexagon_A4_round_rr_sat;	 // "exagon.A4.round.rr.sat"
+        }
+        break;
+      case 'M':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "2.vrcmpys.s1rp", 14))
+          break;
+        return Intrinsic::hexagon_M2_vrcmpys_s1rp;	 // "exagon.M2.vrcmpys.s1rp"
+      case 'S':	 // 6 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "sl.i.", 5))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, ".xacc", 5))
+              break;
+            return Intrinsic::hexagon_S2_asl_i_p_xacc;	 // "exagon.S2.asl.i.p.xacc"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, ".xacc", 5))
+              break;
+            return Intrinsic::hexagon_S2_asl_i_r_xacc;	 // "exagon.S2.asl.i.r.xacc"
+          }
+          break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "einterleave", 11))
+            break;
+          return Intrinsic::hexagon_S2_deinterleave;	 // "exagon.S2.deinterleave"
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "xtractup.rp", 11))
+            break;
+          return Intrinsic::hexagon_S2_extractup_rp;	 // "exagon.S2.extractup.rp"
+        case 'l':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "sr.i.", 5))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, ".xacc", 5))
+              break;
+            return Intrinsic::hexagon_S2_lsr_i_p_xacc;	 // "exagon.S2.lsr.i.p.xacc"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, ".xacc", 5))
+              break;
+            return Intrinsic::hexagon_S2_lsr_i_r_xacc;	 // "exagon.S2.lsr.i.r.xacc"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 23:	 // 42 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'M':	 // 38 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 35 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 33 strings to match.
+            if (memcmp(NameR.data()+11, "py.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'a':	 // 8 strings to match.
+              if (memcmp(NameR.data()+15, "cc.", 3))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_hh_s0;	 // "exagon.M2.mpy.acc.hh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_hh_s1;	 // "exagon.M2.mpy.acc.hh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_hl_s0;	 // "exagon.M2.mpy.acc.hl.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_hl_s1;	 // "exagon.M2.mpy.acc.hl.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_lh_s0;	 // "exagon.M2.mpy.acc.lh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_lh_s1;	 // "exagon.M2.mpy.acc.lh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_ll_s0;	 // "exagon.M2.mpy.acc.ll.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_acc_ll_s1;	 // "exagon.M2.mpy.acc.ll.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 8 strings to match.
+              if (memcmp(NameR.data()+15, "ac.", 3))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_hh_s0;	 // "exagon.M2.mpy.nac.hh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_hh_s1;	 // "exagon.M2.mpy.nac.hh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_hl_s0;	 // "exagon.M2.mpy.nac.hl.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_hl_s1;	 // "exagon.M2.mpy.nac.hl.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_lh_s0;	 // "exagon.M2.mpy.nac.lh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_lh_s1;	 // "exagon.M2.mpy.nac.lh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_ll_s0;	 // "exagon.M2.mpy.nac.ll.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_nac_ll_s1;	 // "exagon.M2.mpy.nac.ll.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 8 strings to match.
+              if (memcmp(NameR.data()+15, "nd.", 3))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_hh_s0;	 // "exagon.M2.mpy.rnd.hh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_hh_s1;	 // "exagon.M2.mpy.rnd.hh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_hl_s0;	 // "exagon.M2.mpy.rnd.hl.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_hl_s1;	 // "exagon.M2.mpy.rnd.hl.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_lh_s0;	 // "exagon.M2.mpy.rnd.lh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_lh_s1;	 // "exagon.M2.mpy.rnd.lh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_ll_s0;	 // "exagon.M2.mpy.rnd.ll.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_rnd_ll_s1;	 // "exagon.M2.mpy.rnd.ll.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 's':	 // 8 strings to match.
+              if (memcmp(NameR.data()+15, "at.", 3))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_hh_s0;	 // "exagon.M2.mpy.sat.hh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_hh_s1;	 // "exagon.M2.mpy.sat.hh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_hl_s0;	 // "exagon.M2.mpy.sat.hl.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_hl_s1;	 // "exagon.M2.mpy.sat.hl.s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_lh_s0;	 // "exagon.M2.mpy.sat.lh.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_lh_s1;	 // "exagon.M2.mpy.sat.lh.s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+20, ".s", 2))
+                    break;
+                  switch (NameR[22]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_ll_s0;	 // "exagon.M2.mpy.sat.ll.s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpy_sat_ll_s1;	 // "exagon.M2.mpy.sat.ll.s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "p.s1.sat", 8))
+                break;
+              return Intrinsic::hexagon_M2_mpy_up_s1_sat;	 // "exagon.M2.mpy.up.s1.sat"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "mpy2s.s", 7))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "pack", 4))
+                break;
+              return Intrinsic::hexagon_M2_vmpy2s_s0pack;	 // "exagon.M2.vmpy2s.s0pack"
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "pack", 4))
+                break;
+              return Intrinsic::hexagon_M2_vmpy2s_s1pack;	 // "exagon.M2.vmpy2s.s1pack"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 3 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "c.up.s1.sat", 11))
+                break;
+              return Intrinsic::hexagon_M4_mac_up_s1_sat;	 // "exagon.M4.mac.up.s1.sat"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "yri.addr.u2", 11))
+                break;
+              return Intrinsic::hexagon_M4_mpyri_addr_u2;	 // "exagon.M4.mpyri.addr.u2"
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ac.up.s1.sat", 12))
+              break;
+            return Intrinsic::hexagon_M4_nac_up_s1_sat;	 // "exagon.M4.nac.up.s1.sat"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 4 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, ".vsat", 5))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "b.nopack", 8))
+              break;
+            return Intrinsic::hexagon_S2_vsathb_nopack;	 // "exagon.S2.vsathb.nopack"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "h.nopack", 8))
+              break;
+            return Intrinsic::hexagon_S2_vsatwh_nopack;	 // "exagon.S2.vsatwh.nopack"
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".vrcrotate.acc", 14))
+            break;
+          return Intrinsic::hexagon_S4_vrcrotate_acc;	 // "exagon.S4.vrcrotate.acc"
+        case 'I':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".to.SXTHI.asrh", 14))
+            break;
+          return Intrinsic::hexagon_SI_to_SXTHI_asrh;	 // "exagon.SI.to.SXTHI.asrh"
+        }
+        break;
+      }
+      break;
+    case 24:	 // 64 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'F':	 // 4 strings to match.
+        if (memcmp(NameR.data()+8, "2.conv.", 7))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "f2", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_df2d_chop;	 // "exagon.F2.conv.df2d.chop"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_df2w_chop;	 // "exagon.F2.conv.df2w.chop"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "f2", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_sf2d_chop;	 // "exagon.F2.conv.sf2d.chop"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_sf2w_chop;	 // "exagon.F2.conv.sf2w.chop"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 56 strings to match.
+        switch (NameR[8]) {
+        default: break;
+        case '2':	 // 52 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'd':	 // 5 strings to match.
+            if (memcmp(NameR.data()+11, "pmpy", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 's':	 // 3 strings to match.
+              if (memcmp(NameR.data()+16, "s.", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "cc.s0", 5))
+                  break;
+                return Intrinsic::hexagon_M2_dpmpyss_acc_s0;	 // "exagon.M2.dpmpyss.acc.s0"
+              case 'n':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "ac.s0", 5))
+                  break;
+                return Intrinsic::hexagon_M2_dpmpyss_nac_s0;	 // "exagon.M2.dpmpyss.nac.s0"
+              case 'r':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "nd.s0", 5))
+                  break;
+                return Intrinsic::hexagon_M2_dpmpyss_rnd_s0;	 // "exagon.M2.dpmpyss.rnd.s0"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "u.", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "cc.s0", 5))
+                  break;
+                return Intrinsic::hexagon_M2_dpmpyuu_acc_s0;	 // "exagon.M2.dpmpyuu.acc.s0"
+              case 'n':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "ac.s0", 5))
+                  break;
+                return Intrinsic::hexagon_M2_dpmpyuu_nac_s0;	 // "exagon.M2.dpmpyuu.nac.s0"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 40 strings to match.
+            if (memcmp(NameR.data()+11, "py", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'd':	 // 24 strings to match.
+              if (NameR[14] != '.')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'a':	 // 8 strings to match.
+                if (memcmp(NameR.data()+16, "cc.", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_hh_s0;	 // "exagon.M2.mpyd.acc.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_hh_s1;	 // "exagon.M2.mpyd.acc.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_hl_s0;	 // "exagon.M2.mpyd.acc.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_hl_s1;	 // "exagon.M2.mpyd.acc.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_lh_s0;	 // "exagon.M2.mpyd.acc.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_lh_s1;	 // "exagon.M2.mpyd.acc.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_ll_s0;	 // "exagon.M2.mpyd.acc.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_acc_ll_s1;	 // "exagon.M2.mpyd.acc.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'n':	 // 8 strings to match.
+                if (memcmp(NameR.data()+16, "ac.", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_hh_s0;	 // "exagon.M2.mpyd.nac.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_hh_s1;	 // "exagon.M2.mpyd.nac.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_hl_s0;	 // "exagon.M2.mpyd.nac.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_hl_s1;	 // "exagon.M2.mpyd.nac.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_lh_s0;	 // "exagon.M2.mpyd.nac.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_lh_s1;	 // "exagon.M2.mpyd.nac.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_ll_s0;	 // "exagon.M2.mpyd.nac.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_nac_ll_s1;	 // "exagon.M2.mpyd.nac.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 8 strings to match.
+                if (memcmp(NameR.data()+16, "nd.", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_hh_s0;	 // "exagon.M2.mpyd.rnd.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_hh_s1;	 // "exagon.M2.mpyd.rnd.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_hl_s0;	 // "exagon.M2.mpyd.rnd.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_hl_s1;	 // "exagon.M2.mpyd.rnd.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_lh_s0;	 // "exagon.M2.mpyd.rnd.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_lh_s1;	 // "exagon.M2.mpyd.rnd.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_ll_s0;	 // "exagon.M2.mpyd.rnd.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyd_rnd_ll_s1;	 // "exagon.M2.mpyd.rnd.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 16 strings to match.
+              if (NameR[14] != '.')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'a':	 // 8 strings to match.
+                if (memcmp(NameR.data()+16, "cc.", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_hh_s0;	 // "exagon.M2.mpyu.acc.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_hh_s1;	 // "exagon.M2.mpyu.acc.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_hl_s0;	 // "exagon.M2.mpyu.acc.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_hl_s1;	 // "exagon.M2.mpyu.acc.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_lh_s0;	 // "exagon.M2.mpyu.acc.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_lh_s1;	 // "exagon.M2.mpyu.acc.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_ll_s0;	 // "exagon.M2.mpyu.acc.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_acc_ll_s1;	 // "exagon.M2.mpyu.acc.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'n':	 // 8 strings to match.
+                if (memcmp(NameR.data()+16, "ac.", 3))
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_hh_s0;	 // "exagon.M2.mpyu.nac.hh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_hh_s1;	 // "exagon.M2.mpyu.nac.hh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_hl_s0;	 // "exagon.M2.mpyu.nac.hl.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_hl_s1;	 // "exagon.M2.mpyu.nac.hl.s1"
+                    }
+                    break;
+                  }
+                  break;
+                case 'l':	 // 4 strings to match.
+                  switch (NameR[20]) {
+                  default: break;
+                  case 'h':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_lh_s0;	 // "exagon.M2.mpyu.nac.lh.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_lh_s1;	 // "exagon.M2.mpyu.nac.lh.s1"
+                    }
+                    break;
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+21, ".s", 2))
+                      break;
+                    switch (NameR[23]) {
+                    default: break;
+                    case '0':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_ll_s0;	 // "exagon.M2.mpyu.nac.ll.s0"
+                    case '1':	 // 1 string to match.
+                      return Intrinsic::hexagon_M2_mpyu_nac_ll_s1;	 // "exagon.M2.mpyu.nac.ll.s1"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 7 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'c':	 // 6 strings to match.
+              if (NameR[12] != 'm')
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "c.s0.sat.", 9))
+                  break;
+                switch (NameR[23]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmac_s0_sat_i;	 // "exagon.M2.vcmac.s0.sat.i"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmac_s0_sat_r;	 // "exagon.M2.vcmac.s0.sat.r"
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                if (memcmp(NameR.data()+14, "y.s", 3))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case '0':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+18, ".sat.", 5))
+                    break;
+                  switch (NameR[23]) {
+                  default: break;
+                  case 'i':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vcmpy_s0_sat_i;	 // "exagon.M2.vcmpy.s0.sat.i"
+                  case 'r':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vcmpy_s0_sat_r;	 // "exagon.M2.vcmpy.s0.sat.r"
+                  }
+                  break;
+                case '1':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+18, ".sat.", 5))
+                    break;
+                  switch (NameR[23]) {
+                  default: break;
+                  case 'i':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vcmpy_s1_sat_i;	 // "exagon.M2.vcmpy.s1.sat.i"
+                  case 'r':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_vcmpy_s1_sat_r;	 // "exagon.M2.vcmpy.s1.sat.r"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "cmpys.acc.s1", 12))
+                break;
+              return Intrinsic::hexagon_M2_vrcmpys_acc_s1;	 // "exagon.M2.vrcmpys.acc.s1"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, ".vrmpy", 6))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "h.acc.s", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_vrmpyeh_acc_s0;	 // "exagon.M4.vrmpyeh.acc.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_vrmpyeh_acc_s1;	 // "exagon.M4.vrmpyeh.acc.s1"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "h.acc.s", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_vrmpyoh_acc_s0;	 // "exagon.M4.vrmpyoh.acc.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_vrmpyoh_acc_s1;	 // "exagon.M4.vrmpyoh.acc.s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 4 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "sr.", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".svw.trun", 9))
+              break;
+            return Intrinsic::hexagon_S2_asr_i_svw_trun;	 // "exagon.S2.asr.i.svw.trun"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, ".svw.trun", 9))
+              break;
+            return Intrinsic::hexagon_S2_asr_r_svw_trun;	 // "exagon.S2.asr.r.svw.trun"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "sat", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "ub.nopack", 9))
+              break;
+            return Intrinsic::hexagon_S2_vsathub_nopack;	 // "exagon.S2.vsathub.nopack"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "uh.nopack", 9))
+              break;
+            return Intrinsic::hexagon_S2_vsatwuh_nopack;	 // "exagon.S2.vsatwuh.nopack"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 25:	 // 33 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.", 7))
+        break;
+      switch (NameR[7]) {
+      default: break;
+      case 'A':	 // 12 strings to match.
+        if (memcmp(NameR.data()+8, "2.", 2))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(NameR.data()+11, "ddh.", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            if (memcmp(NameR.data()+16, "16.sat.", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              switch (NameR[24]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_sat_hh;	 // "exagon.A2.addh.h16.sat.hh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_sat_hl;	 // "exagon.A2.addh.h16.sat.hl"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              switch (NameR[24]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_sat_lh;	 // "exagon.A2.addh.h16.sat.lh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_sat_ll;	 // "exagon.A2.addh.h16.sat.ll"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "16.sat.", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (NameR[24] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_addh_l16_sat_hl;	 // "exagon.A2.addh.l16.sat.hl"
+            case 'l':	 // 1 string to match.
+              if (NameR[24] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_addh_l16_sat_ll;	 // "exagon.A2.addh.l16.sat.ll"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(NameR.data()+11, "ubh.", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            if (memcmp(NameR.data()+16, "16.sat.", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              switch (NameR[24]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_sat_hh;	 // "exagon.A2.subh.h16.sat.hh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_sat_hl;	 // "exagon.A2.subh.h16.sat.hl"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              switch (NameR[24]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_sat_lh;	 // "exagon.A2.subh.h16.sat.lh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_sat_ll;	 // "exagon.A2.subh.h16.sat.ll"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "16.sat.", 7))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (NameR[24] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_subh_l16_sat_hl;	 // "exagon.A2.subh.l16.sat.hl"
+            case 'l':	 // 1 string to match.
+              if (NameR[24] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_subh_l16_sat_ll;	 // "exagon.A2.subh.l16.sat.ll"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'C':	 // 1 string to match.
+        if (memcmp(NameR.data()+8, "4.fastcorner9.not", 17))
+          break;
+        return Intrinsic::hexagon_C4_fastcorner9_not;	 // "exagon.C4.fastcorner9.not"
+      case 'F':	 // 4 strings to match.
+        if (memcmp(NameR.data()+8, "2.conv.", 7))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "f2u", 3))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_df2ud_chop;	 // "exagon.F2.conv.df2ud.chop"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_df2uw_chop;	 // "exagon.F2.conv.df2uw.chop"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "f2u", 3))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_sf2ud_chop;	 // "exagon.F2.conv.sf2ud.chop"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".chop", 5))
+              break;
+            return Intrinsic::hexagon_F2_conv_sf2uw_chop;	 // "exagon.F2.conv.sf2uw.chop"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 16 strings to match.
+        if (memcmp(NameR.data()+8, "2.mpyud.", 8))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (memcmp(NameR.data()+17, "cc.", 3))
+            break;
+          switch (NameR[20]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (NameR[21]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_hh_s0;	 // "exagon.M2.mpyud.acc.hh.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_hh_s1;	 // "exagon.M2.mpyud.acc.hh.s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_hl_s0;	 // "exagon.M2.mpyud.acc.hl.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_hl_s1;	 // "exagon.M2.mpyud.acc.hl.s1"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[21]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_lh_s0;	 // "exagon.M2.mpyud.acc.lh.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_lh_s1;	 // "exagon.M2.mpyud.acc.lh.s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_ll_s0;	 // "exagon.M2.mpyud.acc.ll.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_acc_ll_s1;	 // "exagon.M2.mpyud.acc.ll.s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 8 strings to match.
+          if (memcmp(NameR.data()+17, "ac.", 3))
+            break;
+          switch (NameR[20]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (NameR[21]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_hh_s0;	 // "exagon.M2.mpyud.nac.hh.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_hh_s1;	 // "exagon.M2.mpyud.nac.hh.s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_hl_s0;	 // "exagon.M2.mpyud.nac.hl.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_hl_s1;	 // "exagon.M2.mpyud.nac.hl.s1"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[21]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_lh_s0;	 // "exagon.M2.mpyud.nac.lh.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_lh_s1;	 // "exagon.M2.mpyud.nac.lh.s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, ".s", 2))
+                break;
+              switch (NameR[24]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_ll_s0;	 // "exagon.M2.mpyud.nac.ll.s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_nac_ll_s1;	 // "exagon.M2.mpyud.nac.ll.s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 27:	 // 24 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.M2.mpy.", 14))
+        break;
+      switch (NameR[14]) {
+      default: break;
+      case 'a':	 // 8 strings to match.
+        if (memcmp(NameR.data()+15, "cc.sat.", 7))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_hh_s0;	 // "exagon.M2.mpy.acc.sat.hh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_hh_s1;	 // "exagon.M2.mpy.acc.sat.hh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_hl_s0;	 // "exagon.M2.mpy.acc.sat.hl.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_hl_s1;	 // "exagon.M2.mpy.acc.sat.hl.s1"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_lh_s0;	 // "exagon.M2.mpy.acc.sat.lh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_lh_s1;	 // "exagon.M2.mpy.acc.sat.lh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_ll_s0;	 // "exagon.M2.mpy.acc.sat.ll.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_acc_sat_ll_s1;	 // "exagon.M2.mpy.acc.sat.ll.s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 8 strings to match.
+        if (memcmp(NameR.data()+15, "ac.sat.", 7))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_hh_s0;	 // "exagon.M2.mpy.nac.sat.hh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_hh_s1;	 // "exagon.M2.mpy.nac.sat.hh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_hl_s0;	 // "exagon.M2.mpy.nac.sat.hl.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_hl_s1;	 // "exagon.M2.mpy.nac.sat.hl.s1"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_lh_s0;	 // "exagon.M2.mpy.nac.sat.lh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_lh_s1;	 // "exagon.M2.mpy.nac.sat.lh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_ll_s0;	 // "exagon.M2.mpy.nac.sat.ll.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_nac_sat_ll_s1;	 // "exagon.M2.mpy.nac.sat.ll.s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 8 strings to match.
+        if (memcmp(NameR.data()+15, "at.rnd.", 7))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_hh_s0;	 // "exagon.M2.mpy.sat.rnd.hh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_hh_s1;	 // "exagon.M2.mpy.sat.rnd.hh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_hl_s0;	 // "exagon.M2.mpy.sat.rnd.hl.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_hl_s1;	 // "exagon.M2.mpy.sat.rnd.hl.s1"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 4 strings to match.
+          switch (NameR[23]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_lh_s0;	 // "exagon.M2.mpy.sat.rnd.lh.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_lh_s1;	 // "exagon.M2.mpy.sat.rnd.lh.s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+24, ".s", 2))
+              break;
+            switch (NameR[26]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_ll_s0;	 // "exagon.M2.mpy.sat.rnd.ll.s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpy_sat_rnd_ll_s1;	 // "exagon.M2.mpy.sat.rnd.ll.s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 29:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "exagon.S5.vasrhrnd.goodsyntax", 29))
+        break;
+      return Intrinsic::hexagon_S5_vasrhrnd_goodsyntax;	 // "exagon.S5.vasrhrnd.goodsyntax"
+    case 30:	 // 4 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.S2.tableidx", 18))
+        break;
+      switch (NameR[18]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(NameR.data()+19, ".goodsyntax", 11))
+          break;
+        return Intrinsic::hexagon_S2_tableidxb_goodsyntax;	 // "exagon.S2.tableidxb.goodsyntax"
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+19, ".goodsyntax", 11))
+          break;
+        return Intrinsic::hexagon_S2_tableidxd_goodsyntax;	 // "exagon.S2.tableidxd.goodsyntax"
+      case 'h':	 // 1 string to match.
+        if (memcmp(NameR.data()+19, ".goodsyntax", 11))
+          break;
+        return Intrinsic::hexagon_S2_tableidxh_goodsyntax;	 // "exagon.S2.tableidxh.goodsyntax"
+      case 'w':	 // 1 string to match.
+        if (memcmp(NameR.data()+19, ".goodsyntax", 11))
+          break;
+        return Intrinsic::hexagon_S2_tableidxw_goodsyntax;	 // "exagon.S2.tableidxw.goodsyntax"
+      }
+      break;
+    case 32:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "exagon.S2.asr.i.", 16))
+        break;
+      switch (NameR[16]) {
+      default: break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(NameR.data()+17, ".rnd.goodsyntax", 15))
+          break;
+        return Intrinsic::hexagon_S2_asr_i_p_rnd_goodsyntax;	 // "exagon.S2.asr.i.p.rnd.goodsyntax"
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+17, ".rnd.goodsyntax", 15))
+          break;
+        return Intrinsic::hexagon_S2_asr_i_r_rnd_goodsyntax;	 // "exagon.S2.asr.i.r.rnd.goodsyntax"
+      }
+      break;
+    case 35:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "exagon.S5.asrhub.rnd.sat.goodsyntax", 35))
+        break;
+      return Intrinsic::hexagon_S5_asrhub_rnd_sat_goodsyntax;	 // "exagon.S5.asrhub.rnd.sat.goodsyntax"
+    }
+    break;  // end of 'h' case.
+  case 'i':
+    switch (NameR.size()) {
+    default: break;
+    case 12:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "nvariant.end", 12))
+        break;
+      return Intrinsic::invariant_end;	 // "nvariant.end"
+    case 14:	 // 2 strings to match.
+      if (NameR[0] != 'n')
+        break;
+      switch (NameR[1]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(NameR.data()+2, "t.trampoline", 12))
+          break;
+        return Intrinsic::init_trampoline;	 // "nit.trampoline"
+      case 'v':	 // 1 string to match.
+        if (memcmp(NameR.data()+2, "ariant.start", 12))
+          break;
+        return Intrinsic::invariant_start;	 // "nvariant.start"
+      }
+      break;
+    }
+    break;  // end of 'i' case.
+  case 'l':
+    if (NameR.startswith("og2.")) return Intrinsic::log2;
+    if (NameR.startswith("og10.")) return Intrinsic::log10;
+    if (NameR.startswith("og.")) return Intrinsic::log;
+    switch (NameR.size()) {
+    default: break;
+    case 6:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "ongjmp", 6))
+        break;
+      return Intrinsic::longjmp;	 // "ongjmp"
+    case 11:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "ifetime.end", 11))
+        break;
+      return Intrinsic::lifetime_end;	 // "ifetime.end"
+    case 13:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "ifetime.start", 13))
+        break;
+      return Intrinsic::lifetime_start;	 // "ifetime.start"
+    }
+    break;  // end of 'l' case.
+  case 'm':
+    if (NameR.startswith("emset.")) return Intrinsic::memset;
+    if (NameR.startswith("emmove.")) return Intrinsic::memmove;
+    if (NameR.startswith("emcpy.")) return Intrinsic::memcpy;
+    switch (NameR.size()) {
+    default: break;
+    case 7:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "ips.l", 5))
+        break;
+      switch (NameR[5]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (NameR[6] != 'x')
+          break;
+        return Intrinsic::mips_lhx;	 // "ips.lhx"
+      case 's':	 // 1 string to match.
+        if (NameR[6] != 'a')
+          break;
+        return Intrinsic::mips_lsa;	 // "ips.lsa"
+      case 'w':	 // 1 string to match.
+        if (NameR[6] != 'x')
+          break;
+        return Intrinsic::mips_lwx;	 // "ips.lwx"
+      }
+      break;
+    case 8:	 // 21 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'b':	 // 5 strings to match.
+        if (memcmp(NameR.data()+5, "z.", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_bz_b;	 // "ips.bz.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_bz_d;	 // "ips.bz.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_bz_h;	 // "ips.bz.h"
+        case 'v':	 // 1 string to match.
+          return Intrinsic::mips_bz_v;	 // "ips.bz.v"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_bz_w;	 // "ips.bz.w"
+        }
+        break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "lsa", 3))
+          break;
+        return Intrinsic::mips_dlsa;	 // "ips.dlsa"
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xtp", 3))
+          break;
+        return Intrinsic::mips_extp;	 // "ips.extp"
+      case 'i':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "nsv", 3))
+          break;
+        return Intrinsic::mips_insv;	 // "ips.insv"
+      case 'l':	 // 5 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ux", 2))
+            break;
+          return Intrinsic::mips_lbux;	 // "ips.lbux"
+        case 'd':	 // 4 strings to match.
+          if (NameR[6] != '.')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ld_b;	 // "ips.ld.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ld_d;	 // "ips.ld.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ld_h;	 // "ips.ld.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ld_w;	 // "ips.ld.w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "dd", 2))
+            break;
+          return Intrinsic::mips_madd;	 // "ips.madd"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ub", 2))
+            break;
+          return Intrinsic::mips_msub;	 // "ips.msub"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "lt", 2))
+            break;
+          return Intrinsic::mips_mult;	 // "ips.mult"
+        }
+        break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "r.v", 3))
+          break;
+        return Intrinsic::mips_or_v;	 // "ips.or.v"
+      case 's':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "t.", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_st_b;	 // "ips.st.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_st_d;	 // "ips.st.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_st_h;	 // "ips.st.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_st_w;	 // "ips.st.w"
+        }
+        break;
+      }
+      break;
+    case 9:	 // 47 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (NameR[6] != 'd')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (NameR[8] != 'c')
+              break;
+            return Intrinsic::mips_addsc;	 // "ips.addsc"
+          case 'w':	 // 1 string to match.
+            if (NameR[8] != 'c')
+              break;
+            return Intrinsic::mips_addwc;	 // "ips.addwc"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "d.v", 3))
+            break;
+          return Intrinsic::mips_and_v;	 // "ips.and.v"
+        }
+        break;
+      case 'b':	 // 6 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "z.v", 3))
+            break;
+          return Intrinsic::mips_bmz_v;	 // "ips.bmz.v"
+        case 'n':	 // 5 strings to match.
+          if (memcmp(NameR.data()+6, "z.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bnz_b;	 // "ips.bnz.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bnz_d;	 // "ips.bnz.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bnz_h;	 // "ips.bnz.h"
+          case 'v':	 // 1 string to match.
+            return Intrinsic::mips_bnz_v;	 // "ips.bnz.v"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bnz_w;	 // "ips.bnz.w"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "eq.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_ceq_b;	 // "ips.ceq.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_ceq_d;	 // "ips.ceq.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ceq_h;	 // "ips.ceq.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ceq_w;	 // "ips.ceq.w"
+        }
+        break;
+      case 'f':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "tq.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ftq_h;	 // "ips.ftq.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ftq_w;	 // "ips.ftq.w"
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "di.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_ldi_b;	 // "ips.ldi.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_ldi_d;	 // "ips.ldi.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ldi_h;	 // "ips.ldi.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ldi_w;	 // "ips.ldi.w"
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ddu", 3))
+            break;
+          return Intrinsic::mips_maddu;	 // "ips.maddu"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ubu", 3))
+            break;
+          return Intrinsic::mips_msubu;	 // "ips.msubu"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ltu", 3))
+            break;
+          return Intrinsic::mips_multu;	 // "ips.multu"
+        }
+        break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "or.v", 4))
+          break;
+        return Intrinsic::mips_nor_v;	 // "ips.nor.v"
+      case 'o':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ri.b", 4))
+          break;
+        return Intrinsic::mips_ori_b;	 // "ips.ori.b"
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ddsp", 4))
+          break;
+        return Intrinsic::mips_rddsp;	 // "ips.rddsp"
+      case 's':	 // 20 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'f':	 // 3 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_shf_b;	 // "ips.shf.b"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_shf_h;	 // "ips.shf.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_shf_w;	 // "ips.shf.w"
+            }
+            break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "lo", 2))
+              break;
+            return Intrinsic::mips_shilo;	 // "ips.shilo"
+          }
+          break;
+        case 'l':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sld_b;	 // "ips.sld.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sld_d;	 // "ips.sld.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sld_h;	 // "ips.sld.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sld_w;	 // "ips.sld.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sll_b;	 // "ips.sll.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sll_d;	 // "ips.sll.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sll_h;	 // "ips.sll.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sll_w;	 // "ips.sll.w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sra_b;	 // "ips.sra.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sra_d;	 // "ips.sra.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sra_h;	 // "ips.sra.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sra_w;	 // "ips.sra.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srl_b;	 // "ips.srl.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srl_d;	 // "ips.srl.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srl_h;	 // "ips.srl.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srl_w;	 // "ips.srl.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'w':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "rdsp", 4))
+          break;
+        return Intrinsic::mips_wrdsp;	 // "ips.wrdsp"
+      case 'x':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "or.v", 4))
+          break;
+        return Intrinsic::mips_xor_v;	 // "ips.xor.v"
+      }
+      break;
+    case 10:	 // 143 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "dv.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_addv_b;	 // "ips.addv.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_addv_d;	 // "ips.addv.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_addv_h;	 // "ips.addv.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_addv_w;	 // "ips.addv.w"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "di.b", 4))
+            break;
+          return Intrinsic::mips_andi_b;	 // "ips.andi.b"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "pend", 4))
+            break;
+          return Intrinsic::mips_append;	 // "ips.append"
+        }
+        break;
+      case 'b':	 // 17 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "lign", 4))
+            break;
+          return Intrinsic::mips_balign;	 // "ips.balign"
+        case 'c':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "lr.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bclr_b;	 // "ips.bclr.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bclr_d;	 // "ips.bclr.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bclr_h;	 // "ips.bclr.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bclr_w;	 // "ips.bclr.w"
+          }
+          break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "trev", 4))
+            break;
+          return Intrinsic::mips_bitrev;	 // "ips.bitrev"
+        case 'm':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "z.v", 3))
+              break;
+            return Intrinsic::mips_bmnz_v;	 // "ips.bmnz.v"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "i.b", 3))
+              break;
+            return Intrinsic::mips_bmzi_b;	 // "ips.bmzi.b"
+          }
+          break;
+        case 'n':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "eg.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bneg_b;	 // "ips.bneg.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bneg_d;	 // "ips.bneg.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bneg_h;	 // "ips.bneg.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bneg_w;	 // "ips.bneg.w"
+          }
+          break;
+        case 's':	 // 5 strings to match.
+          if (NameR[6] != 'e')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, ".v", 2))
+              break;
+            return Intrinsic::mips_bsel_v;	 // "ips.bsel.v"
+          case 't':	 // 4 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_bset_b;	 // "ips.bset.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_bset_d;	 // "ips.bset.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_bset_h;	 // "ips.bset.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_bset_w;	 // "ips.bset.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 6 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "qi.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_b;	 // "ips.ceqi.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_d;	 // "ips.ceqi.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_h;	 // "ips.ceqi.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_w;	 // "ips.ceqi.w"
+          }
+          break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "cmsa", 4))
+            break;
+          return Intrinsic::mips_cfcmsa;	 // "ips.cfcmsa"
+        case 't':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "cmsa", 4))
+            break;
+          return Intrinsic::mips_ctcmsa;	 // "ips.ctcmsa"
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "xt", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "dp", 2))
+            break;
+          return Intrinsic::mips_extpdp;	 // "ips.extpdp"
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, ".w", 2))
+            break;
+          return Intrinsic::mips_extr_w;	 // "ips.extr.w"
+        }
+        break;
+      case 'f':	 // 50 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "dd.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fadd_d;	 // "ips.fadd.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fadd_w;	 // "ips.fadd.w"
+          }
+          break;
+        case 'c':	 // 14 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "f.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcaf_d;	 // "ips.fcaf.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcaf_w;	 // "ips.fcaf.w"
+            }
+            break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "q.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fceq_d;	 // "ips.fceq.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fceq_w;	 // "ips.fceq.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcle_d;	 // "ips.fcle.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcle_w;	 // "ips.fcle.w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fclt_d;	 // "ips.fclt.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fclt_w;	 // "ips.fclt.w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "e.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcne_d;	 // "ips.fcne.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcne_w;	 // "ips.fcne.w"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "r.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcor_d;	 // "ips.fcor.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcor_w;	 // "ips.fcor.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "n.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcun_d;	 // "ips.fcun.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcun_w;	 // "ips.fcun.w"
+            }
+            break;
+          }
+          break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "iv.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fdiv_d;	 // "ips.fdiv.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fdiv_w;	 // "ips.fdiv.w"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (NameR[6] != 'q')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffql_d;	 // "ips.ffql.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffql_w;	 // "ips.ffql.w"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffqr_d;	 // "ips.ffqr.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffqr_w;	 // "ips.ffqr.w"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "ll.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_fill_b;	 // "ips.fill.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fill_d;	 // "ips.fill.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_fill_h;	 // "ips.fill.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fill_w;	 // "ips.fill.w"
+          }
+          break;
+        case 'm':	 // 6 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "x.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmax_d;	 // "ips.fmax.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmax_w;	 // "ips.fmax.w"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "n.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmin_d;	 // "ips.fmin.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmin_w;	 // "ips.fmin.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "l.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmul_d;	 // "ips.fmul.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmul_w;	 // "ips.fmul.w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "cp.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frcp_d;	 // "ips.frcp.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frcp_w;	 // "ips.frcp.w"
+          }
+          break;
+        case 's':	 // 16 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "f.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsaf_d;	 // "ips.fsaf.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsaf_w;	 // "ips.fsaf.w"
+            }
+            break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "q.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fseq_d;	 // "ips.fseq.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fseq_w;	 // "ips.fseq.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsle_d;	 // "ips.fsle.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsle_w;	 // "ips.fsle.w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fslt_d;	 // "ips.fslt.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fslt_w;	 // "ips.fslt.w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "e.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsne_d;	 // "ips.fsne.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsne_w;	 // "ips.fsne.w"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "r.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsor_d;	 // "ips.fsor.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsor_w;	 // "ips.fsor.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsub_d;	 // "ips.fsub.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsub_w;	 // "ips.fsub.w"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsun_d;	 // "ips.fsun.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsun_w;	 // "ips.fsun.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "lv", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (NameR[8] != '.')
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_b;	 // "ips.ilvl.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_d;	 // "ips.ilvl.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_h;	 // "ips.ilvl.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_w;	 // "ips.ilvl.w"
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          if (NameR[8] != '.')
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_b;	 // "ips.ilvr.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_d;	 // "ips.ilvr.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_h;	 // "ips.ilvr.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_w;	 // "ips.ilvr.w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 8 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'o':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "sub", 3))
+              break;
+            return Intrinsic::mips_modsub;	 // "ips.modsub"
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "e.v", 3))
+              break;
+            return Intrinsic::mips_move_v;	 // "ips.move.v"
+          }
+          break;
+        case 't':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "hlip", 4))
+            break;
+          return Intrinsic::mips_mthlip;	 // "ips.mthlip"
+        case 'u':	 // 5 strings to match.
+          if (NameR[6] != 'l')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "ph", 2))
+              break;
+            return Intrinsic::mips_mul_ph;	 // "ips.mul.ph"
+          case 'v':	 // 4 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mulv_b;	 // "ips.mulv.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mulv_d;	 // "ips.mulv.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mulv_h;	 // "ips.mulv.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mulv_w;	 // "ips.mulv.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 9 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'o':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "c.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_nloc_b;	 // "ips.nloc.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_nloc_d;	 // "ips.nloc.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_nloc_h;	 // "ips.nloc.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_nloc_w;	 // "ips.nloc.w"
+            }
+            break;
+          case 'z':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "c.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_b;	 // "ips.nlzc.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_d;	 // "ips.nlzc.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_h;	 // "ips.nlzc.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_w;	 // "ips.nlzc.w"
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ri.b", 4))
+            break;
+          return Intrinsic::mips_nori_b;	 // "ips.nori.b"
+        }
+        break;
+      case 'p':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "cnt.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_b;	 // "ips.pcnt.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_d;	 // "ips.pcnt.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_h;	 // "ips.pcnt.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_w;	 // "ips.pcnt.w"
+        }
+        break;
+      case 's':	 // 28 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "i.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sldi_b;	 // "ips.sldi.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sldi_d;	 // "ips.sldi.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sldi_h;	 // "ips.sldi.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sldi_w;	 // "ips.sldi.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "i.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_slli_b;	 // "ips.slli.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_slli_d;	 // "ips.slli.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_slli_h;	 // "ips.slli.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_slli_w;	 // "ips.slli.w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 16 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'i':	 // 4 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srai_b;	 // "ips.srai.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srai_d;	 // "ips.srai.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srai_h;	 // "ips.srai.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srai_w;	 // "ips.srai.w"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srar_b;	 // "ips.srar.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srar_d;	 // "ips.srar.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srar_h;	 // "ips.srar.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srar_w;	 // "ips.srar.w"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 8 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'i':	 // 4 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srli_b;	 // "ips.srli.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srli_d;	 // "ips.srli.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srli_h;	 // "ips.srli.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srli_w;	 // "ips.srli.w"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srlr_b;	 // "ips.srlr.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srlr_d;	 // "ips.srlr.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srlr_h;	 // "ips.srlr.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srlr_w;	 // "ips.srlr.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "bv.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_subv_b;	 // "ips.subv.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_subv_d;	 // "ips.subv.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_subv_h;	 // "ips.subv.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_subv_w;	 // "ips.subv.w"
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "shf.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_vshf_b;	 // "ips.vshf.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_vshf_d;	 // "ips.vshf.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_vshf_h;	 // "ips.vshf.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_vshf_w;	 // "ips.vshf.w"
+        }
+        break;
+      case 'x':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ori.b", 5))
+          break;
+        return Intrinsic::mips_xori_b;	 // "ips.xori.b"
+      }
+      break;
+    case 11:	 // 197 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 20 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'd':	 // 12 strings to match.
+          if (NameR[6] != 'd')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case '.':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "a.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_add_a_b;	 // "ips.add.a.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_add_a_d;	 // "ips.add.a.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_add_a_h;	 // "ips.add.a.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_add_a_w;	 // "ips.add.a.w"
+            }
+            break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "ph", 2))
+                break;
+              return Intrinsic::mips_addq_ph;	 // "ips.addq.ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".w", 2))
+                break;
+              return Intrinsic::mips_addqh_w;	 // "ips.addqh.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[10] != 'h')
+                break;
+              return Intrinsic::mips_addu_ph;	 // "ips.addu.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[10] != 'b')
+                break;
+              return Intrinsic::mips_addu_qb;	 // "ips.addu.qb"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "i.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_addvi_b;	 // "ips.addvi.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_addvi_d;	 // "ips.addvi.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_addvi_h;	 // "ips.addvi.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_addvi_w;	 // "ips.addvi.w"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "e.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_b;	 // "ips.ave.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_d;	 // "ips.ave.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_h;	 // "ips.ave.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_w;	 // "ips.ave.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_b;	 // "ips.ave.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_d;	 // "ips.ave.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_h;	 // "ips.ave.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_w;	 // "ips.ave.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 22 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "lri.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bclri_b;	 // "ips.bclri.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bclri_d;	 // "ips.bclri.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bclri_h;	 // "ips.bclri.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bclri_w;	 // "ips.bclri.w"
+          }
+          break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "ns", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsl_b;	 // "ips.binsl.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsl_d;	 // "ips.binsl.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsl_h;	 // "ips.binsl.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsl_w;	 // "ips.binsl.w"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsr_b;	 // "ips.binsr.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsr_d;	 // "ips.binsr.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsr_h;	 // "ips.binsr.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsr_w;	 // "ips.binsr.w"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "nzi.b", 5))
+            break;
+          return Intrinsic::mips_bmnzi_b;	 // "ips.bmnzi.b"
+        case 'n':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "egi.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_b;	 // "ips.bnegi.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_d;	 // "ips.bnegi.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_h;	 // "ips.bnegi.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_w;	 // "ips.bnegi.w"
+          }
+          break;
+        case 's':	 // 5 strings to match.
+          if (NameR[6] != 'e')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "i.b", 3))
+              break;
+            return Intrinsic::mips_bseli_b;	 // "ips.bseli.b"
+          case 't':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "i.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_bseti_b;	 // "ips.bseti.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_bseti_d;	 // "ips.bseti.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_bseti_h;	 // "ips.bseti.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_bseti_w;	 // "ips.bseti.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 16 strings to match.
+        if (NameR[5] != 'l')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'e':	 // 8 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_b;	 // "ips.cle.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_d;	 // "ips.cle.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_h;	 // "ips.cle.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_w;	 // "ips.cle.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_b;	 // "ips.cle.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_d;	 // "ips.cle.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_h;	 // "ips.cle.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_w;	 // "ips.cle.u.w"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 8 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_b;	 // "ips.clt.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_d;	 // "ips.clt.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_h;	 // "ips.clt.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_w;	 // "ips.clt.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_b;	 // "ips.clt.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_d;	 // "ips.clt.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_h;	 // "ips.clt.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_w;	 // "ips.clt.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "iv.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_div_s_b;	 // "ips.div.s.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_div_s_d;	 // "ips.div.s.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_div_s_h;	 // "ips.div.s.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_div_s_w;	 // "ips.div.s.w"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (NameR[9] != '.')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_div_u_b;	 // "ips.div.u.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_div_u_d;	 // "ips.div.u.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_div_u_h;	 // "ips.div.u.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_div_u_w;	 // "ips.div.u.w"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 30 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 8 strings to match.
+          if (NameR[6] != 'u')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "q.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcueq_d;	 // "ips.fcueq.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcueq_w;	 // "ips.fcueq.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (NameR[9] != '.')
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcule_d;	 // "ips.fcule.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcule_w;	 // "ips.fcule.w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (NameR[9] != '.')
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcult_d;	 // "ips.fcult.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcult_w;	 // "ips.fcult.w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "e.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcune_d;	 // "ips.fcune.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcune_w;	 // "ips.fcune.w"
+            }
+            break;
+          }
+          break;
+        case 'e':	 // 4 strings to match.
+          if (NameR[6] != 'x')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "o.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_fexdo_h;	 // "ips.fexdo.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexdo_w;	 // "ips.fexdo.w"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "2.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexp2_d;	 // "ips.fexp2.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexp2_w;	 // "ips.fexp2.w"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "og2.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_flog2_d;	 // "ips.flog2.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_flog2_w;	 // "ips.flog2.w"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "dd.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmadd_d;	 // "ips.fmadd.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmadd_w;	 // "ips.fmadd.w"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "ub.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmsub_d;	 // "ips.fmsub.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmsub_w;	 // "ips.fmsub.w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "int.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frint_d;	 // "ips.frint.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frint_w;	 // "ips.frint.w"
+          }
+          break;
+        case 's':	 // 10 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "rt.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsqrt_d;	 // "ips.fsqrt.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsqrt_w;	 // "ips.fsqrt.w"
+            }
+            break;
+          case 'u':	 // 8 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "q.", 2))
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsueq_d;	 // "ips.fsueq.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsueq_w;	 // "ips.fsueq.w"
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                if (NameR[9] != '.')
+                  break;
+                switch (NameR[10]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::mips_fsule_d;	 // "ips.fsule.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::mips_fsule_w;	 // "ips.fsule.w"
+                }
+                break;
+              case 't':	 // 2 strings to match.
+                if (NameR[9] != '.')
+                  break;
+                switch (NameR[10]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::mips_fsult_d;	 // "ips.fsult.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::mips_fsult_w;	 // "ips.fsult.w"
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "e.", 2))
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsune_d;	 // "ips.fsune.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsune_w;	 // "ips.fsune.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 12 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          if (NameR[6] != 'v')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'e':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "v.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_b;	 // "ips.ilvev.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_d;	 // "ips.ilvev.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_h;	 // "ips.ilvev.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_w;	 // "ips.ilvev.w"
+            }
+            break;
+          case 'o':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "d.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_b;	 // "ips.ilvod.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_d;	 // "ips.ilvod.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_h;	 // "ips.ilvod.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_w;	 // "ips.ilvod.w"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "sve.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_insve_b;	 // "ips.insve.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_insve_d;	 // "ips.insve.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_insve_h;	 // "ips.insve.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_insve_w;	 // "ips.insve.w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 42 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 16 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "dv.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_maddv_b;	 // "ips.maddv.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_maddv_d;	 // "ips.maddv.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_maddv_h;	 // "ips.maddv.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_maddv_w;	 // "ips.maddv.w"
+            }
+            break;
+          case 'x':	 // 12 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (NameR[9] != '.')
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_a_b;	 // "ips.max.a.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_a_d;	 // "ips.max.a.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_a_h;	 // "ips.max.a.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_a_w;	 // "ips.max.a.w"
+              }
+              break;
+            case 's':	 // 4 strings to match.
+              if (NameR[9] != '.')
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_s_b;	 // "ips.max.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_s_d;	 // "ips.max.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_s_h;	 // "ips.max.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_s_w;	 // "ips.max.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[9] != '.')
+                break;
+              switch (NameR[10]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_u_b;	 // "ips.max.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_u_d;	 // "ips.max.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_u_h;	 // "ips.max.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_u_w;	 // "ips.max.u.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 12 strings to match.
+          if (memcmp(NameR.data()+6, "n.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_a_b;	 // "ips.min.a.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_a_d;	 // "ips.min.a.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_a_h;	 // "ips.min.a.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_a_w;	 // "ips.min.a.w"
+            }
+            break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_s_b;	 // "ips.min.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_s_d;	 // "ips.min.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_s_h;	 // "ips.min.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_s_w;	 // "ips.min.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_u_b;	 // "ips.min.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_u_d;	 // "ips.min.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_u_h;	 // "ips.min.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_u_w;	 // "ips.min.u.w"
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "d.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_b;	 // "ips.mod.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_d;	 // "ips.mod.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_h;	 // "ips.mod.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_w;	 // "ips.mod.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_b;	 // "ips.mod.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_d;	 // "ips.mod.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_h;	 // "ips.mod.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_w;	 // "ips.mod.u.w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "ubv.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_msubv_b;	 // "ips.msubv.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_msubv_d;	 // "ips.msubv.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msubv_h;	 // "ips.msubv.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msubv_w;	 // "ips.msubv.w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "l.q.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_mul_q_h;	 // "ips.mul.q.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_mul_q_w;	 // "ips.mul.q.w"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 11 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 8 strings to match.
+          if (NameR[6] != 'k')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'e':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "v.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_pckev_b;	 // "ips.pckev.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_pckev_d;	 // "ips.pckev.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_pckev_h;	 // "ips.pckev.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_pckev_w;	 // "ips.pckev.w"
+            }
+            break;
+          case 'o':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "d.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_pckod_b;	 // "ips.pckod.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_pckod_d;	 // "ips.pckod.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_pckod_h;	 // "ips.pckod.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_pckod_w;	 // "ips.pckod.w"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "ck.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (NameR[10] != 'h')
+              break;
+            return Intrinsic::mips_pick_ph;	 // "ips.pick.ph"
+          case 'q':	 // 1 string to match.
+            if (NameR[10] != 'b')
+              break;
+            return Intrinsic::mips_pick_qb;	 // "ips.pick.qb"
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "epend", 5))
+            break;
+          return Intrinsic::mips_prepend;	 // "ips.prepend"
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "epl.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (NameR[10] != 'h')
+            break;
+          return Intrinsic::mips_repl_ph;	 // "ips.repl.ph"
+        case 'q':	 // 1 string to match.
+          if (NameR[10] != 'b')
+            break;
+          return Intrinsic::mips_repl_qb;	 // "ips.repl.qb"
+        }
+        break;
+      case 's':	 // 34 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "t.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_b;	 // "ips.sat.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_d;	 // "ips.sat.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_h;	 // "ips.sat.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_w;	 // "ips.sat.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[9] != '.')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_b;	 // "ips.sat.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_d;	 // "ips.sat.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_h;	 // "ips.sat.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_w;	 // "ips.sat.u.w"
+            }
+            break;
+          }
+          break;
+        case 'h':	 // 6 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "l.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[10] != 'h')
+                break;
+              return Intrinsic::mips_shll_ph;	 // "ips.shll.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[10] != 'b')
+                break;
+              return Intrinsic::mips_shll_qb;	 // "ips.shll.qb"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (NameR[10] != 'h')
+                  break;
+                return Intrinsic::mips_shra_ph;	 // "ips.shra.ph"
+              case 'q':	 // 1 string to match.
+                if (NameR[10] != 'b')
+                  break;
+                return Intrinsic::mips_shra_qb;	 // "ips.shra.qb"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (NameR[10] != 'h')
+                  break;
+                return Intrinsic::mips_shrl_ph;	 // "ips.shrl.ph"
+              case 'q':	 // 1 string to match.
+                if (NameR[10] != 'b')
+                  break;
+                return Intrinsic::mips_shrl_qb;	 // "ips.shrl.qb"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "lat.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_splat_b;	 // "ips.splat.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_splat_d;	 // "ips.splat.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_splat_h;	 // "ips.splat.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_splat_w;	 // "ips.splat.w"
+          }
+          break;
+        case 'r':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "ri.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srari_b;	 // "ips.srari.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srari_d;	 // "ips.srari.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srari_h;	 // "ips.srari.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srari_w;	 // "ips.srari.w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "ri.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srlri_b;	 // "ips.srlri.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srlri_d;	 // "ips.srlri.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srlri_h;	 // "ips.srlri.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srlri_w;	 // "ips.srlri.w"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 8 strings to match.
+          if (NameR[6] != 'b')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "ph", 2))
+                break;
+              return Intrinsic::mips_subq_ph;	 // "ips.subq.ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".w", 2))
+                break;
+              return Intrinsic::mips_subqh_w;	 // "ips.subqh.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[10] != 'h')
+                break;
+              return Intrinsic::mips_subu_ph;	 // "ips.subu.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[10] != 'b')
+                break;
+              return Intrinsic::mips_subu_qb;	 // "ips.subu.qb"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "i.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_subvi_b;	 // "ips.subvi.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_subvi_d;	 // "ips.subvi.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_subvi_h;	 // "ips.subvi.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_subvi_w;	 // "ips.subvi.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 12:	 // 144 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 32 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "sq.s.w", 6))
+            break;
+          return Intrinsic::mips_absq_s_w;	 // "ips.absq.s.w"
+        case 'd':	 // 15 strings to match.
+          if (NameR[6] != 'd')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "s.w", 3))
+                break;
+              return Intrinsic::mips_addq_s_w;	 // "ips.addq.s.w"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".ph", 3))
+                break;
+              return Intrinsic::mips_addqh_ph;	 // "ips.addqh.ph"
+            }
+            break;
+          case 's':	 // 12 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_adds_a_b;	 // "ips.adds.a.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_adds_a_d;	 // "ips.adds.a.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_adds_a_h;	 // "ips.adds.a.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_adds_a_w;	 // "ips.adds.a.w"
+              }
+              break;
+            case 's':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_adds_s_b;	 // "ips.adds.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_adds_s_d;	 // "ips.adds.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_adds_s_h;	 // "ips.adds.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_adds_s_w;	 // "ips.adds.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_adds_u_b;	 // "ips.adds.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_adds_u_d;	 // "ips.adds.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_adds_u_h;	 // "ips.adds.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_adds_u_w;	 // "ips.adds.u.w"
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "h.qb", 4))
+              break;
+            return Intrinsic::mips_adduh_qb;	 // "ips.adduh.qb"
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "ub.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_b;	 // "ips.asub.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_d;	 // "ips.asub.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_h;	 // "ips.asub.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_w;	 // "ips.asub.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_b;	 // "ips.asub.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_d;	 // "ips.asub.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_h;	 // "ips.asub.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_w;	 // "ips.asub.u.w"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "er.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_b;	 // "ips.aver.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_d;	 // "ips.aver.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_h;	 // "ips.aver.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_w;	 // "ips.aver.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_b;	 // "ips.aver.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_d;	 // "ips.aver.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_h;	 // "ips.aver.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_w;	 // "ips.aver.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 9 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "ns", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "i.", 2))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsli_b;	 // "ips.binsli.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsli_d;	 // "ips.binsli.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsli_h;	 // "ips.binsli.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsli_w;	 // "ips.binsli.w"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "i.", 2))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsri_b;	 // "ips.binsri.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsri_d;	 // "ips.binsri.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsri_h;	 // "ips.binsri.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsri_w;	 // "ips.binsri.w"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "osge32", 6))
+            break;
+          return Intrinsic::mips_bposge32;	 // "ips.bposge32"
+        }
+        break;
+      case 'c':	 // 24 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'l':	 // 16 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'e':	 // 8 strings to match.
+            if (memcmp(NameR.data()+7, "i.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_b;	 // "ips.clei.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_d;	 // "ips.clei.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_h;	 // "ips.clei.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_w;	 // "ips.clei.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_b;	 // "ips.clei.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_d;	 // "ips.clei.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_h;	 // "ips.clei.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_w;	 // "ips.clei.u.w"
+              }
+              break;
+            }
+            break;
+          case 't':	 // 8 strings to match.
+            if (memcmp(NameR.data()+7, "i.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_b;	 // "ips.clti.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_d;	 // "ips.clti.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_h;	 // "ips.clti.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_w;	 // "ips.clti.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_b;	 // "ips.clti.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_d;	 // "ips.clti.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_h;	 // "ips.clti.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_w;	 // "ips.clti.u.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "py.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_b;	 // "ips.copy.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_d;	 // "ips.copy.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_h;	 // "ips.copy.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_w;	 // "ips.copy.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_b;	 // "ips.copy.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_d;	 // "ips.copy.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_h;	 // "ips.copy.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_w;	 // "ips.copy.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 8 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'o':	 // 6 strings to match.
+          if (memcmp(NameR.data()+6, "tp.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dotp_s_d;	 // "ips.dotp.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dotp_s_h;	 // "ips.dotp.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dotp_s_w;	 // "ips.dotp.s.w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dotp_u_d;	 // "ips.dotp.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dotp_u_h;	 // "ips.dotp.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dotp_u_w;	 // "ips.dotp.u.w"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".w.ph", 5))
+              break;
+            return Intrinsic::mips_dpa_w_ph;	 // "ips.dpa.w.ph"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".w.ph", 5))
+              break;
+            return Intrinsic::mips_dps_w_ph;	 // "ips.dps.w.ph"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "xtr.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".w", 2))
+            break;
+          return Intrinsic::mips_extr_r_w;	 // "ips.extr.r.w"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".h", 2))
+            break;
+          return Intrinsic::mips_extr_s_h;	 // "ips.extr.s.h"
+        }
+        break;
+      case 'f':	 // 12 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "lass.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fclass_d;	 // "ips.fclass.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fclass_w;	 // "ips.fclass.w"
+          }
+          break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "xup", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexupl_d;	 // "ips.fexupl.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexupl_w;	 // "ips.fexupl.w"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexupr_d;	 // "ips.fexupr.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexupr_w;	 // "ips.fexupr.w"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "x.a.", 4))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmax_a_d;	 // "ips.fmax.a.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmax_a_w;	 // "ips.fmax.a.w"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "n.a.", 4))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmin_a_d;	 // "ips.fmin.a.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmin_a_w;	 // "ips.fmin.a.w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "sqrt.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frsqrt_d;	 // "ips.frsqrt.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frsqrt_w;	 // "ips.frsqrt.w"
+          }
+          break;
+        }
+        break;
+      case 'h':	 // 12 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(NameR.data()+6, "dd.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_d;	 // "ips.hadd.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_h;	 // "ips.hadd.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_w;	 // "ips.hadd.s.w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_d;	 // "ips.hadd.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_h;	 // "ips.hadd.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_w;	 // "ips.hadd.u.w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(NameR.data()+6, "ub.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_d;	 // "ips.hsub.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_h;	 // "ips.hsub.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_w;	 // "ips.hsub.s.w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_d;	 // "ips.hsub.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_h;	 // "ips.hsub.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_w;	 // "ips.hsub.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "nsert.", 6))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_insert_b;	 // "ips.insert.b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_insert_d;	 // "ips.insert.d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_insert_h;	 // "ips.insert.h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_insert_w;	 // "ips.insert.w"
+        }
+        break;
+      case 'm':	 // 24 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 10 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "d.q.", 4))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_madd_q_h;	 // "ips.madd.q.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_madd_q_w;	 // "ips.madd.q.w"
+            }
+            break;
+          case 'x':	 // 8 strings to match.
+            if (memcmp(NameR.data()+7, "i.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_b;	 // "ips.maxi.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_d;	 // "ips.maxi.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_h;	 // "ips.maxi.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_w;	 // "ips.maxi.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_b;	 // "ips.maxi.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_d;	 // "ips.maxi.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_h;	 // "ips.maxi.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_w;	 // "ips.maxi.u.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "ni.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_b;	 // "ips.mini.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_d;	 // "ips.mini.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_h;	 // "ips.mini.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_w;	 // "ips.mini.s.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_b;	 // "ips.mini.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_d;	 // "ips.mini.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_h;	 // "ips.mini.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_w;	 // "ips.mini.u.w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "ub.q.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msub_q_h;	 // "ips.msub.q.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msub_q_w;	 // "ips.msub.q.w"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (NameR[6] != 'l')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "s.ph", 4))
+              break;
+            return Intrinsic::mips_mul_s_ph;	 // "ips.mul.s.ph"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, ".s.w", 4))
+              break;
+            return Intrinsic::mips_mulq_s_w;	 // "ips.mulq.s.w"
+          case 'r':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, ".q.", 3))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mulr_q_h;	 // "ips.mulr.q.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mulr_q_w;	 // "ips.mulr.q.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 17 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "l.s.w", 5))
+              break;
+            return Intrinsic::mips_shll_s_w;	 // "ips.shll.s.w"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "a.r.w", 5))
+              break;
+            return Intrinsic::mips_shra_r_w;	 // "ips.shra.r.w"
+          }
+          break;
+        case 'p':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "lati.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_splati_b;	 // "ips.splati.b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_splati_d;	 // "ips.splati.d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_splati_h;	 // "ips.splati.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_splati_w;	 // "ips.splati.w"
+          }
+          break;
+        case 'u':	 // 11 strings to match.
+          if (NameR[6] != 'b')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "s.w", 3))
+                break;
+              return Intrinsic::mips_subq_s_w;	 // "ips.subq.s.w"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".ph", 3))
+                break;
+              return Intrinsic::mips_subqh_ph;	 // "ips.subqh.ph"
+            }
+            break;
+          case 's':	 // 8 strings to match.
+            if (NameR[8] != '.')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_subs_s_b;	 // "ips.subs.s.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_subs_s_d;	 // "ips.subs.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_subs_s_h;	 // "ips.subs.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_subs_s_w;	 // "ips.subs.s.w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_subs_u_b;	 // "ips.subs.u.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_subs_u_d;	 // "ips.subs.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_subs_u_h;	 // "ips.subs.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_subs_u_w;	 // "ips.subs.u.w"
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "h.qb", 4))
+              break;
+            return Intrinsic::mips_subuh_qb;	 // "ips.subuh.qb"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 13:	 // 46 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "sq.s.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (NameR[12] != 'h')
+              break;
+            return Intrinsic::mips_absq_s_ph;	 // "ips.absq.s.ph"
+          case 'q':	 // 1 string to match.
+            if (NameR[12] != 'b')
+              break;
+            return Intrinsic::mips_absq_s_qb;	 // "ips.absq.s.qb"
+          }
+          break;
+        case 'd':	 // 4 strings to match.
+          if (NameR[6] != 'd')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "s.ph", 4))
+                break;
+              return Intrinsic::mips_addq_s_ph;	 // "ips.addq.s.ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".r.w", 4))
+                break;
+              return Intrinsic::mips_addqh_r_w;	 // "ips.addqh.r.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, ".s.", 3))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[12] != 'h')
+                break;
+              return Intrinsic::mips_addu_s_ph;	 // "ips.addu.s.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[12] != 'b')
+                break;
+              return Intrinsic::mips_addu_s_qb;	 // "ips.addu.s.qb"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "mp.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "q.ph", 4))
+            break;
+          return Intrinsic::mips_cmp_eq_ph;	 // "ips.cmp.eq.ph"
+        case 'l':	 // 2 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ph", 3))
+              break;
+            return Intrinsic::mips_cmp_le_ph;	 // "ips.cmp.le.ph"
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ph", 3))
+              break;
+            return Intrinsic::mips_cmp_lt_ph;	 // "ips.cmp.lt.ph"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 14 strings to match.
+        if (NameR[5] != 'p')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'a':	 // 7 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'd':	 // 6 strings to match.
+            if (memcmp(NameR.data()+8, "d.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 's':	 // 3 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_s_d;	 // "ips.dpadd.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_s_h;	 // "ips.dpadd.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_s_w;	 // "ips.dpadd.s.w"
+              }
+              break;
+            case 'u':	 // 3 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_u_d;	 // "ips.dpadd.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_u_h;	 // "ips.dpadd.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_dpadd_u_w;	 // "ips.dpadd.u.w"
+              }
+              break;
+            }
+            break;
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, ".w.ph", 5))
+              break;
+            return Intrinsic::mips_dpax_w_ph;	 // "ips.dpax.w.ph"
+          }
+          break;
+        case 's':	 // 7 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'u':	 // 6 strings to match.
+            if (memcmp(NameR.data()+8, "b.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 's':	 // 3 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_s_d;	 // "ips.dpsub.s.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_s_h;	 // "ips.dpsub.s.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_s_w;	 // "ips.dpsub.s.w"
+              }
+              break;
+            case 'u':	 // 3 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_u_d;	 // "ips.dpsub.u.d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_u_h;	 // "ips.dpsub.u.h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_dpsub_u_w;	 // "ips.dpsub.u.w"
+              }
+              break;
+            }
+            break;
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, ".w.ph", 5))
+              break;
+            return Intrinsic::mips_dpsx_w_ph;	 // "ips.dpsx.w.ph"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xtr.rs.w", 8))
+          break;
+        return Intrinsic::mips_extr_rs_w;	 // "ips.extr.rs.w"
+      case 'f':	 // 8 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "int.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffint_s_d;	 // "ips.ffint.s.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffint_s_w;	 // "ips.ffint.s.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffint_u_d;	 // "ips.ffint.u.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffint_u_w;	 // "ips.ffint.u.w"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "int.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ftint_s_d;	 // "ips.ftint.s.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ftint_s_w;	 // "ips.ftint.s.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ftint_u_d;	 // "ips.ftint.u.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ftint_u_w;	 // "ips.ftint.u.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 6 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "ddr.q.", 6))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_maddr_q_h;	 // "ips.maddr.q.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_maddr_q_w;	 // "ips.maddr.q.w"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "ubr.q.", 6))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msubr_q_h;	 // "ips.msubr.q.h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msubr_q_w;	 // "ips.msubr.q.w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "lq.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, "s.w", 3))
+              break;
+            return Intrinsic::mips_mulq_rs_w;	 // "ips.mulq.rs.w"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ph", 3))
+              break;
+            return Intrinsic::mips_mulq_s_ph;	 // "ips.mulq.s.ph"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ackrl.ph", 8))
+          break;
+        return Intrinsic::mips_packrl_ph;	 // "ips.packrl.ph"
+      case 's':	 // 7 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'h':	 // 3 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "l.s.ph", 6))
+              break;
+            return Intrinsic::mips_shll_s_ph;	 // "ips.shll.s.ph"
+          case 'r':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "a.r.", 4))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[12] != 'h')
+                break;
+              return Intrinsic::mips_shra_r_ph;	 // "ips.shra.r.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[12] != 'b')
+                break;
+              return Intrinsic::mips_shra_r_qb;	 // "ips.shra.r.qb"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (NameR[6] != 'b')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "s.ph", 4))
+                break;
+              return Intrinsic::mips_subq_s_ph;	 // "ips.subq.s.ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, ".r.w", 4))
+                break;
+              return Intrinsic::mips_subqh_r_w;	 // "ips.subqh.r.w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, ".s.", 3))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[12] != 'h')
+                break;
+              return Intrinsic::mips_subu_s_ph;	 // "ips.subu.s.ph"
+            case 'q':	 // 1 string to match.
+              if (NameR[12] != 'b')
+                break;
+              return Intrinsic::mips_subu_s_qb;	 // "ips.subu.s.qb"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 14:	 // 26 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "dd", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "h.r.ph", 6))
+            break;
+          return Intrinsic::mips_addqh_r_ph;	 // "ips.addqh.r.ph"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "h.r.qb", 6))
+            break;
+          return Intrinsic::mips_adduh_r_qb;	 // "ips.adduh.r.qb"
+        }
+        break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "mpu.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, "q.qb", 4))
+            break;
+          return Intrinsic::mips_cmpu_eq_qb;	 // "ips.cmpu.eq.qb"
+        case 'l':	 // 2 strings to match.
+          switch (NameR[10]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpu_le_qb;	 // "ips.cmpu.le.qb"
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpu_lt_qb;	 // "ips.cmpu.lt.qb"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 4 strings to match.
+        if (NameR[5] != 'p')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "u.h.qb", 6))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::mips_dpau_h_qbl;	 // "ips.dpau.h.qbl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::mips_dpau_h_qbr;	 // "ips.dpau.h.qbr"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "u.h.qb", 6))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::mips_dpsu_h_qbl;	 // "ips.dpsu.h.qbl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::mips_dpsu_h_qbr;	 // "ips.dpsu.h.qbr"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "trunc.", 6))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          if (NameR[12] != '.')
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_s_d;	 // "ips.ftrunc.s.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_s_w;	 // "ips.ftrunc.s.w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (NameR[12] != '.')
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_u_d;	 // "ips.ftrunc.u.d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_u_w;	 // "ips.ftrunc.u.w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "ul", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, ".rs.ph", 6))
+            break;
+          return Intrinsic::mips_mulq_rs_ph;	 // "ips.mulq.rs.ph"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "a.w.ph", 6))
+            break;
+          return Intrinsic::mips_mulsa_w_ph;	 // "ips.mulsa.w.ph"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "addu.w.qb", 9))
+          break;
+        return Intrinsic::mips_raddu_w_qb;	 // "ips.raddu.w.qb"
+      case 's':	 // 10 strings to match.
+        if (memcmp(NameR.data()+5, "ub", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "h.r.ph", 6))
+            break;
+          return Intrinsic::mips_subqh_r_ph;	 // "ips.subqh.r.ph"
+        case 's':	 // 8 strings to match.
+          if (NameR[8] != 'u')
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, ".u.", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_subsus_u_b;	 // "ips.subsus.u.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_subsus_u_d;	 // "ips.subsus.u.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_subsus_u_h;	 // "ips.subsus.u.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_subsus_u_w;	 // "ips.subsus.u.w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, ".s.", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_subsuu_s_b;	 // "ips.subsuu.s.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_subsuu_s_d;	 // "ips.subsuu.s.d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_subsuu_s_h;	 // "ips.subsuu.s.h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_subsuu_s_w;	 // "ips.subsuu.s.w"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "h.r.qb", 6))
+            break;
+          return Intrinsic::mips_subuh_r_qb;	 // "ips.subuh.r.qb"
+        }
+        break;
+      }
+      break;
+    case 15:	 // 11 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "mpgu.", 5))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+11, "q.qb", 4))
+            break;
+          return Intrinsic::mips_cmpgu_eq_qb;	 // "ips.cmpgu.eq.qb"
+        case 'l':	 // 2 strings to match.
+          switch (NameR[11]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpgu_le_qb;	 // "ips.cmpgu.le.qb"
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpgu_lt_qb;	 // "ips.cmpgu.lt.qb"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 4 strings to match.
+        if (NameR[5] != 'p')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "q.s", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "w.ph", 4))
+              break;
+            return Intrinsic::mips_dpaq_s_w_ph;	 // "ips.dpaq.s.w.ph"
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".l.w", 4))
+              break;
+            return Intrinsic::mips_dpaq_sa_l_w;	 // "ips.dpaq.sa.l.w"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "q.s", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "w.ph", 4))
+              break;
+            return Intrinsic::mips_dpsq_s_w_ph;	 // "ips.dpsq.s.w.ph"
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".l.w", 4))
+              break;
+            return Intrinsic::mips_dpsq_sa_l_w;	 // "ips.dpsq.sa.l.w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "aq.s.w.ph", 9))
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_maq_s_w_phl;	 // "ips.maq.s.w.phl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_maq_s_w_phr;	 // "ips.maq.s.w.phr"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "recr", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case '.':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, "qb.ph", 5))
+            break;
+          return Intrinsic::mips_precr_qb_ph;	 // "ips.precr.qb.ph"
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ph.w", 5))
+            break;
+          return Intrinsic::mips_precrq_ph_w;	 // "ips.precrq.ph.w"
+        }
+        break;
+      }
+      break;
+    case 16:	 // 10 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "mpgdu.", 6))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "q.qb", 4))
+            break;
+          return Intrinsic::mips_cmpgdu_eq_qb;	 // "ips.cmpgdu.eq.qb"
+        case 'l':	 // 2 strings to match.
+          switch (NameR[12]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpgdu_le_qb;	 // "ips.cmpgdu.le.qb"
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, ".qb", 3))
+              break;
+            return Intrinsic::mips_cmpgdu_lt_qb;	 // "ips.cmpgdu.lt.qb"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 2 strings to match.
+        if (NameR[5] != 'p')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, "qx.s.w.ph", 9))
+            break;
+          return Intrinsic::mips_dpaqx_s_w_ph;	 // "ips.dpaqx.s.w.ph"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, "qx.s.w.ph", 9))
+            break;
+          return Intrinsic::mips_dpsqx_s_w_ph;	 // "ips.dpsqx.s.w.ph"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "aq.sa.w.ph", 10))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_maq_sa_w_phl;	 // "ips.maq.sa.w.phl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_maq_sa_w_phr;	 // "ips.maq.sa.w.phr"
+        }
+        break;
+      case 'p':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "rec", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, "q.w.ph", 6))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::mips_preceq_w_phl;	 // "ips.preceq.w.phl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::mips_preceq_w_phr;	 // "ips.preceq.w.phr"
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "q.qb.ph", 7))
+            break;
+          return Intrinsic::mips_precrq_qb_ph;	 // "ips.precrq.qb.ph"
+        }
+        break;
+      }
+      break;
+    case 17:	 // 7 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (NameR[5] != 'p')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, "qx.sa.w.ph", 10))
+            break;
+          return Intrinsic::mips_dpaqx_sa_w_ph;	 // "ips.dpaqx.sa.w.ph"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, "qx.sa.w.ph", 10))
+            break;
+          return Intrinsic::mips_dpsqx_sa_w_ph;	 // "ips.dpsqx.sa.w.ph"
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "ul", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+8, "q.s.w.ph", 8))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::mips_muleq_s_w_phl;	 // "ips.muleq.s.w.phl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::mips_muleq_s_w_phr;	 // "ips.muleq.s.w.phr"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "aq.s.w.ph", 9))
+            break;
+          return Intrinsic::mips_mulsaq_s_w_ph;	 // "ips.mulsaq.s.w.ph"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "receu.ph.qb", 11))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_preceu_ph_qbl;	 // "ips.preceu.ph.qbl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_preceu_ph_qbr;	 // "ips.preceu.ph.qbr"
+        }
+        break;
+      }
+      break;
+    case 18:	 // 8 strings to match.
+      if (memcmp(NameR.data()+0, "ips.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "uleu.s.ph.qb", 12))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_muleu_s_ph_qbl;	 // "ips.muleu.s.ph.qbl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_muleu_s_ph_qbr;	 // "ips.muleu.s.ph.qbr"
+        }
+        break;
+      case 'p':	 // 6 strings to match.
+        if (memcmp(NameR.data()+5, "rec", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            if (memcmp(NameR.data()+10, "u.ph.qb", 7))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              return Intrinsic::mips_precequ_ph_qbl;	 // "ips.precequ.ph.qbl"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::mips_precequ_ph_qbr;	 // "ips.precequ.ph.qbr"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+10, ".ph.qb", 6))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (NameR[17] != 'a')
+                break;
+              return Intrinsic::mips_preceu_ph_qbla;	 // "ips.preceu.ph.qbla"
+            case 'r':	 // 1 string to match.
+              if (NameR[17] != 'a')
+                break;
+              return Intrinsic::mips_preceu_ph_qbra;	 // "ips.preceu.ph.qbra"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, "sra.ph.w", 8))
+              break;
+            return Intrinsic::mips_precr_sra_ph_w;	 // "ips.precr.sra.ph.w"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".rs.ph.w", 8))
+              break;
+            return Intrinsic::mips_precrq_rs_ph_w;	 // "ips.precrq.rs.ph.w"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 19:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "ips.prec", 8))
+        break;
+      switch (NameR[8]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(NameR.data()+9, "qu.ph.qb", 8))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (NameR[18] != 'a')
+            break;
+          return Intrinsic::mips_precequ_ph_qbla;	 // "ips.precequ.ph.qbla"
+        case 'r':	 // 1 string to match.
+          if (NameR[18] != 'a')
+            break;
+          return Intrinsic::mips_precequ_ph_qbra;	 // "ips.precequ.ph.qbra"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+9, "qu.s.qb.ph", 10))
+          break;
+        return Intrinsic::mips_precrqu_s_qb_ph;	 // "ips.precrqu.s.qb.ph"
+      }
+      break;
+    case 20:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "ips.precr.sra.r.ph.w", 20))
+        break;
+      return Intrinsic::mips_precr_sra_r_ph_w;	 // "ips.precr.sra.r.ph.w"
+    }
+    break;  // end of 'm' case.
+  case 'n':
+    if (NameR.startswith("vvm.texsurf.handle.internal.")) return Intrinsic::nvvm_texsurf_handle_internal;
+    if (NameR.startswith("vvm.texsurf.handle.")) return Intrinsic::nvvm_texsurf_handle;
+    if (NameR.startswith("vvm.reflect.")) return Intrinsic::nvvm_reflect;
+    if (NameR.startswith("vvm.ptr.shared.to.gen.")) return Intrinsic::nvvm_ptr_shared_to_gen;
+    if (NameR.startswith("vvm.ptr.local.to.gen.")) return Intrinsic::nvvm_ptr_local_to_gen;
+    if (NameR.startswith("vvm.ptr.global.to.gen.")) return Intrinsic::nvvm_ptr_global_to_gen;
+    if (NameR.startswith("vvm.ptr.gen.to.shared.")) return Intrinsic::nvvm_ptr_gen_to_shared;
+    if (NameR.startswith("vvm.ptr.gen.to.param.")) return Intrinsic::nvvm_ptr_gen_to_param;
+    if (NameR.startswith("vvm.ptr.gen.to.local.")) return Intrinsic::nvvm_ptr_gen_to_local;
+    if (NameR.startswith("vvm.ptr.gen.to.global.")) return Intrinsic::nvvm_ptr_gen_to_global;
+    if (NameR.startswith("vvm.ptr.gen.to.constant.")) return Intrinsic::nvvm_ptr_gen_to_constant;
+    if (NameR.startswith("vvm.ptr.constant.to.gen.")) return Intrinsic::nvvm_ptr_constant_to_gen;
+    if (NameR.startswith("vvm.move.ptr.")) return Intrinsic::nvvm_move_ptr;
+    if (NameR.startswith("vvm.ldu.global.p.")) return Intrinsic::nvvm_ldu_global_p;
+    if (NameR.startswith("vvm.ldu.global.i.")) return Intrinsic::nvvm_ldu_global_i;
+    if (NameR.startswith("vvm.ldu.global.f.")) return Intrinsic::nvvm_ldu_global_f;
+    if (NameR.startswith("vvm.ldg.global.p.")) return Intrinsic::nvvm_ldg_global_p;
+    if (NameR.startswith("vvm.ldg.global.i.")) return Intrinsic::nvvm_ldg_global_i;
+    if (NameR.startswith("vvm.ldg.global.f.")) return Intrinsic::nvvm_ldg_global_f;
+    if (NameR.startswith("vvm.compiler.warn.")) return Intrinsic::nvvm_compiler_warn;
+    if (NameR.startswith("vvm.compiler.error.")) return Intrinsic::nvvm_compiler_error;
+    if (NameR.startswith("vvm.atomic.load.inc.32.")) return Intrinsic::nvvm_atomic_load_inc_32;
+    if (NameR.startswith("vvm.atomic.load.dec.32.")) return Intrinsic::nvvm_atomic_load_dec_32;
+    if (NameR.startswith("vvm.atomic.load.add.f32.")) return Intrinsic::nvvm_atomic_load_add_f32;
+    if (NameR.startswith("earbyint.")) return Intrinsic::nearbyint;
+    switch (NameR.size()) {
+    default: break;
+    case 7:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "vvm.h2f", 7))
+        break;
+      return Intrinsic::nvvm_h2f;	 // "vvm.h2f"
+    case 8:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "vvm.prmt", 8))
+        break;
+      return Intrinsic::nvvm_prmt;	 // "vvm.prmt"
+    case 9:	 // 5 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "bs.i", 4))
+          break;
+        return Intrinsic::nvvm_abs_i;	 // "vvm.abs.i"
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "lz.i", 4))
+          break;
+        return Intrinsic::nvvm_clz_i;	 // "vvm.clz.i"
+      case 'm':	 // 2 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "x.i", 3))
+            break;
+          return Intrinsic::nvvm_max_i;	 // "vvm.max.i"
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "n.i", 3))
+            break;
+          return Intrinsic::nvvm_min_i;	 // "vvm.min.i"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ad.i", 4))
+          break;
+        return Intrinsic::nvvm_sad_i;	 // "vvm.sad.i"
+      }
+      break;
+    case 10:	 // 42 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "bs.ll", 5))
+          break;
+        return Intrinsic::nvvm_abs_ll;	 // "vvm.abs.ll"
+      case 'b':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "rev", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (NameR[9] != '2')
+            break;
+          return Intrinsic::nvvm_brev32;	 // "vvm.brev32"
+        case '6':	 // 1 string to match.
+          if (NameR[9] != '4')
+            break;
+          return Intrinsic::nvvm_brev64;	 // "vvm.brev64"
+        }
+        break;
+      case 'c':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "il.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_ceil_d;	 // "vvm.ceil.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_ceil_f;	 // "vvm.ceil.f"
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "z.ll", 4))
+            break;
+          return Intrinsic::nvvm_clz_ll;	 // "vvm.clz.ll"
+        }
+        break;
+      case 'd':	 // 10 strings to match.
+        if (NameR[5] != '2')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, ".r", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rm;	 // "vvm.d2f.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rn;	 // "vvm.d2f.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rp;	 // "vvm.d2f.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rz;	 // "vvm.d2f.rz"
+          }
+          break;
+        case 'i':	 // 6 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (NameR[9] != 'i')
+              break;
+            return Intrinsic::nvvm_d2i_hi;	 // "vvm.d2i.hi"
+          case 'l':	 // 1 string to match.
+            if (NameR[9] != 'o')
+              break;
+            return Intrinsic::nvvm_d2i_lo;	 // "vvm.d2i.lo"
+          case 'r':	 // 4 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rm;	 // "vvm.d2i.rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rn;	 // "vvm.d2i.rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rp;	 // "vvm.d2i.rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rz;	 // "vvm.d2i.rz"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 11 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 5 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".rn", 3))
+              break;
+            return Intrinsic::nvvm_f2h_rn;	 // "vvm.f2h.rn"
+          case 'i':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, ".r", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rm;	 // "vvm.f2i.rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rn;	 // "vvm.f2i.rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rp;	 // "vvm.f2i.rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rz;	 // "vvm.f2i.rz"
+            }
+            break;
+          }
+          break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "bs.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fabs_d;	 // "vvm.fabs.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fabs_f;	 // "vvm.fabs.f"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "x.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fmax_d;	 // "vvm.fmax.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fmax_f;	 // "vvm.fmax.f"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "n.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fmin_d;	 // "vvm.fmin.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fmin_f;	 // "vvm.fmin.f"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 8 strings to match.
+        if (NameR[5] != '2')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, ".r", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rm;	 // "vvm.i2d.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rn;	 // "vvm.i2d.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rp;	 // "vvm.i2d.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rz;	 // "vvm.i2d.rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, ".r", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rm;	 // "vvm.i2f.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rn;	 // "vvm.i2f.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rp;	 // "vvm.i2f.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rz;	 // "vvm.i2f.rz"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "x.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (NameR[9] != 'l')
+              break;
+            return Intrinsic::nvvm_max_ll;	 // "vvm.max.ll"
+          case 'u':	 // 1 string to match.
+            if (NameR[9] != 'i')
+              break;
+            return Intrinsic::nvvm_max_ui;	 // "vvm.max.ui"
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "n.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (NameR[9] != 'l')
+              break;
+            return Intrinsic::nvvm_min_ll;	 // "vvm.min.ll"
+          case 'u':	 // 1 string to match.
+            if (NameR[9] != 'i')
+              break;
+            return Intrinsic::nvvm_min_ui;	 // "vvm.min.ui"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "opc.i", 5))
+          break;
+        return Intrinsic::nvvm_popc_i;	 // "vvm.popc.i"
+      case 's':	 // 2 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "d.ui", 4))
+            break;
+          return Intrinsic::nvvm_sad_ui;	 // "vvm.sad.ui"
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "rt.f", 4))
+            break;
+          return Intrinsic::nvvm_sqrt_f;	 // "vvm.sqrt.f"
+        }
+        break;
+      }
+      break;
+    case 11:	 // 43 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'd':	 // 8 strings to match.
+        if (NameR[5] != '2')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, "l.r", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rm;	 // "vvm.d2ll.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rn;	 // "vvm.d2ll.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rp;	 // "vvm.d2ll.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rz;	 // "vvm.d2ll.rz"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, "i.r", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rm;	 // "vvm.d2ui.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rn;	 // "vvm.d2ui.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rp;	 // "vvm.d2ui.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rz;	 // "vvm.d2ui.rz"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 10 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "l.r", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rm;	 // "vvm.f2ll.rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rn;	 // "vvm.f2ll.rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rp;	 // "vvm.f2ll.rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rz;	 // "vvm.f2ll.rz"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "i.r", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rm;	 // "vvm.f2ui.rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rn;	 // "vvm.f2ui.rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rp;	 // "vvm.f2ui.rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rz;	 // "vvm.f2ui.rz"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "oor.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_floor_d;	 // "vvm.floor.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_floor_f;	 // "vvm.floor.f"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "l2", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+8, ".r", 2))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rm;	 // "vvm.ll2d.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rn;	 // "vvm.ll2d.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rp;	 // "vvm.ll2d.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rz;	 // "vvm.ll2d.rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+8, ".r", 2))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rm;	 // "vvm.ll2f.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rn;	 // "vvm.ll2f.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rp;	 // "vvm.ll2f.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rz;	 // "vvm.ll2f.rz"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "x.ull", 5))
+            break;
+          return Intrinsic::nvvm_max_ull;	 // "vvm.max.ull"
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "n.ull", 5))
+            break;
+          return Intrinsic::nvvm_min_ull;	 // "vvm.min.ull"
+        case 'u':	 // 2 strings to match.
+          if (NameR[6] != 'l')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "4.i", 3))
+              break;
+            return Intrinsic::nvvm_mul24_i;	 // "vvm.mul24.i"
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "i.i", 3))
+              break;
+            return Intrinsic::nvvm_mulhi_i;	 // "vvm.mulhi.i"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "opc.ll", 6))
+          break;
+        return Intrinsic::nvvm_popc_ll;	 // "vvm.popc.ll"
+      case 'r':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "ound.", 5))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_round_d;	 // "vvm.round.d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_round_f;	 // "vvm.round.f"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "runc.", 5))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_trunc_d;	 // "vvm.trunc.d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_trunc_f;	 // "vvm.trunc.f"
+        }
+        break;
+      case 'u':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "i2", 2))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+8, ".r", 2))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rm;	 // "vvm.ui2d.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rn;	 // "vvm.ui2d.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rp;	 // "vvm.ui2d.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rz;	 // "vvm.ui2d.rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+8, ".r", 2))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rm;	 // "vvm.ui2f.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rn;	 // "vvm.ui2f.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rp;	 // "vvm.ui2f.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rz;	 // "vvm.ui2f.rz"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 12:	 // 64 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "dd.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rm_d;	 // "vvm.add.rm.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rm_f;	 // "vvm.add.rm.f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rn_d;	 // "vvm.add.rn.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rn_f;	 // "vvm.add.rn.f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rp_d;	 // "vvm.add.rp.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rp_f;	 // "vvm.add.rp.f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rz_d;	 // "vvm.add.rz.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_add_rz_f;	 // "vvm.add.rz.f"
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "arrier0", 7))
+          break;
+        return Intrinsic::nvvm_barrier0;	 // "vvm.barrier0"
+      case 'd':	 // 12 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "ull.r", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ull_rm;	 // "vvm.d2ull.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ull_rn;	 // "vvm.d2ull.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ull_rp;	 // "vvm.d2ull.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ull_rz;	 // "vvm.d2ull.rz"
+          }
+          break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "v.r", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rm_d;	 // "vvm.div.rm.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rm_f;	 // "vvm.div.rm.f"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rn_d;	 // "vvm.div.rn.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rn_f;	 // "vvm.div.rn.f"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rp_d;	 // "vvm.div.rp.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rp_f;	 // "vvm.div.rp.f"
+            }
+            break;
+          case 'z':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rz_d;	 // "vvm.div.rz.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_div_rz_f;	 // "vvm.div.rz.f"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 12 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "ull.r", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_f2ull_rm;	 // "vvm.f2ull.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_f2ull_rn;	 // "vvm.f2ull.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_f2ull_rp;	 // "vvm.f2ull.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_f2ull_rz;	 // "vvm.f2ull.rz"
+          }
+          break;
+        case 'm':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "a.r", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rm_d;	 // "vvm.fma.rm.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rm_f;	 // "vvm.fma.rm.f"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rn_d;	 // "vvm.fma.rn.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rn_f;	 // "vvm.fma.rn.f"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rp_d;	 // "vvm.fma.rp.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rp_f;	 // "vvm.fma.rp.f"
+            }
+            break;
+          case 'z':	 // 2 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rz_d;	 // "vvm.fma.rz.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fma_rz_f;	 // "vvm.fma.rz.f"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ohi.i2d", 7))
+          break;
+        return Intrinsic::nvvm_lohi_i2d;	 // "vvm.lohi.i2d"
+      case 'm':	 // 14 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'o':	 // 3 strings to match.
+          if (memcmp(NameR.data()+6, "ve.i", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (NameR[11] != '6')
+              break;
+            return Intrinsic::nvvm_move_i16;	 // "vvm.move.i16"
+          case '3':	 // 1 string to match.
+            if (NameR[11] != '2')
+              break;
+            return Intrinsic::nvvm_move_i32;	 // "vvm.move.i32"
+          case '6':	 // 1 string to match.
+            if (NameR[11] != '4')
+              break;
+            return Intrinsic::nvvm_move_i64;	 // "vvm.move.i64"
+          }
+          break;
+        case 'u':	 // 11 strings to match.
+          if (NameR[6] != 'l')
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case '.':	 // 8 strings to match.
+            if (NameR[8] != 'r')
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'm':	 // 2 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rm_d;	 // "vvm.mul.rm.d"
+              case 'f':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rm_f;	 // "vvm.mul.rm.f"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rn_d;	 // "vvm.mul.rn.d"
+              case 'f':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rn_f;	 // "vvm.mul.rn.f"
+              }
+              break;
+            case 'p':	 // 2 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rp_d;	 // "vvm.mul.rp.d"
+              case 'f':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rp_f;	 // "vvm.mul.rp.f"
+              }
+              break;
+            case 'z':	 // 2 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rz_d;	 // "vvm.mul.rz.d"
+              case 'f':	 // 1 string to match.
+                return Intrinsic::nvvm_mul_rz_f;	 // "vvm.mul.rz.f"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "4.ui", 4))
+              break;
+            return Intrinsic::nvvm_mul24_ui;	 // "vvm.mul24.ui"
+          case 'h':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "i.", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (NameR[11] != 'l')
+                break;
+              return Intrinsic::nvvm_mulhi_ll;	 // "vvm.mulhi.ll"
+            case 'u':	 // 1 string to match.
+              if (NameR[11] != 'i')
+                break;
+              return Intrinsic::nvvm_mulhi_ui;	 // "vvm.mulhi.ui"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'r':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "cp.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rm_d;	 // "vvm.rcp.rm.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rm_f;	 // "vvm.rcp.rm.f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rn_d;	 // "vvm.rcp.rn.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rn_f;	 // "vvm.rcp.rn.f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rp_d;	 // "vvm.rcp.rp.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rp_f;	 // "vvm.rcp.rp.f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rz_d;	 // "vvm.rcp.rz.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_rcp_rz_f;	 // "vvm.rcp.rz.f"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 8 strings to match.
+        if (memcmp(NameR.data()+5, "ll2", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, ".r", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2d_rm;	 // "vvm.ull2d.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2d_rn;	 // "vvm.ull2d.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2d_rp;	 // "vvm.ull2d.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2d_rz;	 // "vvm.ull2d.rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, ".r", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2f_rm;	 // "vvm.ull2f.rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2f_rn;	 // "vvm.ull2f.rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2f_rp;	 // "vvm.ull2f.rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ull2f_rz;	 // "vvm.ull2f.rz"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 13:	 // 14 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "mbar.gl", 7))
+            break;
+          return Intrinsic::nvvm_membar_gl;	 // "vvm.membar.gl"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "lhi.ull", 7))
+            break;
+          return Intrinsic::nvvm_mulhi_ull;	 // "vvm.mulhi.ull"
+        }
+        break;
+      case 's':	 // 10 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'q':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "rt.r", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rm_d;	 // "vvm.sqrt.rm.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rm_f;	 // "vvm.sqrt.rm.f"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rn_d;	 // "vvm.sqrt.rn.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rn_f;	 // "vvm.sqrt.rn.f"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rp_d;	 // "vvm.sqrt.rp.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rp_f;	 // "vvm.sqrt.rp.f"
+            }
+            break;
+          case 'z':	 // 2 strings to match.
+            if (NameR[11] != '.')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rz_d;	 // "vvm.sqrt.rz.d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_sqrt_rz_f;	 // "vvm.sqrt.rz.f"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "q.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "epth", 4))
+              break;
+            return Intrinsic::nvvm_suq_depth;	 // "vvm.suq.depth"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "idth", 4))
+              break;
+            return Intrinsic::nvvm_suq_width;	 // "vvm.suq.width"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "xq.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "epth", 4))
+            break;
+          return Intrinsic::nvvm_txq_depth;	 // "vvm.txq.depth"
+        case 'w':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "idth", 4))
+            break;
+          return Intrinsic::nvvm_txq_width;	 // "vvm.txq.width"
+        }
+        break;
+      }
+      break;
+    case 14:	 // 22 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "eil.ftz.f", 9))
+          break;
+        return Intrinsic::nvvm_ceil_ftz_f;	 // "vvm.ceil.ftz.f"
+      case 'd':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "2f.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz", 4))
+            break;
+          return Intrinsic::nvvm_d2f_rm_ftz;	 // "vvm.d2f.rm.ftz"
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz", 4))
+            break;
+          return Intrinsic::nvvm_d2f_rn_ftz;	 // "vvm.d2f.rn.ftz"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz", 4))
+            break;
+          return Intrinsic::nvvm_d2f_rp_ftz;	 // "vvm.d2f.rp.ftz"
+        case 'z':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz", 4))
+            break;
+          return Intrinsic::nvvm_d2f_rz_ftz;	 // "vvm.d2f.rz.ftz"
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 5 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".rn.ftz", 7))
+              break;
+            return Intrinsic::nvvm_f2h_rn_ftz;	 // "vvm.f2h.rn.ftz"
+          case 'i':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, ".r", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2i_rm_ftz;	 // "vvm.f2i.rm.ftz"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2i_rn_ftz;	 // "vvm.f2i.rn.ftz"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2i_rp_ftz;	 // "vvm.f2i.rp.ftz"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2i_rz_ftz;	 // "vvm.f2i.rz.ftz"
+            }
+            break;
+          }
+          break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "bs.ftz.f", 8))
+            break;
+          return Intrinsic::nvvm_fabs_ftz_f;	 // "vvm.fabs.ftz.f"
+        case 'm':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "x.ftz.f", 7))
+              break;
+            return Intrinsic::nvvm_fmax_ftz_f;	 // "vvm.fmax.ftz.f"
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "n.ftz.f", 7))
+              break;
+            return Intrinsic::nvvm_fmin_ftz_f;	 // "vvm.fmin.ftz.f"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "mbar.", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ta", 2))
+              break;
+            return Intrinsic::nvvm_membar_cta;	 // "vvm.membar.cta"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ys", 2))
+              break;
+            return Intrinsic::nvvm_membar_sys;	 // "vvm.membar.sys"
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ve.float", 8))
+            break;
+          return Intrinsic::nvvm_move_float;	 // "vvm.move.float"
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "otate.b", 7))
+          break;
+        switch (NameR[12]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (NameR[13] != '2')
+            break;
+          return Intrinsic::nvvm_rotate_b32;	 // "vvm.rotate.b32"
+        case '6':	 // 1 string to match.
+          if (NameR[13] != '4')
+            break;
+          return Intrinsic::nvvm_rotate_b64;	 // "vvm.rotate.b64"
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "turate.", 7))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_saturate_d;	 // "vvm.saturate.d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_saturate_f;	 // "vvm.saturate.f"
+          }
+          break;
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "q.height", 8))
+            break;
+          return Intrinsic::nvvm_suq_height;	 // "vvm.suq.height"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xq.height", 9))
+          break;
+        return Intrinsic::nvvm_txq_height;	 // "vvm.txq.height"
+      }
+      break;
+    case 15:	 // 15 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'b':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "rrier0.or", 9))
+            break;
+          return Intrinsic::nvvm_barrier0_or;	 // "vvm.barrier0.or"
+        case 'i':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "tcast.", 6))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "2i", 2))
+              break;
+            return Intrinsic::nvvm_bitcast_f2i;	 // "vvm.bitcast.f2i"
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "2f", 2))
+              break;
+            return Intrinsic::nvvm_bitcast_i2f;	 // "vvm.bitcast.i2f"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 9 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 8 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "l.r", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ll_rm_ftz;	 // "vvm.f2ll.rm.ftz"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ll_rn_ftz;	 // "vvm.f2ll.rn.ftz"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ll_rp_ftz;	 // "vvm.f2ll.rp.ftz"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ll_rz_ftz;	 // "vvm.f2ll.rz.ftz"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, "i.r", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ui_rm_ftz;	 // "vvm.f2ui.rm.ftz"
+            case 'n':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ui_rn_ftz;	 // "vvm.f2ui.rn.ftz"
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ui_rp_ftz;	 // "vvm.f2ui.rp.ftz"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, ".ftz", 4))
+                break;
+              return Intrinsic::nvvm_f2ui_rz_ftz;	 // "vvm.f2ui.rz.ftz"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "oor.ftz.f", 9))
+            break;
+          return Intrinsic::nvvm_floor_ftz_f;	 // "vvm.floor.ftz.f"
+        }
+        break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ove.double", 10))
+          break;
+        return Intrinsic::nvvm_move_double;	 // "vvm.move.double"
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "ound.ftz.f", 10))
+          break;
+        return Intrinsic::nvvm_round_ftz_f;	 // "vvm.round.ftz.f"
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "runc.ftz.f", 10))
+          break;
+        return Intrinsic::nvvm_trunc_ftz_f;	 // "vvm.trunc.ftz.f"
+      }
+      break;
+    case 16:	 // 34 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "dd.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_add_rm_ftz_f;	 // "vvm.add.rm.ftz.f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_add_rn_ftz_f;	 // "vvm.add.rn.ftz.f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_add_rp_ftz_f;	 // "vvm.add.rp.ftz.f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_add_rz_ftz_f;	 // "vvm.add.rz.ftz.f"
+        }
+        break;
+      case 'b':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "rrier0.and", 10))
+            break;
+          return Intrinsic::nvvm_barrier0_and;	 // "vvm.barrier0.and"
+        case 'i':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "tcast.", 6))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "2ll", 3))
+              break;
+            return Intrinsic::nvvm_bitcast_d2ll;	 // "vvm.bitcast.d2ll"
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "l2d", 3))
+              break;
+            return Intrinsic::nvvm_bitcast_ll2d;	 // "vvm.bitcast.ll2d"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "os.approx.f", 11))
+          break;
+        return Intrinsic::nvvm_cos_approx_f;	 // "vvm.cos.approx.f"
+      case 'd':	 // 5 strings to match.
+        if (memcmp(NameR.data()+5, "iv.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "pprox.f", 7))
+            break;
+          return Intrinsic::nvvm_div_approx_f;	 // "vvm.div.approx.f"
+        case 'r':	 // 4 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_div_rm_ftz_f;	 // "vvm.div.rm.ftz.f"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_div_rn_ftz_f;	 // "vvm.div.rn.ftz.f"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_div_rp_ftz_f;	 // "vvm.div.rp.ftz.f"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_div_rz_ftz_f;	 // "vvm.div.rz.ftz.f"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "x2.approx.", 10))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_ex2_approx_d;	 // "vvm.ex2.approx.d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_ex2_approx_f;	 // "vvm.ex2.approx.f"
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "ull.r", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rm_ftz;	 // "vvm.f2ull.rm.ftz"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rn_ftz;	 // "vvm.f2ull.rn.ftz"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rp_ftz;	 // "vvm.f2ull.rp.ftz"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, ".ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rz_ftz;	 // "vvm.f2ull.rz.ftz"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "a.r", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rm_ftz_f;	 // "vvm.fma.rm.ftz.f"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rn_ftz_f;	 // "vvm.fma.rn.ftz.f"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rp_ftz_f;	 // "vvm.fma.rp.ftz.f"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rz_ftz_f;	 // "vvm.fma.rz.ftz.f"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "g2.approx.", 10))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_lg2_approx_d;	 // "vvm.lg2.approx.d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_lg2_approx_f;	 // "vvm.lg2.approx.f"
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "ul.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rm_ftz_f;	 // "vvm.mul.rm.ftz.f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rn_ftz_f;	 // "vvm.mul.rn.ftz.f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rp_ftz_f;	 // "vvm.mul.rp.ftz.f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rz_ftz_f;	 // "vvm.mul.rz.ftz.f"
+        }
+        break;
+      case 'r':	 // 4 strings to match.
+        if (memcmp(NameR.data()+5, "cp.r", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rm_ftz_f;	 // "vvm.rcp.rm.ftz.f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rn_ftz_f;	 // "vvm.rcp.rn.ftz.f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rp_ftz_f;	 // "vvm.rcp.rp.ftz.f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, ".ftz.f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rz_ftz_f;	 // "vvm.rcp.rz.ftz.f"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "in.approx.f", 11))
+          break;
+        return Intrinsic::nvvm_sin_approx_f;	 // "vvm.sin.approx.f"
+      }
+      break;
+    case 17:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "arrier0.popc", 12))
+          break;
+        return Intrinsic::nvvm_barrier0_popc;	 // "vvm.barrier0.popc"
+      case 's':	 // 5 strings to match.
+        if (memcmp(NameR.data()+5, "qrt.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, "pprox.f", 7))
+            break;
+          return Intrinsic::nvvm_sqrt_approx_f;	 // "vvm.sqrt.approx.f"
+        case 'r':	 // 4 strings to match.
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_sqrt_rm_ftz_f;	 // "vvm.sqrt.rm.ftz.f"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_sqrt_rn_ftz_f;	 // "vvm.sqrt.rn.ftz.f"
+          case 'p':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_sqrt_rp_ftz_f;	 // "vvm.sqrt.rp.ftz.f"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, ".ftz.f", 6))
+              break;
+            return Intrinsic::nvvm_sqrt_rz_ftz_f;	 // "vvm.sqrt.rz.ftz.f"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 18:	 // 8 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'i':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "sspacep.", 8))
+          break;
+        switch (NameR[13]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "onst", 4))
+            break;
+          return Intrinsic::nvvm_isspacep_const;	 // "vvm.isspacep.const"
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "ocal", 4))
+            break;
+          return Intrinsic::nvvm_isspacep_local;	 // "vvm.isspacep.local"
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(NameR.data()+5, "sqrt.approx.", 12))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rsqrt_approx_d;	 // "vvm.rsqrt.approx.d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rsqrt_approx_f;	 // "vvm.rsqrt.approx.f"
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "turate.ftz.f", 12))
+            break;
+          return Intrinsic::nvvm_saturate_ftz_f;	 // "vvm.saturate.ftz.f"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "q.array.size", 12))
+            break;
+          return Intrinsic::nvvm_suq_array_size;	 // "vvm.suq.array.size"
+        case 'w':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ap.lo.hi.b64", 12))
+            break;
+          return Intrinsic::nvvm_swap_lo_hi_b64;	 // "vvm.swap.lo.hi.b64"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xq.array.size", 13))
+          break;
+        return Intrinsic::nvvm_txq_array_size;	 // "vvm.txq.array.size"
+      }
+      break;
+    case 19:	 // 12 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'i':	 // 5 strings to match.
+        if (NameR[5] != 's')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "pacep.", 6))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'g':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "lobal", 5))
+              break;
+            return Intrinsic::nvvm_isspacep_global;	 // "vvm.isspacep.global"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "hared", 5))
+              break;
+            return Intrinsic::nvvm_isspacep_shared;	 // "vvm.isspacep.shared"
+          }
+          break;
+        case 't':	 // 3 strings to match.
+          if (memcmp(NameR.data()+7, "ypep.", 5))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "mpler", 5))
+                break;
+              return Intrinsic::nvvm_istypep_sampler;	 // "vvm.istypep.sampler"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "rface", 5))
+                break;
+              return Intrinsic::nvvm_istypep_surface;	 // "vvm.istypep.surface"
+            }
+            break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "exture", 6))
+              break;
+            return Intrinsic::nvvm_istypep_texture;	 // "vvm.istypep.texture"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 6 strings to match.
+        if (memcmp(NameR.data()+5, "uld.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case '1':	 // 2 strings to match.
+          if (memcmp(NameR.data()+10, "d.i8.", 5))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "rap", 3))
+              break;
+            return Intrinsic::nvvm_suld_1d_i8_trap;	 // "vvm.suld.1d.i8.trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "ero", 3))
+              break;
+            return Intrinsic::nvvm_suld_1d_i8_zero;	 // "vvm.suld.1d.i8.zero"
+          }
+          break;
+        case '2':	 // 2 strings to match.
+          if (memcmp(NameR.data()+10, "d.i8.", 5))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "rap", 3))
+              break;
+            return Intrinsic::nvvm_suld_2d_i8_trap;	 // "vvm.suld.2d.i8.trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "ero", 3))
+              break;
+            return Intrinsic::nvvm_suld_2d_i8_zero;	 // "vvm.suld.2d.i8.zero"
+          }
+          break;
+        case '3':	 // 2 strings to match.
+          if (memcmp(NameR.data()+10, "d.i8.", 5))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "rap", 3))
+              break;
+            return Intrinsic::nvvm_suld_3d_i8_trap;	 // "vvm.suld.3d.i8.trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "ero", 3))
+              break;
+            return Intrinsic::nvvm_suld_3d_i8_zero;	 // "vvm.suld.3d.i8.zero"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xq.num.samples", 14))
+          break;
+        return Intrinsic::nvvm_txq_num_samples;	 // "vvm.txq.num.samples"
+      }
+      break;
+    case 20:	 // 46 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "os.approx.ftz.f", 15))
+          break;
+        return Intrinsic::nvvm_cos_approx_ftz_f;	 // "vvm.cos.approx.ftz.f"
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "iv.approx.ftz.f", 15))
+          break;
+        return Intrinsic::nvvm_div_approx_ftz_f;	 // "vvm.div.approx.ftz.f"
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "x2.approx.ftz.f", 15))
+          break;
+        return Intrinsic::nvvm_ex2_approx_ftz_f;	 // "vvm.ex2.approx.ftz.f"
+      case 'l':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "g2.approx.ftz.f", 15))
+          break;
+        return Intrinsic::nvvm_lg2_approx_ftz_f;	 // "vvm.lg2.approx.ftz.f"
+      case 'r':	 // 2 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "p.approx.ftz.d", 14))
+            break;
+          return Intrinsic::nvvm_rcp_approx_ftz_d;	 // "vvm.rcp.approx.ftz.d"
+        case 'o':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "tate.right.b64", 14))
+            break;
+          return Intrinsic::nvvm_rotate_right_b64;	 // "vvm.rotate.right.b64"
+        }
+        break;
+      case 's':	 // 22 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "n.approx.ftz.f", 14))
+            break;
+          return Intrinsic::nvvm_sin_approx_ftz_f;	 // "vvm.sin.approx.ftz.f"
+        case 'u':	 // 21 strings to match.
+          if (memcmp(NameR.data()+6, "ld.", 3))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case '1':	 // 7 strings to match.
+            if (memcmp(NameR.data()+10, "d.i", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "6.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i16_trap;	 // "vvm.suld.1d.i16.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i16_zero;	 // "vvm.suld.1d.i16.zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "2.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i32_trap;	 // "vvm.suld.1d.i32.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i32_zero;	 // "vvm.suld.1d.i32.zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "4.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i64_trap;	 // "vvm.suld.1d.i64.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_i64_zero;	 // "vvm.suld.1d.i64.zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, ".clamp", 6))
+                break;
+              return Intrinsic::nvvm_suld_1d_i8_clamp;	 // "vvm.suld.1d.i8.clamp"
+            }
+            break;
+          case '2':	 // 7 strings to match.
+            if (memcmp(NameR.data()+10, "d.i", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "6.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i16_trap;	 // "vvm.suld.2d.i16.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i16_zero;	 // "vvm.suld.2d.i16.zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "2.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i32_trap;	 // "vvm.suld.2d.i32.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i32_zero;	 // "vvm.suld.2d.i32.zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "4.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i64_trap;	 // "vvm.suld.2d.i64.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_i64_zero;	 // "vvm.suld.2d.i64.zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, ".clamp", 6))
+                break;
+              return Intrinsic::nvvm_suld_2d_i8_clamp;	 // "vvm.suld.2d.i8.clamp"
+            }
+            break;
+          case '3':	 // 7 strings to match.
+            if (memcmp(NameR.data()+10, "d.i", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "6.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i16_trap;	 // "vvm.suld.3d.i16.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i16_zero;	 // "vvm.suld.3d.i16.zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "2.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i32_trap;	 // "vvm.suld.3d.i32.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i32_zero;	 // "vvm.suld.3d.i32.zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "4.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i64_trap;	 // "vvm.suld.3d.i64.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+17, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_3d_i64_zero;	 // "vvm.suld.3d.i64.zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, ".clamp", 6))
+                break;
+              return Intrinsic::nvvm_suld_3d_i8_clamp;	 // "vvm.suld.3d.i8.clamp"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 18 strings to match.
+        if (memcmp(NameR.data()+5, "ex.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case '1':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, "d.v4", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4f32_f32;	 // "vvm.tex.1d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4f32_s32;	 // "vvm.tex.1d.v4f32.s32"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4s32_f32;	 // "vvm.tex.1d.v4s32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4s32_s32;	 // "vvm.tex.1d.v4s32.s32"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4u32_f32;	 // "vvm.tex.1d.v4u32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_1d_v4u32_s32;	 // "vvm.tex.1d.v4u32.s32"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, "d.v4", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4f32_f32;	 // "vvm.tex.2d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4f32_s32;	 // "vvm.tex.2d.v4f32.s32"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4s32_f32;	 // "vvm.tex.2d.v4s32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4s32_s32;	 // "vvm.tex.2d.v4s32.s32"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4u32_f32;	 // "vvm.tex.2d.v4u32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_2d_v4u32_s32;	 // "vvm.tex.2d.v4u32.s32"
+            }
+            break;
+          }
+          break;
+        case '3':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, "d.v4", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4f32_f32;	 // "vvm.tex.3d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4f32_s32;	 // "vvm.tex.3d.v4f32.s32"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4s32_f32;	 // "vvm.tex.3d.v4s32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4s32_s32;	 // "vvm.tex.3d.v4s32.s32"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "32.", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4u32_f32;	 // "vvm.tex.3d.v4u32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "32", 2))
+                break;
+              return Intrinsic::nvvm_tex_3d_v4u32_s32;	 // "vvm.tex.3d.v4u32.s32"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 21:	 // 33 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 's':	 // 32 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "rt.approx.ftz.f", 15))
+            break;
+          return Intrinsic::nvvm_sqrt_approx_ftz_f;	 // "vvm.sqrt.approx.ftz.f"
+        case 'u':	 // 31 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 21 strings to match.
+            if (memcmp(NameR.data()+7, "d.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case '1':	 // 7 strings to match.
+              if (memcmp(NameR.data()+10, "d.", 2))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_i16_clamp;	 // "vvm.suld.1d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_i32_clamp;	 // "vvm.suld.1d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_i64_clamp;	 // "vvm.suld.1d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_1d_v2i8_trap;	 // "vvm.suld.1d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_1d_v2i8_zero;	 // "vvm.suld.1d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_1d_v4i8_trap;	 // "vvm.suld.1d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_1d_v4i8_zero;	 // "vvm.suld.1d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case '2':	 // 7 strings to match.
+              if (memcmp(NameR.data()+10, "d.", 2))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_i16_clamp;	 // "vvm.suld.2d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_i32_clamp;	 // "vvm.suld.2d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_i64_clamp;	 // "vvm.suld.2d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_2d_v2i8_trap;	 // "vvm.suld.2d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_2d_v2i8_zero;	 // "vvm.suld.2d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_2d_v4i8_trap;	 // "vvm.suld.2d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_2d_v4i8_zero;	 // "vvm.suld.2d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case '3':	 // 7 strings to match.
+              if (memcmp(NameR.data()+10, "d.", 2))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_i16_clamp;	 // "vvm.suld.3d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_i32_clamp;	 // "vvm.suld.3d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_i64_clamp;	 // "vvm.suld.3d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_3d_v2i8_trap;	 // "vvm.suld.3d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_3d_v2i8_zero;	 // "vvm.suld.3d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+14, "i8.", 3))
+                    break;
+                  switch (NameR[17]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_3d_v4i8_trap;	 // "vvm.suld.3d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+18, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_suld_3d_v4i8_zero;	 // "vvm.suld.3d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".channel.order", 14))
+              break;
+            return Intrinsic::nvvm_suq_channel_order;	 // "vvm.suq.channel.order"
+          case 's':	 // 9 strings to match.
+            if (memcmp(NameR.data()+7, "t.", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'b':	 // 6 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+12, "d.i8.", 5))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i8_trap;	 // "vvm.sust.b.1d.i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i8_zero;	 // "vvm.sust.b.1d.i8.zero"
+                }
+                break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(NameR.data()+12, "d.i8.", 5))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i8_trap;	 // "vvm.sust.b.2d.i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i8_zero;	 // "vvm.sust.b.2d.i8.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+12, "d.i8.", 5))
+                  break;
+                switch (NameR[17]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i8_trap;	 // "vvm.sust.b.3d.i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+18, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i8_zero;	 // "vvm.sust.b.3d.i8.zero"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 3 strings to match.
+              if (NameR[10] != '.')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, "d.i8.trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_i8_trap;	 // "vvm.sust.p.1d.i8.trap"
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, "d.i8.trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_i8_trap;	 // "vvm.sust.p.2d.i8.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, "d.i8.trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_i8_trap;	 // "vvm.sust.p.3d.i8.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "xq.channel.order", 16))
+          break;
+        return Intrinsic::nvvm_txq_channel_order;	 // "vvm.txq.channel.order"
+      }
+      break;
+    case 22:	 // 67 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+5, "sqrt.approx.ftz.f", 17))
+          break;
+        return Intrinsic::nvvm_rsqrt_approx_ftz_f;	 // "vvm.rsqrt.approx.ftz.f"
+      case 's':	 // 63 strings to match.
+        if (NameR[5] != 'u')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'l':	 // 36 strings to match.
+          if (memcmp(NameR.data()+7, "d.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case '1':	 // 12 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i16_trap;	 // "vvm.suld.1d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i16_zero;	 // "vvm.suld.1d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i32_trap;	 // "vvm.suld.1d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i32_zero;	 // "vvm.suld.1d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i64_trap;	 // "vvm.suld.1d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v2i64_zero;	 // "vvm.suld.1d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v2i8_clamp;	 // "vvm.suld.1d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v4i16_trap;	 // "vvm.suld.1d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v4i16_zero;	 // "vvm.suld.1d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v4i32_trap;	 // "vvm.suld.1d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_v4i32_zero;	 // "vvm.suld.1d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v4i8_clamp;	 // "vvm.suld.1d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i16_trap;	 // "vvm.suld.2d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i16_zero;	 // "vvm.suld.2d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i32_trap;	 // "vvm.suld.2d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i32_zero;	 // "vvm.suld.2d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i64_trap;	 // "vvm.suld.2d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v2i64_zero;	 // "vvm.suld.2d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v2i8_clamp;	 // "vvm.suld.2d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v4i16_trap;	 // "vvm.suld.2d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v4i16_zero;	 // "vvm.suld.2d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v4i32_trap;	 // "vvm.suld.2d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_v4i32_zero;	 // "vvm.suld.2d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v4i8_clamp;	 // "vvm.suld.2d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 12 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i16_trap;	 // "vvm.suld.3d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i16_zero;	 // "vvm.suld.3d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i32_trap;	 // "vvm.suld.3d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i32_zero;	 // "vvm.suld.3d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i64_trap;	 // "vvm.suld.3d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v2i64_zero;	 // "vvm.suld.3d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v2i8_clamp;	 // "vvm.suld.3d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v4i16_trap;	 // "vvm.suld.3d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v4i16_zero;	 // "vvm.suld.3d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v4i32_trap;	 // "vvm.suld.3d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_3d_v4i32_zero;	 // "vvm.suld.3d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v4i8_clamp;	 // "vvm.suld.3d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 27 strings to match.
+          if (memcmp(NameR.data()+7, "t.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 21 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i16_trap;	 // "vvm.sust.b.1d.i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i16_zero;	 // "vvm.sust.b.1d.i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i32_trap;	 // "vvm.sust.b.1d.i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i32_zero;	 // "vvm.sust.b.1d.i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i64_trap;	 // "vvm.sust.b.1d.i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i64_zero;	 // "vvm.sust.b.1d.i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i8_clamp;	 // "vvm.sust.b.1d.i8.clamp"
+              }
+              break;
+            case '2':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i16_trap;	 // "vvm.sust.b.2d.i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i16_zero;	 // "vvm.sust.b.2d.i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i32_trap;	 // "vvm.sust.b.2d.i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i32_zero;	 // "vvm.sust.b.2d.i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i64_trap;	 // "vvm.sust.b.2d.i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i64_zero;	 // "vvm.sust.b.2d.i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i8_clamp;	 // "vvm.sust.b.2d.i8.clamp"
+              }
+              break;
+            case '3':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "6.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i16_trap;	 // "vvm.sust.b.3d.i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i16_zero;	 // "vvm.sust.b.3d.i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "2.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i32_trap;	 // "vvm.sust.b.3d.i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i32_zero;	 // "vvm.sust.b.3d.i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, "4.", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i64_trap;	 // "vvm.sust.b.3d.i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+19, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i64_zero;	 // "vvm.sust.b.3d.i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i8_clamp;	 // "vvm.sust.b.3d.i8.clamp"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 6 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_i16_trap;	 // "vvm.sust.p.1d.i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_i32_trap;	 // "vvm.sust.p.1d.i32.trap"
+              }
+              break;
+            case '2':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_i16_trap;	 // "vvm.sust.p.2d.i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_i32_trap;	 // "vvm.sust.p.2d.i32.trap"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.i", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_i16_trap;	 // "vvm.sust.p.3d.i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_i32_trap;	 // "vvm.sust.p.3d.i32.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "ex.cube.v4", 10))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+16, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_v4f32_f32;	 // "vvm.tex.cube.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+16, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_v4s32_f32;	 // "vvm.tex.cube.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+16, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_v4u32_f32;	 // "vvm.tex.cube.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 23:	 // 57 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "ead.ptx.sreg.tid.", 17))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'x':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_x;	 // "vvm.read.ptx.sreg.tid.x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_y;	 // "vvm.read.ptx.sreg.tid.y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_z;	 // "vvm.read.ptx.sreg.tid.z"
+        }
+        break;
+      case 's':	 // 42 strings to match.
+        if (NameR[5] != 'u')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'l':	 // 15 strings to match.
+          if (memcmp(NameR.data()+7, "d.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case '1':	 // 5 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v2i16_clamp;	 // "vvm.suld.1d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v2i32_clamp;	 // "vvm.suld.1d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v2i64_clamp;	 // "vvm.suld.1d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v4i16_clamp;	 // "vvm.suld.1d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_1d_v4i32_clamp;	 // "vvm.suld.1d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 5 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v2i16_clamp;	 // "vvm.suld.2d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v2i32_clamp;	 // "vvm.suld.2d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v2i64_clamp;	 // "vvm.suld.2d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v4i16_clamp;	 // "vvm.suld.2d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_2d_v4i32_clamp;	 // "vvm.suld.2d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 5 strings to match.
+            if (memcmp(NameR.data()+10, "d.v", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v2i16_clamp;	 // "vvm.suld.3d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v2i32_clamp;	 // "vvm.suld.3d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v2i64_clamp;	 // "vvm.suld.3d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v4i16_clamp;	 // "vvm.suld.3d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_suld_3d_v4i32_clamp;	 // "vvm.suld.3d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 27 strings to match.
+          if (memcmp(NameR.data()+7, "t.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 21 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i16_clamp;	 // "vvm.sust.b.1d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i32_clamp;	 // "vvm.sust.b.1d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i64_clamp;	 // "vvm.sust.b.1d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_1d_v2i8_trap;	 // "vvm.sust.b.1d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_1d_v2i8_zero;	 // "vvm.sust.b.1d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_1d_v4i8_trap;	 // "vvm.sust.b.1d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_1d_v4i8_zero;	 // "vvm.sust.b.1d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case '2':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i16_clamp;	 // "vvm.sust.b.2d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i32_clamp;	 // "vvm.sust.b.2d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i64_clamp;	 // "vvm.sust.b.2d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_2d_v2i8_trap;	 // "vvm.sust.b.2d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_2d_v2i8_zero;	 // "vvm.sust.b.2d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_2d_v4i8_trap;	 // "vvm.sust.b.2d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_2d_v4i8_zero;	 // "vvm.sust.b.2d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case '3':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'i':	 // 3 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "6.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i16_clamp;	 // "vvm.sust.b.3d.i16.clamp"
+                case '3':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "2.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i32_clamp;	 // "vvm.sust.b.3d.i32.clamp"
+                case '6':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, "4.clamp", 7))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i64_clamp;	 // "vvm.sust.b.3d.i64.clamp"
+                }
+                break;
+              case 'v':	 // 4 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case '2':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_3d_v2i8_trap;	 // "vvm.sust.b.3d.v2i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_3d_v2i8_zero;	 // "vvm.sust.b.3d.v2i8.zero"
+                  }
+                  break;
+                case '4':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+16, "i8.", 3))
+                    break;
+                  switch (NameR[19]) {
+                  default: break;
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "rap", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_3d_v4i8_trap;	 // "vvm.sust.b.3d.v4i8.trap"
+                  case 'z':	 // 1 string to match.
+                    if (memcmp(NameR.data()+20, "ero", 3))
+                      break;
+                    return Intrinsic::nvvm_sust_b_3d_v4i8_zero;	 // "vvm.sust.b.3d.v4i8.zero"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 6 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.v", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v2i8_trap;	 // "vvm.sust.p.1d.v2i8.trap"
+              case '4':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v4i8_trap;	 // "vvm.sust.p.1d.v4i8.trap"
+              }
+              break;
+            case '2':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.v", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v2i8_trap;	 // "vvm.sust.p.2d.v2i8.trap"
+              case '4':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v4i8_trap;	 // "vvm.sust.p.2d.v4i8.trap"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.v", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v2i8_trap;	 // "vvm.sust.p.3d.v2i8.trap"
+              case '4':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, "i8.trap", 7))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v4i8_trap;	 // "vvm.sust.p.3d.v4i8.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 12 strings to match.
+        if (memcmp(NameR.data()+5, "ld4.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'a':	 // 3 strings to match.
+          if (memcmp(NameR.data()+10, ".2d.v4", 6))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_a_2d_v4f32_f32;	 // "vvm.tld4.a.2d.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_a_2d_v4s32_f32;	 // "vvm.tld4.a.2d.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_a_2d_v4u32_f32;	 // "vvm.tld4.a.2d.v4u32.f32"
+          }
+          break;
+        case 'b':	 // 3 strings to match.
+          if (memcmp(NameR.data()+10, ".2d.v4", 6))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_b_2d_v4f32_f32;	 // "vvm.tld4.b.2d.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_b_2d_v4s32_f32;	 // "vvm.tld4.b.2d.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_b_2d_v4u32_f32;	 // "vvm.tld4.b.2d.v4u32.f32"
+          }
+          break;
+        case 'g':	 // 3 strings to match.
+          if (memcmp(NameR.data()+10, ".2d.v4", 6))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_g_2d_v4f32_f32;	 // "vvm.tld4.g.2d.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_g_2d_v4s32_f32;	 // "vvm.tld4.g.2d.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_g_2d_v4u32_f32;	 // "vvm.tld4.g.2d.v4u32.f32"
+          }
+          break;
+        case 'r':	 // 3 strings to match.
+          if (memcmp(NameR.data()+10, ".2d.v4", 6))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_r_2d_v4f32_f32;	 // "vvm.tld4.r.2d.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_r_2d_v4s32_f32;	 // "vvm.tld4.r.2d.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tld4_r_2d_v4u32_f32;	 // "vvm.tld4.r.2d.v4u32.f32"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 24:	 // 51 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "ead.ptx.sreg.ntid.", 18))
+          break;
+        switch (NameR[23]) {
+        default: break;
+        case 'x':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_x;	 // "vvm.read.ptx.sreg.ntid.x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_y;	 // "vvm.read.ptx.sreg.ntid.y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_z;	 // "vvm.read.ptx.sreg.ntid.z"
+        }
+        break;
+      case 's':	 // 48 strings to match.
+        if (memcmp(NameR.data()+5, "ust.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 36 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 12 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i16_trap;	 // "vvm.sust.b.1d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i16_zero;	 // "vvm.sust.b.1d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i32_trap;	 // "vvm.sust.b.1d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i32_zero;	 // "vvm.sust.b.1d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "4.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i64_trap;	 // "vvm.sust.b.1d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i64_zero;	 // "vvm.sust.b.1d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i8_clamp;	 // "vvm.sust.b.1d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i16_trap;	 // "vvm.sust.b.1d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i16_zero;	 // "vvm.sust.b.1d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i32_trap;	 // "vvm.sust.b.1d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i32_zero;	 // "vvm.sust.b.1d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i8_clamp;	 // "vvm.sust.b.1d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i16_trap;	 // "vvm.sust.b.2d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i16_zero;	 // "vvm.sust.b.2d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i32_trap;	 // "vvm.sust.b.2d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i32_zero;	 // "vvm.sust.b.2d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "4.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i64_trap;	 // "vvm.sust.b.2d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i64_zero;	 // "vvm.sust.b.2d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i8_clamp;	 // "vvm.sust.b.2d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i16_trap;	 // "vvm.sust.b.2d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i16_zero;	 // "vvm.sust.b.2d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i32_trap;	 // "vvm.sust.b.2d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i32_zero;	 // "vvm.sust.b.2d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i8_clamp;	 // "vvm.sust.b.2d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 12 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i16_trap;	 // "vvm.sust.b.3d.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i16_zero;	 // "vvm.sust.b.3d.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i32_trap;	 // "vvm.sust.b.3d.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i32_zero;	 // "vvm.sust.b.3d.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "4.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i64_trap;	 // "vvm.sust.b.3d.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i64_zero;	 // "vvm.sust.b.3d.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i8_clamp;	 // "vvm.sust.b.3d.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "6.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i16_trap;	 // "vvm.sust.b.3d.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i16_zero;	 // "vvm.sust.b.3d.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+18, "2.", 2))
+                  break;
+                switch (NameR[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i32_trap;	 // "vvm.sust.b.3d.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i32_zero;	 // "vvm.sust.b.3d.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i8_clamp;	 // "vvm.sust.b.3d.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 12 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v2i16_trap;	 // "vvm.sust.p.1d.v2i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v2i32_trap;	 // "vvm.sust.p.1d.v2i32.trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v4i16_trap;	 // "vvm.sust.p.1d.v4i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v4i32_trap;	 // "vvm.sust.p.1d.v4i32.trap"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v2i16_trap;	 // "vvm.sust.p.2d.v2i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v2i32_trap;	 // "vvm.sust.p.2d.v2i32.trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v4i16_trap;	 // "vvm.sust.p.2d.v4i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v4i32_trap;	 // "vvm.sust.p.2d.v4i32.trap"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v2i16_trap;	 // "vvm.sust.p.3d.v2i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v2i32_trap;	 // "vvm.sust.p.3d.v2i32.trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v4i16_trap;	 // "vvm.sust.p.3d.v4i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v4i32_trap;	 // "vvm.sust.p.3d.v4i32.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 25:	 // 44 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'r':	 // 13 strings to match.
+        if (memcmp(NameR.data()+5, "ead.ptx.sreg.", 13))
+          break;
+        switch (NameR[18]) {
+        default: break;
+        case 'c':	 // 3 strings to match.
+          if (memcmp(NameR.data()+19, "taid.", 5))
+            break;
+          switch (NameR[24]) {
+          default: break;
+          case 'x':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_x;	 // "vvm.read.ptx.sreg.ctaid.x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_y;	 // "vvm.read.ptx.sreg.ctaid.y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_z;	 // "vvm.read.ptx.sreg.ctaid.z"
+          }
+          break;
+        case 'e':	 // 10 strings to match.
+          if (memcmp(NameR.data()+19, "nvreg", 5))
+            break;
+          switch (NameR[24]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg0;	 // "vvm.read.ptx.sreg.envreg0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg1;	 // "vvm.read.ptx.sreg.envreg1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg2;	 // "vvm.read.ptx.sreg.envreg2"
+          case '3':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg3;	 // "vvm.read.ptx.sreg.envreg3"
+          case '4':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg4;	 // "vvm.read.ptx.sreg.envreg4"
+          case '5':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg5;	 // "vvm.read.ptx.sreg.envreg5"
+          case '6':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg6;	 // "vvm.read.ptx.sreg.envreg6"
+          case '7':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg7;	 // "vvm.read.ptx.sreg.envreg7"
+          case '8':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg8;	 // "vvm.read.ptx.sreg.envreg8"
+          case '9':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg9;	 // "vvm.read.ptx.sreg.envreg9"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 20 strings to match.
+        if (NameR[5] != 'u')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, "d.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(NameR.data()+10, "d.array.i8.", 11))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i8_trap;	 // "vvm.suld.1d.array.i8.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i8_zero;	 // "vvm.suld.1d.array.i8.zero"
+            }
+            break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(NameR.data()+10, "d.array.i8.", 11))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i8_trap;	 // "vvm.suld.2d.array.i8.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i8_zero;	 // "vvm.suld.2d.array.i8.zero"
+            }
+            break;
+          }
+          break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, ".channel.data.type", 18))
+            break;
+          return Intrinsic::nvvm_suq_channel_data_type;	 // "vvm.suq.channel.data.type"
+        case 's':	 // 15 strings to match.
+          if (memcmp(NameR.data()+7, "t.b.", 4))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 5 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i16_clamp;	 // "vvm.sust.b.1d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i32_clamp;	 // "vvm.sust.b.1d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i64_clamp;	 // "vvm.sust.b.1d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i16_clamp;	 // "vvm.sust.b.1d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i32_clamp;	 // "vvm.sust.b.1d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 5 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i16_clamp;	 // "vvm.sust.b.2d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i32_clamp;	 // "vvm.sust.b.2d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i64_clamp;	 // "vvm.sust.b.2d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i16_clamp;	 // "vvm.sust.b.2d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i32_clamp;	 // "vvm.sust.b.2d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 5 strings to match.
+            if (memcmp(NameR.data()+12, "d.v", 3))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i16_clamp;	 // "vvm.sust.b.3d.v2i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i32_clamp;	 // "vvm.sust.b.3d.v2i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i64_clamp;	 // "vvm.sust.b.3d.v2i64.clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[16] != 'i')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i16_clamp;	 // "vvm.sust.b.3d.v4i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i32_clamp;	 // "vvm.sust.b.3d.v4i32.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 11 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 9 strings to match.
+          if (memcmp(NameR.data()+6, "x.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case '1':	 // 3 strings to match.
+            if (memcmp(NameR.data()+9, "d.grad.v4", 9))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_grad_v4f32_f32;	 // "vvm.tex.1d.grad.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_grad_v4s32_f32;	 // "vvm.tex.1d.grad.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_grad_v4u32_f32;	 // "vvm.tex.1d.grad.v4u32.f32"
+            }
+            break;
+          case '2':	 // 3 strings to match.
+            if (memcmp(NameR.data()+9, "d.grad.v4", 9))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_grad_v4f32_f32;	 // "vvm.tex.2d.grad.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_grad_v4s32_f32;	 // "vvm.tex.2d.grad.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_grad_v4u32_f32;	 // "vvm.tex.2d.grad.v4u32.f32"
+            }
+            break;
+          case '3':	 // 3 strings to match.
+            if (memcmp(NameR.data()+9, "d.grad.v4", 9))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_3d_grad_v4f32_f32;	 // "vvm.tex.3d.grad.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_3d_grad_v4s32_f32;	 // "vvm.tex.3d.grad.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_3d_grad_v4u32_f32;	 // "vvm.tex.3d.grad.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case 'x':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "q.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "hannel.data.type", 16))
+              break;
+            return Intrinsic::nvvm_txq_channel_data_type;	 // "vvm.txq.channel.data.type"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "um.mipmap.levels", 16))
+              break;
+            return Intrinsic::nvvm_txq_num_mipmap_levels;	 // "vvm.txq.num.mipmap.levels"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 26:	 // 61 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 'r':	 // 26 strings to match.
+        if (memcmp(NameR.data()+5, "ead.ptx.sreg.", 13))
+          break;
+        switch (NameR[18]) {
+        default: break;
+        case 'e':	 // 22 strings to match.
+          if (memcmp(NameR.data()+19, "nvreg", 5))
+            break;
+          switch (NameR[24]) {
+          default: break;
+          case '1':	 // 10 strings to match.
+            switch (NameR[25]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg10;	 // "vvm.read.ptx.sreg.envreg10"
+            case '1':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg11;	 // "vvm.read.ptx.sreg.envreg11"
+            case '2':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg12;	 // "vvm.read.ptx.sreg.envreg12"
+            case '3':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg13;	 // "vvm.read.ptx.sreg.envreg13"
+            case '4':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg14;	 // "vvm.read.ptx.sreg.envreg14"
+            case '5':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg15;	 // "vvm.read.ptx.sreg.envreg15"
+            case '6':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg16;	 // "vvm.read.ptx.sreg.envreg16"
+            case '7':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg17;	 // "vvm.read.ptx.sreg.envreg17"
+            case '8':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg18;	 // "vvm.read.ptx.sreg.envreg18"
+            case '9':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg19;	 // "vvm.read.ptx.sreg.envreg19"
+            }
+            break;
+          case '2':	 // 10 strings to match.
+            switch (NameR[25]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg20;	 // "vvm.read.ptx.sreg.envreg20"
+            case '1':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg21;	 // "vvm.read.ptx.sreg.envreg21"
+            case '2':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg22;	 // "vvm.read.ptx.sreg.envreg22"
+            case '3':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg23;	 // "vvm.read.ptx.sreg.envreg23"
+            case '4':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg24;	 // "vvm.read.ptx.sreg.envreg24"
+            case '5':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg25;	 // "vvm.read.ptx.sreg.envreg25"
+            case '6':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg26;	 // "vvm.read.ptx.sreg.envreg26"
+            case '7':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg27;	 // "vvm.read.ptx.sreg.envreg27"
+            case '8':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg28;	 // "vvm.read.ptx.sreg.envreg28"
+            case '9':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg29;	 // "vvm.read.ptx.sreg.envreg29"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            switch (NameR[25]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg30;	 // "vvm.read.ptx.sreg.envreg30"
+            case '1':	 // 1 string to match.
+              return Intrinsic::nvvm_read_ptx_sreg_envreg31;	 // "vvm.read.ptx.sreg.envreg31"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 3 strings to match.
+          if (memcmp(NameR.data()+19, "ctaid.", 6))
+            break;
+          switch (NameR[25]) {
+          default: break;
+          case 'x':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_nctaid_x;	 // "vvm.read.ptx.sreg.nctaid.x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_nctaid_y;	 // "vvm.read.ptx.sreg.nctaid.y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_nctaid_z;	 // "vvm.read.ptx.sreg.nctaid.z"
+          }
+          break;
+        case 'w':	 // 1 string to match.
+          if (memcmp(NameR.data()+19, "arpsize", 7))
+            break;
+          return Intrinsic::nvvm_read_ptx_sreg_warpsize;	 // "vvm.read.ptx.sreg.warpsize"
+        }
+        break;
+      case 's':	 // 14 strings to match.
+        if (memcmp(NameR.data()+5, "uld.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case '1':	 // 7 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.i", 9))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "6.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i16_trap;	 // "vvm.suld.1d.array.i16.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i16_zero;	 // "vvm.suld.1d.array.i16.zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "2.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i32_trap;	 // "vvm.suld.1d.array.i32.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i32_zero;	 // "vvm.suld.1d.array.i32.zero"
+            }
+            break;
+          case '6':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "4.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i64_trap;	 // "vvm.suld.1d.array.i64.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i64_zero;	 // "vvm.suld.1d.array.i64.zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".clamp", 6))
+              break;
+            return Intrinsic::nvvm_suld_1d_array_i8_clamp;	 // "vvm.suld.1d.array.i8.clamp"
+          }
+          break;
+        case '2':	 // 7 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.i", 9))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "6.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i16_trap;	 // "vvm.suld.2d.array.i16.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i16_zero;	 // "vvm.suld.2d.array.i16.zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "2.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i32_trap;	 // "vvm.suld.2d.array.i32.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i32_zero;	 // "vvm.suld.2d.array.i32.zero"
+            }
+            break;
+          case '6':	 // 2 strings to match.
+            if (memcmp(NameR.data()+20, "4.", 2))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "rap", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i64_trap;	 // "vvm.suld.2d.array.i64.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, "ero", 3))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i64_zero;	 // "vvm.suld.2d.array.i64.zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, ".clamp", 6))
+              break;
+            return Intrinsic::nvvm_suld_2d_array_i8_clamp;	 // "vvm.suld.2d.array.i8.clamp"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 21 strings to match.
+        if (memcmp(NameR.data()+5, "ex.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case '1':	 // 9 strings to match.
+          if (memcmp(NameR.data()+9, "d.", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(NameR.data()+12, "rray.v4", 7))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4f32_f32;	 // "vvm.tex.1d.array.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4f32_s32;	 // "vvm.tex.1d.array.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4s32_f32;	 // "vvm.tex.1d.array.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4s32_s32;	 // "vvm.tex.1d.array.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4u32_f32;	 // "vvm.tex.1d.array.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_1d_array_v4u32_s32;	 // "vvm.tex.1d.array.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+12, "evel.v4", 7))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_level_v4f32_f32;	 // "vvm.tex.1d.level.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_level_v4s32_f32;	 // "vvm.tex.1d.level.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_level_v4u32_f32;	 // "vvm.tex.1d.level.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 9 strings to match.
+          if (memcmp(NameR.data()+9, "d.", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(NameR.data()+12, "rray.v4", 7))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4f32_f32;	 // "vvm.tex.2d.array.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4f32_s32;	 // "vvm.tex.2d.array.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4s32_f32;	 // "vvm.tex.2d.array.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4s32_s32;	 // "vvm.tex.2d.array.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "32.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4u32_f32;	 // "vvm.tex.2d.array.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_2d_array_v4u32_s32;	 // "vvm.tex.2d.array.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+12, "evel.v4", 7))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_level_v4f32_f32;	 // "vvm.tex.2d.level.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_level_v4s32_f32;	 // "vvm.tex.2d.level.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_level_v4u32_f32;	 // "vvm.tex.2d.level.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case '3':	 // 3 strings to match.
+          if (memcmp(NameR.data()+9, "d.level.v4", 10))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_3d_level_v4f32_f32;	 // "vvm.tex.3d.level.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_3d_level_v4s32_f32;	 // "vvm.tex.3d.level.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+20, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_3d_level_v4u32_f32;	 // "vvm.tex.3d.level.v4u32.f32"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 27:	 // 20 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.su", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case 'l':	 // 14 strings to match.
+        if (memcmp(NameR.data()+7, "d.", 2))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case '1':	 // 7 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.", 8))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'i':	 // 3 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i16_clamp;	 // "vvm.suld.1d.array.i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i32_clamp;	 // "vvm.suld.1d.array.i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_i64_clamp;	 // "vvm.suld.1d.array.i64.clamp"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "i8.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v2i8_trap;	 // "vvm.suld.1d.array.v2i8.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v2i8_zero;	 // "vvm.suld.1d.array.v2i8.zero"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "i8.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v4i8_trap;	 // "vvm.suld.1d.array.v4i8.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v4i8_zero;	 // "vvm.suld.1d.array.v4i8.zero"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '2':	 // 7 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.", 8))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'i':	 // 3 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i16_clamp;	 // "vvm.suld.2d.array.i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i32_clamp;	 // "vvm.suld.2d.array.i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_i64_clamp;	 // "vvm.suld.2d.array.i64.clamp"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "i8.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v2i8_trap;	 // "vvm.suld.2d.array.v2i8.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v2i8_zero;	 // "vvm.suld.2d.array.v2i8.zero"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (memcmp(NameR.data()+20, "i8.", 3))
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v4i8_trap;	 // "vvm.suld.2d.array.v4i8.trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v4i8_zero;	 // "vvm.suld.2d.array.v4i8.zero"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 6 strings to match.
+        if (memcmp(NameR.data()+7, "t.", 2))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 4 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.i8.", 11))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_i8_trap;	 // "vvm.sust.b.1d.array.i8.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_i8_zero;	 // "vvm.sust.b.1d.array.i8.zero"
+            }
+            break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.i8.", 11))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_i8_trap;	 // "vvm.sust.b.2d.array.i8.trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_i8_zero;	 // "vvm.sust.b.2d.array.i8.zero"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "d.array.i8.trap", 15))
+              break;
+            return Intrinsic::nvvm_sust_p_1d_array_i8_trap;	 // "vvm.sust.p.1d.array.i8.trap"
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "d.array.i8.trap", 15))
+              break;
+            return Intrinsic::nvvm_sust_p_2d_array_i8_trap;	 // "vvm.sust.p.2d.array.i8.trap"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 28:	 // 66 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 's':	 // 42 strings to match.
+        if (NameR[5] != 'u')
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case 'l':	 // 24 strings to match.
+          if (memcmp(NameR.data()+7, "d.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case '1':	 // 12 strings to match.
+            if (memcmp(NameR.data()+10, "d.array.v", 9))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[20] != 'i')
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i16_trap;	 // "vvm.suld.1d.array.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i16_zero;	 // "vvm.suld.1d.array.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i32_trap;	 // "vvm.suld.1d.array.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i32_zero;	 // "vvm.suld.1d.array.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "4.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i64_trap;	 // "vvm.suld.1d.array.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v2i64_zero;	 // "vvm.suld.1d.array.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v2i8_clamp;	 // "vvm.suld.1d.array.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[20] != 'i')
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v4i16_trap;	 // "vvm.suld.1d.array.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v4i16_zero;	 // "vvm.suld.1d.array.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v4i32_trap;	 // "vvm.suld.1d.array.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_1d_array_v4i32_zero;	 // "vvm.suld.1d.array.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_1d_array_v4i8_clamp;	 // "vvm.suld.1d.array.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (memcmp(NameR.data()+10, "d.array.v", 9))
+              break;
+            switch (NameR[19]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[20] != 'i')
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i16_trap;	 // "vvm.suld.2d.array.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i16_zero;	 // "vvm.suld.2d.array.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i32_trap;	 // "vvm.suld.2d.array.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i32_zero;	 // "vvm.suld.2d.array.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "4.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i64_trap;	 // "vvm.suld.2d.array.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v2i64_zero;	 // "vvm.suld.2d.array.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v2i8_clamp;	 // "vvm.suld.2d.array.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[20] != 'i')
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v4i16_trap;	 // "vvm.suld.2d.array.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v4i16_zero;	 // "vvm.suld.2d.array.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v4i32_trap;	 // "vvm.suld.2d.array.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_suld_2d_array_v4i32_zero;	 // "vvm.suld.2d.array.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_suld_2d_array_v4i8_clamp;	 // "vvm.suld.2d.array.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 18 strings to match.
+          if (memcmp(NameR.data()+7, "t.", 2))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'b':	 // 14 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.array.i", 9))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i16_trap;	 // "vvm.sust.b.1d.array.i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i16_zero;	 // "vvm.sust.b.1d.array.i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i32_trap;	 // "vvm.sust.b.1d.array.i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i32_zero;	 // "vvm.sust.b.1d.array.i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "4.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i64_trap;	 // "vvm.sust.b.1d.array.i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_i64_zero;	 // "vvm.sust.b.1d.array.i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_i8_clamp;	 // "vvm.sust.b.1d.array.i8.clamp"
+              }
+              break;
+            case '2':	 // 7 strings to match.
+              if (memcmp(NameR.data()+12, "d.array.i", 9))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "6.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i16_trap;	 // "vvm.sust.b.2d.array.i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i16_zero;	 // "vvm.sust.b.2d.array.i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "2.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i32_trap;	 // "vvm.sust.b.2d.array.i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i32_zero;	 // "vvm.sust.b.2d.array.i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "4.", 2))
+                  break;
+                switch (NameR[24]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i64_trap;	 // "vvm.sust.b.2d.array.i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+25, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_i64_zero;	 // "vvm.sust.b.2d.array.i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_i8_clamp;	 // "vvm.sust.b.2d.array.i8.clamp"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 4 strings to match.
+            if (NameR[10] != '.')
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.array.i", 9))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_i16_trap;	 // "vvm.sust.p.1d.array.i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_i32_trap;	 // "vvm.sust.p.1d.array.i32.trap"
+              }
+              break;
+            case '2':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "d.array.i", 9))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_i16_trap;	 // "vvm.sust.p.2d.array.i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_i32_trap;	 // "vvm.sust.p.2d.array.i32.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 24 strings to match.
+        if (memcmp(NameR.data()+5, "ex.", 3))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'c':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, "ube.", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'a':	 // 3 strings to match.
+            if (memcmp(NameR.data()+14, "rray.v4", 7))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_array_v4f32_f32;	 // "vvm.tex.cube.array.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_array_v4s32_f32;	 // "vvm.tex.cube.array.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_array_v4u32_f32;	 // "vvm.tex.cube.array.v4u32.f32"
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+14, "evel.v4", 7))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_level_v4f32_f32;	 // "vvm.tex.cube.level.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_level_v4s32_f32;	 // "vvm.tex.cube.level.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_cube_level_v4u32_f32;	 // "vvm.tex.cube.level.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 18 strings to match.
+          if (memcmp(NameR.data()+9, "nified.", 7))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case '1':	 // 6 strings to match.
+            if (memcmp(NameR.data()+17, "d.v4", 4))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4f32_f32;	 // "vvm.tex.unified.1d.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4f32_s32;	 // "vvm.tex.unified.1d.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4s32_f32;	 // "vvm.tex.unified.1d.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4s32_s32;	 // "vvm.tex.unified.1d.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4u32_f32;	 // "vvm.tex.unified.1d.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_v4u32_s32;	 // "vvm.tex.unified.1d.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 6 strings to match.
+            if (memcmp(NameR.data()+17, "d.v4", 4))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4f32_f32;	 // "vvm.tex.unified.2d.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4f32_s32;	 // "vvm.tex.unified.2d.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4s32_f32;	 // "vvm.tex.unified.2d.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4s32_s32;	 // "vvm.tex.unified.2d.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4u32_f32;	 // "vvm.tex.unified.2d.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_v4u32_s32;	 // "vvm.tex.unified.2d.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 6 strings to match.
+            if (memcmp(NameR.data()+17, "d.v4", 4))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4f32_f32;	 // "vvm.tex.unified.3d.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4f32_s32;	 // "vvm.tex.unified.3d.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4s32_f32;	 // "vvm.tex.unified.3d.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4s32_s32;	 // "vvm.tex.unified.3d.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+22, "32.", 3))
+                break;
+              switch (NameR[25]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4u32_f32;	 // "vvm.tex.unified.3d.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+26, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_3d_v4u32_s32;	 // "vvm.tex.unified.3d.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 29:	 // 28 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.su", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case 'l':	 // 10 strings to match.
+        if (memcmp(NameR.data()+7, "d.", 2))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case '1':	 // 5 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.v", 9))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case '2':	 // 3 strings to match.
+            if (NameR[20] != 'i')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_v2i16_clamp;	 // "vvm.suld.1d.array.v2i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_v2i32_clamp;	 // "vvm.suld.1d.array.v2i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_v2i64_clamp;	 // "vvm.suld.1d.array.v2i64.clamp"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (NameR[20] != 'i')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_v4i16_clamp;	 // "vvm.suld.1d.array.v4i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_1d_array_v4i32_clamp;	 // "vvm.suld.1d.array.v4i32.clamp"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 5 strings to match.
+          if (memcmp(NameR.data()+10, "d.array.v", 9))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case '2':	 // 3 strings to match.
+            if (NameR[20] != 'i')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_v2i16_clamp;	 // "vvm.suld.2d.array.v2i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_v2i32_clamp;	 // "vvm.suld.2d.array.v2i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_v2i64_clamp;	 // "vvm.suld.2d.array.v2i64.clamp"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (NameR[20] != 'i')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_v4i16_clamp;	 // "vvm.suld.2d.array.v4i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_suld_2d_array_v4i32_clamp;	 // "vvm.suld.2d.array.v4i32.clamp"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 18 strings to match.
+        if (memcmp(NameR.data()+7, "t.", 2))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 14 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 7 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.", 8))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'i':	 // 3 strings to match.
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_i16_clamp;	 // "vvm.sust.b.1d.array.i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_i32_clamp;	 // "vvm.sust.b.1d.array.i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_i64_clamp;	 // "vvm.sust.b.1d.array.i64.clamp"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (NameR[21]) {
+              default: break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "i8.", 3))
+                  break;
+                switch (NameR[25]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i8_trap;	 // "vvm.sust.b.1d.array.v2i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i8_zero;	 // "vvm.sust.b.1d.array.v2i8.zero"
+                }
+                break;
+              case '4':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "i8.", 3))
+                  break;
+                switch (NameR[25]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i8_trap;	 // "vvm.sust.b.1d.array.v4i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i8_zero;	 // "vvm.sust.b.1d.array.v4i8.zero"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '2':	 // 7 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.", 8))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'i':	 // 3 strings to match.
+              switch (NameR[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "6.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_i16_clamp;	 // "vvm.sust.b.2d.array.i16.clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "2.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_i32_clamp;	 // "vvm.sust.b.2d.array.i32.clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "4.clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_i64_clamp;	 // "vvm.sust.b.2d.array.i64.clamp"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (NameR[21]) {
+              default: break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "i8.", 3))
+                  break;
+                switch (NameR[25]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i8_trap;	 // "vvm.sust.b.2d.array.v2i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i8_zero;	 // "vvm.sust.b.2d.array.v2i8.zero"
+                }
+                break;
+              case '4':	 // 2 strings to match.
+                if (memcmp(NameR.data()+22, "i8.", 3))
+                  break;
+                switch (NameR[25]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i8_trap;	 // "vvm.sust.b.2d.array.v4i8.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+26, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i8_zero;	 // "vvm.sust.b.2d.array.v4i8.zero"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 4 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "i8.trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_array_v2i8_trap;	 // "vvm.sust.p.1d.array.v2i8.trap"
+            case '4':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "i8.trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_array_v4i8_trap;	 // "vvm.sust.p.1d.array.v4i8.trap"
+            }
+            break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "i8.trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_array_v2i8_trap;	 // "vvm.sust.p.2d.array.v2i8.trap"
+            case '4':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, "i8.trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_array_v4i8_trap;	 // "vvm.sust.p.2d.array.v4i8.trap"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 30:	 // 35 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 's':	 // 32 strings to match.
+        if (memcmp(NameR.data()+5, "ust.", 4))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'b':	 // 24 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 12 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "6.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i16_trap;	 // "vvm.sust.b.1d.array.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i16_zero;	 // "vvm.sust.b.1d.array.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "2.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i32_trap;	 // "vvm.sust.b.1d.array.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i32_zero;	 // "vvm.sust.b.1d.array.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "4.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i64_trap;	 // "vvm.sust.b.1d.array.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v2i64_zero;	 // "vvm.sust.b.1d.array.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_v2i8_clamp;	 // "vvm.sust.b.1d.array.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "6.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i16_trap;	 // "vvm.sust.b.1d.array.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i16_zero;	 // "vvm.sust.b.1d.array.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "2.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i32_trap;	 // "vvm.sust.b.1d.array.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_array_v4i32_zero;	 // "vvm.sust.b.1d.array.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_array_v4i8_clamp;	 // "vvm.sust.b.1d.array.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "6.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i16_trap;	 // "vvm.sust.b.2d.array.v2i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i16_zero;	 // "vvm.sust.b.2d.array.v2i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "2.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i32_trap;	 // "vvm.sust.b.2d.array.v2i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i32_zero;	 // "vvm.sust.b.2d.array.v2i32.zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "4.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i64_trap;	 // "vvm.sust.b.2d.array.v2i64.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v2i64_zero;	 // "vvm.sust.b.2d.array.v2i64.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_v2i8_clamp;	 // "vvm.sust.b.2d.array.v2i8.clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "6.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i16_trap;	 // "vvm.sust.b.2d.array.v4i16.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i16_zero;	 // "vvm.sust.b.2d.array.v4i16.zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(NameR.data()+24, "2.", 2))
+                  break;
+                switch (NameR[26]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i32_trap;	 // "vvm.sust.b.2d.array.v4i32.trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(NameR.data()+27, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_array_v4i32_zero;	 // "vvm.sust.b.2d.array.v4i32.zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, ".clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_array_v4i8_clamp;	 // "vvm.sust.b.2d.array.v4i8.clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 8 strings to match.
+          if (NameR[10] != '.')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case '1':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_v2i16_trap;	 // "vvm.sust.p.1d.array.v2i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_v2i32_trap;	 // "vvm.sust.p.1d.array.v2i32.trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_v4i16_trap;	 // "vvm.sust.p.1d.array.v4i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_array_v4i32_trap;	 // "vvm.sust.p.1d.array.v4i32.trap"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 4 strings to match.
+            if (memcmp(NameR.data()+12, "d.array.v", 9))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_v2i16_trap;	 // "vvm.sust.p.2d.array.v2i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_v2i32_trap;	 // "vvm.sust.p.2d.array.v2i32.trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (NameR[22] != 'i')
+                break;
+              switch (NameR[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "6.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_v4i16_trap;	 // "vvm.sust.p.2d.array.v4i16.trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(NameR.data()+24, "2.trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_array_v4i32_trap;	 // "vvm.sust.p.2d.array.v4i32.trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 3 strings to match.
+        if (memcmp(NameR.data()+5, "ex.unified.cube.v4", 18))
+          break;
+        switch (NameR[23]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+24, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_v4f32_f32;	 // "vvm.tex.unified.cube.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+24, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_v4s32_f32;	 // "vvm.tex.unified.cube.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+24, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_v4u32_f32;	 // "vvm.tex.unified.cube.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 31:	 // 28 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.", 4))
+        break;
+      switch (NameR[4]) {
+      default: break;
+      case 's':	 // 10 strings to match.
+        if (memcmp(NameR.data()+5, "ust.b.", 6))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case '1':	 // 5 strings to match.
+          if (memcmp(NameR.data()+12, "d.array.v", 9))
+            break;
+          switch (NameR[21]) {
+          default: break;
+          case '2':	 // 3 strings to match.
+            if (NameR[22] != 'i')
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i16_clamp;	 // "vvm.sust.b.1d.array.v2i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i32_clamp;	 // "vvm.sust.b.1d.array.v2i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i64_clamp;	 // "vvm.sust.b.1d.array.v2i64.clamp"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (NameR[22] != 'i')
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i16_clamp;	 // "vvm.sust.b.1d.array.v4i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i32_clamp;	 // "vvm.sust.b.1d.array.v4i32.clamp"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 5 strings to match.
+          if (memcmp(NameR.data()+12, "d.array.v", 9))
+            break;
+          switch (NameR[21]) {
+          default: break;
+          case '2':	 // 3 strings to match.
+            if (NameR[22] != 'i')
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i16_clamp;	 // "vvm.sust.b.2d.array.v2i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i32_clamp;	 // "vvm.sust.b.2d.array.v2i32.clamp"
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "4.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i64_clamp;	 // "vvm.sust.b.2d.array.v2i64.clamp"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (NameR[22] != 'i')
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "6.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i16_clamp;	 // "vvm.sust.b.2d.array.v4i16.clamp"
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, "2.clamp", 7))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i32_clamp;	 // "vvm.sust.b.2d.array.v4i32.clamp"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 18 strings to match.
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 6 strings to match.
+          if (memcmp(NameR.data()+6, "x.", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case '1':	 // 3 strings to match.
+            if (memcmp(NameR.data()+9, "d.array.grad.v4", 15))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_array_grad_v4f32_f32;	 // "vvm.tex.1d.array.grad.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_array_grad_v4s32_f32;	 // "vvm.tex.1d.array.grad.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_1d_array_grad_v4u32_f32;	 // "vvm.tex.1d.array.grad.v4u32.f32"
+            }
+            break;
+          case '2':	 // 3 strings to match.
+            if (memcmp(NameR.data()+9, "d.array.grad.v4", 15))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_array_grad_v4f32_f32;	 // "vvm.tex.2d.array.grad.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_array_grad_v4s32_f32;	 // "vvm.tex.2d.array.grad.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_2d_array_grad_v4u32_f32;	 // "vvm.tex.2d.array.grad.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 12 strings to match.
+          if (memcmp(NameR.data()+6, "d4.unified.", 11))
+            break;
+          switch (NameR[17]) {
+          default: break;
+          case 'a':	 // 3 strings to match.
+            if (memcmp(NameR.data()+18, ".2d.v4", 6))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_a_2d_v4f32_f32;	 // "vvm.tld4.unified.a.2d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_a_2d_v4s32_f32;	 // "vvm.tld4.unified.a.2d.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_a_2d_v4u32_f32;	 // "vvm.tld4.unified.a.2d.v4u32.f32"
+            }
+            break;
+          case 'b':	 // 3 strings to match.
+            if (memcmp(NameR.data()+18, ".2d.v4", 6))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_b_2d_v4f32_f32;	 // "vvm.tld4.unified.b.2d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_b_2d_v4s32_f32;	 // "vvm.tld4.unified.b.2d.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_b_2d_v4u32_f32;	 // "vvm.tld4.unified.b.2d.v4u32.f32"
+            }
+            break;
+          case 'g':	 // 3 strings to match.
+            if (memcmp(NameR.data()+18, ".2d.v4", 6))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_g_2d_v4f32_f32;	 // "vvm.tld4.unified.g.2d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_g_2d_v4s32_f32;	 // "vvm.tld4.unified.g.2d.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_g_2d_v4u32_f32;	 // "vvm.tld4.unified.g.2d.v4u32.f32"
+            }
+            break;
+          case 'r':	 // 3 strings to match.
+            if (memcmp(NameR.data()+18, ".2d.v4", 6))
+              break;
+            switch (NameR[24]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_r_2d_v4f32_f32;	 // "vvm.tld4.unified.r.2d.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_r_2d_v4s32_f32;	 // "vvm.tld4.unified.r.2d.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+25, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tld4_unified_r_2d_v4u32_f32;	 // "vvm.tld4.unified.r.2d.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 32:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.", 8))
+        break;
+      switch (NameR[8]) {
+      default: break;
+      case '1':	 // 3 strings to match.
+        if (memcmp(NameR.data()+9, "d.array.level.v4", 16))
+          break;
+        switch (NameR[25]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_1d_array_level_v4f32_f32;	 // "vvm.tex.1d.array.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_1d_array_level_v4s32_f32;	 // "vvm.tex.1d.array.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_1d_array_level_v4u32_f32;	 // "vvm.tex.1d.array.level.v4u32.f32"
+        }
+        break;
+      case '2':	 // 3 strings to match.
+        if (memcmp(NameR.data()+9, "d.array.level.v4", 16))
+          break;
+        switch (NameR[25]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_2d_array_level_v4f32_f32;	 // "vvm.tex.2d.array.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_2d_array_level_v4s32_f32;	 // "vvm.tex.2d.array.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_2d_array_level_v4u32_f32;	 // "vvm.tex.2d.array.level.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 33:	 // 9 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.unified.", 16))
+        break;
+      switch (NameR[16]) {
+      default: break;
+      case '1':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.grad.v4", 9))
+          break;
+        switch (NameR[26]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_grad_v4f32_f32;	 // "vvm.tex.unified.1d.grad.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_grad_v4s32_f32;	 // "vvm.tex.unified.1d.grad.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_grad_v4u32_f32;	 // "vvm.tex.unified.1d.grad.v4u32.f32"
+        }
+        break;
+      case '2':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.grad.v4", 9))
+          break;
+        switch (NameR[26]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_grad_v4f32_f32;	 // "vvm.tex.unified.2d.grad.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_grad_v4s32_f32;	 // "vvm.tex.unified.2d.grad.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_grad_v4u32_f32;	 // "vvm.tex.unified.2d.grad.v4u32.f32"
+        }
+        break;
+      case '3':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.grad.v4", 9))
+          break;
+        switch (NameR[26]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_3d_grad_v4f32_f32;	 // "vvm.tex.unified.3d.grad.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_3d_grad_v4s32_f32;	 // "vvm.tex.unified.3d.grad.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+27, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_3d_grad_v4u32_f32;	 // "vvm.tex.unified.3d.grad.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 34:	 // 24 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.", 8))
+        break;
+      switch (NameR[8]) {
+      default: break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(NameR.data()+9, "ube.array.level.v4", 18))
+          break;
+        switch (NameR[27]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+28, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_array_level_v4f32_f32;	 // "vvm.tex.cube.array.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+28, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_array_level_v4s32_f32;	 // "vvm.tex.cube.array.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+28, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_cube_array_level_v4u32_f32;	 // "vvm.tex.cube.array.level.v4u32.f32"
+        }
+        break;
+      case 'u':	 // 21 strings to match.
+        if (memcmp(NameR.data()+9, "nified.", 7))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case '1':	 // 9 strings to match.
+          if (memcmp(NameR.data()+17, "d.", 2))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(NameR.data()+20, "rray.v4", 7))
+              break;
+            switch (NameR[27]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4f32_f32;	 // "vvm.tex.unified.1d.array.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4f32_s32;	 // "vvm.tex.unified.1d.array.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4s32_f32;	 // "vvm.tex.unified.1d.array.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4s32_s32;	 // "vvm.tex.unified.1d.array.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4u32_f32;	 // "vvm.tex.unified.1d.array.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_1d_array_v4u32_s32;	 // "vvm.tex.unified.1d.array.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+20, "evel.v4", 7))
+              break;
+            switch (NameR[27]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_1d_level_v4f32_f32;	 // "vvm.tex.unified.1d.level.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_1d_level_v4s32_f32;	 // "vvm.tex.unified.1d.level.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_1d_level_v4u32_f32;	 // "vvm.tex.unified.1d.level.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 9 strings to match.
+          if (memcmp(NameR.data()+17, "d.", 2))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(NameR.data()+20, "rray.v4", 7))
+              break;
+            switch (NameR[27]) {
+            default: break;
+            case 'f':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4f32_f32;	 // "vvm.tex.unified.2d.array.v4f32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4f32_s32;	 // "vvm.tex.unified.2d.array.v4f32.s32"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4s32_f32;	 // "vvm.tex.unified.2d.array.v4s32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4s32_s32;	 // "vvm.tex.unified.2d.array.v4s32.s32"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+28, "32.", 3))
+                break;
+              switch (NameR[31]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4u32_f32;	 // "vvm.tex.unified.2d.array.v4u32.f32"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+32, "32", 2))
+                  break;
+                return Intrinsic::nvvm_tex_unified_2d_array_v4u32_s32;	 // "vvm.tex.unified.2d.array.v4u32.s32"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+20, "evel.v4", 7))
+              break;
+            switch (NameR[27]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_2d_level_v4f32_f32;	 // "vvm.tex.unified.2d.level.v4f32.f32"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_2d_level_v4s32_f32;	 // "vvm.tex.unified.2d.level.v4s32.f32"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+28, "32.f32", 6))
+                break;
+              return Intrinsic::nvvm_tex_unified_2d_level_v4u32_f32;	 // "vvm.tex.unified.2d.level.v4u32.f32"
+            }
+            break;
+          }
+          break;
+        case '3':	 // 3 strings to match.
+          if (memcmp(NameR.data()+17, "d.level.v4", 10))
+            break;
+          switch (NameR[27]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+28, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_unified_3d_level_v4f32_f32;	 // "vvm.tex.unified.3d.level.v4f32.f32"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+28, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_unified_3d_level_v4s32_f32;	 // "vvm.tex.unified.3d.level.v4s32.f32"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+28, "32.f32", 6))
+              break;
+            return Intrinsic::nvvm_tex_unified_3d_level_v4u32_f32;	 // "vvm.tex.unified.3d.level.v4u32.f32"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 36:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.unified.cube.", 21))
+        break;
+      switch (NameR[21]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        if (memcmp(NameR.data()+22, "rray.v4", 7))
+          break;
+        switch (NameR[29]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_array_v4f32_f32;	 // "vvm.tex.unified.cube.array.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_array_v4s32_f32;	 // "vvm.tex.unified.cube.array.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_array_v4u32_f32;	 // "vvm.tex.unified.cube.array.v4u32.f32"
+        }
+        break;
+      case 'l':	 // 3 strings to match.
+        if (memcmp(NameR.data()+22, "evel.v4", 7))
+          break;
+        switch (NameR[29]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_level_v4f32_f32;	 // "vvm.tex.unified.cube.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_level_v4s32_f32;	 // "vvm.tex.unified.cube.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+30, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_cube_level_v4u32_f32;	 // "vvm.tex.unified.cube.level.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 39:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.unified.", 16))
+        break;
+      switch (NameR[16]) {
+      default: break;
+      case '1':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.array.grad.v4", 15))
+          break;
+        switch (NameR[32]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_grad_v4f32_f32;	 // "vvm.tex.unified.1d.array.grad.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_grad_v4s32_f32;	 // "vvm.tex.unified.1d.array.grad.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_grad_v4u32_f32;	 // "vvm.tex.unified.1d.array.grad.v4u32.f32"
+        }
+        break;
+      case '2':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.array.grad.v4", 15))
+          break;
+        switch (NameR[32]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_grad_v4f32_f32;	 // "vvm.tex.unified.2d.array.grad.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_grad_v4s32_f32;	 // "vvm.tex.unified.2d.array.grad.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+33, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_grad_v4u32_f32;	 // "vvm.tex.unified.2d.array.grad.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 40:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.unified.", 16))
+        break;
+      switch (NameR[16]) {
+      default: break;
+      case '1':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.array.level.v4", 16))
+          break;
+        switch (NameR[33]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_level_v4f32_f32;	 // "vvm.tex.unified.1d.array.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_level_v4s32_f32;	 // "vvm.tex.unified.1d.array.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_1d_array_level_v4u32_f32;	 // "vvm.tex.unified.1d.array.level.v4u32.f32"
+        }
+        break;
+      case '2':	 // 3 strings to match.
+        if (memcmp(NameR.data()+17, "d.array.level.v4", 16))
+          break;
+        switch (NameR[33]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_level_v4f32_f32;	 // "vvm.tex.unified.2d.array.level.v4f32.f32"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_level_v4s32_f32;	 // "vvm.tex.unified.2d.array.level.v4s32.f32"
+        case 'u':	 // 1 string to match.
+          if (memcmp(NameR.data()+34, "32.f32", 6))
+            break;
+          return Intrinsic::nvvm_tex_unified_2d_array_level_v4u32_f32;	 // "vvm.tex.unified.2d.array.level.v4u32.f32"
+        }
+        break;
+      }
+      break;
+    case 42:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "vvm.tex.unified.cube.array.level.v4", 35))
+        break;
+      switch (NameR[35]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(NameR.data()+36, "32.f32", 6))
+          break;
+        return Intrinsic::nvvm_tex_unified_cube_array_level_v4f32_f32;	 // "vvm.tex.unified.cube.array.level.v4f32.f32"
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+36, "32.f32", 6))
+          break;
+        return Intrinsic::nvvm_tex_unified_cube_array_level_v4s32_f32;	 // "vvm.tex.unified.cube.array.level.v4s32.f32"
+      case 'u':	 // 1 string to match.
+        if (memcmp(NameR.data()+36, "32.f32", 6))
+          break;
+        return Intrinsic::nvvm_tex_unified_cube_array_level_v4u32_f32;	 // "vvm.tex.unified.cube.array.level.v4u32.f32"
+      }
+      break;
+    }
+    break;  // end of 'n' case.
+  case 'o':
+    if (NameR.startswith("bjectsize.")) return Intrinsic::objectsize;
+    break;  // end of 'o' case.
+  case 'p':
+    if (NameR.startswith("tr.annotation.")) return Intrinsic::ptr_annotation;
+    if (NameR.startswith("pc.mtctr.")) return Intrinsic::ppc_mtctr;
+    if (NameR.startswith("owi.")) return Intrinsic::powi;
+    if (NameR.startswith("ow.")) return Intrinsic::pow;
+    switch (NameR.size()) {
+    default: break;
+    case 7:	 // 8 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "marker", 6))
+          break;
+        return Intrinsic::pcmarker;	 // "cmarker"
+      case 'p':	 // 6 strings to match.
+        if (memcmp(NameR.data()+1, "c.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case 'd':	 // 5 strings to match.
+          if (memcmp(NameR.data()+4, "cb", 2))
+            break;
+          switch (NameR[6]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            return Intrinsic::ppc_dcba;	 // "pc.dcba"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::ppc_dcbf;	 // "pc.dcbf"
+          case 'i':	 // 1 string to match.
+            return Intrinsic::ppc_dcbi;	 // "pc.dcbi"
+          case 't':	 // 1 string to match.
+            return Intrinsic::ppc_dcbt;	 // "pc.dcbt"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ppc_dcbz;	 // "pc.dcbz"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+4, "ync", 3))
+            break;
+          return Intrinsic::ppc_sync;	 // "pc.sync"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "efetch", 6))
+          break;
+        return Intrinsic::prefetch;	 // "refetch"
+      }
+      break;
+    case 8:	 // 2 strings to match.
+      if (memcmp(NameR.data()+0, "pc.dcb", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case 's':	 // 1 string to match.
+        if (NameR[7] != 't')
+          break;
+        return Intrinsic::ppc_dcbst;	 // "pc.dcbst"
+      case 'z':	 // 1 string to match.
+        if (NameR[7] != 'l')
+          break;
+        return Intrinsic::ppc_dcbzl;	 // "pc.dcbzl"
+      }
+      break;
+    case 9:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "pc.dcbtst", 9))
+        break;
+      return Intrinsic::ppc_dcbtst;	 // "pc.dcbtst"
+    case 11:	 // 5 strings to match.
+      if (memcmp(NameR.data()+0, "tx.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "ar.sync", 7))
+          break;
+        return Intrinsic::ptx_bar_sync;	 // "tx.bar.sync"
+      case 'r':	 // 4 strings to match.
+        if (memcmp(NameR.data()+4, "ead.pm", 6))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::ptx_read_pm0;	 // "tx.read.pm0"
+        case '1':	 // 1 string to match.
+          return Intrinsic::ptx_read_pm1;	 // "tx.read.pm1"
+        case '2':	 // 1 string to match.
+          return Intrinsic::ptx_read_pm2;	 // "tx.read.pm2"
+        case '3':	 // 1 string to match.
+          return Intrinsic::ptx_read_pm3;	 // "tx.read.pm3"
+        }
+        break;
+      }
+      break;
+    case 12:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "tx.read.smid", 12))
+        break;
+      return Intrinsic::ptx_read_smid;	 // "tx.read.smid"
+    case 13:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "tx.read.", 8))
+        break;
+      switch (NameR[8]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+9, "lock", 4))
+          break;
+        return Intrinsic::ptx_read_clock;	 // "tx.read.clock"
+      case 'n':	 // 1 string to match.
+        if (memcmp(NameR.data()+9, "smid", 4))
+          break;
+        return Intrinsic::ptx_read_nsmid;	 // "tx.read.nsmid"
+      case 't':	 // 4 strings to match.
+        if (memcmp(NameR.data()+9, "id.", 3))
+          break;
+        switch (NameR[12]) {
+        default: break;
+        case 'w':	 // 1 string to match.
+          return Intrinsic::ptx_read_tid_w;	 // "tx.read.tid.w"
+        case 'x':	 // 1 string to match.
+          return Intrinsic::ptx_read_tid_x;	 // "tx.read.tid.x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::ptx_read_tid_y;	 // "tx.read.tid.y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::ptx_read_tid_z;	 // "tx.read.tid.z"
+        }
+        break;
+      }
+      break;
+    case 14:	 // 12 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'p':	 // 5 strings to match.
+        if (memcmp(NameR.data()+1, "c.altivec.", 10))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (NameR[12] != 's')
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_dss;	 // "pc.altivec.dss"
+          case 't':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_dst;	 // "pc.altivec.dst"
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "vx", 2))
+            break;
+          return Intrinsic::ppc_altivec_lvx;	 // "pc.altivec.lvx"
+        case 'v':	 // 2 strings to match.
+          if (NameR[12] != 's')
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsl;	 // "pc.altivec.vsl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsr;	 // "pc.altivec.vsr"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 7 strings to match.
+        if (memcmp(NameR.data()+1, "x.read.", 7))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'g':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "ridid", 5))
+            break;
+          return Intrinsic::ptx_read_gridid;	 // "tx.read.gridid"
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "aneid", 5))
+            break;
+          return Intrinsic::ptx_read_laneid;	 // "tx.read.laneid"
+        case 'n':	 // 4 strings to match.
+          if (memcmp(NameR.data()+9, "tid.", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_w;	 // "tx.read.ntid.w"
+          case 'x':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_x;	 // "tx.read.ntid.x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_y;	 // "tx.read.ntid.y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_z;	 // "tx.read.ntid.z"
+          }
+          break;
+        case 'w':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "arpid", 5))
+            break;
+          return Intrinsic::ptx_read_warpid;	 // "tx.read.warpid"
+        }
+        break;
+      }
+      break;
+    case 15:	 // 23 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'p':	 // 17 strings to match.
+        if (memcmp(NameR.data()+1, "c.altivec.", 10))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "stt", 3))
+            break;
+          return Intrinsic::ppc_altivec_dstt;	 // "pc.altivec.dstt"
+        case 'l':	 // 3 strings to match.
+          if (NameR[12] != 'v')
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[14]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_lvsl;	 // "pc.altivec.lvsl"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_lvsr;	 // "pc.altivec.lvsr"
+            }
+            break;
+          case 'x':	 // 1 string to match.
+            if (NameR[14] != 'l')
+              break;
+            return Intrinsic::ppc_altivec_lvxl;	 // "pc.altivec.lvxl"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "tvx", 3))
+            break;
+          return Intrinsic::ppc_altivec_stvx;	 // "pc.altivec.stvx"
+        case 'v':	 // 12 strings to match.
+          switch (NameR[12]) {
+          default: break;
+          case 'r':	 // 3 strings to match.
+            if (NameR[13] != 'l')
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vrlb;	 // "pc.altivec.vrlb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vrlh;	 // "pc.altivec.vrlh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vrlw;	 // "pc.altivec.vrlw"
+            }
+            break;
+          case 's':	 // 9 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (NameR[14] != 'l')
+                break;
+              return Intrinsic::ppc_altivec_vsel;	 // "pc.altivec.vsel"
+            case 'l':	 // 4 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vslb;	 // "pc.altivec.vslb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vslh;	 // "pc.altivec.vslh"
+              case 'o':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vslo;	 // "pc.altivec.vslo"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vslw;	 // "pc.altivec.vslw"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vsrb;	 // "pc.altivec.vsrb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vsrh;	 // "pc.altivec.vsrh"
+              case 'o':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vsro;	 // "pc.altivec.vsro"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vsrw;	 // "pc.altivec.vsrw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 6 strings to match.
+        if (memcmp(NameR.data()+1, "x.read.", 7))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'c':	 // 5 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, "ock64", 5))
+              break;
+            return Intrinsic::ptx_read_clock64;	 // "tx.read.clock64"
+          case 't':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, "aid.", 4))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ptx_read_ctaid_w;	 // "tx.read.ctaid.w"
+            case 'x':	 // 1 string to match.
+              return Intrinsic::ptx_read_ctaid_x;	 // "tx.read.ctaid.x"
+            case 'y':	 // 1 string to match.
+              return Intrinsic::ptx_read_ctaid_y;	 // "tx.read.ctaid.y"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::ptx_read_ctaid_z;	 // "tx.read.ctaid.z"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "warpid", 6))
+            break;
+          return Intrinsic::ptx_read_nwarpid;	 // "tx.read.nwarpid"
+        }
+        break;
+      }
+      break;
+    case 16:	 // 21 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'p':	 // 17 strings to match.
+        if (memcmp(NameR.data()+1, "c.altivec.", 10))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "stst", 4))
+            break;
+          return Intrinsic::ppc_altivec_dstst;	 // "pc.altivec.dstst"
+        case 'l':	 // 3 strings to match.
+          if (memcmp(NameR.data()+12, "ve", 2))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (NameR[15] != 'x')
+              break;
+            return Intrinsic::ppc_altivec_lvebx;	 // "pc.altivec.lvebx"
+          case 'h':	 // 1 string to match.
+            if (NameR[15] != 'x')
+              break;
+            return Intrinsic::ppc_altivec_lvehx;	 // "pc.altivec.lvehx"
+          case 'w':	 // 1 string to match.
+            if (NameR[15] != 'x')
+              break;
+            return Intrinsic::ppc_altivec_lvewx;	 // "pc.altivec.lvewx"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+12, "tvxl", 4))
+            break;
+          return Intrinsic::ppc_altivec_stvxl;	 // "pc.altivec.stvxl"
+        case 'v':	 // 12 strings to match.
+          switch (NameR[12]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (NameR[13] != 'f')
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (NameR[15] != 'x')
+                break;
+              return Intrinsic::ppc_altivec_vcfsx;	 // "pc.altivec.vcfsx"
+            case 'u':	 // 1 string to match.
+              if (NameR[15] != 'x')
+                break;
+              return Intrinsic::ppc_altivec_vcfux;	 // "pc.altivec.vcfux"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "rm", 2))
+                break;
+              return Intrinsic::ppc_altivec_vperm;	 // "pc.altivec.vperm"
+            case 'k':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "px", 2))
+                break;
+              return Intrinsic::ppc_altivec_vpkpx;	 // "pc.altivec.vpkpx"
+            }
+            break;
+          case 'r':	 // 5 strings to match.
+            switch (NameR[13]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "fp", 2))
+                break;
+              return Intrinsic::ppc_altivec_vrefp;	 // "pc.altivec.vrefp"
+            case 'f':	 // 4 strings to match.
+              if (NameR[14] != 'i')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'm':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vrfim;	 // "pc.altivec.vrfim"
+              case 'n':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vrfin;	 // "pc.altivec.vrfin"
+              case 'p':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vrfip;	 // "pc.altivec.vrfip"
+              case 'z':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vrfiz;	 // "pc.altivec.vrfiz"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(NameR.data()+13, "ra", 2))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vsrab;	 // "pc.altivec.vsrab"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vsrah;	 // "pc.altivec.vsrah"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vsraw;	 // "pc.altivec.vsraw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 4 strings to match.
+        if (memcmp(NameR.data()+1, "x.read.nctaid.", 14))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'w':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_w;	 // "tx.read.nctaid.w"
+        case 'x':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_x;	 // "tx.read.nctaid.x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_y;	 // "tx.read.nctaid.y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_z;	 // "tx.read.nctaid.z"
+        }
+        break;
+      }
+      break;
+    case 17:	 // 29 strings to match.
+      if (memcmp(NameR.data()+0, "pc.altivec.", 11))
+        break;
+      switch (NameR[11]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (NameR[12] != 's')
+          break;
+        switch (NameR[13]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "all", 3))
+            break;
+          return Intrinsic::ppc_altivec_dssall;	 // "pc.altivec.dssall"
+        case 't':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "stt", 3))
+            break;
+          return Intrinsic::ppc_altivec_dststt;	 // "pc.altivec.dststt"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        switch (NameR[12]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+13, "vscr", 4))
+            break;
+          return Intrinsic::ppc_altivec_mfvscr;	 // "pc.altivec.mfvscr"
+        case 't':	 // 1 string to match.
+          if (memcmp(NameR.data()+13, "vscr", 4))
+            break;
+          return Intrinsic::ppc_altivec_mtvscr;	 // "pc.altivec.mtvscr"
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        if (memcmp(NameR.data()+12, "tve", 3))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (NameR[16] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_stvebx;	 // "pc.altivec.stvebx"
+        case 'h':	 // 1 string to match.
+          if (NameR[16] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_stvehx;	 // "pc.altivec.stvehx"
+        case 'w':	 // 1 string to match.
+          if (NameR[16] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_stvewx;	 // "pc.altivec.stvewx"
+        }
+        break;
+      case 'v':	 // 22 strings to match.
+        switch (NameR[12]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(NameR.data()+13, "vg", 2))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavgsb;	 // "pc.altivec.vavgsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavgsh;	 // "pc.altivec.vavgsh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavgsw;	 // "pc.altivec.vavgsw"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavgub;	 // "pc.altivec.vavgub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavguh;	 // "pc.altivec.vavguh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vavguw;	 // "pc.altivec.vavguw"
+            }
+            break;
+          }
+          break;
+        case 'c':	 // 2 strings to match.
+          if (NameR[13] != 't')
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "xs", 2))
+              break;
+            return Intrinsic::ppc_altivec_vctsxs;	 // "pc.altivec.vctsxs"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+15, "xs", 2))
+              break;
+            return Intrinsic::ppc_altivec_vctuxs;	 // "pc.altivec.vctuxs"
+          }
+          break;
+        case 'm':	 // 14 strings to match.
+          switch (NameR[13]) {
+          default: break;
+          case 'a':	 // 7 strings to match.
+            if (NameR[14] != 'x')
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (NameR[16] != 'p')
+                break;
+              return Intrinsic::ppc_altivec_vmaxfp;	 // "pc.altivec.vmaxfp"
+            case 's':	 // 3 strings to match.
+              switch (NameR[16]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxsb;	 // "pc.altivec.vmaxsb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxsh;	 // "pc.altivec.vmaxsh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxsw;	 // "pc.altivec.vmaxsw"
+              }
+              break;
+            case 'u':	 // 3 strings to match.
+              switch (NameR[16]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxub;	 // "pc.altivec.vmaxub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxuh;	 // "pc.altivec.vmaxuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmaxuw;	 // "pc.altivec.vmaxuw"
+              }
+              break;
+            }
+            break;
+          case 'i':	 // 7 strings to match.
+            if (NameR[14] != 'n')
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (NameR[16] != 'p')
+                break;
+              return Intrinsic::ppc_altivec_vminfp;	 // "pc.altivec.vminfp"
+            case 's':	 // 3 strings to match.
+              switch (NameR[16]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminsb;	 // "pc.altivec.vminsb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminsh;	 // "pc.altivec.vminsh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminsw;	 // "pc.altivec.vminsw"
+              }
+              break;
+            case 'u':	 // 3 strings to match.
+              switch (NameR[16]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminub;	 // "pc.altivec.vminub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminuh;	 // "pc.altivec.vminuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vminuw;	 // "pc.altivec.vminuw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 18:	 // 38 strings to match.
+      if (memcmp(NameR.data()+0, "pc.altivec.v", 12))
+        break;
+      switch (NameR[12]) {
+      default: break;
+      case 'a':	 // 7 strings to match.
+        if (memcmp(NameR.data()+13, "dd", 2))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(NameR.data()+16, "uw", 2))
+            break;
+          return Intrinsic::ppc_altivec_vaddcuw;	 // "pc.altivec.vaddcuw"
+        case 's':	 // 3 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vaddsbs;	 // "pc.altivec.vaddsbs"
+          case 'h':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vaddshs;	 // "pc.altivec.vaddshs"
+          case 'w':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vaddsws;	 // "pc.altivec.vaddsws"
+          }
+          break;
+        case 'u':	 // 3 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vaddubs;	 // "pc.altivec.vaddubs"
+          case 'h':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vadduhs;	 // "pc.altivec.vadduhs"
+          case 'w':	 // 1 string to match.
+            if (NameR[17] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vadduws;	 // "pc.altivec.vadduws"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+13, "mpbfp", 5))
+          break;
+        return Intrinsic::ppc_altivec_vcmpbfp;	 // "pc.altivec.vcmpbfp"
+      case 'l':	 // 1 string to match.
+        if (memcmp(NameR.data()+13, "ogefp", 5))
+          break;
+        return Intrinsic::ppc_altivec_vlogefp;	 // "pc.altivec.vlogefp"
+      case 'm':	 // 9 strings to match.
+        switch (NameR[13]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "ddfp", 4))
+            break;
+          return Intrinsic::ppc_altivec_vmaddfp;	 // "pc.altivec.vmaddfp"
+        case 'u':	 // 8 strings to match.
+          if (NameR[14] != 'l')
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'e':	 // 4 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmulesb;	 // "pc.altivec.vmulesb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmulesh;	 // "pc.altivec.vmulesh"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmuleub;	 // "pc.altivec.vmuleub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmuleuh;	 // "pc.altivec.vmuleuh"
+              }
+              break;
+            }
+            break;
+          case 'o':	 // 4 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmulosb;	 // "pc.altivec.vmulosb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmulosh;	 // "pc.altivec.vmulosh"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmuloub;	 // "pc.altivec.vmuloub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmulouh;	 // "pc.altivec.vmulouh"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 6 strings to match.
+        if (NameR[13] != 'k')
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          switch (NameR[15]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vpkshss;	 // "pc.altivec.vpkshss"
+            case 'u':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vpkshus;	 // "pc.altivec.vpkshus"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vpkswss;	 // "pc.altivec.vpkswss"
+            case 'u':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vpkswus;	 // "pc.altivec.vpkswus"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          switch (NameR[15]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "us", 2))
+              break;
+            return Intrinsic::ppc_altivec_vpkuhus;	 // "pc.altivec.vpkuhus"
+          case 'w':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "us", 2))
+              break;
+            return Intrinsic::ppc_altivec_vpkuwus;	 // "pc.altivec.vpkuwus"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 8 strings to match.
+        if (NameR[13] != 'u')
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 'b':	 // 7 strings to match.
+          switch (NameR[15]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "uw", 2))
+              break;
+            return Intrinsic::ppc_altivec_vsubcuw;	 // "pc.altivec.vsubcuw"
+          case 's':	 // 3 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsubsbs;	 // "pc.altivec.vsubsbs"
+            case 'h':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsubshs;	 // "pc.altivec.vsubshs"
+            case 'w':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsubsws;	 // "pc.altivec.vsubsws"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsububs;	 // "pc.altivec.vsububs"
+            case 'h':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsubuhs;	 // "pc.altivec.vsubuhs"
+            case 'w':	 // 1 string to match.
+              if (NameR[17] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsubuws;	 // "pc.altivec.vsubuws"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+15, "sws", 3))
+            break;
+          return Intrinsic::ppc_altivec_vsumsws;	 // "pc.altivec.vsumsws"
+        }
+        break;
+      case 'u':	 // 6 strings to match.
+        if (memcmp(NameR.data()+13, "pk", 2))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'h':	 // 3 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (NameR[17] != 'x')
+              break;
+            return Intrinsic::ppc_altivec_vupkhpx;	 // "pc.altivec.vupkhpx"
+          case 's':	 // 2 strings to match.
+            switch (NameR[17]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vupkhsb;	 // "pc.altivec.vupkhsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vupkhsh;	 // "pc.altivec.vupkhsh"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 3 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (NameR[17] != 'x')
+              break;
+            return Intrinsic::ppc_altivec_vupklpx;	 // "pc.altivec.vupklpx"
+          case 's':	 // 2 strings to match.
+            switch (NameR[17]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vupklsb;	 // "pc.altivec.vupklsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vupklsh;	 // "pc.altivec.vupklsh"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 19:	 // 29 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'p':	 // 24 strings to match.
+        if (memcmp(NameR.data()+1, "c.altivec.v", 11))
+          break;
+        switch (NameR[12]) {
+        default: break;
+        case 'c':	 // 12 strings to match.
+          if (memcmp(NameR.data()+13, "mp", 2))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'e':	 // 4 strings to match.
+            if (NameR[16] != 'q')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (NameR[18] != 'p')
+                break;
+              return Intrinsic::ppc_altivec_vcmpeqfp;	 // "pc.altivec.vcmpeqfp"
+            case 'u':	 // 3 strings to match.
+              switch (NameR[18]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vcmpequb;	 // "pc.altivec.vcmpequb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vcmpequh;	 // "pc.altivec.vcmpequh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vcmpequw;	 // "pc.altivec.vcmpequw"
+              }
+              break;
+            }
+            break;
+          case 'g':	 // 8 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, "fp", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgefp;	 // "pc.altivec.vcmpgefp"
+            case 't':	 // 7 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (NameR[18] != 'p')
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtfp;	 // "pc.altivec.vcmpgtfp"
+              case 's':	 // 3 strings to match.
+                switch (NameR[18]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtsb;	 // "pc.altivec.vcmpgtsb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtsh;	 // "pc.altivec.vcmpgtsh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtsw;	 // "pc.altivec.vcmpgtsw"
+                }
+                break;
+              case 'u':	 // 3 strings to match.
+                switch (NameR[18]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtub;	 // "pc.altivec.vcmpgtub"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtuh;	 // "pc.altivec.vcmpgtuh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::ppc_altivec_vcmpgtuw;	 // "pc.altivec.vcmpgtuw"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+13, "xptefp", 6))
+            break;
+          return Intrinsic::ppc_altivec_vexptefp;	 // "pc.altivec.vexptefp"
+        case 'm':	 // 6 strings to match.
+          if (memcmp(NameR.data()+13, "sum", 3))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "bm", 2))
+              break;
+            return Intrinsic::ppc_altivec_vmsummbm;	 // "pc.altivec.vmsummbm"
+          case 's':	 // 2 strings to match.
+            if (NameR[17] != 'h')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmsumshm;	 // "pc.altivec.vmsumshm"
+            case 's':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmsumshs;	 // "pc.altivec.vmsumshs"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (NameR[17]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[18] != 'm')
+                break;
+              return Intrinsic::ppc_altivec_vmsumubm;	 // "pc.altivec.vmsumubm"
+            case 'h':	 // 2 strings to match.
+              switch (NameR[18]) {
+              default: break;
+              case 'm':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmsumuhm;	 // "pc.altivec.vmsumuhm"
+              case 's':	 // 1 string to match.
+                return Intrinsic::ppc_altivec_vmsumuhs;	 // "pc.altivec.vmsumuhs"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+13, "msubfp", 6))
+            break;
+          return Intrinsic::ppc_altivec_vnmsubfp;	 // "pc.altivec.vnmsubfp"
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+13, "um", 2))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+16, "sws", 3))
+              break;
+            return Intrinsic::ppc_altivec_vsum2sws;	 // "pc.altivec.vsum2sws"
+          case '4':	 // 3 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (NameR[18] != 's')
+                  break;
+                return Intrinsic::ppc_altivec_vsum4sbs;	 // "pc.altivec.vsum4sbs"
+              case 'h':	 // 1 string to match.
+                if (NameR[18] != 's')
+                  break;
+                return Intrinsic::ppc_altivec_vsum4shs;	 // "pc.altivec.vsum4shs"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, "bs", 2))
+                break;
+              return Intrinsic::ppc_altivec_vsum4ubs;	 // "pc.altivec.vsum4ubs"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 5 strings to match.
+        if (memcmp(NameR.data()+1, "x.read.lanemask.", 16))
+          break;
+        switch (NameR[17]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (NameR[18] != 'q')
+            break;
+          return Intrinsic::ptx_read_lanemask_eq;	 // "tx.read.lanemask.eq"
+        case 'g':	 // 2 strings to match.
+          switch (NameR[18]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            return Intrinsic::ptx_read_lanemask_ge;	 // "tx.read.lanemask.ge"
+          case 't':	 // 1 string to match.
+            return Intrinsic::ptx_read_lanemask_gt;	 // "tx.read.lanemask.gt"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          switch (NameR[18]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            return Intrinsic::ptx_read_lanemask_le;	 // "tx.read.lanemask.le"
+          case 't':	 // 1 string to match.
+            return Intrinsic::ptx_read_lanemask_lt;	 // "tx.read.lanemask.lt"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 20:	 // 4 strings to match.
+      if (memcmp(NameR.data()+0, "pc.altivec.v", 12))
+        break;
+      switch (NameR[12]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+13, "mpbfp.p", 7))
+          break;
+        return Intrinsic::ppc_altivec_vcmpbfp_p;	 // "pc.altivec.vcmpbfp.p"
+      case 'm':	 // 2 strings to match.
+        switch (NameR[13]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "addshs", 6))
+            break;
+          return Intrinsic::ppc_altivec_vmhaddshs;	 // "pc.altivec.vmhaddshs"
+        case 'l':	 // 1 string to match.
+          if (memcmp(NameR.data()+14, "adduhm", 6))
+            break;
+          return Intrinsic::ppc_altivec_vmladduhm;	 // "pc.altivec.vmladduhm"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(NameR.data()+13, "sqrtefp", 7))
+          break;
+        return Intrinsic::ppc_altivec_vrsqrtefp;	 // "pc.altivec.vrsqrtefp"
+      }
+      break;
+    case 21:	 // 13 strings to match.
+      if (memcmp(NameR.data()+0, "pc.altivec.v", 12))
+        break;
+      switch (NameR[12]) {
+      default: break;
+      case 'c':	 // 12 strings to match.
+        if (memcmp(NameR.data()+13, "mp", 2))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          if (NameR[16] != 'q')
+            break;
+          switch (NameR[17]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+18, "p.p", 3))
+              break;
+            return Intrinsic::ppc_altivec_vcmpeqfp_p;	 // "pc.altivec.vcmpeqfp.p"
+          case 'u':	 // 3 strings to match.
+            switch (NameR[18]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, ".p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpequb_p;	 // "pc.altivec.vcmpequb.p"
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, ".p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpequh_p;	 // "pc.altivec.vcmpequh.p"
+            case 'w':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, ".p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpequw_p;	 // "pc.altivec.vcmpequw.p"
+            }
+            break;
+          }
+          break;
+        case 'g':	 // 8 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "fp.p", 4))
+              break;
+            return Intrinsic::ppc_altivec_vcmpgefp_p;	 // "pc.altivec.vcmpgefp.p"
+          case 't':	 // 7 strings to match.
+            switch (NameR[17]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "p.p", 3))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtfp_p;	 // "pc.altivec.vcmpgtfp.p"
+            case 's':	 // 3 strings to match.
+              switch (NameR[18]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtsb_p;	 // "pc.altivec.vcmpgtsb.p"
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtsh_p;	 // "pc.altivec.vcmpgtsh.p"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtsw_p;	 // "pc.altivec.vcmpgtsw.p"
+              }
+              break;
+            case 'u':	 // 3 strings to match.
+              switch (NameR[18]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtub_p;	 // "pc.altivec.vcmpgtub.p"
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtuh_p;	 // "pc.altivec.vcmpgtuh.p"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".p", 2))
+                  break;
+                return Intrinsic::ppc_altivec_vcmpgtuw_p;	 // "pc.altivec.vcmpgtuw.p"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(NameR.data()+13, "hraddshs", 8))
+          break;
+        return Intrinsic::ppc_altivec_vmhraddshs;	 // "pc.altivec.vmhraddshs"
+      }
+      break;
+    case 29:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "pc.is.decremented.ctr.nonzero", 29))
+        break;
+      return Intrinsic::ppc_is_decremented_ctr_nonzero;	 // "pc.is.decremented.ctr.nonzero"
+    }
+    break;  // end of 'p' case.
+  case 'r':
+    if (NameR.startswith("ound.")) return Intrinsic::round;
+    if (NameR.startswith("int.")) return Intrinsic::rint;
+    if (NameR.startswith("ead_register.")) return Intrinsic::read_register;
+    switch (NameR.size()) {
+    default: break;
+    case 12:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "eturnaddress", 12))
+        break;
+      return Intrinsic::returnaddress;	 // "eturnaddress"
+    case 15:	 // 4 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '6':	 // 3 strings to match.
+        if (memcmp(NameR.data()+1, "00.read.tgid.", 13))
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 'x':	 // 1 string to match.
+          return Intrinsic::r600_read_tgid_x;	 // "600.read.tgid.x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::r600_read_tgid_y;	 // "600.read.tgid.y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::r600_read_tgid_z;	 // "600.read.tgid.z"
+        }
+        break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "adcyclecounter", 14))
+          break;
+        return Intrinsic::readcyclecounter;	 // "eadcyclecounter"
+      }
+      break;
+    case 16:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "600.read.tidig.", 15))
+        break;
+      switch (NameR[15]) {
+      default: break;
+      case 'x':	 // 1 string to match.
+        return Intrinsic::r600_read_tidig_x;	 // "600.read.tidig.x"
+      case 'y':	 // 1 string to match.
+        return Intrinsic::r600_read_tidig_y;	 // "600.read.tidig.y"
+      case 'z':	 // 1 string to match.
+        return Intrinsic::r600_read_tidig_z;	 // "600.read.tidig.z"
+      }
+      break;
+    case 18:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "600.read.ngroups.", 17))
+        break;
+      switch (NameR[17]) {
+      default: break;
+      case 'x':	 // 1 string to match.
+        return Intrinsic::r600_read_ngroups_x;	 // "600.read.ngroups.x"
+      case 'y':	 // 1 string to match.
+        return Intrinsic::r600_read_ngroups_y;	 // "600.read.ngroups.y"
+      case 'z':	 // 1 string to match.
+        return Intrinsic::r600_read_ngroups_z;	 // "600.read.ngroups.z"
+      }
+      break;
+    case 21:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "600.read.local.size.", 20))
+        break;
+      switch (NameR[20]) {
+      default: break;
+      case 'x':	 // 1 string to match.
+        return Intrinsic::r600_read_local_size_x;	 // "600.read.local.size.x"
+      case 'y':	 // 1 string to match.
+        return Intrinsic::r600_read_local_size_y;	 // "600.read.local.size.y"
+      case 'z':	 // 1 string to match.
+        return Intrinsic::r600_read_local_size_z;	 // "600.read.local.size.z"
+      }
+      break;
+    case 22:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "600.read.global.size.", 21))
+        break;
+      switch (NameR[21]) {
+      default: break;
+      case 'x':	 // 1 string to match.
+        return Intrinsic::r600_read_global_size_x;	 // "600.read.global.size.x"
+      case 'y':	 // 1 string to match.
+        return Intrinsic::r600_read_global_size_y;	 // "600.read.global.size.y"
+      case 'z':	 // 1 string to match.
+        return Intrinsic::r600_read_global_size_z;	 // "600.read.global.size.z"
+      }
+      break;
+    }
+    break;  // end of 'r' case.
+  case 's':
+    if (NameR.startswith("sub.with.overflow.")) return Intrinsic::ssub_with_overflow;
+    if (NameR.startswith("qrt.")) return Intrinsic::sqrt;
+    if (NameR.startswith("mul.with.overflow.")) return Intrinsic::smul_with_overflow;
+    if (NameR.startswith("in.")) return Intrinsic::sin;
+    if (NameR.startswith("add.with.overflow.")) return Intrinsic::sadd_with_overflow;
+    switch (NameR.size()) {
+    default: break;
+    case 5:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "etjmp", 5))
+        break;
+      return Intrinsic::setjmp;	 // "etjmp"
+    case 8:	 // 2 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "gsetjmp", 7))
+          break;
+        return Intrinsic::sigsetjmp;	 // "igsetjmp"
+      case 't':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "acksave", 7))
+          break;
+        return Intrinsic::stacksave;	 // "tacksave"
+      }
+      break;
+    case 9:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "iglongjmp", 9))
+        break;
+      return Intrinsic::siglongjmp;	 // "iglongjmp"
+    case 11:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "tackrestore", 11))
+        break;
+      return Intrinsic::stackrestore;	 // "tackrestore"
+    case 13:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "tackprotector", 13))
+        break;
+      return Intrinsic::stackprotector;	 // "tackprotector"
+    case 18:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "tackprotectorcheck", 18))
+        break;
+      return Intrinsic::stackprotectorcheck;	 // "tackprotectorcheck"
+    }
+    break;  // end of 's' case.
+  case 't':
+    if (NameR.startswith("runc.")) return Intrinsic::trunc;
+    switch (NameR.size()) {
+    default: break;
+    case 3:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "rap", 3))
+        break;
+      return Intrinsic::trap;	 // "rap"
+    }
+    break;  // end of 't' case.
+  case 'u':
+    if (NameR.startswith("sub.with.overflow.")) return Intrinsic::usub_with_overflow;
+    if (NameR.startswith("mul.with.overflow.")) return Intrinsic::umul_with_overflow;
+    if (NameR.startswith("add.with.overflow.")) return Intrinsic::uadd_with_overflow;
+    break;  // end of 'u' case.
+  case 'v':
+    switch (NameR.size()) {
+    default: break;
+    case 5:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "a_end", 5))
+        break;
+      return Intrinsic::vaend;	 // "a_end"
+    case 6:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "a_copy", 6))
+        break;
+      return Intrinsic::vacopy;	 // "a_copy"
+    case 7:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "a_start", 7))
+        break;
+      return Intrinsic::vastart;	 // "a_start"
+    case 13:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "ar.annotation", 13))
+        break;
+      return Intrinsic::var_annotation;	 // "ar.annotation"
+    }
+    break;  // end of 'v' case.
+  case 'w':
+    if (NameR.startswith("rite_register.")) return Intrinsic::write_register;
+    break;  // end of 'w' case.
+  case 'x':
+    if (NameR.startswith("core.testwct.")) return Intrinsic::xcore_testwct;
+    if (NameR.startswith("core.testct.")) return Intrinsic::xcore_testct;
+    if (NameR.startswith("core.syncr.")) return Intrinsic::xcore_syncr;
+    if (NameR.startswith("core.setv.")) return Intrinsic::xcore_setv;
+    if (NameR.startswith("core.settw.")) return Intrinsic::xcore_settw;
+    if (NameR.startswith("core.setrdy.")) return Intrinsic::xcore_setrdy;
+    if (NameR.startswith("core.setpt.")) return Intrinsic::xcore_setpt;
+    if (NameR.startswith("core.setpsc.")) return Intrinsic::xcore_setpsc;
+    if (NameR.startswith("core.setev.")) return Intrinsic::xcore_setev;
+    if (NameR.startswith("core.setd.")) return Intrinsic::xcore_setd;
+    if (NameR.startswith("core.setclk.")) return Intrinsic::xcore_setclk;
+    if (NameR.startswith("core.setc.")) return Intrinsic::xcore_setc;
+    if (NameR.startswith("core.peek.")) return Intrinsic::xcore_peek;
+    if (NameR.startswith("core.outt.")) return Intrinsic::xcore_outt;
+    if (NameR.startswith("core.outshr.")) return Intrinsic::xcore_outshr;
+    if (NameR.startswith("core.outct.")) return Intrinsic::xcore_outct;
+    if (NameR.startswith("core.out.")) return Intrinsic::xcore_out;
+    if (NameR.startswith("core.msync.")) return Intrinsic::xcore_msync;
+    if (NameR.startswith("core.mjoin.")) return Intrinsic::xcore_mjoin;
+    if (NameR.startswith("core.int.")) return Intrinsic::xcore_int;
+    if (NameR.startswith("core.inshr.")) return Intrinsic::xcore_inshr;
+    if (NameR.startswith("core.initsp.")) return Intrinsic::xcore_initsp;
+    if (NameR.startswith("core.initpc.")) return Intrinsic::xcore_initpc;
+    if (NameR.startswith("core.initlr.")) return Intrinsic::xcore_initlr;
+    if (NameR.startswith("core.initdp.")) return Intrinsic::xcore_initdp;
+    if (NameR.startswith("core.initcp.")) return Intrinsic::xcore_initcp;
+    if (NameR.startswith("core.inct.")) return Intrinsic::xcore_inct;
+    if (NameR.startswith("core.in.")) return Intrinsic::xcore_in;
+    if (NameR.startswith("core.getts.")) return Intrinsic::xcore_getts;
+    if (NameR.startswith("core.getst.")) return Intrinsic::xcore_getst;
+    if (NameR.startswith("core.getr.")) return Intrinsic::xcore_getr;
+    if (NameR.startswith("core.freer.")) return Intrinsic::xcore_freer;
+    if (NameR.startswith("core.endin.")) return Intrinsic::xcore_endin;
+    if (NameR.startswith("core.eeu.")) return Intrinsic::xcore_eeu;
+    if (NameR.startswith("core.edu.")) return Intrinsic::xcore_edu;
+    if (NameR.startswith("core.clrpt.")) return Intrinsic::xcore_clrpt;
+    if (NameR.startswith("core.chkct.")) return Intrinsic::xcore_chkct;
+    switch (NameR.size()) {
+    default: break;
+    case 6:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "86.int", 6))
+        break;
+      return Intrinsic::x86_int;	 // "86.int"
+    case 7:	 // 1 string to match.
+      if (memcmp(NameR.data()+0, "86.xend", 7))
+        break;
+      return Intrinsic::x86_xend;	 // "86.xend"
+    case 8:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'r':	 // 2 strings to match.
+        if (NameR[4] != 'd')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "mc", 2))
+            break;
+          return Intrinsic::x86_rdpmc;	 // "86.rdpmc"
+        case 't':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "sc", 2))
+            break;
+          return Intrinsic::x86_rdtsc;	 // "86.rdtsc"
+        }
+        break;
+      case 'x':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "test", 4))
+          break;
+        return Intrinsic::x86_xtest;	 // "86.xtest"
+      }
+      break;
+    case 9:	 // 7 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '8':	 // 3 strings to match.
+        if (memcmp(NameR.data()+1, "6.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+4, "dtscp", 5))
+            break;
+          return Intrinsic::x86_rdtscp;	 // "86.rdtscp"
+        case 'x':	 // 2 strings to match.
+          switch (NameR[4]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+5, "bort", 4))
+              break;
+            return Intrinsic::x86_xabort;	 // "86.xabort"
+          case 'b':	 // 1 string to match.
+            if (memcmp(NameR.data()+5, "egin", 4))
+              break;
+            return Intrinsic::x86_xbegin;	 // "86.xbegin"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 4 strings to match.
+        if (memcmp(NameR.data()+1, "ore.", 4))
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "re", 2))
+              break;
+            return Intrinsic::xcore_clre;	 // "core.clre"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "c8", 2))
+              break;
+            return Intrinsic::xcore_crc8;	 // "core.crc8"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ext", 3))
+            break;
+          return Intrinsic::xcore_sext;	 // "core.sext"
+        case 'z':	 // 1 string to match.
+          if (memcmp(NameR.data()+6, "ext", 3))
+            break;
+          return Intrinsic::xcore_zext;	 // "core.zext"
+        }
+        break;
+      }
+      break;
+    case 10:	 // 10 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '8':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "6.mmx.por", 9))
+          break;
+        return Intrinsic::x86_mmx_por;	 // "86.mmx.por"
+      case 'c':	 // 9 strings to match.
+        if (memcmp(NameR.data()+1, "ore.", 4))
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "rsr", 3))
+              break;
+            return Intrinsic::xcore_clrsr;	 // "core.clrsr"
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "c32", 3))
+              break;
+            return Intrinsic::xcore_crc32;	 // "core.crc32"
+          }
+          break;
+        case 'g':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "et", 2))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::xcore_geted;	 // "core.geted"
+            case 't':	 // 1 string to match.
+              return Intrinsic::xcore_getet;	 // "core.getet"
+            }
+            break;
+          case 'i':	 // 1 string to match.
+            if (NameR[9] != 'd')
+              break;
+            return Intrinsic::xcore_getid;	 // "core.getid"
+          case 'p':	 // 1 string to match.
+            if (NameR[9] != 's')
+              break;
+            return Intrinsic::xcore_getps;	 // "core.getps"
+          }
+          break;
+        case 's':	 // 3 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (NameR[7] != 't')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (NameR[9] != 's')
+                break;
+              return Intrinsic::xcore_setps;	 // "core.setps"
+            case 's':	 // 1 string to match.
+              if (NameR[9] != 'r')
+                break;
+              return Intrinsic::xcore_setsr;	 // "core.setsr"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, "ync", 3))
+              break;
+            return Intrinsic::xcore_ssync;	 // "core.ssync"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 11:	 // 6 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '8':	 // 5 strings to match.
+        if (memcmp(NameR.data()+1, "6.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case 'm':	 // 3 strings to match.
+          if (memcmp(NameR.data()+4, "mx.", 3))
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "mms", 3))
+              break;
+            return Intrinsic::x86_mmx_emms;	 // "86.mmx.emms"
+          case 'p':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "nd", 2))
+                break;
+              return Intrinsic::x86_mmx_pand;	 // "86.mmx.pand"
+            case 'x':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "or", 2))
+                break;
+              return Intrinsic::x86_mmx_pxor;	 // "86.mmx.pxor"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+4, "ha1msg", 6))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            return Intrinsic::x86_sha1msg1;	 // "86.sha1msg1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::x86_sha1msg2;	 // "86.sha1msg2"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "ore.bitrev", 10))
+          break;
+        return Intrinsic::xcore_bitrev;	 // "core.bitrev"
+      }
+      break;
+    case 12:	 // 11 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+4, "mx.", 3))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "emms", 4))
+            break;
+          return Intrinsic::x86_mmx_femms;	 // "86.mmx.femms"
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "andn", 4))
+            break;
+          return Intrinsic::x86_mmx_pandn;	 // "86.mmx.pandn"
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "clmulqdq", 8))
+          break;
+        return Intrinsic::x86_pclmulqdq;	 // "86.pclmulqdq"
+      case 'r':	 // 6 strings to match.
+        if (NameR[4] != 'd')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'r':	 // 3 strings to match.
+          if (memcmp(NameR.data()+6, "and.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (NameR[11] != '6')
+              break;
+            return Intrinsic::x86_rdrand_16;	 // "86.rdrand.16"
+          case '3':	 // 1 string to match.
+            if (NameR[11] != '2')
+              break;
+            return Intrinsic::x86_rdrand_32;	 // "86.rdrand.32"
+          case '6':	 // 1 string to match.
+            if (NameR[11] != '4')
+              break;
+            return Intrinsic::x86_rdrand_64;	 // "86.rdrand.64"
+          }
+          break;
+        case 's':	 // 3 strings to match.
+          if (memcmp(NameR.data()+6, "eed.", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (NameR[11] != '6')
+              break;
+            return Intrinsic::x86_rdseed_16;	 // "86.rdseed.16"
+          case '3':	 // 1 string to match.
+            if (NameR[11] != '2')
+              break;
+            return Intrinsic::x86_rdseed_32;	 // "86.rdseed.32"
+          case '6':	 // 1 string to match.
+            if (NameR[11] != '4')
+              break;
+            return Intrinsic::x86_rdseed_64;	 // "86.rdseed.64"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(NameR.data()+4, "ha1", 3))
+          break;
+        switch (NameR[7]) {
+        default: break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "exte", 4))
+            break;
+          return Intrinsic::x86_sha1nexte;	 // "86.sha1nexte"
+        case 'r':	 // 1 string to match.
+          if (memcmp(NameR.data()+8, "nds4", 4))
+            break;
+          return Intrinsic::x86_sha1rnds4;	 // "86.sha1rnds4"
+        }
+        break;
+      }
+      break;
+    case 13:	 // 56 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "vx2.permd", 9))
+          break;
+        return Intrinsic::x86_avx2_permd;	 // "86.avx2.permd"
+      case 'm':	 // 18 strings to match.
+        if (memcmp(NameR.data()+4, "mx.p", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, "d.", 2))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padd_b;	 // "86.mmx.padd.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padd_d;	 // "86.mmx.padd.d"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padd_q;	 // "86.mmx.padd.q"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padd_w;	 // "86.mmx.padd.w"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+10, "g.", 2))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_mmx_pavg_b;	 // "86.mmx.pavg.b"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_pavg_w;	 // "86.mmx.pavg.w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 12 strings to match.
+          switch (NameR[9]) {
+          default: break;
+          case 'l':	 // 3 strings to match.
+            if (memcmp(NameR.data()+10, "l.", 2))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psll_d;	 // "86.mmx.psll.d"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psll_q;	 // "86.mmx.psll.q"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psll_w;	 // "86.mmx.psll.w"
+            }
+            break;
+          case 'r':	 // 5 strings to match.
+            switch (NameR[10]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psra_d;	 // "86.mmx.psra.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psra_w;	 // "86.mmx.psra.w"
+              }
+              break;
+            case 'l':	 // 3 strings to match.
+              if (NameR[11] != '.')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psrl_d;	 // "86.mmx.psrl.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psrl_q;	 // "86.mmx.psrl.q"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psrl_w;	 // "86.mmx.psrl.w"
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, "b.", 2))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psub_b;	 // "86.mmx.psub.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psub_d;	 // "86.mmx.psub.d"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psub_q;	 // "86.mmx.psub.q"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psub_w;	 // "86.mmx.psub.w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 19 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(NameR.data()+5, "a256msg", 7))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            return Intrinsic::x86_sha256msg1;	 // "86.sha256msg1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::x86_sha256msg2;	 // "86.sha256msg2"
+          }
+          break;
+        case 's':	 // 17 strings to match.
+          if (NameR[5] != 'e')
+            break;
+          switch (NameR[6]) {
+          default: break;
+          case '.':	 // 13 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, "dd.ss", 5))
+                break;
+              return Intrinsic::x86_sse_add_ss;	 // "86.sse.add.ss"
+            case 'c':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "mp.", 3))
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (NameR[12] != 's')
+                  break;
+                return Intrinsic::x86_sse_cmp_ps;	 // "86.sse.cmp.ps"
+              case 's':	 // 1 string to match.
+                if (NameR[12] != 's')
+                  break;
+                return Intrinsic::x86_sse_cmp_ss;	 // "86.sse.cmp.ss"
+              }
+              break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, "iv.ss", 5))
+                break;
+              return Intrinsic::x86_sse_div_ss;	 // "86.sse.div.ss"
+            case 'm':	 // 5 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "x.", 2))
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (NameR[12] != 's')
+                    break;
+                  return Intrinsic::x86_sse_max_ps;	 // "86.sse.max.ps"
+                case 's':	 // 1 string to match.
+                  if (NameR[12] != 's')
+                    break;
+                  return Intrinsic::x86_sse_max_ss;	 // "86.sse.max.ss"
+                }
+                break;
+              case 'i':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "n.", 2))
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (NameR[12] != 's')
+                    break;
+                  return Intrinsic::x86_sse_min_ps;	 // "86.sse.min.ps"
+                case 's':	 // 1 string to match.
+                  if (NameR[12] != 's')
+                    break;
+                  return Intrinsic::x86_sse_min_ss;	 // "86.sse.min.ss"
+                }
+                break;
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "l.ss", 4))
+                  break;
+                return Intrinsic::x86_sse_mul_ss;	 // "86.sse.mul.ss"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "cp.", 3))
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (NameR[12] != 's')
+                  break;
+                return Intrinsic::x86_sse_rcp_ps;	 // "86.sse.rcp.ps"
+              case 's':	 // 1 string to match.
+                if (NameR[12] != 's')
+                  break;
+                return Intrinsic::x86_sse_rcp_ss;	 // "86.sse.rcp.ss"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'f':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "ence", 4))
+                  break;
+                return Intrinsic::x86_sse_sfence;	 // "86.sse.sfence"
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "b.ss", 4))
+                  break;
+                return Intrinsic::x86_sse_sub_ss;	 // "86.sse.sub.ss"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".pause", 6))
+              break;
+            return Intrinsic::x86_sse2_pause;	 // "86.sse2.pause"
+          case '3':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".mwait", 6))
+              break;
+            return Intrinsic::x86_sse3_mwait;	 // "86.sse3.mwait"
+          case '4':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, "1.dpp", 5))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_sse41_dppd;	 // "86.sse41.dppd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_sse41_dpps;	 // "86.sse41.dpps"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'x':	 // 18 strings to match.
+        if (memcmp(NameR.data()+4, "op.vp", 5))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'c':	 // 5 strings to match.
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ov", 2))
+              break;
+            return Intrinsic::x86_xop_vpcmov;	 // "86.xop.vpcmov"
+          case 'o':	 // 4 strings to match.
+            if (NameR[11] != 'm')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomb;	 // "86.xop.vpcomb"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomd;	 // "86.xop.vpcomd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomq;	 // "86.xop.vpcomq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomw;	 // "86.xop.vpcomw"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, "erm", 3))
+            break;
+          return Intrinsic::x86_xop_vpperm;	 // "86.xop.vpperm"
+        case 'r':	 // 4 strings to match.
+          if (memcmp(NameR.data()+10, "ot", 2))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotb;	 // "86.xop.vprotb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotd;	 // "86.xop.vprotd"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotq;	 // "86.xop.vprotq"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotw;	 // "86.xop.vprotw"
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (NameR[10] != 'h')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshab;	 // "86.xop.vpshab"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshad;	 // "86.xop.vpshad"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshaq;	 // "86.xop.vpshaq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshaw;	 // "86.xop.vpshaw"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlb;	 // "86.xop.vpshlb"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshld;	 // "86.xop.vpshld"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlq;	 // "86.xop.vpshlq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlw;	 // "86.xop.vpshlw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 14:	 // 97 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '8':	 // 96 strings to match.
+        if (memcmp(NameR.data()+1, "6.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case '3':	 // 9 strings to match.
+          if (memcmp(NameR.data()+4, "dnow.p", 6))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'f':	 // 8 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "id", 2))
+                break;
+              return Intrinsic::x86_3dnow_pf2id;	 // "86.3dnow.pf2id"
+            case 'a':	 // 2 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'c':	 // 1 string to match.
+                if (NameR[13] != 'c')
+                  break;
+                return Intrinsic::x86_3dnow_pfacc;	 // "86.3dnow.pfacc"
+              case 'd':	 // 1 string to match.
+                if (NameR[13] != 'd')
+                  break;
+                return Intrinsic::x86_3dnow_pfadd;	 // "86.3dnow.pfadd"
+              }
+              break;
+            case 'm':	 // 3 strings to match.
+              switch (NameR[12]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (NameR[13] != 'x')
+                  break;
+                return Intrinsic::x86_3dnow_pfmax;	 // "86.3dnow.pfmax"
+              case 'i':	 // 1 string to match.
+                if (NameR[13] != 'n')
+                  break;
+                return Intrinsic::x86_3dnow_pfmin;	 // "86.3dnow.pfmin"
+              case 'u':	 // 1 string to match.
+                if (NameR[13] != 'l')
+                  break;
+                return Intrinsic::x86_3dnow_pfmul;	 // "86.3dnow.pfmul"
+              }
+              break;
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "cp", 2))
+                break;
+              return Intrinsic::x86_3dnow_pfrcp;	 // "86.3dnow.pfrcp"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ub", 2))
+                break;
+              return Intrinsic::x86_3dnow_pfsub;	 // "86.3dnow.pfsub"
+            }
+            break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "2fd", 3))
+              break;
+            return Intrinsic::x86_3dnow_pi2fd;	 // "86.3dnow.pi2fd"
+          }
+          break;
+        case 'a':	 // 14 strings to match.
+          if (memcmp(NameR.data()+4, "vx2.p", 5))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'a':	 // 5 strings to match.
+            switch (NameR[10]) {
+            default: break;
+            case 'b':	 // 3 strings to match.
+              if (memcmp(NameR.data()+11, "s.", 2))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_avx2_pabs_b;	 // "86.avx2.pabs.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx2_pabs_d;	 // "86.avx2.pabs.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_avx2_pabs_w;	 // "86.avx2.pabs.w"
+              }
+              break;
+            case 'v':	 // 2 strings to match.
+              if (memcmp(NameR.data()+11, "g.", 2))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_avx2_pavg_b;	 // "86.avx2.pavg.b"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_avx2_pavg_w;	 // "86.avx2.pavg.w"
+              }
+              break;
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+10, "rmps", 4))
+              break;
+            return Intrinsic::x86_avx2_permps;	 // "86.avx2.permps"
+          case 's':	 // 8 strings to match.
+            switch (NameR[10]) {
+            default: break;
+            case 'l':	 // 3 strings to match.
+              if (memcmp(NameR.data()+11, "l.", 2))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx2_psll_d;	 // "86.avx2.psll.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx2_psll_q;	 // "86.avx2.psll.q"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_avx2_psll_w;	 // "86.avx2.psll.w"
+              }
+              break;
+            case 'r':	 // 5 strings to match.
+              switch (NameR[11]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (NameR[12] != '.')
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_psra_d;	 // "86.avx2.psra.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_psra_w;	 // "86.avx2.psra.w"
+                }
+                break;
+              case 'l':	 // 3 strings to match.
+                if (NameR[12] != '.')
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_psrl_d;	 // "86.avx2.psrl.d"
+                case 'q':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_psrl_q;	 // "86.avx2.psrl.q"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_psrl_w;	 // "86.avx2.psrl.w"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'b':	 // 6 strings to match.
+          if (memcmp(NameR.data()+4, "mi.", 3))
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "zhi.", 4))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '3':	 // 1 string to match.
+              if (NameR[13] != '2')
+                break;
+              return Intrinsic::x86_bmi_bzhi_32;	 // "86.bmi.bzhi.32"
+            case '6':	 // 1 string to match.
+              if (NameR[13] != '4')
+                break;
+              return Intrinsic::x86_bmi_bzhi_64;	 // "86.bmi.bzhi.64"
+            }
+            break;
+          case 'p':	 // 4 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "ep.", 3))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case '3':	 // 1 string to match.
+                if (NameR[13] != '2')
+                  break;
+                return Intrinsic::x86_bmi_pdep_32;	 // "86.bmi.pdep.32"
+              case '6':	 // 1 string to match.
+                if (NameR[13] != '4')
+                  break;
+                return Intrinsic::x86_bmi_pdep_64;	 // "86.bmi.pdep.64"
+              }
+              break;
+            case 'e':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "xt.", 3))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case '3':	 // 1 string to match.
+                if (NameR[13] != '2')
+                  break;
+                return Intrinsic::x86_bmi_pext_32;	 // "86.bmi.pext.32"
+              case '6':	 // 1 string to match.
+                if (NameR[13] != '4')
+                  break;
+                return Intrinsic::x86_bmi_pext_64;	 // "86.bmi.pext.64"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 21 strings to match.
+          if (memcmp(NameR.data()+4, "mx.p", 4))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+9, "dds.", 4))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padds_b;	 // "86.mmx.padds.b"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_padds_w;	 // "86.mmx.padds.w"
+            }
+            break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "xtr.w", 5))
+              break;
+            return Intrinsic::x86_mmx_pextr_w;	 // "86.mmx.pextr.w"
+          case 'i':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "nsr.w", 5))
+              break;
+            return Intrinsic::x86_mmx_pinsr_w;	 // "86.mmx.pinsr.w"
+          case 'm':	 // 6 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (NameR[10] != 'x')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".w", 2))
+                  break;
+                return Intrinsic::x86_mmx_pmaxs_w;	 // "86.mmx.pmaxs.w"
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".b", 2))
+                  break;
+                return Intrinsic::x86_mmx_pmaxu_b;	 // "86.mmx.pmaxu.b"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (NameR[10] != 'n')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".w", 2))
+                  break;
+                return Intrinsic::x86_mmx_pmins_w;	 // "86.mmx.pmins.w"
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".b", 2))
+                  break;
+                return Intrinsic::x86_mmx_pminu_b;	 // "86.mmx.pminu.b"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (NameR[10] != 'l')
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".w", 2))
+                  break;
+                return Intrinsic::x86_mmx_pmulh_w;	 // "86.mmx.pmulh.w"
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+12, ".w", 2))
+                  break;
+                return Intrinsic::x86_mmx_pmull_w;	 // "86.mmx.pmull.w"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 11 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, "d.bw", 4))
+                break;
+              return Intrinsic::x86_mmx_psad_bw;	 // "86.mmx.psad.bw"
+            case 'l':	 // 3 strings to match.
+              if (memcmp(NameR.data()+10, "li.", 3))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_mmx_pslli_d;	 // "86.mmx.pslli.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_mmx_pslli_q;	 // "86.mmx.pslli.q"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_mmx_pslli_w;	 // "86.mmx.pslli.w"
+              }
+              break;
+            case 'r':	 // 5 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+11, "i.", 2))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_psrai_d;	 // "86.mmx.psrai.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_psrai_w;	 // "86.mmx.psrai.w"
+                }
+                break;
+              case 'l':	 // 3 strings to match.
+                if (memcmp(NameR.data()+11, "i.", 2))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_psrli_d;	 // "86.mmx.psrli.d"
+                case 'q':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_psrli_q;	 // "86.mmx.psrli.q"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_psrli_w;	 // "86.mmx.psrli.w"
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+10, "bs.", 3))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psubs_b;	 // "86.mmx.psubs.b"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psubs_w;	 // "86.mmx.psubs.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          if (NameR[4] != 'd')
+            break;
+          switch (NameR[5]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(NameR.data()+6, "sbase.", 6))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '3':	 // 1 string to match.
+              if (NameR[13] != '2')
+                break;
+              return Intrinsic::x86_rdfsbase_32;	 // "86.rdfsbase.32"
+            case '6':	 // 1 string to match.
+              if (NameR[13] != '4')
+                break;
+              return Intrinsic::x86_rdfsbase_64;	 // "86.rdfsbase.64"
+            }
+            break;
+          case 'g':	 // 2 strings to match.
+            if (memcmp(NameR.data()+6, "sbase.", 6))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '3':	 // 1 string to match.
+              if (NameR[13] != '2')
+                break;
+              return Intrinsic::x86_rdgsbase_32;	 // "86.rdgsbase.32"
+            case '6':	 // 1 string to match.
+              if (NameR[13] != '4')
+                break;
+              return Intrinsic::x86_rdgsbase_64;	 // "86.rdgsbase.64"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 30 strings to match.
+          switch (NameR[4]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(NameR.data()+5, "a256rnds2", 9))
+              break;
+            return Intrinsic::x86_sha256rnds2;	 // "86.sha256rnds2"
+          case 's':	 // 29 strings to match.
+            if (NameR[5] != 'e')
+              break;
+            switch (NameR[6]) {
+            default: break;
+            case '.':	 // 5 strings to match.
+              switch (NameR[7]) {
+              default: break;
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+8, "dmxcsr", 6))
+                  break;
+                return Intrinsic::x86_sse_ldmxcsr;	 // "86.sse.ldmxcsr"
+              case 'p':	 // 1 string to match.
+                if (memcmp(NameR.data()+8, "shuf.w", 6))
+                  break;
+                return Intrinsic::x86_sse_pshuf_w;	 // "86.sse.pshuf.w"
+              case 's':	 // 3 strings to match.
+                switch (NameR[8]) {
+                default: break;
+                case 'q':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+9, "rt.", 3))
+                    break;
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'p':	 // 1 string to match.
+                    if (NameR[13] != 's')
+                      break;
+                    return Intrinsic::x86_sse_sqrt_ps;	 // "86.sse.sqrt.ps"
+                  case 's':	 // 1 string to match.
+                    if (NameR[13] != 's')
+                      break;
+                    return Intrinsic::x86_sse_sqrt_ss;	 // "86.sse.sqrt.ss"
+                  }
+                  break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+9, "mxcsr", 5))
+                    break;
+                  return Intrinsic::x86_sse_stmxcsr;	 // "86.sse.stmxcsr"
+                }
+                break;
+              }
+              break;
+            case '2':	 // 22 strings to match.
+              if (NameR[7] != '.')
+                break;
+              switch (NameR[8]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "dd.sd", 5))
+                  break;
+                return Intrinsic::x86_sse2_add_sd;	 // "86.sse2.add.sd"
+              case 'c':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "mp.", 3))
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (NameR[13] != 'd')
+                    break;
+                  return Intrinsic::x86_sse2_cmp_pd;	 // "86.sse2.cmp.pd"
+                case 's':	 // 1 string to match.
+                  if (NameR[13] != 'd')
+                    break;
+                  return Intrinsic::x86_sse2_cmp_sd;	 // "86.sse2.cmp.sd"
+                }
+                break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "iv.sd", 5))
+                  break;
+                return Intrinsic::x86_sse2_div_sd;	 // "86.sse2.div.sd"
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "fence", 5))
+                  break;
+                return Intrinsic::x86_sse2_lfence;	 // "86.sse2.lfence"
+              case 'm':	 // 6 strings to match.
+                switch (NameR[9]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "x.", 2))
+                    break;
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'p':	 // 1 string to match.
+                    if (NameR[13] != 'd')
+                      break;
+                    return Intrinsic::x86_sse2_max_pd;	 // "86.sse2.max.pd"
+                  case 's':	 // 1 string to match.
+                    if (NameR[13] != 'd')
+                      break;
+                    return Intrinsic::x86_sse2_max_sd;	 // "86.sse2.max.sd"
+                  }
+                  break;
+                case 'f':	 // 1 string to match.
+                  if (memcmp(NameR.data()+10, "ence", 4))
+                    break;
+                  return Intrinsic::x86_sse2_mfence;	 // "86.sse2.mfence"
+                case 'i':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "n.", 2))
+                    break;
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'p':	 // 1 string to match.
+                    if (NameR[13] != 'd')
+                      break;
+                    return Intrinsic::x86_sse2_min_pd;	 // "86.sse2.min.pd"
+                  case 's':	 // 1 string to match.
+                    if (NameR[13] != 'd')
+                      break;
+                    return Intrinsic::x86_sse2_min_sd;	 // "86.sse2.min.sd"
+                  }
+                  break;
+                case 'u':	 // 1 string to match.
+                  if (memcmp(NameR.data()+10, "l.sd", 4))
+                    break;
+                  return Intrinsic::x86_sse2_mul_sd;	 // "86.sse2.mul.sd"
+                }
+                break;
+              case 'p':	 // 10 strings to match.
+                switch (NameR[9]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "vg.", 3))
+                    break;
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_pavg_b;	 // "86.sse2.pavg.b"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_pavg_w;	 // "86.sse2.pavg.w"
+                  }
+                  break;
+                case 's':	 // 8 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'l':	 // 3 strings to match.
+                    if (memcmp(NameR.data()+11, "l.", 2))
+                      break;
+                    switch (NameR[13]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_sse2_psll_d;	 // "86.sse2.psll.d"
+                    case 'q':	 // 1 string to match.
+                      return Intrinsic::x86_sse2_psll_q;	 // "86.sse2.psll.q"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_sse2_psll_w;	 // "86.sse2.psll.w"
+                    }
+                    break;
+                  case 'r':	 // 5 strings to match.
+                    switch (NameR[11]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      if (NameR[12] != '.')
+                        break;
+                      switch (NameR[13]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psra_d;	 // "86.sse2.psra.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psra_w;	 // "86.sse2.psra.w"
+                      }
+                      break;
+                    case 'l':	 // 3 strings to match.
+                      if (NameR[12] != '.')
+                        break;
+                      switch (NameR[13]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psrl_d;	 // "86.sse2.psrl.d"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psrl_q;	 // "86.sse2.psrl.q"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psrl_w;	 // "86.sse2.psrl.w"
+                      }
+                      break;
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "ub.sd", 5))
+                  break;
+                return Intrinsic::x86_sse2_sub_sd;	 // "86.sse2.sub.sd"
+              }
+              break;
+            case '3':	 // 1 string to match.
+              if (memcmp(NameR.data()+7, ".ldu.dq", 7))
+                break;
+              return Intrinsic::x86_sse3_ldu_dq;	 // "86.sse3.ldu.dq"
+            case '4':	 // 1 string to match.
+              if (memcmp(NameR.data()+7, "a.extrq", 7))
+                break;
+              return Intrinsic::x86_sse4a_extrq;	 // "86.sse4a.extrq"
+            }
+            break;
+          }
+          break;
+        case 'w':	 // 4 strings to match.
+          if (NameR[4] != 'r')
+            break;
+          switch (NameR[5]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(NameR.data()+6, "sbase.", 6))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '3':	 // 1 string to match.
+              if (NameR[13] != '2')
+                break;
+              return Intrinsic::x86_wrfsbase_32;	 // "86.wrfsbase.32"
+            case '6':	 // 1 string to match.
+              if (NameR[13] != '4')
+                break;
+              return Intrinsic::x86_wrfsbase_64;	 // "86.wrfsbase.64"
+            }
+            break;
+          case 'g':	 // 2 strings to match.
+            if (memcmp(NameR.data()+6, "sbase.", 6))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '3':	 // 1 string to match.
+              if (NameR[13] != '2')
+                break;
+              return Intrinsic::x86_wrgsbase_32;	 // "86.wrgsbase.32"
+            case '6':	 // 1 string to match.
+              if (NameR[13] != '4')
+                break;
+              return Intrinsic::x86_wrgsbase_64;	 // "86.wrgsbase.64"
+            }
+            break;
+          }
+          break;
+        case 'x':	 // 8 strings to match.
+          if (memcmp(NameR.data()+4, "op.vp", 5))
+            break;
+          switch (NameR[9]) {
+          default: break;
+          case 'c':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, "omu", 3))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomub;	 // "86.xop.vpcomub"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomud;	 // "86.xop.vpcomud"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomuq;	 // "86.xop.vpcomuq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomuw;	 // "86.xop.vpcomuw"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (memcmp(NameR.data()+10, "ot", 2))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[13] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotbi;	 // "86.xop.vprotbi"
+            case 'd':	 // 1 string to match.
+              if (NameR[13] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotdi;	 // "86.xop.vprotdi"
+            case 'q':	 // 1 string to match.
+              if (NameR[13] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotqi;	 // "86.xop.vprotqi"
+            case 'w':	 // 1 string to match.
+              if (NameR[13] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotwi;	 // "86.xop.vprotwi"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "ore.waitevent", 13))
+          break;
+        return Intrinsic::xcore_waitevent;	 // "core.waitevent"
+      }
+      break;
+    case 15:	 // 145 strings to match.
+      switch (NameR[0]) {
+      default: break;
+      case '8':	 // 144 strings to match.
+        if (memcmp(NameR.data()+1, "6.", 2))
+          break;
+        switch (NameR[3]) {
+        default: break;
+        case '3':	 // 3 strings to match.
+          if (memcmp(NameR.data()+4, "dnow", 4))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case '.':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "pfsubr", 6))
+              break;
+            return Intrinsic::x86_3dnow_pfsubr;	 // "86.3dnow.pfsubr"
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+9, ".p", 2))
+              break;
+            switch (NameR[11]) {
+            default: break;
+            case 'f':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "2iw", 3))
+                break;
+              return Intrinsic::x86_3dnowa_pf2iw;	 // "86.3dnowa.pf2iw"
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "2fw", 3))
+                break;
+              return Intrinsic::x86_3dnowa_pi2fw;	 // "86.3dnowa.pi2fw"
+            }
+            break;
+          }
+          break;
+        case 'a':	 // 49 strings to match.
+          switch (NameR[4]) {
+          default: break;
+          case 'e':	 // 3 strings to match.
+            if (memcmp(NameR.data()+5, "sni.aes", 7))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "ec", 2))
+                break;
+              return Intrinsic::x86_aesni_aesdec;	 // "86.aesni.aesdec"
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "nc", 2))
+                break;
+              return Intrinsic::x86_aesni_aesenc;	 // "86.aesni.aesenc"
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "mc", 2))
+                break;
+              return Intrinsic::x86_aesni_aesimc;	 // "86.aesni.aesimc"
+            }
+            break;
+          case 'v':	 // 46 strings to match.
+            if (NameR[5] != 'x')
+              break;
+            switch (NameR[6]) {
+            default: break;
+            case '.':	 // 1 string to match.
+              if (memcmp(NameR.data()+7, "vzeroall", 8))
+                break;
+              return Intrinsic::x86_avx_vzeroall;	 // "86.avx.vzeroall"
+            case '2':	 // 44 strings to match.
+              if (NameR[7] != '.')
+                break;
+              switch (NameR[8]) {
+              default: break;
+              case 'm':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "psadbw", 6))
+                  break;
+                return Intrinsic::x86_avx2_mpsadbw;	 // "86.avx2.mpsadbw"
+              case 'p':	 // 43 strings to match.
+                switch (NameR[9]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "dds.", 4))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::x86_avx2_padds_b;	 // "86.avx2.padds.b"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::x86_avx2_padds_w;	 // "86.avx2.padds.w"
+                  }
+                  break;
+                case 'b':	 // 1 string to match.
+                  if (memcmp(NameR.data()+10, "lendw", 5))
+                    break;
+                  return Intrinsic::x86_avx2_pblendw;	 // "86.avx2.pblendw"
+                case 'h':	 // 4 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+11, "dd.", 3))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_phadd_d;	 // "86.avx2.phadd.d"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_phadd_w;	 // "86.avx2.phadd.w"
+                    }
+                    break;
+                  case 's':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+11, "ub.", 3))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_phsub_d;	 // "86.avx2.phsub.d"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_phsub_w;	 // "86.avx2.phsub.w"
+                    }
+                    break;
+                  }
+                  break;
+                case 'm':	 // 14 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'a':	 // 6 strings to match.
+                    if (NameR[11] != 'x')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case 's':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxs_b;	 // "86.avx2.pmaxs.b"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxs_d;	 // "86.avx2.pmaxs.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxs_w;	 // "86.avx2.pmaxs.w"
+                      }
+                      break;
+                    case 'u':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxu_b;	 // "86.avx2.pmaxu.b"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxu_d;	 // "86.avx2.pmaxu.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmaxu_w;	 // "86.avx2.pmaxu.w"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'i':	 // 6 strings to match.
+                    if (NameR[11] != 'n')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case 's':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmins_b;	 // "86.avx2.pmins.b"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmins_d;	 // "86.avx2.pmins.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pmins_w;	 // "86.avx2.pmins.w"
+                      }
+                      break;
+                    case 'u':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pminu_b;	 // "86.avx2.pminu.b"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pminu_d;	 // "86.avx2.pminu.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pminu_w;	 // "86.avx2.pminu.w"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'u':	 // 2 strings to match.
+                    if (NameR[11] != 'l')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case '.':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, "dq", 2))
+                        break;
+                      return Intrinsic::x86_avx2_pmul_dq;	 // "86.avx2.pmul.dq"
+                    case 'h':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, ".w", 2))
+                        break;
+                      return Intrinsic::x86_avx2_pmulh_w;	 // "86.avx2.pmulh.w"
+                    }
+                    break;
+                  }
+                  break;
+                case 's':	 // 22 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'a':	 // 1 string to match.
+                    if (memcmp(NameR.data()+11, "d.bw", 4))
+                      break;
+                    return Intrinsic::x86_avx2_psad_bw;	 // "86.avx2.psad.bw"
+                  case 'h':	 // 1 string to match.
+                    if (memcmp(NameR.data()+11, "uf.b", 4))
+                      break;
+                    return Intrinsic::x86_avx2_pshuf_b;	 // "86.avx2.pshuf.b"
+                  case 'i':	 // 3 strings to match.
+                    if (memcmp(NameR.data()+11, "gn.", 3))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'b':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_psign_b;	 // "86.avx2.psign.b"
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_psign_d;	 // "86.avx2.psign.d"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_psign_w;	 // "86.avx2.psign.w"
+                    }
+                    break;
+                  case 'l':	 // 6 strings to match.
+                    if (NameR[11] != 'l')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case '.':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, "dq", 2))
+                        break;
+                      return Intrinsic::x86_avx2_psll_dq;	 // "86.avx2.psll.dq"
+                    case 'i':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pslli_d;	 // "86.avx2.pslli.d"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pslli_q;	 // "86.avx2.pslli.q"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_pslli_w;	 // "86.avx2.pslli.w"
+                      }
+                      break;
+                    case 'v':	 // 2 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_psllv_d;	 // "86.avx2.psllv.d"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_avx2_psllv_q;	 // "86.avx2.psllv.q"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'r':	 // 9 strings to match.
+                    switch (NameR[11]) {
+                    default: break;
+                    case 'a':	 // 3 strings to match.
+                      switch (NameR[12]) {
+                      default: break;
+                      case 'i':	 // 2 strings to match.
+                        if (NameR[13] != '.')
+                          break;
+                        switch (NameR[14]) {
+                        default: break;
+                        case 'd':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrai_d;	 // "86.avx2.psrai.d"
+                        case 'w':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrai_w;	 // "86.avx2.psrai.w"
+                        }
+                        break;
+                      case 'v':	 // 1 string to match.
+                        if (memcmp(NameR.data()+13, ".d", 2))
+                          break;
+                        return Intrinsic::x86_avx2_psrav_d;	 // "86.avx2.psrav.d"
+                      }
+                      break;
+                    case 'l':	 // 6 strings to match.
+                      switch (NameR[12]) {
+                      default: break;
+                      case '.':	 // 1 string to match.
+                        if (memcmp(NameR.data()+13, "dq", 2))
+                          break;
+                        return Intrinsic::x86_avx2_psrl_dq;	 // "86.avx2.psrl.dq"
+                      case 'i':	 // 3 strings to match.
+                        if (NameR[13] != '.')
+                          break;
+                        switch (NameR[14]) {
+                        default: break;
+                        case 'd':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrli_d;	 // "86.avx2.psrli.d"
+                        case 'q':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrli_q;	 // "86.avx2.psrli.q"
+                        case 'w':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrli_w;	 // "86.avx2.psrli.w"
+                        }
+                        break;
+                      case 'v':	 // 2 strings to match.
+                        if (NameR[13] != '.')
+                          break;
+                        switch (NameR[14]) {
+                        default: break;
+                        case 'd':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrlv_d;	 // "86.avx2.psrlv.d"
+                        case 'q':	 // 1 string to match.
+                          return Intrinsic::x86_avx2_psrlv_q;	 // "86.avx2.psrlv.q"
+                        }
+                        break;
+                      }
+                      break;
+                    }
+                    break;
+                  case 'u':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+11, "bs.", 3))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'b':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_psubs_b;	 // "86.avx2.psubs.b"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_psubs_w;	 // "86.avx2.psubs.w"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+7, "12.kor.w", 8))
+                break;
+              return Intrinsic::x86_avx512_kor_w;	 // "86.avx512.kor.w"
+            }
+            break;
+          }
+          break;
+        case 'b':	 // 2 strings to match.
+          if (memcmp(NameR.data()+4, "mi.bextr.", 9))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case '3':	 // 1 string to match.
+            if (NameR[14] != '2')
+              break;
+            return Intrinsic::x86_bmi_bextr_32;	 // "86.bmi.bextr.32"
+          case '6':	 // 1 string to match.
+            if (NameR[14] != '4')
+              break;
+            return Intrinsic::x86_bmi_bextr_64;	 // "86.bmi.bextr.64"
+          }
+          break;
+        case 'm':	 // 19 strings to match.
+          if (memcmp(NameR.data()+4, "mx.", 3))
+            break;
+          switch (NameR[7]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "skmovq", 6))
+                break;
+              return Intrinsic::x86_mmx_maskmovq;	 // "86.mmx.maskmovq"
+            case 'o':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "vnt.dq", 6))
+                break;
+              return Intrinsic::x86_mmx_movnt_dq;	 // "86.mmx.movnt.dq"
+            }
+            break;
+          case 'p':	 // 17 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 5 strings to match.
+              switch (NameR[9]) {
+              default: break;
+              case 'c':	 // 3 strings to match.
+                if (NameR[10] != 'k')
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 's':	 // 2 strings to match.
+                  if (NameR[12] != 's')
+                    break;
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[14] != 'w')
+                      break;
+                    return Intrinsic::x86_mmx_packssdw;	 // "86.mmx.packssdw"
+                  case 'w':	 // 1 string to match.
+                    if (NameR[14] != 'b')
+                      break;
+                    return Intrinsic::x86_mmx_packsswb;	 // "86.mmx.packsswb"
+                  }
+                  break;
+                case 'u':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "swb", 3))
+                    break;
+                  return Intrinsic::x86_mmx_packuswb;	 // "86.mmx.packuswb"
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "dus.", 4))
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_paddus_b;	 // "86.mmx.paddus.b"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_paddus_w;	 // "86.mmx.paddus.w"
+                }
+                break;
+              }
+              break;
+            case 'c':	 // 6 strings to match.
+              if (memcmp(NameR.data()+9, "mp", 2))
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'e':	 // 3 strings to match.
+                if (memcmp(NameR.data()+12, "q.", 2))
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpeq_b;	 // "86.mmx.pcmpeq.b"
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpeq_d;	 // "86.mmx.pcmpeq.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpeq_w;	 // "86.mmx.pcmpeq.w"
+                }
+                break;
+              case 'g':	 // 3 strings to match.
+                if (memcmp(NameR.data()+12, "t.", 2))
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpgt_b;	 // "86.mmx.pcmpgt.b"
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpgt_d;	 // "86.mmx.pcmpgt.d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_mmx_pcmpgt_w;	 // "86.mmx.pcmpgt.w"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 4 strings to match.
+              switch (NameR[9]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "dd.wd", 5))
+                  break;
+                return Intrinsic::x86_mmx_pmadd_wd;	 // "86.mmx.pmadd.wd"
+              case 'o':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "vmskb", 5))
+                  break;
+                return Intrinsic::x86_mmx_pmovmskb;	 // "86.mmx.pmovmskb"
+              case 'u':	 // 2 strings to match.
+                if (NameR[10] != 'l')
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "u.w", 3))
+                    break;
+                  return Intrinsic::x86_mmx_pmulhu_w;	 // "86.mmx.pmulhu.w"
+                case 'u':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, ".dq", 3))
+                    break;
+                  return Intrinsic::x86_mmx_pmulu_dq;	 // "86.mmx.pmulu.dq"
+                }
+                break;
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "ubus.", 5))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psubus_b;	 // "86.mmx.psubus.b"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_mmx_psubus_w;	 // "86.mmx.psubus.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 55 strings to match.
+          if (NameR[4] != 's')
+            break;
+          switch (NameR[5]) {
+          default: break;
+          case 'e':	 // 52 strings to match.
+            switch (NameR[6]) {
+            default: break;
+            case '.':	 // 8 strings to match.
+              switch (NameR[7]) {
+              default: break;
+              case 'c':	 // 6 strings to match.
+                if (memcmp(NameR.data()+8, "vt", 2))
+                  break;
+                switch (NameR[10]) {
+                default: break;
+                case 'p':	 // 4 strings to match.
+                  switch (NameR[11]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "2pi", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvtpd2pi;	 // "86.sse.cvtpd2pi"
+                  case 'i':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+12, "2p", 2))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_sse_cvtpi2pd;	 // "86.sse.cvtpi2pd"
+                    case 's':	 // 1 string to match.
+                      return Intrinsic::x86_sse_cvtpi2ps;	 // "86.sse.cvtpi2ps"
+                    }
+                    break;
+                  case 's':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "2pi", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvtps2pi;	 // "86.sse.cvtps2pi"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  switch (NameR[11]) {
+                  default: break;
+                  case 'i':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "2ss", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvtsi2ss;	 // "86.sse.cvtsi2ss"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "2si", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvtss2si;	 // "86.sse.cvtss2si"
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 2 strings to match.
+                if (memcmp(NameR.data()+8, "sqrt.", 5))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (NameR[14] != 's')
+                    break;
+                  return Intrinsic::x86_sse_rsqrt_ps;	 // "86.sse.rsqrt.ps"
+                case 's':	 // 1 string to match.
+                  if (NameR[14] != 's')
+                    break;
+                  return Intrinsic::x86_sse_rsqrt_ss;	 // "86.sse.rsqrt.ss"
+                }
+                break;
+              }
+              break;
+            case '2':	 // 24 strings to match.
+              if (NameR[7] != '.')
+                break;
+              switch (NameR[8]) {
+              default: break;
+              case 'c':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "lflush", 6))
+                  break;
+                return Intrinsic::x86_sse2_clflush;	 // "86.sse2.clflush"
+              case 'p':	 // 21 strings to match.
+                switch (NameR[9]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "dds.", 4))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_padds_b;	 // "86.sse2.padds.b"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_padds_w;	 // "86.sse2.padds.w"
+                  }
+                  break;
+                case 'm':	 // 5 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    if (NameR[11] != 'x')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case 's':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, ".w", 2))
+                        break;
+                      return Intrinsic::x86_sse2_pmaxs_w;	 // "86.sse2.pmaxs.w"
+                    case 'u':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, ".b", 2))
+                        break;
+                      return Intrinsic::x86_sse2_pmaxu_b;	 // "86.sse2.pmaxu.b"
+                    }
+                    break;
+                  case 'i':	 // 2 strings to match.
+                    if (NameR[11] != 'n')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case 's':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, ".w", 2))
+                        break;
+                      return Intrinsic::x86_sse2_pmins_w;	 // "86.sse2.pmins.w"
+                    case 'u':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, ".b", 2))
+                        break;
+                      return Intrinsic::x86_sse2_pminu_b;	 // "86.sse2.pminu.b"
+                    }
+                    break;
+                  case 'u':	 // 1 string to match.
+                    if (memcmp(NameR.data()+11, "lh.w", 4))
+                      break;
+                    return Intrinsic::x86_sse2_pmulh_w;	 // "86.sse2.pmulh.w"
+                  }
+                  break;
+                case 's':	 // 14 strings to match.
+                  switch (NameR[10]) {
+                  default: break;
+                  case 'a':	 // 1 string to match.
+                    if (memcmp(NameR.data()+11, "d.bw", 4))
+                      break;
+                    return Intrinsic::x86_sse2_psad_bw;	 // "86.sse2.psad.bw"
+                  case 'h':	 // 1 string to match.
+                    if (memcmp(NameR.data()+11, "uf.d", 4))
+                      break;
+                    return Intrinsic::x86_sse2_pshuf_d;	 // "86.sse2.pshuf.d"
+                  case 'l':	 // 4 strings to match.
+                    if (NameR[11] != 'l')
+                      break;
+                    switch (NameR[12]) {
+                    default: break;
+                    case '.':	 // 1 string to match.
+                      if (memcmp(NameR.data()+13, "dq", 2))
+                        break;
+                      return Intrinsic::x86_sse2_psll_dq;	 // "86.sse2.psll.dq"
+                    case 'i':	 // 3 strings to match.
+                      if (NameR[13] != '.')
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_pslli_d;	 // "86.sse2.pslli.d"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_pslli_q;	 // "86.sse2.pslli.q"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_pslli_w;	 // "86.sse2.pslli.w"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'r':	 // 6 strings to match.
+                    switch (NameR[11]) {
+                    default: break;
+                    case 'a':	 // 2 strings to match.
+                      if (memcmp(NameR.data()+12, "i.", 2))
+                        break;
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psrai_d;	 // "86.sse2.psrai.d"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse2_psrai_w;	 // "86.sse2.psrai.w"
+                      }
+                      break;
+                    case 'l':	 // 4 strings to match.
+                      switch (NameR[12]) {
+                      default: break;
+                      case '.':	 // 1 string to match.
+                        if (memcmp(NameR.data()+13, "dq", 2))
+                          break;
+                        return Intrinsic::x86_sse2_psrl_dq;	 // "86.sse2.psrl.dq"
+                      case 'i':	 // 3 strings to match.
+                        if (NameR[13] != '.')
+                          break;
+                        switch (NameR[14]) {
+                        default: break;
+                        case 'd':	 // 1 string to match.
+                          return Intrinsic::x86_sse2_psrli_d;	 // "86.sse2.psrli.d"
+                        case 'q':	 // 1 string to match.
+                          return Intrinsic::x86_sse2_psrli_q;	 // "86.sse2.psrli.q"
+                        case 'w':	 // 1 string to match.
+                          return Intrinsic::x86_sse2_psrli_w;	 // "86.sse2.psrli.w"
+                        }
+                        break;
+                      }
+                      break;
+                    }
+                    break;
+                  case 'u':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+11, "bs.", 3))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'b':	 // 1 string to match.
+                      return Intrinsic::x86_sse2_psubs_b;	 // "86.sse2.psubs.b"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_sse2_psubs_w;	 // "86.sse2.psubs.w"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "qrt.", 4))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'p':	 // 1 string to match.
+                  if (NameR[14] != 'd')
+                    break;
+                  return Intrinsic::x86_sse2_sqrt_pd;	 // "86.sse2.sqrt.pd"
+                case 's':	 // 1 string to match.
+                  if (NameR[14] != 'd')
+                    break;
+                  return Intrinsic::x86_sse2_sqrt_sd;	 // "86.sse2.sqrt.sd"
+                }
+                break;
+              }
+              break;
+            case '3':	 // 5 strings to match.
+              if (NameR[7] != '.')
+                break;
+              switch (NameR[8]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (NameR[9]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "dd.p", 4))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_sse3_hadd_pd;	 // "86.sse3.hadd.pd"
+                  case 's':	 // 1 string to match.
+                    return Intrinsic::x86_sse3_hadd_ps;	 // "86.sse3.hadd.ps"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+10, "ub.p", 4))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_sse3_hsub_pd;	 // "86.sse3.hsub.pd"
+                  case 's':	 // 1 string to match.
+                    return Intrinsic::x86_sse3_hsub_ps;	 // "86.sse3.hsub.ps"
+                  }
+                  break;
+                }
+                break;
+              case 'm':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "onitor", 6))
+                  break;
+                return Intrinsic::x86_sse3_monitor;	 // "86.sse3.monitor"
+              }
+              break;
+            case '4':	 // 15 strings to match.
+              switch (NameR[7]) {
+              default: break;
+              case '1':	 // 14 strings to match.
+                if (memcmp(NameR.data()+8, ".p", 2))
+                  break;
+                switch (NameR[10]) {
+                default: break;
+                case 'e':	 // 3 strings to match.
+                  if (memcmp(NameR.data()+11, "xtr", 3))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_pextrb;	 // "86.sse41.pextrb"
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_pextrd;	 // "86.sse41.pextrd"
+                  case 'q':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_pextrq;	 // "86.sse41.pextrq"
+                  }
+                  break;
+                case 'm':	 // 9 strings to match.
+                  switch (NameR[11]) {
+                  default: break;
+                  case 'a':	 // 4 strings to match.
+                    if (NameR[12] != 'x')
+                      break;
+                    switch (NameR[13]) {
+                    default: break;
+                    case 's':	 // 2 strings to match.
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmaxsb;	 // "86.sse41.pmaxsb"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmaxsd;	 // "86.sse41.pmaxsd"
+                      }
+                      break;
+                    case 'u':	 // 2 strings to match.
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmaxud;	 // "86.sse41.pmaxud"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmaxuw;	 // "86.sse41.pmaxuw"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'i':	 // 4 strings to match.
+                    if (NameR[12] != 'n')
+                      break;
+                    switch (NameR[13]) {
+                    default: break;
+                    case 's':	 // 2 strings to match.
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'b':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pminsb;	 // "86.sse41.pminsb"
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pminsd;	 // "86.sse41.pminsd"
+                      }
+                      break;
+                    case 'u':	 // 2 strings to match.
+                      switch (NameR[14]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pminud;	 // "86.sse41.pminud"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pminuw;	 // "86.sse41.pminuw"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'u':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "ldq", 3))
+                      break;
+                    return Intrinsic::x86_sse41_pmuldq;	 // "86.sse41.pmuldq"
+                  }
+                  break;
+                case 't':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+11, "est", 3))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_ptestc;	 // "86.sse41.ptestc"
+                  case 'z':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_ptestz;	 // "86.sse41.ptestz"
+                  }
+                  break;
+                }
+                break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+8, ".extrqi", 7))
+                  break;
+                return Intrinsic::x86_sse4a_extrqi;	 // "86.sse4a.extrqi"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(NameR.data()+6, "e3.pabs.", 8))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_ssse3_pabs_b;	 // "86.ssse3.pabs.b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_ssse3_pabs_d;	 // "86.ssse3.pabs.d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_ssse3_pabs_w;	 // "86.ssse3.pabs.w"
+            }
+            break;
+          }
+          break;
+        case 'x':	 // 16 strings to match.
+          if (memcmp(NameR.data()+4, "op.v", 4))
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'f':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "rcz.", 4))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'p':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_xop_vfrcz_pd;	 // "86.xop.vfrcz.pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_xop_vfrcz_ps;	 // "86.xop.vfrcz.ps"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_xop_vfrcz_sd;	 // "86.xop.vfrcz.sd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_xop_vfrcz_ss;	 // "86.xop.vfrcz.ss"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 12 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'h':	 // 9 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'a':	 // 6 strings to match.
+                if (memcmp(NameR.data()+11, "dd", 2))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'b':	 // 3 strings to match.
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_xop_vphaddbd;	 // "86.xop.vphaddbd"
+                  case 'q':	 // 1 string to match.
+                    return Intrinsic::x86_xop_vphaddbq;	 // "86.xop.vphaddbq"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::x86_xop_vphaddbw;	 // "86.xop.vphaddbw"
+                  }
+                  break;
+                case 'd':	 // 1 string to match.
+                  if (NameR[14] != 'q')
+                    break;
+                  return Intrinsic::x86_xop_vphadddq;	 // "86.xop.vphadddq"
+                case 'w':	 // 2 strings to match.
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_xop_vphaddwd;	 // "86.xop.vphaddwd"
+                  case 'q':	 // 1 string to match.
+                    return Intrinsic::x86_xop_vphaddwq;	 // "86.xop.vphaddwq"
+                  }
+                  break;
+                }
+                break;
+              case 's':	 // 3 strings to match.
+                if (memcmp(NameR.data()+11, "ub", 2))
+                  break;
+                switch (NameR[13]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  if (NameR[14] != 'w')
+                    break;
+                  return Intrinsic::x86_xop_vphsubbw;	 // "86.xop.vphsubbw"
+                case 'd':	 // 1 string to match.
+                  if (NameR[14] != 'q')
+                    break;
+                  return Intrinsic::x86_xop_vphsubdq;	 // "86.xop.vphsubdq"
+                case 'w':	 // 1 string to match.
+                  if (NameR[14] != 'd')
+                    break;
+                  return Intrinsic::x86_xop_vphsubwd;	 // "86.xop.vphsubwd"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 3 strings to match.
+              if (memcmp(NameR.data()+10, "acs", 3))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (NameR[14] != 'd')
+                  break;
+                return Intrinsic::x86_xop_vpmacsdd;	 // "86.xop.vpmacsdd"
+              case 'w':	 // 2 strings to match.
+                switch (NameR[14]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacswd;	 // "86.xop.vpmacswd"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacsww;	 // "86.xop.vpmacsww"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(NameR.data()+1, "ore.checkevent", 14))
+          break;
+        return Intrinsic::xcore_checkevent;	 // "core.checkevent"
+      }
+      break;
+    case 16:	 // 117 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case '3':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "dnow", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case '.':	 // 6 strings to match.
+          if (NameR[9] != 'p')
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "vgusb", 5))
+              break;
+            return Intrinsic::x86_3dnow_pavgusb;	 // "86.3dnow.pavgusb"
+          case 'f':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'c':	 // 3 strings to match.
+              if (memcmp(NameR.data()+12, "mp", 2))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (NameR[15] != 'q')
+                  break;
+                return Intrinsic::x86_3dnow_pfcmpeq;	 // "86.3dnow.pfcmpeq"
+              case 'g':	 // 2 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  return Intrinsic::x86_3dnow_pfcmpge;	 // "86.3dnow.pfcmpge"
+                case 't':	 // 1 string to match.
+                  return Intrinsic::x86_3dnow_pfcmpgt;	 // "86.3dnow.pfcmpgt"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "sqrt", 4))
+                break;
+              return Intrinsic::x86_3dnow_pfrsqrt;	 // "86.3dnow.pfrsqrt"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ulhrw", 5))
+              break;
+            return Intrinsic::x86_3dnow_pmulhrw;	 // "86.3dnow.pmulhrw"
+          }
+          break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, ".p", 2))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "nacc", 4))
+              break;
+            return Intrinsic::x86_3dnowa_pfnacc;	 // "86.3dnowa.pfnacc"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "wapd", 4))
+              break;
+            return Intrinsic::x86_3dnowa_pswapd;	 // "86.3dnowa.pswapd"
+          }
+          break;
+        }
+        break;
+      case 'a':	 // 36 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 5 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "p.ps.256", 8))
+              break;
+            return Intrinsic::x86_avx_dp_ps_256;	 // "86.avx.dp.ps.256"
+          case 'v':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "test", 4))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'c':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, ".p", 2))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx_vtestc_pd;	 // "86.avx.vtestc.pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx_vtestc_ps;	 // "86.avx.vtestc.ps"
+              }
+              break;
+            case 'z':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, ".p", 2))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx_vtestz_pd;	 // "86.avx.vtestz.pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx_vtestz_ps;	 // "86.avx.vtestz.ps"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '2':	 // 28 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "ovntdqa", 7))
+              break;
+            return Intrinsic::x86_avx2_movntdqa;	 // "86.avx2.movntdqa"
+          case 'p':	 // 27 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'a':	 // 6 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'c':	 // 4 strings to match.
+                if (NameR[11] != 'k')
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 's':	 // 2 strings to match.
+                  if (NameR[13] != 's')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'w')
+                      break;
+                    return Intrinsic::x86_avx2_packssdw;	 // "86.avx2.packssdw"
+                  case 'w':	 // 1 string to match.
+                    if (NameR[15] != 'b')
+                      break;
+                    return Intrinsic::x86_avx2_packsswb;	 // "86.avx2.packsswb"
+                  }
+                  break;
+                case 'u':	 // 2 strings to match.
+                  if (NameR[13] != 's')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'w')
+                      break;
+                    return Intrinsic::x86_avx2_packusdw;	 // "86.avx2.packusdw"
+                  case 'w':	 // 1 string to match.
+                    if (NameR[15] != 'b')
+                      break;
+                    return Intrinsic::x86_avx2_packuswb;	 // "86.avx2.packuswb"
+                  }
+                  break;
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                if (memcmp(NameR.data()+11, "dus.", 4))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_paddus_b;	 // "86.avx2.paddus.b"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_paddus_w;	 // "86.avx2.paddus.w"
+                }
+                break;
+              }
+              break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, "lendvb", 6))
+                break;
+              return Intrinsic::x86_avx2_pblendvb;	 // "86.avx2.pblendvb"
+            case 'h':	 // 2 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+11, "dd.sw", 5))
+                  break;
+                return Intrinsic::x86_avx2_phadd_sw;	 // "86.avx2.phadd.sw"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+11, "ub.sw", 5))
+                  break;
+                return Intrinsic::x86_avx2_phsub_sw;	 // "86.avx2.phsub.sw"
+              }
+              break;
+            case 'm':	 // 16 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'a':	 // 1 string to match.
+                if (memcmp(NameR.data()+11, "dd.wd", 5))
+                  break;
+                return Intrinsic::x86_avx2_pmadd_wd;	 // "86.avx2.pmadd.wd"
+              case 'o':	 // 13 strings to match.
+                if (NameR[11] != 'v')
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 'm':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "skb", 3))
+                    break;
+                  return Intrinsic::x86_avx2_pmovmskb;	 // "86.avx2.pmovmskb"
+                case 's':	 // 6 strings to match.
+                  if (NameR[13] != 'x')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'b':	 // 3 strings to match.
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovsxbd;	 // "86.avx2.pmovsxbd"
+                    case 'q':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovsxbq;	 // "86.avx2.pmovsxbq"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovsxbw;	 // "86.avx2.pmovsxbw"
+                    }
+                    break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'q')
+                      break;
+                    return Intrinsic::x86_avx2_pmovsxdq;	 // "86.avx2.pmovsxdq"
+                  case 'w':	 // 2 strings to match.
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovsxwd;	 // "86.avx2.pmovsxwd"
+                    case 'q':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovsxwq;	 // "86.avx2.pmovsxwq"
+                    }
+                    break;
+                  }
+                  break;
+                case 'z':	 // 6 strings to match.
+                  if (NameR[13] != 'x')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'b':	 // 3 strings to match.
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovzxbd;	 // "86.avx2.pmovzxbd"
+                    case 'q':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovzxbq;	 // "86.avx2.pmovzxbq"
+                    case 'w':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovzxbw;	 // "86.avx2.pmovzxbw"
+                    }
+                    break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'q')
+                      break;
+                    return Intrinsic::x86_avx2_pmovzxdq;	 // "86.avx2.pmovzxdq"
+                  case 'w':	 // 2 strings to match.
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovzxwd;	 // "86.avx2.pmovzxwd"
+                    case 'q':	 // 1 string to match.
+                      return Intrinsic::x86_avx2_pmovzxwq;	 // "86.avx2.pmovzxwq"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              case 'u':	 // 2 strings to match.
+                if (NameR[11] != 'l')
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "u.w", 3))
+                    break;
+                  return Intrinsic::x86_avx2_pmulhu_w;	 // "86.avx2.pmulhu.w"
+                case 'u':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, ".dq", 3))
+                    break;
+                  return Intrinsic::x86_avx2_pmulu_dq;	 // "86.avx2.pmulu.dq"
+                }
+                break;
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+10, "ubus.", 5))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_avx2_psubus_b;	 // "86.avx2.psubus.b"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_avx2_psubus_w;	 // "86.avx2.psubus.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '5':	 // 3 strings to match.
+          if (memcmp(NameR.data()+7, "12.k", 4))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "nd.w", 4))
+              break;
+            return Intrinsic::x86_avx512_kand_w;	 // "86.avx512.kand.w"
+          case 'n':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ot.w", 4))
+              break;
+            return Intrinsic::x86_avx512_knot_w;	 // "86.avx512.knot.w"
+          case 'x':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "or.w", 4))
+              break;
+            return Intrinsic::x86_avx512_kxor_w;	 // "86.avx512.kxor.w"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfm", 6))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "dd.", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_pd;	 // "86.fma.vfmadd.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_ps;	 // "86.fma.vfmadd.ps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_sd;	 // "86.fma.vfmadd.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_ss;	 // "86.fma.vfmadd.ss"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ub.", 3))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_pd;	 // "86.fma.vfmsub.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_ps;	 // "86.fma.vfmsub.ps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_sd;	 // "86.fma.vfmsub.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_ss;	 // "86.fma.vfmsub.ss"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 7 strings to match.
+        if (memcmp(NameR.data()+4, "mx.p", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, "lignr.b", 7))
+            break;
+          return Intrinsic::x86_mmx_palignr_b;	 // "86.mmx.palignr.b"
+        case 'u':	 // 6 strings to match.
+          if (memcmp(NameR.data()+9, "npck", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'h':	 // 3 strings to match.
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[15] != 'w')
+                break;
+              return Intrinsic::x86_mmx_punpckhbw;	 // "86.mmx.punpckhbw"
+            case 'd':	 // 1 string to match.
+              if (NameR[15] != 'q')
+                break;
+              return Intrinsic::x86_mmx_punpckhdq;	 // "86.mmx.punpckhdq"
+            case 'w':	 // 1 string to match.
+              if (NameR[15] != 'd')
+                break;
+              return Intrinsic::x86_mmx_punpckhwd;	 // "86.mmx.punpckhwd"
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (NameR[15] != 'w')
+                break;
+              return Intrinsic::x86_mmx_punpcklbw;	 // "86.mmx.punpcklbw"
+            case 'd':	 // 1 string to match.
+              if (NameR[15] != 'q')
+                break;
+              return Intrinsic::x86_mmx_punpckldq;	 // "86.mmx.punpckldq"
+            case 'w':	 // 1 string to match.
+              if (NameR[15] != 'd')
+                break;
+              return Intrinsic::x86_mmx_punpcklwd;	 // "86.mmx.punpcklwd"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 42 strings to match.
+        if (NameR[4] != 's')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 34 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case '.':	 // 10 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'c':	 // 8 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'o':	 // 5 strings to match.
+                if (memcmp(NameR.data()+9, "mi", 2))
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "q.ss", 4))
+                    break;
+                  return Intrinsic::x86_sse_comieq_ss;	 // "86.sse.comieq.ss"
+                case 'g':	 // 2 strings to match.
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'e':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, ".ss", 3))
+                      break;
+                    return Intrinsic::x86_sse_comige_ss;	 // "86.sse.comige.ss"
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, ".ss", 3))
+                      break;
+                    return Intrinsic::x86_sse_comigt_ss;	 // "86.sse.comigt.ss"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'e':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, ".ss", 3))
+                      break;
+                    return Intrinsic::x86_sse_comile_ss;	 // "86.sse.comile.ss"
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, ".ss", 3))
+                      break;
+                    return Intrinsic::x86_sse_comilt_ss;	 // "86.sse.comilt.ss"
+                  }
+                  break;
+                }
+                break;
+              case 'v':	 // 3 strings to match.
+                if (memcmp(NameR.data()+9, "tt", 2))
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'p':	 // 2 strings to match.
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, "2pi", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvttpd2pi;	 // "86.sse.cvttpd2pi"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, "2pi", 3))
+                      break;
+                    return Intrinsic::x86_sse_cvttps2pi;	 // "86.sse.cvttps2pi"
+                  }
+                  break;
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "s2si", 4))
+                    break;
+                  return Intrinsic::x86_sse_cvttss2si;	 // "86.sse.cvttss2si"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, "ovmsk.ps", 8))
+                break;
+              return Intrinsic::x86_sse_movmsk_ps;	 // "86.sse.movmsk.ps"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, "toreu.ps", 8))
+                break;
+              return Intrinsic::x86_sse_storeu_ps;	 // "86.sse.storeu.ps"
+            }
+            break;
+          case '2':	 // 19 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'c':	 // 10 strings to match.
+              if (memcmp(NameR.data()+9, "vt", 2))
+                break;
+              switch (NameR[11]) {
+              default: break;
+              case 'd':	 // 2 strings to match.
+                if (memcmp(NameR.data()+12, "q2p", 3))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_sse2_cvtdq2pd;	 // "86.sse2.cvtdq2pd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_sse2_cvtdq2ps;	 // "86.sse2.cvtdq2ps"
+                }
+                break;
+              case 'p':	 // 4 strings to match.
+                switch (NameR[12]) {
+                default: break;
+                case 'd':	 // 2 strings to match.
+                  if (NameR[13] != '2')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'q')
+                      break;
+                    return Intrinsic::x86_sse2_cvtpd2dq;	 // "86.sse2.cvtpd2dq"
+                  case 'p':	 // 1 string to match.
+                    if (NameR[15] != 's')
+                      break;
+                    return Intrinsic::x86_sse2_cvtpd2ps;	 // "86.sse2.cvtpd2ps"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  if (NameR[13] != '2')
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (NameR[15] != 'q')
+                      break;
+                    return Intrinsic::x86_sse2_cvtps2dq;	 // "86.sse2.cvtps2dq"
+                  case 'p':	 // 1 string to match.
+                    if (NameR[15] != 'd')
+                      break;
+                    return Intrinsic::x86_sse2_cvtps2pd;	 // "86.sse2.cvtps2pd"
+                  }
+                  break;
+                }
+                break;
+              case 's':	 // 4 strings to match.
+                switch (NameR[12]) {
+                default: break;
+                case 'd':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+13, "2s", 2))
+                    break;
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'i':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_cvtsd2si;	 // "86.sse2.cvtsd2si"
+                  case 's':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_cvtsd2ss;	 // "86.sse2.cvtsd2ss"
+                  }
+                  break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "2sd", 3))
+                    break;
+                  return Intrinsic::x86_sse2_cvtsi2sd;	 // "86.sse2.cvtsi2sd"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "2sd", 3))
+                    break;
+                  return Intrinsic::x86_sse2_cvtss2sd;	 // "86.sse2.cvtss2sd"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 9 strings to match.
+              switch (NameR[9]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "ddus.", 5))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::x86_sse2_paddus_b;	 // "86.sse2.paddus.b"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_sse2_paddus_w;	 // "86.sse2.paddus.w"
+                }
+                break;
+              case 'm':	 // 3 strings to match.
+                switch (NameR[10]) {
+                default: break;
+                case 'a':	 // 1 string to match.
+                  if (memcmp(NameR.data()+11, "dd.wd", 5))
+                    break;
+                  return Intrinsic::x86_sse2_pmadd_wd;	 // "86.sse2.pmadd.wd"
+                case 'u':	 // 2 strings to match.
+                  if (NameR[11] != 'l')
+                    break;
+                  switch (NameR[12]) {
+                  default: break;
+                  case 'h':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, "u.w", 3))
+                      break;
+                    return Intrinsic::x86_sse2_pmulhu_w;	 // "86.sse2.pmulhu.w"
+                  case 'u':	 // 1 string to match.
+                    if (memcmp(NameR.data()+13, ".dq", 3))
+                      break;
+                    return Intrinsic::x86_sse2_pmulu_dq;	 // "86.sse2.pmulu.dq"
+                  }
+                  break;
+                }
+                break;
+              case 's':	 // 4 strings to match.
+                switch (NameR[10]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+11, "uf", 2))
+                    break;
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'h':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".w", 2))
+                      break;
+                    return Intrinsic::x86_sse2_pshufh_w;	 // "86.sse2.pshufh.w"
+                  case 'l':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".w", 2))
+                      break;
+                    return Intrinsic::x86_sse2_pshufl_w;	 // "86.sse2.pshufl.w"
+                  }
+                  break;
+                case 'u':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+11, "bus.", 4))
+                    break;
+                  switch (NameR[15]) {
+                  default: break;
+                  case 'b':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_psubus_b;	 // "86.sse2.psubus.b"
+                  case 'w':	 // 1 string to match.
+                    return Intrinsic::x86_sse2_psubus_w;	 // "86.sse2.psubus.w"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '4':	 // 5 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case '1':	 // 4 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "lendp", 5))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_sse41_blendpd;	 // "86.sse41.blendpd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_sse41_blendps;	 // "86.sse41.blendps"
+                }
+                break;
+              case 'm':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "psadbw", 6))
+                  break;
+                return Intrinsic::x86_sse41_mpsadbw;	 // "86.sse41.mpsadbw"
+              case 'p':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "blendw", 6))
+                  break;
+                return Intrinsic::x86_sse41_pblendw;	 // "86.sse41.pblendw"
+              }
+              break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, ".insertq", 8))
+                break;
+              return Intrinsic::x86_sse4a_insertq;	 // "86.sse4a.insertq"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (memcmp(NameR.data()+6, "e3.p", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "dd.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_phadd_d;	 // "86.ssse3.phadd.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_phadd_w;	 // "86.ssse3.phadd.w"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "ub.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_phsub_d;	 // "86.ssse3.phsub.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_phsub_w;	 // "86.ssse3.phsub.w"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "uf.b", 4))
+                break;
+              return Intrinsic::x86_ssse3_pshuf_b;	 // "86.ssse3.pshuf.b"
+            case 'i':	 // 3 strings to match.
+              if (memcmp(NameR.data()+12, "gn.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_psign_b;	 // "86.ssse3.psign.b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_psign_d;	 // "86.ssse3.psign.d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_ssse3_psign_w;	 // "86.ssse3.psign.w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 4 strings to match.
+        if (memcmp(NameR.data()+4, "cvtp", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, "2ps.", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "28", 2))
+              break;
+            return Intrinsic::x86_vcvtph2ps_128;	 // "86.vcvtph2ps.128"
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "56", 2))
+              break;
+            return Intrinsic::x86_vcvtph2ps_256;	 // "86.vcvtph2ps.256"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+9, "2ph.", 4))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "28", 2))
+              break;
+            return Intrinsic::x86_vcvtps2ph_128;	 // "86.vcvtps2ph.128"
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+14, "56", 2))
+              break;
+            return Intrinsic::x86_vcvtps2ph_256;	 // "86.vcvtps2ph.256"
+          }
+          break;
+        }
+        break;
+      case 'x':	 // 12 strings to match.
+        if (memcmp(NameR.data()+4, "op.vp", 5))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'h':	 // 6 strings to match.
+          if (memcmp(NameR.data()+10, "addu", 4))
+            break;
+          switch (NameR[14]) {
+          default: break;
+          case 'b':	 // 3 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubd;	 // "86.xop.vphaddubd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubq;	 // "86.xop.vphaddubq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubw;	 // "86.xop.vphaddubw"
+            }
+            break;
+          case 'd':	 // 1 string to match.
+            if (NameR[15] != 'q')
+              break;
+            return Intrinsic::x86_xop_vphaddudq;	 // "86.xop.vphaddudq"
+          case 'w':	 // 2 strings to match.
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphadduwd;	 // "86.xop.vphadduwd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphadduwq;	 // "86.xop.vphadduwq"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 6 strings to match.
+          if (NameR[10] != 'a')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'c':	 // 5 strings to match.
+            if (NameR[12] != 's')
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (NameR[14] != 'q')
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpmacsdqh;	 // "86.xop.vpmacsdqh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpmacsdql;	 // "86.xop.vpmacsdql"
+              }
+              break;
+            case 's':	 // 3 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (NameR[15] != 'd')
+                  break;
+                return Intrinsic::x86_xop_vpmacssdd;	 // "86.xop.vpmacssdd"
+              case 'w':	 // 2 strings to match.
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacsswd;	 // "86.xop.vpmacsswd"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacssww;	 // "86.xop.vpmacssww"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "cswd", 4))
+              break;
+            return Intrinsic::x86_xop_vpmadcswd;	 // "86.xop.vpmadcswd"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 17:	 // 87 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case '3':	 // 4 strings to match.
+        if (memcmp(NameR.data()+4, "dnow", 4))
+          break;
+        switch (NameR[8]) {
+        default: break;
+        case '.':	 // 3 strings to match.
+          if (memcmp(NameR.data()+9, "pfr", 3))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+13, "pit", 3))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              return Intrinsic::x86_3dnow_pfrcpit1;	 // "86.3dnow.pfrcpit1"
+            case '2':	 // 1 string to match.
+              return Intrinsic::x86_3dnow_pfrcpit2;	 // "86.3dnow.pfrcpit2"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "qit1", 4))
+              break;
+            return Intrinsic::x86_3dnow_pfrsqit1;	 // "86.3dnow.pfrsqit1"
+          }
+          break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(NameR.data()+9, ".pfpnacc", 8))
+            break;
+          return Intrinsic::x86_3dnowa_pfpnacc;	 // "86.3dnowa.pfpnacc"
+        }
+        break;
+      case 'a':	 // 17 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 11 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "mp.p", 4))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_cmp_pd_256;	 // "86.avx.cmp.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_cmp_ps_256;	 // "86.avx.cmp.ps.256"
+            }
+            break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "du.dq.256", 9))
+              break;
+            return Intrinsic::x86_avx_ldu_dq_256;	 // "86.avx.ldu.dq.256"
+          case 'm':	 // 4 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "x.p", 3))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_max_pd_256;	 // "86.avx.max.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_max_ps_256;	 // "86.avx.max.ps.256"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "n.p", 3))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_min_pd_256;	 // "86.avx.min.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_min_ps_256;	 // "86.avx.min.ps.256"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "test", 4))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_ptestc_256;	 // "86.avx.ptestc.256"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_ptestz_256;	 // "86.avx.ptestz.256"
+            }
+            break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "cp.ps.256", 9))
+              break;
+            return Intrinsic::x86_avx_rcp_ps_256;	 // "86.avx.rcp.ps.256"
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "zeroupper", 9))
+              break;
+            return Intrinsic::x86_avx_vzeroupper;	 // "86.avx.vzeroupper"
+          }
+          break;
+        case '5':	 // 6 strings to match.
+          if (memcmp(NameR.data()+7, "12.", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'k':	 // 2 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "ndn.w", 5))
+                break;
+              return Intrinsic::x86_avx512_kandn_w;	 // "86.avx512.kandn.w"
+            case 'x':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "nor.w", 5))
+                break;
+              return Intrinsic::x86_avx512_kxnor_w;	 // "86.avx512.kxnor.w"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "l.dq", 4))
+                break;
+              return Intrinsic::x86_avx512_psll_dq;	 // "86.avx512.psll.dq"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "l.dq", 4))
+                break;
+              return Intrinsic::x86_avx512_psrl_dq;	 // "86.avx512.psrl.dq"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "qrt.s", 5))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_avx512_sqrt_sd;	 // "86.avx512.sqrt.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_avx512_sqrt_ss;	 // "86.avx512.sqrt.ss"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfnm", 7))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(NameR.data()+12, "dd.", 3))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_pd;	 // "86.fma.vfnmadd.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_ps;	 // "86.fma.vfnmadd.ps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_sd;	 // "86.fma.vfnmadd.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_ss;	 // "86.fma.vfnmadd.ss"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+12, "ub.", 3))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_pd;	 // "86.fma.vfnmsub.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_ps;	 // "86.fma.vfnmsub.ps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_sd;	 // "86.fma.vfnmsub.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_ss;	 // "86.fma.vfnmsub.ss"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 50 strings to match.
+        if (NameR[4] != 's')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 48 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case '.':	 // 8 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'c':	 // 3 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'o':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "mineq.ss", 8))
+                  break;
+                return Intrinsic::x86_sse_comineq_ss;	 // "86.sse.comineq.ss"
+              case 'v':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "ts", 2))
+                  break;
+                switch (NameR[11]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "642ss", 5))
+                    break;
+                  return Intrinsic::x86_sse_cvtsi642ss;	 // "86.sse.cvtsi642ss"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+12, "2si64", 5))
+                    break;
+                  return Intrinsic::x86_sse_cvtss2si64;	 // "86.sse.cvtss2si64"
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 5 strings to match.
+              if (memcmp(NameR.data()+8, "comi", 4))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "q.ss", 4))
+                  break;
+                return Intrinsic::x86_sse_ucomieq_ss;	 // "86.sse.ucomieq.ss"
+              case 'g':	 // 2 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, ".ss", 3))
+                    break;
+                  return Intrinsic::x86_sse_ucomige_ss;	 // "86.sse.ucomige.ss"
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, ".ss", 3))
+                    break;
+                  return Intrinsic::x86_sse_ucomigt_ss;	 // "86.sse.ucomigt.ss"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                switch (NameR[13]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, ".ss", 3))
+                    break;
+                  return Intrinsic::x86_sse_ucomile_ss;	 // "86.sse.ucomile.ss"
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+14, ".ss", 3))
+                    break;
+                  return Intrinsic::x86_sse_ucomilt_ss;	 // "86.sse.ucomilt.ss"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'c':	 // 8 strings to match.
+              switch (NameR[9]) {
+              default: break;
+              case 'o':	 // 5 strings to match.
+                if (memcmp(NameR.data()+10, "mi", 2))
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 'e':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "q.sd", 4))
+                    break;
+                  return Intrinsic::x86_sse2_comieq_sd;	 // "86.sse2.comieq.sd"
+                case 'g':	 // 2 strings to match.
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'e':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".sd", 3))
+                      break;
+                    return Intrinsic::x86_sse2_comige_sd;	 // "86.sse2.comige.sd"
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".sd", 3))
+                      break;
+                    return Intrinsic::x86_sse2_comigt_sd;	 // "86.sse2.comigt.sd"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'e':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".sd", 3))
+                      break;
+                    return Intrinsic::x86_sse2_comile_sd;	 // "86.sse2.comile.sd"
+                  case 't':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, ".sd", 3))
+                      break;
+                    return Intrinsic::x86_sse2_comilt_sd;	 // "86.sse2.comilt.sd"
+                  }
+                  break;
+                }
+                break;
+              case 'v':	 // 3 strings to match.
+                if (memcmp(NameR.data()+10, "tt", 2))
+                  break;
+                switch (NameR[12]) {
+                default: break;
+                case 'p':	 // 2 strings to match.
+                  switch (NameR[13]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, "2dq", 3))
+                      break;
+                    return Intrinsic::x86_sse2_cvttpd2dq;	 // "86.sse2.cvttpd2dq"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(NameR.data()+14, "2dq", 3))
+                      break;
+                    return Intrinsic::x86_sse2_cvttps2dq;	 // "86.sse2.cvttps2dq"
+                  }
+                  break;
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+13, "d2si", 4))
+                    break;
+                  return Intrinsic::x86_sse2_cvttsd2si;	 // "86.sse2.cvttsd2si"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "ovmsk.pd", 8))
+                break;
+              return Intrinsic::x86_sse2_movmsk_pd;	 // "86.sse2.movmsk.pd"
+            case 's':	 // 3 strings to match.
+              if (memcmp(NameR.data()+9, "tore", 4))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, ".dq", 3))
+                  break;
+                return Intrinsic::x86_sse2_storel_dq;	 // "86.sse2.storel.dq"
+              case 'u':	 // 2 strings to match.
+                if (NameR[14] != '.')
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (NameR[16] != 'q')
+                    break;
+                  return Intrinsic::x86_sse2_storeu_dq;	 // "86.sse2.storeu.dq"
+                case 'p':	 // 1 string to match.
+                  if (NameR[16] != 'd')
+                    break;
+                  return Intrinsic::x86_sse2_storeu_pd;	 // "86.sse2.storeu.pd"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(NameR.data()+7, ".addsub.p", 9))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_sse3_addsub_pd;	 // "86.sse3.addsub.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_sse3_addsub_ps;	 // "86.sse3.addsub.ps"
+            }
+            break;
+          case '4':	 // 26 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case '1':	 // 23 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "lendvp", 6))
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_sse41_blendvpd;	 // "86.sse41.blendvpd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_sse41_blendvps;	 // "86.sse41.blendvps"
+                }
+                break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "nsertps", 7))
+                  break;
+                return Intrinsic::x86_sse41_insertps;	 // "86.sse41.insertps"
+              case 'm':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "ovntdqa", 7))
+                  break;
+                return Intrinsic::x86_sse41_movntdqa;	 // "86.sse41.movntdqa"
+              case 'p':	 // 15 strings to match.
+                switch (NameR[10]) {
+                default: break;
+                case 'a':	 // 1 string to match.
+                  if (memcmp(NameR.data()+11, "ckusdw", 6))
+                    break;
+                  return Intrinsic::x86_sse41_packusdw;	 // "86.sse41.packusdw"
+                case 'b':	 // 1 string to match.
+                  if (memcmp(NameR.data()+11, "lendvb", 6))
+                    break;
+                  return Intrinsic::x86_sse41_pblendvb;	 // "86.sse41.pblendvb"
+                case 'm':	 // 12 strings to match.
+                  if (memcmp(NameR.data()+11, "ov", 2))
+                    break;
+                  switch (NameR[13]) {
+                  default: break;
+                  case 's':	 // 6 strings to match.
+                    if (NameR[14] != 'x')
+                      break;
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'b':	 // 3 strings to match.
+                      switch (NameR[16]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovsxbd;	 // "86.sse41.pmovsxbd"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovsxbq;	 // "86.sse41.pmovsxbq"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovsxbw;	 // "86.sse41.pmovsxbw"
+                      }
+                      break;
+                    case 'd':	 // 1 string to match.
+                      if (NameR[16] != 'q')
+                        break;
+                      return Intrinsic::x86_sse41_pmovsxdq;	 // "86.sse41.pmovsxdq"
+                    case 'w':	 // 2 strings to match.
+                      switch (NameR[16]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovsxwd;	 // "86.sse41.pmovsxwd"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovsxwq;	 // "86.sse41.pmovsxwq"
+                      }
+                      break;
+                    }
+                    break;
+                  case 'z':	 // 6 strings to match.
+                    if (NameR[14] != 'x')
+                      break;
+                    switch (NameR[15]) {
+                    default: break;
+                    case 'b':	 // 3 strings to match.
+                      switch (NameR[16]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovzxbd;	 // "86.sse41.pmovzxbd"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovzxbq;	 // "86.sse41.pmovzxbq"
+                      case 'w':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovzxbw;	 // "86.sse41.pmovzxbw"
+                      }
+                      break;
+                    case 'd':	 // 1 string to match.
+                      if (NameR[16] != 'q')
+                        break;
+                      return Intrinsic::x86_sse41_pmovzxdq;	 // "86.sse41.pmovzxdq"
+                    case 'w':	 // 2 strings to match.
+                      switch (NameR[16]) {
+                      default: break;
+                      case 'd':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovzxwd;	 // "86.sse41.pmovzxwd"
+                      case 'q':	 // 1 string to match.
+                        return Intrinsic::x86_sse41_pmovzxwq;	 // "86.sse41.pmovzxwq"
+                      }
+                      break;
+                    }
+                    break;
+                  }
+                  break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(NameR.data()+11, "estnzc", 6))
+                    break;
+                  return Intrinsic::x86_sse41_ptestnzc;	 // "86.sse41.ptestnzc"
+                }
+                break;
+              case 'r':	 // 4 strings to match.
+                if (memcmp(NameR.data()+10, "ound.", 5))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'p':	 // 2 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_round_pd;	 // "86.sse41.round.pd"
+                  case 's':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_round_ps;	 // "86.sse41.round.ps"
+                  }
+                  break;
+                case 's':	 // 2 strings to match.
+                  switch (NameR[16]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_round_sd;	 // "86.sse41.round.sd"
+                  case 's':	 // 1 string to match.
+                    return Intrinsic::x86_sse41_round_ss;	 // "86.sse41.round.ss"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'a':	 // 3 strings to match.
+              if (NameR[8] != '.')
+                break;
+              switch (NameR[9]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "nsertqi", 7))
+                  break;
+                return Intrinsic::x86_sse4a_insertqi;	 // "86.sse4a.insertqi"
+              case 'm':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "ovnt.s", 6))
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_sse4a_movnt_sd;	 // "86.sse4a.movnt.sd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_sse4a_movnt_ss;	 // "86.sse4a.movnt.ss"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "e3.ph", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "dd.sw", 5))
+              break;
+            return Intrinsic::x86_ssse3_phadd_sw;	 // "86.ssse3.phadd.sw"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ub.sw", 5))
+              break;
+            return Intrinsic::x86_ssse3_phsub_sw;	 // "86.ssse3.phsub.sw"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(NameR.data()+4, "bm.bextri.u", 11))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (NameR[16] != '2')
+            break;
+          return Intrinsic::x86_tbm_bextri_u32;	 // "86.tbm.bextri.u32"
+        case '6':	 // 1 string to match.
+          if (NameR[16] != '4')
+            break;
+          return Intrinsic::x86_tbm_bextri_u64;	 // "86.tbm.bextri.u64"
+        }
+        break;
+      case 'x':	 // 6 strings to match.
+        if (memcmp(NameR.data()+4, "op.vp", 5))
+          break;
+        switch (NameR[9]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(NameR.data()+10, "mov.256", 7))
+            break;
+          return Intrinsic::x86_xop_vpcmov_256;	 // "86.xop.vpcmov.256"
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+10, "rmil2p", 6))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_xop_vpermil2pd;	 // "86.xop.vpermil2pd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_xop_vpermil2ps;	 // "86.xop.vpermil2ps"
+          }
+          break;
+        case 'm':	 // 3 strings to match.
+          if (NameR[10] != 'a')
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+12, "ssdq", 4))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpmacssdqh;	 // "86.xop.vpmacssdqh"
+            case 'l':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpmacssdql;	 // "86.xop.vpmacssdql"
+            }
+            break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "csswd", 5))
+              break;
+            return Intrinsic::x86_xop_vpmadcsswd;	 // "86.xop.vpmadcsswd"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 18:	 // 45 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 32 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 10 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "dd.p", 4))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_hadd_pd_256;	 // "86.avx.hadd.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_hadd_ps_256;	 // "86.avx.hadd.ps.256"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "ub.p", 4))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_hsub_pd_256;	 // "86.avx.hsub.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+14, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_hsub_ps_256;	 // "86.avx.hsub.ps.256"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "askload.p", 9))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_avx_maskload_pd;	 // "86.avx.maskload.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_avx_maskload_ps;	 // "86.avx.maskload.ps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "qrt.p", 5))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_sqrt_pd_256;	 // "86.avx.sqrt.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_sqrt_ps_256;	 // "86.avx.sqrt.ps.256"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "testnzc.p", 9))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_avx_vtestnzc_pd;	 // "86.avx.vtestnzc.pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_avx_vtestnzc_ps;	 // "86.avx.vtestnzc.ps"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 10 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'g':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "ather.", 6))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (NameR[16] != '.')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx2_gather_d_d;	 // "86.avx2.gather.d.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx2_gather_d_q;	 // "86.avx2.gather.d.q"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              if (NameR[16] != '.')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx2_gather_q_d;	 // "86.avx2.gather.q.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx2_gather_q_q;	 // "86.avx2.gather.q.q"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+9, "askload.", 8))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_avx2_maskload_d;	 // "86.avx2.maskload.d"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_avx2_maskload_q;	 // "86.avx2.maskload.q"
+            }
+            break;
+          case 'p':	 // 3 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, "ul.hr.sw", 8))
+                break;
+              return Intrinsic::x86_avx2_pmul_hr_sw;	 // "86.avx2.pmul.hr.sw"
+            case 's':	 // 2 strings to match.
+              switch (NameR[10]) {
+              default: break;
+              case 'l':	 // 1 string to match.
+                if (memcmp(NameR.data()+11, "l.dq.bs", 7))
+                  break;
+                return Intrinsic::x86_avx2_psll_dq_bs;	 // "86.avx2.psll.dq.bs"
+              case 'r':	 // 1 string to match.
+                if (memcmp(NameR.data()+11, "l.dq.bs", 7))
+                  break;
+                return Intrinsic::x86_avx2_psrl_dq_bs;	 // "86.avx2.psrl.dq.bs"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "perm2i128", 9))
+              break;
+            return Intrinsic::x86_avx2_vperm2i128;	 // "86.avx2.vperm2i128"
+          }
+          break;
+        case '5':	 // 12 strings to match.
+          if (memcmp(NameR.data()+7, "12.", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ovntdqa", 7))
+              break;
+            return Intrinsic::x86_avx512_movntdqa;	 // "86.avx512.movntdqa"
+          case 'p':	 // 5 strings to match.
+            if (memcmp(NameR.data()+11, "movzx", 5))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx512_pmovzxbd;	 // "86.avx512.pmovzxbd"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx512_pmovzxbq;	 // "86.avx512.pmovzxbq"
+              }
+              break;
+            case 'd':	 // 1 string to match.
+              if (NameR[17] != 'q')
+                break;
+              return Intrinsic::x86_avx512_pmovzxdq;	 // "86.avx512.pmovzxdq"
+            case 'w':	 // 2 strings to match.
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx512_pmovzxwd;	 // "86.avx512.pmovzxwd"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx512_pmovzxwq;	 // "86.avx512.pmovzxwq"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "cp", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "4.s", 3))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx512_rcp14_sd;	 // "86.avx512.rcp14.sd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx512_rcp14_ss;	 // "86.avx512.rcp14.ss"
+              }
+              break;
+            case '2':	 // 4 strings to match.
+              if (memcmp(NameR.data()+14, "8.", 2))
+                break;
+              switch (NameR[16]) {
+              default: break;
+              case 'p':	 // 2 strings to match.
+                switch (NameR[17]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rcp28_pd;	 // "86.avx512.rcp28.pd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rcp28_ps;	 // "86.avx512.rcp28.ps"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                switch (NameR[17]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rcp28_sd;	 // "86.avx512.rcp28.sd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rcp28_ss;	 // "86.avx512.rcp28.ss"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 13 strings to match.
+        if (memcmp(NameR.data()+4, "se", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 2 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "vttss2si64", 10))
+              break;
+            return Intrinsic::x86_sse_cvttss2si64;	 // "86.sse.cvttss2si64"
+          case 'u':	 // 1 string to match.
+            if (memcmp(NameR.data()+8, "comineq.ss", 10))
+              break;
+            return Intrinsic::x86_sse_ucomineq_ss;	 // "86.sse.ucomineq.ss"
+          }
+          break;
+        case '2':	 // 10 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'c':	 // 3 strings to match.
+            switch (NameR[9]) {
+            default: break;
+            case 'o':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, "mineq.sd", 8))
+                break;
+              return Intrinsic::x86_sse2_comineq_sd;	 // "86.sse2.comineq.sd"
+            case 'v':	 // 2 strings to match.
+              if (memcmp(NameR.data()+10, "ts", 2))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "2si64", 5))
+                  break;
+                return Intrinsic::x86_sse2_cvtsd2si64;	 // "86.sse2.cvtsd2si64"
+              case 'i':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "642sd", 5))
+                  break;
+                return Intrinsic::x86_sse2_cvtsi642sd;	 // "86.sse2.cvtsi642sd"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[9] != 's')
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, "l.dq.bs", 7))
+                break;
+              return Intrinsic::x86_sse2_psll_dq_bs;	 // "86.sse2.psll.dq.bs"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, "l.dq.bs", 7))
+                break;
+              return Intrinsic::x86_sse2_psrl_dq_bs;	 // "86.sse2.psrl.dq.bs"
+            }
+            break;
+          case 'u':	 // 5 strings to match.
+            if (memcmp(NameR.data()+9, "comi", 4))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "q.sd", 4))
+                break;
+              return Intrinsic::x86_sse2_ucomieq_sd;	 // "86.sse2.ucomieq.sd"
+            case 'g':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".sd", 3))
+                  break;
+                return Intrinsic::x86_sse2_ucomige_sd;	 // "86.sse2.ucomige.sd"
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".sd", 3))
+                  break;
+                return Intrinsic::x86_sse2_ucomigt_sd;	 // "86.sse2.ucomigt.sd"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".sd", 3))
+                  break;
+                return Intrinsic::x86_sse2_ucomile_sd;	 // "86.sse2.ucomile.sd"
+              case 't':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".sd", 3))
+                  break;
+                return Intrinsic::x86_sse2_ucomilt_sd;	 // "86.sse2.ucomilt.sd"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, "1.extractps", 11))
+            break;
+          return Intrinsic::x86_sse41_extractps;	 // "86.sse41.extractps"
+        }
+        break;
+      }
+      break;
+    case 19:	 // 45 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 30 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(NameR.data()+5, "sni.aes", 7))
+            break;
+          switch (NameR[12]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "eclast", 6))
+              break;
+            return Intrinsic::x86_aesni_aesdeclast;	 // "86.aesni.aesdeclast"
+          case 'e':	 // 1 string to match.
+            if (memcmp(NameR.data()+13, "nclast", 6))
+              break;
+            return Intrinsic::x86_aesni_aesenclast;	 // "86.aesni.aesenclast"
+          }
+          break;
+        case 'v':	 // 28 strings to match.
+          if (NameR[5] != 'x')
+            break;
+          switch (NameR[6]) {
+          default: break;
+          case '.':	 // 8 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "lend.p", 6))
+                break;
+              switch (NameR[14]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_blend_pd_256;	 // "86.avx.blend.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_blend_ps_256;	 // "86.avx.blend.ps.256"
+              }
+              break;
+            case 'm':	 // 2 strings to match.
+              if (memcmp(NameR.data()+8, "askstore.p", 10))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx_maskstore_pd;	 // "86.avx.maskstore.pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx_maskstore_ps;	 // "86.avx.maskstore.ps"
+              }
+              break;
+            case 'p':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, "testnzc.256", 11))
+                break;
+              return Intrinsic::x86_avx_ptestnzc_256;	 // "86.avx.ptestnzc.256"
+            case 'r':	 // 3 strings to match.
+              switch (NameR[8]) {
+              default: break;
+              case 'o':	 // 2 strings to match.
+                if (memcmp(NameR.data()+9, "und.p", 5))
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_round_pd_256;	 // "86.avx.round.pd.256"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_round_ps_256;	 // "86.avx.round.ps.256"
+                }
+                break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+9, "qrt.ps.256", 10))
+                  break;
+                return Intrinsic::x86_avx_rsqrt_ps_256;	 // "86.avx.rsqrt.ps.256"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 15 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'g':	 // 4 strings to match.
+              if (memcmp(NameR.data()+9, "ather.", 6))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, ".p", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_gather_d_pd;	 // "86.avx2.gather.d.pd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_gather_d_ps;	 // "86.avx2.gather.d.ps"
+                }
+                break;
+              case 'q':	 // 2 strings to match.
+                if (memcmp(NameR.data()+16, ".p", 2))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_gather_q_pd;	 // "86.avx2.gather.q.pd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx2_gather_q_ps;	 // "86.avx2.gather.q.ps"
+                }
+                break;
+              }
+              break;
+            case 'm':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "askstore.", 9))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx2_maskstore_d;	 // "86.avx2.maskstore.d"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_avx2_maskstore_q;	 // "86.avx2.maskstore.q"
+              }
+              break;
+            case 'p':	 // 8 strings to match.
+              switch (NameR[9]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                if (memcmp(NameR.data()+10, "lendd.", 6))
+                  break;
+                switch (NameR[16]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, "28", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pblendd_128;	 // "86.avx2.pblendd.128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(NameR.data()+17, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pblendd_256;	 // "86.avx2.pblendd.256"
+                }
+                break;
+              case 'm':	 // 1 string to match.
+                if (memcmp(NameR.data()+10, "add.ub.sw", 9))
+                  break;
+                return Intrinsic::x86_avx2_pmadd_ub_sw;	 // "86.avx2.pmadd.ub.sw"
+              case 's':	 // 5 strings to match.
+                switch (NameR[10]) {
+                default: break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(NameR.data()+11, "lv.", 3))
+                    break;
+                  switch (NameR[14]) {
+                  default: break;
+                  case 'd':	 // 1 string to match.
+                    if (memcmp(NameR.data()+15, ".256", 4))
+                      break;
+                    return Intrinsic::x86_avx2_psllv_d_256;	 // "86.avx2.psllv.d.256"
+                  case 'q':	 // 1 string to match.
+                    if (memcmp(NameR.data()+15, ".256", 4))
+                      break;
+                    return Intrinsic::x86_avx2_psllv_q_256;	 // "86.avx2.psllv.q.256"
+                  }
+                  break;
+                case 'r':	 // 3 strings to match.
+                  switch (NameR[11]) {
+                  default: break;
+                  case 'a':	 // 1 string to match.
+                    if (memcmp(NameR.data()+12, "v.d.256", 7))
+                      break;
+                    return Intrinsic::x86_avx2_psrav_d_256;	 // "86.avx2.psrav.d.256"
+                  case 'l':	 // 2 strings to match.
+                    if (memcmp(NameR.data()+12, "v.", 2))
+                      break;
+                    switch (NameR[14]) {
+                    default: break;
+                    case 'd':	 // 1 string to match.
+                      if (memcmp(NameR.data()+15, ".256", 4))
+                        break;
+                      return Intrinsic::x86_avx2_psrlv_d_256;	 // "86.avx2.psrlv.d.256"
+                    case 'q':	 // 1 string to match.
+                      if (memcmp(NameR.data()+15, ".256", 4))
+                        break;
+                      return Intrinsic::x86_avx2_psrlv_q_256;	 // "86.avx2.psrlv.q.256"
+                    }
+                    break;
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'v':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "inserti128", 10))
+                break;
+              return Intrinsic::x86_avx2_vinserti128;	 // "86.avx2.vinserti128"
+            }
+            break;
+          case '5':	 // 5 strings to match.
+            if (memcmp(NameR.data()+7, "12.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'c':	 // 4 strings to match.
+              if (memcmp(NameR.data()+11, "vt", 2))
+                break;
+              switch (NameR[13]) {
+              default: break;
+              case 's':	 // 2 strings to match.
+                switch (NameR[14]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "2usi", 4))
+                    break;
+                  return Intrinsic::x86_avx512_cvtsd2usi;	 // "86.avx512.cvtsd2usi"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "2usi", 4))
+                    break;
+                  return Intrinsic::x86_avx512_cvtss2usi;	 // "86.avx512.cvtss2usi"
+                }
+                break;
+              case 'u':	 // 2 strings to match.
+                if (memcmp(NameR.data()+14, "si2s", 4))
+                  break;
+                switch (NameR[18]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_cvtusi2sd;	 // "86.avx512.cvtusi2sd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_cvtusi2ss;	 // "86.avx512.cvtusi2ss"
+                }
+                break;
+              }
+              break;
+            case 'k':	 // 1 string to match.
+              if (memcmp(NameR.data()+11, "unpck.bw", 8))
+                break;
+              return Intrinsic::x86_avx512_kunpck_bw;	 // "86.avx512.kunpck.bw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 4 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfm", 6))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "ddsub.p", 7))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_fma_vfmaddsub_pd;	 // "86.fma.vfmaddsub.pd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_fma_vfmaddsub_ps;	 // "86.fma.vfmaddsub.ps"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "ubadd.p", 7))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_fma_vfmsubadd_pd;	 // "86.fma.vfmsubadd.pd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_fma_vfmsubadd_ps;	 // "86.fma.vfmsubadd.ps"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 9 strings to match.
+        if (NameR[4] != 's')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 5 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case '2':	 // 3 strings to match.
+            if (NameR[7] != '.')
+              break;
+            switch (NameR[8]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "vttsd2si64", 10))
+                break;
+              return Intrinsic::x86_sse2_cvttsd2si64;	 // "86.sse2.cvttsd2si64"
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "askmov.dqu", 10))
+                break;
+              return Intrinsic::x86_sse2_maskmov_dqu;	 // "86.sse2.maskmov.dqu"
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+9, "comineq.sd", 10))
+                break;
+              return Intrinsic::x86_sse2_ucomineq_sd;	 // "86.sse2.ucomineq.sd"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            switch (NameR[7]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, ".phminposuw", 11))
+                break;
+              return Intrinsic::x86_sse41_phminposuw;	 // "86.sse41.phminposuw"
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+8, ".crc32.32.8", 11))
+                break;
+              return Intrinsic::x86_sse42_crc32_32_8;	 // "86.sse42.crc32.32.8"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "e3.p", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'a':	 // 3 strings to match.
+            if (memcmp(NameR.data()+11, "bs.", 3))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".128", 4))
+                break;
+              return Intrinsic::x86_ssse3_pabs_b_128;	 // "86.ssse3.pabs.b.128"
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".128", 4))
+                break;
+              return Intrinsic::x86_ssse3_pabs_d_128;	 // "86.ssse3.pabs.d.128"
+            case 'w':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, ".128", 4))
+                break;
+              return Intrinsic::x86_ssse3_pabs_w_128;	 // "86.ssse3.pabs.w.128"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "ul.hr.sw", 8))
+              break;
+            return Intrinsic::x86_ssse3_pmul_hr_sw;	 // "86.ssse3.pmul.hr.sw"
+          }
+          break;
+        }
+        break;
+      case 'x':	 // 2 strings to match.
+        if (memcmp(NameR.data()+4, "op.vfrcz.p", 10))
+          break;
+        switch (NameR[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+15, ".256", 4))
+            break;
+          return Intrinsic::x86_xop_vfrcz_pd_256;	 // "86.xop.vfrcz.pd.256"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+15, ".256", 4))
+            break;
+          return Intrinsic::x86_xop_vfrcz_ps_256;	 // "86.xop.vfrcz.ps.256"
+        }
+        break;
+      }
+      break;
+    case 20:	 // 56 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 32 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 19 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "ddsub.p", 7))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_addsub_pd_256;	 // "86.avx.addsub.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_addsub_ps_256;	 // "86.avx.addsub.ps.256"
+            }
+            break;
+          case 'b':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "lendv.p", 7))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_blendv_pd_256;	 // "86.avx.blendv.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_blendv_ps_256;	 // "86.avx.blendv.ps.256"
+            }
+            break;
+          case 'c':	 // 4 strings to match.
+            if (memcmp(NameR.data()+8, "vt", 2))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case '.':	 // 2 strings to match.
+              if (NameR[11] != 'p')
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "2dq.256", 7))
+                  break;
+                return Intrinsic::x86_avx_cvt_pd2dq_256;	 // "86.avx.cvt.pd2dq.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "2dq.256", 7))
+                  break;
+                return Intrinsic::x86_avx_cvt_ps2dq_256;	 // "86.avx.cvt.ps2dq.256"
+              }
+              break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(NameR.data()+11, "q2.p", 4))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_cvtdq2_pd_256;	 // "86.avx.cvtdq2.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_cvtdq2_ps_256;	 // "86.avx.cvtdq2.ps.256"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "ovmsk.p", 7))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_movmsk_pd_256;	 // "86.avx.movmsk.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_movmsk_ps_256;	 // "86.avx.movmsk.ps.256"
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(NameR.data()+8, "toreu.", 6))
+              break;
+            switch (NameR[14]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+15, "q.256", 5))
+                break;
+              return Intrinsic::x86_avx_storeu_dq_256;	 // "86.avx.storeu.dq.256"
+            case 'p':	 // 2 strings to match.
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_storeu_pd_256;	 // "86.avx.storeu.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_storeu_ps_256;	 // "86.avx.storeu.ps.256"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 6 strings to match.
+            switch (NameR[8]) {
+            default: break;
+            case 'p':	 // 2 strings to match.
+              if (memcmp(NameR.data()+9, "ermilvar.p", 10))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx_vpermilvar_pd;	 // "86.avx.vpermilvar.pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx_vpermilvar_ps;	 // "86.avx.vpermilvar.ps"
+              }
+              break;
+            case 't':	 // 4 strings to match.
+              if (memcmp(NameR.data()+9, "est", 3))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 'c':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, ".p", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vtestc_pd_256;	 // "86.avx.vtestc.pd.256"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vtestc_ps_256;	 // "86.avx.vtestc.ps.256"
+                }
+                break;
+              case 'z':	 // 2 strings to match.
+                if (memcmp(NameR.data()+13, ".p", 2))
+                  break;
+                switch (NameR[15]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vtestz_pd_256;	 // "86.avx.vtestz.pd.256"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+16, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vtestz_ps_256;	 // "86.avx.vtestz.ps.256"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '2':	 // 1 string to match.
+          if (memcmp(NameR.data()+7, ".vextracti128", 13))
+            break;
+          return Intrinsic::x86_avx2_vextracti128;	 // "86.avx2.vextracti128"
+        case '5':	 // 12 strings to match.
+          if (memcmp(NameR.data()+7, "12.", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "vtts", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "2usi", 4))
+                break;
+              return Intrinsic::x86_avx512_cvttsd2usi;	 // "86.avx512.cvttsd2usi"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "2usi", 4))
+                break;
+              return Intrinsic::x86_avx512_cvttss2usi;	 // "86.avx512.cvttss2usi"
+            }
+            break;
+          case 'k':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "ortest", 6))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".w", 2))
+                break;
+              return Intrinsic::x86_avx512_kortestc_w;	 // "86.avx512.kortestc.w"
+            case 'z':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".w", 2))
+                break;
+              return Intrinsic::x86_avx512_kortestz_w;	 // "86.avx512.kortestz.w"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (NameR[11] != 's')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "l.dq.bs", 7))
+                break;
+              return Intrinsic::x86_avx512_psll_dq_bs;	 // "86.avx512.psll.dq.bs"
+            case 'r':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "l.dq.bs", 7))
+                break;
+              return Intrinsic::x86_avx512_psrl_dq_bs;	 // "86.avx512.psrl.dq.bs"
+            }
+            break;
+          case 'r':	 // 6 strings to match.
+            if (memcmp(NameR.data()+11, "sqrt", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "4.s", 3))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx512_rsqrt14_sd;	 // "86.avx512.rsqrt14.sd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx512_rsqrt14_ss;	 // "86.avx512.rsqrt14.ss"
+              }
+              break;
+            case '2':	 // 4 strings to match.
+              if (memcmp(NameR.data()+16, "8.", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'p':	 // 2 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rsqrt28_pd;	 // "86.avx512.rsqrt28.pd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rsqrt28_ps;	 // "86.avx512.rsqrt28.ps"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rsqrt28_sd;	 // "86.avx512.rsqrt28.sd"
+                case 's':	 // 1 string to match.
+                  return Intrinsic::x86_avx512_rsqrt28_ss;	 // "86.avx512.rsqrt28.ss"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfm", 6))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "dd.p", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[16] != '.')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmadd_pd_256;	 // "86.fma.vfmadd.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmadd_pd_512;	 // "86.fma.vfmadd.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[16] != '.')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmadd_ps_256;	 // "86.fma.vfmadd.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmadd_ps_512;	 // "86.fma.vfmadd.ps.512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ub.p", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[16] != '.')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsub_pd_256;	 // "86.fma.vfmsub.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsub_pd_512;	 // "86.fma.vfmsub.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[16] != '.')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsub_ps_256;	 // "86.fma.vfmsub.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsub_ps_512;	 // "86.fma.vfmsub.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 16 strings to match.
+        if (NameR[4] != 's')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 7 strings to match.
+          switch (NameR[6]) {
+          default: break;
+          case '2':	 // 4 strings to match.
+            if (memcmp(NameR.data()+7, ".p", 2))
+              break;
+            switch (NameR[9]) {
+            default: break;
+            case 'a':	 // 3 strings to match.
+              if (memcmp(NameR.data()+10, "ck", 2))
+                break;
+              switch (NameR[12]) {
+              default: break;
+              case 's':	 // 2 strings to match.
+                if (NameR[13] != 's')
+                  break;
+                switch (NameR[14]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "w.128", 5))
+                    break;
+                  return Intrinsic::x86_sse2_packssdw_128;	 // "86.sse2.packssdw.128"
+                case 'w':	 // 1 string to match.
+                  if (memcmp(NameR.data()+15, "b.128", 5))
+                    break;
+                  return Intrinsic::x86_sse2_packsswb_128;	 // "86.sse2.packsswb.128"
+                }
+                break;
+              case 'u':	 // 1 string to match.
+                if (memcmp(NameR.data()+13, "swb.128", 7))
+                  break;
+                return Intrinsic::x86_sse2_packuswb_128;	 // "86.sse2.packuswb.128"
+              }
+              break;
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+10, "ovmskb.128", 10))
+                break;
+              return Intrinsic::x86_sse2_pmovmskb_128;	 // "86.sse2.pmovmskb.128"
+            }
+            break;
+          case '4':	 // 3 strings to match.
+            if (memcmp(NameR.data()+7, "2.crc32.", 8))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, "2.", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (NameR[19] != '6')
+                  break;
+                return Intrinsic::x86_sse42_crc32_32_16;	 // "86.sse42.crc32.32.16"
+              case '3':	 // 1 string to match.
+                if (NameR[19] != '2')
+                  break;
+                return Intrinsic::x86_sse42_crc32_32_32;	 // "86.sse42.crc32.32.32"
+              }
+              break;
+            case '6':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "4.64", 4))
+                break;
+              return Intrinsic::x86_sse42_crc32_64_64;	 // "86.sse42.crc32.64.64"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 9 strings to match.
+          if (memcmp(NameR.data()+6, "e3.p", 4))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "dd.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_phadd_d_128;	 // "86.ssse3.phadd.d.128"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_phadd_w_128;	 // "86.ssse3.phadd.w.128"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(NameR.data()+12, "ub.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_phsub_d_128;	 // "86.ssse3.phsub.d.128"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_phsub_w_128;	 // "86.ssse3.phsub.w.128"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+11, "add.ub.sw", 9))
+              break;
+            return Intrinsic::x86_ssse3_pmadd_ub_sw;	 // "86.ssse3.pmadd.ub.sw"
+          case 's':	 // 4 strings to match.
+            switch (NameR[11]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+12, "uf.b.128", 8))
+                break;
+              return Intrinsic::x86_ssse3_pshuf_b_128;	 // "86.ssse3.pshuf.b.128"
+            case 'i':	 // 3 strings to match.
+              if (memcmp(NameR.data()+12, "gn.", 3))
+                break;
+              switch (NameR[15]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_psign_b_128;	 // "86.ssse3.psign.b.128"
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_psign_d_128;	 // "86.ssse3.psign.d.128"
+              case 'w':	 // 1 string to match.
+                if (memcmp(NameR.data()+16, ".128", 4))
+                  break;
+                return Intrinsic::x86_ssse3_psign_w_128;	 // "86.ssse3.psign.w.128"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 21:	 // 28 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 12 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, "cvt", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case '.':	 // 2 strings to match.
+            if (NameR[11] != 'p')
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "2.ps.256", 8))
+                break;
+              return Intrinsic::x86_avx_cvt_pd2_ps_256;	 // "86.avx.cvt.pd2.ps.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+13, "2.pd.256", 8))
+                break;
+              return Intrinsic::x86_avx_cvt_ps2_pd_256;	 // "86.avx.cvt.ps2.pd.256"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, ".p", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "2dq.256", 7))
+                break;
+              return Intrinsic::x86_avx_cvtt_pd2dq_256;	 // "86.avx.cvtt.pd2dq.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+14, "2dq.256", 7))
+                break;
+              return Intrinsic::x86_avx_cvtt_ps2dq_256;	 // "86.avx.cvtt.ps2dq.256"
+            }
+            break;
+          }
+          break;
+        case '5':	 // 8 strings to match.
+          if (memcmp(NameR.data()+7, "12.", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 4 strings to match.
+            if (memcmp(NameR.data()+11, "vt", 2))
+              break;
+            switch (NameR[13]) {
+            default: break;
+            case 's':	 // 2 strings to match.
+              switch (NameR[14]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "2usi64", 6))
+                  break;
+                return Intrinsic::x86_avx512_cvtsd2usi64;	 // "86.avx512.cvtsd2usi64"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+15, "2usi64", 6))
+                  break;
+                return Intrinsic::x86_avx512_cvtss2usi64;	 // "86.avx512.cvtss2usi64"
+              }
+              break;
+            case 'u':	 // 2 strings to match.
+              if (memcmp(NameR.data()+14, "si642s", 6))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_avx512_cvtusi642sd;	 // "86.avx512.cvtusi642sd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_avx512_cvtusi642ss;	 // "86.avx512.cvtusi642ss"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "ndscale.s", 9))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_avx512_rndscale_sd;	 // "86.avx512.rndscale.sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_avx512_rndscale_ss;	 // "86.avx512.rndscale.ss"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "qrt.p", 5))
+              break;
+            switch (NameR[16]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_sqrt_pd_512;	 // "86.avx512.sqrt.pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+17, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_sqrt_ps_512;	 // "86.avx512.sqrt.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfnm", 7))
+          break;
+        switch (NameR[11]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(NameR.data()+12, "dd.p", 4))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[17] != '.')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_pd_256;	 // "86.fma.vfnmadd.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_pd_512;	 // "86.fma.vfnmadd.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[17] != '.')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_ps_256;	 // "86.fma.vfnmadd.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_ps_512;	 // "86.fma.vfnmadd.ps.512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+12, "ub.p", 4))
+            break;
+          switch (NameR[16]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[17] != '.')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_pd_256;	 // "86.fma.vfnmsub.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_pd_512;	 // "86.fma.vfnmsub.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[17] != '.')
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_ps_256;	 // "86.fma.vfnmsub.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_ps_512;	 // "86.fma.vfnmsub.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 6 strings to match.
+        if (NameR[4] != 's')
+          break;
+        switch (NameR[5]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(NameR.data()+6, "42.pcmp", 7))
+            break;
+          switch (NameR[13]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "str", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpestri128;	 // "86.sse42.pcmpestri128"
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpestrm128;	 // "86.sse42.pcmpestrm128"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(NameR.data()+14, "str", 3))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpistri128;	 // "86.sse42.pcmpistri128"
+            case 'm':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpistrm128;	 // "86.sse42.pcmpistrm128"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+6, "e3.ph", 5))
+            break;
+          switch (NameR[11]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "dd.sw.128", 9))
+              break;
+            return Intrinsic::x86_ssse3_phadd_sw_128;	 // "86.ssse3.phadd.sw.128"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+12, "ub.sw.128", 9))
+              break;
+            return Intrinsic::x86_ssse3_phsub_sw_128;	 // "86.ssse3.phsub.sw.128"
+          }
+          break;
+        }
+        break;
+      case 'x':	 // 2 strings to match.
+        if (memcmp(NameR.data()+4, "op.vpermil2p", 12))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+17, ".256", 4))
+            break;
+          return Intrinsic::x86_xop_vpermil2pd_256;	 // "86.xop.vpermil2pd.256"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+17, ".256", 4))
+            break;
+          return Intrinsic::x86_xop_vpermil2ps_256;	 // "86.xop.vpermil2ps.256"
+        }
+        break;
+      }
+      break;
+    case 22:	 // 25 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 15 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 4 strings to match.
+          switch (NameR[7]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "askload.p", 9))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_maskload_pd_256;	 // "86.avx.maskload.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_maskload_ps_256;	 // "86.avx.maskload.ps.256"
+            }
+            break;
+          case 'v':	 // 2 strings to match.
+            if (memcmp(NameR.data()+8, "testnzc.p", 9))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_vtestnzc_pd_256;	 // "86.avx.vtestnzc.pd.256"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx_vtestnzc_ps_256;	 // "86.avx.vtestnzc.ps.256"
+            }
+            break;
+          }
+          break;
+        case '2':	 // 7 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'g':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "ather.", 6))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (NameR[16] != '.')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_d_d_256;	 // "86.avx2.gather.d.d.256"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_d_q_256;	 // "86.avx2.gather.d.q.256"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              if (NameR[16] != '.')
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_q_d_256;	 // "86.avx2.gather.q.d.256"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+18, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_q_q_256;	 // "86.avx2.gather.q.q.256"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+9, "askload.", 8))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx2_maskload_d_256;	 // "86.avx2.maskload.d.256"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".256", 4))
+                break;
+              return Intrinsic::x86_avx2_maskload_q_256;	 // "86.avx2.maskload.q.256"
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(NameR.data()+9, "broadcasti128", 13))
+              break;
+            return Intrinsic::x86_avx2_vbroadcasti128;	 // "86.avx2.vbroadcasti128"
+          }
+          break;
+        case '5':	 // 4 strings to match.
+          if (memcmp(NameR.data()+7, "12.", 3))
+            break;
+          switch (NameR[10]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "vtts", 4))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "2usi64", 6))
+                break;
+              return Intrinsic::x86_avx512_cvttsd2usi64;	 // "86.avx512.cvttsd2usi64"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+16, "2usi64", 6))
+                break;
+              return Intrinsic::x86_avx512_cvttss2usi64;	 // "86.avx512.cvttss2usi64"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (memcmp(NameR.data()+11, "cp14.p", 6))
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_rcp14_pd_512;	 // "86.avx512.rcp14.pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_rcp14_ps_512;	 // "86.avx512.rcp14.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 10 strings to match.
+        if (memcmp(NameR.data()+4, "se42.pcmp", 9))
+          break;
+        switch (NameR[13]) {
+        default: break;
+        case 'e':	 // 5 strings to match.
+          if (memcmp(NameR.data()+14, "stri", 4))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestria128;	 // "86.sse42.pcmpestria128"
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestric128;	 // "86.sse42.pcmpestric128"
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestrio128;	 // "86.sse42.pcmpestrio128"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestris128;	 // "86.sse42.pcmpestris128"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestriz128;	 // "86.sse42.pcmpestriz128"
+          }
+          break;
+        case 'i':	 // 5 strings to match.
+          if (memcmp(NameR.data()+14, "stri", 4))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistria128;	 // "86.sse42.pcmpistria128"
+          case 'c':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistric128;	 // "86.sse42.pcmpistric128"
+          case 'o':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistrio128;	 // "86.sse42.pcmpistrio128"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistris128;	 // "86.sse42.pcmpistris128"
+          case 'z':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistriz128;	 // "86.sse42.pcmpistriz128"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 23:	 // 25 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 16 strings to match.
+        if (memcmp(NameR.data()+4, "vx", 2))
+          break;
+        switch (NameR[6]) {
+        default: break;
+        case '.':	 // 2 strings to match.
+          if (memcmp(NameR.data()+7, "maskstore.p", 11))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_maskstore_pd_256;	 // "86.avx.maskstore.pd.256"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+19, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_maskstore_ps_256;	 // "86.avx.maskstore.ps.256"
+          }
+          break;
+        case '2':	 // 14 strings to match.
+          if (NameR[7] != '.')
+            break;
+          switch (NameR[8]) {
+          default: break;
+          case 'g':	 // 4 strings to match.
+            if (memcmp(NameR.data()+9, "ather.", 6))
+              break;
+            switch (NameR[15]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, ".p", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_d_pd_256;	 // "86.avx2.gather.d.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_d_ps_256;	 // "86.avx2.gather.d.ps.256"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              if (memcmp(NameR.data()+16, ".p", 2))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_q_pd_256;	 // "86.avx2.gather.q.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx2_gather_q_ps_256;	 // "86.avx2.gather.q.ps.256"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(NameR.data()+9, "askstore.", 9))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, ".256", 4))
+                break;
+              return Intrinsic::x86_avx2_maskstore_d_256;	 // "86.avx2.maskstore.d.256"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+19, ".256", 4))
+                break;
+              return Intrinsic::x86_avx2_maskstore_q_256;	 // "86.avx2.maskstore.q.256"
+            }
+            break;
+          case 'p':	 // 8 strings to match.
+            if (memcmp(NameR.data()+9, "broadcast", 9))
+              break;
+            switch (NameR[18]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              if (NameR[19] != '.')
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastb_128;	 // "86.avx2.pbroadcastb.128"
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastb_256;	 // "86.avx2.pbroadcastb.256"
+              }
+              break;
+            case 'd':	 // 2 strings to match.
+              if (NameR[19] != '.')
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastd_128;	 // "86.avx2.pbroadcastd.128"
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastd_256;	 // "86.avx2.pbroadcastd.256"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              if (NameR[19] != '.')
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastq_128;	 // "86.avx2.pbroadcastq.128"
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastq_256;	 // "86.avx2.pbroadcastq.256"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              if (NameR[19] != '.')
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastw_128;	 // "86.avx2.pbroadcastw.128"
+              case '2':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pbroadcastw_256;	 // "86.avx2.pbroadcastw.256"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(NameR.data()+4, "ma.vfm", 6))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ddsub.p", 7))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[19] != '.')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmaddsub_pd_256;	 // "86.fma.vfmaddsub.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmaddsub_pd_512;	 // "86.fma.vfmaddsub.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[19] != '.')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmaddsub_ps_256;	 // "86.fma.vfmaddsub.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmaddsub_ps_512;	 // "86.fma.vfmaddsub.ps.512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "ubadd.p", 7))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[19] != '.')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsubadd_pd_256;	 // "86.fma.vfmsubadd.pd.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsubadd_pd_512;	 // "86.fma.vfmsubadd.pd.512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (NameR[19] != '.')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsubadd_ps_256;	 // "86.fma.vfmsubadd.ps.256"
+            case '5':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfmsubadd_ps_512;	 // "86.fma.vfmsubadd.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "sse3.pmul.hr.sw.128", 19))
+          break;
+        return Intrinsic::x86_ssse3_pmul_hr_sw_128;	 // "86.ssse3.pmul.hr.sw.128"
+      }
+      break;
+    case 24:	 // 18 strings to match.
+      if (memcmp(NameR.data()+0, "86.", 3))
+        break;
+      switch (NameR[3]) {
+      default: break;
+      case 'a':	 // 17 strings to match.
+        switch (NameR[4]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(NameR.data()+5, "sni.aeskeygenassist", 19))
+            break;
+          return Intrinsic::x86_aesni_aeskeygenassist;	 // "86.aesni.aeskeygenassist"
+        case 'v':	 // 16 strings to match.
+          if (NameR[5] != 'x')
+            break;
+          switch (NameR[6]) {
+          default: break;
+          case '.':	 // 5 strings to match.
+            if (memcmp(NameR.data()+7, "vperm", 5))
+              break;
+            switch (NameR[12]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (memcmp(NameR.data()+13, "f128.", 5))
+                break;
+              switch (NameR[18]) {
+              default: break;
+              case 'p':	 // 2 strings to match.
+                switch (NameR[19]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vperm2f128_pd_256;	 // "86.avx.vperm2f128.pd.256"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".256", 4))
+                    break;
+                  return Intrinsic::x86_avx_vperm2f128_ps_256;	 // "86.avx.vperm2f128.ps.256"
+                }
+                break;
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+19, "i.256", 5))
+                  break;
+                return Intrinsic::x86_avx_vperm2f128_si_256;	 // "86.avx.vperm2f128.si.256"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(NameR.data()+13, "lvar.p", 6))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+20, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_vpermilvar_pd_256;	 // "86.avx.vpermilvar.pd.256"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+20, ".256", 4))
+                  break;
+                return Intrinsic::x86_avx_vpermilvar_ps_256;	 // "86.avx.vpermilvar.ps.256"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 1 string to match.
+            if (memcmp(NameR.data()+7, ".vbroadcast.ss.ps", 17))
+              break;
+            return Intrinsic::x86_avx2_vbroadcast_ss_ps;	 // "86.avx2.vbroadcast.ss.ps"
+          case '5':	 // 10 strings to match.
+            if (memcmp(NameR.data()+7, "12.", 3))
+              break;
+            switch (NameR[10]) {
+            default: break;
+            case 'g':	 // 8 strings to match.
+              if (memcmp(NameR.data()+11, "ather.", 6))
+                break;
+              switch (NameR[17]) {
+              default: break;
+              case 'd':	 // 4 strings to match.
+                if (NameR[18] != 'p')
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_dpd_512;	 // "86.avx512.gather.dpd.512"
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_dpi_512;	 // "86.avx512.gather.dpi.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_dpq_512;	 // "86.avx512.gather.dpq.512"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_dps_512;	 // "86.avx512.gather.dps.512"
+                }
+                break;
+              case 'q':	 // 4 strings to match.
+                if (NameR[18] != 'p')
+                  break;
+                switch (NameR[19]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_qpd_512;	 // "86.avx512.gather.qpd.512"
+                case 'i':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_qpi_512;	 // "86.avx512.gather.qpi.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_qpq_512;	 // "86.avx512.gather.qpq.512"
+                case 's':	 // 1 string to match.
+                  if (memcmp(NameR.data()+20, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_gather_qps_512;	 // "86.avx512.gather.qps.512"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(NameR.data()+11, "sqrt14.p", 8))
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+20, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_rsqrt14_pd_512;	 // "86.avx512.rsqrt14.pd.512"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+20, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_rsqrt14_ps_512;	 // "86.avx512.rsqrt14.ps.512"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(NameR.data()+4, "sse3.pmadd.ub.sw.128", 20))
+          break;
+        return Intrinsic::x86_ssse3_pmadd_ub_sw_128;	 // "86.ssse3.pmadd.ub.sw.128"
+      }
+      break;
+    case 25:	 // 23 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case '.':	 // 3 strings to match.
+        if (memcmp(NameR.data()+7, "vinsertf128.", 12))
+          break;
+        switch (NameR[19]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (NameR[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_vinsertf128_pd_256;	 // "86.avx.vinsertf128.pd.256"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_vinsertf128_ps_256;	 // "86.avx.vinsertf128.ps.256"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+20, "i.256", 5))
+            break;
+          return Intrinsic::x86_avx_vinsertf128_si_256;	 // "86.avx.vinsertf128.si.256"
+        }
+        break;
+      case '5':	 // 20 strings to match.
+        if (memcmp(NameR.data()+7, "12.", 3))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'm':	 // 10 strings to match.
+          if (memcmp(NameR.data()+11, "ask.", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "mp.p", 4))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cmp_pd_512;	 // "86.avx512.mask.cmp.pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cmp_ps_512;	 // "86.avx512.mask.cmp.ps.512"
+            }
+            break;
+          case 'm':	 // 4 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(NameR.data()+17, "x.p", 3))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_max_pd_512;	 // "86.avx512.mask.max.pd.512"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_max_ps_512;	 // "86.avx512.mask.max.ps.512"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(NameR.data()+17, "n.p", 3))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_min_pd_512;	 // "86.avx512.mask.min.pd.512"
+              case 's':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_min_ps_512;	 // "86.avx512.mask.min.ps.512"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 4 strings to match.
+            if (NameR[16] != 'a')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              if (memcmp(NameR.data()+18, "s.", 2))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_pabs_d_512;	 // "86.avx512.mask.pabs.d.512"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_pabs_q_512;	 // "86.avx512.mask.pabs.q.512"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(NameR.data()+18, "d.", 2))
+                break;
+              switch (NameR[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_pand_d_512;	 // "86.avx512.mask.pand.d.512"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+21, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_pand_q_512;	 // "86.avx512.mask.pand.q.512"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (memcmp(NameR.data()+11, "broadcast", 9))
+            break;
+          switch (NameR[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_pbroadcastd_512;	 // "86.avx512.pbroadcastd.512"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_pbroadcastq_512;	 // "86.avx512.pbroadcastq.512"
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (memcmp(NameR.data()+11, "catter.", 7))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (NameR[19] != 'p')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_dpd_512;	 // "86.avx512.scatter.dpd.512"
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_dpi_512;	 // "86.avx512.scatter.dpi.512"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_dpq_512;	 // "86.avx512.scatter.dpq.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_dps_512;	 // "86.avx512.scatter.dps.512"
+            }
+            break;
+          case 'q':	 // 4 strings to match.
+            if (NameR[19] != 'p')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_qpd_512;	 // "86.avx512.scatter.qpd.512"
+            case 'i':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_qpi_512;	 // "86.avx512.scatter.qpi.512"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_qpq_512;	 // "86.avx512.scatter.qpq.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_scatter_qps_512;	 // "86.avx512.scatter.qps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 26:	 // 22 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case '.':	 // 3 strings to match.
+        if (memcmp(NameR.data()+7, "vextractf128.", 13))
+          break;
+        switch (NameR[20]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (NameR[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+22, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_vextractf128_pd_256;	 // "86.avx.vextractf128.pd.256"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+22, ".256", 4))
+              break;
+            return Intrinsic::x86_avx_vextractf128_ps_256;	 // "86.avx.vextractf128.ps.256"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+21, "i.256", 5))
+            break;
+          return Intrinsic::x86_avx_vextractf128_si_256;	 // "86.avx.vextractf128.si.256"
+        }
+        break;
+      case '5':	 // 19 strings to match.
+        if (memcmp(NameR.data()+7, "12.", 3))
+          break;
+        switch (NameR[10]) {
+        default: break;
+        case 'g':	 // 4 strings to match.
+          if (memcmp(NameR.data()+11, "atherpf.", 8))
+            break;
+          switch (NameR[19]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (NameR[20] != 'p')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_gatherpf_dpd_512;	 // "86.avx512.gatherpf.dpd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_gatherpf_dps_512;	 // "86.avx512.gatherpf.dps.512"
+            }
+            break;
+          case 'q':	 // 2 strings to match.
+            if (NameR[20] != 'p')
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_gatherpf_qpd_512;	 // "86.avx512.gatherpf.qpd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_gatherpf_qps_512;	 // "86.avx512.gatherpf.qps.512"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 15 strings to match.
+          if (memcmp(NameR.data()+11, "ask.", 4))
+            break;
+          switch (NameR[15]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            if (memcmp(NameR.data()+16, "lend.", 5))
+              break;
+            switch (NameR[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_blend_d_512;	 // "86.avx512.mask.blend.d.512"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+22, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_blend_q_512;	 // "86.avx512.mask.blend.q.512"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (NameR[16]) {
+            default: break;
+            case 'o':	 // 2 strings to match.
+              if (memcmp(NameR.data()+17, "adu.", 4))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_loadu_d_512;	 // "86.avx512.mask.loadu.d.512"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_loadu_q_512;	 // "86.avx512.mask.loadu.q.512"
+              }
+              break;
+            case 'z':	 // 2 strings to match.
+              if (memcmp(NameR.data()+17, "cnt.", 4))
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_lzcnt_d_512;	 // "86.avx512.mask.lzcnt.d.512"
+              case 'q':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, ".512", 4))
+                  break;
+                return Intrinsic::x86_avx512_mask_lzcnt_q_512;	 // "86.avx512.mask.lzcnt.q.512"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 9 strings to match.
+            if (NameR[16] != 'm')
+              break;
+            switch (NameR[17]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (NameR[18] != 'x')
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 's':	 // 2 strings to match.
+                if (NameR[20] != '.')
+                  break;
+                switch (NameR[21]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmaxs_d_512;	 // "86.avx512.mask.pmaxs.d.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmaxs_q_512;	 // "86.avx512.mask.pmaxs.q.512"
+                }
+                break;
+              case 'u':	 // 2 strings to match.
+                if (NameR[20] != '.')
+                  break;
+                switch (NameR[21]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmaxu_d_512;	 // "86.avx512.mask.pmaxu.d.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmaxu_q_512;	 // "86.avx512.mask.pmaxu.q.512"
+                }
+                break;
+              }
+              break;
+            case 'i':	 // 4 strings to match.
+              if (NameR[18] != 'n')
+                break;
+              switch (NameR[19]) {
+              default: break;
+              case 's':	 // 2 strings to match.
+                if (NameR[20] != '.')
+                  break;
+                switch (NameR[21]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmins_d_512;	 // "86.avx512.mask.pmins.d.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pmins_q_512;	 // "86.avx512.mask.pmins.q.512"
+                }
+                break;
+              case 'u':	 // 2 strings to match.
+                if (NameR[20] != '.')
+                  break;
+                switch (NameR[21]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pminu_d_512;	 // "86.avx512.mask.pminu.d.512"
+                case 'q':	 // 1 string to match.
+                  if (memcmp(NameR.data()+22, ".512", 4))
+                    break;
+                  return Intrinsic::x86_avx512_mask_pminu_q_512;	 // "86.avx512.mask.pminu.q.512"
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(NameR.data()+18, "l.dq.512", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmul_dq_512;	 // "86.avx512.mask.pmul.dq.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 27:	 // 24 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx512.", 10))
+        break;
+      switch (NameR[10]) {
+      default: break;
+      case 'm':	 // 18 strings to match.
+        if (memcmp(NameR.data()+11, "ask.", 4))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "lend.p", 6))
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_blend_pd_512;	 // "86.avx512.mask.blend.pd.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_blend_ps_512;	 // "86.avx512.mask.blend.ps.512"
+          }
+          break;
+        case 'c':	 // 5 strings to match.
+          if (memcmp(NameR.data()+16, "vt", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(NameR.data()+19, "q2p", 3))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtdq2pd_512;	 // "86.avx512.mask.cvtdq2pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtdq2ps_512;	 // "86.avx512.mask.cvtdq2ps.512"
+            }
+            break;
+          case 'p':	 // 3 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (NameR[20] != '2')
+                break;
+              switch (NameR[21]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "q.512", 5))
+                  break;
+                return Intrinsic::x86_avx512_mask_cvtpd2dq_512;	 // "86.avx512.mask.cvtpd2dq.512"
+              case 'p':	 // 1 string to match.
+                if (memcmp(NameR.data()+22, "s.512", 5))
+                  break;
+                return Intrinsic::x86_avx512_mask_cvtpd2ps_512;	 // "86.avx512.mask.cvtpd2ps.512"
+              }
+              break;
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "2dq.512", 7))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtps2dq_512;	 // "86.avx512.mask.cvtps2dq.512"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "oadu.p", 6))
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_loadu_pd_512;	 // "86.avx512.mask.loadu.pd.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_loadu_ps_512;	 // "86.avx512.mask.loadu.ps.512"
+          }
+          break;
+        case 'p':	 // 5 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+17, "mpeq.", 5))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_pcmpeq_d_512;	 // "86.avx512.mask.pcmpeq.d.512"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_pcmpeq_q_512;	 // "86.avx512.mask.pcmpeq.q.512"
+            }
+            break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(NameR.data()+17, "ulu.dq.512", 10))
+              break;
+            return Intrinsic::x86_avx512_mask_pmulu_dq_512;	 // "86.avx512.mask.pmulu.dq.512"
+          case 't':	 // 2 strings to match.
+            if (memcmp(NameR.data()+17, "estm.", 5))
+              break;
+            switch (NameR[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_ptestm_d_512;	 // "86.avx512.mask.ptestm.d.512"
+            case 'q':	 // 1 string to match.
+              if (memcmp(NameR.data()+23, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_ptestm_q_512;	 // "86.avx512.mask.ptestm.q.512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "toreu.", 6))
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_storeu_d_512;	 // "86.avx512.mask.storeu.d.512"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_storeu_q_512;	 // "86.avx512.mask.storeu.q.512"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "permt.", 6))
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_vpermt_d_512;	 // "86.avx512.mask.vpermt.d.512"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_vpermt_q_512;	 // "86.avx512.mask.vpermt.q.512"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 4 strings to match.
+        if (memcmp(NameR.data()+11, "catterpf.", 9))
+          break;
+        switch (NameR[20]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (NameR[21] != 'p')
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_scatterpf_dpd_512;	 // "86.avx512.scatterpf.dpd.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_scatterpf_dps_512;	 // "86.avx512.scatterpf.dps.512"
+          }
+          break;
+        case 'q':	 // 2 strings to match.
+          if (NameR[21] != 'p')
+            break;
+          switch (NameR[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_scatterpf_qpd_512;	 // "86.avx512.scatterpf.qpd.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+23, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_scatterpf_qps_512;	 // "86.avx512.scatterpf.qps.512"
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 2 strings to match.
+        if (memcmp(NameR.data()+11, "broadcast.s", 11))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+23, ".512", 4))
+            break;
+          return Intrinsic::x86_avx512_vbroadcast_sd_512;	 // "86.avx512.vbroadcast.sd.512"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+23, ".512", 4))
+            break;
+          return Intrinsic::x86_avx512_vbroadcast_ss_512;	 // "86.avx512.vbroadcast.ss.512"
+        }
+        break;
+      }
+      break;
+    case 28:	 // 16 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx", 6))
+        break;
+      switch (NameR[6]) {
+      default: break;
+      case '.':	 // 2 strings to match.
+        if (memcmp(NameR.data()+7, "vbroadcastf128.p", 16))
+          break;
+        switch (NameR[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+24, ".256", 4))
+            break;
+          return Intrinsic::x86_avx_vbroadcastf128_pd_256;	 // "86.avx.vbroadcastf128.pd.256"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+24, ".256", 4))
+            break;
+          return Intrinsic::x86_avx_vbroadcastf128_ps_256;	 // "86.avx.vbroadcastf128.ps.256"
+        }
+        break;
+      case '2':	 // 2 strings to match.
+        if (memcmp(NameR.data()+7, ".vbroadcast.s", 13))
+          break;
+        switch (NameR[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+21, ".pd.256", 7))
+            break;
+          return Intrinsic::x86_avx2_vbroadcast_sd_pd_256;	 // "86.avx2.vbroadcast.sd.pd.256"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+21, ".ps.256", 7))
+            break;
+          return Intrinsic::x86_avx2_vbroadcast_ss_ps_256;	 // "86.avx2.vbroadcast.ss.ps.256"
+        }
+        break;
+      case '5':	 // 12 strings to match.
+        if (memcmp(NameR.data()+7, "12.mask.", 8))
+          break;
+        switch (NameR[15]) {
+        default: break;
+        case 'c':	 // 6 strings to match.
+          if (memcmp(NameR.data()+16, "vt", 2))
+            break;
+          switch (NameR[18]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (NameR[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "2udq.512", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtpd2udq_512;	 // "86.avx512.mask.cvtpd2udq.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+20, "2udq.512", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtps2udq_512;	 // "86.avx512.mask.cvtps2udq.512"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (NameR[19] != 'p')
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "2dq.512", 7))
+                break;
+              return Intrinsic::x86_avx512_mask_cvttpd2dq_512;	 // "86.avx512.mask.cvttpd2dq.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "2dq.512", 7))
+                break;
+              return Intrinsic::x86_avx512_mask_cvttps2dq_512;	 // "86.avx512.mask.cvttps2dq.512"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(NameR.data()+19, "dq2p", 4))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtudq2pd_512;	 // "86.avx512.mask.cvtudq2pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_cvtudq2ps_512;	 // "86.avx512.mask.cvtudq2ps.512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(NameR.data()+16, "toreu.p", 7))
+            break;
+          switch (NameR[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+24, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_storeu_pd_512;	 // "86.avx512.mask.storeu.pd.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+24, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_storeu_ps_512;	 // "86.avx512.mask.storeu.ps.512"
+          }
+          break;
+        case 'v':	 // 4 strings to match.
+          switch (NameR[16]) {
+          default: break;
+          case 'c':	 // 2 strings to match.
+            if (memcmp(NameR.data()+17, "vtp", 3))
+              break;
+            switch (NameR[20]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "2ps.512", 7))
+                break;
+              return Intrinsic::x86_avx512_mask_vcvtph2ps_512;	 // "86.avx512.mask.vcvtph2ps.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+21, "2ph.512", 7))
+                break;
+              return Intrinsic::x86_avx512_mask_vcvtps2ph_512;	 // "86.avx512.mask.vcvtps2ph.512"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(NameR.data()+17, "ermt.p", 6))
+              break;
+            switch (NameR[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_vpermt_pd_512;	 // "86.avx512.mask.vpermt.pd.512"
+            case 's':	 // 1 string to match.
+              if (memcmp(NameR.data()+24, ".512", 4))
+                break;
+              return Intrinsic::x86_avx512_mask_vpermt_ps_512;	 // "86.avx512.mask.vpermt.ps.512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 29:	 // 6 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx512.", 10))
+        break;
+      switch (NameR[10]) {
+      default: break;
+      case 'm':	 // 4 strings to match.
+        if (memcmp(NameR.data()+11, "ask.c", 5))
+          break;
+        switch (NameR[16]) {
+        default: break;
+        case 'o':	 // 2 strings to match.
+          if (memcmp(NameR.data()+17, "nflict.", 7))
+            break;
+          switch (NameR[24]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+25, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_conflict_d_512;	 // "86.avx512.mask.conflict.d.512"
+          case 'q':	 // 1 string to match.
+            if (memcmp(NameR.data()+25, ".512", 4))
+              break;
+            return Intrinsic::x86_avx512_mask_conflict_q_512;	 // "86.avx512.mask.conflict.q.512"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(NameR.data()+17, "ttp", 3))
+            break;
+          switch (NameR[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, "2udq.512", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_cvttpd2udq_512;	 // "86.avx512.mask.cvttpd2udq.512"
+          case 's':	 // 1 string to match.
+            if (memcmp(NameR.data()+21, "2udq.512", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_cvttps2udq_512;	 // "86.avx512.mask.cvttps2udq.512"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(NameR.data()+11, "broadcast", 9))
+          break;
+        switch (NameR[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+21, ".i32.512", 8))
+            break;
+          return Intrinsic::x86_avx512_pbroadcastd_i32_512;	 // "86.avx512.pbroadcastd.i32.512"
+        case 'q':	 // 1 string to match.
+          if (memcmp(NameR.data()+21, ".i64.512", 8))
+            break;
+          return Intrinsic::x86_avx512_pbroadcastq_i64_512;	 // "86.avx512.pbroadcastq.i64.512"
+        }
+        break;
+      }
+      break;
+    case 30:	 // 4 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx512.", 10))
+        break;
+      switch (NameR[10]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(NameR.data()+11, "ask.rndscale.p", 14))
+          break;
+        switch (NameR[25]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, ".512", 4))
+            break;
+          return Intrinsic::x86_avx512_mask_rndscale_pd_512;	 // "86.avx512.mask.rndscale.pd.512"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+26, ".512", 4))
+            break;
+          return Intrinsic::x86_avx512_mask_rndscale_ps_512;	 // "86.avx512.mask.rndscale.ps.512"
+        }
+        break;
+      case 'v':	 // 2 strings to match.
+        if (memcmp(NameR.data()+11, "broadcast.s", 11))
+          break;
+        switch (NameR[22]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(NameR.data()+23, ".pd.512", 7))
+            break;
+          return Intrinsic::x86_avx512_vbroadcast_sd_pd_512;	 // "86.avx512.vbroadcast.sd.pd.512"
+        case 's':	 // 1 string to match.
+          if (memcmp(NameR.data()+23, ".ps.512", 7))
+            break;
+          return Intrinsic::x86_avx512_vbroadcast_ss_ps_512;	 // "86.avx512.vbroadcast.ss.ps.512"
+        }
+        break;
+      }
+      break;
+    case 35:	 // 3 strings to match.
+      if (memcmp(NameR.data()+0, "86.avx512.mask.pbroadcast.", 26))
+        break;
+      switch (NameR[26]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(NameR.data()+27, ".gpr.512", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_pbroadcast_d_gpr_512;	 // "86.avx512.mask.pbroadcast.d.gpr.512"
+      case 'q':	 // 2 strings to match.
+        if (NameR[27] != '.')
+          break;
+        switch (NameR[28]) {
+        default: break;
+        case 'g':	 // 1 string to match.
+          if (memcmp(NameR.data()+29, "pr.512", 6))
+            break;
+          return Intrinsic::x86_avx512_mask_pbroadcast_q_gpr_512;	 // "86.avx512.mask.pbroadcast.q.gpr.512"
+        case 'm':	 // 1 string to match.
+          if (memcmp(NameR.data()+29, "em.512", 6))
+            break;
+          return Intrinsic::x86_avx512_mask_pbroadcast_q_mem_512;	 // "86.avx512.mask.pbroadcast.q.mem.512"
+        }
+        break;
+      }
+      break;
+    }
+    break;  // end of 'x' case.
+  }
+#endif
+
+// Global intrinsic function declaration type table.
+#ifdef GET_INTRINSIC_GENERATOR_GLOBAL
+static const unsigned IIT_Table[] = {
+  0x1F1F1F1F, 0x1F1F1F1F, (1U<<31) | 19, 0x1F1F, 0x1F1F, 0x1F1F, 0x41F1F, 
+  0x0, 0x444, 0x444, 0x444, 0x444, 0x544, 0x444, 0x444, 
+  0x544, 0x2C2C2C, 0x2C2C2C, 0x2C2C, 0x2C2C, 0x4A44A4A, 0x44, 0x4A44A4A, 
+  0x4A44A4A, 0x4A4A4A4A, 0x4A4A4A, 0x4A4A4A4A, 0x4A4A4A4A, 0x4A4A4A, 0x4A4A4A4A, 0x40, 
+  0x40, 0x40, 0x40, (1U<<31) | 332, 0x3F5, (1U<<31) | 332, 0x3F5, 0xF0F, 
+  (1U<<31) | 400, 0x2F2F2F, 0x2F2F, 0x2F2F2F, 0x5F5F0F, 0x5F5F0F, 0x6F1F, 0x5F0F, 
+  0x5F0F, 0x5F0F, 0x5F0F, 0x5F0F, 0x5F0F, 0x5F0F, 0x5F0F, 0x6F2F, 
+  0x5F0F, 0x5F0F, 0x2F2F2F, 0x1F1F1F, 0x2F2F2F, 0x6F1F, 0x2F2F2F, 0x6F1F, 
+  0x2F2F2F, 0x1F1F1F, 0x2F2F2F, 0x6F1F, 0x2F2F2F, 0x6F1F, 0x1F1F1F, 0x1F1F, 
+  0x1F1F1F, 0x1F1F, 0x1F1F, 0x1F1F, 0x1F1F1F, (1U<<31) | 1673, (1U<<31) | 1663, (1U<<31) | 1651, 
+  (1U<<31) | 1673, (1U<<31) | 1743, (1U<<31) | 1673, (1U<<31) | 1663, (1U<<31) | 1726, (1U<<31) | 1663, (1U<<31) | 1651, (1U<<31) | 1705, 
+  (1U<<31) | 1651, 0x2F2F2F, (1U<<31) | 412, 0x552C, (1U<<31) | 400, 0x2F2F, (1U<<31) | 454, (1U<<31) | 400, 
+  0x2F2F2F, 0x6F2F, 0x6F0F, 0x6F0F, 0x4F0F, 0x4F0F, 0x4F0F, 0x2F2F2F, 
+  (1U<<31) | 407, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x6F0F, 0x2F2F2F, 0x2F2F2F, 0x6F0F, 
+  (1U<<31) | 412, 0xF0F, 0xF0F0F, 0xF0F0F, (1U<<31) | 412, 0x445, 0xF0F, 0xF0F0F, 
+  0xF0F0F, (1U<<31) | 454, (1U<<31) | 454, 0xF0F0F, 0xF0F0F, (1U<<31) | 454, (1U<<31) | 454, 0xF0F0F, 
+  (1U<<31) | 14, (1U<<31) | 14, 0x2F2F2F, 0xF0F0F, 0xF0F0F, (1U<<31) | 646, 0x7F2F2F0, (1U<<31) | 1629, 
+  (1U<<31) | 1639, 0x7F2F2F0, 0x7F52F2F0, (1U<<31) | 1629, (1U<<31) | 1681, (1U<<31) | 1639, (1U<<31) | 1692, (1U<<31) | 400, 
+  0xF0F0F, 0x2F2C2F, 0x2F2C2C2F, (1U<<31) | 368, (1U<<31) | 353, 0x2F2C2F2F, (1U<<31) | 379, (1U<<31) | 366, 
+  (1U<<31) | 351, 0x2F2F2F, 0x6F2F, 0x6F0F, 0x6F0F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 
+  0x2F2F2F, 0x6F0F, 0x2F2F2F, 0x2F2F2F, 0x6F0F, (1U<<31) | 412, 0xF0F0F, 0xF0F0F, 
+  (1U<<31) | 454, 0xF0F0F, (1U<<31) | 454, 0xF0F0F, (1U<<31) | 14, 0x2F2F, 0x2F2F2F, 0xF0F0F, 
+  0x2F2F, 0xF0F0F, (1U<<31) | 646, 0xF0F0F, 0x52F56F2F, 0x45F0F, 0x45F0F, 0x7A3A, 
+  0x44F1F, 0x44F1F, 0x3A7A, 0x42F2F2F, 0x42F2F2F, 0xF0F, 0xF0F0F, 0x1F1F1F, 
+  0x87, 0x2E554, 0x3F54, 0x2E554, 0x3F54, 0xF0F0F, 0x2E2E, (1U<<31) | 569, 
+  0x4444440, 0x4444440, 0x0, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x40, 0x40, 0x4, 0x40, 0x40, 0x3F4, (1U<<31) | 326, 
+  0x3F4, (1U<<31) | 326, 0x4444440, 0x4444440, 0x444440, 0x444440, 0x444444, 0x444444, 
+  0x2C2C2C, 0x2C2C2C, 0x2C2C, 0x2C2C, 0x4A44A4A, 0x44, 0x4A44A4A, 0x4A44A4A, 
+  0x4A4A4A4A, 0x4A4A4A, 0x4A4A4A4A, 0x4A4A4A4A, 0x4A4A4A, 0x4A4A4A4A, 0x2F2F2F, 0x2F2F2F, 
+  0x2F2F, 0x6F6F2F, 0x6F6F2F, 0x2F2F2F2F, 0x2F2F, 0x2F2F, 0x2F2F, 0x6F2F, 
+  0x6F2F, 0x45F0F, 0x45F0F, 0x7A3A, 0x44F1F, 0x44F1F, 0x3A7A, 0x6F2F, 
+  0x6F2F, 0x6F2F, 0x6F2F, 0x6F2F, 0x6F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 
+  0x2F2F2F, 0x42E2F, (1U<<31) | 613, (1U<<31) | 709, (1U<<31) | 602, (1U<<31) | 735, (1U<<31) | 589, (1U<<31) | 767, 
+  0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 412, (1U<<31) | 412, 
+  (1U<<31) | 412, 0x2F2F2F, 0x6F2F2F, 0x6F2F2F, 0x2F2F2F, 0x6F2F, 0x6F2F, 0x2F2F2F, 
+  0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, (1U<<31) | 412, 
+  (1U<<31) | 395, (1U<<31) | 395, (1U<<31) | 395, 0x2F2F, 0x2F2F2F, (1U<<31) | 400, (1U<<31) | 400, (1U<<31) | 400, 
+  0x2F2F2F, 0x2F2F2F, (1U<<31) | 400, (1U<<31) | 400, (1U<<31) | 400, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 
+  0x2F2F2F, 0x2F2F2F, (1U<<31) | 400, 0x2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x2F2F, 
+  0x2F2F, 0x2F2F, 0x2F2F, 0x2F2F, 0x2F2F, (1U<<31) | 400, 0x2F2F2F, 0x2F2F2F, 
+  0x2F2F, 0x2F2F2F, (1U<<31) | 400, 0x2F2F2F2F, 0x2F2F2F, 0x2F2F2F, 0x42F2E0, 0x42F2F2E0, 
+  (1U<<31) | 699, (1U<<31) | 622, (1U<<31) | 723, (1U<<31) | 633, (1U<<31) | 753, 0x2B2B2B, 0x2B2B2B2B, (1U<<31) | 315, 
+  (1U<<31) | 313, 0x2B2B2B2B, (1U<<31) | 315, (1U<<31) | 313, (1U<<31) | 311, 0x444, 0x444, 0x44, 
+  0x40, 0x444, 0x3F44, 0x2E444, 0x3F44, 0x2E444, 0x2E, 0x40, 
+  0x444, 0x1F7, 0x1F7, 0xF0F, 0x1F1F, 0x2E2E0, 0x31F, 0x1F3, 
+  0x445F1F, 0x444F1F, 0x444F1F, 0x445F0F, 0x444F0F, 0x444F0F, 0x445F0F, 0x444F0F, 
+  0x444F0F, 0x1F1F1F, 0x1F1F, 0x10F0F, 0xF0F, 0x10F0F, 0x0, (1U<<31) | 1818, 
+  (1U<<31) | 1813, 0x0, 0x0, 0x42E, 0x2E40, 0x2E50, 0x40, 0x2E0, 
+  0x2E0, 0x2E, 0x2E4, 0x2E4, 0x0, 0x1F1F, 0x1F1F, 0xF0F0F, 
+  (1U<<31) | 1830, (1U<<31) | 1822, (1U<<31) | 1838, 0x1F1F, 0x1F1F, 0x4, 0x1F1F1F1F, 0x1F1F1F1F, 
+  0x42E, 0x2EE2E2E, 0x2E2EE0, 0x2EE2E2E0, 0x44, 0x55, 0x44, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x555, 0x555, 0x444, 
+  0x545, 0x444, 0x444, 0x555, 0x44, 0x44, 0x444, 0x444, 
+  0x444, 0x444, 0x445, 0x445, 0x444, 0x555, 0x444, 0x555, 
+  0x444, 0x555, 0x444, 0x555, 0x44, 0x55, 0x44, 0x44, 
+  0x55, 0x444, 0x444, 0x555, 0x54, 0x54, 0x44, 0x44, 
+  0x44, 0x44, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x555, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x44, 0x44, 0x44, 0x45, 0x44, 
+  0x444, 0x444, 0x55, 0x45, 0x44, 0x55, 0x55, 0x55, 
+  0x55, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x551, 0x551, 0x551, 
+  0x551, 0x551, 0x551, 0x551, 0x551, 0x55, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x5555, 0x555, 0x5555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x444, 0x555, 0x44, 0x44, 
+  0x444, 0x555, 0x445, 0x445, 0x541, 0x441, 0x441, 0x441, 
+  0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 
+  0x441, 0x445, 0x445, 0x444, 0x444, 0x444, 0x444, 0x555, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x451, 0x551, 0x451, 0x551, 0x451, 0x451, 0x451, 0x451, 
+  0x451, 0x451, 0x451, 0x451, 0x4555, 0x4555, 0x4555, 0x4555, 
+  0x4555, 0x4555, 0x4555, 0x4555, 0x554, 0x41, 0x441, 0x441, 
+  0x41, 0x441, 0x441, 0x441, 0x441, 0x441, 0x551, 0x441, 
+  0x441, 0x441, 0x441, 0x551, 0x441, 0x441, 0x551, 0x441, 
+  0x441, 0x45, 0x4444, 0x4444, 0x4444, 0x4444, 0x41, 0x441, 
+  0x441, 0x41, 0x44, 0x41, 0x444, 0x5545, 0x441, 0x4441, 
+  0x4441, 0x4441, 0x4441, 0x441, 0x441, 0x441, 0x441, 0x441, 
+  0x441, 0x441, 0x441, 0x441, 0x441, 0x441, 0x4441, 0x4441, 
+  0x4441, 0x4441, 0x58, 0x57, 0x85, 0x85, 0x87, 0x85, 
+  0x85, 0x84, 0x84, 0x84, 0x84, 0x75, 0x75, 0x78, 
+  0x75, 0x75, 0x74, 0x74, 0x74, 0x74, 0x58, 0x57, 
+  0x48, 0x47, 0x48, 0x47, 0x888, 0x481, 0x881, 0x881, 
+  0x881, 0x881, 0x888, 0x888, 0x88, 0x8888, 0x8888, 0x48888, 
+  0x8888, 0x8888, 0x48, 0x48, 0x888, 0x888, 0x888, 0x888, 
+  0x777, 0x471, 0x771, 0x771, 0x771, 0x771, 0x777, 0x777, 
+  0x77, 0x7777, 0x7777, 0x47777, 0x7777, 0x7777, 0x47, 0x47, 
+  0x777, 0x777, 0x777, 0x777, 0x4444, 0x4444, 0x4455, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x4455, 0x445, 0x445, 0x444, 0x444, 
+  0x444, 0x444, 0x445, 0x445, 0x445, 0x445, 0x4455, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x4455, 0x444, 0x445, 0x4455, 0x4455, 
+  0x445, 0x444, 0x444, 0x444, 0x444, 0x4444, 0x4444, 0x4444, 
+  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 
+  0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x445, 0x445, 0x445, 0x445, 0x445, 
+  0x445, 0x445, 0x445, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x445, 0x445, 0x445, 0x445, 0x445, 
+  0x445, 0x445, 0x445, 0x444, 0x444, 0x444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x444, 
+  0x444, 0x444, 0x444, 0x444, 0x444, 0x444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x445, 
+  0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x445, 0x4455, 
+  0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x4455, 0x444, 
+  0x4444, 0x4444, 0x4444, 0x555, 0x555, 0x5555, 0x5555, 0x555, 
+  0x555, 0x555, 0x555, 0x5555, 0x5555, 0x554, 0x554, 0x555, 
+  0x555, 0x4455, 0x5555, 0x5555, 0x5555, 0x4455, 0x4455, 0x4455, 
+  0x4455, 0x555, 0x555, 0x445, 0x444, 0x445, 0x444, 0x445, 
+  0x445, 0x554, 0x554, 0x5555, 0x5555, 0x5555, 0x5555, 0x555, 
+  0x555, 0x555, 0x555, 0x4555, 0x455, 0x454, 0x5555, 0x555, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x454, 0x454, 0x454, 
+  0x454, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x445, 0x4455, 0x445, 0x4455, 
+  0x5555, 0x5555, 0x555, 0x555, 0x5555, 0x5555, 0x555, 0x555, 
+  0x4444, 0x4444, 0x4444, 0x5555, 0x5555, 0x555, 0x4455, 0x4455, 
+  0x445, 0x445, 0x5555, 0x5555, 0x555, 0x555, 0x4444, 0x455, 
+  0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 
+  0x4444, 0x4444, 0x444, 0x4444, 0x455, 0x455, 0x455, 0x4555, 
+  0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 
+  0x4444, 0x444, 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 
+  0x4555, 0x455, 0x455, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x444, 0x444, 0x454, 0x455, 0x455, 0x455, 0x4555, 0x4555, 
+  0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x444, 0x454, 0x455, 0x455, 0x44, 0x55, 0x44, 0x54, 
+  0x44, 0x54, 0x44, 0x44, 0x54, 0x444, 0x444, 0x44, 
+  0x54, 0x44, 0x54, 0x55, 0x4444, 0x544, 0x4455, 0x555, 
+  0x44444, 0x5444, 0x44555, 0x5555, 0x55, 0x555, 0x455, 0x4555, 
+  0x4555, 0x4555, 0x4555, 0x4555, 0x444, 0x4444, 0x4444, 0x4444, 
+  0x4444, 0x455, 0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 
+  0x4555, 0x444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x455, 
+  0x455, 0x455, 0x4555, 0x4555, 0x4555, 0x4555, 0x4555, 0x444, 
+  0x4444, 0x4444, 0x4444, 0x4444, 0x455, 0x455, 0x445, 0x554, 
+  0x444, 0x444, 0x555, 0x555, 0x555, 0x555, 0x44, 0x44, 
+  0x44444, 0x44444, 0x44444, 0x44444, 0x444, 0x444, 0x441, 0x441, 
+  0x4555, 0x4555, 0x455, 0x455, 0x4555, 0x54, 0x54, 0x54, 
+  0x55, 0x54, 0x55, 0x54, 0x55, 0x54, 0x55, 0x44, 
+  0x45, 0x4555, 0x4555, 0x45, 0x45, 0x54, 0x555, 0x54, 
+  0x555, 0x45, 0x45, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 
+  0x444, 0x454, 0x54, 0x4444, 0x544, 0x4455, 0x555, 0x444, 
+  0x441, 0x441, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x444, 
+  0x4444, 0x4444, 0x4444, 0x4455, 0x44555, 0x555, 0x555, 0x555, 
+  0x555, 0x555, 0x555, 0x454, 0x454, 0x54, 0x455, 0x44, 
+  0x442E2E2E, 0x2E2E2E0, (1U<<31) | 338, (1U<<31) | 339, 0x2E50, 0x2E50, 0x1F1F, 0x1F1F, 
+  0x1F1F, 0x42E0, (1U<<31) | 29, (1U<<31) | 29, 0x144F23F0, 0x3939, 0x2A2A, 0x44, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x393939, 0x393939, 0x444, 0x393939, 
+  0x393939, 0x444, 0x444, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 
+  0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x444, 
+  0x393939, 0x2A2A2A, 0x393939, 0x2A2A2A, 0x2A2A2A, 0x2A2A2A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x444, 0x2C2C2C, 
+  0x42C2C, 0x4444, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x4444, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 
+  0x45959, 0x43B3B, 0x44A4A, 0x2C2C2C2C, 0x59595959, 0x3B3B3B3B, 0x4A4A4A4A, 0x42C2C2C, 
+  0x4595959, 0x43B3B3B, 0x44A4A4A, 0x2C2C2C2C, 0x59595959, 0x3B3B3B3B, 0x4A4A4A4A, 0x42C2C2C, 
+  0x4595959, 0x43B3B3B, 0x44A4A4A, 0x44, 0x2C2C2C2C, 0x42C2C2C, 0x2C2C2C2C, 0x42C2C2C, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C4, 0x594, 0x3B4, 0x2C4, 0x4A4, 0x4, 0x2C2C2C2C, 0x42C2C2C, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C4, 0x594, 0x3B4, 0x2C4, 0x4A4, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x44, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 
+  0x43B3B, 0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 
+  0x43B3B, 0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x39390, 0x39390, 
+  0x39390, 0x2A2A4, 0x2A2A4, 0x2A2A4, 0x2A2A4, 0x2A2A4, 0x2A2A4, 0x2A2A0, 
+  0x2A2A0, 0x2A2A0, 0x42C4, 0x4595, 0x43B4, 0x44A4, 0x42C4, 0x4595, 
+  0x43B4, 0x44A4, 0x440, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 
+  0x595959, 0x3B3B3B, 0x4A4A4A, 0x4555, 0x4A4A59, 0x2C2C3B, 0x3B3B4A, 0x4A4A59, 
+  0x2C2C3B, 0x3B3B4A, 0x393955, 0x4A4A5959, 0x2C2C3B3B, 0x3B3B4A4A, 0x4A4A5959, 0x2C2C3B3B, 
+  0x3B3B4A4A, 0x393955, 0x4455, 0x393955, 0x393955, 0x2A2A55, 0x2A2A55, 0x393955, 
+  0x393955, 0x393955, 0x4455, 0x393955, 0x393955, 0x2A2A55, 0x2A2A55, 0x4A4A5959, 
+  0x2C2C3B3B, 0x3B3B4A4A, 0x4A4A5959, 0x2C2C3B3B, 0x3B3B4A4A, 0x393955, 0x454, 0x454, 
+  0x454, 0x454, 0x454, 0x454, 0x898989, 0x7A7A7A, 0x898959, 0x7A7A4A, 
+  0x898959, 0x7A7A4A, 0x8959, 0x7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 
+  0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 
+  0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898989, 0x7A7A7A, 
+  0x7A7A6B, 0x89897A, 0x598989, 0x4A7A7A, 0x7A89, 0x6B7A, 0x7A89, 0x6B7A, 
+  0x5989, 0x4A7A, 0x5989, 0x4A7A, 0x4A89, 0x3B7A, 0x4A89, 0x3B7A, 
+  0x42C, 0x559, 0x43B, 0x44A, 0x8989, 0x7A7A, (1U<<31) | 1756, 0x7A7A7A7A, 
+  0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 
+  (1U<<31) | 1756, 0x7A7A7A7A, 0x898989, 0x7A7A7A, 0x8989, 0x7A7A, 0x8989, 0x7A7A, 
+  0x8989, 0x7A7A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 
+  0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x8989, 0x7A7A, 
+  0x898989, 0x7A7A7A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 
+  0x898959, 0x7A7A4A, 0x898959, 0x7A7A4A, 0x8959, 0x7A4A, 0x8959, 0x7A4A, 
+  0x7A7A3B, 0x89894A, 0x8959, 0x7A4A, 0x8959, 0x7A4A, 0x4A4A59, 0x2C2C3B, 
+  0x3B3B4A, 0x4A4A59, 0x2C2C3B, 0x3B3B4A, 0x4A4A59, 0x2C2C3B, 0x3B3B4A, 0x4A4A59, 
+  0x2C2C3B, 0x3B3B4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 
+  0x3B3B3B, 0x4A4A4A, 0x442C2C, 0x545959, 0x443B3B, 0x444A4A, 0x444, 0x2C42C2C, 
+  0x5945959, 0x3B43B3B, 0x4A44A4A, 0x42E4, 0x42E2C, 0x42E59, 0x42E3B, 0x42E4A, 
+  0x42C, 0x459, 0x43B, 0x44A, 0x42E4, 0x4444, 0x42E4, 0x4455, 
+  0x3B3B3B3B, 0x4A4A4A4A, 0x3B3B3B3B, 0x4A4A4A4A, 0x4455, 0x2C2C2C2C, 0x59595959, 0x3B3B3B3B, 
+  0x4A4A4A4A, 0x393955, 0x393955, 0x393955, 0x393955, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 
+  0x44A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 
+  0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x444, 0x2C2C, 0x4455, 
+  0x3B3B3B3B, 0x4A4A4A4A, 0x3B3B3B3B, 0x4A4A4A4A, 0x4455, 0x2C2C2C2C, 0x59595959, 0x3B3B3B3B, 
+  0x4A4A4A4A, 0x455, 0x393939, 0x3B3B3B, 0x4A4A4A, 0x393939, 0x39394, 0x39394, 
+  0x392A39, 0x392A39, 0x393939, 0x444, 0x393939, 0x444, 0x3B3B3B, 0x4A4A4A, 
+  0x393955, 0x393955, 0x445, 0x445, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 
+  0x2C2C, 0x5959, 0x3B3B, 0x4A4A, 0x2C2C, 0x5959, 0x3B3B, 0x4A4A, 
+  0x2C2C2C, 0x42C2C, 0x2C2C2C, 0x42C2C, 0x393939, 0x2C2C2C, 0x595959, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C, 0x5959, 0x3B3B, 
+  0x4A4A, 0x393939, 0x2A2A2A, 0x394, 0x394, 0x2A39, 0x2A39, 0x2A39, 
+  0x2A39, 0x2A39, 0x2A39, 0x2A39, 0x2A39, 0x39392A, 0x44439, 0x44439, 
+  0x4439, 0x39392A, 0x4439, 0x39392A, 0x4444, 0x2A4, 0x44, 0x439, 
+  0x42A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 
+  0x44A4A, 0x42C2C, 0x43B3B, 0x44A4A, 0x455, 0x43939, 0x42A2A, 0x43939, 
+  0x444, 0x43939, 0x42A2A, 0x43939, 0x42A2A, 0x444, 0x43939, 0x42A2A, 
+  0x42C2C2C, 0x4595959, 0x43B3B3B, 0x44A4A4A, 0x42C2C2C, 0x4595959, 0x43B3B3B, 0x44A4A4A, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 0x44A4A, 
+  0x42E2C0, 0x42E590, 0x42E3B0, 0x42E4A0, 0x393939, 0x393939, 0x444, 0x393939, 
+  0x393939, 0x444, 0x444, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 
+  0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 
+  0x595959, 0x3B3B3B, 0x4A4A4A, 0x393939, 0x2A2A2A, 0x393939, 0x2A2A2A, 0x2A2A2A, 
+  0x2A2A2A, 0x2C2C2C, 0x595959, 0x3B3B3B, 0x4A4A4A, 0x42C2C, 0x45959, 0x43B3B, 
+  0x44A4A, 0x2C2C2C2C, 0x59595959, 0x3B3B3B3B, 0x4A4A4A4A, 0x440, 0x2C2C2C, 0x42C2C, 
+  0x1F1F, 0x44, 0x55, 0x888, 0x777, 0x777, 0x888, 0x777, 
+  0x777, 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 0x73F7, 
+  0x43F4, 0x43F4, 0x0, 0x44, 0x44, 0x44, 0x85, 0x74, 
+  0x47, 0x58, 0x44, 0x55, 0x88, 0x77, 0x77, 0x44, 
+  0x54, 0x3F0, 0x3F0, 0x77, 0x77, 0x87, 0x87, 0x87, 
+  0x87, 0x87, 0x87, 0x87, 0x87, 0x84, 0x84, 0x84, 
+  0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x84, 
+  0x84, 0x84, 0x84, 0x85, 0x85, 0x85, 0x85, 0x777, 
+  0x777, 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 0x888, 
+  0x777, 0x777, 0x888, 0x777, 0x777, 0x88, 0x77, 0x77, 
+  0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 
+  0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 
+  0x75, 0x75, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 
+  0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 
+  0x75, 0x75, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 
+  0x8888, 0x7777, 0x7777, 0x8888, 0x7777, 0x7777, 0x8888, 0x7777, 
+  0x7777, 0x8888, 0x7777, 0x7777, 0x888, 0x777, 0x777, 0x888, 
+  0x777, 0x777, 0x37, 0x48, 0x48, 0x48, 0x48, 0x47, 
+  0x47, 0x47, 0x47, 0x2E1, 0x2E1, 0x2E1, 0x2E1, 0x51, 
+  0x51, 0x51, 0x7F1F, 0x7F0F, 0x7F3F, 0x7F1F, 0x7F0F, 0x7F3F, 
+  0x88, 0x77, 0x77, 0x58, 0x58, 0x58, 0x58, 0x57, 
+  0x57, 0x57, 0x57, 0x448, 0x444, 0x555, 0x444, 0x555, 
+  0x0, 0x0, 0x0, 0x444, 0x555, 0x444, 0x555, 0x88, 
+  0x77, 0x33, 0x44, 0x55, 0x7F3F, 0x444, 0x444, 0x888, 
+  0x777, 0x777, 0x888, 0x777, 0x777, 0x888, 0x777, 0x777, 
+  0x888, 0x777, 0x777, 0x444, 0x555, 0x444, 0x555, 0x44, 
+  0x54, 0x4444, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 0x7F3F, 
+  0x7F3F, 0x7F3F, 0x7F3F, 0x88, 0x88, 0x77, 0x77, 0x88, 
+  0x77, 0x77, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x3F4, 0x444, 0x455, 
+  0x455, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 0x4444, 
+  0x4444, 0x88, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 
+  0x77, 0x88, 0x77, 0x77, 0x88, 0x77, 0x77, 0x88, 
+  0x77, 0x77, 0x88, 0x77, 0x77, 0x4453, 0x4453, 0x4453, 
+  0x4454, 0x4454, 0x4454, 0x4455, 0x4455, 0x4455, 0x4453, 0x4453, 
+  0x4453, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 907, (1U<<31) | 907, (1U<<31) | 907, (1U<<31) | 924, 
+  (1U<<31) | 924, (1U<<31) | 924, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 882, (1U<<31) | 882, (1U<<31) | 882, 
+  (1U<<31) | 898, (1U<<31) | 898, (1U<<31) | 898, (1U<<31) | 882, (1U<<31) | 882, (1U<<31) | 882, 0x453, 0x453, 
+  0x453, 0x454, 0x454, 0x454, 0x455, 0x455, 0x455, 0x453, 
+  0x453, 0x453, (1U<<31) | 987, (1U<<31) | 987, (1U<<31) | 987, (1U<<31) | 1001, (1U<<31) | 1001, (1U<<31) | 1001, 
+  (1U<<31) | 1016, (1U<<31) | 1016, (1U<<31) | 1016, (1U<<31) | 987, (1U<<31) | 987, (1U<<31) | 987, (1U<<31) | 979, (1U<<31) | 979, 
+  (1U<<31) | 979, (1U<<31) | 993, (1U<<31) | 993, (1U<<31) | 993, (1U<<31) | 979, (1U<<31) | 979, (1U<<31) | 979, 0x44453, 
+  0x44453, 0x44453, 0x44454, 0x44454, 0x44454, 0x44455, 0x44455, 0x44455, 
+  0x44453, 0x44453, 0x44453, (1U<<31) | 816, (1U<<31) | 816, (1U<<31) | 816, (1U<<31) | 834, (1U<<31) | 834, 
+  (1U<<31) | 834, (1U<<31) | 853, (1U<<31) | 853, (1U<<31) | 853, (1U<<31) | 816, (1U<<31) | 816, (1U<<31) | 816, (1U<<31) | 806, 
+  (1U<<31) | 806, (1U<<31) | 806, (1U<<31) | 824, (1U<<31) | 824, (1U<<31) | 824, (1U<<31) | 806, (1U<<31) | 806, (1U<<31) | 806, 
+  0x4453, 0x4453, 0x4453, 0x4454, 0x4454, 0x4454, 0x4455, 0x4455, 
+  0x4455, 0x4453, 0x4453, 0x4453, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 907, 
+  (1U<<31) | 907, (1U<<31) | 907, (1U<<31) | 924, (1U<<31) | 924, (1U<<31) | 924, (1U<<31) | 891, (1U<<31) | 891, (1U<<31) | 891, 
+  (1U<<31) | 882, (1U<<31) | 882, (1U<<31) | 882, (1U<<31) | 898, (1U<<31) | 898, (1U<<31) | 898, (1U<<31) | 882, (1U<<31) | 882, 
+  (1U<<31) | 882, 0x44453, 0x44453, 0x44453, 0x44454, 0x44454, 0x44454, 0x44455, 
+  0x44455, 0x44455, 0x44453, 0x44453, 0x44453, (1U<<31) | 816, (1U<<31) | 816, (1U<<31) | 816, 
+  (1U<<31) | 834, (1U<<31) | 834, (1U<<31) | 834, (1U<<31) | 853, (1U<<31) | 853, (1U<<31) | 853, (1U<<31) | 816, (1U<<31) | 816, 
+  (1U<<31) | 816, (1U<<31) | 806, (1U<<31) | 806, (1U<<31) | 806, (1U<<31) | 824, (1U<<31) | 824, (1U<<31) | 824, (1U<<31) | 806, 
+  (1U<<31) | 806, (1U<<31) | 806, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 
+  0x34450, 0x34450, 0x34450, 0x44450, 0x44450, 0x44450, 0x54450, 0x54450, 
+  0x54450, 0x34450, 0x34450, 0x34450, 0x334450, 0x334450, 0x334450, 0x444450, 
+  0x444450, 0x444450, 0x554450, 0x554450, 0x554450, 0x334450, 0x334450, 0x334450, 
+  0x33334450, 0x33334450, 0x33334450, 0x44444450, 0x44444450, 0x44444450, 0x33334450, 0x33334450, 
+  0x33334450, 0x3450, 0x3450, 0x3450, 0x4450, 0x4450, 0x4450, 0x5450, 
+  0x5450, 0x5450, 0x3450, 0x3450, 0x3450, 0x33450, 0x33450, 0x33450, 
+  0x44450, 0x44450, 0x44450, 0x55450, 0x55450, 0x55450, 0x33450, 0x33450, 
+  0x33450, 0x3333450, 0x3333450, 0x3333450, 0x4444450, 0x4444450, 0x4444450, 0x3333450, 
+  0x3333450, 0x3333450, 0x344450, 0x344450, 0x344450, 0x444450, 0x444450, 0x444450, 
+  0x544450, 0x544450, 0x544450, 0x344450, 0x344450, 0x344450, 0x3344450, 0x3344450, 
+  0x3344450, 0x4444450, 0x4444450, 0x4444450, 0x5544450, 0x5544450, 0x5544450, 0x3344450, 
+  0x3344450, 0x3344450, (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 789, (1U<<31) | 789, (1U<<31) | 789, 
+  (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 419, 0x34450, 0x34450, 0x34450, 0x44450, 0x44450, 
+  0x44450, 0x54450, 0x54450, 0x54450, 0x34450, 0x34450, 0x34450, 0x334450, 
+  0x334450, 0x334450, 0x444450, 0x444450, 0x444450, 0x554450, 0x554450, 0x554450, 
+  0x334450, 0x334450, 0x334450, 0x33334450, 0x33334450, 0x33334450, 0x44444450, 0x44444450, 
+  0x44444450, 0x33334450, 0x33334450, 0x33334450, 0x344450, 0x344450, 0x344450, 0x444450, 
+  0x444450, 0x444450, 0x544450, 0x544450, 0x544450, 0x344450, 0x344450, 0x344450, 
+  0x3344450, 0x3344450, 0x3344450, 0x4444450, 0x4444450, 0x4444450, 0x5544450, 0x5544450, 
+  0x5544450, 0x3344450, 0x3344450, 0x3344450, (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 789, 
+  (1U<<31) | 789, (1U<<31) | 789, (1U<<31) | 419, (1U<<31) | 419, (1U<<31) | 419, 0x34450, 0x44450, 0x34450, 
+  0x334450, 0x444450, 0x334450, 0x33334450, 0x44444450, 0x33334450, 0x3450, 0x4450, 
+  0x3450, 0x33450, 0x44450, 0x33450, 0x3333450, 0x4444450, 0x3333450, 0x344450, 
+  0x444450, 0x344450, 0x3344450, 0x4444450, 0x3344450, (1U<<31) | 419, (1U<<31) | 789, (1U<<31) | 419, 
+  0x34450, 0x44450, 0x34450, 0x334450, 0x444450, 0x334450, 0x33334450, 0x44444450, 
+  0x33334450, 0x344450, 0x444450, 0x344450, 0x3344450, 0x4444450, 0x3344450, (1U<<31) | 419, 
+  (1U<<31) | 789, (1U<<31) | 419, 0x55, (1U<<31) | 1286, (1U<<31) | 1274, (1U<<31) | 1274, (1U<<31) | 1204, (1U<<31) | 1193, 
+  (1U<<31) | 1193, (1U<<31) | 1130, (1U<<31) | 931, (1U<<31) | 1120, (1U<<31) | 914, (1U<<31) | 1120, (1U<<31) | 914, (1U<<31) | 1330, 
+  (1U<<31) | 1319, (1U<<31) | 1319, (1U<<31) | 1244, (1U<<31) | 1234, (1U<<31) | 1234, (1U<<31) | 1166, (1U<<31) | 1022, (1U<<31) | 1157, 
+  (1U<<31) | 1007, (1U<<31) | 1157, (1U<<31) | 1007, (1U<<31) | 1476, (1U<<31) | 1461, (1U<<31) | 1461, (1U<<31) | 1286, (1U<<31) | 1274, 
+  (1U<<31) | 1274, (1U<<31) | 1204, (1U<<31) | 861, (1U<<31) | 1193, (1U<<31) | 842, (1U<<31) | 1193, (1U<<31) | 842, (1U<<31) | 1532, 
+  (1U<<31) | 1518, (1U<<31) | 1518, (1U<<31) | 1330, (1U<<31) | 1319, (1U<<31) | 1319, (1U<<31) | 1244, (1U<<31) | 931, (1U<<31) | 1234, 
+  (1U<<31) | 914, (1U<<31) | 1234, (1U<<31) | 914, (1U<<31) | 1592, (1U<<31) | 1575, (1U<<31) | 1575, (1U<<31) | 1424, (1U<<31) | 1412, 
+  (1U<<31) | 1412, (1U<<31) | 1330, (1U<<31) | 861, (1U<<31) | 1319, (1U<<31) | 842, (1U<<31) | 1319, (1U<<31) | 842, (1U<<31) | 1376, 
+  (1U<<31) | 1363, (1U<<31) | 1363, (1U<<31) | 1286, (1U<<31) | 1274, (1U<<31) | 1274, (1U<<31) | 1424, (1U<<31) | 1412, (1U<<31) | 1412, 
+  (1U<<31) | 1330, (1U<<31) | 1319, (1U<<31) | 1319, (1U<<31) | 1298, (1U<<31) | 1263, (1U<<31) | 1263, (1U<<31) | 1215, (1U<<31) | 1183, 
+  (1U<<31) | 1183, (1U<<31) | 1140, (1U<<31) | 941, (1U<<31) | 1111, (1U<<31) | 898, (1U<<31) | 1111, (1U<<31) | 898, (1U<<31) | 1341, 
+  (1U<<31) | 1309, (1U<<31) | 1309, (1U<<31) | 1254, (1U<<31) | 1225, (1U<<31) | 1225, (1U<<31) | 1175, (1U<<31) | 1031, (1U<<31) | 1149, 
+  (1U<<31) | 993, (1U<<31) | 1149, (1U<<31) | 993, (1U<<31) | 1491, (1U<<31) | 1447, (1U<<31) | 1447, (1U<<31) | 1298, (1U<<31) | 1263, 
+  (1U<<31) | 1263, (1U<<31) | 1215, (1U<<31) | 872, (1U<<31) | 1183, (1U<<31) | 824, (1U<<31) | 1183, (1U<<31) | 824, (1U<<31) | 1546, 
+  (1U<<31) | 1505, (1U<<31) | 1505, (1U<<31) | 1341, (1U<<31) | 1309, (1U<<31) | 1309, (1U<<31) | 1254, (1U<<31) | 941, (1U<<31) | 1225, 
+  (1U<<31) | 898, (1U<<31) | 1225, (1U<<31) | 898, (1U<<31) | 1609, (1U<<31) | 1559, (1U<<31) | 1559, (1U<<31) | 1436, (1U<<31) | 1401, 
+  (1U<<31) | 1401, (1U<<31) | 1341, (1U<<31) | 872, (1U<<31) | 1309, (1U<<31) | 824, (1U<<31) | 1309, (1U<<31) | 824, (1U<<31) | 1389, 
+  (1U<<31) | 1351, (1U<<31) | 1351, (1U<<31) | 1298, (1U<<31) | 1263, (1U<<31) | 1263, (1U<<31) | 1436, (1U<<31) | 1401, (1U<<31) | 1401, 
+  (1U<<31) | 1341, (1U<<31) | 1309, (1U<<31) | 1309, (1U<<31) | 449, 0x3F5, (1U<<31) | 1244, (1U<<31) | 1234, (1U<<31) | 1234, 
+  (1U<<31) | 1244, (1U<<31) | 1234, (1U<<31) | 1234, (1U<<31) | 1244, (1U<<31) | 1234, (1U<<31) | 1234, (1U<<31) | 1244, (1U<<31) | 1234, 
+  (1U<<31) | 1234, (1U<<31) | 1254, (1U<<31) | 1225, (1U<<31) | 1225, (1U<<31) | 1254, (1U<<31) | 1225, (1U<<31) | 1225, (1U<<31) | 1254, 
+  (1U<<31) | 1225, (1U<<31) | 1225, (1U<<31) | 1254, (1U<<31) | 1225, (1U<<31) | 1225, 0x88, 0x77, 0x77, 
+  0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 
+  0x48, 0x48, 0x48, 0x48, 0x47, 0x47, 0x47, 0x47, 
+  0x58, 0x58, 0x58, 0x58, 0x57, 0x57, 0x57, 0x57, 
+  0x17F0F, 0x40, 0x1F1F1F, 0x41F1F, 0x40, 0x0, 0x442E0, 0x442E0, 
+  0x442E0, 0x442E0, 0x2E2C, 0x2E3B, 0x2E4A, 0x2E2C, 0x2E2C, 0x2E4A, 
+  0x2E4A, 0x3B, 0x4A0, 0x2E2C0, 0x2E3B0, 0x2E4A0, 0x2E4A0, 0x2E4A0, 
+  0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x44A7A, 0x44A7A, 0x7A7A4A, 
+  0x7A7A44, 0x7A7A4A, 0x7A7A44, 0x2C2C2C, 0x2C2C44, 0x3B3B3B, 0x3B3B44, 0x4A4A4A, 
+  0x4A4A44, 0x7A7A4A, 0x7A7A44, 0x7A7A4A, 0x7A7A44, 0x2C2C2C, 0x2C2C44, 0x3B3B3B, 
+  0x3B3B44, 0x4A4A4A, 0x4A4A44, 0x2C2C2C, 0x2C2C44, 0x3B3B3B, 0x3B3B44, 0x4A4A4A, 
+  0x4A4A44, 0x47A4A, 0x47A4A, 0x7A7A, 0x7A7A, 0x7A7A7A7A, 0x7A7A7A, 0x2C2C2C, 
+  0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x3B3B3B3B, 0x3B3B3B3B, 0x7A7A7A, 
+  0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x3B3B3B3B, 0x4A2C2C4A, 
+  0x4A3B3B4A, 0x4A3B3B4A, 0x4A2C2C4A, 0x4A3B3B4A, 0x4A3B3B4A, 0x2C2C3B, 0x3B3B4A, 0x2C2C3B, 
+  0x3B3B4A, 0x2C2C3B, 0x3B3B4A, 0x2C2C3B, 0x3B3B4A, 0x7A7A7A7A, 0x2C4A4A4A, 0x4A4A3B, 
+  0x3B3B2C, 0x3B3B2C, 0x4A4A2C, 0x4A4A3B, 0x3B3B2C, 0x4A4A3B, 0x7A7A, 0x7A7A, 
+  0x7A7A, 0x7A7A, 0x7A7A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x7A7A, 0x4A4A4A4A, 
+  0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 
+  0x4A4A4A, 0x2C2C2C, 0x3B3B3B, 0x4A4A4A, 0x4A4A4A, 0x4A2C4A, 0x4A3B4A, 0x4A2C4A, 
+  0x4A4A4A, 0x3B4A, 0x2C3B, 0x3B4A, 0x3B4A, 0x2C3B, 0x3B4A, 0x2E0, 
+  0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x2E0, 0x1, 
+  0xF0, 0x0, 0x4442E0, (1U<<31) | 579, 0x40, 0x4, 0x5, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 
+  0x4, 0x4, 0x4, 0x4, 0x4, (1U<<31) | 1809, 0x5, 0x42E, 
+  0x1F1F, 0x1F1F, (1U<<31) | 0, 0x2E4, 0x42E0, 0x42E4, 0x1F1F, (1U<<31) | 0, 
+  0x1F1F, (1U<<31) | 0, 0x2EE2E0, 0x2EE0, 0x2E0, 0x2E, 0x0, 0x1F1F, 
+  (1U<<31) | 0, (1U<<31) | 0, (1U<<31) | 0, 0x2E2E0, 0x2E0, 0x42E2E2E0, 0x2E0, (1U<<31) | 9, 
+  (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1802, (1U<<31) | 1802, 
+  0x595959, 0x595959, 0x595959, 0x595959, 0x5959, 0x25959, (1U<<31) | 49, (1U<<31) | 85, 
+  (1U<<31) | 233, (1U<<31) | 267, (1U<<31) | 165, (1U<<31) | 211, (1U<<31) | 97, (1U<<31) | 121, (1U<<31) | 61, (1U<<31) | 73, 
+  (1U<<31) | 245, (1U<<31) | 279, (1U<<31) | 177, (1U<<31) | 189, (1U<<31) | 109, (1U<<31) | 133, 0x4A2E4A, 0x4B2E4B, 
+  0x592E59, 0x5A2E5A, 0x4A4A2E0, 0x4B4B2E0, 0x59592E0, 0x5A5A2E0, 0x2E5A, 0x42D2D3C, 
+  0x2D2D, 0x4B4B, 0x3C3C, 0x4B4B3C, 0x3C3C2D, 0x4B4B3C, 0x3C3C2D, 0x2D2D2D, 
+  0x3C3C3C, 0x2D2D2D, 0x3C3C3C, 0x2D2D2D, 0x3C3C3C, 0x44A4A4A, 0x44B4B4B, 0x2D2D2D2D, 
+  0x43C3C3C, 0x2C2C, 0x2C2D, 0x4A4A, 0x4A4B, 0x5959, 0x595A, 0x3B3B, 
+  0x3B3C, 0x4B4B4B, 0x7B7B7B, 0x4B4B4B, 0x3C3C3C, 0x3C3C3C, 0x4B4B4B, 0x3C3C3C, 
+  0x3C3C3C, 0x2D2D3C, 0x3C3C4B, 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x2D2D2D, 0x4B4B4B, 
+  0x3C3C3C, 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x2D4, 
+  0x2C4B, 0x2C5A, 0x2C3C, 0x4A5A, 0x3B4B, 0x3B5A, 0x2C4B, 0x2C5A, 
+  0x2C3C, 0x4A5A, 0x3B4B, 0x3B5A, 0x4B4B5A, 0x3C3C3C, 0x3C3C3C, 0x3C3C3C, 
+  0x4B4B5A, 0x2D2D5A, 0x2D2D2D, 0x2D2D2D, 0x4B4B4B, 0x3C3C3C, 0x4A4B4B, 0x45A5A, 
+  0x45A5A, 0x595A5A, 0x3B3C3C, 0x44B4B, 0x45A5A, 0x43C3C, 0x4A4A4A, 0x4B4B4B, 
+  0x595959, 0x5A5A5A, 0x4A4B4B, 0x3B3C3C, 0x44B4B, 0x43C3C, 0x4A4A4A, 0x4B4B4B, 
+  0x4A4B4B, 0x45A5A, 0x45A5A, 0x595A5A, 0x3B3C3C, 0x44B4B, 0x45A5A, 0x43C3C, 
+  0x4A4A4A, 0x4B4B4B, 0x595959, 0x5A5A5A, 0x2D2D2D, 0x3C3C3C, 0x2D2D2D, 0x3C3C3C, 
+  0x898A, 0x7A7A, 0x7A7B, 0x2E5A, 0x25A59, 0x2595A5A, 0x25A5A5A, 0x894, 
+  0x895, 0x7A4, 0x7A5, 0x894, 0x895, 0x7A4, 0x7A5, 0x48989, 
+  0x47A7A, 0x58989, 0x57A7A, (1U<<31) | 471, (1U<<31) | 652, (1U<<31) | 460, (1U<<31) | 663, (1U<<31) | 515, 
+  (1U<<31) | 482, (1U<<31) | 493, (1U<<31) | 504, 0x442E4B20, 0x442E4C30, 0x442E5B20, 0x442E5B20, 0x333, 
+  0x333, 0x33, 0x333, 0x334, 0x334, 0x333, 0x333, 0x333, 
+  0x34C4C4C, 0x28B8B8B, 0x37C7C7C, 0x25B5B5B, 0x4248B8B2, 0x4347C7C3, 0x34C4C4C, 0x25B5B5B, 
+  0x28B4B8B, 0x437C4C7C, 0x424B8B4B, 0x427B8B7B, 0x424B8B4B, 0x434C7C4C, 0x434C7C4C, 0x424B8B4B, 
+  0x424B8B4B, 0x434C7C4C, 0x434C7C4C, 0x28B4B8B, 0x437C4C7C, 0x34C2E4C, 0x28B2E8B, 0x37C2E7C, 
+  0x25B2E5B, 0x34C4C4C, 0x25B5B5B, (1U<<31) | 558, (1U<<31) | 684, (1U<<31) | 558, (1U<<31) | 684, 0x34C4C4C, 
+  0x25B5B5B, (1U<<31) | 429, (1U<<31) | 155, 0x34C44C, 0x25B55B, 0x25B55B, 0x34C4C3, 0x25B5B2, 
+  (1U<<31) | 429, (1U<<31) | 155, (1U<<31) | 429, (1U<<31) | 155, (1U<<31) | 429, (1U<<31) | 155, (1U<<31) | 429, (1U<<31) | 155, 
+  (1U<<31) | 145, (1U<<31) | 145, 0x34C4C3, 0x25B5B2, (1U<<31) | 548, (1U<<31) | 674, 0x34C2E0, 0x28B2E0, 
+  0x37C2E0, 0x25B2E0, 0x437C3C7C, 0x33C47C3C, (1U<<31) | 429, (1U<<31) | 301, (1U<<31) | 439, (1U<<31) | 155, 
+  0x2E5B, 0x4A4C, 0x44C, 0x595B, 0x55B, 0x2C4C, 0x2C5B, 0x4B5B, 
+  0x3C4C, 0x3B5B, 0x45B5B, 0x45B5B, 0x45B5B, 0x45B5B, 0x28B8B8B, 0x37C7C7C, 
+  (1U<<31) | 257, (1U<<31) | 201, 0x428B8B8B, 0x437C7C7C, (1U<<31) | 537, (1U<<31) | 526, 0x4898989, 0x47A7A7A, 
+  0x28B8B8B, 0x37C7C7C, (1U<<31) | 257, (1U<<31) | 201, 0x428B8B8B, 0x437C7C7C, (1U<<31) | 537, (1U<<31) | 526, 
+  (1U<<31) | 1083, (1U<<31) | 960, (1U<<31) | 1039, (1U<<31) | 1073, (1U<<31) | 1093, (1U<<31) | 950, (1U<<31) | 1049, (1U<<31) | 1063, 
+  0x442E4B20, 0x442E4C30, 0x442E5B20, 0x442E5B20, 0x8B8B, 0x7C7C, 0x898989, 0x7A7A7A, 
+  0x2E8B, 0x898B, 0x2E7C, 0x7A7C, 0x8A8A8A, 0x7B7B7B, 0x48A8A8A, 0x47B7B7B, 
+  (1U<<31) | 1769, 0x7B7B7B7B, 0x28A8A8A, 0x27B7B7B, 0x8A7A, 0x8A4A, 0x7A8A, 0x7B4B, 
+  0x4A8A, 0x4B7B, 0x8A4A, 0x7B4B, 0x47B7B7B, 0x8A8A8A, 0x7B7B7B, 0x8A8A8A, 
+  0x7B7B7B, 0x2E2D, 0x892E89, 0x8A2E8A, 0x7A2E7A, 0x7B2E7B, 0x89892E0, 0x8A8A2E0, 
+  0x7A7A2E0, 0x7B7B2E0, 0x8A8A8A, 0x7B7B7B, 0x8A8A8A, 0x7B7B7B, 0x8A4, 0x7B4, 
+  0x5A5A4, 0x5A5A4, 0x5A5A4, 0x7B7B, 0x48A8A, 0x47B7B, 0x7B7B, 0x8A8A, 
+  0x7B7B, 0x2D2E0, 0x8A2E0, 0x7B2E0, 0x2E8A, 0x2E7B, 0x28A89, 0x27B7A, 
+  0x24B4A, 0x2898A8A, 0x27A7B7B, 0x24A4B4B, 0x28A8A8A, 0x27B7B7B, 0x24B4B4B, 0x598989, 
+  0x5A8A8A, 0x4A7A7A, 0x4B7B7B, 0x89894, 0x8A8A4, 0x7A7A4, 0x7B7B4, 0x89894, 
+  0x8A8A4, 0x7A7A4, 0x7B7B4, 0x89894, 0x8A8A4, 0x7A7A4, 0x7B7B4, 0x0, 
+  0x0, 0x444, 0x555, 0x444, 0x555, 0x444, 0x555, 0x444, 
+  0x555, (1U<<31) | 1756, (1U<<31) | 1769, (1U<<31) | 1778, 0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, 
+  0x7A7A7A7A, (1U<<31) | 1756, (1U<<31) | 1769, (1U<<31) | 1778, 0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, 
+  (1U<<31) | 1769, (1U<<31) | 1778, 0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, 0x7A7A7A7A, (1U<<31) | 1756, 
+  (1U<<31) | 1769, (1U<<31) | 1778, 0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, (1U<<31) | 1769, (1U<<31) | 1778, 
+  0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, 0x7A7A7A7A, (1U<<31) | 1756, (1U<<31) | 1769, (1U<<31) | 1778, 
+  0x7A7A7A7A, 0x7B7B7B7B, 0x7C7C7C7C, (1U<<31) | 1756, 0x7A7A7A7A, 0x20, 0x0, 0x0, 
+  (1U<<31) | 345, (1U<<31) | 1800, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 390, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1103, (1U<<31) | 970, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1787, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1107, (1U<<31) | 1107, (1U<<31) | 1107, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1107, (1U<<31) | 1107, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1107, (1U<<31) | 1107, (1U<<31) | 1107, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 
+  (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, (1U<<31) | 1805, 0x2595959, 0x4, 0x5, 
+  0x4, 0x5, 0x45, (1U<<31) | 695, (1U<<31) | 975, (1U<<31) | 1059, (1U<<31) | 695, (1U<<31) | 975, 
+  (1U<<31) | 1059, 0x5, 0x2E5, 0x4A4A4A, 0x4A4A4A, 0x4A4A4A, 0x24A4A4A, 0x4A4A4A, 
+  0x4A4A4A, 0x4A4A4A4A, 0x898989, 0x2E0, 0x2898989, 0x2898989, 0x89894, 0x89894, 
+  0x89894, 0x89894, 0x89894, 0x89894, 0x4A89, 0x4A7A, 0x894A, 0x897A, 
+  0x7A4A, 0x7A89, 0x894, 0x895, 0x897A7A, 0x48989, 0x58989, 0x7A8989, 
+  0x894A, 0x7A4A, 0x894, 0x895, 0x898989, 0x0, 0x2E2C2C0, 0x898989, 
+  0x898989, 0x0, 0x898989, 0x898989, 0x894, 0x898989, 0x4A4A3B, 0x3B3B2C, 
+  0x3B3B2C, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x0, 0x2C2C2C, 0x3B3B3B, 
+  0x3B3B4A, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x2C4, 0x3B3B3B, 0x3B3B3B, 
+  0x4A4A59, 0x2C2C59, 0x24A4A, 0x23B3B, 0x23B3B, 0x4A4A4A, 0x45959, 0x45959, 
+  0x595959, 0x3B3B3B, 0x44A4A, 0x45959, 0x43B3B, 0x4A4A4A, 0x3B3B3B, 0x44A4A, 
+  0x43B3B, 0x4A4A4A, 0x45959, 0x45959, 0x595959, 0x3B3B3B, 0x44A4A, 0x45959, 
+  0x43B3B, 0x2C2C2C, 0x3B3B3B, 0x2C2C2C, 0x3B3B3B, 0x8989, 0x8989, 0x4A2E0, 
+  0x2C2E0, 0x892E0, 0x898989, 0x89894, 0x89894, 0x89894, 0x89894, 0x89894, 
+  0x89894, 0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 0x898989, 0x7A7A7A, 0x2E2C, 
+  0x442E0, 0x440, 0x4898989, 0x47A7A7A, (1U<<31) | 1756, 0x7A7A7A7A, 0x4898989, 0x47A7A7A, 
+  0x47A4, 0x47A7A7A, 0x2E59, 0x42C2C3B, 0x4A4A3B, 0x2C2C2C2C, 0x43B3B3B, 0x42C4, 
+  0x44A4, 0x4595, 0x3B3B, 0x2C2C2C, 0x4A4A4A, 0x4A4A4A, 0x3B3B3B, 0x2C2C2C, 
+  0x4A4A4A, 0x4A4A4A, 0x3B3B3B, 0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 0x3B4A, 
+  0x3B59, 0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 0x3B4A, 0x3B59, 0x4A4A59, 
+  0x59594, 0x59594, 0x59594, 0x48989, 0x47A7A, 0x4898989, 0x47A7A7A, 0x344, 
+  0x444, 0x244, 0x555, 0x242C42C4, 0x242C42C4, 0x242C42C4, 0x242C42C4, 0x242C42C4, 
+  0x242C42C4, (1U<<31) | 39, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4, 0x22C2C4, 
+  0x22C2C2C, 0x2C5959, 0x225959, 0x595959, 0x22595959, 0x892E0, 0x7A2E0, 0x7A7A7A, 
+  0x27A7A7A, 0x27A7A7A, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 
+  (1U<<31) | 1765, (1U<<31) | 1796, (1U<<31) | 1790, (1U<<31) | 1625, 0x47A7A, 0x57A7A, 0x7A4, 0x7A5, 
+  (1U<<31) | 1765, (1U<<31) | 1625, 0x7A4, 0x7A5, 0x7A7A7A, 0x2E0, 0x7A7A7A, 0x7A7A7A, 
+  0x7A7A7A, 0x7A7A7A, 0x7A4, 0x7A7A7A, (1U<<31) | 391, 0x7A7A, 0x7A7A, 0x7A7A, 
+  0x7A7A, 0x0, 0x7A7A, 0x7A7A, 0x2E0, 0x7A2E0, 0x7A7A7A, 0x7A7A4, 
+  0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, 0x7A7A4, (1U<<31) | 1802, 0x2C2C, (1U<<31) | 1802, 
+  0x4A4A, (1U<<31) | 1802, 0x3B3B, (1U<<31) | 1805, 0x4A4A4A, (1U<<31) | 1805, 0x3B3B3B, (1U<<31) | 1805, 
+  0x3B3B3B, (1U<<31) | 1805, 0x4A4A4A, (1U<<31) | 1805, 0x3B3B3B, (1U<<31) | 1805, 0x3B3B3B, (1U<<31) | 1805, 
+  0x2C2C3B, (1U<<31) | 1805, 0x3B3B3B, (1U<<31) | 1805, 0x2C2C2C, (1U<<31) | 1805, 0x2C2C2C, (1U<<31) | 1805, 
+  0x4A4A4A, (1U<<31) | 1805, 0x3B3B3B, 0x444, 0x555, 0x3B7A, 0x3B7B, 0x47A3B, 
+  0x47B3B, 0x40, 0x50, 0x40, 0x50, 0x20, 0x4, 0x0, 
+  0x8989, 0x8A8A, 0x7A7A, 0x7B7B, 0x8989, 0x7A7A, 0x59595959, 0x5A5A5A5A, 
+  0x22C2C2C, 0x24A4A4A, 0x2595959, 0x22C2C2C, 0x24A4A4A, 0x2595959, 0x23B3B3B, 0x23B3B3B, 
+  (1U<<31) | 257, (1U<<31) | 291, (1U<<31) | 201, (1U<<31) | 223, 0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 
+  0x2C4A, 0x2C59, 0x2C3B, 0x4A59, 0x3B4A, 0x3B59, 0x3B4A, 0x3B59, 
+  0x2C3B, 0x4A59, 0x3B4A, 0x4A4A4A4A, 0x594A4A59, 0x594A4A59, 0x4A4A4A4A, 0x594A4A59, 
+  0x594A4A59, 0x4A3B3B4A, 0x3B3B3B3B, 0x4A3B3B4A, 0x3B3B3B3B, 0x4A3B3B4A, 0x4A3B3B4A, 0x2C2C2C2C, 
+  0x2C2C2C, 0x22C2C, 0x4A4A4A, 0x24A4A, 0x595959, 0x25959, 0x3B3B3B, 0x23B3B, 
+  0x2C2C2C, 0x4A4A4A, 0x595959, 0x3B3B3B, 0x2C2C2C, 0x4A4A4A, 0x595959, 0x3B3B3B, 
+  0x4, 0x44, 0x2E2E, 0x43F0, 0x0, 0x3F0, 0x40, 0x4444, 
+  (1U<<31) | 799, 0x3F0, 0x3F0, 0x3F4, 0x3F0, 0x4, 0x4, 0x4, 
+  0x44, 0x43F, 0x7F3F, 0x3F4, 0x3F4, 0x3F4, 0x2E3F0, 0x2E3F0, 
+  0x2E3F0, 0x2E3F0, 0x2E3F0, 0x43F4, 0x3F4, 0x3F0, 0x3F0, 0x43F0, 
+  0x43F0, 0x43F4, 0x43F0, 0x3F4, 0x43F0, 0x7F3F0, 0x43F0, 0x2E3F0, 
+  0x440, 0x43F0, 0x43F0, 0x7F3F0, 0x40, 0x43F0, 0x2E3F0, 0x444, 
+  0x0, 0x3F0, 0x3F4, 0x3F4, 0x2E, 0x444, 0
+};
+
+static const unsigned char IIT_LongEncodingTable[] = {
+  /* 0 */ 19, 15, 0, 1, 15, 0, 15, 0, 0,
+  /* 9 */ 0, 17, 15, 0, 0,
+  /* 14 */ 15, 0, 23, 0, 0,
+  /* 19 */ 19, 15, 1, 1, 15, 1, 15, 1, 1, 0,
+  /* 29 */ 0, 15, 3, 15, 7, 15, 8, 4, 1, 0,
+  /* 39 */ 12, 2, 12, 2, 4, 12, 2, 4, 2, 0,
+  /* 49 */ 10, 4, 10, 4, 14, 2, 10, 4, 10, 4, 2, 0,
+  /* 61 */ 10, 4, 10, 4, 14, 2, 9, 5, 10, 4, 2, 0,
+  /* 73 */ 10, 4, 10, 4, 14, 2, 10, 5, 10, 4, 2, 0,
+  /* 85 */ 11, 4, 11, 4, 14, 2, 11, 4, 11, 4, 2, 0,
+  /* 97 */ 9, 5, 9, 5, 14, 2, 10, 4, 9, 5, 2, 0,
+  /* 109 */ 9, 5, 9, 5, 14, 2, 9, 5, 9, 5, 2, 0,
+  /* 121 */ 10, 5, 10, 5, 14, 2, 10, 4, 10, 5, 2, 0,
+  /* 133 */ 10, 5, 10, 5, 14, 2, 10, 5, 10, 5, 2, 0,
+  /* 145 */ 11, 5, 12, 4, 12, 4, 11, 5, 2, 0,
+  /* 155 */ 11, 5, 11, 5, 11, 5, 11, 5, 2, 0,
+  /* 165 */ 10, 7, 10, 7, 14, 2, 10, 4, 10, 7, 2, 0,
+  /* 177 */ 10, 7, 10, 7, 14, 2, 9, 5, 10, 7, 2, 0,
+  /* 189 */ 10, 7, 10, 7, 14, 2, 10, 5, 10, 7, 2, 0,
+  /* 201 */ 10, 7, 10, 7, 10, 7, 10, 7, 2, 0,
+  /* 211 */ 11, 7, 11, 7, 14, 2, 11, 4, 11, 7, 2, 0,
+  /* 223 */ 11, 7, 11, 7, 11, 7, 11, 7, 2, 0,
+  /* 233 */ 9, 8, 9, 8, 14, 2, 10, 4, 9, 8, 2, 0,
+  /* 245 */ 9, 8, 9, 8, 14, 2, 9, 5, 9, 8, 2, 0,
+  /* 257 */ 9, 8, 9, 8, 9, 8, 9, 8, 2, 0,
+  /* 267 */ 10, 8, 10, 8, 14, 2, 10, 4, 10, 8, 2, 0,
+  /* 279 */ 10, 8, 10, 8, 14, 2, 10, 5, 10, 8, 2, 0,
+  /* 291 */ 10, 8, 10, 8, 10, 8, 10, 8, 2, 0,
+  /* 301 */ 11, 8, 11, 5, 11, 8, 11, 8, 2, 0,
+  /* 311 */ 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 0,
+  /* 326 */ 19, 4, 4, 14, 2, 0,
+  /* 332 */ 19, 5, 5, 14, 2, 0,
+  /* 338 */ 0, 14, 18, 5, 14, 2, 0,
+  /* 345 */ 0, 16, 16, 14, 2, 0,
+  /* 351 */ 15, 2, 15, 2, 12, 2, 12, 2, 12, 2, 12, 2, 15, 2, 0,
+  /* 366 */ 15, 2, 15, 2, 12, 2, 12, 2, 12, 2, 15, 2, 0,
+  /* 379 */ 15, 2, 15, 2, 12, 2, 12, 2, 15, 2, 0,
+  /* 390 */ 16, 16, 16, 2, 0,
+  /* 395 */ 15, 2, 23, 2, 0,
+  /* 400 */ 15, 2, 23, 2, 23, 2, 0,
+  /* 407 */ 15, 2, 24, 2, 0,
+  /* 412 */ 15, 2, 24, 2, 24, 2, 0,
+  /* 419 */ 0, 5, 4, 4, 4, 3, 3, 3, 3, 0,
+  /* 429 */ 12, 4, 12, 4, 12, 4, 12, 4, 3, 0,
+  /* 439 */ 12, 7, 12, 4, 12, 7, 12, 7, 3, 0,
+  /* 449 */ 5, 17, 15, 3, 0,
+  /* 454 */ 15, 0, 23, 0, 4, 0,
+  /* 460 */ 11, 5, 11, 5, 14, 2, 11, 4, 2, 4, 0,
+  /* 471 */ 11, 8, 11, 8, 14, 2, 11, 4, 2, 4, 0,
+  /* 482 */ 11, 4, 11, 4, 14, 2, 11, 5, 2, 4, 0,
+  /* 493 */ 11, 5, 11, 5, 14, 2, 11, 5, 2, 4, 0,
+  /* 504 */ 11, 7, 11, 7, 14, 2, 11, 5, 2, 4, 0,
+  /* 515 */ 11, 8, 11, 8, 14, 2, 11, 5, 2, 4, 0,
+  /* 526 */ 10, 7, 10, 7, 10, 7, 10, 7, 2, 4, 0,
+  /* 537 */ 9, 8, 9, 8, 9, 8, 9, 8, 2, 4, 0,
+  /* 548 */ 11, 8, 11, 8, 4, 11, 8, 2, 4, 0,
+  /* 558 */ 11, 8, 11, 8, 11, 8, 11, 8, 2, 4, 0,
+  /* 569 */ 15, 0, 15, 0, 14, 2, 14, 2, 4, 0,
+  /* 579 */ 15, 3, 15, 3, 14, 2, 14, 2, 4, 0,
+  /* 589 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0,
+  /* 602 */ 20, 15, 2, 15, 2, 15, 2, 14, 2, 4, 0,
+  /* 613 */ 19, 15, 2, 15, 2, 14, 2, 4, 0,
+  /* 622 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 0,
+  /* 633 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 0,
+  /* 646 */ 15, 2, 24, 2, 4, 0,
+  /* 652 */ 12, 4, 12, 4, 14, 2, 12, 4, 3, 4, 0,
+  /* 663 */ 12, 7, 12, 7, 14, 2, 12, 4, 3, 4, 0,
+  /* 674 */ 12, 7, 12, 7, 4, 12, 7, 3, 4, 0,
+  /* 684 */ 12, 7, 12, 7, 12, 7, 12, 7, 3, 4, 0,
+  /* 695 */ 19, 3, 4, 0,
+  /* 699 */ 0, 14, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 709 */ 19, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 723 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 735 */ 20, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 753 */ 0, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 767 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 14, 2, 15, 2, 15, 2, 15, 2, 15, 2, 4, 4, 0,
+  /* 789 */ 0, 5, 4, 4, 4, 4, 4, 4, 4, 0,
+  /* 799 */ 19, 4, 4, 4, 4, 4, 0,
+  /* 806 */ 21, 3, 3, 3, 3, 5, 4, 4, 4, 0,
+  /* 816 */ 19, 3, 3, 5, 4, 4, 4, 0,
+  /* 824 */ 21, 4, 4, 4, 4, 5, 4, 4, 4, 0,
+  /* 834 */ 19, 4, 4, 5, 4, 4, 4, 0,
+  /* 842 */ 21, 4, 4, 4, 4, 5, 5, 4, 4, 4, 0,
+  /* 853 */ 19, 5, 5, 5, 4, 4, 4, 0,
+  /* 861 */ 21, 7, 7, 7, 7, 5, 5, 4, 4, 4, 0,
+  /* 872 */ 21, 7, 7, 7, 7, 5, 4, 4, 4, 0,
+  /* 882 */ 21, 3, 3, 3, 3, 5, 4, 4, 0,
+  /* 891 */ 19, 3, 3, 5, 4, 4, 0,
+  /* 898 */ 21, 4, 4, 4, 4, 5, 4, 4, 0,
+  /* 907 */ 19, 4, 4, 5, 4, 4, 0,
+  /* 914 */ 21, 4, 4, 4, 4, 5, 5, 4, 4, 0,
+  /* 924 */ 19, 5, 5, 5, 4, 4, 0,
+  /* 931 */ 21, 7, 7, 7, 7, 5, 5, 4, 4, 0,
+  /* 941 */ 21, 7, 7, 7, 7, 5, 4, 4, 0,
+  /* 950 */ 0, 14, 2, 2, 11, 5, 11, 4, 4, 0,
+  /* 960 */ 0, 14, 2, 3, 12, 4, 12, 4, 4, 0,
+  /* 970 */ 16, 16, 4, 4, 0,
+  /* 975 */ 19, 4, 4, 0,
+  /* 979 */ 21, 3, 3, 3, 3, 5, 4, 0,
+  /* 987 */ 19, 3, 3, 5, 4, 0,
+  /* 993 */ 21, 4, 4, 4, 4, 5, 4, 0,
+  /* 1001 */ 19, 4, 4, 5, 4, 0,
+  /* 1007 */ 21, 4, 4, 4, 4, 5, 5, 4, 0,
+  /* 1016 */ 19, 5, 5, 5, 4, 0,
+  /* 1022 */ 21, 7, 7, 7, 7, 5, 5, 4, 0,
+  /* 1031 */ 21, 7, 7, 7, 7, 5, 4, 0,
+  /* 1039 */ 0, 14, 2, 2, 11, 4, 11, 5, 4, 0,
+  /* 1049 */ 0, 14, 2, 2, 11, 5, 11, 5, 4, 0,
+  /* 1059 */ 19, 5, 4, 0,
+  /* 1063 */ 0, 14, 2, 2, 11, 5, 11, 7, 4, 0,
+  /* 1073 */ 0, 14, 2, 3, 12, 4, 12, 7, 4, 0,
+  /* 1083 */ 0, 14, 2, 2, 11, 4, 11, 8, 4, 0,
+  /* 1093 */ 0, 14, 2, 2, 11, 5, 11, 8, 4, 0,
+  /* 1103 */ 4, 16, 4, 0,
+  /* 1107 */ 16, 16, 4, 0,
+  /* 1111 */ 21, 4, 4, 4, 4, 5, 4, 7, 0,
+  /* 1120 */ 21, 4, 4, 4, 4, 5, 5, 4, 7, 0,
+  /* 1130 */ 21, 7, 7, 7, 7, 5, 5, 4, 7, 0,
+  /* 1140 */ 21, 7, 7, 7, 7, 5, 4, 7, 0,
+  /* 1149 */ 21, 4, 4, 4, 4, 5, 7, 0,
+  /* 1157 */ 21, 4, 4, 4, 4, 5, 5, 7, 0,
+  /* 1166 */ 21, 7, 7, 7, 7, 5, 5, 7, 0,
+  /* 1175 */ 21, 7, 7, 7, 7, 5, 7, 0,
+  /* 1183 */ 21, 4, 4, 4, 4, 5, 4, 7, 7, 0,
+  /* 1193 */ 21, 4, 4, 4, 4, 5, 5, 4, 7, 7, 0,
+  /* 1204 */ 21, 7, 7, 7, 7, 5, 5, 4, 7, 7, 0,
+  /* 1215 */ 21, 7, 7, 7, 7, 5, 4, 7, 7, 0,
+  /* 1225 */ 21, 4, 4, 4, 4, 5, 7, 7, 0,
+  /* 1234 */ 21, 4, 4, 4, 4, 5, 5, 7, 7, 0,
+  /* 1244 */ 21, 7, 7, 7, 7, 5, 5, 7, 7, 0,
+  /* 1254 */ 21, 7, 7, 7, 7, 5, 7, 7, 0,
+  /* 1263 */ 21, 4, 4, 4, 4, 5, 4, 7, 7, 7, 0,
+  /* 1274 */ 21, 4, 4, 4, 4, 5, 5, 4, 7, 7, 7, 0,
+  /* 1286 */ 21, 7, 7, 7, 7, 5, 5, 4, 7, 7, 7, 0,
+  /* 1298 */ 21, 7, 7, 7, 7, 5, 4, 7, 7, 7, 0,
+  /* 1309 */ 21, 4, 4, 4, 4, 5, 7, 7, 7, 0,
+  /* 1319 */ 21, 4, 4, 4, 4, 5, 5, 7, 7, 7, 0,
+  /* 1330 */ 21, 7, 7, 7, 7, 5, 5, 7, 7, 7, 0,
+  /* 1341 */ 21, 7, 7, 7, 7, 5, 7, 7, 7, 0,
+  /* 1351 */ 21, 4, 4, 4, 4, 5, 4, 7, 7, 7, 7, 0,
+  /* 1363 */ 21, 4, 4, 4, 4, 5, 5, 4, 7, 7, 7, 7, 0,
+  /* 1376 */ 21, 7, 7, 7, 7, 5, 5, 4, 7, 7, 7, 7, 0,
+  /* 1389 */ 21, 7, 7, 7, 7, 5, 4, 7, 7, 7, 7, 0,
+  /* 1401 */ 21, 4, 4, 4, 4, 5, 7, 7, 7, 7, 0,
+  /* 1412 */ 21, 4, 4, 4, 4, 5, 5, 7, 7, 7, 7, 0,
+  /* 1424 */ 21, 7, 7, 7, 7, 5, 5, 7, 7, 7, 7, 0,
+  /* 1436 */ 21, 7, 7, 7, 7, 5, 7, 7, 7, 7, 0,
+  /* 1447 */ 21, 4, 4, 4, 4, 5, 4, 7, 7, 7, 7, 7, 7, 0,
+  /* 1461 */ 21, 4, 4, 4, 4, 5, 5, 4, 7, 7, 7, 7, 7, 7, 0,
+  /* 1476 */ 21, 7, 7, 7, 7, 5, 5, 4, 7, 7, 7, 7, 7, 7, 0,
+  /* 1491 */ 21, 7, 7, 7, 7, 5, 4, 7, 7, 7, 7, 7, 7, 0,
+  /* 1505 */ 21, 4, 4, 4, 4, 5, 7, 7, 7, 7, 7, 7, 0,
+  /* 1518 */ 21, 4, 4, 4, 4, 5, 5, 7, 7, 7, 7, 7, 7, 0,
+  /* 1532 */ 21, 7, 7, 7, 7, 5, 5, 7, 7, 7, 7, 7, 7, 0,
+  /* 1546 */ 21, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 0,
+  /* 1559 */ 21, 4, 4, 4, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+  /* 1575 */ 21, 4, 4, 4, 4, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+  /* 1592 */ 21, 7, 7, 7, 7, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+  /* 1609 */ 21, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0,
+  /* 1625 */ 16, 10, 7, 0,
+  /* 1629 */ 0, 15, 2, 15, 2, 15, 2, 15, 7, 0,
+  /* 1639 */ 0, 15, 2, 15, 2, 15, 2, 15, 2, 15, 7, 0,
+  /* 1651 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 15, 7, 0,
+  /* 1663 */ 20, 15, 2, 15, 2, 15, 2, 15, 7, 0,
+  /* 1673 */ 19, 15, 2, 15, 2, 15, 7, 0,
+  /* 1681 */ 0, 15, 2, 15, 2, 15, 2, 5, 15, 7, 0,
+  /* 1692 */ 0, 15, 2, 15, 2, 15, 2, 15, 2, 5, 15, 7, 0,
+  /* 1705 */ 21, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 5, 15, 7, 0,
+  /* 1726 */ 20, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 15, 2, 5, 15, 7, 0,
+  /* 1743 */ 19, 15, 2, 15, 2, 15, 2, 15, 2, 5, 15, 7, 0,
+  /* 1756 */ 9, 8, 9, 8, 9, 8, 9, 8, 0,
+  /* 1765 */ 16, 9, 8, 0,
+  /* 1769 */ 10, 8, 10, 8, 10, 8, 10, 8, 0,
+  /* 1778 */ 11, 8, 11, 8, 11, 8, 11, 8, 0,
+  /* 1787 */ 4, 16, 0,
+  /* 1790 */ 10, 7, 10, 7, 16, 0,
+  /* 1796 */ 9, 8, 16, 0,
+  /* 1800 */ 0, 14, 16, 16, 0,
+  /* 1805 */ 16, 16, 16, 0,
+  /* 1809 */ 15, 0, 17, 0,
+  /* 1813 */ 0, 17, 5, 17, 0,
+  /* 1818 */ 0, 17, 17, 0,
+  /* 1822 */ 0, 5, 4, 14, 2, 4, 27, 0,
+  /* 1830 */ 5, 5, 4, 14, 2, 4, 27, 0,
+  /* 1838 */ 0, 5, 4, 27, 0,
+  255
+};
+
+#endif
+
+// Add parameter attributes that are not common to all intrinsics.
+#ifdef GET_INTRINSIC_ATTRIBUTES
+AttributeSet Intrinsic::getAttributes(LLVMContext &C, ID id) {
+  static const uint8_t IntrinsicsToAttributesMap[] = {
+    1, // llvm.AMDGPU.div.fixup
+    1, // llvm.AMDGPU.div.fmas
+    1, // llvm.AMDGPU.div.scale
+    1, // llvm.AMDGPU.rcp
+    1, // llvm.AMDGPU.rsq
+    1, // llvm.AMDGPU.rsq.clamped
+    1, // llvm.AMDGPU.trig.preop
+    2, // llvm.aarch64.clrex
+    1, // llvm.aarch64.crc32b
+    1, // llvm.aarch64.crc32cb
+    1, // llvm.aarch64.crc32ch
+    1, // llvm.aarch64.crc32cw
+    1, // llvm.aarch64.crc32cx
+    1, // llvm.aarch64.crc32h
+    1, // llvm.aarch64.crc32w
+    1, // llvm.aarch64.crc32x
+    1, // llvm.aarch64.crypto.aesd
+    1, // llvm.aarch64.crypto.aese
+    1, // llvm.aarch64.crypto.aesimc
+    1, // llvm.aarch64.crypto.aesmc
+    1, // llvm.aarch64.crypto.sha1c
+    1, // llvm.aarch64.crypto.sha1h
+    1, // llvm.aarch64.crypto.sha1m
+    1, // llvm.aarch64.crypto.sha1p
+    1, // llvm.aarch64.crypto.sha1su0
+    1, // llvm.aarch64.crypto.sha1su1
+    1, // llvm.aarch64.crypto.sha256h
+    1, // llvm.aarch64.crypto.sha256h2
+    1, // llvm.aarch64.crypto.sha256su0
+    1, // llvm.aarch64.crypto.sha256su1
+    2, // llvm.aarch64.dmb
+    2, // llvm.aarch64.dsb
+    2, // llvm.aarch64.hint
+    2, // llvm.aarch64.isb
+    2, // llvm.aarch64.ldaxp
+    2, // llvm.aarch64.ldaxr
+    2, // llvm.aarch64.ldxp
+    2, // llvm.aarch64.ldxr
+    1, // llvm.aarch64.neon.abs
+    1, // llvm.aarch64.neon.addhn
+    1, // llvm.aarch64.neon.addp
+    1, // llvm.aarch64.neon.cls
+    1, // llvm.aarch64.neon.fabd
+    1, // llvm.aarch64.neon.facge
+    1, // llvm.aarch64.neon.facgt
+    1, // llvm.aarch64.neon.faddv
+    1, // llvm.aarch64.neon.fcvtas
+    1, // llvm.aarch64.neon.fcvtau
+    1, // llvm.aarch64.neon.fcvtms
+    1, // llvm.aarch64.neon.fcvtmu
+    1, // llvm.aarch64.neon.fcvtns
+    1, // llvm.aarch64.neon.fcvtnu
+    1, // llvm.aarch64.neon.fcvtps
+    1, // llvm.aarch64.neon.fcvtpu
+    1, // llvm.aarch64.neon.fcvtxn
+    1, // llvm.aarch64.neon.fcvtzs
+    1, // llvm.aarch64.neon.fcvtzu
+    1, // llvm.aarch64.neon.fmax
+    1, // llvm.aarch64.neon.fmaxnm
+    1, // llvm.aarch64.neon.fmaxnmp
+    1, // llvm.aarch64.neon.fmaxnmv
+    1, // llvm.aarch64.neon.fmaxp
+    1, // llvm.aarch64.neon.fmaxv
+    1, // llvm.aarch64.neon.fmin
+    1, // llvm.aarch64.neon.fminnm
+    1, // llvm.aarch64.neon.fminnmp
+    1, // llvm.aarch64.neon.fminnmv
+    1, // llvm.aarch64.neon.fminp
+    1, // llvm.aarch64.neon.fminv
+    1, // llvm.aarch64.neon.fmulx
+    1, // llvm.aarch64.neon.frecpe
+    1, // llvm.aarch64.neon.frecps
+    1, // llvm.aarch64.neon.frecpx
+    1, // llvm.aarch64.neon.frintn
+    1, // llvm.aarch64.neon.frsqrte
+    1, // llvm.aarch64.neon.frsqrts
+    3, // llvm.aarch64.neon.ld1x2
+    3, // llvm.aarch64.neon.ld1x3
+    3, // llvm.aarch64.neon.ld1x4
+    3, // llvm.aarch64.neon.ld2
+    3, // llvm.aarch64.neon.ld2lane
+    3, // llvm.aarch64.neon.ld2r
+    3, // llvm.aarch64.neon.ld3
+    3, // llvm.aarch64.neon.ld3lane
+    3, // llvm.aarch64.neon.ld3r
+    3, // llvm.aarch64.neon.ld4
+    3, // llvm.aarch64.neon.ld4lane
+    3, // llvm.aarch64.neon.ld4r
+    1, // llvm.aarch64.neon.pmul
+    1, // llvm.aarch64.neon.pmull
+    1, // llvm.aarch64.neon.pmull64
+    1, // llvm.aarch64.neon.raddhn
+    1, // llvm.aarch64.neon.rbit
+    1, // llvm.aarch64.neon.rshrn
+    1, // llvm.aarch64.neon.rsubhn
+    1, // llvm.aarch64.neon.sabd
+    1, // llvm.aarch64.neon.saddlp
+    1, // llvm.aarch64.neon.saddlv
+    1, // llvm.aarch64.neon.saddv
+    1, // llvm.aarch64.neon.scalar.sqxtn
+    1, // llvm.aarch64.neon.scalar.sqxtun
+    1, // llvm.aarch64.neon.scalar.uqxtn
+    1, // llvm.aarch64.neon.shadd
+    1, // llvm.aarch64.neon.shll
+    1, // llvm.aarch64.neon.shsub
+    1, // llvm.aarch64.neon.smax
+    1, // llvm.aarch64.neon.smaxp
+    1, // llvm.aarch64.neon.smaxv
+    1, // llvm.aarch64.neon.smin
+    1, // llvm.aarch64.neon.sminp
+    1, // llvm.aarch64.neon.sminv
+    1, // llvm.aarch64.neon.smull
+    1, // llvm.aarch64.neon.sqabs
+    1, // llvm.aarch64.neon.sqadd
+    1, // llvm.aarch64.neon.sqdmulh
+    1, // llvm.aarch64.neon.sqdmull
+    1, // llvm.aarch64.neon.sqdmulls.scalar
+    1, // llvm.aarch64.neon.sqneg
+    1, // llvm.aarch64.neon.sqrdmulh
+    1, // llvm.aarch64.neon.sqrshl
+    1, // llvm.aarch64.neon.sqrshrn
+    1, // llvm.aarch64.neon.sqrshrun
+    1, // llvm.aarch64.neon.sqshl
+    1, // llvm.aarch64.neon.sqshlu
+    1, // llvm.aarch64.neon.sqshrn
+    1, // llvm.aarch64.neon.sqshrun
+    1, // llvm.aarch64.neon.sqsub
+    1, // llvm.aarch64.neon.sqxtn
+    1, // llvm.aarch64.neon.sqxtun
+    1, // llvm.aarch64.neon.srhadd
+    1, // llvm.aarch64.neon.srshl
+    1, // llvm.aarch64.neon.sshl
+    1, // llvm.aarch64.neon.sshll
+    4, // llvm.aarch64.neon.st1x2
+    5, // llvm.aarch64.neon.st1x3
+    6, // llvm.aarch64.neon.st1x4
+    4, // llvm.aarch64.neon.st2
+    5, // llvm.aarch64.neon.st2lane
+    5, // llvm.aarch64.neon.st3
+    6, // llvm.aarch64.neon.st3lane
+    6, // llvm.aarch64.neon.st4
+    7, // llvm.aarch64.neon.st4lane
+    1, // llvm.aarch64.neon.subhn
+    1, // llvm.aarch64.neon.suqadd
+    1, // llvm.aarch64.neon.tbl1
+    1, // llvm.aarch64.neon.tbl2
+    1, // llvm.aarch64.neon.tbl3
+    1, // llvm.aarch64.neon.tbl4
+    1, // llvm.aarch64.neon.tbx1
+    1, // llvm.aarch64.neon.tbx2
+    1, // llvm.aarch64.neon.tbx3
+    1, // llvm.aarch64.neon.tbx4
+    1, // llvm.aarch64.neon.uabd
+    1, // llvm.aarch64.neon.uaddlp
+    1, // llvm.aarch64.neon.uaddlv
+    1, // llvm.aarch64.neon.uaddv
+    1, // llvm.aarch64.neon.uhadd
+    1, // llvm.aarch64.neon.uhsub
+    1, // llvm.aarch64.neon.umax
+    1, // llvm.aarch64.neon.umaxp
+    1, // llvm.aarch64.neon.umaxv
+    1, // llvm.aarch64.neon.umin
+    1, // llvm.aarch64.neon.uminp
+    1, // llvm.aarch64.neon.uminv
+    1, // llvm.aarch64.neon.umull
+    1, // llvm.aarch64.neon.uqadd
+    1, // llvm.aarch64.neon.uqrshl
+    1, // llvm.aarch64.neon.uqrshrn
+    1, // llvm.aarch64.neon.uqshl
+    1, // llvm.aarch64.neon.uqshrn
+    1, // llvm.aarch64.neon.uqsub
+    1, // llvm.aarch64.neon.uqxtn
+    1, // llvm.aarch64.neon.urecpe
+    1, // llvm.aarch64.neon.urhadd
+    1, // llvm.aarch64.neon.urshl
+    1, // llvm.aarch64.neon.ursqrte
+    1, // llvm.aarch64.neon.ushl
+    1, // llvm.aarch64.neon.ushll
+    1, // llvm.aarch64.neon.usqadd
+    1, // llvm.aarch64.neon.vcopy.lane
+    1, // llvm.aarch64.neon.vcvtfp2fxs
+    1, // llvm.aarch64.neon.vcvtfp2fxu
+    1, // llvm.aarch64.neon.vcvtfp2hf
+    1, // llvm.aarch64.neon.vcvtfxs2fp
+    1, // llvm.aarch64.neon.vcvtfxu2fp
+    1, // llvm.aarch64.neon.vcvthf2fp
+    1, // llvm.aarch64.neon.vsli
+    1, // llvm.aarch64.neon.vsri
+    1, // llvm.aarch64.rbit
+    1, // llvm.aarch64.sdiv
+    1, // llvm.aarch64.sisd.fabd
+    1, // llvm.aarch64.sisd.fcvtxn
+    2, // llvm.aarch64.stlxp
+    2, // llvm.aarch64.stlxr
+    2, // llvm.aarch64.stxp
+    2, // llvm.aarch64.stxr
+    1, // llvm.aarch64.udiv
+    3, // llvm.adjust.trampoline
+    2, // llvm.annotation
+    2, // llvm.arm.cdp
+    2, // llvm.arm.cdp2
+    2, // llvm.arm.clrex
+    1, // llvm.arm.crc32b
+    1, // llvm.arm.crc32cb
+    1, // llvm.arm.crc32ch
+    1, // llvm.arm.crc32cw
+    1, // llvm.arm.crc32h
+    1, // llvm.arm.crc32w
+    2, // llvm.arm.dmb
+    2, // llvm.arm.dsb
+    1, // llvm.arm.get.fpscr
+    2, // llvm.arm.hint
+    2, // llvm.arm.isb
+    2, // llvm.arm.ldaex
+    2, // llvm.arm.ldaexd
+    2, // llvm.arm.ldrex
+    2, // llvm.arm.ldrexd
+    2, // llvm.arm.mcr
+    2, // llvm.arm.mcr2
+    2, // llvm.arm.mcrr
+    2, // llvm.arm.mcrr2
+    2, // llvm.arm.mrc
+    2, // llvm.arm.mrc2
+    1, // llvm.arm.neon.aesd
+    1, // llvm.arm.neon.aese
+    1, // llvm.arm.neon.aesimc
+    1, // llvm.arm.neon.aesmc
+    1, // llvm.arm.neon.sha1c
+    1, // llvm.arm.neon.sha1h
+    1, // llvm.arm.neon.sha1m
+    1, // llvm.arm.neon.sha1p
+    1, // llvm.arm.neon.sha1su0
+    1, // llvm.arm.neon.sha1su1
+    1, // llvm.arm.neon.sha256h
+    1, // llvm.arm.neon.sha256h2
+    1, // llvm.arm.neon.sha256su0
+    1, // llvm.arm.neon.sha256su1
+    1, // llvm.arm.neon.vabds
+    1, // llvm.arm.neon.vabdu
+    1, // llvm.arm.neon.vabs
+    1, // llvm.arm.neon.vacge
+    1, // llvm.arm.neon.vacgt
+    1, // llvm.arm.neon.vbsl
+    1, // llvm.arm.neon.vcls
+    1, // llvm.arm.neon.vclz
+    1, // llvm.arm.neon.vcnt
+    1, // llvm.arm.neon.vcvtas
+    1, // llvm.arm.neon.vcvtau
+    1, // llvm.arm.neon.vcvtfp2fxs
+    1, // llvm.arm.neon.vcvtfp2fxu
+    1, // llvm.arm.neon.vcvtfp2hf
+    1, // llvm.arm.neon.vcvtfxs2fp
+    1, // llvm.arm.neon.vcvtfxu2fp
+    1, // llvm.arm.neon.vcvthf2fp
+    1, // llvm.arm.neon.vcvtms
+    1, // llvm.arm.neon.vcvtmu
+    1, // llvm.arm.neon.vcvtns
+    1, // llvm.arm.neon.vcvtnu
+    1, // llvm.arm.neon.vcvtps
+    1, // llvm.arm.neon.vcvtpu
+    1, // llvm.arm.neon.vhadds
+    1, // llvm.arm.neon.vhaddu
+    1, // llvm.arm.neon.vhsubs
+    1, // llvm.arm.neon.vhsubu
+    3, // llvm.arm.neon.vld1
+    3, // llvm.arm.neon.vld2
+    3, // llvm.arm.neon.vld2lane
+    3, // llvm.arm.neon.vld3
+    3, // llvm.arm.neon.vld3lane
+    3, // llvm.arm.neon.vld4
+    3, // llvm.arm.neon.vld4lane
+    1, // llvm.arm.neon.vmaxnm
+    1, // llvm.arm.neon.vmaxs
+    1, // llvm.arm.neon.vmaxu
+    1, // llvm.arm.neon.vminnm
+    1, // llvm.arm.neon.vmins
+    1, // llvm.arm.neon.vminu
+    1, // llvm.arm.neon.vmullp
+    1, // llvm.arm.neon.vmulls
+    1, // llvm.arm.neon.vmullu
+    1, // llvm.arm.neon.vmulp
+    1, // llvm.arm.neon.vpadals
+    1, // llvm.arm.neon.vpadalu
+    1, // llvm.arm.neon.vpadd
+    1, // llvm.arm.neon.vpaddls
+    1, // llvm.arm.neon.vpaddlu
+    1, // llvm.arm.neon.vpmaxs
+    1, // llvm.arm.neon.vpmaxu
+    1, // llvm.arm.neon.vpmins
+    1, // llvm.arm.neon.vpminu
+    1, // llvm.arm.neon.vqabs
+    1, // llvm.arm.neon.vqadds
+    1, // llvm.arm.neon.vqaddu
+    1, // llvm.arm.neon.vqdmulh
+    1, // llvm.arm.neon.vqdmull
+    1, // llvm.arm.neon.vqmovns
+    1, // llvm.arm.neon.vqmovnsu
+    1, // llvm.arm.neon.vqmovnu
+    1, // llvm.arm.neon.vqneg
+    1, // llvm.arm.neon.vqrdmulh
+    1, // llvm.arm.neon.vqrshiftns
+    1, // llvm.arm.neon.vqrshiftnsu
+    1, // llvm.arm.neon.vqrshiftnu
+    1, // llvm.arm.neon.vqrshifts
+    1, // llvm.arm.neon.vqrshiftu
+    1, // llvm.arm.neon.vqshiftns
+    1, // llvm.arm.neon.vqshiftnsu
+    1, // llvm.arm.neon.vqshiftnu
+    1, // llvm.arm.neon.vqshifts
+    1, // llvm.arm.neon.vqshiftsu
+    1, // llvm.arm.neon.vqshiftu
+    1, // llvm.arm.neon.vqsubs
+    1, // llvm.arm.neon.vqsubu
+    1, // llvm.arm.neon.vraddhn
+    1, // llvm.arm.neon.vrecpe
+    1, // llvm.arm.neon.vrecps
+    1, // llvm.arm.neon.vrhadds
+    1, // llvm.arm.neon.vrhaddu
+    1, // llvm.arm.neon.vrinta
+    1, // llvm.arm.neon.vrintm
+    1, // llvm.arm.neon.vrintn
+    1, // llvm.arm.neon.vrintp
+    1, // llvm.arm.neon.vrintx
+    1, // llvm.arm.neon.vrintz
+    1, // llvm.arm.neon.vrshiftn
+    1, // llvm.arm.neon.vrshifts
+    1, // llvm.arm.neon.vrshiftu
+    1, // llvm.arm.neon.vrsqrte
+    1, // llvm.arm.neon.vrsqrts
+    1, // llvm.arm.neon.vrsubhn
+    1, // llvm.arm.neon.vshiftins
+    1, // llvm.arm.neon.vshifts
+    1, // llvm.arm.neon.vshiftu
+    2, // llvm.arm.neon.vst1
+    2, // llvm.arm.neon.vst2
+    2, // llvm.arm.neon.vst2lane
+    2, // llvm.arm.neon.vst3
+    2, // llvm.arm.neon.vst3lane
+    2, // llvm.arm.neon.vst4
+    2, // llvm.arm.neon.vst4lane
+    1, // llvm.arm.neon.vtbl1
+    1, // llvm.arm.neon.vtbl2
+    1, // llvm.arm.neon.vtbl3
+    1, // llvm.arm.neon.vtbl4
+    1, // llvm.arm.neon.vtbx1
+    1, // llvm.arm.neon.vtbx2
+    1, // llvm.arm.neon.vtbx3
+    1, // llvm.arm.neon.vtbx4
+    1, // llvm.arm.qadd
+    1, // llvm.arm.qsub
+    1, // llvm.arm.rbit
+    2, // llvm.arm.set.fpscr
+    1, // llvm.arm.ssat
+    2, // llvm.arm.stlex
+    2, // llvm.arm.stlexd
+    2, // llvm.arm.strex
+    2, // llvm.arm.strexd
+    1, // llvm.arm.thread.pointer
+    2, // llvm.arm.undefined
+    1, // llvm.arm.usat
+    1, // llvm.arm.vcvtr
+    1, // llvm.arm.vcvtru
+    1, // llvm.bswap
+    1, // llvm.ceil
+    2, // llvm.clear_cache
+    1, // llvm.convert.from.fp16
+    1, // llvm.convert.to.fp16
+    2, // llvm.convertff
+    2, // llvm.convertfsi
+    2, // llvm.convertfui
+    2, // llvm.convertsif
+    2, // llvm.convertss
+    2, // llvm.convertsu
+    2, // llvm.convertuif
+    2, // llvm.convertus
+    2, // llvm.convertuu
+    1, // llvm.copysign
+    1, // llvm.cos
+    1, // llvm.ctlz
+    1, // llvm.ctpop
+    1, // llvm.cttz
+    8, // llvm.cuda.syncthreads
+    1, // llvm.dbg.declare
+    1, // llvm.dbg.value
+    2, // llvm.debugtrap
+    1, // llvm.donothing
+    2, // llvm.eh.dwarf.cfa
+    2, // llvm.eh.return.i32
+    2, // llvm.eh.return.i64
+    1, // llvm.eh.sjlj.callsite
+    2, // llvm.eh.sjlj.functioncontext
+    9, // llvm.eh.sjlj.longjmp
+    1, // llvm.eh.sjlj.lsda
+    2, // llvm.eh.sjlj.setjmp
+    1, // llvm.eh.typeid.for
+    2, // llvm.eh.unwind.init
+    1, // llvm.exp
+    1, // llvm.exp2
+    1, // llvm.expect
+    2, // llvm.experimental.patchpoint.i64
+    2, // llvm.experimental.patchpoint.void
+    10, // llvm.experimental.stackmap
+    1, // llvm.fabs
+    1, // llvm.floor
+    2, // llvm.flt.rounds
+    1, // llvm.fma
+    1, // llvm.fmuladd
+    1, // llvm.frameaddress
+    3, // llvm.gcread
+    2, // llvm.gcroot
+    11, // llvm.gcwrite
+    1, // llvm.hexagon.A2.abs
+    1, // llvm.hexagon.A2.absp
+    1, // llvm.hexagon.A2.abssat
+    1, // llvm.hexagon.A2.add
+    1, // llvm.hexagon.A2.addh.h16.hh
+    1, // llvm.hexagon.A2.addh.h16.hl
+    1, // llvm.hexagon.A2.addh.h16.lh
+    1, // llvm.hexagon.A2.addh.h16.ll
+    1, // llvm.hexagon.A2.addh.h16.sat.hh
+    1, // llvm.hexagon.A2.addh.h16.sat.hl
+    1, // llvm.hexagon.A2.addh.h16.sat.lh
+    1, // llvm.hexagon.A2.addh.h16.sat.ll
+    1, // llvm.hexagon.A2.addh.l16.hl
+    1, // llvm.hexagon.A2.addh.l16.ll
+    1, // llvm.hexagon.A2.addh.l16.sat.hl
+    1, // llvm.hexagon.A2.addh.l16.sat.ll
+    1, // llvm.hexagon.A2.addi
+    1, // llvm.hexagon.A2.addp
+    1, // llvm.hexagon.A2.addpsat
+    1, // llvm.hexagon.A2.addsat
+    1, // llvm.hexagon.A2.addsp
+    1, // llvm.hexagon.A2.and
+    1, // llvm.hexagon.A2.andir
+    1, // llvm.hexagon.A2.andp
+    1, // llvm.hexagon.A2.aslh
+    1, // llvm.hexagon.A2.asrh
+    1, // llvm.hexagon.A2.combine.hh
+    1, // llvm.hexagon.A2.combine.hl
+    1, // llvm.hexagon.A2.combine.lh
+    1, // llvm.hexagon.A2.combine.ll
+    1, // llvm.hexagon.A2.combineii
+    1, // llvm.hexagon.A2.combinew
+    1, // llvm.hexagon.A2.max
+    1, // llvm.hexagon.A2.maxp
+    1, // llvm.hexagon.A2.maxu
+    1, // llvm.hexagon.A2.maxup
+    1, // llvm.hexagon.A2.min
+    1, // llvm.hexagon.A2.minp
+    1, // llvm.hexagon.A2.minu
+    1, // llvm.hexagon.A2.minup
+    1, // llvm.hexagon.A2.neg
+    1, // llvm.hexagon.A2.negp
+    1, // llvm.hexagon.A2.negsat
+    1, // llvm.hexagon.A2.not
+    1, // llvm.hexagon.A2.notp
+    1, // llvm.hexagon.A2.or
+    1, // llvm.hexagon.A2.orir
+    1, // llvm.hexagon.A2.orp
+    1, // llvm.hexagon.A2.roundsat
+    1, // llvm.hexagon.A2.sat
+    1, // llvm.hexagon.A2.satb
+    1, // llvm.hexagon.A2.sath
+    1, // llvm.hexagon.A2.satub
+    1, // llvm.hexagon.A2.satuh
+    1, // llvm.hexagon.A2.sub
+    1, // llvm.hexagon.A2.subh.h16.hh
+    1, // llvm.hexagon.A2.subh.h16.hl
+    1, // llvm.hexagon.A2.subh.h16.lh
+    1, // llvm.hexagon.A2.subh.h16.ll
+    1, // llvm.hexagon.A2.subh.h16.sat.hh
+    1, // llvm.hexagon.A2.subh.h16.sat.hl
+    1, // llvm.hexagon.A2.subh.h16.sat.lh
+    1, // llvm.hexagon.A2.subh.h16.sat.ll
+    1, // llvm.hexagon.A2.subh.l16.hl
+    1, // llvm.hexagon.A2.subh.l16.ll
+    1, // llvm.hexagon.A2.subh.l16.sat.hl
+    1, // llvm.hexagon.A2.subh.l16.sat.ll
+    1, // llvm.hexagon.A2.subp
+    1, // llvm.hexagon.A2.subri
+    1, // llvm.hexagon.A2.subsat
+    1, // llvm.hexagon.A2.svaddh
+    1, // llvm.hexagon.A2.svaddhs
+    1, // llvm.hexagon.A2.svadduhs
+    1, // llvm.hexagon.A2.svavgh
+    1, // llvm.hexagon.A2.svavghs
+    1, // llvm.hexagon.A2.svnavgh
+    1, // llvm.hexagon.A2.svsubh
+    1, // llvm.hexagon.A2.svsubhs
+    1, // llvm.hexagon.A2.svsubuhs
+    1, // llvm.hexagon.A2.swiz
+    1, // llvm.hexagon.A2.sxtb
+    1, // llvm.hexagon.A2.sxth
+    1, // llvm.hexagon.A2.sxtw
+    1, // llvm.hexagon.A2.tfr
+    1, // llvm.hexagon.A2.tfrih
+    1, // llvm.hexagon.A2.tfril
+    1, // llvm.hexagon.A2.tfrp
+    1, // llvm.hexagon.A2.tfrpi
+    1, // llvm.hexagon.A2.tfrsi
+    1, // llvm.hexagon.A2.vabsh
+    1, // llvm.hexagon.A2.vabshsat
+    1, // llvm.hexagon.A2.vabsw
+    1, // llvm.hexagon.A2.vabswsat
+    1, // llvm.hexagon.A2.vaddb.map
+    1, // llvm.hexagon.A2.vaddh
+    1, // llvm.hexagon.A2.vaddhs
+    1, // llvm.hexagon.A2.vaddub
+    1, // llvm.hexagon.A2.vaddubs
+    1, // llvm.hexagon.A2.vadduhs
+    1, // llvm.hexagon.A2.vaddw
+    1, // llvm.hexagon.A2.vaddws
+    1, // llvm.hexagon.A2.vavgh
+    1, // llvm.hexagon.A2.vavghcr
+    1, // llvm.hexagon.A2.vavghr
+    1, // llvm.hexagon.A2.vavgub
+    1, // llvm.hexagon.A2.vavgubr
+    1, // llvm.hexagon.A2.vavguh
+    1, // llvm.hexagon.A2.vavguhr
+    1, // llvm.hexagon.A2.vavguw
+    1, // llvm.hexagon.A2.vavguwr
+    1, // llvm.hexagon.A2.vavgw
+    1, // llvm.hexagon.A2.vavgwcr
+    1, // llvm.hexagon.A2.vavgwr
+    1, // llvm.hexagon.A2.vcmpbeq
+    1, // llvm.hexagon.A2.vcmpbgtu
+    1, // llvm.hexagon.A2.vcmpheq
+    1, // llvm.hexagon.A2.vcmphgt
+    1, // llvm.hexagon.A2.vcmphgtu
+    1, // llvm.hexagon.A2.vcmpweq
+    1, // llvm.hexagon.A2.vcmpwgt
+    1, // llvm.hexagon.A2.vcmpwgtu
+    1, // llvm.hexagon.A2.vconj
+    1, // llvm.hexagon.A2.vmaxb
+    1, // llvm.hexagon.A2.vmaxh
+    1, // llvm.hexagon.A2.vmaxub
+    1, // llvm.hexagon.A2.vmaxuh
+    1, // llvm.hexagon.A2.vmaxuw
+    1, // llvm.hexagon.A2.vmaxw
+    1, // llvm.hexagon.A2.vminb
+    1, // llvm.hexagon.A2.vminh
+    1, // llvm.hexagon.A2.vminub
+    1, // llvm.hexagon.A2.vminuh
+    1, // llvm.hexagon.A2.vminuw
+    1, // llvm.hexagon.A2.vminw
+    1, // llvm.hexagon.A2.vnavgh
+    1, // llvm.hexagon.A2.vnavghcr
+    1, // llvm.hexagon.A2.vnavghr
+    1, // llvm.hexagon.A2.vnavgw
+    1, // llvm.hexagon.A2.vnavgwcr
+    1, // llvm.hexagon.A2.vnavgwr
+    1, // llvm.hexagon.A2.vraddub
+    1, // llvm.hexagon.A2.vraddub.acc
+    1, // llvm.hexagon.A2.vrsadub
+    1, // llvm.hexagon.A2.vrsadub.acc
+    1, // llvm.hexagon.A2.vsubb.map
+    1, // llvm.hexagon.A2.vsubh
+    1, // llvm.hexagon.A2.vsubhs
+    1, // llvm.hexagon.A2.vsubub
+    1, // llvm.hexagon.A2.vsububs
+    1, // llvm.hexagon.A2.vsubuhs
+    1, // llvm.hexagon.A2.vsubw
+    1, // llvm.hexagon.A2.vsubws
+    1, // llvm.hexagon.A2.xor
+    1, // llvm.hexagon.A2.xorp
+    1, // llvm.hexagon.A2.zxtb
+    1, // llvm.hexagon.A2.zxth
+    1, // llvm.hexagon.A4.andn
+    1, // llvm.hexagon.A4.andnp
+    1, // llvm.hexagon.A4.bitsplit
+    1, // llvm.hexagon.A4.bitspliti
+    1, // llvm.hexagon.A4.boundscheck
+    1, // llvm.hexagon.A4.cmpbeq
+    1, // llvm.hexagon.A4.cmpbeqi
+    1, // llvm.hexagon.A4.cmpbgt
+    1, // llvm.hexagon.A4.cmpbgti
+    1, // llvm.hexagon.A4.cmpbgtu
+    1, // llvm.hexagon.A4.cmpbgtui
+    1, // llvm.hexagon.A4.cmpheq
+    1, // llvm.hexagon.A4.cmpheqi
+    1, // llvm.hexagon.A4.cmphgt
+    1, // llvm.hexagon.A4.cmphgti
+    1, // llvm.hexagon.A4.cmphgtu
+    1, // llvm.hexagon.A4.cmphgtui
+    1, // llvm.hexagon.A4.combineir
+    1, // llvm.hexagon.A4.combineri
+    1, // llvm.hexagon.A4.cround.ri
+    1, // llvm.hexagon.A4.cround.rr
+    1, // llvm.hexagon.A4.modwrapu
+    1, // llvm.hexagon.A4.orn
+    1, // llvm.hexagon.A4.ornp
+    1, // llvm.hexagon.A4.rcmpeq
+    1, // llvm.hexagon.A4.rcmpeqi
+    1, // llvm.hexagon.A4.rcmpneq
+    1, // llvm.hexagon.A4.rcmpneqi
+    1, // llvm.hexagon.A4.round.ri
+    1, // llvm.hexagon.A4.round.ri.sat
+    1, // llvm.hexagon.A4.round.rr
+    1, // llvm.hexagon.A4.round.rr.sat
+    1, // llvm.hexagon.A4.tlbmatch
+    1, // llvm.hexagon.A4.vcmpbeq.any
+    1, // llvm.hexagon.A4.vcmpbeqi
+    1, // llvm.hexagon.A4.vcmpbgt
+    1, // llvm.hexagon.A4.vcmpbgti
+    1, // llvm.hexagon.A4.vcmpbgtui
+    1, // llvm.hexagon.A4.vcmpheqi
+    1, // llvm.hexagon.A4.vcmphgti
+    1, // llvm.hexagon.A4.vcmphgtui
+    1, // llvm.hexagon.A4.vcmpweqi
+    1, // llvm.hexagon.A4.vcmpwgti
+    1, // llvm.hexagon.A4.vcmpwgtui
+    1, // llvm.hexagon.A4.vrmaxh
+    1, // llvm.hexagon.A4.vrmaxuh
+    1, // llvm.hexagon.A4.vrmaxuw
+    1, // llvm.hexagon.A4.vrmaxw
+    1, // llvm.hexagon.A4.vrminh
+    1, // llvm.hexagon.A4.vrminuh
+    1, // llvm.hexagon.A4.vrminuw
+    1, // llvm.hexagon.A4.vrminw
+    1, // llvm.hexagon.A5.vaddhubs
+    1, // llvm.hexagon.C2.all8
+    1, // llvm.hexagon.C2.and
+    1, // llvm.hexagon.C2.andn
+    1, // llvm.hexagon.C2.any8
+    1, // llvm.hexagon.C2.bitsclr
+    1, // llvm.hexagon.C2.bitsclri
+    1, // llvm.hexagon.C2.bitsset
+    1, // llvm.hexagon.C2.cmpeq
+    1, // llvm.hexagon.C2.cmpeqi
+    1, // llvm.hexagon.C2.cmpeqp
+    1, // llvm.hexagon.C2.cmpgei
+    1, // llvm.hexagon.C2.cmpgeui
+    1, // llvm.hexagon.C2.cmpgt
+    1, // llvm.hexagon.C2.cmpgti
+    1, // llvm.hexagon.C2.cmpgtp
+    1, // llvm.hexagon.C2.cmpgtu
+    1, // llvm.hexagon.C2.cmpgtui
+    1, // llvm.hexagon.C2.cmpgtup
+    1, // llvm.hexagon.C2.cmplt
+    1, // llvm.hexagon.C2.cmpltu
+    1, // llvm.hexagon.C2.mask
+    1, // llvm.hexagon.C2.mux
+    1, // llvm.hexagon.C2.muxii
+    1, // llvm.hexagon.C2.muxir
+    1, // llvm.hexagon.C2.muxri
+    1, // llvm.hexagon.C2.not
+    1, // llvm.hexagon.C2.or
+    1, // llvm.hexagon.C2.orn
+    1, // llvm.hexagon.C2.pxfer.map
+    1, // llvm.hexagon.C2.tfrpr
+    1, // llvm.hexagon.C2.tfrrp
+    1, // llvm.hexagon.C2.vitpack
+    1, // llvm.hexagon.C2.vmux
+    1, // llvm.hexagon.C2.xor
+    1, // llvm.hexagon.C4.and.and
+    1, // llvm.hexagon.C4.and.andn
+    1, // llvm.hexagon.C4.and.or
+    1, // llvm.hexagon.C4.and.orn
+    1, // llvm.hexagon.C4.cmplte
+    1, // llvm.hexagon.C4.cmpltei
+    1, // llvm.hexagon.C4.cmplteu
+    1, // llvm.hexagon.C4.cmplteui
+    1, // llvm.hexagon.C4.cmpneq
+    1, // llvm.hexagon.C4.cmpneqi
+    1, // llvm.hexagon.C4.fastcorner9
+    1, // llvm.hexagon.C4.fastcorner9.not
+    1, // llvm.hexagon.C4.nbitsclr
+    1, // llvm.hexagon.C4.nbitsclri
+    1, // llvm.hexagon.C4.nbitsset
+    1, // llvm.hexagon.C4.or.and
+    1, // llvm.hexagon.C4.or.andn
+    1, // llvm.hexagon.C4.or.or
+    1, // llvm.hexagon.C4.or.orn
+    1, // llvm.hexagon.F2.conv.d2df
+    1, // llvm.hexagon.F2.conv.d2sf
+    1, // llvm.hexagon.F2.conv.df2d
+    1, // llvm.hexagon.F2.conv.df2d.chop
+    1, // llvm.hexagon.F2.conv.df2sf
+    1, // llvm.hexagon.F2.conv.df2ud
+    1, // llvm.hexagon.F2.conv.df2ud.chop
+    1, // llvm.hexagon.F2.conv.df2uw
+    1, // llvm.hexagon.F2.conv.df2uw.chop
+    1, // llvm.hexagon.F2.conv.df2w
+    1, // llvm.hexagon.F2.conv.df2w.chop
+    1, // llvm.hexagon.F2.conv.sf2d
+    1, // llvm.hexagon.F2.conv.sf2d.chop
+    1, // llvm.hexagon.F2.conv.sf2df
+    1, // llvm.hexagon.F2.conv.sf2ud
+    1, // llvm.hexagon.F2.conv.sf2ud.chop
+    1, // llvm.hexagon.F2.conv.sf2uw
+    1, // llvm.hexagon.F2.conv.sf2uw.chop
+    1, // llvm.hexagon.F2.conv.sf2w
+    1, // llvm.hexagon.F2.conv.sf2w.chop
+    1, // llvm.hexagon.F2.conv.ud2df
+    1, // llvm.hexagon.F2.conv.ud2sf
+    1, // llvm.hexagon.F2.conv.uw2df
+    1, // llvm.hexagon.F2.conv.uw2sf
+    1, // llvm.hexagon.F2.conv.w2df
+    1, // llvm.hexagon.F2.conv.w2sf
+    1, // llvm.hexagon.F2.dfadd
+    1, // llvm.hexagon.F2.dfclass
+    1, // llvm.hexagon.F2.dfcmpeq
+    1, // llvm.hexagon.F2.dfcmpge
+    1, // llvm.hexagon.F2.dfcmpgt
+    1, // llvm.hexagon.F2.dfcmpuo
+    1, // llvm.hexagon.F2.dffixupd
+    1, // llvm.hexagon.F2.dffixupn
+    1, // llvm.hexagon.F2.dffixupr
+    1, // llvm.hexagon.F2.dffma
+    1, // llvm.hexagon.F2.dffma.lib
+    1, // llvm.hexagon.F2.dffma.sc
+    1, // llvm.hexagon.F2.dffms
+    1, // llvm.hexagon.F2.dffms.lib
+    1, // llvm.hexagon.F2.dfimm.n
+    1, // llvm.hexagon.F2.dfimm.p
+    1, // llvm.hexagon.F2.dfmax
+    1, // llvm.hexagon.F2.dfmin
+    1, // llvm.hexagon.F2.dfmpy
+    1, // llvm.hexagon.F2.dfsub
+    1, // llvm.hexagon.F2.sfadd
+    1, // llvm.hexagon.F2.sfclass
+    1, // llvm.hexagon.F2.sfcmpeq
+    1, // llvm.hexagon.F2.sfcmpge
+    1, // llvm.hexagon.F2.sfcmpgt
+    1, // llvm.hexagon.F2.sfcmpuo
+    1, // llvm.hexagon.F2.sffixupd
+    1, // llvm.hexagon.F2.sffixupn
+    1, // llvm.hexagon.F2.sffixupr
+    1, // llvm.hexagon.F2.sffma
+    1, // llvm.hexagon.F2.sffma.lib
+    1, // llvm.hexagon.F2.sffma.sc
+    1, // llvm.hexagon.F2.sffms
+    1, // llvm.hexagon.F2.sffms.lib
+    1, // llvm.hexagon.F2.sfimm.n
+    1, // llvm.hexagon.F2.sfimm.p
+    1, // llvm.hexagon.F2.sfmax
+    1, // llvm.hexagon.F2.sfmin
+    1, // llvm.hexagon.F2.sfmpy
+    1, // llvm.hexagon.F2.sfsub
+    1, // llvm.hexagon.M2.acci
+    1, // llvm.hexagon.M2.accii
+    1, // llvm.hexagon.M2.cmaci.s0
+    1, // llvm.hexagon.M2.cmacr.s0
+    1, // llvm.hexagon.M2.cmacs.s0
+    1, // llvm.hexagon.M2.cmacs.s1
+    1, // llvm.hexagon.M2.cmacsc.s0
+    1, // llvm.hexagon.M2.cmacsc.s1
+    1, // llvm.hexagon.M2.cmpyi.s0
+    1, // llvm.hexagon.M2.cmpyr.s0
+    1, // llvm.hexagon.M2.cmpyrs.s0
+    1, // llvm.hexagon.M2.cmpyrs.s1
+    1, // llvm.hexagon.M2.cmpyrsc.s0
+    1, // llvm.hexagon.M2.cmpyrsc.s1
+    1, // llvm.hexagon.M2.cmpys.s0
+    1, // llvm.hexagon.M2.cmpys.s1
+    1, // llvm.hexagon.M2.cmpysc.s0
+    1, // llvm.hexagon.M2.cmpysc.s1
+    1, // llvm.hexagon.M2.cnacs.s0
+    1, // llvm.hexagon.M2.cnacs.s1
+    1, // llvm.hexagon.M2.cnacsc.s0
+    1, // llvm.hexagon.M2.cnacsc.s1
+    1, // llvm.hexagon.M2.dpmpyss.acc.s0
+    1, // llvm.hexagon.M2.dpmpyss.nac.s0
+    1, // llvm.hexagon.M2.dpmpyss.rnd.s0
+    1, // llvm.hexagon.M2.dpmpyss.s0
+    1, // llvm.hexagon.M2.dpmpyuu.acc.s0
+    1, // llvm.hexagon.M2.dpmpyuu.nac.s0
+    1, // llvm.hexagon.M2.dpmpyuu.s0
+    1, // llvm.hexagon.M2.hmmpyh.rs1
+    1, // llvm.hexagon.M2.hmmpyh.s1
+    1, // llvm.hexagon.M2.hmmpyl.rs1
+    1, // llvm.hexagon.M2.hmmpyl.s1
+    1, // llvm.hexagon.M2.maci
+    1, // llvm.hexagon.M2.macsin
+    1, // llvm.hexagon.M2.macsip
+    1, // llvm.hexagon.M2.mmachs.rs0
+    1, // llvm.hexagon.M2.mmachs.rs1
+    1, // llvm.hexagon.M2.mmachs.s0
+    1, // llvm.hexagon.M2.mmachs.s1
+    1, // llvm.hexagon.M2.mmacls.rs0
+    1, // llvm.hexagon.M2.mmacls.rs1
+    1, // llvm.hexagon.M2.mmacls.s0
+    1, // llvm.hexagon.M2.mmacls.s1
+    1, // llvm.hexagon.M2.mmacuhs.rs0
+    1, // llvm.hexagon.M2.mmacuhs.rs1
+    1, // llvm.hexagon.M2.mmacuhs.s0
+    1, // llvm.hexagon.M2.mmacuhs.s1
+    1, // llvm.hexagon.M2.mmaculs.rs0
+    1, // llvm.hexagon.M2.mmaculs.rs1
+    1, // llvm.hexagon.M2.mmaculs.s0
+    1, // llvm.hexagon.M2.mmaculs.s1
+    1, // llvm.hexagon.M2.mmpyh.rs0
+    1, // llvm.hexagon.M2.mmpyh.rs1
+    1, // llvm.hexagon.M2.mmpyh.s0
+    1, // llvm.hexagon.M2.mmpyh.s1
+    1, // llvm.hexagon.M2.mmpyl.rs0
+    1, // llvm.hexagon.M2.mmpyl.rs1
+    1, // llvm.hexagon.M2.mmpyl.s0
+    1, // llvm.hexagon.M2.mmpyl.s1
+    1, // llvm.hexagon.M2.mmpyuh.rs0
+    1, // llvm.hexagon.M2.mmpyuh.rs1
+    1, // llvm.hexagon.M2.mmpyuh.s0
+    1, // llvm.hexagon.M2.mmpyuh.s1
+    1, // llvm.hexagon.M2.mmpyul.rs0
+    1, // llvm.hexagon.M2.mmpyul.rs1
+    1, // llvm.hexagon.M2.mmpyul.s0
+    1, // llvm.hexagon.M2.mmpyul.s1
+    1, // llvm.hexagon.M2.mpy.acc.hh.s0
+    1, // llvm.hexagon.M2.mpy.acc.hh.s1
+    1, // llvm.hexagon.M2.mpy.acc.hl.s0
+    1, // llvm.hexagon.M2.mpy.acc.hl.s1
+    1, // llvm.hexagon.M2.mpy.acc.lh.s0
+    1, // llvm.hexagon.M2.mpy.acc.lh.s1
+    1, // llvm.hexagon.M2.mpy.acc.ll.s0
+    1, // llvm.hexagon.M2.mpy.acc.ll.s1
+    1, // llvm.hexagon.M2.mpy.acc.sat.hh.s0
+    1, // llvm.hexagon.M2.mpy.acc.sat.hh.s1
+    1, // llvm.hexagon.M2.mpy.acc.sat.hl.s0
+    1, // llvm.hexagon.M2.mpy.acc.sat.hl.s1
+    1, // llvm.hexagon.M2.mpy.acc.sat.lh.s0
+    1, // llvm.hexagon.M2.mpy.acc.sat.lh.s1
+    1, // llvm.hexagon.M2.mpy.acc.sat.ll.s0
+    1, // llvm.hexagon.M2.mpy.acc.sat.ll.s1
+    1, // llvm.hexagon.M2.mpy.hh.s0
+    1, // llvm.hexagon.M2.mpy.hh.s1
+    1, // llvm.hexagon.M2.mpy.hl.s0
+    1, // llvm.hexagon.M2.mpy.hl.s1
+    1, // llvm.hexagon.M2.mpy.lh.s0
+    1, // llvm.hexagon.M2.mpy.lh.s1
+    1, // llvm.hexagon.M2.mpy.ll.s0
+    1, // llvm.hexagon.M2.mpy.ll.s1
+    1, // llvm.hexagon.M2.mpy.nac.hh.s0
+    1, // llvm.hexagon.M2.mpy.nac.hh.s1
+    1, // llvm.hexagon.M2.mpy.nac.hl.s0
+    1, // llvm.hexagon.M2.mpy.nac.hl.s1
+    1, // llvm.hexagon.M2.mpy.nac.lh.s0
+    1, // llvm.hexagon.M2.mpy.nac.lh.s1
+    1, // llvm.hexagon.M2.mpy.nac.ll.s0
+    1, // llvm.hexagon.M2.mpy.nac.ll.s1
+    1, // llvm.hexagon.M2.mpy.nac.sat.hh.s0
+    1, // llvm.hexagon.M2.mpy.nac.sat.hh.s1
+    1, // llvm.hexagon.M2.mpy.nac.sat.hl.s0
+    1, // llvm.hexagon.M2.mpy.nac.sat.hl.s1
+    1, // llvm.hexagon.M2.mpy.nac.sat.lh.s0
+    1, // llvm.hexagon.M2.mpy.nac.sat.lh.s1
+    1, // llvm.hexagon.M2.mpy.nac.sat.ll.s0
+    1, // llvm.hexagon.M2.mpy.nac.sat.ll.s1
+    1, // llvm.hexagon.M2.mpy.rnd.hh.s0
+    1, // llvm.hexagon.M2.mpy.rnd.hh.s1
+    1, // llvm.hexagon.M2.mpy.rnd.hl.s0
+    1, // llvm.hexagon.M2.mpy.rnd.hl.s1
+    1, // llvm.hexagon.M2.mpy.rnd.lh.s0
+    1, // llvm.hexagon.M2.mpy.rnd.lh.s1
+    1, // llvm.hexagon.M2.mpy.rnd.ll.s0
+    1, // llvm.hexagon.M2.mpy.rnd.ll.s1
+    1, // llvm.hexagon.M2.mpy.sat.hh.s0
+    1, // llvm.hexagon.M2.mpy.sat.hh.s1
+    1, // llvm.hexagon.M2.mpy.sat.hl.s0
+    1, // llvm.hexagon.M2.mpy.sat.hl.s1
+    1, // llvm.hexagon.M2.mpy.sat.lh.s0
+    1, // llvm.hexagon.M2.mpy.sat.lh.s1
+    1, // llvm.hexagon.M2.mpy.sat.ll.s0
+    1, // llvm.hexagon.M2.mpy.sat.ll.s1
+    1, // llvm.hexagon.M2.mpy.sat.rnd.hh.s0
+    1, // llvm.hexagon.M2.mpy.sat.rnd.hh.s1
+    1, // llvm.hexagon.M2.mpy.sat.rnd.hl.s0
+    1, // llvm.hexagon.M2.mpy.sat.rnd.hl.s1
+    1, // llvm.hexagon.M2.mpy.sat.rnd.lh.s0
+    1, // llvm.hexagon.M2.mpy.sat.rnd.lh.s1
+    1, // llvm.hexagon.M2.mpy.sat.rnd.ll.s0
+    1, // llvm.hexagon.M2.mpy.sat.rnd.ll.s1
+    1, // llvm.hexagon.M2.mpy.up
+    1, // llvm.hexagon.M2.mpy.up.s1
+    1, // llvm.hexagon.M2.mpy.up.s1.sat
+    1, // llvm.hexagon.M2.mpyd.acc.hh.s0
+    1, // llvm.hexagon.M2.mpyd.acc.hh.s1
+    1, // llvm.hexagon.M2.mpyd.acc.hl.s0
+    1, // llvm.hexagon.M2.mpyd.acc.hl.s1
+    1, // llvm.hexagon.M2.mpyd.acc.lh.s0
+    1, // llvm.hexagon.M2.mpyd.acc.lh.s1
+    1, // llvm.hexagon.M2.mpyd.acc.ll.s0
+    1, // llvm.hexagon.M2.mpyd.acc.ll.s1
+    1, // llvm.hexagon.M2.mpyd.hh.s0
+    1, // llvm.hexagon.M2.mpyd.hh.s1
+    1, // llvm.hexagon.M2.mpyd.hl.s0
+    1, // llvm.hexagon.M2.mpyd.hl.s1
+    1, // llvm.hexagon.M2.mpyd.lh.s0
+    1, // llvm.hexagon.M2.mpyd.lh.s1
+    1, // llvm.hexagon.M2.mpyd.ll.s0
+    1, // llvm.hexagon.M2.mpyd.ll.s1
+    1, // llvm.hexagon.M2.mpyd.nac.hh.s0
+    1, // llvm.hexagon.M2.mpyd.nac.hh.s1
+    1, // llvm.hexagon.M2.mpyd.nac.hl.s0
+    1, // llvm.hexagon.M2.mpyd.nac.hl.s1
+    1, // llvm.hexagon.M2.mpyd.nac.lh.s0
+    1, // llvm.hexagon.M2.mpyd.nac.lh.s1
+    1, // llvm.hexagon.M2.mpyd.nac.ll.s0
+    1, // llvm.hexagon.M2.mpyd.nac.ll.s1
+    1, // llvm.hexagon.M2.mpyd.rnd.hh.s0
+    1, // llvm.hexagon.M2.mpyd.rnd.hh.s1
+    1, // llvm.hexagon.M2.mpyd.rnd.hl.s0
+    1, // llvm.hexagon.M2.mpyd.rnd.hl.s1
+    1, // llvm.hexagon.M2.mpyd.rnd.lh.s0
+    1, // llvm.hexagon.M2.mpyd.rnd.lh.s1
+    1, // llvm.hexagon.M2.mpyd.rnd.ll.s0
+    1, // llvm.hexagon.M2.mpyd.rnd.ll.s1
+    1, // llvm.hexagon.M2.mpyi
+    1, // llvm.hexagon.M2.mpysmi
+    1, // llvm.hexagon.M2.mpysu.up
+    1, // llvm.hexagon.M2.mpyu.acc.hh.s0
+    1, // llvm.hexagon.M2.mpyu.acc.hh.s1
+    1, // llvm.hexagon.M2.mpyu.acc.hl.s0
+    1, // llvm.hexagon.M2.mpyu.acc.hl.s1
+    1, // llvm.hexagon.M2.mpyu.acc.lh.s0
+    1, // llvm.hexagon.M2.mpyu.acc.lh.s1
+    1, // llvm.hexagon.M2.mpyu.acc.ll.s0
+    1, // llvm.hexagon.M2.mpyu.acc.ll.s1
+    1, // llvm.hexagon.M2.mpyu.hh.s0
+    1, // llvm.hexagon.M2.mpyu.hh.s1
+    1, // llvm.hexagon.M2.mpyu.hl.s0
+    1, // llvm.hexagon.M2.mpyu.hl.s1
+    1, // llvm.hexagon.M2.mpyu.lh.s0
+    1, // llvm.hexagon.M2.mpyu.lh.s1
+    1, // llvm.hexagon.M2.mpyu.ll.s0
+    1, // llvm.hexagon.M2.mpyu.ll.s1
+    1, // llvm.hexagon.M2.mpyu.nac.hh.s0
+    1, // llvm.hexagon.M2.mpyu.nac.hh.s1
+    1, // llvm.hexagon.M2.mpyu.nac.hl.s0
+    1, // llvm.hexagon.M2.mpyu.nac.hl.s1
+    1, // llvm.hexagon.M2.mpyu.nac.lh.s0
+    1, // llvm.hexagon.M2.mpyu.nac.lh.s1
+    1, // llvm.hexagon.M2.mpyu.nac.ll.s0
+    1, // llvm.hexagon.M2.mpyu.nac.ll.s1
+    1, // llvm.hexagon.M2.mpyu.up
+    1, // llvm.hexagon.M2.mpyud.acc.hh.s0
+    1, // llvm.hexagon.M2.mpyud.acc.hh.s1
+    1, // llvm.hexagon.M2.mpyud.acc.hl.s0
+    1, // llvm.hexagon.M2.mpyud.acc.hl.s1
+    1, // llvm.hexagon.M2.mpyud.acc.lh.s0
+    1, // llvm.hexagon.M2.mpyud.acc.lh.s1
+    1, // llvm.hexagon.M2.mpyud.acc.ll.s0
+    1, // llvm.hexagon.M2.mpyud.acc.ll.s1
+    1, // llvm.hexagon.M2.mpyud.hh.s0
+    1, // llvm.hexagon.M2.mpyud.hh.s1
+    1, // llvm.hexagon.M2.mpyud.hl.s0
+    1, // llvm.hexagon.M2.mpyud.hl.s1
+    1, // llvm.hexagon.M2.mpyud.lh.s0
+    1, // llvm.hexagon.M2.mpyud.lh.s1
+    1, // llvm.hexagon.M2.mpyud.ll.s0
+    1, // llvm.hexagon.M2.mpyud.ll.s1
+    1, // llvm.hexagon.M2.mpyud.nac.hh.s0
+    1, // llvm.hexagon.M2.mpyud.nac.hh.s1
+    1, // llvm.hexagon.M2.mpyud.nac.hl.s0
+    1, // llvm.hexagon.M2.mpyud.nac.hl.s1
+    1, // llvm.hexagon.M2.mpyud.nac.lh.s0
+    1, // llvm.hexagon.M2.mpyud.nac.lh.s1
+    1, // llvm.hexagon.M2.mpyud.nac.ll.s0
+    1, // llvm.hexagon.M2.mpyud.nac.ll.s1
+    1, // llvm.hexagon.M2.mpyui
+    1, // llvm.hexagon.M2.nacci
+    1, // llvm.hexagon.M2.naccii
+    1, // llvm.hexagon.M2.subacc
+    1, // llvm.hexagon.M2.vabsdiffh
+    1, // llvm.hexagon.M2.vabsdiffw
+    1, // llvm.hexagon.M2.vcmac.s0.sat.i
+    1, // llvm.hexagon.M2.vcmac.s0.sat.r
+    1, // llvm.hexagon.M2.vcmpy.s0.sat.i
+    1, // llvm.hexagon.M2.vcmpy.s0.sat.r
+    1, // llvm.hexagon.M2.vcmpy.s1.sat.i
+    1, // llvm.hexagon.M2.vcmpy.s1.sat.r
+    1, // llvm.hexagon.M2.vdmacs.s0
+    1, // llvm.hexagon.M2.vdmacs.s1
+    1, // llvm.hexagon.M2.vdmpyrs.s0
+    1, // llvm.hexagon.M2.vdmpyrs.s1
+    1, // llvm.hexagon.M2.vdmpys.s0
+    1, // llvm.hexagon.M2.vdmpys.s1
+    1, // llvm.hexagon.M2.vmac2
+    1, // llvm.hexagon.M2.vmac2es
+    1, // llvm.hexagon.M2.vmac2es.s0
+    1, // llvm.hexagon.M2.vmac2es.s1
+    1, // llvm.hexagon.M2.vmac2s.s0
+    1, // llvm.hexagon.M2.vmac2s.s1
+    1, // llvm.hexagon.M2.vmac2su.s0
+    1, // llvm.hexagon.M2.vmac2su.s1
+    1, // llvm.hexagon.M2.vmpy2es.s0
+    1, // llvm.hexagon.M2.vmpy2es.s1
+    1, // llvm.hexagon.M2.vmpy2s.s0
+    1, // llvm.hexagon.M2.vmpy2s.s0pack
+    1, // llvm.hexagon.M2.vmpy2s.s1
+    1, // llvm.hexagon.M2.vmpy2s.s1pack
+    1, // llvm.hexagon.M2.vmpy2su.s0
+    1, // llvm.hexagon.M2.vmpy2su.s1
+    1, // llvm.hexagon.M2.vraddh
+    1, // llvm.hexagon.M2.vradduh
+    1, // llvm.hexagon.M2.vrcmaci.s0
+    1, // llvm.hexagon.M2.vrcmaci.s0c
+    1, // llvm.hexagon.M2.vrcmacr.s0
+    1, // llvm.hexagon.M2.vrcmacr.s0c
+    1, // llvm.hexagon.M2.vrcmpyi.s0
+    1, // llvm.hexagon.M2.vrcmpyi.s0c
+    1, // llvm.hexagon.M2.vrcmpyr.s0
+    1, // llvm.hexagon.M2.vrcmpyr.s0c
+    1, // llvm.hexagon.M2.vrcmpys.acc.s1
+    1, // llvm.hexagon.M2.vrcmpys.s1
+    1, // llvm.hexagon.M2.vrcmpys.s1rp
+    1, // llvm.hexagon.M2.vrmac.s0
+    1, // llvm.hexagon.M2.vrmpy.s0
+    1, // llvm.hexagon.M2.xor.xacc
+    1, // llvm.hexagon.M4.and.and
+    1, // llvm.hexagon.M4.and.andn
+    1, // llvm.hexagon.M4.and.or
+    1, // llvm.hexagon.M4.and.xor
+    1, // llvm.hexagon.M4.cmpyi.wh
+    1, // llvm.hexagon.M4.cmpyi.whc
+    1, // llvm.hexagon.M4.cmpyr.wh
+    1, // llvm.hexagon.M4.cmpyr.whc
+    1, // llvm.hexagon.M4.mac.up.s1.sat
+    1, // llvm.hexagon.M4.mpyri.addi
+    1, // llvm.hexagon.M4.mpyri.addr
+    1, // llvm.hexagon.M4.mpyri.addr.u2
+    1, // llvm.hexagon.M4.mpyrr.addi
+    1, // llvm.hexagon.M4.mpyrr.addr
+    1, // llvm.hexagon.M4.nac.up.s1.sat
+    1, // llvm.hexagon.M4.or.and
+    1, // llvm.hexagon.M4.or.andn
+    1, // llvm.hexagon.M4.or.or
+    1, // llvm.hexagon.M4.or.xor
+    1, // llvm.hexagon.M4.pmpyw
+    1, // llvm.hexagon.M4.pmpyw.acc
+    1, // llvm.hexagon.M4.vpmpyh
+    1, // llvm.hexagon.M4.vpmpyh.acc
+    1, // llvm.hexagon.M4.vrmpyeh.acc.s0
+    1, // llvm.hexagon.M4.vrmpyeh.acc.s1
+    1, // llvm.hexagon.M4.vrmpyeh.s0
+    1, // llvm.hexagon.M4.vrmpyeh.s1
+    1, // llvm.hexagon.M4.vrmpyoh.acc.s0
+    1, // llvm.hexagon.M4.vrmpyoh.acc.s1
+    1, // llvm.hexagon.M4.vrmpyoh.s0
+    1, // llvm.hexagon.M4.vrmpyoh.s1
+    1, // llvm.hexagon.M4.xor.and
+    1, // llvm.hexagon.M4.xor.andn
+    1, // llvm.hexagon.M4.xor.or
+    1, // llvm.hexagon.M4.xor.xacc
+    1, // llvm.hexagon.M5.vdmacbsu
+    1, // llvm.hexagon.M5.vdmpybsu
+    1, // llvm.hexagon.M5.vmacbsu
+    1, // llvm.hexagon.M5.vmacbuu
+    1, // llvm.hexagon.M5.vmpybsu
+    1, // llvm.hexagon.M5.vmpybuu
+    1, // llvm.hexagon.M5.vrmacbsu
+    1, // llvm.hexagon.M5.vrmacbuu
+    1, // llvm.hexagon.M5.vrmpybsu
+    1, // llvm.hexagon.M5.vrmpybuu
+    1, // llvm.hexagon.S2.addasl.rrri
+    1, // llvm.hexagon.S2.asl.i.p
+    1, // llvm.hexagon.S2.asl.i.p.acc
+    1, // llvm.hexagon.S2.asl.i.p.and
+    1, // llvm.hexagon.S2.asl.i.p.nac
+    1, // llvm.hexagon.S2.asl.i.p.or
+    1, // llvm.hexagon.S2.asl.i.p.xacc
+    1, // llvm.hexagon.S2.asl.i.r
+    1, // llvm.hexagon.S2.asl.i.r.acc
+    1, // llvm.hexagon.S2.asl.i.r.and
+    1, // llvm.hexagon.S2.asl.i.r.nac
+    1, // llvm.hexagon.S2.asl.i.r.or
+    1, // llvm.hexagon.S2.asl.i.r.sat
+    1, // llvm.hexagon.S2.asl.i.r.xacc
+    1, // llvm.hexagon.S2.asl.i.vh
+    1, // llvm.hexagon.S2.asl.i.vw
+    1, // llvm.hexagon.S2.asl.r.p
+    1, // llvm.hexagon.S2.asl.r.p.acc
+    1, // llvm.hexagon.S2.asl.r.p.and
+    1, // llvm.hexagon.S2.asl.r.p.nac
+    1, // llvm.hexagon.S2.asl.r.p.or
+    1, // llvm.hexagon.S2.asl.r.p.xor
+    1, // llvm.hexagon.S2.asl.r.r
+    1, // llvm.hexagon.S2.asl.r.r.acc
+    1, // llvm.hexagon.S2.asl.r.r.and
+    1, // llvm.hexagon.S2.asl.r.r.nac
+    1, // llvm.hexagon.S2.asl.r.r.or
+    1, // llvm.hexagon.S2.asl.r.r.sat
+    1, // llvm.hexagon.S2.asl.r.vh
+    1, // llvm.hexagon.S2.asl.r.vw
+    1, // llvm.hexagon.S2.asr.i.p
+    1, // llvm.hexagon.S2.asr.i.p.acc
+    1, // llvm.hexagon.S2.asr.i.p.and
+    1, // llvm.hexagon.S2.asr.i.p.nac
+    1, // llvm.hexagon.S2.asr.i.p.or
+    1, // llvm.hexagon.S2.asr.i.p.rnd
+    1, // llvm.hexagon.S2.asr.i.p.rnd.goodsyntax
+    1, // llvm.hexagon.S2.asr.i.r
+    1, // llvm.hexagon.S2.asr.i.r.acc
+    1, // llvm.hexagon.S2.asr.i.r.and
+    1, // llvm.hexagon.S2.asr.i.r.nac
+    1, // llvm.hexagon.S2.asr.i.r.or
+    1, // llvm.hexagon.S2.asr.i.r.rnd
+    1, // llvm.hexagon.S2.asr.i.r.rnd.goodsyntax
+    1, // llvm.hexagon.S2.asr.i.svw.trun
+    1, // llvm.hexagon.S2.asr.i.vh
+    1, // llvm.hexagon.S2.asr.i.vw
+    1, // llvm.hexagon.S2.asr.r.p
+    1, // llvm.hexagon.S2.asr.r.p.acc
+    1, // llvm.hexagon.S2.asr.r.p.and
+    1, // llvm.hexagon.S2.asr.r.p.nac
+    1, // llvm.hexagon.S2.asr.r.p.or
+    1, // llvm.hexagon.S2.asr.r.p.xor
+    1, // llvm.hexagon.S2.asr.r.r
+    1, // llvm.hexagon.S2.asr.r.r.acc
+    1, // llvm.hexagon.S2.asr.r.r.and
+    1, // llvm.hexagon.S2.asr.r.r.nac
+    1, // llvm.hexagon.S2.asr.r.r.or
+    1, // llvm.hexagon.S2.asr.r.r.sat
+    1, // llvm.hexagon.S2.asr.r.svw.trun
+    1, // llvm.hexagon.S2.asr.r.vh
+    1, // llvm.hexagon.S2.asr.r.vw
+    1, // llvm.hexagon.S2.brev
+    1, // llvm.hexagon.S2.brevp
+    1, // llvm.hexagon.S2.cl0
+    1, // llvm.hexagon.S2.cl0p
+    1, // llvm.hexagon.S2.cl1
+    1, // llvm.hexagon.S2.cl1p
+    1, // llvm.hexagon.S2.clb
+    1, // llvm.hexagon.S2.clbnorm
+    1, // llvm.hexagon.S2.clbp
+    1, // llvm.hexagon.S2.clrbit.i
+    1, // llvm.hexagon.S2.clrbit.r
+    1, // llvm.hexagon.S2.ct0
+    1, // llvm.hexagon.S2.ct0p
+    1, // llvm.hexagon.S2.ct1
+    1, // llvm.hexagon.S2.ct1p
+    1, // llvm.hexagon.S2.deinterleave
+    1, // llvm.hexagon.S2.extractu
+    1, // llvm.hexagon.S2.extractu.rp
+    1, // llvm.hexagon.S2.extractup
+    1, // llvm.hexagon.S2.extractup.rp
+    1, // llvm.hexagon.S2.insert
+    1, // llvm.hexagon.S2.insert.rp
+    1, // llvm.hexagon.S2.insertp
+    1, // llvm.hexagon.S2.insertp.rp
+    1, // llvm.hexagon.S2.interleave
+    1, // llvm.hexagon.S2.lfsp
+    1, // llvm.hexagon.S2.lsl.r.p
+    1, // llvm.hexagon.S2.lsl.r.p.acc
+    1, // llvm.hexagon.S2.lsl.r.p.and
+    1, // llvm.hexagon.S2.lsl.r.p.nac
+    1, // llvm.hexagon.S2.lsl.r.p.or
+    1, // llvm.hexagon.S2.lsl.r.p.xor
+    1, // llvm.hexagon.S2.lsl.r.r
+    1, // llvm.hexagon.S2.lsl.r.r.acc
+    1, // llvm.hexagon.S2.lsl.r.r.and
+    1, // llvm.hexagon.S2.lsl.r.r.nac
+    1, // llvm.hexagon.S2.lsl.r.r.or
+    1, // llvm.hexagon.S2.lsl.r.vh
+    1, // llvm.hexagon.S2.lsl.r.vw
+    1, // llvm.hexagon.S2.lsr.i.p
+    1, // llvm.hexagon.S2.lsr.i.p.acc
+    1, // llvm.hexagon.S2.lsr.i.p.and
+    1, // llvm.hexagon.S2.lsr.i.p.nac
+    1, // llvm.hexagon.S2.lsr.i.p.or
+    1, // llvm.hexagon.S2.lsr.i.p.xacc
+    1, // llvm.hexagon.S2.lsr.i.r
+    1, // llvm.hexagon.S2.lsr.i.r.acc
+    1, // llvm.hexagon.S2.lsr.i.r.and
+    1, // llvm.hexagon.S2.lsr.i.r.nac
+    1, // llvm.hexagon.S2.lsr.i.r.or
+    1, // llvm.hexagon.S2.lsr.i.r.xacc
+    1, // llvm.hexagon.S2.lsr.i.vh
+    1, // llvm.hexagon.S2.lsr.i.vw
+    1, // llvm.hexagon.S2.lsr.r.p
+    1, // llvm.hexagon.S2.lsr.r.p.acc
+    1, // llvm.hexagon.S2.lsr.r.p.and
+    1, // llvm.hexagon.S2.lsr.r.p.nac
+    1, // llvm.hexagon.S2.lsr.r.p.or
+    1, // llvm.hexagon.S2.lsr.r.p.xor
+    1, // llvm.hexagon.S2.lsr.r.r
+    1, // llvm.hexagon.S2.lsr.r.r.acc
+    1, // llvm.hexagon.S2.lsr.r.r.and
+    1, // llvm.hexagon.S2.lsr.r.r.nac
+    1, // llvm.hexagon.S2.lsr.r.r.or
+    1, // llvm.hexagon.S2.lsr.r.vh
+    1, // llvm.hexagon.S2.lsr.r.vw
+    1, // llvm.hexagon.S2.packhl
+    1, // llvm.hexagon.S2.parityp
+    1, // llvm.hexagon.S2.setbit.i
+    1, // llvm.hexagon.S2.setbit.r
+    1, // llvm.hexagon.S2.shuffeb
+    1, // llvm.hexagon.S2.shuffeh
+    1, // llvm.hexagon.S2.shuffob
+    1, // llvm.hexagon.S2.shuffoh
+    1, // llvm.hexagon.S2.svsathb
+    1, // llvm.hexagon.S2.svsathub
+    1, // llvm.hexagon.S2.tableidxb.goodsyntax
+    1, // llvm.hexagon.S2.tableidxd.goodsyntax
+    1, // llvm.hexagon.S2.tableidxh.goodsyntax
+    1, // llvm.hexagon.S2.tableidxw.goodsyntax
+    1, // llvm.hexagon.S2.togglebit.i
+    1, // llvm.hexagon.S2.togglebit.r
+    1, // llvm.hexagon.S2.tstbit.i
+    1, // llvm.hexagon.S2.tstbit.r
+    1, // llvm.hexagon.S2.valignib
+    1, // llvm.hexagon.S2.valignrb
+    1, // llvm.hexagon.S2.vcnegh
+    1, // llvm.hexagon.S2.vcrotate
+    1, // llvm.hexagon.S2.vrcnegh
+    1, // llvm.hexagon.S2.vrndpackwh
+    1, // llvm.hexagon.S2.vrndpackwhs
+    1, // llvm.hexagon.S2.vsathb
+    1, // llvm.hexagon.S2.vsathb.nopack
+    1, // llvm.hexagon.S2.vsathub
+    1, // llvm.hexagon.S2.vsathub.nopack
+    1, // llvm.hexagon.S2.vsatwh
+    1, // llvm.hexagon.S2.vsatwh.nopack
+    1, // llvm.hexagon.S2.vsatwuh
+    1, // llvm.hexagon.S2.vsatwuh.nopack
+    1, // llvm.hexagon.S2.vsplatrb
+    1, // llvm.hexagon.S2.vsplatrh
+    1, // llvm.hexagon.S2.vspliceib
+    1, // llvm.hexagon.S2.vsplicerb
+    1, // llvm.hexagon.S2.vsxtbh
+    1, // llvm.hexagon.S2.vsxthw
+    1, // llvm.hexagon.S2.vtrunehb
+    1, // llvm.hexagon.S2.vtrunewh
+    1, // llvm.hexagon.S2.vtrunohb
+    1, // llvm.hexagon.S2.vtrunowh
+    1, // llvm.hexagon.S2.vzxtbh
+    1, // llvm.hexagon.S2.vzxthw
+    1, // llvm.hexagon.S4.addaddi
+    1, // llvm.hexagon.S4.addi.asl.ri
+    1, // llvm.hexagon.S4.addi.lsr.ri
+    1, // llvm.hexagon.S4.andi.asl.ri
+    1, // llvm.hexagon.S4.andi.lsr.ri
+    1, // llvm.hexagon.S4.clbaddi
+    1, // llvm.hexagon.S4.clbpaddi
+    1, // llvm.hexagon.S4.clbpnorm
+    1, // llvm.hexagon.S4.extract
+    1, // llvm.hexagon.S4.extract.rp
+    1, // llvm.hexagon.S4.extractp
+    1, // llvm.hexagon.S4.extractp.rp
+    1, // llvm.hexagon.S4.lsli
+    1, // llvm.hexagon.S4.ntstbit.i
+    1, // llvm.hexagon.S4.ntstbit.r
+    1, // llvm.hexagon.S4.or.andi
+    1, // llvm.hexagon.S4.or.andix
+    1, // llvm.hexagon.S4.or.ori
+    1, // llvm.hexagon.S4.ori.asl.ri
+    1, // llvm.hexagon.S4.ori.lsr.ri
+    1, // llvm.hexagon.S4.parity
+    1, // llvm.hexagon.S4.subaddi
+    1, // llvm.hexagon.S4.subi.asl.ri
+    1, // llvm.hexagon.S4.subi.lsr.ri
+    1, // llvm.hexagon.S4.vrcrotate
+    1, // llvm.hexagon.S4.vrcrotate.acc
+    1, // llvm.hexagon.S4.vxaddsubh
+    1, // llvm.hexagon.S4.vxaddsubhr
+    1, // llvm.hexagon.S4.vxaddsubw
+    1, // llvm.hexagon.S4.vxsubaddh
+    1, // llvm.hexagon.S4.vxsubaddhr
+    1, // llvm.hexagon.S4.vxsubaddw
+    1, // llvm.hexagon.S5.asrhub.rnd.sat.goodsyntax
+    1, // llvm.hexagon.S5.asrhub.sat
+    1, // llvm.hexagon.S5.popcountp
+    1, // llvm.hexagon.S5.vasrhrnd.goodsyntax
+    1, // llvm.hexagon.SI.to.SXTHI.asrh
+    2, // llvm.hexagon.circ.ldd
+    12, // llvm.init.trampoline
+    4, // llvm.invariant.end
+    13, // llvm.invariant.start
+    13, // llvm.lifetime.end
+    13, // llvm.lifetime.start
+    1, // llvm.log
+    1, // llvm.log10
+    1, // llvm.log2
+    9, // llvm.longjmp
+    14, // llvm.memcpy
+    14, // llvm.memmove
+    12, // llvm.memset
+    2, // llvm.mips.absq.s.ph
+    2, // llvm.mips.absq.s.qb
+    2, // llvm.mips.absq.s.w
+    1, // llvm.mips.add.a.b
+    1, // llvm.mips.add.a.d
+    1, // llvm.mips.add.a.h
+    1, // llvm.mips.add.a.w
+    1, // llvm.mips.addq.ph
+    1, // llvm.mips.addq.s.ph
+    2, // llvm.mips.addq.s.w
+    1, // llvm.mips.addqh.ph
+    1, // llvm.mips.addqh.r.ph
+    1, // llvm.mips.addqh.r.w
+    1, // llvm.mips.addqh.w
+    1, // llvm.mips.adds.a.b
+    1, // llvm.mips.adds.a.d
+    1, // llvm.mips.adds.a.h
+    1, // llvm.mips.adds.a.w
+    1, // llvm.mips.adds.s.b
+    1, // llvm.mips.adds.s.d
+    1, // llvm.mips.adds.s.h
+    1, // llvm.mips.adds.s.w
+    1, // llvm.mips.adds.u.b
+    1, // llvm.mips.adds.u.d
+    1, // llvm.mips.adds.u.h
+    1, // llvm.mips.adds.u.w
+    2, // llvm.mips.addsc
+    2, // llvm.mips.addu.ph
+    1, // llvm.mips.addu.qb
+    2, // llvm.mips.addu.s.ph
+    1, // llvm.mips.addu.s.qb
+    1, // llvm.mips.adduh.qb
+    1, // llvm.mips.adduh.r.qb
+    1, // llvm.mips.addv.b
+    1, // llvm.mips.addv.d
+    1, // llvm.mips.addv.h
+    1, // llvm.mips.addv.w
+    1, // llvm.mips.addvi.b
+    1, // llvm.mips.addvi.d
+    1, // llvm.mips.addvi.h
+    1, // llvm.mips.addvi.w
+    2, // llvm.mips.addwc
+    1, // llvm.mips.and.v
+    1, // llvm.mips.andi.b
+    1, // llvm.mips.append
+    1, // llvm.mips.asub.s.b
+    1, // llvm.mips.asub.s.d
+    1, // llvm.mips.asub.s.h
+    1, // llvm.mips.asub.s.w
+    1, // llvm.mips.asub.u.b
+    1, // llvm.mips.asub.u.d
+    1, // llvm.mips.asub.u.h
+    1, // llvm.mips.asub.u.w
+    1, // llvm.mips.ave.s.b
+    1, // llvm.mips.ave.s.d
+    1, // llvm.mips.ave.s.h
+    1, // llvm.mips.ave.s.w
+    1, // llvm.mips.ave.u.b
+    1, // llvm.mips.ave.u.d
+    1, // llvm.mips.ave.u.h
+    1, // llvm.mips.ave.u.w
+    1, // llvm.mips.aver.s.b
+    1, // llvm.mips.aver.s.d
+    1, // llvm.mips.aver.s.h
+    1, // llvm.mips.aver.s.w
+    1, // llvm.mips.aver.u.b
+    1, // llvm.mips.aver.u.d
+    1, // llvm.mips.aver.u.h
+    1, // llvm.mips.aver.u.w
+    1, // llvm.mips.balign
+    1, // llvm.mips.bclr.b
+    1, // llvm.mips.bclr.d
+    1, // llvm.mips.bclr.h
+    1, // llvm.mips.bclr.w
+    1, // llvm.mips.bclri.b
+    1, // llvm.mips.bclri.d
+    1, // llvm.mips.bclri.h
+    1, // llvm.mips.bclri.w
+    1, // llvm.mips.binsl.b
+    1, // llvm.mips.binsl.d
+    1, // llvm.mips.binsl.h
+    1, // llvm.mips.binsl.w
+    1, // llvm.mips.binsli.b
+    1, // llvm.mips.binsli.d
+    1, // llvm.mips.binsli.h
+    1, // llvm.mips.binsli.w
+    1, // llvm.mips.binsr.b
+    1, // llvm.mips.binsr.d
+    1, // llvm.mips.binsr.h
+    1, // llvm.mips.binsr.w
+    1, // llvm.mips.binsri.b
+    1, // llvm.mips.binsri.d
+    1, // llvm.mips.binsri.h
+    1, // llvm.mips.binsri.w
+    1, // llvm.mips.bitrev
+    1, // llvm.mips.bmnz.v
+    1, // llvm.mips.bmnzi.b
+    1, // llvm.mips.bmz.v
+    1, // llvm.mips.bmzi.b
+    1, // llvm.mips.bneg.b
+    1, // llvm.mips.bneg.d
+    1, // llvm.mips.bneg.h
+    1, // llvm.mips.bneg.w
+    1, // llvm.mips.bnegi.b
+    1, // llvm.mips.bnegi.d
+    1, // llvm.mips.bnegi.h
+    1, // llvm.mips.bnegi.w
+    1, // llvm.mips.bnz.b
+    1, // llvm.mips.bnz.d
+    1, // llvm.mips.bnz.h
+    1, // llvm.mips.bnz.v
+    1, // llvm.mips.bnz.w
+    3, // llvm.mips.bposge32
+    1, // llvm.mips.bsel.v
+    1, // llvm.mips.bseli.b
+    1, // llvm.mips.bset.b
+    1, // llvm.mips.bset.d
+    1, // llvm.mips.bset.h
+    1, // llvm.mips.bset.w
+    1, // llvm.mips.bseti.b
+    1, // llvm.mips.bseti.d
+    1, // llvm.mips.bseti.h
+    1, // llvm.mips.bseti.w
+    1, // llvm.mips.bz.b
+    1, // llvm.mips.bz.d
+    1, // llvm.mips.bz.h
+    1, // llvm.mips.bz.v
+    1, // llvm.mips.bz.w
+    1, // llvm.mips.ceq.b
+    1, // llvm.mips.ceq.d
+    1, // llvm.mips.ceq.h
+    1, // llvm.mips.ceq.w
+    1, // llvm.mips.ceqi.b
+    1, // llvm.mips.ceqi.d
+    1, // llvm.mips.ceqi.h
+    1, // llvm.mips.ceqi.w
+    2, // llvm.mips.cfcmsa
+    1, // llvm.mips.cle.s.b
+    1, // llvm.mips.cle.s.d
+    1, // llvm.mips.cle.s.h
+    1, // llvm.mips.cle.s.w
+    1, // llvm.mips.cle.u.b
+    1, // llvm.mips.cle.u.d
+    1, // llvm.mips.cle.u.h
+    1, // llvm.mips.cle.u.w
+    1, // llvm.mips.clei.s.b
+    1, // llvm.mips.clei.s.d
+    1, // llvm.mips.clei.s.h
+    1, // llvm.mips.clei.s.w
+    1, // llvm.mips.clei.u.b
+    1, // llvm.mips.clei.u.d
+    1, // llvm.mips.clei.u.h
+    1, // llvm.mips.clei.u.w
+    1, // llvm.mips.clt.s.b
+    1, // llvm.mips.clt.s.d
+    1, // llvm.mips.clt.s.h
+    1, // llvm.mips.clt.s.w
+    1, // llvm.mips.clt.u.b
+    1, // llvm.mips.clt.u.d
+    1, // llvm.mips.clt.u.h
+    1, // llvm.mips.clt.u.w
+    1, // llvm.mips.clti.s.b
+    1, // llvm.mips.clti.s.d
+    1, // llvm.mips.clti.s.h
+    1, // llvm.mips.clti.s.w
+    1, // llvm.mips.clti.u.b
+    1, // llvm.mips.clti.u.d
+    1, // llvm.mips.clti.u.h
+    1, // llvm.mips.clti.u.w
+    2, // llvm.mips.cmp.eq.ph
+    2, // llvm.mips.cmp.le.ph
+    2, // llvm.mips.cmp.lt.ph
+    2, // llvm.mips.cmpgdu.eq.qb
+    2, // llvm.mips.cmpgdu.le.qb
+    2, // llvm.mips.cmpgdu.lt.qb
+    2, // llvm.mips.cmpgu.eq.qb
+    2, // llvm.mips.cmpgu.le.qb
+    2, // llvm.mips.cmpgu.lt.qb
+    2, // llvm.mips.cmpu.eq.qb
+    2, // llvm.mips.cmpu.le.qb
+    2, // llvm.mips.cmpu.lt.qb
+    1, // llvm.mips.copy.s.b
+    1, // llvm.mips.copy.s.d
+    1, // llvm.mips.copy.s.h
+    1, // llvm.mips.copy.s.w
+    1, // llvm.mips.copy.u.b
+    1, // llvm.mips.copy.u.d
+    1, // llvm.mips.copy.u.h
+    1, // llvm.mips.copy.u.w
+    2, // llvm.mips.ctcmsa
+    1, // llvm.mips.div.s.b
+    1, // llvm.mips.div.s.d
+    1, // llvm.mips.div.s.h
+    1, // llvm.mips.div.s.w
+    1, // llvm.mips.div.u.b
+    1, // llvm.mips.div.u.d
+    1, // llvm.mips.div.u.h
+    1, // llvm.mips.div.u.w
+    1, // llvm.mips.dlsa
+    1, // llvm.mips.dotp.s.d
+    1, // llvm.mips.dotp.s.h
+    1, // llvm.mips.dotp.s.w
+    1, // llvm.mips.dotp.u.d
+    1, // llvm.mips.dotp.u.h
+    1, // llvm.mips.dotp.u.w
+    1, // llvm.mips.dpa.w.ph
+    1, // llvm.mips.dpadd.s.d
+    1, // llvm.mips.dpadd.s.h
+    1, // llvm.mips.dpadd.s.w
+    1, // llvm.mips.dpadd.u.d
+    1, // llvm.mips.dpadd.u.h
+    1, // llvm.mips.dpadd.u.w
+    2, // llvm.mips.dpaq.s.w.ph
+    2, // llvm.mips.dpaq.sa.l.w
+    2, // llvm.mips.dpaqx.s.w.ph
+    2, // llvm.mips.dpaqx.sa.w.ph
+    1, // llvm.mips.dpau.h.qbl
+    1, // llvm.mips.dpau.h.qbr
+    1, // llvm.mips.dpax.w.ph
+    1, // llvm.mips.dps.w.ph
+    2, // llvm.mips.dpsq.s.w.ph
+    2, // llvm.mips.dpsq.sa.l.w
+    2, // llvm.mips.dpsqx.s.w.ph
+    2, // llvm.mips.dpsqx.sa.w.ph
+    1, // llvm.mips.dpsu.h.qbl
+    1, // llvm.mips.dpsu.h.qbr
+    1, // llvm.mips.dpsub.s.d
+    1, // llvm.mips.dpsub.s.h
+    1, // llvm.mips.dpsub.s.w
+    1, // llvm.mips.dpsub.u.d
+    1, // llvm.mips.dpsub.u.h
+    1, // llvm.mips.dpsub.u.w
+    1, // llvm.mips.dpsx.w.ph
+    2, // llvm.mips.extp
+    2, // llvm.mips.extpdp
+    2, // llvm.mips.extr.r.w
+    2, // llvm.mips.extr.rs.w
+    2, // llvm.mips.extr.s.h
+    2, // llvm.mips.extr.w
+    1, // llvm.mips.fadd.d
+    1, // llvm.mips.fadd.w
+    1, // llvm.mips.fcaf.d
+    1, // llvm.mips.fcaf.w
+    1, // llvm.mips.fceq.d
+    1, // llvm.mips.fceq.w
+    1, // llvm.mips.fclass.d
+    1, // llvm.mips.fclass.w
+    1, // llvm.mips.fcle.d
+    1, // llvm.mips.fcle.w
+    1, // llvm.mips.fclt.d
+    1, // llvm.mips.fclt.w
+    1, // llvm.mips.fcne.d
+    1, // llvm.mips.fcne.w
+    1, // llvm.mips.fcor.d
+    1, // llvm.mips.fcor.w
+    1, // llvm.mips.fcueq.d
+    1, // llvm.mips.fcueq.w
+    1, // llvm.mips.fcule.d
+    1, // llvm.mips.fcule.w
+    1, // llvm.mips.fcult.d
+    1, // llvm.mips.fcult.w
+    1, // llvm.mips.fcun.d
+    1, // llvm.mips.fcun.w
+    1, // llvm.mips.fcune.d
+    1, // llvm.mips.fcune.w
+    1, // llvm.mips.fdiv.d
+    1, // llvm.mips.fdiv.w
+    1, // llvm.mips.fexdo.h
+    1, // llvm.mips.fexdo.w
+    1, // llvm.mips.fexp2.d
+    1, // llvm.mips.fexp2.w
+    1, // llvm.mips.fexupl.d
+    1, // llvm.mips.fexupl.w
+    1, // llvm.mips.fexupr.d
+    1, // llvm.mips.fexupr.w
+    1, // llvm.mips.ffint.s.d
+    1, // llvm.mips.ffint.s.w
+    1, // llvm.mips.ffint.u.d
+    1, // llvm.mips.ffint.u.w
+    1, // llvm.mips.ffql.d
+    1, // llvm.mips.ffql.w
+    1, // llvm.mips.ffqr.d
+    1, // llvm.mips.ffqr.w
+    1, // llvm.mips.fill.b
+    1, // llvm.mips.fill.d
+    1, // llvm.mips.fill.h
+    1, // llvm.mips.fill.w
+    1, // llvm.mips.flog2.d
+    1, // llvm.mips.flog2.w
+    1, // llvm.mips.fmadd.d
+    1, // llvm.mips.fmadd.w
+    1, // llvm.mips.fmax.a.d
+    1, // llvm.mips.fmax.a.w
+    1, // llvm.mips.fmax.d
+    1, // llvm.mips.fmax.w
+    1, // llvm.mips.fmin.a.d
+    1, // llvm.mips.fmin.a.w
+    1, // llvm.mips.fmin.d
+    1, // llvm.mips.fmin.w
+    1, // llvm.mips.fmsub.d
+    1, // llvm.mips.fmsub.w
+    1, // llvm.mips.fmul.d
+    1, // llvm.mips.fmul.w
+    1, // llvm.mips.frcp.d
+    1, // llvm.mips.frcp.w
+    1, // llvm.mips.frint.d
+    1, // llvm.mips.frint.w
+    1, // llvm.mips.frsqrt.d
+    1, // llvm.mips.frsqrt.w
+    1, // llvm.mips.fsaf.d
+    1, // llvm.mips.fsaf.w
+    1, // llvm.mips.fseq.d
+    1, // llvm.mips.fseq.w
+    1, // llvm.mips.fsle.d
+    1, // llvm.mips.fsle.w
+    1, // llvm.mips.fslt.d
+    1, // llvm.mips.fslt.w
+    1, // llvm.mips.fsne.d
+    1, // llvm.mips.fsne.w
+    1, // llvm.mips.fsor.d
+    1, // llvm.mips.fsor.w
+    1, // llvm.mips.fsqrt.d
+    1, // llvm.mips.fsqrt.w
+    1, // llvm.mips.fsub.d
+    1, // llvm.mips.fsub.w
+    1, // llvm.mips.fsueq.d
+    1, // llvm.mips.fsueq.w
+    1, // llvm.mips.fsule.d
+    1, // llvm.mips.fsule.w
+    1, // llvm.mips.fsult.d
+    1, // llvm.mips.fsult.w
+    1, // llvm.mips.fsun.d
+    1, // llvm.mips.fsun.w
+    1, // llvm.mips.fsune.d
+    1, // llvm.mips.fsune.w
+    1, // llvm.mips.ftint.s.d
+    1, // llvm.mips.ftint.s.w
+    1, // llvm.mips.ftint.u.d
+    1, // llvm.mips.ftint.u.w
+    1, // llvm.mips.ftq.h
+    1, // llvm.mips.ftq.w
+    1, // llvm.mips.ftrunc.s.d
+    1, // llvm.mips.ftrunc.s.w
+    1, // llvm.mips.ftrunc.u.d
+    1, // llvm.mips.ftrunc.u.w
+    1, // llvm.mips.hadd.s.d
+    1, // llvm.mips.hadd.s.h
+    1, // llvm.mips.hadd.s.w
+    1, // llvm.mips.hadd.u.d
+    1, // llvm.mips.hadd.u.h
+    1, // llvm.mips.hadd.u.w
+    1, // llvm.mips.hsub.s.d
+    1, // llvm.mips.hsub.s.h
+    1, // llvm.mips.hsub.s.w
+    1, // llvm.mips.hsub.u.d
+    1, // llvm.mips.hsub.u.h
+    1, // llvm.mips.hsub.u.w
+    1, // llvm.mips.ilvev.b
+    1, // llvm.mips.ilvev.d
+    1, // llvm.mips.ilvev.h
+    1, // llvm.mips.ilvev.w
+    1, // llvm.mips.ilvl.b
+    1, // llvm.mips.ilvl.d
+    1, // llvm.mips.ilvl.h
+    1, // llvm.mips.ilvl.w
+    1, // llvm.mips.ilvod.b
+    1, // llvm.mips.ilvod.d
+    1, // llvm.mips.ilvod.h
+    1, // llvm.mips.ilvod.w
+    1, // llvm.mips.ilvr.b
+    1, // llvm.mips.ilvr.d
+    1, // llvm.mips.ilvr.h
+    1, // llvm.mips.ilvr.w
+    1, // llvm.mips.insert.b
+    1, // llvm.mips.insert.d
+    1, // llvm.mips.insert.h
+    1, // llvm.mips.insert.w
+    3, // llvm.mips.insv
+    1, // llvm.mips.insve.b
+    1, // llvm.mips.insve.d
+    1, // llvm.mips.insve.h
+    1, // llvm.mips.insve.w
+    3, // llvm.mips.lbux
+    3, // llvm.mips.ld.b
+    3, // llvm.mips.ld.d
+    3, // llvm.mips.ld.h
+    3, // llvm.mips.ld.w
+    1, // llvm.mips.ldi.b
+    1, // llvm.mips.ldi.d
+    1, // llvm.mips.ldi.h
+    1, // llvm.mips.ldi.w
+    3, // llvm.mips.lhx
+    1, // llvm.mips.lsa
+    3, // llvm.mips.lwx
+    1, // llvm.mips.madd
+    1, // llvm.mips.madd.q.h
+    1, // llvm.mips.madd.q.w
+    1, // llvm.mips.maddr.q.h
+    1, // llvm.mips.maddr.q.w
+    1, // llvm.mips.maddu
+    1, // llvm.mips.maddv.b
+    1, // llvm.mips.maddv.d
+    1, // llvm.mips.maddv.h
+    1, // llvm.mips.maddv.w
+    2, // llvm.mips.maq.s.w.phl
+    2, // llvm.mips.maq.s.w.phr
+    2, // llvm.mips.maq.sa.w.phl
+    2, // llvm.mips.maq.sa.w.phr
+    1, // llvm.mips.max.a.b
+    1, // llvm.mips.max.a.d
+    1, // llvm.mips.max.a.h
+    1, // llvm.mips.max.a.w
+    1, // llvm.mips.max.s.b
+    1, // llvm.mips.max.s.d
+    1, // llvm.mips.max.s.h
+    1, // llvm.mips.max.s.w
+    1, // llvm.mips.max.u.b
+    1, // llvm.mips.max.u.d
+    1, // llvm.mips.max.u.h
+    1, // llvm.mips.max.u.w
+    1, // llvm.mips.maxi.s.b
+    1, // llvm.mips.maxi.s.d
+    1, // llvm.mips.maxi.s.h
+    1, // llvm.mips.maxi.s.w
+    1, // llvm.mips.maxi.u.b
+    1, // llvm.mips.maxi.u.d
+    1, // llvm.mips.maxi.u.h
+    1, // llvm.mips.maxi.u.w
+    1, // llvm.mips.min.a.b
+    1, // llvm.mips.min.a.d
+    1, // llvm.mips.min.a.h
+    1, // llvm.mips.min.a.w
+    1, // llvm.mips.min.s.b
+    1, // llvm.mips.min.s.d
+    1, // llvm.mips.min.s.h
+    1, // llvm.mips.min.s.w
+    1, // llvm.mips.min.u.b
+    1, // llvm.mips.min.u.d
+    1, // llvm.mips.min.u.h
+    1, // llvm.mips.min.u.w
+    1, // llvm.mips.mini.s.b
+    1, // llvm.mips.mini.s.d
+    1, // llvm.mips.mini.s.h
+    1, // llvm.mips.mini.s.w
+    1, // llvm.mips.mini.u.b
+    1, // llvm.mips.mini.u.d
+    1, // llvm.mips.mini.u.h
+    1, // llvm.mips.mini.u.w
+    1, // llvm.mips.mod.s.b
+    1, // llvm.mips.mod.s.d
+    1, // llvm.mips.mod.s.h
+    1, // llvm.mips.mod.s.w
+    1, // llvm.mips.mod.u.b
+    1, // llvm.mips.mod.u.d
+    1, // llvm.mips.mod.u.h
+    1, // llvm.mips.mod.u.w
+    1, // llvm.mips.modsub
+    1, // llvm.mips.move.v
+    1, // llvm.mips.msub
+    1, // llvm.mips.msub.q.h
+    1, // llvm.mips.msub.q.w
+    1, // llvm.mips.msubr.q.h
+    1, // llvm.mips.msubr.q.w
+    1, // llvm.mips.msubu
+    1, // llvm.mips.msubv.b
+    1, // llvm.mips.msubv.d
+    1, // llvm.mips.msubv.h
+    1, // llvm.mips.msubv.w
+    2, // llvm.mips.mthlip
+    2, // llvm.mips.mul.ph
+    1, // llvm.mips.mul.q.h
+    1, // llvm.mips.mul.q.w
+    2, // llvm.mips.mul.s.ph
+    2, // llvm.mips.muleq.s.w.phl
+    2, // llvm.mips.muleq.s.w.phr
+    2, // llvm.mips.muleu.s.ph.qbl
+    2, // llvm.mips.muleu.s.ph.qbr
+    2, // llvm.mips.mulq.rs.ph
+    2, // llvm.mips.mulq.rs.w
+    2, // llvm.mips.mulq.s.ph
+    2, // llvm.mips.mulq.s.w
+    1, // llvm.mips.mulr.q.h
+    1, // llvm.mips.mulr.q.w
+    1, // llvm.mips.mulsa.w.ph
+    2, // llvm.mips.mulsaq.s.w.ph
+    1, // llvm.mips.mult
+    1, // llvm.mips.multu
+    1, // llvm.mips.mulv.b
+    1, // llvm.mips.mulv.d
+    1, // llvm.mips.mulv.h
+    1, // llvm.mips.mulv.w
+    1, // llvm.mips.nloc.b
+    1, // llvm.mips.nloc.d
+    1, // llvm.mips.nloc.h
+    1, // llvm.mips.nloc.w
+    1, // llvm.mips.nlzc.b
+    1, // llvm.mips.nlzc.d
+    1, // llvm.mips.nlzc.h
+    1, // llvm.mips.nlzc.w
+    1, // llvm.mips.nor.v
+    1, // llvm.mips.nori.b
+    1, // llvm.mips.or.v
+    1, // llvm.mips.ori.b
+    1, // llvm.mips.packrl.ph
+    1, // llvm.mips.pckev.b
+    1, // llvm.mips.pckev.d
+    1, // llvm.mips.pckev.h
+    1, // llvm.mips.pckev.w
+    1, // llvm.mips.pckod.b
+    1, // llvm.mips.pckod.d
+    1, // llvm.mips.pckod.h
+    1, // llvm.mips.pckod.w
+    1, // llvm.mips.pcnt.b
+    1, // llvm.mips.pcnt.d
+    1, // llvm.mips.pcnt.h
+    1, // llvm.mips.pcnt.w
+    3, // llvm.mips.pick.ph
+    3, // llvm.mips.pick.qb
+    1, // llvm.mips.preceq.w.phl
+    1, // llvm.mips.preceq.w.phr
+    1, // llvm.mips.precequ.ph.qbl
+    1, // llvm.mips.precequ.ph.qbla
+    1, // llvm.mips.precequ.ph.qbr
+    1, // llvm.mips.precequ.ph.qbra
+    1, // llvm.mips.preceu.ph.qbl
+    1, // llvm.mips.preceu.ph.qbla
+    1, // llvm.mips.preceu.ph.qbr
+    1, // llvm.mips.preceu.ph.qbra
+    2, // llvm.mips.precr.qb.ph
+    1, // llvm.mips.precr.sra.ph.w
+    1, // llvm.mips.precr.sra.r.ph.w
+    1, // llvm.mips.precrq.ph.w
+    1, // llvm.mips.precrq.qb.ph
+    2, // llvm.mips.precrq.rs.ph.w
+    2, // llvm.mips.precrqu.s.qb.ph
+    1, // llvm.mips.prepend
+    1, // llvm.mips.raddu.w.qb
+    3, // llvm.mips.rddsp
+    1, // llvm.mips.repl.ph
+    1, // llvm.mips.repl.qb
+    1, // llvm.mips.sat.s.b
+    1, // llvm.mips.sat.s.d
+    1, // llvm.mips.sat.s.h
+    1, // llvm.mips.sat.s.w
+    1, // llvm.mips.sat.u.b
+    1, // llvm.mips.sat.u.d
+    1, // llvm.mips.sat.u.h
+    1, // llvm.mips.sat.u.w
+    1, // llvm.mips.shf.b
+    1, // llvm.mips.shf.h
+    1, // llvm.mips.shf.w
+    1, // llvm.mips.shilo
+    2, // llvm.mips.shll.ph
+    2, // llvm.mips.shll.qb
+    2, // llvm.mips.shll.s.ph
+    2, // llvm.mips.shll.s.w
+    1, // llvm.mips.shra.ph
+    1, // llvm.mips.shra.qb
+    1, // llvm.mips.shra.r.ph
+    1, // llvm.mips.shra.r.qb
+    1, // llvm.mips.shra.r.w
+    1, // llvm.mips.shrl.ph
+    1, // llvm.mips.shrl.qb
+    1, // llvm.mips.sld.b
+    1, // llvm.mips.sld.d
+    1, // llvm.mips.sld.h
+    1, // llvm.mips.sld.w
+    1, // llvm.mips.sldi.b
+    1, // llvm.mips.sldi.d
+    1, // llvm.mips.sldi.h
+    1, // llvm.mips.sldi.w
+    1, // llvm.mips.sll.b
+    1, // llvm.mips.sll.d
+    1, // llvm.mips.sll.h
+    1, // llvm.mips.sll.w
+    1, // llvm.mips.slli.b
+    1, // llvm.mips.slli.d
+    1, // llvm.mips.slli.h
+    1, // llvm.mips.slli.w
+    1, // llvm.mips.splat.b
+    1, // llvm.mips.splat.d
+    1, // llvm.mips.splat.h
+    1, // llvm.mips.splat.w
+    1, // llvm.mips.splati.b
+    1, // llvm.mips.splati.d
+    1, // llvm.mips.splati.h
+    1, // llvm.mips.splati.w
+    1, // llvm.mips.sra.b
+    1, // llvm.mips.sra.d
+    1, // llvm.mips.sra.h
+    1, // llvm.mips.sra.w
+    1, // llvm.mips.srai.b
+    1, // llvm.mips.srai.d
+    1, // llvm.mips.srai.h
+    1, // llvm.mips.srai.w
+    1, // llvm.mips.srar.b
+    1, // llvm.mips.srar.d
+    1, // llvm.mips.srar.h
+    1, // llvm.mips.srar.w
+    1, // llvm.mips.srari.b
+    1, // llvm.mips.srari.d
+    1, // llvm.mips.srari.h
+    1, // llvm.mips.srari.w
+    1, // llvm.mips.srl.b
+    1, // llvm.mips.srl.d
+    1, // llvm.mips.srl.h
+    1, // llvm.mips.srl.w
+    1, // llvm.mips.srli.b
+    1, // llvm.mips.srli.d
+    1, // llvm.mips.srli.h
+    1, // llvm.mips.srli.w
+    1, // llvm.mips.srlr.b
+    1, // llvm.mips.srlr.d
+    1, // llvm.mips.srlr.h
+    1, // llvm.mips.srlr.w
+    1, // llvm.mips.srlri.b
+    1, // llvm.mips.srlri.d
+    1, // llvm.mips.srlri.h
+    1, // llvm.mips.srlri.w
+    2, // llvm.mips.st.b
+    2, // llvm.mips.st.d
+    2, // llvm.mips.st.h
+    2, // llvm.mips.st.w
+    1, // llvm.mips.subq.ph
+    1, // llvm.mips.subq.s.ph
+    2, // llvm.mips.subq.s.w
+    1, // llvm.mips.subqh.ph
+    1, // llvm.mips.subqh.r.ph
+    1, // llvm.mips.subqh.r.w
+    1, // llvm.mips.subqh.w
+    1, // llvm.mips.subs.s.b
+    1, // llvm.mips.subs.s.d
+    1, // llvm.mips.subs.s.h
+    1, // llvm.mips.subs.s.w
+    1, // llvm.mips.subs.u.b
+    1, // llvm.mips.subs.u.d
+    1, // llvm.mips.subs.u.h
+    1, // llvm.mips.subs.u.w
+    1, // llvm.mips.subsus.u.b
+    1, // llvm.mips.subsus.u.d
+    1, // llvm.mips.subsus.u.h
+    1, // llvm.mips.subsus.u.w
+    1, // llvm.mips.subsuu.s.b
+    1, // llvm.mips.subsuu.s.d
+    1, // llvm.mips.subsuu.s.h
+    1, // llvm.mips.subsuu.s.w
+    2, // llvm.mips.subu.ph
+    1, // llvm.mips.subu.qb
+    2, // llvm.mips.subu.s.ph
+    1, // llvm.mips.subu.s.qb
+    1, // llvm.mips.subuh.qb
+    1, // llvm.mips.subuh.r.qb
+    1, // llvm.mips.subv.b
+    1, // llvm.mips.subv.d
+    1, // llvm.mips.subv.h
+    1, // llvm.mips.subv.w
+    1, // llvm.mips.subvi.b
+    1, // llvm.mips.subvi.d
+    1, // llvm.mips.subvi.h
+    1, // llvm.mips.subvi.w
+    1, // llvm.mips.vshf.b
+    1, // llvm.mips.vshf.d
+    1, // llvm.mips.vshf.h
+    1, // llvm.mips.vshf.w
+    2, // llvm.mips.wrdsp
+    1, // llvm.mips.xor.v
+    1, // llvm.mips.xori.b
+    1, // llvm.nearbyint
+    1, // llvm.nvvm.abs.i
+    1, // llvm.nvvm.abs.ll
+    1, // llvm.nvvm.add.rm.d
+    1, // llvm.nvvm.add.rm.f
+    1, // llvm.nvvm.add.rm.ftz.f
+    1, // llvm.nvvm.add.rn.d
+    1, // llvm.nvvm.add.rn.f
+    1, // llvm.nvvm.add.rn.ftz.f
+    1, // llvm.nvvm.add.rp.d
+    1, // llvm.nvvm.add.rp.f
+    1, // llvm.nvvm.add.rp.ftz.f
+    1, // llvm.nvvm.add.rz.d
+    1, // llvm.nvvm.add.rz.f
+    1, // llvm.nvvm.add.rz.ftz.f
+    12, // llvm.nvvm.atomic.load.add.f32
+    12, // llvm.nvvm.atomic.load.dec.32
+    12, // llvm.nvvm.atomic.load.inc.32
+    8, // llvm.nvvm.barrier0
+    8, // llvm.nvvm.barrier0.and
+    8, // llvm.nvvm.barrier0.or
+    8, // llvm.nvvm.barrier0.popc
+    1, // llvm.nvvm.bitcast.d2ll
+    1, // llvm.nvvm.bitcast.f2i
+    1, // llvm.nvvm.bitcast.i2f
+    1, // llvm.nvvm.bitcast.ll2d
+    1, // llvm.nvvm.brev32
+    1, // llvm.nvvm.brev64
+    1, // llvm.nvvm.ceil.d
+    1, // llvm.nvvm.ceil.f
+    1, // llvm.nvvm.ceil.ftz.f
+    1, // llvm.nvvm.clz.i
+    1, // llvm.nvvm.clz.ll
+    2, // llvm.nvvm.compiler.error
+    2, // llvm.nvvm.compiler.warn
+    1, // llvm.nvvm.cos.approx.f
+    1, // llvm.nvvm.cos.approx.ftz.f
+    1, // llvm.nvvm.d2f.rm
+    1, // llvm.nvvm.d2f.rm.ftz
+    1, // llvm.nvvm.d2f.rn
+    1, // llvm.nvvm.d2f.rn.ftz
+    1, // llvm.nvvm.d2f.rp
+    1, // llvm.nvvm.d2f.rp.ftz
+    1, // llvm.nvvm.d2f.rz
+    1, // llvm.nvvm.d2f.rz.ftz
+    1, // llvm.nvvm.d2i.hi
+    1, // llvm.nvvm.d2i.lo
+    1, // llvm.nvvm.d2i.rm
+    1, // llvm.nvvm.d2i.rn
+    1, // llvm.nvvm.d2i.rp
+    1, // llvm.nvvm.d2i.rz
+    1, // llvm.nvvm.d2ll.rm
+    1, // llvm.nvvm.d2ll.rn
+    1, // llvm.nvvm.d2ll.rp
+    1, // llvm.nvvm.d2ll.rz
+    1, // llvm.nvvm.d2ui.rm
+    1, // llvm.nvvm.d2ui.rn
+    1, // llvm.nvvm.d2ui.rp
+    1, // llvm.nvvm.d2ui.rz
+    1, // llvm.nvvm.d2ull.rm
+    1, // llvm.nvvm.d2ull.rn
+    1, // llvm.nvvm.d2ull.rp
+    1, // llvm.nvvm.d2ull.rz
+    1, // llvm.nvvm.div.approx.f
+    1, // llvm.nvvm.div.approx.ftz.f
+    1, // llvm.nvvm.div.rm.d
+    1, // llvm.nvvm.div.rm.f
+    1, // llvm.nvvm.div.rm.ftz.f
+    1, // llvm.nvvm.div.rn.d
+    1, // llvm.nvvm.div.rn.f
+    1, // llvm.nvvm.div.rn.ftz.f
+    1, // llvm.nvvm.div.rp.d
+    1, // llvm.nvvm.div.rp.f
+    1, // llvm.nvvm.div.rp.ftz.f
+    1, // llvm.nvvm.div.rz.d
+    1, // llvm.nvvm.div.rz.f
+    1, // llvm.nvvm.div.rz.ftz.f
+    1, // llvm.nvvm.ex2.approx.d
+    1, // llvm.nvvm.ex2.approx.f
+    1, // llvm.nvvm.ex2.approx.ftz.f
+    1, // llvm.nvvm.f2h.rn
+    1, // llvm.nvvm.f2h.rn.ftz
+    1, // llvm.nvvm.f2i.rm
+    1, // llvm.nvvm.f2i.rm.ftz
+    1, // llvm.nvvm.f2i.rn
+    1, // llvm.nvvm.f2i.rn.ftz
+    1, // llvm.nvvm.f2i.rp
+    1, // llvm.nvvm.f2i.rp.ftz
+    1, // llvm.nvvm.f2i.rz
+    1, // llvm.nvvm.f2i.rz.ftz
+    1, // llvm.nvvm.f2ll.rm
+    1, // llvm.nvvm.f2ll.rm.ftz
+    1, // llvm.nvvm.f2ll.rn
+    1, // llvm.nvvm.f2ll.rn.ftz
+    1, // llvm.nvvm.f2ll.rp
+    1, // llvm.nvvm.f2ll.rp.ftz
+    1, // llvm.nvvm.f2ll.rz
+    1, // llvm.nvvm.f2ll.rz.ftz
+    1, // llvm.nvvm.f2ui.rm
+    1, // llvm.nvvm.f2ui.rm.ftz
+    1, // llvm.nvvm.f2ui.rn
+    1, // llvm.nvvm.f2ui.rn.ftz
+    1, // llvm.nvvm.f2ui.rp
+    1, // llvm.nvvm.f2ui.rp.ftz
+    1, // llvm.nvvm.f2ui.rz
+    1, // llvm.nvvm.f2ui.rz.ftz
+    1, // llvm.nvvm.f2ull.rm
+    1, // llvm.nvvm.f2ull.rm.ftz
+    1, // llvm.nvvm.f2ull.rn
+    1, // llvm.nvvm.f2ull.rn.ftz
+    1, // llvm.nvvm.f2ull.rp
+    1, // llvm.nvvm.f2ull.rp.ftz
+    1, // llvm.nvvm.f2ull.rz
+    1, // llvm.nvvm.f2ull.rz.ftz
+    1, // llvm.nvvm.fabs.d
+    1, // llvm.nvvm.fabs.f
+    1, // llvm.nvvm.fabs.ftz.f
+    1, // llvm.nvvm.floor.d
+    1, // llvm.nvvm.floor.f
+    1, // llvm.nvvm.floor.ftz.f
+    1, // llvm.nvvm.fma.rm.d
+    1, // llvm.nvvm.fma.rm.f
+    1, // llvm.nvvm.fma.rm.ftz.f
+    1, // llvm.nvvm.fma.rn.d
+    1, // llvm.nvvm.fma.rn.f
+    1, // llvm.nvvm.fma.rn.ftz.f
+    1, // llvm.nvvm.fma.rp.d
+    1, // llvm.nvvm.fma.rp.f
+    1, // llvm.nvvm.fma.rp.ftz.f
+    1, // llvm.nvvm.fma.rz.d
+    1, // llvm.nvvm.fma.rz.f
+    1, // llvm.nvvm.fma.rz.ftz.f
+    1, // llvm.nvvm.fmax.d
+    1, // llvm.nvvm.fmax.f
+    1, // llvm.nvvm.fmax.ftz.f
+    1, // llvm.nvvm.fmin.d
+    1, // llvm.nvvm.fmin.f
+    1, // llvm.nvvm.fmin.ftz.f
+    1, // llvm.nvvm.h2f
+    1, // llvm.nvvm.i2d.rm
+    1, // llvm.nvvm.i2d.rn
+    1, // llvm.nvvm.i2d.rp
+    1, // llvm.nvvm.i2d.rz
+    1, // llvm.nvvm.i2f.rm
+    1, // llvm.nvvm.i2f.rn
+    1, // llvm.nvvm.i2f.rp
+    1, // llvm.nvvm.i2f.rz
+    1, // llvm.nvvm.isspacep.const
+    1, // llvm.nvvm.isspacep.global
+    1, // llvm.nvvm.isspacep.local
+    1, // llvm.nvvm.isspacep.shared
+    1, // llvm.nvvm.istypep.sampler
+    1, // llvm.nvvm.istypep.surface
+    1, // llvm.nvvm.istypep.texture
+    15, // llvm.nvvm.ldg.global.f
+    15, // llvm.nvvm.ldg.global.i
+    15, // llvm.nvvm.ldg.global.p
+    15, // llvm.nvvm.ldu.global.f
+    15, // llvm.nvvm.ldu.global.i
+    15, // llvm.nvvm.ldu.global.p
+    1, // llvm.nvvm.lg2.approx.d
+    1, // llvm.nvvm.lg2.approx.f
+    1, // llvm.nvvm.lg2.approx.ftz.f
+    1, // llvm.nvvm.ll2d.rm
+    1, // llvm.nvvm.ll2d.rn
+    1, // llvm.nvvm.ll2d.rp
+    1, // llvm.nvvm.ll2d.rz
+    1, // llvm.nvvm.ll2f.rm
+    1, // llvm.nvvm.ll2f.rn
+    1, // llvm.nvvm.ll2f.rp
+    1, // llvm.nvvm.ll2f.rz
+    1, // llvm.nvvm.lohi.i2d
+    1, // llvm.nvvm.max.i
+    1, // llvm.nvvm.max.ll
+    1, // llvm.nvvm.max.ui
+    1, // llvm.nvvm.max.ull
+    2, // llvm.nvvm.membar.cta
+    2, // llvm.nvvm.membar.gl
+    2, // llvm.nvvm.membar.sys
+    1, // llvm.nvvm.min.i
+    1, // llvm.nvvm.min.ll
+    1, // llvm.nvvm.min.ui
+    1, // llvm.nvvm.min.ull
+    1, // llvm.nvvm.move.double
+    1, // llvm.nvvm.move.float
+    1, // llvm.nvvm.move.i16
+    1, // llvm.nvvm.move.i32
+    1, // llvm.nvvm.move.i64
+    16, // llvm.nvvm.move.ptr
+    1, // llvm.nvvm.mul24.i
+    1, // llvm.nvvm.mul24.ui
+    1, // llvm.nvvm.mul.rm.d
+    1, // llvm.nvvm.mul.rm.f
+    1, // llvm.nvvm.mul.rm.ftz.f
+    1, // llvm.nvvm.mul.rn.d
+    1, // llvm.nvvm.mul.rn.f
+    1, // llvm.nvvm.mul.rn.ftz.f
+    1, // llvm.nvvm.mul.rp.d
+    1, // llvm.nvvm.mul.rp.f
+    1, // llvm.nvvm.mul.rp.ftz.f
+    1, // llvm.nvvm.mul.rz.d
+    1, // llvm.nvvm.mul.rz.f
+    1, // llvm.nvvm.mul.rz.ftz.f
+    1, // llvm.nvvm.mulhi.i
+    1, // llvm.nvvm.mulhi.ll
+    1, // llvm.nvvm.mulhi.ui
+    1, // llvm.nvvm.mulhi.ull
+    1, // llvm.nvvm.popc.i
+    1, // llvm.nvvm.popc.ll
+    1, // llvm.nvvm.prmt
+    1, // llvm.nvvm.ptr.constant.to.gen
+    1, // llvm.nvvm.ptr.gen.to.constant
+    1, // llvm.nvvm.ptr.gen.to.global
+    1, // llvm.nvvm.ptr.gen.to.local
+    1, // llvm.nvvm.ptr.gen.to.param
+    1, // llvm.nvvm.ptr.gen.to.shared
+    1, // llvm.nvvm.ptr.global.to.gen
+    1, // llvm.nvvm.ptr.local.to.gen
+    1, // llvm.nvvm.ptr.shared.to.gen
+    1, // llvm.nvvm.rcp.approx.ftz.d
+    1, // llvm.nvvm.rcp.rm.d
+    1, // llvm.nvvm.rcp.rm.f
+    1, // llvm.nvvm.rcp.rm.ftz.f
+    1, // llvm.nvvm.rcp.rn.d
+    1, // llvm.nvvm.rcp.rn.f
+    1, // llvm.nvvm.rcp.rn.ftz.f
+    1, // llvm.nvvm.rcp.rp.d
+    1, // llvm.nvvm.rcp.rp.f
+    1, // llvm.nvvm.rcp.rp.ftz.f
+    1, // llvm.nvvm.rcp.rz.d
+    1, // llvm.nvvm.rcp.rz.f
+    1, // llvm.nvvm.rcp.rz.ftz.f
+    1, // llvm.nvvm.read.ptx.sreg.ctaid.x
+    1, // llvm.nvvm.read.ptx.sreg.ctaid.y
+    1, // llvm.nvvm.read.ptx.sreg.ctaid.z
+    1, // llvm.nvvm.read.ptx.sreg.envreg0
+    1, // llvm.nvvm.read.ptx.sreg.envreg1
+    1, // llvm.nvvm.read.ptx.sreg.envreg10
+    1, // llvm.nvvm.read.ptx.sreg.envreg11
+    1, // llvm.nvvm.read.ptx.sreg.envreg12
+    1, // llvm.nvvm.read.ptx.sreg.envreg13
+    1, // llvm.nvvm.read.ptx.sreg.envreg14
+    1, // llvm.nvvm.read.ptx.sreg.envreg15
+    1, // llvm.nvvm.read.ptx.sreg.envreg16
+    1, // llvm.nvvm.read.ptx.sreg.envreg17
+    1, // llvm.nvvm.read.ptx.sreg.envreg18
+    1, // llvm.nvvm.read.ptx.sreg.envreg19
+    1, // llvm.nvvm.read.ptx.sreg.envreg2
+    1, // llvm.nvvm.read.ptx.sreg.envreg20
+    1, // llvm.nvvm.read.ptx.sreg.envreg21
+    1, // llvm.nvvm.read.ptx.sreg.envreg22
+    1, // llvm.nvvm.read.ptx.sreg.envreg23
+    1, // llvm.nvvm.read.ptx.sreg.envreg24
+    1, // llvm.nvvm.read.ptx.sreg.envreg25
+    1, // llvm.nvvm.read.ptx.sreg.envreg26
+    1, // llvm.nvvm.read.ptx.sreg.envreg27
+    1, // llvm.nvvm.read.ptx.sreg.envreg28
+    1, // llvm.nvvm.read.ptx.sreg.envreg29
+    1, // llvm.nvvm.read.ptx.sreg.envreg3
+    1, // llvm.nvvm.read.ptx.sreg.envreg30
+    1, // llvm.nvvm.read.ptx.sreg.envreg31
+    1, // llvm.nvvm.read.ptx.sreg.envreg4
+    1, // llvm.nvvm.read.ptx.sreg.envreg5
+    1, // llvm.nvvm.read.ptx.sreg.envreg6
+    1, // llvm.nvvm.read.ptx.sreg.envreg7
+    1, // llvm.nvvm.read.ptx.sreg.envreg8
+    1, // llvm.nvvm.read.ptx.sreg.envreg9
+    1, // llvm.nvvm.read.ptx.sreg.nctaid.x
+    1, // llvm.nvvm.read.ptx.sreg.nctaid.y
+    1, // llvm.nvvm.read.ptx.sreg.nctaid.z
+    1, // llvm.nvvm.read.ptx.sreg.ntid.x
+    1, // llvm.nvvm.read.ptx.sreg.ntid.y
+    1, // llvm.nvvm.read.ptx.sreg.ntid.z
+    1, // llvm.nvvm.read.ptx.sreg.tid.x
+    1, // llvm.nvvm.read.ptx.sreg.tid.y
+    1, // llvm.nvvm.read.ptx.sreg.tid.z
+    1, // llvm.nvvm.read.ptx.sreg.warpsize
+    1, // llvm.nvvm.reflect
+    1, // llvm.nvvm.rotate.b32
+    1, // llvm.nvvm.rotate.b64
+    1, // llvm.nvvm.rotate.right.b64
+    1, // llvm.nvvm.round.d
+    1, // llvm.nvvm.round.f
+    1, // llvm.nvvm.round.ftz.f
+    1, // llvm.nvvm.rsqrt.approx.d
+    1, // llvm.nvvm.rsqrt.approx.f
+    1, // llvm.nvvm.rsqrt.approx.ftz.f
+    1, // llvm.nvvm.sad.i
+    1, // llvm.nvvm.sad.ui
+    1, // llvm.nvvm.saturate.d
+    1, // llvm.nvvm.saturate.f
+    1, // llvm.nvvm.saturate.ftz.f
+    1, // llvm.nvvm.sin.approx.f
+    1, // llvm.nvvm.sin.approx.ftz.f
+    1, // llvm.nvvm.sqrt.approx.f
+    1, // llvm.nvvm.sqrt.approx.ftz.f
+    1, // llvm.nvvm.sqrt.f
+    1, // llvm.nvvm.sqrt.rm.d
+    1, // llvm.nvvm.sqrt.rm.f
+    1, // llvm.nvvm.sqrt.rm.ftz.f
+    1, // llvm.nvvm.sqrt.rn.d
+    1, // llvm.nvvm.sqrt.rn.f
+    1, // llvm.nvvm.sqrt.rn.ftz.f
+    1, // llvm.nvvm.sqrt.rp.d
+    1, // llvm.nvvm.sqrt.rp.f
+    1, // llvm.nvvm.sqrt.rp.ftz.f
+    1, // llvm.nvvm.sqrt.rz.d
+    1, // llvm.nvvm.sqrt.rz.f
+    1, // llvm.nvvm.sqrt.rz.ftz.f
+    2, // llvm.nvvm.suld.1d.array.i16.clamp
+    2, // llvm.nvvm.suld.1d.array.i16.trap
+    2, // llvm.nvvm.suld.1d.array.i16.zero
+    2, // llvm.nvvm.suld.1d.array.i32.clamp
+    2, // llvm.nvvm.suld.1d.array.i32.trap
+    2, // llvm.nvvm.suld.1d.array.i32.zero
+    2, // llvm.nvvm.suld.1d.array.i64.clamp
+    2, // llvm.nvvm.suld.1d.array.i64.trap
+    2, // llvm.nvvm.suld.1d.array.i64.zero
+    2, // llvm.nvvm.suld.1d.array.i8.clamp
+    2, // llvm.nvvm.suld.1d.array.i8.trap
+    2, // llvm.nvvm.suld.1d.array.i8.zero
+    2, // llvm.nvvm.suld.1d.array.v2i16.clamp
+    2, // llvm.nvvm.suld.1d.array.v2i16.trap
+    2, // llvm.nvvm.suld.1d.array.v2i16.zero
+    2, // llvm.nvvm.suld.1d.array.v2i32.clamp
+    2, // llvm.nvvm.suld.1d.array.v2i32.trap
+    2, // llvm.nvvm.suld.1d.array.v2i32.zero
+    2, // llvm.nvvm.suld.1d.array.v2i64.clamp
+    2, // llvm.nvvm.suld.1d.array.v2i64.trap
+    2, // llvm.nvvm.suld.1d.array.v2i64.zero
+    2, // llvm.nvvm.suld.1d.array.v2i8.clamp
+    2, // llvm.nvvm.suld.1d.array.v2i8.trap
+    2, // llvm.nvvm.suld.1d.array.v2i8.zero
+    2, // llvm.nvvm.suld.1d.array.v4i16.clamp
+    2, // llvm.nvvm.suld.1d.array.v4i16.trap
+    2, // llvm.nvvm.suld.1d.array.v4i16.zero
+    2, // llvm.nvvm.suld.1d.array.v4i32.clamp
+    2, // llvm.nvvm.suld.1d.array.v4i32.trap
+    2, // llvm.nvvm.suld.1d.array.v4i32.zero
+    2, // llvm.nvvm.suld.1d.array.v4i8.clamp
+    2, // llvm.nvvm.suld.1d.array.v4i8.trap
+    2, // llvm.nvvm.suld.1d.array.v4i8.zero
+    2, // llvm.nvvm.suld.1d.i16.clamp
+    2, // llvm.nvvm.suld.1d.i16.trap
+    2, // llvm.nvvm.suld.1d.i16.zero
+    2, // llvm.nvvm.suld.1d.i32.clamp
+    2, // llvm.nvvm.suld.1d.i32.trap
+    2, // llvm.nvvm.suld.1d.i32.zero
+    2, // llvm.nvvm.suld.1d.i64.clamp
+    2, // llvm.nvvm.suld.1d.i64.trap
+    2, // llvm.nvvm.suld.1d.i64.zero
+    2, // llvm.nvvm.suld.1d.i8.clamp
+    2, // llvm.nvvm.suld.1d.i8.trap
+    2, // llvm.nvvm.suld.1d.i8.zero
+    2, // llvm.nvvm.suld.1d.v2i16.clamp
+    2, // llvm.nvvm.suld.1d.v2i16.trap
+    2, // llvm.nvvm.suld.1d.v2i16.zero
+    2, // llvm.nvvm.suld.1d.v2i32.clamp
+    2, // llvm.nvvm.suld.1d.v2i32.trap
+    2, // llvm.nvvm.suld.1d.v2i32.zero
+    2, // llvm.nvvm.suld.1d.v2i64.clamp
+    2, // llvm.nvvm.suld.1d.v2i64.trap
+    2, // llvm.nvvm.suld.1d.v2i64.zero
+    2, // llvm.nvvm.suld.1d.v2i8.clamp
+    2, // llvm.nvvm.suld.1d.v2i8.trap
+    2, // llvm.nvvm.suld.1d.v2i8.zero
+    2, // llvm.nvvm.suld.1d.v4i16.clamp
+    2, // llvm.nvvm.suld.1d.v4i16.trap
+    2, // llvm.nvvm.suld.1d.v4i16.zero
+    2, // llvm.nvvm.suld.1d.v4i32.clamp
+    2, // llvm.nvvm.suld.1d.v4i32.trap
+    2, // llvm.nvvm.suld.1d.v4i32.zero
+    2, // llvm.nvvm.suld.1d.v4i8.clamp
+    2, // llvm.nvvm.suld.1d.v4i8.trap
+    2, // llvm.nvvm.suld.1d.v4i8.zero
+    2, // llvm.nvvm.suld.2d.array.i16.clamp
+    2, // llvm.nvvm.suld.2d.array.i16.trap
+    2, // llvm.nvvm.suld.2d.array.i16.zero
+    2, // llvm.nvvm.suld.2d.array.i32.clamp
+    2, // llvm.nvvm.suld.2d.array.i32.trap
+    2, // llvm.nvvm.suld.2d.array.i32.zero
+    2, // llvm.nvvm.suld.2d.array.i64.clamp
+    2, // llvm.nvvm.suld.2d.array.i64.trap
+    2, // llvm.nvvm.suld.2d.array.i64.zero
+    2, // llvm.nvvm.suld.2d.array.i8.clamp
+    2, // llvm.nvvm.suld.2d.array.i8.trap
+    2, // llvm.nvvm.suld.2d.array.i8.zero
+    2, // llvm.nvvm.suld.2d.array.v2i16.clamp
+    2, // llvm.nvvm.suld.2d.array.v2i16.trap
+    2, // llvm.nvvm.suld.2d.array.v2i16.zero
+    2, // llvm.nvvm.suld.2d.array.v2i32.clamp
+    2, // llvm.nvvm.suld.2d.array.v2i32.trap
+    2, // llvm.nvvm.suld.2d.array.v2i32.zero
+    2, // llvm.nvvm.suld.2d.array.v2i64.clamp
+    2, // llvm.nvvm.suld.2d.array.v2i64.trap
+    2, // llvm.nvvm.suld.2d.array.v2i64.zero
+    2, // llvm.nvvm.suld.2d.array.v2i8.clamp
+    2, // llvm.nvvm.suld.2d.array.v2i8.trap
+    2, // llvm.nvvm.suld.2d.array.v2i8.zero
+    2, // llvm.nvvm.suld.2d.array.v4i16.clamp
+    2, // llvm.nvvm.suld.2d.array.v4i16.trap
+    2, // llvm.nvvm.suld.2d.array.v4i16.zero
+    2, // llvm.nvvm.suld.2d.array.v4i32.clamp
+    2, // llvm.nvvm.suld.2d.array.v4i32.trap
+    2, // llvm.nvvm.suld.2d.array.v4i32.zero
+    2, // llvm.nvvm.suld.2d.array.v4i8.clamp
+    2, // llvm.nvvm.suld.2d.array.v4i8.trap
+    2, // llvm.nvvm.suld.2d.array.v4i8.zero
+    2, // llvm.nvvm.suld.2d.i16.clamp
+    2, // llvm.nvvm.suld.2d.i16.trap
+    2, // llvm.nvvm.suld.2d.i16.zero
+    2, // llvm.nvvm.suld.2d.i32.clamp
+    2, // llvm.nvvm.suld.2d.i32.trap
+    2, // llvm.nvvm.suld.2d.i32.zero
+    2, // llvm.nvvm.suld.2d.i64.clamp
+    2, // llvm.nvvm.suld.2d.i64.trap
+    2, // llvm.nvvm.suld.2d.i64.zero
+    2, // llvm.nvvm.suld.2d.i8.clamp
+    2, // llvm.nvvm.suld.2d.i8.trap
+    2, // llvm.nvvm.suld.2d.i8.zero
+    2, // llvm.nvvm.suld.2d.v2i16.clamp
+    2, // llvm.nvvm.suld.2d.v2i16.trap
+    2, // llvm.nvvm.suld.2d.v2i16.zero
+    2, // llvm.nvvm.suld.2d.v2i32.clamp
+    2, // llvm.nvvm.suld.2d.v2i32.trap
+    2, // llvm.nvvm.suld.2d.v2i32.zero
+    2, // llvm.nvvm.suld.2d.v2i64.clamp
+    2, // llvm.nvvm.suld.2d.v2i64.trap
+    2, // llvm.nvvm.suld.2d.v2i64.zero
+    2, // llvm.nvvm.suld.2d.v2i8.clamp
+    2, // llvm.nvvm.suld.2d.v2i8.trap
+    2, // llvm.nvvm.suld.2d.v2i8.zero
+    2, // llvm.nvvm.suld.2d.v4i16.clamp
+    2, // llvm.nvvm.suld.2d.v4i16.trap
+    2, // llvm.nvvm.suld.2d.v4i16.zero
+    2, // llvm.nvvm.suld.2d.v4i32.clamp
+    2, // llvm.nvvm.suld.2d.v4i32.trap
+    2, // llvm.nvvm.suld.2d.v4i32.zero
+    2, // llvm.nvvm.suld.2d.v4i8.clamp
+    2, // llvm.nvvm.suld.2d.v4i8.trap
+    2, // llvm.nvvm.suld.2d.v4i8.zero
+    2, // llvm.nvvm.suld.3d.i16.clamp
+    2, // llvm.nvvm.suld.3d.i16.trap
+    2, // llvm.nvvm.suld.3d.i16.zero
+    2, // llvm.nvvm.suld.3d.i32.clamp
+    2, // llvm.nvvm.suld.3d.i32.trap
+    2, // llvm.nvvm.suld.3d.i32.zero
+    2, // llvm.nvvm.suld.3d.i64.clamp
+    2, // llvm.nvvm.suld.3d.i64.trap
+    2, // llvm.nvvm.suld.3d.i64.zero
+    2, // llvm.nvvm.suld.3d.i8.clamp
+    2, // llvm.nvvm.suld.3d.i8.trap
+    2, // llvm.nvvm.suld.3d.i8.zero
+    2, // llvm.nvvm.suld.3d.v2i16.clamp
+    2, // llvm.nvvm.suld.3d.v2i16.trap
+    2, // llvm.nvvm.suld.3d.v2i16.zero
+    2, // llvm.nvvm.suld.3d.v2i32.clamp
+    2, // llvm.nvvm.suld.3d.v2i32.trap
+    2, // llvm.nvvm.suld.3d.v2i32.zero
+    2, // llvm.nvvm.suld.3d.v2i64.clamp
+    2, // llvm.nvvm.suld.3d.v2i64.trap
+    2, // llvm.nvvm.suld.3d.v2i64.zero
+    2, // llvm.nvvm.suld.3d.v2i8.clamp
+    2, // llvm.nvvm.suld.3d.v2i8.trap
+    2, // llvm.nvvm.suld.3d.v2i8.zero
+    2, // llvm.nvvm.suld.3d.v4i16.clamp
+    2, // llvm.nvvm.suld.3d.v4i16.trap
+    2, // llvm.nvvm.suld.3d.v4i16.zero
+    2, // llvm.nvvm.suld.3d.v4i32.clamp
+    2, // llvm.nvvm.suld.3d.v4i32.trap
+    2, // llvm.nvvm.suld.3d.v4i32.zero
+    2, // llvm.nvvm.suld.3d.v4i8.clamp
+    2, // llvm.nvvm.suld.3d.v4i8.trap
+    2, // llvm.nvvm.suld.3d.v4i8.zero
+    1, // llvm.nvvm.suq.array.size
+    1, // llvm.nvvm.suq.channel.data.type
+    1, // llvm.nvvm.suq.channel.order
+    1, // llvm.nvvm.suq.depth
+    1, // llvm.nvvm.suq.height
+    1, // llvm.nvvm.suq.width
+    2, // llvm.nvvm.sust.b.1d.array.i16.clamp
+    2, // llvm.nvvm.sust.b.1d.array.i16.trap
+    2, // llvm.nvvm.sust.b.1d.array.i16.zero
+    2, // llvm.nvvm.sust.b.1d.array.i32.clamp
+    2, // llvm.nvvm.sust.b.1d.array.i32.trap
+    2, // llvm.nvvm.sust.b.1d.array.i32.zero
+    2, // llvm.nvvm.sust.b.1d.array.i64.clamp
+    2, // llvm.nvvm.sust.b.1d.array.i64.trap
+    2, // llvm.nvvm.sust.b.1d.array.i64.zero
+    2, // llvm.nvvm.sust.b.1d.array.i8.clamp
+    2, // llvm.nvvm.sust.b.1d.array.i8.trap
+    2, // llvm.nvvm.sust.b.1d.array.i8.zero
+    2, // llvm.nvvm.sust.b.1d.array.v2i16.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v2i16.trap
+    2, // llvm.nvvm.sust.b.1d.array.v2i16.zero
+    2, // llvm.nvvm.sust.b.1d.array.v2i32.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v2i32.trap
+    2, // llvm.nvvm.sust.b.1d.array.v2i32.zero
+    2, // llvm.nvvm.sust.b.1d.array.v2i64.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v2i64.trap
+    2, // llvm.nvvm.sust.b.1d.array.v2i64.zero
+    2, // llvm.nvvm.sust.b.1d.array.v2i8.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v2i8.trap
+    2, // llvm.nvvm.sust.b.1d.array.v2i8.zero
+    2, // llvm.nvvm.sust.b.1d.array.v4i16.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v4i16.trap
+    2, // llvm.nvvm.sust.b.1d.array.v4i16.zero
+    2, // llvm.nvvm.sust.b.1d.array.v4i32.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v4i32.trap
+    2, // llvm.nvvm.sust.b.1d.array.v4i32.zero
+    2, // llvm.nvvm.sust.b.1d.array.v4i8.clamp
+    2, // llvm.nvvm.sust.b.1d.array.v4i8.trap
+    2, // llvm.nvvm.sust.b.1d.array.v4i8.zero
+    2, // llvm.nvvm.sust.b.1d.i16.clamp
+    2, // llvm.nvvm.sust.b.1d.i16.trap
+    2, // llvm.nvvm.sust.b.1d.i16.zero
+    2, // llvm.nvvm.sust.b.1d.i32.clamp
+    2, // llvm.nvvm.sust.b.1d.i32.trap
+    2, // llvm.nvvm.sust.b.1d.i32.zero
+    2, // llvm.nvvm.sust.b.1d.i64.clamp
+    2, // llvm.nvvm.sust.b.1d.i64.trap
+    2, // llvm.nvvm.sust.b.1d.i64.zero
+    2, // llvm.nvvm.sust.b.1d.i8.clamp
+    2, // llvm.nvvm.sust.b.1d.i8.trap
+    2, // llvm.nvvm.sust.b.1d.i8.zero
+    2, // llvm.nvvm.sust.b.1d.v2i16.clamp
+    2, // llvm.nvvm.sust.b.1d.v2i16.trap
+    2, // llvm.nvvm.sust.b.1d.v2i16.zero
+    2, // llvm.nvvm.sust.b.1d.v2i32.clamp
+    2, // llvm.nvvm.sust.b.1d.v2i32.trap
+    2, // llvm.nvvm.sust.b.1d.v2i32.zero
+    2, // llvm.nvvm.sust.b.1d.v2i64.clamp
+    2, // llvm.nvvm.sust.b.1d.v2i64.trap
+    2, // llvm.nvvm.sust.b.1d.v2i64.zero
+    2, // llvm.nvvm.sust.b.1d.v2i8.clamp
+    2, // llvm.nvvm.sust.b.1d.v2i8.trap
+    2, // llvm.nvvm.sust.b.1d.v2i8.zero
+    2, // llvm.nvvm.sust.b.1d.v4i16.clamp
+    2, // llvm.nvvm.sust.b.1d.v4i16.trap
+    2, // llvm.nvvm.sust.b.1d.v4i16.zero
+    2, // llvm.nvvm.sust.b.1d.v4i32.clamp
+    2, // llvm.nvvm.sust.b.1d.v4i32.trap
+    2, // llvm.nvvm.sust.b.1d.v4i32.zero
+    2, // llvm.nvvm.sust.b.1d.v4i8.clamp
+    2, // llvm.nvvm.sust.b.1d.v4i8.trap
+    2, // llvm.nvvm.sust.b.1d.v4i8.zero
+    2, // llvm.nvvm.sust.b.2d.array.i16.clamp
+    2, // llvm.nvvm.sust.b.2d.array.i16.trap
+    2, // llvm.nvvm.sust.b.2d.array.i16.zero
+    2, // llvm.nvvm.sust.b.2d.array.i32.clamp
+    2, // llvm.nvvm.sust.b.2d.array.i32.trap
+    2, // llvm.nvvm.sust.b.2d.array.i32.zero
+    2, // llvm.nvvm.sust.b.2d.array.i64.clamp
+    2, // llvm.nvvm.sust.b.2d.array.i64.trap
+    2, // llvm.nvvm.sust.b.2d.array.i64.zero
+    2, // llvm.nvvm.sust.b.2d.array.i8.clamp
+    2, // llvm.nvvm.sust.b.2d.array.i8.trap
+    2, // llvm.nvvm.sust.b.2d.array.i8.zero
+    2, // llvm.nvvm.sust.b.2d.array.v2i16.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v2i16.trap
+    2, // llvm.nvvm.sust.b.2d.array.v2i16.zero
+    2, // llvm.nvvm.sust.b.2d.array.v2i32.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v2i32.trap
+    2, // llvm.nvvm.sust.b.2d.array.v2i32.zero
+    2, // llvm.nvvm.sust.b.2d.array.v2i64.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v2i64.trap
+    2, // llvm.nvvm.sust.b.2d.array.v2i64.zero
+    2, // llvm.nvvm.sust.b.2d.array.v2i8.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v2i8.trap
+    2, // llvm.nvvm.sust.b.2d.array.v2i8.zero
+    2, // llvm.nvvm.sust.b.2d.array.v4i16.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v4i16.trap
+    2, // llvm.nvvm.sust.b.2d.array.v4i16.zero
+    2, // llvm.nvvm.sust.b.2d.array.v4i32.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v4i32.trap
+    2, // llvm.nvvm.sust.b.2d.array.v4i32.zero
+    2, // llvm.nvvm.sust.b.2d.array.v4i8.clamp
+    2, // llvm.nvvm.sust.b.2d.array.v4i8.trap
+    2, // llvm.nvvm.sust.b.2d.array.v4i8.zero
+    2, // llvm.nvvm.sust.b.2d.i16.clamp
+    2, // llvm.nvvm.sust.b.2d.i16.trap
+    2, // llvm.nvvm.sust.b.2d.i16.zero
+    2, // llvm.nvvm.sust.b.2d.i32.clamp
+    2, // llvm.nvvm.sust.b.2d.i32.trap
+    2, // llvm.nvvm.sust.b.2d.i32.zero
+    2, // llvm.nvvm.sust.b.2d.i64.clamp
+    2, // llvm.nvvm.sust.b.2d.i64.trap
+    2, // llvm.nvvm.sust.b.2d.i64.zero
+    2, // llvm.nvvm.sust.b.2d.i8.clamp
+    2, // llvm.nvvm.sust.b.2d.i8.trap
+    2, // llvm.nvvm.sust.b.2d.i8.zero
+    2, // llvm.nvvm.sust.b.2d.v2i16.clamp
+    2, // llvm.nvvm.sust.b.2d.v2i16.trap
+    2, // llvm.nvvm.sust.b.2d.v2i16.zero
+    2, // llvm.nvvm.sust.b.2d.v2i32.clamp
+    2, // llvm.nvvm.sust.b.2d.v2i32.trap
+    2, // llvm.nvvm.sust.b.2d.v2i32.zero
+    2, // llvm.nvvm.sust.b.2d.v2i64.clamp
+    2, // llvm.nvvm.sust.b.2d.v2i64.trap
+    2, // llvm.nvvm.sust.b.2d.v2i64.zero
+    2, // llvm.nvvm.sust.b.2d.v2i8.clamp
+    2, // llvm.nvvm.sust.b.2d.v2i8.trap
+    2, // llvm.nvvm.sust.b.2d.v2i8.zero
+    2, // llvm.nvvm.sust.b.2d.v4i16.clamp
+    2, // llvm.nvvm.sust.b.2d.v4i16.trap
+    2, // llvm.nvvm.sust.b.2d.v4i16.zero
+    2, // llvm.nvvm.sust.b.2d.v4i32.clamp
+    2, // llvm.nvvm.sust.b.2d.v4i32.trap
+    2, // llvm.nvvm.sust.b.2d.v4i32.zero
+    2, // llvm.nvvm.sust.b.2d.v4i8.clamp
+    2, // llvm.nvvm.sust.b.2d.v4i8.trap
+    2, // llvm.nvvm.sust.b.2d.v4i8.zero
+    2, // llvm.nvvm.sust.b.3d.i16.clamp
+    2, // llvm.nvvm.sust.b.3d.i16.trap
+    2, // llvm.nvvm.sust.b.3d.i16.zero
+    2, // llvm.nvvm.sust.b.3d.i32.clamp
+    2, // llvm.nvvm.sust.b.3d.i32.trap
+    2, // llvm.nvvm.sust.b.3d.i32.zero
+    2, // llvm.nvvm.sust.b.3d.i64.clamp
+    2, // llvm.nvvm.sust.b.3d.i64.trap
+    2, // llvm.nvvm.sust.b.3d.i64.zero
+    2, // llvm.nvvm.sust.b.3d.i8.clamp
+    2, // llvm.nvvm.sust.b.3d.i8.trap
+    2, // llvm.nvvm.sust.b.3d.i8.zero
+    2, // llvm.nvvm.sust.b.3d.v2i16.clamp
+    2, // llvm.nvvm.sust.b.3d.v2i16.trap
+    2, // llvm.nvvm.sust.b.3d.v2i16.zero
+    2, // llvm.nvvm.sust.b.3d.v2i32.clamp
+    2, // llvm.nvvm.sust.b.3d.v2i32.trap
+    2, // llvm.nvvm.sust.b.3d.v2i32.zero
+    2, // llvm.nvvm.sust.b.3d.v2i64.clamp
+    2, // llvm.nvvm.sust.b.3d.v2i64.trap
+    2, // llvm.nvvm.sust.b.3d.v2i64.zero
+    2, // llvm.nvvm.sust.b.3d.v2i8.clamp
+    2, // llvm.nvvm.sust.b.3d.v2i8.trap
+    2, // llvm.nvvm.sust.b.3d.v2i8.zero
+    2, // llvm.nvvm.sust.b.3d.v4i16.clamp
+    2, // llvm.nvvm.sust.b.3d.v4i16.trap
+    2, // llvm.nvvm.sust.b.3d.v4i16.zero
+    2, // llvm.nvvm.sust.b.3d.v4i32.clamp
+    2, // llvm.nvvm.sust.b.3d.v4i32.trap
+    2, // llvm.nvvm.sust.b.3d.v4i32.zero
+    2, // llvm.nvvm.sust.b.3d.v4i8.clamp
+    2, // llvm.nvvm.sust.b.3d.v4i8.trap
+    2, // llvm.nvvm.sust.b.3d.v4i8.zero
+    2, // llvm.nvvm.sust.p.1d.array.i16.trap
+    2, // llvm.nvvm.sust.p.1d.array.i32.trap
+    2, // llvm.nvvm.sust.p.1d.array.i8.trap
+    2, // llvm.nvvm.sust.p.1d.array.v2i16.trap
+    2, // llvm.nvvm.sust.p.1d.array.v2i32.trap
+    2, // llvm.nvvm.sust.p.1d.array.v2i8.trap
+    2, // llvm.nvvm.sust.p.1d.array.v4i16.trap
+    2, // llvm.nvvm.sust.p.1d.array.v4i32.trap
+    2, // llvm.nvvm.sust.p.1d.array.v4i8.trap
+    2, // llvm.nvvm.sust.p.1d.i16.trap
+    2, // llvm.nvvm.sust.p.1d.i32.trap
+    2, // llvm.nvvm.sust.p.1d.i8.trap
+    2, // llvm.nvvm.sust.p.1d.v2i16.trap
+    2, // llvm.nvvm.sust.p.1d.v2i32.trap
+    2, // llvm.nvvm.sust.p.1d.v2i8.trap
+    2, // llvm.nvvm.sust.p.1d.v4i16.trap
+    2, // llvm.nvvm.sust.p.1d.v4i32.trap
+    2, // llvm.nvvm.sust.p.1d.v4i8.trap
+    2, // llvm.nvvm.sust.p.2d.array.i16.trap
+    2, // llvm.nvvm.sust.p.2d.array.i32.trap
+    2, // llvm.nvvm.sust.p.2d.array.i8.trap
+    2, // llvm.nvvm.sust.p.2d.array.v2i16.trap
+    2, // llvm.nvvm.sust.p.2d.array.v2i32.trap
+    2, // llvm.nvvm.sust.p.2d.array.v2i8.trap
+    2, // llvm.nvvm.sust.p.2d.array.v4i16.trap
+    2, // llvm.nvvm.sust.p.2d.array.v4i32.trap
+    2, // llvm.nvvm.sust.p.2d.array.v4i8.trap
+    2, // llvm.nvvm.sust.p.2d.i16.trap
+    2, // llvm.nvvm.sust.p.2d.i32.trap
+    2, // llvm.nvvm.sust.p.2d.i8.trap
+    2, // llvm.nvvm.sust.p.2d.v2i16.trap
+    2, // llvm.nvvm.sust.p.2d.v2i32.trap
+    2, // llvm.nvvm.sust.p.2d.v2i8.trap
+    2, // llvm.nvvm.sust.p.2d.v4i16.trap
+    2, // llvm.nvvm.sust.p.2d.v4i32.trap
+    2, // llvm.nvvm.sust.p.2d.v4i8.trap
+    2, // llvm.nvvm.sust.p.3d.i16.trap
+    2, // llvm.nvvm.sust.p.3d.i32.trap
+    2, // llvm.nvvm.sust.p.3d.i8.trap
+    2, // llvm.nvvm.sust.p.3d.v2i16.trap
+    2, // llvm.nvvm.sust.p.3d.v2i32.trap
+    2, // llvm.nvvm.sust.p.3d.v2i8.trap
+    2, // llvm.nvvm.sust.p.3d.v4i16.trap
+    2, // llvm.nvvm.sust.p.3d.v4i32.trap
+    2, // llvm.nvvm.sust.p.3d.v4i8.trap
+    1, // llvm.nvvm.swap.lo.hi.b64
+    2, // llvm.nvvm.tex.1d.array.grad.v4f32.f32
+    2, // llvm.nvvm.tex.1d.array.grad.v4s32.f32
+    2, // llvm.nvvm.tex.1d.array.grad.v4u32.f32
+    2, // llvm.nvvm.tex.1d.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.1d.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.1d.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.1d.array.v4f32.f32
+    2, // llvm.nvvm.tex.1d.array.v4f32.s32
+    2, // llvm.nvvm.tex.1d.array.v4s32.f32
+    2, // llvm.nvvm.tex.1d.array.v4s32.s32
+    2, // llvm.nvvm.tex.1d.array.v4u32.f32
+    2, // llvm.nvvm.tex.1d.array.v4u32.s32
+    2, // llvm.nvvm.tex.1d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.1d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.1d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.1d.level.v4f32.f32
+    2, // llvm.nvvm.tex.1d.level.v4s32.f32
+    2, // llvm.nvvm.tex.1d.level.v4u32.f32
+    2, // llvm.nvvm.tex.1d.v4f32.f32
+    2, // llvm.nvvm.tex.1d.v4f32.s32
+    2, // llvm.nvvm.tex.1d.v4s32.f32
+    2, // llvm.nvvm.tex.1d.v4s32.s32
+    2, // llvm.nvvm.tex.1d.v4u32.f32
+    2, // llvm.nvvm.tex.1d.v4u32.s32
+    2, // llvm.nvvm.tex.2d.array.grad.v4f32.f32
+    2, // llvm.nvvm.tex.2d.array.grad.v4s32.f32
+    2, // llvm.nvvm.tex.2d.array.grad.v4u32.f32
+    2, // llvm.nvvm.tex.2d.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.2d.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.2d.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.2d.array.v4f32.f32
+    2, // llvm.nvvm.tex.2d.array.v4f32.s32
+    2, // llvm.nvvm.tex.2d.array.v4s32.f32
+    2, // llvm.nvvm.tex.2d.array.v4s32.s32
+    2, // llvm.nvvm.tex.2d.array.v4u32.f32
+    2, // llvm.nvvm.tex.2d.array.v4u32.s32
+    2, // llvm.nvvm.tex.2d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.2d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.2d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.2d.level.v4f32.f32
+    2, // llvm.nvvm.tex.2d.level.v4s32.f32
+    2, // llvm.nvvm.tex.2d.level.v4u32.f32
+    2, // llvm.nvvm.tex.2d.v4f32.f32
+    2, // llvm.nvvm.tex.2d.v4f32.s32
+    2, // llvm.nvvm.tex.2d.v4s32.f32
+    2, // llvm.nvvm.tex.2d.v4s32.s32
+    2, // llvm.nvvm.tex.2d.v4u32.f32
+    2, // llvm.nvvm.tex.2d.v4u32.s32
+    2, // llvm.nvvm.tex.3d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.3d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.3d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.3d.level.v4f32.f32
+    2, // llvm.nvvm.tex.3d.level.v4s32.f32
+    2, // llvm.nvvm.tex.3d.level.v4u32.f32
+    2, // llvm.nvvm.tex.3d.v4f32.f32
+    2, // llvm.nvvm.tex.3d.v4f32.s32
+    2, // llvm.nvvm.tex.3d.v4s32.f32
+    2, // llvm.nvvm.tex.3d.v4s32.s32
+    2, // llvm.nvvm.tex.3d.v4u32.f32
+    2, // llvm.nvvm.tex.3d.v4u32.s32
+    2, // llvm.nvvm.tex.cube.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.cube.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.cube.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.cube.array.v4f32.f32
+    2, // llvm.nvvm.tex.cube.array.v4s32.f32
+    2, // llvm.nvvm.tex.cube.array.v4u32.f32
+    2, // llvm.nvvm.tex.cube.level.v4f32.f32
+    2, // llvm.nvvm.tex.cube.level.v4s32.f32
+    2, // llvm.nvvm.tex.cube.level.v4u32.f32
+    2, // llvm.nvvm.tex.cube.v4f32.f32
+    2, // llvm.nvvm.tex.cube.v4s32.f32
+    2, // llvm.nvvm.tex.cube.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.grad.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.grad.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.grad.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.v4f32.s32
+    2, // llvm.nvvm.tex.unified.1d.array.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.v4s32.s32
+    2, // llvm.nvvm.tex.unified.1d.array.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.array.v4u32.s32
+    2, // llvm.nvvm.tex.unified.1d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.v4f32.f32
+    2, // llvm.nvvm.tex.unified.1d.v4f32.s32
+    2, // llvm.nvvm.tex.unified.1d.v4s32.f32
+    2, // llvm.nvvm.tex.unified.1d.v4s32.s32
+    2, // llvm.nvvm.tex.unified.1d.v4u32.f32
+    2, // llvm.nvvm.tex.unified.1d.v4u32.s32
+    2, // llvm.nvvm.tex.unified.2d.array.grad.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.grad.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.grad.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.v4f32.s32
+    2, // llvm.nvvm.tex.unified.2d.array.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.v4s32.s32
+    2, // llvm.nvvm.tex.unified.2d.array.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.array.v4u32.s32
+    2, // llvm.nvvm.tex.unified.2d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.v4f32.f32
+    2, // llvm.nvvm.tex.unified.2d.v4f32.s32
+    2, // llvm.nvvm.tex.unified.2d.v4s32.f32
+    2, // llvm.nvvm.tex.unified.2d.v4s32.s32
+    2, // llvm.nvvm.tex.unified.2d.v4u32.f32
+    2, // llvm.nvvm.tex.unified.2d.v4u32.s32
+    2, // llvm.nvvm.tex.unified.3d.grad.v4f32.f32
+    2, // llvm.nvvm.tex.unified.3d.grad.v4s32.f32
+    2, // llvm.nvvm.tex.unified.3d.grad.v4u32.f32
+    2, // llvm.nvvm.tex.unified.3d.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.3d.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.3d.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.3d.v4f32.f32
+    2, // llvm.nvvm.tex.unified.3d.v4f32.s32
+    2, // llvm.nvvm.tex.unified.3d.v4s32.f32
+    2, // llvm.nvvm.tex.unified.3d.v4s32.s32
+    2, // llvm.nvvm.tex.unified.3d.v4u32.f32
+    2, // llvm.nvvm.tex.unified.3d.v4u32.s32
+    2, // llvm.nvvm.tex.unified.cube.array.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.cube.array.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.cube.array.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.cube.array.v4f32.f32
+    2, // llvm.nvvm.tex.unified.cube.array.v4s32.f32
+    2, // llvm.nvvm.tex.unified.cube.array.v4u32.f32
+    2, // llvm.nvvm.tex.unified.cube.level.v4f32.f32
+    2, // llvm.nvvm.tex.unified.cube.level.v4s32.f32
+    2, // llvm.nvvm.tex.unified.cube.level.v4u32.f32
+    2, // llvm.nvvm.tex.unified.cube.v4f32.f32
+    2, // llvm.nvvm.tex.unified.cube.v4s32.f32
+    2, // llvm.nvvm.tex.unified.cube.v4u32.f32
+    1, // llvm.nvvm.texsurf.handle
+    1, // llvm.nvvm.texsurf.handle.internal
+    2, // llvm.nvvm.tld4.a.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.a.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.a.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.b.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.b.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.b.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.g.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.g.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.g.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.r.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.r.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.r.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.unified.a.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.unified.a.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.unified.a.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.unified.b.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.unified.b.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.unified.b.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.unified.g.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.unified.g.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.unified.g.2d.v4u32.f32
+    2, // llvm.nvvm.tld4.unified.r.2d.v4f32.f32
+    2, // llvm.nvvm.tld4.unified.r.2d.v4s32.f32
+    2, // llvm.nvvm.tld4.unified.r.2d.v4u32.f32
+    1, // llvm.nvvm.trunc.d
+    1, // llvm.nvvm.trunc.f
+    1, // llvm.nvvm.trunc.ftz.f
+    1, // llvm.nvvm.txq.array.size
+    1, // llvm.nvvm.txq.channel.data.type
+    1, // llvm.nvvm.txq.channel.order
+    1, // llvm.nvvm.txq.depth
+    1, // llvm.nvvm.txq.height
+    1, // llvm.nvvm.txq.num.mipmap.levels
+    1, // llvm.nvvm.txq.num.samples
+    1, // llvm.nvvm.txq.width
+    1, // llvm.nvvm.ui2d.rm
+    1, // llvm.nvvm.ui2d.rn
+    1, // llvm.nvvm.ui2d.rp
+    1, // llvm.nvvm.ui2d.rz
+    1, // llvm.nvvm.ui2f.rm
+    1, // llvm.nvvm.ui2f.rn
+    1, // llvm.nvvm.ui2f.rp
+    1, // llvm.nvvm.ui2f.rz
+    1, // llvm.nvvm.ull2d.rm
+    1, // llvm.nvvm.ull2d.rn
+    1, // llvm.nvvm.ull2d.rp
+    1, // llvm.nvvm.ull2d.rz
+    1, // llvm.nvvm.ull2f.rm
+    1, // llvm.nvvm.ull2f.rn
+    1, // llvm.nvvm.ull2f.rp
+    1, // llvm.nvvm.ull2f.rz
+    1, // llvm.objectsize
+    2, // llvm.pcmarker
+    1, // llvm.pow
+    1, // llvm.powi
+    2, // llvm.ppc.altivec.dss
+    2, // llvm.ppc.altivec.dssall
+    2, // llvm.ppc.altivec.dst
+    2, // llvm.ppc.altivec.dstst
+    2, // llvm.ppc.altivec.dststt
+    2, // llvm.ppc.altivec.dstt
+    3, // llvm.ppc.altivec.lvebx
+    3, // llvm.ppc.altivec.lvehx
+    3, // llvm.ppc.altivec.lvewx
+    1, // llvm.ppc.altivec.lvsl
+    1, // llvm.ppc.altivec.lvsr
+    3, // llvm.ppc.altivec.lvx
+    3, // llvm.ppc.altivec.lvxl
+    3, // llvm.ppc.altivec.mfvscr
+    2, // llvm.ppc.altivec.mtvscr
+    2, // llvm.ppc.altivec.stvebx
+    2, // llvm.ppc.altivec.stvehx
+    2, // llvm.ppc.altivec.stvewx
+    2, // llvm.ppc.altivec.stvx
+    2, // llvm.ppc.altivec.stvxl
+    1, // llvm.ppc.altivec.vaddcuw
+    1, // llvm.ppc.altivec.vaddsbs
+    1, // llvm.ppc.altivec.vaddshs
+    1, // llvm.ppc.altivec.vaddsws
+    1, // llvm.ppc.altivec.vaddubs
+    1, // llvm.ppc.altivec.vadduhs
+    1, // llvm.ppc.altivec.vadduws
+    1, // llvm.ppc.altivec.vavgsb
+    1, // llvm.ppc.altivec.vavgsh
+    1, // llvm.ppc.altivec.vavgsw
+    1, // llvm.ppc.altivec.vavgub
+    1, // llvm.ppc.altivec.vavguh
+    1, // llvm.ppc.altivec.vavguw
+    1, // llvm.ppc.altivec.vcfsx
+    1, // llvm.ppc.altivec.vcfux
+    1, // llvm.ppc.altivec.vcmpbfp
+    1, // llvm.ppc.altivec.vcmpbfp.p
+    1, // llvm.ppc.altivec.vcmpeqfp
+    1, // llvm.ppc.altivec.vcmpeqfp.p
+    1, // llvm.ppc.altivec.vcmpequb
+    1, // llvm.ppc.altivec.vcmpequb.p
+    1, // llvm.ppc.altivec.vcmpequh
+    1, // llvm.ppc.altivec.vcmpequh.p
+    1, // llvm.ppc.altivec.vcmpequw
+    1, // llvm.ppc.altivec.vcmpequw.p
+    1, // llvm.ppc.altivec.vcmpgefp
+    1, // llvm.ppc.altivec.vcmpgefp.p
+    1, // llvm.ppc.altivec.vcmpgtfp
+    1, // llvm.ppc.altivec.vcmpgtfp.p
+    1, // llvm.ppc.altivec.vcmpgtsb
+    1, // llvm.ppc.altivec.vcmpgtsb.p
+    1, // llvm.ppc.altivec.vcmpgtsh
+    1, // llvm.ppc.altivec.vcmpgtsh.p
+    1, // llvm.ppc.altivec.vcmpgtsw
+    1, // llvm.ppc.altivec.vcmpgtsw.p
+    1, // llvm.ppc.altivec.vcmpgtub
+    1, // llvm.ppc.altivec.vcmpgtub.p
+    1, // llvm.ppc.altivec.vcmpgtuh
+    1, // llvm.ppc.altivec.vcmpgtuh.p
+    1, // llvm.ppc.altivec.vcmpgtuw
+    1, // llvm.ppc.altivec.vcmpgtuw.p
+    1, // llvm.ppc.altivec.vctsxs
+    1, // llvm.ppc.altivec.vctuxs
+    1, // llvm.ppc.altivec.vexptefp
+    1, // llvm.ppc.altivec.vlogefp
+    1, // llvm.ppc.altivec.vmaddfp
+    1, // llvm.ppc.altivec.vmaxfp
+    1, // llvm.ppc.altivec.vmaxsb
+    1, // llvm.ppc.altivec.vmaxsh
+    1, // llvm.ppc.altivec.vmaxsw
+    1, // llvm.ppc.altivec.vmaxub
+    1, // llvm.ppc.altivec.vmaxuh
+    1, // llvm.ppc.altivec.vmaxuw
+    1, // llvm.ppc.altivec.vmhaddshs
+    1, // llvm.ppc.altivec.vmhraddshs
+    1, // llvm.ppc.altivec.vminfp
+    1, // llvm.ppc.altivec.vminsb
+    1, // llvm.ppc.altivec.vminsh
+    1, // llvm.ppc.altivec.vminsw
+    1, // llvm.ppc.altivec.vminub
+    1, // llvm.ppc.altivec.vminuh
+    1, // llvm.ppc.altivec.vminuw
+    1, // llvm.ppc.altivec.vmladduhm
+    1, // llvm.ppc.altivec.vmsummbm
+    1, // llvm.ppc.altivec.vmsumshm
+    1, // llvm.ppc.altivec.vmsumshs
+    1, // llvm.ppc.altivec.vmsumubm
+    1, // llvm.ppc.altivec.vmsumuhm
+    1, // llvm.ppc.altivec.vmsumuhs
+    1, // llvm.ppc.altivec.vmulesb
+    1, // llvm.ppc.altivec.vmulesh
+    1, // llvm.ppc.altivec.vmuleub
+    1, // llvm.ppc.altivec.vmuleuh
+    1, // llvm.ppc.altivec.vmulosb
+    1, // llvm.ppc.altivec.vmulosh
+    1, // llvm.ppc.altivec.vmuloub
+    1, // llvm.ppc.altivec.vmulouh
+    1, // llvm.ppc.altivec.vnmsubfp
+    1, // llvm.ppc.altivec.vperm
+    1, // llvm.ppc.altivec.vpkpx
+    1, // llvm.ppc.altivec.vpkshss
+    1, // llvm.ppc.altivec.vpkshus
+    1, // llvm.ppc.altivec.vpkswss
+    1, // llvm.ppc.altivec.vpkswus
+    1, // llvm.ppc.altivec.vpkuhus
+    1, // llvm.ppc.altivec.vpkuwus
+    1, // llvm.ppc.altivec.vrefp
+    1, // llvm.ppc.altivec.vrfim
+    1, // llvm.ppc.altivec.vrfin
+    1, // llvm.ppc.altivec.vrfip
+    1, // llvm.ppc.altivec.vrfiz
+    1, // llvm.ppc.altivec.vrlb
+    1, // llvm.ppc.altivec.vrlh
+    1, // llvm.ppc.altivec.vrlw
+    1, // llvm.ppc.altivec.vrsqrtefp
+    1, // llvm.ppc.altivec.vsel
+    1, // llvm.ppc.altivec.vsl
+    1, // llvm.ppc.altivec.vslb
+    1, // llvm.ppc.altivec.vslh
+    1, // llvm.ppc.altivec.vslo
+    1, // llvm.ppc.altivec.vslw
+    1, // llvm.ppc.altivec.vsr
+    1, // llvm.ppc.altivec.vsrab
+    1, // llvm.ppc.altivec.vsrah
+    1, // llvm.ppc.altivec.vsraw
+    1, // llvm.ppc.altivec.vsrb
+    1, // llvm.ppc.altivec.vsrh
+    1, // llvm.ppc.altivec.vsro
+    1, // llvm.ppc.altivec.vsrw
+    1, // llvm.ppc.altivec.vsubcuw
+    1, // llvm.ppc.altivec.vsubsbs
+    1, // llvm.ppc.altivec.vsubshs
+    1, // llvm.ppc.altivec.vsubsws
+    1, // llvm.ppc.altivec.vsububs
+    1, // llvm.ppc.altivec.vsubuhs
+    1, // llvm.ppc.altivec.vsubuws
+    1, // llvm.ppc.altivec.vsum2sws
+    1, // llvm.ppc.altivec.vsum4sbs
+    1, // llvm.ppc.altivec.vsum4shs
+    1, // llvm.ppc.altivec.vsum4ubs
+    1, // llvm.ppc.altivec.vsumsws
+    1, // llvm.ppc.altivec.vupkhpx
+    1, // llvm.ppc.altivec.vupkhsb
+    1, // llvm.ppc.altivec.vupkhsh
+    1, // llvm.ppc.altivec.vupklpx
+    1, // llvm.ppc.altivec.vupklsb
+    1, // llvm.ppc.altivec.vupklsh
+    2, // llvm.ppc.dcba
+    2, // llvm.ppc.dcbf
+    2, // llvm.ppc.dcbi
+    2, // llvm.ppc.dcbst
+    12, // llvm.ppc.dcbt
+    2, // llvm.ppc.dcbtst
+    2, // llvm.ppc.dcbz
+    2, // llvm.ppc.dcbzl
+    2, // llvm.ppc.is.decremented.ctr.nonzero
+    2, // llvm.ppc.mtctr
+    2, // llvm.ppc.sync
+    12, // llvm.prefetch
+    2, // llvm.ptr.annotation
+    2, // llvm.ptx.bar.sync
+    1, // llvm.ptx.read.clock
+    1, // llvm.ptx.read.clock64
+    1, // llvm.ptx.read.ctaid.w
+    1, // llvm.ptx.read.ctaid.x
+    1, // llvm.ptx.read.ctaid.y
+    1, // llvm.ptx.read.ctaid.z
+    1, // llvm.ptx.read.gridid
+    1, // llvm.ptx.read.laneid
+    1, // llvm.ptx.read.lanemask.eq
+    1, // llvm.ptx.read.lanemask.ge
+    1, // llvm.ptx.read.lanemask.gt
+    1, // llvm.ptx.read.lanemask.le
+    1, // llvm.ptx.read.lanemask.lt
+    1, // llvm.ptx.read.nctaid.w
+    1, // llvm.ptx.read.nctaid.x
+    1, // llvm.ptx.read.nctaid.y
+    1, // llvm.ptx.read.nctaid.z
+    1, // llvm.ptx.read.nsmid
+    1, // llvm.ptx.read.ntid.w
+    1, // llvm.ptx.read.ntid.x
+    1, // llvm.ptx.read.ntid.y
+    1, // llvm.ptx.read.ntid.z
+    1, // llvm.ptx.read.nwarpid
+    1, // llvm.ptx.read.pm0
+    1, // llvm.ptx.read.pm1
+    1, // llvm.ptx.read.pm2
+    1, // llvm.ptx.read.pm3
+    1, // llvm.ptx.read.smid
+    1, // llvm.ptx.read.tid.w
+    1, // llvm.ptx.read.tid.x
+    1, // llvm.ptx.read.tid.y
+    1, // llvm.ptx.read.tid.z
+    1, // llvm.ptx.read.warpid
+    1, // llvm.r600.read.global.size.x
+    1, // llvm.r600.read.global.size.y
+    1, // llvm.r600.read.global.size.z
+    1, // llvm.r600.read.local.size.x
+    1, // llvm.r600.read.local.size.y
+    1, // llvm.r600.read.local.size.z
+    1, // llvm.r600.read.ngroups.x
+    1, // llvm.r600.read.ngroups.y
+    1, // llvm.r600.read.ngroups.z
+    1, // llvm.r600.read.tgid.x
+    1, // llvm.r600.read.tgid.y
+    1, // llvm.r600.read.tgid.z
+    1, // llvm.r600.read.tidig.x
+    1, // llvm.r600.read.tidig.y
+    1, // llvm.r600.read.tidig.z
+    1, // llvm.read_register
+    2, // llvm.readcyclecounter
+    1, // llvm.returnaddress
+    1, // llvm.rint
+    1, // llvm.round
+    1, // llvm.sadd.with.overflow
+    2, // llvm.setjmp
+    9, // llvm.siglongjmp
+    2, // llvm.sigsetjmp
+    1, // llvm.sin
+    1, // llvm.smul.with.overflow
+    1, // llvm.sqrt
+    1, // llvm.ssub.with.overflow
+    2, // llvm.stackprotector
+    2, // llvm.stackprotectorcheck
+    2, // llvm.stackrestore
+    2, // llvm.stacksave
+    9, // llvm.trap
+    1, // llvm.trunc
+    1, // llvm.uadd.with.overflow
+    1, // llvm.umul.with.overflow
+    1, // llvm.usub.with.overflow
+    2, // llvm.va_copy
+    2, // llvm.va_end
+    2, // llvm.var.annotation
+    2, // llvm.va_start
+    2, // llvm.write_register
+    1, // llvm.x86.3dnow.pavgusb
+    1, // llvm.x86.3dnow.pf2id
+    1, // llvm.x86.3dnow.pfacc
+    1, // llvm.x86.3dnow.pfadd
+    1, // llvm.x86.3dnow.pfcmpeq
+    1, // llvm.x86.3dnow.pfcmpge
+    1, // llvm.x86.3dnow.pfcmpgt
+    1, // llvm.x86.3dnow.pfmax
+    1, // llvm.x86.3dnow.pfmin
+    1, // llvm.x86.3dnow.pfmul
+    1, // llvm.x86.3dnow.pfrcp
+    1, // llvm.x86.3dnow.pfrcpit1
+    1, // llvm.x86.3dnow.pfrcpit2
+    1, // llvm.x86.3dnow.pfrsqit1
+    1, // llvm.x86.3dnow.pfrsqrt
+    1, // llvm.x86.3dnow.pfsub
+    1, // llvm.x86.3dnow.pfsubr
+    1, // llvm.x86.3dnow.pi2fd
+    1, // llvm.x86.3dnow.pmulhrw
+    1, // llvm.x86.3dnowa.pf2iw
+    1, // llvm.x86.3dnowa.pfnacc
+    1, // llvm.x86.3dnowa.pfpnacc
+    1, // llvm.x86.3dnowa.pi2fw
+    1, // llvm.x86.3dnowa.pswapd
+    1, // llvm.x86.aesni.aesdec
+    1, // llvm.x86.aesni.aesdeclast
+    1, // llvm.x86.aesni.aesenc
+    1, // llvm.x86.aesni.aesenclast
+    1, // llvm.x86.aesni.aesimc
+    1, // llvm.x86.aesni.aeskeygenassist
+    3, // llvm.x86.avx2.gather.d.d
+    3, // llvm.x86.avx2.gather.d.d.256
+    3, // llvm.x86.avx2.gather.d.pd
+    3, // llvm.x86.avx2.gather.d.pd.256
+    3, // llvm.x86.avx2.gather.d.ps
+    3, // llvm.x86.avx2.gather.d.ps.256
+    3, // llvm.x86.avx2.gather.d.q
+    3, // llvm.x86.avx2.gather.d.q.256
+    3, // llvm.x86.avx2.gather.q.d
+    3, // llvm.x86.avx2.gather.q.d.256
+    3, // llvm.x86.avx2.gather.q.pd
+    3, // llvm.x86.avx2.gather.q.pd.256
+    3, // llvm.x86.avx2.gather.q.ps
+    3, // llvm.x86.avx2.gather.q.ps.256
+    3, // llvm.x86.avx2.gather.q.q
+    3, // llvm.x86.avx2.gather.q.q.256
+    3, // llvm.x86.avx2.maskload.d
+    3, // llvm.x86.avx2.maskload.d.256
+    3, // llvm.x86.avx2.maskload.q
+    3, // llvm.x86.avx2.maskload.q.256
+    2, // llvm.x86.avx2.maskstore.d
+    2, // llvm.x86.avx2.maskstore.d.256
+    2, // llvm.x86.avx2.maskstore.q
+    2, // llvm.x86.avx2.maskstore.q.256
+    3, // llvm.x86.avx2.movntdqa
+    1, // llvm.x86.avx2.mpsadbw
+    1, // llvm.x86.avx2.pabs.b
+    1, // llvm.x86.avx2.pabs.d
+    1, // llvm.x86.avx2.pabs.w
+    1, // llvm.x86.avx2.packssdw
+    1, // llvm.x86.avx2.packsswb
+    1, // llvm.x86.avx2.packusdw
+    1, // llvm.x86.avx2.packuswb
+    1, // llvm.x86.avx2.padds.b
+    1, // llvm.x86.avx2.padds.w
+    1, // llvm.x86.avx2.paddus.b
+    1, // llvm.x86.avx2.paddus.w
+    1, // llvm.x86.avx2.pavg.b
+    1, // llvm.x86.avx2.pavg.w
+    1, // llvm.x86.avx2.pblendd.128
+    1, // llvm.x86.avx2.pblendd.256
+    1, // llvm.x86.avx2.pblendvb
+    1, // llvm.x86.avx2.pblendw
+    1, // llvm.x86.avx2.pbroadcastb.128
+    1, // llvm.x86.avx2.pbroadcastb.256
+    1, // llvm.x86.avx2.pbroadcastd.128
+    1, // llvm.x86.avx2.pbroadcastd.256
+    1, // llvm.x86.avx2.pbroadcastq.128
+    1, // llvm.x86.avx2.pbroadcastq.256
+    1, // llvm.x86.avx2.pbroadcastw.128
+    1, // llvm.x86.avx2.pbroadcastw.256
+    1, // llvm.x86.avx2.permd
+    1, // llvm.x86.avx2.permps
+    1, // llvm.x86.avx2.phadd.d
+    1, // llvm.x86.avx2.phadd.sw
+    1, // llvm.x86.avx2.phadd.w
+    1, // llvm.x86.avx2.phsub.d
+    1, // llvm.x86.avx2.phsub.sw
+    1, // llvm.x86.avx2.phsub.w
+    1, // llvm.x86.avx2.pmadd.ub.sw
+    1, // llvm.x86.avx2.pmadd.wd
+    1, // llvm.x86.avx2.pmaxs.b
+    1, // llvm.x86.avx2.pmaxs.d
+    1, // llvm.x86.avx2.pmaxs.w
+    1, // llvm.x86.avx2.pmaxu.b
+    1, // llvm.x86.avx2.pmaxu.d
+    1, // llvm.x86.avx2.pmaxu.w
+    1, // llvm.x86.avx2.pmins.b
+    1, // llvm.x86.avx2.pmins.d
+    1, // llvm.x86.avx2.pmins.w
+    1, // llvm.x86.avx2.pminu.b
+    1, // llvm.x86.avx2.pminu.d
+    1, // llvm.x86.avx2.pminu.w
+    1, // llvm.x86.avx2.pmovmskb
+    1, // llvm.x86.avx2.pmovsxbd
+    1, // llvm.x86.avx2.pmovsxbq
+    1, // llvm.x86.avx2.pmovsxbw
+    1, // llvm.x86.avx2.pmovsxdq
+    1, // llvm.x86.avx2.pmovsxwd
+    1, // llvm.x86.avx2.pmovsxwq
+    1, // llvm.x86.avx2.pmovzxbd
+    1, // llvm.x86.avx2.pmovzxbq
+    1, // llvm.x86.avx2.pmovzxbw
+    1, // llvm.x86.avx2.pmovzxdq
+    1, // llvm.x86.avx2.pmovzxwd
+    1, // llvm.x86.avx2.pmovzxwq
+    1, // llvm.x86.avx2.pmul.dq
+    1, // llvm.x86.avx2.pmul.hr.sw
+    1, // llvm.x86.avx2.pmulh.w
+    1, // llvm.x86.avx2.pmulhu.w
+    1, // llvm.x86.avx2.pmulu.dq
+    1, // llvm.x86.avx2.psad.bw
+    1, // llvm.x86.avx2.pshuf.b
+    1, // llvm.x86.avx2.psign.b
+    1, // llvm.x86.avx2.psign.d
+    1, // llvm.x86.avx2.psign.w
+    1, // llvm.x86.avx2.psll.d
+    1, // llvm.x86.avx2.psll.dq
+    1, // llvm.x86.avx2.psll.dq.bs
+    1, // llvm.x86.avx2.psll.q
+    1, // llvm.x86.avx2.psll.w
+    1, // llvm.x86.avx2.pslli.d
+    1, // llvm.x86.avx2.pslli.q
+    1, // llvm.x86.avx2.pslli.w
+    1, // llvm.x86.avx2.psllv.d
+    1, // llvm.x86.avx2.psllv.d.256
+    1, // llvm.x86.avx2.psllv.q
+    1, // llvm.x86.avx2.psllv.q.256
+    1, // llvm.x86.avx2.psra.d
+    1, // llvm.x86.avx2.psra.w
+    1, // llvm.x86.avx2.psrai.d
+    1, // llvm.x86.avx2.psrai.w
+    1, // llvm.x86.avx2.psrav.d
+    1, // llvm.x86.avx2.psrav.d.256
+    1, // llvm.x86.avx2.psrl.d
+    1, // llvm.x86.avx2.psrl.dq
+    1, // llvm.x86.avx2.psrl.dq.bs
+    1, // llvm.x86.avx2.psrl.q
+    1, // llvm.x86.avx2.psrl.w
+    1, // llvm.x86.avx2.psrli.d
+    1, // llvm.x86.avx2.psrli.q
+    1, // llvm.x86.avx2.psrli.w
+    1, // llvm.x86.avx2.psrlv.d
+    1, // llvm.x86.avx2.psrlv.d.256
+    1, // llvm.x86.avx2.psrlv.q
+    1, // llvm.x86.avx2.psrlv.q.256
+    1, // llvm.x86.avx2.psubs.b
+    1, // llvm.x86.avx2.psubs.w
+    1, // llvm.x86.avx2.psubus.b
+    1, // llvm.x86.avx2.psubus.w
+    1, // llvm.x86.avx2.vbroadcast.sd.pd.256
+    1, // llvm.x86.avx2.vbroadcast.ss.ps
+    1, // llvm.x86.avx2.vbroadcast.ss.ps.256
+    3, // llvm.x86.avx2.vbroadcasti128
+    1, // llvm.x86.avx2.vextracti128
+    1, // llvm.x86.avx2.vinserti128
+    1, // llvm.x86.avx2.vperm2i128
+    1, // llvm.x86.avx512.cvtsd2usi
+    1, // llvm.x86.avx512.cvtsd2usi64
+    1, // llvm.x86.avx512.cvtss2usi
+    1, // llvm.x86.avx512.cvtss2usi64
+    1, // llvm.x86.avx512.cvttsd2usi
+    1, // llvm.x86.avx512.cvttsd2usi64
+    1, // llvm.x86.avx512.cvttss2usi
+    1, // llvm.x86.avx512.cvttss2usi64
+    1, // llvm.x86.avx512.cvtusi2sd
+    1, // llvm.x86.avx512.cvtusi2ss
+    1, // llvm.x86.avx512.cvtusi642sd
+    1, // llvm.x86.avx512.cvtusi642ss
+    3, // llvm.x86.avx512.gather.dpd.512
+    3, // llvm.x86.avx512.gather.dpi.512
+    3, // llvm.x86.avx512.gather.dpq.512
+    3, // llvm.x86.avx512.gather.dps.512
+    3, // llvm.x86.avx512.gather.qpd.512
+    3, // llvm.x86.avx512.gather.qpi.512
+    3, // llvm.x86.avx512.gather.qpq.512
+    3, // llvm.x86.avx512.gather.qps.512
+    2, // llvm.x86.avx512.gatherpf.dpd.512
+    2, // llvm.x86.avx512.gatherpf.dps.512
+    2, // llvm.x86.avx512.gatherpf.qpd.512
+    2, // llvm.x86.avx512.gatherpf.qps.512
+    1, // llvm.x86.avx512.kand.w
+    1, // llvm.x86.avx512.kandn.w
+    1, // llvm.x86.avx512.knot.w
+    1, // llvm.x86.avx512.kor.w
+    1, // llvm.x86.avx512.kortestc.w
+    1, // llvm.x86.avx512.kortestz.w
+    1, // llvm.x86.avx512.kunpck.bw
+    1, // llvm.x86.avx512.kxnor.w
+    1, // llvm.x86.avx512.kxor.w
+    1, // llvm.x86.avx512.mask.blend.d.512
+    1, // llvm.x86.avx512.mask.blend.pd.512
+    1, // llvm.x86.avx512.mask.blend.ps.512
+    1, // llvm.x86.avx512.mask.blend.q.512
+    1, // llvm.x86.avx512.mask.cmp.pd.512
+    1, // llvm.x86.avx512.mask.cmp.ps.512
+    2, // llvm.x86.avx512.mask.conflict.d.512
+    2, // llvm.x86.avx512.mask.conflict.q.512
+    1, // llvm.x86.avx512.mask.cvtdq2pd.512
+    1, // llvm.x86.avx512.mask.cvtdq2ps.512
+    1, // llvm.x86.avx512.mask.cvtpd2dq.512
+    1, // llvm.x86.avx512.mask.cvtpd2ps.512
+    1, // llvm.x86.avx512.mask.cvtpd2udq.512
+    1, // llvm.x86.avx512.mask.cvtps2dq.512
+    1, // llvm.x86.avx512.mask.cvtps2udq.512
+    1, // llvm.x86.avx512.mask.cvttpd2dq.512
+    1, // llvm.x86.avx512.mask.cvttpd2udq.512
+    1, // llvm.x86.avx512.mask.cvttps2dq.512
+    1, // llvm.x86.avx512.mask.cvttps2udq.512
+    1, // llvm.x86.avx512.mask.cvtudq2pd.512
+    1, // llvm.x86.avx512.mask.cvtudq2ps.512
+    3, // llvm.x86.avx512.mask.loadu.d.512
+    3, // llvm.x86.avx512.mask.loadu.pd.512
+    3, // llvm.x86.avx512.mask.loadu.ps.512
+    3, // llvm.x86.avx512.mask.loadu.q.512
+    2, // llvm.x86.avx512.mask.lzcnt.d.512
+    2, // llvm.x86.avx512.mask.lzcnt.q.512
+    1, // llvm.x86.avx512.mask.max.pd.512
+    1, // llvm.x86.avx512.mask.max.ps.512
+    1, // llvm.x86.avx512.mask.min.pd.512
+    1, // llvm.x86.avx512.mask.min.ps.512
+    1, // llvm.x86.avx512.mask.pabs.d.512
+    1, // llvm.x86.avx512.mask.pabs.q.512
+    1, // llvm.x86.avx512.mask.pand.d.512
+    1, // llvm.x86.avx512.mask.pand.q.512
+    1, // llvm.x86.avx512.mask.pbroadcast.d.gpr.512
+    1, // llvm.x86.avx512.mask.pbroadcast.q.gpr.512
+    1, // llvm.x86.avx512.mask.pbroadcast.q.mem.512
+    1, // llvm.x86.avx512.mask.pcmpeq.d.512
+    1, // llvm.x86.avx512.mask.pcmpeq.q.512
+    1, // llvm.x86.avx512.mask.pmaxs.d.512
+    1, // llvm.x86.avx512.mask.pmaxs.q.512
+    1, // llvm.x86.avx512.mask.pmaxu.d.512
+    1, // llvm.x86.avx512.mask.pmaxu.q.512
+    1, // llvm.x86.avx512.mask.pmins.d.512
+    1, // llvm.x86.avx512.mask.pmins.q.512
+    1, // llvm.x86.avx512.mask.pminu.d.512
+    1, // llvm.x86.avx512.mask.pminu.q.512
+    1, // llvm.x86.avx512.mask.pmul.dq.512
+    1, // llvm.x86.avx512.mask.pmulu.dq.512
+    1, // llvm.x86.avx512.mask.ptestm.d.512
+    1, // llvm.x86.avx512.mask.ptestm.q.512
+    1, // llvm.x86.avx512.mask.rndscale.pd.512
+    1, // llvm.x86.avx512.mask.rndscale.ps.512
+    2, // llvm.x86.avx512.mask.storeu.d.512
+    2, // llvm.x86.avx512.mask.storeu.pd.512
+    2, // llvm.x86.avx512.mask.storeu.ps.512
+    2, // llvm.x86.avx512.mask.storeu.q.512
+    1, // llvm.x86.avx512.mask.vcvtph2ps.512
+    1, // llvm.x86.avx512.mask.vcvtps2ph.512
+    1, // llvm.x86.avx512.mask.vpermt.d.512
+    1, // llvm.x86.avx512.mask.vpermt.pd.512
+    1, // llvm.x86.avx512.mask.vpermt.ps.512
+    1, // llvm.x86.avx512.mask.vpermt.q.512
+    3, // llvm.x86.avx512.movntdqa
+    1, // llvm.x86.avx512.pbroadcastd.512
+    1, // llvm.x86.avx512.pbroadcastd.i32.512
+    1, // llvm.x86.avx512.pbroadcastq.512
+    1, // llvm.x86.avx512.pbroadcastq.i64.512
+    1, // llvm.x86.avx512.pmovzxbd
+    1, // llvm.x86.avx512.pmovzxbq
+    1, // llvm.x86.avx512.pmovzxdq
+    1, // llvm.x86.avx512.pmovzxwd
+    1, // llvm.x86.avx512.pmovzxwq
+    1, // llvm.x86.avx512.psll.dq
+    1, // llvm.x86.avx512.psll.dq.bs
+    1, // llvm.x86.avx512.psrl.dq
+    1, // llvm.x86.avx512.psrl.dq.bs
+    1, // llvm.x86.avx512.rcp14.pd.512
+    1, // llvm.x86.avx512.rcp14.ps.512
+    1, // llvm.x86.avx512.rcp14.sd
+    1, // llvm.x86.avx512.rcp14.ss
+    1, // llvm.x86.avx512.rcp28.pd
+    1, // llvm.x86.avx512.rcp28.ps
+    1, // llvm.x86.avx512.rcp28.sd
+    1, // llvm.x86.avx512.rcp28.ss
+    1, // llvm.x86.avx512.rndscale.sd
+    1, // llvm.x86.avx512.rndscale.ss
+    1, // llvm.x86.avx512.rsqrt14.pd.512
+    1, // llvm.x86.avx512.rsqrt14.ps.512
+    1, // llvm.x86.avx512.rsqrt14.sd
+    1, // llvm.x86.avx512.rsqrt14.ss
+    1, // llvm.x86.avx512.rsqrt28.pd
+    1, // llvm.x86.avx512.rsqrt28.ps
+    1, // llvm.x86.avx512.rsqrt28.sd
+    1, // llvm.x86.avx512.rsqrt28.ss
+    2, // llvm.x86.avx512.scatter.dpd.512
+    2, // llvm.x86.avx512.scatter.dpi.512
+    2, // llvm.x86.avx512.scatter.dpq.512
+    2, // llvm.x86.avx512.scatter.dps.512
+    2, // llvm.x86.avx512.scatter.qpd.512
+    2, // llvm.x86.avx512.scatter.qpi.512
+    2, // llvm.x86.avx512.scatter.qpq.512
+    2, // llvm.x86.avx512.scatter.qps.512
+    2, // llvm.x86.avx512.scatterpf.dpd.512
+    2, // llvm.x86.avx512.scatterpf.dps.512
+    2, // llvm.x86.avx512.scatterpf.qpd.512
+    2, // llvm.x86.avx512.scatterpf.qps.512
+    1, // llvm.x86.avx512.sqrt.pd.512
+    1, // llvm.x86.avx512.sqrt.ps.512
+    1, // llvm.x86.avx512.sqrt.sd
+    1, // llvm.x86.avx512.sqrt.ss
+    3, // llvm.x86.avx512.vbroadcast.sd.512
+    1, // llvm.x86.avx512.vbroadcast.sd.pd.512
+    3, // llvm.x86.avx512.vbroadcast.ss.512
+    1, // llvm.x86.avx512.vbroadcast.ss.ps.512
+    1, // llvm.x86.avx.addsub.pd.256
+    1, // llvm.x86.avx.addsub.ps.256
+    1, // llvm.x86.avx.blend.pd.256
+    1, // llvm.x86.avx.blend.ps.256
+    1, // llvm.x86.avx.blendv.pd.256
+    1, // llvm.x86.avx.blendv.ps.256
+    1, // llvm.x86.avx.cmp.pd.256
+    1, // llvm.x86.avx.cmp.ps.256
+    1, // llvm.x86.avx.cvt.pd2.ps.256
+    1, // llvm.x86.avx.cvt.pd2dq.256
+    1, // llvm.x86.avx.cvt.ps2.pd.256
+    1, // llvm.x86.avx.cvt.ps2dq.256
+    1, // llvm.x86.avx.cvtdq2.pd.256
+    1, // llvm.x86.avx.cvtdq2.ps.256
+    1, // llvm.x86.avx.cvtt.pd2dq.256
+    1, // llvm.x86.avx.cvtt.ps2dq.256
+    1, // llvm.x86.avx.dp.ps.256
+    1, // llvm.x86.avx.hadd.pd.256
+    1, // llvm.x86.avx.hadd.ps.256
+    1, // llvm.x86.avx.hsub.pd.256
+    1, // llvm.x86.avx.hsub.ps.256
+    3, // llvm.x86.avx.ldu.dq.256
+    3, // llvm.x86.avx.maskload.pd
+    3, // llvm.x86.avx.maskload.pd.256
+    3, // llvm.x86.avx.maskload.ps
+    3, // llvm.x86.avx.maskload.ps.256
+    2, // llvm.x86.avx.maskstore.pd
+    2, // llvm.x86.avx.maskstore.pd.256
+    2, // llvm.x86.avx.maskstore.ps
+    2, // llvm.x86.avx.maskstore.ps.256
+    1, // llvm.x86.avx.max.pd.256
+    1, // llvm.x86.avx.max.ps.256
+    1, // llvm.x86.avx.min.pd.256
+    1, // llvm.x86.avx.min.ps.256
+    1, // llvm.x86.avx.movmsk.pd.256
+    1, // llvm.x86.avx.movmsk.ps.256
+    1, // llvm.x86.avx.ptestc.256
+    1, // llvm.x86.avx.ptestnzc.256
+    1, // llvm.x86.avx.ptestz.256
+    1, // llvm.x86.avx.rcp.ps.256
+    1, // llvm.x86.avx.round.pd.256
+    1, // llvm.x86.avx.round.ps.256
+    1, // llvm.x86.avx.rsqrt.ps.256
+    1, // llvm.x86.avx.sqrt.pd.256
+    1, // llvm.x86.avx.sqrt.ps.256
+    2, // llvm.x86.avx.storeu.dq.256
+    2, // llvm.x86.avx.storeu.pd.256
+    2, // llvm.x86.avx.storeu.ps.256
+    3, // llvm.x86.avx.vbroadcastf128.pd.256
+    3, // llvm.x86.avx.vbroadcastf128.ps.256
+    1, // llvm.x86.avx.vextractf128.pd.256
+    1, // llvm.x86.avx.vextractf128.ps.256
+    1, // llvm.x86.avx.vextractf128.si.256
+    1, // llvm.x86.avx.vinsertf128.pd.256
+    1, // llvm.x86.avx.vinsertf128.ps.256
+    1, // llvm.x86.avx.vinsertf128.si.256
+    1, // llvm.x86.avx.vperm2f128.pd.256
+    1, // llvm.x86.avx.vperm2f128.ps.256
+    1, // llvm.x86.avx.vperm2f128.si.256
+    1, // llvm.x86.avx.vpermilvar.pd
+    1, // llvm.x86.avx.vpermilvar.pd.256
+    1, // llvm.x86.avx.vpermilvar.ps
+    1, // llvm.x86.avx.vpermilvar.ps.256
+    1, // llvm.x86.avx.vtestc.pd
+    1, // llvm.x86.avx.vtestc.pd.256
+    1, // llvm.x86.avx.vtestc.ps
+    1, // llvm.x86.avx.vtestc.ps.256
+    1, // llvm.x86.avx.vtestnzc.pd
+    1, // llvm.x86.avx.vtestnzc.pd.256
+    1, // llvm.x86.avx.vtestnzc.ps
+    1, // llvm.x86.avx.vtestnzc.ps.256
+    1, // llvm.x86.avx.vtestz.pd
+    1, // llvm.x86.avx.vtestz.pd.256
+    1, // llvm.x86.avx.vtestz.ps
+    1, // llvm.x86.avx.vtestz.ps.256
+    2, // llvm.x86.avx.vzeroall
+    2, // llvm.x86.avx.vzeroupper
+    1, // llvm.x86.bmi.bextr.32
+    1, // llvm.x86.bmi.bextr.64
+    1, // llvm.x86.bmi.bzhi.32
+    1, // llvm.x86.bmi.bzhi.64
+    1, // llvm.x86.bmi.pdep.32
+    1, // llvm.x86.bmi.pdep.64
+    1, // llvm.x86.bmi.pext.32
+    1, // llvm.x86.bmi.pext.64
+    1, // llvm.x86.fma.vfmadd.pd
+    1, // llvm.x86.fma.vfmadd.pd.256
+    1, // llvm.x86.fma.vfmadd.pd.512
+    1, // llvm.x86.fma.vfmadd.ps
+    1, // llvm.x86.fma.vfmadd.ps.256
+    1, // llvm.x86.fma.vfmadd.ps.512
+    1, // llvm.x86.fma.vfmadd.sd
+    1, // llvm.x86.fma.vfmadd.ss
+    1, // llvm.x86.fma.vfmaddsub.pd
+    1, // llvm.x86.fma.vfmaddsub.pd.256
+    1, // llvm.x86.fma.vfmaddsub.pd.512
+    1, // llvm.x86.fma.vfmaddsub.ps
+    1, // llvm.x86.fma.vfmaddsub.ps.256
+    1, // llvm.x86.fma.vfmaddsub.ps.512
+    1, // llvm.x86.fma.vfmsub.pd
+    1, // llvm.x86.fma.vfmsub.pd.256
+    1, // llvm.x86.fma.vfmsub.pd.512
+    1, // llvm.x86.fma.vfmsub.ps
+    1, // llvm.x86.fma.vfmsub.ps.256
+    1, // llvm.x86.fma.vfmsub.ps.512
+    1, // llvm.x86.fma.vfmsub.sd
+    1, // llvm.x86.fma.vfmsub.ss
+    1, // llvm.x86.fma.vfmsubadd.pd
+    1, // llvm.x86.fma.vfmsubadd.pd.256
+    1, // llvm.x86.fma.vfmsubadd.pd.512
+    1, // llvm.x86.fma.vfmsubadd.ps
+    1, // llvm.x86.fma.vfmsubadd.ps.256
+    1, // llvm.x86.fma.vfmsubadd.ps.512
+    1, // llvm.x86.fma.vfnmadd.pd
+    1, // llvm.x86.fma.vfnmadd.pd.256
+    1, // llvm.x86.fma.vfnmadd.pd.512
+    1, // llvm.x86.fma.vfnmadd.ps
+    1, // llvm.x86.fma.vfnmadd.ps.256
+    1, // llvm.x86.fma.vfnmadd.ps.512
+    1, // llvm.x86.fma.vfnmadd.sd
+    1, // llvm.x86.fma.vfnmadd.ss
+    1, // llvm.x86.fma.vfnmsub.pd
+    1, // llvm.x86.fma.vfnmsub.pd.256
+    1, // llvm.x86.fma.vfnmsub.pd.512
+    1, // llvm.x86.fma.vfnmsub.ps
+    1, // llvm.x86.fma.vfnmsub.ps.256
+    1, // llvm.x86.fma.vfnmsub.ps.512
+    1, // llvm.x86.fma.vfnmsub.sd
+    1, // llvm.x86.fma.vfnmsub.ss
+    2, // llvm.x86.int
+    2, // llvm.x86.mmx.emms
+    2, // llvm.x86.mmx.femms
+    2, // llvm.x86.mmx.maskmovq
+    2, // llvm.x86.mmx.movnt.dq
+    1, // llvm.x86.mmx.packssdw
+    1, // llvm.x86.mmx.packsswb
+    1, // llvm.x86.mmx.packuswb
+    1, // llvm.x86.mmx.padd.b
+    1, // llvm.x86.mmx.padd.d
+    1, // llvm.x86.mmx.padd.q
+    1, // llvm.x86.mmx.padd.w
+    1, // llvm.x86.mmx.padds.b
+    1, // llvm.x86.mmx.padds.w
+    1, // llvm.x86.mmx.paddus.b
+    1, // llvm.x86.mmx.paddus.w
+    1, // llvm.x86.mmx.palignr.b
+    1, // llvm.x86.mmx.pand
+    1, // llvm.x86.mmx.pandn
+    1, // llvm.x86.mmx.pavg.b
+    1, // llvm.x86.mmx.pavg.w
+    1, // llvm.x86.mmx.pcmpeq.b
+    1, // llvm.x86.mmx.pcmpeq.d
+    1, // llvm.x86.mmx.pcmpeq.w
+    1, // llvm.x86.mmx.pcmpgt.b
+    1, // llvm.x86.mmx.pcmpgt.d
+    1, // llvm.x86.mmx.pcmpgt.w
+    1, // llvm.x86.mmx.pextr.w
+    1, // llvm.x86.mmx.pinsr.w
+    1, // llvm.x86.mmx.pmadd.wd
+    1, // llvm.x86.mmx.pmaxs.w
+    1, // llvm.x86.mmx.pmaxu.b
+    1, // llvm.x86.mmx.pmins.w
+    1, // llvm.x86.mmx.pminu.b
+    1, // llvm.x86.mmx.pmovmskb
+    1, // llvm.x86.mmx.pmulh.w
+    1, // llvm.x86.mmx.pmulhu.w
+    1, // llvm.x86.mmx.pmull.w
+    1, // llvm.x86.mmx.pmulu.dq
+    1, // llvm.x86.mmx.por
+    1, // llvm.x86.mmx.psad.bw
+    1, // llvm.x86.mmx.psll.d
+    1, // llvm.x86.mmx.psll.q
+    1, // llvm.x86.mmx.psll.w
+    1, // llvm.x86.mmx.pslli.d
+    1, // llvm.x86.mmx.pslli.q
+    1, // llvm.x86.mmx.pslli.w
+    1, // llvm.x86.mmx.psra.d
+    1, // llvm.x86.mmx.psra.w
+    1, // llvm.x86.mmx.psrai.d
+    1, // llvm.x86.mmx.psrai.w
+    1, // llvm.x86.mmx.psrl.d
+    1, // llvm.x86.mmx.psrl.q
+    1, // llvm.x86.mmx.psrl.w
+    1, // llvm.x86.mmx.psrli.d
+    1, // llvm.x86.mmx.psrli.q
+    1, // llvm.x86.mmx.psrli.w
+    1, // llvm.x86.mmx.psub.b
+    1, // llvm.x86.mmx.psub.d
+    1, // llvm.x86.mmx.psub.q
+    1, // llvm.x86.mmx.psub.w
+    1, // llvm.x86.mmx.psubs.b
+    1, // llvm.x86.mmx.psubs.w
+    1, // llvm.x86.mmx.psubus.b
+    1, // llvm.x86.mmx.psubus.w
+    1, // llvm.x86.mmx.punpckhbw
+    1, // llvm.x86.mmx.punpckhdq
+    1, // llvm.x86.mmx.punpckhwd
+    1, // llvm.x86.mmx.punpcklbw
+    1, // llvm.x86.mmx.punpckldq
+    1, // llvm.x86.mmx.punpcklwd
+    1, // llvm.x86.mmx.pxor
+    1, // llvm.x86.pclmulqdq
+    2, // llvm.x86.rdfsbase.32
+    2, // llvm.x86.rdfsbase.64
+    2, // llvm.x86.rdgsbase.32
+    2, // llvm.x86.rdgsbase.64
+    2, // llvm.x86.rdpmc
+    2, // llvm.x86.rdrand.16
+    2, // llvm.x86.rdrand.32
+    2, // llvm.x86.rdrand.64
+    2, // llvm.x86.rdseed.16
+    2, // llvm.x86.rdseed.32
+    2, // llvm.x86.rdseed.64
+    2, // llvm.x86.rdtsc
+    2, // llvm.x86.rdtscp
+    1, // llvm.x86.sha1msg1
+    1, // llvm.x86.sha1msg2
+    1, // llvm.x86.sha1nexte
+    1, // llvm.x86.sha1rnds4
+    1, // llvm.x86.sha256msg1
+    1, // llvm.x86.sha256msg2
+    1, // llvm.x86.sha256rnds2
+    1, // llvm.x86.sse2.add.sd
+    2, // llvm.x86.sse2.clflush
+    1, // llvm.x86.sse2.cmp.pd
+    1, // llvm.x86.sse2.cmp.sd
+    1, // llvm.x86.sse2.comieq.sd
+    1, // llvm.x86.sse2.comige.sd
+    1, // llvm.x86.sse2.comigt.sd
+    1, // llvm.x86.sse2.comile.sd
+    1, // llvm.x86.sse2.comilt.sd
+    1, // llvm.x86.sse2.comineq.sd
+    1, // llvm.x86.sse2.cvtdq2pd
+    1, // llvm.x86.sse2.cvtdq2ps
+    1, // llvm.x86.sse2.cvtpd2dq
+    1, // llvm.x86.sse2.cvtpd2ps
+    1, // llvm.x86.sse2.cvtps2dq
+    1, // llvm.x86.sse2.cvtps2pd
+    1, // llvm.x86.sse2.cvtsd2si
+    1, // llvm.x86.sse2.cvtsd2si64
+    1, // llvm.x86.sse2.cvtsd2ss
+    1, // llvm.x86.sse2.cvtsi2sd
+    1, // llvm.x86.sse2.cvtsi642sd
+    1, // llvm.x86.sse2.cvtss2sd
+    1, // llvm.x86.sse2.cvttpd2dq
+    1, // llvm.x86.sse2.cvttps2dq
+    1, // llvm.x86.sse2.cvttsd2si
+    1, // llvm.x86.sse2.cvttsd2si64
+    1, // llvm.x86.sse2.div.sd
+    2, // llvm.x86.sse2.lfence
+    2, // llvm.x86.sse2.maskmov.dqu
+    1, // llvm.x86.sse2.max.pd
+    1, // llvm.x86.sse2.max.sd
+    2, // llvm.x86.sse2.mfence
+    1, // llvm.x86.sse2.min.pd
+    1, // llvm.x86.sse2.min.sd
+    1, // llvm.x86.sse2.movmsk.pd
+    1, // llvm.x86.sse2.mul.sd
+    1, // llvm.x86.sse2.packssdw.128
+    1, // llvm.x86.sse2.packsswb.128
+    1, // llvm.x86.sse2.packuswb.128
+    1, // llvm.x86.sse2.padds.b
+    1, // llvm.x86.sse2.padds.w
+    1, // llvm.x86.sse2.paddus.b
+    1, // llvm.x86.sse2.paddus.w
+    2, // llvm.x86.sse2.pause
+    1, // llvm.x86.sse2.pavg.b
+    1, // llvm.x86.sse2.pavg.w
+    1, // llvm.x86.sse2.pmadd.wd
+    1, // llvm.x86.sse2.pmaxs.w
+    1, // llvm.x86.sse2.pmaxu.b
+    1, // llvm.x86.sse2.pmins.w
+    1, // llvm.x86.sse2.pminu.b
+    1, // llvm.x86.sse2.pmovmskb.128
+    1, // llvm.x86.sse2.pmulh.w
+    1, // llvm.x86.sse2.pmulhu.w
+    1, // llvm.x86.sse2.pmulu.dq
+    1, // llvm.x86.sse2.psad.bw
+    1, // llvm.x86.sse2.pshuf.d
+    1, // llvm.x86.sse2.pshufh.w
+    1, // llvm.x86.sse2.pshufl.w
+    1, // llvm.x86.sse2.psll.d
+    1, // llvm.x86.sse2.psll.dq
+    1, // llvm.x86.sse2.psll.dq.bs
+    1, // llvm.x86.sse2.psll.q
+    1, // llvm.x86.sse2.psll.w
+    1, // llvm.x86.sse2.pslli.d
+    1, // llvm.x86.sse2.pslli.q
+    1, // llvm.x86.sse2.pslli.w
+    1, // llvm.x86.sse2.psra.d
+    1, // llvm.x86.sse2.psra.w
+    1, // llvm.x86.sse2.psrai.d
+    1, // llvm.x86.sse2.psrai.w
+    1, // llvm.x86.sse2.psrl.d
+    1, // llvm.x86.sse2.psrl.dq
+    1, // llvm.x86.sse2.psrl.dq.bs
+    1, // llvm.x86.sse2.psrl.q
+    1, // llvm.x86.sse2.psrl.w
+    1, // llvm.x86.sse2.psrli.d
+    1, // llvm.x86.sse2.psrli.q
+    1, // llvm.x86.sse2.psrli.w
+    1, // llvm.x86.sse2.psubs.b
+    1, // llvm.x86.sse2.psubs.w
+    1, // llvm.x86.sse2.psubus.b
+    1, // llvm.x86.sse2.psubus.w
+    1, // llvm.x86.sse2.sqrt.pd
+    1, // llvm.x86.sse2.sqrt.sd
+    2, // llvm.x86.sse2.storel.dq
+    2, // llvm.x86.sse2.storeu.dq
+    2, // llvm.x86.sse2.storeu.pd
+    1, // llvm.x86.sse2.sub.sd
+    1, // llvm.x86.sse2.ucomieq.sd
+    1, // llvm.x86.sse2.ucomige.sd
+    1, // llvm.x86.sse2.ucomigt.sd
+    1, // llvm.x86.sse2.ucomile.sd
+    1, // llvm.x86.sse2.ucomilt.sd
+    1, // llvm.x86.sse2.ucomineq.sd
+    1, // llvm.x86.sse3.addsub.pd
+    1, // llvm.x86.sse3.addsub.ps
+    1, // llvm.x86.sse3.hadd.pd
+    1, // llvm.x86.sse3.hadd.ps
+    1, // llvm.x86.sse3.hsub.pd
+    1, // llvm.x86.sse3.hsub.ps
+    3, // llvm.x86.sse3.ldu.dq
+    2, // llvm.x86.sse3.monitor
+    2, // llvm.x86.sse3.mwait
+    1, // llvm.x86.sse41.blendpd
+    1, // llvm.x86.sse41.blendps
+    1, // llvm.x86.sse41.blendvpd
+    1, // llvm.x86.sse41.blendvps
+    1, // llvm.x86.sse41.dppd
+    1, // llvm.x86.sse41.dpps
+    1, // llvm.x86.sse41.extractps
+    1, // llvm.x86.sse41.insertps
+    3, // llvm.x86.sse41.movntdqa
+    1, // llvm.x86.sse41.mpsadbw
+    1, // llvm.x86.sse41.packusdw
+    1, // llvm.x86.sse41.pblendvb
+    1, // llvm.x86.sse41.pblendw
+    1, // llvm.x86.sse41.pextrb
+    1, // llvm.x86.sse41.pextrd
+    1, // llvm.x86.sse41.pextrq
+    1, // llvm.x86.sse41.phminposuw
+    1, // llvm.x86.sse41.pmaxsb
+    1, // llvm.x86.sse41.pmaxsd
+    1, // llvm.x86.sse41.pmaxud
+    1, // llvm.x86.sse41.pmaxuw
+    1, // llvm.x86.sse41.pminsb
+    1, // llvm.x86.sse41.pminsd
+    1, // llvm.x86.sse41.pminud
+    1, // llvm.x86.sse41.pminuw
+    1, // llvm.x86.sse41.pmovsxbd
+    1, // llvm.x86.sse41.pmovsxbq
+    1, // llvm.x86.sse41.pmovsxbw
+    1, // llvm.x86.sse41.pmovsxdq
+    1, // llvm.x86.sse41.pmovsxwd
+    1, // llvm.x86.sse41.pmovsxwq
+    1, // llvm.x86.sse41.pmovzxbd
+    1, // llvm.x86.sse41.pmovzxbq
+    1, // llvm.x86.sse41.pmovzxbw
+    1, // llvm.x86.sse41.pmovzxdq
+    1, // llvm.x86.sse41.pmovzxwd
+    1, // llvm.x86.sse41.pmovzxwq
+    1, // llvm.x86.sse41.pmuldq
+    1, // llvm.x86.sse41.ptestc
+    1, // llvm.x86.sse41.ptestnzc
+    1, // llvm.x86.sse41.ptestz
+    1, // llvm.x86.sse41.round.pd
+    1, // llvm.x86.sse41.round.ps
+    1, // llvm.x86.sse41.round.sd
+    1, // llvm.x86.sse41.round.ss
+    1, // llvm.x86.sse42.crc32.32.16
+    1, // llvm.x86.sse42.crc32.32.32
+    1, // llvm.x86.sse42.crc32.32.8
+    1, // llvm.x86.sse42.crc32.64.64
+    1, // llvm.x86.sse42.pcmpestri128
+    1, // llvm.x86.sse42.pcmpestria128
+    1, // llvm.x86.sse42.pcmpestric128
+    1, // llvm.x86.sse42.pcmpestrio128
+    1, // llvm.x86.sse42.pcmpestris128
+    1, // llvm.x86.sse42.pcmpestriz128
+    1, // llvm.x86.sse42.pcmpestrm128
+    1, // llvm.x86.sse42.pcmpistri128
+    1, // llvm.x86.sse42.pcmpistria128
+    1, // llvm.x86.sse42.pcmpistric128
+    1, // llvm.x86.sse42.pcmpistrio128
+    1, // llvm.x86.sse42.pcmpistris128
+    1, // llvm.x86.sse42.pcmpistriz128
+    1, // llvm.x86.sse42.pcmpistrm128
+    1, // llvm.x86.sse4a.extrq
+    1, // llvm.x86.sse4a.extrqi
+    1, // llvm.x86.sse4a.insertq
+    1, // llvm.x86.sse4a.insertqi
+    2, // llvm.x86.sse4a.movnt.sd
+    2, // llvm.x86.sse4a.movnt.ss
+    1, // llvm.x86.sse.add.ss
+    1, // llvm.x86.sse.cmp.ps
+    1, // llvm.x86.sse.cmp.ss
+    1, // llvm.x86.sse.comieq.ss
+    1, // llvm.x86.sse.comige.ss
+    1, // llvm.x86.sse.comigt.ss
+    1, // llvm.x86.sse.comile.ss
+    1, // llvm.x86.sse.comilt.ss
+    1, // llvm.x86.sse.comineq.ss
+    1, // llvm.x86.sse.cvtpd2pi
+    1, // llvm.x86.sse.cvtpi2pd
+    1, // llvm.x86.sse.cvtpi2ps
+    1, // llvm.x86.sse.cvtps2pi
+    1, // llvm.x86.sse.cvtsi2ss
+    1, // llvm.x86.sse.cvtsi642ss
+    1, // llvm.x86.sse.cvtss2si
+    1, // llvm.x86.sse.cvtss2si64
+    1, // llvm.x86.sse.cvttpd2pi
+    1, // llvm.x86.sse.cvttps2pi
+    1, // llvm.x86.sse.cvttss2si
+    1, // llvm.x86.sse.cvttss2si64
+    1, // llvm.x86.sse.div.ss
+    2, // llvm.x86.sse.ldmxcsr
+    1, // llvm.x86.sse.max.ps
+    1, // llvm.x86.sse.max.ss
+    1, // llvm.x86.sse.min.ps
+    1, // llvm.x86.sse.min.ss
+    1, // llvm.x86.sse.movmsk.ps
+    1, // llvm.x86.sse.mul.ss
+    1, // llvm.x86.sse.pshuf.w
+    1, // llvm.x86.sse.rcp.ps
+    1, // llvm.x86.sse.rcp.ss
+    1, // llvm.x86.sse.rsqrt.ps
+    1, // llvm.x86.sse.rsqrt.ss
+    2, // llvm.x86.sse.sfence
+    1, // llvm.x86.sse.sqrt.ps
+    1, // llvm.x86.sse.sqrt.ss
+    2, // llvm.x86.sse.stmxcsr
+    2, // llvm.x86.sse.storeu.ps
+    1, // llvm.x86.sse.sub.ss
+    1, // llvm.x86.sse.ucomieq.ss
+    1, // llvm.x86.sse.ucomige.ss
+    1, // llvm.x86.sse.ucomigt.ss
+    1, // llvm.x86.sse.ucomile.ss
+    1, // llvm.x86.sse.ucomilt.ss
+    1, // llvm.x86.sse.ucomineq.ss
+    1, // llvm.x86.ssse3.pabs.b
+    1, // llvm.x86.ssse3.pabs.b.128
+    1, // llvm.x86.ssse3.pabs.d
+    1, // llvm.x86.ssse3.pabs.d.128
+    1, // llvm.x86.ssse3.pabs.w
+    1, // llvm.x86.ssse3.pabs.w.128
+    1, // llvm.x86.ssse3.phadd.d
+    1, // llvm.x86.ssse3.phadd.d.128
+    1, // llvm.x86.ssse3.phadd.sw
+    1, // llvm.x86.ssse3.phadd.sw.128
+    1, // llvm.x86.ssse3.phadd.w
+    1, // llvm.x86.ssse3.phadd.w.128
+    1, // llvm.x86.ssse3.phsub.d
+    1, // llvm.x86.ssse3.phsub.d.128
+    1, // llvm.x86.ssse3.phsub.sw
+    1, // llvm.x86.ssse3.phsub.sw.128
+    1, // llvm.x86.ssse3.phsub.w
+    1, // llvm.x86.ssse3.phsub.w.128
+    1, // llvm.x86.ssse3.pmadd.ub.sw
+    1, // llvm.x86.ssse3.pmadd.ub.sw.128
+    1, // llvm.x86.ssse3.pmul.hr.sw
+    1, // llvm.x86.ssse3.pmul.hr.sw.128
+    1, // llvm.x86.ssse3.pshuf.b
+    1, // llvm.x86.ssse3.pshuf.b.128
+    1, // llvm.x86.ssse3.psign.b
+    1, // llvm.x86.ssse3.psign.b.128
+    1, // llvm.x86.ssse3.psign.d
+    1, // llvm.x86.ssse3.psign.d.128
+    1, // llvm.x86.ssse3.psign.w
+    1, // llvm.x86.ssse3.psign.w.128
+    1, // llvm.x86.tbm.bextri.u32
+    1, // llvm.x86.tbm.bextri.u64
+    1, // llvm.x86.vcvtph2ps.128
+    1, // llvm.x86.vcvtph2ps.256
+    1, // llvm.x86.vcvtps2ph.128
+    1, // llvm.x86.vcvtps2ph.256
+    2, // llvm.x86.wrfsbase.32
+    2, // llvm.x86.wrfsbase.64
+    2, // llvm.x86.wrgsbase.32
+    2, // llvm.x86.wrgsbase.64
+    9, // llvm.x86.xabort
+    2, // llvm.x86.xbegin
+    2, // llvm.x86.xend
+    1, // llvm.x86.xop.vfrcz.pd
+    1, // llvm.x86.xop.vfrcz.pd.256
+    1, // llvm.x86.xop.vfrcz.ps
+    1, // llvm.x86.xop.vfrcz.ps.256
+    1, // llvm.x86.xop.vfrcz.sd
+    1, // llvm.x86.xop.vfrcz.ss
+    1, // llvm.x86.xop.vpcmov
+    1, // llvm.x86.xop.vpcmov.256
+    1, // llvm.x86.xop.vpcomb
+    1, // llvm.x86.xop.vpcomd
+    1, // llvm.x86.xop.vpcomq
+    1, // llvm.x86.xop.vpcomub
+    1, // llvm.x86.xop.vpcomud
+    1, // llvm.x86.xop.vpcomuq
+    1, // llvm.x86.xop.vpcomuw
+    1, // llvm.x86.xop.vpcomw
+    1, // llvm.x86.xop.vpermil2pd
+    1, // llvm.x86.xop.vpermil2pd.256
+    1, // llvm.x86.xop.vpermil2ps
+    1, // llvm.x86.xop.vpermil2ps.256
+    1, // llvm.x86.xop.vphaddbd
+    1, // llvm.x86.xop.vphaddbq
+    1, // llvm.x86.xop.vphaddbw
+    1, // llvm.x86.xop.vphadddq
+    1, // llvm.x86.xop.vphaddubd
+    1, // llvm.x86.xop.vphaddubq
+    1, // llvm.x86.xop.vphaddubw
+    1, // llvm.x86.xop.vphaddudq
+    1, // llvm.x86.xop.vphadduwd
+    1, // llvm.x86.xop.vphadduwq
+    1, // llvm.x86.xop.vphaddwd
+    1, // llvm.x86.xop.vphaddwq
+    1, // llvm.x86.xop.vphsubbw
+    1, // llvm.x86.xop.vphsubdq
+    1, // llvm.x86.xop.vphsubwd
+    1, // llvm.x86.xop.vpmacsdd
+    1, // llvm.x86.xop.vpmacsdqh
+    1, // llvm.x86.xop.vpmacsdql
+    1, // llvm.x86.xop.vpmacssdd
+    1, // llvm.x86.xop.vpmacssdqh
+    1, // llvm.x86.xop.vpmacssdql
+    1, // llvm.x86.xop.vpmacsswd
+    1, // llvm.x86.xop.vpmacssww
+    1, // llvm.x86.xop.vpmacswd
+    1, // llvm.x86.xop.vpmacsww
+    1, // llvm.x86.xop.vpmadcsswd
+    1, // llvm.x86.xop.vpmadcswd
+    1, // llvm.x86.xop.vpperm
+    1, // llvm.x86.xop.vprotb
+    1, // llvm.x86.xop.vprotbi
+    1, // llvm.x86.xop.vprotd
+    1, // llvm.x86.xop.vprotdi
+    1, // llvm.x86.xop.vprotq
+    1, // llvm.x86.xop.vprotqi
+    1, // llvm.x86.xop.vprotw
+    1, // llvm.x86.xop.vprotwi
+    1, // llvm.x86.xop.vpshab
+    1, // llvm.x86.xop.vpshad
+    1, // llvm.x86.xop.vpshaq
+    1, // llvm.x86.xop.vpshaw
+    1, // llvm.x86.xop.vpshlb
+    1, // llvm.x86.xop.vpshld
+    1, // llvm.x86.xop.vpshlq
+    1, // llvm.x86.xop.vpshlw
+    2, // llvm.x86.xtest
+    1, // llvm.xcore.bitrev
+    2, // llvm.xcore.checkevent
+    12, // llvm.xcore.chkct
+    2, // llvm.xcore.clre
+    12, // llvm.xcore.clrpt
+    2, // llvm.xcore.clrsr
+    1, // llvm.xcore.crc32
+    1, // llvm.xcore.crc8
+    12, // llvm.xcore.edu
+    12, // llvm.xcore.eeu
+    12, // llvm.xcore.endin
+    12, // llvm.xcore.freer
+    2, // llvm.xcore.geted
+    2, // llvm.xcore.getet
+    1, // llvm.xcore.getid
+    2, // llvm.xcore.getps
+    2, // llvm.xcore.getr
+    12, // llvm.xcore.getst
+    12, // llvm.xcore.getts
+    12, // llvm.xcore.in
+    12, // llvm.xcore.inct
+    12, // llvm.xcore.initcp
+    12, // llvm.xcore.initdp
+    12, // llvm.xcore.initlr
+    12, // llvm.xcore.initpc
+    12, // llvm.xcore.initsp
+    12, // llvm.xcore.inshr
+    12, // llvm.xcore.int
+    12, // llvm.xcore.mjoin
+    12, // llvm.xcore.msync
+    12, // llvm.xcore.out
+    12, // llvm.xcore.outct
+    12, // llvm.xcore.outshr
+    12, // llvm.xcore.outt
+    12, // llvm.xcore.peek
+    12, // llvm.xcore.setc
+    17, // llvm.xcore.setclk
+    12, // llvm.xcore.setd
+    12, // llvm.xcore.setev
+    2, // llvm.xcore.setps
+    12, // llvm.xcore.setpsc
+    12, // llvm.xcore.setpt
+    17, // llvm.xcore.setrdy
+    2, // llvm.xcore.setsr
+    12, // llvm.xcore.settw
+    12, // llvm.xcore.setv
+    1, // llvm.xcore.sext
+    2, // llvm.xcore.ssync
+    12, // llvm.xcore.syncr
+    12, // llvm.xcore.testct
+    12, // llvm.xcore.testwct
+    3, // llvm.xcore.waitevent
+    1, // llvm.xcore.zext
+  };
+
+  AttributeSet AS[4];
+  unsigned NumAttrs = 0;
+  if (id != 0) {
+    switch(IntrinsicsToAttributesMap[id - 1]) {
+    default: llvm_unreachable("Invalid attribute number");
+    case 1: {
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::ReadNone};
+      AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 1;
+      break;
+      }
+    case 16: {
+      const Attribute::AttrKind AttrParam1[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 1, AttrParam1);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::ReadNone};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 3: {
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::ReadOnly};
+      AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 1;
+      break;
+      }
+    case 15: {
+      const Attribute::AttrKind AttrParam1[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 1, AttrParam1);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::ReadOnly};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 2: {
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 1;
+      break;
+      }
+    case 12: {
+      const Attribute::AttrKind AttrParam1[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 1, AttrParam1);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 17: {
+      const Attribute::AttrKind AttrParam1[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 1, AttrParam1);
+      const Attribute::AttrKind AttrParam2[]= {Attribute::NoCapture};
+      AS[1] = AttributeSet::get(C, 2, AttrParam2);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[2] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 3;
+      break;
+      }
+    case 14: {
+      const Attribute::AttrKind AttrParam1[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 1, AttrParam1);
+      const Attribute::AttrKind AttrParam2[]= {Attribute::NoCapture,Attribute::ReadOnly};
+      AS[1] = AttributeSet::get(C, 2, AttrParam2);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[2] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 3;
+      break;
+      }
+    case 13: {
+      const Attribute::AttrKind AttrParam2[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 2, AttrParam2);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 11: {
+      const Attribute::AttrKind AttrParam2[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 2, AttrParam2);
+      const Attribute::AttrKind AttrParam3[]= {Attribute::NoCapture};
+      AS[1] = AttributeSet::get(C, 3, AttrParam3);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[2] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 3;
+      break;
+      }
+    case 4: {
+      const Attribute::AttrKind AttrParam3[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 3, AttrParam3);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 5: {
+      const Attribute::AttrKind AttrParam4[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 4, AttrParam4);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 6: {
+      const Attribute::AttrKind AttrParam5[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 5, AttrParam5);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 7: {
+      const Attribute::AttrKind AttrParam6[]= {Attribute::NoCapture};
+      AS[0] = AttributeSet::get(C, 6, AttrParam6);
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind};
+      AS[1] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 2;
+      break;
+      }
+    case 9: {
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::NoReturn};
+      AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 1;
+      break;
+      }
+    case 8: {
+      const Attribute::AttrKind Atts[] = {Attribute::NoUnwind,Attribute::NoDuplicate};
+      AS[0] = AttributeSet::get(C, AttributeSet::FunctionIndex, Atts);
+      NumAttrs = 1;
+      break;
+      }
+    case 10: {
+      return AttributeSet();
+      }
+    }
+  }
+  return AttributeSet::get(C, ArrayRef<AttributeSet>(AS, NumAttrs));
+}
+#endif // GET_INTRINSIC_ATTRIBUTES
+
+// Determine intrinsic alias analysis mod/ref behavior.
+#ifdef GET_INTRINSIC_MODREF_BEHAVIOR
+assert(iid <= Intrinsic::xcore_zext && "Unknown intrinsic.");
+
+static const uint8_t IntrinsicModRefBehavior[] = {
+  /* invalid */ UnknownModRefBehavior,
+  /* AMDGPU_div_fixup */ DoesNotAccessMemory,
+  /* AMDGPU_div_fmas */ DoesNotAccessMemory,
+  /* AMDGPU_div_scale */ DoesNotAccessMemory,
+  /* AMDGPU_rcp */ DoesNotAccessMemory,
+  /* AMDGPU_rsq */ DoesNotAccessMemory,
+  /* AMDGPU_rsq_clamped */ DoesNotAccessMemory,
+  /* AMDGPU_trig_preop */ DoesNotAccessMemory,
+  /* aarch64_clrex */ UnknownModRefBehavior,
+  /* aarch64_crc32b */ DoesNotAccessMemory,
+  /* aarch64_crc32cb */ DoesNotAccessMemory,
+  /* aarch64_crc32ch */ DoesNotAccessMemory,
+  /* aarch64_crc32cw */ DoesNotAccessMemory,
+  /* aarch64_crc32cx */ DoesNotAccessMemory,
+  /* aarch64_crc32h */ DoesNotAccessMemory,
+  /* aarch64_crc32w */ DoesNotAccessMemory,
+  /* aarch64_crc32x */ DoesNotAccessMemory,
+  /* aarch64_crypto_aesd */ DoesNotAccessMemory,
+  /* aarch64_crypto_aese */ DoesNotAccessMemory,
+  /* aarch64_crypto_aesimc */ DoesNotAccessMemory,
+  /* aarch64_crypto_aesmc */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1c */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1h */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1m */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1p */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1su0 */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha1su1 */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha256h */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha256h2 */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha256su0 */ DoesNotAccessMemory,
+  /* aarch64_crypto_sha256su1 */ DoesNotAccessMemory,
+  /* aarch64_dmb */ UnknownModRefBehavior,
+  /* aarch64_dsb */ UnknownModRefBehavior,
+  /* aarch64_hint */ UnknownModRefBehavior,
+  /* aarch64_isb */ UnknownModRefBehavior,
+  /* aarch64_ldaxp */ UnknownModRefBehavior,
+  /* aarch64_ldaxr */ UnknownModRefBehavior,
+  /* aarch64_ldxp */ UnknownModRefBehavior,
+  /* aarch64_ldxr */ UnknownModRefBehavior,
+  /* aarch64_neon_abs */ DoesNotAccessMemory,
+  /* aarch64_neon_addhn */ DoesNotAccessMemory,
+  /* aarch64_neon_addp */ DoesNotAccessMemory,
+  /* aarch64_neon_cls */ DoesNotAccessMemory,
+  /* aarch64_neon_fabd */ DoesNotAccessMemory,
+  /* aarch64_neon_facge */ DoesNotAccessMemory,
+  /* aarch64_neon_facgt */ DoesNotAccessMemory,
+  /* aarch64_neon_faddv */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtas */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtau */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtms */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtmu */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtns */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtnu */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtps */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtpu */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtxn */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtzs */ DoesNotAccessMemory,
+  /* aarch64_neon_fcvtzu */ DoesNotAccessMemory,
+  /* aarch64_neon_fmax */ DoesNotAccessMemory,
+  /* aarch64_neon_fmaxnm */ DoesNotAccessMemory,
+  /* aarch64_neon_fmaxnmp */ DoesNotAccessMemory,
+  /* aarch64_neon_fmaxnmv */ DoesNotAccessMemory,
+  /* aarch64_neon_fmaxp */ DoesNotAccessMemory,
+  /* aarch64_neon_fmaxv */ DoesNotAccessMemory,
+  /* aarch64_neon_fmin */ DoesNotAccessMemory,
+  /* aarch64_neon_fminnm */ DoesNotAccessMemory,
+  /* aarch64_neon_fminnmp */ DoesNotAccessMemory,
+  /* aarch64_neon_fminnmv */ DoesNotAccessMemory,
+  /* aarch64_neon_fminp */ DoesNotAccessMemory,
+  /* aarch64_neon_fminv */ DoesNotAccessMemory,
+  /* aarch64_neon_fmulx */ DoesNotAccessMemory,
+  /* aarch64_neon_frecpe */ DoesNotAccessMemory,
+  /* aarch64_neon_frecps */ DoesNotAccessMemory,
+  /* aarch64_neon_frecpx */ DoesNotAccessMemory,
+  /* aarch64_neon_frintn */ DoesNotAccessMemory,
+  /* aarch64_neon_frsqrte */ DoesNotAccessMemory,
+  /* aarch64_neon_frsqrts */ DoesNotAccessMemory,
+  /* aarch64_neon_ld1x2 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld1x3 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld1x4 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld2 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld2lane */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld2r */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld3 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld3lane */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld3r */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld4 */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld4lane */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_ld4r */ OnlyReadsArgumentPointees,
+  /* aarch64_neon_pmul */ DoesNotAccessMemory,
+  /* aarch64_neon_pmull */ DoesNotAccessMemory,
+  /* aarch64_neon_pmull64 */ DoesNotAccessMemory,
+  /* aarch64_neon_raddhn */ DoesNotAccessMemory,
+  /* aarch64_neon_rbit */ DoesNotAccessMemory,
+  /* aarch64_neon_rshrn */ DoesNotAccessMemory,
+  /* aarch64_neon_rsubhn */ DoesNotAccessMemory,
+  /* aarch64_neon_sabd */ DoesNotAccessMemory,
+  /* aarch64_neon_saddlp */ DoesNotAccessMemory,
+  /* aarch64_neon_saddlv */ DoesNotAccessMemory,
+  /* aarch64_neon_saddv */ DoesNotAccessMemory,
+  /* aarch64_neon_scalar_sqxtn */ DoesNotAccessMemory,
+  /* aarch64_neon_scalar_sqxtun */ DoesNotAccessMemory,
+  /* aarch64_neon_scalar_uqxtn */ DoesNotAccessMemory,
+  /* aarch64_neon_shadd */ DoesNotAccessMemory,
+  /* aarch64_neon_shll */ DoesNotAccessMemory,
+  /* aarch64_neon_shsub */ DoesNotAccessMemory,
+  /* aarch64_neon_smax */ DoesNotAccessMemory,
+  /* aarch64_neon_smaxp */ DoesNotAccessMemory,
+  /* aarch64_neon_smaxv */ DoesNotAccessMemory,
+  /* aarch64_neon_smin */ DoesNotAccessMemory,
+  /* aarch64_neon_sminp */ DoesNotAccessMemory,
+  /* aarch64_neon_sminv */ DoesNotAccessMemory,
+  /* aarch64_neon_smull */ DoesNotAccessMemory,
+  /* aarch64_neon_sqabs */ DoesNotAccessMemory,
+  /* aarch64_neon_sqadd */ DoesNotAccessMemory,
+  /* aarch64_neon_sqdmulh */ DoesNotAccessMemory,
+  /* aarch64_neon_sqdmull */ DoesNotAccessMemory,
+  /* aarch64_neon_sqdmulls_scalar */ DoesNotAccessMemory,
+  /* aarch64_neon_sqneg */ DoesNotAccessMemory,
+  /* aarch64_neon_sqrdmulh */ DoesNotAccessMemory,
+  /* aarch64_neon_sqrshl */ DoesNotAccessMemory,
+  /* aarch64_neon_sqrshrn */ DoesNotAccessMemory,
+  /* aarch64_neon_sqrshrun */ DoesNotAccessMemory,
+  /* aarch64_neon_sqshl */ DoesNotAccessMemory,
+  /* aarch64_neon_sqshlu */ DoesNotAccessMemory,
+  /* aarch64_neon_sqshrn */ DoesNotAccessMemory,
+  /* aarch64_neon_sqshrun */ DoesNotAccessMemory,
+  /* aarch64_neon_sqsub */ DoesNotAccessMemory,
+  /* aarch64_neon_sqxtn */ DoesNotAccessMemory,
+  /* aarch64_neon_sqxtun */ DoesNotAccessMemory,
+  /* aarch64_neon_srhadd */ DoesNotAccessMemory,
+  /* aarch64_neon_srshl */ DoesNotAccessMemory,
+  /* aarch64_neon_sshl */ DoesNotAccessMemory,
+  /* aarch64_neon_sshll */ DoesNotAccessMemory,
+  /* aarch64_neon_st1x2 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st1x3 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st1x4 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st2 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st2lane */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st3 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st3lane */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st4 */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_st4lane */ OnlyAccessesArgumentPointees,
+  /* aarch64_neon_subhn */ DoesNotAccessMemory,
+  /* aarch64_neon_suqadd */ DoesNotAccessMemory,
+  /* aarch64_neon_tbl1 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbl2 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbl3 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbl4 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbx1 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbx2 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbx3 */ DoesNotAccessMemory,
+  /* aarch64_neon_tbx4 */ DoesNotAccessMemory,
+  /* aarch64_neon_uabd */ DoesNotAccessMemory,
+  /* aarch64_neon_uaddlp */ DoesNotAccessMemory,
+  /* aarch64_neon_uaddlv */ DoesNotAccessMemory,
+  /* aarch64_neon_uaddv */ DoesNotAccessMemory,
+  /* aarch64_neon_uhadd */ DoesNotAccessMemory,
+  /* aarch64_neon_uhsub */ DoesNotAccessMemory,
+  /* aarch64_neon_umax */ DoesNotAccessMemory,
+  /* aarch64_neon_umaxp */ DoesNotAccessMemory,
+  /* aarch64_neon_umaxv */ DoesNotAccessMemory,
+  /* aarch64_neon_umin */ DoesNotAccessMemory,
+  /* aarch64_neon_uminp */ DoesNotAccessMemory,
+  /* aarch64_neon_uminv */ DoesNotAccessMemory,
+  /* aarch64_neon_umull */ DoesNotAccessMemory,
+  /* aarch64_neon_uqadd */ DoesNotAccessMemory,
+  /* aarch64_neon_uqrshl */ DoesNotAccessMemory,
+  /* aarch64_neon_uqrshrn */ DoesNotAccessMemory,
+  /* aarch64_neon_uqshl */ DoesNotAccessMemory,
+  /* aarch64_neon_uqshrn */ DoesNotAccessMemory,
+  /* aarch64_neon_uqsub */ DoesNotAccessMemory,
+  /* aarch64_neon_uqxtn */ DoesNotAccessMemory,
+  /* aarch64_neon_urecpe */ DoesNotAccessMemory,
+  /* aarch64_neon_urhadd */ DoesNotAccessMemory,
+  /* aarch64_neon_urshl */ DoesNotAccessMemory,
+  /* aarch64_neon_ursqrte */ DoesNotAccessMemory,
+  /* aarch64_neon_ushl */ DoesNotAccessMemory,
+  /* aarch64_neon_ushll */ DoesNotAccessMemory,
+  /* aarch64_neon_usqadd */ DoesNotAccessMemory,
+  /* aarch64_neon_vcopy_lane */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvtfp2fxs */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvtfp2fxu */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvtfp2hf */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvtfxs2fp */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvtfxu2fp */ DoesNotAccessMemory,
+  /* aarch64_neon_vcvthf2fp */ DoesNotAccessMemory,
+  /* aarch64_neon_vsli */ DoesNotAccessMemory,
+  /* aarch64_neon_vsri */ DoesNotAccessMemory,
+  /* aarch64_rbit */ DoesNotAccessMemory,
+  /* aarch64_sdiv */ DoesNotAccessMemory,
+  /* aarch64_sisd_fabd */ DoesNotAccessMemory,
+  /* aarch64_sisd_fcvtxn */ DoesNotAccessMemory,
+  /* aarch64_stlxp */ UnknownModRefBehavior,
+  /* aarch64_stlxr */ UnknownModRefBehavior,
+  /* aarch64_stxp */ UnknownModRefBehavior,
+  /* aarch64_stxr */ UnknownModRefBehavior,
+  /* aarch64_udiv */ DoesNotAccessMemory,
+  /* adjust_trampoline */ OnlyReadsArgumentPointees,
+  /* annotation */ UnknownModRefBehavior,
+  /* arm_cdp */ UnknownModRefBehavior,
+  /* arm_cdp2 */ UnknownModRefBehavior,
+  /* arm_clrex */ UnknownModRefBehavior,
+  /* arm_crc32b */ DoesNotAccessMemory,
+  /* arm_crc32cb */ DoesNotAccessMemory,
+  /* arm_crc32ch */ DoesNotAccessMemory,
+  /* arm_crc32cw */ DoesNotAccessMemory,
+  /* arm_crc32h */ DoesNotAccessMemory,
+  /* arm_crc32w */ DoesNotAccessMemory,
+  /* arm_dmb */ UnknownModRefBehavior,
+  /* arm_dsb */ UnknownModRefBehavior,
+  /* arm_get_fpscr */ DoesNotAccessMemory,
+  /* arm_hint */ UnknownModRefBehavior,
+  /* arm_isb */ UnknownModRefBehavior,
+  /* arm_ldaex */ UnknownModRefBehavior,
+  /* arm_ldaexd */ UnknownModRefBehavior,
+  /* arm_ldrex */ UnknownModRefBehavior,
+  /* arm_ldrexd */ UnknownModRefBehavior,
+  /* arm_mcr */ UnknownModRefBehavior,
+  /* arm_mcr2 */ UnknownModRefBehavior,
+  /* arm_mcrr */ UnknownModRefBehavior,
+  /* arm_mcrr2 */ UnknownModRefBehavior,
+  /* arm_mrc */ UnknownModRefBehavior,
+  /* arm_mrc2 */ UnknownModRefBehavior,
+  /* arm_neon_aesd */ DoesNotAccessMemory,
+  /* arm_neon_aese */ DoesNotAccessMemory,
+  /* arm_neon_aesimc */ DoesNotAccessMemory,
+  /* arm_neon_aesmc */ DoesNotAccessMemory,
+  /* arm_neon_sha1c */ DoesNotAccessMemory,
+  /* arm_neon_sha1h */ DoesNotAccessMemory,
+  /* arm_neon_sha1m */ DoesNotAccessMemory,
+  /* arm_neon_sha1p */ DoesNotAccessMemory,
+  /* arm_neon_sha1su0 */ DoesNotAccessMemory,
+  /* arm_neon_sha1su1 */ DoesNotAccessMemory,
+  /* arm_neon_sha256h */ DoesNotAccessMemory,
+  /* arm_neon_sha256h2 */ DoesNotAccessMemory,
+  /* arm_neon_sha256su0 */ DoesNotAccessMemory,
+  /* arm_neon_sha256su1 */ DoesNotAccessMemory,
+  /* arm_neon_vabds */ DoesNotAccessMemory,
+  /* arm_neon_vabdu */ DoesNotAccessMemory,
+  /* arm_neon_vabs */ DoesNotAccessMemory,
+  /* arm_neon_vacge */ DoesNotAccessMemory,
+  /* arm_neon_vacgt */ DoesNotAccessMemory,
+  /* arm_neon_vbsl */ DoesNotAccessMemory,
+  /* arm_neon_vcls */ DoesNotAccessMemory,
+  /* arm_neon_vclz */ DoesNotAccessMemory,
+  /* arm_neon_vcnt */ DoesNotAccessMemory,
+  /* arm_neon_vcvtas */ DoesNotAccessMemory,
+  /* arm_neon_vcvtau */ DoesNotAccessMemory,
+  /* arm_neon_vcvtfp2fxs */ DoesNotAccessMemory,
+  /* arm_neon_vcvtfp2fxu */ DoesNotAccessMemory,
+  /* arm_neon_vcvtfp2hf */ DoesNotAccessMemory,
+  /* arm_neon_vcvtfxs2fp */ DoesNotAccessMemory,
+  /* arm_neon_vcvtfxu2fp */ DoesNotAccessMemory,
+  /* arm_neon_vcvthf2fp */ DoesNotAccessMemory,
+  /* arm_neon_vcvtms */ DoesNotAccessMemory,
+  /* arm_neon_vcvtmu */ DoesNotAccessMemory,
+  /* arm_neon_vcvtns */ DoesNotAccessMemory,
+  /* arm_neon_vcvtnu */ DoesNotAccessMemory,
+  /* arm_neon_vcvtps */ DoesNotAccessMemory,
+  /* arm_neon_vcvtpu */ DoesNotAccessMemory,
+  /* arm_neon_vhadds */ DoesNotAccessMemory,
+  /* arm_neon_vhaddu */ DoesNotAccessMemory,
+  /* arm_neon_vhsubs */ DoesNotAccessMemory,
+  /* arm_neon_vhsubu */ DoesNotAccessMemory,
+  /* arm_neon_vld1 */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld2 */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld2lane */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld3 */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld3lane */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld4 */ OnlyReadsArgumentPointees,
+  /* arm_neon_vld4lane */ OnlyReadsArgumentPointees,
+  /* arm_neon_vmaxnm */ DoesNotAccessMemory,
+  /* arm_neon_vmaxs */ DoesNotAccessMemory,
+  /* arm_neon_vmaxu */ DoesNotAccessMemory,
+  /* arm_neon_vminnm */ DoesNotAccessMemory,
+  /* arm_neon_vmins */ DoesNotAccessMemory,
+  /* arm_neon_vminu */ DoesNotAccessMemory,
+  /* arm_neon_vmullp */ DoesNotAccessMemory,
+  /* arm_neon_vmulls */ DoesNotAccessMemory,
+  /* arm_neon_vmullu */ DoesNotAccessMemory,
+  /* arm_neon_vmulp */ DoesNotAccessMemory,
+  /* arm_neon_vpadals */ DoesNotAccessMemory,
+  /* arm_neon_vpadalu */ DoesNotAccessMemory,
+  /* arm_neon_vpadd */ DoesNotAccessMemory,
+  /* arm_neon_vpaddls */ DoesNotAccessMemory,
+  /* arm_neon_vpaddlu */ DoesNotAccessMemory,
+  /* arm_neon_vpmaxs */ DoesNotAccessMemory,
+  /* arm_neon_vpmaxu */ DoesNotAccessMemory,
+  /* arm_neon_vpmins */ DoesNotAccessMemory,
+  /* arm_neon_vpminu */ DoesNotAccessMemory,
+  /* arm_neon_vqabs */ DoesNotAccessMemory,
+  /* arm_neon_vqadds */ DoesNotAccessMemory,
+  /* arm_neon_vqaddu */ DoesNotAccessMemory,
+  /* arm_neon_vqdmulh */ DoesNotAccessMemory,
+  /* arm_neon_vqdmull */ DoesNotAccessMemory,
+  /* arm_neon_vqmovns */ DoesNotAccessMemory,
+  /* arm_neon_vqmovnsu */ DoesNotAccessMemory,
+  /* arm_neon_vqmovnu */ DoesNotAccessMemory,
+  /* arm_neon_vqneg */ DoesNotAccessMemory,
+  /* arm_neon_vqrdmulh */ DoesNotAccessMemory,
+  /* arm_neon_vqrshiftns */ DoesNotAccessMemory,
+  /* arm_neon_vqrshiftnsu */ DoesNotAccessMemory,
+  /* arm_neon_vqrshiftnu */ DoesNotAccessMemory,
+  /* arm_neon_vqrshifts */ DoesNotAccessMemory,
+  /* arm_neon_vqrshiftu */ DoesNotAccessMemory,
+  /* arm_neon_vqshiftns */ DoesNotAccessMemory,
+  /* arm_neon_vqshiftnsu */ DoesNotAccessMemory,
+  /* arm_neon_vqshiftnu */ DoesNotAccessMemory,
+  /* arm_neon_vqshifts */ DoesNotAccessMemory,
+  /* arm_neon_vqshiftsu */ DoesNotAccessMemory,
+  /* arm_neon_vqshiftu */ DoesNotAccessMemory,
+  /* arm_neon_vqsubs */ DoesNotAccessMemory,
+  /* arm_neon_vqsubu */ DoesNotAccessMemory,
+  /* arm_neon_vraddhn */ DoesNotAccessMemory,
+  /* arm_neon_vrecpe */ DoesNotAccessMemory,
+  /* arm_neon_vrecps */ DoesNotAccessMemory,
+  /* arm_neon_vrhadds */ DoesNotAccessMemory,
+  /* arm_neon_vrhaddu */ DoesNotAccessMemory,
+  /* arm_neon_vrinta */ DoesNotAccessMemory,
+  /* arm_neon_vrintm */ DoesNotAccessMemory,
+  /* arm_neon_vrintn */ DoesNotAccessMemory,
+  /* arm_neon_vrintp */ DoesNotAccessMemory,
+  /* arm_neon_vrintx */ DoesNotAccessMemory,
+  /* arm_neon_vrintz */ DoesNotAccessMemory,
+  /* arm_neon_vrshiftn */ DoesNotAccessMemory,
+  /* arm_neon_vrshifts */ DoesNotAccessMemory,
+  /* arm_neon_vrshiftu */ DoesNotAccessMemory,
+  /* arm_neon_vrsqrte */ DoesNotAccessMemory,
+  /* arm_neon_vrsqrts */ DoesNotAccessMemory,
+  /* arm_neon_vrsubhn */ DoesNotAccessMemory,
+  /* arm_neon_vshiftins */ DoesNotAccessMemory,
+  /* arm_neon_vshifts */ DoesNotAccessMemory,
+  /* arm_neon_vshiftu */ DoesNotAccessMemory,
+  /* arm_neon_vst1 */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst2 */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst2lane */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst3 */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst3lane */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst4 */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vst4lane */ OnlyAccessesArgumentPointees,
+  /* arm_neon_vtbl1 */ DoesNotAccessMemory,
+  /* arm_neon_vtbl2 */ DoesNotAccessMemory,
+  /* arm_neon_vtbl3 */ DoesNotAccessMemory,
+  /* arm_neon_vtbl4 */ DoesNotAccessMemory,
+  /* arm_neon_vtbx1 */ DoesNotAccessMemory,
+  /* arm_neon_vtbx2 */ DoesNotAccessMemory,
+  /* arm_neon_vtbx3 */ DoesNotAccessMemory,
+  /* arm_neon_vtbx4 */ DoesNotAccessMemory,
+  /* arm_qadd */ DoesNotAccessMemory,
+  /* arm_qsub */ DoesNotAccessMemory,
+  /* arm_rbit */ DoesNotAccessMemory,
+  /* arm_set_fpscr */ UnknownModRefBehavior,
+  /* arm_ssat */ DoesNotAccessMemory,
+  /* arm_stlex */ UnknownModRefBehavior,
+  /* arm_stlexd */ UnknownModRefBehavior,
+  /* arm_strex */ UnknownModRefBehavior,
+  /* arm_strexd */ UnknownModRefBehavior,
+  /* arm_thread_pointer */ DoesNotAccessMemory,
+  /* arm_undefined */ UnknownModRefBehavior,
+  /* arm_usat */ DoesNotAccessMemory,
+  /* arm_vcvtr */ DoesNotAccessMemory,
+  /* arm_vcvtru */ DoesNotAccessMemory,
+  /* bswap */ DoesNotAccessMemory,
+  /* ceil */ DoesNotAccessMemory,
+  /* clear_cache */ UnknownModRefBehavior,
+  /* convert_from_fp16 */ DoesNotAccessMemory,
+  /* convert_to_fp16 */ DoesNotAccessMemory,
+  /* convertff */ UnknownModRefBehavior,
+  /* convertfsi */ UnknownModRefBehavior,
+  /* convertfui */ UnknownModRefBehavior,
+  /* convertsif */ UnknownModRefBehavior,
+  /* convertss */ UnknownModRefBehavior,
+  /* convertsu */ UnknownModRefBehavior,
+  /* convertuif */ UnknownModRefBehavior,
+  /* convertus */ UnknownModRefBehavior,
+  /* convertuu */ UnknownModRefBehavior,
+  /* copysign */ DoesNotAccessMemory,
+  /* cos */ DoesNotAccessMemory,
+  /* ctlz */ DoesNotAccessMemory,
+  /* ctpop */ DoesNotAccessMemory,
+  /* cttz */ DoesNotAccessMemory,
+  /* cuda_syncthreads */ UnknownModRefBehavior,
+  /* dbg_declare */ DoesNotAccessMemory,
+  /* dbg_value */ DoesNotAccessMemory,
+  /* debugtrap */ UnknownModRefBehavior,
+  /* donothing */ DoesNotAccessMemory,
+  /* eh_dwarf_cfa */ UnknownModRefBehavior,
+  /* eh_return_i32 */ UnknownModRefBehavior,
+  /* eh_return_i64 */ UnknownModRefBehavior,
+  /* eh_sjlj_callsite */ DoesNotAccessMemory,
+  /* eh_sjlj_functioncontext */ UnknownModRefBehavior,
+  /* eh_sjlj_longjmp */ UnknownModRefBehavior,
+  /* eh_sjlj_lsda */ DoesNotAccessMemory,
+  /* eh_sjlj_setjmp */ UnknownModRefBehavior,
+  /* eh_typeid_for */ DoesNotAccessMemory,
+  /* eh_unwind_init */ UnknownModRefBehavior,
+  /* exp */ DoesNotAccessMemory,
+  /* exp2 */ DoesNotAccessMemory,
+  /* expect */ DoesNotAccessMemory,
+  /* experimental_patchpoint_i64 */ UnknownModRefBehavior,
+  /* experimental_patchpoint_void */ UnknownModRefBehavior,
+  /* experimental_stackmap */ UnknownModRefBehavior,
+  /* fabs */ DoesNotAccessMemory,
+  /* floor */ DoesNotAccessMemory,
+  /* flt_rounds */ UnknownModRefBehavior,
+  /* fma */ DoesNotAccessMemory,
+  /* fmuladd */ DoesNotAccessMemory,
+  /* frameaddress */ DoesNotAccessMemory,
+  /* gcread */ OnlyReadsArgumentPointees,
+  /* gcroot */ UnknownModRefBehavior,
+  /* gcwrite */ OnlyAccessesArgumentPointees,
+  /* hexagon_A2_abs */ DoesNotAccessMemory,
+  /* hexagon_A2_absp */ DoesNotAccessMemory,
+  /* hexagon_A2_abssat */ DoesNotAccessMemory,
+  /* hexagon_A2_add */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_hh */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_lh */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_sat_hh */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_sat_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_sat_lh */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_h16_sat_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_l16_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_l16_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_l16_sat_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_addh_l16_sat_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_addi */ DoesNotAccessMemory,
+  /* hexagon_A2_addp */ DoesNotAccessMemory,
+  /* hexagon_A2_addpsat */ DoesNotAccessMemory,
+  /* hexagon_A2_addsat */ DoesNotAccessMemory,
+  /* hexagon_A2_addsp */ DoesNotAccessMemory,
+  /* hexagon_A2_and */ DoesNotAccessMemory,
+  /* hexagon_A2_andir */ DoesNotAccessMemory,
+  /* hexagon_A2_andp */ DoesNotAccessMemory,
+  /* hexagon_A2_aslh */ DoesNotAccessMemory,
+  /* hexagon_A2_asrh */ DoesNotAccessMemory,
+  /* hexagon_A2_combine_hh */ DoesNotAccessMemory,
+  /* hexagon_A2_combine_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_combine_lh */ DoesNotAccessMemory,
+  /* hexagon_A2_combine_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_combineii */ DoesNotAccessMemory,
+  /* hexagon_A2_combinew */ DoesNotAccessMemory,
+  /* hexagon_A2_max */ DoesNotAccessMemory,
+  /* hexagon_A2_maxp */ DoesNotAccessMemory,
+  /* hexagon_A2_maxu */ DoesNotAccessMemory,
+  /* hexagon_A2_maxup */ DoesNotAccessMemory,
+  /* hexagon_A2_min */ DoesNotAccessMemory,
+  /* hexagon_A2_minp */ DoesNotAccessMemory,
+  /* hexagon_A2_minu */ DoesNotAccessMemory,
+  /* hexagon_A2_minup */ DoesNotAccessMemory,
+  /* hexagon_A2_neg */ DoesNotAccessMemory,
+  /* hexagon_A2_negp */ DoesNotAccessMemory,
+  /* hexagon_A2_negsat */ DoesNotAccessMemory,
+  /* hexagon_A2_not */ DoesNotAccessMemory,
+  /* hexagon_A2_notp */ DoesNotAccessMemory,
+  /* hexagon_A2_or */ DoesNotAccessMemory,
+  /* hexagon_A2_orir */ DoesNotAccessMemory,
+  /* hexagon_A2_orp */ DoesNotAccessMemory,
+  /* hexagon_A2_roundsat */ DoesNotAccessMemory,
+  /* hexagon_A2_sat */ DoesNotAccessMemory,
+  /* hexagon_A2_satb */ DoesNotAccessMemory,
+  /* hexagon_A2_sath */ DoesNotAccessMemory,
+  /* hexagon_A2_satub */ DoesNotAccessMemory,
+  /* hexagon_A2_satuh */ DoesNotAccessMemory,
+  /* hexagon_A2_sub */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_hh */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_lh */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_sat_hh */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_sat_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_sat_lh */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_h16_sat_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_l16_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_l16_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_l16_sat_hl */ DoesNotAccessMemory,
+  /* hexagon_A2_subh_l16_sat_ll */ DoesNotAccessMemory,
+  /* hexagon_A2_subp */ DoesNotAccessMemory,
+  /* hexagon_A2_subri */ DoesNotAccessMemory,
+  /* hexagon_A2_subsat */ DoesNotAccessMemory,
+  /* hexagon_A2_svaddh */ DoesNotAccessMemory,
+  /* hexagon_A2_svaddhs */ DoesNotAccessMemory,
+  /* hexagon_A2_svadduhs */ DoesNotAccessMemory,
+  /* hexagon_A2_svavgh */ DoesNotAccessMemory,
+  /* hexagon_A2_svavghs */ DoesNotAccessMemory,
+  /* hexagon_A2_svnavgh */ DoesNotAccessMemory,
+  /* hexagon_A2_svsubh */ DoesNotAccessMemory,
+  /* hexagon_A2_svsubhs */ DoesNotAccessMemory,
+  /* hexagon_A2_svsubuhs */ DoesNotAccessMemory,
+  /* hexagon_A2_swiz */ DoesNotAccessMemory,
+  /* hexagon_A2_sxtb */ DoesNotAccessMemory,
+  /* hexagon_A2_sxth */ DoesNotAccessMemory,
+  /* hexagon_A2_sxtw */ DoesNotAccessMemory,
+  /* hexagon_A2_tfr */ DoesNotAccessMemory,
+  /* hexagon_A2_tfrih */ DoesNotAccessMemory,
+  /* hexagon_A2_tfril */ DoesNotAccessMemory,
+  /* hexagon_A2_tfrp */ DoesNotAccessMemory,
+  /* hexagon_A2_tfrpi */ DoesNotAccessMemory,
+  /* hexagon_A2_tfrsi */ DoesNotAccessMemory,
+  /* hexagon_A2_vabsh */ DoesNotAccessMemory,
+  /* hexagon_A2_vabshsat */ DoesNotAccessMemory,
+  /* hexagon_A2_vabsw */ DoesNotAccessMemory,
+  /* hexagon_A2_vabswsat */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddb_map */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddh */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddhs */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddub */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddubs */ DoesNotAccessMemory,
+  /* hexagon_A2_vadduhs */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddw */ DoesNotAccessMemory,
+  /* hexagon_A2_vaddws */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgh */ DoesNotAccessMemory,
+  /* hexagon_A2_vavghcr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavghr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgub */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgubr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavguh */ DoesNotAccessMemory,
+  /* hexagon_A2_vavguhr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavguw */ DoesNotAccessMemory,
+  /* hexagon_A2_vavguwr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgw */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgwcr */ DoesNotAccessMemory,
+  /* hexagon_A2_vavgwr */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpbeq */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpbgtu */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpheq */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmphgt */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmphgtu */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpweq */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpwgt */ DoesNotAccessMemory,
+  /* hexagon_A2_vcmpwgtu */ DoesNotAccessMemory,
+  /* hexagon_A2_vconj */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxb */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxh */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxub */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxuh */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxuw */ DoesNotAccessMemory,
+  /* hexagon_A2_vmaxw */ DoesNotAccessMemory,
+  /* hexagon_A2_vminb */ DoesNotAccessMemory,
+  /* hexagon_A2_vminh */ DoesNotAccessMemory,
+  /* hexagon_A2_vminub */ DoesNotAccessMemory,
+  /* hexagon_A2_vminuh */ DoesNotAccessMemory,
+  /* hexagon_A2_vminuw */ DoesNotAccessMemory,
+  /* hexagon_A2_vminw */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavgh */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavghcr */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavghr */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavgw */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavgwcr */ DoesNotAccessMemory,
+  /* hexagon_A2_vnavgwr */ DoesNotAccessMemory,
+  /* hexagon_A2_vraddub */ DoesNotAccessMemory,
+  /* hexagon_A2_vraddub_acc */ DoesNotAccessMemory,
+  /* hexagon_A2_vrsadub */ DoesNotAccessMemory,
+  /* hexagon_A2_vrsadub_acc */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubb_map */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubh */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubhs */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubub */ DoesNotAccessMemory,
+  /* hexagon_A2_vsububs */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubuhs */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubw */ DoesNotAccessMemory,
+  /* hexagon_A2_vsubws */ DoesNotAccessMemory,
+  /* hexagon_A2_xor */ DoesNotAccessMemory,
+  /* hexagon_A2_xorp */ DoesNotAccessMemory,
+  /* hexagon_A2_zxtb */ DoesNotAccessMemory,
+  /* hexagon_A2_zxth */ DoesNotAccessMemory,
+  /* hexagon_A4_andn */ DoesNotAccessMemory,
+  /* hexagon_A4_andnp */ DoesNotAccessMemory,
+  /* hexagon_A4_bitsplit */ DoesNotAccessMemory,
+  /* hexagon_A4_bitspliti */ DoesNotAccessMemory,
+  /* hexagon_A4_boundscheck */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbeq */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbeqi */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbgt */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbgti */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbgtu */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpbgtui */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpheq */ DoesNotAccessMemory,
+  /* hexagon_A4_cmpheqi */ DoesNotAccessMemory,
+  /* hexagon_A4_cmphgt */ DoesNotAccessMemory,
+  /* hexagon_A4_cmphgti */ DoesNotAccessMemory,
+  /* hexagon_A4_cmphgtu */ DoesNotAccessMemory,
+  /* hexagon_A4_cmphgtui */ DoesNotAccessMemory,
+  /* hexagon_A4_combineir */ DoesNotAccessMemory,
+  /* hexagon_A4_combineri */ DoesNotAccessMemory,
+  /* hexagon_A4_cround_ri */ DoesNotAccessMemory,
+  /* hexagon_A4_cround_rr */ DoesNotAccessMemory,
+  /* hexagon_A4_modwrapu */ DoesNotAccessMemory,
+  /* hexagon_A4_orn */ DoesNotAccessMemory,
+  /* hexagon_A4_ornp */ DoesNotAccessMemory,
+  /* hexagon_A4_rcmpeq */ DoesNotAccessMemory,
+  /* hexagon_A4_rcmpeqi */ DoesNotAccessMemory,
+  /* hexagon_A4_rcmpneq */ DoesNotAccessMemory,
+  /* hexagon_A4_rcmpneqi */ DoesNotAccessMemory,
+  /* hexagon_A4_round_ri */ DoesNotAccessMemory,
+  /* hexagon_A4_round_ri_sat */ DoesNotAccessMemory,
+  /* hexagon_A4_round_rr */ DoesNotAccessMemory,
+  /* hexagon_A4_round_rr_sat */ DoesNotAccessMemory,
+  /* hexagon_A4_tlbmatch */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpbeq_any */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpbeqi */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpbgt */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpbgti */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpbgtui */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpheqi */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmphgti */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmphgtui */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpweqi */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpwgti */ DoesNotAccessMemory,
+  /* hexagon_A4_vcmpwgtui */ DoesNotAccessMemory,
+  /* hexagon_A4_vrmaxh */ DoesNotAccessMemory,
+  /* hexagon_A4_vrmaxuh */ DoesNotAccessMemory,
+  /* hexagon_A4_vrmaxuw */ DoesNotAccessMemory,
+  /* hexagon_A4_vrmaxw */ DoesNotAccessMemory,
+  /* hexagon_A4_vrminh */ DoesNotAccessMemory,
+  /* hexagon_A4_vrminuh */ DoesNotAccessMemory,
+  /* hexagon_A4_vrminuw */ DoesNotAccessMemory,
+  /* hexagon_A4_vrminw */ DoesNotAccessMemory,
+  /* hexagon_A5_vaddhubs */ DoesNotAccessMemory,
+  /* hexagon_C2_all8 */ DoesNotAccessMemory,
+  /* hexagon_C2_and */ DoesNotAccessMemory,
+  /* hexagon_C2_andn */ DoesNotAccessMemory,
+  /* hexagon_C2_any8 */ DoesNotAccessMemory,
+  /* hexagon_C2_bitsclr */ DoesNotAccessMemory,
+  /* hexagon_C2_bitsclri */ DoesNotAccessMemory,
+  /* hexagon_C2_bitsset */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpeq */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpeqi */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpeqp */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgei */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgeui */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgt */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgti */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgtp */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgtu */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgtui */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpgtup */ DoesNotAccessMemory,
+  /* hexagon_C2_cmplt */ DoesNotAccessMemory,
+  /* hexagon_C2_cmpltu */ DoesNotAccessMemory,
+  /* hexagon_C2_mask */ DoesNotAccessMemory,
+  /* hexagon_C2_mux */ DoesNotAccessMemory,
+  /* hexagon_C2_muxii */ DoesNotAccessMemory,
+  /* hexagon_C2_muxir */ DoesNotAccessMemory,
+  /* hexagon_C2_muxri */ DoesNotAccessMemory,
+  /* hexagon_C2_not */ DoesNotAccessMemory,
+  /* hexagon_C2_or */ DoesNotAccessMemory,
+  /* hexagon_C2_orn */ DoesNotAccessMemory,
+  /* hexagon_C2_pxfer_map */ DoesNotAccessMemory,
+  /* hexagon_C2_tfrpr */ DoesNotAccessMemory,
+  /* hexagon_C2_tfrrp */ DoesNotAccessMemory,
+  /* hexagon_C2_vitpack */ DoesNotAccessMemory,
+  /* hexagon_C2_vmux */ DoesNotAccessMemory,
+  /* hexagon_C2_xor */ DoesNotAccessMemory,
+  /* hexagon_C4_and_and */ DoesNotAccessMemory,
+  /* hexagon_C4_and_andn */ DoesNotAccessMemory,
+  /* hexagon_C4_and_or */ DoesNotAccessMemory,
+  /* hexagon_C4_and_orn */ DoesNotAccessMemory,
+  /* hexagon_C4_cmplte */ DoesNotAccessMemory,
+  /* hexagon_C4_cmpltei */ DoesNotAccessMemory,
+  /* hexagon_C4_cmplteu */ DoesNotAccessMemory,
+  /* hexagon_C4_cmplteui */ DoesNotAccessMemory,
+  /* hexagon_C4_cmpneq */ DoesNotAccessMemory,
+  /* hexagon_C4_cmpneqi */ DoesNotAccessMemory,
+  /* hexagon_C4_fastcorner9 */ DoesNotAccessMemory,
+  /* hexagon_C4_fastcorner9_not */ DoesNotAccessMemory,
+  /* hexagon_C4_nbitsclr */ DoesNotAccessMemory,
+  /* hexagon_C4_nbitsclri */ DoesNotAccessMemory,
+  /* hexagon_C4_nbitsset */ DoesNotAccessMemory,
+  /* hexagon_C4_or_and */ DoesNotAccessMemory,
+  /* hexagon_C4_or_andn */ DoesNotAccessMemory,
+  /* hexagon_C4_or_or */ DoesNotAccessMemory,
+  /* hexagon_C4_or_orn */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_d2df */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_d2sf */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2d */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2d_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2sf */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2ud */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2ud_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2uw */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2uw_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2w */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_df2w_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2d */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2d_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2df */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2ud */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2ud_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2uw */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2uw_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2w */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_sf2w_chop */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_ud2df */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_ud2sf */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_uw2df */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_uw2sf */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_w2df */ DoesNotAccessMemory,
+  /* hexagon_F2_conv_w2sf */ DoesNotAccessMemory,
+  /* hexagon_F2_dfadd */ DoesNotAccessMemory,
+  /* hexagon_F2_dfclass */ DoesNotAccessMemory,
+  /* hexagon_F2_dfcmpeq */ DoesNotAccessMemory,
+  /* hexagon_F2_dfcmpge */ DoesNotAccessMemory,
+  /* hexagon_F2_dfcmpgt */ DoesNotAccessMemory,
+  /* hexagon_F2_dfcmpuo */ DoesNotAccessMemory,
+  /* hexagon_F2_dffixupd */ DoesNotAccessMemory,
+  /* hexagon_F2_dffixupn */ DoesNotAccessMemory,
+  /* hexagon_F2_dffixupr */ DoesNotAccessMemory,
+  /* hexagon_F2_dffma */ DoesNotAccessMemory,
+  /* hexagon_F2_dffma_lib */ DoesNotAccessMemory,
+  /* hexagon_F2_dffma_sc */ DoesNotAccessMemory,
+  /* hexagon_F2_dffms */ DoesNotAccessMemory,
+  /* hexagon_F2_dffms_lib */ DoesNotAccessMemory,
+  /* hexagon_F2_dfimm_n */ DoesNotAccessMemory,
+  /* hexagon_F2_dfimm_p */ DoesNotAccessMemory,
+  /* hexagon_F2_dfmax */ DoesNotAccessMemory,
+  /* hexagon_F2_dfmin */ DoesNotAccessMemory,
+  /* hexagon_F2_dfmpy */ DoesNotAccessMemory,
+  /* hexagon_F2_dfsub */ DoesNotAccessMemory,
+  /* hexagon_F2_sfadd */ DoesNotAccessMemory,
+  /* hexagon_F2_sfclass */ DoesNotAccessMemory,
+  /* hexagon_F2_sfcmpeq */ DoesNotAccessMemory,
+  /* hexagon_F2_sfcmpge */ DoesNotAccessMemory,
+  /* hexagon_F2_sfcmpgt */ DoesNotAccessMemory,
+  /* hexagon_F2_sfcmpuo */ DoesNotAccessMemory,
+  /* hexagon_F2_sffixupd */ DoesNotAccessMemory,
+  /* hexagon_F2_sffixupn */ DoesNotAccessMemory,
+  /* hexagon_F2_sffixupr */ DoesNotAccessMemory,
+  /* hexagon_F2_sffma */ DoesNotAccessMemory,
+  /* hexagon_F2_sffma_lib */ DoesNotAccessMemory,
+  /* hexagon_F2_sffma_sc */ DoesNotAccessMemory,
+  /* hexagon_F2_sffms */ DoesNotAccessMemory,
+  /* hexagon_F2_sffms_lib */ DoesNotAccessMemory,
+  /* hexagon_F2_sfimm_n */ DoesNotAccessMemory,
+  /* hexagon_F2_sfimm_p */ DoesNotAccessMemory,
+  /* hexagon_F2_sfmax */ DoesNotAccessMemory,
+  /* hexagon_F2_sfmin */ DoesNotAccessMemory,
+  /* hexagon_F2_sfmpy */ DoesNotAccessMemory,
+  /* hexagon_F2_sfsub */ DoesNotAccessMemory,
+  /* hexagon_M2_acci */ DoesNotAccessMemory,
+  /* hexagon_M2_accii */ DoesNotAccessMemory,
+  /* hexagon_M2_cmaci_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmacr_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmacs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmacs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmacsc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmacsc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyi_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyr_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyrs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyrs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyrsc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpyrsc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpys_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpys_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpysc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cmpysc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cnacs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cnacs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_cnacsc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_cnacsc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyss_acc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyss_nac_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyss_rnd_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyss_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyuu_acc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyuu_nac_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_dpmpyuu_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_hmmpyh_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_hmmpyh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_hmmpyl_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_hmmpyl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_maci */ DoesNotAccessMemory,
+  /* hexagon_M2_macsin */ DoesNotAccessMemory,
+  /* hexagon_M2_macsip */ DoesNotAccessMemory,
+  /* hexagon_M2_mmachs_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmachs_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmachs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmachs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacls_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacls_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacls_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacls_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacuhs_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacuhs_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacuhs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmacuhs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmaculs_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmaculs_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmaculs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmaculs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyh_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyh_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyl_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyl_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyuh_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyuh_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyuh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyuh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyul_rs0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyul_rs1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyul_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mmpyul_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_acc_sat_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_nac_sat_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_rnd_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_sat_rnd_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_up */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_up_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpy_up_s1_sat */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_acc_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_nac_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyd_rnd_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyi */ DoesNotAccessMemory,
+  /* hexagon_M2_mpysmi */ DoesNotAccessMemory,
+  /* hexagon_M2_mpysu_up */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_acc_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_nac_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyu_up */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_acc_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_hh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_hh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_hl_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_hl_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_lh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_lh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_ll_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyud_nac_ll_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_mpyui */ DoesNotAccessMemory,
+  /* hexagon_M2_nacci */ DoesNotAccessMemory,
+  /* hexagon_M2_naccii */ DoesNotAccessMemory,
+  /* hexagon_M2_subacc */ DoesNotAccessMemory,
+  /* hexagon_M2_vabsdiffh */ DoesNotAccessMemory,
+  /* hexagon_M2_vabsdiffw */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmac_s0_sat_i */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmac_s0_sat_r */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmpy_s0_sat_i */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmpy_s0_sat_r */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmpy_s1_sat_i */ DoesNotAccessMemory,
+  /* hexagon_M2_vcmpy_s1_sat_r */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmacs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmacs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmpyrs_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmpyrs_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmpys_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vdmpys_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2es */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2es_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2es_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2s_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2s_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2su_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmac2su_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2es_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2es_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2s_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2s_s0pack */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2s_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2s_s1pack */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2su_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vmpy2su_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vraddh */ DoesNotAccessMemory,
+  /* hexagon_M2_vradduh */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmaci_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmaci_s0c */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmacr_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmacr_s0c */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpyi_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpyi_s0c */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpyr_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpyr_s0c */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpys_acc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpys_s1 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrcmpys_s1rp */ DoesNotAccessMemory,
+  /* hexagon_M2_vrmac_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_vrmpy_s0 */ DoesNotAccessMemory,
+  /* hexagon_M2_xor_xacc */ DoesNotAccessMemory,
+  /* hexagon_M4_and_and */ DoesNotAccessMemory,
+  /* hexagon_M4_and_andn */ DoesNotAccessMemory,
+  /* hexagon_M4_and_or */ DoesNotAccessMemory,
+  /* hexagon_M4_and_xor */ DoesNotAccessMemory,
+  /* hexagon_M4_cmpyi_wh */ DoesNotAccessMemory,
+  /* hexagon_M4_cmpyi_whc */ DoesNotAccessMemory,
+  /* hexagon_M4_cmpyr_wh */ DoesNotAccessMemory,
+  /* hexagon_M4_cmpyr_whc */ DoesNotAccessMemory,
+  /* hexagon_M4_mac_up_s1_sat */ DoesNotAccessMemory,
+  /* hexagon_M4_mpyri_addi */ DoesNotAccessMemory,
+  /* hexagon_M4_mpyri_addr */ DoesNotAccessMemory,
+  /* hexagon_M4_mpyri_addr_u2 */ DoesNotAccessMemory,
+  /* hexagon_M4_mpyrr_addi */ DoesNotAccessMemory,
+  /* hexagon_M4_mpyrr_addr */ DoesNotAccessMemory,
+  /* hexagon_M4_nac_up_s1_sat */ DoesNotAccessMemory,
+  /* hexagon_M4_or_and */ DoesNotAccessMemory,
+  /* hexagon_M4_or_andn */ DoesNotAccessMemory,
+  /* hexagon_M4_or_or */ DoesNotAccessMemory,
+  /* hexagon_M4_or_xor */ DoesNotAccessMemory,
+  /* hexagon_M4_pmpyw */ DoesNotAccessMemory,
+  /* hexagon_M4_pmpyw_acc */ DoesNotAccessMemory,
+  /* hexagon_M4_vpmpyh */ DoesNotAccessMemory,
+  /* hexagon_M4_vpmpyh_acc */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyeh_acc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyeh_acc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyeh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyeh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyoh_acc_s0 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyoh_acc_s1 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyoh_s0 */ DoesNotAccessMemory,
+  /* hexagon_M4_vrmpyoh_s1 */ DoesNotAccessMemory,
+  /* hexagon_M4_xor_and */ DoesNotAccessMemory,
+  /* hexagon_M4_xor_andn */ DoesNotAccessMemory,
+  /* hexagon_M4_xor_or */ DoesNotAccessMemory,
+  /* hexagon_M4_xor_xacc */ DoesNotAccessMemory,
+  /* hexagon_M5_vdmacbsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vdmpybsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vmacbsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vmacbuu */ DoesNotAccessMemory,
+  /* hexagon_M5_vmpybsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vmpybuu */ DoesNotAccessMemory,
+  /* hexagon_M5_vrmacbsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vrmacbuu */ DoesNotAccessMemory,
+  /* hexagon_M5_vrmpybsu */ DoesNotAccessMemory,
+  /* hexagon_M5_vrmpybuu */ DoesNotAccessMemory,
+  /* hexagon_S2_addasl_rrri */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_p_xacc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_sat */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_r_xacc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_i_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_p_xor */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_r_sat */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_asl_r_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_rnd */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_p_rnd_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_rnd */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_r_rnd_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_svw_trun */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_i_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_p_xor */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_r_sat */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_svw_trun */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_asr_r_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_brev */ DoesNotAccessMemory,
+  /* hexagon_S2_brevp */ DoesNotAccessMemory,
+  /* hexagon_S2_cl0 */ DoesNotAccessMemory,
+  /* hexagon_S2_cl0p */ DoesNotAccessMemory,
+  /* hexagon_S2_cl1 */ DoesNotAccessMemory,
+  /* hexagon_S2_cl1p */ DoesNotAccessMemory,
+  /* hexagon_S2_clb */ DoesNotAccessMemory,
+  /* hexagon_S2_clbnorm */ DoesNotAccessMemory,
+  /* hexagon_S2_clbp */ DoesNotAccessMemory,
+  /* hexagon_S2_clrbit_i */ DoesNotAccessMemory,
+  /* hexagon_S2_clrbit_r */ DoesNotAccessMemory,
+  /* hexagon_S2_ct0 */ DoesNotAccessMemory,
+  /* hexagon_S2_ct0p */ DoesNotAccessMemory,
+  /* hexagon_S2_ct1 */ DoesNotAccessMemory,
+  /* hexagon_S2_ct1p */ DoesNotAccessMemory,
+  /* hexagon_S2_deinterleave */ DoesNotAccessMemory,
+  /* hexagon_S2_extractu */ DoesNotAccessMemory,
+  /* hexagon_S2_extractu_rp */ DoesNotAccessMemory,
+  /* hexagon_S2_extractup */ DoesNotAccessMemory,
+  /* hexagon_S2_extractup_rp */ DoesNotAccessMemory,
+  /* hexagon_S2_insert */ DoesNotAccessMemory,
+  /* hexagon_S2_insert_rp */ DoesNotAccessMemory,
+  /* hexagon_S2_insertp */ DoesNotAccessMemory,
+  /* hexagon_S2_insertp_rp */ DoesNotAccessMemory,
+  /* hexagon_S2_interleave */ DoesNotAccessMemory,
+  /* hexagon_S2_lfsp */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_p_xor */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_r */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_lsl_r_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_p_xacc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_r_xacc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_i_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_p_xor */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_r */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_r_acc */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_r_and */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_r_nac */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_r_or */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_vh */ DoesNotAccessMemory,
+  /* hexagon_S2_lsr_r_vw */ DoesNotAccessMemory,
+  /* hexagon_S2_packhl */ DoesNotAccessMemory,
+  /* hexagon_S2_parityp */ DoesNotAccessMemory,
+  /* hexagon_S2_setbit_i */ DoesNotAccessMemory,
+  /* hexagon_S2_setbit_r */ DoesNotAccessMemory,
+  /* hexagon_S2_shuffeb */ DoesNotAccessMemory,
+  /* hexagon_S2_shuffeh */ DoesNotAccessMemory,
+  /* hexagon_S2_shuffob */ DoesNotAccessMemory,
+  /* hexagon_S2_shuffoh */ DoesNotAccessMemory,
+  /* hexagon_S2_svsathb */ DoesNotAccessMemory,
+  /* hexagon_S2_svsathub */ DoesNotAccessMemory,
+  /* hexagon_S2_tableidxb_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_tableidxd_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_tableidxh_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_tableidxw_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S2_togglebit_i */ DoesNotAccessMemory,
+  /* hexagon_S2_togglebit_r */ DoesNotAccessMemory,
+  /* hexagon_S2_tstbit_i */ DoesNotAccessMemory,
+  /* hexagon_S2_tstbit_r */ DoesNotAccessMemory,
+  /* hexagon_S2_valignib */ DoesNotAccessMemory,
+  /* hexagon_S2_valignrb */ DoesNotAccessMemory,
+  /* hexagon_S2_vcnegh */ DoesNotAccessMemory,
+  /* hexagon_S2_vcrotate */ DoesNotAccessMemory,
+  /* hexagon_S2_vrcnegh */ DoesNotAccessMemory,
+  /* hexagon_S2_vrndpackwh */ DoesNotAccessMemory,
+  /* hexagon_S2_vrndpackwhs */ DoesNotAccessMemory,
+  /* hexagon_S2_vsathb */ DoesNotAccessMemory,
+  /* hexagon_S2_vsathb_nopack */ DoesNotAccessMemory,
+  /* hexagon_S2_vsathub */ DoesNotAccessMemory,
+  /* hexagon_S2_vsathub_nopack */ DoesNotAccessMemory,
+  /* hexagon_S2_vsatwh */ DoesNotAccessMemory,
+  /* hexagon_S2_vsatwh_nopack */ DoesNotAccessMemory,
+  /* hexagon_S2_vsatwuh */ DoesNotAccessMemory,
+  /* hexagon_S2_vsatwuh_nopack */ DoesNotAccessMemory,
+  /* hexagon_S2_vsplatrb */ DoesNotAccessMemory,
+  /* hexagon_S2_vsplatrh */ DoesNotAccessMemory,
+  /* hexagon_S2_vspliceib */ DoesNotAccessMemory,
+  /* hexagon_S2_vsplicerb */ DoesNotAccessMemory,
+  /* hexagon_S2_vsxtbh */ DoesNotAccessMemory,
+  /* hexagon_S2_vsxthw */ DoesNotAccessMemory,
+  /* hexagon_S2_vtrunehb */ DoesNotAccessMemory,
+  /* hexagon_S2_vtrunewh */ DoesNotAccessMemory,
+  /* hexagon_S2_vtrunohb */ DoesNotAccessMemory,
+  /* hexagon_S2_vtrunowh */ DoesNotAccessMemory,
+  /* hexagon_S2_vzxtbh */ DoesNotAccessMemory,
+  /* hexagon_S2_vzxthw */ DoesNotAccessMemory,
+  /* hexagon_S4_addaddi */ DoesNotAccessMemory,
+  /* hexagon_S4_addi_asl_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_addi_lsr_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_andi_asl_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_andi_lsr_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_clbaddi */ DoesNotAccessMemory,
+  /* hexagon_S4_clbpaddi */ DoesNotAccessMemory,
+  /* hexagon_S4_clbpnorm */ DoesNotAccessMemory,
+  /* hexagon_S4_extract */ DoesNotAccessMemory,
+  /* hexagon_S4_extract_rp */ DoesNotAccessMemory,
+  /* hexagon_S4_extractp */ DoesNotAccessMemory,
+  /* hexagon_S4_extractp_rp */ DoesNotAccessMemory,
+  /* hexagon_S4_lsli */ DoesNotAccessMemory,
+  /* hexagon_S4_ntstbit_i */ DoesNotAccessMemory,
+  /* hexagon_S4_ntstbit_r */ DoesNotAccessMemory,
+  /* hexagon_S4_or_andi */ DoesNotAccessMemory,
+  /* hexagon_S4_or_andix */ DoesNotAccessMemory,
+  /* hexagon_S4_or_ori */ DoesNotAccessMemory,
+  /* hexagon_S4_ori_asl_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_ori_lsr_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_parity */ DoesNotAccessMemory,
+  /* hexagon_S4_subaddi */ DoesNotAccessMemory,
+  /* hexagon_S4_subi_asl_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_subi_lsr_ri */ DoesNotAccessMemory,
+  /* hexagon_S4_vrcrotate */ DoesNotAccessMemory,
+  /* hexagon_S4_vrcrotate_acc */ DoesNotAccessMemory,
+  /* hexagon_S4_vxaddsubh */ DoesNotAccessMemory,
+  /* hexagon_S4_vxaddsubhr */ DoesNotAccessMemory,
+  /* hexagon_S4_vxaddsubw */ DoesNotAccessMemory,
+  /* hexagon_S4_vxsubaddh */ DoesNotAccessMemory,
+  /* hexagon_S4_vxsubaddhr */ DoesNotAccessMemory,
+  /* hexagon_S4_vxsubaddw */ DoesNotAccessMemory,
+  /* hexagon_S5_asrhub_rnd_sat_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_S5_asrhub_sat */ DoesNotAccessMemory,
+  /* hexagon_S5_popcountp */ DoesNotAccessMemory,
+  /* hexagon_S5_vasrhrnd_goodsyntax */ DoesNotAccessMemory,
+  /* hexagon_SI_to_SXTHI_asrh */ DoesNotAccessMemory,
+  /* hexagon_circ_ldd */ OnlyAccessesArgumentPointees,
+  /* init_trampoline */ OnlyAccessesArgumentPointees,
+  /* invariant_end */ OnlyAccessesArgumentPointees,
+  /* invariant_start */ OnlyAccessesArgumentPointees,
+  /* lifetime_end */ OnlyAccessesArgumentPointees,
+  /* lifetime_start */ OnlyAccessesArgumentPointees,
+  /* log */ DoesNotAccessMemory,
+  /* log10 */ DoesNotAccessMemory,
+  /* log2 */ DoesNotAccessMemory,
+  /* longjmp */ UnknownModRefBehavior,
+  /* memcpy */ OnlyAccessesArgumentPointees,
+  /* memmove */ OnlyAccessesArgumentPointees,
+  /* memset */ OnlyAccessesArgumentPointees,
+  /* mips_absq_s_ph */ UnknownModRefBehavior,
+  /* mips_absq_s_qb */ UnknownModRefBehavior,
+  /* mips_absq_s_w */ UnknownModRefBehavior,
+  /* mips_add_a_b */ DoesNotAccessMemory,
+  /* mips_add_a_d */ DoesNotAccessMemory,
+  /* mips_add_a_h */ DoesNotAccessMemory,
+  /* mips_add_a_w */ DoesNotAccessMemory,
+  /* mips_addq_ph */ DoesNotAccessMemory,
+  /* mips_addq_s_ph */ DoesNotAccessMemory,
+  /* mips_addq_s_w */ UnknownModRefBehavior,
+  /* mips_addqh_ph */ DoesNotAccessMemory,
+  /* mips_addqh_r_ph */ DoesNotAccessMemory,
+  /* mips_addqh_r_w */ DoesNotAccessMemory,
+  /* mips_addqh_w */ DoesNotAccessMemory,
+  /* mips_adds_a_b */ DoesNotAccessMemory,
+  /* mips_adds_a_d */ DoesNotAccessMemory,
+  /* mips_adds_a_h */ DoesNotAccessMemory,
+  /* mips_adds_a_w */ DoesNotAccessMemory,
+  /* mips_adds_s_b */ DoesNotAccessMemory,
+  /* mips_adds_s_d */ DoesNotAccessMemory,
+  /* mips_adds_s_h */ DoesNotAccessMemory,
+  /* mips_adds_s_w */ DoesNotAccessMemory,
+  /* mips_adds_u_b */ DoesNotAccessMemory,
+  /* mips_adds_u_d */ DoesNotAccessMemory,
+  /* mips_adds_u_h */ DoesNotAccessMemory,
+  /* mips_adds_u_w */ DoesNotAccessMemory,
+  /* mips_addsc */ UnknownModRefBehavior,
+  /* mips_addu_ph */ UnknownModRefBehavior,
+  /* mips_addu_qb */ DoesNotAccessMemory,
+  /* mips_addu_s_ph */ UnknownModRefBehavior,
+  /* mips_addu_s_qb */ DoesNotAccessMemory,
+  /* mips_adduh_qb */ DoesNotAccessMemory,
+  /* mips_adduh_r_qb */ DoesNotAccessMemory,
+  /* mips_addv_b */ DoesNotAccessMemory,
+  /* mips_addv_d */ DoesNotAccessMemory,
+  /* mips_addv_h */ DoesNotAccessMemory,
+  /* mips_addv_w */ DoesNotAccessMemory,
+  /* mips_addvi_b */ DoesNotAccessMemory,
+  /* mips_addvi_d */ DoesNotAccessMemory,
+  /* mips_addvi_h */ DoesNotAccessMemory,
+  /* mips_addvi_w */ DoesNotAccessMemory,
+  /* mips_addwc */ UnknownModRefBehavior,
+  /* mips_and_v */ DoesNotAccessMemory,
+  /* mips_andi_b */ DoesNotAccessMemory,
+  /* mips_append */ DoesNotAccessMemory,
+  /* mips_asub_s_b */ DoesNotAccessMemory,
+  /* mips_asub_s_d */ DoesNotAccessMemory,
+  /* mips_asub_s_h */ DoesNotAccessMemory,
+  /* mips_asub_s_w */ DoesNotAccessMemory,
+  /* mips_asub_u_b */ DoesNotAccessMemory,
+  /* mips_asub_u_d */ DoesNotAccessMemory,
+  /* mips_asub_u_h */ DoesNotAccessMemory,
+  /* mips_asub_u_w */ DoesNotAccessMemory,
+  /* mips_ave_s_b */ DoesNotAccessMemory,
+  /* mips_ave_s_d */ DoesNotAccessMemory,
+  /* mips_ave_s_h */ DoesNotAccessMemory,
+  /* mips_ave_s_w */ DoesNotAccessMemory,
+  /* mips_ave_u_b */ DoesNotAccessMemory,
+  /* mips_ave_u_d */ DoesNotAccessMemory,
+  /* mips_ave_u_h */ DoesNotAccessMemory,
+  /* mips_ave_u_w */ DoesNotAccessMemory,
+  /* mips_aver_s_b */ DoesNotAccessMemory,
+  /* mips_aver_s_d */ DoesNotAccessMemory,
+  /* mips_aver_s_h */ DoesNotAccessMemory,
+  /* mips_aver_s_w */ DoesNotAccessMemory,
+  /* mips_aver_u_b */ DoesNotAccessMemory,
+  /* mips_aver_u_d */ DoesNotAccessMemory,
+  /* mips_aver_u_h */ DoesNotAccessMemory,
+  /* mips_aver_u_w */ DoesNotAccessMemory,
+  /* mips_balign */ DoesNotAccessMemory,
+  /* mips_bclr_b */ DoesNotAccessMemory,
+  /* mips_bclr_d */ DoesNotAccessMemory,
+  /* mips_bclr_h */ DoesNotAccessMemory,
+  /* mips_bclr_w */ DoesNotAccessMemory,
+  /* mips_bclri_b */ DoesNotAccessMemory,
+  /* mips_bclri_d */ DoesNotAccessMemory,
+  /* mips_bclri_h */ DoesNotAccessMemory,
+  /* mips_bclri_w */ DoesNotAccessMemory,
+  /* mips_binsl_b */ DoesNotAccessMemory,
+  /* mips_binsl_d */ DoesNotAccessMemory,
+  /* mips_binsl_h */ DoesNotAccessMemory,
+  /* mips_binsl_w */ DoesNotAccessMemory,
+  /* mips_binsli_b */ DoesNotAccessMemory,
+  /* mips_binsli_d */ DoesNotAccessMemory,
+  /* mips_binsli_h */ DoesNotAccessMemory,
+  /* mips_binsli_w */ DoesNotAccessMemory,
+  /* mips_binsr_b */ DoesNotAccessMemory,
+  /* mips_binsr_d */ DoesNotAccessMemory,
+  /* mips_binsr_h */ DoesNotAccessMemory,
+  /* mips_binsr_w */ DoesNotAccessMemory,
+  /* mips_binsri_b */ DoesNotAccessMemory,
+  /* mips_binsri_d */ DoesNotAccessMemory,
+  /* mips_binsri_h */ DoesNotAccessMemory,
+  /* mips_binsri_w */ DoesNotAccessMemory,
+  /* mips_bitrev */ DoesNotAccessMemory,
+  /* mips_bmnz_v */ DoesNotAccessMemory,
+  /* mips_bmnzi_b */ DoesNotAccessMemory,
+  /* mips_bmz_v */ DoesNotAccessMemory,
+  /* mips_bmzi_b */ DoesNotAccessMemory,
+  /* mips_bneg_b */ DoesNotAccessMemory,
+  /* mips_bneg_d */ DoesNotAccessMemory,
+  /* mips_bneg_h */ DoesNotAccessMemory,
+  /* mips_bneg_w */ DoesNotAccessMemory,
+  /* mips_bnegi_b */ DoesNotAccessMemory,
+  /* mips_bnegi_d */ DoesNotAccessMemory,
+  /* mips_bnegi_h */ DoesNotAccessMemory,
+  /* mips_bnegi_w */ DoesNotAccessMemory,
+  /* mips_bnz_b */ DoesNotAccessMemory,
+  /* mips_bnz_d */ DoesNotAccessMemory,
+  /* mips_bnz_h */ DoesNotAccessMemory,
+  /* mips_bnz_v */ DoesNotAccessMemory,
+  /* mips_bnz_w */ DoesNotAccessMemory,
+  /* mips_bposge32 */ OnlyReadsMemory,
+  /* mips_bsel_v */ DoesNotAccessMemory,
+  /* mips_bseli_b */ DoesNotAccessMemory,
+  /* mips_bset_b */ DoesNotAccessMemory,
+  /* mips_bset_d */ DoesNotAccessMemory,
+  /* mips_bset_h */ DoesNotAccessMemory,
+  /* mips_bset_w */ DoesNotAccessMemory,
+  /* mips_bseti_b */ DoesNotAccessMemory,
+  /* mips_bseti_d */ DoesNotAccessMemory,
+  /* mips_bseti_h */ DoesNotAccessMemory,
+  /* mips_bseti_w */ DoesNotAccessMemory,
+  /* mips_bz_b */ DoesNotAccessMemory,
+  /* mips_bz_d */ DoesNotAccessMemory,
+  /* mips_bz_h */ DoesNotAccessMemory,
+  /* mips_bz_v */ DoesNotAccessMemory,
+  /* mips_bz_w */ DoesNotAccessMemory,
+  /* mips_ceq_b */ DoesNotAccessMemory,
+  /* mips_ceq_d */ DoesNotAccessMemory,
+  /* mips_ceq_h */ DoesNotAccessMemory,
+  /* mips_ceq_w */ DoesNotAccessMemory,
+  /* mips_ceqi_b */ DoesNotAccessMemory,
+  /* mips_ceqi_d */ DoesNotAccessMemory,
+  /* mips_ceqi_h */ DoesNotAccessMemory,
+  /* mips_ceqi_w */ DoesNotAccessMemory,
+  /* mips_cfcmsa */ UnknownModRefBehavior,
+  /* mips_cle_s_b */ DoesNotAccessMemory,
+  /* mips_cle_s_d */ DoesNotAccessMemory,
+  /* mips_cle_s_h */ DoesNotAccessMemory,
+  /* mips_cle_s_w */ DoesNotAccessMemory,
+  /* mips_cle_u_b */ DoesNotAccessMemory,
+  /* mips_cle_u_d */ DoesNotAccessMemory,
+  /* mips_cle_u_h */ DoesNotAccessMemory,
+  /* mips_cle_u_w */ DoesNotAccessMemory,
+  /* mips_clei_s_b */ DoesNotAccessMemory,
+  /* mips_clei_s_d */ DoesNotAccessMemory,
+  /* mips_clei_s_h */ DoesNotAccessMemory,
+  /* mips_clei_s_w */ DoesNotAccessMemory,
+  /* mips_clei_u_b */ DoesNotAccessMemory,
+  /* mips_clei_u_d */ DoesNotAccessMemory,
+  /* mips_clei_u_h */ DoesNotAccessMemory,
+  /* mips_clei_u_w */ DoesNotAccessMemory,
+  /* mips_clt_s_b */ DoesNotAccessMemory,
+  /* mips_clt_s_d */ DoesNotAccessMemory,
+  /* mips_clt_s_h */ DoesNotAccessMemory,
+  /* mips_clt_s_w */ DoesNotAccessMemory,
+  /* mips_clt_u_b */ DoesNotAccessMemory,
+  /* mips_clt_u_d */ DoesNotAccessMemory,
+  /* mips_clt_u_h */ DoesNotAccessMemory,
+  /* mips_clt_u_w */ DoesNotAccessMemory,
+  /* mips_clti_s_b */ DoesNotAccessMemory,
+  /* mips_clti_s_d */ DoesNotAccessMemory,
+  /* mips_clti_s_h */ DoesNotAccessMemory,
+  /* mips_clti_s_w */ DoesNotAccessMemory,
+  /* mips_clti_u_b */ DoesNotAccessMemory,
+  /* mips_clti_u_d */ DoesNotAccessMemory,
+  /* mips_clti_u_h */ DoesNotAccessMemory,
+  /* mips_clti_u_w */ DoesNotAccessMemory,
+  /* mips_cmp_eq_ph */ UnknownModRefBehavior,
+  /* mips_cmp_le_ph */ UnknownModRefBehavior,
+  /* mips_cmp_lt_ph */ UnknownModRefBehavior,
+  /* mips_cmpgdu_eq_qb */ UnknownModRefBehavior,
+  /* mips_cmpgdu_le_qb */ UnknownModRefBehavior,
+  /* mips_cmpgdu_lt_qb */ UnknownModRefBehavior,
+  /* mips_cmpgu_eq_qb */ UnknownModRefBehavior,
+  /* mips_cmpgu_le_qb */ UnknownModRefBehavior,
+  /* mips_cmpgu_lt_qb */ UnknownModRefBehavior,
+  /* mips_cmpu_eq_qb */ UnknownModRefBehavior,
+  /* mips_cmpu_le_qb */ UnknownModRefBehavior,
+  /* mips_cmpu_lt_qb */ UnknownModRefBehavior,
+  /* mips_copy_s_b */ DoesNotAccessMemory,
+  /* mips_copy_s_d */ DoesNotAccessMemory,
+  /* mips_copy_s_h */ DoesNotAccessMemory,
+  /* mips_copy_s_w */ DoesNotAccessMemory,
+  /* mips_copy_u_b */ DoesNotAccessMemory,
+  /* mips_copy_u_d */ DoesNotAccessMemory,
+  /* mips_copy_u_h */ DoesNotAccessMemory,
+  /* mips_copy_u_w */ DoesNotAccessMemory,
+  /* mips_ctcmsa */ UnknownModRefBehavior,
+  /* mips_div_s_b */ DoesNotAccessMemory,
+  /* mips_div_s_d */ DoesNotAccessMemory,
+  /* mips_div_s_h */ DoesNotAccessMemory,
+  /* mips_div_s_w */ DoesNotAccessMemory,
+  /* mips_div_u_b */ DoesNotAccessMemory,
+  /* mips_div_u_d */ DoesNotAccessMemory,
+  /* mips_div_u_h */ DoesNotAccessMemory,
+  /* mips_div_u_w */ DoesNotAccessMemory,
+  /* mips_dlsa */ DoesNotAccessMemory,
+  /* mips_dotp_s_d */ DoesNotAccessMemory,
+  /* mips_dotp_s_h */ DoesNotAccessMemory,
+  /* mips_dotp_s_w */ DoesNotAccessMemory,
+  /* mips_dotp_u_d */ DoesNotAccessMemory,
+  /* mips_dotp_u_h */ DoesNotAccessMemory,
+  /* mips_dotp_u_w */ DoesNotAccessMemory,
+  /* mips_dpa_w_ph */ DoesNotAccessMemory,
+  /* mips_dpadd_s_d */ DoesNotAccessMemory,
+  /* mips_dpadd_s_h */ DoesNotAccessMemory,
+  /* mips_dpadd_s_w */ DoesNotAccessMemory,
+  /* mips_dpadd_u_d */ DoesNotAccessMemory,
+  /* mips_dpadd_u_h */ DoesNotAccessMemory,
+  /* mips_dpadd_u_w */ DoesNotAccessMemory,
+  /* mips_dpaq_s_w_ph */ UnknownModRefBehavior,
+  /* mips_dpaq_sa_l_w */ UnknownModRefBehavior,
+  /* mips_dpaqx_s_w_ph */ UnknownModRefBehavior,
+  /* mips_dpaqx_sa_w_ph */ UnknownModRefBehavior,
+  /* mips_dpau_h_qbl */ DoesNotAccessMemory,
+  /* mips_dpau_h_qbr */ DoesNotAccessMemory,
+  /* mips_dpax_w_ph */ DoesNotAccessMemory,
+  /* mips_dps_w_ph */ DoesNotAccessMemory,
+  /* mips_dpsq_s_w_ph */ UnknownModRefBehavior,
+  /* mips_dpsq_sa_l_w */ UnknownModRefBehavior,
+  /* mips_dpsqx_s_w_ph */ UnknownModRefBehavior,
+  /* mips_dpsqx_sa_w_ph */ UnknownModRefBehavior,
+  /* mips_dpsu_h_qbl */ DoesNotAccessMemory,
+  /* mips_dpsu_h_qbr */ DoesNotAccessMemory,
+  /* mips_dpsub_s_d */ DoesNotAccessMemory,
+  /* mips_dpsub_s_h */ DoesNotAccessMemory,
+  /* mips_dpsub_s_w */ DoesNotAccessMemory,
+  /* mips_dpsub_u_d */ DoesNotAccessMemory,
+  /* mips_dpsub_u_h */ DoesNotAccessMemory,
+  /* mips_dpsub_u_w */ DoesNotAccessMemory,
+  /* mips_dpsx_w_ph */ DoesNotAccessMemory,
+  /* mips_extp */ UnknownModRefBehavior,
+  /* mips_extpdp */ UnknownModRefBehavior,
+  /* mips_extr_r_w */ UnknownModRefBehavior,
+  /* mips_extr_rs_w */ UnknownModRefBehavior,
+  /* mips_extr_s_h */ UnknownModRefBehavior,
+  /* mips_extr_w */ UnknownModRefBehavior,
+  /* mips_fadd_d */ DoesNotAccessMemory,
+  /* mips_fadd_w */ DoesNotAccessMemory,
+  /* mips_fcaf_d */ DoesNotAccessMemory,
+  /* mips_fcaf_w */ DoesNotAccessMemory,
+  /* mips_fceq_d */ DoesNotAccessMemory,
+  /* mips_fceq_w */ DoesNotAccessMemory,
+  /* mips_fclass_d */ DoesNotAccessMemory,
+  /* mips_fclass_w */ DoesNotAccessMemory,
+  /* mips_fcle_d */ DoesNotAccessMemory,
+  /* mips_fcle_w */ DoesNotAccessMemory,
+  /* mips_fclt_d */ DoesNotAccessMemory,
+  /* mips_fclt_w */ DoesNotAccessMemory,
+  /* mips_fcne_d */ DoesNotAccessMemory,
+  /* mips_fcne_w */ DoesNotAccessMemory,
+  /* mips_fcor_d */ DoesNotAccessMemory,
+  /* mips_fcor_w */ DoesNotAccessMemory,
+  /* mips_fcueq_d */ DoesNotAccessMemory,
+  /* mips_fcueq_w */ DoesNotAccessMemory,
+  /* mips_fcule_d */ DoesNotAccessMemory,
+  /* mips_fcule_w */ DoesNotAccessMemory,
+  /* mips_fcult_d */ DoesNotAccessMemory,
+  /* mips_fcult_w */ DoesNotAccessMemory,
+  /* mips_fcun_d */ DoesNotAccessMemory,
+  /* mips_fcun_w */ DoesNotAccessMemory,
+  /* mips_fcune_d */ DoesNotAccessMemory,
+  /* mips_fcune_w */ DoesNotAccessMemory,
+  /* mips_fdiv_d */ DoesNotAccessMemory,
+  /* mips_fdiv_w */ DoesNotAccessMemory,
+  /* mips_fexdo_h */ DoesNotAccessMemory,
+  /* mips_fexdo_w */ DoesNotAccessMemory,
+  /* mips_fexp2_d */ DoesNotAccessMemory,
+  /* mips_fexp2_w */ DoesNotAccessMemory,
+  /* mips_fexupl_d */ DoesNotAccessMemory,
+  /* mips_fexupl_w */ DoesNotAccessMemory,
+  /* mips_fexupr_d */ DoesNotAccessMemory,
+  /* mips_fexupr_w */ DoesNotAccessMemory,
+  /* mips_ffint_s_d */ DoesNotAccessMemory,
+  /* mips_ffint_s_w */ DoesNotAccessMemory,
+  /* mips_ffint_u_d */ DoesNotAccessMemory,
+  /* mips_ffint_u_w */ DoesNotAccessMemory,
+  /* mips_ffql_d */ DoesNotAccessMemory,
+  /* mips_ffql_w */ DoesNotAccessMemory,
+  /* mips_ffqr_d */ DoesNotAccessMemory,
+  /* mips_ffqr_w */ DoesNotAccessMemory,
+  /* mips_fill_b */ DoesNotAccessMemory,
+  /* mips_fill_d */ DoesNotAccessMemory,
+  /* mips_fill_h */ DoesNotAccessMemory,
+  /* mips_fill_w */ DoesNotAccessMemory,
+  /* mips_flog2_d */ DoesNotAccessMemory,
+  /* mips_flog2_w */ DoesNotAccessMemory,
+  /* mips_fmadd_d */ DoesNotAccessMemory,
+  /* mips_fmadd_w */ DoesNotAccessMemory,
+  /* mips_fmax_a_d */ DoesNotAccessMemory,
+  /* mips_fmax_a_w */ DoesNotAccessMemory,
+  /* mips_fmax_d */ DoesNotAccessMemory,
+  /* mips_fmax_w */ DoesNotAccessMemory,
+  /* mips_fmin_a_d */ DoesNotAccessMemory,
+  /* mips_fmin_a_w */ DoesNotAccessMemory,
+  /* mips_fmin_d */ DoesNotAccessMemory,
+  /* mips_fmin_w */ DoesNotAccessMemory,
+  /* mips_fmsub_d */ DoesNotAccessMemory,
+  /* mips_fmsub_w */ DoesNotAccessMemory,
+  /* mips_fmul_d */ DoesNotAccessMemory,
+  /* mips_fmul_w */ DoesNotAccessMemory,
+  /* mips_frcp_d */ DoesNotAccessMemory,
+  /* mips_frcp_w */ DoesNotAccessMemory,
+  /* mips_frint_d */ DoesNotAccessMemory,
+  /* mips_frint_w */ DoesNotAccessMemory,
+  /* mips_frsqrt_d */ DoesNotAccessMemory,
+  /* mips_frsqrt_w */ DoesNotAccessMemory,
+  /* mips_fsaf_d */ DoesNotAccessMemory,
+  /* mips_fsaf_w */ DoesNotAccessMemory,
+  /* mips_fseq_d */ DoesNotAccessMemory,
+  /* mips_fseq_w */ DoesNotAccessMemory,
+  /* mips_fsle_d */ DoesNotAccessMemory,
+  /* mips_fsle_w */ DoesNotAccessMemory,
+  /* mips_fslt_d */ DoesNotAccessMemory,
+  /* mips_fslt_w */ DoesNotAccessMemory,
+  /* mips_fsne_d */ DoesNotAccessMemory,
+  /* mips_fsne_w */ DoesNotAccessMemory,
+  /* mips_fsor_d */ DoesNotAccessMemory,
+  /* mips_fsor_w */ DoesNotAccessMemory,
+  /* mips_fsqrt_d */ DoesNotAccessMemory,
+  /* mips_fsqrt_w */ DoesNotAccessMemory,
+  /* mips_fsub_d */ DoesNotAccessMemory,
+  /* mips_fsub_w */ DoesNotAccessMemory,
+  /* mips_fsueq_d */ DoesNotAccessMemory,
+  /* mips_fsueq_w */ DoesNotAccessMemory,
+  /* mips_fsule_d */ DoesNotAccessMemory,
+  /* mips_fsule_w */ DoesNotAccessMemory,
+  /* mips_fsult_d */ DoesNotAccessMemory,
+  /* mips_fsult_w */ DoesNotAccessMemory,
+  /* mips_fsun_d */ DoesNotAccessMemory,
+  /* mips_fsun_w */ DoesNotAccessMemory,
+  /* mips_fsune_d */ DoesNotAccessMemory,
+  /* mips_fsune_w */ DoesNotAccessMemory,
+  /* mips_ftint_s_d */ DoesNotAccessMemory,
+  /* mips_ftint_s_w */ DoesNotAccessMemory,
+  /* mips_ftint_u_d */ DoesNotAccessMemory,
+  /* mips_ftint_u_w */ DoesNotAccessMemory,
+  /* mips_ftq_h */ DoesNotAccessMemory,
+  /* mips_ftq_w */ DoesNotAccessMemory,
+  /* mips_ftrunc_s_d */ DoesNotAccessMemory,
+  /* mips_ftrunc_s_w */ DoesNotAccessMemory,
+  /* mips_ftrunc_u_d */ DoesNotAccessMemory,
+  /* mips_ftrunc_u_w */ DoesNotAccessMemory,
+  /* mips_hadd_s_d */ DoesNotAccessMemory,
+  /* mips_hadd_s_h */ DoesNotAccessMemory,
+  /* mips_hadd_s_w */ DoesNotAccessMemory,
+  /* mips_hadd_u_d */ DoesNotAccessMemory,
+  /* mips_hadd_u_h */ DoesNotAccessMemory,
+  /* mips_hadd_u_w */ DoesNotAccessMemory,
+  /* mips_hsub_s_d */ DoesNotAccessMemory,
+  /* mips_hsub_s_h */ DoesNotAccessMemory,
+  /* mips_hsub_s_w */ DoesNotAccessMemory,
+  /* mips_hsub_u_d */ DoesNotAccessMemory,
+  /* mips_hsub_u_h */ DoesNotAccessMemory,
+  /* mips_hsub_u_w */ DoesNotAccessMemory,
+  /* mips_ilvev_b */ DoesNotAccessMemory,
+  /* mips_ilvev_d */ DoesNotAccessMemory,
+  /* mips_ilvev_h */ DoesNotAccessMemory,
+  /* mips_ilvev_w */ DoesNotAccessMemory,
+  /* mips_ilvl_b */ DoesNotAccessMemory,
+  /* mips_ilvl_d */ DoesNotAccessMemory,
+  /* mips_ilvl_h */ DoesNotAccessMemory,
+  /* mips_ilvl_w */ DoesNotAccessMemory,
+  /* mips_ilvod_b */ DoesNotAccessMemory,
+  /* mips_ilvod_d */ DoesNotAccessMemory,
+  /* mips_ilvod_h */ DoesNotAccessMemory,
+  /* mips_ilvod_w */ DoesNotAccessMemory,
+  /* mips_ilvr_b */ DoesNotAccessMemory,
+  /* mips_ilvr_d */ DoesNotAccessMemory,
+  /* mips_ilvr_h */ DoesNotAccessMemory,
+  /* mips_ilvr_w */ DoesNotAccessMemory,
+  /* mips_insert_b */ DoesNotAccessMemory,
+  /* mips_insert_d */ DoesNotAccessMemory,
+  /* mips_insert_h */ DoesNotAccessMemory,
+  /* mips_insert_w */ DoesNotAccessMemory,
+  /* mips_insv */ OnlyReadsMemory,
+  /* mips_insve_b */ DoesNotAccessMemory,
+  /* mips_insve_d */ DoesNotAccessMemory,
+  /* mips_insve_h */ DoesNotAccessMemory,
+  /* mips_insve_w */ DoesNotAccessMemory,
+  /* mips_lbux */ OnlyReadsArgumentPointees,
+  /* mips_ld_b */ OnlyReadsArgumentPointees,
+  /* mips_ld_d */ OnlyReadsArgumentPointees,
+  /* mips_ld_h */ OnlyReadsArgumentPointees,
+  /* mips_ld_w */ OnlyReadsArgumentPointees,
+  /* mips_ldi_b */ DoesNotAccessMemory,
+  /* mips_ldi_d */ DoesNotAccessMemory,
+  /* mips_ldi_h */ DoesNotAccessMemory,
+  /* mips_ldi_w */ DoesNotAccessMemory,
+  /* mips_lhx */ OnlyReadsArgumentPointees,
+  /* mips_lsa */ DoesNotAccessMemory,
+  /* mips_lwx */ OnlyReadsArgumentPointees,
+  /* mips_madd */ DoesNotAccessMemory,
+  /* mips_madd_q_h */ DoesNotAccessMemory,
+  /* mips_madd_q_w */ DoesNotAccessMemory,
+  /* mips_maddr_q_h */ DoesNotAccessMemory,
+  /* mips_maddr_q_w */ DoesNotAccessMemory,
+  /* mips_maddu */ DoesNotAccessMemory,
+  /* mips_maddv_b */ DoesNotAccessMemory,
+  /* mips_maddv_d */ DoesNotAccessMemory,
+  /* mips_maddv_h */ DoesNotAccessMemory,
+  /* mips_maddv_w */ DoesNotAccessMemory,
+  /* mips_maq_s_w_phl */ UnknownModRefBehavior,
+  /* mips_maq_s_w_phr */ UnknownModRefBehavior,
+  /* mips_maq_sa_w_phl */ UnknownModRefBehavior,
+  /* mips_maq_sa_w_phr */ UnknownModRefBehavior,
+  /* mips_max_a_b */ DoesNotAccessMemory,
+  /* mips_max_a_d */ DoesNotAccessMemory,
+  /* mips_max_a_h */ DoesNotAccessMemory,
+  /* mips_max_a_w */ DoesNotAccessMemory,
+  /* mips_max_s_b */ DoesNotAccessMemory,
+  /* mips_max_s_d */ DoesNotAccessMemory,
+  /* mips_max_s_h */ DoesNotAccessMemory,
+  /* mips_max_s_w */ DoesNotAccessMemory,
+  /* mips_max_u_b */ DoesNotAccessMemory,
+  /* mips_max_u_d */ DoesNotAccessMemory,
+  /* mips_max_u_h */ DoesNotAccessMemory,
+  /* mips_max_u_w */ DoesNotAccessMemory,
+  /* mips_maxi_s_b */ DoesNotAccessMemory,
+  /* mips_maxi_s_d */ DoesNotAccessMemory,
+  /* mips_maxi_s_h */ DoesNotAccessMemory,
+  /* mips_maxi_s_w */ DoesNotAccessMemory,
+  /* mips_maxi_u_b */ DoesNotAccessMemory,
+  /* mips_maxi_u_d */ DoesNotAccessMemory,
+  /* mips_maxi_u_h */ DoesNotAccessMemory,
+  /* mips_maxi_u_w */ DoesNotAccessMemory,
+  /* mips_min_a_b */ DoesNotAccessMemory,
+  /* mips_min_a_d */ DoesNotAccessMemory,
+  /* mips_min_a_h */ DoesNotAccessMemory,
+  /* mips_min_a_w */ DoesNotAccessMemory,
+  /* mips_min_s_b */ DoesNotAccessMemory,
+  /* mips_min_s_d */ DoesNotAccessMemory,
+  /* mips_min_s_h */ DoesNotAccessMemory,
+  /* mips_min_s_w */ DoesNotAccessMemory,
+  /* mips_min_u_b */ DoesNotAccessMemory,
+  /* mips_min_u_d */ DoesNotAccessMemory,
+  /* mips_min_u_h */ DoesNotAccessMemory,
+  /* mips_min_u_w */ DoesNotAccessMemory,
+  /* mips_mini_s_b */ DoesNotAccessMemory,
+  /* mips_mini_s_d */ DoesNotAccessMemory,
+  /* mips_mini_s_h */ DoesNotAccessMemory,
+  /* mips_mini_s_w */ DoesNotAccessMemory,
+  /* mips_mini_u_b */ DoesNotAccessMemory,
+  /* mips_mini_u_d */ DoesNotAccessMemory,
+  /* mips_mini_u_h */ DoesNotAccessMemory,
+  /* mips_mini_u_w */ DoesNotAccessMemory,
+  /* mips_mod_s_b */ DoesNotAccessMemory,
+  /* mips_mod_s_d */ DoesNotAccessMemory,
+  /* mips_mod_s_h */ DoesNotAccessMemory,
+  /* mips_mod_s_w */ DoesNotAccessMemory,
+  /* mips_mod_u_b */ DoesNotAccessMemory,
+  /* mips_mod_u_d */ DoesNotAccessMemory,
+  /* mips_mod_u_h */ DoesNotAccessMemory,
+  /* mips_mod_u_w */ DoesNotAccessMemory,
+  /* mips_modsub */ DoesNotAccessMemory,
+  /* mips_move_v */ DoesNotAccessMemory,
+  /* mips_msub */ DoesNotAccessMemory,
+  /* mips_msub_q_h */ DoesNotAccessMemory,
+  /* mips_msub_q_w */ DoesNotAccessMemory,
+  /* mips_msubr_q_h */ DoesNotAccessMemory,
+  /* mips_msubr_q_w */ DoesNotAccessMemory,
+  /* mips_msubu */ DoesNotAccessMemory,
+  /* mips_msubv_b */ DoesNotAccessMemory,
+  /* mips_msubv_d */ DoesNotAccessMemory,
+  /* mips_msubv_h */ DoesNotAccessMemory,
+  /* mips_msubv_w */ DoesNotAccessMemory,
+  /* mips_mthlip */ UnknownModRefBehavior,
+  /* mips_mul_ph */ UnknownModRefBehavior,
+  /* mips_mul_q_h */ DoesNotAccessMemory,
+  /* mips_mul_q_w */ DoesNotAccessMemory,
+  /* mips_mul_s_ph */ UnknownModRefBehavior,
+  /* mips_muleq_s_w_phl */ UnknownModRefBehavior,
+  /* mips_muleq_s_w_phr */ UnknownModRefBehavior,
+  /* mips_muleu_s_ph_qbl */ UnknownModRefBehavior,
+  /* mips_muleu_s_ph_qbr */ UnknownModRefBehavior,
+  /* mips_mulq_rs_ph */ UnknownModRefBehavior,
+  /* mips_mulq_rs_w */ UnknownModRefBehavior,
+  /* mips_mulq_s_ph */ UnknownModRefBehavior,
+  /* mips_mulq_s_w */ UnknownModRefBehavior,
+  /* mips_mulr_q_h */ DoesNotAccessMemory,
+  /* mips_mulr_q_w */ DoesNotAccessMemory,
+  /* mips_mulsa_w_ph */ DoesNotAccessMemory,
+  /* mips_mulsaq_s_w_ph */ UnknownModRefBehavior,
+  /* mips_mult */ DoesNotAccessMemory,
+  /* mips_multu */ DoesNotAccessMemory,
+  /* mips_mulv_b */ DoesNotAccessMemory,
+  /* mips_mulv_d */ DoesNotAccessMemory,
+  /* mips_mulv_h */ DoesNotAccessMemory,
+  /* mips_mulv_w */ DoesNotAccessMemory,
+  /* mips_nloc_b */ DoesNotAccessMemory,
+  /* mips_nloc_d */ DoesNotAccessMemory,
+  /* mips_nloc_h */ DoesNotAccessMemory,
+  /* mips_nloc_w */ DoesNotAccessMemory,
+  /* mips_nlzc_b */ DoesNotAccessMemory,
+  /* mips_nlzc_d */ DoesNotAccessMemory,
+  /* mips_nlzc_h */ DoesNotAccessMemory,
+  /* mips_nlzc_w */ DoesNotAccessMemory,
+  /* mips_nor_v */ DoesNotAccessMemory,
+  /* mips_nori_b */ DoesNotAccessMemory,
+  /* mips_or_v */ DoesNotAccessMemory,
+  /* mips_ori_b */ DoesNotAccessMemory,
+  /* mips_packrl_ph */ DoesNotAccessMemory,
+  /* mips_pckev_b */ DoesNotAccessMemory,
+  /* mips_pckev_d */ DoesNotAccessMemory,
+  /* mips_pckev_h */ DoesNotAccessMemory,
+  /* mips_pckev_w */ DoesNotAccessMemory,
+  /* mips_pckod_b */ DoesNotAccessMemory,
+  /* mips_pckod_d */ DoesNotAccessMemory,
+  /* mips_pckod_h */ DoesNotAccessMemory,
+  /* mips_pckod_w */ DoesNotAccessMemory,
+  /* mips_pcnt_b */ DoesNotAccessMemory,
+  /* mips_pcnt_d */ DoesNotAccessMemory,
+  /* mips_pcnt_h */ DoesNotAccessMemory,
+  /* mips_pcnt_w */ DoesNotAccessMemory,
+  /* mips_pick_ph */ OnlyReadsMemory,
+  /* mips_pick_qb */ OnlyReadsMemory,
+  /* mips_preceq_w_phl */ DoesNotAccessMemory,
+  /* mips_preceq_w_phr */ DoesNotAccessMemory,
+  /* mips_precequ_ph_qbl */ DoesNotAccessMemory,
+  /* mips_precequ_ph_qbla */ DoesNotAccessMemory,
+  /* mips_precequ_ph_qbr */ DoesNotAccessMemory,
+  /* mips_precequ_ph_qbra */ DoesNotAccessMemory,
+  /* mips_preceu_ph_qbl */ DoesNotAccessMemory,
+  /* mips_preceu_ph_qbla */ DoesNotAccessMemory,
+  /* mips_preceu_ph_qbr */ DoesNotAccessMemory,
+  /* mips_preceu_ph_qbra */ DoesNotAccessMemory,
+  /* mips_precr_qb_ph */ UnknownModRefBehavior,
+  /* mips_precr_sra_ph_w */ DoesNotAccessMemory,
+  /* mips_precr_sra_r_ph_w */ DoesNotAccessMemory,
+  /* mips_precrq_ph_w */ DoesNotAccessMemory,
+  /* mips_precrq_qb_ph */ DoesNotAccessMemory,
+  /* mips_precrq_rs_ph_w */ UnknownModRefBehavior,
+  /* mips_precrqu_s_qb_ph */ UnknownModRefBehavior,
+  /* mips_prepend */ DoesNotAccessMemory,
+  /* mips_raddu_w_qb */ DoesNotAccessMemory,
+  /* mips_rddsp */ OnlyReadsMemory,
+  /* mips_repl_ph */ DoesNotAccessMemory,
+  /* mips_repl_qb */ DoesNotAccessMemory,
+  /* mips_sat_s_b */ DoesNotAccessMemory,
+  /* mips_sat_s_d */ DoesNotAccessMemory,
+  /* mips_sat_s_h */ DoesNotAccessMemory,
+  /* mips_sat_s_w */ DoesNotAccessMemory,
+  /* mips_sat_u_b */ DoesNotAccessMemory,
+  /* mips_sat_u_d */ DoesNotAccessMemory,
+  /* mips_sat_u_h */ DoesNotAccessMemory,
+  /* mips_sat_u_w */ DoesNotAccessMemory,
+  /* mips_shf_b */ DoesNotAccessMemory,
+  /* mips_shf_h */ DoesNotAccessMemory,
+  /* mips_shf_w */ DoesNotAccessMemory,
+  /* mips_shilo */ DoesNotAccessMemory,
+  /* mips_shll_ph */ UnknownModRefBehavior,
+  /* mips_shll_qb */ UnknownModRefBehavior,
+  /* mips_shll_s_ph */ UnknownModRefBehavior,
+  /* mips_shll_s_w */ UnknownModRefBehavior,
+  /* mips_shra_ph */ DoesNotAccessMemory,
+  /* mips_shra_qb */ DoesNotAccessMemory,
+  /* mips_shra_r_ph */ DoesNotAccessMemory,
+  /* mips_shra_r_qb */ DoesNotAccessMemory,
+  /* mips_shra_r_w */ DoesNotAccessMemory,
+  /* mips_shrl_ph */ DoesNotAccessMemory,
+  /* mips_shrl_qb */ DoesNotAccessMemory,
+  /* mips_sld_b */ DoesNotAccessMemory,
+  /* mips_sld_d */ DoesNotAccessMemory,
+  /* mips_sld_h */ DoesNotAccessMemory,
+  /* mips_sld_w */ DoesNotAccessMemory,
+  /* mips_sldi_b */ DoesNotAccessMemory,
+  /* mips_sldi_d */ DoesNotAccessMemory,
+  /* mips_sldi_h */ DoesNotAccessMemory,
+  /* mips_sldi_w */ DoesNotAccessMemory,
+  /* mips_sll_b */ DoesNotAccessMemory,
+  /* mips_sll_d */ DoesNotAccessMemory,
+  /* mips_sll_h */ DoesNotAccessMemory,
+  /* mips_sll_w */ DoesNotAccessMemory,
+  /* mips_slli_b */ DoesNotAccessMemory,
+  /* mips_slli_d */ DoesNotAccessMemory,
+  /* mips_slli_h */ DoesNotAccessMemory,
+  /* mips_slli_w */ DoesNotAccessMemory,
+  /* mips_splat_b */ DoesNotAccessMemory,
+  /* mips_splat_d */ DoesNotAccessMemory,
+  /* mips_splat_h */ DoesNotAccessMemory,
+  /* mips_splat_w */ DoesNotAccessMemory,
+  /* mips_splati_b */ DoesNotAccessMemory,
+  /* mips_splati_d */ DoesNotAccessMemory,
+  /* mips_splati_h */ DoesNotAccessMemory,
+  /* mips_splati_w */ DoesNotAccessMemory,
+  /* mips_sra_b */ DoesNotAccessMemory,
+  /* mips_sra_d */ DoesNotAccessMemory,
+  /* mips_sra_h */ DoesNotAccessMemory,
+  /* mips_sra_w */ DoesNotAccessMemory,
+  /* mips_srai_b */ DoesNotAccessMemory,
+  /* mips_srai_d */ DoesNotAccessMemory,
+  /* mips_srai_h */ DoesNotAccessMemory,
+  /* mips_srai_w */ DoesNotAccessMemory,
+  /* mips_srar_b */ DoesNotAccessMemory,
+  /* mips_srar_d */ DoesNotAccessMemory,
+  /* mips_srar_h */ DoesNotAccessMemory,
+  /* mips_srar_w */ DoesNotAccessMemory,
+  /* mips_srari_b */ DoesNotAccessMemory,
+  /* mips_srari_d */ DoesNotAccessMemory,
+  /* mips_srari_h */ DoesNotAccessMemory,
+  /* mips_srari_w */ DoesNotAccessMemory,
+  /* mips_srl_b */ DoesNotAccessMemory,
+  /* mips_srl_d */ DoesNotAccessMemory,
+  /* mips_srl_h */ DoesNotAccessMemory,
+  /* mips_srl_w */ DoesNotAccessMemory,
+  /* mips_srli_b */ DoesNotAccessMemory,
+  /* mips_srli_d */ DoesNotAccessMemory,
+  /* mips_srli_h */ DoesNotAccessMemory,
+  /* mips_srli_w */ DoesNotAccessMemory,
+  /* mips_srlr_b */ DoesNotAccessMemory,
+  /* mips_srlr_d */ DoesNotAccessMemory,
+  /* mips_srlr_h */ DoesNotAccessMemory,
+  /* mips_srlr_w */ DoesNotAccessMemory,
+  /* mips_srlri_b */ DoesNotAccessMemory,
+  /* mips_srlri_d */ DoesNotAccessMemory,
+  /* mips_srlri_h */ DoesNotAccessMemory,
+  /* mips_srlri_w */ DoesNotAccessMemory,
+  /* mips_st_b */ OnlyAccessesArgumentPointees,
+  /* mips_st_d */ OnlyAccessesArgumentPointees,
+  /* mips_st_h */ OnlyAccessesArgumentPointees,
+  /* mips_st_w */ OnlyAccessesArgumentPointees,
+  /* mips_subq_ph */ DoesNotAccessMemory,
+  /* mips_subq_s_ph */ DoesNotAccessMemory,
+  /* mips_subq_s_w */ UnknownModRefBehavior,
+  /* mips_subqh_ph */ DoesNotAccessMemory,
+  /* mips_subqh_r_ph */ DoesNotAccessMemory,
+  /* mips_subqh_r_w */ DoesNotAccessMemory,
+  /* mips_subqh_w */ DoesNotAccessMemory,
+  /* mips_subs_s_b */ DoesNotAccessMemory,
+  /* mips_subs_s_d */ DoesNotAccessMemory,
+  /* mips_subs_s_h */ DoesNotAccessMemory,
+  /* mips_subs_s_w */ DoesNotAccessMemory,
+  /* mips_subs_u_b */ DoesNotAccessMemory,
+  /* mips_subs_u_d */ DoesNotAccessMemory,
+  /* mips_subs_u_h */ DoesNotAccessMemory,
+  /* mips_subs_u_w */ DoesNotAccessMemory,
+  /* mips_subsus_u_b */ DoesNotAccessMemory,
+  /* mips_subsus_u_d */ DoesNotAccessMemory,
+  /* mips_subsus_u_h */ DoesNotAccessMemory,
+  /* mips_subsus_u_w */ DoesNotAccessMemory,
+  /* mips_subsuu_s_b */ DoesNotAccessMemory,
+  /* mips_subsuu_s_d */ DoesNotAccessMemory,
+  /* mips_subsuu_s_h */ DoesNotAccessMemory,
+  /* mips_subsuu_s_w */ DoesNotAccessMemory,
+  /* mips_subu_ph */ UnknownModRefBehavior,
+  /* mips_subu_qb */ DoesNotAccessMemory,
+  /* mips_subu_s_ph */ UnknownModRefBehavior,
+  /* mips_subu_s_qb */ DoesNotAccessMemory,
+  /* mips_subuh_qb */ DoesNotAccessMemory,
+  /* mips_subuh_r_qb */ DoesNotAccessMemory,
+  /* mips_subv_b */ DoesNotAccessMemory,
+  /* mips_subv_d */ DoesNotAccessMemory,
+  /* mips_subv_h */ DoesNotAccessMemory,
+  /* mips_subv_w */ DoesNotAccessMemory,
+  /* mips_subvi_b */ DoesNotAccessMemory,
+  /* mips_subvi_d */ DoesNotAccessMemory,
+  /* mips_subvi_h */ DoesNotAccessMemory,
+  /* mips_subvi_w */ DoesNotAccessMemory,
+  /* mips_vshf_b */ DoesNotAccessMemory,
+  /* mips_vshf_d */ DoesNotAccessMemory,
+  /* mips_vshf_h */ DoesNotAccessMemory,
+  /* mips_vshf_w */ DoesNotAccessMemory,
+  /* mips_wrdsp */ UnknownModRefBehavior,
+  /* mips_xor_v */ DoesNotAccessMemory,
+  /* mips_xori_b */ DoesNotAccessMemory,
+  /* nearbyint */ DoesNotAccessMemory,
+  /* nvvm_abs_i */ DoesNotAccessMemory,
+  /* nvvm_abs_ll */ DoesNotAccessMemory,
+  /* nvvm_add_rm_d */ DoesNotAccessMemory,
+  /* nvvm_add_rm_f */ DoesNotAccessMemory,
+  /* nvvm_add_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_add_rn_d */ DoesNotAccessMemory,
+  /* nvvm_add_rn_f */ DoesNotAccessMemory,
+  /* nvvm_add_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_add_rp_d */ DoesNotAccessMemory,
+  /* nvvm_add_rp_f */ DoesNotAccessMemory,
+  /* nvvm_add_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_add_rz_d */ DoesNotAccessMemory,
+  /* nvvm_add_rz_f */ DoesNotAccessMemory,
+  /* nvvm_add_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_atomic_load_add_f32 */ OnlyAccessesArgumentPointees,
+  /* nvvm_atomic_load_dec_32 */ OnlyAccessesArgumentPointees,
+  /* nvvm_atomic_load_inc_32 */ OnlyAccessesArgumentPointees,
+  /* nvvm_barrier0 */ UnknownModRefBehavior,
+  /* nvvm_barrier0_and */ UnknownModRefBehavior,
+  /* nvvm_barrier0_or */ UnknownModRefBehavior,
+  /* nvvm_barrier0_popc */ UnknownModRefBehavior,
+  /* nvvm_bitcast_d2ll */ DoesNotAccessMemory,
+  /* nvvm_bitcast_f2i */ DoesNotAccessMemory,
+  /* nvvm_bitcast_i2f */ DoesNotAccessMemory,
+  /* nvvm_bitcast_ll2d */ DoesNotAccessMemory,
+  /* nvvm_brev32 */ DoesNotAccessMemory,
+  /* nvvm_brev64 */ DoesNotAccessMemory,
+  /* nvvm_ceil_d */ DoesNotAccessMemory,
+  /* nvvm_ceil_f */ DoesNotAccessMemory,
+  /* nvvm_ceil_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_clz_i */ DoesNotAccessMemory,
+  /* nvvm_clz_ll */ DoesNotAccessMemory,
+  /* nvvm_compiler_error */ UnknownModRefBehavior,
+  /* nvvm_compiler_warn */ UnknownModRefBehavior,
+  /* nvvm_cos_approx_f */ DoesNotAccessMemory,
+  /* nvvm_cos_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_d2f_rm */ DoesNotAccessMemory,
+  /* nvvm_d2f_rm_ftz */ DoesNotAccessMemory,
+  /* nvvm_d2f_rn */ DoesNotAccessMemory,
+  /* nvvm_d2f_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_d2f_rp */ DoesNotAccessMemory,
+  /* nvvm_d2f_rp_ftz */ DoesNotAccessMemory,
+  /* nvvm_d2f_rz */ DoesNotAccessMemory,
+  /* nvvm_d2f_rz_ftz */ DoesNotAccessMemory,
+  /* nvvm_d2i_hi */ DoesNotAccessMemory,
+  /* nvvm_d2i_lo */ DoesNotAccessMemory,
+  /* nvvm_d2i_rm */ DoesNotAccessMemory,
+  /* nvvm_d2i_rn */ DoesNotAccessMemory,
+  /* nvvm_d2i_rp */ DoesNotAccessMemory,
+  /* nvvm_d2i_rz */ DoesNotAccessMemory,
+  /* nvvm_d2ll_rm */ DoesNotAccessMemory,
+  /* nvvm_d2ll_rn */ DoesNotAccessMemory,
+  /* nvvm_d2ll_rp */ DoesNotAccessMemory,
+  /* nvvm_d2ll_rz */ DoesNotAccessMemory,
+  /* nvvm_d2ui_rm */ DoesNotAccessMemory,
+  /* nvvm_d2ui_rn */ DoesNotAccessMemory,
+  /* nvvm_d2ui_rp */ DoesNotAccessMemory,
+  /* nvvm_d2ui_rz */ DoesNotAccessMemory,
+  /* nvvm_d2ull_rm */ DoesNotAccessMemory,
+  /* nvvm_d2ull_rn */ DoesNotAccessMemory,
+  /* nvvm_d2ull_rp */ DoesNotAccessMemory,
+  /* nvvm_d2ull_rz */ DoesNotAccessMemory,
+  /* nvvm_div_approx_f */ DoesNotAccessMemory,
+  /* nvvm_div_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_div_rm_d */ DoesNotAccessMemory,
+  /* nvvm_div_rm_f */ DoesNotAccessMemory,
+  /* nvvm_div_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_div_rn_d */ DoesNotAccessMemory,
+  /* nvvm_div_rn_f */ DoesNotAccessMemory,
+  /* nvvm_div_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_div_rp_d */ DoesNotAccessMemory,
+  /* nvvm_div_rp_f */ DoesNotAccessMemory,
+  /* nvvm_div_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_div_rz_d */ DoesNotAccessMemory,
+  /* nvvm_div_rz_f */ DoesNotAccessMemory,
+  /* nvvm_div_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_ex2_approx_d */ DoesNotAccessMemory,
+  /* nvvm_ex2_approx_f */ DoesNotAccessMemory,
+  /* nvvm_ex2_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_f2h_rn */ DoesNotAccessMemory,
+  /* nvvm_f2h_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2i_rm */ DoesNotAccessMemory,
+  /* nvvm_f2i_rm_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2i_rn */ DoesNotAccessMemory,
+  /* nvvm_f2i_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2i_rp */ DoesNotAccessMemory,
+  /* nvvm_f2i_rp_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2i_rz */ DoesNotAccessMemory,
+  /* nvvm_f2i_rz_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rm */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rm_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rn */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rp */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rp_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rz */ DoesNotAccessMemory,
+  /* nvvm_f2ll_rz_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rm */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rm_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rn */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rp */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rp_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rz */ DoesNotAccessMemory,
+  /* nvvm_f2ui_rz_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rm */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rm_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rn */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rn_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rp */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rp_ftz */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rz */ DoesNotAccessMemory,
+  /* nvvm_f2ull_rz_ftz */ DoesNotAccessMemory,
+  /* nvvm_fabs_d */ DoesNotAccessMemory,
+  /* nvvm_fabs_f */ DoesNotAccessMemory,
+  /* nvvm_fabs_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_floor_d */ DoesNotAccessMemory,
+  /* nvvm_floor_f */ DoesNotAccessMemory,
+  /* nvvm_floor_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rm_d */ DoesNotAccessMemory,
+  /* nvvm_fma_rm_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rn_d */ DoesNotAccessMemory,
+  /* nvvm_fma_rn_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rp_d */ DoesNotAccessMemory,
+  /* nvvm_fma_rp_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rz_d */ DoesNotAccessMemory,
+  /* nvvm_fma_rz_f */ DoesNotAccessMemory,
+  /* nvvm_fma_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fmax_d */ DoesNotAccessMemory,
+  /* nvvm_fmax_f */ DoesNotAccessMemory,
+  /* nvvm_fmax_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_fmin_d */ DoesNotAccessMemory,
+  /* nvvm_fmin_f */ DoesNotAccessMemory,
+  /* nvvm_fmin_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_h2f */ DoesNotAccessMemory,
+  /* nvvm_i2d_rm */ DoesNotAccessMemory,
+  /* nvvm_i2d_rn */ DoesNotAccessMemory,
+  /* nvvm_i2d_rp */ DoesNotAccessMemory,
+  /* nvvm_i2d_rz */ DoesNotAccessMemory,
+  /* nvvm_i2f_rm */ DoesNotAccessMemory,
+  /* nvvm_i2f_rn */ DoesNotAccessMemory,
+  /* nvvm_i2f_rp */ DoesNotAccessMemory,
+  /* nvvm_i2f_rz */ DoesNotAccessMemory,
+  /* nvvm_isspacep_const */ DoesNotAccessMemory,
+  /* nvvm_isspacep_global */ DoesNotAccessMemory,
+  /* nvvm_isspacep_local */ DoesNotAccessMemory,
+  /* nvvm_isspacep_shared */ DoesNotAccessMemory,
+  /* nvvm_istypep_sampler */ DoesNotAccessMemory,
+  /* nvvm_istypep_surface */ DoesNotAccessMemory,
+  /* nvvm_istypep_texture */ DoesNotAccessMemory,
+  /* nvvm_ldg_global_f */ OnlyReadsMemory,
+  /* nvvm_ldg_global_i */ OnlyReadsMemory,
+  /* nvvm_ldg_global_p */ OnlyReadsMemory,
+  /* nvvm_ldu_global_f */ OnlyReadsMemory,
+  /* nvvm_ldu_global_i */ OnlyReadsMemory,
+  /* nvvm_ldu_global_p */ OnlyReadsMemory,
+  /* nvvm_lg2_approx_d */ DoesNotAccessMemory,
+  /* nvvm_lg2_approx_f */ DoesNotAccessMemory,
+  /* nvvm_lg2_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_ll2d_rm */ DoesNotAccessMemory,
+  /* nvvm_ll2d_rn */ DoesNotAccessMemory,
+  /* nvvm_ll2d_rp */ DoesNotAccessMemory,
+  /* nvvm_ll2d_rz */ DoesNotAccessMemory,
+  /* nvvm_ll2f_rm */ DoesNotAccessMemory,
+  /* nvvm_ll2f_rn */ DoesNotAccessMemory,
+  /* nvvm_ll2f_rp */ DoesNotAccessMemory,
+  /* nvvm_ll2f_rz */ DoesNotAccessMemory,
+  /* nvvm_lohi_i2d */ DoesNotAccessMemory,
+  /* nvvm_max_i */ DoesNotAccessMemory,
+  /* nvvm_max_ll */ DoesNotAccessMemory,
+  /* nvvm_max_ui */ DoesNotAccessMemory,
+  /* nvvm_max_ull */ DoesNotAccessMemory,
+  /* nvvm_membar_cta */ UnknownModRefBehavior,
+  /* nvvm_membar_gl */ UnknownModRefBehavior,
+  /* nvvm_membar_sys */ UnknownModRefBehavior,
+  /* nvvm_min_i */ DoesNotAccessMemory,
+  /* nvvm_min_ll */ DoesNotAccessMemory,
+  /* nvvm_min_ui */ DoesNotAccessMemory,
+  /* nvvm_min_ull */ DoesNotAccessMemory,
+  /* nvvm_move_double */ DoesNotAccessMemory,
+  /* nvvm_move_float */ DoesNotAccessMemory,
+  /* nvvm_move_i16 */ DoesNotAccessMemory,
+  /* nvvm_move_i32 */ DoesNotAccessMemory,
+  /* nvvm_move_i64 */ DoesNotAccessMemory,
+  /* nvvm_move_ptr */ DoesNotAccessMemory,
+  /* nvvm_mul24_i */ DoesNotAccessMemory,
+  /* nvvm_mul24_ui */ DoesNotAccessMemory,
+  /* nvvm_mul_rm_d */ DoesNotAccessMemory,
+  /* nvvm_mul_rm_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rn_d */ DoesNotAccessMemory,
+  /* nvvm_mul_rn_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rp_d */ DoesNotAccessMemory,
+  /* nvvm_mul_rp_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rz_d */ DoesNotAccessMemory,
+  /* nvvm_mul_rz_f */ DoesNotAccessMemory,
+  /* nvvm_mul_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_mulhi_i */ DoesNotAccessMemory,
+  /* nvvm_mulhi_ll */ DoesNotAccessMemory,
+  /* nvvm_mulhi_ui */ DoesNotAccessMemory,
+  /* nvvm_mulhi_ull */ DoesNotAccessMemory,
+  /* nvvm_popc_i */ DoesNotAccessMemory,
+  /* nvvm_popc_ll */ DoesNotAccessMemory,
+  /* nvvm_prmt */ DoesNotAccessMemory,
+  /* nvvm_ptr_constant_to_gen */ DoesNotAccessMemory,
+  /* nvvm_ptr_gen_to_constant */ DoesNotAccessMemory,
+  /* nvvm_ptr_gen_to_global */ DoesNotAccessMemory,
+  /* nvvm_ptr_gen_to_local */ DoesNotAccessMemory,
+  /* nvvm_ptr_gen_to_param */ DoesNotAccessMemory,
+  /* nvvm_ptr_gen_to_shared */ DoesNotAccessMemory,
+  /* nvvm_ptr_global_to_gen */ DoesNotAccessMemory,
+  /* nvvm_ptr_local_to_gen */ DoesNotAccessMemory,
+  /* nvvm_ptr_shared_to_gen */ DoesNotAccessMemory,
+  /* nvvm_rcp_approx_ftz_d */ DoesNotAccessMemory,
+  /* nvvm_rcp_rm_d */ DoesNotAccessMemory,
+  /* nvvm_rcp_rm_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rn_d */ DoesNotAccessMemory,
+  /* nvvm_rcp_rn_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rp_d */ DoesNotAccessMemory,
+  /* nvvm_rcp_rp_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rz_d */ DoesNotAccessMemory,
+  /* nvvm_rcp_rz_f */ DoesNotAccessMemory,
+  /* nvvm_rcp_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ctaid_x */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ctaid_y */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ctaid_z */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg0 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg1 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg10 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg11 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg12 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg13 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg14 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg15 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg16 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg17 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg18 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg19 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg2 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg20 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg21 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg22 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg23 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg24 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg25 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg26 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg27 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg28 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg29 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg3 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg30 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg31 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg4 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg5 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg6 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg7 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg8 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_envreg9 */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_nctaid_x */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_nctaid_y */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_nctaid_z */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ntid_x */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ntid_y */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_ntid_z */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_tid_x */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_tid_y */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_tid_z */ DoesNotAccessMemory,
+  /* nvvm_read_ptx_sreg_warpsize */ DoesNotAccessMemory,
+  /* nvvm_reflect */ DoesNotAccessMemory,
+  /* nvvm_rotate_b32 */ DoesNotAccessMemory,
+  /* nvvm_rotate_b64 */ DoesNotAccessMemory,
+  /* nvvm_rotate_right_b64 */ DoesNotAccessMemory,
+  /* nvvm_round_d */ DoesNotAccessMemory,
+  /* nvvm_round_f */ DoesNotAccessMemory,
+  /* nvvm_round_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_rsqrt_approx_d */ DoesNotAccessMemory,
+  /* nvvm_rsqrt_approx_f */ DoesNotAccessMemory,
+  /* nvvm_rsqrt_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sad_i */ DoesNotAccessMemory,
+  /* nvvm_sad_ui */ DoesNotAccessMemory,
+  /* nvvm_saturate_d */ DoesNotAccessMemory,
+  /* nvvm_saturate_f */ DoesNotAccessMemory,
+  /* nvvm_saturate_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sin_approx_f */ DoesNotAccessMemory,
+  /* nvvm_sin_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_approx_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_approx_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rm_d */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rm_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rm_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rn_d */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rn_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rn_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rp_d */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rp_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rp_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rz_d */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rz_f */ DoesNotAccessMemory,
+  /* nvvm_sqrt_rz_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_suld_1d_array_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_array_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_1d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_array_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_2d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_suld_3d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_suq_array_size */ DoesNotAccessMemory,
+  /* nvvm_suq_channel_data_type */ DoesNotAccessMemory,
+  /* nvvm_suq_channel_order */ DoesNotAccessMemory,
+  /* nvvm_suq_depth */ DoesNotAccessMemory,
+  /* nvvm_suq_height */ DoesNotAccessMemory,
+  /* nvvm_suq_width */ DoesNotAccessMemory,
+  /* nvvm_sust_b_1d_array_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_array_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_1d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_array_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_2d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i64_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i64_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i64_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v2i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i16_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i16_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i32_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i32_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i8_clamp */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_b_3d_v4i8_zero */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_1d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_array_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_2d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v2i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v2i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v2i8_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v4i16_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v4i32_trap */ UnknownModRefBehavior,
+  /* nvvm_sust_p_3d_v4i8_trap */ UnknownModRefBehavior,
+  /* nvvm_swap_lo_hi_b64 */ DoesNotAccessMemory,
+  /* nvvm_tex_1d_array_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_array_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_1d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_array_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_2d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_3d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_cube_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_array_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_1d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_array_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_2d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_grad_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_grad_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_grad_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4f32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4s32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_3d_v4u32_s32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_array_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_level_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_level_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_level_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tex_unified_cube_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_texsurf_handle */ DoesNotAccessMemory,
+  /* nvvm_texsurf_handle_internal */ DoesNotAccessMemory,
+  /* nvvm_tld4_a_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_a_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_a_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_b_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_b_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_b_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_g_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_g_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_g_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_r_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_r_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_r_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_a_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_a_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_a_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_b_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_b_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_b_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_g_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_g_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_g_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_r_2d_v4f32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_r_2d_v4s32_f32 */ UnknownModRefBehavior,
+  /* nvvm_tld4_unified_r_2d_v4u32_f32 */ UnknownModRefBehavior,
+  /* nvvm_trunc_d */ DoesNotAccessMemory,
+  /* nvvm_trunc_f */ DoesNotAccessMemory,
+  /* nvvm_trunc_ftz_f */ DoesNotAccessMemory,
+  /* nvvm_txq_array_size */ DoesNotAccessMemory,
+  /* nvvm_txq_channel_data_type */ DoesNotAccessMemory,
+  /* nvvm_txq_channel_order */ DoesNotAccessMemory,
+  /* nvvm_txq_depth */ DoesNotAccessMemory,
+  /* nvvm_txq_height */ DoesNotAccessMemory,
+  /* nvvm_txq_num_mipmap_levels */ DoesNotAccessMemory,
+  /* nvvm_txq_num_samples */ DoesNotAccessMemory,
+  /* nvvm_txq_width */ DoesNotAccessMemory,
+  /* nvvm_ui2d_rm */ DoesNotAccessMemory,
+  /* nvvm_ui2d_rn */ DoesNotAccessMemory,
+  /* nvvm_ui2d_rp */ DoesNotAccessMemory,
+  /* nvvm_ui2d_rz */ DoesNotAccessMemory,
+  /* nvvm_ui2f_rm */ DoesNotAccessMemory,
+  /* nvvm_ui2f_rn */ DoesNotAccessMemory,
+  /* nvvm_ui2f_rp */ DoesNotAccessMemory,
+  /* nvvm_ui2f_rz */ DoesNotAccessMemory,
+  /* nvvm_ull2d_rm */ DoesNotAccessMemory,
+  /* nvvm_ull2d_rn */ DoesNotAccessMemory,
+  /* nvvm_ull2d_rp */ DoesNotAccessMemory,
+  /* nvvm_ull2d_rz */ DoesNotAccessMemory,
+  /* nvvm_ull2f_rm */ DoesNotAccessMemory,
+  /* nvvm_ull2f_rn */ DoesNotAccessMemory,
+  /* nvvm_ull2f_rp */ DoesNotAccessMemory,
+  /* nvvm_ull2f_rz */ DoesNotAccessMemory,
+  /* objectsize */ DoesNotAccessMemory,
+  /* pcmarker */ UnknownModRefBehavior,
+  /* pow */ DoesNotAccessMemory,
+  /* powi */ DoesNotAccessMemory,
+  /* ppc_altivec_dss */ UnknownModRefBehavior,
+  /* ppc_altivec_dssall */ UnknownModRefBehavior,
+  /* ppc_altivec_dst */ UnknownModRefBehavior,
+  /* ppc_altivec_dstst */ UnknownModRefBehavior,
+  /* ppc_altivec_dststt */ UnknownModRefBehavior,
+  /* ppc_altivec_dstt */ UnknownModRefBehavior,
+  /* ppc_altivec_lvebx */ OnlyReadsArgumentPointees,
+  /* ppc_altivec_lvehx */ OnlyReadsArgumentPointees,
+  /* ppc_altivec_lvewx */ OnlyReadsArgumentPointees,
+  /* ppc_altivec_lvsl */ DoesNotAccessMemory,
+  /* ppc_altivec_lvsr */ DoesNotAccessMemory,
+  /* ppc_altivec_lvx */ OnlyReadsArgumentPointees,
+  /* ppc_altivec_lvxl */ OnlyReadsArgumentPointees,
+  /* ppc_altivec_mfvscr */ OnlyReadsMemory,
+  /* ppc_altivec_mtvscr */ UnknownModRefBehavior,
+  /* ppc_altivec_stvebx */ OnlyAccessesArgumentPointees,
+  /* ppc_altivec_stvehx */ OnlyAccessesArgumentPointees,
+  /* ppc_altivec_stvewx */ OnlyAccessesArgumentPointees,
+  /* ppc_altivec_stvx */ OnlyAccessesArgumentPointees,
+  /* ppc_altivec_stvxl */ OnlyAccessesArgumentPointees,
+  /* ppc_altivec_vaddcuw */ DoesNotAccessMemory,
+  /* ppc_altivec_vaddsbs */ DoesNotAccessMemory,
+  /* ppc_altivec_vaddshs */ DoesNotAccessMemory,
+  /* ppc_altivec_vaddsws */ DoesNotAccessMemory,
+  /* ppc_altivec_vaddubs */ DoesNotAccessMemory,
+  /* ppc_altivec_vadduhs */ DoesNotAccessMemory,
+  /* ppc_altivec_vadduws */ DoesNotAccessMemory,
+  /* ppc_altivec_vavgsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vavgsh */ DoesNotAccessMemory,
+  /* ppc_altivec_vavgsw */ DoesNotAccessMemory,
+  /* ppc_altivec_vavgub */ DoesNotAccessMemory,
+  /* ppc_altivec_vavguh */ DoesNotAccessMemory,
+  /* ppc_altivec_vavguw */ DoesNotAccessMemory,
+  /* ppc_altivec_vcfsx */ DoesNotAccessMemory,
+  /* ppc_altivec_vcfux */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpbfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpbfp_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpeqfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpeqfp_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequb */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequb_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequh */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequh_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequw */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpequw_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgefp */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgefp_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtfp_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsb_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsh */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsh_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsw */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtsw_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtub */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtub_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtuh */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtuh_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtuw */ DoesNotAccessMemory,
+  /* ppc_altivec_vcmpgtuw_p */ DoesNotAccessMemory,
+  /* ppc_altivec_vctsxs */ DoesNotAccessMemory,
+  /* ppc_altivec_vctuxs */ DoesNotAccessMemory,
+  /* ppc_altivec_vexptefp */ DoesNotAccessMemory,
+  /* ppc_altivec_vlogefp */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaddfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxsh */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxsw */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxub */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxuh */ DoesNotAccessMemory,
+  /* ppc_altivec_vmaxuw */ DoesNotAccessMemory,
+  /* ppc_altivec_vmhaddshs */ DoesNotAccessMemory,
+  /* ppc_altivec_vmhraddshs */ DoesNotAccessMemory,
+  /* ppc_altivec_vminfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vminsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vminsh */ DoesNotAccessMemory,
+  /* ppc_altivec_vminsw */ DoesNotAccessMemory,
+  /* ppc_altivec_vminub */ DoesNotAccessMemory,
+  /* ppc_altivec_vminuh */ DoesNotAccessMemory,
+  /* ppc_altivec_vminuw */ DoesNotAccessMemory,
+  /* ppc_altivec_vmladduhm */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsummbm */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsumshm */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsumshs */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsumubm */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsumuhm */ DoesNotAccessMemory,
+  /* ppc_altivec_vmsumuhs */ DoesNotAccessMemory,
+  /* ppc_altivec_vmulesb */ DoesNotAccessMemory,
+  /* ppc_altivec_vmulesh */ DoesNotAccessMemory,
+  /* ppc_altivec_vmuleub */ DoesNotAccessMemory,
+  /* ppc_altivec_vmuleuh */ DoesNotAccessMemory,
+  /* ppc_altivec_vmulosb */ DoesNotAccessMemory,
+  /* ppc_altivec_vmulosh */ DoesNotAccessMemory,
+  /* ppc_altivec_vmuloub */ DoesNotAccessMemory,
+  /* ppc_altivec_vmulouh */ DoesNotAccessMemory,
+  /* ppc_altivec_vnmsubfp */ DoesNotAccessMemory,
+  /* ppc_altivec_vperm */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkpx */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkshss */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkshus */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkswss */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkswus */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkuhus */ DoesNotAccessMemory,
+  /* ppc_altivec_vpkuwus */ DoesNotAccessMemory,
+  /* ppc_altivec_vrefp */ DoesNotAccessMemory,
+  /* ppc_altivec_vrfim */ DoesNotAccessMemory,
+  /* ppc_altivec_vrfin */ DoesNotAccessMemory,
+  /* ppc_altivec_vrfip */ DoesNotAccessMemory,
+  /* ppc_altivec_vrfiz */ DoesNotAccessMemory,
+  /* ppc_altivec_vrlb */ DoesNotAccessMemory,
+  /* ppc_altivec_vrlh */ DoesNotAccessMemory,
+  /* ppc_altivec_vrlw */ DoesNotAccessMemory,
+  /* ppc_altivec_vrsqrtefp */ DoesNotAccessMemory,
+  /* ppc_altivec_vsel */ DoesNotAccessMemory,
+  /* ppc_altivec_vsl */ DoesNotAccessMemory,
+  /* ppc_altivec_vslb */ DoesNotAccessMemory,
+  /* ppc_altivec_vslh */ DoesNotAccessMemory,
+  /* ppc_altivec_vslo */ DoesNotAccessMemory,
+  /* ppc_altivec_vslw */ DoesNotAccessMemory,
+  /* ppc_altivec_vsr */ DoesNotAccessMemory,
+  /* ppc_altivec_vsrab */ DoesNotAccessMemory,
+  /* ppc_altivec_vsrah */ DoesNotAccessMemory,
+  /* ppc_altivec_vsraw */ DoesNotAccessMemory,
+  /* ppc_altivec_vsrb */ DoesNotAccessMemory,
+  /* ppc_altivec_vsrh */ DoesNotAccessMemory,
+  /* ppc_altivec_vsro */ DoesNotAccessMemory,
+  /* ppc_altivec_vsrw */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubcuw */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubsbs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubshs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubsws */ DoesNotAccessMemory,
+  /* ppc_altivec_vsububs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubuhs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsubuws */ DoesNotAccessMemory,
+  /* ppc_altivec_vsum2sws */ DoesNotAccessMemory,
+  /* ppc_altivec_vsum4sbs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsum4shs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsum4ubs */ DoesNotAccessMemory,
+  /* ppc_altivec_vsumsws */ DoesNotAccessMemory,
+  /* ppc_altivec_vupkhpx */ DoesNotAccessMemory,
+  /* ppc_altivec_vupkhsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vupkhsh */ DoesNotAccessMemory,
+  /* ppc_altivec_vupklpx */ DoesNotAccessMemory,
+  /* ppc_altivec_vupklsb */ DoesNotAccessMemory,
+  /* ppc_altivec_vupklsh */ DoesNotAccessMemory,
+  /* ppc_dcba */ UnknownModRefBehavior,
+  /* ppc_dcbf */ UnknownModRefBehavior,
+  /* ppc_dcbi */ UnknownModRefBehavior,
+  /* ppc_dcbst */ UnknownModRefBehavior,
+  /* ppc_dcbt */ OnlyAccessesArgumentPointees,
+  /* ppc_dcbtst */ UnknownModRefBehavior,
+  /* ppc_dcbz */ UnknownModRefBehavior,
+  /* ppc_dcbzl */ UnknownModRefBehavior,
+  /* ppc_is_decremented_ctr_nonzero */ UnknownModRefBehavior,
+  /* ppc_mtctr */ UnknownModRefBehavior,
+  /* ppc_sync */ UnknownModRefBehavior,
+  /* prefetch */ OnlyAccessesArgumentPointees,
+  /* ptr_annotation */ UnknownModRefBehavior,
+  /* ptx_bar_sync */ UnknownModRefBehavior,
+  /* ptx_read_clock */ DoesNotAccessMemory,
+  /* ptx_read_clock64 */ DoesNotAccessMemory,
+  /* ptx_read_ctaid_w */ DoesNotAccessMemory,
+  /* ptx_read_ctaid_x */ DoesNotAccessMemory,
+  /* ptx_read_ctaid_y */ DoesNotAccessMemory,
+  /* ptx_read_ctaid_z */ DoesNotAccessMemory,
+  /* ptx_read_gridid */ DoesNotAccessMemory,
+  /* ptx_read_laneid */ DoesNotAccessMemory,
+  /* ptx_read_lanemask_eq */ DoesNotAccessMemory,
+  /* ptx_read_lanemask_ge */ DoesNotAccessMemory,
+  /* ptx_read_lanemask_gt */ DoesNotAccessMemory,
+  /* ptx_read_lanemask_le */ DoesNotAccessMemory,
+  /* ptx_read_lanemask_lt */ DoesNotAccessMemory,
+  /* ptx_read_nctaid_w */ DoesNotAccessMemory,
+  /* ptx_read_nctaid_x */ DoesNotAccessMemory,
+  /* ptx_read_nctaid_y */ DoesNotAccessMemory,
+  /* ptx_read_nctaid_z */ DoesNotAccessMemory,
+  /* ptx_read_nsmid */ DoesNotAccessMemory,
+  /* ptx_read_ntid_w */ DoesNotAccessMemory,
+  /* ptx_read_ntid_x */ DoesNotAccessMemory,
+  /* ptx_read_ntid_y */ DoesNotAccessMemory,
+  /* ptx_read_ntid_z */ DoesNotAccessMemory,
+  /* ptx_read_nwarpid */ DoesNotAccessMemory,
+  /* ptx_read_pm0 */ DoesNotAccessMemory,
+  /* ptx_read_pm1 */ DoesNotAccessMemory,
+  /* ptx_read_pm2 */ DoesNotAccessMemory,
+  /* ptx_read_pm3 */ DoesNotAccessMemory,
+  /* ptx_read_smid */ DoesNotAccessMemory,
+  /* ptx_read_tid_w */ DoesNotAccessMemory,
+  /* ptx_read_tid_x */ DoesNotAccessMemory,
+  /* ptx_read_tid_y */ DoesNotAccessMemory,
+  /* ptx_read_tid_z */ DoesNotAccessMemory,
+  /* ptx_read_warpid */ DoesNotAccessMemory,
+  /* r600_read_global_size_x */ DoesNotAccessMemory,
+  /* r600_read_global_size_y */ DoesNotAccessMemory,
+  /* r600_read_global_size_z */ DoesNotAccessMemory,
+  /* r600_read_local_size_x */ DoesNotAccessMemory,
+  /* r600_read_local_size_y */ DoesNotAccessMemory,
+  /* r600_read_local_size_z */ DoesNotAccessMemory,
+  /* r600_read_ngroups_x */ DoesNotAccessMemory,
+  /* r600_read_ngroups_y */ DoesNotAccessMemory,
+  /* r600_read_ngroups_z */ DoesNotAccessMemory,
+  /* r600_read_tgid_x */ DoesNotAccessMemory,
+  /* r600_read_tgid_y */ DoesNotAccessMemory,
+  /* r600_read_tgid_z */ DoesNotAccessMemory,
+  /* r600_read_tidig_x */ DoesNotAccessMemory,
+  /* r600_read_tidig_y */ DoesNotAccessMemory,
+  /* r600_read_tidig_z */ DoesNotAccessMemory,
+  /* read_register */ DoesNotAccessMemory,
+  /* readcyclecounter */ UnknownModRefBehavior,
+  /* returnaddress */ DoesNotAccessMemory,
+  /* rint */ DoesNotAccessMemory,
+  /* round */ DoesNotAccessMemory,
+  /* sadd_with_overflow */ DoesNotAccessMemory,
+  /* setjmp */ UnknownModRefBehavior,
+  /* siglongjmp */ UnknownModRefBehavior,
+  /* sigsetjmp */ UnknownModRefBehavior,
+  /* sin */ DoesNotAccessMemory,
+  /* smul_with_overflow */ DoesNotAccessMemory,
+  /* sqrt */ DoesNotAccessMemory,
+  /* ssub_with_overflow */ DoesNotAccessMemory,
+  /* stackprotector */ UnknownModRefBehavior,
+  /* stackprotectorcheck */ OnlyAccessesArgumentPointees,
+  /* stackrestore */ UnknownModRefBehavior,
+  /* stacksave */ UnknownModRefBehavior,
+  /* trap */ UnknownModRefBehavior,
+  /* trunc */ DoesNotAccessMemory,
+  /* uadd_with_overflow */ DoesNotAccessMemory,
+  /* umul_with_overflow */ DoesNotAccessMemory,
+  /* usub_with_overflow */ DoesNotAccessMemory,
+  /* vacopy */ UnknownModRefBehavior,
+  /* vaend */ UnknownModRefBehavior,
+  /* var_annotation */ UnknownModRefBehavior,
+  /* vastart */ UnknownModRefBehavior,
+  /* write_register */ UnknownModRefBehavior,
+  /* x86_3dnow_pavgusb */ DoesNotAccessMemory,
+  /* x86_3dnow_pf2id */ DoesNotAccessMemory,
+  /* x86_3dnow_pfacc */ DoesNotAccessMemory,
+  /* x86_3dnow_pfadd */ DoesNotAccessMemory,
+  /* x86_3dnow_pfcmpeq */ DoesNotAccessMemory,
+  /* x86_3dnow_pfcmpge */ DoesNotAccessMemory,
+  /* x86_3dnow_pfcmpgt */ DoesNotAccessMemory,
+  /* x86_3dnow_pfmax */ DoesNotAccessMemory,
+  /* x86_3dnow_pfmin */ DoesNotAccessMemory,
+  /* x86_3dnow_pfmul */ DoesNotAccessMemory,
+  /* x86_3dnow_pfrcp */ DoesNotAccessMemory,
+  /* x86_3dnow_pfrcpit1 */ DoesNotAccessMemory,
+  /* x86_3dnow_pfrcpit2 */ DoesNotAccessMemory,
+  /* x86_3dnow_pfrsqit1 */ DoesNotAccessMemory,
+  /* x86_3dnow_pfrsqrt */ DoesNotAccessMemory,
+  /* x86_3dnow_pfsub */ DoesNotAccessMemory,
+  /* x86_3dnow_pfsubr */ DoesNotAccessMemory,
+  /* x86_3dnow_pi2fd */ DoesNotAccessMemory,
+  /* x86_3dnow_pmulhrw */ DoesNotAccessMemory,
+  /* x86_3dnowa_pf2iw */ DoesNotAccessMemory,
+  /* x86_3dnowa_pfnacc */ DoesNotAccessMemory,
+  /* x86_3dnowa_pfpnacc */ DoesNotAccessMemory,
+  /* x86_3dnowa_pi2fw */ DoesNotAccessMemory,
+  /* x86_3dnowa_pswapd */ DoesNotAccessMemory,
+  /* x86_aesni_aesdec */ DoesNotAccessMemory,
+  /* x86_aesni_aesdeclast */ DoesNotAccessMemory,
+  /* x86_aesni_aesenc */ DoesNotAccessMemory,
+  /* x86_aesni_aesenclast */ DoesNotAccessMemory,
+  /* x86_aesni_aesimc */ DoesNotAccessMemory,
+  /* x86_aesni_aeskeygenassist */ DoesNotAccessMemory,
+  /* x86_avx2_gather_d_d */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_d_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_pd */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_pd_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_ps */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_ps_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_q */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_d_q_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_d */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_d_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_pd */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_pd_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_ps */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_ps_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_q */ OnlyReadsArgumentPointees,
+  /* x86_avx2_gather_q_q_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_maskload_d */ OnlyReadsArgumentPointees,
+  /* x86_avx2_maskload_d_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_maskload_q */ OnlyReadsArgumentPointees,
+  /* x86_avx2_maskload_q_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_maskstore_d */ OnlyAccessesArgumentPointees,
+  /* x86_avx2_maskstore_d_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx2_maskstore_q */ OnlyAccessesArgumentPointees,
+  /* x86_avx2_maskstore_q_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx2_movntdqa */ OnlyReadsMemory,
+  /* x86_avx2_mpsadbw */ DoesNotAccessMemory,
+  /* x86_avx2_pabs_b */ DoesNotAccessMemory,
+  /* x86_avx2_pabs_d */ DoesNotAccessMemory,
+  /* x86_avx2_pabs_w */ DoesNotAccessMemory,
+  /* x86_avx2_packssdw */ DoesNotAccessMemory,
+  /* x86_avx2_packsswb */ DoesNotAccessMemory,
+  /* x86_avx2_packusdw */ DoesNotAccessMemory,
+  /* x86_avx2_packuswb */ DoesNotAccessMemory,
+  /* x86_avx2_padds_b */ DoesNotAccessMemory,
+  /* x86_avx2_padds_w */ DoesNotAccessMemory,
+  /* x86_avx2_paddus_b */ DoesNotAccessMemory,
+  /* x86_avx2_paddus_w */ DoesNotAccessMemory,
+  /* x86_avx2_pavg_b */ DoesNotAccessMemory,
+  /* x86_avx2_pavg_w */ DoesNotAccessMemory,
+  /* x86_avx2_pblendd_128 */ DoesNotAccessMemory,
+  /* x86_avx2_pblendd_256 */ DoesNotAccessMemory,
+  /* x86_avx2_pblendvb */ DoesNotAccessMemory,
+  /* x86_avx2_pblendw */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastb_128 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastb_256 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastd_128 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastd_256 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastq_128 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastq_256 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastw_128 */ DoesNotAccessMemory,
+  /* x86_avx2_pbroadcastw_256 */ DoesNotAccessMemory,
+  /* x86_avx2_permd */ DoesNotAccessMemory,
+  /* x86_avx2_permps */ DoesNotAccessMemory,
+  /* x86_avx2_phadd_d */ DoesNotAccessMemory,
+  /* x86_avx2_phadd_sw */ DoesNotAccessMemory,
+  /* x86_avx2_phadd_w */ DoesNotAccessMemory,
+  /* x86_avx2_phsub_d */ DoesNotAccessMemory,
+  /* x86_avx2_phsub_sw */ DoesNotAccessMemory,
+  /* x86_avx2_phsub_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmadd_ub_sw */ DoesNotAccessMemory,
+  /* x86_avx2_pmadd_wd */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxs_b */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxs_d */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxs_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxu_b */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxu_d */ DoesNotAccessMemory,
+  /* x86_avx2_pmaxu_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmins_b */ DoesNotAccessMemory,
+  /* x86_avx2_pmins_d */ DoesNotAccessMemory,
+  /* x86_avx2_pmins_w */ DoesNotAccessMemory,
+  /* x86_avx2_pminu_b */ DoesNotAccessMemory,
+  /* x86_avx2_pminu_d */ DoesNotAccessMemory,
+  /* x86_avx2_pminu_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmovmskb */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxbd */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxbq */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxbw */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxdq */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxwd */ DoesNotAccessMemory,
+  /* x86_avx2_pmovsxwq */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxbd */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxbq */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxbw */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxdq */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxwd */ DoesNotAccessMemory,
+  /* x86_avx2_pmovzxwq */ DoesNotAccessMemory,
+  /* x86_avx2_pmul_dq */ DoesNotAccessMemory,
+  /* x86_avx2_pmul_hr_sw */ DoesNotAccessMemory,
+  /* x86_avx2_pmulh_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmulhu_w */ DoesNotAccessMemory,
+  /* x86_avx2_pmulu_dq */ DoesNotAccessMemory,
+  /* x86_avx2_psad_bw */ DoesNotAccessMemory,
+  /* x86_avx2_pshuf_b */ DoesNotAccessMemory,
+  /* x86_avx2_psign_b */ DoesNotAccessMemory,
+  /* x86_avx2_psign_d */ DoesNotAccessMemory,
+  /* x86_avx2_psign_w */ DoesNotAccessMemory,
+  /* x86_avx2_psll_d */ DoesNotAccessMemory,
+  /* x86_avx2_psll_dq */ DoesNotAccessMemory,
+  /* x86_avx2_psll_dq_bs */ DoesNotAccessMemory,
+  /* x86_avx2_psll_q */ DoesNotAccessMemory,
+  /* x86_avx2_psll_w */ DoesNotAccessMemory,
+  /* x86_avx2_pslli_d */ DoesNotAccessMemory,
+  /* x86_avx2_pslli_q */ DoesNotAccessMemory,
+  /* x86_avx2_pslli_w */ DoesNotAccessMemory,
+  /* x86_avx2_psllv_d */ DoesNotAccessMemory,
+  /* x86_avx2_psllv_d_256 */ DoesNotAccessMemory,
+  /* x86_avx2_psllv_q */ DoesNotAccessMemory,
+  /* x86_avx2_psllv_q_256 */ DoesNotAccessMemory,
+  /* x86_avx2_psra_d */ DoesNotAccessMemory,
+  /* x86_avx2_psra_w */ DoesNotAccessMemory,
+  /* x86_avx2_psrai_d */ DoesNotAccessMemory,
+  /* x86_avx2_psrai_w */ DoesNotAccessMemory,
+  /* x86_avx2_psrav_d */ DoesNotAccessMemory,
+  /* x86_avx2_psrav_d_256 */ DoesNotAccessMemory,
+  /* x86_avx2_psrl_d */ DoesNotAccessMemory,
+  /* x86_avx2_psrl_dq */ DoesNotAccessMemory,
+  /* x86_avx2_psrl_dq_bs */ DoesNotAccessMemory,
+  /* x86_avx2_psrl_q */ DoesNotAccessMemory,
+  /* x86_avx2_psrl_w */ DoesNotAccessMemory,
+  /* x86_avx2_psrli_d */ DoesNotAccessMemory,
+  /* x86_avx2_psrli_q */ DoesNotAccessMemory,
+  /* x86_avx2_psrli_w */ DoesNotAccessMemory,
+  /* x86_avx2_psrlv_d */ DoesNotAccessMemory,
+  /* x86_avx2_psrlv_d_256 */ DoesNotAccessMemory,
+  /* x86_avx2_psrlv_q */ DoesNotAccessMemory,
+  /* x86_avx2_psrlv_q_256 */ DoesNotAccessMemory,
+  /* x86_avx2_psubs_b */ DoesNotAccessMemory,
+  /* x86_avx2_psubs_w */ DoesNotAccessMemory,
+  /* x86_avx2_psubus_b */ DoesNotAccessMemory,
+  /* x86_avx2_psubus_w */ DoesNotAccessMemory,
+  /* x86_avx2_vbroadcast_sd_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx2_vbroadcast_ss_ps */ DoesNotAccessMemory,
+  /* x86_avx2_vbroadcast_ss_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx2_vbroadcasti128 */ OnlyReadsArgumentPointees,
+  /* x86_avx2_vextracti128 */ DoesNotAccessMemory,
+  /* x86_avx2_vinserti128 */ DoesNotAccessMemory,
+  /* x86_avx2_vperm2i128 */ DoesNotAccessMemory,
+  /* x86_avx512_cvtsd2usi */ DoesNotAccessMemory,
+  /* x86_avx512_cvtsd2usi64 */ DoesNotAccessMemory,
+  /* x86_avx512_cvtss2usi */ DoesNotAccessMemory,
+  /* x86_avx512_cvtss2usi64 */ DoesNotAccessMemory,
+  /* x86_avx512_cvttsd2usi */ DoesNotAccessMemory,
+  /* x86_avx512_cvttsd2usi64 */ DoesNotAccessMemory,
+  /* x86_avx512_cvttss2usi */ DoesNotAccessMemory,
+  /* x86_avx512_cvttss2usi64 */ DoesNotAccessMemory,
+  /* x86_avx512_cvtusi2sd */ DoesNotAccessMemory,
+  /* x86_avx512_cvtusi2ss */ DoesNotAccessMemory,
+  /* x86_avx512_cvtusi642sd */ DoesNotAccessMemory,
+  /* x86_avx512_cvtusi642ss */ DoesNotAccessMemory,
+  /* x86_avx512_gather_dpd_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_dpi_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_dpq_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_dps_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_qpd_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_qpi_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_qpq_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gather_qps_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_gatherpf_dpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_gatherpf_dps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_gatherpf_qpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_gatherpf_qps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_kand_w */ DoesNotAccessMemory,
+  /* x86_avx512_kandn_w */ DoesNotAccessMemory,
+  /* x86_avx512_knot_w */ DoesNotAccessMemory,
+  /* x86_avx512_kor_w */ DoesNotAccessMemory,
+  /* x86_avx512_kortestc_w */ DoesNotAccessMemory,
+  /* x86_avx512_kortestz_w */ DoesNotAccessMemory,
+  /* x86_avx512_kunpck_bw */ DoesNotAccessMemory,
+  /* x86_avx512_kxnor_w */ DoesNotAccessMemory,
+  /* x86_avx512_kxor_w */ DoesNotAccessMemory,
+  /* x86_avx512_mask_blend_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_blend_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_blend_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_blend_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cmp_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cmp_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_conflict_d_512 */ UnknownModRefBehavior,
+  /* x86_avx512_mask_conflict_q_512 */ UnknownModRefBehavior,
+  /* x86_avx512_mask_cvtdq2pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtdq2ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtpd2dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtpd2ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtpd2udq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtps2dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtps2udq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvttpd2dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvttpd2udq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvttps2dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvttps2udq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtudq2pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_cvtudq2ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_loadu_d_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_mask_loadu_pd_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_mask_loadu_ps_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_mask_loadu_q_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_mask_lzcnt_d_512 */ UnknownModRefBehavior,
+  /* x86_avx512_mask_lzcnt_q_512 */ UnknownModRefBehavior,
+  /* x86_avx512_mask_max_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_max_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_min_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_min_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pabs_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pabs_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pand_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pand_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pbroadcast_d_gpr_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pbroadcast_q_gpr_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pbroadcast_q_mem_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pcmpeq_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pcmpeq_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmaxs_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmaxs_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmaxu_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmaxu_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmins_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmins_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pminu_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pminu_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmul_dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_pmulu_dq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_ptestm_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_ptestm_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_rndscale_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_rndscale_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_storeu_d_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_mask_storeu_pd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_mask_storeu_ps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_mask_storeu_q_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_mask_vcvtph2ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_vcvtps2ph_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_vpermt_d_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_vpermt_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_vpermt_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_mask_vpermt_q_512 */ DoesNotAccessMemory,
+  /* x86_avx512_movntdqa */ OnlyReadsMemory,
+  /* x86_avx512_pbroadcastd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_pbroadcastd_i32_512 */ DoesNotAccessMemory,
+  /* x86_avx512_pbroadcastq_512 */ DoesNotAccessMemory,
+  /* x86_avx512_pbroadcastq_i64_512 */ DoesNotAccessMemory,
+  /* x86_avx512_pmovzxbd */ DoesNotAccessMemory,
+  /* x86_avx512_pmovzxbq */ DoesNotAccessMemory,
+  /* x86_avx512_pmovzxdq */ DoesNotAccessMemory,
+  /* x86_avx512_pmovzxwd */ DoesNotAccessMemory,
+  /* x86_avx512_pmovzxwq */ DoesNotAccessMemory,
+  /* x86_avx512_psll_dq */ DoesNotAccessMemory,
+  /* x86_avx512_psll_dq_bs */ DoesNotAccessMemory,
+  /* x86_avx512_psrl_dq */ DoesNotAccessMemory,
+  /* x86_avx512_psrl_dq_bs */ DoesNotAccessMemory,
+  /* x86_avx512_rcp14_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_rcp14_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_rcp14_sd */ DoesNotAccessMemory,
+  /* x86_avx512_rcp14_ss */ DoesNotAccessMemory,
+  /* x86_avx512_rcp28_pd */ DoesNotAccessMemory,
+  /* x86_avx512_rcp28_ps */ DoesNotAccessMemory,
+  /* x86_avx512_rcp28_sd */ DoesNotAccessMemory,
+  /* x86_avx512_rcp28_ss */ DoesNotAccessMemory,
+  /* x86_avx512_rndscale_sd */ DoesNotAccessMemory,
+  /* x86_avx512_rndscale_ss */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt14_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt14_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt14_sd */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt14_ss */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt28_pd */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt28_ps */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt28_sd */ DoesNotAccessMemory,
+  /* x86_avx512_rsqrt28_ss */ DoesNotAccessMemory,
+  /* x86_avx512_scatter_dpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_dpi_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_dpq_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_dps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_qpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_qpi_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_qpq_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatter_qps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatterpf_dpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatterpf_dps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatterpf_qpd_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_scatterpf_qps_512 */ OnlyAccessesArgumentPointees,
+  /* x86_avx512_sqrt_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_sqrt_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx512_sqrt_sd */ DoesNotAccessMemory,
+  /* x86_avx512_sqrt_ss */ DoesNotAccessMemory,
+  /* x86_avx512_vbroadcast_sd_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_vbroadcast_sd_pd_512 */ DoesNotAccessMemory,
+  /* x86_avx512_vbroadcast_ss_512 */ OnlyReadsArgumentPointees,
+  /* x86_avx512_vbroadcast_ss_ps_512 */ DoesNotAccessMemory,
+  /* x86_avx_addsub_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_addsub_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_blend_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_blend_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_blendv_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_blendv_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_cmp_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_cmp_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvt_pd2_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvt_pd2dq_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvt_ps2_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvt_ps2dq_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvtdq2_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvtdq2_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvtt_pd2dq_256 */ DoesNotAccessMemory,
+  /* x86_avx_cvtt_ps2dq_256 */ DoesNotAccessMemory,
+  /* x86_avx_dp_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_hadd_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_hadd_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_hsub_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_hsub_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_ldu_dq_256 */ OnlyReadsMemory,
+  /* x86_avx_maskload_pd */ OnlyReadsArgumentPointees,
+  /* x86_avx_maskload_pd_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx_maskload_ps */ OnlyReadsArgumentPointees,
+  /* x86_avx_maskload_ps_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx_maskstore_pd */ OnlyAccessesArgumentPointees,
+  /* x86_avx_maskstore_pd_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx_maskstore_ps */ OnlyAccessesArgumentPointees,
+  /* x86_avx_maskstore_ps_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx_max_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_max_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_min_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_min_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_movmsk_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_movmsk_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_ptestc_256 */ DoesNotAccessMemory,
+  /* x86_avx_ptestnzc_256 */ DoesNotAccessMemory,
+  /* x86_avx_ptestz_256 */ DoesNotAccessMemory,
+  /* x86_avx_rcp_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_round_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_round_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_rsqrt_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_sqrt_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_sqrt_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_storeu_dq_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx_storeu_pd_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx_storeu_ps_256 */ OnlyAccessesArgumentPointees,
+  /* x86_avx_vbroadcastf128_pd_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx_vbroadcastf128_ps_256 */ OnlyReadsArgumentPointees,
+  /* x86_avx_vextractf128_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vextractf128_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vextractf128_si_256 */ DoesNotAccessMemory,
+  /* x86_avx_vinsertf128_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vinsertf128_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vinsertf128_si_256 */ DoesNotAccessMemory,
+  /* x86_avx_vperm2f128_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vperm2f128_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vperm2f128_si_256 */ DoesNotAccessMemory,
+  /* x86_avx_vpermilvar_pd */ DoesNotAccessMemory,
+  /* x86_avx_vpermilvar_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vpermilvar_ps */ DoesNotAccessMemory,
+  /* x86_avx_vpermilvar_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestc_pd */ DoesNotAccessMemory,
+  /* x86_avx_vtestc_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestc_ps */ DoesNotAccessMemory,
+  /* x86_avx_vtestc_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestnzc_pd */ DoesNotAccessMemory,
+  /* x86_avx_vtestnzc_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestnzc_ps */ DoesNotAccessMemory,
+  /* x86_avx_vtestnzc_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestz_pd */ DoesNotAccessMemory,
+  /* x86_avx_vtestz_pd_256 */ DoesNotAccessMemory,
+  /* x86_avx_vtestz_ps */ DoesNotAccessMemory,
+  /* x86_avx_vtestz_ps_256 */ DoesNotAccessMemory,
+  /* x86_avx_vzeroall */ UnknownModRefBehavior,
+  /* x86_avx_vzeroupper */ UnknownModRefBehavior,
+  /* x86_bmi_bextr_32 */ DoesNotAccessMemory,
+  /* x86_bmi_bextr_64 */ DoesNotAccessMemory,
+  /* x86_bmi_bzhi_32 */ DoesNotAccessMemory,
+  /* x86_bmi_bzhi_64 */ DoesNotAccessMemory,
+  /* x86_bmi_pdep_32 */ DoesNotAccessMemory,
+  /* x86_bmi_pdep_64 */ DoesNotAccessMemory,
+  /* x86_bmi_pext_32 */ DoesNotAccessMemory,
+  /* x86_bmi_pext_64 */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_sd */ DoesNotAccessMemory,
+  /* x86_fma_vfmadd_ss */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmaddsub_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_sd */ DoesNotAccessMemory,
+  /* x86_fma_vfmsub_ss */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfmsubadd_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_sd */ DoesNotAccessMemory,
+  /* x86_fma_vfnmadd_ss */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_pd */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_pd_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_pd_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_ps */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_ps_256 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_ps_512 */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_sd */ DoesNotAccessMemory,
+  /* x86_fma_vfnmsub_ss */ DoesNotAccessMemory,
+  /* x86_int */ UnknownModRefBehavior,
+  /* x86_mmx_emms */ UnknownModRefBehavior,
+  /* x86_mmx_femms */ UnknownModRefBehavior,
+  /* x86_mmx_maskmovq */ UnknownModRefBehavior,
+  /* x86_mmx_movnt_dq */ UnknownModRefBehavior,
+  /* x86_mmx_packssdw */ DoesNotAccessMemory,
+  /* x86_mmx_packsswb */ DoesNotAccessMemory,
+  /* x86_mmx_packuswb */ DoesNotAccessMemory,
+  /* x86_mmx_padd_b */ DoesNotAccessMemory,
+  /* x86_mmx_padd_d */ DoesNotAccessMemory,
+  /* x86_mmx_padd_q */ DoesNotAccessMemory,
+  /* x86_mmx_padd_w */ DoesNotAccessMemory,
+  /* x86_mmx_padds_b */ DoesNotAccessMemory,
+  /* x86_mmx_padds_w */ DoesNotAccessMemory,
+  /* x86_mmx_paddus_b */ DoesNotAccessMemory,
+  /* x86_mmx_paddus_w */ DoesNotAccessMemory,
+  /* x86_mmx_palignr_b */ DoesNotAccessMemory,
+  /* x86_mmx_pand */ DoesNotAccessMemory,
+  /* x86_mmx_pandn */ DoesNotAccessMemory,
+  /* x86_mmx_pavg_b */ DoesNotAccessMemory,
+  /* x86_mmx_pavg_w */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpeq_b */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpeq_d */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpeq_w */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpgt_b */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpgt_d */ DoesNotAccessMemory,
+  /* x86_mmx_pcmpgt_w */ DoesNotAccessMemory,
+  /* x86_mmx_pextr_w */ DoesNotAccessMemory,
+  /* x86_mmx_pinsr_w */ DoesNotAccessMemory,
+  /* x86_mmx_pmadd_wd */ DoesNotAccessMemory,
+  /* x86_mmx_pmaxs_w */ DoesNotAccessMemory,
+  /* x86_mmx_pmaxu_b */ DoesNotAccessMemory,
+  /* x86_mmx_pmins_w */ DoesNotAccessMemory,
+  /* x86_mmx_pminu_b */ DoesNotAccessMemory,
+  /* x86_mmx_pmovmskb */ DoesNotAccessMemory,
+  /* x86_mmx_pmulh_w */ DoesNotAccessMemory,
+  /* x86_mmx_pmulhu_w */ DoesNotAccessMemory,
+  /* x86_mmx_pmull_w */ DoesNotAccessMemory,
+  /* x86_mmx_pmulu_dq */ DoesNotAccessMemory,
+  /* x86_mmx_por */ DoesNotAccessMemory,
+  /* x86_mmx_psad_bw */ DoesNotAccessMemory,
+  /* x86_mmx_psll_d */ DoesNotAccessMemory,
+  /* x86_mmx_psll_q */ DoesNotAccessMemory,
+  /* x86_mmx_psll_w */ DoesNotAccessMemory,
+  /* x86_mmx_pslli_d */ DoesNotAccessMemory,
+  /* x86_mmx_pslli_q */ DoesNotAccessMemory,
+  /* x86_mmx_pslli_w */ DoesNotAccessMemory,
+  /* x86_mmx_psra_d */ DoesNotAccessMemory,
+  /* x86_mmx_psra_w */ DoesNotAccessMemory,
+  /* x86_mmx_psrai_d */ DoesNotAccessMemory,
+  /* x86_mmx_psrai_w */ DoesNotAccessMemory,
+  /* x86_mmx_psrl_d */ DoesNotAccessMemory,
+  /* x86_mmx_psrl_q */ DoesNotAccessMemory,
+  /* x86_mmx_psrl_w */ DoesNotAccessMemory,
+  /* x86_mmx_psrli_d */ DoesNotAccessMemory,
+  /* x86_mmx_psrli_q */ DoesNotAccessMemory,
+  /* x86_mmx_psrli_w */ DoesNotAccessMemory,
+  /* x86_mmx_psub_b */ DoesNotAccessMemory,
+  /* x86_mmx_psub_d */ DoesNotAccessMemory,
+  /* x86_mmx_psub_q */ DoesNotAccessMemory,
+  /* x86_mmx_psub_w */ DoesNotAccessMemory,
+  /* x86_mmx_psubs_b */ DoesNotAccessMemory,
+  /* x86_mmx_psubs_w */ DoesNotAccessMemory,
+  /* x86_mmx_psubus_b */ DoesNotAccessMemory,
+  /* x86_mmx_psubus_w */ DoesNotAccessMemory,
+  /* x86_mmx_punpckhbw */ DoesNotAccessMemory,
+  /* x86_mmx_punpckhdq */ DoesNotAccessMemory,
+  /* x86_mmx_punpckhwd */ DoesNotAccessMemory,
+  /* x86_mmx_punpcklbw */ DoesNotAccessMemory,
+  /* x86_mmx_punpckldq */ DoesNotAccessMemory,
+  /* x86_mmx_punpcklwd */ DoesNotAccessMemory,
+  /* x86_mmx_pxor */ DoesNotAccessMemory,
+  /* x86_pclmulqdq */ DoesNotAccessMemory,
+  /* x86_rdfsbase_32 */ UnknownModRefBehavior,
+  /* x86_rdfsbase_64 */ UnknownModRefBehavior,
+  /* x86_rdgsbase_32 */ UnknownModRefBehavior,
+  /* x86_rdgsbase_64 */ UnknownModRefBehavior,
+  /* x86_rdpmc */ UnknownModRefBehavior,
+  /* x86_rdrand_16 */ UnknownModRefBehavior,
+  /* x86_rdrand_32 */ UnknownModRefBehavior,
+  /* x86_rdrand_64 */ UnknownModRefBehavior,
+  /* x86_rdseed_16 */ UnknownModRefBehavior,
+  /* x86_rdseed_32 */ UnknownModRefBehavior,
+  /* x86_rdseed_64 */ UnknownModRefBehavior,
+  /* x86_rdtsc */ UnknownModRefBehavior,
+  /* x86_rdtscp */ OnlyAccessesArgumentPointees,
+  /* x86_sha1msg1 */ DoesNotAccessMemory,
+  /* x86_sha1msg2 */ DoesNotAccessMemory,
+  /* x86_sha1nexte */ DoesNotAccessMemory,
+  /* x86_sha1rnds4 */ DoesNotAccessMemory,
+  /* x86_sha256msg1 */ DoesNotAccessMemory,
+  /* x86_sha256msg2 */ DoesNotAccessMemory,
+  /* x86_sha256rnds2 */ DoesNotAccessMemory,
+  /* x86_sse2_add_sd */ DoesNotAccessMemory,
+  /* x86_sse2_clflush */ UnknownModRefBehavior,
+  /* x86_sse2_cmp_pd */ DoesNotAccessMemory,
+  /* x86_sse2_cmp_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comieq_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comige_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comigt_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comile_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comilt_sd */ DoesNotAccessMemory,
+  /* x86_sse2_comineq_sd */ DoesNotAccessMemory,
+  /* x86_sse2_cvtdq2pd */ DoesNotAccessMemory,
+  /* x86_sse2_cvtdq2ps */ DoesNotAccessMemory,
+  /* x86_sse2_cvtpd2dq */ DoesNotAccessMemory,
+  /* x86_sse2_cvtpd2ps */ DoesNotAccessMemory,
+  /* x86_sse2_cvtps2dq */ DoesNotAccessMemory,
+  /* x86_sse2_cvtps2pd */ DoesNotAccessMemory,
+  /* x86_sse2_cvtsd2si */ DoesNotAccessMemory,
+  /* x86_sse2_cvtsd2si64 */ DoesNotAccessMemory,
+  /* x86_sse2_cvtsd2ss */ DoesNotAccessMemory,
+  /* x86_sse2_cvtsi2sd */ DoesNotAccessMemory,
+  /* x86_sse2_cvtsi642sd */ DoesNotAccessMemory,
+  /* x86_sse2_cvtss2sd */ DoesNotAccessMemory,
+  /* x86_sse2_cvttpd2dq */ DoesNotAccessMemory,
+  /* x86_sse2_cvttps2dq */ DoesNotAccessMemory,
+  /* x86_sse2_cvttsd2si */ DoesNotAccessMemory,
+  /* x86_sse2_cvttsd2si64 */ DoesNotAccessMemory,
+  /* x86_sse2_div_sd */ DoesNotAccessMemory,
+  /* x86_sse2_lfence */ UnknownModRefBehavior,
+  /* x86_sse2_maskmov_dqu */ UnknownModRefBehavior,
+  /* x86_sse2_max_pd */ DoesNotAccessMemory,
+  /* x86_sse2_max_sd */ DoesNotAccessMemory,
+  /* x86_sse2_mfence */ UnknownModRefBehavior,
+  /* x86_sse2_min_pd */ DoesNotAccessMemory,
+  /* x86_sse2_min_sd */ DoesNotAccessMemory,
+  /* x86_sse2_movmsk_pd */ DoesNotAccessMemory,
+  /* x86_sse2_mul_sd */ DoesNotAccessMemory,
+  /* x86_sse2_packssdw_128 */ DoesNotAccessMemory,
+  /* x86_sse2_packsswb_128 */ DoesNotAccessMemory,
+  /* x86_sse2_packuswb_128 */ DoesNotAccessMemory,
+  /* x86_sse2_padds_b */ DoesNotAccessMemory,
+  /* x86_sse2_padds_w */ DoesNotAccessMemory,
+  /* x86_sse2_paddus_b */ DoesNotAccessMemory,
+  /* x86_sse2_paddus_w */ DoesNotAccessMemory,
+  /* x86_sse2_pause */ UnknownModRefBehavior,
+  /* x86_sse2_pavg_b */ DoesNotAccessMemory,
+  /* x86_sse2_pavg_w */ DoesNotAccessMemory,
+  /* x86_sse2_pmadd_wd */ DoesNotAccessMemory,
+  /* x86_sse2_pmaxs_w */ DoesNotAccessMemory,
+  /* x86_sse2_pmaxu_b */ DoesNotAccessMemory,
+  /* x86_sse2_pmins_w */ DoesNotAccessMemory,
+  /* x86_sse2_pminu_b */ DoesNotAccessMemory,
+  /* x86_sse2_pmovmskb_128 */ DoesNotAccessMemory,
+  /* x86_sse2_pmulh_w */ DoesNotAccessMemory,
+  /* x86_sse2_pmulhu_w */ DoesNotAccessMemory,
+  /* x86_sse2_pmulu_dq */ DoesNotAccessMemory,
+  /* x86_sse2_psad_bw */ DoesNotAccessMemory,
+  /* x86_sse2_pshuf_d */ DoesNotAccessMemory,
+  /* x86_sse2_pshufh_w */ DoesNotAccessMemory,
+  /* x86_sse2_pshufl_w */ DoesNotAccessMemory,
+  /* x86_sse2_psll_d */ DoesNotAccessMemory,
+  /* x86_sse2_psll_dq */ DoesNotAccessMemory,
+  /* x86_sse2_psll_dq_bs */ DoesNotAccessMemory,
+  /* x86_sse2_psll_q */ DoesNotAccessMemory,
+  /* x86_sse2_psll_w */ DoesNotAccessMemory,
+  /* x86_sse2_pslli_d */ DoesNotAccessMemory,
+  /* x86_sse2_pslli_q */ DoesNotAccessMemory,
+  /* x86_sse2_pslli_w */ DoesNotAccessMemory,
+  /* x86_sse2_psra_d */ DoesNotAccessMemory,
+  /* x86_sse2_psra_w */ DoesNotAccessMemory,
+  /* x86_sse2_psrai_d */ DoesNotAccessMemory,
+  /* x86_sse2_psrai_w */ DoesNotAccessMemory,
+  /* x86_sse2_psrl_d */ DoesNotAccessMemory,
+  /* x86_sse2_psrl_dq */ DoesNotAccessMemory,
+  /* x86_sse2_psrl_dq_bs */ DoesNotAccessMemory,
+  /* x86_sse2_psrl_q */ DoesNotAccessMemory,
+  /* x86_sse2_psrl_w */ DoesNotAccessMemory,
+  /* x86_sse2_psrli_d */ DoesNotAccessMemory,
+  /* x86_sse2_psrli_q */ DoesNotAccessMemory,
+  /* x86_sse2_psrli_w */ DoesNotAccessMemory,
+  /* x86_sse2_psubs_b */ DoesNotAccessMemory,
+  /* x86_sse2_psubs_w */ DoesNotAccessMemory,
+  /* x86_sse2_psubus_b */ DoesNotAccessMemory,
+  /* x86_sse2_psubus_w */ DoesNotAccessMemory,
+  /* x86_sse2_sqrt_pd */ DoesNotAccessMemory,
+  /* x86_sse2_sqrt_sd */ DoesNotAccessMemory,
+  /* x86_sse2_storel_dq */ OnlyAccessesArgumentPointees,
+  /* x86_sse2_storeu_dq */ OnlyAccessesArgumentPointees,
+  /* x86_sse2_storeu_pd */ OnlyAccessesArgumentPointees,
+  /* x86_sse2_sub_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomieq_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomige_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomigt_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomile_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomilt_sd */ DoesNotAccessMemory,
+  /* x86_sse2_ucomineq_sd */ DoesNotAccessMemory,
+  /* x86_sse3_addsub_pd */ DoesNotAccessMemory,
+  /* x86_sse3_addsub_ps */ DoesNotAccessMemory,
+  /* x86_sse3_hadd_pd */ DoesNotAccessMemory,
+  /* x86_sse3_hadd_ps */ DoesNotAccessMemory,
+  /* x86_sse3_hsub_pd */ DoesNotAccessMemory,
+  /* x86_sse3_hsub_ps */ DoesNotAccessMemory,
+  /* x86_sse3_ldu_dq */ OnlyReadsMemory,
+  /* x86_sse3_monitor */ UnknownModRefBehavior,
+  /* x86_sse3_mwait */ UnknownModRefBehavior,
+  /* x86_sse41_blendpd */ DoesNotAccessMemory,
+  /* x86_sse41_blendps */ DoesNotAccessMemory,
+  /* x86_sse41_blendvpd */ DoesNotAccessMemory,
+  /* x86_sse41_blendvps */ DoesNotAccessMemory,
+  /* x86_sse41_dppd */ DoesNotAccessMemory,
+  /* x86_sse41_dpps */ DoesNotAccessMemory,
+  /* x86_sse41_extractps */ DoesNotAccessMemory,
+  /* x86_sse41_insertps */ DoesNotAccessMemory,
+  /* x86_sse41_movntdqa */ OnlyReadsMemory,
+  /* x86_sse41_mpsadbw */ DoesNotAccessMemory,
+  /* x86_sse41_packusdw */ DoesNotAccessMemory,
+  /* x86_sse41_pblendvb */ DoesNotAccessMemory,
+  /* x86_sse41_pblendw */ DoesNotAccessMemory,
+  /* x86_sse41_pextrb */ DoesNotAccessMemory,
+  /* x86_sse41_pextrd */ DoesNotAccessMemory,
+  /* x86_sse41_pextrq */ DoesNotAccessMemory,
+  /* x86_sse41_phminposuw */ DoesNotAccessMemory,
+  /* x86_sse41_pmaxsb */ DoesNotAccessMemory,
+  /* x86_sse41_pmaxsd */ DoesNotAccessMemory,
+  /* x86_sse41_pmaxud */ DoesNotAccessMemory,
+  /* x86_sse41_pmaxuw */ DoesNotAccessMemory,
+  /* x86_sse41_pminsb */ DoesNotAccessMemory,
+  /* x86_sse41_pminsd */ DoesNotAccessMemory,
+  /* x86_sse41_pminud */ DoesNotAccessMemory,
+  /* x86_sse41_pminuw */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxbd */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxbq */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxbw */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxdq */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxwd */ DoesNotAccessMemory,
+  /* x86_sse41_pmovsxwq */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxbd */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxbq */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxbw */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxdq */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxwd */ DoesNotAccessMemory,
+  /* x86_sse41_pmovzxwq */ DoesNotAccessMemory,
+  /* x86_sse41_pmuldq */ DoesNotAccessMemory,
+  /* x86_sse41_ptestc */ DoesNotAccessMemory,
+  /* x86_sse41_ptestnzc */ DoesNotAccessMemory,
+  /* x86_sse41_ptestz */ DoesNotAccessMemory,
+  /* x86_sse41_round_pd */ DoesNotAccessMemory,
+  /* x86_sse41_round_ps */ DoesNotAccessMemory,
+  /* x86_sse41_round_sd */ DoesNotAccessMemory,
+  /* x86_sse41_round_ss */ DoesNotAccessMemory,
+  /* x86_sse42_crc32_32_16 */ DoesNotAccessMemory,
+  /* x86_sse42_crc32_32_32 */ DoesNotAccessMemory,
+  /* x86_sse42_crc32_32_8 */ DoesNotAccessMemory,
+  /* x86_sse42_crc32_64_64 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestri128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestria128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestric128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestrio128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestris128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestriz128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpestrm128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistri128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistria128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistric128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistrio128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistris128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistriz128 */ DoesNotAccessMemory,
+  /* x86_sse42_pcmpistrm128 */ DoesNotAccessMemory,
+  /* x86_sse4a_extrq */ DoesNotAccessMemory,
+  /* x86_sse4a_extrqi */ DoesNotAccessMemory,
+  /* x86_sse4a_insertq */ DoesNotAccessMemory,
+  /* x86_sse4a_insertqi */ DoesNotAccessMemory,
+  /* x86_sse4a_movnt_sd */ UnknownModRefBehavior,
+  /* x86_sse4a_movnt_ss */ UnknownModRefBehavior,
+  /* x86_sse_add_ss */ DoesNotAccessMemory,
+  /* x86_sse_cmp_ps */ DoesNotAccessMemory,
+  /* x86_sse_cmp_ss */ DoesNotAccessMemory,
+  /* x86_sse_comieq_ss */ DoesNotAccessMemory,
+  /* x86_sse_comige_ss */ DoesNotAccessMemory,
+  /* x86_sse_comigt_ss */ DoesNotAccessMemory,
+  /* x86_sse_comile_ss */ DoesNotAccessMemory,
+  /* x86_sse_comilt_ss */ DoesNotAccessMemory,
+  /* x86_sse_comineq_ss */ DoesNotAccessMemory,
+  /* x86_sse_cvtpd2pi */ DoesNotAccessMemory,
+  /* x86_sse_cvtpi2pd */ DoesNotAccessMemory,
+  /* x86_sse_cvtpi2ps */ DoesNotAccessMemory,
+  /* x86_sse_cvtps2pi */ DoesNotAccessMemory,
+  /* x86_sse_cvtsi2ss */ DoesNotAccessMemory,
+  /* x86_sse_cvtsi642ss */ DoesNotAccessMemory,
+  /* x86_sse_cvtss2si */ DoesNotAccessMemory,
+  /* x86_sse_cvtss2si64 */ DoesNotAccessMemory,
+  /* x86_sse_cvttpd2pi */ DoesNotAccessMemory,
+  /* x86_sse_cvttps2pi */ DoesNotAccessMemory,
+  /* x86_sse_cvttss2si */ DoesNotAccessMemory,
+  /* x86_sse_cvttss2si64 */ DoesNotAccessMemory,
+  /* x86_sse_div_ss */ DoesNotAccessMemory,
+  /* x86_sse_ldmxcsr */ UnknownModRefBehavior,
+  /* x86_sse_max_ps */ DoesNotAccessMemory,
+  /* x86_sse_max_ss */ DoesNotAccessMemory,
+  /* x86_sse_min_ps */ DoesNotAccessMemory,
+  /* x86_sse_min_ss */ DoesNotAccessMemory,
+  /* x86_sse_movmsk_ps */ DoesNotAccessMemory,
+  /* x86_sse_mul_ss */ DoesNotAccessMemory,
+  /* x86_sse_pshuf_w */ DoesNotAccessMemory,
+  /* x86_sse_rcp_ps */ DoesNotAccessMemory,
+  /* x86_sse_rcp_ss */ DoesNotAccessMemory,
+  /* x86_sse_rsqrt_ps */ DoesNotAccessMemory,
+  /* x86_sse_rsqrt_ss */ DoesNotAccessMemory,
+  /* x86_sse_sfence */ UnknownModRefBehavior,
+  /* x86_sse_sqrt_ps */ DoesNotAccessMemory,
+  /* x86_sse_sqrt_ss */ DoesNotAccessMemory,
+  /* x86_sse_stmxcsr */ UnknownModRefBehavior,
+  /* x86_sse_storeu_ps */ OnlyAccessesArgumentPointees,
+  /* x86_sse_sub_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomieq_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomige_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomigt_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomile_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomilt_ss */ DoesNotAccessMemory,
+  /* x86_sse_ucomineq_ss */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_b */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_b_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_d */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_d_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_w */ DoesNotAccessMemory,
+  /* x86_ssse3_pabs_w_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_d */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_d_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_sw */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_sw_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_w */ DoesNotAccessMemory,
+  /* x86_ssse3_phadd_w_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_d */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_d_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_sw */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_sw_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_w */ DoesNotAccessMemory,
+  /* x86_ssse3_phsub_w_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_pmadd_ub_sw */ DoesNotAccessMemory,
+  /* x86_ssse3_pmadd_ub_sw_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_pmul_hr_sw */ DoesNotAccessMemory,
+  /* x86_ssse3_pmul_hr_sw_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_pshuf_b */ DoesNotAccessMemory,
+  /* x86_ssse3_pshuf_b_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_b */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_b_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_d */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_d_128 */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_w */ DoesNotAccessMemory,
+  /* x86_ssse3_psign_w_128 */ DoesNotAccessMemory,
+  /* x86_tbm_bextri_u32 */ DoesNotAccessMemory,
+  /* x86_tbm_bextri_u64 */ DoesNotAccessMemory,
+  /* x86_vcvtph2ps_128 */ DoesNotAccessMemory,
+  /* x86_vcvtph2ps_256 */ DoesNotAccessMemory,
+  /* x86_vcvtps2ph_128 */ DoesNotAccessMemory,
+  /* x86_vcvtps2ph_256 */ DoesNotAccessMemory,
+  /* x86_wrfsbase_32 */ UnknownModRefBehavior,
+  /* x86_wrfsbase_64 */ UnknownModRefBehavior,
+  /* x86_wrgsbase_32 */ UnknownModRefBehavior,
+  /* x86_wrgsbase_64 */ UnknownModRefBehavior,
+  /* x86_xabort */ UnknownModRefBehavior,
+  /* x86_xbegin */ UnknownModRefBehavior,
+  /* x86_xend */ UnknownModRefBehavior,
+  /* x86_xop_vfrcz_pd */ DoesNotAccessMemory,
+  /* x86_xop_vfrcz_pd_256 */ DoesNotAccessMemory,
+  /* x86_xop_vfrcz_ps */ DoesNotAccessMemory,
+  /* x86_xop_vfrcz_ps_256 */ DoesNotAccessMemory,
+  /* x86_xop_vfrcz_sd */ DoesNotAccessMemory,
+  /* x86_xop_vfrcz_ss */ DoesNotAccessMemory,
+  /* x86_xop_vpcmov */ DoesNotAccessMemory,
+  /* x86_xop_vpcmov_256 */ DoesNotAccessMemory,
+  /* x86_xop_vpcomb */ DoesNotAccessMemory,
+  /* x86_xop_vpcomd */ DoesNotAccessMemory,
+  /* x86_xop_vpcomq */ DoesNotAccessMemory,
+  /* x86_xop_vpcomub */ DoesNotAccessMemory,
+  /* x86_xop_vpcomud */ DoesNotAccessMemory,
+  /* x86_xop_vpcomuq */ DoesNotAccessMemory,
+  /* x86_xop_vpcomuw */ DoesNotAccessMemory,
+  /* x86_xop_vpcomw */ DoesNotAccessMemory,
+  /* x86_xop_vpermil2pd */ DoesNotAccessMemory,
+  /* x86_xop_vpermil2pd_256 */ DoesNotAccessMemory,
+  /* x86_xop_vpermil2ps */ DoesNotAccessMemory,
+  /* x86_xop_vpermil2ps_256 */ DoesNotAccessMemory,
+  /* x86_xop_vphaddbd */ DoesNotAccessMemory,
+  /* x86_xop_vphaddbq */ DoesNotAccessMemory,
+  /* x86_xop_vphaddbw */ DoesNotAccessMemory,
+  /* x86_xop_vphadddq */ DoesNotAccessMemory,
+  /* x86_xop_vphaddubd */ DoesNotAccessMemory,
+  /* x86_xop_vphaddubq */ DoesNotAccessMemory,
+  /* x86_xop_vphaddubw */ DoesNotAccessMemory,
+  /* x86_xop_vphaddudq */ DoesNotAccessMemory,
+  /* x86_xop_vphadduwd */ DoesNotAccessMemory,
+  /* x86_xop_vphadduwq */ DoesNotAccessMemory,
+  /* x86_xop_vphaddwd */ DoesNotAccessMemory,
+  /* x86_xop_vphaddwq */ DoesNotAccessMemory,
+  /* x86_xop_vphsubbw */ DoesNotAccessMemory,
+  /* x86_xop_vphsubdq */ DoesNotAccessMemory,
+  /* x86_xop_vphsubwd */ DoesNotAccessMemory,
+  /* x86_xop_vpmacsdd */ DoesNotAccessMemory,
+  /* x86_xop_vpmacsdqh */ DoesNotAccessMemory,
+  /* x86_xop_vpmacsdql */ DoesNotAccessMemory,
+  /* x86_xop_vpmacssdd */ DoesNotAccessMemory,
+  /* x86_xop_vpmacssdqh */ DoesNotAccessMemory,
+  /* x86_xop_vpmacssdql */ DoesNotAccessMemory,
+  /* x86_xop_vpmacsswd */ DoesNotAccessMemory,
+  /* x86_xop_vpmacssww */ DoesNotAccessMemory,
+  /* x86_xop_vpmacswd */ DoesNotAccessMemory,
+  /* x86_xop_vpmacsww */ DoesNotAccessMemory,
+  /* x86_xop_vpmadcsswd */ DoesNotAccessMemory,
+  /* x86_xop_vpmadcswd */ DoesNotAccessMemory,
+  /* x86_xop_vpperm */ DoesNotAccessMemory,
+  /* x86_xop_vprotb */ DoesNotAccessMemory,
+  /* x86_xop_vprotbi */ DoesNotAccessMemory,
+  /* x86_xop_vprotd */ DoesNotAccessMemory,
+  /* x86_xop_vprotdi */ DoesNotAccessMemory,
+  /* x86_xop_vprotq */ DoesNotAccessMemory,
+  /* x86_xop_vprotqi */ DoesNotAccessMemory,
+  /* x86_xop_vprotw */ DoesNotAccessMemory,
+  /* x86_xop_vprotwi */ DoesNotAccessMemory,
+  /* x86_xop_vpshab */ DoesNotAccessMemory,
+  /* x86_xop_vpshad */ DoesNotAccessMemory,
+  /* x86_xop_vpshaq */ DoesNotAccessMemory,
+  /* x86_xop_vpshaw */ DoesNotAccessMemory,
+  /* x86_xop_vpshlb */ DoesNotAccessMemory,
+  /* x86_xop_vpshld */ DoesNotAccessMemory,
+  /* x86_xop_vpshlq */ DoesNotAccessMemory,
+  /* x86_xop_vpshlw */ DoesNotAccessMemory,
+  /* x86_xtest */ UnknownModRefBehavior,
+  /* xcore_bitrev */ DoesNotAccessMemory,
+  /* xcore_checkevent */ UnknownModRefBehavior,
+  /* xcore_chkct */ UnknownModRefBehavior,
+  /* xcore_clre */ UnknownModRefBehavior,
+  /* xcore_clrpt */ UnknownModRefBehavior,
+  /* xcore_clrsr */ UnknownModRefBehavior,
+  /* xcore_crc32 */ DoesNotAccessMemory,
+  /* xcore_crc8 */ DoesNotAccessMemory,
+  /* xcore_edu */ UnknownModRefBehavior,
+  /* xcore_eeu */ UnknownModRefBehavior,
+  /* xcore_endin */ UnknownModRefBehavior,
+  /* xcore_freer */ UnknownModRefBehavior,
+  /* xcore_geted */ UnknownModRefBehavior,
+  /* xcore_getet */ UnknownModRefBehavior,
+  /* xcore_getid */ DoesNotAccessMemory,
+  /* xcore_getps */ UnknownModRefBehavior,
+  /* xcore_getr */ UnknownModRefBehavior,
+  /* xcore_getst */ UnknownModRefBehavior,
+  /* xcore_getts */ UnknownModRefBehavior,
+  /* xcore_in */ UnknownModRefBehavior,
+  /* xcore_inct */ UnknownModRefBehavior,
+  /* xcore_initcp */ UnknownModRefBehavior,
+  /* xcore_initdp */ UnknownModRefBehavior,
+  /* xcore_initlr */ UnknownModRefBehavior,
+  /* xcore_initpc */ UnknownModRefBehavior,
+  /* xcore_initsp */ UnknownModRefBehavior,
+  /* xcore_inshr */ UnknownModRefBehavior,
+  /* xcore_int */ UnknownModRefBehavior,
+  /* xcore_mjoin */ UnknownModRefBehavior,
+  /* xcore_msync */ UnknownModRefBehavior,
+  /* xcore_out */ UnknownModRefBehavior,
+  /* xcore_outct */ UnknownModRefBehavior,
+  /* xcore_outshr */ UnknownModRefBehavior,
+  /* xcore_outt */ UnknownModRefBehavior,
+  /* xcore_peek */ UnknownModRefBehavior,
+  /* xcore_setc */ UnknownModRefBehavior,
+  /* xcore_setclk */ UnknownModRefBehavior,
+  /* xcore_setd */ UnknownModRefBehavior,
+  /* xcore_setev */ UnknownModRefBehavior,
+  /* xcore_setps */ UnknownModRefBehavior,
+  /* xcore_setpsc */ UnknownModRefBehavior,
+  /* xcore_setpt */ UnknownModRefBehavior,
+  /* xcore_setrdy */ UnknownModRefBehavior,
+  /* xcore_setsr */ UnknownModRefBehavior,
+  /* xcore_settw */ UnknownModRefBehavior,
+  /* xcore_setv */ UnknownModRefBehavior,
+  /* xcore_sext */ DoesNotAccessMemory,
+  /* xcore_ssync */ UnknownModRefBehavior,
+  /* xcore_syncr */ UnknownModRefBehavior,
+  /* xcore_testct */ UnknownModRefBehavior,
+  /* xcore_testwct */ UnknownModRefBehavior,
+  /* xcore_waitevent */ OnlyReadsMemory,
+  /* xcore_zext */ DoesNotAccessMemory,
+};
+
+return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);
+#endif // GET_INTRINSIC_MODREF_BEHAVIOR
+
+// Get the LLVM intrinsic that corresponds to a GCC builtin.
+// This is used by the C front-end.  The GCC builtin name is passed
+// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed
+// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.
+#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
+Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char *TargetPrefixStr, const char *BuiltinNameStr) {
+  StringRef BuiltinName(BuiltinNameStr);
+  StringRef TargetPrefix(TargetPrefixStr);
+
+  /* Target Independent Builtins */ {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 10:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_h2f", 10))
+      break;
+    return Intrinsic::nvvm_h2f;	 // "__nvvm_h2f"
+  case 11:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ar0", 3))
+        break;
+      return Intrinsic::nvvm_barrier0;	 // "__nvvm_bar0"
+    case 'p':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "rmt", 3))
+        break;
+      return Intrinsic::nvvm_prmt;	 // "__nvvm_prmt"
+    }
+    break;
+  case 12:	 // 5 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "bs_i", 4))
+        break;
+      return Intrinsic::nvvm_abs_i;	 // "__nvvm_abs_i"
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "lz_i", 4))
+        break;
+      return Intrinsic::nvvm_clz_i;	 // "__nvvm_clz_i"
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "x_i", 3))
+          break;
+        return Intrinsic::nvvm_max_i;	 // "__nvvm_max_i"
+      case 'i':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "n_i", 3))
+          break;
+        return Intrinsic::nvvm_min_i;	 // "__nvvm_min_i"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ad_i", 4))
+        break;
+      return Intrinsic::nvvm_sad_i;	 // "__nvvm_sad_i"
+    }
+    break;
+  case 13:	 // 43 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'n':	 // 42 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "bs_ll", 5))
+          break;
+        return Intrinsic::nvvm_abs_ll;	 // "__nvvm_abs_ll"
+      case 'b':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "rev", 3))
+          break;
+        switch (BuiltinName[11]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (BuiltinName[12] != '2')
+            break;
+          return Intrinsic::nvvm_brev32;	 // "__nvvm_brev32"
+        case '6':	 // 1 string to match.
+          if (BuiltinName[12] != '4')
+            break;
+          return Intrinsic::nvvm_brev64;	 // "__nvvm_brev64"
+        }
+        break;
+      case 'c':	 // 3 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+9, "il_", 3))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_ceil_d;	 // "__nvvm_ceil_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_ceil_f;	 // "__nvvm_ceil_f"
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "z_ll", 4))
+            break;
+          return Intrinsic::nvvm_clz_ll;	 // "__nvvm_clz_ll"
+        }
+        break;
+      case 'd':	 // 10 strings to match.
+        if (BuiltinName[8] != '2')
+          break;
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "_r", 2))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rm;	 // "__nvvm_d2f_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rn;	 // "__nvvm_d2f_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rp;	 // "__nvvm_d2f_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2f_rz;	 // "__nvvm_d2f_rz"
+          }
+          break;
+        case 'i':	 // 6 strings to match.
+          if (BuiltinName[10] != '_')
+            break;
+          switch (BuiltinName[11]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[12] != 'i')
+              break;
+            return Intrinsic::nvvm_d2i_hi;	 // "__nvvm_d2i_hi"
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[12] != 'o')
+              break;
+            return Intrinsic::nvvm_d2i_lo;	 // "__nvvm_d2i_lo"
+          case 'r':	 // 4 strings to match.
+            switch (BuiltinName[12]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rm;	 // "__nvvm_d2i_rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rn;	 // "__nvvm_d2i_rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rp;	 // "__nvvm_d2i_rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_d2i_rz;	 // "__nvvm_d2i_rz"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 11 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case '2':	 // 5 strings to match.
+          switch (BuiltinName[9]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+10, "_rn", 3))
+              break;
+            return Intrinsic::nvvm_f2h_rn;	 // "__nvvm_f2h_rn"
+          case 'i':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+10, "_r", 2))
+              break;
+            switch (BuiltinName[12]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rm;	 // "__nvvm_f2i_rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rn;	 // "__nvvm_f2i_rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rp;	 // "__nvvm_f2i_rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2i_rz;	 // "__nvvm_f2i_rz"
+            }
+            break;
+          }
+          break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+9, "bs_", 3))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fabs_d;	 // "__nvvm_fabs_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fabs_f;	 // "__nvvm_fabs_f"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (BuiltinName[9]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+10, "x_", 2))
+              break;
+            switch (BuiltinName[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fmax_d;	 // "__nvvm_fmax_d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fmax_f;	 // "__nvvm_fmax_f"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+10, "n_", 2))
+              break;
+            switch (BuiltinName[12]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::nvvm_fmin_d;	 // "__nvvm_fmin_d"
+            case 'f':	 // 1 string to match.
+              return Intrinsic::nvvm_fmin_f;	 // "__nvvm_fmin_f"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 8 strings to match.
+        if (BuiltinName[8] != '2')
+          break;
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "_r", 2))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rm;	 // "__nvvm_i2d_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rn;	 // "__nvvm_i2d_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rp;	 // "__nvvm_i2d_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_i2d_rz;	 // "__nvvm_i2d_rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "_r", 2))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rm;	 // "__nvvm_i2f_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rn;	 // "__nvvm_i2f_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rp;	 // "__nvvm_i2f_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_i2f_rz;	 // "__nvvm_i2f_rz"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+9, "x_", 2))
+            break;
+          switch (BuiltinName[11]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[12] != 'l')
+              break;
+            return Intrinsic::nvvm_max_ll;	 // "__nvvm_max_ll"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[12] != 'i')
+              break;
+            return Intrinsic::nvvm_max_ui;	 // "__nvvm_max_ui"
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+9, "n_", 2))
+            break;
+          switch (BuiltinName[11]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[12] != 'l')
+              break;
+            return Intrinsic::nvvm_min_ll;	 // "__nvvm_min_ll"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[12] != 'i')
+              break;
+            return Intrinsic::nvvm_min_ui;	 // "__nvvm_min_ui"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "opc_i", 5))
+          break;
+        return Intrinsic::nvvm_popc_i;	 // "__nvvm_popc_i"
+      case 's':	 // 2 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "d_ui", 4))
+            break;
+          return Intrinsic::nvvm_sad_ui;	 // "__nvvm_sad_ui"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "rt_f", 4))
+            break;
+          return Intrinsic::nvvm_sqrt_f;	 // "__nvvm_sqrt_f"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+3, "yncthreads", 10))
+        break;
+      return Intrinsic::cuda_syncthreads;	 // "__syncthreads"
+    }
+    break;
+  case 14:	 // 45 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_trap", 11))
+        break;
+      return Intrinsic::trap;	 // "__builtin_trap"
+    case 'n':	 // 44 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "ar0_or", 6))
+          break;
+        return Intrinsic::nvvm_barrier0_or;	 // "__nvvm_bar0_or"
+      case 'd':	 // 8 strings to match.
+        if (BuiltinName[8] != '2')
+          break;
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "l_r", 3))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rm;	 // "__nvvm_d2ll_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rn;	 // "__nvvm_d2ll_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rp;	 // "__nvvm_d2ll_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ll_rz;	 // "__nvvm_d2ll_rz"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "i_r", 3))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rm;	 // "__nvvm_d2ui_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rn;	 // "__nvvm_d2ui_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rp;	 // "__nvvm_d2ui_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_d2ui_rz;	 // "__nvvm_d2ui_rz"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 10 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case '2':	 // 8 strings to match.
+          switch (BuiltinName[9]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+10, "l_r", 3))
+              break;
+            switch (BuiltinName[13]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rm;	 // "__nvvm_f2ll_rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rn;	 // "__nvvm_f2ll_rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rp;	 // "__nvvm_f2ll_rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ll_rz;	 // "__nvvm_f2ll_rz"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+10, "i_r", 3))
+              break;
+            switch (BuiltinName[13]) {
+            default: break;
+            case 'm':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rm;	 // "__nvvm_f2ui_rm"
+            case 'n':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rn;	 // "__nvvm_f2ui_rn"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rp;	 // "__nvvm_f2ui_rp"
+            case 'z':	 // 1 string to match.
+              return Intrinsic::nvvm_f2ui_rz;	 // "__nvvm_f2ui_rz"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+9, "oor_", 4))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_floor_d;	 // "__nvvm_floor_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_floor_f;	 // "__nvvm_floor_f"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+8, "l2", 2))
+          break;
+        switch (BuiltinName[10]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+11, "_r", 2))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rm;	 // "__nvvm_ll2d_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rn;	 // "__nvvm_ll2d_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rp;	 // "__nvvm_ll2d_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2d_rz;	 // "__nvvm_ll2d_rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+11, "_r", 2))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rm;	 // "__nvvm_ll2f_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rn;	 // "__nvvm_ll2f_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rp;	 // "__nvvm_ll2f_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ll2f_rz;	 // "__nvvm_ll2f_rz"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "x_ull", 5))
+            break;
+          return Intrinsic::nvvm_max_ull;	 // "__nvvm_max_ull"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "n_ull", 5))
+            break;
+          return Intrinsic::nvvm_min_ull;	 // "__nvvm_min_ull"
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[9] != 'l')
+            break;
+          switch (BuiltinName[10]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+11, "4_i", 3))
+              break;
+            return Intrinsic::nvvm_mul24_i;	 // "__nvvm_mul24_i"
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+11, "i_i", 3))
+              break;
+            return Intrinsic::nvvm_mulhi_i;	 // "__nvvm_mulhi_i"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "opc_ll", 6))
+          break;
+        return Intrinsic::nvvm_popc_ll;	 // "__nvvm_popc_ll"
+      case 'r':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ound_", 5))
+          break;
+        switch (BuiltinName[13]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_round_d;	 // "__nvvm_round_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_round_f;	 // "__nvvm_round_f"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "runc_", 5))
+          break;
+        switch (BuiltinName[13]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_trunc_d;	 // "__nvvm_trunc_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_trunc_f;	 // "__nvvm_trunc_f"
+        }
+        break;
+      case 'u':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+8, "i2", 2))
+          break;
+        switch (BuiltinName[10]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+11, "_r", 2))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rm;	 // "__nvvm_ui2d_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rn;	 // "__nvvm_ui2d_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rp;	 // "__nvvm_ui2d_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2d_rz;	 // "__nvvm_ui2d_rz"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+11, "_r", 2))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rm;	 // "__nvvm_ui2f_rm"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rn;	 // "__nvvm_ui2f_rn"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rp;	 // "__nvvm_ui2f_rp"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_ui2f_rz;	 // "__nvvm_ui2f_rz"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 15:	 // 61 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'a':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+8, "dd_r", 4))
+        break;
+      switch (BuiltinName[12]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rm_d;	 // "__nvvm_add_rm_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rm_f;	 // "__nvvm_add_rm_f"
+        }
+        break;
+      case 'n':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rn_d;	 // "__nvvm_add_rn_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rn_f;	 // "__nvvm_add_rn_f"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rp_d;	 // "__nvvm_add_rp_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rp_f;	 // "__nvvm_add_rp_f"
+        }
+        break;
+      case 'z':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rz_d;	 // "__nvvm_add_rz_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_add_rz_f;	 // "__nvvm_add_rz_f"
+        }
+        break;
+      }
+      break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ar0_and", 7))
+        break;
+      return Intrinsic::nvvm_barrier0_and;	 // "__nvvm_bar0_and"
+    case 'd':	 // 12 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case '2':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+9, "ull_r", 5))
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          return Intrinsic::nvvm_d2ull_rm;	 // "__nvvm_d2ull_rm"
+        case 'n':	 // 1 string to match.
+          return Intrinsic::nvvm_d2ull_rn;	 // "__nvvm_d2ull_rn"
+        case 'p':	 // 1 string to match.
+          return Intrinsic::nvvm_d2ull_rp;	 // "__nvvm_d2ull_rp"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_d2ull_rz;	 // "__nvvm_d2ull_rz"
+        }
+        break;
+      case 'i':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+9, "v_r", 3))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rm_d;	 // "__nvvm_div_rm_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rm_f;	 // "__nvvm_div_rm_f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rn_d;	 // "__nvvm_div_rn_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rn_f;	 // "__nvvm_div_rn_f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rp_d;	 // "__nvvm_div_rp_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rp_f;	 // "__nvvm_div_rp_f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rz_d;	 // "__nvvm_div_rz_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_div_rz_f;	 // "__nvvm_div_rz_f"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'f':	 // 12 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case '2':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+9, "ull_r", 5))
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          return Intrinsic::nvvm_f2ull_rm;	 // "__nvvm_f2ull_rm"
+        case 'n':	 // 1 string to match.
+          return Intrinsic::nvvm_f2ull_rn;	 // "__nvvm_f2ull_rn"
+        case 'p':	 // 1 string to match.
+          return Intrinsic::nvvm_f2ull_rp;	 // "__nvvm_f2ull_rp"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_f2ull_rz;	 // "__nvvm_f2ull_rz"
+        }
+        break;
+      case 'm':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+9, "a_r", 3))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rm_d;	 // "__nvvm_fma_rm_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rm_f;	 // "__nvvm_fma_rm_f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rn_d;	 // "__nvvm_fma_rn_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rn_f;	 // "__nvvm_fma_rn_f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rp_d;	 // "__nvvm_fma_rp_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rp_f;	 // "__nvvm_fma_rp_f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rz_d;	 // "__nvvm_fma_rz_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_fma_rz_f;	 // "__nvvm_fma_rz_f"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ohi_i2d", 7))
+        break;
+      return Intrinsic::nvvm_lohi_i2d;	 // "__nvvm_lohi_i2d"
+    case 'm':	 // 11 strings to match.
+      if (memcmp(BuiltinName.data()+8, "ul", 2))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case '2':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "4_ui", 4))
+          break;
+        return Intrinsic::nvvm_mul24_ui;	 // "__nvvm_mul24_ui"
+      case '_':	 // 8 strings to match.
+        if (BuiltinName[11] != 'r')
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rm_d;	 // "__nvvm_mul_rm_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rm_f;	 // "__nvvm_mul_rm_f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rn_d;	 // "__nvvm_mul_rn_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rn_f;	 // "__nvvm_mul_rn_f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rp_d;	 // "__nvvm_mul_rp_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rp_f;	 // "__nvvm_mul_rp_f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rz_d;	 // "__nvvm_mul_rz_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_mul_rz_f;	 // "__nvvm_mul_rz_f"
+          }
+          break;
+        }
+        break;
+      case 'h':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+11, "i_", 2))
+          break;
+        switch (BuiltinName[13]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (BuiltinName[14] != 'l')
+            break;
+          return Intrinsic::nvvm_mulhi_ll;	 // "__nvvm_mulhi_ll"
+        case 'u':	 // 1 string to match.
+          if (BuiltinName[14] != 'i')
+            break;
+          return Intrinsic::nvvm_mulhi_ui;	 // "__nvvm_mulhi_ui"
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+8, "cp_r", 4))
+        break;
+      switch (BuiltinName[12]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rm_d;	 // "__nvvm_rcp_rm_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rm_f;	 // "__nvvm_rcp_rm_f"
+        }
+        break;
+      case 'n':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rn_d;	 // "__nvvm_rcp_rn_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rn_f;	 // "__nvvm_rcp_rn_f"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rp_d;	 // "__nvvm_rcp_rp_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rp_f;	 // "__nvvm_rcp_rp_f"
+        }
+        break;
+      case 'z':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rz_d;	 // "__nvvm_rcp_rz_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rcp_rz_f;	 // "__nvvm_rcp_rz_f"
+        }
+        break;
+      }
+      break;
+    case 'u':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+8, "ll2", 3))
+        break;
+      switch (BuiltinName[11]) {
+      default: break;
+      case 'd':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+12, "_r", 2))
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2d_rm;	 // "__nvvm_ull2d_rm"
+        case 'n':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2d_rn;	 // "__nvvm_ull2d_rn"
+        case 'p':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2d_rp;	 // "__nvvm_ull2d_rp"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2d_rz;	 // "__nvvm_ull2d_rz"
+        }
+        break;
+      case 'f':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+12, "_r", 2))
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2f_rm;	 // "__nvvm_ull2f_rm"
+        case 'n':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2f_rn;	 // "__nvvm_ull2f_rn"
+        case 'p':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2f_rp;	 // "__nvvm_ull2f_rp"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_ull2f_rz;	 // "__nvvm_ull2f_rz"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 16:	 // 15 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ar0_popc", 8))
+        break;
+      return Intrinsic::nvvm_barrier0_popc;	 // "__nvvm_bar0_popc"
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "mbar_gl", 7))
+          break;
+        return Intrinsic::nvvm_membar_gl;	 // "__nvvm_membar_gl"
+      case 'u':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "lhi_ull", 7))
+          break;
+        return Intrinsic::nvvm_mulhi_ull;	 // "__nvvm_mulhi_ull"
+      }
+      break;
+    case 's':	 // 10 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case 'q':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+9, "rt_r", 4))
+          break;
+        switch (BuiltinName[13]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (BuiltinName[14] != '_')
+            break;
+          switch (BuiltinName[15]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rm_d;	 // "__nvvm_sqrt_rm_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rm_f;	 // "__nvvm_sqrt_rm_f"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (BuiltinName[14] != '_')
+            break;
+          switch (BuiltinName[15]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rn_d;	 // "__nvvm_sqrt_rn_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rn_f;	 // "__nvvm_sqrt_rn_f"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (BuiltinName[14] != '_')
+            break;
+          switch (BuiltinName[15]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rp_d;	 // "__nvvm_sqrt_rp_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rp_f;	 // "__nvvm_sqrt_rp_f"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[14] != '_')
+            break;
+          switch (BuiltinName[15]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rz_d;	 // "__nvvm_sqrt_rz_d"
+          case 'f':	 // 1 string to match.
+            return Intrinsic::nvvm_sqrt_rz_f;	 // "__nvvm_sqrt_rz_f"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+9, "q_", 2))
+          break;
+        switch (BuiltinName[11]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "epth", 4))
+            break;
+          return Intrinsic::nvvm_suq_depth;	 // "__nvvm_suq_depth"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "idth", 4))
+            break;
+          return Intrinsic::nvvm_suq_width;	 // "__nvvm_suq_width"
+        }
+        break;
+      }
+      break;
+    case 't':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+8, "xq_", 3))
+        break;
+      switch (BuiltinName[11]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+12, "epth", 4))
+          break;
+        return Intrinsic::nvvm_txq_depth;	 // "__nvvm_txq_depth"
+      case 'w':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+12, "idth", 4))
+          break;
+        return Intrinsic::nvvm_txq_width;	 // "__nvvm_txq_width"
+      }
+      break;
+    }
+    break;
+  case 17:	 // 21 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "eil_ftz_f", 9))
+        break;
+      return Intrinsic::nvvm_ceil_ftz_f;	 // "__nvvm_ceil_ftz_f"
+    case 'd':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+8, "2f_r", 4))
+        break;
+      switch (BuiltinName[12]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+          break;
+        return Intrinsic::nvvm_d2f_rm_ftz;	 // "__nvvm_d2f_rm_ftz"
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+          break;
+        return Intrinsic::nvvm_d2f_rn_ftz;	 // "__nvvm_d2f_rn_ftz"
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+          break;
+        return Intrinsic::nvvm_d2f_rp_ftz;	 // "__nvvm_d2f_rp_ftz"
+      case 'z':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+          break;
+        return Intrinsic::nvvm_d2f_rz_ftz;	 // "__nvvm_d2f_rz_ftz"
+      }
+      break;
+    case 'f':	 // 8 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case '2':	 // 5 strings to match.
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+10, "_rn_ftz", 7))
+            break;
+          return Intrinsic::nvvm_f2h_rn_ftz;	 // "__nvvm_f2h_rn_ftz"
+        case 'i':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "_r", 2))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2i_rm_ftz;	 // "__nvvm_f2i_rm_ftz"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2i_rn_ftz;	 // "__nvvm_f2i_rn_ftz"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2i_rp_ftz;	 // "__nvvm_f2i_rp_ftz"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2i_rz_ftz;	 // "__nvvm_f2i_rz_ftz"
+          }
+          break;
+        }
+        break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "bs_ftz_f", 8))
+          break;
+        return Intrinsic::nvvm_fabs_ftz_f;	 // "__nvvm_fabs_ftz_f"
+      case 'm':	 // 2 strings to match.
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+10, "x_ftz_f", 7))
+            break;
+          return Intrinsic::nvvm_fmax_ftz_f;	 // "__nvvm_fmax_ftz_f"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+10, "n_ftz_f", 7))
+            break;
+          return Intrinsic::nvvm_fmin_ftz_f;	 // "__nvvm_fmin_ftz_f"
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+8, "embar_", 6))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "ta", 2))
+          break;
+        return Intrinsic::nvvm_membar_cta;	 // "__nvvm_membar_cta"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "ys", 2))
+          break;
+        return Intrinsic::nvvm_membar_sys;	 // "__nvvm_membar_sys"
+      }
+      break;
+    case 'r':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+8, "otate_b", 7))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case '3':	 // 1 string to match.
+        if (BuiltinName[16] != '2')
+          break;
+        return Intrinsic::nvvm_rotate_b32;	 // "__nvvm_rotate_b32"
+      case '6':	 // 1 string to match.
+        if (BuiltinName[16] != '4')
+          break;
+        return Intrinsic::nvvm_rotate_b64;	 // "__nvvm_rotate_b64"
+      }
+      break;
+    case 's':	 // 3 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+9, "turate_", 7))
+          break;
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_saturate_d;	 // "__nvvm_saturate_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_saturate_f;	 // "__nvvm_saturate_f"
+        }
+        break;
+      case 'u':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "q_height", 8))
+          break;
+        return Intrinsic::nvvm_suq_height;	 // "__nvvm_suq_height"
+      }
+      break;
+    case 't':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "xq_height", 9))
+        break;
+      return Intrinsic::nvvm_txq_height;	 // "__nvvm_txq_height"
+    }
+    break;
+  case 18:	 // 13 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_", 7))
+      break;
+    switch (BuiltinName[7]) {
+    default: break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+8, "itcast_", 7))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "2i", 2))
+          break;
+        return Intrinsic::nvvm_bitcast_f2i;	 // "__nvvm_bitcast_f2i"
+      case 'i':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "2f", 2))
+          break;
+        return Intrinsic::nvvm_bitcast_i2f;	 // "__nvvm_bitcast_i2f"
+      }
+      break;
+    case 'f':	 // 9 strings to match.
+      switch (BuiltinName[8]) {
+      default: break;
+      case '2':	 // 8 strings to match.
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "l_r", 3))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ll_rm_ftz;	 // "__nvvm_f2ll_rm_ftz"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ll_rn_ftz;	 // "__nvvm_f2ll_rn_ftz"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ll_rp_ftz;	 // "__nvvm_f2ll_rp_ftz"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ll_rz_ftz;	 // "__nvvm_f2ll_rz_ftz"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+10, "i_r", 3))
+            break;
+          switch (BuiltinName[13]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ui_rm_ftz;	 // "__nvvm_f2ui_rm_ftz"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ui_rn_ftz;	 // "__nvvm_f2ui_rn_ftz"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ui_rp_ftz;	 // "__nvvm_f2ui_rp_ftz"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+14, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ui_rz_ftz;	 // "__nvvm_f2ui_rz_ftz"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+9, "oor_ftz_f", 9))
+          break;
+        return Intrinsic::nvvm_floor_ftz_f;	 // "__nvvm_floor_ftz_f"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "ound_ftz_f", 10))
+        break;
+      return Intrinsic::nvvm_round_ftz_f;	 // "__nvvm_round_ftz_f"
+    case 't':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+8, "runc_ftz_f", 10))
+        break;
+      return Intrinsic::nvvm_trunc_ftz_f;	 // "__nvvm_trunc_ftz_f"
+    }
+    break;
+  case 19:	 // 34 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_debugtrap", 16))
+        break;
+      return Intrinsic::debugtrap;	 // "__builtin_debugtrap"
+    case 'n':	 // 33 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+8, "dd_r", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_add_rm_ftz_f;	 // "__nvvm_add_rm_ftz_f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_add_rn_ftz_f;	 // "__nvvm_add_rn_ftz_f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_add_rp_ftz_f;	 // "__nvvm_add_rp_ftz_f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_add_rz_ftz_f;	 // "__nvvm_add_rz_ftz_f"
+        }
+        break;
+      case 'b':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "itcast_", 7))
+          break;
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "2ll", 3))
+            break;
+          return Intrinsic::nvvm_bitcast_d2ll;	 // "__nvvm_bitcast_d2ll"
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "l2d", 3))
+            break;
+          return Intrinsic::nvvm_bitcast_ll2d;	 // "__nvvm_bitcast_ll2d"
+        }
+        break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "os_approx_f", 11))
+          break;
+        return Intrinsic::nvvm_cos_approx_f;	 // "__nvvm_cos_approx_f"
+      case 'd':	 // 5 strings to match.
+        if (memcmp(BuiltinName.data()+8, "iv_", 3))
+          break;
+        switch (BuiltinName[11]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "pprox_f", 7))
+            break;
+          return Intrinsic::nvvm_div_approx_f;	 // "__nvvm_div_approx_f"
+        case 'r':	 // 4 strings to match.
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_div_rm_ftz_f;	 // "__nvvm_div_rm_ftz_f"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_div_rn_ftz_f;	 // "__nvvm_div_rn_ftz_f"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_div_rp_ftz_f;	 // "__nvvm_div_rp_ftz_f"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_div_rz_ftz_f;	 // "__nvvm_div_rz_ftz_f"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "x2_approx_", 10))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_ex2_approx_d;	 // "__nvvm_ex2_approx_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_ex2_approx_f;	 // "__nvvm_ex2_approx_f"
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+9, "ull_r", 5))
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+15, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rm_ftz;	 // "__nvvm_f2ull_rm_ftz"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+15, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rn_ftz;	 // "__nvvm_f2ull_rn_ftz"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+15, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rp_ftz;	 // "__nvvm_f2ull_rp_ftz"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+15, "_ftz", 4))
+              break;
+            return Intrinsic::nvvm_f2ull_rz_ftz;	 // "__nvvm_f2ull_rz_ftz"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+9, "a_r", 3))
+            break;
+          switch (BuiltinName[12]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rm_ftz_f;	 // "__nvvm_fma_rm_ftz_f"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rn_ftz_f;	 // "__nvvm_fma_rn_ftz_f"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rp_ftz_f;	 // "__nvvm_fma_rp_ftz_f"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+              break;
+            return Intrinsic::nvvm_fma_rz_ftz_f;	 // "__nvvm_fma_rz_ftz_f"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "g2_approx_", 10))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_lg2_approx_d;	 // "__nvvm_lg2_approx_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_lg2_approx_f;	 // "__nvvm_lg2_approx_f"
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ul_r", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rm_ftz_f;	 // "__nvvm_mul_rm_ftz_f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rn_ftz_f;	 // "__nvvm_mul_rn_ftz_f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rp_ftz_f;	 // "__nvvm_mul_rp_ftz_f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_mul_rz_ftz_f;	 // "__nvvm_mul_rz_ftz_f"
+        }
+        break;
+      case 'r':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+8, "cp_r", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rm_ftz_f;	 // "__nvvm_rcp_rm_ftz_f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rn_ftz_f;	 // "__nvvm_rcp_rn_ftz_f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rp_ftz_f;	 // "__nvvm_rcp_rp_ftz_f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+13, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_rcp_rz_ftz_f;	 // "__nvvm_rcp_rz_ftz_f"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "in_approx_f", 11))
+          break;
+        return Intrinsic::nvvm_sin_approx_f;	 // "__nvvm_sin_approx_f"
+      }
+      break;
+    }
+    break;
+  case 20:	 // 7 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "lt_rounds", 9))
+          break;
+        return Intrinsic::flt_rounds;	 // "__builtin_flt_rounds"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "tack_save", 9))
+          break;
+        return Intrinsic::stacksave;	 // "__builtin_stack_save"
+      }
+      break;
+    case 'n':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_sqrt_", 9))
+        break;
+      switch (BuiltinName[12]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+13, "pprox_f", 7))
+          break;
+        return Intrinsic::nvvm_sqrt_approx_f;	 // "__nvvm_sqrt_approx_f"
+      case 'r':	 // 4 strings to match.
+        switch (BuiltinName[13]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+14, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_sqrt_rm_ftz_f;	 // "__nvvm_sqrt_rm_ftz_f"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+14, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_sqrt_rn_ftz_f;	 // "__nvvm_sqrt_rn_ftz_f"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+14, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_sqrt_rp_ftz_f;	 // "__nvvm_sqrt_rp_ftz_f"
+        case 'z':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+14, "_ftz_f", 6))
+            break;
+          return Intrinsic::nvvm_sqrt_rz_ftz_f;	 // "__nvvm_sqrt_rz_ftz_f"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 21:	 // 28 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 20 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'i':	 // 18 strings to match.
+        if (memcmp(BuiltinName.data()+11, "a32_vp", 6))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'c':	 // 5 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+19, "ov", 2))
+              break;
+            return Intrinsic::x86_xop_vpcmov;	 // "__builtin_ia32_vpcmov"
+          case 'o':	 // 4 strings to match.
+            if (BuiltinName[19] != 'm')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomb;	 // "__builtin_ia32_vpcomb"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomd;	 // "__builtin_ia32_vpcomd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomq;	 // "__builtin_ia32_vpcomq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomw;	 // "__builtin_ia32_vpcomw"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "erm", 3))
+            break;
+          return Intrinsic::x86_xop_vpperm;	 // "__builtin_ia32_vpperm"
+        case 'r':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ot", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotb;	 // "__builtin_ia32_vprotb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotd;	 // "__builtin_ia32_vprotd"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotq;	 // "__builtin_ia32_vprotq"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_xop_vprotw;	 // "__builtin_ia32_vprotw"
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (BuiltinName[18] != 'h')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshab;	 // "__builtin_ia32_vpshab"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshad;	 // "__builtin_ia32_vpshad"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshaq;	 // "__builtin_ia32_vpshaq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshaw;	 // "__builtin_ia32_vpshaw"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlb;	 // "__builtin_ia32_vpshlb"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshld;	 // "__builtin_ia32_vpshld"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlq;	 // "__builtin_ia32_vpshlq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpshlw;	 // "__builtin_ia32_vpshlw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "bject_size", 10))
+          break;
+        return Intrinsic::objectsize;	 // "__builtin_object_size"
+      case 'u':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "nwind_init", 10))
+          break;
+        return Intrinsic::eh_unwind_init;	 // "__builtin_unwind_init"
+      }
+      break;
+    case 'n':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'i':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "sspacep_", 8))
+          break;
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "onst", 4))
+            break;
+          return Intrinsic::nvvm_isspacep_const;	 // "__nvvm_isspacep_const"
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "ocal", 4))
+            break;
+          return Intrinsic::nvvm_isspacep_local;	 // "__nvvm_isspacep_local"
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "sqrt_approx_", 12))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::nvvm_rsqrt_approx_d;	 // "__nvvm_rsqrt_approx_d"
+        case 'f':	 // 1 string to match.
+          return Intrinsic::nvvm_rsqrt_approx_f;	 // "__nvvm_rsqrt_approx_f"
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "turate_ftz_f", 12))
+            break;
+          return Intrinsic::nvvm_saturate_ftz_f;	 // "__nvvm_saturate_ftz_f"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "q_array_size", 12))
+            break;
+          return Intrinsic::nvvm_suq_array_size;	 // "__nvvm_suq_array_size"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "ap_lo_hi_b64", 12))
+            break;
+          return Intrinsic::nvvm_swap_lo_hi_b64;	 // "__nvvm_swap_lo_hi_b64"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "xq_array_size", 13))
+          break;
+        return Intrinsic::nvvm_txq_array_size;	 // "__nvvm_txq_array_size"
+      }
+      break;
+    }
+    break;
+  case 22:	 // 23 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 17 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'i':	 // 12 strings to match.
+        if (memcmp(BuiltinName.data()+11, "a32_v", 5))
+          break;
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+17, "rcz", 3))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vfrcz_pd;	 // "__builtin_ia32_vfrczpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_xop_vfrcz_ps;	 // "__builtin_ia32_vfrczps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vfrcz_sd;	 // "__builtin_ia32_vfrczsd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_xop_vfrcz_ss;	 // "__builtin_ia32_vfrczss"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 8 strings to match.
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'c':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "omu", 3))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomub;	 // "__builtin_ia32_vpcomub"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomud;	 // "__builtin_ia32_vpcomud"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomuq;	 // "__builtin_ia32_vpcomuq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpcomuw;	 // "__builtin_ia32_vpcomuw"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "ot", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[21] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotbi;	 // "__builtin_ia32_vprotbi"
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[21] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotdi;	 // "__builtin_ia32_vprotdi"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[21] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotqi;	 // "__builtin_ia32_vprotqi"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[21] != 'i')
+                break;
+              return Intrinsic::x86_xop_vprotwi;	 // "__builtin_ia32_vprotwi"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 5 strings to match.
+        if (memcmp(BuiltinName.data()+11, "tx_", 3))
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+15, "ar_sync", 7))
+            break;
+          return Intrinsic::ptx_bar_sync;	 // "__builtin_ptx_bar_sync"
+        case 'r':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+15, "ead_pm", 6))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::ptx_read_pm0;	 // "__builtin_ptx_read_pm0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::ptx_read_pm1;	 // "__builtin_ptx_read_pm1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::ptx_read_pm2;	 // "__builtin_ptx_read_pm2"
+          case '3':	 // 1 string to match.
+            return Intrinsic::ptx_read_pm3;	 // "__builtin_ptx_read_pm3"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'i':	 // 5 strings to match.
+        if (BuiltinName[8] != 's')
+          break;
+        switch (BuiltinName[9]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+10, "pacep_", 6))
+            break;
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'g':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+17, "lobal", 5))
+              break;
+            return Intrinsic::nvvm_isspacep_global;	 // "__nvvm_isspacep_global"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+17, "hared", 5))
+              break;
+            return Intrinsic::nvvm_isspacep_shared;	 // "__nvvm_isspacep_shared"
+          }
+          break;
+        case 't':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+10, "ypep_", 5))
+            break;
+          switch (BuiltinName[15]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[16]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+17, "mpler", 5))
+                break;
+              return Intrinsic::nvvm_istypep_sampler;	 // "__nvvm_istypep_sampler"
+            case 'u':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+17, "rface", 5))
+                break;
+              return Intrinsic::nvvm_istypep_surface;	 // "__nvvm_istypep_surface"
+            }
+            break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+16, "exture", 6))
+              break;
+            return Intrinsic::nvvm_istypep_texture;	 // "__nvvm_istypep_texture"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "xq_num_samples", 14))
+          break;
+        return Intrinsic::nvvm_txq_num_samples;	 // "__nvvm_txq_num_samples"
+      }
+      break;
+    }
+    break;
+  case 23:	 // 21 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 14 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'i':	 // 12 strings to match.
+        if (memcmp(BuiltinName.data()+11, "a32_vp", 6))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'h':	 // 9 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            if (memcmp(BuiltinName.data()+19, "dd", 2))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 3 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_xop_vphaddbd;	 // "__builtin_ia32_vphaddbd"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_xop_vphaddbq;	 // "__builtin_ia32_vphaddbq"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::x86_xop_vphaddbw;	 // "__builtin_ia32_vphaddbw"
+              }
+              break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              return Intrinsic::x86_xop_vphadddq;	 // "__builtin_ia32_vphadddq"
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_xop_vphaddwd;	 // "__builtin_ia32_vphaddwd"
+              case 'q':	 // 1 string to match.
+                return Intrinsic::x86_xop_vphaddwq;	 // "__builtin_ia32_vphaddwq"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+19, "ub", 2))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[22] != 'w')
+                break;
+              return Intrinsic::x86_xop_vphsubbw;	 // "__builtin_ia32_vphsubbw"
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              return Intrinsic::x86_xop_vphsubdq;	 // "__builtin_ia32_vphsubdq"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[22] != 'd')
+                break;
+              return Intrinsic::x86_xop_vphsubwd;	 // "__builtin_ia32_vphsubwd"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "acs", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[22] != 'd')
+              break;
+            return Intrinsic::x86_xop_vpmacsdd;	 // "__builtin_ia32_vpmacsdd"
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpmacswd;	 // "__builtin_ia32_vpmacswd"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vpmacsww;	 // "__builtin_ia32_vpmacsww"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "tx_read_smid", 12))
+          break;
+        return Intrinsic::ptx_read_smid;	 // "__builtin_ptx_read_smid"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "tack_restore", 12))
+          break;
+        return Intrinsic::stackrestore;	 // "__builtin_stack_restore"
+      }
+      break;
+    case 'n':	 // 7 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "os_approx_ftz_f", 15))
+          break;
+        return Intrinsic::nvvm_cos_approx_ftz_f;	 // "__nvvm_cos_approx_ftz_f"
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "iv_approx_ftz_f", 15))
+          break;
+        return Intrinsic::nvvm_div_approx_ftz_f;	 // "__nvvm_div_approx_ftz_f"
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "x2_approx_ftz_f", 15))
+          break;
+        return Intrinsic::nvvm_ex2_approx_ftz_f;	 // "__nvvm_ex2_approx_ftz_f"
+      case 'l':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "g2_approx_ftz_f", 15))
+          break;
+        return Intrinsic::nvvm_lg2_approx_ftz_f;	 // "__nvvm_lg2_approx_ftz_f"
+      case 'r':	 // 2 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "p_approx_ftz_d", 14))
+            break;
+          return Intrinsic::nvvm_rcp_approx_ftz_d;	 // "__nvvm_rcp_approx_ftz_d"
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "tate_right_b64", 14))
+            break;
+          return Intrinsic::nvvm_rotate_right_b64;	 // "__nvvm_rotate_right_b64"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "in_approx_ftz_f", 15))
+          break;
+        return Intrinsic::nvvm_sin_approx_ftz_f;	 // "__nvvm_sin_approx_ftz_f"
+      }
+      break;
+    }
+    break;
+  case 24:	 // 30 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 18 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'i':	 // 12 strings to match.
+        if (memcmp(BuiltinName.data()+11, "a32_vp", 6))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'h':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+18, "addu", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubd;	 // "__builtin_ia32_vphaddubd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubq;	 // "__builtin_ia32_vphaddubq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphaddubw;	 // "__builtin_ia32_vphaddubw"
+            }
+            break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[23] != 'q')
+              break;
+            return Intrinsic::x86_xop_vphaddudq;	 // "__builtin_ia32_vphaddudq"
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphadduwd;	 // "__builtin_ia32_vphadduwd"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_xop_vphadduwq;	 // "__builtin_ia32_vphadduwq"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 6 strings to match.
+          if (BuiltinName[18] != 'a')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'c':	 // 5 strings to match.
+            if (BuiltinName[20] != 's')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              switch (BuiltinName[23]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpmacsdqh;	 // "__builtin_ia32_vpmacsdqh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpmacsdql;	 // "__builtin_ia32_vpmacsdql"
+              }
+              break;
+            case 's':	 // 3 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (BuiltinName[23] != 'd')
+                  break;
+                return Intrinsic::x86_xop_vpmacssdd;	 // "__builtin_ia32_vpmacssdd"
+              case 'w':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacsswd;	 // "__builtin_ia32_vpmacsswd"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacssww;	 // "__builtin_ia32_vpmacssww"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "cswd", 4))
+              break;
+            return Intrinsic::x86_xop_vpmadcswd;	 // "__builtin_ia32_vpmadcswd"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+11, "tx_read_", 8))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "lock", 4))
+            break;
+          return Intrinsic::ptx_read_clock;	 // "__builtin_ptx_read_clock"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "smid", 4))
+            break;
+          return Intrinsic::ptx_read_nsmid;	 // "__builtin_ptx_read_nsmid"
+        case 't':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "id_", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ptx_read_tid_w;	 // "__builtin_ptx_read_tid_w"
+          case 'x':	 // 1 string to match.
+            return Intrinsic::ptx_read_tid_x;	 // "__builtin_ptx_read_tid_x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::ptx_read_tid_y;	 // "__builtin_ptx_read_tid_y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ptx_read_tid_z;	 // "__builtin_ptx_read_tid_z"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 's':	 // 11 strings to match.
+        switch (BuiltinName[8]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+9, "rt_approx_ftz_f", 15))
+            break;
+          return Intrinsic::nvvm_sqrt_approx_ftz_f;	 // "__nvvm_sqrt_approx_ftz_f"
+        case 'u':	 // 10 strings to match.
+          switch (BuiltinName[9]) {
+          default: break;
+          case 'q':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+10, "_channel_order", 14))
+              break;
+            return Intrinsic::nvvm_suq_channel_order;	 // "__nvvm_suq_channel_order"
+          case 's':	 // 9 strings to match.
+            if (memcmp(BuiltinName.data()+10, "t_", 2))
+              break;
+            switch (BuiltinName[12]) {
+            default: break;
+            case 'b':	 // 6 strings to match.
+              if (BuiltinName[13] != '_')
+                break;
+              switch (BuiltinName[14]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_", 5))
+                  break;
+                switch (BuiltinName[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i8_trap;	 // "__nvvm_sust_b_1d_i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_i8_zero;	 // "__nvvm_sust_b_1d_i8_zero"
+                }
+                break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_", 5))
+                  break;
+                switch (BuiltinName[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i8_trap;	 // "__nvvm_sust_b_2d_i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_i8_zero;	 // "__nvvm_sust_b_2d_i8_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_", 5))
+                  break;
+                switch (BuiltinName[20]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i8_trap;	 // "__nvvm_sust_b_3d_i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+21, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_i8_zero;	 // "__nvvm_sust_b_3d_i8_zero"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 3 strings to match.
+              if (BuiltinName[13] != '_')
+                break;
+              switch (BuiltinName[14]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_i8_trap;	 // "__nvvm_sust_p_1d_i8_trap"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_i8_trap;	 // "__nvvm_sust_p_2d_i8_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+15, "d_i8_trap", 9))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_i8_trap;	 // "__nvvm_sust_p_3d_i8_trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "xq_channel_order", 16))
+          break;
+        return Intrinsic::nvvm_txq_channel_order;	 // "__nvvm_txq_channel_order"
+      }
+      break;
+    }
+    break;
+  case 25:	 // 44 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 16 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'i':	 // 9 strings to match.
+        switch (BuiltinName[11]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+12, "32_v", 4))
+            break;
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'f':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "rczp", 4))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "256", 3))
+                break;
+              return Intrinsic::x86_xop_vfrcz_pd_256;	 // "__builtin_ia32_vfrczpd256"
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "256", 3))
+                break;
+              return Intrinsic::x86_xop_vfrcz_ps_256;	 // "__builtin_ia32_vfrczps256"
+            }
+            break;
+          case 'p':	 // 6 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+18, "mov_256", 7))
+                break;
+              return Intrinsic::x86_xop_vpcmov_256;	 // "__builtin_ia32_vpcmov_256"
+            case 'e':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+18, "rmil2p", 6))
+                break;
+              switch (BuiltinName[24]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpermil2pd;	 // "__builtin_ia32_vpermil2pd"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_xop_vpermil2ps;	 // "__builtin_ia32_vpermil2ps"
+              }
+              break;
+            case 'm':	 // 3 strings to match.
+              if (BuiltinName[18] != 'a')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'c':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+20, "ssdq", 4))
+                  break;
+                switch (BuiltinName[24]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacssdqh;	 // "__builtin_ia32_vpmacssdqh"
+                case 'l':	 // 1 string to match.
+                  return Intrinsic::x86_xop_vpmacssdql;	 // "__builtin_ia32_vpmacssdql"
+                }
+                break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+20, "csswd", 5))
+                  break;
+                return Intrinsic::x86_xop_vpmadcsswd;	 // "__builtin_ia32_vpmadcsswd"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "it_trampoline", 13))
+            break;
+          return Intrinsic::init_trampoline;	 // "__builtin_init_trampoline"
+        }
+        break;
+      case 'p':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+11, "tx_read_", 8))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'g':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "ridid", 5))
+            break;
+          return Intrinsic::ptx_read_gridid;	 // "__builtin_ptx_read_gridid"
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "aneid", 5))
+            break;
+          return Intrinsic::ptx_read_laneid;	 // "__builtin_ptx_read_laneid"
+        case 'n':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "tid_", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_w;	 // "__builtin_ptx_read_ntid_w"
+          case 'x':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_x;	 // "__builtin_ptx_read_ntid_x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_y;	 // "__builtin_ptx_read_ntid_y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ptx_read_ntid_z;	 // "__builtin_ptx_read_ntid_z"
+          }
+          break;
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "arpid", 5))
+            break;
+          return Intrinsic::ptx_read_warpid;	 // "__builtin_ptx_read_warpid"
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 28 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+8, "sqrt_approx_ftz_f", 17))
+          break;
+        return Intrinsic::nvvm_rsqrt_approx_ftz_f;	 // "__nvvm_rsqrt_approx_ftz_f"
+      case 's':	 // 27 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ust_", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'b':	 // 21 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "6_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i16_trap;	 // "__nvvm_sust_b_1d_i16_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i16_zero;	 // "__nvvm_sust_b_1d_i16_zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "2_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i32_trap;	 // "__nvvm_sust_b_1d_i32_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i32_zero;	 // "__nvvm_sust_b_1d_i32_zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "4_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i64_trap;	 // "__nvvm_sust_b_1d_i64_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i64_zero;	 // "__nvvm_sust_b_1d_i64_zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "_clamp", 6))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_i8_clamp;	 // "__nvvm_sust_b_1d_i8_clamp"
+            }
+            break;
+          case '2':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "6_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i16_trap;	 // "__nvvm_sust_b_2d_i16_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i16_zero;	 // "__nvvm_sust_b_2d_i16_zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "2_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i32_trap;	 // "__nvvm_sust_b_2d_i32_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i32_zero;	 // "__nvvm_sust_b_2d_i32_zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "4_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i64_trap;	 // "__nvvm_sust_b_2d_i64_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i64_zero;	 // "__nvvm_sust_b_2d_i64_zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "_clamp", 6))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_i8_clamp;	 // "__nvvm_sust_b_2d_i8_clamp"
+            }
+            break;
+          case '3':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "6_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i16_trap;	 // "__nvvm_sust_b_3d_i16_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i16_zero;	 // "__nvvm_sust_b_3d_i16_zero"
+              }
+              break;
+            case '3':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "2_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i32_trap;	 // "__nvvm_sust_b_3d_i32_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i32_zero;	 // "__nvvm_sust_b_3d_i32_zero"
+              }
+              break;
+            case '6':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+19, "4_", 2))
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 't':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "rap", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i64_trap;	 // "__nvvm_sust_b_3d_i64_trap"
+              case 'z':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "ero", 3))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i64_zero;	 // "__nvvm_sust_b_3d_i64_zero"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "_clamp", 6))
+                break;
+              return Intrinsic::nvvm_sust_b_3d_i8_clamp;	 // "__nvvm_sust_b_3d_i8_clamp"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 6 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "6_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_i16_trap;	 // "__nvvm_sust_p_1d_i16_trap"
+            case '3':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "2_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_i32_trap;	 // "__nvvm_sust_p_1d_i32_trap"
+            }
+            break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "6_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_i16_trap;	 // "__nvvm_sust_p_2d_i16_trap"
+            case '3':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "2_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_i32_trap;	 // "__nvvm_sust_p_2d_i32_trap"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_i", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "6_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_3d_i16_trap;	 // "__nvvm_sust_p_3d_i16_trap"
+            case '3':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "2_trap", 6))
+                break;
+              return Intrinsic::nvvm_sust_p_3d_i32_trap;	 // "__nvvm_sust_p_3d_i32_trap"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 26:	 // 36 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_ptx_read_", 16))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'c':	 // 5 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "ock64", 5))
+            break;
+          return Intrinsic::ptx_read_clock64;	 // "__builtin_ptx_read_clock64"
+        case 't':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+21, "aid_", 4))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ptx_read_ctaid_w;	 // "__builtin_ptx_read_ctaid_w"
+          case 'x':	 // 1 string to match.
+            return Intrinsic::ptx_read_ctaid_x;	 // "__builtin_ptx_read_ctaid_x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::ptx_read_ctaid_y;	 // "__builtin_ptx_read_ctaid_y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ptx_read_ctaid_z;	 // "__builtin_ptx_read_ctaid_z"
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "warpid", 6))
+          break;
+        return Intrinsic::ptx_read_nwarpid;	 // "__builtin_ptx_read_nwarpid"
+      }
+      break;
+    case 'n':	 // 30 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ead_ptx_sreg_tid_", 17))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'x':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_x;	 // "__nvvm_read_ptx_sreg_tid_x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_y;	 // "__nvvm_read_ptx_sreg_tid_y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_tid_z;	 // "__nvvm_read_ptx_sreg_tid_z"
+        }
+        break;
+      case 's':	 // 27 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ust_", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'b':	 // 21 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_", 2))
+              break;
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'i':	 // 3 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i16_clamp;	 // "__nvvm_sust_b_1d_i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i32_clamp;	 // "__nvvm_sust_b_1d_i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_i64_clamp;	 // "__nvvm_sust_b_1d_i64_clamp"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i8_trap;	 // "__nvvm_sust_b_1d_v2i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i8_zero;	 // "__nvvm_sust_b_1d_v2i8_zero"
+                }
+                break;
+              case '4':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i8_trap;	 // "__nvvm_sust_b_1d_v4i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i8_zero;	 // "__nvvm_sust_b_1d_v4i8_zero"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '2':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_", 2))
+              break;
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'i':	 // 3 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i16_clamp;	 // "__nvvm_sust_b_2d_i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i32_clamp;	 // "__nvvm_sust_b_2d_i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_i64_clamp;	 // "__nvvm_sust_b_2d_i64_clamp"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i8_trap;	 // "__nvvm_sust_b_2d_v2i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i8_zero;	 // "__nvvm_sust_b_2d_v2i8_zero"
+                }
+                break;
+              case '4':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i8_trap;	 // "__nvvm_sust_b_2d_v4i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i8_zero;	 // "__nvvm_sust_b_2d_v4i8_zero"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case '3':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_", 2))
+              break;
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'i':	 // 3 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i16_clamp;	 // "__nvvm_sust_b_3d_i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i32_clamp;	 // "__nvvm_sust_b_3d_i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+19, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_i64_clamp;	 // "__nvvm_sust_b_3d_i64_clamp"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case '2':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i8_trap;	 // "__nvvm_sust_b_3d_v2i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i8_zero;	 // "__nvvm_sust_b_3d_v2i8_zero"
+                }
+                break;
+              case '4':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+19, "i8_", 3))
+                  break;
+                switch (BuiltinName[22]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i8_trap;	 // "__nvvm_sust_b_3d_v4i8_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+23, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i8_zero;	 // "__nvvm_sust_b_3d_v4i8_zero"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 6 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_v2i8_trap;	 // "__nvvm_sust_p_1d_v2i8_trap"
+            case '4':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_1d_v4i8_trap;	 // "__nvvm_sust_p_1d_v4i8_trap"
+            }
+            break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_v2i8_trap;	 // "__nvvm_sust_p_2d_v2i8_trap"
+            case '4':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_2d_v4i8_trap;	 // "__nvvm_sust_p_2d_v4i8_trap"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_3d_v2i8_trap;	 // "__nvvm_sust_p_3d_v2i8_trap"
+            case '4':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+19, "i8_trap", 7))
+                break;
+              return Intrinsic::nvvm_sust_p_3d_v4i8_trap;	 // "__nvvm_sust_p_3d_v4i8_trap"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 27:	 // 56 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_", 7))
+        break;
+      switch (BuiltinName[10]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+11, "djust_trampoline", 16))
+          break;
+        return Intrinsic::adjust_trampoline;	 // "__builtin_adjust_trampoline"
+      case 'p':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+11, "tx_read_nctaid_", 15))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'w':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_w;	 // "__builtin_ptx_read_nctaid_w"
+        case 'x':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_x;	 // "__builtin_ptx_read_nctaid_x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_y;	 // "__builtin_ptx_read_nctaid_y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::ptx_read_nctaid_z;	 // "__builtin_ptx_read_nctaid_z"
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 51 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ead_ptx_sreg_ntid_", 18))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'x':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_x;	 // "__nvvm_read_ptx_sreg_ntid_x"
+        case 'y':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_y;	 // "__nvvm_read_ptx_sreg_ntid_y"
+        case 'z':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_ntid_z;	 // "__nvvm_read_ptx_sreg_ntid_z"
+        }
+        break;
+      case 's':	 // 48 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ust_", 4))
+          break;
+        switch (BuiltinName[12]) {
+        default: break;
+        case 'b':	 // 36 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 12 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i16_trap;	 // "__nvvm_sust_b_1d_v2i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i16_zero;	 // "__nvvm_sust_b_1d_v2i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i32_trap;	 // "__nvvm_sust_b_1d_v2i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i32_zero;	 // "__nvvm_sust_b_1d_v2i32_zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "4_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i64_trap;	 // "__nvvm_sust_b_1d_v2i64_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v2i64_zero;	 // "__nvvm_sust_b_1d_v2i64_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i8_clamp;	 // "__nvvm_sust_b_1d_v2i8_clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i16_trap;	 // "__nvvm_sust_b_1d_v4i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i16_zero;	 // "__nvvm_sust_b_1d_v4i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i32_trap;	 // "__nvvm_sust_b_1d_v4i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_1d_v4i32_zero;	 // "__nvvm_sust_b_1d_v4i32_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i8_clamp;	 // "__nvvm_sust_b_1d_v4i8_clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 12 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i16_trap;	 // "__nvvm_sust_b_2d_v2i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i16_zero;	 // "__nvvm_sust_b_2d_v2i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i32_trap;	 // "__nvvm_sust_b_2d_v2i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i32_zero;	 // "__nvvm_sust_b_2d_v2i32_zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "4_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i64_trap;	 // "__nvvm_sust_b_2d_v2i64_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v2i64_zero;	 // "__nvvm_sust_b_2d_v2i64_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i8_clamp;	 // "__nvvm_sust_b_2d_v2i8_clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i16_trap;	 // "__nvvm_sust_b_2d_v4i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i16_zero;	 // "__nvvm_sust_b_2d_v4i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i32_trap;	 // "__nvvm_sust_b_2d_v4i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_2d_v4i32_zero;	 // "__nvvm_sust_b_2d_v4i32_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i8_clamp;	 // "__nvvm_sust_b_2d_v4i8_clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 12 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 7 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i16_trap;	 // "__nvvm_sust_b_3d_v2i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i16_zero;	 // "__nvvm_sust_b_3d_v2i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i32_trap;	 // "__nvvm_sust_b_3d_v2i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i32_zero;	 // "__nvvm_sust_b_3d_v2i32_zero"
+                }
+                break;
+              case '6':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "4_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i64_trap;	 // "__nvvm_sust_b_3d_v2i64_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v2i64_zero;	 // "__nvvm_sust_b_3d_v2i64_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i8_clamp;	 // "__nvvm_sust_b_3d_v2i8_clamp"
+              }
+              break;
+            case '4':	 // 5 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "6_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i16_trap;	 // "__nvvm_sust_b_3d_v4i16_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i16_zero;	 // "__nvvm_sust_b_3d_v4i16_zero"
+                }
+                break;
+              case '3':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+21, "2_", 2))
+                  break;
+                switch (BuiltinName[23]) {
+                default: break;
+                case 't':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "rap", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i32_trap;	 // "__nvvm_sust_b_3d_v4i32_trap"
+                case 'z':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "ero", 3))
+                    break;
+                  return Intrinsic::nvvm_sust_b_3d_v4i32_zero;	 // "__nvvm_sust_b_3d_v4i32_zero"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "_clamp", 6))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i8_clamp;	 // "__nvvm_sust_b_3d_v4i8_clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 12 strings to match.
+          if (BuiltinName[13] != '_')
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v2i16_trap;	 // "__nvvm_sust_p_1d_v2i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v2i32_trap;	 // "__nvvm_sust_p_1d_v2i32_trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v4i16_trap;	 // "__nvvm_sust_p_1d_v4i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_1d_v4i32_trap;	 // "__nvvm_sust_p_1d_v4i32_trap"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v2i16_trap;	 // "__nvvm_sust_p_2d_v2i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v2i32_trap;	 // "__nvvm_sust_p_2d_v2i32_trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v4i16_trap;	 // "__nvvm_sust_p_2d_v4i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_2d_v4i32_trap;	 // "__nvvm_sust_p_2d_v4i32_trap"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v2i16_trap;	 // "__nvvm_sust_p_3d_v2i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v2i32_trap;	 // "__nvvm_sust_p_3d_v2i32_trap"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v4i16_trap;	 // "__nvvm_sust_p_3d_v4i16_trap"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_trap", 6))
+                  break;
+                return Intrinsic::nvvm_sust_p_3d_v4i32_trap;	 // "__nvvm_sust_p_3d_v4i32_trap"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 28:	 // 33 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_ia32_vpermil2p", 21))
+        break;
+      switch (BuiltinName[24]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+25, "256", 3))
+          break;
+        return Intrinsic::x86_xop_vpermil2pd_256;	 // "__builtin_ia32_vpermil2pd256"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+25, "256", 3))
+          break;
+        return Intrinsic::x86_xop_vpermil2ps_256;	 // "__builtin_ia32_vpermil2ps256"
+      }
+      break;
+    case 'n':	 // 31 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_", 4))
+        break;
+      switch (BuiltinName[7]) {
+      default: break;
+      case 'r':	 // 13 strings to match.
+        if (memcmp(BuiltinName.data()+8, "ead_ptx_sreg_", 13))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+22, "taid_", 5))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'x':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_x;	 // "__nvvm_read_ptx_sreg_ctaid_x"
+          case 'y':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_y;	 // "__nvvm_read_ptx_sreg_ctaid_y"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_ctaid_z;	 // "__nvvm_read_ptx_sreg_ctaid_z"
+          }
+          break;
+        case 'e':	 // 10 strings to match.
+          if (memcmp(BuiltinName.data()+22, "nvreg", 5))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg0;	 // "__nvvm_read_ptx_sreg_envreg0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg1;	 // "__nvvm_read_ptx_sreg_envreg1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg2;	 // "__nvvm_read_ptx_sreg_envreg2"
+          case '3':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg3;	 // "__nvvm_read_ptx_sreg_envreg3"
+          case '4':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg4;	 // "__nvvm_read_ptx_sreg_envreg4"
+          case '5':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg5;	 // "__nvvm_read_ptx_sreg_envreg5"
+          case '6':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg6;	 // "__nvvm_read_ptx_sreg_envreg6"
+          case '7':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg7;	 // "__nvvm_read_ptx_sreg_envreg7"
+          case '8':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg8;	 // "__nvvm_read_ptx_sreg_envreg8"
+          case '9':	 // 1 string to match.
+            return Intrinsic::nvvm_read_ptx_sreg_envreg9;	 // "__nvvm_read_ptx_sreg_envreg9"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 16 strings to match.
+        if (BuiltinName[8] != 'u')
+          break;
+        switch (BuiltinName[9]) {
+        default: break;
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+10, "_channel_data_type", 18))
+            break;
+          return Intrinsic::nvvm_suq_channel_data_type;	 // "__nvvm_suq_channel_data_type"
+        case 's':	 // 15 strings to match.
+          if (memcmp(BuiltinName.data()+10, "t_b_", 4))
+            break;
+          switch (BuiltinName[14]) {
+          default: break;
+          case '1':	 // 5 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i16_clamp;	 // "__nvvm_sust_b_1d_v2i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i32_clamp;	 // "__nvvm_sust_b_1d_v2i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v2i64_clamp;	 // "__nvvm_sust_b_1d_v2i64_clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i16_clamp;	 // "__nvvm_sust_b_1d_v4i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_1d_v4i32_clamp;	 // "__nvvm_sust_b_1d_v4i32_clamp"
+              }
+              break;
+            }
+            break;
+          case '2':	 // 5 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i16_clamp;	 // "__nvvm_sust_b_2d_v2i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i32_clamp;	 // "__nvvm_sust_b_2d_v2i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v2i64_clamp;	 // "__nvvm_sust_b_2d_v2i64_clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i16_clamp;	 // "__nvvm_sust_b_2d_v4i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_2d_v4i32_clamp;	 // "__nvvm_sust_b_2d_v4i32_clamp"
+              }
+              break;
+            }
+            break;
+          case '3':	 // 5 strings to match.
+            if (memcmp(BuiltinName.data()+15, "d_v", 3))
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case '2':	 // 3 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i16_clamp;	 // "__nvvm_sust_b_3d_v2i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i32_clamp;	 // "__nvvm_sust_b_3d_v2i32_clamp"
+              case '6':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "4_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v2i64_clamp;	 // "__nvvm_sust_b_3d_v2i64_clamp"
+              }
+              break;
+            case '4':	 // 2 strings to match.
+              if (BuiltinName[19] != 'i')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "6_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i16_clamp;	 // "__nvvm_sust_b_3d_v4i16_clamp"
+              case '3':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "2_clamp", 7))
+                  break;
+                return Intrinsic::nvvm_sust_b_3d_v4i32_clamp;	 // "__nvvm_sust_b_3d_v4i32_clamp"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+8, "xq_", 3))
+          break;
+        switch (BuiltinName[11]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "hannel_data_type", 16))
+            break;
+          return Intrinsic::nvvm_txq_channel_data_type;	 // "__nvvm_txq_channel_data_type"
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+12, "um_mipmap_levels", 16))
+            break;
+          return Intrinsic::nvvm_txq_num_mipmap_levels;	 // "__nvvm_txq_num_mipmap_levels"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 29:	 // 26 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_read_ptx_sreg_", 21))
+      break;
+    switch (BuiltinName[21]) {
+    default: break;
+    case 'e':	 // 22 strings to match.
+      if (memcmp(BuiltinName.data()+22, "nvreg", 5))
+        break;
+      switch (BuiltinName[27]) {
+      default: break;
+      case '1':	 // 10 strings to match.
+        switch (BuiltinName[28]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg10;	 // "__nvvm_read_ptx_sreg_envreg10"
+        case '1':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg11;	 // "__nvvm_read_ptx_sreg_envreg11"
+        case '2':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg12;	 // "__nvvm_read_ptx_sreg_envreg12"
+        case '3':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg13;	 // "__nvvm_read_ptx_sreg_envreg13"
+        case '4':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg14;	 // "__nvvm_read_ptx_sreg_envreg14"
+        case '5':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg15;	 // "__nvvm_read_ptx_sreg_envreg15"
+        case '6':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg16;	 // "__nvvm_read_ptx_sreg_envreg16"
+        case '7':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg17;	 // "__nvvm_read_ptx_sreg_envreg17"
+        case '8':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg18;	 // "__nvvm_read_ptx_sreg_envreg18"
+        case '9':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg19;	 // "__nvvm_read_ptx_sreg_envreg19"
+        }
+        break;
+      case '2':	 // 10 strings to match.
+        switch (BuiltinName[28]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg20;	 // "__nvvm_read_ptx_sreg_envreg20"
+        case '1':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg21;	 // "__nvvm_read_ptx_sreg_envreg21"
+        case '2':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg22;	 // "__nvvm_read_ptx_sreg_envreg22"
+        case '3':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg23;	 // "__nvvm_read_ptx_sreg_envreg23"
+        case '4':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg24;	 // "__nvvm_read_ptx_sreg_envreg24"
+        case '5':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg25;	 // "__nvvm_read_ptx_sreg_envreg25"
+        case '6':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg26;	 // "__nvvm_read_ptx_sreg_envreg26"
+        case '7':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg27;	 // "__nvvm_read_ptx_sreg_envreg27"
+        case '8':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg28;	 // "__nvvm_read_ptx_sreg_envreg28"
+        case '9':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg29;	 // "__nvvm_read_ptx_sreg_envreg29"
+        }
+        break;
+      case '3':	 // 2 strings to match.
+        switch (BuiltinName[28]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg30;	 // "__nvvm_read_ptx_sreg_envreg30"
+        case '1':	 // 1 string to match.
+          return Intrinsic::nvvm_read_ptx_sreg_envreg31;	 // "__nvvm_read_ptx_sreg_envreg31"
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+22, "ctaid_", 6))
+        break;
+      switch (BuiltinName[28]) {
+      default: break;
+      case 'x':	 // 1 string to match.
+        return Intrinsic::nvvm_read_ptx_sreg_nctaid_x;	 // "__nvvm_read_ptx_sreg_nctaid_x"
+      case 'y':	 // 1 string to match.
+        return Intrinsic::nvvm_read_ptx_sreg_nctaid_y;	 // "__nvvm_read_ptx_sreg_nctaid_y"
+      case 'z':	 // 1 string to match.
+        return Intrinsic::nvvm_read_ptx_sreg_nctaid_z;	 // "__nvvm_read_ptx_sreg_nctaid_z"
+      }
+      break;
+    case 'w':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+22, "arpsize", 7))
+        break;
+      return Intrinsic::nvvm_read_ptx_sreg_warpsize;	 // "__nvvm_read_ptx_sreg_warpsize"
+    }
+    break;
+  case 30:	 // 11 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'b':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+3, "uiltin_ptx_read_lanemask_", 25))
+        break;
+      switch (BuiltinName[28]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (BuiltinName[29] != 'q')
+          break;
+        return Intrinsic::ptx_read_lanemask_eq;	 // "__builtin_ptx_read_lanemask_eq"
+      case 'g':	 // 2 strings to match.
+        switch (BuiltinName[29]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::ptx_read_lanemask_ge;	 // "__builtin_ptx_read_lanemask_ge"
+        case 't':	 // 1 string to match.
+          return Intrinsic::ptx_read_lanemask_gt;	 // "__builtin_ptx_read_lanemask_gt"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[29]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::ptx_read_lanemask_le;	 // "__builtin_ptx_read_lanemask_le"
+        case 't':	 // 1 string to match.
+          return Intrinsic::ptx_read_lanemask_lt;	 // "__builtin_ptx_read_lanemask_lt"
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+3, "vvm_sust_", 9))
+        break;
+      switch (BuiltinName[12]) {
+      default: break;
+      case 'b':	 // 4 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case '1':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+15, "d_array_i8_", 11))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i8_trap;	 // "__nvvm_sust_b_1d_array_i8_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i8_zero;	 // "__nvvm_sust_b_1d_array_i8_zero"
+          }
+          break;
+        case '2':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+15, "d_array_i8_", 11))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i8_trap;	 // "__nvvm_sust_b_2d_array_i8_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i8_zero;	 // "__nvvm_sust_b_2d_array_i8_zero"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (BuiltinName[13] != '_')
+          break;
+        switch (BuiltinName[14]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+15, "d_array_i8_trap", 15))
+            break;
+          return Intrinsic::nvvm_sust_p_1d_array_i8_trap;	 // "__nvvm_sust_p_1d_array_i8_trap"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+15, "d_array_i8_trap", 15))
+            break;
+          return Intrinsic::nvvm_sust_p_2d_array_i8_trap;	 // "__nvvm_sust_p_2d_array_i8_trap"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 31:	 // 18 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_sust_", 12))
+      break;
+    switch (BuiltinName[12]) {
+    default: break;
+    case 'b':	 // 14 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_i", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "6_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i16_trap;	 // "__nvvm_sust_b_1d_array_i16_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i16_zero;	 // "__nvvm_sust_b_1d_array_i16_zero"
+          }
+          break;
+        case '3':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "2_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i32_trap;	 // "__nvvm_sust_b_1d_array_i32_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i32_zero;	 // "__nvvm_sust_b_1d_array_i32_zero"
+          }
+          break;
+        case '6':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "4_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i64_trap;	 // "__nvvm_sust_b_1d_array_i64_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i64_zero;	 // "__nvvm_sust_b_1d_array_i64_zero"
+          }
+          break;
+        case '8':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "_clamp", 6))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_i8_clamp;	 // "__nvvm_sust_b_1d_array_i8_clamp"
+        }
+        break;
+      case '2':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_i", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "6_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i16_trap;	 // "__nvvm_sust_b_2d_array_i16_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i16_zero;	 // "__nvvm_sust_b_2d_array_i16_zero"
+          }
+          break;
+        case '3':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "2_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i32_trap;	 // "__nvvm_sust_b_2d_array_i32_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i32_zero;	 // "__nvvm_sust_b_2d_array_i32_zero"
+          }
+          break;
+        case '6':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+25, "4_", 2))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "rap", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i64_trap;	 // "__nvvm_sust_b_2d_array_i64_trap"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ero", 3))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i64_zero;	 // "__nvvm_sust_b_2d_array_i64_zero"
+          }
+          break;
+        case '8':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "_clamp", 6))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_i8_clamp;	 // "__nvvm_sust_b_2d_array_i8_clamp"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 4 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_i", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "6_trap", 6))
+            break;
+          return Intrinsic::nvvm_sust_p_1d_array_i16_trap;	 // "__nvvm_sust_p_1d_array_i16_trap"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "2_trap", 6))
+            break;
+          return Intrinsic::nvvm_sust_p_1d_array_i32_trap;	 // "__nvvm_sust_p_1d_array_i32_trap"
+        }
+        break;
+      case '2':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_i", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "6_trap", 6))
+            break;
+          return Intrinsic::nvvm_sust_p_2d_array_i16_trap;	 // "__nvvm_sust_p_2d_array_i16_trap"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "2_trap", 6))
+            break;
+          return Intrinsic::nvvm_sust_p_2d_array_i32_trap;	 // "__nvvm_sust_p_2d_array_i32_trap"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 32:	 // 18 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_sust_", 12))
+      break;
+    switch (BuiltinName[12]) {
+    default: break;
+    case 'b':	 // 14 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_", 8))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'i':	 // 3 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "6_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i16_clamp;	 // "__nvvm_sust_b_1d_array_i16_clamp"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "2_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i32_clamp;	 // "__nvvm_sust_b_1d_array_i32_clamp"
+          case '6':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "4_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_i64_clamp;	 // "__nvvm_sust_b_1d_array_i64_clamp"
+          }
+          break;
+        case 'v':	 // 4 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "i8_", 3))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i8_trap;	 // "__nvvm_sust_b_1d_array_v2i8_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i8_zero;	 // "__nvvm_sust_b_1d_array_v2i8_zero"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "i8_", 3))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i8_trap;	 // "__nvvm_sust_b_1d_array_v4i8_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i8_zero;	 // "__nvvm_sust_b_1d_array_v4i8_zero"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '2':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_", 8))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'i':	 // 3 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "6_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i16_clamp;	 // "__nvvm_sust_b_2d_array_i16_clamp"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "2_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i32_clamp;	 // "__nvvm_sust_b_2d_array_i32_clamp"
+          case '6':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "4_clamp", 7))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_i64_clamp;	 // "__nvvm_sust_b_2d_array_i64_clamp"
+          }
+          break;
+        case 'v':	 // 4 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case '2':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "i8_", 3))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i8_trap;	 // "__nvvm_sust_b_2d_array_v2i8_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i8_zero;	 // "__nvvm_sust_b_2d_array_v2i8_zero"
+            }
+            break;
+          case '4':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "i8_", 3))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i8_trap;	 // "__nvvm_sust_b_2d_array_v4i8_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+29, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i8_zero;	 // "__nvvm_sust_b_2d_array_v4i8_zero"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 4 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "i8_trap", 7))
+            break;
+          return Intrinsic::nvvm_sust_p_1d_array_v2i8_trap;	 // "__nvvm_sust_p_1d_array_v2i8_trap"
+        case '4':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "i8_trap", 7))
+            break;
+          return Intrinsic::nvvm_sust_p_1d_array_v4i8_trap;	 // "__nvvm_sust_p_1d_array_v4i8_trap"
+        }
+        break;
+      case '2':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "i8_trap", 7))
+            break;
+          return Intrinsic::nvvm_sust_p_2d_array_v2i8_trap;	 // "__nvvm_sust_p_2d_array_v2i8_trap"
+        case '4':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "i8_trap", 7))
+            break;
+          return Intrinsic::nvvm_sust_p_2d_array_v4i8_trap;	 // "__nvvm_sust_p_2d_array_v4i8_trap"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 33:	 // 32 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_sust_", 12))
+      break;
+    switch (BuiltinName[12]) {
+    default: break;
+    case 'b':	 // 24 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 12 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 7 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "6_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i16_trap;	 // "__nvvm_sust_b_1d_array_v2i16_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i16_zero;	 // "__nvvm_sust_b_1d_array_v2i16_zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "2_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i32_trap;	 // "__nvvm_sust_b_1d_array_v2i32_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i32_zero;	 // "__nvvm_sust_b_1d_array_v2i32_zero"
+            }
+            break;
+          case '6':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "4_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i64_trap;	 // "__nvvm_sust_b_1d_array_v2i64_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v2i64_zero;	 // "__nvvm_sust_b_1d_array_v2i64_zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_clamp", 6))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_v2i8_clamp;	 // "__nvvm_sust_b_1d_array_v2i8_clamp"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "6_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i16_trap;	 // "__nvvm_sust_b_1d_array_v4i16_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i16_zero;	 // "__nvvm_sust_b_1d_array_v4i16_zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "2_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i32_trap;	 // "__nvvm_sust_b_1d_array_v4i32_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_1d_array_v4i32_zero;	 // "__nvvm_sust_b_1d_array_v4i32_zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_clamp", 6))
+              break;
+            return Intrinsic::nvvm_sust_b_1d_array_v4i8_clamp;	 // "__nvvm_sust_b_1d_array_v4i8_clamp"
+          }
+          break;
+        }
+        break;
+      case '2':	 // 12 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 7 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "6_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i16_trap;	 // "__nvvm_sust_b_2d_array_v2i16_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i16_zero;	 // "__nvvm_sust_b_2d_array_v2i16_zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "2_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i32_trap;	 // "__nvvm_sust_b_2d_array_v2i32_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i32_zero;	 // "__nvvm_sust_b_2d_array_v2i32_zero"
+            }
+            break;
+          case '6':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "4_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i64_trap;	 // "__nvvm_sust_b_2d_array_v2i64_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v2i64_zero;	 // "__nvvm_sust_b_2d_array_v2i64_zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_clamp", 6))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_v2i8_clamp;	 // "__nvvm_sust_b_2d_array_v2i8_clamp"
+          }
+          break;
+        case '4':	 // 5 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "6_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i16_trap;	 // "__nvvm_sust_b_2d_array_v4i16_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i16_zero;	 // "__nvvm_sust_b_2d_array_v4i16_zero"
+            }
+            break;
+          case '3':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "2_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 't':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "rap", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i32_trap;	 // "__nvvm_sust_b_2d_array_v4i32_trap"
+            case 'z':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ero", 3))
+                break;
+              return Intrinsic::nvvm_sust_b_2d_array_v4i32_zero;	 // "__nvvm_sust_b_2d_array_v4i32_zero"
+            }
+            break;
+          case '8':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_clamp", 6))
+              break;
+            return Intrinsic::nvvm_sust_b_2d_array_v4i8_clamp;	 // "__nvvm_sust_b_2d_array_v4i8_clamp"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 8 strings to match.
+      if (BuiltinName[13] != '_')
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case '1':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 2 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "6_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_1d_array_v2i16_trap;	 // "__nvvm_sust_p_1d_array_v2i16_trap"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "2_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_1d_array_v2i32_trap;	 // "__nvvm_sust_p_1d_array_v2i32_trap"
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "6_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_1d_array_v4i16_trap;	 // "__nvvm_sust_p_1d_array_v4i16_trap"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "2_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_1d_array_v4i32_trap;	 // "__nvvm_sust_p_1d_array_v4i32_trap"
+          }
+          break;
+        }
+        break;
+      case '2':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '2':	 // 2 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "6_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_2d_array_v2i16_trap;	 // "__nvvm_sust_p_2d_array_v2i16_trap"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "2_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_2d_array_v2i32_trap;	 // "__nvvm_sust_p_2d_array_v2i32_trap"
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (BuiltinName[25] != 'i')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "6_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_2d_array_v4i16_trap;	 // "__nvvm_sust_p_2d_array_v4i16_trap"
+          case '3':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "2_trap", 6))
+              break;
+            return Intrinsic::nvvm_sust_p_2d_array_v4i32_trap;	 // "__nvvm_sust_p_2d_array_v4i32_trap"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 34:	 // 10 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__nvvm_sust_b_", 14))
+      break;
+    switch (BuiltinName[14]) {
+    default: break;
+    case '1':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+        break;
+      switch (BuiltinName[24]) {
+      default: break;
+      case '2':	 // 3 strings to match.
+        if (BuiltinName[25] != 'i')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "6_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_v2i16_clamp;	 // "__nvvm_sust_b_1d_array_v2i16_clamp"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "2_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_v2i32_clamp;	 // "__nvvm_sust_b_1d_array_v2i32_clamp"
+        case '6':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "4_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_v2i64_clamp;	 // "__nvvm_sust_b_1d_array_v2i64_clamp"
+        }
+        break;
+      case '4':	 // 2 strings to match.
+        if (BuiltinName[25] != 'i')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "6_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_v4i16_clamp;	 // "__nvvm_sust_b_1d_array_v4i16_clamp"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "2_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_1d_array_v4i32_clamp;	 // "__nvvm_sust_b_1d_array_v4i32_clamp"
+        }
+        break;
+      }
+      break;
+    case '2':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+15, "d_array_v", 9))
+        break;
+      switch (BuiltinName[24]) {
+      default: break;
+      case '2':	 // 3 strings to match.
+        if (BuiltinName[25] != 'i')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "6_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_v2i16_clamp;	 // "__nvvm_sust_b_2d_array_v2i16_clamp"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "2_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_v2i32_clamp;	 // "__nvvm_sust_b_2d_array_v2i32_clamp"
+        case '6':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "4_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_v2i64_clamp;	 // "__nvvm_sust_b_2d_array_v2i64_clamp"
+        }
+        break;
+      case '4':	 // 2 strings to match.
+        if (BuiltinName[25] != 'i')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "6_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_v4i16_clamp;	 // "__nvvm_sust_b_2d_array_v4i16_clamp"
+        case '3':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "2_clamp", 7))
+            break;
+          return Intrinsic::nvvm_sust_b_2d_array_v4i32_clamp;	 // "__nvvm_sust_b_2d_array_v4i32_clamp"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  }
+  }
+  if (TargetPrefix == "AMDGPU") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 20:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_amdgpu_r", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (BuiltinName[19] != 'p')
+        break;
+      return Intrinsic::AMDGPU_rcp;	 // "__builtin_amdgpu_rcp"
+    case 's':	 // 1 string to match.
+      if (BuiltinName[19] != 'q')
+        break;
+      return Intrinsic::AMDGPU_rsq;	 // "__builtin_amdgpu_rsq"
+    }
+    break;
+  case 25:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_amdgpu_div_fmas", 25))
+      break;
+    return Intrinsic::AMDGPU_div_fmas;	 // "__builtin_amdgpu_div_fmas"
+  case 26:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_amdgpu_div_", 21))
+      break;
+    switch (BuiltinName[21]) {
+    default: break;
+    case 'f':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+22, "ixup", 4))
+        break;
+      return Intrinsic::AMDGPU_div_fixup;	 // "__builtin_amdgpu_div_fixup"
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+22, "cale", 4))
+        break;
+      return Intrinsic::AMDGPU_div_scale;	 // "__builtin_amdgpu_div_scale"
+    }
+    break;
+  case 27:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_amdgpu_trig_preop", 27))
+      break;
+    return Intrinsic::AMDGPU_trig_preop;	 // "__builtin_amdgpu_trig_preop"
+  case 28:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_amdgpu_rsq_clamped", 28))
+      break;
+    return Intrinsic::AMDGPU_rsq_clamped;	 // "__builtin_amdgpu_rsq_clamped"
+  }
+  }
+  if (TargetPrefix == "aarch64") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 17:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_arm_", 14))
+      break;
+    switch (BuiltinName[14]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (BuiltinName[16] != 'b')
+          break;
+        return Intrinsic::aarch64_dmb;	 // "__builtin_arm_dmb"
+      case 's':	 // 1 string to match.
+        if (BuiltinName[16] != 'b')
+          break;
+        return Intrinsic::aarch64_dsb;	 // "__builtin_arm_dsb"
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "sb", 2))
+        break;
+      return Intrinsic::aarch64_isb;	 // "__builtin_arm_isb"
+    }
+    break;
+  }
+  }
+  if (TargetPrefix == "arm") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 17:	 // 6 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_arm_", 14))
+      break;
+    switch (BuiltinName[14]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "dp", 2))
+        break;
+      return Intrinsic::arm_cdp;	 // "__builtin_arm_cdp"
+    case 'd':	 // 2 strings to match.
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (BuiltinName[16] != 'b')
+          break;
+        return Intrinsic::arm_dmb;	 // "__builtin_arm_dmb"
+      case 's':	 // 1 string to match.
+        if (BuiltinName[16] != 'b')
+          break;
+        return Intrinsic::arm_dsb;	 // "__builtin_arm_dsb"
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "sb", 2))
+        break;
+      return Intrinsic::arm_isb;	 // "__builtin_arm_isb"
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (BuiltinName[16] != 'r')
+          break;
+        return Intrinsic::arm_mcr;	 // "__builtin_arm_mcr"
+      case 'r':	 // 1 string to match.
+        if (BuiltinName[16] != 'c')
+          break;
+        return Intrinsic::arm_mrc;	 // "__builtin_arm_mrc"
+      }
+      break;
+    }
+    break;
+  case 18:	 // 8 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_arm_", 14))
+      break;
+    switch (BuiltinName[14]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "dp2", 3))
+        break;
+      return Intrinsic::arm_cdp2;	 // "__builtin_arm_cdp2"
+    case 'm':	 // 3 strings to match.
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (BuiltinName[16] != 'r')
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          return Intrinsic::arm_mcr2;	 // "__builtin_arm_mcr2"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::arm_mcrr;	 // "__builtin_arm_mcrr"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "c2", 2))
+          break;
+        return Intrinsic::arm_mrc2;	 // "__builtin_arm_mrc2"
+      }
+      break;
+    case 'q':	 // 2 strings to match.
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "dd", 2))
+          break;
+        return Intrinsic::arm_qadd;	 // "__builtin_arm_qadd"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "ub", 2))
+          break;
+        return Intrinsic::arm_qsub;	 // "__builtin_arm_qsub"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "sat", 3))
+        break;
+      return Intrinsic::arm_ssat;	 // "__builtin_arm_ssat"
+    case 'u':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "sat", 3))
+        break;
+      return Intrinsic::arm_usat;	 // "__builtin_arm_usat"
+    }
+    break;
+  case 19:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_arm_mcrr2", 19))
+      break;
+    return Intrinsic::arm_mcrr2;	 // "__builtin_arm_mcrr2"
+  case 23:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_arm_", 14))
+      break;
+    switch (BuiltinName[14]) {
+    default: break;
+    case 'g':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "et_fpscr", 8))
+        break;
+      return Intrinsic::arm_get_fpscr;	 // "__builtin_arm_get_fpscr"
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+15, "et_fpscr", 8))
+        break;
+      return Intrinsic::arm_set_fpscr;	 // "__builtin_arm_set_fpscr"
+    }
+    break;
+  case 24:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_thread_pointer", 24))
+      break;
+    return Intrinsic::arm_thread_pointer;	 // "__builtin_thread_pointer"
+  }
+  }
+  if (TargetPrefix == "hexagon") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 18:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_circ_ldd", 18))
+      break;
+    return Intrinsic::hexagon_circ_ldd;	 // "__builtin_circ_ldd"
+  case 23:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "2_or", 4))
+        break;
+      return Intrinsic::hexagon_A2_or;	 // "__builtin_HEXAGON_A2_or"
+    case 'C':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "2_or", 4))
+        break;
+      return Intrinsic::hexagon_C2_or;	 // "__builtin_HEXAGON_C2_or"
+    }
+    break;
+  case 24:	 // 23 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 13 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 12 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (BuiltinName[23] != 's')
+              break;
+            return Intrinsic::hexagon_A2_abs;	 // "__builtin_HEXAGON_A2_abs"
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[23] != 'd')
+              break;
+            return Intrinsic::hexagon_A2_add;	 // "__builtin_HEXAGON_A2_add"
+          case 'n':	 // 1 string to match.
+            if (BuiltinName[23] != 'd')
+              break;
+            return Intrinsic::hexagon_A2_and;	 // "__builtin_HEXAGON_A2_and"
+          }
+          break;
+        case 'm':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (BuiltinName[23] != 'x')
+              break;
+            return Intrinsic::hexagon_A2_max;	 // "__builtin_HEXAGON_A2_max"
+          case 'i':	 // 1 string to match.
+            if (BuiltinName[23] != 'n')
+              break;
+            return Intrinsic::hexagon_A2_min;	 // "__builtin_HEXAGON_A2_min"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (BuiltinName[23] != 'g')
+              break;
+            return Intrinsic::hexagon_A2_neg;	 // "__builtin_HEXAGON_A2_neg"
+          case 'o':	 // 1 string to match.
+            if (BuiltinName[23] != 't')
+              break;
+            return Intrinsic::hexagon_A2_not;	 // "__builtin_HEXAGON_A2_not"
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rp", 2))
+            break;
+          return Intrinsic::hexagon_A2_orp;	 // "__builtin_HEXAGON_A2_orp"
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (BuiltinName[23] != 't')
+              break;
+            return Intrinsic::hexagon_A2_sat;	 // "__builtin_HEXAGON_A2_sat"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[23] != 'b')
+              break;
+            return Intrinsic::hexagon_A2_sub;	 // "__builtin_HEXAGON_A2_sub"
+          }
+          break;
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "fr", 2))
+            break;
+          return Intrinsic::hexagon_A2_tfr;	 // "__builtin_HEXAGON_A2_tfr"
+        case 'x':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "or", 2))
+            break;
+          return Intrinsic::hexagon_A2_xor;	 // "__builtin_HEXAGON_A2_xor"
+        }
+        break;
+      case '4':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_orn", 4))
+          break;
+        return Intrinsic::hexagon_A4_orn;	 // "__builtin_HEXAGON_A4_orn"
+      }
+      break;
+    case 'C':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "nd", 2))
+          break;
+        return Intrinsic::hexagon_C2_and;	 // "__builtin_HEXAGON_C2_and"
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "ux", 2))
+          break;
+        return Intrinsic::hexagon_C2_mux;	 // "__builtin_HEXAGON_C2_mux"
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "ot", 2))
+          break;
+        return Intrinsic::hexagon_C2_not;	 // "__builtin_HEXAGON_C2_not"
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "rn", 2))
+          break;
+        return Intrinsic::hexagon_C2_orn;	 // "__builtin_HEXAGON_C2_orn"
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "or", 2))
+          break;
+        return Intrinsic::hexagon_C2_xor;	 // "__builtin_HEXAGON_C2_xor"
+      }
+      break;
+    case 'S':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_c", 3))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'l':	 // 3 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::hexagon_S2_cl0;	 // "__builtin_HEXAGON_S2_cl0"
+        case '1':	 // 1 string to match.
+          return Intrinsic::hexagon_S2_cl1;	 // "__builtin_HEXAGON_S2_cl1"
+        case 'b':	 // 1 string to match.
+          return Intrinsic::hexagon_S2_clb;	 // "__builtin_HEXAGON_S2_clb"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case '0':	 // 1 string to match.
+          return Intrinsic::hexagon_S2_ct0;	 // "__builtin_HEXAGON_S2_ct0"
+        case '1':	 // 1 string to match.
+          return Intrinsic::hexagon_S2_ct1;	 // "__builtin_HEXAGON_S2_ct1"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 25:	 // 42 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 26 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 24 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "sp", 2))
+              break;
+            return Intrinsic::hexagon_A2_absp;	 // "__builtin_HEXAGON_A2_absp"
+          case 'd':	 // 2 strings to match.
+            if (BuiltinName[23] != 'd')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addi;	 // "__builtin_HEXAGON_A2_addi"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addp;	 // "__builtin_HEXAGON_A2_addp"
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "dp", 2))
+              break;
+            return Intrinsic::hexagon_A2_andp;	 // "__builtin_HEXAGON_A2_andp"
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'l':	 // 1 string to match.
+              if (BuiltinName[24] != 'h')
+                break;
+              return Intrinsic::hexagon_A2_aslh;	 // "__builtin_HEXAGON_A2_aslh"
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[24] != 'h')
+                break;
+              return Intrinsic::hexagon_A2_asrh;	 // "__builtin_HEXAGON_A2_asrh"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (BuiltinName[23] != 'x')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_maxp;	 // "__builtin_HEXAGON_A2_maxp"
+            case 'u':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_maxu;	 // "__builtin_HEXAGON_A2_maxu"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (BuiltinName[23] != 'n')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_minp;	 // "__builtin_HEXAGON_A2_minp"
+            case 'u':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_minu;	 // "__builtin_HEXAGON_A2_minu"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "gp", 2))
+              break;
+            return Intrinsic::hexagon_A2_negp;	 // "__builtin_HEXAGON_A2_negp"
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "tp", 2))
+              break;
+            return Intrinsic::hexagon_A2_notp;	 // "__builtin_HEXAGON_A2_notp"
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rir", 3))
+            break;
+          return Intrinsic::hexagon_A2_orir;	 // "__builtin_HEXAGON_A2_orir"
+        case 's':	 // 7 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (BuiltinName[23] != 't')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_satb;	 // "__builtin_HEXAGON_A2_satb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_sath;	 // "__builtin_HEXAGON_A2_sath"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "bp", 2))
+              break;
+            return Intrinsic::hexagon_A2_subp;	 // "__builtin_HEXAGON_A2_subp"
+          case 'w':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "iz", 2))
+              break;
+            return Intrinsic::hexagon_A2_swiz;	 // "__builtin_HEXAGON_A2_swiz"
+          case 'x':	 // 3 strings to match.
+            if (BuiltinName[23] != 't')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_sxtb;	 // "__builtin_HEXAGON_A2_sxtb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_sxth;	 // "__builtin_HEXAGON_A2_sxth"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_sxtw;	 // "__builtin_HEXAGON_A2_sxtw"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "frp", 3))
+            break;
+          return Intrinsic::hexagon_A2_tfrp;	 // "__builtin_HEXAGON_A2_tfrp"
+        case 'x':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "orp", 3))
+            break;
+          return Intrinsic::hexagon_A2_xorp;	 // "__builtin_HEXAGON_A2_xorp"
+        case 'z':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "xt", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_zxtb;	 // "__builtin_HEXAGON_A2_zxtb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::hexagon_A2_zxth;	 // "__builtin_HEXAGON_A2_zxth"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 2 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ndn", 3))
+            break;
+          return Intrinsic::hexagon_A4_andn;	 // "__builtin_HEXAGON_A4_andn"
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rnp", 3))
+            break;
+          return Intrinsic::hexagon_A4_ornp;	 // "__builtin_HEXAGON_A4_ornp"
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "l8", 2))
+            break;
+          return Intrinsic::hexagon_C2_all8;	 // "__builtin_HEXAGON_C2_all8"
+        case 'n':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[24] != 'n')
+              break;
+            return Intrinsic::hexagon_C2_andn;	 // "__builtin_HEXAGON_C2_andn"
+          case 'y':	 // 1 string to match.
+            if (BuiltinName[24] != '8')
+              break;
+            return Intrinsic::hexagon_C2_any8;	 // "__builtin_HEXAGON_C2_any8"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "ask", 3))
+          break;
+        return Intrinsic::hexagon_C2_mask;	 // "__builtin_HEXAGON_C2_mask"
+      case 'v':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "mux", 3))
+          break;
+        return Intrinsic::hexagon_C2_vmux;	 // "__builtin_HEXAGON_C2_vmux"
+      }
+      break;
+    case 'M':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "cci", 3))
+          break;
+        return Intrinsic::hexagon_M2_acci;	 // "__builtin_HEXAGON_M2_acci"
+      case 'm':	 // 2 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "ci", 2))
+            break;
+          return Intrinsic::hexagon_M2_maci;	 // "__builtin_HEXAGON_M2_maci"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "yi", 2))
+            break;
+          return Intrinsic::hexagon_M2_mpyi;	 // "__builtin_HEXAGON_M2_mpyi"
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 8 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 7 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rev", 3))
+            break;
+          return Intrinsic::hexagon_S2_brev;	 // "__builtin_HEXAGON_S2_brev"
+        case 'c':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'l':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              if (BuiltinName[24] != 'p')
+                break;
+              return Intrinsic::hexagon_S2_cl0p;	 // "__builtin_HEXAGON_S2_cl0p"
+            case '1':	 // 1 string to match.
+              if (BuiltinName[24] != 'p')
+                break;
+              return Intrinsic::hexagon_S2_cl1p;	 // "__builtin_HEXAGON_S2_cl1p"
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[24] != 'p')
+                break;
+              return Intrinsic::hexagon_S2_clbp;	 // "__builtin_HEXAGON_S2_clbp"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              if (BuiltinName[24] != 'p')
+                break;
+              return Intrinsic::hexagon_S2_ct0p;	 // "__builtin_HEXAGON_S2_ct0p"
+            case '1':	 // 1 string to match.
+              if (BuiltinName[24] != 'p')
+                break;
+              return Intrinsic::hexagon_S2_ct1p;	 // "__builtin_HEXAGON_S2_ct1p"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "fsp", 3))
+            break;
+          return Intrinsic::hexagon_S2_lfsp;	 // "__builtin_HEXAGON_S2_lfsp"
+        }
+        break;
+      case '4':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_lsli", 5))
+          break;
+        return Intrinsic::hexagon_S4_lsli;	 // "__builtin_HEXAGON_S4_lsli"
+      }
+      break;
+    }
+    break;
+  case 26:	 // 58 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_", 10))
+      break;
+    switch (BuiltinName[10]) {
+    default: break;
+    case 'H':	 // 57 strings to match.
+      if (memcmp(BuiltinName.data()+11, "EXAGON_", 7))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'A':	 // 27 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case '2':	 // 26 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "dsp", 3))
+                break;
+              return Intrinsic::hexagon_A2_addsp;	 // "__builtin_HEXAGON_A2_addsp"
+            case 'n':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "dir", 3))
+                break;
+              return Intrinsic::hexagon_A2_andir;	 // "__builtin_HEXAGON_A2_andir"
+            }
+            break;
+          case 'm':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "xup", 3))
+                break;
+              return Intrinsic::hexagon_A2_maxup;	 // "__builtin_HEXAGON_A2_maxup"
+            case 'i':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "nup", 3))
+                break;
+              return Intrinsic::hexagon_A2_minup;	 // "__builtin_HEXAGON_A2_minup"
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+23, "tu", 2))
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_satub;	 // "__builtin_HEXAGON_A2_satub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_satuh;	 // "__builtin_HEXAGON_A2_satuh"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "bri", 3))
+                break;
+              return Intrinsic::hexagon_A2_subri;	 // "__builtin_HEXAGON_A2_subri"
+            }
+            break;
+          case 't':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+22, "fr", 2))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_tfrih;	 // "__builtin_HEXAGON_A2_tfrih"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_tfril;	 // "__builtin_HEXAGON_A2_tfril"
+              }
+              break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[25] != 'i')
+                break;
+              return Intrinsic::hexagon_A2_tfrpi;	 // "__builtin_HEXAGON_A2_tfrpi"
+            case 's':	 // 1 string to match.
+              if (BuiltinName[25] != 'i')
+                break;
+              return Intrinsic::hexagon_A2_tfrsi;	 // "__builtin_HEXAGON_A2_tfrsi"
+            }
+            break;
+          case 'v':	 // 15 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'a':	 // 6 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                if (BuiltinName[24] != 's')
+                  break;
+                switch (BuiltinName[25]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vabsh;	 // "__builtin_HEXAGON_A2_vabsh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vabsw;	 // "__builtin_HEXAGON_A2_vabsw"
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                if (BuiltinName[24] != 'd')
+                  break;
+                switch (BuiltinName[25]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vaddh;	 // "__builtin_HEXAGON_A2_vaddh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vaddw;	 // "__builtin_HEXAGON_A2_vaddw"
+                }
+                break;
+              case 'v':	 // 2 strings to match.
+                if (BuiltinName[24] != 'g')
+                  break;
+                switch (BuiltinName[25]) {
+                default: break;
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavgh;	 // "__builtin_HEXAGON_A2_vavgh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavgw;	 // "__builtin_HEXAGON_A2_vavgw"
+                }
+                break;
+              }
+              break;
+            case 'c':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "onj", 3))
+                break;
+              return Intrinsic::hexagon_A2_vconj;	 // "__builtin_HEXAGON_A2_vconj"
+            case 'm':	 // 6 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case 'a':	 // 3 strings to match.
+                if (BuiltinName[24] != 'x')
+                  break;
+                switch (BuiltinName[25]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxb;	 // "__builtin_HEXAGON_A2_vmaxb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxh;	 // "__builtin_HEXAGON_A2_vmaxh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vmaxw;	 // "__builtin_HEXAGON_A2_vmaxw"
+                }
+                break;
+              case 'i':	 // 3 strings to match.
+                if (BuiltinName[24] != 'n')
+                  break;
+                switch (BuiltinName[25]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminb;	 // "__builtin_HEXAGON_A2_vminb"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminh;	 // "__builtin_HEXAGON_A2_vminh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vminw;	 // "__builtin_HEXAGON_A2_vminw"
+                }
+                break;
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+23, "ub", 2))
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vsubh;	 // "__builtin_HEXAGON_A2_vsubh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vsubw;	 // "__builtin_HEXAGON_A2_vsubw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "_andnp", 6))
+            break;
+          return Intrinsic::hexagon_A4_andnp;	 // "__builtin_HEXAGON_A4_andnp"
+        }
+        break;
+      case 'C':	 // 9 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case '2':	 // 8 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'c':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+22, "mp", 2))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (BuiltinName[25] != 'q')
+                break;
+              return Intrinsic::hexagon_C2_cmpeq;	 // "__builtin_HEXAGON_C2_cmpeq"
+            case 'g':	 // 1 string to match.
+              if (BuiltinName[25] != 't')
+                break;
+              return Intrinsic::hexagon_C2_cmpgt;	 // "__builtin_HEXAGON_C2_cmpgt"
+            case 'l':	 // 1 string to match.
+              if (BuiltinName[25] != 't')
+                break;
+              return Intrinsic::hexagon_C2_cmplt;	 // "__builtin_HEXAGON_C2_cmplt"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+22, "ux", 2))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_muxii;	 // "__builtin_HEXAGON_C2_muxii"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_C2_muxir;	 // "__builtin_HEXAGON_C2_muxir"
+              }
+              break;
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[25] != 'i')
+                break;
+              return Intrinsic::hexagon_C2_muxri;	 // "__builtin_HEXAGON_C2_muxri"
+            }
+            break;
+          case 't':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+22, "fr", 2))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[25] != 'r')
+                break;
+              return Intrinsic::hexagon_C2_tfrpr;	 // "__builtin_HEXAGON_C2_tfrpr"
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[25] != 'p')
+                break;
+              return Intrinsic::hexagon_C2_tfrrp;	 // "__builtin_HEXAGON_C2_tfrrp"
+            }
+            break;
+          }
+          break;
+        case '4':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "_or_or", 6))
+            break;
+          return Intrinsic::hexagon_C4_or_or;	 // "__builtin_HEXAGON_C4_or_or"
+        }
+        break;
+      case 'F':	 // 14 strings to match.
+        if (memcmp(BuiltinName.data()+19, "2_", 2))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 7 strings to match.
+          if (BuiltinName[22] != 'f')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "dd", 2))
+              break;
+            return Intrinsic::hexagon_F2_dfadd;	 // "__builtin_HEXAGON_F2_dfadd"
+          case 'f':	 // 2 strings to match.
+            if (BuiltinName[24] != 'm')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffma;	 // "__builtin_HEXAGON_F2_dffma"
+            case 's':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_dffms;	 // "__builtin_HEXAGON_F2_dffms"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (BuiltinName[25] != 'x')
+                break;
+              return Intrinsic::hexagon_F2_dfmax;	 // "__builtin_HEXAGON_F2_dfmax"
+            case 'i':	 // 1 string to match.
+              if (BuiltinName[25] != 'n')
+                break;
+              return Intrinsic::hexagon_F2_dfmin;	 // "__builtin_HEXAGON_F2_dfmin"
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[25] != 'y')
+                break;
+              return Intrinsic::hexagon_F2_dfmpy;	 // "__builtin_HEXAGON_F2_dfmpy"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ub", 2))
+              break;
+            return Intrinsic::hexagon_F2_dfsub;	 // "__builtin_HEXAGON_F2_dfsub"
+          }
+          break;
+        case 's':	 // 7 strings to match.
+          if (BuiltinName[22] != 'f')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "dd", 2))
+              break;
+            return Intrinsic::hexagon_F2_sfadd;	 // "__builtin_HEXAGON_F2_sfadd"
+          case 'f':	 // 2 strings to match.
+            if (BuiltinName[24] != 'm')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffma;	 // "__builtin_HEXAGON_F2_sffma"
+            case 's':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_sffms;	 // "__builtin_HEXAGON_F2_sffms"
+            }
+            break;
+          case 'm':	 // 3 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (BuiltinName[25] != 'x')
+                break;
+              return Intrinsic::hexagon_F2_sfmax;	 // "__builtin_HEXAGON_F2_sfmax"
+            case 'i':	 // 1 string to match.
+              if (BuiltinName[25] != 'n')
+                break;
+              return Intrinsic::hexagon_F2_sfmin;	 // "__builtin_HEXAGON_F2_sfmin"
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[25] != 'y')
+                break;
+              return Intrinsic::hexagon_F2_sfmpy;	 // "__builtin_HEXAGON_F2_sfmpy"
+            }
+            break;
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ub", 2))
+              break;
+            return Intrinsic::hexagon_F2_sfsub;	 // "__builtin_HEXAGON_F2_sfsub"
+          }
+          break;
+        }
+        break;
+      case 'M':	 // 6 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case '2':	 // 4 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "ccii", 4))
+              break;
+            return Intrinsic::hexagon_M2_accii;	 // "__builtin_HEXAGON_M2_accii"
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "pyui", 4))
+              break;
+            return Intrinsic::hexagon_M2_mpyui;	 // "__builtin_HEXAGON_M2_mpyui"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "acci", 4))
+              break;
+            return Intrinsic::hexagon_M2_nacci;	 // "__builtin_HEXAGON_M2_nacci"
+          case 'v':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "mac2", 4))
+              break;
+            return Intrinsic::hexagon_M2_vmac2;	 // "__builtin_HEXAGON_M2_vmac2"
+          }
+          break;
+        case '4':	 // 2 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "r_or", 4))
+              break;
+            return Intrinsic::hexagon_M4_or_or;	 // "__builtin_HEXAGON_M4_or_or"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "mpyw", 4))
+              break;
+            return Intrinsic::hexagon_M4_pmpyw;	 // "__builtin_HEXAGON_M4_pmpyw"
+          }
+          break;
+        }
+        break;
+      case 'S':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "2_brevp", 7))
+          break;
+        return Intrinsic::hexagon_S2_brevp;	 // "__builtin_HEXAGON_S2_brevp"
+      }
+      break;
+    case 'S':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+11, "I_to_SXTHI_asrh", 15))
+        break;
+      return Intrinsic::hexagon_SI_to_SXTHI_asrh;	 // "__builtin_SI_to_SXTHI_asrh"
+    }
+    break;
+  case 27:	 // 70 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 35 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 26 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "ssat", 4))
+              break;
+            return Intrinsic::hexagon_A2_abssat;	 // "__builtin_HEXAGON_A2_abssat"
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "dsat", 4))
+              break;
+            return Intrinsic::hexagon_A2_addsat;	 // "__builtin_HEXAGON_A2_addsat"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "egsat", 5))
+            break;
+          return Intrinsic::hexagon_A2_negsat;	 // "__builtin_HEXAGON_A2_negsat"
+        case 's':	 // 4 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "bsat", 4))
+              break;
+            return Intrinsic::hexagon_A2_subsat;	 // "__builtin_HEXAGON_A2_subsat"
+          case 'v':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              switch (BuiltinName[24]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+25, "dh", 2))
+                  break;
+                return Intrinsic::hexagon_A2_svaddh;	 // "__builtin_HEXAGON_A2_svaddh"
+              case 'v':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+25, "gh", 2))
+                  break;
+                return Intrinsic::hexagon_A2_svavgh;	 // "__builtin_HEXAGON_A2_svavgh"
+              }
+              break;
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "ubh", 3))
+                break;
+              return Intrinsic::hexagon_A2_svsubh;	 // "__builtin_HEXAGON_A2_svsubh"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 19 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 3 strings to match.
+              if (BuiltinName[24] != 'd')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[26] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vaddhs;	 // "__builtin_HEXAGON_A2_vaddhs"
+              case 'u':	 // 1 string to match.
+                if (BuiltinName[26] != 'b')
+                  break;
+                return Intrinsic::hexagon_A2_vaddub;	 // "__builtin_HEXAGON_A2_vaddub"
+              case 'w':	 // 1 string to match.
+                if (BuiltinName[26] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vaddws;	 // "__builtin_HEXAGON_A2_vaddws"
+              }
+              break;
+            case 'v':	 // 5 strings to match.
+              if (BuiltinName[24] != 'g')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[26] != 'r')
+                  break;
+                return Intrinsic::hexagon_A2_vavghr;	 // "__builtin_HEXAGON_A2_vavghr"
+              case 'u':	 // 3 strings to match.
+                switch (BuiltinName[26]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavgub;	 // "__builtin_HEXAGON_A2_vavgub"
+                case 'h':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavguh;	 // "__builtin_HEXAGON_A2_vavguh"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::hexagon_A2_vavguw;	 // "__builtin_HEXAGON_A2_vavguw"
+                }
+                break;
+              case 'w':	 // 1 string to match.
+                if (BuiltinName[26] != 'r')
+                  break;
+                return Intrinsic::hexagon_A2_vavgwr;	 // "__builtin_HEXAGON_A2_vavgwr"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 6 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 3 strings to match.
+              if (memcmp(BuiltinName.data()+24, "xu", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vmaxub;	 // "__builtin_HEXAGON_A2_vmaxub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vmaxuh;	 // "__builtin_HEXAGON_A2_vmaxuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vmaxuw;	 // "__builtin_HEXAGON_A2_vmaxuw"
+              }
+              break;
+            case 'i':	 // 3 strings to match.
+              if (memcmp(BuiltinName.data()+24, "nu", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vminub;	 // "__builtin_HEXAGON_A2_vminub"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vminuh;	 // "__builtin_HEXAGON_A2_vminuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_vminuw;	 // "__builtin_HEXAGON_A2_vminuw"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "avg", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_vnavgh;	 // "__builtin_HEXAGON_A2_vnavgh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_vnavgw;	 // "__builtin_HEXAGON_A2_vnavgw"
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+23, "ub", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[26] != 's')
+                break;
+              return Intrinsic::hexagon_A2_vsubhs;	 // "__builtin_HEXAGON_A2_vsubhs"
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[26] != 'b')
+                break;
+              return Intrinsic::hexagon_A2_vsubub;	 // "__builtin_HEXAGON_A2_vsubub"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[26] != 's')
+                break;
+              return Intrinsic::hexagon_A2_vsubws;	 // "__builtin_HEXAGON_A2_vsubws"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 9 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mp", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (BuiltinName[26] != 'q')
+                break;
+              return Intrinsic::hexagon_A4_cmpbeq;	 // "__builtin_HEXAGON_A4_cmpbeq"
+            case 'g':	 // 1 string to match.
+              if (BuiltinName[26] != 't')
+                break;
+              return Intrinsic::hexagon_A4_cmpbgt;	 // "__builtin_HEXAGON_A4_cmpbgt"
+            }
+            break;
+          case 'h':	 // 2 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (BuiltinName[26] != 'q')
+                break;
+              return Intrinsic::hexagon_A4_cmpheq;	 // "__builtin_HEXAGON_A4_cmpheq"
+            case 'g':	 // 1 string to match.
+              if (BuiltinName[26] != 't')
+                break;
+              return Intrinsic::hexagon_A4_cmphgt;	 // "__builtin_HEXAGON_A4_cmphgt"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "cmpeq", 5))
+            break;
+          return Intrinsic::hexagon_A4_rcmpeq;	 // "__builtin_HEXAGON_A4_rcmpeq"
+        case 'v':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+22, "rm", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (BuiltinName[25] != 'x')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_vrmaxh;	 // "__builtin_HEXAGON_A4_vrmaxh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_vrmaxw;	 // "__builtin_HEXAGON_A4_vrmaxw"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (BuiltinName[25] != 'n')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_vrminh;	 // "__builtin_HEXAGON_A4_vrminh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_vrminw;	 // "__builtin_HEXAGON_A4_vrminw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 12 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 7 strings to match.
+        if (memcmp(BuiltinName.data()+20, "_cmp", 4))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (BuiltinName[25] != 'q')
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            return Intrinsic::hexagon_C2_cmpeqi;	 // "__builtin_HEXAGON_C2_cmpeqi"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::hexagon_C2_cmpeqp;	 // "__builtin_HEXAGON_C2_cmpeqp"
+          }
+          break;
+        case 'g':	 // 4 strings to match.
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (BuiltinName[26] != 'i')
+              break;
+            return Intrinsic::hexagon_C2_cmpgei;	 // "__builtin_HEXAGON_C2_cmpgei"
+          case 't':	 // 3 strings to match.
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpgti;	 // "__builtin_HEXAGON_C2_cmpgti"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpgtp;	 // "__builtin_HEXAGON_C2_cmpgtp"
+            case 'u':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpgtu;	 // "__builtin_HEXAGON_C2_cmpgtu"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "tu", 2))
+            break;
+          return Intrinsic::hexagon_C2_cmpltu;	 // "__builtin_HEXAGON_C2_cmpltu"
+        }
+        break;
+      case '4':	 // 5 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nd_or", 5))
+            break;
+          return Intrinsic::hexagon_C4_and_or;	 // "__builtin_HEXAGON_C4_and_or"
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mp", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "te", 2))
+              break;
+            return Intrinsic::hexagon_C4_cmplte;	 // "__builtin_HEXAGON_C4_cmplte"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "eq", 2))
+              break;
+            return Intrinsic::hexagon_C4_cmpneq;	 // "__builtin_HEXAGON_C4_cmpneq"
+          }
+          break;
+        case 'o':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "r_", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "nd", 2))
+              break;
+            return Intrinsic::hexagon_C4_or_and;	 // "__builtin_HEXAGON_C4_or_and"
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "rn", 2))
+              break;
+            return Intrinsic::hexagon_C4_or_orn;	 // "__builtin_HEXAGON_C4_or_orn"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 12 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 7 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'm':	 // 4 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "csi", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'n':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_macsin;	 // "__builtin_HEXAGON_M2_macsin"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_macsip;	 // "__builtin_HEXAGON_M2_macsip"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (BuiltinName[23] != 'y')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "up", 2))
+                break;
+              return Intrinsic::hexagon_M2_mpy_up;	 // "__builtin_HEXAGON_M2_mpy_up"
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "mi", 2))
+                break;
+              return Intrinsic::hexagon_M2_mpysmi;	 // "__builtin_HEXAGON_M2_mpysmi"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "accii", 5))
+            break;
+          return Intrinsic::hexagon_M2_naccii;	 // "__builtin_HEXAGON_M2_naccii"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ubacc", 5))
+            break;
+          return Intrinsic::hexagon_M2_subacc;	 // "__builtin_HEXAGON_M2_subacc"
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "raddh", 5))
+            break;
+          return Intrinsic::hexagon_M2_vraddh;	 // "__builtin_HEXAGON_M2_vraddh"
+        }
+        break;
+      case '4':	 // 5 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nd_or", 5))
+            break;
+          return Intrinsic::hexagon_M4_and_or;	 // "__builtin_HEXAGON_M4_and_or"
+        case 'o':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "r_", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "nd", 2))
+              break;
+            return Intrinsic::hexagon_M4_or_and;	 // "__builtin_HEXAGON_M4_or_and"
+          case 'x':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "or", 2))
+              break;
+            return Intrinsic::hexagon_M4_or_xor;	 // "__builtin_HEXAGON_M4_or_xor"
+          }
+          break;
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "pmpyh", 5))
+            break;
+          return Intrinsic::hexagon_M4_vpmpyh;	 // "__builtin_HEXAGON_M4_vpmpyh"
+        case 'x':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "or_or", 5))
+            break;
+          return Intrinsic::hexagon_M4_xor_or;	 // "__builtin_HEXAGON_M4_xor_or"
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 11 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 9 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nsert", 5))
+            break;
+          return Intrinsic::hexagon_S2_insert;	 // "__builtin_HEXAGON_S2_insert"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ackhl", 5))
+            break;
+          return Intrinsic::hexagon_S2_packhl;	 // "__builtin_HEXAGON_S2_packhl"
+        case 'v':	 // 7 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "negh", 4))
+              break;
+            return Intrinsic::hexagon_S2_vcnegh;	 // "__builtin_HEXAGON_S2_vcnegh"
+          case 's':	 // 4 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (BuiltinName[24] != 't')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[26] != 'b')
+                  break;
+                return Intrinsic::hexagon_S2_vsathb;	 // "__builtin_HEXAGON_S2_vsathb"
+              case 'w':	 // 1 string to match.
+                if (BuiltinName[26] != 'h')
+                  break;
+                return Intrinsic::hexagon_S2_vsatwh;	 // "__builtin_HEXAGON_S2_vsatwh"
+              }
+              break;
+            case 'x':	 // 2 strings to match.
+              if (BuiltinName[24] != 't')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (BuiltinName[26] != 'h')
+                  break;
+                return Intrinsic::hexagon_S2_vsxtbh;	 // "__builtin_HEXAGON_S2_vsxtbh"
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[26] != 'w')
+                  break;
+                return Intrinsic::hexagon_S2_vsxthw;	 // "__builtin_HEXAGON_S2_vsxthw"
+              }
+              break;
+            }
+            break;
+          case 'z':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "xt", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[26] != 'h')
+                break;
+              return Intrinsic::hexagon_S2_vzxtbh;	 // "__builtin_HEXAGON_S2_vzxtbh"
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[26] != 'w')
+                break;
+              return Intrinsic::hexagon_S2_vzxthw;	 // "__builtin_HEXAGON_S2_vzxthw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 2 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "r_ori", 5))
+            break;
+          return Intrinsic::hexagon_S4_or_ori;	 // "__builtin_HEXAGON_S4_or_ori"
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "arity", 5))
+            break;
+          return Intrinsic::hexagon_S4_parity;	 // "__builtin_HEXAGON_S4_parity"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 28:	 // 103 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 36 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 23 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ddpsat", 6))
+            break;
+          return Intrinsic::hexagon_A2_addpsat;	 // "__builtin_HEXAGON_A2_addpsat"
+        case 's':	 // 4 strings to match.
+          if (BuiltinName[22] != 'v')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "dhs", 3))
+                break;
+              return Intrinsic::hexagon_A2_svaddhs;	 // "__builtin_HEXAGON_A2_svaddhs"
+            case 'v':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "ghs", 3))
+                break;
+              return Intrinsic::hexagon_A2_svavghs;	 // "__builtin_HEXAGON_A2_svavghs"
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "avgh", 4))
+              break;
+            return Intrinsic::hexagon_A2_svnavgh;	 // "__builtin_HEXAGON_A2_svnavgh"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ubhs", 4))
+              break;
+            return Intrinsic::hexagon_A2_svsubhs;	 // "__builtin_HEXAGON_A2_svsubhs"
+          }
+          break;
+        case 'v':	 // 18 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 7 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "du", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                if (BuiltinName[27] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vaddubs;	 // "__builtin_HEXAGON_A2_vaddubs"
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[27] != 's')
+                  break;
+                return Intrinsic::hexagon_A2_vadduhs;	 // "__builtin_HEXAGON_A2_vadduhs"
+              }
+              break;
+            case 'v':	 // 5 strings to match.
+              if (BuiltinName[24] != 'g')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "cr", 2))
+                  break;
+                return Intrinsic::hexagon_A2_vavghcr;	 // "__builtin_HEXAGON_A2_vavghcr"
+              case 'u':	 // 3 strings to match.
+                switch (BuiltinName[26]) {
+                default: break;
+                case 'b':	 // 1 string to match.
+                  if (BuiltinName[27] != 'r')
+                    break;
+                  return Intrinsic::hexagon_A2_vavgubr;	 // "__builtin_HEXAGON_A2_vavgubr"
+                case 'h':	 // 1 string to match.
+                  if (BuiltinName[27] != 'r')
+                    break;
+                  return Intrinsic::hexagon_A2_vavguhr;	 // "__builtin_HEXAGON_A2_vavguhr"
+                case 'w':	 // 1 string to match.
+                  if (BuiltinName[27] != 'r')
+                    break;
+                  return Intrinsic::hexagon_A2_vavguwr;	 // "__builtin_HEXAGON_A2_vavguwr"
+                }
+                break;
+              case 'w':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "cr", 2))
+                  break;
+                return Intrinsic::hexagon_A2_vavgwcr;	 // "__builtin_HEXAGON_A2_vavgwcr"
+              }
+              break;
+            }
+            break;
+          case 'c':	 // 5 strings to match.
+            if (memcmp(BuiltinName.data()+23, "mp", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "eq", 2))
+                break;
+              return Intrinsic::hexagon_A2_vcmpbeq;	 // "__builtin_HEXAGON_A2_vcmpbeq"
+            case 'h':	 // 2 strings to match.
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (BuiltinName[27] != 'q')
+                  break;
+                return Intrinsic::hexagon_A2_vcmpheq;	 // "__builtin_HEXAGON_A2_vcmpheq"
+              case 'g':	 // 1 string to match.
+                if (BuiltinName[27] != 't')
+                  break;
+                return Intrinsic::hexagon_A2_vcmphgt;	 // "__builtin_HEXAGON_A2_vcmphgt"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                if (BuiltinName[27] != 'q')
+                  break;
+                return Intrinsic::hexagon_A2_vcmpweq;	 // "__builtin_HEXAGON_A2_vcmpweq"
+              case 'g':	 // 1 string to match.
+                if (BuiltinName[27] != 't')
+                  break;
+                return Intrinsic::hexagon_A2_vcmpwgt;	 // "__builtin_HEXAGON_A2_vcmpwgt"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "avg", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[27] != 'r')
+                break;
+              return Intrinsic::hexagon_A2_vnavghr;	 // "__builtin_HEXAGON_A2_vnavghr"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[27] != 'r')
+                break;
+              return Intrinsic::hexagon_A2_vnavgwr;	 // "__builtin_HEXAGON_A2_vnavgwr"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "ddub", 4))
+                break;
+              return Intrinsic::hexagon_A2_vraddub;	 // "__builtin_HEXAGON_A2_vraddub"
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "adub", 4))
+                break;
+              return Intrinsic::hexagon_A2_vrsadub;	 // "__builtin_HEXAGON_A2_vrsadub"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "ubu", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[27] != 's')
+                break;
+              return Intrinsic::hexagon_A2_vsububs;	 // "__builtin_HEXAGON_A2_vsububs"
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[27] != 's')
+                break;
+              return Intrinsic::hexagon_A2_vsubuhs;	 // "__builtin_HEXAGON_A2_vsubuhs"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 13 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mp", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_cmpbeqi;	 // "__builtin_HEXAGON_A4_cmpbeqi"
+            case 'g':	 // 2 strings to match.
+              if (BuiltinName[26] != 't')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cmpbgti;	 // "__builtin_HEXAGON_A4_cmpbgti"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cmpbgtu;	 // "__builtin_HEXAGON_A4_cmpbgtu"
+              }
+              break;
+            }
+            break;
+          case 'h':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_cmpheqi;	 // "__builtin_HEXAGON_A4_cmpheqi"
+            case 'g':	 // 2 strings to match.
+              if (BuiltinName[26] != 't')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cmphgti;	 // "__builtin_HEXAGON_A4_cmphgti"
+              case 'u':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_cmphgtu;	 // "__builtin_HEXAGON_A4_cmphgtu"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "cmp", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "qi", 2))
+              break;
+            return Intrinsic::hexagon_A4_rcmpeqi;	 // "__builtin_HEXAGON_A4_rcmpeqi"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "eq", 2))
+              break;
+            return Intrinsic::hexagon_A4_rcmpneq;	 // "__builtin_HEXAGON_A4_rcmpneq"
+          }
+          break;
+        case 'v':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "mpbgt", 5))
+              break;
+            return Intrinsic::hexagon_A4_vcmpbgt;	 // "__builtin_HEXAGON_A4_vcmpbgt"
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[23] != 'm')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+25, "xu", 2))
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrmaxuh;	 // "__builtin_HEXAGON_A4_vrmaxuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrmaxuw;	 // "__builtin_HEXAGON_A4_vrmaxuw"
+              }
+              break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+25, "nu", 2))
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrminuh;	 // "__builtin_HEXAGON_A4_vrminuh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_A4_vrminuw;	 // "__builtin_HEXAGON_A4_vrminuw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 12 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 6 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "its", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "lr", 2))
+              break;
+            return Intrinsic::hexagon_C2_bitsclr;	 // "__builtin_HEXAGON_C2_bitsclr"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "et", 2))
+              break;
+            return Intrinsic::hexagon_C2_bitsset;	 // "__builtin_HEXAGON_C2_bitsset"
+          }
+          break;
+        case 'c':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mpg", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "ui", 2))
+              break;
+            return Intrinsic::hexagon_C2_cmpgeui;	 // "__builtin_HEXAGON_C2_cmpgeui"
+          case 't':	 // 2 strings to match.
+            if (BuiltinName[26] != 'u')
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpgtui;	 // "__builtin_HEXAGON_C2_cmpgtui"
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_C2_cmpgtup;	 // "__builtin_HEXAGON_C2_cmpgtup"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "itpack", 6))
+            break;
+          return Intrinsic::hexagon_C2_vitpack;	 // "__builtin_HEXAGON_C2_vitpack"
+        }
+        break;
+      case '4':	 // 6 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "nd_", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "nd", 2))
+              break;
+            return Intrinsic::hexagon_C4_and_and;	 // "__builtin_HEXAGON_C4_and_and"
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "rn", 2))
+              break;
+            return Intrinsic::hexagon_C4_and_orn;	 // "__builtin_HEXAGON_C4_and_orn"
+          }
+          break;
+        case 'c':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mp", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "te", 2))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_C4_cmpltei;	 // "__builtin_HEXAGON_C4_cmpltei"
+            case 'u':	 // 1 string to match.
+              return Intrinsic::hexagon_C4_cmplteu;	 // "__builtin_HEXAGON_C4_cmplteu"
+            }
+            break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "eqi", 3))
+              break;
+            return Intrinsic::hexagon_C4_cmpneqi;	 // "__builtin_HEXAGON_C4_cmpneqi"
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "r_andn", 6))
+            break;
+          return Intrinsic::hexagon_C4_or_andn;	 // "__builtin_HEXAGON_C4_or_andn"
+        }
+        break;
+      }
+      break;
+    case 'F':	 // 14 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 7 strings to match.
+        if (BuiltinName[22] != 'f')
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'c':	 // 5 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "ass", 3))
+              break;
+            return Intrinsic::hexagon_F2_dfclass;	 // "__builtin_HEXAGON_F2_dfclass"
+          case 'm':	 // 4 strings to match.
+            if (BuiltinName[25] != 'p')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (BuiltinName[27] != 'q')
+                break;
+              return Intrinsic::hexagon_F2_dfcmpeq;	 // "__builtin_HEXAGON_F2_dfcmpeq"
+            case 'g':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_dfcmpge;	 // "__builtin_HEXAGON_F2_dfcmpge"
+              case 't':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_dfcmpgt;	 // "__builtin_HEXAGON_F2_dfcmpgt"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[27] != 'o')
+                break;
+              return Intrinsic::hexagon_F2_dfcmpuo;	 // "__builtin_HEXAGON_F2_dfcmpuo"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+24, "mm_", 3))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'n':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_dfimm_n;	 // "__builtin_HEXAGON_F2_dfimm_n"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_dfimm_p;	 // "__builtin_HEXAGON_F2_dfimm_p"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 7 strings to match.
+        if (BuiltinName[22] != 'f')
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'c':	 // 5 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "ass", 3))
+              break;
+            return Intrinsic::hexagon_F2_sfclass;	 // "__builtin_HEXAGON_F2_sfclass"
+          case 'm':	 // 4 strings to match.
+            if (BuiltinName[25] != 'p')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (BuiltinName[27] != 'q')
+                break;
+              return Intrinsic::hexagon_F2_sfcmpeq;	 // "__builtin_HEXAGON_F2_sfcmpeq"
+            case 'g':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'e':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_sfcmpge;	 // "__builtin_HEXAGON_F2_sfcmpge"
+              case 't':	 // 1 string to match.
+                return Intrinsic::hexagon_F2_sfcmpgt;	 // "__builtin_HEXAGON_F2_sfcmpgt"
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[27] != 'o')
+                break;
+              return Intrinsic::hexagon_F2_sfcmpuo;	 // "__builtin_HEXAGON_F2_sfcmpuo"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+24, "mm_", 3))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'n':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_sfimm_n;	 // "__builtin_HEXAGON_F2_sfimm_n"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_sfimm_p;	 // "__builtin_HEXAGON_F2_sfimm_p"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 11 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 3 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "pyu_up", 6))
+            break;
+          return Intrinsic::hexagon_M2_mpyu_up;	 // "__builtin_HEXAGON_M2_mpyu_up"
+        case 'v':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "ac2es", 5))
+              break;
+            return Intrinsic::hexagon_M2_vmac2es;	 // "__builtin_HEXAGON_M2_vmac2es"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "adduh", 5))
+              break;
+            return Intrinsic::hexagon_M2_vradduh;	 // "__builtin_HEXAGON_M2_vradduh"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 4 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "nd_", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "nd", 2))
+              break;
+            return Intrinsic::hexagon_M4_and_and;	 // "__builtin_HEXAGON_M4_and_and"
+          case 'x':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "or", 2))
+              break;
+            return Intrinsic::hexagon_M4_and_xor;	 // "__builtin_HEXAGON_M4_and_xor"
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "r_andn", 6))
+            break;
+          return Intrinsic::hexagon_M4_or_andn;	 // "__builtin_HEXAGON_M4_or_andn"
+        case 'x':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "or_and", 6))
+            break;
+          return Intrinsic::hexagon_M4_xor_and;	 // "__builtin_HEXAGON_M4_xor_and"
+        }
+        break;
+      case '5':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+20, "_vm", 3))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+24, "cb", 2))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[27] != 'u')
+              break;
+            return Intrinsic::hexagon_M5_vmacbsu;	 // "__builtin_HEXAGON_M5_vmacbsu"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[27] != 'u')
+              break;
+            return Intrinsic::hexagon_M5_vmacbuu;	 // "__builtin_HEXAGON_M5_vmacbuu"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+24, "yb", 2))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[27] != 'u')
+              break;
+            return Intrinsic::hexagon_M5_vmpybsu;	 // "__builtin_HEXAGON_M5_vmpybsu"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[27] != 'u')
+              break;
+            return Intrinsic::hexagon_M5_vmpybuu;	 // "__builtin_HEXAGON_M5_vmpybuu"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 30 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 25 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_i_p;	 // "__builtin_HEXAGON_S2_asl_i_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_i_r;	 // "__builtin_HEXAGON_S2_asl_i_r"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_r_p;	 // "__builtin_HEXAGON_S2_asl_r_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_r_r;	 // "__builtin_HEXAGON_S2_asl_r_r"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_i_p;	 // "__builtin_HEXAGON_S2_asr_i_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_i_r;	 // "__builtin_HEXAGON_S2_asr_i_r"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_r_p;	 // "__builtin_HEXAGON_S2_asr_r_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_r_r;	 // "__builtin_HEXAGON_S2_asr_r_r"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "lbnorm", 6))
+            break;
+          return Intrinsic::hexagon_S2_clbnorm;	 // "__builtin_HEXAGON_S2_clbnorm"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nsertp", 6))
+            break;
+          return Intrinsic::hexagon_S2_insertp;	 // "__builtin_HEXAGON_S2_insertp"
+        case 'l':	 // 6 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+24, "_r_", 3))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_lsl_r_p;	 // "__builtin_HEXAGON_S2_lsl_r_p"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_lsl_r_r;	 // "__builtin_HEXAGON_S2_lsl_r_r"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_i_p;	 // "__builtin_HEXAGON_S2_lsr_i_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_i_r;	 // "__builtin_HEXAGON_S2_lsr_i_r"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_r_p;	 // "__builtin_HEXAGON_S2_lsr_r_p"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_r_r;	 // "__builtin_HEXAGON_S2_lsr_r_r"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "arityp", 6))
+            break;
+          return Intrinsic::hexagon_S2_parityp;	 // "__builtin_HEXAGON_S2_parityp"
+        case 's':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+23, "uff", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_shuffeb;	 // "__builtin_HEXAGON_S2_shuffeb"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_shuffeh;	 // "__builtin_HEXAGON_S2_shuffeh"
+              }
+              break;
+            case 'o':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_shuffob;	 // "__builtin_HEXAGON_S2_shuffob"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_shuffoh;	 // "__builtin_HEXAGON_S2_shuffoh"
+              }
+              break;
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "sathb", 5))
+              break;
+            return Intrinsic::hexagon_S2_svsathb;	 // "__builtin_HEXAGON_S2_svsathb"
+          }
+          break;
+        case 'v':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "cnegh", 5))
+              break;
+            return Intrinsic::hexagon_S2_vrcnegh;	 // "__builtin_HEXAGON_S2_vrcnegh"
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "at", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "ub", 2))
+                break;
+              return Intrinsic::hexagon_S2_vsathub;	 // "__builtin_HEXAGON_S2_vsathub"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "uh", 2))
+                break;
+              return Intrinsic::hexagon_S2_vsatwuh;	 // "__builtin_HEXAGON_S2_vsatwuh"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 5 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ddaddi", 6))
+            break;
+          return Intrinsic::hexagon_S4_addaddi;	 // "__builtin_HEXAGON_S4_addaddi"
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "lbaddi", 6))
+            break;
+          return Intrinsic::hexagon_S4_clbaddi;	 // "__builtin_HEXAGON_S4_clbaddi"
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtract", 6))
+            break;
+          return Intrinsic::hexagon_S4_extract;	 // "__builtin_HEXAGON_S4_extract"
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "r_andi", 6))
+            break;
+          return Intrinsic::hexagon_S4_or_andi;	 // "__builtin_HEXAGON_S4_or_andi"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ubaddi", 6))
+            break;
+          return Intrinsic::hexagon_S4_subaddi;	 // "__builtin_HEXAGON_S4_subaddi"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 29:	 // 103 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 26 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 11 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ombinew", 7))
+            break;
+          return Intrinsic::hexagon_A2_combinew;	 // "__builtin_HEXAGON_A2_combinew"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "oundsat", 7))
+            break;
+          return Intrinsic::hexagon_A2_roundsat;	 // "__builtin_HEXAGON_A2_roundsat"
+        case 's':	 // 2 strings to match.
+          if (BuiltinName[22] != 'v')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "dduhs", 5))
+              break;
+            return Intrinsic::hexagon_A2_svadduhs;	 // "__builtin_HEXAGON_A2_svadduhs"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ubuhs", 5))
+              break;
+            return Intrinsic::hexagon_A2_svsubuhs;	 // "__builtin_HEXAGON_A2_svsubuhs"
+          }
+          break;
+        case 'v':	 // 7 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "bs", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "sat", 3))
+                break;
+              return Intrinsic::hexagon_A2_vabshsat;	 // "__builtin_HEXAGON_A2_vabshsat"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "sat", 3))
+                break;
+              return Intrinsic::hexagon_A2_vabswsat;	 // "__builtin_HEXAGON_A2_vabswsat"
+            }
+            break;
+          case 'c':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+23, "mp", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "gtu", 3))
+                break;
+              return Intrinsic::hexagon_A2_vcmpbgtu;	 // "__builtin_HEXAGON_A2_vcmpbgtu"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "gtu", 3))
+                break;
+              return Intrinsic::hexagon_A2_vcmphgtu;	 // "__builtin_HEXAGON_A2_vcmphgtu"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "gtu", 3))
+                break;
+              return Intrinsic::hexagon_A2_vcmpwgtu;	 // "__builtin_HEXAGON_A2_vcmpwgtu"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "avg", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "cr", 2))
+                break;
+              return Intrinsic::hexagon_A2_vnavghcr;	 // "__builtin_HEXAGON_A2_vnavghcr"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "cr", 2))
+                break;
+              return Intrinsic::hexagon_A2_vnavgwcr;	 // "__builtin_HEXAGON_A2_vnavgwcr"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 14 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "itsplit", 7))
+            break;
+          return Intrinsic::hexagon_A4_bitsplit;	 // "__builtin_HEXAGON_A4_bitsplit"
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mp", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "gtui", 4))
+              break;
+            return Intrinsic::hexagon_A4_cmpbgtui;	 // "__builtin_HEXAGON_A4_cmpbgtui"
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "gtui", 4))
+              break;
+            return Intrinsic::hexagon_A4_cmphgtui;	 // "__builtin_HEXAGON_A4_cmphgtui"
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "odwrapu", 7))
+            break;
+          return Intrinsic::hexagon_A4_modwrapu;	 // "__builtin_HEXAGON_A4_modwrapu"
+        case 'r':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "mpneqi", 6))
+              break;
+            return Intrinsic::hexagon_A4_rcmpneqi;	 // "__builtin_HEXAGON_A4_rcmpneqi"
+          case 'o':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "und_r", 5))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_round_ri;	 // "__builtin_HEXAGON_A4_round_ri"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_round_rr;	 // "__builtin_HEXAGON_A4_round_rr"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "lbmatch", 7))
+            break;
+          return Intrinsic::hexagon_A4_tlbmatch;	 // "__builtin_HEXAGON_A4_tlbmatch"
+        case 'v':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+22, "cmp", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmpbeqi;	 // "__builtin_HEXAGON_A4_vcmpbeqi"
+            case 'g':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "ti", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmpbgti;	 // "__builtin_HEXAGON_A4_vcmpbgti"
+            }
+            break;
+          case 'h':	 // 2 strings to match.
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmpheqi;	 // "__builtin_HEXAGON_A4_vcmpheqi"
+            case 'g':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "ti", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmphgti;	 // "__builtin_HEXAGON_A4_vcmphgti"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "qi", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmpweqi;	 // "__builtin_HEXAGON_A4_vcmpweqi"
+            case 'g':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "ti", 2))
+                break;
+              return Intrinsic::hexagon_A4_vcmpwgti;	 // "__builtin_HEXAGON_A4_vcmpwgti"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '5':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_vaddhubs", 9))
+          break;
+        return Intrinsic::hexagon_A5_vaddhubs;	 // "__builtin_HEXAGON_A5_vaddhubs"
+      }
+      break;
+    case 'C':	 // 5 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_bitsclri", 9))
+          break;
+        return Intrinsic::hexagon_C2_bitsclri;	 // "__builtin_HEXAGON_C2_bitsclri"
+      case '4':	 // 4 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nd_andn", 7))
+            break;
+          return Intrinsic::hexagon_C4_and_andn;	 // "__builtin_HEXAGON_C4_and_andn"
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "mplteui", 7))
+            break;
+          return Intrinsic::hexagon_C4_cmplteui;	 // "__builtin_HEXAGON_C4_cmplteui"
+        case 'n':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "bits", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "lr", 2))
+              break;
+            return Intrinsic::hexagon_C4_nbitsclr;	 // "__builtin_HEXAGON_C4_nbitsclr"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "et", 2))
+              break;
+            return Intrinsic::hexagon_C4_nbitsset;	 // "__builtin_HEXAGON_C4_nbitsset"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'F':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ff", 2))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'i':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+25, "xup", 3))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_dffixupd;	 // "__builtin_HEXAGON_F2_dffixupd"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_dffixupn;	 // "__builtin_HEXAGON_F2_dffixupn"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_dffixupr;	 // "__builtin_HEXAGON_F2_dffixupr"
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "a_sc", 4))
+            break;
+          return Intrinsic::hexagon_F2_dffma_sc;	 // "__builtin_HEXAGON_F2_dffma_sc"
+        }
+        break;
+      case 's':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ff", 2))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'i':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+25, "xup", 3))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_sffixupd;	 // "__builtin_HEXAGON_F2_sffixupd"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_sffixupn;	 // "__builtin_HEXAGON_F2_sffixupn"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_sffixupr;	 // "__builtin_HEXAGON_F2_sffixupr"
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "a_sc", 4))
+            break;
+          return Intrinsic::hexagon_F2_sffma_sc;	 // "__builtin_HEXAGON_F2_sffma_sc"
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 29 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 18 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 10 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 8 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (BuiltinName[24] != 'c')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_cmaci_s0;	 // "__builtin_HEXAGON_M2_cmaci_s0"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_cmacr_s0;	 // "__builtin_HEXAGON_M2_cmacr_s0"
+              case 's':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "_s", 2))
+                  break;
+                switch (BuiltinName[28]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmacs_s0;	 // "__builtin_HEXAGON_M2_cmacs_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmacs_s1;	 // "__builtin_HEXAGON_M2_cmacs_s1"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 4 strings to match.
+              if (BuiltinName[24] != 'y')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_cmpyi_s0;	 // "__builtin_HEXAGON_M2_cmpyi_s0"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+26, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_cmpyr_s0;	 // "__builtin_HEXAGON_M2_cmpyr_s0"
+              case 's':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "_s", 2))
+                  break;
+                switch (BuiltinName[28]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpys_s0;	 // "__builtin_HEXAGON_M2_cmpys_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpys_s1;	 // "__builtin_HEXAGON_M2_cmpys_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "acs_s", 5))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cnacs_s0;	 // "__builtin_HEXAGON_M2_cnacs_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cnacs_s1;	 // "__builtin_HEXAGON_M2_cnacs_s1"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+23, "py", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_s", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmpyh_s0;	 // "__builtin_HEXAGON_M2_mmpyh_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmpyh_s1;	 // "__builtin_HEXAGON_M2_mmpyh_s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_s", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmpyl_s0;	 // "__builtin_HEXAGON_M2_mmpyl_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mmpyl_s1;	 // "__builtin_HEXAGON_M2_mmpyl_s1"
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "ysu_up", 6))
+              break;
+            return Intrinsic::hexagon_M2_mpysu_up;	 // "__builtin_HEXAGON_M2_mpysu_up"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "rm", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "c_s0", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrmac_s0;	 // "__builtin_HEXAGON_M2_vrmac_s0"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "y_s0", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrmpy_s0;	 // "__builtin_HEXAGON_M2_vrmpy_s0"
+          }
+          break;
+        case 'x':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "or_xacc", 7))
+            break;
+          return Intrinsic::hexagon_M2_xor_xacc;	 // "__builtin_HEXAGON_M2_xor_xacc"
+        }
+        break;
+      case '4':	 // 5 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nd_andn", 7))
+            break;
+          return Intrinsic::hexagon_M4_and_andn;	 // "__builtin_HEXAGON_M4_and_andn"
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mpy", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_wh", 3))
+              break;
+            return Intrinsic::hexagon_M4_cmpyi_wh;	 // "__builtin_HEXAGON_M4_cmpyi_wh"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_wh", 3))
+              break;
+            return Intrinsic::hexagon_M4_cmpyr_wh;	 // "__builtin_HEXAGON_M4_cmpyr_wh"
+          }
+          break;
+        case 'x':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "or_", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "ndn", 3))
+              break;
+            return Intrinsic::hexagon_M4_xor_andn;	 // "__builtin_HEXAGON_M4_xor_andn"
+          case 'x':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "acc", 3))
+              break;
+            return Intrinsic::hexagon_M4_xor_xacc;	 // "__builtin_HEXAGON_M4_xor_xacc"
+          }
+          break;
+        }
+        break;
+      case '5':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+20, "_v", 2))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (BuiltinName[23] != 'm')
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "cbsu", 4))
+              break;
+            return Intrinsic::hexagon_M5_vdmacbsu;	 // "__builtin_HEXAGON_M5_vdmacbsu"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "ybsu", 4))
+              break;
+            return Intrinsic::hexagon_M5_vdmpybsu;	 // "__builtin_HEXAGON_M5_vdmpybsu"
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          if (BuiltinName[23] != 'm')
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "cb", 2))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (BuiltinName[28] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vrmacbsu;	 // "__builtin_HEXAGON_M5_vrmacbsu"
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[28] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vrmacbuu;	 // "__builtin_HEXAGON_M5_vrmacbuu"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+25, "yb", 2))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 's':	 // 1 string to match.
+              if (BuiltinName[28] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vrmpybsu;	 // "__builtin_HEXAGON_M5_vrmpybsu"
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[28] != 'u')
+                break;
+              return Intrinsic::hexagon_M5_vrmpybuu;	 // "__builtin_HEXAGON_M5_vrmpybuu"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 35 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 31 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_i_vh;	 // "__builtin_HEXAGON_S2_asl_i_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_i_vw;	 // "__builtin_HEXAGON_S2_asl_i_vw"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_r_vh;	 // "__builtin_HEXAGON_S2_asl_r_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asl_r_vw;	 // "__builtin_HEXAGON_S2_asl_r_vw"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_i_vh;	 // "__builtin_HEXAGON_S2_asr_i_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_i_vw;	 // "__builtin_HEXAGON_S2_asr_i_vw"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_r_vh;	 // "__builtin_HEXAGON_S2_asr_r_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_asr_r_vw;	 // "__builtin_HEXAGON_S2_asr_r_vw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "lrbit_", 6))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_clrbit_i;	 // "__builtin_HEXAGON_S2_clrbit_i"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_clrbit_r;	 // "__builtin_HEXAGON_S2_clrbit_r"
+          }
+          break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtractu", 7))
+            break;
+          return Intrinsic::hexagon_S2_extractu;	 // "__builtin_HEXAGON_S2_extractu"
+        case 'l':	 // 6 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+24, "_r_v", 4))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_lsl_r_vh;	 // "__builtin_HEXAGON_S2_lsl_r_vh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_lsl_r_vw;	 // "__builtin_HEXAGON_S2_lsl_r_vw"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_i_vh;	 // "__builtin_HEXAGON_S2_lsr_i_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_i_vw;	 // "__builtin_HEXAGON_S2_lsr_i_vw"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+26, "_v", 2))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_r_vh;	 // "__builtin_HEXAGON_S2_lsr_r_vh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S2_lsr_r_vw;	 // "__builtin_HEXAGON_S2_lsr_r_vw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "tbit_", 5))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_setbit_i;	 // "__builtin_HEXAGON_S2_setbit_i"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_setbit_r;	 // "__builtin_HEXAGON_S2_setbit_r"
+            }
+            break;
+          case 'v':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "sathub", 6))
+              break;
+            return Intrinsic::hexagon_S2_svsathub;	 // "__builtin_HEXAGON_S2_svsathub"
+          }
+          break;
+        case 't':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "stbit_", 6))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_tstbit_i;	 // "__builtin_HEXAGON_S2_tstbit_i"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_tstbit_r;	 // "__builtin_HEXAGON_S2_tstbit_r"
+          }
+          break;
+        case 'v':	 // 9 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "lign", 4))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (BuiltinName[28] != 'b')
+                break;
+              return Intrinsic::hexagon_S2_valignib;	 // "__builtin_HEXAGON_S2_valignib"
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[28] != 'b')
+                break;
+              return Intrinsic::hexagon_S2_valignrb;	 // "__builtin_HEXAGON_S2_valignrb"
+            }
+            break;
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "rotate", 6))
+              break;
+            return Intrinsic::hexagon_S2_vcrotate;	 // "__builtin_HEXAGON_S2_vcrotate"
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "platr", 5))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_vsplatrb;	 // "__builtin_HEXAGON_S2_vsplatrb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_S2_vsplatrh;	 // "__builtin_HEXAGON_S2_vsplatrh"
+            }
+            break;
+          case 't':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+23, "run", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[28] != 'b')
+                  break;
+                return Intrinsic::hexagon_S2_vtrunehb;	 // "__builtin_HEXAGON_S2_vtrunehb"
+              case 'w':	 // 1 string to match.
+                if (BuiltinName[28] != 'h')
+                  break;
+                return Intrinsic::hexagon_S2_vtrunewh;	 // "__builtin_HEXAGON_S2_vtrunewh"
+              }
+              break;
+            case 'o':	 // 2 strings to match.
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                if (BuiltinName[28] != 'b')
+                  break;
+                return Intrinsic::hexagon_S2_vtrunohb;	 // "__builtin_HEXAGON_S2_vtrunohb"
+              case 'w':	 // 1 string to match.
+                if (BuiltinName[28] != 'h')
+                  break;
+                return Intrinsic::hexagon_S2_vtrunowh;	 // "__builtin_HEXAGON_S2_vtrunowh"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 4 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "lbp", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "ddi", 3))
+              break;
+            return Intrinsic::hexagon_S4_clbpaddi;	 // "__builtin_HEXAGON_S4_clbpaddi"
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "orm", 3))
+              break;
+            return Intrinsic::hexagon_S4_clbpnorm;	 // "__builtin_HEXAGON_S4_clbpnorm"
+          }
+          break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtractp", 7))
+            break;
+          return Intrinsic::hexagon_S4_extractp;	 // "__builtin_HEXAGON_S4_extractp"
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "r_andix", 7))
+            break;
+          return Intrinsic::hexagon_S4_or_andix;	 // "__builtin_HEXAGON_S4_or_andix"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 30:	 // 81 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 11 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 3 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ombineii", 8))
+            break;
+          return Intrinsic::hexagon_A2_combineii;	 // "__builtin_HEXAGON_A2_combineii"
+        case 'v':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "ddb_map", 7))
+              break;
+            return Intrinsic::hexagon_A2_vaddb_map;	 // "__builtin_HEXAGON_A2_vaddb_map"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "ubb_map", 7))
+              break;
+            return Intrinsic::hexagon_A2_vsubb_map;	 // "__builtin_HEXAGON_A2_vsubb_map"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 8 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "itspliti", 8))
+            break;
+          return Intrinsic::hexagon_A4_bitspliti;	 // "__builtin_HEXAGON_A4_bitspliti"
+        case 'c':	 // 4 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "mbine", 5))
+              break;
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (BuiltinName[29] != 'r')
+                break;
+              return Intrinsic::hexagon_A4_combineir;	 // "__builtin_HEXAGON_A4_combineir"
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[29] != 'i')
+                break;
+              return Intrinsic::hexagon_A4_combineri;	 // "__builtin_HEXAGON_A4_combineri"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "ound_r", 6))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_cround_ri;	 // "__builtin_HEXAGON_A4_cround_ri"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_A4_cround_rr;	 // "__builtin_HEXAGON_A4_cround_rr"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+22, "cmp", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "gtui", 4))
+              break;
+            return Intrinsic::hexagon_A4_vcmpbgtui;	 // "__builtin_HEXAGON_A4_vcmpbgtui"
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "gtui", 4))
+              break;
+            return Intrinsic::hexagon_A4_vcmphgtui;	 // "__builtin_HEXAGON_A4_vcmphgtui"
+          case 'w':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "gtui", 4))
+              break;
+            return Intrinsic::hexagon_A4_vcmpwgtui;	 // "__builtin_HEXAGON_A4_vcmpwgtui"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 2 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_pxfer_map", 10))
+          break;
+        return Intrinsic::hexagon_C2_pxfer_map;	 // "__builtin_HEXAGON_C2_pxfer_map"
+      case '4':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_nbitsclri", 10))
+          break;
+        return Intrinsic::hexagon_C4_nbitsclri;	 // "__builtin_HEXAGON_C4_nbitsclri"
+      }
+      break;
+    case 'F':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'c':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+22, "onv_", 4))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          switch (BuiltinName[27]) {
+          default: break;
+          case '2':	 // 2 strings to match.
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[29] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_d2df;	 // "__builtin_HEXAGON_F2_conv_d2df"
+            case 's':	 // 1 string to match.
+              if (BuiltinName[29] != 'f')
+                break;
+              return Intrinsic::hexagon_F2_conv_d2sf;	 // "__builtin_HEXAGON_F2_conv_d2sf"
+            }
+            break;
+          case 'f':	 // 2 strings to match.
+            if (BuiltinName[28] != '2')
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_df2d;	 // "__builtin_HEXAGON_F2_conv_df2d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_F2_conv_df2w;	 // "__builtin_HEXAGON_F2_conv_df2w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "f2", 2))
+            break;
+          switch (BuiltinName[29]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_sf2d;	 // "__builtin_HEXAGON_F2_conv_sf2d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_sf2w;	 // "__builtin_HEXAGON_F2_conv_sf2w"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          if (BuiltinName[27] != '2')
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[29] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_w2df;	 // "__builtin_HEXAGON_F2_conv_w2df"
+          case 's':	 // 1 string to match.
+            if (BuiltinName[29] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_w2sf;	 // "__builtin_HEXAGON_F2_conv_w2sf"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ffm", 3))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_lib", 4))
+            break;
+          return Intrinsic::hexagon_F2_dffma_lib;	 // "__builtin_HEXAGON_F2_dffma_lib"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_lib", 4))
+            break;
+          return Intrinsic::hexagon_F2_dffms_lib;	 // "__builtin_HEXAGON_F2_dffms_lib"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ffm", 3))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_lib", 4))
+            break;
+          return Intrinsic::hexagon_F2_sffma_lib;	 // "__builtin_HEXAGON_F2_sffma_lib"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_lib", 4))
+            break;
+          return Intrinsic::hexagon_F2_sffms_lib;	 // "__builtin_HEXAGON_F2_sffms_lib"
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 44 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 41 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 8 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 6 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "csc_s", 5))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cmacsc_s0;	 // "__builtin_HEXAGON_M2_cmacsc_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_cmacsc_s1;	 // "__builtin_HEXAGON_M2_cmacsc_s1"
+              }
+              break;
+            case 'p':	 // 4 strings to match.
+              if (BuiltinName[24] != 'y')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'r':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "s_s", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpyrs_s0;	 // "__builtin_HEXAGON_M2_cmpyrs_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpyrs_s1;	 // "__builtin_HEXAGON_M2_cmpyrs_s1"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "c_s", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpysc_s0;	 // "__builtin_HEXAGON_M2_cmpysc_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_cmpysc_s1;	 // "__builtin_HEXAGON_M2_cmpysc_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "acsc_s", 6))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cnacsc_s0;	 // "__builtin_HEXAGON_M2_cnacsc_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_cnacsc_s1;	 // "__builtin_HEXAGON_M2_cnacsc_s1"
+            }
+            break;
+          }
+          break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mmpy", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_s1", 3))
+              break;
+            return Intrinsic::hexagon_M2_hmmpyh_s1;	 // "__builtin_HEXAGON_M2_hmmpyh_s1"
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_s1", 3))
+              break;
+            return Intrinsic::hexagon_M2_hmmpyl_s1;	 // "__builtin_HEXAGON_M2_hmmpyl_s1"
+          }
+          break;
+        case 'm':	 // 21 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 12 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (BuiltinName[24] != 'c')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "s_s", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmachs_s0;	 // "__builtin_HEXAGON_M2_mmachs_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmachs_s1;	 // "__builtin_HEXAGON_M2_mmachs_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "s_s", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmacls_s0;	 // "__builtin_HEXAGON_M2_mmacls_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmacls_s1;	 // "__builtin_HEXAGON_M2_mmacls_s1"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 8 strings to match.
+              if (BuiltinName[24] != 'y')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "_rs", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyh_rs0;	 // "__builtin_HEXAGON_M2_mmpyh_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyh_rs1;	 // "__builtin_HEXAGON_M2_mmpyh_rs1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "_rs", 3))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyl_rs0;	 // "__builtin_HEXAGON_M2_mmpyl_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyl_rs1;	 // "__builtin_HEXAGON_M2_mmpyl_rs1"
+                }
+                break;
+              case 'u':	 // 4 strings to match.
+                switch (BuiltinName[26]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+27, "_s", 2))
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyuh_s0;	 // "__builtin_HEXAGON_M2_mmpyuh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyuh_s1;	 // "__builtin_HEXAGON_M2_mmpyuh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+27, "_s", 2))
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyul_s0;	 // "__builtin_HEXAGON_M2_mmpyul_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmpyul_s1;	 // "__builtin_HEXAGON_M2_mmpyul_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 9 strings to match.
+            if (memcmp(BuiltinName.data()+23, "y_", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_s", 2))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_hh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_hh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_s", 2))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_hl_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_hl_s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_s", 2))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_lh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_lh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_s", 2))
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_ll_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_ll_s1"
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "p_s1", 4))
+                break;
+              return Intrinsic::hexagon_M2_mpy_up_s1;	 // "__builtin_HEXAGON_M2_mpy_up_s1"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 10 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "bsdiff", 6))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_vabsdiffh;	 // "__builtin_HEXAGON_M2_vabsdiffh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_vabsdiffw;	 // "__builtin_HEXAGON_M2_vabsdiffw"
+            }
+            break;
+          case 'd':	 // 4 strings to match.
+            if (BuiltinName[23] != 'm')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+25, "cs_s", 4))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmacs_s0;	 // "__builtin_HEXAGON_M2_vdmacs_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmacs_s1;	 // "__builtin_HEXAGON_M2_vdmacs_s1"
+              }
+              break;
+            case 'p':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+25, "ys_s", 4))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmpys_s0;	 // "__builtin_HEXAGON_M2_vdmpys_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vdmpys_s1;	 // "__builtin_HEXAGON_M2_vdmpys_s1"
+              }
+              break;
+            }
+            break;
+          case 'm':	 // 4 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "c2s_s", 5))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vmac2s_s0;	 // "__builtin_HEXAGON_M2_vmac2s_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vmac2s_s1;	 // "__builtin_HEXAGON_M2_vmac2s_s1"
+              }
+              break;
+            case 'p':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "y2s_s", 5))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vmpy2s_s0;	 // "__builtin_HEXAGON_M2_vmpy2s_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vmpy2s_s1;	 // "__builtin_HEXAGON_M2_vmpy2s_s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 3 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mpy", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_whc", 4))
+              break;
+            return Intrinsic::hexagon_M4_cmpyi_whc;	 // "__builtin_HEXAGON_M4_cmpyi_whc"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_whc", 4))
+              break;
+            return Intrinsic::hexagon_M4_cmpyr_whc;	 // "__builtin_HEXAGON_M4_cmpyr_whc"
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "mpyw_acc", 8))
+            break;
+          return Intrinsic::hexagon_M4_pmpyw_acc;	 // "__builtin_HEXAGON_M4_pmpyw_acc"
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 12 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 4 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtractup", 8))
+            break;
+          return Intrinsic::hexagon_S2_extractup;	 // "__builtin_HEXAGON_S2_extractup"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "nsert_rp", 8))
+            break;
+          return Intrinsic::hexagon_S2_insert_rp;	 // "__builtin_HEXAGON_S2_insert_rp"
+        case 'v':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "splice", 6))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (BuiltinName[29] != 'b')
+              break;
+            return Intrinsic::hexagon_S2_vspliceib;	 // "__builtin_HEXAGON_S2_vspliceib"
+          case 'r':	 // 1 string to match.
+            if (BuiltinName[29] != 'b')
+              break;
+            return Intrinsic::hexagon_S2_vsplicerb;	 // "__builtin_HEXAGON_S2_vsplicerb"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 7 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'n':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "tstbit_", 7))
+            break;
+          switch (BuiltinName[29]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            return Intrinsic::hexagon_S4_ntstbit_i;	 // "__builtin_HEXAGON_S4_ntstbit_i"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_S4_ntstbit_r;	 // "__builtin_HEXAGON_S4_ntstbit_r"
+          }
+          break;
+        case 'v':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "crotate", 7))
+              break;
+            return Intrinsic::hexagon_S4_vrcrotate;	 // "__builtin_HEXAGON_S4_vrcrotate"
+          case 'x':	 // 4 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "ddsub", 5))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S4_vxaddsubh;	 // "__builtin_HEXAGON_S4_vxaddsubh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S4_vxaddsubw;	 // "__builtin_HEXAGON_S4_vxaddsubw"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+24, "ubadd", 5))
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_S4_vxsubaddh;	 // "__builtin_HEXAGON_S4_vxsubaddh"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::hexagon_S4_vxsubaddw;	 // "__builtin_HEXAGON_S4_vxsubaddw"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '5':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_popcountp", 10))
+          break;
+        return Intrinsic::hexagon_S5_popcountp;	 // "__builtin_HEXAGON_S5_popcountp"
+      }
+      break;
+    }
+    break;
+  case 31:	 // 95 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_combine_", 10))
+        break;
+      switch (BuiltinName[29]) {
+      default: break;
+      case 'h':	 // 2 strings to match.
+        switch (BuiltinName[30]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          return Intrinsic::hexagon_A2_combine_hh;	 // "__builtin_HEXAGON_A2_combine_hh"
+        case 'l':	 // 1 string to match.
+          return Intrinsic::hexagon_A2_combine_hl;	 // "__builtin_HEXAGON_A2_combine_hl"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[30]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          return Intrinsic::hexagon_A2_combine_lh;	 // "__builtin_HEXAGON_A2_combine_lh"
+        case 'l':	 // 1 string to match.
+          return Intrinsic::hexagon_A2_combine_ll;	 // "__builtin_HEXAGON_A2_combine_ll"
+        }
+        break;
+      }
+      break;
+    case 'F':	 // 10 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_conv_", 7))
+        break;
+      switch (BuiltinName[26]) {
+      default: break;
+      case 'd':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2", 2))
+          break;
+        switch (BuiltinName[29]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (BuiltinName[30] != 'f')
+            break;
+          return Intrinsic::hexagon_F2_conv_df2sf;	 // "__builtin_HEXAGON_F2_conv_df2sf"
+        case 'u':	 // 2 strings to match.
+          switch (BuiltinName[30]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_df2ud;	 // "__builtin_HEXAGON_F2_conv_df2ud"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_df2uw;	 // "__builtin_HEXAGON_F2_conv_df2uw"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2", 2))
+          break;
+        switch (BuiltinName[29]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (BuiltinName[30] != 'f')
+            break;
+          return Intrinsic::hexagon_F2_conv_sf2df;	 // "__builtin_HEXAGON_F2_conv_sf2df"
+        case 'u':	 // 2 strings to match.
+          switch (BuiltinName[30]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_sf2ud;	 // "__builtin_HEXAGON_F2_conv_sf2ud"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::hexagon_F2_conv_sf2uw;	 // "__builtin_HEXAGON_F2_conv_sf2uw"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 4 strings to match.
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (BuiltinName[28] != '2')
+            break;
+          switch (BuiltinName[29]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[30] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_ud2df;	 // "__builtin_HEXAGON_F2_conv_ud2df"
+          case 's':	 // 1 string to match.
+            if (BuiltinName[30] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_ud2sf;	 // "__builtin_HEXAGON_F2_conv_ud2sf"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          if (BuiltinName[28] != '2')
+            break;
+          switch (BuiltinName[29]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[30] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_uw2df;	 // "__builtin_HEXAGON_F2_conv_uw2df"
+          case 's':	 // 1 string to match.
+            if (BuiltinName[30] != 'f')
+              break;
+            return Intrinsic::hexagon_F2_conv_uw2sf;	 // "__builtin_HEXAGON_F2_conv_uw2sf"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 58 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 49 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mpyrsc_s", 8))
+            break;
+          switch (BuiltinName[30]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_cmpyrsc_s0;	 // "__builtin_HEXAGON_M2_cmpyrsc_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_cmpyrsc_s1;	 // "__builtin_HEXAGON_M2_cmpyrsc_s1"
+          }
+          break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "pmpy", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "s_s0", 4))
+              break;
+            return Intrinsic::hexagon_M2_dpmpyss_s0;	 // "__builtin_HEXAGON_M2_dpmpyss_s0"
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "u_s0", 4))
+              break;
+            return Intrinsic::hexagon_M2_dpmpyuu_s0;	 // "__builtin_HEXAGON_M2_dpmpyuu_s0"
+          }
+          break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mmpy", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_rs1", 4))
+              break;
+            return Intrinsic::hexagon_M2_hmmpyh_rs1;	 // "__builtin_HEXAGON_M2_hmmpyh_rs1"
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "_rs1", 4))
+              break;
+            return Intrinsic::hexagon_M2_hmmpyl_rs1;	 // "__builtin_HEXAGON_M2_hmmpyl_rs1"
+          }
+          break;
+        case 'm':	 // 28 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 12 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 8 strings to match.
+              if (BuiltinName[24] != 'c')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "s_rs", 4))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmachs_rs0;	 // "__builtin_HEXAGON_M2_mmachs_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmachs_rs1;	 // "__builtin_HEXAGON_M2_mmachs_rs1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+26, "s_rs", 4))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmacls_rs0;	 // "__builtin_HEXAGON_M2_mmacls_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmacls_rs1;	 // "__builtin_HEXAGON_M2_mmacls_rs1"
+                }
+                break;
+              case 'u':	 // 4 strings to match.
+                switch (BuiltinName[26]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+27, "s_s", 3))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacuhs_s0;	 // "__builtin_HEXAGON_M2_mmacuhs_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmacuhs_s1;	 // "__builtin_HEXAGON_M2_mmacuhs_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+27, "s_s", 3))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmaculs_s0;	 // "__builtin_HEXAGON_M2_mmaculs_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mmaculs_s1;	 // "__builtin_HEXAGON_M2_mmaculs_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 4 strings to match.
+              if (memcmp(BuiltinName.data()+24, "yu", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_rs", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyuh_rs0;	 // "__builtin_HEXAGON_M2_mmpyuh_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyuh_rs1;	 // "__builtin_HEXAGON_M2_mmpyuh_rs1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "_rs", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyul_rs0;	 // "__builtin_HEXAGON_M2_mmpyul_rs0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mmpyul_rs1;	 // "__builtin_HEXAGON_M2_mmpyul_rs1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'p':	 // 16 strings to match.
+            if (BuiltinName[23] != 'y')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'd':	 // 8 strings to match.
+              if (BuiltinName[25] != '_')
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_hh_s0;	 // "__builtin_HEXAGON_M2_mpyd_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_hh_s1;	 // "__builtin_HEXAGON_M2_mpyd_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_hl_s0;	 // "__builtin_HEXAGON_M2_mpyd_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_hl_s1;	 // "__builtin_HEXAGON_M2_mpyd_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_lh_s0;	 // "__builtin_HEXAGON_M2_mpyd_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_lh_s1;	 // "__builtin_HEXAGON_M2_mpyd_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_ll_s0;	 // "__builtin_HEXAGON_M2_mpyd_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_ll_s1;	 // "__builtin_HEXAGON_M2_mpyd_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 8 strings to match.
+              if (BuiltinName[25] != '_')
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_hh_s0;	 // "__builtin_HEXAGON_M2_mpyu_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_hh_s1;	 // "__builtin_HEXAGON_M2_mpyu_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_hl_s0;	 // "__builtin_HEXAGON_M2_mpyu_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_hl_s1;	 // "__builtin_HEXAGON_M2_mpyu_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_lh_s0;	 // "__builtin_HEXAGON_M2_mpyu_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_lh_s1;	 // "__builtin_HEXAGON_M2_mpyu_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+28, "_s", 2))
+                    break;
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_ll_s0;	 // "__builtin_HEXAGON_M2_mpyu_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_ll_s1;	 // "__builtin_HEXAGON_M2_mpyu_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 15 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "mpyrs_s", 7))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_vdmpyrs_s0;	 // "__builtin_HEXAGON_M2_vdmpyrs_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_vdmpyrs_s1;	 // "__builtin_HEXAGON_M2_vdmpyrs_s1"
+            }
+            break;
+          case 'm':	 // 8 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (memcmp(BuiltinName.data()+24, "c2", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "s_s", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2es_s0;	 // "__builtin_HEXAGON_M2_vmac2es_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2es_s1;	 // "__builtin_HEXAGON_M2_vmac2es_s1"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "u_s", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2su_s0;	 // "__builtin_HEXAGON_M2_vmac2su_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmac2su_s1;	 // "__builtin_HEXAGON_M2_vmac2su_s1"
+                }
+                break;
+              }
+              break;
+            case 'p':	 // 4 strings to match.
+              if (memcmp(BuiltinName.data()+24, "y2", 2))
+                break;
+              switch (BuiltinName[26]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "s_s", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2es_s0;	 // "__builtin_HEXAGON_M2_vmpy2es_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2es_s1;	 // "__builtin_HEXAGON_M2_vmpy2es_s1"
+                }
+                break;
+              case 's':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+27, "u_s", 3))
+                  break;
+                switch (BuiltinName[30]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2su_s0;	 // "__builtin_HEXAGON_M2_vmpy2su_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vmpy2su_s1;	 // "__builtin_HEXAGON_M2_vmpy2su_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 5 strings to match.
+            if (memcmp(BuiltinName.data()+23, "cm", 2))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (BuiltinName[26] != 'c')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_vrcmaci_s0;	 // "__builtin_HEXAGON_M2_vrcmaci_s0"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_vrcmacr_s0;	 // "__builtin_HEXAGON_M2_vrcmacr_s0"
+              }
+              break;
+            case 'p':	 // 3 strings to match.
+              if (BuiltinName[26] != 'y')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_vrcmpyi_s0;	 // "__builtin_HEXAGON_M2_vrcmpyi_s0"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_s0", 3))
+                  break;
+                return Intrinsic::hexagon_M2_vrcmpyr_s0;	 // "__builtin_HEXAGON_M2_vrcmpyr_s0"
+              case 's':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_s1", 3))
+                  break;
+                return Intrinsic::hexagon_M2_vrcmpys_s1;	 // "__builtin_HEXAGON_M2_vrcmpys_s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case '4':	 // 9 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'm':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+22, "pyr", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+26, "_add", 4))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_mpyri_addi;	 // "__builtin_HEXAGON_M4_mpyri_addi"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_mpyri_addr;	 // "__builtin_HEXAGON_M4_mpyri_addr"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+26, "_add", 4))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_mpyrr_addi;	 // "__builtin_HEXAGON_M4_mpyrr_addi"
+            case 'r':	 // 1 string to match.
+              return Intrinsic::hexagon_M4_mpyrr_addr;	 // "__builtin_HEXAGON_M4_mpyrr_addr"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 5 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "mpyh_acc", 8))
+              break;
+            return Intrinsic::hexagon_M4_vpmpyh_acc;	 // "__builtin_HEXAGON_M4_vpmpyh_acc"
+          case 'r':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+23, "mpy", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+27, "h_s", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_vrmpyeh_s0;	 // "__builtin_HEXAGON_M4_vrmpyeh_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_vrmpyeh_s1;	 // "__builtin_HEXAGON_M4_vrmpyeh_s1"
+              }
+              break;
+            case 'o':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+27, "h_s", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_vrmpyoh_s0;	 // "__builtin_HEXAGON_M4_vrmpyoh_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M4_vrmpyoh_s1;	 // "__builtin_HEXAGON_M4_vrmpyoh_s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 23 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 17 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asl_i_p_or;	 // "__builtin_HEXAGON_S2_asl_i_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asl_i_r_or;	 // "__builtin_HEXAGON_S2_asl_i_r_or"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asl_r_p_or;	 // "__builtin_HEXAGON_S2_asl_r_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asl_r_r_or;	 // "__builtin_HEXAGON_S2_asl_r_r_or"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asr_i_p_or;	 // "__builtin_HEXAGON_S2_asr_i_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asr_i_r_or;	 // "__builtin_HEXAGON_S2_asr_i_r_or"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asr_r_p_or;	 // "__builtin_HEXAGON_S2_asr_r_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_asr_r_r_or;	 // "__builtin_HEXAGON_S2_asr_r_r_or"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (BuiltinName[22] != 'n')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ertp_rp", 7))
+              break;
+            return Intrinsic::hexagon_S2_insertp_rp;	 // "__builtin_HEXAGON_S2_insertp_rp"
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "erleave", 7))
+              break;
+            return Intrinsic::hexagon_S2_interleave;	 // "__builtin_HEXAGON_S2_interleave"
+          }
+          break;
+        case 'l':	 // 6 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+24, "_r_", 3))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+28, "_or", 3))
+                break;
+              return Intrinsic::hexagon_S2_lsl_r_p_or;	 // "__builtin_HEXAGON_S2_lsl_r_p_or"
+            case 'r':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+28, "_or", 3))
+                break;
+              return Intrinsic::hexagon_S2_lsl_r_r_or;	 // "__builtin_HEXAGON_S2_lsl_r_r_or"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsr_i_p_or;	 // "__builtin_HEXAGON_S2_lsr_i_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsr_i_r_or;	 // "__builtin_HEXAGON_S2_lsr_i_r_or"
+              }
+              break;
+            case 'r':	 // 2 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsr_r_p_or;	 // "__builtin_HEXAGON_S2_lsr_r_p_or"
+              case 'r':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+28, "_or", 3))
+                  break;
+                return Intrinsic::hexagon_S2_lsr_r_r_or;	 // "__builtin_HEXAGON_S2_lsr_r_r_or"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rndpackwh", 9))
+            break;
+          return Intrinsic::hexagon_S2_vrndpackwh;	 // "__builtin_HEXAGON_S2_vrndpackwh"
+        }
+        break;
+      case '4':	 // 5 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtract_rp", 9))
+            break;
+          return Intrinsic::hexagon_S4_extract_rp;	 // "__builtin_HEXAGON_S4_extract_rp"
+        case 'o':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "ri_", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "sl_ri", 5))
+              break;
+            return Intrinsic::hexagon_S4_ori_asl_ri;	 // "__builtin_HEXAGON_S4_ori_asl_ri"
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "sr_ri", 5))
+              break;
+            return Intrinsic::hexagon_S4_ori_lsr_ri;	 // "__builtin_HEXAGON_S4_ori_lsr_ri"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (BuiltinName[22] != 'x')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ddsubhr", 7))
+              break;
+            return Intrinsic::hexagon_S4_vxaddsubhr;	 // "__builtin_HEXAGON_S4_vxaddsubhr"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ubaddhr", 7))
+              break;
+            return Intrinsic::hexagon_S4_vxsubaddhr;	 // "__builtin_HEXAGON_S4_vxsubaddhr"
+          }
+          break;
+        }
+        break;
+      case '5':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_asrhub_sat", 11))
+          break;
+        return Intrinsic::hexagon_S5_asrhub_sat;	 // "__builtin_HEXAGON_S5_asrhub_sat"
+      }
+      break;
+    }
+    break;
+  case 32:	 // 96 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 16 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 14 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+22, "ddh_", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+27, "16_", 3))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              switch (BuiltinName[31]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_hh;	 // "__builtin_HEXAGON_A2_addh_h16_hh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_hl;	 // "__builtin_HEXAGON_A2_addh_h16_hl"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              switch (BuiltinName[31]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_lh;	 // "__builtin_HEXAGON_A2_addh_h16_lh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_addh_h16_ll;	 // "__builtin_HEXAGON_A2_addh_h16_ll"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "16_", 3))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[31] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_addh_l16_hl;	 // "__builtin_HEXAGON_A2_addh_l16_hl"
+            case 'l':	 // 1 string to match.
+              if (BuiltinName[31] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_addh_l16_ll;	 // "__builtin_HEXAGON_A2_addh_l16_ll"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+22, "ubh_", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+27, "16_", 3))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              switch (BuiltinName[31]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_hh;	 // "__builtin_HEXAGON_A2_subh_h16_hh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_hl;	 // "__builtin_HEXAGON_A2_subh_h16_hl"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              switch (BuiltinName[31]) {
+              default: break;
+              case 'h':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_lh;	 // "__builtin_HEXAGON_A2_subh_h16_lh"
+              case 'l':	 // 1 string to match.
+                return Intrinsic::hexagon_A2_subh_h16_ll;	 // "__builtin_HEXAGON_A2_subh_h16_ll"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "16_", 3))
+              break;
+            switch (BuiltinName[30]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[31] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_subh_l16_hl;	 // "__builtin_HEXAGON_A2_subh_l16_hl"
+            case 'l':	 // 1 string to match.
+              if (BuiltinName[31] != 'l')
+                break;
+              return Intrinsic::hexagon_A2_subh_l16_ll;	 // "__builtin_HEXAGON_A2_subh_l16_ll"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (BuiltinName[22] != 'r')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "ddub_acc", 8))
+              break;
+            return Intrinsic::hexagon_A2_vraddub_acc;	 // "__builtin_HEXAGON_A2_vraddub_acc"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "adub_acc", 8))
+              break;
+            return Intrinsic::hexagon_A2_vrsadub_acc;	 // "__builtin_HEXAGON_A2_vrsadub_acc"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 2 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "oundscheck", 10))
+            break;
+          return Intrinsic::hexagon_A4_boundscheck;	 // "__builtin_HEXAGON_A4_boundscheck"
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "cmpbeq_any", 10))
+            break;
+          return Intrinsic::hexagon_A4_vcmpbeq_any;	 // "__builtin_HEXAGON_A4_vcmpbeq_any"
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "4_fastcorner9", 13))
+        break;
+      return Intrinsic::hexagon_C4_fastcorner9;	 // "__builtin_HEXAGON_C4_fastcorner9"
+    case 'M':	 // 16 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'm':	 // 12 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'm':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+23, "acu", 3))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "s_rs", 4))
+              break;
+            switch (BuiltinName[31]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mmacuhs_rs0;	 // "__builtin_HEXAGON_M2_mmacuhs_rs0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mmacuhs_rs1;	 // "__builtin_HEXAGON_M2_mmacuhs_rs1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "s_rs", 4))
+              break;
+            switch (BuiltinName[31]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mmaculs_rs0;	 // "__builtin_HEXAGON_M2_mmaculs_rs0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mmaculs_rs1;	 // "__builtin_HEXAGON_M2_mmaculs_rs1"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+23, "yud_", 4))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'h':	 // 4 strings to match.
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+29, "_s", 2))
+                break;
+              switch (BuiltinName[31]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_hh_s0;	 // "__builtin_HEXAGON_M2_mpyud_hh_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_hh_s1;	 // "__builtin_HEXAGON_M2_mpyud_hh_s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+29, "_s", 2))
+                break;
+              switch (BuiltinName[31]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_hl_s0;	 // "__builtin_HEXAGON_M2_mpyud_hl_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_hl_s1;	 // "__builtin_HEXAGON_M2_mpyud_hl_s1"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (BuiltinName[28]) {
+            default: break;
+            case 'h':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+29, "_s", 2))
+                break;
+              switch (BuiltinName[31]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_lh_s0;	 // "__builtin_HEXAGON_M2_mpyud_lh_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_lh_s1;	 // "__builtin_HEXAGON_M2_mpyud_lh_s1"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+29, "_s", 2))
+                break;
+              switch (BuiltinName[31]) {
+              default: break;
+              case '0':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_ll_s0;	 // "__builtin_HEXAGON_M2_mpyud_ll_s0"
+              case '1':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_mpyud_ll_s1;	 // "__builtin_HEXAGON_M2_mpyud_ll_s1"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+22, "rcm", 3))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (BuiltinName[26] != 'c')
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "_s0c", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrcmaci_s0c;	 // "__builtin_HEXAGON_M2_vrcmaci_s0c"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "_s0c", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrcmacr_s0c;	 // "__builtin_HEXAGON_M2_vrcmacr_s0c"
+          }
+          break;
+        case 'p':	 // 2 strings to match.
+          if (BuiltinName[26] != 'y')
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "_s0c", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrcmpyi_s0c;	 // "__builtin_HEXAGON_M2_vrcmpyi_s0c"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "_s0c", 4))
+              break;
+            return Intrinsic::hexagon_M2_vrcmpyr_s0c;	 // "__builtin_HEXAGON_M2_vrcmpyr_s0c"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 63 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 56 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 32 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "dasl_rrri", 9))
+              break;
+            return Intrinsic::hexagon_S2_addasl_rrri;	 // "__builtin_HEXAGON_S2_addasl_rrri"
+          case 's':	 // 31 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'l':	 // 15 strings to match.
+              if (BuiltinName[24] != '_')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'i':	 // 7 strings to match.
+                if (BuiltinName[26] != '_')
+                  break;
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'p':	 // 3 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_p_acc;	 // "__builtin_HEXAGON_S2_asl_i_p_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_p_and;	 // "__builtin_HEXAGON_S2_asl_i_p_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_i_p_nac;	 // "__builtin_HEXAGON_S2_asl_i_p_nac"
+                  }
+                  break;
+                case 'r':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_r_acc;	 // "__builtin_HEXAGON_S2_asl_i_r_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_i_r_and;	 // "__builtin_HEXAGON_S2_asl_i_r_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_i_r_nac;	 // "__builtin_HEXAGON_S2_asl_i_r_nac"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "at", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_i_r_sat;	 // "__builtin_HEXAGON_S2_asl_i_r_sat"
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 8 strings to match.
+                if (BuiltinName[26] != '_')
+                  break;
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'p':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_p_acc;	 // "__builtin_HEXAGON_S2_asl_r_p_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_p_and;	 // "__builtin_HEXAGON_S2_asl_r_p_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_r_p_nac;	 // "__builtin_HEXAGON_S2_asl_r_p_nac"
+                  case 'x':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "or", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_r_p_xor;	 // "__builtin_HEXAGON_S2_asl_r_p_xor"
+                  }
+                  break;
+                case 'r':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_r_acc;	 // "__builtin_HEXAGON_S2_asl_r_r_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asl_r_r_and;	 // "__builtin_HEXAGON_S2_asl_r_r_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_r_r_nac;	 // "__builtin_HEXAGON_S2_asl_r_r_nac"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "at", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asl_r_r_sat;	 // "__builtin_HEXAGON_S2_asl_r_r_sat"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 16 strings to match.
+              if (BuiltinName[24] != '_')
+                break;
+              switch (BuiltinName[25]) {
+              default: break;
+              case 'i':	 // 8 strings to match.
+                if (BuiltinName[26] != '_')
+                  break;
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'p':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_p_acc;	 // "__builtin_HEXAGON_S2_asr_i_p_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_p_and;	 // "__builtin_HEXAGON_S2_asr_i_p_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_i_p_nac;	 // "__builtin_HEXAGON_S2_asr_i_p_nac"
+                  case 'r':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "nd", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_i_p_rnd;	 // "__builtin_HEXAGON_S2_asr_i_p_rnd"
+                  }
+                  break;
+                case 'r':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_r_acc;	 // "__builtin_HEXAGON_S2_asr_i_r_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_i_r_and;	 // "__builtin_HEXAGON_S2_asr_i_r_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_i_r_nac;	 // "__builtin_HEXAGON_S2_asr_i_r_nac"
+                  case 'r':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "nd", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_i_r_rnd;	 // "__builtin_HEXAGON_S2_asr_i_r_rnd"
+                  }
+                  break;
+                }
+                break;
+              case 'r':	 // 8 strings to match.
+                if (BuiltinName[26] != '_')
+                  break;
+                switch (BuiltinName[27]) {
+                default: break;
+                case 'p':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_p_acc;	 // "__builtin_HEXAGON_S2_asr_r_p_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_p_and;	 // "__builtin_HEXAGON_S2_asr_r_p_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_r_p_nac;	 // "__builtin_HEXAGON_S2_asr_r_p_nac"
+                  case 'x':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "or", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_r_p_xor;	 // "__builtin_HEXAGON_S2_asr_r_p_xor"
+                  }
+                  break;
+                case 'r':	 // 4 strings to match.
+                  if (BuiltinName[28] != '_')
+                    break;
+                  switch (BuiltinName[29]) {
+                  default: break;
+                  case 'a':	 // 2 strings to match.
+                    switch (BuiltinName[30]) {
+                    default: break;
+                    case 'c':	 // 1 string to match.
+                      if (BuiltinName[31] != 'c')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_r_acc;	 // "__builtin_HEXAGON_S2_asr_r_r_acc"
+                    case 'n':	 // 1 string to match.
+                      if (BuiltinName[31] != 'd')
+                        break;
+                      return Intrinsic::hexagon_S2_asr_r_r_and;	 // "__builtin_HEXAGON_S2_asr_r_r_and"
+                    }
+                    break;
+                  case 'n':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "ac", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_r_r_nac;	 // "__builtin_HEXAGON_S2_asr_r_r_nac"
+                  case 's':	 // 1 string to match.
+                    if (memcmp(BuiltinName.data()+30, "at", 2))
+                      break;
+                    return Intrinsic::hexagon_S2_asr_r_r_sat;	 // "__builtin_HEXAGON_S2_asr_r_r_sat"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtractu_rp", 10))
+            break;
+          return Intrinsic::hexagon_S2_extractu_rp;	 // "__builtin_HEXAGON_S2_extractu_rp"
+        case 'l':	 // 20 strings to match.
+          if (BuiltinName[22] != 's')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'l':	 // 7 strings to match.
+            if (memcmp(BuiltinName.data()+24, "_r_", 3))
+              break;
+            switch (BuiltinName[27]) {
+            default: break;
+            case 'p':	 // 4 strings to match.
+              if (BuiltinName[28] != '_')
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                switch (BuiltinName[30]) {
+                default: break;
+                case 'c':	 // 1 string to match.
+                  if (BuiltinName[31] != 'c')
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_p_acc;	 // "__builtin_HEXAGON_S2_lsl_r_p_acc"
+                case 'n':	 // 1 string to match.
+                  if (BuiltinName[31] != 'd')
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_p_and;	 // "__builtin_HEXAGON_S2_lsl_r_p_and"
+                }
+                break;
+              case 'n':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+30, "ac", 2))
+                  break;
+                return Intrinsic::hexagon_S2_lsl_r_p_nac;	 // "__builtin_HEXAGON_S2_lsl_r_p_nac"
+              case 'x':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+30, "or", 2))
+                  break;
+                return Intrinsic::hexagon_S2_lsl_r_p_xor;	 // "__builtin_HEXAGON_S2_lsl_r_p_xor"
+              }
+              break;
+            case 'r':	 // 3 strings to match.
+              if (BuiltinName[28] != '_')
+                break;
+              switch (BuiltinName[29]) {
+              default: break;
+              case 'a':	 // 2 strings to match.
+                switch (BuiltinName[30]) {
+                default: break;
+                case 'c':	 // 1 string to match.
+                  if (BuiltinName[31] != 'c')
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_r_acc;	 // "__builtin_HEXAGON_S2_lsl_r_r_acc"
+                case 'n':	 // 1 string to match.
+                  if (BuiltinName[31] != 'd')
+                    break;
+                  return Intrinsic::hexagon_S2_lsl_r_r_and;	 // "__builtin_HEXAGON_S2_lsl_r_r_and"
+                }
+                break;
+              case 'n':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+30, "ac", 2))
+                  break;
+                return Intrinsic::hexagon_S2_lsl_r_r_nac;	 // "__builtin_HEXAGON_S2_lsl_r_r_nac"
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 13 strings to match.
+            if (BuiltinName[24] != '_')
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'i':	 // 6 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 3 strings to match.
+                if (BuiltinName[28] != '_')
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (BuiltinName[31] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_p_acc;	 // "__builtin_HEXAGON_S2_lsr_i_p_acc"
+                  case 'n':	 // 1 string to match.
+                    if (BuiltinName[31] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_p_and;	 // "__builtin_HEXAGON_S2_lsr_i_p_and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+30, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_i_p_nac;	 // "__builtin_HEXAGON_S2_lsr_i_p_nac"
+                }
+                break;
+              case 'r':	 // 3 strings to match.
+                if (BuiltinName[28] != '_')
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (BuiltinName[31] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_r_acc;	 // "__builtin_HEXAGON_S2_lsr_i_r_acc"
+                  case 'n':	 // 1 string to match.
+                    if (BuiltinName[31] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_i_r_and;	 // "__builtin_HEXAGON_S2_lsr_i_r_and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+30, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_i_r_nac;	 // "__builtin_HEXAGON_S2_lsr_i_r_nac"
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 7 strings to match.
+              if (BuiltinName[26] != '_')
+                break;
+              switch (BuiltinName[27]) {
+              default: break;
+              case 'p':	 // 4 strings to match.
+                if (BuiltinName[28] != '_')
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (BuiltinName[31] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_p_acc;	 // "__builtin_HEXAGON_S2_lsr_r_p_acc"
+                  case 'n':	 // 1 string to match.
+                    if (BuiltinName[31] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_p_and;	 // "__builtin_HEXAGON_S2_lsr_r_p_and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+30, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_r_p_nac;	 // "__builtin_HEXAGON_S2_lsr_r_p_nac"
+                case 'x':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+30, "or", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_r_p_xor;	 // "__builtin_HEXAGON_S2_lsr_r_p_xor"
+                }
+                break;
+              case 'r':	 // 3 strings to match.
+                if (BuiltinName[28] != '_')
+                  break;
+                switch (BuiltinName[29]) {
+                default: break;
+                case 'a':	 // 2 strings to match.
+                  switch (BuiltinName[30]) {
+                  default: break;
+                  case 'c':	 // 1 string to match.
+                    if (BuiltinName[31] != 'c')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_r_acc;	 // "__builtin_HEXAGON_S2_lsr_r_r_acc"
+                  case 'n':	 // 1 string to match.
+                    if (BuiltinName[31] != 'd')
+                      break;
+                    return Intrinsic::hexagon_S2_lsr_r_r_and;	 // "__builtin_HEXAGON_S2_lsr_r_r_and"
+                  }
+                  break;
+                case 'n':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+30, "ac", 2))
+                    break;
+                  return Intrinsic::hexagon_S2_lsr_r_r_nac;	 // "__builtin_HEXAGON_S2_lsr_r_r_nac"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 't':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "ogglebit_", 9))
+            break;
+          switch (BuiltinName[31]) {
+          default: break;
+          case 'i':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_togglebit_i;	 // "__builtin_HEXAGON_S2_togglebit_i"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::hexagon_S2_togglebit_r;	 // "__builtin_HEXAGON_S2_togglebit_r"
+          }
+          break;
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "rndpackwhs", 10))
+            break;
+          return Intrinsic::hexagon_S2_vrndpackwhs;	 // "__builtin_HEXAGON_S2_vrndpackwhs"
+        }
+        break;
+      case '4':	 // 7 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "di_", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "sl_ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_addi_asl_ri;	 // "__builtin_HEXAGON_S4_addi_asl_ri"
+            case 'l':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "sr_ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_addi_lsr_ri;	 // "__builtin_HEXAGON_S4_addi_lsr_ri"
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+23, "di_", 3))
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "sl_ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_andi_asl_ri;	 // "__builtin_HEXAGON_S4_andi_asl_ri"
+            case 'l':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+27, "sr_ri", 5))
+                break;
+              return Intrinsic::hexagon_S4_andi_lsr_ri;	 // "__builtin_HEXAGON_S4_andi_lsr_ri"
+            }
+            break;
+          }
+          break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xtractp_rp", 10))
+            break;
+          return Intrinsic::hexagon_S4_extractp_rp;	 // "__builtin_HEXAGON_S4_extractp_rp"
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "ubi_", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "sl_ri", 5))
+              break;
+            return Intrinsic::hexagon_S4_subi_asl_ri;	 // "__builtin_HEXAGON_S4_subi_asl_ri"
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "sr_ri", 5))
+              break;
+            return Intrinsic::hexagon_S4_subi_lsr_ri;	 // "__builtin_HEXAGON_S4_subi_lsr_ri"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 33:	 // 9 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+19, "4_round_r", 9))
+        break;
+      switch (BuiltinName[28]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+29, "_sat", 4))
+          break;
+        return Intrinsic::hexagon_A4_round_ri_sat;	 // "__builtin_HEXAGON_A4_round_ri_sat"
+      case 'r':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+29, "_sat", 4))
+          break;
+        return Intrinsic::hexagon_A4_round_rr_sat;	 // "__builtin_HEXAGON_A4_round_rr_sat"
+      }
+      break;
+    case 'M':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "2_vrcmpys_s1rp", 14))
+        break;
+      return Intrinsic::hexagon_M2_vrcmpys_s1rp;	 // "__builtin_HEXAGON_M2_vrcmpys_s1rp"
+    case 'S':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "sl_i_", 5))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "_xacc", 5))
+            break;
+          return Intrinsic::hexagon_S2_asl_i_p_xacc;	 // "__builtin_HEXAGON_S2_asl_i_p_xacc"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "_xacc", 5))
+            break;
+          return Intrinsic::hexagon_S2_asl_i_r_xacc;	 // "__builtin_HEXAGON_S2_asl_i_r_xacc"
+        }
+        break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "einterleave", 11))
+          break;
+        return Intrinsic::hexagon_S2_deinterleave;	 // "__builtin_HEXAGON_S2_deinterleave"
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "xtractup_rp", 11))
+          break;
+        return Intrinsic::hexagon_S2_extractup_rp;	 // "__builtin_HEXAGON_S2_extractup_rp"
+      case 'l':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "sr_i_", 5))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "_xacc", 5))
+            break;
+          return Intrinsic::hexagon_S2_lsr_i_p_xacc;	 // "__builtin_HEXAGON_S2_lsr_i_p_xacc"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "_xacc", 5))
+            break;
+          return Intrinsic::hexagon_S2_lsr_i_r_xacc;	 // "__builtin_HEXAGON_S2_lsr_i_r_xacc"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 34:	 // 41 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'M':	 // 38 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 35 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'm':	 // 33 strings to match.
+          if (memcmp(BuiltinName.data()+22, "py_", 3))
+            break;
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+26, "cc_", 3))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_hh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_hh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_hl_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_hl_s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_lh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_lh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_ll_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_acc_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_ll_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+26, "ac_", 3))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_hh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_hh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_hl_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_hl_s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_lh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_lh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_ll_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_nac_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_ll_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+26, "nd_", 3))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_rnd_hh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_rnd_hh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_rnd_hl_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_rnd_hl_s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_rnd_lh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_rnd_lh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_rnd_ll_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_rnd_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_rnd_ll_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 's':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+26, "at_", 3))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'h':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_hh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_hh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_hl_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_hl_s1"
+                }
+                break;
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_lh_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_lh_s1"
+                }
+                break;
+              case 'l':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+31, "_s", 2))
+                  break;
+                switch (BuiltinName[33]) {
+                default: break;
+                case '0':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_ll_s0"
+                case '1':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_mpy_sat_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_ll_s1"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "p_s1_sat", 8))
+              break;
+            return Intrinsic::hexagon_M2_mpy_up_s1_sat;	 // "__builtin_HEXAGON_M2_mpy_up_s1_sat"
+          }
+          break;
+        case 'v':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+22, "mpy2s_s", 7))
+            break;
+          switch (BuiltinName[29]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+30, "pack", 4))
+              break;
+            return Intrinsic::hexagon_M2_vmpy2s_s0pack;	 // "__builtin_HEXAGON_M2_vmpy2s_s0pack"
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+30, "pack", 4))
+              break;
+            return Intrinsic::hexagon_M2_vmpy2s_s1pack;	 // "__builtin_HEXAGON_M2_vmpy2s_s1pack"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 3 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "c_up_s1_sat", 11))
+              break;
+            return Intrinsic::hexagon_M4_mac_up_s1_sat;	 // "__builtin_HEXAGON_M4_mac_up_s1_sat"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "yri_addr_u2", 11))
+              break;
+            return Intrinsic::hexagon_M4_mpyri_addr_u2;	 // "__builtin_HEXAGON_M4_mpyri_addr_u2"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "ac_up_s1_sat", 12))
+            break;
+          return Intrinsic::hexagon_M4_nac_up_s1_sat;	 // "__builtin_HEXAGON_M4_nac_up_s1_sat"
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 3 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+20, "_vsat", 5))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "b_nopack", 8))
+            break;
+          return Intrinsic::hexagon_S2_vsathb_nopack;	 // "__builtin_HEXAGON_S2_vsathb_nopack"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "h_nopack", 8))
+            break;
+          return Intrinsic::hexagon_S2_vsatwh_nopack;	 // "__builtin_HEXAGON_S2_vsatwh_nopack"
+        }
+        break;
+      case '4':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "_vrcrotate_acc", 14))
+          break;
+        return Intrinsic::hexagon_S4_vrcrotate_acc;	 // "__builtin_HEXAGON_S4_vrcrotate_acc"
+      }
+      break;
+    }
+    break;
+  case 35:	 // 64 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'F':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_conv_", 7))
+        break;
+      switch (BuiltinName[26]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2", 2))
+          break;
+        switch (BuiltinName[29]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+30, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_df2d_chop;	 // "__builtin_HEXAGON_F2_conv_df2d_chop"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+30, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_df2w_chop;	 // "__builtin_HEXAGON_F2_conv_df2w_chop"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2", 2))
+          break;
+        switch (BuiltinName[29]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+30, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_sf2d_chop;	 // "__builtin_HEXAGON_F2_conv_sf2d_chop"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+30, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_sf2w_chop;	 // "__builtin_HEXAGON_F2_conv_sf2w_chop"
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 56 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case '2':	 // 52 strings to match.
+        if (BuiltinName[20] != '_')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 5 strings to match.
+          if (memcmp(BuiltinName.data()+22, "pmpy", 4))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (memcmp(BuiltinName.data()+27, "s_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "cc_s0", 5))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyss_acc_s0;	 // "__builtin_HEXAGON_M2_dpmpyss_acc_s0"
+            case 'n':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ac_s0", 5))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyss_nac_s0;	 // "__builtin_HEXAGON_M2_dpmpyss_nac_s0"
+            case 'r':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "nd_s0", 5))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyss_rnd_s0;	 // "__builtin_HEXAGON_M2_dpmpyss_rnd_s0"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+27, "u_", 2))
+              break;
+            switch (BuiltinName[29]) {
+            default: break;
+            case 'a':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "cc_s0", 5))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyuu_acc_s0;	 // "__builtin_HEXAGON_M2_dpmpyuu_acc_s0"
+            case 'n':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+30, "ac_s0", 5))
+                break;
+              return Intrinsic::hexagon_M2_dpmpyuu_nac_s0;	 // "__builtin_HEXAGON_M2_dpmpyuu_nac_s0"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 40 strings to match.
+          if (memcmp(BuiltinName.data()+22, "py", 2))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'd':	 // 24 strings to match.
+            if (BuiltinName[25] != '_')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'a':	 // 8 strings to match.
+              if (memcmp(BuiltinName.data()+27, "cc_", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_hh_s0;	 // "__builtin_HEXAGON_M2_mpyd_acc_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_hh_s1;	 // "__builtin_HEXAGON_M2_mpyd_acc_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_hl_s0;	 // "__builtin_HEXAGON_M2_mpyd_acc_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_hl_s1;	 // "__builtin_HEXAGON_M2_mpyd_acc_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_lh_s0;	 // "__builtin_HEXAGON_M2_mpyd_acc_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_lh_s1;	 // "__builtin_HEXAGON_M2_mpyd_acc_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_ll_s0;	 // "__builtin_HEXAGON_M2_mpyd_acc_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_acc_ll_s1;	 // "__builtin_HEXAGON_M2_mpyd_acc_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 8 strings to match.
+              if (memcmp(BuiltinName.data()+27, "ac_", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_hh_s0;	 // "__builtin_HEXAGON_M2_mpyd_nac_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_hh_s1;	 // "__builtin_HEXAGON_M2_mpyd_nac_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_hl_s0;	 // "__builtin_HEXAGON_M2_mpyd_nac_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_hl_s1;	 // "__builtin_HEXAGON_M2_mpyd_nac_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_lh_s0;	 // "__builtin_HEXAGON_M2_mpyd_nac_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_lh_s1;	 // "__builtin_HEXAGON_M2_mpyd_nac_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_ll_s0;	 // "__builtin_HEXAGON_M2_mpyd_nac_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_nac_ll_s1;	 // "__builtin_HEXAGON_M2_mpyd_nac_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'r':	 // 8 strings to match.
+              if (memcmp(BuiltinName.data()+27, "nd_", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_hh_s0;	 // "__builtin_HEXAGON_M2_mpyd_rnd_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_hh_s1;	 // "__builtin_HEXAGON_M2_mpyd_rnd_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_hl_s0;	 // "__builtin_HEXAGON_M2_mpyd_rnd_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_hl_s1;	 // "__builtin_HEXAGON_M2_mpyd_rnd_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_lh_s0;	 // "__builtin_HEXAGON_M2_mpyd_rnd_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_lh_s1;	 // "__builtin_HEXAGON_M2_mpyd_rnd_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_ll_s0;	 // "__builtin_HEXAGON_M2_mpyd_rnd_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyd_rnd_ll_s1;	 // "__builtin_HEXAGON_M2_mpyd_rnd_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 16 strings to match.
+            if (BuiltinName[25] != '_')
+              break;
+            switch (BuiltinName[26]) {
+            default: break;
+            case 'a':	 // 8 strings to match.
+              if (memcmp(BuiltinName.data()+27, "cc_", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_hh_s0;	 // "__builtin_HEXAGON_M2_mpyu_acc_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_hh_s1;	 // "__builtin_HEXAGON_M2_mpyu_acc_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_hl_s0;	 // "__builtin_HEXAGON_M2_mpyu_acc_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_hl_s1;	 // "__builtin_HEXAGON_M2_mpyu_acc_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_lh_s0;	 // "__builtin_HEXAGON_M2_mpyu_acc_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_lh_s1;	 // "__builtin_HEXAGON_M2_mpyu_acc_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_ll_s0;	 // "__builtin_HEXAGON_M2_mpyu_acc_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_acc_ll_s1;	 // "__builtin_HEXAGON_M2_mpyu_acc_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 8 strings to match.
+              if (memcmp(BuiltinName.data()+27, "ac_", 3))
+                break;
+              switch (BuiltinName[30]) {
+              default: break;
+              case 'h':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_hh_s0;	 // "__builtin_HEXAGON_M2_mpyu_nac_hh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_hh_s1;	 // "__builtin_HEXAGON_M2_mpyu_nac_hh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_hl_s0;	 // "__builtin_HEXAGON_M2_mpyu_nac_hl_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_hl_s1;	 // "__builtin_HEXAGON_M2_mpyu_nac_hl_s1"
+                  }
+                  break;
+                }
+                break;
+              case 'l':	 // 4 strings to match.
+                switch (BuiltinName[31]) {
+                default: break;
+                case 'h':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_lh_s0;	 // "__builtin_HEXAGON_M2_mpyu_nac_lh_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_lh_s1;	 // "__builtin_HEXAGON_M2_mpyu_nac_lh_s1"
+                  }
+                  break;
+                case 'l':	 // 2 strings to match.
+                  if (memcmp(BuiltinName.data()+32, "_s", 2))
+                    break;
+                  switch (BuiltinName[34]) {
+                  default: break;
+                  case '0':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_ll_s0;	 // "__builtin_HEXAGON_M2_mpyu_nac_ll_s0"
+                  case '1':	 // 1 string to match.
+                    return Intrinsic::hexagon_M2_mpyu_nac_ll_s1;	 // "__builtin_HEXAGON_M2_mpyu_nac_ll_s1"
+                  }
+                  break;
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 7 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'c':	 // 6 strings to match.
+            if (BuiltinName[23] != 'm')
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+25, "c_s0_sat_", 9))
+                break;
+              switch (BuiltinName[34]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vcmac_s0_sat_i;	 // "__builtin_HEXAGON_M2_vcmac_s0_sat_i"
+              case 'r':	 // 1 string to match.
+                return Intrinsic::hexagon_M2_vcmac_s0_sat_r;	 // "__builtin_HEXAGON_M2_vcmac_s0_sat_r"
+              }
+              break;
+            case 'p':	 // 4 strings to match.
+              if (memcmp(BuiltinName.data()+25, "y_s", 3))
+                break;
+              switch (BuiltinName[28]) {
+              default: break;
+              case '0':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+29, "_sat_", 5))
+                  break;
+                switch (BuiltinName[34]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmpy_s0_sat_i;	 // "__builtin_HEXAGON_M2_vcmpy_s0_sat_i"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmpy_s0_sat_r;	 // "__builtin_HEXAGON_M2_vcmpy_s0_sat_r"
+                }
+                break;
+              case '1':	 // 2 strings to match.
+                if (memcmp(BuiltinName.data()+29, "_sat_", 5))
+                  break;
+                switch (BuiltinName[34]) {
+                default: break;
+                case 'i':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmpy_s1_sat_i;	 // "__builtin_HEXAGON_M2_vcmpy_s1_sat_i"
+                case 'r':	 // 1 string to match.
+                  return Intrinsic::hexagon_M2_vcmpy_s1_sat_r;	 // "__builtin_HEXAGON_M2_vcmpy_s1_sat_r"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "cmpys_acc_s1", 12))
+              break;
+            return Intrinsic::hexagon_M2_vrcmpys_acc_s1;	 // "__builtin_HEXAGON_M2_vrcmpys_acc_s1"
+          }
+          break;
+        }
+        break;
+      case '4':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+20, "_vrmpy", 6))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'e':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "h_acc_s", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M4_vrmpyeh_acc_s0;	 // "__builtin_HEXAGON_M4_vrmpyeh_acc_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M4_vrmpyeh_acc_s1;	 // "__builtin_HEXAGON_M4_vrmpyeh_acc_s1"
+          }
+          break;
+        case 'o':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "h_acc_s", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M4_vrmpyoh_acc_s0;	 // "__builtin_HEXAGON_M4_vrmpyoh_acc_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M4_vrmpyoh_acc_s1;	 // "__builtin_HEXAGON_M4_vrmpyoh_acc_s1"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'S':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "sr_", 3))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_svw_trun", 9))
+            break;
+          return Intrinsic::hexagon_S2_asr_i_svw_trun;	 // "__builtin_HEXAGON_S2_asr_i_svw_trun"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "_svw_trun", 9))
+            break;
+          return Intrinsic::hexagon_S2_asr_r_svw_trun;	 // "__builtin_HEXAGON_S2_asr_r_svw_trun"
+        }
+        break;
+      case 'v':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "sat", 3))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "ub_nopack", 9))
+            break;
+          return Intrinsic::hexagon_S2_vsathub_nopack;	 // "__builtin_HEXAGON_S2_vsathub_nopack"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+26, "uh_nopack", 9))
+            break;
+          return Intrinsic::hexagon_S2_vsatwuh_nopack;	 // "__builtin_HEXAGON_S2_vsatwuh_nopack"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 36:	 // 33 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'A':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_", 2))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ddh_", 4))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+27, "16_sat_", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            switch (BuiltinName[35]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addh_h16_sat_hh;	 // "__builtin_HEXAGON_A2_addh_h16_sat_hh"
+            case 'l':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addh_h16_sat_hl;	 // "__builtin_HEXAGON_A2_addh_h16_sat_hl"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            switch (BuiltinName[35]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addh_h16_sat_lh;	 // "__builtin_HEXAGON_A2_addh_h16_sat_lh"
+            case 'l':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_addh_h16_sat_ll;	 // "__builtin_HEXAGON_A2_addh_h16_sat_ll"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "16_sat_", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[35] != 'l')
+              break;
+            return Intrinsic::hexagon_A2_addh_l16_sat_hl;	 // "__builtin_HEXAGON_A2_addh_l16_sat_hl"
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[35] != 'l')
+              break;
+            return Intrinsic::hexagon_A2_addh_l16_sat_ll;	 // "__builtin_HEXAGON_A2_addh_l16_sat_ll"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+22, "ubh_", 4))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+27, "16_sat_", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            switch (BuiltinName[35]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_subh_h16_sat_hh;	 // "__builtin_HEXAGON_A2_subh_h16_sat_hh"
+            case 'l':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_subh_h16_sat_hl;	 // "__builtin_HEXAGON_A2_subh_h16_sat_hl"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            switch (BuiltinName[35]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_subh_h16_sat_lh;	 // "__builtin_HEXAGON_A2_subh_h16_sat_lh"
+            case 'l':	 // 1 string to match.
+              return Intrinsic::hexagon_A2_subh_h16_sat_ll;	 // "__builtin_HEXAGON_A2_subh_h16_sat_ll"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "16_sat_", 7))
+            break;
+          switch (BuiltinName[34]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[35] != 'l')
+              break;
+            return Intrinsic::hexagon_A2_subh_l16_sat_hl;	 // "__builtin_HEXAGON_A2_subh_l16_sat_hl"
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[35] != 'l')
+              break;
+            return Intrinsic::hexagon_A2_subh_l16_sat_ll;	 // "__builtin_HEXAGON_A2_subh_l16_sat_ll"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'C':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "4_fastcorner9_not", 17))
+        break;
+      return Intrinsic::hexagon_C4_fastcorner9_not;	 // "__builtin_HEXAGON_C4_fastcorner9_not"
+    case 'F':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_conv_", 7))
+        break;
+      switch (BuiltinName[26]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2u", 3))
+          break;
+        switch (BuiltinName[30]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+31, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_df2ud_chop;	 // "__builtin_HEXAGON_F2_conv_df2ud_chop"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+31, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_df2uw_chop;	 // "__builtin_HEXAGON_F2_conv_df2uw_chop"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+27, "f2u", 3))
+          break;
+        switch (BuiltinName[30]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+31, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_sf2ud_chop;	 // "__builtin_HEXAGON_F2_conv_sf2ud_chop"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+31, "_chop", 5))
+            break;
+          return Intrinsic::hexagon_F2_conv_sf2uw_chop;	 // "__builtin_HEXAGON_F2_conv_sf2uw_chop"
+        }
+        break;
+      }
+      break;
+    case 'M':	 // 16 strings to match.
+      if (memcmp(BuiltinName.data()+19, "2_mpyud_", 8))
+        break;
+      switch (BuiltinName[27]) {
+      default: break;
+      case 'a':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+28, "cc_", 3))
+          break;
+        switch (BuiltinName[31]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (BuiltinName[32]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_hh_s0;	 // "__builtin_HEXAGON_M2_mpyud_acc_hh_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_hh_s1;	 // "__builtin_HEXAGON_M2_mpyud_acc_hh_s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_hl_s0;	 // "__builtin_HEXAGON_M2_mpyud_acc_hl_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_hl_s1;	 // "__builtin_HEXAGON_M2_mpyud_acc_hl_s1"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 4 strings to match.
+          switch (BuiltinName[32]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_lh_s0;	 // "__builtin_HEXAGON_M2_mpyud_acc_lh_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_lh_s1;	 // "__builtin_HEXAGON_M2_mpyud_acc_lh_s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_ll_s0;	 // "__builtin_HEXAGON_M2_mpyud_acc_ll_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_acc_ll_s1;	 // "__builtin_HEXAGON_M2_mpyud_acc_ll_s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+28, "ac_", 3))
+          break;
+        switch (BuiltinName[31]) {
+        default: break;
+        case 'h':	 // 4 strings to match.
+          switch (BuiltinName[32]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_hh_s0;	 // "__builtin_HEXAGON_M2_mpyud_nac_hh_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_hh_s1;	 // "__builtin_HEXAGON_M2_mpyud_nac_hh_s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_hl_s0;	 // "__builtin_HEXAGON_M2_mpyud_nac_hl_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_hl_s1;	 // "__builtin_HEXAGON_M2_mpyud_nac_hl_s1"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 4 strings to match.
+          switch (BuiltinName[32]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_lh_s0;	 // "__builtin_HEXAGON_M2_mpyud_nac_lh_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_lh_s1;	 // "__builtin_HEXAGON_M2_mpyud_nac_lh_s1"
+            }
+            break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+33, "_s", 2))
+              break;
+            switch (BuiltinName[35]) {
+            default: break;
+            case '0':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_ll_s0;	 // "__builtin_HEXAGON_M2_mpyud_nac_ll_s0"
+            case '1':	 // 1 string to match.
+              return Intrinsic::hexagon_M2_mpyud_nac_ll_s1;	 // "__builtin_HEXAGON_M2_mpyud_nac_ll_s1"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 38:	 // 24 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_M2_mpy_", 25))
+      break;
+    switch (BuiltinName[25]) {
+    default: break;
+    case 'a':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+26, "cc_sat_", 7))
+        break;
+      switch (BuiltinName[33]) {
+      default: break;
+      case 'h':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_acc_sat_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+26, "ac_sat_", 7))
+        break;
+      switch (BuiltinName[33]) {
+      default: break;
+      case 'h':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_nac_sat_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+26, "at_rnd_", 7))
+        break;
+      switch (BuiltinName[33]) {
+      default: break;
+      case 'h':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_hh_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_hh_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_hl_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_hl_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        switch (BuiltinName[34]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_lh_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_lh_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+35, "_s", 2))
+            break;
+          switch (BuiltinName[37]) {
+          default: break;
+          case '0':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_ll_s0;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0"
+          case '1':	 // 1 string to match.
+            return Intrinsic::hexagon_M2_mpy_sat_rnd_ll_s1;	 // "__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 40:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_S5_vasrhrnd_goodsyntax", 40))
+      break;
+    return Intrinsic::hexagon_S5_vasrhrnd_goodsyntax;	 // "__builtin_HEXAGON_S5_vasrhrnd_goodsyntax"
+  case 41:	 // 4 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_S2_tableidx", 29))
+      break;
+    switch (BuiltinName[29]) {
+    default: break;
+    case 'b':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+30, "_goodsyntax", 11))
+        break;
+      return Intrinsic::hexagon_S2_tableidxb_goodsyntax;	 // "__builtin_HEXAGON_S2_tableidxb_goodsyntax"
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+30, "_goodsyntax", 11))
+        break;
+      return Intrinsic::hexagon_S2_tableidxd_goodsyntax;	 // "__builtin_HEXAGON_S2_tableidxd_goodsyntax"
+    case 'h':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+30, "_goodsyntax", 11))
+        break;
+      return Intrinsic::hexagon_S2_tableidxh_goodsyntax;	 // "__builtin_HEXAGON_S2_tableidxh_goodsyntax"
+    case 'w':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+30, "_goodsyntax", 11))
+        break;
+      return Intrinsic::hexagon_S2_tableidxw_goodsyntax;	 // "__builtin_HEXAGON_S2_tableidxw_goodsyntax"
+    }
+    break;
+  case 43:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_S2_asr_i_", 27))
+      break;
+    switch (BuiltinName[27]) {
+    default: break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+28, "_rnd_goodsyntax", 15))
+        break;
+      return Intrinsic::hexagon_S2_asr_i_p_rnd_goodsyntax;	 // "__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax"
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+28, "_rnd_goodsyntax", 15))
+        break;
+      return Intrinsic::hexagon_S2_asr_i_r_rnd_goodsyntax;	 // "__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax"
+    }
+    break;
+  case 46:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax", 46))
+      break;
+    return Intrinsic::hexagon_S5_asrhub_rnd_sat_goodsyntax;	 // "__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax"
+  }
+  }
+  if (TargetPrefix == "mips") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 18:	 // 17 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_l", 4))
+        break;
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (BuiltinName[17] != 'x')
+          break;
+        return Intrinsic::mips_lhx;	 // "__builtin_mips_lhx"
+      case 's':	 // 1 string to match.
+        if (BuiltinName[17] != 'a')
+          break;
+        return Intrinsic::mips_lsa;	 // "__builtin_mips_lsa"
+      case 'w':	 // 1 string to match.
+        if (BuiltinName[17] != 'x')
+          break;
+        return Intrinsic::mips_lwx;	 // "__builtin_mips_lwx"
+      }
+      break;
+    case 's':	 // 14 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'b':	 // 5 strings to match.
+        if (memcmp(BuiltinName.data()+15, "z_", 2))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_bz_b;	 // "__builtin_msa_bz_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_bz_d;	 // "__builtin_msa_bz_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_bz_h;	 // "__builtin_msa_bz_h"
+        case 'v':	 // 1 string to match.
+          return Intrinsic::mips_bz_v;	 // "__builtin_msa_bz_v"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_bz_w;	 // "__builtin_msa_bz_w"
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "d_", 2))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_ld_b;	 // "__builtin_msa_ld_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_ld_d;	 // "__builtin_msa_ld_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ld_h;	 // "__builtin_msa_ld_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ld_w;	 // "__builtin_msa_ld_w"
+        }
+        break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "r_v", 3))
+          break;
+        return Intrinsic::mips_or_v;	 // "__builtin_msa_or_v"
+      case 's':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "t_", 2))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_st_b;	 // "__builtin_msa_st_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_st_d;	 // "__builtin_msa_st_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_st_h;	 // "__builtin_msa_st_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_st_w;	 // "__builtin_msa_st_w"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 19:	 // 46 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 7 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "lsa", 3))
+          break;
+        return Intrinsic::mips_dlsa;	 // "__builtin_mips_dlsa"
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "xtp", 3))
+          break;
+        return Intrinsic::mips_extp;	 // "__builtin_mips_extp"
+      case 'i':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "nsv", 3))
+          break;
+        return Intrinsic::mips_insv;	 // "__builtin_mips_insv"
+      case 'l':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "bux", 3))
+          break;
+        return Intrinsic::mips_lbux;	 // "__builtin_mips_lbux"
+      case 'm':	 // 3 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "dd", 2))
+            break;
+          return Intrinsic::mips_madd;	 // "__builtin_mips_madd"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "ub", 2))
+            break;
+          return Intrinsic::mips_msub;	 // "__builtin_mips_msub"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "lt", 2))
+            break;
+          return Intrinsic::mips_mult;	 // "__builtin_mips_mult"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 39 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "nd_v", 4))
+          break;
+        return Intrinsic::mips_and_v;	 // "__builtin_msa_and_v"
+      case 'b':	 // 6 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "z_v", 3))
+            break;
+          return Intrinsic::mips_bmz_v;	 // "__builtin_msa_bmz_v"
+        case 'n':	 // 5 strings to match.
+          if (memcmp(BuiltinName.data()+16, "z_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bnz_b;	 // "__builtin_msa_bnz_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bnz_d;	 // "__builtin_msa_bnz_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bnz_h;	 // "__builtin_msa_bnz_h"
+          case 'v':	 // 1 string to match.
+            return Intrinsic::mips_bnz_v;	 // "__builtin_msa_bnz_v"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bnz_w;	 // "__builtin_msa_bnz_w"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "eq_", 3))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_ceq_b;	 // "__builtin_msa_ceq_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_ceq_d;	 // "__builtin_msa_ceq_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ceq_h;	 // "__builtin_msa_ceq_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ceq_w;	 // "__builtin_msa_ceq_w"
+        }
+        break;
+      case 'f':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+15, "tq_", 3))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ftq_h;	 // "__builtin_msa_ftq_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ftq_w;	 // "__builtin_msa_ftq_w"
+        }
+        break;
+      case 'l':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "di_", 3))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_ldi_b;	 // "__builtin_msa_ldi_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_ldi_d;	 // "__builtin_msa_ldi_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_ldi_h;	 // "__builtin_msa_ldi_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_ldi_w;	 // "__builtin_msa_ldi_w"
+        }
+        break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "or_v", 4))
+          break;
+        return Intrinsic::mips_nor_v;	 // "__builtin_msa_nor_v"
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "ri_b", 4))
+          break;
+        return Intrinsic::mips_ori_b;	 // "__builtin_msa_ori_b"
+      case 's':	 // 19 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'h':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+16, "f_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_shf_b;	 // "__builtin_msa_shf_b"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_shf_h;	 // "__builtin_msa_shf_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_shf_w;	 // "__builtin_msa_shf_w"
+          }
+          break;
+        case 'l':	 // 8 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (BuiltinName[17] != '_')
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sld_b;	 // "__builtin_msa_sld_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sld_d;	 // "__builtin_msa_sld_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sld_h;	 // "__builtin_msa_sld_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sld_w;	 // "__builtin_msa_sld_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[17] != '_')
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sll_b;	 // "__builtin_msa_sll_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sll_d;	 // "__builtin_msa_sll_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sll_h;	 // "__builtin_msa_sll_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sll_w;	 // "__builtin_msa_sll_w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 8 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (BuiltinName[17] != '_')
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sra_b;	 // "__builtin_msa_sra_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sra_d;	 // "__builtin_msa_sra_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sra_h;	 // "__builtin_msa_sra_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sra_w;	 // "__builtin_msa_sra_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[17] != '_')
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srl_b;	 // "__builtin_msa_srl_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srl_d;	 // "__builtin_msa_srl_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srl_h;	 // "__builtin_msa_srl_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srl_w;	 // "__builtin_msa_srl_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "or_v", 4))
+          break;
+        return Intrinsic::mips_xor_v;	 // "__builtin_msa_xor_v"
+      }
+      break;
+    }
+    break;
+  case 20:	 // 143 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "dd", 2))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (BuiltinName[19] != 'c')
+            break;
+          return Intrinsic::mips_addsc;	 // "__builtin_mips_addsc"
+        case 'w':	 // 1 string to match.
+          if (BuiltinName[19] != 'c')
+            break;
+          return Intrinsic::mips_addwc;	 // "__builtin_mips_addwc"
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "ddu", 3))
+            break;
+          return Intrinsic::mips_maddu;	 // "__builtin_mips_maddu"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "ubu", 3))
+            break;
+          return Intrinsic::mips_msubu;	 // "__builtin_mips_msubu"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "ltu", 3))
+            break;
+          return Intrinsic::mips_multu;	 // "__builtin_mips_multu"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "ddsp", 4))
+          break;
+        return Intrinsic::mips_rddsp;	 // "__builtin_mips_rddsp"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "hilo", 4))
+          break;
+        return Intrinsic::mips_shilo;	 // "__builtin_mips_shilo"
+      case 'w':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "rdsp", 4))
+          break;
+        return Intrinsic::mips_wrdsp;	 // "__builtin_mips_wrdsp"
+      }
+      break;
+    case 's':	 // 135 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'a':	 // 5 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'd':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "dv_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_addv_b;	 // "__builtin_msa_addv_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_addv_d;	 // "__builtin_msa_addv_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_addv_h;	 // "__builtin_msa_addv_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_addv_w;	 // "__builtin_msa_addv_w"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "di_b", 4))
+            break;
+          return Intrinsic::mips_andi_b;	 // "__builtin_msa_andi_b"
+        }
+        break;
+      case 'b':	 // 15 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'c':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lr_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bclr_b;	 // "__builtin_msa_bclr_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bclr_d;	 // "__builtin_msa_bclr_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bclr_h;	 // "__builtin_msa_bclr_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bclr_w;	 // "__builtin_msa_bclr_w"
+          }
+          break;
+        case 'm':	 // 2 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'n':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+17, "z_v", 3))
+              break;
+            return Intrinsic::mips_bmnz_v;	 // "__builtin_msa_bmnz_v"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+17, "i_b", 3))
+              break;
+            return Intrinsic::mips_bmzi_b;	 // "__builtin_msa_bmzi_b"
+          }
+          break;
+        case 'n':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "eg_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bneg_b;	 // "__builtin_msa_bneg_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bneg_d;	 // "__builtin_msa_bneg_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bneg_h;	 // "__builtin_msa_bneg_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bneg_w;	 // "__builtin_msa_bneg_w"
+          }
+          break;
+        case 's':	 // 5 strings to match.
+          if (BuiltinName[16] != 'e')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+18, "_v", 2))
+              break;
+            return Intrinsic::mips_bsel_v;	 // "__builtin_msa_bsel_v"
+          case 't':	 // 4 strings to match.
+            if (BuiltinName[18] != '_')
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_bset_b;	 // "__builtin_msa_bset_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_bset_d;	 // "__builtin_msa_bset_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_bset_h;	 // "__builtin_msa_bset_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_bset_w;	 // "__builtin_msa_bset_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 6 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "qi_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_b;	 // "__builtin_msa_ceqi_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_d;	 // "__builtin_msa_ceqi_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_h;	 // "__builtin_msa_ceqi_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ceqi_w;	 // "__builtin_msa_ceqi_w"
+          }
+          break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "cmsa", 4))
+            break;
+          return Intrinsic::mips_cfcmsa;	 // "__builtin_msa_cfcmsa"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "cmsa", 4))
+            break;
+          return Intrinsic::mips_ctcmsa;	 // "__builtin_msa_ctcmsa"
+        }
+        break;
+      case 'f':	 // 50 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "dd_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fadd_d;	 // "__builtin_msa_fadd_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fadd_w;	 // "__builtin_msa_fadd_w"
+          }
+          break;
+        case 'c':	 // 14 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "f_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcaf_d;	 // "__builtin_msa_fcaf_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcaf_w;	 // "__builtin_msa_fcaf_w"
+            }
+            break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "q_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fceq_d;	 // "__builtin_msa_fceq_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fceq_w;	 // "__builtin_msa_fceq_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcle_d;	 // "__builtin_msa_fcle_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcle_w;	 // "__builtin_msa_fcle_w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fclt_d;	 // "__builtin_msa_fclt_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fclt_w;	 // "__builtin_msa_fclt_w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "e_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcne_d;	 // "__builtin_msa_fcne_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcne_w;	 // "__builtin_msa_fcne_w"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "r_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcor_d;	 // "__builtin_msa_fcor_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcor_w;	 // "__builtin_msa_fcor_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "n_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcun_d;	 // "__builtin_msa_fcun_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcun_w;	 // "__builtin_msa_fcun_w"
+            }
+            break;
+          }
+          break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "iv_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fdiv_d;	 // "__builtin_msa_fdiv_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fdiv_w;	 // "__builtin_msa_fdiv_w"
+          }
+          break;
+        case 'f':	 // 4 strings to match.
+          if (BuiltinName[16] != 'q')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (BuiltinName[18] != '_')
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffql_d;	 // "__builtin_msa_ffql_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffql_w;	 // "__builtin_msa_ffql_w"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (BuiltinName[18] != '_')
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffqr_d;	 // "__builtin_msa_ffqr_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffqr_w;	 // "__builtin_msa_ffqr_w"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ll_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_fill_b;	 // "__builtin_msa_fill_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fill_d;	 // "__builtin_msa_fill_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_fill_h;	 // "__builtin_msa_fill_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fill_w;	 // "__builtin_msa_fill_w"
+          }
+          break;
+        case 'm':	 // 6 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "x_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmax_d;	 // "__builtin_msa_fmax_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmax_w;	 // "__builtin_msa_fmax_w"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "n_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmin_d;	 // "__builtin_msa_fmin_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmin_w;	 // "__builtin_msa_fmin_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "l_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmul_d;	 // "__builtin_msa_fmul_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmul_w;	 // "__builtin_msa_fmul_w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "cp_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frcp_d;	 // "__builtin_msa_frcp_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frcp_w;	 // "__builtin_msa_frcp_w"
+          }
+          break;
+        case 's':	 // 16 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "f_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsaf_d;	 // "__builtin_msa_fsaf_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsaf_w;	 // "__builtin_msa_fsaf_w"
+            }
+            break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "q_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fseq_d;	 // "__builtin_msa_fseq_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fseq_w;	 // "__builtin_msa_fseq_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsle_d;	 // "__builtin_msa_fsle_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsle_w;	 // "__builtin_msa_fsle_w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fslt_d;	 // "__builtin_msa_fslt_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fslt_w;	 // "__builtin_msa_fslt_w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "e_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsne_d;	 // "__builtin_msa_fsne_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsne_w;	 // "__builtin_msa_fsne_w"
+            }
+            break;
+          case 'o':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "r_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsor_d;	 // "__builtin_msa_fsor_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsor_w;	 // "__builtin_msa_fsor_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsub_d;	 // "__builtin_msa_fsub_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsub_w;	 // "__builtin_msa_fsub_w"
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsun_d;	 // "__builtin_msa_fsun_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsun_w;	 // "__builtin_msa_fsun_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+15, "lv", 2))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (BuiltinName[18] != '_')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_b;	 // "__builtin_msa_ilvl_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_d;	 // "__builtin_msa_ilvl_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_h;	 // "__builtin_msa_ilvl_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ilvl_w;	 // "__builtin_msa_ilvl_w"
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          if (BuiltinName[18] != '_')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_b;	 // "__builtin_msa_ilvr_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_d;	 // "__builtin_msa_ilvr_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_h;	 // "__builtin_msa_ilvr_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ilvr_w;	 // "__builtin_msa_ilvr_w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 5 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "ve_v", 4))
+            break;
+          return Intrinsic::mips_move_v;	 // "__builtin_msa_move_v"
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lv_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_mulv_b;	 // "__builtin_msa_mulv_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_mulv_d;	 // "__builtin_msa_mulv_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_mulv_h;	 // "__builtin_msa_mulv_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_mulv_w;	 // "__builtin_msa_mulv_w"
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 9 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'o':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "c_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_nloc_b;	 // "__builtin_msa_nloc_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_nloc_d;	 // "__builtin_msa_nloc_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_nloc_h;	 // "__builtin_msa_nloc_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_nloc_w;	 // "__builtin_msa_nloc_w"
+            }
+            break;
+          case 'z':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "c_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_b;	 // "__builtin_msa_nlzc_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_d;	 // "__builtin_msa_nlzc_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_h;	 // "__builtin_msa_nlzc_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_nlzc_w;	 // "__builtin_msa_nlzc_w"
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "ri_b", 4))
+            break;
+          return Intrinsic::mips_nori_b;	 // "__builtin_msa_nori_b"
+        }
+        break;
+      case 'p':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "cnt_", 4))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_b;	 // "__builtin_msa_pcnt_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_d;	 // "__builtin_msa_pcnt_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_h;	 // "__builtin_msa_pcnt_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_pcnt_w;	 // "__builtin_msa_pcnt_w"
+        }
+        break;
+      case 's':	 // 28 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "i_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sldi_b;	 // "__builtin_msa_sldi_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sldi_d;	 // "__builtin_msa_sldi_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sldi_h;	 // "__builtin_msa_sldi_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sldi_w;	 // "__builtin_msa_sldi_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "i_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_slli_b;	 // "__builtin_msa_slli_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_slli_d;	 // "__builtin_msa_slli_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_slli_h;	 // "__builtin_msa_slli_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_slli_w;	 // "__builtin_msa_slli_w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 16 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 8 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'i':	 // 4 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srai_b;	 // "__builtin_msa_srai_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srai_d;	 // "__builtin_msa_srai_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srai_h;	 // "__builtin_msa_srai_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srai_w;	 // "__builtin_msa_srai_w"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srar_b;	 // "__builtin_msa_srar_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srar_d;	 // "__builtin_msa_srar_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srar_h;	 // "__builtin_msa_srar_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srar_w;	 // "__builtin_msa_srar_w"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 8 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'i':	 // 4 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srli_b;	 // "__builtin_msa_srli_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srli_d;	 // "__builtin_msa_srli_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srli_h;	 // "__builtin_msa_srli_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srli_w;	 // "__builtin_msa_srli_w"
+              }
+              break;
+            case 'r':	 // 4 strings to match.
+              if (BuiltinName[18] != '_')
+                break;
+              switch (BuiltinName[19]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_srlr_b;	 // "__builtin_msa_srlr_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_srlr_d;	 // "__builtin_msa_srlr_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_srlr_h;	 // "__builtin_msa_srlr_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_srlr_w;	 // "__builtin_msa_srlr_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "bv_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_subv_b;	 // "__builtin_msa_subv_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_subv_d;	 // "__builtin_msa_subv_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_subv_h;	 // "__builtin_msa_subv_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_subv_w;	 // "__builtin_msa_subv_w"
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "shf_", 4))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_vshf_b;	 // "__builtin_msa_vshf_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_vshf_d;	 // "__builtin_msa_vshf_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_vshf_h;	 // "__builtin_msa_vshf_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_vshf_w;	 // "__builtin_msa_vshf_w"
+        }
+        break;
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+15, "ori_b", 5))
+          break;
+        return Intrinsic::mips_xori_b;	 // "__builtin_msa_xori_b"
+      }
+      break;
+    }
+    break;
+  case 21:	 // 186 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "ppend", 5))
+          break;
+        return Intrinsic::mips_append;	 // "__builtin_mips_append"
+      case 'b':	 // 2 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "lign", 4))
+            break;
+          return Intrinsic::mips_balign;	 // "__builtin_mips_balign"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "trev", 4))
+            break;
+          return Intrinsic::mips_bitrev;	 // "__builtin_mips_bitrev"
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "xt", 2))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "dp", 2))
+            break;
+          return Intrinsic::mips_extpdp;	 // "__builtin_mips_extpdp"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "_w", 2))
+            break;
+          return Intrinsic::mips_extr_w;	 // "__builtin_mips_extr_w"
+        }
+        break;
+      case 'm':	 // 3 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "dsub", 4))
+            break;
+          return Intrinsic::mips_modsub;	 // "__builtin_mips_modsub"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "hlip", 4))
+            break;
+          return Intrinsic::mips_mthlip;	 // "__builtin_mips_mthlip"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "l_ph", 4))
+            break;
+          return Intrinsic::mips_mul_ph;	 // "__builtin_mips_mul_ph"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 178 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'a':	 // 16 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'd':	 // 8 strings to match.
+          if (BuiltinName[16] != 'd')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case '_':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "a_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_add_a_b;	 // "__builtin_msa_add_a_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_add_a_d;	 // "__builtin_msa_add_a_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_add_a_h;	 // "__builtin_msa_add_a_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_add_a_w;	 // "__builtin_msa_add_a_w"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "i_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_addvi_b;	 // "__builtin_msa_addvi_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_addvi_d;	 // "__builtin_msa_addvi_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_addvi_h;	 // "__builtin_msa_addvi_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_addvi_w;	 // "__builtin_msa_addvi_w"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "e_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_b;	 // "__builtin_msa_ave_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_d;	 // "__builtin_msa_ave_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_h;	 // "__builtin_msa_ave_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ave_s_w;	 // "__builtin_msa_ave_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_b;	 // "__builtin_msa_ave_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_d;	 // "__builtin_msa_ave_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_h;	 // "__builtin_msa_ave_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ave_u_w;	 // "__builtin_msa_ave_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 22 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'c':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lri_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bclri_b;	 // "__builtin_msa_bclri_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bclri_d;	 // "__builtin_msa_bclri_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bclri_h;	 // "__builtin_msa_bclri_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bclri_w;	 // "__builtin_msa_bclri_w"
+          }
+          break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ns", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'l':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsl_b;	 // "__builtin_msa_binsl_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsl_d;	 // "__builtin_msa_binsl_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsl_h;	 // "__builtin_msa_binsl_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsl_w;	 // "__builtin_msa_binsl_w"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_binsr_b;	 // "__builtin_msa_binsr_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_binsr_d;	 // "__builtin_msa_binsr_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_binsr_h;	 // "__builtin_msa_binsr_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_binsr_w;	 // "__builtin_msa_binsr_w"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+16, "nzi_b", 5))
+            break;
+          return Intrinsic::mips_bmnzi_b;	 // "__builtin_msa_bmnzi_b"
+        case 'n':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "egi_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_b;	 // "__builtin_msa_bnegi_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_d;	 // "__builtin_msa_bnegi_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_h;	 // "__builtin_msa_bnegi_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_bnegi_w;	 // "__builtin_msa_bnegi_w"
+          }
+          break;
+        case 's':	 // 5 strings to match.
+          if (BuiltinName[16] != 'e')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+18, "i_b", 3))
+              break;
+            return Intrinsic::mips_bseli_b;	 // "__builtin_msa_bseli_b"
+          case 't':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "i_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_bseti_b;	 // "__builtin_msa_bseti_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_bseti_d;	 // "__builtin_msa_bseti_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_bseti_h;	 // "__builtin_msa_bseti_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_bseti_w;	 // "__builtin_msa_bseti_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 16 strings to match.
+        if (BuiltinName[15] != 'l')
+          break;
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'e':	 // 8 strings to match.
+          if (BuiltinName[17] != '_')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_b;	 // "__builtin_msa_cle_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_d;	 // "__builtin_msa_cle_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_h;	 // "__builtin_msa_cle_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_cle_s_w;	 // "__builtin_msa_cle_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_b;	 // "__builtin_msa_cle_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_d;	 // "__builtin_msa_cle_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_h;	 // "__builtin_msa_cle_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_cle_u_w;	 // "__builtin_msa_cle_u_w"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 8 strings to match.
+          if (BuiltinName[17] != '_')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_b;	 // "__builtin_msa_clt_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_d;	 // "__builtin_msa_clt_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_h;	 // "__builtin_msa_clt_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_clt_s_w;	 // "__builtin_msa_clt_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_b;	 // "__builtin_msa_clt_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_d;	 // "__builtin_msa_clt_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_h;	 // "__builtin_msa_clt_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_clt_u_w;	 // "__builtin_msa_clt_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+15, "iv_", 3))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          if (BuiltinName[19] != '_')
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_div_s_b;	 // "__builtin_msa_div_s_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_div_s_d;	 // "__builtin_msa_div_s_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_div_s_h;	 // "__builtin_msa_div_s_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_div_s_w;	 // "__builtin_msa_div_s_w"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[19] != '_')
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_div_u_b;	 // "__builtin_msa_div_u_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_div_u_d;	 // "__builtin_msa_div_u_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_div_u_h;	 // "__builtin_msa_div_u_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_div_u_w;	 // "__builtin_msa_div_u_w"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 30 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'c':	 // 8 strings to match.
+          if (BuiltinName[16] != 'u')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "q_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcueq_d;	 // "__builtin_msa_fcueq_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcueq_w;	 // "__builtin_msa_fcueq_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcule_d;	 // "__builtin_msa_fcule_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcule_w;	 // "__builtin_msa_fcule_w"
+              }
+              break;
+            case 't':	 // 2 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fcult_d;	 // "__builtin_msa_fcult_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fcult_w;	 // "__builtin_msa_fcult_w"
+              }
+              break;
+            }
+            break;
+          case 'n':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "e_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fcune_d;	 // "__builtin_msa_fcune_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fcune_w;	 // "__builtin_msa_fcune_w"
+            }
+            break;
+          }
+          break;
+        case 'e':	 // 4 strings to match.
+          if (BuiltinName[16] != 'x')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "o_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_fexdo_h;	 // "__builtin_msa_fexdo_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexdo_w;	 // "__builtin_msa_fexdo_w"
+            }
+            break;
+          case 'p':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "2_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexp2_d;	 // "__builtin_msa_fexp2_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexp2_w;	 // "__builtin_msa_fexp2_w"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "og2_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_flog2_d;	 // "__builtin_msa_flog2_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_flog2_w;	 // "__builtin_msa_flog2_w"
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "dd_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmadd_d;	 // "__builtin_msa_fmadd_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmadd_w;	 // "__builtin_msa_fmadd_w"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "ub_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmsub_d;	 // "__builtin_msa_fmsub_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmsub_w;	 // "__builtin_msa_fmsub_w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "int_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frint_d;	 // "__builtin_msa_frint_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frint_w;	 // "__builtin_msa_frint_w"
+          }
+          break;
+        case 's':	 // 10 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "rt_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fsqrt_d;	 // "__builtin_msa_fsqrt_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fsqrt_w;	 // "__builtin_msa_fsqrt_w"
+            }
+            break;
+          case 'u':	 // 8 strings to match.
+            switch (BuiltinName[17]) {
+            default: break;
+            case 'e':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+18, "q_", 2))
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsueq_d;	 // "__builtin_msa_fsueq_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsueq_w;	 // "__builtin_msa_fsueq_w"
+              }
+              break;
+            case 'l':	 // 4 strings to match.
+              switch (BuiltinName[18]) {
+              default: break;
+              case 'e':	 // 2 strings to match.
+                if (BuiltinName[19] != '_')
+                  break;
+                switch (BuiltinName[20]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::mips_fsule_d;	 // "__builtin_msa_fsule_d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::mips_fsule_w;	 // "__builtin_msa_fsule_w"
+                }
+                break;
+              case 't':	 // 2 strings to match.
+                if (BuiltinName[19] != '_')
+                  break;
+                switch (BuiltinName[20]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  return Intrinsic::mips_fsult_d;	 // "__builtin_msa_fsult_d"
+                case 'w':	 // 1 string to match.
+                  return Intrinsic::mips_fsult_w;	 // "__builtin_msa_fsult_w"
+                }
+                break;
+              }
+              break;
+            case 'n':	 // 2 strings to match.
+              if (memcmp(BuiltinName.data()+18, "e_", 2))
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_fsune_d;	 // "__builtin_msa_fsune_d"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_fsune_w;	 // "__builtin_msa_fsune_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 12 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'l':	 // 8 strings to match.
+          if (BuiltinName[16] != 'v')
+            break;
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'e':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "v_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_b;	 // "__builtin_msa_ilvev_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_d;	 // "__builtin_msa_ilvev_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_h;	 // "__builtin_msa_ilvev_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ilvev_w;	 // "__builtin_msa_ilvev_w"
+            }
+            break;
+          case 'o':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+18, "d_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_b;	 // "__builtin_msa_ilvod_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_d;	 // "__builtin_msa_ilvod_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_h;	 // "__builtin_msa_ilvod_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ilvod_w;	 // "__builtin_msa_ilvod_w"
+            }
+            break;
+          }
+          break;
+        case 'n':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "sve_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_insve_b;	 // "__builtin_msa_insve_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_insve_d;	 // "__builtin_msa_insve_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_insve_h;	 // "__builtin_msa_insve_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_insve_w;	 // "__builtin_msa_insve_w"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 42 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 16 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'd':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "dv_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_maddv_b;	 // "__builtin_msa_maddv_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_maddv_d;	 // "__builtin_msa_maddv_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_maddv_h;	 // "__builtin_msa_maddv_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_maddv_w;	 // "__builtin_msa_maddv_w"
+            }
+            break;
+          case 'x':	 // 12 strings to match.
+            if (BuiltinName[17] != '_')
+              break;
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'a':	 // 4 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_a_b;	 // "__builtin_msa_max_a_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_a_d;	 // "__builtin_msa_max_a_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_a_h;	 // "__builtin_msa_max_a_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_a_w;	 // "__builtin_msa_max_a_w"
+              }
+              break;
+            case 's':	 // 4 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_s_b;	 // "__builtin_msa_max_s_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_s_d;	 // "__builtin_msa_max_s_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_s_h;	 // "__builtin_msa_max_s_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_s_w;	 // "__builtin_msa_max_s_w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_max_u_b;	 // "__builtin_msa_max_u_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_max_u_d;	 // "__builtin_msa_max_u_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_max_u_h;	 // "__builtin_msa_max_u_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_max_u_w;	 // "__builtin_msa_max_u_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 12 strings to match.
+          if (memcmp(BuiltinName.data()+16, "n_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_a_b;	 // "__builtin_msa_min_a_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_a_d;	 // "__builtin_msa_min_a_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_a_h;	 // "__builtin_msa_min_a_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_a_w;	 // "__builtin_msa_min_a_w"
+            }
+            break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_s_b;	 // "__builtin_msa_min_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_s_d;	 // "__builtin_msa_min_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_s_h;	 // "__builtin_msa_min_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_s_w;	 // "__builtin_msa_min_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_min_u_b;	 // "__builtin_msa_min_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_min_u_d;	 // "__builtin_msa_min_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_min_u_h;	 // "__builtin_msa_min_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_min_u_w;	 // "__builtin_msa_min_u_w"
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "d_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_b;	 // "__builtin_msa_mod_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_d;	 // "__builtin_msa_mod_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_h;	 // "__builtin_msa_mod_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mod_s_w;	 // "__builtin_msa_mod_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_b;	 // "__builtin_msa_mod_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_d;	 // "__builtin_msa_mod_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_h;	 // "__builtin_msa_mod_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mod_u_w;	 // "__builtin_msa_mod_u_w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ubv_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_msubv_b;	 // "__builtin_msa_msubv_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_msubv_d;	 // "__builtin_msa_msubv_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msubv_h;	 // "__builtin_msa_msubv_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msubv_w;	 // "__builtin_msa_msubv_w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "l_q_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_mul_q_h;	 // "__builtin_msa_mul_q_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_mul_q_w;	 // "__builtin_msa_mul_q_w"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+15, "ck", 2))
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "v_", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_pckev_b;	 // "__builtin_msa_pckev_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_pckev_d;	 // "__builtin_msa_pckev_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_pckev_h;	 // "__builtin_msa_pckev_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_pckev_w;	 // "__builtin_msa_pckev_w"
+          }
+          break;
+        case 'o':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "d_", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_pckod_b;	 // "__builtin_msa_pckod_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_pckod_d;	 // "__builtin_msa_pckod_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_pckod_h;	 // "__builtin_msa_pckod_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_pckod_w;	 // "__builtin_msa_pckod_w"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 24 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "t_", 2))
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_b;	 // "__builtin_msa_sat_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_d;	 // "__builtin_msa_sat_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_h;	 // "__builtin_msa_sat_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sat_s_w;	 // "__builtin_msa_sat_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_b;	 // "__builtin_msa_sat_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_d;	 // "__builtin_msa_sat_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_h;	 // "__builtin_msa_sat_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_sat_u_w;	 // "__builtin_msa_sat_u_w"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lat_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_splat_b;	 // "__builtin_msa_splat_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_splat_d;	 // "__builtin_msa_splat_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_splat_h;	 // "__builtin_msa_splat_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_splat_w;	 // "__builtin_msa_splat_w"
+          }
+          break;
+        case 'r':	 // 8 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "ri_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srari_b;	 // "__builtin_msa_srari_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srari_d;	 // "__builtin_msa_srari_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srari_h;	 // "__builtin_msa_srari_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srari_w;	 // "__builtin_msa_srari_w"
+            }
+            break;
+          case 'l':	 // 4 strings to match.
+            if (memcmp(BuiltinName.data()+17, "ri_", 3))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_srlri_b;	 // "__builtin_msa_srlri_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_srlri_d;	 // "__builtin_msa_srlri_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_srlri_h;	 // "__builtin_msa_srlri_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_srlri_w;	 // "__builtin_msa_srlri_w"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "bvi_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_subvi_b;	 // "__builtin_msa_subvi_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_subvi_d;	 // "__builtin_msa_subvi_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_subvi_h;	 // "__builtin_msa_subvi_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_subvi_w;	 // "__builtin_msa_subvi_w"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 22:	 // 147 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 19 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+16, "dd", 2))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'q':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case '_':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "ph", 2))
+              break;
+            return Intrinsic::mips_addq_ph;	 // "__builtin_mips_addq_ph"
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "_w", 2))
+              break;
+            return Intrinsic::mips_addqh_w;	 // "__builtin_mips_addqh_w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[19] != '_')
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (BuiltinName[21] != 'h')
+              break;
+            return Intrinsic::mips_addu_ph;	 // "__builtin_mips_addu_ph"
+          case 'q':	 // 1 string to match.
+            if (BuiltinName[21] != 'b')
+              break;
+            return Intrinsic::mips_addu_qb;	 // "__builtin_mips_addu_qb"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 3 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+17, "ck_", 3))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (BuiltinName[21] != 'h')
+              break;
+            return Intrinsic::mips_pick_ph;	 // "__builtin_mips_pick_ph"
+          case 'q':	 // 1 string to match.
+            if (BuiltinName[21] != 'b')
+              break;
+            return Intrinsic::mips_pick_qb;	 // "__builtin_mips_pick_qb"
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "epend", 5))
+            break;
+          return Intrinsic::mips_prepend;	 // "__builtin_mips_prepend"
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "epl_", 4))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (BuiltinName[21] != 'h')
+            break;
+          return Intrinsic::mips_repl_ph;	 // "__builtin_mips_repl_ph"
+        case 'q':	 // 1 string to match.
+          if (BuiltinName[21] != 'b')
+            break;
+          return Intrinsic::mips_repl_qb;	 // "__builtin_mips_repl_qb"
+        }
+        break;
+      case 's':	 // 10 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'h':	 // 6 strings to match.
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "l_", 2))
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[21] != 'h')
+                break;
+              return Intrinsic::mips_shll_ph;	 // "__builtin_mips_shll_ph"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[21] != 'b')
+                break;
+              return Intrinsic::mips_shll_qb;	 // "__builtin_mips_shll_qb"
+            }
+            break;
+          case 'r':	 // 4 strings to match.
+            switch (BuiltinName[18]) {
+            default: break;
+            case 'a':	 // 2 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (BuiltinName[21] != 'h')
+                  break;
+                return Intrinsic::mips_shra_ph;	 // "__builtin_mips_shra_ph"
+              case 'q':	 // 1 string to match.
+                if (BuiltinName[21] != 'b')
+                  break;
+                return Intrinsic::mips_shra_qb;	 // "__builtin_mips_shra_qb"
+              }
+              break;
+            case 'l':	 // 2 strings to match.
+              if (BuiltinName[19] != '_')
+                break;
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'p':	 // 1 string to match.
+                if (BuiltinName[21] != 'h')
+                  break;
+                return Intrinsic::mips_shrl_ph;	 // "__builtin_mips_shrl_ph"
+              case 'q':	 // 1 string to match.
+                if (BuiltinName[21] != 'b')
+                  break;
+                return Intrinsic::mips_shrl_qb;	 // "__builtin_mips_shrl_qb"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[17] != 'b')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "ph", 2))
+                break;
+              return Intrinsic::mips_subq_ph;	 // "__builtin_mips_subq_ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "_w", 2))
+                break;
+              return Intrinsic::mips_subqh_w;	 // "__builtin_mips_subqh_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (BuiltinName[19] != '_')
+              break;
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[21] != 'h')
+                break;
+              return Intrinsic::mips_subu_ph;	 // "__builtin_mips_subu_ph"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[21] != 'b')
+                break;
+              return Intrinsic::mips_subu_qb;	 // "__builtin_mips_subu_qb"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 128 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'a':	 // 28 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'd':	 // 12 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ds_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_adds_a_b;	 // "__builtin_msa_adds_a_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_adds_a_d;	 // "__builtin_msa_adds_a_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_adds_a_h;	 // "__builtin_msa_adds_a_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_adds_a_w;	 // "__builtin_msa_adds_a_w"
+            }
+            break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_adds_s_b;	 // "__builtin_msa_adds_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_adds_s_d;	 // "__builtin_msa_adds_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_adds_s_h;	 // "__builtin_msa_adds_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_adds_s_w;	 // "__builtin_msa_adds_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_adds_u_b;	 // "__builtin_msa_adds_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_adds_u_d;	 // "__builtin_msa_adds_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_adds_u_h;	 // "__builtin_msa_adds_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_adds_u_w;	 // "__builtin_msa_adds_u_w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ub_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_b;	 // "__builtin_msa_asub_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_d;	 // "__builtin_msa_asub_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_h;	 // "__builtin_msa_asub_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_asub_s_w;	 // "__builtin_msa_asub_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_b;	 // "__builtin_msa_asub_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_d;	 // "__builtin_msa_asub_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_h;	 // "__builtin_msa_asub_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_asub_u_w;	 // "__builtin_msa_asub_u_w"
+            }
+            break;
+          }
+          break;
+        case 'v':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "er_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_b;	 // "__builtin_msa_aver_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_d;	 // "__builtin_msa_aver_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_h;	 // "__builtin_msa_aver_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_aver_s_w;	 // "__builtin_msa_aver_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_b;	 // "__builtin_msa_aver_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_d;	 // "__builtin_msa_aver_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_h;	 // "__builtin_msa_aver_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_aver_u_w;	 // "__builtin_msa_aver_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+15, "ins", 3))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+19, "i_", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_binsli_b;	 // "__builtin_msa_binsli_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_binsli_d;	 // "__builtin_msa_binsli_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_binsli_h;	 // "__builtin_msa_binsli_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_binsli_w;	 // "__builtin_msa_binsli_w"
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+19, "i_", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_binsri_b;	 // "__builtin_msa_binsri_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_binsri_d;	 // "__builtin_msa_binsri_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_binsri_h;	 // "__builtin_msa_binsri_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_binsri_w;	 // "__builtin_msa_binsri_w"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 24 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'l':	 // 16 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'e':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+17, "i_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_b;	 // "__builtin_msa_clei_s_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_d;	 // "__builtin_msa_clei_s_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_h;	 // "__builtin_msa_clei_s_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clei_s_w;	 // "__builtin_msa_clei_s_w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_b;	 // "__builtin_msa_clei_u_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_d;	 // "__builtin_msa_clei_u_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_h;	 // "__builtin_msa_clei_u_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clei_u_w;	 // "__builtin_msa_clei_u_w"
+              }
+              break;
+            }
+            break;
+          case 't':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+17, "i_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_b;	 // "__builtin_msa_clti_s_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_d;	 // "__builtin_msa_clti_s_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_h;	 // "__builtin_msa_clti_s_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clti_s_w;	 // "__builtin_msa_clti_s_w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_b;	 // "__builtin_msa_clti_u_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_d;	 // "__builtin_msa_clti_u_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_h;	 // "__builtin_msa_clti_u_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_clti_u_w;	 // "__builtin_msa_clti_u_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "py_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_b;	 // "__builtin_msa_copy_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_d;	 // "__builtin_msa_copy_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_h;	 // "__builtin_msa_copy_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_copy_s_w;	 // "__builtin_msa_copy_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_b;	 // "__builtin_msa_copy_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_d;	 // "__builtin_msa_copy_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_h;	 // "__builtin_msa_copy_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_copy_u_w;	 // "__builtin_msa_copy_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+15, "otp_", 4))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 's':	 // 3 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_dotp_s_d;	 // "__builtin_msa_dotp_s_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_dotp_s_h;	 // "__builtin_msa_dotp_s_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_dotp_s_w;	 // "__builtin_msa_dotp_s_w"
+          }
+          break;
+        case 'u':	 // 3 strings to match.
+          if (BuiltinName[20] != '_')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_dotp_u_d;	 // "__builtin_msa_dotp_u_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_dotp_u_h;	 // "__builtin_msa_dotp_u_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_dotp_u_w;	 // "__builtin_msa_dotp_u_w"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 12 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lass_", 5))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_fclass_d;	 // "__builtin_msa_fclass_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_fclass_w;	 // "__builtin_msa_fclass_w"
+          }
+          break;
+        case 'e':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "xup", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexupl_d;	 // "__builtin_msa_fexupl_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexupl_w;	 // "__builtin_msa_fexupl_w"
+            }
+            break;
+          case 'r':	 // 2 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fexupr_d;	 // "__builtin_msa_fexupr_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fexupr_w;	 // "__builtin_msa_fexupr_w"
+            }
+            break;
+          }
+          break;
+        case 'm':	 // 4 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "x_a_", 4))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmax_a_d;	 // "__builtin_msa_fmax_a_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmax_a_w;	 // "__builtin_msa_fmax_a_w"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "n_a_", 4))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_fmin_a_d;	 // "__builtin_msa_fmin_a_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_fmin_a_w;	 // "__builtin_msa_fmin_a_w"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "sqrt_", 5))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_frsqrt_d;	 // "__builtin_msa_frsqrt_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_frsqrt_w;	 // "__builtin_msa_frsqrt_w"
+          }
+          break;
+        }
+        break;
+      case 'h':	 // 12 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+16, "dd_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_d;	 // "__builtin_msa_hadd_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_h;	 // "__builtin_msa_hadd_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hadd_s_w;	 // "__builtin_msa_hadd_s_w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_d;	 // "__builtin_msa_hadd_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_h;	 // "__builtin_msa_hadd_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hadd_u_w;	 // "__builtin_msa_hadd_u_w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ub_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_d;	 // "__builtin_msa_hsub_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_h;	 // "__builtin_msa_hsub_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hsub_s_w;	 // "__builtin_msa_hsub_s_w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_d;	 // "__builtin_msa_hsub_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_h;	 // "__builtin_msa_hsub_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_hsub_u_w;	 // "__builtin_msa_hsub_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "nsert_", 6))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::mips_insert_b;	 // "__builtin_msa_insert_b"
+        case 'd':	 // 1 string to match.
+          return Intrinsic::mips_insert_d;	 // "__builtin_msa_insert_d"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::mips_insert_h;	 // "__builtin_msa_insert_h"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::mips_insert_w;	 // "__builtin_msa_insert_w"
+        }
+        break;
+      case 'm':	 // 22 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 10 strings to match.
+          switch (BuiltinName[16]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+17, "d_q_", 4))
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_madd_q_h;	 // "__builtin_msa_madd_q_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_madd_q_w;	 // "__builtin_msa_madd_q_w"
+            }
+            break;
+          case 'x':	 // 8 strings to match.
+            if (memcmp(BuiltinName.data()+17, "i_", 2))
+              break;
+            switch (BuiltinName[19]) {
+            default: break;
+            case 's':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_b;	 // "__builtin_msa_maxi_s_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_d;	 // "__builtin_msa_maxi_s_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_h;	 // "__builtin_msa_maxi_s_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_maxi_s_w;	 // "__builtin_msa_maxi_s_w"
+              }
+              break;
+            case 'u':	 // 4 strings to match.
+              if (BuiltinName[20] != '_')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'b':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_b;	 // "__builtin_msa_maxi_u_b"
+              case 'd':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_d;	 // "__builtin_msa_maxi_u_d"
+              case 'h':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_h;	 // "__builtin_msa_maxi_u_h"
+              case 'w':	 // 1 string to match.
+                return Intrinsic::mips_maxi_u_w;	 // "__builtin_msa_maxi_u_w"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ni_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_b;	 // "__builtin_msa_mini_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_d;	 // "__builtin_msa_mini_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_h;	 // "__builtin_msa_mini_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mini_s_w;	 // "__builtin_msa_mini_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_b;	 // "__builtin_msa_mini_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_d;	 // "__builtin_msa_mini_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_h;	 // "__builtin_msa_mini_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_mini_u_w;	 // "__builtin_msa_mini_u_w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ub_q_", 5))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msub_q_h;	 // "__builtin_msa_msub_q_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msub_q_w;	 // "__builtin_msa_msub_q_w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lr_q_", 5))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_mulr_q_h;	 // "__builtin_msa_mulr_q_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_mulr_q_w;	 // "__builtin_msa_mulr_q_w"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 12 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'p':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "lati_", 5))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_splati_b;	 // "__builtin_msa_splati_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_splati_d;	 // "__builtin_msa_splati_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_splati_h;	 // "__builtin_msa_splati_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_splati_w;	 // "__builtin_msa_splati_w"
+          }
+          break;
+        case 'u':	 // 8 strings to match.
+          if (memcmp(BuiltinName.data()+16, "bs_", 3))
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_subs_s_b;	 // "__builtin_msa_subs_s_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_subs_s_d;	 // "__builtin_msa_subs_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_subs_s_h;	 // "__builtin_msa_subs_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_subs_s_w;	 // "__builtin_msa_subs_s_w"
+            }
+            break;
+          case 'u':	 // 4 strings to match.
+            if (BuiltinName[20] != '_')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::mips_subs_u_b;	 // "__builtin_msa_subs_u_b"
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_subs_u_d;	 // "__builtin_msa_subs_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_subs_u_h;	 // "__builtin_msa_subs_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_subs_u_w;	 // "__builtin_msa_subs_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 23:	 // 40 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 16 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+17, "sq_s_w", 6))
+            break;
+          return Intrinsic::mips_absq_s_w;	 // "__builtin_mips_absq_s_w"
+        case 'd':	 // 3 strings to match.
+          if (BuiltinName[17] != 'd')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "s_w", 3))
+                break;
+              return Intrinsic::mips_addq_s_w;	 // "__builtin_mips_addq_s_w"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "_ph", 3))
+                break;
+              return Intrinsic::mips_addqh_ph;	 // "__builtin_mips_addqh_ph"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+19, "h_qb", 4))
+              break;
+            return Intrinsic::mips_adduh_qb;	 // "__builtin_mips_adduh_qb"
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "posge32", 7))
+          break;
+        return Intrinsic::mips_bposge32;	 // "__builtin_mips_bposge32"
+      case 'd':	 // 2 strings to match.
+        if (BuiltinName[16] != 'p')
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "_w_ph", 5))
+            break;
+          return Intrinsic::mips_dpa_w_ph;	 // "__builtin_mips_dpa_w_ph"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "_w_ph", 5))
+            break;
+          return Intrinsic::mips_dps_w_ph;	 // "__builtin_mips_dps_w_ph"
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "xtr_", 4))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "_w", 2))
+            break;
+          return Intrinsic::mips_extr_r_w;	 // "__builtin_mips_extr_r_w"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "_h", 2))
+            break;
+          return Intrinsic::mips_extr_s_h;	 // "__builtin_mips_extr_s_h"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "ul", 2))
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case '_':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "s_ph", 4))
+            break;
+          return Intrinsic::mips_mul_s_ph;	 // "__builtin_mips_mul_s_ph"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "_s_w", 4))
+            break;
+          return Intrinsic::mips_mulq_s_w;	 // "__builtin_mips_mulq_s_w"
+        }
+        break;
+      case 's':	 // 5 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+18, "l_s_w", 5))
+              break;
+            return Intrinsic::mips_shll_s_w;	 // "__builtin_mips_shll_s_w"
+          case 'r':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+18, "a_r_w", 5))
+              break;
+            return Intrinsic::mips_shra_r_w;	 // "__builtin_mips_shra_r_w"
+          }
+          break;
+        case 'u':	 // 3 strings to match.
+          if (BuiltinName[17] != 'b')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "s_w", 3))
+                break;
+              return Intrinsic::mips_subq_s_w;	 // "__builtin_mips_subq_s_w"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "_ph", 3))
+                break;
+              return Intrinsic::mips_subqh_ph;	 // "__builtin_mips_subqh_ph"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+19, "h_qb", 4))
+              break;
+            return Intrinsic::mips_subuh_qb;	 // "__builtin_mips_subuh_qb"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 24 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'd':	 // 12 strings to match.
+        if (BuiltinName[15] != 'p')
+          break;
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+17, "dd_", 3))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_s_d;	 // "__builtin_msa_dpadd_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_s_h;	 // "__builtin_msa_dpadd_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_s_w;	 // "__builtin_msa_dpadd_s_w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_u_d;	 // "__builtin_msa_dpadd_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_u_h;	 // "__builtin_msa_dpadd_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dpadd_u_w;	 // "__builtin_msa_dpadd_u_w"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+17, "ub_", 3))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 's':	 // 3 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_s_d;	 // "__builtin_msa_dpsub_s_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_s_h;	 // "__builtin_msa_dpsub_s_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_s_w;	 // "__builtin_msa_dpsub_s_w"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_u_d;	 // "__builtin_msa_dpsub_u_d"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_u_h;	 // "__builtin_msa_dpsub_u_h"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_dpsub_u_w;	 // "__builtin_msa_dpsub_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'f':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "int_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffint_s_d;	 // "__builtin_msa_ffint_s_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffint_s_w;	 // "__builtin_msa_ffint_s_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ffint_u_d;	 // "__builtin_msa_ffint_u_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ffint_u_w;	 // "__builtin_msa_ffint_u_w"
+            }
+            break;
+          }
+          break;
+        case 't':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+16, "int_", 4))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ftint_s_d;	 // "__builtin_msa_ftint_s_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ftint_s_w;	 // "__builtin_msa_ftint_s_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (BuiltinName[21] != '_')
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::mips_ftint_u_d;	 // "__builtin_msa_ftint_u_d"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::mips_ftint_u_w;	 // "__builtin_msa_ftint_u_w"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (BuiltinName[15]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ddr_q_", 6))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_maddr_q_h;	 // "__builtin_msa_maddr_q_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_maddr_q_w;	 // "__builtin_msa_maddr_q_w"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+16, "ubr_q_", 6))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_msubr_q_h;	 // "__builtin_msa_msubr_q_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_msubr_q_w;	 // "__builtin_msa_msubr_q_w"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 24:	 // 34 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_m", 11))
+      break;
+    switch (BuiltinName[11]) {
+    default: break;
+    case 'i':	 // 22 strings to match.
+      if (memcmp(BuiltinName.data()+12, "ps_", 3))
+        break;
+      switch (BuiltinName[15]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+17, "sq_s_", 5))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'p':	 // 1 string to match.
+            if (BuiltinName[23] != 'h')
+              break;
+            return Intrinsic::mips_absq_s_ph;	 // "__builtin_mips_absq_s_ph"
+          case 'q':	 // 1 string to match.
+            if (BuiltinName[23] != 'b')
+              break;
+            return Intrinsic::mips_absq_s_qb;	 // "__builtin_mips_absq_s_qb"
+          }
+          break;
+        case 'd':	 // 4 strings to match.
+          if (BuiltinName[17] != 'd')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "s_ph", 4))
+                break;
+              return Intrinsic::mips_addq_s_ph;	 // "__builtin_mips_addq_s_ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "_r_w", 4))
+                break;
+              return Intrinsic::mips_addqh_r_w;	 // "__builtin_mips_addqh_r_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+19, "_s_", 3))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[23] != 'h')
+                break;
+              return Intrinsic::mips_addu_s_ph;	 // "__builtin_mips_addu_s_ph"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[23] != 'b')
+                break;
+              return Intrinsic::mips_addu_s_qb;	 // "__builtin_mips_addu_s_qb"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+16, "mp_", 3))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "q_ph", 4))
+            break;
+          return Intrinsic::mips_cmp_eq_ph;	 // "__builtin_mips_cmp_eq_ph"
+        case 'l':	 // 2 strings to match.
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+21, "_ph", 3))
+              break;
+            return Intrinsic::mips_cmp_le_ph;	 // "__builtin_mips_cmp_le_ph"
+          case 't':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+21, "_ph", 3))
+              break;
+            return Intrinsic::mips_cmp_lt_ph;	 // "__builtin_mips_cmp_lt_ph"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 2 strings to match.
+        if (BuiltinName[16] != 'p')
+          break;
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "x_w_ph", 6))
+            break;
+          return Intrinsic::mips_dpax_w_ph;	 // "__builtin_mips_dpax_w_ph"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "x_w_ph", 6))
+            break;
+          return Intrinsic::mips_dpsx_w_ph;	 // "__builtin_mips_dpsx_w_ph"
+        }
+        break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "xtr_rs_w", 8))
+          break;
+        return Intrinsic::mips_extr_rs_w;	 // "__builtin_mips_extr_rs_w"
+      case 'm':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+16, "ulq_", 4))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "s_w", 3))
+            break;
+          return Intrinsic::mips_mulq_rs_w;	 // "__builtin_mips_mulq_rs_w"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "_ph", 3))
+            break;
+          return Intrinsic::mips_mulq_s_ph;	 // "__builtin_mips_mulq_s_ph"
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+16, "ackrl_ph", 8))
+          break;
+        return Intrinsic::mips_packrl_ph;	 // "__builtin_mips_packrl_ph"
+      case 's':	 // 7 strings to match.
+        switch (BuiltinName[16]) {
+        default: break;
+        case 'h':	 // 3 strings to match.
+          switch (BuiltinName[17]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+18, "l_s_ph", 6))
+              break;
+            return Intrinsic::mips_shll_s_ph;	 // "__builtin_mips_shll_s_ph"
+          case 'r':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+18, "a_r_", 4))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[23] != 'h')
+                break;
+              return Intrinsic::mips_shra_r_ph;	 // "__builtin_mips_shra_r_ph"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[23] != 'b')
+                break;
+              return Intrinsic::mips_shra_r_qb;	 // "__builtin_mips_shra_r_qb"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[17] != 'b')
+            break;
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case '_':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "s_ph", 4))
+                break;
+              return Intrinsic::mips_subq_s_ph;	 // "__builtin_mips_subq_s_ph"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+20, "_r_w", 4))
+                break;
+              return Intrinsic::mips_subqh_r_w;	 // "__builtin_mips_subqh_r_w"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+19, "_s_", 3))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'p':	 // 1 string to match.
+              if (BuiltinName[23] != 'h')
+                break;
+              return Intrinsic::mips_subu_s_ph;	 // "__builtin_mips_subu_s_ph"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[23] != 'b')
+                break;
+              return Intrinsic::mips_subu_s_qb;	 // "__builtin_mips_subu_s_qb"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+12, "a_", 2))
+        break;
+      switch (BuiltinName[14]) {
+      default: break;
+      case 'f':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+15, "trunc_", 6))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          if (BuiltinName[22] != '_')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_s_d;	 // "__builtin_msa_ftrunc_s_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_s_w;	 // "__builtin_msa_ftrunc_s_w"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[22] != '_')
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_u_d;	 // "__builtin_msa_ftrunc_u_d"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_ftrunc_u_w;	 // "__builtin_msa_ftrunc_u_w"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+15, "ubsu", 4))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "_u_", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_subsus_u_b;	 // "__builtin_msa_subsus_u_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_subsus_u_d;	 // "__builtin_msa_subsus_u_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_subsus_u_h;	 // "__builtin_msa_subsus_u_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_subsus_u_w;	 // "__builtin_msa_subsus_u_w"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "_s_", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::mips_subsuu_s_b;	 // "__builtin_msa_subsuu_s_b"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::mips_subsuu_s_d;	 // "__builtin_msa_subsuu_s_d"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::mips_subsuu_s_h;	 // "__builtin_msa_subsuu_s_h"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::mips_subsuu_s_w;	 // "__builtin_msa_subsuu_s_w"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 25:	 // 14 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "dd", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "h_r_ph", 6))
+          break;
+        return Intrinsic::mips_addqh_r_ph;	 // "__builtin_mips_addqh_r_ph"
+      case 'u':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "h_r_qb", 6))
+          break;
+        return Intrinsic::mips_adduh_r_qb;	 // "__builtin_mips_adduh_r_qb"
+      }
+      break;
+    case 'c':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "mpu_", 4))
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "q_qb", 4))
+          break;
+        return Intrinsic::mips_cmpu_eq_qb;	 // "__builtin_mips_cmpu_eq_qb"
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpu_le_qb;	 // "__builtin_mips_cmpu_le_qb"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpu_lt_qb;	 // "__builtin_mips_cmpu_lt_qb"
+        }
+        break;
+      }
+      break;
+    case 'd':	 // 4 strings to match.
+      if (BuiltinName[16] != 'p')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "u_h_qb", 6))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_dpau_h_qbl;	 // "__builtin_mips_dpau_h_qbl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_dpau_h_qbr;	 // "__builtin_mips_dpau_h_qbr"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "u_h_qb", 6))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_dpsu_h_qbl;	 // "__builtin_mips_dpsu_h_qbl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_dpsu_h_qbr;	 // "__builtin_mips_dpsu_h_qbr"
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ul", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "_rs_ph", 6))
+          break;
+        return Intrinsic::mips_mulq_rs_ph;	 // "__builtin_mips_mulq_rs_ph"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "a_w_ph", 6))
+          break;
+        return Intrinsic::mips_mulsa_w_ph;	 // "__builtin_mips_mulsa_w_ph"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "addu_w_qb", 9))
+        break;
+      return Intrinsic::mips_raddu_w_qb;	 // "__builtin_mips_raddu_w_qb"
+    case 's':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ub", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "h_r_ph", 6))
+          break;
+        return Intrinsic::mips_subqh_r_ph;	 // "__builtin_mips_subqh_r_ph"
+      case 'u':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "h_r_qb", 6))
+          break;
+        return Intrinsic::mips_subuh_r_qb;	 // "__builtin_mips_subuh_r_qb"
+      }
+      break;
+    }
+    break;
+  case 26:	 // 11 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'c':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "mpgu_", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "q_qb", 4))
+          break;
+        return Intrinsic::mips_cmpgu_eq_qb;	 // "__builtin_mips_cmpgu_eq_qb"
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpgu_le_qb;	 // "__builtin_mips_cmpgu_le_qb"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpgu_lt_qb;	 // "__builtin_mips_cmpgu_lt_qb"
+        }
+        break;
+      }
+      break;
+    case 'd':	 // 4 strings to match.
+      if (BuiltinName[16] != 'p')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "q_s", 3))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case '_':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "w_ph", 4))
+            break;
+          return Intrinsic::mips_dpaq_s_w_ph;	 // "__builtin_mips_dpaq_s_w_ph"
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_l_w", 4))
+            break;
+          return Intrinsic::mips_dpaq_sa_l_w;	 // "__builtin_mips_dpaq_sa_l_w"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "q_s", 3))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case '_':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "w_ph", 4))
+            break;
+          return Intrinsic::mips_dpsq_s_w_ph;	 // "__builtin_mips_dpsq_s_w_ph"
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_l_w", 4))
+            break;
+          return Intrinsic::mips_dpsq_sa_l_w;	 // "__builtin_mips_dpsq_sa_l_w"
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "aq_s_w_ph", 9))
+        break;
+      switch (BuiltinName[25]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        return Intrinsic::mips_maq_s_w_phl;	 // "__builtin_mips_maq_s_w_phl"
+      case 'r':	 // 1 string to match.
+        return Intrinsic::mips_maq_s_w_phr;	 // "__builtin_mips_maq_s_w_phr"
+      }
+      break;
+    case 'p':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "recr", 4))
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case '_':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "qb_ph", 5))
+          break;
+        return Intrinsic::mips_precr_qb_ph;	 // "__builtin_mips_precr_qb_ph"
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "_ph_w", 5))
+          break;
+        return Intrinsic::mips_precrq_ph_w;	 // "__builtin_mips_precrq_ph_w"
+      }
+      break;
+    }
+    break;
+  case 27:	 // 10 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'c':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "mpgdu_", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "q_qb", 4))
+          break;
+        return Intrinsic::mips_cmpgdu_eq_qb;	 // "__builtin_mips_cmpgdu_eq_qb"
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpgdu_le_qb;	 // "__builtin_mips_cmpgdu_le_qb"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "_qb", 3))
+            break;
+          return Intrinsic::mips_cmpgdu_lt_qb;	 // "__builtin_mips_cmpgdu_lt_qb"
+        }
+        break;
+      }
+      break;
+    case 'd':	 // 2 strings to match.
+      if (BuiltinName[16] != 'p')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+18, "qx_s_w_ph", 9))
+          break;
+        return Intrinsic::mips_dpaqx_s_w_ph;	 // "__builtin_mips_dpaqx_s_w_ph"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+18, "qx_s_w_ph", 9))
+          break;
+        return Intrinsic::mips_dpsqx_s_w_ph;	 // "__builtin_mips_dpsqx_s_w_ph"
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "aq_sa_w_ph", 10))
+        break;
+      switch (BuiltinName[26]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        return Intrinsic::mips_maq_sa_w_phl;	 // "__builtin_mips_maq_sa_w_phl"
+      case 'r':	 // 1 string to match.
+        return Intrinsic::mips_maq_sa_w_phr;	 // "__builtin_mips_maq_sa_w_phr"
+      }
+      break;
+    case 'p':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "rec", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+20, "q_w_ph", 6))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_preceq_w_phl;	 // "__builtin_mips_preceq_w_phl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_preceq_w_phr;	 // "__builtin_mips_preceq_w_phr"
+        }
+        break;
+      case 'r':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "q_qb_ph", 7))
+          break;
+        return Intrinsic::mips_precrq_qb_ph;	 // "__builtin_mips_precrq_qb_ph"
+      }
+      break;
+    }
+    break;
+  case 28:	 // 7 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (BuiltinName[16] != 'p')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+18, "qx_sa_w_ph", 10))
+          break;
+        return Intrinsic::mips_dpaqx_sa_w_ph;	 // "__builtin_mips_dpaqx_sa_w_ph"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+18, "qx_sa_w_ph", 10))
+          break;
+        return Intrinsic::mips_dpsqx_sa_w_ph;	 // "__builtin_mips_dpsqx_sa_w_ph"
+      }
+      break;
+    case 'm':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ul", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "q_s_w_ph", 8))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          return Intrinsic::mips_muleq_s_w_phl;	 // "__builtin_mips_muleq_s_w_phl"
+        case 'r':	 // 1 string to match.
+          return Intrinsic::mips_muleq_s_w_phr;	 // "__builtin_mips_muleq_s_w_phr"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "aq_s_w_ph", 9))
+          break;
+        return Intrinsic::mips_mulsaq_s_w_ph;	 // "__builtin_mips_mulsaq_s_w_ph"
+      }
+      break;
+    case 'p':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "receu_ph_qb", 11))
+        break;
+      switch (BuiltinName[27]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        return Intrinsic::mips_preceu_ph_qbl;	 // "__builtin_mips_preceu_ph_qbl"
+      case 'r':	 // 1 string to match.
+        return Intrinsic::mips_preceu_ph_qbr;	 // "__builtin_mips_preceu_ph_qbr"
+      }
+      break;
+    }
+    break;
+  case 29:	 // 8 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "uleu_s_ph_qb", 12))
+        break;
+      switch (BuiltinName[28]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        return Intrinsic::mips_muleu_s_ph_qbl;	 // "__builtin_mips_muleu_s_ph_qbl"
+      case 'r':	 // 1 string to match.
+        return Intrinsic::mips_muleu_s_ph_qbr;	 // "__builtin_mips_muleu_s_ph_qbr"
+      }
+      break;
+    case 'p':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+16, "rec", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'e':	 // 4 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'q':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+21, "u_ph_qb", 7))
+            break;
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            return Intrinsic::mips_precequ_ph_qbl;	 // "__builtin_mips_precequ_ph_qbl"
+          case 'r':	 // 1 string to match.
+            return Intrinsic::mips_precequ_ph_qbr;	 // "__builtin_mips_precequ_ph_qbr"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+21, "_ph_qb", 6))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[28] != 'a')
+              break;
+            return Intrinsic::mips_preceu_ph_qbla;	 // "__builtin_mips_preceu_ph_qbla"
+          case 'r':	 // 1 string to match.
+            if (BuiltinName[28] != 'a')
+              break;
+            return Intrinsic::mips_preceu_ph_qbra;	 // "__builtin_mips_preceu_ph_qbra"
+          }
+          break;
+        }
+        break;
+      case 'r':	 // 2 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case '_':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "sra_ph_w", 8))
+            break;
+          return Intrinsic::mips_precr_sra_ph_w;	 // "__builtin_mips_precr_sra_ph_w"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "_rs_ph_w", 8))
+            break;
+          return Intrinsic::mips_precrq_rs_ph_w;	 // "__builtin_mips_precrq_rs_ph_w"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 30:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_prec", 19))
+      break;
+    switch (BuiltinName[19]) {
+    default: break;
+    case 'e':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+20, "qu_ph_qb", 8))
+        break;
+      switch (BuiltinName[28]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        if (BuiltinName[29] != 'a')
+          break;
+        return Intrinsic::mips_precequ_ph_qbla;	 // "__builtin_mips_precequ_ph_qbla"
+      case 'r':	 // 1 string to match.
+        if (BuiltinName[29] != 'a')
+          break;
+        return Intrinsic::mips_precequ_ph_qbra;	 // "__builtin_mips_precequ_ph_qbra"
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "qu_s_qb_ph", 10))
+        break;
+      return Intrinsic::mips_precrqu_s_qb_ph;	 // "__builtin_mips_precrqu_s_qb_ph"
+    }
+    break;
+  case 31:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_mips_precr_sra_r_ph_w", 31))
+      break;
+    return Intrinsic::mips_precr_sra_r_ph_w;	 // "__builtin_mips_precr_sra_r_ph_w"
+  }
+  }
+  if (TargetPrefix == "ppc") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 21:	 // 4 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (BuiltinName[19] != 's')
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 's':	 // 1 string to match.
+        return Intrinsic::ppc_altivec_dss;	 // "__builtin_altivec_dss"
+      case 't':	 // 1 string to match.
+        return Intrinsic::ppc_altivec_dst;	 // "__builtin_altivec_dst"
+      }
+      break;
+    case 'v':	 // 2 strings to match.
+      if (BuiltinName[19] != 's')
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        return Intrinsic::ppc_altivec_vsl;	 // "__builtin_altivec_vsl"
+      case 'r':	 // 1 string to match.
+        return Intrinsic::ppc_altivec_vsr;	 // "__builtin_altivec_vsr"
+      }
+      break;
+    }
+    break;
+  case 22:	 // 12 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "stt", 3))
+        break;
+      return Intrinsic::ppc_altivec_dstt;	 // "__builtin_altivec_dstt"
+    case 'v':	 // 11 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'r':	 // 3 strings to match.
+        if (BuiltinName[20] != 'l')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vrlb;	 // "__builtin_altivec_vrlb"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vrlh;	 // "__builtin_altivec_vrlh"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vrlw;	 // "__builtin_altivec_vrlw"
+        }
+        break;
+      case 's':	 // 8 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'l':	 // 4 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vslb;	 // "__builtin_altivec_vslb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vslh;	 // "__builtin_altivec_vslh"
+          case 'o':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vslo;	 // "__builtin_altivec_vslo"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vslw;	 // "__builtin_altivec_vslw"
+          }
+          break;
+        case 'r':	 // 4 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsrb;	 // "__builtin_altivec_vsrb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsrh;	 // "__builtin_altivec_vsrh"
+          case 'o':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsro;	 // "__builtin_altivec_vsro"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vsrw;	 // "__builtin_altivec_vsrw"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 23:	 // 12 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+19, "stst", 4))
+        break;
+      return Intrinsic::ppc_altivec_dstst;	 // "__builtin_altivec_dstst"
+    case 'v':	 // 11 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (BuiltinName[20] != 'f')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (BuiltinName[22] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_vcfsx;	 // "__builtin_altivec_vcfsx"
+        case 'u':	 // 1 string to match.
+          if (BuiltinName[22] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_vcfux;	 // "__builtin_altivec_vcfux"
+        }
+        break;
+      case 'p':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "kpx", 3))
+          break;
+        return Intrinsic::ppc_altivec_vpkpx;	 // "__builtin_altivec_vpkpx"
+      case 'r':	 // 5 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "fp", 2))
+            break;
+          return Intrinsic::ppc_altivec_vrefp;	 // "__builtin_altivec_vrefp"
+        case 'f':	 // 4 strings to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vrfim;	 // "__builtin_altivec_vrfim"
+          case 'n':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vrfin;	 // "__builtin_altivec_vrfin"
+          case 'p':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vrfip;	 // "__builtin_altivec_vrfip"
+          case 'z':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vrfiz;	 // "__builtin_altivec_vrfiz"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+20, "ra", 2))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vsrab;	 // "__builtin_altivec_vsrab"
+        case 'h':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vsrah;	 // "__builtin_altivec_vsrah"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vsraw;	 // "__builtin_altivec_vsraw"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 24:	 // 26 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_", 18))
+      break;
+    switch (BuiltinName[18]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (BuiltinName[19] != 's')
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "all", 3))
+          break;
+        return Intrinsic::ppc_altivec_dssall;	 // "__builtin_altivec_dssall"
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "stt", 3))
+          break;
+        return Intrinsic::ppc_altivec_dststt;	 // "__builtin_altivec_dststt"
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "vscr", 4))
+          break;
+        return Intrinsic::ppc_altivec_mfvscr;	 // "__builtin_altivec_mfvscr"
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "vscr", 4))
+          break;
+        return Intrinsic::ppc_altivec_mtvscr;	 // "__builtin_altivec_mtvscr"
+      }
+      break;
+    case 'v':	 // 22 strings to match.
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+20, "vg", 2))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 's':	 // 3 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavgsb;	 // "__builtin_altivec_vavgsb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavgsh;	 // "__builtin_altivec_vavgsh"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavgsw;	 // "__builtin_altivec_vavgsw"
+          }
+          break;
+        case 'u':	 // 3 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavgub;	 // "__builtin_altivec_vavgub"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavguh;	 // "__builtin_altivec_vavguh"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vavguw;	 // "__builtin_altivec_vavguw"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 2 strings to match.
+        if (BuiltinName[20] != 't')
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xs", 2))
+            break;
+          return Intrinsic::ppc_altivec_vctsxs;	 // "__builtin_altivec_vctsxs"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "xs", 2))
+            break;
+          return Intrinsic::ppc_altivec_vctuxs;	 // "__builtin_altivec_vctuxs"
+        }
+        break;
+      case 'm':	 // 14 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'a':	 // 7 strings to match.
+          if (BuiltinName[21] != 'x')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (BuiltinName[23] != 'p')
+              break;
+            return Intrinsic::ppc_altivec_vmaxfp;	 // "__builtin_altivec_vmaxfp"
+          case 's':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxsb;	 // "__builtin_altivec_vmaxsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxsh;	 // "__builtin_altivec_vmaxsh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxsw;	 // "__builtin_altivec_vmaxsw"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxub;	 // "__builtin_altivec_vmaxub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxuh;	 // "__builtin_altivec_vmaxuh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmaxuw;	 // "__builtin_altivec_vmaxuw"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 7 strings to match.
+          if (BuiltinName[21] != 'n')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (BuiltinName[23] != 'p')
+              break;
+            return Intrinsic::ppc_altivec_vminfp;	 // "__builtin_altivec_vminfp"
+          case 's':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminsb;	 // "__builtin_altivec_vminsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminsh;	 // "__builtin_altivec_vminsh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminsw;	 // "__builtin_altivec_vminsw"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminub;	 // "__builtin_altivec_vminub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminuh;	 // "__builtin_altivec_vminuh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vminuw;	 // "__builtin_altivec_vminuw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 25:	 // 38 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_v", 19))
+      break;
+    switch (BuiltinName[19]) {
+    default: break;
+    case 'a':	 // 7 strings to match.
+      if (memcmp(BuiltinName.data()+20, "dd", 2))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "uw", 2))
+          break;
+        return Intrinsic::ppc_altivec_vaddcuw;	 // "__builtin_altivec_vaddcuw"
+      case 's':	 // 3 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vaddsbs;	 // "__builtin_altivec_vaddsbs"
+        case 'h':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vaddshs;	 // "__builtin_altivec_vaddshs"
+        case 'w':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vaddsws;	 // "__builtin_altivec_vaddsws"
+        }
+        break;
+      case 'u':	 // 3 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vaddubs;	 // "__builtin_altivec_vaddubs"
+        case 'h':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vadduhs;	 // "__builtin_altivec_vadduhs"
+        case 'w':	 // 1 string to match.
+          if (BuiltinName[24] != 's')
+            break;
+          return Intrinsic::ppc_altivec_vadduws;	 // "__builtin_altivec_vadduws"
+        }
+        break;
+      }
+      break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "mpbfp", 5))
+        break;
+      return Intrinsic::ppc_altivec_vcmpbfp;	 // "__builtin_altivec_vcmpbfp"
+    case 'l':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "ogefp", 5))
+        break;
+      return Intrinsic::ppc_altivec_vlogefp;	 // "__builtin_altivec_vlogefp"
+    case 'm':	 // 9 strings to match.
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "ddfp", 4))
+          break;
+        return Intrinsic::ppc_altivec_vmaddfp;	 // "__builtin_altivec_vmaddfp"
+      case 'u':	 // 8 strings to match.
+        if (BuiltinName[21] != 'l')
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'e':	 // 4 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmulesb;	 // "__builtin_altivec_vmulesb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmulesh;	 // "__builtin_altivec_vmulesh"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmuleub;	 // "__builtin_altivec_vmuleub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmuleuh;	 // "__builtin_altivec_vmuleuh"
+            }
+            break;
+          }
+          break;
+        case 'o':	 // 4 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmulosb;	 // "__builtin_altivec_vmulosb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmulosh;	 // "__builtin_altivec_vmulosh"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmuloub;	 // "__builtin_altivec_vmuloub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vmulouh;	 // "__builtin_altivec_vmulouh"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 6 strings to match.
+      if (BuiltinName[20] != 'k')
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 's':	 // 4 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vpkshss;	 // "__builtin_altivec_vpkshss"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vpkshus;	 // "__builtin_altivec_vpkshus"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vpkswss;	 // "__builtin_altivec_vpkswss"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vpkswus;	 // "__builtin_altivec_vpkswus"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 2 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "us", 2))
+            break;
+          return Intrinsic::ppc_altivec_vpkuhus;	 // "__builtin_altivec_vpkuhus"
+        case 'w':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "us", 2))
+            break;
+          return Intrinsic::ppc_altivec_vpkuwus;	 // "__builtin_altivec_vpkuwus"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 8 strings to match.
+      if (BuiltinName[20] != 'u')
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'b':	 // 7 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'c':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "uw", 2))
+            break;
+          return Intrinsic::ppc_altivec_vsubcuw;	 // "__builtin_altivec_vsubcuw"
+        case 's':	 // 3 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsubsbs;	 // "__builtin_altivec_vsubsbs"
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsubshs;	 // "__builtin_altivec_vsubshs"
+          case 'w':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsubsws;	 // "__builtin_altivec_vsubsws"
+          }
+          break;
+        case 'u':	 // 3 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsububs;	 // "__builtin_altivec_vsububs"
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsubuhs;	 // "__builtin_altivec_vsubuhs"
+          case 'w':	 // 1 string to match.
+            if (BuiltinName[24] != 's')
+              break;
+            return Intrinsic::ppc_altivec_vsubuws;	 // "__builtin_altivec_vsubuws"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "sws", 3))
+          break;
+        return Intrinsic::ppc_altivec_vsumsws;	 // "__builtin_altivec_vsumsws"
+      }
+      break;
+    case 'u':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+20, "pk", 2))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'h':	 // 3 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (BuiltinName[24] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_vupkhpx;	 // "__builtin_altivec_vupkhpx"
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vupkhsb;	 // "__builtin_altivec_vupkhsb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vupkhsh;	 // "__builtin_altivec_vupkhsh"
+          }
+          break;
+        }
+        break;
+      case 'l':	 // 3 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (BuiltinName[24] != 'x')
+            break;
+          return Intrinsic::ppc_altivec_vupklpx;	 // "__builtin_altivec_vupklpx"
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vupklsb;	 // "__builtin_altivec_vupklsb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vupklsh;	 // "__builtin_altivec_vupklsh"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 26:	 // 25 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_v", 19))
+      break;
+    switch (BuiltinName[19]) {
+    default: break;
+    case 'c':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+20, "mp", 2))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'e':	 // 4 strings to match.
+        if (BuiltinName[23] != 'q')
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (BuiltinName[25] != 'p')
+            break;
+          return Intrinsic::ppc_altivec_vcmpeqfp;	 // "__builtin_altivec_vcmpeqfp"
+        case 'u':	 // 3 strings to match.
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vcmpequb;	 // "__builtin_altivec_vcmpequb"
+          case 'h':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vcmpequh;	 // "__builtin_altivec_vcmpequh"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vcmpequw;	 // "__builtin_altivec_vcmpequw"
+          }
+          break;
+        }
+        break;
+      case 'g':	 // 8 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "fp", 2))
+            break;
+          return Intrinsic::ppc_altivec_vcmpgefp;	 // "__builtin_altivec_vcmpgefp"
+        case 't':	 // 7 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (BuiltinName[25] != 'p')
+              break;
+            return Intrinsic::ppc_altivec_vcmpgtfp;	 // "__builtin_altivec_vcmpgtfp"
+          case 's':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtsb;	 // "__builtin_altivec_vcmpgtsb"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtsh;	 // "__builtin_altivec_vcmpgtsh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtsw;	 // "__builtin_altivec_vcmpgtsw"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtub;	 // "__builtin_altivec_vcmpgtub"
+            case 'h':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtuh;	 // "__builtin_altivec_vcmpgtuh"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::ppc_altivec_vcmpgtuw;	 // "__builtin_altivec_vcmpgtuw"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "xptefp", 6))
+        break;
+      return Intrinsic::ppc_altivec_vexptefp;	 // "__builtin_altivec_vexptefp"
+    case 'm':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+20, "sum", 3))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "bm", 2))
+          break;
+        return Intrinsic::ppc_altivec_vmsummbm;	 // "__builtin_altivec_vmsummbm"
+      case 's':	 // 2 strings to match.
+        if (BuiltinName[24] != 'h')
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'm':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vmsumshm;	 // "__builtin_altivec_vmsumshm"
+        case 's':	 // 1 string to match.
+          return Intrinsic::ppc_altivec_vmsumshs;	 // "__builtin_altivec_vmsumshs"
+        }
+        break;
+      case 'u':	 // 3 strings to match.
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          if (BuiltinName[25] != 'm')
+            break;
+          return Intrinsic::ppc_altivec_vmsumubm;	 // "__builtin_altivec_vmsumubm"
+        case 'h':	 // 2 strings to match.
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'm':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vmsumuhm;	 // "__builtin_altivec_vmsumuhm"
+          case 's':	 // 1 string to match.
+            return Intrinsic::ppc_altivec_vmsumuhs;	 // "__builtin_altivec_vmsumuhs"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'n':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "msubfp", 6))
+        break;
+      return Intrinsic::ppc_altivec_vnmsubfp;	 // "__builtin_altivec_vnmsubfp"
+    case 's':	 // 5 strings to match.
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "l_4si", 5))
+          break;
+        return Intrinsic::ppc_altivec_vsel;	 // "__builtin_altivec_vsel_4si"
+      case 'u':	 // 4 strings to match.
+        if (BuiltinName[21] != 'm')
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "sws", 3))
+            break;
+          return Intrinsic::ppc_altivec_vsum2sws;	 // "__builtin_altivec_vsum2sws"
+        case '4':	 // 3 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (BuiltinName[25] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsum4sbs;	 // "__builtin_altivec_vsum4sbs"
+            case 'h':	 // 1 string to match.
+              if (BuiltinName[25] != 's')
+                break;
+              return Intrinsic::ppc_altivec_vsum4shs;	 // "__builtin_altivec_vsum4shs"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "bs", 2))
+              break;
+            return Intrinsic::ppc_altivec_vsum4ubs;	 // "__builtin_altivec_vsum4ubs"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 27:	 // 5 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_v", 19))
+      break;
+    switch (BuiltinName[19]) {
+    default: break;
+    case 'c':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "mpbfp_p", 7))
+        break;
+      return Intrinsic::ppc_altivec_vcmpbfp_p;	 // "__builtin_altivec_vcmpbfp_p"
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "addshs", 6))
+          break;
+        return Intrinsic::ppc_altivec_vmhaddshs;	 // "__builtin_altivec_vmhaddshs"
+      case 'l':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "adduhm", 6))
+          break;
+        return Intrinsic::ppc_altivec_vmladduhm;	 // "__builtin_altivec_vmladduhm"
+      }
+      break;
+    case 'p':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "erm_4si", 7))
+        break;
+      return Intrinsic::ppc_altivec_vperm;	 // "__builtin_altivec_vperm_4si"
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "sqrtefp", 7))
+        break;
+      return Intrinsic::ppc_altivec_vrsqrtefp;	 // "__builtin_altivec_vrsqrtefp"
+    }
+    break;
+  case 28:	 // 13 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_altivec_v", 19))
+      break;
+    switch (BuiltinName[19]) {
+    default: break;
+    case 'c':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+20, "mp", 2))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'e':	 // 4 strings to match.
+        if (BuiltinName[23] != 'q')
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "p_p", 3))
+            break;
+          return Intrinsic::ppc_altivec_vcmpeqfp_p;	 // "__builtin_altivec_vcmpeqfp_p"
+        case 'u':	 // 3 strings to match.
+          switch (BuiltinName[25]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_p", 2))
+              break;
+            return Intrinsic::ppc_altivec_vcmpequb_p;	 // "__builtin_altivec_vcmpequb_p"
+          case 'h':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_p", 2))
+              break;
+            return Intrinsic::ppc_altivec_vcmpequh_p;	 // "__builtin_altivec_vcmpequh_p"
+          case 'w':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+26, "_p", 2))
+              break;
+            return Intrinsic::ppc_altivec_vcmpequw_p;	 // "__builtin_altivec_vcmpequw_p"
+          }
+          break;
+        }
+        break;
+      case 'g':	 // 8 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "fp_p", 4))
+            break;
+          return Intrinsic::ppc_altivec_vcmpgefp_p;	 // "__builtin_altivec_vcmpgefp_p"
+        case 't':	 // 7 strings to match.
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "p_p", 3))
+              break;
+            return Intrinsic::ppc_altivec_vcmpgtfp_p;	 // "__builtin_altivec_vcmpgtfp_p"
+          case 's':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtsb_p;	 // "__builtin_altivec_vcmpgtsb_p"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtsh_p;	 // "__builtin_altivec_vcmpgtsh_p"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtsw_p;	 // "__builtin_altivec_vcmpgtsw_p"
+            }
+            break;
+          case 'u':	 // 3 strings to match.
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'b':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtub_p;	 // "__builtin_altivec_vcmpgtub_p"
+            case 'h':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtuh_p;	 // "__builtin_altivec_vcmpgtuh_p"
+            case 'w':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+26, "_p", 2))
+                break;
+              return Intrinsic::ppc_altivec_vcmpgtuw_p;	 // "__builtin_altivec_vcmpgtuw_p"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+20, "hraddshs", 8))
+        break;
+      return Intrinsic::ppc_altivec_vmhraddshs;	 // "__builtin_altivec_vmhraddshs"
+    }
+    break;
+  }
+  }
+  if (TargetPrefix == "r600") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 26:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_tgid_", 25))
+      break;
+    switch (BuiltinName[25]) {
+    default: break;
+    case 'x':	 // 1 string to match.
+      return Intrinsic::r600_read_tgid_x;	 // "__builtin_r600_read_tgid_x"
+    case 'y':	 // 1 string to match.
+      return Intrinsic::r600_read_tgid_y;	 // "__builtin_r600_read_tgid_y"
+    case 'z':	 // 1 string to match.
+      return Intrinsic::r600_read_tgid_z;	 // "__builtin_r600_read_tgid_z"
+    }
+    break;
+  case 27:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_tidig_", 26))
+      break;
+    switch (BuiltinName[26]) {
+    default: break;
+    case 'x':	 // 1 string to match.
+      return Intrinsic::r600_read_tidig_x;	 // "__builtin_r600_read_tidig_x"
+    case 'y':	 // 1 string to match.
+      return Intrinsic::r600_read_tidig_y;	 // "__builtin_r600_read_tidig_y"
+    case 'z':	 // 1 string to match.
+      return Intrinsic::r600_read_tidig_z;	 // "__builtin_r600_read_tidig_z"
+    }
+    break;
+  case 29:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_ngroups_", 28))
+      break;
+    switch (BuiltinName[28]) {
+    default: break;
+    case 'x':	 // 1 string to match.
+      return Intrinsic::r600_read_ngroups_x;	 // "__builtin_r600_read_ngroups_x"
+    case 'y':	 // 1 string to match.
+      return Intrinsic::r600_read_ngroups_y;	 // "__builtin_r600_read_ngroups_y"
+    case 'z':	 // 1 string to match.
+      return Intrinsic::r600_read_ngroups_z;	 // "__builtin_r600_read_ngroups_z"
+    }
+    break;
+  case 32:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_local_size_", 31))
+      break;
+    switch (BuiltinName[31]) {
+    default: break;
+    case 'x':	 // 1 string to match.
+      return Intrinsic::r600_read_local_size_x;	 // "__builtin_r600_read_local_size_x"
+    case 'y':	 // 1 string to match.
+      return Intrinsic::r600_read_local_size_y;	 // "__builtin_r600_read_local_size_y"
+    case 'z':	 // 1 string to match.
+      return Intrinsic::r600_read_local_size_z;	 // "__builtin_r600_read_local_size_z"
+    }
+    break;
+  case 33:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_r600_read_global_size_", 32))
+      break;
+    switch (BuiltinName[32]) {
+    default: break;
+    case 'x':	 // 1 string to match.
+      return Intrinsic::r600_read_global_size_x;	 // "__builtin_r600_read_global_size_x"
+    case 'y':	 // 1 string to match.
+      return Intrinsic::r600_read_global_size_y;	 // "__builtin_r600_read_global_size_y"
+    case 'z':	 // 1 string to match.
+      return Intrinsic::r600_read_global_size_z;	 // "__builtin_r600_read_global_size_z"
+    }
+    break;
+  }
+  }
+  if (TargetPrefix == "x86") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 18:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_por", 18))
+      break;
+    return Intrinsic::x86_mmx_por;	 // "__builtin_ia32_por"
+  case 19:	 // 6 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "pp", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse41_dppd;	 // "__builtin_ia32_dppd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse41_dpps;	 // "__builtin_ia32_dpps"
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "mms", 3))
+        break;
+      return Intrinsic::x86_mmx_emms;	 // "__builtin_ia32_emms"
+    case 'p':	 // 2 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "nd", 2))
+          break;
+        return Intrinsic::x86_mmx_pand;	 // "__builtin_ia32_pand"
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "or", 2))
+          break;
+        return Intrinsic::x86_mmx_pxor;	 // "__builtin_ia32_pxor"
+      }
+      break;
+    case 'x':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "end", 3))
+        break;
+      return Intrinsic::x86_xend;	 // "__builtin_ia32_xend"
+    }
+    break;
+  case 20:	 // 64 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "dds", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse2_add_sd;	 // "__builtin_ia32_addsd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse_add_ss;	 // "__builtin_ia32_addss"
+      }
+      break;
+    case 'c':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "mp", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'p':	 // 2 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse2_cmp_pd;	 // "__builtin_ia32_cmppd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse_cmp_ps;	 // "__builtin_ia32_cmpps"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse2_cmp_sd;	 // "__builtin_ia32_cmpsd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse_cmp_ss;	 // "__builtin_ia32_cmpss"
+        }
+        break;
+      }
+      break;
+    case 'd':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ivs", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse2_div_sd;	 // "__builtin_ia32_divsd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse_div_ss;	 // "__builtin_ia32_divss"
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "xtrq", 4))
+        break;
+      return Intrinsic::x86_sse4a_extrq;	 // "__builtin_ia32_extrq"
+    case 'f':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "emms", 4))
+        break;
+      return Intrinsic::x86_mmx_femms;	 // "__builtin_ia32_femms"
+    case 'k':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "orhi", 4))
+        break;
+      return Intrinsic::x86_avx512_kor_w;	 // "__builtin_ia32_korhi"
+    case 'l':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "ddqu", 4))
+        break;
+      return Intrinsic::x86_sse3_ldu_dq;	 // "__builtin_ia32_lddqu"
+    case 'm':	 // 11 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (BuiltinName[17] != 'x')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_max_pd;	 // "__builtin_ia32_maxpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_max_ps;	 // "__builtin_ia32_maxps"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_max_sd;	 // "__builtin_ia32_maxsd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_max_ss;	 // "__builtin_ia32_maxss"
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 4 strings to match.
+        if (BuiltinName[17] != 'n')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_min_pd;	 // "__builtin_ia32_minpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_min_ps;	 // "__builtin_ia32_minps"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_min_sd;	 // "__builtin_ia32_minsd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_min_ss;	 // "__builtin_ia32_minss"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ls", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse2_mul_sd;	 // "__builtin_ia32_mulsd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse_mul_ss;	 // "__builtin_ia32_mulss"
+        }
+        break;
+      case 'w':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "ait", 3))
+          break;
+        return Intrinsic::x86_sse3_mwait;	 // "__builtin_ia32_mwait"
+      }
+      break;
+    case 'p':	 // 34 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 11 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 3 strings to match.
+          if (BuiltinName[18] != 's')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_pabs_b;	 // "__builtin_ia32_pabsb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_pabs_d;	 // "__builtin_ia32_pabsd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_pabs_w;	 // "__builtin_ia32_pabsw"
+          }
+          break;
+        case 'd':	 // 4 strings to match.
+          if (BuiltinName[18] != 'd')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_padd_b;	 // "__builtin_ia32_paddb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_mmx_padd_d;	 // "__builtin_ia32_paddd"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_mmx_padd_q;	 // "__builtin_ia32_paddq"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_padd_w;	 // "__builtin_ia32_paddw"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "dn", 2))
+            break;
+          return Intrinsic::x86_mmx_pandn;	 // "__builtin_ia32_pandn"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "se", 2))
+            break;
+          return Intrinsic::x86_sse2_pause;	 // "__builtin_ia32_pause"
+        case 'v':	 // 2 strings to match.
+          if (BuiltinName[18] != 'g')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pavg_b;	 // "__builtin_ia32_pavgb"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pavg_w;	 // "__builtin_ia32_pavgw"
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 9 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case '2':	 // 2 strings to match.
+          if (BuiltinName[18] != 'i')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_3dnow_pf2id;	 // "__builtin_ia32_pf2id"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_3dnowa_pf2iw;	 // "__builtin_ia32_pf2iw"
+          }
+          break;
+        case 'a':	 // 2 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'c':	 // 1 string to match.
+            if (BuiltinName[19] != 'c')
+              break;
+            return Intrinsic::x86_3dnow_pfacc;	 // "__builtin_ia32_pfacc"
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[19] != 'd')
+              break;
+            return Intrinsic::x86_3dnow_pfadd;	 // "__builtin_ia32_pfadd"
+          }
+          break;
+        case 'm':	 // 3 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (BuiltinName[19] != 'x')
+              break;
+            return Intrinsic::x86_3dnow_pfmax;	 // "__builtin_ia32_pfmax"
+          case 'i':	 // 1 string to match.
+            if (BuiltinName[19] != 'n')
+              break;
+            return Intrinsic::x86_3dnow_pfmin;	 // "__builtin_ia32_pfmin"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[19] != 'l')
+              break;
+            return Intrinsic::x86_3dnow_pfmul;	 // "__builtin_ia32_pfmul"
+          }
+          break;
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "cp", 2))
+            break;
+          return Intrinsic::x86_3dnow_pfrcp;	 // "__builtin_ia32_pfrcp"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ub", 2))
+            break;
+          return Intrinsic::x86_3dnow_pfsub;	 // "__builtin_ia32_pfsub"
+        }
+        break;
+      case 'i':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "2f", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_3dnow_pi2fd;	 // "__builtin_ia32_pi2fd"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::x86_3dnowa_pi2fw;	 // "__builtin_ia32_pi2fw"
+        }
+        break;
+      case 's':	 // 12 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'l':	 // 3 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psll_d;	 // "__builtin_ia32_pslld"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psll_q;	 // "__builtin_ia32_psllq"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psll_w;	 // "__builtin_ia32_psllw"
+          }
+          break;
+        case 'r':	 // 5 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psra_d;	 // "__builtin_ia32_psrad"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psra_w;	 // "__builtin_ia32_psraw"
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psrl_d;	 // "__builtin_ia32_psrld"
+            case 'q':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psrl_q;	 // "__builtin_ia32_psrlq"
+            case 'w':	 // 1 string to match.
+              return Intrinsic::x86_mmx_psrl_w;	 // "__builtin_ia32_psrlw"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[18] != 'b')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psub_b;	 // "__builtin_ia32_psubb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psub_d;	 // "__builtin_ia32_psubd"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psub_q;	 // "__builtin_ia32_psubq"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psub_w;	 // "__builtin_ia32_psubw"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (BuiltinName[17] != 'p')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (BuiltinName[19] != 's')
+            break;
+          return Intrinsic::x86_sse_rcp_ps;	 // "__builtin_ia32_rcpps"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[19] != 's')
+            break;
+          return Intrinsic::x86_sse_rcp_ss;	 // "__builtin_ia32_rcpss"
+        }
+        break;
+      case 'd':	 // 2 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "mc", 2))
+            break;
+          return Intrinsic::x86_rdpmc;	 // "__builtin_ia32_rdpmc"
+        case 't':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "sc", 2))
+            break;
+          return Intrinsic::x86_rdtsc;	 // "__builtin_ia32_rdtsc"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ubs", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse2_sub_sd;	 // "__builtin_ia32_subsd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse_sub_ss;	 // "__builtin_ia32_subss"
+      }
+      break;
+    case 'x':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "test", 4))
+        break;
+      return Intrinsic::x86_xtest;	 // "__builtin_ia32_xtest"
+    }
+    break;
+  case 21:	 // 55 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'c':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+16, "omi", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (BuiltinName[20] != 'q')
+          break;
+        return Intrinsic::x86_sse_comieq_ss;	 // "__builtin_ia32_comieq"
+      case 'g':	 // 2 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse_comige_ss;	 // "__builtin_ia32_comige"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse_comigt_ss;	 // "__builtin_ia32_comigt"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse_comile_ss;	 // "__builtin_ia32_comile"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse_comilt_ss;	 // "__builtin_ia32_comilt"
+        }
+        break;
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "xtrqi", 5))
+        break;
+      return Intrinsic::x86_sse4a_extrqi;	 // "__builtin_ia32_extrqi"
+    case 'h':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ddp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse3_hadd_pd;	 // "__builtin_ia32_haddpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse3_hadd_ps;	 // "__builtin_ia32_haddps"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ubp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse3_hsub_pd;	 // "__builtin_ia32_hsubpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse3_hsub_ps;	 // "__builtin_ia32_hsubps"
+        }
+        break;
+      }
+      break;
+    case 'k':	 // 3 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "ndhi", 4))
+          break;
+        return Intrinsic::x86_avx512_kand_w;	 // "__builtin_ia32_kandhi"
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "othi", 4))
+          break;
+        return Intrinsic::x86_avx512_knot_w;	 // "__builtin_ia32_knothi"
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "orhi", 4))
+          break;
+        return Intrinsic::x86_avx512_kxor_w;	 // "__builtin_ia32_kxorhi"
+      }
+      break;
+    case 'l':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "fence", 5))
+        break;
+      return Intrinsic::x86_sse2_lfence;	 // "__builtin_ia32_lfence"
+    case 'm':	 // 2 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "ence", 4))
+          break;
+        return Intrinsic::x86_sse2_mfence;	 // "__builtin_ia32_mfence"
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "vntq", 4))
+          break;
+        return Intrinsic::x86_mmx_movnt_dq;	 // "__builtin_ia32_movntq"
+      }
+      break;
+    case 'p':	 // 31 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "dds", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'b':	 // 1 string to match.
+          return Intrinsic::x86_mmx_padds_b;	 // "__builtin_ia32_paddsb"
+        case 'w':	 // 1 string to match.
+          return Intrinsic::x86_mmx_padds_w;	 // "__builtin_ia32_paddsw"
+        }
+        break;
+      case 'f':	 // 2 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "acc", 3))
+            break;
+          return Intrinsic::x86_3dnowa_pfnacc;	 // "__builtin_ia32_pfnacc"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ubr", 3))
+            break;
+          return Intrinsic::x86_3dnow_pfsubr;	 // "__builtin_ia32_pfsubr"
+        }
+        break;
+      case 'h':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "dd", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_phadd_d;	 // "__builtin_ia32_phaddd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_phadd_w;	 // "__builtin_ia32_phaddw"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ub", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_phsub_d;	 // "__builtin_ia32_phsubd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_phsub_w;	 // "__builtin_ia32_phsubw"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 6 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (BuiltinName[18] != 'x')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[20] != 'w')
+              break;
+            return Intrinsic::x86_mmx_pmaxs_w;	 // "__builtin_ia32_pmaxsw"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[20] != 'b')
+              break;
+            return Intrinsic::x86_mmx_pmaxu_b;	 // "__builtin_ia32_pmaxub"
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (BuiltinName[18] != 'n')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 1 string to match.
+            if (BuiltinName[20] != 'w')
+              break;
+            return Intrinsic::x86_mmx_pmins_w;	 // "__builtin_ia32_pminsw"
+          case 'u':	 // 1 string to match.
+            if (BuiltinName[20] != 'b')
+              break;
+            return Intrinsic::x86_mmx_pminu_b;	 // "__builtin_ia32_pminub"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[20] != 'w')
+              break;
+            return Intrinsic::x86_mmx_pmulh_w;	 // "__builtin_ia32_pmulhw"
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[20] != 'w')
+              break;
+            return Intrinsic::x86_mmx_pmull_w;	 // "__builtin_ia32_pmullw"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 17 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "dbw", 3))
+            break;
+          return Intrinsic::x86_mmx_psad_bw;	 // "__builtin_ia32_psadbw"
+        case 'h':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "uf", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_pshuf_b;	 // "__builtin_ia32_pshufb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_pshuf_d;	 // "__builtin_ia32_pshufd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_sse_pshuf_w;	 // "__builtin_ia32_pshufw"
+          }
+          break;
+        case 'i':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "gn", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_psign_b;	 // "__builtin_ia32_psignb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_psign_d;	 // "__builtin_ia32_psignd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_ssse3_psign_w;	 // "__builtin_ia32_psignw"
+          }
+          break;
+        case 'l':	 // 3 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            return Intrinsic::x86_mmx_pslli_d;	 // "__builtin_ia32_pslldi"
+          case 'q':	 // 1 string to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            return Intrinsic::x86_mmx_pslli_q;	 // "__builtin_ia32_psllqi"
+          case 'w':	 // 1 string to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            return Intrinsic::x86_mmx_pslli_w;	 // "__builtin_ia32_psllwi"
+          }
+          break;
+        case 'r':	 // 5 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              return Intrinsic::x86_mmx_psrai_d;	 // "__builtin_ia32_psradi"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              return Intrinsic::x86_mmx_psrai_w;	 // "__builtin_ia32_psrawi"
+            }
+            break;
+          case 'l':	 // 3 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              return Intrinsic::x86_mmx_psrli_d;	 // "__builtin_ia32_psrldi"
+            case 'q':	 // 1 string to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              return Intrinsic::x86_mmx_psrli_q;	 // "__builtin_ia32_psrlqi"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              return Intrinsic::x86_mmx_psrli_w;	 // "__builtin_ia32_psrlwi"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "bs", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psubs_b;	 // "__builtin_ia32_psubsb"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psubs_w;	 // "__builtin_ia32_psubsw"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "dtscp", 5))
+        break;
+      return Intrinsic::x86_rdtscp;	 // "__builtin_ia32_rdtscp"
+    case 's':	 // 5 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'f':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "ence", 4))
+          break;
+        return Intrinsic::x86_sse_sfence;	 // "__builtin_ia32_sfence"
+      case 'q':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "rt", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_sqrt_pd;	 // "__builtin_ia32_sqrtpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_sqrt_ps;	 // "__builtin_ia32_sqrtps"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_sqrt_sd;	 // "__builtin_ia32_sqrtsd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_sqrt_ss;	 // "__builtin_ia32_sqrtss"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'x':	 // 2 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "bort", 4))
+          break;
+        return Intrinsic::x86_xabort;	 // "__builtin_ia32_xabort"
+      case 'b':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "egin", 4))
+          break;
+        return Intrinsic::x86_xbegin;	 // "__builtin_ia32_xbegin"
+      }
+      break;
+    }
+    break;
+  case 22:	 // 57 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'b':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'l':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "endp", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse41_blendpd;	 // "__builtin_ia32_blendpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse41_blendps;	 // "__builtin_ia32_blendps"
+        }
+        break;
+      case 'z':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "hi_", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_bzhi_64;	 // "__builtin_ia32_bzhi_di"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_bzhi_32;	 // "__builtin_ia32_bzhi_si"
+        }
+        break;
+      }
+      break;
+    case 'c':	 // 6 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'l':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "flush", 5))
+          break;
+        return Intrinsic::x86_sse2_clflush;	 // "__builtin_ia32_clflush"
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "mineq", 5))
+          break;
+        return Intrinsic::x86_sse_comineq_ss;	 // "__builtin_ia32_comineq"
+      case 'r':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "c32", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_sse42_crc32_64_64;	 // "__builtin_ia32_crc32di"
+        case 'h':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_sse42_crc32_32_16;	 // "__builtin_ia32_crc32hi"
+        case 'q':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_sse42_crc32_32_8;	 // "__builtin_ia32_crc32qi"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_sse42_crc32_32_32;	 // "__builtin_ia32_crc32si"
+        }
+        break;
+      }
+      break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "pps256", 6))
+        break;
+      return Intrinsic::x86_avx_dp_ps_256;	 // "__builtin_ia32_dpps256"
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "nsertq", 6))
+        break;
+      return Intrinsic::x86_sse4a_insertq;	 // "__builtin_ia32_insertq"
+    case 'k':	 // 2 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "ndnhi", 5))
+          break;
+        return Intrinsic::x86_avx512_kandn_w;	 // "__builtin_ia32_kandnhi"
+      case 'x':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "norhi", 5))
+          break;
+        return Intrinsic::x86_avx512_kxnor_w;	 // "__builtin_ia32_kxnorhi"
+      }
+      break;
+    case 'm':	 // 3 strings to match.
+      if (BuiltinName[16] != 'o')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'n':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+18, "itor", 4))
+          break;
+        return Intrinsic::x86_sse3_monitor;	 // "__builtin_ia32_monitor"
+      case 'v':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "nts", 3))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_sse4a_movnt_sd;	 // "__builtin_ia32_movntsd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_sse4a_movnt_ss;	 // "__builtin_ia32_movntss"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 29 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "dus", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_paddus_b;	 // "__builtin_ia32_paddusb"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_paddus_w;	 // "__builtin_ia32_paddusw"
+          }
+          break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ignr", 4))
+            break;
+          return Intrinsic::x86_mmx_palignr_b;	 // "__builtin_ia32_palignr"
+        case 'v':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "gusb", 4))
+            break;
+          return Intrinsic::x86_3dnow_pavgusb;	 // "__builtin_ia32_pavgusb"
+        }
+        break;
+      case 'c':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+17, "mp", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'e':	 // 3 strings to match.
+          if (BuiltinName[20] != 'q')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpeq_b;	 // "__builtin_ia32_pcmpeqb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpeq_d;	 // "__builtin_ia32_pcmpeqd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpeq_w;	 // "__builtin_ia32_pcmpeqw"
+          }
+          break;
+        case 'g':	 // 3 strings to match.
+          if (BuiltinName[20] != 't')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpgt_b;	 // "__builtin_ia32_pcmpgtb"
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpgt_d;	 // "__builtin_ia32_pcmpgtd"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_pcmpgt_w;	 // "__builtin_ia32_pcmpgtw"
+          }
+          break;
+        }
+        break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ep_", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_pdep_64;	 // "__builtin_ia32_pdep_di"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_pdep_32;	 // "__builtin_ia32_pdep_si"
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "xt_", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_pext_64;	 // "__builtin_ia32_pext_di"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[21] != 'i')
+            break;
+          return Intrinsic::x86_bmi_pext_32;	 // "__builtin_ia32_pext_si"
+        }
+        break;
+      case 'f':	 // 5 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'c':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "mp", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            if (BuiltinName[21] != 'q')
+              break;
+            return Intrinsic::x86_3dnow_pfcmpeq;	 // "__builtin_ia32_pfcmpeq"
+          case 'g':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'e':	 // 1 string to match.
+              return Intrinsic::x86_3dnow_pfcmpge;	 // "__builtin_ia32_pfcmpge"
+            case 't':	 // 1 string to match.
+              return Intrinsic::x86_3dnow_pfcmpgt;	 // "__builtin_ia32_pfcmpgt"
+            }
+            break;
+          }
+          break;
+        case 'p':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "nacc", 4))
+            break;
+          return Intrinsic::x86_3dnowa_pfpnacc;	 // "__builtin_ia32_pfpnacc"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "sqrt", 4))
+            break;
+          return Intrinsic::x86_3dnow_pfrsqrt;	 // "__builtin_ia32_pfrsqrt"
+        }
+        break;
+      case 'h':	 // 2 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ddsw", 4))
+            break;
+          return Intrinsic::x86_ssse3_phadd_sw;	 // "__builtin_ia32_phaddsw"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ubsw", 4))
+            break;
+          return Intrinsic::x86_ssse3_phsub_sw;	 // "__builtin_ia32_phsubsw"
+        }
+        break;
+      case 'm':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ddwd", 4))
+            break;
+          return Intrinsic::x86_mmx_pmadd_wd;	 // "__builtin_ia32_pmaddwd"
+        case 'u':	 // 3 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'r':	 // 1 string to match.
+              if (BuiltinName[21] != 'w')
+                break;
+              return Intrinsic::x86_3dnow_pmulhrw;	 // "__builtin_ia32_pmulhrw"
+            case 'u':	 // 1 string to match.
+              if (BuiltinName[21] != 'w')
+                break;
+              return Intrinsic::x86_mmx_pmulhu_w;	 // "__builtin_ia32_pmulhuw"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "dq", 2))
+              break;
+            return Intrinsic::x86_mmx_pmulu_dq;	 // "__builtin_ia32_pmuludq"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "uf", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'h':	 // 1 string to match.
+            if (BuiltinName[21] != 'w')
+              break;
+            return Intrinsic::x86_sse2_pshufh_w;	 // "__builtin_ia32_pshufhw"
+          case 'l':	 // 1 string to match.
+            if (BuiltinName[21] != 'w')
+              break;
+            return Intrinsic::x86_sse2_pshufl_w;	 // "__builtin_ia32_pshuflw"
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "bus", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psubus_b;	 // "__builtin_ia32_psubusb"
+          case 'w':	 // 1 string to match.
+            return Intrinsic::x86_mmx_psubus_w;	 // "__builtin_ia32_psubusw"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 6 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'o':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "und", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse41_round_pd;	 // "__builtin_ia32_roundpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse41_round_ps;	 // "__builtin_ia32_roundps"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse41_round_sd;	 // "__builtin_ia32_roundsd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse41_round_ss;	 // "__builtin_ia32_roundss"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "qrt", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'p':	 // 1 string to match.
+          if (BuiltinName[21] != 's')
+            break;
+          return Intrinsic::x86_sse_rsqrt_ps;	 // "__builtin_ia32_rsqrtps"
+        case 's':	 // 1 string to match.
+          if (BuiltinName[21] != 's')
+            break;
+          return Intrinsic::x86_sse_rsqrt_ss;	 // "__builtin_ia32_rsqrtss"
+        }
+        break;
+      }
+      break;
+    case 'u':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+16, "comi", 4))
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (BuiltinName[21] != 'q')
+          break;
+        return Intrinsic::x86_sse_ucomieq_ss;	 // "__builtin_ia32_ucomieq"
+      case 'g':	 // 2 strings to match.
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse_ucomige_ss;	 // "__builtin_ia32_ucomige"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse_ucomigt_ss;	 // "__builtin_ia32_ucomigt"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse_ucomile_ss;	 // "__builtin_ia32_ucomile"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse_ucomilt_ss;	 // "__builtin_ia32_ucomilt"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 23:	 // 102 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ddsubp", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse3_addsub_pd;	 // "__builtin_ia32_addsubpd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse3_addsub_ps;	 // "__builtin_ia32_addsubps"
+      }
+      break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "lendvp", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_sse41_blendvpd;	 // "__builtin_ia32_blendvpd"
+      case 's':	 // 1 string to match.
+        return Intrinsic::x86_sse41_blendvps;	 // "__builtin_ia32_blendvps"
+      }
+      break;
+    case 'c':	 // 23 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "pp", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "256", 3))
+            break;
+          return Intrinsic::x86_avx_cmp_pd_256;	 // "__builtin_ia32_cmppd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "256", 3))
+            break;
+          return Intrinsic::x86_avx_cmp_ps_256;	 // "__builtin_ia32_cmpps256"
+        }
+        break;
+      case 'o':	 // 5 strings to match.
+        if (memcmp(BuiltinName.data()+17, "misd", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (BuiltinName[22] != 'q')
+            break;
+          return Intrinsic::x86_sse2_comieq_sd;	 // "__builtin_ia32_comisdeq"
+        case 'g':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            return Intrinsic::x86_sse2_comige_sd;	 // "__builtin_ia32_comisdge"
+          case 't':	 // 1 string to match.
+            return Intrinsic::x86_sse2_comigt_sd;	 // "__builtin_ia32_comisdgt"
+          }
+          break;
+        case 'l':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'e':	 // 1 string to match.
+            return Intrinsic::x86_sse2_comile_sd;	 // "__builtin_ia32_comisdle"
+          case 't':	 // 1 string to match.
+            return Intrinsic::x86_sse2_comilt_sd;	 // "__builtin_ia32_comisdlt"
+          }
+          break;
+        }
+        break;
+      case 'v':	 // 16 strings to match.
+        if (BuiltinName[17] != 't')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "q2p", 3))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_cvtdq2pd;	 // "__builtin_ia32_cvtdq2pd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse2_cvtdq2ps;	 // "__builtin_ia32_cvtdq2ps"
+          }
+          break;
+        case 'p':	 // 8 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 3 strings to match.
+            if (BuiltinName[20] != '2')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              return Intrinsic::x86_sse2_cvtpd2dq;	 // "__builtin_ia32_cvtpd2dq"
+            case 'p':	 // 2 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'i':	 // 1 string to match.
+                return Intrinsic::x86_sse_cvtpd2pi;	 // "__builtin_ia32_cvtpd2pi"
+              case 's':	 // 1 string to match.
+                return Intrinsic::x86_sse2_cvtpd2ps;	 // "__builtin_ia32_cvtpd2ps"
+              }
+              break;
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "2p", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_sse_cvtpi2pd;	 // "__builtin_ia32_cvtpi2pd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_sse_cvtpi2ps;	 // "__builtin_ia32_cvtpi2ps"
+            }
+            break;
+          case 's':	 // 3 strings to match.
+            if (BuiltinName[20] != '2')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              return Intrinsic::x86_sse2_cvtps2dq;	 // "__builtin_ia32_cvtps2dq"
+            case 'p':	 // 2 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                return Intrinsic::x86_sse2_cvtps2pd;	 // "__builtin_ia32_cvtps2pd"
+              case 'i':	 // 1 string to match.
+                return Intrinsic::x86_sse_cvtps2pi;	 // "__builtin_ia32_cvtps2pi"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "2s", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              return Intrinsic::x86_sse2_cvtsd2si;	 // "__builtin_ia32_cvtsd2si"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_sse2_cvtsd2ss;	 // "__builtin_ia32_cvtsd2ss"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "2s", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_sse2_cvtsi2sd;	 // "__builtin_ia32_cvtsi2sd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_sse_cvtsi2ss;	 // "__builtin_ia32_cvtsi2ss"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "2s", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_sse2_cvtss2sd;	 // "__builtin_ia32_cvtss2sd"
+            case 'i':	 // 1 string to match.
+              return Intrinsic::x86_sse_cvtss2si;	 // "__builtin_ia32_cvtss2si"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "nsertqi", 7))
+        break;
+      return Intrinsic::x86_sse4a_insertqi;	 // "__builtin_ia32_insertqi"
+    case 'k':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "unpckhi", 7))
+        break;
+      return Intrinsic::x86_avx512_kunpck_bw;	 // "__builtin_ia32_kunpckhi"
+    case 'l':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "ddqu256", 7))
+        break;
+      return Intrinsic::x86_avx_ldu_dq_256;	 // "__builtin_ia32_lddqu256"
+    case 'm':	 // 8 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 3 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "kmovq", 5))
+            break;
+          return Intrinsic::x86_mmx_maskmovq;	 // "__builtin_ia32_maskmovq"
+        case 'x':	 // 2 strings to match.
+          if (BuiltinName[18] != 'p')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "256", 3))
+              break;
+            return Intrinsic::x86_avx_max_pd_256;	 // "__builtin_ia32_maxpd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "256", 3))
+              break;
+            return Intrinsic::x86_avx_max_ps_256;	 // "__builtin_ia32_maxps256"
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "np", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "256", 3))
+            break;
+          return Intrinsic::x86_avx_min_pd_256;	 // "__builtin_ia32_minpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "256", 3))
+            break;
+          return Intrinsic::x86_avx_min_ps_256;	 // "__builtin_ia32_minps256"
+        }
+        break;
+      case 'o':	 // 3 strings to match.
+        if (BuiltinName[17] != 'v')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "skp", 3))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_movmsk_pd;	 // "__builtin_ia32_movmskpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_movmsk_ps;	 // "__builtin_ia32_movmskps"
+          }
+          break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "tdqa", 4))
+            break;
+          return Intrinsic::x86_sse41_movntdqa;	 // "__builtin_ia32_movntdqa"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 44 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 13 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 6 strings to match.
+          if (BuiltinName[18] != 's')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_pabs_b_128;	 // "__builtin_ia32_pabsb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pabs_b;	 // "__builtin_ia32_pabsb256"
+            }
+            break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_pabs_d_128;	 // "__builtin_ia32_pabsd128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pabs_d;	 // "__builtin_ia32_pabsd256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_pabs_w_128;	 // "__builtin_ia32_pabsw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pabs_w;	 // "__builtin_ia32_pabsw256"
+            }
+            break;
+          }
+          break;
+        case 'c':	 // 3 strings to match.
+          if (BuiltinName[18] != 'k')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            if (BuiltinName[20] != 's')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (BuiltinName[22] != 'w')
+                break;
+              return Intrinsic::x86_mmx_packssdw;	 // "__builtin_ia32_packssdw"
+            case 'w':	 // 1 string to match.
+              if (BuiltinName[22] != 'b')
+                break;
+              return Intrinsic::x86_mmx_packsswb;	 // "__builtin_ia32_packsswb"
+            }
+            break;
+          case 'u':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "swb", 3))
+              break;
+            return Intrinsic::x86_mmx_packuswb;	 // "__builtin_ia32_packuswb"
+          }
+          break;
+        case 'v':	 // 4 strings to match.
+          if (BuiltinName[18] != 'g')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pavg_b;	 // "__builtin_ia32_pavgb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pavg_b;	 // "__builtin_ia32_pavgb256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pavg_w;	 // "__builtin_ia32_pavgw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pavg_w;	 // "__builtin_ia32_pavgw256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'f':	 // 3 strings to match.
+        if (BuiltinName[17] != 'r')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "pit", 3))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            return Intrinsic::x86_3dnow_pfrcpit1;	 // "__builtin_ia32_pfrcpit1"
+          case '2':	 // 1 string to match.
+            return Intrinsic::x86_3dnow_pfrcpit2;	 // "__builtin_ia32_pfrcpit2"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+19, "qit1", 4))
+            break;
+          return Intrinsic::x86_3dnow_pfrsqit1;	 // "__builtin_ia32_pfrsqit1"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'o':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "vmskb", 5))
+            break;
+          return Intrinsic::x86_mmx_pmovmskb;	 // "__builtin_ia32_pmovmskb"
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "lhrsw", 5))
+            break;
+          return Intrinsic::x86_ssse3_pmul_hr_sw;	 // "__builtin_ia32_pmulhrsw"
+        }
+        break;
+      case 's':	 // 26 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'l':	 // 10 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psll_d;	 // "__builtin_ia32_pslld128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psll_d;	 // "__builtin_ia32_pslld256"
+            }
+            break;
+          case 'q':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psll_q;	 // "__builtin_ia32_psllq128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psll_q;	 // "__builtin_ia32_psllq256"
+            }
+            break;
+          case 'v':	 // 4 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "di", 2))
+                break;
+              return Intrinsic::x86_avx2_psllv_q;	 // "__builtin_ia32_psllv2di"
+            case '4':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (BuiltinName[22] != 'i')
+                  break;
+                return Intrinsic::x86_avx2_psllv_q_256;	 // "__builtin_ia32_psllv4di"
+              case 's':	 // 1 string to match.
+                if (BuiltinName[22] != 'i')
+                  break;
+                return Intrinsic::x86_avx2_psllv_d;	 // "__builtin_ia32_psllv4si"
+              }
+              break;
+            case '8':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "si", 2))
+                break;
+              return Intrinsic::x86_avx2_psllv_d_256;	 // "__builtin_ia32_psllv8si"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psll_w;	 // "__builtin_ia32_psllw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psll_w;	 // "__builtin_ia32_psllw256"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 16 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 6 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psra_d;	 // "__builtin_ia32_psrad128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psra_d;	 // "__builtin_ia32_psrad256"
+              }
+              break;
+            case 'v':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '4':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "si", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrav_d;	 // "__builtin_ia32_psrav4si"
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "si", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrav_d_256;	 // "__builtin_ia32_psrav8si"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psra_w;	 // "__builtin_ia32_psraw128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psra_w;	 // "__builtin_ia32_psraw256"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 10 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrl_d;	 // "__builtin_ia32_psrld128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrl_d;	 // "__builtin_ia32_psrld256"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrl_q;	 // "__builtin_ia32_psrlq128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrl_q;	 // "__builtin_ia32_psrlq256"
+              }
+              break;
+            case 'v':	 // 4 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "di", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrlv_q;	 // "__builtin_ia32_psrlv2di"
+              case '4':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case 'd':	 // 1 string to match.
+                  if (BuiltinName[22] != 'i')
+                    break;
+                  return Intrinsic::x86_avx2_psrlv_q_256;	 // "__builtin_ia32_psrlv4di"
+                case 's':	 // 1 string to match.
+                  if (BuiltinName[22] != 'i')
+                    break;
+                  return Intrinsic::x86_avx2_psrlv_d;	 // "__builtin_ia32_psrlv4si"
+                }
+                break;
+              case '8':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "si", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrlv_d_256;	 // "__builtin_ia32_psrlv8si"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrl_w;	 // "__builtin_ia32_psrlw128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+21, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrl_w;	 // "__builtin_ia32_psrlw256"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "cpps256", 7))
+        break;
+      return Intrinsic::x86_avx_rcp_ps_256;	 // "__builtin_ia32_rcpps256"
+    case 's':	 // 5 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'h':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "a1msg", 5))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          return Intrinsic::x86_sha1msg1;	 // "__builtin_ia32_sha1msg1"
+        case '2':	 // 1 string to match.
+          return Intrinsic::x86_sha1msg2;	 // "__builtin_ia32_sha1msg2"
+        }
+        break;
+      case 't':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ore", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "qu", 2))
+            break;
+          return Intrinsic::x86_sse2_storeu_dq;	 // "__builtin_ia32_storedqu"
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_storeu_pd;	 // "__builtin_ia32_storeupd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_storeu_ps;	 // "__builtin_ia32_storeups"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'u':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "comineq", 7))
+        break;
+      return Intrinsic::x86_sse_ucomineq_ss;	 // "__builtin_ia32_ucomineq"
+    case 'v':	 // 13 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'f':	 // 8 strings to match.
+        if (BuiltinName[17] != 'm')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+19, "dd", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_pd;	 // "__builtin_ia32_vfmaddpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_ps;	 // "__builtin_ia32_vfmaddps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_sd;	 // "__builtin_ia32_vfmaddsd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmadd_ss;	 // "__builtin_ia32_vfmaddss"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+19, "ub", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_pd;	 // "__builtin_ia32_vfmsubpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_ps;	 // "__builtin_ia32_vfmsubps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_sd;	 // "__builtin_ia32_vfmsubsd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsub_ss;	 // "__builtin_ia32_vfmsubss"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "est", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx_vtestc_pd;	 // "__builtin_ia32_vtestcpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_avx_vtestc_ps;	 // "__builtin_ia32_vtestcps"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx_vtestz_pd;	 // "__builtin_ia32_vtestzpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_avx_vtestz_ps;	 // "__builtin_ia32_vtestzps"
+          }
+          break;
+        }
+        break;
+      case 'z':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "eroall", 6))
+          break;
+        return Intrinsic::x86_avx_vzeroall;	 // "__builtin_ia32_vzeroall"
+      }
+      break;
+    }
+    break;
+  case 24:	 // 131 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "es", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "ec128", 5))
+          break;
+        return Intrinsic::x86_aesni_aesdec;	 // "__builtin_ia32_aesdec128"
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "nc128", 5))
+          break;
+        return Intrinsic::x86_aesni_aesenc;	 // "__builtin_ia32_aesenc128"
+      case 'i':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "mc128", 5))
+          break;
+        return Intrinsic::x86_aesni_aesimc;	 // "__builtin_ia32_aesimc128"
+      }
+      break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "extr_u", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case '3':	 // 1 string to match.
+        if (BuiltinName[23] != '2')
+          break;
+        return Intrinsic::x86_bmi_bextr_32;	 // "__builtin_ia32_bextr_u32"
+      case '6':	 // 1 string to match.
+        if (BuiltinName[23] != '4')
+          break;
+        return Intrinsic::x86_bmi_bextr_64;	 // "__builtin_ia32_bextr_u64"
+      }
+      break;
+    case 'c':	 // 11 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'o':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "misdneq", 7))
+          break;
+        return Intrinsic::x86_sse2_comineq_sd;	 // "__builtin_ia32_comisdneq"
+      case 'v':	 // 10 strings to match.
+        if (BuiltinName[17] != 't')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "2usi", 4))
+              break;
+            return Intrinsic::x86_avx512_cvtsd2usi;	 // "__builtin_ia32_cvtsd2usi"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "2usi", 4))
+              break;
+            return Intrinsic::x86_avx512_cvtss2usi;	 // "__builtin_ia32_cvtss2usi"
+          }
+          break;
+        case 't':	 // 6 strings to match.
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'p':	 // 4 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (BuiltinName[21] != '2')
+                break;
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (BuiltinName[23] != 'q')
+                  break;
+                return Intrinsic::x86_sse2_cvttpd2dq;	 // "__builtin_ia32_cvttpd2dq"
+              case 'p':	 // 1 string to match.
+                if (BuiltinName[23] != 'i')
+                  break;
+                return Intrinsic::x86_sse_cvttpd2pi;	 // "__builtin_ia32_cvttpd2pi"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              if (BuiltinName[21] != '2')
+                break;
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 1 string to match.
+                if (BuiltinName[23] != 'q')
+                  break;
+                return Intrinsic::x86_sse2_cvttps2dq;	 // "__builtin_ia32_cvttps2dq"
+              case 'p':	 // 1 string to match.
+                if (BuiltinName[23] != 'i')
+                  break;
+                return Intrinsic::x86_sse_cvttps2pi;	 // "__builtin_ia32_cvttps2pi"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "2si", 3))
+                break;
+              return Intrinsic::x86_sse2_cvttsd2si;	 // "__builtin_ia32_cvttsd2si"
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "2si", 3))
+                break;
+              return Intrinsic::x86_sse_cvttss2si;	 // "__builtin_ia32_cvttss2si"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "si2s", 4))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx512_cvtusi2sd;	 // "__builtin_ia32_cvtusi2sd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_avx512_cvtusi2ss;	 // "__builtin_ia32_cvtusi2ss"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'g':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ather", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (BuiltinName[22] != '_')
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_d_d;	 // "__builtin_ia32_gatherd_d"
+        case 'q':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_d_q;	 // "__builtin_ia32_gatherd_q"
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (BuiltinName[22] != '_')
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_q_d;	 // "__builtin_ia32_gatherq_d"
+        case 'q':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_q_q;	 // "__builtin_ia32_gatherq_q"
+        }
+        break;
+      }
+      break;
+    case 'h':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ddp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "256", 3))
+            break;
+          return Intrinsic::x86_avx_hadd_pd_256;	 // "__builtin_ia32_haddpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "256", 3))
+            break;
+          return Intrinsic::x86_avx_hadd_ps_256;	 // "__builtin_ia32_haddps256"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ubp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "256", 3))
+            break;
+          return Intrinsic::x86_avx_hsub_pd_256;	 // "__builtin_ia32_hsubpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "256", 3))
+            break;
+          return Intrinsic::x86_avx_hsub_ps_256;	 // "__builtin_ia32_hsubps256"
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "askload", 7))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        return Intrinsic::x86_avx2_maskload_d;	 // "__builtin_ia32_maskloadd"
+      case 'q':	 // 1 string to match.
+        return Intrinsic::x86_avx2_maskload_q;	 // "__builtin_ia32_maskloadq"
+      }
+      break;
+    case 'p':	 // 82 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "dds", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_padds_b;	 // "__builtin_ia32_paddsb128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_padds_b;	 // "__builtin_ia32_paddsb256"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_padds_w;	 // "__builtin_ia32_paddsw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_padds_w;	 // "__builtin_ia32_paddsw256"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "rmti256", 7))
+          break;
+        return Intrinsic::x86_avx2_vperm2i128;	 // "__builtin_ia32_permti256"
+      case 'h':	 // 8 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "dd", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_phadd_d_128;	 // "__builtin_ia32_phaddd128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_phadd_d;	 // "__builtin_ia32_phaddd256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_phadd_w_128;	 // "__builtin_ia32_phaddw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_phadd_w;	 // "__builtin_ia32_phaddw256"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ub", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_phsub_d_128;	 // "__builtin_ia32_phsubd128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_phsub_d;	 // "__builtin_ia32_phsubd256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_phsub_w_128;	 // "__builtin_ia32_phsubw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_phsub_w;	 // "__builtin_ia32_phsubw256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 29 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 13 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+19, "dubsw", 5))
+              break;
+            return Intrinsic::x86_ssse3_pmadd_ub_sw;	 // "__builtin_ia32_pmaddubsw"
+          case 'x':	 // 12 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 's':	 // 6 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmaxsb;	 // "__builtin_ia32_pmaxsb128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxs_b;	 // "__builtin_ia32_pmaxsb256"
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmaxsd;	 // "__builtin_ia32_pmaxsd128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxs_d;	 // "__builtin_ia32_pmaxsd256"
+                }
+                break;
+              case 'w':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse2_pmaxs_w;	 // "__builtin_ia32_pmaxsw128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxs_w;	 // "__builtin_ia32_pmaxsw256"
+                }
+                break;
+              }
+              break;
+            case 'u':	 // 6 strings to match.
+              switch (BuiltinName[20]) {
+              default: break;
+              case 'b':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse2_pmaxu_b;	 // "__builtin_ia32_pmaxub128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxu_b;	 // "__builtin_ia32_pmaxub256"
+                }
+                break;
+              case 'd':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmaxud;	 // "__builtin_ia32_pmaxud128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxu_d;	 // "__builtin_ia32_pmaxud256"
+                }
+                break;
+              case 'w':	 // 2 strings to match.
+                switch (BuiltinName[21]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmaxuw;	 // "__builtin_ia32_pmaxuw128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+22, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmaxu_w;	 // "__builtin_ia32_pmaxuw256"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 12 strings to match.
+          if (BuiltinName[18] != 'n')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 6 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pminsb;	 // "__builtin_ia32_pminsb128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pmins_b;	 // "__builtin_ia32_pminsb256"
+              }
+              break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pminsd;	 // "__builtin_ia32_pminsd128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pmins_d;	 // "__builtin_ia32_pminsd256"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_pmins_w;	 // "__builtin_ia32_pminsw128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pmins_w;	 // "__builtin_ia32_pminsw256"
+              }
+              break;
+            }
+            break;
+          case 'u':	 // 6 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'b':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_pminu_b;	 // "__builtin_ia32_pminub128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pminu_b;	 // "__builtin_ia32_pminub256"
+              }
+              break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pminud;	 // "__builtin_ia32_pminud128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pminu_d;	 // "__builtin_ia32_pminud256"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pminuw;	 // "__builtin_ia32_pminuw128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pminu_w;	 // "__builtin_ia32_pminuw256"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (BuiltinName[20] != 'q')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse41_pmuldq;	 // "__builtin_ia32_pmuldq128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pmul_dq;	 // "__builtin_ia32_pmuldq256"
+            }
+            break;
+          case 'h':	 // 2 strings to match.
+            if (BuiltinName[20] != 'w')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pmulh_w;	 // "__builtin_ia32_pmulhw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pmulh_w;	 // "__builtin_ia32_pmulhw256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 30 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "dbw", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_psad_bw;	 // "__builtin_ia32_psadbw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_psad_bw;	 // "__builtin_ia32_psadbw256"
+          }
+          break;
+        case 'h':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ufb", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_ssse3_pshuf_b_128;	 // "__builtin_ia32_pshufb128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pshuf_b;	 // "__builtin_ia32_pshufb256"
+          }
+          break;
+        case 'i':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+18, "gn", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_psign_b_128;	 // "__builtin_ia32_psignb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psign_b;	 // "__builtin_ia32_psignb256"
+            }
+            break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_psign_d_128;	 // "__builtin_ia32_psignd128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psign_d;	 // "__builtin_ia32_psignd256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_ssse3_psign_w_128;	 // "__builtin_ia32_psignw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psign_w;	 // "__builtin_ia32_psignw256"
+            }
+            break;
+          }
+          break;
+        case 'l':	 // 6 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pslli_d;	 // "__builtin_ia32_pslldi128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pslli_d;	 // "__builtin_ia32_pslldi256"
+            }
+            break;
+          case 'q':	 // 2 strings to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pslli_q;	 // "__builtin_ia32_psllqi128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pslli_q;	 // "__builtin_ia32_psllqi256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            if (BuiltinName[20] != 'i')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pslli_w;	 // "__builtin_ia32_psllwi128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pslli_w;	 // "__builtin_ia32_psllwi256"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 10 strings to match.
+          switch (BuiltinName[18]) {
+          default: break;
+          case 'a':	 // 4 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrai_d;	 // "__builtin_ia32_psradi128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrai_d;	 // "__builtin_ia32_psradi256"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrai_w;	 // "__builtin_ia32_psrawi128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrai_w;	 // "__builtin_ia32_psrawi256"
+              }
+              break;
+            }
+            break;
+          case 'l':	 // 6 strings to match.
+            switch (BuiltinName[19]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrli_d;	 // "__builtin_ia32_psrldi128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrli_d;	 // "__builtin_ia32_psrldi256"
+              }
+              break;
+            case 'q':	 // 2 strings to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrli_q;	 // "__builtin_ia32_psrlqi128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrli_q;	 // "__builtin_ia32_psrlqi256"
+              }
+              break;
+            case 'w':	 // 2 strings to match.
+              if (BuiltinName[20] != 'i')
+                break;
+              switch (BuiltinName[21]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "28", 2))
+                  break;
+                return Intrinsic::x86_sse2_psrli_w;	 // "__builtin_ia32_psrlwi128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+22, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_psrli_w;	 // "__builtin_ia32_psrlwi256"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "bs", 2))
+            break;
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psubs_b;	 // "__builtin_ia32_psubsb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psubs_b;	 // "__builtin_ia32_psubsb256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psubs_w;	 // "__builtin_ia32_psubsw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psubs_w;	 // "__builtin_ia32_psubsw256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "est", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_sse41_ptestc;	 // "__builtin_ia32_ptestc128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx_ptestc_256;	 // "__builtin_ia32_ptestc256"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "28", 2))
+              break;
+            return Intrinsic::x86_sse41_ptestz;	 // "__builtin_ia32_ptestz128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "56", 2))
+              break;
+            return Intrinsic::x86_avx_ptestz_256;	 // "__builtin_ia32_ptestz256"
+          }
+          break;
+        }
+        break;
+      case 'u':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+17, "npck", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'h':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (BuiltinName[23] != 'w')
+              break;
+            return Intrinsic::x86_mmx_punpckhbw;	 // "__builtin_ia32_punpckhbw"
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[23] != 'q')
+              break;
+            return Intrinsic::x86_mmx_punpckhdq;	 // "__builtin_ia32_punpckhdq"
+          case 'w':	 // 1 string to match.
+            if (BuiltinName[23] != 'd')
+              break;
+            return Intrinsic::x86_mmx_punpckhwd;	 // "__builtin_ia32_punpckhwd"
+          }
+          break;
+        case 'l':	 // 3 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'b':	 // 1 string to match.
+            if (BuiltinName[23] != 'w')
+              break;
+            return Intrinsic::x86_mmx_punpcklbw;	 // "__builtin_ia32_punpcklbw"
+          case 'd':	 // 1 string to match.
+            if (BuiltinName[23] != 'q')
+              break;
+            return Intrinsic::x86_mmx_punpckldq;	 // "__builtin_ia32_punpckldq"
+          case 'w':	 // 1 string to match.
+            if (BuiltinName[23] != 'd')
+              break;
+            return Intrinsic::x86_mmx_punpcklwd;	 // "__builtin_ia32_punpcklwd"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 8 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'h':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "a1", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'n':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "exte", 4))
+            break;
+          return Intrinsic::x86_sha1nexte;	 // "__builtin_ia32_sha1nexte"
+        case 'r':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "nds4", 4))
+            break;
+          return Intrinsic::x86_sha1rnds4;	 // "__builtin_ia32_sha1rnds4"
+        }
+        break;
+      case 'q':	 // 6 strings to match.
+        if (memcmp(BuiltinName.data()+17, "rt", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'p':	 // 4 strings to match.
+          switch (BuiltinName[20]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx_sqrt_pd_256;	 // "__builtin_ia32_sqrtpd256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "12", 2))
+                break;
+              return Intrinsic::x86_avx512_sqrt_pd_512;	 // "__builtin_ia32_sqrtpd512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[21]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "56", 2))
+                break;
+              return Intrinsic::x86_avx_sqrt_ps_256;	 // "__builtin_ia32_sqrtps256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+22, "12", 2))
+                break;
+              return Intrinsic::x86_avx512_sqrt_ps_512;	 // "__builtin_ia32_sqrtps512"
+            }
+            break;
+          }
+          break;
+        case 'r':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+20, "nds", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx512_sqrt_sd;	 // "__builtin_ia32_sqrtrndsd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_avx512_sqrt_ss;	 // "__builtin_ia32_sqrtrndss"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'u':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+16, "comisd", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'e':	 // 1 string to match.
+        if (BuiltinName[23] != 'q')
+          break;
+        return Intrinsic::x86_sse2_ucomieq_sd;	 // "__builtin_ia32_ucomisdeq"
+      case 'g':	 // 2 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse2_ucomige_sd;	 // "__builtin_ia32_ucomisdge"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse2_ucomigt_sd;	 // "__builtin_ia32_ucomisdgt"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          return Intrinsic::x86_sse2_ucomile_sd;	 // "__builtin_ia32_ucomisdle"
+        case 't':	 // 1 string to match.
+          return Intrinsic::x86_sse2_ucomilt_sd;	 // "__builtin_ia32_ucomisdlt"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 10 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "vtp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ps", 3))
+            break;
+          return Intrinsic::x86_vcvtph2ps_128;	 // "__builtin_ia32_vcvtph2ps"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ph", 3))
+            break;
+          return Intrinsic::x86_vcvtps2ph_128;	 // "__builtin_ia32_vcvtps2ph"
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+17, "nm", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "dd", 2))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_pd;	 // "__builtin_ia32_vfnmaddpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_ps;	 // "__builtin_ia32_vfnmaddps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_sd;	 // "__builtin_ia32_vfnmaddsd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmadd_ss;	 // "__builtin_ia32_vfnmaddss"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "ub", 2))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'p':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_pd;	 // "__builtin_ia32_vfnmsubpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_ps;	 // "__builtin_ia32_vfnmsubps"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_sd;	 // "__builtin_ia32_vfnmsubsd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfnmsub_ss;	 // "__builtin_ia32_vfnmsubss"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 25:	 // 73 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'b':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "xtri_u", 6))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (BuiltinName[24] != '2')
+            break;
+          return Intrinsic::x86_tbm_bextri_u32;	 // "__builtin_ia32_bextri_u32"
+        case '6':	 // 1 string to match.
+          if (BuiltinName[24] != '4')
+            break;
+          return Intrinsic::x86_tbm_bextri_u64;	 // "__builtin_ia32_bextri_u64"
+        }
+        break;
+      case 'l':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "endp", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "256", 3))
+            break;
+          return Intrinsic::x86_avx_blend_pd_256;	 // "__builtin_ia32_blendpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "256", 3))
+            break;
+          return Intrinsic::x86_avx_blend_ps_256;	 // "__builtin_ia32_blendps256"
+        }
+        break;
+      }
+      break;
+    case 'c':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vt", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 's':	 // 4 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2si64", 5))
+            break;
+          return Intrinsic::x86_sse2_cvtsd2si64;	 // "__builtin_ia32_cvtsd2si64"
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+20, "642s", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_sse2_cvtsi642sd;	 // "__builtin_ia32_cvtsi642sd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_sse_cvtsi642ss;	 // "__builtin_ia32_cvtsi642ss"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2si64", 5))
+            break;
+          return Intrinsic::x86_sse_cvtss2si64;	 // "__builtin_ia32_cvtss2si64"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (BuiltinName[19] != 's')
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2usi", 4))
+            break;
+          return Intrinsic::x86_avx512_cvttsd2usi;	 // "__builtin_ia32_cvttsd2usi"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2usi", 4))
+            break;
+          return Intrinsic::x86_avx512_cvttss2usi;	 // "__builtin_ia32_cvttss2usi"
+        }
+        break;
+      }
+      break;
+    case 'g':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ather", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "_p", 2))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_d_pd;	 // "__builtin_ia32_gatherd_pd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_d_ps;	 // "__builtin_ia32_gatherd_ps"
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "_p", 2))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_q_pd;	 // "__builtin_ia32_gatherq_pd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx2_gather_q_ps;	 // "__builtin_ia32_gatherq_ps"
+        }
+        break;
+      }
+      break;
+    case 'k':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ortest", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'c':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "hi", 2))
+          break;
+        return Intrinsic::x86_avx512_kortestc_w;	 // "__builtin_ia32_kortestchi"
+      case 'z':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "hi", 2))
+          break;
+        return Intrinsic::x86_avx512_kortestz_w;	 // "__builtin_ia32_kortestzhi"
+      }
+      break;
+    case 'm':	 // 7 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 5 strings to match.
+        if (memcmp(BuiltinName.data()+17, "sk", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'l':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+20, "oadp", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx_maskload_pd;	 // "__builtin_ia32_maskloadpd"
+          case 's':	 // 1 string to match.
+            return Intrinsic::x86_avx_maskload_ps;	 // "__builtin_ia32_maskloadps"
+          }
+          break;
+        case 'm':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "ovdqu", 5))
+            break;
+          return Intrinsic::x86_sse2_maskmov_dqu;	 // "__builtin_ia32_maskmovdqu"
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+20, "tore", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            return Intrinsic::x86_avx2_maskstore_d;	 // "__builtin_ia32_maskstored"
+          case 'q':	 // 1 string to match.
+            return Intrinsic::x86_avx2_maskstore_q;	 // "__builtin_ia32_maskstoreq"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "sadbw", 5))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "28", 2))
+            break;
+          return Intrinsic::x86_sse41_mpsadbw;	 // "__builtin_ia32_mpsadbw128"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "56", 2))
+            break;
+          return Intrinsic::x86_avx2_mpsadbw;	 // "__builtin_ia32_mpsadbw256"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 30 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ddus", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_paddus_b;	 // "__builtin_ia32_paddusb128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_paddus_b;	 // "__builtin_ia32_paddusb256"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_paddus_w;	 // "__builtin_ia32_paddusw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_paddus_w;	 // "__builtin_ia32_paddusw256"
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "lend", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_avx2_pblendd_128;	 // "__builtin_ia32_pblendd128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pblendd_256;	 // "__builtin_ia32_pblendd256"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse41_pblendw;	 // "__builtin_ia32_pblendw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pblendw;	 // "__builtin_ia32_pblendw256"
+          }
+          break;
+        }
+        break;
+      case 'h':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ddsw", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_ssse3_phadd_sw_128;	 // "__builtin_ia32_phaddsw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_phadd_sw;	 // "__builtin_ia32_phaddsw256"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ubsw", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_ssse3_phsub_sw_128;	 // "__builtin_ia32_phsubsw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_phsub_sw;	 // "__builtin_ia32_phsubsw256"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 6 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ddwd", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_pmadd_wd;	 // "__builtin_ia32_pmaddwd128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pmadd_wd;	 // "__builtin_ia32_pmaddwd256"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[18] != 'l')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'h':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "uw", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pmulhu_w;	 // "__builtin_ia32_pmulhuw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pmulhu_w;	 // "__builtin_ia32_pmulhuw256"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "dq", 2))
+              break;
+            switch (BuiltinName[22]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pmulu_dq;	 // "__builtin_ia32_pmuludq128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pmulu_dq;	 // "__builtin_ia32_pmuludq256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 's':	 // 10 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'l':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ldqi", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_psll_dq;	 // "__builtin_ia32_pslldqi128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_psll_dq;	 // "__builtin_ia32_pslldqi256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_psll_dq;	 // "__builtin_ia32_pslldqi512"
+          }
+          break;
+        case 'r':	 // 3 strings to match.
+          if (memcmp(BuiltinName.data()+18, "ldqi", 4))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "28", 2))
+              break;
+            return Intrinsic::x86_sse2_psrl_dq;	 // "__builtin_ia32_psrldqi128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_psrl_dq;	 // "__builtin_ia32_psrldqi256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_psrl_dq;	 // "__builtin_ia32_psrldqi512"
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+18, "bus", 3))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'b':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psubus_b;	 // "__builtin_ia32_psubusb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psubus_b;	 // "__builtin_ia32_psubusb256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_psubus_w;	 // "__builtin_ia32_psubusw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+23, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_psubus_w;	 // "__builtin_ia32_psubusw256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "estm", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512", 3))
+            break;
+          return Intrinsic::x86_avx512_mask_ptestm_d_512;	 // "__builtin_ia32_ptestmd512"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512", 3))
+            break;
+          return Intrinsic::x86_avx512_mask_ptestm_q_512;	 // "__builtin_ia32_ptestmq512"
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 9 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'd':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'f':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "sbase", 5))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case '3':	 // 1 string to match.
+            if (BuiltinName[24] != '2')
+              break;
+            return Intrinsic::x86_rdfsbase_32;	 // "__builtin_ia32_rdfsbase32"
+          case '6':	 // 1 string to match.
+            if (BuiltinName[24] != '4')
+              break;
+            return Intrinsic::x86_rdfsbase_64;	 // "__builtin_ia32_rdfsbase64"
+          }
+          break;
+        case 'g':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "sbase", 5))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case '3':	 // 1 string to match.
+            if (BuiltinName[24] != '2')
+              break;
+            return Intrinsic::x86_rdgsbase_32;	 // "__builtin_ia32_rdgsbase32"
+          case '6':	 // 1 string to match.
+            if (BuiltinName[24] != '4')
+              break;
+            return Intrinsic::x86_rdgsbase_64;	 // "__builtin_ia32_rdgsbase64"
+          }
+          break;
+        }
+        break;
+      case 'n':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "dscales", 7))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_rndscale_sd;	 // "__builtin_ia32_rndscalesd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_rndscale_ss;	 // "__builtin_ia32_rndscaless"
+        }
+        break;
+      case 'o':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "undp", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "256", 3))
+            break;
+          return Intrinsic::x86_avx_round_pd_256;	 // "__builtin_ia32_roundpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "256", 3))
+            break;
+          return Intrinsic::x86_avx_round_ps_256;	 // "__builtin_ia32_roundps256"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "qrtps256", 8))
+          break;
+        return Intrinsic::x86_avx_rsqrt_ps_256;	 // "__builtin_ia32_rsqrtps256"
+      }
+      break;
+    case 's':	 // 3 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'h':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "a256msg", 7))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          return Intrinsic::x86_sha256msg1;	 // "__builtin_ia32_sha256msg1"
+        case '2':	 // 1 string to match.
+          return Intrinsic::x86_sha256msg2;	 // "__builtin_ia32_sha256msg2"
+        }
+        break;
+      case 't':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "orelv4si", 8))
+          break;
+        return Intrinsic::x86_sse2_storel_dq;	 // "__builtin_ia32_storelv4si"
+      }
+      break;
+    case 'u':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "comisdneq", 9))
+        break;
+      return Intrinsic::x86_sse2_ucomineq_sd;	 // "__builtin_ia32_ucomisdneq"
+    case 'v':	 // 3 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "estnzcp", 7))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx_vtestnzc_pd;	 // "__builtin_ia32_vtestnzcpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx_vtestnzc_ps;	 // "__builtin_ia32_vtestnzcps"
+        }
+        break;
+      case 'z':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "eroupper", 8))
+          break;
+        return Intrinsic::x86_avx_vzeroupper;	 // "__builtin_ia32_vzeroupper"
+      }
+      break;
+    case 'w':	 // 4 strings to match.
+      if (BuiltinName[16] != 'r')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'f':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "sbase", 5))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (BuiltinName[24] != '2')
+            break;
+          return Intrinsic::x86_wrfsbase_32;	 // "__builtin_ia32_wrfsbase32"
+        case '6':	 // 1 string to match.
+          if (BuiltinName[24] != '4')
+            break;
+          return Intrinsic::x86_wrfsbase_64;	 // "__builtin_ia32_wrfsbase64"
+        }
+        break;
+      case 'g':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+18, "sbase", 5))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case '3':	 // 1 string to match.
+          if (BuiltinName[24] != '2')
+            break;
+          return Intrinsic::x86_wrgsbase_32;	 // "__builtin_ia32_wrgsbase32"
+        case '6':	 // 1 string to match.
+          if (BuiltinName[24] != '4')
+            break;
+          return Intrinsic::x86_wrgsbase_64;	 // "__builtin_ia32_wrgsbase64"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 26:	 // 92 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ddsubp", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "256", 3))
+          break;
+        return Intrinsic::x86_avx_addsub_pd_256;	 // "__builtin_ia32_addsubpd256"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "256", 3))
+          break;
+        return Intrinsic::x86_avx_addsub_ps_256;	 // "__builtin_ia32_addsubps256"
+      }
+      break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "lendvp", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "256", 3))
+          break;
+        return Intrinsic::x86_avx_blendv_pd_256;	 // "__builtin_ia32_blendvpd256"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "256", 3))
+          break;
+        return Intrinsic::x86_avx_blendv_ps_256;	 // "__builtin_ia32_blendvps256"
+      }
+      break;
+    case 'c':	 // 12 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vt", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "q2p", 3))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "256", 3))
+            break;
+          return Intrinsic::x86_avx_cvtdq2_pd_256;	 // "__builtin_ia32_cvtdq2pd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "256", 3))
+            break;
+          return Intrinsic::x86_avx_cvtdq2_ps_256;	 // "__builtin_ia32_cvtdq2ps256"
+        }
+        break;
+      case 'p':	 // 4 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (BuiltinName[20] != '2')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "q256", 4))
+              break;
+            return Intrinsic::x86_avx_cvt_pd2dq_256;	 // "__builtin_ia32_cvtpd2dq256"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "s256", 4))
+              break;
+            return Intrinsic::x86_avx_cvt_pd2_ps_256;	 // "__builtin_ia32_cvtpd2ps256"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (BuiltinName[20] != '2')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "q256", 4))
+              break;
+            return Intrinsic::x86_avx_cvt_ps2dq_256;	 // "__builtin_ia32_cvtps2dq256"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "d256", 4))
+              break;
+            return Intrinsic::x86_avx_cvt_ps2_pd_256;	 // "__builtin_ia32_cvtps2pd256"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2usi64", 6))
+            break;
+          return Intrinsic::x86_avx512_cvtsd2usi64;	 // "__builtin_ia32_cvtsd2usi64"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2usi64", 6))
+            break;
+          return Intrinsic::x86_avx512_cvtss2usi64;	 // "__builtin_ia32_cvtss2usi64"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (BuiltinName[19] != 's')
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2si64", 5))
+            break;
+          return Intrinsic::x86_sse2_cvttsd2si64;	 // "__builtin_ia32_cvttsd2si64"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2si64", 5))
+            break;
+          return Intrinsic::x86_sse_cvttss2si64;	 // "__builtin_ia32_cvttss2si64"
+        }
+        break;
+      case 'u':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "si642s", 6))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_cvtusi642sd;	 // "__builtin_ia32_cvtusi642sd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_cvtusi642ss;	 // "__builtin_ia32_cvtusi642ss"
+        }
+        break;
+      }
+      break;
+    case 'g':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "atherpf", 7))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (BuiltinName[24] != 'p')
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gatherpf_dpd_512;	 // "__builtin_ia32_gatherpfdpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gatherpf_dps_512;	 // "__builtin_ia32_gatherpfdps"
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (BuiltinName[24] != 'p')
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gatherpf_qpd_512;	 // "__builtin_ia32_gatherpfqpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gatherpf_qps_512;	 // "__builtin_ia32_gatherpfqps"
+        }
+        break;
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "nsertps128", 10))
+        break;
+      return Intrinsic::x86_sse41_insertps;	 // "__builtin_ia32_insertps128"
+    case 'm':	 // 6 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "skstorep", 8))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx_maskstore_pd;	 // "__builtin_ia32_maskstorepd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx_maskstore_ps;	 // "__builtin_ia32_maskstoreps"
+        }
+        break;
+      case 'o':	 // 4 strings to match.
+        if (BuiltinName[17] != 'v')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'm':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "skp", 3))
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_movmsk_pd_256;	 // "__builtin_ia32_movmskpd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_movmsk_ps_256;	 // "__builtin_ia32_movmskps256"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+19, "tdqa", 4))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_movntdqa;	 // "__builtin_ia32_movntdqa256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_movntdqa;	 // "__builtin_ia32_movntdqa512"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 45 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ck", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          if (BuiltinName[20] != 's')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (BuiltinName[22] != 'w')
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_packssdw_128;	 // "__builtin_ia32_packssdw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_packssdw;	 // "__builtin_ia32_packssdw256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            if (BuiltinName[22] != 'b')
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_packsswb_128;	 // "__builtin_ia32_packsswb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_packsswb;	 // "__builtin_ia32_packsswb256"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 4 strings to match.
+          if (BuiltinName[20] != 's')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            if (BuiltinName[22] != 'w')
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "28", 2))
+                break;
+              return Intrinsic::x86_sse41_packusdw;	 // "__builtin_ia32_packusdw128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_packusdw;	 // "__builtin_ia32_packusdw256"
+            }
+            break;
+          case 'w':	 // 2 strings to match.
+            if (BuiltinName[22] != 'b')
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_packuswb_128;	 // "__builtin_ia32_packuswb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_packuswb;	 // "__builtin_ia32_packuswb256"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'b':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "lendvb", 6))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "28", 2))
+            break;
+          return Intrinsic::x86_sse41_pblendvb;	 // "__builtin_ia32_pblendvb128"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "56", 2))
+            break;
+          return Intrinsic::x86_avx2_pblendvb;	 // "__builtin_ia32_pblendvb256"
+        }
+        break;
+      case 'm':	 // 33 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'o':	 // 31 strings to match.
+          if (BuiltinName[18] != 'v')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'm':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "skb", 3))
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case '1':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "28", 2))
+                break;
+              return Intrinsic::x86_sse2_pmovmskb_128;	 // "__builtin_ia32_pmovmskb128"
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "56", 2))
+                break;
+              return Intrinsic::x86_avx2_pmovmskb;	 // "__builtin_ia32_pmovmskb256"
+            }
+            break;
+          case 's':	 // 12 strings to match.
+            if (BuiltinName[20] != 'x')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 6 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovsxbd;	 // "__builtin_ia32_pmovsxbd128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovsxbd;	 // "__builtin_ia32_pmovsxbd256"
+                }
+                break;
+              case 'q':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovsxbq;	 // "__builtin_ia32_pmovsxbq128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovsxbq;	 // "__builtin_ia32_pmovsxbq256"
+                }
+                break;
+              case 'w':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovsxbw;	 // "__builtin_ia32_pmovsxbw128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovsxbw;	 // "__builtin_ia32_pmovsxbw256"
+                }
+                break;
+              }
+              break;
+            case 'd':	 // 2 strings to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              switch (BuiltinName[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pmovsxdq;	 // "__builtin_ia32_pmovsxdq128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pmovsxdq;	 // "__builtin_ia32_pmovsxdq256"
+              }
+              break;
+            case 'w':	 // 4 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovsxwd;	 // "__builtin_ia32_pmovsxwd128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovsxwd;	 // "__builtin_ia32_pmovsxwd256"
+                }
+                break;
+              case 'q':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovsxwq;	 // "__builtin_ia32_pmovsxwq128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovsxwq;	 // "__builtin_ia32_pmovsxwq256"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          case 'z':	 // 17 strings to match.
+            if (BuiltinName[20] != 'x')
+              break;
+            switch (BuiltinName[21]) {
+            default: break;
+            case 'b':	 // 8 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 3 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovzxbd;	 // "__builtin_ia32_pmovzxbd128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovzxbd;	 // "__builtin_ia32_pmovzxbd256"
+                case '5':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "12", 2))
+                    break;
+                  return Intrinsic::x86_avx512_pmovzxbd;	 // "__builtin_ia32_pmovzxbd512"
+                }
+                break;
+              case 'q':	 // 3 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovzxbq;	 // "__builtin_ia32_pmovzxbq128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovzxbq;	 // "__builtin_ia32_pmovzxbq256"
+                case '5':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "12", 2))
+                    break;
+                  return Intrinsic::x86_avx512_pmovzxbq;	 // "__builtin_ia32_pmovzxbq512"
+                }
+                break;
+              case 'w':	 // 2 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovzxbw;	 // "__builtin_ia32_pmovzxbw128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovzxbw;	 // "__builtin_ia32_pmovzxbw256"
+                }
+                break;
+              }
+              break;
+            case 'd':	 // 3 strings to match.
+              if (BuiltinName[22] != 'q')
+                break;
+              switch (BuiltinName[23]) {
+              default: break;
+              case '1':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "28", 2))
+                  break;
+                return Intrinsic::x86_sse41_pmovzxdq;	 // "__builtin_ia32_pmovzxdq128"
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_avx2_pmovzxdq;	 // "__builtin_ia32_pmovzxdq256"
+              case '5':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "12", 2))
+                  break;
+                return Intrinsic::x86_avx512_pmovzxdq;	 // "__builtin_ia32_pmovzxdq512"
+              }
+              break;
+            case 'w':	 // 6 strings to match.
+              switch (BuiltinName[22]) {
+              default: break;
+              case 'd':	 // 3 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovzxwd;	 // "__builtin_ia32_pmovzxwd128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovzxwd;	 // "__builtin_ia32_pmovzxwd256"
+                case '5':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "12", 2))
+                    break;
+                  return Intrinsic::x86_avx512_pmovzxwd;	 // "__builtin_ia32_pmovzxwd512"
+                }
+                break;
+              case 'q':	 // 3 strings to match.
+                switch (BuiltinName[23]) {
+                default: break;
+                case '1':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "28", 2))
+                    break;
+                  return Intrinsic::x86_sse41_pmovzxwq;	 // "__builtin_ia32_pmovzxwq128"
+                case '2':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "56", 2))
+                    break;
+                  return Intrinsic::x86_avx2_pmovzxwq;	 // "__builtin_ia32_pmovzxwq256"
+                case '5':	 // 1 string to match.
+                  if (memcmp(BuiltinName.data()+24, "12", 2))
+                    break;
+                  return Intrinsic::x86_avx512_pmovzxwq;	 // "__builtin_ia32_pmovzxwq512"
+                }
+                break;
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+18, "lhrsw", 5))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "28", 2))
+              break;
+            return Intrinsic::x86_ssse3_pmul_hr_sw_128;	 // "__builtin_ia32_pmulhrsw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pmul_hr_sw;	 // "__builtin_ia32_pmulhrsw256"
+          }
+          break;
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "estnzc", 6))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "28", 2))
+            break;
+          return Intrinsic::x86_sse41_ptestnzc;	 // "__builtin_ia32_ptestnzc128"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "56", 2))
+            break;
+          return Intrinsic::x86_avx_ptestnzc_256;	 // "__builtin_ia32_ptestnzc256"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "a256rnds2", 9))
+          break;
+        return Intrinsic::x86_sha256rnds2;	 // "__builtin_ia32_sha256rnds2"
+      case 't':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ore", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "qu256", 5))
+            break;
+          return Intrinsic::x86_avx_storeu_dq_256;	 // "__builtin_ia32_storedqu256"
+        case 'u':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_storeu_pd_256;	 // "__builtin_ia32_storeupd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_storeu_ps_256;	 // "__builtin_ia32_storeups256"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 16 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'f':	 // 12 strings to match.
+        if (BuiltinName[17] != 'm')
+          break;
+        switch (BuiltinName[18]) {
+        default: break;
+        case 'a':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+19, "dd", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'p':	 // 4 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmadd_pd_256;	 // "__builtin_ia32_vfmaddpd256"
+              case '5':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "12", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmadd_pd_512;	 // "__builtin_ia32_vfmaddpd512"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmadd_ps_256;	 // "__builtin_ia32_vfmaddps256"
+              case '5':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "12", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmadd_ps_512;	 // "__builtin_ia32_vfmaddps512"
+              }
+              break;
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+22, "ubp", 3))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmaddsub_pd;	 // "__builtin_ia32_vfmaddsubpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmaddsub_ps;	 // "__builtin_ia32_vfmaddsubps"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 6 strings to match.
+          if (memcmp(BuiltinName.data()+19, "ub", 2))
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'a':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+22, "ddp", 3))
+              break;
+            switch (BuiltinName[25]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsubadd_pd;	 // "__builtin_ia32_vfmsubaddpd"
+            case 's':	 // 1 string to match.
+              return Intrinsic::x86_fma_vfmsubadd_ps;	 // "__builtin_ia32_vfmsubaddps"
+            }
+            break;
+          case 'p':	 // 4 strings to match.
+            switch (BuiltinName[22]) {
+            default: break;
+            case 'd':	 // 2 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmsub_pd_256;	 // "__builtin_ia32_vfmsubpd256"
+              case '5':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "12", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmsub_pd_512;	 // "__builtin_ia32_vfmsubpd512"
+              }
+              break;
+            case 's':	 // 2 strings to match.
+              switch (BuiltinName[23]) {
+              default: break;
+              case '2':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "56", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmsub_ps_256;	 // "__builtin_ia32_vfmsubps256"
+              case '5':	 // 1 string to match.
+                if (memcmp(BuiltinName.data()+24, "12", 2))
+                  break;
+                return Intrinsic::x86_fma_vfmsub_ps_512;	 // "__builtin_ia32_vfmsubps512"
+              }
+              break;
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 't':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "est", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'c':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vtestc_pd_256;	 // "__builtin_ia32_vtestcpd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vtestc_ps_256;	 // "__builtin_ia32_vtestcps256"
+          }
+          break;
+        case 'z':	 // 2 strings to match.
+          if (BuiltinName[21] != 'p')
+            break;
+          switch (BuiltinName[22]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vtestz_pd_256;	 // "__builtin_ia32_vtestzpd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+23, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vtestz_ps_256;	 // "__builtin_ia32_vtestzps256"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 27:	 // 48 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'c':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vtt", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'p':	 // 2 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2dq256", 6))
+            break;
+          return Intrinsic::x86_avx_cvtt_pd2dq_256;	 // "__builtin_ia32_cvttpd2dq256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2dq256", 6))
+            break;
+          return Intrinsic::x86_avx_cvtt_ps2dq_256;	 // "__builtin_ia32_cvttps2dq256"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2usi64", 6))
+            break;
+          return Intrinsic::x86_avx512_cvttsd2usi64;	 // "__builtin_ia32_cvttsd2usi64"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2usi64", 6))
+            break;
+          return Intrinsic::x86_avx512_cvttss2usi64;	 // "__builtin_ia32_cvttss2usi64"
+        }
+        break;
+      }
+      break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "xtractps128", 11))
+        break;
+      return Intrinsic::x86_sse41_extractps;	 // "__builtin_ia32_extractps128"
+    case 'g':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ather", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 4 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case '_':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "256", 3))
+              break;
+            return Intrinsic::x86_avx2_gather_d_d_256;	 // "__builtin_ia32_gatherd_d256"
+          case 'q':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "256", 3))
+              break;
+            return Intrinsic::x86_avx2_gather_d_q_256;	 // "__builtin_ia32_gatherd_q256"
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+23, "v8d", 3))
+            break;
+          switch (BuiltinName[26]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            return Intrinsic::x86_avx512_gather_qpd_512;	 // "__builtin_ia32_gatherdiv8df"
+          case 'i':	 // 1 string to match.
+            return Intrinsic::x86_avx512_gather_qpq_512;	 // "__builtin_ia32_gatherdiv8di"
+          }
+          break;
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (BuiltinName[22] != '_')
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_gather_q_d_256;	 // "__builtin_ia32_gatherq_d256"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_gather_q_q_256;	 // "__builtin_ia32_gatherq_q256"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "iv8d", 4))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gather_dpd_512;	 // "__builtin_ia32_gathersiv8df"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gather_dpq_512;	 // "__builtin_ia32_gathersiv8di"
+        }
+        break;
+      }
+      break;
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "askload", 7))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "256", 3))
+          break;
+        return Intrinsic::x86_avx2_maskload_d_256;	 // "__builtin_ia32_maskloadd256"
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "256", 3))
+          break;
+        return Intrinsic::x86_avx2_maskload_q_256;	 // "__builtin_ia32_maskloadq256"
+      }
+      break;
+    case 'p':	 // 9 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 5 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'l':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "mulqdq128", 9))
+            break;
+          return Intrinsic::x86_pclmulqdq;	 // "__builtin_ia32_pclmulqdq128"
+        case 'm':	 // 4 strings to match.
+          if (BuiltinName[18] != 'p')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'e':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "str", 3))
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpestri128;	 // "__builtin_ia32_pcmpestri128"
+            case 'm':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpestrm128;	 // "__builtin_ia32_pcmpestrm128"
+            }
+            break;
+          case 'i':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "str", 3))
+              break;
+            switch (BuiltinName[23]) {
+            default: break;
+            case 'i':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpistri128;	 // "__builtin_ia32_pcmpistri128"
+            case 'm':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+24, "128", 3))
+                break;
+              return Intrinsic::x86_sse42_pcmpistrm128;	 // "__builtin_ia32_pcmpistrm128"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "rmvars", 6))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_permps;	 // "__builtin_ia32_permvarsf256"
+        case 'i':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_permd;	 // "__builtin_ia32_permvarsi256"
+        }
+        break;
+      case 'm':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "addubsw", 7))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "28", 2))
+            break;
+          return Intrinsic::x86_ssse3_pmadd_ub_sw_128;	 // "__builtin_ia32_pmaddubsw128"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "56", 2))
+            break;
+          return Intrinsic::x86_avx2_pmadd_ub_sw;	 // "__builtin_ia32_pmaddubsw256"
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+16, "cp", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case '1':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "4s", 2))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_rcp14_sd;	 // "__builtin_ia32_rcp14sd_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_rcp14_ss;	 // "__builtin_ia32_rcp14ss_mask"
+        }
+        break;
+      case '2':	 // 4 strings to match.
+        if (BuiltinName[19] != '8')
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rcp28_pd;	 // "__builtin_ia32_rcp28pd_mask"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rcp28_ps;	 // "__builtin_ia32_rcp28ps_mask"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rcp28_sd;	 // "__builtin_ia32_rcp28sd_mask"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rcp28_ss;	 // "__builtin_ia32_rcp28ss_mask"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "catterpf", 8))
+        break;
+      switch (BuiltinName[24]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (BuiltinName[25] != 'p')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatterpf_dpd_512;	 // "__builtin_ia32_scatterpfdpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatterpf_dps_512;	 // "__builtin_ia32_scatterpfdps"
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (BuiltinName[25] != 'p')
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatterpf_qpd_512;	 // "__builtin_ia32_scatterpfqpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatterpf_qps_512;	 // "__builtin_ia32_scatterpfqps"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 14 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "vtp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ps256", 6))
+            break;
+          return Intrinsic::x86_vcvtph2ps_256;	 // "__builtin_ia32_vcvtph2ps256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ph256", 6))
+            break;
+          return Intrinsic::x86_vcvtps2ph_256;	 // "__builtin_ia32_vcvtps2ph256"
+        }
+        break;
+      case 'e':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "c_", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'e':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "xt_v4hi", 7))
+            break;
+          return Intrinsic::x86_mmx_pextr_w;	 // "__builtin_ia32_vec_ext_v4hi"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "et_v4hi", 7))
+            break;
+          return Intrinsic::x86_mmx_pinsr_w;	 // "__builtin_ia32_vec_set_v4hi"
+        }
+        break;
+      case 'f':	 // 8 strings to match.
+        if (memcmp(BuiltinName.data()+17, "nm", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "ddp", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_pd_256;	 // "__builtin_ia32_vfnmaddpd256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_pd_512;	 // "__builtin_ia32_vfnmaddpd512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_ps_256;	 // "__builtin_ia32_vfnmaddps256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmadd_ps_512;	 // "__builtin_ia32_vfnmaddps512"
+            }
+            break;
+          }
+          break;
+        case 's':	 // 4 strings to match.
+          if (memcmp(BuiltinName.data()+20, "ubp", 3))
+            break;
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_pd_256;	 // "__builtin_ia32_vfnmsubpd256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_pd_512;	 // "__builtin_ia32_vfnmsubpd512"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[24]) {
+            default: break;
+            case '2':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "56", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_ps_256;	 // "__builtin_ia32_vfnmsubps256"
+            case '5':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "12", 2))
+                break;
+              return Intrinsic::x86_fma_vfnmsub_ps_512;	 // "__builtin_ia32_vfnmsubps512"
+            }
+            break;
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ermilvarp", 9))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          return Intrinsic::x86_avx_vpermilvar_pd;	 // "__builtin_ia32_vpermilvarpd"
+        case 's':	 // 1 string to match.
+          return Intrinsic::x86_avx_vpermilvar_ps;	 // "__builtin_ia32_vpermilvarps"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 28:	 // 42 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "es", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "eclast128", 9))
+          break;
+        return Intrinsic::x86_aesni_aesdeclast;	 // "__builtin_ia32_aesdeclast128"
+      case 'e':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+19, "nclast128", 9))
+          break;
+        return Intrinsic::x86_aesni_aesenclast;	 // "__builtin_ia32_aesenclast128"
+      }
+      break;
+    case 'c':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "mpp", 3))
+        break;
+      switch (BuiltinName[19]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_cmp_pd_512;	 // "__builtin_ia32_cmppd512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_cmp_ps_512;	 // "__builtin_ia32_cmpps512_mask"
+      }
+      break;
+    case 'g':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+16, "ather", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 4 strings to match.
+        switch (BuiltinName[22]) {
+        default: break;
+        case '_':	 // 2 strings to match.
+          if (BuiltinName[23] != 'p')
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "256", 3))
+              break;
+            return Intrinsic::x86_avx2_gather_d_pd_256;	 // "__builtin_ia32_gatherd_pd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "256", 3))
+              break;
+            return Intrinsic::x86_avx2_gather_d_ps_256;	 // "__builtin_ia32_gatherd_ps256"
+          }
+          break;
+        case 'i':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+23, "v16s", 4))
+            break;
+          switch (BuiltinName[27]) {
+          default: break;
+          case 'f':	 // 1 string to match.
+            return Intrinsic::x86_avx512_gather_qps_512;	 // "__builtin_ia32_gatherdiv16sf"
+          case 'i':	 // 1 string to match.
+            return Intrinsic::x86_avx512_gather_qpi_512;	 // "__builtin_ia32_gatherdiv16si"
+          }
+          break;
+        }
+        break;
+      case 'q':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "_p", 2))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_gather_q_pd_256;	 // "__builtin_ia32_gatherq_pd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "256", 3))
+            break;
+          return Intrinsic::x86_avx2_gather_q_ps_256;	 // "__builtin_ia32_gatherq_ps256"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+22, "iv16s", 5))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gather_dps_512;	 // "__builtin_ia32_gathersiv16sf"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_gather_dpi_512;	 // "__builtin_ia32_gathersiv16si"
+        }
+        break;
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "nsert128i256", 12))
+        break;
+      return Intrinsic::x86_avx2_vinserti128;	 // "__builtin_ia32_insert128i256"
+    case 'm':	 // 8 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 6 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 's':	 // 4 strings to match.
+          if (BuiltinName[18] != 'k')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'l':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "oadp", 4))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "256", 3))
+                break;
+              return Intrinsic::x86_avx_maskload_pd_256;	 // "__builtin_ia32_maskloadpd256"
+            case 's':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "256", 3))
+                break;
+              return Intrinsic::x86_avx_maskload_ps_256;	 // "__builtin_ia32_maskloadps256"
+            }
+            break;
+          case 's':	 // 2 strings to match.
+            if (memcmp(BuiltinName.data()+20, "tore", 4))
+              break;
+            switch (BuiltinName[24]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "256", 3))
+                break;
+              return Intrinsic::x86_avx2_maskstore_d_256;	 // "__builtin_ia32_maskstored256"
+            case 'q':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+25, "256", 3))
+                break;
+              return Intrinsic::x86_avx2_maskstore_q_256;	 // "__builtin_ia32_maskstoreq256"
+            }
+            break;
+          }
+          break;
+        case 'x':	 // 2 strings to match.
+          if (BuiltinName[18] != 'p')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_max_pd_512;	 // "__builtin_ia32_maxpd512_mask"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_max_ps_512;	 // "__builtin_ia32_maxps512_mask"
+          }
+          break;
+        }
+        break;
+      case 'i':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "np", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_min_pd_512;	 // "__builtin_ia32_minpd512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_min_ps_512;	 // "__builtin_ia32_minps512_mask"
+        }
+        break;
+      }
+      break;
+    case 'p':	 // 15 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          if (BuiltinName[18] != 's')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_pabs_d_512;	 // "__builtin_ia32_pabsd512_mask"
+          case 'q':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_pabs_q_512;	 // "__builtin_ia32_pabsq512_mask"
+          }
+          break;
+        case 'n':	 // 2 strings to match.
+          if (BuiltinName[18] != 'd')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_pand_d_512;	 // "__builtin_ia32_pandd512_mask"
+          case 'q':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+20, "512_mask", 8))
+              break;
+            return Intrinsic::x86_avx512_mask_pand_q_512;	 // "__builtin_ia32_pandq512_mask"
+          }
+          break;
+        }
+        break;
+      case 'c':	 // 10 strings to match.
+        if (memcmp(BuiltinName.data()+17, "mp", 2))
+          break;
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'e':	 // 5 strings to match.
+          if (memcmp(BuiltinName.data()+20, "stri", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestria128;	 // "__builtin_ia32_pcmpestria128"
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestric128;	 // "__builtin_ia32_pcmpestric128"
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestrio128;	 // "__builtin_ia32_pcmpestrio128"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestris128;	 // "__builtin_ia32_pcmpestris128"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpestriz128;	 // "__builtin_ia32_pcmpestriz128"
+          }
+          break;
+        case 'i':	 // 5 strings to match.
+          if (memcmp(BuiltinName.data()+20, "stri", 4))
+            break;
+          switch (BuiltinName[24]) {
+          default: break;
+          case 'a':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistria128;	 // "__builtin_ia32_pcmpistria128"
+          case 'c':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistric128;	 // "__builtin_ia32_pcmpistric128"
+          case 'o':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistrio128;	 // "__builtin_ia32_pcmpistrio128"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistris128;	 // "__builtin_ia32_pcmpistris128"
+          case 'z':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+25, "128", 3))
+              break;
+            return Intrinsic::x86_sse42_pcmpistriz128;	 // "__builtin_ia32_pcmpistriz128"
+          }
+          break;
+        }
+        break;
+      case 'h':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "minposuw128", 11))
+          break;
+        return Intrinsic::x86_sse41_phminposuw;	 // "__builtin_ia32_phminposuw128"
+      }
+      break;
+    case 's':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "catter", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+23, "iv8d", 4))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_qpd_512;	 // "__builtin_ia32_scatterdiv8df"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_qpq_512;	 // "__builtin_ia32_scatterdiv8di"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+23, "iv8d", 4))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_dpd_512;	 // "__builtin_ia32_scattersiv8df"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_dpq_512;	 // "__builtin_ia32_scattersiv8di"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "testnzcp", 8))
+        break;
+      switch (BuiltinName[24]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+25, "256", 3))
+          break;
+        return Intrinsic::x86_avx_vtestnzc_pd_256;	 // "__builtin_ia32_vtestnzcpd256"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+25, "256", 3))
+          break;
+        return Intrinsic::x86_avx_vtestnzc_ps_256;	 // "__builtin_ia32_vtestnzcps256"
+      }
+      break;
+    }
+    break;
+  case 29:	 // 40 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'e':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "xtract128i256", 13))
+        break;
+      return Intrinsic::x86_avx2_vextracti128;	 // "__builtin_ia32_extract128i256"
+    case 'm':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "askstorep", 9))
+        break;
+      switch (BuiltinName[25]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+26, "256", 3))
+          break;
+        return Intrinsic::x86_avx_maskstore_pd_256;	 // "__builtin_ia32_maskstorepd256"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+26, "256", 3))
+          break;
+        return Intrinsic::x86_avx_maskstore_ps_256;	 // "__builtin_ia32_maskstoreps256"
+      }
+      break;
+    case 'p':	 // 19 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'b':	 // 10 strings to match.
+        if (memcmp(BuiltinName.data()+17, "roadcast", 8))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'b':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "28", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastb_128;	 // "__builtin_ia32_pbroadcastb128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastb_256;	 // "__builtin_ia32_pbroadcastb256"
+          }
+          break;
+        case 'd':	 // 3 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "28", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastd_128;	 // "__builtin_ia32_pbroadcastd128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastd_256;	 // "__builtin_ia32_pbroadcastd256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_pbroadcastd_512;	 // "__builtin_ia32_pbroadcastd512"
+          }
+          break;
+        case 'q':	 // 3 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "28", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastq_128;	 // "__builtin_ia32_pbroadcastq128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastq_256;	 // "__builtin_ia32_pbroadcastq256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_pbroadcastq_512;	 // "__builtin_ia32_pbroadcastq512"
+          }
+          break;
+        case 'w':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '1':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "28", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastw_128;	 // "__builtin_ia32_pbroadcastw128"
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_pbroadcastw_256;	 // "__builtin_ia32_pbroadcastw256"
+          }
+          break;
+        }
+        break;
+      case 'm':	 // 9 strings to match.
+        switch (BuiltinName[17]) {
+        default: break;
+        case 'a':	 // 4 strings to match.
+          if (BuiltinName[18] != 'x')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmaxs_d_512;	 // "__builtin_ia32_pmaxsd512_mask"
+            case 'q':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmaxs_q_512;	 // "__builtin_ia32_pmaxsq512_mask"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmaxu_d_512;	 // "__builtin_ia32_pmaxud512_mask"
+            case 'q':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmaxu_q_512;	 // "__builtin_ia32_pmaxuq512_mask"
+            }
+            break;
+          }
+          break;
+        case 'i':	 // 4 strings to match.
+          if (BuiltinName[18] != 'n')
+            break;
+          switch (BuiltinName[19]) {
+          default: break;
+          case 's':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmins_d_512;	 // "__builtin_ia32_pminsd512_mask"
+            case 'q':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pmins_q_512;	 // "__builtin_ia32_pminsq512_mask"
+            }
+            break;
+          case 'u':	 // 2 strings to match.
+            switch (BuiltinName[20]) {
+            default: break;
+            case 'd':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pminu_d_512;	 // "__builtin_ia32_pminud512_mask"
+            case 'q':	 // 1 string to match.
+              if (memcmp(BuiltinName.data()+21, "512_mask", 8))
+                break;
+              return Intrinsic::x86_avx512_mask_pminu_q_512;	 // "__builtin_ia32_pminuq512_mask"
+            }
+            break;
+          }
+          break;
+        case 'u':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+18, "ldq512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_pmul_dq_512;	 // "__builtin_ia32_pmuldq512_mask"
+        }
+        break;
+      }
+      break;
+    case 'r':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+16, "sqrt", 4))
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case '1':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+21, "4s", 2))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_rsqrt14_sd;	 // "__builtin_ia32_rsqrt14sd_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_rsqrt14_ss;	 // "__builtin_ia32_rsqrt14ss_mask"
+        }
+        break;
+      case '2':	 // 4 strings to match.
+        if (BuiltinName[21] != '8')
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rsqrt28_pd;	 // "__builtin_ia32_rsqrt28pd_mask"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rsqrt28_ps;	 // "__builtin_ia32_rsqrt28ps_mask"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[23]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rsqrt28_sd;	 // "__builtin_ia32_rsqrt28sd_mask"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+24, "_mask", 5))
+              break;
+            return Intrinsic::x86_avx512_rsqrt28_ss;	 // "__builtin_ia32_rsqrt28ss_mask"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case 's':	 // 4 strings to match.
+      if (memcmp(BuiltinName.data()+16, "catter", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+23, "iv16s", 5))
+          break;
+        switch (BuiltinName[28]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_qps_512;	 // "__builtin_ia32_scatterdiv16sf"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_qpi_512;	 // "__builtin_ia32_scatterdiv16si"
+        }
+        break;
+      case 's':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+23, "iv16s", 5))
+          break;
+        switch (BuiltinName[28]) {
+        default: break;
+        case 'f':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_dps_512;	 // "__builtin_ia32_scattersiv16sf"
+        case 'i':	 // 1 string to match.
+          return Intrinsic::x86_avx512_scatter_dpi_512;	 // "__builtin_ia32_scattersiv16si"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 8 strings to match.
+      if (memcmp(BuiltinName.data()+16, "fm", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'a':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+19, "ddsubp", 6))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_fma_vfmaddsub_pd_256;	 // "__builtin_ia32_vfmaddsubpd256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_fma_vfmaddsub_pd_512;	 // "__builtin_ia32_vfmaddsubpd512"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_fma_vfmaddsub_ps_256;	 // "__builtin_ia32_vfmaddsubps256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_fma_vfmaddsub_ps_512;	 // "__builtin_ia32_vfmaddsubps512"
+          }
+          break;
+        }
+        break;
+      case 's':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+19, "ubaddp", 6))
+          break;
+        switch (BuiltinName[25]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_fma_vfmsubadd_pd_256;	 // "__builtin_ia32_vfmsubaddpd256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_fma_vfmsubadd_pd_512;	 // "__builtin_ia32_vfmsubaddpd512"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[26]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "56", 2))
+              break;
+            return Intrinsic::x86_fma_vfmsubadd_ps_256;	 // "__builtin_ia32_vfmsubaddps256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+27, "12", 2))
+              break;
+            return Intrinsic::x86_fma_vfmsubadd_ps_512;	 // "__builtin_ia32_vfmsubaddps512"
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 30:	 // 14 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'l':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "oadup", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_loadu_pd_512;	 // "__builtin_ia32_loadupd512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_loadu_ps_512;	 // "__builtin_ia32_loadups512_mask"
+      }
+      break;
+    case 'p':	 // 3 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "mpeq", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_pcmpeq_d_512;	 // "__builtin_ia32_pcmpeqd512_mask"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_pcmpeq_q_512;	 // "__builtin_ia32_pcmpeqq512_mask"
+        }
+        break;
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+17, "uludq512_mask", 13))
+          break;
+        return Intrinsic::x86_avx512_mask_pmulu_dq_512;	 // "__builtin_ia32_pmuludq512_mask"
+      }
+      break;
+    case 'r':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "p14p", 4))
+          break;
+        switch (BuiltinName[21]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_rcp14_pd_512;	 // "__builtin_ia32_rcp14pd512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+22, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_rcp14_ps_512;	 // "__builtin_ia32_rcp14ps512_mask"
+        }
+        break;
+      case 'n':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "dscalep", 7))
+          break;
+        switch (BuiltinName[24]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_mask_rndscale_pd_512;	 // "__builtin_ia32_rndscalepd_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+25, "_mask", 5))
+            break;
+          return Intrinsic::x86_avx512_mask_rndscale_ps_512;	 // "__builtin_ia32_rndscaleps_mask"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 5 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'b':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+17, "roadcasts", 9))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "512", 3))
+            break;
+          return Intrinsic::x86_avx512_vbroadcast_sd_512;	 // "__builtin_ia32_vbroadcastsd512"
+        case 's':	 // 2 strings to match.
+          switch (BuiltinName[27]) {
+          default: break;
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_vbroadcast_ss_512;	 // "__builtin_ia32_vbroadcastss512"
+          case '_':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+28, "ps", 2))
+              break;
+            return Intrinsic::x86_avx2_vbroadcast_ss_ps;	 // "__builtin_ia32_vbroadcastss_ps"
+          }
+          break;
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ermilvarp", 9))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vpermilvar_pd_256;	 // "__builtin_ia32_vpermilvarpd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vpermilvar_ps_256;	 // "__builtin_ia32_vpermilvarps256"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 31:	 // 12 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "lendm", 5))
+        break;
+      switch (BuiltinName[21]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "_512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_blend_d_512;	 // "__builtin_ia32_blendmd_512_mask"
+      case 'q':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+22, "_512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_blend_q_512;	 // "__builtin_ia32_blendmq_512_mask"
+      }
+      break;
+    case 'c':	 // 5 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vt", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'd':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "q2p", 3))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtdq2pd_512;	 // "__builtin_ia32_cvtdq2pd512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtdq2ps_512;	 // "__builtin_ia32_cvtdq2ps512_mask"
+        }
+        break;
+      case 'p':	 // 3 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (BuiltinName[20] != '2')
+            break;
+          switch (BuiltinName[21]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "q512_mask", 9))
+              break;
+            return Intrinsic::x86_avx512_mask_cvtpd2dq_512;	 // "__builtin_ia32_cvtpd2dq512_mask"
+          case 'p':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+22, "s512_mask", 9))
+              break;
+            return Intrinsic::x86_avx512_mask_cvtpd2ps_512;	 // "__builtin_ia32_cvtpd2ps512_mask"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2dq512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtps2dq_512;	 // "__builtin_ia32_cvtps2dq512_mask"
+        }
+        break;
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "toreup", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_storeu_pd_512;	 // "__builtin_ia32_storeupd512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_mask_storeu_ps_512;	 // "__builtin_ia32_storeups512_mask"
+      }
+      break;
+    case 'v':	 // 3 strings to match.
+      if (memcmp(BuiltinName.data()+16, "perm2f128_", 10))
+        break;
+      switch (BuiltinName[26]) {
+      default: break;
+      case 'p':	 // 2 strings to match.
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vperm2f128_pd_256;	 // "__builtin_ia32_vperm2f128_pd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vperm2f128_ps_256;	 // "__builtin_ia32_vperm2f128_ps256"
+        }
+        break;
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+27, "i256", 4))
+          break;
+        return Intrinsic::x86_avx_vperm2f128_si_256;	 // "__builtin_ia32_vperm2f128_si256"
+      }
+      break;
+    }
+    break;
+  case 32:	 // 19 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'b':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "lendmp", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "_512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_blend_pd_512;	 // "__builtin_ia32_blendmpd_512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "_512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_blend_ps_512;	 // "__builtin_ia32_blendmps_512_mask"
+      }
+      break;
+    case 'c':	 // 6 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vt", 2))
+        break;
+      switch (BuiltinName[18]) {
+      default: break;
+      case 'p':	 // 2 strings to match.
+        switch (BuiltinName[19]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2udq512_mask", 12))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtpd2udq_512;	 // "__builtin_ia32_cvtpd2udq512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+20, "2udq512_mask", 12))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtps2udq_512;	 // "__builtin_ia32_cvtps2udq512_mask"
+        }
+        break;
+      case 't':	 // 2 strings to match.
+        if (BuiltinName[19] != 'p')
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2dq512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_cvttpd2dq_512;	 // "__builtin_ia32_cvttpd2dq512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2dq512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_cvttps2dq_512;	 // "__builtin_ia32_cvttps2dq512_mask"
+        }
+        break;
+      case 'u':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+19, "dq2p", 4))
+          break;
+        switch (BuiltinName[23]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtudq2pd_512;	 // "__builtin_ia32_cvtudq2pd512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+24, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_cvtudq2ps_512;	 // "__builtin_ia32_cvtudq2ps512_mask"
+        }
+        break;
+      }
+      break;
+    case 'l':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "oaddqu", 6))
+        break;
+      switch (BuiltinName[22]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "i512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_loadu_q_512;	 // "__builtin_ia32_loaddqudi512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+23, "i512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_loadu_d_512;	 // "__builtin_ia32_loaddqusi512_mask"
+      }
+      break;
+    case 'r':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "sqrt14p", 7))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_rsqrt14_pd_512;	 // "__builtin_ia32_rsqrt14pd512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "512_mask", 8))
+          break;
+        return Intrinsic::x86_avx512_rsqrt14_ps_512;	 // "__builtin_ia32_rsqrt14ps512_mask"
+      }
+      break;
+    case 'v':	 // 7 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'c':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "vtp", 3))
+          break;
+        switch (BuiltinName[20]) {
+        default: break;
+        case 'h':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ps512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_vcvtph2ps_512;	 // "__builtin_ia32_vcvtph2ps512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+21, "2ph512_mask", 11))
+            break;
+          return Intrinsic::x86_avx512_mask_vcvtps2ph_512;	 // "__builtin_ia32_vcvtps2ph512_mask"
+        }
+        break;
+      case 'i':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+17, "nsertf128_", 10))
+          break;
+        switch (BuiltinName[27]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[28]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+29, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vinsertf128_pd_256;	 // "__builtin_ia32_vinsertf128_pd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+29, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vinsertf128_ps_256;	 // "__builtin_ia32_vinsertf128_ps256"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+28, "i256", 4))
+            break;
+          return Intrinsic::x86_avx_vinsertf128_si_256;	 // "__builtin_ia32_vinsertf128_si256"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "lzcnt", 5))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "_512_mask", 9))
+            break;
+          return Intrinsic::x86_avx512_mask_lzcnt_d_512;	 // "__builtin_ia32_vplzcntd_512_mask"
+        case 'q':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "_512_mask", 9))
+            break;
+          return Intrinsic::x86_avx512_mask_lzcnt_q_512;	 // "__builtin_ia32_vplzcntq_512_mask"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 33:	 // 12 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'a':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+16, "eskeygenassist128", 17))
+        break;
+      return Intrinsic::x86_aesni_aeskeygenassist;	 // "__builtin_ia32_aeskeygenassist128"
+    case 'c':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "vttp", 4))
+        break;
+      switch (BuiltinName[20]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "2udq512_mask", 12))
+          break;
+        return Intrinsic::x86_avx512_mask_cvttpd2udq_512;	 // "__builtin_ia32_cvttpd2udq512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+21, "2udq512_mask", 12))
+          break;
+        return Intrinsic::x86_avx512_mask_cvttps2udq_512;	 // "__builtin_ia32_cvttps2udq512_mask"
+      }
+      break;
+    case 's':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+16, "toredqu", 7))
+        break;
+      switch (BuiltinName[23]) {
+      default: break;
+      case 'd':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "i512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_storeu_q_512;	 // "__builtin_ia32_storedqudi512_mask"
+      case 's':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+24, "i512_mask", 9))
+          break;
+        return Intrinsic::x86_avx512_mask_storeu_d_512;	 // "__builtin_ia32_storedqusi512_mask"
+      }
+      break;
+    case 'v':	 // 7 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'b':	 // 4 strings to match.
+        if (memcmp(BuiltinName.data()+17, "roadcasts", 9))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "_pd", 3))
+            break;
+          switch (BuiltinName[30]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+31, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_vbroadcast_sd_pd_256;	 // "__builtin_ia32_vbroadcastsd_pd256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+31, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_vbroadcast_sd_pd_512;	 // "__builtin_ia32_vbroadcastsd_pd512"
+          }
+          break;
+        case 's':	 // 2 strings to match.
+          if (memcmp(BuiltinName.data()+27, "_ps", 3))
+            break;
+          switch (BuiltinName[30]) {
+          default: break;
+          case '2':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+31, "56", 2))
+              break;
+            return Intrinsic::x86_avx2_vbroadcast_ss_ps_256;	 // "__builtin_ia32_vbroadcastss_ps256"
+          case '5':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+31, "12", 2))
+              break;
+            return Intrinsic::x86_avx512_vbroadcast_ss_ps_512;	 // "__builtin_ia32_vbroadcastss_ps512"
+          }
+          break;
+        }
+        break;
+      case 'e':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+17, "xtractf128_", 11))
+          break;
+        switch (BuiltinName[28]) {
+        default: break;
+        case 'p':	 // 2 strings to match.
+          switch (BuiltinName[29]) {
+          default: break;
+          case 'd':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+30, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vextractf128_pd_256;	 // "__builtin_ia32_vextractf128_pd256"
+          case 's':	 // 1 string to match.
+            if (memcmp(BuiltinName.data()+30, "256", 3))
+              break;
+            return Intrinsic::x86_avx_vextractf128_ps_256;	 // "__builtin_ia32_vextractf128_ps256"
+          }
+          break;
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+29, "i256", 4))
+            break;
+          return Intrinsic::x86_avx_vextractf128_si_256;	 // "__builtin_ia32_vextractf128_si256"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 34:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_vpermt2var", 25))
+      break;
+    switch (BuiltinName[25]) {
+    default: break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+26, "512_mask", 8))
+        break;
+      return Intrinsic::x86_avx512_mask_vpermt_d_512;	 // "__builtin_ia32_vpermt2vard512_mask"
+    case 'q':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+26, "512_mask", 8))
+        break;
+      return Intrinsic::x86_avx512_mask_vpermt_q_512;	 // "__builtin_ia32_vpermt2varq512_mask"
+    }
+    break;
+  case 35:	 // 10 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_", 15))
+      break;
+    switch (BuiltinName[15]) {
+    default: break;
+    case 'p':	 // 6 strings to match.
+      if (BuiltinName[16] != 's')
+        break;
+      switch (BuiltinName[17]) {
+      default: break;
+      case 'l':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+18, "ldqi", 4))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "28_byteshift", 12))
+            break;
+          return Intrinsic::x86_sse2_psll_dq_bs;	 // "__builtin_ia32_pslldqi128_byteshift"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "56_byteshift", 12))
+            break;
+          return Intrinsic::x86_avx2_psll_dq_bs;	 // "__builtin_ia32_pslldqi256_byteshift"
+        case '5':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "12_byteshift", 12))
+            break;
+          return Intrinsic::x86_avx512_psll_dq_bs;	 // "__builtin_ia32_pslldqi512_byteshift"
+        }
+        break;
+      case 'r':	 // 3 strings to match.
+        if (memcmp(BuiltinName.data()+18, "ldqi", 4))
+          break;
+        switch (BuiltinName[22]) {
+        default: break;
+        case '1':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "28_byteshift", 12))
+            break;
+          return Intrinsic::x86_sse2_psrl_dq_bs;	 // "__builtin_ia32_psrldqi128_byteshift"
+        case '2':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "56_byteshift", 12))
+            break;
+          return Intrinsic::x86_avx2_psrl_dq_bs;	 // "__builtin_ia32_psrldqi256_byteshift"
+        case '5':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+23, "12_byteshift", 12))
+            break;
+          return Intrinsic::x86_avx512_psrl_dq_bs;	 // "__builtin_ia32_psrldqi512_byteshift"
+        }
+        break;
+      }
+      break;
+    case 'v':	 // 4 strings to match.
+      switch (BuiltinName[16]) {
+      default: break;
+      case 'b':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "roadcastf128_p", 14))
+          break;
+        switch (BuiltinName[31]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+32, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vbroadcastf128_pd_256;	 // "__builtin_ia32_vbroadcastf128_pd256"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+32, "256", 3))
+            break;
+          return Intrinsic::x86_avx_vbroadcastf128_ps_256;	 // "__builtin_ia32_vbroadcastf128_ps256"
+        }
+        break;
+      case 'p':	 // 2 strings to match.
+        if (memcmp(BuiltinName.data()+17, "ermt2varp", 9))
+          break;
+        switch (BuiltinName[26]) {
+        default: break;
+        case 'd':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_vpermt_pd_512;	 // "__builtin_ia32_vpermt2varpd512_mask"
+        case 's':	 // 1 string to match.
+          if (memcmp(BuiltinName.data()+27, "512_mask", 8))
+            break;
+          return Intrinsic::x86_avx512_mask_vpermt_ps_512;	 // "__builtin_ia32_vpermt2varps512_mask"
+        }
+        break;
+      }
+      break;
+    }
+    break;
+  case 36:	 // 2 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_vpconflict", 25))
+      break;
+    switch (BuiltinName[25]) {
+    default: break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+26, "i_512_mask", 10))
+        break;
+      return Intrinsic::x86_avx512_mask_conflict_q_512;	 // "__builtin_ia32_vpconflictdi_512_mask"
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+26, "i_512_mask", 10))
+        break;
+      return Intrinsic::x86_avx512_mask_conflict_d_512;	 // "__builtin_ia32_vpconflictsi_512_mask"
+    }
+    break;
+  case 38:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_ia32_pbroadcast", 25))
+      break;
+    switch (BuiltinName[25]) {
+    default: break;
+    case 'd':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+26, "512_gpr_mask", 12))
+        break;
+      return Intrinsic::x86_avx512_mask_pbroadcast_d_gpr_512;	 // "__builtin_ia32_pbroadcastd512_gpr_mask"
+    case 'q':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+26, "512_", 4))
+        break;
+      switch (BuiltinName[30]) {
+      default: break;
+      case 'g':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+31, "pr_mask", 7))
+          break;
+        return Intrinsic::x86_avx512_mask_pbroadcast_q_gpr_512;	 // "__builtin_ia32_pbroadcastq512_gpr_mask"
+      case 'm':	 // 1 string to match.
+        if (memcmp(BuiltinName.data()+31, "em_mask", 7))
+          break;
+        return Intrinsic::x86_avx512_mask_pbroadcast_q_mem_512;	 // "__builtin_ia32_pbroadcastq512_mem_mask"
+      }
+      break;
+    }
+    break;
+  }
+  }
+  if (TargetPrefix == "xcore") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 15:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_", 10))
+      break;
+    switch (BuiltinName[10]) {
+    default: break;
+    case 'g':	 // 2 strings to match.
+      if (memcmp(BuiltinName.data()+11, "et", 2))
+        break;
+      switch (BuiltinName[13]) {
+      default: break;
+      case 'i':	 // 1 string to match.
+        if (BuiltinName[14] != 'd')
+          break;
+        return Intrinsic::xcore_getid;	 // "__builtin_getid"
+      case 'p':	 // 1 string to match.
+        if (BuiltinName[14] != 's')
+          break;
+        return Intrinsic::xcore_getps;	 // "__builtin_getps"
+      }
+      break;
+    case 's':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+11, "etps", 4))
+        break;
+      return Intrinsic::xcore_setps;	 // "__builtin_setps"
+    }
+    break;
+  case 16:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "__builtin_bitrev", 16))
+      break;
+    return Intrinsic::xcore_bitrev;	 // "__builtin_bitrev"
+  }
+  }
+  return Intrinsic::not_intrinsic;
+}
+#endif
+
+// Get the LLVM intrinsic that corresponds to a MS builtin.
+// This is used by the C front-end.  The MS builtin name is passed
+// in as a BuiltinName, and a target prefix (e.g. 'arm') is passed
+// in as a TargetPrefix.  The result is assigned to 'IntrinsicID'.
+#ifdef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
+Intrinsic::ID Intrinsic::getIntrinsicForMSBuiltin(const char *TP, const char *BN) {
+  StringRef BuiltinName(BN);
+  StringRef TargetPrefix(TP);
+
+  if (TargetPrefix == "arm") {
+  switch (BuiltinName.size()) {
+  default: break;
+  case 5:	 // 3 strings to match.
+    if (memcmp(BuiltinName.data()+0, "__", 2))
+      break;
+    switch (BuiltinName[2]) {
+    default: break;
+    case 'd':	 // 2 strings to match.
+      switch (BuiltinName[3]) {
+      default: break;
+      case 'm':	 // 1 string to match.
+        if (BuiltinName[4] != 'b')
+          break;
+        return Intrinsic::arm_dmb;	 // "__dmb"
+      case 's':	 // 1 string to match.
+        if (BuiltinName[4] != 'b')
+          break;
+        return Intrinsic::arm_dsb;	 // "__dsb"
+      }
+      break;
+    case 'i':	 // 1 string to match.
+      if (memcmp(BuiltinName.data()+3, "sb", 2))
+        break;
+      return Intrinsic::arm_isb;	 // "__isb"
+    }
+    break;
+  case 18:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "_MoveToCoprocessor", 18))
+      break;
+    return Intrinsic::arm_mcr;	 // "_MoveToCoprocessor"
+  case 19:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "_MoveToCoprocessor2", 19))
+      break;
+    return Intrinsic::arm_mcr2;	 // "_MoveToCoprocessor2"
+  case 20:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "_MoveFromCoprocessor", 20))
+      break;
+    return Intrinsic::arm_mrc;	 // "_MoveFromCoprocessor"
+  case 21:	 // 1 string to match.
+    if (memcmp(BuiltinName.data()+0, "_MoveFromCoprocessor2", 21))
+      break;
+    return Intrinsic::arm_mrc2;	 // "_MoveFromCoprocessor2"
+  }
+}  return Intrinsic::not_intrinsic;
+}
+#endif
+
+#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)
+// let's return it to _setjmp state
+#  pragma pop_macro("setjmp")
+#  undef setjmp_undefined_for_msvc
+#endif
+
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
new file mode 100644
index 0000000..b0d746b
--- /dev/null
+++ b/include/llvm/IR/Intrinsics.h
@@ -0,0 +1,129 @@
+//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- 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 set of enums which allow processing of intrinsic
+// functions.  Values of these enum types are returned by
+// Function::getIntrinsicID.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_INTRINSICS_H
+#define LLVM_IR_INTRINSICS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include <string>
+
+namespace llvm {
+
+class Type;
+class FunctionType;
+class Function;
+class LLVMContext;
+class Module;
+class AttributeSet;
+
+/// Intrinsic Namespace - This namespace contains an enum with a value for
+/// every intrinsic/builtin function known by LLVM.  These enum values are
+/// returned by Function::getIntrinsicID().
+///
+namespace Intrinsic {
+  enum ID {
+    not_intrinsic = 0,   // Must be zero
+
+    // Get the intrinsic enums generated from Intrinsics.td
+#define GET_INTRINSIC_ENUM_VALUES
+#include "llvm/IR/Intrinsics.gen"
+#undef GET_INTRINSIC_ENUM_VALUES
+    , num_intrinsics
+  };
+  
+  /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
+  /// "llvm.ppc.altivec.lvx".
+  std::string getName(ID id, ArrayRef<Type*> Tys = None);
+
+  /// Intrinsic::getType(ID) - Return the function type for an intrinsic.
+  ///
+  FunctionType *getType(LLVMContext &Context, ID id,
+                        ArrayRef<Type*> Tys = None);
+
+  /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be
+  /// overloaded.
+  bool isOverloaded(ID id);
+
+  /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic.
+  ///
+  AttributeSet getAttributes(LLVMContext &C, ID id);
+
+  /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
+  /// declaration for an intrinsic, and return it.
+  ///
+  /// The Tys parameter is for intrinsics with overloaded types (e.g., those
+  /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
+  /// intrinsic, Tys must provide exactly one type for each overloaded type in
+  /// the intrinsic.
+  Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
+
+  /// Map a GCC builtin name to an intrinsic ID.
+  ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
+
+  /// Map a MS builtin name to an intrinsic ID.
+  ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
+  
+  /// IITDescriptor - This is a type descriptor which explains the type
+  /// requirements of an intrinsic.  This is returned by
+  /// getIntrinsicInfoTableEntries.
+  struct IITDescriptor {
+    enum IITDescriptorKind {
+      Void, VarArg, MMX, Metadata, Half, Float, Double,
+      Integer, Vector, Pointer, Struct,
+      Argument, ExtendArgument, TruncArgument, HalfVecArgument
+    } Kind;
+    
+    union {
+      unsigned Integer_Width;
+      unsigned Float_Width;
+      unsigned Vector_Width;
+      unsigned Pointer_AddressSpace;
+      unsigned Struct_NumElements;
+      unsigned Argument_Info;
+    };
+    
+    enum ArgKind {
+      AK_AnyInteger,
+      AK_AnyFloat,
+      AK_AnyVector,
+      AK_AnyPointer
+    };
+    unsigned getArgumentNumber() const {
+      assert(Kind == Argument || Kind == ExtendArgument ||
+             Kind == TruncArgument || Kind == HalfVecArgument);
+      return Argument_Info >> 2;
+    }
+    ArgKind getArgumentKind() const {
+      assert(Kind == Argument || Kind == ExtendArgument ||
+             Kind == TruncArgument || Kind == HalfVecArgument);
+      return (ArgKind)(Argument_Info&3);
+    }
+    
+    static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
+      IITDescriptor Result = { K, { Field } };
+      return Result;
+    }
+  };
+  
+  /// getIntrinsicInfoTableEntries - Return the IIT table descriptor for the
+  /// specified intrinsic into an array of IITDescriptors.
+  /// 
+  void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
+  
+} // End Intrinsic namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
new file mode 100644
index 0000000..0b8f64f
--- /dev/null
+++ b/include/llvm/IR/Intrinsics.td
@@ -0,0 +1,543 @@
+//===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines properties of all LLVM intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CodeGen/ValueTypes.td"
+
+//===----------------------------------------------------------------------===//
+//  Properties we keep track of for intrinsics.
+//===----------------------------------------------------------------------===//
+
+class IntrinsicProperty;
+
+// Intr*Mem - Memory properties.  An intrinsic is allowed to have at most one of
+// these properties set.  They are listed from the most aggressive (best to use
+// if correct) to the least aggressive.  If no property is set, the worst case
+// is assumed (it may read and write any memory it can get access to and it may
+// have other side effects).
+
+// IntrNoMem - The intrinsic does not access memory or have any other side
+// effects.  It may be CSE'd deleted if dead, etc.
+def IntrNoMem : IntrinsicProperty;
+
+// IntrReadArgMem - This intrinsic reads only from memory that one of its
+// pointer-typed arguments points to, but may read an unspecified amount.
+def IntrReadArgMem : IntrinsicProperty;
+
+// IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be
+// moved across stores.  However, it can be reordered otherwise and can be
+// deleted if dead.
+def IntrReadMem : IntrinsicProperty;
+
+// IntrReadWriteArgMem - This intrinsic reads and writes only from memory that
+// one of its arguments points to, but may access an unspecified amount.  The
+// reads and writes may be volatile, but except for this it has no other side
+// effects.
+def IntrReadWriteArgMem : IntrinsicProperty;
+
+// Commutative - This intrinsic is commutative: X op Y == Y op X.
+def Commutative : IntrinsicProperty;
+
+// Throws - This intrinsic can throw.
+def Throws : IntrinsicProperty;
+
+// NoCapture - The specified argument pointer is not captured by the intrinsic.
+class NoCapture<int argNo> : IntrinsicProperty {
+  int ArgNo = argNo;
+}
+
+// ReadOnly - The specified argument pointer is not written to through the
+// pointer by the intrinsic.
+class ReadOnly<int argNo> : IntrinsicProperty {
+  int ArgNo = argNo;
+}
+
+// ReadNone - The specified argument pointer is not dereferenced by the
+// intrinsic.
+class ReadNone<int argNo> : IntrinsicProperty {
+  int ArgNo = argNo;
+}
+
+def IntrNoReturn : IntrinsicProperty;
+
+// IntrNoduplicate - Calls to this intrinsic cannot be duplicated.
+// Parallels the noduplicate attribute on LLVM IR functions.
+def IntrNoDuplicate : IntrinsicProperty;
+
+//===----------------------------------------------------------------------===//
+// Types used by intrinsics.
+//===----------------------------------------------------------------------===//
+
+class LLVMType<ValueType vt> {
+  ValueType VT = vt;
+}
+
+class LLVMQualPointerType<LLVMType elty, int addrspace>
+  : LLVMType<iPTR>{
+  LLVMType ElTy = elty;
+  int AddrSpace = addrspace;
+}
+
+class LLVMPointerType<LLVMType elty>
+  : LLVMQualPointerType<elty, 0>;
+
+class LLVMAnyPointerType<LLVMType elty>
+  : LLVMType<iPTRAny>{
+  LLVMType ElTy = elty;
+}
+
+// Match the type of another intrinsic parameter.  Number is an index into the
+// list of overloaded types for the intrinsic, excluding all the fixed types.
+// The Number value must refer to a previously listed type.  For example:
+//   Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyfloat_ty, LLVMMatchType<0>]>
+// has two overloaded types, the 2nd and 3rd arguments.  LLVMMatchType<0>
+// refers to the first overloaded type, which is the 2nd argument.
+class LLVMMatchType<int num>
+  : LLVMType<OtherVT>{
+  int Number = num;
+}
+
+// Match the type of another intrinsic parameter that is expected to be based on
+// an integral type (i.e. either iN or <N x iM>), but change the scalar size to
+// be twice as wide or half as wide as the other type.  This is only useful when
+// the intrinsic is overloaded, so the matched type should be declared as iAny.
+class LLVMExtendedType<int num> : LLVMMatchType<num>;
+class LLVMTruncatedType<int num> : LLVMMatchType<num>;
+
+// Match the type of another intrinsic parameter that is expected to be a
+// vector type, but change the element count to be half as many
+class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
+
+def llvm_void_ty       : LLVMType<isVoid>;
+def llvm_anyint_ty     : LLVMType<iAny>;
+def llvm_anyfloat_ty   : LLVMType<fAny>;
+def llvm_anyvector_ty  : LLVMType<vAny>;
+def llvm_i1_ty         : LLVMType<i1>;
+def llvm_i8_ty         : LLVMType<i8>;
+def llvm_i16_ty        : LLVMType<i16>;
+def llvm_i32_ty        : LLVMType<i32>;
+def llvm_i64_ty        : LLVMType<i64>;
+def llvm_half_ty       : LLVMType<f16>;
+def llvm_float_ty      : LLVMType<f32>;
+def llvm_double_ty     : LLVMType<f64>;
+def llvm_f80_ty        : LLVMType<f80>;
+def llvm_f128_ty       : LLVMType<f128>;
+def llvm_ppcf128_ty    : LLVMType<ppcf128>;
+def llvm_ptr_ty        : LLVMPointerType<llvm_i8_ty>;             // i8*
+def llvm_ptrptr_ty     : LLVMPointerType<llvm_ptr_ty>;            // i8**
+def llvm_anyptr_ty     : LLVMAnyPointerType<llvm_i8_ty>;          // (space)i8*
+def llvm_empty_ty      : LLVMType<OtherVT>;                       // { }
+def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>;          // { }*
+def llvm_metadata_ty   : LLVMType<MetadataVT>;                    // !{...}
+
+def llvm_x86mmx_ty     : LLVMType<x86mmx>;
+def llvm_ptrx86mmx_ty  : LLVMPointerType<llvm_x86mmx_ty>;         // <1 x i64>*
+
+def llvm_v2i1_ty       : LLVMType<v2i1>;     //  2 x i1
+def llvm_v4i1_ty       : LLVMType<v4i1>;     //  4 x i1
+def llvm_v8i1_ty       : LLVMType<v8i1>;     //  8 x i1
+def llvm_v16i1_ty      : LLVMType<v16i1>;    // 16 x i1
+def llvm_v32i1_ty      : LLVMType<v32i1>;    // 32 x i1
+def llvm_v64i1_ty      : LLVMType<v64i1>;    // 64 x i1
+def llvm_v1i8_ty       : LLVMType<v1i8>;     //  1 x i8
+def llvm_v2i8_ty       : LLVMType<v2i8>;     //  2 x i8
+def llvm_v4i8_ty       : LLVMType<v4i8>;     //  4 x i8
+def llvm_v8i8_ty       : LLVMType<v8i8>;     //  8 x i8
+def llvm_v16i8_ty      : LLVMType<v16i8>;    // 16 x i8
+def llvm_v32i8_ty      : LLVMType<v32i8>;    // 32 x i8
+def llvm_v64i8_ty      : LLVMType<v64i8>;    // 64 x i8
+
+def llvm_v1i16_ty      : LLVMType<v1i16>;    //  1 x i16
+def llvm_v2i16_ty      : LLVMType<v2i16>;    //  2 x i16
+def llvm_v4i16_ty      : LLVMType<v4i16>;    //  4 x i16
+def llvm_v8i16_ty      : LLVMType<v8i16>;    //  8 x i16
+def llvm_v16i16_ty     : LLVMType<v16i16>;   // 16 x i16
+def llvm_v32i16_ty     : LLVMType<v32i16>;   // 32 x i16
+
+def llvm_v1i32_ty      : LLVMType<v1i32>;    //  1 x i32
+def llvm_v2i32_ty      : LLVMType<v2i32>;    //  2 x i32
+def llvm_v4i32_ty      : LLVMType<v4i32>;    //  4 x i32
+def llvm_v8i32_ty      : LLVMType<v8i32>;    //  8 x i32
+def llvm_v16i32_ty     : LLVMType<v16i32>;   // 16 x i32
+def llvm_v1i64_ty      : LLVMType<v1i64>;    //  1 x i64
+def llvm_v2i64_ty      : LLVMType<v2i64>;    //  2 x i64
+def llvm_v4i64_ty      : LLVMType<v4i64>;    //  4 x i64
+def llvm_v8i64_ty      : LLVMType<v8i64>;    //  8 x i64
+def llvm_v16i64_ty     : LLVMType<v16i64>;   // 16 x i64
+
+def llvm_v2f16_ty      : LLVMType<v2f16>;    //  2 x half (__fp16)
+def llvm_v4f16_ty      : LLVMType<v4f16>;    //  4 x half (__fp16)
+def llvm_v8f16_ty      : LLVMType<v8f16>;    //  8 x half (__fp16)
+def llvm_v1f32_ty      : LLVMType<v1f32>;    //  1 x float
+def llvm_v2f32_ty      : LLVMType<v2f32>;    //  2 x float
+def llvm_v4f32_ty      : LLVMType<v4f32>;    //  4 x float
+def llvm_v8f32_ty      : LLVMType<v8f32>;    //  8 x float
+def llvm_v16f32_ty     : LLVMType<v16f32>;   // 16 x float
+def llvm_v1f64_ty      : LLVMType<v1f64>;    //  1 x double
+def llvm_v2f64_ty      : LLVMType<v2f64>;    //  2 x double
+def llvm_v4f64_ty      : LLVMType<v4f64>;    //  4 x double
+def llvm_v8f64_ty      : LLVMType<v8f64>;    //  8 x double
+
+def llvm_vararg_ty     : LLVMType<isVoid>;   // this means vararg here
+
+
+//===----------------------------------------------------------------------===//
+// Intrinsic Definitions.
+//===----------------------------------------------------------------------===//
+
+// Intrinsic class - This is used to define one LLVM intrinsic.  The name of the
+// intrinsic definition should start with "int_", then match the LLVM intrinsic
+// name with the "llvm." prefix removed, and all "."s turned into "_"s.  For
+// example, llvm.bswap.i16 -> int_bswap_i16.
+//
+//  * RetTypes is a list containing the return types expected for the
+//    intrinsic.
+//  * ParamTypes is a list containing the parameter types expected for the
+//    intrinsic.
+//  * Properties can be set to describe the behavior of the intrinsic.
+//
+class SDPatternOperator;
+class Intrinsic<list<LLVMType> ret_types,
+                list<LLVMType> param_types = [],
+                list<IntrinsicProperty> properties = [],
+                string name = ""> : SDPatternOperator {
+  string LLVMName = name;
+  string TargetPrefix = "";   // Set to a prefix for target-specific intrinsics.
+  list<LLVMType> RetTypes = ret_types;
+  list<LLVMType> ParamTypes = param_types;
+  list<IntrinsicProperty> Properties = properties;
+
+  bit isTarget = 0;
+}
+
+/// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this
+/// specifies the name of the builtin.  This provides automatic CBE and CFE
+/// support.
+class GCCBuiltin<string name> {
+  string GCCBuiltinName = name;
+}
+
+class MSBuiltin<string name> {
+  string MSBuiltinName = name;
+}
+
+
+//===--------------- Variable Argument Handling Intrinsics ----------------===//
+//
+
+def int_vastart : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">;
+def int_vacopy  : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
+                            "llvm.va_copy">;
+def int_vaend   : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
+
+//===------------------- Garbage Collection Intrinsics --------------------===//
+//
+def int_gcroot  : Intrinsic<[],
+                            [llvm_ptrptr_ty, llvm_ptr_ty]>;
+def int_gcread  : Intrinsic<[llvm_ptr_ty],
+                            [llvm_ptr_ty, llvm_ptrptr_ty],
+                            [IntrReadArgMem]>;
+def int_gcwrite : Intrinsic<[],
+                            [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
+                            [IntrReadWriteArgMem, NoCapture<1>, NoCapture<2>]>;
+
+//===--------------------- Code Generator Intrinsics ----------------------===//
+//
+def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_frameaddress  : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_read_register  : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
+                                   [IntrNoMem], "llvm.read_register">;
+def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
+                                   [], "llvm.write_register">;
+
+// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
+// model their dependencies on allocas.
+def int_stacksave     : Intrinsic<[llvm_ptr_ty]>,
+                        GCCBuiltin<"__builtin_stack_save">;
+def int_stackrestore  : Intrinsic<[], [llvm_ptr_ty]>,
+                        GCCBuiltin<"__builtin_stack_restore">;
+
+// IntrReadWriteArgMem is more pessimistic than strictly necessary for prefetch,
+// however it does conveniently prevent the prefetch from being reordered
+// with respect to nearby accesses to the same memory.
+def int_prefetch      : Intrinsic<[],
+                                  [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty,
+                                   llvm_i32_ty],
+                                  [IntrReadWriteArgMem, NoCapture<0>]>;
+def int_pcmarker      : Intrinsic<[], [llvm_i32_ty]>;
+
+def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
+
+// Stack Protector Intrinsic - The stackprotector intrinsic writes the stack
+// guard to the correct place on the stack frame.
+def int_stackprotector : Intrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
+def int_stackprotectorcheck : Intrinsic<[], [llvm_ptrptr_ty],
+                                        [IntrReadWriteArgMem]>;
+
+//===------------------- Standard C Library Intrinsics --------------------===//
+//
+
+def int_memcpy  : Intrinsic<[],
+                             [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
+                              llvm_i32_ty, llvm_i1_ty],
+                            [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
+                             ReadOnly<1>]>;
+def int_memmove : Intrinsic<[],
+                            [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
+                             llvm_i32_ty, llvm_i1_ty],
+                            [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>,
+                             ReadOnly<1>]>;
+def int_memset  : Intrinsic<[],
+                            [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
+                             llvm_i32_ty, llvm_i1_ty],
+                            [IntrReadWriteArgMem, NoCapture<0>]>;
+
+let Properties = [IntrNoMem] in {
+  def int_fma  : Intrinsic<[llvm_anyfloat_ty],
+                           [LLVMMatchType<0>, LLVMMatchType<0>,
+                            LLVMMatchType<0>]>;
+  def int_fmuladd : Intrinsic<[llvm_anyfloat_ty],
+                              [LLVMMatchType<0>, LLVMMatchType<0>,
+                               LLVMMatchType<0>]>;
+
+  // These functions do not read memory, but are sensitive to the
+  // rounding mode. LLVM purposely does not model changes to the FP
+  // environment so they can be treated as readnone.
+  def int_sqrt : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_powi : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
+  def int_sin  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_cos  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_pow  : Intrinsic<[llvm_anyfloat_ty],
+                           [LLVMMatchType<0>, LLVMMatchType<0>]>;
+  def int_log  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_exp  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_fabs : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_copysign : Intrinsic<[llvm_anyfloat_ty],
+                               [LLVMMatchType<0>, LLVMMatchType<0>]>;
+  def int_floor : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_ceil  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_trunc : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_rint  : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+  def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+}
+
+// NOTE: these are internal interfaces.
+def int_setjmp     : Intrinsic<[llvm_i32_ty],  [llvm_ptr_ty]>;
+def int_longjmp    : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
+def int_sigsetjmp  : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
+def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
+
+// Internal interface for object size checking
+def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_anyptr_ty, llvm_i1_ty],
+                               [IntrNoMem]>,
+                               GCCBuiltin<"__builtin_object_size">;
+
+//===------------------------- Expect Intrinsics --------------------------===//
+//
+def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+                                              LLVMMatchType<0>], [IntrNoMem]>;
+
+//===-------------------- Bit Manipulation Intrinsics ---------------------===//
+//
+
+// None of these intrinsics accesses memory at all.
+let Properties = [IntrNoMem] in {
+  def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+  def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+  def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+  def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+}
+
+//===------------------------ Debugger Intrinsics -------------------------===//
+//
+
+// None of these intrinsics accesses memory at all...but that doesn't mean the
+// optimizers can change them aggressively.  Special handling needed in a few
+// places.
+let Properties = [IntrNoMem] in {
+  def int_dbg_declare      : Intrinsic<[],
+                                       [llvm_metadata_ty, llvm_metadata_ty]>;
+  def int_dbg_value        : Intrinsic<[],
+                                       [llvm_metadata_ty, llvm_i64_ty,
+                                        llvm_metadata_ty]>;
+}
+
+//===------------------ Exception Handling Intrinsics----------------------===//
+//
+
+// The result of eh.typeid.for depends on the enclosing function, but inside a
+// given function it is 'const' and may be CSE'd etc.
+def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
+
+def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
+def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
+
+// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
+// callee-saved registers to be saved and restored (regardless of whether they
+// are used) in the calling function. It is used by libgcc_eh.
+def int_eh_unwind_init: Intrinsic<[]>,
+                        GCCBuiltin<"__builtin_unwind_init">;
+
+def int_eh_dwarf_cfa  : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
+
+let Properties = [IntrNoMem] in {
+  def int_eh_sjlj_lsda             : Intrinsic<[llvm_ptr_ty]>;
+  def int_eh_sjlj_callsite         : Intrinsic<[], [llvm_i32_ty]>;
+}
+def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>;
+def int_eh_sjlj_setjmp          : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
+def int_eh_sjlj_longjmp         : Intrinsic<[], [llvm_ptr_ty], [IntrNoReturn]>;
+
+//===---------------- Generic Variable Attribute Intrinsics----------------===//
+//
+def int_var_annotation : Intrinsic<[],
+                                   [llvm_ptr_ty, llvm_ptr_ty,
+                                    llvm_ptr_ty, llvm_i32_ty],
+                                   [], "llvm.var.annotation">;
+def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType<llvm_anyint_ty>],
+                                   [LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty,
+                                    llvm_i32_ty],
+                                   [], "llvm.ptr.annotation">;
+def int_annotation : Intrinsic<[llvm_anyint_ty],
+                               [LLVMMatchType<0>, llvm_ptr_ty,
+                                llvm_ptr_ty, llvm_i32_ty],
+                               [], "llvm.annotation">;
+
+//===------------------------ Trampoline Intrinsics -----------------------===//
+//
+def int_init_trampoline : Intrinsic<[],
+                                    [llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
+                                    [IntrReadWriteArgMem, NoCapture<0>]>,
+                                   GCCBuiltin<"__builtin_init_trampoline">;
+
+def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
+                                      [IntrReadArgMem]>,
+                                     GCCBuiltin<"__builtin_adjust_trampoline">;
+
+//===------------------------ Overflow Intrinsics -------------------------===//
+//
+
+// Expose the carry flag from add operations on two integrals.
+def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+
+def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+
+def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+                                       [LLVMMatchType<0>, LLVMMatchType<0>],
+                                       [IntrNoMem]>;
+
+//===------------------------- Memory Use Markers -------------------------===//
+//
+def int_lifetime_start  : Intrinsic<[],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_lifetime_end    : Intrinsic<[],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
+                                    [llvm_i64_ty, llvm_ptr_ty],
+                                    [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_invariant_end   : Intrinsic<[],
+                                    [llvm_descriptor_ty, llvm_i64_ty,
+                                     llvm_ptr_ty],
+                                    [IntrReadWriteArgMem, NoCapture<2>]>;
+
+//===------------------------ Stackmap Intrinsics -------------------------===//
+//
+def int_experimental_stackmap : Intrinsic<[],
+                                  [llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty],
+                                  [Throws]>;
+def int_experimental_patchpoint_void : Intrinsic<[],
+                                                 [llvm_i64_ty, llvm_i32_ty,
+                                                  llvm_ptr_ty, llvm_i32_ty,
+                                                  llvm_vararg_ty]>;
+def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
+                                                [llvm_i64_ty, llvm_i32_ty,
+                                                 llvm_ptr_ty, llvm_i32_ty,
+                                                 llvm_vararg_ty]>;
+
+//===-------------------------- Other Intrinsics --------------------------===//
+//
+def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
+                     GCCBuiltin<"__builtin_flt_rounds">;
+def int_trap : Intrinsic<[], [], [IntrNoReturn]>,
+               GCCBuiltin<"__builtin_trap">;
+def int_debugtrap : Intrinsic<[]>,
+                    GCCBuiltin<"__builtin_debugtrap">;
+
+// NOP: calls/invokes to this intrinsic are removed by codegen
+def int_donothing : Intrinsic<[], [], [IntrNoMem]>;
+
+// Intrisics to support half precision floating point format
+let Properties = [IntrNoMem] in {
+def int_convert_to_fp16   : Intrinsic<[llvm_i16_ty], [llvm_anyfloat_ty]>;
+def int_convert_from_fp16 : Intrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>;
+}
+
+// These convert intrinsics are to support various conversions between
+// various types with rounding and saturation. NOTE: avoid using these
+// intrinsics as they might be removed sometime in the future and
+// most targets don't support them.
+def int_convertff  : Intrinsic<[llvm_anyfloat_ty],
+                               [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfsi : Intrinsic<[llvm_anyfloat_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfui : Intrinsic<[llvm_anyfloat_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsif : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuif : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertss  : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsu  : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertus  : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuu  : Intrinsic<[llvm_anyint_ty],
+                               [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+
+// Clear cache intrinsic, default to ignore (ie. emit nothing)
+// maps to void __clear_cache() on supporting platforms
+def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+                                [], "llvm.clear_cache">;
+
+//===----------------------------------------------------------------------===//
+// Target-specific intrinsics
+//===----------------------------------------------------------------------===//
+
+include "llvm/IR/IntrinsicsPowerPC.td"
+include "llvm/IR/IntrinsicsX86.td"
+include "llvm/IR/IntrinsicsARM.td"
+include "llvm/IR/IntrinsicsAArch64.td"
+include "llvm/IR/IntrinsicsXCore.td"
+include "llvm/IR/IntrinsicsHexagon.td"
+include "llvm/IR/IntrinsicsNVVM.td"
+include "llvm/IR/IntrinsicsMips.td"
+include "llvm/IR/IntrinsicsR600.td"
diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td
new file mode 100644
index 0000000..7d69ed5
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsAArch64.td
@@ -0,0 +1,655 @@
+//===- IntrinsicsAARCH64.td - Defines AARCH64 intrinsics ---*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the AARCH64-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "aarch64" in {
+
+def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>;
+def int_aarch64_ldaxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>;
+def int_aarch64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty]>;
+def int_aarch64_stlxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty]>;
+
+def int_aarch64_ldxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty]>;
+def int_aarch64_ldaxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty]>;
+def int_aarch64_stxp : Intrinsic<[llvm_i32_ty],
+                               [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty]>;
+def int_aarch64_stlxp : Intrinsic<[llvm_i32_ty],
+                                [llvm_i64_ty, llvm_i64_ty, llvm_ptr_ty]>;
+
+def int_aarch64_clrex : Intrinsic<[]>;
+
+def int_aarch64_sdiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+                                LLVMMatchType<0>], [IntrNoMem]>;
+def int_aarch64_udiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+                                LLVMMatchType<0>], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// HINT
+
+def int_aarch64_hint : Intrinsic<[], [llvm_i32_ty]>;
+
+//===----------------------------------------------------------------------===//
+// RBIT
+
+def int_aarch64_rbit : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
+                                 [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Data Barrier Instructions
+
+def int_aarch64_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
+def int_aarch64_dsb : GCCBuiltin<"__builtin_arm_dsb">, Intrinsic<[], [llvm_i32_ty]>;
+def int_aarch64_isb : GCCBuiltin<"__builtin_arm_isb">, Intrinsic<[], [llvm_i32_ty]>;
+
+}
+
+//===----------------------------------------------------------------------===//
+// Advanced SIMD (NEON)
+
+let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
+  class AdvSIMD_2Scalar_Float_Intrinsic
+    : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+                [IntrNoMem]>;
+
+  class AdvSIMD_FPToIntRounding_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+
+  class AdvSIMD_1IntArg_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_1FloatArg_Intrinsic
+    : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Expand_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Long_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>], [IntrNoMem]>;
+  class AdvSIMD_1IntArg_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Int_Across_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Float_Across_Intrinsic
+    : Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+
+  class AdvSIMD_2IntArg_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2FloatArg_Intrinsic
+    : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Compare_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
+                [IntrNoMem]>;
+  class AdvSIMD_2Arg_FloatCompare_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Long_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Wide_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMMatchType<0>, LLVMTruncatedType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMExtendedType<0>, LLVMExtendedType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2Arg_Scalar_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyint_ty],
+                [LLVMExtendedType<0>, llvm_i32_ty],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Scalar_Expand_BySize_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [llvm_anyvector_ty],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Scalar_Wide_BySize_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMTruncatedType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMTruncatedType<0>, llvm_i32_ty],
+                [IntrNoMem]>;
+  class AdvSIMD_2VectorArg_Tied_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty],
+                [IntrNoMem]>;
+
+  class AdvSIMD_3VectorArg_Intrinsic
+      : Intrinsic<[llvm_anyvector_ty],
+               [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+               [IntrNoMem]>;
+  class AdvSIMD_3VectorArg_Scalar_Intrinsic
+      : Intrinsic<[llvm_anyvector_ty],
+               [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
+               [IntrNoMem]>;
+  class AdvSIMD_3VectorArg_Tied_Narrow_Intrinsic
+      : Intrinsic<[llvm_anyvector_ty],
+               [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty,
+                LLVMMatchType<1>], [IntrNoMem]>;
+  class AdvSIMD_3VectorArg_Scalar_Tied_Narrow_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty, llvm_i32_ty],
+                [IntrNoMem]>;
+  class AdvSIMD_CvtFxToFP_Intrinsic
+    : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
+                [IntrNoMem]>;
+  class AdvSIMD_CvtFPToFx_Intrinsic
+    : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty],
+                [IntrNoMem]>;
+}
+
+// Arithmetic ops
+
+let Properties = [IntrNoMem] in {
+  // Vector Add Across Lanes
+  def int_aarch64_neon_saddv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_uaddv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_faddv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+  // Vector Long Add Across Lanes
+  def int_aarch64_neon_saddlv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_uaddlv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+
+  // Vector Halving Add
+  def int_aarch64_neon_shadd : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_uhadd : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Rounding Halving Add
+  def int_aarch64_neon_srhadd : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_urhadd : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Saturating Add
+  def int_aarch64_neon_sqadd : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_suqadd : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_usqadd : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_uqadd : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Add High-Half
+  // FIXME: this is a legacy intrinsic for aarch64_simd.h. Remove it when that
+  // header is no longer supported.
+  def int_aarch64_neon_addhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+  // Vector Rounding Add High-Half
+  def int_aarch64_neon_raddhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+  // Vector Saturating Doubling Multiply High
+  def int_aarch64_neon_sqdmulh : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Saturating Rounding Doubling Multiply High
+  def int_aarch64_neon_sqrdmulh : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Polynominal Multiply
+  def int_aarch64_neon_pmul : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Long Multiply
+  def int_aarch64_neon_smull : AdvSIMD_2VectorArg_Long_Intrinsic;
+  def int_aarch64_neon_umull : AdvSIMD_2VectorArg_Long_Intrinsic;
+  def int_aarch64_neon_pmull : AdvSIMD_2VectorArg_Long_Intrinsic;
+
+  // 64-bit polynomial multiply really returns an i128, which is not legal. Fake
+  // it with a v16i8.
+  def int_aarch64_neon_pmull64 :
+        Intrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
+  // Vector Extending Multiply
+  def int_aarch64_neon_fmulx : AdvSIMD_2FloatArg_Intrinsic {
+    let Properties = [IntrNoMem, Commutative];
+  }
+
+  // Vector Saturating Doubling Long Multiply
+  def int_aarch64_neon_sqdmull : AdvSIMD_2VectorArg_Long_Intrinsic;
+  def int_aarch64_neon_sqdmulls_scalar
+    : Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+  // Vector Halving Subtract
+  def int_aarch64_neon_shsub : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_uhsub : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Saturating Subtract
+  def int_aarch64_neon_sqsub : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_uqsub : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Subtract High-Half
+  // FIXME: this is a legacy intrinsic for aarch64_simd.h. Remove it when that
+  // header is no longer supported.
+  def int_aarch64_neon_subhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+  // Vector Rounding Subtract High-Half
+  def int_aarch64_neon_rsubhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+  // Vector Compare Absolute Greater-than-or-equal
+  def int_aarch64_neon_facge : AdvSIMD_2Arg_FloatCompare_Intrinsic;
+
+  // Vector Compare Absolute Greater-than
+  def int_aarch64_neon_facgt : AdvSIMD_2Arg_FloatCompare_Intrinsic;
+
+  // Vector Absolute Difference
+  def int_aarch64_neon_sabd : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_uabd : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fabd : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Scalar Absolute Difference
+  def int_aarch64_sisd_fabd : AdvSIMD_2Scalar_Float_Intrinsic;
+
+  // Vector Max
+  def int_aarch64_neon_smax : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_umax : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fmax : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fmaxnmp : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Max Across Lanes
+  def int_aarch64_neon_smaxv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_umaxv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_fmaxv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+  def int_aarch64_neon_fmaxnmv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+  // Vector Min
+  def int_aarch64_neon_smin : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_umin : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fmin : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fminnmp : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Vector Min/Max Number
+  def int_aarch64_neon_fminnm : AdvSIMD_2FloatArg_Intrinsic;
+  def int_aarch64_neon_fmaxnm : AdvSIMD_2FloatArg_Intrinsic;
+
+  // Vector Min Across Lanes
+  def int_aarch64_neon_sminv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_uminv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+  def int_aarch64_neon_fminv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+  def int_aarch64_neon_fminnmv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+  // Pairwise Add
+  def int_aarch64_neon_addp : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Long Pairwise Add
+  // FIXME: In theory, we shouldn't need intrinsics for saddlp or
+  // uaddlp, but tblgen's type inference currently can't handle the
+  // pattern fragments this ends up generating.
+  def int_aarch64_neon_saddlp : AdvSIMD_1VectorArg_Expand_Intrinsic;
+  def int_aarch64_neon_uaddlp : AdvSIMD_1VectorArg_Expand_Intrinsic;
+
+  // Folding Maximum
+  def int_aarch64_neon_smaxp : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_umaxp : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fmaxp : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Folding Minimum
+  def int_aarch64_neon_sminp : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_uminp : AdvSIMD_2VectorArg_Intrinsic;
+  def int_aarch64_neon_fminp : AdvSIMD_2VectorArg_Intrinsic;
+
+  // Reciprocal Estimate/Step
+  def int_aarch64_neon_frecps : AdvSIMD_2FloatArg_Intrinsic;
+  def int_aarch64_neon_frsqrts : AdvSIMD_2FloatArg_Intrinsic;
+
+  // Reciprocal Exponent
+  def int_aarch64_neon_frecpx : AdvSIMD_1FloatArg_Intrinsic;
+
+  // Vector Saturating Shift Left
+  def int_aarch64_neon_sqshl : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_uqshl : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Rounding Shift Left
+  def int_aarch64_neon_srshl : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_urshl : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Saturating Rounding Shift Left
+  def int_aarch64_neon_sqrshl : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_uqrshl : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Signed->Unsigned Shift Left by Constant
+  def int_aarch64_neon_sqshlu : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Signed->Unsigned Narrowing Saturating Shift Right by Constant
+  def int_aarch64_neon_sqshrun : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+  // Vector Signed->Unsigned Rounding Narrowing Saturating Shift Right by Const
+  def int_aarch64_neon_sqrshrun : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+  // Vector Narrowing Shift Right by Constant
+  def int_aarch64_neon_sqshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+  def int_aarch64_neon_uqshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+  // Vector Rounding Narrowing Shift Right by Constant
+  def int_aarch64_neon_rshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+  // Vector Rounding Narrowing Saturating Shift Right by Constant
+  def int_aarch64_neon_sqrshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+  def int_aarch64_neon_uqrshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+  // Vector Shift Left
+  def int_aarch64_neon_sshl : AdvSIMD_2IntArg_Intrinsic;
+  def int_aarch64_neon_ushl : AdvSIMD_2IntArg_Intrinsic;
+
+  // Vector Widening Shift Left by Constant
+  def int_aarch64_neon_shll : AdvSIMD_2VectorArg_Scalar_Wide_BySize_Intrinsic;
+  def int_aarch64_neon_sshll : AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic;
+  def int_aarch64_neon_ushll : AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic;
+
+  // Vector Shift Right by Constant and Insert
+  def int_aarch64_neon_vsri : AdvSIMD_3VectorArg_Scalar_Intrinsic;
+
+  // Vector Shift Left by Constant and Insert
+  def int_aarch64_neon_vsli : AdvSIMD_3VectorArg_Scalar_Intrinsic;
+
+  // Vector Saturating Narrow
+  def int_aarch64_neon_scalar_sqxtn: AdvSIMD_1IntArg_Narrow_Intrinsic;
+  def int_aarch64_neon_scalar_uqxtn : AdvSIMD_1IntArg_Narrow_Intrinsic;
+  def int_aarch64_neon_sqxtn : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+  def int_aarch64_neon_uqxtn : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+
+  // Vector Saturating Extract and Unsigned Narrow
+  def int_aarch64_neon_scalar_sqxtun : AdvSIMD_1IntArg_Narrow_Intrinsic;
+  def int_aarch64_neon_sqxtun : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+
+  // Vector Absolute Value
+  def int_aarch64_neon_abs : AdvSIMD_1IntArg_Intrinsic;
+
+  // Vector Saturating Absolute Value
+  def int_aarch64_neon_sqabs : AdvSIMD_1IntArg_Intrinsic;
+
+  // Vector Saturating Negation
+  def int_aarch64_neon_sqneg : AdvSIMD_1IntArg_Intrinsic;
+
+  // Vector Count Leading Sign Bits
+  def int_aarch64_neon_cls : AdvSIMD_1VectorArg_Intrinsic;
+
+  // Vector Reciprocal Estimate
+  def int_aarch64_neon_urecpe : AdvSIMD_1VectorArg_Intrinsic;
+  def int_aarch64_neon_frecpe : AdvSIMD_1FloatArg_Intrinsic;
+
+  // Vector Square Root Estimate
+  def int_aarch64_neon_ursqrte : AdvSIMD_1VectorArg_Intrinsic;
+  def int_aarch64_neon_frsqrte : AdvSIMD_1FloatArg_Intrinsic;
+
+  // Vector Bitwise Reverse
+  def int_aarch64_neon_rbit : AdvSIMD_1VectorArg_Intrinsic;
+
+  // Vector Conversions Between Half-Precision and Single-Precision.
+  def int_aarch64_neon_vcvtfp2hf
+    : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_aarch64_neon_vcvthf2fp
+    : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+
+  // Vector Conversions Between Floating-point and Fixed-point.
+  def int_aarch64_neon_vcvtfp2fxs : AdvSIMD_CvtFPToFx_Intrinsic;
+  def int_aarch64_neon_vcvtfp2fxu : AdvSIMD_CvtFPToFx_Intrinsic;
+  def int_aarch64_neon_vcvtfxs2fp : AdvSIMD_CvtFxToFP_Intrinsic;
+  def int_aarch64_neon_vcvtfxu2fp : AdvSIMD_CvtFxToFP_Intrinsic;
+
+  // Vector FP->Int Conversions
+  def int_aarch64_neon_fcvtas : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtau : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtms : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtmu : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtns : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtnu : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtps : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtpu : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtzs : AdvSIMD_FPToIntRounding_Intrinsic;
+  def int_aarch64_neon_fcvtzu : AdvSIMD_FPToIntRounding_Intrinsic;
+
+  // Vector FP Rounding: only ties to even is unrepresented by a normal
+  // intrinsic.
+  def int_aarch64_neon_frintn : AdvSIMD_1FloatArg_Intrinsic;
+
+  // Scalar FP->Int conversions
+
+  // Vector FP Inexact Narrowing
+  def int_aarch64_neon_fcvtxn : AdvSIMD_1VectorArg_Expand_Intrinsic;
+
+  // Scalar FP Inexact Narrowing
+  def int_aarch64_sisd_fcvtxn : Intrinsic<[llvm_float_ty], [llvm_double_ty],
+                                        [IntrNoMem]>;
+}
+
+let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
+  class AdvSIMD_2Vector2Index_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [llvm_anyvector_ty, llvm_i64_ty, LLVMMatchType<0>, llvm_i64_ty],
+                [IntrNoMem]>;
+}
+
+// Vector element to element moves
+def int_aarch64_neon_vcopy_lane: AdvSIMD_2Vector2Index_Intrinsic;
+
+let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
+  class AdvSIMD_1Vec_Load_Intrinsic
+      : Intrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>],
+                  [IntrReadArgMem]>;
+  class AdvSIMD_1Vec_Store_Lane_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadWriteArgMem, NoCapture<2>]>;
+
+  class AdvSIMD_2Vec_Load_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+                [LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadArgMem]>;
+  class AdvSIMD_2Vec_Load_Lane_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+                [LLVMMatchType<0>, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadArgMem]>;
+  class AdvSIMD_2Vec_Store_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+                     LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadWriteArgMem, NoCapture<2>]>;
+  class AdvSIMD_2Vec_Store_Lane_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadWriteArgMem, NoCapture<3>]>;
+
+  class AdvSIMD_3Vec_Load_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>],
+                [LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadArgMem]>;
+  class AdvSIMD_3Vec_Load_Lane_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>],
+                [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadArgMem]>;
+  class AdvSIMD_3Vec_Store_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+                     LLVMMatchType<0>, LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadWriteArgMem, NoCapture<3>]>;
+  class AdvSIMD_3Vec_Store_Lane_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty,
+                 LLVMMatchType<0>, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadWriteArgMem, NoCapture<4>]>;
+
+  class AdvSIMD_4Vec_Load_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                 LLVMMatchType<0>, LLVMMatchType<0>],
+                [LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadArgMem]>;
+  class AdvSIMD_4Vec_Load_Lane_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                 LLVMMatchType<0>, LLVMMatchType<0>],
+                [LLVMMatchType<0>, LLVMMatchType<0>,
+                 LLVMMatchType<0>, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadArgMem]>;
+  class AdvSIMD_4Vec_Store_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+                 LLVMMatchType<0>, LLVMMatchType<0>,
+                 LLVMAnyPointerType<LLVMMatchType<0>>],
+                [IntrReadWriteArgMem, NoCapture<4>]>;
+  class AdvSIMD_4Vec_Store_Lane_Intrinsic
+    : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+                 LLVMMatchType<0>, LLVMMatchType<0>,
+                 llvm_i64_ty, llvm_anyptr_ty],
+                [IntrReadWriteArgMem, NoCapture<5>]>;
+}
+
+// Memory ops
+
+def int_aarch64_neon_ld1x2 : AdvSIMD_2Vec_Load_Intrinsic;
+def int_aarch64_neon_ld1x3 : AdvSIMD_3Vec_Load_Intrinsic;
+def int_aarch64_neon_ld1x4 : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_aarch64_neon_st1x2 : AdvSIMD_2Vec_Store_Intrinsic;
+def int_aarch64_neon_st1x3 : AdvSIMD_3Vec_Store_Intrinsic;
+def int_aarch64_neon_st1x4 : AdvSIMD_4Vec_Store_Intrinsic;
+
+def int_aarch64_neon_ld2 : AdvSIMD_2Vec_Load_Intrinsic;
+def int_aarch64_neon_ld3 : AdvSIMD_3Vec_Load_Intrinsic;
+def int_aarch64_neon_ld4 : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_aarch64_neon_ld2lane : AdvSIMD_2Vec_Load_Lane_Intrinsic;
+def int_aarch64_neon_ld3lane : AdvSIMD_3Vec_Load_Lane_Intrinsic;
+def int_aarch64_neon_ld4lane : AdvSIMD_4Vec_Load_Lane_Intrinsic;
+
+def int_aarch64_neon_ld2r : AdvSIMD_2Vec_Load_Intrinsic;
+def int_aarch64_neon_ld3r : AdvSIMD_3Vec_Load_Intrinsic;
+def int_aarch64_neon_ld4r : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_aarch64_neon_st2  : AdvSIMD_2Vec_Store_Intrinsic;
+def int_aarch64_neon_st3  : AdvSIMD_3Vec_Store_Intrinsic;
+def int_aarch64_neon_st4  : AdvSIMD_4Vec_Store_Intrinsic;
+
+def int_aarch64_neon_st2lane  : AdvSIMD_2Vec_Store_Lane_Intrinsic;
+def int_aarch64_neon_st3lane  : AdvSIMD_3Vec_Store_Lane_Intrinsic;
+def int_aarch64_neon_st4lane  : AdvSIMD_4Vec_Store_Lane_Intrinsic;
+
+let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
+  class AdvSIMD_Tbl1_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty], [llvm_v16i8_ty, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_Tbl2_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_Tbl3_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+                 LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_Tbl4_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+                 LLVMMatchType<0>],
+                [IntrNoMem]>;
+
+  class AdvSIMD_Tbx1_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMMatchType<0>, llvm_v16i8_ty, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_Tbx2_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+                 LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_Tbx3_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+                 llvm_v16i8_ty, LLVMMatchType<0>],
+                [IntrNoMem]>;
+  class AdvSIMD_Tbx4_Intrinsic
+    : Intrinsic<[llvm_anyvector_ty],
+                [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+                 llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>],
+                [IntrNoMem]>;
+}
+def int_aarch64_neon_tbl1 : AdvSIMD_Tbl1_Intrinsic;
+def int_aarch64_neon_tbl2 : AdvSIMD_Tbl2_Intrinsic;
+def int_aarch64_neon_tbl3 : AdvSIMD_Tbl3_Intrinsic;
+def int_aarch64_neon_tbl4 : AdvSIMD_Tbl4_Intrinsic;
+
+def int_aarch64_neon_tbx1 : AdvSIMD_Tbx1_Intrinsic;
+def int_aarch64_neon_tbx2 : AdvSIMD_Tbx2_Intrinsic;
+def int_aarch64_neon_tbx3 : AdvSIMD_Tbx3_Intrinsic;
+def int_aarch64_neon_tbx4 : AdvSIMD_Tbx4_Intrinsic;
+
+let TargetPrefix = "aarch64" in {
+  class Crypto_AES_DataKey_Intrinsic
+    : Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+  class Crypto_AES_Data_Intrinsic
+    : Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+  // SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
+  // (v4i32).
+  class Crypto_SHA_5Hash4Schedule_Intrinsic
+    : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+                [IntrNoMem]>;
+
+  // SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
+  // (v4i32).
+  class Crypto_SHA_1Hash_Intrinsic
+    : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  // SHA intrinsic taking 8 words of the schedule
+  class Crypto_SHA_8Schedule_Intrinsic
+    : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+  // SHA intrinsic taking 12 words of the schedule
+  class Crypto_SHA_12Schedule_Intrinsic
+    : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                [IntrNoMem]>;
+
+  // SHA intrinsic taking 8 words of the hash and 4 of the schedule.
+  class Crypto_SHA_8Hash4Schedule_Intrinsic
+    : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                [IntrNoMem]>;
+}
+
+// AES
+def int_aarch64_crypto_aese   : Crypto_AES_DataKey_Intrinsic;
+def int_aarch64_crypto_aesd   : Crypto_AES_DataKey_Intrinsic;
+def int_aarch64_crypto_aesmc  : Crypto_AES_Data_Intrinsic;
+def int_aarch64_crypto_aesimc : Crypto_AES_Data_Intrinsic;
+
+// SHA1
+def int_aarch64_crypto_sha1c  : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_aarch64_crypto_sha1p  : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_aarch64_crypto_sha1m  : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_aarch64_crypto_sha1h  : Crypto_SHA_1Hash_Intrinsic;
+
+def int_aarch64_crypto_sha1su0 : Crypto_SHA_12Schedule_Intrinsic;
+def int_aarch64_crypto_sha1su1 : Crypto_SHA_8Schedule_Intrinsic;
+
+// SHA256
+def int_aarch64_crypto_sha256h   : Crypto_SHA_8Hash4Schedule_Intrinsic;
+def int_aarch64_crypto_sha256h2  : Crypto_SHA_8Hash4Schedule_Intrinsic;
+def int_aarch64_crypto_sha256su0 : Crypto_SHA_8Schedule_Intrinsic;
+def int_aarch64_crypto_sha256su1 : Crypto_SHA_12Schedule_Intrinsic;
+
+//===----------------------------------------------------------------------===//
+// CRC32
+
+let TargetPrefix = "aarch64" in {
+
+def int_aarch64_crc32b  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32cb : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32h  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32ch : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32w  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32x  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+    [IntrNoMem]>;
+def int_aarch64_crc32cx : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+    [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
new file mode 100644
index 0000000..a02d707
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -0,0 +1,519 @@
+//===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the ARM-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+
+//===----------------------------------------------------------------------===//
+// TLS
+
+let TargetPrefix = "arm" in {  // All intrinsics start with "llvm.arm.".
+
+def int_arm_thread_pointer : GCCBuiltin<"__builtin_thread_pointer">,
+            Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Saturating Arithmentic
+
+def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">,
+    Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem, Commutative]>;
+def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">,
+    Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
+    Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
+    Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Load, Store and Clear exclusive
+
+def int_arm_ldrex : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>;
+def int_arm_strex : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyptr_ty]>;
+
+def int_arm_ldaex : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>;
+def int_arm_stlex : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyptr_ty]>;
+
+def int_arm_clrex : Intrinsic<[]>;
+
+def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+    llvm_ptr_ty]>;
+def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
+
+def int_arm_stlexd : Intrinsic<[llvm_i32_ty],
+                               [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty]>;
+def int_arm_ldaexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
+
+//===----------------------------------------------------------------------===//
+// Data barrier instructions
+def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, MSBuiltin<"__dmb">,
+                  Intrinsic<[], [llvm_i32_ty]>;
+def int_arm_dsb : GCCBuiltin<"__builtin_arm_dsb">, MSBuiltin<"__dsb">,
+                  Intrinsic<[], [llvm_i32_ty]>;
+def int_arm_isb : GCCBuiltin<"__builtin_arm_isb">, MSBuiltin<"__isb">,
+                  Intrinsic<[], [llvm_i32_ty]>;
+
+//===----------------------------------------------------------------------===//
+// VFP
+
+def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">,
+                       Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+def int_arm_set_fpscr : GCCBuiltin<"__builtin_arm_set_fpscr">,
+                       Intrinsic<[], [llvm_i32_ty], []>;
+def int_arm_vcvtr     : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
+                                  [IntrNoMem]>;
+def int_arm_vcvtru    : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
+                                  [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Coprocessor
+
+// Move to coprocessor
+def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
+                  MSBuiltin<"_MoveToCoprocessor">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
+                   MSBuiltin<"_MoveToCoprocessor2">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+// Move from coprocessor
+def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
+                  MSBuiltin<"_MoveFromCoprocessor">,
+   Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                             llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
+                   MSBuiltin<"_MoveFromCoprocessor2">,
+   Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                             llvm_i32_ty, llvm_i32_ty], []>;
+
+// Coprocessor data processing
+def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+// Move from two registers to coprocessor
+def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty], []>;
+def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">,
+   Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                  llvm_i32_ty, llvm_i32_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// CRC32
+
+def int_arm_crc32b  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_arm_crc32cb : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_arm_crc32h  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_arm_crc32ch : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_arm_crc32w  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+def int_arm_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+    [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// HINT
+
+def int_arm_hint : Intrinsic<[], [llvm_i32_ty]>;
+
+//===----------------------------------------------------------------------===//
+// RBIT
+
+def int_arm_rbit : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// UND (reserved undefined sequence)
+
+def int_arm_undefined : Intrinsic<[], [llvm_i32_ty]>;
+
+//===----------------------------------------------------------------------===//
+// Advanced SIMD (NEON)
+
+// The following classes do not correspond directly to GCC builtins.
+class Neon_1Arg_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+class Neon_1Arg_Narrow_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
+class Neon_2Arg_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+              [IntrNoMem]>;
+class Neon_2Arg_Narrow_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>, LLVMExtendedType<0>],
+              [IntrNoMem]>;
+class Neon_2Arg_Long_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
+              [IntrNoMem]>;
+class Neon_3Arg_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty],
+              [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+              [IntrNoMem]>;
+class Neon_3Arg_Long_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty],
+              [LLVMMatchType<0>, LLVMTruncatedType<0>, LLVMTruncatedType<0>],
+              [IntrNoMem]>;
+class Neon_CvtFxToFP_Intrinsic
+  : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
+class Neon_CvtFPToFx_Intrinsic
+  : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
+class Neon_CvtFPtoInt_1Arg_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+
+class Neon_Compare_Intrinsic
+  : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
+              [IntrNoMem]>;
+
+// The table operands for VTBL and VTBX consist of 1 to 4 v8i8 vectors.
+// Besides the table, VTBL has one other v8i8 argument and VTBX has two.
+// Overall, the classes range from 2 to 6 v8i8 arguments.
+class Neon_Tbl2Arg_Intrinsic
+  : Intrinsic<[llvm_v8i8_ty],
+              [llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl3Arg_Intrinsic
+  : Intrinsic<[llvm_v8i8_ty],
+              [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl4Arg_Intrinsic
+  : Intrinsic<[llvm_v8i8_ty],
+              [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty],
+              [IntrNoMem]>;
+class Neon_Tbl5Arg_Intrinsic
+  : Intrinsic<[llvm_v8i8_ty],
+              [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
+               llvm_v8i8_ty], [IntrNoMem]>;
+class Neon_Tbl6Arg_Intrinsic
+  : Intrinsic<[llvm_v8i8_ty],
+              [llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_v8i8_ty,
+               llvm_v8i8_ty, llvm_v8i8_ty], [IntrNoMem]>;
+
+// Arithmetic ops
+
+let Properties = [IntrNoMem, Commutative] in {
+
+  // Vector Add.
+  def int_arm_neon_vhadds : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vhaddu : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vrhadds : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vrhaddu : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vqadds : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vqaddu : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vraddhn : Neon_2Arg_Narrow_Intrinsic;
+
+  // Vector Multiply.
+  def int_arm_neon_vmulp : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic;
+  def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic;
+  def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic;
+  def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic;
+
+  // Vector Maximum.
+  def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vmaxnm : Neon_2Arg_Intrinsic;
+
+  // Vector Minimum.
+  def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
+  def int_arm_neon_vminnm : Neon_2Arg_Intrinsic;
+
+  // Vector Reciprocal Step.
+  def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;
+
+  // Vector Reciprocal Square Root Step.
+  def int_arm_neon_vrsqrts : Neon_2Arg_Intrinsic;
+}
+
+// Vector Subtract.
+def int_arm_neon_vhsubs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vhsubu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqsubs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqsubu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vrsubhn : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Absolute Compare.
+def int_arm_neon_vacge : Neon_Compare_Intrinsic;
+def int_arm_neon_vacgt : Neon_Compare_Intrinsic;
+
+// Vector Absolute Differences.
+def int_arm_neon_vabds : Neon_2Arg_Intrinsic;
+def int_arm_neon_vabdu : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise Add.
+def int_arm_neon_vpadd : Neon_2Arg_Intrinsic;
+
+// Vector Pairwise Add Long.
+// Note: This is different than the other "long" NEON intrinsics because
+// the result vector has half as many elements as the source vector.
+// The source and destination vector types must be specified separately.
+def int_arm_neon_vpaddls : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
+                                     [IntrNoMem]>;
+def int_arm_neon_vpaddlu : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty],
+                                     [IntrNoMem]>;
+
+// Vector Pairwise Add and Accumulate Long.
+// Note: This is similar to vpaddl but the destination vector also appears
+// as the first argument.
+def int_arm_neon_vpadals : Intrinsic<[llvm_anyvector_ty],
+                                     [LLVMMatchType<0>, llvm_anyvector_ty],
+                                     [IntrNoMem]>;
+def int_arm_neon_vpadalu : Intrinsic<[llvm_anyvector_ty],
+                                     [LLVMMatchType<0>, llvm_anyvector_ty],
+                                     [IntrNoMem]>;
+
+// Vector Pairwise Maximum and Minimum.
+def int_arm_neon_vpmaxs : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpmaxu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpmins : Neon_2Arg_Intrinsic;
+def int_arm_neon_vpminu : Neon_2Arg_Intrinsic;
+
+// Vector Shifts:
+//
+// The various saturating and rounding vector shift operations need to be
+// represented by intrinsics in LLVM, and even the basic VSHL variable shift
+// operation cannot be safely translated to LLVM's shift operators.  VSHL can
+// be used for both left and right shifts, or even combinations of the two,
+// depending on the signs of the shift amounts.  It also has well-defined
+// behavior for shift amounts that LLVM leaves undefined.  Only basic shifts
+// by constants can be represented with LLVM's shift operators.
+//
+// The shift counts for these intrinsics are always vectors, even for constant
+// shifts, where the constant is replicated.  For consistency with VSHL (and
+// other variable shift instructions), left shifts have positive shift counts
+// and right shifts have negative shift counts.  This convention is also used
+// for constant right shift intrinsics, and to help preserve sanity, the
+// intrinsic names use "shift" instead of either "shl" or "shr".  Where
+// applicable, signed and unsigned versions of the intrinsics are
+// distinguished with "s" and "u" suffixes.  A few NEON shift instructions,
+// such as VQSHLU, take signed operands but produce unsigned results; these
+// use a "su" suffix.
+
+// Vector Shift.
+def int_arm_neon_vshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vshiftu : Neon_2Arg_Intrinsic;
+
+// Vector Rounding Shift.
+def int_arm_neon_vrshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vrshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vrshiftn : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Saturating Shift.
+def int_arm_neon_vqshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftsu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqshiftns : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqshiftnu : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqshiftnsu : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Saturating Rounding Shift.
+def int_arm_neon_vqrshifts : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqrshiftu : Neon_2Arg_Intrinsic;
+def int_arm_neon_vqrshiftns : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqrshiftnu : Neon_2Arg_Narrow_Intrinsic;
+def int_arm_neon_vqrshiftnsu : Neon_2Arg_Narrow_Intrinsic;
+
+// Vector Shift and Insert.
+def int_arm_neon_vshiftins : Neon_3Arg_Intrinsic;
+
+// Vector Absolute Value and Saturating Absolute Value.
+def int_arm_neon_vabs : Neon_1Arg_Intrinsic;
+def int_arm_neon_vqabs : Neon_1Arg_Intrinsic;
+
+// Vector Saturating Negate.
+def int_arm_neon_vqneg : Neon_1Arg_Intrinsic;
+
+// Vector Count Leading Sign/Zero Bits.
+def int_arm_neon_vcls : Neon_1Arg_Intrinsic;
+def int_arm_neon_vclz : Neon_1Arg_Intrinsic;
+
+// Vector Count One Bits.
+def int_arm_neon_vcnt : Neon_1Arg_Intrinsic;
+
+// Vector Reciprocal Estimate.
+def int_arm_neon_vrecpe : Neon_1Arg_Intrinsic;
+
+// Vector Reciprocal Square Root Estimate.
+def int_arm_neon_vrsqrte : Neon_1Arg_Intrinsic;
+
+// Vector Conversions Between Floating-point and Integer
+def int_arm_neon_vcvtau : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtas : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtnu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtns : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtpu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtps : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtmu : Neon_CvtFPtoInt_1Arg_Intrinsic;
+def int_arm_neon_vcvtms : Neon_CvtFPtoInt_1Arg_Intrinsic;
+
+// Vector Conversions Between Floating-point and Fixed-point.
+def int_arm_neon_vcvtfp2fxs : Neon_CvtFPToFx_Intrinsic;
+def int_arm_neon_vcvtfp2fxu : Neon_CvtFPToFx_Intrinsic;
+def int_arm_neon_vcvtfxs2fp : Neon_CvtFxToFP_Intrinsic;
+def int_arm_neon_vcvtfxu2fp : Neon_CvtFxToFP_Intrinsic;
+
+// Vector Conversions Between Half-Precision and Single-Precision.
+def int_arm_neon_vcvtfp2hf
+    : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_arm_neon_vcvthf2fp
+    : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+
+// Narrowing Saturating Vector Moves.
+def int_arm_neon_vqmovns : Neon_1Arg_Narrow_Intrinsic;
+def int_arm_neon_vqmovnu : Neon_1Arg_Narrow_Intrinsic;
+def int_arm_neon_vqmovnsu : Neon_1Arg_Narrow_Intrinsic;
+
+// Vector Table Lookup.
+// The first 1-4 arguments are the table.
+def int_arm_neon_vtbl1 : Neon_Tbl2Arg_Intrinsic;
+def int_arm_neon_vtbl2 : Neon_Tbl3Arg_Intrinsic;
+def int_arm_neon_vtbl3 : Neon_Tbl4Arg_Intrinsic;
+def int_arm_neon_vtbl4 : Neon_Tbl5Arg_Intrinsic;
+
+// Vector Table Extension.
+// Some elements of the destination vector may not be updated, so the original
+// value of that vector is passed as the first argument.  The next 1-4
+// arguments after that are the table.
+def int_arm_neon_vtbx1 : Neon_Tbl3Arg_Intrinsic;
+def int_arm_neon_vtbx2 : Neon_Tbl4Arg_Intrinsic;
+def int_arm_neon_vtbx3 : Neon_Tbl5Arg_Intrinsic;
+def int_arm_neon_vtbx4 : Neon_Tbl6Arg_Intrinsic;
+
+// Vector Rounding
+def int_arm_neon_vrintn : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintx : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrinta : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintz : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintm : Neon_1Arg_Intrinsic;
+def int_arm_neon_vrintp : Neon_1Arg_Intrinsic;
+
+// De-interleaving vector loads from N-element structures.
+// Source operands are the address and alignment.
+def int_arm_neon_vld1 : Intrinsic<[llvm_anyvector_ty],
+                                  [llvm_ptr_ty, llvm_i32_ty],
+                                  [IntrReadArgMem]>;
+def int_arm_neon_vld2 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+                                  [llvm_ptr_ty, llvm_i32_ty],
+                                  [IntrReadArgMem]>;
+def int_arm_neon_vld3 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                                   LLVMMatchType<0>],
+                                  [llvm_ptr_ty, llvm_i32_ty],
+                                  [IntrReadArgMem]>;
+def int_arm_neon_vld4 : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                                   LLVMMatchType<0>, LLVMMatchType<0>],
+                                  [llvm_ptr_ty, llvm_i32_ty],
+                                  [IntrReadArgMem]>;
+
+// Vector load N-element structure to one lane.
+// Source operands are: the address, the N input vectors (since only one
+// lane is assigned), the lane number, and the alignment.
+def int_arm_neon_vld2lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+                                      [llvm_ptr_ty, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, llvm_i32_ty,
+                                       llvm_i32_ty], [IntrReadArgMem]>;
+def int_arm_neon_vld3lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                                       LLVMMatchType<0>],
+                                      [llvm_ptr_ty, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, LLVMMatchType<0>,
+                                       llvm_i32_ty, llvm_i32_ty],
+                                      [IntrReadArgMem]>;
+def int_arm_neon_vld4lane : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, LLVMMatchType<0>],
+                                      [llvm_ptr_ty, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, llvm_i32_ty,
+                                       llvm_i32_ty], [IntrReadArgMem]>;
+
+// Interleaving vector stores from N-element structures.
+// Source operands are: the address, the N vectors, and the alignment.
+def int_arm_neon_vst1 : Intrinsic<[],
+                                  [llvm_ptr_ty, llvm_anyvector_ty,
+                                   llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst2 : Intrinsic<[],
+                                  [llvm_ptr_ty, llvm_anyvector_ty,
+                                   LLVMMatchType<0>, llvm_i32_ty],
+                                  [IntrReadWriteArgMem]>;
+def int_arm_neon_vst3 : Intrinsic<[],
+                                  [llvm_ptr_ty, llvm_anyvector_ty,
+                                   LLVMMatchType<0>, LLVMMatchType<0>,
+                                   llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst4 : Intrinsic<[],
+                                  [llvm_ptr_ty, llvm_anyvector_ty,
+                                   LLVMMatchType<0>, LLVMMatchType<0>,
+                                   LLVMMatchType<0>, llvm_i32_ty],
+                                  [IntrReadWriteArgMem]>;
+
+// Vector store N-element structure from one lane.
+// Source operands are: the address, the N vectors, the lane number, and
+// the alignment.
+def int_arm_neon_vst2lane : Intrinsic<[],
+                                      [llvm_ptr_ty, llvm_anyvector_ty,
+                                       LLVMMatchType<0>, llvm_i32_ty,
+                                       llvm_i32_ty], [IntrReadWriteArgMem]>;
+def int_arm_neon_vst3lane : Intrinsic<[],
+                                      [llvm_ptr_ty, llvm_anyvector_ty,
+                                       LLVMMatchType<0>, LLVMMatchType<0>,
+                                       llvm_i32_ty, llvm_i32_ty],
+                                      [IntrReadWriteArgMem]>;
+def int_arm_neon_vst4lane : Intrinsic<[],
+                                      [llvm_ptr_ty, llvm_anyvector_ty,
+                                       LLVMMatchType<0>, LLVMMatchType<0>,
+                                       LLVMMatchType<0>, llvm_i32_ty,
+                                       llvm_i32_ty], [IntrReadWriteArgMem]>;
+
+// Vector bitwise select.
+def int_arm_neon_vbsl : Intrinsic<[llvm_anyvector_ty],
+                        [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+                        [IntrNoMem]>;
+
+
+// Crypto instructions
+class AES_1Arg_Intrinsic : Intrinsic<[llvm_v16i8_ty],
+                                     [llvm_v16i8_ty], [IntrNoMem]>;
+class AES_2Arg_Intrinsic : Intrinsic<[llvm_v16i8_ty],
+                                     [llvm_v16i8_ty, llvm_v16i8_ty],
+                                     [IntrNoMem]>;
+
+class SHA_1Arg_Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
+                                     [IntrNoMem]>;
+class SHA_2Arg_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+                                     [llvm_v4i32_ty, llvm_v4i32_ty],
+                                     [IntrNoMem]>;
+class SHA_3Arg_i32_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+                                   [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+                                   [IntrNoMem]>;
+class SHA_3Arg_v4i32_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+                                   [llvm_v4i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
+                                   [IntrNoMem]>;
+
+def int_arm_neon_aesd : AES_2Arg_Intrinsic;
+def int_arm_neon_aese : AES_2Arg_Intrinsic;
+def int_arm_neon_aesimc : AES_1Arg_Intrinsic;
+def int_arm_neon_aesmc : AES_1Arg_Intrinsic;
+def int_arm_neon_sha1h : SHA_1Arg_Intrinsic;
+def int_arm_neon_sha1su1 : SHA_2Arg_Intrinsic;
+def int_arm_neon_sha256su0 : SHA_2Arg_Intrinsic;
+def int_arm_neon_sha1c : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1m : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1p : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1su0: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256h: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256h2: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256su1: SHA_3Arg_v4i32_Intrinsic;
+
+} // end TargetPrefix
diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td
new file mode 100644
index 0000000..8a88729
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsHexagon.td
@@ -0,0 +1,4877 @@
+//===- IntrinsicsHexagon.td - Defines Hexagon intrinsics ---*- tablegen -*-===//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the Hexagon-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all Hexagon intrinsics.
+//
+// All Hexagon intrinsics start with "llvm.hexagon.".
+let TargetPrefix = "hexagon" in {
+  /// Hexagon_Intrinsic - Base class for all Hexagon intrinsics.
+  class Hexagon_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
+                              list<LLVMType> param_types,
+                              list<IntrinsicProperty> properties>
+    : GCCBuiltin<!strconcat("__builtin_", GCCIntSuffix)>,
+      Intrinsic<ret_types, param_types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_MEM,BT_BOOL,BT_PTR) ->
+// Hexagon_qi_mem_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_mem_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_ptr_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(void_ftype_SI,BT_VOID,BT_INT) ->
+// Hexagon_void_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_void_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(HI_ftype_SI,BT_I16,BT_INT) ->
+// Hexagon_hi_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_hi_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i16_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_SI,BT_INT,BT_INT) ->
+// Hexagon_si_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_SI,BT_LONGLONG,BT_INT) ->
+// Hexagon_di_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_DI,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_di_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_DI,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_di_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_di_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_QI,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_SI,BT_BOOL,BT_INT) ->
+// Hexagon_qi_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_QI,BT_LONGLONG,BT_BOOL) ->
+// Hexagon_di_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_QI,BT_INT,BT_BOOL) ->
+// Hexagon_si_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_SISI,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_qi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(void_ftype_SISI,BT_VOID,BT_INT,BT_INT) ->
+// Hexagon_void_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_void_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_SISI,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(USI_ftype_SISI,BT_UINT,BT_INT,BT_INT) ->
+// Hexagon_usi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_usi_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_SISI,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(UDI_ftype_SISI,BT_ULONGLONG,BT_INT,BT_INT) ->
+// Hexagon_udi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_udi_sisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_SIDI,BT_LONGLONG,BT_INT,BT_LONGLONG) ->
+// Hexagon_di_sidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sidi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_DISI,BT_LONGLONG,BT_LONGLONG,BT_INT) ->
+// Hexagon_di_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_disi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_SIDI,BT_INT,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_sidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sidi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_DIDI,BT_INT,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_si_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_didi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i64_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_DIDI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_di_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(UDI_ftype_DIDI,BT_ULONGLONG,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_udi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_udi_didi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_DISI,BT_INT,BT_LONGLONG,BT_INT) ->
+// Hexagon_si_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_disi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_DIDI,BT_BOOL,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i64_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_SIDI,BT_BOOL,BT_INT,BT_LONGLONG) ->
+// Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sidi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty, llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_DISI,BT_BOOL,BT_LONGLONG,BT_INT) ->
+// Hexagon_qi_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_disi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i64_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_QIQI,BT_BOOL,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_QIQIQI,BT_BOOL,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qiqiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qiqiqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_QIQI,BT_INT,BT_BOOL,BT_BOOL) ->
+// Hexagon_si_qiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qiqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_QISI,BT_INT,BT_BOOL,BT_INT) ->
+// Hexagon_si_qisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i1_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(void_ftype_SISISI,BT_VOID,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_void_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_sisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_void_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SISISI,BT_INT,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_SISISI,BT_LONGLONG,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_di_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_DISISI,BT_INT,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_si_disisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_disisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DISISI,BT_LONGLONG,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_disisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_disisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SIDISI,BT_INT,BT_INT,BT_LONGLONG,BT_INT) ->
+// Hexagon_si_sidisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sidisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDISI,BT_LONGLONG,BT_LONGLONG,
+//                     BT_LONGLONG,BT_INT) ->
+// Hexagon_di_didisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SIDIDI,BT_INT,BT_INT,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_si_sididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sididi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty,
+                           llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDIDI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG,
+//                     BT_LONGLONG) ->
+// Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+                           llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SISIDI,BT_INT,BT_INT,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_sisidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisidi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_QISISI,BT_INT,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_si_qisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_QISISI,BT_LONGLONG,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_di_qisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i1_ty, llvm_i32_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_QIDIDI,BT_LONGLONG,BT_BOOL,BT_LONGLONG,
+//                     BT_LONGLONG) ->
+// Hexagon_di_qididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qididi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty,
+                           llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDIQI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG,
+//                     BT_BOOL) ->
+// Hexagon_di_didiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didiqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_4(SI_ftype_SISISISI,BT_INT,BT_INT,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+                           llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_4(DI_ftype_DIDISISI,BT_LONGLONG,BT_LONGLONG,
+//                     BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+                           llvm_i32_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+
+class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
+                           llvm_i32_ty, llvm_i32_ty],
+                          [IntrReadWriteArgMem]>;
+
+//
+// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_di_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_sf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_di_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_si_sf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_si_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_df_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i32_ty], [llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_sfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_float_ty, llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_float_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_qi_sfqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sfqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_float_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_sfsfsf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsfsf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_float_ty, llvm_float_ty,
+                                            llvm_float_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_float_ty], [llvm_float_ty, llvm_float_ty,
+                                            llvm_float_ty,
+                           llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_dididisi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+                           llvm_i64_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_si_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_di_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_i64_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_di_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_df_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i64_ty], [llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_df_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_df_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_dfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_double_ty, llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_i1_ty], [llvm_double_ty, llvm_i32_ty],
+                          [IntrNoMem]>;
+//
+//
+// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_double_ty, llvm_double_ty,
+                                             llvm_double_ty],
+                          [IntrNoMem]>;
+//
+// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix>
+  : Hexagon_Intrinsic<GCCIntSuffix,
+                          [llvm_double_ty], [llvm_double_ty, llvm_double_ty,
+                                             llvm_double_ty,
+                          llvm_i32_ty],
+                          [IntrNoMem]>;
+
+
+// This one below will not be generated from iset.py.
+// So make sure, you don't overwrite this one.
+//
+// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
+//
+def int_hexagon_SI_to_SXTHI_asrh :
+Hexagon_si_si_Intrinsic<"SI_to_SXTHI_asrh">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldd :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldd">;
+// This one above will not be generated from iset.py.
+// So make sure, you don't overwrite this one.
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpeq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgt,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeqp,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpeqp :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpeqp">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtp,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpgtp :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtp">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtup,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpgtup :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtup">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpneq">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsset,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsset :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsset">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsclr,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsclr :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclr">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsset,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsset :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsset">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsclr,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsclr :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclr">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeqi,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpeqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeqi">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgti,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgti">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtui">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgei,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgei :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgei">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgeui,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgeui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgeui">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmplt,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmplt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmplt">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpltu,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpltu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpltu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsclri,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsclri :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclri">;
+//
+// BUILTIN_INFO(HEXAGON.C4_nbitsclri,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_nbitsclri :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclri">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneqi,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpltei,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpltei :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpltei">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteui,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteui">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneq,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneq">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplte,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplte :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplte">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteu,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_and,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_and :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_and">;
+//
+// BUILTIN_INFO(HEXAGON.C2_or,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_or :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_or">;
+//
+// BUILTIN_INFO(HEXAGON.C2_xor,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_xor :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_xor">;
+//
+// BUILTIN_INFO(HEXAGON.C2_andn,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_andn :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C2_not,QI_ftype_QI,1)
+//
+def int_hexagon_C2_not :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_not">;
+//
+// BUILTIN_INFO(HEXAGON.C2_orn,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_orn :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_or">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_or">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C2_pxfer_map,QI_ftype_QI,1)
+//
+def int_hexagon_C2_pxfer_map :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_pxfer_map">;
+//
+// BUILTIN_INFO(HEXAGON.C2_any8,QI_ftype_QI,1)
+//
+def int_hexagon_C2_any8 :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_any8">;
+//
+// BUILTIN_INFO(HEXAGON.C2_all8,QI_ftype_QI,1)
+//
+def int_hexagon_C2_all8 :
+Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_all8">;
+//
+// BUILTIN_INFO(HEXAGON.C2_vitpack,SI_ftype_QIQI,2)
+//
+def int_hexagon_C2_vitpack :
+Hexagon_si_qiqi_Intrinsic<"HEXAGON_C2_vitpack">;
+//
+// BUILTIN_INFO(HEXAGON.C2_mux,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_mux :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_mux">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxii,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxii :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxii">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxir,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxir :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxir">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxri,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxri :
+Hexagon_si_qisisi_Intrinsic<"HEXAGON_C2_muxri">;
+//
+// BUILTIN_INFO(HEXAGON.C2_vmux,DI_ftype_QIDIDI,3)
+//
+def int_hexagon_C2_vmux :
+Hexagon_di_qididi_Intrinsic<"HEXAGON_C2_vmux">;
+//
+// BUILTIN_INFO(HEXAGON.C2_mask,DI_ftype_QI,1)
+//
+def int_hexagon_C2_mask :
+Hexagon_di_qi_Intrinsic<"HEXAGON_C2_mask">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpbeq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpbeq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbeqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbeqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbeq_any,QI_ftype_DIDI,2)
+//
+def int_hexagon_A4_vcmpbeq_any :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpbgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpbgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A4_vcmpbgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpbgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpbgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbeq,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbeq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbeqi,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbeqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgt,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpbgti,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpbgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgti">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpheq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpheq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpheq">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmphgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmphgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgt">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmphgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmphgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpheqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpheqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpheqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmphgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmphgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmphgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmphgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpheq,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpheq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgt,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgt :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgt">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgtu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmpheqi,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmpheqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgti,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgti :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cmphgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_A4_cmphgtui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpweq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpweq :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpweq">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpwgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpwgt :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgt">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpwgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpwgtu :
+Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpweqi,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpweqi :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpweqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpwgti,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpwgti :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vcmpwgtui,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_vcmpwgtui :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgtui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_boundscheck,QI_ftype_SIDI,2)
+//
+def int_hexagon_A4_boundscheck :
+Hexagon_qi_sidi_Intrinsic<"HEXAGON_A4_boundscheck">;
+//
+// BUILTIN_INFO(HEXAGON.A4_tlbmatch,QI_ftype_DISI,2)
+//
+def int_hexagon_A4_tlbmatch :
+Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_tlbmatch">;
+//
+// BUILTIN_INFO(HEXAGON.C2_tfrpr,SI_ftype_QI,1)
+//
+def int_hexagon_C2_tfrpr :
+Hexagon_si_qi_Intrinsic<"HEXAGON_C2_tfrpr">;
+//
+// BUILTIN_INFO(HEXAGON.C2_tfrrp,QI_ftype_SI,1)
+//
+def int_hexagon_C2_tfrrp :
+Hexagon_qi_si_Intrinsic<"HEXAGON_C2_tfrrp">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9 :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9_not,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9_not :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hl_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hl_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_lh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_lh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_ll_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_ll_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hl_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hl_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_lh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_lh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_ll_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_ll_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hl_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hl_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_hl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_lh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_lh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_lh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_lh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_ll_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_ll_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_ll_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_mpyud_ll_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpysmi,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpysmi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpysmi">;
+//
+// BUILTIN_INFO(HEXAGON.M2_macsip,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_macsip :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_macsip">;
+//
+// BUILTIN_INFO(HEXAGON.M2_macsin,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_macsin :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_macsin">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyss_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_dpmpyss_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_acc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyss_acc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyss_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_nac_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyss_nac_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyss_nac_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyuu_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_dpmpyuu_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_acc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyuu_acc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyuu_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_nac_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyuu_nac_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_dpmpyuu_nac_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up_s1_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up_s1_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpy_up_s1_sat">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_up,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_up :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyu_up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpysu_up,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpysu_up :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpysu_up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_rnd_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyss_rnd_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_dpmpyss_rnd_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mac_up_s1_sat,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mac_up_s1_sat :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mac_up_s1_sat">;
+//
+// BUILTIN_INFO(HEXAGON.M4_nac_up_s1_sat,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_nac_up_s1_sat :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_nac_up_s1_sat">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyi,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyi">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyui,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyui :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_mpyui">;
+//
+// BUILTIN_INFO(HEXAGON.M2_maci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_maci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_maci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_acci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_acci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_acci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_accii,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_accii :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_accii">;
+//
+// BUILTIN_INFO(HEXAGON.M2_nacci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_nacci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_nacci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_naccii,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_naccii :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_naccii">;
+//
+// BUILTIN_INFO(HEXAGON.M2_subacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_subacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_subacc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyrr_addr,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyrr_addr :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyrr_addr">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addr_u2,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addr_u2 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addr_u2">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addr,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addr :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addr">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyri_addi,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyri_addi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyri_addi">;
+//
+// BUILTIN_INFO(HEXAGON.M4_mpyrr_addi,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_mpyrr_addi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_mpyrr_addi">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2s_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2s_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2s_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2s_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2s_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2s_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2su_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2su_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2su_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2su_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2su_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_vmpy2su_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2su_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2su_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2su_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2su_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2su_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2su_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0pack,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s0pack :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s0pack">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1pack,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s1pack :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_vmpy2s_s1pack">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_vmac2">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vmpy2es_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vmpy2es_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vmpy2es_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vmpy2es_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vmac2es">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrmac_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrmac_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrmac_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrmpy_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrmpy_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrmpy_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s0,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpyrs_s0 :
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vdmpyrs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s1,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpyrs_s1 :
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vdmpyrs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmpybuu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vrmpybuu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vrmpybuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmacbuu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vrmacbuu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vrmacbuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmpybsu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vrmpybsu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vrmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vrmacbsu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vrmacbsu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vrmacbsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmpybuu,DI_ftype_SISI,2)
+//
+def int_hexagon_M5_vmpybuu :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M5_vmpybuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmpybsu,DI_ftype_SISI,2)
+//
+def int_hexagon_M5_vmpybsu :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M5_vmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmacbuu,DI_ftype_DISISI,3)
+//
+def int_hexagon_M5_vmacbuu :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M5_vmacbuu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vmacbsu,DI_ftype_DISISI,3)
+//
+def int_hexagon_M5_vmacbsu :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M5_vmacbsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vdmpybsu,DI_ftype_DIDI,2)
+//
+def int_hexagon_M5_vdmpybsu :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M5_vdmpybsu">;
+//
+// BUILTIN_INFO(HEXAGON.M5_vdmacbsu,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M5_vdmacbsu :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M5_vdmacbsu">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmacs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vdmacs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vdmacs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmacs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vdmacs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vdmacs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpys_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpys_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vdmpys_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpys_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpys_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vdmpys_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrs_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrs_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrsc_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrsc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrsc_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_cmpyrsc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacs_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacs_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacs_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacs_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacsc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacsc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacsc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacsc_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacsc_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacsc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpys_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpys_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpys_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpys_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpys_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpys_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpysc_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpysc_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpysc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpysc_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpysc_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpysc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacs_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacs_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacs_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacs_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacsc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacsc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacsc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacsc_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacsc_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cnacsc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1,DI_ftype_DISI,2)
+//
+def int_hexagon_M2_vrcmpys_s1 :
+Hexagon_di_disi_Intrinsic<"HEXAGON_M2_vrcmpys_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_acc_s1,DI_ftype_DIDISI,3)
+//
+def int_hexagon_M2_vrcmpys_acc_s1 :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_M2_vrcmpys_acc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1rp,SI_ftype_DISI,2)
+//
+def int_hexagon_M2_vrcmpys_s1rp :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M2_vrcmpys_s1rp">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacls_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmachs_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyl_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyh_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyeh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyeh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyeh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyeh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_acc_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyeh_acc_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyeh_acc_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyeh_acc_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyoh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyoh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M4_vrmpyoh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M4_vrmpyoh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_acc_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyoh_acc_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vrmpyoh_acc_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_vrmpyoh_acc_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyl_rs1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyl_rs1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyl_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyh_rs1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyh_rs1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyh_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyl_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_M2_hmmpyh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmaculs_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_mmacuhs_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyul_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_mmpyuh_rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmaci_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmaci_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmacr_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmacr_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0c,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmaci_s0c :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmaci_s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0c,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmacr_s0c :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vrcmacr_s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmaci_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmaci_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmaci_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacr_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacr_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M2_cmacr_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyi_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyi_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyr_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyr_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0c,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyi_s0c :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyi_s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0c,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyr_s0c :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vrcmpyr_s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyi_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyi_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpyi_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyr_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyr_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M2_cmpyr_s0">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyi_wh,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyi_wh :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyi_wh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyr_wh,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyr_wh :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyr_wh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyi_whc,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyi_whc :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyi_whc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_cmpyr_whc,SI_ftype_DISI,2)
+//
+def int_hexagon_M4_cmpyr_whc :
+Hexagon_si_disi_Intrinsic<"HEXAGON_M4_cmpyr_whc">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_i,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s0_sat_i :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_r,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s0_sat_r :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_r">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_i,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s1_sat_i :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_r,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s1_sat_r :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_r">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_i,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vcmac_s0_sat_i :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_r,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vcmac_s0_sat_r :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vcrotate,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_vcrotate :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_vcrotate">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vrcrotate_acc,DI_ftype_DIDISISI,4)
+//
+def int_hexagon_S4_vrcrotate_acc :
+Hexagon_di_didisisi_Intrinsic<"HEXAGON_S4_vrcrotate_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vrcrotate,DI_ftype_DISISI,3)
+//
+def int_hexagon_S4_vrcrotate :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S4_vrcrotate">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vcnegh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_vcnegh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_vcnegh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrcnegh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_vrcnegh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_vrcnegh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_pmpyw,DI_ftype_SISI,2)
+//
+def int_hexagon_M4_pmpyw :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M4_pmpyw">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vpmpyh,DI_ftype_SISI,2)
+//
+def int_hexagon_M4_vpmpyh :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_M4_vpmpyh">;
+//
+// BUILTIN_INFO(HEXAGON.M4_pmpyw_acc,DI_ftype_DISISI,3)
+//
+def int_hexagon_M4_pmpyw_acc :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M4_pmpyw_acc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_vpmpyh_acc,DI_ftype_DISISI,3)
+//
+def int_hexagon_M4_vpmpyh_acc :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_M4_vpmpyh_acc">;
+//
+// BUILTIN_INFO(HEXAGON.A2_add,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_add :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_add">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sub,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_sub :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_sub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addsat,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addsat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subsat,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subsat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addi,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_sat_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_l16_sat_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_sat_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_l16_sat_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_addh_h16_sat_hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subh_h16_sat_hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_aslh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_aslh :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_aslh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_asrh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_asrh :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_asrh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_addp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_addp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addpsat,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_addpsat :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_addpsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addsp,DI_ftype_SIDI,2)
+//
+def int_hexagon_A2_addsp :
+Hexagon_di_sidi_Intrinsic<"HEXAGON_A2_addsp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_subp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_subp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_neg,SI_ftype_SI,1)
+//
+def int_hexagon_A2_neg :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_neg">;
+//
+// BUILTIN_INFO(HEXAGON.A2_negsat,SI_ftype_SI,1)
+//
+def int_hexagon_A2_negsat :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_negsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_abs,SI_ftype_SI,1)
+//
+def int_hexagon_A2_abs :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_abs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_abssat,SI_ftype_SI,1)
+//
+def int_hexagon_A2_abssat :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_abssat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vconj,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vconj :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vconj">;
+//
+// BUILTIN_INFO(HEXAGON.A2_negp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_negp :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_negp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_absp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_absp :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_absp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_max,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_max :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_max">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxu,USI_ftype_SISI,2)
+//
+def int_hexagon_A2_maxu :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_maxu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_min,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_min :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_min">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minu,USI_ftype_SISI,2)
+//
+def int_hexagon_A2_minu :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_minu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_maxp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_maxp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxup,UDI_ftype_DIDI,2)
+//
+def int_hexagon_A2_maxup :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_maxup">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_minp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_minp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minup,UDI_ftype_DIDI,2)
+//
+def int_hexagon_A2_minup :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_minup">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfr,SI_ftype_SI,1)
+//
+def int_hexagon_A2_tfr :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_tfr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrsi,SI_ftype_SI,1)
+//
+def int_hexagon_A2_tfrsi :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_tfrsi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_tfrp :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_tfrp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrpi,DI_ftype_SI,1)
+//
+def int_hexagon_A2_tfrpi :
+Hexagon_di_si_Intrinsic<"HEXAGON_A2_tfrpi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_zxtb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_zxtb :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_zxtb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxtb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sxtb :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sxtb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_zxth,SI_ftype_SI,1)
+//
+def int_hexagon_A2_zxth :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_zxth">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxth,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sxth :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sxth">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combinew,DI_ftype_SISI,2)
+//
+def int_hexagon_A2_combinew :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A2_combinew">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineri,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_combineri :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_combineri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_combineir :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_combineir">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combineii,DI_ftype_SISI,2)
+//
+def int_hexagon_A2_combineii :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A2_combineii">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_combine_ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfril,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_tfril :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_tfril">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrih,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_tfrih :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_tfrih">;
+//
+// BUILTIN_INFO(HEXAGON.A2_and,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_and :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_and">;
+//
+// BUILTIN_INFO(HEXAGON.A2_or,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_or :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_or">;
+//
+// BUILTIN_INFO(HEXAGON.A2_xor,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_xor :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_xor">;
+//
+// BUILTIN_INFO(HEXAGON.A2_not,SI_ftype_SI,1)
+//
+def int_hexagon_A2_not :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_not">;
+//
+// BUILTIN_INFO(HEXAGON.M2_xor_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_xor_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M2_xor_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_xacc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_xor_xacc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_M4_xor_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_andn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_andn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_orn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_orn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_orn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andnp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_andnp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A4_andnp">;
+//
+// BUILTIN_INFO(HEXAGON.A4_ornp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_ornp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A4_ornp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subaddi">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_and_xor">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_or_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andix,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andix :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_andix">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_andi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_ori,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_ori :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_or_ori">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_M4_xor_andn">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subri,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_subri">;
+//
+// BUILTIN_INFO(HEXAGON.A2_andir,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_andir :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_andir">;
+//
+// BUILTIN_INFO(HEXAGON.A2_orir,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_orir :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_orir">;
+//
+// BUILTIN_INFO(HEXAGON.A2_andp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_andp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_andp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_orp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_orp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_orp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_xorp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_xorp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_xorp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_notp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_notp :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_notp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxtw,DI_ftype_SI,1)
+//
+def int_hexagon_A2_sxtw :
+Hexagon_di_si_Intrinsic<"HEXAGON_A2_sxtw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sat,SI_ftype_DI,1)
+//
+def int_hexagon_A2_sat :
+Hexagon_si_di_Intrinsic<"HEXAGON_A2_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_roundsat,SI_ftype_DI,1)
+//
+def int_hexagon_A2_roundsat :
+Hexagon_si_di_Intrinsic<"HEXAGON_A2_roundsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sath,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sath :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_sath">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satuh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satuh :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satub,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satub :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satb :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_satb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddb_map,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddb_map :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddb_map">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddubs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddubs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddubs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vadduhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vadduhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vadduhs">;
+//
+// BUILTIN_INFO(HEXAGON.A5_vaddhubs,SI_ftype_DIDI,2)
+//
+def int_hexagon_A5_vaddhubs :
+Hexagon_si_didi_Intrinsic<"HEXAGON_A5_vaddhubs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddws,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddws :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vaddws">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubw,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubw">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddw,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddw">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubh">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddh">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxaddsubhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxaddsubhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxaddsubhr">;
+//
+// BUILTIN_INFO(HEXAGON.S4_vxsubaddhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_vxsubaddhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_vxsubaddhr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svavgh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svavgh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svavghs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svavghs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svavghs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svnavgh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svnavgh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svnavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svaddh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svaddh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svaddh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svaddhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svaddhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svaddhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svadduhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svadduhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svadduhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubuhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubuhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A2_svsubuhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vraddub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vraddub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vraddub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vraddub_acc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_A2_vraddub_acc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_A2_vraddub_acc">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vraddh,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vraddh :
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vraddh">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vradduh,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vradduh :
+Hexagon_si_didi_Intrinsic<"HEXAGON_M2_vradduh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubb_map,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubb_map :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubb_map">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsububs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsububs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsububs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubuhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubuhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubuhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubws,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubws :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vsubws">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabsh,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabsh :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabsh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabshsat,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabshsat :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabshsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabsw,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabsw :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabsw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabswsat,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabswsat :
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_vabswsat">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vabsdiffw,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vabsdiffw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vabsdiffw">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vabsdiffh,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vabsdiffh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_M2_vabsdiffh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vrsadub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vrsadub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vrsadub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vrsadub_acc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_A2_vrsadub_acc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_A2_vrsadub_acc">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgwcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgwcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgwcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgwcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgwcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavgwcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavghcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavghcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavghcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavghcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavghcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavghcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgubr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgubr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavgubr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavguhr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavghr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavghr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vavghr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavghr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavghr :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vnavghr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_ri,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_ri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_rr,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_ri_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_ri_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_ri_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_rr_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_rr_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_round_rr_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_ri,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cround_ri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_rr,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cround_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminuh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminuh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminuh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxuh,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxuh :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxuh">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrminuw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrminuw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrminuw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_vrmaxuw,DI_ftype_DIDISI,3)
+//
+def int_hexagon_A4_vrmaxuw :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_A4_vrmaxuw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminb,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminb :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxb,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxb :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxub :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminuh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminuh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxuh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxuh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminuw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminuw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vminuw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxuw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxuw :
+Hexagon_di_didi_Intrinsic<"HEXAGON_A2_vmaxuw">;
+//
+// BUILTIN_INFO(HEXAGON.A4_modwrapu,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_modwrapu :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_modwrapu">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfadd,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfadd :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfadd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfsub,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfsub :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfsub">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmpy,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmpy :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmpy">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffma :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffma">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma_sc,SF_ftype_SFSFSFQI,4)
+//
+def int_hexagon_F2_sffma_sc :
+Hexagon_sf_sfsfsfqi_Intrinsic<"HEXAGON_F2_sffma_sc">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffms,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffms :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffms">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffma_lib,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffma_lib :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffma_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffms_lib,SF_ftype_SFSFSF,3)
+//
+def int_hexagon_F2_sffms_lib :
+Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffms_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpeq,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpeq :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpgt,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpgt :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpge,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpge :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpge">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfcmpuo,QI_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfcmpuo :
+Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpuo">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmax,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmax :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmax">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfmin,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sfmin :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmin">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfclass,QI_ftype_SFSI,2)
+//
+def int_hexagon_F2_sfclass :
+Hexagon_qi_sfsi_Intrinsic<"HEXAGON_F2_sfclass">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfimm_p,SF_ftype_SI,1)
+//
+def int_hexagon_F2_sfimm_p :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_sfimm_p">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sfimm_n,SF_ftype_SI,1)
+//
+def int_hexagon_F2_sfimm_n :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_sfimm_n">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupn,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sffixupn :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupn">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupd,SF_ftype_SFSF,2)
+//
+def int_hexagon_F2_sffixupd :
+Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_sffixupr,SF_ftype_SF,1)
+//
+def int_hexagon_F2_sffixupr :
+Hexagon_sf_sf_Intrinsic<"HEXAGON_F2_sffixupr">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfadd,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfadd :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfadd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfsub,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfsub :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfsub">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmpy,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmpy :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmpy">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffma :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffms,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffms :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma_lib,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffma_lib :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffms_lib,DF_ftype_DFDFDF,3)
+//
+def int_hexagon_F2_dffms_lib :
+Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms_lib">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffma_sc,DF_ftype_DFDFDFQI,4)
+//
+def int_hexagon_F2_dffma_sc :
+Hexagon_df_dfdfdfqi_Intrinsic<"HEXAGON_F2_dffma_sc">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmax,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmax :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmax">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfmin,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfmin :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmin">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpeq,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpeq :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpgt,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpgt :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpge,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpge :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpge">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfcmpuo,QI_ftype_DFDF,2)
+//
+def int_hexagon_F2_dfcmpuo :
+Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpuo">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfclass,QI_ftype_DFSI,2)
+//
+def int_hexagon_F2_dfclass :
+Hexagon_qi_dfsi_Intrinsic<"HEXAGON_F2_dfclass">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfimm_p,DF_ftype_SI,1)
+//
+def int_hexagon_F2_dfimm_p :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_p">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dfimm_n,DF_ftype_SI,1)
+//
+def int_hexagon_F2_dfimm_n :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_n">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupn,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dffixupn :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupn">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupd,DF_ftype_DFDF,2)
+//
+def int_hexagon_F2_dffixupd :
+Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupd">;
+//
+// BUILTIN_INFO(HEXAGON.F2_dffixupr,DF_ftype_DF,1)
+//
+def int_hexagon_F2_dffixupr :
+Hexagon_df_df_Intrinsic<"HEXAGON_F2_dffixupr">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2df,DF_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2df :
+Hexagon_df_sf_Intrinsic<"HEXAGON_F2_conv_sf2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2sf,SF_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2sf :
+Hexagon_sf_df_Intrinsic<"HEXAGON_F2_conv_df2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_uw2sf,SF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_uw2sf :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_conv_uw2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_uw2df,DF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_uw2df :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_conv_uw2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_w2sf,SF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_w2sf :
+Hexagon_sf_si_Intrinsic<"HEXAGON_F2_conv_w2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_w2df,DF_ftype_SI,1)
+//
+def int_hexagon_F2_conv_w2df :
+Hexagon_df_si_Intrinsic<"HEXAGON_F2_conv_w2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_ud2sf,SF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_ud2sf :
+Hexagon_sf_di_Intrinsic<"HEXAGON_F2_conv_ud2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_ud2df,DF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_ud2df :
+Hexagon_df_di_Intrinsic<"HEXAGON_F2_conv_ud2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_d2sf,SF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_d2sf :
+Hexagon_sf_di_Intrinsic<"HEXAGON_F2_conv_d2sf">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_d2df,DF_ftype_DI,1)
+//
+def int_hexagon_F2_conv_d2df :
+Hexagon_df_di_Intrinsic<"HEXAGON_F2_conv_d2df">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2uw,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2uw :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2uw">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2w,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2w :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2w">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2ud,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2ud :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2ud">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2d,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2d :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2d">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2uw,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2uw :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2uw">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2w,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2w :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2w">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2ud,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2ud :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2ud">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2d,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2d :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2d">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2uw_chop,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2uw_chop :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2uw_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2w_chop,SI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2w_chop :
+Hexagon_si_sf_Intrinsic<"HEXAGON_F2_conv_sf2w_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2ud_chop,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2ud_chop :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2ud_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_sf2d_chop,DI_ftype_SF,1)
+//
+def int_hexagon_F2_conv_sf2d_chop :
+Hexagon_di_sf_Intrinsic<"HEXAGON_F2_conv_sf2d_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2uw_chop,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2uw_chop :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2uw_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2w_chop,SI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2w_chop :
+Hexagon_si_df_Intrinsic<"HEXAGON_F2_conv_df2w_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2ud_chop,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2ud_chop :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2ud_chop">;
+//
+// BUILTIN_INFO(HEXAGON.F2_conv_df2d_chop,DI_ftype_DF,1)
+//
+def int_hexagon_F2_conv_df2d_chop :
+Hexagon_di_df_Intrinsic<"HEXAGON_F2_conv_df2d_chop">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_r_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_r_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsr_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsr_r_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsl_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsl_r_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_r_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_r_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_r_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsl_r_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_xor,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_xor :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsl_r_p_xor">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_r_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_r_r_sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_r_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_r_r_sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsr_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_lsr_i_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_i_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_xacc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_xacc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_xacc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_xacc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asr_i_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_lsr_i_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_asl_i_r_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asr_i_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_lsr_i_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_asl_i_p_or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_i_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asl_i_r_sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r_rnd :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r_rnd">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd_goodsyntax,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r_rnd_goodsyntax :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_rnd,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p_rnd :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p_rnd">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_rnd_goodsyntax,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p_rnd_goodsyntax :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S4_lsli,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_lsli :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_lsli">;
+//
+// BUILTIN_INFO(HEXAGON.S2_addasl_rrri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_addasl_rrri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_addasl_rrri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_andi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_andi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_andi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ori_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_ori_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_ori_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subi_asl_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subi_asl_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subi_asl_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_andi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_andi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_andi_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ori_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_ori_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_ori_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_addi_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subi_lsr_ri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subi_lsr_ri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_subi_lsr_ri">;
+//
+// BUILTIN_INFO(HEXAGON.S2_valignib,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_valignib :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_valignib">;
+//
+// BUILTIN_INFO(HEXAGON.S2_valignrb,DI_ftype_DIDIQI,3)
+//
+def int_hexagon_S2_valignrb :
+Hexagon_di_didiqi_Intrinsic<"HEXAGON_S2_valignrb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vspliceib,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_vspliceib :
+Hexagon_di_didisi_Intrinsic<"HEXAGON_S2_vspliceib">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplicerb,DI_ftype_DIDIQI,3)
+//
+def int_hexagon_S2_vsplicerb :
+Hexagon_di_didiqi_Intrinsic<"HEXAGON_S2_vsplicerb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplatrh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsplatrh :
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsplatrh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplatrb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_vsplatrb :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_vsplatrb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insert,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_insert :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_insert">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxb_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxb_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxb_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxh_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxh_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxh_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxw_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxw_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxw_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxd_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxd_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON_S2_tableidxd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.A4_bitspliti,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_bitspliti :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_bitspliti">;
+//
+// BUILTIN_INFO(HEXAGON.A4_bitsplit,DI_ftype_SISI,2)
+//
+def int_hexagon_A4_bitsplit :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_A4_bitsplit">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extract,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_extract :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S4_extract">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractu,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_extractu :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_S2_extractu">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insertp,DI_ftype_DIDISISI,4)
+//
+def int_hexagon_S2_insertp :
+Hexagon_di_didisisi_Intrinsic<"HEXAGON_S2_insertp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extractp,DI_ftype_DISISI,3)
+//
+def int_hexagon_S4_extractp :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S4_extractp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractup,DI_ftype_DISISI,3)
+//
+def int_hexagon_S2_extractup :
+Hexagon_di_disisi_Intrinsic<"HEXAGON_S2_extractup">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insert_rp,SI_ftype_SISIDI,3)
+//
+def int_hexagon_S2_insert_rp :
+Hexagon_si_sisidi_Intrinsic<"HEXAGON_S2_insert_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extract_rp,SI_ftype_SIDI,2)
+//
+def int_hexagon_S4_extract_rp :
+Hexagon_si_sidi_Intrinsic<"HEXAGON_S4_extract_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractu_rp,SI_ftype_SIDI,2)
+//
+def int_hexagon_S2_extractu_rp :
+Hexagon_si_sidi_Intrinsic<"HEXAGON_S2_extractu_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insertp_rp,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_S2_insertp_rp :
+Hexagon_di_dididi_Intrinsic<"HEXAGON_S2_insertp_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_extractp_rp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_extractp_rp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S4_extractp_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractup_rp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_extractup_rp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_extractup_rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tstbit_i,QI_ftype_SISI,2)
+//
+def int_hexagon_S2_tstbit_i :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ntstbit_i,QI_ftype_SISI,2)
+//
+def int_hexagon_S4_ntstbit_i :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_setbit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_setbit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_setbit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_togglebit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_togglebit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_togglebit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clrbit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_clrbit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_clrbit_i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tstbit_r,QI_ftype_SISI,2)
+//
+def int_hexagon_S2_tstbit_r :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ntstbit_r,QI_ftype_SISI,2)
+//
+def int_hexagon_S4_ntstbit_r :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_setbit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_setbit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_setbit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_togglebit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_togglebit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_togglebit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clrbit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_clrbit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_clrbit_r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S5_asrhub_rnd_sat_goodsyntax,SI_ftype_DISI,2)
+//
+def int_hexagon_S5_asrhub_rnd_sat_goodsyntax :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S5_asrhub_sat,SI_ftype_DISI,2)
+//
+def int_hexagon_S5_asrhub_sat :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S5_asrhub_sat">;
+//
+// BUILTIN_INFO(HEXAGON.S5_vasrhrnd_goodsyntax,DI_ftype_DISI,2)
+//
+def int_hexagon_S5_vasrhrnd_goodsyntax :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_i_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_svw_trun,SI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_svw_trun :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S2_asr_i_svw_trun">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_svw_trun,SI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_svw_trun :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S2_asr_r_svw_trun">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_i_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_i_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asr_r_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_asl_r_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsr_r_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON_S2_lsl_r_vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrndpackwh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vrndpackwh :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vrndpackwh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrndpackwhs,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vrndpackwhs :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vrndpackwhs">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsxtbh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsxtbh :
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsxtbh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vzxtbh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vzxtbh :
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vzxtbh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathub,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathub :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsathub">;
+//
+// BUILTIN_INFO(HEXAGON.S2_svsathub,SI_ftype_SI,1)
+//
+def int_hexagon_S2_svsathub :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_svsathub">;
+//
+// BUILTIN_INFO(HEXAGON.S2_svsathb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_svsathb :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_svsathb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathb :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsathb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunohb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vtrunohb :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vtrunohb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunewh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_vtrunewh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_vtrunewh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunowh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_vtrunowh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_vtrunowh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunehb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vtrunehb :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vtrunehb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsxthw,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsxthw :
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vsxthw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vzxthw,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vzxthw :
+Hexagon_di_si_Intrinsic<"HEXAGON_S2_vzxthw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwh :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsatwh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwuh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwuh :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_vsatwuh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_packhl,DI_ftype_SISI,2)
+//
+def int_hexagon_S2_packhl :
+Hexagon_di_sisi_Intrinsic<"HEXAGON_S2_packhl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_swiz,SI_ftype_SI,1)
+//
+def int_hexagon_A2_swiz :
+Hexagon_si_si_Intrinsic<"HEXAGON_A2_swiz">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathub_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathub_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsathub_nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathb_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathb_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsathb_nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwh_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwh_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsatwh_nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwuh_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwuh_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_vsatwuh_nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffob,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffob :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffob">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffeb,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffeb :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffeb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffoh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffoh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffoh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffeh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffeh :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_shuffeh">;
+//
+// BUILTIN_INFO(HEXAGON.S5_popcountp,SI_ftype_DI,1)
+//
+def int_hexagon_S5_popcountp :
+Hexagon_si_di_Intrinsic<"HEXAGON_S5_popcountp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_parity,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_parity :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_parity">;
+//
+// BUILTIN_INFO(HEXAGON.S2_parityp,SI_ftype_DIDI,2)
+//
+def int_hexagon_S2_parityp :
+Hexagon_si_didi_Intrinsic<"HEXAGON_S2_parityp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lfsp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_lfsp :
+Hexagon_di_didi_Intrinsic<"HEXAGON_S2_lfsp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clbnorm,SI_ftype_SI,1)
+//
+def int_hexagon_S2_clbnorm :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_clbnorm">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbaddi,SI_ftype_SISI,2)
+//
+def int_hexagon_S4_clbaddi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_clbaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbpnorm,SI_ftype_DI,1)
+//
+def int_hexagon_S4_clbpnorm :
+Hexagon_si_di_Intrinsic<"HEXAGON_S4_clbpnorm">;
+//
+// BUILTIN_INFO(HEXAGON.S4_clbpaddi,SI_ftype_DISI,2)
+//
+def int_hexagon_S4_clbpaddi :
+Hexagon_si_disi_Intrinsic<"HEXAGON_S4_clbpaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_clb :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_clb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl0,SI_ftype_SI,1)
+//
+def int_hexagon_S2_cl0 :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_cl0">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl1,SI_ftype_SI,1)
+//
+def int_hexagon_S2_cl1 :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_cl1">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clbp,SI_ftype_DI,1)
+//
+def int_hexagon_S2_clbp :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_clbp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl0p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_cl0p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_cl0p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl1p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_cl1p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_cl1p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_brev,SI_ftype_SI,1)
+//
+def int_hexagon_S2_brev :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_brev">;
+//
+// BUILTIN_INFO(HEXAGON.S2_brevp,DI_ftype_DI,1)
+//
+def int_hexagon_S2_brevp :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_brevp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct0,SI_ftype_SI,1)
+//
+def int_hexagon_S2_ct0 :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_ct0">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct1,SI_ftype_SI,1)
+//
+def int_hexagon_S2_ct1 :
+Hexagon_si_si_Intrinsic<"HEXAGON_S2_ct1">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct0p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_ct0p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_ct0p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct1p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_ct1p :
+Hexagon_si_di_Intrinsic<"HEXAGON_S2_ct1p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_interleave,DI_ftype_DI,1)
+//
+def int_hexagon_S2_interleave :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_interleave">;
+//
+// BUILTIN_INFO(HEXAGON.S2_deinterleave,DI_ftype_DI,1)
+//
+def int_hexagon_S2_deinterleave :
+Hexagon_di_di_Intrinsic<"HEXAGON_S2_deinterleave">;
diff --git a/include/llvm/IR/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td
new file mode 100644
index 0000000..3455761
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsMips.td
@@ -0,0 +1,1771 @@
+//===- IntrinsicsMips.td - Defines Mips intrinsics ---------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the MIPS-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MIPS DSP data types
+def mips_v2q15_ty: LLVMType<v2i16>;
+def mips_v4q7_ty: LLVMType<v4i8>;
+def mips_q31_ty: LLVMType<i32>;
+
+let TargetPrefix = "mips" in {  // All intrinsics start with "llvm.mips.".
+
+//===----------------------------------------------------------------------===//
+// MIPS DSP Rev 1
+
+//===----------------------------------------------------------------------===//
+// Addition/subtraction
+
+def int_mips_addu_qb : GCCBuiltin<"__builtin_mips_addu_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+            [Commutative, IntrNoMem]>;
+def int_mips_addu_s_qb : GCCBuiltin<"__builtin_mips_addu_s_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+            [Commutative, IntrNoMem]>;
+def int_mips_subu_qb : GCCBuiltin<"__builtin_mips_subu_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_subu_s_qb : GCCBuiltin<"__builtin_mips_subu_s_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
+
+def int_mips_addq_ph : GCCBuiltin<"__builtin_mips_addq_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+            [Commutative, IntrNoMem]>;
+def int_mips_addq_s_ph : GCCBuiltin<"__builtin_mips_addq_s_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+            [Commutative, IntrNoMem]>;
+def int_mips_subq_ph : GCCBuiltin<"__builtin_mips_subq_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_subq_s_ph : GCCBuiltin<"__builtin_mips_subq_s_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+
+def int_mips_madd: GCCBuiltin<"__builtin_mips_madd">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_maddu: GCCBuiltin<"__builtin_mips_maddu">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem, Commutative]>;
+
+def int_mips_msub: GCCBuiltin<"__builtin_mips_msub">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_msubu: GCCBuiltin<"__builtin_mips_msubu">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_addq_s_w: GCCBuiltin<"__builtin_mips_addq_s_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>;
+def int_mips_subq_s_w: GCCBuiltin<"__builtin_mips_subq_s_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], []>;
+
+def int_mips_addsc: GCCBuiltin<"__builtin_mips_addsc">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;
+def int_mips_addwc: GCCBuiltin<"__builtin_mips_addwc">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [Commutative]>;
+
+def int_mips_modsub: GCCBuiltin<"__builtin_mips_modsub">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_raddu_w_qb: GCCBuiltin<"__builtin_mips_raddu_w_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Absolute value
+
+def int_mips_absq_s_ph: GCCBuiltin<"__builtin_mips_absq_s_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty], []>;
+def int_mips_absq_s_w: GCCBuiltin<"__builtin_mips_absq_s_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Precision reduce/expand
+
+def int_mips_precrq_qb_ph: GCCBuiltin<"__builtin_mips_precrq_qb_ph">,
+  Intrinsic<[llvm_v4i8_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_precrqu_s_qb_ph: GCCBuiltin<"__builtin_mips_precrqu_s_qb_ph">,
+  Intrinsic<[llvm_v4i8_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_precrq_ph_w: GCCBuiltin<"__builtin_mips_precrq_ph_w">,
+  Intrinsic<[mips_v2q15_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>;
+def int_mips_precrq_rs_ph_w: GCCBuiltin<"__builtin_mips_precrq_rs_ph_w">,
+  Intrinsic<[mips_v2q15_ty], [mips_q31_ty, mips_q31_ty], []>;
+def int_mips_preceq_w_phl: GCCBuiltin<"__builtin_mips_preceq_w_phl">,
+  Intrinsic<[mips_q31_ty], [mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_preceq_w_phr: GCCBuiltin<"__builtin_mips_preceq_w_phr">,
+  Intrinsic<[mips_q31_ty], [mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbl: GCCBuiltin<"__builtin_mips_precequ_ph_qbl">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbr: GCCBuiltin<"__builtin_mips_precequ_ph_qbr">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbla: GCCBuiltin<"__builtin_mips_precequ_ph_qbla">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_precequ_ph_qbra: GCCBuiltin<"__builtin_mips_precequ_ph_qbra">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbl: GCCBuiltin<"__builtin_mips_preceu_ph_qbl">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbr: GCCBuiltin<"__builtin_mips_preceu_ph_qbr">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbla: GCCBuiltin<"__builtin_mips_preceu_ph_qbla">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_preceu_ph_qbra: GCCBuiltin<"__builtin_mips_preceu_ph_qbra">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Shift
+
+def int_mips_shll_qb: GCCBuiltin<"__builtin_mips_shll_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], []>;
+def int_mips_shrl_qb: GCCBuiltin<"__builtin_mips_shrl_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shll_ph: GCCBuiltin<"__builtin_mips_shll_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], []>;
+def int_mips_shll_s_ph: GCCBuiltin<"__builtin_mips_shll_s_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], []>;
+def int_mips_shra_ph: GCCBuiltin<"__builtin_mips_shra_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shra_r_ph: GCCBuiltin<"__builtin_mips_shra_r_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shll_s_w: GCCBuiltin<"__builtin_mips_shll_s_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, llvm_i32_ty], []>;
+def int_mips_shra_r_w: GCCBuiltin<"__builtin_mips_shra_r_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shilo: GCCBuiltin<"__builtin_mips_shilo">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// Multiplication
+
+def int_mips_muleu_s_ph_qbl: GCCBuiltin<"__builtin_mips_muleu_s_ph_qbl">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty, mips_v2q15_ty], []>;
+def int_mips_muleu_s_ph_qbr: GCCBuiltin<"__builtin_mips_muleu_s_ph_qbr">,
+  Intrinsic<[mips_v2q15_ty], [llvm_v4i8_ty, mips_v2q15_ty], []>;
+def int_mips_mulq_rs_ph: GCCBuiltin<"__builtin_mips_mulq_rs_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_muleq_s_w_phl: GCCBuiltin<"__builtin_mips_muleq_s_w_phl">,
+  Intrinsic<[mips_q31_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_muleq_s_w_phr: GCCBuiltin<"__builtin_mips_muleq_s_w_phr">,
+  Intrinsic<[mips_q31_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_mulsaq_s_w_ph: GCCBuiltin<"__builtin_mips_mulsaq_s_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_s_w_phl: GCCBuiltin<"__builtin_mips_maq_s_w_phl">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_s_w_phr: GCCBuiltin<"__builtin_mips_maq_s_w_phr">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_sa_w_phl: GCCBuiltin<"__builtin_mips_maq_sa_w_phl">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_maq_sa_w_phr: GCCBuiltin<"__builtin_mips_maq_sa_w_phr">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_mult: GCCBuiltin<"__builtin_mips_mult">,
+  Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_multu: GCCBuiltin<"__builtin_mips_multu">,
+  Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem, Commutative]>;
+
+//===----------------------------------------------------------------------===//
+// Dot product with accumulate/subtract
+
+def int_mips_dpau_h_qbl: GCCBuiltin<"__builtin_mips_dpau_h_qbl">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem]>;
+def int_mips_dpau_h_qbr: GCCBuiltin<"__builtin_mips_dpau_h_qbr">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem]>;
+def int_mips_dpsu_h_qbl: GCCBuiltin<"__builtin_mips_dpsu_h_qbl">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem]>;
+def int_mips_dpsu_h_qbr: GCCBuiltin<"__builtin_mips_dpsu_h_qbr">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem]>;
+def int_mips_dpaq_s_w_ph: GCCBuiltin<"__builtin_mips_dpaq_s_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpsq_s_w_ph: GCCBuiltin<"__builtin_mips_dpsq_s_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpaq_sa_l_w: GCCBuiltin<"__builtin_mips_dpaq_sa_l_w">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>;
+def int_mips_dpsq_sa_l_w: GCCBuiltin<"__builtin_mips_dpsq_sa_l_w">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_q31_ty, mips_q31_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Comparison
+
+def int_mips_cmpu_eq_qb: GCCBuiltin<"__builtin_mips_cmpu_eq_qb">,
+  Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpu_lt_qb: GCCBuiltin<"__builtin_mips_cmpu_lt_qb">,
+  Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_cmpu_le_qb: GCCBuiltin<"__builtin_mips_cmpu_le_qb">,
+  Intrinsic<[], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_cmpgu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgu_eq_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpgu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgu_lt_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_cmpgu_le_qb: GCCBuiltin<"__builtin_mips_cmpgu_le_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_cmp_eq_ph: GCCBuiltin<"__builtin_mips_cmp_eq_ph">,
+  Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_cmp_lt_ph: GCCBuiltin<"__builtin_mips_cmp_lt_ph">,
+  Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_cmp_le_ph: GCCBuiltin<"__builtin_mips_cmp_le_ph">,
+  Intrinsic<[], [mips_v2q15_ty, mips_v2q15_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Extracting
+
+def int_mips_extr_s_h: GCCBuiltin<"__builtin_mips_extr_s_h">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_w: GCCBuiltin<"__builtin_mips_extr_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_rs_w: GCCBuiltin<"__builtin_mips_extr_rs_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extr_r_w: GCCBuiltin<"__builtin_mips_extr_r_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extp: GCCBuiltin<"__builtin_mips_extp">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+def int_mips_extpdp: GCCBuiltin<"__builtin_mips_extpdp">,
+  Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+
+//===----------------------------------------------------------------------===//
+// Misc
+
+def int_mips_wrdsp: GCCBuiltin<"__builtin_mips_wrdsp">,
+  Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;
+def int_mips_rddsp: GCCBuiltin<"__builtin_mips_rddsp">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>;
+
+def int_mips_insv: GCCBuiltin<"__builtin_mips_insv">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>;
+def int_mips_bitrev: GCCBuiltin<"__builtin_mips_bitrev">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_packrl_ph: GCCBuiltin<"__builtin_mips_packrl_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+
+def int_mips_repl_qb: GCCBuiltin<"__builtin_mips_repl_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_repl_ph: GCCBuiltin<"__builtin_mips_repl_ph">,
+  Intrinsic<[mips_v2q15_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_pick_qb: GCCBuiltin<"__builtin_mips_pick_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrReadMem]>;
+def int_mips_pick_ph: GCCBuiltin<"__builtin_mips_pick_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrReadMem]>;
+
+def int_mips_mthlip: GCCBuiltin<"__builtin_mips_mthlip">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], []>;
+
+def int_mips_bposge32: GCCBuiltin<"__builtin_mips_bposge32">,
+  Intrinsic<[llvm_i32_ty], [], [IntrReadMem]>;
+
+def int_mips_lbux: GCCBuiltin<"__builtin_mips_lbux">,
+  Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+def int_mips_lhx: GCCBuiltin<"__builtin_mips_lhx">,
+  Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+def int_mips_lwx: GCCBuiltin<"__builtin_mips_lwx">,
+  Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty], [IntrReadArgMem]>;
+
+//===----------------------------------------------------------------------===//
+// MIPS DSP Rev 2
+
+def int_mips_absq_s_qb: GCCBuiltin<"__builtin_mips_absq_s_qb">,
+  Intrinsic<[mips_v4q7_ty], [mips_v4q7_ty], []>;
+
+def int_mips_addqh_ph: GCCBuiltin<"__builtin_mips_addqh_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_addqh_r_ph: GCCBuiltin<"__builtin_mips_addqh_r_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_addqh_w: GCCBuiltin<"__builtin_mips_addqh_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_addqh_r_w: GCCBuiltin<"__builtin_mips_addqh_r_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty],
+            [IntrNoMem, Commutative]>;
+
+def int_mips_addu_ph: GCCBuiltin<"__builtin_mips_addu_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>;
+def int_mips_addu_s_ph: GCCBuiltin<"__builtin_mips_addu_s_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>;
+
+def int_mips_adduh_qb: GCCBuiltin<"__builtin_mips_adduh_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem, Commutative]>;
+def int_mips_adduh_r_qb: GCCBuiltin<"__builtin_mips_adduh_r_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+            [IntrNoMem, Commutative]>;
+
+def int_mips_append: GCCBuiltin<"__builtin_mips_append">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+def int_mips_cmpgdu_lt_qb: GCCBuiltin<"__builtin_mips_cmpgdu_lt_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+def int_mips_cmpgdu_le_qb: GCCBuiltin<"__builtin_mips_cmpgdu_le_qb">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+
+def int_mips_dpa_w_ph: GCCBuiltin<"__builtin_mips_dpa_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
+            [IntrNoMem]>;
+def int_mips_dps_w_ph: GCCBuiltin<"__builtin_mips_dps_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
+            [IntrNoMem]>;
+
+def int_mips_dpaqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_s_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpaqx_sa_w_ph: GCCBuiltin<"__builtin_mips_dpaqx_sa_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpax_w_ph: GCCBuiltin<"__builtin_mips_dpax_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
+            [IntrNoMem]>;
+def int_mips_dpsx_w_ph: GCCBuiltin<"__builtin_mips_dpsx_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
+            [IntrNoMem]>;
+def int_mips_dpsqx_s_w_ph: GCCBuiltin<"__builtin_mips_dpsqx_s_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+def int_mips_dpsqx_sa_w_ph: GCCBuiltin<"__builtin_mips_dpsqx_sa_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, mips_v2q15_ty, mips_v2q15_ty], []>;
+
+def int_mips_mul_ph: GCCBuiltin<"__builtin_mips_mul_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>;
+def int_mips_mul_s_ph: GCCBuiltin<"__builtin_mips_mul_s_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], [Commutative]>;
+
+def int_mips_mulq_rs_w: GCCBuiltin<"__builtin_mips_mulq_rs_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>;
+def int_mips_mulq_s_ph: GCCBuiltin<"__builtin_mips_mulq_s_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+def int_mips_mulq_s_w: GCCBuiltin<"__builtin_mips_mulq_s_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [Commutative]>;
+def int_mips_mulsa_w_ph: GCCBuiltin<"__builtin_mips_mulsa_w_ph">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_v2i16_ty, llvm_v2i16_ty],
+            [IntrNoMem]>;
+
+def int_mips_precr_qb_ph: GCCBuiltin<"__builtin_mips_precr_qb_ph">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>;
+def int_mips_precr_sra_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_ph_w">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_precr_sra_r_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_r_ph_w">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_prepend: GCCBuiltin<"__builtin_mips_prepend">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_shra_qb: GCCBuiltin<"__builtin_mips_shra_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shra_r_qb: GCCBuiltin<"__builtin_mips_shra_r_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shrl_ph: GCCBuiltin<"__builtin_mips_shrl_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_subqh_ph: GCCBuiltin<"__builtin_mips_subqh_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_subqh_r_ph: GCCBuiltin<"__builtin_mips_subqh_r_ph">,
+  Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
+def int_mips_subqh_w: GCCBuiltin<"__builtin_mips_subqh_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>;
+def int_mips_subqh_r_w: GCCBuiltin<"__builtin_mips_subqh_r_w">,
+  Intrinsic<[mips_q31_ty], [mips_q31_ty, mips_q31_ty], [IntrNoMem]>;
+
+def int_mips_subu_ph: GCCBuiltin<"__builtin_mips_subu_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>;
+def int_mips_subu_s_ph: GCCBuiltin<"__builtin_mips_subu_s_ph">,
+  Intrinsic<[llvm_v2i16_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>;
+
+def int_mips_subuh_qb: GCCBuiltin<"__builtin_mips_subuh_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
+def int_mips_subuh_r_qb: GCCBuiltin<"__builtin_mips_subuh_r_qb">,
+  Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// MIPS MSA
+
+//===----------------------------------------------------------------------===//
+// Addition/subtraction
+
+def int_mips_add_a_b : GCCBuiltin<"__builtin_msa_add_a_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_add_a_h : GCCBuiltin<"__builtin_msa_add_a_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_add_a_w : GCCBuiltin<"__builtin_msa_add_a_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_add_a_d : GCCBuiltin<"__builtin_msa_add_a_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_adds_a_b : GCCBuiltin<"__builtin_msa_adds_a_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_a_h : GCCBuiltin<"__builtin_msa_adds_a_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_a_w : GCCBuiltin<"__builtin_msa_adds_a_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_a_d : GCCBuiltin<"__builtin_msa_adds_a_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_adds_s_b : GCCBuiltin<"__builtin_msa_adds_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_s_h : GCCBuiltin<"__builtin_msa_adds_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_s_w : GCCBuiltin<"__builtin_msa_adds_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_s_d : GCCBuiltin<"__builtin_msa_adds_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_adds_u_b : GCCBuiltin<"__builtin_msa_adds_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_u_h : GCCBuiltin<"__builtin_msa_adds_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_u_w : GCCBuiltin<"__builtin_msa_adds_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_adds_u_d : GCCBuiltin<"__builtin_msa_adds_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_addv_b : GCCBuiltin<"__builtin_msa_addv_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addv_h : GCCBuiltin<"__builtin_msa_addv_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addv_w : GCCBuiltin<"__builtin_msa_addv_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addv_d : GCCBuiltin<"__builtin_msa_addv_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_addvi_b : GCCBuiltin<"__builtin_msa_addvi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addvi_h : GCCBuiltin<"__builtin_msa_addvi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addvi_w : GCCBuiltin<"__builtin_msa_addvi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_addvi_d : GCCBuiltin<"__builtin_msa_addvi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_and_v : GCCBuiltin<"__builtin_msa_and_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_andi_b : GCCBuiltin<"__builtin_msa_andi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_asub_s_b : GCCBuiltin<"__builtin_msa_asub_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_asub_s_h : GCCBuiltin<"__builtin_msa_asub_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_asub_s_w : GCCBuiltin<"__builtin_msa_asub_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_asub_s_d : GCCBuiltin<"__builtin_msa_asub_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_asub_u_b : GCCBuiltin<"__builtin_msa_asub_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_asub_u_h : GCCBuiltin<"__builtin_msa_asub_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_asub_u_w : GCCBuiltin<"__builtin_msa_asub_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_asub_u_d : GCCBuiltin<"__builtin_msa_asub_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ave_s_b : GCCBuiltin<"__builtin_msa_ave_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_s_h : GCCBuiltin<"__builtin_msa_ave_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_s_w : GCCBuiltin<"__builtin_msa_ave_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_s_d : GCCBuiltin<"__builtin_msa_ave_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_ave_u_b : GCCBuiltin<"__builtin_msa_ave_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_u_h : GCCBuiltin<"__builtin_msa_ave_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_u_w : GCCBuiltin<"__builtin_msa_ave_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_ave_u_d : GCCBuiltin<"__builtin_msa_ave_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_aver_s_b : GCCBuiltin<"__builtin_msa_aver_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_s_h : GCCBuiltin<"__builtin_msa_aver_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_s_w : GCCBuiltin<"__builtin_msa_aver_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_s_d : GCCBuiltin<"__builtin_msa_aver_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_aver_u_b : GCCBuiltin<"__builtin_msa_aver_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_u_h : GCCBuiltin<"__builtin_msa_aver_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_u_w : GCCBuiltin<"__builtin_msa_aver_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+  [Commutative, IntrNoMem]>;
+def int_mips_aver_u_d : GCCBuiltin<"__builtin_msa_aver_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+  [Commutative, IntrNoMem]>;
+
+def int_mips_bclr_b : GCCBuiltin<"__builtin_msa_bclr_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_bclr_h : GCCBuiltin<"__builtin_msa_bclr_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_bclr_w : GCCBuiltin<"__builtin_msa_bclr_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_bclr_d : GCCBuiltin<"__builtin_msa_bclr_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_bclri_b : GCCBuiltin<"__builtin_msa_bclri_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bclri_h : GCCBuiltin<"__builtin_msa_bclri_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bclri_w : GCCBuiltin<"__builtin_msa_bclri_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bclri_d : GCCBuiltin<"__builtin_msa_bclri_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_binsl_b : GCCBuiltin<"__builtin_msa_binsl_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+def int_mips_binsl_h : GCCBuiltin<"__builtin_msa_binsl_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+            [IntrNoMem]>;
+def int_mips_binsl_w : GCCBuiltin<"__builtin_msa_binsl_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsl_d : GCCBuiltin<"__builtin_msa_binsl_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+            [IntrNoMem]>;
+
+def int_mips_binsli_b : GCCBuiltin<"__builtin_msa_binsli_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsli_h : GCCBuiltin<"__builtin_msa_binsli_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsli_w : GCCBuiltin<"__builtin_msa_binsli_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsli_d : GCCBuiltin<"__builtin_msa_binsli_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_binsr_b : GCCBuiltin<"__builtin_msa_binsr_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+def int_mips_binsr_h : GCCBuiltin<"__builtin_msa_binsr_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+            [IntrNoMem]>;
+def int_mips_binsr_w : GCCBuiltin<"__builtin_msa_binsr_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsr_d : GCCBuiltin<"__builtin_msa_binsr_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+            [IntrNoMem]>;
+
+def int_mips_binsri_b : GCCBuiltin<"__builtin_msa_binsri_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsri_h : GCCBuiltin<"__builtin_msa_binsri_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsri_w : GCCBuiltin<"__builtin_msa_binsri_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_binsri_d : GCCBuiltin<"__builtin_msa_binsri_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_bmnz_v : GCCBuiltin<"__builtin_msa_bmnz_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+
+def int_mips_bmnzi_b : GCCBuiltin<"__builtin_msa_bmnzi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_bmz_v : GCCBuiltin<"__builtin_msa_bmz_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+
+def int_mips_bmzi_b : GCCBuiltin<"__builtin_msa_bmzi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_bneg_b : GCCBuiltin<"__builtin_msa_bneg_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_bneg_h : GCCBuiltin<"__builtin_msa_bneg_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_bneg_w : GCCBuiltin<"__builtin_msa_bneg_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_bneg_d : GCCBuiltin<"__builtin_msa_bneg_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_bnegi_b : GCCBuiltin<"__builtin_msa_bnegi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bnegi_h : GCCBuiltin<"__builtin_msa_bnegi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bnegi_w : GCCBuiltin<"__builtin_msa_bnegi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bnegi_d : GCCBuiltin<"__builtin_msa_bnegi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_bnz_b : GCCBuiltin<"__builtin_msa_bnz_b">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_bnz_h : GCCBuiltin<"__builtin_msa_bnz_h">,
+  Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_bnz_w : GCCBuiltin<"__builtin_msa_bnz_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_bnz_d : GCCBuiltin<"__builtin_msa_bnz_d">,
+  Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_bnz_v : GCCBuiltin<"__builtin_msa_bnz_v">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_bsel_v : GCCBuiltin<"__builtin_msa_bsel_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+
+def int_mips_bseli_b : GCCBuiltin<"__builtin_msa_bseli_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_bset_b : GCCBuiltin<"__builtin_msa_bset_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_bset_h : GCCBuiltin<"__builtin_msa_bset_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_bset_w : GCCBuiltin<"__builtin_msa_bset_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_bset_d : GCCBuiltin<"__builtin_msa_bset_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_bseti_b : GCCBuiltin<"__builtin_msa_bseti_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bseti_h : GCCBuiltin<"__builtin_msa_bseti_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bseti_w : GCCBuiltin<"__builtin_msa_bseti_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_bseti_d : GCCBuiltin<"__builtin_msa_bseti_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_bz_b : GCCBuiltin<"__builtin_msa_bz_b">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_bz_h : GCCBuiltin<"__builtin_msa_bz_h">,
+  Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_bz_w : GCCBuiltin<"__builtin_msa_bz_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_bz_d : GCCBuiltin<"__builtin_msa_bz_d">,
+  Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_bz_v : GCCBuiltin<"__builtin_msa_bz_v">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_ceq_b : GCCBuiltin<"__builtin_msa_ceq_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_ceq_h : GCCBuiltin<"__builtin_msa_ceq_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ceq_w : GCCBuiltin<"__builtin_msa_ceq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ceq_d : GCCBuiltin<"__builtin_msa_ceq_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ceqi_b : GCCBuiltin<"__builtin_msa_ceqi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ceqi_h : GCCBuiltin<"__builtin_msa_ceqi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ceqi_w : GCCBuiltin<"__builtin_msa_ceqi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ceqi_d : GCCBuiltin<"__builtin_msa_ceqi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_cfcmsa : GCCBuiltin<"__builtin_msa_cfcmsa">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_mips_cle_s_b : GCCBuiltin<"__builtin_msa_cle_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_cle_s_h : GCCBuiltin<"__builtin_msa_cle_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_cle_s_w : GCCBuiltin<"__builtin_msa_cle_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_cle_s_d : GCCBuiltin<"__builtin_msa_cle_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_cle_u_b : GCCBuiltin<"__builtin_msa_cle_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_cle_u_h : GCCBuiltin<"__builtin_msa_cle_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_cle_u_w : GCCBuiltin<"__builtin_msa_cle_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_cle_u_d : GCCBuiltin<"__builtin_msa_cle_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_clei_s_b : GCCBuiltin<"__builtin_msa_clei_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_s_h : GCCBuiltin<"__builtin_msa_clei_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_s_w : GCCBuiltin<"__builtin_msa_clei_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_s_d : GCCBuiltin<"__builtin_msa_clei_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_clei_u_b : GCCBuiltin<"__builtin_msa_clei_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_u_h : GCCBuiltin<"__builtin_msa_clei_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_u_w : GCCBuiltin<"__builtin_msa_clei_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clei_u_d : GCCBuiltin<"__builtin_msa_clei_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_clt_s_b : GCCBuiltin<"__builtin_msa_clt_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_clt_s_h : GCCBuiltin<"__builtin_msa_clt_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_clt_s_w : GCCBuiltin<"__builtin_msa_clt_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_clt_s_d : GCCBuiltin<"__builtin_msa_clt_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_clt_u_b : GCCBuiltin<"__builtin_msa_clt_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_clt_u_h : GCCBuiltin<"__builtin_msa_clt_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_clt_u_w : GCCBuiltin<"__builtin_msa_clt_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_clt_u_d : GCCBuiltin<"__builtin_msa_clt_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_clti_s_b : GCCBuiltin<"__builtin_msa_clti_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_s_h : GCCBuiltin<"__builtin_msa_clti_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_s_w : GCCBuiltin<"__builtin_msa_clti_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_s_d : GCCBuiltin<"__builtin_msa_clti_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_clti_u_b : GCCBuiltin<"__builtin_msa_clti_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_u_h : GCCBuiltin<"__builtin_msa_clti_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_u_w : GCCBuiltin<"__builtin_msa_clti_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_clti_u_d : GCCBuiltin<"__builtin_msa_clti_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_copy_s_b : GCCBuiltin<"__builtin_msa_copy_s_b">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_s_h : GCCBuiltin<"__builtin_msa_copy_s_h">,
+  Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_s_w : GCCBuiltin<"__builtin_msa_copy_s_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_s_d : GCCBuiltin<"__builtin_msa_copy_s_d">,
+  Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_copy_u_b : GCCBuiltin<"__builtin_msa_copy_u_b">,
+  Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_u_h : GCCBuiltin<"__builtin_msa_copy_u_h">,
+  Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_u_w : GCCBuiltin<"__builtin_msa_copy_u_w">,
+  Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_copy_u_d : GCCBuiltin<"__builtin_msa_copy_u_d">,
+  Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_ctcmsa : GCCBuiltin<"__builtin_msa_ctcmsa">,
+  Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;
+
+def int_mips_div_s_b : GCCBuiltin<"__builtin_msa_div_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_div_s_h : GCCBuiltin<"__builtin_msa_div_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_div_s_w : GCCBuiltin<"__builtin_msa_div_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_div_s_d : GCCBuiltin<"__builtin_msa_div_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_div_u_b : GCCBuiltin<"__builtin_msa_div_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_div_u_h : GCCBuiltin<"__builtin_msa_div_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_div_u_w : GCCBuiltin<"__builtin_msa_div_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_div_u_d : GCCBuiltin<"__builtin_msa_div_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+// This instruction is part of the MSA spec but it does not share the
+// __builtin_msa prefix because it operates on GP registers.
+def int_mips_dlsa : GCCBuiltin<"__builtin_mips_dlsa">,
+  Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_dotp_s_h : GCCBuiltin<"__builtin_msa_dotp_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_dotp_s_w : GCCBuiltin<"__builtin_msa_dotp_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_dotp_s_d : GCCBuiltin<"__builtin_msa_dotp_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_dotp_u_h : GCCBuiltin<"__builtin_msa_dotp_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_dotp_u_w : GCCBuiltin<"__builtin_msa_dotp_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_dotp_u_d : GCCBuiltin<"__builtin_msa_dotp_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_dpadd_s_h : GCCBuiltin<"__builtin_msa_dpadd_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_dpadd_s_w : GCCBuiltin<"__builtin_msa_dpadd_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_dpadd_s_d : GCCBuiltin<"__builtin_msa_dpadd_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_dpadd_u_h : GCCBuiltin<"__builtin_msa_dpadd_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_dpadd_u_w : GCCBuiltin<"__builtin_msa_dpadd_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_dpadd_u_d : GCCBuiltin<"__builtin_msa_dpadd_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_dpsub_s_h : GCCBuiltin<"__builtin_msa_dpsub_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_dpsub_s_w : GCCBuiltin<"__builtin_msa_dpsub_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_dpsub_s_d : GCCBuiltin<"__builtin_msa_dpsub_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_dpsub_u_h : GCCBuiltin<"__builtin_msa_dpsub_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_dpsub_u_w : GCCBuiltin<"__builtin_msa_dpsub_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_dpsub_u_d : GCCBuiltin<"__builtin_msa_dpsub_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_fadd_w : GCCBuiltin<"__builtin_msa_fadd_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fadd_d : GCCBuiltin<"__builtin_msa_fadd_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcaf_w : GCCBuiltin<"__builtin_msa_fcaf_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcaf_d : GCCBuiltin<"__builtin_msa_fcaf_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fceq_w : GCCBuiltin<"__builtin_msa_fceq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fceq_d : GCCBuiltin<"__builtin_msa_fceq_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcle_w : GCCBuiltin<"__builtin_msa_fcle_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcle_d : GCCBuiltin<"__builtin_msa_fcle_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fclt_w : GCCBuiltin<"__builtin_msa_fclt_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fclt_d : GCCBuiltin<"__builtin_msa_fclt_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fclass_w : GCCBuiltin<"__builtin_msa_fclass_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fclass_d : GCCBuiltin<"__builtin_msa_fclass_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcne_w : GCCBuiltin<"__builtin_msa_fcne_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcne_d : GCCBuiltin<"__builtin_msa_fcne_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcor_w : GCCBuiltin<"__builtin_msa_fcor_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcor_d : GCCBuiltin<"__builtin_msa_fcor_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcueq_w : GCCBuiltin<"__builtin_msa_fcueq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcueq_d : GCCBuiltin<"__builtin_msa_fcueq_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcule_w : GCCBuiltin<"__builtin_msa_fcule_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcule_d : GCCBuiltin<"__builtin_msa_fcule_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcult_w : GCCBuiltin<"__builtin_msa_fcult_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcult_d : GCCBuiltin<"__builtin_msa_fcult_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcun_w : GCCBuiltin<"__builtin_msa_fcun_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcun_d : GCCBuiltin<"__builtin_msa_fcun_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fcune_w : GCCBuiltin<"__builtin_msa_fcune_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fcune_d : GCCBuiltin<"__builtin_msa_fcune_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fdiv_w : GCCBuiltin<"__builtin_msa_fdiv_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fdiv_d : GCCBuiltin<"__builtin_msa_fdiv_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fexdo_h : GCCBuiltin<"__builtin_msa_fexdo_h">,
+  Intrinsic<[llvm_v8f16_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fexdo_w : GCCBuiltin<"__builtin_msa_fexdo_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fexp2_w : GCCBuiltin<"__builtin_msa_fexp2_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_fexp2_d : GCCBuiltin<"__builtin_msa_fexp2_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_fexupl_w : GCCBuiltin<"__builtin_msa_fexupl_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v8f16_ty], [IntrNoMem]>;
+def int_mips_fexupl_d : GCCBuiltin<"__builtin_msa_fexupl_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+def int_mips_fexupr_w : GCCBuiltin<"__builtin_msa_fexupr_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v8f16_ty], [IntrNoMem]>;
+def int_mips_fexupr_d : GCCBuiltin<"__builtin_msa_fexupr_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+def int_mips_ffint_s_w : GCCBuiltin<"__builtin_msa_ffint_s_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ffint_s_d : GCCBuiltin<"__builtin_msa_ffint_s_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ffint_u_w : GCCBuiltin<"__builtin_msa_ffint_u_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ffint_u_d : GCCBuiltin<"__builtin_msa_ffint_u_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ffql_w : GCCBuiltin<"__builtin_msa_ffql_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ffql_d : GCCBuiltin<"__builtin_msa_ffql_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_ffqr_w : GCCBuiltin<"__builtin_msa_ffqr_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ffqr_d : GCCBuiltin<"__builtin_msa_ffqr_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_fill_b : GCCBuiltin<"__builtin_msa_fill_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_fill_h : GCCBuiltin<"__builtin_msa_fill_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_fill_w : GCCBuiltin<"__builtin_msa_fill_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_fill_d : GCCBuiltin<"__builtin_msa_fill_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+def int_mips_flog2_w : GCCBuiltin<"__builtin_msa_flog2_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_flog2_d : GCCBuiltin<"__builtin_msa_flog2_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fmadd_w : GCCBuiltin<"__builtin_msa_fmadd_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+            [IntrNoMem]>;
+def int_mips_fmadd_d : GCCBuiltin<"__builtin_msa_fmadd_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+            [IntrNoMem]>;
+
+def int_mips_fmax_w : GCCBuiltin<"__builtin_msa_fmax_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fmax_d : GCCBuiltin<"__builtin_msa_fmax_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fmax_a_w : GCCBuiltin<"__builtin_msa_fmax_a_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fmax_a_d : GCCBuiltin<"__builtin_msa_fmax_a_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fmin_w : GCCBuiltin<"__builtin_msa_fmin_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fmin_d : GCCBuiltin<"__builtin_msa_fmin_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fmin_a_w : GCCBuiltin<"__builtin_msa_fmin_a_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fmin_a_d : GCCBuiltin<"__builtin_msa_fmin_a_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fmsub_w : GCCBuiltin<"__builtin_msa_fmsub_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+            [IntrNoMem]>;
+def int_mips_fmsub_d : GCCBuiltin<"__builtin_msa_fmsub_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+            [IntrNoMem]>;
+
+def int_mips_fmul_w : GCCBuiltin<"__builtin_msa_fmul_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fmul_d : GCCBuiltin<"__builtin_msa_fmul_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_frint_w : GCCBuiltin<"__builtin_msa_frint_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_frint_d : GCCBuiltin<"__builtin_msa_frint_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_frcp_w : GCCBuiltin<"__builtin_msa_frcp_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_frcp_d : GCCBuiltin<"__builtin_msa_frcp_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_frsqrt_w : GCCBuiltin<"__builtin_msa_frsqrt_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_frsqrt_d : GCCBuiltin<"__builtin_msa_frsqrt_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsaf_w : GCCBuiltin<"__builtin_msa_fsaf_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsaf_d : GCCBuiltin<"__builtin_msa_fsaf_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fseq_w : GCCBuiltin<"__builtin_msa_fseq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fseq_d : GCCBuiltin<"__builtin_msa_fseq_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsle_w : GCCBuiltin<"__builtin_msa_fsle_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsle_d : GCCBuiltin<"__builtin_msa_fsle_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fslt_w : GCCBuiltin<"__builtin_msa_fslt_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fslt_d : GCCBuiltin<"__builtin_msa_fslt_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsne_w : GCCBuiltin<"__builtin_msa_fsne_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsne_d : GCCBuiltin<"__builtin_msa_fsne_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsor_w : GCCBuiltin<"__builtin_msa_fsor_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsor_d : GCCBuiltin<"__builtin_msa_fsor_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsqrt_w : GCCBuiltin<"__builtin_msa_fsqrt_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsqrt_d : GCCBuiltin<"__builtin_msa_fsqrt_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsub_w : GCCBuiltin<"__builtin_msa_fsub_w">,
+  Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsub_d : GCCBuiltin<"__builtin_msa_fsub_d">,
+  Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsueq_w : GCCBuiltin<"__builtin_msa_fsueq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsueq_d : GCCBuiltin<"__builtin_msa_fsueq_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsule_w : GCCBuiltin<"__builtin_msa_fsule_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsule_d : GCCBuiltin<"__builtin_msa_fsule_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsult_w : GCCBuiltin<"__builtin_msa_fsult_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsult_d : GCCBuiltin<"__builtin_msa_fsult_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsun_w : GCCBuiltin<"__builtin_msa_fsun_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsun_d : GCCBuiltin<"__builtin_msa_fsun_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_fsune_w : GCCBuiltin<"__builtin_msa_fsune_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_fsune_d : GCCBuiltin<"__builtin_msa_fsune_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_ftint_s_w : GCCBuiltin<"__builtin_msa_ftint_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_ftint_s_d : GCCBuiltin<"__builtin_msa_ftint_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_ftint_u_w : GCCBuiltin<"__builtin_msa_ftint_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_ftint_u_d : GCCBuiltin<"__builtin_msa_ftint_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_ftq_h : GCCBuiltin<"__builtin_msa_ftq_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_ftq_w : GCCBuiltin<"__builtin_msa_ftq_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty, llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_ftrunc_s_w : GCCBuiltin<"__builtin_msa_ftrunc_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_ftrunc_s_d : GCCBuiltin<"__builtin_msa_ftrunc_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_ftrunc_u_w : GCCBuiltin<"__builtin_msa_ftrunc_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_mips_ftrunc_u_d : GCCBuiltin<"__builtin_msa_ftrunc_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+def int_mips_hadd_s_h : GCCBuiltin<"__builtin_msa_hadd_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_hadd_s_w : GCCBuiltin<"__builtin_msa_hadd_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_hadd_s_d : GCCBuiltin<"__builtin_msa_hadd_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_hadd_u_h : GCCBuiltin<"__builtin_msa_hadd_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_hadd_u_w : GCCBuiltin<"__builtin_msa_hadd_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_hadd_u_d : GCCBuiltin<"__builtin_msa_hadd_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_hsub_s_h : GCCBuiltin<"__builtin_msa_hsub_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_hsub_s_w : GCCBuiltin<"__builtin_msa_hsub_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_hsub_s_d : GCCBuiltin<"__builtin_msa_hsub_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_hsub_u_h : GCCBuiltin<"__builtin_msa_hsub_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_hsub_u_w : GCCBuiltin<"__builtin_msa_hsub_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_hsub_u_d : GCCBuiltin<"__builtin_msa_hsub_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_ilvev_b : GCCBuiltin<"__builtin_msa_ilvev_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_ilvev_h : GCCBuiltin<"__builtin_msa_ilvev_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ilvev_w : GCCBuiltin<"__builtin_msa_ilvev_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ilvev_d : GCCBuiltin<"__builtin_msa_ilvev_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ilvl_b : GCCBuiltin<"__builtin_msa_ilvl_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_ilvl_h : GCCBuiltin<"__builtin_msa_ilvl_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ilvl_w : GCCBuiltin<"__builtin_msa_ilvl_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ilvl_d : GCCBuiltin<"__builtin_msa_ilvl_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ilvod_b : GCCBuiltin<"__builtin_msa_ilvod_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_ilvod_h : GCCBuiltin<"__builtin_msa_ilvod_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ilvod_w : GCCBuiltin<"__builtin_msa_ilvod_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ilvod_d : GCCBuiltin<"__builtin_msa_ilvod_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_ilvr_b : GCCBuiltin<"__builtin_msa_ilvr_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_ilvr_h : GCCBuiltin<"__builtin_msa_ilvr_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_ilvr_w : GCCBuiltin<"__builtin_msa_ilvr_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_ilvr_d : GCCBuiltin<"__builtin_msa_ilvr_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_insert_b : GCCBuiltin<"__builtin_msa_insert_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+def int_mips_insert_h : GCCBuiltin<"__builtin_msa_insert_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+def int_mips_insert_w : GCCBuiltin<"__builtin_msa_insert_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty],
+  [IntrNoMem]>;
+def int_mips_insert_d : GCCBuiltin<"__builtin_msa_insert_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty, llvm_i64_ty],
+  [IntrNoMem]>;
+
+def int_mips_insve_b : GCCBuiltin<"__builtin_msa_insve_b">,
+  Intrinsic<[llvm_v16i8_ty],
+            [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+def int_mips_insve_h : GCCBuiltin<"__builtin_msa_insve_h">,
+  Intrinsic<[llvm_v8i16_ty],
+            [llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
+            [IntrNoMem]>;
+def int_mips_insve_w : GCCBuiltin<"__builtin_msa_insve_w">,
+  Intrinsic<[llvm_v4i32_ty],
+            [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+            [IntrNoMem]>;
+def int_mips_insve_d : GCCBuiltin<"__builtin_msa_insve_d">,
+  Intrinsic<[llvm_v2i64_ty],
+            [llvm_v2i64_ty, llvm_i32_ty, llvm_v2i64_ty],
+            [IntrNoMem]>;
+
+def int_mips_ld_b : GCCBuiltin<"__builtin_msa_ld_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadArgMem]>;
+def int_mips_ld_h : GCCBuiltin<"__builtin_msa_ld_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadArgMem]>;
+def int_mips_ld_w : GCCBuiltin<"__builtin_msa_ld_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadArgMem]>;
+def int_mips_ld_d : GCCBuiltin<"__builtin_msa_ld_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadArgMem]>;
+
+def int_mips_ldi_b : GCCBuiltin<"__builtin_msa_ldi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ldi_h : GCCBuiltin<"__builtin_msa_ldi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ldi_w : GCCBuiltin<"__builtin_msa_ldi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_mips_ldi_d : GCCBuiltin<"__builtin_msa_ldi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+// This instruction is part of the MSA spec but it does not share the
+// __builtin_msa prefix because it operates on the GPR registers.
+def int_mips_lsa : GCCBuiltin<"__builtin_mips_lsa">,
+  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_madd_q_h : GCCBuiltin<"__builtin_msa_madd_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_madd_q_w : GCCBuiltin<"__builtin_msa_madd_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_maddr_q_h : GCCBuiltin<"__builtin_msa_maddr_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_maddr_q_w : GCCBuiltin<"__builtin_msa_maddr_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_maddv_b : GCCBuiltin<"__builtin_msa_maddv_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_maddv_h : GCCBuiltin<"__builtin_msa_maddv_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_maddv_w : GCCBuiltin<"__builtin_msa_maddv_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+def int_mips_maddv_d : GCCBuiltin<"__builtin_msa_maddv_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+  [IntrNoMem]>;
+
+def int_mips_max_a_b : GCCBuiltin<"__builtin_msa_max_a_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_max_a_h : GCCBuiltin<"__builtin_msa_max_a_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_max_a_w : GCCBuiltin<"__builtin_msa_max_a_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_max_a_d : GCCBuiltin<"__builtin_msa_max_a_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_max_s_b : GCCBuiltin<"__builtin_msa_max_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_max_s_h : GCCBuiltin<"__builtin_msa_max_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_max_s_w : GCCBuiltin<"__builtin_msa_max_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_max_s_d : GCCBuiltin<"__builtin_msa_max_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_max_u_b : GCCBuiltin<"__builtin_msa_max_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_max_u_h : GCCBuiltin<"__builtin_msa_max_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_max_u_w : GCCBuiltin<"__builtin_msa_max_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_max_u_d : GCCBuiltin<"__builtin_msa_max_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_maxi_s_b : GCCBuiltin<"__builtin_msa_maxi_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_s_h : GCCBuiltin<"__builtin_msa_maxi_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_s_w : GCCBuiltin<"__builtin_msa_maxi_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_s_d : GCCBuiltin<"__builtin_msa_maxi_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_maxi_u_b : GCCBuiltin<"__builtin_msa_maxi_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_u_h : GCCBuiltin<"__builtin_msa_maxi_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_u_w : GCCBuiltin<"__builtin_msa_maxi_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_maxi_u_d : GCCBuiltin<"__builtin_msa_maxi_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_min_a_b : GCCBuiltin<"__builtin_msa_min_a_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_min_a_h : GCCBuiltin<"__builtin_msa_min_a_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_min_a_w : GCCBuiltin<"__builtin_msa_min_a_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_min_a_d : GCCBuiltin<"__builtin_msa_min_a_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_min_s_b : GCCBuiltin<"__builtin_msa_min_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_min_s_h : GCCBuiltin<"__builtin_msa_min_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_min_s_w : GCCBuiltin<"__builtin_msa_min_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_min_s_d : GCCBuiltin<"__builtin_msa_min_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_min_u_b : GCCBuiltin<"__builtin_msa_min_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_min_u_h : GCCBuiltin<"__builtin_msa_min_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_min_u_w : GCCBuiltin<"__builtin_msa_min_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_min_u_d : GCCBuiltin<"__builtin_msa_min_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_mini_s_b : GCCBuiltin<"__builtin_msa_mini_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_s_h : GCCBuiltin<"__builtin_msa_mini_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_s_w : GCCBuiltin<"__builtin_msa_mini_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_s_d : GCCBuiltin<"__builtin_msa_mini_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_mini_u_b : GCCBuiltin<"__builtin_msa_mini_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_u_h : GCCBuiltin<"__builtin_msa_mini_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_u_w : GCCBuiltin<"__builtin_msa_mini_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_mini_u_d : GCCBuiltin<"__builtin_msa_mini_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_mod_s_b : GCCBuiltin<"__builtin_msa_mod_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_mod_s_h : GCCBuiltin<"__builtin_msa_mod_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_mod_s_w : GCCBuiltin<"__builtin_msa_mod_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_mod_s_d : GCCBuiltin<"__builtin_msa_mod_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_mod_u_b : GCCBuiltin<"__builtin_msa_mod_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_mod_u_h : GCCBuiltin<"__builtin_msa_mod_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_mod_u_w : GCCBuiltin<"__builtin_msa_mod_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_mod_u_d : GCCBuiltin<"__builtin_msa_mod_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_move_v : GCCBuiltin<"__builtin_msa_move_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_msub_q_h : GCCBuiltin<"__builtin_msa_msub_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_msub_q_w : GCCBuiltin<"__builtin_msa_msub_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_msubr_q_h : GCCBuiltin<"__builtin_msa_msubr_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_msubr_q_w : GCCBuiltin<"__builtin_msa_msubr_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+
+def int_mips_msubv_b : GCCBuiltin<"__builtin_msa_msubv_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+  [IntrNoMem]>;
+def int_mips_msubv_h : GCCBuiltin<"__builtin_msa_msubv_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+  [IntrNoMem]>;
+def int_mips_msubv_w : GCCBuiltin<"__builtin_msa_msubv_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+  [IntrNoMem]>;
+def int_mips_msubv_d : GCCBuiltin<"__builtin_msa_msubv_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+  [IntrNoMem]>;
+
+def int_mips_mul_q_h : GCCBuiltin<"__builtin_msa_mul_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_mul_q_w : GCCBuiltin<"__builtin_msa_mul_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_mulr_q_h : GCCBuiltin<"__builtin_msa_mulr_q_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_mulr_q_w : GCCBuiltin<"__builtin_msa_mulr_q_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+def int_mips_mulv_b : GCCBuiltin<"__builtin_msa_mulv_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_mulv_h : GCCBuiltin<"__builtin_msa_mulv_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_mulv_w : GCCBuiltin<"__builtin_msa_mulv_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_mulv_d : GCCBuiltin<"__builtin_msa_mulv_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_nloc_b : GCCBuiltin<"__builtin_msa_nloc_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_nloc_h : GCCBuiltin<"__builtin_msa_nloc_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_nloc_w : GCCBuiltin<"__builtin_msa_nloc_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_nloc_d : GCCBuiltin<"__builtin_msa_nloc_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_nlzc_b : GCCBuiltin<"__builtin_msa_nlzc_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_nlzc_h : GCCBuiltin<"__builtin_msa_nlzc_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_nlzc_w : GCCBuiltin<"__builtin_msa_nlzc_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_nlzc_d : GCCBuiltin<"__builtin_msa_nlzc_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_nor_v : GCCBuiltin<"__builtin_msa_nor_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_nori_b : GCCBuiltin<"__builtin_msa_nori_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_or_v : GCCBuiltin<"__builtin_msa_or_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_ori_b : GCCBuiltin<"__builtin_msa_ori_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_pckev_b : GCCBuiltin<"__builtin_msa_pckev_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_pckev_h : GCCBuiltin<"__builtin_msa_pckev_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_pckev_w : GCCBuiltin<"__builtin_msa_pckev_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_pckev_d : GCCBuiltin<"__builtin_msa_pckev_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_pckod_b : GCCBuiltin<"__builtin_msa_pckod_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_pckod_h : GCCBuiltin<"__builtin_msa_pckod_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_pckod_w : GCCBuiltin<"__builtin_msa_pckod_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_pckod_d : GCCBuiltin<"__builtin_msa_pckod_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_pcnt_b : GCCBuiltin<"__builtin_msa_pcnt_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_pcnt_h : GCCBuiltin<"__builtin_msa_pcnt_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_pcnt_w : GCCBuiltin<"__builtin_msa_pcnt_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_pcnt_d : GCCBuiltin<"__builtin_msa_pcnt_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_sat_s_b : GCCBuiltin<"__builtin_msa_sat_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_s_h : GCCBuiltin<"__builtin_msa_sat_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_s_w : GCCBuiltin<"__builtin_msa_sat_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_s_d : GCCBuiltin<"__builtin_msa_sat_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_sat_u_b : GCCBuiltin<"__builtin_msa_sat_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_u_h : GCCBuiltin<"__builtin_msa_sat_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_u_w : GCCBuiltin<"__builtin_msa_sat_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sat_u_d : GCCBuiltin<"__builtin_msa_sat_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_shf_b : GCCBuiltin<"__builtin_msa_shf_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shf_h : GCCBuiltin<"__builtin_msa_shf_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_shf_w : GCCBuiltin<"__builtin_msa_shf_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_sld_b : GCCBuiltin<"__builtin_msa_sld_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sld_h : GCCBuiltin<"__builtin_msa_sld_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sld_w : GCCBuiltin<"__builtin_msa_sld_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_sld_d : GCCBuiltin<"__builtin_msa_sld_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_sldi_b : GCCBuiltin<"__builtin_msa_sldi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_sldi_h : GCCBuiltin<"__builtin_msa_sldi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_sldi_w : GCCBuiltin<"__builtin_msa_sldi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+def int_mips_sldi_d : GCCBuiltin<"__builtin_msa_sldi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_mips_sll_b : GCCBuiltin<"__builtin_msa_sll_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_sll_h : GCCBuiltin<"__builtin_msa_sll_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_sll_w : GCCBuiltin<"__builtin_msa_sll_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_sll_d : GCCBuiltin<"__builtin_msa_sll_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_slli_b : GCCBuiltin<"__builtin_msa_slli_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_slli_h : GCCBuiltin<"__builtin_msa_slli_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_slli_w : GCCBuiltin<"__builtin_msa_slli_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_slli_d : GCCBuiltin<"__builtin_msa_slli_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_splat_b : GCCBuiltin<"__builtin_msa_splat_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splat_h : GCCBuiltin<"__builtin_msa_splat_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splat_w : GCCBuiltin<"__builtin_msa_splat_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splat_d : GCCBuiltin<"__builtin_msa_splat_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_splati_b : GCCBuiltin<"__builtin_msa_splati_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splati_h : GCCBuiltin<"__builtin_msa_splati_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splati_w : GCCBuiltin<"__builtin_msa_splati_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_splati_d : GCCBuiltin<"__builtin_msa_splati_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_sra_b : GCCBuiltin<"__builtin_msa_sra_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_sra_h : GCCBuiltin<"__builtin_msa_sra_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_sra_w : GCCBuiltin<"__builtin_msa_sra_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_sra_d : GCCBuiltin<"__builtin_msa_sra_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_srai_b : GCCBuiltin<"__builtin_msa_srai_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srai_h : GCCBuiltin<"__builtin_msa_srai_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srai_w : GCCBuiltin<"__builtin_msa_srai_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srai_d : GCCBuiltin<"__builtin_msa_srai_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_srar_b : GCCBuiltin<"__builtin_msa_srar_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_srar_h : GCCBuiltin<"__builtin_msa_srar_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_srar_w : GCCBuiltin<"__builtin_msa_srar_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_srar_d : GCCBuiltin<"__builtin_msa_srar_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_srari_b : GCCBuiltin<"__builtin_msa_srari_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srari_h : GCCBuiltin<"__builtin_msa_srari_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srari_w : GCCBuiltin<"__builtin_msa_srari_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srari_d : GCCBuiltin<"__builtin_msa_srari_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_srl_b : GCCBuiltin<"__builtin_msa_srl_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_srl_h : GCCBuiltin<"__builtin_msa_srl_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_srl_w : GCCBuiltin<"__builtin_msa_srl_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_srl_d : GCCBuiltin<"__builtin_msa_srl_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_srli_b : GCCBuiltin<"__builtin_msa_srli_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srli_h : GCCBuiltin<"__builtin_msa_srli_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srli_w : GCCBuiltin<"__builtin_msa_srli_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srli_d : GCCBuiltin<"__builtin_msa_srli_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_srlr_b : GCCBuiltin<"__builtin_msa_srlr_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_srlr_h : GCCBuiltin<"__builtin_msa_srlr_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_srlr_w : GCCBuiltin<"__builtin_msa_srlr_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_srlr_d : GCCBuiltin<"__builtin_msa_srlr_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_srlri_b : GCCBuiltin<"__builtin_msa_srlri_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srlri_h : GCCBuiltin<"__builtin_msa_srlri_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srlri_w : GCCBuiltin<"__builtin_msa_srlri_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_srlri_d : GCCBuiltin<"__builtin_msa_srlri_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_st_b : GCCBuiltin<"__builtin_msa_st_b">,
+  Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadWriteArgMem]>;
+def int_mips_st_h : GCCBuiltin<"__builtin_msa_st_h">,
+  Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadWriteArgMem]>;
+def int_mips_st_w : GCCBuiltin<"__builtin_msa_st_w">,
+  Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadWriteArgMem]>;
+def int_mips_st_d : GCCBuiltin<"__builtin_msa_st_d">,
+  Intrinsic<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty],
+  [IntrReadWriteArgMem]>;
+
+def int_mips_subs_s_b : GCCBuiltin<"__builtin_msa_subs_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_subs_s_h : GCCBuiltin<"__builtin_msa_subs_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_subs_s_w : GCCBuiltin<"__builtin_msa_subs_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_subs_s_d : GCCBuiltin<"__builtin_msa_subs_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_subs_u_b : GCCBuiltin<"__builtin_msa_subs_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_subs_u_h : GCCBuiltin<"__builtin_msa_subs_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_subs_u_w : GCCBuiltin<"__builtin_msa_subs_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_subs_u_d : GCCBuiltin<"__builtin_msa_subs_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_subsus_u_b : GCCBuiltin<"__builtin_msa_subsus_u_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_subsus_u_h : GCCBuiltin<"__builtin_msa_subsus_u_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_subsus_u_w : GCCBuiltin<"__builtin_msa_subsus_u_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_subsus_u_d : GCCBuiltin<"__builtin_msa_subsus_u_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_subsuu_s_b : GCCBuiltin<"__builtin_msa_subsuu_s_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_subsuu_s_h : GCCBuiltin<"__builtin_msa_subsuu_s_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_subsuu_s_w : GCCBuiltin<"__builtin_msa_subsuu_s_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_subsuu_s_d : GCCBuiltin<"__builtin_msa_subsuu_s_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_subv_b : GCCBuiltin<"__builtin_msa_subv_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+def int_mips_subv_h : GCCBuiltin<"__builtin_msa_subv_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+def int_mips_subv_w : GCCBuiltin<"__builtin_msa_subv_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+def int_mips_subv_d : GCCBuiltin<"__builtin_msa_subv_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+def int_mips_subvi_b : GCCBuiltin<"__builtin_msa_subvi_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_subvi_h : GCCBuiltin<"__builtin_msa_subvi_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_subvi_w : GCCBuiltin<"__builtin_msa_subvi_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_mips_subvi_d : GCCBuiltin<"__builtin_msa_subvi_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+def int_mips_vshf_b : GCCBuiltin<"__builtin_msa_vshf_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+            [IntrNoMem]>;
+def int_mips_vshf_h : GCCBuiltin<"__builtin_msa_vshf_h">,
+  Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+            [IntrNoMem]>;
+def int_mips_vshf_w : GCCBuiltin<"__builtin_msa_vshf_w">,
+  Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+            [IntrNoMem]>;
+def int_mips_vshf_d : GCCBuiltin<"__builtin_msa_vshf_d">,
+  Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+            [IntrNoMem]>;
+
+def int_mips_xor_v : GCCBuiltin<"__builtin_msa_xor_v">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_mips_xori_b : GCCBuiltin<"__builtin_msa_xori_b">,
+  Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
new file mode 100644
index 0000000..cd51284
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsNVVM.td
@@ -0,0 +1,3740 @@
+//===- IntrinsicsNVVM.td - Defines NVVM intrinsics ---------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the NVVM-specific intrinsics for use with NVPTX.
+//
+//===----------------------------------------------------------------------===//
+
+def llvm_anyi64ptr_ty     : LLVMAnyPointerType<llvm_i64_ty>;     // (space)i64*
+
+//
+// MISC
+//
+
+  def int_nvvm_clz_i : GCCBuiltin<"__nvvm_clz_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_clz_ll : GCCBuiltin<"__nvvm_clz_ll">,
+      Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+  def int_nvvm_popc_i : GCCBuiltin<"__nvvm_popc_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_popc_ll : GCCBuiltin<"__nvvm_popc_ll">,
+      Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+  def int_nvvm_prmt : GCCBuiltin<"__nvvm_prmt">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Min Max
+//
+
+  def int_nvvm_min_i : GCCBuiltin<"__nvvm_min_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_min_ui : GCCBuiltin<"__nvvm_min_ui">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_min_ll : GCCBuiltin<"__nvvm_min_ll">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_min_ull : GCCBuiltin<"__nvvm_min_ull">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_max_i : GCCBuiltin<"__nvvm_max_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_max_ui : GCCBuiltin<"__nvvm_max_ui">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_max_ll : GCCBuiltin<"__nvvm_max_ll">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_max_ull : GCCBuiltin<"__nvvm_max_ull">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_fmin_f : GCCBuiltin<"__nvvm_fmin_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fmin_ftz_f : GCCBuiltin<"__nvvm_fmin_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_fmax_f : GCCBuiltin<"__nvvm_fmax_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty]
+        , [IntrNoMem, Commutative]>;
+  def int_nvvm_fmax_ftz_f : GCCBuiltin<"__nvvm_fmax_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_fmin_d : GCCBuiltin<"__nvvm_fmin_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fmax_d : GCCBuiltin<"__nvvm_fmax_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Multiplication
+//
+
+  def int_nvvm_mulhi_i : GCCBuiltin<"__nvvm_mulhi_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mulhi_ui : GCCBuiltin<"__nvvm_mulhi_ui">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_mulhi_ll : GCCBuiltin<"__nvvm_mulhi_ll">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mulhi_ull : GCCBuiltin<"__nvvm_mulhi_ull">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_mul_rn_ftz_f : GCCBuiltin<"__nvvm_mul_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rn_f : GCCBuiltin<"__nvvm_mul_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rz_ftz_f : GCCBuiltin<"__nvvm_mul_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rz_f : GCCBuiltin<"__nvvm_mul_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rm_ftz_f : GCCBuiltin<"__nvvm_mul_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rm_f : GCCBuiltin<"__nvvm_mul_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rp_ftz_f : GCCBuiltin<"__nvvm_mul_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rp_f : GCCBuiltin<"__nvvm_mul_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_mul_rn_d : GCCBuiltin<"__nvvm_mul_rn_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rz_d : GCCBuiltin<"__nvvm_mul_rz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rm_d : GCCBuiltin<"__nvvm_mul_rm_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul_rp_d : GCCBuiltin<"__nvvm_mul_rp_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_mul24_i : GCCBuiltin<"__nvvm_mul24_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_mul24_ui : GCCBuiltin<"__nvvm_mul24_ui">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Div
+//
+
+  def int_nvvm_div_approx_ftz_f : GCCBuiltin<"__nvvm_div_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_approx_f : GCCBuiltin<"__nvvm_div_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_div_rn_ftz_f : GCCBuiltin<"__nvvm_div_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rn_f : GCCBuiltin<"__nvvm_div_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_div_rz_ftz_f : GCCBuiltin<"__nvvm_div_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rz_f : GCCBuiltin<"__nvvm_div_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_div_rm_ftz_f : GCCBuiltin<"__nvvm_div_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rm_f : GCCBuiltin<"__nvvm_div_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_div_rp_ftz_f : GCCBuiltin<"__nvvm_div_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rp_f : GCCBuiltin<"__nvvm_div_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_div_rn_d : GCCBuiltin<"__nvvm_div_rn_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rz_d : GCCBuiltin<"__nvvm_div_rz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rm_d : GCCBuiltin<"__nvvm_div_rm_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_div_rp_d : GCCBuiltin<"__nvvm_div_rp_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Brev
+//
+
+  def int_nvvm_brev32 : GCCBuiltin<"__nvvm_brev32">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_brev64 : GCCBuiltin<"__nvvm_brev64">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+//
+// Sad
+//
+
+  def int_nvvm_sad_i : GCCBuiltin<"__nvvm_sad_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_sad_ui : GCCBuiltin<"__nvvm_sad_ui">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Floor  Ceil
+//
+
+  def int_nvvm_floor_ftz_f : GCCBuiltin<"__nvvm_floor_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_floor_f : GCCBuiltin<"__nvvm_floor_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_floor_d : GCCBuiltin<"__nvvm_floor_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_ceil_ftz_f : GCCBuiltin<"__nvvm_ceil_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_ceil_f : GCCBuiltin<"__nvvm_ceil_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_ceil_d : GCCBuiltin<"__nvvm_ceil_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Abs
+//
+
+  def int_nvvm_abs_i : GCCBuiltin<"__nvvm_abs_i">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_abs_ll : GCCBuiltin<"__nvvm_abs_ll">,
+      Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+  def int_nvvm_fabs_ftz_f : GCCBuiltin<"__nvvm_fabs_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_fabs_f : GCCBuiltin<"__nvvm_fabs_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_fabs_d : GCCBuiltin<"__nvvm_fabs_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Round
+//
+
+  def int_nvvm_round_ftz_f : GCCBuiltin<"__nvvm_round_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_round_f : GCCBuiltin<"__nvvm_round_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_round_d : GCCBuiltin<"__nvvm_round_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Trunc
+//
+
+  def int_nvvm_trunc_ftz_f : GCCBuiltin<"__nvvm_trunc_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_trunc_f : GCCBuiltin<"__nvvm_trunc_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_trunc_d : GCCBuiltin<"__nvvm_trunc_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Saturate
+//
+
+  def int_nvvm_saturate_ftz_f : GCCBuiltin<"__nvvm_saturate_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_saturate_f : GCCBuiltin<"__nvvm_saturate_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_saturate_d : GCCBuiltin<"__nvvm_saturate_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Exp2  Log2
+//
+
+  def int_nvvm_ex2_approx_ftz_f : GCCBuiltin<"__nvvm_ex2_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_ex2_approx_f : GCCBuiltin<"__nvvm_ex2_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_ex2_approx_d : GCCBuiltin<"__nvvm_ex2_approx_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_lg2_approx_ftz_f : GCCBuiltin<"__nvvm_lg2_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_lg2_approx_f : GCCBuiltin<"__nvvm_lg2_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_lg2_approx_d : GCCBuiltin<"__nvvm_lg2_approx_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Sin  Cos
+//
+
+  def int_nvvm_sin_approx_ftz_f : GCCBuiltin<"__nvvm_sin_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sin_approx_f : GCCBuiltin<"__nvvm_sin_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_cos_approx_ftz_f : GCCBuiltin<"__nvvm_cos_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_cos_approx_f : GCCBuiltin<"__nvvm_cos_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+//
+// Fma
+//
+
+  def int_nvvm_fma_rn_ftz_f : GCCBuiltin<"__nvvm_fma_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rn_f : GCCBuiltin<"__nvvm_fma_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rz_ftz_f : GCCBuiltin<"__nvvm_fma_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rz_f : GCCBuiltin<"__nvvm_fma_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rm_ftz_f : GCCBuiltin<"__nvvm_fma_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rm_f : GCCBuiltin<"__nvvm_fma_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rp_ftz_f : GCCBuiltin<"__nvvm_fma_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rp_f : GCCBuiltin<"__nvvm_fma_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_fma_rn_d : GCCBuiltin<"__nvvm_fma_rn_d">,
+      Intrinsic<[llvm_double_ty],
+        [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rz_d : GCCBuiltin<"__nvvm_fma_rz_d">,
+      Intrinsic<[llvm_double_ty],
+        [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rm_d : GCCBuiltin<"__nvvm_fma_rm_d">,
+      Intrinsic<[llvm_double_ty],
+        [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_fma_rp_d : GCCBuiltin<"__nvvm_fma_rp_d">,
+      Intrinsic<[llvm_double_ty],
+        [llvm_double_ty, llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Rcp
+//
+
+  def int_nvvm_rcp_rn_ftz_f : GCCBuiltin<"__nvvm_rcp_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rn_f : GCCBuiltin<"__nvvm_rcp_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rz_ftz_f : GCCBuiltin<"__nvvm_rcp_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rz_f : GCCBuiltin<"__nvvm_rcp_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rm_ftz_f : GCCBuiltin<"__nvvm_rcp_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rm_f : GCCBuiltin<"__nvvm_rcp_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rp_ftz_f : GCCBuiltin<"__nvvm_rcp_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rp_f : GCCBuiltin<"__nvvm_rcp_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_rcp_rn_d : GCCBuiltin<"__nvvm_rcp_rn_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rz_d : GCCBuiltin<"__nvvm_rcp_rz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rm_d : GCCBuiltin<"__nvvm_rcp_rm_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_rcp_rp_d : GCCBuiltin<"__nvvm_rcp_rp_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_rcp_approx_ftz_d : GCCBuiltin<"__nvvm_rcp_approx_ftz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Sqrt
+//
+
+  def int_nvvm_sqrt_f : GCCBuiltin<"__nvvm_sqrt_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rn_ftz_f : GCCBuiltin<"__nvvm_sqrt_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rn_f : GCCBuiltin<"__nvvm_sqrt_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rz_ftz_f : GCCBuiltin<"__nvvm_sqrt_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rz_f : GCCBuiltin<"__nvvm_sqrt_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rm_ftz_f : GCCBuiltin<"__nvvm_sqrt_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rm_f : GCCBuiltin<"__nvvm_sqrt_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rp_ftz_f : GCCBuiltin<"__nvvm_sqrt_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rp_f : GCCBuiltin<"__nvvm_sqrt_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_approx_ftz_f : GCCBuiltin<"__nvvm_sqrt_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_approx_f : GCCBuiltin<"__nvvm_sqrt_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_sqrt_rn_d : GCCBuiltin<"__nvvm_sqrt_rn_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rz_d : GCCBuiltin<"__nvvm_sqrt_rz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rm_d : GCCBuiltin<"__nvvm_sqrt_rm_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_sqrt_rp_d : GCCBuiltin<"__nvvm_sqrt_rp_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Rsqrt
+//
+
+  def int_nvvm_rsqrt_approx_ftz_f : GCCBuiltin<"__nvvm_rsqrt_approx_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rsqrt_approx_f : GCCBuiltin<"__nvvm_rsqrt_approx_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_rsqrt_approx_d : GCCBuiltin<"__nvvm_rsqrt_approx_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+
+//
+// Add
+//
+
+  def int_nvvm_add_rn_ftz_f : GCCBuiltin<"__nvvm_add_rn_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rn_f : GCCBuiltin<"__nvvm_add_rn_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rz_ftz_f : GCCBuiltin<"__nvvm_add_rz_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rz_f : GCCBuiltin<"__nvvm_add_rz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rm_ftz_f : GCCBuiltin<"__nvvm_add_rm_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rm_f : GCCBuiltin<"__nvvm_add_rm_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rp_ftz_f : GCCBuiltin<"__nvvm_add_rp_ftz_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rp_f : GCCBuiltin<"__nvvm_add_rp_f">,
+      Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_add_rn_d : GCCBuiltin<"__nvvm_add_rn_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rz_d : GCCBuiltin<"__nvvm_add_rz_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rm_d : GCCBuiltin<"__nvvm_add_rm_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+  def int_nvvm_add_rp_d : GCCBuiltin<"__nvvm_add_rp_d">,
+      Intrinsic<[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
+        [IntrNoMem, Commutative]>;
+
+//
+// Convert
+//
+
+  def int_nvvm_d2f_rn_ftz : GCCBuiltin<"__nvvm_d2f_rn_ftz">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rn : GCCBuiltin<"__nvvm_d2f_rn">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rz_ftz : GCCBuiltin<"__nvvm_d2f_rz_ftz">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rz : GCCBuiltin<"__nvvm_d2f_rz">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rm_ftz : GCCBuiltin<"__nvvm_d2f_rm_ftz">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rm : GCCBuiltin<"__nvvm_d2f_rm">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rp_ftz : GCCBuiltin<"__nvvm_d2f_rp_ftz">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2f_rp : GCCBuiltin<"__nvvm_d2f_rp">,
+      Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_d2i_rn : GCCBuiltin<"__nvvm_d2i_rn">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2i_rz : GCCBuiltin<"__nvvm_d2i_rz">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2i_rm : GCCBuiltin<"__nvvm_d2i_rm">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2i_rp : GCCBuiltin<"__nvvm_d2i_rp">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_d2ui_rn : GCCBuiltin<"__nvvm_d2ui_rn">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ui_rz : GCCBuiltin<"__nvvm_d2ui_rz">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ui_rm : GCCBuiltin<"__nvvm_d2ui_rm">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ui_rp : GCCBuiltin<"__nvvm_d2ui_rp">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_i2d_rn : GCCBuiltin<"__nvvm_i2d_rn">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2d_rz : GCCBuiltin<"__nvvm_i2d_rz">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2d_rm : GCCBuiltin<"__nvvm_i2d_rm">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2d_rp : GCCBuiltin<"__nvvm_i2d_rp">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_nvvm_ui2d_rn : GCCBuiltin<"__nvvm_ui2d_rn">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2d_rz : GCCBuiltin<"__nvvm_ui2d_rz">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2d_rm : GCCBuiltin<"__nvvm_ui2d_rm">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2d_rp : GCCBuiltin<"__nvvm_ui2d_rp">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_nvvm_f2i_rn_ftz : GCCBuiltin<"__nvvm_f2i_rn_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rn : GCCBuiltin<"__nvvm_f2i_rn">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rz_ftz : GCCBuiltin<"__nvvm_f2i_rz_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rz : GCCBuiltin<"__nvvm_f2i_rz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rm_ftz : GCCBuiltin<"__nvvm_f2i_rm_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rm : GCCBuiltin<"__nvvm_f2i_rm">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rp_ftz : GCCBuiltin<"__nvvm_f2i_rp_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2i_rp : GCCBuiltin<"__nvvm_f2i_rp">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_f2ui_rn_ftz : GCCBuiltin<"__nvvm_f2ui_rn_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rn : GCCBuiltin<"__nvvm_f2ui_rn">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rz_ftz : GCCBuiltin<"__nvvm_f2ui_rz_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rz : GCCBuiltin<"__nvvm_f2ui_rz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rm_ftz : GCCBuiltin<"__nvvm_f2ui_rm_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rm : GCCBuiltin<"__nvvm_f2ui_rm">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rp_ftz : GCCBuiltin<"__nvvm_f2ui_rp_ftz">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ui_rp : GCCBuiltin<"__nvvm_f2ui_rp">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_i2f_rn : GCCBuiltin<"__nvvm_i2f_rn">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2f_rz : GCCBuiltin<"__nvvm_i2f_rz">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2f_rm : GCCBuiltin<"__nvvm_i2f_rm">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_i2f_rp : GCCBuiltin<"__nvvm_i2f_rp">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_nvvm_ui2f_rn : GCCBuiltin<"__nvvm_ui2f_rn">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2f_rz : GCCBuiltin<"__nvvm_ui2f_rz">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2f_rm : GCCBuiltin<"__nvvm_ui2f_rm">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+  def int_nvvm_ui2f_rp : GCCBuiltin<"__nvvm_ui2f_rp">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_nvvm_lohi_i2d : GCCBuiltin<"__nvvm_lohi_i2d">,
+      Intrinsic<[llvm_double_ty], [llvm_i32_ty, llvm_i32_ty],
+        [IntrNoMem, Commutative]>;
+
+  def int_nvvm_d2i_lo : GCCBuiltin<"__nvvm_d2i_lo">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2i_hi : GCCBuiltin<"__nvvm_d2i_hi">,
+      Intrinsic<[llvm_i32_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_f2ll_rn_ftz : GCCBuiltin<"__nvvm_f2ll_rn_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rn : GCCBuiltin<"__nvvm_f2ll_rn">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rz_ftz : GCCBuiltin<"__nvvm_f2ll_rz_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rz : GCCBuiltin<"__nvvm_f2ll_rz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rm_ftz : GCCBuiltin<"__nvvm_f2ll_rm_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rm : GCCBuiltin<"__nvvm_f2ll_rm">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rp_ftz : GCCBuiltin<"__nvvm_f2ll_rp_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ll_rp : GCCBuiltin<"__nvvm_f2ll_rp">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_f2ull_rn_ftz : GCCBuiltin<"__nvvm_f2ull_rn_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rn : GCCBuiltin<"__nvvm_f2ull_rn">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rz_ftz : GCCBuiltin<"__nvvm_f2ull_rz_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rz : GCCBuiltin<"__nvvm_f2ull_rz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rm_ftz : GCCBuiltin<"__nvvm_f2ull_rm_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rm : GCCBuiltin<"__nvvm_f2ull_rm">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rp_ftz : GCCBuiltin<"__nvvm_f2ull_rp_ftz">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2ull_rp : GCCBuiltin<"__nvvm_f2ull_rp">,
+      Intrinsic<[llvm_i64_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_d2ll_rn : GCCBuiltin<"__nvvm_d2ll_rn">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ll_rz : GCCBuiltin<"__nvvm_d2ll_rz">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ll_rm : GCCBuiltin<"__nvvm_d2ll_rm">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ll_rp : GCCBuiltin<"__nvvm_d2ll_rp">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_d2ull_rn : GCCBuiltin<"__nvvm_d2ull_rn">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ull_rz : GCCBuiltin<"__nvvm_d2ull_rz">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ull_rm : GCCBuiltin<"__nvvm_d2ull_rm">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_nvvm_d2ull_rp : GCCBuiltin<"__nvvm_d2ull_rp">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+  def int_nvvm_ll2f_rn : GCCBuiltin<"__nvvm_ll2f_rn">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2f_rz : GCCBuiltin<"__nvvm_ll2f_rz">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2f_rm : GCCBuiltin<"__nvvm_ll2f_rm">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2f_rp : GCCBuiltin<"__nvvm_ll2f_rp">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2f_rn : GCCBuiltin<"__nvvm_ull2f_rn">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2f_rz : GCCBuiltin<"__nvvm_ull2f_rz">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2f_rm : GCCBuiltin<"__nvvm_ull2f_rm">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2f_rp : GCCBuiltin<"__nvvm_ull2f_rp">,
+      Intrinsic<[llvm_float_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+  def int_nvvm_ll2d_rn : GCCBuiltin<"__nvvm_ll2d_rn">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2d_rz : GCCBuiltin<"__nvvm_ll2d_rz">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2d_rm : GCCBuiltin<"__nvvm_ll2d_rm">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ll2d_rp : GCCBuiltin<"__nvvm_ll2d_rp">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2d_rn : GCCBuiltin<"__nvvm_ull2d_rn">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2d_rz : GCCBuiltin<"__nvvm_ull2d_rz">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2d_rm : GCCBuiltin<"__nvvm_ull2d_rm">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_ull2d_rp : GCCBuiltin<"__nvvm_ull2d_rp">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+
+  def int_nvvm_f2h_rn_ftz : GCCBuiltin<"__nvvm_f2h_rn_ftz">,
+      Intrinsic<[llvm_i16_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_f2h_rn : GCCBuiltin<"__nvvm_f2h_rn">,
+      Intrinsic<[llvm_i16_ty], [llvm_float_ty], [IntrNoMem]>;
+
+  def int_nvvm_h2f : GCCBuiltin<"__nvvm_h2f">,
+      Intrinsic<[llvm_float_ty], [llvm_i16_ty], [IntrNoMem]>;
+
+//
+// Bitcast
+//
+
+  def int_nvvm_bitcast_f2i : GCCBuiltin<"__nvvm_bitcast_f2i">,
+      Intrinsic<[llvm_i32_ty], [llvm_float_ty], [IntrNoMem]>;
+  def int_nvvm_bitcast_i2f : GCCBuiltin<"__nvvm_bitcast_i2f">,
+      Intrinsic<[llvm_float_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_nvvm_bitcast_ll2d : GCCBuiltin<"__nvvm_bitcast_ll2d">,
+      Intrinsic<[llvm_double_ty], [llvm_i64_ty], [IntrNoMem]>;
+  def int_nvvm_bitcast_d2ll : GCCBuiltin<"__nvvm_bitcast_d2ll">,
+      Intrinsic<[llvm_i64_ty], [llvm_double_ty], [IntrNoMem]>;
+
+
+// Atomic not available as an llvm intrinsic.
+  def int_nvvm_atomic_load_add_f32 : Intrinsic<[llvm_float_ty],
+          [LLVMAnyPointerType<llvm_float_ty>, llvm_float_ty],
+                                      [IntrReadWriteArgMem, NoCapture<0>]>;
+  def int_nvvm_atomic_load_inc_32 : Intrinsic<[llvm_i32_ty],
+          [LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
+                                      [IntrReadWriteArgMem, NoCapture<0>]>;
+  def int_nvvm_atomic_load_dec_32 : Intrinsic<[llvm_i32_ty],
+          [LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
+                                      [IntrReadWriteArgMem, NoCapture<0>]>;
+
+// Bar.Sync
+  def int_cuda_syncthreads : GCCBuiltin<"__syncthreads">,
+      Intrinsic<[], [], [IntrNoDuplicate]>;
+  def int_nvvm_barrier0 : GCCBuiltin<"__nvvm_bar0">,
+      Intrinsic<[], [], [IntrNoDuplicate]>;
+  def int_nvvm_barrier0_popc : GCCBuiltin<"__nvvm_bar0_popc">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
+  def int_nvvm_barrier0_and : GCCBuiltin<"__nvvm_bar0_and">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
+  def int_nvvm_barrier0_or : GCCBuiltin<"__nvvm_bar0_or">,
+      Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
+
+  // Membar
+  def int_nvvm_membar_cta : GCCBuiltin<"__nvvm_membar_cta">,
+      Intrinsic<[], [], []>;
+  def int_nvvm_membar_gl : GCCBuiltin<"__nvvm_membar_gl">,
+      Intrinsic<[], [], []>;
+  def int_nvvm_membar_sys : GCCBuiltin<"__nvvm_membar_sys">,
+      Intrinsic<[], [], []>;
+
+
+// Accessing special registers
+  def int_nvvm_read_ptx_sreg_tid_x :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_tid_x">;
+  def int_nvvm_read_ptx_sreg_tid_y :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_tid_y">;
+  def int_nvvm_read_ptx_sreg_tid_z :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_tid_z">;
+
+  def int_nvvm_read_ptx_sreg_ntid_x :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_x">;
+  def int_nvvm_read_ptx_sreg_ntid_y :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_y">;
+  def int_nvvm_read_ptx_sreg_ntid_z :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ntid_z">;
+
+  def int_nvvm_read_ptx_sreg_ctaid_x :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_x">;
+  def int_nvvm_read_ptx_sreg_ctaid_y :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_y">;
+  def int_nvvm_read_ptx_sreg_ctaid_z :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_ctaid_z">;
+
+  def int_nvvm_read_ptx_sreg_nctaid_x :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_x">;
+  def int_nvvm_read_ptx_sreg_nctaid_y :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_y">;
+  def int_nvvm_read_ptx_sreg_nctaid_z :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_nctaid_z">;
+
+  def int_nvvm_read_ptx_sreg_warpsize :
+      Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+      GCCBuiltin<"__nvvm_read_ptx_sreg_warpsize">;
+
+
+// Generated within nvvm. Use for ldu on sm_20 or later
+def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldu.global.i">;
+def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldu.global.f">;
+def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldu.global.p">;
+
+// Generated within nvvm. Use for ldg on sm_35 or later
+def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldg.global.i">;
+def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldg.global.f">;
+def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty],
+  [LLVMAnyPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+  "llvm.nvvm.ldg.global.p">;
+
+// Use for generic pointers
+// - These intrinsics are used to convert address spaces.
+// - The input pointer and output pointer must have the same type, except for
+//   the address-space. (This restriction is not enforced here as there is
+//   currently no way to describe it).
+// - This complements the llvm bitcast, which can be used to cast one type
+//   of pointer to another type of pointer, while the address space remains
+//   the same.
+def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.local.to.gen">;
+def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.shared.to.gen">;
+def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.global.to.gen">;
+def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.constant.to.gen">;
+
+def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.gen.to.global">;
+def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.gen.to.shared">;
+def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.gen.to.local">;
+def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty],
+                 [llvm_anyptr_ty], [IntrNoMem],
+                 "llvm.nvvm.ptr.gen.to.constant">;
+
+// Used in nvvm internally to help address space opt and ptx code generation
+// This is for params that are passed to kernel functions by pointer by-val.
+def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty],
+                                     [llvm_anyptr_ty],
+                                   [IntrNoMem],
+                                   "llvm.nvvm.ptr.gen.to.param">;
+
+// Move intrinsics, used in nvvm internally
+
+def int_nvvm_move_i16 : Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem],
+  "llvm.nvvm.move.i16">;
+def int_nvvm_move_i32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem],
+  "llvm.nvvm.move.i32">;
+def int_nvvm_move_i64 : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem],
+  "llvm.nvvm.move.i64">;
+def int_nvvm_move_float : Intrinsic<[llvm_float_ty], [llvm_float_ty],
+  [IntrNoMem], "llvm.nvvm.move.float">;
+def int_nvvm_move_double : Intrinsic<[llvm_double_ty], [llvm_double_ty],
+  [IntrNoMem], "llvm.nvvm.move.double">;
+def int_nvvm_move_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty],
+  [IntrNoMem, NoCapture<0>], "llvm.nvvm.move.ptr">;
+
+
+// For getting the handle from a texture or surface variable
+def int_nvvm_texsurf_handle
+  : Intrinsic<[llvm_i64_ty], [llvm_metadata_ty, llvm_anyi64ptr_ty],
+              [IntrNoMem], "llvm.nvvm.texsurf.handle">;
+def int_nvvm_texsurf_handle_internal
+  : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
+              [IntrNoMem], "llvm.nvvm.texsurf.handle.internal">;
+
+/// Error / Warn
+def int_nvvm_compiler_error :
+    Intrinsic<[], [llvm_anyptr_ty], [], "llvm.nvvm.compiler.error">;
+def int_nvvm_compiler_warn :
+    Intrinsic<[], [llvm_anyptr_ty], [], "llvm.nvvm.compiler.warn">;
+
+def int_nvvm_reflect :
+  Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem], "llvm.nvvm.reflect">;
+
+// isspacep.{const, global, local, shared}
+def int_nvvm_isspacep_const
+  : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+              "llvm.nvvm.isspacep.const">,
+    GCCBuiltin<"__nvvm_isspacep_const">;
+def int_nvvm_isspacep_global
+  : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+              "llvm.nvvm.isspacep.global">,
+    GCCBuiltin<"__nvvm_isspacep_global">;
+def int_nvvm_isspacep_local
+  : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+              "llvm.nvvm.isspacep.local">,
+    GCCBuiltin<"__nvvm_isspacep_local">;
+def int_nvvm_isspacep_shared
+  : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty], [IntrNoMem],
+              "llvm.nvvm.isspacep.shared">,
+    GCCBuiltin<"__nvvm_isspacep_shared">;
+
+// Environment register read
+def int_nvvm_read_ptx_sreg_envreg0
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg0">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg0">;
+def int_nvvm_read_ptx_sreg_envreg1
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg1">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg1">;
+def int_nvvm_read_ptx_sreg_envreg2
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg2">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg2">;
+def int_nvvm_read_ptx_sreg_envreg3
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg3">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg3">;
+def int_nvvm_read_ptx_sreg_envreg4
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg4">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg4">;
+def int_nvvm_read_ptx_sreg_envreg5
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg5">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg5">;
+def int_nvvm_read_ptx_sreg_envreg6
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg6">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg6">;
+def int_nvvm_read_ptx_sreg_envreg7
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg7">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg7">;
+def int_nvvm_read_ptx_sreg_envreg8
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg8">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg8">;
+def int_nvvm_read_ptx_sreg_envreg9
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg9">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg9">;
+def int_nvvm_read_ptx_sreg_envreg10
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg10">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg10">;
+def int_nvvm_read_ptx_sreg_envreg11
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg11">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg11">;
+def int_nvvm_read_ptx_sreg_envreg12
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg12">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg12">;
+def int_nvvm_read_ptx_sreg_envreg13
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg13">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg13">;
+def int_nvvm_read_ptx_sreg_envreg14
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg14">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg14">;
+def int_nvvm_read_ptx_sreg_envreg15
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg15">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg15">;
+def int_nvvm_read_ptx_sreg_envreg16
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg16">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg16">;
+def int_nvvm_read_ptx_sreg_envreg17
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg17">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg17">;
+def int_nvvm_read_ptx_sreg_envreg18
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg18">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg18">;
+def int_nvvm_read_ptx_sreg_envreg19
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg19">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg19">;
+def int_nvvm_read_ptx_sreg_envreg20
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg20">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg20">;
+def int_nvvm_read_ptx_sreg_envreg21
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg21">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg21">;
+def int_nvvm_read_ptx_sreg_envreg22
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg22">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg22">;
+def int_nvvm_read_ptx_sreg_envreg23
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg23">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg23">;
+def int_nvvm_read_ptx_sreg_envreg24
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg24">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg24">;
+def int_nvvm_read_ptx_sreg_envreg25
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg25">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg25">;
+def int_nvvm_read_ptx_sreg_envreg26
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg26">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg26">;
+def int_nvvm_read_ptx_sreg_envreg27
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg27">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg27">;
+def int_nvvm_read_ptx_sreg_envreg28
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg28">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg28">;
+def int_nvvm_read_ptx_sreg_envreg29
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg29">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg29">;
+def int_nvvm_read_ptx_sreg_envreg30
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg30">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg30">;
+def int_nvvm_read_ptx_sreg_envreg31
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem],
+              "llvm.nvvm.read.ptx.sreg.envreg31">,
+    GCCBuiltin<"__nvvm_read_ptx_sreg_envreg31">;
+
+
+// Texture Fetch
+// texmode_independent
+def int_nvvm_tex_1d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.v4f32.s32">;
+def int_nvvm_tex_1d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.v4f32.f32">;
+def int_nvvm_tex_1d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.level.v4f32.f32">;
+def int_nvvm_tex_1d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.grad.v4f32.f32">;
+def int_nvvm_tex_1d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.v4s32.s32">;
+def int_nvvm_tex_1d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.v4s32.f32">;
+def int_nvvm_tex_1d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.level.v4s32.f32">;
+def int_nvvm_tex_1d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.grad.v4s32.f32">;
+def int_nvvm_tex_1d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.v4u32.s32">;
+def int_nvvm_tex_1d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.v4u32.f32">;
+def int_nvvm_tex_1d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.level.v4u32.f32">;
+def int_nvvm_tex_1d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.grad.v4u32.f32">;
+
+def int_nvvm_tex_1d_array_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.array.v4f32.s32">;
+def int_nvvm_tex_1d_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.v4f32.f32">;
+def int_nvvm_tex_1d_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.level.v4f32.f32">;
+def int_nvvm_tex_1d_array_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.grad.v4f32.f32">;
+def int_nvvm_tex_1d_array_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.array.v4s32.s32">;
+def int_nvvm_tex_1d_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.v4s32.f32">;
+def int_nvvm_tex_1d_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.level.v4s32.f32">;
+def int_nvvm_tex_1d_array_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.grad.v4s32.f32">;
+def int_nvvm_tex_1d_array_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.1d.array.v4u32.s32">;
+def int_nvvm_tex_1d_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.v4u32.f32">;
+def int_nvvm_tex_1d_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.level.v4u32.f32">;
+def int_nvvm_tex_1d_array_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.1d.array.grad.v4u32.f32">;
+
+def int_nvvm_tex_2d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.v4f32.s32">;
+def int_nvvm_tex_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.v4f32.f32">;
+def int_nvvm_tex_2d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.level.v4f32.f32">;
+def int_nvvm_tex_2d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.grad.v4f32.f32">;
+def int_nvvm_tex_2d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.v4s32.s32">;
+def int_nvvm_tex_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.v4s32.f32">;
+def int_nvvm_tex_2d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.level.v4s32.f32">;
+def int_nvvm_tex_2d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.grad.v4s32.f32">;
+def int_nvvm_tex_2d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.v4u32.s32">;
+def int_nvvm_tex_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.v4u32.f32">;
+def int_nvvm_tex_2d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.level.v4u32.f32">;
+def int_nvvm_tex_2d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.grad.v4u32.f32">;
+
+def int_nvvm_tex_2d_array_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.array.v4f32.s32">;
+def int_nvvm_tex_2d_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.v4f32.f32">;
+def int_nvvm_tex_2d_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.level.v4f32.f32">;
+def int_nvvm_tex_2d_array_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.grad.v4f32.f32">;
+def int_nvvm_tex_2d_array_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.array.v4s32.s32">;
+def int_nvvm_tex_2d_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.v4s32.f32">;
+def int_nvvm_tex_2d_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.level.v4s32.f32">;
+def int_nvvm_tex_2d_array_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.grad.v4s32.f32">;
+def int_nvvm_tex_2d_array_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.2d.array.v4u32.s32">;
+def int_nvvm_tex_2d_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.v4u32.f32">;
+def int_nvvm_tex_2d_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.level.v4u32.f32">;
+def int_nvvm_tex_2d_array_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.2d.array.grad.v4u32.f32">;
+
+def int_nvvm_tex_3d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.3d.v4f32.s32">;
+def int_nvvm_tex_3d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.v4f32.f32">;
+def int_nvvm_tex_3d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.level.v4f32.f32">;
+def int_nvvm_tex_3d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.grad.v4f32.f32">;
+def int_nvvm_tex_3d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.3d.v4s32.s32">;
+def int_nvvm_tex_3d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.v4s32.f32">;
+def int_nvvm_tex_3d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.level.v4s32.f32">;
+def int_nvvm_tex_3d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.grad.v4s32.f32">;
+def int_nvvm_tex_3d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.3d.v4u32.s32">;
+def int_nvvm_tex_3d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.v4u32.f32">;
+def int_nvvm_tex_3d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.level.v4u32.f32">;
+def int_nvvm_tex_3d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.3d.grad.v4u32.f32">;
+
+def int_nvvm_tex_cube_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.v4f32.f32">;
+def int_nvvm_tex_cube_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.level.v4f32.f32">;
+def int_nvvm_tex_cube_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.v4s32.f32">;
+def int_nvvm_tex_cube_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.level.v4s32.f32">;
+def int_nvvm_tex_cube_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.v4u32.f32">;
+def int_nvvm_tex_cube_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.level.v4u32.f32">;
+
+def int_nvvm_tex_cube_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.v4f32.f32">;
+def int_nvvm_tex_cube_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.level.v4f32.f32">;
+def int_nvvm_tex_cube_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.v4s32.f32">;
+def int_nvvm_tex_cube_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.level.v4s32.f32">;
+def int_nvvm_tex_cube_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.v4u32.f32">;
+def int_nvvm_tex_cube_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.cube.array.level.v4u32.f32">;
+
+def int_nvvm_tld4_r_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.r.2d.v4f32.f32">;
+def int_nvvm_tld4_g_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.g.2d.v4f32.f32">;
+def int_nvvm_tld4_b_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.b.2d.v4f32.f32">;
+def int_nvvm_tld4_a_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.a.2d.v4f32.f32">;
+def int_nvvm_tld4_r_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.r.2d.v4s32.f32">;
+def int_nvvm_tld4_g_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.g.2d.v4s32.f32">;
+def int_nvvm_tld4_b_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.b.2d.v4s32.f32">;
+def int_nvvm_tld4_a_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.a.2d.v4s32.f32">;
+def int_nvvm_tld4_r_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.r.2d.v4u32.f32">;
+def int_nvvm_tld4_g_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.g.2d.v4u32.f32">;
+def int_nvvm_tld4_b_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.b.2d.v4u32.f32">;
+def int_nvvm_tld4_a_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.a.2d.v4u32.f32">;
+
+
+// texmode_unified
+def int_nvvm_tex_unified_1d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4f32.s32">;
+def int_nvvm_tex_unified_1d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4f32.f32">;
+def int_nvvm_tex_unified_1d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.level.v4f32.f32">;
+def int_nvvm_tex_unified_1d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.grad.v4f32.f32">;
+def int_nvvm_tex_unified_1d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4s32.s32">;
+def int_nvvm_tex_unified_1d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4s32.f32">;
+def int_nvvm_tex_unified_1d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.level.v4s32.f32">;
+def int_nvvm_tex_unified_1d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.grad.v4s32.f32">;
+def int_nvvm_tex_unified_1d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4u32.s32">;
+def int_nvvm_tex_unified_1d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.v4u32.f32">;
+def int_nvvm_tex_unified_1d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.level.v4u32.f32">;
+def int_nvvm_tex_unified_1d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.grad.v4u32.f32">;
+
+def int_nvvm_tex_unified_1d_array_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4f32.s32">;
+def int_nvvm_tex_unified_1d_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4f32.f32">;
+def int_nvvm_tex_unified_1d_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.level.v4f32.f32">;
+def int_nvvm_tex_unified_1d_array_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.grad.v4f32.f32">;
+def int_nvvm_tex_unified_1d_array_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4s32.s32">;
+def int_nvvm_tex_unified_1d_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4s32.f32">;
+def int_nvvm_tex_unified_1d_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.level.v4s32.f32">;
+def int_nvvm_tex_unified_1d_array_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.grad.v4s32.f32">;
+def int_nvvm_tex_unified_1d_array_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4u32.s32">;
+def int_nvvm_tex_unified_1d_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.v4u32.f32">;
+def int_nvvm_tex_unified_1d_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.level.v4u32.f32">;
+def int_nvvm_tex_unified_1d_array_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.1d.array.grad.v4u32.f32">;
+
+def int_nvvm_tex_unified_2d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4f32.s32">;
+def int_nvvm_tex_unified_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4f32.f32">;
+def int_nvvm_tex_unified_2d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.level.v4f32.f32">;
+def int_nvvm_tex_unified_2d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.grad.v4f32.f32">;
+def int_nvvm_tex_unified_2d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4s32.s32">;
+def int_nvvm_tex_unified_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4s32.f32">;
+def int_nvvm_tex_unified_2d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.level.v4s32.f32">;
+def int_nvvm_tex_unified_2d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.grad.v4s32.f32">;
+def int_nvvm_tex_unified_2d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4u32.s32">;
+def int_nvvm_tex_unified_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.v4u32.f32">;
+def int_nvvm_tex_unified_2d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.level.v4u32.f32">;
+def int_nvvm_tex_unified_2d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.grad.v4u32.f32">;
+
+def int_nvvm_tex_unified_2d_array_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4f32.s32">;
+def int_nvvm_tex_unified_2d_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4f32.f32">;
+def int_nvvm_tex_unified_2d_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.level.v4f32.f32">;
+def int_nvvm_tex_unified_2d_array_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.grad.v4f32.f32">;
+def int_nvvm_tex_unified_2d_array_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4s32.s32">;
+def int_nvvm_tex_unified_2d_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4s32.f32">;
+def int_nvvm_tex_unified_2d_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.level.v4s32.f32">;
+def int_nvvm_tex_unified_2d_array_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.grad.v4s32.f32">;
+def int_nvvm_tex_unified_2d_array_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+               llvm_i32_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4u32.s32">;
+def int_nvvm_tex_unified_2d_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.v4u32.f32">;
+def int_nvvm_tex_unified_2d_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.level.v4u32.f32">;
+def int_nvvm_tex_unified_2d_array_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.2d.array.grad.v4u32.f32">;
+
+def int_nvvm_tex_unified_3d_v4f32_s32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.unified.3d.v4f32.s32">;
+def int_nvvm_tex_unified_3d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.v4f32.f32">;
+def int_nvvm_tex_unified_3d_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.level.v4f32.f32">;
+def int_nvvm_tex_unified_3d_grad_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.grad.v4f32.f32">;
+def int_nvvm_tex_unified_3d_v4s32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.unified.3d.v4s32.s32">;
+def int_nvvm_tex_unified_3d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.v4s32.f32">;
+def int_nvvm_tex_unified_3d_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.level.v4s32.f32">;
+def int_nvvm_tex_unified_3d_grad_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.grad.v4s32.f32">;
+def int_nvvm_tex_unified_3d_v4u32_s32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [], "llvm.nvvm.tex.unified.3d.v4u32.s32">;
+def int_nvvm_tex_unified_3d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.v4u32.f32">;
+def int_nvvm_tex_unified_3d_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.level.v4u32.f32">;
+def int_nvvm_tex_unified_3d_grad_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.3d.grad.v4u32.f32">;
+
+def int_nvvm_tex_unified_cube_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.v4f32.f32">;
+def int_nvvm_tex_unified_cube_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.level.v4f32.f32">;
+def int_nvvm_tex_unified_cube_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.v4s32.f32">;
+def int_nvvm_tex_unified_cube_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.level.v4s32.f32">;
+def int_nvvm_tex_unified_cube_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.v4u32.f32">;
+def int_nvvm_tex_unified_cube_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.level.v4u32.f32">;
+
+def int_nvvm_tex_unified_cube_array_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.v4f32.f32">;
+def int_nvvm_tex_unified_cube_array_level_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.level.v4f32.f32">;
+def int_nvvm_tex_unified_cube_array_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.v4s32.f32">;
+def int_nvvm_tex_unified_cube_array_level_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.level.v4s32.f32">;
+def int_nvvm_tex_unified_cube_array_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.v4u32.f32">;
+def int_nvvm_tex_unified_cube_array_level_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty,
+               llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tex.unified.cube.array.level.v4u32.f32">;
+
+def int_nvvm_tld4_unified_r_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.r.2d.v4f32.f32">;
+def int_nvvm_tld4_unified_g_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.g.2d.v4f32.f32">;
+def int_nvvm_tld4_unified_b_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.b.2d.v4f32.f32">;
+def int_nvvm_tld4_unified_a_2d_v4f32_f32
+  : Intrinsic<[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_float_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.a.2d.v4f32.f32">;
+def int_nvvm_tld4_unified_r_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.r.2d.v4s32.f32">;
+def int_nvvm_tld4_unified_g_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.g.2d.v4s32.f32">;
+def int_nvvm_tld4_unified_b_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.b.2d.v4s32.f32">;
+def int_nvvm_tld4_unified_a_2d_v4s32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.a.2d.v4s32.f32">;
+def int_nvvm_tld4_unified_r_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.r.2d.v4u32.f32">;
+def int_nvvm_tld4_unified_g_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.g.2d.v4u32.f32">;
+def int_nvvm_tld4_unified_b_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.b.2d.v4u32.f32">;
+def int_nvvm_tld4_unified_a_2d_v4u32_f32
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_float_ty, llvm_float_ty], [],
+              "llvm.nvvm.tld4.unified.a.2d.v4u32.f32">;
+
+
+//=== Surface Load
+// .clamp variants
+def int_nvvm_suld_1d_i8_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i8.clamp">;
+def int_nvvm_suld_1d_i16_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i16.clamp">;
+def int_nvvm_suld_1d_i32_clamp
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i32.clamp">;
+def int_nvvm_suld_1d_i64_clamp
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i64.clamp">;
+def int_nvvm_suld_1d_v2i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i8.clamp">;
+def int_nvvm_suld_1d_v2i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i16.clamp">;
+def int_nvvm_suld_1d_v2i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i32.clamp">;
+def int_nvvm_suld_1d_v2i64_clamp
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i64.clamp">;
+def int_nvvm_suld_1d_v4i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i8.clamp">;
+def int_nvvm_suld_1d_v4i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i16.clamp">;
+def int_nvvm_suld_1d_v4i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i32.clamp">;
+
+def int_nvvm_suld_1d_array_i8_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i8.clamp">;
+def int_nvvm_suld_1d_array_i16_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i16.clamp">;
+def int_nvvm_suld_1d_array_i32_clamp
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i32.clamp">;
+def int_nvvm_suld_1d_array_i64_clamp
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i64.clamp">;
+def int_nvvm_suld_1d_array_v2i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i8.clamp">;
+def int_nvvm_suld_1d_array_v2i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i16.clamp">;
+def int_nvvm_suld_1d_array_v2i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i32.clamp">;
+def int_nvvm_suld_1d_array_v2i64_clamp
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i64.clamp">;
+def int_nvvm_suld_1d_array_v4i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i8.clamp">;
+def int_nvvm_suld_1d_array_v4i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i16.clamp">;
+def int_nvvm_suld_1d_array_v4i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i32.clamp">;
+
+def int_nvvm_suld_2d_i8_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i8.clamp">;
+def int_nvvm_suld_2d_i16_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i16.clamp">;
+def int_nvvm_suld_2d_i32_clamp
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i32.clamp">;
+def int_nvvm_suld_2d_i64_clamp
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i64.clamp">;
+def int_nvvm_suld_2d_v2i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i8.clamp">;
+def int_nvvm_suld_2d_v2i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i16.clamp">;
+def int_nvvm_suld_2d_v2i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i32.clamp">;
+def int_nvvm_suld_2d_v2i64_clamp
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i64.clamp">;
+def int_nvvm_suld_2d_v4i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i8.clamp">;
+def int_nvvm_suld_2d_v4i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i16.clamp">;
+def int_nvvm_suld_2d_v4i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i32.clamp">;
+
+def int_nvvm_suld_2d_array_i8_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i8.clamp">;
+def int_nvvm_suld_2d_array_i16_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i16.clamp">;
+def int_nvvm_suld_2d_array_i32_clamp
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i32.clamp">;
+def int_nvvm_suld_2d_array_i64_clamp
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i64.clamp">;
+def int_nvvm_suld_2d_array_v2i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i8.clamp">;
+def int_nvvm_suld_2d_array_v2i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i16.clamp">;
+def int_nvvm_suld_2d_array_v2i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i32.clamp">;
+def int_nvvm_suld_2d_array_v2i64_clamp
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i64.clamp">;
+def int_nvvm_suld_2d_array_v4i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i8.clamp">;
+def int_nvvm_suld_2d_array_v4i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i16.clamp">;
+def int_nvvm_suld_2d_array_v4i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i32.clamp">;
+
+def int_nvvm_suld_3d_i8_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i8.clamp">;
+def int_nvvm_suld_3d_i16_clamp
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i16.clamp">;
+def int_nvvm_suld_3d_i32_clamp
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i32.clamp">;
+def int_nvvm_suld_3d_i64_clamp
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i64.clamp">;
+def int_nvvm_suld_3d_v2i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i8.clamp">;
+def int_nvvm_suld_3d_v2i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i16.clamp">;
+def int_nvvm_suld_3d_v2i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i32.clamp">;
+def int_nvvm_suld_3d_v2i64_clamp
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i64.clamp">;
+def int_nvvm_suld_3d_v4i8_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i8.clamp">;
+def int_nvvm_suld_3d_v4i16_clamp
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i16.clamp">;
+def int_nvvm_suld_3d_v4i32_clamp
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i32.clamp">;
+
+// .trap variants
+def int_nvvm_suld_1d_i8_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i8.trap">;
+def int_nvvm_suld_1d_i16_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i16.trap">;
+def int_nvvm_suld_1d_i32_trap
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i32.trap">;
+def int_nvvm_suld_1d_i64_trap
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i64.trap">;
+def int_nvvm_suld_1d_v2i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i8.trap">;
+def int_nvvm_suld_1d_v2i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i16.trap">;
+def int_nvvm_suld_1d_v2i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i32.trap">;
+def int_nvvm_suld_1d_v2i64_trap
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i64.trap">;
+def int_nvvm_suld_1d_v4i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i8.trap">;
+def int_nvvm_suld_1d_v4i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i16.trap">;
+def int_nvvm_suld_1d_v4i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i32.trap">;
+
+def int_nvvm_suld_1d_array_i8_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i8.trap">;
+def int_nvvm_suld_1d_array_i16_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i16.trap">;
+def int_nvvm_suld_1d_array_i32_trap
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i32.trap">;
+def int_nvvm_suld_1d_array_i64_trap
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i64.trap">;
+def int_nvvm_suld_1d_array_v2i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i8.trap">;
+def int_nvvm_suld_1d_array_v2i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i16.trap">;
+def int_nvvm_suld_1d_array_v2i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i32.trap">;
+def int_nvvm_suld_1d_array_v2i64_trap
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i64.trap">;
+def int_nvvm_suld_1d_array_v4i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i8.trap">;
+def int_nvvm_suld_1d_array_v4i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i16.trap">;
+def int_nvvm_suld_1d_array_v4i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i32.trap">;
+
+def int_nvvm_suld_2d_i8_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i8.trap">;
+def int_nvvm_suld_2d_i16_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i16.trap">;
+def int_nvvm_suld_2d_i32_trap
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i32.trap">;
+def int_nvvm_suld_2d_i64_trap
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i64.trap">;
+def int_nvvm_suld_2d_v2i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i8.trap">;
+def int_nvvm_suld_2d_v2i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i16.trap">;
+def int_nvvm_suld_2d_v2i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i32.trap">;
+def int_nvvm_suld_2d_v2i64_trap
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i64.trap">;
+def int_nvvm_suld_2d_v4i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i8.trap">;
+def int_nvvm_suld_2d_v4i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i16.trap">;
+def int_nvvm_suld_2d_v4i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i32.trap">;
+
+def int_nvvm_suld_2d_array_i8_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i8.trap">;
+def int_nvvm_suld_2d_array_i16_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i16.trap">;
+def int_nvvm_suld_2d_array_i32_trap
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i32.trap">;
+def int_nvvm_suld_2d_array_i64_trap
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i64.trap">;
+def int_nvvm_suld_2d_array_v2i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i8.trap">;
+def int_nvvm_suld_2d_array_v2i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i16.trap">;
+def int_nvvm_suld_2d_array_v2i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i32.trap">;
+def int_nvvm_suld_2d_array_v2i64_trap
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i64.trap">;
+def int_nvvm_suld_2d_array_v4i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i8.trap">;
+def int_nvvm_suld_2d_array_v4i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i16.trap">;
+def int_nvvm_suld_2d_array_v4i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i32.trap">;
+
+def int_nvvm_suld_3d_i8_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i8.trap">;
+def int_nvvm_suld_3d_i16_trap
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i16.trap">;
+def int_nvvm_suld_3d_i32_trap
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i32.trap">;
+def int_nvvm_suld_3d_i64_trap
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i64.trap">;
+def int_nvvm_suld_3d_v2i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i8.trap">;
+def int_nvvm_suld_3d_v2i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i16.trap">;
+def int_nvvm_suld_3d_v2i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i32.trap">;
+def int_nvvm_suld_3d_v2i64_trap
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i64.trap">;
+def int_nvvm_suld_3d_v4i8_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i8.trap">;
+def int_nvvm_suld_3d_v4i16_trap
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i16.trap">;
+def int_nvvm_suld_3d_v4i32_trap
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i32.trap">;
+
+// .zero variants
+def int_nvvm_suld_1d_i8_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i8.zero">;
+def int_nvvm_suld_1d_i16_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i16.zero">;
+def int_nvvm_suld_1d_i32_zero
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i32.zero">;
+def int_nvvm_suld_1d_i64_zero
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.i64.zero">;
+def int_nvvm_suld_1d_v2i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i8.zero">;
+def int_nvvm_suld_1d_v2i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i16.zero">;
+def int_nvvm_suld_1d_v2i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i32.zero">;
+def int_nvvm_suld_1d_v2i64_zero
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v2i64.zero">;
+def int_nvvm_suld_1d_v4i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i8.zero">;
+def int_nvvm_suld_1d_v4i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i16.zero">;
+def int_nvvm_suld_1d_v4i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.v4i32.zero">;
+
+def int_nvvm_suld_1d_array_i8_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i8.zero">;
+def int_nvvm_suld_1d_array_i16_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i16.zero">;
+def int_nvvm_suld_1d_array_i32_zero
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i32.zero">;
+def int_nvvm_suld_1d_array_i64_zero
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.i64.zero">;
+def int_nvvm_suld_1d_array_v2i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i8.zero">;
+def int_nvvm_suld_1d_array_v2i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i16.zero">;
+def int_nvvm_suld_1d_array_v2i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i32.zero">;
+def int_nvvm_suld_1d_array_v2i64_zero
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v2i64.zero">;
+def int_nvvm_suld_1d_array_v4i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i8.zero">;
+def int_nvvm_suld_1d_array_v4i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i16.zero">;
+def int_nvvm_suld_1d_array_v4i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.1d.array.v4i32.zero">;
+
+def int_nvvm_suld_2d_i8_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i8.zero">;
+def int_nvvm_suld_2d_i16_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i16.zero">;
+def int_nvvm_suld_2d_i32_zero
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i32.zero">;
+def int_nvvm_suld_2d_i64_zero
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.i64.zero">;
+def int_nvvm_suld_2d_v2i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i8.zero">;
+def int_nvvm_suld_2d_v2i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i16.zero">;
+def int_nvvm_suld_2d_v2i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i32.zero">;
+def int_nvvm_suld_2d_v2i64_zero
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v2i64.zero">;
+def int_nvvm_suld_2d_v4i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i8.zero">;
+def int_nvvm_suld_2d_v4i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i16.zero">;
+def int_nvvm_suld_2d_v4i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.v4i32.zero">;
+
+def int_nvvm_suld_2d_array_i8_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i8.zero">;
+def int_nvvm_suld_2d_array_i16_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i16.zero">;
+def int_nvvm_suld_2d_array_i32_zero
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i32.zero">;
+def int_nvvm_suld_2d_array_i64_zero
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.i64.zero">;
+def int_nvvm_suld_2d_array_v2i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i8.zero">;
+def int_nvvm_suld_2d_array_v2i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i16.zero">;
+def int_nvvm_suld_2d_array_v2i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i32.zero">;
+def int_nvvm_suld_2d_array_v2i64_zero
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v2i64.zero">;
+def int_nvvm_suld_2d_array_v4i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i8.zero">;
+def int_nvvm_suld_2d_array_v4i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i16.zero">;
+def int_nvvm_suld_2d_array_v4i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.2d.array.v4i32.zero">;
+
+def int_nvvm_suld_3d_i8_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i8.zero">;
+def int_nvvm_suld_3d_i16_zero
+  : Intrinsic<[llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i16.zero">;
+def int_nvvm_suld_3d_i32_zero
+  : Intrinsic<[llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i32.zero">;
+def int_nvvm_suld_3d_i64_zero
+  : Intrinsic<[llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.i64.zero">;
+def int_nvvm_suld_3d_v2i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i8.zero">;
+def int_nvvm_suld_3d_v2i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i16.zero">;
+def int_nvvm_suld_3d_v2i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i32.zero">;
+def int_nvvm_suld_3d_v2i64_zero
+  : Intrinsic<[llvm_i64_ty, llvm_i64_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v2i64.zero">;
+def int_nvvm_suld_3d_v4i8_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i8.zero">;
+def int_nvvm_suld_3d_v4i16_zero
+  : Intrinsic<[llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i16.zero">;
+def int_nvvm_suld_3d_v4i32_zero
+  : Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+              [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.suld.3d.v4i32.zero">;
+
+//===- Texture Query ------------------------------------------------------===//
+
+def int_nvvm_txq_channel_order
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.channel.order">,
+    GCCBuiltin<"__nvvm_txq_channel_order">;
+def int_nvvm_txq_channel_data_type
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.channel.data.type">,
+    GCCBuiltin<"__nvvm_txq_channel_data_type">;
+def int_nvvm_txq_width
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.width">,
+    GCCBuiltin<"__nvvm_txq_width">;
+def int_nvvm_txq_height
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.height">,
+    GCCBuiltin<"__nvvm_txq_height">;
+def int_nvvm_txq_depth
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.depth">,
+    GCCBuiltin<"__nvvm_txq_depth">;
+def int_nvvm_txq_array_size
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.array.size">,
+    GCCBuiltin<"__nvvm_txq_array_size">;
+def int_nvvm_txq_num_samples
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.num.samples">,
+    GCCBuiltin<"__nvvm_txq_num_samples">;
+def int_nvvm_txq_num_mipmap_levels
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.txq.num.mipmap.levels">,
+    GCCBuiltin<"__nvvm_txq_num_mipmap_levels">;
+
+//===- Surface Query ------------------------------------------------------===//
+
+def int_nvvm_suq_channel_order
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.channel.order">,
+    GCCBuiltin<"__nvvm_suq_channel_order">;
+def int_nvvm_suq_channel_data_type
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.channel.data.type">,
+    GCCBuiltin<"__nvvm_suq_channel_data_type">;
+def int_nvvm_suq_width
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.width">,
+    GCCBuiltin<"__nvvm_suq_width">;
+def int_nvvm_suq_height
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.height">,
+    GCCBuiltin<"__nvvm_suq_height">;
+def int_nvvm_suq_depth
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.depth">,
+    GCCBuiltin<"__nvvm_suq_depth">;
+def int_nvvm_suq_array_size
+  : Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.suq.array.size">,
+    GCCBuiltin<"__nvvm_suq_array_size">;
+
+
+//===- Handle Query -------------------------------------------------------===//
+
+def int_nvvm_istypep_sampler
+  : Intrinsic<[llvm_i1_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.istypep.sampler">,
+    GCCBuiltin<"__nvvm_istypep_sampler">;
+def int_nvvm_istypep_surface
+  : Intrinsic<[llvm_i1_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.istypep.surface">,
+    GCCBuiltin<"__nvvm_istypep_surface">;
+def int_nvvm_istypep_texture
+  : Intrinsic<[llvm_i1_ty], [llvm_i64_ty], [IntrNoMem],
+              "llvm.nvvm.istypep.texture">,
+    GCCBuiltin<"__nvvm_istypep_texture">;
+
+
+
+//===- Surface Stores -----------------------------------------------------===//
+
+// Unformatted
+// .clamp variant
+def int_nvvm_sust_b_1d_i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i8_clamp">;
+def int_nvvm_sust_b_1d_i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i16_clamp">;
+def int_nvvm_sust_b_1d_i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i32_clamp">;
+def int_nvvm_sust_b_1d_i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i64_clamp">;
+def int_nvvm_sust_b_1d_v2i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i8_clamp">;
+def int_nvvm_sust_b_1d_v2i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i16_clamp">;
+def int_nvvm_sust_b_1d_v2i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i32_clamp">;
+def int_nvvm_sust_b_1d_v2i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i64_clamp">;
+def int_nvvm_sust_b_1d_v4i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i8_clamp">;
+def int_nvvm_sust_b_1d_v4i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i16_clamp">;
+def int_nvvm_sust_b_1d_v4i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i32_clamp">;
+
+
+def int_nvvm_sust_b_1d_array_i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i8_clamp">;
+def int_nvvm_sust_b_1d_array_i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i16_clamp">;
+def int_nvvm_sust_b_1d_array_i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i32_clamp">;
+def int_nvvm_sust_b_1d_array_i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i64_clamp">;
+def int_nvvm_sust_b_1d_array_v2i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i8_clamp">;
+def int_nvvm_sust_b_1d_array_v2i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i16_clamp">;
+def int_nvvm_sust_b_1d_array_v2i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i32_clamp">;
+def int_nvvm_sust_b_1d_array_v2i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i64_clamp">;
+def int_nvvm_sust_b_1d_array_v4i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i8_clamp">;
+def int_nvvm_sust_b_1d_array_v4i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i16_clamp">;
+def int_nvvm_sust_b_1d_array_v4i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i32_clamp">;
+
+
+def int_nvvm_sust_b_2d_i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i8_clamp">;
+def int_nvvm_sust_b_2d_i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i16_clamp">;
+def int_nvvm_sust_b_2d_i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i32_clamp">;
+def int_nvvm_sust_b_2d_i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i64_clamp">;
+def int_nvvm_sust_b_2d_v2i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i8_clamp">;
+def int_nvvm_sust_b_2d_v2i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i16_clamp">;
+def int_nvvm_sust_b_2d_v2i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i32_clamp">;
+def int_nvvm_sust_b_2d_v2i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i64_clamp">;
+def int_nvvm_sust_b_2d_v4i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i8_clamp">;
+def int_nvvm_sust_b_2d_v4i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i16_clamp">;
+def int_nvvm_sust_b_2d_v4i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i32_clamp">;
+
+
+def int_nvvm_sust_b_2d_array_i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i8_clamp">;
+def int_nvvm_sust_b_2d_array_i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i16_clamp">;
+def int_nvvm_sust_b_2d_array_i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i32_clamp">;
+def int_nvvm_sust_b_2d_array_i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i64_clamp">;
+def int_nvvm_sust_b_2d_array_v2i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i8_clamp">;
+def int_nvvm_sust_b_2d_array_v2i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i16_clamp">;
+def int_nvvm_sust_b_2d_array_v2i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i32_clamp">;
+def int_nvvm_sust_b_2d_array_v2i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i64_clamp">;
+def int_nvvm_sust_b_2d_array_v4i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i8_clamp">;
+def int_nvvm_sust_b_2d_array_v4i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i16_clamp">;
+def int_nvvm_sust_b_2d_array_v4i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i32_clamp">;
+
+
+def int_nvvm_sust_b_3d_i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i8_clamp">;
+def int_nvvm_sust_b_3d_i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i16_clamp">;
+def int_nvvm_sust_b_3d_i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i32_clamp">;
+def int_nvvm_sust_b_3d_i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i64_clamp">;
+def int_nvvm_sust_b_3d_v2i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i8_clamp">;
+def int_nvvm_sust_b_3d_v2i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i16_clamp">;
+def int_nvvm_sust_b_3d_v2i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i32_clamp">;
+def int_nvvm_sust_b_3d_v2i64_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i64.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i64_clamp">;
+def int_nvvm_sust_b_3d_v4i8_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i8.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i8_clamp">;
+def int_nvvm_sust_b_3d_v4i16_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i16.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i16_clamp">;
+def int_nvvm_sust_b_3d_v4i32_clamp
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i32.clamp">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i32_clamp">;
+
+
+// .trap variant
+def int_nvvm_sust_b_1d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i8_trap">;
+def int_nvvm_sust_b_1d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i16_trap">;
+def int_nvvm_sust_b_1d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i32_trap">;
+def int_nvvm_sust_b_1d_i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i64_trap">;
+def int_nvvm_sust_b_1d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i8_trap">;
+def int_nvvm_sust_b_1d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i16_trap">;
+def int_nvvm_sust_b_1d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i32_trap">;
+def int_nvvm_sust_b_1d_v2i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i64_trap">;
+def int_nvvm_sust_b_1d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i8_trap">;
+def int_nvvm_sust_b_1d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i16_trap">;
+def int_nvvm_sust_b_1d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i32_trap">;
+
+
+def int_nvvm_sust_b_1d_array_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i8_trap">;
+def int_nvvm_sust_b_1d_array_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i16_trap">;
+def int_nvvm_sust_b_1d_array_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i32_trap">;
+def int_nvvm_sust_b_1d_array_i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i64_trap">;
+def int_nvvm_sust_b_1d_array_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i8_trap">;
+def int_nvvm_sust_b_1d_array_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i16_trap">;
+def int_nvvm_sust_b_1d_array_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i32_trap">;
+def int_nvvm_sust_b_1d_array_v2i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i64_trap">;
+def int_nvvm_sust_b_1d_array_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i8_trap">;
+def int_nvvm_sust_b_1d_array_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i16_trap">;
+def int_nvvm_sust_b_1d_array_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i32_trap">;
+
+
+def int_nvvm_sust_b_2d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i8_trap">;
+def int_nvvm_sust_b_2d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i16_trap">;
+def int_nvvm_sust_b_2d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i32_trap">;
+def int_nvvm_sust_b_2d_i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i64_trap">;
+def int_nvvm_sust_b_2d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i8_trap">;
+def int_nvvm_sust_b_2d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i16_trap">;
+def int_nvvm_sust_b_2d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i32_trap">;
+def int_nvvm_sust_b_2d_v2i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i64_trap">;
+def int_nvvm_sust_b_2d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i8_trap">;
+def int_nvvm_sust_b_2d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i16_trap">;
+def int_nvvm_sust_b_2d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i32_trap">;
+
+
+def int_nvvm_sust_b_2d_array_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i8_trap">;
+def int_nvvm_sust_b_2d_array_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i16_trap">;
+def int_nvvm_sust_b_2d_array_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i32_trap">;
+def int_nvvm_sust_b_2d_array_i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i64_trap">;
+def int_nvvm_sust_b_2d_array_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i8_trap">;
+def int_nvvm_sust_b_2d_array_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i16_trap">;
+def int_nvvm_sust_b_2d_array_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i32_trap">;
+def int_nvvm_sust_b_2d_array_v2i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i64_trap">;
+def int_nvvm_sust_b_2d_array_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i8_trap">;
+def int_nvvm_sust_b_2d_array_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i16_trap">;
+def int_nvvm_sust_b_2d_array_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i32_trap">;
+
+
+def int_nvvm_sust_b_3d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i8_trap">;
+def int_nvvm_sust_b_3d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i16_trap">;
+def int_nvvm_sust_b_3d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i32_trap">;
+def int_nvvm_sust_b_3d_i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i64_trap">;
+def int_nvvm_sust_b_3d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i8_trap">;
+def int_nvvm_sust_b_3d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i16_trap">;
+def int_nvvm_sust_b_3d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i32_trap">;
+def int_nvvm_sust_b_3d_v2i64_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i64.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i64_trap">;
+def int_nvvm_sust_b_3d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i8_trap">;
+def int_nvvm_sust_b_3d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i16_trap">;
+def int_nvvm_sust_b_3d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i32_trap">;
+
+
+// .zero variant
+def int_nvvm_sust_b_1d_i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i8_zero">;
+def int_nvvm_sust_b_1d_i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i16_zero">;
+def int_nvvm_sust_b_1d_i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i32_zero">;
+def int_nvvm_sust_b_1d_i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_i64_zero">;
+def int_nvvm_sust_b_1d_v2i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i8_zero">;
+def int_nvvm_sust_b_1d_v2i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i16_zero">;
+def int_nvvm_sust_b_1d_v2i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i32_zero">;
+def int_nvvm_sust_b_1d_v2i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.v2i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v2i64_zero">;
+def int_nvvm_sust_b_1d_v4i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i8_zero">;
+def int_nvvm_sust_b_1d_v4i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i16_zero">;
+def int_nvvm_sust_b_1d_v4i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.v4i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_v4i32_zero">;
+
+
+def int_nvvm_sust_b_1d_array_i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i8_zero">;
+def int_nvvm_sust_b_1d_array_i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i16_zero">;
+def int_nvvm_sust_b_1d_array_i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i32_zero">;
+def int_nvvm_sust_b_1d_array_i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_i64_zero">;
+def int_nvvm_sust_b_1d_array_v2i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i8_zero">;
+def int_nvvm_sust_b_1d_array_v2i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i16_zero">;
+def int_nvvm_sust_b_1d_array_v2i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i32_zero">;
+def int_nvvm_sust_b_1d_array_v2i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v2i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v2i64_zero">;
+def int_nvvm_sust_b_1d_array_v4i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i8_zero">;
+def int_nvvm_sust_b_1d_array_v4i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i16_zero">;
+def int_nvvm_sust_b_1d_array_v4i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.1d.array.v4i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_1d_array_v4i32_zero">;
+
+
+def int_nvvm_sust_b_2d_i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i8_zero">;
+def int_nvvm_sust_b_2d_i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i16_zero">;
+def int_nvvm_sust_b_2d_i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i32_zero">;
+def int_nvvm_sust_b_2d_i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_i64_zero">;
+def int_nvvm_sust_b_2d_v2i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i8_zero">;
+def int_nvvm_sust_b_2d_v2i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i16_zero">;
+def int_nvvm_sust_b_2d_v2i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i32_zero">;
+def int_nvvm_sust_b_2d_v2i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.v2i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v2i64_zero">;
+def int_nvvm_sust_b_2d_v4i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i8_zero">;
+def int_nvvm_sust_b_2d_v4i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i16_zero">;
+def int_nvvm_sust_b_2d_v4i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.v4i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_v4i32_zero">;
+
+
+def int_nvvm_sust_b_2d_array_i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i8_zero">;
+def int_nvvm_sust_b_2d_array_i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i16_zero">;
+def int_nvvm_sust_b_2d_array_i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i32_zero">;
+def int_nvvm_sust_b_2d_array_i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_i64_zero">;
+def int_nvvm_sust_b_2d_array_v2i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i8_zero">;
+def int_nvvm_sust_b_2d_array_v2i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i16_zero">;
+def int_nvvm_sust_b_2d_array_v2i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i32_zero">;
+def int_nvvm_sust_b_2d_array_v2i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v2i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v2i64_zero">;
+def int_nvvm_sust_b_2d_array_v4i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i8_zero">;
+def int_nvvm_sust_b_2d_array_v4i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i16_zero">;
+def int_nvvm_sust_b_2d_array_v4i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.2d.array.v4i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_2d_array_v4i32_zero">;
+
+
+def int_nvvm_sust_b_3d_i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i8_zero">;
+def int_nvvm_sust_b_3d_i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i16_zero">;
+def int_nvvm_sust_b_3d_i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i32_zero">;
+def int_nvvm_sust_b_3d_i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_i64_zero">;
+def int_nvvm_sust_b_3d_v2i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i8_zero">;
+def int_nvvm_sust_b_3d_v2i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i16_zero">;
+def int_nvvm_sust_b_3d_v2i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i32_zero">;
+def int_nvvm_sust_b_3d_v2i64_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i64_ty, llvm_i64_ty], [],
+              "llvm.nvvm.sust.b.3d.v2i64.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v2i64_zero">;
+def int_nvvm_sust_b_3d_v4i8_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i8.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i8_zero">;
+def int_nvvm_sust_b_3d_v4i16_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i16.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i16_zero">;
+def int_nvvm_sust_b_3d_v4i32_zero
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.b.3d.v4i32.zero">,
+    GCCBuiltin<"__nvvm_sust_b_3d_v4i32_zero">;
+
+
+
+// Formatted
+
+def int_nvvm_sust_p_1d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_i8_trap">;
+def int_nvvm_sust_p_1d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_i16_trap">;
+def int_nvvm_sust_p_1d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_i32_trap">;
+def int_nvvm_sust_p_1d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v2i8_trap">;
+def int_nvvm_sust_p_1d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v2i16_trap">;
+def int_nvvm_sust_p_1d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v2i32_trap">;
+def int_nvvm_sust_p_1d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v4i8_trap">;
+def int_nvvm_sust_p_1d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v4i16_trap">;
+def int_nvvm_sust_p_1d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_v4i32_trap">;
+
+
+def int_nvvm_sust_p_1d_array_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_i8_trap">;
+def int_nvvm_sust_p_1d_array_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_i16_trap">;
+def int_nvvm_sust_p_1d_array_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.array.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_i32_trap">;
+def int_nvvm_sust_p_1d_array_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v2i8_trap">;
+def int_nvvm_sust_p_1d_array_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v2i16_trap">;
+def int_nvvm_sust_p_1d_array_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v2i32_trap">;
+def int_nvvm_sust_p_1d_array_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v4i8_trap">;
+def int_nvvm_sust_p_1d_array_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v4i16_trap">;
+def int_nvvm_sust_p_1d_array_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.1d.array.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_1d_array_v4i32_trap">;
+
+
+def int_nvvm_sust_p_2d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_i8_trap">;
+def int_nvvm_sust_p_2d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_i16_trap">;
+def int_nvvm_sust_p_2d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_i32_trap">;
+def int_nvvm_sust_p_2d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v2i8_trap">;
+def int_nvvm_sust_p_2d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v2i16_trap">;
+def int_nvvm_sust_p_2d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v2i32_trap">;
+def int_nvvm_sust_p_2d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v4i8_trap">;
+def int_nvvm_sust_p_2d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i16_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v4i16_trap">;
+def int_nvvm_sust_p_2d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_v4i32_trap">;
+
+
+def int_nvvm_sust_p_2d_array_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_i8_trap">;
+def int_nvvm_sust_p_2d_array_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_i16_trap">;
+def int_nvvm_sust_p_2d_array_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.array.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_i32_trap">;
+def int_nvvm_sust_p_2d_array_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v2i8_trap">;
+def int_nvvm_sust_p_2d_array_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v2i16_trap">;
+def int_nvvm_sust_p_2d_array_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v2i32_trap">;
+def int_nvvm_sust_p_2d_array_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v4i8_trap">;
+def int_nvvm_sust_p_2d_array_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v4i16_trap">;
+def int_nvvm_sust_p_2d_array_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.2d.array.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_2d_array_v4i32_trap">;
+
+
+def int_nvvm_sust_p_3d_i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_i8_trap">;
+def int_nvvm_sust_p_3d_i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_i16_trap">;
+def int_nvvm_sust_p_3d_i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.3d.i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_i32_trap">;
+def int_nvvm_sust_p_3d_v2i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.v2i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v2i8_trap">;
+def int_nvvm_sust_p_3d_v2i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.v2i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v2i16_trap">;
+def int_nvvm_sust_p_3d_v2i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.3d.v2i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v2i32_trap">;
+def int_nvvm_sust_p_3d_v4i8_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.v4i8.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v4i8_trap">;
+def int_nvvm_sust_p_3d_v4i16_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i16_ty, llvm_i16_ty, llvm_i16_ty, llvm_i16_ty], [],
+              "llvm.nvvm.sust.p.3d.v4i16.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v4i16_trap">;
+def int_nvvm_sust_p_3d_v4i32_trap
+  : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+                   llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [],
+              "llvm.nvvm.sust.p.3d.v4i32.trap">,
+    GCCBuiltin<"__nvvm_sust_p_3d_v4i32_trap">;
+
+
+def int_nvvm_rotate_b32
+  : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+              [IntrNoMem], "llvm.nvvm.rotate.b32">,
+              GCCBuiltin<"__nvvm_rotate_b32">;
+
+def int_nvvm_rotate_b64
+  :Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+             [IntrNoMem], "llvm.nvvm.rotate.b64">,
+             GCCBuiltin<"__nvvm_rotate_b64">;
+
+def int_nvvm_rotate_right_b64
+  : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+              [IntrNoMem], "llvm.nvvm.rotate.right.b64">,
+              GCCBuiltin<"__nvvm_rotate_right_b64">;
+
+def int_nvvm_swap_lo_hi_b64
+  : Intrinsic<[llvm_i64_ty], [llvm_i64_ty],
+              [IntrNoMem], "llvm.nvvm.swap.lo.hi.b64">,
+              GCCBuiltin<"__nvvm_swap_lo_hi_b64">;
+
+
+// Old PTX back-end intrinsics retained here for backwards-compatibility
+
+multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> {
+// FIXME: Do we need the 128-bit integer type version?
+//    def _r64   : Intrinsic<[llvm_i128_ty],   [], [IntrNoMem]>;
+
+// FIXME: Enable this once v4i32 support is enabled in back-end.
+//    def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>;
+
+  def _x     : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+               GCCBuiltin<!strconcat(prefix, "_x")>;
+  def _y     : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+               GCCBuiltin<!strconcat(prefix, "_y")>;
+  def _z     : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+               GCCBuiltin<!strconcat(prefix, "_z")>;
+  def _w     : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+               GCCBuiltin<!strconcat(prefix, "_w")>;
+}
+
+class PTXReadSpecialRegisterIntrinsic_r32<string name>
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+    GCCBuiltin<name>;
+
+class PTXReadSpecialRegisterIntrinsic_r64<string name>
+  : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>,
+    GCCBuiltin<name>;
+
+defm int_ptx_read_tid        : PTXReadSpecialRegisterIntrinsic_v4i32
+                               <"__builtin_ptx_read_tid">;
+defm int_ptx_read_ntid       : PTXReadSpecialRegisterIntrinsic_v4i32
+                               <"__builtin_ptx_read_ntid">;
+
+def int_ptx_read_laneid      : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_laneid">;
+def int_ptx_read_warpid      : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_warpid">;
+def int_ptx_read_nwarpid     : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_nwarpid">;
+
+defm int_ptx_read_ctaid      : PTXReadSpecialRegisterIntrinsic_v4i32
+                               <"__builtin_ptx_read_ctaid">;
+defm int_ptx_read_nctaid     : PTXReadSpecialRegisterIntrinsic_v4i32
+                               <"__builtin_ptx_read_nctaid">;
+
+def int_ptx_read_smid        : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_smid">;
+def int_ptx_read_nsmid       : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_nsmid">;
+def int_ptx_read_gridid      : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_gridid">;
+
+def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_lanemask_eq">;
+def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_lanemask_le">;
+def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_lanemask_lt">;
+def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_lanemask_ge">;
+def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_lanemask_gt">;
+
+def int_ptx_read_clock       : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_clock">;
+def int_ptx_read_clock64     : PTXReadSpecialRegisterIntrinsic_r64
+                               <"__builtin_ptx_read_clock64">;
+
+def int_ptx_read_pm0         : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_pm0">;
+def int_ptx_read_pm1         : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_pm1">;
+def int_ptx_read_pm2         : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_pm2">;
+def int_ptx_read_pm3         : PTXReadSpecialRegisterIntrinsic_r32
+                               <"__builtin_ptx_read_pm3">;
+
+def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>,
+                       GCCBuiltin<"__builtin_ptx_bar_sync">;
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
new file mode 100644
index 0000000..49ddfb8
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -0,0 +1,476 @@
+//===- IntrinsicsPowerPC.td - Defines PowerPC intrinsics ---*- tablegen -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the PowerPC-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all PowerPC intrinsics.
+//
+
+// Non-altivec intrinsics.
+let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
+  // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions.
+  def int_ppc_dcba  : Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbf  : Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbi  : Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbt  : Intrinsic<[], [llvm_ptr_ty],
+    [IntrReadWriteArgMem, NoCapture<0>]>;
+  def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbz  : Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
+
+  // sync instruction
+  def int_ppc_sync : Intrinsic<[], [], []>;
+
+  // Intrinsics used to generate ctr-based loops. These should only be
+  // generated by the PowerPC backend!
+  def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
+  def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>;
+}
+
+
+let TargetPrefix = "ppc" in {  // All PPC intrinsics start with "llvm.ppc.".
+  /// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics.
+  class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
+                              list<LLVMType> param_types,
+                              list<IntrinsicProperty> properties>
+    : GCCBuiltin<!strconcat("__builtin_altivec_", GCCIntSuffix)>,
+      Intrinsic<ret_types, param_types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Class Definitions.
+//
+
+/// PowerPC_Vec_FF_Intrinsic - A PowerPC intrinsic that takes one v4f32
+/// vector and returns one.  These intrinsics have no side effects.
+class PowerPC_Vec_FF_Intrinsic<string GCCIntSuffix>
+  : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+                          [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+/// PowerPC_Vec_FFF_Intrinsic - A PowerPC intrinsic that takes two v4f32
+/// vectors and returns one.  These intrinsics have no side effects.
+class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
+  : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+                          [llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                          [IntrNoMem]>;
+
+/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
+/// vectors and returns one.  These intrinsics have no side effects.
+class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix> 
+  : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+                          [llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                          [IntrNoMem]>;
+
+/// PowerPC_Vec_HHH_Intrinsic - A PowerPC intrinsic that takes two v8i16
+/// vectors and returns one.  These intrinsics have no side effects.
+class PowerPC_Vec_HHH_Intrinsic<string GCCIntSuffix> 
+  : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+                          [llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                          [IntrNoMem]>;
+
+/// PowerPC_Vec_WWW_Intrinsic - A PowerPC intrinsic that takes two v4i32
+/// vectors and returns one.  These intrinsics have no side effects.
+class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix> 
+  : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+                          [llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                          [IntrNoMem]>;
+
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".
+  // Data Stream Control.
+  def int_ppc_altivec_dss : GCCBuiltin<"__builtin_altivec_dss">,
+              Intrinsic<[], [llvm_i32_ty], []>;
+  def int_ppc_altivec_dssall : GCCBuiltin<"__builtin_altivec_dssall">,
+              Intrinsic<[], [], []>;
+  def int_ppc_altivec_dst : GCCBuiltin<"__builtin_altivec_dst">,
+              Intrinsic<[],
+                        [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+                        []>;
+  def int_ppc_altivec_dstt : GCCBuiltin<"__builtin_altivec_dstt">,
+              Intrinsic<[],
+                        [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+                        []>;
+  def int_ppc_altivec_dstst : GCCBuiltin<"__builtin_altivec_dstst">,
+              Intrinsic<[],
+                        [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+                        []>;
+  def int_ppc_altivec_dststt : GCCBuiltin<"__builtin_altivec_dststt">,
+              Intrinsic<[],
+                        [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+                        []>;
+
+  // VSCR access.
+  def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">,
+              Intrinsic<[llvm_v8i16_ty], [], [IntrReadMem]>;
+  def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">,
+              Intrinsic<[], [llvm_v4i32_ty], []>;
+
+
+  // Loads.  These don't map directly to GCC builtins because they represent the
+  // source address with a single pointer.
+  def int_ppc_altivec_lvx :
+              Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_ppc_altivec_lvxl :
+              Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_ppc_altivec_lvebx :
+              Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_ppc_altivec_lvehx :
+              Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_ppc_altivec_lvewx :
+              Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+
+  // Stores.  These don't map directly to GCC builtins because they represent the
+  // source address with a single pointer.
+  def int_ppc_altivec_stvx :
+              Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
+                        [IntrReadWriteArgMem]>;
+  def int_ppc_altivec_stvxl :
+              Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
+                        [IntrReadWriteArgMem]>;
+  def int_ppc_altivec_stvebx :
+              Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty],
+                        [IntrReadWriteArgMem]>;
+  def int_ppc_altivec_stvehx :
+              Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty],
+                        [IntrReadWriteArgMem]>;
+  def int_ppc_altivec_stvewx :
+              Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty],
+                        [IntrReadWriteArgMem]>;
+
+  // Comparisons setting a vector.
+  def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+                        
+  def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsw : GCCBuiltin<"__builtin_altivec_vcmpgtsw">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtuw : GCCBuiltin<"__builtin_altivec_vcmpgtuw">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+                        
+  def int_ppc_altivec_vcmpequh : GCCBuiltin<"__builtin_altivec_vcmpequh">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsh : GCCBuiltin<"__builtin_altivec_vcmpgtsh">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtuh : GCCBuiltin<"__builtin_altivec_vcmpgtuh">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+
+  def int_ppc_altivec_vcmpequb : GCCBuiltin<"__builtin_altivec_vcmpequb">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsb : GCCBuiltin<"__builtin_altivec_vcmpgtsb">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtub : GCCBuiltin<"__builtin_altivec_vcmpgtub">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+
+  // Predicate Comparisons.  The first operand specifies interpretation of CR6.
+  def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpeqfp_p : GCCBuiltin<"__builtin_altivec_vcmpeqfp_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgefp_p : GCCBuiltin<"__builtin_altivec_vcmpgefp_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+                        [IntrNoMem]>;
+                        
+  def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsw_p : GCCBuiltin<"__builtin_altivec_vcmpgtsw_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtuw_p : GCCBuiltin<"__builtin_altivec_vcmpgtuw_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+                        [IntrNoMem]>;
+                        
+  def int_ppc_altivec_vcmpequh_p : GCCBuiltin<"__builtin_altivec_vcmpequh_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsh_p : GCCBuiltin<"__builtin_altivec_vcmpgtsh_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtuh_p : GCCBuiltin<"__builtin_altivec_vcmpgtuh_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+                        [IntrNoMem]>;
+
+  def int_ppc_altivec_vcmpequb_p : GCCBuiltin<"__builtin_altivec_vcmpequb_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtsb_p : GCCBuiltin<"__builtin_altivec_vcmpgtsb_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcmpgtub_p : GCCBuiltin<"__builtin_altivec_vcmpgtub_p">,
+              Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector average.
+def int_ppc_altivec_vavgsb : PowerPC_Vec_BBB_Intrinsic<"vavgsb">;
+def int_ppc_altivec_vavgsh : PowerPC_Vec_HHH_Intrinsic<"vavgsh">;
+def int_ppc_altivec_vavgsw : PowerPC_Vec_WWW_Intrinsic<"vavgsw">;
+def int_ppc_altivec_vavgub : PowerPC_Vec_BBB_Intrinsic<"vavgub">;
+def int_ppc_altivec_vavguh : PowerPC_Vec_HHH_Intrinsic<"vavguh">;
+def int_ppc_altivec_vavguw : PowerPC_Vec_WWW_Intrinsic<"vavguw">;
+
+// Vector maximum.
+def int_ppc_altivec_vmaxfp : PowerPC_Vec_FFF_Intrinsic<"vmaxfp">;
+def int_ppc_altivec_vmaxsb : PowerPC_Vec_BBB_Intrinsic<"vmaxsb">;
+def int_ppc_altivec_vmaxsh : PowerPC_Vec_HHH_Intrinsic<"vmaxsh">;
+def int_ppc_altivec_vmaxsw : PowerPC_Vec_WWW_Intrinsic<"vmaxsw">;
+def int_ppc_altivec_vmaxub : PowerPC_Vec_BBB_Intrinsic<"vmaxub">;
+def int_ppc_altivec_vmaxuh : PowerPC_Vec_HHH_Intrinsic<"vmaxuh">;
+def int_ppc_altivec_vmaxuw : PowerPC_Vec_WWW_Intrinsic<"vmaxuw">;
+
+// Vector minimum.
+def int_ppc_altivec_vminfp : PowerPC_Vec_FFF_Intrinsic<"vminfp">;
+def int_ppc_altivec_vminsb : PowerPC_Vec_BBB_Intrinsic<"vminsb">;
+def int_ppc_altivec_vminsh : PowerPC_Vec_HHH_Intrinsic<"vminsh">;
+def int_ppc_altivec_vminsw : PowerPC_Vec_WWW_Intrinsic<"vminsw">;
+def int_ppc_altivec_vminub : PowerPC_Vec_BBB_Intrinsic<"vminub">;
+def int_ppc_altivec_vminuh : PowerPC_Vec_HHH_Intrinsic<"vminuh">;
+def int_ppc_altivec_vminuw : PowerPC_Vec_WWW_Intrinsic<"vminuw">;
+
+// Saturating adds.
+def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">;
+def int_ppc_altivec_vaddsbs : PowerPC_Vec_BBB_Intrinsic<"vaddsbs">;
+def int_ppc_altivec_vadduhs : PowerPC_Vec_HHH_Intrinsic<"vadduhs">;
+def int_ppc_altivec_vaddshs : PowerPC_Vec_HHH_Intrinsic<"vaddshs">;
+def int_ppc_altivec_vadduws : PowerPC_Vec_WWW_Intrinsic<"vadduws">;
+def int_ppc_altivec_vaddsws : PowerPC_Vec_WWW_Intrinsic<"vaddsws">;
+def int_ppc_altivec_vaddcuw : PowerPC_Vec_WWW_Intrinsic<"vaddcuw">;
+
+// Saturating subs.
+def int_ppc_altivec_vsububs : PowerPC_Vec_BBB_Intrinsic<"vsububs">;
+def int_ppc_altivec_vsubsbs : PowerPC_Vec_BBB_Intrinsic<"vsubsbs">;
+def int_ppc_altivec_vsubuhs : PowerPC_Vec_HHH_Intrinsic<"vsubuhs">;
+def int_ppc_altivec_vsubshs : PowerPC_Vec_HHH_Intrinsic<"vsubshs">;
+def int_ppc_altivec_vsubuws : PowerPC_Vec_WWW_Intrinsic<"vsubuws">;
+def int_ppc_altivec_vsubsws : PowerPC_Vec_WWW_Intrinsic<"vsubsws">;
+def int_ppc_altivec_vsubcuw : PowerPC_Vec_WWW_Intrinsic<"vsubcuw">;
+
+let TargetPrefix = "ppc" in {  // All PPC intrinsics start with "llvm.ppc.".
+  // Saturating multiply-adds.
+  def int_ppc_altivec_vmhaddshs : GCCBuiltin<"__builtin_altivec_vmhaddshs">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmhraddshs : GCCBuiltin<"__builtin_altivec_vmhraddshs">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_ppc_altivec_vmaddfp : GCCBuiltin<"__builtin_altivec_vmaddfp">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vnmsubfp : GCCBuiltin<"__builtin_altivec_vnmsubfp">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+
+  // Vector Multiply Sum Intructions.
+  def int_ppc_altivec_vmsummbm : GCCBuiltin<"__builtin_altivec_vmsummbm">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+                       llvm_v4i32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmsumshm : GCCBuiltin<"__builtin_altivec_vmsumshm">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+                       llvm_v4i32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmsumshs : GCCBuiltin<"__builtin_altivec_vmsumshs">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty, 
+                       llvm_v4i32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmsumubm : GCCBuiltin<"__builtin_altivec_vmsumubm">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty, 
+                       llvm_v4i32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmsumuhm : GCCBuiltin<"__builtin_altivec_vmsumuhm">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+                       llvm_v4i32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vmsumuhs : GCCBuiltin<"__builtin_altivec_vmsumuhs">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+                       llvm_v4i32_ty], [IntrNoMem]>;
+
+  // Vector Multiply Intructions.
+  def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
+          Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
+          Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
+          Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">,
+          Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                    [IntrNoMem]>;
+
+  def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
+          Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
+          Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
+          Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                    [IntrNoMem]>;
+  def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">,
+          Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                    [IntrNoMem]>;
+
+  // Vector Sum Intructions.
+  def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vsum2sws : GCCBuiltin<"__builtin_altivec_vsum2sws">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vsum4sbs : GCCBuiltin<"__builtin_altivec_vsum4sbs">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vsum4shs : GCCBuiltin<"__builtin_altivec_vsum4shs">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vsum4ubs : GCCBuiltin<"__builtin_altivec_vsum4ubs">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+
+  // Other multiplies.
+  def int_ppc_altivec_vmladduhm : GCCBuiltin<"__builtin_altivec_vmladduhm">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, 
+                       llvm_v8i16_ty], [IntrNoMem]>;
+
+  // Packs.
+  def int_ppc_altivec_vpkpx : GCCBuiltin<"__builtin_altivec_vpkpx">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vpkshss : GCCBuiltin<"__builtin_altivec_vpkshss">,
+            Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vpkshus : GCCBuiltin<"__builtin_altivec_vpkshus">,
+            Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
+            Intrinsic<[llvm_v16i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+  // vpkuhum is lowered to a shuffle.
+  def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
+            Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                      [IntrNoMem]>;
+  // vpkuwum is lowered to a shuffle.
+  def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                      [IntrNoMem]>;
+
+  // Unpacks.
+  def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vupkhsb : GCCBuiltin<"__builtin_altivec_vupkhsb">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vupkhsh : GCCBuiltin<"__builtin_altivec_vupkhsh">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vupklpx : GCCBuiltin<"__builtin_altivec_vupklpx">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vupklsb : GCCBuiltin<"__builtin_altivec_vupklsb">,
+            Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vupklsh : GCCBuiltin<"__builtin_altivec_vupklsh">,
+            Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+
+
+  // FP <-> integer conversion.
+  def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+
+  def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vrfin : GCCBuiltin<"__builtin_altivec_vrfin">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vrfip : GCCBuiltin<"__builtin_altivec_vrfip">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vrfiz : GCCBuiltin<"__builtin_altivec_vrfiz">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vsl   : PowerPC_Vec_WWW_Intrinsic<"vsl">;
+def int_ppc_altivec_vslo  : PowerPC_Vec_WWW_Intrinsic<"vslo">;
+
+def int_ppc_altivec_vslb  : PowerPC_Vec_BBB_Intrinsic<"vslb">;
+def int_ppc_altivec_vslh  : PowerPC_Vec_HHH_Intrinsic<"vslh">;
+def int_ppc_altivec_vslw  : PowerPC_Vec_WWW_Intrinsic<"vslw">;
+
+// Right Shifts.
+def int_ppc_altivec_vsr   : PowerPC_Vec_WWW_Intrinsic<"vsr">;
+def int_ppc_altivec_vsro  : PowerPC_Vec_WWW_Intrinsic<"vsro">;
+  
+def int_ppc_altivec_vsrb  : PowerPC_Vec_BBB_Intrinsic<"vsrb">;
+def int_ppc_altivec_vsrh  : PowerPC_Vec_HHH_Intrinsic<"vsrh">;
+def int_ppc_altivec_vsrw  : PowerPC_Vec_WWW_Intrinsic<"vsrw">;
+def int_ppc_altivec_vsrab : PowerPC_Vec_BBB_Intrinsic<"vsrab">;
+def int_ppc_altivec_vsrah : PowerPC_Vec_HHH_Intrinsic<"vsrah">;
+def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">;
+
+// Rotates.
+def int_ppc_altivec_vrlb  : PowerPC_Vec_BBB_Intrinsic<"vrlb">;
+def int_ppc_altivec_vrlh  : PowerPC_Vec_HHH_Intrinsic<"vrlh">;
+def int_ppc_altivec_vrlw  : PowerPC_Vec_WWW_Intrinsic<"vrlw">;
+
+let TargetPrefix = "ppc" in {  // All PPC intrinsics start with "llvm.ppc.".
+  // Miscellaneous.
+  def int_ppc_altivec_lvsl :
+              Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
+  def int_ppc_altivec_lvsr :
+              Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
+
+  def int_ppc_altivec_vperm : GCCBuiltin<"__builtin_altivec_vperm_4si">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, 
+                         llvm_v4i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+  def int_ppc_altivec_vsel : GCCBuiltin<"__builtin_altivec_vsel_4si">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, 
+                         llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vexptefp  : PowerPC_Vec_FF_Intrinsic<"vexptefp">;
+def int_ppc_altivec_vlogefp   : PowerPC_Vec_FF_Intrinsic<"vlogefp">;
+def int_ppc_altivec_vrefp     : PowerPC_Vec_FF_Intrinsic<"vrefp">;
+def int_ppc_altivec_vrsqrtefp : PowerPC_Vec_FF_Intrinsic<"vrsqrtefp">;
diff --git a/include/llvm/IR/IntrinsicsR600.td b/include/llvm/IR/IntrinsicsR600.td
new file mode 100644
index 0000000..ba69eaa
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsR600.td
@@ -0,0 +1,72 @@
+//===- IntrinsicsR600.td - Defines R600 intrinsics ---------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the R600-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "r600" in {
+
+class R600ReadPreloadRegisterIntrinsic<string name>
+  : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+    GCCBuiltin<name>;
+
+multiclass R600ReadPreloadRegisterIntrinsic_xyz<string prefix> {
+  def _x : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_x")>;
+  def _y : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_y")>;
+  def _z : R600ReadPreloadRegisterIntrinsic<!strconcat(prefix, "_z")>;
+}
+
+defm int_r600_read_global_size : R600ReadPreloadRegisterIntrinsic_xyz <
+                                       "__builtin_r600_read_global_size">;
+defm int_r600_read_local_size : R600ReadPreloadRegisterIntrinsic_xyz <
+                                       "__builtin_r600_read_local_size">;
+defm int_r600_read_ngroups : R600ReadPreloadRegisterIntrinsic_xyz <
+                                       "__builtin_r600_read_ngroups">;
+defm int_r600_read_tgid : R600ReadPreloadRegisterIntrinsic_xyz <
+                                       "__builtin_r600_read_tgid">;
+defm int_r600_read_tidig : R600ReadPreloadRegisterIntrinsic_xyz <
+                                       "__builtin_r600_read_tidig">;
+
+} // End TargetPrefix = "r600"
+
+let TargetPrefix = "AMDGPU" in {
+def int_AMDGPU_div_scale : GCCBuiltin<"__builtin_amdgpu_div_scale">,
+  // 1st parameter: Numerator
+  // 2nd parameter: Denominator
+  // 3rd parameter: Constant to select select between first and
+  //                second. (0 = first, 1 = second).
+  Intrinsic<[llvm_anyfloat_ty, llvm_i1_ty],
+            [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
+            [IntrNoMem]>;
+
+def int_AMDGPU_div_fmas : GCCBuiltin<"__builtin_amdgpu_div_fmas">,
+  Intrinsic<[llvm_anyfloat_ty],
+            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+            [IntrNoMem]>;
+
+def int_AMDGPU_div_fixup : GCCBuiltin<"__builtin_amdgpu_div_fixup">,
+  Intrinsic<[llvm_anyfloat_ty],
+            [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+            [IntrNoMem]>;
+
+def int_AMDGPU_trig_preop : GCCBuiltin<"__builtin_amdgpu_trig_preop">,
+  Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
+            [IntrNoMem]>;
+
+def int_AMDGPU_rcp : GCCBuiltin<"__builtin_amdgpu_rcp">,
+  Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_AMDGPU_rsq : GCCBuiltin<"__builtin_amdgpu_rsq">,
+  Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_AMDGPU_rsq_clamped : GCCBuiltin<"__builtin_amdgpu_rsq_clamped">,
+  Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+} // End TargetPrefix = "AMDGPU"
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
new file mode 100644
index 0000000..5de9508
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -0,0 +1,3229 @@
+//===- IntrinsicsX86.td - Defines X86 intrinsics -----------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the X86-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Interrupt traps
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_int : Intrinsic<[], [llvm_i8_ty]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Read Time Stamp Counter.
+let TargetPrefix = "x86" in {
+  def int_x86_rdtsc : GCCBuiltin<"__builtin_ia32_rdtsc">,
+              Intrinsic<[llvm_i64_ty], [], []>;
+  def int_x86_rdtscp : GCCBuiltin<"__builtin_ia32_rdtscp">,
+              Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], [IntrReadWriteArgMem]>;
+}
+
+// Read Performance-Monitoring Counter.
+let TargetPrefix = "x86" in {
+  def int_x86_rdpmc : GCCBuiltin<"__builtin_ia32_rdpmc">,
+              Intrinsic<[llvm_i64_ty], [llvm_i32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// 3DNow!
+
+let TargetPrefix = "x86" in {
+  def int_x86_3dnow_pavgusb : GCCBuiltin<"__builtin_ia32_pavgusb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pf2id : GCCBuiltin<"__builtin_ia32_pf2id">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnow_pfacc : GCCBuiltin<"__builtin_ia32_pfacc">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfadd : GCCBuiltin<"__builtin_ia32_pfadd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfcmpeq : GCCBuiltin<"__builtin_ia32_pfcmpeq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfcmpge : GCCBuiltin<"__builtin_ia32_pfcmpge">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfcmpgt : GCCBuiltin<"__builtin_ia32_pfcmpgt">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfmax : GCCBuiltin<"__builtin_ia32_pfmax">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfmin : GCCBuiltin<"__builtin_ia32_pfmin">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfmul : GCCBuiltin<"__builtin_ia32_pfmul">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfrcp : GCCBuiltin<"__builtin_ia32_pfrcp">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnow_pfrcpit1 : GCCBuiltin<"__builtin_ia32_pfrcpit1">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfrcpit2 : GCCBuiltin<"__builtin_ia32_pfrcpit2">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfrsqrt : GCCBuiltin<"__builtin_ia32_pfrsqrt">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnow_pfrsqit1 : GCCBuiltin<"__builtin_ia32_pfrsqit1">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfsub : GCCBuiltin<"__builtin_ia32_pfsub">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pfsubr : GCCBuiltin<"__builtin_ia32_pfsubr">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnow_pi2fd : GCCBuiltin<"__builtin_ia32_pi2fd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnow_pmulhrw : GCCBuiltin<"__builtin_ia32_pmulhrw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// 3DNow! extensions
+
+let TargetPrefix = "x86" in {
+  def int_x86_3dnowa_pf2iw : GCCBuiltin<"__builtin_ia32_pf2iw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnowa_pfnacc : GCCBuiltin<"__builtin_ia32_pfnacc">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnowa_pfpnacc : GCCBuiltin<"__builtin_ia32_pfpnacc">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_3dnowa_pi2fw : GCCBuiltin<"__builtin_ia32_pi2fw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_3dnowa_pswapd :
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE1
+
+// Arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_add_ss : GCCBuiltin<"__builtin_ia32_addss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_sub_ss : GCCBuiltin<"__builtin_ia32_subss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_mul_ss : GCCBuiltin<"__builtin_ia32_mulss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_div_ss : GCCBuiltin<"__builtin_ia32_divss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_sqrt_ps : GCCBuiltin<"__builtin_ia32_sqrtps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_rcp_ss : GCCBuiltin<"__builtin_ia32_rcpss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_rcp_ps : GCCBuiltin<"__builtin_ia32_rcpps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_rsqrt_ss : GCCBuiltin<"__builtin_ia32_rsqrtss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_rsqrt_ps : GCCBuiltin<"__builtin_ia32_rsqrtps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse_min_ss : GCCBuiltin<"__builtin_ia32_minss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_min_ps : GCCBuiltin<"__builtin_ia32_minps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_max_ss : GCCBuiltin<"__builtin_ia32_maxss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_max_ps : GCCBuiltin<"__builtin_ia32_maxps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+// Comparison ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_cmp_ss : GCCBuiltin<"__builtin_ia32_cmpss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_sse_cmp_ps : GCCBuiltin<"__builtin_ia32_cmpps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_sse_comieq_ss : GCCBuiltin<"__builtin_ia32_comieq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_comilt_ss : GCCBuiltin<"__builtin_ia32_comilt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_comile_ss : GCCBuiltin<"__builtin_ia32_comile">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_comigt_ss : GCCBuiltin<"__builtin_ia32_comigt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_comige_ss : GCCBuiltin<"__builtin_ia32_comige">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_comineq_ss : GCCBuiltin<"__builtin_ia32_comineq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomieq_ss : GCCBuiltin<"__builtin_ia32_ucomieq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomilt_ss : GCCBuiltin<"__builtin_ia32_ucomilt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomile_ss : GCCBuiltin<"__builtin_ia32_ucomile">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomigt_ss : GCCBuiltin<"__builtin_ia32_ucomigt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomige_ss : GCCBuiltin<"__builtin_ia32_ucomige">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_ucomineq_ss : GCCBuiltin<"__builtin_ia32_ucomineq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+
+// Conversion ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_cvtss2si : GCCBuiltin<"__builtin_ia32_cvtss2si">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtss2si64 : GCCBuiltin<"__builtin_ia32_cvtss2si64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvttss2si : GCCBuiltin<"__builtin_ia32_cvttss2si">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvttss2si64 : GCCBuiltin<"__builtin_ia32_cvttss2si64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtsi2ss : GCCBuiltin<"__builtin_ia32_cvtsi2ss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtsi642ss : GCCBuiltin<"__builtin_ia32_cvtsi642ss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_i64_ty], [IntrNoMem]>;
+
+  def int_x86_sse_cvtps2pi : GCCBuiltin<"__builtin_ia32_cvtps2pi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvttps2pi: GCCBuiltin<"__builtin_ia32_cvttps2pi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtpi2ps : GCCBuiltin<"__builtin_ia32_cvtpi2ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">,
+              Intrinsic<[], [llvm_ptr_ty,
+                         llvm_v4f32_ty], [IntrReadWriteArgMem]>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_sfence : GCCBuiltin<"__builtin_ia32_sfence">,
+              Intrinsic<[], [], []>;
+}
+
+// Control register.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_stmxcsr :
+              Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_x86_sse_ldmxcsr :
+              Intrinsic<[], [llvm_ptr_ty], []>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse_movmsk_ps : GCCBuiltin<"__builtin_ia32_movmskps">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE2
+
+// FP arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_add_sd : GCCBuiltin<"__builtin_ia32_addsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_sub_sd : GCCBuiltin<"__builtin_ia32_subsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_mul_sd : GCCBuiltin<"__builtin_ia32_mulsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_div_sd : GCCBuiltin<"__builtin_ia32_divsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_sqrt_sd : GCCBuiltin<"__builtin_ia32_sqrtsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse2_sqrt_pd : GCCBuiltin<"__builtin_ia32_sqrtpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse2_min_sd : GCCBuiltin<"__builtin_ia32_minsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_min_pd : GCCBuiltin<"__builtin_ia32_minpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_max_sd : GCCBuiltin<"__builtin_ia32_maxsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_max_pd : GCCBuiltin<"__builtin_ia32_maxpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// FP comparison ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_cmp_sd : GCCBuiltin<"__builtin_ia32_cmpsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_cmp_pd : GCCBuiltin<"__builtin_ia32_cmppd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_comieq_sd : GCCBuiltin<"__builtin_ia32_comisdeq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_comilt_sd : GCCBuiltin<"__builtin_ia32_comisdlt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_comile_sd : GCCBuiltin<"__builtin_ia32_comisdle">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_comigt_sd : GCCBuiltin<"__builtin_ia32_comisdgt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_comige_sd : GCCBuiltin<"__builtin_ia32_comisdge">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_comineq_sd : GCCBuiltin<"__builtin_ia32_comisdneq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomieq_sd : GCCBuiltin<"__builtin_ia32_ucomisdeq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomilt_sd : GCCBuiltin<"__builtin_ia32_ucomisdlt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomile_sd : GCCBuiltin<"__builtin_ia32_ucomisdle">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomigt_sd : GCCBuiltin<"__builtin_ia32_ucomisdgt">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomige_sd : GCCBuiltin<"__builtin_ia32_ucomisdge">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_ucomineq_sd : GCCBuiltin<"__builtin_ia32_ucomisdneq">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_padds_b : GCCBuiltin<"__builtin_ia32_paddsb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_padds_w : GCCBuiltin<"__builtin_ia32_paddsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pminu_b : GCCBuiltin<"__builtin_ia32_pminub128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_sse2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_psll_w : GCCBuiltin<"__builtin_ia32_psllw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_psll_d : GCCBuiltin<"__builtin_ia32_pslld128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psll_q : GCCBuiltin<"__builtin_ia32_psllq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrl_d : GCCBuiltin<"__builtin_ia32_psrld128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_sse2_psra_w : GCCBuiltin<"__builtin_ia32_psraw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_psra_d : GCCBuiltin<"__builtin_ia32_psrad128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+
+  def int_x86_sse2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrai_d : GCCBuiltin<"__builtin_ia32_psradi128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_sse2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi128_byteshift">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi128_byteshift">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Conversion ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_cvtdq2pd : GCCBuiltin<"__builtin_ia32_cvtdq2pd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtdq2ps : GCCBuiltin<"__builtin_ia32_cvtdq2ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtpd2dq : GCCBuiltin<"__builtin_ia32_cvtpd2dq">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvttpd2dq : GCCBuiltin<"__builtin_ia32_cvttpd2dq">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtpd2ps : GCCBuiltin<"__builtin_ia32_cvtpd2ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtps2dq : GCCBuiltin<"__builtin_ia32_cvtps2dq">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvttps2dq : GCCBuiltin<"__builtin_ia32_cvttps2dq">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtps2pd : GCCBuiltin<"__builtin_ia32_cvtps2pd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtsd2si : GCCBuiltin<"__builtin_ia32_cvtsd2si">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtsd2si64 : GCCBuiltin<"__builtin_ia32_cvtsd2si64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvttsd2si : GCCBuiltin<"__builtin_ia32_cvttsd2si">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_cvttsd2si64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtsi2sd : GCCBuiltin<"__builtin_ia32_cvtsi2sd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtsi642sd : GCCBuiltin<"__builtin_ia32_cvtsi642sd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_i64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtsd2ss : GCCBuiltin<"__builtin_ia32_cvtsd2ss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_cvtss2sd : GCCBuiltin<"__builtin_ia32_cvtss2sd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtpd2pi : GCCBuiltin<"__builtin_ia32_cvtpd2pi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse_cvttpd2pi: GCCBuiltin<"__builtin_ia32_cvttpd2pi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse_cvtpi2pd : GCCBuiltin<"__builtin_ia32_cvtpi2pd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">,
+              Intrinsic<[], [llvm_ptr_ty,
+                         llvm_v2f64_ty], [IntrReadWriteArgMem]>;
+  def int_x86_sse2_storeu_dq : GCCBuiltin<"__builtin_ia32_storedqu">,
+              Intrinsic<[], [llvm_ptr_ty,
+                         llvm_v16i8_ty], [IntrReadWriteArgMem]>;
+  def int_x86_sse2_storel_dq : GCCBuiltin<"__builtin_ia32_storelv4si">,
+              Intrinsic<[], [llvm_ptr_ty,
+                         llvm_v4i32_ty], [IntrReadWriteArgMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse2_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_packssdw_128 : GCCBuiltin<"__builtin_ia32_packssdw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sse2_packuswb_128 : GCCBuiltin<"__builtin_ia32_packuswb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_sse2_movmsk_pd : GCCBuiltin<"__builtin_ia32_movmskpd">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse2_pmovmskb_128 : GCCBuiltin<"__builtin_ia32_pmovmskb128">,
+              Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_maskmov_dqu : GCCBuiltin<"__builtin_ia32_maskmovdqu">,
+              Intrinsic<[], [llvm_v16i8_ty,
+                         llvm_v16i8_ty, llvm_ptr_ty], []>;
+  def int_x86_sse2_clflush : GCCBuiltin<"__builtin_ia32_clflush">,
+              Intrinsic<[], [llvm_ptr_ty], []>;
+  def int_x86_sse2_lfence : GCCBuiltin<"__builtin_ia32_lfence">,
+              Intrinsic<[], [], []>;
+  def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
+              Intrinsic<[], [], []>;
+  def int_x86_sse2_pause : GCCBuiltin<"__builtin_ia32_pause">,
+              Intrinsic<[], [], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE3
+
+// Addition / subtraction ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse3_addsub_ps : GCCBuiltin<"__builtin_ia32_addsubps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse3_addsub_pd : GCCBuiltin<"__builtin_ia32_addsubpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Horizontal ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse3_hadd_ps : GCCBuiltin<"__builtin_ia32_haddps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse3_hadd_pd : GCCBuiltin<"__builtin_ia32_haddpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_sse3_hsub_ps : GCCBuiltin<"__builtin_ia32_hsubps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_sse3_hsub_pd : GCCBuiltin<"__builtin_ia32_hsubpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Specialized unaligned load.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse3_ldu_dq : GCCBuiltin<"__builtin_ia32_lddqu">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// Thread synchronization ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse3_monitor : GCCBuiltin<"__builtin_ia32_monitor">,
+              Intrinsic<[], [llvm_ptr_ty,
+                         llvm_i32_ty, llvm_i32_ty], []>;
+  def int_x86_sse3_mwait : GCCBuiltin<"__builtin_ia32_mwait">,
+              Intrinsic<[], [llvm_i32_ty,
+                         llvm_i32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSSE3
+
+// Horizontal arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_ssse3_phadd_w         : GCCBuiltin<"__builtin_ia32_phaddw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phadd_w_128     : GCCBuiltin<"__builtin_ia32_phaddw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_phadd_d         : GCCBuiltin<"__builtin_ia32_phaddd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phadd_d_128     : GCCBuiltin<"__builtin_ia32_phaddd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_phadd_sw        : GCCBuiltin<"__builtin_ia32_phaddsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phadd_sw_128    : GCCBuiltin<"__builtin_ia32_phaddsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_phsub_w         : GCCBuiltin<"__builtin_ia32_phsubw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phsub_w_128     : GCCBuiltin<"__builtin_ia32_phsubw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_phsub_d         : GCCBuiltin<"__builtin_ia32_phsubd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phsub_d_128     : GCCBuiltin<"__builtin_ia32_phsubd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_phsub_sw        : GCCBuiltin<"__builtin_ia32_phsubsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_phsub_sw_128    : GCCBuiltin<"__builtin_ia32_phsubsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_pmadd_ub_sw     : GCCBuiltin<"__builtin_ia32_pmaddubsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_pmadd_ub_sw_128 : GCCBuiltin<"__builtin_ia32_pmaddubsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem]>;
+}
+
+// Packed multiply high with round and scale
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_ssse3_pmul_hr_sw      : GCCBuiltin<"__builtin_ia32_pmulhrsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_ssse3_pmul_hr_sw_128  : GCCBuiltin<"__builtin_ia32_pmulhrsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+}
+
+// Shuffle ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_ssse3_pshuf_b         : GCCBuiltin<"__builtin_ia32_pshufb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_pshuf_b_128     : GCCBuiltin<"__builtin_ia32_pshufb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_sse2_pshuf_d          : GCCBuiltin<"__builtin_ia32_pshufd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i8_ty],
+                         [IntrNoMem]>;
+  def int_x86_sse2_pshufl_w         : GCCBuiltin<"__builtin_ia32_pshuflw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+                         [IntrNoMem]>;
+  def int_x86_sse2_pshufh_w         : GCCBuiltin<"__builtin_ia32_pshufhw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+                         [IntrNoMem]>;
+  def int_x86_sse_pshuf_w           : GCCBuiltin<"__builtin_ia32_pshufw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i8_ty],
+                         [IntrNoMem]>;
+}
+
+// Sign ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_ssse3_psign_b         : GCCBuiltin<"__builtin_ia32_psignb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_psign_b_128     : GCCBuiltin<"__builtin_ia32_psignb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+                         llvm_v16i8_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_psign_w         : GCCBuiltin<"__builtin_ia32_psignw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_psign_w_128     : GCCBuiltin<"__builtin_ia32_psignw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_psign_d         : GCCBuiltin<"__builtin_ia32_psignd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_psign_d_128     : GCCBuiltin<"__builtin_ia32_psignd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+// Absolute value ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_ssse3_pabs_b     : GCCBuiltin<"__builtin_ia32_pabsb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_pabs_b_128 : GCCBuiltin<"__builtin_ia32_pabsb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_pabs_w     : GCCBuiltin<"__builtin_ia32_pabsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_pabs_w_128 : GCCBuiltin<"__builtin_ia32_pabsw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+
+  def int_x86_ssse3_pabs_d     : GCCBuiltin<"__builtin_ia32_pabsd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_ssse3_pabs_d_128 : GCCBuiltin<"__builtin_ia32_pabsd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE4.1
+
+// FP rounding ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_round_ss        : GCCBuiltin<"__builtin_ia32_roundss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse41_round_ps        : GCCBuiltin<"__builtin_ia32_roundps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse41_round_sd        : GCCBuiltin<"__builtin_ia32_roundsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_sse41_round_pd        : GCCBuiltin<"__builtin_ia32_roundpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector sign and zero extend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_pmovsxbd        : GCCBuiltin<"__builtin_ia32_pmovsxbd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovsxbq        : GCCBuiltin<"__builtin_ia32_pmovsxbq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovsxbw        : GCCBuiltin<"__builtin_ia32_pmovsxbw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovsxdq        : GCCBuiltin<"__builtin_ia32_pmovsxdq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovsxwd        : GCCBuiltin<"__builtin_ia32_pmovsxwd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovsxwq        : GCCBuiltin<"__builtin_ia32_pmovsxwq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxbd        : GCCBuiltin<"__builtin_ia32_pmovzxbd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxbq        : GCCBuiltin<"__builtin_ia32_pmovzxbq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxbw        : GCCBuiltin<"__builtin_ia32_pmovzxbw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxdq        : GCCBuiltin<"__builtin_ia32_pmovzxdq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxwd        : GCCBuiltin<"__builtin_ia32_pmovzxwd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pmovzxwq        : GCCBuiltin<"__builtin_ia32_pmovzxwq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector min element
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_phminposuw     : GCCBuiltin<"__builtin_ia32_phminposuw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector compare, min, max
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_pmaxsb          : GCCBuiltin<"__builtin_ia32_pmaxsb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pmaxsd          : GCCBuiltin<"__builtin_ia32_pmaxsd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pmaxud          : GCCBuiltin<"__builtin_ia32_pmaxud128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pmaxuw          : GCCBuiltin<"__builtin_ia32_pmaxuw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pminsb          : GCCBuiltin<"__builtin_ia32_pminsb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pminsd          : GCCBuiltin<"__builtin_ia32_pminsd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pminud          : GCCBuiltin<"__builtin_ia32_pminud128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem, Commutative]>;
+  def int_x86_sse41_pminuw          : GCCBuiltin<"__builtin_ia32_pminuw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem, Commutative]>;
+}
+
+// Advanced Encryption Standard (AES) Instructions
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_aesni_aesimc          : GCCBuiltin<"__builtin_ia32_aesimc128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_aesni_aesenc          : GCCBuiltin<"__builtin_ia32_aesenc128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_aesni_aesenclast : GCCBuiltin<"__builtin_ia32_aesenclast128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_aesni_aesdec          : GCCBuiltin<"__builtin_ia32_aesdec128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_aesni_aesdeclast : GCCBuiltin<"__builtin_ia32_aesdeclast128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_aesni_aeskeygenassist :
+              GCCBuiltin<"__builtin_ia32_aeskeygenassist128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+}
+
+// PCLMUL instruction
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+  def int_x86_pclmulqdq : GCCBuiltin<"__builtin_ia32_pclmulqdq128">,
+          Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
+                    [IntrNoMem]>;
+}
+
+// Vector pack
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_packusdw        : GCCBuiltin<"__builtin_ia32_packusdw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector multiply
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_pmuldq          : GCCBuiltin<"__builtin_ia32_pmuldq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem, Commutative]>;
+}
+
+// Vector extract
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_pextrb         :
+              Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pextrd         :
+              Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_pextrq         :
+              Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_sse41_extractps      : GCCBuiltin<"__builtin_ia32_extractps128">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector insert
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_insertps       : GCCBuiltin<"__builtin_ia32_insertps128">,
+          Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_i32_ty],
+                    [IntrNoMem]>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_pblendvb         : GCCBuiltin<"__builtin_ia32_pblendvb128">,
+        Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_v16i8_ty],
+                  [IntrNoMem]>;
+  def int_x86_sse41_pblendw          : GCCBuiltin<"__builtin_ia32_pblendw128">,
+        Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+                  [IntrNoMem]>;
+  def int_x86_sse41_blendpd          : GCCBuiltin<"__builtin_ia32_blendpd">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
+                  [IntrNoMem]>;
+  def int_x86_sse41_blendps          : GCCBuiltin<"__builtin_ia32_blendps">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
+                  [IntrNoMem]>;
+  def int_x86_sse41_blendvpd         : GCCBuiltin<"__builtin_ia32_blendvpd">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_v2f64_ty],
+                  [IntrNoMem]>;
+  def int_x86_sse41_blendvps         : GCCBuiltin<"__builtin_ia32_blendvps">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
+                  [IntrNoMem]>;
+}
+
+// Vector dot product
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_dppd            : GCCBuiltin<"__builtin_ia32_dppd">,
+          Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_i32_ty],
+                    [IntrNoMem, Commutative]>;
+  def int_x86_sse41_dpps            : GCCBuiltin<"__builtin_ia32_dpps">,
+          Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_i32_ty],
+                    [IntrNoMem, Commutative]>;
+}
+
+// Vector sum of absolute differences
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_mpsadbw         : GCCBuiltin<"__builtin_ia32_mpsadbw128">,
+          Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_i32_ty],
+                    [IntrNoMem, Commutative]>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_movntdqa        : GCCBuiltin<"__builtin_ia32_movntdqa">,
+          Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// Test instruction with bitwise comparison.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+  def int_x86_sse41_ptestz          : GCCBuiltin<"__builtin_ia32_ptestz128">,
+          Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                    [IntrNoMem]>;
+  def int_x86_sse41_ptestc          : GCCBuiltin<"__builtin_ia32_ptestc128">,
+          Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                    [IntrNoMem]>;
+  def int_x86_sse41_ptestnzc        : GCCBuiltin<"__builtin_ia32_ptestnzc128">,
+          Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                    [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE4.2
+
+// Miscellaneous
+// CRC Instruction
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+  def int_x86_sse42_crc32_32_8       : GCCBuiltin<"__builtin_ia32_crc32qi">,
+          Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i8_ty],
+                    [IntrNoMem]>;
+  def int_x86_sse42_crc32_32_16      : GCCBuiltin<"__builtin_ia32_crc32hi">,
+          Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i16_ty],
+                    [IntrNoMem]>;
+  def int_x86_sse42_crc32_32_32      : GCCBuiltin<"__builtin_ia32_crc32si">,
+          Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                    [IntrNoMem]>;
+  def int_x86_sse42_crc32_64_64      : GCCBuiltin<"__builtin_ia32_crc32di">,
+          Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+                    [IntrNoMem]>;
+}
+
+// String/text processing ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+  def int_x86_sse42_pcmpistrm128  : GCCBuiltin<"__builtin_ia32_pcmpistrm128">,
+    Intrinsic<[llvm_v16i8_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistri128  : GCCBuiltin<"__builtin_ia32_pcmpistri128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestrm128  : GCCBuiltin<"__builtin_ia32_pcmpestrm128">,
+    Intrinsic<[llvm_v16i8_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestri128  : GCCBuiltin<"__builtin_ia32_pcmpestri128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+  def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">,
+    Intrinsic<[llvm_i32_ty],
+        [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+         llvm_i8_ty],
+        [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE4A
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_sse4a_extrqi : GCCBuiltin<"__builtin_ia32_extrqi">,
+    Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty, llvm_i8_ty],
+              [IntrNoMem]>;
+  def int_x86_sse4a_extrq  : GCCBuiltin<"__builtin_ia32_extrq">,
+    Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+  def int_x86_sse4a_insertqi : GCCBuiltin<"__builtin_ia32_insertqi">,
+    Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+                                llvm_i8_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_sse4a_insertq  : GCCBuiltin<"__builtin_ia32_insertq">,
+    Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+
+  def int_x86_sse4a_movnt_ss : GCCBuiltin<"__builtin_ia32_movntss">,
+    Intrinsic<[], [llvm_ptr_ty, llvm_v4f32_ty], []>;
+  def int_x86_sse4a_movnt_sd : GCCBuiltin<"__builtin_ia32_movntsd">,
+    Intrinsic<[], [llvm_ptr_ty, llvm_v2f64_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// AVX
+
+// Arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_addsub_pd_256 : GCCBuiltin<"__builtin_ia32_addsubpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_addsub_ps_256 : GCCBuiltin<"__builtin_ia32_addsubps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_max_pd_256 : GCCBuiltin<"__builtin_ia32_maxpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_max_ps_256 : GCCBuiltin<"__builtin_ia32_maxps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_min_pd_256 : GCCBuiltin<"__builtin_ia32_minpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_min_ps_256 : GCCBuiltin<"__builtin_ia32_minps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_sqrt_pd_256 : GCCBuiltin<"__builtin_ia32_sqrtpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_sqrt_ps_256 : GCCBuiltin<"__builtin_ia32_sqrtps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_rsqrt_ps_256 : GCCBuiltin<"__builtin_ia32_rsqrtps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_rcp_ps_256 : GCCBuiltin<"__builtin_ia32_rcpps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_round_pd_256 : GCCBuiltin<"__builtin_ia32_roundpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx_round_ps_256 : GCCBuiltin<"__builtin_ia32_roundps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Horizontal ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_hadd_pd_256 : GCCBuiltin<"__builtin_ia32_haddpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_hsub_ps_256 : GCCBuiltin<"__builtin_ia32_hsubps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_hsub_pd_256 : GCCBuiltin<"__builtin_ia32_hsubpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_hadd_ps_256 : GCCBuiltin<"__builtin_ia32_haddps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector permutation
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_vpermilvar_pd : GCCBuiltin<"__builtin_ia32_vpermilvarpd">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                  llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx_vpermilvar_ps : GCCBuiltin<"__builtin_ia32_vpermilvarps">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                  llvm_v4i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_vpermilvar_pd_256 :
+        GCCBuiltin<"__builtin_ia32_vpermilvarpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4i64_ty], [IntrNoMem]>;
+  def int_x86_avx_vpermilvar_ps_256 :
+        GCCBuiltin<"__builtin_ia32_vpermilvarps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx_vperm2f128_pd_256 :
+        GCCBuiltin<"__builtin_ia32_vperm2f128_pd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vperm2f128_ps_256 :
+        GCCBuiltin<"__builtin_ia32_vperm2f128_ps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vperm2f128_si_256 :
+        GCCBuiltin<"__builtin_ia32_vperm2f128_si256">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                  llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_mask_vpermt_d_512:
+        GCCBuiltin<"__builtin_ia32_vpermt2vard512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
+                  llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_mask_vpermt_q_512:
+        GCCBuiltin<"__builtin_ia32_vpermt2varq512_mask">,
+        Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                  llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_mask_vpermt_ps_512:
+        GCCBuiltin<"__builtin_ia32_vpermt2varps512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty,
+                  llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_mask_vpermt_pd_512:
+        GCCBuiltin<"__builtin_ia32_vpermt2varpd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8i64_ty,
+                  llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>;
+
+}
+
+// Vector blend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_blend_pd_256 : GCCBuiltin<"__builtin_ia32_blendpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx_blend_ps_256 : GCCBuiltin<"__builtin_ia32_blendps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_blendv_ps_256 : GCCBuiltin<"__builtin_ia32_blendvps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector dot product
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_dp_ps_256 : GCCBuiltin<"__builtin_ia32_dpps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector compare
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_cmp_pd_256 : GCCBuiltin<"__builtin_ia32_cmppd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_cmp_ps_256 : GCCBuiltin<"__builtin_ia32_cmpps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector extract and insert
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_vextractf128_pd_256 :
+        GCCBuiltin<"__builtin_ia32_vextractf128_pd256">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vextractf128_ps_256 :
+        GCCBuiltin<"__builtin_ia32_vextractf128_ps256">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vextractf128_si_256 :
+        GCCBuiltin<"__builtin_ia32_vextractf128_si256">,
+        Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_avx_vinsertf128_pd_256 :
+        GCCBuiltin<"__builtin_ia32_vinsertf128_pd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+                  llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vinsertf128_ps_256 :
+        GCCBuiltin<"__builtin_ia32_vinsertf128_ps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+                  llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx_vinsertf128_si_256 :
+        GCCBuiltin<"__builtin_ia32_vinsertf128_si256">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                  llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector convert
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_cvtdq2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtdq2pd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx_cvtdq2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtdq2ps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8i32_ty], [IntrNoMem]>;
+  def int_x86_avx_cvt_pd2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtpd2ps256">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_cvt_ps2dq_256 : GCCBuiltin<"__builtin_ia32_cvtps2dq256">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_cvt_ps2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtps2pd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx_cvtt_pd2dq_256 : GCCBuiltin<"__builtin_ia32_cvttpd2dq256">,
+        Intrinsic<[llvm_v4i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_cvt_pd2dq_256 : GCCBuiltin<"__builtin_ia32_cvtpd2dq256">,
+        Intrinsic<[llvm_v4i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_cvtt_ps2dq_256 : GCCBuiltin<"__builtin_ia32_cvttps2dq256">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector bit test
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_vtestz_pd : GCCBuiltin<"__builtin_ia32_vtestzpd">,
+        Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                  llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestc_pd : GCCBuiltin<"__builtin_ia32_vtestcpd">,
+        Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                  llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestnzc_pd : GCCBuiltin<"__builtin_ia32_vtestnzcpd">,
+        Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+                  llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestz_ps : GCCBuiltin<"__builtin_ia32_vtestzps">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                  llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestc_ps : GCCBuiltin<"__builtin_ia32_vtestcps">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                  llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestnzc_ps : GCCBuiltin<"__builtin_ia32_vtestnzcps">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+                  llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestz_pd_256 : GCCBuiltin<"__builtin_ia32_vtestzpd256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestc_pd_256 : GCCBuiltin<"__builtin_ia32_vtestcpd256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestnzc_pd_256 : GCCBuiltin<"__builtin_ia32_vtestnzcpd256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+                  llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestz_ps_256 : GCCBuiltin<"__builtin_ia32_vtestzps256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestc_ps_256 : GCCBuiltin<"__builtin_ia32_vtestcps256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_vtestnzc_ps_256 : GCCBuiltin<"__builtin_ia32_vtestnzcps256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+                  llvm_v8f32_ty], [IntrNoMem]>;
+  def int_x86_avx_ptestz_256 : GCCBuiltin<"__builtin_ia32_ptestz256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+                  llvm_v4i64_ty], [IntrNoMem]>;
+  def int_x86_avx_ptestc_256 : GCCBuiltin<"__builtin_ia32_ptestc256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+                  llvm_v4i64_ty], [IntrNoMem]>;
+  def int_x86_avx_ptestnzc_256 : GCCBuiltin<"__builtin_ia32_ptestnzc256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+                  llvm_v4i64_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_ptestm_d_512 : GCCBuiltin<"__builtin_ia32_ptestmd512">,
+        Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                  llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_ptestm_q_512 : GCCBuiltin<"__builtin_ia32_ptestmq512">,
+        Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                  llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector extract sign mask
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_movmsk_pd_256 : GCCBuiltin<"__builtin_ia32_movmskpd256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_avx_movmsk_ps_256 : GCCBuiltin<"__builtin_ia32_movmskps256">,
+        Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector zero
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_vzeroall : GCCBuiltin<"__builtin_ia32_vzeroall">,
+        Intrinsic<[], [], []>;
+  def int_x86_avx_vzeroupper : GCCBuiltin<"__builtin_ia32_vzeroupper">,
+        Intrinsic<[], [], []>;
+}
+
+// Vector load with broadcast
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_vbroadcastf128_pd_256 :
+        GCCBuiltin<"__builtin_ia32_vbroadcastf128_pd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_x86_avx_vbroadcastf128_ps_256 :
+        GCCBuiltin<"__builtin_ia32_vbroadcastf128_ps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+}
+
+// SIMD load ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_ldu_dq_256 : GCCBuiltin<"__builtin_ia32_lddqu256">,
+        Intrinsic<[llvm_v32i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_storeu_pd_256 : GCCBuiltin<"__builtin_ia32_storeupd256">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx_storeu_ps_256 : GCCBuiltin<"__builtin_ia32_storeups256">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx_storeu_dq_256 : GCCBuiltin<"__builtin_ia32_storedqu256">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v32i8_ty], [IntrReadWriteArgMem]>;
+}
+
+// Conditional load ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_maskload_pd : GCCBuiltin<"__builtin_ia32_maskloadpd">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2f64_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx_maskload_ps : GCCBuiltin<"__builtin_ia32_maskloadps">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4f32_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx_maskload_pd_256 : GCCBuiltin<"__builtin_ia32_maskloadpd256">,
+        Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4f64_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx_maskload_ps_256 : GCCBuiltin<"__builtin_ia32_maskloadps256">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx512_mask_loadu_ps_512 : GCCBuiltin<"__builtin_ia32_loadups512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx512_mask_loadu_pd_512 : GCCBuiltin<"__builtin_ia32_loadupd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+                  [IntrReadArgMem]>;
+}
+
+// Conditional store ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx_maskstore_pd : GCCBuiltin<"__builtin_ia32_maskstorepd">,
+        Intrinsic<[], [llvm_ptr_ty,
+                  llvm_v2f64_ty, llvm_v2f64_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx_maskstore_ps : GCCBuiltin<"__builtin_ia32_maskstoreps">,
+        Intrinsic<[], [llvm_ptr_ty,
+                  llvm_v4f32_ty, llvm_v4f32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx_maskstore_pd_256 :
+        GCCBuiltin<"__builtin_ia32_maskstorepd256">,
+        Intrinsic<[], [llvm_ptr_ty,
+                  llvm_v4f64_ty, llvm_v4f64_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx_maskstore_ps_256 :
+        GCCBuiltin<"__builtin_ia32_maskstoreps256">,
+        Intrinsic<[], [llvm_ptr_ty,
+                  llvm_v8f32_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_mask_storeu_ps_512 :
+        GCCBuiltin<"__builtin_ia32_storeups512_mask">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx512_mask_storeu_pd_512 :
+        GCCBuiltin<"__builtin_ia32_storeupd512_mask">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+                  [IntrReadWriteArgMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// AVX2
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_padds_b : GCCBuiltin<"__builtin_ia32_paddsb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_padds_w : GCCBuiltin<"__builtin_ia32_paddsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmul_dq : GCCBuiltin<"__builtin_ia32_pmuldq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector min, max
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmaxu_w : GCCBuiltin<"__builtin_ia32_pmaxuw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmaxu_d : GCCBuiltin<"__builtin_ia32_pmaxud256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmaxs_b : GCCBuiltin<"__builtin_ia32_pmaxsb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmaxs_d : GCCBuiltin<"__builtin_ia32_pmaxsd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pminu_b : GCCBuiltin<"__builtin_ia32_pminub256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pminu_w : GCCBuiltin<"__builtin_ia32_pminuw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pminu_d : GCCBuiltin<"__builtin_ia32_pminud256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmins_b : GCCBuiltin<"__builtin_ia32_pminsb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_pmins_d : GCCBuiltin<"__builtin_ia32_pminsd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx512_mask_pmaxu_d_512 : GCCBuiltin<"__builtin_ia32_pmaxud512_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmaxs_d_512 : GCCBuiltin<"__builtin_ia32_pmaxsd512_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmaxu_q_512 : GCCBuiltin<"__builtin_ia32_pmaxuq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmaxs_q_512 : GCCBuiltin<"__builtin_ia32_pmaxsq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pminu_d_512 : GCCBuiltin<"__builtin_ia32_pminud512_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmins_d_512 : GCCBuiltin<"__builtin_ia32_pminsd512_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                         llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pminu_q_512 : GCCBuiltin<"__builtin_ia32_pminuq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pmins_q_512 : GCCBuiltin<"__builtin_ia32_pminsq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                         llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_psll_w : GCCBuiltin<"__builtin_ia32_psllw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_psll_d : GCCBuiltin<"__builtin_ia32_pslld256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psll_q : GCCBuiltin<"__builtin_ia32_psllq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrl_d : GCCBuiltin<"__builtin_ia32_psrld256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx2_psra_w : GCCBuiltin<"__builtin_ia32_psraw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_psra_d : GCCBuiltin<"__builtin_ia32_psrad256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v4i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrai_d : GCCBuiltin<"__builtin_ia32_psradi256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi256_byteshift">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi256_byteshift">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Pack ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_packsswb : GCCBuiltin<"__builtin_ia32_packsswb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_packssdw : GCCBuiltin<"__builtin_ia32_packssdw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_packuswb : GCCBuiltin<"__builtin_ia32_packuswb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_packusdw : GCCBuiltin<"__builtin_ia32_packusdw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem]>;
+}
+
+// Absolute value ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pabs_b : GCCBuiltin<"__builtin_ia32_pabsb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_pabs_w : GCCBuiltin<"__builtin_ia32_pabsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_pabs_d : GCCBuiltin<"__builtin_ia32_pabsd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pabs_d_512 : GCCBuiltin<"__builtin_ia32_pabsd512_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                                           llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pabs_q_512 : GCCBuiltin<"__builtin_ia32_pabsq512_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                                          llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Horizontal arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_phadd_w : GCCBuiltin<"__builtin_ia32_phaddw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_phadd_d : GCCBuiltin<"__builtin_ia32_phaddd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_phadd_sw : GCCBuiltin<"__builtin_ia32_phaddsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_phsub_w : GCCBuiltin<"__builtin_ia32_phsubw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_phsub_d : GCCBuiltin<"__builtin_ia32_phsubd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_phsub_sw : GCCBuiltin<"__builtin_ia32_phsubsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_pmadd_ub_sw : GCCBuiltin<"__builtin_ia32_pmaddubsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+}
+
+// Sign ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_psign_b : GCCBuiltin<"__builtin_ia32_psignb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_psign_w : GCCBuiltin<"__builtin_ia32_psignw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_psign_d : GCCBuiltin<"__builtin_ia32_psignd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+                         llvm_v8i32_ty], [IntrNoMem]>;
+}
+
+// Packed multiply high with round and scale
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+                         llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+}
+
+// Vector sign and zero extend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pmovsxbd : GCCBuiltin<"__builtin_ia32_pmovsxbd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovsxbq : GCCBuiltin<"__builtin_ia32_pmovsxbq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovsxbw : GCCBuiltin<"__builtin_ia32_pmovsxbw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovsxdq : GCCBuiltin<"__builtin_ia32_pmovsxdq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovsxwd : GCCBuiltin<"__builtin_ia32_pmovsxwd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovsxwq : GCCBuiltin<"__builtin_ia32_pmovsxwq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxbd : GCCBuiltin<"__builtin_ia32_pmovzxbd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxbq : GCCBuiltin<"__builtin_ia32_pmovzxbq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxbw : GCCBuiltin<"__builtin_ia32_pmovzxbw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxdq : GCCBuiltin<"__builtin_ia32_pmovzxdq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxwd : GCCBuiltin<"__builtin_ia32_pmovzxwd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_pmovzxwq : GCCBuiltin<"__builtin_ia32_pmovzxwq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_pblendw : GCCBuiltin<"__builtin_ia32_pblendw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pblendd_128 : GCCBuiltin<"__builtin_ia32_pblendd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pblendd_256 : GCCBuiltin<"__builtin_ia32_pblendd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector load with broadcast
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_vbroadcast_ss_ps :
+              GCCBuiltin<"__builtin_ia32_vbroadcastss_ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx2_vbroadcast_sd_pd_256 :
+              GCCBuiltin<"__builtin_ia32_vbroadcastsd_pd256">,
+              Intrinsic<[llvm_v4f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx2_vbroadcast_ss_ps_256 :
+              GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">,
+              Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx2_vbroadcasti128 :
+              Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_x86_avx2_pbroadcastb_128 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastb128">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastb_256 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastw_128 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastw128">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastw_256 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastd_128 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastd128">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastd_256 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastd256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastq_128 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastq128">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx2_pbroadcastq_256 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastq256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pbroadcast_d_gpr_512 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastd512_gpr_mask">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_i32_ty, llvm_v16i32_ty,
+              llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pbroadcast_q_gpr_512 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastq512_gpr_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty, llvm_v8i64_ty,
+              llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_pbroadcast_q_mem_512 :
+              GCCBuiltin<"__builtin_ia32_pbroadcastq512_mem_mask">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty, llvm_v8i64_ty,
+              llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector permutation
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_permd : GCCBuiltin<"__builtin_ia32_permvarsi256">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_permps : GCCBuiltin<"__builtin_ia32_permvarsf256">,
+              Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_vperm2i128 : GCCBuiltin<"__builtin_ia32_permti256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector extract and insert
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_vextracti128 : GCCBuiltin<"__builtin_ia32_extract128i256">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_vinserti128 : GCCBuiltin<"__builtin_ia32_insert128i256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+                         llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Conditional load ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_maskload_d : GCCBuiltin<"__builtin_ia32_maskloadd">,
+        Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_v4i32_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx2_maskload_q : GCCBuiltin<"__builtin_ia32_maskloadq">,
+        Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_v2i64_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx2_maskload_d_256 : GCCBuiltin<"__builtin_ia32_maskloadd256">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_v8i32_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx2_maskload_q_256 : GCCBuiltin<"__builtin_ia32_maskloadq256">,
+        Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_v4i64_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx512_mask_loadu_d_512 : GCCBuiltin<"__builtin_ia32_loaddqusi512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty],
+                  [IntrReadArgMem]>;
+  def int_x86_avx512_mask_loadu_q_512 : GCCBuiltin<"__builtin_ia32_loaddqudi512_mask">,
+        Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty],
+                  [IntrReadArgMem]>;
+}
+
+// Conditional store ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_maskstore_d : GCCBuiltin<"__builtin_ia32_maskstored">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx2_maskstore_q : GCCBuiltin<"__builtin_ia32_maskstoreq">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx2_maskstore_d_256 :
+        GCCBuiltin<"__builtin_ia32_maskstored256">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx2_maskstore_q_256 :
+        GCCBuiltin<"__builtin_ia32_maskstoreq256">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx512_mask_storeu_d_512 :
+        GCCBuiltin<"__builtin_ia32_storedqusi512_mask">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty],
+                  [IntrReadWriteArgMem]>;
+  def int_x86_avx512_mask_storeu_q_512 :
+        GCCBuiltin<"__builtin_ia32_storedqudi512_mask">,
+        Intrinsic<[], [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty],
+                  [IntrReadWriteArgMem]>;
+}
+
+// Variable bit shift ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_psllv_d : GCCBuiltin<"__builtin_ia32_psllv4si">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psllv_d_256 : GCCBuiltin<"__builtin_ia32_psllv8si">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psllv_q : GCCBuiltin<"__builtin_ia32_psllv2di">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psllv_q_256 : GCCBuiltin<"__builtin_ia32_psllv4di">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_avx2_psrlv_d : GCCBuiltin<"__builtin_ia32_psrlv4si">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psrlv_d_256 : GCCBuiltin<"__builtin_ia32_psrlv8si">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psrlv_q : GCCBuiltin<"__builtin_ia32_psrlv2di">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psrlv_q_256 : GCCBuiltin<"__builtin_ia32_psrlv4di">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_avx2_psrav_d : GCCBuiltin<"__builtin_ia32_psrav4si">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx2_psrav_d_256 : GCCBuiltin<"__builtin_ia32_psrav8si">,
+              Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+                        [IntrNoMem]>;
+}
+
+// Gather ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">,
+      Intrinsic<[llvm_v2f64_ty],
+        [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">,
+      Intrinsic<[llvm_v4f64_ty],
+        [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">,
+      Intrinsic<[llvm_v2f64_ty],
+        [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">,
+      Intrinsic<[llvm_v4f64_ty],
+        [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">,
+      Intrinsic<[llvm_v4f32_ty],
+        [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">,
+      Intrinsic<[llvm_v8f32_ty],
+        [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">,
+      Intrinsic<[llvm_v4f32_ty],
+        [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">,
+      Intrinsic<[llvm_v4f32_ty],
+        [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+
+  def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">,
+      Intrinsic<[llvm_v2i64_ty],
+        [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">,
+      Intrinsic<[llvm_v4i64_ty],
+        [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">,
+      Intrinsic<[llvm_v2i64_ty],
+        [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">,
+      Intrinsic<[llvm_v4i64_ty],
+        [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">,
+      Intrinsic<[llvm_v4i32_ty],
+        [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">,
+      Intrinsic<[llvm_v8i32_ty],
+        [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">,
+      Intrinsic<[llvm_v4i32_ty],
+        [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+  def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">,
+      Intrinsic<[llvm_v4i32_ty],
+        [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty],
+        [IntrReadArgMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx2_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb256">,
+              Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_pshuf_b : GCCBuiltin<"__builtin_ia32_pshufb256">,
+              Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+                         llvm_v32i8_ty], [IntrNoMem]>;
+  def int_x86_avx2_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw256">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+                         llvm_i32_ty], [IntrNoMem, Commutative]>;
+  def int_x86_avx2_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa256">,
+              Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+  def int_x86_avx512_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// FMA3 and FMA4
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_fma_vfmadd_ss : GCCBuiltin<"__builtin_ia32_vfmaddss">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_sd : GCCBuiltin<"__builtin_ia32_vfmaddsd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_ps : GCCBuiltin<"__builtin_ia32_vfmaddps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_pd : GCCBuiltin<"__builtin_ia32_vfmaddpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfmaddps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfmaddpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_ss : GCCBuiltin<"__builtin_ia32_vfmsubss">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_sd : GCCBuiltin<"__builtin_ia32_vfmsubsd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_ps : GCCBuiltin<"__builtin_ia32_vfmsubps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_pd : GCCBuiltin<"__builtin_ia32_vfmsubpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfmsubps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfmsubpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_ss : GCCBuiltin<"__builtin_ia32_vfnmaddss">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_sd : GCCBuiltin<"__builtin_ia32_vfnmaddsd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_ps : GCCBuiltin<"__builtin_ia32_vfnmaddps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_pd : GCCBuiltin<"__builtin_ia32_vfnmaddpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmaddps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmaddpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfnmaddps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfnmaddpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_ss : GCCBuiltin<"__builtin_ia32_vfnmsubss">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_sd : GCCBuiltin<"__builtin_ia32_vfnmsubsd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_ps : GCCBuiltin<"__builtin_ia32_vfnmsubps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_pd : GCCBuiltin<"__builtin_ia32_vfnmsubpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmsubps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmsubpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfnmsubps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfnmsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfnmsubpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_ps_256 :
+               GCCBuiltin<"__builtin_ia32_vfmaddsubps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_pd_256 :
+              GCCBuiltin<"__builtin_ia32_vfmaddsubpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_ps_512 : GCCBuiltin<"__builtin_ia32_vfmaddsubps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmaddsub_pd_512 : GCCBuiltin<"__builtin_ia32_vfmaddsubpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_ps : GCCBuiltin<"__builtin_ia32_vfmsubaddps">,
+              Intrinsic<[llvm_v4f32_ty],
+                        [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_pd : GCCBuiltin<"__builtin_ia32_vfmsubaddpd">,
+              Intrinsic<[llvm_v2f64_ty],
+                        [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_ps_256 :
+              GCCBuiltin<"__builtin_ia32_vfmsubaddps256">,
+              Intrinsic<[llvm_v8f32_ty],
+                        [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_pd_256 :
+              GCCBuiltin<"__builtin_ia32_vfmsubaddpd256">,
+              Intrinsic<[llvm_v4f64_ty],
+                        [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_ps_512 : GCCBuiltin<"__builtin_ia32_vfmsubaddps512">,
+              Intrinsic<[llvm_v16f32_ty],
+                        [llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_fma_vfmsubadd_pd_512 : GCCBuiltin<"__builtin_ia32_vfmsubaddpd512">,
+              Intrinsic<[llvm_v8f64_ty],
+                        [llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+                        [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// XOP
+
+  def int_x86_xop_vpermil2pd : GCCBuiltin<"__builtin_ia32_vpermil2pd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+                                          llvm_v2f64_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vpermil2pd_256 :
+              GCCBuiltin<"__builtin_ia32_vpermil2pd256">,
+              Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+                                          llvm_v4f64_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vpermil2ps : GCCBuiltin<"__builtin_ia32_vpermil2ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+                                          llvm_v4f32_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpermil2ps_256 :
+              GCCBuiltin<"__builtin_ia32_vpermil2ps256">,
+              Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+                                          llvm_v8f32_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vfrcz_pd : GCCBuiltin<"__builtin_ia32_vfrczpd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_xop_vfrcz_ps : GCCBuiltin<"__builtin_ia32_vfrczps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_xop_vfrcz_sd : GCCBuiltin<"__builtin_ia32_vfrczsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_xop_vfrcz_ss : GCCBuiltin<"__builtin_ia32_vfrczss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_xop_vfrcz_pd_256 : GCCBuiltin<"__builtin_ia32_vfrczpd256">,
+              Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+  def int_x86_xop_vfrcz_ps_256 : GCCBuiltin<"__builtin_ia32_vfrczps256">,
+              Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+  def int_x86_xop_vpcmov :
+              GCCBuiltin<"__builtin_ia32_vpcmov">,
+              Intrinsic<[llvm_v2i64_ty],
+                        [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpcmov_256 :
+              GCCBuiltin<"__builtin_ia32_vpcmov_256">,
+              Intrinsic<[llvm_v4i64_ty],
+                        [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vpcomb : GCCBuiltin<"__builtin_ia32_vpcomb">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomw : GCCBuiltin<"__builtin_ia32_vpcomw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomd : GCCBuiltin<"__builtin_ia32_vpcomd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomq : GCCBuiltin<"__builtin_ia32_vpcomq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomub : GCCBuiltin<"__builtin_ia32_vpcomub">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomuw : GCCBuiltin<"__builtin_ia32_vpcomuw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomud : GCCBuiltin<"__builtin_ia32_vpcomud">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vpcomuq : GCCBuiltin<"__builtin_ia32_vpcomuq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+                         llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_xop_vphaddbd :
+              GCCBuiltin<"__builtin_ia32_vphaddbd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddbq :
+              GCCBuiltin<"__builtin_ia32_vphaddbq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddbw :
+              GCCBuiltin<"__builtin_ia32_vphaddbw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphadddq :
+              GCCBuiltin<"__builtin_ia32_vphadddq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddubd :
+              GCCBuiltin<"__builtin_ia32_vphaddubd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddubq :
+              GCCBuiltin<"__builtin_ia32_vphaddubq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddubw :
+              GCCBuiltin<"__builtin_ia32_vphaddubw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddudq :
+              GCCBuiltin<"__builtin_ia32_vphaddudq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_xop_vphadduwd :
+              GCCBuiltin<"__builtin_ia32_vphadduwd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_xop_vphadduwq :
+              GCCBuiltin<"__builtin_ia32_vphadduwq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddwd :
+              GCCBuiltin<"__builtin_ia32_vphaddwd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_xop_vphaddwq :
+              GCCBuiltin<"__builtin_ia32_vphaddwq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_xop_vphsubbw :
+              GCCBuiltin<"__builtin_ia32_vphsubbw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+  def int_x86_xop_vphsubdq :
+              GCCBuiltin<"__builtin_ia32_vphsubdq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_xop_vphsubwd :
+              GCCBuiltin<"__builtin_ia32_vphsubwd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_xop_vpmacsdd :
+              GCCBuiltin<"__builtin_ia32_vpmacsdd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacsdqh :
+              GCCBuiltin<"__builtin_ia32_vpmacsdqh">,
+              Intrinsic<[llvm_v2i64_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacsdql :
+              GCCBuiltin<"__builtin_ia32_vpmacsdql">,
+              Intrinsic<[llvm_v2i64_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacssdd :
+              GCCBuiltin<"__builtin_ia32_vpmacssdd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacssdqh :
+              GCCBuiltin<"__builtin_ia32_vpmacssdqh">,
+              Intrinsic<[llvm_v2i64_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacssdql :
+              GCCBuiltin<"__builtin_ia32_vpmacssdql">,
+              Intrinsic<[llvm_v2i64_ty],
+                        [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacsswd :
+              GCCBuiltin<"__builtin_ia32_vpmacsswd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacssww :
+              GCCBuiltin<"__builtin_ia32_vpmacssww">,
+              Intrinsic<[llvm_v8i16_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacswd :
+              GCCBuiltin<"__builtin_ia32_vpmacswd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmacsww :
+              GCCBuiltin<"__builtin_ia32_vpmacsww">,
+              Intrinsic<[llvm_v8i16_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmadcsswd :
+              GCCBuiltin<"__builtin_ia32_vpmadcsswd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpmadcswd :
+              GCCBuiltin<"__builtin_ia32_vpmadcswd">,
+              Intrinsic<[llvm_v4i32_ty],
+                        [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpperm :
+              GCCBuiltin<"__builtin_ia32_vpperm">,
+              Intrinsic<[llvm_v16i8_ty],
+                        [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vprotb : GCCBuiltin<"__builtin_ia32_vprotb">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotd : GCCBuiltin<"__builtin_ia32_vprotd">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotq : GCCBuiltin<"__builtin_ia32_vprotq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotw : GCCBuiltin<"__builtin_ia32_vprotw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotbi : GCCBuiltin<"__builtin_ia32_vprotbi">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotdi : GCCBuiltin<"__builtin_ia32_vprotdi">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotqi : GCCBuiltin<"__builtin_ia32_vprotqi">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vprotwi : GCCBuiltin<"__builtin_ia32_vprotwi">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i8_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_xop_vpshab :
+              GCCBuiltin<"__builtin_ia32_vpshab">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshad :
+              GCCBuiltin<"__builtin_ia32_vpshad">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshaq :
+              GCCBuiltin<"__builtin_ia32_vpshaq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshaw :
+              GCCBuiltin<"__builtin_ia32_vpshaw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshlb :
+              GCCBuiltin<"__builtin_ia32_vpshlb">,
+              Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshld :
+              GCCBuiltin<"__builtin_ia32_vpshld">,
+              Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshlq :
+              GCCBuiltin<"__builtin_ia32_vpshlq">,
+              Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+                        [IntrNoMem]>;
+  def int_x86_xop_vpshlw :
+              GCCBuiltin<"__builtin_ia32_vpshlw">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+                        [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// MMX
+
+// Empty MMX state op.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_emms  : GCCBuiltin<"__builtin_ia32_emms">,
+              Intrinsic<[], [], []>;
+  def int_x86_mmx_femms : GCCBuiltin<"__builtin_ia32_femms">,
+              Intrinsic<[], [], []>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  // Addition
+  def int_x86_mmx_padd_b : GCCBuiltin<"__builtin_ia32_paddb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_padd_w : GCCBuiltin<"__builtin_ia32_paddw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_padd_d : GCCBuiltin<"__builtin_ia32_paddd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_padd_q : GCCBuiltin<"__builtin_ia32_paddq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_mmx_padds_b : GCCBuiltin<"__builtin_ia32_paddsb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_padds_w : GCCBuiltin<"__builtin_ia32_paddsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  def int_x86_mmx_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  // Subtraction
+  def int_x86_mmx_psub_b : GCCBuiltin<"__builtin_ia32_psubb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_psub_w : GCCBuiltin<"__builtin_ia32_psubw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_psub_d : GCCBuiltin<"__builtin_ia32_psubd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_psub_q : GCCBuiltin<"__builtin_ia32_psubq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_mmx_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+
+  // Multiplication
+  def int_x86_mmx_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmull_w : GCCBuiltin<"__builtin_ia32_pmullw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  // Bitwise operations
+  def int_x86_mmx_pand : GCCBuiltin<"__builtin_ia32_pand">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_pandn : GCCBuiltin<"__builtin_ia32_pandn">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_por : GCCBuiltin<"__builtin_ia32_por">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_pxor : GCCBuiltin<"__builtin_ia32_pxor">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+
+  // Averages
+  def int_x86_mmx_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  // Maximum
+  def int_x86_mmx_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  // Minimum
+  def int_x86_mmx_pminu_b : GCCBuiltin<"__builtin_ia32_pminub">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  // Packed sum of absolute differences
+  def int_x86_mmx_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  // Shift left logical
+  def int_x86_mmx_psll_w : GCCBuiltin<"__builtin_ia32_psllw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psll_d : GCCBuiltin<"__builtin_ia32_pslld">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psll_q : GCCBuiltin<"__builtin_ia32_psllq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psrl_d : GCCBuiltin<"__builtin_ia32_psrld">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_psra_w : GCCBuiltin<"__builtin_ia32_psraw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_psra_d : GCCBuiltin<"__builtin_ia32_psrad">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_mmx_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_mmx_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_mmx_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_mmx_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_mmx_psrai_d : GCCBuiltin<"__builtin_ia32_psradi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Pack ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_packsswb : GCCBuiltin<"__builtin_ia32_packsswb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_packssdw : GCCBuiltin<"__builtin_ia32_packssdw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_packuswb : GCCBuiltin<"__builtin_ia32_packuswb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// Unpacking ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_punpckhbw : GCCBuiltin<"__builtin_ia32_punpckhbw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_punpckhwd : GCCBuiltin<"__builtin_ia32_punpckhwd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_punpckhdq : GCCBuiltin<"__builtin_ia32_punpckhdq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_punpcklbw : GCCBuiltin<"__builtin_ia32_punpcklbw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_punpcklwd : GCCBuiltin<"__builtin_ia32_punpcklwd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+  def int_x86_mmx_punpckldq : GCCBuiltin<"__builtin_ia32_punpckldq">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+                        [IntrNoMem]>;
+}
+
+// Integer comparison ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_pcmpeq_b : GCCBuiltin<"__builtin_ia32_pcmpeqb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pcmpeq_w : GCCBuiltin<"__builtin_ia32_pcmpeqw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+  def int_x86_mmx_pcmpeq_d : GCCBuiltin<"__builtin_ia32_pcmpeqd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+  def int_x86_mmx_pcmpgt_b : GCCBuiltin<"__builtin_ia32_pcmpgtb">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_pcmpgt_w : GCCBuiltin<"__builtin_ia32_pcmpgtw">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+  def int_x86_mmx_pcmpgt_d : GCCBuiltin<"__builtin_ia32_pcmpgtd">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                         llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_mmx_maskmovq : GCCBuiltin<"__builtin_ia32_maskmovq">,
+              Intrinsic<[], [llvm_x86mmx_ty, llvm_x86mmx_ty, llvm_ptr_ty], []>;
+
+  def int_x86_mmx_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb">,
+              Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_movnt_dq : GCCBuiltin<"__builtin_ia32_movntq">,
+              Intrinsic<[], [llvm_ptrx86mmx_ty, llvm_x86mmx_ty], []>;
+
+  def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                        llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">,
+              Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">,
+              Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+                        llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// BMI
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_bmi_bextr_32 : GCCBuiltin<"__builtin_ia32_bextr_u32">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_bmi_bextr_64 : GCCBuiltin<"__builtin_ia32_bextr_u64">,
+              Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+  def int_x86_bmi_bzhi_32 : GCCBuiltin<"__builtin_ia32_bzhi_si">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_bmi_bzhi_64 : GCCBuiltin<"__builtin_ia32_bzhi_di">,
+              Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+  def int_x86_bmi_pdep_32 : GCCBuiltin<"__builtin_ia32_pdep_si">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_bmi_pdep_64 : GCCBuiltin<"__builtin_ia32_pdep_di">,
+              Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+  def int_x86_bmi_pext_32 : GCCBuiltin<"__builtin_ia32_pext_si">,
+              Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_bmi_pext_64 : GCCBuiltin<"__builtin_ia32_pext_di">,
+              Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// FS/GS Base
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_rdfsbase_32 : GCCBuiltin<"__builtin_ia32_rdfsbase32">,
+              Intrinsic<[llvm_i32_ty], []>;
+  def int_x86_rdgsbase_32 : GCCBuiltin<"__builtin_ia32_rdgsbase32">,
+              Intrinsic<[llvm_i32_ty], []>;
+  def int_x86_rdfsbase_64 : GCCBuiltin<"__builtin_ia32_rdfsbase64">,
+              Intrinsic<[llvm_i64_ty], []>;
+  def int_x86_rdgsbase_64 : GCCBuiltin<"__builtin_ia32_rdgsbase64">,
+              Intrinsic<[llvm_i64_ty], []>;
+  def int_x86_wrfsbase_32 : GCCBuiltin<"__builtin_ia32_wrfsbase32">,
+              Intrinsic<[], [llvm_i32_ty]>;
+  def int_x86_wrgsbase_32 : GCCBuiltin<"__builtin_ia32_wrgsbase32">,
+              Intrinsic<[], [llvm_i32_ty]>;
+  def int_x86_wrfsbase_64 : GCCBuiltin<"__builtin_ia32_wrfsbase64">,
+              Intrinsic<[], [llvm_i64_ty]>;
+  def int_x86_wrgsbase_64 : GCCBuiltin<"__builtin_ia32_wrgsbase64">,
+              Intrinsic<[], [llvm_i64_ty]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Half float conversion
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_vcvtph2ps_128 : GCCBuiltin<"__builtin_ia32_vcvtph2ps">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_vcvtph2ps_256 : GCCBuiltin<"__builtin_ia32_vcvtph2ps256">,
+              Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+  def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">,
+              Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_mask_vcvtph2ps_512 : GCCBuiltin<"__builtin_ia32_vcvtph2ps512_mask">,
+              Intrinsic<[llvm_v16f32_ty], [llvm_v16i16_ty, llvm_v16f32_ty,
+                                           llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_vcvtps2ph_512 : GCCBuiltin<"__builtin_ia32_vcvtps2ph512_mask">,
+              Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty, llvm_i32_ty,
+                                           llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// TBM
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_tbm_bextri_u32 : GCCBuiltin<"__builtin_ia32_bextri_u32">,
+        Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_tbm_bextri_u64 : GCCBuiltin<"__builtin_ia32_bextri_u64">,
+        Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// RDRAND intrinsics - Return a random value and whether it is valid.
+// RDSEED intrinsics - Return a NIST SP800-90B & C compliant random value and
+// whether it is valid.
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  // These are declared side-effecting so they don't get eliminated by CSE or
+  // LICM.
+  def int_x86_rdrand_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>;
+  def int_x86_rdrand_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>;
+  def int_x86_rdrand_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
+  def int_x86_rdseed_16 : Intrinsic<[llvm_i16_ty, llvm_i32_ty], [], []>;
+  def int_x86_rdseed_32 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [], []>;
+  def int_x86_rdseed_64 : Intrinsic<[llvm_i64_ty, llvm_i32_ty], [], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// RTM intrinsics. Transactional Memory support.
+
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_xbegin : GCCBuiltin<"__builtin_ia32_xbegin">,
+              Intrinsic<[llvm_i32_ty], [], []>;
+  def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">,
+              Intrinsic<[], [], []>;
+  def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">,
+              Intrinsic<[], [llvm_i8_ty], [IntrNoReturn]>;
+  def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">,
+              Intrinsic<[llvm_i32_ty], [], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// AVX512
+
+// Mask ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  // Mask instructions
+  // 16-bit mask
+  def int_x86_avx512_kand_w : GCCBuiltin<"__builtin_ia32_kandhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_kandn_w : GCCBuiltin<"__builtin_ia32_kandnhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_knot_w : GCCBuiltin<"__builtin_ia32_knothi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_kor_w : GCCBuiltin<"__builtin_ia32_korhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_kxor_w : GCCBuiltin<"__builtin_ia32_kxorhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_kxnor_w : GCCBuiltin<"__builtin_ia32_kxnorhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_kunpck_bw : GCCBuiltin<"__builtin_ia32_kunpckhi">,
+              Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
+                         [IntrNoMem]>;
+  def int_x86_avx512_kortestz_w : GCCBuiltin<"__builtin_ia32_kortestzhi">,
+              Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_kortestc_w : GCCBuiltin<"__builtin_ia32_kortestchi">,
+              Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
+                        [IntrNoMem]>;
+}
+
+// Conversion ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_cvtss2usi : GCCBuiltin<"__builtin_ia32_cvtss2usi">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtss2usi64 : GCCBuiltin<"__builtin_ia32_cvtss2usi64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvttss2usi : GCCBuiltin<"__builtin_ia32_cvttss2usi">,
+              Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvttss2usi64 : GCCBuiltin<"__builtin_ia32_cvttss2usi64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtusi2ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtusi642ss : GCCBuiltin<"__builtin_ia32_cvtusi642ss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+                         llvm_i64_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_cvtsd2usi : GCCBuiltin<"__builtin_ia32_cvtsd2usi">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtsd2usi64 : GCCBuiltin<"__builtin_ia32_cvtsd2usi64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvttsd2usi : GCCBuiltin<"__builtin_ia32_cvttsd2usi">,
+              Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_cvttsd2usi64">,
+              Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtusi2sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_cvtusi642sd : GCCBuiltin<"__builtin_ia32_cvtusi642sd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+                         llvm_i64_ty], [IntrNoMem]>;
+}
+
+// Vector convert
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_mask_cvttps2dq_512: GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvttps2udq_512: GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvttpd2dq_512: GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+                                    llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvttpd2udq_512: GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+                                    llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_rndscale_ps_512: GCCBuiltin<"__builtin_ia32_rndscaleps_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_rndscale_pd_512: GCCBuiltin<"__builtin_ia32_rndscalepd_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty,
+                                     llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtps2dq_512: GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtpd2dq_512: GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+                                    llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtps2udq_512: GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">,
+        Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtpd2udq_512: GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">,
+        Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+                                    llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtdq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtdq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtdq2pd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtudq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtudq2ps512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty,
+                                     llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtudq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtudq2pd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cvtpd2ps_512 : GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">,
+        Intrinsic<[llvm_v8f32_ty], [llvm_v8f64_ty, llvm_v8f32_ty,
+                                    llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector load with broadcast
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_vbroadcast_ss_512 :
+        GCCBuiltin<"__builtin_ia32_vbroadcastss512">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_x86_avx512_vbroadcast_ss_ps_512 :
+              GCCBuiltin<"__builtin_ia32_vbroadcastss_ps512">,
+              Intrinsic<[llvm_v16f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_vbroadcast_sd_512 :
+        GCCBuiltin<"__builtin_ia32_vbroadcastsd512">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+  def int_x86_avx512_vbroadcast_sd_pd_512 :
+              GCCBuiltin<"__builtin_ia32_vbroadcastsd_pd512">,
+              Intrinsic<[llvm_v8f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_pbroadcastd_512 :
+         GCCBuiltin<"__builtin_ia32_pbroadcastd512">,
+         Intrinsic<[llvm_v16i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_pbroadcastd_i32_512 :
+         Intrinsic<[llvm_v16i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_pbroadcastq_512 :
+         GCCBuiltin<"__builtin_ia32_pbroadcastq512">,
+         Intrinsic<[llvm_v8i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+  def int_x86_avx512_pbroadcastq_i64_512 :
+         Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+}
+
+// Vector sign and zero extend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_pmovzxbq : GCCBuiltin<"__builtin_ia32_pmovzxbq512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_pmovzxwd : GCCBuiltin<"__builtin_ia32_pmovzxwd512">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_pmovzxbd : GCCBuiltin<"__builtin_ia32_pmovzxbd512">,
+              Intrinsic<[llvm_v16i32_ty], [llvm_v16i8_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_pmovzxwq : GCCBuiltin<"__builtin_ia32_pmovzxwq512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i16_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_pmovzxdq : GCCBuiltin<"__builtin_ia32_pmovzxdq512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i32_ty],
+                        [IntrNoMem]>;
+}
+
+// Arithmetic ops
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_mask_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512_mask">,
+          Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                     llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512_mask">,
+          Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                     llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512_mask">,
+          Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                     llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512_mask">,
+          Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                     llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_rndscale_ss        : GCCBuiltin<"__builtin_ia32_rndscaless">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_rndscale_sd        : GCCBuiltin<"__builtin_ia32_rndscalesd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_sqrt_ss        : GCCBuiltin<"__builtin_ia32_sqrtrndss">,
+              Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+                        [IntrNoMem]>;
+  def int_x86_avx512_sqrt_sd        : GCCBuiltin<"__builtin_ia32_sqrtrndsd">,
+              Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
+                        [IntrNoMem]>;
+
+  def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty], [IntrNoMem]>;
+  def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss_mask">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_rsqrt14_sd : GCCBuiltin<"__builtin_ia32_rsqrt14sd_mask">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_rsqrt14_pd_512 : GCCBuiltin<"__builtin_ia32_rsqrt14pd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_rsqrt14_ps_512 : GCCBuiltin<"__builtin_ia32_rsqrt14ps512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                                     llvm_i16_ty], [IntrNoMem]>;
+  def int_x86_avx512_rcp14_ss : GCCBuiltin<"__builtin_ia32_rcp14ss_mask">,
+        Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_rcp14_sd : GCCBuiltin<"__builtin_ia32_rcp14sd_mask">,
+        Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_rcp14_pd_512 : GCCBuiltin<"__builtin_ia32_rcp14pd512_mask">,
+        Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                                    llvm_i8_ty], [IntrNoMem]>;
+  def int_x86_avx512_rcp14_ps_512 : GCCBuiltin<"__builtin_ia32_rcp14ps512_mask">,
+        Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                                     llvm_i16_ty], [IntrNoMem]>;
+
+  def int_x86_avx512_rcp28_ps : GCCBuiltin<"__builtin_ia32_rcp28ps_mask">,
+            Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                                         llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_rcp28_pd : GCCBuiltin<"__builtin_ia32_rcp28pd_mask">,
+            Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                                        llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_mask">,
+            Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+                                        llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_mask">,
+            Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+                                        llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_rsqrt28_ps : GCCBuiltin<"__builtin_ia32_rsqrt28ps_mask">,
+            Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+                                         llvm_i16_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_rsqrt28_pd : GCCBuiltin<"__builtin_ia32_rsqrt28pd_mask">,
+            Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+                                        llvm_i8_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_mask">,
+            Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+                                        llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_mask">,
+            Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+                                        llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
+                      [IntrNoMem]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi512">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi512_byteshift">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi512_byteshift">,
+              Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                         llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Gather and Scatter ops
+let TargetPrefix = "x86" in {
+  def int_x86_avx512_gather_dpd_512  : GCCBuiltin<"__builtin_ia32_gathersiv8df">,
+          Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
+                     llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_dps_512  : GCCBuiltin<"__builtin_ia32_gathersiv16sf">,
+          Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty,
+                     llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_qpd_512  : GCCBuiltin<"__builtin_ia32_gatherdiv8df">,
+          Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
+                     llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_qps_512  : GCCBuiltin<"__builtin_ia32_gatherdiv16sf">,
+          Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty,
+                     llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+
+
+  def int_x86_avx512_gather_dpq_512  : GCCBuiltin<"__builtin_ia32_gathersiv8di">,
+          Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_dpi_512  : GCCBuiltin<"__builtin_ia32_gathersiv16si">,
+          Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty,
+                     llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_qpq_512  : GCCBuiltin<"__builtin_ia32_gatherdiv8di">,
+          Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+  def int_x86_avx512_gather_qpi_512  : GCCBuiltin<"__builtin_ia32_gatherdiv16si">,
+          Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty,
+                     llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
+                    [IntrReadArgMem]>;
+
+// scatter
+  def int_x86_avx512_scatter_dpd_512  : GCCBuiltin<"__builtin_ia32_scattersiv8df">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
+                        llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_dps_512  : GCCBuiltin<"__builtin_ia32_scattersiv16sf">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty,
+                       llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_qpd_512  : GCCBuiltin<"__builtin_ia32_scatterdiv8df">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
+                     llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_qps_512  : GCCBuiltin<"__builtin_ia32_scatterdiv16sf">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
+                     llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+
+
+  def int_x86_avx512_scatter_dpq_512  : GCCBuiltin<"__builtin_ia32_scattersiv8di">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
+                         llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_dpi_512  : GCCBuiltin<"__builtin_ia32_scattersiv16si">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty,
+                     llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_qpq_512  : GCCBuiltin<"__builtin_ia32_scatterdiv8di">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,llvm_v8i64_ty, llvm_v8i64_ty,
+                         llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatter_qpi_512  : GCCBuiltin<"__builtin_ia32_scatterdiv16si">,
+          Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8i32_ty, 
+                         llvm_i32_ty],
+                    [IntrReadWriteArgMem]>;
+
+  // gather prefetch
+  def int_x86_avx512_gatherpf_dpd_512  : GCCBuiltin<"__builtin_ia32_gatherpfdpd">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_gatherpf_dps_512  : GCCBuiltin<"__builtin_ia32_gatherpfdps">,
+          Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_gatherpf_qpd_512  : GCCBuiltin<"__builtin_ia32_gatherpfqpd">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_gatherpf_qps_512  : GCCBuiltin<"__builtin_ia32_gatherpfqps">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+
+  // scatter prefetch
+  def int_x86_avx512_scatterpf_dpd_512  : GCCBuiltin<"__builtin_ia32_scatterpfdpd">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatterpf_dps_512  : GCCBuiltin<"__builtin_ia32_scatterpfdps">,
+          Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatterpf_qpd_512  : GCCBuiltin<"__builtin_ia32_scatterpfqpd">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+  def int_x86_avx512_scatterpf_qps_512  : GCCBuiltin<"__builtin_ia32_scatterpfqps">,
+          Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
+                     llvm_i32_ty, llvm_i32_ty], [IntrReadWriteArgMem]>;
+}
+
+// AVX-512 conflict detection
+let TargetPrefix = "x86" in {
+  def int_x86_avx512_mask_conflict_d_512 :
+          GCCBuiltin<"__builtin_ia32_vpconflictsi_512_mask">,
+          Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
+                    llvm_v16i32_ty, llvm_i16_ty],
+                    []>;
+  def int_x86_avx512_mask_conflict_q_512 :
+          GCCBuiltin<"__builtin_ia32_vpconflictdi_512_mask">,
+          Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                    llvm_v8i64_ty, llvm_i8_ty],
+                    []>;
+  def int_x86_avx512_mask_lzcnt_d_512 :
+          GCCBuiltin<"__builtin_ia32_vplzcntd_512_mask">,
+          Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
+                    llvm_v16i32_ty, llvm_i16_ty],
+                    []>;
+  def int_x86_avx512_mask_lzcnt_q_512 :
+          GCCBuiltin<"__builtin_ia32_vplzcntq_512_mask">,
+          Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
+                    llvm_v8i64_ty, llvm_i8_ty],
+                    []>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
+  def int_x86_avx512_mask_blend_ps_512 : GCCBuiltin<"__builtin_ia32_blendmps_512_mask">,
+        Intrinsic<[llvm_v16f32_ty],
+                  [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty],
+                  [IntrNoMem]>;
+  def int_x86_avx512_mask_blend_pd_512 : GCCBuiltin<"__builtin_ia32_blendmpd_512_mask">,
+        Intrinsic<[llvm_v8f64_ty],
+                  [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty],
+                  [IntrNoMem]>;
+
+  def int_x86_avx512_mask_blend_d_512 : GCCBuiltin<"__builtin_ia32_blendmd_512_mask">,
+        Intrinsic<[llvm_v16i32_ty],
+                  [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
+                  [IntrNoMem]>;
+  def int_x86_avx512_mask_blend_q_512 : GCCBuiltin<"__builtin_ia32_blendmq_512_mask">,
+        Intrinsic<[llvm_v8i64_ty],
+                  [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
+                  [IntrNoMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in {
+  def int_x86_avx512_mask_cmp_ps_512 : GCCBuiltin<"__builtin_ia32_cmpps512_mask">,
+            Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty,
+                                      llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+  def int_x86_avx512_mask_cmp_pd_512 : GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
+            Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty,
+                                      llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+  
+  def int_x86_avx512_mask_pcmpeq_d_512 : GCCBuiltin<"__builtin_ia32_pcmpeqd512_mask">,
+            Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_mask_pcmpeq_q_512 : GCCBuiltin<"__builtin_ia32_pcmpeqq512_mask">,
+            Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
+            Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+                                         llvm_v16i32_ty, llvm_i16_ty],
+                      [IntrNoMem]>;
+  def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
+            Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+                                        llvm_v8i64_ty, llvm_i8_ty],
+                      [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SHA intrinsics
+let TargetPrefix = "x86" in {
+  def int_x86_sha1rnds4 : GCCBuiltin<"__builtin_ia32_sha1rnds4">,
+        Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
+                  [IntrNoMem]>;
+  def int_x86_sha1nexte : GCCBuiltin<"__builtin_ia32_sha1nexte">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sha1msg1 : GCCBuiltin<"__builtin_ia32_sha1msg1">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sha1msg2 : GCCBuiltin<"__builtin_ia32_sha1msg2">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sha256rnds2 : GCCBuiltin<"__builtin_ia32_sha256rnds2">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+                [IntrNoMem]>;
+  def int_x86_sha256msg1 : GCCBuiltin<"__builtin_ia32_sha256msg1">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+  def int_x86_sha256msg2 : GCCBuiltin<"__builtin_ia32_sha256msg2">,
+      Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsXCore.td b/include/llvm/IR/IntrinsicsXCore.td
new file mode 100644
index 0000000..b614e1e
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsXCore.td
@@ -0,0 +1,121 @@
+//==- IntrinsicsXCore.td - XCore intrinsics                 -*- tablegen -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the XCore-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "xcore" in {  // All intrinsics start with "llvm.xcore.".
+  // Miscellaneous instructions.
+  def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>,
+                         GCCBuiltin<"__builtin_bitrev">;
+  def int_xcore_crc8 : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+                                 [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+                                 [IntrNoMem]>;
+  def int_xcore_crc32 : Intrinsic<[llvm_i32_ty],
+                                  [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+                                  [IntrNoMem]>;
+  def int_xcore_sext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                                 [IntrNoMem]>;
+  def int_xcore_zext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+                                 [IntrNoMem]>;
+  def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>,
+                        GCCBuiltin<"__builtin_getid">;
+  def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>,
+                        GCCBuiltin<"__builtin_getps">;
+  def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>,
+                        GCCBuiltin<"__builtin_setps">;
+  def int_xcore_geted : Intrinsic<[llvm_i32_ty],[]>;
+  def int_xcore_getet : Intrinsic<[llvm_i32_ty],[]>;
+  def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>;
+  def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>;
+
+  // Resource instructions.
+  def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>;
+  def int_xcore_freer : Intrinsic<[],[llvm_anyptr_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_in : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],[NoCapture<0>]>;
+  def int_xcore_int : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                [NoCapture<0>]>;
+  def int_xcore_inct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                 [NoCapture<0>]>;
+  def int_xcore_out : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                [NoCapture<0>]>;
+  def int_xcore_outt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                 [NoCapture<0>]>;
+  def int_xcore_outct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_chkct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_testct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_testwct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_setd : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_setc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_inshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_outshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_setpt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_clrpt : Intrinsic<[],[llvm_anyptr_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_getts : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_syncr : Intrinsic<[],[llvm_anyptr_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_settw : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                 [NoCapture<0>]>;
+  def int_xcore_setev : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                  [NoCapture<0>]>;
+  def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_edu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
+                                   [NoCapture<0>, NoCapture<1>]>;
+  def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
+                                   [NoCapture<0>, NoCapture<1>]>;
+  def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_peek : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                 [NoCapture<0>]>;
+  def int_xcore_endin : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+                                 [NoCapture<0>]>;
+
+  // Intrinsics for events.
+  def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>;
+
+  // If any of the resources owned by the thread are ready this returns the
+  // vector of one of the ready resources. If no resources owned by the thread
+  // are ready then the operand passed to the intrinsic is returned.
+  def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>;
+
+  def int_xcore_clre : Intrinsic<[],[],[]>;
+
+  // Intrinsics for threads.
+  def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
+                                   [NoCapture<0>]>;
+  def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_ssync : Intrinsic <[],[]>;
+  def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+  def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+  def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+                                    [NoCapture<0>]>;
+}
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
new file mode 100644
index 0000000..4d940d5
--- /dev/null
+++ b/include/llvm/IR/LLVMContext.h
@@ -0,0 +1,194 @@
+//===-- llvm/LLVMContext.h - Class for managing "global" state --*- 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 LLVMContext, a container of "global" state in LLVM, such
+// as the global type and constant uniquing tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LLVMCONTEXT_H
+#define LLVM_IR_LLVMCONTEXT_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class LLVMContextImpl;
+class StringRef;
+class Twine;
+class Instruction;
+class Module;
+class SMDiagnostic;
+class DiagnosticInfo;
+template <typename T> class SmallVectorImpl;
+class Function;
+class DebugLoc;
+
+/// This is an important class for using LLVM in a threaded context.  It
+/// (opaquely) owns and manages the core "global" data of LLVM's core
+/// infrastructure, including the type and constant uniquing tables.
+/// LLVMContext itself provides no locking guarantees, so you should be careful
+/// to have one context per thread.
+class LLVMContext {
+public:
+  LLVMContextImpl *const pImpl;
+  LLVMContext();
+  ~LLVMContext();
+
+  // Pinned metadata names, which always have the same value.  This is a
+  // compile-time performance optimization, not a correctness optimization.
+  enum {
+    MD_dbg = 0,  // "dbg"
+    MD_tbaa = 1, // "tbaa"
+    MD_prof = 2,  // "prof"
+    MD_fpmath = 3,  // "fpmath"
+    MD_range = 4, // "range"
+    MD_tbaa_struct = 5, // "tbaa.struct"
+    MD_invariant_load = 6 // "invariant.load"
+  };
+
+  /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
+  /// This ID is uniqued across modules in the current LLVMContext.
+  unsigned getMDKindID(StringRef Name) const;
+
+  /// getMDKindNames - Populate client supplied SmallVector with the name for
+  /// custom metadata IDs registered in this LLVMContext.
+  void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
+
+
+  typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
+                                         unsigned LocCookie);
+
+  /// Defines the type of a diagnostic handler.
+  /// \see LLVMContext::setDiagnosticHandler.
+  /// \see LLVMContext::diagnose.
+  typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
+
+  /// Defines the type of a yield callback.
+  /// \see LLVMContext::setYieldCallback.
+  typedef void (*YieldCallbackTy)(LLVMContext *Context, void *OpaqueHandle);
+
+  /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
+  /// when problems with inline asm are detected by the backend.  The first
+  /// argument is a function pointer and the second is a context pointer that
+  /// gets passed into the DiagHandler.
+  ///
+  /// LLVMContext doesn't take ownership or interpret either of these
+  /// pointers.
+  void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
+                                     void *DiagContext = nullptr);
+
+  /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
+  /// setInlineAsmDiagnosticHandler.
+  InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
+
+  /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
+  /// setInlineAsmDiagnosticHandler.
+  void *getInlineAsmDiagnosticContext() const;
+
+  /// setDiagnosticHandler - This method sets a handler that is invoked
+  /// when the backend needs to report anything to the user.  The first
+  /// argument is a function pointer and the second is a context pointer that
+  /// gets passed into the DiagHandler.
+  ///
+  /// LLVMContext doesn't take ownership or interpret either of these
+  /// pointers.
+  void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,
+                            void *DiagContext = nullptr);
+
+  /// getDiagnosticHandler - Return the diagnostic handler set by
+  /// setDiagnosticHandler.
+  DiagnosticHandlerTy getDiagnosticHandler() const;
+
+  /// getDiagnosticContext - Return the diagnostic context set by
+  /// setDiagnosticContext.
+  void *getDiagnosticContext() const;
+
+  /// diagnose - Report a message to the currently installed diagnostic handler.
+  /// This function returns, in particular in the case of error reporting
+  /// (DI.Severity == RS_Error), so the caller should leave the compilation
+  /// process in a self-consistent state, even though the generated code
+  /// need not be correct.
+  /// The diagnostic message will be implicitly prefixed with a severity
+  /// keyword according to \p DI.getSeverity(), i.e., "error: "
+  /// for RS_Error, "warning: " for RS_Warning, and "note: " for RS_Note.
+  void diagnose(const DiagnosticInfo &DI);
+
+  /// \brief Registers a yield callback with the given context.
+  ///
+  /// The yield callback function may be called by LLVM to transfer control back
+  /// to the client that invoked the LLVM compilation. This can be used to yield
+  /// control of the thread, or perform periodic work needed by the client.
+  /// There is no guaranteed frequency at which callbacks must occur; in fact,
+  /// the client is not guaranteed to ever receive this callback. It is at the
+  /// sole discretion of LLVM to do so and only if it can guarantee that
+  /// suspending the thread won't block any forward progress in other LLVM
+  /// contexts in the same process.
+  ///
+  /// At a suspend point, the state of the current LLVM context is intentionally
+  /// undefined. No assumptions about it can or should be made. Only LLVM
+  /// context API calls that explicitly state that they can be used during a
+  /// yield callback are allowed to be used. Any other API calls into the
+  /// context are not supported until the yield callback function returns
+  /// control to LLVM. Other LLVM contexts are unaffected by this restriction.
+  void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle);
+
+  /// \brief Calls the yield callback (if applicable).
+  ///
+  /// This transfers control of the current thread back to the client, which may
+  /// suspend the current thread. Only call this method when LLVM doesn't hold
+  /// any global mutex or cannot block the execution in another LLVM context.
+  void yield();
+
+  /// emitError - Emit an error message to the currently installed error handler
+  /// with optional location information.  This function returns, so code should
+  /// be prepared to drop the erroneous construct on the floor and "not crash".
+  /// The generated code need not be correct.  The error message will be
+  /// implicitly prefixed with "error: " and should not end with a ".".
+  void emitError(unsigned LocCookie, const Twine &ErrorStr);
+  void emitError(const Instruction *I, const Twine &ErrorStr);
+  void emitError(const Twine &ErrorStr);
+
+private:
+  LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
+  void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
+
+  /// addModule - Register a module as being instantiated in this context.  If
+  /// the context is deleted, the module will be deleted as well.
+  void addModule(Module*);
+
+  /// removeModule - Unregister a module from this context.
+  void removeModule(Module*);
+
+  // Module needs access to the add/removeModule methods.
+  friend class Module;
+};
+
+/// getGlobalContext - Returns a global context.  This is for LLVM clients that
+/// only care about operating on a single thread.
+extern LLVMContext &getGlobalContext();
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef)
+
+/* Specialized opaque context conversions.
+ */
+inline LLVMContext **unwrap(LLVMContextRef* Tys) {
+  return reinterpret_cast<LLVMContext**>(Tys);
+}
+
+inline LLVMContextRef *wrap(const LLVMContext **Tys) {
+  return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
+}
+
+}
+
+#endif
diff --git a/include/llvm/IR/LeakDetector.h b/include/llvm/IR/LeakDetector.h
new file mode 100644
index 0000000..cb18df8
--- /dev/null
+++ b/include/llvm/IR/LeakDetector.h
@@ -0,0 +1,92 @@
+//===- LeakDetector.h - Provide leak detection ------------------*- 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 class that can be used to provide very simple memory leak
+// checks for an API.  Basically LLVM uses this to make sure that Instructions,
+// for example, are deleted when they are supposed to be, and not leaked away.
+//
+// When compiling with NDEBUG (Release build), this class does nothing, thus
+// adding no checking overhead to release builds.  Note that this class is
+// implemented in a very simple way, requiring completely manual manipulation
+// and checking for garbage, but this is intentional: users should not be using
+// this API, only other APIs should.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LEAKDETECTOR_H
+#define LLVM_IR_LEAKDETECTOR_H
+
+#include <string>
+
+namespace llvm {
+
+class LLVMContext;
+class Value;
+
+struct LeakDetector {
+  /// addGarbageObject - Add a pointer to the internal set of "garbage" object
+  /// pointers.  This should be called when objects are created, or if they are
+  /// taken out of an owning collection.
+  ///
+  static void addGarbageObject(void *Object) {
+#ifndef NDEBUG
+    addGarbageObjectImpl(Object);
+#endif
+  }
+
+  /// removeGarbageObject - Remove a pointer from our internal representation of
+  /// our "garbage" objects.  This should be called when an object is added to
+  /// an "owning" collection.
+  ///
+  static void removeGarbageObject(void *Object) {
+#ifndef NDEBUG
+    removeGarbageObjectImpl(Object);
+#endif
+  }
+
+  /// checkForGarbage - Traverse the internal representation of garbage
+  /// pointers.  If there are any pointers that have been add'ed, but not
+  /// remove'd, big obnoxious warnings about memory leaks are issued.
+  ///
+  /// The specified message will be printed indicating when the check was
+  /// performed.
+  ///
+  static void checkForGarbage(LLVMContext &C, const std::string &Message) {
+#ifndef NDEBUG
+    checkForGarbageImpl(C, Message);
+#endif
+  }
+
+  /// Overload the normal methods to work better with Value*'s because they are
+  /// by far the most common in LLVM.  This does not affect the actual
+  /// functioning of this class, it just makes the warning messages nicer.
+  ///
+  static void addGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+    addGarbageObjectImpl(Object);
+#endif
+  }
+  static void removeGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+    removeGarbageObjectImpl(Object);
+#endif
+  }
+
+private:
+  // If we are debugging, the actual implementations will be called...
+  static void addGarbageObjectImpl(const Value *Object);
+  static void removeGarbageObjectImpl(const Value *Object);
+  static void addGarbageObjectImpl(void *Object);
+  static void removeGarbageObjectImpl(void *Object);
+  static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h
new file mode 100644
index 0000000..c967a6b
--- /dev/null
+++ b/include/llvm/IR/LegacyPassManager.h
@@ -0,0 +1,111 @@
+//===- LegacyPassManager.h - Legacy Container for Passes --------*- 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 legacy PassManager class.  This class is used to hold,
+// maintain, and optimize execution of Passes.  The PassManager class ensures
+// that analysis results are available before a pass runs, and that Pass's are
+// destroyed when the PassManager is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LEGACYPASSMANAGER_H
+#define LLVM_IR_LEGACYPASSMANAGER_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/CBindingWrapping.h"
+
+namespace llvm {
+
+class Pass;
+class Module;
+
+namespace legacy {
+
+class PassManagerImpl;
+class FunctionPassManagerImpl;
+
+/// PassManagerBase - An abstract interface to allow code to add passes to
+/// a pass manager without having to hard-code what kind of pass manager
+/// it is.
+class PassManagerBase {
+public:
+  virtual ~PassManagerBase();
+
+  /// add - Add a pass to the queue of passes to run.  This passes ownership of
+  /// the Pass to the PassManager.  When the PassManager is destroyed, the pass
+  /// will be destroyed as well, so there is no need to delete the pass.  This
+  /// implies that all passes MUST be allocated with 'new'.
+  virtual void add(Pass *P) = 0;
+};
+
+/// PassManager manages ModulePassManagers
+class PassManager : public PassManagerBase {
+public:
+
+  PassManager();
+  ~PassManager();
+
+  /// add - Add a pass to the queue of passes to run.  This passes ownership of
+  /// the Pass to the PassManager.  When the PassManager is destroyed, the pass
+  /// will be destroyed as well, so there is no need to delete the pass.  This
+  /// implies that all passes MUST be allocated with 'new'.
+  void add(Pass *P) override;
+
+  /// run - Execute all of the passes scheduled for execution.  Keep track of
+  /// whether any of the passes modifies the module, and if so, return true.
+  bool run(Module &M);
+
+private:
+  /// PassManagerImpl_New is the actual class. PassManager is just the
+  /// wraper to publish simple pass manager interface
+  PassManagerImpl *PM;
+};
+
+/// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
+class FunctionPassManager : public PassManagerBase {
+public:
+  /// FunctionPassManager ctor - This initializes the pass manager.  It needs,
+  /// but does not take ownership of, the specified Module.
+  explicit FunctionPassManager(Module *M);
+  ~FunctionPassManager();
+
+  /// add - Add a pass to the queue of passes to run.  This passes
+  /// ownership of the Pass to the PassManager.  When the
+  /// PassManager_X is destroyed, the pass will be destroyed as well, so
+  /// there is no need to delete the pass.
+  /// This implies that all passes MUST be allocated with 'new'.
+  void add(Pass *P) override;
+
+  /// run - Execute all of the passes scheduled for execution.  Keep
+  /// track of whether any of the passes modifies the function, and if
+  /// so, return true.
+  ///
+  bool run(Function &F);
+
+  /// doInitialization - Run all of the initializers for the function passes.
+  ///
+  bool doInitialization();
+
+  /// doFinalization - Run all of the finalizers for the function passes.
+  ///
+  bool doFinalization();
+
+private:
+  FunctionPassManagerImpl *FPM;
+  Module *M;
+};
+
+} // End legacy namespace
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h
new file mode 100644
index 0000000..f6065a4
--- /dev/null
+++ b/include/llvm/IR/LegacyPassManagers.h
@@ -0,0 +1,470 @@
+//===- LegacyPassManagers.h - Legacy Pass Infrastructure --------*- 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 LLVM Pass Manager infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGERS_H
+#define LLVM_PASSMANAGERS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Pass.h"
+#include <map>
+#include <vector>
+
+//===----------------------------------------------------------------------===//
+// Overview:
+// The Pass Manager Infrastructure manages passes. It's responsibilities are:
+//
+//   o Manage optimization pass execution order
+//   o Make required Analysis information available before pass P is run
+//   o Release memory occupied by dead passes
+//   o If Analysis information is dirtied by a pass then regenerate Analysis
+//     information before it is consumed by another pass.
+//
+// Pass Manager Infrastructure uses multiple pass managers.  They are
+// PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager.
+// This class hierarchy uses multiple inheritance but pass managers do not
+// derive from another pass manager.
+//
+// PassManager and FunctionPassManager are two top-level pass manager that
+// represents the external interface of this entire pass manager infrastucture.
+//
+// Important classes :
+//
+// [o] class PMTopLevelManager;
+//
+// Two top level managers, PassManager and FunctionPassManager, derive from
+// PMTopLevelManager. PMTopLevelManager manages information used by top level
+// managers such as last user info.
+//
+// [o] class PMDataManager;
+//
+// PMDataManager manages information, e.g. list of available analysis info,
+// used by a pass manager to manage execution order of passes. It also provides
+// a place to implement common pass manager APIs. All pass managers derive from
+// PMDataManager.
+//
+// [o] class BBPassManager : public FunctionPass, public PMDataManager;
+//
+// BBPassManager manages BasicBlockPasses.
+//
+// [o] class FunctionPassManager;
+//
+// This is a external interface used by JIT to manage FunctionPasses. This
+// interface relies on FunctionPassManagerImpl to do all the tasks.
+//
+// [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager,
+//                                     public PMTopLevelManager;
+//
+// FunctionPassManagerImpl is a top level manager. It manages FPPassManagers
+//
+// [o] class FPPassManager : public ModulePass, public PMDataManager;
+//
+// FPPassManager manages FunctionPasses and BBPassManagers
+//
+// [o] class MPPassManager : public Pass, public PMDataManager;
+//
+// MPPassManager manages ModulePasses and FPPassManagers
+//
+// [o] class PassManager;
+//
+// This is a external interface used by various tools to manages passes. It
+// relies on PassManagerImpl to do all the tasks.
+//
+// [o] class PassManagerImpl : public Pass, public PMDataManager,
+//                             public PMTopLevelManager
+//
+// PassManagerImpl is a top level pass manager responsible for managing
+// MPPassManagers.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace llvm {
+  class Module;
+  class Pass;
+  class StringRef;
+  class Value;
+  class Timer;
+  class PMDataManager;
+
+// enums for debugging strings
+enum PassDebuggingString {
+  EXECUTION_MSG, // "Executing Pass '" + PassName
+  MODIFICATION_MSG, // "Made Modification '" + PassName
+  FREEING_MSG, // " Freeing Pass '" + PassName
+  ON_BASICBLOCK_MSG, // "' on BasicBlock '" + InstructionName + "'...\n"
+  ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n"
+  ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n"
+  ON_REGION_MSG, // "' on Region '" + Msg + "'...\n'"
+  ON_LOOP_MSG, // "' on Loop '" + Msg + "'...\n'"
+  ON_CG_MSG // "' on Call Graph Nodes '" + Msg + "'...\n'"
+};
+
+/// PassManagerPrettyStackEntry - This is used to print informative information
+/// about what pass is running when/if a stack trace is generated.
+class PassManagerPrettyStackEntry : public PrettyStackTraceEntry {
+  Pass *P;
+  Value *V;
+  Module *M;
+public:
+  explicit PassManagerPrettyStackEntry(Pass *p)
+    : P(p), V(nullptr), M(nullptr) {}  // When P is releaseMemory'd.
+  PassManagerPrettyStackEntry(Pass *p, Value &v)
+    : P(p), V(&v), M(nullptr) {} // When P is run on V
+  PassManagerPrettyStackEntry(Pass *p, Module &m)
+    : P(p), V(nullptr), M(&m) {} // When P is run on M
+
+  /// print - Emit information about this stack frame to OS.
+  void print(raw_ostream &OS) const override;
+};
+
+
+//===----------------------------------------------------------------------===//
+// PMStack
+//
+/// PMStack - This class implements a stack data structure of PMDataManager
+/// pointers.
+///
+/// Top level pass managers (see PassManager.cpp) maintain active Pass Managers
+/// using PMStack. Each Pass implements assignPassManager() to connect itself
+/// with appropriate manager. assignPassManager() walks PMStack to find
+/// suitable manager.
+class PMStack {
+public:
+  typedef std::vector<PMDataManager *>::const_reverse_iterator iterator;
+  iterator begin() const { return S.rbegin(); }
+  iterator end() const { return S.rend(); }
+
+  void pop();
+  PMDataManager *top() const { return S.back(); }
+  void push(PMDataManager *PM);
+  bool empty() const { return S.empty(); }
+
+  void dump() const;
+
+private:
+  std::vector<PMDataManager *> S;
+};
+
+
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager
+//
+/// PMTopLevelManager manages LastUser info and collects common APIs used by
+/// top level pass managers.
+class PMTopLevelManager {
+protected:
+  explicit PMTopLevelManager(PMDataManager *PMDM);
+
+  unsigned getNumContainedManagers() const {
+    return (unsigned)PassManagers.size();
+  }
+
+  void initializeAllAnalysisInfo();
+
+private:
+  virtual PMDataManager *getAsPMDataManager() = 0;
+  virtual PassManagerType getTopLevelPassManagerType() = 0;
+
+public:
+  /// Schedule pass P for execution. Make sure that passes required by
+  /// P are run before P is run. Update analysis info maintained by
+  /// the manager. Remove dead passes. This is a recursive function.
+  void schedulePass(Pass *P);
+
+  /// Set pass P as the last user of the given analysis passes.
+  void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P);
+
+  /// Collect passes whose last user is P
+  void collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P);
+
+  /// Find the pass that implements Analysis AID. Search immutable
+  /// passes and all pass managers. If desired pass is not found
+  /// then return NULL.
+  Pass *findAnalysisPass(AnalysisID AID);
+
+  /// Find analysis usage information for the pass P.
+  AnalysisUsage *findAnalysisUsage(Pass *P);
+
+  virtual ~PMTopLevelManager();
+
+  /// Add immutable pass and initialize it.
+  inline void addImmutablePass(ImmutablePass *P) {
+    P->initializePass();
+    ImmutablePasses.push_back(P);
+  }
+
+  inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() {
+    return ImmutablePasses;
+  }
+
+  void addPassManager(PMDataManager *Manager) {
+    PassManagers.push_back(Manager);
+  }
+
+  // Add Manager into the list of managers that are not directly
+  // maintained by this top level pass manager
+  inline void addIndirectPassManager(PMDataManager *Manager) {
+    IndirectPassManagers.push_back(Manager);
+  }
+
+  // Print passes managed by this top level manager.
+  void dumpPasses() const;
+  void dumpArguments() const;
+
+  // Active Pass Managers
+  PMStack activeStack;
+
+protected:
+
+  /// Collection of pass managers
+  SmallVector<PMDataManager *, 8> PassManagers;
+
+private:
+
+  /// Collection of pass managers that are not directly maintained
+  /// by this pass manager
+  SmallVector<PMDataManager *, 8> IndirectPassManagers;
+
+  // Map to keep track of last user of the analysis pass.
+  // LastUser->second is the last user of Lastuser->first.
+  DenseMap<Pass *, Pass *> LastUser;
+
+  // Map to keep track of passes that are last used by a pass.
+  // This inverse map is initialized at PM->run() based on
+  // LastUser map.
+  DenseMap<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser;
+
+  /// Immutable passes are managed by top level manager.
+  SmallVector<ImmutablePass *, 8> ImmutablePasses;
+
+  DenseMap<Pass *, AnalysisUsage *> AnUsageMap;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// PMDataManager
+
+/// PMDataManager provides the common place to manage the analysis data
+/// used by pass managers.
+class PMDataManager {
+public:
+
+  explicit PMDataManager() : TPM(nullptr), Depth(0) {
+    initializeAnalysisInfo();
+  }
+
+  virtual ~PMDataManager();
+
+  virtual Pass *getAsPass() = 0;
+
+  /// Augment AvailableAnalysis by adding analysis made available by pass P.
+  void recordAvailableAnalysis(Pass *P);
+
+  /// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
+  void verifyPreservedAnalysis(Pass *P);
+
+  /// Remove Analysis that is not preserved by the pass
+  void removeNotPreservedAnalysis(Pass *P);
+
+  /// Remove dead passes used by P.
+  void removeDeadPasses(Pass *P, StringRef Msg,
+                        enum PassDebuggingString);
+
+  /// Remove P.
+  void freePass(Pass *P, StringRef Msg,
+                enum PassDebuggingString);
+
+  /// Add pass P into the PassVector. Update
+  /// AvailableAnalysis appropriately if ProcessAnalysis is true.
+  void add(Pass *P, bool ProcessAnalysis = true);
+
+  /// Add RequiredPass into list of lower level passes required by pass P.
+  /// RequiredPass is run on the fly by Pass Manager when P requests it
+  /// through getAnalysis interface.
+  virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
+
+  virtual Pass *getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F);
+
+  /// Initialize available analysis information.
+  void initializeAnalysisInfo() {
+    AvailableAnalysis.clear();
+    for (unsigned i = 0; i < PMT_Last; ++i)
+      InheritedAnalysis[i] = nullptr;
+  }
+
+  // Return true if P preserves high level analysis used by other
+  // passes that are managed by this manager.
+  bool preserveHigherLevelAnalysis(Pass *P);
+
+
+  /// Populate RequiredPasses with analysis pass that are required by
+  /// pass P and are available. Populate ReqPassNotAvailable with analysis
+  /// pass that are required by pass P but are not available.
+  void collectRequiredAnalysis(SmallVectorImpl<Pass *> &RequiredPasses,
+                               SmallVectorImpl<AnalysisID> &ReqPassNotAvailable,
+                               Pass *P);
+
+  /// All Required analyses should be available to the pass as it runs!  Here
+  /// we fill in the AnalysisImpls member of the pass so that it can
+  /// successfully use the getAnalysis() method to retrieve the
+  /// implementations it needs.
+  void initializeAnalysisImpl(Pass *P);
+
+  /// Find the pass that implements Analysis AID. If desired pass is not found
+  /// then return NULL.
+  Pass *findAnalysisPass(AnalysisID AID, bool Direction);
+
+  // Access toplevel manager
+  PMTopLevelManager *getTopLevelManager() { return TPM; }
+  void setTopLevelManager(PMTopLevelManager *T) { TPM = T; }
+
+  unsigned getDepth() const { return Depth; }
+  void setDepth(unsigned newDepth) { Depth = newDepth; }
+
+  // Print routines used by debug-pass
+  void dumpLastUses(Pass *P, unsigned Offset) const;
+  void dumpPassArguments() const;
+  void dumpPassInfo(Pass *P, enum PassDebuggingString S1,
+                    enum PassDebuggingString S2, StringRef Msg);
+  void dumpRequiredSet(const Pass *P) const;
+  void dumpPreservedSet(const Pass *P) const;
+
+  unsigned getNumContainedPasses() const {
+    return (unsigned)PassVector.size();
+  }
+
+  virtual PassManagerType getPassManagerType() const {
+    assert ( 0 && "Invalid use of getPassManagerType");
+    return PMT_Unknown;
+  }
+
+  DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() {
+    return &AvailableAnalysis;
+  }
+
+  // Collect AvailableAnalysis from all the active Pass Managers.
+  void populateInheritedAnalysis(PMStack &PMS) {
+    unsigned Index = 0;
+    for (PMStack::iterator I = PMS.begin(), E = PMS.end();
+         I != E; ++I)
+      InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis();
+  }
+
+protected:
+
+  // Top level manager.
+  PMTopLevelManager *TPM;
+
+  // Collection of pass that are managed by this manager
+  SmallVector<Pass *, 16> PassVector;
+
+  // Collection of Analysis provided by Parent pass manager and
+  // used by current pass manager. At at time there can not be more
+  // then PMT_Last active pass mangers.
+  DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
+
+  /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
+  /// or higher is specified.
+  bool isPassDebuggingExecutionsOrMore() const;
+
+private:
+  void dumpAnalysisUsage(StringRef Msg, const Pass *P,
+                         const AnalysisUsage::VectorType &Set) const;
+
+  // Set of available Analysis. This information is used while scheduling
+  // pass. If a pass requires an analysis which is not available then
+  // the required analysis pass is scheduled to run before the pass itself is
+  // scheduled to run.
+  DenseMap<AnalysisID, Pass*> AvailableAnalysis;
+
+  // Collection of higher level analysis used by the pass managed by
+  // this manager.
+  SmallVector<Pass *, 8> HigherLevelAnalysis;
+
+  unsigned Depth;
+};
+
+//===----------------------------------------------------------------------===//
+// FPPassManager
+//
+/// FPPassManager manages BBPassManagers and FunctionPasses.
+/// It batches all function passes and basic block pass managers together and
+/// sequence them to process one function at a time before processing next
+/// function.
+class FPPassManager : public ModulePass, public PMDataManager {
+public:
+  static char ID;
+  explicit FPPassManager()
+  : ModulePass(ID), PMDataManager() { }
+
+  /// run - Execute all of the passes scheduled for execution.  Keep track of
+  /// whether any of the passes modifies the module, and if so, return true.
+  bool runOnFunction(Function &F);
+  bool runOnModule(Module &M) override;
+
+  /// cleanup - After running all passes, clean up pass manager cache.
+  void cleanup();
+
+  /// doInitialization - Overrides ModulePass doInitialization for global
+  /// initialization tasks
+  ///
+  using ModulePass::doInitialization;
+
+  /// doInitialization - Run all of the initializers for the function passes.
+  ///
+  bool doInitialization(Module &M) override;
+
+  /// doFinalization - Overrides ModulePass doFinalization for global
+  /// finalization tasks
+  /// 
+  using ModulePass::doFinalization;
+  
+  /// doFinalization - Run all of the finalizers for the function passes.
+  ///
+  bool doFinalization(Module &M) override;
+
+  PMDataManager *getAsPMDataManager() override { return this; }
+  Pass *getAsPass() override { return this; }
+
+  /// Pass Manager itself does not invalidate any analysis info.
+  void getAnalysisUsage(AnalysisUsage &Info) const override {
+    Info.setPreservesAll();
+  }
+
+  // Print passes managed by this manager
+  void dumpPassStructure(unsigned Offset) override;
+
+  const char *getPassName() const override {
+    return "Function Pass Manager";
+  }
+
+  FunctionPass *getContainedPass(unsigned N) {
+    assert ( N < PassVector.size() && "Pass number out of range!");
+    FunctionPass *FP = static_cast<FunctionPass *>(PassVector[N]);
+    return FP;
+  }
+
+  PassManagerType getPassManagerType() const override {
+    return PMT_FunctionPassManager;
+  }
+};
+
+Timer *getPassTimer(Pass *);
+
+}
+
+#endif
diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h
new file mode 100644
index 0000000..e2e4912
--- /dev/null
+++ b/include/llvm/IR/LegacyPassNameParser.h
@@ -0,0 +1,141 @@
+//===- LegacyPassNameParser.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PassNameParser and FilteredPassNameParser<> classes,
+// which are used to add command line arguments to a utility for all of the
+// passes that have been registered into the system.
+//
+// The PassNameParser class adds ALL passes linked into the system (that are
+// creatable) as command line arguments to the tool (when instantiated with the
+// appropriate command line option template).  The FilteredPassNameParser<>
+// template is used for the same purposes as PassNameParser, except that it only
+// includes passes that have a PassType that are compatible with the filter
+// (which is the template argument).
+//
+// Note that this is part of the legacy pass manager infrastructure and will be
+// (eventually) going away.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LEGACYPASSNAMEPARSER_H
+#define LLVM_IR_LEGACYPASSNAMEPARSER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// PassNameParser class - Make use of the pass registration mechanism to
+// automatically add a command line argument to opt for each pass.
+//
+class PassNameParser : public PassRegistrationListener,
+                       public cl::parser<const PassInfo*> {
+  cl::Option *Opt;
+public:
+  PassNameParser();
+  virtual ~PassNameParser();
+
+  void initialize(cl::Option &O) {
+    Opt = &O;
+    cl::parser<const PassInfo*>::initialize(O);
+
+    // Add all of the passes to the map that got initialized before 'this' did.
+    enumeratePasses();
+  }
+
+  // ignorablePassImpl - Can be overriden in subclasses to refine the list of
+  // which passes we want to include.
+  //
+  virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
+
+  inline bool ignorablePass(const PassInfo *P) const {
+    // Ignore non-selectable and non-constructible passes!  Ignore
+    // non-optimizations.
+    return P->getPassArgument() == nullptr || *P->getPassArgument() == 0 ||
+           P->getNormalCtor() == nullptr || ignorablePassImpl(P);
+  }
+
+  // Implement the PassRegistrationListener callbacks used to populate our map
+  //
+  void passRegistered(const PassInfo *P) override {
+    if (ignorablePass(P) || !Opt) return;
+    if (findOption(P->getPassArgument()) != getNumOptions()) {
+      errs() << "Two passes with the same argument (-"
+           << P->getPassArgument() << ") attempted to be registered!\n";
+      llvm_unreachable(nullptr);
+    }
+    addLiteralOption(P->getPassArgument(), P, P->getPassName());
+  }
+  void passEnumerate(const PassInfo *P) override { passRegistered(P); }
+
+  // printOptionInfo - Print out information about this option.  Override the
+  // default implementation to sort the table before we print...
+  void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override {
+    PassNameParser *PNP = const_cast<PassNameParser*>(this);
+    array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+    cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
+  }
+
+private:
+  // ValLessThan - Provide a sorting comparator for Values elements...
+  static int ValLessThan(const PassNameParser::OptionInfo *VT1,
+                         const PassNameParser::OptionInfo *VT2) {
+    return std::strcmp(VT1->Name, VT2->Name);
+  }
+};
+
+///===----------------------------------------------------------------------===//
+/// FilteredPassNameParser class - Make use of the pass registration
+/// mechanism to automatically add a command line argument to opt for
+/// each pass that satisfies a filter criteria.  Filter should return
+/// true for passes to be registered as command-line options.
+///
+template<typename Filter>
+class FilteredPassNameParser : public PassNameParser {
+private:
+  Filter filter;
+
+public:
+  bool ignorablePassImpl(const PassInfo *P) const override {
+    return !filter(*P);
+  }
+};
+
+///===----------------------------------------------------------------------===//
+/// PassArgFilter - A filter for use with PassNameFilterParser that only
+/// accepts a Pass whose Arg matches certain strings.
+///
+/// Use like this:
+///
+/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
+///
+/// static cl::list<
+///   const PassInfo*,
+///   bool,
+///   FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
+/// PassList(cl::desc("Passes available:"));
+///
+/// Only the -anders_aa and -dse options will be available to the user.
+///
+template<const char *Args>
+class PassArgFilter {
+public:
+  bool operator()(const PassInfo &P) const {
+    return(std::strstr(Args, P.getPassArgument()));
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
new file mode 100644
index 0000000..37d263b
--- /dev/null
+++ b/include/llvm/IR/MDBuilder.h
@@ -0,0 +1,115 @@
+//===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- 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 MDBuilder class, which is used as a convenient way to
+// create LLVM metadata with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_MDBUILDER_H
+#define LLVM_IR_MDBUILDER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <utility>
+
+namespace llvm {
+
+class APInt;
+template <typename T> class ArrayRef;
+class LLVMContext;
+class MDNode;
+class MDString;
+class StringRef;
+
+class MDBuilder {
+  LLVMContext &Context;
+
+public:
+  MDBuilder(LLVMContext &context) : Context(context) {}
+
+  /// \brief Return the given string as metadata.
+  MDString *createString(StringRef Str);
+
+  //===------------------------------------------------------------------===//
+  // FPMath metadata.
+  //===------------------------------------------------------------------===//
+
+  /// \brief Return metadata with the given settings.  The special value 0.0
+  /// for the Accuracy parameter indicates the default (maximal precision)
+  /// setting.
+  MDNode *createFPMath(float Accuracy);
+
+  //===------------------------------------------------------------------===//
+  // Prof metadata.
+  //===------------------------------------------------------------------===//
+
+  /// \brief Return metadata containing two branch weights.
+  MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight);
+
+  /// \brief Return metadata containing a number of branch weights.
+  MDNode *createBranchWeights(ArrayRef<uint32_t> Weights);
+
+  //===------------------------------------------------------------------===//
+  // Range metadata.
+  //===------------------------------------------------------------------===//
+
+  /// \brief Return metadata describing the range [Lo, Hi).
+  MDNode *createRange(const APInt &Lo, const APInt &Hi);
+
+  //===------------------------------------------------------------------===//
+  // TBAA metadata.
+  //===------------------------------------------------------------------===//
+
+  /// \brief Return metadata appropriate for a TBAA root node.  Each returned
+  /// node is distinct from all other metadata and will never be identified
+  /// (uniqued) with anything else.
+  MDNode *createAnonymousTBAARoot();
+
+  /// \brief Return metadata appropriate for a TBAA root node with the given
+  /// name.  This may be identified (uniqued) with other roots with the same
+  /// name.
+  MDNode *createTBAARoot(StringRef Name);
+
+  /// \brief Return metadata for a non-root TBAA node with the given name,
+  /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
+  MDNode *createTBAANode(StringRef Name, MDNode *Parent,
+                         bool isConstant = false);
+
+  struct TBAAStructField {
+    uint64_t Offset;
+    uint64_t Size;
+    MDNode *TBAA;
+    TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) :
+      Offset(Offset), Size(Size), TBAA(TBAA) {}
+  };
+
+  /// \brief Return metadata for a tbaa.struct node with the given
+  /// struct field descriptions.
+  MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields);
+
+  /// \brief Return metadata for a TBAA struct node in the type DAG
+  /// with the given name, a list of pairs (offset, field type in the type DAG).
+  MDNode *
+  createTBAAStructTypeNode(StringRef Name,
+                           ArrayRef<std::pair<MDNode *, uint64_t>> Fields);
+
+  /// \brief Return metadata for a TBAA scalar type node with the
+  /// given name, an offset and a parent in the TBAA type DAG.
+  MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
+                                   uint64_t Offset = 0);
+
+  /// \brief Return metadata for a TBAA tag node with the given
+  /// base type, access type and offset relative to the base type.
+  MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
+                                  uint64_t Offset);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/Mangler.h b/include/llvm/IR/Mangler.h
new file mode 100644
index 0000000..c1ba585
--- /dev/null
+++ b/include/llvm/IR/Mangler.h
@@ -0,0 +1,69 @@
+//===-- llvm/IR/Mangler.h - Self-contained name mangler ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_MANGLER_H
+#define LLVM_TARGET_MANGLER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class DataLayout;
+class GlobalValue;
+template <typename T> class SmallVectorImpl;
+class Twine;
+
+class Mangler {
+public:
+  enum ManglerPrefixTy {
+    Default,               ///< Emit default string before each symbol.
+    Private,               ///< Emit "private" prefix before each symbol.
+    LinkerPrivate          ///< Emit "linker private" prefix before each symbol.
+  };
+
+private:
+  const DataLayout *DL;
+
+  /// AnonGlobalIDs - We need to give global values the same name every time
+  /// they are mangled.  This keeps track of the number we give to anonymous
+  /// ones.
+  ///
+  mutable DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
+
+  /// NextAnonGlobalID - This simple counter is used to unique value names.
+  ///
+  mutable unsigned NextAnonGlobalID;
+
+public:
+  Mangler(const DataLayout *DL) : DL(DL), NextAnonGlobalID(1) {}
+
+  /// Print the appropriate prefix and the specified global variable's name.
+  /// If the global variable doesn't have a name, this fills in a unique name
+  /// for the global.
+  void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
+                         bool CannotUsePrivateLabel) const;
+  void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
+                         bool CannotUsePrivateLabel) const;
+
+  /// Print the appropriate prefix and the specified name as the global variable
+  /// name. GVName must not be empty.
+  void getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
+                         ManglerPrefixTy PrefixTy = Mangler::Default) const;
+  void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
+                         ManglerPrefixTy PrefixTy = Mangler::Default) const;
+};
+
+} // End llvm namespace
+
+#endif // LLVM_TARGET_MANGLER_H
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
new file mode 100644
index 0000000..7a0ca88
--- /dev/null
+++ b/include/llvm/IR/Metadata.h
@@ -0,0 +1,301 @@
+//===-- llvm/Metadata.h - Metadata definitions ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// This file contains the declarations for metadata subclasses.
+/// They represent the different flavors of metadata that live in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_METADATA_H
+#define LLVM_IR_METADATA_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+class LLVMContext;
+class Module;
+template<typename ValueSubClass, typename ItemParentClass>
+  class SymbolTableListTraits;
+
+
+enum LLVMConstants : uint32_t {
+  DEBUG_METADATA_VERSION = 1  // Current debug info version number.
+};
+
+//===----------------------------------------------------------------------===//
+/// MDString - a single uniqued string.
+/// These are used to efficiently contain a byte sequence for metadata.
+/// MDString is always unnamed.
+class MDString : public Value {
+  virtual void anchor();
+  MDString(const MDString &) LLVM_DELETED_FUNCTION;
+
+  explicit MDString(LLVMContext &C);
+public:
+  static MDString *get(LLVMContext &Context, StringRef Str);
+  static MDString *get(LLVMContext &Context, const char *Str) {
+    return get(Context, Str ? StringRef(Str) : StringRef());
+  }
+
+  StringRef getString() const { return getName(); }
+
+  unsigned getLength() const { return (unsigned)getName().size(); }
+
+  typedef StringRef::iterator iterator;
+
+  /// begin() - Pointer to the first byte of the string.
+  iterator begin() const { return getName().begin(); }
+
+  /// end() - Pointer to one byte past the end of the string.
+  iterator end() const { return getName().end(); }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == MDStringVal;
+  }
+};
+
+
+class MDNodeOperand;
+
+//===----------------------------------------------------------------------===//
+/// MDNode - a tuple of other values.
+class MDNode : public Value, public FoldingSetNode {
+  MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
+  void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
+  friend class MDNodeOperand;
+  friend class LLVMContextImpl;
+  friend struct FoldingSetTrait<MDNode>;
+
+  /// Hash - If the MDNode is uniqued cache the hash to speed up lookup.
+  unsigned Hash;
+
+  /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the
+  /// end of this MDNode.
+  unsigned NumOperands;
+
+  // Subclass data enums.
+  enum {
+    /// FunctionLocalBit - This bit is set if this MDNode is function local.
+    /// This is true when it (potentially transitively) contains a reference to
+    /// something in a function, like an argument, basicblock, or instruction.
+    FunctionLocalBit = 1 << 0,
+
+    /// NotUniquedBit - This is set on MDNodes that are not uniqued because they
+    /// have a null operand.
+    NotUniquedBit    = 1 << 1,
+
+    /// DestroyFlag - This bit is set by destroy() so the destructor can assert
+    /// that the node isn't being destroyed with a plain 'delete'.
+    DestroyFlag      = 1 << 2
+  };
+
+  // FunctionLocal enums.
+  enum FunctionLocalness {
+    FL_Unknown = -1,
+    FL_No = 0,
+    FL_Yes = 1
+  };
+
+  /// replaceOperand - Replace each instance of F from the operand list of this
+  /// node with T.
+  void replaceOperand(MDNodeOperand *Op, Value *NewVal);
+  ~MDNode();
+
+  MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);
+
+  static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
+                           FunctionLocalness FL, bool Insert = true);
+public:
+  // Constructors and destructors.
+  static MDNode *get(LLVMContext &Context, ArrayRef<Value*> Vals);
+  // getWhenValsUnresolved - Construct MDNode determining function-localness
+  // from isFunctionLocal argument, not by analyzing Vals.
+  static MDNode *getWhenValsUnresolved(LLVMContext &Context,
+                                       ArrayRef<Value*> Vals,
+                                       bool isFunctionLocal);
+
+  static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals);
+
+  /// getTemporary - Return a temporary MDNode, for use in constructing
+  /// cyclic MDNode structures. A temporary MDNode is not uniqued,
+  /// may be RAUW'd, and must be manually deleted with deleteTemporary.
+  static MDNode *getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals);
+
+  /// deleteTemporary - Deallocate a node created by getTemporary. The
+  /// node must not have any users.
+  static void deleteTemporary(MDNode *N);
+
+  /// replaceOperandWith - Replace a specific operand.
+  void replaceOperandWith(unsigned i, Value *NewVal);
+
+  /// getOperand - Return specified operand.
+  Value *getOperand(unsigned i) const LLVM_READONLY;
+
+  /// getNumOperands - Return number of MDNode operands.
+  unsigned getNumOperands() const { return NumOperands; }
+
+  /// isFunctionLocal - Return whether MDNode is local to a function.
+  bool isFunctionLocal() const {
+    return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
+  }
+
+  // getFunction - If this metadata is function-local and recursively has a
+  // function-local operand, return the first such operand's parent function.
+  // Otherwise, return null. getFunction() should not be used for performance-
+  // critical code because it recursively visits all the MDNode's operands.
+  const Function *getFunction() const;
+
+  /// Profile - calculate a unique identifier for this MDNode to collapse
+  /// duplicates
+  void Profile(FoldingSetNodeID &ID) const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  static bool classof(const Value *V) {
+    return V->getValueID() == MDNodeVal;
+  }
+
+  /// Check whether MDNode is a vtable access.
+  bool isTBAAVtableAccess() const;
+
+  /// Methods for metadata merging.
+  static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
+  static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
+  static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
+private:
+  // destroy - Delete this node.  Only when there are no uses.
+  void destroy();
+
+  bool isNotUniqued() const {
+    return (getSubclassDataFromValue() & NotUniquedBit) != 0;
+  }
+  void setIsNotUniqued();
+
+  // Shadow Value::setValueSubclassData with a private forwarding method so that
+  // any future subclasses cannot accidentally use it.
+  void setValueSubclassData(unsigned short D) {
+    Value::setValueSubclassData(D);
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// NamedMDNode - a tuple of MDNodes. Despite its name, a NamedMDNode isn't
+/// itself an MDNode. NamedMDNodes belong to modules, have names, and contain
+/// lists of MDNodes.
+class NamedMDNode : public ilist_node<NamedMDNode> {
+  friend class SymbolTableListTraits<NamedMDNode, Module>;
+  friend struct ilist_traits<NamedMDNode>;
+  friend class LLVMContextImpl;
+  friend class Module;
+  NamedMDNode(const NamedMDNode &) LLVM_DELETED_FUNCTION;
+
+  std::string Name;
+  Module *Parent;
+  void *Operands; // SmallVector<TrackingVH<MDNode>, 4>
+
+  void setParent(Module *M) { Parent = M; }
+
+  explicit NamedMDNode(const Twine &N);
+
+  template<class T1, class T2>
+  class op_iterator_impl :
+      public std::iterator<std::bidirectional_iterator_tag, T2> {
+    const NamedMDNode *Node;
+    unsigned Idx;
+    op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) { }
+
+    friend class NamedMDNode;
+
+  public:
+    op_iterator_impl() : Node(nullptr), Idx(0) { }
+
+    bool operator==(const op_iterator_impl &o) const { return Idx == o.Idx; }
+    bool operator!=(const op_iterator_impl &o) const { return Idx != o.Idx; }
+    op_iterator_impl &operator++() {
+      ++Idx;
+      return *this;
+    }
+    op_iterator_impl operator++(int) {
+      op_iterator_impl tmp(*this);
+      operator++();
+      return tmp;
+    }
+    op_iterator_impl &operator--() {
+      --Idx;
+      return *this;
+    }
+    op_iterator_impl operator--(int) {
+      op_iterator_impl tmp(*this);
+      operator--();
+      return tmp;
+    }
+
+    T1 operator*() const { return Node->getOperand(Idx); }
+  };
+
+public:
+  /// eraseFromParent - Drop all references and remove the node from parent
+  /// module.
+  void eraseFromParent();
+
+  /// dropAllReferences - Remove all uses and clear node vector.
+  void dropAllReferences();
+
+  /// ~NamedMDNode - Destroy NamedMDNode.
+  ~NamedMDNode();
+
+  /// getParent - Get the module that holds this named metadata collection.
+  inline Module *getParent() { return Parent; }
+  inline const Module *getParent() const { return Parent; }
+
+  /// getOperand - Return specified operand.
+  MDNode *getOperand(unsigned i) const;
+
+  /// getNumOperands - Return the number of NamedMDNode operands.
+  unsigned getNumOperands() const;
+
+  /// addOperand - Add metadata operand.
+  void addOperand(MDNode *M);
+
+  /// getName - Return a constant reference to this named metadata's name.
+  StringRef getName() const;
+
+  /// print - Implement operator<< on NamedMDNode.
+  void print(raw_ostream &ROS) const;
+
+  /// dump() - Allow printing of NamedMDNodes from the debugger.
+  void dump() const;
+
+  // ---------------------------------------------------------------------------
+  // Operand Iterator interface...
+  //
+  typedef op_iterator_impl<MDNode*, MDNode> op_iterator;
+  op_iterator op_begin() { return op_iterator(this, 0); }
+  op_iterator op_end()   { return op_iterator(this, getNumOperands()); }
+
+  typedef op_iterator_impl<const MDNode*, MDNode> const_op_iterator;
+  const_op_iterator op_begin() const { return const_op_iterator(this, 0); }
+  const_op_iterator op_end()   const { return const_op_iterator(this, getNumOperands()); }
+
+  inline iterator_range<op_iterator>  operands() {
+    return iterator_range<op_iterator>(op_begin(), op_end());
+  }
+  inline iterator_range<const_op_iterator> operands() const {
+    return iterator_range<const_op_iterator>(op_begin(), op_end());
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
new file mode 100644
index 0000000..26f62db
--- /dev/null
+++ b/include/llvm/IR/Module.h
@@ -0,0 +1,643 @@
+//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// Module.h This file contains the declarations for the Module class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_MODULE_H
+#define LLVM_IR_MODULE_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Comdat.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/DataTypes.h"
+#include <system_error>
+
+namespace llvm {
+class FunctionType;
+class GVMaterializer;
+class LLVMContext;
+class RandomNumberGenerator;
+class StructType;
+template<typename T> struct DenseMapInfo;
+template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap;
+
+template<> struct ilist_traits<Function>
+  : public SymbolTableListTraits<Function, Module> {
+
+  // createSentinel is used to get hold of the node that marks the end of the
+  // list... (same trick used here as in ilist_traits<Instruction>)
+  Function *createSentinel() const {
+    return static_cast<Function*>(&Sentinel);
+  }
+  static void destroySentinel(Function*) {}
+
+  Function *provideInitialHead() const { return createSentinel(); }
+  Function *ensureHead(Function*) const { return createSentinel(); }
+  static void noteHead(Function*, Function*) {}
+
+private:
+  mutable ilist_node<Function> Sentinel;
+};
+
+template<> struct ilist_traits<GlobalVariable>
+  : public SymbolTableListTraits<GlobalVariable, Module> {
+  // createSentinel is used to create a node that marks the end of the list.
+  GlobalVariable *createSentinel() const {
+    return static_cast<GlobalVariable*>(&Sentinel);
+  }
+  static void destroySentinel(GlobalVariable*) {}
+
+  GlobalVariable *provideInitialHead() const { return createSentinel(); }
+  GlobalVariable *ensureHead(GlobalVariable*) const { return createSentinel(); }
+  static void noteHead(GlobalVariable*, GlobalVariable*) {}
+private:
+  mutable ilist_node<GlobalVariable> Sentinel;
+};
+
+template<> struct ilist_traits<GlobalAlias>
+  : public SymbolTableListTraits<GlobalAlias, Module> {
+  // createSentinel is used to create a node that marks the end of the list.
+  GlobalAlias *createSentinel() const {
+    return static_cast<GlobalAlias*>(&Sentinel);
+  }
+  static void destroySentinel(GlobalAlias*) {}
+
+  GlobalAlias *provideInitialHead() const { return createSentinel(); }
+  GlobalAlias *ensureHead(GlobalAlias*) const { return createSentinel(); }
+  static void noteHead(GlobalAlias*, GlobalAlias*) {}
+private:
+  mutable ilist_node<GlobalAlias> Sentinel;
+};
+
+template<> struct ilist_traits<NamedMDNode>
+  : public ilist_default_traits<NamedMDNode> {
+  // createSentinel is used to get hold of a node that marks the end of
+  // the list...
+  NamedMDNode *createSentinel() const {
+    return static_cast<NamedMDNode*>(&Sentinel);
+  }
+  static void destroySentinel(NamedMDNode*) {}
+
+  NamedMDNode *provideInitialHead() const { return createSentinel(); }
+  NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
+  static void noteHead(NamedMDNode*, NamedMDNode*) {}
+  void addNodeToList(NamedMDNode *) {}
+  void removeNodeFromList(NamedMDNode *) {}
+private:
+  mutable ilist_node<NamedMDNode> Sentinel;
+};
+
+/// A Module instance is used to store all the information related to an
+/// LLVM module. Modules are the top level container of all other LLVM
+/// Intermediate Representation (IR) objects. Each module directly contains a
+/// list of globals variables, a list of functions, a list of libraries (or
+/// other modules) this module depends on, a symbol table, and various data
+/// about the target's characteristics.
+///
+/// A module maintains a GlobalValRefMap object that is used to hold all
+/// constant references to global variables in the module.  When a global
+/// variable is destroyed, it should have no entries in the GlobalValueRefMap.
+/// @brief The main container class for the LLVM Intermediate Representation.
+class Module {
+/// @name Types And Enumerations
+/// @{
+public:
+  /// The type for the list of global variables.
+  typedef iplist<GlobalVariable> GlobalListType;
+  /// The type for the list of functions.
+  typedef iplist<Function> FunctionListType;
+  /// The type for the list of aliases.
+  typedef iplist<GlobalAlias> AliasListType;
+  /// The type for the list of named metadata.
+  typedef ilist<NamedMDNode> NamedMDListType;
+  /// The type of the comdat "symbol" table.
+  typedef StringMap<Comdat> ComdatSymTabType;
+
+  /// The Global Variable iterator.
+  typedef GlobalListType::iterator                      global_iterator;
+  /// The Global Variable constant iterator.
+  typedef GlobalListType::const_iterator          const_global_iterator;
+
+  /// The Function iterators.
+  typedef FunctionListType::iterator                           iterator;
+  /// The Function constant iterator
+  typedef FunctionListType::const_iterator               const_iterator;
+
+  /// The Global Alias iterators.
+  typedef AliasListType::iterator                        alias_iterator;
+  /// The Global Alias constant iterator
+  typedef AliasListType::const_iterator            const_alias_iterator;
+
+  /// The named metadata iterators.
+  typedef NamedMDListType::iterator             named_metadata_iterator;
+  /// The named metadata constant interators.
+  typedef NamedMDListType::const_iterator const_named_metadata_iterator;
+
+  /// This enumeration defines the supported behaviors of module flags.
+  enum ModFlagBehavior {
+    /// Emits an error if two values disagree, otherwise the resulting value is
+    /// that of the operands.
+    Error = 1,
+
+    /// Emits a warning if two values disagree. The result value will be the
+    /// operand for the flag from the first module being linked.
+    Warning = 2,
+
+    /// Adds a requirement that another module flag be present and have a
+    /// specified value after linking is performed. The value must be a metadata
+    /// pair, where the first element of the pair is the ID of the module flag
+    /// to be restricted, and the second element of the pair is the value the
+    /// module flag should be restricted to. This behavior can be used to
+    /// restrict the allowable results (via triggering of an error) of linking
+    /// IDs with the **Override** behavior.
+    Require = 3,
+
+    /// Uses the specified value, regardless of the behavior or value of the
+    /// other module. If both modules specify **Override**, but the values
+    /// differ, an error will be emitted.
+    Override = 4,
+
+    /// Appends the two values, which are required to be metadata nodes.
+    Append = 5,
+
+    /// Appends the two values, which are required to be metadata
+    /// nodes. However, duplicate entries in the second list are dropped
+    /// during the append operation.
+    AppendUnique = 6
+  };
+
+  struct ModuleFlagEntry {
+    ModFlagBehavior Behavior;
+    MDString *Key;
+    Value *Val;
+    ModuleFlagEntry(ModFlagBehavior B, MDString *K, Value *V)
+      : Behavior(B), Key(K), Val(V) {}
+  };
+
+/// @}
+/// @name Member Variables
+/// @{
+private:
+  LLVMContext &Context;           ///< The LLVMContext from which types and
+                                  ///< constants are allocated.
+  GlobalListType GlobalList;      ///< The Global Variables in the module
+  FunctionListType FunctionList;  ///< The Functions in the module
+  AliasListType AliasList;        ///< The Aliases in the module
+  NamedMDListType NamedMDList;    ///< The named metadata in the module
+  std::string GlobalScopeAsm;     ///< Inline Asm at global scope.
+  ValueSymbolTable *ValSymTab;    ///< Symbol table for values
+  ComdatSymTabType ComdatSymTab;  ///< Symbol table for COMDATs
+  std::unique_ptr<GVMaterializer>
+  Materializer;                   ///< Used to materialize GlobalValues
+  std::string ModuleID;           ///< Human readable identifier for the module
+  std::string TargetTriple;       ///< Platform target triple Module compiled on
+  void *NamedMDSymTab;            ///< NamedMDNode names.
+  // Allow lazy initialization in const method.
+  mutable RandomNumberGenerator *RNG; ///< The random number generator for this module.
+
+  // We need to keep the string because the C API expects us to own the string
+  // representation.
+  // Since we have it, we also use an empty string to represent a module without
+  // a DataLayout. If it has a DataLayout, these variables are in sync and the
+  // string is just a cache of getDataLayout()->getStringRepresentation().
+  std::string DataLayoutStr;
+  DataLayout DL;
+
+  friend class Constant;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+  /// The Module constructor. Note that there is no default constructor. You
+  /// must provide a name for the module upon construction.
+  explicit Module(StringRef ModuleID, LLVMContext& C);
+  /// The module destructor. This will dropAllReferences.
+  ~Module();
+
+/// @}
+/// @name Module Level Accessors
+/// @{
+
+  /// Get the module identifier which is, essentially, the name of the module.
+  /// @returns the module identifier as a string
+  const std::string &getModuleIdentifier() const { return ModuleID; }
+
+  /// Get the data layout string for the module's target platform. This is
+  /// equivalent to getDataLayout()->getStringRepresentation().
+  const std::string &getDataLayoutStr() const { return DataLayoutStr; }
+
+  /// Get the data layout for the module's target platform.
+  const DataLayout *getDataLayout() const;
+
+  /// Get the target triple which is a string describing the target host.
+  /// @returns a string containing the target triple.
+  const std::string &getTargetTriple() const { return TargetTriple; }
+
+  /// Get the global data context.
+  /// @returns LLVMContext - a container for LLVM's global information
+  LLVMContext &getContext() const { return Context; }
+
+  /// Get any module-scope inline assembly blocks.
+  /// @returns a string containing the module-scope inline assembly blocks.
+  const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }
+
+  /// Get the RandomNumberGenerator for this module. The RNG can be
+  /// seeded via -rng-seed=<uint64> and is salted with the ModuleID.
+  /// The returned RNG should not be shared across threads.
+  RandomNumberGenerator &getRNG() const;
+
+/// @}
+/// @name Module Level Mutators
+/// @{
+
+  /// Set the module identifier.
+  void setModuleIdentifier(StringRef ID) { ModuleID = ID; }
+
+  /// Set the data layout
+  void setDataLayout(StringRef Desc);
+  void setDataLayout(const DataLayout *Other);
+
+  /// Set the target triple.
+  void setTargetTriple(StringRef T) { TargetTriple = T; }
+
+  /// Set the module-scope inline assembly blocks.
+  void setModuleInlineAsm(StringRef Asm) {
+    GlobalScopeAsm = Asm;
+    if (!GlobalScopeAsm.empty() &&
+        GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+      GlobalScopeAsm += '\n';
+  }
+
+  /// Append to the module-scope inline assembly blocks, automatically inserting
+  /// a separating newline if necessary.
+  void appendModuleInlineAsm(StringRef Asm) {
+    GlobalScopeAsm += Asm;
+    if (!GlobalScopeAsm.empty() &&
+        GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+      GlobalScopeAsm += '\n';
+  }
+
+/// @}
+/// @name Generic Value Accessors
+/// @{
+
+  /// Return the global value in the module with the specified name, of
+  /// arbitrary type. This method returns null if a global with the specified
+  /// name is not found.
+  GlobalValue *getNamedValue(StringRef Name) const;
+
+  /// Return a unique non-zero ID for the specified metadata kind. This ID is
+  /// uniqued across modules in the current LLVMContext.
+  unsigned getMDKindID(StringRef Name) const;
+
+  /// Populate client supplied SmallVector with the name for custom metadata IDs
+  /// registered in this LLVMContext.
+  void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
+
+  /// Return the type with the specified name, or null if there is none by that
+  /// name.
+  StructType *getTypeByName(StringRef Name) const;
+
+/// @}
+/// @name Function Accessors
+/// @{
+
+  /// Look up the specified function in the module symbol table. Four
+  /// possibilities:
+  ///   1. If it does not exist, add a prototype for the function and return it.
+  ///   2. If it exists, and has a local linkage, the existing function is
+  ///      renamed and a new one is inserted.
+  ///   3. Otherwise, if the existing function has the correct prototype, return
+  ///      the existing function.
+  ///   4. Finally, the function exists but has the wrong prototype: return the
+  ///      function with a constantexpr cast to the right prototype.
+  Constant *getOrInsertFunction(StringRef Name, FunctionType *T,
+                                AttributeSet AttributeList);
+
+  Constant *getOrInsertFunction(StringRef Name, FunctionType *T);
+
+  /// Look up the specified function in the module symbol table. If it does not
+  /// exist, add a prototype for the function and return it. This function
+  /// guarantees to return a constant of pointer to the specified function type
+  /// or a ConstantExpr BitCast of that type if the named function has a
+  /// different type. This version of the method takes a null terminated list of
+  /// function arguments, which makes it easier for clients to use.
+  Constant *getOrInsertFunction(StringRef Name,
+                                AttributeSet AttributeList,
+                                Type *RetTy, ...)  END_WITH_NULL;
+
+  /// Same as above, but without the attributes.
+  Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...)
+    END_WITH_NULL;
+
+  /// Look up the specified function in the module symbol table. If it does not
+  /// exist, return null.
+  Function *getFunction(StringRef Name) const;
+
+/// @}
+/// @name Global Variable Accessors
+/// @{
+
+  /// Look up the specified global variable in the module symbol table. If it
+  /// does not exist, return null. If AllowInternal is set to true, this
+  /// function will return types that have InternalLinkage. By default, these
+  /// types are not returned.
+  const GlobalVariable *getGlobalVariable(StringRef Name,
+                                          bool AllowInternal = false) const {
+    return const_cast<Module *>(this)->getGlobalVariable(Name, AllowInternal);
+  }
+
+  GlobalVariable *getGlobalVariable(StringRef Name, bool AllowInternal = false);
+
+  /// Return the global variable in the module with the specified name, of
+  /// arbitrary type. This method returns null if a global with the specified
+  /// name is not found.
+  GlobalVariable *getNamedGlobal(StringRef Name) {
+    return getGlobalVariable(Name, true);
+  }
+  const GlobalVariable *getNamedGlobal(StringRef Name) const {
+    return const_cast<Module *>(this)->getNamedGlobal(Name);
+  }
+
+  /// Look up the specified global in the module symbol table.
+  ///   1. If it does not exist, add a declaration of the global and return it.
+  ///   2. Else, the global exists but has the wrong type: return the function
+  ///      with a constantexpr cast to the right type.
+  ///   3. Finally, if the existing global is the correct declaration, return
+  ///      the existing global.
+  Constant *getOrInsertGlobal(StringRef Name, Type *Ty);
+
+/// @}
+/// @name Global Alias Accessors
+/// @{
+
+  /// Return the global alias in the module with the specified name, of
+  /// arbitrary type. This method returns null if a global with the specified
+  /// name is not found.
+  GlobalAlias *getNamedAlias(StringRef Name) const;
+
+/// @}
+/// @name Named Metadata Accessors
+/// @{
+
+  /// Return the first NamedMDNode in the module with the specified name. This
+  /// method returns null if a NamedMDNode with the specified name is not found.
+  NamedMDNode *getNamedMetadata(const Twine &Name) const;
+
+  /// Return the named MDNode in the module with the specified name. This method
+  /// returns a new NamedMDNode if a NamedMDNode with the specified name is not
+  /// found.
+  NamedMDNode *getOrInsertNamedMetadata(StringRef Name);
+
+  /// Remove the given NamedMDNode from this module and delete it.
+  void eraseNamedMetadata(NamedMDNode *NMD);
+
+/// @}
+/// @name Comdat Accessors
+/// @{
+
+  /// Return the Comdat in the module with the specified name. It is created
+  /// if it didn't already exist.
+  Comdat *getOrInsertComdat(StringRef Name);
+
+/// @}
+/// @name Module Flags Accessors
+/// @{
+
+  /// Returns the module flags in the provided vector.
+  void getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const;
+
+  /// Return the corresponding value if Key appears in module flags, otherwise
+  /// return null.
+  Value *getModuleFlag(StringRef Key) const;
+
+  /// Returns the NamedMDNode in the module that represents module-level flags.
+  /// This method returns null if there are no module-level flags.
+  NamedMDNode *getModuleFlagsMetadata() const;
+
+  /// Returns the NamedMDNode in the module that represents module-level flags.
+  /// If module-level flags aren't found, it creates the named metadata that
+  /// contains them.
+  NamedMDNode *getOrInsertModuleFlagsMetadata();
+
+  /// Add a module-level flag to the module-level flags metadata. It will create
+  /// the module-level flags named metadata if it doesn't already exist.
+  void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Value *Val);
+  void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val);
+  void addModuleFlag(MDNode *Node);
+
+/// @}
+/// @name Materialization
+/// @{
+
+  /// Sets the GVMaterializer to GVM. This module must not yet have a
+  /// Materializer. To reset the materializer for a module that already has one,
+  /// call MaterializeAllPermanently first. Destroying this module will destroy
+  /// its materializer without materializing any more GlobalValues. Without
+  /// destroying the Module, there is no way to detach or destroy a materializer
+  /// without materializing all the GVs it controls, to avoid leaving orphan
+  /// unmaterialized GVs.
+  void setMaterializer(GVMaterializer *GVM);
+  /// Retrieves the GVMaterializer, if any, for this Module.
+  GVMaterializer *getMaterializer() const { return Materializer.get(); }
+
+  /// True if the definition of GV has yet to be materializedfrom the
+  /// GVMaterializer.
+  bool isMaterializable(const GlobalValue *GV) const;
+  /// Returns true if this GV was loaded from this Module's GVMaterializer and
+  /// the GVMaterializer knows how to dematerialize the GV.
+  bool isDematerializable(const GlobalValue *GV) const;
+
+  /// Make sure the GlobalValue is fully read. If the module is corrupt, this
+  /// returns true and fills in the optional string with information about the
+  /// problem. If successful, this returns false.
+  bool Materialize(GlobalValue *GV, std::string *ErrInfo = nullptr);
+  /// If the GlobalValue is read in, and if the GVMaterializer supports it,
+  /// release the memory for the function, and set it up to be materialized
+  /// lazily. If !isDematerializable(), this method is a noop.
+  void Dematerialize(GlobalValue *GV);
+
+  /// Make sure all GlobalValues in this Module are fully read.
+  std::error_code materializeAll();
+
+  /// Make sure all GlobalValues in this Module are fully read and clear the
+  /// Materializer. If the module is corrupt, this DOES NOT clear the old
+  /// Materializer.
+  std::error_code materializeAllPermanently(bool ReleaseBuffer = false);
+
+/// @}
+/// @name Direct access to the globals list, functions list, and symbol table
+/// @{
+
+  /// Get the Module's list of global variables (constant).
+  const GlobalListType   &getGlobalList() const       { return GlobalList; }
+  /// Get the Module's list of global variables.
+  GlobalListType         &getGlobalList()             { return GlobalList; }
+  static iplist<GlobalVariable> Module::*getSublistAccess(GlobalVariable*) {
+    return &Module::GlobalList;
+  }
+  /// Get the Module's list of functions (constant).
+  const FunctionListType &getFunctionList() const     { return FunctionList; }
+  /// Get the Module's list of functions.
+  FunctionListType       &getFunctionList()           { return FunctionList; }
+  static iplist<Function> Module::*getSublistAccess(Function*) {
+    return &Module::FunctionList;
+  }
+  /// Get the Module's list of aliases (constant).
+  const AliasListType    &getAliasList() const        { return AliasList; }
+  /// Get the Module's list of aliases.
+  AliasListType          &getAliasList()              { return AliasList; }
+  static iplist<GlobalAlias> Module::*getSublistAccess(GlobalAlias*) {
+    return &Module::AliasList;
+  }
+  /// Get the Module's list of named metadata (constant).
+  const NamedMDListType  &getNamedMDList() const      { return NamedMDList; }
+  /// Get the Module's list of named metadata.
+  NamedMDListType        &getNamedMDList()            { return NamedMDList; }
+  static ilist<NamedMDNode> Module::*getSublistAccess(NamedMDNode*) {
+    return &Module::NamedMDList;
+  }
+  /// Get the symbol table of global variable and function identifiers
+  const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
+  /// Get the Module's symbol table of global variable and function identifiers.
+  ValueSymbolTable       &getValueSymbolTable()       { return *ValSymTab; }
+  /// Get the Module's symbol table for COMDATs (constant).
+  const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; }
+  /// Get the Module's symbol table for COMDATs.
+  ComdatSymTabType &getComdatSymbolTable() { return ComdatSymTab; }
+
+/// @}
+/// @name Global Variable Iteration
+/// @{
+
+  global_iterator       global_begin()       { return GlobalList.begin(); }
+  const_global_iterator global_begin() const { return GlobalList.begin(); }
+  global_iterator       global_end  ()       { return GlobalList.end(); }
+  const_global_iterator global_end  () const { return GlobalList.end(); }
+  bool                  global_empty() const { return GlobalList.empty(); }
+
+  iterator_range<global_iterator> globals() {
+    return iterator_range<global_iterator>(global_begin(), global_end());
+  }
+  iterator_range<const_global_iterator> globals() const {
+    return iterator_range<const_global_iterator>(global_begin(), global_end());
+  }
+
+/// @}
+/// @name Function Iteration
+/// @{
+
+  iterator                begin()       { return FunctionList.begin(); }
+  const_iterator          begin() const { return FunctionList.begin(); }
+  iterator                end  ()       { return FunctionList.end();   }
+  const_iterator          end  () const { return FunctionList.end();   }
+  size_t                  size() const  { return FunctionList.size(); }
+  bool                    empty() const { return FunctionList.empty(); }
+
+/// @}
+/// @name Alias Iteration
+/// @{
+
+  alias_iterator       alias_begin()            { return AliasList.begin(); }
+  const_alias_iterator alias_begin() const      { return AliasList.begin(); }
+  alias_iterator       alias_end  ()            { return AliasList.end();   }
+  const_alias_iterator alias_end  () const      { return AliasList.end();   }
+  size_t               alias_size () const      { return AliasList.size();  }
+  bool                 alias_empty() const      { return AliasList.empty(); }
+
+  iterator_range<alias_iterator> aliases() {
+    return iterator_range<alias_iterator>(alias_begin(), alias_end());
+  }
+  iterator_range<const_alias_iterator> aliases() const {
+    return iterator_range<const_alias_iterator>(alias_begin(), alias_end());
+  }
+
+/// @}
+/// @name Named Metadata Iteration
+/// @{
+
+  named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); }
+  const_named_metadata_iterator named_metadata_begin() const {
+    return NamedMDList.begin();
+  }
+
+  named_metadata_iterator named_metadata_end() { return NamedMDList.end(); }
+  const_named_metadata_iterator named_metadata_end() const {
+    return NamedMDList.end();
+  }
+
+  size_t named_metadata_size() const { return NamedMDList.size();  }
+  bool named_metadata_empty() const { return NamedMDList.empty(); }
+
+  iterator_range<named_metadata_iterator> named_metadata() {
+    return iterator_range<named_metadata_iterator>(named_metadata_begin(),
+                                                   named_metadata_end());
+  }
+  iterator_range<const_named_metadata_iterator> named_metadata() const {
+    return iterator_range<const_named_metadata_iterator>(named_metadata_begin(),
+                                                         named_metadata_end());
+  }
+
+/// @}
+/// @name Utility functions for printing and dumping Module objects
+/// @{
+
+  /// Print the module to an output stream with an optional
+  /// AssemblyAnnotationWriter.
+  void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+  /// Dump the module to stderr (for debugging).
+  void dump() const;
+  
+  /// This function causes all the subinstructions to "let go" of all references
+  /// that they are maintaining.  This allows one to 'delete' a whole class at
+  /// a time, even though there may be circular references... first all
+  /// references are dropped, and all use counts go to zero.  Then everything
+  /// is delete'd for real.  Note that no operations are valid on an object
+  /// that has "dropped all references", except operator delete.
+  void dropAllReferences();
+
+/// @}
+/// @name Utility functions for querying Debug information.
+/// @{
+
+  /// \brief Returns the Dwarf Version by checking module flags.
+  unsigned getDwarfVersion() const;
+
+/// @}
+};
+
+/// An raw_ostream inserter for modules.
+inline raw_ostream &operator<<(raw_ostream &O, const Module &M) {
+  M.print(O, nullptr);
+  return O;
+}
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef)
+
+/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
+ * Module.
+ */
+inline Module *unwrap(LLVMModuleProviderRef MP) {
+  return reinterpret_cast<Module*>(MP);
+}
+  
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h
new file mode 100644
index 0000000..a9cdfc3
--- /dev/null
+++ b/include/llvm/IR/NoFolder.h
@@ -0,0 +1,298 @@
+//===- NoFolder.h - Constant folding helper ---------------------*- 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 NoFolder class, a helper for IRBuilder.  It provides
+// IRBuilder with a set of methods for creating unfolded constants.  This is
+// useful for learners trying to understand how LLVM IR works, and who don't
+// want details to be hidden by the constant folder.  For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
+//
+// Note: since it is not actually possible to create unfolded constants, this
+// class returns instructions rather than constants.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_NOFOLDER_H
+#define LLVM_IR_NOFOLDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+
+namespace llvm {
+
+/// NoFolder - Create "constants" (actually, instructions) with no folding.
+class NoFolder {
+public:
+  explicit NoFolder() {}
+
+  //===--------------------------------------------------------------------===//
+  // Binary Operators
+  //===--------------------------------------------------------------------===//
+
+  Instruction *CreateAdd(Constant *LHS, Constant *RHS,
+                         bool HasNUW = false, bool HasNSW = false) const {
+    BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNSWAdd(LHS, RHS);
+  }
+  Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNUWAdd(LHS, RHS);
+  }
+  Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateFAdd(LHS, RHS);
+  }
+  Instruction *CreateSub(Constant *LHS, Constant *RHS,
+                         bool HasNUW = false, bool HasNSW = false) const {
+    BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNSWSub(LHS, RHS);
+  }
+  Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNUWSub(LHS, RHS);
+  }
+  Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateFSub(LHS, RHS);
+  }
+  Instruction *CreateMul(Constant *LHS, Constant *RHS,
+                         bool HasNUW = false, bool HasNSW = false) const {
+    BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNSWMul(LHS, RHS);
+  }
+  Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateNUWMul(LHS, RHS);
+  }
+  Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateFMul(LHS, RHS);
+  }
+  Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
+                          bool isExact = false) const {
+    if (!isExact)
+      return BinaryOperator::CreateUDiv(LHS, RHS);
+    return BinaryOperator::CreateExactUDiv(LHS, RHS);
+  }
+  Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateExactUDiv(LHS, RHS);
+  }
+  Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
+                          bool isExact = false) const {
+    if (!isExact)
+      return BinaryOperator::CreateSDiv(LHS, RHS);
+    return BinaryOperator::CreateExactSDiv(LHS, RHS);
+  }
+  Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateExactSDiv(LHS, RHS);
+  }
+  Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateFDiv(LHS, RHS);
+  }
+  Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateURem(LHS, RHS);
+  }
+  Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateSRem(LHS, RHS);
+  }
+  Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateFRem(LHS, RHS);
+  }
+  Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
+                         bool HasNSW = false) const {
+    BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Instruction *CreateLShr(Constant *LHS, Constant *RHS,
+                          bool isExact = false) const {
+    if (!isExact)
+      return BinaryOperator::CreateLShr(LHS, RHS);
+    return BinaryOperator::CreateExactLShr(LHS, RHS);
+  }
+  Instruction *CreateAShr(Constant *LHS, Constant *RHS,
+                          bool isExact = false) const {
+    if (!isExact)
+      return BinaryOperator::CreateAShr(LHS, RHS);
+    return BinaryOperator::CreateExactAShr(LHS, RHS);
+  }
+  Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateAnd(LHS, RHS);
+  }
+  Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateOr(LHS, RHS);
+  }
+  Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::CreateXor(LHS, RHS);
+  }
+
+  Instruction *CreateBinOp(Instruction::BinaryOps Opc,
+                           Constant *LHS, Constant *RHS) const {
+    return BinaryOperator::Create(Opc, LHS, RHS);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Unary Operators
+  //===--------------------------------------------------------------------===//
+
+  Instruction *CreateNeg(Constant *C,
+                         bool HasNUW = false, bool HasNSW = false) const {
+    BinaryOperator *BO = BinaryOperator::CreateNeg(C);
+    if (HasNUW) BO->setHasNoUnsignedWrap();
+    if (HasNSW) BO->setHasNoSignedWrap();
+    return BO;
+  }
+  Instruction *CreateNSWNeg(Constant *C) const {
+    return BinaryOperator::CreateNSWNeg(C);
+  }
+  Instruction *CreateNUWNeg(Constant *C) const {
+    return BinaryOperator::CreateNUWNeg(C);
+  }
+  Instruction *CreateFNeg(Constant *C) const {
+    return BinaryOperator::CreateFNeg(C);
+  }
+  Instruction *CreateNot(Constant *C) const {
+    return BinaryOperator::CreateNot(C);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Memory Instructions
+  //===--------------------------------------------------------------------===//
+
+  Constant *CreateGetElementPtr(Constant *C,
+                                ArrayRef<Constant *> IdxList) const {
+    return ConstantExpr::getGetElementPtr(C, IdxList);
+  }
+  Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return ConstantExpr::getGetElementPtr(C, Idx);
+  }
+  Instruction *CreateGetElementPtr(Constant *C,
+                                   ArrayRef<Value *> IdxList) const {
+    return GetElementPtrInst::Create(C, IdxList);
+  }
+
+  Constant *CreateInBoundsGetElementPtr(Constant *C,
+                                        ArrayRef<Constant *> IdxList) const {
+    return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+  }
+  Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+    // This form of the function only exists to avoid ambiguous overload
+    // warnings about whether to convert Idx to ArrayRef<Constant *> or
+    // ArrayRef<Value *>.
+    return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+  }
+  Instruction *CreateInBoundsGetElementPtr(Constant *C,
+                                           ArrayRef<Value *> IdxList) const {
+    return GetElementPtrInst::CreateInBounds(C, IdxList);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Cast/Conversion Operators
+  //===--------------------------------------------------------------------===//
+
+  Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
+                    Type *DestTy) const {
+    return CastInst::Create(Op, C, DestTy);
+  }
+  Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
+    return CastInst::CreatePointerCast(C, DestTy);
+  }
+  Instruction *CreateIntCast(Constant *C, Type *DestTy,
+                       bool isSigned) const {
+    return CastInst::CreateIntegerCast(C, DestTy, isSigned);
+  }
+  Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
+    return CastInst::CreateFPCast(C, DestTy);
+  }
+
+  Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::BitCast, C, DestTy);
+  }
+  Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::IntToPtr, C, DestTy);
+  }
+  Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
+    return CreateCast(Instruction::PtrToInt, C, DestTy);
+  }
+  Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+    return CastInst::CreateZExtOrBitCast(C, DestTy);
+  }
+  Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+    return CastInst::CreateSExtOrBitCast(C, DestTy);
+  }
+
+  Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+    return CastInst::CreateTruncOrBitCast(C, DestTy);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Compare Instructions
+  //===--------------------------------------------------------------------===//
+
+  Instruction *CreateICmp(CmpInst::Predicate P,
+                          Constant *LHS, Constant *RHS) const {
+    return new ICmpInst(P, LHS, RHS);
+  }
+  Instruction *CreateFCmp(CmpInst::Predicate P,
+                          Constant *LHS, Constant *RHS) const {
+    return new FCmpInst(P, LHS, RHS);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Other Instructions
+  //===--------------------------------------------------------------------===//
+
+  Instruction *CreateSelect(Constant *C,
+                            Constant *True, Constant *False) const {
+    return SelectInst::Create(C, True, False);
+  }
+
+  Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+    return ExtractElementInst::Create(Vec, Idx);
+  }
+
+  Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
+                                   Constant *Idx) const {
+    return InsertElementInst::Create(Vec, NewElt, Idx);
+  }
+
+  Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
+                                   Constant *Mask) const {
+    return new ShuffleVectorInst(V1, V2, Mask);
+  }
+
+  Instruction *CreateExtractValue(Constant *Agg,
+                                  ArrayRef<unsigned> IdxList) const {
+    return ExtractValueInst::Create(Agg, IdxList);
+  }
+
+  Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
+                                 ArrayRef<unsigned> IdxList) const {
+    return InsertValueInst::Create(Agg, Val, IdxList);
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/IR/OperandTraits.h b/include/llvm/IR/OperandTraits.h
new file mode 100644
index 0000000..0e4b195
--- /dev/null
+++ b/include/llvm/IR/OperandTraits.h
@@ -0,0 +1,160 @@
+//===-- llvm/OperandTraits.h - OperandTraits class definition ---*- 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 traits classes that are handy for enforcing the correct
+// layout of various User subclasses. It also provides the means for accessing
+// the operands in the most efficient manner.
+//
+
+#ifndef LLVM_IR_OPERANDTRAITS_H
+#define LLVM_IR_OPERANDTRAITS_H
+
+#include "llvm/IR/User.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//                          FixedNumOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// FixedNumOperandTraits - determine the allocation regime of the Use array
+/// when it is a prefix to the User object, and the number of Use objects is
+/// known at compile time.
+
+template <typename SubClass, unsigned ARITY>
+struct FixedNumOperandTraits {
+  static Use *op_begin(SubClass* U) {
+    return reinterpret_cast<Use*>(U) - ARITY;
+  }
+  static Use *op_end(SubClass* U) {
+    return reinterpret_cast<Use*>(U);
+  }
+  static unsigned operands(const User*) {
+    return ARITY;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                          OptionalOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// OptionalOperandTraits - when the number of operands may change at runtime.
+/// Naturally it may only decrease, because the allocations may not change.
+
+template <typename SubClass, unsigned ARITY = 1>
+struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
+  static unsigned operands(const User *U) {
+    return U->getNumOperands();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                          VariadicOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// VariadicOperandTraits - determine the allocation regime of the Use array
+/// when it is a prefix to the User object, and the number of Use objects is
+/// only known at allocation time.
+
+template <typename SubClass, unsigned MINARITY = 0>
+struct VariadicOperandTraits {
+  static Use *op_begin(SubClass* U) {
+    return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
+  }
+  static Use *op_end(SubClass* U) {
+    return reinterpret_cast<Use*>(U);
+  }
+  static unsigned operands(const User *U) {
+    return U->getNumOperands();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//                          HungoffOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// HungoffOperandTraits - determine the allocation regime of the Use array
+/// when it is not a prefix to the User object, but allocated at an unrelated
+/// heap address.
+/// Assumes that the User subclass that is determined by this traits class
+/// has an OperandList member of type User::op_iterator. [Note: this is now
+/// trivially satisfied, because User has that member for historic reasons.]
+///
+/// This is the traits class that is needed when the Use array must be
+/// resizable.
+
+template <unsigned MINARITY = 1>
+struct HungoffOperandTraits {
+  static Use *op_begin(User* U) {
+    return U->OperandList;
+  }
+  static Use *op_end(User* U) {
+    return U->OperandList + U->getNumOperands();
+  }
+  static unsigned operands(const User *U) {
+    return U->getNumOperands();
+  }
+};
+
+/// Macro for generating in-class operand accessor declarations.
+/// It should only be called in the public section of the interface.
+///
+#define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
+  public: \
+  inline VALUECLASS *getOperand(unsigned) const; \
+  inline void setOperand(unsigned, VALUECLASS*); \
+  inline op_iterator op_begin(); \
+  inline const_op_iterator op_begin() const; \
+  inline op_iterator op_end(); \
+  inline const_op_iterator op_end() const; \
+  protected: \
+  template <int> inline Use &Op(); \
+  template <int> inline const Use &Op() const; \
+  public: \
+  inline unsigned getNumOperands() const
+
+/// Macro for generating out-of-class operand accessor definitions
+#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
+CLASS::op_iterator CLASS::op_begin() { \
+  return OperandTraits<CLASS>::op_begin(this); \
+} \
+CLASS::const_op_iterator CLASS::op_begin() const { \
+  return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
+} \
+CLASS::op_iterator CLASS::op_end() { \
+  return OperandTraits<CLASS>::op_end(this); \
+} \
+CLASS::const_op_iterator CLASS::op_end() const { \
+  return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
+} \
+VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
+  assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
+         && "getOperand() out of range!"); \
+  return cast_or_null<VALUECLASS>( \
+    OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
+} \
+void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
+  assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
+         && "setOperand() out of range!"); \
+  OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
+} \
+unsigned CLASS::getNumOperands() const { \
+  return OperandTraits<CLASS>::operands(this); \
+} \
+template <int Idx_nocapture> Use &CLASS::Op() { \
+  return this->OpFrom<Idx_nocapture>(this); \
+} \
+template <int Idx_nocapture> const Use &CLASS::Op() const { \
+  return this->OpFrom<Idx_nocapture>(this); \
+}
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
new file mode 100644
index 0000000..888cabf
--- /dev/null
+++ b/include/llvm/IR/Operator.h
@@ -0,0 +1,512 @@
+//===-- llvm/Operator.h - Operator utility subclass -------------*- 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 various classes for working with Instructions and
+// ConstantExprs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_OPERATOR_H
+#define LLVM_IR_OPERATOR_H
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Type.h"
+
+namespace llvm {
+
+class GetElementPtrInst;
+class BinaryOperator;
+class ConstantExpr;
+
+/// Operator - This is a utility class that provides an abstraction for the
+/// common functionality between Instructions and ConstantExprs.
+///
+class Operator : public User {
+private:
+  // The Operator class is intended to be used as a utility, and is never itself
+  // instantiated.
+  void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+  void *operator new(size_t s) LLVM_DELETED_FUNCTION;
+  Operator() LLVM_DELETED_FUNCTION;
+
+protected:
+  // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete
+  // an overridden method that's not deleted in the base class. Cannot leave
+  // this unimplemented because that leads to an ODR-violation.
+  ~Operator();
+
+public:
+  /// getOpcode - Return the opcode for this Instruction or ConstantExpr.
+  ///
+  unsigned getOpcode() const {
+    if (const Instruction *I = dyn_cast<Instruction>(this))
+      return I->getOpcode();
+    return cast<ConstantExpr>(this)->getOpcode();
+  }
+
+  /// getOpcode - If V is an Instruction or ConstantExpr, return its
+  /// opcode. Otherwise return UserOp1.
+  ///
+  static unsigned getOpcode(const Value *V) {
+    if (const Instruction *I = dyn_cast<Instruction>(V))
+      return I->getOpcode();
+    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+      return CE->getOpcode();
+    return Instruction::UserOp1;
+  }
+
+  static inline bool classof(const Instruction *) { return true; }
+  static inline bool classof(const ConstantExpr *) { return true; }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) || isa<ConstantExpr>(V);
+  }
+};
+
+/// OverflowingBinaryOperator - Utility class for integer arithmetic operators
+/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv,
+/// despite that operator having the potential for overflow.
+///
+class OverflowingBinaryOperator : public Operator {
+public:
+  enum {
+    NoUnsignedWrap = (1 << 0),
+    NoSignedWrap   = (1 << 1)
+  };
+
+private:
+  friend class BinaryOperator;
+  friend class ConstantExpr;
+  void setHasNoUnsignedWrap(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
+  }
+  void setHasNoSignedWrap(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
+  }
+
+public:
+  /// hasNoUnsignedWrap - Test whether this operation is known to never
+  /// undergo unsigned overflow, aka the nuw property.
+  bool hasNoUnsignedWrap() const {
+    return SubclassOptionalData & NoUnsignedWrap;
+  }
+
+  /// hasNoSignedWrap - Test whether this operation is known to never
+  /// undergo signed overflow, aka the nsw property.
+  bool hasNoSignedWrap() const {
+    return (SubclassOptionalData & NoSignedWrap) != 0;
+  }
+
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Instruction::Add ||
+           I->getOpcode() == Instruction::Sub ||
+           I->getOpcode() == Instruction::Mul ||
+           I->getOpcode() == Instruction::Shl;
+  }
+  static inline bool classof(const ConstantExpr *CE) {
+    return CE->getOpcode() == Instruction::Add ||
+           CE->getOpcode() == Instruction::Sub ||
+           CE->getOpcode() == Instruction::Mul ||
+           CE->getOpcode() == Instruction::Shl;
+  }
+  static inline bool classof(const Value *V) {
+    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+  }
+};
+
+/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
+/// "exact", indicating that no bits are destroyed.
+class PossiblyExactOperator : public Operator {
+public:
+  enum {
+    IsExact = (1 << 0)
+  };
+
+private:
+  friend class BinaryOperator;
+  friend class ConstantExpr;
+  void setIsExact(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
+  }
+
+public:
+  /// isExact - Test whether this division is known to be exact, with
+  /// zero remainder.
+  bool isExact() const {
+    return SubclassOptionalData & IsExact;
+  }
+
+  static bool isPossiblyExactOpcode(unsigned OpC) {
+    return OpC == Instruction::SDiv ||
+           OpC == Instruction::UDiv ||
+           OpC == Instruction::AShr ||
+           OpC == Instruction::LShr;
+  }
+  static inline bool classof(const ConstantExpr *CE) {
+    return isPossiblyExactOpcode(CE->getOpcode());
+  }
+  static inline bool classof(const Instruction *I) {
+    return isPossiblyExactOpcode(I->getOpcode());
+  }
+  static inline bool classof(const Value *V) {
+    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+  }
+};
+
+/// Convenience struct for specifying and reasoning about fast-math flags.
+class FastMathFlags {
+private:
+  friend class FPMathOperator;
+  unsigned Flags;
+  FastMathFlags(unsigned F) : Flags(F) { }
+
+public:
+  enum {
+    UnsafeAlgebra   = (1 << 0),
+    NoNaNs          = (1 << 1),
+    NoInfs          = (1 << 2),
+    NoSignedZeros   = (1 << 3),
+    AllowReciprocal = (1 << 4)
+  };
+
+  FastMathFlags() : Flags(0)
+  { }
+
+  /// Whether any flag is set
+  bool any() { return Flags != 0; }
+
+  /// Set all the flags to false
+  void clear() { Flags = 0; }
+
+  /// Flag queries
+  bool noNaNs()          { return 0 != (Flags & NoNaNs); }
+  bool noInfs()          { return 0 != (Flags & NoInfs); }
+  bool noSignedZeros()   { return 0 != (Flags & NoSignedZeros); }
+  bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); }
+  bool unsafeAlgebra()   { return 0 != (Flags & UnsafeAlgebra); }
+
+  /// Flag setters
+  void setNoNaNs()          { Flags |= NoNaNs; }
+  void setNoInfs()          { Flags |= NoInfs; }
+  void setNoSignedZeros()   { Flags |= NoSignedZeros; }
+  void setAllowReciprocal() { Flags |= AllowReciprocal; }
+  void setUnsafeAlgebra() {
+    Flags |= UnsafeAlgebra;
+    setNoNaNs();
+    setNoInfs();
+    setNoSignedZeros();
+    setAllowReciprocal();
+  }
+
+  void operator&=(const FastMathFlags &OtherFlags) {
+    Flags &= OtherFlags.Flags;
+  }
+};
+
+
+/// FPMathOperator - Utility class for floating point operations which can have
+/// information about relaxed accuracy requirements attached to them.
+class FPMathOperator : public Operator {
+private:
+  friend class Instruction;
+
+  void setHasUnsafeAlgebra(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
+      (B * FastMathFlags::UnsafeAlgebra);
+
+    // Unsafe algebra implies all the others
+    if (B) {
+      setHasNoNaNs(true);
+      setHasNoInfs(true);
+      setHasNoSignedZeros(true);
+      setHasAllowReciprocal(true);
+    }
+  }
+  void setHasNoNaNs(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
+      (B * FastMathFlags::NoNaNs);
+  }
+  void setHasNoInfs(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~FastMathFlags::NoInfs) |
+      (B * FastMathFlags::NoInfs);
+  }
+  void setHasNoSignedZeros(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
+      (B * FastMathFlags::NoSignedZeros);
+  }
+  void setHasAllowReciprocal(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
+      (B * FastMathFlags::AllowReciprocal);
+  }
+
+  /// Convenience function for setting all the fast-math flags
+  void setFastMathFlags(FastMathFlags FMF) {
+    SubclassOptionalData |= FMF.Flags;
+  }
+
+public:
+  /// Test whether this operation is permitted to be
+  /// algebraically transformed, aka the 'A' fast-math property.
+  bool hasUnsafeAlgebra() const {
+    return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
+  }
+
+  /// Test whether this operation's arguments and results are to be
+  /// treated as non-NaN, aka the 'N' fast-math property.
+  bool hasNoNaNs() const {
+    return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
+  }
+
+  /// Test whether this operation's arguments and results are to be
+  /// treated as NoN-Inf, aka the 'I' fast-math property.
+  bool hasNoInfs() const {
+    return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
+  }
+
+  /// Test whether this operation can treat the sign of zero
+  /// as insignificant, aka the 'S' fast-math property.
+  bool hasNoSignedZeros() const {
+    return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
+  }
+
+  /// Test whether this operation is permitted to use
+  /// reciprocal instead of division, aka the 'R' fast-math property.
+  bool hasAllowReciprocal() const {
+    return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
+  }
+
+  /// Convenience function for getting all the fast-math flags
+  FastMathFlags getFastMathFlags() const {
+    return FastMathFlags(SubclassOptionalData);
+  }
+
+  /// \brief Get the maximum error permitted by this operation in ULPs.  An
+  /// accuracy of 0.0 means that the operation should be performed with the
+  /// default precision.
+  float getFPAccuracy() const;
+
+  static inline bool classof(const Instruction *I) {
+    return I->getType()->isFPOrFPVectorTy();
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+};
+
+
+/// ConcreteOperator - A helper template for defining operators for individual
+/// opcodes.
+template<typename SuperClass, unsigned Opc>
+class ConcreteOperator : public SuperClass {
+public:
+  static inline bool classof(const Instruction *I) {
+    return I->getOpcode() == Opc;
+  }
+  static inline bool classof(const ConstantExpr *CE) {
+    return CE->getOpcode() == Opc;
+  }
+  static inline bool classof(const Value *V) {
+    return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+           (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+  }
+};
+
+class AddOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
+};
+class SubOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
+};
+class MulOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
+};
+class ShlOperator
+  : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
+};
+
+
+class SDivOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
+};
+class UDivOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
+};
+class AShrOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
+};
+class LShrOperator
+  : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
+};
+
+
+
+class GEPOperator
+  : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
+  enum {
+    IsInBounds = (1 << 0)
+  };
+
+  friend class GetElementPtrInst;
+  friend class ConstantExpr;
+  void setIsInBounds(bool B) {
+    SubclassOptionalData =
+      (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
+  }
+
+public:
+  /// isInBounds - Test whether this is an inbounds GEP, as defined
+  /// by LangRef.html.
+  bool isInBounds() const {
+    return SubclassOptionalData & IsInBounds;
+  }
+
+  inline op_iterator       idx_begin()       { return op_begin()+1; }
+  inline const_op_iterator idx_begin() const { return op_begin()+1; }
+  inline op_iterator       idx_end()         { return op_end(); }
+  inline const_op_iterator idx_end()   const { return op_end(); }
+
+  Value *getPointerOperand() {
+    return getOperand(0);
+  }
+  const Value *getPointerOperand() const {
+    return getOperand(0);
+  }
+  static unsigned getPointerOperandIndex() {
+    return 0U;                      // get index for modifying correct operand
+  }
+
+  /// getPointerOperandType - Method to return the pointer operand as a
+  /// PointerType.
+  Type *getPointerOperandType() const {
+    return getPointerOperand()->getType();
+  }
+
+  /// getPointerAddressSpace - Method to return the address space of the
+  /// pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+  }
+
+  unsigned getNumIndices() const {  // Note: always non-negative
+    return getNumOperands() - 1;
+  }
+
+  bool hasIndices() const {
+    return getNumOperands() > 1;
+  }
+
+  /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+  /// zeros.  If so, the result pointer and the first operand have the same
+  /// value, just potentially different types.
+  bool hasAllZeroIndices() const {
+    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+      if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+        if (C->isZero())
+          continue;
+      return false;
+    }
+    return true;
+  }
+
+  /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+  /// constant integers.  If so, the result pointer and the first operand have
+  /// a constant offset between them.
+  bool hasAllConstantIndices() const {
+    for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+      if (!isa<ConstantInt>(I))
+        return false;
+    }
+    return true;
+  }
+
+  /// \brief Accumulate the constant address offset of this GEP if possible.
+  ///
+  /// This routine accepts an APInt into which it will accumulate the constant
+  /// offset of this GEP if the GEP is in fact constant. If the GEP is not
+  /// all-constant, it returns false and the value of the offset APInt is
+  /// undefined (it is *not* preserved!). The APInt passed into this routine
+  /// must be at exactly as wide as the IntPtr type for the address space of the
+  /// base GEP pointer.
+  bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
+    assert(Offset.getBitWidth() ==
+           DL.getPointerSizeInBits(getPointerAddressSpace()) &&
+           "The offset must have exactly as many bits as our pointer.");
+
+    for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
+         GTI != GTE; ++GTI) {
+      ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
+      if (!OpC)
+        return false;
+      if (OpC->isZero())
+        continue;
+
+      // Handle a struct index, which adds its field offset to the pointer.
+      if (StructType *STy = dyn_cast<StructType>(*GTI)) {
+        unsigned ElementIdx = OpC->getZExtValue();
+        const StructLayout *SL = DL.getStructLayout(STy);
+        Offset += APInt(Offset.getBitWidth(),
+                        SL->getElementOffset(ElementIdx));
+        continue;
+      }
+
+      // For array or vector indices, scale the index by the size of the type.
+      APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
+      Offset += Index * APInt(Offset.getBitWidth(),
+                              DL.getTypeAllocSize(GTI.getIndexedType()));
+    }
+    return true;
+  }
+
+};
+
+class PtrToIntOperator
+    : public ConcreteOperator<Operator, Instruction::PtrToInt> {
+  friend class PtrToInt;
+  friend class ConstantExpr;
+
+public:
+  Value *getPointerOperand() {
+    return getOperand(0);
+  }
+  const Value *getPointerOperand() const {
+    return getOperand(0);
+  }
+  static unsigned getPointerOperandIndex() {
+    return 0U;                      // get index for modifying correct operand
+  }
+
+  /// getPointerOperandType - Method to return the pointer operand as a
+  /// PointerType.
+  Type *getPointerOperandType() const {
+    return getPointerOperand()->getType();
+  }
+
+  /// getPointerAddressSpace - Method to return the address space of the
+  /// pointer operand.
+  unsigned getPointerAddressSpace() const {
+    return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+  }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
new file mode 100644
index 0000000..cc2a80b
--- /dev/null
+++ b/include/llvm/IR/PassManager.h
@@ -0,0 +1,1034 @@
+//===- PassManager.h - Pass management infrastructure -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header defines various interfaces for pass management in LLVM. There
+/// is no "pass" interface in LLVM per se. Instead, an instance of any class
+/// which supports a method to 'run' it over a unit of IR can be used as
+/// a pass. A pass manager is generally a tool to collect a sequence of passes
+/// which run over a particular IR construct, and run each of them in sequence
+/// over each such construct in the containing IR construct. As there is no
+/// containing IR construct for a Module, a manager for passes over modules
+/// forms the base case which runs its managed passes in sequence over the
+/// single module provided.
+///
+/// The core IR library provides managers for running passes over
+/// modules and functions.
+///
+/// * FunctionPassManager can run over a Module, runs each pass over
+///   a Function.
+/// * ModulePassManager must be directly run, runs each pass over the Module.
+///
+/// Note that the implementations of the pass managers use concept-based
+/// polymorphism as outlined in the "Value Semantics and Concept-based
+/// Polymorphism" talk (or its abbreviated sibling "Inheritance Is The Base
+/// Class of Evil") by Sean Parent:
+/// * http://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations
+/// * http://www.youtube.com/watch?v=_BpMYeUFXv8
+/// * http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_PASS_MANAGER_H
+#define LLVM_IR_PASS_MANAGER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/type_traits.h"
+#include <list>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+class Module;
+class Function;
+
+/// \brief An abstract set of preserved analyses following a transformation pass
+/// run.
+///
+/// When a transformation pass is run, it can return a set of analyses whose
+/// results were preserved by that transformation. The default set is "none",
+/// and preserving analyses must be done explicitly.
+///
+/// There is also an explicit all state which can be used (for example) when
+/// the IR is not mutated at all.
+class PreservedAnalyses {
+public:
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  PreservedAnalyses() {}
+  PreservedAnalyses(const PreservedAnalyses &Arg)
+      : PreservedPassIDs(Arg.PreservedPassIDs) {}
+  PreservedAnalyses(PreservedAnalyses &&Arg)
+      : PreservedPassIDs(std::move(Arg.PreservedPassIDs)) {}
+  friend void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {
+    using std::swap;
+    swap(LHS.PreservedPassIDs, RHS.PreservedPassIDs);
+  }
+  PreservedAnalyses &operator=(PreservedAnalyses RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief Convenience factory function for the empty preserved set.
+  static PreservedAnalyses none() { return PreservedAnalyses(); }
+
+  /// \brief Construct a special preserved set that preserves all passes.
+  static PreservedAnalyses all() {
+    PreservedAnalyses PA;
+    PA.PreservedPassIDs.insert((void *)AllPassesID);
+    return PA;
+  }
+
+  /// \brief Mark a particular pass as preserved, adding it to the set.
+  template <typename PassT> void preserve() {
+    if (!areAllPreserved())
+      PreservedPassIDs.insert(PassT::ID());
+  }
+
+  /// \brief Intersect this set with another in place.
+  ///
+  /// This is a mutating operation on this preserved set, removing all
+  /// preserved passes which are not also preserved in the argument.
+  void intersect(const PreservedAnalyses &Arg) {
+    if (Arg.areAllPreserved())
+      return;
+    if (areAllPreserved()) {
+      PreservedPassIDs = Arg.PreservedPassIDs;
+      return;
+    }
+    for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
+                                                E = PreservedPassIDs.end();
+         I != E; ++I)
+      if (!Arg.PreservedPassIDs.count(*I))
+        PreservedPassIDs.erase(*I);
+  }
+
+  /// \brief Intersect this set with a temporary other set in place.
+  ///
+  /// This is a mutating operation on this preserved set, removing all
+  /// preserved passes which are not also preserved in the argument.
+  void intersect(PreservedAnalyses &&Arg) {
+    if (Arg.areAllPreserved())
+      return;
+    if (areAllPreserved()) {
+      PreservedPassIDs = std::move(Arg.PreservedPassIDs);
+      return;
+    }
+    for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
+                                                E = PreservedPassIDs.end();
+         I != E; ++I)
+      if (!Arg.PreservedPassIDs.count(*I))
+        PreservedPassIDs.erase(*I);
+  }
+
+  /// \brief Query whether a pass is marked as preserved by this set.
+  template <typename PassT> bool preserved() const {
+    return preserved(PassT::ID());
+  }
+
+  /// \brief Query whether an abstract pass ID is marked as preserved by this
+  /// set.
+  bool preserved(void *PassID) const {
+    return PreservedPassIDs.count((void *)AllPassesID) ||
+           PreservedPassIDs.count(PassID);
+  }
+
+private:
+  // Note that this must not be -1 or -2 as those are already used by the
+  // SmallPtrSet.
+  static const uintptr_t AllPassesID = (intptr_t)(-3);
+
+  bool areAllPreserved() const {
+    return PreservedPassIDs.count((void *)AllPassesID);
+  }
+
+  SmallPtrSet<void *, 2> PreservedPassIDs;
+};
+
+/// \brief Implementation details of the pass manager interfaces.
+namespace detail {
+
+/// \brief Template for the abstract base class used to dispatch
+/// polymorphically over pass objects.
+template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
+  // Boiler plate necessary for the container of derived classes.
+  virtual ~PassConcept() {}
+
+  /// \brief The polymorphic API which runs the pass over a given IR entity.
+  ///
+  /// Note that actual pass object can omit the analysis manager argument if
+  /// desired. Also that the analysis manager may be null if there is no
+  /// analysis manager in the pass pipeline.
+  virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
+
+  /// \brief Polymorphic method to access the name of a pass.
+  virtual StringRef name() = 0;
+};
+
+/// \brief SFINAE metafunction for computing whether \c PassT has a run method
+/// accepting an \c AnalysisManagerT.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+          typename ResultT>
+class PassRunAcceptsAnalysisManager {
+  typedef char SmallType;
+  struct BigType {
+    char a, b;
+  };
+
+  template <typename T, ResultT (T::*)(IRUnitT, AnalysisManagerT *)>
+  struct Checker;
+
+  template <typename T> static SmallType f(Checker<T, &T::run> *);
+  template <typename T> static BigType f(...);
+
+public:
+  enum { Value = sizeof(f<PassT>(nullptr)) == sizeof(SmallType) };
+};
+
+/// \brief A template wrapper used to implement the polymorphic API.
+///
+/// Can be instantiated for any object which provides a \c run method accepting
+/// an \c IRUnitT. It requires the pass to be a copyable object. When the
+/// \c run method also accepts an \c AnalysisManagerT*, we pass it along.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+          bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
+              IRUnitT, AnalysisManagerT, PassT, PreservedAnalyses>::Value>
+struct PassModel;
+
+/// \brief Specialization of \c PassModel for passes that accept an analyis
+/// manager.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct PassModel<IRUnitT, AnalysisManagerT, PassT, true>
+    : PassConcept<IRUnitT, AnalysisManagerT> {
+  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
+  PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+  friend void swap(PassModel &LHS, PassModel &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  PassModel &operator=(PassModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
+    return Pass.run(IR, AM);
+  }
+  StringRef name() override { return PassT::name(); }
+  PassT Pass;
+};
+
+/// \brief Specialization of \c PassModel for passes that accept an analyis
+/// manager.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct PassModel<IRUnitT, AnalysisManagerT, PassT, false>
+    : PassConcept<IRUnitT, AnalysisManagerT> {
+  explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
+  PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+  friend void swap(PassModel &LHS, PassModel &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  PassModel &operator=(PassModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
+    return Pass.run(IR);
+  }
+  StringRef name() override { return PassT::name(); }
+  PassT Pass;
+};
+
+/// \brief Abstract concept of an analysis result.
+///
+/// This concept is parameterized over the IR unit that this result pertains
+/// to.
+template <typename IRUnitT> struct AnalysisResultConcept {
+  virtual ~AnalysisResultConcept() {}
+
+  /// \brief Method to try and mark a result as invalid.
+  ///
+  /// When the outer analysis manager detects a change in some underlying
+  /// unit of the IR, it will call this method on all of the results cached.
+  ///
+  /// This method also receives a set of preserved analyses which can be used
+  /// to avoid invalidation because the pass which changed the underlying IR
+  /// took care to update or preserve the analysis result in some way.
+  ///
+  /// \returns true if the result is indeed invalid (the default).
+  virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) = 0;
+};
+
+/// \brief SFINAE metafunction for computing whether \c ResultT provides an
+/// \c invalidate member function.
+template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
+  typedef char SmallType;
+  struct BigType {
+    char a, b;
+  };
+
+  template <typename T, bool (T::*)(IRUnitT, const PreservedAnalyses &)>
+  struct Checker;
+
+  template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
+  template <typename T> static BigType f(...);
+
+public:
+  enum { Value = sizeof(f<ResultT>(nullptr)) == sizeof(SmallType) };
+};
+
+/// \brief Wrapper to model the analysis result concept.
+///
+/// By default, this will implement the invalidate method with a trivial
+/// implementation so that the actual analysis result doesn't need to provide
+/// an invalidation handler. It is only selected when the invalidation handler
+/// is not part of the ResultT's interface.
+template <typename IRUnitT, typename PassT, typename ResultT,
+          bool HasInvalidateHandler =
+              ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
+struct AnalysisResultModel;
+
+/// \brief Specialization of \c AnalysisResultModel which provides the default
+/// invalidate functionality.
+template <typename IRUnitT, typename PassT, typename ResultT>
+struct AnalysisResultModel<IRUnitT, PassT, ResultT, false>
+    : AnalysisResultConcept<IRUnitT> {
+  explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
+  AnalysisResultModel(AnalysisResultModel &&Arg)
+      : Result(std::move(Arg.Result)) {}
+  friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
+    using std::swap;
+    swap(LHS.Result, RHS.Result);
+  }
+  AnalysisResultModel &operator=(AnalysisResultModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief The model bases invalidation solely on being in the preserved set.
+  //
+  // FIXME: We should actually use two different concepts for analysis results
+  // rather than two different models, and avoid the indirect function call for
+  // ones that use the trivial behavior.
+  bool invalidate(IRUnitT, const PreservedAnalyses &PA) override {
+    return !PA.preserved(PassT::ID());
+  }
+
+  ResultT Result;
+};
+
+/// \brief Specialization of \c AnalysisResultModel which delegates invalidate
+/// handling to \c ResultT.
+template <typename IRUnitT, typename PassT, typename ResultT>
+struct AnalysisResultModel<IRUnitT, PassT, ResultT, true>
+    : AnalysisResultConcept<IRUnitT> {
+  explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
+  AnalysisResultModel(AnalysisResultModel &&Arg)
+      : Result(std::move(Arg.Result)) {}
+  friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
+    using std::swap;
+    swap(LHS.Result, RHS.Result);
+  }
+  AnalysisResultModel &operator=(AnalysisResultModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief The model delegates to the \c ResultT method.
+  bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
+    return Result.invalidate(IR, PA);
+  }
+
+  ResultT Result;
+};
+
+/// \brief Abstract concept of an analysis pass.
+///
+/// This concept is parameterized over the IR unit that it can run over and
+/// produce an analysis result.
+template <typename IRUnitT, typename AnalysisManagerT>
+struct AnalysisPassConcept {
+  virtual ~AnalysisPassConcept() {}
+
+  /// \brief Method to run this analysis over a unit of IR.
+  /// \returns A unique_ptr to the analysis result object to be queried by
+  /// users.
+  virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+  run(IRUnitT IR, AnalysisManagerT *AM) = 0;
+};
+
+/// \brief Wrapper to model the analysis pass concept.
+///
+/// Can wrap any type which implements a suitable \c run method. The method
+/// must accept the IRUnitT as an argument and produce an object which can be
+/// wrapped in a \c AnalysisResultModel.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+          bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
+              IRUnitT, AnalysisManagerT, PassT, typename PassT::Result>::Value>
+struct AnalysisPassModel;
+
+/// \brief Specialization of \c AnalysisPassModel which passes an
+/// \c AnalysisManager to PassT's run method.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, true>
+    : AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
+  explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
+  AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+  friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  AnalysisPassModel &operator=(AnalysisPassModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  // FIXME: Replace PassT::Result with type traits when we use C++11.
+  typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+      ResultModelT;
+
+  /// \brief The model delegates to the \c PassT::run method.
+  ///
+  /// The return is wrapped in an \c AnalysisResultModel.
+  std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+  run(IRUnitT IR, AnalysisManagerT *AM) override {
+    return make_unique<ResultModelT>(Pass.run(IR, AM));
+  }
+
+  PassT Pass;
+};
+
+/// \brief Specialization of \c AnalysisPassModel which does not pass an
+/// \c AnalysisManager to PassT's run method.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, false>
+    : AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
+  explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
+  AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+  friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  AnalysisPassModel &operator=(AnalysisPassModel RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  // FIXME: Replace PassT::Result with type traits when we use C++11.
+  typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+      ResultModelT;
+
+  /// \brief The model delegates to the \c PassT::run method.
+  ///
+  /// The return is wrapped in an \c AnalysisResultModel.
+  std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+  run(IRUnitT IR, AnalysisManagerT *) override {
+    return make_unique<ResultModelT>(Pass.run(IR));
+  }
+
+  PassT Pass;
+};
+
+} // End namespace detail
+
+class ModuleAnalysisManager;
+
+class ModulePassManager {
+public:
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModulePassManager() {}
+  ModulePassManager(ModulePassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
+  ModulePassManager &operator=(ModulePassManager &&RHS) {
+    Passes = std::move(RHS.Passes);
+    return *this;
+  }
+
+  /// \brief Run all of the module passes in this module pass manager over
+  /// a module.
+  ///
+  /// This method should only be called for a single module as there is the
+  /// expectation that the lifetime of a pass is bounded to that of a module.
+  PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = nullptr);
+
+  template <typename ModulePassT> void addPass(ModulePassT Pass) {
+    Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
+  }
+
+  static StringRef name() { return "ModulePassManager"; }
+
+private:
+  // Pull in the concept type and model template specialized for modules.
+  typedef detail::PassConcept<Module *, ModuleAnalysisManager>
+  ModulePassConcept;
+  template <typename PassT>
+  struct ModulePassModel
+      : detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
+    ModulePassModel(PassT Pass)
+        : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(
+              std::move(Pass)) {}
+  };
+
+  ModulePassManager(const ModulePassManager &) LLVM_DELETED_FUNCTION;
+  ModulePassManager &operator=(const ModulePassManager &) LLVM_DELETED_FUNCTION;
+
+  std::vector<std::unique_ptr<ModulePassConcept>> Passes;
+};
+
+class FunctionAnalysisManager;
+
+class FunctionPassManager {
+public:
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  FunctionPassManager() {}
+  FunctionPassManager(FunctionPassManager &&Arg)
+      : Passes(std::move(Arg.Passes)) {}
+  FunctionPassManager &operator=(FunctionPassManager &&RHS) {
+    Passes = std::move(RHS.Passes);
+    return *this;
+  }
+
+  template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
+    Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
+  }
+
+  PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = nullptr);
+
+  static StringRef name() { return "FunctionPassManager"; }
+
+private:
+  // Pull in the concept type and model template specialized for functions.
+  typedef detail::PassConcept<Function *, FunctionAnalysisManager>
+  FunctionPassConcept;
+  template <typename PassT>
+  struct FunctionPassModel
+      : detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
+    FunctionPassModel(PassT Pass)
+        : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(
+              std::move(Pass)) {}
+  };
+
+  FunctionPassManager(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
+  FunctionPassManager &
+  operator=(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
+
+  std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
+};
+
+namespace detail {
+
+/// \brief A CRTP base used to implement analysis managers.
+///
+/// This class template serves as the boiler plate of an analysis manager. Any
+/// analysis manager can be implemented on top of this base class. Any
+/// implementation will be required to provide specific hooks:
+///
+/// - getResultImpl
+/// - getCachedResultImpl
+/// - invalidateImpl
+///
+/// The details of the call pattern are within.
+template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
+  DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
+  const DerivedT *derived_this() const {
+    return static_cast<const DerivedT *>(this);
+  }
+
+  AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+  AnalysisManagerBase &
+  operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+
+protected:
+  typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
+  typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
+
+  // FIXME: Provide template aliases for the models when we're using C++11 in
+  // a mode supporting them.
+
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  AnalysisManagerBase() {}
+  AnalysisManagerBase(AnalysisManagerBase &&Arg)
+      : AnalysisPasses(std::move(Arg.AnalysisPasses)) {}
+  AnalysisManagerBase &operator=(AnalysisManagerBase &&RHS) {
+    AnalysisPasses = std::move(RHS.AnalysisPasses);
+    return *this;
+  }
+
+public:
+  /// \brief Get the result of an analysis pass for this module.
+  ///
+  /// If there is not a valid cached result in the manager already, this will
+  /// re-run the analysis to produce a valid result.
+  template <typename PassT> typename PassT::Result &getResult(IRUnitT IR) {
+    assert(AnalysisPasses.count(PassT::ID()) &&
+           "This analysis pass was not registered prior to being queried");
+
+    ResultConceptT &ResultConcept =
+        derived_this()->getResultImpl(PassT::ID(), IR);
+    typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+        ResultModelT;
+    return static_cast<ResultModelT &>(ResultConcept).Result;
+  }
+
+  /// \brief Get the cached result of an analysis pass for this module.
+  ///
+  /// This method never runs the analysis.
+  ///
+  /// \returns null if there is no cached result.
+  template <typename PassT>
+  typename PassT::Result *getCachedResult(IRUnitT IR) const {
+    assert(AnalysisPasses.count(PassT::ID()) &&
+           "This analysis pass was not registered prior to being queried");
+
+    ResultConceptT *ResultConcept =
+        derived_this()->getCachedResultImpl(PassT::ID(), IR);
+    if (!ResultConcept)
+      return nullptr;
+
+    typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+        ResultModelT;
+    return &static_cast<ResultModelT *>(ResultConcept)->Result;
+  }
+
+  /// \brief Register an analysis pass with the manager.
+  ///
+  /// This provides an initialized and set-up analysis pass to the analysis
+  /// manager. Whomever is setting up analysis passes must use this to populate
+  /// the manager with all of the analysis passes available.
+  template <typename PassT> void registerPass(PassT Pass) {
+    assert(!AnalysisPasses.count(PassT::ID()) &&
+           "Registered the same analysis pass twice!");
+    typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
+    AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
+  }
+
+  /// \brief Invalidate a specific analysis pass for an IR module.
+  ///
+  /// Note that the analysis result can disregard invalidation.
+  template <typename PassT> void invalidate(Module *M) {
+    assert(AnalysisPasses.count(PassT::ID()) &&
+           "This analysis pass was not registered prior to being invalidated");
+    derived_this()->invalidateImpl(PassT::ID(), M);
+  }
+
+  /// \brief Invalidate analyses cached for an IR unit.
+  ///
+  /// Walk through all of the analyses pertaining to this unit of IR and
+  /// invalidate them unless they are preserved by the PreservedAnalyses set.
+  void invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
+    derived_this()->invalidateImpl(IR, PA);
+  }
+
+protected:
+  /// \brief Lookup a registered analysis pass.
+  PassConceptT &lookupPass(void *PassID) {
+    typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
+    assert(PI != AnalysisPasses.end() &&
+           "Analysis passes must be registered prior to being queried!");
+    return *PI->second;
+  }
+
+  /// \brief Lookup a registered analysis pass.
+  const PassConceptT &lookupPass(void *PassID) const {
+    typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
+    assert(PI != AnalysisPasses.end() &&
+           "Analysis passes must be registered prior to being queried!");
+    return *PI->second;
+  }
+
+private:
+  /// \brief Map type from module analysis pass ID to pass concept pointer.
+  typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
+
+  /// \brief Collection of module analysis passes, indexed by ID.
+  AnalysisPassMapT AnalysisPasses;
+};
+
+} // End namespace detail
+
+/// \brief A module analysis pass manager with lazy running and caching of
+/// results.
+class ModuleAnalysisManager
+    : public detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> {
+  friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module *>;
+  typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> BaseT;
+  typedef BaseT::ResultConceptT ResultConceptT;
+  typedef BaseT::PassConceptT PassConceptT;
+
+public:
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModuleAnalysisManager() {}
+  ModuleAnalysisManager(ModuleAnalysisManager &&Arg)
+      : BaseT(std::move(static_cast<BaseT &>(Arg))),
+        ModuleAnalysisResults(std::move(Arg.ModuleAnalysisResults)) {}
+  ModuleAnalysisManager &operator=(ModuleAnalysisManager &&RHS) {
+    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+    ModuleAnalysisResults = std::move(RHS.ModuleAnalysisResults);
+    return *this;
+  }
+
+private:
+  ModuleAnalysisManager(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
+  ModuleAnalysisManager &
+  operator=(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
+
+  /// \brief Get a module pass result, running the pass if necessary.
+  ResultConceptT &getResultImpl(void *PassID, Module *M);
+
+  /// \brief Get a cached module pass result or return null.
+  ResultConceptT *getCachedResultImpl(void *PassID, Module *M) const;
+
+  /// \brief Invalidate a module pass result.
+  void invalidateImpl(void *PassID, Module *M);
+
+  /// \brief Invalidate results across a module.
+  void invalidateImpl(Module *M, const PreservedAnalyses &PA);
+
+  /// \brief Map type from module analysis pass ID to pass result concept
+  /// pointer.
+  typedef DenseMap<void *,
+                   std::unique_ptr<detail::AnalysisResultConcept<Module *>>>
+      ModuleAnalysisResultMapT;
+
+  /// \brief Cache of computed module analysis results for this module.
+  ModuleAnalysisResultMapT ModuleAnalysisResults;
+};
+
+/// \brief A function analysis manager to coordinate and cache analyses run over
+/// a module.
+class FunctionAnalysisManager
+    : public detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> {
+  friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>;
+  typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>
+      BaseT;
+  typedef BaseT::ResultConceptT ResultConceptT;
+  typedef BaseT::PassConceptT PassConceptT;
+
+public:
+  // Most public APIs are inherited from the CRTP base class.
+
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  FunctionAnalysisManager() {}
+  FunctionAnalysisManager(FunctionAnalysisManager &&Arg)
+      : BaseT(std::move(static_cast<BaseT &>(Arg))),
+        FunctionAnalysisResults(std::move(Arg.FunctionAnalysisResults)) {}
+  FunctionAnalysisManager &operator=(FunctionAnalysisManager &&RHS) {
+    BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+    FunctionAnalysisResults = std::move(RHS.FunctionAnalysisResults);
+    return *this;
+  }
+
+  /// \brief Returns true if the analysis manager has an empty results cache.
+  bool empty() const;
+
+  /// \brief Clear the function analysis result cache.
+  ///
+  /// This routine allows cleaning up when the set of functions itself has
+  /// potentially changed, and thus we can't even look up a a result and
+  /// invalidate it directly. Notably, this does *not* call invalidate
+  /// functions as there is nothing to be done for them.
+  void clear();
+
+private:
+  FunctionAnalysisManager(const FunctionAnalysisManager &)
+      LLVM_DELETED_FUNCTION;
+  FunctionAnalysisManager &
+  operator=(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;
+
+  /// \brief Get a function pass result, running the pass if necessary.
+  ResultConceptT &getResultImpl(void *PassID, Function *F);
+
+  /// \brief Get a cached function pass result or return null.
+  ResultConceptT *getCachedResultImpl(void *PassID, Function *F) const;
+
+  /// \brief Invalidate a function pass result.
+  void invalidateImpl(void *PassID, Function *F);
+
+  /// \brief Invalidate the results for a function..
+  void invalidateImpl(Function *F, const PreservedAnalyses &PA);
+
+  /// \brief List of function analysis pass IDs and associated concept pointers.
+  ///
+  /// Requires iterators to be valid across appending new entries and arbitrary
+  /// erases. Provides both the pass ID and concept pointer such that it is
+  /// half of a bijection and provides storage for the actual result concept.
+  typedef std::list<std::pair<
+      void *, std::unique_ptr<detail::AnalysisResultConcept<Function *>>>>
+          FunctionAnalysisResultListT;
+
+  /// \brief Map type from function pointer to our custom list type.
+  typedef DenseMap<Function *, FunctionAnalysisResultListT>
+      FunctionAnalysisResultListMapT;
+
+  /// \brief Map from function to a list of function analysis results.
+  ///
+  /// Provides linear time removal of all analysis results for a function and
+  /// the ultimate storage for a particular cached analysis result.
+  FunctionAnalysisResultListMapT FunctionAnalysisResultLists;
+
+  /// \brief Map type from a pair of analysis ID and function pointer to an
+  /// iterator into a particular result list.
+  typedef DenseMap<std::pair<void *, Function *>,
+                   FunctionAnalysisResultListT::iterator>
+      FunctionAnalysisResultMapT;
+
+  /// \brief Map from an analysis ID and function to a particular cached
+  /// analysis result.
+  FunctionAnalysisResultMapT FunctionAnalysisResults;
+};
+
+/// \brief A module analysis which acts as a proxy for a function analysis
+/// manager.
+///
+/// This primarily proxies invalidation information from the module analysis
+/// manager and module pass manager to a function analysis manager. You should
+/// never use a function analysis manager from within (transitively) a module
+/// pass manager unless your parent module pass has received a proxy result
+/// object for it.
+class FunctionAnalysisManagerModuleProxy {
+public:
+  class Result;
+
+  static void *ID() { return (void *)&PassID; }
+
+  explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
+      : FAM(&FAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  FunctionAnalysisManagerModuleProxy(
+      const FunctionAnalysisManagerModuleProxy &Arg)
+      : FAM(Arg.FAM) {}
+  FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
+      : FAM(std::move(Arg.FAM)) {}
+  FunctionAnalysisManagerModuleProxy &
+  operator=(FunctionAnalysisManagerModuleProxy RHS) {
+    std::swap(FAM, RHS.FAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  ///
+  /// This doesn't do any interesting work, it is primarily used to insert our
+  /// proxy result object into the module analysis cache so that we can proxy
+  /// invalidation to the function analysis manager.
+  ///
+  /// In debug builds, it will also assert that the analysis manager is empty
+  /// as no queries should arrive at the function analysis manager prior to
+  /// this analysis being requested.
+  Result run(Module *M);
+
+private:
+  static char PassID;
+
+  FunctionAnalysisManager *FAM;
+};
+
+/// \brief The result proxy object for the
+/// \c FunctionAnalysisManagerModuleProxy.
+///
+/// See its documentation for more information.
+class FunctionAnalysisManagerModuleProxy::Result {
+public:
+  explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  Result(const Result &Arg) : FAM(Arg.FAM) {}
+  Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
+  Result &operator=(Result RHS) {
+    std::swap(FAM, RHS.FAM);
+    return *this;
+  }
+  ~Result();
+
+  /// \brief Accessor for the \c FunctionAnalysisManager.
+  FunctionAnalysisManager &getManager() { return *FAM; }
+
+  /// \brief Handler for invalidation of the module.
+  ///
+  /// If this analysis itself is preserved, then we assume that the set of \c
+  /// Function objects in the \c Module hasn't changed and thus we don't need
+  /// to invalidate *all* cached data associated with a \c Function* in the \c
+  /// FunctionAnalysisManager.
+  ///
+  /// Regardless of whether this analysis is marked as preserved, all of the
+  /// analyses in the \c FunctionAnalysisManager are potentially invalidated
+  /// based on the set of preserved analyses.
+  bool invalidate(Module *M, const PreservedAnalyses &PA);
+
+private:
+  FunctionAnalysisManager *FAM;
+};
+
+/// \brief A function analysis which acts as a proxy for a module analysis
+/// manager.
+///
+/// This primarily provides an accessor to a parent module analysis manager to
+/// function passes. Only the const interface of the module analysis manager is
+/// provided to indicate that once inside of a function analysis pass you
+/// cannot request a module analysis to actually run. Instead, the user must
+/// rely on the \c getCachedResult API.
+///
+/// This proxy *doesn't* manage the invalidation in any way. That is handled by
+/// the recursive return path of each layer of the pass manager and the
+/// returned PreservedAnalysis set.
+class ModuleAnalysisManagerFunctionProxy {
+public:
+  /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+  class Result {
+  public:
+    explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+    // We have to explicitly define all the special member functions because
+    // MSVC refuses to generate them.
+    Result(const Result &Arg) : MAM(Arg.MAM) {}
+    Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
+    Result &operator=(Result RHS) {
+      std::swap(MAM, RHS.MAM);
+      return *this;
+    }
+
+    const ModuleAnalysisManager &getManager() const { return *MAM; }
+
+    /// \brief Handle invalidation by ignoring it, this pass is immutable.
+    bool invalidate(Function *) { return false; }
+
+  private:
+    const ModuleAnalysisManager *MAM;
+  };
+
+  static void *ID() { return (void *)&PassID; }
+
+  ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
+      : MAM(&MAM) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModuleAnalysisManagerFunctionProxy(
+      const ModuleAnalysisManagerFunctionProxy &Arg)
+      : MAM(Arg.MAM) {}
+  ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
+      : MAM(std::move(Arg.MAM)) {}
+  ModuleAnalysisManagerFunctionProxy &
+  operator=(ModuleAnalysisManagerFunctionProxy RHS) {
+    std::swap(MAM, RHS.MAM);
+    return *this;
+  }
+
+  /// \brief Run the analysis pass and create our proxy result object.
+  /// Nothing to see here, it just forwards the \c MAM reference into the
+  /// result.
+  Result run(Function *) { return Result(*MAM); }
+
+private:
+  static char PassID;
+
+  const ModuleAnalysisManager *MAM;
+};
+
+/// \brief Trivial adaptor that maps from a module to its functions.
+///
+/// Designed to allow composition of a FunctionPass(Manager) and
+/// a ModulePassManager. Note that if this pass is constructed with a pointer
+/// to a \c ModuleAnalysisManager it will run the
+/// \c FunctionAnalysisManagerModuleProxy analysis prior to running the function
+/// pass over the module to enable a \c FunctionAnalysisManager to be used
+/// within this run safely.
+template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
+public:
+  explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
+      : Pass(std::move(Pass)) {}
+  // We have to explicitly define all the special member functions because MSVC
+  // refuses to generate them.
+  ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)
+      : Pass(Arg.Pass) {}
+  ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)
+      : Pass(std::move(Arg.Pass)) {}
+  friend void swap(ModuleToFunctionPassAdaptor &LHS, ModuleToFunctionPassAdaptor &RHS) {
+    using std::swap;
+    swap(LHS.Pass, RHS.Pass);
+  }
+  ModuleToFunctionPassAdaptor &operator=(ModuleToFunctionPassAdaptor RHS) {
+    swap(*this, RHS);
+    return *this;
+  }
+
+  /// \brief Runs the function pass across every function in the module.
+  PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
+    FunctionAnalysisManager *FAM = nullptr;
+    if (AM)
+      // Setup the function analysis manager from its proxy.
+      FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+    PreservedAnalyses PA = PreservedAnalyses::all();
+    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+      PreservedAnalyses PassPA = Pass.run(I, FAM);
+
+      // We know that the function pass couldn't have invalidated any other
+      // function's analyses (that's the contract of a function pass), so
+      // directly handle the function analysis manager's invalidation here.
+      if (FAM)
+        FAM->invalidate(I, PassPA);
+
+      // Then intersect the preserved set so that invalidation of module
+      // analyses will eventually occur when the module pass completes.
+      PA.intersect(std::move(PassPA));
+    }
+
+    // By definition we preserve the proxy. This precludes *any* invalidation
+    // of function analyses by the proxy, but that's OK because we've taken
+    // care to invalidate analyses in the function analysis manager
+    // incrementally above.
+    PA.preserve<FunctionAnalysisManagerModuleProxy>();
+    return PA;
+  }
+
+  static StringRef name() { return "ModuleToFunctionPassAdaptor"; }
+
+private:
+  FunctionPassT Pass;
+};
+
+/// \brief A function to deduce a function pass type and wrap it in the
+/// templated adaptor.
+template <typename FunctionPassT>
+ModuleToFunctionPassAdaptor<FunctionPassT>
+createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
+  return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
+}
+
+}
+
+#endif
diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h
new file mode 100644
index 0000000..2efb294
--- /dev/null
+++ b/include/llvm/IR/PatternMatch.h
@@ -0,0 +1,1211 @@
+//===- PatternMatch.h - Match on the LLVM IR --------------------*- 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 a simple and efficient mechanism for performing general
+// tree-based pattern matches on the LLVM IR.  The power of these routines is
+// that it allows you to write concise patterns that are expressive and easy to
+// understand.  The other major advantage of this is that it allows you to
+// trivially capture/bind elements in the pattern to variables.  For example,
+// you can do something like this:
+//
+//  Value *Exp = ...
+//  Value *X, *Y;  ConstantInt *C1, *C2;      // (X & C1) | (Y & C2)
+//  if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
+//                      m_And(m_Value(Y), m_ConstantInt(C2))))) {
+//    ... Pattern is matched and variables are bound ...
+//  }
+//
+// This is primarily useful to things like the instruction combiner, but can
+// also be useful for static analysis tools or code generators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_PATTERNMATCH_H
+#define LLVM_IR_PATTERNMATCH_H
+
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Operator.h"
+
+namespace llvm {
+namespace PatternMatch {
+
+template<typename Val, typename Pattern>
+bool match(Val *V, const Pattern &P) {
+  return const_cast<Pattern&>(P).match(V);
+}
+
+
+template<typename SubPattern_t>
+struct OneUse_match {
+  SubPattern_t SubPattern;
+
+  OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    return V->hasOneUse() && SubPattern.match(V);
+  }
+};
+
+template<typename T>
+inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; }
+
+
+template<typename Class>
+struct class_match {
+  template<typename ITy>
+  bool match(ITy *V) { return isa<Class>(V); }
+};
+
+/// m_Value() - Match an arbitrary value and ignore it.
+inline class_match<Value> m_Value() { return class_match<Value>(); }
+/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
+inline class_match<ConstantInt> m_ConstantInt() {
+  return class_match<ConstantInt>();
+}
+/// m_Undef() - Match an arbitrary undef constant.
+inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
+
+inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+
+/// Matching combinators
+template<typename LTy, typename RTy>
+struct match_combine_or {
+  LTy L;
+  RTy R;
+
+  match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (L.match(V))
+      return true;
+    if (R.match(V))
+      return true;
+    return false;
+  }
+};
+
+template<typename LTy, typename RTy>
+struct match_combine_and {
+  LTy L;
+  RTy R;
+
+  match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) { }
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (L.match(V))
+      if (R.match(V))
+        return true;
+    return false;
+  }
+};
+
+/// Combine two pattern matchers matching L || R
+template<typename LTy, typename RTy>
+inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) {
+  return match_combine_or<LTy, RTy>(L, R);
+}
+
+/// Combine two pattern matchers matching L && R
+template<typename LTy, typename RTy>
+inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
+  return match_combine_and<LTy, RTy>(L, R);
+}
+
+struct match_zero {
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const Constant *C = dyn_cast<Constant>(V))
+      return C->isNullValue();
+    return false;
+  }
+};
+
+/// m_Zero() - Match an arbitrary zero/null constant.  This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers.
+inline match_zero m_Zero() { return match_zero(); }
+
+struct match_neg_zero {
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const Constant *C = dyn_cast<Constant>(V))
+      return C->isNegativeZeroValue();
+    return false;
+  }
+};
+
+/// m_NegZero() - Match an arbitrary zero/null constant.  This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero but not positive
+/// zero
+inline match_neg_zero m_NegZero() { return match_neg_zero(); }
+
+/// m_AnyZero() - Match an arbitrary zero/null constant.  This includes
+/// zero_initializer for vectors and ConstantPointerNull for pointers. For
+/// floating point constants, this will match negative zero and positive zero
+inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() {
+  return m_CombineOr(m_Zero(), m_NegZero());
+}
+
+struct apint_match {
+  const APInt *&Res;
+  apint_match(const APInt *&R) : Res(R) {}
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      Res = &CI->getValue();
+      return true;
+    }
+    if (V->getType()->isVectorTy())
+      if (const Constant *C = dyn_cast<Constant>(V))
+        if (ConstantInt *CI =
+            dyn_cast_or_null<ConstantInt>(C->getSplatValue())) {
+          Res = &CI->getValue();
+          return true;
+        }
+    return false;
+  }
+};
+
+/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the
+/// specified pointer to the contained APInt.
+inline apint_match m_APInt(const APInt *&Res) { return Res; }
+
+
+template<int64_t Val>
+struct constantint_match {
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      const APInt &CIV = CI->getValue();
+      if (Val >= 0)
+        return CIV == static_cast<uint64_t>(Val);
+      // If Val is negative, and CI is shorter than it, truncate to the right
+      // number of bits.  If it is larger, then we have to sign extend.  Just
+      // compare their negated values.
+      return -CIV == -Val;
+    }
+    return false;
+  }
+};
+
+/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value.
+template<int64_t Val>
+inline constantint_match<Val> m_ConstantInt() {
+  return constantint_match<Val>();
+}
+
+/// cst_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate.
+template<typename Predicate>
+struct cst_pred_ty : public Predicate {
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+      return this->isValue(CI->getValue());
+    if (V->getType()->isVectorTy())
+      if (const Constant *C = dyn_cast<Constant>(V))
+        if (const ConstantInt *CI =
+            dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+          return this->isValue(CI->getValue());
+    return false;
+  }
+};
+
+/// api_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate, and bind them to an APInt.
+template<typename Predicate>
+struct api_pred_ty : public Predicate {
+  const APInt *&Res;
+  api_pred_ty(const APInt *&R) : Res(R) {}
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+      if (this->isValue(CI->getValue())) {
+        Res = &CI->getValue();
+        return true;
+      }
+    if (V->getType()->isVectorTy())
+      if (const Constant *C = dyn_cast<Constant>(V))
+        if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
+          if (this->isValue(CI->getValue())) {
+            Res = &CI->getValue();
+            return true;
+          }
+
+    return false;
+  }
+};
+
+
+struct is_one {
+  bool isValue(const APInt &C) { return C == 1; }
+};
+
+/// m_One() - Match an integer 1 or a vector with all elements equal to 1.
+inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); }
+inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; }
+
+struct is_all_ones {
+  bool isValue(const APInt &C) { return C.isAllOnesValue(); }
+};
+
+/// m_AllOnes() - Match an integer or vector with all bits set to true.
+inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();}
+inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; }
+
+struct is_sign_bit {
+  bool isValue(const APInt &C) { return C.isSignBit(); }
+};
+
+/// m_SignBit() - Match an integer or vector with only the sign bit(s) set.
+inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();}
+inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
+
+struct is_power2 {
+  bool isValue(const APInt &C) { return C.isPowerOf2(); }
+};
+
+/// m_Power2() - Match an integer or vector power of 2.
+inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
+inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
+
+template<typename Class>
+struct bind_ty {
+  Class *&VR;
+  bind_ty(Class *&V) : VR(V) {}
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (Class *CV = dyn_cast<Class>(V)) {
+      VR = CV;
+      return true;
+    }
+    return false;
+  }
+};
+
+/// m_Value - Match a value, capturing it if we match.
+inline bind_ty<Value> m_Value(Value *&V) { return V; }
+
+/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
+inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+
+/// m_Constant - Match a Constant, capturing the value if we match.
+inline bind_ty<Constant> m_Constant(Constant *&C) { return C; }
+
+/// m_ConstantFP - Match a ConstantFP, capturing the value if we match.
+inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
+
+/// specificval_ty - Match a specified Value*.
+struct specificval_ty {
+  const Value *Val;
+  specificval_ty(const Value *V) : Val(V) {}
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    return V == Val;
+  }
+};
+
+/// m_Specific - Match if we have a specific specified value.
+inline specificval_ty m_Specific(const Value *V) { return V; }
+
+/// Match a specified floating point value or vector of all elements of that
+/// value.
+struct specific_fpval {
+  double Val;
+  specific_fpval(double V) : Val(V) {}
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V))
+      return CFP->isExactlyValue(Val);
+    if (V->getType()->isVectorTy())
+      if (const Constant *C = dyn_cast<Constant>(V))
+        if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
+          return CFP->isExactlyValue(Val);
+    return false;
+  }
+};
+
+/// Match a specific floating point value or vector with all elements equal to
+/// the value.
+inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); }
+
+/// Match a float 1.0 or vector with all elements equal to 1.0.
+inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
+
+struct bind_const_intval_ty {
+  uint64_t &VR;
+  bind_const_intval_ty(uint64_t &V) : VR(V) {}
+
+  template<typename ITy>
+  bool match(ITy *V) {
+    if (ConstantInt *CV = dyn_cast<ConstantInt>(V))
+      if (CV->getBitWidth() <= 64) {
+        VR = CV->getZExtValue();
+        return true;
+      }
+    return false;
+  }
+};
+
+/// m_ConstantInt - Match a ConstantInt and bind to its value.  This does not
+/// match ConstantInts wider than 64-bits.
+inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }
+
+//===----------------------------------------------------------------------===//
+// Matchers for specific binary operators.
+//
+
+template<typename LHS_t, typename RHS_t, unsigned Opcode>
+struct BinaryOp_match {
+  LHS_t L;
+  RHS_t R;
+
+  BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (V->getValueID() == Value::InstructionVal + Opcode) {
+      BinaryOperator *I = cast<BinaryOperator>(V);
+      return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+    }
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+      return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+             R.match(CE->getOperand(1));
+    return false;
+  }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add>
+m_Add(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FAdd>
+m_FAdd(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Sub>
+m_Sub(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FSub>
+m_FSub(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul>
+m_Mul(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FMul>
+m_FMul(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv>
+m_UDiv(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv>
+m_SDiv(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv>
+m_FDiv(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::URem>
+m_URem(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SRem>
+m_SRem(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FRem>
+m_FRem(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And>
+m_And(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or>
+m_Or(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor>
+m_Xor(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Shl>
+m_Shl(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::LShr>
+m_LShr(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::AShr>
+m_AShr(const LHS &L, const RHS &R) {
+  return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
+}
+
+template<typename LHS_t, typename RHS_t, unsigned Opcode, unsigned WrapFlags = 0>
+struct OverflowingBinaryOp_match {
+  LHS_t L;
+  RHS_t R;
+
+  OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (OverflowingBinaryOperator *Op = dyn_cast<OverflowingBinaryOperator>(V)) {
+      if (Op->getOpcode() != Opcode)
+        return false;
+      if (WrapFlags & OverflowingBinaryOperator::NoUnsignedWrap &&
+          !Op->hasNoUnsignedWrap())
+        return false;
+      if (WrapFlags & OverflowingBinaryOperator::NoSignedWrap &&
+          !Op->hasNoSignedWrap())
+        return false;
+      return L.match(Op->getOperand(0)) && R.match(Op->getOperand(1));
+    }
+    return false;
+  }
+};
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+                                 OverflowingBinaryOperator::NoSignedWrap>
+m_NSWAdd(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+                                   OverflowingBinaryOperator::NoSignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+                                 OverflowingBinaryOperator::NoSignedWrap>
+m_NSWSub(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+                                   OverflowingBinaryOperator::NoSignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+                                 OverflowingBinaryOperator::NoSignedWrap>
+m_NSWMul(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+                                   OverflowingBinaryOperator::NoSignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+                                 OverflowingBinaryOperator::NoSignedWrap>
+m_NSWShl(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+                                   OverflowingBinaryOperator::NoSignedWrap>(
+      L, R);
+}
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+                                 OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWAdd(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+                                   OverflowingBinaryOperator::NoUnsignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+                                 OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWSub(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+                                   OverflowingBinaryOperator::NoUnsignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+                                 OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWMul(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+                                   OverflowingBinaryOperator::NoUnsignedWrap>(
+      L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+                                 OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWShl(const LHS &L, const RHS &R) {
+  return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+                                   OverflowingBinaryOperator::NoUnsignedWrap>(
+      L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Class that matches two different binary ops.
+//
+template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
+struct BinOp2_match {
+  LHS_t L;
+  RHS_t R;
+
+  BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (V->getValueID() == Value::InstructionVal + Opc1 ||
+        V->getValueID() == Value::InstructionVal + Opc2) {
+      BinaryOperator *I = cast<BinaryOperator>(V);
+      return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+    }
+    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+      return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
+             L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
+    return false;
+  }
+};
+
+/// m_Shr - Matches LShr or AShr.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
+m_Shr(const LHS &L, const RHS &R) {
+  return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
+}
+
+/// m_LogicalShift - Matches LShr or Shl.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
+m_LogicalShift(const LHS &L, const RHS &R) {
+  return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
+}
+
+/// m_IDiv - Matches UDiv and SDiv.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
+m_IDiv(const LHS &L, const RHS &R) {
+  return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Class that matches exact binary ops.
+//
+template<typename SubPattern_t>
+struct Exact_match {
+  SubPattern_t SubPattern;
+
+  Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V))
+      return PEO->isExact() && SubPattern.match(V);
+    return false;
+  }
+};
+
+template<typename T>
+inline Exact_match<T> m_Exact(const T &SubPattern) { return SubPattern; }
+
+//===----------------------------------------------------------------------===//
+// Matchers for CmpInst classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct CmpClass_match {
+  PredicateTy &Predicate;
+  LHS_t L;
+  RHS_t R;
+
+  CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
+    : Predicate(Pred), L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Class *I = dyn_cast<Class>(V))
+      if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+        Predicate = I->getPredicate();
+        return true;
+      }
+    return false;
+  }
+};
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+  return CmpClass_match<LHS, RHS,
+                        ICmpInst, ICmpInst::Predicate>(Pred, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+  return CmpClass_match<LHS, RHS,
+                        FCmpInst, FCmpInst::Predicate>(Pred, L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for SelectInst classes
+//
+
+template<typename Cond_t, typename LHS_t, typename RHS_t>
+struct SelectClass_match {
+  Cond_t C;
+  LHS_t L;
+  RHS_t R;
+
+  SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
+                    const RHS_t &RHS)
+    : C(Cond), L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (SelectInst *I = dyn_cast<SelectInst>(V))
+      return C.match(I->getOperand(0)) &&
+             L.match(I->getOperand(1)) &&
+             R.match(I->getOperand(2));
+    return false;
+  }
+};
+
+template<typename Cond, typename LHS, typename RHS>
+inline SelectClass_match<Cond, LHS, RHS>
+m_Select(const Cond &C, const LHS &L, const RHS &R) {
+  return SelectClass_match<Cond, LHS, RHS>(C, L, R);
+}
+
+/// m_SelectCst - This matches a select of two constants, e.g.:
+///    m_SelectCst<-1, 0>(m_Value(V))
+template<int64_t L, int64_t R, typename Cond>
+inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> >
+m_SelectCst(const Cond &C) {
+  return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for CastInst classes
+//
+
+template<typename Op_t, unsigned Opcode>
+struct CastClass_match {
+  Op_t Op;
+
+  CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Operator *O = dyn_cast<Operator>(V))
+      return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
+    return false;
+  }
+};
+
+/// m_BitCast
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::BitCast>
+m_BitCast(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::BitCast>(Op);
+}
+
+/// m_PtrToInt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::PtrToInt>
+m_PtrToInt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
+}
+
+/// m_Trunc
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::Trunc>
+m_Trunc(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::Trunc>(Op);
+}
+
+/// m_SExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SExt>
+m_SExt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::SExt>(Op);
+}
+
+/// m_ZExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::ZExt>
+m_ZExt(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::ZExt>(Op);
+}
+
+/// m_UIToFP
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::UIToFP>
+m_UIToFP(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::UIToFP>(Op);
+}
+
+/// m_SIToFP
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SIToFP>
+m_SIToFP(const OpTy &Op) {
+  return CastClass_match<OpTy, Instruction::SIToFP>(Op);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for unary operators
+//
+
+template<typename LHS_t>
+struct not_match {
+  LHS_t L;
+
+  not_match(const LHS_t &LHS) : L(LHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Operator *O = dyn_cast<Operator>(V))
+      if (O->getOpcode() == Instruction::Xor)
+        return matchIfNot(O->getOperand(0), O->getOperand(1));
+    return false;
+  }
+private:
+  bool matchIfNot(Value *LHS, Value *RHS) {
+    return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) ||
+            // FIXME: Remove CV.
+            isa<ConstantVector>(RHS)) &&
+           cast<Constant>(RHS)->isAllOnesValue() &&
+           L.match(LHS);
+  }
+};
+
+template<typename LHS>
+inline not_match<LHS> m_Not(const LHS &L) { return L; }
+
+
+template<typename LHS_t>
+struct neg_match {
+  LHS_t L;
+
+  neg_match(const LHS_t &LHS) : L(LHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Operator *O = dyn_cast<Operator>(V))
+      if (O->getOpcode() == Instruction::Sub)
+        return matchIfNeg(O->getOperand(0), O->getOperand(1));
+    return false;
+  }
+private:
+  bool matchIfNeg(Value *LHS, Value *RHS) {
+    return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) ||
+            isa<ConstantAggregateZero>(LHS)) &&
+           L.match(RHS);
+  }
+};
+
+/// m_Neg - Match an integer negate.
+template<typename LHS>
+inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
+
+
+template<typename LHS_t>
+struct fneg_match {
+  LHS_t L;
+
+  fneg_match(const LHS_t &LHS) : L(LHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (Operator *O = dyn_cast<Operator>(V))
+      if (O->getOpcode() == Instruction::FSub)
+        return matchIfFNeg(O->getOperand(0), O->getOperand(1));
+    return false;
+  }
+private:
+  bool matchIfFNeg(Value *LHS, Value *RHS) {
+    if (ConstantFP *C = dyn_cast<ConstantFP>(LHS))
+      return C->isNegativeZeroValue() && L.match(RHS);
+    return false;
+  }
+};
+
+/// m_FNeg - Match a floating point negate.
+template<typename LHS>
+inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for control flow.
+//
+
+struct br_match {
+  BasicBlock *&Succ;
+  br_match(BasicBlock *&Succ)
+    : Succ(Succ) {
+  }
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (BranchInst *BI = dyn_cast<BranchInst>(V))
+      if (BI->isUnconditional()) {
+        Succ = BI->getSuccessor(0);
+        return true;
+      }
+    return false;
+  }
+};
+
+inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
+
+template<typename Cond_t>
+struct brc_match {
+  Cond_t Cond;
+  BasicBlock *&T, *&F;
+  brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
+    : Cond(C), T(t), F(f) {
+  }
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    if (BranchInst *BI = dyn_cast<BranchInst>(V))
+      if (BI->isConditional() && Cond.match(BI->getCondition())) {
+        T = BI->getSuccessor(0);
+        F = BI->getSuccessor(1);
+        return true;
+      }
+    return false;
+  }
+};
+
+template<typename Cond_t>
+inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
+  return brc_match<Cond_t>(C, T, F);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
+//
+
+template<typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t>
+struct MaxMin_match {
+  LHS_t L;
+  RHS_t R;
+
+  MaxMin_match(const LHS_t &LHS, const RHS_t &RHS)
+    : L(LHS), R(RHS) {}
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
+    SelectInst *SI = dyn_cast<SelectInst>(V);
+    if (!SI)
+      return false;
+    CmpInst_t *Cmp = dyn_cast<CmpInst_t>(SI->getCondition());
+    if (!Cmp)
+      return false;
+    // At this point we have a select conditioned on a comparison.  Check that
+    // it is the values returned by the select that are being compared.
+    Value *TrueVal = SI->getTrueValue();
+    Value *FalseVal = SI->getFalseValue();
+    Value *LHS = Cmp->getOperand(0);
+    Value *RHS = Cmp->getOperand(1);
+    if ((TrueVal != LHS || FalseVal != RHS) &&
+        (TrueVal != RHS || FalseVal != LHS))
+      return false;
+    typename CmpInst_t::Predicate Pred = LHS == TrueVal ?
+      Cmp->getPredicate() : Cmp->getSwappedPredicate();
+    // Does "(x pred y) ? x : y" represent the desired max/min operation?
+    if (!Pred_t::match(Pred))
+      return false;
+    // It does!  Bind the operands.
+    return L.match(LHS) && R.match(RHS);
+  }
+};
+
+/// smax_pred_ty - Helper class for identifying signed max predicates.
+struct smax_pred_ty {
+  static bool match(ICmpInst::Predicate Pred) {
+    return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
+  }
+};
+
+/// smin_pred_ty - Helper class for identifying signed min predicates.
+struct smin_pred_ty {
+  static bool match(ICmpInst::Predicate Pred) {
+    return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE;
+  }
+};
+
+/// umax_pred_ty - Helper class for identifying unsigned max predicates.
+struct umax_pred_ty {
+  static bool match(ICmpInst::Predicate Pred) {
+    return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE;
+  }
+};
+
+/// umin_pred_ty - Helper class for identifying unsigned min predicates.
+struct umin_pred_ty {
+  static bool match(ICmpInst::Predicate Pred) {
+    return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE;
+  }
+};
+
+/// ofmax_pred_ty - Helper class for identifying ordered max predicates.
+struct ofmax_pred_ty {
+  static bool match(FCmpInst::Predicate Pred) {
+    return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE;
+  }
+};
+
+/// ofmin_pred_ty - Helper class for identifying ordered min predicates.
+struct ofmin_pred_ty {
+  static bool match(FCmpInst::Predicate Pred) {
+    return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE;
+  }
+};
+
+/// ufmax_pred_ty - Helper class for identifying unordered max predicates.
+struct ufmax_pred_ty {
+  static bool match(FCmpInst::Predicate Pred) {
+    return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE;
+  }
+};
+
+/// ufmin_pred_ty - Helper class for identifying unordered min predicates.
+struct ufmin_pred_ty {
+  static bool match(FCmpInst::Predicate Pred) {
+    return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE;
+  }
+};
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>
+m_SMax(const LHS &L, const RHS &R) {
+  return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>
+m_SMin(const LHS &L, const RHS &R) {
+  return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>
+m_UMax(const LHS &L, const RHS &R) {
+  return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>
+m_UMin(const LHS &L, const RHS &R) {
+  return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R);
+}
+
+/// \brief Match an 'ordered' floating point maximum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate.
+///
+///                         max(L, R)  iff L and R are not NaN
+///  m_OrdFMax(L, R) =      R          iff L or R are NaN
+template<typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>
+m_OrdFMax(const LHS &L, const RHS &R) {
+  return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R);
+}
+
+/// \brief Match an 'ordered' floating point minimum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
+///
+///                         max(L, R)  iff L and R are not NaN
+///  m_OrdFMin(L, R) =      R          iff L or R are NaN
+template<typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>
+m_OrdFMin(const LHS &L, const RHS &R) {
+  return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R);
+}
+
+/// \brief Match an 'unordered' floating point maximum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
+///
+///                         max(L, R)  iff L and R are not NaN
+///  m_UnordFMin(L, R) =    L          iff L or R are NaN
+template<typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
+m_UnordFMax(const LHS &L, const RHS &R) {
+  return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
+}
+
+/// \brief Match an 'unordered' floating point minimum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
+///
+///                          max(L, R)  iff L and R are not NaN
+///  m_UnordFMin(L, R) =     L          iff L or R are NaN
+template<typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
+m_UnordFMin(const LHS &L, const RHS &R) {
+  return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
+}
+
+template<typename Opnd_t>
+struct Argument_match {
+  unsigned OpI;
+  Opnd_t Val;
+  Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { }
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    CallSite CS(V);
+    return CS.isCall() && Val.match(CS.getArgument(OpI));
+  }
+};
+
+/// Match an argument
+template<unsigned OpI, typename Opnd_t>
+inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
+  return Argument_match<Opnd_t>(OpI, Op);
+}
+
+/// Intrinsic matchers.
+struct IntrinsicID_match {
+  unsigned ID;
+  IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) { }
+
+  template<typename OpTy>
+  bool match(OpTy *V) {
+    IntrinsicInst *II = dyn_cast<IntrinsicInst>(V);
+    return II && II->getIntrinsicID() == ID;
+  }
+};
+
+/// Intrinsic matches are combinations of ID matchers, and argument
+/// matchers. Higher arity matcher are defined recursively in terms of and-ing
+/// them with lower arity matchers. Here's some convenient typedefs for up to
+/// several arguments, and more can be added as needed
+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, typename T10 = void> struct m_Intrinsic_Ty;
+template <typename T0>
+struct m_Intrinsic_Ty<T0> {
+  typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty;
+};
+template <typename T0, typename T1>
+struct m_Intrinsic_Ty<T0, T1> {
+  typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty,
+                            Argument_match<T1> > Ty;
+};
+template <typename T0, typename T1, typename T2>
+struct m_Intrinsic_Ty<T0, T1, T2> {
+  typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
+                            Argument_match<T2> > Ty;
+};
+template <typename T0, typename T1, typename T2, typename T3>
+struct m_Intrinsic_Ty<T0, T1, T2, T3> {
+  typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
+                            Argument_match<T3> > Ty;
+};
+
+/// Match intrinsic calls like this:
+///   m_Intrinsic<Intrinsic::fabs>(m_Value(X))
+template <Intrinsic::ID IntrID>
+inline IntrinsicID_match
+m_Intrinsic() { return IntrinsicID_match(IntrID); }
+
+template<Intrinsic::ID IntrID, typename T0>
+inline typename m_Intrinsic_Ty<T0>::Ty
+m_Intrinsic(const T0 &Op0) {
+  return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0));
+}
+
+template<Intrinsic::ID IntrID, typename T0, typename T1>
+inline typename m_Intrinsic_Ty<T0, T1>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1) {
+  return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1));
+}
+
+template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2>
+inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) {
+  return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2));
+}
+
+template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2, typename T3>
+inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) {
+  return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3));
+}
+
+// Helper intrinsic matching specializations
+template<typename Opnd0>
+inline typename m_Intrinsic_Ty<Opnd0>::Ty
+m_BSwap(const Opnd0 &Op0) {
+  return m_Intrinsic<Intrinsic::bswap>(Op0);
+}
+
+} // end namespace PatternMatch
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/PredIteratorCache.h b/include/llvm/IR/PredIteratorCache.h
new file mode 100644
index 0000000..02bc583
--- /dev/null
+++ b/include/llvm/IR/PredIteratorCache.h
@@ -0,0 +1,70 @@
+//===- PredIteratorCache.h - pred_iterator Cache ----------------*- 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 PredIteratorCache class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/Support/Allocator.h"
+
+#ifndef LLVM_IR_PREDITERATORCACHE_H
+#define LLVM_IR_PREDITERATORCACHE_H
+
+namespace llvm {
+
+  /// PredIteratorCache - This class is an extremely trivial cache for
+  /// predecessor iterator queries.  This is useful for code that repeatedly
+  /// wants the predecessor list for the same blocks.
+  class PredIteratorCache {
+    /// BlockToPredsMap - Pointer to null-terminated list.
+    DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
+    DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
+
+    /// Memory - This is the space that holds cached preds.
+    BumpPtrAllocator Memory;
+  public:
+
+    /// GetPreds - Get a cached list for the null-terminated predecessor list of
+    /// the specified block.  This can be used in a loop like this:
+    ///   for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
+    ///      use(*PI);
+    /// instead of:
+    /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
+    BasicBlock **GetPreds(BasicBlock *BB) {
+      BasicBlock **&Entry = BlockToPredsMap[BB];
+      if (Entry) return Entry;
+
+      SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
+      PredCache.push_back(nullptr); // null terminator.
+      
+      BlockToPredCountMap[BB] = PredCache.size()-1;
+
+      Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
+      std::copy(PredCache.begin(), PredCache.end(), Entry);
+      return Entry;
+    }
+    
+    unsigned GetNumPreds(BasicBlock *BB) {
+      GetPreds(BB);
+      return BlockToPredCountMap[BB];
+    }
+
+    /// clear - Remove all information.
+    void clear() {
+      BlockToPredsMap.clear();
+      BlockToPredCountMap.clear();
+      Memory.Reset();
+    }
+  };
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h
new file mode 100644
index 0000000..0a5149c
--- /dev/null
+++ b/include/llvm/IR/SymbolTableListTraits.h
@@ -0,0 +1,78 @@
+//===-- llvm/SymbolTableListTraits.h - Traits for iplist --------*- 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 generic class that is used to implement the automatic
+// symbol table manipulation that occurs when you put (for example) a named
+// instruction into a basic block.
+//
+// The way that this is implemented is by using a special traits class with the
+// intrusive list that makes up the list of instructions in a basic block.  When
+// a new element is added to the list of instructions, the traits class is
+// notified, allowing the symbol table to be updated.
+//
+// This generic class implements the traits class.  It must be generic so that
+// it can work for all uses it, which include lists of instructions, basic
+// blocks, arguments, functions, global variables, etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H
+#define LLVM_IR_SYMBOLTABLELISTTRAITS_H
+
+#include "llvm/ADT/ilist.h"
+
+namespace llvm {
+class ValueSymbolTable;
+  
+template<typename NodeTy> class ilist_iterator;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename Ty> struct ilist_traits;
+
+// ValueSubClass   - The type of objects that I hold, e.g. Instruction.
+// ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
+//
+template<typename ValueSubClass, typename ItemParentClass>
+class SymbolTableListTraits : public ilist_default_traits<ValueSubClass> {
+  typedef ilist_traits<ValueSubClass> TraitsClass;
+public:
+  SymbolTableListTraits() {}
+
+  /// getListOwner - Return the object that owns this list.  If this is a list
+  /// of instructions, it returns the BasicBlock that owns them.
+  ItemParentClass *getListOwner() {
+    size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
+                           getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
+    iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this));
+    return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
+                                              Offset);
+  }
+
+  static iplist<ValueSubClass> &getList(ItemParentClass *Par) {
+    return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
+  }
+
+  static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
+    return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
+  }
+
+  void addNodeToList(ValueSubClass *V);
+  void removeNodeFromList(ValueSubClass *V);
+  void transferNodesFromList(ilist_traits<ValueSubClass> &L2,
+                             ilist_iterator<ValueSubClass> first,
+                             ilist_iterator<ValueSubClass> last);
+//private:
+  template<typename TPtr>
+  void setSymTabObject(TPtr *, TPtr);
+  static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
+  static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
new file mode 100644
index 0000000..7955587
--- /dev/null
+++ b/include/llvm/IR/Type.h
@@ -0,0 +1,485 @@
+//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Type class.  For more "Type"
+// stuff, look in DerivedTypes.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_TYPE_H
+#define LLVM_IR_TYPE_H
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class PointerType;
+class IntegerType;
+class raw_ostream;
+class Module;
+class LLVMContext;
+class LLVMContextImpl;
+class StringRef;
+template<class GraphType> struct GraphTraits;
+
+/// The instances of the Type class are immutable: once they are created,
+/// they are never changed.  Also note that only one instance of a particular
+/// type is ever created.  Thus seeing if two types are equal is a matter of
+/// doing a trivial pointer comparison. To enforce that no two equal instances
+/// are created, Type instances can only be created via static factory methods 
+/// in class Type and in derived classes.  Once allocated, Types are never
+/// free'd.
+/// 
+class Type {
+public:
+  //===--------------------------------------------------------------------===//
+  /// Definitions of all of the base types for the Type system.  Based on this
+  /// value, you can cast to a class defined in DerivedTypes.h.
+  /// Note: If you add an element to this, you need to add an element to the
+  /// Type::getPrimitiveType function, or else things will break!
+  /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
+  ///
+  enum TypeID {
+    // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date.
+    VoidTyID = 0,    ///<  0: type with no size
+    HalfTyID,        ///<  1: 16-bit floating point type
+    FloatTyID,       ///<  2: 32-bit floating point type
+    DoubleTyID,      ///<  3: 64-bit floating point type
+    X86_FP80TyID,    ///<  4: 80-bit floating point type (X87)
+    FP128TyID,       ///<  5: 128-bit floating point type (112-bit mantissa)
+    PPC_FP128TyID,   ///<  6: 128-bit floating point type (two 64-bits, PowerPC)
+    LabelTyID,       ///<  7: Labels
+    MetadataTyID,    ///<  8: Metadata
+    X86_MMXTyID,     ///<  9: MMX vectors (64 bits, X86 specific)
+
+    // Derived types... see DerivedTypes.h file.
+    // Make sure FirstDerivedTyID stays up to date!
+    IntegerTyID,     ///< 10: Arbitrary bit width integers
+    FunctionTyID,    ///< 11: Functions
+    StructTyID,      ///< 12: Structures
+    ArrayTyID,       ///< 13: Arrays
+    PointerTyID,     ///< 14: Pointers
+    VectorTyID       ///< 15: SIMD 'packed' format, or other vector type
+  };
+
+private:
+  /// Context - This refers to the LLVMContext in which this type was uniqued.
+  LLVMContext &Context;
+
+  // Due to Ubuntu GCC bug 910363:
+  // https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/910363
+  // Bitpack ID and SubclassData manually.
+  // Note: TypeID : low 8 bit; SubclassData : high 24 bit.
+  uint32_t IDAndSubclassData;
+
+protected:
+  friend class LLVMContextImpl;
+  explicit Type(LLVMContext &C, TypeID tid)
+    : Context(C), IDAndSubclassData(0),
+      NumContainedTys(0), ContainedTys(nullptr) {
+    setTypeID(tid);
+  }
+  ~Type() {}
+  
+  void setTypeID(TypeID ID) {
+    IDAndSubclassData = (ID & 0xFF) | (IDAndSubclassData & 0xFFFFFF00);
+    assert(getTypeID() == ID && "TypeID data too large for field");
+  }
+  
+  unsigned getSubclassData() const { return IDAndSubclassData >> 8; }
+  
+  void setSubclassData(unsigned val) {
+    IDAndSubclassData = (IDAndSubclassData & 0xFF) | (val << 8);
+    // Ensure we don't have any accidental truncation.
+    assert(getSubclassData() == val && "Subclass data too large for field");
+  }
+
+  /// NumContainedTys - Keeps track of how many Type*'s there are in the
+  /// ContainedTys list.
+  unsigned NumContainedTys;
+
+  /// ContainedTys - A pointer to the array of Types contained by this Type.
+  /// For example, this includes the arguments of a function type, the elements
+  /// of a structure, the pointee of a pointer, the element type of an array,
+  /// etc.  This pointer may be 0 for types that don't contain other types
+  /// (Integer, Double, Float).
+  Type * const *ContainedTys;
+
+public:
+  void print(raw_ostream &O) const;
+  void dump() const;
+
+  /// getContext - Return the LLVMContext in which this type was uniqued.
+  LLVMContext &getContext() const { return Context; }
+
+  //===--------------------------------------------------------------------===//
+  // Accessors for working with types.
+  //
+
+  /// getTypeID - Return the type id for the type.  This will return one
+  /// of the TypeID enum elements defined above.
+  ///
+  TypeID getTypeID() const { return (TypeID)(IDAndSubclassData & 0xFF); }
+
+  /// isVoidTy - Return true if this is 'void'.
+  bool isVoidTy() const { return getTypeID() == VoidTyID; }
+
+  /// isHalfTy - Return true if this is 'half', a 16-bit IEEE fp type.
+  bool isHalfTy() const { return getTypeID() == HalfTyID; }
+
+  /// isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
+  bool isFloatTy() const { return getTypeID() == FloatTyID; }
+  
+  /// isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
+  bool isDoubleTy() const { return getTypeID() == DoubleTyID; }
+
+  /// isX86_FP80Ty - Return true if this is x86 long double.
+  bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; }
+
+  /// isFP128Ty - Return true if this is 'fp128'.
+  bool isFP128Ty() const { return getTypeID() == FP128TyID; }
+
+  /// isPPC_FP128Ty - Return true if this is powerpc long double.
+  bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }
+
+  /// isFloatingPointTy - Return true if this is one of the six floating point
+  /// types
+  bool isFloatingPointTy() const {
+    return getTypeID() == HalfTyID || getTypeID() == FloatTyID ||
+           getTypeID() == DoubleTyID ||
+           getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID ||
+           getTypeID() == PPC_FP128TyID;
+  }
+
+  const fltSemantics &getFltSemantics() const {
+    switch (getTypeID()) {
+    case HalfTyID: return APFloat::IEEEhalf;
+    case FloatTyID: return APFloat::IEEEsingle;
+    case DoubleTyID: return APFloat::IEEEdouble;
+    case X86_FP80TyID: return APFloat::x87DoubleExtended;
+    case FP128TyID: return APFloat::IEEEquad;
+    case PPC_FP128TyID: return APFloat::PPCDoubleDouble;
+    default: llvm_unreachable("Invalid floating type");
+    }
+  }
+
+  /// isX86_MMXTy - Return true if this is X86 MMX.
+  bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }
+
+  /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
+  ///
+  bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }
+ 
+  /// isLabelTy - Return true if this is 'label'.
+  bool isLabelTy() const { return getTypeID() == LabelTyID; }
+
+  /// isMetadataTy - Return true if this is 'metadata'.
+  bool isMetadataTy() const { return getTypeID() == MetadataTyID; }
+
+  /// isIntegerTy - True if this is an instance of IntegerType.
+  ///
+  bool isIntegerTy() const { return getTypeID() == IntegerTyID; } 
+
+  /// isIntegerTy - Return true if this is an IntegerType of the given width.
+  bool isIntegerTy(unsigned Bitwidth) const;
+
+  /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
+  /// integer types.
+  ///
+  bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }
+  
+  /// isFunctionTy - True if this is an instance of FunctionType.
+  ///
+  bool isFunctionTy() const { return getTypeID() == FunctionTyID; }
+
+  /// isStructTy - True if this is an instance of StructType.
+  ///
+  bool isStructTy() const { return getTypeID() == StructTyID; }
+
+  /// isArrayTy - True if this is an instance of ArrayType.
+  ///
+  bool isArrayTy() const { return getTypeID() == ArrayTyID; }
+
+  /// isPointerTy - True if this is an instance of PointerType.
+  ///
+  bool isPointerTy() const { return getTypeID() == PointerTyID; }
+
+  /// isPtrOrPtrVectorTy - Return true if this is a pointer type or a vector of
+  /// pointer types.
+  ///
+  bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }
+ 
+  /// isVectorTy - True if this is an instance of VectorType.
+  ///
+  bool isVectorTy() const { return getTypeID() == VectorTyID; }
+
+  /// canLosslesslyBitCastTo - Return true if this type could be converted 
+  /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts 
+  /// are valid for types of the same size only where no re-interpretation of 
+  /// the bits is done.
+  /// @brief Determine if this type could be losslessly bitcast to Ty
+  bool canLosslesslyBitCastTo(Type *Ty) const;
+
+  /// isEmptyTy - Return true if this type is empty, that is, it has no
+  /// elements or all its elements are empty.
+  bool isEmptyTy() const;
+
+  /// isFirstClassType - Return true if the type is "first class", meaning it
+  /// is a valid type for a Value.
+  ///
+  bool isFirstClassType() const {
+    return getTypeID() != FunctionTyID && getTypeID() != VoidTyID;
+  }
+
+  /// isSingleValueType - Return true if the type is a valid type for a
+  /// register in codegen.  This includes all first-class types except struct
+  /// and array types.
+  ///
+  bool isSingleValueType() const {
+    return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() ||
+           isPointerTy() || isVectorTy();
+  }
+
+  /// isAggregateType - Return true if the type is an aggregate type. This
+  /// means it is valid as the first operand of an insertvalue or
+  /// extractvalue instruction. This includes struct and array types, but
+  /// does not include vector types.
+  ///
+  bool isAggregateType() const {
+    return getTypeID() == StructTyID || getTypeID() == ArrayTyID;
+  }
+
+  /// isSized - Return true if it makes sense to take the size of this type.  To
+  /// get the actual size for a particular target, it is reasonable to use the
+  /// DataLayout subsystem to do this.
+  ///
+  bool isSized(SmallPtrSet<const Type*, 4> *Visited = nullptr) const {
+    // If it's a primitive, it is always sized.
+    if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
+        getTypeID() == PointerTyID ||
+        getTypeID() == X86_MMXTyID)
+      return true;
+    // If it is not something that can have a size (e.g. a function or label),
+    // it doesn't have a size.
+    if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
+        getTypeID() != VectorTyID)
+      return false;
+    // Otherwise we have to try harder to decide.
+    return isSizedDerivedType(Visited);
+  }
+
+  /// getPrimitiveSizeInBits - Return the basic size of this type if it is a
+  /// primitive type.  These are fixed by LLVM and are not target dependent.
+  /// This will return zero if the type does not have a size or is not a
+  /// primitive type.
+  ///
+  /// Note that this may not reflect the size of memory allocated for an
+  /// instance of the type or the number of bytes that are written when an
+  /// instance of the type is stored to memory. The DataLayout class provides
+  /// additional query functions to provide this information.
+  ///
+  unsigned getPrimitiveSizeInBits() const LLVM_READONLY;
+
+  /// getScalarSizeInBits - If this is a vector type, return the
+  /// getPrimitiveSizeInBits value for the element type. Otherwise return the
+  /// getPrimitiveSizeInBits value for this type.
+  unsigned getScalarSizeInBits() const LLVM_READONLY;
+
+  /// getFPMantissaWidth - Return the width of the mantissa of this type.  This
+  /// is only valid on floating point types.  If the FP type does not
+  /// have a stable mantissa (e.g. ppc long double), this method returns -1.
+  int getFPMantissaWidth() const;
+
+  /// getScalarType - If this is a vector type, return the element type,
+  /// otherwise return 'this'.
+  const Type *getScalarType() const LLVM_READONLY;
+  Type *getScalarType() LLVM_READONLY;
+
+  //===--------------------------------------------------------------------===//
+  // Type Iteration support.
+  //
+  typedef Type * const *subtype_iterator;
+  subtype_iterator subtype_begin() const { return ContainedTys; }
+  subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
+
+  typedef std::reverse_iterator<subtype_iterator> subtype_reverse_iterator;
+  subtype_reverse_iterator subtype_rbegin() const {
+    return subtype_reverse_iterator(subtype_end());
+  }
+  subtype_reverse_iterator subtype_rend() const {
+    return subtype_reverse_iterator(subtype_begin());
+  }
+
+  /// getContainedType - This method is used to implement the type iterator
+  /// (defined a the end of the file).  For derived types, this returns the
+  /// types 'contained' in the derived type.
+  ///
+  Type *getContainedType(unsigned i) const {
+    assert(i < NumContainedTys && "Index out of range!");
+    return ContainedTys[i];
+  }
+
+  /// getNumContainedTypes - Return the number of types in the derived type.
+  ///
+  unsigned getNumContainedTypes() const { return NumContainedTys; }
+
+  //===--------------------------------------------------------------------===//
+  // Helper methods corresponding to subclass methods.  This forces a cast to
+  // the specified subclass and calls its accessor.  "getVectorNumElements" (for
+  // example) is shorthand for cast<VectorType>(Ty)->getNumElements().  This is
+  // only intended to cover the core methods that are frequently used, helper
+  // methods should not be added here.
+  
+  unsigned getIntegerBitWidth() const;
+
+  Type *getFunctionParamType(unsigned i) const;
+  unsigned getFunctionNumParams() const;
+  bool isFunctionVarArg() const;
+  
+  StringRef getStructName() const;
+  unsigned getStructNumElements() const;
+  Type *getStructElementType(unsigned N) const;
+  
+  Type *getSequentialElementType() const;
+  
+  uint64_t getArrayNumElements() const;
+  Type *getArrayElementType() const { return getSequentialElementType(); }
+
+  unsigned getVectorNumElements() const;
+  Type *getVectorElementType() const { return getSequentialElementType(); }
+
+  Type *getPointerElementType() const { return getSequentialElementType(); }
+
+  /// \brief Get the address space of this pointer or pointer vector type.
+  unsigned getPointerAddressSpace() const;
+  
+  //===--------------------------------------------------------------------===//
+  // Static members exported by the Type class itself.  Useful for getting
+  // instances of Type.
+  //
+
+  /// getPrimitiveType - Return a type based on an identifier.
+  static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);
+
+  //===--------------------------------------------------------------------===//
+  // These are the builtin types that are always available.
+  //
+  static Type *getVoidTy(LLVMContext &C);
+  static Type *getLabelTy(LLVMContext &C);
+  static Type *getHalfTy(LLVMContext &C);
+  static Type *getFloatTy(LLVMContext &C);
+  static Type *getDoubleTy(LLVMContext &C);
+  static Type *getMetadataTy(LLVMContext &C);
+  static Type *getX86_FP80Ty(LLVMContext &C);
+  static Type *getFP128Ty(LLVMContext &C);
+  static Type *getPPC_FP128Ty(LLVMContext &C);
+  static Type *getX86_MMXTy(LLVMContext &C);
+  static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
+  static IntegerType *getInt1Ty(LLVMContext &C);
+  static IntegerType *getInt8Ty(LLVMContext &C);
+  static IntegerType *getInt16Ty(LLVMContext &C);
+  static IntegerType *getInt32Ty(LLVMContext &C);
+  static IntegerType *getInt64Ty(LLVMContext &C);
+
+  //===--------------------------------------------------------------------===//
+  // Convenience methods for getting pointer types with one of the above builtin
+  // types as pointee.
+  //
+  static PointerType *getHalfPtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0);
+  static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getInt32PtrTy(LLVMContext &C, unsigned AS = 0);
+  static PointerType *getInt64PtrTy(LLVMContext &C, unsigned AS = 0);
+
+  /// getPointerTo - Return a pointer to the current type.  This is equivalent
+  /// to PointerType::get(Foo, AddrSpace).
+  PointerType *getPointerTo(unsigned AddrSpace = 0);
+
+private:
+  /// isSizedDerivedType - Derived types like structures and arrays are sized
+  /// iff all of the members of the type are sized as well.  Since asking for
+  /// their size is relatively uncommon, move this operation out of line.
+  bool isSizedDerivedType(SmallPtrSet<const Type*, 4> *Visited = nullptr) const;
+};
+
+// Printing of types.
+static inline raw_ostream &operator<<(raw_ostream &OS, Type &T) {
+  T.print(OS);
+  return OS;
+}
+
+// allow isa<PointerType>(x) to work without DerivedTypes.h included.
+template <> struct isa_impl<PointerType, Type> {
+  static inline bool doit(const Type &Ty) {
+    return Ty.getTypeID() == Type::PointerTyID;
+  }
+};
+
+  
+//===----------------------------------------------------------------------===//
+// Provide specializations of GraphTraits to be able to treat a type as a
+// graph of sub types.
+
+
+template <> struct GraphTraits<Type*> {
+  typedef Type NodeType;
+  typedef Type::subtype_iterator ChildIteratorType;
+
+  static inline NodeType *getEntryNode(Type *T) { return T; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->subtype_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->subtype_end();
+  }
+};
+
+template <> struct GraphTraits<const Type*> {
+  typedef const Type NodeType;
+  typedef Type::subtype_iterator ChildIteratorType;
+
+  static inline NodeType *getEntryNode(NodeType *T) { return T; }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->subtype_begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->subtype_end();
+  }
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef)
+
+/* Specialized opaque type conversions.
+ */
+inline Type **unwrap(LLVMTypeRef* Tys) {
+  return reinterpret_cast<Type**>(Tys);
+}
+
+inline LLVMTypeRef *wrap(Type **Tys) {
+  return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
+}
+  
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/TypeBuilder.h b/include/llvm/IR/TypeBuilder.h
new file mode 100644
index 0000000..5a29e1e
--- /dev/null
+++ b/include/llvm/IR/TypeBuilder.h
@@ -0,0 +1,399 @@
+//===---- llvm/TypeBuilder.h - Builder for LLVM types -----------*- 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 TypeBuilder class, which is used as a convenient way to
+// create LLVM types with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_TYPEBUILDER_H
+#define LLVM_IR_TYPEBUILDER_H
+
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include <climits>
+
+namespace llvm {
+
+/// TypeBuilder - This provides a uniform API for looking up types
+/// known at compile time.  To support cross-compilation, we define a
+/// series of tag types in the llvm::types namespace, like i<N>,
+/// ieee_float, ppc_fp128, etc.  TypeBuilder<T, false> allows T to be
+/// any of these, a native C type (whose size may depend on the host
+/// compiler), or a pointer, function, or struct type built out of
+/// these.  TypeBuilder<T, true> removes native C types from this set
+/// to guarantee that its result is suitable for cross-compilation.
+/// We define the primitive types, pointer types, and functions up to
+/// 5 arguments here, but to use this class with your own types,
+/// you'll need to specialize it.  For example, say you want to call a
+/// function defined externally as:
+///
+///   struct MyType {
+///     int32 a;
+///     int32 *b;
+///     void *array[1];  // Intended as a flexible array.
+///   };
+///   int8 AFunction(struct MyType *value);
+///
+/// You'll want to use
+///   Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
+/// to declare the function, but when you first try this, your compiler will
+/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
+/// write:
+///
+///   namespace llvm {
+///   template<bool xcompile> class TypeBuilder<MyType, xcompile> {
+///   public:
+///     static StructType *get(LLVMContext &Context) {
+///       // If you cache this result, be sure to cache it separately
+///       // for each LLVMContext.
+///       return StructType::get(
+///         TypeBuilder<types::i<32>, xcompile>::get(Context),
+///         TypeBuilder<types::i<32>*, xcompile>::get(Context),
+///         TypeBuilder<types::i<8>*[], xcompile>::get(Context),
+///         NULL);
+///     }
+///
+///     // You may find this a convenient place to put some constants
+///     // to help with getelementptr.  They don't have any effect on
+///     // the operation of TypeBuilder.
+///     enum Fields {
+///       FIELD_A,
+///       FIELD_B,
+///       FIELD_ARRAY
+///     };
+///   }
+///   }  // namespace llvm
+///
+/// TypeBuilder cannot handle recursive types or types you only know at runtime.
+/// If you try to give it a recursive type, it will deadlock, infinitely
+/// recurse, or do something similarly undesirable.
+template<typename T, bool cross_compilable> class TypeBuilder {};
+
+// Types for use with cross-compilable TypeBuilders.  These correspond
+// exactly with an LLVM-native type.
+namespace types {
+/// i<N> corresponds to the LLVM IntegerType with N bits.
+template<uint32_t num_bits> class i {};
+
+// The following classes represent the LLVM floating types.
+class ieee_float {};
+class ieee_double {};
+class x86_fp80 {};
+class fp128 {};
+class ppc_fp128 {};
+// X86 MMX.
+class x86_mmx {};
+}  // namespace types
+
+// LLVM doesn't have const or volatile types.
+template<typename T, bool cross> class TypeBuilder<const T, cross>
+  : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<volatile T, cross>
+  : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
+  : public TypeBuilder<T, cross> {};
+
+// Pointers
+template<typename T, bool cross> class TypeBuilder<T*, cross> {
+public:
+  static PointerType *get(LLVMContext &Context) {
+    return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
+  }
+};
+
+/// There is no support for references
+template<typename T, bool cross> class TypeBuilder<T&, cross> {};
+
+// Arrays
+template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
+public:
+  static ArrayType *get(LLVMContext &Context) {
+    return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
+  }
+};
+/// LLVM uses an array of length 0 to represent an unknown-length array.
+template<typename T, bool cross> class TypeBuilder<T[], cross> {
+public:
+  static ArrayType *get(LLVMContext &Context) {
+    return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
+  }
+};
+
+// Define the C integral types only for TypeBuilder<T, false>.
+//
+// C integral types do not have a defined size. It would be nice to use the
+// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
+// following problem:
+//
+// On an ILP32 machine, stdint.h might define:
+//
+//   typedef int int32_t;
+//   typedef long long int64_t;
+//   typedef long size_t;
+//
+// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
+// TypeBuilder<size_t> would fail.  We couldn't define TypeBuilder<size_t> in
+// addition to the defined-size types because we'd get duplicate definitions on
+// platforms where stdint.h instead defines:
+//
+//   typedef int int32_t;
+//   typedef long long int64_t;
+//   typedef int size_t;
+//
+// So we define all the primitive C types and nothing else.
+#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
+template<> class TypeBuilder<T, false> { \
+public: \
+  static IntegerType *get(LLVMContext &Context) { \
+    return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
+  } \
+}; \
+template<> class TypeBuilder<T, true> { \
+  /* We provide a definition here so users don't accidentally */ \
+  /* define these types to work. */ \
+}
+DEFINE_INTEGRAL_TYPEBUILDER(char);
+DEFINE_INTEGRAL_TYPEBUILDER(signed char);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
+DEFINE_INTEGRAL_TYPEBUILDER(short);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
+DEFINE_INTEGRAL_TYPEBUILDER(int);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
+DEFINE_INTEGRAL_TYPEBUILDER(long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
+#ifdef _MSC_VER
+DEFINE_INTEGRAL_TYPEBUILDER(__int64);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
+#else /* _MSC_VER */
+DEFINE_INTEGRAL_TYPEBUILDER(long long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
+#endif /* _MSC_VER */
+#undef DEFINE_INTEGRAL_TYPEBUILDER
+
+template<uint32_t num_bits, bool cross>
+class TypeBuilder<types::i<num_bits>, cross> {
+public:
+  static IntegerType *get(LLVMContext &C) {
+    return IntegerType::get(C, num_bits);
+  }
+};
+
+template<> class TypeBuilder<float, false> {
+public:
+  static Type *get(LLVMContext& C) {
+    return Type::getFloatTy(C);
+  }
+};
+template<> class TypeBuilder<float, true> {};
+
+template<> class TypeBuilder<double, false> {
+public:
+  static Type *get(LLVMContext& C) {
+    return Type::getDoubleTy(C);
+  }
+};
+template<> class TypeBuilder<double, true> {};
+
+template<bool cross> class TypeBuilder<types::ieee_float, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
+};
+template<bool cross> class TypeBuilder<types::ieee_double, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::fp128, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
+};
+
+template<bool cross> class TypeBuilder<void, cross> {
+public:
+  static Type *get(LLVMContext &C) {
+    return Type::getVoidTy(C);
+  }
+};
+
+/// void* is disallowed in LLVM types, but it occurs often enough in C code that
+/// we special case it.
+template<> class TypeBuilder<void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<volatile void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const volatile void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+
+template<typename R, bool cross> class TypeBuilder<R(), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
+  }
+};
+template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         bool cross>
+class TypeBuilder<R(A1, A2, A3, A4), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+      TypeBuilder<A5, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, bool cross> class TypeBuilder<R(...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
+  }
+};
+template<typename R, typename A1, bool cross>
+class TypeBuilder<R(A1, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
+  }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, true);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+      TypeBuilder<A5, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+
+}  // namespace llvm
+
+#endif
diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h
new file mode 100644
index 0000000..cea66a4
--- /dev/null
+++ b/include/llvm/IR/TypeFinder.h
@@ -0,0 +1,78 @@
+//===-- llvm/IR/TypeFinder.h - Class to find used struct types --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the TypeFinder class. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_TYPEFINDER_H
+#define LLVM_IR_TYPEFINDER_H
+
+#include "llvm/ADT/DenseSet.h"
+#include <vector>
+
+namespace llvm {
+
+class MDNode;
+class Module;
+class StructType;
+class Type;
+class Value;
+
+/// TypeFinder - Walk over a module, identifying all of the types that are
+/// used by the module.
+class TypeFinder {
+  // To avoid walking constant expressions multiple times and other IR
+  // objects, we keep several helper maps.
+  DenseSet<const Value*> VisitedConstants;
+  DenseSet<Type*> VisitedTypes;
+
+  std::vector<StructType*> StructTypes;
+  bool OnlyNamed;
+
+public:
+  TypeFinder() : OnlyNamed(false) {}
+
+  void run(const Module &M, bool onlyNamed);
+  void clear();
+
+  typedef std::vector<StructType*>::iterator iterator;
+  typedef std::vector<StructType*>::const_iterator const_iterator;
+
+  iterator begin() { return StructTypes.begin(); }
+  iterator end() { return StructTypes.end(); }
+
+  const_iterator begin() const { return StructTypes.begin(); }
+  const_iterator end() const { return StructTypes.end(); }
+
+  bool empty() const { return StructTypes.empty(); }
+  size_t size() const { return StructTypes.size(); }
+  iterator erase(iterator I, iterator E) { return StructTypes.erase(I, E); }
+
+  StructType *&operator[](unsigned Idx) { return StructTypes[Idx]; }
+
+private:
+  /// incorporateType - This method adds the type to the list of used
+  /// structures if it's not in there already.
+  void incorporateType(Type *Ty);
+
+  /// incorporateValue - This method is used to walk operand lists finding types
+  /// hiding in constant expressions and other operands that won't be walked in
+  /// other ways.  GlobalValues, basic blocks, instructions, and inst operands
+  /// are all explicitly enumerated.
+  void incorporateValue(const Value *V);
+
+  /// incorporateMDNode - This method is used to walk the operands of an MDNode
+  /// to find types hiding within.
+  void incorporateMDNode(const MDNode *V);
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h
new file mode 100644
index 0000000..033cd3e
--- /dev/null
+++ b/include/llvm/IR/Use.h
@@ -0,0 +1,173 @@
+//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This defines the Use class.  The Use class represents the operand of an
+/// instruction or some other User instance which refers to a Value.  The Use
+/// class keeps the "use list" of the referenced value up to date.
+///
+/// Pointer tagging is used to efficiently find the User corresponding to a Use
+/// without having to store a User pointer in every Use. A User is preceded in
+/// memory by all the Uses corresponding to its operands, and the low bits of
+/// one of the fields (Prev) of the Use class are used to encode offsets to be
+/// able to find that User given a pointer to any Use. For details, see:
+///
+///   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_USE_H
+#define LLVM_IR_USE_H
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Compiler.h"
+#include <cstddef>
+#include <iterator>
+
+namespace llvm {
+
+class Value;
+class User;
+class Use;
+template <typename> struct simplify_type;
+
+// Use** is only 4-byte aligned.
+template <> class PointerLikeTypeTraits<Use **> {
+public:
+  static inline void *getAsVoidPointer(Use **P) { return P; }
+  static inline Use **getFromVoidPointer(void *P) {
+    return static_cast<Use **>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+
+/// \brief A Use represents the edge between a Value definition and its users.
+///
+/// This is notionally a two-dimensional linked list. It supports traversing
+/// all of the uses for a particular value definition. It also supports jumping
+/// directly to the used value when we arrive from the User's operands, and
+/// jumping directly to the User when we arrive from the Value's uses.
+///
+/// The pointer to the used Value is explicit, and the pointer to the User is
+/// implicit. The implicit pointer is found via a waymarking algorithm
+/// described in the programmer's manual:
+///
+///   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
+///
+/// This is essentially the single most memory intensive object in LLVM because
+/// of the number of uses in the system. At the same time, the constant time
+/// operations it allows are essential to many optimizations having reasonable
+/// time complexity.
+class Use {
+public:
+  /// \brief Provide a fast substitute to std::swap<Use>
+  /// that also works with less standard-compliant compilers
+  void swap(Use &RHS);
+
+  // A type for the word following an array of hung-off Uses in memory, which is
+  // a pointer back to their User with the bottom bit set.
+  typedef PointerIntPair<User *, 1, unsigned> UserRef;
+
+private:
+  Use(const Use &U) LLVM_DELETED_FUNCTION;
+
+  /// Destructor - Only for zap()
+  ~Use() {
+    if (Val)
+      removeFromList();
+  }
+
+  enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
+
+  /// Constructor
+  Use(PrevPtrTag tag) : Val(nullptr) { Prev.setInt(tag); }
+
+public:
+  operator Value *() const { return Val; }
+  Value *get() const { return Val; }
+
+  /// \brief Returns the User that contains this Use.
+  ///
+  /// For an instruction operand, for example, this will return the
+  /// instruction.
+  User *getUser() const;
+
+  inline void set(Value *Val);
+
+  Value *operator=(Value *RHS) {
+    set(RHS);
+    return RHS;
+  }
+  const Use &operator=(const Use &RHS) {
+    set(RHS.Val);
+    return *this;
+  }
+
+  Value *operator->() { return Val; }
+  const Value *operator->() const { return Val; }
+
+  Use *getNext() const { return Next; }
+
+  /// \brief Return the operand # of this use in its User.
+  unsigned getOperandNo() const;
+
+  /// \brief Initializes the waymarking tags on an array of Uses.
+  ///
+  /// This sets up the array of Uses such that getUser() can find the User from
+  /// any of those Uses.
+  static Use *initTags(Use *Start, Use *Stop);
+
+  /// \brief Destroys Use operands when the number of operands of
+  /// a User changes.
+  static void zap(Use *Start, const Use *Stop, bool del = false);
+
+private:
+  const Use *getImpliedUser() const;
+
+  Value *Val;
+  Use *Next;
+  PointerIntPair<Use **, 2, PrevPtrTag> Prev;
+
+  void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
+  void addToList(Use **List) {
+    Next = *List;
+    if (Next)
+      Next->setPrev(&Next);
+    setPrev(List);
+    *List = this;
+  }
+  void removeFromList() {
+    Use **StrippedPrev = Prev.getPointer();
+    *StrippedPrev = Next;
+    if (Next)
+      Next->setPrev(StrippedPrev);
+  }
+
+  friend class Value;
+};
+
+/// \brief Allow clients to treat uses just like values when using
+/// casting operators.
+template <> struct simplify_type<Use> {
+  typedef Value *SimpleType;
+  static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
+};
+template <> struct simplify_type<const Use> {
+  typedef /*const*/ Value *SimpleType;
+  static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
+
+}
+
+#endif
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
new file mode 100644
index 0000000..848adae
--- /dev/null
+++ b/include/llvm/IR/User.h
@@ -0,0 +1,192 @@
+//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines the interface that one who uses a Value must implement.
+// Each instance of the Value class keeps track of what User's have handles
+// to it.
+//
+//  * Instructions are the largest class of Users.
+//  * Constants may be users of other constants (think arrays and stuff)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_USER_H
+#define LLVM_IR_USER_H
+
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+/// OperandTraits - Compile-time customization of
+/// operand-related allocators and accessors
+/// for use of the User class
+template <class>
+struct OperandTraits;
+
+class User : public Value {
+  User(const User &) LLVM_DELETED_FUNCTION;
+  void *operator new(size_t) LLVM_DELETED_FUNCTION;
+  template <unsigned>
+  friend struct HungoffOperandTraits;
+  virtual void anchor();
+protected:
+  /// NumOperands - The number of values used by this User.
+  ///
+  unsigned NumOperands;
+
+  /// OperandList - This is a pointer to the array of Uses for this User.
+  /// For nodes of fixed arity (e.g. a binary operator) this array will live
+  /// prefixed to some derived class instance.  For nodes of resizable variable
+  /// arity (e.g. PHINodes, SwitchInst etc.), this memory will be dynamically
+  /// allocated and should be destroyed by the classes' virtual dtor.
+  Use *OperandList;
+
+  void *operator new(size_t s, unsigned Us);
+  User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
+    : Value(ty, vty), NumOperands(NumOps), OperandList(OpList) {}
+  Use *allocHungoffUses(unsigned) const;
+  void dropHungoffUses() {
+    Use::zap(OperandList, OperandList + NumOperands, true);
+    OperandList = nullptr;
+    // Reset NumOperands so User::operator delete() does the right thing.
+    NumOperands = 0;
+  }
+public:
+  ~User() {
+    Use::zap(OperandList, OperandList + NumOperands);
+  }
+  /// operator delete - free memory allocated for User and Use objects
+  void operator delete(void *Usr);
+  /// placement delete - required by std, but never called.
+  void operator delete(void*, unsigned) {
+    llvm_unreachable("Constructor throws?");
+  }
+  /// placement delete - required by std, but never called.
+  void operator delete(void*, unsigned, bool) {
+    llvm_unreachable("Constructor throws?");
+  }
+protected:
+  template <int Idx, typename U> static Use &OpFrom(const U *that) {
+    return Idx < 0
+      ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx]
+      : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx];
+  }
+  template <int Idx> Use &Op() {
+    return OpFrom<Idx>(this);
+  }
+  template <int Idx> const Use &Op() const {
+    return OpFrom<Idx>(this);
+  }
+public:
+  Value *getOperand(unsigned i) const {
+    assert(i < NumOperands && "getOperand() out of range!");
+    return OperandList[i];
+  }
+  void setOperand(unsigned i, Value *Val) {
+    assert(i < NumOperands && "setOperand() out of range!");
+    assert((!isa<Constant>((const Value*)this) ||
+            isa<GlobalValue>((const Value*)this)) &&
+           "Cannot mutate a constant with setOperand!");
+    OperandList[i] = Val;
+  }
+  const Use &getOperandUse(unsigned i) const {
+    assert(i < NumOperands && "getOperandUse() out of range!");
+    return OperandList[i];
+  }
+  Use &getOperandUse(unsigned i) {
+    assert(i < NumOperands && "getOperandUse() out of range!");
+    return OperandList[i];
+  }
+
+  unsigned getNumOperands() const { return NumOperands; }
+
+  // ---------------------------------------------------------------------------
+  // Operand Iterator interface...
+  //
+  typedef Use*       op_iterator;
+  typedef const Use* const_op_iterator;
+  typedef iterator_range<op_iterator> op_range;
+  typedef iterator_range<const_op_iterator> const_op_range;
+
+  inline op_iterator       op_begin()       { return OperandList; }
+  inline const_op_iterator op_begin() const { return OperandList; }
+  inline op_iterator       op_end()         { return OperandList+NumOperands; }
+  inline const_op_iterator op_end()   const { return OperandList+NumOperands; }
+  inline op_range operands() {
+    return op_range(op_begin(), op_end());
+  }
+  inline const_op_range operands() const {
+    return const_op_range(op_begin(), op_end());
+  }
+
+  /// Convenience iterator for directly iterating over the Values in the
+  /// OperandList
+  struct value_op_iterator
+      : iterator_adaptor_base<value_op_iterator, op_iterator,
+                              std::random_access_iterator_tag, Value *,
+                              ptrdiff_t, Value *, Value *> {
+    explicit value_op_iterator(Use *U = nullptr) : iterator_adaptor_base(U) {}
+
+    Value *operator*() const { return *I; }
+    Value *operator->() const { return operator*(); }
+  };
+
+  inline value_op_iterator value_op_begin() {
+    return value_op_iterator(op_begin());
+  }
+  inline value_op_iterator value_op_end() {
+    return value_op_iterator(op_end());
+  }
+  inline iterator_range<value_op_iterator> operand_values() {
+    return iterator_range<value_op_iterator>(value_op_begin(), value_op_end());
+  }
+
+  // dropAllReferences() - This function is in charge of "letting go" of all
+  // objects that this User refers to.  This allows one to
+  // 'delete' a whole class at a time, even though there may be circular
+  // references...  First all references are dropped, and all use counts go to
+  // zero.  Then everything is deleted for real.  Note that no operations are
+  // valid on an object that has "dropped all references", except operator
+  // delete.
+  //
+  void dropAllReferences() {
+    for (Use &U : operands())
+      U.set(nullptr);
+  }
+
+  /// replaceUsesOfWith - Replaces all references to the "From" definition with
+  /// references to the "To" definition.
+  ///
+  void replaceUsesOfWith(Value *From, Value *To);
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) || isa<Constant>(V);
+  }
+};
+
+template<> struct simplify_type<User::op_iterator> {
+  typedef Value* SimpleType;
+  static SimpleType getSimplifiedValue(User::op_iterator &Val) {
+    return Val->get();
+  }
+};
+template<> struct simplify_type<User::const_op_iterator> {
+  typedef /*const*/ Value* SimpleType;
+  static SimpleType getSimplifiedValue(User::const_op_iterator &Val) {
+    return Val->get();
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
new file mode 100644
index 0000000..b5bbc96
--- /dev/null
+++ b/include/llvm/IR/Value.h
@@ -0,0 +1,583 @@
+//===-- llvm/Value.h - Definition of the Value class ------------*- 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 Value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VALUE_H
+#define LLVM_IR_VALUE_H
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/Use.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class APInt;
+class Argument;
+class AssemblyAnnotationWriter;
+class BasicBlock;
+class Constant;
+class DataLayout;
+class Function;
+class GlobalAlias;
+class GlobalObject;
+class GlobalValue;
+class GlobalVariable;
+class InlineAsm;
+class Instruction;
+class LLVMContext;
+class MDNode;
+class Module;
+class StringRef;
+class Twine;
+class Type;
+class ValueHandleBase;
+class ValueSymbolTable;
+class raw_ostream;
+
+template<typename ValueTy> class StringMapEntry;
+typedef StringMapEntry<Value*> ValueName;
+
+//===----------------------------------------------------------------------===//
+//                                 Value Class
+//===----------------------------------------------------------------------===//
+
+/// This is a very important LLVM class. It is the base class of all values
+/// computed by a program that may be used as operands to other values. Value is
+/// the super class of other important classes such as Instruction and Function.
+/// All Values have a Type. Type is not a subclass of Value. Some values can
+/// have a name and they belong to some Module.  Setting the name on the Value
+/// automatically updates the module's symbol table.
+///
+/// Every value has a "use list" that keeps track of which other Values are
+/// using this Value.  A Value can also have an arbitrary number of ValueHandle
+/// objects that watch it and listen to RAUW and Destroy events.  See
+/// llvm/IR/ValueHandle.h for details.
+///
+/// @brief LLVM Value Representation
+class Value {
+  Type *VTy;
+  Use *UseList;
+
+  friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
+  friend class ValueHandleBase;
+  ValueName *Name;
+
+  const unsigned char SubclassID;   // Subclass identifier (for isa/dyn_cast)
+  unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
+protected:
+  /// SubclassOptionalData - This member is similar to SubclassData, however it
+  /// is for holding information which may be used to aid optimization, but
+  /// which may be cleared to zero without affecting conservative
+  /// interpretation.
+  unsigned char SubclassOptionalData : 7;
+
+private:
+  /// SubclassData - This member is defined by this class, but is not used for
+  /// anything.  Subclasses can use it to hold whatever state they find useful.
+  /// This field is initialized to zero by the ctor.
+  unsigned short SubclassData;
+
+  template <typename UseT> // UseT == 'Use' or 'const Use'
+  class use_iterator_impl
+      : public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> {
+    typedef std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> super;
+
+    UseT *U;
+    explicit use_iterator_impl(UseT *u) : U(u) {}
+    friend class Value;
+
+  public:
+    typedef typename super::reference reference;
+    typedef typename super::pointer pointer;
+
+    use_iterator_impl() : U() {}
+
+    bool operator==(const use_iterator_impl &x) const { return U == x.U; }
+    bool operator!=(const use_iterator_impl &x) const { return !operator==(x); }
+
+    use_iterator_impl &operator++() { // Preincrement
+      assert(U && "Cannot increment end iterator!");
+      U = U->getNext();
+      return *this;
+    }
+    use_iterator_impl operator++(int) { // Postincrement
+      auto tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    UseT &operator*() const {
+      assert(U && "Cannot dereference end iterator!");
+      return *U;
+    }
+
+    UseT *operator->() const { return &operator*(); }
+
+    operator use_iterator_impl<const UseT>() const {
+      return use_iterator_impl<const UseT>(U);
+    }
+  };
+
+  template <typename UserTy> // UserTy == 'User' or 'const User'
+  class user_iterator_impl
+      : public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> {
+    typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super;
+
+    use_iterator_impl<Use> UI;
+    explicit user_iterator_impl(Use *U) : UI(U) {}
+    friend class Value;
+
+  public:
+    typedef typename super::reference reference;
+    typedef typename super::pointer pointer;
+
+    user_iterator_impl() {}
+
+    bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
+    bool operator!=(const user_iterator_impl &x) const { return !operator==(x); }
+
+    /// \brief Returns true if this iterator is equal to user_end() on the value.
+    bool atEnd() const { return *this == user_iterator_impl(); }
+
+    user_iterator_impl &operator++() { // Preincrement
+      ++UI;
+      return *this;
+    }
+    user_iterator_impl operator++(int) { // Postincrement
+      auto tmp = *this;
+      ++*this;
+      return tmp;
+    }
+
+    // Retrieve a pointer to the current User.
+    UserTy *operator*() const {
+      return UI->getUser();
+    }
+
+    UserTy *operator->() const { return operator*(); }
+
+    operator user_iterator_impl<const UserTy>() const {
+      return user_iterator_impl<const UserTy>(*UI);
+    }
+
+    Use &getUse() const { return *UI; }
+
+    /// \brief Return the operand # of this use in its User.
+    /// FIXME: Replace all callers with a direct call to Use::getOperandNo.
+    unsigned getOperandNo() const { return UI->getOperandNo(); }
+  };
+
+  void operator=(const Value &) LLVM_DELETED_FUNCTION;
+  Value(const Value &) LLVM_DELETED_FUNCTION;
+
+protected:
+  Value(Type *Ty, unsigned scid);
+public:
+  virtual ~Value();
+
+  /// dump - Support for debugging, callable in GDB: V->dump()
+  //
+  void dump() const;
+
+  /// print - Implement operator<< on Value.
+  ///
+  void print(raw_ostream &O) const;
+
+  /// \brief Print the name of this Value out to the specified raw_ostream.
+  /// This is useful when you just want to print 'int %reg126', not the
+  /// instruction that generated it. If you specify a Module for context, then
+  /// even constanst get pretty-printed; for example, the type of a null
+  /// pointer is printed symbolically.
+  void printAsOperand(raw_ostream &O, bool PrintType = true,
+                      const Module *M = nullptr) const;
+
+  /// All values are typed, get the type of this value.
+  ///
+  Type *getType() const { return VTy; }
+
+  /// All values hold a context through their type.
+  LLVMContext &getContext() const;
+
+  // All values can potentially be named.
+  bool hasName() const { return Name != nullptr && SubclassID != MDStringVal; }
+  ValueName *getValueName() const { return Name; }
+  void setValueName(ValueName *VN) { Name = VN; }
+
+  /// getName() - Return a constant reference to the value's name. This is cheap
+  /// and guaranteed to return the same reference as long as the value is not
+  /// modified.
+  StringRef getName() const;
+
+  /// setName() - Change the name of the value, choosing a new unique name if
+  /// the provided name is taken.
+  ///
+  /// \param Name The new name; or "" if the value's name should be removed.
+  void setName(const Twine &Name);
+
+
+  /// takeName - transfer the name from V to this value, setting V's name to
+  /// empty.  It is an error to call V->takeName(V).
+  void takeName(Value *V);
+
+  /// replaceAllUsesWith - Go through the uses list for this definition and make
+  /// each use point to "V" instead of "this".  After this completes, 'this's
+  /// use list is guaranteed to be empty.
+  ///
+  void replaceAllUsesWith(Value *V);
+
+  //----------------------------------------------------------------------
+  // Methods for handling the chain of uses of this Value.
+  //
+  bool               use_empty() const { return UseList == nullptr; }
+
+  typedef use_iterator_impl<Use>       use_iterator;
+  typedef use_iterator_impl<const Use> const_use_iterator;
+  use_iterator       use_begin()       { return use_iterator(UseList); }
+  const_use_iterator use_begin() const { return const_use_iterator(UseList); }
+  use_iterator       use_end()         { return use_iterator();   }
+  const_use_iterator use_end()   const { return const_use_iterator();   }
+  iterator_range<use_iterator> uses() {
+    return iterator_range<use_iterator>(use_begin(), use_end());
+  }
+  iterator_range<const_use_iterator> uses() const {
+    return iterator_range<const_use_iterator>(use_begin(), use_end());
+  }
+
+  typedef user_iterator_impl<User>       user_iterator;
+  typedef user_iterator_impl<const User> const_user_iterator;
+  user_iterator       user_begin()       { return user_iterator(UseList); }
+  const_user_iterator user_begin() const { return const_user_iterator(UseList); }
+  user_iterator       user_end()         { return user_iterator();   }
+  const_user_iterator user_end()   const { return const_user_iterator();   }
+  User               *user_back()        { return *user_begin(); }
+  const User         *user_back()  const { return *user_begin(); }
+  iterator_range<user_iterator> users() {
+    return iterator_range<user_iterator>(user_begin(), user_end());
+  }
+  iterator_range<const_user_iterator> users() const {
+    return iterator_range<const_user_iterator>(user_begin(), user_end());
+  }
+
+  /// hasOneUse - Return true if there is exactly one user of this value.  This
+  /// is specialized because it is a common request and does not require
+  /// traversing the whole use list.
+  ///
+  bool hasOneUse() const {
+    const_use_iterator I = use_begin(), E = use_end();
+    if (I == E) return false;
+    return ++I == E;
+  }
+
+  /// hasNUses - Return true if this Value has exactly N users.
+  ///
+  bool hasNUses(unsigned N) const;
+
+  /// hasNUsesOrMore - Return true if this value has N users or more.  This is
+  /// logically equivalent to getNumUses() >= N.
+  ///
+  bool hasNUsesOrMore(unsigned N) const;
+
+  bool isUsedInBasicBlock(const BasicBlock *BB) const;
+
+  /// getNumUses - This method computes the number of uses of this Value.  This
+  /// is a linear time operation.  Use hasOneUse, hasNUses, or hasNUsesOrMore
+  /// to check for specific values.
+  unsigned getNumUses() const;
+
+  /// addUse - This method should only be used by the Use class.
+  ///
+  void addUse(Use &U) { U.addToList(&UseList); }
+
+  /// An enumeration for keeping track of the concrete subclass of Value that
+  /// is actually instantiated. Values of this enumeration are kept in the
+  /// Value classes SubclassID field. They are used for concrete type
+  /// identification.
+  enum ValueTy {
+    ArgumentVal,              // This is an instance of Argument
+    BasicBlockVal,            // This is an instance of BasicBlock
+    FunctionVal,              // This is an instance of Function
+    GlobalAliasVal,           // This is an instance of GlobalAlias
+    GlobalVariableVal,        // This is an instance of GlobalVariable
+    UndefValueVal,            // This is an instance of UndefValue
+    BlockAddressVal,          // This is an instance of BlockAddress
+    ConstantExprVal,          // This is an instance of ConstantExpr
+    ConstantAggregateZeroVal, // This is an instance of ConstantAggregateZero
+    ConstantDataArrayVal,     // This is an instance of ConstantDataArray
+    ConstantDataVectorVal,    // This is an instance of ConstantDataVector
+    ConstantIntVal,           // This is an instance of ConstantInt
+    ConstantFPVal,            // This is an instance of ConstantFP
+    ConstantArrayVal,         // This is an instance of ConstantArray
+    ConstantStructVal,        // This is an instance of ConstantStruct
+    ConstantVectorVal,        // This is an instance of ConstantVector
+    ConstantPointerNullVal,   // This is an instance of ConstantPointerNull
+    MDNodeVal,                // This is an instance of MDNode
+    MDStringVal,              // This is an instance of MDString
+    InlineAsmVal,             // This is an instance of InlineAsm
+    InstructionVal,           // This is an instance of Instruction
+    // Enum values starting at InstructionVal are used for Instructions;
+    // don't add new values here!
+
+    // Markers:
+    ConstantFirstVal = FunctionVal,
+    ConstantLastVal  = ConstantPointerNullVal
+  };
+
+  /// getValueID - Return an ID for the concrete type of this object.  This is
+  /// used to implement the classof checks.  This should not be used for any
+  /// other purpose, as the values may change as LLVM evolves.  Also, note that
+  /// for instructions, the Instruction's opcode is added to InstructionVal. So
+  /// this means three things:
+  /// # there is no value with code InstructionVal (no opcode==0).
+  /// # there are more possible values for the value type than in ValueTy enum.
+  /// # the InstructionVal enumerator must be the highest valued enumerator in
+  ///   the ValueTy enum.
+  unsigned getValueID() const {
+    return SubclassID;
+  }
+
+  /// getRawSubclassOptionalData - Return the raw optional flags value
+  /// contained in this value. This should only be used when testing two
+  /// Values for equivalence.
+  unsigned getRawSubclassOptionalData() const {
+    return SubclassOptionalData;
+  }
+
+  /// clearSubclassOptionalData - Clear the optional flags contained in
+  /// this value.
+  void clearSubclassOptionalData() {
+    SubclassOptionalData = 0;
+  }
+
+  /// hasSameSubclassOptionalData - Test whether the optional flags contained
+  /// in this value are equal to the optional flags in the given value.
+  bool hasSameSubclassOptionalData(const Value *V) const {
+    return SubclassOptionalData == V->SubclassOptionalData;
+  }
+
+  /// intersectOptionalDataWith - Clear any optional flags in this value
+  /// that are not also set in the given value.
+  void intersectOptionalDataWith(const Value *V) {
+    SubclassOptionalData &= V->SubclassOptionalData;
+  }
+
+  /// hasValueHandle - Return true if there is a value handle associated with
+  /// this value.
+  bool hasValueHandle() const { return HasValueHandle; }
+
+  /// \brief Strips off any unneeded pointer casts, all-zero GEPs and aliases
+  /// from the specified value, returning the original uncasted value.
+  ///
+  /// If this is called on a non-pointer value, it returns 'this'.
+  Value *stripPointerCasts();
+  const Value *stripPointerCasts() const {
+    return const_cast<Value*>(this)->stripPointerCasts();
+  }
+
+  /// \brief Strips off any unneeded pointer casts and all-zero GEPs from the
+  /// specified value, returning the original uncasted value.
+  ///
+  /// If this is called on a non-pointer value, it returns 'this'.
+  Value *stripPointerCastsNoFollowAliases();
+  const Value *stripPointerCastsNoFollowAliases() const {
+    return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases();
+  }
+
+  /// \brief Strips off unneeded pointer casts and all-constant GEPs from the
+  /// specified value, returning the original pointer value.
+  ///
+  /// If this is called on a non-pointer value, it returns 'this'.
+  Value *stripInBoundsConstantOffsets();
+  const Value *stripInBoundsConstantOffsets() const {
+    return const_cast<Value*>(this)->stripInBoundsConstantOffsets();
+  }
+
+  /// \brief Strips like \c stripInBoundsConstantOffsets but also accumulates
+  /// the constant offset stripped.
+  ///
+  /// Stores the resulting constant offset stripped into the APInt provided.
+  /// The provided APInt will be extended or truncated as needed to be the
+  /// correct bitwidth for an offset of this pointer type.
+  ///
+  /// If this is called on a non-pointer value, it returns 'this'.
+  Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
+                                                   APInt &Offset);
+  const Value *stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
+                                                         APInt &Offset) const {
+    return const_cast<Value *>(this)
+        ->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
+  }
+
+  /// \brief Strips off unneeded pointer casts and any in-bounds offsets from
+  /// the specified value, returning the original pointer value.
+  ///
+  /// If this is called on a non-pointer value, it returns 'this'.
+  Value *stripInBoundsOffsets();
+  const Value *stripInBoundsOffsets() const {
+    return const_cast<Value*>(this)->stripInBoundsOffsets();
+  }
+
+  /// isDereferenceablePointer - Test if this value is always a pointer to
+  /// allocated and suitably aligned memory for a simple load or store.
+  bool isDereferenceablePointer(const DataLayout *DL = nullptr) const;
+
+  /// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
+  /// return the value in the PHI node corresponding to PredBB.  If not, return
+  /// ourself.  This is useful if you want to know the value something has in a
+  /// predecessor block.
+  Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB);
+
+  const Value *DoPHITranslation(const BasicBlock *CurBB,
+                                const BasicBlock *PredBB) const{
+    return const_cast<Value*>(this)->DoPHITranslation(CurBB, PredBB);
+  }
+
+  /// MaximumAlignment - This is the greatest alignment value supported by
+  /// load, store, and alloca instructions, and global values.
+  static const unsigned MaximumAlignment = 1u << 29;
+
+  /// mutateType - Mutate the type of this Value to be of the specified type.
+  /// Note that this is an extremely dangerous operation which can create
+  /// completely invalid IR very easily.  It is strongly recommended that you
+  /// recreate IR objects with the right types instead of mutating them in
+  /// place.
+  void mutateType(Type *Ty) {
+    VTy = Ty;
+  }
+
+protected:
+  unsigned short getSubclassDataFromValue() const { return SubclassData; }
+  void setValueSubclassData(unsigned short D) { SubclassData = D; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
+  V.print(OS);
+  return OS;
+}
+
+void Use::set(Value *V) {
+  if (Val) removeFromList();
+  Val = V;
+  if (V) V->addUse(*this);
+}
+
+
+// isa - Provide some specializations of isa so that we don't have to include
+// the subtype header files to test to see if the value is a subclass...
+//
+template <> struct isa_impl<Constant, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() >= Value::ConstantFirstVal &&
+      Val.getValueID() <= Value::ConstantLastVal;
+  }
+};
+
+template <> struct isa_impl<Argument, Value> {
+  static inline bool doit (const Value &Val) {
+    return Val.getValueID() == Value::ArgumentVal;
+  }
+};
+
+template <> struct isa_impl<InlineAsm, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::InlineAsmVal;
+  }
+};
+
+template <> struct isa_impl<Instruction, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() >= Value::InstructionVal;
+  }
+};
+
+template <> struct isa_impl<BasicBlock, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::BasicBlockVal;
+  }
+};
+
+template <> struct isa_impl<Function, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::FunctionVal;
+  }
+};
+
+template <> struct isa_impl<GlobalVariable, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::GlobalVariableVal;
+  }
+};
+
+template <> struct isa_impl<GlobalAlias, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::GlobalAliasVal;
+  }
+};
+
+template <> struct isa_impl<GlobalValue, Value> {
+  static inline bool doit(const Value &Val) {
+    return isa<GlobalObject>(Val) || isa<GlobalAlias>(Val);
+  }
+};
+
+template <> struct isa_impl<GlobalObject, Value> {
+  static inline bool doit(const Value &Val) {
+    return isa<GlobalVariable>(Val) || isa<Function>(Val);
+  }
+};
+
+template <> struct isa_impl<MDNode, Value> {
+  static inline bool doit(const Value &Val) {
+    return Val.getValueID() == Value::MDNodeVal;
+  }
+};
+
+// Value* is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<Value*> {
+  typedef Value* PT;
+public:
+  static inline void *getAsVoidPointer(PT P) { return P; }
+  static inline PT getFromVoidPointer(void *P) {
+    return static_cast<PT>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(Value, LLVMValueRef)
+
+/* Specialized opaque value conversions.
+ */
+inline Value **unwrap(LLVMValueRef *Vals) {
+  return reinterpret_cast<Value**>(Vals);
+}
+
+template<typename T>
+inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
+#ifdef DEBUG
+  for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
+    cast<T>(*I);
+#endif
+  (void)Length;
+  return reinterpret_cast<T**>(Vals);
+}
+
+inline LLVMValueRef *wrap(const Value **Vals) {
+  return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h
new file mode 100644
index 0000000..aa29b2e
--- /dev/null
+++ b/include/llvm/IR/ValueHandle.h
@@ -0,0 +1,380 @@
+//===- ValueHandle.h - Value Smart Pointer classes --------------*- 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 ValueHandle class and its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VALUEHANDLE_H
+#define LLVM_IR_VALUEHANDLE_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+class ValueHandleBase;
+template<typename From> struct simplify_type;
+
+// ValueHandleBase** is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<ValueHandleBase**> {
+public:
+  static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
+  static inline ValueHandleBase **getFromVoidPointer(void *P) {
+    return static_cast<ValueHandleBase**>(P);
+  }
+  enum { NumLowBitsAvailable = 2 };
+};
+
+/// ValueHandleBase - This is the common base class of value handles.
+/// ValueHandle's are smart pointers to Value's that have special behavior when
+/// the value is deleted or ReplaceAllUsesWith'd.  See the specific handles
+/// below for details.
+///
+class ValueHandleBase {
+  friend class Value;
+protected:
+  /// HandleBaseKind - This indicates what sub class the handle actually is.
+  /// This is to avoid having a vtable for the light-weight handle pointers. The
+  /// fully general Callback version does have a vtable.
+  enum HandleBaseKind {
+    Assert,
+    Callback,
+    Tracking,
+    Weak
+  };
+
+private:
+  PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
+  ValueHandleBase *Next;
+
+  // A subclass may want to store some information along with the value
+  // pointer. Allow them to do this by making the value pointer a pointer-int
+  // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
+  // access.
+  PointerIntPair<Value*, 2> VP;
+
+  ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
+public:
+  explicit ValueHandleBase(HandleBaseKind Kind)
+    : PrevPair(nullptr, Kind), Next(nullptr), VP(nullptr, 0) {}
+  ValueHandleBase(HandleBaseKind Kind, Value *V)
+    : PrevPair(nullptr, Kind), Next(nullptr), VP(V, 0) {
+    if (isValid(VP.getPointer()))
+      AddToUseList();
+  }
+  ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
+    : PrevPair(nullptr, Kind), Next(nullptr), VP(RHS.VP) {
+    if (isValid(VP.getPointer()))
+      AddToExistingUseList(RHS.getPrevPtr());
+  }
+  ~ValueHandleBase() {
+    if (isValid(VP.getPointer()))
+      RemoveFromUseList();
+  }
+
+  Value *operator=(Value *RHS) {
+    if (VP.getPointer() == RHS) return RHS;
+    if (isValid(VP.getPointer())) RemoveFromUseList();
+    VP.setPointer(RHS);
+    if (isValid(VP.getPointer())) AddToUseList();
+    return RHS;
+  }
+
+  Value *operator=(const ValueHandleBase &RHS) {
+    if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
+    if (isValid(VP.getPointer())) RemoveFromUseList();
+    VP.setPointer(RHS.VP.getPointer());
+    if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
+    return VP.getPointer();
+  }
+
+  Value *operator->() const { return getValPtr(); }
+  Value &operator*() const { return *getValPtr(); }
+
+protected:
+  Value *getValPtr() const { return VP.getPointer(); }
+
+  void setValPtrInt(unsigned K) { VP.setInt(K); }
+  unsigned getValPtrInt() const { return VP.getInt(); }
+
+  static bool isValid(Value *V) {
+    return V &&
+           V != DenseMapInfo<Value *>::getEmptyKey() &&
+           V != DenseMapInfo<Value *>::getTombstoneKey();
+  }
+
+public:
+  // Callbacks made from Value.
+  static void ValueIsDeleted(Value *V);
+  static void ValueIsRAUWd(Value *Old, Value *New);
+
+private:
+  // Internal implementation details.
+  ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
+  HandleBaseKind getKind() const { return PrevPair.getInt(); }
+  void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
+
+  /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
+  /// List is the address of either the head of the list or a Next node within
+  /// the existing use list.
+  void AddToExistingUseList(ValueHandleBase **List);
+
+  /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
+  /// Node.
+  void AddToExistingUseListAfter(ValueHandleBase *Node);
+
+  /// AddToUseList - Add this ValueHandle to the use list for VP.
+  void AddToUseList();
+  /// RemoveFromUseList - Remove this ValueHandle from its current use list.
+  void RemoveFromUseList();
+};
+
+/// WeakVH - This is a value handle that tries hard to point to a Value, even
+/// across RAUW operations, but will null itself out if the value is destroyed.
+/// this is useful for advisory sorts of information, but should not be used as
+/// the key of a map (since the map would have to rearrange itself when the
+/// pointer changes).
+class WeakVH : public ValueHandleBase {
+public:
+  WeakVH() : ValueHandleBase(Weak) {}
+  WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
+  WeakVH(const WeakVH &RHS)
+    : ValueHandleBase(Weak, RHS) {}
+
+  Value *operator=(Value *RHS) {
+    return ValueHandleBase::operator=(RHS);
+  }
+  Value *operator=(const ValueHandleBase &RHS) {
+    return ValueHandleBase::operator=(RHS);
+  }
+
+  operator Value*() const {
+    return getValPtr();
+  }
+};
+
+// Specialize simplify_type to allow WeakVH to participate in
+// dyn_cast, isa, etc.
+template<> struct simplify_type<WeakVH> {
+  typedef Value* SimpleType;
+  static SimpleType getSimplifiedValue(WeakVH &WVH) {
+    return WVH;
+  }
+};
+
+/// AssertingVH - This is a Value Handle that points to a value and asserts out
+/// if the value is destroyed while the handle is still live.  This is very
+/// useful for catching dangling pointer bugs and other things which can be
+/// non-obvious.  One particularly useful place to use this is as the Key of a
+/// map.  Dangling pointer bugs often lead to really subtle bugs that only occur
+/// if another object happens to get allocated to the same address as the old
+/// one.  Using an AssertingVH ensures that an assert is triggered as soon as
+/// the bad delete occurs.
+///
+/// Note that an AssertingVH handle does *not* follow values across RAUW
+/// operations.  This means that RAUW's need to explicitly update the
+/// AssertingVH's as it moves.  This is required because in non-assert mode this
+/// class turns into a trivial wrapper around a pointer.
+template <typename ValueTy>
+class AssertingVH
+#ifndef NDEBUG
+  : public ValueHandleBase
+#endif
+  {
+
+#ifndef NDEBUG
+  ValueTy *getValPtr() const {
+    return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+  }
+  void setValPtr(ValueTy *P) {
+    ValueHandleBase::operator=(GetAsValue(P));
+  }
+#else
+  ValueTy *ThePtr;
+  ValueTy *getValPtr() const { return ThePtr; }
+  void setValPtr(ValueTy *P) { ThePtr = P; }
+#endif
+
+  // Convert a ValueTy*, which may be const, to the type the base
+  // class expects.
+  static Value *GetAsValue(Value *V) { return V; }
+  static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
+public:
+#ifndef NDEBUG
+  AssertingVH() : ValueHandleBase(Assert) {}
+  AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
+  AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
+#else
+  AssertingVH() : ThePtr(nullptr) {}
+  AssertingVH(ValueTy *P) : ThePtr(P) {}
+#endif
+
+  operator ValueTy*() const {
+    return getValPtr();
+  }
+
+  ValueTy *operator=(ValueTy *RHS) {
+    setValPtr(RHS);
+    return getValPtr();
+  }
+  ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
+    setValPtr(RHS.getValPtr());
+    return getValPtr();
+  }
+
+  ValueTy *operator->() const { return getValPtr(); }
+  ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
+template<typename T>
+struct DenseMapInfo<AssertingVH<T> > {
+  typedef DenseMapInfo<T*> PointerInfo;
+  static inline AssertingVH<T> getEmptyKey() {
+    return AssertingVH<T>(PointerInfo::getEmptyKey());
+  }
+  static inline T* getTombstoneKey() {
+    return AssertingVH<T>(PointerInfo::getTombstoneKey());
+  }
+  static unsigned getHashValue(const AssertingVH<T> &Val) {
+    return PointerInfo::getHashValue(Val);
+  }
+  static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
+    return LHS == RHS;
+  }
+};
+  
+template <typename T>
+struct isPodLike<AssertingVH<T> > {
+#ifdef NDEBUG
+  static const bool value = true;
+#else
+  static const bool value = false;
+#endif
+};
+
+
+/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
+/// even across RAUW operations.
+///
+/// TrackingVH is designed for situations where a client needs to hold a handle
+/// to a Value (or subclass) across some operations which may move that value,
+/// but should never destroy it or replace it with some unacceptable type.
+///
+/// It is an error to do anything with a TrackingVH whose value has been
+/// destroyed, except to destruct it.
+///
+/// It is an error to attempt to replace a value with one of a type which is
+/// incompatible with any of its outstanding TrackingVHs.
+template<typename ValueTy>
+class TrackingVH : public ValueHandleBase {
+  void CheckValidity() const {
+    Value *VP = ValueHandleBase::getValPtr();
+
+    // Null is always ok.
+    if (!VP) return;
+
+    // Check that this value is valid (i.e., it hasn't been deleted). We
+    // explicitly delay this check until access to avoid requiring clients to be
+    // unnecessarily careful w.r.t. destruction.
+    assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
+
+    // Check that the value is a member of the correct subclass. We would like
+    // to check this property on assignment for better debugging, but we don't
+    // want to require a virtual interface on this VH. Instead we allow RAUW to
+    // replace this value with a value of an invalid type, and check it here.
+    assert(isa<ValueTy>(VP) &&
+           "Tracked Value was replaced by one with an invalid type!");
+  }
+
+  ValueTy *getValPtr() const {
+    CheckValidity();
+    return (ValueTy*)ValueHandleBase::getValPtr();
+  }
+  void setValPtr(ValueTy *P) {
+    CheckValidity();
+    ValueHandleBase::operator=(GetAsValue(P));
+  }
+
+  // Convert a ValueTy*, which may be const, to the type the base
+  // class expects.
+  static Value *GetAsValue(Value *V) { return V; }
+  static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
+public:
+  TrackingVH() : ValueHandleBase(Tracking) {}
+  TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
+  TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
+
+  operator ValueTy*() const {
+    return getValPtr();
+  }
+
+  ValueTy *operator=(ValueTy *RHS) {
+    setValPtr(RHS);
+    return getValPtr();
+  }
+  ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
+    setValPtr(RHS.getValPtr());
+    return getValPtr();
+  }
+
+  ValueTy *operator->() const { return getValPtr(); }
+  ValueTy &operator*() const { return *getValPtr(); }
+};
+
+/// CallbackVH - This is a value handle that allows subclasses to define
+/// callbacks that run when the underlying Value has RAUW called on it or is
+/// destroyed.  This class can be used as the key of a map, as long as the user
+/// takes it out of the map before calling setValPtr() (since the map has to
+/// rearrange itself when the pointer changes).  Unlike ValueHandleBase, this
+/// class has a vtable and a virtual destructor.
+class CallbackVH : public ValueHandleBase {
+  virtual void anchor();
+protected:
+  CallbackVH(const CallbackVH &RHS)
+    : ValueHandleBase(Callback, RHS) {}
+
+  virtual ~CallbackVH() {}
+
+  void setValPtr(Value *P) {
+    ValueHandleBase::operator=(P);
+  }
+
+public:
+  CallbackVH() : ValueHandleBase(Callback) {}
+  CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
+
+  operator Value*() const {
+    return getValPtr();
+  }
+
+  /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
+  /// call any non-virtual Value method on getValPtr(), but no subclass methods.
+  /// If WeakVH were implemented as a CallbackVH, it would use this method to
+  /// call setValPtr(NULL).  AssertingVH would use this method to cause an
+  /// assertion failure.
+  ///
+  /// All implementations must remove the reference from this object to the
+  /// Value that's being destroyed.
+  virtual void deleted() { setValPtr(nullptr); }
+
+  /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
+  /// _before_ any of the uses have actually been replaced.  If WeakVH were
+  /// implemented as a CallbackVH, it would use this method to call
+  /// setValPtr(new_value).  AssertingVH would do nothing in this method.
+  virtual void allUsesReplacedWith(Value *) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h
new file mode 100644
index 0000000..43a79c7
--- /dev/null
+++ b/include/llvm/IR/ValueMap.h
@@ -0,0 +1,380 @@
+//===- ValueMap.h - Safe map from Values to data ----------------*- 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 ValueMap class.  ValueMap maps Value* or any subclass
+// to an arbitrary other type.  It provides the DenseMap interface but updates
+// itself to remain safe when keys are RAUWed or deleted.  By default, when a
+// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
+// mapping V2->target is added.  If V2 already existed, its old target is
+// overwritten.  When a key is deleted, its mapping is removed.
+//
+// You can override a ValueMap's Config parameter to control exactly what
+// happens on RAUW and destruction and to get called back on each event.  It's
+// legal to call back into the ValueMap from a Config's callbacks.  Config
+// parameters should inherit from ValueMapConfig<KeyT> to get default
+// implementations of all the methods ValueMap uses.  See ValueMapConfig for
+// documentation of the functions you can override.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VALUEMAP_H
+#define LLVM_IR_VALUEMAP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/type_traits.h"
+#include <iterator>
+
+namespace llvm {
+
+template<typename KeyT, typename ValueT, typename Config>
+class ValueMapCallbackVH;
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapIterator;
+template<typename DenseMapT, typename KeyT>
+class ValueMapConstIterator;
+
+/// This class defines the default behavior for configurable aspects of
+/// ValueMap<>.  User Configs should inherit from this class to be as compatible
+/// as possible with future versions of ValueMap.
+template<typename KeyT, typename MutexT = sys::Mutex>
+struct ValueMapConfig {
+  typedef MutexT mutex_type;
+
+  /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
+  /// false, the ValueMap will leave the original mapping in place.
+  enum { FollowRAUW = true };
+
+  // All methods will be called with a first argument of type ExtraData.  The
+  // default implementations in this class take a templated first argument so
+  // that users' subclasses can use any type they want without having to
+  // override all the defaults.
+  struct ExtraData {};
+
+  template<typename ExtraDataT>
+  static void onRAUW(const ExtraDataT & /*Data*/, KeyT /*Old*/, KeyT /*New*/) {}
+  template<typename ExtraDataT>
+  static void onDelete(const ExtraDataT &/*Data*/, KeyT /*Old*/) {}
+
+  /// Returns a mutex that should be acquired around any changes to the map.
+  /// This is only acquired from the CallbackVH (and held around calls to onRAUW
+  /// and onDelete) and not inside other ValueMap methods.  NULL means that no
+  /// mutex is necessary.
+  template<typename ExtraDataT>
+  static mutex_type *getMutex(const ExtraDataT &/*Data*/) { return nullptr; }
+};
+
+/// See the file comment.
+template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> >
+class ValueMap {
+  friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
+  typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
+  typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT;
+  typedef typename Config::ExtraData ExtraData;
+  MapT Map;
+  ExtraData Data;
+  ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
+  ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
+public:
+  typedef KeyT key_type;
+  typedef ValueT mapped_type;
+  typedef std::pair<KeyT, ValueT> value_type;
+  typedef unsigned size_type;
+
+  explicit ValueMap(unsigned NumInitBuckets = 64)
+    : Map(NumInitBuckets), Data() {}
+  explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
+    : Map(NumInitBuckets), Data(Data) {}
+
+  ~ValueMap() {}
+
+  typedef ValueMapIterator<MapT, KeyT> iterator;
+  typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
+  inline iterator begin() { return iterator(Map.begin()); }
+  inline iterator end() { return iterator(Map.end()); }
+  inline const_iterator begin() const { return const_iterator(Map.begin()); }
+  inline const_iterator end() const { return const_iterator(Map.end()); }
+
+  bool empty() const { return Map.empty(); }
+  size_type size() const { return Map.size(); }
+
+  /// Grow the map so that it has at least Size buckets. Does not shrink
+  void resize(size_t Size) { Map.resize(Size); }
+
+  void clear() { Map.clear(); }
+
+  /// Return 1 if the specified key is in the map, 0 otherwise.

+  size_type count(const KeyT &Val) const {
+    return Map.find_as(Val) == Map.end() ? 0 : 1;
+  }
+
+  iterator find(const KeyT &Val) {
+    return iterator(Map.find_as(Val));
+  }
+  const_iterator find(const KeyT &Val) const {
+    return const_iterator(Map.find_as(Val));
+  }
+
+  /// lookup - Return the entry for the specified key, or a default
+  /// constructed value if no such entry exists.
+  ValueT lookup(const KeyT &Val) const {
+    typename MapT::const_iterator I = Map.find_as(Val);
+    return I != Map.end() ? I->second : ValueT();
+  }
+
+  // Inserts key,value pair into the map if the key isn't already in the map.
+  // If the key is already in the map, it returns false and doesn't update the
+  // value.
+  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+    std::pair<typename MapT::iterator, bool> map_result=
+      Map.insert(std::make_pair(Wrap(KV.first), KV.second));
+    return std::make_pair(iterator(map_result.first), map_result.second);
+  }
+
+  /// insert - Range insertion of pairs.
+  template<typename InputIt>
+  void insert(InputIt I, InputIt E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+
+
+  bool erase(const KeyT &Val) {
+    typename MapT::iterator I = Map.find_as(Val);
+    if (I == Map.end())
+      return false;
+
+    Map.erase(I);
+    return true;
+  }
+  void erase(iterator I) {
+    return Map.erase(I.base());
+  }
+
+  value_type& FindAndConstruct(const KeyT &Key) {
+    return Map.FindAndConstruct(Wrap(Key));
+  }
+
+  ValueT &operator[](const KeyT &Key) {
+    return Map[Wrap(Key)];
+  }
+
+  /// isPointerIntoBucketsArray - Return true if the specified pointer points
+  /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
+  /// value in the ValueMap).
+  bool isPointerIntoBucketsArray(const void *Ptr) const {
+    return Map.isPointerIntoBucketsArray(Ptr);
+  }
+
+  /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+  /// array.  In conjunction with the previous method, this can be used to
+  /// determine whether an insertion caused the ValueMap to reallocate.
+  const void *getPointerIntoBucketsArray() const {
+    return Map.getPointerIntoBucketsArray();
+  }
+
+private:
+  // Takes a key being looked up in the map and wraps it into a
+  // ValueMapCallbackVH, the actual key type of the map.  We use a helper
+  // function because ValueMapCVH is constructed with a second parameter.
+  ValueMapCVH Wrap(KeyT key) const {
+    // The only way the resulting CallbackVH could try to modify *this (making
+    // the const_cast incorrect) is if it gets inserted into the map.  But then
+    // this function must have been called from a non-const method, making the
+    // const_cast ok.
+    return ValueMapCVH(key, const_cast<ValueMap*>(this));
+  }
+};
+
+// This CallbackVH updates its ValueMap when the contained Value changes,
+// according to the user's preferences expressed through the Config object.
+template<typename KeyT, typename ValueT, typename Config>
+class ValueMapCallbackVH : public CallbackVH {
+  friend class ValueMap<KeyT, ValueT, Config>;
+  friend struct DenseMapInfo<ValueMapCallbackVH>;
+  typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
+  typedef typename std::remove_pointer<KeyT>::type KeySansPointerT;
+
+  ValueMapT *Map;
+
+  ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
+      : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
+        Map(Map) {}
+
+public:
+  KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
+
+  void deleted() override {
+    // Make a copy that won't get changed even when *this is destroyed.
+    ValueMapCallbackVH Copy(*this);
+    typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
+    if (M)
+      M->acquire();
+    Config::onDelete(Copy.Map->Data, Copy.Unwrap());  // May destroy *this.
+    Copy.Map->Map.erase(Copy);  // Definitely destroys *this.
+    if (M)
+      M->release();
+  }
+  void allUsesReplacedWith(Value *new_key) override {
+    assert(isa<KeySansPointerT>(new_key) &&
+           "Invalid RAUW on key of ValueMap<>");
+    // Make a copy that won't get changed even when *this is destroyed.
+    ValueMapCallbackVH Copy(*this);
+    typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
+    if (M)
+      M->acquire();
+
+    KeyT typed_new_key = cast<KeySansPointerT>(new_key);
+    // Can destroy *this:
+    Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
+    if (Config::FollowRAUW) {
+      typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
+      // I could == Copy.Map->Map.end() if the onRAUW callback already
+      // removed the old mapping.
+      if (I != Copy.Map->Map.end()) {
+        ValueT Target(I->second);
+        Copy.Map->Map.erase(I);  // Definitely destroys *this.
+        Copy.Map->insert(std::make_pair(typed_new_key, Target));
+      }
+    }
+    if (M)
+      M->release();
+  }
+};
+
+template<typename KeyT, typename ValueT, typename Config>
+struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > {
+  typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
+  typedef DenseMapInfo<KeyT> PointerInfo;
+
+  static inline VH getEmptyKey() {
+    return VH(PointerInfo::getEmptyKey(), nullptr);
+  }
+  static inline VH getTombstoneKey() {
+    return VH(PointerInfo::getTombstoneKey(), nullptr);
+  }
+  static unsigned getHashValue(const VH &Val) {
+    return PointerInfo::getHashValue(Val.Unwrap());
+  }
+  static unsigned getHashValue(const KeyT &Val) {
+    return PointerInfo::getHashValue(Val);
+  }
+  static bool isEqual(const VH &LHS, const VH &RHS) {
+    return LHS == RHS;
+  }
+  static bool isEqual(const KeyT &LHS, const VH &RHS) {
+    return LHS == RHS.getValPtr();
+  }
+};
+
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapIterator :
+    public std::iterator<std::forward_iterator_tag,
+                         std::pair<KeyT, typename DenseMapT::mapped_type>,
+                         ptrdiff_t> {
+  typedef typename DenseMapT::iterator BaseT;
+  typedef typename DenseMapT::mapped_type ValueT;
+  BaseT I;
+public:
+  ValueMapIterator() : I() {}
+
+  ValueMapIterator(BaseT I) : I(I) {}
+
+  BaseT base() const { return I; }
+
+  struct ValueTypeProxy {
+    const KeyT first;
+    ValueT& second;
+    ValueTypeProxy *operator->() { return this; }
+    operator std::pair<KeyT, ValueT>() const {
+      return std::make_pair(first, second);
+    }
+  };
+
+  ValueTypeProxy operator*() const {
+    ValueTypeProxy Result = {I->first.Unwrap(), I->second};
+    return Result;
+  }
+
+  ValueTypeProxy operator->() const {
+    return operator*();
+  }
+
+  bool operator==(const ValueMapIterator &RHS) const {
+    return I == RHS.I;
+  }
+  bool operator!=(const ValueMapIterator &RHS) const {
+    return I != RHS.I;
+  }
+
+  inline ValueMapIterator& operator++() {  // Preincrement
+    ++I;
+    return *this;
+  }
+  ValueMapIterator operator++(int) {  // Postincrement
+    ValueMapIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapConstIterator :
+    public std::iterator<std::forward_iterator_tag,
+                         std::pair<KeyT, typename DenseMapT::mapped_type>,
+                         ptrdiff_t> {
+  typedef typename DenseMapT::const_iterator BaseT;
+  typedef typename DenseMapT::mapped_type ValueT;
+  BaseT I;
+public:
+  ValueMapConstIterator() : I() {}
+  ValueMapConstIterator(BaseT I) : I(I) {}
+  ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
+    : I(Other.base()) {}
+
+  BaseT base() const { return I; }
+
+  struct ValueTypeProxy {
+    const KeyT first;
+    const ValueT& second;
+    ValueTypeProxy *operator->() { return this; }
+    operator std::pair<KeyT, ValueT>() const {
+      return std::make_pair(first, second);
+    }
+  };
+
+  ValueTypeProxy operator*() const {
+    ValueTypeProxy Result = {I->first.Unwrap(), I->second};
+    return Result;
+  }
+
+  ValueTypeProxy operator->() const {
+    return operator*();
+  }
+
+  bool operator==(const ValueMapConstIterator &RHS) const {
+    return I == RHS.I;
+  }
+  bool operator!=(const ValueMapConstIterator &RHS) const {
+    return I != RHS.I;
+  }
+
+  inline ValueMapConstIterator& operator++() {  // Preincrement
+    ++I;
+    return *this;
+  }
+  ValueMapConstIterator operator++(int) {  // Postincrement
+    ValueMapConstIterator tmp = *this; ++*this; return tmp;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h
new file mode 100644
index 0000000..bf1fade
--- /dev/null
+++ b/include/llvm/IR/ValueSymbolTable.h
@@ -0,0 +1,133 @@
+//===-- llvm/ValueSymbolTable.h - Implement a Value Symtab ------*- C++ -*-===//
+//
+//                     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 name/Value symbol table for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VALUESYMBOLTABLE_H
+#define LLVM_IR_VALUESYMBOLTABLE_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  template<typename ValueSubClass, typename ItemParentClass>
+        class SymbolTableListTraits;
+  class BasicBlock;
+  class Function;
+  class NamedMDNode;
+  class Module;
+  class StringRef;
+
+/// This class provides a symbol table of name/value pairs. It is essentially
+/// a std::map<std::string,Value*> but has a controlled interface provided by
+/// LLVM as well as ensuring uniqueness of names.
+///
+class ValueSymbolTable {
+  friend class Value;
+  friend class SymbolTableListTraits<Argument, Function>;
+  friend class SymbolTableListTraits<BasicBlock, Function>;
+  friend class SymbolTableListTraits<Instruction, BasicBlock>;
+  friend class SymbolTableListTraits<Function, Module>;
+  friend class SymbolTableListTraits<GlobalVariable, Module>;
+  friend class SymbolTableListTraits<GlobalAlias, Module>;
+/// @name Types
+/// @{
+public:
+  /// @brief A mapping of names to values.
+  typedef StringMap<Value*> ValueMap;
+
+  /// @brief An iterator over a ValueMap.
+  typedef ValueMap::iterator iterator;
+
+  /// @brief A const_iterator over a ValueMap.
+  typedef ValueMap::const_iterator const_iterator;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+
+  ValueSymbolTable() : vmap(0), LastUnique(0) {}
+  ~ValueSymbolTable();
+
+/// @}
+/// @name Accessors
+/// @{
+public:
+
+  /// This method finds the value with the given \p Name in the
+  /// the symbol table. 
+  /// @returns the value associated with the \p Name
+  /// @brief Lookup a named Value.
+  Value *lookup(StringRef Name) const { return vmap.lookup(Name); }
+
+  /// @returns true iff the symbol table is empty
+  /// @brief Determine if the symbol table is empty
+  inline bool empty() const { return vmap.empty(); }
+
+  /// @brief The number of name/type pairs is returned.
+  inline unsigned size() const { return unsigned(vmap.size()); }
+
+  /// This function can be used from the debugger to display the
+  /// content of the symbol table while debugging.
+  /// @brief Print out symbol table on stderr
+  void dump() const;
+
+/// @}
+/// @name Iteration
+/// @{
+public:
+  /// @brief Get an iterator that from the beginning of the symbol table.
+  inline iterator begin() { return vmap.begin(); }
+
+  /// @brief Get a const_iterator that from the beginning of the symbol table.
+  inline const_iterator begin() const { return vmap.begin(); }
+
+  /// @brief Get an iterator to the end of the symbol table.
+  inline iterator end() { return vmap.end(); }
+
+  /// @brief Get a const_iterator to the end of the symbol table.
+  inline const_iterator end() const { return vmap.end(); }
+  
+/// @}
+/// @name Mutators
+/// @{
+private:
+  /// This method adds the provided value \p N to the symbol table.  The Value
+  /// must have a name which is used to place the value in the symbol table. 
+  /// If the inserted name conflicts, this renames the value.
+  /// @brief Add a named value to the symbol table
+  void reinsertValue(Value *V);
+    
+  /// createValueName - This method attempts to create a value name and insert
+  /// it into the symbol table with the specified name.  If it conflicts, it
+  /// auto-renames the name and returns that instead.
+  ValueName *createValueName(StringRef Name, Value *V);
+  
+  /// This method removes a value from the symbol table.  It leaves the
+  /// ValueName attached to the value, but it is no longer inserted in the
+  /// symtab.
+  void removeValueName(ValueName *V);
+  
+/// @}
+/// @name Internal Data
+/// @{
+private:
+  ValueMap vmap;                    ///< The map that holds the symbol table.
+  mutable uint32_t LastUnique; ///< Counter for tracking unique names
+
+/// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h
new file mode 100644
index 0000000..0272e20
--- /dev/null
+++ b/include/llvm/IR/Verifier.h
@@ -0,0 +1,88 @@
+//===- Verifier.h - LLVM IR Verifier ----------------------------*- 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 function verifier interface, that can be used for some
+// sanity checking of input to the system, and for checking that transformations
+// haven't done something bad.
+//
+// Note that this does not provide full 'java style' security and verifications,
+// instead it just tries to ensure that code is well formed.
+//
+// To see what specifically is checked, look at the top of Verifier.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_VERIFIER_H
+#define LLVM_IR_VERIFIER_H
+
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+
+class Function;
+class FunctionPass;
+class ModulePass;
+class Module;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief Check a function for errors, useful for use when debugging a
+/// pass.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// a message describing the error is written to OS (if non-null) and true is
+/// returned.
+bool verifyFunction(const Function &F, raw_ostream *OS = nullptr);
+
+/// \brief Check a module for errors.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// a message describing the error is written to OS (if non-null) and true is
+/// returned.
+bool verifyModule(const Module &M, raw_ostream *OS = nullptr);
+
+/// \brief Create a verifier pass.
+///
+/// Check a module or function for validity. This is essentially a pass wrapped
+/// around the above verifyFunction and verifyModule routines and
+/// functionality. When the pass detects a verification error it is always
+/// printed to stderr, and by default they are fatal. You can override that by
+/// passing \c false to \p FatalErrors.
+///
+/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
+FunctionPass *createVerifierPass(bool FatalErrors = true);
+
+/// \brief Create a debug-info verifier pass.
+///
+/// Check a module for validity of debug info. This is essentially a pass
+/// wrapped around the debug-info parts of \a verifyModule().  When the pass
+/// detects a verification error it is always printed to stderr, and by default
+/// they are fatal. You can override that by passing \c false to \p
+/// FatalErrors.
+///
+/// Note that this creates a pass suitable for the legacy pass manager. It has
+/// nothing to do with \c VerifierPass.
+ModulePass *createDebugInfoVerifierPass(bool FatalErrors = true);
+
+class VerifierPass {
+  bool FatalErrors;
+
+public:
+  explicit VerifierPass(bool FatalErrors = true) : FatalErrors(FatalErrors) {}
+
+  PreservedAnalyses run(Module *M);
+  PreservedAnalyses run(Function *F);
+
+  static StringRef name() { return "VerifierPass"; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IRReader/IRReader.h b/include/llvm/IRReader/IRReader.h
new file mode 100644
index 0000000..59ffc09
--- /dev/null
+++ b/include/llvm/IRReader/IRReader.h
@@ -0,0 +1,47 @@
+//===---- llvm/IRReader/IRReader.h - Reader for LLVM IR files ---*- 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 functions for reading LLVM IR. They support both
+// Bitcode and Assembly, automatically detecting the input format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IRREADER_IRREADER_H
+#define LLVM_IRREADER_IRREADER_H
+
+#include <string>
+
+namespace llvm {
+
+class Module;
+class MemoryBuffer;
+class SMDiagnostic;
+class LLVMContext;
+
+/// If the given file holds a bitcode image, return a Module
+/// for it which does lazy deserialization of function bodies.  Otherwise,
+/// attempt to parse it as LLVM Assembly and return a fully populated
+/// Module.
+Module *getLazyIRFileModule(const std::string &Filename, SMDiagnostic &Err,
+                            LLVMContext &Context);
+
+/// If the given MemoryBuffer holds a bitcode image, return a Module
+/// for it.  Otherwise, attempt to parse it as LLVM Assembly and return
+/// a Module for it. This function *never* takes ownership of Buffer.
+Module *ParseIR(MemoryBuffer *Buffer, SMDiagnostic &Err, LLVMContext &Context);
+
+/// If the given file holds a bitcode image, return a Module for it.
+/// Otherwise, attempt to parse it as LLVM Assembly and return a Module
+/// for it.
+Module *ParseIRFile(const std::string &Filename, SMDiagnostic &Err,
+                    LLVMContext &Context);
+
+}
+
+#endif
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
new file mode 100644
index 0000000..02f4259
--- /dev/null
+++ b/include/llvm/InitializePasses.h
@@ -0,0 +1,283 @@
+//===- llvm/InitializePasses.h -------- Initialize All Passes ---*- C++ -*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations for the pass initialization routines
+// for the entire LLVM project.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INITIALIZEPASSES_H
+#define LLVM_INITIALIZEPASSES_H
+
+namespace llvm {
+
+class PassRegistry;
+
+/// initializeCore - Initialize all passes linked into the
+/// TransformUtils library.
+void initializeCore(PassRegistry&);
+
+/// initializeTransformUtils - Initialize all passes linked into the
+/// TransformUtils library.
+void initializeTransformUtils(PassRegistry&);
+
+/// initializeScalarOpts - Initialize all passes linked into the
+/// ScalarOpts library.
+void initializeScalarOpts(PassRegistry&);
+
+/// initializeObjCARCOpts - Initialize all passes linked into the ObjCARCOpts
+/// library.
+void initializeObjCARCOpts(PassRegistry&);
+
+/// initializeVectorization - Initialize all passes linked into the
+/// Vectorize library.
+void initializeVectorization(PassRegistry&);
+
+/// initializeInstCombine - Initialize all passes linked into the
+/// ScalarOpts library.
+void initializeInstCombine(PassRegistry&);
+
+/// initializeIPO - Initialize all passes linked into the IPO library.
+void initializeIPO(PassRegistry&);
+
+/// initializeInstrumentation - Initialize all passes linked into the
+/// Instrumentation library.
+void initializeInstrumentation(PassRegistry&);
+
+/// initializeAnalysis - Initialize all passes linked into the Analysis library.
+void initializeAnalysis(PassRegistry&);
+
+/// initializeIPA - Initialize all passes linked into the IPA library.
+void initializeIPA(PassRegistry&);
+
+/// initializeCodeGen - Initialize all passes linked into the CodeGen library.
+void initializeCodeGen(PassRegistry&);
+
+/// initializeCodeGen - Initialize all passes linked into the CodeGen library.
+void initializeTarget(PassRegistry&);
+
+void initializeAAEvalPass(PassRegistry&);
+void initializeAddDiscriminatorsPass(PassRegistry&);
+void initializeADCEPass(PassRegistry&);
+void initializeAliasAnalysisAnalysisGroup(PassRegistry&);
+void initializeAliasAnalysisCounterPass(PassRegistry&);
+void initializeAliasDebuggerPass(PassRegistry&);
+void initializeAliasSetPrinterPass(PassRegistry&);
+void initializeAlwaysInlinerPass(PassRegistry&);
+void initializeArgPromotionPass(PassRegistry&);
+void initializeAtomicExpandLoadLinkedPass(PassRegistry&);
+void initializeSampleProfileLoaderPass(PassRegistry&);
+void initializeBarrierNoopPass(PassRegistry&);
+void initializeBasicAliasAnalysisPass(PassRegistry&);
+void initializeCallGraphWrapperPassPass(PassRegistry &);
+void initializeBasicTTIPass(PassRegistry&);
+void initializeBlockExtractorPassPass(PassRegistry&);
+void initializeBlockFrequencyInfoPass(PassRegistry&);
+void initializeBoundsCheckingPass(PassRegistry&);
+void initializeBranchFolderPassPass(PassRegistry&);
+void initializeBranchProbabilityInfoPass(PassRegistry&);
+void initializeBreakCriticalEdgesPass(PassRegistry&);
+void initializeCallGraphPrinterPass(PassRegistry&);
+void initializeCallGraphViewerPass(PassRegistry&);
+void initializeCFGOnlyPrinterPass(PassRegistry&);
+void initializeCFGOnlyViewerPass(PassRegistry&);
+void initializeCFGPrinterPass(PassRegistry&);
+void initializeCFGSimplifyPassPass(PassRegistry&);
+void initializeFlattenCFGPassPass(PassRegistry&);
+void initializeStructurizeCFGPass(PassRegistry&);
+void initializeCFGViewerPass(PassRegistry&);
+void initializeConstantHoistingPass(PassRegistry&);
+void initializeCodeGenPreparePass(PassRegistry&);
+void initializeConstantMergePass(PassRegistry&);
+void initializeConstantPropagationPass(PassRegistry&);
+void initializeMachineCopyPropagationPass(PassRegistry&);
+void initializeCostModelAnalysisPass(PassRegistry&);
+void initializeCorrelatedValuePropagationPass(PassRegistry&);
+void initializeDAEPass(PassRegistry&);
+void initializeDAHPass(PassRegistry&);
+void initializeDCEPass(PassRegistry&);
+void initializeDSEPass(PassRegistry&);
+void initializeDebugIRPass(PassRegistry&);
+void initializeDebugInfoVerifierLegacyPassPass(PassRegistry &);
+void initializeDeadInstEliminationPass(PassRegistry&);
+void initializeDeadMachineInstructionElimPass(PassRegistry&);
+void initializeDelinearizationPass(PassRegistry &);
+void initializeDependenceAnalysisPass(PassRegistry&);
+void initializeDomOnlyPrinterPass(PassRegistry&);
+void initializeDomOnlyViewerPass(PassRegistry&);
+void initializeDomPrinterPass(PassRegistry&);
+void initializeDomViewerPass(PassRegistry&);
+void initializeDominanceFrontierPass(PassRegistry&);
+void initializeDominatorTreeWrapperPassPass(PassRegistry&);
+void initializeEarlyIfConverterPass(PassRegistry&);
+void initializeEdgeBundlesPass(PassRegistry&);
+void initializeExpandPostRAPass(PassRegistry&);
+void initializeGCOVProfilerPass(PassRegistry&);
+void initializeAddressSanitizerPass(PassRegistry&);
+void initializeAddressSanitizerModulePass(PassRegistry&);
+void initializeMemorySanitizerPass(PassRegistry&);
+void initializeThreadSanitizerPass(PassRegistry&);
+void initializeDataFlowSanitizerPass(PassRegistry&);
+void initializeScalarizerPass(PassRegistry&);
+void initializeEarlyCSEPass(PassRegistry&);
+void initializeExpandISelPseudosPass(PassRegistry&);
+void initializeFindUsedTypesPass(PassRegistry&);
+void initializeFunctionAttrsPass(PassRegistry&);
+void initializeGCMachineCodeAnalysisPass(PassRegistry&);
+void initializeGCModuleInfoPass(PassRegistry&);
+void initializeGVNPass(PassRegistry&);
+void initializeGlobalDCEPass(PassRegistry&);
+void initializeGlobalOptPass(PassRegistry&);
+void initializeGlobalsModRefPass(PassRegistry&);
+void initializeIPCPPass(PassRegistry&);
+void initializeIPSCCPPass(PassRegistry&);
+void initializeIVUsersPass(PassRegistry&);
+void initializeIfConverterPass(PassRegistry&);
+void initializeIndVarSimplifyPass(PassRegistry&);
+void initializeInlineCostAnalysisPass(PassRegistry&);
+void initializeInstCombinerPass(PassRegistry&);
+void initializeInstCountPass(PassRegistry&);
+void initializeInstNamerPass(PassRegistry&);
+void initializeInternalizePassPass(PassRegistry&);
+void initializeIntervalPartitionPass(PassRegistry&);
+void initializeJumpInstrTableInfoPass(PassRegistry&);
+void initializeJumpInstrTablesPass(PassRegistry&);
+void initializeJumpThreadingPass(PassRegistry&);
+void initializeLCSSAPass(PassRegistry&);
+void initializeLICMPass(PassRegistry&);
+void initializeLazyValueInfoPass(PassRegistry&);
+void initializeLibCallAliasAnalysisPass(PassRegistry&);
+void initializeLintPass(PassRegistry&);
+void initializeLiveDebugVariablesPass(PassRegistry&);
+void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveRegMatrixPass(PassRegistry&);
+void initializeLiveStacksPass(PassRegistry&);
+void initializeLiveVariablesPass(PassRegistry&);
+void initializeLoaderPassPass(PassRegistry&);
+void initializeLocalStackSlotPassPass(PassRegistry&);
+void initializeLoopDeletionPass(PassRegistry&);
+void initializeLoopExtractorPass(PassRegistry&);
+void initializeLoopInfoPass(PassRegistry&);
+void initializeLoopInstSimplifyPass(PassRegistry&);
+void initializeLoopRotatePass(PassRegistry&);
+void initializeLoopSimplifyPass(PassRegistry&);
+void initializeLoopStrengthReducePass(PassRegistry&);
+void initializeGlobalMergePass(PassRegistry&);
+void initializeLoopRerollPass(PassRegistry&);
+void initializeLoopUnrollPass(PassRegistry&);
+void initializeLoopUnswitchPass(PassRegistry&);
+void initializeLoopIdiomRecognizePass(PassRegistry&);
+void initializeLowerAtomicPass(PassRegistry&);
+void initializeLowerExpectIntrinsicPass(PassRegistry&);
+void initializeLowerIntrinsicsPass(PassRegistry&);
+void initializeLowerInvokePass(PassRegistry&);
+void initializeLowerSwitchPass(PassRegistry&);
+void initializeMachineBlockFrequencyInfoPass(PassRegistry&);
+void initializeMachineBlockPlacementPass(PassRegistry&);
+void initializeMachineBlockPlacementStatsPass(PassRegistry&);
+void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
+void initializeMachineCSEPass(PassRegistry&);
+void initializeMachineDominatorTreePass(PassRegistry&);
+void initializeMachineDominanceFrontierPass(PassRegistry&);
+void initializeMachinePostDominatorTreePass(PassRegistry&);
+void initializeMachineLICMPass(PassRegistry&);
+void initializeMachineLoopInfoPass(PassRegistry&);
+void initializeMachineModuleInfoPass(PassRegistry&);
+void initializeMachineRegionInfoPassPass(PassRegistry&);
+void initializeMachineSchedulerPass(PassRegistry&);
+void initializeMachineSinkingPass(PassRegistry&);
+void initializeMachineTraceMetricsPass(PassRegistry&);
+void initializeMachineVerifierPassPass(PassRegistry&);
+void initializeMemCpyOptPass(PassRegistry&);
+void initializeMemDepPrinterPass(PassRegistry&);
+void initializeMemoryDependenceAnalysisPass(PassRegistry&);
+void initializeMergedLoadStoreMotionPass(PassRegistry &);
+void initializeMetaRenamerPass(PassRegistry&);
+void initializeMergeFunctionsPass(PassRegistry&);
+void initializeModuleDebugInfoPrinterPass(PassRegistry&);
+void initializeNoAAPass(PassRegistry&);
+void initializeObjCARCAliasAnalysisPass(PassRegistry&);
+void initializeObjCARCAPElimPass(PassRegistry&);
+void initializeObjCARCExpandPass(PassRegistry&);
+void initializeObjCARCContractPass(PassRegistry&);
+void initializeObjCARCOptPass(PassRegistry&);
+void initializeOptimizePHIsPass(PassRegistry&);
+void initializePartiallyInlineLibCallsPass(PassRegistry&);
+void initializePEIPass(PassRegistry&);
+void initializePHIEliminationPass(PassRegistry&);
+void initializePartialInlinerPass(PassRegistry&);
+void initializePeepholeOptimizerPass(PassRegistry&);
+void initializePostDomOnlyPrinterPass(PassRegistry&);
+void initializePostDomOnlyViewerPass(PassRegistry&);
+void initializePostDomPrinterPass(PassRegistry&);
+void initializePostDomViewerPass(PassRegistry&);
+void initializePostDominatorTreePass(PassRegistry&);
+void initializePostRASchedulerPass(PassRegistry&);
+void initializePostMachineSchedulerPass(PassRegistry&);
+void initializePrintFunctionPassWrapperPass(PassRegistry&);
+void initializePrintModulePassWrapperPass(PassRegistry&);
+void initializePrintBasicBlockPassPass(PassRegistry&);
+void initializeProcessImplicitDefsPass(PassRegistry&);
+void initializePromotePassPass(PassRegistry&);
+void initializePruneEHPass(PassRegistry&);
+void initializeReassociatePass(PassRegistry&);
+void initializeRegToMemPass(PassRegistry&);
+void initializeRegionInfoPassPass(PassRegistry&);
+void initializeRegionOnlyPrinterPass(PassRegistry&);
+void initializeRegionOnlyViewerPass(PassRegistry&);
+void initializeRegionPrinterPass(PassRegistry&);
+void initializeRegionViewerPass(PassRegistry&);
+void initializeSCCPPass(PassRegistry&);
+void initializeSROAPass(PassRegistry&);
+void initializeSROA_DTPass(PassRegistry&);
+void initializeSROA_SSAUpPass(PassRegistry&);
+void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
+void initializeScalarEvolutionPass(PassRegistry&);
+void initializeSimpleInlinerPass(PassRegistry&);
+void initializeRegisterCoalescerPass(PassRegistry&);
+void initializeSingleLoopExtractorPass(PassRegistry&);
+void initializeSinkingPass(PassRegistry&);
+void initializeSeparateConstOffsetFromGEPPass(PassRegistry &);
+void initializeSlotIndexesPass(PassRegistry&);
+void initializeSpillPlacementPass(PassRegistry&);
+void initializeStackProtectorPass(PassRegistry&);
+void initializeStackColoringPass(PassRegistry&);
+void initializeStackSlotColoringPass(PassRegistry&);
+void initializeStripDeadDebugInfoPass(PassRegistry&);
+void initializeStripDeadPrototypesPassPass(PassRegistry&);
+void initializeStripDebugDeclarePass(PassRegistry&);
+void initializeStripNonDebugSymbolsPass(PassRegistry&);
+void initializeStripSymbolsPass(PassRegistry&);
+void initializeTailCallElimPass(PassRegistry&);
+void initializeTailDuplicatePassPass(PassRegistry&);
+void initializeTargetPassConfigPass(PassRegistry&);
+void initializeDataLayoutPassPass(PassRegistry &);
+void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
+void initializeNoTTIPass(PassRegistry&);
+void initializeTargetLibraryInfoPass(PassRegistry&);
+void initializeTwoAddressInstructionPassPass(PassRegistry&);
+void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
+void initializeUnifyFunctionExitNodesPass(PassRegistry&);
+void initializeUnreachableBlockElimPass(PassRegistry&);
+void initializeUnreachableMachineBlockElimPass(PassRegistry&);
+void initializeVerifierLegacyPassPass(PassRegistry&);
+void initializeVirtRegMapPass(PassRegistry&);
+void initializeVirtRegRewriterPass(PassRegistry&);
+void initializeInstSimplifierPass(PassRegistry&);
+void initializeUnpackMachineBundlesPass(PassRegistry&);
+void initializeFinalizeMachineBundlesPass(PassRegistry&);
+void initializeLoopVectorizePass(PassRegistry&);
+void initializeSLPVectorizerPass(PassRegistry&);
+void initializeBBVectorizePass(PassRegistry&);
+void initializeMachineFunctionPrinterPassPass(PassRegistry&);
+void initializeStackMapLivenessPass(PassRegistry&);
+void initializeLoadCombinePass(PassRegistry&);
+}
+
+#endif
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
new file mode 100644
index 0000000..b19b232
--- /dev/null
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -0,0 +1,155 @@
+//===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===//
+//
+//                     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 LTOCodeGenerator class.
+//
+//   LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
+//
+//   The Pre-IPO phase compiles source code into bitcode file. The resulting
+// bitcode files, along with object files and libraries, will be fed to the
+// linker to through the IPO and Post-IPO phases. By using obj-file extension,
+// the resulting bitcode file disguises itself as an object file, and therefore
+// obviates the need of writing a special set of the make-rules only for LTO
+// compilation.
+//
+//   The IPO phase perform inter-procedural analyses and optimizations, and
+// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations
+// (SOPT), and intra-procedural target-dependent code generator (CG).
+//
+//   As of this writing, we don't separate IPO and the Post-IPO SOPT. They
+// are intermingled together, and are driven by a single pass manager (see
+// PassManagerBuilder::populateLTOPassManager()).
+//
+//   The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
+// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator"
+// with the machine specific code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LTO_CODE_GENERATOR_H
+#define LTO_CODE_GENERATOR_H
+
+#include "llvm-c/lto.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Linker/Linker.h"
+#include "llvm/Target/TargetOptions.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+  class LLVMContext;
+  class DiagnosticInfo;
+  class GlobalValue;
+  class Mangler;
+  class MemoryBuffer;
+  class TargetLibraryInfo;
+  class TargetMachine;
+  class raw_ostream;
+
+//===----------------------------------------------------------------------===//
+/// C++ class which implements the opaque lto_code_gen_t type.
+///
+struct LTOCodeGenerator {
+  static const char *getVersionString();
+
+  LTOCodeGenerator();
+  ~LTOCodeGenerator();
+
+  // Merge given module, return true on success.
+  bool addModule(struct LTOModule*, std::string &errMsg);
+
+  void setTargetOptions(TargetOptions options);
+  void setDebugInfo(lto_debug_model);
+  void setCodePICModel(lto_codegen_model);
+
+  void setCpu(const char *mCpu) { MCpu = mCpu; }
+  void setAttr(const char *mAttr) { MAttr = mAttr; }
+
+  void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
+
+  // To pass options to the driver and optimization passes. These options are
+  // not necessarily for debugging purpose (The function name is misleading).
+  // This function should be called before LTOCodeGenerator::compilexxx(),
+  // and LTOCodeGenerator::writeMergedModules().
+  void setCodeGenDebugOptions(const char *opts);
+
+  // Parse the options set in setCodeGenDebugOptions. Like
+  // setCodeGenDebugOptions, this must be called before
+  // LTOCodeGenerator::compilexxx() and LTOCodeGenerator::writeMergedModules()
+  void parseCodeGenDebugOptions();
+
+  // Write the merged module to the file specified by the given path.
+  // Return true on success.
+  bool writeMergedModules(const char *path, std::string &errMsg);
+
+  // Compile the merged module into a *single* object file; the path to object
+  // file is returned to the caller via argument "name". Return true on
+  // success.
+  //
+  // NOTE that it is up to the linker to remove the intermediate object file.
+  //  Do not try to remove the object file in LTOCodeGenerator's destructor
+  //  as we don't who (LTOCodeGenerator or the obj file) will last longer.
+  bool compile_to_file(const char **name,
+                       bool disableOpt,
+                       bool disableInline,
+                       bool disableGVNLoadPRE,
+                       std::string &errMsg);
+
+  // As with compile_to_file(), this function compiles the merged module into
+  // single object file. Instead of returning the object-file-path to the caller
+  // (linker), it brings the object to a buffer, and return the buffer to the
+  // caller. This function should delete intermediate object file once its content
+  // is brought to memory. Return NULL if the compilation was not successful.
+  const void *compile(size_t *length,
+                      bool disableOpt,
+                      bool disableInline,
+                      bool disableGVNLoadPRE,
+                      std::string &errMsg);
+
+  void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
+
+private:
+  void initializeLTOPasses();
+
+  bool generateObjectFile(raw_ostream &out, bool disableOpt, bool disableInline,
+                          bool disableGVNLoadPRE, std::string &errMsg);
+  void applyScopeRestrictions();
+  void applyRestriction(GlobalValue &GV, const ArrayRef<StringRef> &Libcalls,
+                        std::vector<const char *> &MustPreserveList,
+                        SmallPtrSet<GlobalValue *, 8> &AsmUsed,
+                        Mangler &Mangler);
+  bool determineTarget(std::string &errMsg);
+
+  static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context);
+
+  void DiagnosticHandler2(const DiagnosticInfo &DI);
+
+  typedef StringMap<uint8_t> StringSet;
+
+  LLVMContext &Context;
+  Linker IRLinker;
+  TargetMachine *TargetMach;
+  bool EmitDwarfDebugInfo;
+  bool ScopeRestrictionsDone;
+  lto_codegen_model CodeModel;
+  StringSet MustPreserveSymbols;
+  StringSet AsmUndefinedRefs;
+  MemoryBuffer *NativeObjectFile;
+  std::vector<char *> CodegenOptions;
+  std::string MCpu;
+  std::string MAttr;
+  std::string NativeObjectPath;
+  TargetOptions Options;
+  lto_diagnostic_handler_t DiagHandler;
+  void *DiagContext;
+};
+}
+#endif // LTO_CODE_GENERATOR_H
diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h
new file mode 100644
index 0000000..c43846a
--- /dev/null
+++ b/include/llvm/LTO/LTOModule.h
@@ -0,0 +1,211 @@
+//===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===//
+//
+//                     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 LTOModule class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LTO_MODULE_H
+#define LTO_MODULE_H
+
+#include "llvm-c/lto.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include <string>
+#include <vector>
+
+// Forward references to llvm classes.
+namespace llvm {
+  class Function;
+  class GlobalValue;
+  class MemoryBuffer;
+  class TargetOptions;
+  class Value;
+
+//===----------------------------------------------------------------------===//
+/// C++ class which implements the opaque lto_module_t type.
+///
+struct LTOModule {
+private:
+  typedef StringMap<uint8_t> StringSet;
+
+  struct NameAndAttributes {
+    const char        *name;
+    uint32_t           attributes;
+    bool               isFunction;
+    const GlobalValue *symbol;
+  };
+
+  std::unique_ptr<object::IRObjectFile> IRFile;
+  std::unique_ptr<TargetMachine> _target;
+  StringSet                               _linkeropt_strings;
+  std::vector<const char *>               _deplibs;
+  std::vector<const char *>               _linkeropts;
+  std::vector<NameAndAttributes>          _symbols;
+
+  // _defines and _undefines only needed to disambiguate tentative definitions
+  StringSet                               _defines;
+  StringMap<NameAndAttributes> _undefines;
+  std::vector<const char*>                _asm_undefines;
+
+  LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM);
+
+public:
+  /// Returns 'true' if the file or memory contents is LLVM bitcode.
+  static bool isBitcodeFile(const void *mem, size_t length);
+  static bool isBitcodeFile(const char *path);
+
+  /// Returns 'true' if the memory buffer is LLVM bitcode for the specified
+  /// triple.
+  static bool isBitcodeForTarget(MemoryBuffer *memBuffer,
+                                 StringRef triplePrefix);
+
+  /// Create a MemoryBuffer from a memory range with an optional name.
+  static MemoryBuffer *makeBuffer(const void *mem, size_t length,
+                                  StringRef name = "");
+
+  /// Create an LTOModule. N.B. These methods take ownership of the buffer. The
+  /// caller must have initialized the Targets, the TargetMCs, the AsmPrinters,
+  /// and the AsmParsers by calling:
+  ///
+  /// InitializeAllTargets();
+  /// InitializeAllTargetMCs();
+  /// InitializeAllAsmPrinters();
+  /// InitializeAllAsmParsers();
+  static LTOModule *createFromFile(const char *path, TargetOptions options,
+                                   std::string &errMsg);
+  static LTOModule *createFromOpenFile(int fd, const char *path, size_t size,
+                                       TargetOptions options,
+                                       std::string &errMsg);
+  static LTOModule *createFromOpenFileSlice(int fd, const char *path,
+                                            size_t map_size, off_t offset,
+                                            TargetOptions options,
+                                            std::string &errMsg);
+  static LTOModule *createFromBuffer(const void *mem, size_t length,
+                                     TargetOptions options, std::string &errMsg,
+                                     StringRef path = "");
+
+  const Module &getModule() const {
+    return const_cast<LTOModule*>(this)->getModule();
+  }
+  Module &getModule() {
+    return IRFile->getModule();
+  }
+
+  /// Return the Module's target triple.
+  const std::string &getTargetTriple() {
+    return getModule().getTargetTriple();
+  }
+
+  /// Set the Module's target triple.
+  void setTargetTriple(StringRef Triple) {
+    getModule().setTargetTriple(Triple);
+  }
+
+  /// Get the number of symbols
+  uint32_t getSymbolCount() {
+    return _symbols.size();
+  }
+
+  /// Get the attributes for a symbol at the specified index.
+  lto_symbol_attributes getSymbolAttributes(uint32_t index) {
+    if (index < _symbols.size())
+      return lto_symbol_attributes(_symbols[index].attributes);
+    return lto_symbol_attributes(0);
+  }
+
+  /// Get the name of the symbol at the specified index.
+  const char *getSymbolName(uint32_t index) {
+    if (index < _symbols.size())
+      return _symbols[index].name;
+    return nullptr;
+  }
+
+  /// Get the number of dependent libraries
+  uint32_t getDependentLibraryCount() {
+    return _deplibs.size();
+  }
+
+  /// Get the dependent library at the specified index.
+  const char *getDependentLibrary(uint32_t index) {
+    if (index < _deplibs.size())
+      return _deplibs[index];
+    return nullptr;
+  }
+
+  /// Get the number of linker options
+  uint32_t getLinkerOptCount() {
+    return _linkeropts.size();
+  }
+
+  /// Get the linker option at the specified index.
+  const char *getLinkerOpt(uint32_t index) {
+    if (index < _linkeropts.size())
+      return _linkeropts[index];
+    return nullptr;
+  }
+
+  const std::vector<const char*> &getAsmUndefinedRefs() {
+    return _asm_undefines;
+  }
+
+private:
+  /// Parse metadata from the module
+  // FIXME: it only parses "Linker Options" metadata at the moment
+  void parseMetadata();
+
+  /// Parse the symbols from the module and model-level ASM and add them to
+  /// either the defined or undefined lists.
+  bool parseSymbols(std::string &errMsg);
+
+  /// Add a symbol which isn't defined just yet to a list to be resolved later.
+  void addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
+                                   bool isFunc);
+
+  /// Add a defined symbol to the list.
+  void addDefinedSymbol(const char *Name, const GlobalValue *def,
+                        bool isFunction);
+
+  /// Add a data symbol as defined to the list.
+  void addDefinedDataSymbol(const object::BasicSymbolRef &Sym);
+  void addDefinedDataSymbol(const char*Name, const GlobalValue *v);
+
+  /// Add a function symbol as defined to the list.
+  void addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym);
+  void addDefinedFunctionSymbol(const char *Name, const Function *F);
+
+  /// Add a global symbol from module-level ASM to the defined list.
+  void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
+
+  /// Add a global symbol from module-level ASM to the undefined list.
+  void addAsmGlobalSymbolUndef(const char *);
+
+  /// Parse i386/ppc ObjC class data structure.
+  void addObjCClass(const GlobalVariable *clgv);
+
+  /// Parse i386/ppc ObjC category data structure.
+  void addObjCCategory(const GlobalVariable *clgv);
+
+  /// Parse i386/ppc ObjC class list data structure.
+  void addObjCClassRef(const GlobalVariable *clgv);
+
+  /// Get string that the data pointer points to.
+  bool objcClassNameFromExpression(const Constant *c, std::string &name);
+
+  /// Create an LTOModule (private version). N.B. This method takes ownership of
+  /// the buffer.
+  static LTOModule *makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
+                                  TargetOptions options, std::string &errMsg);
+};
+}
+#endif // LTO_MODULE_H
diff --git a/include/llvm/LineEditor/LineEditor.h b/include/llvm/LineEditor/LineEditor.h
new file mode 100644
index 0000000..1a9a691
--- /dev/null
+++ b/include/llvm/LineEditor/LineEditor.h
@@ -0,0 +1,153 @@
+//===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINEEDITOR_LINEEDITOR_H
+#define LLVM_LINEEDITOR_LINEEDITOR_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class LineEditor {
+public:
+  /// Create a LineEditor object.
+  ///
+  /// \param ProgName The name of the current program. Used to form a default
+  /// prompt.
+  /// \param HistoryPath Path to the file in which to store history data, if
+  /// possible.
+  /// \param In The input stream used by the editor.
+  /// \param Out The output stream used by the editor.
+  /// \param Err The error stream used by the editor.
+  LineEditor(StringRef ProgName, StringRef HistoryPath = "", FILE *In = stdin,
+             FILE *Out = stdout, FILE *Err = stderr);
+  ~LineEditor();
+
+  /// Reads a line.
+  ///
+  /// \return The line, or llvm::Optional<std::string>() on EOF.
+  llvm::Optional<std::string> readLine() const;
+
+  void saveHistory();
+  void loadHistory();
+
+  static std::string getDefaultHistoryPath(StringRef ProgName);
+
+  /// The action to perform upon a completion request.
+  struct CompletionAction {
+    enum ActionKind {
+      /// Insert Text at the cursor position.
+      AK_Insert,
+      /// Show Completions, or beep if the list is empty.
+      AK_ShowCompletions
+    };
+
+    ActionKind Kind;
+
+    /// The text to insert.
+    std::string Text;
+
+    /// The list of completions to show.
+    std::vector<std::string> Completions;
+  };
+
+  /// A possible completion at a given cursor position.
+  struct Completion {
+    Completion() {}
+    Completion(const std::string &TypedText, const std::string &DisplayText)
+        : TypedText(TypedText), DisplayText(DisplayText) {}
+
+    /// The text to insert. If the user has already input some of the
+    /// completion, this should only include the rest of the text.
+    std::string TypedText;
+
+    /// A description of this completion. This may be the completion itself, or
+    /// maybe a summary of its type or arguments.
+    std::string DisplayText;
+  };
+
+  /// Set the completer for this LineEditor. A completer is a function object
+  /// which takes arguments of type StringRef (the string to complete) and
+  /// size_t (the zero-based cursor position in the StringRef) and returns a
+  /// CompletionAction.
+  template <typename T> void setCompleter(T Comp) {
+    Completer.reset(new CompleterModel<T>(Comp));
+  }
+
+  /// Set the completer for this LineEditor to the given list completer.
+  /// A list completer is a function object which takes arguments of type
+  /// StringRef (the string to complete) and size_t (the zero-based cursor
+  /// position in the StringRef) and returns a std::vector<Completion>.
+  template <typename T> void setListCompleter(T Comp) {
+    Completer.reset(new ListCompleterModel<T>(Comp));
+  }
+
+  /// Use the current completer to produce a CompletionAction for the given
+  /// completion request. If the current completer is a list completer, this
+  /// will return an AK_Insert CompletionAction if each completion has a common
+  /// prefix, or an AK_ShowCompletions CompletionAction otherwise.
+  ///
+  /// \param Buffer The string to complete
+  /// \param Pos The zero-based cursor position in the StringRef
+  CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const;
+
+  const std::string &getPrompt() const { return Prompt; }
+  void setPrompt(const std::string &P) { Prompt = P; }
+
+  // Public so callbacks in LineEditor.cpp can use it.
+  struct InternalData;
+
+private:
+  std::string Prompt;
+  std::string HistoryPath;
+  std::unique_ptr<InternalData> Data;
+
+  struct CompleterConcept {
+    virtual ~CompleterConcept();
+    virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
+  };
+
+  struct ListCompleterConcept : CompleterConcept {
+    ~ListCompleterConcept();
+    CompletionAction complete(StringRef Buffer, size_t Pos) const override;
+    static std::string getCommonPrefix(const std::vector<Completion> &Comps);
+    virtual std::vector<Completion> getCompletions(StringRef Buffer,
+                                                   size_t Pos) const = 0;
+  };
+
+  template <typename T>
+  struct CompleterModel : CompleterConcept {
+    CompleterModel(T Value) : Value(Value) {}
+    CompletionAction complete(StringRef Buffer, size_t Pos) const override {
+      return Value(Buffer, Pos);
+    }
+    T Value;
+  };
+
+  template <typename T>
+  struct ListCompleterModel : ListCompleterConcept {
+    ListCompleterModel(T Value) : Value(Value) {}
+    std::vector<Completion> getCompletions(StringRef Buffer,
+                                           size_t Pos) const override {
+      return Value(Buffer, Pos);
+    }
+    T Value;
+  };
+
+  std::unique_ptr<const CompleterConcept> Completer;
+};
+
+}
+
+#endif
diff --git a/include/llvm/LinkAllIR.h b/include/llvm/LinkAllIR.h
new file mode 100644
index 0000000..2b0604a
--- /dev/null
+++ b/include/llvm/LinkAllIR.h
@@ -0,0 +1,53 @@
+//===----- LinkAllIR.h - Reference All VMCore Code --------------*- C++ -*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all the object modules of the VMCore library so
+// that tools like llc, opt, and lli can ensure they are linked with all symbols
+// from libVMCore.a It should only be used from a tool's main program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKALLIR_H
+#define LLVM_LINKALLIR_H
+
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/TimeValue.h"
+#include <cstdlib>
+
+namespace {
+  struct ForceVMCoreLinking {
+    ForceVMCoreLinking() {
+      // We must reference VMCore in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+      (void)new llvm::Module("", llvm::getGlobalContext());
+      (void)new llvm::UnreachableInst(llvm::getGlobalContext());
+      (void)    llvm::createVerifierPass(); 
+    }
+  } ForceVMCoreLinking;
+}
+
+#endif
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
new file mode 100644
index 0000000..e06560c
--- /dev/null
+++ b/include/llvm/LinkAllPasses.h
@@ -0,0 +1,176 @@
+//===- llvm/LinkAllPasses.h ------------ Reference All Passes ---*- C++ -*-===//
+//
+//                      The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all transformation and analysis passes for tools
+// like opt and bugpoint that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKALLPASSES_H
+#define LLVM_LINKALLPASSES_H
+
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/CallPrinter.h"
+#include "llvm/Analysis/DomPrinter.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/Analysis/Lint.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionPass.h"
+#include "llvm/Analysis/RegionPrinter.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include "llvm/Transforms/Vectorize.h"
+#include <cstdlib>
+
+namespace {
+  struct ForcePassLinking {
+    ForcePassLinking() {
+      // We must reference the passes in such a way that compilers will not
+      // delete it all as dead code, even with whole program optimization,
+      // yet is effectively a NO-OP. As the compiler isn't smart enough
+      // to know that getenv() never returns -1, this will do the job.
+      if (std::getenv("bar") != (char*) -1)
+        return;
+
+      (void) llvm::createAAEvalPass();
+      (void) llvm::createAggressiveDCEPass();
+      (void) llvm::createAliasAnalysisCounterPass();
+      (void) llvm::createAliasDebugger();
+      (void) llvm::createArgumentPromotionPass();
+      (void) llvm::createBasicAliasAnalysisPass();
+      (void) llvm::createLibCallAliasAnalysisPass(nullptr);
+      (void) llvm::createScalarEvolutionAliasAnalysisPass();
+      (void) llvm::createTypeBasedAliasAnalysisPass();
+      (void) llvm::createBoundsCheckingPass();
+      (void) llvm::createBreakCriticalEdgesPass();
+      (void) llvm::createCallGraphPrinterPass();
+      (void) llvm::createCallGraphViewerPass();
+      (void) llvm::createCFGSimplificationPass();
+      (void) llvm::createStructurizeCFGPass();
+      (void) llvm::createConstantMergePass();
+      (void) llvm::createConstantPropagationPass();
+      (void) llvm::createCostModelAnalysisPass();
+      (void) llvm::createDeadArgEliminationPass();
+      (void) llvm::createDeadCodeEliminationPass();
+      (void) llvm::createDeadInstEliminationPass();
+      (void) llvm::createDeadStoreEliminationPass();
+      (void) llvm::createDependenceAnalysisPass();
+      (void) llvm::createDomOnlyPrinterPass();
+      (void) llvm::createDomPrinterPass();
+      (void) llvm::createDomOnlyViewerPass();
+      (void) llvm::createDomViewerPass();
+      (void) llvm::createGCOVProfilerPass();
+      (void) llvm::createFunctionInliningPass();
+      (void) llvm::createAlwaysInlinerPass();
+      (void) llvm::createGlobalDCEPass();
+      (void) llvm::createGlobalOptimizerPass();
+      (void) llvm::createGlobalsModRefPass();
+      (void) llvm::createIPConstantPropagationPass();
+      (void) llvm::createIPSCCPPass();
+      (void) llvm::createIndVarSimplifyPass();
+      (void) llvm::createInstructionCombiningPass();
+      (void) llvm::createInternalizePass();
+      (void) llvm::createJumpInstrTableInfoPass();
+      (void) llvm::createJumpInstrTablesPass();
+      (void) llvm::createLCSSAPass();
+      (void) llvm::createLICMPass();
+      (void) llvm::createLazyValueInfoPass();
+      (void) llvm::createLoopExtractorPass();
+      (void) llvm::createLoopSimplifyPass();
+      (void) llvm::createLoopStrengthReducePass();
+      (void) llvm::createLoopRerollPass();
+      (void) llvm::createLoopUnrollPass();
+      (void) llvm::createLoopUnswitchPass();
+      (void) llvm::createLoopIdiomPass();
+      (void) llvm::createLoopRotatePass();
+      (void) llvm::createLowerExpectIntrinsicPass();
+      (void) llvm::createLowerInvokePass();
+      (void) llvm::createLowerSwitchPass();
+      (void) llvm::createNoAAPass();
+      (void) llvm::createObjCARCAliasAnalysisPass();
+      (void) llvm::createObjCARCAPElimPass();
+      (void) llvm::createObjCARCExpandPass();
+      (void) llvm::createObjCARCContractPass();
+      (void) llvm::createObjCARCOptPass();
+      (void) llvm::createPromoteMemoryToRegisterPass();
+      (void) llvm::createDemoteRegisterToMemoryPass();
+      (void) llvm::createPruneEHPass();
+      (void) llvm::createPostDomOnlyPrinterPass();
+      (void) llvm::createPostDomPrinterPass();
+      (void) llvm::createPostDomOnlyViewerPass();
+      (void) llvm::createPostDomViewerPass();
+      (void) llvm::createReassociatePass();
+      (void) llvm::createRegionInfoPass();
+      (void) llvm::createRegionOnlyPrinterPass();
+      (void) llvm::createRegionOnlyViewerPass();
+      (void) llvm::createRegionPrinterPass();
+      (void) llvm::createRegionViewerPass();
+      (void) llvm::createSCCPPass();
+      (void) llvm::createScalarReplAggregatesPass();
+      (void) llvm::createSingleLoopExtractorPass();
+      (void) llvm::createStripSymbolsPass();
+      (void) llvm::createStripNonDebugSymbolsPass();
+      (void) llvm::createStripDeadDebugInfoPass();
+      (void) llvm::createStripDeadPrototypesPass();
+      (void) llvm::createTailCallEliminationPass();
+      (void) llvm::createJumpThreadingPass();
+      (void) llvm::createUnifyFunctionExitNodesPass();
+      (void) llvm::createInstCountPass();
+      (void) llvm::createConstantHoistingPass();
+      (void) llvm::createCodeGenPreparePass();
+      (void) llvm::createEarlyCSEPass();
+      (void)llvm::createMergedLoadStoreMotionPass();
+      (void) llvm::createGVNPass();
+      (void) llvm::createMemCpyOptPass();
+      (void) llvm::createLoopDeletionPass();
+      (void) llvm::createPostDomTree();
+      (void) llvm::createInstructionNamerPass();
+      (void) llvm::createMetaRenamerPass();
+      (void) llvm::createFunctionAttrsPass();
+      (void) llvm::createMergeFunctionsPass();
+      (void) llvm::createPrintModulePass(*(llvm::raw_ostream*)nullptr);
+      (void) llvm::createPrintFunctionPass(*(llvm::raw_ostream*)nullptr);
+      (void) llvm::createPrintBasicBlockPass(*(llvm::raw_ostream*)nullptr);
+      (void) llvm::createModuleDebugInfoPrinterPass();
+      (void) llvm::createPartialInliningPass();
+      (void) llvm::createLintPass();
+      (void) llvm::createSinkingPass();
+      (void) llvm::createLowerAtomicPass();
+      (void) llvm::createCorrelatedValuePropagationPass();
+      (void) llvm::createMemDepPrinter();
+      (void) llvm::createInstructionSimplifierPass();
+      (void) llvm::createLoopVectorizePass();
+      (void) llvm::createSLPVectorizerPass();
+      (void) llvm::createBBVectorizePass();
+      (void) llvm::createPartiallyInlineLibCallsPass();
+      (void) llvm::createScalarizerPass();
+      (void) llvm::createSeparateConstOffsetFromGEPPass();
+
+      (void)new llvm::IntervalPartition();
+      (void)new llvm::FindUsedTypes();
+      (void)new llvm::ScalarEvolution();
+      ((llvm::Function*)nullptr)->viewCFGOnly();
+      llvm::RGPassManager RGM;
+      ((llvm::RegionPass*)nullptr)->runOnRegion((llvm::Region*)nullptr, RGM);
+      llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)nullptr);
+      X.add((llvm::Value*)nullptr, 0, nullptr);  // for -print-alias-sets
+    }
+  } ForcePassLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h
new file mode 100644
index 0000000..6254bbb
--- /dev/null
+++ b/include/llvm/Linker/Linker.h
@@ -0,0 +1,63 @@
+//===- Linker.h - Module Linker Interface -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER_LINKER_H
+#define LLVM_LINKER_LINKER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include <string>
+
+namespace llvm {
+
+class Comdat;
+class GlobalValue;
+class Module;
+class StringRef;
+class StructType;
+
+/// This class provides the core functionality of linking in LLVM. It keeps a
+/// pointer to the merged module so far. It doesn't take ownership of the
+/// module since it is assumed that the user of this class will want to do
+/// something with it after the linking.
+class Linker {
+  public:
+    enum LinkerMode {
+      DestroySource = 0, // Allow source module to be destroyed.
+      PreserveSource = 1 // Preserve the source module.
+    };
+
+    Linker(Module *M, bool SuppressWarnings=false);
+    ~Linker();
+
+    Module *getModule() const { return Composite; }
+    void deleteModule();
+
+    /// \brief Link \p Src into the composite. The source is destroyed if
+    /// \p Mode is DestroySource and preserved if it is PreserveSource.
+    /// If \p ErrorMsg is not null, information about any error is written
+    /// to it.
+    /// Returns true on error.
+    bool linkInModule(Module *Src, unsigned Mode, std::string *ErrorMsg);
+    bool linkInModule(Module *Src, std::string *ErrorMsg) {
+      return linkInModule(Src, Linker::DestroySource, ErrorMsg);
+    }
+
+    static bool LinkModules(Module *Dest, Module *Src, unsigned Mode,
+                            std::string *ErrorMsg);
+
+  private:
+    Module *Composite;
+    SmallPtrSet<StructType*, 32> IdentifiedStructTypes;
+
+    bool SuppressWarnings;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h
new file mode 100644
index 0000000..2e76074
--- /dev/null
+++ b/include/llvm/MC/ConstantPools.h
@@ -0,0 +1,92 @@
+//===- ConstantPool.h - Keep track of assembler-generated  ------*- 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 ConstantPool and AssemblerConstantPools classes.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_CONSTANTPOOL_H
+#define LLVM_MC_CONSTANTPOOL_H
+
+#include "llvm/ADT/SmallVector.h"
+namespace llvm {
+class MCContext;
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+
+struct ConstantPoolEntry {
+  ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz)
+    : Label(L), Value(Val), Size(Sz) {}
+  MCSymbol *Label;
+  const MCExpr *Value;
+  unsigned Size;
+};
+
+// A class to keep track of assembler-generated constant pools that are use to
+// implement the ldr-pseudo.
+class ConstantPool {
+  typedef SmallVector<ConstantPoolEntry, 4> EntryVecTy;
+  EntryVecTy Entries;
+
+public:
+  // Initialize a new empty constant pool
+  ConstantPool() {}
+
+  // Add a new entry to the constant pool in the next slot.
+  // \param Value is the new entry to put in the constant pool.
+  // \param Size is the size in bytes of the entry
+  //
+  // \returns a MCExpr that references the newly inserted value
+  const MCExpr *addEntry(const MCExpr *Value, MCContext &Context,
+                         unsigned Size);
+
+  // Emit the contents of the constant pool using the provided streamer.
+  void emitEntries(MCStreamer &Streamer);
+
+  // Return true if the constant pool is empty
+  bool empty();
+};
+
+class AssemblerConstantPools {
+  // Map type used to keep track of per-Section constant pools used by the
+  // ldr-pseudo opcode. The map associates a section to its constant pool. The
+  // constant pool is a vector of (label, value) pairs. When the ldr
+  // pseudo is parsed we insert a new (label, value) pair into the constant pool
+  // for the current section and add MCSymbolRefExpr to the new label as
+  // an opcode to the ldr. After we have parsed all the user input we
+  // output the (label, value) pairs in each constant pool at the end of the
+  // section.
+  //
+  // We use the MapVector for the map type to ensure stable iteration of
+  // the sections at the end of the parse. We need to iterate over the
+  // sections in a stable order to ensure that we have print the
+  // constant pools in a deterministic order when printing an assembly
+  // file.
+  typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
+  ConstantPoolMapTy ConstantPools;
+
+public:
+  AssemblerConstantPools() {}
+  ~AssemblerConstantPools() {}
+
+  void emitAll(MCStreamer &Streamer);
+  void emitForCurrentSection(MCStreamer &Streamer);
+  const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
+                         unsigned Size);
+
+private:
+  ConstantPool *getConstantPool(const MCSection *Section);
+  ConstantPool &getOrCreateConstantPool(const MCSection *Section);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAnalysis/MCAtom.h b/include/llvm/MC/MCAnalysis/MCAtom.h
new file mode 100644
index 0000000..33f3431
--- /dev/null
+++ b/include/llvm/MC/MCAnalysis/MCAtom.h
@@ -0,0 +1,199 @@
+//===-- MCAtom.h ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCAtom class, which is used to
+// represent a contiguous region in a decoded object that is uniformly data or
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCANALYSIS_MCATOM_H
+#define LLVM_MC_MCANALYSIS_MCATOM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MCModule;
+
+class MCAtom;
+class MCTextAtom;
+class MCDataAtom;
+
+/// \brief Represents a contiguous range of either instructions (a TextAtom)
+/// or data (a DataAtom).  Address ranges are expressed as _closed_ intervals.
+class MCAtom {
+  virtual void anchor();
+public:
+  virtual ~MCAtom() {}
+
+  enum AtomKind { TextAtom, DataAtom };
+  AtomKind getKind() const { return Kind; }
+
+  /// \brief Get the start address of the atom.
+  uint64_t getBeginAddr() const { return Begin; }
+  /// \brief Get the end address, i.e. the last one inside the atom.
+  uint64_t getEndAddr() const { return End; }
+
+  /// \name Atom modification methods:
+  /// When modifying a TextAtom, keep instruction boundaries in mind.
+  /// For instance, split must me given the start address of an instruction.
+  /// @{
+
+  /// \brief Splits the atom in two at a given address.
+  /// \param SplitPt Address at which to start a new atom, splitting this one.
+  /// \returns The newly created atom starting at \p SplitPt.
+  virtual MCAtom *split(uint64_t SplitPt) = 0;
+
+  /// \brief Truncates an atom, discarding everything after \p TruncPt.
+  /// \param TruncPt Last byte address to be contained in this atom.
+  virtual void truncate(uint64_t TruncPt) = 0;
+  /// @}
+
+  /// \name Naming:
+  ///
+  /// This is mostly for display purposes, and may contain anything that hints
+  /// at what the atom contains: section or symbol name, BB start address, ..
+  /// @{
+  StringRef getName() const { return Name; }
+  void setName(StringRef NewName) { Name = NewName.str(); }
+  /// @}
+
+protected:
+  const AtomKind Kind;
+  std::string Name;
+  MCModule *Parent;
+  uint64_t Begin, End;
+
+  friend class MCModule;
+  MCAtom(AtomKind K, MCModule *P, uint64_t B, uint64_t E)
+    : Kind(K), Name("(unknown)"), Parent(P), Begin(B), End(E) { }
+
+  /// \name Atom remapping helpers
+  /// @{
+
+  /// \brief Remap the atom, using the given range, updating Begin/End.
+  /// One or both of the bounds can remain the same, but overlapping with other
+  /// atoms in the module is still forbidden.
+  void remap(uint64_t NewBegin, uint64_t NewEnd);
+
+  /// \brief Remap the atom to prepare for a truncation at TruncPt.
+  /// Equivalent to:
+  /// \code
+  ///   // Bound checks
+  ///   remap(Begin, TruncPt);
+  /// \endcode
+  void remapForTruncate(uint64_t TruncPt);
+
+  /// \brief Remap the atom to prepare for a split at SplitPt.
+  /// The bounds for the resulting atoms are returned in {L,R}{Begin,End}.
+  /// The current atom is truncated to \p LEnd.
+  void remapForSplit(uint64_t SplitPt,
+                     uint64_t &LBegin, uint64_t &LEnd,
+                     uint64_t &RBegin, uint64_t &REnd);
+  /// @}
+};
+
+/// \name Text atom
+/// @{
+
+/// \brief An entry in an MCTextAtom: a disassembled instruction.
+/// NOTE: Both the Address and Size field are actually redundant when taken in
+/// the context of the text atom, and may better be exposed in an iterator
+/// instead of stored in the atom, which would replace this class.
+class MCDecodedInst {
+public:
+  MCInst Inst;
+  uint64_t Address;
+  uint64_t Size;
+  MCDecodedInst(const MCInst &Inst, uint64_t Address, uint64_t Size)
+    : Inst(Inst), Address(Address), Size(Size) {}
+};
+
+/// \brief An atom consisting of disassembled instructions.
+class MCTextAtom : public MCAtom {
+private:
+  typedef std::vector<MCDecodedInst> InstListTy;
+  InstListTy Insts;
+
+  /// \brief The address of the next appended instruction, i.e., the
+  /// address immediately after the last instruction in the atom.
+  uint64_t NextInstAddress;
+public:
+  /// Append an instruction, expanding the atom if necessary.
+  void addInst(const MCInst &Inst, uint64_t Size);
+
+  /// \name Instruction list access
+  /// @{
+  typedef InstListTy::const_iterator const_iterator;
+  const_iterator begin() const { return Insts.begin(); }
+  const_iterator end()   const { return Insts.end(); }
+
+  const MCDecodedInst &back() const { return Insts.back(); }
+  const MCDecodedInst &at(size_t n) const { return Insts.at(n); }
+  size_t size() const { return Insts.size(); }
+  /// @}
+
+  /// \name Atom type specific split/truncate logic.
+  /// @{
+  MCTextAtom *split(uint64_t SplitPt) override;
+  void     truncate(uint64_t TruncPt) override;
+  /// @}
+
+  // Class hierarchy.
+  static bool classof(const MCAtom *A) { return A->getKind() == TextAtom; }
+private:
+  friend class MCModule;
+  // Private constructor - only callable by MCModule
+  MCTextAtom(MCModule *P, uint64_t Begin, uint64_t End)
+    : MCAtom(TextAtom, P, Begin, End), NextInstAddress(Begin) {}
+};
+/// @}
+
+/// \name Data atom
+/// @{
+
+/// \brief An entry in an MCDataAtom.
+// NOTE: This may change to a more complex type in the future.
+typedef uint8_t MCData;
+
+/// \brief An atom consising of a sequence of bytes.
+class MCDataAtom : public MCAtom {
+  std::vector<MCData> Data;
+
+public:
+  /// Append a data entry, expanding the atom if necessary.
+  void addData(const MCData &D);
+
+  /// Get a reference to the data in this atom.
+  ArrayRef<MCData> getData() const { return Data; }
+
+  /// \name Atom type specific split/truncate logic.
+  /// @{
+  MCDataAtom *split(uint64_t SplitPt) override;
+  void     truncate(uint64_t TruncPt) override;
+  /// @}
+
+  // Class hierarchy.
+  static bool classof(const MCAtom *A) { return A->getKind() == DataAtom; }
+private:
+  friend class MCModule;
+  // Private constructor - only callable by MCModule
+  MCDataAtom(MCModule *P, uint64_t Begin, uint64_t End)
+    : MCAtom(DataAtom, P, Begin, End) {
+    Data.reserve(End + 1 - Begin);
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCAnalysis/MCFunction.h b/include/llvm/MC/MCAnalysis/MCFunction.h
new file mode 100644
index 0000000..44fa450
--- /dev/null
+++ b/include/llvm/MC/MCAnalysis/MCFunction.h
@@ -0,0 +1,142 @@
+//===-- MCFunction.h --------------------------------------------*- 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 data structures to hold a CFG reconstructed from
+// machine code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCANALYSIS_MCFUNCTION_H
+#define LLVM_MC_MCANALYSIS_MCFUNCTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCInst.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class MCFunction;
+class MCModule;
+class MCTextAtom;
+
+/// \brief Basic block containing a sequence of disassembled instructions.
+/// The basic block is backed by an MCTextAtom, which holds the instructions,
+/// and the address range it covers.
+/// Create a basic block using MCFunction::createBlock.
+class MCBasicBlock {
+  const MCTextAtom *Insts;
+
+  // MCFunction owns the basic block.
+  MCFunction *Parent;
+  friend class MCFunction;
+  MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent);
+
+  /// \name Predecessors/Successors, to represent the CFG.
+  /// @{
+  typedef std::vector<const MCBasicBlock *> BasicBlockListTy;
+  BasicBlockListTy Successors;
+  BasicBlockListTy Predecessors;
+  /// @}
+public:
+
+  /// \brief Get the backing MCTextAtom, containing the instruction sequence.
+  const MCTextAtom *getInsts() const { return Insts; }
+
+  /// \name Get the owning MCFunction.
+  /// @{
+  const MCFunction *getParent() const { return Parent; }
+        MCFunction *getParent()       { return Parent; }
+  /// @}
+
+  /// MC CFG access: Predecessors/Successors.
+  /// @{
+  typedef BasicBlockListTy::const_iterator succ_const_iterator;
+  succ_const_iterator succ_begin() const { return Successors.begin(); }
+  succ_const_iterator succ_end()   const { return Successors.end(); }
+
+  typedef BasicBlockListTy::const_iterator pred_const_iterator;
+  pred_const_iterator pred_begin() const { return Predecessors.begin(); }
+  pred_const_iterator pred_end()   const { return Predecessors.end(); }
+
+  void addSuccessor(const MCBasicBlock *MCBB);
+  bool isSuccessor(const MCBasicBlock *MCBB) const;
+
+  void addPredecessor(const MCBasicBlock *MCBB);
+  bool isPredecessor(const MCBasicBlock *MCBB) const;
+
+  /// \brief Split block, mirrorring NewAtom = Insts->split(..).
+  /// This moves all successors to \p SplitBB, and
+  /// adds a fallthrough to it.
+  /// \p SplitBB The result of splitting Insts, a basic block directly following
+  /// this basic block.
+  void splitBasicBlock(MCBasicBlock *SplitBB);
+  /// @}
+};
+
+/// \brief Represents a function in machine code, containing MCBasicBlocks.
+/// MCFunctions are created by MCModule.
+class MCFunction {
+  MCFunction           (const MCFunction&) LLVM_DELETED_FUNCTION;
+  MCFunction& operator=(const MCFunction&) LLVM_DELETED_FUNCTION;
+
+  std::string Name;
+  MCModule *ParentModule;
+  typedef std::vector<std::unique_ptr<MCBasicBlock>> BasicBlockListTy;
+  BasicBlockListTy Blocks;
+
+  // MCModule owns the function.
+  friend class MCModule;
+  MCFunction(StringRef Name, MCModule *Parent);
+
+public:
+  /// \brief Create an MCBasicBlock backed by Insts and add it to this function.
+  /// \param Insts Sequence of straight-line code backing the basic block.
+  /// \returns The newly created basic block.
+  MCBasicBlock &createBlock(const MCTextAtom &Insts);
+
+  StringRef getName() const { return Name; }
+
+  /// \name Get the owning MC Module.
+  /// @{
+  const MCModule *getParent() const { return ParentModule; }
+        MCModule *getParent()       { return ParentModule; }
+  /// @}
+
+  /// \name Access to the function's basic blocks. No ordering is enforced,
+  /// except that the first block is the entry block.
+  /// @{
+  /// \brief Get the entry point basic block.
+  const MCBasicBlock *getEntryBlock() const { return front(); }
+        MCBasicBlock *getEntryBlock()       { return front(); }
+
+  bool empty() const { return Blocks.empty(); }
+
+  typedef BasicBlockListTy::const_iterator const_iterator;
+  typedef BasicBlockListTy::      iterator       iterator;
+  const_iterator begin() const { return Blocks.begin(); }
+        iterator begin()       { return Blocks.begin(); }
+  const_iterator   end() const { return Blocks.end(); }
+        iterator   end()       { return Blocks.end(); }
+
+  const MCBasicBlock* front() const { return Blocks.front().get(); }
+        MCBasicBlock* front()       { return Blocks.front().get(); }
+  const MCBasicBlock*  back() const { return Blocks.back().get(); }
+        MCBasicBlock*  back()       { return Blocks.back().get(); }
+
+  /// \brief Find the basic block, if any, that starts at \p StartAddr.
+  const MCBasicBlock *find(uint64_t StartAddr) const;
+        MCBasicBlock *find(uint64_t StartAddr);
+  /// @}
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCAnalysis/MCModule.h b/include/llvm/MC/MCAnalysis/MCModule.h
new file mode 100644
index 0000000..cf7e2c0
--- /dev/null
+++ b/include/llvm/MC/MCAnalysis/MCModule.h
@@ -0,0 +1,134 @@
+//===-- MCModule.h - MCModule class -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCModule class, which is used to
+// represent a complete, disassembled object file or executable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCANALYSIS_MCMODULE_H
+#define LLVM_MC_MCANALYSIS_MCMODULE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+class MCAtom;
+class MCBasicBlock;
+class MCDataAtom;
+class MCFunction;
+class MCObjectDisassembler;
+class MCTextAtom;
+
+/// \brief A completely disassembled object file or executable.
+/// It comprises a list of MCAtom's, each representing a contiguous range of
+/// either instructions or data.
+/// An MCModule is created using MCObjectDisassembler::buildModule.
+class MCModule {
+  /// \name Atom tracking
+  /// @{
+
+  /// \brief Atoms in this module, sorted by begin address.
+  /// FIXME: This doesn't handle overlapping atoms (which happen when a basic
+  /// block starts in the middle of an instruction of another basic block.)
+  typedef std::vector<MCAtom*> AtomListTy;
+  AtomListTy Atoms;
+
+  // For access to map/remap.
+  friend class MCAtom;
+
+  /// \brief Remap \p Atom to the given range, and update its Begin/End fields.
+  /// \param Atom An atom belonging to this module.
+  /// An atom should always use this method to update its bounds, because this
+  /// enables the owning MCModule to keep track of its atoms.
+  void remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd);
+
+  /// \brief Insert an atom in the module, using its Begin and End addresses.
+  void map(MCAtom *NewAtom);
+  /// @}
+
+  /// \name Basic block tracking
+  /// @{
+  typedef std::vector<MCBasicBlock*> BBsByAtomTy;
+  BBsByAtomTy BBsByAtom;
+
+  // For access to basic block > atom tracking.
+  friend class MCBasicBlock;
+  friend class MCTextAtom;
+
+  /// \brief Keep track of \p BBBackedByAtom as being backed by \p Atom.
+  /// This is used to update succs/preds when \p Atom is split.
+  void trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BBBackedByAtom);
+  void splitBasicBlocksForAtom(const MCTextAtom *TA, const MCTextAtom *NewTA);
+  /// @}
+
+  /// \name Function tracking
+  /// @{
+  typedef std::vector<std::unique_ptr<MCFunction>> FunctionListTy;
+  FunctionListTy Functions;
+  /// @}
+
+  /// The address of the entrypoint function.
+  uint64_t Entrypoint;
+
+  MCModule           (const MCModule &) LLVM_DELETED_FUNCTION;
+  MCModule& operator=(const MCModule &) LLVM_DELETED_FUNCTION;
+
+  // MCObjectDisassembler creates MCModules.
+  friend class MCObjectDisassembler;
+
+public:
+  MCModule();
+  ~MCModule();
+
+  /// \name Create a new MCAtom covering the specified offset range.
+  /// @{
+  MCTextAtom *createTextAtom(uint64_t Begin, uint64_t End);
+  MCDataAtom *createDataAtom(uint64_t Begin, uint64_t End);
+  /// @}
+
+  /// \name Access to the owned atom list, ordered by begin address.
+  /// @{
+  const MCAtom *findAtomContaining(uint64_t Addr) const;
+        MCAtom *findAtomContaining(uint64_t Addr);
+  const MCAtom *findFirstAtomAfter(uint64_t Addr) const;
+        MCAtom *findFirstAtomAfter(uint64_t Addr);
+
+  typedef AtomListTy::const_iterator const_atom_iterator;
+  typedef AtomListTy::      iterator       atom_iterator;
+  const_atom_iterator atom_begin() const { return Atoms.begin(); }
+        atom_iterator atom_begin()       { return Atoms.begin(); }
+  const_atom_iterator atom_end()   const { return Atoms.end(); }
+        atom_iterator atom_end()         { return Atoms.end(); }
+  /// @}
+
+  /// \brief Create a new MCFunction.
+  MCFunction *createFunction(StringRef Name);
+
+  /// \name Access to the owned function list.
+  /// @{
+  typedef FunctionListTy::const_iterator const_func_iterator;
+  typedef FunctionListTy::      iterator       func_iterator;
+  const_func_iterator func_begin() const { return Functions.begin(); }
+        func_iterator func_begin()       { return Functions.begin(); }
+  const_func_iterator func_end()   const { return Functions.end(); }
+        func_iterator func_end()         { return Functions.end(); }
+  /// @}
+
+  /// \brief Get the address of the entrypoint function, or 0 if there is none.
+  uint64_t getEntrypoint() const { return Entrypoint; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCAnalysis/MCModuleYAML.h b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
new file mode 100644
index 0000000..4856277
--- /dev/null
+++ b/include/llvm/MC/MCAnalysis/MCModuleYAML.h
@@ -0,0 +1,40 @@
+//===- MCModuleYAML.h - MCModule YAMLIO implementation ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares classes for handling the YAML representation
+/// of MCModule.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCANALYSIS_MCMODULEYAML_H
+#define LLVM_MC_MCANALYSIS_MCMODULEYAML_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCAnalysis/MCModule.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class MCInstrInfo;
+class MCRegisterInfo;
+
+/// \brief Dump a YAML representation of the MCModule \p MCM to \p OS.
+/// \returns The empty string on success, an error message on failure.
+StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
+                        const MCInstrInfo &MII, const MCRegisterInfo &MRI);
+
+/// \brief Creates a new module and returns it in \p MCM.
+/// \returns The empty string on success, an error message on failure.
+StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
+                        const MCInstrInfo &MII, const MCRegisterInfo &MRI);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
new file mode 100644
index 0000000..82b65fd
--- /dev/null
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -0,0 +1,156 @@
+//===-- llvm/MC/MCAsmBack.h - MC Asm Backend --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMBACKEND_H
+#define LLVM_MC_MCASMBACKEND_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+class MCAsmLayout;
+class MCAssembler;
+class MCELFObjectTargetWriter;
+struct MCFixupKindInfo;
+class MCFragment;
+class MCInst;
+class MCRelaxableFragment;
+class MCObjectWriter;
+class MCSection;
+class MCValue;
+class raw_ostream;
+
+/// MCAsmBackend - Generic interface to target specific assembler backends.
+class MCAsmBackend {
+  MCAsmBackend(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCAsmBackend &) LLVM_DELETED_FUNCTION;
+
+protected: // Can only create subclasses.
+  MCAsmBackend();
+
+  unsigned HasDataInCodeSupport : 1;
+
+public:
+  virtual ~MCAsmBackend();
+
+  /// lifetime management
+  virtual void reset() {}
+
+  /// createObjectWriter - Create a new MCObjectWriter instance for use by the
+  /// assembler backend to emit the final object file.
+  virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
+
+  /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable
+  /// non-standard ELFObjectWriters.
+  virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const {
+    llvm_unreachable("createELFObjectTargetWriter is not supported by asm "
+                     "backend");
+  }
+
+  /// hasDataInCodeSupport - Check whether this target implements data-in-code
+  /// markers. If not, data region directives will be ignored.
+  bool hasDataInCodeSupport() const { return HasDataInCodeSupport; }
+
+  /// doesSectionRequireSymbols - Check whether the given section requires that
+  /// all symbols (even temporaries) have symbol table entries.
+  virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+    return false;
+  }
+
+  /// isSectionAtomizable - Check whether the given section can be split into
+  /// atoms.
+  ///
+  /// \see MCAssembler::isSymbolLinkerVisible().
+  virtual bool isSectionAtomizable(const MCSection &Section) const {
+    return true;
+  }
+
+  /// @name Target Fixup Interfaces
+  /// @{
+
+  /// getNumFixupKinds - Get the number of target specific fixup kinds.
+  virtual unsigned getNumFixupKinds() const = 0;
+
+  /// getFixupKindInfo - Get information on a fixup kind.
+  virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+  /// processFixupValue - Target hook to adjust the literal value of a fixup
+  /// if necessary. IsResolved signals whether the caller believes a relocation
+  /// is needed; the target can modify the value. The default does nothing.
+  virtual void processFixupValue(const MCAssembler &Asm,
+                                 const MCAsmLayout &Layout,
+                                 const MCFixup &Fixup, const MCFragment *DF,
+                                 const MCValue &Target, uint64_t &Value,
+                                 bool &IsResolved) {}
+
+  /// applyFixup - Apply the \p Value for given \p Fixup into the provided
+  /// data fragment, at the offset specified by the fixup and following the
+  /// fixup kind as appropriate.
+  virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
+                          uint64_t Value, bool IsPCRel) const = 0;
+
+  /// @}
+
+  /// @name Target Relaxation Interfaces
+  /// @{
+
+  /// mayNeedRelaxation - Check whether the given instruction may need
+  /// relaxation.
+  ///
+  /// \param Inst - The instruction to test.
+  virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0;
+
+  /// fixupNeedsRelaxation - Target specific predicate for whether a given
+  /// fixup requires the associated instruction to be relaxed.
+  virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+                                    const MCRelaxableFragment *DF,
+                                    const MCAsmLayout &Layout) const = 0;
+
+  /// RelaxInstruction - Relax the instruction in the given fragment to the next
+  /// wider instruction.
+  ///
+  /// \param Inst The instruction to relax, which may be the same as the
+  /// output.
+  /// \param [out] Res On return, the relaxed instruction.
+  virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
+
+  /// @}
+
+  /// getMinimumNopSize - Returns the minimum size of a nop in bytes on this
+  /// target. The assembler will use this to emit excess padding in situations
+  /// where the padding required for simple alignment would be less than the
+  /// minimum nop size.
+  ///
+  virtual unsigned getMinimumNopSize() const { return 1; }
+
+  /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given
+  /// output. If the target cannot generate such a sequence, it should return an
+  /// error.
+  ///
+  /// \return - True on success.
+  virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+
+  /// handleAssemblerFlag - Handle any target-specific assembler flags.
+  /// By default, do nothing.
+  virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
+
+  /// \brief Generate the compact unwind encoding for the CFI instructions.
+  virtual uint32_t
+  generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction>) const {
+    return 0;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
new file mode 100644
index 0000000..06e473d
--- /dev/null
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -0,0 +1,518 @@
+//===-- llvm/MC/MCAsmInfo.h - Asm 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 contains a class to be used as the basis for target specific
+// asm writers.  This class primarily takes care of global printing constants,
+// which are used in very similar ways across all targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MachineLocation.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+class MCExpr;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCContext;
+
+namespace WinEH {
+enum class EncodingType {
+  ET_Invalid, /// Invalid
+  ET_Alpha,   /// Windows Alpha
+  ET_Alpha64, /// Windows AXP64
+  ET_ARM,     /// Windows NT (Windows on ARM)
+  ET_CE,      /// Windows CE ARM, PowerPC, SH3, SH4
+  ET_Itanium, /// Windows x64, Windows Itanium (IA-64)
+  ET_MIPS = ET_Alpha,
+};
+}
+
+enum class ExceptionHandling {
+  None,     /// No exception support
+  DwarfCFI, /// DWARF-like instruction based exceptions
+  SjLj,     /// setjmp/longjmp based exceptions
+  ARM,      /// ARM EHABI
+  WinEH,    /// Windows Exception Handling
+};
+
+namespace LCOMM {
+enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+}
+
+/// This class is intended to be used as a base class for asm
+/// properties and features specific to the target.
+class MCAsmInfo {
+protected:
+  //===------------------------------------------------------------------===//
+  // Properties to be set by the target writer, used to configure asm printer.
+  //
+
+  /// Pointer size in bytes.  Default is 4.
+  unsigned PointerSize;
+
+  /// Size of the stack slot reserved for callee-saved registers, in bytes.
+  /// Default is same as pointer size.
+  unsigned CalleeSaveStackSlotSize;
+
+  /// True if target is little endian.  Default is true.
+  bool IsLittleEndian;
+
+  /// True if target stack grow up.  Default is false.
+  bool StackGrowsUp;
+
+  /// True if this target has the MachO .subsections_via_symbols directive.
+  /// Default is false.
+  bool HasSubsectionsViaSymbols;
+
+  /// True if this is a MachO target that supports the macho-specific .zerofill
+  /// directive for emitting BSS Symbols.  Default is false.
+  bool HasMachoZeroFillDirective;
+
+  /// True if this is a MachO target that supports the macho-specific .tbss
+  /// directive for emitting thread local BSS Symbols.  Default is false.
+  bool HasMachoTBSSDirective;
+
+  /// True if the compiler should emit a ".reference .constructors_used" or
+  /// ".reference .destructors_used" directive after the a static ctor/dtor
+  /// list.  This directive is only emitted in Static relocation model.  Default
+  /// is false.
+  bool HasStaticCtorDtorReferenceInStaticMode;
+
+  /// True if the linker has a bug and requires that the debug_line section be
+  /// of a minimum size. In practice such a linker requires a non-empty line
+  /// sequence if a file is present.  Default to false.
+  bool LinkerRequiresNonEmptyDwarfLines;
+
+  /// This is the maximum possible length of an instruction, which is needed to
+  /// compute the size of an inline asm.  Defaults to 4.
+  unsigned MaxInstLength;
+
+  /// Every possible instruction length is a multiple of this value.  Factored
+  /// out in .debug_frame and .debug_line.  Defaults to 1.
+  unsigned MinInstAlignment;
+
+  /// The '$' token, when not referencing an identifier or constant, refers to
+  /// the current PC.  Defaults to false.
+  bool DollarIsPC;
+
+  /// This string, if specified, is used to separate instructions from each
+  /// other when on the same line.  Defaults to ';'
+  const char *SeparatorString;
+
+  /// This indicates the comment character used by the assembler.  Defaults to
+  /// "#"
+  const char *CommentString;
+
+  /// This is appended to emitted labels.  Defaults to ":"
+  const char *LabelSuffix;
+
+  // Print the EH begin symbol with an assignment. Defaults to false.
+  bool UseAssignmentForEHBegin;
+
+  /// This prefix is used for globals like constant pool entries that are
+  /// completely private to the .s file and should not have names in the .o
+  /// file.  Defaults to "L"
+  const char *PrivateGlobalPrefix;
+
+  /// This prefix is used for symbols that should be passed through the
+  /// assembler but be removed by the linker.  This is 'l' on Darwin, currently
+  /// used for some ObjC metadata.  The default of "" meast that for this system
+  /// a plain private symbol should be used.  Defaults to "".
+  const char *LinkerPrivateGlobalPrefix;
+
+  /// If these are nonempty, they contain a directive to emit before and after
+  /// an inline assembly statement.  Defaults to "#APP\n", "#NO_APP\n"
+  const char *InlineAsmStart;
+  const char *InlineAsmEnd;
+
+  /// These are assembly directives that tells the assembler to interpret the
+  /// following instructions differently.  Defaults to ".code16", ".code32",
+  /// ".code64".
+  const char *Code16Directive;
+  const char *Code32Directive;
+  const char *Code64Directive;
+
+  /// Which dialect of an assembler variant to use.  Defaults to 0
+  unsigned AssemblerDialect;
+
+  /// This is true if the assembler allows @ characters in symbol names.
+  /// Defaults to false.
+  bool AllowAtInName;
+
+  /// This is true if data region markers should be printed as
+  /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
+  /// instead.
+  bool UseDataRegionDirectives;
+
+  //===--- Data Emission Directives -------------------------------------===//
+
+  /// This should be set to the directive used to get some number of zero bytes
+  /// emitted to the current section.  Common cases are "\t.zero\t" and
+  /// "\t.space\t".  If this is set to null, the Data*bitsDirective's will be
+  /// used to emit zero bytes.  Defaults to "\t.zero\t"
+  const char *ZeroDirective;
+
+  /// This directive allows emission of an ascii string with the standard C
+  /// escape characters embedded into it.  Defaults to "\t.ascii\t"
+  const char *AsciiDirective;
+
+  /// If not null, this allows for special handling of zero terminated strings
+  /// on this target.  This is commonly supported as ".asciz".  If a target
+  /// doesn't support this, it can be set to null.  Defaults to "\t.asciz\t"
+  const char *AscizDirective;
+
+  /// These directives are used to output some unit of integer data to the
+  /// current section.  If a data directive is set to null, smaller data
+  /// directives will be used to emit the large sizes.  Defaults to "\t.byte\t",
+  /// "\t.short\t", "\t.long\t", "\t.quad\t"
+  const char *Data8bitsDirective;
+  const char *Data16bitsDirective;
+  const char *Data32bitsDirective;
+  const char *Data64bitsDirective;
+
+  /// If non-null, a directive that is used to emit a word which should be
+  /// relocated as a 64-bit GP-relative offset, e.g. .gpdword on Mips.  Defaults
+  /// to NULL.
+  const char *GPRel64Directive;
+
+  /// If non-null, a directive that is used to emit a word which should be
+  /// relocated as a 32-bit GP-relative offset, e.g. .gpword on Mips or .gprel32
+  /// on Alpha.  Defaults to NULL.
+  const char *GPRel32Directive;
+
+  /// This is true if this target uses "Sun Style" syntax for section switching
+  /// ("#alloc,#write" etc) instead of the normal ELF syntax (,"a,w") in
+  /// .section directives.  Defaults to false.
+  bool SunStyleELFSectionSwitchSyntax;
+
+  /// This is true if this target uses ELF '.section' directive before the
+  /// '.bss' one. It's used for PPC/Linux which doesn't support the '.bss'
+  /// directive only.  Defaults to false.
+  bool UsesELFSectionDirectiveForBSS;
+
+  bool NeedsDwarfSectionOffsetDirective;
+
+  //===--- Alignment Information ----------------------------------------===//
+
+  /// If this is true (the default) then the asmprinter emits ".align N"
+  /// directives, where N is the number of bytes to align to.  Otherwise, it
+  /// emits ".align log2(N)", e.g. 3 to align to an 8 byte boundary.  Defaults
+  /// to true.
+  bool AlignmentIsInBytes;
+
+  /// If non-zero, this is used to fill the executable space created as the
+  /// result of a alignment directive.  Defaults to 0
+  unsigned TextAlignFillValue;
+
+  //===--- Global Variable Emission Directives --------------------------===//
+
+  /// This is the directive used to declare a global entity.  Defaults to NULL.
+  const char *GlobalDirective;
+
+  /// True if the assembler supports the .set directive.  Defaults to true.
+  bool HasSetDirective;
+
+  /// False if the assembler requires that we use
+  /// \code
+  ///   Lc = a - b
+  ///   .long Lc
+  /// \endcode
+  //
+  /// instead of
+  //
+  /// \code
+  ///   .long a - b
+  /// \endcode
+  ///
+  ///  Defaults to true.
+  bool HasAggressiveSymbolFolding;
+
+  /// True is .comm's and .lcomms optional alignment is to be specified in bytes
+  /// instead of log2(n).  Defaults to true.
+  bool COMMDirectiveAlignmentIsInBytes;
+
+  /// Describes if the .lcomm directive for the target supports an alignment
+  /// argument and how it is interpreted.  Defaults to NoAlignment.
+  LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+
+  /// True if the target has .type and .size directives, this is true for most
+  /// ELF targets.  Defaults to true.
+  bool HasDotTypeDotSizeDirective;
+
+  /// True if the target has a single parameter .file directive, this is true
+  /// for ELF targets.  Defaults to true.
+  bool HasSingleParameterDotFile;
+
+  /// True if the target has a .ident directive, this is true for ELF targets.
+  /// Defaults to false.
+  bool HasIdentDirective;
+
+  /// True if this target supports the MachO .no_dead_strip directive.  Defaults
+  /// to false.
+  bool HasNoDeadStrip;
+
+  /// This directive, if non-null, is used to declare a global as being a weak
+  /// undefined symbol.  Defaults to NULL.
+  const char *WeakRefDirective;
+
+  /// True if we have a directive to declare a global as being a weak defined
+  /// symbol.  Defaults to false.
+  bool HasWeakDefDirective;
+
+  /// True if we have a directive to declare a global as being a weak defined
+  /// symbol that can be hidden (unexported).  Defaults to false.
+  bool HasWeakDefCanBeHiddenDirective;
+
+  /// True if we have a .linkonce directive.  This is used on cygwin/mingw.
+  /// Defaults to false.
+  bool HasLinkOnceDirective;
+
+  /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+  /// hidden visibility.  Defaults to MCSA_Hidden.
+  MCSymbolAttr HiddenVisibilityAttr;
+
+  /// This attribute, if not MCSA_Invalid, is used to declare an undefined
+  /// symbol as having hidden visibility. Defaults to MCSA_Hidden.
+  MCSymbolAttr HiddenDeclarationVisibilityAttr;
+
+  /// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
+  /// protected visibility.  Defaults to MCSA_Protected
+  MCSymbolAttr ProtectedVisibilityAttr;
+
+  //===--- Dwarf Emission Directives -----------------------------------===//
+
+  /// True if target asm supports leb128 directives.  Defaults to false.
+  bool HasLEB128;
+
+  /// True if target supports emission of debugging information.  Defaults to
+  /// false.
+  bool SupportsDebugInformation;
+
+  /// Exception handling format for the target.  Defaults to None.
+  ExceptionHandling ExceptionsType;
+
+  /// Windows exception handling data (.pdata) encoding.  Defaults to Invalid.
+  WinEH::EncodingType WinEHEncodingType;
+
+  /// True if Dwarf2 output generally uses relocations for references to other
+  /// .debug_* sections.
+  bool DwarfUsesRelocationsAcrossSections;
+
+  /// True if DWARF FDE symbol reference relocations should be replaced by an
+  /// absolute difference.
+  bool DwarfFDESymbolsUseAbsDiff;
+
+  /// True if dwarf register numbers are printed instead of symbolic register
+  /// names in .cfi_* directives.  Defaults to false.
+  bool DwarfRegNumForCFI;
+
+  /// True if target uses parens to indicate the symbol variant instead of @.
+  /// For example, foo(plt) instead of foo@plt.  Defaults to false.
+  bool UseParensForSymbolVariant;
+
+  //===--- Prologue State ----------------------------------------------===//
+
+  std::vector<MCCFIInstruction> InitialFrameState;
+
+  //===--- Integrated Assembler State ----------------------------------===//
+
+  /// Should we use the integrated assembler?
+  /// The integrated assembler should be enabled by default (by the
+  /// constructors) when failing to parse a valid piece of assembly (inline
+  /// or otherwise) is considered a bug. It may then be overridden after
+  /// construction (see LLVMTargetMachine::initAsmInfo()).
+  bool UseIntegratedAssembler;
+
+  /// Compress DWARF debug sections. Defaults to false.
+  bool CompressDebugSections;
+
+public:
+  explicit MCAsmInfo();
+  virtual ~MCAsmInfo();
+
+  /// Get the pointer size in bytes.
+  unsigned getPointerSize() const { return PointerSize; }
+
+  /// Get the callee-saved register stack slot
+  /// size in bytes.
+  unsigned getCalleeSaveStackSlotSize() const {
+    return CalleeSaveStackSlotSize;
+  }
+
+  /// True if the target is little endian.
+  bool isLittleEndian() const { return IsLittleEndian; }
+
+  /// True if target stack grow up.
+  bool isStackGrowthDirectionUp() const { return StackGrowsUp; }
+
+  bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
+  // Data directive accessors.
+
+  const char *getData8bitsDirective() const { return Data8bitsDirective; }
+  const char *getData16bitsDirective() const { return Data16bitsDirective; }
+  const char *getData32bitsDirective() const { return Data32bitsDirective; }
+  const char *getData64bitsDirective() const { return Data64bitsDirective; }
+  const char *getGPRel64Directive() const { return GPRel64Directive; }
+  const char *getGPRel32Directive() const { return GPRel32Directive; }
+
+  /// Targets can implement this method to specify a section to switch to if the
+  /// translation unit doesn't have any trampolines that require an executable
+  /// stack.
+  virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
+    return nullptr;
+  }
+
+  virtual const MCExpr *getExprForPersonalitySymbol(const MCSymbol *Sym,
+                                                    unsigned Encoding,
+                                                    MCStreamer &Streamer) const;
+
+  virtual const MCExpr *getExprForFDESymbol(const MCSymbol *Sym,
+                                            unsigned Encoding,
+                                            MCStreamer &Streamer) const;
+
+  bool usesSunStyleELFSectionSwitchSyntax() const {
+    return SunStyleELFSectionSwitchSyntax;
+  }
+
+  bool usesELFSectionDirectiveForBSS() const {
+    return UsesELFSectionDirectiveForBSS;
+  }
+
+  bool needsDwarfSectionOffsetDirective() const {
+    return NeedsDwarfSectionOffsetDirective;
+  }
+
+  // Accessors.
+
+  bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+  bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
+  bool hasStaticCtorDtorReferenceInStaticMode() const {
+    return HasStaticCtorDtorReferenceInStaticMode;
+  }
+  bool getLinkerRequiresNonEmptyDwarfLines() const {
+    return LinkerRequiresNonEmptyDwarfLines;
+  }
+  unsigned getMaxInstLength() const { return MaxInstLength; }
+  unsigned getMinInstAlignment() const { return MinInstAlignment; }
+  bool getDollarIsPC() const { return DollarIsPC; }
+  const char *getSeparatorString() const { return SeparatorString; }
+
+  /// This indicates the column (zero-based) at which asm comments should be
+  /// printed.
+  unsigned getCommentColumn() const { return 40; }
+
+  const char *getCommentString() const { return CommentString; }
+  const char *getLabelSuffix() const { return LabelSuffix; }
+
+  bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+  const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
+  bool hasLinkerPrivateGlobalPrefix() const {
+    return LinkerPrivateGlobalPrefix[0] != '\0';
+  }
+  const char *getLinkerPrivateGlobalPrefix() const {
+    if (hasLinkerPrivateGlobalPrefix())
+      return LinkerPrivateGlobalPrefix;
+    return getPrivateGlobalPrefix();
+  }
+  const char *getInlineAsmStart() const { return InlineAsmStart; }
+  const char *getInlineAsmEnd() const { return InlineAsmEnd; }
+  const char *getCode16Directive() const { return Code16Directive; }
+  const char *getCode32Directive() const { return Code32Directive; }
+  const char *getCode64Directive() const { return Code64Directive; }
+  unsigned getAssemblerDialect() const { return AssemblerDialect; }
+  bool doesAllowAtInName() const { return AllowAtInName; }
+  bool doesSupportDataRegionDirectives() const {
+    return UseDataRegionDirectives;
+  }
+  const char *getZeroDirective() const { return ZeroDirective; }
+  const char *getAsciiDirective() const { return AsciiDirective; }
+  const char *getAscizDirective() const { return AscizDirective; }
+  bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
+  unsigned getTextAlignFillValue() const { return TextAlignFillValue; }
+  const char *getGlobalDirective() const { return GlobalDirective; }
+  bool hasSetDirective() const { return HasSetDirective; }
+  bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; }
+  bool getCOMMDirectiveAlignmentIsInBytes() const {
+    return COMMDirectiveAlignmentIsInBytes;
+  }
+  LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
+    return LCOMMDirectiveAlignmentType;
+  }
+  bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
+  bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
+  bool hasIdentDirective() const { return HasIdentDirective; }
+  bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+  const char *getWeakRefDirective() const { return WeakRefDirective; }
+  bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+  bool hasWeakDefCanBeHiddenDirective() const {
+    return HasWeakDefCanBeHiddenDirective;
+  }
+  bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
+
+  MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
+  MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+    return HiddenDeclarationVisibilityAttr;
+  }
+  MCSymbolAttr getProtectedVisibilityAttr() const {
+    return ProtectedVisibilityAttr;
+  }
+  bool hasLEB128() const { return HasLEB128; }
+  bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
+  bool doesSupportExceptionHandling() const {
+    return ExceptionsType != ExceptionHandling::None;
+  }
+  ExceptionHandling getExceptionHandlingType() const { return ExceptionsType; }
+  WinEH::EncodingType getWinEHEncodingType() const { return WinEHEncodingType; }
+  bool isExceptionHandlingDwarf() const {
+    return (ExceptionsType == ExceptionHandling::DwarfCFI ||
+            ExceptionsType == ExceptionHandling::ARM ||
+            // Windows handler data still uses DWARF LSDA encoding.
+            ExceptionsType == ExceptionHandling::WinEH);
+  }
+  bool doesDwarfUseRelocationsAcrossSections() const {
+    return DwarfUsesRelocationsAcrossSections;
+  }
+  bool doDwarfFDESymbolsUseAbsDiff() const { return DwarfFDESymbolsUseAbsDiff; }
+  bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; }
+  bool useParensForSymbolVariant() const { return UseParensForSymbolVariant; }
+
+  void addInitialFrameState(const MCCFIInstruction &Inst) {
+    InitialFrameState.push_back(Inst);
+  }
+
+  const std::vector<MCCFIInstruction> &getInitialFrameState() const {
+    return InitialFrameState;
+  }
+
+  /// Return true if assembly (inline or otherwise) should be parsed.
+  bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
+
+  /// Set whether assembly (inline or otherwise) should be parsed.
+  virtual void setUseIntegratedAssembler(bool Value) {
+    UseIntegratedAssembler = Value;
+  }
+
+  bool compressDebugSections() const { return CompressDebugSections; }
+
+  void setCompressDebugSections(bool CompressDebugSections) {
+    this->CompressDebugSections = CompressDebugSections;
+  }
+};
+}
+
+#endif
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
new file mode 100644
index 0000000..56444f3
--- /dev/null
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -0,0 +1,36 @@
+//===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOCOFF_H
+#define LLVM_MC_MCASMINFOCOFF_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+  class MCAsmInfoCOFF : public MCAsmInfo {
+    virtual void anchor();
+  protected:
+    explicit MCAsmInfoCOFF();
+  };
+
+  class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
+    void anchor() override;
+  protected:
+    explicit MCAsmInfoMicrosoft();
+  };
+
+  class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
+    void anchor() override;
+  protected:
+    explicit MCAsmInfoGNUCOFF();
+  };
+}
+
+
+#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h
new file mode 100644
index 0000000..3d249f9
--- /dev/null
+++ b/include/llvm/MC/MCAsmInfoDarwin.h
@@ -0,0 +1,29 @@
+//===---- MCAsmInfoDarwin.h - Darwin asm properties -------------*- 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 target asm properties related what form asm statements
+// should take in general on Darwin-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFODARWIN_H
+#define LLVM_MC_MCASMINFODARWIN_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+  class MCAsmInfoDarwin : public MCAsmInfo {
+    virtual void anchor();
+  public:
+    explicit MCAsmInfoDarwin();
+  };
+}
+
+
+#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/include/llvm/MC/MCAsmInfoELF.h b/include/llvm/MC/MCAsmInfoELF.h
new file mode 100644
index 0000000..27fea84
--- /dev/null
+++ b/include/llvm/MC/MCAsmInfoELF.h
@@ -0,0 +1,23 @@
+//===-- llvm/MC/MCAsmInfoELF.h - ELF Asm info -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMINFOELF_H
+#define LLVM_MC_MCASMINFOELF_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+class MCAsmInfoELF : public MCAsmInfo {
+  virtual void anchor();
+protected:
+  MCAsmInfoELF();
+};
+}
+
+#endif
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
new file mode 100644
index 0000000..f048e34
--- /dev/null
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -0,0 +1,120 @@
+//===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMLAYOUT_H
+#define LLVM_MC_MCASMLAYOUT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+class MCAssembler;
+class MCFragment;
+class MCSectionData;
+class MCSymbol;
+class MCSymbolData;
+
+/// Encapsulates the layout of an assembly file at a particular point in time.
+///
+/// Assembly may require computing multiple layouts for a particular assembly
+/// file as part of the relaxation process. This class encapsulates the layout
+/// at a single point in time in such a way that it is always possible to
+/// efficiently compute the exact address of any symbol in the assembly file,
+/// even during the relaxation process.
+class MCAsmLayout {
+public:
+  typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
+  typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
+
+private:
+  MCAssembler &Assembler;
+
+  /// List of sections in layout order.
+  llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+
+  /// The last fragment which was laid out, or 0 if nothing has been laid
+  /// out. Fragments are always laid out in order, so all fragments with a
+  /// lower ordinal will be valid.
+  mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment;
+
+  /// \brief Make sure that the layout for the given fragment is valid, lazily
+  /// computing it if necessary.
+  void ensureValid(const MCFragment *F) const;
+
+  /// \brief Is the layout for this fragment valid?
+  bool isFragmentValid(const MCFragment *F) const;
+
+  /// \brief Compute the amount of padding required before this fragment to
+  /// obey bundling restrictions.
+  uint64_t computeBundlePadding(const MCFragment *F,
+                                uint64_t FOffset, uint64_t FSize);
+
+public:
+  MCAsmLayout(MCAssembler &_Assembler);
+
+  /// Get the assembler object this is a layout for.
+  MCAssembler &getAssembler() const { return Assembler; }
+
+  /// \brief Invalidate the fragments starting with F because it has been
+  /// resized. The fragment's size should have already been updated, but
+  /// its bundle padding will be recomputed.
+  void invalidateFragmentsFrom(MCFragment *F);
+
+  /// \brief Perform layout for a single fragment, assuming that the previous
+  /// fragment has already been laid out correctly, and the parent section has
+  /// been initialized.
+  void layoutFragment(MCFragment *Fragment);
+
+  /// @name Section Access (in layout order)
+  /// @{
+
+  llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() {
+    return SectionOrder;
+  }
+  const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const {
+    return SectionOrder;
+  }
+
+  /// @}
+  /// @name Fragment Layout Data
+  /// @{
+
+  /// \brief Get the offset of the given fragment inside its containing section.
+  uint64_t getFragmentOffset(const MCFragment *F) const;
+
+  /// @}
+  /// @name Utility Functions
+  /// @{
+
+  /// \brief Get the address space size of the given section, as it effects
+  /// layout. This may differ from the size reported by \see getSectionSize() by
+  /// not including section tail padding.
+  uint64_t getSectionAddressSize(const MCSectionData *SD) const;
+
+  /// \brief Get the data size of the given section, as emitted to the object
+  /// file. This may include additional padding, or be 0 for virtual sections.
+  uint64_t getSectionFileSize(const MCSectionData *SD) const;
+
+  /// \brief Get the offset of the given symbol, as computed in the current
+  /// layout.
+  /// \result True on success.
+  bool getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const;
+
+  /// \brief Variant that reports a fatal error if the offset is not computable.
+  uint64_t getSymbolOffset(const MCSymbolData *SD) const;
+
+  /// \brief If this symbol is equivalent to A + Constant, return A.
+  const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;
+
+  /// @}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
new file mode 100644
index 0000000..1cb34c2
--- /dev/null
+++ b/include/llvm/MC/MCAssembler.h
@@ -0,0 +1,1251 @@
+//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASSEMBLER_H
+#define LLVM_MC_MCASSEMBLER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include <algorithm>
+#include <vector> // FIXME: Shouldn't be needed.
+
+namespace llvm {
+class raw_ostream;
+class MCAsmLayout;
+class MCAssembler;
+class MCContext;
+class MCCodeEmitter;
+class MCExpr;
+class MCFragment;
+class MCObjectWriter;
+class MCSection;
+class MCSectionData;
+class MCSubtargetInfo;
+class MCSymbol;
+class MCSymbolData;
+class MCValue;
+class MCAsmBackend;
+
+class MCFragment : public ilist_node<MCFragment> {
+  friend class MCAsmLayout;
+
+  MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
+  void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
+
+public:
+  enum FragmentType {
+    FT_Align,
+    FT_Data,
+    FT_CompactEncodedInst,
+    FT_Fill,
+    FT_Relaxable,
+    FT_Org,
+    FT_Dwarf,
+    FT_DwarfFrame,
+    FT_LEB
+  };
+
+private:
+  FragmentType Kind;
+
+  /// Parent - The data for the section this fragment is in.
+  MCSectionData *Parent;
+
+  /// Atom - The atom this fragment is in, as represented by it's defining
+  /// symbol.
+  MCSymbolData *Atom;
+
+  /// @name Assembler Backend Data
+  /// @{
+  //
+  // FIXME: This could all be kept private to the assembler implementation.
+
+  /// Offset - The offset of this fragment in its section. This is ~0 until
+  /// initialized.
+  uint64_t Offset;
+
+  /// LayoutOrder - The layout order of this fragment.
+  unsigned LayoutOrder;
+
+  /// @}
+
+protected:
+  MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
+
+public:
+  // Only for sentinel.
+  MCFragment();
+  virtual ~MCFragment();
+
+  FragmentType getKind() const { return Kind; }
+
+  MCSectionData *getParent() const { return Parent; }
+  void setParent(MCSectionData *Value) { Parent = Value; }
+
+  MCSymbolData *getAtom() const { return Atom; }
+  void setAtom(MCSymbolData *Value) { Atom = Value; }
+
+  unsigned getLayoutOrder() const { return LayoutOrder; }
+  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+  /// \brief Does this fragment have instructions emitted into it? By default
+  /// this is false, but specific fragment types may set it to true.
+  virtual bool hasInstructions() const { return false; }
+
+  /// \brief Should this fragment be placed at the end of an aligned bundle?
+  virtual bool alignToBundleEnd() const { return false; }
+  virtual void setAlignToBundleEnd(bool V) { }
+
+  /// \brief Get the padding size that must be inserted before this fragment.
+  /// Used for bundling. By default, no padding is inserted.
+  /// Note that padding size is restricted to 8 bits. This is an optimization
+  /// to reduce the amount of space used for each fragment. In practice, larger
+  /// padding should never be required.
+  virtual uint8_t getBundlePadding() const {
+    return 0;
+  }
+
+  /// \brief Set the padding size for this fragment. By default it's a no-op,
+  /// and only some fragments have a meaningful implementation.
+  virtual void setBundlePadding(uint8_t N) {
+  }
+
+  void dump();
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+///
+class MCEncodedFragment : public MCFragment {
+  virtual void anchor();
+
+  uint8_t BundlePadding;
+public:
+  MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr)
+    : MCFragment(FType, SD), BundlePadding(0)
+  {
+  }
+  virtual ~MCEncodedFragment();
+
+  virtual SmallVectorImpl<char> &getContents() = 0;
+  virtual const SmallVectorImpl<char> &getContents() const = 0;
+
+  uint8_t getBundlePadding() const override {
+    return BundlePadding;
+  }
+
+  void setBundlePadding(uint8_t N) override {
+    BundlePadding = N;
+  }
+
+  static bool classof(const MCFragment *F) {
+    MCFragment::FragmentType Kind = F->getKind();
+    switch (Kind) {
+      default:
+        return false;
+      case MCFragment::FT_Relaxable:
+      case MCFragment::FT_CompactEncodedInst:
+      case MCFragment::FT_Data:
+        return true;
+    }
+  }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+class MCEncodedFragmentWithFixups : public MCEncodedFragment {
+  void anchor() override;
+
+public:
+  MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+                              MCSectionData *SD = nullptr)
+    : MCEncodedFragment(FType, SD)
+  {
+  }
+
+  virtual ~MCEncodedFragmentWithFixups();
+
+  typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+  typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
+
+  virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+  virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
+
+  virtual fixup_iterator fixup_begin() = 0;
+  virtual const_fixup_iterator fixup_begin() const  = 0;
+  virtual fixup_iterator fixup_end() = 0;
+  virtual const_fixup_iterator fixup_end() const = 0;
+
+  static bool classof(const MCFragment *F) {
+    MCFragment::FragmentType Kind = F->getKind();
+    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
+  }
+};
+
+/// Fragment for data and encoded instructions.
+///
+class MCDataFragment : public MCEncodedFragmentWithFixups {
+  void anchor() override;
+
+  /// \brief Does this fragment contain encoded instructions anywhere in it?
+  bool HasInstructions;
+
+  /// \brief Should this fragment be aligned to the end of a bundle?
+  bool AlignToBundleEnd;
+
+  SmallVector<char, 32> Contents;
+
+  /// Fixups - The list of fixups in this fragment.
+  SmallVector<MCFixup, 4> Fixups;
+public:
+  MCDataFragment(MCSectionData *SD = nullptr)
+    : MCEncodedFragmentWithFixups(FT_Data, SD),
+      HasInstructions(false), AlignToBundleEnd(false)
+  {
+  }
+
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override {
+    return Contents;
+  }
+
+  SmallVectorImpl<MCFixup> &getFixups() override {
+    return Fixups;
+  }
+
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
+    return Fixups;
+  }
+
+  bool hasInstructions() const override { return HasInstructions; }
+  virtual void setHasInstructions(bool V) { HasInstructions = V; }
+
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
+
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
+
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Data;
+  }
+};
+
+/// This is a compact (memory-size-wise) fragment for holding an encoded
+/// instruction (non-relaxable) that has no fixups registered. When applicable,
+/// it can be used instead of MCDataFragment and lead to lower memory
+/// consumption.
+///
+class MCCompactEncodedInstFragment : public MCEncodedFragment {
+  void anchor() override;
+
+  /// \brief Should this fragment be aligned to the end of a bundle?
+  bool AlignToBundleEnd;
+
+  SmallVector<char, 4> Contents;
+public:
+  MCCompactEncodedInstFragment(MCSectionData *SD = nullptr)
+    : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
+  {
+  }
+
+  bool hasInstructions() const override {
+    return true;
+  }
+
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
+
+  bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+  void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_CompactEncodedInst;
+  }
+};
+
+/// A relaxable fragment holds on to its MCInst, since it may need to be
+/// relaxed during the assembler layout and relaxation stage.
+///
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
+  void anchor() override;
+
+  /// Inst - The instruction this is a fragment for.
+  MCInst Inst;
+
+  /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+  /// Keep a copy instead of a reference to make sure that updates to STI
+  /// in the assembler are not seen here.
+  const MCSubtargetInfo STI;
+
+  /// Contents - Binary data for the currently encoded instruction.
+  SmallVector<char, 8> Contents;
+
+  /// Fixups - The list of fixups in this fragment.
+  SmallVector<MCFixup, 1> Fixups;
+
+public:
+  MCRelaxableFragment(const MCInst &_Inst,
+                      const MCSubtargetInfo &_STI,
+                      MCSectionData *SD = nullptr)
+    : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
+  }
+
+  SmallVectorImpl<char> &getContents() override { return Contents; }
+  const SmallVectorImpl<char> &getContents() const override { return Contents; }
+
+  const MCInst &getInst() const { return Inst; }
+  void setInst(const MCInst& Value) { Inst = Value; }
+
+  const MCSubtargetInfo &getSubtargetInfo() { return STI; }
+
+  SmallVectorImpl<MCFixup> &getFixups() override {
+    return Fixups;
+  }
+
+  const SmallVectorImpl<MCFixup> &getFixups() const override {
+    return Fixups;
+  }
+
+  bool hasInstructions() const override { return true; }
+
+  fixup_iterator fixup_begin() override { return Fixups.begin(); }
+  const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
+
+  fixup_iterator fixup_end() override {return Fixups.end();}
+  const_fixup_iterator fixup_end() const override {return Fixups.end();}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Relaxable;
+  }
+};
+
+class MCAlignFragment : public MCFragment {
+  virtual void anchor();
+
+  /// Alignment - The alignment to ensure, in bytes.
+  unsigned Alignment;
+
+  /// Value - Value to use for filling padding bytes.
+  int64_t Value;
+
+  /// ValueSize - The size of the integer (in bytes) of \p Value.
+  unsigned ValueSize;
+
+  /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
+  /// cannot be satisfied in this width then this fragment is ignored.
+  unsigned MaxBytesToEmit;
+
+  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+  /// of using the provided value. The exact interpretation of this flag is
+  /// target dependent.
+  bool EmitNops : 1;
+
+public:
+  MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
+                  unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
+    : MCFragment(FT_Align, SD), Alignment(_Alignment),
+      Value(_Value),ValueSize(_ValueSize),
+      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
+
+  /// @name Accessors
+  /// @{
+
+  unsigned getAlignment() const { return Alignment; }
+
+  int64_t getValue() const { return Value; }
+
+  unsigned getValueSize() const { return ValueSize; }
+
+  unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
+
+  bool hasEmitNops() const { return EmitNops; }
+  void setEmitNops(bool Value) { EmitNops = Value; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Align;
+  }
+};
+
+class MCFillFragment : public MCFragment {
+  virtual void anchor();
+
+  /// Value - Value to use for filling bytes.
+  int64_t Value;
+
+  /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
+  /// this is a virtual fill fragment.
+  unsigned ValueSize;
+
+  /// Size - The number of bytes to insert.
+  uint64_t Size;
+
+public:
+  MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
+                 MCSectionData *SD = nullptr)
+    : MCFragment(FT_Fill, SD),
+      Value(_Value), ValueSize(_ValueSize), Size(_Size) {
+    assert((!ValueSize || (Size % ValueSize) == 0) &&
+           "Fill size must be a multiple of the value size!");
+  }
+
+  /// @name Accessors
+  /// @{
+
+  int64_t getValue() const { return Value; }
+
+  unsigned getValueSize() const { return ValueSize; }
+
+  uint64_t getSize() const { return Size; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Fill;
+  }
+};
+
+class MCOrgFragment : public MCFragment {
+  virtual void anchor();
+
+  /// Offset - The offset this fragment should start at.
+  const MCExpr *Offset;
+
+  /// Value - Value to use for filling bytes.
+  int8_t Value;
+
+public:
+  MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
+                MCSectionData *SD = nullptr)
+    : MCFragment(FT_Org, SD),
+      Offset(&_Offset), Value(_Value) {}
+
+  /// @name Accessors
+  /// @{
+
+  const MCExpr &getOffset() const { return *Offset; }
+
+  uint8_t getValue() const { return Value; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Org;
+  }
+};
+
+class MCLEBFragment : public MCFragment {
+  virtual void anchor();
+
+  /// Value - The value this fragment should contain.
+  const MCExpr *Value;
+
+  /// IsSigned - True if this is a sleb128, false if uleb128.
+  bool IsSigned;
+
+  SmallString<8> Contents;
+public:
+  MCLEBFragment(const MCExpr &Value_, bool IsSigned_,
+                MCSectionData *SD = nullptr)
+    : MCFragment(FT_LEB, SD),
+      Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
+
+  /// @name Accessors
+  /// @{
+
+  const MCExpr &getValue() const { return *Value; }
+
+  bool isSigned() const { return IsSigned; }
+
+  SmallString<8> &getContents() { return Contents; }
+  const SmallString<8> &getContents() const { return Contents; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_LEB;
+  }
+};
+
+class MCDwarfLineAddrFragment : public MCFragment {
+  virtual void anchor();
+
+  /// LineDelta - the value of the difference between the two line numbers
+  /// between two .loc dwarf directives.
+  int64_t LineDelta;
+
+  /// AddrDelta - The expression for the difference of the two symbols that
+  /// make up the address delta between two .loc dwarf directives.
+  const MCExpr *AddrDelta;
+
+  SmallString<8> Contents;
+
+public:
+  MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
+                      MCSectionData *SD = nullptr)
+    : MCFragment(FT_Dwarf, SD),
+      LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+  /// @name Accessors
+  /// @{
+
+  int64_t getLineDelta() const { return LineDelta; }
+
+  const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+  SmallString<8> &getContents() { return Contents; }
+  const SmallString<8> &getContents() const { return Contents; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Dwarf;
+  }
+};
+
+class MCDwarfCallFrameFragment : public MCFragment {
+  virtual void anchor();
+
+  /// AddrDelta - The expression for the difference of the two symbols that
+  /// make up the address delta between two .cfi_* dwarf directives.
+  const MCExpr *AddrDelta;
+
+  SmallString<8> Contents;
+
+public:
+  MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
+                           MCSectionData *SD = nullptr)
+    : MCFragment(FT_DwarfFrame, SD),
+      AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+  /// @name Accessors
+  /// @{
+
+  const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+  SmallString<8> &getContents() { return Contents; }
+  const SmallString<8> &getContents() const { return Contents; }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_DwarfFrame;
+  }
+};
+
+// FIXME: Should this be a separate class, or just merged into MCSection? Since
+// we anticipate the fast path being through an MCAssembler, the only reason to
+// keep it out is for API abstraction.
+class MCSectionData : public ilist_node<MCSectionData> {
+  friend class MCAsmLayout;
+
+  MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
+  void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
+
+public:
+  typedef iplist<MCFragment> FragmentListType;
+
+  typedef FragmentListType::const_iterator const_iterator;
+  typedef FragmentListType::iterator iterator;
+
+  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+  typedef FragmentListType::reverse_iterator reverse_iterator;
+
+  /// \brief Express the state of bundle locked groups while emitting code.
+  enum BundleLockStateType {
+    NotBundleLocked,
+    BundleLocked,
+    BundleLockedAlignToEnd
+  };
+private:
+  FragmentListType Fragments;
+  const MCSection *Section;
+
+  /// Ordinal - The section index in the assemblers section list.
+  unsigned Ordinal;
+
+  /// LayoutOrder - The index of this section in the layout order.
+  unsigned LayoutOrder;
+
+  /// Alignment - The maximum alignment seen in this section.
+  unsigned Alignment;
+
+  /// \brief Keeping track of bundle-locked state.
+  BundleLockStateType BundleLockState; 
+
+  /// \brief We've seen a bundle_lock directive but not its first instruction
+  /// yet.
+  bool BundleGroupBeforeFirstInst;
+
+  /// @name Assembler Backend Data
+  /// @{
+  //
+  // FIXME: This could all be kept private to the assembler implementation.
+
+  /// HasInstructions - Whether this section has had instructions emitted into
+  /// it.
+  unsigned HasInstructions : 1;
+
+  /// Mapping from subsection number to insertion point for subsection numbers
+  /// below that number.
+  SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap;
+
+  /// @}
+
+public:
+  // Only for use as sentinel.
+  MCSectionData();
+  MCSectionData(const MCSection &Section, MCAssembler *A = nullptr);
+
+  const MCSection &getSection() const { return *Section; }
+
+  unsigned getAlignment() const { return Alignment; }
+  void setAlignment(unsigned Value) { Alignment = Value; }
+
+  bool hasInstructions() const { return HasInstructions; }
+  void setHasInstructions(bool Value) { HasInstructions = Value; }
+
+  unsigned getOrdinal() const { return Ordinal; }
+  void setOrdinal(unsigned Value) { Ordinal = Value; }
+
+  unsigned getLayoutOrder() const { return LayoutOrder; }
+  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+  /// @name Fragment Access
+  /// @{
+
+  const FragmentListType &getFragmentList() const { return Fragments; }
+  FragmentListType &getFragmentList() { return Fragments; }
+
+  iterator begin() { return Fragments.begin(); }
+  const_iterator begin() const { return Fragments.begin(); }
+
+  iterator end() { return Fragments.end(); }
+  const_iterator end() const { return Fragments.end(); }
+
+  reverse_iterator rbegin() { return Fragments.rbegin(); }
+  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
+
+  reverse_iterator rend() { return Fragments.rend(); }
+  const_reverse_iterator rend() const { return Fragments.rend(); }
+
+  size_t size() const { return Fragments.size(); }
+
+  bool empty() const { return Fragments.empty(); }
+
+  iterator getSubsectionInsertionPoint(unsigned Subsection);
+
+  bool isBundleLocked() const {
+    return BundleLockState != NotBundleLocked;
+  }
+
+  BundleLockStateType getBundleLockState() const {
+    return BundleLockState;
+  }
+
+  void setBundleLockState(BundleLockStateType NewState) {
+    BundleLockState = NewState;
+  }
+
+  bool isBundleGroupBeforeFirstInst() const {
+    return BundleGroupBeforeFirstInst;
+  }
+
+  void setBundleGroupBeforeFirstInst(bool IsFirst) {
+    BundleGroupBeforeFirstInst = IsFirst;
+  }
+
+  void dump();
+
+  /// @}
+};
+
+// FIXME: Same concerns as with SectionData.
+class MCSymbolData : public ilist_node<MCSymbolData> {
+public:
+  const MCSymbol *Symbol;
+
+  /// Fragment - The fragment this symbol's value is relative to, if any.
+  MCFragment *Fragment;
+
+  /// Offset - The offset to apply to the fragment address to form this symbol's
+  /// value.
+  uint64_t Offset;
+
+  /// IsExternal - True if this symbol is visible outside this translation
+  /// unit.
+  unsigned IsExternal : 1;
+
+  /// IsPrivateExtern - True if this symbol is private extern.
+  unsigned IsPrivateExtern : 1;
+
+  /// CommonSize - The size of the symbol, if it is 'common', or 0.
+  //
+  // FIXME: Pack this in with other fields? We could put it in offset, since a
+  // common symbol can never get a definition.
+  uint64_t CommonSize;
+
+  /// SymbolSize - An expression describing how to calculate the size of
+  /// a symbol. If a symbol has no size this field will be NULL.
+  const MCExpr *SymbolSize;
+
+  /// CommonAlign - The alignment of the symbol, if it is 'common'.
+  //
+  // FIXME: Pack this in with other fields?
+  unsigned CommonAlign;
+
+  /// Flags - The Flags field is used by object file implementations to store
+  /// additional per symbol information which is not easily classified.
+  uint32_t Flags;
+
+  /// Index - Index field, for use by the object file implementation.
+  uint64_t Index;
+
+public:
+  // Only for use as sentinel.
+  MCSymbolData();
+  MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
+               MCAssembler *A = nullptr);
+
+  /// @name Accessors
+  /// @{
+
+  const MCSymbol &getSymbol() const { return *Symbol; }
+
+  MCFragment *getFragment() const { return Fragment; }
+  void setFragment(MCFragment *Value) { Fragment = Value; }
+
+  uint64_t getOffset() const { return Offset; }
+  void setOffset(uint64_t Value) { Offset = Value; }
+
+  /// @}
+  /// @name Symbol Attributes
+  /// @{
+
+  bool isExternal() const { return IsExternal; }
+  void setExternal(bool Value) { IsExternal = Value; }
+
+  bool isPrivateExtern() const { return IsPrivateExtern; }
+  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
+
+  /// isCommon - Is this a 'common' symbol.
+  bool isCommon() const { return CommonSize != 0; }
+
+  /// setCommon - Mark this symbol as being 'common'.
+  ///
+  /// \param Size - The size of the symbol.
+  /// \param Align - The alignment of the symbol.
+  void setCommon(uint64_t Size, unsigned Align) {
+    CommonSize = Size;
+    CommonAlign = Align;
+  }
+
+  /// getCommonSize - Return the size of a 'common' symbol.
+  uint64_t getCommonSize() const {
+    assert(isCommon() && "Not a 'common' symbol!");
+    return CommonSize;
+  }
+
+  void setSize(const MCExpr *SS) {
+    SymbolSize = SS;
+  }
+
+  const MCExpr *getSize() const {
+    return SymbolSize;
+  }
+
+
+  /// getCommonAlignment - Return the alignment of a 'common' symbol.
+  unsigned getCommonAlignment() const {
+    assert(isCommon() && "Not a 'common' symbol!");
+    return CommonAlign;
+  }
+
+  /// getFlags - Get the (implementation defined) symbol flags.
+  uint32_t getFlags() const { return Flags; }
+
+  /// setFlags - Set the (implementation defined) symbol flags.
+  void setFlags(uint32_t Value) { Flags = Value; }
+
+  /// modifyFlags - Modify the flags via a mask
+  void modifyFlags(uint32_t Value, uint32_t Mask) {
+    Flags = (Flags & ~Mask) | Value;
+  }
+
+  /// getIndex - Get the (implementation defined) index.
+  uint64_t getIndex() const { return Index; }
+
+  /// setIndex - Set the (implementation defined) index.
+  void setIndex(uint64_t Value) { Index = Value; }
+
+  /// @}
+
+  void dump() const;
+};
+
+// FIXME: This really doesn't belong here. See comments below.
+struct IndirectSymbolData {
+  MCSymbol *Symbol;
+  MCSectionData *SectionData;
+};
+
+// FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
+// to one another.
+struct DataRegionData {
+  // This enum should be kept in sync w/ the mach-o definition in
+  // llvm/Object/MachOFormat.h.
+  enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
+  MCSymbol *Start;
+  MCSymbol *End;
+};
+
+class MCAssembler {
+  friend class MCAsmLayout;
+
+public:
+  typedef iplist<MCSectionData> SectionDataListType;
+  typedef iplist<MCSymbolData> SymbolDataListType;
+
+  typedef SectionDataListType::const_iterator const_iterator;
+  typedef SectionDataListType::iterator iterator;
+
+  typedef SymbolDataListType::const_iterator const_symbol_iterator;
+  typedef SymbolDataListType::iterator symbol_iterator;
+
+  typedef iterator_range<symbol_iterator> symbol_range;
+  typedef iterator_range<const_symbol_iterator> const_symbol_range;
+
+  typedef std::vector<std::string> FileNameVectorType;
+  typedef FileNameVectorType::const_iterator const_file_name_iterator;
+
+  typedef std::vector<IndirectSymbolData>::const_iterator
+    const_indirect_symbol_iterator;
+  typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
+
+  typedef std::vector<DataRegionData>::const_iterator
+    const_data_region_iterator;
+  typedef std::vector<DataRegionData>::iterator data_region_iterator;
+
+  /// MachO specific deployment target version info.
+  // A Major version of 0 indicates that no version information was supplied
+  // and so the corresponding load command should not be emitted.
+  typedef struct {
+    MCVersionMinType Kind;
+    unsigned Major;
+    unsigned Minor;
+    unsigned Update;
+  } VersionMinInfoType;
+private:
+  MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
+  void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
+
+  MCContext &Context;
+
+  MCAsmBackend &Backend;
+
+  MCCodeEmitter &Emitter;
+
+  MCObjectWriter &Writer;
+
+  raw_ostream &OS;
+
+  iplist<MCSectionData> Sections;
+
+  iplist<MCSymbolData> Symbols;
+
+  /// The map of sections to their associated assembler backend data.
+  //
+  // FIXME: Avoid this indirection?
+  DenseMap<const MCSection*, MCSectionData*> SectionMap;
+
+  /// The map of symbols to their associated assembler backend data.
+  //
+  // FIXME: Avoid this indirection?
+  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
+
+  std::vector<IndirectSymbolData> IndirectSymbols;
+
+  std::vector<DataRegionData> DataRegions;
+
+  /// The list of linker options to propagate into the object file.
+  std::vector<std::vector<std::string> > LinkerOptions;
+
+  /// List of declared file names
+  FileNameVectorType FileNames;
+
+  /// The set of function symbols for which a .thumb_func directive has
+  /// been seen.
+  //
+  // FIXME: We really would like this in target specific code rather than
+  // here. Maybe when the relocation stuff moves to target specific,
+  // this can go with it? The streamer would need some target specific
+  // refactoring too.
+  mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+
+  /// \brief The bundle alignment size currently set in the assembler.
+  ///
+  /// By default it's 0, which means bundling is disabled.
+  unsigned BundleAlignSize;
+
+  unsigned RelaxAll : 1;
+  unsigned NoExecStack : 1;
+  unsigned SubsectionsViaSymbols : 1;
+
+  /// ELF specific e_header flags
+  // It would be good if there were an MCELFAssembler class to hold this.
+  // ELF header flags are used both by the integrated and standalone assemblers.
+  // Access to the flags is necessary in cases where assembler directives affect
+  // which flags to be set.
+  unsigned ELFHeaderEFlags;
+
+  /// Used to communicate Linker Optimization Hint information between
+  /// the Streamer and the .o writer
+  MCLOHContainer LOHContainer;
+
+  VersionMinInfoType VersionMinInfo;
+private:
+  /// Evaluate a fixup to a relocatable expression and the value which should be
+  /// placed into the fixup.
+  ///
+  /// \param Layout The layout to use for evaluation.
+  /// \param Fixup The fixup to evaluate.
+  /// \param DF The fragment the fixup is inside.
+  /// \param Target [out] On return, the relocatable expression the fixup
+  /// evaluates to.
+  /// \param Value [out] On return, the value of the fixup as currently laid
+  /// out.
+  /// \return Whether the fixup value was fully resolved. This is true if the
+  /// \p Value result is fixed, otherwise the value may change due to
+  /// relocation.
+  bool evaluateFixup(const MCAsmLayout &Layout,
+                     const MCFixup &Fixup, const MCFragment *DF,
+                     MCValue &Target, uint64_t &Value) const;
+
+  /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
+  /// (increased in size, in order to hold its value correctly).
+  bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
+                            const MCAsmLayout &Layout) const;
+
+  /// Check whether the given fragment needs relaxation.
+  bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
+                               const MCAsmLayout &Layout) const;
+
+  /// \brief Perform one layout iteration and return true if any offsets
+  /// were adjusted.
+  bool layoutOnce(MCAsmLayout &Layout);
+
+  /// \brief Perform one layout iteration of the given section and return true
+  /// if any offsets were adjusted.
+  bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
+
+  bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
+
+  bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
+
+  bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
+  bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+                                   MCDwarfCallFrameFragment &DF);
+
+  /// finishLayout - Finalize a layout, including fragment lowering.
+  void finishLayout(MCAsmLayout &Layout);
+
+  std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+                                        MCFragment &F, const MCFixup &Fixup);
+
+public:
+  /// Compute the effective fragment size assuming it is laid out at the given
+  /// \p SectionAddress and \p FragmentOffset.
+  uint64_t computeFragmentSize(const MCAsmLayout &Layout,
+                               const MCFragment &F) const;
+
+  /// Find the symbol which defines the atom containing the given symbol, or
+  /// null if there is no such symbol.
+  const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
+
+  /// Check whether a particular symbol is visible to the linker and is required
+  /// in the symbol table, or whether it can be discarded by the assembler. This
+  /// also effects whether the assembler treats the label as potentially
+  /// defining a separate atom.
+  bool isSymbolLinkerVisible(const MCSymbol &SD) const;
+
+  /// Emit the section contents using the given object writer.
+  void writeSectionData(const MCSectionData *Section,
+                        const MCAsmLayout &Layout) const;
+
+  /// Check whether a given symbol has been flagged with .thumb_func.
+  bool isThumbFunc(const MCSymbol *Func) const;
+
+  /// Flag a function symbol as the target of a .thumb_func directive.
+  void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
+
+  /// ELF e_header flags
+  unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
+  void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+
+  /// MachO deployment target version information.
+  const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+  void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+                         unsigned Update) {
+    VersionMinInfo.Kind = Kind;
+    VersionMinInfo.Major = Major;
+    VersionMinInfo.Minor = Minor;
+    VersionMinInfo.Update = Update;
+  }
+
+public:
+  /// Construct a new assembler instance.
+  ///
+  /// \param OS The stream to output to.
+  //
+  // FIXME: How are we going to parameterize this? Two obvious options are stay
+  // concrete and require clients to pass in a target like object. The other
+  // option is to make this abstract, and have targets provide concrete
+  // implementations as we do with AsmParser.
+  MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
+              MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
+              raw_ostream &OS);
+  ~MCAssembler();
+
+  /// Reuse an assembler instance
+  ///
+  void reset();
+
+  MCContext &getContext() const { return Context; }
+
+  MCAsmBackend &getBackend() const { return Backend; }
+
+  MCCodeEmitter &getEmitter() const { return Emitter; }
+
+  MCObjectWriter &getWriter() const { return Writer; }
+
+  /// Finish - Do final processing and write the object to the output stream.
+  /// \p Writer is used for custom object writer (as the MCJIT does),
+  /// if not specified it is automatically created from backend.
+  void Finish();
+
+  // FIXME: This does not belong here.
+  bool getSubsectionsViaSymbols() const {
+    return SubsectionsViaSymbols;
+  }
+  void setSubsectionsViaSymbols(bool Value) {
+    SubsectionsViaSymbols = Value;
+  }
+
+  bool getRelaxAll() const { return RelaxAll; }
+  void setRelaxAll(bool Value) { RelaxAll = Value; }
+
+  bool getNoExecStack() const { return NoExecStack; }
+  void setNoExecStack(bool Value) { NoExecStack = Value; }
+
+  bool isBundlingEnabled() const {
+    return BundleAlignSize != 0;
+  }
+
+  unsigned getBundleAlignSize() const {
+    return BundleAlignSize;
+  }
+
+  void setBundleAlignSize(unsigned Size) {
+    assert((Size == 0 || !(Size & (Size - 1))) && 
+           "Expect a power-of-two bundle align size");
+    BundleAlignSize = Size;
+  }
+
+  /// @name Section List Access
+  /// @{
+
+  const SectionDataListType &getSectionList() const { return Sections; }
+  SectionDataListType &getSectionList() { return Sections; }
+
+  iterator begin() { return Sections.begin(); }
+  const_iterator begin() const { return Sections.begin(); }
+
+  iterator end() { return Sections.end(); }
+  const_iterator end() const { return Sections.end(); }
+
+  size_t size() const { return Sections.size(); }
+
+  /// @}
+  /// @name Symbol List Access
+  /// @{
+
+  const SymbolDataListType &getSymbolList() const { return Symbols; }
+  SymbolDataListType &getSymbolList() { return Symbols; }
+
+  symbol_iterator symbol_begin() { return Symbols.begin(); }
+  const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
+
+  symbol_iterator symbol_end() { return Symbols.end(); }
+  const_symbol_iterator symbol_end() const { return Symbols.end(); }
+
+  symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); }
+  const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); }
+
+  size_t symbol_size() const { return Symbols.size(); }
+
+  /// @}
+  /// @name Indirect Symbol List Access
+  /// @{
+
+  // FIXME: This is a total hack, this should not be here. Once things are
+  // factored so that the streamer has direct access to the .o writer, it can
+  // disappear.
+  std::vector<IndirectSymbolData> &getIndirectSymbols() {
+    return IndirectSymbols;
+  }
+
+  indirect_symbol_iterator indirect_symbol_begin() {
+    return IndirectSymbols.begin();
+  }
+  const_indirect_symbol_iterator indirect_symbol_begin() const {
+    return IndirectSymbols.begin();
+  }
+
+  indirect_symbol_iterator indirect_symbol_end() {
+    return IndirectSymbols.end();
+  }
+  const_indirect_symbol_iterator indirect_symbol_end() const {
+    return IndirectSymbols.end();
+  }
+
+  size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
+
+  /// @}
+  /// @name Linker Option List Access
+  /// @{
+
+  std::vector<std::vector<std::string> > &getLinkerOptions() {
+    return LinkerOptions;
+  }
+
+  /// @}
+  /// @name Data Region List Access
+  /// @{
+
+  // FIXME: This is a total hack, this should not be here. Once things are
+  // factored so that the streamer has direct access to the .o writer, it can
+  // disappear.
+  std::vector<DataRegionData> &getDataRegions() {
+    return DataRegions;
+  }
+
+  data_region_iterator data_region_begin() {
+    return DataRegions.begin();
+  }
+  const_data_region_iterator data_region_begin() const {
+    return DataRegions.begin();
+  }
+
+  data_region_iterator data_region_end() {
+    return DataRegions.end();
+  }
+  const_data_region_iterator data_region_end() const {
+    return DataRegions.end();
+  }
+
+  size_t data_region_size() const { return DataRegions.size(); }
+
+  /// @}
+  /// @name Data Region List Access
+  /// @{
+
+  // FIXME: This is a total hack, this should not be here. Once things are
+  // factored so that the streamer has direct access to the .o writer, it can
+  // disappear.
+  MCLOHContainer & getLOHContainer() {
+    return LOHContainer;
+  }
+  const MCLOHContainer & getLOHContainer() const {
+    return const_cast<MCAssembler *>(this)->getLOHContainer();
+  }
+  /// @}
+  /// @name Backend Data Access
+  /// @{
+
+  MCSectionData &getSectionData(const MCSection &Section) const {
+    MCSectionData *Entry = SectionMap.lookup(&Section);
+    assert(Entry && "Missing section data!");
+    return *Entry;
+  }
+
+  MCSectionData &getOrCreateSectionData(const MCSection &Section,
+                                        bool *Created = nullptr) {
+    MCSectionData *&Entry = SectionMap[&Section];
+
+    if (Created) *Created = !Entry;
+    if (!Entry)
+      Entry = new MCSectionData(Section, this);
+
+    return *Entry;
+  }
+
+  bool hasSymbolData(const MCSymbol &Symbol) const {
+    return SymbolMap.lookup(&Symbol) != nullptr;
+  }
+
+  MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
+    return const_cast<MCSymbolData &>(
+        static_cast<const MCAssembler &>(*this).getSymbolData(Symbol));
+  }
+
+  const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+    MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
+    assert(Entry && "Missing symbol data!");
+    return *Entry;
+  }
+
+  MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
+                                      bool *Created = nullptr) {
+    MCSymbolData *&Entry = SymbolMap[&Symbol];
+
+    if (Created) *Created = !Entry;
+    if (!Entry)
+      Entry = new MCSymbolData(Symbol, nullptr, 0, this);
+
+    return *Entry;
+  }
+
+  const_file_name_iterator file_names_begin() const {
+    return FileNames.begin();
+  }
+
+  const_file_name_iterator file_names_end() const {
+    return FileNames.end();
+  }
+
+  void addFileName(StringRef FileName) {
+    if (std::find(file_names_begin(), file_names_end(), FileName) ==
+        file_names_end())
+      FileNames.push_back(FileName);
+  }
+
+  /// @}
+
+  void dump();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
new file mode 100644
index 0000000..d3b5617
--- /dev/null
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -0,0 +1,45 @@
+//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEEMITTER_H
+#define LLVM_MC_MCCODEEMITTER_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+class MCFixup;
+class MCInst;
+class MCSubtargetInfo;
+class raw_ostream;
+template<typename T> class SmallVectorImpl;
+
+/// MCCodeEmitter - Generic instruction encoding interface.
+class MCCodeEmitter {
+private:
+  MCCodeEmitter(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCCodeEmitter &) LLVM_DELETED_FUNCTION;
+protected: // Can only create subclasses.
+  MCCodeEmitter();
+
+public:
+  virtual ~MCCodeEmitter();
+
+  /// Lifetime management
+  virtual void reset() { }
+
+  /// EncodeInstruction - Encode the given \p Inst to bytes on the output
+  /// stream \p OS.
+  virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
+                                 SmallVectorImpl<MCFixup> &Fixups,
+                                 const MCSubtargetInfo &STI) const = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h
new file mode 100644
index 0000000..84ce934
--- /dev/null
+++ b/include/llvm/MC/MCCodeGenInfo.h
@@ -0,0 +1,51 @@
+//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen 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 tracks information about the target which can affect codegen,
+// asm parsing, and asm printing. For example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEGENINFO_H
+#define LLVM_MC_MCCODEGENINFO_H
+
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+
+  class MCCodeGenInfo {
+    /// RelocationModel - Relocation model: static, pic, etc.
+    ///
+    Reloc::Model RelocationModel;
+
+    /// CMModel - Code model.
+    ///
+    CodeModel::Model CMModel;
+
+    /// OptLevel - Optimization level.
+    ///
+    CodeGenOpt::Level OptLevel;
+
+  public:
+    void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
+                           CodeModel::Model CM = CodeModel::Default,
+                           CodeGenOpt::Level OL = CodeGenOpt::Default);
+
+    Reloc::Model getRelocationModel() const { return RelocationModel; }
+
+    CodeModel::Model getCodeModel() const { return CMModel; }
+
+    CodeGenOpt::Level getOptLevel() const { return OptLevel; }
+
+    // Allow overriding OptLevel on a per-function basis.
+    void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
+  };
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
new file mode 100644
index 0000000..eb0340f
--- /dev/null
+++ b/include/llvm/MC/MCContext.h
@@ -0,0 +1,507 @@
+//===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCONTEXT_H
+#define LLVM_MC_MCCONTEXT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <tuple>
+#include <vector> // FIXME: Shouldn't be needed.
+
+namespace llvm {
+  class MCAsmInfo;
+  class MCExpr;
+  class MCSection;
+  class MCSymbol;
+  class MCLabel;
+  struct MCDwarfFile;
+  class MCDwarfLoc;
+  class MCObjectFileInfo;
+  class MCRegisterInfo;
+  class MCLineSection;
+  class SMLoc;
+  class StringRef;
+  class Twine;
+  class MCSectionMachO;
+  class MCSectionELF;
+  class MCSectionCOFF;
+
+  /// MCContext - Context object for machine code objects.  This class owns all
+  /// of the sections that it creates.
+  ///
+  class MCContext {
+    MCContext(const MCContext&) LLVM_DELETED_FUNCTION;
+    MCContext &operator=(const MCContext&) LLVM_DELETED_FUNCTION;
+  public:
+    typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
+  private:
+    /// The SourceMgr for this object, if any.
+    const SourceMgr *SrcMgr;
+
+    /// The MCAsmInfo for this target.
+    const MCAsmInfo *MAI;
+
+    /// The MCRegisterInfo for this target.
+    const MCRegisterInfo *MRI;
+
+    /// The MCObjectFileInfo for this target.
+    const MCObjectFileInfo *MOFI;
+
+    /// Allocator - Allocator object used for creating machine code objects.
+    ///
+    /// We use a bump pointer allocator to avoid the need to track all allocated
+    /// objects.
+    BumpPtrAllocator Allocator;
+
+    /// Symbols - Bindings of names to symbols.
+    SymbolTable Symbols;
+
+    /// A maping from a local label number and an instance count to a symbol.
+    /// For example, in the assembly
+    ///     1:
+    ///     2:
+    ///     1:
+    /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1)
+    DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols;
+
+    /// UsedNames - Keeps tracks of names that were used both for used declared
+    /// and artificial symbols.
+    StringMap<bool, BumpPtrAllocator&> UsedNames;
+
+    /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
+    /// symbol.
+    unsigned NextUniqueID;
+
+    /// Instances of directional local labels.
+    DenseMap<unsigned, MCLabel *> Instances;
+    /// NextInstance() creates the next instance of the directional local label
+    /// for the LocalLabelVal and adds it to the map if needed.
+    unsigned NextInstance(unsigned LocalLabelVal);
+    /// GetInstance() gets the current instance of the directional local label
+    /// for the LocalLabelVal and adds it to the map if needed.
+    unsigned GetInstance(unsigned LocalLabelVal);
+
+    /// The file name of the log file from the environment variable
+    /// AS_SECURE_LOG_FILE.  Which must be set before the .secure_log_unique
+    /// directive is used or it is an error.
+    char *SecureLogFile;
+    /// The stream that gets written to for the .secure_log_unique directive.
+    raw_ostream *SecureLog;
+    /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
+    /// catch errors if .secure_log_unique appears twice without
+    /// .secure_log_reset appearing between them.
+    bool SecureLogUsed;
+
+    /// The compilation directory to use for DW_AT_comp_dir.
+    SmallString<128> CompilationDir;
+
+    /// The main file name if passed in explicitly.
+    std::string MainFileName;
+
+    /// The dwarf file and directory tables from the dwarf .file directive.
+    /// We now emit a line table for each compile unit. To reduce the prologue
+    /// size of each line table, the files and directories used by each compile
+    /// unit are separated.
+    std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap;
+
+    /// The current dwarf line information from the last dwarf .loc directive.
+    MCDwarfLoc CurrentDwarfLoc;
+    bool DwarfLocSeen;
+
+    /// Generate dwarf debugging info for assembly source files.
+    bool GenDwarfForAssembly;
+
+    /// The current dwarf file number when generate dwarf debugging info for
+    /// assembly source files.
+    unsigned GenDwarfFileNumber;
+
+    /// Symbols created for the start and end of each section, used for
+    /// generating the .debug_ranges and .debug_aranges sections.
+    MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >
+    SectionStartEndSyms;
+
+    /// The information gathered from labels that will have dwarf label
+    /// entries when generating dwarf assembly source files.
+    std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries;
+
+    /// The string to embed in the debug information for the compile unit, if
+    /// non-empty.
+    StringRef DwarfDebugFlags;
+
+    /// The string to embed in as the dwarf AT_producer for the compile unit, if
+    /// non-empty.
+    StringRef DwarfDebugProducer;
+
+    /// The maximum version of dwarf that we should emit.
+    uint16_t DwarfVersion;
+
+    /// Honor temporary labels, this is useful for debugging semantic
+    /// differences between temporary and non-temporary labels (primarily on
+    /// Darwin).
+    bool AllowTemporaryLabels;
+
+    /// The Compile Unit ID that we are currently processing.
+    unsigned DwarfCompileUnitID;
+
+    typedef std::pair<std::string, std::string> SectionGroupPair;
+    typedef std::tuple<std::string, std::string, int> SectionGroupTriple;
+
+    StringMap<const MCSectionMachO*> MachOUniquingMap;
+    std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap;
+    std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap;
+
+    /// Do automatic reset in destructor
+    bool AutoReset;
+
+    MCSymbol *CreateSymbol(StringRef Name);
+
+    MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
+                                                unsigned Instance);
+
+  public:
+    explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
+                       const MCObjectFileInfo *MOFI,
+                       const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
+    ~MCContext();
+
+    const SourceMgr *getSourceManager() const { return SrcMgr; }
+
+    const MCAsmInfo *getAsmInfo() const { return MAI; }
+
+    const MCRegisterInfo *getRegisterInfo() const { return MRI; }
+
+    const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
+
+    void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+
+    /// @name Module Lifetime Management
+    /// @{
+
+    /// reset - return object to right after construction state to prepare
+    /// to process a new module
+    void reset();
+
+    /// @}
+
+    /// @name Symbol Management
+    /// @{
+
+    /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
+    /// symbol with a unique but unspecified name.
+    MCSymbol *CreateLinkerPrivateTempSymbol();
+
+    /// CreateTempSymbol - Create and return a new assembler temporary symbol
+    /// with a unique but unspecified name.
+    MCSymbol *CreateTempSymbol();
+
+    /// getUniqueSymbolID() - Return a unique identifier for use in constructing
+    /// symbol names.
+    unsigned getUniqueSymbolID() { return NextUniqueID++; }
+
+    /// Create the definition of a directional local symbol for numbered label
+    /// (used for "1:" definitions).
+    MCSymbol *CreateDirectionalLocalSymbol(unsigned LocalLabelVal);
+
+    /// Create and return a directional local symbol for numbered label (used
+    /// for "1b" or 1f" references).
+    MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
+
+    /// GetOrCreateSymbol - Lookup the symbol inside with the specified
+    /// @p Name.  If it exists, return it.  If not, create a forward
+    /// reference and return it.
+    ///
+    /// @param Name - The symbol name, which must be unique across all symbols.
+    MCSymbol *GetOrCreateSymbol(StringRef Name);
+    MCSymbol *GetOrCreateSymbol(const Twine &Name);
+
+    /// LookupSymbol - Get the symbol for \p Name, or null.
+    MCSymbol *LookupSymbol(StringRef Name) const;
+    MCSymbol *LookupSymbol(const Twine &Name) const;
+
+    /// getSymbols - Get a reference for the symbol table for clients that
+    /// want to, for example, iterate over all symbols. 'const' because we
+    /// still want any modifications to the table itself to use the MCContext
+    /// APIs.
+    const SymbolTable &getSymbols() const {
+      return Symbols;
+    }
+
+    /// @}
+
+    /// @name Section Management
+    /// @{
+
+    /// getMachOSection - Return the MCSection for the specified mach-o section.
+    /// This requires the operands to be valid.
+    const MCSectionMachO *getMachOSection(StringRef Segment,
+                                          StringRef Section,
+                                          unsigned TypeAndAttributes,
+                                          unsigned Reserved2,
+                                          SectionKind K);
+    const MCSectionMachO *getMachOSection(StringRef Segment,
+                                          StringRef Section,
+                                          unsigned TypeAndAttributes,
+                                          SectionKind K) {
+      return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+    }
+
+    const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+                                      unsigned Flags, SectionKind Kind);
+
+    const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+                                      unsigned Flags, SectionKind Kind,
+                                      unsigned EntrySize, StringRef Group);
+
+    void renameELFSection(const MCSectionELF *Section, StringRef Name);
+
+    const MCSectionELF *CreateELFGroupSection();
+
+    const MCSectionCOFF *getCOFFSection(StringRef Section,
+                                        unsigned Characteristics,
+                                        SectionKind Kind,
+                                        StringRef COMDATSymName, int Selection);
+
+    const MCSectionCOFF *getCOFFSection(StringRef Section,
+                                        unsigned Characteristics,
+                                        SectionKind Kind);
+
+    const MCSectionCOFF *getCOFFSection(StringRef Section);
+
+    /// @}
+
+    /// @name Dwarf Management
+    /// @{
+
+    /// \brief Get the compilation directory for DW_AT_comp_dir
+    /// This can be overridden by clients which want to control the reported
+    /// compilation directory and have it be something other than the current
+    /// working directory.
+    /// Returns an empty string if the current directory cannot be determined.
+    StringRef getCompilationDir() const { return CompilationDir; }
+
+    /// \brief Set the compilation directory for DW_AT_comp_dir
+    /// Override the default (CWD) compilation directory.
+    void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
+
+    /// \brief Get the main file name for use in error messages and debug
+    /// info. This can be set to ensure we've got the correct file name
+    /// after preprocessing or for -save-temps.
+    const std::string &getMainFileName() const { return MainFileName; }
+
+    /// \brief Set the main file name and override the default.
+    void setMainFileName(StringRef S) { MainFileName = S; }
+
+    /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
+    unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
+                          unsigned FileNumber, unsigned CUID);
+
+    bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
+
+    const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
+      return MCDwarfLineTablesCUMap;
+    }
+
+    MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) {
+      return MCDwarfLineTablesCUMap[CUID];
+    }
+
+    const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const {
+      auto I = MCDwarfLineTablesCUMap.find(CUID);
+      assert(I != MCDwarfLineTablesCUMap.end());
+      return I->second;
+    }
+
+    const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
+      return getMCDwarfLineTable(CUID).getMCDwarfFiles();
+    }
+    const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
+      return getMCDwarfLineTable(CUID).getMCDwarfDirs();
+    }
+
+    bool hasMCLineSections() const {
+      for (const auto &Table : MCDwarfLineTablesCUMap)
+        if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
+          return true;
+      return false;
+    }
+    unsigned getDwarfCompileUnitID() {
+      return DwarfCompileUnitID;
+    }
+    void setDwarfCompileUnitID(unsigned CUIndex) {
+      DwarfCompileUnitID = CUIndex;
+    }
+    void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
+      getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
+    }
+
+    /// setCurrentDwarfLoc - saves the information from the currently parsed
+    /// dwarf .loc directive and sets DwarfLocSeen.  When the next instruction
+    /// is assembled an entry in the line number table with this information and
+    /// the address of the instruction will be created.
+    void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
+                            unsigned Flags, unsigned Isa,
+                            unsigned Discriminator) {
+      CurrentDwarfLoc.setFileNum(FileNum);
+      CurrentDwarfLoc.setLine(Line);
+      CurrentDwarfLoc.setColumn(Column);
+      CurrentDwarfLoc.setFlags(Flags);
+      CurrentDwarfLoc.setIsa(Isa);
+      CurrentDwarfLoc.setDiscriminator(Discriminator);
+      DwarfLocSeen = true;
+    }
+    void ClearDwarfLocSeen() { DwarfLocSeen = false; }
+
+    bool getDwarfLocSeen() { return DwarfLocSeen; }
+    const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
+
+    bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
+    void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
+    unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
+    void setGenDwarfFileNumber(unsigned FileNumber) {
+      GenDwarfFileNumber = FileNumber;
+    }
+    MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
+    getGenDwarfSectionSyms() {
+      return SectionStartEndSyms;
+    }
+    std::pair<MapVector<const MCSection *,
+                        std::pair<MCSymbol *, MCSymbol *> >::iterator,
+              bool>
+    addGenDwarfSection(const MCSection *Sec) {
+      return SectionStartEndSyms.insert(
+          std::make_pair(Sec, std::make_pair(nullptr, nullptr)));
+    }
+    void finalizeDwarfSections(MCStreamer &MCOS);
+    const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
+      return MCGenDwarfLabelEntries;
+    }
+    void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
+      MCGenDwarfLabelEntries.push_back(E);
+    }
+
+    void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
+    StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
+
+    void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
+    StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+
+    void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
+    uint16_t getDwarfVersion() const { return DwarfVersion; }
+
+    /// @}
+
+    char *getSecureLogFile() { return SecureLogFile; }
+    raw_ostream *getSecureLog() { return SecureLog; }
+    bool getSecureLogUsed() { return SecureLogUsed; }
+    void setSecureLog(raw_ostream *Value) {
+      SecureLog = Value;
+    }
+    void setSecureLogUsed(bool Value) {
+      SecureLogUsed = Value;
+    }
+
+    void *Allocate(unsigned Size, unsigned Align = 8) {
+      return Allocator.Allocate(Size, Align);
+    }
+    void Deallocate(void *Ptr) {
+    }
+
+    // Unrecoverable error has occurred. Display the best diagnostic we can
+    // and bail via exit(1). For now, most MC backend errors are unrecoverable.
+    // FIXME: We should really do something about that.
+    LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg) const;
+  };
+
+} // end namespace llvm
+
+// operator new and delete aren't allowed inside namespaces.
+// The throw specifications are mandated by the standard.
+/// @brief Placement new for using the MCContext's allocator.
+///
+/// This placement form of operator new uses the MCContext's allocator for
+/// obtaining memory. It is a non-throwing new, which means that it returns
+/// null on error. (If that is what the allocator does. The current does, so if
+/// this ever changes, this operator will have to be changed, too.)
+/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
+/// @code
+/// // Default alignment (16)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The MCContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, llvm::MCContext &C,
+                          size_t Alignment = 16) throw () {
+  return C.Allocate(Bytes, Alignment);
+}
+/// @brief Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the MCContext throws in the object constructor.
+inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
+              throw () {
+  C.Deallocate(Ptr);
+}
+
+/// This placement form of operator new[] uses the MCContext's allocator for
+/// obtaining memory. It is a non-throwing new[], which means that it returns
+/// null on error.
+/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
+/// @code
+/// // Default alignment (16)
+/// char *data = new (Context) char[10];
+/// // Specific alignment
+/// char *data = new (Context, 8) char[10];
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The MCContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+///                  allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new[](size_t Bytes, llvm::MCContext& C,
+                            size_t Alignment = 16) throw () {
+  return C.Allocate(Bytes, Alignment);
+}
+
+/// @brief Placement delete[] companion to the new[] above.
+///
+/// This operator is just a companion to the new[] above. There is no way of
+/// invoking it directly; see the new[] operator for more details. This operator
+/// is called implicitly by the compiler if a placement new[] expression using
+/// the MCContext throws in the object constructor.
+inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
+  C.Deallocate(Ptr);
+}
+
+#endif
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
new file mode 100644
index 0000000..f9d66e0
--- /dev/null
+++ b/include/llvm/MC/MCDirectives.h
@@ -0,0 +1,70 @@
+//===- MCDirectives.h - Enums for directives on various targets -*- 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 various enums that represent target-specific directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDIRECTIVES_H
+#define LLVM_MC_MCDIRECTIVES_H
+
+namespace llvm {
+
+enum MCSymbolAttr {
+  MCSA_Invalid = 0,    ///< Not a valid directive.
+
+  // Various directives in alphabetical order.
+  MCSA_ELF_TypeFunction,    ///< .type _foo, STT_FUNC  # aka @function
+  MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+  MCSA_ELF_TypeObject,      ///< .type _foo, STT_OBJECT  # aka @object
+  MCSA_ELF_TypeTLS,         ///< .type _foo, STT_TLS     # aka @tls_object
+  MCSA_ELF_TypeCommon,      ///< .type _foo, STT_COMMON  # aka @common
+  MCSA_ELF_TypeNoType,      ///< .type _foo, STT_NOTYPE  # aka @notype
+  MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
+  MCSA_Global,              ///< .globl
+  MCSA_Hidden,              ///< .hidden (ELF)
+  MCSA_IndirectSymbol,      ///< .indirect_symbol (MachO)
+  MCSA_Internal,            ///< .internal (ELF)
+  MCSA_LazyReference,       ///< .lazy_reference (MachO)
+  MCSA_Local,               ///< .local (ELF)
+  MCSA_NoDeadStrip,         ///< .no_dead_strip (MachO)
+  MCSA_SymbolResolver,      ///< .symbol_resolver (MachO)
+  MCSA_PrivateExtern,       ///< .private_extern (MachO)
+  MCSA_Protected,           ///< .protected (ELF)
+  MCSA_Reference,           ///< .reference (MachO)
+  MCSA_Weak,                ///< .weak
+  MCSA_WeakDefinition,      ///< .weak_definition (MachO)
+  MCSA_WeakReference,       ///< .weak_reference (MachO)
+  MCSA_WeakDefAutoPrivate   ///< .weak_def_can_be_hidden (MachO)
+};
+
+enum MCAssemblerFlag {
+  MCAF_SyntaxUnified,         ///< .syntax (ARM/ELF)
+  MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO)
+  MCAF_Code16,                ///< .code16 (X86) / .code 16 (ARM)
+  MCAF_Code32,                ///< .code32 (X86) / .code 32 (ARM)
+  MCAF_Code64                 ///< .code64 (X86)
+};
+
+enum MCDataRegionType {
+  MCDR_DataRegion,            ///< .data_region
+  MCDR_DataRegionJT8,         ///< .data_region jt8
+  MCDR_DataRegionJT16,        ///< .data_region jt16
+  MCDR_DataRegionJT32,        ///< .data_region jt32
+  MCDR_DataRegionEnd          ///< .end_data_region
+};
+
+enum MCVersionMinType {
+  MCVM_IOSVersionMin,         ///< .ios_version_min
+  MCVM_OSXVersionMin          ///< .macosx_version_min
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
new file mode 100644
index 0000000..9d441bb
--- /dev/null
+++ b/include/llvm/MC/MCDisassembler.h
@@ -0,0 +1,117 @@
+//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCDISASSEMBLER_H
+#define LLVM_MC_MCDISASSEMBLER_H
+
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/MC/MCSymbolizer.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MCInst;
+class MCSubtargetInfo;
+class MemoryObject;
+class raw_ostream;
+class MCContext;
+
+/// MCDisassembler - Superclass for all disassemblers.  Consumes a memory region
+///   and provides an array of assembly instructions.
+class MCDisassembler {
+public:
+  /// Ternary decode status. Most backends will just use Fail and
+  /// Success, however some have a concept of an instruction with
+  /// understandable semantics but which is architecturally
+  /// incorrect. An example of this is ARM UNPREDICTABLE instructions
+  /// which are disassemblable but cause undefined behaviour.
+  ///
+  /// Because it makes sense to disassemble these instructions, there
+  /// is a "soft fail" failure mode that indicates the MCInst& is
+  /// valid but architecturally incorrect.
+  ///
+  /// The enum numbers are deliberately chosen such that reduction
+  /// from Success->SoftFail ->Fail can be done with a simple
+  /// bitwise-AND:
+  ///
+  ///   LEFT & TOP =  | Success       Unpredictable   Fail
+  ///   --------------+-----------------------------------
+  ///   Success       | Success       Unpredictable   Fail
+  ///   Unpredictable | Unpredictable Unpredictable   Fail
+  ///   Fail          | Fail          Fail            Fail
+  ///
+  /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
+  /// Success, SoftFail, Fail respectively.
+  enum DecodeStatus {
+    Fail = 0,
+    SoftFail = 1,
+    Success = 3
+  };
+
+  /// Constructor     - Performs initial setup for the disassembler.
+  MCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
+    : Ctx(Ctx), STI(STI), Symbolizer(), CommentStream(nullptr) {}
+
+  virtual ~MCDisassembler();
+
+  /// getInstruction  - Returns the disassembly of a single instruction.
+  ///
+  /// @param instr    - An MCInst to populate with the contents of the
+  ///                   instruction.
+  /// @param size     - A value to populate with the size of the instruction, or
+  ///                   the number of bytes consumed while attempting to decode
+  ///                   an invalid instruction.
+  /// @param region   - The memory object to use as a source for machine code.
+  /// @param address  - The address, in the memory space of region, of the first
+  ///                   byte of the instruction.
+  /// @param vStream  - The stream to print warnings and diagnostic messages on.
+  /// @param cStream  - The stream to print comments and annotations on.
+  /// @return         - MCDisassembler::Success if the instruction is valid,
+  ///                   MCDisassembler::SoftFail if the instruction was
+  ///                                            disassemblable but invalid,
+  ///                   MCDisassembler::Fail if the instruction was invalid.
+  virtual DecodeStatus  getInstruction(MCInst& instr,
+                                       uint64_t& size,
+                                       const MemoryObject &region,
+                                       uint64_t address,
+                                       raw_ostream &vStream,
+                                       raw_ostream &cStream) const = 0;
+private:
+  MCContext &Ctx;
+
+protected:
+  // Subtarget information, for instruction decoding predicates if required.
+  const MCSubtargetInfo &STI;
+  std::unique_ptr<MCSymbolizer> Symbolizer;
+
+public:
+  // Helpers around MCSymbolizer
+  bool tryAddingSymbolicOperand(MCInst &Inst,
+                                int64_t Value,
+                                uint64_t Address, bool IsBranch,
+                                uint64_t Offset, uint64_t InstSize) const;
+
+  void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const;
+
+  /// Set \p Symzer as the current symbolizer.
+  /// This takes ownership of \p Symzer, and deletes the previously set one.
+  void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
+
+  MCContext& getContext() const { return Ctx; }
+
+  const MCSubtargetInfo& getSubtargetInfo() const { return STI; }
+
+  // Marked mutable because we cache it inside the disassembler, rather than
+  // having to pass it around as an argument through all the autogenerated code.
+  mutable raw_ostream *CommentStream;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
new file mode 100644
index 0000000..6cd9a9a
--- /dev/null
+++ b/include/llvm/MC/MCDwarf.h
@@ -0,0 +1,495 @@
+//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCDwarfFile to support the dwarf
+// .file directive and the .loc directive.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDWARF_H
+#define LLVM_MC_MCDWARF_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <vector>
+#include <string>
+#include <utility>
+
+namespace llvm {
+class MCAsmBackend;
+class MCContext;
+class MCObjectStreamer;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class SourceMgr;
+class SMLoc;
+
+/// MCDwarfFile - Instances of this class represent the name of the dwarf
+/// .file directive and its associated dwarf file number in the MC file,
+/// and MCDwarfFile's are created and unique'd by the MCContext class where
+/// the file number for each is its index into the vector of DwarfFiles (note
+/// index 0 is not used and not a valid dwarf file number).
+struct MCDwarfFile {
+  // Name - the base name of the file without its directory path.
+  // The StringRef references memory allocated in the MCContext.
+  std::string Name;
+
+  // DirIndex - the index into the list of directory names for this file name.
+  unsigned DirIndex;
+};
+
+/// MCDwarfLoc - Instances of this class represent the information from a
+/// dwarf .loc directive.
+class MCDwarfLoc {
+  // FileNum - the file number.
+  unsigned FileNum;
+  // Line - the line number.
+  unsigned Line;
+  // Column - the column position.
+  unsigned Column;
+  // Flags (see #define's below)
+  unsigned Flags;
+  // Isa
+  unsigned Isa;
+  // Discriminator
+  unsigned Discriminator;
+
+// Flag that indicates the initial value of the is_stmt_start flag.
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+#define DWARF2_FLAG_IS_STMT (1 << 0)
+#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
+#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
+#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
+
+private: // MCContext manages these
+  friend class MCContext;
+  friend class MCLineEntry;
+  MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
+             unsigned isa, unsigned discriminator)
+      : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
+        Discriminator(discriminator) {}
+
+  // Allow the default copy constructor and assignment operator to be used
+  // for an MCDwarfLoc object.
+
+public:
+  /// getFileNum - Get the FileNum of this MCDwarfLoc.
+  unsigned getFileNum() const { return FileNum; }
+
+  /// getLine - Get the Line of this MCDwarfLoc.
+  unsigned getLine() const { return Line; }
+
+  /// getColumn - Get the Column of this MCDwarfLoc.
+  unsigned getColumn() const { return Column; }
+
+  /// getFlags - Get the Flags of this MCDwarfLoc.
+  unsigned getFlags() const { return Flags; }
+
+  /// getIsa - Get the Isa of this MCDwarfLoc.
+  unsigned getIsa() const { return Isa; }
+
+  /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
+  unsigned getDiscriminator() const { return Discriminator; }
+
+  /// setFileNum - Set the FileNum of this MCDwarfLoc.
+  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+  /// setLine - Set the Line of this MCDwarfLoc.
+  void setLine(unsigned line) { Line = line; }
+
+  /// setColumn - Set the Column of this MCDwarfLoc.
+  void setColumn(unsigned column) { Column = column; }
+
+  /// setFlags - Set the Flags of this MCDwarfLoc.
+  void setFlags(unsigned flags) { Flags = flags; }
+
+  /// setIsa - Set the Isa of this MCDwarfLoc.
+  void setIsa(unsigned isa) { Isa = isa; }
+
+  /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
+  void setDiscriminator(unsigned discriminator) {
+    Discriminator = discriminator;
+  }
+};
+
+/// MCLineEntry - Instances of this class represent the line information for
+/// the dwarf line table entries.  Which is created after a machine
+/// instruction is assembled and uses an address from a temporary label
+/// created at the current address in the current section and the info from
+/// the last .loc directive seen as stored in the context.
+class MCLineEntry : public MCDwarfLoc {
+  MCSymbol *Label;
+
+private:
+  // Allow the default copy constructor and assignment operator to be used
+  // for an MCLineEntry object.
+
+public:
+  // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
+  MCLineEntry(MCSymbol *label, const MCDwarfLoc loc)
+      : MCDwarfLoc(loc), Label(label) {}
+
+  MCSymbol *getLabel() const { return Label; }
+
+  // This is called when an instruction is assembled into the specified
+  // section and if there is information from the last .loc directive that
+  // has yet to have a line entry made for it is made.
+  static void Make(MCObjectStreamer *MCOS, const MCSection *Section);
+};
+
+/// MCLineSection - Instances of this class represent the line information
+/// for a compile unit where machine instructions have been assembled after seeing
+/// .loc directives.  This is the information used to build the dwarf line
+/// table for a section.
+class MCLineSection {
+public:
+  // addLineEntry - adds an entry to this MCLineSection's line entries
+  void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
+    MCLineDivisions[Sec].push_back(LineEntry);
+  }
+
+  typedef std::vector<MCLineEntry> MCLineEntryCollection;
+  typedef MCLineEntryCollection::iterator iterator;
+  typedef MCLineEntryCollection::const_iterator const_iterator;
+  typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
+
+private:
+  // A collection of MCLineEntry for each section.
+  MCLineDivisionMap MCLineDivisions;
+
+public:
+  // Returns the collection of MCLineEntry for a given Compile Unit ID.
+  const MCLineDivisionMap &getMCLineEntries() const {
+    return MCLineDivisions;
+  }
+};
+
+struct MCDwarfLineTableHeader {
+  MCSymbol *Label;
+  SmallVector<std::string, 3> MCDwarfDirs;
+  SmallVector<MCDwarfFile, 3> MCDwarfFiles;
+  StringMap<unsigned> SourceIdMap;
+  StringRef CompilationDir;
+
+  MCDwarfLineTableHeader() : Label(nullptr) {}
+  unsigned getFile(StringRef &Directory, StringRef &FileName,
+                   unsigned FileNumber = 0);
+  std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
+  std::pair<MCSymbol *, MCSymbol *>
+  Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
+};
+
+class MCDwarfDwoLineTable {
+  MCDwarfLineTableHeader Header;
+public:
+  void setCompilationDir(StringRef CompilationDir) {
+    Header.CompilationDir = CompilationDir;
+  }
+  unsigned getFile(StringRef Directory, StringRef FileName) {
+    return Header.getFile(Directory, FileName);
+  }
+  void Emit(MCStreamer &MCOS) const;
+};
+
+class MCDwarfLineTable {
+  MCDwarfLineTableHeader Header;
+  MCLineSection MCLineSections;
+
+public:
+  // This emits the Dwarf file and the line tables for all Compile Units.
+  static void Emit(MCObjectStreamer *MCOS);
+
+  // This emits the Dwarf file and the line tables for a given Compile Unit.
+  void EmitCU(MCObjectStreamer *MCOS) const;
+
+  unsigned getFile(StringRef &Directory, StringRef &FileName,
+                   unsigned FileNumber = 0);
+
+  MCSymbol *getLabel() const {
+    return Header.Label;
+  }
+
+  void setLabel(MCSymbol *Label) {
+    Header.Label = Label;
+  }
+
+  void setCompilationDir(StringRef CompilationDir) {
+    Header.CompilationDir = CompilationDir;
+  }
+
+  const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
+    return Header.MCDwarfDirs;
+  }
+
+  SmallVectorImpl<std::string> &getMCDwarfDirs() {
+    return Header.MCDwarfDirs;
+  }
+
+  const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
+    return Header.MCDwarfFiles;
+  }
+
+  SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
+    return Header.MCDwarfFiles;
+  }
+
+  const MCLineSection &getMCLineSections() const {
+    return MCLineSections;
+  }
+  MCLineSection &getMCLineSections() {
+    return MCLineSections;
+  }
+};
+
+class MCDwarfLineAddr {
+public:
+  /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
+  static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta,
+                     raw_ostream &OS);
+
+  /// Utility function to emit the encoding to a streamer.
+  static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta);
+};
+
+class MCGenDwarfInfo {
+public:
+  //
+  // When generating dwarf for assembly source files this emits the Dwarf
+  // sections.
+  //
+  static void Emit(MCStreamer *MCOS);
+};
+
+// When generating dwarf for assembly source files this is the info that is
+// needed to be gathered for each symbol that will have a dwarf label.
+class MCGenDwarfLabelEntry {
+private:
+  // Name of the symbol without a leading underbar, if any.
+  StringRef Name;
+  // The dwarf file number this symbol is in.
+  unsigned FileNumber;
+  // The line number this symbol is at.
+  unsigned LineNumber;
+  // The low_pc for the dwarf label is taken from this symbol.
+  MCSymbol *Label;
+
+public:
+  MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
+                       MCSymbol *label)
+      : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
+        Label(label) {}
+
+  StringRef getName() const { return Name; }
+  unsigned getFileNumber() const { return FileNumber; }
+  unsigned getLineNumber() const { return LineNumber; }
+  MCSymbol *getLabel() const { return Label; }
+
+  // This is called when label is created when we are generating dwarf for
+  // assembly source files.
+  static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
+                   SMLoc &Loc);
+};
+
+class MCCFIInstruction {
+public:
+  enum OpType {
+    OpSameValue,
+    OpRememberState,
+    OpRestoreState,
+    OpOffset,
+    OpDefCfaRegister,
+    OpDefCfaOffset,
+    OpDefCfa,
+    OpRelOffset,
+    OpAdjustCfaOffset,
+    OpEscape,
+    OpRestore,
+    OpUndefined,
+    OpRegister,
+    OpWindowSave
+  };
+
+private:
+  OpType Operation;
+  MCSymbol *Label;
+  unsigned Register;
+  union {
+    int Offset;
+    unsigned Register2;
+  };
+  std::vector<char> Values;
+
+  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
+      : Operation(Op), Label(L), Register(R), Offset(O),
+        Values(V.begin(), V.end()) {
+    assert(Op != OpRegister);
+  }
+
+  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
+      : Operation(Op), Label(L), Register(R1), Register2(R2) {
+    assert(Op == OpRegister);
+  }
+
+public:
+  /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from
+  /// Register and add Offset to it.
+  static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
+                                       int Offset) {
+    return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
+  }
+
+  /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now
+  /// on Register will be used instead of the old one. Offset remains the same.
+  static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
+    return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
+  }
+
+  /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register
+  /// remains the same, but offset is new. Note that it is the absolute offset
+  /// that will be added to a defined register to the compute CFA address.
+  static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
+    return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
+  }
+
+  /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
+  /// Offset is a relative value that is added/subtracted from the previous
+  /// offset.
+  static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
+    return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
+  }
+
+  /// \brief .cfi_offset Previous value of Register is saved at offset Offset
+  /// from CFA.
+  static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
+                                       int Offset) {
+    return MCCFIInstruction(OpOffset, L, Register, Offset, "");
+  }
+
+  /// \brief .cfi_rel_offset Previous value of Register is saved at offset
+  /// Offset from the current CFA register. This is transformed to .cfi_offset
+  /// using the known displacement of the CFA register from the CFA.
+  static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
+                                          int Offset) {
+    return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
+  }
+
+  /// \brief .cfi_register Previous value of Register1 is saved in
+  /// register Register2.
+  static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
+                                         unsigned Register2) {
+    return MCCFIInstruction(OpRegister, L, Register1, Register2);
+  }
+
+  /// \brief .cfi_window_save SPARC register window is saved.
+  static MCCFIInstruction createWindowSave(MCSymbol *L) {
+    return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
+  }
+
+  /// \brief .cfi_restore says that the rule for Register is now the same as it
+  /// was at the beginning of the function, after all initial instructions added
+  /// by .cfi_startproc were executed.
+  static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
+    return MCCFIInstruction(OpRestore, L, Register, 0, "");
+  }
+
+  /// \brief .cfi_undefined From now on the previous value of Register can't be
+  /// restored anymore.
+  static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
+    return MCCFIInstruction(OpUndefined, L, Register, 0, "");
+  }
+
+  /// \brief .cfi_same_value Current value of Register is the same as in the
+  /// previous frame. I.e., no restoration is needed.
+  static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
+    return MCCFIInstruction(OpSameValue, L, Register, 0, "");
+  }
+
+  /// \brief .cfi_remember_state Save all current rules for all registers.
+  static MCCFIInstruction createRememberState(MCSymbol *L) {
+    return MCCFIInstruction(OpRememberState, L, 0, 0, "");
+  }
+
+  /// \brief .cfi_restore_state Restore the previously saved state.
+  static MCCFIInstruction createRestoreState(MCSymbol *L) {
+    return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
+  }
+
+  /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind
+  /// info.
+  static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
+    return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
+  }
+
+  OpType getOperation() const { return Operation; }
+  MCSymbol *getLabel() const { return Label; }
+
+  unsigned getRegister() const {
+    assert(Operation == OpDefCfa || Operation == OpOffset ||
+           Operation == OpRestore || Operation == OpUndefined ||
+           Operation == OpSameValue || Operation == OpDefCfaRegister ||
+           Operation == OpRelOffset || Operation == OpRegister);
+    return Register;
+  }
+
+  unsigned getRegister2() const {
+    assert(Operation == OpRegister);
+    return Register2;
+  }
+
+  int getOffset() const {
+    assert(Operation == OpDefCfa || Operation == OpOffset ||
+           Operation == OpRelOffset || Operation == OpDefCfaOffset ||
+           Operation == OpAdjustCfaOffset);
+    return Offset;
+  }
+
+  const StringRef getValues() const {
+    assert(Operation == OpEscape);
+    return StringRef(&Values[0], Values.size());
+  }
+};
+
+struct MCDwarfFrameInfo {
+  MCDwarfFrameInfo()
+      : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
+        Instructions(), PersonalityEncoding(), LsdaEncoding(0),
+        CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {}
+  MCSymbol *Begin;
+  MCSymbol *End;
+  const MCSymbol *Personality;
+  const MCSymbol *Lsda;
+  std::vector<MCCFIInstruction> Instructions;
+  unsigned PersonalityEncoding;
+  unsigned LsdaEncoding;
+  uint32_t CompactUnwindEncoding;
+  bool IsSignalFrame;
+  bool IsSimple;
+};
+
+class MCDwarfFrameEmitter {
+public:
+  //
+  // This emits the frame info section.
+  //
+  static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
+  static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
+  static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
+                               raw_ostream &OS);
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
new file mode 100644
index 0000000..294a51b
--- /dev/null
+++ b/include/llvm/MC/MCELF.h
@@ -0,0 +1,37 @@
+//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some support functions used by the ELF Streamer and
+// ObjectWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELF_H
+#define LLVM_MC_MCELF_H
+
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+class MCSymbolData;
+
+class MCELF {
+ public:
+  static void SetBinding(MCSymbolData &SD, unsigned Binding);
+  static unsigned GetBinding(const MCSymbolData &SD);
+  static void SetType(MCSymbolData &SD, unsigned Type);
+  static unsigned GetType(const MCSymbolData &SD);
+  static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
+  static unsigned GetVisibility(const MCSymbolData &SD);
+  static void setOther(MCSymbolData &SD, unsigned Other);
+  static unsigned getOther(const MCSymbolData &SD);
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
new file mode 100644
index 0000000..421e7a0
--- /dev/null
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -0,0 +1,119 @@
+//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFOBJECTWRITER_H
+#define LLVM_MC_MCELFOBJECTWRITER_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ELF.h"
+#include <vector>
+
+namespace llvm {
+class MCAssembler;
+class MCFixup;
+class MCFragment;
+class MCObjectWriter;
+class MCSectionData;
+class MCSymbol;
+class MCSymbolData;
+class MCValue;
+
+class MCELFObjectTargetWriter {
+  const uint8_t OSABI;
+  const uint16_t EMachine;
+  const unsigned HasRelocationAddend : 1;
+  const unsigned Is64Bit : 1;
+  const unsigned IsN64 : 1;
+
+protected:
+
+  MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
+                          uint16_t EMachine_,  bool HasRelocationAddend,
+                          bool IsN64=false);
+
+public:
+  static uint8_t getOSABI(Triple::OSType OSType) {
+    switch (OSType) {
+      case Triple::FreeBSD:
+        return ELF::ELFOSABI_FREEBSD;
+      case Triple::Linux:
+        return ELF::ELFOSABI_LINUX;
+      default:
+        return ELF::ELFOSABI_NONE;
+    }
+  }
+
+  virtual ~MCELFObjectTargetWriter() {}
+
+  virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                bool IsPCRel) const = 0;
+
+  virtual bool needsRelocateWithSymbol(const MCSymbolData &SD,
+                                       unsigned Type) const;
+
+  /// @name Accessors
+  /// @{
+  uint8_t getOSABI() const { return OSABI; }
+  uint16_t getEMachine() const { return EMachine; }
+  bool hasRelocationAddend() const { return HasRelocationAddend; }
+  bool is64Bit() const { return Is64Bit; }
+  bool isN64() const { return IsN64; }
+  /// @}
+
+  // Instead of changing everyone's API we pack the N64 Type fields
+  // into the existing 32 bit data unsigned.
+#define R_TYPE_SHIFT 0
+#define R_TYPE_MASK 0xffffff00
+#define R_TYPE2_SHIFT 8
+#define R_TYPE2_MASK 0xffff00ff
+#define R_TYPE3_SHIFT 16
+#define R_TYPE3_MASK 0xff00ffff
+#define R_SSYM_SHIFT 24
+#define R_SSYM_MASK 0x00ffffff
+
+  // N64 relocation type accessors
+  uint8_t getRType(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
+  }
+  uint8_t getRType2(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
+  }
+  uint8_t getRType3(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
+  }
+  uint8_t getRSsym(uint32_t Type) const {
+    return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
+  }
+
+  // N64 relocation type setting
+  unsigned setRType(unsigned Value, unsigned Type) const {
+    return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
+  }
+  unsigned setRType2(unsigned Value, unsigned Type) const {
+    return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
+  }
+  unsigned setRType3(unsigned Value, unsigned Type) const {
+    return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
+  }
+  unsigned setRSsym(unsigned Value, unsigned Type) const {
+    return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
+  }
+};
+
+/// \brief Construct a new ELF writer instance.
+///
+/// \param MOTW - The target specific ELF writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+                                      raw_ostream &OS, bool IsLittleEndian);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
new file mode 100644
index 0000000..66729fe
--- /dev/null
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -0,0 +1,115 @@
+//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSTREAMER_H
+#define LLVM_MC_MCELFSTREAMER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+class MCAsmBackend;
+class MCAssembler;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class MCSymbol;
+class MCSymbolData;
+class raw_ostream;
+
+class MCELFStreamer : public MCObjectStreamer {
+public:
+  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+                MCCodeEmitter *Emitter)
+      : MCObjectStreamer(Context, TAB, OS, Emitter),
+        SeenIdent(false) {}
+
+  MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+                MCCodeEmitter *Emitter, MCAssembler *Assembler)
+      : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
+        SeenIdent(false) {}
+
+  virtual ~MCELFStreamer();
+
+  /// @name MCStreamer Interface
+  /// @{
+
+  void InitSections() override;
+  void ChangeSection(const MCSection *Section,
+                     const MCExpr *Subsection) override;
+  void EmitLabel(MCSymbol *Symbol) override;
+  void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+  void EmitThumbFunc(MCSymbol *Func) override;
+  void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+  bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+  void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+  void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                        unsigned ByteAlignment) override;
+  void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
+  void EmitCOFFSymbolStorageClass(int StorageClass) override;
+  void EmitCOFFSymbolType(int Type) override;
+  void EndCOFFSymbolDef() override;
+
+  void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+
+  void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                             unsigned ByteAlignment) override;
+
+  void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
+                    uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+  void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+                      uint64_t Size, unsigned ByteAlignment = 0) override;
+  void EmitValueImpl(const MCExpr *Value, unsigned Size,
+                     const SMLoc &Loc = SMLoc()) override;
+
+  void EmitFileDirective(StringRef Filename) override;
+
+  void EmitIdent(StringRef IdentString) override;
+
+  void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+
+  void Flush() override;
+
+  void FinishImpl() override;
+
+  void EmitBundleAlignMode(unsigned AlignPow2) override;
+  void EmitBundleLock(bool AlignToEnd) override;
+  void EmitBundleUnlock() override;
+
+private:
+  void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+  void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+
+  void fixSymbolsInTLSFixups(const MCExpr *expr);
+
+  bool SeenIdent;
+
+  struct LocalCommon {
+    MCSymbolData *SD;
+    uint64_t Size;
+    unsigned ByteAlignment;
+  };
+
+  std::vector<LocalCommon> LocalCommons;
+
+  SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+};
+
+MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+                                    raw_ostream &OS, MCCodeEmitter *Emitter,
+                                    bool RelaxAll, bool NoExecStack,
+                                    bool IsThumb);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h
new file mode 100644
index 0000000..297c442
--- /dev/null
+++ b/include/llvm/MC/MCELFSymbolFlags.h
@@ -0,0 +1,56 @@
+//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- 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 SymbolFlags used for the ELF target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H
+#define LLVM_MC_MCELFSYMBOLFLAGS_H
+
+#include "llvm/Support/ELF.h"
+
+// Because all the symbol flags need to be stored in the MCSymbolData
+// 'flags' variable we need to provide shift constants per flag type.
+
+namespace llvm {
+  enum {
+    ELF_STT_Shift   = 0,  // Shift value for STT_* flags.
+    ELF_STB_Shift   = 4,  // Shift value for STB_* flags.
+    ELF_STV_Shift   = 8,  // Shift value for STV_* flags.
+    ELF_STO_Shift   = 10  // Shift value for STO_* flags.
+  };
+
+  enum ELFSymbolFlags {
+    ELF_STB_Local     = (ELF::STB_LOCAL     << ELF_STB_Shift),
+      ELF_STB_Global    = (ELF::STB_GLOBAL    << ELF_STB_Shift),
+      ELF_STB_Weak      = (ELF::STB_WEAK      << ELF_STB_Shift),
+      ELF_STB_Loproc    = (ELF::STB_LOPROC    << ELF_STB_Shift),
+      ELF_STB_Hiproc    = (ELF::STB_HIPROC    << ELF_STB_Shift),
+
+      ELF_STT_Notype    = (ELF::STT_NOTYPE    << ELF_STT_Shift),
+      ELF_STT_Object    = (ELF::STT_OBJECT    << ELF_STT_Shift),
+      ELF_STT_Func      = (ELF::STT_FUNC      << ELF_STT_Shift),
+      ELF_STT_Section   = (ELF::STT_SECTION   << ELF_STT_Shift),
+      ELF_STT_File      = (ELF::STT_FILE      << ELF_STT_Shift),
+      ELF_STT_Common    = (ELF::STT_COMMON    << ELF_STT_Shift),
+      ELF_STT_Tls       = (ELF::STT_TLS       << ELF_STT_Shift),
+      ELF_STT_GnuIFunc  = (ELF::STT_GNU_IFUNC << ELF_STT_Shift),
+      ELF_STT_Loproc    = (ELF::STT_LOPROC    << ELF_STT_Shift),
+      ELF_STT_Hiproc    = (ELF::STT_HIPROC    << ELF_STT_Shift),
+
+      ELF_STV_Default   = (ELF::STV_DEFAULT   << ELF_STV_Shift),
+      ELF_STV_Internal  = (ELF::STV_INTERNAL  << ELF_STV_Shift),
+      ELF_STV_Hidden    = (ELF::STV_HIDDEN    << ELF_STV_Shift),
+      ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift)
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
new file mode 100644
index 0000000..e96ecb4
--- /dev/null
+++ b/include/llvm/MC/MCExpr.h
@@ -0,0 +1,540 @@
+//===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCEXPR_H
+#define LLVM_MC_MCEXPR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCAsmInfo;
+class MCAsmLayout;
+class MCAssembler;
+class MCContext;
+class MCSection;
+class MCSectionData;
+class MCStreamer;
+class MCSymbol;
+class MCValue;
+class raw_ostream;
+class StringRef;
+typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
+
+/// MCExpr - Base class for the full range of assembler expressions which are
+/// needed for parsing.
+class MCExpr {
+public:
+  enum ExprKind {
+    Binary,    ///< Binary expressions.
+    Constant,  ///< Constant expressions.
+    SymbolRef, ///< References to labels and assigned expressions.
+    Unary,     ///< Unary expressions.
+    Target     ///< Target specific expression.
+  };
+
+private:
+  ExprKind Kind;
+
+  MCExpr(const MCExpr&) LLVM_DELETED_FUNCTION;
+  void operator=(const MCExpr&) LLVM_DELETED_FUNCTION;
+
+  bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+                          const MCAsmLayout *Layout,
+                          const SectionAddrMap *Addrs) const;
+protected:
+  explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+
+  bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+                                 const MCAsmLayout *Layout,
+                                 const SectionAddrMap *Addrs, bool InSet,
+                                 bool ForceVarExpansion) const;
+
+public:
+  /// @name Accessors
+  /// @{
+
+  ExprKind getKind() const { return Kind; }
+
+  /// @}
+  /// @name Utility Methods
+  /// @{
+
+  void print(raw_ostream &OS) const;
+  void dump() const;
+
+  /// @}
+  /// @name Expression Evaluation
+  /// @{
+
+  /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
+  ///
+  /// @param Res - The absolute value, if evaluation succeeds.
+  /// @param Layout - The assembler layout object to use for evaluating symbol
+  /// values. If not given, then only non-symbolic expressions will be
+  /// evaluated.
+  /// @result - True on success.
+  bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
+                          const SectionAddrMap &Addrs) const;
+  bool EvaluateAsAbsolute(int64_t &Res) const;
+  bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
+  bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+
+  /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
+  /// value, i.e. an expression of the fixed form (a - b + constant).
+  ///
+  /// @param Res - The relocatable value, if evaluation succeeds.
+  /// @param Layout - The assembler layout object to use for evaluating values.
+  /// @result - True on success.
+  bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const;
+
+  /// \brief Try to evaluate the expression to the form (a - b + constant) where
+  /// neither a nor b are variables.
+  ///
+  /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
+  /// use is for when relocations are not available, like the symbol value in
+  /// the symbol table.
+  bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const;
+
+  /// FindAssociatedSection - Find the "associated section" for this expression,
+  /// which is currently defined as the absolute section for constants, or
+  /// otherwise the section associated with the first defined symbol in the
+  /// expression.
+  const MCSection *FindAssociatedSection() const;
+
+  /// @}
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
+  E.print(OS);
+  return OS;
+}
+
+//// MCConstantExpr - Represent a constant integer expression.
+class MCConstantExpr : public MCExpr {
+  int64_t Value;
+
+  explicit MCConstantExpr(int64_t _Value)
+    : MCExpr(MCExpr::Constant), Value(_Value) {}
+
+public:
+  /// @name Construction
+  /// @{
+
+  static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
+
+  /// @}
+  /// @name Accessors
+  /// @{
+
+  int64_t getValue() const { return Value; }
+
+  /// @}
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::Constant;
+  }
+};
+
+/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
+/// expression.
+///
+/// A symbol reference in an expression may be a use of a label, a use of an
+/// assembler variable (defined constant), or constitute an implicit definition
+/// of the symbol as external.
+class MCSymbolRefExpr : public MCExpr {
+public:
+  enum VariantKind {
+    VK_None,
+    VK_Invalid,
+
+    VK_GOT,
+    VK_GOTOFF,
+    VK_GOTPCREL,
+    VK_GOTTPOFF,
+    VK_INDNTPOFF,
+    VK_NTPOFF,
+    VK_GOTNTPOFF,
+    VK_PLT,
+    VK_TLSGD,
+    VK_TLSLD,
+    VK_TLSLDM,
+    VK_TPOFF,
+    VK_DTPOFF,
+    VK_TLVP,      // Mach-O thread local variable relocations
+    VK_TLVPPAGE,
+    VK_TLVPPAGEOFF,
+    VK_PAGE,
+    VK_PAGEOFF,
+    VK_GOTPAGE,
+    VK_GOTPAGEOFF,
+    VK_SECREL,
+    VK_WEAKREF,   // The link between the symbols in .weakref foo, bar
+
+    VK_ARM_NONE,
+    VK_ARM_TARGET1,
+    VK_ARM_TARGET2,
+    VK_ARM_PREL31,
+    VK_ARM_TLSLDO,         // symbol(tlsldo)
+    VK_ARM_TLSCALL,        // symbol(tlscall)
+    VK_ARM_TLSDESC,        // symbol(tlsdesc)
+    VK_ARM_TLSDESCSEQ,
+
+    VK_PPC_LO,             // symbol@l
+    VK_PPC_HI,             // symbol@h
+    VK_PPC_HA,             // symbol@ha
+    VK_PPC_HIGHER,         // symbol@higher
+    VK_PPC_HIGHERA,        // symbol@highera
+    VK_PPC_HIGHEST,        // symbol@highest
+    VK_PPC_HIGHESTA,       // symbol@highesta
+    VK_PPC_GOT_LO,         // symbol@got@l
+    VK_PPC_GOT_HI,         // symbol@got@h
+    VK_PPC_GOT_HA,         // symbol@got@ha
+    VK_PPC_TOCBASE,        // symbol@tocbase
+    VK_PPC_TOC,            // symbol@toc
+    VK_PPC_TOC_LO,         // symbol@toc@l
+    VK_PPC_TOC_HI,         // symbol@toc@h
+    VK_PPC_TOC_HA,         // symbol@toc@ha
+    VK_PPC_DTPMOD,         // symbol@dtpmod
+    VK_PPC_TPREL,          // symbol@tprel
+    VK_PPC_TPREL_LO,       // symbol@tprel@l
+    VK_PPC_TPREL_HI,       // symbol@tprel@h
+    VK_PPC_TPREL_HA,       // symbol@tprel@ha
+    VK_PPC_TPREL_HIGHER,   // symbol@tprel@higher
+    VK_PPC_TPREL_HIGHERA,  // symbol@tprel@highera
+    VK_PPC_TPREL_HIGHEST,  // symbol@tprel@highest
+    VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
+    VK_PPC_DTPREL,         // symbol@dtprel
+    VK_PPC_DTPREL_LO,      // symbol@dtprel@l
+    VK_PPC_DTPREL_HI,      // symbol@dtprel@h
+    VK_PPC_DTPREL_HA,      // symbol@dtprel@ha
+    VK_PPC_DTPREL_HIGHER,  // symbol@dtprel@higher
+    VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
+    VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
+    VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
+    VK_PPC_GOT_TPREL,      // symbol@got@tprel
+    VK_PPC_GOT_TPREL_LO,   // symbol@got@tprel@l
+    VK_PPC_GOT_TPREL_HI,   // symbol@got@tprel@h
+    VK_PPC_GOT_TPREL_HA,   // symbol@got@tprel@ha
+    VK_PPC_GOT_DTPREL,     // symbol@got@dtprel
+    VK_PPC_GOT_DTPREL_LO,  // symbol@got@dtprel@l
+    VK_PPC_GOT_DTPREL_HI,  // symbol@got@dtprel@h
+    VK_PPC_GOT_DTPREL_HA,  // symbol@got@dtprel@ha
+    VK_PPC_TLS,            // symbol@tls
+    VK_PPC_GOT_TLSGD,      // symbol@got@tlsgd
+    VK_PPC_GOT_TLSGD_LO,   // symbol@got@tlsgd@l
+    VK_PPC_GOT_TLSGD_HI,   // symbol@got@tlsgd@h
+    VK_PPC_GOT_TLSGD_HA,   // symbol@got@tlsgd@ha
+    VK_PPC_TLSGD,          // symbol@tlsgd
+    VK_PPC_GOT_TLSLD,      // symbol@got@tlsld
+    VK_PPC_GOT_TLSLD_LO,   // symbol@got@tlsld@l
+    VK_PPC_GOT_TLSLD_HI,   // symbol@got@tlsld@h
+    VK_PPC_GOT_TLSLD_HA,   // symbol@got@tlsld@ha
+    VK_PPC_TLSLD,          // symbol@tlsld
+
+    VK_Mips_GPREL,
+    VK_Mips_GOT_CALL,
+    VK_Mips_GOT16,
+    VK_Mips_GOT,
+    VK_Mips_ABS_HI,
+    VK_Mips_ABS_LO,
+    VK_Mips_TLSGD,
+    VK_Mips_TLSLDM,
+    VK_Mips_DTPREL_HI,
+    VK_Mips_DTPREL_LO,
+    VK_Mips_GOTTPREL,
+    VK_Mips_TPREL_HI,
+    VK_Mips_TPREL_LO,
+    VK_Mips_GPOFF_HI,
+    VK_Mips_GPOFF_LO,
+    VK_Mips_GOT_DISP,
+    VK_Mips_GOT_PAGE,
+    VK_Mips_GOT_OFST,
+    VK_Mips_HIGHER,
+    VK_Mips_HIGHEST,
+    VK_Mips_GOT_HI16,
+    VK_Mips_GOT_LO16,
+    VK_Mips_CALL_HI16,
+    VK_Mips_CALL_LO16,
+    VK_Mips_PCREL_HI16,
+    VK_Mips_PCREL_LO16,
+
+    VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
+  };
+
+private:
+  /// The symbol being referenced.
+  const MCSymbol *Symbol;
+
+  /// The symbol reference modifier.
+  const VariantKind Kind;
+
+  /// MCAsmInfo that is used to print symbol variants correctly.
+  const MCAsmInfo *MAI;
+
+  explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind,
+                           const MCAsmInfo *_MAI)
+    : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) {
+    assert(Symbol);
+    assert(MAI);
+  }
+
+public:
+  /// @name Construction
+  /// @{
+
+  static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
+    return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
+  }
+
+  static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
+                                       MCContext &Ctx);
+  static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
+                                       MCContext &Ctx);
+
+  /// @}
+  /// @name Accessors
+  /// @{
+
+  const MCSymbol &getSymbol() const { return *Symbol; }
+  const MCAsmInfo &getMCAsmInfo() const { return *MAI; }
+
+  VariantKind getKind() const { return Kind; }
+
+  /// @}
+  /// @name Static Utility Functions
+  /// @{
+
+  static StringRef getVariantKindName(VariantKind Kind);
+
+  static VariantKind getVariantKindForName(StringRef Name);
+
+  /// @}
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::SymbolRef;
+  }
+};
+
+/// MCUnaryExpr - Unary assembler expressions.
+class MCUnaryExpr : public MCExpr {
+public:
+  enum Opcode {
+    LNot,  ///< Logical negation.
+    Minus, ///< Unary minus.
+    Not,   ///< Bitwise negation.
+    Plus   ///< Unary plus.
+  };
+
+private:
+  Opcode Op;
+  const MCExpr *Expr;
+
+  MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
+    : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
+
+public:
+  /// @name Construction
+  /// @{
+
+  static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
+                                   MCContext &Ctx);
+  static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
+    return Create(LNot, Expr, Ctx);
+  }
+  static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
+    return Create(Minus, Expr, Ctx);
+  }
+  static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
+    return Create(Not, Expr, Ctx);
+  }
+  static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
+    return Create(Plus, Expr, Ctx);
+  }
+
+  /// @}
+  /// @name Accessors
+  /// @{
+
+  /// getOpcode - Get the kind of this unary expression.
+  Opcode getOpcode() const { return Op; }
+
+  /// getSubExpr - Get the child of this unary expression.
+  const MCExpr *getSubExpr() const { return Expr; }
+
+  /// @}
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::Unary;
+  }
+};
+
+/// MCBinaryExpr - Binary assembler expressions.
+class MCBinaryExpr : public MCExpr {
+public:
+  enum Opcode {
+    Add,  ///< Addition.
+    And,  ///< Bitwise and.
+    Div,  ///< Signed division.
+    EQ,   ///< Equality comparison.
+    GT,   ///< Signed greater than comparison (result is either 0 or some
+          ///< target-specific non-zero value)
+    GTE,  ///< Signed greater than or equal comparison (result is either 0 or
+          ///< some target-specific non-zero value).
+    LAnd, ///< Logical and.
+    LOr,  ///< Logical or.
+    LT,   ///< Signed less than comparison (result is either 0 or
+          ///< some target-specific non-zero value).
+    LTE,  ///< Signed less than or equal comparison (result is either 0 or
+          ///< some target-specific non-zero value).
+    Mod,  ///< Signed remainder.
+    Mul,  ///< Multiplication.
+    NE,   ///< Inequality comparison.
+    Or,   ///< Bitwise or.
+    Shl,  ///< Shift left.
+    Shr,  ///< Shift right (arithmetic or logical, depending on target)
+    Sub,  ///< Subtraction.
+    Xor   ///< Bitwise exclusive or.
+  };
+
+private:
+  Opcode Op;
+  const MCExpr *LHS, *RHS;
+
+  MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
+    : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
+
+public:
+  /// @name Construction
+  /// @{
+
+  static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
+                                    const MCExpr *RHS, MCContext &Ctx);
+  static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Add, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(And, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Div, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
+                                      MCContext &Ctx) {
+    return Create(EQ, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
+                                      MCContext &Ctx) {
+    return Create(GT, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(GTE, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
+                                        MCContext &Ctx) {
+    return Create(LAnd, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(LOr, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
+                                      MCContext &Ctx) {
+    return Create(LT, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(LTE, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Mod, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Mul, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
+                                      MCContext &Ctx) {
+    return Create(NE, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
+                                      MCContext &Ctx) {
+    return Create(Or, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Shl, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Shr, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Sub, LHS, RHS, Ctx);
+  }
+  static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
+                                       MCContext &Ctx) {
+    return Create(Xor, LHS, RHS, Ctx);
+  }
+
+  /// @}
+  /// @name Accessors
+  /// @{
+
+  /// getOpcode - Get the kind of this binary expression.
+  Opcode getOpcode() const { return Op; }
+
+  /// getLHS - Get the left-hand side expression of the binary operator.
+  const MCExpr *getLHS() const { return LHS; }
+
+  /// getRHS - Get the right-hand side expression of the binary operator.
+  const MCExpr *getRHS() const { return RHS; }
+
+  /// @}
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::Binary;
+  }
+};
+
+/// MCTargetExpr - This is an extension point for target-specific MCExpr
+/// subclasses to implement.
+///
+/// NOTE: All subclasses are required to have trivial destructors because
+/// MCExprs are bump pointer allocated and not destructed.
+class MCTargetExpr : public MCExpr {
+  virtual void anchor();
+protected:
+  MCTargetExpr() : MCExpr(Target) {}
+  virtual ~MCTargetExpr() {}
+public:
+
+  virtual void PrintImpl(raw_ostream &OS) const = 0;
+  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
+                                         const MCAsmLayout *Layout) const = 0;
+  virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
+  virtual const MCSection *FindAssociatedSection() const = 0;
+
+  virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
+
+  static bool classof(const MCExpr *E) {
+    return E->getKind() == MCExpr::Target;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h
new file mode 100644
index 0000000..2c7d237
--- /dev/null
+++ b/include/llvm/MC/MCExternalSymbolizer.h
@@ -0,0 +1,58 @@
+//===-- llvm/MC/MCExternalSymbolizer.h - ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCExternalSymbolizer class, which
+// enables library users to provide callbacks (through the C API) to do the
+// symbolization externally.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCEXTERNALSYMBOLIZER_H
+#define LLVM_MC_MCEXTERNALSYMBOLIZER_H
+
+#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCSymbolizer.h"
+#include <memory>
+
+namespace llvm {
+
+/// \brief Symbolize using user-provided, C API, callbacks.
+///
+/// See llvm-c/Disassembler.h.
+class MCExternalSymbolizer : public MCSymbolizer {
+protected:
+  /// \name Hooks for symbolic disassembly via the public 'C' interface.
+  /// @{
+  /// The function to get the symbolic information for operands.
+  LLVMOpInfoCallback GetOpInfo;
+  /// The function to lookup a symbol name.
+  LLVMSymbolLookupCallback SymbolLookUp;
+  /// The pointer to the block of symbolic information for above call back.
+  void *DisInfo;
+  /// @}
+
+public:
+  MCExternalSymbolizer(MCContext &Ctx,
+                       std::unique_ptr<MCRelocationInfo> RelInfo,
+                       LLVMOpInfoCallback getOpInfo,
+                       LLVMSymbolLookupCallback symbolLookUp, void *disInfo)
+    : MCSymbolizer(Ctx, std::move(RelInfo)), GetOpInfo(getOpInfo),
+      SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
+
+  bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream,
+                                int64_t Value, uint64_t Address, bool IsBranch,
+                                uint64_t Offset, uint64_t InstSize) override;
+  void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream,
+                                       int64_t Value,
+                                       uint64_t Address) override;
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCFixedLenDisassembler.h b/include/llvm/MC/MCFixedLenDisassembler.h
new file mode 100644
index 0000000..ad99943
--- /dev/null
+++ b/include/llvm/MC/MCFixedLenDisassembler.h
@@ -0,0 +1,32 @@
+//===-- llvm/MC/MCFixedLenDisassembler.h - Decoder driver -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Fixed length disassembler decoder state machine driver.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+
+namespace llvm {
+
+namespace MCD {
+// Disassembler state machine opcodes.
+enum DecoderOps {
+  OPC_ExtractField = 1, // OPC_ExtractField(uint8_t Start, uint8_t Len)
+  OPC_FilterValue,      // OPC_FilterValue(uleb128 Val, uint16_t NumToSkip)
+  OPC_CheckField,       // OPC_CheckField(uint8_t Start, uint8_t Len,
+                        //                uleb128 Val, uint16_t NumToSkip)
+  OPC_CheckPredicate,   // OPC_CheckPredicate(uleb128 PIdx, uint16_t NumToSkip)
+  OPC_Decode,           // OPC_Decode(uleb128 Opcode, uleb128 DIdx)
+  OPC_SoftFail,         // OPC_SoftFail(uleb128 PMask, uleb128 NMask)
+  OPC_Fail              // OPC_Fail()
+};
+
+} // namespace MCDecode
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
new file mode 100644
index 0000000..98a1419
--- /dev/null
+++ b/include/llvm/MC/MCFixup.h
@@ -0,0 +1,113 @@
+//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUP_H
+#define LLVM_MC_MCFIXUP_H
+
+#include "llvm/MC/MCExpr.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+
+namespace llvm {
+class MCExpr;
+
+/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
+enum MCFixupKind {
+  FK_Data_1 = 0, ///< A one-byte fixup.
+  FK_Data_2,     ///< A two-byte fixup.
+  FK_Data_4,     ///< A four-byte fixup.
+  FK_Data_8,     ///< A eight-byte fixup.
+  FK_PCRel_1,    ///< A one-byte pc relative fixup.
+  FK_PCRel_2,    ///< A two-byte pc relative fixup.
+  FK_PCRel_4,    ///< A four-byte pc relative fixup.
+  FK_PCRel_8,    ///< A eight-byte pc relative fixup.
+  FK_GPRel_1,    ///< A one-byte gp relative fixup.
+  FK_GPRel_2,    ///< A two-byte gp relative fixup.
+  FK_GPRel_4,    ///< A four-byte gp relative fixup.
+  FK_GPRel_8,    ///< A eight-byte gp relative fixup.
+  FK_SecRel_1,   ///< A one-byte section relative fixup.
+  FK_SecRel_2,   ///< A two-byte section relative fixup.
+  FK_SecRel_4,   ///< A four-byte section relative fixup.
+  FK_SecRel_8,   ///< A eight-byte section relative fixup.
+
+  FirstTargetFixupKind = 128,
+
+  // Limit range of target fixups, in case we want to pack more efficiently
+  // later.
+  MaxTargetFixupKind = (1 << 8)
+};
+
+/// MCFixup - Encode information on a single operation to perform on a byte
+/// sequence (e.g., an encoded instruction) which requires assemble- or run-
+/// time patching.
+///
+/// Fixups are used any time the target instruction encoder needs to represent
+/// some value in an instruction which is not yet concrete. The encoder will
+/// encode the instruction assuming the value is 0, and emit a fixup which
+/// communicates to the assembler backend how it should rewrite the encoded
+/// value.
+///
+/// During the process of relaxation, the assembler will apply fixups as
+/// symbolic values become concrete. When relaxation is complete, any remaining
+/// fixups become relocations in the object file (or errors, if the fixup cannot
+/// be encoded on the target).
+class MCFixup {
+  /// The value to put into the fixup location. The exact interpretation of the
+  /// expression is target dependent, usually it will be one of the operands to
+  /// an instruction or an assembler directive.
+  const MCExpr *Value;
+
+  /// The byte index of start of the relocation inside the encoded instruction.
+  uint32_t Offset;
+
+  /// The target dependent kind of fixup item this is. The kind is used to
+  /// determine how the operand value should be encoded into the instruction.
+  unsigned Kind;
+
+  /// The source location which gave rise to the fixup, if any.
+  SMLoc Loc;
+public:
+  static MCFixup Create(uint32_t Offset, const MCExpr *Value,
+                        MCFixupKind Kind, SMLoc Loc = SMLoc()) {
+    assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
+    MCFixup FI;
+    FI.Value = Value;
+    FI.Offset = Offset;
+    FI.Kind = unsigned(Kind);
+    FI.Loc = Loc;
+    return FI;
+  }
+
+  MCFixupKind getKind() const { return MCFixupKind(Kind); }
+
+  uint32_t getOffset() const { return Offset; }
+  void setOffset(uint32_t Value) { Offset = Value; }
+
+  const MCExpr *getValue() const { return Value; }
+
+  /// getKindForSize - Return the generic fixup kind for a value with the given
+  /// size. It is an error to pass an unsupported size.
+  static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
+    switch (Size) {
+    default: llvm_unreachable("Invalid generic fixup size!");
+    case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
+    case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
+    case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
+    case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
+    }
+  }
+
+  SMLoc getLoc() const { return Loc; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCFixupKindInfo.h b/include/llvm/MC/MCFixupKindInfo.h
new file mode 100644
index 0000000..6979ad5
--- /dev/null
+++ b/include/llvm/MC/MCFixupKindInfo.h
@@ -0,0 +1,43 @@
+//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUPKINDINFO_H
+#define LLVM_MC_MCFIXUPKINDINFO_H
+
+namespace llvm {
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+  enum FixupKindFlags {
+    /// Is this fixup kind PCrelative? This is used by the assembler backend to
+    /// evaluate fixup values in a target independent manner when possible.
+    FKF_IsPCRel = (1 << 0),
+
+    /// Should this fixup kind force a 4-byte aligned effective PC value?
+    FKF_IsAlignedDownTo32Bits = (1 << 1)
+  };
+
+  /// A target specific name for the fixup kind. The names will be unique for
+  /// distinct kinds on any given target.
+  const char *Name;
+
+  /// The bit offset to write the relocation into.
+  unsigned TargetOffset;
+
+  /// The number of bits written by this fixup. The bits are assumed to be
+  /// contiguous.
+  unsigned TargetSize;
+
+  /// Flags describing additional information on this fixup kind.
+  unsigned Flags;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
new file mode 100644
index 0000000..6918280
--- /dev/null
+++ b/include/llvm/MC/MCInst.h
@@ -0,0 +1,204 @@
+//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCInst and MCOperand classes, which
+// is the basic representation used to represent low-level machine code
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINST_H
+#define LLVM_MC_MCINST_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class raw_ostream;
+class MCAsmInfo;
+class MCInstPrinter;
+class MCExpr;
+class MCInst;
+
+/// MCOperand - Instances of this class represent operands of the MCInst class.
+/// This is a simple discriminated union.
+class MCOperand {
+  enum MachineOperandType {
+    kInvalid,                 ///< Uninitialized.
+    kRegister,                ///< Register operand.
+    kImmediate,               ///< Immediate operand.
+    kFPImmediate,             ///< Floating-point immediate operand.
+    kExpr,                    ///< Relocatable immediate operand.
+    kInst                     ///< Sub-instruction operand.
+  };
+  unsigned char Kind;
+
+  union {
+    unsigned RegVal;
+    int64_t ImmVal;
+    double FPImmVal;
+    const MCExpr *ExprVal;
+    const MCInst *InstVal;
+  };
+public:
+
+  MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
+
+  bool isValid() const { return Kind != kInvalid; }
+  bool isReg() const { return Kind == kRegister; }
+  bool isImm() const { return Kind == kImmediate; }
+  bool isFPImm() const { return Kind == kFPImmediate; }
+  bool isExpr() const { return Kind == kExpr; }
+  bool isInst() const { return Kind == kInst; }
+
+  /// getReg - Returns the register number.
+  unsigned getReg() const {
+    assert(isReg() && "This is not a register operand!");
+    return RegVal;
+  }
+
+  /// setReg - Set the register number.
+  void setReg(unsigned Reg) {
+    assert(isReg() && "This is not a register operand!");
+    RegVal = Reg;
+  }
+
+  int64_t getImm() const {
+    assert(isImm() && "This is not an immediate");
+    return ImmVal;
+  }
+  void setImm(int64_t Val) {
+    assert(isImm() && "This is not an immediate");
+    ImmVal = Val;
+  }
+
+  double getFPImm() const {
+    assert(isFPImm() && "This is not an FP immediate");
+    return FPImmVal;
+  }
+
+  void setFPImm(double Val) {
+    assert(isFPImm() && "This is not an FP immediate");
+    FPImmVal = Val;
+  }
+
+  const MCExpr *getExpr() const {
+    assert(isExpr() && "This is not an expression");
+    return ExprVal;
+  }
+  void setExpr(const MCExpr *Val) {
+    assert(isExpr() && "This is not an expression");
+    ExprVal = Val;
+  }
+
+  const MCInst *getInst() const {
+    assert(isInst() && "This is not a sub-instruction");
+    return InstVal;
+  }
+  void setInst(const MCInst *Val) {
+    assert(isInst() && "This is not a sub-instruction");
+    InstVal = Val;
+  }
+
+  static MCOperand CreateReg(unsigned Reg) {
+    MCOperand Op;
+    Op.Kind = kRegister;
+    Op.RegVal = Reg;
+    return Op;
+  }
+  static MCOperand CreateImm(int64_t Val) {
+    MCOperand Op;
+    Op.Kind = kImmediate;
+    Op.ImmVal = Val;
+    return Op;
+  }
+  static MCOperand CreateFPImm(double Val) {
+    MCOperand Op;
+    Op.Kind = kFPImmediate;
+    Op.FPImmVal = Val;
+    return Op;
+  }
+  static MCOperand CreateExpr(const MCExpr *Val) {
+    MCOperand Op;
+    Op.Kind = kExpr;
+    Op.ExprVal = Val;
+    return Op;
+  }
+  static MCOperand CreateInst(const MCInst *Val) {
+    MCOperand Op;
+    Op.Kind = kInst;
+    Op.InstVal = Val;
+    return Op;
+  }
+
+  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+  void dump() const;
+};
+
+template <> struct isPodLike<MCOperand> { static const bool value = true; };
+
+/// MCInst - Instances of this class represent a single low-level machine
+/// instruction.
+class MCInst {
+  unsigned Opcode;
+  SMLoc Loc;
+  SmallVector<MCOperand, 8> Operands;
+public:
+  MCInst() : Opcode(0) {}
+
+  void setOpcode(unsigned Op) { Opcode = Op; }
+  unsigned getOpcode() const { return Opcode; }
+
+  void setLoc(SMLoc loc) { Loc = loc; }
+  SMLoc getLoc() const { return Loc; }
+
+  const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
+  MCOperand &getOperand(unsigned i) { return Operands[i]; }
+  unsigned getNumOperands() const { return Operands.size(); }
+
+  void addOperand(const MCOperand &Op) {
+    Operands.push_back(Op);
+  }
+
+  void clear() { Operands.clear(); }
+  size_t size() { return Operands.size(); }
+
+  typedef SmallVectorImpl<MCOperand>::iterator iterator;
+  iterator begin() { return Operands.begin(); }
+  iterator end()   { return Operands.end();   }
+  iterator insert(iterator I, const MCOperand &Op) {
+    return Operands.insert(I, Op);
+  }
+
+  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+  void dump() const;
+
+  /// \brief Dump the MCInst as prettily as possible using the additional MC
+  /// structures, if given. Operators are separated by the \p Separator
+  /// string.
+  void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = nullptr,
+                   const MCInstPrinter *Printer = nullptr,
+                   StringRef Separator = " ") const;
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
+  MO.print(OS, nullptr);
+  return OS;
+}
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
+  MI.print(OS, nullptr);
+  return OS;
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h
new file mode 100644
index 0000000..c5acb26
--- /dev/null
+++ b/include/llvm/MC/MCInstBuilder.h
@@ -0,0 +1,68 @@
+//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MCInstBuilder class for convenient creation of
+// MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTBUILDER_H
+#define LLVM_MC_MCINSTBUILDER_H
+
+#include "llvm/MC/MCInst.h"
+
+namespace llvm {
+
+class MCInstBuilder {
+  MCInst Inst;
+
+public:
+  /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode.
+  MCInstBuilder(unsigned Opcode) {
+    Inst.setOpcode(Opcode);
+  }
+
+  /// \brief Add a new register operand.
+  MCInstBuilder &addReg(unsigned Reg) {
+    Inst.addOperand(MCOperand::CreateReg(Reg));
+    return *this;
+  }
+
+  /// \brief Add a new integer immediate operand.
+  MCInstBuilder &addImm(int64_t Val) {
+    Inst.addOperand(MCOperand::CreateImm(Val));
+    return *this;
+  }
+
+  /// \brief Add a new floating point immediate operand.
+  MCInstBuilder &addFPImm(double Val) {
+    Inst.addOperand(MCOperand::CreateFPImm(Val));
+    return *this;
+  }
+
+  /// \brief Add a new MCExpr operand.
+  MCInstBuilder &addExpr(const MCExpr *Val) {
+    Inst.addOperand(MCOperand::CreateExpr(Val));
+    return *this;
+  }
+
+  /// \brief Add a new MCInst operand.
+  MCInstBuilder &addInst(const MCInst *Val) {
+    Inst.addOperand(MCOperand::CreateInst(Val));
+    return *this;
+  }
+
+  operator MCInst&() {
+    return Inst;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
new file mode 100644
index 0000000..7f55b29
--- /dev/null
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -0,0 +1,108 @@
+//===-- MCInstPrinter.h - Convert an MCInst to target assembly syntax -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTPRINTER_H
+#define LLVM_MC_MCINSTPRINTER_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Format.h"
+
+namespace llvm {
+class MCInst;
+class raw_ostream;
+class MCAsmInfo;
+class MCInstrInfo;
+class MCRegisterInfo;
+class StringRef;
+
+namespace HexStyle {
+    enum Style {
+        C,          ///< 0xff
+        Asm         ///< 0ffh
+    };
+}
+
+/// MCInstPrinter - This is an instance of a target assembly language printer
+/// that converts an MCInst to valid target assembly syntax.
+class MCInstPrinter {
+protected:
+  /// CommentStream - a stream that comments can be emitted to if desired.
+  /// Each comment must end with a newline.  This will be null if verbose
+  /// assembly emission is disable.
+  raw_ostream *CommentStream;
+  const MCAsmInfo &MAI;
+  const MCInstrInfo &MII;
+  const MCRegisterInfo &MRI;
+
+  /// The current set of available features.
+  uint64_t AvailableFeatures;
+
+  /// True if we are printing marked up assembly.
+  bool UseMarkup;
+
+  /// True if we are printing immediates as hex.
+  bool PrintImmHex;
+
+  /// Which style to use for printing hexadecimal values.
+  HexStyle::Style PrintHexStyle;
+
+  /// Utility function for printing annotations.
+  void printAnnotation(raw_ostream &OS, StringRef Annot);
+public:
+  MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
+                const MCRegisterInfo &mri)
+    : CommentStream(nullptr), MAI(mai), MII(mii), MRI(mri),
+      AvailableFeatures(0), UseMarkup(0), PrintImmHex(0),
+      PrintHexStyle(HexStyle::C) {}
+
+  virtual ~MCInstPrinter();
+
+  /// setCommentStream - Specify a stream to emit comments to.
+  void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
+
+  /// printInst - Print the specified MCInst to the specified raw_ostream.
+  ///
+  virtual void printInst(const MCInst *MI, raw_ostream &OS,
+                         StringRef Annot) = 0;
+
+  /// getOpcodeName - Return the name of the specified opcode enum (e.g.
+  /// "MOV32ri") or empty if we can't resolve it.
+  StringRef getOpcodeName(unsigned Opcode) const;
+
+  /// printRegName - Print the assembler register name.
+  virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
+
+  uint64_t getAvailableFeatures() const { return AvailableFeatures; }
+  void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; }
+
+  bool getUseMarkup() const { return UseMarkup; }
+  void setUseMarkup(bool Value) { UseMarkup = Value; }
+
+  /// Utility functions to make adding mark ups simpler.
+  StringRef markup(StringRef s) const;
+  StringRef markup(StringRef a, StringRef b) const;
+
+  bool getPrintImmHex() const { return PrintImmHex; }
+  void setPrintImmHex(bool Value) { PrintImmHex = Value; }
+
+  HexStyle::Style getPrintHexStyleHex() const { return PrintHexStyle; }
+  void setPrintImmHex(HexStyle::Style Value) { PrintHexStyle = Value; }
+
+  /// Utility function to print immediates in decimal or hex.
+  format_object1<int64_t> formatImm(const int64_t Value) const { return PrintImmHex ? formatHex(Value) : formatDec(Value); }
+
+  /// Utility functions to print decimal/hexadecimal values.
+  format_object1<int64_t> formatDec(const int64_t Value) const;
+  format_object1<int64_t> formatHex(const int64_t Value) const;
+  format_object1<uint64_t> formatHex(const uint64_t Value) const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h
new file mode 100644
index 0000000..e921f76
--- /dev/null
+++ b/include/llvm/MC/MCInstrAnalysis.h
@@ -0,0 +1,71 @@
+//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- 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 MCInstrAnalysis class which the MCTargetDescs can
+// derive from to give additional information to MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRANALYSIS_H
+#define LLVM_MC_MCINSTRANALYSIS_H
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+
+namespace llvm {
+
+class MCInstrAnalysis {
+protected:
+  friend class Target;
+  const MCInstrInfo *Info;
+
+public:
+  MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
+
+  virtual ~MCInstrAnalysis() {}
+
+  virtual bool isBranch(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isBranch();
+  }
+
+  virtual bool isConditionalBranch(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isConditionalBranch();
+  }
+
+  virtual bool isUnconditionalBranch(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isUnconditionalBranch();
+  }
+
+  virtual bool isIndirectBranch(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isIndirectBranch();
+  }
+
+  virtual bool isCall(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isCall();
+  }
+
+  virtual bool isReturn(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isReturn();
+  }
+
+  virtual bool isTerminator(const MCInst &Inst) const {
+    return Info->get(Inst.getOpcode()).isTerminator();
+  }
+
+  /// evaluateBranch - Given a branch instruction try to get the address the
+  /// branch targets. Return true on success, and the address in Target.
+  virtual bool
+  evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
+                 uint64_t &Target) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
new file mode 100644
index 0000000..5896de7
--- /dev/null
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -0,0 +1,595 @@
+//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- 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 MCOperandInfo and MCInstrDesc classes, which
+// are used to describe target instructions and their operands.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRDESC_H
+#define LLVM_MC_MCINSTRDESC_H
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Machine Operand Flags and Description
+//===----------------------------------------------------------------------===//
+
+namespace MCOI {
+  // Operand constraints
+  enum OperandConstraint {
+    TIED_TO = 0,    // Must be allocated the same register as.
+    EARLY_CLOBBER   // Operand is an early clobber register operand
+  };
+
+  /// OperandFlags - These are flags set on operands, but should be considered
+  /// private, all access should go through the MCOperandInfo accessors.
+  /// See the accessors for a description of what these are.
+  enum OperandFlags {
+    LookupPtrRegClass = 0,
+    Predicate,
+    OptionalDef
+  };
+
+  /// Operand Type - Operands are tagged with one of the values of this enum.
+  enum OperandType {
+    OPERAND_UNKNOWN,
+    OPERAND_IMMEDIATE,
+    OPERAND_REGISTER,
+    OPERAND_MEMORY,
+    OPERAND_PCREL
+  };
+}
+
+/// MCOperandInfo - This holds information about one operand of a machine
+/// instruction, indicating the register class for register operands, etc.
+///
+class MCOperandInfo {
+public:
+  /// RegClass - This specifies the register class enumeration of the operand
+  /// if the operand is a register.  If isLookupPtrRegClass is set, then this is
+  /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+  /// get a dynamic register class.
+  int16_t RegClass;
+
+  /// Flags - These are flags from the MCOI::OperandFlags enum.
+  uint8_t Flags;
+
+  /// OperandType - Information about the type of the operand.
+  uint8_t OperandType;
+
+  /// Lower 16 bits are used to specify which constraints are set. The higher 16
+  /// bits are used to specify the value of constraints (4 bits each).
+  uint32_t Constraints;
+  /// Currently no other information.
+
+  /// isLookupPtrRegClass - Set if this operand is a pointer value and it
+  /// requires a callback to look up its register class.
+  bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);}
+
+  /// isPredicate - Set if this is one of the operands that made up of
+  /// the predicate operand that controls an isPredicable() instruction.
+  bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
+
+  /// isOptionalDef - Set if this operand is a optional def.
+  ///
+  bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+/// MCInstrDesc flags - These should be considered private to the
+/// implementation of the MCInstrDesc class.  Clients should use the predicate
+/// methods on MCInstrDesc, not use these directly.  These all correspond to
+/// bitfields in the MCInstrDesc::Flags field.
+namespace MCID {
+  enum {
+    Variadic = 0,
+    HasOptionalDef,
+    Pseudo,
+    Return,
+    Call,
+    Barrier,
+    Terminator,
+    Branch,
+    IndirectBranch,
+    Compare,
+    MoveImm,
+    Bitcast,
+    Select,
+    DelaySlot,
+    FoldableAsLoad,
+    MayLoad,
+    MayStore,
+    Predicable,
+    NotDuplicable,
+    UnmodeledSideEffects,
+    Commutable,
+    ConvertibleTo3Addr,
+    UsesCustomInserter,
+    HasPostISelHook,
+    Rematerializable,
+    CheapAsAMove,
+    ExtraSrcRegAllocReq,
+    ExtraDefRegAllocReq
+  };
+}
+
+/// MCInstrDesc - Describe properties that are true of each instruction in the
+/// target description file.  This captures information about side effects,
+/// register use and many other things.  There is one instance of this struct
+/// for each target instruction class, and the MachineInstr class points to
+/// this struct directly to describe itself.
+class MCInstrDesc {
+public:
+  unsigned short  Opcode;        // The opcode number
+  unsigned short  NumOperands;   // Num of args (may be more if variable_ops)
+  unsigned short  NumDefs;       // Num of args that are definitions
+  unsigned short  SchedClass;    // enum identifying instr sched class
+  unsigned short  Size;          // Number of bytes in encoding.
+  unsigned        Flags;         // Flags identifying machine instr class
+  uint64_t        TSFlags;       // Target Specific Flag values
+  const uint16_t *ImplicitUses;  // Registers implicitly read by this instr
+  const uint16_t *ImplicitDefs;  // Registers implicitly defined by this instr
+  const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
+  uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any
+  // A complex method to determine is a certain is deprecated or not, and return
+  // the reason for deprecation.
+  bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
+
+  /// \brief Returns the value of the specific constraint if
+  /// it is set. Returns -1 if it is not set.
+  int getOperandConstraint(unsigned OpNum,
+                           MCOI::OperandConstraint Constraint) const {
+    if (OpNum < NumOperands &&
+        (OpInfo[OpNum].Constraints & (1 << Constraint))) {
+      unsigned Pos = 16 + Constraint * 4;
+      return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+    }
+    return -1;
+  }
+
+  /// \brief Returns true if a certain instruction is deprecated and if so
+  /// returns the reason in \p Info.
+  bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI,
+                         std::string &Info) const {
+    if (ComplexDeprecationInfo)
+      return ComplexDeprecationInfo(MI, STI, Info);
+    if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) {
+      // FIXME: it would be nice to include the subtarget feature here.
+      Info = "deprecated";
+      return true;
+    }
+    return false;
+  }
+
+  /// \brief Return the opcode number for this descriptor.
+  unsigned getOpcode() const {
+    return Opcode;
+  }
+
+  /// \brief Return the number of declared MachineOperands for this
+  /// MachineInstruction.  Note that variadic (isVariadic() returns true)
+  /// instructions may have additional operands at the end of the list, and note
+  /// that the machine instruction may include implicit register def/uses as
+  /// well.
+  unsigned getNumOperands() const {
+    return NumOperands;
+  }
+
+  /// \brief Return the number of MachineOperands that are register
+  /// definitions.  Register definitions always occur at the start of the
+  /// machine operand list.  This is the number of "outs" in the .td file,
+  /// and does not include implicit defs.
+  unsigned getNumDefs() const {
+    return NumDefs;
+  }
+
+  /// \brief Return flags of this instruction.
+  unsigned getFlags() const { return Flags; }
+
+  /// \brief Return true if this instruction can have a variable number of
+  /// operands.  In this case, the variable operands will be after the normal
+  /// operands but before the implicit definitions and uses (if any are
+  /// present).
+  bool isVariadic() const {
+    return Flags & (1 << MCID::Variadic);
+  }
+
+  /// \brief Set if this instruction has an optional definition, e.g.
+  /// ARM instructions which can set condition code if 's' bit is set.
+  bool hasOptionalDef() const {
+    return Flags & (1 << MCID::HasOptionalDef);
+  }
+
+  /// \brief Return true if this is a pseudo instruction that doesn't
+  /// correspond to a real machine instruction.
+  ///
+  bool isPseudo() const {
+    return Flags & (1 << MCID::Pseudo);
+  }
+
+  /// \brief Return true if the instruction is a return.
+  bool isReturn() const {
+    return Flags & (1 << MCID::Return);
+  }
+
+  /// \brief  Return true if the instruction is a call.
+  bool isCall() const {
+    return Flags & (1 << MCID::Call);
+  }
+
+  /// \brief Returns true if the specified instruction stops control flow
+  /// from executing the instruction immediately following it.  Examples include
+  /// unconditional branches and return instructions.
+  bool isBarrier() const {
+    return Flags & (1 << MCID::Barrier);
+  }
+
+  /// \brief Returns true if this instruction part of the terminator for
+  /// a basic block.  Typically this is things like return and branch
+  /// instructions.
+  ///
+  /// Various passes use this to insert code into the bottom of a basic block,
+  /// but before control flow occurs.
+  bool isTerminator() const {
+    return Flags & (1 << MCID::Terminator);
+  }
+
+  /// \brief Returns true if this is a conditional, unconditional, or
+  /// indirect branch.  Predicates below can be used to discriminate between
+  /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+  /// get more information.
+  bool isBranch() const {
+    return Flags & (1 << MCID::Branch);
+  }
+
+  /// \brief Return true if this is an indirect branch, such as a
+  /// branch through a register.
+  bool isIndirectBranch() const {
+    return Flags & (1 << MCID::IndirectBranch);
+  }
+
+  /// \brief Return true if this is a branch which may fall
+  /// through to the next instruction or may transfer control flow to some other
+  /// block.  The TargetInstrInfo::AnalyzeBranch method can be used to get more
+  /// information about this branch.
+  bool isConditionalBranch() const {
+    return isBranch() & !isBarrier() & !isIndirectBranch();
+  }
+
+  /// \brief Return true if this is a branch which always
+  /// transfers control flow to some other block.  The
+  /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+  /// about this branch.
+  bool isUnconditionalBranch() const {
+    return isBranch() & isBarrier() & !isIndirectBranch();
+  }
+
+  /// \brief Return true if this is a branch or an instruction which directly
+  /// writes to the program counter. Considered 'may' affect rather than
+  /// 'does' affect as things like predication are not taken into account.
+  bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
+    if (isBranch() || isCall() || isReturn() || isIndirectBranch())
+      return true;
+    unsigned PC = RI.getProgramCounter();
+    if (PC == 0)
+      return false;
+    if (hasDefOfPhysReg(MI, PC, RI))
+      return true;
+    // A variadic instruction may define PC in the variable operand list.
+    // There's currently no indication of which entries in a variable
+    // list are defs and which are uses. While that's the case, this function
+    // needs to assume they're defs in order to be conservatively correct.
+    for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
+      if (MI.getOperand(i).isReg() &&
+          RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
+        return true;
+    }
+    return false;
+  }
+
+  /// \brief Return true if this instruction has a predicate operand
+  /// that controls execution. It may be set to 'always', or may be set to other
+  /// values. There are various methods in TargetInstrInfo that can be used to
+  /// control and modify the predicate in this instruction.
+  bool isPredicable() const {
+    return Flags & (1 << MCID::Predicable);
+  }
+
+  /// \brief Return true if this instruction is a comparison.
+  bool isCompare() const {
+    return Flags & (1 << MCID::Compare);
+  }
+
+  /// \brief Return true if this instruction is a move immediate
+  /// (including conditional moves) instruction.
+  bool isMoveImmediate() const {
+    return Flags & (1 << MCID::MoveImm);
+  }
+
+  /// \brief Return true if this instruction is a bitcast instruction.
+  bool isBitcast() const {
+    return Flags & (1 << MCID::Bitcast);
+  }
+
+  /// \brief Return true if this is a select instruction.
+  bool isSelect() const {
+    return Flags & (1 << MCID::Select);
+  }
+
+  /// \brief Return true if this instruction cannot be safely
+  /// duplicated.  For example, if the instruction has a unique labels attached
+  /// to it, duplicating it would cause multiple definition errors.
+  bool isNotDuplicable() const {
+    return Flags & (1 << MCID::NotDuplicable);
+  }
+
+  /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+  /// which must be filled by the code generator.
+  bool hasDelaySlot() const {
+    return Flags & (1 << MCID::DelaySlot);
+  }
+
+  /// canFoldAsLoad - Return true for instructions that can be folded as
+  /// memory operands in other instructions. The most common use for this
+  /// is instructions that are simple loads from memory that don't modify
+  /// the loaded value in any way, but it can also be used for instructions
+  /// that can be expressed as constant-pool loads, such as V_SETALLONES
+  /// on x86, to allow them to be folded when it is beneficial.
+  /// This should only be set on instructions that return a value in their
+  /// only virtual register definition.
+  bool canFoldAsLoad() const {
+    return Flags & (1 << MCID::FoldableAsLoad);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Side Effect Analysis
+  //===--------------------------------------------------------------------===//
+
+  /// \brief Return true if this instruction could possibly read memory.
+  /// Instructions with this flag set are not necessarily simple load
+  /// instructions, they may load a value and modify it, for example.
+  bool mayLoad() const {
+    return Flags & (1 << MCID::MayLoad);
+  }
+
+
+  /// \brief Return true if this instruction could possibly modify memory.
+  /// Instructions with this flag set are not necessarily simple store
+  /// instructions, they may store a modified value based on their operands, or
+  /// may not actually modify anything, for example.
+  bool mayStore() const {
+    return Flags & (1 << MCID::MayStore);
+  }
+
+  /// hasUnmodeledSideEffects - Return true if this instruction has side
+  /// effects that are not modeled by other flags.  This does not return true
+  /// for instructions whose effects are captured by:
+  ///
+  ///  1. Their operand list and implicit definition/use list.  Register use/def
+  ///     info is explicit for instructions.
+  ///  2. Memory accesses.  Use mayLoad/mayStore.
+  ///  3. Calling, branching, returning: use isCall/isReturn/isBranch.
+  ///
+  /// Examples of side effects would be modifying 'invisible' machine state like
+  /// a control register, flushing a cache, modifying a register invisible to
+  /// LLVM, etc.
+  ///
+  bool hasUnmodeledSideEffects() const {
+    return Flags & (1 << MCID::UnmodeledSideEffects);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Flags that indicate whether an instruction can be modified by a method.
+  //===--------------------------------------------------------------------===//
+
+  /// isCommutable - Return true if this may be a 2- or 3-address
+  /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+  /// result if Y and Z are exchanged.  If this flag is set, then the
+  /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+  /// instruction.
+  ///
+  /// Note that this flag may be set on instructions that are only commutable
+  /// sometimes.  In these cases, the call to commuteInstruction will fail.
+  /// Also note that some instructions require non-trivial modification to
+  /// commute them.
+  bool isCommutable() const {
+    return Flags & (1 << MCID::Commutable);
+  }
+
+  /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+  /// which can be changed into a 3-address instruction if needed.  Doing this
+  /// transformation can be profitable in the register allocator, because it
+  /// means that the instruction can use a 2-address form if possible, but
+  /// degrade into a less efficient form if the source and dest register cannot
+  /// be assigned to the same register.  For example, this allows the x86
+  /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+  /// is the same speed as the shift but has bigger code size.
+  ///
+  /// If this returns true, then the target must implement the
+  /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+  /// is allowed to fail if the transformation isn't valid for this specific
+  /// instruction (e.g. shl reg, 4 on x86).
+  ///
+  bool isConvertibleTo3Addr() const {
+    return Flags & (1 << MCID::ConvertibleTo3Addr);
+  }
+
+  /// usesCustomInsertionHook - Return true if this instruction requires
+  /// custom insertion support when the DAG scheduler is inserting it into a
+  /// machine basic block.  If this is true for the instruction, it basically
+  /// means that it is a pseudo instruction used at SelectionDAG time that is
+  /// expanded out into magic code by the target when MachineInstrs are formed.
+  ///
+  /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+  /// is used to insert this into the MachineBasicBlock.
+  bool usesCustomInsertionHook() const {
+    return Flags & (1 << MCID::UsesCustomInserter);
+  }
+
+  /// hasPostISelHook - Return true if this instruction requires *adjustment*
+  /// after instruction selection by calling a target hook. For example, this
+  /// can be used to fill in ARM 's' optional operand depending on whether
+  /// the conditional flag register is used.
+  bool hasPostISelHook() const {
+    return Flags & (1 << MCID::HasPostISelHook);
+  }
+
+  /// isRematerializable - Returns true if this instruction is a candidate for
+  /// remat.  This flag is deprecated, please don't use it anymore.  If this
+  /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+  /// verify the instruction is really rematable.
+  bool isRematerializable() const {
+    return Flags & (1 << MCID::Rematerializable);
+  }
+
+  /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+  /// less) than a move instruction. This is useful during certain types of
+  /// optimizations (e.g., remat during two-address conversion or machine licm)
+  /// where we would like to remat or hoist the instruction, but not if it costs
+  /// more than moving the instruction into the appropriate register. Note, we
+  /// are not marking copies from and to the same register class with this flag.
+  bool isAsCheapAsAMove() const {
+    return Flags & (1 << MCID::CheapAsAMove);
+  }
+
+  /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+  /// have special register allocation requirements that are not captured by the
+  /// operand register classes. e.g. ARM::STRD's two source registers must be an
+  /// even / odd pair, ARM::STM registers have to be in ascending order.
+  /// Post-register allocation passes should not attempt to change allocations
+  /// for sources of instructions with this flag.
+  bool hasExtraSrcRegAllocReq() const {
+    return Flags & (1 << MCID::ExtraSrcRegAllocReq);
+  }
+
+  /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+  /// have special register allocation requirements that are not captured by the
+  /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+  /// even / odd pair, ARM::LDM registers have to be in ascending order.
+  /// Post-register allocation passes should not attempt to change allocations
+  /// for definitions of instructions with this flag.
+  bool hasExtraDefRegAllocReq() const {
+    return Flags & (1 << MCID::ExtraDefRegAllocReq);
+  }
+
+
+  /// getImplicitUses - Return a list of registers that are potentially
+  /// read by any instance of this machine instruction.  For example, on X86,
+  /// the "adc" instruction adds two register operands and adds the carry bit in
+  /// from the flags register.  In this case, the instruction is marked as
+  /// implicitly reading the flags.  Likewise, the variable shift instruction on
+  /// X86 is marked as implicitly reading the 'CL' register, which it always
+  /// does.
+  ///
+  /// This method returns null if the instruction has no implicit uses.
+  const uint16_t *getImplicitUses() const {
+    return ImplicitUses;
+  }
+
+  /// \brief Return the number of implicit uses this instruction has.
+  unsigned getNumImplicitUses() const {
+    if (!ImplicitUses) return 0;
+    unsigned i = 0;
+    for (; ImplicitUses[i]; ++i) /*empty*/;
+    return i;
+  }
+
+  /// getImplicitDefs - Return a list of registers that are potentially
+  /// written by any instance of this machine instruction.  For example, on X86,
+  /// many instructions implicitly set the flags register.  In this case, they
+  /// are marked as setting the FLAGS.  Likewise, many instructions always
+  /// deposit their result in a physical register.  For example, the X86 divide
+  /// instruction always deposits the quotient and remainder in the EAX/EDX
+  /// registers.  For that instruction, this will return a list containing the
+  /// EAX/EDX/EFLAGS registers.
+  ///
+  /// This method returns null if the instruction has no implicit defs.
+  const uint16_t *getImplicitDefs() const {
+    return ImplicitDefs;
+  }
+
+  /// \brief Return the number of implicit defs this instruct has.
+  unsigned getNumImplicitDefs() const {
+    if (!ImplicitDefs) return 0;
+    unsigned i = 0;
+    for (; ImplicitDefs[i]; ++i) /*empty*/;
+    return i;
+  }
+
+  /// \brief Return true if this instruction implicitly
+  /// uses the specified physical register.
+  bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+    if (const uint16_t *ImpUses = ImplicitUses)
+      for (; *ImpUses; ++ImpUses)
+        if (*ImpUses == Reg) return true;
+    return false;
+  }
+
+  /// \brief Return true if this instruction implicitly
+  /// defines the specified physical register.
+  bool hasImplicitDefOfPhysReg(unsigned Reg,
+                               const MCRegisterInfo *MRI = nullptr) const {
+    if (const uint16_t *ImpDefs = ImplicitDefs)
+      for (; *ImpDefs; ++ImpDefs)
+        if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
+            return true;
+    return false;
+  }
+
+  /// \brief Return true if this instruction defines the specified physical
+  /// register, either explicitly or implicitly.
+  bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+                       const MCRegisterInfo &RI) const {
+    for (int i = 0, e = NumDefs; i != e; ++i)
+      if (MI.getOperand(i).isReg() &&
+          RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
+        return true;
+    return hasImplicitDefOfPhysReg(Reg, &RI);
+  }
+
+  /// \brief Return the scheduling class for this instruction.  The
+  /// scheduling class is an index into the InstrItineraryData table.  This
+  /// returns zero if there is no known scheduling information for the
+  /// instruction.
+  unsigned getSchedClass() const {
+    return SchedClass;
+  }
+
+  /// \brief Return the number of bytes in the encoding of this instruction,
+  /// or zero if the encoding size cannot be known from the opcode.
+  unsigned getSize() const {
+    return Size;
+  }
+
+  /// \brief Find the index of the first operand in the
+  /// operand list that is used to represent the predicate. It returns -1 if
+  /// none is found.
+  int findFirstPredOperandIdx() const {
+    if (isPredicable()) {
+      for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+        if (OpInfo[i].isPredicate())
+          return i;
+    }
+    return -1;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h
new file mode 100644
index 0000000..1d3a36c
--- /dev/null
+++ b/include/llvm/MC/MCInstrInfo.h
@@ -0,0 +1,62 @@
+//===-- llvm/MC/MCInstrInfo.h - Target Instruction 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 describes the target machine instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRINFO_H
+#define LLVM_MC_MCINSTRINFO_H
+
+#include "llvm/MC/MCInstrDesc.h"
+#include <cassert>
+
+namespace llvm {
+
+//---------------------------------------------------------------------------
+///
+/// MCInstrInfo - Interface to description of machine instruction set
+///
+class MCInstrInfo {
+  const MCInstrDesc *Desc;          // Raw array to allow static init'n
+  const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
+  const char *InstrNameData;        // Instruction name string pool
+  unsigned NumOpcodes;              // Number of entries in the desc array
+
+public:
+  /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
+  /// auto-generated routines. *DO NOT USE*.
+  void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
+                       unsigned NO) {
+    Desc = D;
+    InstrNameIndices = NI;
+    InstrNameData = ND;
+    NumOpcodes = NO;
+  }
+
+  unsigned getNumOpcodes() const { return NumOpcodes; }
+
+  /// get - Return the machine instruction descriptor that corresponds to the
+  /// specified instruction opcode.
+  ///
+  const MCInstrDesc &get(unsigned Opcode) const {
+    assert(Opcode < NumOpcodes && "Invalid opcode!");
+    return Desc[Opcode];
+  }
+
+  /// getName - Returns the name for the instructions with the given opcode.
+  const char *getName(unsigned Opcode) const {
+    assert(Opcode < NumOpcodes && "Invalid opcode!");
+    return &InstrNameData[InstrNameIndices[Opcode]];
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
new file mode 100644
index 0000000..5104345
--- /dev/null
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -0,0 +1,251 @@
+//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the structures used for instruction
+// itineraries, stages, and operand reads/writes.  This is used by
+// schedulers to determine instruction stages and latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
+
+#include "llvm/MC/MCSchedule.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// Instruction stage - These values represent a non-pipelined step in
+/// the execution of an instruction.  Cycles represents the number of
+/// discrete time slots needed to complete the stage.  Units represent
+/// the choice of functional units that can be used to complete the
+/// stage.  Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+/// cycles should elapse from the start of this stage to the start of
+/// the next stage in the itinerary. A value of -1 indicates that the
+/// next stage should start immediately after the current one.
+/// For example:
+///
+///   { 1, x, -1 }
+///      indicates that the stage occupies FU x for 1 cycle and that
+///      the next stage starts immediately after this one.
+///
+///   { 2, x|y, 1 }
+///      indicates that the stage occupies either FU x or FU y for 2
+///      consecuative cycles and that the next stage starts one cycle
+///      after this stage starts. That is, the stage requirements
+///      overlap in time.
+///
+///   { 1, x, 0 }
+///      indicates that the stage occupies FU x for 1 cycle and that
+///      the next stage starts in this same cycle. This can be used to
+///      indicate that the instruction requires multiple stages at the
+///      same time.
+///
+/// FU reservation can be of two different kinds:
+///  - FUs which instruction actually requires
+///  - FUs which instruction just reserves. Reserved unit is not available for
+///    execution of other instruction. However, several instructions can reserve
+///    the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
+struct InstrStage {
+  enum ReservationKinds {
+    Required = 0,
+    Reserved = 1
+  };
+
+  unsigned Cycles_;  ///< Length of stage in machine cycles
+  unsigned Units_;   ///< Choice of functional units
+  int NextCycles_;   ///< Number of machine cycles to next stage
+  ReservationKinds Kind_; ///< Kind of the FU reservation
+
+  /// getCycles - returns the number of cycles the stage is occupied
+  unsigned getCycles() const {
+    return Cycles_;
+  }
+
+  /// getUnits - returns the choice of FUs
+  unsigned getUnits() const {
+    return Units_;
+  }
+
+  ReservationKinds getReservationKind() const {
+    return Kind_;
+  }
+
+  /// getNextCycles - returns the number of cycles from the start of
+  /// this stage to the start of the next stage in the itinerary
+  unsigned getNextCycles() const {
+    return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary - An itinerary represents the scheduling
+/// information for an instruction. This includes a set of stages
+/// occupies by the instruction, and the pipeline cycle in which
+/// operands are read and written.
+///
+struct InstrItinerary {
+  int      NumMicroOps;        ///< # of micro-ops, -1 means it's variable
+  unsigned FirstStage;         ///< Index of first stage in itinerary
+  unsigned LastStage;          ///< Index of last + 1 stage in itinerary
+  unsigned FirstOperandCycle;  ///< Index of first operand rd/wr
+  unsigned LastOperandCycle;   ///< Index of last + 1 operand rd/wr
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
+/// used by a target.
+///
+class InstrItineraryData {
+public:
+  const MCSchedModel   *SchedModel;     ///< Basic machine properties.
+  const InstrStage     *Stages;         ///< Array of stages selected
+  const unsigned       *OperandCycles;  ///< Array of operand cycles selected
+  const unsigned       *Forwardings;    ///< Array of pipeline forwarding pathes
+  const InstrItinerary *Itineraries;    ///< Array of itineraries selected
+
+  /// Ctors.
+  ///
+  InstrItineraryData() : SchedModel(&MCSchedModel::DefaultSchedModel),
+                         Stages(nullptr), OperandCycles(nullptr),
+                         Forwardings(nullptr), Itineraries(nullptr) {}
+
+  InstrItineraryData(const MCSchedModel *SM, const InstrStage *S,
+                     const unsigned *OS, const unsigned *F)
+    : SchedModel(SM), Stages(S), OperandCycles(OS), Forwardings(F),
+      Itineraries(SchedModel->InstrItineraries) {}
+
+  /// isEmpty - Returns true if there are no itineraries.
+  ///
+  bool isEmpty() const { return Itineraries == nullptr; }
+
+  /// isEndMarker - Returns true if the index is for the end marker
+  /// itinerary.
+  ///
+  bool isEndMarker(unsigned ItinClassIndx) const {
+    return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
+            (Itineraries[ItinClassIndx].LastStage == ~0U));
+  }
+
+  /// beginStage - Return the first stage of the itinerary.
+  ///
+  const InstrStage *beginStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
+    return Stages + StageIdx;
+  }
+
+  /// endStage - Return the last+1 stage of the itinerary.
+  ///
+  const InstrStage *endStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
+    return Stages + StageIdx;
+  }
+
+  /// getStageLatency - Return the total stage latency of the given
+  /// class.  The latency is the maximum completion time for any stage
+  /// in the itinerary.
+  ///
+  /// If no stages exist, it defaults to one cycle.
+  unsigned getStageLatency(unsigned ItinClassIndx) const {
+    // If the target doesn't provide itinerary information, use a simple
+    // non-zero default value for all instructions.
+    if (isEmpty())
+      return 1;
+
+    // Calculate the maximum completion time for any stage.
+    unsigned Latency = 0, StartCycle = 0;
+    for (const InstrStage *IS = beginStage(ItinClassIndx),
+           *E = endStage(ItinClassIndx); IS != E; ++IS) {
+      Latency = std::max(Latency, StartCycle + IS->getCycles());
+      StartCycle += IS->getNextCycles();
+    }
+    return Latency;
+  }
+
+  /// getOperandCycle - Return the cycle for the given class and
+  /// operand. Return -1 if no cycle is specified for the operand.
+  ///
+  int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
+    if (isEmpty())
+      return -1;
+
+    unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
+    unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
+    if ((FirstIdx + OperandIdx) >= LastIdx)
+      return -1;
+
+    return (int)OperandCycles[FirstIdx + OperandIdx];
+  }
+
+  /// hasPipelineForwarding - Return true if there is a pipeline forwarding
+  /// between instructions of itinerary classes DefClass and UseClasses so that
+  /// value produced by an instruction of itinerary class DefClass, operand
+  /// index DefIdx can be bypassed when it's read by an instruction of
+  /// itinerary class UseClass, operand index UseIdx.
+  bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
+                             unsigned UseClass, unsigned UseIdx) const {
+    unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
+    unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
+    if ((FirstDefIdx + DefIdx) >= LastDefIdx)
+      return false;
+    if (Forwardings[FirstDefIdx + DefIdx] == 0)
+      return false;
+
+    unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
+    unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
+    if ((FirstUseIdx + UseIdx) >= LastUseIdx)
+      return false;
+
+    return Forwardings[FirstDefIdx + DefIdx] ==
+      Forwardings[FirstUseIdx + UseIdx];
+  }
+
+  /// getOperandLatency - Compute and return the use operand latency of a given
+  /// itinerary class and operand index if the value is produced by an
+  /// instruction of the specified itinerary class and def operand index.
+  int getOperandLatency(unsigned DefClass, unsigned DefIdx,
+                        unsigned UseClass, unsigned UseIdx) const {
+    if (isEmpty())
+      return -1;
+
+    int DefCycle = getOperandCycle(DefClass, DefIdx);
+    if (DefCycle == -1)
+      return -1;
+
+    int UseCycle = getOperandCycle(UseClass, UseIdx);
+    if (UseCycle == -1)
+      return -1;
+
+    UseCycle = DefCycle - UseCycle + 1;
+    if (UseCycle > 0 &&
+        hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
+      // FIXME: This assumes one cycle benefit for every pipeline forwarding.
+      --UseCycle;
+    return UseCycle;
+  }
+
+  /// getNumMicroOps - Return the number of micro-ops that the given class
+  /// decodes to. Return -1 for classes that require dynamic lookup via
+  /// TargetInstrInfo.
+  int getNumMicroOps(unsigned ItinClassIndx) const {
+    if (isEmpty())
+      return 1;
+    return Itineraries[ItinClassIndx].NumMicroOps;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCLabel.h b/include/llvm/MC/MCLabel.h
new file mode 100644
index 0000000..f531de8
--- /dev/null
+++ b/include/llvm/MC/MCLabel.h
@@ -0,0 +1,58 @@
+//===- MCLabel.h - Machine Code Directional Local Labels --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCLabel class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLABEL_H
+#define LLVM_MC_MCLABEL_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MCContext;
+  class raw_ostream;
+
+  /// MCLabel - Instances of this class represent a label name in the MC file,
+  /// and MCLabel are created and unique'd by the MCContext class.  MCLabel
+  /// should only be constructed for valid instances in the object file.
+  class MCLabel {
+    // Instance - the instance number of this Directional Local Label
+    unsigned Instance;
+
+  private:  // MCContext creates and uniques these.
+    friend class MCContext;
+    MCLabel(unsigned instance)
+      : Instance(instance) {}
+
+    MCLabel(const MCLabel&) LLVM_DELETED_FUNCTION;
+    void operator=(const MCLabel&) LLVM_DELETED_FUNCTION;
+  public:
+    /// getInstance - Get the current instance of this Directional Local Label.
+    unsigned getInstance() const { return Instance; }
+
+    /// incInstance - Increment the current instance of this Directional Local
+    /// Label.
+    unsigned incInstance() { return ++Instance; }
+
+    /// print - Print the value to the stream \p OS.
+    void print(raw_ostream &OS) const;
+
+    /// dump - Print the value to stderr.
+    void dump() const;
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
+    Label.print(OS);
+    return OS;
+  }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
new file mode 100644
index 0000000..50fd527
--- /dev/null
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -0,0 +1,205 @@
+//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- 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 some helpers classes to handle Linker Optimization Hint
+// (LOH).
+//
+// FIXME: LOH interface supports only MachO format at the moment.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+// Forward declarations.
+class MCAsmLayout;
+class MCSymbol;
+
+/// Linker Optimization Hint Type.
+enum MCLOHType {
+  MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
+  MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
+  MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
+  MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
+  MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
+  MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
+  MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
+  MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
+};
+
+static inline StringRef MCLOHDirectiveName() {
+  return StringRef(".loh");
+}
+
+static inline bool isValidMCLOHType(MCLOHType Kind) {
+  return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
+}
+
+static inline int MCLOHNameToId(StringRef Name) {
+#define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)
+  return StringSwitch<int>(Name)
+    MCLOHCaseNameToId(AdrpAdrp)
+    MCLOHCaseNameToId(AdrpLdr)
+    MCLOHCaseNameToId(AdrpAddLdr)
+    MCLOHCaseNameToId(AdrpLdrGotLdr)
+    MCLOHCaseNameToId(AdrpAddStr)
+    MCLOHCaseNameToId(AdrpLdrGotStr)
+    MCLOHCaseNameToId(AdrpAdd)
+    MCLOHCaseNameToId(AdrpLdrGot)
+    .Default(-1);
+}
+
+static inline StringRef MCLOHIdToName(MCLOHType Kind) {
+#define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);
+  switch (Kind) {
+    MCLOHCaseIdToName(AdrpAdrp);
+    MCLOHCaseIdToName(AdrpLdr);
+    MCLOHCaseIdToName(AdrpAddLdr);
+    MCLOHCaseIdToName(AdrpLdrGotLdr);
+    MCLOHCaseIdToName(AdrpAddStr);
+    MCLOHCaseIdToName(AdrpLdrGotStr);
+    MCLOHCaseIdToName(AdrpAdd);
+    MCLOHCaseIdToName(AdrpLdrGot);
+  }
+  return StringRef();
+}
+
+static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
+  switch (Kind) {
+    // LOH with two arguments
+  case MCLOH_AdrpAdrp:
+  case MCLOH_AdrpLdr:
+  case MCLOH_AdrpAdd:
+  case MCLOH_AdrpLdrGot:
+    return 2;
+    // LOH with three arguments
+  case MCLOH_AdrpAddLdr:
+  case MCLOH_AdrpLdrGotLdr:
+  case MCLOH_AdrpAddStr:
+  case MCLOH_AdrpLdrGotStr:
+    return 3;
+  }
+  return -1;
+}
+
+/// Store Linker Optimization Hint information (LOH).
+class MCLOHDirective {
+  MCLOHType Kind;
+
+  /// Arguments of this directive. Order matters.
+  SmallVector<MCSymbol *, 3> Args;
+
+  /// Emit this directive in @p OutStream using the information available
+  /// in the given @p ObjWriter and @p Layout to get the address of the
+  /// arguments within the object file.
+  void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
+                 const MCAsmLayout &Layout) const;
+
+public:
+  typedef SmallVectorImpl<MCSymbol *> LOHArgs;
+
+  MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
+      : Kind(Kind), Args(Args.begin(), Args.end()) {
+    assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
+  }
+
+  MCLOHType getKind() const { return Kind; }
+
+  const LOHArgs &getArgs() const { return Args; }
+
+  /// Emit this directive as:
+  /// <kind, numArgs, addr1, ..., addrN>
+  void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+    raw_ostream &OutStream = ObjWriter.getStream();
+    Emit_impl(OutStream, ObjWriter, Layout);
+  }
+
+  /// Get the size in bytes of this directive if emitted in @p ObjWriter with
+  /// the given @p Layout.
+  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+                       const MCAsmLayout &Layout) const {
+    class raw_counting_ostream : public raw_ostream {
+      uint64_t Count;
+
+      void write_impl(const char *, size_t size) override { Count += size; }
+
+      uint64_t current_pos() const override { return Count; }
+
+    public:
+      raw_counting_ostream() : Count(0) {}
+      ~raw_counting_ostream() { flush(); }
+    };
+
+    raw_counting_ostream OutStream;
+    Emit_impl(OutStream, ObjWriter, Layout);
+    return OutStream.tell();
+  }
+};
+
+class MCLOHContainer {
+  /// Keep track of the emit size of all the LOHs.
+  mutable uint64_t EmitSize;
+
+  /// Keep track of all LOH directives.
+  SmallVector<MCLOHDirective, 32> Directives;
+
+public:
+  typedef SmallVectorImpl<MCLOHDirective> LOHDirectives;
+
+  MCLOHContainer() : EmitSize(0) {};
+
+  /// Const accessor to the directives.
+  const LOHDirectives &getDirectives() const {
+    return Directives;
+  }
+
+  /// Add the directive of the given kind @p Kind with the given arguments
+  /// @p Args to the container.
+  void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
+    Directives.push_back(MCLOHDirective(Kind, Args));
+  }
+
+  /// Get the size of the directives if emitted.
+  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+                       const MCAsmLayout &Layout) const {
+    if (!EmitSize) {
+      for (const MCLOHDirective &D : Directives)
+        EmitSize += D.getEmitSize(ObjWriter, Layout);
+    }
+    return EmitSize;
+  }
+
+  /// Emit all Linker Optimization Hint in one big table.
+  /// Each line of the table is emitted by LOHDirective::Emit.
+  void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+    for (const MCLOHDirective &D : Directives)
+      D.Emit(ObjWriter, Layout);
+  }
+
+  void reset() {
+    Directives.clear();
+    EmitSize = 0;
+  }
+};
+
+// Add types for specialized template using MCSymbol.
+typedef MCLOHDirective::LOHArgs MCLOHArgs;
+typedef MCLOHContainer::LOHDirectives MCLOHDirectives;
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h
new file mode 100644
index 0000000..71f01fa
--- /dev/null
+++ b/include/llvm/MC/MCMachOSymbolFlags.h
@@ -0,0 +1,46 @@
+//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- 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 SymbolFlags used for the MachO target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
+#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
+
+// These flags are mostly used in MCMachOStreamer.cpp but also needed in
+// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
+// the correct relocation information.
+
+namespace llvm {
+  /// MachOSymbolFlags - We store the value for the 'desc' symbol field in the
+  /// lowest 16 bits of the implementation defined flags.
+  enum MachOSymbolFlags { // See <mach-o/nlist.h>.
+    SF_DescFlagsMask                        = 0xFFFF,
+
+    // Reference type flags.
+    SF_ReferenceTypeMask                    = 0x0007,
+    SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
+    SF_ReferenceTypeUndefinedLazy           = 0x0001,
+    SF_ReferenceTypeDefined                 = 0x0002,
+    SF_ReferenceTypePrivateDefined          = 0x0003,
+    SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+    SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
+
+    // Other 'desc' flags.
+    SF_ThumbFunc                            = 0x0008,
+    SF_NoDeadStrip                          = 0x0020,
+    SF_WeakReference                        = 0x0040,
+    SF_WeakDefinition                       = 0x0080,
+    SF_SymbolResolver                       = 0x0100
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
new file mode 100644
index 0000000..12a7f0e
--- /dev/null
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -0,0 +1,278 @@
+//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
+#define LLVM_MC_MCMACHOBJECTWRITER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MachO.h"
+#include <vector>
+
+namespace llvm {
+
+class MCSectionData;
+class MachObjectWriter;
+
+class MCMachObjectTargetWriter {
+  const unsigned Is64Bit : 1;
+  const uint32_t CPUType;
+  const uint32_t CPUSubtype;
+  // FIXME: Remove this, we should just always use it once we no longer care
+  // about Darwin 'as' compatibility.
+  const unsigned UseAggressiveSymbolFolding : 1;
+  unsigned LocalDifference_RIT;
+
+protected:
+  MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
+                           uint32_t CPUSubtype_,
+                           bool UseAggressiveSymbolFolding_ = false);
+
+  void setLocalDifferenceRelocationType(unsigned Type) {
+    LocalDifference_RIT = Type;
+  }
+
+public:
+  virtual ~MCMachObjectTargetWriter();
+
+  /// @name Lifetime Management
+  /// @{
+
+  virtual void reset() {};
+
+  /// @}
+
+  /// @name Accessors
+  /// @{
+
+  bool is64Bit() const { return Is64Bit; }
+  bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; }
+  uint32_t getCPUType() const { return CPUType; }
+  uint32_t getCPUSubtype() const { return CPUSubtype; }
+  unsigned getLocalDifferenceRelocationType() const {
+    return LocalDifference_RIT;
+  }
+
+  /// @}
+
+  /// @name API
+  /// @{
+
+  virtual void RecordRelocation(MachObjectWriter *Writer,
+                                const MCAssembler &Asm,
+                                const MCAsmLayout &Layout,
+                                const MCFragment *Fragment,
+                                const MCFixup &Fixup,
+                                MCValue Target,
+                                uint64_t &FixedValue) = 0;
+
+  /// @}
+};
+
+class MachObjectWriter : public MCObjectWriter {
+  /// MachSymbolData - Helper struct for containing some precomputed information
+  /// on symbols.
+  struct MachSymbolData {
+    MCSymbolData *SymbolData;
+    uint64_t StringIndex;
+    uint8_t SectionIndex;
+
+    // Support lexicographic sorting.
+    bool operator<(const MachSymbolData &RHS) const;
+  };
+
+  /// The target specific Mach-O writer instance.
+  std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
+
+  /// @name Relocation Data
+  /// @{
+
+  llvm::DenseMap<const MCSectionData*,
+                 std::vector<MachO::any_relocation_info> > Relocations;
+  llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
+
+  /// @}
+  /// @name Symbol Table Data
+  /// @{
+
+  SmallString<256> StringTable;
+  std::vector<MachSymbolData> LocalSymbolData;
+  std::vector<MachSymbolData> ExternalSymbolData;
+  std::vector<MachSymbolData> UndefinedSymbolData;
+
+  /// @}
+
+  MachSymbolData *findSymbolData(const MCSymbol &Sym);
+
+public:
+  MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
+                   bool _IsLittleEndian)
+    : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
+  }
+
+  /// @name Lifetime management Methods
+  /// @{
+
+  void reset() override;
+
+  /// @}
+
+  /// @name Utility Methods
+  /// @{
+
+  bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+
+  SectionAddrMap SectionAddress;
+
+  SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
+
+  uint64_t getSectionAddress(const MCSectionData* SD) const {
+    return SectionAddress.lookup(SD);
+  }
+  uint64_t getSymbolAddress(const MCSymbolData* SD,
+                            const MCAsmLayout &Layout) const;
+
+  uint64_t getFragmentAddress(const MCFragment *Fragment,
+                              const MCAsmLayout &Layout) const;
+
+  uint64_t getPaddingSize(const MCSectionData *SD,
+                          const MCAsmLayout &Layout) const;
+
+  bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
+
+  /// @}
+
+  /// @name Target Writer Proxy Accessors
+  /// @{
+
+  bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+  bool isX86_64() const {
+    uint32_t CPUType = TargetObjectWriter->getCPUType();
+    return CPUType == MachO::CPU_TYPE_X86_64;
+  }
+
+  /// @}
+
+  void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
+                   bool SubsectionsViaSymbols);
+
+  /// WriteSegmentLoadCommand - Write a segment load command.
+  ///
+  /// \param NumSections The number of sections in this segment.
+  /// \param SectionDataSize The total size of the sections.
+  void WriteSegmentLoadCommand(unsigned NumSections,
+                               uint64_t VMSize,
+                               uint64_t SectionDataStartOffset,
+                               uint64_t SectionDataSize);
+
+  void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
+                    const MCSectionData &SD, uint64_t FileOffset,
+                    uint64_t RelocationsStart, unsigned NumRelocations);
+
+  void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+                              uint32_t StringTableOffset,
+                              uint32_t StringTableSize);
+
+  void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
+                                uint32_t NumLocalSymbols,
+                                uint32_t FirstExternalSymbol,
+                                uint32_t NumExternalSymbols,
+                                uint32_t FirstUndefinedSymbol,
+                                uint32_t NumUndefinedSymbols,
+                                uint32_t IndirectSymbolOffset,
+                                uint32_t NumIndirectSymbols);
+
+  void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+
+  void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
+                                uint32_t DataSize);
+
+  void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
+
+  // FIXME: We really need to improve the relocation validation. Basically, we
+  // want to implement a separate computation which evaluates the relocation
+  // entry as the linker would, and verifies that the resultant fixup value is
+  // exactly what the encoder wanted. This will catch several classes of
+  // problems:
+  //
+  //  - Relocation entry bugs, the two algorithms are unlikely to have the same
+  //    exact bug.
+  //
+  //  - Relaxation issues, where we forget to relax something.
+  //
+  //  - Input errors, where something cannot be correctly encoded. 'as' allows
+  //    these through in many cases.
+
+  void addRelocation(const MCSectionData *SD,
+                     MachO::any_relocation_info &MRE) {
+    Relocations[SD].push_back(MRE);
+  }
+
+  void RecordScatteredRelocation(const MCAssembler &Asm,
+                                 const MCAsmLayout &Layout,
+                                 const MCFragment *Fragment,
+                                 const MCFixup &Fixup, MCValue Target,
+                                 unsigned Log2Size,
+                                 uint64_t &FixedValue);
+
+  void RecordTLVPRelocation(const MCAssembler &Asm,
+                            const MCAsmLayout &Layout,
+                            const MCFragment *Fragment,
+                            const MCFixup &Fixup, MCValue Target,
+                            uint64_t &FixedValue);
+
+  void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+                        const MCFragment *Fragment, const MCFixup &Fixup,
+                        MCValue Target, bool &IsPCRel,
+                        uint64_t &FixedValue) override;
+
+  void BindIndirectSymbols(MCAssembler &Asm);
+
+  /// ComputeSymbolTable - Compute the symbol table data
+  ///
+  /// \param StringTable [out] - The string table data.
+  void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
+                          std::vector<MachSymbolData> &LocalSymbolData,
+                          std::vector<MachSymbolData> &ExternalSymbolData,
+                          std::vector<MachSymbolData> &UndefinedSymbolData);
+
+  void computeSectionAddresses(const MCAssembler &Asm,
+                               const MCAsmLayout &Layout);
+
+  void markAbsoluteVariableSymbols(MCAssembler &Asm,
+                                   const MCAsmLayout &Layout);
+  void ExecutePostLayoutBinding(MCAssembler &Asm,
+                                const MCAsmLayout &Layout) override;
+
+  bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+                                              const MCSymbolData &DataA,
+                                              const MCFragment &FB,
+                                              bool InSet,
+                                              bool IsPCRel) const override;
+
+  void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+};
+
+
+/// \brief Construct a new Mach-O writer instance.
+///
+/// This routine takes ownership of the target writer subclass.
+///
+/// \param MOTW - The target specific Mach-O writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
+                                       raw_ostream &OS, bool IsLittleEndian);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCObjectDisassembler.h b/include/llvm/MC/MCObjectDisassembler.h
new file mode 100644
index 0000000..5b935db
--- /dev/null
+++ b/include/llvm/MC/MCObjectDisassembler.h
@@ -0,0 +1,174 @@
+//===-- llvm/MC/MCObjectDisassembler.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCObjectDisassembler class, which
+// can be used to construct an MCModule and an MC CFG from an ObjectFile.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTDISASSEMBLER_H
+#define LLVM_MC_MCOBJECTDISASSEMBLER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MemoryObject.h"
+#include <vector>
+
+namespace llvm {
+
+namespace object {
+  class ObjectFile;
+  class MachOObjectFile;
+}
+
+class MCBasicBlock;
+class MCDisassembler;
+class MCFunction;
+class MCInstrAnalysis;
+class MCModule;
+class MCObjectSymbolizer;
+
+/// \brief Disassemble an ObjectFile to an MCModule and MCFunctions.
+/// This class builds on MCDisassembler to disassemble whole sections, creating
+/// MCAtom (MCTextAtom for disassembled sections and MCDataAtom for raw data).
+/// It can also be used to create a control flow graph consisting of MCFunctions
+/// and MCBasicBlocks.
+class MCObjectDisassembler {
+public:
+  MCObjectDisassembler(const object::ObjectFile &Obj,
+                       const MCDisassembler &Dis,
+                       const MCInstrAnalysis &MIA);
+  virtual ~MCObjectDisassembler() {}
+
+  /// \brief Build an MCModule, creating atoms and optionally functions.
+  /// \param withCFG Also build a CFG by adding MCFunctions to the Module.
+  /// If withCFG is false, the MCModule built only contains atoms, representing
+  /// what was found in the object file. If withCFG is true, MCFunctions are
+  /// created, containing MCBasicBlocks. All text atoms are split to form basic
+  /// block atoms, which then each back an MCBasicBlock.
+  MCModule *buildModule(bool withCFG = false);
+
+  MCModule *buildEmptyModule();
+
+  typedef std::vector<uint64_t> AddressSetTy;
+  /// \name Create a new MCFunction.
+  MCFunction *createFunction(MCModule *Module, uint64_t BeginAddr,
+                             AddressSetTy &CallTargets,
+                             AddressSetTy &TailCallTargets);
+
+  /// \brief Set the region on which to fallback if disassembly was requested
+  /// somewhere not accessible in the object file.
+  /// This is used for dynamic disassembly (see RawMemoryObject).
+  void setFallbackRegion(std::unique_ptr<MemoryObject> &Region) {
+    FallbackRegion.reset(Region.release());
+  }
+
+  /// \brief Set the symbolizer to use to get information on external functions.
+  /// Note that this isn't used to do instruction-level symbolization (that is,
+  /// plugged into MCDisassembler), but to symbolize function call targets.
+  void setSymbolizer(MCObjectSymbolizer *ObjectSymbolizer) {
+    MOS = ObjectSymbolizer;
+  }
+
+  /// \brief Get the effective address of the entrypoint, or 0 if there is none.
+  virtual uint64_t getEntrypoint();
+
+  /// \name Get the addresses of static constructors/destructors in the object.
+  /// The caller is expected to know how to interpret the addresses;
+  /// for example, Mach-O init functions expect 5 arguments, not for ELF.
+  /// The addresses are original object file load addresses, not effective.
+  /// @{
+  virtual ArrayRef<uint64_t> getStaticInitFunctions();
+  virtual ArrayRef<uint64_t> getStaticExitFunctions();
+  /// @}
+
+  /// \name Translation between effective and objectfile load address.
+  /// @{
+  /// \brief Compute the effective load address, from an objectfile virtual
+  /// address. This is implemented in a format-specific way, to take into
+  /// account things like PIE/ASLR when doing dynamic disassembly.
+  /// For example, on Mach-O this would be done by adding the VM addr slide,
+  /// on glibc ELF by keeping a map between segment load addresses, filled
+  /// using dl_iterate_phdr, etc..
+  /// In most static situations and in the default impl., this returns \p Addr.
+  virtual uint64_t getEffectiveLoadAddr(uint64_t Addr);
+
+  /// \brief Compute the original load address, as specified in the objectfile.
+  /// This is the inverse of getEffectiveLoadAddr.
+  virtual uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr);
+  /// @}
+
+protected:
+  const object::ObjectFile &Obj;
+  const MCDisassembler &Dis;
+  const MCInstrAnalysis &MIA;
+  MCObjectSymbolizer *MOS;
+
+  /// \brief The fallback memory region, outside the object file.
+  std::unique_ptr<MemoryObject> FallbackRegion;
+
+  /// \brief Return a memory region suitable for reading starting at \p Addr.
+  /// In most cases, this returns a StringRefMemoryObject backed by the
+  /// containing section. When no section was found, this returns the
+  /// FallbackRegion, if it is suitable.
+  /// If it is not, or if there is no fallback region, this returns 0.
+  MemoryObject *getRegionFor(uint64_t Addr);
+
+private:
+  /// \brief Fill \p Module by creating an atom for each section.
+  /// This could be made much smarter, using information like symbols, but also
+  /// format-specific features, like mach-o function_start or data_in_code LCs.
+  void buildSectionAtoms(MCModule *Module);
+
+  /// \brief Enrich \p Module with a CFG consisting of MCFunctions.
+  /// \param Module An MCModule returned by buildModule, with no CFG.
+  /// NOTE: Each MCBasicBlock in a MCFunction is backed by a single MCTextAtom.
+  /// When the CFG is built, contiguous instructions that were previously in a
+  /// single MCTextAtom will be split in multiple basic block atoms.
+  void buildCFG(MCModule *Module);
+
+  MCBasicBlock *getBBAt(MCModule *Module, MCFunction *MCFN, uint64_t BeginAddr,
+                        AddressSetTy &CallTargets,
+                        AddressSetTy &TailCallTargets);
+};
+
+class MCMachOObjectDisassembler : public MCObjectDisassembler {
+  const object::MachOObjectFile &MOOF;
+
+  uint64_t VMAddrSlide;
+  uint64_t HeaderLoadAddress;
+
+  // __DATA;__mod_init_func support.
+  llvm::StringRef ModInitContents;
+  // __DATA;__mod_exit_func support.
+  llvm::StringRef ModExitContents;
+
+public:
+  /// \brief Construct a Mach-O specific object disassembler.
+  /// \param VMAddrSlide The virtual address slide applied by dyld.
+  /// \param HeaderLoadAddress The load address of the mach_header for this
+  /// object.
+  MCMachOObjectDisassembler(const object::MachOObjectFile &MOOF,
+                            const MCDisassembler &Dis,
+                            const MCInstrAnalysis &MIA, uint64_t VMAddrSlide,
+                            uint64_t HeaderLoadAddress);
+
+protected:
+  uint64_t getEffectiveLoadAddr(uint64_t Addr) override;
+  uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) override;
+  uint64_t getEntrypoint() override;
+
+  ArrayRef<uint64_t> getStaticInitFunctions() override;
+  ArrayRef<uint64_t> getStaticExitFunctions() override;
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
new file mode 100644
index 0000000..4d1715e
--- /dev/null
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -0,0 +1,390 @@
+//===-- llvm/MC/MCObjectFileInfo.h - Object File 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 describes common object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCBJECTFILEINFO_H
+#define LLVM_MC_MCBJECTFILEINFO_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+  class MCContext;
+  class MCSection;
+  class StringRef;
+
+class MCObjectFileInfo {
+protected:
+  /// CommDirectiveSupportsAlignment - True if .comm supports alignment.  This
+  /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't
+  /// support alignment on comm.
+  bool CommDirectiveSupportsAlignment;
+
+  /// SupportsWeakEmptyEHFrame - True if target object file supports a
+  /// weak_definition of constant 0 for an omitted EH frame.
+  bool SupportsWeakOmittedEHFrame;
+
+  /// SupportsCompactUnwindWithoutEHFrame - True if the target object file
+  /// supports emitting a compact unwind section without an associated EH frame
+  /// section.
+  bool SupportsCompactUnwindWithoutEHFrame;
+
+  /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
+  /// for EH.
+  unsigned PersonalityEncoding;
+  unsigned LSDAEncoding;
+  unsigned FDECFIEncoding;
+  unsigned TTypeEncoding;
+
+  /// Section flags for eh_frame
+  unsigned EHSectionType;
+  unsigned EHSectionFlags;
+
+  /// CompactUnwindDwarfEHFrameOnly - Compact unwind encoding indicating that we
+  /// should emit only an EH frame.
+  unsigned CompactUnwindDwarfEHFrameOnly;
+
+  /// TextSection - Section directive for standard text.
+  ///
+  const MCSection *TextSection;
+
+  /// DataSection - Section directive for standard data.
+  ///
+  const MCSection *DataSection;
+
+  /// BSSSection - Section that is default initialized to zero.
+  const MCSection *BSSSection;
+
+  /// ReadOnlySection - Section that is readonly and can contain arbitrary
+  /// initialized data.  Targets are not required to have a readonly section.
+  /// If they don't, various bits of code will fall back to using the data
+  /// section for constants.
+  const MCSection *ReadOnlySection;
+
+  /// StaticCtorSection - This section contains the static constructor pointer
+  /// list.
+  const MCSection *StaticCtorSection;
+
+  /// StaticDtorSection - This section contains the static destructor pointer
+  /// list.
+  const MCSection *StaticDtorSection;
+
+  /// LSDASection - If exception handling is supported by the target, this is
+  /// the section the Language Specific Data Area information is emitted to.
+  const MCSection *LSDASection;
+
+  /// CompactUnwindSection - If exception handling is supported by the target
+  /// and the target can support a compact representation of the CIE and FDE,
+  /// this is the section to emit them into.
+  const MCSection *CompactUnwindSection;
+
+  // Dwarf sections for debug info.  If a target supports debug info, these must
+  // be set.
+  const MCSection *DwarfAbbrevSection;
+  const MCSection *DwarfInfoSection;
+  const MCSection *DwarfLineSection;
+  const MCSection *DwarfFrameSection;
+  const MCSection *DwarfPubTypesSection;
+  const MCSection *DwarfDebugInlineSection;
+  const MCSection *DwarfStrSection;
+  const MCSection *DwarfLocSection;
+  const MCSection *DwarfARangesSection;
+  const MCSection *DwarfRangesSection;
+  const MCSection *DwarfMacroInfoSection;
+  // The pubnames section is no longer generated by default.  The generation
+  // can be enabled by a compiler flag.
+  const MCSection *DwarfPubNamesSection;
+
+  // DWARF5 Experimental Debug Info Sections
+  /// DwarfAccelNamesSection, DwarfAccelObjCSection,
+  /// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
+  /// If we use the DWARF accelerated hash tables then we want to emit these
+  /// sections.
+  const MCSection *DwarfAccelNamesSection;
+  const MCSection *DwarfAccelObjCSection;
+  const MCSection *DwarfAccelNamespaceSection;
+  const MCSection *DwarfAccelTypesSection;
+
+  /// These are used for the Fission separate debug information files.
+  const MCSection *DwarfInfoDWOSection;
+  const MCSection *DwarfAbbrevDWOSection;
+  const MCSection *DwarfStrDWOSection;
+  const MCSection *DwarfLineDWOSection;
+  const MCSection *DwarfLocDWOSection;
+  const MCSection *DwarfStrOffDWOSection;
+  const MCSection *DwarfAddrSection;
+
+  /// Sections for newer gnu pubnames and pubtypes.
+  const MCSection *DwarfGnuPubNamesSection;
+  const MCSection *DwarfGnuPubTypesSection;
+
+  const MCSection *COFFDebugSymbolsSection;
+
+  // Extra TLS Variable Data section.  If the target needs to put additional
+  // information for a TLS variable, it'll go here.
+  const MCSection *TLSExtraDataSection;
+
+  /// TLSDataSection - Section directive for Thread Local data.
+  /// ELF, MachO and COFF.
+  const MCSection *TLSDataSection;        // Defaults to ".tdata".
+
+  /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+  /// Null if this target doesn't support a BSS section.
+  /// ELF and MachO only.
+  const MCSection *TLSBSSSection;         // Defaults to ".tbss".
+
+  /// StackMap section.
+  const MCSection *StackMapSection;
+
+  /// EHFrameSection - EH frame section. It is initialized on demand so it
+  /// can be overwritten (with uniquing).
+  const MCSection *EHFrameSection;
+
+  /// ELF specific sections.
+  ///
+  const MCSection *DataRelSection;
+  const MCSection *DataRelLocalSection;
+  const MCSection *DataRelROSection;
+  const MCSection *DataRelROLocalSection;
+  const MCSection *MergeableConst4Section;
+  const MCSection *MergeableConst8Section;
+  const MCSection *MergeableConst16Section;
+
+  /// MachO specific sections.
+  ///
+
+  /// TLSTLVSection - Section for thread local structure information.
+  /// Contains the source code name of the variable, visibility and a pointer
+  /// to the initial value (.tdata or .tbss).
+  const MCSection *TLSTLVSection;         // Defaults to ".tlv".
+
+  /// TLSThreadInitSection - Section for thread local data initialization
+  /// functions.
+  const MCSection *TLSThreadInitSection;  // Defaults to ".thread_init_func".
+
+  const MCSection *CStringSection;
+  const MCSection *UStringSection;
+  const MCSection *TextCoalSection;
+  const MCSection *ConstTextCoalSection;
+  const MCSection *ConstDataSection;
+  const MCSection *DataCoalSection;
+  const MCSection *DataCommonSection;
+  const MCSection *DataBSSSection;
+  const MCSection *FourByteConstantSection;
+  const MCSection *EightByteConstantSection;
+  const MCSection *SixteenByteConstantSection;
+  const MCSection *LazySymbolPointerSection;
+  const MCSection *NonLazySymbolPointerSection;
+
+  /// COFF specific sections.
+  ///
+  const MCSection *DrectveSection;
+  const MCSection *PDataSection;
+  const MCSection *XDataSection;
+
+public:
+  void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
+                            MCContext &ctx);
+
+  bool getSupportsWeakOmittedEHFrame() const {
+    return SupportsWeakOmittedEHFrame;
+  }
+  bool getSupportsCompactUnwindWithoutEHFrame() const {
+    return SupportsCompactUnwindWithoutEHFrame;
+  }
+  bool getCommDirectiveSupportsAlignment() const {
+    return CommDirectiveSupportsAlignment;
+  }
+
+  unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
+  unsigned getLSDAEncoding() const { return LSDAEncoding; }
+  unsigned getFDEEncoding() const { return FDECFIEncoding; }
+  unsigned getTTypeEncoding() const { return TTypeEncoding; }
+
+  unsigned getCompactUnwindDwarfEHFrameOnly() const {
+    return CompactUnwindDwarfEHFrameOnly;
+  }
+
+  const MCSection *getTextSection() const { return TextSection; }
+  const MCSection *getDataSection() const { return DataSection; }
+  const MCSection *getBSSSection() const { return BSSSection; }
+  const MCSection *getLSDASection() const { return LSDASection; }
+  const MCSection *getCompactUnwindSection() const{
+    return CompactUnwindSection;
+  }
+  const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
+  const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
+  const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
+  const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+  const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}
+  const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
+  const MCSection *getDwarfGnuPubNamesSection() const {
+    return DwarfGnuPubNamesSection;
+  }
+  const MCSection *getDwarfGnuPubTypesSection() const {
+    return DwarfGnuPubTypesSection;
+  }
+  const MCSection *getDwarfDebugInlineSection() const {
+    return DwarfDebugInlineSection;
+  }
+  const MCSection *getDwarfStrSection() const { return DwarfStrSection; }
+  const MCSection *getDwarfLocSection() const { return DwarfLocSection; }
+  const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;}
+  const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
+  const MCSection *getDwarfMacroInfoSection() const {
+    return DwarfMacroInfoSection;
+  }
+
+  // DWARF5 Experimental Debug Info Sections
+  const MCSection *getDwarfAccelNamesSection() const {
+    return DwarfAccelNamesSection;
+  }
+  const MCSection *getDwarfAccelObjCSection() const {
+    return DwarfAccelObjCSection;
+  }
+  const MCSection *getDwarfAccelNamespaceSection() const {
+    return DwarfAccelNamespaceSection;
+  }
+  const MCSection *getDwarfAccelTypesSection() const {
+    return DwarfAccelTypesSection;
+  }
+  const MCSection *getDwarfInfoDWOSection() const {
+    return DwarfInfoDWOSection;
+  }
+  const MCSection *getDwarfTypesSection(uint64_t Hash) const;
+  const MCSection *getDwarfTypesDWOSection(uint64_t Hash) const;
+  const MCSection *getDwarfAbbrevDWOSection() const {
+    return DwarfAbbrevDWOSection;
+  }
+  const MCSection *getDwarfStrDWOSection() const {
+    return DwarfStrDWOSection;
+  }
+  const MCSection *getDwarfLineDWOSection() const {
+    return DwarfLineDWOSection;
+  }
+  const MCSection *getDwarfLocDWOSection() const {
+    return DwarfLocDWOSection;
+  }
+  const MCSection *getDwarfStrOffDWOSection() const {
+    return DwarfStrOffDWOSection;
+  }
+  const MCSection *getDwarfAddrSection() const {
+    return DwarfAddrSection;
+  }
+
+  const MCSection *getCOFFDebugSymbolsSection() const {
+    return COFFDebugSymbolsSection;
+  }
+
+  const MCSection *getTLSExtraDataSection() const {
+    return TLSExtraDataSection;
+  }
+  const MCSection *getTLSDataSection() const { return TLSDataSection; }
+  const MCSection *getTLSBSSSection() const { return TLSBSSSection; }
+
+  const MCSection *getStackMapSection() const { return StackMapSection; }
+
+  /// ELF specific sections.
+  ///
+  const MCSection *getDataRelSection() const { return DataRelSection; }
+  const MCSection *getDataRelLocalSection() const {
+    return DataRelLocalSection;
+  }
+  const MCSection *getDataRelROSection() const { return DataRelROSection; }
+  const MCSection *getDataRelROLocalSection() const {
+    return DataRelROLocalSection;
+  }
+  const MCSection *getMergeableConst4Section() const {
+    return MergeableConst4Section;
+  }
+  const MCSection *getMergeableConst8Section() const {
+    return MergeableConst8Section;
+  }
+  const MCSection *getMergeableConst16Section() const {
+    return MergeableConst16Section;
+  }
+
+  /// MachO specific sections.
+  ///
+  const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
+  const MCSection *getTLSThreadInitSection() const {
+    return TLSThreadInitSection;
+  }
+  const MCSection *getCStringSection() const { return CStringSection; }
+  const MCSection *getUStringSection() const { return UStringSection; }
+  const MCSection *getTextCoalSection() const { return TextCoalSection; }
+  const MCSection *getConstTextCoalSection() const {
+    return ConstTextCoalSection;
+  }
+  const MCSection *getConstDataSection() const { return ConstDataSection; }
+  const MCSection *getDataCoalSection() const { return DataCoalSection; }
+  const MCSection *getDataCommonSection() const { return DataCommonSection; }
+  const MCSection *getDataBSSSection() const { return DataBSSSection; }
+  const MCSection *getFourByteConstantSection() const {
+    return FourByteConstantSection;
+  }
+  const MCSection *getEightByteConstantSection() const {
+    return EightByteConstantSection;
+  }
+  const MCSection *getSixteenByteConstantSection() const {
+    return SixteenByteConstantSection;
+  }
+  const MCSection *getLazySymbolPointerSection() const {
+    return LazySymbolPointerSection;
+  }
+  const MCSection *getNonLazySymbolPointerSection() const {
+    return NonLazySymbolPointerSection;
+  }
+
+  /// COFF specific sections.
+  ///
+  const MCSection *getDrectveSection() const { return DrectveSection; }
+  const MCSection *getPDataSection() const { return PDataSection; }
+  const MCSection *getXDataSection() const { return XDataSection; }
+
+  const MCSection *getEHFrameSection() {
+    if (!EHFrameSection)
+      InitEHFrameSection();
+    return EHFrameSection;
+  }
+
+  enum Environment { IsMachO, IsELF, IsCOFF };
+  Environment getObjectFileType() const {
+    return Env;
+  }
+
+  Reloc::Model getRelocM() const {
+    return RelocM;
+  }
+
+private:
+  Environment Env;
+  Reloc::Model RelocM;
+  CodeModel::Model CMModel;
+  MCContext *Ctx;
+  Triple TT;
+
+  void InitMachOMCObjectFileInfo(Triple T);
+  void InitELFMCObjectFileInfo(Triple T);
+  void InitCOFFMCObjectFileInfo(Triple T);
+
+  /// InitEHFrameSection - Initialize EHFrameSection on demand.
+  ///
+  void InitEHFrameSection();
+
+public:
+  const Triple &getTargetTriple() const { return TT; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
new file mode 100644
index 0000000..8d37c85
--- /dev/null
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -0,0 +1,136 @@
+//===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTSTREAMER_H
+#define LLVM_MC_MCOBJECTSTREAMER_H
+
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+class MCAssembler;
+class MCCodeEmitter;
+class MCSectionData;
+class MCSubtargetInfo;
+class MCExpr;
+class MCFragment;
+class MCDataFragment;
+class MCAsmBackend;
+class raw_ostream;
+
+/// \brief Streaming object file generation interface.
+///
+/// This class provides an implementation of the MCStreamer interface which is
+/// suitable for use with the assembler backend. Specific object file formats
+/// are expected to subclass this interface to implement directives specific
+/// to that file format or custom semantics expected by the object writer
+/// implementation.
+class MCObjectStreamer : public MCStreamer {
+  MCAssembler *Assembler;
+  MCSectionData *CurSectionData;
+  MCSectionData::iterator CurInsertionPoint;
+  bool EmitEHFrame;
+  bool EmitDebugFrame;
+
+  virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
+  void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+  void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
+
+protected:
+  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
+                   MCCodeEmitter *_Emitter);
+  MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
+                   MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
+  ~MCObjectStreamer();
+
+public:
+  /// state management
+  void reset() override;
+
+  /// Object streamers require the integrated assembler.
+  bool isIntegratedAssemblerRequired() const override { return true; }
+
+  MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) {
+    return getAssembler().getOrCreateSymbolData(*Symbol);
+  }
+  void EmitFrames(MCAsmBackend *MAB);
+  void EmitCFISections(bool EH, bool Debug) override;
+
+protected:
+  MCSectionData *getCurrentSectionData() const {
+    return CurSectionData;
+  }
+
+  MCFragment *getCurrentFragment() const;
+
+  void insert(MCFragment *F) const {
+    CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
+    F->setParent(CurSectionData);
+  }
+
+  /// Get a data fragment to write into, creating a new one if the current
+  /// fragment is not a data fragment.
+  MCDataFragment *getOrCreateDataFragment() const;
+
+public:
+  void visitUsedSymbol(const MCSymbol &Sym) override;
+
+  MCAssembler &getAssembler() { return *Assembler; }
+
+  /// @name MCStreamer Interface
+  /// @{
+
+  void EmitLabel(MCSymbol *Symbol) override;
+  void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+  void EmitValueImpl(const MCExpr *Value, unsigned Size,
+                     const SMLoc &Loc = SMLoc()) override;
+  void EmitULEB128Value(const MCExpr *Value) override;
+  void EmitSLEB128Value(const MCExpr *Value) override;
+  void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+  void ChangeSection(const MCSection *Section,
+                     const MCExpr *Subsection) override;
+  void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override;
+
+  /// \brief Emit an instruction to a special fragment, because this instruction
+  /// can change its size during relaxation.
+  virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+
+  void EmitBundleAlignMode(unsigned AlignPow2) override;
+  void EmitBundleLock(bool AlignToEnd) override;
+  void EmitBundleUnlock() override;
+  void EmitBytes(StringRef Data) override;
+  void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+                            unsigned ValueSize = 1,
+                            unsigned MaxBytesToEmit = 0) override;
+  void EmitCodeAlignment(unsigned ByteAlignment,
+                         unsigned MaxBytesToEmit = 0) override;
+  bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override;
+  void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+                             unsigned Column, unsigned Flags,
+                             unsigned Isa, unsigned Discriminator,
+                             StringRef FileName) override;
+  void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
+                                const MCSymbol *Label,
+                                unsigned PointerSize);
+  void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+                                 const MCSymbol *Label);
+  void EmitGPRel32Value(const MCExpr *Value) override;
+  void EmitGPRel64Value(const MCExpr *Value) override;
+  void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+  void EmitZeros(uint64_t NumBytes) override;
+  void FinishImpl() override;
+
+  virtual bool mayHaveInstructions() const {
+    return getCurrentSectionData()->hasInstructions();
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCObjectSymbolizer.h b/include/llvm/MC/MCObjectSymbolizer.h
new file mode 100644
index 0000000..f75b7f5
--- /dev/null
+++ b/include/llvm/MC/MCObjectSymbolizer.h
@@ -0,0 +1,83 @@
+//===-- llvm/MC/MCObjectSymbolizer.h --------------------------------------===//
+//
+//                     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 MCObjectSymbolizer class, an MCSymbolizer that is
+// backed by an object::ObjectFile.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTSYMBOLIZER_H
+#define LLVM_MC_MCOBJECTSYMBOLIZER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/MC/MCSymbolizer.h"
+#include "llvm/Object/ObjectFile.h"
+#include <vector>
+
+namespace llvm {
+
+class MCExpr;
+class MCInst;
+class MCRelocationInfo;
+class raw_ostream;
+
+/// \brief An ObjectFile-backed symbolizer.
+class MCObjectSymbolizer : public MCSymbolizer {
+protected:
+  const object::ObjectFile *Obj;
+
+  // Map a load address to the first relocation that applies there. As far as I
+  // know, if there are several relocations at the exact same address, they are
+  // related and the others can be determined from the first that was found in
+  // the relocation table. For instance, on x86-64 mach-o, a SUBTRACTOR
+  // relocation (referencing the minuend symbol) is followed by an UNSIGNED
+  // relocation (referencing the subtrahend symbol).
+  const object::RelocationRef *findRelocationAt(uint64_t Addr);
+  const object::SectionRef *findSectionContaining(uint64_t Addr);
+
+  MCObjectSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
+                     const object::ObjectFile *Obj);
+
+public:
+  /// \name Overridden MCSymbolizer methods:
+  /// @{
+  bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
+                                int64_t Value, uint64_t Address,
+                                bool IsBranch, uint64_t Offset,
+                                uint64_t InstSize) override;
+
+  void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
+                                       int64_t Value,
+                                       uint64_t Address) override;
+  /// @}
+
+  /// \brief Look for an external function symbol at \p Addr.
+  /// (References through the ELF PLT, Mach-O stubs, and similar).
+  /// \returns An MCExpr representing the external symbol, or 0 if not found.
+  virtual StringRef findExternalFunctionAt(uint64_t Addr);
+
+  /// \brief Create an object symbolizer for \p Obj.
+  static MCObjectSymbolizer *
+  createObjectSymbolizer(MCContext &Ctx,
+                         std::unique_ptr<MCRelocationInfo> RelInfo,
+                         const object::ObjectFile *Obj);
+
+private:
+  typedef DenseMap<uint64_t, object::RelocationRef> AddrToRelocMap;
+  typedef std::vector<object::SectionRef> SortedSectionList;
+  SortedSectionList SortedSections;
+  AddrToRelocMap AddrToReloc;
+
+  void buildSectionList();
+  void buildRelocationByAddrMap();
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
new file mode 100644
index 0000000..55c828c
--- /dev/null
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -0,0 +1,200 @@
+//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCOBJECTWRITER_H
+#define LLVM_MC_MCOBJECTWRITER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmLayout;
+class MCAssembler;
+class MCFixup;
+class MCFragment;
+class MCSymbolData;
+class MCSymbolRefExpr;
+class MCValue;
+
+/// MCObjectWriter - Defines the object file and target independent interfaces
+/// used by the assembler backend to write native file format object files.
+///
+/// The object writer contains a few callbacks used by the assembler to allow
+/// the object writer to modify the assembler data structures at appropriate
+/// points. Once assembly is complete, the object writer is given the
+/// MCAssembler instance, which contains all the symbol and section data which
+/// should be emitted as part of WriteObject().
+///
+/// The object writer also contains a number of helper methods for writing
+/// binary data to the output stream.
+class MCObjectWriter {
+  MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
+
+protected:
+  raw_ostream &OS;
+
+  unsigned IsLittleEndian : 1;
+
+protected: // Can only create subclasses.
+  MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
+    : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
+
+public:
+  virtual ~MCObjectWriter();
+
+  /// lifetime management
+  virtual void reset() { }
+
+  bool isLittleEndian() const { return IsLittleEndian; }
+
+  raw_ostream &getStream() { return OS; }
+
+  /// @name High-Level API
+  /// @{
+
+  /// \brief Perform any late binding of symbols (for example, to assign symbol
+  /// indices for use when generating relocations).
+  ///
+  /// This routine is called by the assembler after layout and relaxation is
+  /// complete.
+  virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+                                        const MCAsmLayout &Layout) = 0;
+
+  /// \brief Record a relocation entry.
+  ///
+  /// This routine is called by the assembler after layout and relaxation, and
+  /// post layout binding. The implementation is responsible for storing
+  /// information about the relocation so that it can be emitted during
+  /// WriteObject().
+  virtual void RecordRelocation(const MCAssembler &Asm,
+                                const MCAsmLayout &Layout,
+                                const MCFragment *Fragment,
+                                const MCFixup &Fixup, MCValue Target,
+                                bool &IsPCRel,
+                                uint64_t &FixedValue) = 0;
+
+  /// \brief Check whether the difference (A - B) between two symbol
+  /// references is fully resolved.
+  ///
+  /// Clients are not required to answer precisely and may conservatively return
+  /// false, even when a difference is fully resolved.
+  bool
+  IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+                                     const MCSymbolRefExpr *A,
+                                     const MCSymbolRefExpr *B,
+                                     bool InSet) const;
+
+  virtual bool
+  IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+                                         const MCSymbolData &DataA,
+                                         const MCFragment &FB,
+                                         bool InSet,
+                                         bool IsPCRel) const;
+
+  /// \brief Write the object file.
+  ///
+  /// This routine is called by the assembler after layout and relaxation is
+  /// complete, fixups have been evaluated and applied, and relocations
+  /// generated.
+  virtual void WriteObject(MCAssembler &Asm,
+                           const MCAsmLayout &Layout) = 0;
+
+  /// @}
+  /// @name Binary Output
+  /// @{
+
+  void Write8(uint8_t Value) {
+    OS << char(Value);
+  }
+
+  void WriteLE16(uint16_t Value) {
+    Write8(uint8_t(Value >> 0));
+    Write8(uint8_t(Value >> 8));
+  }
+
+  void WriteLE32(uint32_t Value) {
+    WriteLE16(uint16_t(Value >> 0));
+    WriteLE16(uint16_t(Value >> 16));
+  }
+
+  void WriteLE64(uint64_t Value) {
+    WriteLE32(uint32_t(Value >> 0));
+    WriteLE32(uint32_t(Value >> 32));
+  }
+
+  void WriteBE16(uint16_t Value) {
+    Write8(uint8_t(Value >> 8));
+    Write8(uint8_t(Value >> 0));
+  }
+
+  void WriteBE32(uint32_t Value) {
+    WriteBE16(uint16_t(Value >> 16));
+    WriteBE16(uint16_t(Value >> 0));
+  }
+
+  void WriteBE64(uint64_t Value) {
+    WriteBE32(uint32_t(Value >> 32));
+    WriteBE32(uint32_t(Value >> 0));
+  }
+
+  void Write16(uint16_t Value) {
+    if (IsLittleEndian)
+      WriteLE16(Value);
+    else
+      WriteBE16(Value);
+  }
+
+  void Write32(uint32_t Value) {
+    if (IsLittleEndian)
+      WriteLE32(Value);
+    else
+      WriteBE32(Value);
+  }
+
+  void Write64(uint64_t Value) {
+    if (IsLittleEndian)
+      WriteLE64(Value);
+    else
+      WriteBE64(Value);
+  }
+
+  void WriteZeros(unsigned N) {
+    const char Zeros[16] = { 0 };
+
+    for (unsigned i = 0, e = N / 16; i != e; ++i)
+      OS << StringRef(Zeros, 16);
+
+    OS << StringRef(Zeros, N % 16);
+  }
+
+  void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
+    WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
+  }
+
+  void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+    // TODO: this version may need to go away once all fragment contents are
+    // converted to SmallVector<char, N>
+    assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
+      "data size greater than fill size, unexpected large write will occur");
+    OS << Str;
+    if (ZeroFillSize)
+      WriteZeros(ZeroFillSize - Str.size());
+  }
+
+  /// @}
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h
new file mode 100644
index 0000000..a918b56
--- /dev/null
+++ b/include/llvm/MC/MCParser/AsmCond.h
@@ -0,0 +1,40 @@
+//===- AsmCond.h - Assembly file conditional assembly  ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_ASMCOND_H
+#define LLVM_MC_MCPARSER_ASMCOND_H
+
+namespace llvm {
+
+/// AsmCond - Class to support conditional assembly
+///
+/// The conditional assembly feature (.if, .else, .elseif and .endif) is
+/// implemented with AsmCond that tells us what we are in the middle of 
+/// processing.  Ignore can be either true or false.  When true we are ignoring
+/// the block of code in the middle of a conditional.
+
+class AsmCond {
+public:
+  enum ConditionalAssemblyType {
+    NoCond,     // no conditional is being processed
+    IfCond,     // inside if conditional
+    ElseIfCond, // inside elseif conditional
+    ElseCond    // inside else conditional
+  };
+
+  ConditionalAssemblyType TheCond;
+  bool CondMet;
+  bool Ignore;
+
+  AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
new file mode 100644
index 0000000..0b550ba
--- /dev/null
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -0,0 +1,73 @@
+//===- AsmLexer.h - Lexer for Assembly 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 declares the lexer for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_ASMLEXER_H
+#define LLVM_MC_MCPARSER_ASMLEXER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+class MemoryBuffer;
+class MCAsmInfo;
+
+/// AsmLexer - Lexer class for assembly files.
+class AsmLexer : public MCAsmLexer {
+  const MCAsmInfo &MAI;
+
+  const char *CurPtr;
+  StringRef CurBuf;
+  bool isAtStartOfLine;
+
+  void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
+  AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION;
+
+protected:
+  /// LexToken - Read the next token and return its code.
+  AsmToken LexToken() override;
+
+public:
+  AsmLexer(const MCAsmInfo &MAI);
+  ~AsmLexer();
+
+  void setBuffer(StringRef Buf, const char *ptr = nullptr);
+
+  StringRef LexUntilEndOfStatement() override;
+  StringRef LexUntilEndOfLine();
+
+  const AsmToken peekTok(bool ShouldSkipSpace = true) override;
+
+  bool isAtStartOfComment(char Char);
+  bool isAtStatementSeparator(const char *Ptr);
+
+  const MCAsmInfo &getMAI() const { return MAI; }
+
+private:
+  int getNextChar();
+  AsmToken ReturnError(const char *Loc, const std::string &Msg);
+
+  AsmToken LexIdentifier();
+  AsmToken LexSlash();
+  AsmToken LexLineComment();
+  AsmToken LexDigit();
+  AsmToken LexSingleQuote();
+  AsmToken LexQuote();
+  AsmToken LexFloatLiteral();
+  AsmToken LexHexFloatLiteral(bool NoIntDigits);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
new file mode 100644
index 0000000..e3d4181
--- /dev/null
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -0,0 +1,194 @@
+//===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
+#define LLVM_MC_MCPARSER_MCASMLEXER_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+
+/// AsmToken - Target independent representation for an assembler token.
+class AsmToken {
+public:
+  enum TokenKind {
+    // Markers
+    Eof, Error,
+
+    // String values.
+    Identifier,
+    String,
+
+    // Integer values.
+    Integer,
+    BigNum, // larger than 64 bits
+
+    // Real values.
+    Real,
+
+    // No-value.
+    EndOfStatement,
+    Colon,
+    Space,
+    Plus, Minus, Tilde,
+    Slash,    // '/'
+    BackSlash, // '\'
+    LParen, RParen, LBrac, RBrac, LCurly, RCurly,
+    Star, Dot, Comma, Dollar, Equal, EqualEqual,
+
+    Pipe, PipePipe, Caret,
+    Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
+    Less, LessEqual, LessLess, LessGreater,
+    Greater, GreaterEqual, GreaterGreater, At
+  };
+
+private:
+  TokenKind Kind;
+
+  /// A reference to the entire token contents; this is always a pointer into
+  /// a memory buffer owned by the source manager.
+  StringRef Str;
+
+  APInt IntVal;
+
+public:
+  AsmToken() {}
+  AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
+    : Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
+  AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+    : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {}
+
+  TokenKind getKind() const { return Kind; }
+  bool is(TokenKind K) const { return Kind == K; }
+  bool isNot(TokenKind K) const { return Kind != K; }
+
+  SMLoc getLoc() const;
+  SMLoc getEndLoc() const;
+
+  /// getStringContents - Get the contents of a string token (without quotes).
+  StringRef getStringContents() const {
+    assert(Kind == String && "This token isn't a string!");
+    return Str.slice(1, Str.size() - 1);
+  }
+
+  /// getIdentifier - Get the identifier string for the current token, which
+  /// should be an identifier or a string. This gets the portion of the string
+  /// which should be used as the identifier, e.g., it does not include the
+  /// quotes on strings.
+  StringRef getIdentifier() const {
+    if (Kind == Identifier)
+      return getString();
+    return getStringContents();
+  }
+
+  /// getString - Get the string for the current token, this includes all
+  /// characters (for example, the quotes on strings) in the token.
+  ///
+  /// The returned StringRef points into the source manager's memory buffer, and
+  /// is safe to store across calls to Lex().
+  StringRef getString() const { return Str; }
+
+  // FIXME: Don't compute this in advance, it makes every token larger, and is
+  // also not generally what we want (it is nicer for recovery etc. to lex 123br
+  // as a single token, then diagnose as an invalid number).
+  int64_t getIntVal() const {
+    assert(Kind == Integer && "This token isn't an integer!");
+    return IntVal.getZExtValue();
+  }
+
+  APInt getAPIntVal() const {
+    assert((Kind == Integer || Kind == BigNum) &&
+           "This token isn't an integer!");
+    return IntVal;
+  }
+};
+
+/// MCAsmLexer - Generic assembler lexer interface, for use by target specific
+/// assembly lexers.
+class MCAsmLexer {
+  /// The current token, stored in the base class for faster access.
+  AsmToken CurTok;
+
+  /// The location and description of the current error
+  SMLoc ErrLoc;
+  std::string Err;
+
+  MCAsmLexer(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
+protected: // Can only create subclasses.
+  const char *TokStart;
+  bool SkipSpace;
+  bool AllowAtInIdentifier;
+
+  MCAsmLexer();
+
+  virtual AsmToken LexToken() = 0;
+
+  void SetError(const SMLoc &errLoc, const std::string &err) {
+    ErrLoc = errLoc;
+    Err = err;
+  }
+
+public:
+  virtual ~MCAsmLexer();
+
+  /// Lex - Consume the next token from the input stream and return it.
+  ///
+  /// The lexer will continuosly return the end-of-file token once the end of
+  /// the main input file has been reached.
+  const AsmToken &Lex() {
+    return CurTok = LexToken();
+  }
+
+  virtual StringRef LexUntilEndOfStatement() = 0;
+
+  /// getLoc - Get the current source location.
+  SMLoc getLoc() const;
+
+  /// getTok - Get the current (last) lexed token.
+  const AsmToken &getTok() {
+    return CurTok;
+  }
+
+  /// peekTok - Look ahead at the next token to be lexed.
+  virtual const AsmToken peekTok(bool ShouldSkipSpace = true) = 0;
+
+  /// getErrLoc - Get the current error location
+  const SMLoc &getErrLoc() {
+    return ErrLoc;
+  }
+
+  /// getErr - Get the current error string
+  const std::string &getErr() {
+    return Err;
+  }
+
+  /// getKind - Get the kind of current token.
+  AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
+
+  /// is - Check if the current token has kind \p K.
+  bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
+
+  /// isNot - Check if the current token has kind \p K.
+  bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
+
+  /// setSkipSpace - Set whether spaces should be ignored by the lexer
+  void setSkipSpace(bool val) { SkipSpace = val; }
+
+  bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
+  void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
new file mode 100644
index 0000000..9836795
--- /dev/null
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -0,0 +1,205 @@
+//===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
+#define LLVM_MC_MCPARSER_MCASMPARSER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCAsmInfo;
+class MCAsmLexer;
+class MCAsmParserExtension;
+class MCContext;
+class MCExpr;
+class MCInstPrinter;
+class MCInstrInfo;
+class MCStreamer;
+class MCTargetAsmParser;
+class SMLoc;
+class SMRange;
+class SourceMgr;
+class Twine;
+
+class InlineAsmIdentifierInfo {
+public:
+  void *OpDecl;
+  bool IsVarDecl;
+  unsigned Length, Size, Type;
+
+  void clear() {
+    OpDecl = nullptr;
+    IsVarDecl = false;
+    Length = 1;
+    Size = 0;
+    Type = 0;
+  }
+};
+
+/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
+class MCAsmParserSemaCallback {
+public:
+  virtual ~MCAsmParserSemaCallback();
+  virtual void *LookupInlineAsmIdentifier(StringRef &LineBuf,
+                                          InlineAsmIdentifierInfo &Info,
+                                          bool IsUnevaluatedContext) = 0;
+
+  virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                                    unsigned &Offset) = 0;
+};
+
+/// MCAsmParser - Generic assembler parser interface, for use by target specific
+/// assembly parsers.
+class MCAsmParser {
+public:
+  typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
+  typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
+    ExtensionDirectiveHandler;
+
+private:
+  MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCAsmParser &) LLVM_DELETED_FUNCTION;
+
+  MCTargetAsmParser *TargetParser;
+
+  unsigned ShowParsedOperands : 1;
+
+protected: // Can only create subclasses.
+  MCAsmParser();
+
+public:
+  virtual ~MCAsmParser();
+
+  virtual void addDirectiveHandler(StringRef Directive,
+                                   ExtensionDirectiveHandler Handler) = 0;
+
+  virtual SourceMgr &getSourceManager() = 0;
+
+  virtual MCAsmLexer &getLexer() = 0;
+
+  virtual MCContext &getContext() = 0;
+
+  /// getStreamer - Return the output streamer for the assembler.
+  virtual MCStreamer &getStreamer() = 0;
+
+  MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
+  void setTargetParser(MCTargetAsmParser &P);
+
+  virtual unsigned getAssemblerDialect() { return 0;}
+  virtual void setAssemblerDialect(unsigned i) { }
+
+  bool getShowParsedOperands() const { return ShowParsedOperands; }
+  void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
+
+  /// Run - Run the parser on the input source buffer.
+  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
+
+  virtual void setParsingInlineAsm(bool V) = 0;
+  virtual bool isParsingInlineAsm() = 0;
+
+  /// parseMSInlineAsm - Parse ms-style inline assembly.
+  virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+                                unsigned &NumOutputs, unsigned &NumInputs,
+                                SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
+                                SmallVectorImpl<std::string> &Constraints,
+                                SmallVectorImpl<std::string> &Clobbers,
+                                const MCInstrInfo *MII,
+                                const MCInstPrinter *IP,
+                                MCAsmParserSemaCallback &SI) = 0;
+
+  /// Note - Emit a note at the location \p L, with the message \p Msg.
+  virtual void Note(SMLoc L, const Twine &Msg,
+                    ArrayRef<SMRange> Ranges = None) = 0;
+
+  /// Warning - Emit a warning at the location \p L, with the message \p Msg.
+  ///
+  /// \return The return value is true, if warnings are fatal.
+  virtual bool Warning(SMLoc L, const Twine &Msg,
+                       ArrayRef<SMRange> Ranges = None) = 0;
+
+  /// Error - Emit an error at the location \p L, with the message \p Msg.
+  ///
+  /// \return The return value is always true, as an idiomatic convenience to
+  /// clients.
+  virtual bool Error(SMLoc L, const Twine &Msg,
+                     ArrayRef<SMRange> Ranges = None) = 0;
+
+  /// Lex - Get the next AsmToken in the stream, possibly handling file
+  /// inclusion first.
+  virtual const AsmToken &Lex() = 0;
+
+  /// getTok - Get the current AsmToken from the stream.
+  const AsmToken &getTok();
+
+  /// \brief Report an error at the current lexer location.
+  bool TokError(const Twine &Msg, ArrayRef<SMRange> Ranges = None);
+
+  /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
+  /// and set \p Res to the identifier contents.
+  virtual bool parseIdentifier(StringRef &Res) = 0;
+
+  /// \brief Parse up to the end of statement and return the contents from the
+  /// current token until the end of the statement; the current token on exit
+  /// will be either the EndOfStatement or EOF.
+  virtual StringRef parseStringToEndOfStatement() = 0;
+
+  /// parseEscapedString - Parse the current token as a string which may include
+  /// escaped characters and return the string contents.
+  virtual bool parseEscapedString(std::string &Data) = 0;
+
+  /// eatToEndOfStatement - Skip to the end of the current statement, for error
+  /// recovery.
+  virtual void eatToEndOfStatement() = 0;
+
+  /// parseExpression - Parse an arbitrary expression.
+  ///
+  /// @param Res - The value of the expression. The result is undefined
+  /// on error.
+  /// @result - False on success.
+  virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+  bool parseExpression(const MCExpr *&Res);
+
+  /// parsePrimaryExpr - Parse a primary expression.
+  ///
+  /// @param Res - The value of the expression. The result is undefined
+  /// on error.
+  /// @result - False on success.
+  virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+
+  /// parseParenExpression - Parse an arbitrary expression, assuming that an
+  /// initial '(' has already been consumed.
+  ///
+  /// @param Res - The value of the expression. The result is undefined
+  /// on error.
+  /// @result - False on success.
+  virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+
+  /// parseAbsoluteExpression - Parse an expression which must evaluate to an
+  /// absolute value.
+  ///
+  /// @param Res - The value of the absolute expression. The result is undefined
+  /// on error.
+  /// @result - False on success.
+  virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
+
+  /// checkForValidSection - Ensure that we have a valid section set in the
+  /// streamer. Otherwise, report an error and switch to .text.
+  virtual void checkForValidSection() = 0;
+};
+
+/// \brief Create an MCAsmParser instance.
+MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &,
+                               MCStreamer &, const MCAsmInfo &);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
new file mode 100644
index 0000000..2eda3a9
--- /dev/null
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -0,0 +1,80 @@
+//===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class Twine;
+
+/// \brief Generic interface for extending the MCAsmParser,
+/// which is implemented by target and object file assembly parser
+/// implementations.
+class MCAsmParserExtension {
+  MCAsmParserExtension(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCAsmParserExtension &) LLVM_DELETED_FUNCTION;
+
+  MCAsmParser *Parser;
+
+protected:
+  MCAsmParserExtension();
+
+  // Helper template for implementing static dispatch functions.
+  template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
+  static bool HandleDirective(MCAsmParserExtension *Target,
+                              StringRef Directive,
+                              SMLoc DirectiveLoc) {
+    T *Obj = static_cast<T*>(Target);
+    return (Obj->*Handler)(Directive, DirectiveLoc);
+  }
+
+  bool BracketExpressionsSupported;
+
+public:
+  virtual ~MCAsmParserExtension();
+
+  /// \brief Initialize the extension for parsing using the given \p Parser.
+  /// The extension should use the AsmParser interfaces to register its
+  /// parsing routines.
+  virtual void Initialize(MCAsmParser &Parser);
+
+  /// @name MCAsmParser Proxy Interfaces
+  /// @{
+
+  MCContext &getContext() { return getParser().getContext(); }
+  MCAsmLexer &getLexer() { return getParser().getLexer(); }
+  MCAsmParser &getParser() { return *Parser; }
+  SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
+  MCStreamer &getStreamer() { return getParser().getStreamer(); }
+  bool Warning(SMLoc L, const Twine &Msg) {
+    return getParser().Warning(L, Msg);
+  }
+  bool Error(SMLoc L, const Twine &Msg) {
+    return getParser().Error(L, Msg);
+  }
+  bool TokError(const Twine &Msg) {
+    return getParser().TokError(Msg);
+  }
+
+  const AsmToken &Lex() { return getParser().Lex(); }
+
+  const AsmToken &getTok() { return getParser().getTok(); }
+
+  bool HasBracketExpressions() const { return BracketExpressionsSupported; }
+
+  /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
new file mode 100644
index 0000000..e8740aa
--- /dev/null
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -0,0 +1,87 @@
+//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+
+namespace llvm {
+class SMLoc;
+class raw_ostream;
+
+/// MCParsedAsmOperand - This abstract class represents a source-level assembly
+/// instruction operand.  It should be subclassed by target-specific code.  This
+/// base class is used by target-independent clients and is the interface
+/// between parsing an asm instruction and recognizing it.
+class MCParsedAsmOperand {
+  /// MCOperandNum - The corresponding MCInst operand number.  Only valid when
+  /// parsing MS-style inline assembly.
+  unsigned MCOperandNum;
+
+  /// Constraint - The constraint on this operand.  Only valid when parsing
+  /// MS-style inline assembly.
+  std::string Constraint;
+
+public:
+  MCParsedAsmOperand() {}
+  virtual ~MCParsedAsmOperand() {}
+
+  void setConstraint(StringRef C) { Constraint = C.str(); }
+  StringRef getConstraint() { return Constraint; }
+
+  void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
+  unsigned getMCOperandNum() { return MCOperandNum; }
+
+  virtual StringRef getSymName() { return StringRef(); }
+  virtual void *getOpDecl() { return nullptr; }
+
+  /// isToken - Is this a token operand?
+  virtual bool isToken() const = 0;
+  /// isImm - Is this an immediate operand?
+  virtual bool isImm() const = 0;
+  /// isReg - Is this a register operand?
+  virtual bool isReg() const = 0;
+  virtual unsigned getReg() const = 0;
+
+  /// isMem - Is this a memory operand?
+  virtual bool isMem() const = 0;
+
+  /// getStartLoc - Get the location of the first token of this operand.
+  virtual SMLoc getStartLoc() const = 0;
+  /// getEndLoc - Get the location of the last token of this operand.
+  virtual SMLoc getEndLoc() const = 0;
+
+  /// needAddressOf - Do we need to emit code to get the address of the
+  /// variable/label?   Only valid when parsing MS-style inline assembly.
+  virtual bool needAddressOf() const { return false; }
+
+  /// isOffsetOf - Do we need to emit code to get the offset of the variable,
+  /// rather then the value of the variable?   Only valid when parsing MS-style
+  /// inline assembly.
+  virtual bool isOffsetOf() const { return false; }
+
+  /// getOffsetOfLoc - Get the location of the offset operator.
+  virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
+
+  /// print - Print a debug representation of the operand to the given stream.
+  virtual void print(raw_ostream &OS) const = 0;
+  /// dump - Print to the debug stream.
+  virtual void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
+  MO.print(OS);
+  return OS;
+}
+
+} // end namespace llvm.
+
+#endif
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
new file mode 100644
index 0000000..766f631
--- /dev/null
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -0,0 +1,616 @@
+//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file.  This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCREGISTERINFO_H
+#define LLVM_MC_MCREGISTERINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+
+/// An unsigned integer type large enough to represent all physical registers,
+/// but not necessarily virtual registers.
+typedef uint16_t MCPhysReg;
+
+/// MCRegisterClass - Base class of TargetRegisterClass.
+class MCRegisterClass {
+public:
+  typedef const MCPhysReg* iterator;
+  typedef const MCPhysReg* const_iterator;
+
+  const char *Name;
+  const iterator RegsBegin;
+  const uint8_t *const RegSet;
+  const uint16_t RegsSize;
+  const uint16_t RegSetSize;
+  const uint16_t ID;
+  const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes
+  const int8_t CopyCost;
+  const bool Allocatable;
+
+  /// getID() - Return the register class ID number.
+  ///
+  unsigned getID() const { return ID; }
+
+  /// getName() - Return the register class name for debugging.
+  ///
+  const char *getName() const { return Name; }
+
+  /// begin/end - Return all of the registers in this class.
+  ///
+  iterator       begin() const { return RegsBegin; }
+  iterator         end() const { return RegsBegin + RegsSize; }
+
+  /// getNumRegs - Return the number of registers in this class.
+  ///
+  unsigned getNumRegs() const { return RegsSize; }
+
+  /// getRegister - Return the specified register in the class.
+  ///
+  unsigned getRegister(unsigned i) const {
+    assert(i < getNumRegs() && "Register number out of range!");
+    return RegsBegin[i];
+  }
+
+  /// contains - Return true if the specified register is included in this
+  /// register class.  This does not include virtual registers.
+  bool contains(unsigned Reg) const {
+    unsigned InByte = Reg % 8;
+    unsigned Byte = Reg / 8;
+    if (Byte >= RegSetSize)
+      return false;
+    return (RegSet[Byte] & (1 << InByte)) != 0;
+  }
+
+  /// contains - Return true if both registers are in this class.
+  bool contains(unsigned Reg1, unsigned Reg2) const {
+    return contains(Reg1) && contains(Reg2);
+  }
+
+  /// getSize - Return the size of the register in bytes, which is also the size
+  /// of a stack slot allocated to hold a spilled copy of this register.
+  unsigned getSize() const { return RegSize; }
+
+  /// getAlignment - Return the minimum required alignment for a register of
+  /// this class.
+  unsigned getAlignment() const { return Alignment; }
+
+  /// getCopyCost - Return the cost of copying a value between two registers in
+  /// this class. A negative number means the register class is very expensive
+  /// to copy e.g. status flag register classes.
+  int getCopyCost() const { return CopyCost; }
+
+  /// isAllocatable - Return true if this register class may be used to create
+  /// virtual registers.
+  bool isAllocatable() const { return Allocatable; }
+};
+
+/// MCRegisterDesc - This record contains information about a particular
+/// register.  The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers
+/// of AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are
+/// super-registers of AX.
+///
+struct MCRegisterDesc {
+  uint32_t Name;      // Printable name for the reg (for debugging)
+  uint32_t SubRegs;   // Sub-register set, described above
+  uint32_t SuperRegs; // Super-register set, described above
+
+  // Offset into MCRI::SubRegIndices of a list of sub-register indices for each
+  // sub-register in SubRegs.
+  uint32_t SubRegIndices;
+
+  // RegUnits - Points to the list of register units. The low 4 bits holds the
+  // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
+  uint32_t RegUnits;
+};
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has.  As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+class MCRegisterInfo {
+public:
+  typedef const MCRegisterClass *regclass_iterator;
+
+  /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
+  /// performed with a binary search.
+  struct DwarfLLVMRegPair {
+    unsigned FromReg;
+    unsigned ToReg;
+
+    bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; }
+  };
+
+  /// SubRegCoveredBits - Emitted by tablegen: bit range covered by a subreg
+  /// index, -1 in any being invalid.
+  struct SubRegCoveredBits {
+    uint16_t Offset;
+    uint16_t Size;
+  };
+private:
+  const MCRegisterDesc *Desc;                 // Pointer to the descriptor array
+  unsigned NumRegs;                           // Number of entries in the array
+  unsigned RAReg;                             // Return address register
+  unsigned PCReg;                             // Program counter register
+  const MCRegisterClass *Classes;             // Pointer to the regclass array
+  unsigned NumClasses;                        // Number of entries in the array
+  unsigned NumRegUnits;                       // Number of regunits.
+  const MCPhysReg (*RegUnitRoots)[2];         // Pointer to regunit root table.
+  const MCPhysReg *DiffLists;                 // Pointer to the difflists array
+  const char *RegStrings;                     // Pointer to the string table.
+  const uint16_t *SubRegIndices;              // Pointer to the subreg lookup
+                                              // array.
+  const SubRegCoveredBits *SubRegIdxRanges;   // Pointer to the subreg covered
+                                              // bit ranges array.
+  unsigned NumSubRegIndices;                  // Number of subreg indices.
+  const uint16_t *RegEncodingTable;           // Pointer to array of register
+                                              // encodings.
+
+  unsigned L2DwarfRegsSize;
+  unsigned EHL2DwarfRegsSize;
+  unsigned Dwarf2LRegsSize;
+  unsigned EHDwarf2LRegsSize;
+  const DwarfLLVMRegPair *L2DwarfRegs;        // LLVM to Dwarf regs mapping
+  const DwarfLLVMRegPair *EHL2DwarfRegs;      // LLVM to Dwarf regs mapping EH
+  const DwarfLLVMRegPair *Dwarf2LRegs;        // Dwarf to LLVM regs mapping
+  const DwarfLLVMRegPair *EHDwarf2LRegs;      // Dwarf to LLVM regs mapping EH
+  DenseMap<unsigned, int> L2SEHRegs;          // LLVM to SEH regs mapping
+
+public:
+  /// DiffListIterator - Base iterator class that can traverse the
+  /// differentially encoded register and regunit lists in DiffLists.
+  /// Don't use this class directly, use one of the specialized sub-classes
+  /// defined below.
+  class DiffListIterator {
+    uint16_t Val;
+    const MCPhysReg *List;
+
+  protected:
+    /// Create an invalid iterator. Call init() to point to something useful.
+    DiffListIterator() : Val(0), List(nullptr) {}
+
+    /// init - Point the iterator to InitVal, decoding subsequent values from
+    /// DiffList. The iterator will initially point to InitVal, sub-classes are
+    /// responsible for skipping the seed value if it is not part of the list.
+    void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {
+      Val = InitVal;
+      List = DiffList;
+    }
+
+    /// advance - Move to the next list position, return the applied
+    /// differential. This function does not detect the end of the list, that
+    /// is the caller's responsibility (by checking for a 0 return value).
+    unsigned advance() {
+      assert(isValid() && "Cannot move off the end of the list.");
+      MCPhysReg D = *List++;
+      Val += D;
+      return D;
+    }
+
+  public:
+
+    /// isValid - returns true if this iterator is not yet at the end.
+    bool isValid() const { return List; }
+
+    /// Dereference the iterator to get the value at the current position.
+    unsigned operator*() const { return Val; }
+
+    /// Pre-increment to move to the next position.
+    void operator++() {
+      // The end of the list is encoded as a 0 differential.
+      if (!advance())
+        List = nullptr;
+    }
+  };
+
+  // These iterators are allowed to sub-class DiffListIterator and access
+  // internal list pointers.
+  friend class MCSubRegIterator;
+  friend class MCSuperRegIterator;
+  friend class MCRegUnitIterator;
+  friend class MCRegUnitRootIterator;
+
+  /// \brief Initialize MCRegisterInfo, called by TableGen
+  /// auto-generated routines. *DO NOT USE*.
+  void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+                          unsigned PC,
+                          const MCRegisterClass *C, unsigned NC,
+                          const MCPhysReg (*RURoots)[2],
+                          unsigned NRU,
+                          const MCPhysReg *DL,
+                          const char *Strings,
+                          const uint16_t *SubIndices,
+                          unsigned NumIndices,
+                          const SubRegCoveredBits *SubIdxRanges,
+                          const uint16_t *RET) {
+    Desc = D;
+    NumRegs = NR;
+    RAReg = RA;
+    PCReg = PC;
+    Classes = C;
+    DiffLists = DL;
+    RegStrings = Strings;
+    NumClasses = NC;
+    RegUnitRoots = RURoots;
+    NumRegUnits = NRU;
+    SubRegIndices = SubIndices;
+    NumSubRegIndices = NumIndices;
+    SubRegIdxRanges = SubIdxRanges;
+    RegEncodingTable = RET;
+  }
+
+  /// \brief Used to initialize LLVM register to Dwarf
+  /// register number mapping. Called by TableGen auto-generated routines.
+  /// *DO NOT USE*.
+  void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
+                              bool isEH) {
+    if (isEH) {
+      EHL2DwarfRegs = Map;
+      EHL2DwarfRegsSize = Size;
+    } else {
+      L2DwarfRegs = Map;
+      L2DwarfRegsSize = Size;
+    }
+  }
+
+  /// \brief Used to initialize Dwarf register to LLVM
+  /// register number mapping. Called by TableGen auto-generated routines.
+  /// *DO NOT USE*.
+  void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
+                              bool isEH) {
+    if (isEH) {
+      EHDwarf2LRegs = Map;
+      EHDwarf2LRegsSize = Size;
+    } else {
+      Dwarf2LRegs = Map;
+      Dwarf2LRegsSize = Size;
+    }
+  }
+
+  /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register
+  /// number mapping. By default the SEH register number is just the same
+  /// as the LLVM register number.
+  /// FIXME: TableGen these numbers. Currently this requires target specific
+  /// initialization code.
+  void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) {
+    L2SEHRegs[LLVMReg] = SEHReg;
+  }
+
+  /// \brief This method should return the register where the return
+  /// address can be found.
+  unsigned getRARegister() const {
+    return RAReg;
+  }
+
+  /// Return the register which is the program counter.
+  unsigned getProgramCounter() const {
+    return PCReg;
+  }
+
+  const MCRegisterDesc &operator[](unsigned RegNo) const {
+    assert(RegNo < NumRegs &&
+           "Attempting to access record for invalid register number!");
+    return Desc[RegNo];
+  }
+
+  /// \brief Provide a get method, equivalent to [], but more useful with a
+  /// pointer to this object.
+  const MCRegisterDesc &get(unsigned RegNo) const {
+    return operator[](RegNo);
+  }
+
+  /// \brief Returns the physical register number of sub-register "Index"
+  /// for physical register RegNo. Return zero if the sub-register does not
+  /// exist.
+  unsigned getSubReg(unsigned Reg, unsigned Idx) const;
+
+  /// \brief Return a super-register of the specified register
+  /// Reg so its sub-register of index SubIdx is Reg.
+  unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
+                               const MCRegisterClass *RC) const;
+
+  /// \brief For a given register pair, return the sub-register index
+  /// if the second register is a sub-register of the first. Return zero
+  /// otherwise.
+  unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
+
+  /// \brief Get the size of the bit range covered by a sub-register index.
+  /// If the index isn't continuous, return the sum of the sizes of its parts.
+  /// If the index is used to access subregisters of different sizes, return -1.
+  unsigned getSubRegIdxSize(unsigned Idx) const;
+
+  /// \brief Get the offset of the bit range covered by a sub-register index.
+  /// If an Offset doesn't make sense (the index isn't continuous, or is used to
+  /// access sub-registers at different offsets), return -1.
+  unsigned getSubRegIdxOffset(unsigned Idx) const;
+
+  /// \brief Return the human-readable symbolic target-specific name for the
+  /// specified physical register.
+  const char *getName(unsigned RegNo) const {
+    return RegStrings + get(RegNo).Name;
+  }
+
+  /// \brief Return the number of registers this target has (useful for
+  /// sizing arrays holding per register information)
+  unsigned getNumRegs() const {
+    return NumRegs;
+  }
+
+  /// \brief Return the number of sub-register indices
+  /// understood by the target. Index 0 is reserved for the no-op sub-register,
+  /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.
+  unsigned getNumSubRegIndices() const {
+    return NumSubRegIndices;
+  }
+
+  /// \brief Return the number of (native) register units in the
+  /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
+  /// can be accessed through MCRegUnitIterator defined below.
+  unsigned getNumRegUnits() const {
+    return NumRegUnits;
+  }
+
+  /// \brief Map a target register to an equivalent dwarf register
+  /// number.  Returns -1 if there is no equivalent value.  The second
+  /// parameter allows targets to use different numberings for EH info and
+  /// debugging info.
+  int getDwarfRegNum(unsigned RegNum, bool isEH) const;
+
+  /// \brief Map a dwarf register back to a target register.
+  int getLLVMRegNum(unsigned RegNum, bool isEH) const;
+
+  /// \brief Map a target register to an equivalent SEH register
+  /// number.  Returns LLVM register number if there is no equivalent value.
+  int getSEHRegNum(unsigned RegNum) const;
+
+  regclass_iterator regclass_begin() const { return Classes; }
+  regclass_iterator regclass_end() const { return Classes+NumClasses; }
+
+  unsigned getNumRegClasses() const {
+    return (unsigned)(regclass_end()-regclass_begin());
+  }
+
+  /// \brief Returns the register class associated with the enumeration
+  /// value.  See class MCOperandInfo.
+  const MCRegisterClass& getRegClass(unsigned i) const {
+    assert(i < getNumRegClasses() && "Register Class ID out of range");
+    return Classes[i];
+  }
+
+   /// \brief Returns the encoding for RegNo
+  uint16_t getEncodingValue(unsigned RegNo) const {
+    assert(RegNo < NumRegs &&
+           "Attempting to get encoding for invalid register number!");
+    return RegEncodingTable[RegNo];
+  }
+
+  /// \brief Returns true if RegB is a sub-register of RegA.
+  bool isSubRegister(unsigned RegA, unsigned RegB) const {
+    return isSuperRegister(RegB, RegA);
+  }
+
+  /// \brief Returns true if RegB is a super-register of RegA.
+  bool isSuperRegister(unsigned RegA, unsigned RegB) const;
+
+  /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA.
+  bool isSubRegisterEq(unsigned RegA, unsigned RegB) const {
+    return isSuperRegisterEq(RegB, RegA);
+  }
+
+  /// \brief Returns true if RegB is a super-register of RegA or if
+  /// RegB == RegA.
+  bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const {
+    return RegA == RegB || isSuperRegister(RegA, RegB);
+  }
+
+};
+
+//===----------------------------------------------------------------------===//
+//                          Register List Iterators
+//===----------------------------------------------------------------------===//
+
+// MCRegisterInfo provides lists of super-registers, sub-registers, and
+// aliasing registers. Use these iterator classes to traverse the lists.
+
+/// MCSubRegIterator enumerates all sub-registers of Reg.
+/// If IncludeSelf is set, Reg itself is included in the list.
+class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+  MCSubRegIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+                     bool IncludeSelf = false) {
+    init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs);
+    // Initially, the iterator points to Reg itself.
+    if (!IncludeSelf)
+      ++*this;
+  }
+};
+
+/// MCSuperRegIterator enumerates all super-registers of Reg.
+/// If IncludeSelf is set, Reg itself is included in the list.
+class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
+public:
+  MCSuperRegIterator() {}
+  MCSuperRegIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+                     bool IncludeSelf = false) {
+    init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
+    // Initially, the iterator points to Reg itself.
+    if (!IncludeSelf)
+      ++*this;
+  }
+};
+
+// Definition for isSuperRegister. Put it down here since it needs the
+// iterator defined above in addition to the MCRegisterInfo class itself.
+inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{
+  for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
+    if (*I == RegB)
+      return true;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+//                               Register Units
+//===----------------------------------------------------------------------===//
+
+// Register units are used to compute register aliasing. Every register has at
+// least one register unit, but it can have more. Two registers overlap if and
+// only if they have a common register unit.
+//
+// A target with a complicated sub-register structure will typically have many
+// fewer register units than actual registers. MCRI::getNumRegUnits() returns
+// the number of register units in the target.
+
+// MCRegUnitIterator enumerates a list of register units for Reg. The list is
+// in ascending numerical order.
+class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
+public:
+  /// MCRegUnitIterator - Create an iterator that traverses the register units
+  /// in Reg.
+  MCRegUnitIterator() {}
+  MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+    assert(Reg && "Null register has no regunits");
+    // Decode the RegUnits MCRegisterDesc field.
+    unsigned RU = MCRI->get(Reg).RegUnits;
+    unsigned Scale = RU & 15;
+    unsigned Offset = RU >> 4;
+
+    // Initialize the iterator to Reg * Scale, and the List pointer to
+    // DiffLists + Offset.
+    init(Reg * Scale, MCRI->DiffLists + Offset);
+
+    // That may not be a valid unit, we need to advance by one to get the real
+    // unit number. The first differential can be 0 which would normally
+    // terminate the list, but since we know every register has at least one
+    // unit, we can allow a 0 differential here.
+    advance();
+  }
+};
+
+// Each register unit has one or two root registers. The complete set of
+// registers containing a register unit is the union of the roots and their
+// super-registers. All registers aliasing Unit can be visited like this:
+//
+//   for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) {
+//     for (MCSuperRegIterator SI(*RI, MCRI, true); SI.isValid(); ++SI)
+//       visit(*SI);
+//    }
+
+/// MCRegUnitRootIterator enumerates the root registers of a register unit.
+class MCRegUnitRootIterator {
+  uint16_t Reg0;
+  uint16_t Reg1;
+public:
+  MCRegUnitRootIterator() : Reg0(0), Reg1(0) {}
+  MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
+    assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
+    Reg0 = MCRI->RegUnitRoots[RegUnit][0];
+    Reg1 = MCRI->RegUnitRoots[RegUnit][1];
+  }
+
+  /// \brief Dereference to get the current root register.
+  unsigned operator*() const {
+    return Reg0;
+  }
+
+  /// \brief Check if the iterator is at the end of the list.
+  bool isValid() const {
+    return Reg0;
+  }
+
+  /// \brief Preincrement to move to the next root register.
+  void operator++() {
+    assert(isValid() && "Cannot move off the end of the list.");
+    Reg0 = Reg1;
+    Reg1 = 0;
+  }
+};
+
+/// MCRegAliasIterator enumerates all registers aliasing Reg.  If IncludeSelf is
+/// set, Reg itself is included in the list.  This iterator does not guarantee
+/// any ordering or that entries are unique.
+class MCRegAliasIterator {
+private:
+  unsigned Reg;
+  const MCRegisterInfo *MCRI;
+  bool IncludeSelf;
+  
+  MCRegUnitIterator RI;
+  MCRegUnitRootIterator RRI;
+  MCSuperRegIterator SI;
+public:
+  MCRegAliasIterator(unsigned Reg, const MCRegisterInfo *MCRI,
+                     bool IncludeSelf)
+    : Reg(Reg), MCRI(MCRI), IncludeSelf(IncludeSelf) {
+
+    // Initialize the iterators.
+    for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
+      for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
+        for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {
+          if (!(!IncludeSelf && Reg == *SI))
+            return;
+        }
+      }
+    }
+  }
+
+  bool isValid() const {
+    return RI.isValid();
+  }
+  
+  unsigned operator*() const {
+    assert (SI.isValid() && "Cannot dereference an invalid iterator.");
+    return *SI;
+  }
+
+  void advance() {
+    // Assuming SI is valid.
+    ++SI;
+    if (SI.isValid()) return;
+
+    ++RRI;
+    if (RRI.isValid()) {
+      SI = MCSuperRegIterator(*RRI, MCRI, true);
+      return;
+    }
+
+    ++RI;
+    if (RI.isValid()) {
+      RRI = MCRegUnitRootIterator(*RI, MCRI);
+      SI = MCSuperRegIterator(*RRI, MCRI, true);
+    }
+  }
+
+  void operator++() {
+    assert(isValid() && "Cannot move off the end of the list.");
+    do advance();
+    while (!IncludeSelf && isValid() && *SI == Reg);
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCRelocationInfo.h b/include/llvm/MC/MCRelocationInfo.h
new file mode 100644
index 0000000..9dab900
--- /dev/null
+++ b/include/llvm/MC/MCRelocationInfo.h
@@ -0,0 +1,55 @@
+//==-- llvm/MC/MCRelocationInfo.h --------------------------------*- 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 MCRelocationInfo class, which provides methods to
+// create MCExprs from relocations, either found in an object::ObjectFile
+// (object::RelocationRef), or provided through the C API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCRELOCATIONINFO_H
+#define LLVM_MC_MCRELOCATIONINFO_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+namespace object {
+class RelocationRef;
+}
+class MCExpr;
+class MCContext;
+
+/// \brief Create MCExprs from relocations found in an object file.
+class MCRelocationInfo {
+  MCRelocationInfo(const MCRelocationInfo &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCRelocationInfo &) LLVM_DELETED_FUNCTION;
+
+protected:
+  MCContext &Ctx;
+
+public:
+  MCRelocationInfo(MCContext &Ctx);
+  virtual ~MCRelocationInfo();
+
+  /// \brief Create an MCExpr for the relocation \p Rel.
+  /// \returns If possible, an MCExpr corresponding to Rel, else 0.
+  virtual const MCExpr *createExprForRelocation(object::RelocationRef Rel);
+
+  /// \brief Create an MCExpr for the target-specific \p VariantKind.
+  /// The VariantKinds are defined in llvm-c/Disassembler.h.
+  /// Used by MCExternalSymbolizer.
+  /// \returns If possible, an MCExpr corresponding to VariantKind, else 0.
+  virtual const MCExpr *createExprForCAPIVariantKind(const MCExpr *SubExpr,
+                                                     unsigned VariantKind);
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
new file mode 100644
index 0000000..43b8672
--- /dev/null
+++ b/include/llvm/MC/MCSchedule.h
@@ -0,0 +1,265 @@
+//===-- llvm/MC/MCSchedule.h - Scheduling -----------------------*- 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 classes used to describe a subtarget's machine model
+// for scheduling and other instruction cost heuristics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSCHEDULE_H
+#define LLVM_MC_MCSCHEDULE_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+struct InstrItinerary;
+
+/// Define a kind of processor resource that will be modeled by the scheduler.
+struct MCProcResourceDesc {
+#ifndef NDEBUG
+  const char *Name;
+#endif
+  unsigned NumUnits; // Number of resource of this kind
+  unsigned SuperIdx; // Index of the resources kind that contains this kind.
+
+  // Number of resources that may be buffered.
+  //
+  // Buffered resources (BufferSize != 0) may be consumed at some indeterminate
+  // cycle after dispatch. This should be used for out-of-order cpus when
+  // instructions that use this resource can be buffered in a reservaton
+  // station.
+  //
+  // Unbuffered resources (BufferSize == 0) always consume their resource some
+  // fixed number of cycles after dispatch. If a resource is unbuffered, then
+  // the scheduler will avoid scheduling instructions with conflicting resources
+  // in the same cycle. This is for in-order cpus, or the in-order portion of
+  // an out-of-order cpus.
+  int BufferSize;
+
+  bool operator==(const MCProcResourceDesc &Other) const {
+    return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
+      && BufferSize == Other.BufferSize;
+  }
+};
+
+/// Identify one of the processor resource kinds consumed by a particular
+/// scheduling class for the specified number of cycles.
+struct MCWriteProcResEntry {
+  unsigned ProcResourceIdx;
+  unsigned Cycles;
+
+  bool operator==(const MCWriteProcResEntry &Other) const {
+    return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;
+  }
+};
+
+/// Specify the latency in cpu cycles for a particular scheduling class and def
+/// index. -1 indicates an invalid latency. Heuristics would typically consider
+/// an instruction with invalid latency to have infinite latency.  Also identify
+/// the WriteResources of this def. When the operand expands to a sequence of
+/// writes, this ID is the last write in the sequence.
+struct MCWriteLatencyEntry {
+  int Cycles;
+  unsigned WriteResourceID;
+
+  bool operator==(const MCWriteLatencyEntry &Other) const {
+    return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;
+  }
+};
+
+/// Specify the number of cycles allowed after instruction issue before a
+/// particular use operand reads its registers. This effectively reduces the
+/// write's latency. Here we allow negative cycles for corner cases where
+/// latency increases. This rule only applies when the entry's WriteResource
+/// matches the write's WriteResource.
+///
+/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by
+/// WriteResourceIdx.
+struct MCReadAdvanceEntry {
+  unsigned UseIdx;
+  unsigned WriteResourceID;
+  int Cycles;
+
+  bool operator==(const MCReadAdvanceEntry &Other) const {
+    return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID
+      && Cycles == Other.Cycles;
+  }
+};
+
+/// Summarize the scheduling resources required for an instruction of a
+/// particular scheduling class.
+///
+/// Defined as an aggregate struct for creating tables with initializer lists.
+struct MCSchedClassDesc {
+  static const unsigned short InvalidNumMicroOps = UINT16_MAX;
+  static const unsigned short VariantNumMicroOps = UINT16_MAX - 1;
+
+#ifndef NDEBUG
+  const char* Name;
+#endif
+  unsigned short NumMicroOps;
+  bool     BeginGroup;
+  bool     EndGroup;
+  unsigned WriteProcResIdx; // First index into WriteProcResTable.
+  unsigned NumWriteProcResEntries;
+  unsigned WriteLatencyIdx; // First index into WriteLatencyTable.
+  unsigned NumWriteLatencyEntries;
+  unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable.
+  unsigned NumReadAdvanceEntries;
+
+  bool isValid() const {
+    return NumMicroOps != InvalidNumMicroOps;
+  }
+  bool isVariant() const {
+    return NumMicroOps == VariantNumMicroOps;
+  }
+};
+
+/// Machine model for scheduling, bundling, and heuristics.
+///
+/// The machine model directly provides basic information about the
+/// microarchitecture to the scheduler in the form of properties. It also
+/// optionally refers to scheduler resource tables and itinerary
+/// tables. Scheduler resource tables model the latency and cost for each
+/// instruction type. Itinerary tables are an independent mechanism that
+/// provides a detailed reservation table describing each cycle of instruction
+/// execution. Subtargets may define any or all of the above categories of data
+/// depending on the type of CPU and selected scheduler.
+class MCSchedModel {
+public:
+  static MCSchedModel DefaultSchedModel; // For unknown processors.
+
+  // IssueWidth is the maximum number of instructions that may be scheduled in
+  // the same per-cycle group.
+  unsigned IssueWidth;
+  static const unsigned DefaultIssueWidth = 1;
+
+  // MicroOpBufferSize is the number of micro-ops that the processor may buffer
+  // for out-of-order execution.
+  //
+  // "0" means operations that are not ready in this cycle are not considered
+  // for scheduling (they go in the pending queue). Latency is paramount. This
+  // may be more efficient if many instructions are pending in a schedule.
+  //
+  // "1" means all instructions are considered for scheduling regardless of
+  // whether they are ready in this cycle. Latency still causes issue stalls,
+  // but we balance those stalls against other heuristics.
+  //
+  // "> 1" means the processor is out-of-order. This is a machine independent
+  // estimate of highly machine specific characteristics such as the register
+  // renaming pool and reorder buffer.
+  unsigned MicroOpBufferSize;
+  static const unsigned DefaultMicroOpBufferSize = 0;
+
+  // LoopMicroOpBufferSize is the number of micro-ops that the processor may
+  // buffer for optimized loop execution. More generally, this represents the
+  // optimal number of micro-ops in a loop body. A loop may be partially
+  // unrolled to bring the count of micro-ops in the loop body closer to this
+  // number.
+  unsigned LoopMicroOpBufferSize;
+  static const unsigned DefaultLoopMicroOpBufferSize = 0;
+
+  // LoadLatency is the expected latency of load instructions.
+  //
+  // If MinLatency >= 0, this may be overriden for individual load opcodes by
+  // InstrItinerary OperandCycles.
+  unsigned LoadLatency;
+  static const unsigned DefaultLoadLatency = 4;
+
+  // HighLatency is the expected latency of "very high latency" operations.
+  // See TargetInstrInfo::isHighLatencyDef().
+  // By default, this is set to an arbitrarily high number of cycles
+  // likely to have some impact on scheduling heuristics.
+  // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles.
+  unsigned HighLatency;
+  static const unsigned DefaultHighLatency = 10;
+
+  // MispredictPenalty is the typical number of extra cycles the processor
+  // takes to recover from a branch misprediction.
+  unsigned MispredictPenalty;
+  static const unsigned DefaultMispredictPenalty = 10;
+  
+  bool PostRAScheduler; // default value is false
+
+  bool CompleteModel;
+
+private:
+  unsigned ProcID;
+  const MCProcResourceDesc *ProcResourceTable;
+  const MCSchedClassDesc *SchedClassTable;
+  unsigned NumProcResourceKinds;
+  unsigned NumSchedClasses;
+  // Instruction itinerary tables used by InstrItineraryData.
+  friend class InstrItineraryData;
+  const InstrItinerary *InstrItineraries;
+
+public:
+  // Default's must be specified as static const literals so that tablegenerated
+  // target code can use it in static initializers. The defaults need to be
+  // initialized in this default ctor because some clients directly instantiate
+  // MCSchedModel instead of using a generated itinerary.
+  MCSchedModel(): IssueWidth(DefaultIssueWidth),
+                  MicroOpBufferSize(DefaultMicroOpBufferSize),
+                  LoopMicroOpBufferSize(DefaultLoopMicroOpBufferSize),
+                  LoadLatency(DefaultLoadLatency),
+                  HighLatency(DefaultHighLatency),
+                  MispredictPenalty(DefaultMispredictPenalty),
+                  PostRAScheduler(false), CompleteModel(true),
+                  ProcID(0), ProcResourceTable(nullptr),
+                  SchedClassTable(nullptr), NumProcResourceKinds(0),
+                  NumSchedClasses(0), InstrItineraries(nullptr) {
+    (void)NumProcResourceKinds;
+    (void)NumSchedClasses;
+  }
+
+  // Table-gen driven ctor.
+  MCSchedModel(unsigned iw, int mbs, int lmbs, unsigned ll, unsigned hl,
+               unsigned mp, bool postRASched, bool cm, unsigned pi,
+               const MCProcResourceDesc *pr, const MCSchedClassDesc *sc,
+               unsigned npr, unsigned nsc, const InstrItinerary *ii):
+    IssueWidth(iw), MicroOpBufferSize(mbs), LoopMicroOpBufferSize(lmbs),
+    LoadLatency(ll), HighLatency(hl),
+    MispredictPenalty(mp), PostRAScheduler(postRASched),
+    CompleteModel(cm), ProcID(pi),
+    ProcResourceTable(pr), SchedClassTable(sc), NumProcResourceKinds(npr),
+    NumSchedClasses(nsc), InstrItineraries(ii) {}
+
+  unsigned getProcessorID() const { return ProcID; }
+
+  /// Does this machine model include instruction-level scheduling.
+  bool hasInstrSchedModel() const { return SchedClassTable; }
+
+  /// Return true if this machine model data for all instructions with a
+  /// scheduling class (itinerary class or SchedRW list).
+  bool isComplete() const { return CompleteModel; }
+
+  unsigned getNumProcResourceKinds() const {
+    return NumProcResourceKinds;
+  }
+
+  const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
+    assert(hasInstrSchedModel() && "No scheduling machine model");
+
+    assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");
+    return &ProcResourceTable[ProcResourceIdx];
+  }
+
+  const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {
+    assert(hasInstrSchedModel() && "No scheduling machine model");
+
+    assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
+    return &SchedClassTable[SchedClassIdx];
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
new file mode 100644
index 0000000..de2678a
--- /dev/null
+++ b/include/llvm/MC/MCSection.h
@@ -0,0 +1,79 @@
+//===- MCSection.h - Machine Code Sections ----------------------*- 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 MCSection class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTION_H
+#define LLVM_MC_MCSECTION_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MCAsmInfo;
+  class MCExpr;
+  class raw_ostream;
+
+  /// MCSection - Instances of this class represent a uniqued identifier for a
+  /// section in the current translation unit.  The MCContext class uniques and
+  /// creates these.
+  class MCSection {
+  public:
+    enum SectionVariant {
+      SV_COFF = 0,
+      SV_ELF,
+      SV_MachO
+    };
+
+  private:
+    MCSection(const MCSection&) LLVM_DELETED_FUNCTION;
+    void operator=(const MCSection&) LLVM_DELETED_FUNCTION;
+  protected:
+    MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
+    SectionVariant Variant;
+    SectionKind Kind;
+  public:
+    virtual ~MCSection();
+
+    SectionKind getKind() const { return Kind; }
+
+    SectionVariant getVariant() const { return Variant; }
+
+    virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
+                                      raw_ostream &OS,
+                                      const MCExpr *Subsection) const = 0;
+
+    // Convenience routines to get label names for the beginning/end of a
+    // section.
+    virtual std::string getLabelBeginName() const = 0;
+    virtual std::string getLabelEndName() const = 0;
+
+    /// isBaseAddressKnownZero - Return true if we know that this section will
+    /// get a base address of zero.  In cases where we know that this is true we
+    /// can emit section offsets as direct references to avoid a subtraction
+    /// from the base of the section, saving a relocation.
+    virtual bool isBaseAddressKnownZero() const {
+      return false;
+    }
+
+    // UseCodeAlign - Return true if a .align directive should use
+    // "optimized nops" to fill instead of 0s.
+    virtual bool UseCodeAlign() const = 0;
+
+    /// isVirtualSection - Check whether this section is "virtual", that is
+    /// has no actual object file contents.
+    virtual bool isVirtualSection() const = 0;
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
new file mode 100644
index 0000000..0bbf369
--- /dev/null
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -0,0 +1,87 @@
+//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- 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 MCSectionCOFF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONCOFF_H
+#define LLVM_MC_MCSECTIONCOFF_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/COFF.h"
+
+namespace llvm {
+class MCSymbol;
+
+/// MCSectionCOFF - This represents a section on Windows
+  class MCSectionCOFF : public MCSection {
+    // The memory for this string is stored in the same MCContext as *this.
+    StringRef SectionName;
+
+    // FIXME: The following fields should not be mutable, but are for now so
+    // the asm parser can honor the .linkonce directive.
+
+    /// Characteristics - This is the Characteristics field of a section,
+    /// drawn from the enums below.
+    mutable unsigned Characteristics;
+
+    /// The COMDAT symbol of this section. Only valid if this is a COMDAT
+    /// section. Two COMDAT sections are merged if they have the same
+    /// COMDAT symbol.
+    MCSymbol *COMDATSymbol;
+
+    /// Selection - This is the Selection field for the section symbol, if
+    /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
+    mutable int Selection;
+
+  private:
+    friend class MCContext;
+    MCSectionCOFF(StringRef Section, unsigned Characteristics,
+                  MCSymbol *COMDATSymbol, int Selection, SectionKind K)
+        : MCSection(SV_COFF, K), SectionName(Section),
+          Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
+          Selection(Selection) {
+      assert ((Characteristics & 0x00F00000) == 0 &&
+        "alignment must not be set upon section creation");
+    }
+    ~MCSectionCOFF();
+
+  public:
+    /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+    /// should be printed before the section name
+    bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+    StringRef getSectionName() const { return SectionName; }
+    std::string getLabelBeginName() const override {
+      return SectionName.str() + "_begin";
+    }
+    std::string getLabelEndName() const override {
+      return SectionName.str() + "_end";
+    }
+    unsigned getCharacteristics() const { return Characteristics; }
+    MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
+    int getSelection() const { return Selection; }
+
+    void setSelection(int Selection) const;
+
+    void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+                              const MCExpr *Subsection) const override;
+    bool UseCodeAlign() const override;
+    bool isVirtualSection() const override;
+
+    static bool classof(const MCSection *S) {
+      return S->getVariant() == SV_COFF;
+    }
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
new file mode 100644
index 0000000..5ec23f1
--- /dev/null
+++ b/include/llvm/MC/MCSectionELF.h
@@ -0,0 +1,103 @@
+//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- 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 MCSectionELF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONELF_H
+#define LLVM_MC_MCSECTIONELF_H
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class MCSymbol;
+
+/// MCSectionELF - This represents a section on linux, lots of unix variants
+/// and some bare metal systems.
+class MCSectionELF : public MCSection {
+  /// SectionName - This is the name of the section.  The referenced memory is
+  /// owned by TargetLoweringObjectFileELF's ELFUniqueMap.
+  StringRef SectionName;
+
+  /// Type - This is the sh_type field of a section, drawn from the enums below.
+  unsigned Type;
+
+  /// Flags - This is the sh_flags field of a section, drawn from the enums.
+  /// below.
+  unsigned Flags;
+
+  /// EntrySize - The size of each entry in this section. This size only
+  /// makes sense for sections that contain fixed-sized entries. If a
+  /// section does not contain fixed-sized entries 'EntrySize' will be 0.
+  unsigned EntrySize;
+
+  const MCSymbol *Group;
+
+private:
+  friend class MCContext;
+  MCSectionELF(StringRef Section, unsigned type, unsigned flags,
+               SectionKind K, unsigned entrySize, const MCSymbol *group)
+    : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
+      EntrySize(entrySize), Group(group) {}
+  ~MCSectionELF();
+
+  void setSectionName(StringRef Name) { SectionName = Name; }
+
+public:
+
+  /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+  /// should be printed before the section name
+  bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+  StringRef getSectionName() const { return SectionName; }
+  std::string getLabelBeginName() const override {
+    if (Group)
+      return (SectionName.str() + '_' + Group->getName() + "_begin").str();
+    return SectionName.str() + "_begin";
+  }
+  std::string getLabelEndName() const override {
+    if (Group)
+      return (SectionName.str() + '_' + Group->getName() + "_end").str();
+    return SectionName.str() + "_end";
+  }
+  unsigned getType() const { return Type; }
+  unsigned getFlags() const { return Flags; }
+  unsigned getEntrySize() const { return EntrySize; }
+  const MCSymbol *getGroup() const { return Group; }
+
+  void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+                            const MCExpr *Subsection) const override;
+  bool UseCodeAlign() const override;
+  bool isVirtualSection() const override;
+
+  /// isBaseAddressKnownZero - We know that non-allocatable sections (like
+  /// debug info) have a base of zero.
+  bool isBaseAddressKnownZero() const override {
+    return (getFlags() & ELF::SHF_ALLOC) == 0;
+  }
+
+  static bool classof(const MCSection *S) {
+    return S->getVariant() == SV_ELF;
+  }
+
+  // Return the entry size for sections with fixed-width data.
+  static unsigned DetermineEntrySize(SectionKind Kind);
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
new file mode 100644
index 0000000..a5a2089
--- /dev/null
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -0,0 +1,100 @@
+//===- MCSectionMachO.h - MachO Machine Code Sections -----------*- 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 MCSectionMachO class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONMACHO_H
+#define LLVM_MC_MCSECTIONMACHO_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/MachO.h"
+
+namespace llvm {
+
+/// MCSectionMachO - This represents a section on a Mach-O system (used by
+/// Mac OS X).  On a Mac system, these are also described in
+/// /usr/include/mach-o/loader.h.
+class MCSectionMachO : public MCSection {
+  char SegmentName[16];  // Not necessarily null terminated!
+  char SectionName[16];  // Not necessarily null terminated!
+
+  /// TypeAndAttributes - This is the SECTION_TYPE and SECTION_ATTRIBUTES
+  /// field of a section, drawn from the enums below.
+  unsigned TypeAndAttributes;
+
+  /// Reserved2 - The 'reserved2' field of a section, used to represent the
+  /// size of stubs, for example.
+  unsigned Reserved2;
+
+  MCSectionMachO(StringRef Segment, StringRef Section,
+                 unsigned TAA, unsigned reserved2, SectionKind K);
+  friend class MCContext;
+public:
+
+  StringRef getSegmentName() const {
+    // SegmentName is not necessarily null terminated!
+    if (SegmentName[15])
+      return StringRef(SegmentName, 16);
+    return StringRef(SegmentName);
+  }
+  StringRef getSectionName() const {
+    // SectionName is not necessarily null terminated!
+    if (SectionName[15])
+      return StringRef(SectionName, 16);
+    return StringRef(SectionName);
+  }
+
+  std::string getLabelBeginName() const override {
+    return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
+  }
+
+  std::string getLabelEndName() const override {
+    return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
+  }
+
+  unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
+  unsigned getStubSize() const { return Reserved2; }
+
+  MachO::SectionType getType() const {
+    return static_cast<MachO::SectionType>(TypeAndAttributes &
+                                           MachO::SECTION_TYPE);
+  }
+  bool hasAttribute(unsigned Value) const {
+    return (TypeAndAttributes & Value) != 0;
+  }
+
+  /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
+  /// This is a string that can appear after a .section directive in a mach-o
+  /// flavored .s file.  If successful, this fills in the specified Out
+  /// parameters and returns an empty string.  When an invalid section
+  /// specifier is present, this returns a string indicating the problem.
+  /// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false.
+  static std::string ParseSectionSpecifier(StringRef Spec,       // In.
+                                           StringRef &Segment,   // Out.
+                                           StringRef &Section,   // Out.
+                                           unsigned  &TAA,       // Out.
+                                           bool      &TAAParsed, // Out.
+                                           unsigned  &StubSize); // Out.
+
+  void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+                            const MCExpr *Subsection) const override;
+  bool UseCodeAlign() const override;
+  bool isVirtualSection() const override;
+
+  static bool classof(const MCSection *S) {
+    return S->getVariant() == SV_MachO;
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
new file mode 100644
index 0000000..63a43d0
--- /dev/null
+++ b/include/llvm/MC/MCStreamer.h
@@ -0,0 +1,790 @@
+//===- MCStreamer.h - High-level Streaming Machine Code Output --*- 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 MCStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSTREAMER_H
+#define LLVM_MC_MCSTREAMER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCWin64EH.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCExpr;
+class MCInst;
+class MCInstPrinter;
+class MCSection;
+class MCStreamer;
+class MCSymbol;
+class MCSymbolRefExpr;
+class MCSubtargetInfo;
+class StringRef;
+class Twine;
+class raw_ostream;
+class formatted_raw_ostream;
+class AssemblerConstantPools;
+
+typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
+
+/// Target specific streamer interface. This is used so that targets can
+/// implement support for target specific assembly directives.
+///
+/// If target foo wants to use this, it should implement 3 classes:
+/// * FooTargetStreamer : public MCTargetStreamer
+/// * FooTargetAsmSreamer : public FooTargetStreamer
+/// * FooTargetELFStreamer : public FooTargetStreamer
+///
+/// FooTargetStreamer should have a pure virtual method for each directive. For
+/// example, for a ".bar symbol_name" directive, it should have
+/// virtual emitBar(const MCSymbol &Symbol) = 0;
+///
+/// The FooTargetAsmSreamer and FooTargetELFStreamer classes implement the
+/// method. The assembly streamer just prints ".bar symbol_name". The object
+/// streamer does whatever is needed to implement .bar in the object file.
+///
+/// In the assembly printer and parser the target streamer can be used by
+/// calling getTargetStreamer and casting it to FooTargetStreamer:
+///
+/// MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
+/// FooTargetStreamer &ATS = static_cast<FooTargetStreamer &>(TS);
+///
+/// The base classes FooTargetAsmSreamer and FooTargetELFStreamer should *never*
+/// be treated differently. Callers should always talk to a FooTargetStreamer.
+class MCTargetStreamer {
+protected:
+  MCStreamer &Streamer;
+
+public:
+  MCTargetStreamer(MCStreamer &S);
+  virtual ~MCTargetStreamer();
+
+  const MCStreamer &getStreamer() { return Streamer; }
+
+  // Allow a target to add behavior to the EmitLabel of MCStreamer.
+  virtual void emitLabel(MCSymbol *Symbol);
+  // Allow a target to add behavior to the emitAssignment of MCStreamer.
+  virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+  virtual void finish();
+};
+
+class AArch64TargetStreamer : public MCTargetStreamer {
+public:
+  AArch64TargetStreamer(MCStreamer &S);
+  ~AArch64TargetStreamer();
+
+
+  void finish() override;
+
+  /// Callback used to implement the ldr= pseudo.
+  /// Add a new entry to the constant pool for the current section and return an
+  /// MCExpr that can be used to refer to the constant pool location.
+  const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size);
+
+  /// Callback used to implemnt the .ltorg directive.
+  /// Emit contents of constant pool for the current section.
+  void emitCurrentConstantPool();
+
+private:
+  std::unique_ptr<AssemblerConstantPools> ConstantPools;
+};
+
+// FIXME: declared here because it is used from
+// lib/CodeGen/AsmPrinter/ARMException.cpp.
+class ARMTargetStreamer : public MCTargetStreamer {
+public:
+  ARMTargetStreamer(MCStreamer &S);
+  ~ARMTargetStreamer();
+
+  virtual void emitFnStart();
+  virtual void emitFnEnd();
+  virtual void emitCantUnwind();
+  virtual void emitPersonality(const MCSymbol *Personality);
+  virtual void emitPersonalityIndex(unsigned Index);
+  virtual void emitHandlerData();
+  virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
+                         int64_t Offset = 0);
+  virtual void emitMovSP(unsigned Reg, int64_t Offset = 0);
+  virtual void emitPad(int64_t Offset);
+  virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+                           bool isVector);
+  virtual void emitUnwindRaw(int64_t StackOffset,
+                             const SmallVectorImpl<uint8_t> &Opcodes);
+
+  virtual void switchVendor(StringRef Vendor);
+  virtual void emitAttribute(unsigned Attribute, unsigned Value);
+  virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+  virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
+                                    StringRef StringValue = "");
+  virtual void emitFPU(unsigned FPU);
+  virtual void emitArch(unsigned Arch);
+  virtual void emitObjectArch(unsigned Arch);
+  virtual void finishAttributeSection();
+  virtual void emitInst(uint32_t Inst, char Suffix = '\0');
+
+  virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
+  virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value);
+
+  void finish() override;
+
+  /// Callback used to implement the ldr= pseudo.
+  /// Add a new entry to the constant pool for the current section and return an
+  /// MCExpr that can be used to refer to the constant pool location.
+  const MCExpr *addConstantPoolEntry(const MCExpr *);
+
+  /// Callback used to implemnt the .ltorg directive.
+  /// Emit contents of constant pool for the current section.
+  void emitCurrentConstantPool();
+
+private:
+  std::unique_ptr<AssemblerConstantPools> ConstantPools;
+};
+
+/// MCStreamer - Streaming machine code generation interface.  This interface
+/// is intended to provide a programatic interface that is very similar to the
+/// level that an assembler .s file provides.  It has callbacks to emit bytes,
+/// handle directives, etc.  The implementation of this interface retains
+/// state to know what the current section is etc.
+///
+/// There are multiple implementations of this interface: one for writing out
+/// a .s file, and implementations that write out .o files of various formats.
+///
+class MCStreamer {
+  MCContext &Context;
+  std::unique_ptr<MCTargetStreamer> TargetStreamer;
+
+  MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
+  MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
+
+  std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
+  MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
+  void EnsureValidDwarfFrame();
+
+  MCSymbol *EmitCFICommon();
+
+  std::vector<MCWinFrameInfo *> WinFrameInfos;
+  MCWinFrameInfo *CurrentWinFrameInfo;
+  void EnsureValidWinFrameInfo();
+
+  // SymbolOrdering - Tracks an index to represent the order
+  // a symbol was emitted in. Zero means we did not emit that symbol.
+  DenseMap<const MCSymbol *, unsigned> SymbolOrdering;
+
+  /// SectionStack - This is stack of current and previous section
+  /// values saved by PushSection.
+  SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
+
+protected:
+  MCStreamer(MCContext &Ctx);
+
+  const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
+                                const MCSymbol *B);
+
+  const MCExpr *ForceExpAbs(const MCExpr *Expr);
+
+  virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+  virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
+
+  MCWinFrameInfo *getCurrentWinFrameInfo() {
+    return CurrentWinFrameInfo;
+  }
+
+  void EmitWindowsUnwindTables();
+
+  virtual void EmitRawTextImpl(StringRef String);
+
+public:
+  virtual ~MCStreamer();
+
+  void visitUsedExpr(const MCExpr &Expr);
+  virtual void visitUsedSymbol(const MCSymbol &Sym);
+
+  void setTargetStreamer(MCTargetStreamer *TS) {
+    TargetStreamer.reset(TS);
+  }
+
+  /// State management
+  ///
+  virtual void reset();
+
+  MCContext &getContext() const { return Context; }
+
+  MCTargetStreamer *getTargetStreamer() {
+    return TargetStreamer.get();
+  }
+
+  unsigned getNumFrameInfos() { return DwarfFrameInfos.size(); }
+  ArrayRef<MCDwarfFrameInfo> getDwarfFrameInfos() const {
+    return DwarfFrameInfos;
+  }
+
+  unsigned getNumWinFrameInfos() { return WinFrameInfos.size(); }
+  ArrayRef<MCWinFrameInfo *> getWinFrameInfos() const {
+    return WinFrameInfos;
+  }
+
+  void generateCompactUnwindEncodings(MCAsmBackend *MAB);
+
+  /// @name Assembly File Formatting.
+  /// @{
+
+  /// isVerboseAsm - Return true if this streamer supports verbose assembly
+  /// and if it is enabled.
+  virtual bool isVerboseAsm() const { return false; }
+
+  /// hasRawTextSupport - Return true if this asm streamer supports emitting
+  /// unformatted text to the .s file with EmitRawText.
+  virtual bool hasRawTextSupport() const { return false; }
+
+  /// Is the integrated assembler required for this streamer to function
+  /// correctly?
+  virtual bool isIntegratedAssemblerRequired() const { return false; }
+
+  /// AddComment - Add a comment that can be emitted to the generated .s
+  /// file if applicable as a QoI issue to make the output of the compiler
+  /// more readable.  This only affects the MCAsmStreamer, and only when
+  /// verbose assembly output is enabled.
+  ///
+  /// If the comment includes embedded \n's, they will each get the comment
+  /// prefix as appropriate.  The added comment should not end with a \n.
+  virtual void AddComment(const Twine &T) {}
+
+  /// GetCommentOS - Return a raw_ostream that comments can be written to.
+  /// Unlike AddComment, you are required to terminate comments with \n if you
+  /// use this method.
+  virtual raw_ostream &GetCommentOS();
+
+  /// Print T and prefix it with the comment string (normally #) and optionally
+  /// a tab. This prints the comment immediately, not at the end of the
+  /// current line. It is basically a safe version of EmitRawText: since it
+  /// only prints comments, the object streamer ignores it instead of asserting.
+  virtual void emitRawComment(const Twine &T, bool TabPrefix = true);
+
+  /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
+  virtual void AddBlankLine() {}
+
+  /// @}
+
+  /// @name Symbol & Section Management
+  /// @{
+
+  /// getCurrentSection - Return the current section that the streamer is
+  /// emitting code to.
+  MCSectionSubPair getCurrentSection() const {
+    if (!SectionStack.empty())
+      return SectionStack.back().first;
+    return MCSectionSubPair();
+  }
+
+  /// getPreviousSection - Return the previous section that the streamer is
+  /// emitting code to.
+  MCSectionSubPair getPreviousSection() const {
+    if (!SectionStack.empty())
+      return SectionStack.back().second;
+    return MCSectionSubPair();
+  }
+
+  /// GetSymbolOrder - Returns an index to represent the order
+  /// a symbol was emitted in. (zero if we did not emit that symbol)
+  unsigned GetSymbolOrder(const MCSymbol *Sym) const {
+    return SymbolOrdering.lookup(Sym);
+  }
+
+  /// ChangeSection - Update streamer for a new active section.
+  ///
+  /// This is called by PopSection and SwitchSection, if the current
+  /// section changes.
+  virtual void ChangeSection(const MCSection *, const MCExpr *);
+
+  /// pushSection - Save the current and previous section on the
+  /// section stack.
+  void PushSection() {
+    SectionStack.push_back(
+        std::make_pair(getCurrentSection(), getPreviousSection()));
+  }
+
+  /// popSection - Restore the current and previous section from
+  /// the section stack.  Calls ChangeSection as needed.
+  ///
+  /// Returns false if the stack was empty.
+  bool PopSection() {
+    if (SectionStack.size() <= 1)
+      return false;
+    MCSectionSubPair oldSection = SectionStack.pop_back_val().first;
+    MCSectionSubPair curSection = SectionStack.back().first;
+
+    if (oldSection != curSection)
+      ChangeSection(curSection.first, curSection.second);
+    return true;
+  }
+
+  bool SubSection(const MCExpr *Subsection) {
+    if (SectionStack.empty())
+      return false;
+
+    SwitchSection(SectionStack.back().first.first, Subsection);
+    return true;
+  }
+
+  /// SwitchSection - Set the current section where code is being emitted to
+  /// @p Section.  This is required to update CurSection.
+  ///
+  /// This corresponds to assembler directives like .section, .text, etc.
+  void SwitchSection(const MCSection *Section,
+                     const MCExpr *Subsection = nullptr) {
+    assert(Section && "Cannot switch to a null section!");
+    MCSectionSubPair curSection = SectionStack.back().first;
+    SectionStack.back().second = curSection;
+    if (MCSectionSubPair(Section, Subsection) != curSection) {
+      SectionStack.back().first = MCSectionSubPair(Section, Subsection);
+      ChangeSection(Section, Subsection);
+    }
+  }
+
+  /// SwitchSectionNoChange - Set the current section where code is being
+  /// emitted to @p Section.  This is required to update CurSection. This
+  /// version does not call ChangeSection.
+  void SwitchSectionNoChange(const MCSection *Section,
+                             const MCExpr *Subsection = nullptr) {
+    assert(Section && "Cannot switch to a null section!");
+    MCSectionSubPair curSection = SectionStack.back().first;
+    SectionStack.back().second = curSection;
+    if (MCSectionSubPair(Section, Subsection) != curSection)
+      SectionStack.back().first = MCSectionSubPair(Section, Subsection);
+  }
+
+  /// Create the default sections and set the initial one.
+  virtual void InitSections();
+
+  /// AssignSection - Sets the symbol's section.
+  ///
+  /// Each emitted symbol will be tracked in the ordering table,
+  /// so we can sort on them later.
+  void AssignSection(MCSymbol *Symbol, const MCSection *Section);
+
+  /// EmitLabel - Emit a label for @p Symbol into the current section.
+  ///
+  /// This corresponds to an assembler statement such as:
+  ///   foo:
+  ///
+  /// @param Symbol - The symbol to emit. A given symbol should only be
+  /// emitted as a label once, and symbols emitted as a label should never be
+  /// used in an assignment.
+  // FIXME: These emission are non-const because we mutate the symbol to
+  // add the section we're emitting it to later.
+  virtual void EmitLabel(MCSymbol *Symbol);
+
+  virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
+
+  /// EmitAssemblerFlag - Note in the output the specified @p Flag.
+  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+
+  /// EmitLinkerOptions - Emit the given list @p Options of strings as linker
+  /// options into the output.
+  virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
+
+  /// EmitDataRegion - Note in the output the specified region @p Kind.
+  virtual void EmitDataRegion(MCDataRegionType Kind) {}
+
+  /// EmitVersionMin - Specify the MachO minimum deployment target version.
+  virtual void EmitVersionMin(MCVersionMinType, unsigned Major, unsigned Minor,
+                              unsigned Update) {}
+
+  /// EmitThumbFunc - Note in the output that the specified @p Func is
+  /// a Thumb mode function (ARM target only).
+  virtual void EmitThumbFunc(MCSymbol *Func);
+
+  /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
+  ///
+  /// This corresponds to an assembler statement such as:
+  ///  symbol = value
+  ///
+  /// The assignment generates no code, but has the side effect of binding the
+  /// value in the current context. For the assembly streamer, this prints the
+  /// binding into the .s file.
+  ///
+  /// @param Symbol - The symbol being assigned to.
+  /// @param Value - The value for the symbol.
+  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+  /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
+  ///
+  /// This corresponds to an assembler statement such as:
+  ///  .weakref alias, symbol
+  ///
+  /// @param Alias - The alias that is being created.
+  /// @param Symbol - The symbol being aliased.
+  virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+
+  /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
+  virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
+                                   MCSymbolAttr Attribute) = 0;
+
+  /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
+  ///
+  /// @param Symbol - The symbol to have its n_desc field set.
+  /// @param DescValue - The value to set into the n_desc field.
+  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+
+  /// BeginCOFFSymbolDef - Start emitting COFF symbol definition
+  ///
+  /// @param Symbol - The symbol to have its External & Type fields set.
+  virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
+
+  /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
+  ///
+  /// @param StorageClass - The storage class the symbol should have.
+  virtual void EmitCOFFSymbolStorageClass(int StorageClass);
+
+  /// EmitCOFFSymbolType - Emit the type of the symbol.
+  ///
+  /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
+  virtual void EmitCOFFSymbolType(int Type);
+
+  /// EndCOFFSymbolDef - Marks the end of the symbol definition.
+  virtual void EndCOFFSymbolDef();
+
+  /// EmitCOFFSectionIndex - Emits a COFF section index.
+  ///
+  /// @param Symbol - Symbol the section number relocation should point to.
+  virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
+
+  /// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
+  ///
+  /// @param Symbol - Symbol the section relative relocation should point to.
+  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
+
+  /// EmitELFSize - Emit an ELF .size directive.
+  ///
+  /// This corresponds to an assembler statement such as:
+  ///  .size symbol, expression
+  ///
+  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+
+  /// \brief Emit a Linker Optimization Hint (LOH) directive.
+  /// \param Args - Arguments of the LOH.
+  virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
+
+  /// EmitCommonSymbol - Emit a common symbol.
+  ///
+  /// @param Symbol - The common symbol to emit.
+  /// @param Size - The size of the common symbol.
+  /// @param ByteAlignment - The alignment of the symbol if
+  /// non-zero. This must be a power of 2.
+  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                unsigned ByteAlignment) = 0;
+
+  /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+  ///
+  /// @param Symbol - The common symbol to emit.
+  /// @param Size - The size of the common symbol.
+  /// @param ByteAlignment - The alignment of the common symbol in bytes.
+  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                     unsigned ByteAlignment);
+
+  /// EmitZerofill - Emit the zerofill section and an optional symbol.
+  ///
+  /// @param Section - The zerofill section to create and or to put the symbol
+  /// @param Symbol - The zerofill symbol to emit, if non-NULL.
+  /// @param Size - The size of the zerofill symbol.
+  /// @param ByteAlignment - The alignment of the zerofill symbol if
+  /// non-zero. This must be a power of 2 on some targets.
+  virtual void EmitZerofill(const MCSection *Section,
+                            MCSymbol *Symbol = nullptr, uint64_t Size = 0,
+                            unsigned ByteAlignment = 0) = 0;
+
+  /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
+  ///
+  /// @param Section - The thread local common section.
+  /// @param Symbol - The thread local common symbol to emit.
+  /// @param Size - The size of the symbol.
+  /// @param ByteAlignment - The alignment of the thread local common symbol
+  /// if non-zero.  This must be a power of 2 on some targets.
+  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+                              uint64_t Size, unsigned ByteAlignment = 0);
+
+  /// @}
+  /// @name Generating Data
+  /// @{
+
+  /// EmitBytes - Emit the bytes in \p Data into the output.
+  ///
+  /// This is used to implement assembler directives such as .byte, .ascii,
+  /// etc.
+  virtual void EmitBytes(StringRef Data);
+
+  /// EmitValue - Emit the expression @p Value into the output as a native
+  /// integer of the given @p Size bytes.
+  ///
+  /// This is used to implement assembler directives such as .word, .quad,
+  /// etc.
+  ///
+  /// @param Value - The value to emit.
+  /// @param Size - The size of the integer (in bytes) to emit. This must
+  /// match a native machine width.
+  /// @param Loc - The location of the expression for error reporting.
+  virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+                             const SMLoc &Loc = SMLoc());
+
+  void EmitValue(const MCExpr *Value, unsigned Size,
+                 const SMLoc &Loc = SMLoc());
+
+  /// EmitIntValue - Special case of EmitValue that avoids the client having
+  /// to pass in a MCExpr for constant integers.
+  virtual void EmitIntValue(uint64_t Value, unsigned Size);
+
+  /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
+  /// this is done by producing
+  /// foo = value
+  /// .long foo
+  void EmitAbsValue(const MCExpr *Value, unsigned Size);
+
+  virtual void EmitULEB128Value(const MCExpr *Value);
+
+  virtual void EmitSLEB128Value(const MCExpr *Value);
+
+  /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
+  /// client having to pass in a MCExpr for constant integers.
+  void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0);
+
+  /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
+  /// client having to pass in a MCExpr for constant integers.
+  void EmitSLEB128IntValue(int64_t Value);
+
+  /// EmitSymbolValue - Special case of EmitValue that avoids the client
+  /// having to pass in a MCExpr for MCSymbols.
+  void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+                       bool IsSectionRelative = false);
+
+  /// EmitGPRel64Value - Emit the expression @p Value into the output as a
+  /// gprel64 (64-bit GP relative) value.
+  ///
+  /// This is used to implement assembler directives such as .gpdword on
+  /// targets that support them.
+  virtual void EmitGPRel64Value(const MCExpr *Value);
+
+  /// EmitGPRel32Value - Emit the expression @p Value into the output as a
+  /// gprel32 (32-bit GP relative) value.
+  ///
+  /// This is used to implement assembler directives such as .gprel32 on
+  /// targets that support them.
+  virtual void EmitGPRel32Value(const MCExpr *Value);
+
+  /// EmitFill - Emit NumBytes bytes worth of the value specified by
+  /// FillValue.  This implements directives such as '.space'.
+  virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
+
+  /// \brief Emit NumBytes worth of zeros.
+  /// This function properly handles data in virtual sections.
+  virtual void EmitZeros(uint64_t NumBytes);
+
+  /// EmitValueToAlignment - Emit some number of copies of @p Value until
+  /// the byte alignment @p ByteAlignment is reached.
+  ///
+  /// If the number of bytes need to emit for the alignment is not a multiple
+  /// of @p ValueSize, then the contents of the emitted fill bytes is
+  /// undefined.
+  ///
+  /// This used to implement the .align assembler directive.
+  ///
+  /// @param ByteAlignment - The alignment to reach. This must be a power of
+  /// two on some targets.
+  /// @param Value - The value to use when filling bytes.
+  /// @param ValueSize - The size of the integer (in bytes) to emit for
+  /// @p Value. This must match a native machine width.
+  /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+  /// the alignment cannot be reached in this many bytes, no bytes are
+  /// emitted.
+  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+                                    unsigned ValueSize = 1,
+                                    unsigned MaxBytesToEmit = 0);
+
+  /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
+  /// is reached.
+  ///
+  /// This used to align code where the alignment bytes may be executed.  This
+  /// can emit different bytes for different sizes to optimize execution.
+  ///
+  /// @param ByteAlignment - The alignment to reach. This must be a power of
+  /// two on some targets.
+  /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+  /// the alignment cannot be reached in this many bytes, no bytes are
+  /// emitted.
+  virtual void EmitCodeAlignment(unsigned ByteAlignment,
+                                 unsigned MaxBytesToEmit = 0);
+
+  /// EmitValueToOffset - Emit some number of copies of @p Value until the
+  /// byte offset @p Offset is reached.
+  ///
+  /// This is used to implement assembler directives such as .org.
+  ///
+  /// @param Offset - The offset to reach. This may be an expression, but the
+  /// expression must be associated with the current section.
+  /// @param Value - The value to use when filling bytes.
+  /// @return false on success, true if the offset was invalid.
+  virtual bool EmitValueToOffset(const MCExpr *Offset,
+                                 unsigned char Value = 0);
+
+  /// @}
+
+  /// EmitFileDirective - Switch to a new logical file.  This is used to
+  /// implement the '.file "foo.c"' assembler directive.
+  virtual void EmitFileDirective(StringRef Filename);
+
+  /// Emit the "identifiers" directive.  This implements the
+  /// '.ident "version foo"' assembler directive.
+  virtual void EmitIdent(StringRef IdentString) {}
+
+  /// EmitDwarfFileDirective - Associate a filename with a specified logical
+  /// file number.  This implements the DWARF2 '.file 4 "foo.c"' assembler
+  /// directive.
+  virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+                                          StringRef Filename,
+                                          unsigned CUID = 0);
+
+  /// EmitDwarfLocDirective - This implements the DWARF2
+  // '.loc fileno lineno ...' assembler directive.
+  virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+                                     unsigned Column, unsigned Flags,
+                                     unsigned Isa, unsigned Discriminator,
+                                     StringRef FileName);
+
+  virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
+
+  void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label,
+                            int PointerSize);
+
+  virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding);
+  virtual void EmitCFISections(bool EH, bool Debug);
+  void EmitCFIStartProc(bool IsSimple);
+  void EmitCFIEndProc();
+  virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
+  virtual void EmitCFIDefCfaOffset(int64_t Offset);
+  virtual void EmitCFIDefCfaRegister(int64_t Register);
+  virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
+  virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
+  virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+  virtual void EmitCFIRememberState();
+  virtual void EmitCFIRestoreState();
+  virtual void EmitCFISameValue(int64_t Register);
+  virtual void EmitCFIRestore(int64_t Register);
+  virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
+  virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
+  virtual void EmitCFIEscape(StringRef Values);
+  virtual void EmitCFISignalFrame();
+  virtual void EmitCFIUndefined(int64_t Register);
+  virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
+  virtual void EmitCFIWindowSave();
+
+  virtual void EmitWinCFIStartProc(const MCSymbol *Symbol);
+  virtual void EmitWinCFIEndProc();
+  virtual void EmitWinCFIStartChained();
+  virtual void EmitWinCFIEndChained();
+  virtual void EmitWinCFIPushReg(unsigned Register);
+  virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset);
+  virtual void EmitWinCFIAllocStack(unsigned Size);
+  virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset);
+  virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset);
+  virtual void EmitWinCFIPushFrame(bool Code);
+  virtual void EmitWinCFIEndProlog();
+
+  virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
+  virtual void EmitWinEHHandlerData();
+
+  /// EmitInstruction - Emit the given @p Instruction into the current
+  /// section.
+  virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
+
+  /// \brief Set the bundle alignment mode from now on in the section.
+  /// The argument is the power of 2 to which the alignment is set. The
+  /// value 0 means turn the bundle alignment off.
+  virtual void EmitBundleAlignMode(unsigned AlignPow2);
+
+  /// \brief The following instructions are a bundle-locked group.
+  ///
+  /// \param AlignToEnd - If true, the bundle-locked group will be aligned to
+  ///                     the end of a bundle.
+  virtual void EmitBundleLock(bool AlignToEnd);
+
+  /// \brief Ends a bundle-locked group.
+  virtual void EmitBundleUnlock();
+
+  /// EmitRawText - If this file is backed by a assembly streamer, this dumps
+  /// the specified string in the output .s file.  This capability is
+  /// indicated by the hasRawTextSupport() predicate.  By default this aborts.
+  void EmitRawText(const Twine &String);
+
+  /// Flush - Causes any cached state to be written out.
+  virtual void Flush() {}
+
+  /// FinishImpl - Streamer specific finalization.
+  virtual void FinishImpl();
+  /// Finish - Finish emission of machine code.
+  void Finish();
+
+  virtual bool mayHaveInstructions() const { return true; }
+};
+
+/// createNullStreamer - Create a dummy machine code streamer, which does
+/// nothing. This is useful for timing the assembler front end.
+MCStreamer *createNullStreamer(MCContext &Ctx);
+
+/// createAsmStreamer - Create a machine code streamer which will print out
+/// assembly for the native target, suitable for compiling with a native
+/// assembler.
+///
+/// \param InstPrint - If given, the instruction printer to use. If not given
+/// the MCInst representation will be printed.  This method takes ownership of
+/// InstPrint.
+///
+/// \param CE - If given, a code emitter to use to show the instruction
+/// encoding inline with the assembly. This method takes ownership of \p CE.
+///
+/// \param TAB - If given, a target asm backend to use to show the fixup
+/// information in conjunction with encoding information. This method takes
+/// ownership of \p TAB.
+///
+/// \param ShowInst - Whether to show the MCInst representation inline with
+/// the assembly.
+MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+                              bool isVerboseAsm, bool useDwarfDirectory,
+                              MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+                              MCAsmBackend *TAB, bool ShowInst);
+
+/// createMachOStreamer - Create a machine code streamer which will generate
+/// Mach-O format object files.
+///
+/// Takes ownership of \p TAB and \p CE.
+MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+                                raw_ostream &OS, MCCodeEmitter *CE,
+                                bool RelaxAll = false,
+                                bool LabelSections = false);
+
+/// createELFStreamer - Create a machine code streamer which will generate
+/// ELF format object files.
+MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+                              raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll,
+                              bool NoExecStack);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
new file mode 100644
index 0000000..088c5e7
--- /dev/null
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -0,0 +1,139 @@
+//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSUBTARGET_H
+#define LLVM_MC_MCSUBTARGET_H
+
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include <string>
+
+namespace llvm {
+
+class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// MCSubtargetInfo - Generic base class for all target subtargets.
+///
+class MCSubtargetInfo {
+  std::string TargetTriple;            // Target triple
+  ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
+  ArrayRef<SubtargetFeatureKV> ProcDesc;  // Processor descriptions
+
+  // Scheduler machine model
+  const SubtargetInfoKV *ProcSchedModels;
+  const MCWriteProcResEntry *WriteProcResTable;
+  const MCWriteLatencyEntry *WriteLatencyTable;
+  const MCReadAdvanceEntry *ReadAdvanceTable;
+  const MCSchedModel *CPUSchedModel;
+
+  const InstrStage *Stages;            // Instruction itinerary stages
+  const unsigned *OperandCycles;       // Itinerary operand cycles
+  const unsigned *ForwardingPaths;     // Forwarding paths
+  uint64_t FeatureBits;                // Feature bits for current CPU + FS
+
+public:
+  void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
+                           ArrayRef<SubtargetFeatureKV> PF,
+                           ArrayRef<SubtargetFeatureKV> PD,
+                           const SubtargetInfoKV *ProcSched,
+                           const MCWriteProcResEntry *WPR,
+                           const MCWriteLatencyEntry *WL,
+                           const MCReadAdvanceEntry *RA,
+                           const InstrStage *IS,
+                           const unsigned *OC, const unsigned *FP);
+
+  /// getTargetTriple - Return the target triple string.
+  StringRef getTargetTriple() const {
+    return TargetTriple;
+  }
+
+  /// getFeatureBits - Return the feature bits.
+  ///
+  uint64_t getFeatureBits() const {
+    return FeatureBits;
+  }
+
+  /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
+  /// feature string). Recompute feature bits and scheduling model.
+  void InitMCProcessorInfo(StringRef CPU, StringRef FS);
+
+  /// InitCPUSchedModel - Recompute scheduling model based on CPU.
+  void InitCPUSchedModel(StringRef CPU);
+
+  /// ToggleFeature - Toggle a feature and returns the re-computed feature
+  /// bits. This version does not change the implied bits.
+  uint64_t ToggleFeature(uint64_t FB);
+
+  /// ToggleFeature - Toggle a feature and returns the re-computed feature
+  /// bits. This version will also change all implied bits.
+  uint64_t ToggleFeature(StringRef FS);
+
+  /// getSchedModelForCPU - Get the machine model of a CPU.
+  ///
+  const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
+
+  /// getSchedModel - Get the machine model for this subtarget's CPU.
+  ///
+  const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
+
+  /// Return an iterator at the first process resource consumed by the given
+  /// scheduling class.
+  const MCWriteProcResEntry *getWriteProcResBegin(
+    const MCSchedClassDesc *SC) const {
+    return &WriteProcResTable[SC->WriteProcResIdx];
+  }
+  const MCWriteProcResEntry *getWriteProcResEnd(
+    const MCSchedClassDesc *SC) const {
+    return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
+  }
+
+  const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
+                                                  unsigned DefIdx) const {
+    assert(DefIdx < SC->NumWriteLatencyEntries &&
+           "MachineModel does not specify a WriteResource for DefIdx");
+
+    return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
+  }
+
+  int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
+                           unsigned WriteResID) const {
+    // TODO: The number of read advance entries in a class can be significant
+    // (~50). Consider compressing the WriteID into a dense ID of those that are
+    // used by ReadAdvance and representing them as a bitset.
+    for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
+           *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
+      if (I->UseIdx < UseIdx)
+        continue;
+      if (I->UseIdx > UseIdx)
+        break;
+      // Find the first WriteResIdx match, which has the highest cycle count.
+      if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
+        return I->Cycles;
+      }
+    }
+    return 0;
+  }
+
+  /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
+  ///
+  InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+
+  /// Initialize an InstrItineraryData instance.
+  void initInstrItins(InstrItineraryData &InstrItins) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
new file mode 100644
index 0000000..0b3c3ce
--- /dev/null
+++ b/include/llvm/MC/MCSymbol.h
@@ -0,0 +1,165 @@
+//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCSymbol class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSYMBOL_H
+#define LLVM_MC_MCSYMBOL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class MCExpr;
+  class MCSection;
+  class MCContext;
+  class raw_ostream;
+
+  /// MCSymbol - Instances of this class represent a symbol name in the MC file,
+  /// and MCSymbols are created and unique'd by the MCContext class.  MCSymbols
+  /// should only be constructed with valid names for the object file.
+  ///
+  /// If the symbol is defined/emitted into the current translation unit, the
+  /// Section member is set to indicate what section it lives in.  Otherwise, if
+  /// it is a reference to an external entity, it has a null section.
+  class MCSymbol {
+    // Special sentinal value for the absolute pseudo section.
+    //
+    // FIXME: Use a PointerInt wrapper for this?
+    static const MCSection *AbsolutePseudoSection;
+
+    /// Name - The name of the symbol.  The referred-to string data is actually
+    /// held by the StringMap that lives in MCContext.
+    StringRef Name;
+
+    /// Section - The section the symbol is defined in. This is null for
+    /// undefined symbols, and the special AbsolutePseudoSection value for
+    /// absolute symbols.
+    const MCSection *Section;
+
+    /// Value - If non-null, the value for a variable symbol.
+    const MCExpr *Value;
+
+    /// IsTemporary - True if this is an assembler temporary label, which
+    /// typically does not survive in the .o file's symbol table.  Usually
+    /// "Lfoo" or ".foo".
+    unsigned IsTemporary : 1;
+
+    /// IsUsed - True if this symbol has been used.
+    mutable unsigned IsUsed : 1;
+
+  private:  // MCContext creates and uniques these.
+    friend class MCExpr;
+    friend class MCContext;
+    MCSymbol(StringRef name, bool isTemporary)
+      : Name(name), Section(nullptr), Value(nullptr),
+        IsTemporary(isTemporary), IsUsed(false) {}
+
+    MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
+    void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
+  public:
+    /// getName - Get the symbol name.
+    StringRef getName() const { return Name; }
+
+    /// @name Accessors
+    /// @{
+
+    /// isTemporary - Check if this is an assembler temporary symbol.
+    bool isTemporary() const { return IsTemporary; }
+
+    /// isUsed - Check if this is used.
+    bool isUsed() const { return IsUsed; }
+    void setUsed(bool Value) const { IsUsed = Value; }
+
+    /// @}
+    /// @name Associated Sections
+    /// @{
+
+    /// isDefined - Check if this symbol is defined (i.e., it has an address).
+    ///
+    /// Defined symbols are either absolute or in some section.
+    bool isDefined() const {
+      return Section != nullptr;
+    }
+
+    /// isInSection - Check if this symbol is defined in some section (i.e., it
+    /// is defined but not absolute).
+    bool isInSection() const {
+      return isDefined() && !isAbsolute();
+    }
+
+    /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
+    bool isUndefined() const {
+      return !isDefined();
+    }
+
+    /// isAbsolute - Check if this is an absolute symbol.
+    bool isAbsolute() const {
+      return Section == AbsolutePseudoSection;
+    }
+
+    /// getSection - Get the section associated with a defined, non-absolute
+    /// symbol.
+    const MCSection &getSection() const {
+      assert(isInSection() && "Invalid accessor!");
+      return *Section;
+    }
+
+    /// setSection - Mark the symbol as defined in the section \p S.
+    void setSection(const MCSection &S) { Section = &S; }
+
+    /// setUndefined - Mark the symbol as undefined.
+    void setUndefined() {
+      Section = nullptr;
+    }
+
+    /// setAbsolute - Mark the symbol as absolute.
+    void setAbsolute() { Section = AbsolutePseudoSection; }
+
+    /// @}
+    /// @name Variable Symbols
+    /// @{
+
+    /// isVariable - Check if this is a variable symbol.
+    bool isVariable() const {
+      return Value != nullptr;
+    }
+
+    /// getVariableValue() - Get the value for variable symbols.
+    const MCExpr *getVariableValue() const {
+      assert(isVariable() && "Invalid accessor!");
+      IsUsed = true;
+      return Value;
+    }
+
+    // AliasedSymbol() - If this is an alias (a = b), return the symbol
+    // we ultimately point to. For a non-alias, this just returns the symbol
+    // itself.
+    const MCSymbol &AliasedSymbol() const;
+
+    void setVariableValue(const MCExpr *Value);
+
+    /// @}
+
+    /// print - Print the value to the stream \p OS.
+    void print(raw_ostream &OS) const;
+
+    /// dump - Print the value to stderr.
+    void dump() const;
+  };
+
+  inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
+    Sym.print(OS);
+    return OS;
+  }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h
new file mode 100644
index 0000000..cbbb591
--- /dev/null
+++ b/include/llvm/MC/MCSymbolizer.h
@@ -0,0 +1,85 @@
+//===-- llvm/MC/MCSymbolizer.h - MCSymbolizer class -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCSymbolizer class, which is used
+// to symbolize instructions decoded from an object, that is, transform their
+// immediate operands to MCExprs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSYMBOLIZER_H
+#define LLVM_MC_MCSYMBOLIZER_H
+
+#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <memory>
+
+namespace llvm {
+
+class MCContext;
+class MCInst;
+class raw_ostream;
+
+/// \brief Symbolize and annotate disassembled instructions.
+///
+/// For now this mimics the old symbolization logic (from both ARM and x86), that
+/// relied on user-provided (C API) callbacks to do the actual symbol lookup in
+/// the object file. This was moved to MCExternalSymbolizer.
+/// A better API would not rely on actually calling the two methods here from
+/// inside each disassembler, but would use the instr info to determine what
+/// operands are actually symbolizable, and in what way. I don't think this
+/// information exists right now.
+class MCSymbolizer {
+  MCSymbolizer(const MCSymbolizer &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCSymbolizer &) LLVM_DELETED_FUNCTION;
+
+protected:
+  MCContext &Ctx;
+  std::unique_ptr<MCRelocationInfo> RelInfo;
+
+public:
+  /// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo.
+  MCSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo)
+    : Ctx(Ctx), RelInfo(std::move(RelInfo)) {
+  }
+
+  virtual ~MCSymbolizer();
+
+  /// \brief Try to add a symbolic operand instead of \p Value to the MCInst.
+  ///
+  /// Instead of having a difficult to read immediate, a symbolic operand would
+  /// represent this immediate in a more understandable way, for instance as a
+  /// symbol or an offset from a symbol. Relocations can also be used to enrich
+  /// the symbolic expression.
+  /// @param Inst      - The MCInst where to insert the symbolic operand.
+  /// @param cStream   - Stream to print comments and annotations on.
+  /// @param Value     - Operand value, pc-adjusted by the caller if necessary.
+  /// @param Address   - Load address of the instruction.
+  /// @param IsBranch  - Is the instruction a branch?
+  /// @param Offset    - Byte offset of the operand inside the inst.
+  /// @param InstSize  - Size of the instruction in bytes.
+  /// @return Whether a symbolic operand was added.
+  virtual bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream,
+                                        int64_t Value, uint64_t Address,
+                                        bool IsBranch, uint64_t Offset,
+                                        uint64_t InstSize) = 0;
+
+  /// \brief Try to add a comment on the PC-relative load.
+  /// For instance, in Mach-O, this is used to add annotations to instructions
+  /// that use C string literals, as found in __cstring.
+  virtual void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
+                                               int64_t Value,
+                                               uint64_t Address) = 0;
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
new file mode 100644
index 0000000..9a5881b
--- /dev/null
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -0,0 +1,199 @@
+//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_TARGETPARSER_H
+#define LLVM_MC_TARGETPARSER_H
+
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCTargetOptions.h"
+
+#include <memory>
+
+namespace llvm {
+class AsmToken;
+class MCInst;
+class MCParsedAsmOperand;
+class MCStreamer;
+class SMLoc;
+class StringRef;
+template <typename T> class SmallVectorImpl;
+
+typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
+
+enum AsmRewriteKind {
+  AOK_Delete = 0,     // Rewrite should be ignored.
+  AOK_Align,          // Rewrite align as .align.
+  AOK_DotOperator,    // Rewrite a dot operator expression as an immediate.
+                      // E.g., [eax].foo.bar -> [eax].8
+  AOK_Emit,           // Rewrite _emit as .byte.
+  AOK_Imm,            // Rewrite as $$N.
+  AOK_ImmPrefix,      // Add $$ before a parsed Imm.
+  AOK_Input,          // Rewrite in terms of $N.
+  AOK_Output,         // Rewrite in terms of $N.
+  AOK_SizeDirective,  // Add a sizing directive (e.g., dword ptr).
+  AOK_Skip            // Skip emission (e.g., offset/type operators).
+};
+
+const char AsmRewritePrecedence [] = {
+  0, // AOK_Delete
+  1, // AOK_Align
+  1, // AOK_DotOperator
+  1, // AOK_Emit
+  3, // AOK_Imm
+  3, // AOK_ImmPrefix
+  2, // AOK_Input
+  2, // AOK_Output
+  4, // AOK_SizeDirective
+  1  // AOK_Skip
+};
+
+struct AsmRewrite {
+  AsmRewriteKind Kind;
+  SMLoc Loc;
+  unsigned Len;
+  unsigned Val;
+public:
+  AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
+    : Kind(kind), Loc(loc), Len(len), Val(val) {}
+};
+
+struct ParseInstructionInfo {
+
+  SmallVectorImpl<AsmRewrite> *AsmRewrites;
+
+  ParseInstructionInfo() : AsmRewrites(nullptr) {}
+  ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
+    : AsmRewrites(rewrites) {}
+
+  ~ParseInstructionInfo() {}
+};
+
+/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
+class MCTargetAsmParser : public MCAsmParserExtension {
+public:
+  enum MatchResultTy {
+    Match_InvalidOperand,
+    Match_MissingFeature,
+    Match_MnemonicFail,
+    Match_Success,
+    FIRST_TARGET_MATCH_RESULT_TY
+  };
+
+private:
+  MCTargetAsmParser(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
+  void operator=(const MCTargetAsmParser &) LLVM_DELETED_FUNCTION;
+protected: // Can only create subclasses.
+  MCTargetAsmParser();
+
+  /// AvailableFeatures - The current set of available features.
+  unsigned AvailableFeatures;
+
+  /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
+  bool ParsingInlineAsm;
+
+  /// SemaCallback - The Sema callback implementation.  Must be set when parsing
+  /// ms-style inline assembly.
+  MCAsmParserSemaCallback *SemaCallback;
+
+  /// Set of options which affects instrumentation of inline assembly.
+  MCTargetOptions MCOptions;
+
+public:
+  virtual ~MCTargetAsmParser();
+
+  unsigned getAvailableFeatures() const { return AvailableFeatures; }
+  void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
+  bool isParsingInlineAsm () { return ParsingInlineAsm; }
+  void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
+
+  void setSemaCallback(MCAsmParserSemaCallback *Callback) {
+    SemaCallback = Callback;
+  }
+
+  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
+                             SMLoc &EndLoc) = 0;
+
+  /// ParseInstruction - Parse one assembly instruction.
+  ///
+  /// The parser is positioned following the instruction name. The target
+  /// specific instruction parser should parse the entire instruction and
+  /// construct the appropriate MCInst, or emit an error. On success, the entire
+  /// line should be parsed up to and including the end-of-statement token. On
+  /// failure, the parser is not required to read to the end of the line.
+  //
+  /// \param Name - The instruction name.
+  /// \param NameLoc - The source location of the name.
+  /// \param Operands [out] - The list of parsed operands, this returns
+  ///        ownership of them to the caller.
+  /// \return True on failure.
+  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
+                                SMLoc NameLoc, OperandVector &Operands) = 0;
+
+  /// ParseDirective - Parse a target specific assembler directive
+  ///
+  /// The parser is positioned following the directive name.  The target
+  /// specific directive parser should parse the entire directive doing or
+  /// recording any target specific work, or return true and do nothing if the
+  /// directive is not target specific. If the directive is specific for
+  /// the target, the entire line is parsed up to and including the
+  /// end-of-statement token and false is returned.
+  ///
+  /// \param DirectiveID - the identifier token of the directive.
+  virtual bool ParseDirective(AsmToken DirectiveID) = 0;
+
+  /// mnemonicIsValid - This returns true if this is a valid mnemonic and false
+  /// otherwise.
+  virtual bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) = 0;
+
+  /// MatchAndEmitInstruction - Recognize a series of operands of a parsed
+  /// instruction as an actual MCInst and emit it to the specified MCStreamer.
+  /// This returns false on success and returns true on failure to match.
+  ///
+  /// On failure, the target parser is responsible for emitting a diagnostic
+  /// explaining the match failure.
+  virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
+                                       OperandVector &Operands, MCStreamer &Out,
+                                       unsigned &ErrorInfo,
+                                       bool MatchingInlineAsm) = 0;
+
+  /// Allows targets to let registers opt out of clobber lists.
+  virtual bool OmitRegisterFromClobberLists(unsigned RegNo) { return false; }
+
+  /// Allow a target to add special case operand matching for things that
+  /// tblgen doesn't/can't handle effectively. For example, literal
+  /// immediates on ARM. TableGen expects a token operand, but the parser
+  /// will recognize them as immediates.
+  virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
+                                              unsigned Kind) {
+    return Match_InvalidOperand;
+  }
+
+  /// checkTargetMatchPredicate - Validate the instruction match against
+  /// any complex target predicates not expressible via match classes.
+  virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
+    return Match_Success;
+  }
+
+  virtual void convertToMapAndConstraints(unsigned Kind,
+                                          const OperandVector &Operands) = 0;
+
+  virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
+                                            MCSymbolRefExpr::VariantKind,
+                                            MCContext &Ctx) {
+    return nullptr;
+  }
+
+  virtual void onLabelParsed(MCSymbol *Symbol) { };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCTargetOptions.h b/include/llvm/MC/MCTargetOptions.h
new file mode 100644
index 0000000..eb4348e
--- /dev/null
+++ b/include/llvm/MC/MCTargetOptions.h
@@ -0,0 +1,56 @@
+//===- MCTargetOptions.h - MC Target Options -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONS_H
+#define LLVM_MC_MCTARGETOPTIONS_H
+
+namespace llvm {
+
+class MCTargetOptions {
+public:
+  enum AsmInstrumentation {
+    AsmInstrumentationNone,
+    AsmInstrumentationAddress
+  };
+
+  /// Enables AddressSanitizer instrumentation at machine level.
+  bool SanitizeAddress : 1;
+
+  bool MCRelaxAll : 1;
+  bool MCNoExecStack : 1;
+  bool MCSaveTempLabels : 1;
+  bool MCUseDwarfDirectory : 1;
+  bool ShowMCEncoding : 1;
+  bool ShowMCInst : 1;
+  bool AsmVerbose : 1;
+  int DwarfVersion;
+  MCTargetOptions();
+};
+
+inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
+#define ARE_EQUAL(X) LHS.X == RHS.X
+  return (ARE_EQUAL(SanitizeAddress) &&
+          ARE_EQUAL(MCRelaxAll) &&
+          ARE_EQUAL(MCNoExecStack) &&
+          ARE_EQUAL(MCSaveTempLabels) &&
+          ARE_EQUAL(MCUseDwarfDirectory) &&
+          ARE_EQUAL(ShowMCEncoding) &&
+          ARE_EQUAL(ShowMCInst) &&
+          ARE_EQUAL(AsmVerbose) &&
+	  ARE_EQUAL(DwarfVersion));
+#undef ARE_EQUAL
+}
+
+inline bool operator!=(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
+  return !(LHS == RHS);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCTargetOptionsCommandFlags.h b/include/llvm/MC/MCTargetOptionsCommandFlags.h
new file mode 100644
index 0000000..6d4eb0e
--- /dev/null
+++ b/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -0,0 +1,53 @@
+//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/MC/MCTargetOptions.h"
+using namespace llvm;
+
+cl::opt<MCTargetOptions::AsmInstrumentation> AsmInstrumentation(
+    "asm-instrumentation", cl::desc("Instrumentation of inline assembly and "
+                                    "assembly source files"),
+    cl::init(MCTargetOptions::AsmInstrumentationNone),
+    cl::values(clEnumValN(MCTargetOptions::AsmInstrumentationNone, "none",
+                          "no instrumentation at all"),
+               clEnumValN(MCTargetOptions::AsmInstrumentationAddress, "address",
+                          "instrument instructions with memory arguments"),
+               clEnumValEnd));
+
+cl::opt<bool> RelaxAll("mc-relax-all",
+                       cl::desc("When used with filetype=obj, "
+                                "relax all fixups in the emitted object file"));
+
+cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
+                          cl::init(0));
+
+cl::opt<bool> ShowMCInst("asm-show-inst",
+                         cl::desc("Emit internal instruction representation to "
+                                  "assembly file"));
+
+static inline MCTargetOptions InitMCTargetOptionsFromFlags() {
+  MCTargetOptions Options;
+  Options.SanitizeAddress =
+      (AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
+  Options.MCRelaxAll = RelaxAll;
+  Options.DwarfVersion = DwarfVersion;
+  Options.ShowMCInst = ShowMCInst;
+  return Options;
+}
+
+#endif
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
new file mode 100644
index 0000000..dd86979
--- /dev/null
+++ b/include/llvm/MC/MCValue.h
@@ -0,0 +1,90 @@
+//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCVALUE_H
+#define LLVM_MC_MCVALUE_H
+
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmInfo;
+class raw_ostream;
+
+/// MCValue - This represents an "assembler immediate".  In its most
+/// general form, this can hold ":Kind:(SymbolA - SymbolB + imm64)".
+/// Not all targets supports relocations of this general form, but we
+/// need to represent this anyway.
+///
+/// In general both SymbolA and SymbolB will also have a modifier
+/// analogous to the top-level Kind. Current targets are not expected
+/// to make use of both though. The choice comes down to whether
+/// relocation modifiers apply to the closest symbol or the whole
+/// expression.
+///
+/// In the general form, SymbolB can only be defined if SymbolA is, and both
+/// must be in the same (non-external) section. The latter constraint is not
+/// enforced, since a symbol's section may not be known at construction.
+///
+/// Note that this class must remain a simple POD value class, because we need
+/// it to live in unions etc.
+class MCValue {
+  const MCSymbolRefExpr *SymA, *SymB;
+  int64_t Cst;
+  uint32_t RefKind;
+public:
+
+  int64_t getConstant() const { return Cst; }
+  const MCSymbolRefExpr *getSymA() const { return SymA; }
+  const MCSymbolRefExpr *getSymB() const { return SymB; }
+  uint32_t getRefKind() const { return RefKind; }
+
+  /// isAbsolute - Is this an absolute (as opposed to relocatable) value.
+  bool isAbsolute() const { return !SymA && !SymB; }
+
+  /// print - Print the value to the stream \p OS.
+  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+
+  /// dump - Print the value to stderr.
+  void dump() const;
+
+  MCSymbolRefExpr::VariantKind getAccessVariant() const;
+
+  static MCValue get(const MCSymbolRefExpr *SymA,
+                     const MCSymbolRefExpr *SymB = nullptr,
+                     int64_t Val = 0, uint32_t RefKind = 0) {
+    MCValue R;
+    assert((!SymB || SymA) && "Invalid relocatable MCValue!");
+    R.Cst = Val;
+    R.SymA = SymA;
+    R.SymB = SymB;
+    R.RefKind = RefKind;
+    return R;
+  }
+
+  static MCValue get(int64_t Val) {
+    MCValue R;
+    R.Cst = Val;
+    R.SymA = nullptr;
+    R.SymB = nullptr;
+    R.RefKind = 0;
+    return R;
+  }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h
new file mode 100644
index 0000000..3df0d0a
--- /dev/null
+++ b/include/llvm/MC/MCWin64EH.h
@@ -0,0 +1,87 @@
+//===- MCWin64EH.h - Machine Code Win64 EH support --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains declarations to support the Win64 Exception Handling
+// scheme in MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWIN64EH_H
+#define LLVM_MC_MCWIN64EH_H
+
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/Win64EH.h"
+#include <vector>
+
+namespace llvm {
+  class StringRef;
+  class MCStreamer;
+  class MCSymbol;
+
+namespace Win64EH {
+struct Instruction {
+  static WinEH::Instruction PushNonVol(MCSymbol *L, unsigned Reg) {
+    return WinEH::Instruction(Win64EH::UOP_PushNonVol, L, Reg, -1);
+  }
+  static WinEH::Instruction Alloc(MCSymbol *L, unsigned Size) {
+    return WinEH::Instruction(Size > 128 ? UOP_AllocLarge : UOP_AllocSmall, L,
+                              -1, Size);
+  }
+  static WinEH::Instruction PushMachFrame(MCSymbol *L, bool Code) {
+    return WinEH::Instruction(UOP_PushMachFrame, L, -1, Code ? 1 : 0);
+  }
+  static WinEH::Instruction SaveNonVol(MCSymbol *L, unsigned Reg,
+                                       unsigned Offset) {
+    return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveNonVolBig
+                                                      : UOP_SaveNonVol,
+                              L, Reg, Offset);
+  }
+  static WinEH::Instruction SaveXMM(MCSymbol *L, unsigned Reg,
+                                    unsigned Offset) {
+    return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveXMM128Big
+                                                      : UOP_SaveXMM128,
+                              L, Reg, Offset);
+  }
+  static WinEH::Instruction SetFPReg(MCSymbol *L, unsigned Reg, unsigned Off) {
+    return WinEH::Instruction(UOP_SetFPReg, L, Reg, Off);
+  }
+};
+}
+
+  struct MCWinFrameInfo {
+    MCWinFrameInfo()
+      : Begin(nullptr), End(nullptr),ExceptionHandler(nullptr),
+        Function(nullptr), PrologEnd(nullptr), Symbol(nullptr),
+        HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
+        ChainedParent(nullptr), Instructions() {}
+    MCSymbol *Begin;
+    MCSymbol *End;
+    const MCSymbol *ExceptionHandler;
+    const MCSymbol *Function;
+    MCSymbol *PrologEnd;
+    MCSymbol *Symbol;
+    bool HandlesUnwind;
+    bool HandlesExceptions;
+    int LastFrameInst;
+    MCWinFrameInfo *ChainedParent;
+    std::vector<WinEH::Instruction> Instructions;
+  };
+
+  class MCWin64EHUnwindEmitter {
+  public:
+    static StringRef GetSectionSuffix(const MCSymbol *func);
+    //
+    // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
+    //
+    static void Emit(MCStreamer &streamer);
+    static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info);
+  };
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
new file mode 100644
index 0000000..dad7bb5
--- /dev/null
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -0,0 +1,45 @@
+//===-- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINCOFFOBJECTWRITER_H
+#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
+
+namespace llvm {
+  class MCFixup;
+  class MCObjectWriter;
+  class MCValue;
+  class raw_ostream;
+
+  class MCWinCOFFObjectTargetWriter {
+    virtual void anchor();
+    const unsigned Machine;
+
+  protected:
+    MCWinCOFFObjectTargetWriter(unsigned Machine_);
+
+  public:
+    virtual ~MCWinCOFFObjectTargetWriter() {}
+
+    unsigned getMachine() const { return Machine; }
+    virtual unsigned getRelocType(const MCValue &Target,
+                                  const MCFixup &Fixup,
+                                  bool IsCrossSection) const = 0;
+    virtual bool recordRelocation(const MCFixup &) const { return true; }
+  };
+
+  /// \brief Construct a new Win COFF writer instance.
+  ///
+  /// \param MOTW - The target specific WinCOFF writer subclass.
+  /// \param OS - The stream to write to.
+  /// \returns The constructed object writer.
+  MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
+                                            raw_ostream &OS);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h
new file mode 100644
index 0000000..7d2d0e4
--- /dev/null
+++ b/include/llvm/MC/MCWinCOFFStreamer.h
@@ -0,0 +1,74 @@
+//===- MCWinCOFFStreamer.h - COFF Object File Interface ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINCOFFSTREAMER_H
+#define LLVM_MC_MCWINCOFFSTREAMER_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+
+namespace llvm {
+class MCAsmBackend;
+class MCContext;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class MCSection;
+class MCSubtargetInfo;
+class MCSymbol;
+class StringRef;
+class raw_ostream;
+
+class MCWinCOFFStreamer : public MCObjectStreamer {
+public:
+  MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE,
+                    raw_ostream &OS);
+
+  /// \name MCStreamer interface
+  /// \{
+
+  void InitSections() override;
+  void EmitLabel(MCSymbol *Symbol) override;
+  void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+  void EmitThumbFunc(MCSymbol *Func) override;
+  bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+  void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+  void BeginCOFFSymbolDef(MCSymbol const *Symbol) override;
+  void EmitCOFFSymbolStorageClass(int StorageClass) override;
+  void EmitCOFFSymbolType(int Type) override;
+  void EndCOFFSymbolDef() override;
+  void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
+  void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+  void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
+  void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                        unsigned ByteAlignment) override;
+  void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                             unsigned ByteAlignment) override;
+  void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+                    unsigned ByteAlignment) override;
+  void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+                      unsigned ByteAlignment) override;
+  void EmitFileDirective(StringRef Filename) override;
+  void EmitIdent(StringRef IdentString) override;
+  void EmitWinEHHandlerData() override;
+  void FinishImpl() override;
+
+  /// \}
+
+protected:
+  const MCSymbol *CurSymbol;
+  void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+private:
+  LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const;
+};
+}
+
+#endif
+
diff --git a/include/llvm/MC/MCWinEH.h b/include/llvm/MC/MCWinEH.h
new file mode 100644
index 0000000..1cd1b0f
--- /dev/null
+++ b/include/llvm/MC/MCWinEH.h
@@ -0,0 +1,29 @@
+//===- MCWinEH.h - Windows Unwinding Support --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINEH_H
+#define LLVM_MC_MCWINEH_H
+
+namespace llvm {
+class MCSymbol;
+
+namespace WinEH {
+struct Instruction {
+  const MCSymbol *Label;
+  const unsigned Offset;
+  const unsigned Register;
+  const unsigned Operation;
+
+  Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
+    : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
+};
+}
+}
+
+#endif
diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h
new file mode 100644
index 0000000..2a18615
--- /dev/null
+++ b/include/llvm/MC/MachineLocation.h
@@ -0,0 +1,83 @@
+//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame.  Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset.  Register indirection can be specified by
+// explicitly passing an offset to the constructor.
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_MACHINELOCATION_H
+#define LLVM_MC_MACHINELOCATION_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class MCSymbol;
+
+class MachineLocation {
+private:
+  bool IsRegister;                      // True if location is a register.
+  unsigned Register;                    // gcc/gdb register number.
+  int Offset;                           // Displacement if not register.
+public:
+  enum : uint32_t {
+    // The target register number for an abstract frame pointer. The value is
+    // an arbitrary value that doesn't collide with any real target register.
+    VirtualFP = ~0U
+  };
+  MachineLocation()
+    : IsRegister(false), Register(0), Offset(0) {}
+  /// Create a direct register location.
+  explicit MachineLocation(unsigned R)
+    : IsRegister(true), Register(R), Offset(0) {}
+  /// Create a register-indirect location with an offset.
+  MachineLocation(unsigned R, int O)
+    : IsRegister(false), Register(R), Offset(O) {}
+
+  bool operator==(const MachineLocation &Other) const {
+      return IsRegister == Other.IsRegister && Register == Other.Register &&
+        Offset == Other.Offset;
+  }
+
+  // Accessors.
+  /// \return true iff this is a register-indirect location.
+  bool isIndirect()      const { return !IsRegister; }
+  bool isReg()           const { return IsRegister; }
+  unsigned getReg()      const { return Register; }
+  int getOffset()        const { return Offset; }
+  void setIsRegister(bool Is)  { IsRegister = Is; }
+  void setRegister(unsigned R) { Register = R; }
+  void setOffset(int O)        { Offset = O; }
+  /// Make this location a direct register location.
+  void set(unsigned R) {
+    IsRegister = true;
+    Register = R;
+    Offset = 0;
+  }
+  /// Make this location a register-indirect+offset location.
+  void set(unsigned R, int O) {
+    IsRegister = false;
+    Register = R;
+    Offset = O;
+  }
+
+#ifndef NDEBUG
+  void dump();
+#endif
+};
+
+inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) {
+  return !(LHS == RHS);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h
new file mode 100644
index 0000000..85a91c6
--- /dev/null
+++ b/include/llvm/MC/SectionKind.h
@@ -0,0 +1,240 @@
+//===-- llvm/Target/TargetLoweringObjectFile.h - Object 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 implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SECTIONKIND_H
+#define LLVM_MC_SECTIONKIND_H
+
+namespace llvm {
+
+/// SectionKind - This is a simple POD value that classifies the properties of
+/// a section.  A section is classified into the deepest possible
+/// classification, and then the target maps them onto their sections based on
+/// what capabilities they have.
+///
+/// The comments below describe these as if they were an inheritance hierarchy
+/// in order to explain the predicates below.
+///
+class SectionKind {
+  enum Kind {
+    /// Metadata - Debug info sections or other metadata.
+    Metadata,
+
+    /// Text - Text section, used for functions and other executable code.
+    Text,
+
+    /// ReadOnly - Data that is never written to at program runtime by the
+    /// program or the dynamic linker.  Things in the top-level readonly
+    /// SectionKind are not mergeable.
+    ReadOnly,
+
+        /// MergableCString - Any null-terminated string which allows merging.
+        /// These values are known to end in a nul value of the specified size,
+        /// not otherwise contain a nul value, and be mergable.  This allows the
+        /// linker to unique the strings if it so desires.
+
+           /// Mergeable1ByteCString - 1 byte mergable, null terminated, string.
+           Mergeable1ByteCString,
+
+           /// Mergeable2ByteCString - 2 byte mergable, null terminated, string.
+           Mergeable2ByteCString,
+
+           /// Mergeable4ByteCString - 4 byte mergable, null terminated, string.
+           Mergeable4ByteCString,
+
+        /// MergeableConst - These are sections for merging fixed-length
+        /// constants together.  For example, this can be used to unique
+        /// constant pool entries etc.
+        MergeableConst,
+
+            /// MergeableConst4 - This is a section used by 4-byte constants,
+            /// for example, floats.
+            MergeableConst4,
+
+            /// MergeableConst8 - This is a section used by 8-byte constants,
+            /// for example, doubles.
+            MergeableConst8,
+
+            /// MergeableConst16 - This is a section used by 16-byte constants,
+            /// for example, vectors.
+            MergeableConst16,
+
+    /// Writeable - This is the base of all segments that need to be written
+    /// to during program runtime.
+
+       /// ThreadLocal - This is the base of all TLS segments.  All TLS
+       /// objects must be writeable, otherwise there is no reason for them to
+       /// be thread local!
+
+           /// ThreadBSS - Zero-initialized TLS data objects.
+           ThreadBSS,
+
+           /// ThreadData - Initialized TLS data objects.
+           ThreadData,
+
+       /// GlobalWriteableData - Writeable data that is global (not thread
+       /// local).
+
+           /// BSS - Zero initialized writeable data.
+           BSS,
+
+               /// BSSLocal - This is BSS (zero initialized and writable) data
+               /// which has local linkage.
+               BSSLocal,
+
+               /// BSSExtern - This is BSS data with normal external linkage.
+               BSSExtern,
+
+           /// Common - Data with common linkage.  These represent tentative
+           /// definitions, which always have a zero initializer and are never
+           /// marked 'constant'.
+           Common,
+
+           /// DataRel - This is the most general form of data that is written
+           /// to by the program, it can have random relocations to arbitrary
+           /// globals.
+           DataRel,
+
+               /// DataRelLocal - This is writeable data that has a non-zero
+               /// initializer and has relocations in it, but all of the
+               /// relocations are known to be within the final linked image
+               /// the global is linked into.
+               DataRelLocal,
+
+                   /// DataNoRel - This is writeable data that has a non-zero
+                   /// initializer, but whose initializer is known to have no
+                   /// relocations.
+                   DataNoRel,
+
+           /// ReadOnlyWithRel - These are global variables that are never
+           /// written to by the program, but that have relocations, so they
+           /// must be stuck in a writeable section so that the dynamic linker
+           /// can write to them.  If it chooses to, the dynamic linker can
+           /// mark the pages these globals end up on as read-only after it is
+           /// done with its relocation phase.
+           ReadOnlyWithRel,
+
+               /// ReadOnlyWithRelLocal - This is data that is readonly by the
+               /// program, but must be writeable so that the dynamic linker
+               /// can perform relocations in it.  This is used when we know
+               /// that all the relocations are to globals in this final
+               /// linked image.
+               ReadOnlyWithRelLocal
+
+  } K : 8;
+public:
+
+  bool isMetadata() const { return K == Metadata; }
+  bool isText() const { return K == Text; }
+
+  bool isReadOnly() const {
+    return K == ReadOnly || isMergeableCString() ||
+           isMergeableConst();
+  }
+
+  bool isMergeableCString() const {
+    return K == Mergeable1ByteCString || K == Mergeable2ByteCString ||
+           K == Mergeable4ByteCString;
+  }
+  bool isMergeable1ByteCString() const { return K == Mergeable1ByteCString; }
+  bool isMergeable2ByteCString() const { return K == Mergeable2ByteCString; }
+  bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
+
+  bool isMergeableConst() const {
+    return K == MergeableConst || K == MergeableConst4 ||
+           K == MergeableConst8 || K == MergeableConst16;
+  }
+  bool isMergeableConst4() const { return K == MergeableConst4; }
+  bool isMergeableConst8() const { return K == MergeableConst8; }
+  bool isMergeableConst16() const { return K == MergeableConst16; }
+
+  bool isWriteable() const {
+    return isThreadLocal() || isGlobalWriteableData();
+  }
+
+  bool isThreadLocal() const {
+    return K == ThreadData || K == ThreadBSS;
+  }
+
+  bool isThreadBSS() const { return K == ThreadBSS; }
+  bool isThreadData() const { return K == ThreadData; }
+
+  bool isGlobalWriteableData() const {
+    return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
+  }
+
+  bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
+  bool isBSSLocal() const { return K == BSSLocal; }
+  bool isBSSExtern() const { return K == BSSExtern; }
+
+  bool isCommon() const { return K == Common; }
+
+  bool isDataRel() const {
+    return K == DataRel || K == DataRelLocal || K == DataNoRel;
+  }
+
+  bool isDataRelLocal() const {
+    return K == DataRelLocal || K == DataNoRel;
+  }
+
+  bool isDataNoRel() const { return K == DataNoRel; }
+
+  bool isReadOnlyWithRel() const {
+    return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
+  }
+
+  bool isReadOnlyWithRelLocal() const {
+    return K == ReadOnlyWithRelLocal;
+  }
+private:
+  static SectionKind get(Kind K) {
+    SectionKind Res;
+    Res.K = K;
+    return Res;
+  }
+public:
+
+  static SectionKind getMetadata() { return get(Metadata); }
+  static SectionKind getText() { return get(Text); }
+  static SectionKind getReadOnly() { return get(ReadOnly); }
+  static SectionKind getMergeable1ByteCString() {
+    return get(Mergeable1ByteCString);
+  }
+  static SectionKind getMergeable2ByteCString() {
+    return get(Mergeable2ByteCString);
+  }
+  static SectionKind getMergeable4ByteCString() {
+    return get(Mergeable4ByteCString);
+  }
+  static SectionKind getMergeableConst() { return get(MergeableConst); }
+  static SectionKind getMergeableConst4() { return get(MergeableConst4); }
+  static SectionKind getMergeableConst8() { return get(MergeableConst8); }
+  static SectionKind getMergeableConst16() { return get(MergeableConst16); }
+  static SectionKind getThreadBSS() { return get(ThreadBSS); }
+  static SectionKind getThreadData() { return get(ThreadData); }
+  static SectionKind getBSS() { return get(BSS); }
+  static SectionKind getBSSLocal() { return get(BSSLocal); }
+  static SectionKind getBSSExtern() { return get(BSSExtern); }
+  static SectionKind getCommon() { return get(Common); }
+  static SectionKind getDataRel() { return get(DataRel); }
+  static SectionKind getDataRelLocal() { return get(DataRelLocal); }
+  static SectionKind getDataNoRel() { return get(DataNoRel); }
+  static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
+  static SectionKind getReadOnlyWithRelLocal(){
+    return get(ReadOnlyWithRelLocal);
+  }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/StringTableBuilder.h b/include/llvm/MC/StringTableBuilder.h
new file mode 100644
index 0000000..065e9e0
--- /dev/null
+++ b/include/llvm/MC/StringTableBuilder.h
@@ -0,0 +1,59 @@
+//===-- StringTableBuilder.h - String table building utility ------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_STRINGTABLE_BUILDER_H
+#define LLVM_MC_STRINGTABLE_BUILDER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include <cassert>
+
+namespace llvm {
+
+/// \brief Utility for building string tables with deduplicated suffixes.
+class StringTableBuilder {
+  SmallString<256> StringTable;
+  StringMap<size_t> StringIndexMap;
+
+public:
+  /// \brief Add a string to the builder. Returns a StringRef to the internal
+  /// copy of s. Can only be used before the table is finalized.
+  StringRef add(StringRef s) {
+    assert(!isFinalized());
+    return StringIndexMap.GetOrCreateValue(s, 0).getKey();
+  }
+
+  /// \brief Analyze the strings and build the final table. No more strings can
+  /// be added after this point.
+  void finalize();
+
+  /// \brief Retrieve the string table data. Can only be used after the table
+  /// is finalized.
+  StringRef data() {
+    assert(isFinalized());
+    return StringTable;
+  }
+
+  /// \brief Get the offest of a string in the string table. Can only be used
+  /// after the table is finalized.
+  size_t getOffset(StringRef s) {
+    assert(isFinalized());
+    assert(StringIndexMap.count(s) && "String is not in table!");
+    return StringIndexMap[s];
+  }
+
+private:
+  bool isFinalized() {
+    return !StringTable.empty();
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
new file mode 100644
index 0000000..c5d62a6
--- /dev/null
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -0,0 +1,105 @@
+//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- 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 and manages user or tool specified CPU characteristics.
+// The intent is to be able to package specific features that should or should
+// not be used on a specific target processor.  A tool, such as llc, could, as
+// as example, gather chip info from the command line, a long with features
+// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class raw_ostream;
+  class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatureKV - Used to provide key value pairs for feature and
+/// CPU bit flags.
+//
+struct SubtargetFeatureKV {
+  const char *Key;                      // K-V key string
+  const char *Desc;                     // Help descriptor
+  uint64_t Value;                       // K-V integer value
+  uint64_t Implies;                     // K-V bit mask
+
+  // Compare routine for std::lower_bound
+  bool operator<(StringRef S) const {
+    return StringRef(Key) < S;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
+/// pointers.
+//
+struct SubtargetInfoKV {
+  const char *Key;                      // K-V key string
+  const void *Value;                    // K-V pointer value
+
+  // Compare routine for std::lower_bound
+  bool operator<(StringRef S) const {
+    return StringRef(Key) < S;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatures - Manages the enabling and disabling of subtarget
+/// specific features.  Features are encoded as a string of the form
+///   "+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+///
+
+class SubtargetFeatures {
+  std::vector<std::string> Features;    // Subtarget features as a vector
+public:
+  explicit SubtargetFeatures(const StringRef Initial = "");
+
+  /// Features string accessors.
+  std::string getString() const;
+
+  /// Adding Features.
+  void AddFeature(const StringRef String);
+
+  /// ToggleFeature - Toggle a feature and returns the newly updated feature
+  /// bits.
+  uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
+                         ArrayRef<SubtargetFeatureKV> FeatureTable);
+
+  /// Get feature bits of a CPU.
+  uint64_t getFeatureBits(const StringRef CPU,
+                          ArrayRef<SubtargetFeatureKV> CPUTable,
+                          ArrayRef<SubtargetFeatureKV> FeatureTable);
+
+  /// Print feature string.
+  void print(raw_ostream &OS) const;
+
+  // Dump feature info.
+  void dump() const;
+
+  /// Adds the default features for the specified target triple.
+  void getDefaultSubtargetFeatures(const Triple& Triple);
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/MC/YAML.h b/include/llvm/MC/YAML.h
new file mode 100644
index 0000000..383cdc6
--- /dev/null
+++ b/include/llvm/MC/YAML.h
@@ -0,0 +1,94 @@
+#ifndef LLVM_MC_YAML_H
+#define LLVM_MC_YAML_H
+
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace yaml {
+/// \brief Specialized YAMLIO scalar type for representing a binary blob.
+///
+/// A typical use case would be to represent the content of a section in a
+/// binary file.
+/// This class has custom YAMLIO traits for convenient reading and writing.
+/// It renders as a string of hex digits in a YAML file.
+/// For example, it might render as `DEADBEEFCAFEBABE` (YAML does not
+/// require the quotation marks, so for simplicity when outputting they are
+/// omitted).
+/// When reading, any string whose content is an even number of hex digits
+/// will be accepted.
+/// For example, all of the following are acceptable:
+/// `DEADBEEF`, `"DeADbEeF"`, `"\x44EADBEEF"` (Note: '\x44' == 'D')
+///
+/// A significant advantage of using this class is that it never allocates
+/// temporary strings or buffers for any of its functionality.
+///
+/// Example:
+///
+/// The YAML mapping:
+/// \code
+/// Foo: DEADBEEFCAFEBABE
+/// \endcode
+///
+/// Could be modeled in YAMLIO by the struct:
+/// \code
+/// struct FooHolder {
+///   BinaryRef Foo;
+/// };
+/// namespace llvm {
+/// namespace yaml {
+/// template <>
+/// struct MappingTraits<FooHolder> {
+///   static void mapping(IO &IO, FooHolder &FH) {
+///     IO.mapRequired("Foo", FH.Foo);
+///   }
+/// };
+/// } // end namespace yaml
+/// } // end namespace llvm
+/// \endcode
+class BinaryRef {
+  friend bool operator==(const BinaryRef &LHS, const BinaryRef &RHS);
+  /// \brief Either raw binary data, or a string of hex bytes (must always
+  /// be an even number of characters).
+  ArrayRef<uint8_t> Data;
+  /// \brief Discriminator between the two states of the `Data` member.
+  bool DataIsHexString;
+
+public:
+  BinaryRef(ArrayRef<uint8_t> Data) : Data(Data), DataIsHexString(false) {}
+  BinaryRef(StringRef Data)
+      : Data(reinterpret_cast<const uint8_t *>(Data.data()), Data.size()),
+        DataIsHexString(true) {}
+  BinaryRef() : DataIsHexString(true) {}
+  /// \brief The number of bytes that are represented by this BinaryRef.
+  /// This is the number of bytes that writeAsBinary() will write.
+  ArrayRef<uint8_t>::size_type binary_size() const {
+    if (DataIsHexString)
+      return Data.size() / 2;
+    return Data.size();
+  }
+  /// \brief Write the contents (regardless of whether it is binary or a
+  /// hex string) as binary to the given raw_ostream.
+  void writeAsBinary(raw_ostream &OS) const;
+  /// \brief Write the contents (regardless of whether it is binary or a
+  /// hex string) as hex to the given raw_ostream.
+  ///
+  /// For example, a possible output could be `DEADBEEFCAFEBABE`.
+  void writeAsHex(raw_ostream &OS) const;
+};
+
+inline bool operator==(const BinaryRef &LHS, const BinaryRef &RHS) {
+  // Special case for default constructed BinaryRef.
+  if (LHS.Data.empty() && RHS.Data.empty())
+    return true;
+
+  return LHS.DataIsHexString == RHS.DataIsHexString && LHS.Data == RHS.Data;
+}
+
+template <> struct ScalarTraits<BinaryRef> {
+  static void output(const BinaryRef &, void *, llvm::raw_ostream &);
+  static StringRef input(StringRef, void *, BinaryRef &);
+  static bool mustQuote(StringRef S) { return needsQuotes(S); }
+};
+}
+}
+#endif
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
new file mode 100644
index 0000000..af6c995
--- /dev/null
+++ b/include/llvm/Object/Archive.h
@@ -0,0 +1,206 @@
+//===- Archive.h - ar archive file format -----------------------*- 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 ar archive file format class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVE_H
+#define LLVM_OBJECT_ARCHIVE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+namespace object {
+struct ArchiveMemberHeader {
+  char Name[16];
+  char LastModified[12];
+  char UID[6];
+  char GID[6];
+  char AccessMode[8];
+  char Size[10]; ///< Size of data, not including header or padding.
+  char Terminator[2];
+
+  /// Get the name without looking up long names.
+  llvm::StringRef getName() const;
+
+  /// Members are not larger than 4GB.
+  uint32_t getSize() const;
+
+  sys::fs::perms getAccessMode() const;
+  sys::TimeValue getLastModified() const;
+  unsigned getUID() const;
+  unsigned getGID() const;
+};
+
+class Archive : public Binary {
+  virtual void anchor();
+public:
+  class Child {
+    const Archive *Parent;
+    /// \brief Includes header but not padding byte.
+    StringRef Data;
+    /// \brief Offset from Data to the start of the file.
+    uint16_t StartOfFile;
+
+    const ArchiveMemberHeader *getHeader() const {
+      return reinterpret_cast<const ArchiveMemberHeader *>(Data.data());
+    }
+
+  public:
+    Child(const Archive *Parent, const char *Start);
+
+    bool operator ==(const Child &other) const {
+      assert(Parent == other.Parent);
+      return Data.begin() == other.Data.begin();
+    }
+
+    bool operator <(const Child &other) const {
+      return Data.begin() < other.Data.begin();
+    }
+
+    Child getNext() const;
+
+    ErrorOr<StringRef> getName() const;
+    StringRef getRawName() const { return getHeader()->getName(); }
+    sys::TimeValue getLastModified() const {
+      return getHeader()->getLastModified();
+    }
+    unsigned getUID() const { return getHeader()->getUID(); }
+    unsigned getGID() const { return getHeader()->getGID(); }
+    sys::fs::perms getAccessMode() const {
+      return getHeader()->getAccessMode();
+    }
+    /// \return the size of the archive member without the header or padding.
+    uint64_t getSize() const { return Data.size() - StartOfFile; }
+
+    StringRef getBuffer() const {
+      return StringRef(Data.data() + StartOfFile, getSize());
+    }
+
+    ErrorOr<std::unique_ptr<MemoryBuffer>>
+    getMemoryBuffer(bool FullPath = false) const;
+
+    ErrorOr<std::unique_ptr<Binary>>
+    getAsBinary(LLVMContext *Context = nullptr) const;
+  };
+
+  class child_iterator {
+    Child child;
+  public:
+    child_iterator() : child(Child(nullptr, nullptr)) {}
+    child_iterator(const Child &c) : child(c) {}
+    const Child* operator->() const {
+      return &child;
+    }
+
+    bool operator==(const child_iterator &other) const {
+      return child == other.child;
+    }
+
+    bool operator!=(const child_iterator &other) const {
+      return !(*this == other);
+    }
+
+    bool operator <(const child_iterator &other) const {
+      return child < other.child;
+    }
+
+    child_iterator& operator++() {  // Preincrement
+      child = child.getNext();
+      return *this;
+    }
+  };
+
+  class Symbol {
+    const Archive *Parent;
+    uint32_t SymbolIndex;
+    uint32_t StringIndex; // Extra index to the string.
+
+  public:
+    bool operator ==(const Symbol &other) const {
+      return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
+    }
+
+    Symbol(const Archive *p, uint32_t symi, uint32_t stri)
+      : Parent(p)
+      , SymbolIndex(symi)
+      , StringIndex(stri) {}
+    StringRef getName() const;
+    ErrorOr<child_iterator> getMember() const;
+    Symbol getNext() const;
+  };
+
+  class symbol_iterator {
+    Symbol symbol;
+  public:
+    symbol_iterator(const Symbol &s) : symbol(s) {}
+    const Symbol *operator->() const {
+      return &symbol;
+    }
+
+    bool operator==(const symbol_iterator &other) const {
+      return symbol == other.symbol;
+    }
+
+    bool operator!=(const symbol_iterator &other) const {
+      return !(*this == other);
+    }
+
+    symbol_iterator& operator++() {  // Preincrement
+      symbol = symbol.getNext();
+      return *this;
+    }
+  };
+
+  Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &EC);
+  static ErrorOr<Archive *> create(std::unique_ptr<MemoryBuffer> Source);
+
+  enum Kind {
+    K_GNU,
+    K_BSD,
+    K_COFF
+  };
+
+  Kind kind() const { 
+    return Format;
+  }
+
+  child_iterator child_begin(bool SkipInternal = true) const;
+  child_iterator child_end() const;
+
+  symbol_iterator symbol_begin() const;
+  symbol_iterator symbol_end() const;
+
+  // Cast methods.
+  static inline bool classof(Binary const *v) {
+    return v->isArchive();
+  }
+
+  // check if a symbol is in the archive
+  child_iterator findSym(StringRef name) const;
+
+  bool hasSymbolTable() const;
+
+private:
+  child_iterator SymbolTable;
+  child_iterator StringTable;
+  child_iterator FirstRegular;
+  Kind Format;
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
new file mode 100644
index 0000000..91984cb
--- /dev/null
+++ b/include/llvm/Object/Binary.h
@@ -0,0 +1,136 @@
+//===- Binary.h - A generic binary 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 Binary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_BINARY_H
+#define LLVM_OBJECT_BINARY_H
+
+#include "llvm/Object/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+
+class LLVMContext;
+class MemoryBuffer;
+class StringRef;
+
+namespace object {
+
+class Binary {
+private:
+  Binary() LLVM_DELETED_FUNCTION;
+  Binary(const Binary &other) LLVM_DELETED_FUNCTION;
+
+  unsigned int TypeID;
+
+protected:
+  std::unique_ptr<MemoryBuffer> Data;
+
+  Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
+
+  enum {
+    ID_Archive,
+    ID_MachOUniversalBinary,
+    ID_IR, // LLVM IR
+
+    // Object and children.
+    ID_StartObjects,
+    ID_COFF,
+
+    ID_ELF32L, // ELF 32-bit, little endian
+    ID_ELF32B, // ELF 32-bit, big endian
+    ID_ELF64L, // ELF 64-bit, little endian
+    ID_ELF64B, // ELF 64-bit, big endian
+
+    ID_MachO32L, // MachO 32-bit, little endian
+    ID_MachO32B, // MachO 32-bit, big endian
+    ID_MachO64L, // MachO 64-bit, little endian
+    ID_MachO64B, // MachO 64-bit, big endian
+
+    ID_EndObjects
+  };
+
+  static inline unsigned int getELFType(bool isLE, bool is64Bits) {
+    if (isLE)
+      return is64Bits ? ID_ELF64L : ID_ELF32L;
+    else
+      return is64Bits ? ID_ELF64B : ID_ELF32B;
+  }
+
+  static unsigned int getMachOType(bool isLE, bool is64Bits) {
+    if (isLE)
+      return is64Bits ? ID_MachO64L : ID_MachO32L;
+    else
+      return is64Bits ? ID_MachO64B : ID_MachO32B;
+  }
+
+public:
+  virtual ~Binary();
+
+  StringRef getData() const;
+  MemoryBuffer *releaseBuffer() { return Data.release(); }
+  StringRef getFileName() const;
+
+  // Cast methods.
+  unsigned int getType() const { return TypeID; }
+
+  // Convenience methods
+  bool isObject() const {
+    return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
+  }
+
+  bool isSymbolic() const {
+    return isIR() || isObject();
+  }
+
+  bool isArchive() const {
+    return TypeID == ID_Archive;
+  }
+
+  bool isMachOUniversalBinary() const {
+    return TypeID == ID_MachOUniversalBinary;
+  }
+
+  bool isELF() const {
+    return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
+  }
+
+  bool isMachO() const {
+    return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
+  }
+
+  bool isCOFF() const {
+    return TypeID == ID_COFF;
+  }
+
+  bool isIR() const {
+    return TypeID == ID_IR;
+  }
+
+  bool isLittleEndian() const {
+    return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
+             TypeID == ID_MachO32B || TypeID == ID_MachO64B);
+  }
+};
+
+/// @brief Create a Binary from Source, autodetecting the file type.
+///
+/// @param Source The data to create the Binary from.
+ErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> Source,
+                               LLVMContext *Context = nullptr);
+
+ErrorOr<Binary *> createBinary(StringRef Path);
+}
+}
+
+#endif
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
new file mode 100644
index 0000000..e2da070
--- /dev/null
+++ b/include/llvm/Object/COFF.h
@@ -0,0 +1,525 @@
+//===- COFF.h - COFF object file implementation -----------------*- 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 COFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_H
+#define LLVM_OBJECT_COFF_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+template <typename T> class ArrayRef;
+
+namespace object {
+class ImportDirectoryEntryRef;
+class ExportDirectoryEntryRef;
+typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator;
+typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator;
+
+/// The DOS compatible header at the front of all PE/COFF executables.
+struct dos_header {
+  support::ulittle16_t Magic;
+  support::ulittle16_t UsedBytesInTheLastPage;
+  support::ulittle16_t FileSizeInPages;
+  support::ulittle16_t NumberOfRelocationItems;
+  support::ulittle16_t HeaderSizeInParagraphs;
+  support::ulittle16_t MinimumExtraParagraphs;
+  support::ulittle16_t MaximumExtraParagraphs;
+  support::ulittle16_t InitialRelativeSS;
+  support::ulittle16_t InitialSP;
+  support::ulittle16_t Checksum;
+  support::ulittle16_t InitialIP;
+  support::ulittle16_t InitialRelativeCS;
+  support::ulittle16_t AddressOfRelocationTable;
+  support::ulittle16_t OverlayNumber;
+  support::ulittle16_t Reserved[4];
+  support::ulittle16_t OEMid;
+  support::ulittle16_t OEMinfo;
+  support::ulittle16_t Reserved2[10];
+  support::ulittle32_t AddressOfNewExeHeader;
+};
+
+struct coff_file_header {
+  support::ulittle16_t Machine;
+  support::ulittle16_t NumberOfSections;
+  support::ulittle32_t TimeDateStamp;
+  support::ulittle32_t PointerToSymbolTable;
+  support::ulittle32_t NumberOfSymbols;
+  support::ulittle16_t SizeOfOptionalHeader;
+  support::ulittle16_t Characteristics;
+
+  bool isImportLibrary() const { return NumberOfSections == 0xffff; }
+};
+
+/// The 32-bit PE header that follows the COFF header.
+struct pe32_header {
+  support::ulittle16_t Magic;
+  uint8_t MajorLinkerVersion;
+  uint8_t MinorLinkerVersion;
+  support::ulittle32_t SizeOfCode;
+  support::ulittle32_t SizeOfInitializedData;
+  support::ulittle32_t SizeOfUninitializedData;
+  support::ulittle32_t AddressOfEntryPoint;
+  support::ulittle32_t BaseOfCode;
+  support::ulittle32_t BaseOfData;
+  support::ulittle32_t ImageBase;
+  support::ulittle32_t SectionAlignment;
+  support::ulittle32_t FileAlignment;
+  support::ulittle16_t MajorOperatingSystemVersion;
+  support::ulittle16_t MinorOperatingSystemVersion;
+  support::ulittle16_t MajorImageVersion;
+  support::ulittle16_t MinorImageVersion;
+  support::ulittle16_t MajorSubsystemVersion;
+  support::ulittle16_t MinorSubsystemVersion;
+  support::ulittle32_t Win32VersionValue;
+  support::ulittle32_t SizeOfImage;
+  support::ulittle32_t SizeOfHeaders;
+  support::ulittle32_t CheckSum;
+  support::ulittle16_t Subsystem;
+  support::ulittle16_t DLLCharacteristics;
+  support::ulittle32_t SizeOfStackReserve;
+  support::ulittle32_t SizeOfStackCommit;
+  support::ulittle32_t SizeOfHeapReserve;
+  support::ulittle32_t SizeOfHeapCommit;
+  support::ulittle32_t LoaderFlags;
+  support::ulittle32_t NumberOfRvaAndSize;
+};
+
+/// The 64-bit PE header that follows the COFF header.
+struct pe32plus_header {
+  support::ulittle16_t Magic;
+  uint8_t MajorLinkerVersion;
+  uint8_t MinorLinkerVersion;
+  support::ulittle32_t SizeOfCode;
+  support::ulittle32_t SizeOfInitializedData;
+  support::ulittle32_t SizeOfUninitializedData;
+  support::ulittle32_t AddressOfEntryPoint;
+  support::ulittle32_t BaseOfCode;
+  support::ulittle64_t ImageBase;
+  support::ulittle32_t SectionAlignment;
+  support::ulittle32_t FileAlignment;
+  support::ulittle16_t MajorOperatingSystemVersion;
+  support::ulittle16_t MinorOperatingSystemVersion;
+  support::ulittle16_t MajorImageVersion;
+  support::ulittle16_t MinorImageVersion;
+  support::ulittle16_t MajorSubsystemVersion;
+  support::ulittle16_t MinorSubsystemVersion;
+  support::ulittle32_t Win32VersionValue;
+  support::ulittle32_t SizeOfImage;
+  support::ulittle32_t SizeOfHeaders;
+  support::ulittle32_t CheckSum;
+  support::ulittle16_t Subsystem;
+  support::ulittle16_t DLLCharacteristics;
+  support::ulittle64_t SizeOfStackReserve;
+  support::ulittle64_t SizeOfStackCommit;
+  support::ulittle64_t SizeOfHeapReserve;
+  support::ulittle64_t SizeOfHeapCommit;
+  support::ulittle32_t LoaderFlags;
+  support::ulittle32_t NumberOfRvaAndSize;
+};
+
+struct data_directory {
+  support::ulittle32_t RelativeVirtualAddress;
+  support::ulittle32_t Size;
+};
+
+struct import_directory_table_entry {
+  support::ulittle32_t ImportLookupTableRVA;
+  support::ulittle32_t TimeDateStamp;
+  support::ulittle32_t ForwarderChain;
+  support::ulittle32_t NameRVA;
+  support::ulittle32_t ImportAddressTableRVA;
+};
+
+struct import_lookup_table_entry32 {
+  support::ulittle32_t data;
+
+  bool isOrdinal() const { return data & 0x80000000; }
+
+  uint16_t getOrdinal() const {
+    assert(isOrdinal() && "ILT entry is not an ordinal!");
+    return data & 0xFFFF;
+  }
+
+  uint32_t getHintNameRVA() const {
+    assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+    return data;
+  }
+};
+
+struct export_directory_table_entry {
+  support::ulittle32_t ExportFlags;
+  support::ulittle32_t TimeDateStamp;
+  support::ulittle16_t MajorVersion;
+  support::ulittle16_t MinorVersion;
+  support::ulittle32_t NameRVA;
+  support::ulittle32_t OrdinalBase;
+  support::ulittle32_t AddressTableEntries;
+  support::ulittle32_t NumberOfNamePointers;
+  support::ulittle32_t ExportAddressTableRVA;
+  support::ulittle32_t NamePointerRVA;
+  support::ulittle32_t OrdinalTableRVA;
+};
+
+union export_address_table_entry {
+  support::ulittle32_t ExportRVA;
+  support::ulittle32_t ForwarderRVA;
+};
+
+typedef support::ulittle32_t export_name_pointer_table_entry;
+typedef support::ulittle16_t export_ordinal_table_entry;
+
+struct coff_symbol {
+  struct StringTableOffset {
+    support::ulittle32_t Zeroes;
+    support::ulittle32_t Offset;
+  };
+
+  union {
+    char ShortName[8];
+    StringTableOffset Offset;
+  } Name;
+
+  support::ulittle32_t Value;
+  support::ulittle16_t SectionNumber;
+
+  support::ulittle16_t Type;
+
+  support::ulittle8_t StorageClass;
+  support::ulittle8_t NumberOfAuxSymbols;
+
+  uint8_t getBaseType() const { return Type & 0x0F; }
+
+  uint8_t getComplexType() const { return (Type & 0xF0) >> 4; }
+
+  bool isFunctionDefinition() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+           getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+           getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+           !COFF::isReservedSectionNumber(SectionNumber);
+  }
+
+  bool isFunctionLineInfo() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION;
+  }
+
+  bool isWeakExternal() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
+           (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+            SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0);
+  }
+
+  bool isFileRecord() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_FILE;
+  }
+
+  bool isSectionDefinition() const {
+    // C++/CLI creates external ABS symbols for non-const appdomain globals.
+    // These are also followed by an auxiliary section definition.
+    bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+                             SectionNumber == COFF::IMAGE_SYM_ABSOLUTE;
+    bool isOrdinarySection =
+        StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0;
+    return isAppdomainGlobal || isOrdinarySection;
+  }
+
+  bool isCLRToken() const {
+    return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
+  }
+};
+
+struct coff_section {
+  char Name[8];
+  support::ulittle32_t VirtualSize;
+  support::ulittle32_t VirtualAddress;
+  support::ulittle32_t SizeOfRawData;
+  support::ulittle32_t PointerToRawData;
+  support::ulittle32_t PointerToRelocations;
+  support::ulittle32_t PointerToLinenumbers;
+  support::ulittle16_t NumberOfRelocations;
+  support::ulittle16_t NumberOfLinenumbers;
+  support::ulittle32_t Characteristics;
+
+  // Returns true if the actual number of relocations is stored in
+  // VirtualAddress field of the first relocation table entry.
+  bool hasExtendedRelocations() const {
+    return Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL &&
+        NumberOfRelocations == UINT16_MAX;
+  };
+};
+
+struct coff_relocation {
+  support::ulittle32_t VirtualAddress;
+  support::ulittle32_t SymbolTableIndex;
+  support::ulittle16_t Type;
+};
+
+struct coff_aux_function_definition {
+  support::ulittle32_t TagIndex;
+  support::ulittle32_t TotalSize;
+  support::ulittle32_t PointerToLinenumber;
+  support::ulittle32_t PointerToNextFunction;
+  char Unused[2];
+};
+
+struct coff_aux_bf_and_ef_symbol {
+  char Unused1[4];
+  support::ulittle16_t Linenumber;
+  char Unused2[6];
+  support::ulittle32_t PointerToNextFunction;
+  char Unused3[2];
+};
+
+struct coff_aux_weak_external {
+  support::ulittle32_t TagIndex;
+  support::ulittle32_t Characteristics;
+  char Unused[10];
+};
+
+struct coff_aux_file {
+  char FileName[18];
+};
+
+struct coff_aux_section_definition {
+  support::ulittle32_t Length;
+  support::ulittle16_t NumberOfRelocations;
+  support::ulittle16_t NumberOfLinenumbers;
+  support::ulittle32_t CheckSum;
+  support::ulittle16_t Number;
+  support::ulittle8_t Selection;
+  char Unused[3];
+};
+
+struct coff_aux_clr_token {
+  support::ulittle8_t AuxType;
+  support::ulittle8_t Reserved;
+  support::ulittle32_t SymbolTableIndex;
+  char Unused[12];
+};
+
+struct coff_load_configuration32 {
+  support::ulittle32_t Characteristics;
+  support::ulittle32_t TimeDateStamp;
+  support::ulittle16_t MajorVersion;
+  support::ulittle16_t MinorVersion;
+  support::ulittle32_t GlobalFlagsClear;
+  support::ulittle32_t GlobalFlagsSet;
+  support::ulittle32_t CriticalSectionDefaultTimeout;
+  support::ulittle32_t DeCommitFreeBlockThreshold;
+  support::ulittle32_t DeCommitTotalFreeThreshold;
+  support::ulittle32_t LockPrefixTable;
+  support::ulittle32_t MaximumAllocationSize;
+  support::ulittle32_t VirtualMemoryThreshold;
+  support::ulittle32_t ProcessAffinityMask;
+  support::ulittle32_t ProcessHeapFlags;
+  support::ulittle16_t CSDVersion;
+  uint16_t Reserved;
+  support::ulittle32_t EditList;
+  support::ulittle32_t SecurityCookie;
+  support::ulittle32_t SEHandlerTable;
+  support::ulittle32_t SEHandlerCount;
+};
+
+struct coff_runtime_function_x64 {
+  support::ulittle32_t BeginAddress;
+  support::ulittle32_t EndAddress;
+  support::ulittle32_t UnwindInformation;
+};
+
+class COFFObjectFile : public ObjectFile {
+private:
+  friend class ImportDirectoryEntryRef;
+  friend class ExportDirectoryEntryRef;
+  const coff_file_header *COFFHeader;
+  const pe32_header *PE32Header;
+  const pe32plus_header *PE32PlusHeader;
+  const data_directory *DataDirectory;
+  const coff_section *SectionTable;
+  const coff_symbol *SymbolTable;
+  const char *StringTable;
+  uint32_t StringTableSize;
+  const import_directory_table_entry *ImportDirectory;
+  uint32_t NumberOfImportDirectory;
+  const export_directory_table_entry *ExportDirectory;
+
+  std::error_code getString(uint32_t offset, StringRef &Res) const;
+
+  const coff_symbol *toSymb(DataRefImpl Symb) const;
+  const coff_section *toSec(DataRefImpl Sec) const;
+  const coff_relocation *toRel(DataRefImpl Rel) const;
+
+  std::error_code initSymbolTablePtr();
+  std::error_code initImportTablePtr();
+  std::error_code initExportTablePtr();
+
+protected:
+  void moveSymbolNext(DataRefImpl &Symb) const override;
+  std::error_code getSymbolName(DataRefImpl Symb,
+                                StringRef &Res) const override;
+  std::error_code getSymbolAddress(DataRefImpl Symb,
+                                   uint64_t &Res) const override;
+  std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+  std::error_code getSymbolType(DataRefImpl Symb,
+                                SymbolRef::Type &Res) const override;
+  std::error_code getSymbolSection(DataRefImpl Symb,
+                                   section_iterator &Res) const override;
+  void moveSectionNext(DataRefImpl &Sec) const override;
+  std::error_code getSectionName(DataRefImpl Sec,
+                                 StringRef &Res) const override;
+  std::error_code getSectionAddress(DataRefImpl Sec,
+                                    uint64_t &Res) const override;
+  std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+  std::error_code getSectionContents(DataRefImpl Sec,
+                                     StringRef &Res) const override;
+  std::error_code getSectionAlignment(DataRefImpl Sec,
+                                      uint64_t &Res) const override;
+  std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+                                        bool &Res) const override;
+  std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+                                                bool &Res) const override;
+  std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+                                        bool &Result) const override;
+  relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+  relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+  void moveRelocationNext(DataRefImpl &Rel) const override;
+  std::error_code getRelocationAddress(DataRefImpl Rel,
+                                       uint64_t &Res) const override;
+  std::error_code getRelocationOffset(DataRefImpl Rel,
+                                      uint64_t &Res) const override;
+  symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+  std::error_code getRelocationType(DataRefImpl Rel,
+                                    uint64_t &Res) const override;
+  std::error_code
+  getRelocationTypeName(DataRefImpl Rel,
+                        SmallVectorImpl<char> &Result) const override;
+  std::error_code
+  getRelocationValueString(DataRefImpl Rel,
+                           SmallVectorImpl<char> &Result) const override;
+
+  std::error_code getLibraryNext(DataRefImpl LibData,
+                                 LibraryRef &Result) const override;
+  std::error_code getLibraryPath(DataRefImpl LibData,
+                                 StringRef &Result) const override;
+
+public:
+  COFFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
+  basic_symbol_iterator symbol_begin_impl() const override;
+  basic_symbol_iterator symbol_end_impl() const override;
+  library_iterator needed_library_begin() const override;
+  library_iterator needed_library_end() const override;
+  section_iterator section_begin() const override;
+  section_iterator section_end() const override;
+
+  const coff_section *getCOFFSection(const SectionRef &Section) const;
+  const coff_symbol *getCOFFSymbol(const SymbolRef &Symbol) const;
+  const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
+
+  uint8_t getBytesInAddress() const override;
+  StringRef getFileFormatName() const override;
+  unsigned getArch() const override;
+  StringRef getLoadName() const override;
+
+  import_directory_iterator import_directory_begin() const;
+  import_directory_iterator import_directory_end() const;
+  export_directory_iterator export_directory_begin() const;
+  export_directory_iterator export_directory_end() const;
+
+  std::error_code getHeader(const coff_file_header *&Res) const;
+  std::error_code getCOFFHeader(const coff_file_header *&Res) const;
+  std::error_code getPE32Header(const pe32_header *&Res) const;
+  std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
+  std::error_code getDataDirectory(uint32_t index,
+                                   const data_directory *&Res) const;
+  std::error_code getSection(int32_t index, const coff_section *&Res) const;
+  std::error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
+  template <typename T>
+  std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+    const coff_symbol *s;
+    std::error_code ec = getSymbol(index, s);
+    Res = reinterpret_cast<const T *>(s);
+    return ec;
+  }
+  std::error_code getSymbolName(const coff_symbol *symbol,
+                                StringRef &Res) const;
+  ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
+
+  std::error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+  std::error_code getSectionContents(const coff_section *Sec,
+                                     ArrayRef<uint8_t> &Res) const;
+
+  std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
+  std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+  std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
+                              StringRef &Name) const;
+
+  static inline bool classof(const Binary *v) { return v->isCOFF(); }
+};
+
+// The iterator for the import directory table.
+class ImportDirectoryEntryRef {
+public:
+  ImportDirectoryEntryRef() : OwningObject(nullptr) {}
+  ImportDirectoryEntryRef(const import_directory_table_entry *Table, uint32_t I,
+                          const COFFObjectFile *Owner)
+      : ImportTable(Table), Index(I), OwningObject(Owner) {}
+
+  bool operator==(const ImportDirectoryEntryRef &Other) const;
+  void moveNext();
+  std::error_code getName(StringRef &Result) const;
+
+  std::error_code
+  getImportTableEntry(const import_directory_table_entry *&Result) const;
+
+  std::error_code
+  getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
+
+private:
+  const import_directory_table_entry *ImportTable;
+  uint32_t Index;
+  const COFFObjectFile *OwningObject;
+};
+
+// The iterator for the export directory table entry.
+class ExportDirectoryEntryRef {
+public:
+  ExportDirectoryEntryRef() : OwningObject(nullptr) {}
+  ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
+                          const COFFObjectFile *Owner)
+      : ExportTable(Table), Index(I), OwningObject(Owner) {}
+
+  bool operator==(const ExportDirectoryEntryRef &Other) const;
+  void moveNext();
+
+  std::error_code getDllName(StringRef &Result) const;
+  std::error_code getOrdinalBase(uint32_t &Result) const;
+  std::error_code getOrdinal(uint32_t &Result) const;
+  std::error_code getExportRVA(uint32_t &Result) const;
+  std::error_code getSymbolName(StringRef &Result) const;
+
+private:
+  const export_directory_table_entry *ExportTable;
+  uint32_t Index;
+  const COFFObjectFile *OwningObject;
+};
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h
new file mode 100644
index 0000000..4aba08f
--- /dev/null
+++ b/include/llvm/Object/COFFYAML.h
@@ -0,0 +1,191 @@
+//===- COFFYAML.h - COFF YAMLIO implementation ------------------*- 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 classes for handling the YAML representation of COFF.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFFYAML_H
+#define LLVM_OBJECT_COFFYAML_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/MC/YAML.h"
+#include "llvm/Support/COFF.h"
+
+namespace llvm {
+
+namespace COFF {
+inline Characteristics operator|(Characteristics a, Characteristics b) {
+  uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
+  return static_cast<Characteristics>(Ret);
+}
+
+inline SectionCharacteristics operator|(SectionCharacteristics a,
+                                        SectionCharacteristics b) {
+  uint32_t Ret = static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
+  return static_cast<SectionCharacteristics>(Ret);
+}
+}
+
+// The structure of the yaml files is not an exact 1:1 match to COFF. In order
+// to use yaml::IO, we use these structures which are closer to the source.
+namespace COFFYAML {
+  LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
+  LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
+  LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
+
+  struct Relocation {
+    uint32_t VirtualAddress;
+    uint16_t Type;
+    StringRef SymbolName;
+  };
+
+  struct Section {
+    COFF::section Header;
+    unsigned Alignment;
+    yaml::BinaryRef SectionData;
+    std::vector<Relocation> Relocations;
+    StringRef Name;
+    Section();
+  };
+
+  struct Symbol {
+    COFF::symbol Header;
+    COFF::SymbolBaseType SimpleType;
+    COFF::SymbolComplexType ComplexType;
+    Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
+    Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
+    Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
+    StringRef File;
+    Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
+    Optional<COFF::AuxiliaryCLRToken> CLRToken;
+    StringRef Name;
+    Symbol();
+  };
+
+  struct Object {
+    COFF::header Header;
+    std::vector<Section> Sections;
+    std::vector<Symbol> Symbols;
+    Object();
+  };
+}
+}
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section)
+LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol)
+LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> {
+  static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> {
+  static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::COMDATType> {
+  static void enumeration(IO &IO, COFFYAML::COMDATType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::MachineTypes> {
+  static void enumeration(IO &IO, COFF::MachineTypes &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::SymbolBaseType> {
+  static void enumeration(IO &IO, COFF::SymbolBaseType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::SymbolStorageClass> {
+  static void enumeration(IO &IO, COFF::SymbolStorageClass &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::SymbolComplexType> {
+  static void enumeration(IO &IO, COFF::SymbolComplexType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::RelocationTypeI386> {
+  static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> {
+  static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value);
+};
+
+template <>
+struct ScalarBitSetTraits<COFF::Characteristics> {
+  static void bitset(IO &IO, COFF::Characteristics &Value);
+};
+
+template <>
+struct ScalarBitSetTraits<COFF::SectionCharacteristics> {
+  static void bitset(IO &IO, COFF::SectionCharacteristics &Value);
+};
+
+template <>
+struct MappingTraits<COFFYAML::Relocation> {
+  static void mapping(IO &IO, COFFYAML::Relocation &Rel);
+};
+
+template <>
+struct MappingTraits<COFF::header> {
+  static void mapping(IO &IO, COFF::header &H);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> {
+  static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> {
+  static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> {
+  static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> {
+  static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryCLRToken> {
+  static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
+};
+
+template <>
+struct MappingTraits<COFFYAML::Symbol> {
+  static void mapping(IO &IO, COFFYAML::Symbol &S);
+};
+
+template <>
+struct MappingTraits<COFFYAML::Section> {
+  static void mapping(IO &IO, COFFYAML::Section &Sec);
+};
+
+template <>
+struct MappingTraits<COFFYAML::Object> {
+  static void mapping(IO &IO, COFFYAML::Object &Obj);
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
new file mode 100644
index 0000000..fbc48e6
--- /dev/null
+++ b/include/llvm/Object/ELF.h
@@ -0,0 +1,1015 @@
+//===- ELF.h - ELF object file implementation -------------------*- 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 ELFFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_H
+#define LLVM_OBJECT_ELF_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+namespace llvm {
+namespace object {
+
+StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
+
+// Subclasses of ELFFile may need this for template instantiation
+inline std::pair<unsigned char, unsigned char>
+getElfArchType(StringRef Object) {
+  if (Object.size() < ELF::EI_NIDENT)
+    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
+                          (uint8_t)ELF::ELFDATANONE);
+  return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
+                        (uint8_t)Object[ELF::EI_DATA]);
+}
+
+template <class ELFT>
+class ELFFile {
+public:
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  typedef typename std::conditional<ELFT::Is64Bits,
+                                    uint64_t, uint32_t>::type uintX_t;
+
+  /// \brief Iterate over constant sized entities.
+  template <class EntT>
+  class ELFEntityIterator {
+  public:
+    typedef ptrdiff_t difference_type;
+    typedef EntT value_type;
+    typedef std::forward_iterator_tag iterator_category;
+    typedef value_type &reference;
+    typedef value_type *pointer;
+
+    /// \brief Default construct iterator.
+    ELFEntityIterator() : EntitySize(0), Current(nullptr) {}
+    ELFEntityIterator(uintX_t EntSize, const char *Start)
+        : EntitySize(EntSize), Current(Start) {}
+
+    reference operator *() {
+      assert(Current && "Attempted to dereference an invalid iterator!");
+      return *reinterpret_cast<pointer>(Current);
+    }
+
+    pointer operator ->() {
+      assert(Current && "Attempted to dereference an invalid iterator!");
+      return reinterpret_cast<pointer>(Current);
+    }
+
+    bool operator ==(const ELFEntityIterator &Other) {
+      return Current == Other.Current;
+    }
+
+    bool operator !=(const ELFEntityIterator &Other) {
+      return !(*this == Other);
+    }
+
+    ELFEntityIterator &operator ++() {
+      assert(Current && "Attempted to increment an invalid iterator!");
+      Current += EntitySize;
+      return *this;
+    }
+
+    ELFEntityIterator operator ++(int) {
+      ELFEntityIterator Tmp = *this;
+      ++*this;
+      return Tmp;
+    }
+
+    ELFEntityIterator &operator =(const ELFEntityIterator &Other) {
+      EntitySize = Other.EntitySize;
+      Current = Other.Current;
+      return *this;
+    }
+
+    difference_type operator -(const ELFEntityIterator &Other) const {
+      assert(EntitySize == Other.EntitySize &&
+             "Subtracting iterators of different EntitySize!");
+      return (Current - Other.Current) / EntitySize;
+    }
+
+    const char *get() const { return Current; }
+
+    uintX_t getEntSize() const { return EntitySize; }
+
+  private:
+    uintX_t EntitySize;
+    const char *Current;
+  };
+
+  typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
+  typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
+  typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+  typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
+  typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
+  typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
+  typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
+  typedef Elf_Verdef_Impl<ELFT> Elf_Verdef;
+  typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+  typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
+  typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
+  typedef Elf_Versym_Impl<ELFT> Elf_Versym;
+  typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
+  typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
+  typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
+  typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
+  typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter;
+  typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range;
+
+  /// \brief Archive files are 2 byte aligned, so we need this for
+  ///     PointerIntPair to work.
+  template <typename T>
+  class ArchivePointerTypeTraits {
+  public:
+    static inline const void *getAsVoidPointer(T *P) { return P; }
+    static inline T *getFromVoidPointer(const void *P) {
+      return static_cast<T *>(P);
+    }
+    enum { NumLowBitsAvailable = 1 };
+  };
+
+  class Elf_Sym_Iter {
+  public:
+    typedef ptrdiff_t difference_type;
+    typedef const Elf_Sym value_type;
+    typedef std::random_access_iterator_tag iterator_category;
+    typedef value_type &reference;
+    typedef value_type *pointer;
+
+    /// \brief Default construct iterator.
+    Elf_Sym_Iter() : EntitySize(0), Current(0, false) {}
+    Elf_Sym_Iter(uintX_t EntSize, const char *Start, bool IsDynamic)
+        : EntitySize(EntSize), Current(Start, IsDynamic) {}
+
+    reference operator*() {
+      assert(Current.getPointer() &&
+             "Attempted to dereference an invalid iterator!");
+      return *reinterpret_cast<pointer>(Current.getPointer());
+    }
+
+    pointer operator->() {
+      assert(Current.getPointer() &&
+             "Attempted to dereference an invalid iterator!");
+      return reinterpret_cast<pointer>(Current.getPointer());
+    }
+
+    bool operator==(const Elf_Sym_Iter &Other) {
+      return Current == Other.Current;
+    }
+
+    bool operator!=(const Elf_Sym_Iter &Other) { return !(*this == Other); }
+
+    Elf_Sym_Iter &operator++() {
+      assert(Current.getPointer() &&
+             "Attempted to increment an invalid iterator!");
+      Current.setPointer(Current.getPointer() + EntitySize);
+      return *this;
+    }
+
+    Elf_Sym_Iter operator++(int) {
+      Elf_Sym_Iter Tmp = *this;
+      ++*this;
+      return Tmp;
+    }
+
+    Elf_Sym_Iter operator+(difference_type Dist) {
+      assert(Current.getPointer() &&
+             "Attempted to increment an invalid iterator!");
+      Current.setPointer(Current.getPointer() + EntitySize * Dist);
+      return *this;
+    }
+
+    Elf_Sym_Iter &operator=(const Elf_Sym_Iter &Other) {
+      EntitySize = Other.EntitySize;
+      Current = Other.Current;
+      return *this;
+    }
+
+    difference_type operator-(const Elf_Sym_Iter &Other) const {
+      assert(EntitySize == Other.EntitySize &&
+             "Subtracting iterators of different EntitySize!");
+      return (Current.getPointer() - Other.Current.getPointer()) / EntitySize;
+    }
+
+    const char *get() const { return Current.getPointer(); }
+
+    bool isDynamic() const { return Current.getInt(); }
+
+    uintX_t getEntSize() const { return EntitySize; }
+
+  private:
+    uintX_t EntitySize;
+    PointerIntPair<const char *, 1, bool,
+                   ArchivePointerTypeTraits<const char> > Current;
+  };
+
+private:
+  typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
+  typedef DenseMap<unsigned, unsigned> IndexMap_t;
+
+  StringRef Buf;
+
+  const uint8_t *base() const {
+    return reinterpret_cast<const uint8_t *>(Buf.data());
+  }
+
+  const Elf_Ehdr *Header;
+  const Elf_Shdr *SectionHeaderTable;
+  const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
+  const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
+  const Elf_Shdr *dot_symtab_sec;   // Symbol table section.
+
+  const Elf_Shdr *SymbolTableSectionHeaderIndex;
+  DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable;
+
+  const Elf_Shdr *dot_gnu_version_sec;   // .gnu.version
+  const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
+  const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
+
+  /// \brief Represents a region described by entries in the .dynamic table.
+  struct DynRegionInfo {
+    DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
+    /// \brief Address in current address space.
+    const void *Addr;
+    /// \brief Size in bytes of the region.
+    uintX_t Size;
+    /// \brief Size of each entity in the region.
+    uintX_t EntSize;
+  };
+
+  DynRegionInfo DynamicRegion;
+  DynRegionInfo DynHashRegion;
+  DynRegionInfo DynStrRegion;
+  DynRegionInfo DynSymRegion;
+
+  // Pointer to SONAME entry in dynamic string table
+  // This is set the first time getLoadName is called.
+  mutable const char *dt_soname;
+
+  // Records for each version index the corresponding Verdef or Vernaux entry.
+  // This is filled the first time LoadVersionMap() is called.
+  class VersionMapEntry : public PointerIntPair<const void*, 1> {
+    public:
+    // If the integer is 0, this is an Elf_Verdef*.
+    // If the integer is 1, this is an Elf_Vernaux*.
+    VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { }
+    VersionMapEntry(const Elf_Verdef *verdef)
+        : PointerIntPair<const void*, 1>(verdef, 0) { }
+    VersionMapEntry(const Elf_Vernaux *vernaux)
+        : PointerIntPair<const void*, 1>(vernaux, 1) { }
+    bool isNull() const { return getPointer() == nullptr; }
+    bool isVerdef() const { return !isNull() && getInt() == 0; }
+    bool isVernaux() const { return !isNull() && getInt() == 1; }
+    const Elf_Verdef *getVerdef() const {
+      return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr;
+    }
+    const Elf_Vernaux *getVernaux() const {
+      return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr;
+    }
+  };
+  mutable SmallVector<VersionMapEntry, 16> VersionMap;
+  void LoadVersionDefs(const Elf_Shdr *sec) const;
+  void LoadVersionNeeds(const Elf_Shdr *ec) const;
+  void LoadVersionMap() const;
+
+public:
+  template<typename T>
+  const T        *getEntry(uint32_t Section, uint32_t Entry) const;
+  template <typename T>
+  const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
+  const char     *getString(uint32_t section, uint32_t offset) const;
+  const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
+  const char *getDynamicString(uintX_t Offset) const;
+  ErrorOr<StringRef> getSymbolVersion(const Elf_Shdr *section,
+                                      const Elf_Sym *Symb,
+                                      bool &IsDefault) const;
+  void VerifyStrTab(const Elf_Shdr *sh) const;
+
+  StringRef getRelocationTypeName(uint32_t Type) const;
+  void getRelocationTypeName(uint32_t Type,
+                             SmallVectorImpl<char> &Result) const;
+
+  /// \brief Get the symbol table section and symbol for a given relocation.
+  template <class RelT>
+  std::pair<const Elf_Shdr *, const Elf_Sym *>
+  getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const;
+
+  ELFFile(StringRef Object, std::error_code &ec);
+
+  bool isMipsELF64() const {
+    return Header->e_machine == ELF::EM_MIPS &&
+      Header->getFileClass() == ELF::ELFCLASS64;
+  }
+
+  bool isMips64EL() const {
+    return Header->e_machine == ELF::EM_MIPS &&
+      Header->getFileClass() == ELF::ELFCLASS64 &&
+      Header->getDataEncoding() == ELF::ELFDATA2LSB;
+  }
+
+  Elf_Shdr_Iter begin_sections() const;
+  Elf_Shdr_Iter end_sections() const;
+  Elf_Shdr_Range sections() const {
+    return make_range(begin_sections(), end_sections());
+  }
+
+  Elf_Sym_Iter begin_symbols() const;
+  Elf_Sym_Iter end_symbols() const;
+
+  Elf_Dyn_Iter begin_dynamic_table() const;
+  /// \param NULLEnd use one past the first DT_NULL entry as the end instead of
+  /// the section size.
+  Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const;
+  Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const {
+    return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd));
+  }
+
+  Elf_Sym_Iter begin_dynamic_symbols() const {
+    if (DynSymRegion.Addr)
+      return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr,
+                          true);
+    return Elf_Sym_Iter(0, nullptr, true);
+  }
+
+  Elf_Sym_Iter end_dynamic_symbols() const {
+    if (DynSymRegion.Addr)
+      return Elf_Sym_Iter(DynSymRegion.EntSize,
+                          (const char *)DynSymRegion.Addr + DynSymRegion.Size,
+                          true);
+    return Elf_Sym_Iter(0, nullptr, true);
+  }
+
+  Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const {
+    return Elf_Rela_Iter(sec->sh_entsize,
+                         (const char *)(base() + sec->sh_offset));
+  }
+
+  Elf_Rela_Iter end_rela(const Elf_Shdr *sec) const {
+    return Elf_Rela_Iter(
+        sec->sh_entsize,
+        (const char *)(base() + sec->sh_offset + sec->sh_size));
+  }
+
+  Elf_Rel_Iter begin_rel(const Elf_Shdr *sec) const {
+    return Elf_Rel_Iter(sec->sh_entsize,
+                        (const char *)(base() + sec->sh_offset));
+  }
+
+  Elf_Rel_Iter end_rel(const Elf_Shdr *sec) const {
+    return Elf_Rel_Iter(sec->sh_entsize,
+                        (const char *)(base() + sec->sh_offset + sec->sh_size));
+  }
+
+  /// \brief Iterate over program header table.
+  typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
+
+  Elf_Phdr_Iter begin_program_headers() const {
+    return Elf_Phdr_Iter(Header->e_phentsize,
+                         (const char*)base() + Header->e_phoff);
+  }
+
+  Elf_Phdr_Iter end_program_headers() const {
+    return Elf_Phdr_Iter(Header->e_phentsize,
+                         (const char*)base() +
+                           Header->e_phoff +
+                           (Header->e_phnum * Header->e_phentsize));
+  }
+
+  uint64_t getNumSections() const;
+  uintX_t getStringTableIndex() const;
+  ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
+  const Elf_Ehdr *getHeader() const { return Header; }
+  const Elf_Shdr *getSection(const Elf_Sym *symb) const;
+  const Elf_Shdr *getSection(uint32_t Index) const;
+  const Elf_Sym *getSymbol(uint32_t index) const;
+
+  ErrorOr<StringRef> getSymbolName(Elf_Sym_Iter Sym) const;
+
+  /// \brief Get the name of \p Symb.
+  /// \param SymTab The symbol table section \p Symb is contained in.
+  /// \param Symb The symbol to get the name of.
+  ///
+  /// \p SymTab is used to lookup the string table to use to get the symbol's
+  /// name.
+  ErrorOr<StringRef> getSymbolName(const Elf_Shdr *SymTab,
+                                   const Elf_Sym *Symb) const;
+  ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const;
+  uint64_t getSymbolIndex(const Elf_Sym *sym) const;
+  ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const;
+  StringRef getLoadName() const;
+};
+
+// Use an alignment of 2 for the typedefs since that is the worst case for
+// ELF files in archives.
+typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile;
+typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile;
+typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile;
+typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile;
+
+// Iterate through the version definitions, and place each Elf_Verdef
+// in the VersionMap according to its index.
+template <class ELFT>
+void ELFFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
+  unsigned vd_size = sec->sh_size;  // Size of section in bytes
+  unsigned vd_count = sec->sh_info; // Number of Verdef entries
+  const char *sec_start = (const char*)base() + sec->sh_offset;
+  const char *sec_end = sec_start + vd_size;
+  // The first Verdef entry is at the start of the section.
+  const char *p = sec_start;
+  for (unsigned i = 0; i < vd_count; i++) {
+    if (p + sizeof(Elf_Verdef) > sec_end)
+      report_fatal_error("Section ended unexpectedly while scanning "
+                         "version definitions.");
+    const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
+    if (vd->vd_version != ELF::VER_DEF_CURRENT)
+      report_fatal_error("Unexpected verdef version");
+    size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
+    if (index >= VersionMap.size())
+      VersionMap.resize(index + 1);
+    VersionMap[index] = VersionMapEntry(vd);
+    p += vd->vd_next;
+  }
+}
+
+// Iterate through the versions needed section, and place each Elf_Vernaux
+// in the VersionMap according to its index.
+template <class ELFT>
+void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
+  unsigned vn_size = sec->sh_size;  // Size of section in bytes
+  unsigned vn_count = sec->sh_info; // Number of Verneed entries
+  const char *sec_start = (const char *)base() + sec->sh_offset;
+  const char *sec_end = sec_start + vn_size;
+  // The first Verneed entry is at the start of the section.
+  const char *p = sec_start;
+  for (unsigned i = 0; i < vn_count; i++) {
+    if (p + sizeof(Elf_Verneed) > sec_end)
+      report_fatal_error("Section ended unexpectedly while scanning "
+                         "version needed records.");
+    const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
+    if (vn->vn_version != ELF::VER_NEED_CURRENT)
+      report_fatal_error("Unexpected verneed version");
+    // Iterate through the Vernaux entries
+    const char *paux = p + vn->vn_aux;
+    for (unsigned j = 0; j < vn->vn_cnt; j++) {
+      if (paux + sizeof(Elf_Vernaux) > sec_end)
+        report_fatal_error("Section ended unexpected while scanning auxiliary "
+                           "version needed records.");
+      const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
+      size_t index = vna->vna_other & ELF::VERSYM_VERSION;
+      if (index >= VersionMap.size())
+        VersionMap.resize(index + 1);
+      VersionMap[index] = VersionMapEntry(vna);
+      paux += vna->vna_next;
+    }
+    p += vn->vn_next;
+  }
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::LoadVersionMap() const {
+  // If there is no dynamic symtab or version table, there is nothing to do.
+  if (!DynSymRegion.Addr || !dot_gnu_version_sec)
+    return;
+
+  // Has the VersionMap already been loaded?
+  if (VersionMap.size() > 0)
+    return;
+
+  // The first two version indexes are reserved.
+  // Index 0 is LOCAL, index 1 is GLOBAL.
+  VersionMap.push_back(VersionMapEntry());
+  VersionMap.push_back(VersionMapEntry());
+
+  if (dot_gnu_version_d_sec)
+    LoadVersionDefs(dot_gnu_version_d_sec);
+
+  if (dot_gnu_version_r_sec)
+    LoadVersionNeeds(dot_gnu_version_r_sec);
+}
+
+template <class ELFT>
+ELF::Elf64_Word ELFFile<ELFT>::getSymbolTableIndex(const Elf_Sym *symb) const {
+  if (symb->st_shndx == ELF::SHN_XINDEX)
+    return ExtendedSymbolTable.lookup(symb);
+  return symb->st_shndx;
+}
+
+template <class ELFT>
+const typename ELFFile<ELFT>::Elf_Shdr *
+ELFFile<ELFT>::getSection(const Elf_Sym *symb) const {
+  if (symb->st_shndx == ELF::SHN_XINDEX)
+    return getSection(ExtendedSymbolTable.lookup(symb));
+  if (symb->st_shndx >= ELF::SHN_LORESERVE)
+    return nullptr;
+  return getSection(symb->st_shndx);
+}
+
+template <class ELFT>
+const typename ELFFile<ELFT>::Elf_Sym *
+ELFFile<ELFT>::getSymbol(uint32_t Index) const {
+  return &*(begin_symbols() + Index);
+}
+
+template <class ELFT>
+ErrorOr<ArrayRef<uint8_t> >
+ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
+  if (Sec->sh_offset + Sec->sh_size > Buf.size())
+    return object_error::parse_failed;
+  const uint8_t *Start = base() + Sec->sh_offset;
+  return ArrayRef<uint8_t>(Start, Sec->sh_size);
+}
+
+template <class ELFT>
+StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+  return getELFRelocationTypeName(Header->e_machine, Type);
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
+                                          SmallVectorImpl<char> &Result) const {
+  if (!isMipsELF64()) {
+    StringRef Name = getRelocationTypeName(Type);
+    Result.append(Name.begin(), Name.end());
+  } else {
+    // The Mips N64 ABI allows up to three operations to be specified per
+    // relocation record. Unfortunately there's no easy way to test for the
+    // presence of N64 ELFs as they have no special flag that identifies them
+    // as being N64. We can safely assume at the moment that all Mips
+    // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
+    // information to disambiguate between old vs new ABIs.
+    uint8_t Type1 = (Type >> 0) & 0xFF;
+    uint8_t Type2 = (Type >> 8) & 0xFF;
+    uint8_t Type3 = (Type >> 16) & 0xFF;
+
+    // Concat all three relocation type names.
+    StringRef Name = getRelocationTypeName(Type1);
+    Result.append(Name.begin(), Name.end());
+
+    Name = getRelocationTypeName(Type2);
+    Result.append(1, '/');
+    Result.append(Name.begin(), Name.end());
+
+    Name = getRelocationTypeName(Type3);
+    Result.append(1, '/');
+    Result.append(Name.begin(), Name.end());
+  }
+}
+
+template <class ELFT>
+template <class RelT>
+std::pair<const typename ELFFile<ELFT>::Elf_Shdr *,
+          const typename ELFFile<ELFT>::Elf_Sym *>
+ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const {
+  if (!Sec->sh_link)
+    return std::make_pair(nullptr, nullptr);
+  const Elf_Shdr *SymTable = getSection(Sec->sh_link);
+  return std::make_pair(
+      SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL())));
+}
+
+// Verify that the last byte in the string table in a null.
+template <class ELFT>
+void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
+  const char *strtab = (const char *)base() + sh->sh_offset;
+  if (strtab[sh->sh_size - 1] != 0)
+    // FIXME: Proper error handling.
+    report_fatal_error("String table must end with a null terminator!");
+}
+
+template <class ELFT>
+uint64_t ELFFile<ELFT>::getNumSections() const {
+  assert(Header && "Header not initialized!");
+  if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) {
+    assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
+    return SectionHeaderTable->sh_size;
+  }
+  return Header->e_shnum;
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const {
+  if (Header->e_shnum == ELF::SHN_UNDEF) {
+    if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
+      return SectionHeaderTable->sh_link;
+    if (Header->e_shstrndx >= getNumSections())
+      return 0;
+  }
+  return Header->e_shstrndx;
+}
+
+template <class ELFT>
+ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
+    : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
+      dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
+      SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
+      dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr),
+      dt_soname(nullptr) {
+  const uint64_t FileSize = Buf.size();
+
+  if (sizeof(Elf_Ehdr) > FileSize)
+    // FIXME: Proper error handling.
+    report_fatal_error("File too short!");
+
+  Header = reinterpret_cast<const Elf_Ehdr *>(base());
+
+  if (Header->e_shoff == 0)
+    return;
+
+  const uint64_t SectionTableOffset = Header->e_shoff;
+
+  if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
+    // FIXME: Proper error handling.
+    report_fatal_error("Section header table goes past end of file!");
+
+  // The getNumSections() call below depends on SectionHeaderTable being set.
+  SectionHeaderTable =
+    reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
+  const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
+
+  if (SectionTableOffset + SectionTableSize > FileSize)
+    // FIXME: Proper error handling.
+    report_fatal_error("Section table goes past end of file!");
+
+  // Scan sections for special sections.
+
+  for (const Elf_Shdr &Sec : sections()) {
+    switch (Sec.sh_type) {
+    case ELF::SHT_SYMTAB_SHNDX:
+      if (SymbolTableSectionHeaderIndex)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .symtab_shndx!");
+      SymbolTableSectionHeaderIndex = &Sec;
+      break;
+    case ELF::SHT_SYMTAB:
+      if (dot_symtab_sec)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .symtab!");
+      dot_symtab_sec = &Sec;
+      dot_strtab_sec = getSection(Sec.sh_link);
+      break;
+    case ELF::SHT_DYNSYM: {
+      if (DynSymRegion.Addr)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .dynsym!");
+      DynSymRegion.Addr = base() + Sec.sh_offset;
+      DynSymRegion.Size = Sec.sh_size;
+      DynSymRegion.EntSize = Sec.sh_entsize;
+      const Elf_Shdr *DynStr = getSection(Sec.sh_link);
+      DynStrRegion.Addr = base() + DynStr->sh_offset;
+      DynStrRegion.Size = DynStr->sh_size;
+      DynStrRegion.EntSize = DynStr->sh_entsize;
+      break;
+    }
+    case ELF::SHT_DYNAMIC:
+      if (DynamicRegion.Addr)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .dynamic!");
+      DynamicRegion.Addr = base() + Sec.sh_offset;
+      DynamicRegion.Size = Sec.sh_size;
+      DynamicRegion.EntSize = Sec.sh_entsize;
+      break;
+    case ELF::SHT_GNU_versym:
+      if (dot_gnu_version_sec != nullptr)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .gnu.version section!");
+      dot_gnu_version_sec = &Sec;
+      break;
+    case ELF::SHT_GNU_verdef:
+      if (dot_gnu_version_d_sec != nullptr)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .gnu.version_d section!");
+      dot_gnu_version_d_sec = &Sec;
+      break;
+    case ELF::SHT_GNU_verneed:
+      if (dot_gnu_version_r_sec != nullptr)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .gnu.version_r section!");
+      dot_gnu_version_r_sec = &Sec;
+      break;
+    }
+  }
+
+  // Get string table sections.
+  dot_shstrtab_sec = getSection(getStringTableIndex());
+  if (dot_shstrtab_sec) {
+    // Verify that the last byte in the string table in a null.
+    VerifyStrTab(dot_shstrtab_sec);
+  }
+
+  // Build symbol name side-mapping if there is one.
+  if (SymbolTableSectionHeaderIndex) {
+    const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
+                                      SymbolTableSectionHeaderIndex->sh_offset);
+    for (Elf_Sym_Iter SI = begin_symbols(), SE = end_symbols(); SI != SE;
+         ++SI) {
+      if (*ShndxTable != ELF::SHN_UNDEF)
+        ExtendedSymbolTable[&*SI] = *ShndxTable;
+      ++ShndxTable;
+    }
+  }
+
+  // Scan program headers.
+  for (Elf_Phdr_Iter PhdrI = begin_program_headers(),
+                     PhdrE = end_program_headers();
+       PhdrI != PhdrE; ++PhdrI) {
+    if (PhdrI->p_type == ELF::PT_DYNAMIC) {
+      DynamicRegion.Addr = base() + PhdrI->p_offset;
+      DynamicRegion.Size = PhdrI->p_filesz;
+      DynamicRegion.EntSize = sizeof(Elf_Dyn);
+      break;
+    }
+  }
+
+  ec = std::error_code();
+}
+
+// Get the symbol table index in the symtab section given a symbol
+template <class ELFT>
+uint64_t ELFFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const {
+  uintptr_t SymLoc = uintptr_t(Sym);
+  uintptr_t SymTabLoc = uintptr_t(base() + dot_symtab_sec->sh_offset);
+  assert(SymLoc > SymTabLoc && "Symbol not in symbol table!");
+  uint64_t SymOffset = SymLoc - SymTabLoc;
+  assert(SymOffset % dot_symtab_sec->sh_entsize == 0 &&
+         "Symbol not multiple of symbol size!");
+  return SymOffset / dot_symtab_sec->sh_entsize;
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::begin_sections() const {
+  return Elf_Shdr_Iter(Header->e_shentsize,
+                       (const char *)base() + Header->e_shoff);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const {
+  return Elf_Shdr_Iter(Header->e_shentsize,
+                       (const char *)base() + Header->e_shoff +
+                           (getNumSections() * Header->e_shentsize));
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const {
+  if (!dot_symtab_sec)
+    return Elf_Sym_Iter(0, nullptr, false);
+  return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
+                      (const char *)base() + dot_symtab_sec->sh_offset, false);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const {
+  if (!dot_symtab_sec)
+    return Elf_Sym_Iter(0, nullptr, false);
+  return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
+                      (const char *)base() + dot_symtab_sec->sh_offset +
+                          dot_symtab_sec->sh_size,
+                      false);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Dyn_Iter
+ELFFile<ELFT>::begin_dynamic_table() const {
+  if (DynamicRegion.Addr)
+    return Elf_Dyn_Iter(DynamicRegion.EntSize,
+                        (const char *)DynamicRegion.Addr);
+  return Elf_Dyn_Iter(0, nullptr);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::Elf_Dyn_Iter
+ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
+  if (!DynamicRegion.Addr)
+    return Elf_Dyn_Iter(0, nullptr);
+  Elf_Dyn_Iter Ret(DynamicRegion.EntSize,
+                    (const char *)DynamicRegion.Addr + DynamicRegion.Size);
+
+  if (NULLEnd) {
+    Elf_Dyn_Iter Start = begin_dynamic_table();
+    while (Start != Ret && Start->getTag() != ELF::DT_NULL)
+      ++Start;
+
+    // Include the DT_NULL.
+    if (Start != Ret)
+      ++Start;
+    Ret = Start;
+  }
+  return Ret;
+}
+
+template <class ELFT>
+StringRef ELFFile<ELFT>::getLoadName() const {
+  if (!dt_soname) {
+    dt_soname = "";
+    // Find the DT_SONAME entry
+    for (const auto &Entry : dynamic_table())
+      if (Entry.getTag() == ELF::DT_SONAME) {
+        dt_soname = getDynamicString(Entry.getVal());
+        break;
+      }
+  }
+  return dt_soname;
+}
+
+template <class ELFT>
+template <typename T>
+const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
+  return getEntry<T>(getSection(Section), Entry);
+}
+
+template <class ELFT>
+template <typename T>
+const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
+                                 uint32_t Entry) const {
+  return reinterpret_cast<const T *>(base() + Section->sh_offset +
+                                     (Entry * Section->sh_entsize));
+}
+
+template <class ELFT>
+const typename ELFFile<ELFT>::Elf_Shdr *
+ELFFile<ELFT>::getSection(uint32_t index) const {
+  if (index == 0)
+    return nullptr;
+  if (!SectionHeaderTable || index >= getNumSections())
+    // FIXME: Proper error handling.
+    report_fatal_error("Invalid section index!");
+
+  return reinterpret_cast<const Elf_Shdr *>(
+         reinterpret_cast<const char *>(SectionHeaderTable)
+         + (index * Header->e_shentsize));
+}
+
+template <class ELFT>
+const char *ELFFile<ELFT>::getString(uint32_t section,
+                                     ELF::Elf32_Word offset) const {
+  return getString(getSection(section), offset);
+}
+
+template <class ELFT>
+const char *ELFFile<ELFT>::getString(const Elf_Shdr *section,
+                                     ELF::Elf32_Word offset) const {
+  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
+  if (offset >= section->sh_size)
+    // FIXME: Proper error handling.
+    report_fatal_error("Symbol name offset outside of string table!");
+  return (const char *)base() + section->sh_offset + offset;
+}
+
+template <class ELFT>
+const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
+  if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size)
+    return nullptr;
+  return (const char *)DynStrRegion.Addr + Offset;
+}
+
+template <class ELFT>
+ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const {
+  if (!Sym.isDynamic())
+    return getSymbolName(dot_symtab_sec, &*Sym);
+
+  if (!DynStrRegion.Addr || Sym->st_name >= DynStrRegion.Size)
+    return object_error::parse_failed;
+  return StringRef(getDynamicString(Sym->st_name));
+}
+
+template <class ELFT>
+ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section,
+                                                const Elf_Sym *Symb) const {
+  if (Symb->st_name == 0) {
+    const Elf_Shdr *ContainingSec = getSection(Symb);
+    if (ContainingSec)
+      return getSectionName(ContainingSec);
+  }
+
+  const Elf_Shdr *StrTab = getSection(Section->sh_link);
+  if (Symb->st_name >= StrTab->sh_size)
+    return object_error::parse_failed;
+  return StringRef(getString(StrTab, Symb->st_name));
+}
+
+template <class ELFT>
+ErrorOr<StringRef>
+ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
+  if (Section->sh_name >= dot_shstrtab_sec->sh_size)
+    return object_error::parse_failed;
+  return StringRef(getString(dot_shstrtab_sec, Section->sh_name));
+}
+
+template <class ELFT>
+ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
+                                                   const Elf_Sym *symb,
+                                                   bool &IsDefault) const {
+  // Handle non-dynamic symbols.
+  if (section != DynSymRegion.Addr && section != nullptr) {
+    // Non-dynamic symbols can have versions in their names
+    // A name of the form 'foo@V1' indicates version 'V1', non-default.
+    // A name of the form 'foo@@V2' indicates version 'V2', default version.
+    ErrorOr<StringRef> SymName = getSymbolName(section, symb);
+    if (!SymName)
+      return SymName;
+    StringRef Name = *SymName;
+    size_t atpos = Name.find('@');
+    if (atpos == StringRef::npos) {
+      IsDefault = false;
+      return StringRef("");
+    }
+    ++atpos;
+    if (atpos < Name.size() && Name[atpos] == '@') {
+      IsDefault = true;
+      ++atpos;
+    } else {
+      IsDefault = false;
+    }
+    return Name.substr(atpos);
+  }
+
+  // This is a dynamic symbol. Look in the GNU symbol version table.
+  if (!dot_gnu_version_sec) {
+    // No version table.
+    IsDefault = false;
+    return StringRef("");
+  }
+
+  // Determine the position in the symbol table of this entry.
+  size_t entry_index = ((const char *)symb - (const char *)DynSymRegion.Addr) /
+                       DynSymRegion.EntSize;
+
+  // Get the corresponding version index entry
+  const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
+  size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
+
+  // Special markers for unversioned symbols.
+  if (version_index == ELF::VER_NDX_LOCAL ||
+      version_index == ELF::VER_NDX_GLOBAL) {
+    IsDefault = false;
+    return StringRef("");
+  }
+
+  // Lookup this symbol in the version table
+  LoadVersionMap();
+  if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
+    return object_error::parse_failed;
+  const VersionMapEntry &entry = VersionMap[version_index];
+
+  // Get the version name string
+  size_t name_offset;
+  if (entry.isVerdef()) {
+    // The first Verdaux entry holds the name.
+    name_offset = entry.getVerdef()->getAux()->vda_name;
+  } else {
+    name_offset = entry.getVernaux()->vna_name;
+  }
+
+  // Set IsDefault
+  if (entry.isVerdef()) {
+    IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
+  } else {
+    IsDefault = false;
+  }
+
+  if (name_offset >= DynStrRegion.Size)
+    return object_error::parse_failed;
+  return StringRef(getDynamicString(name_offset));
+}
+
+/// This function returns the hash value for a symbol in the .dynsym section
+/// Name of the API remains consistent as specified in the libelf
+/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
+static inline unsigned elf_hash(StringRef &symbolName) {
+  unsigned h = 0, g;
+  for (unsigned i = 0, j = symbolName.size(); i < j; i++) {
+    h = (h << 4) + symbolName[i];
+    g = h & 0xf0000000L;
+    if (g != 0)
+      h ^= g >> 24;
+    h &= ~g;
+  }
+  return h;
+}
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
new file mode 100644
index 0000000..069f381
--- /dev/null
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -0,0 +1,1041 @@
+//===- ELFObjectFile.h - ELF object file implementation ---------*- 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 ELFObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_OBJECT_FILE_H
+#define LLVM_OBJECT_ELF_OBJECT_FILE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cctype>
+#include <limits>
+#include <utility>
+
+namespace llvm {
+namespace object {
+
+template <class ELFT>
+class ELFObjectFile : public ObjectFile {
+public:
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
+
+  typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
+  typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+  typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
+  typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
+  typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
+  typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
+
+  typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
+  typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
+  typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
+
+protected:
+  ELFFile<ELFT> EF;
+
+  void moveSymbolNext(DataRefImpl &Symb) const override;
+  std::error_code getSymbolName(DataRefImpl Symb,
+                                StringRef &Res) const override;
+  std::error_code getSymbolAddress(DataRefImpl Symb,
+                                   uint64_t &Res) const override;
+  std::error_code getSymbolAlignment(DataRefImpl Symb,
+                                     uint32_t &Res) const override;
+  std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+  std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override;
+  std::error_code getSymbolType(DataRefImpl Symb,
+                                SymbolRef::Type &Res) const override;
+  std::error_code getSymbolSection(DataRefImpl Symb,
+                                   section_iterator &Res) const override;
+
+  std::error_code getLibraryNext(DataRefImpl Data,
+                                 LibraryRef &Result) const override;
+  std::error_code getLibraryPath(DataRefImpl Data,
+                                 StringRef &Res) const override;
+
+  void moveSectionNext(DataRefImpl &Sec) const override;
+  std::error_code getSectionName(DataRefImpl Sec,
+                                 StringRef &Res) const override;
+  std::error_code getSectionAddress(DataRefImpl Sec,
+                                    uint64_t &Res) const override;
+  std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+  std::error_code getSectionContents(DataRefImpl Sec,
+                                     StringRef &Res) const override;
+  std::error_code getSectionAlignment(DataRefImpl Sec,
+                                      uint64_t &Res) const override;
+  std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+                                                bool &Res) const override;
+  std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+                                        bool &Res) const override;
+  std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+                                        bool &Result) const override;
+  relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+  relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+  section_iterator getRelocatedSection(DataRefImpl Sec) const override;
+
+  void moveRelocationNext(DataRefImpl &Rel) const override;
+  std::error_code getRelocationAddress(DataRefImpl Rel,
+                                       uint64_t &Res) const override;
+  std::error_code getRelocationOffset(DataRefImpl Rel,
+                                      uint64_t &Res) const override;
+  symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+  std::error_code getRelocationType(DataRefImpl Rel,
+                                    uint64_t &Res) const override;
+  std::error_code
+  getRelocationTypeName(DataRefImpl Rel,
+                        SmallVectorImpl<char> &Result) const override;
+  std::error_code
+  getRelocationValueString(DataRefImpl Rel,
+                           SmallVectorImpl<char> &Result) const override;
+
+  uint64_t getROffset(DataRefImpl Rel) const;
+  StringRef getRelocationTypeName(uint32_t Type) const;
+
+  /// \brief Get the relocation section that contains \a Rel.
+  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+    return EF.getSection(Rel.d.a);
+  }
+
+  const Elf_Rel *getRel(DataRefImpl Rel) const;
+  const Elf_Rela *getRela(DataRefImpl Rela) const;
+
+  Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const {
+    bool IsDynamic = Symb.p & 1;
+    if (IsDynamic)
+      return Elf_Sym_Iter(
+          EF.begin_dynamic_symbols().getEntSize(),
+          reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic);
+    return Elf_Sym_Iter(EF.begin_symbols().getEntSize(),
+                        reinterpret_cast<const char *>(Symb.p), IsDynamic);
+  }
+
+  DataRefImpl toDRI(Elf_Sym_Iter Symb) const {
+    DataRefImpl DRI;
+    DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) |
+      static_cast<uintptr_t>(Symb.isDynamic());
+    return DRI;
+  }
+
+  Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const {
+    return Elf_Shdr_Iter(EF.getHeader()->e_shentsize,
+                         reinterpret_cast<const char *>(Sec.p));
+  }
+
+  DataRefImpl toDRI(Elf_Shdr_Iter Sec) const {
+    DataRefImpl DRI;
+    DRI.p = reinterpret_cast<uintptr_t>(Sec.get());
+    return DRI;
+  }
+
+  DataRefImpl toDRI(const Elf_Shdr *Sec) const {
+    DataRefImpl DRI;
+    DRI.p = reinterpret_cast<uintptr_t>(Sec);
+    return DRI;
+  }
+
+  Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
+    return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
+                        reinterpret_cast<const char *>(Dyn.p));
+  }
+
+  DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
+    DataRefImpl DRI;
+    DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
+    return DRI;
+  }
+
+  // This flag is used for classof, to distinguish ELFObjectFile from
+  // its subclass. If more subclasses will be created, this flag will
+  // have to become an enum.
+  bool isDyldELFObject;
+
+public:
+  ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC);
+
+  const Elf_Sym *getSymbol(DataRefImpl Symb) const;
+
+  basic_symbol_iterator symbol_begin_impl() const override;
+  basic_symbol_iterator symbol_end_impl() const override;
+
+  symbol_iterator dynamic_symbol_begin() const;
+  symbol_iterator dynamic_symbol_end() const;
+
+  section_iterator section_begin() const override;
+  section_iterator section_end() const override;
+
+  library_iterator needed_library_begin() const override;
+  library_iterator needed_library_end() const override;
+
+  std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
+  std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
+                                   bool &IsDefault) const;
+
+  uint8_t getBytesInAddress() const override;
+  StringRef getFileFormatName() const override;
+  unsigned getArch() const override;
+  StringRef getLoadName() const override;
+
+  std::error_code getPlatformFlags(unsigned &Result) const override {
+    Result = EF.getHeader()->e_flags;
+    return object_error::success;
+  }
+
+  const ELFFile<ELFT> *getELFFile() const { return &EF; }
+
+  bool isDyldType() const { return isDyldELFObject; }
+  static inline bool classof(const Binary *v) {
+    return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
+                                      ELFT::Is64Bits);
+  }
+};
+
+// Use an alignment of 2 for the typedefs since that is the worst case for
+// ELF files in archives.
+typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile;
+typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile;
+typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile;
+typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile;
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
+  Symb = toDRI(++toELFSymIter(Symb));
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
+                                                   StringRef &Result) const {
+  ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
+  if (!Name)
+    return Name.getError();
+  Result = *Name;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
+                                                      StringRef &Version,
+                                                      bool &IsDefault) const {
+  DataRefImpl Symb = SymRef.getRawDataRefImpl();
+  const Elf_Sym *symb = getSymbol(Symb);
+  ErrorOr<StringRef> Ver =
+      EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault);
+  if (!Ver)
+    return Ver.getError();
+  Version = *Ver;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
+                                                      uint64_t &Result) const {
+  const Elf_Sym *ESym = getSymbol(Symb);
+  switch (EF.getSymbolTableIndex(ESym)) {
+  case ELF::SHN_COMMON:
+  case ELF::SHN_UNDEF:
+    Result = UnknownAddressOrSize;
+    return object_error::success;
+  case ELF::SHN_ABS:
+    Result = ESym->st_value;
+    return object_error::success;
+  default:
+    break;
+  }
+
+  const Elf_Ehdr *Header = EF.getHeader();
+  Result = ESym->st_value;
+
+  // Clear the ARM/Thumb indicator flag.
+  if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC)
+    Result &= ~1;
+
+  if (Header->e_type == ELF::ET_REL)
+    Result += EF.getSection(ESym)->sh_addr;
+
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
+                                                        uint32_t &Res) const {
+  Elf_Sym_Iter Sym = toELFSymIter(Symb);
+  if (Sym->st_shndx == ELF::SHN_COMMON)
+    Res = Sym->st_value;
+  else
+    Res = 0;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
+                                                   uint64_t &Result) const {
+  Result = toELFSymIter(Symb)->st_size;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb,
+                                                    uint8_t &Result) const {
+  Result = toELFSymIter(Symb)->st_other;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
+                                   SymbolRef::Type &Result) const {
+  const Elf_Sym *ESym = getSymbol(Symb);
+
+  switch (ESym->getType()) {
+  case ELF::STT_NOTYPE:
+    Result = SymbolRef::ST_Unknown;
+    break;
+  case ELF::STT_SECTION:
+    Result = SymbolRef::ST_Debug;
+    break;
+  case ELF::STT_FILE:
+    Result = SymbolRef::ST_File;
+    break;
+  case ELF::STT_FUNC:
+    Result = SymbolRef::ST_Function;
+    break;
+  case ELF::STT_OBJECT:
+  case ELF::STT_COMMON:
+  case ELF::STT_TLS:
+    Result = SymbolRef::ST_Data;
+    break;
+  default:
+    Result = SymbolRef::ST_Other;
+    break;
+  }
+  return object_error::success;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
+  Elf_Sym_Iter EIter = toELFSymIter(Symb);
+  const Elf_Sym *ESym = &*EIter;
+
+  uint32_t Result = SymbolRef::SF_None;
+
+  if (ESym->getBinding() != ELF::STB_LOCAL)
+    Result |= SymbolRef::SF_Global;
+
+  if (ESym->getBinding() == ELF::STB_WEAK)
+    Result |= SymbolRef::SF_Weak;
+
+  if (ESym->st_shndx == ELF::SHN_ABS)
+    Result |= SymbolRef::SF_Absolute;
+
+  if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
+      EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols())
+    Result |= SymbolRef::SF_FormatSpecific;
+
+  if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
+    Result |= SymbolRef::SF_Undefined;
+
+  if (ESym->getType() == ELF::STT_COMMON ||
+      EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON)
+    Result |= SymbolRef::SF_Common;
+
+  return Result;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
+                                      section_iterator &Res) const {
+  const Elf_Sym *ESym = getSymbol(Symb);
+  const Elf_Shdr *ESec = EF.getSection(ESym);
+  if (!ESec)
+    Res = section_end();
+  else {
+    DataRefImpl Sec;
+    Sec.p = reinterpret_cast<intptr_t>(ESec);
+    Res = section_iterator(SectionRef(Sec, this));
+  }
+  return object_error::success;
+}
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
+  Sec = toDRI(++toELFShdrIter(Sec));
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
+                                                    StringRef &Result) const {
+  ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
+  if (!Name)
+    return Name.getError();
+  Result = *Name;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
+                                                       uint64_t &Result) const {
+  Result = toELFShdrIter(Sec)->sh_addr;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
+                                                    uint64_t &Result) const {
+  Result = toELFShdrIter(Sec)->sh_size;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
+                                        StringRef &Result) const {
+  Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+  Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
+                                         uint64_t &Result) const {
+  Result = toELFShdrIter(Sec)->sh_addralign;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
+                                                   bool &Result) const {
+  Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
+                                                   bool &Result) const {
+  Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+  Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+           EShdr->sh_type == ELF::SHT_PROGBITS;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
+                                                  bool &Result) const {
+  Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+  Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+           EShdr->sh_type == ELF::SHT_NOBITS;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec,
+                                                   bool &Result) const {
+  Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
+                                                      bool &Result) const {
+  Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
+                                                       bool &Result) const {
+  Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS;
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
+                                                           bool &Result) const {
+  Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+  Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
+                                                           DataRefImpl Symb,
+                                                           bool &Result) const {
+  Elf_Sym_Iter ESym = toELFSymIter(Symb);
+
+  uintX_t Index = ESym->st_shndx;
+  bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE;
+
+  Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx));
+  return object_error::success;
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
+  DataRefImpl RelData;
+  uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
+  RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
+  RelData.d.b = 0;
+  return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
+  DataRefImpl RelData;
+  uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get());
+  const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+  RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
+  if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
+    RelData.d.b = 0;
+  else
+    RelData.d.b = S->sh_size / S->sh_entsize;
+
+  return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+section_iterator
+ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
+  if (EF.getHeader()->e_type != ELF::ET_REL)
+    return section_end();
+
+  Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
+  uintX_t Type = EShdr->sh_type;
+  if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
+    return section_end();
+
+  const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
+  return section_iterator(SectionRef(toDRI(R), this));
+}
+
+// Relocations
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
+  ++Rel.d.b;
+}
+
+template <class ELFT>
+symbol_iterator
+ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
+  uint32_t symbolIdx;
+  const Elf_Shdr *sec = getRelSection(Rel);
+  switch (sec->sh_type) {
+  default:
+    report_fatal_error("Invalid section type in Rel!");
+  case ELF::SHT_REL: {
+    symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
+    break;
+  }
+  case ELF::SHT_RELA: {
+    symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
+    break;
+  }
+  }
+  if (!symbolIdx)
+    return symbol_end();
+
+  const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
+
+  DataRefImpl SymbolData;
+  switch (SymSec->sh_type) {
+  default:
+    report_fatal_error("Invalid symbol table section type!");
+  case ELF::SHT_SYMTAB:
+    SymbolData = toDRI(EF.begin_symbols() + symbolIdx);
+    break;
+  case ELF::SHT_DYNSYM:
+    SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx);
+    break;
+  }
+
+  return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
+                                          uint64_t &Result) const {
+  uint64_t ROffset = getROffset(Rel);
+  const Elf_Ehdr *Header = EF.getHeader();
+
+  if (Header->e_type == ELF::ET_REL) {
+    const Elf_Shdr *RelocationSec = getRelSection(Rel);
+    const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
+    Result = ROffset + RelocatedSec->sh_addr;
+  } else {
+    Result = ROffset;
+  }
+
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
+                                         uint64_t &Result) const {
+  assert(EF.getHeader()->e_type == ELF::ET_REL &&
+         "Only relocatable object files have relocation offsets");
+  Result = getROffset(Rel);
+  return object_error::success;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  switch (sec->sh_type) {
+  default:
+    report_fatal_error("Invalid section type in Rel!");
+  case ELF::SHT_REL:
+    return getRel(Rel)->r_offset;
+  case ELF::SHT_RELA:
+    return getRela(Rel)->r_offset;
+  }
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
+                                                       uint64_t &Result) const {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  switch (sec->sh_type) {
+  default:
+    report_fatal_error("Invalid section type in Rel!");
+  case ELF::SHT_REL: {
+    Result = getRel(Rel)->getType(EF.isMips64EL());
+    break;
+  }
+  case ELF::SHT_RELA: {
+    Result = getRela(Rel)->getType(EF.isMips64EL());
+    break;
+  }
+  }
+  return object_error::success;
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+  return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getRelocationTypeName(
+    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  uint32_t type;
+  switch (sec->sh_type) {
+  default:
+    return object_error::parse_failed;
+  case ELF::SHT_REL: {
+    type = getRel(Rel)->getType(EF.isMips64EL());
+    break;
+  }
+  case ELF::SHT_RELA: {
+    type = getRela(Rel)->getType(EF.isMips64EL());
+    break;
+  }
+  }
+
+  EF.getRelocationTypeName(type, Result);
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code
+ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel,
+                                         int64_t &Result) const {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  switch (sec->sh_type) {
+  default:
+    report_fatal_error("Invalid section type in Rel!");
+  case ELF::SHT_REL: {
+    Result = 0;
+    return object_error::success;
+  }
+  case ELF::SHT_RELA: {
+    Result = getRela(Rel)->r_addend;
+    return object_error::success;
+  }
+  }
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getRelocationValueString(
+    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  uint8_t type;
+  StringRef res;
+  int64_t addend = 0;
+  uint16_t symbol_index = 0;
+  switch (sec->sh_type) {
+  default:
+    return object_error::parse_failed;
+  case ELF::SHT_REL: {
+    type = getRel(Rel)->getType(EF.isMips64EL());
+    symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL());
+    // TODO: Read implicit addend from section data.
+    break;
+  }
+  case ELF::SHT_RELA: {
+    type = getRela(Rel)->getType(EF.isMips64EL());
+    symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL());
+    addend = getRela(Rel)->r_addend;
+    break;
+  }
+  }
+  const Elf_Sym *symb =
+      EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
+  ErrorOr<StringRef> SymName =
+      EF.getSymbolName(EF.getSection(sec->sh_link), symb);
+  if (!SymName)
+    return SymName.getError();
+  switch (EF.getHeader()->e_machine) {
+  case ELF::EM_X86_64:
+    switch (type) {
+    case ELF::R_X86_64_PC8:
+    case ELF::R_X86_64_PC16:
+    case ELF::R_X86_64_PC32: {
+      std::string fmtbuf;
+      raw_string_ostream fmt(fmtbuf);
+      fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P";
+      fmt.flush();
+      Result.append(fmtbuf.begin(), fmtbuf.end());
+    } break;
+    case ELF::R_X86_64_8:
+    case ELF::R_X86_64_16:
+    case ELF::R_X86_64_32:
+    case ELF::R_X86_64_32S:
+    case ELF::R_X86_64_64: {
+      std::string fmtbuf;
+      raw_string_ostream fmt(fmtbuf);
+      fmt << *SymName << (addend < 0 ? "" : "+") << addend;
+      fmt.flush();
+      Result.append(fmtbuf.begin(), fmtbuf.end());
+    } break;
+    default:
+      res = "Unknown";
+    }
+    break;
+  case ELF::EM_AARCH64: {
+    std::string fmtbuf;
+    raw_string_ostream fmt(fmtbuf);
+    fmt << *SymName;
+    if (addend != 0)
+      fmt << (addend < 0 ? "" : "+") << addend;
+    fmt.flush();
+    Result.append(fmtbuf.begin(), fmtbuf.end());
+    break;
+  }
+  case ELF::EM_ARM:
+  case ELF::EM_HEXAGON:
+  case ELF::EM_MIPS:
+    res = *SymName;
+    break;
+  default:
+    res = "Unknown";
+  }
+  if (Result.empty())
+    Result.append(res.begin(), res.end());
+  return object_error::success;
+}
+
+template <class ELFT>
+const typename ELFFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
+  return &*toELFSymIter(Symb);
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rel *
+ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
+  return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rela *
+ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
+  return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
+}
+
+template <class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object,
+                                   std::error_code &EC)
+    : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
+                                support::little,
+                            ELFT::Is64Bits),
+                 std::move(Object)),
+      EF(Data->getBuffer(), EC) {}
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
+  return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
+}
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
+  return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
+}
+
+template <class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
+  return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
+}
+
+template <class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
+  return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_begin() const {
+  return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_end() const {
+  return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getLoadName() const {
+  Elf_Dyn_Iter DI = EF.begin_dynamic_table();
+  Elf_Dyn_Iter DE = EF.end_dynamic_table();
+
+  while (DI != DE && DI->getTag() != ELF::DT_SONAME)
+    ++DI;
+
+  if (DI != DE)
+    return EF.getDynamicString(DI->getVal());
+  return "";
+}
+
+template <class ELFT>
+library_iterator ELFObjectFile<ELFT>::needed_library_begin() const {
+  Elf_Dyn_Iter DI = EF.begin_dynamic_table();
+  Elf_Dyn_Iter DE = EF.end_dynamic_table();
+
+  while (DI != DE && DI->getTag() != ELF::DT_SONAME)
+    ++DI;
+
+  return library_iterator(LibraryRef(toDRI(DI), this));
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
+                                                    LibraryRef &Result) const {
+  Elf_Dyn_Iter DI = toELFDynIter(Data);
+  Elf_Dyn_Iter DE = EF.end_dynamic_table();
+
+  // Skip to the next DT_NEEDED entry.
+  do
+    ++DI;
+  while (DI != DE && DI->getTag() != ELF::DT_NEEDED);
+
+  Result = LibraryRef(toDRI(DI), this);
+  return object_error::success;
+}
+
+template <class ELFT>
+std::error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
+                                                    StringRef &Res) const {
+  Res = EF.getDynamicString(toELFDynIter(Data)->getVal());
+  return object_error::success;
+}
+
+template <class ELFT>
+library_iterator ELFObjectFile<ELFT>::needed_library_end() const {
+  return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this));
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
+  return ELFT::Is64Bits ? 8 : 4;
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
+  switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+  case ELF::ELFCLASS32:
+    switch (EF.getHeader()->e_machine) {
+    case ELF::EM_386:
+      return "ELF32-i386";
+    case ELF::EM_X86_64:
+      return "ELF32-x86-64";
+    case ELF::EM_ARM:
+      return "ELF32-arm";
+    case ELF::EM_HEXAGON:
+      return "ELF32-hexagon";
+    case ELF::EM_MIPS:
+      return "ELF32-mips";
+    case ELF::EM_PPC:
+      return "ELF32-ppc";
+    case ELF::EM_SPARC:
+    case ELF::EM_SPARC32PLUS:
+      return "ELF32-sparc";
+    default:
+      return "ELF32-unknown";
+    }
+  case ELF::ELFCLASS64:
+    switch (EF.getHeader()->e_machine) {
+    case ELF::EM_386:
+      return "ELF64-i386";
+    case ELF::EM_X86_64:
+      return "ELF64-x86-64";
+    case ELF::EM_AARCH64:
+      return "ELF64-aarch64";
+    case ELF::EM_PPC64:
+      return "ELF64-ppc64";
+    case ELF::EM_S390:
+      return "ELF64-s390";
+    case ELF::EM_SPARCV9:
+      return "ELF64-sparc";
+    case ELF::EM_MIPS:
+      return "ELF64-mips";
+    default:
+      return "ELF64-unknown";
+    }
+  default:
+    // FIXME: Proper error handling.
+    report_fatal_error("Invalid ELFCLASS!");
+  }
+}
+
+template <class ELFT>
+unsigned ELFObjectFile<ELFT>::getArch() const {
+  bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+  switch (EF.getHeader()->e_machine) {
+  case ELF::EM_386:
+    return Triple::x86;
+  case ELF::EM_X86_64:
+    return Triple::x86_64;
+  case ELF::EM_AARCH64:
+    return Triple::aarch64;
+  case ELF::EM_ARM:
+    return Triple::arm;
+  case ELF::EM_HEXAGON:
+    return Triple::hexagon;
+  case ELF::EM_MIPS:
+    switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+    case ELF::ELFCLASS32:
+      return IsLittleEndian ? Triple::mipsel : Triple::mips;
+    case ELF::ELFCLASS64:
+      return IsLittleEndian ? Triple::mips64el : Triple::mips64;
+    default:
+      report_fatal_error("Invalid ELFCLASS!");
+    }
+  case ELF::EM_PPC64:
+    return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
+  case ELF::EM_S390:
+    return Triple::systemz;
+
+  case ELF::EM_SPARC:
+  case ELF::EM_SPARC32PLUS:
+    return Triple::sparc;
+  case ELF::EM_SPARCV9:
+    return Triple::sparcv9;
+
+  default:
+    return Triple::UnknownArch;
+  }
+}
+
+/// FIXME: Maybe we should have a base ElfObjectFile that is not a template
+/// and make these member functions?
+inline std::error_code getELFRelocationAddend(const RelocationRef R,
+                                              int64_t &Addend) {
+  const ObjectFile *Obj = R.getObjectFile();
+  DataRefImpl DRI = R.getRawDataRefImpl();
+  // Little-endian 32-bit
+  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
+    return ELFObj->getRelocationAddend(DRI, Addend);
+
+  // Big-endian 32-bit
+  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
+    return ELFObj->getRelocationAddend(DRI, Addend);
+
+  // Little-endian 64-bit
+  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
+    return ELFObj->getRelocationAddend(DRI, Addend);
+
+  // Big-endian 64-bit
+  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
+    return ELFObj->getRelocationAddend(DRI, Addend);
+
+  llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF");
+}
+
+inline std::pair<symbol_iterator, symbol_iterator>
+getELFDynamicSymbolIterators(SymbolicFile *Obj) {
+  if (const ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
+    return std::make_pair(ELF->dynamic_symbol_begin(),
+                          ELF->dynamic_symbol_end());
+  if (const ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
+    return std::make_pair(ELF->dynamic_symbol_begin(),
+                          ELF->dynamic_symbol_end());
+  if (const ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
+    return std::make_pair(ELF->dynamic_symbol_begin(),
+                          ELF->dynamic_symbol_end());
+  if (const ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj))
+    return std::make_pair(ELF->dynamic_symbol_begin(),
+                          ELF->dynamic_symbol_end());
+
+  llvm_unreachable(
+      "Object passed to getELFDynamicSymbolIterators() is not ELF");
+}
+
+/// This is a generic interface for retrieving GNU symbol version
+/// information from an ELFObjectFile.
+inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj,
+                                           const SymbolRef &Sym,
+                                           StringRef &Version,
+                                           bool &IsDefault) {
+  // Little-endian 32-bit
+  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
+    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+  // Big-endian 32-bit
+  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
+    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+  // Little-endian 64-bit
+  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
+    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+  // Big-endian 64-bit
+  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
+    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+  llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
+}
+}
+}
+
+#endif
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
new file mode 100644
index 0000000..84b6031
--- /dev/null
+++ b/include/llvm/Object/ELFTypes.h
@@ -0,0 +1,463 @@
+//===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_TYPES_H
+#define LLVM_OBJECT_ELF_TYPES_H
+
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace object {
+
+using support::endianness;
+
+template <endianness target_endianness, std::size_t max_alignment,
+          bool is64Bits>
+struct ELFType {
+  static const endianness TargetEndianness = target_endianness;
+  static const std::size_t MaxAlignment = max_alignment;
+  static const bool Is64Bits = is64Bits;
+};
+
+template <typename T, int max_align> struct MaximumAlignment {
+  enum { value = AlignOf<T>::Alignment > max_align ? max_align
+                                                   : AlignOf<T>::Alignment
+  };
+};
+
+// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
+template <endianness target_endianness, std::size_t max_alignment>
+struct ELFDataTypeTypedefHelperCommon {
+  typedef support::detail::packed_endian_specific_integral<
+      uint16_t, target_endianness,
+      MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
+  typedef support::detail::packed_endian_specific_integral<
+      uint32_t, target_endianness,
+      MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
+  typedef support::detail::packed_endian_specific_integral<
+      int32_t, target_endianness,
+      MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
+  typedef support::detail::packed_endian_specific_integral<
+      uint64_t, target_endianness,
+      MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
+  typedef support::detail::packed_endian_specific_integral<
+      int64_t, target_endianness,
+      MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
+};
+
+template <class ELFT> struct ELFDataTypeTypedefHelper;
+
+/// ELF 32bit types.
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
+    : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
+  typedef uint32_t value_type;
+  typedef support::detail::packed_endian_specific_integral<
+      value_type, TargetEndianness,
+      MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
+  typedef support::detail::packed_endian_specific_integral<
+      value_type, TargetEndianness,
+      MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
+};
+
+/// ELF 64bit types.
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
+    : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
+  typedef uint64_t value_type;
+  typedef support::detail::packed_endian_specific_integral<
+      value_type, TargetEndianness,
+      MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
+  typedef support::detail::packed_endian_specific_integral<
+      value_type, TargetEndianness,
+      MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
+};
+
+// I really don't like doing this, but the alternative is copypasta.
+#define LLVM_ELF_IMPORT_TYPES(E, M, W)                                         \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr         \
+    Elf_Addr;                                                                  \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off          \
+    Elf_Off;                                                                   \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half         \
+    Elf_Half;                                                                  \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word         \
+    Elf_Word;                                                                  \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword        \
+    Elf_Sword;                                                                 \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword        \
+    Elf_Xword;                                                                 \
+typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword       \
+    Elf_Sxword;
+
+#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
+  LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment,            \
+                        ELFT::Is64Bits)
+
+// Section header.
+template <class ELFT> struct Elf_Shdr_Base;
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Word sh_name;      // Section name (index into string table)
+  Elf_Word sh_type;      // Section type (SHT_*)
+  Elf_Word sh_flags;     // Section flags (SHF_*)
+  Elf_Addr sh_addr;      // Address where section is to be loaded
+  Elf_Off sh_offset;     // File offset of section data, in bytes
+  Elf_Word sh_size;      // Size of section, in bytes
+  Elf_Word sh_link;      // Section type-specific header table index link
+  Elf_Word sh_info;      // Section type-specific extra information
+  Elf_Word sh_addralign; // Section address alignment
+  Elf_Word sh_entsize;   // Size of records contained within the section
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Word sh_name;       // Section name (index into string table)
+  Elf_Word sh_type;       // Section type (SHT_*)
+  Elf_Xword sh_flags;     // Section flags (SHF_*)
+  Elf_Addr sh_addr;       // Address where section is to be loaded
+  Elf_Off sh_offset;      // File offset of section data, in bytes
+  Elf_Xword sh_size;      // Size of section, in bytes
+  Elf_Word sh_link;       // Section type-specific header table index link
+  Elf_Word sh_info;       // Section type-specific extra information
+  Elf_Xword sh_addralign; // Section address alignment
+  Elf_Xword sh_entsize;   // Size of records contained within the section
+};
+
+template <class ELFT>
+struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
+  using Elf_Shdr_Base<ELFT>::sh_entsize;
+  using Elf_Shdr_Base<ELFT>::sh_size;
+
+  /// @brief Get the number of entities this section contains if it has any.
+  unsigned getEntityCount() const {
+    if (sh_entsize == 0)
+      return 0;
+    return sh_size / sh_entsize;
+  }
+};
+
+template <class ELFT> struct Elf_Sym_Base;
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Word st_name;       // Symbol name (index into string table)
+  Elf_Addr st_value;      // Value or address associated with the symbol
+  Elf_Word st_size;       // Size of the symbol
+  unsigned char st_info;  // Symbol's type and binding attributes
+  unsigned char st_other; // Must be zero; reserved
+  Elf_Half st_shndx;      // Which section (header table index) it's defined in
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Word st_name;       // Symbol name (index into string table)
+  unsigned char st_info;  // Symbol's type and binding attributes
+  unsigned char st_other; // Must be zero; reserved
+  Elf_Half st_shndx;      // Which section (header table index) it's defined in
+  Elf_Addr st_value;      // Value or address associated with the symbol
+  Elf_Xword st_size;      // Size of the symbol
+};
+
+template <class ELFT>
+struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
+  using Elf_Sym_Base<ELFT>::st_info;
+
+  // These accessors and mutators correspond to the ELF32_ST_BIND,
+  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+  unsigned char getBinding() const { return st_info >> 4; }
+  unsigned char getType() const { return st_info & 0x0f; }
+  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+  void setBindingAndType(unsigned char b, unsigned char t) {
+    st_info = (b << 4) + (t & 0x0f);
+  }
+};
+
+/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
+/// (.gnu.version). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Versym_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
+};
+
+template <class ELFT> struct Elf_Verdaux_Impl;
+
+/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
+/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdef_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+  Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
+  Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
+  Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
+  Elf_Half vd_cnt;     // Number of Verdaux entries
+  Elf_Word vd_hash;    // Hash of name
+  Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
+  Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
+
+  /// Get the first Verdaux entry for this Verdef.
+  const Elf_Verdaux *getAux() const {
+    return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
+  }
+};
+
+/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
+/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdaux_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  Elf_Word vda_name; // Version name (offset in string table)
+  Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
+};
+
+/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verneed_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
+  Elf_Half vn_cnt;     // Number of associated Vernaux entries
+  Elf_Word vn_file;    // Library name (string table offset)
+  Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
+  Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
+};
+
+/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Vernaux_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  Elf_Word vna_hash;  // Hash of dependency name
+  Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
+  Elf_Half vna_other; // Version index, used in .gnu.version entries
+  Elf_Word vna_name;  // Dependency name
+  Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
+};
+
+/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
+///               table section (.dynamic) look like.
+template <class ELFT> struct Elf_Dyn_Base;
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Sword d_tag;
+  union {
+    Elf_Word d_val;
+    Elf_Addr d_ptr;
+  } d_un;
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Sxword d_tag;
+  union {
+    Elf_Xword d_val;
+    Elf_Addr d_ptr;
+  } d_un;
+};
+
+/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
+template <class ELFT>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
+  using Elf_Dyn_Base<ELFT>::d_tag;
+  using Elf_Dyn_Base<ELFT>::d_un;
+  int64_t getTag() const { return d_tag; }
+  uint64_t getVal() const { return d_un.d_val; }
+  uint64_t getPtr() const { return d_un.ptr; }
+};
+
+// Elf_Rel: Elf Relocation
+template <class ELFT, bool isRela> struct Elf_Rel_Base;
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+  Elf_Word r_info;   // Symbol table index and type of relocation to apply
+
+  uint32_t getRInfo(bool isMips64EL) const {
+    assert(!isMips64EL);
+    return r_info;
+  }
+  void setRInfo(uint32_t R) { r_info = R; }
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+  Elf_Xword r_info;  // Symbol table index and type of relocation to apply
+
+  uint64_t getRInfo(bool isMips64EL) const {
+    uint64_t t = r_info;
+    if (!isMips64EL)
+      return t;
+    // Mips64 little endian has a "special" encoding of r_info. Instead of one
+    // 64 bit little endian number, it is a little endian 32 bit number followed
+    // by a 32 bit big endian number.
+    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+           ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+  }
+  void setRInfo(uint64_t R) {
+    // FIXME: Add mips64el support.
+    r_info = R;
+  }
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Addr r_offset;  // Location (file byte offset, or program virtual addr)
+  Elf_Word r_info;    // Symbol table index and type of relocation to apply
+  Elf_Sword r_addend; // Compute value for relocatable field by adding this
+
+  uint32_t getRInfo(bool isMips64EL) const {
+    assert(!isMips64EL);
+    return r_info;
+  }
+  void setRInfo(uint32_t R) { r_info = R; }
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Addr r_offset;   // Location (file byte offset, or program virtual addr)
+  Elf_Xword r_info;    // Symbol table index and type of relocation to apply
+  Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
+
+  uint64_t getRInfo(bool isMips64EL) const {
+    // Mips64 little endian has a "special" encoding of r_info. Instead of one
+    // 64 bit little endian number, it is a little endian 32 bit number followed
+    // by a 32 bit big endian number.
+    uint64_t t = r_info;
+    if (!isMips64EL)
+      return t;
+    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+           ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+  }
+  void setRInfo(uint64_t R) {
+    // FIXME: Add mips64el support.
+    r_info = R;
+  }
+};
+
+template <class ELFT, bool isRela> struct Elf_Rel_Impl;
+
+template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>,
+                    isRela> : Elf_Rel_Base<
+    ELFType<TargetEndianness, MaxAlign, true>, isRela> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+
+  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+  // and ELF64_R_INFO macros defined in the ELF specification:
+  uint32_t getSymbol(bool isMips64EL) const {
+    return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
+  }
+  uint32_t getType(bool isMips64EL) const {
+    return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
+  }
+  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
+  void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(uint32_t s, uint32_t t) {
+    this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL));
+  }
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>,
+                    isRela> : Elf_Rel_Base<
+    ELFType<TargetEndianness, MaxAlign, false>, isRela> {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+
+  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+  // and ELF32_R_INFO macros defined in the ELF specification:
+  uint32_t getSymbol(bool isMips64EL) const {
+    return this->getRInfo(isMips64EL) >> 8;
+  }
+  unsigned char getType(bool isMips64EL) const {
+    return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
+  }
+  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
+  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(uint32_t s, unsigned char t) {
+    this->setRInfo((s << 8) + t);
+  }
+};
+
+template <class ELFT>
+struct Elf_Ehdr_Impl {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
+  Elf_Half e_type;                       // Type of file (see ET_*)
+  Elf_Half e_machine;   // Required architecture for this file (see EM_*)
+  Elf_Word e_version;   // Must be equal to 1
+  Elf_Addr e_entry;     // Address to jump to in order to start program
+  Elf_Off e_phoff;      // Program header table's file offset, in bytes
+  Elf_Off e_shoff;      // Section header table's file offset, in bytes
+  Elf_Word e_flags;     // Processor-specific flags
+  Elf_Half e_ehsize;    // Size of ELF header, in bytes
+  Elf_Half e_phentsize; // Size of an entry in the program header table
+  Elf_Half e_phnum;     // Number of entries in the program header table
+  Elf_Half e_shentsize; // Size of an entry in the section header table
+  Elf_Half e_shnum;     // Number of entries in the section header table
+  Elf_Half e_shstrndx;  // Section header table index of section name
+                        // string table
+  bool checkMagic() const {
+    return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+  }
+  unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
+  unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
+};
+
+template <class ELFT> struct Elf_Phdr_Impl;
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
+  Elf_Word p_type;   // Type of segment
+  Elf_Off p_offset;  // FileOffset where segment is located, in bytes
+  Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
+  Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
+  Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+  Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
+  Elf_Word p_flags;  // Segment flags
+  Elf_Word p_align;  // Segment alignment constraint
+};
+
+template <endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
+  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
+  Elf_Word p_type;    // Type of segment
+  Elf_Word p_flags;   // Segment flags
+  Elf_Off p_offset;   // FileOffset where segment is located, in bytes
+  Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
+  Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
+  Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
+  Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
+  Elf_Xword p_align;  // Segment alignment constraint
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
new file mode 100644
index 0000000..fc8cc95
--- /dev/null
+++ b/include/llvm/Object/ELFYAML.h
@@ -0,0 +1,215 @@
+//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares classes for handling the YAML representation
+/// of ELF.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELFYAML_H
+#define LLVM_OBJECT_ELFYAML_H
+
+#include "llvm/MC/YAML.h"
+#include "llvm/Support/ELF.h"
+
+namespace llvm {
+namespace ELFYAML {
+
+// These types are invariant across 32/64-bit ELF, so for simplicity just
+// directly give them their exact sizes. We don't need to worry about
+// endianness because these are just the types in the YAMLIO structures,
+// and are appropriately converted to the necessary endianness when
+// reading/generating binary object files.
+// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
+// the common prefix of the respective constants. E.g. ELF_EM corresponds
+// to the `e_machine` constants, like `EM_X86_64`.
+// In the future, these would probably be better suited by C++11 enum
+// class's with appropriate fixed underlying type.
+LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
+// Just use 64, since it can hold 32-bit values too.
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL)
+// Just use 64, since it can hold 32-bit values too.
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
+
+// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
+// since 64-bit can hold 32-bit values too.
+struct FileHeader {
+  ELF_ELFCLASS Class;
+  ELF_ELFDATA Data;
+  ELF_ELFOSABI OSABI;
+  ELF_ET Type;
+  ELF_EM Machine;
+  ELF_EF Flags;
+  llvm::yaml::Hex64 Entry;
+};
+struct Symbol {
+  StringRef Name;
+  ELF_STT Type;
+  StringRef Section;
+  llvm::yaml::Hex64 Value;
+  llvm::yaml::Hex64 Size;
+  ELF_STV Visibility;
+};
+struct LocalGlobalWeakSymbols {
+  std::vector<Symbol> Local;
+  std::vector<Symbol> Global;
+  std::vector<Symbol> Weak;
+};
+struct Section {
+  enum class SectionKind { RawContent, Relocation };
+  SectionKind Kind;
+  StringRef Name;
+  ELF_SHT Type;
+  ELF_SHF Flags;
+  llvm::yaml::Hex64 Address;
+  StringRef Link;
+  llvm::yaml::Hex64 AddressAlign;
+  Section(SectionKind Kind) : Kind(Kind) {}
+  virtual ~Section();
+};
+struct RawContentSection : Section {
+  yaml::BinaryRef Content;
+  llvm::yaml::Hex64 Size;
+  RawContentSection() : Section(SectionKind::RawContent) {}
+  static bool classof(const Section *S) {
+    return S->Kind == SectionKind::RawContent;
+  }
+};
+struct Relocation {
+  llvm::yaml::Hex64 Offset;
+  int64_t Addend;
+  ELF_REL Type;
+  StringRef Symbol;
+};
+struct RelocationSection : Section {
+  StringRef Info;
+  std::vector<Relocation> Relocations;
+  RelocationSection() : Section(SectionKind::Relocation) {}
+  static bool classof(const Section *S) {
+    return S->Kind == SectionKind::Relocation;
+  }
+};
+struct Object {
+  FileHeader Header;
+  std::vector<std::unique_ptr<Section>> Sections;
+  // Although in reality the symbols reside in a section, it is a lot
+  // cleaner and nicer if we read them from the YAML as a separate
+  // top-level key, which automatically ensures that invariants like there
+  // being a single SHT_SYMTAB section are upheld.
+  LocalGlobalWeakSymbols Symbols;
+};
+
+} // end namespace ELFYAML
+} // end namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
+  static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
+  static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
+  static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
+  static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
+  static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
+};
+
+template <>
+struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
+  static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
+  static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
+};
+
+template <>
+struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
+  static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
+  static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
+  static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
+  static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
+};
+
+template <>
+struct MappingTraits<ELFYAML::FileHeader> {
+  static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
+};
+
+template <>
+struct MappingTraits<ELFYAML::Symbol> {
+  static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
+};
+
+template <>
+struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
+  static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
+};
+
+template <> struct MappingTraits<ELFYAML::Relocation> {
+  static void mapping(IO &IO, ELFYAML::Relocation &Rel);
+};
+
+template <>
+struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
+  static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
+  static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
+};
+
+template <>
+struct MappingTraits<ELFYAML::Object> {
+  static void mapping(IO &IO, ELFYAML::Object &Object);
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
new file mode 100644
index 0000000..701da12
--- /dev/null
+++ b/include/llvm/Object/Error.h
@@ -0,0 +1,45 @@
+//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This declares a new error_category for the Object library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ERROR_H
+#define LLVM_OBJECT_ERROR_H
+
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+const std::error_category &object_category();
+
+enum class object_error {
+  success = 0,
+  arch_not_found,
+  invalid_file_type,
+  parse_failed,
+  unexpected_eof
+};
+
+inline std::error_code make_error_code(object_error e) {
+  return std::error_code(static_cast<int>(e), object_category());
+}
+
+} // end namespace object.
+
+} // end namespace llvm.
+
+namespace std {
+template <>
+struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
+}
+
+#endif
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
new file mode 100644
index 0000000..b33cc26
--- /dev/null
+++ b/include/llvm/Object/IRObjectFile.h
@@ -0,0 +1,59 @@
+//===- IRObjectFile.h - LLVM IR object file implementation ------*- 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 IRObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IR_OBJECT_FILE_H
+#define LLVM_OBJECT_IR_OBJECT_FILE_H
+
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class Mangler;
+class Module;
+class GlobalValue;
+
+namespace object {
+class IRObjectFile : public SymbolicFile {
+  std::unique_ptr<Module> M;
+  std::unique_ptr<Mangler> Mang;
+  std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
+
+public:
+  IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<Module> M);
+  ~IRObjectFile();
+  void moveSymbolNext(DataRefImpl &Symb) const override;
+  std::error_code printSymbolName(raw_ostream &OS,
+                                  DataRefImpl Symb) const override;
+  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+  const GlobalValue *getSymbolGV(DataRefImpl Symb) const;
+  basic_symbol_iterator symbol_begin_impl() const override;
+  basic_symbol_iterator symbol_end_impl() const override;
+
+  const Module &getModule() const {
+    return const_cast<IRObjectFile*>(this)->getModule();
+  }
+  Module &getModule() {
+    return *M;
+  }
+
+  static inline bool classof(const Binary *v) {
+    return v->isIR();
+  }
+
+  static ErrorOr<IRObjectFile *>
+  createIRObjectFile(std::unique_ptr<MemoryBuffer> Object,
+                     LLVMContext &Context);
+};
+}
+}
+
+#endif
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
new file mode 100644
index 0000000..4835eb8
--- /dev/null
+++ b/include/llvm/Object/MachO.h
@@ -0,0 +1,306 @@
+//===- MachO.h - MachO object file implementation ---------------*- 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 MachOObjectFile class, which implement the ObjectFile
+// interface for MachO files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHO_H
+#define LLVM_OBJECT_MACHO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/MachO.h"
+
+namespace llvm {
+namespace object {
+
+/// DiceRef - This is a value type class that represents a single
+/// data in code entry in the table in a Mach-O object file.
+class DiceRef {
+  DataRefImpl DicePimpl;
+  const ObjectFile *OwningObject;
+
+public:
+  DiceRef() : OwningObject(nullptr) { }
+
+  DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
+
+  bool operator==(const DiceRef &Other) const;
+  bool operator<(const DiceRef &Other) const;
+
+  void moveNext();
+
+  std::error_code getOffset(uint32_t &Result) const;
+  std::error_code getLength(uint16_t &Result) const;
+  std::error_code getKind(uint16_t &Result) const;
+
+  DataRefImpl getRawDataRefImpl() const;
+  const ObjectFile *getObjectFile() const;
+};
+typedef content_iterator<DiceRef> dice_iterator;
+
+class MachOObjectFile : public ObjectFile {
+public:
+  struct LoadCommandInfo {
+    const char *Ptr;      // Where in memory the load command is.
+    MachO::load_command C; // The command itself.
+  };
+
+  MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian,
+                  bool Is64Bits, std::error_code &EC);
+
+  void moveSymbolNext(DataRefImpl &Symb) const override;
+  std::error_code getSymbolName(DataRefImpl Symb,
+                                StringRef &Res) const override;
+
+  // MachO specific.
+  std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
+
+  std::error_code getSymbolAddress(DataRefImpl Symb,
+                                   uint64_t &Res) const override;
+  std::error_code getSymbolAlignment(DataRefImpl Symb,
+                                     uint32_t &Res) const override;
+  std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+  std::error_code getSymbolType(DataRefImpl Symb,
+                                SymbolRef::Type &Res) const override;
+  uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+  std::error_code getSymbolSection(DataRefImpl Symb,
+                                   section_iterator &Res) const override;
+
+  void moveSectionNext(DataRefImpl &Sec) const override;
+  std::error_code getSectionName(DataRefImpl Sec,
+                                 StringRef &Res) const override;
+  std::error_code getSectionAddress(DataRefImpl Sec,
+                                    uint64_t &Res) const override;
+  std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+  std::error_code getSectionContents(DataRefImpl Sec,
+                                     StringRef &Res) const override;
+  std::error_code getSectionAlignment(DataRefImpl Sec,
+                                      uint64_t &Res) const override;
+  std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+                                                bool &Res) const override;
+  std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+  std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+                                        bool &Res) const override;
+  std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+                                        bool &Result) const override;
+  relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+  relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+  void moveRelocationNext(DataRefImpl &Rel) const override;
+  std::error_code getRelocationAddress(DataRefImpl Rel,
+                                       uint64_t &Res) const override;
+  std::error_code getRelocationOffset(DataRefImpl Rel,
+                                      uint64_t &Res) const override;
+  symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+  std::error_code getRelocationType(DataRefImpl Rel,
+                                    uint64_t &Res) const override;
+  std::error_code
+  getRelocationTypeName(DataRefImpl Rel,
+                        SmallVectorImpl<char> &Result) const override;
+  std::error_code
+  getRelocationValueString(DataRefImpl Rel,
+                           SmallVectorImpl<char> &Result) const override;
+  std::error_code getRelocationHidden(DataRefImpl Rel,
+                                      bool &Result) const override;
+
+  std::error_code getLibraryNext(DataRefImpl LibData,
+                                 LibraryRef &Res) const override;
+  std::error_code getLibraryPath(DataRefImpl LibData,
+                                 StringRef &Res) const override;
+
+  // MachO specific.
+  std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &Res);
+
+  // TODO: Would be useful to have an iterator based version
+  // of the load command interface too.
+
+  basic_symbol_iterator symbol_begin_impl() const override;
+  basic_symbol_iterator symbol_end_impl() const override;
+
+  // MachO specific.
+  basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
+
+  section_iterator section_begin() const override;
+  section_iterator section_end() const override;
+
+  library_iterator needed_library_begin() const override;
+  library_iterator needed_library_end() const override;
+
+  uint8_t getBytesInAddress() const override;
+
+  StringRef getFileFormatName() const override;
+  unsigned getArch() const override;
+
+  StringRef getLoadName() const override;
+
+  relocation_iterator section_rel_begin(unsigned Index) const;
+  relocation_iterator section_rel_end(unsigned Index) const;
+
+  dice_iterator begin_dices() const;
+  dice_iterator end_dices() const;
+
+  // In a MachO file, sections have a segment name. This is used in the .o
+  // files. They have a single segment, but this field specifies which segment
+  // a section should be put in in the final object.
+  StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
+
+  // Names are stored as 16 bytes. These returns the raw 16 bytes without
+  // interpreting them as a C string.
+  ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
+  ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
+
+  // MachO specific Info about relocations.
+  bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
+  unsigned getPlainRelocationSymbolNum(
+                                    const MachO::any_relocation_info &RE) const;
+  bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
+  bool getScatteredRelocationScattered(
+                                    const MachO::any_relocation_info &RE) const;
+  uint32_t getScatteredRelocationValue(
+                                    const MachO::any_relocation_info &RE) const;
+  unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
+  unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
+  unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
+  unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
+  SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const;
+
+  // Walk load commands.
+  LoadCommandInfo getFirstLoadCommandInfo() const;
+  LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;
+
+  // MachO specific structures.
+  MachO::section getSection(DataRefImpl DRI) const;
+  MachO::section_64 getSection64(DataRefImpl DRI) const;
+  MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
+  MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
+  MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
+  MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
+
+  MachO::linkedit_data_command
+  getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
+  MachO::segment_command
+  getSegmentLoadCommand(const LoadCommandInfo &L) const;
+  MachO::segment_command_64
+  getSegment64LoadCommand(const LoadCommandInfo &L) const;
+  MachO::linker_options_command
+  getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
+  MachO::version_min_command
+  getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+  MachO::dylib_command
+  getDylibIDLoadCommand(const LoadCommandInfo &L) const;
+
+  MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
+  MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
+  MachO::mach_header getHeader() const;
+  MachO::mach_header_64 getHeader64() const;
+  uint32_t
+  getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
+                              unsigned Index) const;
+  MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
+                                                    unsigned Index) const;
+  MachO::symtab_command getSymtabLoadCommand() const;
+  MachO::dysymtab_command getDysymtabLoadCommand() const;
+  MachO::linkedit_data_command getDataInCodeLoadCommand() const;
+
+  StringRef getStringTableData() const;
+  bool is64Bit() const;
+  void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+
+  static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
+                                         StringRef &Suffix);
+
+  static Triple::ArchType getArch(uint32_t CPUType);
+  static Triple getArch(uint32_t CPUType, uint32_t CPUSubType);
+  static Triple getArch(StringRef ArchFlag);
+  static Triple getHostArch();
+
+  static bool classof(const Binary *v) {
+    return v->isMachO();
+  }
+
+private:
+  typedef SmallVector<const char*, 1> SectionList;
+  SectionList Sections;
+  typedef SmallVector<const char*, 1> LibraryList;
+  LibraryList Libraries;
+  typedef SmallVector<StringRef, 1> LibraryShortName;
+  LibraryShortName LibrariesShortNames;
+  const char *SymtabLoadCmd;
+  const char *DysymtabLoadCmd;
+  const char *DataInCodeLoadCmd;
+};
+
+/// DiceRef
+inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
+  : DicePimpl(DiceP) , OwningObject(Owner) {}
+
+inline bool DiceRef::operator==(const DiceRef &Other) const {
+  return DicePimpl == Other.DicePimpl;
+}
+
+inline bool DiceRef::operator<(const DiceRef &Other) const {
+  return DicePimpl < Other.DicePimpl;
+}
+
+inline void DiceRef::moveNext() {
+  const MachO::data_in_code_entry *P =
+    reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
+  DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
+}
+
+// Since a Mach-O data in code reference, a DiceRef, can only be created when
+// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
+// the methods that get the values of the fields of the reference.
+
+inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
+  const MachOObjectFile *MachOOF =
+    static_cast<const MachOObjectFile *>(OwningObject);
+  MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+  Result = Dice.offset;
+  return object_error::success;
+}
+
+inline std::error_code DiceRef::getLength(uint16_t &Result) const {
+  const MachOObjectFile *MachOOF =
+    static_cast<const MachOObjectFile *>(OwningObject);
+  MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+  Result = Dice.length;
+  return object_error::success;
+}
+
+inline std::error_code DiceRef::getKind(uint16_t &Result) const {
+  const MachOObjectFile *MachOOF =
+    static_cast<const MachOObjectFile *>(OwningObject);
+  MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+  Result = Dice.kind;
+  return object_error::success;
+}
+
+inline DataRefImpl DiceRef::getRawDataRefImpl() const {
+  return DicePimpl;
+}
+
+inline const ObjectFile *DiceRef::getObjectFile() const {
+  return OwningObject;
+}
+
+}
+}
+
+#endif
+
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
new file mode 100644
index 0000000..e6677f5
--- /dev/null
+++ b/include/llvm/Object/MachOUniversal.h
@@ -0,0 +1,113 @@
+//===- MachOUniversal.h - Mach-O universal binaries -------------*- 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 Mach-O fat/universal binaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
+#define LLVM_OBJECT_MACHOUNIVERSAL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MachO.h"
+
+namespace llvm {
+namespace object {
+
+class ObjectFile;
+
+class MachOUniversalBinary : public Binary {
+  virtual void anchor();
+
+  uint32_t NumberOfObjects;
+public:
+  class ObjectForArch {
+    const MachOUniversalBinary *Parent;
+    /// \brief Index of object in the universal binary.
+    uint32_t Index;
+    /// \brief Descriptor of the object.
+    MachO::fat_arch Header;
+
+  public:
+    ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
+
+    void clear() {
+      Parent = nullptr;
+      Index = 0;
+    }
+
+    bool operator==(const ObjectForArch &Other) const {
+      return (Parent == Other.Parent) && (Index == Other.Index);
+    }
+
+    ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+    uint32_t getCPUType() const { return Header.cputype; }
+    std::string getArchTypeName() const {
+      Triple T = MachOObjectFile::getArch(Header.cputype, Header.cpusubtype);
+      return T.getArchName();
+    }
+
+    ErrorOr<std::unique_ptr<ObjectFile>> getAsObjectFile() const;
+
+    std::error_code getAsArchive(std::unique_ptr<Archive> &Result) const;
+  };
+
+  class object_iterator {
+    ObjectForArch Obj;
+  public:
+    object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+    const ObjectForArch* operator->() const {
+      return &Obj;
+    }
+
+    bool operator==(const object_iterator &Other) const {
+      return Obj == Other.Obj;
+    }
+    bool operator!=(const object_iterator &Other) const {
+      return !(*this == Other);
+    }
+
+    object_iterator& operator++() {  // Preincrement
+      Obj = Obj.getNext();
+      return *this;
+    }
+  };
+
+  MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source,
+                       std::error_code &ec);
+  static ErrorOr<MachOUniversalBinary *>
+  create(std::unique_ptr<MemoryBuffer> Source);
+
+  object_iterator begin_objects() const {
+    return ObjectForArch(this, 0);
+  }
+  object_iterator end_objects() const {
+    return ObjectForArch(nullptr, 0);
+  }
+
+  uint32_t getNumberOfObjects() const { return NumberOfObjects; }
+
+  // Cast methods.
+  static inline bool classof(Binary const *V) {
+    return V->isMachOUniversalBinary();
+  }
+
+  ErrorOr<std::unique_ptr<ObjectFile>>
+  getObjectForArch(Triple::ArchType Arch) const;
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
new file mode 100644
index 0000000..a4370a3
--- /dev/null
+++ b/include/llvm/Object/ObjectFile.h
@@ -0,0 +1,575 @@
+//===- ObjectFile.h - File format independent object 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 a file format independent ObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_OBJECTFILE_H
+#define LLVM_OBJECT_OBJECTFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstring>
+#include <vector>
+
+namespace llvm {
+namespace object {
+
+class ObjectFile;
+
+class SymbolRef;
+class symbol_iterator;
+
+/// RelocationRef - This is a value type class that represents a single
+/// relocation in the list of relocations in the object file.
+class RelocationRef {
+  DataRefImpl RelocationPimpl;
+  const ObjectFile *OwningObject;
+
+public:
+  RelocationRef() : OwningObject(nullptr) { }
+
+  RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
+
+  bool operator==(const RelocationRef &Other) const;
+
+  void moveNext();
+
+  std::error_code getAddress(uint64_t &Result) const;
+  std::error_code getOffset(uint64_t &Result) const;
+  symbol_iterator getSymbol() const;
+  std::error_code getType(uint64_t &Result) const;
+
+  /// @brief Indicates whether this relocation should hidden when listing
+  /// relocations, usually because it is the trailing part of a multipart
+  /// relocation that will be printed as part of the leading relocation.
+  std::error_code getHidden(bool &Result) const;
+
+  /// @brief Get a string that represents the type of this relocation.
+  ///
+  /// This is for display purposes only.
+  std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
+
+  /// @brief Get a string that represents the calculation of the value of this
+  ///        relocation.
+  ///
+  /// This is for display purposes only.
+  std::error_code getValueString(SmallVectorImpl<char> &Result) const;
+
+  DataRefImpl getRawDataRefImpl() const;
+  const ObjectFile *getObjectFile() const;
+};
+typedef content_iterator<RelocationRef> relocation_iterator;
+
+/// SectionRef - This is a value type class that represents a single section in
+/// the list of sections in the object file.
+class SectionRef;
+typedef content_iterator<SectionRef> section_iterator;
+class SectionRef {
+  friend class SymbolRef;
+  DataRefImpl SectionPimpl;
+  const ObjectFile *OwningObject;
+
+public:
+  SectionRef() : OwningObject(nullptr) { }
+
+  SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
+
+  bool operator==(const SectionRef &Other) const;
+  bool operator!=(const SectionRef &Other) const;
+  bool operator<(const SectionRef &Other) const;
+
+  void moveNext();
+
+  std::error_code getName(StringRef &Result) const;
+  std::error_code getAddress(uint64_t &Result) const;
+  std::error_code getSize(uint64_t &Result) const;
+  std::error_code getContents(StringRef &Result) const;
+
+  /// @brief Get the alignment of this section as the actual value (not log 2).
+  std::error_code getAlignment(uint64_t &Result) const;
+
+  // FIXME: Move to the normalization layer when it's created.
+  std::error_code isText(bool &Result) const;
+  std::error_code isData(bool &Result) const;
+  std::error_code isBSS(bool &Result) const;
+  std::error_code isRequiredForExecution(bool &Result) const;
+  std::error_code isVirtual(bool &Result) const;
+  std::error_code isZeroInit(bool &Result) const;
+  std::error_code isReadOnlyData(bool &Result) const;
+
+  std::error_code containsSymbol(SymbolRef S, bool &Result) const;
+
+  relocation_iterator relocation_begin() const;
+  relocation_iterator relocation_end() const;
+  iterator_range<relocation_iterator> relocations() const {
+    return iterator_range<relocation_iterator>(relocation_begin(),
+                                               relocation_end());
+  }
+  section_iterator getRelocatedSection() const;
+
+  DataRefImpl getRawDataRefImpl() const;
+};
+
+/// SymbolRef - This is a value type class that represents a single symbol in
+/// the list of symbols in the object file.
+class SymbolRef : public BasicSymbolRef {
+  friend class SectionRef;
+
+public:
+  SymbolRef() : BasicSymbolRef() {}
+
+  enum Type {
+    ST_Unknown, // Type not specified
+    ST_Data,
+    ST_Debug,
+    ST_File,
+    ST_Function,
+    ST_Other
+  };
+
+  SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
+
+  std::error_code getName(StringRef &Result) const;
+  /// Returns the symbol virtual address (i.e. address at which it will be
+  /// mapped).
+  std::error_code getAddress(uint64_t &Result) const;
+  /// @brief Get the alignment of this symbol as the actual value (not log 2).
+  std::error_code getAlignment(uint32_t &Result) const;
+  std::error_code getSize(uint64_t &Result) const;
+  std::error_code getType(SymbolRef::Type &Result) const;
+  std::error_code getOther(uint8_t &Result) const;
+
+  /// @brief Get section this symbol is defined in reference to. Result is
+  /// end_sections() if it is undefined or is an absolute symbol.
+  std::error_code getSection(section_iterator &Result) const;
+
+  const ObjectFile *getObject() const;
+};
+
+class symbol_iterator : public basic_symbol_iterator {
+public:
+  symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
+  symbol_iterator(const basic_symbol_iterator &B)
+      : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+                                        cast<ObjectFile>(B->getObject()))) {}
+
+  const SymbolRef *operator->() const {
+    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+    return static_cast<const SymbolRef*>(&P);
+  }
+
+  const SymbolRef &operator*() const {
+    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+    return static_cast<const SymbolRef&>(P);
+  }
+};
+
+/// LibraryRef - This is a value type class that represents a single library in
+/// the list of libraries needed by a shared or dynamic object.
+class LibraryRef {
+  friend class SectionRef;
+  DataRefImpl LibraryPimpl;
+  const ObjectFile *OwningObject;
+
+public:
+  LibraryRef() : OwningObject(nullptr) { }
+
+  LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
+
+  bool operator==(const LibraryRef &Other) const;
+  bool operator<(const LibraryRef &Other) const;
+
+  std::error_code getNext(LibraryRef &Result) const;
+
+  // Get the path to this library, as stored in the object file.
+  std::error_code getPath(StringRef &Result) const;
+
+  DataRefImpl getRawDataRefImpl() const;
+};
+typedef content_iterator<LibraryRef> library_iterator;
+
+/// ObjectFile - This class is the base class for all object file types.
+/// Concrete instances of this object are created by createObjectFile, which
+/// figures out which type to create.
+class ObjectFile : public SymbolicFile {
+  virtual void anchor();
+  ObjectFile() LLVM_DELETED_FUNCTION;
+  ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
+
+protected:
+  ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
+
+  const uint8_t *base() const {
+    return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
+  }
+
+  // These functions are for SymbolRef to call internally. The main goal of
+  // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
+  // entry in the memory mapped object file. SymbolPimpl cannot contain any
+  // virtual functions because then it could not point into the memory mapped
+  // file.
+  //
+  // Implementations assume that the DataRefImpl is valid and has not been
+  // modified externally. It's UB otherwise.
+  friend class SymbolRef;
+  virtual std::error_code getSymbolName(DataRefImpl Symb,
+                                        StringRef &Res) const = 0;
+  std::error_code printSymbolName(raw_ostream &OS,
+                                  DataRefImpl Symb) const override;
+  virtual std::error_code getSymbolAddress(DataRefImpl Symb,
+                                           uint64_t &Res) const = 0;
+  virtual std::error_code getSymbolAlignment(DataRefImpl Symb,
+                                             uint32_t &Res) const;
+  virtual std::error_code getSymbolSize(DataRefImpl Symb,
+                                        uint64_t &Res) const = 0;
+  virtual std::error_code getSymbolType(DataRefImpl Symb,
+                                        SymbolRef::Type &Res) const = 0;
+  virtual std::error_code getSymbolSection(DataRefImpl Symb,
+                                           section_iterator &Res) const = 0;
+  virtual std::error_code getSymbolOther(DataRefImpl Symb,
+                                         uint8_t &Res) const {
+    return object_error::invalid_file_type;
+  }
+
+  // Same as above for SectionRef.
+  friend class SectionRef;
+  virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
+  virtual std::error_code getSectionName(DataRefImpl Sec,
+                                         StringRef &Res) const = 0;
+  virtual std::error_code getSectionAddress(DataRefImpl Sec,
+                                            uint64_t &Res) const = 0;
+  virtual std::error_code getSectionSize(DataRefImpl Sec,
+                                         uint64_t &Res) const = 0;
+  virtual std::error_code getSectionContents(DataRefImpl Sec,
+                                             StringRef &Res) const = 0;
+  virtual std::error_code getSectionAlignment(DataRefImpl Sec,
+                                              uint64_t &Res) const = 0;
+  virtual std::error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
+  virtual std::error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
+  virtual std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
+  virtual std::error_code isSectionRequiredForExecution(DataRefImpl Sec,
+                                                        bool &Res) const = 0;
+  // A section is 'virtual' if its contents aren't present in the object image.
+  virtual std::error_code isSectionVirtual(DataRefImpl Sec,
+                                           bool &Res) const = 0;
+  virtual std::error_code isSectionZeroInit(DataRefImpl Sec,
+                                            bool &Res) const = 0;
+  virtual std::error_code isSectionReadOnlyData(DataRefImpl Sec,
+                                                bool &Res) const = 0;
+  virtual std::error_code sectionContainsSymbol(DataRefImpl Sec,
+                                                DataRefImpl Symb,
+                                                bool &Result) const = 0;
+  virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
+  virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
+  virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
+
+  // Same as above for RelocationRef.
+  friend class RelocationRef;
+  virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
+  virtual std::error_code getRelocationAddress(DataRefImpl Rel,
+                                               uint64_t &Res) const = 0;
+  virtual std::error_code getRelocationOffset(DataRefImpl Rel,
+                                              uint64_t &Res) const = 0;
+  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
+  virtual std::error_code getRelocationType(DataRefImpl Rel,
+                                            uint64_t &Res) const = 0;
+  virtual std::error_code
+  getRelocationTypeName(DataRefImpl Rel,
+                        SmallVectorImpl<char> &Result) const = 0;
+  virtual std::error_code
+  getRelocationValueString(DataRefImpl Rel,
+                           SmallVectorImpl<char> &Result) const = 0;
+  virtual std::error_code getRelocationHidden(DataRefImpl Rel,
+                                              bool &Result) const {
+    Result = false;
+    return object_error::success;
+  }
+
+  // Same for LibraryRef
+  friend class LibraryRef;
+  virtual std::error_code getLibraryNext(DataRefImpl Lib,
+                                         LibraryRef &Res) const = 0;
+  virtual std::error_code getLibraryPath(DataRefImpl Lib,
+                                         StringRef &Res) const = 0;
+
+public:
+  typedef iterator_range<symbol_iterator> symbol_iterator_range;
+  symbol_iterator_range symbols() const {
+    return symbol_iterator_range(symbol_begin(), symbol_end());
+  }
+
+  virtual section_iterator section_begin() const = 0;
+  virtual section_iterator section_end() const = 0;
+
+  typedef iterator_range<section_iterator> section_iterator_range;
+  section_iterator_range sections() const {
+    return section_iterator_range(section_begin(), section_end());
+  }
+
+  virtual library_iterator needed_library_begin() const = 0;
+  virtual library_iterator needed_library_end() const = 0;
+
+  /// @brief The number of bytes used to represent an address in this object
+  ///        file format.
+  virtual uint8_t getBytesInAddress() const = 0;
+
+  virtual StringRef getFileFormatName() const = 0;
+  virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+  /// For shared objects, returns the name which this object should be
+  /// loaded from at runtime. This corresponds to DT_SONAME on ELF and
+  /// LC_ID_DYLIB (install name) on MachO.
+  virtual StringRef getLoadName() const = 0;
+
+  /// Returns platform-specific object flags, if any.
+  virtual std::error_code getPlatformFlags(unsigned &Result) const {
+    Result = 0;
+    return object_error::invalid_file_type;
+  }
+
+  /// @returns Pointer to ObjectFile subclass to handle this type of object.
+  /// @param ObjectPath The path to the object file. ObjectPath.isObject must
+  ///        return true.
+  /// @brief Create ObjectFile from path.
+  static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
+  static ErrorOr<ObjectFile *>
+  createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
+                   sys::fs::file_magic Type);
+  static ErrorOr<ObjectFile *>
+  createObjectFile(std::unique_ptr<MemoryBuffer> &Object) {
+    return createObjectFile(Object, sys::fs::file_magic::unknown);
+  }
+
+
+  static inline bool classof(const Binary *v) {
+    return v->isObject();
+  }
+
+public:
+  static ErrorOr<ObjectFile *>
+  createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object);
+  static ErrorOr<ObjectFile *>
+  createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object);
+  static ErrorOr<ObjectFile *>
+  createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object);
+};
+
+// Inline function definitions.
+inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
+    : BasicSymbolRef(SymbolP, Owner) {}
+
+inline std::error_code SymbolRef::getName(StringRef &Result) const {
+  return getObject()->getSymbolName(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
+  return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const {
+  return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getSize(uint64_t &Result) const {
+  return getObject()->getSymbolSize(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
+  return getObject()->getSymbolSection(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const {
+  return getObject()->getSymbolType(getRawDataRefImpl(), Result);
+}
+
+inline std::error_code SymbolRef::getOther(uint8_t &Result) const {
+  return getObject()->getSymbolOther(getRawDataRefImpl(), Result);
+}
+
+inline const ObjectFile *SymbolRef::getObject() const {
+  const SymbolicFile *O = BasicSymbolRef::getObject();
+  return cast<ObjectFile>(O);
+}
+
+
+/// SectionRef
+inline SectionRef::SectionRef(DataRefImpl SectionP,
+                              const ObjectFile *Owner)
+  : SectionPimpl(SectionP)
+  , OwningObject(Owner) {}
+
+inline bool SectionRef::operator==(const SectionRef &Other) const {
+  return SectionPimpl == Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator!=(const SectionRef &Other) const {
+  return SectionPimpl != Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator<(const SectionRef &Other) const {
+  return SectionPimpl < Other.SectionPimpl;
+}
+
+inline void SectionRef::moveNext() {
+  return OwningObject->moveSectionNext(SectionPimpl);
+}
+
+inline std::error_code SectionRef::getName(StringRef &Result) const {
+  return OwningObject->getSectionName(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::getAddress(uint64_t &Result) const {
+  return OwningObject->getSectionAddress(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::getSize(uint64_t &Result) const {
+  return OwningObject->getSectionSize(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::getContents(StringRef &Result) const {
+  return OwningObject->getSectionContents(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::getAlignment(uint64_t &Result) const {
+  return OwningObject->getSectionAlignment(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isText(bool &Result) const {
+  return OwningObject->isSectionText(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isData(bool &Result) const {
+  return OwningObject->isSectionData(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isBSS(bool &Result) const {
+  return OwningObject->isSectionBSS(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isRequiredForExecution(bool &Result) const {
+  return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isVirtual(bool &Result) const {
+  return OwningObject->isSectionVirtual(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isZeroInit(bool &Result) const {
+  return OwningObject->isSectionZeroInit(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::isReadOnlyData(bool &Result) const {
+  return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
+}
+
+inline std::error_code SectionRef::containsSymbol(SymbolRef S,
+                                                  bool &Result) const {
+  return OwningObject->sectionContainsSymbol(SectionPimpl,
+                                             S.getRawDataRefImpl(), Result);
+}
+
+inline relocation_iterator SectionRef::relocation_begin() const {
+  return OwningObject->section_rel_begin(SectionPimpl);
+}
+
+inline relocation_iterator SectionRef::relocation_end() const {
+  return OwningObject->section_rel_end(SectionPimpl);
+}
+
+inline section_iterator SectionRef::getRelocatedSection() const {
+  return OwningObject->getRelocatedSection(SectionPimpl);
+}
+
+inline DataRefImpl SectionRef::getRawDataRefImpl() const {
+  return SectionPimpl;
+}
+
+/// RelocationRef
+inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
+                              const ObjectFile *Owner)
+  : RelocationPimpl(RelocationP)
+  , OwningObject(Owner) {}
+
+inline bool RelocationRef::operator==(const RelocationRef &Other) const {
+  return RelocationPimpl == Other.RelocationPimpl;
+}
+
+inline void RelocationRef::moveNext() {
+  return OwningObject->moveRelocationNext(RelocationPimpl);
+}
+
+inline std::error_code RelocationRef::getAddress(uint64_t &Result) const {
+  return OwningObject->getRelocationAddress(RelocationPimpl, Result);
+}
+
+inline std::error_code RelocationRef::getOffset(uint64_t &Result) const {
+  return OwningObject->getRelocationOffset(RelocationPimpl, Result);
+}
+
+inline symbol_iterator RelocationRef::getSymbol() const {
+  return OwningObject->getRelocationSymbol(RelocationPimpl);
+}
+
+inline std::error_code RelocationRef::getType(uint64_t &Result) const {
+  return OwningObject->getRelocationType(RelocationPimpl, Result);
+}
+
+inline std::error_code
+RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
+  return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
+}
+
+inline std::error_code
+RelocationRef::getValueString(SmallVectorImpl<char> &Result) const {
+  return OwningObject->getRelocationValueString(RelocationPimpl, Result);
+}
+
+inline std::error_code RelocationRef::getHidden(bool &Result) const {
+  return OwningObject->getRelocationHidden(RelocationPimpl, Result);
+}
+
+inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
+  return RelocationPimpl;
+}
+
+inline const ObjectFile *RelocationRef::getObjectFile() const {
+  return OwningObject;
+}
+
+// Inline function definitions.
+inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
+  : LibraryPimpl(LibraryP)
+  , OwningObject(Owner) {}
+
+inline bool LibraryRef::operator==(const LibraryRef &Other) const {
+  return LibraryPimpl == Other.LibraryPimpl;
+}
+
+inline bool LibraryRef::operator<(const LibraryRef &Other) const {
+  return LibraryPimpl < Other.LibraryPimpl;
+}
+
+inline std::error_code LibraryRef::getNext(LibraryRef &Result) const {
+  return OwningObject->getLibraryNext(LibraryPimpl, Result);
+}
+
+inline std::error_code LibraryRef::getPath(StringRef &Result) const {
+  return OwningObject->getLibraryPath(LibraryPimpl, Result);
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
new file mode 100644
index 0000000..5ca2450
--- /dev/null
+++ b/include/llvm/Object/RelocVisitor.h
@@ -0,0 +1,347 @@
+//===-- RelocVisitor.h - Visitor for object file relocations -*- 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 a wrapper around all the different types of relocations
+// in different file formats, such that a client can handle them in a unified
+// manner by only implementing a minimal number of functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RELOCVISITOR_H
+#define LLVM_OBJECT_RELOCVISITOR_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace object {
+
+struct RelocToApply {
+  // The computed value after applying the relevant relocations.
+  int64_t Value;
+
+  // The width of the value; how many bytes to touch when applying the
+  // relocation.
+  char Width;
+  RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
+  RelocToApply() : Value(0), Width(0) {}
+};
+
+/// @brief Base class for object file relocation visitors.
+class RelocVisitor {
+public:
+  explicit RelocVisitor(StringRef FileFormat)
+    : FileFormat(FileFormat), HasError(false) {}
+
+  // TODO: Should handle multiple applied relocations via either passing in the
+  // previously computed value or just count paired relocations as a single
+  // visit.
+  RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
+                     uint64_t Value = 0) {
+    if (FileFormat == "ELF64-x86-64") {
+      switch (RelocType) {
+        case llvm::ELF::R_X86_64_NONE:
+          return visitELF_X86_64_NONE(R);
+        case llvm::ELF::R_X86_64_64:
+          return visitELF_X86_64_64(R, Value);
+        case llvm::ELF::R_X86_64_PC32:
+          return visitELF_X86_64_PC32(R, Value, SecAddr);
+        case llvm::ELF::R_X86_64_32:
+          return visitELF_X86_64_32(R, Value);
+        case llvm::ELF::R_X86_64_32S:
+          return visitELF_X86_64_32S(R, Value);
+        default:
+          HasError = true;
+          return RelocToApply();
+      }
+    } else if (FileFormat == "ELF32-i386") {
+      switch (RelocType) {
+      case llvm::ELF::R_386_NONE:
+        return visitELF_386_NONE(R);
+      case llvm::ELF::R_386_32:
+        return visitELF_386_32(R, Value);
+      case llvm::ELF::R_386_PC32:
+        return visitELF_386_PC32(R, Value, SecAddr);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF64-ppc64") {
+      switch (RelocType) {
+      case llvm::ELF::R_PPC64_ADDR32:
+        return visitELF_PPC64_ADDR32(R, Value);
+      case llvm::ELF::R_PPC64_ADDR64:
+        return visitELF_PPC64_ADDR64(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF32-ppc") {
+      switch (RelocType) {
+      case llvm::ELF::R_PPC_ADDR32:
+        return visitELF_PPC_ADDR32(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF32-mips") {
+      switch (RelocType) {
+      case llvm::ELF::R_MIPS_32:
+        return visitELF_MIPS_32(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF64-mips") {
+      switch (RelocType) {
+      case llvm::ELF::R_MIPS_32:
+        return visitELF_MIPS_32(R, Value);
+      case llvm::ELF::R_MIPS_64:
+        return visitELF_MIPS_64(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF64-aarch64") {
+      switch (RelocType) {
+      case llvm::ELF::R_AARCH64_ABS32:
+        return visitELF_AARCH64_ABS32(R, Value);
+      case llvm::ELF::R_AARCH64_ABS64:
+        return visitELF_AARCH64_ABS64(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF64-s390") {
+      switch (RelocType) {
+      case llvm::ELF::R_390_32:
+        return visitELF_390_32(R, Value);
+      case llvm::ELF::R_390_64:
+        return visitELF_390_64(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF32-sparc") {
+      switch (RelocType) {
+      case llvm::ELF::R_SPARC_32:
+      case llvm::ELF::R_SPARC_UA32:
+        return visitELF_SPARC_32(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF64-sparc") {
+      switch (RelocType) {
+      case llvm::ELF::R_SPARC_32:
+      case llvm::ELF::R_SPARC_UA32:
+        return visitELF_SPARCV9_32(R, Value);
+      case llvm::ELF::R_SPARC_64:
+      case llvm::ELF::R_SPARC_UA64:
+        return visitELF_SPARCV9_64(R, Value);
+      default:
+        HasError = true;
+        return RelocToApply();
+      }
+    } else if (FileFormat == "ELF32-arm") {
+      switch (RelocType) {
+      default:
+        HasError = true;
+        return RelocToApply();
+      case llvm::ELF::R_ARM_ABS32:
+        return visitELF_ARM_ABS32(R, Value);
+      }
+    }
+    HasError = true;
+    return RelocToApply();
+  }
+
+  bool error() { return HasError; }
+
+private:
+  StringRef FileFormat;
+  bool HasError;
+
+  int64_t getAddend32LE(RelocationRef R) {
+    const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile());
+    DataRefImpl DRI = R.getRawDataRefImpl();
+    int64_t Addend;
+    Obj->getRelocationAddend(DRI, Addend);
+    return Addend;
+  }
+
+  int64_t getAddend64LE(RelocationRef R) {
+    const ELF64LEObjectFile *Obj = cast<ELF64LEObjectFile>(R.getObjectFile());
+    DataRefImpl DRI = R.getRawDataRefImpl();
+    int64_t Addend;
+    Obj->getRelocationAddend(DRI, Addend);
+    return Addend;
+  }
+
+  int64_t getAddend32BE(RelocationRef R) {
+    const ELF32BEObjectFile *Obj = cast<ELF32BEObjectFile>(R.getObjectFile());
+    DataRefImpl DRI = R.getRawDataRefImpl();
+    int64_t Addend;
+    Obj->getRelocationAddend(DRI, Addend);
+    return Addend;
+  }
+
+  int64_t getAddend64BE(RelocationRef R) {
+    const ELF64BEObjectFile *Obj = cast<ELF64BEObjectFile>(R.getObjectFile());
+    DataRefImpl DRI = R.getRawDataRefImpl();
+    int64_t Addend;
+    Obj->getRelocationAddend(DRI, Addend);
+    return Addend;
+  }
+  /// Operations
+
+  /// 386-ELF
+  RelocToApply visitELF_386_NONE(RelocationRef R) {
+    return RelocToApply(0, 0);
+  }
+
+  // Ideally the Addend here will be the addend in the data for
+  // the relocation. It's not actually the case for Rel relocations.
+  RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend32LE(R);
+    return RelocToApply(Value + Addend, 4);
+  }
+
+  RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
+                                 uint64_t SecAddr) {
+    int64_t Addend = getAddend32LE(R);
+    uint64_t Address;
+    R.getOffset(Address);
+    return RelocToApply(Value + Addend - Address, 4);
+  }
+
+  /// X86-64 ELF
+  RelocToApply visitELF_X86_64_NONE(RelocationRef R) {
+    return RelocToApply(0, 0);
+  }
+  RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64LE(R);
+    return RelocToApply(Value + Addend, 8);
+  }
+  RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
+                                    uint64_t SecAddr) {
+    int64_t Addend = getAddend64LE(R);
+    uint64_t Address;
+    R.getOffset(Address);
+    return RelocToApply(Value + Addend - Address, 4);
+  }
+  RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64LE(R);
+    uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+    return RelocToApply(Res, 4);
+  }
+  RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64LE(R);
+    int32_t Res = (Value + Addend) & 0xFFFFFFFF;
+    return RelocToApply(Res, 4);
+  }
+
+  /// PPC64 ELF
+  RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
+    int64_t Addend;
+    getELFRelocationAddend(R, Addend);
+    uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+    return RelocToApply(Res, 4);
+  }
+  RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) {
+    int64_t Addend;
+    getELFRelocationAddend(R, Addend);
+    return RelocToApply(Value + Addend, 8);
+  }
+
+  /// PPC32 ELF
+  RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend32BE(R);
+    uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+    return RelocToApply(Res, 4);
+  }
+
+  /// MIPS ELF
+  RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
+    int64_t Addend;
+    getELFRelocationAddend(R, Addend);
+    uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+    return RelocToApply(Res, 4);
+  }
+
+  RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) {
+    int64_t Addend;
+    getELFRelocationAddend(R, Addend);
+    uint64_t Res = (Value + Addend);
+    return RelocToApply(Res, 8);
+  }
+
+  // AArch64 ELF
+  RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64LE(R);
+    int64_t Res =  Value + Addend;
+
+    // Overflow check allows for both signed and unsigned interpretation.
+    if (Res < INT32_MIN || Res > UINT32_MAX)
+      HasError = true;
+
+    return RelocToApply(static_cast<uint32_t>(Res), 4);
+  }
+
+  RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64LE(R);
+    return RelocToApply(Value + Addend, 8);
+  }
+
+  // SystemZ ELF
+  RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64BE(R);
+    int64_t Res = Value + Addend;
+
+    // Overflow check allows for both signed and unsigned interpretation.
+    if (Res < INT32_MIN || Res > UINT32_MAX)
+      HasError = true;
+
+    return RelocToApply(static_cast<uint32_t>(Res), 4);
+  }
+
+  RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64BE(R);
+    return RelocToApply(Value + Addend, 8);
+  }
+
+  RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
+    int32_t Addend = getAddend32BE(R);
+    return RelocToApply(Value + Addend, 4);
+  }
+
+  RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
+    int32_t Addend = getAddend64BE(R);
+    return RelocToApply(Value + Addend, 4);
+  }
+
+  RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend64BE(R);
+    return RelocToApply(Value + Addend, 8);
+  }
+
+  RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getAddend32LE(R);
+    return RelocToApply(Value + Addend, 4);
+  }
+
+};
+
+}
+}
+#endif
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
new file mode 100644
index 0000000..77eef4a
--- /dev/null
+++ b/include/llvm/Object/SymbolicFile.h
@@ -0,0 +1,195 @@
+//===- SymbolicFile.h - Interface that only provides symbols ----*- 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 SymbolicFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLIC_FILE_H
+#define LLVM_OBJECT_SYMBOLIC_FILE_H
+
+#include "llvm/Object/Binary.h"
+
+namespace llvm {
+namespace object {
+
+union DataRefImpl {
+  // This entire union should probably be a
+  // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+  struct {
+    uint32_t a, b;
+  } d;
+  uintptr_t p;
+  DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
+};
+
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
+  // Check bitwise identical. This is the only legal way to compare a union w/o
+  // knowing which member is in use.
+  return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
+
+inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
+  return !operator==(a, b);
+}
+
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
+  // Check bitwise identical. This is the only legal way to compare a union w/o
+  // knowing which member is in use.
+  return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
+}
+
+template <class content_type> class content_iterator {
+  content_type Current;
+
+public:
+  content_iterator(content_type symb) : Current(symb) {}
+
+  const content_type *operator->() const { return &Current; }
+
+  const content_type &operator*() const { return Current; }
+
+  bool operator==(const content_iterator &other) const {
+    return Current == other.Current;
+  }
+
+  bool operator!=(const content_iterator &other) const {
+    return !(*this == other);
+  }
+
+  content_iterator &operator++() { // preincrement
+    Current.moveNext();
+    return *this;
+  }
+};
+
+class SymbolicFile;
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class BasicSymbolRef {
+  DataRefImpl SymbolPimpl;
+  const SymbolicFile *OwningObject;
+
+public:
+  // FIXME: should we add a SF_Text?
+  enum Flags : unsigned {
+    SF_None = 0,
+    SF_Undefined = 1U << 0,      // Symbol is defined in another object file
+    SF_Global = 1U << 1,         // Global symbol
+    SF_Weak = 1U << 2,           // Weak symbol
+    SF_Absolute = 1U << 3,       // Absolute symbol
+    SF_Common = 1U << 4,         // Symbol has common linkage
+    SF_Indirect = 1U << 5,       // Symbol is an alias to another symbol
+    SF_FormatSpecific = 1U << 6  // Specific to the object file format
+                                 // (e.g. section symbols)
+  };
+
+  BasicSymbolRef() : OwningObject(nullptr) { }
+  BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+  bool operator==(const BasicSymbolRef &Other) const;
+  bool operator<(const BasicSymbolRef &Other) const;
+
+  void moveNext();
+
+  std::error_code printName(raw_ostream &OS) const;
+
+  /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+  uint32_t getFlags() const;
+
+  DataRefImpl getRawDataRefImpl() const;
+  const SymbolicFile *getObject() const;
+};
+
+typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
+
+const uint64_t UnknownAddressOrSize = ~0ULL;
+
+class SymbolicFile : public Binary {
+public:
+  virtual ~SymbolicFile();
+  SymbolicFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
+
+  // virtual interface.
+  virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+  virtual std::error_code printSymbolName(raw_ostream &OS,
+                                          DataRefImpl Symb) const = 0;
+
+  virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
+
+  virtual basic_symbol_iterator symbol_begin_impl() const = 0;
+
+  virtual basic_symbol_iterator symbol_end_impl() const = 0;
+
+  // convenience wrappers.
+  basic_symbol_iterator symbol_begin() const {
+    return symbol_begin_impl();
+  }
+  basic_symbol_iterator symbol_end() const {
+    return symbol_end_impl();
+  }
+  typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range;
+  basic_symbol_iterator_range symbols() const {
+    return basic_symbol_iterator_range(symbol_begin(), symbol_end());
+  }
+
+  // construction aux.
+  static ErrorOr<SymbolicFile *>
+  createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
+                     sys::fs::file_magic Type, LLVMContext *Context);
+
+  static ErrorOr<SymbolicFile *>
+  createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) {
+    return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
+  }
+  static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
+
+  static inline bool classof(const Binary *v) {
+    return v->isSymbolic();
+  }
+};
+
+inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
+                                      const SymbolicFile *Owner)
+    : SymbolPimpl(SymbolP), OwningObject(Owner) {}
+
+inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
+  return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
+  return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline void BasicSymbolRef::moveNext() {
+  return OwningObject->moveSymbolNext(SymbolPimpl);
+}
+
+inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+  return OwningObject->printSymbolName(OS, SymbolPimpl);
+}
+
+inline uint32_t BasicSymbolRef::getFlags() const {
+  return OwningObject->getSymbolFlags(SymbolPimpl);
+}
+
+inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
+  return SymbolPimpl;
+}
+
+inline const SymbolicFile *BasicSymbolRef::getObject() const {
+  return OwningObject;
+}
+
+}
+}
+
+#endif
diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h
new file mode 100644
index 0000000..dcaa540
--- /dev/null
+++ b/include/llvm/Option/Arg.h
@@ -0,0 +1,129 @@
+//===--- Arg.h - Parsed Argument Classes ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the llvm::Arg class for parsed arguments.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPTION_ARG_H
+#define LLVM_OPTION_ARG_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/Option.h"
+#include <string>
+
+namespace llvm {
+namespace opt {
+class ArgList;
+
+/// \brief A concrete instance of a particular driver option.
+///
+/// The Arg class encodes just enough information to be able to
+/// derive the argument values efficiently.
+class Arg {
+  Arg(const Arg &) LLVM_DELETED_FUNCTION;
+  void operator=(const Arg &) LLVM_DELETED_FUNCTION;
+
+private:
+  /// \brief The option this argument is an instance of.
+  const Option Opt;
+
+  /// \brief The argument this argument was derived from (during tool chain
+  /// argument translation), if any.
+  const Arg *BaseArg;
+
+  /// \brief How this instance of the option was spelled.
+  StringRef Spelling;
+
+  /// \brief The index at which this argument appears in the containing
+  /// ArgList.
+  unsigned Index;
+
+  /// \brief Was this argument used to effect compilation?
+  ///
+  /// This is used for generating "argument unused" diagnostics.
+  mutable unsigned Claimed : 1;
+
+  /// \brief Does this argument own its values?
+  mutable unsigned OwnsValues : 1;
+
+  /// \brief The argument values, as C strings.
+  SmallVector<const char *, 2> Values;
+
+public:
+  Arg(const Option Opt, StringRef Spelling, unsigned Index,
+      const Arg *BaseArg = nullptr);
+  Arg(const Option Opt, StringRef Spelling, unsigned Index,
+      const char *Value0, const Arg *BaseArg = nullptr);
+  Arg(const Option Opt, StringRef Spelling, unsigned Index,
+      const char *Value0, const char *Value1, const Arg *BaseArg = nullptr);
+  ~Arg();
+
+  const Option &getOption() const { return Opt; }
+  StringRef getSpelling() const { return Spelling; }
+  unsigned getIndex() const { return Index; }
+
+  /// \brief Return the base argument which generated this arg.
+  ///
+  /// This is either the argument itself or the argument it was
+  /// derived from during tool chain specific argument translation.
+  const Arg &getBaseArg() const {
+    return BaseArg ? *BaseArg : *this;
+  }
+  void setBaseArg(const Arg *_BaseArg) {
+    BaseArg = _BaseArg;
+  }
+
+  bool getOwnsValues() const { return OwnsValues; }
+  void setOwnsValues(bool Value) const { OwnsValues = Value; }
+
+  bool isClaimed() const { return getBaseArg().Claimed; }
+
+  /// \brief Set the Arg claimed bit.
+  void claim() const { getBaseArg().Claimed = true; }
+
+  unsigned getNumValues() const { return Values.size(); }
+  const char *getValue(unsigned N = 0) const {
+    return Values[N];
+  }
+
+  SmallVectorImpl<const char*> &getValues() {
+    return Values;
+  }
+
+  bool containsValue(StringRef Value) const {
+    for (unsigned i = 0, e = getNumValues(); i != e; ++i)
+      if (Values[i] == Value)
+        return true;
+    return false;
+  }
+
+  /// \brief Append the argument onto the given array as strings.
+  void render(const ArgList &Args, ArgStringList &Output) const;
+
+  /// \brief Append the argument, render as an input, onto the given
+  /// array as strings.
+  ///
+  /// The distinction is that some options only render their values
+  /// when rendered as a input (e.g., Xlinker).
+  void renderAsInput(const ArgList &Args, ArgStringList &Output) const;
+
+  void dump() const;
+
+  /// \brief Return a formatted version of the argument and
+  /// its values, for debugging and diagnostics.
+  std::string getAsString(const ArgList &Args) const;
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
new file mode 100644
index 0000000..d46b0e8
--- /dev/null
+++ b/include/llvm/Option/ArgList.h
@@ -0,0 +1,434 @@
+//===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPTION_ARGLIST_H
+#define LLVM_OPTION_ARGLIST_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/OptSpecifier.h"
+#include "llvm/Option/Option.h"
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+namespace opt {
+class Arg;
+class ArgList;
+class Option;
+
+/// arg_iterator - Iterates through arguments stored inside an ArgList.
+class arg_iterator {
+  /// The current argument.
+  SmallVectorImpl<Arg*>::const_iterator Current;
+
+  /// The argument list we are iterating over.
+  const ArgList &Args;
+
+  /// Optional filters on the arguments which will be match. Most clients
+  /// should never want to iterate over arguments without filters, so we won't
+  /// bother to factor this into two separate iterator implementations.
+  //
+  // FIXME: Make efficient; the idea is to provide efficient iteration over
+  // all arguments which match a particular id and then just provide an
+  // iterator combinator which takes multiple iterators which can be
+  // efficiently compared and returns them in order.
+  OptSpecifier Id0, Id1, Id2;
+
+  void SkipToNextArg();
+
+public:
+  typedef Arg * const *                 value_type;
+  typedef Arg * const &                 reference;
+  typedef Arg * const *                 pointer;
+  typedef std::forward_iterator_tag   iterator_category;
+  typedef std::ptrdiff_t              difference_type;
+
+  arg_iterator(SmallVectorImpl<Arg*>::const_iterator it,
+                const ArgList &_Args, OptSpecifier _Id0 = 0U,
+                OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+    : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+    SkipToNextArg();
+  }
+
+  operator const Arg*() { return *Current; }
+  reference operator*() const { return *Current; }
+  pointer operator->() const { return Current; }
+
+  arg_iterator &operator++() {
+    ++Current;
+    SkipToNextArg();
+    return *this;
+  }
+
+  arg_iterator operator++(int) {
+    arg_iterator tmp(*this);
+    ++(*this);
+    return tmp;
+  }
+
+  friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+    return LHS.Current == RHS.Current;
+  }
+  friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+    return !(LHS == RHS);
+  }
+};
+
+/// ArgList - Ordered collection of driver arguments.
+///
+/// The ArgList class manages a list of Arg instances as well as
+/// auxiliary data and convenience methods to allow Tools to quickly
+/// check for the presence of Arg instances for a particular Option
+/// and to iterate over groups of arguments.
+class ArgList {
+private:
+  ArgList(const ArgList &) LLVM_DELETED_FUNCTION;
+  void operator=(const ArgList &) LLVM_DELETED_FUNCTION;
+
+public:
+  typedef SmallVector<Arg*, 16> arglist_type;
+  typedef arglist_type::iterator iterator;
+  typedef arglist_type::const_iterator const_iterator;
+  typedef arglist_type::reverse_iterator reverse_iterator;
+  typedef arglist_type::const_reverse_iterator const_reverse_iterator;
+
+private:
+  /// The internal list of arguments.
+  arglist_type Args;
+
+protected:
+  // Default ctor provided explicitly as it is not provided implicitly due to
+  // the presence of the (deleted) copy ctor above.
+  ArgList() { }
+  // Virtual to provide a vtable anchor and because -Wnon-virtua-dtor warns, not
+  // because this type is ever actually destroyed polymorphically.
+  virtual ~ArgList();
+
+public:
+
+  /// @name Arg Access
+  /// @{
+
+  /// append - Append \p A to the arg list.
+  void append(Arg *A);
+
+  arglist_type &getArgs() { return Args; }
+  const arglist_type &getArgs() const { return Args; }
+
+  unsigned size() const { return Args.size(); }
+
+  /// @}
+  /// @name Arg Iteration
+  /// @{
+
+  iterator begin() { return Args.begin(); }
+  iterator end() { return Args.end(); }
+
+  reverse_iterator rbegin() { return Args.rbegin(); }
+  reverse_iterator rend() { return Args.rend(); }
+
+  const_iterator begin() const { return Args.begin(); }
+  const_iterator end() const { return Args.end(); }
+
+  const_reverse_iterator rbegin() const { return Args.rbegin(); }
+  const_reverse_iterator rend() const { return Args.rend(); }
+
+  arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+                              OptSpecifier Id2 = 0U) const {
+    return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+  }
+  arg_iterator filtered_end() const {
+    return arg_iterator(Args.end(), *this);
+  }
+
+  iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U,
+                                        OptSpecifier Id1 = 0U,
+                                        OptSpecifier Id2 = 0U) const {
+    return make_range(filtered_begin(Id0, Id1, Id2), filtered_end());
+  }
+
+  /// @}
+  /// @name Arg Removal
+  /// @{
+
+  /// eraseArg - Remove any option matching \p Id.
+  void eraseArg(OptSpecifier Id);
+
+  /// @}
+  /// @name Arg Access
+  /// @{
+
+  /// hasArg - Does the arg list contain any option matching \p Id.
+  ///
+  /// \p Claim Whether the argument should be claimed, if it exists.
+  bool hasArgNoClaim(OptSpecifier Id) const {
+    return getLastArgNoClaim(Id) != nullptr;
+  }
+  bool hasArg(OptSpecifier Id) const {
+    return getLastArg(Id) != nullptr;
+  }
+  bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
+    return getLastArg(Id0, Id1) != nullptr;
+  }
+  bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
+    return getLastArg(Id0, Id1, Id2) != nullptr;
+  }
+
+  /// getLastArg - Return the last argument matching \p Id, or null.
+  ///
+  /// \p Claim Whether the argument should be claimed, if it exists.
+  Arg *getLastArgNoClaim(OptSpecifier Id) const;
+  Arg *getLastArg(OptSpecifier Id) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                  OptSpecifier Id3) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                  OptSpecifier Id3, OptSpecifier Id4) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                  OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                  OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
+                  OptSpecifier Id6) const;
+  Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+                  OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
+                  OptSpecifier Id6, OptSpecifier Id7) const;
+
+  /// getArgString - Return the input argument string at \p Index.
+  virtual const char *getArgString(unsigned Index) const = 0;
+
+  /// getNumInputArgStrings - Return the number of original argument strings,
+  /// which are guaranteed to be the first strings in the argument string
+  /// list.
+  virtual unsigned getNumInputArgStrings() const = 0;
+
+  /// @}
+  /// @name Argument Lookup Utilities
+  /// @{
+
+  /// getLastArgValue - Return the value of the last argument, or a default.
+  StringRef getLastArgValue(OptSpecifier Id,
+                                  StringRef Default = "") const;
+
+  /// getAllArgValues - Get the values of all instances of the given argument
+  /// as strings.
+  std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
+
+  /// @}
+  /// @name Translation Utilities
+  /// @{
+
+  /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
+  /// true if the option is present, false if the negation is present, and
+  /// \p Default if neither option is given. If both the option and its
+  /// negation are present, the last one wins.
+  bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
+
+  /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
+  /// form \p Neg, return true if the option or its alias is present, false if
+  /// the negation is present, and \p Default if none of the options are
+  /// given. If multiple options are present, the last one wins.
+  bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
+               bool Default = true) const;
+
+  /// AddLastArg - Render only the last argument match \p Id0, if present.
+  void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
+  void AddLastArg(ArgStringList &Output, OptSpecifier Id0,
+                  OptSpecifier Id1) const;
+
+  /// AddAllArgs - Render all arguments matching the given ids.
+  void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+                  OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+  /// AddAllArgValues - Render the argument values of all arguments
+  /// matching the given ids.
+  void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+                        OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
+
+  /// AddAllArgsTranslated - Render all the arguments matching the
+  /// given ids, but forced to separate args and using the provided
+  /// name instead of the first option value.
+  ///
+  /// \param Joined - If true, render the argument as joined with
+  /// the option specifier.
+  void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
+                            const char *Translation,
+                            bool Joined = false) const;
+
+  /// ClaimAllArgs - Claim all arguments which match the given
+  /// option id.
+  void ClaimAllArgs(OptSpecifier Id0) const;
+
+  /// ClaimAllArgs - Claim all arguments.
+  ///
+  void ClaimAllArgs() const;
+
+  /// @}
+  /// @name Arg Synthesis
+  /// @{
+
+  /// MakeArgString - Construct a constant string pointer whose
+  /// lifetime will match that of the ArgList.
+  virtual const char *MakeArgString(StringRef Str) const = 0;
+  const char *MakeArgString(const char *Str) const {
+    return MakeArgString(StringRef(Str));
+  }
+  const char *MakeArgString(std::string Str) const {
+    return MakeArgString(StringRef(Str));
+  }
+  const char *MakeArgString(const Twine &Str) const;
+
+  /// \brief Create an arg string for (\p LHS + \p RHS), reusing the
+  /// string at \p Index if possible.
+  const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
+                                        StringRef RHS) const;
+
+  /// @}
+};
+
+class InputArgList : public ArgList  {
+private:
+  /// List of argument strings used by the contained Args.
+  ///
+  /// This is mutable since we treat the ArgList as being the list
+  /// of Args, and allow routines to add new strings (to have a
+  /// convenient place to store the memory) via MakeIndex.
+  mutable ArgStringList ArgStrings;
+
+  /// Strings for synthesized arguments.
+  ///
+  /// This is mutable since we treat the ArgList as being the list
+  /// of Args, and allow routines to add new strings (to have a
+  /// convenient place to store the memory) via MakeIndex.
+  mutable std::list<std::string> SynthesizedStrings;
+
+  /// The number of original input argument strings.
+  unsigned NumInputArgStrings;
+
+public:
+  InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
+  ~InputArgList();
+
+  const char *getArgString(unsigned Index) const override {
+    return ArgStrings[Index];
+  }
+
+  unsigned getNumInputArgStrings() const override {
+    return NumInputArgStrings;
+  }
+
+  /// @name Arg Synthesis
+  /// @{
+
+public:
+  /// MakeIndex - Get an index for the given string(s).
+  unsigned MakeIndex(StringRef String0) const;
+  unsigned MakeIndex(StringRef String0, StringRef String1) const;
+
+  using ArgList::MakeArgString;
+  const char *MakeArgString(StringRef Str) const override;
+
+  /// @}
+};
+
+/// DerivedArgList - An ordered collection of driver arguments,
+/// whose storage may be in another argument list.
+class DerivedArgList : public ArgList {
+  const InputArgList &BaseArgs;
+
+  /// The list of arguments we synthesized.
+  mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs;
+
+public:
+  /// Construct a new derived arg list from \p BaseArgs.
+  DerivedArgList(const InputArgList &BaseArgs);
+  ~DerivedArgList();
+
+  const char *getArgString(unsigned Index) const override {
+    return BaseArgs.getArgString(Index);
+  }
+
+  unsigned getNumInputArgStrings() const override {
+    return BaseArgs.getNumInputArgStrings();
+  }
+
+  const InputArgList &getBaseArgs() const {
+    return BaseArgs;
+  }
+
+  /// @name Arg Synthesis
+  /// @{
+
+  /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
+  /// (to be freed).
+  void AddSynthesizedArg(Arg *A);
+
+  using ArgList::MakeArgString;
+  const char *MakeArgString(StringRef Str) const override;
+
+  /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
+  /// append it to the argument list.
+  void AddFlagArg(const Arg *BaseArg, const Option Opt) {
+    append(MakeFlagArg(BaseArg, Opt));
+  }
+
+  /// AddPositionalArg - Construct a new Positional arg for the given option
+  /// \p Id, with the provided \p Value and append it to the argument
+  /// list.
+  void AddPositionalArg(const Arg *BaseArg, const Option Opt,
+                        StringRef Value) {
+    append(MakePositionalArg(BaseArg, Opt, Value));
+  }
+
+
+  /// AddSeparateArg - Construct a new Positional arg for the given option
+  /// \p Id, with the provided \p Value and append it to the argument
+  /// list.
+  void AddSeparateArg(const Arg *BaseArg, const Option Opt,
+                      StringRef Value) {
+    append(MakeSeparateArg(BaseArg, Opt, Value));
+  }
+
+
+  /// AddJoinedArg - Construct a new Positional arg for the given option
+  /// \p Id, with the provided \p Value and append it to the argument list.
+  void AddJoinedArg(const Arg *BaseArg, const Option Opt,
+                    StringRef Value) {
+    append(MakeJoinedArg(BaseArg, Opt, Value));
+  }
+
+
+  /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
+  Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
+
+  /// MakePositionalArg - Construct a new Positional arg for the
+  /// given option \p Id, with the provided \p Value.
+  Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
+                          StringRef Value) const;
+
+  /// MakeSeparateArg - Construct a new Positional arg for the
+  /// given option \p Id, with the provided \p Value.
+  Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
+                        StringRef Value) const;
+
+  /// MakeJoinedArg - Construct a new Positional arg for the
+  /// given option \p Id, with the provided \p Value.
+  Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
+                      StringRef Value) const;
+
+  /// @}
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td
new file mode 100644
index 0000000..dbf240d
--- /dev/null
+++ b/include/llvm/Option/OptParser.td
@@ -0,0 +1,132 @@
+//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
+//
+//                     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 common interfaces used by the option parsing TableGen
+//  backend.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the kinds of options.
+
+class OptionKind<string name, int precedence = 0, bit sentinel = 0> {
+  string Name = name;
+  // The kind precedence, kinds with lower precedence are matched first.
+  int Precedence = precedence;
+  // Indicate a sentinel option.
+  bit Sentinel = sentinel;
+}
+
+// An option group.
+def KIND_GROUP : OptionKind<"Group">;
+// The input option kind.
+def KIND_INPUT : OptionKind<"Input", 1, 1>;
+// The unknown option kind.
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
+// A flag with no values.
+def KIND_FLAG : OptionKind<"Flag">;
+// An option which prefixes its (single) value.
+def KIND_JOINED : OptionKind<"Joined", 1>;
+// An option which is followed by its value.
+def KIND_SEPARATE : OptionKind<"Separate">;
+// An option followed by its values, which are separated by commas.
+def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
+// An option which is which takes multiple (separate) arguments.
+def KIND_MULTIARG : OptionKind<"MultiArg">;
+// An option which is either joined to its (non-empty) value, or followed by its
+// value.
+def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
+// An option which is both joined to its (first) value, and followed by its
+// (second) value.
+def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+// An option which consumes all remaining arguments if there are any.
+def KIND_REMAINING_ARGS : OptionKind<"RemainingArgs">;
+
+// Define the option flags.
+
+class OptionFlag {}
+
+// HelpHidden - The option should not be displayed in --help, even if it has
+// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp
+// arguments to implement hidden help groups.
+def HelpHidden : OptionFlag;
+
+// RenderAsInput - The option should not render the name when rendered as an
+// input (i.e., the option is rendered as values).
+def RenderAsInput : OptionFlag;
+
+// RenderJoined - The option should be rendered joined, even if separate (only
+// sensible on single value separate options).
+def RenderJoined : OptionFlag;
+
+// RenderSeparate - The option should be rendered separately, even if joined
+// (only sensible on joined options).
+def RenderSeparate : OptionFlag;
+
+// Define the option group class.
+
+class OptionGroup<string name> {
+  string EnumName = ?; // Uses the def name if undefined.
+  string Name = name;
+  string HelpText = ?;
+  OptionGroup Group = ?;
+  list<OptionFlag> Flags = [];
+}
+
+// Define the option class.
+
+class Option<list<string> prefixes, string name, OptionKind kind> {
+  string EnumName = ?; // Uses the def name if undefined.
+  list<string> Prefixes = prefixes;
+  string Name = name;
+  OptionKind Kind = kind;
+  // Used by MultiArg option kind.
+  int NumArgs = 0;
+  string HelpText = ?;
+  string MetaVarName = ?;
+  list<OptionFlag> Flags = [];
+  OptionGroup Group = ?;
+  Option Alias = ?;
+  list<string> AliasArgs = [];
+}
+
+// Helpers for defining options.
+
+class Flag<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_FLAG>;
+class Joined<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_JOINED>;
+class Separate<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_SEPARATE>;
+class CommaJoined<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_COMMAJOINED>;
+class MultiArg<list<string> prefixes, string name, int numargs>
+  : Option<prefixes, name, KIND_MULTIARG> {
+  int NumArgs = numargs;
+}
+class JoinedOrSeparate<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_JOINED_OR_SEPARATE>;
+class JoinedAndSeparate<list<string> prefixes, string name>
+  : Option<prefixes, name, KIND_JOINED_AND_SEPARATE>;
+
+// Mix-ins for adding optional attributes.
+
+class Alias<Option alias> { Option Alias = alias; }
+class AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
+class EnumName<string name> { string EnumName = name; }
+class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
+class Group<OptionGroup group> { OptionGroup Group = group; }
+class HelpText<string text> { string HelpText = text; }
+class MetaVarName<string name> { string MetaVarName = name; }
+
+// Predefined options.
+
+// FIXME: Have generator validate that these appear in correct position (and
+// aren't duplicated).
+def INPUT : Option<[], "<input>", KIND_INPUT>;
+def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>;
diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h
new file mode 100644
index 0000000..b7caa6e
--- /dev/null
+++ b/include/llvm/Option/OptSpecifier.h
@@ -0,0 +1,41 @@
+//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPTION_OPTSPECIFIER_H
+#define LLVM_OPTION_OPTSPECIFIER_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+namespace opt {
+  class Option;
+
+  /// OptSpecifier - Wrapper class for abstracting references to option IDs.
+  class OptSpecifier {
+    unsigned ID;
+
+  private:
+    explicit OptSpecifier(bool) LLVM_DELETED_FUNCTION;
+
+  public:
+    OptSpecifier() : ID(0) {}
+    /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+    /*implicit*/ OptSpecifier(const Option *Opt);
+
+    bool isValid() const { return ID != 0; }
+
+    unsigned getID() const { return ID; }
+
+    bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+    bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+  };
+}
+}
+
+#endif
diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h
new file mode 100644
index 0000000..5035940
--- /dev/null
+++ b/include/llvm/Option/OptTable.h
@@ -0,0 +1,179 @@
+//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPTION_OPTTABLE_H
+#define LLVM_OPTION_OPTTABLE_H
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Option/OptSpecifier.h"
+
+namespace llvm {
+class raw_ostream;
+namespace opt {
+class Arg;
+class ArgList;
+class InputArgList;
+class Option;
+
+/// \brief Provide access to the Option info table.
+///
+/// The OptTable class provides a layer of indirection which allows Option
+/// instance to be created lazily. In the common case, only a few options will
+/// be needed at runtime; the OptTable class maintains enough information to
+/// parse command lines without instantiating Options, while letting other
+/// parts of the driver still use Option instances where convenient.
+class OptTable {
+public:
+  /// \brief Entry for a single option instance in the option data table.
+  struct Info {
+    /// A null terminated array of prefix strings to apply to name while
+    /// matching.
+    const char *const *Prefixes;
+    const char *Name;
+    const char *HelpText;
+    const char *MetaVar;
+    unsigned ID;
+    unsigned char Kind;
+    unsigned char Param;
+    unsigned short Flags;
+    unsigned short GroupID;
+    unsigned short AliasID;
+    const char *AliasArgs;
+  };
+
+private:
+  /// \brief The static option information table.
+  const Info *OptionInfos;
+  unsigned NumOptionInfos;
+  bool IgnoreCase;
+
+  unsigned TheInputOptionID;
+  unsigned TheUnknownOptionID;
+
+  /// The index of the first option which can be parsed (i.e., is not a
+  /// special option like 'input' or 'unknown', and is not an option group).
+  unsigned FirstSearchableIndex;
+
+  /// The union of all option prefixes. If an argument does not begin with
+  /// one of these, it is an input.
+  StringSet<> PrefixesUnion;
+  std::string PrefixChars;
+
+private:
+  const Info &getInfo(OptSpecifier Opt) const {
+    unsigned id = Opt.getID();
+    assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
+    return OptionInfos[id - 1];
+  }
+
+protected:
+  OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos,
+           bool _IgnoreCase = false);
+public:
+  ~OptTable();
+
+  /// \brief Return the total number of option classes.
+  unsigned getNumOptions() const { return NumOptionInfos; }
+
+  /// \brief Get the given Opt's Option instance, lazily creating it
+  /// if necessary.
+  ///
+  /// \return The option, or null for the INVALID option id.
+  const Option getOption(OptSpecifier Opt) const;
+
+  /// \brief Lookup the name of the given option.
+  const char *getOptionName(OptSpecifier id) const {
+    return getInfo(id).Name;
+  }
+
+  /// \brief Get the kind of the given option.
+  unsigned getOptionKind(OptSpecifier id) const {
+    return getInfo(id).Kind;
+  }
+
+  /// \brief Get the group id for the given option.
+  unsigned getOptionGroupID(OptSpecifier id) const {
+    return getInfo(id).GroupID;
+  }
+
+  /// \brief Get the help text to use to describe this option.
+  const char *getOptionHelpText(OptSpecifier id) const {
+    return getInfo(id).HelpText;
+  }
+
+  /// \brief Get the meta-variable name to use when describing
+  /// this options values in the help text.
+  const char *getOptionMetaVar(OptSpecifier id) const {
+    return getInfo(id).MetaVar;
+  }
+
+  /// \brief Parse a single argument; returning the new argument and
+  /// updating Index.
+  ///
+  /// \param [in,out] Index - The current parsing position in the argument
+  /// string list; on return this will be the index of the next argument
+  /// string to parse.
+  /// \param [in] FlagsToInclude - Only parse options with any of these flags.
+  /// Zero is the default which includes all flags.
+  /// \param [in] FlagsToExclude - Don't parse options with this flag.  Zero
+  /// is the default and means exclude nothing.
+  ///
+  /// \return The parsed argument, or 0 if the argument is missing values
+  /// (in which case Index still points at the conceptual next argument string
+  /// to parse).
+  Arg *ParseOneArg(const ArgList &Args, unsigned &Index,
+                   unsigned FlagsToInclude = 0,
+                   unsigned FlagsToExclude = 0) const;
+
+  /// \brief Parse an list of arguments into an InputArgList.
+  ///
+  /// The resulting InputArgList will reference the strings in [\p ArgBegin,
+  /// \p ArgEnd), and their lifetime should extend past that of the returned
+  /// InputArgList.
+  ///
+  /// The only error that can occur in this routine is if an argument is
+  /// missing values; in this case \p MissingArgCount will be non-zero.
+  ///
+  /// \param ArgBegin - The beginning of the argument vector.
+  /// \param ArgEnd - The end of the argument vector.
+  /// \param MissingArgIndex - On error, the index of the option which could
+  /// not be parsed.
+  /// \param MissingArgCount - On error, the number of missing options.
+  /// \param FlagsToInclude - Only parse options with any of these flags.
+  /// Zero is the default which includes all flags.
+  /// \param FlagsToExclude - Don't parse options with this flag.  Zero
+  /// is the default and means exclude nothing.
+  /// \return An InputArgList; on error this will contain all the options
+  /// which could be parsed.
+  InputArgList *ParseArgs(const char* const *ArgBegin,
+                          const char* const *ArgEnd,
+                          unsigned &MissingArgIndex,
+                          unsigned &MissingArgCount,
+                          unsigned FlagsToInclude = 0,
+                          unsigned FlagsToExclude = 0) const;
+
+  /// \brief Render the help text for an option table.
+  ///
+  /// \param OS - The stream to write the help text to.
+  /// \param Name - The name to use in the usage line.
+  /// \param Title - The title to use in the usage line.
+  /// \param FlagsToInclude - If non-zero, only include options with any
+  ///                         of these flags set.
+  /// \param FlagsToExclude - Exclude options with any of these flags set.
+  void PrintHelp(raw_ostream &OS, const char *Name,
+                 const char *Title, unsigned FlagsToInclude,
+                 unsigned FlagsToExclude) const;
+
+  void PrintHelp(raw_ostream &OS, const char *Name,
+                  const char *Title, bool ShowHidden = false) const;
+};
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h
new file mode 100644
index 0000000..b2cfacb
--- /dev/null
+++ b/include/llvm/Option/Option.h
@@ -0,0 +1,205 @@
+//===--- Option.h - Abstract Driver Options ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPTION_OPTION_H
+#define LLVM_OPTION_OPTION_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+namespace opt {
+class Arg;
+class ArgList;
+/// ArgStringList - Type used for constructing argv lists for subprocesses.
+typedef SmallVector<const char*, 16> ArgStringList;
+
+/// Base flags for all options. Custom flags may be added after.
+enum DriverFlag {
+  HelpHidden       = (1 << 0),
+  RenderAsInput    = (1 << 1),
+  RenderJoined     = (1 << 2),
+  RenderSeparate   = (1 << 3)
+};
+
+/// Option - Abstract representation for a single form of driver
+/// argument.
+///
+/// An Option class represents a form of option that the driver
+/// takes, for example how many arguments the option has and how
+/// they can be provided. Individual option instances store
+/// additional information about what group the option is a member
+/// of (if any), if the option is an alias, and a number of
+/// flags. At runtime the driver parses the command line into
+/// concrete Arg instances, each of which corresponds to a
+/// particular Option instance.
+class Option {
+public:
+  enum OptionClass {
+    GroupClass = 0,
+    InputClass,
+    UnknownClass,
+    FlagClass,
+    JoinedClass,
+    SeparateClass,
+    RemainingArgsClass,
+    CommaJoinedClass,
+    MultiArgClass,
+    JoinedOrSeparateClass,
+    JoinedAndSeparateClass
+  };
+
+  enum RenderStyleKind {
+    RenderCommaJoinedStyle,
+    RenderJoinedStyle,
+    RenderSeparateStyle,
+    RenderValuesStyle
+  };
+
+protected:
+  const OptTable::Info *Info;
+  const OptTable *Owner;
+
+public:
+  Option(const OptTable::Info *Info, const OptTable *Owner);
+  ~Option();
+
+  bool isValid() const {
+    return Info != nullptr;
+  }
+
+  unsigned getID() const {
+    assert(Info && "Must have a valid info!");
+    return Info->ID;
+  }
+
+  OptionClass getKind() const {
+    assert(Info && "Must have a valid info!");
+    return OptionClass(Info->Kind);
+  }
+
+  /// \brief Get the name of this option without any prefix.
+  StringRef getName() const {
+    assert(Info && "Must have a valid info!");
+    return Info->Name;
+  }
+
+  const Option getGroup() const {
+    assert(Info && "Must have a valid info!");
+    assert(Owner && "Must have a valid owner!");
+    return Owner->getOption(Info->GroupID);
+  }
+
+  const Option getAlias() const {
+    assert(Info && "Must have a valid info!");
+    assert(Owner && "Must have a valid owner!");
+    return Owner->getOption(Info->AliasID);
+  }
+
+  /// \brief Get the alias arguments as a \0 separated list.
+  /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
+  const char *getAliasArgs() const {
+    assert(Info && "Must have a valid info!");
+    assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
+           "AliasArgs should be either 0 or non-empty.");
+
+    return Info->AliasArgs;
+  }
+
+  /// \brief Get the default prefix for this option.
+  StringRef getPrefix() const {
+    const char *Prefix = *Info->Prefixes;
+    return Prefix ? Prefix : StringRef();
+  }
+
+  /// \brief Get the name of this option with the default prefix.
+  std::string getPrefixedName() const {
+    std::string Ret = getPrefix();
+    Ret += getName();
+    return Ret;
+  }
+
+  unsigned getNumArgs() const { return Info->Param; }
+
+  bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
+
+  RenderStyleKind getRenderStyle() const {
+    if (Info->Flags & RenderJoined)
+      return RenderJoinedStyle;
+    if (Info->Flags & RenderSeparate)
+      return RenderSeparateStyle;
+    switch (getKind()) {
+    case GroupClass:
+    case InputClass:
+    case UnknownClass:
+      return RenderValuesStyle;
+    case JoinedClass:
+    case JoinedAndSeparateClass:
+      return RenderJoinedStyle;
+    case CommaJoinedClass:
+      return RenderCommaJoinedStyle;
+    case FlagClass:
+    case SeparateClass:
+    case MultiArgClass:
+    case JoinedOrSeparateClass:
+    case RemainingArgsClass:
+      return RenderSeparateStyle;
+    }
+    llvm_unreachable("Unexpected kind!");
+  }
+
+  /// Test if this option has the flag \a Val.
+  bool hasFlag(unsigned Val) const {
+    return Info->Flags & Val;
+  }
+
+  /// getUnaliasedOption - Return the final option this option
+  /// aliases (itself, if the option has no alias).
+  const Option getUnaliasedOption() const {
+    const Option Alias = getAlias();
+    if (Alias.isValid()) return Alias.getUnaliasedOption();
+    return *this;
+  }
+
+  /// getRenderName - Return the name to use when rendering this
+  /// option.
+  StringRef getRenderName() const {
+    return getUnaliasedOption().getName();
+  }
+
+  /// matches - Predicate for whether this option is part of the
+  /// given option (which may be a group).
+  ///
+  /// Note that matches against options which are an alias should never be
+  /// done -- aliases do not participate in matching and so such a query will
+  /// always be false.
+  bool matches(OptSpecifier ID) const;
+
+  /// accept - Potentially accept the current argument, returning a
+  /// new Arg instance, or 0 if the option does not accept this
+  /// argument (or the argument is missing values).
+  ///
+  /// If the option accepts the current argument, accept() sets
+  /// Index to the position where argument parsing should resume
+  /// (even if the argument is missing values).
+  ///
+  /// \param ArgSize The number of bytes taken up by the matched Option prefix
+  ///                and name. This is used to determine where joined values
+  ///                start.
+  Arg *accept(const ArgList &Args, unsigned &Index, unsigned ArgSize) const;
+
+  void dump() const;
+};
+
+} // end namespace opt
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
new file mode 100644
index 0000000..c2b9f95
--- /dev/null
+++ b/include/llvm/Pass.h
@@ -0,0 +1,380 @@
+//===- llvm/Pass.h - Base class for Passes ----------------------*- 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 base class that indicates that a specified class is a
+// transformation pass implementation.
+//
+// Passes are designed this way so that it is possible to run passes in a cache
+// and organizationally optimal order without having to specify it at the front
+// end.  This allows arbitrary passes to be strung together and have them
+// executed as efficiently as possible.
+//
+// Passes should extend one of the classes below, depending on the guarantees
+// that it can make about what will be modified as it is run.  For example, most
+// global optimizations should derive from FunctionPass, because they do not add
+// or delete functions, they operate on the internals of the function.
+//
+// Note that this file #includes PassSupport.h and PassAnalysisSupport.h (at the
+// bottom), so the APIs exposed by these files are also automatically available
+// to all users of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_H
+#define LLVM_PASS_H
+
+#include "llvm/Support/Compiler.h"
+#include <string>
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Module;
+class AnalysisUsage;
+class PassInfo;
+class ImmutablePass;
+class PMStack;
+class AnalysisResolver;
+class PMDataManager;
+class raw_ostream;
+class StringRef;
+
+// AnalysisID - Use the PassInfo to identify a pass...
+typedef const void* AnalysisID;
+
+/// Different types of internal pass managers. External pass managers
+/// (PassManager and FunctionPassManager) are not represented here.
+/// Ordering of pass manager types is important here.
+enum PassManagerType {
+  PMT_Unknown = 0,
+  PMT_ModulePassManager = 1, ///< MPPassManager
+  PMT_CallGraphPassManager,  ///< CGPassManager
+  PMT_FunctionPassManager,   ///< FPPassManager
+  PMT_LoopPassManager,       ///< LPPassManager
+  PMT_RegionPassManager,     ///< RGPassManager
+  PMT_BasicBlockPassManager, ///< BBPassManager
+  PMT_Last
+};
+
+// Different types of passes.
+enum PassKind {
+  PT_BasicBlock,
+  PT_Region,
+  PT_Loop,
+  PT_Function,
+  PT_CallGraphSCC,
+  PT_Module,
+  PT_PassManager
+};
+
+//===----------------------------------------------------------------------===//
+/// Pass interface - Implemented by all 'passes'.  Subclass this if you are an
+/// interprocedural optimization or you do not fit into any of the more
+/// constrained passes described below.
+///
+class Pass {
+  AnalysisResolver *Resolver;  // Used to resolve analysis
+  const void *PassID;
+  PassKind Kind;
+  void operator=(const Pass&) LLVM_DELETED_FUNCTION;
+  Pass(const Pass &) LLVM_DELETED_FUNCTION;
+
+public:
+  explicit Pass(PassKind K, char &pid)
+    : Resolver(nullptr), PassID(&pid), Kind(K) { }
+  virtual ~Pass();
+
+
+  PassKind getPassKind() const { return Kind; }
+
+  /// getPassName - Return a nice clean name for a pass.  This usually
+  /// implemented in terms of the name that is registered by one of the
+  /// Registration templates, but can be overloaded directly.
+  ///
+  virtual const char *getPassName() const;
+
+  /// getPassID - Return the PassID number that corresponds to this pass.
+  AnalysisID getPassID() const {
+    return PassID;
+  }
+
+  /// doInitialization - Virtual method overridden by subclasses to do
+  /// any necessary initialization before any pass is run.
+  ///
+  virtual bool doInitialization(Module &)  { return false; }
+
+  /// doFinalization - Virtual method overriden by subclasses to do any
+  /// necessary clean up after all passes have run.
+  ///
+  virtual bool doFinalization(Module &) { return false; }
+
+  /// print - Print out the internal state of the pass.  This is called by
+  /// Analyze to print out the contents of an analysis.  Otherwise it is not
+  /// necessary to implement this method.  Beware that the module pointer MAY be
+  /// null.  This automatically forwards to a virtual function that does not
+  /// provide the Module* in case the analysis doesn't need it it can just be
+  /// ignored.
+  ///
+  virtual void print(raw_ostream &O, const Module *M) const;
+  void dump() const; // dump - Print to stderr.
+
+  /// createPrinterPass - Get a Pass appropriate to print the IR this
+  /// pass operates on (Module, Function or MachineFunction).
+  virtual Pass *createPrinterPass(raw_ostream &O,
+                                  const std::string &Banner) const = 0;
+
+  /// Each pass is responsible for assigning a pass manager to itself.
+  /// PMS is the stack of available pass manager.
+  virtual void assignPassManager(PMStack &,
+                                 PassManagerType) {}
+  /// Check if available pass managers are suitable for this pass or not.
+  virtual void preparePassManager(PMStack &);
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  virtual PassManagerType getPotentialPassManagerType() const;
+
+  // Access AnalysisResolver
+  void setResolver(AnalysisResolver *AR);
+  AnalysisResolver *getResolver() const { return Resolver; }
+
+  /// getAnalysisUsage - This function should be overriden by passes that need
+  /// analysis information to do their job.  If a pass specifies that it uses a
+  /// particular analysis result to this function, it can then use the
+  /// getAnalysis<AnalysisType>() function, below.
+  ///
+  virtual void getAnalysisUsage(AnalysisUsage &) const;
+
+  /// releaseMemory() - This member can be implemented by a pass if it wants to
+  /// be able to release its memory when it is no longer needed.  The default
+  /// behavior of passes is to hold onto memory for the entire duration of their
+  /// lifetime (which is the entire compile time).  For pipelined passes, this
+  /// is not a big deal because that memory gets recycled every time the pass is
+  /// invoked on another program unit.  For IP passes, it is more important to
+  /// free memory when it is unused.
+  ///
+  /// Optionally implement this function to release pass memory when it is no
+  /// longer used.
+  ///
+  virtual void releaseMemory();
+
+  /// getAdjustedAnalysisPointer - This method is used when a pass implements
+  /// an analysis interface through multiple inheritance.  If needed, it should
+  /// override this to adjust the this pointer as needed for the specified pass
+  /// info.
+  virtual void *getAdjustedAnalysisPointer(AnalysisID ID);
+  virtual ImmutablePass *getAsImmutablePass();
+  virtual PMDataManager *getAsPMDataManager();
+
+  /// verifyAnalysis() - This member can be implemented by a analysis pass to
+  /// check state of analysis information.
+  virtual void verifyAnalysis() const;
+
+  // dumpPassStructure - Implement the -debug-passes=PassStructure option
+  virtual void dumpPassStructure(unsigned Offset = 0);
+
+  // lookupPassInfo - Return the pass info object for the specified pass class,
+  // or null if it is not known.
+  static const PassInfo *lookupPassInfo(const void *TI);
+
+  // lookupPassInfo - Return the pass info object for the pass with the given
+  // argument string, or null if it is not known.
+  static const PassInfo *lookupPassInfo(StringRef Arg);
+
+  // createPass - Create a object for the specified pass class,
+  // or null if it is not known.
+  static Pass *createPass(AnalysisID ID);
+
+  /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+  /// get analysis information that might be around, for example to update it.
+  /// This is different than getAnalysis in that it can fail (if the analysis
+  /// results haven't been computed), so should only be used if you can handle
+  /// the case when the analysis is not available.  This method is often used by
+  /// transformation APIs to update analysis results for a pass automatically as
+  /// the transform is performed.
+  ///
+  template<typename AnalysisType> AnalysisType *
+    getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
+
+  /// mustPreserveAnalysisID - This method serves the same function as
+  /// getAnalysisIfAvailable, but works if you just have an AnalysisID.  This
+  /// obviously cannot give you a properly typed instance of the class if you
+  /// don't have the class name available (use getAnalysisIfAvailable if you
+  /// do), but it can tell you if you need to preserve the pass at least.
+  ///
+  bool mustPreserveAnalysisID(char &AID) const;
+
+  /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+  /// to the analysis information that they claim to use by overriding the
+  /// getAnalysisUsage function.
+  ///
+  template<typename AnalysisType>
+  AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
+
+  template<typename AnalysisType>
+  AnalysisType &getAnalysis(Function &F); // Defined in PassAnalysisSupport.h
+
+  template<typename AnalysisType>
+  AnalysisType &getAnalysisID(AnalysisID PI) const;
+
+  template<typename AnalysisType>
+  AnalysisType &getAnalysisID(AnalysisID PI, Function &F);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ModulePass class - This class is used to implement unstructured
+/// interprocedural optimizations and analyses.  ModulePasses may do anything
+/// they want to the program.
+///
+class ModulePass : public Pass {
+public:
+  /// createPrinterPass - Get a module printer pass.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  /// runOnModule - Virtual method overriden by subclasses to process the module
+  /// being operated on.
+  virtual bool runOnModule(Module &M) = 0;
+
+  void assignPassManager(PMStack &PMS, PassManagerType T) override;
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  PassManagerType getPotentialPassManagerType() const override;
+
+  explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
+  // Force out-of-line virtual method.
+  virtual ~ModulePass();
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ImmutablePass class - This class is used to provide information that does
+/// not need to be run.  This is useful for things like target information and
+/// "basic" versions of AnalysisGroups.
+///
+class ImmutablePass : public ModulePass {
+public:
+  /// initializePass - This method may be overriden by immutable passes to allow
+  /// them to perform various initialization actions they require.  This is
+  /// primarily because an ImmutablePass can "require" another ImmutablePass,
+  /// and if it does, the overloaded version of initializePass may get access to
+  /// these passes with getAnalysis<>.
+  ///
+  virtual void initializePass();
+
+  ImmutablePass *getAsImmutablePass() override { return this; }
+
+  /// ImmutablePasses are never run.
+  ///
+  bool runOnModule(Module &) override { return false; }
+
+  explicit ImmutablePass(char &pid)
+  : ModulePass(pid) {}
+
+  // Force out-of-line virtual method.
+  virtual ~ImmutablePass();
+};
+
+//===----------------------------------------------------------------------===//
+/// FunctionPass class - This class is used to implement most global
+/// optimizations.  Optimizations should subclass this class if they meet the
+/// following constraints:
+///
+///  1. Optimizations are organized globally, i.e., a function at a time
+///  2. Optimizing a function does not cause the addition or removal of any
+///     functions in the module
+///
+class FunctionPass : public Pass {
+public:
+  explicit FunctionPass(char &pid) : Pass(PT_Function, pid) {}
+
+  /// createPrinterPass - Get a function printer pass.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  /// runOnFunction - Virtual method overriden by subclasses to do the
+  /// per-function processing of the pass.
+  ///
+  virtual bool runOnFunction(Function &F) = 0;
+
+  void assignPassManager(PMStack &PMS, PassManagerType T) override;
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  PassManagerType getPotentialPassManagerType() const override;
+
+protected:
+  /// skipOptnoneFunction - This function has Attribute::OptimizeNone
+  /// and most transformation passes should skip it.
+  bool skipOptnoneFunction(const Function &F) const;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+/// BasicBlockPass class - This class is used to implement most local
+/// optimizations.  Optimizations should subclass this class if they
+/// meet the following constraints:
+///   1. Optimizations are local, operating on either a basic block or
+///      instruction at a time.
+///   2. Optimizations do not modify the CFG of the contained function, or any
+///      other basic block in the function.
+///   3. Optimizations conform to all of the constraints of FunctionPasses.
+///
+class BasicBlockPass : public Pass {
+public:
+  explicit BasicBlockPass(char &pid) : Pass(PT_BasicBlock, pid) {}
+
+  /// createPrinterPass - Get a basic block printer pass.
+  Pass *createPrinterPass(raw_ostream &O,
+                          const std::string &Banner) const override;
+
+  using llvm::Pass::doInitialization;
+  using llvm::Pass::doFinalization;
+
+  /// doInitialization - Virtual method overridden by BasicBlockPass subclasses
+  /// to do any necessary per-function initialization.
+  ///
+  virtual bool doInitialization(Function &);
+
+  /// runOnBasicBlock - Virtual method overriden by subclasses to do the
+  /// per-basicblock processing of the pass.
+  ///
+  virtual bool runOnBasicBlock(BasicBlock &BB) = 0;
+
+  /// doFinalization - Virtual method overriden by BasicBlockPass subclasses to
+  /// do any post processing needed after all passes have run.
+  ///
+  virtual bool doFinalization(Function &);
+
+  void assignPassManager(PMStack &PMS, PassManagerType T) override;
+
+  ///  Return what kind of Pass Manager can manage this pass.
+  PassManagerType getPotentialPassManagerType() const override;
+
+protected:
+  /// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
+  /// and most transformation passes should skip it.
+  bool skipOptnoneFunction(const BasicBlock &BB) const;
+};
+
+/// If the user specifies the -time-passes argument on an LLVM tool command line
+/// then the value of this boolean will be true, otherwise false.
+/// @brief This is the storage for the -time-passes option.
+extern bool TimePassesIsEnabled;
+
+} // End llvm namespace
+
+// Include support files that contain important APIs commonly used by Passes,
+// but that we want to separate out to make it easier to read the header files.
+//
+#include "llvm/PassSupport.h"
+#include "llvm/PassAnalysisSupport.h"
+
+#endif
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
new file mode 100644
index 0000000..9164305
--- /dev/null
+++ b/include/llvm/PassAnalysisSupport.h
@@ -0,0 +1,253 @@
+//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- 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 stuff that is used to define and "use" Analysis Passes.
+// This file is automatically #included by Pass.h, so:
+//
+//           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSANALYSISSUPPORT_H
+#define LLVM_PASSANALYSISSUPPORT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Pass.h"
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// AnalysisUsage - Represent the analysis usage information of a pass.  This
+// tracks analyses that the pass REQUIRES (must be available when the pass
+// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the
+// pass), and analyses that the pass PRESERVES (the pass does not invalidate the
+// results of these analyses).  This information is provided by a pass to the
+// Pass infrastructure through the getAnalysisUsage virtual function.
+//
+class AnalysisUsage {
+public:
+  typedef SmallVector<AnalysisID, 32> VectorType;
+
+private:
+  // Sets of analyses required and preserved by a pass
+  VectorType Required, RequiredTransitive, Preserved;
+  bool PreservesAll;
+
+public:
+  AnalysisUsage() : PreservesAll(false) {}
+
+  // addRequired - Add the specified ID to the required set of the usage info
+  // for a pass.
+  //
+  AnalysisUsage &addRequiredID(const void *ID);
+  AnalysisUsage &addRequiredID(char &ID);
+  template<class PassClass>
+  AnalysisUsage &addRequired() {
+    return addRequiredID(PassClass::ID);
+  }
+
+  AnalysisUsage &addRequiredTransitiveID(char &ID);
+  template<class PassClass>
+  AnalysisUsage &addRequiredTransitive() {
+    return addRequiredTransitiveID(PassClass::ID);
+  }
+
+  // addPreserved - Add the specified ID to the set of analyses preserved by
+  // this pass
+  //
+  AnalysisUsage &addPreservedID(const void *ID) {
+    Preserved.push_back(ID);
+    return *this;
+  }
+  AnalysisUsage &addPreservedID(char &ID) {
+    Preserved.push_back(&ID);
+    return *this;
+  }
+
+  // addPreserved - Add the specified Pass class to the set of analyses
+  // preserved by this pass.
+  //
+  template<class PassClass>
+  AnalysisUsage &addPreserved() {
+    Preserved.push_back(&PassClass::ID);
+    return *this;
+  }
+
+  // addPreserved - Add the Pass with the specified argument string to the set
+  // of analyses preserved by this pass. If no such Pass exists, do nothing.
+  // This can be useful when a pass is trivially preserved, but may not be
+  // linked in. Be careful about spelling!
+  //
+  AnalysisUsage &addPreserved(StringRef Arg);
+
+  // setPreservesAll - Set by analyses that do not transform their input at all
+  void setPreservesAll() { PreservesAll = true; }
+  bool getPreservesAll() const { return PreservesAll; }
+
+  /// setPreservesCFG - This function should be called by the pass, iff they do
+  /// not:
+  ///
+  ///  1. Add or remove basic blocks from the function
+  ///  2. Modify terminator instructions in any way.
+  ///
+  /// This function annotates the AnalysisUsage info object to say that analyses
+  /// that only depend on the CFG are preserved by this pass.
+  ///
+  void setPreservesCFG();
+
+  const VectorType &getRequiredSet() const { return Required; }
+  const VectorType &getRequiredTransitiveSet() const {
+    return RequiredTransitive;
+  }
+  const VectorType &getPreservedSet() const { return Preserved; }
+};
+
+//===----------------------------------------------------------------------===//
+// AnalysisResolver - Simple interface used by Pass objects to pull all
+// analysis information out of pass manager that is responsible to manage
+// the pass.
+//
+class PMDataManager;
+class AnalysisResolver {
+private:
+  AnalysisResolver() LLVM_DELETED_FUNCTION;
+
+public:
+  explicit AnalysisResolver(PMDataManager &P) : PM(P) { }
+  
+  inline PMDataManager &getPMDataManager() { return PM; }
+
+  // Find pass that is implementing PI.
+  Pass *findImplPass(AnalysisID PI) {
+    Pass *ResultPass = nullptr;
+    for (unsigned i = 0; i < AnalysisImpls.size() ; ++i) {
+      if (AnalysisImpls[i].first == PI) {
+        ResultPass = AnalysisImpls[i].second;
+        break;
+      }
+    }
+    return ResultPass;
+  }
+
+  // Find pass that is implementing PI. Initialize pass for Function F.
+  Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
+
+  void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
+    if (findImplPass(PI) == P)
+      return;
+    std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
+    AnalysisImpls.push_back(pir);
+  }
+
+  /// clearAnalysisImpls - Clear cache that is used to connect a pass to the
+  /// the analysis (PassInfo).
+  void clearAnalysisImpls() {
+    AnalysisImpls.clear();
+  }
+
+  // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist
+  Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
+
+private:
+  // AnalysisImpls - This keeps track of which passes implements the interfaces
+  // that are required by the current pass (to implement getAnalysis()).
+  std::vector<std::pair<AnalysisID, Pass*> > AnalysisImpls;
+
+  // PassManager that is used to resolve analysis info
+  PMDataManager &PM;
+};
+
+/// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+/// get analysis information that might be around, for example to update it.
+/// This is different than getAnalysis in that it can fail (if the analysis
+/// results haven't been computed), so should only be used if you can handle
+/// the case when the analysis is not available.  This method is often used by
+/// transformation APIs to update analysis results for a pass automatically as
+/// the transform is performed.
+///
+template<typename AnalysisType>
+AnalysisType *Pass::getAnalysisIfAvailable() const {
+  assert(Resolver && "Pass not resident in a PassManager object!");
+
+  const void *PI = &AnalysisType::ID;
+
+  Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true);
+  if (!ResultPass) return nullptr;
+
+  // Because the AnalysisType may not be a subclass of pass (for
+  // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+  // adjust the return pointer (because the class may multiply inherit, once
+  // from pass, once from AnalysisType).
+  return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis() const {
+  assert(Resolver && "Pass has not been inserted into a PassManager object!");
+  return getAnalysisID<AnalysisType>(&AnalysisType::ID);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
+  assert(PI && "getAnalysis for unregistered pass!");
+  assert(Resolver&&"Pass has not been inserted into a PassManager object!");
+  // PI *must* appear in AnalysisImpls.  Because the number of passes used
+  // should be a small number, we just do a linear search over a (dense)
+  // vector.
+  Pass *ResultPass = Resolver->findImplPass(PI);
+  assert (ResultPass && 
+          "getAnalysis*() called on an analysis that was not "
+          "'required' by pass!");
+
+  // Because the AnalysisType may not be a subclass of pass (for
+  // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+  // adjust the return pointer (because the class may multiply inherit, once
+  // from pass, once from AnalysisType).
+  return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis(Function &F) {
+  assert(Resolver &&"Pass has not been inserted into a PassManager object!");
+
+  return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) {
+  assert(PI && "getAnalysis for unregistered pass!");
+  assert(Resolver && "Pass has not been inserted into a PassManager object!");
+  // PI *must* appear in AnalysisImpls.  Because the number of passes used
+  // should be a small number, we just do a linear search over a (dense)
+  // vector.
+  Pass *ResultPass = Resolver->findImplPass(this, PI, F);
+  assert(ResultPass && "Unable to find requested analysis info");
+  
+  // Because the AnalysisType may not be a subclass of pass (for
+  // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+  // adjust the return pointer (because the class may multiply inherit, once
+  // from pass, once from AnalysisType).
+  return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/PassInfo.h b/include/llvm/PassInfo.h
new file mode 100644
index 0000000..d53daf1
--- /dev/null
+++ b/include/llvm/PassInfo.h
@@ -0,0 +1,147 @@
+//===- llvm/PassInfo.h - Pass Info class ------------------------*- 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 and implements the PassInfo class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_PASSINFO_H
+#define LLVM_PASSINFO_H
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+class Pass;
+class TargetMachine;
+
+//===---------------------------------------------------------------------------
+/// PassInfo class - An instance of this class exists for every pass known by
+/// the system, and can be obtained from a live Pass by calling its
+/// getPassInfo() method.  These objects are set up by the RegisterPass<>
+/// template.
+///
+class PassInfo {
+public:
+  typedef Pass* (*NormalCtor_t)();
+  typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
+
+private:
+  const char      *const PassName;     // Nice name for Pass
+  const char      *const PassArgument; // Command Line argument to run this pass
+  const void *PassID;      
+  const bool IsCFGOnlyPass;            // Pass only looks at the CFG.
+  const bool IsAnalysis;               // True if an analysis pass.
+  const bool IsAnalysisGroup;          // True if an analysis group.
+  std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
+
+  NormalCtor_t NormalCtor;
+  TargetMachineCtor_t TargetMachineCtor;
+
+public:
+  /// PassInfo ctor - Do not call this directly, this should only be invoked
+  /// through RegisterPass.
+  PassInfo(const char *name, const char *arg, const void *pi,
+           NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
+           TargetMachineCtor_t machine = nullptr)
+    : PassName(name), PassArgument(arg), PassID(pi), 
+      IsCFGOnlyPass(isCFGOnly), 
+      IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
+      TargetMachineCtor(machine) {}
+  /// PassInfo ctor - Do not call this directly, this should only be invoked
+  /// through RegisterPass. This version is for use by analysis groups; it
+  /// does not auto-register the pass.
+  PassInfo(const char *name, const void *pi)
+    : PassName(name), PassArgument(""), PassID(pi), 
+      IsCFGOnlyPass(false), 
+      IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(nullptr),
+      TargetMachineCtor(nullptr) {}
+
+  /// getPassName - Return the friendly name for the pass, never returns null
+  ///
+  const char *getPassName() const { return PassName; }
+
+  /// getPassArgument - Return the command line option that may be passed to
+  /// 'opt' that will cause this pass to be run.  This will return null if there
+  /// is no argument.
+  ///
+  const char *getPassArgument() const { return PassArgument; }
+
+  /// getTypeInfo - Return the id object for the pass...
+  /// TODO : Rename
+  const void *getTypeInfo() const { return PassID; }
+
+  /// Return true if this PassID implements the specified ID pointer.
+  bool isPassID(const void *IDPtr) const {
+    return PassID == IDPtr;
+  }
+  
+  /// isAnalysisGroup - Return true if this is an analysis group, not a normal
+  /// pass.
+  ///
+  bool isAnalysisGroup() const { return IsAnalysisGroup; }
+  bool isAnalysis() const { return IsAnalysis; }
+
+  /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
+  /// function.
+  bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
+  
+  /// getNormalCtor - Return a pointer to a function, that when called, creates
+  /// an instance of the pass and returns it.  This pointer may be null if there
+  /// is no default constructor for the pass.
+  ///
+  NormalCtor_t getNormalCtor() const {
+    return NormalCtor;
+  }
+  void setNormalCtor(NormalCtor_t Ctor) {
+    NormalCtor = Ctor;
+  }
+
+  /// getTargetMachineCtor - Return a pointer to a function, that when called
+  /// with a TargetMachine, creates an instance of the pass and returns it.
+  /// This pointer may be null if there is no constructor with a TargetMachine
+  /// for the pass.
+  ///
+  TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
+  void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
+    TargetMachineCtor = Ctor;
+  }
+
+  /// createPass() - Use this method to create an instance of this pass.
+  Pass *createPass() const {
+    assert((!isAnalysisGroup() || NormalCtor) &&
+           "No default implementation found for analysis group!");
+    assert(NormalCtor &&
+           "Cannot call createPass on PassInfo without default ctor!");
+    return NormalCtor();
+  }
+
+  /// addInterfaceImplemented - This method is called when this pass is
+  /// registered as a member of an analysis group with the RegisterAnalysisGroup
+  /// template.
+  ///
+  void addInterfaceImplemented(const PassInfo *ItfPI) {
+    ItfImpl.push_back(ItfPI);
+  }
+
+  /// getInterfacesImplemented - Return a list of all of the analysis group
+  /// interfaces implemented by this pass.
+  ///
+  const std::vector<const PassInfo*> &getInterfacesImplemented() const {
+    return ItfImpl;
+  }
+
+private:
+  void operator=(const PassInfo &) LLVM_DELETED_FUNCTION;
+  PassInfo(const PassInfo &) LLVM_DELETED_FUNCTION;
+};
+
+}
+
+#endif
diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h
new file mode 100644
index 0000000..2a191b3
--- /dev/null
+++ b/include/llvm/PassManager.h
@@ -0,0 +1,39 @@
+//===- llvm/PassManager.h - Container for Passes ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a legacy redirect header for the old PassManager. It is intended to
+// be used by clients that have not been converted to be aware of the new pass
+// management infrastructure being built for LLVM, which is every client
+// initially. Eventually this header (and the legacy management layer) will go
+// away, but we want to minimize changes to out-of-tree users of LLVM in the
+// interim.
+//
+// Note that this header *must not* be included into the same file as the new
+// pass management infrastructure is included. Things will break spectacularly.
+// If you are starting that conversion, you should switch to explicitly
+// including LegacyPassManager.h and using the legacy namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGER_H
+#define LLVM_PASSMANAGER_H
+
+#include "llvm/IR/LegacyPassManager.h"
+
+namespace llvm {
+
+// Pull these into the llvm namespace so that existing code that expects it
+// there can find it.
+using legacy::PassManagerBase;
+using legacy::PassManager;
+using legacy::FunctionPassManager;
+
+}
+
+#endif
diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h
new file mode 100644
index 0000000..1558c51
--- /dev/null
+++ b/include/llvm/PassRegistry.h
@@ -0,0 +1,110 @@
+//===- llvm/PassRegistry.h - Pass Information Registry ----------*- 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 PassRegistry, a class that is used in the initialization
+// and registration of passes.  At application startup, passes are registered
+// with the PassRegistry, which is later provided to the PassManager for 
+// dependency resolution and similar tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSREGISTRY_H
+#define LLVM_PASSREGISTRY_H
+
+#include "llvm-c/Core.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/PassInfo.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/RWMutex.h"
+#include <vector>
+
+namespace llvm {
+
+class PassInfo;
+struct PassRegistrationListener;
+
+/// PassRegistry - This class manages the registration and intitialization of
+/// the pass subsystem as application startup, and assists the PassManager
+/// in resolving pass dependencies.
+/// NOTE: PassRegistry is NOT thread-safe.  If you want to use LLVM on multiple
+/// threads simultaneously, you will need to use a separate PassRegistry on
+/// each thread.
+class PassRegistry {
+  mutable sys::SmartRWMutex<true> Lock;
+
+  /// PassInfoMap - Keep track of the PassInfo object for each registered pass.
+  typedef DenseMap<const void*, const PassInfo*> MapType;
+  MapType PassInfoMap;
+  
+  typedef StringMap<const PassInfo*> StringMapType;
+  StringMapType PassInfoStringMap;
+  
+  /// AnalysisGroupInfo - Keep track of information for each analysis group.
+  struct AnalysisGroupInfo {
+    SmallPtrSet<const PassInfo *, 8> Implementations;
+  };
+  DenseMap<const PassInfo*, AnalysisGroupInfo> AnalysisGroupInfoMap;
+  
+  std::vector<std::unique_ptr<const PassInfo>> ToFree;
+  std::vector<PassRegistrationListener*> Listeners;
+   
+public:
+  PassRegistry() { }
+  ~PassRegistry();
+  
+  /// getPassRegistry - Access the global registry object, which is 
+  /// automatically initialized at application launch and destroyed by
+  /// llvm_shutdown.
+  static PassRegistry *getPassRegistry();
+  
+  /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
+  /// type identifier (&MyPass::ID).
+  const PassInfo *getPassInfo(const void *TI) const;
+  
+  /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
+  /// argument string.
+  const PassInfo *getPassInfo(StringRef Arg) const;
+  
+  /// registerPass - Register a pass (by means of its PassInfo) with the 
+  /// registry.  Required in order to use the pass with a PassManager.
+  void registerPass(const PassInfo &PI, bool ShouldFree = false);
+  
+  /// registerPass - Unregister a pass (by means of its PassInfo) with the 
+  /// registry.
+  void unregisterPass(const PassInfo &PI);
+  
+  /// registerAnalysisGroup - Register an analysis group (or a pass implementing
+  // an analysis group) with the registry.  Like registerPass, this is required 
+  // in order for a PassManager to be able to use this group/pass.
+  void registerAnalysisGroup(const void *InterfaceID, const void *PassID,
+                             PassInfo& Registeree, bool isDefault,
+                             bool ShouldFree = false);
+  
+  /// enumerateWith - Enumerate the registered passes, calling the provided
+  /// PassRegistrationListener's passEnumerate() callback on each of them.
+  void enumerateWith(PassRegistrationListener *L);
+  
+  /// addRegistrationListener - Register the given PassRegistrationListener
+  /// to receive passRegistered() callbacks whenever a new pass is registered.
+  void addRegistrationListener(PassRegistrationListener *L);
+  
+  /// removeRegistrationListener - Unregister a PassRegistrationListener so that
+  /// it no longer receives passRegistered() callbacks.
+  void removeRegistrationListener(PassRegistrationListener *L);
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef)
+
+}
+
+#endif
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
new file mode 100644
index 0000000..449bc92
--- /dev/null
+++ b/include/llvm/PassSupport.h
@@ -0,0 +1,241 @@
+//===- llvm/PassSupport.h - Pass Support code -------------------*- 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 stuff that is used to define and "use" Passes.  This file
+// is automatically #included by Pass.h, so:
+//
+//           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h.
+//
+// This file defines Pass registration code and classes used for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSSUPPORT_H
+#define LLVM_PASSSUPPORT_H
+
+#include "Pass.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/PassInfo.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Valgrind.h"
+#include <vector>
+
+namespace llvm {
+
+class TargetMachine;
+
+#define CALL_ONCE_INITIALIZATION(function) \
+  static volatile sys::cas_flag initialized = 0; \
+  sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
+  if (old_val == 0) { \
+    function(Registry); \
+    sys::MemoryFence(); \
+    TsanIgnoreWritesBegin(); \
+    TsanHappensBefore(&initialized); \
+    initialized = 2; \
+    TsanIgnoreWritesEnd(); \
+  } else { \
+    sys::cas_flag tmp = initialized; \
+    sys::MemoryFence(); \
+    while (tmp != 2) { \
+      tmp = initialized; \
+      sys::MemoryFence(); \
+    } \
+  } \
+  TsanHappensAfter(&initialized);
+
+#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
+  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+    Registry.registerPass(*PI, true); \
+    return PI; \
+  } \
+  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+  }
+
+#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
+  static void* initialize##passName##PassOnce(PassRegistry &Registry) {
+
+#define INITIALIZE_PASS_DEPENDENCY(depName) \
+    initialize##depName##Pass(Registry);
+#define INITIALIZE_AG_DEPENDENCY(depName) \
+    initialize##depName##AnalysisGroup(Registry);
+
+#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \
+    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+    Registry.registerPass(*PI, true); \
+    return PI; \
+  } \
+  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+  }
+
+template<typename PassName>
+Pass *callDefaultCtor() { return new PassName(); }
+
+template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) {
+  return new PassName(TM);
+}
+
+//===---------------------------------------------------------------------------
+/// RegisterPass<t> template - This template class is used to notify the system
+/// that a Pass is available for use, and registers it into the internal
+/// database maintained by the PassManager.  Unless this template is used, opt,
+/// for example will not be able to see the pass and attempts to create the pass
+/// will fail. This template is used in the follow manner (at global scope, in
+/// your .cpp file):
+///
+/// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
+///
+/// This statement will cause your pass to be created by calling the default
+/// constructor exposed by the pass.  If you have a different constructor that
+/// must be called, create a global constructor function (which takes the
+/// arguments you need and returns a Pass*) and register your pass like this:
+///
+/// static RegisterPass<PassClassName> tmp("passopt", "My Name");
+///
+template<typename passName>
+struct RegisterPass : public PassInfo {
+
+  // Register Pass using default constructor...
+  RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false,
+               bool is_analysis = false)
+    : PassInfo(Name, PassArg, &passName::ID,
+               PassInfo::NormalCtor_t(callDefaultCtor<passName>),
+               CFGOnly, is_analysis) {
+    PassRegistry::getPassRegistry()->registerPass(*this);
+  }
+};
+
+
+/// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
+/// Analysis groups are used to define an interface (which need not derive from
+/// Pass) that is required by passes to do their job.  Analysis Groups differ
+/// from normal analyses because any available implementation of the group will
+/// be used if it is available.
+///
+/// If no analysis implementing the interface is available, a default
+/// implementation is created and added.  A pass registers itself as the default
+/// implementation by specifying 'true' as the second template argument of this
+/// class.
+///
+/// In addition to registering itself as an analysis group member, a pass must
+/// register itself normally as well.  Passes may be members of multiple groups
+/// and may still be "required" specifically by name.
+///
+/// The actual interface may also be registered as well (by not specifying the
+/// second template argument).  The interface should be registered to associate
+/// a nice name with the interface.
+///
+class RegisterAGBase : public PassInfo {
+public:
+  RegisterAGBase(const char *Name,
+                 const void *InterfaceID,
+                 const void *PassID = nullptr,
+                 bool isDefault = false);
+};
+
+template<typename Interface, bool Default = false>
+struct RegisterAnalysisGroup : public RegisterAGBase {
+  explicit RegisterAnalysisGroup(PassInfo &RPB)
+    : RegisterAGBase(RPB.getPassName(),
+                     &Interface::ID, RPB.getTypeInfo(),
+                     Default) {
+  }
+
+  explicit RegisterAnalysisGroup(const char *Name)
+    : RegisterAGBase(Name, &Interface::ID) {
+  }
+};
+
+#define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \
+  static void* initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \
+    initialize##defaultPass##Pass(Registry); \
+    PassInfo *AI = new PassInfo(name, & agName :: ID); \
+    Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \
+    return AI; \
+  } \
+  void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
+  }
+
+
+#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
+  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+    if (!def) initialize##agName##AnalysisGroup(Registry); \
+    PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+    Registry.registerPass(*PI, true); \
+    \
+    PassInfo *AI = new PassInfo(name, & agName :: ID); \
+    Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
+                                   *AI, def, true); \
+    return AI; \
+  } \
+  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+  }
+
+
+#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
+  static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+    if (!def) initialize##agName##AnalysisGroup(Registry);
+
+#define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \
+    PassInfo *PI = new PassInfo(n, arg, & passName ::ID, \
+      PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+    Registry.registerPass(*PI, true); \
+    \
+    PassInfo *AI = new PassInfo(n, & agName :: ID); \
+    Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
+                                   *AI, def, true); \
+    return AI; \
+  } \
+  void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+    CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+  }
+
+//===---------------------------------------------------------------------------
+/// PassRegistrationListener class - This class is meant to be derived from by
+/// clients that are interested in which passes get registered and unregistered
+/// at runtime (which can be because of the RegisterPass constructors being run
+/// as the program starts up, or may be because a shared object just got
+/// loaded).
+///
+struct PassRegistrationListener {
+
+  PassRegistrationListener() {}
+  virtual ~PassRegistrationListener() {}
+
+  /// Callback functions - These functions are invoked whenever a pass is loaded
+  /// or removed from the current executable.
+  ///
+  virtual void passRegistered(const PassInfo *) {}
+
+  /// enumeratePasses - Iterate over the registered passes, calling the
+  /// passEnumerate callback on each PassInfo object.
+  ///
+  void enumeratePasses();
+
+  /// passEnumerate - Callback function invoked when someone calls
+  /// enumeratePasses on this PassRegistrationListener object.
+  ///
+  virtual void passEnumerate(const PassInfo *) {}
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
new file mode 100644
index 0000000..eafb768
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProf.h
@@ -0,0 +1,51 @@
+//=-- InstrProf.h - Instrumented profiling format support ---------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Instrumentation-based profiling data is generated by instrumented
+// binaries through library functions in compiler-rt, and read by the clang
+// frontend to feed PGO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_H_
+#define LLVM_PROFILEDATA_INSTRPROF_H_
+
+#include <system_error>
+
+namespace llvm {
+const std::error_category &instrprof_category();
+
+enum class instrprof_error {
+    success = 0,
+    eof,
+    bad_magic,
+    bad_header,
+    unsupported_version,
+    unsupported_hash_type,
+    too_large,
+    truncated,
+    malformed,
+    unknown_function,
+    hash_mismatch,
+    count_mismatch,
+    counter_overflow
+};
+
+inline std::error_code make_error_code(instrprof_error E) {
+  return std::error_code(static_cast<int>(E), instrprof_category());
+}
+
+} // end namespace llvm
+
+namespace std {
+template <>
+struct is_error_code_enum<llvm::instrprof_error> : std::true_type {};
+}
+
+#endif // LLVM_PROFILEDATA_INSTRPROF_H_
diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h
new file mode 100644
index 0000000..7a5a71d
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProfReader.h
@@ -0,0 +1,302 @@
+//=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for reading profiling data for instrumentation
+// based PGO and coverage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_READER_H_
+#define LLVM_PROFILEDATA_INSTRPROF_READER_H_
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+
+#include <iterator>
+
+namespace llvm {
+
+class InstrProfReader;
+
+/// Profiling information for a single function.
+struct InstrProfRecord {
+  InstrProfRecord() {}
+  InstrProfRecord(StringRef Name, uint64_t Hash, ArrayRef<uint64_t> Counts)
+      : Name(Name), Hash(Hash), Counts(Counts) {}
+  StringRef Name;
+  uint64_t Hash;
+  ArrayRef<uint64_t> Counts;
+};
+
+/// A file format agnostic iterator over profiling data.
+class InstrProfIterator : public std::iterator<std::input_iterator_tag,
+                                               InstrProfRecord> {
+  InstrProfReader *Reader;
+  InstrProfRecord Record;
+
+  void Increment();
+public:
+  InstrProfIterator() : Reader(nullptr) {}
+  InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
+
+  InstrProfIterator &operator++() { Increment(); return *this; }
+  bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; }
+  bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; }
+  InstrProfRecord &operator*() { return Record; }
+  InstrProfRecord *operator->() { return &Record; }
+};
+
+/// Base class and interface for reading profiling data of any known instrprof
+/// format. Provides an iterator over InstrProfRecords.
+class InstrProfReader {
+  std::error_code LastError;
+
+public:
+  InstrProfReader() : LastError(instrprof_error::success) {}
+  virtual ~InstrProfReader() {}
+
+  /// Read the header.  Required before reading first record.
+  virtual std::error_code readHeader() = 0;
+  /// Read a single record.
+  virtual std::error_code readNextRecord(InstrProfRecord &Record) = 0;
+  /// Iterator over profile data.
+  InstrProfIterator begin() { return InstrProfIterator(this); }
+  InstrProfIterator end() { return InstrProfIterator(); }
+
+protected:
+  /// Set the current std::error_code and return same.
+  std::error_code error(std::error_code EC) {
+    LastError = EC;
+    return EC;
+  }
+
+  /// Clear the current error code and return a successful one.
+  std::error_code success() { return error(instrprof_error::success); }
+
+public:
+  /// Return true if the reader has finished reading the profile data.
+  bool isEOF() { return LastError == instrprof_error::eof; }
+  /// Return true if the reader encountered an error reading profiling data.
+  bool hasError() { return LastError && !isEOF(); }
+  /// Get the current error code.
+  std::error_code getError() { return LastError; }
+
+  /// Factory method to create an appropriately typed reader for the given
+  /// instrprof file.
+  static std::error_code create(std::string Path,
+                                std::unique_ptr<InstrProfReader> &Result);
+};
+
+/// Reader for the simple text based instrprof format.
+///
+/// This format is a simple text format that's suitable for test data. Records
+/// are separated by one or more blank lines, and record fields are separated by
+/// new lines.
+///
+/// Each record consists of a function name, a function hash, a number of
+/// counters, and then each counter value, in that order.
+class TextInstrProfReader : public InstrProfReader {
+private:
+  /// The profile data file contents.
+  std::unique_ptr<MemoryBuffer> DataBuffer;
+  /// Iterator over the profile data.
+  line_iterator Line;
+  /// The current set of counter values.
+  std::vector<uint64_t> Counts;
+
+  TextInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
+  TextInstrProfReader &operator=(const TextInstrProfReader &)
+    LLVM_DELETED_FUNCTION;
+public:
+  TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
+      : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, '#') {}
+
+  /// Read the header.
+  std::error_code readHeader() override { return success(); }
+  /// Read a single record.
+  std::error_code readNextRecord(InstrProfRecord &Record) override;
+};
+
+/// Reader for the raw instrprof binary format from runtime.
+///
+/// This format is a raw memory dump of the instrumentation-baed profiling data
+/// from the runtime.  It has no index.
+///
+/// Templated on the unsigned type whose size matches pointers on the platform
+/// that wrote the profile.
+template <class IntPtrT>
+class RawInstrProfReader : public InstrProfReader {
+private:
+  /// The profile data file contents.
+  std::unique_ptr<MemoryBuffer> DataBuffer;
+  /// The current set of counter values.
+  std::vector<uint64_t> Counts;
+  struct ProfileData {
+    const uint32_t NameSize;
+    const uint32_t NumCounters;
+    const uint64_t FuncHash;
+    const IntPtrT NamePtr;
+    const IntPtrT CounterPtr;
+  };
+  struct RawHeader {
+    const uint64_t Magic;
+    const uint64_t Version;
+    const uint64_t DataSize;
+    const uint64_t CountersSize;
+    const uint64_t NamesSize;
+    const uint64_t CountersDelta;
+    const uint64_t NamesDelta;
+  };
+
+  bool ShouldSwapBytes;
+  uint64_t CountersDelta;
+  uint64_t NamesDelta;
+  const ProfileData *Data;
+  const ProfileData *DataEnd;
+  const uint64_t *CountersStart;
+  const char *NamesStart;
+  const char *ProfileEnd;
+
+  RawInstrProfReader(const RawInstrProfReader &) LLVM_DELETED_FUNCTION;
+  RawInstrProfReader &operator=(const RawInstrProfReader &)
+    LLVM_DELETED_FUNCTION;
+public:
+  RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
+      : DataBuffer(std::move(DataBuffer)) { }
+
+  static bool hasFormat(const MemoryBuffer &DataBuffer);
+  std::error_code readHeader() override;
+  std::error_code readNextRecord(InstrProfRecord &Record) override;
+
+private:
+  std::error_code readNextHeader(const char *CurrentPos);
+  std::error_code readHeader(const RawHeader &Header);
+  template <class IntT>
+  IntT swap(IntT Int) const {
+    return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
+  }
+  const uint64_t *getCounter(IntPtrT CounterPtr) const {
+    ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
+    return CountersStart + Offset;
+  }
+  const char *getName(IntPtrT NamePtr) const {
+    ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
+    return NamesStart + Offset;
+  }
+};
+
+typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;
+typedef RawInstrProfReader<uint64_t> RawInstrProfReader64;
+
+namespace IndexedInstrProf {
+enum class HashT : uint32_t;
+}
+
+/// Trait for lookups into the on-disk hash table for the binary instrprof
+/// format.
+class InstrProfLookupTrait {
+  std::vector<uint64_t> CountBuffer;
+  IndexedInstrProf::HashT HashType;
+public:
+  InstrProfLookupTrait(IndexedInstrProf::HashT HashType) : HashType(HashType) {}
+
+  typedef InstrProfRecord data_type;
+  typedef StringRef internal_key_type;
+  typedef StringRef external_key_type;
+  typedef uint64_t hash_value_type;
+  typedef uint64_t offset_type;
+
+  static bool EqualKey(StringRef A, StringRef B) { return A == B; }
+  static StringRef GetInternalKey(StringRef K) { return K; }
+
+  hash_value_type ComputeHash(StringRef K);
+
+  static std::pair<offset_type, offset_type>
+  ReadKeyDataLength(const unsigned char *&D) {
+    using namespace support;
+    offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D);
+    offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D);
+    return std::make_pair(KeyLen, DataLen);
+  }
+
+  StringRef ReadKey(const unsigned char *D, offset_type N) {
+    return StringRef((const char *)D, N);
+  }
+
+  InstrProfRecord ReadData(StringRef K, const unsigned char *D, offset_type N) {
+    if (N < 2 * sizeof(uint64_t) || N % sizeof(uint64_t)) {
+      // The data is corrupt, don't try to read it.
+      CountBuffer.clear();
+      return InstrProfRecord("", 0, CountBuffer);
+    }
+
+    using namespace support;
+
+    // The first stored value is the hash.
+    uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
+    // Each counter follows.
+    unsigned NumCounters = N / sizeof(uint64_t) - 1;
+    CountBuffer.clear();
+    CountBuffer.reserve(NumCounters - 1);
+    for (unsigned I = 0; I < NumCounters; ++I)
+      CountBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
+
+    return InstrProfRecord(K, Hash, CountBuffer);
+  }
+};
+typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait>
+    InstrProfReaderIndex;
+
+/// Reader for the indexed binary instrprof format.
+class IndexedInstrProfReader : public InstrProfReader {
+private:
+  /// The profile data file contents.
+  std::unique_ptr<MemoryBuffer> DataBuffer;
+  /// The index into the profile data.
+  std::unique_ptr<InstrProfReaderIndex> Index;
+  /// Iterator over the profile data.
+  InstrProfReaderIndex::data_iterator RecordIterator;
+  /// The maximal execution count among all fucntions.
+  uint64_t MaxFunctionCount;
+
+  IndexedInstrProfReader(const IndexedInstrProfReader &) LLVM_DELETED_FUNCTION;
+  IndexedInstrProfReader &operator=(const IndexedInstrProfReader &)
+    LLVM_DELETED_FUNCTION;
+public:
+  IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
+      : DataBuffer(std::move(DataBuffer)), Index(nullptr),
+        RecordIterator(InstrProfReaderIndex::data_iterator()) {}
+
+  /// Return true if the given buffer is in an indexed instrprof format.
+  static bool hasFormat(const MemoryBuffer &DataBuffer);
+
+  /// Read the file header.
+  std::error_code readHeader() override;
+  /// Read a single record.
+  std::error_code readNextRecord(InstrProfRecord &Record) override;
+
+  /// Fill Counts with the profile data for the given function name.
+  std::error_code getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
+                                    std::vector<uint64_t> &Counts);
+  /// Return the maximum of all known function counts.
+  uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
+
+  /// Factory method to create an indexed reader.
+  static std::error_code
+  create(std::string Path, std::unique_ptr<IndexedInstrProfReader> &Result);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_PROFILEDATA_INSTRPROF_READER_H_
diff --git a/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h
new file mode 100644
index 0000000..6e68bee
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProfWriter.h
@@ -0,0 +1,50 @@
+//=-- InstrProfWriter.h - Instrumented profiling writer -----------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing profiling data for instrumentation
+// based PGO and coverage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_WRITER_H_
+#define LLVM_PROFILEDATA_INSTRPROF_WRITER_H_
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+
+namespace llvm {
+
+/// Writer for instrumentation based profile data.
+class InstrProfWriter {
+public:
+  struct CounterData {
+    uint64_t Hash;
+    std::vector<uint64_t> Counts;
+  };
+private:
+  StringMap<CounterData> FunctionData;
+public:
+  /// Add function counts for the given function. If there are already counts
+  /// for this function and the hash and number of counts match, each counter is
+  /// summed.
+  std::error_code addFunctionCounts(StringRef FunctionName,
+                                    uint64_t FunctionHash,
+                                    ArrayRef<uint64_t> Counters);
+  /// Ensure that all data is written to disk.
+  void write(raw_fd_ostream &OS);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_PROFILE_INSTRPROF_WRITER_H_
diff --git a/include/llvm/Support/AIXDataTypesFix.h b/include/llvm/Support/AIXDataTypesFix.h
new file mode 100644
index 0000000..a9a9147
--- /dev/null
+++ b/include/llvm/Support/AIXDataTypesFix.h
@@ -0,0 +1,25 @@
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
new file mode 100644
index 0000000..f63e0a6
--- /dev/null
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -0,0 +1,217 @@
+//===-- ARMBuildAttributes.h - ARM Build Attributes -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains enumerations and support routines for ARM build attributes
+// as defined in ARM ABI addenda document (ABI release 2.08).
+//
+// ELF for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+#define LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+
+namespace llvm {
+class StringRef;
+
+namespace ARMBuildAttrs {
+
+enum SpecialAttr {
+  // This is for the .cpu asm attr. It translates into one or more
+  // AttrType (below) entries in the .ARM.attributes section in the ELF.
+  SEL_CPU
+};
+
+enum AttrType {
+  // Rest correspond to ELF/.ARM.attributes
+  File                      = 1,
+  CPU_raw_name              = 4,
+  CPU_name                  = 5,
+  CPU_arch                  = 6,
+  CPU_arch_profile          = 7,
+  ARM_ISA_use               = 8,
+  THUMB_ISA_use             = 9,
+  FP_arch                   = 10,
+  WMMX_arch                 = 11,
+  Advanced_SIMD_arch        = 12,
+  PCS_config                = 13,
+  ABI_PCS_R9_use            = 14,
+  ABI_PCS_RW_data           = 15,
+  ABI_PCS_RO_data           = 16,
+  ABI_PCS_GOT_use           = 17,
+  ABI_PCS_wchar_t           = 18,
+  ABI_FP_rounding           = 19,
+  ABI_FP_denormal           = 20,
+  ABI_FP_exceptions         = 21,
+  ABI_FP_user_exceptions    = 22,
+  ABI_FP_number_model       = 23,
+  ABI_align_needed          = 24,
+  ABI_align_preserved       = 25,
+  ABI_enum_size             = 26,
+  ABI_HardFP_use            = 27,
+  ABI_VFP_args              = 28,
+  ABI_WMMX_args             = 29,
+  ABI_optimization_goals    = 30,
+  ABI_FP_optimization_goals = 31,
+  compatibility             = 32,
+  CPU_unaligned_access      = 34,
+  FP_HP_extension           = 36,
+  ABI_FP_16bit_format       = 38,
+  MPextension_use           = 42, // recoded from 70 (ABI r2.08)
+  DIV_use                   = 44,
+  also_compatible_with      = 65,
+  conformance               = 67,
+  Virtualization_use        = 68,
+
+  /// Legacy Tags
+  Section                   = 2,  // deprecated (ABI r2.09)
+  Symbol                    = 3,  // deprecated (ABI r2.09)
+  ABI_align8_needed         = 24, // renamed to ABI_align_needed (ABI r2.09)
+  ABI_align8_preserved      = 25, // renamed to ABI_align_preserved (ABI r2.09)
+  nodefaults                = 64, // deprecated (ABI r2.09)
+  T2EE_use                  = 66, // deprecated (ABI r2.09)
+  MPextension_use_old       = 70  // recoded to MPextension_use (ABI r2.08)
+};
+
+StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix = true);
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true);
+int AttrTypeFromString(StringRef Tag);
+
+// Magic numbers for .ARM.attributes
+enum AttrMagic {
+  Format_Version  = 0x41
+};
+
+// Legal Values for CPU_arch, (=6), uleb128
+enum CPUArch {
+  Pre_v4   = 0,
+  v4       = 1,   // e.g. SA110
+  v4T      = 2,   // e.g. ARM7TDMI
+  v5T      = 3,   // e.g. ARM9TDMI
+  v5TE     = 4,   // e.g. ARM946E_S
+  v5TEJ    = 5,   // e.g. ARM926EJ_S
+  v6       = 6,   // e.g. ARM1136J_S
+  v6KZ     = 7,   // e.g. ARM1176JZ_S
+  v6T2     = 8,   // e.g. ARM1156T2F_S
+  v6K      = 9,   // e.g. ARM1136J_S
+  v7       = 10,  // e.g. Cortex A8, Cortex M3
+  v6_M     = 11,  // e.g. Cortex M1
+  v6S_M    = 12,  // v6_M with the System extensions
+  v7E_M    = 13,  // v7_M with DSP extensions
+  v8       = 14   // v8, AArch32
+};
+
+enum CPUArchProfile {               // (=7), uleb128
+  Not_Applicable          = 0,      // pre v7, or cross-profile code
+  ApplicationProfile      = (0x41), // 'A' (e.g. for Cortex A8)
+  RealTimeProfile         = (0x52), // 'R' (e.g. for Cortex R4)
+  MicroControllerProfile  = (0x4D), // 'M' (e.g. for Cortex M3)
+  SystemProfile           = (0x53)  // 'S' Application or real-time profile
+};
+
+// The following have a lot of common use cases
+enum {
+  Not_Allowed = 0,
+  Allowed = 1,
+
+  // Tag_ARM_ISA_use (=8), uleb128
+
+  // Tag_THUMB_ISA_use, (=9), uleb128
+  AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
+
+  // Tag_FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
+  AllowFPv2  = 2,     // v2 FP ISA permitted (implies use of the v1 FP ISA)
+  AllowFPv3A = 3,     // v3 FP ISA permitted (implies use of the v2 FP ISA)
+  AllowFPv3B = 4,     // v3 FP ISA permitted, but only D0-D15, S0-S31
+  AllowFPv4A = 5,     // v4 FP ISA permitted (implies use of v3 FP ISA)
+  AllowFPv4B = 6,     // v4 FP ISA was permitted, but only D0-D15, S0-S31
+  AllowFPARMv8A = 7,  // Use of the ARM v8-A FP ISA was permitted
+  AllowFPARMv8B = 8,  // Use of the ARM v8-A FP ISA was permitted, but only
+                      // D0-D15, S0-S31
+
+  // Tag_WMMX_arch, (=11), uleb128
+  AllowWMMXv1 = 1,  // The user permitted this entity to use WMMX v1
+  AllowWMMXv2 = 2,  // The user permitted this entity to use WMMX v2
+
+  // Tag_Advanced_SIMD_arch, (=12), uleb128
+  AllowNeon = 1,      // SIMDv1 was permitted
+  AllowNeon2 = 2,     // SIMDv2 was permitted (Half-precision FP, MAC operations)
+  AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+
+  // Tag_ABI_PCS_RW_data, (=15), uleb128
+  AddressRWPCRel = 1, // Address RW static data PC-relative
+  AddressRWSBRel = 2, // Address RW static data SB-relative
+  AddressRWNone = 3, // No RW static data permitted
+
+  // Tag_ABI_PCS_RO_data, (=14), uleb128
+  AddressROPCRel = 1, // Address RO static data PC-relative
+  AddressRONone = 2, // No RO static data permitted
+
+  // Tag_ABI_PCS_GOT_use, (=17), uleb128
+  AddressDirect = 1, // Address imported data directly
+  AddressGOT = 2, // Address imported data indirectly (via GOT)
+
+  // Tag_ABI_PCS_wchar_t, (=18), uleb128
+  WCharProhibited = 0,  // wchar_t is not used
+  WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
+  WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4
+
+  // Tag_ABI_FP_denormal, (=20), uleb128
+  PreserveFPSign = 2, // sign when flushed-to-zero is preserved
+
+  // Tag_ABI_FP_number_model, (=23), uleb128
+  AllowRTABI = 2,  // numbers, infinities, and one quiet NaN (see [RTABI])
+  AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+
+  // Tag_ABI_enum_size, (=26), uleb128
+  EnumProhibited = 0, // The user prohibited the use of enums when building
+                      // this entity.
+  EnumSmallest = 1,   // Enum is smallest container big enough to hold all
+                      // values.
+  Enum32Bit = 2,      // Enum is at least 32 bits.
+  Enum32BitABI = 3,   // Every enumeration visible across an ABI-complying
+                      // interface contains a value needing 32 bits to encode
+                      // it; other enums can be containerized.
+
+  // Tag_ABI_HardFP_use, (=27), uleb128
+  HardFPImplied = 0,          // FP use should be implied by Tag_FP_arch
+  HardFPSinglePrecision = 1,  // Single-precision only
+
+  // Tag_ABI_VFP_args, (=28), uleb128
+  BaseAAPCS = 0,
+  HardFPAAPCS = 1,
+
+  // Tag_FP_HP_extension, (=36), uleb128
+  AllowHPFP = 1, // Allow use of Half Precision FP
+
+  // Tag_MPextension_use, (=42), uleb128
+  AllowMP = 1, // Allow use of MP extensions
+
+  // Tag_DIV_use, (=44), uleb128
+  // Note: AllowDIVExt must be emitted if and only if the permission to use
+  // hardware divide cannot be conveyed using AllowDIVIfExists or DisallowDIV
+  AllowDIVIfExists = 0, // Allow hardware divide if available in arch, or no
+                        // info exists.
+  DisallowDIV = 1,      // Hardware divide explicitly disallowed.
+  AllowDIVExt = 2,      // Allow hardware divide as optional architecture
+                        // extension above the base arch specified by
+                        // Tag_CPU_arch and Tag_CPU_arch_profile.
+
+  // Tag_Virtualization_use, (=68), uleb128
+  AllowTZ = 1,
+  AllowVirtualization = 2,
+  AllowTZVirtualization = 3
+};
+
+} // namespace ARMBuildAttrs
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h
new file mode 100644
index 0000000..c7ac54a
--- /dev/null
+++ b/include/llvm/Support/ARMEHABI.h
@@ -0,0 +1,134 @@
+//===--- ARMEHABI.h - ARM Exception Handling ABI ----------------*- 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 constants for the ARM unwind opcodes and exception
+// handling table entry kinds.
+//
+// The enumerations and constants in this file reflect the ARM EHABI
+// Specification as published by ARM.
+//
+// Exception Handling ABI for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_EHABI_H
+#define LLVM_SUPPORT_ARM_EHABI_H
+
+namespace llvm {
+namespace ARM {
+namespace EHABI {
+  /// ARM exception handling table entry kinds
+  enum EHTEntryKind {
+    EHT_GENERIC = 0x00,
+    EHT_COMPACT = 0x80
+  };
+
+  enum {
+    /// Special entry for the function never unwind
+    EXIDX_CANTUNWIND = 0x1
+  };
+
+  /// ARM-defined frame unwinding opcodes
+  enum UnwindOpcodes {
+    // Format: 00xxxxxx
+    // Purpose: vsp = vsp + ((x << 2) + 4)
+    UNWIND_OPCODE_INC_VSP = 0x00,
+
+    // Format: 01xxxxxx
+    // Purpose: vsp = vsp - ((x << 2) + 4)
+    UNWIND_OPCODE_DEC_VSP = 0x40,
+
+    // Format: 10000000 00000000
+    // Purpose: refuse to unwind
+    UNWIND_OPCODE_REFUSE = 0x8000,
+
+    // Format: 1000xxxx xxxxxxxx
+    // Purpose: pop r[15:12], r[11:4]
+    // Constraint: x != 0
+    UNWIND_OPCODE_POP_REG_MASK_R4 = 0x8000,
+
+    // Format: 1001xxxx
+    // Purpose: vsp = r[x]
+    // Constraint: x != 13 && x != 15
+    UNWIND_OPCODE_SET_VSP = 0x90,
+
+    // Format: 10100xxx
+    // Purpose: pop r[(4+x):4]
+    UNWIND_OPCODE_POP_REG_RANGE_R4 = 0xa0,
+
+    // Format: 10101xxx
+    // Purpose: pop r14, r[(4+x):4]
+    UNWIND_OPCODE_POP_REG_RANGE_R4_R14 = 0xa8,
+
+    // Format: 10110000
+    // Purpose: finish
+    UNWIND_OPCODE_FINISH = 0xb0,
+
+    // Format: 10110001 0000xxxx
+    // Purpose: pop r[3:0]
+    // Constraint: x != 0
+    UNWIND_OPCODE_POP_REG_MASK = 0xb100,
+
+    // Format: 10110010 x(uleb128)
+    // Purpose: vsp = vsp + ((x << 2) + 0x204)
+    UNWIND_OPCODE_INC_VSP_ULEB128 = 0xb2,
+
+    // Format: 10110011 xxxxyyyy
+    // Purpose: pop d[(x+y):x]
+    UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX = 0xb300,
+
+    // Format: 10111xxx
+    // Purpose: pop d[(8+x):8]
+    UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX_D8 = 0xb8,
+
+    // Format: 11000xxx
+    // Purpose: pop wR[(10+x):10]
+    UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE_WR10 = 0xc0,
+
+    // Format: 11000110 xxxxyyyy
+    // Purpose: pop wR[(x+y):x]
+    UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE = 0xc600,
+
+    // Format: 11000111 0000xxxx
+    // Purpose: pop wCGR[3:0]
+    // Constraint: x != 0
+    UNWIND_OPCODE_POP_WIRELESS_MMX_REG_MASK = 0xc700,
+
+    // Format: 11001000 xxxxyyyy
+    // Purpose: pop d[(16+x+y):(16+x)]
+    UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 = 0xc800,
+
+    // Format: 11001001 xxxxyyyy
+    // Purpose: pop d[(x+y):x]
+    UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD = 0xc900,
+
+    // Format: 11010xxx
+    // Purpose: pop d[(8+x):8]
+    UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D8 = 0xd0
+  };
+
+  /// ARM-defined Personality Routine Index
+  enum PersonalityRoutineIndex {
+    // To make the exception handling table become more compact, ARM defined
+    // several personality routines in EHABI.  There are 3 different
+    // personality routines in ARM EHABI currently.  It is possible to have 16
+    // pre-defined personality routines at most.
+    AEABI_UNWIND_CPP_PR0 = 0,
+    AEABI_UNWIND_CPP_PR1 = 1,
+    AEABI_UNWIND_CPP_PR2 = 2,
+
+    NUM_PERSONALITY_INDEX
+  };
+}
+}
+}
+
+#endif // ARM_UNWIND_OP_H
diff --git a/include/llvm/Support/ARMWinEH.h b/include/llvm/Support/ARMWinEH.h
new file mode 100644
index 0000000..78deb8d
--- /dev/null
+++ b/include/llvm/Support/ARMWinEH.h
@@ -0,0 +1,384 @@
+//===-- llvm/Support/WinARMEH.h - Windows on ARM EH Constants ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINARMEH_H
+#define LLVM_SUPPORT_WINARMEH_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace ARM {
+namespace WinEH {
+enum class RuntimeFunctionFlag {
+  RFF_Unpacked,       /// unpacked entry
+  RFF_Packed,         /// packed entry
+  RFF_PackedFragment, /// packed entry representing a fragment
+  RFF_Reserved,       /// reserved
+};
+
+enum class ReturnType {
+  RT_POP,             /// return via pop {pc} (L flag must be set)
+  RT_B,               /// 16-bit branch
+  RT_BW,              /// 32-bit branch
+  RT_NoEpilogue,      /// no epilogue (fragment)
+};
+
+/// RuntimeFunction - An entry in the table of procedure data (.pdata)
+///
+///  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+///  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// |                     Function Start RVA                        |
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+/// |    Stack Adjust   |C|L|R| Reg |H|Ret|   Function Length   |Flg|
+/// +-------------------+-+-+-+-----+-+---+---------------------+---+
+///
+/// Flag : 2-bit field with the following meanings:
+///   - 00 = packed unwind data not used; reamining bits point to .xdata record
+///   - 01 = packed unwind data
+///   - 10 = packed unwind data, function assumed to have no prologue; useful
+///          for function fragments that are discontiguous with the start of the
+///          function
+///   - 11 = reserved
+/// Function Length : 11-bit field providing the length of the entire function
+///                   in bytes, divided by 2; if the function is greater than
+///                   4KB, a full .xdata record must be used instead
+/// Ret : 2-bit field indicating how the function returns
+///   - 00 = return via pop {pc} (the L bit must be set)
+///   - 01 = return via 16-bit branch
+///   - 10 = return via 32-bit branch
+///   - 11 = no epilogue; useful for function fragments that may only contain a
+///          prologue but the epilogue is elsewhere
+/// H : 1-bit flag indicating whether the function "homes" the integer parameter
+///     registers (r0-r3), allocating 16-bytes on the stack
+/// Reg : 3-bit field indicating the index of the last saved non-volatile
+///       register.  If the R bit is set to 0, then only integer registers are
+///       saved (r4-rN, where N is 4 + Reg).  If the R bit is set to 1, then
+///       only floating-point registers are being saved (d8-dN, where N is
+///       8 + Reg).  The special case of the R bit being set to 1 and Reg equal
+///       to 7 indicates that no registers are saved.
+/// R : 1-bit flag indicating whether the non-volatile registers are integer or
+///     floating-point.  0 indicates integer, 1 indicates floating-point.  The
+///     special case of the R-flag being set and Reg being set to 7 indicates
+///     that no non-volatile registers are saved.
+/// L : 1-bit flag indicating whether the function saves/restores the link
+///     register (LR)
+/// C : 1-bit flag indicating whether the function includes extra instructions
+///     to setup a frame chain for fast walking.  If this flag is set, r11 is
+///     implicitly added to the list of saved non-volatile integer registers.
+/// Stack Adjust : 10-bit field indicating the number of bytes of stack that are
+///                allocated for this function.  Only values between 0x000 and
+///                0x3f3 can be directly encoded.  If the value is 0x3f4 or
+///                greater, then the low 4 bits have special meaning as follows:
+///                - Bit 0-1
+///                  indicate the number of words' of adjustment (1-4), minus 1
+///                - Bit 2
+///                  indicates if the prologue combined adjustment into push
+///                - Bit 3
+///                  indicates if the epilogue combined adjustment into pop
+///
+/// RESTRICTIONS:
+///   - IF C is SET:
+///     + L flag must be set since frame chaining requires r11 and lr
+///     + r11 must NOT be included in the set of registers described by Reg
+///   - IF Ret is 0:
+///     + L flag must be set
+
+// NOTE: RuntimeFunction is meant to be a simple class that provides raw access
+// to all fields in the structure.  The accessor methods reflect the names of
+// the bitfields that they correspond to.  Although some obvious simplifications
+// are possible via merging of methods, it would prevent the use of this class
+// to fully inspect the contents of the data structure which is particularly
+// useful for scenarios such as llvm-readobj to aid in testing.
+
+class RuntimeFunction {
+public:
+  const support::ulittle32_t BeginAddress;
+  const support::ulittle32_t UnwindData;
+
+  RuntimeFunction(const support::ulittle32_t *Data)
+    : BeginAddress(Data[0]), UnwindData(Data[1]) {}
+
+  RuntimeFunction(const support::ulittle32_t BeginAddress,
+                  const support::ulittle32_t UnwindData)
+    : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
+
+  RuntimeFunctionFlag Flag() const {
+    return RuntimeFunctionFlag(UnwindData & 0x3);
+  }
+
+  uint32_t ExceptionInformationRVA() const {
+    assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
+           "unpacked form required for this operation");
+    return (UnwindData & ~0x3);
+  }
+
+  uint32_t PackedUnwindData() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return (UnwindData & ~0x3);
+  }
+  uint32_t FunctionLength() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return (((UnwindData & 0x00001ffc) >> 2) << 1);
+  }
+  ReturnType Ret() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    assert(((UnwindData & 0x00006000) || L()) && "L must be set to 1");
+    return ReturnType((UnwindData & 0x00006000) >> 13);
+  }
+  bool H() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return ((UnwindData & 0x00008000) >> 15);
+  }
+  uint8_t Reg() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return ((UnwindData & 0x00070000) >> 16);
+  }
+  bool R() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return ((UnwindData & 0x00080000) >> 19);
+  }
+  bool L() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return ((UnwindData & 0x00100000) >> 20);
+  }
+  bool C() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    assert(((~UnwindData & 0x00200000) || L()) &&
+           "L flag must be set, chaining requires r11 and LR");
+    assert(((~UnwindData & 0x00200000) || (Reg() < 7) || R()) &&
+           "r11 must not be included in Reg; C implies r11");
+    return ((UnwindData & 0x00200000) >> 21);
+  }
+  uint16_t StackAdjust() const {
+    assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
+            Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
+           "packed form required for this operation");
+    return ((UnwindData & 0xffc00000) >> 22);
+  }
+};
+
+/// PrologueFolding - pseudo-flag derived from Stack Adjust indicating that the
+/// prologue has stack adjustment combined into the push
+inline bool PrologueFolding(const RuntimeFunction &RF) {
+  return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x4);
+}
+/// Epilogue - pseudo-flag derived from Stack Adjust indicating that the
+/// epilogue has stack adjustment combined into the pop
+inline bool EpilogueFolding(const RuntimeFunction &RF) {
+  return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x8);
+}
+/// StackAdjustment - calculated stack adjustment in words.  The stack
+/// adjustment should be determined via this function to account for the special
+/// handling the special encoding when the value is >= 0x3f4.
+inline uint16_t StackAdjustment(const RuntimeFunction &RF) {
+  uint16_t Adjustment = RF.StackAdjust();
+  if (Adjustment >= 0x3f4)
+    return (Adjustment & 0x3) ? ((Adjustment & 0x3) << 2) - 1 : 0;
+  return Adjustment;
+}
+
+/// SavedRegisterMask - Utility function to calculate the set of saved general
+/// purpose (r0-r15) and VFP (d0-d31) registers.
+std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF);
+
+/// ExceptionDataRecord - An entry in the table of exception data (.xdata)
+///
+///  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+///  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +-------+---------+-+-+-+---+-----------------------------------+
+/// | C Wrd | Epi Cnt |F|E|X|Ver|         Function Length           |
+/// +-------+--------+'-'-'-'---'---+-------------------------------+
+/// |    Reserved    |Ex. Code Words|   (Extended Epilogue Count)   |
+/// +-------+--------+--------------+-------------------------------+
+///
+/// Function Length : 18-bit field indicating the total length of the function
+///                   in bytes divided by 2.  If a function is larger than
+///                   512KB, then multiple pdata and xdata records must be used.
+/// Vers : 2-bit field describing the version of the remaining structure.  Only
+///        version 0 is currently defined (values 1-3 are not permitted).
+/// X : 1-bit field indicating the presence of exception data
+/// E : 1-bit field indicating that the single epilogue is packed into the
+///     header
+/// F : 1-bit field indicating that the record describes a function fragment
+///     (implies that no prologue is present, and prologue processing should be
+///     skipped)
+/// Epilogue Count : 5-bit field that differs in meaning based on the E field.
+///
+///                  If E is set, then this field specifies the index of the
+///                  first unwind code describing the (only) epilogue.
+///
+///                  Otherwise, this field indicates the number of exception
+///                  scopes.  If more than 31 scopes exist, then this field and
+///                  the Code Words field must both be set to 0 to indicate that
+///                  an extension word is required.
+/// Code Words : 4-bit field that species the number of 32-bit words needed to
+///              contain all the unwind codes.  If more than 15 words (63 code
+///              bytes) are required, then this field and the Epilogue Count
+///              field must both be set to 0 to indicate that an extension word
+///              is required.
+/// Extended Epilogue Count, Extended Code Words :
+///                          Valid only if Epilog Count and Code Words are both
+///                          set to 0.  Provides an 8-bit extended code word
+///                          count and 16-bits for epilogue count
+///
+///  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+///  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +----------------+------+---+---+-------------------------------+
+/// |  Ep Start Idx  | Cond |Res|       Epilogue Start Offset       |
+/// +----------------+------+---+-----------------------------------+
+///
+/// If the E bit is unset in the header, the header is followed by a series of
+/// epilogue scopes, which are sorted by their offset.
+///
+/// Epilogue Start Offset: 18-bit field encoding the offset of epilogue relative
+///                        to the start of the function in bytes divided by two
+/// Res : 2-bit field reserved for future expansion (must be set to 0)
+/// Condition : 4-bit field providing the condition under which the epilogue is
+///             executed.  Unconditional epilogues should set this field to 0xe.
+///             Epilogues must be entirely conditional or unconditional, and in
+///             Thumb-2 mode.  The epilogue beings with the first instruction
+///             after the IT opcode.
+/// Epilogue Start Index : 8-bit field indicating the byte index of the first
+///                        unwind code describing the epilogue
+///
+///  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+///  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------+---------------+---------------+---------------+
+/// | Unwind Code 3 | Unwind Code 2 | Unwind Code 1 | Unwind Code 0 |
+/// +---------------+---------------+---------------+---------------+
+///
+/// Following the epilogue scopes, the byte code describing the unwinding
+/// follows.  This is padded to align up to word alignment.  Bytes are stored in
+/// little endian.
+///
+///  3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+///  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+/// +---------------------------------------------------------------+
+/// |           Exception Handler RVA (requires X = 1)              |
+/// +---------------------------------------------------------------+
+/// |  (possibly followed by data required for exception handler)   |
+/// +---------------------------------------------------------------+
+///
+/// If the X bit is set in the header, the unwind byte code is followed by the
+/// exception handler information.  This constants of one Exception Handler RVA
+/// which is the address to the exception handler, followed immediately by the
+/// variable length data associated with the exception handler.
+///
+
+struct EpilogueScope {
+  const support::ulittle32_t ES;
+
+  EpilogueScope(const support::ulittle32_t Data) : ES(Data) {}
+  uint32_t EpilogueStartOffset() const {
+    return (ES & 0x0003ffff);
+  }
+  uint8_t Res() const {
+    return ((ES & 0x000c0000) >> 18);
+  }
+  uint8_t Condition() const {
+    return ((ES & 0x00f00000) >> 20);
+  }
+  uint8_t EpilogueStartIndex() const {
+    return ((ES & 0xff000000) >> 24);
+  }
+};
+
+struct ExceptionDataRecord;
+inline size_t HeaderWords(const ExceptionDataRecord &XR);
+
+struct ExceptionDataRecord {
+  const support::ulittle32_t *Data;
+
+  ExceptionDataRecord(const support::ulittle32_t *Data) : Data(Data) {}
+
+  uint32_t FunctionLength() const {
+    return (Data[0] & 0x0003ffff);
+  }
+
+  uint8_t Vers() const {
+    return (Data[0] & 0x000C0000) >> 18;
+  }
+
+  bool X() const {
+    return ((Data[0] & 0x00100000) >> 20);
+  }
+
+  bool E() const {
+    return ((Data[0] & 0x00200000) >> 21);
+  }
+
+  bool F() const {
+    return ((Data[0] & 0x00400000) >> 22);
+  }
+
+  uint8_t EpilogueCount() const {
+    if (HeaderWords(*this) == 1)
+      return (Data[0] & 0x0f800000) >> 23;
+    return Data[1] & 0x0000ffff;
+  }
+
+  uint8_t CodeWords() const {
+    if (HeaderWords(*this) == 1)
+      return (Data[0] & 0xf0000000) >> 28;
+    return (Data[1] & 0x00ff0000) >> 16;
+  }
+
+  ArrayRef<support::ulittle32_t> EpilogueScopes() const {
+    assert(E() == 0 && "epilogue scopes are only present when the E bit is 0");
+    size_t Offset = HeaderWords(*this);
+    return ArrayRef<support::ulittle32_t>(&Data[Offset], EpilogueCount());
+  }
+
+  ArrayRef<support::ulittle8_t> UnwindByteCode() const {
+    const size_t Offset = HeaderWords(*this)
+                        + (E() ? 0 :  EpilogueCount());
+    const support::ulittle8_t *ByteCode =
+      reinterpret_cast<const support::ulittle8_t *>(&Data[Offset]);
+    return ArrayRef<support::ulittle8_t>(ByteCode,
+                                         CodeWords() * sizeof(uint32_t));
+  }
+
+  uint32_t ExceptionHandlerRVA() const {
+    assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+    return Data[HeaderWords(*this) + EpilogueCount() + CodeWords()];
+  }
+
+  uint32_t ExceptionHandlerParameter() const {
+    assert(X() && "Exception Handler RVA is only valid if the X bit is set");
+    return Data[HeaderWords(*this) + EpilogueCount() + CodeWords() + 1];
+  }
+};
+
+inline size_t HeaderWords(const ExceptionDataRecord &XR) {
+  return (XR.Data[0] & 0xff800000) ? 1 : 2;
+}
+}
+}
+}
+
+#endif
+
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
new file mode 100644
index 0000000..061d5ac
--- /dev/null
+++ b/include/llvm/Support/AlignOf.h
@@ -0,0 +1,210 @@
+//===--- AlignOf.h - Portable calculation of type alignment -----*- 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 AlignOf function that computes alignments for
+// arbitrary types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALIGNOF_H
+#define LLVM_SUPPORT_ALIGNOF_H
+
+#include "llvm/Support/Compiler.h"
+#include <cstddef>
+
+namespace llvm {
+template <typename T>
+struct AlignmentCalcImpl {
+  char x;
+  T t;
+private:
+  AlignmentCalcImpl() {} // Never instantiate.
+};
+
+/// AlignOf - A templated class that contains an enum value representing
+///  the alignment of the template argument.  For example,
+///  AlignOf<int>::Alignment represents the alignment of type "int".  The
+///  alignment calculated is the minimum alignment, and not necessarily
+///  the "desired" alignment returned by GCC's __alignof__ (for example).  Note
+///  that because the alignment is an enum value, it can be used as a
+///  compile-time constant (e.g., for template instantiation).
+template <typename T>
+struct AlignOf {
+  enum { Alignment =
+         static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
+
+  enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
+  enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
+  enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
+  enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
+
+  enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
+  enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
+  enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
+  enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
+};
+
+/// alignOf - A templated function that returns the minimum alignment of
+///  of a type.  This provides no extra functionality beyond the AlignOf
+///  class besides some cosmetic cleanliness.  Example usage:
+///  alignOf<int>() returns the alignment of an int.
+template <typename T>
+inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+
+/// \struct AlignedCharArray
+/// \brief Helper for building an aligned character array type.
+///
+/// This template is used to explicitly build up a collection of aligned
+/// character array types. We have to build these up using a macro and explicit
+/// specialization to cope with old versions of MSVC and GCC where only an
+/// integer literal can be used to specify an alignment constraint. Once built
+/// up here, we can then begin to indirect between these using normal C++
+/// template parameters.
+
+// MSVC requires special handling here.
+#ifndef _MSC_VER
+
+#if __has_feature(cxx_alignas)
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray {
+  alignas(Alignment) char buffer[Size];
+};
+
+#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
+/// \brief Create a type with an aligned char buffer.
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray;
+
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+  template<std::size_t Size> \
+  struct AlignedCharArray<x, Size> { \
+    __attribute__((aligned(x))) char buffer[Size]; \
+  };
+
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
+
+#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
+
+#else
+# error No supported align as directive.
+#endif
+
+#else // _MSC_VER
+
+/// \brief Create a type with an aligned char buffer.
+template<std::size_t Alignment, std::size_t Size>
+struct AlignedCharArray;
+
+// We provide special variations of this template for the most common
+// alignments because __declspec(align(...)) doesn't actually work when it is
+// a member of a by-value function argument in MSVC, even if the alignment
+// request is something reasonably like 8-byte or 16-byte. Note that we can't
+// even include the declspec with the union that forces the alignment because
+// MSVC warns on the existence of the declspec despite the union member forcing
+// proper alignment.
+
+template<std::size_t Size>
+struct AlignedCharArray<1, Size> {
+  union {
+    char aligned;
+    char buffer[Size];
+  };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<2, Size> {
+  union {
+    short aligned;
+    char buffer[Size];
+  };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<4, Size> {
+  union {
+    int aligned;
+    char buffer[Size];
+  };
+};
+
+template<std::size_t Size>
+struct AlignedCharArray<8, Size> {
+  union {
+    double aligned;
+    char buffer[Size];
+  };
+};
+
+
+// The rest of these are provided with a __declspec(align(...)) and we simply
+// can't pass them by-value as function arguments on MSVC.
+
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+  template<std::size_t Size> \
+  struct AlignedCharArray<x, Size> { \
+    __declspec(align(x)) char buffer[Size]; \
+  };
+
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
+
+#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
+
+#endif // _MSC_VER
+
+namespace detail {
+template <typename T1,
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char,
+          typename T8 = char, typename T9 = char, typename T10 = char>
+class AlignerImpl {
+  T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
+
+  AlignerImpl(); // Never defined or instantiated.
+};
+
+template <typename T1,
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char,
+          typename T8 = char, typename T9 = char, typename T10 = char>
+union SizerImpl {
+  char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
+       arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
+       arr9[sizeof(T9)], arr10[sizeof(T10)];
+};
+} // end namespace detail
+
+/// \brief This union template exposes a suitably aligned and sized character
+/// array member which can hold elements of any of up to four types.
+///
+/// These types may be arrays, structs, or any other types. The goal is to
+/// expose a char array buffer member which can be used as suitable storage for
+/// a placement new of any of these types. Support for more than seven types can
+/// be added at the cost of more boiler plate.
+template <typename T1,
+          typename T2 = char, typename T3 = char, typename T4 = char,
+          typename T5 = char, typename T6 = char, typename T7 = char,
+          typename T8 = char, typename T9 = char, typename T10 = char>
+struct AlignedCharArrayUnion : llvm::AlignedCharArray<
+    AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
+                                T6, T7, T8, T9, T10> >::Alignment,
+    sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
+                             T6, T7, T8, T9, T10>)> {
+};
+} // end namespace llvm
+#endif
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
new file mode 100644
index 0000000..7a7e4c0
--- /dev/null
+++ b/include/llvm/Support/Allocator.h
@@ -0,0 +1,429 @@
+//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines the MallocAllocator and BumpPtrAllocator interfaces. Both
+/// of these conform to an LLVM "Allocator" concept which consists of an
+/// Allocate method accepting a size and alignment, and a Deallocate accepting
+/// a pointer and size. Further, the LLVM "Allocator" concept has overloads of
+/// Allocate and Deallocate for setting size and alignment based on the final
+/// type. These overloads are typically provided by a base class template \c
+/// AllocatorBase.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATOR_H
+#define LLVM_SUPPORT_ALLOCATOR_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+
+namespace llvm {
+
+/// \brief CRTP base class providing obvious overloads for the core \c
+/// Allocate() methods of LLVM-style allocators.
+///
+/// This base class both documents the full public interface exposed by all
+/// LLVM-style allocators, and redirects all of the overloads to a single core
+/// set of methods which the derived class must define.
+template <typename DerivedT> class AllocatorBase {
+public:
+  /// \brief Allocate \a Size bytes of \a Alignment aligned memory. This method
+  /// must be implemented by \c DerivedT.
+  void *Allocate(size_t Size, size_t Alignment) {
+#ifdef __clang__
+    static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
+                      &AllocatorBase::Allocate) !=
+                      static_cast<void *(DerivedT::*)(size_t, size_t)>(
+                          &DerivedT::Allocate),
+                  "Class derives from AllocatorBase without implementing the "
+                  "core Allocate(size_t, size_t) overload!");
+#endif
+    return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
+  }
+
+  /// \brief Deallocate \a Ptr to \a Size bytes of memory allocated by this
+  /// allocator.
+  void Deallocate(const void *Ptr, size_t Size) {
+#ifdef __clang__
+    static_assert(static_cast<void (AllocatorBase::*)(const void *, size_t)>(
+                      &AllocatorBase::Deallocate) !=
+                      static_cast<void (DerivedT::*)(const void *, size_t)>(
+                          &DerivedT::Deallocate),
+                  "Class derives from AllocatorBase without implementing the "
+                  "core Deallocate(void *) overload!");
+#endif
+    return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size);
+  }
+
+  // The rest of these methods are helpers that redirect to one of the above
+  // core methods.
+
+  /// \brief Allocate space for a sequence of objects without constructing them.
+  template <typename T> T *Allocate(size_t Num = 1) {
+    return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+  }
+
+  /// \brief Deallocate space for a sequence of objects without constructing them.
+  template <typename T>
+  typename std::enable_if<
+      !std::is_same<typename std::remove_cv<T>::type, void>::value, void>::type
+  Deallocate(T *Ptr, size_t Num = 1) {
+    Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T));
+  }
+};
+
+class MallocAllocator : public AllocatorBase<MallocAllocator> {
+public:
+  void Reset() {}
+
+  void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
+
+  // Pull in base class overloads.
+  using AllocatorBase<MallocAllocator>::Allocate;
+
+  void Deallocate(const void *Ptr, size_t /*Size*/) {
+    free(const_cast<void *>(Ptr));
+  }
+
+  // Pull in base class overloads.
+  using AllocatorBase<MallocAllocator>::Deallocate;
+
+  void PrintStats() const {}
+};
+
+namespace detail {
+
+// We call out to an external function to actually print the message as the
+// printing code uses Allocator.h in its implementation.
+void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated,
+                                size_t TotalMemory);
+} // End namespace detail.
+
+/// \brief Allocate memory in an ever growing pool, as if by bump-pointer.
+///
+/// This isn't strictly a bump-pointer allocator as it uses backing slabs of
+/// memory rather than relying on boundless contiguous heap. However, it has
+/// bump-pointer semantics in that is a monotonically growing pool of memory
+/// where every allocation is found by merely allocating the next N bytes in
+/// the slab, or the next N bytes in the next slab.
+///
+/// Note that this also has a threshold for forcing allocations above a certain
+/// size into their own slab.
+///
+/// The BumpPtrAllocatorImpl template defaults to using a MallocAllocator
+/// object, which wraps malloc, to allocate memory, but it can be changed to
+/// use a custom allocator.
+template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096,
+          size_t SizeThreshold = SlabSize>
+class BumpPtrAllocatorImpl
+    : public AllocatorBase<
+          BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>> {
+public:
+  static_assert(SizeThreshold <= SlabSize,
+                "The SizeThreshold must be at most the SlabSize to ensure "
+                "that objects larger than a slab go into their own memory "
+                "allocation.");
+
+  BumpPtrAllocatorImpl()
+      : CurPtr(nullptr), End(nullptr), BytesAllocated(0), Allocator() {}
+  template <typename T>
+  BumpPtrAllocatorImpl(T &&Allocator)
+      : CurPtr(nullptr), End(nullptr), BytesAllocated(0),
+        Allocator(std::forward<T &&>(Allocator)) {}
+
+  // Manually implement a move constructor as we must clear the old allocators
+  // slabs as a matter of correctness.
+  BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
+      : CurPtr(Old.CurPtr), End(Old.End), Slabs(std::move(Old.Slabs)),
+        CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
+        BytesAllocated(Old.BytesAllocated),
+        Allocator(std::move(Old.Allocator)) {
+    Old.CurPtr = Old.End = nullptr;
+    Old.BytesAllocated = 0;
+    Old.Slabs.clear();
+    Old.CustomSizedSlabs.clear();
+  }
+
+  ~BumpPtrAllocatorImpl() {
+    DeallocateSlabs(Slabs.begin(), Slabs.end());
+    DeallocateCustomSizedSlabs();
+  }
+
+  BumpPtrAllocatorImpl &operator=(BumpPtrAllocatorImpl &&RHS) {
+    DeallocateSlabs(Slabs.begin(), Slabs.end());
+    DeallocateCustomSizedSlabs();
+
+    CurPtr = RHS.CurPtr;
+    End = RHS.End;
+    BytesAllocated = RHS.BytesAllocated;
+    Slabs = std::move(RHS.Slabs);
+    CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
+    Allocator = std::move(RHS.Allocator);
+
+    RHS.CurPtr = RHS.End = nullptr;
+    RHS.BytesAllocated = 0;
+    RHS.Slabs.clear();
+    RHS.CustomSizedSlabs.clear();
+    return *this;
+  }
+
+  /// \brief Deallocate all but the current slab and reset the current pointer
+  /// to the beginning of it, freeing all memory allocated so far.
+  void Reset() {
+    if (Slabs.empty())
+      return;
+
+    // Reset the state.
+    BytesAllocated = 0;
+    CurPtr = (char *)Slabs.front();
+    End = CurPtr + SlabSize;
+
+    // Deallocate all but the first slab, and all custome sized slabs.
+    DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
+    Slabs.erase(std::next(Slabs.begin()), Slabs.end());
+    DeallocateCustomSizedSlabs();
+    CustomSizedSlabs.clear();
+  }
+
+  /// \brief Allocate space at the specified alignment.
+  void *Allocate(size_t Size, size_t Alignment) {
+    if (!CurPtr) // Start a new slab if we haven't allocated one already.
+      StartNewSlab();
+
+    // Keep track of how many bytes we've allocated.
+    BytesAllocated += Size;
+
+    // 0-byte alignment means 1-byte alignment.
+    if (Alignment == 0)
+      Alignment = 1;
+
+    // Allocate the aligned space, going forwards from CurPtr.
+    char *Ptr = alignPtr(CurPtr, Alignment);
+
+    // Check if we can hold it.
+    if (Ptr + Size <= End) {
+      CurPtr = Ptr + Size;
+      // Update the allocation point of this memory block in MemorySanitizer.
+      // Without this, MemorySanitizer messages for values originated from here
+      // will point to the allocation of the entire slab.
+      __msan_allocated_memory(Ptr, Size);
+      return Ptr;
+    }
+
+    // If Size is really big, allocate a separate slab for it.
+    size_t PaddedSize = Size + Alignment - 1;
+    if (PaddedSize > SizeThreshold) {
+      void *NewSlab = Allocator.Allocate(PaddedSize, 0);
+      CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize));
+
+      Ptr = alignPtr((char *)NewSlab, Alignment);
+      assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + PaddedSize);
+      __msan_allocated_memory(Ptr, Size);
+      return Ptr;
+    }
+
+    // Otherwise, start a new slab and try again.
+    StartNewSlab();
+    Ptr = alignPtr(CurPtr, Alignment);
+    CurPtr = Ptr + Size;
+    assert(CurPtr <= End && "Unable to allocate memory!");
+    __msan_allocated_memory(Ptr, Size);
+    return Ptr;
+  }
+
+  // Pull in base class overloads.
+  using AllocatorBase<BumpPtrAllocatorImpl>::Allocate;
+
+  void Deallocate(const void * /*Ptr*/, size_t /*Size*/) {}
+
+  // Pull in base class overloads.
+  using AllocatorBase<BumpPtrAllocatorImpl>::Deallocate;
+
+  size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
+
+  size_t getTotalMemory() const {
+    size_t TotalMemory = 0;
+    for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)
+      TotalMemory += computeSlabSize(std::distance(Slabs.begin(), I));
+    for (auto &PtrAndSize : CustomSizedSlabs)
+      TotalMemory += PtrAndSize.second;
+    return TotalMemory;
+  }
+
+  void PrintStats() const {
+    detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated,
+                                       getTotalMemory());
+  }
+
+private:
+  /// \brief The current pointer into the current slab.
+  ///
+  /// This points to the next free byte in the slab.
+  char *CurPtr;
+
+  /// \brief The end of the current slab.
+  char *End;
+
+  /// \brief The slabs allocated so far.
+  SmallVector<void *, 4> Slabs;
+
+  /// \brief Custom-sized slabs allocated for too-large allocation requests.
+  SmallVector<std::pair<void *, size_t>, 0> CustomSizedSlabs;
+
+  /// \brief How many bytes we've allocated.
+  ///
+  /// Used so that we can compute how much space was wasted.
+  size_t BytesAllocated;
+
+  /// \brief The allocator instance we use to get slabs of memory.
+  AllocatorT Allocator;
+
+  static size_t computeSlabSize(unsigned SlabIdx) {
+    // Scale the actual allocated slab size based on the number of slabs
+    // allocated. Every 128 slabs allocated, we double the allocated size to
+    // reduce allocation frequency, but saturate at multiplying the slab size by
+    // 2^30.
+    return SlabSize * ((size_t)1 << std::min<size_t>(30, SlabIdx / 128));
+  }
+
+  /// \brief Allocate a new slab and move the bump pointers over into the new
+  /// slab, modifying CurPtr and End.
+  void StartNewSlab() {
+    size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
+
+    void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
+    Slabs.push_back(NewSlab);
+    CurPtr = (char *)(NewSlab);
+    End = ((char *)NewSlab) + AllocatedSlabSize;
+  }
+
+  /// \brief Deallocate a sequence of slabs.
+  void DeallocateSlabs(SmallVectorImpl<void *>::iterator I,
+                       SmallVectorImpl<void *>::iterator E) {
+    for (; I != E; ++I) {
+      size_t AllocatedSlabSize =
+          computeSlabSize(std::distance(Slabs.begin(), I));
+#ifndef NDEBUG
+      // Poison the memory so stale pointers crash sooner.  Note we must
+      // preserve the Size and NextPtr fields at the beginning.
+      sys::Memory::setRangeWritable(*I, AllocatedSlabSize);
+      memset(*I, 0xCD, AllocatedSlabSize);
+#endif
+      Allocator.Deallocate(*I, AllocatedSlabSize);
+    }
+  }
+
+  /// \brief Deallocate all memory for custom sized slabs.
+  void DeallocateCustomSizedSlabs() {
+    for (auto &PtrAndSize : CustomSizedSlabs) {
+      void *Ptr = PtrAndSize.first;
+      size_t Size = PtrAndSize.second;
+#ifndef NDEBUG
+      // Poison the memory so stale pointers crash sooner.  Note we must
+      // preserve the Size and NextPtr fields at the beginning.
+      sys::Memory::setRangeWritable(Ptr, Size);
+      memset(Ptr, 0xCD, Size);
+#endif
+      Allocator.Deallocate(Ptr, Size);
+    }
+  }
+
+  template <typename T> friend class SpecificBumpPtrAllocator;
+};
+
+/// \brief The standard BumpPtrAllocator which just uses the default template
+/// paramaters.
+typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
+
+/// \brief A BumpPtrAllocator that allows only elements of a specific type to be
+/// allocated.
+///
+/// This allows calling the destructor in DestroyAll() and when the allocator is
+/// destroyed.
+template <typename T> class SpecificBumpPtrAllocator {
+  BumpPtrAllocator Allocator;
+
+public:
+  SpecificBumpPtrAllocator() : Allocator() {}
+  SpecificBumpPtrAllocator(SpecificBumpPtrAllocator &&Old)
+      : Allocator(std::move(Old.Allocator)) {}
+  ~SpecificBumpPtrAllocator() { DestroyAll(); }
+
+  SpecificBumpPtrAllocator &operator=(SpecificBumpPtrAllocator &&RHS) {
+    Allocator = std::move(RHS.Allocator);
+    return *this;
+  }
+
+  /// Call the destructor of each allocated object and deallocate all but the
+  /// current slab and reset the current pointer to the beginning of it, freeing
+  /// all memory allocated so far.
+  void DestroyAll() {
+    auto DestroyElements = [](char *Begin, char *End) {
+      assert(Begin == alignPtr(Begin, alignOf<T>()));
+      for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T))
+        reinterpret_cast<T *>(Ptr)->~T();
+    };
+
+    for (auto I = Allocator.Slabs.begin(), E = Allocator.Slabs.end(); I != E;
+         ++I) {
+      size_t AllocatedSlabSize = BumpPtrAllocator::computeSlabSize(
+          std::distance(Allocator.Slabs.begin(), I));
+      char *Begin = alignPtr((char *)*I, alignOf<T>());
+      char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr
+                                               : (char *)*I + AllocatedSlabSize;
+
+      DestroyElements(Begin, End);
+    }
+
+    for (auto &PtrAndSize : Allocator.CustomSizedSlabs) {
+      void *Ptr = PtrAndSize.first;
+      size_t Size = PtrAndSize.second;
+      DestroyElements(alignPtr((char *)Ptr, alignOf<T>()), (char *)Ptr + Size);
+    }
+
+    Allocator.Reset();
+  }
+
+  /// \brief Allocate space for an array of objects without constructing them.
+  T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); }
+};
+
+}  // end namespace llvm
+
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
+void *operator new(size_t Size,
+                   llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize,
+                                              SizeThreshold> &Allocator) {
+  struct S {
+    char c;
+    union {
+      double D;
+      long double LD;
+      long long L;
+      void *P;
+    } x;
+  };
+  return Allocator.Allocate(
+      Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
+}
+
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
+void operator delete(
+    void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold> &) {
+}
+
+#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
new file mode 100644
index 0000000..36f644a
--- /dev/null
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -0,0 +1,143 @@
+//==- llvm/Support/ArrayRecycler.h - Recycling of Arrays ---------*- 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 ArrayRecycler class template which can recycle small
+// arrays allocated from one of the allocators in Allocator.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARRAYRECYCLER_H
+#define LLVM_SUPPORT_ARRAYRECYCLER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/MathExtras.h"
+
+namespace llvm {
+
+/// Recycle small arrays allocated from a BumpPtrAllocator.
+///
+/// Arrays are allocated in a small number of fixed sizes. For each supported
+/// array size, the ArrayRecycler keeps a free list of available arrays.
+///
+template<class T, size_t Align = AlignOf<T>::Alignment>
+class ArrayRecycler {
+  // The free list for a given array size is a simple singly linked list.
+  // We can't use iplist or Recycler here since those classes can't be copied.
+  struct FreeList {
+    FreeList *Next;
+  };
+
+  static_assert(Align >= AlignOf<FreeList>::Alignment, "Object underaligned");
+  static_assert(sizeof(T) >= sizeof(FreeList), "Objects are too small");
+
+  // Keep a free list for each array size.
+  SmallVector<FreeList*, 8> Bucket;
+
+  // Remove an entry from the free list in Bucket[Idx] and return it.
+  // Return NULL if no entries are available.
+  T *pop(unsigned Idx) {
+    if (Idx >= Bucket.size())
+      return nullptr;
+    FreeList *Entry = Bucket[Idx];
+    if (!Entry)
+      return nullptr;
+    Bucket[Idx] = Entry->Next;
+    return reinterpret_cast<T*>(Entry);
+  }
+
+  // Add an entry to the free list at Bucket[Idx].
+  void push(unsigned Idx, T *Ptr) {
+    assert(Ptr && "Cannot recycle NULL pointer");
+    FreeList *Entry = reinterpret_cast<FreeList*>(Ptr);
+    if (Idx >= Bucket.size())
+      Bucket.resize(size_t(Idx) + 1);
+    Entry->Next = Bucket[Idx];
+    Bucket[Idx] = Entry;
+  }
+
+public:
+  /// The size of an allocated array is represented by a Capacity instance.
+  ///
+  /// This class is much smaller than a size_t, and it provides methods to work
+  /// with the set of legal array capacities.
+  class Capacity {
+    uint8_t Index;
+    explicit Capacity(uint8_t idx) : Index(idx) {}
+
+  public:
+    Capacity() : Index(0) {}
+
+    /// Get the capacity of an array that can hold at least N elements.
+    static Capacity get(size_t N) {
+      return Capacity(N ? Log2_64_Ceil(N) : 0);
+    }
+
+    /// Get the number of elements in an array with this capacity.
+    size_t getSize() const { return size_t(1u) << Index; }
+
+    /// Get the bucket number for this capacity.
+    unsigned getBucket() const { return Index; }
+
+    /// Get the next larger capacity. Large capacities grow exponentially, so
+    /// this function can be used to reallocate incrementally growing vectors
+    /// in amortized linear time.
+    Capacity getNext() const { return Capacity(Index + 1); }
+  };
+
+  ~ArrayRecycler() {
+    // The client should always call clear() so recycled arrays can be returned
+    // to the allocator.
+    assert(Bucket.empty() && "Non-empty ArrayRecycler deleted!");
+  }
+
+  /// Release all the tracked allocations to the allocator. The recycler must
+  /// be free of any tracked allocations before being deleted.
+  template<class AllocatorType>
+  void clear(AllocatorType &Allocator) {
+    for (; !Bucket.empty(); Bucket.pop_back())
+      while (T *Ptr = pop(Bucket.size() - 1))
+        Allocator.Deallocate(Ptr);
+  }
+
+  /// Special case for BumpPtrAllocator which has an empty Deallocate()
+  /// function.
+  ///
+  /// There is no need to traverse the free lists, pulling all the objects into
+  /// cache.
+  void clear(BumpPtrAllocator&) {
+    Bucket.clear();
+  }
+
+  /// Allocate an array of at least the requested capacity.
+  ///
+  /// Return an existing recycled array, or allocate one from Allocator if
+  /// none are available for recycling.
+  ///
+  template<class AllocatorType>
+  T *allocate(Capacity Cap, AllocatorType &Allocator) {
+    // Try to recycle an existing array.
+    if (T *Ptr = pop(Cap.getBucket()))
+      return Ptr;
+    // Nope, get more memory.
+    return static_cast<T*>(Allocator.Allocate(sizeof(T)*Cap.getSize(), Align));
+  }
+
+  /// Deallocate an array with the specified Capacity.
+  ///
+  /// Cap must be the same capacity that was given to allocate().
+  ///
+  void deallocate(Capacity Cap, T *Ptr) {
+    push(Cap.getBucket(), Ptr);
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h
new file mode 100644
index 0000000..9ec23e8
--- /dev/null
+++ b/include/llvm/Support/Atomic.h
@@ -0,0 +1,39 @@
+//===- llvm/Support/Atomic.h - Atomic Operations -----------------*- 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 llvm::sys atomic operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ATOMIC_H
+#define LLVM_SUPPORT_ATOMIC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  namespace sys {
+    void MemoryFence();
+
+#ifdef _MSC_VER
+    typedef long cas_flag;
+#else
+    typedef uint32_t cas_flag;
+#endif
+    cas_flag CompareAndSwap(volatile cas_flag* ptr,
+                            cas_flag new_value,
+                            cas_flag old_value);
+    cas_flag AtomicIncrement(volatile cas_flag* ptr);
+    cas_flag AtomicDecrement(volatile cas_flag* ptr);
+    cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
+    cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
new file mode 100644
index 0000000..4304a25
--- /dev/null
+++ b/include/llvm/Support/BlockFrequency.h
@@ -0,0 +1,74 @@
+//===-------- BlockFrequency.h - Block Frequency 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 implements Block Frequency class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H
+#define LLVM_SUPPORT_BLOCKFREQUENCY_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class raw_ostream;
+class BranchProbability;
+
+// This class represents Block Frequency as a 64-bit value.
+class BlockFrequency {
+  uint64_t Frequency;
+
+public:
+  BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
+
+  /// \brief Returns the maximum possible frequency, the saturation value.
+  static uint64_t getMaxFrequency() { return -1ULL; }
+
+  /// \brief Returns the frequency as a fixpoint number scaled by the entry
+  /// frequency.
+  uint64_t getFrequency() const { return Frequency; }
+
+  /// \brief Multiplies with a branch probability. The computation will never
+  /// overflow.
+  BlockFrequency &operator*=(const BranchProbability &Prob);
+  const BlockFrequency operator*(const BranchProbability &Prob) const;
+
+  /// \brief Divide by a non-zero branch probability using saturating
+  /// arithmetic.
+  BlockFrequency &operator/=(const BranchProbability &Prob);
+  BlockFrequency operator/(const BranchProbability &Prob) const;
+
+  /// \brief Adds another block frequency using saturating arithmetic.
+  BlockFrequency &operator+=(const BlockFrequency &Freq);
+  const BlockFrequency operator+(const BlockFrequency &Freq) const;
+
+  /// \brief Shift block frequency to the right by count digits saturating to 1.
+  BlockFrequency &operator>>=(const unsigned count);
+
+  bool operator<(const BlockFrequency &RHS) const {
+    return Frequency < RHS.Frequency;
+  }
+
+  bool operator<=(const BlockFrequency &RHS) const {
+    return Frequency <= RHS.Frequency;
+  }
+
+  bool operator>(const BlockFrequency &RHS) const {
+    return Frequency > RHS.Frequency;
+  }
+
+  bool operator>=(const BlockFrequency &RHS) const {
+    return Frequency >= RHS.Frequency;
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
new file mode 100644
index 0000000..9aab6ac
--- /dev/null
+++ b/include/llvm/Support/BranchProbability.h
@@ -0,0 +1,89 @@
+//===- BranchProbability.h - Branch Probability Wrapper ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Definition of BranchProbability shared by IR and Machine Instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BRANCHPROBABILITY_H
+#define LLVM_SUPPORT_BRANCHPROBABILITY_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class raw_ostream;
+
+// This class represents Branch Probability as a non-negative fraction.
+class BranchProbability {
+  // Numerator
+  uint32_t N;
+
+  // Denominator
+  uint32_t D;
+
+public:
+  BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) {
+    assert(d > 0 && "Denomiator cannot be 0!");
+    assert(n <= d && "Probability cannot be bigger than 1!");
+  }
+
+  static BranchProbability getZero() { return BranchProbability(0, 1); }
+  static BranchProbability getOne() { return BranchProbability(1, 1); }
+
+  uint32_t getNumerator() const { return N; }
+  uint32_t getDenominator() const { return D; }
+
+  // Return (1 - Probability).
+  BranchProbability getCompl() const {
+    return BranchProbability(D - N, D);
+  }
+
+  raw_ostream &print(raw_ostream &OS) const;
+
+  void dump() const;
+
+  /// \brief Scale a large integer.
+  ///
+  /// Scales \c Num.  Guarantees full precision.  Returns the floor of the
+  /// result.
+  ///
+  /// \return \c Num times \c this.
+  uint64_t scale(uint64_t Num) const;
+
+  /// \brief Scale a large integer by the inverse.
+  ///
+  /// Scales \c Num by the inverse of \c this.  Guarantees full precision.
+  /// Returns the floor of the result.
+  ///
+  /// \return \c Num divided by \c this.
+  uint64_t scaleByInverse(uint64_t Num) const;
+
+  bool operator==(BranchProbability RHS) const {
+    return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N;
+  }
+  bool operator!=(BranchProbability RHS) const {
+    return !(*this == RHS);
+  }
+  bool operator<(BranchProbability RHS) const {
+    return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N;
+  }
+  bool operator>(BranchProbability RHS) const { return RHS < *this; }
+  bool operator<=(BranchProbability RHS) const { return !(RHS < *this); }
+  bool operator>=(BranchProbability RHS) const { return !(*this < RHS); }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) {
+  return Prob.print(OS);
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/CBindingWrapping.h b/include/llvm/Support/CBindingWrapping.h
new file mode 100644
index 0000000..51097b8
--- /dev/null
+++ b/include/llvm/Support/CBindingWrapping.h
@@ -0,0 +1,46 @@
+//===- llvm/Support/CBindingWrapph.h - C Interface Wrapping -----*- 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 wrapping macros for the C interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_C_BINDING_WRAPPING_H
+#define LLVM_C_BINDING_WRAPPING_H
+
+#include "llvm/Support/Casting.h"
+
+#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)     \
+  inline ty *unwrap(ref P) {                            \
+    return reinterpret_cast<ty*>(P);                    \
+  }                                                     \
+                                                        \
+  inline ref wrap(const ty *P) {                        \
+    return reinterpret_cast<ref>(const_cast<ty*>(P));   \
+  }
+
+#define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref)        \
+  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)           \
+                                                        \
+  template<typename T>                                  \
+  inline T *unwrap(ref P) {                             \
+    return cast<T>(unwrap(P));                          \
+  }
+
+#define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref)     \
+  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)           \
+                                                        \
+  template<typename T>                                  \
+  inline T *unwrap(ref P) {                             \
+    T *Q = (T*)unwrap(P);                               \
+    assert(Q && "Invalid cast!");                       \
+    return Q;                                           \
+  }
+
+#endif
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
new file mode 100644
index 0000000..e09ef07
--- /dev/null
+++ b/include/llvm/Support/COFF.h
@@ -0,0 +1,657 @@
+//===-- llvm/Support/COFF.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an definitions used in Windows COFF Files.
+//
+// Structures and enums defined within this file where created using
+// information from Microsoft's publicly available PE/COFF format document:
+//
+// Microsoft Portable Executable and Common Object File Format Specification
+// Revision 8.1 - February 15, 2008
+//
+// As of 5/2/2010, hosted by Microsoft at:
+// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COFF_H
+#define LLVM_SUPPORT_COFF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+namespace COFF {
+
+  // The maximum number of sections that a COFF object can have (inclusive).
+  const int MaxNumberOfSections = 65299;
+
+  // The PE signature bytes that follows the DOS stub header.
+  static const char PEMagic[] = { 'P', 'E', '\0', '\0' };
+
+  // Sizes in bytes of various things in the COFF format.
+  enum {
+    HeaderSize     = 20,
+    NameSize       = 8,
+    SymbolSize     = 18,
+    SectionSize    = 40,
+    RelocationSize = 10
+  };
+
+  struct header {
+    uint16_t Machine;
+    uint16_t NumberOfSections;
+    uint32_t TimeDateStamp;
+    uint32_t PointerToSymbolTable;
+    uint32_t NumberOfSymbols;
+    uint16_t SizeOfOptionalHeader;
+    uint16_t Characteristics;
+  };
+
+  enum MachineTypes {
+    MT_Invalid = 0xffff,
+
+    IMAGE_FILE_MACHINE_UNKNOWN   = 0x0,
+    IMAGE_FILE_MACHINE_AM33      = 0x13,
+    IMAGE_FILE_MACHINE_AMD64     = 0x8664,
+    IMAGE_FILE_MACHINE_ARM       = 0x1C0,
+    IMAGE_FILE_MACHINE_ARMNT     = 0x1C4,
+    IMAGE_FILE_MACHINE_EBC       = 0xEBC,
+    IMAGE_FILE_MACHINE_I386      = 0x14C,
+    IMAGE_FILE_MACHINE_IA64      = 0x200,
+    IMAGE_FILE_MACHINE_M32R      = 0x9041,
+    IMAGE_FILE_MACHINE_MIPS16    = 0x266,
+    IMAGE_FILE_MACHINE_MIPSFPU   = 0x366,
+    IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
+    IMAGE_FILE_MACHINE_POWERPC   = 0x1F0,
+    IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
+    IMAGE_FILE_MACHINE_R4000     = 0x166,
+    IMAGE_FILE_MACHINE_SH3       = 0x1A2,
+    IMAGE_FILE_MACHINE_SH3DSP    = 0x1A3,
+    IMAGE_FILE_MACHINE_SH4       = 0x1A6,
+    IMAGE_FILE_MACHINE_SH5       = 0x1A8,
+    IMAGE_FILE_MACHINE_THUMB     = 0x1C2,
+    IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
+  };
+
+  enum Characteristics {
+    C_Invalid = 0,
+
+    /// The file does not contain base relocations and must be loaded at its
+    /// preferred base. If this cannot be done, the loader will error.
+    IMAGE_FILE_RELOCS_STRIPPED         = 0x0001,
+    /// The file is valid and can be run.
+    IMAGE_FILE_EXECUTABLE_IMAGE        = 0x0002,
+    /// COFF line numbers have been stripped. This is deprecated and should be
+    /// 0.
+    IMAGE_FILE_LINE_NUMS_STRIPPED      = 0x0004,
+    /// COFF symbol table entries for local symbols have been removed. This is
+    /// deprecated and should be 0.
+    IMAGE_FILE_LOCAL_SYMS_STRIPPED     = 0x0008,
+    /// Aggressively trim working set. This is deprecated and must be 0.
+    IMAGE_FILE_AGGRESSIVE_WS_TRIM      = 0x0010,
+    /// Image can handle > 2GiB addresses.
+    IMAGE_FILE_LARGE_ADDRESS_AWARE     = 0x0020,
+    /// Little endian: the LSB precedes the MSB in memory. This is deprecated
+    /// and should be 0.
+    IMAGE_FILE_BYTES_REVERSED_LO       = 0x0080,
+    /// Machine is based on a 32bit word architecture.
+    IMAGE_FILE_32BIT_MACHINE           = 0x0100,
+    /// Debugging info has been removed.
+    IMAGE_FILE_DEBUG_STRIPPED          = 0x0200,
+    /// If the image is on removable media, fully load it and copy it to swap.
+    IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
+    /// If the image is on network media, fully load it and copy it to swap.
+    IMAGE_FILE_NET_RUN_FROM_SWAP       = 0x0800,
+    /// The image file is a system file, not a user program.
+    IMAGE_FILE_SYSTEM                  = 0x1000,
+    /// The image file is a DLL.
+    IMAGE_FILE_DLL                     = 0x2000,
+    /// This file should only be run on a uniprocessor machine.
+    IMAGE_FILE_UP_SYSTEM_ONLY          = 0x4000,
+    /// Big endian: the MSB precedes the LSB in memory. This is deprecated
+    /// and should be 0.
+    IMAGE_FILE_BYTES_REVERSED_HI       = 0x8000
+  };
+
+  struct symbol {
+    char     Name[NameSize];
+    uint32_t Value;
+    uint16_t SectionNumber;
+    uint16_t Type;
+    uint8_t  StorageClass;
+    uint8_t  NumberOfAuxSymbols;
+  };
+
+  enum SymbolFlags {
+    SF_TypeMask = 0x0000FFFF,
+    SF_TypeShift = 0,
+
+    SF_ClassMask = 0x00FF0000,
+    SF_ClassShift = 16,
+
+    SF_WeakExternal = 0x01000000
+  };
+
+  enum SymbolSectionNumber {
+    IMAGE_SYM_DEBUG     = 0xFFFE,
+    IMAGE_SYM_ABSOLUTE  = 0xFFFF,
+    IMAGE_SYM_UNDEFINED = 0
+  };
+
+  /// Storage class tells where and what the symbol represents
+  enum SymbolStorageClass {
+    SSC_Invalid = 0xff,
+
+    IMAGE_SYM_CLASS_END_OF_FUNCTION  = -1,  ///< Physical end of function
+    IMAGE_SYM_CLASS_NULL             = 0,   ///< No symbol
+    IMAGE_SYM_CLASS_AUTOMATIC        = 1,   ///< Stack variable
+    IMAGE_SYM_CLASS_EXTERNAL         = 2,   ///< External symbol
+    IMAGE_SYM_CLASS_STATIC           = 3,   ///< Static
+    IMAGE_SYM_CLASS_REGISTER         = 4,   ///< Register variable
+    IMAGE_SYM_CLASS_EXTERNAL_DEF     = 5,   ///< External definition
+    IMAGE_SYM_CLASS_LABEL            = 6,   ///< Label
+    IMAGE_SYM_CLASS_UNDEFINED_LABEL  = 7,   ///< Undefined label
+    IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8,   ///< Member of structure
+    IMAGE_SYM_CLASS_ARGUMENT         = 9,   ///< Function argument
+    IMAGE_SYM_CLASS_STRUCT_TAG       = 10,  ///< Structure tag
+    IMAGE_SYM_CLASS_MEMBER_OF_UNION  = 11,  ///< Member of union
+    IMAGE_SYM_CLASS_UNION_TAG        = 12,  ///< Union tag
+    IMAGE_SYM_CLASS_TYPE_DEFINITION  = 13,  ///< Type definition
+    IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14,  ///< Undefined static
+    IMAGE_SYM_CLASS_ENUM_TAG         = 15,  ///< Enumeration tag
+    IMAGE_SYM_CLASS_MEMBER_OF_ENUM   = 16,  ///< Member of enumeration
+    IMAGE_SYM_CLASS_REGISTER_PARAM   = 17,  ///< Register parameter
+    IMAGE_SYM_CLASS_BIT_FIELD        = 18,  ///< Bit field
+    /// ".bb" or ".eb" - beginning or end of block
+    IMAGE_SYM_CLASS_BLOCK            = 100,
+    /// ".bf" or ".ef" - beginning or end of function
+    IMAGE_SYM_CLASS_FUNCTION         = 101,
+    IMAGE_SYM_CLASS_END_OF_STRUCT    = 102, ///< End of structure
+    IMAGE_SYM_CLASS_FILE             = 103, ///< File name
+    /// Line number, reformatted as symbol
+    IMAGE_SYM_CLASS_SECTION          = 104,
+    IMAGE_SYM_CLASS_WEAK_EXTERNAL    = 105, ///< Duplicate tag
+    /// External symbol in dmert public lib
+    IMAGE_SYM_CLASS_CLR_TOKEN        = 107
+  };
+
+  enum SymbolBaseType {
+    IMAGE_SYM_TYPE_NULL   = 0,  ///< No type information or unknown base type.
+    IMAGE_SYM_TYPE_VOID   = 1,  ///< Used with void pointers and functions.
+    IMAGE_SYM_TYPE_CHAR   = 2,  ///< A character (signed byte).
+    IMAGE_SYM_TYPE_SHORT  = 3,  ///< A 2-byte signed integer.
+    IMAGE_SYM_TYPE_INT    = 4,  ///< A natural integer type on the target.
+    IMAGE_SYM_TYPE_LONG   = 5,  ///< A 4-byte signed integer.
+    IMAGE_SYM_TYPE_FLOAT  = 6,  ///< A 4-byte floating-point number.
+    IMAGE_SYM_TYPE_DOUBLE = 7,  ///< An 8-byte floating-point number.
+    IMAGE_SYM_TYPE_STRUCT = 8,  ///< A structure.
+    IMAGE_SYM_TYPE_UNION  = 9,  ///< An union.
+    IMAGE_SYM_TYPE_ENUM   = 10, ///< An enumerated type.
+    IMAGE_SYM_TYPE_MOE    = 11, ///< A member of enumeration (a specific value).
+    IMAGE_SYM_TYPE_BYTE   = 12, ///< A byte; unsigned 1-byte integer.
+    IMAGE_SYM_TYPE_WORD   = 13, ///< A word; unsigned 2-byte integer.
+    IMAGE_SYM_TYPE_UINT   = 14, ///< An unsigned integer of natural size.
+    IMAGE_SYM_TYPE_DWORD  = 15  ///< An unsigned 4-byte integer.
+  };
+
+  enum SymbolComplexType {
+    IMAGE_SYM_DTYPE_NULL     = 0, ///< No complex type; simple scalar variable.
+    IMAGE_SYM_DTYPE_POINTER  = 1, ///< A pointer to base type.
+    IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
+    IMAGE_SYM_DTYPE_ARRAY    = 3, ///< An array of base type.
+
+    /// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
+    SCT_COMPLEX_TYPE_SHIFT   = 4
+  };
+
+  enum AuxSymbolType {
+    IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
+  };
+
+  struct section {
+    char     Name[NameSize];
+    uint32_t VirtualSize;
+    uint32_t VirtualAddress;
+    uint32_t SizeOfRawData;
+    uint32_t PointerToRawData;
+    uint32_t PointerToRelocations;
+    uint32_t PointerToLineNumbers;
+    uint16_t NumberOfRelocations;
+    uint16_t NumberOfLineNumbers;
+    uint32_t Characteristics;
+  };
+
+  enum SectionCharacteristics : uint32_t {
+    SC_Invalid = 0xffffffff,
+
+    IMAGE_SCN_TYPE_NO_PAD            = 0x00000008,
+    IMAGE_SCN_CNT_CODE               = 0x00000020,
+    IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040,
+    IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
+    IMAGE_SCN_LNK_OTHER              = 0x00000100,
+    IMAGE_SCN_LNK_INFO               = 0x00000200,
+    IMAGE_SCN_LNK_REMOVE             = 0x00000800,
+    IMAGE_SCN_LNK_COMDAT             = 0x00001000,
+    IMAGE_SCN_GPREL                  = 0x00008000,
+    IMAGE_SCN_MEM_PURGEABLE          = 0x00020000,
+    IMAGE_SCN_MEM_16BIT              = 0x00020000,
+    IMAGE_SCN_MEM_LOCKED             = 0x00040000,
+    IMAGE_SCN_MEM_PRELOAD            = 0x00080000,
+    IMAGE_SCN_ALIGN_1BYTES           = 0x00100000,
+    IMAGE_SCN_ALIGN_2BYTES           = 0x00200000,
+    IMAGE_SCN_ALIGN_4BYTES           = 0x00300000,
+    IMAGE_SCN_ALIGN_8BYTES           = 0x00400000,
+    IMAGE_SCN_ALIGN_16BYTES          = 0x00500000,
+    IMAGE_SCN_ALIGN_32BYTES          = 0x00600000,
+    IMAGE_SCN_ALIGN_64BYTES          = 0x00700000,
+    IMAGE_SCN_ALIGN_128BYTES         = 0x00800000,
+    IMAGE_SCN_ALIGN_256BYTES         = 0x00900000,
+    IMAGE_SCN_ALIGN_512BYTES         = 0x00A00000,
+    IMAGE_SCN_ALIGN_1024BYTES        = 0x00B00000,
+    IMAGE_SCN_ALIGN_2048BYTES        = 0x00C00000,
+    IMAGE_SCN_ALIGN_4096BYTES        = 0x00D00000,
+    IMAGE_SCN_ALIGN_8192BYTES        = 0x00E00000,
+    IMAGE_SCN_LNK_NRELOC_OVFL        = 0x01000000,
+    IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000,
+    IMAGE_SCN_MEM_NOT_CACHED         = 0x04000000,
+    IMAGE_SCN_MEM_NOT_PAGED          = 0x08000000,
+    IMAGE_SCN_MEM_SHARED             = 0x10000000,
+    IMAGE_SCN_MEM_EXECUTE            = 0x20000000,
+    IMAGE_SCN_MEM_READ               = 0x40000000,
+    IMAGE_SCN_MEM_WRITE              = 0x80000000
+  };
+
+  struct relocation {
+    uint32_t VirtualAddress;
+    uint32_t SymbolTableIndex;
+    uint16_t Type;
+  };
+
+  enum RelocationTypeI386 {
+    IMAGE_REL_I386_ABSOLUTE = 0x0000,
+    IMAGE_REL_I386_DIR16    = 0x0001,
+    IMAGE_REL_I386_REL16    = 0x0002,
+    IMAGE_REL_I386_DIR32    = 0x0006,
+    IMAGE_REL_I386_DIR32NB  = 0x0007,
+    IMAGE_REL_I386_SEG12    = 0x0009,
+    IMAGE_REL_I386_SECTION  = 0x000A,
+    IMAGE_REL_I386_SECREL   = 0x000B,
+    IMAGE_REL_I386_TOKEN    = 0x000C,
+    IMAGE_REL_I386_SECREL7  = 0x000D,
+    IMAGE_REL_I386_REL32    = 0x0014
+  };
+
+  enum RelocationTypeAMD64 {
+    IMAGE_REL_AMD64_ABSOLUTE  = 0x0000,
+    IMAGE_REL_AMD64_ADDR64    = 0x0001,
+    IMAGE_REL_AMD64_ADDR32    = 0x0002,
+    IMAGE_REL_AMD64_ADDR32NB  = 0x0003,
+    IMAGE_REL_AMD64_REL32     = 0x0004,
+    IMAGE_REL_AMD64_REL32_1   = 0x0005,
+    IMAGE_REL_AMD64_REL32_2   = 0x0006,
+    IMAGE_REL_AMD64_REL32_3   = 0x0007,
+    IMAGE_REL_AMD64_REL32_4   = 0x0008,
+    IMAGE_REL_AMD64_REL32_5   = 0x0009,
+    IMAGE_REL_AMD64_SECTION   = 0x000A,
+    IMAGE_REL_AMD64_SECREL    = 0x000B,
+    IMAGE_REL_AMD64_SECREL7   = 0x000C,
+    IMAGE_REL_AMD64_TOKEN     = 0x000D,
+    IMAGE_REL_AMD64_SREL32    = 0x000E,
+    IMAGE_REL_AMD64_PAIR      = 0x000F,
+    IMAGE_REL_AMD64_SSPAN32   = 0x0010
+  };
+
+  enum RelocationTypesARM {
+    IMAGE_REL_ARM_ABSOLUTE  = 0x0000,
+    IMAGE_REL_ARM_ADDR32    = 0x0001,
+    IMAGE_REL_ARM_ADDR32NB  = 0x0002,
+    IMAGE_REL_ARM_BRANCH24  = 0x0003,
+    IMAGE_REL_ARM_BRANCH11  = 0x0004,
+    IMAGE_REL_ARM_TOKEN     = 0x0005,
+    IMAGE_REL_ARM_BLX24     = 0x0008,
+    IMAGE_REL_ARM_BLX11     = 0x0009,
+    IMAGE_REL_ARM_SECTION   = 0x000E,
+    IMAGE_REL_ARM_SECREL    = 0x000F,
+    IMAGE_REL_ARM_MOV32A    = 0x0010,
+    IMAGE_REL_ARM_MOV32T    = 0x0011,
+    IMAGE_REL_ARM_BRANCH20T = 0x0012,
+    IMAGE_REL_ARM_BRANCH24T = 0x0014,
+    IMAGE_REL_ARM_BLX23T    = 0x0015
+  };
+
+  enum COMDATType {
+    IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
+    IMAGE_COMDAT_SELECT_ANY,
+    IMAGE_COMDAT_SELECT_SAME_SIZE,
+    IMAGE_COMDAT_SELECT_EXACT_MATCH,
+    IMAGE_COMDAT_SELECT_ASSOCIATIVE,
+    IMAGE_COMDAT_SELECT_LARGEST,
+    IMAGE_COMDAT_SELECT_NEWEST
+  };
+
+  // Auxiliary Symbol Formats
+  struct AuxiliaryFunctionDefinition {
+    uint32_t TagIndex;
+    uint32_t TotalSize;
+    uint32_t PointerToLinenumber;
+    uint32_t PointerToNextFunction;
+    char     unused[2];
+  };
+
+  struct AuxiliarybfAndefSymbol {
+    uint8_t  unused1[4];
+    uint16_t Linenumber;
+    uint8_t  unused2[6];
+    uint32_t PointerToNextFunction;
+    uint8_t  unused3[2];
+  };
+
+  struct AuxiliaryWeakExternal {
+    uint32_t TagIndex;
+    uint32_t Characteristics;
+    uint8_t  unused[10];
+  };
+
+  /// These are not documented in the spec, but are located in WinNT.h.
+  enum WeakExternalCharacteristics {
+    IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
+    IMAGE_WEAK_EXTERN_SEARCH_LIBRARY   = 2,
+    IMAGE_WEAK_EXTERN_SEARCH_ALIAS     = 3
+  };
+
+  struct AuxiliaryFile {
+    uint8_t FileName[18];
+  };
+
+  struct AuxiliarySectionDefinition {
+    uint32_t Length;
+    uint16_t NumberOfRelocations;
+    uint16_t NumberOfLinenumbers;
+    uint32_t CheckSum;
+    uint16_t Number;
+    uint8_t  Selection;
+    char     unused[3];
+  };
+
+  struct AuxiliaryCLRToken {
+    uint8_t  AuxType;
+    uint8_t  unused1;
+    uint32_t SymbolTableIndex;
+    char     unused2[12];
+  };
+
+  union Auxiliary {
+    AuxiliaryFunctionDefinition FunctionDefinition;
+    AuxiliarybfAndefSymbol      bfAndefSymbol;
+    AuxiliaryWeakExternal       WeakExternal;
+    AuxiliaryFile               File;
+    AuxiliarySectionDefinition  SectionDefinition;
+  };
+
+  /// @brief The Import Directory Table.
+  ///
+  /// There is a single array of these and one entry per imported DLL.
+  struct ImportDirectoryTableEntry {
+    uint32_t ImportLookupTableRVA;
+    uint32_t TimeDateStamp;
+    uint32_t ForwarderChain;
+    uint32_t NameRVA;
+    uint32_t ImportAddressTableRVA;
+  };
+
+  /// @brief The PE32 Import Lookup Table.
+  ///
+  /// There is an array of these for each imported DLL. It represents either
+  /// the ordinal to import from the target DLL, or a name to lookup and import
+  /// from the target DLL.
+  ///
+  /// This also happens to be the same format used by the Import Address Table
+  /// when it is initially written out to the image.
+  struct ImportLookupTableEntry32 {
+    uint32_t data;
+
+    /// @brief Is this entry specified by ordinal, or name?
+    bool isOrdinal() const { return data & 0x80000000; }
+
+    /// @brief Get the ordinal value of this entry. isOrdinal must be true.
+    uint16_t getOrdinal() const {
+      assert(isOrdinal() && "ILT entry is not an ordinal!");
+      return data & 0xFFFF;
+    }
+
+    /// @brief Set the ordinal value and set isOrdinal to true.
+    void setOrdinal(uint16_t o) {
+      data = o;
+      data |= 0x80000000;
+    }
+
+    /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
+    uint32_t getHintNameRVA() const {
+      assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+      return data;
+    }
+
+    /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
+    void setHintNameRVA(uint32_t rva) { data = rva; }
+  };
+
+  /// @brief The DOS compatible header at the front of all PEs.
+  struct DOSHeader {
+    uint16_t Magic;
+    uint16_t UsedBytesInTheLastPage;
+    uint16_t FileSizeInPages;
+    uint16_t NumberOfRelocationItems;
+    uint16_t HeaderSizeInParagraphs;
+    uint16_t MinimumExtraParagraphs;
+    uint16_t MaximumExtraParagraphs;
+    uint16_t InitialRelativeSS;
+    uint16_t InitialSP;
+    uint16_t Checksum;
+    uint16_t InitialIP;
+    uint16_t InitialRelativeCS;
+    uint16_t AddressOfRelocationTable;
+    uint16_t OverlayNumber;
+    uint16_t Reserved[4];
+    uint16_t OEMid;
+    uint16_t OEMinfo;
+    uint16_t Reserved2[10];
+    uint32_t AddressOfNewExeHeader;
+  };
+
+  struct PE32Header {
+    enum {
+      PE32 = 0x10b,
+      PE32_PLUS = 0x20b
+    };
+
+    uint16_t Magic;
+    uint8_t  MajorLinkerVersion;
+    uint8_t  MinorLinkerVersion;
+    uint32_t SizeOfCode;
+    uint32_t SizeOfInitializedData;
+    uint32_t SizeOfUninitializedData;
+    uint32_t AddressOfEntryPoint; // RVA
+    uint32_t BaseOfCode; // RVA
+    uint32_t BaseOfData; // RVA
+    uint32_t ImageBase;
+    uint32_t SectionAlignment;
+    uint32_t FileAlignment;
+    uint16_t MajorOperatingSystemVersion;
+    uint16_t MinorOperatingSystemVersion;
+    uint16_t MajorImageVersion;
+    uint16_t MinorImageVersion;
+    uint16_t MajorSubsystemVersion;
+    uint16_t MinorSubsystemVersion;
+    uint32_t Win32VersionValue;
+    uint32_t SizeOfImage;
+    uint32_t SizeOfHeaders;
+    uint32_t CheckSum;
+    uint16_t Subsystem;
+    uint16_t DLLCharacteristics;
+    uint32_t SizeOfStackReserve;
+    uint32_t SizeOfStackCommit;
+    uint32_t SizeOfHeapReserve;
+    uint32_t SizeOfHeapCommit;
+    uint32_t LoaderFlags;
+    uint32_t NumberOfRvaAndSize;
+  };
+
+  struct DataDirectory {
+    uint32_t RelativeVirtualAddress;
+    uint32_t Size;
+  };
+
+  enum DataDirectoryIndex {
+    EXPORT_TABLE = 0,
+    IMPORT_TABLE,
+    RESOURCE_TABLE,
+    EXCEPTION_TABLE,
+    CERTIFICATE_TABLE,
+    BASE_RELOCATION_TABLE,
+    DEBUG,
+    ARCHITECTURE,
+    GLOBAL_PTR,
+    TLS_TABLE,
+    LOAD_CONFIG_TABLE,
+    BOUND_IMPORT,
+    IAT,
+    DELAY_IMPORT_DESCRIPTOR,
+    CLR_RUNTIME_HEADER
+  };
+
+  enum WindowsSubsystem {
+    IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
+    IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
+    IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
+    IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
+    IMAGE_SUBSYSTEM_OS2_CUI = 5, ///< The OS/2 character subsytem.
+    IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
+    IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8, ///< Native Windows 9x driver.
+    IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
+    IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
+    IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
+                                                  ///  services.
+    IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
+                                             ///  services.
+    IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
+    IMAGE_SUBSYSTEM_XBOX = 14, ///< XBOX.
+    IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16 ///< A BCD application.
+  };
+
+  enum DLLCharacteristics {
+    /// ASLR with 64 bit address space.
+    IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
+    /// DLL can be relocated at load time.
+    IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
+    /// Code integrity checks are enforced.
+    IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
+    ///< Image is NX compatible.
+    IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
+    /// Isolation aware, but do not isolate the image.
+    IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
+    /// Does not use structured exception handling (SEH). No SEH handler may be
+    /// called in this image.
+    IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
+    /// Do not bind the image.
+    IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
+    ///< Image should execute in an AppContainer.
+    IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000,
+    ///< A WDM driver.
+    IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000,
+    ///< Image supports Control Flow Guard.
+    IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000,
+    /// Terminal Server aware.
+    IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
+  };
+
+  enum DebugType {
+    IMAGE_DEBUG_TYPE_UNKNOWN       = 0,
+    IMAGE_DEBUG_TYPE_COFF          = 1,
+    IMAGE_DEBUG_TYPE_CODEVIEW      = 2,
+    IMAGE_DEBUG_TYPE_FPO           = 3,
+    IMAGE_DEBUG_TYPE_MISC          = 4,
+    IMAGE_DEBUG_TYPE_EXCEPTION     = 5,
+    IMAGE_DEBUG_TYPE_FIXUP         = 6,
+    IMAGE_DEBUG_TYPE_OMAP_TO_SRC   = 7,
+    IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
+    IMAGE_DEBUG_TYPE_BORLAND       = 9,
+    IMAGE_DEBUG_TYPE_CLSID         = 11
+  };
+
+  enum BaseRelocationType {
+    IMAGE_REL_BASED_ABSOLUTE       = 0,
+    IMAGE_REL_BASED_HIGH           = 1,
+    IMAGE_REL_BASED_LOW            = 2,
+    IMAGE_REL_BASED_HIGHLOW        = 3,
+    IMAGE_REL_BASED_HIGHADJ        = 4,
+    IMAGE_REL_BASED_MIPS_JMPADDR   = 5,
+    IMAGE_REL_BASED_ARM_MOV32A     = 5,
+    IMAGE_REL_BASED_ARM_MOV32T     = 7,
+    IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
+    IMAGE_REL_BASED_DIR64          = 10
+  };
+
+  enum ImportType {
+    IMPORT_CODE  = 0,
+    IMPORT_DATA  = 1,
+    IMPORT_CONST = 2
+  };
+
+  enum ImportNameType {
+    /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
+    /// field of the import header is the import's ordinal. If this constant is
+    /// not specified, then the Ordinal/Hint field should always be interpreted
+    /// as the import's hint.
+    IMPORT_ORDINAL         = 0,
+    /// The import name is identical to the public symbol name
+    IMPORT_NAME            = 1,
+    /// The import name is the public symbol name, but skipping the leading ?,
+    /// @, or optionally _.
+    IMPORT_NAME_NOPREFIX   = 2,
+    /// The import name is the public symbol name, but skipping the leading ?,
+    /// @, or optionally _, and truncating at the first @.
+    IMPORT_NAME_UNDECORATE = 3
+  };
+
+  struct ImportHeader {
+    uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
+    uint16_t Sig2; ///< Must be 0xFFFF.
+    uint16_t Version;
+    uint16_t Machine;
+    uint32_t TimeDateStamp;
+    uint32_t SizeOfData;
+    uint16_t OrdinalHint;
+    uint16_t TypeInfo;
+
+    ImportType getType() const {
+      return static_cast<ImportType>(TypeInfo & 0x3);
+    }
+
+    ImportNameType getNameType() const {
+      return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 3);
+    }
+  };
+
+  enum CodeViewLineTableIdentifiers {
+    DEBUG_SECTION_MAGIC           = 0x4,
+    DEBUG_LINE_TABLE_SUBSECTION   = 0xF2,
+    DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
+    DEBUG_INDEX_SUBSECTION        = 0xF4
+  };
+
+  inline bool isReservedSectionNumber(int N) {
+    return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections;
+  }
+
+} // End namespace COFF.
+} // End namespace llvm.
+
+#endif
diff --git a/include/llvm/Support/Capacity.h b/include/llvm/Support/Capacity.h
new file mode 100644
index 0000000..7460f98
--- /dev/null
+++ b/include/llvm/Support/Capacity.h
@@ -0,0 +1,32 @@
+//===--- Capacity.h - Generic computation of ADT memory use -----*- 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 capacity function that computes the amount of
+// memory used by an ADT.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CAPACITY_H
+#define LLVM_SUPPORT_CAPACITY_H
+
+#include <cstddef>
+
+namespace llvm {
+
+template <typename T>
+static inline size_t capacity_in_bytes(const T &x) {
+  // This default definition of capacity should work for things like std::vector
+  // and friends.  More specialized versions will work for others.
+  return x.capacity() * sizeof(typename T::value_type);
+}
+
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
new file mode 100644
index 0000000..beed31a
--- /dev/null
+++ b/include/llvm/Support/Casting.h
@@ -0,0 +1,292 @@
+//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- 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 isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
+// and dyn_cast_or_null<X>() templates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CASTING_H
+#define LLVM_SUPPORT_CASTING_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//                          isa<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+// Define a template that can be specialized by smart pointers to reflect the
+// fact that they are automatically dereferenced, and are not involved with the
+// template selection process...  the default implementation is a noop.
+//
+template<typename From> struct simplify_type {
+  typedef       From SimpleType;        // The real type this represents...
+
+  // An accessor to get the real value...
+  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
+};
+
+template<typename From> struct simplify_type<const From> {
+  typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
+  typedef typename add_const_past_pointer<NonConstSimpleType>::type
+    SimpleType;
+  typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
+    RetType;
+  static RetType getSimplifiedValue(const From& Val) {
+    return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
+  }
+};
+
+// The core of the implementation of isa<X> is here; To and From should be
+// the names of classes.  This template can be specialized to customize the
+// implementation of isa<> without rewriting it from scratch.
+template <typename To, typename From, typename Enabler = void>
+struct isa_impl {
+  static inline bool doit(const From &Val) {
+    return To::classof(&Val);
+  }
+};
+
+/// \brief Always allow upcasts, and perform no dynamic check for them.
+template <typename To, typename From>
+struct isa_impl<
+    To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
+  static inline bool doit(const From &) { return true; }
+};
+
+template <typename To, typename From> struct isa_impl_cl {
+  static inline bool doit(const From &Val) {
+    return isa_impl<To, From>::doit(Val);
+  }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, const From> {
+  static inline bool doit(const From &Val) {
+    return isa_impl<To, From>::doit(Val);
+  }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, From*> {
+  static inline bool doit(const From *Val) {
+    assert(Val && "isa<> used on a null pointer");
+    return isa_impl<To, From>::doit(*Val);
+  }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, From*const> {
+  static inline bool doit(const From *Val) {
+    assert(Val && "isa<> used on a null pointer");
+    return isa_impl<To, From>::doit(*Val);
+  }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, const From*> {
+  static inline bool doit(const From *Val) {
+    assert(Val && "isa<> used on a null pointer");
+    return isa_impl<To, From>::doit(*Val);
+  }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
+  static inline bool doit(const From *Val) {
+    assert(Val && "isa<> used on a null pointer");
+    return isa_impl<To, From>::doit(*Val);
+  }
+};
+
+template<typename To, typename From, typename SimpleFrom>
+struct isa_impl_wrap {
+  // When From != SimplifiedType, we can simplify the type some more by using
+  // the simplify_type template.
+  static bool doit(const From &Val) {
+    return isa_impl_wrap<To, SimpleFrom,
+      typename simplify_type<SimpleFrom>::SimpleType>::doit(
+                          simplify_type<const From>::getSimplifiedValue(Val));
+  }
+};
+
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, FromTy, FromTy> {
+  // When From == SimpleType, we are as simple as we are going to get.
+  static bool doit(const FromTy &Val) {
+    return isa_impl_cl<To,FromTy>::doit(Val);
+  }
+};
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument.  Used like this:
+//
+//  if (isa<Type>(myVal)) { ... }
+//
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) {
+  return isa_impl_wrap<X, const Y,
+                       typename simplify_type<const Y>::SimpleType>::doit(Val);
+}
+
+//===----------------------------------------------------------------------===//
+//                          cast<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<class To, class From> struct cast_retty;
+
+
+// Calculate what type the 'cast' function should return, based on a requested
+// type of To and a source type of From.
+template<class To, class From> struct cast_retty_impl {
+  typedef To& ret_type;         // Normal case, return Ty&
+};
+template<class To, class From> struct cast_retty_impl<To, const From> {
+  typedef const To &ret_type;   // Normal case, return Ty&
+};
+
+template<class To, class From> struct cast_retty_impl<To, From*> {
+  typedef To* ret_type;         // Pointer arg case, return Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*> {
+  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*const> {
+  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
+};
+
+
+template<class To, class From, class SimpleFrom>
+struct cast_retty_wrap {
+  // When the simplified type and the from type are not the same, use the type
+  // simplifier to reduce the type, then reuse cast_retty_impl to get the
+  // resultant type.
+  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+};
+
+template<class To, class FromTy>
+struct cast_retty_wrap<To, FromTy, FromTy> {
+  // When the simplified type is equal to the from type, use it directly.
+  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+};
+
+template<class To, class From>
+struct cast_retty {
+  typedef typename cast_retty_wrap<To, From,
+                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
+};
+
+// Ensure the non-simple values are converted using the simplify_type template
+// that may be specialized by smart pointers...
+//
+template<class To, class From, class SimpleFrom> struct cast_convert_val {
+  // This is not a simple type, use the template to simplify it...
+  static typename cast_retty<To, From>::ret_type doit(From &Val) {
+    return cast_convert_val<To, SimpleFrom,
+      typename simplify_type<SimpleFrom>::SimpleType>::doit(
+                          simplify_type<From>::getSimplifiedValue(Val));
+  }
+};
+
+template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
+  // This _is_ a simple type, just cast it.
+  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
+    typename cast_retty<To, FromTy>::ret_type Res2
+     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
+    return Res2;
+  }
+};
+
+template <class X> struct is_simple_type {
+  static const bool value =
+      std::is_same<X, typename simplify_type<X>::SimpleType>::value;
+};
+
+// cast<X> - Return the argument parameter cast to the specified type.  This
+// casting operator asserts that the type is correct, so it does not return null
+// on failure.  It does not allow a null argument (use cast_or_null for that).
+// It is typically used like this:
+//
+//  cast<Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+inline typename std::enable_if<!is_simple_type<Y>::value,
+                               typename cast_retty<X, const Y>::ret_type>::type
+cast(const Y &Val) {
+  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+  return cast_convert_val<
+      X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
+}
+
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
+  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+  return cast_convert_val<X, Y,
+                          typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+template <class X, class Y>
+inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
+  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+  return cast_convert_val<X, Y*,
+                          typename simplify_type<Y*>::SimpleType>::doit(Val);
+}
+
+// cast_or_null<X> - Functionally identical to cast, except that a null value is
+// accepted.
+//
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+cast_or_null(Y *Val) {
+  if (!Val) return nullptr;
+  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
+  return cast<X>(Val);
+}
+
+
+// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
+// casting operator returns null if the argument is of the wrong type, so it can
+// be used to test for a type as well as cast if successful.  This should be
+// used in the context of an if statement like this:
+//
+//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
+//
+
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
+    !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
+dyn_cast(const Y &Val) {
+  return isa<X>(Val) ? cast<X>(Val) : nullptr;
+}
+
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type
+dyn_cast(Y &Val) {
+  return isa<X>(Val) ? cast<X>(Val) : nullptr;
+}
+
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast(Y *Val) {
+  return isa<X>(Val) ? cast<X>(Val) : nullptr;
+}
+
+// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
+// value is accepted.
+//
+template <class X, class Y>
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast_or_null(Y *Val) {
+  return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h
new file mode 100644
index 0000000..240eba6
--- /dev/null
+++ b/include/llvm/Support/CodeGen.h
@@ -0,0 +1,91 @@
+//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file define some types which define code generation concepts. For
+// example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CODEGEN_H
+#define LLVM_SUPPORT_CODEGEN_H
+
+#include "llvm-c/TargetMachine.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+  // Relocation model types.
+  namespace Reloc {
+    enum Model { Default, Static, PIC_, DynamicNoPIC };
+  }
+
+  // Code model types.
+  namespace CodeModel {
+    enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
+  }
+
+  // TLS models.
+  namespace TLSModel {
+    enum Model {
+      GeneralDynamic,
+      LocalDynamic,
+      InitialExec,
+      LocalExec
+    };
+  }
+
+  // Code generation optimization level.
+  namespace CodeGenOpt {
+    enum Level {
+      None,        // -O0
+      Less,        // -O1
+      Default,     // -O2, -Os
+      Aggressive   // -O3
+    };
+  }
+
+  // Create wrappers for C Binding types (see CBindingWrapping.h).
+  inline CodeModel::Model unwrap(LLVMCodeModel Model) {
+    switch (Model) {
+      case LLVMCodeModelDefault:
+        return CodeModel::Default;
+      case LLVMCodeModelJITDefault:
+        return CodeModel::JITDefault;
+      case LLVMCodeModelSmall:
+        return CodeModel::Small;
+      case LLVMCodeModelKernel:
+        return CodeModel::Kernel;
+      case LLVMCodeModelMedium:
+        return CodeModel::Medium;
+      case LLVMCodeModelLarge:
+        return CodeModel::Large;
+    }
+    return CodeModel::Default;
+  }
+
+  inline LLVMCodeModel wrap(CodeModel::Model Model) {
+    switch (Model) {
+      case CodeModel::Default:
+        return LLVMCodeModelDefault;
+      case CodeModel::JITDefault:
+        return LLVMCodeModelJITDefault;
+      case CodeModel::Small:
+        return LLVMCodeModelSmall;
+      case CodeModel::Kernel:
+        return LLVMCodeModelKernel;
+      case CodeModel::Medium:
+        return LLVMCodeModelMedium;
+      case CodeModel::Large:
+        return LLVMCodeModelLarge;
+    }
+    llvm_unreachable("Bad CodeModel!");
+  }
+}  // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
new file mode 100644
index 0000000..fdd9012
--- /dev/null
+++ b/include/llvm/Support/CommandLine.h
@@ -0,0 +1,1829 @@
+//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a command line argument processor that is useful when
+// creating a tool.  It provides a simple, minimalistic interface that is easily
+// extensible and supports nonlocal (library) command line options.
+//
+// Note that rather than trying to figure out what this code does, you should
+// read the library documentation located in docs/CommandLine.html or looks at
+// the many example usages in tools/*/*.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMMANDLINE_H
+#define LLVM_SUPPORT_COMMANDLINE_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <climits>
+#include <cstdarg>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+/// cl Namespace - This namespace contains all of the command line option
+/// processing machinery.  It is intentionally a short name to make qualified
+/// usage concise.
+namespace cl {
+
+//===----------------------------------------------------------------------===//
+// ParseCommandLineOptions - Command line option processing entry point.
+//
+void ParseCommandLineOptions(int argc, const char * const *argv,
+                             const char *Overview = nullptr);
+
+//===----------------------------------------------------------------------===//
+// ParseEnvironmentOptions - Environment variable option processing alternate
+//                           entry point.
+//
+void ParseEnvironmentOptions(const char *progName, const char *envvar,
+                             const char *Overview = nullptr);
+
+///===---------------------------------------------------------------------===//
+/// SetVersionPrinter - Override the default (LLVM specific) version printer
+///                     used to print out the version when --version is given
+///                     on the command line. This allows other systems using the
+///                     CommandLine utilities to print their own version string.
+void SetVersionPrinter(void (*func)());
+
+///===---------------------------------------------------------------------===//
+/// AddExtraVersionPrinter - Add an extra printer to use in addition to the
+///                          default one. This can be called multiple times,
+///                          and each time it adds a new function to the list
+///                          which will be called after the basic LLVM version
+///                          printing is complete. Each can then add additional
+///                          information specific to the tool.
+void AddExtraVersionPrinter(void (*func)());
+
+
+// PrintOptionValues - Print option values.
+// With -print-options print the difference between option values and defaults.
+// With -print-all-options print all option values.
+// (Currently not perfect, but best-effort.)
+void PrintOptionValues();
+
+// MarkOptionsChanged - Internal helper function.
+void MarkOptionsChanged();
+
+//===----------------------------------------------------------------------===//
+// Flags permitted to be passed to command line arguments
+//
+
+enum NumOccurrencesFlag {      // Flags for the number of occurrences allowed
+  Optional        = 0x00,      // Zero or One occurrence
+  ZeroOrMore      = 0x01,      // Zero or more occurrences allowed
+  Required        = 0x02,      // One occurrence required
+  OneOrMore       = 0x03,      // One or more occurrences required
+
+  // ConsumeAfter - Indicates that this option is fed anything that follows the
+  // last positional argument required by the application (it is an error if
+  // there are zero positional arguments, and a ConsumeAfter option is used).
+  // Thus, for example, all arguments to LLI are processed until a filename is
+  // found.  Once a filename is found, all of the succeeding arguments are
+  // passed, unprocessed, to the ConsumeAfter option.
+  //
+  ConsumeAfter    = 0x04
+};
+
+enum ValueExpected {           // Is a value required for the option?
+  // zero reserved for the unspecified value
+  ValueOptional   = 0x01,      // The value can appear... or not
+  ValueRequired   = 0x02,      // The value is required to appear!
+  ValueDisallowed = 0x03       // A value may not be specified (for flags)
+};
+
+enum OptionHidden {            // Control whether -help shows this option
+  NotHidden       = 0x00,      // Option included in -help & -help-hidden
+  Hidden          = 0x01,      // -help doesn't, but -help-hidden does
+  ReallyHidden    = 0x02       // Neither -help nor -help-hidden show this arg
+};
+
+// Formatting flags - This controls special features that the option might have
+// that cause it to be parsed differently...
+//
+// Prefix - This option allows arguments that are otherwise unrecognized to be
+// matched by options that are a prefix of the actual value.  This is useful for
+// cases like a linker, where options are typically of the form '-lfoo' or
+// '-L../../include' where -l or -L are the actual flags.  When prefix is
+// enabled, and used, the value for the flag comes from the suffix of the
+// argument.
+//
+// Grouping - With this option enabled, multiple letter options are allowed to
+// bunch together with only a single hyphen for the whole group.  This allows
+// emulation of the behavior that ls uses for example: ls -la === ls -l -a
+//
+
+enum FormattingFlags {
+  NormalFormatting = 0x00,     // Nothing special
+  Positional       = 0x01,     // Is a positional argument, no '-' required
+  Prefix           = 0x02,     // Can this option directly prefix its value?
+  Grouping         = 0x03      // Can this option group with other options?
+};
+
+enum MiscFlags {               // Miscellaneous flags to adjust argument
+  CommaSeparated     = 0x01,  // Should this cl::list split between commas?
+  PositionalEatsArgs = 0x02,  // Should this positional cl::list eat -args?
+  Sink               = 0x04   // Should this cl::list eat all unknown options?
+};
+
+//===----------------------------------------------------------------------===//
+// Option Category class
+//
+class OptionCategory {
+private:
+  const char *const Name;
+  const char *const Description;
+  void registerCategory();
+public:
+  OptionCategory(const char *const Name, const char *const Description = nullptr)
+      : Name(Name), Description(Description) { registerCategory(); }
+  const char *getName() const { return Name; }
+  const char *getDescription() const { return Description; }
+};
+
+// The general Option Category (used as default category).
+extern OptionCategory GeneralCategory;
+
+//===----------------------------------------------------------------------===//
+// Option Base class
+//
+class alias;
+class Option {
+  friend class alias;
+
+  // handleOccurrences - Overriden by subclasses to handle the value passed into
+  // an argument.  Should return true if there was an error processing the
+  // argument and the program should exit.
+  //
+  virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
+                                StringRef Arg) = 0;
+
+  virtual enum ValueExpected getValueExpectedFlagDefault() const {
+    return ValueOptional;
+  }
+
+  // Out of line virtual function to provide home for the class.
+  virtual void anchor();
+
+  int NumOccurrences;     // The number of times specified
+  // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid
+  // problems with signed enums in bitfields.
+  unsigned Occurrences : 3; // enum NumOccurrencesFlag
+  // not using the enum type for 'Value' because zero is an implementation
+  // detail representing the non-value
+  unsigned Value : 2;
+  unsigned HiddenFlag : 2; // enum OptionHidden
+  unsigned Formatting : 2; // enum FormattingFlags
+  unsigned Misc : 3;
+  unsigned Position;      // Position of last occurrence of the option
+  unsigned AdditionalVals;// Greater than 0 for multi-valued option.
+  Option *NextRegistered; // Singly linked list of registered options.
+
+public:
+  const char *ArgStr;   // The argument string itself (ex: "help", "o")
+  const char *HelpStr;  // The descriptive text message for -help
+  const char *ValueStr; // String describing what the value of this option is
+  OptionCategory *Category; // The Category this option belongs to
+
+  inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
+    return (enum NumOccurrencesFlag)Occurrences;
+  }
+  inline enum ValueExpected getValueExpectedFlag() const {
+    return Value ? ((enum ValueExpected)Value)
+              : getValueExpectedFlagDefault();
+  }
+  inline enum OptionHidden getOptionHiddenFlag() const {
+    return (enum OptionHidden)HiddenFlag;
+  }
+  inline enum FormattingFlags getFormattingFlag() const {
+    return (enum FormattingFlags)Formatting;
+  }
+  inline unsigned getMiscFlags() const {
+    return Misc;
+  }
+  inline unsigned getPosition() const { return Position; }
+  inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
+
+  // hasArgStr - Return true if the argstr != ""
+  bool hasArgStr() const { return ArgStr[0] != 0; }
+
+  //-------------------------------------------------------------------------===
+  // Accessor functions set by OptionModifiers
+  //
+  void setArgStr(const char *S) { ArgStr = S; }
+  void setDescription(const char *S) { HelpStr = S; }
+  void setValueStr(const char *S) { ValueStr = S; }
+  void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) {
+    Occurrences = Val;
+  }
+  void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; }
+  void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; }
+  void setFormattingFlag(enum FormattingFlags V) { Formatting = V; }
+  void setMiscFlag(enum MiscFlags M) { Misc |= M; }
+  void setPosition(unsigned pos) { Position = pos; }
+  void setCategory(OptionCategory &C) { Category = &C; }
+protected:
+  explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
+                  enum OptionHidden Hidden)
+    : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
+      HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
+      Position(0), AdditionalVals(0), NextRegistered(nullptr),
+      ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) {
+  }
+
+  inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
+public:
+  // addArgument - Register this argument with the commandline system.
+  //
+  void addArgument();
+
+  /// Unregisters this option from the CommandLine system.
+  ///
+  /// This option must have been the last option registered.
+  /// For testing purposes only.
+  void removeArgument();
+
+  Option *getNextRegisteredOption() const { return NextRegistered; }
+
+  // Return the width of the option tag for printing...
+  virtual size_t getOptionWidth() const = 0;
+
+  // printOptionInfo - Print out information about this option.  The
+  // to-be-maintained width is specified.
+  //
+  virtual void printOptionInfo(size_t GlobalWidth) const = 0;
+
+  virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
+
+  virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
+
+  // addOccurrence - Wrapper around handleOccurrence that enforces Flags.
+  //
+  virtual bool addOccurrence(unsigned pos, StringRef ArgName,
+                             StringRef Value, bool MultiArg = false);
+
+  // Prints option name followed by message.  Always returns true.
+  bool error(const Twine &Message, StringRef ArgName = StringRef());
+
+public:
+  inline int getNumOccurrences() const { return NumOccurrences; }
+  virtual ~Option() {}
+};
+
+
+//===----------------------------------------------------------------------===//
+// Command line option modifiers that can be used to modify the behavior of
+// command line option parsers...
+//
+
+// desc - Modifier to set the description shown in the -help output...
+struct desc {
+  const char *Desc;
+  desc(const char *Str) : Desc(Str) {}
+  void apply(Option &O) const { O.setDescription(Desc); }
+};
+
+// value_desc - Modifier to set the value description shown in the -help
+// output...
+struct value_desc {
+  const char *Desc;
+  value_desc(const char *Str) : Desc(Str) {}
+  void apply(Option &O) const { O.setValueStr(Desc); }
+};
+
+// init - Specify a default (initial) value for the command line argument, if
+// the default constructor for the argument type does not give you what you
+// want.  This is only valid on "opt" arguments, not on "list" arguments.
+//
+template<class Ty>
+struct initializer {
+  const Ty &Init;
+  initializer(const Ty &Val) : Init(Val) {}
+
+  template<class Opt>
+  void apply(Opt &O) const { O.setInitialValue(Init); }
+};
+
+template<class Ty>
+initializer<Ty> init(const Ty &Val) {
+  return initializer<Ty>(Val);
+}
+
+
+// location - Allow the user to specify which external variable they want to
+// store the results of the command line argument processing into, if they don't
+// want to store it in the option itself.
+//
+template<class Ty>
+struct LocationClass {
+  Ty &Loc;
+  LocationClass(Ty &L) : Loc(L) {}
+
+  template<class Opt>
+  void apply(Opt &O) const { O.setLocation(O, Loc); }
+};
+
+template<class Ty>
+LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+
+// cat - Specifiy the Option category for the command line argument to belong
+// to.
+struct cat {
+  OptionCategory &Category;
+  cat(OptionCategory &c) : Category(c) {}
+
+  template<class Opt>
+  void apply(Opt &O) const { O.setCategory(Category); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// OptionValue class
+
+// Support value comparison outside the template.
+struct GenericOptionValue {
+  virtual ~GenericOptionValue() {}
+  virtual bool compare(const GenericOptionValue &V) const = 0;
+
+private:
+  virtual void anchor();
+};
+
+template<class DataType> struct OptionValue;
+
+// The default value safely does nothing. Option value printing is only
+// best-effort.
+template<class DataType, bool isClass>
+struct OptionValueBase : public GenericOptionValue {
+  // Temporary storage for argument passing.
+  typedef OptionValue<DataType> WrapperType;
+
+  bool hasValue() const { return false; }
+
+  const DataType &getValue() const { llvm_unreachable("no default value"); }
+
+  // Some options may take their value from a different data type.
+  template<class DT>
+  void setValue(const DT& /*V*/) {}
+
+  bool compare(const DataType &/*V*/) const { return false; }
+
+  bool compare(const GenericOptionValue& /*V*/) const override {
+    return false;
+  }
+};
+
+// Simple copy of the option value.
+template<class DataType>
+class OptionValueCopy : public GenericOptionValue {
+  DataType Value;
+  bool Valid;
+public:
+  OptionValueCopy() : Valid(false) {}
+
+  bool hasValue() const { return Valid; }
+
+  const DataType &getValue() const {
+    assert(Valid && "invalid option value");
+    return Value;
+  }
+
+  void setValue(const DataType &V) { Valid = true; Value = V; }
+
+  bool compare(const DataType &V) const {
+    return Valid && (Value != V);
+  }
+
+  bool compare(const GenericOptionValue &V) const override {
+    const OptionValueCopy<DataType> &VC =
+      static_cast< const OptionValueCopy<DataType>& >(V);
+    if (!VC.hasValue()) return false;
+    return compare(VC.getValue());
+  }
+};
+
+// Non-class option values.
+template<class DataType>
+struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
+  typedef DataType WrapperType;
+};
+
+// Top-level option class.
+template<class DataType>
+struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
+  OptionValue() {}
+
+  OptionValue(const DataType& V) {
+    this->setValue(V);
+  }
+  // Some options may take their value from a different data type.
+  template<class DT>
+  OptionValue<DataType> &operator=(const DT& V) {
+    this->setValue(V);
+    return *this;
+  }
+};
+
+// Other safe-to-copy-by-value common option types.
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+  typedef cl::boolOrDefault WrapperType;
+
+  OptionValue() {}
+
+  OptionValue(const cl::boolOrDefault& V) {
+    this->setValue(V);
+  }
+  OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault& V) {
+    setValue(V);
+    return *this;
+  }
+private:
+  void anchor() override;
+};
+
+template<>
+struct OptionValue<std::string> : OptionValueCopy<std::string> {
+  typedef StringRef WrapperType;
+
+  OptionValue() {}
+
+  OptionValue(const std::string& V) {
+    this->setValue(V);
+  }
+  OptionValue<std::string> &operator=(const std::string& V) {
+    setValue(V);
+    return *this;
+  }
+private:
+  void anchor() override;
+};
+
+//===----------------------------------------------------------------------===//
+// Enum valued command line option
+//
+#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
+#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
+#define clEnumValEnd (reinterpret_cast<void*>(0))
+
+// values - For custom data types, allow specifying a group of values together
+// as the values that go into the mapping that the option handler uses.  Note
+// that the values list must always have a 0 at the end of the list to indicate
+// that the list has ended.
+//
+template<class DataType>
+class ValuesClass {
+  // Use a vector instead of a map, because the lists should be short,
+  // the overhead is less, and most importantly, it keeps them in the order
+  // inserted so we can print our option out nicely.
+  SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
+  void processValues(va_list Vals);
+public:
+  ValuesClass(const char *EnumName, DataType Val, const char *Desc,
+              va_list ValueArgs) {
+    // Insert the first value, which is required.
+    Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
+
+    // Process the varargs portion of the values...
+    while (const char *enumName = va_arg(ValueArgs, const char *)) {
+      DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
+      const char *EnumDesc = va_arg(ValueArgs, const char *);
+      Values.push_back(std::make_pair(enumName,      // Add value to value map
+                                      std::make_pair(EnumVal, EnumDesc)));
+    }
+  }
+
+  template<class Opt>
+  void apply(Opt &O) const {
+    for (size_t i = 0, e = Values.size(); i != e; ++i)
+      O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
+                                     Values[i].second.second);
+  }
+};
+
+template<class DataType>
+ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
+                                           const char *Desc, ...) {
+    va_list ValueArgs;
+    va_start(ValueArgs, Desc);
+    ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
+    va_end(ValueArgs);
+    return Vals;
+}
+
+//===----------------------------------------------------------------------===//
+// parser class - Parameterizable parser for different data types.  By default,
+// known data types (string, int, bool) have specialized parsers, that do what
+// you would expect.  The default parser, used for data types that are not
+// built-in, uses a mapping table to map specific options to values, which is
+// used, among other things, to handle enum types.
+
+//--------------------------------------------------
+// generic_parser_base - This class holds all the non-generic code that we do
+// not need replicated for every instance of the generic parser.  This also
+// allows us to put stuff into CommandLine.cpp
+//
+class generic_parser_base {
+protected:
+  class GenericOptionInfo {
+  public:
+    GenericOptionInfo(const char *name, const char *helpStr) :
+      Name(name), HelpStr(helpStr) {}
+    const char *Name;
+    const char *HelpStr;
+  };
+public:
+  virtual ~generic_parser_base() {}  // Base class should have virtual-dtor
+
+  // getNumOptions - Virtual function implemented by generic subclass to
+  // indicate how many entries are in Values.
+  //
+  virtual unsigned getNumOptions() const = 0;
+
+  // getOption - Return option name N.
+  virtual const char *getOption(unsigned N) const = 0;
+
+  // getDescription - Return description N
+  virtual const char *getDescription(unsigned N) const = 0;
+
+  // Return the width of the option tag for printing...
+  virtual size_t getOptionWidth(const Option &O) const;
+
+  virtual const GenericOptionValue &getOptionValue(unsigned N) const = 0;
+
+  // printOptionInfo - Print out information about this option.  The
+  // to-be-maintained width is specified.
+  //
+  virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+  void printGenericOptionDiff(const Option &O, const GenericOptionValue &V,
+                              const GenericOptionValue &Default,
+                              size_t GlobalWidth) const;
+
+  // printOptionDiff - print the value of an option and it's default.
+  //
+  // Template definition ensures that the option and default have the same
+  // DataType (via the same AnyOptionValue).
+  template<class AnyOptionValue>
+  void printOptionDiff(const Option &O, const AnyOptionValue &V,
+                       const AnyOptionValue &Default,
+                       size_t GlobalWidth) const {
+    printGenericOptionDiff(O, V, Default, GlobalWidth);
+  }
+
+  void initialize(Option &O) {
+    // All of the modifiers for the option have been processed by now, so the
+    // argstr field should be stable, copy it down now.
+    //
+    hasArgStr = O.hasArgStr();
+  }
+
+  void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+    // If there has been no argstr specified, that means that we need to add an
+    // argument for every possible option.  This ensures that our options are
+    // vectored to us.
+    if (!hasArgStr)
+      for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+        OptionNames.push_back(getOption(i));
+  }
+
+
+  enum ValueExpected getValueExpectedFlagDefault() const {
+    // If there is an ArgStr specified, then we are of the form:
+    //
+    //    -opt=O2   or   -opt O2  or  -optO2
+    //
+    // In which case, the value is required.  Otherwise if an arg str has not
+    // been specified, we are of the form:
+    //
+    //    -O2 or O2 or -la (where -l and -a are separate options)
+    //
+    // If this is the case, we cannot allow a value.
+    //
+    if (hasArgStr)
+      return ValueRequired;
+    else
+      return ValueDisallowed;
+  }
+
+  // findOption - Return the option number corresponding to the specified
+  // argument string.  If the option is not found, getNumOptions() is returned.
+  //
+  unsigned findOption(const char *Name);
+
+protected:
+  bool hasArgStr;
+};
+
+// Default parser implementation - This implementation depends on having a
+// mapping of recognized options to values of some sort.  In addition to this,
+// each entry in the mapping also tracks a help message that is printed with the
+// command line option for -help.  Because this is a simple mapping parser, the
+// data type can be any unsupported type.
+//
+template <class DataType>
+class parser : public generic_parser_base {
+protected:
+  class OptionInfo : public GenericOptionInfo {
+  public:
+    OptionInfo(const char *name, DataType v, const char *helpStr) :
+      GenericOptionInfo(name, helpStr), V(v) {}
+    OptionValue<DataType> V;
+  };
+  SmallVector<OptionInfo, 8> Values;
+public:
+  typedef DataType parser_data_type;
+
+  // Implement virtual functions needed by generic_parser_base
+  unsigned getNumOptions() const override { return unsigned(Values.size()); }
+  const char *getOption(unsigned N) const override { return Values[N].Name; }
+  const char *getDescription(unsigned N) const override {
+    return Values[N].HelpStr;
+  }
+
+  // getOptionValue - Return the value of option name N.
+  const GenericOptionValue &getOptionValue(unsigned N) const override {
+    return Values[N].V;
+  }
+
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) {
+    StringRef ArgVal;
+    if (hasArgStr)
+      ArgVal = Arg;
+    else
+      ArgVal = ArgName;
+
+    for (size_t i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].Name == ArgVal) {
+        V = Values[i].V.getValue();
+        return false;
+      }
+
+    return O.error("Cannot find option named '" + ArgVal + "'!");
+  }
+
+  /// addLiteralOption - Add an entry to the mapping table.
+  ///
+  template <class DT>
+  void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
+    assert(findOption(Name) == Values.size() && "Option already exists!");
+    OptionInfo X(Name, static_cast<DataType>(V), HelpStr);
+    Values.push_back(X);
+    MarkOptionsChanged();
+  }
+
+  /// removeLiteralOption - Remove the specified option.
+  ///
+  void removeLiteralOption(const char *Name) {
+    unsigned N = findOption(Name);
+    assert(N != Values.size() && "Option not found!");
+    Values.erase(Values.begin()+N);
+  }
+};
+
+//--------------------------------------------------
+// basic_parser - Super class of parsers to provide boilerplate code
+//
+class basic_parser_impl {  // non-template implementation of basic_parser<t>
+public:
+  virtual ~basic_parser_impl() {}
+
+  enum ValueExpected getValueExpectedFlagDefault() const {
+    return ValueRequired;
+  }
+
+  void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
+
+  void initialize(Option &) {}
+
+  // Return the width of the option tag for printing...
+  size_t getOptionWidth(const Option &O) const;
+
+  // printOptionInfo - Print out information about this option.  The
+  // to-be-maintained width is specified.
+  //
+  void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+  // printOptionNoValue - Print a placeholder for options that don't yet support
+  // printOptionDiff().
+  void printOptionNoValue(const Option &O, size_t GlobalWidth) const;
+
+  // getValueName - Overload in subclass to provide a better default value.
+  virtual const char *getValueName() const { return "value"; }
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  virtual void anchor();
+
+protected:
+  // A helper for basic_parser::printOptionDiff.
+  void printOptionName(const Option &O, size_t GlobalWidth) const;
+};
+
+// basic_parser - The real basic parser is just a template wrapper that provides
+// a typedef for the provided data type.
+//
+template<class DataType>
+class basic_parser : public basic_parser_impl {
+public:
+  typedef DataType parser_data_type;
+  typedef OptionValue<DataType> OptVal;
+};
+
+//--------------------------------------------------
+// parser<bool>
+//
+template<>
+class parser<bool> : public basic_parser<bool> {
+  const char *ArgStr;
+public:
+
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val);
+
+  template <class Opt>
+  void initialize(Opt &O) {
+    ArgStr = O.ArgStr;
+  }
+
+  enum ValueExpected getValueExpectedFlagDefault() const {
+    return ValueOptional;
+  }
+
+  // getValueName - Do not print =<value> at all.
+  const char *getValueName() const override { return nullptr; }
+
+  void printOptionDiff(const Option &O, bool V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+
+//--------------------------------------------------
+// parser<boolOrDefault>
+template<>
+class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val);
+
+  enum ValueExpected getValueExpectedFlagDefault() const {
+    return ValueOptional;
+  }
+
+  // getValueName - Do not print =<value> at all.
+  const char *getValueName() const override { return nullptr; }
+
+  void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+
+//--------------------------------------------------
+// parser<int>
+//
+template<>
+class parser<int> : public basic_parser<int> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "int"; }
+
+  void printOptionDiff(const Option &O, int V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+
+
+//--------------------------------------------------
+// parser<unsigned>
+//
+template<>
+class parser<unsigned> : public basic_parser<unsigned> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "uint"; }
+
+  void printOptionDiff(const Option &O, unsigned V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+
+//--------------------------------------------------
+// parser<unsigned long long>
+//
+template<>
+class parser<unsigned long long> : public basic_parser<unsigned long long> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg,
+             unsigned long long &Val);
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "uint"; }
+
+  void printOptionDiff(const Option &O, unsigned long long V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
+
+//--------------------------------------------------
+// parser<double>
+//
+template<>
+class parser<double> : public basic_parser<double> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "number"; }
+
+  void printOptionDiff(const Option &O, double V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+
+//--------------------------------------------------
+// parser<float>
+//
+template<>
+class parser<float> : public basic_parser<float> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "number"; }
+
+  void printOptionDiff(const Option &O, float V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+
+//--------------------------------------------------
+// parser<std::string>
+//
+template<>
+class parser<std::string> : public basic_parser<std::string> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &, StringRef, StringRef Arg, std::string &Value) {
+    Value = Arg.str();
+    return false;
+  }
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "string"; }
+
+  void printOptionDiff(const Option &O, StringRef V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+
+//--------------------------------------------------
+// parser<char>
+//
+template<>
+class parser<char> : public basic_parser<char> {
+public:
+  // parse - Return true on error.
+  bool parse(Option &, StringRef, StringRef Arg, char &Value) {
+    Value = Arg[0];
+    return false;
+  }
+
+  // getValueName - Overload in subclass to provide a better default value.
+  const char *getValueName() const override { return "char"; }
+
+  void printOptionDiff(const Option &O, char V, OptVal Default,
+                       size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
+
+//--------------------------------------------------
+// PrintOptionDiff
+//
+// This collection of wrappers is the intermediary between class opt and class
+// parser to handle all the template nastiness.
+
+// This overloaded function is selected by the generic parser.
+template<class ParserClass, class DT>
+void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
+                     const OptionValue<DT> &Default, size_t GlobalWidth) {
+  OptionValue<DT> OV = V;
+  P.printOptionDiff(O, OV, Default, GlobalWidth);
+}
+
+// This is instantiated for basic parsers when the parsed value has a different
+// type than the option value. e.g. HelpPrinter.
+template<class ParserDT, class ValDT>
+struct OptionDiffPrinter {
+  void print(const Option &O, const parser<ParserDT> P, const ValDT &/*V*/,
+             const OptionValue<ValDT> &/*Default*/, size_t GlobalWidth) {
+    P.printOptionNoValue(O, GlobalWidth);
+  }
+};
+
+// This is instantiated for basic parsers when the parsed value has the same
+// type as the option value.
+template<class DT>
+struct OptionDiffPrinter<DT, DT> {
+  void print(const Option &O, const parser<DT> P, const DT &V,
+             const OptionValue<DT> &Default, size_t GlobalWidth) {
+    P.printOptionDiff(O, V, Default, GlobalWidth);
+  }
+};
+
+// This overloaded function is selected by the basic parser, which may parse a
+// different type than the option type.
+template<class ParserClass, class ValDT>
+void printOptionDiff(
+  const Option &O,
+  const basic_parser<typename ParserClass::parser_data_type> &P,
+  const ValDT &V, const OptionValue<ValDT> &Default,
+  size_t GlobalWidth) {
+
+  OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer;
+  printer.print(O, static_cast<const ParserClass&>(P), V, Default,
+                GlobalWidth);
+}
+
+//===----------------------------------------------------------------------===//
+// applicator class - This class is used because we must use partial
+// specialization to handle literal string arguments specially (const char* does
+// not correctly respond to the apply method).  Because the syntax to use this
+// is a pain, we have the 'apply' method below to handle the nastiness...
+//
+template<class Mod> struct applicator {
+  template<class Opt>
+  static void opt(const Mod &M, Opt &O) { M.apply(O); }
+};
+
+// Handle const char* as a special case...
+template<unsigned n> struct applicator<char[n]> {
+  template<class Opt>
+  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<unsigned n> struct applicator<const char[n]> {
+  template<class Opt>
+  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<> struct applicator<const char*> {
+  template<class Opt>
+  static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+
+template<> struct applicator<NumOccurrencesFlag> {
+  static void opt(NumOccurrencesFlag N, Option &O) {
+    O.setNumOccurrencesFlag(N);
+  }
+};
+template<> struct applicator<ValueExpected> {
+  static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
+};
+template<> struct applicator<OptionHidden> {
+  static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
+};
+template<> struct applicator<FormattingFlags> {
+  static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
+};
+template<> struct applicator<MiscFlags> {
+  static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
+};
+
+// apply method - Apply a modifier to an option in a type safe way.
+template<class Mod, class Opt>
+void apply(const Mod &M, Opt *O) {
+  applicator<Mod>::opt(M, *O);
+}
+
+//===----------------------------------------------------------------------===//
+// opt_storage class
+
+// Default storage class definition: external storage.  This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, bool ExternalStorage, bool isClass>
+class opt_storage {
+  DataType *Location;   // Where to store the object...
+  OptionValue<DataType> Default;
+
+  void check_location() const {
+    assert(Location && "cl::location(...) not specified for a command "
+           "line option with external storage, "
+           "or cl::init specified before cl::location()!!");
+  }
+public:
+  opt_storage() : Location(nullptr) {}
+
+  bool setLocation(Option &O, DataType &L) {
+    if (Location)
+      return O.error("cl::location(x) specified more than once!");
+    Location = &L;
+    Default = L;
+    return false;
+  }
+
+  template<class T>
+  void setValue(const T &V, bool initial = false) {
+    check_location();
+    *Location = V;
+    if (initial)
+      Default = V;
+  }
+
+  DataType &getValue() { check_location(); return *Location; }
+  const DataType &getValue() const { check_location(); return *Location; }
+
+  operator DataType() const { return this->getValue(); }
+
+  const OptionValue<DataType> &getDefault() const { return Default; }
+};
+
+// Define how to hold a class type object, such as a string.  Since we can
+// inherit from a class, we do so.  This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class opt_storage<DataType,false,true> : public DataType {
+public:
+  OptionValue<DataType> Default;
+
+  template<class T>
+  void setValue(const T &V, bool initial = false) {
+    DataType::operator=(V);
+    if (initial)
+      Default = V;
+  }
+
+  DataType &getValue() { return *this; }
+  const DataType &getValue() const { return *this; }
+
+  const OptionValue<DataType> &getDefault() const { return Default; }
+};
+
+// Define a partial specialization to handle things we cannot inherit from.  In
+// this case, we store an instance through containment, and overload operators
+// to get at the value.
+//
+template<class DataType>
+class opt_storage<DataType, false, false> {
+public:
+  DataType Value;
+  OptionValue<DataType> Default;
+
+  // Make sure we initialize the value with the default constructor for the
+  // type.
+  opt_storage() : Value(DataType()), Default(DataType()) {}
+
+  template<class T>
+  void setValue(const T &V, bool initial = false) {
+    Value = V;
+    if (initial)
+      Default = V;
+  }
+  DataType &getValue() { return Value; }
+  DataType getValue() const { return Value; }
+
+  const OptionValue<DataType> &getDefault() const { return Default; }
+
+  operator DataType() const { return getValue(); }
+
+  // If the datatype is a pointer, support -> on it.
+  DataType operator->() const { return Value; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// opt - A scalar command line option.
+//
+template <class DataType, bool ExternalStorage = false,
+          class ParserClass = parser<DataType> >
+class opt : public Option,
+            public opt_storage<DataType, ExternalStorage,
+                               std::is_class<DataType>::value> {
+  ParserClass Parser;
+
+  bool handleOccurrence(unsigned pos, StringRef ArgName,
+                        StringRef Arg) override {
+    typename ParserClass::parser_data_type Val =
+       typename ParserClass::parser_data_type();
+    if (Parser.parse(*this, ArgName, Arg, Val))
+      return true;                            // Parse error!
+    this->setValue(Val);
+    this->setPosition(pos);
+    return false;
+  }
+
+  enum ValueExpected getValueExpectedFlagDefault() const override {
+    return Parser.getValueExpectedFlagDefault();
+  }
+  void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
+    return Parser.getExtraOptionNames(OptionNames);
+  }
+
+  // Forward printing stuff to the parser...
+  size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+  void printOptionInfo(size_t GlobalWidth) const override {
+    Parser.printOptionInfo(*this, GlobalWidth);
+  }
+
+  void printOptionValue(size_t GlobalWidth, bool Force) const override {
+    if (Force || this->getDefault().compare(this->getValue())) {
+      cl::printOptionDiff<ParserClass>(
+        *this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
+    }
+  }
+
+  void done() {
+    addArgument();
+    Parser.initialize(*this);
+  }
+public:
+  // setInitialValue - Used by the cl::init modifier...
+  void setInitialValue(const DataType &V) { this->setValue(V, true); }
+
+  ParserClass &getParser() { return Parser; }
+
+  template<class T>
+  DataType &operator=(const T &Val) {
+    this->setValue(Val);
+    return this->getValue();
+  }
+
+  // One option...
+  template<class M0t>
+  explicit opt(const M0t &M0) : Option(Optional, NotHidden) {
+    apply(M0, this);
+    done();
+  }
+
+  // Two options...
+  template<class M0t, class M1t>
+  opt(const M0t &M0, const M1t &M1) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this);
+    done();
+  }
+
+  // Three options...
+  template<class M0t, class M1t, class M2t>
+  opt(const M0t &M0, const M1t &M1,
+      const M2t &M2) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this);
+    done();
+  }
+  // Four options...
+  template<class M0t, class M1t, class M2t, class M3t>
+  opt(const M0t &M0, const M1t &M1, const M2t &M2,
+      const M3t &M3) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    done();
+  }
+  // Five options...
+  template<class M0t, class M1t, class M2t, class M3t, class M4t>
+  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+      const M4t &M4) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this);
+    done();
+  }
+  // Six options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t>
+  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+      const M4t &M4, const M5t &M5) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this);
+    done();
+  }
+  // Seven options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t>
+  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+      const M4t &M4, const M5t &M5,
+      const M6t &M6) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this);
+    done();
+  }
+  // Eight options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t, class M7t>
+  opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+      const M4t &M4, const M5t &M5, const M6t &M6,
+      const M7t &M7) : Option(Optional, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+    done();
+  }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+
+//===----------------------------------------------------------------------===//
+// list_storage class
+
+// Default storage class definition: external storage.  This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class list_storage {
+  StorageClass *Location;   // Where to store the object...
+
+public:
+  list_storage() : Location(0) {}
+
+  bool setLocation(Option &O, StorageClass &L) {
+    if (Location)
+      return O.error("cl::location(x) specified more than once!");
+    Location = &L;
+    return false;
+  }
+
+  template<class T>
+  void addValue(const T &V) {
+    assert(Location != 0 && "cl::location(...) not specified for a command "
+           "line option with external storage!");
+    Location->push_back(V);
+  }
+};
+
+
+// Define how to hold a class type object, such as a string.  Since we can
+// inherit from a class, we do so.  This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class list_storage<DataType, bool> : public std::vector<DataType> {
+public:
+  template<class T>
+  void addValue(const T &V) { std::vector<DataType>::push_back(V); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// list - A list of command line options.
+//
+template <class DataType, class Storage = bool,
+          class ParserClass = parser<DataType> >
+class list : public Option, public list_storage<DataType, Storage> {
+  std::vector<unsigned> Positions;
+  ParserClass Parser;
+
+  enum ValueExpected getValueExpectedFlagDefault() const override {
+    return Parser.getValueExpectedFlagDefault();
+  }
+  void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
+    return Parser.getExtraOptionNames(OptionNames);
+  }
+
+  bool handleOccurrence(unsigned pos, StringRef ArgName,
+                        StringRef Arg) override {
+    typename ParserClass::parser_data_type Val =
+      typename ParserClass::parser_data_type();
+    if (Parser.parse(*this, ArgName, Arg, Val))
+      return true;  // Parse Error!
+    list_storage<DataType, Storage>::addValue(Val);
+    setPosition(pos);
+    Positions.push_back(pos);
+    return false;
+  }
+
+  // Forward printing stuff to the parser...
+  size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+  void printOptionInfo(size_t GlobalWidth) const override {
+    Parser.printOptionInfo(*this, GlobalWidth);
+  }
+
+  // Unimplemented: list options don't currently store their default value.
+  void printOptionValue(size_t /*GlobalWidth*/,
+                        bool /*Force*/) const override {}
+
+  void done() {
+    addArgument();
+    Parser.initialize(*this);
+  }
+public:
+  ParserClass &getParser() { return Parser; }
+
+  unsigned getPosition(unsigned optnum) const {
+    assert(optnum < this->size() && "Invalid option index");
+    return Positions[optnum];
+  }
+
+  void setNumAdditionalVals(unsigned n) {
+    Option::setNumAdditionalVals(n);
+  }
+
+  // One option...
+  template<class M0t>
+  explicit list(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this);
+    done();
+  }
+  // Two options...
+  template<class M0t, class M1t>
+  list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this);
+    done();
+  }
+  // Three options...
+  template<class M0t, class M1t, class M2t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this);
+    done();
+  }
+  // Four options...
+  template<class M0t, class M1t, class M2t, class M3t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    done();
+  }
+  // Five options...
+  template<class M0t, class M1t, class M2t, class M3t, class M4t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this);
+    done();
+  }
+  // Six options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this);
+    done();
+  }
+  // Seven options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5, const M6t &M6)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this);
+    done();
+  }
+  // Eight options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t, class M7t>
+  list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5, const M6t &M6,
+       const M7t &M7) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+    done();
+  }
+};
+
+// multi_val - Modifier to set the number of additional values.
+struct multi_val {
+  unsigned AdditionalVals;
+  explicit multi_val(unsigned N) : AdditionalVals(N) {}
+
+  template <typename D, typename S, typename P>
+  void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits_storage class
+
+// Default storage class definition: external storage.  This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class bits_storage {
+  unsigned *Location;   // Where to store the bits...
+
+  template<class T>
+  static unsigned Bit(const T &V) {
+    unsigned BitPos = reinterpret_cast<unsigned>(V);
+    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+          "enum exceeds width of bit vector!");
+    return 1 << BitPos;
+  }
+
+public:
+  bits_storage() : Location(nullptr) {}
+
+  bool setLocation(Option &O, unsigned &L) {
+    if (Location)
+      return O.error("cl::location(x) specified more than once!");
+    Location = &L;
+    return false;
+  }
+
+  template<class T>
+  void addValue(const T &V) {
+    assert(Location != 0 && "cl::location(...) not specified for a command "
+           "line option with external storage!");
+    *Location |= Bit(V);
+  }
+
+  unsigned getBits() { return *Location; }
+
+  template<class T>
+  bool isSet(const T &V) {
+    return (*Location & Bit(V)) != 0;
+  }
+};
+
+
+// Define how to hold bits.  Since we can inherit from a class, we do so.
+// This makes us exactly compatible with the bits in all cases that it is used.
+//
+template<class DataType>
+class bits_storage<DataType, bool> {
+  unsigned Bits;   // Where to store the bits...
+
+  template<class T>
+  static unsigned Bit(const T &V) {
+    unsigned BitPos = (unsigned)V;
+    assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+          "enum exceeds width of bit vector!");
+    return 1 << BitPos;
+  }
+
+public:
+  template<class T>
+  void addValue(const T &V) {
+    Bits |=  Bit(V);
+  }
+
+  unsigned getBits() { return Bits; }
+
+  template<class T>
+  bool isSet(const T &V) {
+    return (Bits & Bit(V)) != 0;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits - A bit vector of command options.
+//
+template <class DataType, class Storage = bool,
+          class ParserClass = parser<DataType> >
+class bits : public Option, public bits_storage<DataType, Storage> {
+  std::vector<unsigned> Positions;
+  ParserClass Parser;
+
+  enum ValueExpected getValueExpectedFlagDefault() const override {
+    return Parser.getValueExpectedFlagDefault();
+  }
+  void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
+    return Parser.getExtraOptionNames(OptionNames);
+  }
+
+  bool handleOccurrence(unsigned pos, StringRef ArgName,
+                        StringRef Arg) override {
+    typename ParserClass::parser_data_type Val =
+      typename ParserClass::parser_data_type();
+    if (Parser.parse(*this, ArgName, Arg, Val))
+      return true;  // Parse Error!
+    this->addValue(Val);
+    setPosition(pos);
+    Positions.push_back(pos);
+    return false;
+  }
+
+  // Forward printing stuff to the parser...
+  size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+  void printOptionInfo(size_t GlobalWidth) const override {
+    Parser.printOptionInfo(*this, GlobalWidth);
+  }
+
+  // Unimplemented: bits options don't currently store their default values.
+  void printOptionValue(size_t /*GlobalWidth*/,
+                        bool /*Force*/) const override {}
+
+  void done() {
+    addArgument();
+    Parser.initialize(*this);
+  }
+public:
+  ParserClass &getParser() { return Parser; }
+
+  unsigned getPosition(unsigned optnum) const {
+    assert(optnum < this->size() && "Invalid option index");
+    return Positions[optnum];
+  }
+
+  // One option...
+  template<class M0t>
+  explicit bits(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this);
+    done();
+  }
+  // Two options...
+  template<class M0t, class M1t>
+  bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this);
+    done();
+  }
+  // Three options...
+  template<class M0t, class M1t, class M2t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this);
+    done();
+  }
+  // Four options...
+  template<class M0t, class M1t, class M2t, class M3t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    done();
+  }
+  // Five options...
+  template<class M0t, class M1t, class M2t, class M3t, class M4t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this);
+    done();
+  }
+  // Six options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this);
+    done();
+  }
+  // Seven options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5, const M6t &M6)
+    : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this);
+    done();
+  }
+  // Eight options...
+  template<class M0t, class M1t, class M2t, class M3t,
+           class M4t, class M5t, class M6t, class M7t>
+  bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+       const M4t &M4, const M5t &M5, const M6t &M6,
+       const M7t &M7) : Option(ZeroOrMore, NotHidden) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+    done();
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Aliased command line option (alias this name to a preexisting name)
+//
+
+class alias : public Option {
+  Option *AliasFor;
+  bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+                                StringRef Arg) override {
+    return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
+  }
+  bool addOccurrence(unsigned pos, StringRef /*ArgName*/,
+                     StringRef Value, bool MultiArg = false) override {
+    return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg);
+  }
+  // Handle printing stuff...
+  size_t getOptionWidth() const override;
+  void printOptionInfo(size_t GlobalWidth) const override;
+
+  // Aliases do not need to print their values.
+  void printOptionValue(size_t /*GlobalWidth*/,
+                        bool /*Force*/) const override {}
+
+  ValueExpected getValueExpectedFlagDefault() const override {
+    return AliasFor->getValueExpectedFlag();
+  }
+
+  void done() {
+    if (!hasArgStr())
+      error("cl::alias must have argument name specified!");
+    if (!AliasFor)
+      error("cl::alias must have an cl::aliasopt(option) specified!");
+      addArgument();
+  }
+public:
+  void setAliasFor(Option &O) {
+    if (AliasFor)
+      error("cl::alias must only have one cl::aliasopt(...) specified!");
+    AliasFor = &O;
+  }
+
+  // One option...
+  template<class M0t>
+  explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(nullptr) {
+    apply(M0, this);
+    done();
+  }
+  // Two options...
+  template<class M0t, class M1t>
+  alias(const M0t &M0, const M1t &M1)
+    : Option(Optional, Hidden), AliasFor(nullptr) {
+    apply(M0, this); apply(M1, this);
+    done();
+  }
+  // Three options...
+  template<class M0t, class M1t, class M2t>
+  alias(const M0t &M0, const M1t &M1, const M2t &M2)
+    : Option(Optional, Hidden), AliasFor(nullptr) {
+    apply(M0, this); apply(M1, this); apply(M2, this);
+    done();
+  }
+  // Four options...
+  template<class M0t, class M1t, class M2t, class M3t>
+  alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+    : Option(Optional, Hidden), AliasFor(nullptr) {
+    apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+    done();
+  }
+};
+
+// aliasfor - Modifier to set the option an alias aliases.
+struct aliasopt {
+  Option &Opt;
+  explicit aliasopt(Option &O) : Opt(O) {}
+  void apply(alias &A) const { A.setAliasFor(Opt); }
+};
+
+// extrahelp - provide additional help at the end of the normal help
+// output. All occurrences of cl::extrahelp will be accumulated and
+// printed to stderr at the end of the regular help, just before
+// exit is called.
+struct extrahelp {
+  const char * morehelp;
+  explicit extrahelp(const char* help);
+};
+
+void PrintVersionMessage();
+
+/// This function just prints the help message, exactly the same way as if the
+/// -help or -help-hidden option had been given on the command line.
+///
+/// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+///
+/// \param Hidden if true will print hidden options
+/// \param Categorized if true print options in categories
+void PrintHelpMessage(bool Hidden=false, bool Categorized=false);
+
+
+//===----------------------------------------------------------------------===//
+// Public interface for accessing registered options.
+//
+
+/// \brief Use this to get a StringMap to all registered named options
+/// (e.g. -help). Note \p Map Should be an empty StringMap.
+///
+/// \param [out] Map will be filled with mappings where the key is the
+/// Option argument string (e.g. "help") and value is the corresponding
+/// Option*.
+///
+/// Access to unnamed arguments (i.e. positional) are not provided because
+/// it is expected that the client already has access to these.
+///
+/// Typical usage:
+/// \code
+/// main(int argc,char* argv[]) {
+/// StringMap<llvm::cl::Option*> opts;
+/// llvm::cl::getRegisteredOptions(opts);
+/// assert(opts.count("help") == 1)
+/// opts["help"]->setDescription("Show alphabetical help information")
+/// // More code
+/// llvm::cl::ParseCommandLineOptions(argc,argv);
+/// //More code
+/// }
+/// \endcode
+///
+/// This interface is useful for modifying options in libraries that are out of
+/// the control of the client. The options should be modified before calling
+/// llvm::cl::ParseCommandLineOptions().
+void getRegisteredOptions(StringMap<Option*> &Map);
+
+//===----------------------------------------------------------------------===//
+// Standalone command line processing utilities.
+//
+
+/// \brief Saves strings in the inheritor's stable storage and returns a stable
+/// raw character pointer.
+class StringSaver {
+  virtual void anchor();
+public:
+  virtual const char *SaveString(const char *Str) = 0;
+  virtual ~StringSaver() {};  // Pacify -Wnon-virtual-dtor.
+};
+
+/// \brief Tokenizes a command line that can contain escapes and quotes.
+//
+/// The quoting rules match those used by GCC and other tools that use
+/// libiberty's buildargv() or expandargv() utilities, and do not match bash.
+/// They differ from buildargv() on treatment of backslashes that do not escape
+/// a special character to make it possible to accept most Windows file paths.
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver,
+                            SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Tokenizes a Windows command line which may contain quotes and escaped
+/// quotes.
+///
+/// See MSDN docs for CommandLineToArgvW for information on the quoting rules.
+/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
+                                SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief String tokenization function type.  Should be compatible with either
+/// Windows or Unix command line tokenizers.
+typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver,
+                                  SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Expand response files on a command line recursively using the given
+/// StringSaver and tokenization strategy.  Argv should contain the command line
+/// before expansion and will be modified in place.
+///
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows.
+/// \param [in,out] Argv Command line into which to expand response files.
+/// \return true if all @files were expanded successfully or there were none.
+bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
+                         SmallVectorImpl<const char *> &Argv);
+
+} // End namespace cl
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
new file mode 100644
index 0000000..25bf32a
--- /dev/null
+++ b/include/llvm/Support/Compiler.h
@@ -0,0 +1,361 @@
+//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- 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 several macros, based on the current compiler.  This allows
+// use of compiler-specific features in a way that remains portable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPILER_H
+#define LLVM_SUPPORT_COMPILER_H
+
+#include "llvm/Config/llvm-config.h"
+
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+#ifndef __has_extension
+# define __has_extension(x) 0
+#endif
+
+#ifndef __has_attribute
+# define __has_attribute(x) 0
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/// \macro __GNUC_PREREQ
+/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available.
+#ifndef __GNUC_PREREQ
+# if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#  define __GNUC_PREREQ(maj, min) \
+    ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+/// \macro LLVM_MSC_PREREQ
+/// \brief Is the compiler MSVC of at least the specified version?
+/// The common \param version values to check for are:
+///  * 1700: Microsoft Visual Studio 2012 / 11.0
+///  * 1800: Microsoft Visual Studio 2013 / 12.0
+#ifdef _MSC_VER
+#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
+
+// We require at least MSVC 2012.
+#if !LLVM_MSC_PREREQ(1700)
+#error LLVM requires at least MSVC 2012.
+#endif
+
+#else
+#define LLVM_MSC_PREREQ(version) 0
+#endif
+
+#ifndef _MSC_VER
+#define LLVM_NOEXCEPT noexcept
+#else
+#define LLVM_NOEXCEPT
+#endif
+
+/// \brief Does the compiler support r-value reference *this?
+///
+/// Sadly, this is separate from just r-value reference support because GCC
+/// implemented everything but this thus far. No release of GCC yet has support
+/// for this feature so it is enabled with Clang only.
+/// FIXME: This should change to a version check when GCC grows support for it.
+#if __has_feature(cxx_rvalue_references)
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
+#else
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
+#endif
+
+/// \macro LLVM_HAS_VARIADIC_TEMPLATES
+/// \brief Does this compiler support variadic templates.
+///
+/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
+#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
+# define LLVM_HAS_VARIADIC_TEMPLATES 1
+#else
+# define LLVM_HAS_VARIADIC_TEMPLATES 0
+#endif
+
+/// Expands to '&' if r-value references are supported.
+///
+/// This can be used to provide l-value/r-value overrides of member functions.
+/// The r-value override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+#define LLVM_LVALUE_FUNCTION &
+#else
+#define LLVM_LVALUE_FUNCTION
+#endif
+
+/// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it.
+/// Use to mark functions as uncallable. Member functions with this should
+/// be declared private so that some behavior is kept in C++03 mode.
+///
+/// class DontCopy {
+/// private:
+///   DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION;
+///   DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION;
+/// public:
+///   ...
+/// };
+#if __has_feature(cxx_deleted_functions) || \
+    defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
+#define LLVM_DELETED_FUNCTION = delete
+#else
+#define LLVM_DELETED_FUNCTION
+#endif
+
+#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define LLVM_CONSTEXPR constexpr
+#else
+# define LLVM_CONSTEXPR
+#endif
+
+/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
+/// into a shared library, then the class should be private to the library and
+/// not accessible from outside it.  Can also be used to mark variables and
+/// functions, making them private to any shared library they are linked into.
+/// On PE/COFF targets, library visibility is the default, so this isn't needed.
+#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) &&                    \
+    !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)
+#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
+#else
+#define LLVM_LIBRARY_VISIBILITY
+#endif
+
+#if __has_attribute(used) || __GNUC_PREREQ(3, 1)
+#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
+#else
+#define LLVM_ATTRIBUTE_USED
+#endif
+
+#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4)
+#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__))
+#else
+#define LLVM_ATTRIBUTE_UNUSED_RESULT
+#endif
+
+// Some compilers warn about unused functions. When a function is sometimes
+// used or not depending on build settings (e.g. a function only called from
+// within "assert"), this attribute can be used to suppress such warnings.
+//
+// However, it shouldn't be used for unused *variables*, as those have a much
+// more portable solution:
+//   (void)unused_var_name;
+// Prefer cast-to-void wherever it is sufficient.
+#if __has_attribute(unused) || __GNUC_PREREQ(3, 1)
+#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
+#else
+#define LLVM_ATTRIBUTE_UNUSED
+#endif
+
+// FIXME: Provide this for PE/COFF targets.
+#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) &&                          \
+    (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32))
+#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
+#else
+#define LLVM_ATTRIBUTE_WEAK
+#endif
+
+// Prior to clang 3.2, clang did not accept any spelling of
+// __has_attribute(const), so assume it is supported.
+#if defined(__clang__) || defined(__GNUC__)
+// aka 'CONST' but following LLVM Conventions.
+#define LLVM_READNONE __attribute__((__const__))
+#else
+#define LLVM_READNONE
+#endif
+
+#if __has_attribute(pure) || defined(__GNUC__)
+// aka 'PURE' but following LLVM Conventions.
+#define LLVM_READONLY __attribute__((__pure__))
+#else
+#define LLVM_READONLY
+#endif
+
+#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0)
+#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
+#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
+#else
+#define LLVM_LIKELY(EXPR) (EXPR)
+#define LLVM_UNLIKELY(EXPR) (EXPR)
+#endif
+
+// C++ doesn't support 'extern template' of template specializations.  GCC does,
+// but requires __extension__ before it.  In the header, use this:
+//   EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
+// in the .cpp file, use this:
+//   TEMPLATE_INSTANTIATION(class foo<bar>);
+#ifdef __GNUC__
+#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
+#define TEMPLATE_INSTANTIATION(X) template X
+#else
+#define EXTERN_TEMPLATE_INSTANTIATION(X)
+#define TEMPLATE_INSTANTIATION(X)
+#endif
+
+/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+/// mark a method "not for inlining".
+#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4)
+#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
+#else
+#define LLVM_ATTRIBUTE_NOINLINE
+#endif
+
+/// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+/// so, mark a method "always inline" because it is performance sensitive. GCC
+/// 3.4 supported this but is buggy in various cases and produces unimplemented
+/// errors, just use it in GCC 4.0 and later.
+#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0)
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+#ifdef __GNUC__
+#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
+#else
+#define LLVM_ATTRIBUTE_NORETURN
+#endif
+
+/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+/// pedantic diagnostics.
+#ifdef __GNUC__
+#define LLVM_EXTENSION __extension__
+#else
+#define LLVM_EXTENSION
+#endif
+
+// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
+#if __has_feature(attribute_deprecated_with_message)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+  decl __attribute__((deprecated(message)))
+#elif defined(__GNUC__)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+  decl __attribute__((deprecated))
+#elif defined(_MSC_VER)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+  __declspec(deprecated(message)) decl
+#else
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+  decl
+#endif
+
+/// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
+/// to an expression which states that it is undefined behavior for the
+/// compiler to reach this point.  Otherwise is not defined.
+#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5)
+# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
+#elif defined(_MSC_VER)
+# define LLVM_BUILTIN_UNREACHABLE __assume(false)
+#endif
+
+/// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
+/// which causes the program to exit abnormally.
+#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3)
+# define LLVM_BUILTIN_TRAP __builtin_trap()
+#else
+# define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
+#endif
+
+/// \macro LLVM_ASSUME_ALIGNED
+/// \brief Returns a pointer with an assumed alignment.
+#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7)
+# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
+#elif defined(LLVM_BUILTIN_UNREACHABLE)
+// As of today, clang does not support __builtin_assume_aligned.
+# define LLVM_ASSUME_ALIGNED(p, a) \
+           (((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
+#else
+# define LLVM_ASSUME_ALIGNED(p, a) (p)
+#endif
+
+/// \macro LLVM_FUNCTION_NAME
+/// \brief Expands to __func__ on compilers which support it.  Otherwise,
+/// expands to a compiler-dependent replacement.
+#if defined(_MSC_VER)
+# define LLVM_FUNCTION_NAME __FUNCTION__
+#else
+# define LLVM_FUNCTION_NAME __func__
+#endif
+
+/// \macro LLVM_MEMORY_SANITIZER_BUILD
+/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
+#if __has_feature(memory_sanitizer)
+# define LLVM_MEMORY_SANITIZER_BUILD 1
+# include <sanitizer/msan_interface.h>
+#else
+# define LLVM_MEMORY_SANITIZER_BUILD 0
+# define __msan_allocated_memory(p, size)
+# define __msan_unpoison(p, size)
+#endif
+
+/// \macro LLVM_ADDRESS_SANITIZER_BUILD
+/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+# define LLVM_ADDRESS_SANITIZER_BUILD 1
+#else
+# define LLVM_ADDRESS_SANITIZER_BUILD 0
+#endif
+
+/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST
+/// \brief Is unaligned memory access fast on the host machine.
+///
+/// Don't specialize on alignment for platforms where unaligned memory accesses
+/// generates the same code as aligned memory accesses for common types.
+#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \
+    defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \
+    defined(_X86_) || defined(__i386) || defined(__i386__)
+# define LLVM_IS_UNALIGNED_ACCESS_FAST 1
+#else
+# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
+#endif
+
+/// \macro LLVM_EXPLICIT
+/// \brief Expands to explicit on compilers which support explicit conversion
+/// operators. Otherwise expands to nothing.
+#if __has_feature(cxx_explicit_conversions) || \
+    defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
+#define LLVM_EXPLICIT explicit
+#else
+#define LLVM_EXPLICIT
+#endif
+
+/// \brief Does the compiler support generalized initializers (using braced
+/// lists and std::initializer_list).  While clang may claim it supports general
+/// initializers, if we're using MSVC's headers, we might not have a usable
+/// std::initializer list type from the STL.  Disable this for now.
+#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
+#define LLVM_HAS_INITIALIZER_LISTS 1
+#else
+#define LLVM_HAS_INITIALIZER_LISTS 0
+#endif
+
+/// \brief Mark debug helper function definitions like dump() that should not be
+/// stripped from debug builds.
+// FIXME: Move this to a private config.h as it's not usable in public headers.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
+#else
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
+#endif
+
+#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
new file mode 100644
index 0000000..8152b60
--- /dev/null
+++ b/include/llvm/Support/Compression.h
@@ -0,0 +1,59 @@
+//===-- llvm/Support/Compression.h ---Compression----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains basic functions for compression/uncompression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPRESSION_H
+#define LLVM_SUPPORT_COMPRESSION_H
+
+#include "llvm/Support/DataTypes.h"
+#include <memory>
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class StringRef;
+
+namespace zlib {
+
+enum CompressionLevel {
+  NoCompression,
+  DefaultCompression,
+  BestSpeedCompression,
+  BestSizeCompression
+};
+
+enum Status {
+  StatusOK,
+  StatusUnsupported,    // zlib is unavailable
+  StatusOutOfMemory,    // there was not enough memory
+  StatusBufferTooShort, // there was not enough room in the output buffer
+  StatusInvalidArg,     // invalid input parameter
+  StatusInvalidData     // data was corrupted or incomplete
+};
+
+bool isAvailable();
+
+Status compress(StringRef InputBuffer, SmallVectorImpl<char> &CompressedBuffer,
+                CompressionLevel Level = DefaultCompression);
+
+Status uncompress(StringRef InputBuffer,
+                  SmallVectorImpl<char> &UncompressedBuffer,
+                  size_t UncompressedSize);
+
+uint32_t crc32(StringRef Buffer);
+
+}  // End of namespace zlib
+
+} // End of namespace llvm
+
+#endif
+
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
new file mode 100644
index 0000000..a184d0d
--- /dev/null
+++ b/include/llvm/Support/ConvertUTF.h
@@ -0,0 +1,260 @@
+/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *==------------------------------------------------------------------------==*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
+
+    Several funtions are included here, forming a complete set of
+    conversions between the three formats.  UTF-7 is not included
+    here, but is handled in a separate source file.
+
+    Each of these routines takes pointers to input buffers and output
+    buffers.  The input buffers are const.
+
+    Each routine converts the text between *sourceStart and sourceEnd,
+    putting the result into the buffer between *targetStart and
+    targetEnd. Note: the end pointers are *after* the last item: e.g.
+    *(sourceEnd - 1) is the last item.
+
+    The return result indicates whether the conversion was successful,
+    and if not, whether the problem was in the source or target buffers.
+    (Only the first encountered problem is indicated.)
+
+    After the conversion, *sourceStart and *targetStart are both
+    updated to point to the end of last text successfully converted in
+    the respective buffers.
+
+    Input parameters:
+        sourceStart - pointer to a pointer to the source buffer.
+                The contents of this are modified on return so that
+                it points at the next thing to be converted.
+        targetStart - similarly, pointer to pointer to the target buffer.
+        sourceEnd, targetEnd - respectively pointers to the ends of the
+                two buffers, for overflow checking only.
+
+    These conversion functions take a ConversionFlags argument. When this
+    flag is set to strict, both irregular sequences and isolated surrogates
+    will cause an error.  When the flag is set to lenient, both irregular
+    sequences and isolated surrogates are converted.
+
+    Whether the flag is strict or lenient, all illegal sequences will cause
+    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+    must check for illegal sequences.
+
+    When the flag is set to lenient, characters over 0x10FFFF are converted
+    to the replacement character; otherwise (when the flag is set to strict)
+    they constitute an error.
+
+    Output parameters:
+        The value "sourceIllegal" is returned from some routines if the input
+        sequence is malformed.  When "sourceIllegal" is returned, the source
+        value will point to the illegal value that caused the problem. E.g.,
+        in UTF-8 when a sequence is malformed, it points to the start of the
+        malformed sequence.
+
+    Author: Mark E. Davis, 1994.
+    Rev History: Rick McGowan, fixes & updates May 2001.
+         Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+#ifndef LLVM_SUPPORT_CONVERTUTF_H
+#define LLVM_SUPPORT_CONVERTUTF_H
+
+/* ---------------------------------------------------------------------
+    The following 4 definitions are compiler-specific.
+    The C standard does not guarantee that wchar_t has at least
+    16 bits, so wchar_t is no less portable than unsigned short!
+    All should be unsigned values to avoid sign extension during
+    bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned int    UTF32;  /* at least 32 bits */
+typedef unsigned short  UTF16;  /* at least 16 bits */
+typedef unsigned char   UTF8;   /* typically 8 bits */
+typedef unsigned char   Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
+
+#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE  0xFEFF
+#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE
+
+typedef enum {
+  conversionOK,           /* conversion successful */
+  sourceExhausted,        /* partial character in source, but hit end */
+  targetExhausted,        /* insuff. room in target for conversion */
+  sourceIllegal           /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+  strictConversion = 0,
+  lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+  const UTF8** sourceStart, const UTF8* sourceEnd,
+  UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+/**
+ * Convert a partial UTF8 sequence to UTF32.  If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceExhausted.
+ */
+ConversionResult ConvertUTF8toUTF32Partial(
+  const UTF8** sourceStart, const UTF8* sourceEnd,
+  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+/**
+ * Convert a partial UTF8 sequence to UTF32.  If the sequence ends in an
+ * incomplete code unit sequence, returns \c sourceIllegal.
+ */
+ConversionResult ConvertUTF8toUTF32(
+  const UTF8** sourceStart, const UTF8* sourceEnd,
+  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (
+  const UTF16** sourceStart, const UTF16* sourceEnd,
+  UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+  const UTF32** sourceStart, const UTF32* sourceEnd,
+  UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (
+  const UTF16** sourceStart, const UTF16* sourceEnd,
+  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+  const UTF32** sourceStart, const UTF32* sourceEnd,
+  UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
+
+unsigned getNumBytesForUTF8(UTF8 firstByte);
+
+#ifdef __cplusplus
+}
+
+/*************************************************************************/
+/* Below are LLVM-specific wrappers of the functions above. */
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/**
+ * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
+ * WideCharWidth. The converted data is written to ResultPtr, which needs to
+ * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
+ * ResultPtr will point one after the end of the copied string. On failure,
+ * ResultPtr will not be changed, and ErrorPtr will be set to the location of
+ * the first character which could not be converted.
+ * \return true on success.
+ */
+bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
+                       char *&ResultPtr, const UTF8 *&ErrorPtr);
+
+/**
+ * Convert an Unicode code point to UTF8 sequence.
+ *
+ * \param Source a Unicode code point.
+ * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
+ * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes.  On success \c ResultPtr is
+ * updated one past end of the converted sequence.
+ *
+ * \returns true on success.
+ */
+bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
+
+/**
+ * Convert the first UTF8 sequence in the given source buffer to a UTF32
+ * code point.
+ *
+ * \param [in,out] source A pointer to the source buffer. If the conversion
+ * succeeds, this pointer will be updated to point to the byte just past the
+ * end of the converted sequence.
+ * \param sourceEnd A pointer just past the end of the source buffer.
+ * \param [out] target The converted code
+ * \param flags Whether the conversion is strict or lenient.
+ *
+ * \returns conversionOK on success
+ *
+ * \sa ConvertUTF8toUTF32
+ */
+static inline ConversionResult convertUTF8Sequence(const UTF8 **source,
+                                                   const UTF8 *sourceEnd,
+                                                   UTF32 *target,
+                                                   ConversionFlags flags) {
+  if (*source == sourceEnd)
+    return sourceExhausted;
+  unsigned size = getNumBytesForUTF8(**source);
+  if ((ptrdiff_t)size > sourceEnd - *source)
+    return sourceExhausted;
+  return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags);
+}
+
+/**
+ * Returns true if a blob of text starts with a UTF-16 big or little endian byte
+ * order mark.
+ */
+bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
+
+/**
+ * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
+ *
+ * \param [in] SrcBytes A buffer of what is assumed to be UTF-16 encoded text.
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
+
+} /* end namespace llvm */
+
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#endif
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
new file mode 100644
index 0000000..3869ebd
--- /dev/null
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -0,0 +1,211 @@
+//===--- CrashRecoveryContext.h - Crash Recovery ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
+#define LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
+
+#include <string>
+
+#include "llvm/ADT/STLExtras.h"
+
+namespace llvm {
+class StringRef;
+
+class CrashRecoveryContextCleanup;
+
+/// \brief Crash recovery helper object.
+///
+/// This class implements support for running operations in a safe context so
+/// that crashes (memory errors, stack overflow, assertion violations) can be
+/// detected and control restored to the crashing thread. Crash detection is
+/// purely "best effort", the exact set of failures which can be recovered from
+/// is platform dependent.
+///
+/// Clients make use of this code by first calling
+/// CrashRecoveryContext::Enable(), and then executing unsafe operations via a
+/// CrashRecoveryContext object. For example:
+///
+///    void actual_work(void *);
+///
+///    void foo() {
+///      CrashRecoveryContext CRC;
+///
+///      if (!CRC.RunSafely(actual_work, 0)) {
+///         ... a crash was detected, report error to user ...
+///      }
+///
+///      ... no crash was detected ...
+///    }
+///
+/// Crash recovery contexts may not be nested.
+class CrashRecoveryContext {
+  void *Impl;
+  CrashRecoveryContextCleanup *head;
+
+public:
+  CrashRecoveryContext() : Impl(nullptr), head(nullptr) {}
+  ~CrashRecoveryContext();
+
+  void registerCleanup(CrashRecoveryContextCleanup *cleanup);
+  void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
+
+  /// \brief Enable crash recovery.
+  static void Enable();
+
+  /// \brief Disable crash recovery.
+  static void Disable();
+
+  /// \brief Return the active context, if the code is currently executing in a
+  /// thread which is in a protected context.
+  static CrashRecoveryContext *GetCurrent();
+
+  /// \brief Return true if the current thread is recovering from a
+  /// crash.
+  static bool isRecoveringFromCrash();
+
+  /// \brief Execute the provide callback function (with the given arguments) in
+  /// a protected context.
+  ///
+  /// \return True if the function completed successfully, and false if the
+  /// function crashed (or HandleCrash was called explicitly). Clients should
+  /// make as little assumptions as possible about the program state when
+  /// RunSafely has returned false. Clients can use getBacktrace() to retrieve
+  /// the backtrace of the crash on failures.
+  bool RunSafely(function_ref<void()> Fn);
+  bool RunSafely(void (*Fn)(void*), void *UserData) {
+    return RunSafely([&]() { Fn(UserData); });
+  }
+
+  /// \brief Execute the provide callback function (with the given arguments) in
+  /// a protected context which is run in another thread (optionally with a
+  /// requested stack size).
+  ///
+  /// See RunSafely() and llvm_execute_on_thread().
+  ///
+  /// On Darwin, if PRIO_DARWIN_BG is set on the calling thread, it will be
+  /// propagated to the new thread as well.
+  bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0);
+  bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
+                         unsigned RequestedStackSize = 0) {
+    return RunSafelyOnThread([&]() { Fn(UserData); }, RequestedStackSize);
+  }
+
+  /// \brief Explicitly trigger a crash recovery in the current process, and
+  /// return failure from RunSafely(). This function does not return.
+  void HandleCrash();
+
+  /// \brief Return a string containing the backtrace where the crash was
+  /// detected; or empty if the backtrace wasn't recovered.
+  ///
+  /// This function is only valid when a crash has been detected (i.e.,
+  /// RunSafely() has returned false.
+  const std::string &getBacktrace() const;
+};
+
+class CrashRecoveryContextCleanup {
+protected:
+  CrashRecoveryContext *context;
+  CrashRecoveryContextCleanup(CrashRecoveryContext *context)
+    : context(context), cleanupFired(false) {}
+public:
+  bool cleanupFired;
+  
+  virtual ~CrashRecoveryContextCleanup();
+  virtual void recoverResources() = 0;
+
+  CrashRecoveryContext *getContext() const {
+    return context;
+  }
+
+private:
+  friend class CrashRecoveryContext;
+  CrashRecoveryContextCleanup *prev, *next;
+};
+
+template<typename DERIVED, typename T>
+class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup {
+protected:
+  T *resource;
+  CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource)
+    : CrashRecoveryContextCleanup(context), resource(resource) {}
+public:
+  static DERIVED *create(T *x) {
+    if (x) {
+      if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent())
+        return new DERIVED(context, x);
+    }
+    return 0;
+  }
+};
+
+template <typename T>
+class CrashRecoveryContextDestructorCleanup : public
+  CrashRecoveryContextCleanupBase<CrashRecoveryContextDestructorCleanup<T>, T> {
+public:
+  CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context,
+                                        T *resource) 
+    : CrashRecoveryContextCleanupBase<
+        CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {}
+
+  virtual void recoverResources() {
+    this->resource->~T();
+  }
+};
+
+template <typename T>
+class CrashRecoveryContextDeleteCleanup : public
+  CrashRecoveryContextCleanupBase<CrashRecoveryContextDeleteCleanup<T>, T> {
+public:
+  CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource)
+    : CrashRecoveryContextCleanupBase<
+        CrashRecoveryContextDeleteCleanup<T>, T>(context, resource) {}
+
+  virtual void recoverResources() {
+    delete this->resource;
+  }  
+};
+
+template <typename T>
+class CrashRecoveryContextReleaseRefCleanup : public
+  CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T>
+{
+public:
+  CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context, 
+                                        T *resource)
+    : CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>,
+          T>(context, resource) {}
+
+  virtual void recoverResources() {
+    this->resource->Release();
+  }
+};
+
+template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> >
+class CrashRecoveryContextCleanupRegistrar {
+  CrashRecoveryContextCleanup *cleanup;
+public:
+  CrashRecoveryContextCleanupRegistrar(T *x)
+    : cleanup(Cleanup::create(x)) {
+    if (cleanup)
+      cleanup->getContext()->registerCleanup(cleanup);
+  }
+
+  ~CrashRecoveryContextCleanupRegistrar() {
+    unregister();
+  }
+  
+  void unregister() {
+    if (cleanup && !cleanup->cleanupFired)
+      cleanup->getContext()->unregisterCleanup(cleanup);
+    cleanup = 0;
+  }
+};
+}
+
+#endif
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
new file mode 100644
index 0000000..95e37c0
--- /dev/null
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -0,0 +1,166 @@
+//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- 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 template class that can be used to customize dot output
+// graphs generated by the GraphWriter.h file.  The default implementation of
+// this file will produce a simple, but not very polished graph.  By
+// specializing this template, lots of customization opportunities are possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
+#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
+
+#include <string>
+
+namespace llvm {
+
+/// DefaultDOTGraphTraits - This class provides the default implementations of
+/// all of the DOTGraphTraits methods.  If a specialization does not need to
+/// override all methods here it should inherit so that it can get the default
+/// implementations.
+///
+struct DefaultDOTGraphTraits {
+private:
+  bool IsSimple;
+
+protected:
+  bool isSimple() {
+    return IsSimple;
+  }
+
+public:
+  explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {}
+
+  /// getGraphName - Return the label for the graph as a whole.  Printed at the
+  /// top of the graph.
+  ///
+  template<typename GraphType>
+  static std::string getGraphName(const GraphType &) { return ""; }
+
+  /// getGraphProperties - Return any custom properties that should be included
+  /// in the top level graph structure for dot.
+  ///
+  template<typename GraphType>
+  static std::string getGraphProperties(const GraphType &) {
+    return "";
+  }
+
+  /// renderGraphFromBottomUp - If this function returns true, the graph is
+  /// emitted bottom-up instead of top-down.  This requires graphviz 2.0 to work
+  /// though.
+  static bool renderGraphFromBottomUp() {
+    return false;
+  }
+
+  /// isNodeHidden - If the function returns true, the given node is not
+  /// displayed in the graph.
+  static bool isNodeHidden(const void *) {
+    return false;
+  }
+
+  /// getNodeLabel - Given a node and a pointer to the top level graph, return
+  /// the label to print in the node.
+  template<typename GraphType>
+  std::string getNodeLabel(const void *, const GraphType &) {
+    return "";
+  }
+
+  /// hasNodeAddressLabel - If this method returns true, the address of the node
+  /// is added to the label of the node.
+  template<typename GraphType>
+  static bool hasNodeAddressLabel(const void *, const GraphType &) {
+    return false;
+  }
+
+  template<typename GraphType>
+  static std::string getNodeDescription(const void *, const GraphType &) {
+    return "";
+  }
+
+  /// If you want to specify custom node attributes, this is the place to do so
+  ///
+  template<typename GraphType>
+  static std::string getNodeAttributes(const void *,
+                                       const GraphType &) {
+    return "";
+  }
+
+  /// If you want to override the dot attributes printed for a particular edge,
+  /// override this method.
+  template<typename EdgeIter, typename GraphType>
+  static std::string getEdgeAttributes(const void *, EdgeIter,
+                                       const GraphType &) {
+    return "";
+  }
+
+  /// getEdgeSourceLabel - If you want to label the edge source itself,
+  /// implement this method.
+  template<typename EdgeIter>
+  static std::string getEdgeSourceLabel(const void *, EdgeIter) {
+    return "";
+  }
+
+  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
+  /// should actually target another edge source, not a node.  If this method is
+  /// implemented, getEdgeTarget should be implemented.
+  template<typename EdgeIter>
+  static bool edgeTargetsEdgeSource(const void *, EdgeIter) {
+    return false;
+  }
+
+  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+  /// called to determine which outgoing edge of Node is the target of this
+  /// edge.
+  template<typename EdgeIter>
+  static EdgeIter getEdgeTarget(const void *, EdgeIter I) {
+    return I;
+  }
+
+  /// hasEdgeDestLabels - If this function returns true, the graph is able
+  /// to provide labels for edge destinations.
+  static bool hasEdgeDestLabels() {
+    return false;
+  }
+
+  /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
+  /// number of incoming edge labels the given node has.
+  static unsigned numEdgeDestLabels(const void *) {
+    return 0;
+  }
+
+  /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
+  /// incoming edge label with the given index in the given node.
+  static std::string getEdgeDestLabel(const void *, unsigned) {
+    return "";
+  }
+
+  /// addCustomGraphFeatures - If a graph is made up of more than just
+  /// straight-forward nodes and edges, this is the place to put all of the
+  /// custom stuff necessary.  The GraphWriter object, instantiated with your
+  /// GraphType is passed in as an argument.  You may call arbitrary methods on
+  /// it to add things to the output graph.
+  ///
+  template<typename GraphType, typename GraphWriter>
+  static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {}
+};
+
+
+/// DOTGraphTraits - Template class that can be specialized to customize how
+/// graphs are converted to 'dot' graphs.  When specializing, you may inherit
+/// from DefaultDOTGraphTraits if you don't need to override everything.
+///
+template <typename Ty>
+struct DOTGraphTraits : public DefaultDOTGraphTraits {
+  DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
new file mode 100644
index 0000000..e8a19cd
--- /dev/null
+++ b/include/llvm/Support/DataExtractor.h
@@ -0,0 +1,355 @@
+//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
+#define LLVM_SUPPORT_DATAEXTRACTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class DataExtractor {
+  StringRef Data;
+  uint8_t IsLittleEndian;
+  uint8_t AddressSize;
+public:
+  /// Construct with a buffer that is owned by the caller.
+  ///
+  /// This constructor allows us to use data that is owned by the
+  /// caller. The data must stay around as long as this object is
+  /// valid.
+  DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
+    : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
+
+  /// \brief Get the data pointed to by this extractor.
+  StringRef getData() const { return Data; }
+  /// \brief Get the endianess for this extractor.
+  bool isLittleEndian() const { return IsLittleEndian; }
+  /// \brief Get the address size for this extractor.
+  uint8_t getAddressSize() const { return AddressSize; }
+  /// \brief Set the address size for this extractor.
+  void setAddressSize(uint8_t Size) { AddressSize = Size; }
+
+  /// Extract a C string from \a *offset_ptr.
+  ///
+  /// Returns a pointer to a C String from the data at the offset
+  /// pointed to by \a offset_ptr. A variable length NULL terminated C
+  /// string will be extracted and the \a offset_ptr will be
+  /// updated with the offset of the byte that follows the NULL
+  /// terminator byte.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     A pointer to the C string value in the data. If the offset
+  ///     pointed to by \a offset_ptr is out of bounds, or if the
+  ///     offset plus the length of the C string is out of bounds,
+  ///     NULL will be returned.
+  const char *getCStr(uint32_t *offset_ptr) const;
+
+  /// Extract an unsigned integer of size \a byte_size from \a
+  /// *offset_ptr.
+  ///
+  /// Extract a single unsigned integer value and update the offset
+  /// pointed to by \a offset_ptr. The size of the extracted integer
+  /// is specified by the \a byte_size argument. \a byte_size should
+  /// have a value greater than or equal to one and less than or equal
+  /// to eight since the return value is 64 bits wide. Any
+  /// \a byte_size values less than 1 or greater than 8 will result in
+  /// nothing being extracted, and zero being returned.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[in] byte_size
+  ///     The size in byte of the integer to extract.
+  ///
+  /// @return
+  ///     The unsigned integer value that was extracted, or zero on
+  ///     failure.
+  uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
+
+  /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
+  ///
+  /// Extract a single signed integer value (sign extending if required)
+  /// and update the offset pointed to by \a offset_ptr. The size of
+  /// the extracted integer is specified by the \a byte_size argument.
+  /// \a byte_size should have a value greater than or equal to one
+  /// and less than or equal to eight since the return value is 64
+  /// bits wide. Any \a byte_size values less than 1 or greater than
+  /// 8 will result in nothing being extracted, and zero being returned.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[in] size
+  ///     The size in bytes of the integer to extract.
+  ///
+  /// @return
+  ///     The sign extended signed integer value that was extracted,
+  ///     or zero on failure.
+  int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
+
+  //------------------------------------------------------------------
+  /// Extract an pointer from \a *offset_ptr.
+  ///
+  /// Extract a single pointer from the data and update the offset
+  /// pointed to by \a offset_ptr. The size of the extracted pointer
+  /// is \a getAddressSize(), so the address size has to be
+  /// set correctly prior to extracting any pointer values.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted pointer value as a 64 integer.
+  uint64_t getAddress(uint32_t *offset_ptr) const {
+    return getUnsigned(offset_ptr, AddressSize);
+  }
+
+  /// Extract a uint8_t value from \a *offset_ptr.
+  ///
+  /// Extract a single uint8_t from the binary data at the offset
+  /// pointed to by \a offset_ptr, and advance the offset on success.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted uint8_t value.
+  uint8_t getU8(uint32_t *offset_ptr) const;
+
+  /// Extract \a count uint8_t values from \a *offset_ptr.
+  ///
+  /// Extract \a count uint8_t values from the binary data at the
+  /// offset pointed to by \a offset_ptr, and advance the offset on
+  /// success. The extracted values are copied into \a dst.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[out] dst
+  ///     A buffer to copy \a count uint8_t values into. \a dst must
+  ///     be large enough to hold all requested data.
+  ///
+  /// @param[in] count
+  ///     The number of uint8_t values to extract.
+  ///
+  /// @return
+  ///     \a dst if all values were properly extracted and copied,
+  ///     NULL otherise.
+  uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
+
+  //------------------------------------------------------------------
+  /// Extract a uint16_t value from \a *offset_ptr.
+  ///
+  /// Extract a single uint16_t from the binary data at the offset
+  /// pointed to by \a offset_ptr, and update the offset on success.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted uint16_t value.
+  //------------------------------------------------------------------
+  uint16_t getU16(uint32_t *offset_ptr) const;
+
+  /// Extract \a count uint16_t values from \a *offset_ptr.
+  ///
+  /// Extract \a count uint16_t values from the binary data at the
+  /// offset pointed to by \a offset_ptr, and advance the offset on
+  /// success. The extracted values are copied into \a dst.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[out] dst
+  ///     A buffer to copy \a count uint16_t values into. \a dst must
+  ///     be large enough to hold all requested data.
+  ///
+  /// @param[in] count
+  ///     The number of uint16_t values to extract.
+  ///
+  /// @return
+  ///     \a dst if all values were properly extracted and copied,
+  ///     NULL otherise.
+  uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
+
+  /// Extract a uint32_t value from \a *offset_ptr.
+  ///
+  /// Extract a single uint32_t from the binary data at the offset
+  /// pointed to by \a offset_ptr, and update the offset on success.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted uint32_t value.
+  uint32_t getU32(uint32_t *offset_ptr) const;
+
+  /// Extract \a count uint32_t values from \a *offset_ptr.
+  ///
+  /// Extract \a count uint32_t values from the binary data at the
+  /// offset pointed to by \a offset_ptr, and advance the offset on
+  /// success. The extracted values are copied into \a dst.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[out] dst
+  ///     A buffer to copy \a count uint32_t values into. \a dst must
+  ///     be large enough to hold all requested data.
+  ///
+  /// @param[in] count
+  ///     The number of uint32_t values to extract.
+  ///
+  /// @return
+  ///     \a dst if all values were properly extracted and copied,
+  ///     NULL otherise.
+  uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
+
+  /// Extract a uint64_t value from \a *offset_ptr.
+  ///
+  /// Extract a single uint64_t from the binary data at the offset
+  /// pointed to by \a offset_ptr, and update the offset on success.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted uint64_t value.
+  uint64_t getU64(uint32_t *offset_ptr) const;
+
+  /// Extract \a count uint64_t values from \a *offset_ptr.
+  ///
+  /// Extract \a count uint64_t values from the binary data at the
+  /// offset pointed to by \a offset_ptr, and advance the offset on
+  /// success. The extracted values are copied into \a dst.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @param[out] dst
+  ///     A buffer to copy \a count uint64_t values into. \a dst must
+  ///     be large enough to hold all requested data.
+  ///
+  /// @param[in] count
+  ///     The number of uint64_t values to extract.
+  ///
+  /// @return
+  ///     \a dst if all values were properly extracted and copied,
+  ///     NULL otherise.
+  uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
+
+  /// Extract a signed LEB128 value from \a *offset_ptr.
+  ///
+  /// Extracts an signed LEB128 number from this object's data
+  /// starting at the offset pointed to by \a offset_ptr. The offset
+  /// pointed to by \a offset_ptr will be updated with the offset of
+  /// the byte following the last extracted byte.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted signed integer value.
+  int64_t getSLEB128(uint32_t *offset_ptr) const;
+
+  /// Extract a unsigned LEB128 value from \a *offset_ptr.
+  ///
+  /// Extracts an unsigned LEB128 number from this object's data
+  /// starting at the offset pointed to by \a offset_ptr. The offset
+  /// pointed to by \a offset_ptr will be updated with the offset of
+  /// the byte following the last extracted byte.
+  ///
+  /// @param[in,out] offset_ptr
+  ///     A pointer to an offset within the data that will be advanced
+  ///     by the appropriate number of bytes if the value is extracted
+  ///     correctly. If the offset is out of bounds or there are not
+  ///     enough bytes to extract this value, the offset will be left
+  ///     unmodified.
+  ///
+  /// @return
+  ///     The extracted unsigned integer value.
+  uint64_t getULEB128(uint32_t *offset_ptr) const;
+
+  /// Test the validity of \a offset.
+  ///
+  /// @return
+  ///     \b true if \a offset is a valid offset into the data in this
+  ///     object, \b false otherwise.
+  bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
+
+  /// Test the availability of \a length bytes of data from \a offset.
+  ///
+  /// @return
+  ///     \b true if \a offset is a valid offset and there are \a
+  ///     length bytes available at that offset, \b false otherwise.
+  bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
+    return offset + length >= offset && isValidOffset(offset + length - 1);
+  }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/DataStream.h b/include/llvm/Support/DataStream.h
new file mode 100644
index 0000000..8bc4133
--- /dev/null
+++ b/include/llvm/Support/DataStream.h
@@ -0,0 +1,38 @@
+//===---- llvm/Support/DataStream.h - Lazy bitcode streaming ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines DataStreamer, which fetches bytes of data from
+// a stream source. It provides support for streaming (lazy reading) of
+// data, e.g. bitcode
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_DATASTREAM_H
+#define LLVM_SUPPORT_DATASTREAM_H
+
+#include <string>
+
+namespace llvm {
+
+class DataStreamer {
+public:
+  /// Fetch bytes [start-end) from the stream, and write them to the
+  /// buffer pointed to by buf. Returns the number of bytes actually written.
+  virtual size_t GetBytes(unsigned char *buf, size_t len) = 0;
+
+  virtual ~DataStreamer();
+};
+
+DataStreamer *getDataFileStreamer(const std::string &Filename,
+                                  std::string *Err);
+
+}
+
+#endif  // LLVM_SUPPORT_DATASTREAM_H_
diff --git a/include/llvm/Support/DataTypes.h b/include/llvm/Support/DataTypes.h
new file mode 100644
index 0000000..a1a78fd
--- /dev/null
+++ b/include/llvm/Support/DataTypes.h
@@ -0,0 +1,129 @@
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough.  This file exports the following            *|
+|* definitions:                                                               *|
+|*                                                                            *|
+|*   [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|*   [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.     *|
+|*                                                                            *|
+|* No library is required when using these functions.                         *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+/* Please keep this file in sync with DataTypes.h.in */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#define HAVE_INTTYPES_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_UINT64_T 1
+#define HAVE_U_INT64_T 1
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#error "Compiler must provide an implementation of stdint.h"
+#endif
+
+#ifndef _MSC_VER
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+   being defined.  We would define it here, but in order to prevent Bad Things
+   happening when system headers or C++ STL headers include stdint.h before we
+   define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+        "#including Support/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#include <sys/types.h>
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#else /* _MSC_VER */
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#if defined(_WIN64)
+typedef signed __int64 ssize_t;
+#else
+typedef signed int ssize_t;
+#endif /* _WIN64 */
+
+#ifndef HAVE_INTTYPES_H
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#endif /* HAVE_INTTYPES_H */
+
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif  /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
new file mode 100644
index 0000000..e93e6ca
--- /dev/null
+++ b/include/llvm/Support/Debug.h
@@ -0,0 +1,97 @@
+//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a handy way of adding debugging information to your
+// code, without it being enabled all of the time, and without having to add
+// command line options to enable it.
+//
+// In particular, just wrap your code with the DEBUG() macro, and it will be
+// enabled automatically if you specify '-debug' on the command-line.
+// Alternatively, you can also define the DEBUG_TYPE macro to "foo" specify
+// that your debug code belongs to class "foo". Be careful that you only do
+// this after including Debug.h and not around any #include of headers. Headers
+// should define and undef the macro acround the code that needs to use the
+// DEBUG() macro. Then, on the command line, you can specify '-debug-only=foo'
+// to enable JUST the debug information for the foo class.
+//
+// When compiling without assertions, the -debug-* options and all code in
+// DEBUG() statements disappears, so it does not affect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUG_H
+#define LLVM_SUPPORT_DEBUG_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+#ifndef NDEBUG
+/// DebugFlag - This boolean is set to true if the '-debug' command line option
+/// is specified.  This should probably not be referenced directly, instead, use
+/// the DEBUG macro below.
+///
+extern bool DebugFlag;
+
+/// isCurrentDebugType - Return true if the specified string is the debug type
+/// specified on the command line, or if none was specified on the command line
+/// with the -debug-only=X option.
+///
+bool isCurrentDebugType(const char *Type);
+
+/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
+/// option were specified.  Note that DebugFlag also needs to be set to true for
+/// debug output to be produced.
+///
+void setCurrentDebugType(const char *Type);
+
+/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
+/// information.  In the '-debug' option is specified on the commandline, and if
+/// this is a debug build, then the code specified as the option to the macro
+/// will be executed.  Otherwise it will not be.  Example:
+///
+/// DEBUG_WITH_TYPE("bitset", dbgs() << "Bitset contains: " << Bitset << "\n");
+///
+/// This will emit the debug information if -debug is present, and -debug-only
+/// is not specified, or is specified as "bitset".
+#define DEBUG_WITH_TYPE(TYPE, X)                                        \
+  do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \
+  } while (0)
+
+#else
+#define isCurrentDebugType(X) (false)
+#define setCurrentDebugType(X)
+#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
+#endif
+
+/// EnableDebugBuffering - This defaults to false.  If true, the debug
+/// stream will install signal handlers to dump any buffered debug
+/// output.  It allows clients to selectively allow the debug stream
+/// to install signal handlers if they are certain there will be no
+/// conflict.
+///
+extern bool EnableDebugBuffering;
+
+/// dbgs() - This returns a reference to a raw_ostream for debugging
+/// messages.  If debugging is disabled it returns errs().  Use it
+/// like: dbgs() << "foo" << "bar";
+raw_ostream &dbgs();
+
+// DEBUG macro - This macro should be used by passes to emit debug information.
+// In the '-debug' option is specified on the commandline, and if this is a
+// debug build, then the code specified as the option to the macro will be
+// executed.  Otherwise it will not be.  Example:
+//
+// DEBUG(dbgs() << "Bitset contains: " << Bitset << "\n");
+//
+#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
new file mode 100644
index 0000000..cd9f756
--- /dev/null
+++ b/include/llvm/Support/Dwarf.h
@@ -0,0 +1,957 @@
+//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants used for implementing Dwarf debug support.  For
+// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
+// V.3 reference manual http://dwarf.freestandards.org ,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DWARF_H
+#define LLVM_SUPPORT_DWARF_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Debug info constants.
+
+enum : uint32_t {
+  LLVMDebugVersion = (12 << 16),    // Current version of debug information.
+  LLVMDebugVersion11 = (11 << 16),  // Constant for version 11.
+  LLVMDebugVersion10 = (10 << 16),  // Constant for version 10.
+  LLVMDebugVersion9 = (9 << 16),    // Constant for version 9.
+  LLVMDebugVersion8 = (8 << 16),    // Constant for version 8.
+  LLVMDebugVersion7 = (7 << 16),    // Constant for version 7.
+  LLVMDebugVersion6 = (6 << 16),    // Constant for version 6.
+  LLVMDebugVersion5 = (5 << 16),    // Constant for version 5.
+  LLVMDebugVersion4 = (4 << 16),    // Constant for version 4.
+  LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+};
+
+namespace dwarf {
+
+//===----------------------------------------------------------------------===//
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
+// reference manual http://www.dwarfstd.org/.
+//
+
+// Do not mix the following two enumerations sets.  DW_TAG_invalid changes the
+// enumeration base type.
+
+enum LLVMConstants : uint32_t {
+  // llvm mock tags
+  DW_TAG_invalid = ~0U, // Tag for invalid results.
+
+  DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+  DW_TAG_arg_variable = 0x101,  // Tag for argument variables.
+
+  DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+
+  DWARF_VERSION = 4,       // Default dwarf version we output.
+  DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
+  DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
+  DW_ARANGES_VERSION = 2   // Section version number for .debug_aranges.
+};
+
+// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
+// Not inside an enum because a 64-bit value is needed.
+const uint32_t DW_CIE_ID = UINT32_MAX;
+const uint64_t DW64_CIE_ID = UINT64_MAX;
+
+enum Tag : uint16_t {
+  DW_TAG_array_type = 0x01,
+  DW_TAG_class_type = 0x02,
+  DW_TAG_entry_point = 0x03,
+  DW_TAG_enumeration_type = 0x04,
+  DW_TAG_formal_parameter = 0x05,
+  DW_TAG_imported_declaration = 0x08,
+  DW_TAG_label = 0x0a,
+  DW_TAG_lexical_block = 0x0b,
+  DW_TAG_member = 0x0d,
+  DW_TAG_pointer_type = 0x0f,
+  DW_TAG_reference_type = 0x10,
+  DW_TAG_compile_unit = 0x11,
+  DW_TAG_string_type = 0x12,
+  DW_TAG_structure_type = 0x13,
+  DW_TAG_subroutine_type = 0x15,
+  DW_TAG_typedef = 0x16,
+  DW_TAG_union_type = 0x17,
+  DW_TAG_unspecified_parameters = 0x18,
+  DW_TAG_variant = 0x19,
+  DW_TAG_common_block = 0x1a,
+  DW_TAG_common_inclusion = 0x1b,
+  DW_TAG_inheritance = 0x1c,
+  DW_TAG_inlined_subroutine = 0x1d,
+  DW_TAG_module = 0x1e,
+  DW_TAG_ptr_to_member_type = 0x1f,
+  DW_TAG_set_type = 0x20,
+  DW_TAG_subrange_type = 0x21,
+  DW_TAG_with_stmt = 0x22,
+  DW_TAG_access_declaration = 0x23,
+  DW_TAG_base_type = 0x24,
+  DW_TAG_catch_block = 0x25,
+  DW_TAG_const_type = 0x26,
+  DW_TAG_constant = 0x27,
+  DW_TAG_enumerator = 0x28,
+  DW_TAG_file_type = 0x29,
+  DW_TAG_friend = 0x2a,
+  DW_TAG_namelist = 0x2b,
+  DW_TAG_namelist_item = 0x2c,
+  DW_TAG_packed_type = 0x2d,
+  DW_TAG_subprogram = 0x2e,
+  DW_TAG_template_type_parameter = 0x2f,
+  DW_TAG_template_value_parameter = 0x30,
+  DW_TAG_thrown_type = 0x31,
+  DW_TAG_try_block = 0x32,
+  DW_TAG_variant_part = 0x33,
+  DW_TAG_variable = 0x34,
+  DW_TAG_volatile_type = 0x35,
+  DW_TAG_dwarf_procedure = 0x36,
+  DW_TAG_restrict_type = 0x37,
+  DW_TAG_interface_type = 0x38,
+  DW_TAG_namespace = 0x39,
+  DW_TAG_imported_module = 0x3a,
+  DW_TAG_unspecified_type = 0x3b,
+  DW_TAG_partial_unit = 0x3c,
+  DW_TAG_imported_unit = 0x3d,
+  DW_TAG_condition = 0x3f,
+  DW_TAG_shared_type = 0x40,
+  DW_TAG_type_unit = 0x41,
+  DW_TAG_rvalue_reference_type = 0x42,
+  DW_TAG_template_alias = 0x43,
+
+  // New in DWARF 5:
+  DW_TAG_coarray_type = 0x44,
+  DW_TAG_generic_subrange = 0x45,
+  DW_TAG_dynamic_type = 0x46,
+
+  DW_TAG_MIPS_loop = 0x4081,
+  DW_TAG_format_label = 0x4101,
+  DW_TAG_function_template = 0x4102,
+  DW_TAG_class_template = 0x4103,
+  DW_TAG_GNU_template_template_param = 0x4106,
+  DW_TAG_GNU_template_parameter_pack = 0x4107,
+  DW_TAG_GNU_formal_parameter_pack = 0x4108,
+  DW_TAG_lo_user = 0x4080,
+  DW_TAG_APPLE_property = 0x4200,
+  DW_TAG_hi_user = 0xffff
+};
+
+inline bool isType(Tag T) {
+  switch (T) {
+  case DW_TAG_array_type:
+  case DW_TAG_class_type:
+  case DW_TAG_interface_type:
+  case DW_TAG_enumeration_type:
+  case DW_TAG_pointer_type:
+  case DW_TAG_reference_type:
+  case DW_TAG_rvalue_reference_type:
+  case DW_TAG_string_type:
+  case DW_TAG_structure_type:
+  case DW_TAG_subroutine_type:
+  case DW_TAG_union_type:
+  case DW_TAG_ptr_to_member_type:
+  case DW_TAG_set_type:
+  case DW_TAG_subrange_type:
+  case DW_TAG_base_type:
+  case DW_TAG_const_type:
+  case DW_TAG_file_type:
+  case DW_TAG_packed_type:
+  case DW_TAG_volatile_type:
+  case DW_TAG_typedef:
+    return true;
+  default:
+    return false;
+  }
+}
+
+enum Attribute : uint16_t {
+  // Attributes
+  DW_AT_sibling = 0x01,
+  DW_AT_location = 0x02,
+  DW_AT_name = 0x03,
+  DW_AT_ordering = 0x09,
+  DW_AT_byte_size = 0x0b,
+  DW_AT_bit_offset = 0x0c,
+  DW_AT_bit_size = 0x0d,
+  DW_AT_stmt_list = 0x10,
+  DW_AT_low_pc = 0x11,
+  DW_AT_high_pc = 0x12,
+  DW_AT_language = 0x13,
+  DW_AT_discr = 0x15,
+  DW_AT_discr_value = 0x16,
+  DW_AT_visibility = 0x17,
+  DW_AT_import = 0x18,
+  DW_AT_string_length = 0x19,
+  DW_AT_common_reference = 0x1a,
+  DW_AT_comp_dir = 0x1b,
+  DW_AT_const_value = 0x1c,
+  DW_AT_containing_type = 0x1d,
+  DW_AT_default_value = 0x1e,
+  DW_AT_inline = 0x20,
+  DW_AT_is_optional = 0x21,
+  DW_AT_lower_bound = 0x22,
+  DW_AT_producer = 0x25,
+  DW_AT_prototyped = 0x27,
+  DW_AT_return_addr = 0x2a,
+  DW_AT_start_scope = 0x2c,
+  DW_AT_bit_stride = 0x2e,
+  DW_AT_upper_bound = 0x2f,
+  DW_AT_abstract_origin = 0x31,
+  DW_AT_accessibility = 0x32,
+  DW_AT_address_class = 0x33,
+  DW_AT_artificial = 0x34,
+  DW_AT_base_types = 0x35,
+  DW_AT_calling_convention = 0x36,
+  DW_AT_count = 0x37,
+  DW_AT_data_member_location = 0x38,
+  DW_AT_decl_column = 0x39,
+  DW_AT_decl_file = 0x3a,
+  DW_AT_decl_line = 0x3b,
+  DW_AT_declaration = 0x3c,
+  DW_AT_discr_list = 0x3d,
+  DW_AT_encoding = 0x3e,
+  DW_AT_external = 0x3f,
+  DW_AT_frame_base = 0x40,
+  DW_AT_friend = 0x41,
+  DW_AT_identifier_case = 0x42,
+  DW_AT_macro_info = 0x43,
+  DW_AT_namelist_item = 0x44,
+  DW_AT_priority = 0x45,
+  DW_AT_segment = 0x46,
+  DW_AT_specification = 0x47,
+  DW_AT_static_link = 0x48,
+  DW_AT_type = 0x49,
+  DW_AT_use_location = 0x4a,
+  DW_AT_variable_parameter = 0x4b,
+  DW_AT_virtuality = 0x4c,
+  DW_AT_vtable_elem_location = 0x4d,
+  DW_AT_allocated = 0x4e,
+  DW_AT_associated = 0x4f,
+  DW_AT_data_location = 0x50,
+  DW_AT_byte_stride = 0x51,
+  DW_AT_entry_pc = 0x52,
+  DW_AT_use_UTF8 = 0x53,
+  DW_AT_extension = 0x54,
+  DW_AT_ranges = 0x55,
+  DW_AT_trampoline = 0x56,
+  DW_AT_call_column = 0x57,
+  DW_AT_call_file = 0x58,
+  DW_AT_call_line = 0x59,
+  DW_AT_description = 0x5a,
+  DW_AT_binary_scale = 0x5b,
+  DW_AT_decimal_scale = 0x5c,
+  DW_AT_small = 0x5d,
+  DW_AT_decimal_sign = 0x5e,
+  DW_AT_digit_count = 0x5f,
+  DW_AT_picture_string = 0x60,
+  DW_AT_mutable = 0x61,
+  DW_AT_threads_scaled = 0x62,
+  DW_AT_explicit = 0x63,
+  DW_AT_object_pointer = 0x64,
+  DW_AT_endianity = 0x65,
+  DW_AT_elemental = 0x66,
+  DW_AT_pure = 0x67,
+  DW_AT_recursive = 0x68,
+  DW_AT_signature = 0x69,
+  DW_AT_main_subprogram = 0x6a,
+  DW_AT_data_bit_offset = 0x6b,
+  DW_AT_const_expr = 0x6c,
+  DW_AT_enum_class = 0x6d,
+  DW_AT_linkage_name = 0x6e,
+
+  // New in DWARF 5:
+  DW_AT_string_length_bit_size = 0x6f,
+  DW_AT_string_length_byte_size = 0x70,
+  DW_AT_rank = 0x71,
+  DW_AT_str_offsets_base = 0x72,
+  DW_AT_addr_base = 0x73,
+  DW_AT_ranges_base = 0x74,
+  DW_AT_dwo_id = 0x75,
+  DW_AT_dwo_name = 0x76,
+  DW_AT_reference = 0x77,
+  DW_AT_rvalue_reference = 0x78,
+
+  DW_AT_lo_user = 0x2000,
+  DW_AT_hi_user = 0x3fff,
+
+  DW_AT_MIPS_loop_begin = 0x2002,
+  DW_AT_MIPS_tail_loop_begin = 0x2003,
+  DW_AT_MIPS_epilog_begin = 0x2004,
+  DW_AT_MIPS_loop_unroll_factor = 0x2005,
+  DW_AT_MIPS_software_pipeline_depth = 0x2006,
+  DW_AT_MIPS_linkage_name = 0x2007,
+  DW_AT_MIPS_stride = 0x2008,
+  DW_AT_MIPS_abstract_name = 0x2009,
+  DW_AT_MIPS_clone_origin = 0x200a,
+  DW_AT_MIPS_has_inlines = 0x200b,
+  DW_AT_MIPS_stride_byte = 0x200c,
+  DW_AT_MIPS_stride_elem = 0x200d,
+  DW_AT_MIPS_ptr_dopetype = 0x200e,
+  DW_AT_MIPS_allocatable_dopetype = 0x200f,
+  DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
+
+  // This one appears to have only been implemented by Open64 for
+  // fortran and may conflict with other extensions.
+  DW_AT_MIPS_assumed_size = 0x2011,
+
+  // GNU extensions
+  DW_AT_sf_names = 0x2101,
+  DW_AT_src_info = 0x2102,
+  DW_AT_mac_info = 0x2103,
+  DW_AT_src_coords = 0x2104,
+  DW_AT_body_begin = 0x2105,
+  DW_AT_body_end = 0x2106,
+  DW_AT_GNU_vector = 0x2107,
+  DW_AT_GNU_template_name = 0x2110,
+
+  DW_AT_GNU_odr_signature = 0x210f,
+
+  // Extensions for Fission proposal.
+  DW_AT_GNU_dwo_name = 0x2130,
+  DW_AT_GNU_dwo_id = 0x2131,
+  DW_AT_GNU_ranges_base = 0x2132,
+  DW_AT_GNU_addr_base = 0x2133,
+  DW_AT_GNU_pubnames = 0x2134,
+  DW_AT_GNU_pubtypes = 0x2135,
+
+  // Apple extensions.
+  DW_AT_APPLE_optimized = 0x3fe1,
+  DW_AT_APPLE_flags = 0x3fe2,
+  DW_AT_APPLE_isa = 0x3fe3,
+  DW_AT_APPLE_block = 0x3fe4,
+  DW_AT_APPLE_major_runtime_vers = 0x3fe5,
+  DW_AT_APPLE_runtime_class = 0x3fe6,
+  DW_AT_APPLE_omit_frame_ptr = 0x3fe7,
+  DW_AT_APPLE_property_name = 0x3fe8,
+  DW_AT_APPLE_property_getter = 0x3fe9,
+  DW_AT_APPLE_property_setter = 0x3fea,
+  DW_AT_APPLE_property_attribute = 0x3feb,
+  DW_AT_APPLE_objc_complete_type = 0x3fec,
+  DW_AT_APPLE_property = 0x3fed
+};
+
+enum Form : uint16_t {
+  // Attribute form encodings
+  DW_FORM_addr = 0x01,
+  DW_FORM_block2 = 0x03,
+  DW_FORM_block4 = 0x04,
+  DW_FORM_data2 = 0x05,
+  DW_FORM_data4 = 0x06,
+  DW_FORM_data8 = 0x07,
+  DW_FORM_string = 0x08,
+  DW_FORM_block = 0x09,
+  DW_FORM_block1 = 0x0a,
+  DW_FORM_data1 = 0x0b,
+  DW_FORM_flag = 0x0c,
+  DW_FORM_sdata = 0x0d,
+  DW_FORM_strp = 0x0e,
+  DW_FORM_udata = 0x0f,
+  DW_FORM_ref_addr = 0x10,
+  DW_FORM_ref1 = 0x11,
+  DW_FORM_ref2 = 0x12,
+  DW_FORM_ref4 = 0x13,
+  DW_FORM_ref8 = 0x14,
+  DW_FORM_ref_udata = 0x15,
+  DW_FORM_indirect = 0x16,
+  DW_FORM_sec_offset = 0x17,
+  DW_FORM_exprloc = 0x18,
+  DW_FORM_flag_present = 0x19,
+  DW_FORM_ref_sig8 = 0x20,
+
+  // Extensions for Fission proposal
+  DW_FORM_GNU_addr_index = 0x1f01,
+  DW_FORM_GNU_str_index = 0x1f02
+};
+
+enum LocationAtom {
+  // Operation encodings
+  DW_OP_addr = 0x03,
+  DW_OP_deref = 0x06,
+  DW_OP_const1u = 0x08,
+  DW_OP_const1s = 0x09,
+  DW_OP_const2u = 0x0a,
+  DW_OP_const2s = 0x0b,
+  DW_OP_const4u = 0x0c,
+  DW_OP_const4s = 0x0d,
+  DW_OP_const8u = 0x0e,
+  DW_OP_const8s = 0x0f,
+  DW_OP_constu = 0x10,
+  DW_OP_consts = 0x11,
+  DW_OP_dup = 0x12,
+  DW_OP_drop = 0x13,
+  DW_OP_over = 0x14,
+  DW_OP_pick = 0x15,
+  DW_OP_swap = 0x16,
+  DW_OP_rot = 0x17,
+  DW_OP_xderef = 0x18,
+  DW_OP_abs = 0x19,
+  DW_OP_and = 0x1a,
+  DW_OP_div = 0x1b,
+  DW_OP_minus = 0x1c,
+  DW_OP_mod = 0x1d,
+  DW_OP_mul = 0x1e,
+  DW_OP_neg = 0x1f,
+  DW_OP_not = 0x20,
+  DW_OP_or = 0x21,
+  DW_OP_plus = 0x22,
+  DW_OP_plus_uconst = 0x23,
+  DW_OP_shl = 0x24,
+  DW_OP_shr = 0x25,
+  DW_OP_shra = 0x26,
+  DW_OP_xor = 0x27,
+  DW_OP_skip = 0x2f,
+  DW_OP_bra = 0x28,
+  DW_OP_eq = 0x29,
+  DW_OP_ge = 0x2a,
+  DW_OP_gt = 0x2b,
+  DW_OP_le = 0x2c,
+  DW_OP_lt = 0x2d,
+  DW_OP_ne = 0x2e,
+  DW_OP_lit0 = 0x30,
+  DW_OP_lit1 = 0x31,
+  DW_OP_lit2 = 0x32,
+  DW_OP_lit3 = 0x33,
+  DW_OP_lit4 = 0x34,
+  DW_OP_lit5 = 0x35,
+  DW_OP_lit6 = 0x36,
+  DW_OP_lit7 = 0x37,
+  DW_OP_lit8 = 0x38,
+  DW_OP_lit9 = 0x39,
+  DW_OP_lit10 = 0x3a,
+  DW_OP_lit11 = 0x3b,
+  DW_OP_lit12 = 0x3c,
+  DW_OP_lit13 = 0x3d,
+  DW_OP_lit14 = 0x3e,
+  DW_OP_lit15 = 0x3f,
+  DW_OP_lit16 = 0x40,
+  DW_OP_lit17 = 0x41,
+  DW_OP_lit18 = 0x42,
+  DW_OP_lit19 = 0x43,
+  DW_OP_lit20 = 0x44,
+  DW_OP_lit21 = 0x45,
+  DW_OP_lit22 = 0x46,
+  DW_OP_lit23 = 0x47,
+  DW_OP_lit24 = 0x48,
+  DW_OP_lit25 = 0x49,
+  DW_OP_lit26 = 0x4a,
+  DW_OP_lit27 = 0x4b,
+  DW_OP_lit28 = 0x4c,
+  DW_OP_lit29 = 0x4d,
+  DW_OP_lit30 = 0x4e,
+  DW_OP_lit31 = 0x4f,
+  DW_OP_reg0 = 0x50,
+  DW_OP_reg1 = 0x51,
+  DW_OP_reg2 = 0x52,
+  DW_OP_reg3 = 0x53,
+  DW_OP_reg4 = 0x54,
+  DW_OP_reg5 = 0x55,
+  DW_OP_reg6 = 0x56,
+  DW_OP_reg7 = 0x57,
+  DW_OP_reg8 = 0x58,
+  DW_OP_reg9 = 0x59,
+  DW_OP_reg10 = 0x5a,
+  DW_OP_reg11 = 0x5b,
+  DW_OP_reg12 = 0x5c,
+  DW_OP_reg13 = 0x5d,
+  DW_OP_reg14 = 0x5e,
+  DW_OP_reg15 = 0x5f,
+  DW_OP_reg16 = 0x60,
+  DW_OP_reg17 = 0x61,
+  DW_OP_reg18 = 0x62,
+  DW_OP_reg19 = 0x63,
+  DW_OP_reg20 = 0x64,
+  DW_OP_reg21 = 0x65,
+  DW_OP_reg22 = 0x66,
+  DW_OP_reg23 = 0x67,
+  DW_OP_reg24 = 0x68,
+  DW_OP_reg25 = 0x69,
+  DW_OP_reg26 = 0x6a,
+  DW_OP_reg27 = 0x6b,
+  DW_OP_reg28 = 0x6c,
+  DW_OP_reg29 = 0x6d,
+  DW_OP_reg30 = 0x6e,
+  DW_OP_reg31 = 0x6f,
+  DW_OP_breg0 = 0x70,
+  DW_OP_breg1 = 0x71,
+  DW_OP_breg2 = 0x72,
+  DW_OP_breg3 = 0x73,
+  DW_OP_breg4 = 0x74,
+  DW_OP_breg5 = 0x75,
+  DW_OP_breg6 = 0x76,
+  DW_OP_breg7 = 0x77,
+  DW_OP_breg8 = 0x78,
+  DW_OP_breg9 = 0x79,
+  DW_OP_breg10 = 0x7a,
+  DW_OP_breg11 = 0x7b,
+  DW_OP_breg12 = 0x7c,
+  DW_OP_breg13 = 0x7d,
+  DW_OP_breg14 = 0x7e,
+  DW_OP_breg15 = 0x7f,
+  DW_OP_breg16 = 0x80,
+  DW_OP_breg17 = 0x81,
+  DW_OP_breg18 = 0x82,
+  DW_OP_breg19 = 0x83,
+  DW_OP_breg20 = 0x84,
+  DW_OP_breg21 = 0x85,
+  DW_OP_breg22 = 0x86,
+  DW_OP_breg23 = 0x87,
+  DW_OP_breg24 = 0x88,
+  DW_OP_breg25 = 0x89,
+  DW_OP_breg26 = 0x8a,
+  DW_OP_breg27 = 0x8b,
+  DW_OP_breg28 = 0x8c,
+  DW_OP_breg29 = 0x8d,
+  DW_OP_breg30 = 0x8e,
+  DW_OP_breg31 = 0x8f,
+  DW_OP_regx = 0x90,
+  DW_OP_fbreg = 0x91,
+  DW_OP_bregx = 0x92,
+  DW_OP_piece = 0x93,
+  DW_OP_deref_size = 0x94,
+  DW_OP_xderef_size = 0x95,
+  DW_OP_nop = 0x96,
+  DW_OP_push_object_address = 0x97,
+  DW_OP_call2 = 0x98,
+  DW_OP_call4 = 0x99,
+  DW_OP_call_ref = 0x9a,
+  DW_OP_form_tls_address = 0x9b,
+  DW_OP_call_frame_cfa = 0x9c,
+  DW_OP_bit_piece = 0x9d,
+  DW_OP_implicit_value = 0x9e,
+  DW_OP_stack_value = 0x9f,
+  DW_OP_lo_user = 0xe0,
+  DW_OP_hi_user = 0xff,
+
+  // Extensions for GNU-style thread-local storage.
+  DW_OP_GNU_push_tls_address = 0xe0,
+
+  // Extensions for Fission proposal.
+  DW_OP_GNU_addr_index = 0xfb,
+  DW_OP_GNU_const_index = 0xfc
+};
+
+enum TypeKind {
+  // Encoding attribute values
+  DW_ATE_address = 0x01,
+  DW_ATE_boolean = 0x02,
+  DW_ATE_complex_float = 0x03,
+  DW_ATE_float = 0x04,
+  DW_ATE_signed = 0x05,
+  DW_ATE_signed_char = 0x06,
+  DW_ATE_unsigned = 0x07,
+  DW_ATE_unsigned_char = 0x08,
+  DW_ATE_imaginary_float = 0x09,
+  DW_ATE_packed_decimal = 0x0a,
+  DW_ATE_numeric_string = 0x0b,
+  DW_ATE_edited = 0x0c,
+  DW_ATE_signed_fixed = 0x0d,
+  DW_ATE_unsigned_fixed = 0x0e,
+  DW_ATE_decimal_float = 0x0f,
+  DW_ATE_UTF = 0x10,
+  DW_ATE_lo_user = 0x80,
+  DW_ATE_hi_user = 0xff
+};
+
+enum DecimalSignEncoding {
+  // Decimal sign attribute values
+  DW_DS_unsigned = 0x01,
+  DW_DS_leading_overpunch = 0x02,
+  DW_DS_trailing_overpunch = 0x03,
+  DW_DS_leading_separate = 0x04,
+  DW_DS_trailing_separate = 0x05
+};
+
+enum EndianityEncoding {
+  // Endianity attribute values
+  DW_END_default = 0x00,
+  DW_END_big = 0x01,
+  DW_END_little = 0x02,
+  DW_END_lo_user = 0x40,
+  DW_END_hi_user = 0xff
+};
+
+enum AccessAttribute {
+  // Accessibility codes
+  DW_ACCESS_public = 0x01,
+  DW_ACCESS_protected = 0x02,
+  DW_ACCESS_private = 0x03
+};
+
+enum VisibilityAttribute {
+  // Visibility codes
+  DW_VIS_local = 0x01,
+  DW_VIS_exported = 0x02,
+  DW_VIS_qualified = 0x03
+};
+
+enum VirtualityAttribute {
+  // Virtuality codes
+  DW_VIRTUALITY_none = 0x00,
+  DW_VIRTUALITY_virtual = 0x01,
+  DW_VIRTUALITY_pure_virtual = 0x02
+};
+
+enum SourceLanguage {
+  // Language names
+  DW_LANG_C89 = 0x0001,
+  DW_LANG_C = 0x0002,
+  DW_LANG_Ada83 = 0x0003,
+  DW_LANG_C_plus_plus = 0x0004,
+  DW_LANG_Cobol74 = 0x0005,
+  DW_LANG_Cobol85 = 0x0006,
+  DW_LANG_Fortran77 = 0x0007,
+  DW_LANG_Fortran90 = 0x0008,
+  DW_LANG_Pascal83 = 0x0009,
+  DW_LANG_Modula2 = 0x000a,
+  DW_LANG_Java = 0x000b,
+  DW_LANG_C99 = 0x000c,
+  DW_LANG_Ada95 = 0x000d,
+  DW_LANG_Fortran95 = 0x000e,
+  DW_LANG_PLI = 0x000f,
+  DW_LANG_ObjC = 0x0010,
+  DW_LANG_ObjC_plus_plus = 0x0011,
+  DW_LANG_UPC = 0x0012,
+  DW_LANG_D = 0x0013,
+  // New in DWARF 5:
+  DW_LANG_Python = 0x0014,
+  DW_LANG_OpenCL = 0x0015,
+  DW_LANG_Go = 0x0016,
+  DW_LANG_Modula3 = 0x0017,
+  DW_LANG_Haskell = 0x0018,
+  DW_LANG_C_plus_plus_03 = 0x0019,
+  DW_LANG_C_plus_plus_11 = 0x001a,
+  DW_LANG_OCaml = 0x001b,
+
+  DW_LANG_lo_user = 0x8000,
+  DW_LANG_Mips_Assembler = 0x8001,
+  DW_LANG_hi_user = 0xffff
+};
+
+enum CaseSensitivity {
+  // Identifier case codes
+  DW_ID_case_sensitive = 0x00,
+  DW_ID_up_case = 0x01,
+  DW_ID_down_case = 0x02,
+  DW_ID_case_insensitive = 0x03
+};
+
+enum CallingConvention {
+  // Calling convention codes
+  DW_CC_normal = 0x01,
+  DW_CC_program = 0x02,
+  DW_CC_nocall = 0x03,
+  DW_CC_lo_user = 0x40,
+  DW_CC_hi_user = 0xff
+};
+
+enum InlineAttribute {
+  // Inline codes
+  DW_INL_not_inlined = 0x00,
+  DW_INL_inlined = 0x01,
+  DW_INL_declared_not_inlined = 0x02,
+  DW_INL_declared_inlined = 0x03
+};
+
+enum ArrayDimensionOrdering {
+  // Array ordering
+  DW_ORD_row_major = 0x00,
+  DW_ORD_col_major = 0x01
+};
+
+enum DiscriminantList {
+  // Discriminant descriptor values
+  DW_DSC_label = 0x00,
+  DW_DSC_range = 0x01
+};
+
+enum LineNumberOps {
+  // Line Number Standard Opcode Encodings
+  DW_LNS_extended_op = 0x00,
+  DW_LNS_copy = 0x01,
+  DW_LNS_advance_pc = 0x02,
+  DW_LNS_advance_line = 0x03,
+  DW_LNS_set_file = 0x04,
+  DW_LNS_set_column = 0x05,
+  DW_LNS_negate_stmt = 0x06,
+  DW_LNS_set_basic_block = 0x07,
+  DW_LNS_const_add_pc = 0x08,
+  DW_LNS_fixed_advance_pc = 0x09,
+  DW_LNS_set_prologue_end = 0x0a,
+  DW_LNS_set_epilogue_begin = 0x0b,
+  DW_LNS_set_isa = 0x0c
+};
+
+enum LineNumberExtendedOps {
+  // Line Number Extended Opcode Encodings
+  DW_LNE_end_sequence = 0x01,
+  DW_LNE_set_address = 0x02,
+  DW_LNE_define_file = 0x03,
+  DW_LNE_set_discriminator = 0x04,
+  DW_LNE_lo_user = 0x80,
+  DW_LNE_hi_user = 0xff
+};
+
+enum MacinfoRecordType {
+  // Macinfo Type Encodings
+  DW_MACINFO_define = 0x01,
+  DW_MACINFO_undef = 0x02,
+  DW_MACINFO_start_file = 0x03,
+  DW_MACINFO_end_file = 0x04,
+  DW_MACINFO_vendor_ext = 0xff
+};
+
+enum CallFrameInfo {
+  // Call frame instruction encodings
+  DW_CFA_extended = 0x00,
+  DW_CFA_nop = 0x00,
+  DW_CFA_advance_loc = 0x40,
+  DW_CFA_offset = 0x80,
+  DW_CFA_restore = 0xc0,
+  DW_CFA_set_loc = 0x01,
+  DW_CFA_advance_loc1 = 0x02,
+  DW_CFA_advance_loc2 = 0x03,
+  DW_CFA_advance_loc4 = 0x04,
+  DW_CFA_offset_extended = 0x05,
+  DW_CFA_restore_extended = 0x06,
+  DW_CFA_undefined = 0x07,
+  DW_CFA_same_value = 0x08,
+  DW_CFA_register = 0x09,
+  DW_CFA_remember_state = 0x0a,
+  DW_CFA_restore_state = 0x0b,
+  DW_CFA_def_cfa = 0x0c,
+  DW_CFA_def_cfa_register = 0x0d,
+  DW_CFA_def_cfa_offset = 0x0e,
+  DW_CFA_def_cfa_expression = 0x0f,
+  DW_CFA_expression = 0x10,
+  DW_CFA_offset_extended_sf = 0x11,
+  DW_CFA_def_cfa_sf = 0x12,
+  DW_CFA_def_cfa_offset_sf = 0x13,
+  DW_CFA_val_offset = 0x14,
+  DW_CFA_val_offset_sf = 0x15,
+  DW_CFA_val_expression = 0x16,
+  DW_CFA_MIPS_advance_loc8 = 0x1d,
+  DW_CFA_GNU_window_save = 0x2d,
+  DW_CFA_GNU_args_size = 0x2e,
+  DW_CFA_lo_user = 0x1c,
+  DW_CFA_hi_user = 0x3f
+};
+
+enum Constants {
+  // Children flag
+  DW_CHILDREN_no = 0x00,
+  DW_CHILDREN_yes = 0x01,
+
+  DW_EH_PE_absptr = 0x00,
+  DW_EH_PE_omit = 0xff,
+  DW_EH_PE_uleb128 = 0x01,
+  DW_EH_PE_udata2 = 0x02,
+  DW_EH_PE_udata4 = 0x03,
+  DW_EH_PE_udata8 = 0x04,
+  DW_EH_PE_sleb128 = 0x09,
+  DW_EH_PE_sdata2 = 0x0A,
+  DW_EH_PE_sdata4 = 0x0B,
+  DW_EH_PE_sdata8 = 0x0C,
+  DW_EH_PE_signed = 0x08,
+  DW_EH_PE_pcrel = 0x10,
+  DW_EH_PE_textrel = 0x20,
+  DW_EH_PE_datarel = 0x30,
+  DW_EH_PE_funcrel = 0x40,
+  DW_EH_PE_aligned = 0x50,
+  DW_EH_PE_indirect = 0x80
+};
+
+// Constants for debug_loc.dwo in the DWARF5 Split Debug Info Proposal
+enum LocationListEntry : unsigned char {
+  DW_LLE_end_of_list_entry,
+  DW_LLE_base_address_selection_entry,
+  DW_LLE_start_end_entry,
+  DW_LLE_start_length_entry,
+  DW_LLE_offset_pair_entry
+};
+
+enum ApplePropertyAttributes {
+  // Apple Objective-C Property Attributes
+  DW_APPLE_PROPERTY_readonly = 0x01,
+  DW_APPLE_PROPERTY_readwrite = 0x02,
+  DW_APPLE_PROPERTY_assign = 0x04,
+  DW_APPLE_PROPERTY_retain = 0x08,
+  DW_APPLE_PROPERTY_copy = 0x10,
+  DW_APPLE_PROPERTY_nonatomic = 0x20
+};
+
+/// TagString - Return the string for the specified tag.
+///
+const char *TagString(unsigned Tag);
+
+/// ChildrenString - Return the string for the specified children flag.
+///
+const char *ChildrenString(unsigned Children);
+
+/// AttributeString - Return the string for the specified attribute.
+///
+const char *AttributeString(unsigned Attribute);
+
+/// FormEncodingString - Return the string for the specified form encoding.
+///
+const char *FormEncodingString(unsigned Encoding);
+
+/// OperationEncodingString - Return the string for the specified operation
+/// encoding.
+const char *OperationEncodingString(unsigned Encoding);
+
+/// AttributeEncodingString - Return the string for the specified attribute
+/// encoding.
+const char *AttributeEncodingString(unsigned Encoding);
+
+/// DecimalSignString - Return the string for the specified decimal sign
+/// attribute.
+const char *DecimalSignString(unsigned Sign);
+
+/// EndianityString - Return the string for the specified endianity.
+///
+const char *EndianityString(unsigned Endian);
+
+/// AccessibilityString - Return the string for the specified accessibility.
+///
+const char *AccessibilityString(unsigned Access);
+
+/// VisibilityString - Return the string for the specified visibility.
+///
+const char *VisibilityString(unsigned Visibility);
+
+/// VirtualityString - Return the string for the specified virtuality.
+///
+const char *VirtualityString(unsigned Virtuality);
+
+/// LanguageString - Return the string for the specified language.
+///
+const char *LanguageString(unsigned Language);
+
+/// CaseString - Return the string for the specified identifier case.
+///
+const char *CaseString(unsigned Case);
+
+/// ConventionString - Return the string for the specified calling convention.
+///
+const char *ConventionString(unsigned Convention);
+
+/// InlineCodeString - Return the string for the specified inline code.
+///
+const char *InlineCodeString(unsigned Code);
+
+/// ArrayOrderString - Return the string for the specified array order.
+///
+const char *ArrayOrderString(unsigned Order);
+
+/// DiscriminantString - Return the string for the specified discriminant
+/// descriptor.
+const char *DiscriminantString(unsigned Discriminant);
+
+/// LNStandardString - Return the string for the specified line number standard.
+///
+const char *LNStandardString(unsigned Standard);
+
+/// LNExtendedString - Return the string for the specified line number extended
+/// opcode encodings.
+const char *LNExtendedString(unsigned Encoding);
+
+/// MacinfoString - Return the string for the specified macinfo type encodings.
+///
+const char *MacinfoString(unsigned Encoding);
+
+/// CallFrameString - Return the string for the specified call frame instruction
+/// encodings.
+const char *CallFrameString(unsigned Encoding);
+
+// Constants for the DWARF5 Accelerator Table Proposal
+enum AcceleratorTable {
+  // Data layout descriptors.
+  DW_ATOM_null = 0u,       // Marker as the end of a list of atoms.
+  DW_ATOM_die_offset = 1u, // DIE offset in the debug_info section.
+  DW_ATOM_cu_offset = 2u, // Offset of the compile unit header that contains the
+                          // item in question.
+  DW_ATOM_die_tag = 3u,   // A tag entry.
+  DW_ATOM_type_flags = 4u, // Set of flags for a type.
+
+  // DW_ATOM_type_flags values.
+
+  // Always set for C++, only set for ObjC if this is the @implementation for a
+  // class.
+  DW_FLAG_type_implementation = 2u,
+
+  // Hash functions.
+
+  // Daniel J. Bernstein hash.
+  DW_hash_function_djb = 0u
+};
+
+/// AtomTypeString - Return the string for the specified Atom type.
+const char *AtomTypeString(unsigned Atom);
+
+// Constants for the GNU pubnames/pubtypes extensions supporting gdb index.
+enum GDBIndexEntryKind {
+  GIEK_NONE,
+  GIEK_TYPE,
+  GIEK_VARIABLE,
+  GIEK_FUNCTION,
+  GIEK_OTHER,
+  GIEK_UNUSED5,
+  GIEK_UNUSED6,
+  GIEK_UNUSED7
+};
+
+const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind);
+
+enum GDBIndexEntryLinkage {
+  GIEL_EXTERNAL,
+  GIEL_STATIC
+};
+
+const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
+
+/// The gnu_pub* kind looks like:
+///
+/// 0-3  reserved
+/// 4-6  symbol kind
+/// 7    0 == global, 1 == static
+///
+/// A gdb_index descriptor includes the above kind, shifted 24 bits up with the
+/// offset of the cu within the debug_info section stored in those 24 bits.
+struct PubIndexEntryDescriptor {
+  GDBIndexEntryKind Kind;
+  GDBIndexEntryLinkage Linkage;
+  PubIndexEntryDescriptor(GDBIndexEntryKind Kind, GDBIndexEntryLinkage Linkage)
+      : Kind(Kind), Linkage(Linkage) {}
+  /* implicit */ PubIndexEntryDescriptor(GDBIndexEntryKind Kind)
+      : Kind(Kind), Linkage(GIEL_EXTERNAL) {}
+  explicit PubIndexEntryDescriptor(uint8_t Value)
+      : Kind(static_cast<GDBIndexEntryKind>((Value & KIND_MASK) >>
+                                            KIND_OFFSET)),
+        Linkage(static_cast<GDBIndexEntryLinkage>((Value & LINKAGE_MASK) >>
+                                                  LINKAGE_OFFSET)) {}
+  uint8_t toBits() { return Kind << KIND_OFFSET | Linkage << LINKAGE_OFFSET; }
+
+private:
+  enum {
+    KIND_OFFSET = 4,
+    KIND_MASK = 7 << KIND_OFFSET,
+    LINKAGE_OFFSET = 7,
+    LINKAGE_MASK = 1 << LINKAGE_OFFSET
+  };
+};
+
+} // End of namespace dwarf
+
+} // End of namespace llvm
+
+#endif
diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
new file mode 100644
index 0000000..de47be6
--- /dev/null
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -0,0 +1,104 @@
+//===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- 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 sys::DynamicLibrary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H
+#define LLVM_SYSTEM_DYNAMICLIBRARY_H
+
+#include <string>
+
+namespace llvm {
+
+class StringRef;
+
+namespace sys {
+
+  /// This class provides a portable interface to dynamic libraries which also
+  /// might be known as shared libraries, shared objects, dynamic shared
+  /// objects, or dynamic link libraries. Regardless of the terminology or the
+  /// operating system interface, this class provides a portable interface that
+  /// allows dynamic libraries to be loaded and searched for externally
+  /// defined symbols. This is typically used to provide "plug-in" support.
+  /// It also allows for symbols to be defined which don't live in any library,
+  /// but rather the main program itself, useful on Windows where the main
+  /// executable cannot be searched.
+  ///
+  /// Note: there is currently no interface for temporarily loading a library,
+  /// or for unloading libraries when the LLVM library is unloaded.
+  class DynamicLibrary {
+    // Placeholder whose address represents an invalid library.
+    // We use this instead of NULL or a pointer-int pair because the OS library
+    // might define 0 or 1 to be "special" handles, such as "search all".
+    static char Invalid;
+
+    // Opaque data used to interface with OS-specific dynamic library handling.
+    void *Data;
+
+    explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
+  public:
+    /// Returns true if the object refers to a valid library.
+    bool isValid() { return Data != &Invalid; }
+
+    /// Searches through the library for the symbol \p symbolName. If it is
+    /// found, the address of that symbol is returned. If not, NULL is returned.
+    /// Note that NULL will also be returned if the library failed to load.
+    /// Use isValid() to distinguish these cases if it is important.
+    /// Note that this will \e not search symbols explicitly registered by
+    /// AddSymbol().
+    void *getAddressOfSymbol(const char *symbolName);
+
+    /// This function permanently loads the dynamic library at the given path.
+    /// The library will only be unloaded when the program terminates.
+    /// This returns a valid DynamicLibrary instance on success and an invalid
+    /// instance on failure (see isValid()). \p *errMsg will only be modified
+    /// if the library fails to load.
+    ///
+    /// It is safe to call this function multiple times for the same library.
+    /// @brief Open a dynamic library permanently.
+    static DynamicLibrary getPermanentLibrary(const char *filename,
+                                              std::string *errMsg = nullptr);
+
+    /// This function permanently loads the dynamic library at the given path.
+    /// Use this instead of getPermanentLibrary() when you won't need to get
+    /// symbols from the library itself.
+    ///
+    /// It is safe to call this function multiple times for the same library.
+    static bool LoadLibraryPermanently(const char *Filename,
+                                       std::string *ErrMsg = nullptr) {
+      return !getPermanentLibrary(Filename, ErrMsg).isValid();
+    }
+
+    /// This function will search through all previously loaded dynamic
+    /// libraries for the symbol \p symbolName. If it is found, the address of
+    /// that symbol is returned. If not, null is returned. Note that this will
+    /// search permanently loaded libraries (getPermanentLibrary()) as well
+    /// as explicitly registered symbols (AddSymbol()).
+    /// @throws std::string on error.
+    /// @brief Search through libraries for address of a symbol
+    static void *SearchForAddressOfSymbol(const char *symbolName);
+
+    /// @brief Convenience function for C++ophiles.
+    static void *SearchForAddressOfSymbol(const std::string &symbolName) {
+      return SearchForAddressOfSymbol(symbolName.c_str());
+    }
+
+    /// This functions permanently adds the symbol \p symbolName with the
+    /// value \p symbolValue.  These symbols are searched before any
+    /// libraries.
+    /// @brief Add searchable symbol/value pair.
+    static void AddSymbol(StringRef symbolName, void *symbolValue);
+  };
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
new file mode 100644
index 0000000..42abe89
--- /dev/null
+++ b/include/llvm/Support/ELF.h
@@ -0,0 +1,1903 @@
+//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the ELF file format.
+//
+// The details of the ELF32 bits in this file are largely based on the Tool
+// Interface Standard (TIS) Executable and Linking Format (ELF) Specification
+// Version 1.2, May 1995. The ELF64 stuff is based on ELF-64 Object File Format
+// Version 1.5, Draft 2, May 1998 as well as OpenBSD header files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELF_H
+#define LLVM_SUPPORT_ELF_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+
+namespace llvm {
+
+namespace ELF {
+
+typedef uint32_t Elf32_Addr; // Program address
+typedef uint32_t Elf32_Off;  // File offset
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Word;
+typedef int32_t  Elf32_Sword;
+
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef uint16_t Elf64_Half;
+typedef uint32_t Elf64_Word;
+typedef int32_t  Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t  Elf64_Sxword;
+
+// Object file magic string.
+static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
+
+// e_ident size and indices.
+enum {
+  EI_MAG0       = 0,          // File identification index.
+  EI_MAG1       = 1,          // File identification index.
+  EI_MAG2       = 2,          // File identification index.
+  EI_MAG3       = 3,          // File identification index.
+  EI_CLASS      = 4,          // File class.
+  EI_DATA       = 5,          // Data encoding.
+  EI_VERSION    = 6,          // File version.
+  EI_OSABI      = 7,          // OS/ABI identification.
+  EI_ABIVERSION = 8,          // ABI version.
+  EI_PAD        = 9,          // Start of padding bytes.
+  EI_NIDENT     = 16          // Number of bytes in e_ident.
+};
+
+struct Elf32_Ehdr {
+  unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes
+  Elf32_Half    e_type;      // Type of file (see ET_* below)
+  Elf32_Half    e_machine;   // Required architecture for this file (see EM_*)
+  Elf32_Word    e_version;   // Must be equal to 1
+  Elf32_Addr    e_entry;     // Address to jump to in order to start program
+  Elf32_Off     e_phoff;     // Program header table's file offset, in bytes
+  Elf32_Off     e_shoff;     // Section header table's file offset, in bytes
+  Elf32_Word    e_flags;     // Processor-specific flags
+  Elf32_Half    e_ehsize;    // Size of ELF header, in bytes
+  Elf32_Half    e_phentsize; // Size of an entry in the program header table
+  Elf32_Half    e_phnum;     // Number of entries in the program header table
+  Elf32_Half    e_shentsize; // Size of an entry in the section header table
+  Elf32_Half    e_shnum;     // Number of entries in the section header table
+  Elf32_Half    e_shstrndx;  // Sect hdr table index of sect name string table
+  bool checkMagic() const {
+    return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
+  }
+  unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
+  unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
+};
+
+// 64-bit ELF header. Fields are the same as for ELF32, but with different
+// types (see above).
+struct Elf64_Ehdr {
+  unsigned char e_ident[EI_NIDENT];
+  Elf64_Half    e_type;
+  Elf64_Half    e_machine;
+  Elf64_Word    e_version;
+  Elf64_Addr    e_entry;
+  Elf64_Off     e_phoff;
+  Elf64_Off     e_shoff;
+  Elf64_Word    e_flags;
+  Elf64_Half    e_ehsize;
+  Elf64_Half    e_phentsize;
+  Elf64_Half    e_phnum;
+  Elf64_Half    e_shentsize;
+  Elf64_Half    e_shnum;
+  Elf64_Half    e_shstrndx;
+  bool checkMagic() const {
+    return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
+  }
+  unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
+  unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
+};
+
+// File types
+enum {
+  ET_NONE   = 0,      // No file type
+  ET_REL    = 1,      // Relocatable file
+  ET_EXEC   = 2,      // Executable file
+  ET_DYN    = 3,      // Shared object file
+  ET_CORE   = 4,      // Core file
+  ET_LOPROC = 0xff00, // Beginning of processor-specific codes
+  ET_HIPROC = 0xffff  // Processor-specific
+};
+
+// Versioning
+enum {
+  EV_NONE = 0,
+  EV_CURRENT = 1
+};
+
+// Machine architectures
+// See current registered ELF machine architectures at:
+//    http://www.uxsglobal.com/developers/gabi/latest/ch4.eheader.html
+enum {
+  EM_NONE          = 0, // No machine
+  EM_M32           = 1, // AT&T WE 32100
+  EM_SPARC         = 2, // SPARC
+  EM_386           = 3, // Intel 386
+  EM_68K           = 4, // Motorola 68000
+  EM_88K           = 5, // Motorola 88000
+  EM_486           = 6, // Intel 486 (deprecated)
+  EM_860           = 7, // Intel 80860
+  EM_MIPS          = 8, // MIPS R3000
+  EM_S370          = 9, // IBM System/370
+  EM_MIPS_RS3_LE   = 10, // MIPS RS3000 Little-endian
+  EM_PARISC        = 15, // Hewlett-Packard PA-RISC
+  EM_VPP500        = 17, // Fujitsu VPP500
+  EM_SPARC32PLUS   = 18, // Enhanced instruction set SPARC
+  EM_960           = 19, // Intel 80960
+  EM_PPC           = 20, // PowerPC
+  EM_PPC64         = 21, // PowerPC64
+  EM_S390          = 22, // IBM System/390
+  EM_SPU           = 23, // IBM SPU/SPC
+  EM_V800          = 36, // NEC V800
+  EM_FR20          = 37, // Fujitsu FR20
+  EM_RH32          = 38, // TRW RH-32
+  EM_RCE           = 39, // Motorola RCE
+  EM_ARM           = 40, // ARM
+  EM_ALPHA         = 41, // DEC Alpha
+  EM_SH            = 42, // Hitachi SH
+  EM_SPARCV9       = 43, // SPARC V9
+  EM_TRICORE       = 44, // Siemens TriCore
+  EM_ARC           = 45, // Argonaut RISC Core
+  EM_H8_300        = 46, // Hitachi H8/300
+  EM_H8_300H       = 47, // Hitachi H8/300H
+  EM_H8S           = 48, // Hitachi H8S
+  EM_H8_500        = 49, // Hitachi H8/500
+  EM_IA_64         = 50, // Intel IA-64 processor architecture
+  EM_MIPS_X        = 51, // Stanford MIPS-X
+  EM_COLDFIRE      = 52, // Motorola ColdFire
+  EM_68HC12        = 53, // Motorola M68HC12
+  EM_MMA           = 54, // Fujitsu MMA Multimedia Accelerator
+  EM_PCP           = 55, // Siemens PCP
+  EM_NCPU          = 56, // Sony nCPU embedded RISC processor
+  EM_NDR1          = 57, // Denso NDR1 microprocessor
+  EM_STARCORE      = 58, // Motorola Star*Core processor
+  EM_ME16          = 59, // Toyota ME16 processor
+  EM_ST100         = 60, // STMicroelectronics ST100 processor
+  EM_TINYJ         = 61, // Advanced Logic Corp. TinyJ embedded processor family
+  EM_X86_64        = 62, // AMD x86-64 architecture
+  EM_PDSP          = 63, // Sony DSP Processor
+  EM_PDP10         = 64, // Digital Equipment Corp. PDP-10
+  EM_PDP11         = 65, // Digital Equipment Corp. PDP-11
+  EM_FX66          = 66, // Siemens FX66 microcontroller
+  EM_ST9PLUS       = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller
+  EM_ST7           = 68, // STMicroelectronics ST7 8-bit microcontroller
+  EM_68HC16        = 69, // Motorola MC68HC16 Microcontroller
+  EM_68HC11        = 70, // Motorola MC68HC11 Microcontroller
+  EM_68HC08        = 71, // Motorola MC68HC08 Microcontroller
+  EM_68HC05        = 72, // Motorola MC68HC05 Microcontroller
+  EM_SVX           = 73, // Silicon Graphics SVx
+  EM_ST19          = 74, // STMicroelectronics ST19 8-bit microcontroller
+  EM_VAX           = 75, // Digital VAX
+  EM_CRIS          = 76, // Axis Communications 32-bit embedded processor
+  EM_JAVELIN       = 77, // Infineon Technologies 32-bit embedded processor
+  EM_FIREPATH      = 78, // Element 14 64-bit DSP Processor
+  EM_ZSP           = 79, // LSI Logic 16-bit DSP Processor
+  EM_MMIX          = 80, // Donald Knuth's educational 64-bit processor
+  EM_HUANY         = 81, // Harvard University machine-independent object files
+  EM_PRISM         = 82, // SiTera Prism
+  EM_AVR           = 83, // Atmel AVR 8-bit microcontroller
+  EM_FR30          = 84, // Fujitsu FR30
+  EM_D10V          = 85, // Mitsubishi D10V
+  EM_D30V          = 86, // Mitsubishi D30V
+  EM_V850          = 87, // NEC v850
+  EM_M32R          = 88, // Mitsubishi M32R
+  EM_MN10300       = 89, // Matsushita MN10300
+  EM_MN10200       = 90, // Matsushita MN10200
+  EM_PJ            = 91, // picoJava
+  EM_OPENRISC      = 92, // OpenRISC 32-bit embedded processor
+  EM_ARC_COMPACT   = 93, // ARC International ARCompact processor (old
+                         // spelling/synonym: EM_ARC_A5)
+  EM_XTENSA        = 94, // Tensilica Xtensa Architecture
+  EM_VIDEOCORE     = 95, // Alphamosaic VideoCore processor
+  EM_TMM_GPP       = 96, // Thompson Multimedia General Purpose Processor
+  EM_NS32K         = 97, // National Semiconductor 32000 series
+  EM_TPC           = 98, // Tenor Network TPC processor
+  EM_SNP1K         = 99, // Trebia SNP 1000 processor
+  EM_ST200         = 100, // STMicroelectronics (www.st.com) ST200
+  EM_IP2K          = 101, // Ubicom IP2xxx microcontroller family
+  EM_MAX           = 102, // MAX Processor
+  EM_CR            = 103, // National Semiconductor CompactRISC microprocessor
+  EM_F2MC16        = 104, // Fujitsu F2MC16
+  EM_MSP430        = 105, // Texas Instruments embedded microcontroller msp430
+  EM_BLACKFIN      = 106, // Analog Devices Blackfin (DSP) processor
+  EM_SE_C33        = 107, // S1C33 Family of Seiko Epson processors
+  EM_SEP           = 108, // Sharp embedded microprocessor
+  EM_ARCA          = 109, // Arca RISC Microprocessor
+  EM_UNICORE       = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC
+                          // of Peking University
+  EM_EXCESS        = 111, // eXcess: 16/32/64-bit configurable embedded CPU
+  EM_DXP           = 112, // Icera Semiconductor Inc. Deep Execution Processor
+  EM_ALTERA_NIOS2  = 113, // Altera Nios II soft-core processor
+  EM_CRX           = 114, // National Semiconductor CompactRISC CRX
+  EM_XGATE         = 115, // Motorola XGATE embedded processor
+  EM_C166          = 116, // Infineon C16x/XC16x processor
+  EM_M16C          = 117, // Renesas M16C series microprocessors
+  EM_DSPIC30F      = 118, // Microchip Technology dsPIC30F Digital Signal
+                          // Controller
+  EM_CE            = 119, // Freescale Communication Engine RISC core
+  EM_M32C          = 120, // Renesas M32C series microprocessors
+  EM_TSK3000       = 131, // Altium TSK3000 core
+  EM_RS08          = 132, // Freescale RS08 embedded processor
+  EM_SHARC         = 133, // Analog Devices SHARC family of 32-bit DSP
+                          // processors
+  EM_ECOG2         = 134, // Cyan Technology eCOG2 microprocessor
+  EM_SCORE7        = 135, // Sunplus S+core7 RISC processor
+  EM_DSP24         = 136, // New Japan Radio (NJR) 24-bit DSP Processor
+  EM_VIDEOCORE3    = 137, // Broadcom VideoCore III processor
+  EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture
+  EM_SE_C17        = 139, // Seiko Epson C17 family
+  EM_TI_C6000      = 140, // The Texas Instruments TMS320C6000 DSP family
+  EM_TI_C2000      = 141, // The Texas Instruments TMS320C2000 DSP family
+  EM_TI_C5500      = 142, // The Texas Instruments TMS320C55x DSP family
+  EM_MMDSP_PLUS    = 160, // STMicroelectronics 64bit VLIW Data Signal Processor
+  EM_CYPRESS_M8C   = 161, // Cypress M8C microprocessor
+  EM_R32C          = 162, // Renesas R32C series microprocessors
+  EM_TRIMEDIA      = 163, // NXP Semiconductors TriMedia architecture family
+  EM_HEXAGON       = 164, // Qualcomm Hexagon processor
+  EM_8051          = 165, // Intel 8051 and variants
+  EM_STXP7X        = 166, // STMicroelectronics STxP7x family of configurable
+                          // and extensible RISC processors
+  EM_NDS32         = 167, // Andes Technology compact code size embedded RISC
+                          // processor family
+  EM_ECOG1         = 168, // Cyan Technology eCOG1X family
+  EM_ECOG1X        = 168, // Cyan Technology eCOG1X family
+  EM_MAXQ30        = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers
+  EM_XIMO16        = 170, // New Japan Radio (NJR) 16-bit DSP Processor
+  EM_MANIK         = 171, // M2000 Reconfigurable RISC Microprocessor
+  EM_CRAYNV2       = 172, // Cray Inc. NV2 vector architecture
+  EM_RX            = 173, // Renesas RX family
+  EM_METAG         = 174, // Imagination Technologies META processor
+                          // architecture
+  EM_MCST_ELBRUS   = 175, // MCST Elbrus general purpose hardware architecture
+  EM_ECOG16        = 176, // Cyan Technology eCOG16 family
+  EM_CR16          = 177, // National Semiconductor CompactRISC CR16 16-bit
+                          // microprocessor
+  EM_ETPU          = 178, // Freescale Extended Time Processing Unit
+  EM_SLE9X         = 179, // Infineon Technologies SLE9X core
+  EM_L10M          = 180, // Intel L10M
+  EM_K10M          = 181, // Intel K10M
+  EM_AARCH64       = 183, // ARM AArch64
+  EM_AVR32         = 185, // Atmel Corporation 32-bit microprocessor family
+  EM_STM8          = 186, // STMicroeletronics STM8 8-bit microcontroller
+  EM_TILE64        = 187, // Tilera TILE64 multicore architecture family
+  EM_TILEPRO       = 188, // Tilera TILEPro multicore architecture family
+  EM_CUDA          = 190, // NVIDIA CUDA architecture
+  EM_TILEGX        = 191, // Tilera TILE-Gx multicore architecture family
+  EM_CLOUDSHIELD   = 192, // CloudShield architecture family
+  EM_COREA_1ST     = 193, // KIPO-KAIST Core-A 1st generation processor family
+  EM_COREA_2ND     = 194, // KIPO-KAIST Core-A 2nd generation processor family
+  EM_ARC_COMPACT2  = 195, // Synopsys ARCompact V2
+  EM_OPEN8         = 196, // Open8 8-bit RISC soft processor core
+  EM_RL78          = 197, // Renesas RL78 family
+  EM_VIDEOCORE5    = 198, // Broadcom VideoCore V processor
+  EM_78KOR         = 199, // Renesas 78KOR family
+  EM_56800EX       = 200, // Freescale 56800EX Digital Signal Controller (DSC)
+  EM_BA1           = 201, // Beyond BA1 CPU architecture
+  EM_BA2           = 202, // Beyond BA2 CPU architecture
+  EM_XCORE         = 203, // XMOS xCORE processor family
+  EM_MCHP_PIC      = 204, // Microchip 8-bit PIC(r) family
+  EM_INTEL205      = 205, // Reserved by Intel
+  EM_INTEL206      = 206, // Reserved by Intel
+  EM_INTEL207      = 207, // Reserved by Intel
+  EM_INTEL208      = 208, // Reserved by Intel
+  EM_INTEL209      = 209, // Reserved by Intel
+  EM_KM32          = 210, // KM211 KM32 32-bit processor
+  EM_KMX32         = 211, // KM211 KMX32 32-bit processor
+  EM_KMX16         = 212, // KM211 KMX16 16-bit processor
+  EM_KMX8          = 213, // KM211 KMX8 8-bit processor
+  EM_KVARC         = 214, // KM211 KVARC processor
+  EM_CDP           = 215, // Paneve CDP architecture family
+  EM_COGE          = 216, // Cognitive Smart Memory Processor
+  EM_COOL          = 217, // iCelero CoolEngine
+  EM_NORC          = 218, // Nanoradio Optimized RISC
+  EM_CSR_KALIMBA   = 219  // CSR Kalimba architecture family
+};
+
+// Object file classes.
+enum {
+  ELFCLASSNONE = 0,
+  ELFCLASS32 = 1, // 32-bit object file
+  ELFCLASS64 = 2  // 64-bit object file
+};
+
+// Object file byte orderings.
+enum {
+  ELFDATANONE = 0, // Invalid data encoding.
+  ELFDATA2LSB = 1, // Little-endian object file
+  ELFDATA2MSB = 2  // Big-endian object file
+};
+
+// OS ABI identification.
+enum {
+  ELFOSABI_NONE = 0,          // UNIX System V ABI
+  ELFOSABI_HPUX = 1,          // HP-UX operating system
+  ELFOSABI_NETBSD = 2,        // NetBSD
+  ELFOSABI_GNU = 3,           // GNU/Linux
+  ELFOSABI_LINUX = 3,         // Historical alias for ELFOSABI_GNU.
+  ELFOSABI_HURD = 4,          // GNU/Hurd
+  ELFOSABI_SOLARIS = 6,       // Solaris
+  ELFOSABI_AIX = 7,           // AIX
+  ELFOSABI_IRIX = 8,          // IRIX
+  ELFOSABI_FREEBSD = 9,       // FreeBSD
+  ELFOSABI_TRU64 = 10,        // TRU64 UNIX
+  ELFOSABI_MODESTO = 11,      // Novell Modesto
+  ELFOSABI_OPENBSD = 12,      // OpenBSD
+  ELFOSABI_OPENVMS = 13,      // OpenVMS
+  ELFOSABI_NSK = 14,          // Hewlett-Packard Non-Stop Kernel
+  ELFOSABI_AROS = 15,         // AROS
+  ELFOSABI_FENIXOS = 16,      // FenixOS
+  ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
+  ELFOSABI_C6000_LINUX = 65,  // Linux TMS320C6000
+  ELFOSABI_ARM = 97,          // ARM
+  ELFOSABI_STANDALONE = 255   // Standalone (embedded) application
+};
+
+// X86_64 relocations.
+enum {
+  R_X86_64_NONE       = 0,
+  R_X86_64_64         = 1,
+  R_X86_64_PC32       = 2,
+  R_X86_64_GOT32      = 3,
+  R_X86_64_PLT32      = 4,
+  R_X86_64_COPY       = 5,
+  R_X86_64_GLOB_DAT   = 6,
+  R_X86_64_JUMP_SLOT  = 7,
+  R_X86_64_RELATIVE   = 8,
+  R_X86_64_GOTPCREL   = 9,
+  R_X86_64_32         = 10,
+  R_X86_64_32S        = 11,
+  R_X86_64_16         = 12,
+  R_X86_64_PC16       = 13,
+  R_X86_64_8          = 14,
+  R_X86_64_PC8        = 15,
+  R_X86_64_DTPMOD64   = 16,
+  R_X86_64_DTPOFF64   = 17,
+  R_X86_64_TPOFF64    = 18,
+  R_X86_64_TLSGD      = 19,
+  R_X86_64_TLSLD      = 20,
+  R_X86_64_DTPOFF32   = 21,
+  R_X86_64_GOTTPOFF   = 22,
+  R_X86_64_TPOFF32    = 23,
+  R_X86_64_PC64       = 24,
+  R_X86_64_GOTOFF64   = 25,
+  R_X86_64_GOTPC32    = 26,
+  R_X86_64_GOT64      = 27,
+  R_X86_64_GOTPCREL64 = 28,
+  R_X86_64_GOTPC64    = 29,
+  R_X86_64_GOTPLT64   = 30,
+  R_X86_64_PLTOFF64   = 31,
+  R_X86_64_SIZE32     = 32,
+  R_X86_64_SIZE64     = 33,
+  R_X86_64_GOTPC32_TLSDESC = 34,
+  R_X86_64_TLSDESC_CALL    = 35,
+  R_X86_64_TLSDESC    = 36,
+  R_X86_64_IRELATIVE  = 37
+};
+
+// i386 relocations.
+// TODO: this is just a subset
+enum {
+  R_386_NONE          = 0,
+  R_386_32            = 1,
+  R_386_PC32          = 2,
+  R_386_GOT32         = 3,
+  R_386_PLT32         = 4,
+  R_386_COPY          = 5,
+  R_386_GLOB_DAT      = 6,
+  R_386_JUMP_SLOT     = 7,
+  R_386_RELATIVE      = 8,
+  R_386_GOTOFF        = 9,
+  R_386_GOTPC         = 10,
+  R_386_32PLT         = 11,
+  R_386_TLS_TPOFF     = 14,
+  R_386_TLS_IE        = 15,
+  R_386_TLS_GOTIE     = 16,
+  R_386_TLS_LE        = 17,
+  R_386_TLS_GD        = 18,
+  R_386_TLS_LDM       = 19,
+  R_386_16            = 20,
+  R_386_PC16          = 21,
+  R_386_8             = 22,
+  R_386_PC8           = 23,
+  R_386_TLS_GD_32     = 24,
+  R_386_TLS_GD_PUSH   = 25,
+  R_386_TLS_GD_CALL   = 26,
+  R_386_TLS_GD_POP    = 27,
+  R_386_TLS_LDM_32    = 28,
+  R_386_TLS_LDM_PUSH  = 29,
+  R_386_TLS_LDM_CALL  = 30,
+  R_386_TLS_LDM_POP   = 31,
+  R_386_TLS_LDO_32    = 32,
+  R_386_TLS_IE_32     = 33,
+  R_386_TLS_LE_32     = 34,
+  R_386_TLS_DTPMOD32  = 35,
+  R_386_TLS_DTPOFF32  = 36,
+  R_386_TLS_TPOFF32   = 37,
+  R_386_TLS_GOTDESC   = 39,
+  R_386_TLS_DESC_CALL = 40,
+  R_386_TLS_DESC      = 41,
+  R_386_IRELATIVE     = 42,
+  R_386_NUM           = 43
+};
+
+// ELF Relocation types for PPC32
+enum {
+  R_PPC_NONE                  = 0,      /* No relocation. */
+  R_PPC_ADDR32                = 1,
+  R_PPC_ADDR24                = 2,
+  R_PPC_ADDR16                = 3,
+  R_PPC_ADDR16_LO             = 4,
+  R_PPC_ADDR16_HI             = 5,
+  R_PPC_ADDR16_HA             = 6,
+  R_PPC_ADDR14                = 7,
+  R_PPC_ADDR14_BRTAKEN        = 8,
+  R_PPC_ADDR14_BRNTAKEN       = 9,
+  R_PPC_REL24                 = 10,
+  R_PPC_REL14                 = 11,
+  R_PPC_REL14_BRTAKEN         = 12,
+  R_PPC_REL14_BRNTAKEN        = 13,
+  R_PPC_GOT16                 = 14,
+  R_PPC_GOT16_LO              = 15,
+  R_PPC_GOT16_HI              = 16,
+  R_PPC_GOT16_HA              = 17,
+  R_PPC_PLTREL24              = 18,
+  R_PPC_REL32                 = 26,
+  R_PPC_TLS                   = 67,
+  R_PPC_DTPMOD32              = 68,
+  R_PPC_TPREL16               = 69,
+  R_PPC_TPREL16_LO            = 70,
+  R_PPC_TPREL16_HI            = 71,
+  R_PPC_TPREL16_HA            = 72,
+  R_PPC_TPREL32               = 73,
+  R_PPC_DTPREL16              = 74,
+  R_PPC_DTPREL16_LO           = 75,
+  R_PPC_DTPREL16_HI           = 76,
+  R_PPC_DTPREL16_HA           = 77,
+  R_PPC_DTPREL32              = 78,
+  R_PPC_GOT_TLSGD16           = 79,
+  R_PPC_GOT_TLSGD16_LO        = 80,
+  R_PPC_GOT_TLSGD16_HI        = 81,
+  R_PPC_GOT_TLSGD16_HA        = 82,
+  R_PPC_GOT_TLSLD16           = 83,
+  R_PPC_GOT_TLSLD16_LO        = 84,
+  R_PPC_GOT_TLSLD16_HI        = 85,
+  R_PPC_GOT_TLSLD16_HA        = 86,
+  R_PPC_GOT_TPREL16           = 87,
+  R_PPC_GOT_TPREL16_LO        = 88,
+  R_PPC_GOT_TPREL16_HI        = 89,
+  R_PPC_GOT_TPREL16_HA        = 90,
+  R_PPC_GOT_DTPREL16          = 91,
+  R_PPC_GOT_DTPREL16_LO       = 92,
+  R_PPC_GOT_DTPREL16_HI       = 93,
+  R_PPC_GOT_DTPREL16_HA       = 94,
+  R_PPC_TLSGD                 = 95,
+  R_PPC_TLSLD                 = 96,
+  R_PPC_REL16                 = 249,
+  R_PPC_REL16_LO              = 250,
+  R_PPC_REL16_HI              = 251,
+  R_PPC_REL16_HA              = 252
+};
+
+// Specific e_flags for PPC64
+enum {
+  // e_flags bits specifying ABI:
+  // 1 for original ABI using function descriptors,
+  // 2 for revised ABI without function descriptors,
+  // 0 for unspecified or not using any features affected by the differences.
+  EF_PPC64_ABI = 3
+};
+
+// Special values for the st_other field in the symbol table entry for PPC64.
+enum {
+  STO_PPC64_LOCAL_BIT = 5,
+  STO_PPC64_LOCAL_MASK = (7 << STO_PPC64_LOCAL_BIT)
+};
+static inline int64_t
+decodePPC64LocalEntryOffset(unsigned Other) {
+  unsigned Val = (Other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
+  return ((1 << Val) >> 2) << 2;
+}
+static inline unsigned
+encodePPC64LocalEntryOffset(int64_t Offset) {
+  unsigned Val = (Offset >= 4 * 4
+                  ? (Offset >= 8 * 4
+                     ? (Offset >= 16 * 4 ? 6 : 5)
+                     : 4)
+                  : (Offset >= 2 * 4
+                     ? 3
+                     : (Offset >= 1 * 4 ? 2 : 0)));
+  return Val << STO_PPC64_LOCAL_BIT;
+}
+
+// ELF Relocation types for PPC64
+enum {
+  R_PPC64_NONE                = 0,
+  R_PPC64_ADDR32              = 1,
+  R_PPC64_ADDR24              = 2,
+  R_PPC64_ADDR16              = 3,
+  R_PPC64_ADDR16_LO           = 4,
+  R_PPC64_ADDR16_HI           = 5,
+  R_PPC64_ADDR16_HA           = 6,
+  R_PPC64_ADDR14              = 7,
+  R_PPC64_ADDR14_BRTAKEN      = 8,
+  R_PPC64_ADDR14_BRNTAKEN     = 9,
+  R_PPC64_REL24               = 10,
+  R_PPC64_REL14               = 11,
+  R_PPC64_REL14_BRTAKEN       = 12,
+  R_PPC64_REL14_BRNTAKEN      = 13,
+  R_PPC64_GOT16               = 14,
+  R_PPC64_GOT16_LO            = 15,
+  R_PPC64_GOT16_HI            = 16,
+  R_PPC64_GOT16_HA            = 17,
+  R_PPC64_REL32               = 26,
+  R_PPC64_ADDR64              = 38,
+  R_PPC64_ADDR16_HIGHER       = 39,
+  R_PPC64_ADDR16_HIGHERA      = 40,
+  R_PPC64_ADDR16_HIGHEST      = 41,
+  R_PPC64_ADDR16_HIGHESTA     = 42,
+  R_PPC64_REL64               = 44,
+  R_PPC64_TOC16               = 47,
+  R_PPC64_TOC16_LO            = 48,
+  R_PPC64_TOC16_HI            = 49,
+  R_PPC64_TOC16_HA            = 50,
+  R_PPC64_TOC                 = 51,
+  R_PPC64_ADDR16_DS           = 56,
+  R_PPC64_ADDR16_LO_DS        = 57,
+  R_PPC64_GOT16_DS            = 58,
+  R_PPC64_GOT16_LO_DS         = 59,
+  R_PPC64_TOC16_DS            = 63,
+  R_PPC64_TOC16_LO_DS         = 64,
+  R_PPC64_TLS                 = 67,
+  R_PPC64_DTPMOD64            = 68,
+  R_PPC64_TPREL16             = 69,
+  R_PPC64_TPREL16_LO          = 70,
+  R_PPC64_TPREL16_HI          = 71,
+  R_PPC64_TPREL16_HA          = 72,
+  R_PPC64_TPREL64             = 73,
+  R_PPC64_DTPREL16            = 74,
+  R_PPC64_DTPREL16_LO         = 75,
+  R_PPC64_DTPREL16_HI         = 76,
+  R_PPC64_DTPREL16_HA         = 77,
+  R_PPC64_DTPREL64            = 78,
+  R_PPC64_GOT_TLSGD16         = 79,
+  R_PPC64_GOT_TLSGD16_LO      = 80,
+  R_PPC64_GOT_TLSGD16_HI      = 81,
+  R_PPC64_GOT_TLSGD16_HA      = 82,
+  R_PPC64_GOT_TLSLD16         = 83,
+  R_PPC64_GOT_TLSLD16_LO      = 84,
+  R_PPC64_GOT_TLSLD16_HI      = 85,
+  R_PPC64_GOT_TLSLD16_HA      = 86,
+  R_PPC64_GOT_TPREL16_DS      = 87,
+  R_PPC64_GOT_TPREL16_LO_DS   = 88,
+  R_PPC64_GOT_TPREL16_HI      = 89,
+  R_PPC64_GOT_TPREL16_HA      = 90,
+  R_PPC64_GOT_DTPREL16_DS     = 91,
+  R_PPC64_GOT_DTPREL16_LO_DS  = 92,
+  R_PPC64_GOT_DTPREL16_HI     = 93,
+  R_PPC64_GOT_DTPREL16_HA     = 94,
+  R_PPC64_TPREL16_DS          = 95,
+  R_PPC64_TPREL16_LO_DS       = 96,
+  R_PPC64_TPREL16_HIGHER      = 97,
+  R_PPC64_TPREL16_HIGHERA     = 98,
+  R_PPC64_TPREL16_HIGHEST     = 99,
+  R_PPC64_TPREL16_HIGHESTA    = 100,
+  R_PPC64_DTPREL16_DS         = 101,
+  R_PPC64_DTPREL16_LO_DS      = 102,
+  R_PPC64_DTPREL16_HIGHER     = 103,
+  R_PPC64_DTPREL16_HIGHERA    = 104,
+  R_PPC64_DTPREL16_HIGHEST    = 105,
+  R_PPC64_DTPREL16_HIGHESTA   = 106,
+  R_PPC64_TLSGD               = 107,
+  R_PPC64_TLSLD               = 108,
+  R_PPC64_REL16               = 249,
+  R_PPC64_REL16_LO            = 250,
+  R_PPC64_REL16_HI            = 251,
+  R_PPC64_REL16_HA            = 252
+};
+
+// ELF Relocation types for AArch64
+
+enum {
+  R_AARCH64_NONE                        = 0x100,
+
+  R_AARCH64_ABS64                       = 0x101,
+  R_AARCH64_ABS32                       = 0x102,
+  R_AARCH64_ABS16                       = 0x103,
+  R_AARCH64_PREL64                      = 0x104,
+  R_AARCH64_PREL32                      = 0x105,
+  R_AARCH64_PREL16                      = 0x106,
+
+  R_AARCH64_MOVW_UABS_G0                = 0x107,
+  R_AARCH64_MOVW_UABS_G0_NC             = 0x108,
+  R_AARCH64_MOVW_UABS_G1                = 0x109,
+  R_AARCH64_MOVW_UABS_G1_NC             = 0x10a,
+  R_AARCH64_MOVW_UABS_G2                = 0x10b,
+  R_AARCH64_MOVW_UABS_G2_NC             = 0x10c,
+  R_AARCH64_MOVW_UABS_G3                = 0x10d,
+  R_AARCH64_MOVW_SABS_G0                = 0x10e,
+  R_AARCH64_MOVW_SABS_G1                = 0x10f,
+  R_AARCH64_MOVW_SABS_G2                = 0x110,
+
+  R_AARCH64_LD_PREL_LO19                = 0x111,
+  R_AARCH64_ADR_PREL_LO21               = 0x112,
+  R_AARCH64_ADR_PREL_PG_HI21            = 0x113,
+  R_AARCH64_ADD_ABS_LO12_NC             = 0x115,
+  R_AARCH64_LDST8_ABS_LO12_NC           = 0x116,
+
+  R_AARCH64_TSTBR14                     = 0x117,
+  R_AARCH64_CONDBR19                    = 0x118,
+  R_AARCH64_JUMP26                      = 0x11a,
+  R_AARCH64_CALL26                      = 0x11b,
+
+  R_AARCH64_LDST16_ABS_LO12_NC          = 0x11c,
+  R_AARCH64_LDST32_ABS_LO12_NC          = 0x11d,
+  R_AARCH64_LDST64_ABS_LO12_NC          = 0x11e,
+
+  R_AARCH64_LDST128_ABS_LO12_NC         = 0x12b,
+
+  R_AARCH64_ADR_GOT_PAGE                = 0x137,
+  R_AARCH64_LD64_GOT_LO12_NC            = 0x138,
+
+  R_AARCH64_TLSLD_MOVW_DTPREL_G2        = 0x20b,
+  R_AARCH64_TLSLD_MOVW_DTPREL_G1        = 0x20c,
+  R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC     = 0x20d,
+  R_AARCH64_TLSLD_MOVW_DTPREL_G0        = 0x20e,
+  R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC     = 0x20f,
+  R_AARCH64_TLSLD_ADD_DTPREL_HI12       = 0x210,
+  R_AARCH64_TLSLD_ADD_DTPREL_LO12       = 0x211,
+  R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC    = 0x212,
+  R_AARCH64_TLSLD_LDST8_DTPREL_LO12     = 0x213,
+  R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC  = 0x214,
+  R_AARCH64_TLSLD_LDST16_DTPREL_LO12    = 0x215,
+  R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 0x216,
+  R_AARCH64_TLSLD_LDST32_DTPREL_LO12    = 0x217,
+  R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 0x218,
+  R_AARCH64_TLSLD_LDST64_DTPREL_LO12    = 0x219,
+  R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 0x21a,
+
+  R_AARCH64_TLSIE_MOVW_GOTTPREL_G1      = 0x21b,
+  R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC   = 0x21c,
+  R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21   = 0x21d,
+  R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 0x21e,
+  R_AARCH64_TLSIE_LD_GOTTPREL_PREL19    = 0x21f,
+
+  R_AARCH64_TLSLE_MOVW_TPREL_G2         = 0x220,
+  R_AARCH64_TLSLE_MOVW_TPREL_G1         = 0x221,
+  R_AARCH64_TLSLE_MOVW_TPREL_G1_NC      = 0x222,
+  R_AARCH64_TLSLE_MOVW_TPREL_G0         = 0x223,
+  R_AARCH64_TLSLE_MOVW_TPREL_G0_NC      = 0x224,
+  R_AARCH64_TLSLE_ADD_TPREL_HI12        = 0x225,
+  R_AARCH64_TLSLE_ADD_TPREL_LO12        = 0x226,
+  R_AARCH64_TLSLE_ADD_TPREL_LO12_NC     = 0x227,
+  R_AARCH64_TLSLE_LDST8_TPREL_LO12      = 0x228,
+  R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC   = 0x229,
+  R_AARCH64_TLSLE_LDST16_TPREL_LO12     = 0x22a,
+  R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC  = 0x22b,
+  R_AARCH64_TLSLE_LDST32_TPREL_LO12     = 0x22c,
+  R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC  = 0x22d,
+  R_AARCH64_TLSLE_LDST64_TPREL_LO12     = 0x22e,
+  R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC  = 0x22f,
+
+  R_AARCH64_TLSDESC_ADR_PAGE            = 0x232,
+  R_AARCH64_TLSDESC_LD64_LO12_NC        = 0x233,
+  R_AARCH64_TLSDESC_ADD_LO12_NC         = 0x234,
+
+  R_AARCH64_TLSDESC_CALL                = 0x239
+};
+
+// ARM Specific e_flags
+enum : unsigned {
+  EF_ARM_SOFT_FLOAT =     0x00000200U,
+  EF_ARM_VFP_FLOAT =      0x00000400U,
+  EF_ARM_EABI_UNKNOWN =   0x00000000U,
+  EF_ARM_EABI_VER1 =      0x01000000U,
+  EF_ARM_EABI_VER2 =      0x02000000U,
+  EF_ARM_EABI_VER3 =      0x03000000U,
+  EF_ARM_EABI_VER4 =      0x04000000U,
+  EF_ARM_EABI_VER5 =      0x05000000U,
+  EF_ARM_EABIMASK =       0xFF000000U
+};
+
+// ELF Relocation types for ARM
+// Meets 2.08 ABI Specs.
+
+enum {
+  R_ARM_NONE                  = 0x00,
+  R_ARM_PC24                  = 0x01,
+  R_ARM_ABS32                 = 0x02,
+  R_ARM_REL32                 = 0x03,
+  R_ARM_LDR_PC_G0             = 0x04,
+  R_ARM_ABS16                 = 0x05,
+  R_ARM_ABS12                 = 0x06,
+  R_ARM_THM_ABS5              = 0x07,
+  R_ARM_ABS8                  = 0x08,
+  R_ARM_SBREL32               = 0x09,
+  R_ARM_THM_CALL              = 0x0a,
+  R_ARM_THM_PC8               = 0x0b,
+  R_ARM_BREL_ADJ              = 0x0c,
+  R_ARM_TLS_DESC              = 0x0d,
+  R_ARM_THM_SWI8              = 0x0e,
+  R_ARM_XPC25                 = 0x0f,
+  R_ARM_THM_XPC22             = 0x10,
+  R_ARM_TLS_DTPMOD32          = 0x11,
+  R_ARM_TLS_DTPOFF32          = 0x12,
+  R_ARM_TLS_TPOFF32           = 0x13,
+  R_ARM_COPY                  = 0x14,
+  R_ARM_GLOB_DAT              = 0x15,
+  R_ARM_JUMP_SLOT             = 0x16,
+  R_ARM_RELATIVE              = 0x17,
+  R_ARM_GOTOFF32              = 0x18,
+  R_ARM_BASE_PREL             = 0x19,
+  R_ARM_GOT_BREL              = 0x1a,
+  R_ARM_PLT32                 = 0x1b,
+  R_ARM_CALL                  = 0x1c,
+  R_ARM_JUMP24                = 0x1d,
+  R_ARM_THM_JUMP24            = 0x1e,
+  R_ARM_BASE_ABS              = 0x1f,
+  R_ARM_ALU_PCREL_7_0         = 0x20,
+  R_ARM_ALU_PCREL_15_8        = 0x21,
+  R_ARM_ALU_PCREL_23_15       = 0x22,
+  R_ARM_LDR_SBREL_11_0_NC     = 0x23,
+  R_ARM_ALU_SBREL_19_12_NC    = 0x24,
+  R_ARM_ALU_SBREL_27_20_CK    = 0x25,
+  R_ARM_TARGET1               = 0x26,
+  R_ARM_SBREL31               = 0x27,
+  R_ARM_V4BX                  = 0x28,
+  R_ARM_TARGET2               = 0x29,
+  R_ARM_PREL31                = 0x2a,
+  R_ARM_MOVW_ABS_NC           = 0x2b,
+  R_ARM_MOVT_ABS              = 0x2c,
+  R_ARM_MOVW_PREL_NC          = 0x2d,
+  R_ARM_MOVT_PREL             = 0x2e,
+  R_ARM_THM_MOVW_ABS_NC       = 0x2f,
+  R_ARM_THM_MOVT_ABS          = 0x30,
+  R_ARM_THM_MOVW_PREL_NC      = 0x31,
+  R_ARM_THM_MOVT_PREL         = 0x32,
+  R_ARM_THM_JUMP19            = 0x33,
+  R_ARM_THM_JUMP6             = 0x34,
+  R_ARM_THM_ALU_PREL_11_0     = 0x35,
+  R_ARM_THM_PC12              = 0x36,
+  R_ARM_ABS32_NOI             = 0x37,
+  R_ARM_REL32_NOI             = 0x38,
+  R_ARM_ALU_PC_G0_NC          = 0x39,
+  R_ARM_ALU_PC_G0             = 0x3a,
+  R_ARM_ALU_PC_G1_NC          = 0x3b,
+  R_ARM_ALU_PC_G1             = 0x3c,
+  R_ARM_ALU_PC_G2             = 0x3d,
+  R_ARM_LDR_PC_G1             = 0x3e,
+  R_ARM_LDR_PC_G2             = 0x3f,
+  R_ARM_LDRS_PC_G0            = 0x40,
+  R_ARM_LDRS_PC_G1            = 0x41,
+  R_ARM_LDRS_PC_G2            = 0x42,
+  R_ARM_LDC_PC_G0             = 0x43,
+  R_ARM_LDC_PC_G1             = 0x44,
+  R_ARM_LDC_PC_G2             = 0x45,
+  R_ARM_ALU_SB_G0_NC          = 0x46,
+  R_ARM_ALU_SB_G0             = 0x47,
+  R_ARM_ALU_SB_G1_NC          = 0x48,
+  R_ARM_ALU_SB_G1             = 0x49,
+  R_ARM_ALU_SB_G2             = 0x4a,
+  R_ARM_LDR_SB_G0             = 0x4b,
+  R_ARM_LDR_SB_G1             = 0x4c,
+  R_ARM_LDR_SB_G2             = 0x4d,
+  R_ARM_LDRS_SB_G0            = 0x4e,
+  R_ARM_LDRS_SB_G1            = 0x4f,
+  R_ARM_LDRS_SB_G2            = 0x50,
+  R_ARM_LDC_SB_G0             = 0x51,
+  R_ARM_LDC_SB_G1             = 0x52,
+  R_ARM_LDC_SB_G2             = 0x53,
+  R_ARM_MOVW_BREL_NC          = 0x54,
+  R_ARM_MOVT_BREL             = 0x55,
+  R_ARM_MOVW_BREL             = 0x56,
+  R_ARM_THM_MOVW_BREL_NC      = 0x57,
+  R_ARM_THM_MOVT_BREL         = 0x58,
+  R_ARM_THM_MOVW_BREL         = 0x59,
+  R_ARM_TLS_GOTDESC           = 0x5a,
+  R_ARM_TLS_CALL              = 0x5b,
+  R_ARM_TLS_DESCSEQ           = 0x5c,
+  R_ARM_THM_TLS_CALL          = 0x5d,
+  R_ARM_PLT32_ABS             = 0x5e,
+  R_ARM_GOT_ABS               = 0x5f,
+  R_ARM_GOT_PREL              = 0x60,
+  R_ARM_GOT_BREL12            = 0x61,
+  R_ARM_GOTOFF12              = 0x62,
+  R_ARM_GOTRELAX              = 0x63,
+  R_ARM_GNU_VTENTRY           = 0x64,
+  R_ARM_GNU_VTINHERIT         = 0x65,
+  R_ARM_THM_JUMP11            = 0x66,
+  R_ARM_THM_JUMP8             = 0x67,
+  R_ARM_TLS_GD32              = 0x68,
+  R_ARM_TLS_LDM32             = 0x69,
+  R_ARM_TLS_LDO32             = 0x6a,
+  R_ARM_TLS_IE32              = 0x6b,
+  R_ARM_TLS_LE32              = 0x6c,
+  R_ARM_TLS_LDO12             = 0x6d,
+  R_ARM_TLS_LE12              = 0x6e,
+  R_ARM_TLS_IE12GP            = 0x6f,
+  R_ARM_PRIVATE_0             = 0x70,
+  R_ARM_PRIVATE_1             = 0x71,
+  R_ARM_PRIVATE_2             = 0x72,
+  R_ARM_PRIVATE_3             = 0x73,
+  R_ARM_PRIVATE_4             = 0x74,
+  R_ARM_PRIVATE_5             = 0x75,
+  R_ARM_PRIVATE_6             = 0x76,
+  R_ARM_PRIVATE_7             = 0x77,
+  R_ARM_PRIVATE_8             = 0x78,
+  R_ARM_PRIVATE_9             = 0x79,
+  R_ARM_PRIVATE_10            = 0x7a,
+  R_ARM_PRIVATE_11            = 0x7b,
+  R_ARM_PRIVATE_12            = 0x7c,
+  R_ARM_PRIVATE_13            = 0x7d,
+  R_ARM_PRIVATE_14            = 0x7e,
+  R_ARM_PRIVATE_15            = 0x7f,
+  R_ARM_ME_TOO                = 0x80,
+  R_ARM_THM_TLS_DESCSEQ16     = 0x81,
+  R_ARM_THM_TLS_DESCSEQ32     = 0x82
+};
+
+// Mips Specific e_flags
+enum : unsigned {
+  EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
+  EF_MIPS_PIC       = 0x00000002, // Position independent code
+  EF_MIPS_CPIC      = 0x00000004, // Call object with Position independent code
+  EF_MIPS_ABI2      = 0x00000020,
+  EF_MIPS_32BITMODE = 0x00000100,
+  EF_MIPS_NAN2008   = 0x00000400, // Uses IEE 754-2008 NaN encoding
+  EF_MIPS_ABI_O32   = 0x00001000, // This file follows the first MIPS 32 bit ABI
+
+  //ARCH_ASE
+  EF_MIPS_MICROMIPS = 0x02000000, // microMIPS
+  EF_MIPS_ARCH_ASE_M16 =
+                      0x04000000, // Has Mips-16 ISA extensions
+  //ARCH
+  EF_MIPS_ARCH_1    = 0x00000000, // MIPS1 instruction set
+  EF_MIPS_ARCH_2    = 0x10000000, // MIPS2 instruction set
+  EF_MIPS_ARCH_3    = 0x20000000, // MIPS3 instruction set
+  EF_MIPS_ARCH_4    = 0x30000000, // MIPS4 instruction set
+  EF_MIPS_ARCH_5    = 0x40000000, // MIPS5 instruction set
+  EF_MIPS_ARCH_32   = 0x50000000, // MIPS32 instruction set per linux not elf.h
+  EF_MIPS_ARCH_64   = 0x60000000, // MIPS64 instruction set per linux not elf.h
+  EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+  EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2
+  EF_MIPS_ARCH_32R6 = 0x90000000, // mips32r6
+  EF_MIPS_ARCH_64R6 = 0xa0000000, // mips64r6
+  EF_MIPS_ARCH      = 0xf0000000  // Mask for applying EF_MIPS_ARCH_ variant
+};
+
+// ELF Relocation types for Mips
+enum {
+  R_MIPS_NONE              =  0,
+  R_MIPS_16                =  1,
+  R_MIPS_32                =  2,
+  R_MIPS_REL32             =  3,
+  R_MIPS_26                =  4,
+  R_MIPS_HI16              =  5,
+  R_MIPS_LO16              =  6,
+  R_MIPS_GPREL16           =  7,
+  R_MIPS_LITERAL           =  8,
+  R_MIPS_GOT16             =  9,
+  R_MIPS_PC16              = 10,
+  R_MIPS_CALL16            = 11,
+  R_MIPS_GPREL32           = 12,
+  R_MIPS_UNUSED1           = 13,
+  R_MIPS_UNUSED2           = 14,
+  R_MIPS_SHIFT5            = 16,
+  R_MIPS_SHIFT6            = 17,
+  R_MIPS_64                = 18,
+  R_MIPS_GOT_DISP          = 19,
+  R_MIPS_GOT_PAGE          = 20,
+  R_MIPS_GOT_OFST          = 21,
+  R_MIPS_GOT_HI16          = 22,
+  R_MIPS_GOT_LO16          = 23,
+  R_MIPS_SUB               = 24,
+  R_MIPS_INSERT_A          = 25,
+  R_MIPS_INSERT_B          = 26,
+  R_MIPS_DELETE            = 27,
+  R_MIPS_HIGHER            = 28,
+  R_MIPS_HIGHEST           = 29,
+  R_MIPS_CALL_HI16         = 30,
+  R_MIPS_CALL_LO16         = 31,
+  R_MIPS_SCN_DISP          = 32,
+  R_MIPS_REL16             = 33,
+  R_MIPS_ADD_IMMEDIATE     = 34,
+  R_MIPS_PJUMP             = 35,
+  R_MIPS_RELGOT            = 36,
+  R_MIPS_JALR              = 37,
+  R_MIPS_TLS_DTPMOD32      = 38,
+  R_MIPS_TLS_DTPREL32      = 39,
+  R_MIPS_TLS_DTPMOD64      = 40,
+  R_MIPS_TLS_DTPREL64      = 41,
+  R_MIPS_TLS_GD            = 42,
+  R_MIPS_TLS_LDM           = 43,
+  R_MIPS_TLS_DTPREL_HI16   = 44,
+  R_MIPS_TLS_DTPREL_LO16   = 45,
+  R_MIPS_TLS_GOTTPREL      = 46,
+  R_MIPS_TLS_TPREL32       = 47,
+  R_MIPS_TLS_TPREL64       = 48,
+  R_MIPS_TLS_TPREL_HI16    = 49,
+  R_MIPS_TLS_TPREL_LO16    = 50,
+  R_MIPS_GLOB_DAT          = 51,
+  R_MIPS_PC21_S2           = 60,
+  R_MIPS_PC26_S2           = 61,
+  R_MIPS_PC18_S3           = 62,
+  R_MIPS_PC19_S2           = 63,
+  R_MIPS_PCHI16            = 64,
+  R_MIPS_PCLO16            = 65,
+  R_MIPS16_GOT16           = 102,
+  R_MIPS16_HI16            = 104,
+  R_MIPS16_LO16            = 105,
+  R_MIPS_COPY              = 126,
+  R_MIPS_JUMP_SLOT         = 127,
+  R_MICROMIPS_26_S1        = 133,
+  R_MICROMIPS_HI16         = 134,
+  R_MICROMIPS_LO16         = 135,
+  R_MICROMIPS_GOT16        = 138,
+  R_MICROMIPS_PC16_S1      = 141,
+  R_MICROMIPS_CALL16       = 142,
+  R_MICROMIPS_GOT_DISP     = 145,
+  R_MICROMIPS_GOT_PAGE     = 146,
+  R_MICROMIPS_GOT_OFST     = 147,
+  R_MICROMIPS_TLS_GD          = 162,
+  R_MICROMIPS_TLS_LDM         = 163,
+  R_MICROMIPS_TLS_DTPREL_HI16 = 164,
+  R_MICROMIPS_TLS_DTPREL_LO16 = 165,
+  R_MICROMIPS_TLS_TPREL_HI16  = 169,
+  R_MICROMIPS_TLS_TPREL_LO16  = 170,
+  R_MIPS_NUM               = 218,
+  R_MIPS_PC32              = 248
+};
+
+// Special values for the st_other field in the symbol table entry for MIPS.
+enum {
+  STO_MIPS_OPTIONAL        = 0x04,  // Symbol whose definition is optional
+  STO_MIPS_PLT             = 0x08,  // PLT entry related dynamic table record
+  STO_MIPS_PIC             = 0x20,  // PIC func in an object mixes PIC/non-PIC
+  STO_MIPS_MICROMIPS       = 0x80,  // MIPS Specific ISA for MicroMips
+  STO_MIPS_MIPS16          = 0xf0   // MIPS Specific ISA for Mips16
+};
+
+// Hexagon Specific e_flags
+// Release 5 ABI
+enum {
+  // Object processor version flags, bits[3:0]
+  EF_HEXAGON_MACH_V2      = 0x00000001,   // Hexagon V2
+  EF_HEXAGON_MACH_V3      = 0x00000002,   // Hexagon V3
+  EF_HEXAGON_MACH_V4      = 0x00000003,   // Hexagon V4
+  EF_HEXAGON_MACH_V5      = 0x00000004,   // Hexagon V5
+
+  // Highest ISA version flags
+  EF_HEXAGON_ISA_MACH     = 0x00000000,   // Same as specified in bits[3:0]
+                                          // of e_flags
+  EF_HEXAGON_ISA_V2       = 0x00000010,   // Hexagon V2 ISA
+  EF_HEXAGON_ISA_V3       = 0x00000020,   // Hexagon V3 ISA
+  EF_HEXAGON_ISA_V4       = 0x00000030,   // Hexagon V4 ISA
+  EF_HEXAGON_ISA_V5       = 0x00000040    // Hexagon V5 ISA
+};
+
+// Hexagon specific Section indexes for common small data
+// Release 5 ABI
+enum {
+  SHN_HEXAGON_SCOMMON     = 0xff00,       // Other access sizes
+  SHN_HEXAGON_SCOMMON_1   = 0xff01,       // Byte-sized access
+  SHN_HEXAGON_SCOMMON_2   = 0xff02,       // Half-word-sized access
+  SHN_HEXAGON_SCOMMON_4   = 0xff03,       // Word-sized access
+  SHN_HEXAGON_SCOMMON_8   = 0xff04        // Double-word-size access
+};
+
+// ELF Relocation types for Hexagon
+// Release 5 ABI
+enum {
+  R_HEX_NONE              =  0,
+  R_HEX_B22_PCREL         =  1,
+  R_HEX_B15_PCREL         =  2,
+  R_HEX_B7_PCREL          =  3,
+  R_HEX_LO16              =  4,
+  R_HEX_HI16              =  5,
+  R_HEX_32                =  6,
+  R_HEX_16                =  7,
+  R_HEX_8                 =  8,
+  R_HEX_GPREL16_0         =  9,
+  R_HEX_GPREL16_1         =  10,
+  R_HEX_GPREL16_2         =  11,
+  R_HEX_GPREL16_3         =  12,
+  R_HEX_HL16              =  13,
+  R_HEX_B13_PCREL         =  14,
+  R_HEX_B9_PCREL          =  15,
+  R_HEX_B32_PCREL_X       =  16,
+  R_HEX_32_6_X            =  17,
+  R_HEX_B22_PCREL_X       =  18,
+  R_HEX_B15_PCREL_X       =  19,
+  R_HEX_B13_PCREL_X       =  20,
+  R_HEX_B9_PCREL_X        =  21,
+  R_HEX_B7_PCREL_X        =  22,
+  R_HEX_16_X              =  23,
+  R_HEX_12_X              =  24,
+  R_HEX_11_X              =  25,
+  R_HEX_10_X              =  26,
+  R_HEX_9_X               =  27,
+  R_HEX_8_X               =  28,
+  R_HEX_7_X               =  29,
+  R_HEX_6_X               =  30,
+  R_HEX_32_PCREL          =  31,
+  R_HEX_COPY              =  32,
+  R_HEX_GLOB_DAT          =  33,
+  R_HEX_JMP_SLOT          =  34,
+  R_HEX_RELATIVE          =  35,
+  R_HEX_PLT_B22_PCREL     =  36,
+  R_HEX_GOTREL_LO16       =  37,
+  R_HEX_GOTREL_HI16       =  38,
+  R_HEX_GOTREL_32         =  39,
+  R_HEX_GOT_LO16          =  40,
+  R_HEX_GOT_HI16          =  41,
+  R_HEX_GOT_32            =  42,
+  R_HEX_GOT_16            =  43,
+  R_HEX_DTPMOD_32         =  44,
+  R_HEX_DTPREL_LO16       =  45,
+  R_HEX_DTPREL_HI16       =  46,
+  R_HEX_DTPREL_32         =  47,
+  R_HEX_DTPREL_16         =  48,
+  R_HEX_GD_PLT_B22_PCREL  =  49,
+  R_HEX_GD_GOT_LO16       =  50,
+  R_HEX_GD_GOT_HI16       =  51,
+  R_HEX_GD_GOT_32         =  52,
+  R_HEX_GD_GOT_16         =  53,
+  R_HEX_IE_LO16           =  54,
+  R_HEX_IE_HI16           =  55,
+  R_HEX_IE_32             =  56,
+  R_HEX_IE_GOT_LO16       =  57,
+  R_HEX_IE_GOT_HI16       =  58,
+  R_HEX_IE_GOT_32         =  59,
+  R_HEX_IE_GOT_16         =  60,
+  R_HEX_TPREL_LO16        =  61,
+  R_HEX_TPREL_HI16        =  62,
+  R_HEX_TPREL_32          =  63,
+  R_HEX_TPREL_16          =  64,
+  R_HEX_6_PCREL_X         =  65,
+  R_HEX_GOTREL_32_6_X     =  66,
+  R_HEX_GOTREL_16_X       =  67,
+  R_HEX_GOTREL_11_X       =  68,
+  R_HEX_GOT_32_6_X        =  69,
+  R_HEX_GOT_16_X          =  70,
+  R_HEX_GOT_11_X          =  71,
+  R_HEX_DTPREL_32_6_X     =  72,
+  R_HEX_DTPREL_16_X       =  73,
+  R_HEX_DTPREL_11_X       =  74,
+  R_HEX_GD_GOT_32_6_X     =  75,
+  R_HEX_GD_GOT_16_X       =  76,
+  R_HEX_GD_GOT_11_X       =  77,
+  R_HEX_IE_32_6_X         =  78,
+  R_HEX_IE_16_X           =  79,
+  R_HEX_IE_GOT_32_6_X     =  80,
+  R_HEX_IE_GOT_16_X       =  81,
+  R_HEX_IE_GOT_11_X       =  82,
+  R_HEX_TPREL_32_6_X      =  83,
+  R_HEX_TPREL_16_X        =  84,
+  R_HEX_TPREL_11_X        =  85
+};
+
+// ELF Relocation types for S390/zSeries
+enum {
+  R_390_NONE        =  0,
+  R_390_8           =  1,
+  R_390_12          =  2,
+  R_390_16          =  3,
+  R_390_32          =  4,
+  R_390_PC32        =  5,
+  R_390_GOT12       =  6,
+  R_390_GOT32       =  7,
+  R_390_PLT32       =  8,
+  R_390_COPY        =  9,
+  R_390_GLOB_DAT    = 10,
+  R_390_JMP_SLOT    = 11,
+  R_390_RELATIVE    = 12,
+  R_390_GOTOFF      = 13,
+  R_390_GOTPC       = 14,
+  R_390_GOT16       = 15,
+  R_390_PC16        = 16,
+  R_390_PC16DBL     = 17,
+  R_390_PLT16DBL    = 18,
+  R_390_PC32DBL     = 19,
+  R_390_PLT32DBL    = 20,
+  R_390_GOTPCDBL    = 21,
+  R_390_64          = 22,
+  R_390_PC64        = 23,
+  R_390_GOT64       = 24,
+  R_390_PLT64       = 25,
+  R_390_GOTENT      = 26,
+  R_390_GOTOFF16    = 27,
+  R_390_GOTOFF64    = 28,
+  R_390_GOTPLT12    = 29,
+  R_390_GOTPLT16    = 30,
+  R_390_GOTPLT32    = 31,
+  R_390_GOTPLT64    = 32,
+  R_390_GOTPLTENT   = 33,
+  R_390_PLTOFF16    = 34,
+  R_390_PLTOFF32    = 35,
+  R_390_PLTOFF64    = 36,
+  R_390_TLS_LOAD    = 37,
+  R_390_TLS_GDCALL  = 38,
+  R_390_TLS_LDCALL  = 39,
+  R_390_TLS_GD32    = 40,
+  R_390_TLS_GD64    = 41,
+  R_390_TLS_GOTIE12 = 42,
+  R_390_TLS_GOTIE32 = 43,
+  R_390_TLS_GOTIE64 = 44,
+  R_390_TLS_LDM32   = 45,
+  R_390_TLS_LDM64   = 46,
+  R_390_TLS_IE32    = 47,
+  R_390_TLS_IE64    = 48,
+  R_390_TLS_IEENT   = 49,
+  R_390_TLS_LE32    = 50,
+  R_390_TLS_LE64    = 51,
+  R_390_TLS_LDO32   = 52,
+  R_390_TLS_LDO64   = 53,
+  R_390_TLS_DTPMOD  = 54,
+  R_390_TLS_DTPOFF  = 55,
+  R_390_TLS_TPOFF   = 56,
+  R_390_20          = 57,
+  R_390_GOT20       = 58,
+  R_390_GOTPLT20    = 59,
+  R_390_TLS_GOTIE20 = 60,
+  R_390_IRELATIVE   = 61
+};
+
+// ELF Relocation type for Sparc.
+enum {
+  R_SPARC_NONE        = 0,
+  R_SPARC_8           = 1,
+  R_SPARC_16          = 2,
+  R_SPARC_32          = 3,
+  R_SPARC_DISP8       = 4,
+  R_SPARC_DISP16      = 5,
+  R_SPARC_DISP32      = 6,
+  R_SPARC_WDISP30     = 7,
+  R_SPARC_WDISP22     = 8,
+  R_SPARC_HI22        = 9,
+  R_SPARC_22          = 10,
+  R_SPARC_13          = 11,
+  R_SPARC_LO10        = 12,
+  R_SPARC_GOT10       = 13,
+  R_SPARC_GOT13       = 14,
+  R_SPARC_GOT22       = 15,
+  R_SPARC_PC10        = 16,
+  R_SPARC_PC22        = 17,
+  R_SPARC_WPLT30      = 18,
+  R_SPARC_COPY        = 19,
+  R_SPARC_GLOB_DAT    = 20,
+  R_SPARC_JMP_SLOT    = 21,
+  R_SPARC_RELATIVE    = 22,
+  R_SPARC_UA32        = 23,
+  R_SPARC_PLT32       = 24,
+  R_SPARC_HIPLT22     = 25,
+  R_SPARC_LOPLT10     = 26,
+  R_SPARC_PCPLT32     = 27,
+  R_SPARC_PCPLT22     = 28,
+  R_SPARC_PCPLT10     = 29,
+  R_SPARC_10          = 30,
+  R_SPARC_11          = 31,
+  R_SPARC_64          = 32,
+  R_SPARC_OLO10       = 33,
+  R_SPARC_HH22        = 34,
+  R_SPARC_HM10        = 35,
+  R_SPARC_LM22        = 36,
+  R_SPARC_PC_HH22     = 37,
+  R_SPARC_PC_HM10     = 38,
+  R_SPARC_PC_LM22     = 39,
+  R_SPARC_WDISP16     = 40,
+  R_SPARC_WDISP19     = 41,
+  R_SPARC_7           = 43,
+  R_SPARC_5           = 44,
+  R_SPARC_6           = 45,
+  R_SPARC_DISP64      = 46,
+  R_SPARC_PLT64       = 47,
+  R_SPARC_HIX22       = 48,
+  R_SPARC_LOX10       = 49,
+  R_SPARC_H44         = 50,
+  R_SPARC_M44         = 51,
+  R_SPARC_L44         = 52,
+  R_SPARC_REGISTER    = 53,
+  R_SPARC_UA64        = 54,
+  R_SPARC_UA16        = 55,
+  R_SPARC_TLS_GD_HI22   = 56,
+  R_SPARC_TLS_GD_LO10   = 57,
+  R_SPARC_TLS_GD_ADD    = 58,
+  R_SPARC_TLS_GD_CALL   = 59,
+  R_SPARC_TLS_LDM_HI22  = 60,
+  R_SPARC_TLS_LDM_LO10  = 61,
+  R_SPARC_TLS_LDM_ADD   = 62,
+  R_SPARC_TLS_LDM_CALL  = 63,
+  R_SPARC_TLS_LDO_HIX22 = 64,
+  R_SPARC_TLS_LDO_LOX10 = 65,
+  R_SPARC_TLS_LDO_ADD   = 66,
+  R_SPARC_TLS_IE_HI22   = 67,
+  R_SPARC_TLS_IE_LO10   = 68,
+  R_SPARC_TLS_IE_LD     = 69,
+  R_SPARC_TLS_IE_LDX    = 70,
+  R_SPARC_TLS_IE_ADD    = 71,
+  R_SPARC_TLS_LE_HIX22  = 72,
+  R_SPARC_TLS_LE_LOX10  = 73,
+  R_SPARC_TLS_DTPMOD32  = 74,
+  R_SPARC_TLS_DTPMOD64  = 75,
+  R_SPARC_TLS_DTPOFF32  = 76,
+  R_SPARC_TLS_DTPOFF64  = 77,
+  R_SPARC_TLS_TPOFF32   = 78,
+  R_SPARC_TLS_TPOFF64   = 79,
+  R_SPARC_GOTDATA_HIX22 = 80,
+  R_SPARC_GOTDATA_LOX22 = 81,
+  R_SPARC_GOTDATA_OP_HIX22 = 82,
+  R_SPARC_GOTDATA_OP_LOX22 = 83,
+  R_SPARC_GOTDATA_OP    = 84
+};
+
+// Section header.
+struct Elf32_Shdr {
+  Elf32_Word sh_name;      // Section name (index into string table)
+  Elf32_Word sh_type;      // Section type (SHT_*)
+  Elf32_Word sh_flags;     // Section flags (SHF_*)
+  Elf32_Addr sh_addr;      // Address where section is to be loaded
+  Elf32_Off  sh_offset;    // File offset of section data, in bytes
+  Elf32_Word sh_size;      // Size of section, in bytes
+  Elf32_Word sh_link;      // Section type-specific header table index link
+  Elf32_Word sh_info;      // Section type-specific extra information
+  Elf32_Word sh_addralign; // Section address alignment
+  Elf32_Word sh_entsize;   // Size of records contained within the section
+};
+
+// Section header for ELF64 - same fields as ELF32, different types.
+struct Elf64_Shdr {
+  Elf64_Word  sh_name;
+  Elf64_Word  sh_type;
+  Elf64_Xword sh_flags;
+  Elf64_Addr  sh_addr;
+  Elf64_Off   sh_offset;
+  Elf64_Xword sh_size;
+  Elf64_Word  sh_link;
+  Elf64_Word  sh_info;
+  Elf64_Xword sh_addralign;
+  Elf64_Xword sh_entsize;
+};
+
+// Special section indices.
+enum {
+  SHN_UNDEF     = 0,      // Undefined, missing, irrelevant, or meaningless
+  SHN_LORESERVE = 0xff00, // Lowest reserved index
+  SHN_LOPROC    = 0xff00, // Lowest processor-specific index
+  SHN_HIPROC    = 0xff1f, // Highest processor-specific index
+  SHN_LOOS      = 0xff20, // Lowest operating system-specific index
+  SHN_HIOS      = 0xff3f, // Highest operating system-specific index
+  SHN_ABS       = 0xfff1, // Symbol has absolute value; does not need relocation
+  SHN_COMMON    = 0xfff2, // FORTRAN COMMON or C external global variables
+  SHN_XINDEX    = 0xffff, // Mark that the index is >= SHN_LORESERVE
+  SHN_HIRESERVE = 0xffff  // Highest reserved index
+};
+
+// Section types.
+enum : unsigned {
+  SHT_NULL          = 0,  // No associated section (inactive entry).
+  SHT_PROGBITS      = 1,  // Program-defined contents.
+  SHT_SYMTAB        = 2,  // Symbol table.
+  SHT_STRTAB        = 3,  // String table.
+  SHT_RELA          = 4,  // Relocation entries; explicit addends.
+  SHT_HASH          = 5,  // Symbol hash table.
+  SHT_DYNAMIC       = 6,  // Information for dynamic linking.
+  SHT_NOTE          = 7,  // Information about the file.
+  SHT_NOBITS        = 8,  // Data occupies no space in the file.
+  SHT_REL           = 9,  // Relocation entries; no explicit addends.
+  SHT_SHLIB         = 10, // Reserved.
+  SHT_DYNSYM        = 11, // Symbol table.
+  SHT_INIT_ARRAY    = 14, // Pointers to initialization functions.
+  SHT_FINI_ARRAY    = 15, // Pointers to termination functions.
+  SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
+  SHT_GROUP         = 17, // Section group.
+  SHT_SYMTAB_SHNDX  = 18, // Indices for SHN_XINDEX entries.
+  SHT_LOOS          = 0x60000000, // Lowest operating system-specific type.
+  SHT_GNU_ATTRIBUTES= 0x6ffffff5, // Object attributes.
+  SHT_GNU_HASH      = 0x6ffffff6, // GNU-style hash table.
+  SHT_GNU_verdef    = 0x6ffffffd, // GNU version definitions.
+  SHT_GNU_verneed   = 0x6ffffffe, // GNU version references.
+  SHT_GNU_versym    = 0x6fffffff, // GNU symbol versions table.
+  SHT_HIOS          = 0x6fffffff, // Highest operating system-specific type.
+  SHT_LOPROC        = 0x70000000, // Lowest processor arch-specific type.
+  // Fixme: All this is duplicated in MCSectionELF. Why??
+  // Exception Index table
+  SHT_ARM_EXIDX           = 0x70000001U,
+  // BPABI DLL dynamic linking pre-emption map
+  SHT_ARM_PREEMPTMAP      = 0x70000002U,
+  //  Object file compatibility attributes
+  SHT_ARM_ATTRIBUTES      = 0x70000003U,
+  SHT_ARM_DEBUGOVERLAY    = 0x70000004U,
+  SHT_ARM_OVERLAYSECTION  = 0x70000005U,
+  SHT_HEX_ORDERED         = 0x70000000, // Link editor is to sort the entries in
+                                        // this section based on their sizes
+  SHT_X86_64_UNWIND       = 0x70000001, // Unwind information
+
+  SHT_MIPS_REGINFO        = 0x70000006, // Register usage information
+  SHT_MIPS_OPTIONS        = 0x7000000d, // General options
+  SHT_MIPS_ABIFLAGS       = 0x7000002a, // ABI information.
+
+  SHT_HIPROC        = 0x7fffffff, // Highest processor arch-specific type.
+  SHT_LOUSER        = 0x80000000, // Lowest type reserved for applications.
+  SHT_HIUSER        = 0xffffffff  // Highest type reserved for applications.
+};
+
+// Section flags.
+enum : unsigned {
+  // Section data should be writable during execution.
+  SHF_WRITE = 0x1,
+
+  // Section occupies memory during program execution.
+  SHF_ALLOC = 0x2,
+
+  // Section contains executable machine instructions.
+  SHF_EXECINSTR = 0x4,
+
+  // The data in this section may be merged.
+  SHF_MERGE = 0x10,
+
+  // The data in this section is null-terminated strings.
+  SHF_STRINGS = 0x20,
+
+  // A field in this section holds a section header table index.
+  SHF_INFO_LINK = 0x40U,
+
+  // Adds special ordering requirements for link editors.
+  SHF_LINK_ORDER = 0x80U,
+
+  // This section requires special OS-specific processing to avoid incorrect
+  // behavior.
+  SHF_OS_NONCONFORMING = 0x100U,
+
+  // This section is a member of a section group.
+  SHF_GROUP = 0x200U,
+
+  // This section holds Thread-Local Storage.
+  SHF_TLS = 0x400U,
+
+  // This section is excluded from the final executable or shared library.
+  SHF_EXCLUDE = 0x80000000U,
+
+  // Start of target-specific flags.
+
+  /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
+  /// together by the linker to form the constant pool and the cp register is
+  /// set to the start of the constant pool by the boot code.
+  XCORE_SHF_CP_SECTION = 0x800U,
+
+  /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
+  /// together by the linker to form the data section and the dp register is
+  /// set to the start of the section by the boot code.
+  XCORE_SHF_DP_SECTION = 0x1000U,
+
+  SHF_MASKOS   = 0x0ff00000,
+
+  // Bits indicating processor-specific flags.
+  SHF_MASKPROC = 0xf0000000,
+
+  // If an object file section does not have this flag set, then it may not hold
+  // more than 2GB and can be freely referred to in objects using smaller code
+  // models. Otherwise, only objects using larger code models can refer to them.
+  // For example, a medium code model object can refer to data in a section that
+  // sets this flag besides being able to refer to data in a section that does
+  // not set it; likewise, a small code model object can refer only to code in a
+  // section that does not set this flag.
+  SHF_X86_64_LARGE = 0x10000000,
+
+  // All sections with the GPREL flag are grouped into a global data area
+  // for faster accesses
+  SHF_HEX_GPREL = 0x10000000,
+
+  // Section contains text/data which may be replicated in other sections.
+  // Linker must retain only one copy.
+  SHF_MIPS_NODUPES = 0x01000000,
+
+  // Linker must generate implicit hidden weak names.
+  SHF_MIPS_NAMES   = 0x02000000,
+
+  // Section data local to process.
+  SHF_MIPS_LOCAL   = 0x04000000,
+
+  // Do not strip this section.
+  SHF_MIPS_NOSTRIP = 0x08000000,
+
+  // Section must be part of global data area.
+  SHF_MIPS_GPREL   = 0x10000000,
+
+  // This section should be merged.
+  SHF_MIPS_MERGE   = 0x20000000,
+
+  // Address size to be inferred from section entry size.
+  SHF_MIPS_ADDR    = 0x40000000,
+
+  // Section data is string data by default.
+  SHF_MIPS_STRING  = 0x80000000
+};
+
+// Section Group Flags
+enum : unsigned {
+  GRP_COMDAT = 0x1,
+  GRP_MASKOS = 0x0ff00000,
+  GRP_MASKPROC = 0xf0000000
+};
+
+// Symbol table entries for ELF32.
+struct Elf32_Sym {
+  Elf32_Word    st_name;  // Symbol name (index into string table)
+  Elf32_Addr    st_value; // Value or address associated with the symbol
+  Elf32_Word    st_size;  // Size of the symbol
+  unsigned char st_info;  // Symbol's type and binding attributes
+  unsigned char st_other; // Must be zero; reserved
+  Elf32_Half    st_shndx; // Which section (header table index) it's defined in
+
+  // These accessors and mutators correspond to the ELF32_ST_BIND,
+  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+  unsigned char getBinding() const { return st_info >> 4; }
+  unsigned char getType() const { return st_info & 0x0f; }
+  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+  void setBindingAndType(unsigned char b, unsigned char t) {
+    st_info = (b << 4) + (t & 0x0f);
+  }
+};
+
+// Symbol table entries for ELF64.
+struct Elf64_Sym {
+  Elf64_Word      st_name;  // Symbol name (index into string table)
+  unsigned char   st_info;  // Symbol's type and binding attributes
+  unsigned char   st_other; // Must be zero; reserved
+  Elf64_Half      st_shndx; // Which section (header tbl index) it's defined in
+  Elf64_Addr      st_value; // Value or address associated with the symbol
+  Elf64_Xword     st_size;  // Size of the symbol
+
+  // These accessors and mutators are identical to those defined for ELF32
+  // symbol table entries.
+  unsigned char getBinding() const { return st_info >> 4; }
+  unsigned char getType() const { return st_info & 0x0f; }
+  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+  void setBindingAndType(unsigned char b, unsigned char t) {
+    st_info = (b << 4) + (t & 0x0f);
+  }
+};
+
+// The size (in bytes) of symbol table entries.
+enum {
+  SYMENTRY_SIZE32 = 16, // 32-bit symbol entry size
+  SYMENTRY_SIZE64 = 24  // 64-bit symbol entry size.
+};
+
+// Symbol bindings.
+enum {
+  STB_LOCAL = 0,   // Local symbol, not visible outside obj file containing def
+  STB_GLOBAL = 1,  // Global symbol, visible to all object files being combined
+  STB_WEAK = 2,    // Weak symbol, like global but lower-precedence
+  STB_LOOS   = 10, // Lowest operating system-specific binding type
+  STB_HIOS   = 12, // Highest operating system-specific binding type
+  STB_LOPROC = 13, // Lowest processor-specific binding type
+  STB_HIPROC = 15  // Highest processor-specific binding type
+};
+
+// Symbol types.
+enum {
+  STT_NOTYPE  = 0,   // Symbol's type is not specified
+  STT_OBJECT  = 1,   // Symbol is a data object (variable, array, etc.)
+  STT_FUNC    = 2,   // Symbol is executable code (function, etc.)
+  STT_SECTION = 3,   // Symbol refers to a section
+  STT_FILE    = 4,   // Local, absolute symbol that refers to a file
+  STT_COMMON  = 5,   // An uninitialized common block
+  STT_TLS     = 6,   // Thread local data object
+  STT_LOOS    = 7,   // Lowest operating system-specific symbol type
+  STT_HIOS    = 8,   // Highest operating system-specific symbol type
+  STT_GNU_IFUNC = 10, // GNU indirect function
+  STT_LOPROC  = 13,  // Lowest processor-specific symbol type
+  STT_HIPROC  = 15   // Highest processor-specific symbol type
+};
+
+enum {
+  STV_DEFAULT   = 0,  // Visibility is specified by binding type
+  STV_INTERNAL  = 1,  // Defined by processor supplements
+  STV_HIDDEN    = 2,  // Not visible to other components
+  STV_PROTECTED = 3   // Visible in other components but not preemptable
+};
+
+// Symbol number.
+enum {
+  STN_UNDEF = 0
+};
+
+// Relocation entry, without explicit addend.
+struct Elf32_Rel {
+  Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+  Elf32_Word r_info;   // Symbol table index and type of relocation to apply
+
+  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+  // and ELF32_R_INFO macros defined in the ELF specification:
+  Elf32_Word getSymbol() const { return (r_info >> 8); }
+  unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+  void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
+  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(Elf32_Word s, unsigned char t) {
+    r_info = (s << 8) + t;
+  }
+};
+
+// Relocation entry with explicit addend.
+struct Elf32_Rela {
+  Elf32_Addr  r_offset; // Location (file byte offset, or program virtual addr)
+  Elf32_Word  r_info;   // Symbol table index and type of relocation to apply
+  Elf32_Sword r_addend; // Compute value for relocatable field by adding this
+
+  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+  // and ELF32_R_INFO macros defined in the ELF specification:
+  Elf32_Word getSymbol() const { return (r_info >> 8); }
+  unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+  void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
+  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(Elf32_Word s, unsigned char t) {
+    r_info = (s << 8) + t;
+  }
+};
+
+// Relocation entry, without explicit addend.
+struct Elf64_Rel {
+  Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
+  Elf64_Xword r_info;   // Symbol table index and type of relocation to apply.
+
+  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+  // and ELF64_R_INFO macros defined in the ELF specification:
+  Elf64_Word getSymbol() const { return (r_info >> 32); }
+  Elf64_Word getType() const {
+    return (Elf64_Word) (r_info & 0xffffffffL);
+  }
+  void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+  void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+    r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
+  }
+};
+
+// Relocation entry with explicit addend.
+struct Elf64_Rela {
+  Elf64_Addr  r_offset; // Location (file byte offset, or program virtual addr).
+  Elf64_Xword  r_info;   // Symbol table index and type of relocation to apply.
+  Elf64_Sxword r_addend; // Compute value for relocatable field by adding this.
+
+  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+  // and ELF64_R_INFO macros defined in the ELF specification:
+  Elf64_Word getSymbol() const { return (r_info >> 32); }
+  Elf64_Word getType() const {
+    return (Elf64_Word) (r_info & 0xffffffffL);
+  }
+  void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+  void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+  void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+    r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
+  }
+};
+
+// Program header for ELF32.
+struct Elf32_Phdr {
+  Elf32_Word p_type;   // Type of segment
+  Elf32_Off  p_offset; // File offset where segment is located, in bytes
+  Elf32_Addr p_vaddr;  // Virtual address of beginning of segment
+  Elf32_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
+  Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+  Elf32_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
+  Elf32_Word p_flags;  // Segment flags
+  Elf32_Word p_align;  // Segment alignment constraint
+};
+
+// Program header for ELF64.
+struct Elf64_Phdr {
+  Elf64_Word   p_type;   // Type of segment
+  Elf64_Word   p_flags;  // Segment flags
+  Elf64_Off    p_offset; // File offset where segment is located, in bytes
+  Elf64_Addr   p_vaddr;  // Virtual address of beginning of segment
+  Elf64_Addr   p_paddr;  // Physical addr of beginning of segment (OS-specific)
+  Elf64_Xword  p_filesz; // Num. of bytes in file image of segment (may be zero)
+  Elf64_Xword  p_memsz;  // Num. of bytes in mem image of segment (may be zero)
+  Elf64_Xword  p_align;  // Segment alignment constraint
+};
+
+// Segment types.
+enum {
+  PT_NULL    = 0, // Unused segment.
+  PT_LOAD    = 1, // Loadable segment.
+  PT_DYNAMIC = 2, // Dynamic linking information.
+  PT_INTERP  = 3, // Interpreter pathname.
+  PT_NOTE    = 4, // Auxiliary information.
+  PT_SHLIB   = 5, // Reserved.
+  PT_PHDR    = 6, // The program header table itself.
+  PT_TLS     = 7, // The thread-local storage template.
+  PT_LOOS    = 0x60000000, // Lowest operating system-specific pt entry type.
+  PT_HIOS    = 0x6fffffff, // Highest operating system-specific pt entry type.
+  PT_LOPROC  = 0x70000000, // Lowest processor-specific program hdr entry type.
+  PT_HIPROC  = 0x7fffffff, // Highest processor-specific program hdr entry type.
+
+  // x86-64 program header types.
+  // These all contain stack unwind tables.
+  PT_GNU_EH_FRAME  = 0x6474e550,
+  PT_SUNW_EH_FRAME = 0x6474e550,
+  PT_SUNW_UNWIND   = 0x6464e550,
+
+  PT_GNU_STACK  = 0x6474e551, // Indicates stack executability.
+  PT_GNU_RELRO  = 0x6474e552, // Read-only after relocation.
+
+  // ARM program header types.
+  PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info
+  // These all contain stack unwind tables.
+  PT_ARM_EXIDX   = 0x70000001,
+  PT_ARM_UNWIND  = 0x70000001,
+
+  // MIPS program header types.
+  PT_MIPS_REGINFO  = 0x70000000,  // Register usage information.
+  PT_MIPS_RTPROC   = 0x70000001,  // Runtime procedure table.
+  PT_MIPS_OPTIONS  = 0x70000002,  // Options segment.
+  PT_MIPS_ABIFLAGS = 0x70000003   // Abiflags segment.
+};
+
+// Segment flag bits.
+enum : unsigned {
+  PF_X        = 1,         // Execute
+  PF_W        = 2,         // Write
+  PF_R        = 4,         // Read
+  PF_MASKOS   = 0x0ff00000,// Bits for operating system-specific semantics.
+  PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics.
+};
+
+// Dynamic table entry for ELF32.
+struct Elf32_Dyn
+{
+  Elf32_Sword d_tag;            // Type of dynamic table entry.
+  union
+  {
+      Elf32_Word d_val;         // Integer value of entry.
+      Elf32_Addr d_ptr;         // Pointer value of entry.
+  } d_un;
+};
+
+// Dynamic table entry for ELF64.
+struct Elf64_Dyn
+{
+  Elf64_Sxword d_tag;           // Type of dynamic table entry.
+  union
+  {
+      Elf64_Xword d_val;        // Integer value of entry.
+      Elf64_Addr  d_ptr;        // Pointer value of entry.
+  } d_un;
+};
+
+// Dynamic table entry tags.
+enum {
+  DT_NULL         = 0,        // Marks end of dynamic array.
+  DT_NEEDED       = 1,        // String table offset of needed library.
+  DT_PLTRELSZ     = 2,        // Size of relocation entries in PLT.
+  DT_PLTGOT       = 3,        // Address associated with linkage table.
+  DT_HASH         = 4,        // Address of symbolic hash table.
+  DT_STRTAB       = 5,        // Address of dynamic string table.
+  DT_SYMTAB       = 6,        // Address of dynamic symbol table.
+  DT_RELA         = 7,        // Address of relocation table (Rela entries).
+  DT_RELASZ       = 8,        // Size of Rela relocation table.
+  DT_RELAENT      = 9,        // Size of a Rela relocation entry.
+  DT_STRSZ        = 10,       // Total size of the string table.
+  DT_SYMENT       = 11,       // Size of a symbol table entry.
+  DT_INIT         = 12,       // Address of initialization function.
+  DT_FINI         = 13,       // Address of termination function.
+  DT_SONAME       = 14,       // String table offset of a shared objects name.
+  DT_RPATH        = 15,       // String table offset of library search path.
+  DT_SYMBOLIC     = 16,       // Changes symbol resolution algorithm.
+  DT_REL          = 17,       // Address of relocation table (Rel entries).
+  DT_RELSZ        = 18,       // Size of Rel relocation table.
+  DT_RELENT       = 19,       // Size of a Rel relocation entry.
+  DT_PLTREL       = 20,       // Type of relocation entry used for linking.
+  DT_DEBUG        = 21,       // Reserved for debugger.
+  DT_TEXTREL      = 22,       // Relocations exist for non-writable segments.
+  DT_JMPREL       = 23,       // Address of relocations associated with PLT.
+  DT_BIND_NOW     = 24,       // Process all relocations before execution.
+  DT_INIT_ARRAY   = 25,       // Pointer to array of initialization functions.
+  DT_FINI_ARRAY   = 26,       // Pointer to array of termination functions.
+  DT_INIT_ARRAYSZ = 27,       // Size of DT_INIT_ARRAY.
+  DT_FINI_ARRAYSZ = 28,       // Size of DT_FINI_ARRAY.
+  DT_RUNPATH      = 29,       // String table offset of lib search path.
+  DT_FLAGS        = 30,       // Flags.
+  DT_ENCODING     = 32,       // Values from here to DT_LOOS follow the rules
+                              // for the interpretation of the d_un union.
+
+  DT_PREINIT_ARRAY = 32,      // Pointer to array of preinit functions.
+  DT_PREINIT_ARRAYSZ = 33,    // Size of the DT_PREINIT_ARRAY array.
+
+  DT_LOOS         = 0x60000000, // Start of environment specific tags.
+  DT_HIOS         = 0x6FFFFFFF, // End of environment specific tags.
+  DT_LOPROC       = 0x70000000, // Start of processor specific tags.
+  DT_HIPROC       = 0x7FFFFFFF, // End of processor specific tags.
+
+  DT_GNU_HASH     = 0x6FFFFEF5, // Reference to the GNU hash table.
+  DT_RELACOUNT    = 0x6FFFFFF9, // ELF32_Rela count.
+  DT_RELCOUNT     = 0x6FFFFFFA, // ELF32_Rel count.
+
+  DT_FLAGS_1      = 0X6FFFFFFB, // Flags_1.
+  DT_VERSYM       = 0x6FFFFFF0, // The address of .gnu.version section.
+  DT_VERDEF       = 0X6FFFFFFC, // The address of the version definition table.
+  DT_VERDEFNUM    = 0X6FFFFFFD, // The number of entries in DT_VERDEF.
+  DT_VERNEED      = 0X6FFFFFFE, // The address of the version Dependency table.
+  DT_VERNEEDNUM   = 0X6FFFFFFF, // The number of entries in DT_VERNEED.
+
+  // Mips specific dynamic table entry tags.
+  DT_MIPS_RLD_VERSION   = 0x70000001, // 32 bit version number for runtime
+                                      // linker interface.
+  DT_MIPS_TIME_STAMP    = 0x70000002, // Time stamp.
+  DT_MIPS_ICHECKSUM     = 0x70000003, // Checksum of external strings
+                                      // and common sizes.
+  DT_MIPS_IVERSION      = 0x70000004, // Index of version string
+                                      // in string table.
+  DT_MIPS_FLAGS         = 0x70000005, // 32 bits of flags.
+  DT_MIPS_BASE_ADDRESS  = 0x70000006, // Base address of the segment.
+  DT_MIPS_MSYM          = 0x70000007, // Address of .msym section.
+  DT_MIPS_CONFLICT      = 0x70000008, // Address of .conflict section.
+  DT_MIPS_LIBLIST       = 0x70000009, // Address of .liblist section.
+  DT_MIPS_LOCAL_GOTNO   = 0x7000000a, // Number of local global offset
+                                      // table entries.
+  DT_MIPS_CONFLICTNO    = 0x7000000b, // Number of entries
+                                      // in the .conflict section.
+  DT_MIPS_LIBLISTNO     = 0x70000010, // Number of entries
+                                      // in the .liblist section.
+  DT_MIPS_SYMTABNO      = 0x70000011, // Number of entries
+                                      // in the .dynsym section.
+  DT_MIPS_UNREFEXTNO    = 0x70000012, // Index of first external dynamic symbol
+                                      // not referenced locally.
+  DT_MIPS_GOTSYM        = 0x70000013, // Index of first dynamic symbol
+                                      // in global offset table.
+  DT_MIPS_HIPAGENO      = 0x70000014, // Number of page table entries
+                                      // in global offset table.
+  DT_MIPS_RLD_MAP       = 0x70000016, // Address of run time loader map,
+                                      // used for debugging.
+  DT_MIPS_DELTA_CLASS       = 0x70000017, // Delta C++ class definition.
+  DT_MIPS_DELTA_CLASS_NO    = 0x70000018, // Number of entries
+                                          // in DT_MIPS_DELTA_CLASS.
+  DT_MIPS_DELTA_INSTANCE    = 0x70000019, // Delta C++ class instances.
+  DT_MIPS_DELTA_INSTANCE_NO = 0x7000001A, // Number of entries
+                                          // in DT_MIPS_DELTA_INSTANCE.
+  DT_MIPS_DELTA_RELOC       = 0x7000001B, // Delta relocations.
+  DT_MIPS_DELTA_RELOC_NO    = 0x7000001C, // Number of entries
+                                          // in DT_MIPS_DELTA_RELOC.
+  DT_MIPS_DELTA_SYM         = 0x7000001D, // Delta symbols that Delta
+                                          // relocations refer to.
+  DT_MIPS_DELTA_SYM_NO      = 0x7000001E, // Number of entries
+                                          // in DT_MIPS_DELTA_SYM.
+  DT_MIPS_DELTA_CLASSSYM    = 0x70000020, // Delta symbols that hold
+                                          // class declarations.
+  DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021, // Number of entries
+                                          // in DT_MIPS_DELTA_CLASSSYM.
+  DT_MIPS_CXX_FLAGS         = 0x70000022, // Flags indicating information
+                                          // about C++ flavor.
+  DT_MIPS_PIXIE_INIT        = 0x70000023, // Pixie information.
+  DT_MIPS_SYMBOL_LIB        = 0x70000024, // Address of .MIPS.symlib
+  DT_MIPS_LOCALPAGE_GOTIDX  = 0x70000025, // The GOT index of the first PTE
+                                          // for a segment
+  DT_MIPS_LOCAL_GOTIDX      = 0x70000026, // The GOT index of the first PTE
+                                          // for a local symbol
+  DT_MIPS_HIDDEN_GOTIDX     = 0x70000027, // The GOT index of the first PTE
+                                          // for a hidden symbol
+  DT_MIPS_PROTECTED_GOTIDX  = 0x70000028, // The GOT index of the first PTE
+                                          // for a protected symbol
+  DT_MIPS_OPTIONS           = 0x70000029, // Address of `.MIPS.options'.
+  DT_MIPS_INTERFACE         = 0x7000002A, // Address of `.interface'.
+  DT_MIPS_DYNSTR_ALIGN      = 0x7000002B, // Unknown.
+  DT_MIPS_INTERFACE_SIZE    = 0x7000002C, // Size of the .interface section.
+  DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002D, // Size of rld_text_resolve
+                                              // function stored in the GOT.
+  DT_MIPS_PERF_SUFFIX       = 0x7000002E, // Default suffix of DSO to be added
+                                          // by rld on dlopen() calls.
+  DT_MIPS_COMPACT_SIZE      = 0x7000002F, // Size of compact relocation
+                                          // section (O32).
+  DT_MIPS_GP_VALUE          = 0x70000030, // GP value for auxiliary GOTs.
+  DT_MIPS_AUX_DYNAMIC       = 0x70000031, // Address of auxiliary .dynamic.
+  DT_MIPS_PLTGOT            = 0x70000032, // Address of the base of the PLTGOT.
+  DT_MIPS_RWPLT             = 0x70000034  // Points to the base
+                                          // of a writable PLT.
+};
+
+// DT_FLAGS values.
+enum {
+  DF_ORIGIN     = 0x01, // The object may reference $ORIGIN.
+  DF_SYMBOLIC   = 0x02, // Search the shared lib before searching the exe.
+  DF_TEXTREL    = 0x04, // Relocations may modify a non-writable segment.
+  DF_BIND_NOW   = 0x08, // Process all relocations on load.
+  DF_STATIC_TLS = 0x10  // Reject attempts to load dynamically.
+};
+
+// State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry.
+enum {
+  DF_1_NOW        = 0x00000001, // Set RTLD_NOW for this object.
+  DF_1_GLOBAL     = 0x00000002, // Set RTLD_GLOBAL for this object.
+  DF_1_GROUP      = 0x00000004, // Set RTLD_GROUP for this object.
+  DF_1_NODELETE   = 0x00000008, // Set RTLD_NODELETE for this object.
+  DF_1_LOADFLTR   = 0x00000010, // Trigger filtee loading at runtime.
+  DF_1_INITFIRST  = 0x00000020, // Set RTLD_INITFIRST for this object.
+  DF_1_NOOPEN     = 0x00000040, // Set RTLD_NOOPEN for this object.
+  DF_1_ORIGIN     = 0x00000080, // $ORIGIN must be handled.
+  DF_1_DIRECT     = 0x00000100, // Direct binding enabled.
+  DF_1_TRANS      = 0x00000200,
+  DF_1_INTERPOSE  = 0x00000400, // Object is used to interpose.
+  DF_1_NODEFLIB   = 0x00000800, // Ignore default lib search path.
+  DF_1_NODUMP     = 0x00001000, // Object can't be dldump'ed.
+  DF_1_CONFALT    = 0x00002000, // Configuration alternative created.
+  DF_1_ENDFILTEE  = 0x00004000, // Filtee terminates filters search.
+  DF_1_DISPRELDNE = 0x00008000, // Disp reloc applied at build time.
+  DF_1_DISPRELPND = 0x00010000  // Disp reloc applied at run-time.
+};
+
+// DT_MIPS_FLAGS values.
+enum {
+  RHF_NONE                    = 0x00000000, // No flags.
+  RHF_QUICKSTART              = 0x00000001, // Uses shortcut pointers.
+  RHF_NOTPOT                  = 0x00000002, // Hash size is not a power of two.
+  RHS_NO_LIBRARY_REPLACEMENT  = 0x00000004, // Ignore LD_LIBRARY_PATH.
+  RHF_NO_MOVE                 = 0x00000008, // DSO address may not be relocated.
+  RHF_SGI_ONLY                = 0x00000010, // SGI specific features.
+  RHF_GUARANTEE_INIT          = 0x00000020, // Guarantee that .init will finish
+                                            // executing before any non-init
+                                            // code in DSO is called.
+  RHF_DELTA_C_PLUS_PLUS       = 0x00000040, // Contains Delta C++ code.
+  RHF_GUARANTEE_START_INIT    = 0x00000080, // Guarantee that .init will start
+                                            // executing before any non-init
+                                            // code in DSO is called.
+  RHF_PIXIE                   = 0x00000100, // Generated by pixie.
+  RHF_DEFAULT_DELAY_LOAD      = 0x00000200, // Delay-load DSO by default.
+  RHF_REQUICKSTART            = 0x00000400, // Object may be requickstarted
+  RHF_REQUICKSTARTED          = 0x00000800, // Object has been requickstarted
+  RHF_CORD                    = 0x00001000, // Generated by cord.
+  RHF_NO_UNRES_UNDEF          = 0x00002000, // Object contains no unresolved
+                                            // undef symbols.
+  RHF_RLD_ORDER_SAFE          = 0x00004000  // Symbol table is in a safe order.
+};
+
+// ElfXX_VerDef structure version (GNU versioning)
+enum {
+  VER_DEF_NONE    = 0,
+  VER_DEF_CURRENT = 1
+};
+
+// VerDef Flags (ElfXX_VerDef::vd_flags)
+enum {
+  VER_FLG_BASE = 0x1,
+  VER_FLG_WEAK = 0x2,
+  VER_FLG_INFO = 0x4
+};
+
+// Special constants for the version table. (SHT_GNU_versym/.gnu.version)
+enum {
+  VER_NDX_LOCAL  = 0,      // Unversioned local symbol
+  VER_NDX_GLOBAL = 1,      // Unversioned global symbol
+  VERSYM_VERSION = 0x7fff, // Version Index mask
+  VERSYM_HIDDEN  = 0x8000  // Hidden bit (non-default version)
+};
+
+// ElfXX_VerNeed structure version (GNU versioning)
+enum {
+  VER_NEED_NONE = 0,
+  VER_NEED_CURRENT = 1
+};
+
+} // end namespace ELF
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
new file mode 100644
index 0000000..455d0fc
--- /dev/null
+++ b/include/llvm/Support/Endian.h
@@ -0,0 +1,190 @@
+//===- Endian.h - Utilities for IO with endian specific data ----*- 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 generic functions to read and write endian specific data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ENDIAN_H
+#define LLVM_SUPPORT_ENDIAN_H
+
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+
+namespace llvm {
+namespace support {
+enum endianness {big, little, native};
+
+// These are named values for common alignments.
+enum {aligned = 0, unaligned = 1};
+
+namespace detail {
+  /// \brief ::value is either alignment, or alignof(T) if alignment is 0.
+  template<class T, int alignment>
+  struct PickAlignment {
+    enum {value = alignment == 0 ? AlignOf<T>::Alignment : alignment};
+  };
+} // end namespace detail
+
+namespace endian {
+/// Swap the bytes of value to match the given endianness.
+template<typename value_type, endianness endian>
+inline value_type byte_swap(value_type value) {
+  if (endian != native && sys::IsBigEndianHost != (endian == big))
+    sys::swapByteOrder(value);
+  return value;
+}
+
+/// Read a value of a particular endianness from memory.
+template<typename value_type,
+         endianness endian,
+         std::size_t alignment>
+inline value_type read(const void *memory) {
+  value_type ret;
+
+  memcpy(&ret,
+         LLVM_ASSUME_ALIGNED(memory,
+           (detail::PickAlignment<value_type, alignment>::value)),
+         sizeof(value_type));
+  return byte_swap<value_type, endian>(ret);
+}
+
+/// Read a value of a particular endianness from a buffer, and increment the
+/// buffer past that value.
+template<typename value_type, endianness endian, std::size_t alignment>
+inline value_type readNext(const unsigned char *&memory) {
+  value_type ret = read<value_type, endian, alignment>(memory);
+  memory += sizeof(value_type);
+  return ret;
+}
+
+/// Write a value to memory with a particular endianness.
+template<typename value_type,
+         endianness endian,
+         std::size_t alignment>
+inline void write(void *memory, value_type value) {
+  value = byte_swap<value_type, endian>(value);
+  memcpy(LLVM_ASSUME_ALIGNED(memory,
+           (detail::PickAlignment<value_type, alignment>::value)),
+         &value,
+         sizeof(value_type));
+}
+} // end namespace endian
+
+namespace detail {
+template<typename value_type,
+         endianness endian,
+         std::size_t alignment>
+struct packed_endian_specific_integral {
+  operator value_type() const {
+    return endian::read<value_type, endian, alignment>(
+      (const void*)Value.buffer);
+  }
+
+  void operator=(value_type newValue) {
+    endian::write<value_type, endian, alignment>(
+      (void*)Value.buffer, newValue);
+  }
+
+private:
+  AlignedCharArray<PickAlignment<value_type, alignment>::value,
+                   sizeof(value_type)> Value;
+};
+} // end namespace detail
+
+typedef detail::packed_endian_specific_integral
+                  <uint8_t, little, unaligned>  ulittle8_t;
+typedef detail::packed_endian_specific_integral
+                  <uint16_t, little, unaligned> ulittle16_t;
+typedef detail::packed_endian_specific_integral
+                  <uint32_t, little, unaligned> ulittle32_t;
+typedef detail::packed_endian_specific_integral
+                  <uint64_t, little, unaligned> ulittle64_t;
+
+typedef detail::packed_endian_specific_integral
+                   <int8_t, little, unaligned>  little8_t;
+typedef detail::packed_endian_specific_integral
+                   <int16_t, little, unaligned> little16_t;
+typedef detail::packed_endian_specific_integral
+                   <int32_t, little, unaligned> little32_t;
+typedef detail::packed_endian_specific_integral
+                   <int64_t, little, unaligned> little64_t;
+
+typedef detail::packed_endian_specific_integral
+                    <uint8_t, little, aligned>  aligned_ulittle8_t;
+typedef detail::packed_endian_specific_integral
+                    <uint16_t, little, aligned> aligned_ulittle16_t;
+typedef detail::packed_endian_specific_integral
+                    <uint32_t, little, aligned> aligned_ulittle32_t;
+typedef detail::packed_endian_specific_integral
+                    <uint64_t, little, aligned> aligned_ulittle64_t;
+
+typedef detail::packed_endian_specific_integral
+                     <int8_t, little, aligned>  aligned_little8_t;
+typedef detail::packed_endian_specific_integral
+                     <int16_t, little, aligned> aligned_little16_t;
+typedef detail::packed_endian_specific_integral
+                     <int32_t, little, aligned> aligned_little32_t;
+typedef detail::packed_endian_specific_integral
+                     <int64_t, little, aligned> aligned_little64_t;
+
+typedef detail::packed_endian_specific_integral
+                  <uint8_t, big, unaligned>     ubig8_t;
+typedef detail::packed_endian_specific_integral
+                  <uint16_t, big, unaligned>    ubig16_t;
+typedef detail::packed_endian_specific_integral
+                  <uint32_t, big, unaligned>    ubig32_t;
+typedef detail::packed_endian_specific_integral
+                  <uint64_t, big, unaligned>    ubig64_t;
+
+typedef detail::packed_endian_specific_integral
+                   <int8_t, big, unaligned>     big8_t;
+typedef detail::packed_endian_specific_integral
+                   <int16_t, big, unaligned>    big16_t;
+typedef detail::packed_endian_specific_integral
+                   <int32_t, big, unaligned>    big32_t;
+typedef detail::packed_endian_specific_integral
+                   <int64_t, big, unaligned>    big64_t;
+
+typedef detail::packed_endian_specific_integral
+                    <uint8_t, big, aligned>     aligned_ubig8_t;
+typedef detail::packed_endian_specific_integral
+                    <uint16_t, big, aligned>    aligned_ubig16_t;
+typedef detail::packed_endian_specific_integral
+                    <uint32_t, big, aligned>    aligned_ubig32_t;
+typedef detail::packed_endian_specific_integral
+                    <uint64_t, big, aligned>    aligned_ubig64_t;
+
+typedef detail::packed_endian_specific_integral
+                     <int8_t, big, aligned>     aligned_big8_t;
+typedef detail::packed_endian_specific_integral
+                     <int16_t, big, aligned>    aligned_big16_t;
+typedef detail::packed_endian_specific_integral
+                     <int32_t, big, aligned>    aligned_big32_t;
+typedef detail::packed_endian_specific_integral
+                     <int64_t, big, aligned>    aligned_big64_t;
+
+typedef detail::packed_endian_specific_integral
+                  <uint16_t, native, unaligned> unaligned_uint16_t;
+typedef detail::packed_endian_specific_integral
+                  <uint32_t, native, unaligned> unaligned_uint32_t;
+typedef detail::packed_endian_specific_integral
+                  <uint64_t, native, unaligned> unaligned_uint64_t;
+
+typedef detail::packed_endian_specific_integral
+                   <int16_t, native, unaligned> unaligned_int16_t;
+typedef detail::packed_endian_specific_integral
+                   <int32_t, native, unaligned> unaligned_int32_t;
+typedef detail::packed_endian_specific_integral
+                   <int64_t, native, unaligned> unaligned_int64_t;
+} // end namespace llvm
+} // end namespace support
+
+#endif
diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h
new file mode 100644
index 0000000..89c66d3
--- /dev/null
+++ b/include/llvm/Support/EndianStream.h
@@ -0,0 +1,39 @@
+//===- EndianStream.h - Stream ops with endian specific data ----*- 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 utilities for operating on streams that have endian
+// specific data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_SUPPORT_ENDIAN_STREAM_H_
+#define _LLVM_SUPPORT_ENDIAN_STREAM_H_
+
+#include <llvm/Support/Endian.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+namespace support {
+
+namespace endian {
+/// Adapter to write values to a stream in a particular byte order.
+template <endianness endian> struct Writer {
+  raw_ostream &OS;
+  Writer(raw_ostream &OS) : OS(OS) {}
+  template <typename value_type> void write(value_type Val) {
+    Val = byte_swap<value_type, endian>(Val);
+    OS.write((const char *)&Val, sizeof(value_type));
+  }
+};
+} // end namespace endian
+
+} // end namespace support
+} // end namespace llvm
+
+#endif // _LLVM_SUPPORT_ENDIAN_STREAM_H_
diff --git a/include/llvm/Support/Errc.h b/include/llvm/Support/Errc.h
new file mode 100644
index 0000000..80bfe2a
--- /dev/null
+++ b/include/llvm/Support/Errc.h
@@ -0,0 +1,86 @@
+//===- llvm/Support/Errc.h - Defines the llvm::errc enum --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// While std::error_code works OK on all platforms we use, there are some
+// some problems with std::errc that can be avoided by using our own
+// enumeration:
+//
+// * std::errc is a namespace in some implementations. That meas that ADL
+//   doesn't work and it is sometimes necessary to write std::make_error_code
+//   or in templates:
+//   using std::make_error_code;
+//   make_error_code(...);
+//
+//   with this enum it is safe to always just use make_error_code.
+//
+// * Some implementations define fewer names than others. This header has
+//   the intersection of all the ones we support.
+//
+// * std::errc is just marked with is_error_condition_enum. This means that
+//   common patters like AnErrorCode == errc::no_such_file_or_directory take
+//   4 virtual calls instead of two comparisons.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRC_H
+#define LLVM_SUPPORT_ERRC_H
+
+#include <system_error>
+
+namespace llvm {
+enum class errc {
+  argument_list_too_long = int(std::errc::argument_list_too_long),
+  argument_out_of_domain = int(std::errc::argument_out_of_domain),
+  bad_address = int(std::errc::bad_address),
+  bad_file_descriptor = int(std::errc::bad_file_descriptor),
+  broken_pipe = int(std::errc::broken_pipe),
+  device_or_resource_busy = int(std::errc::device_or_resource_busy),
+  directory_not_empty = int(std::errc::directory_not_empty),
+  executable_format_error = int(std::errc::executable_format_error),
+  file_exists = int(std::errc::file_exists),
+  file_too_large = int(std::errc::file_too_large),
+  filename_too_long = int(std::errc::filename_too_long),
+  function_not_supported = int(std::errc::function_not_supported),
+  illegal_byte_sequence = int(std::errc::illegal_byte_sequence),
+  inappropriate_io_control_operation =
+      int(std::errc::inappropriate_io_control_operation),
+  interrupted = int(std::errc::interrupted),
+  invalid_argument = int(std::errc::invalid_argument),
+  invalid_seek = int(std::errc::invalid_seek),
+  io_error = int(std::errc::io_error),
+  is_a_directory = int(std::errc::is_a_directory),
+  no_child_process = int(std::errc::no_child_process),
+  no_lock_available = int(std::errc::no_lock_available),
+  no_space_on_device = int(std::errc::no_space_on_device),
+  no_such_device_or_address = int(std::errc::no_such_device_or_address),
+  no_such_device = int(std::errc::no_such_device),
+  no_such_file_or_directory = int(std::errc::no_such_file_or_directory),
+  no_such_process = int(std::errc::no_such_process),
+  not_a_directory = int(std::errc::not_a_directory),
+  not_enough_memory = int(std::errc::not_enough_memory),
+  operation_not_permitted = int(std::errc::operation_not_permitted),
+  permission_denied = int(std::errc::permission_denied),
+  read_only_file_system = int(std::errc::read_only_file_system),
+  resource_deadlock_would_occur = int(std::errc::resource_deadlock_would_occur),
+  resource_unavailable_try_again =
+      int(std::errc::resource_unavailable_try_again),
+  result_out_of_range = int(std::errc::result_out_of_range),
+  too_many_files_open_in_system = int(std::errc::too_many_files_open_in_system),
+  too_many_files_open = int(std::errc::too_many_files_open),
+  too_many_links = int(std::errc::too_many_links)
+};
+
+inline std::error_code make_error_code(errc E) {
+  return std::error_code(static_cast<int>(E), std::generic_category());
+}
+}
+
+namespace std {
+template <> struct is_error_code_enum<llvm::errc> : std::true_type {};
+}
+#endif
diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h
new file mode 100644
index 0000000..8e145c7
--- /dev/null
+++ b/include/llvm/Support/Errno.h
@@ -0,0 +1,34 @@
+//===- llvm/Support/Errno.h - Portable+convenient errno handling -*- 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 some portable and convenient functions to deal with errno.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRNO_H
+#define LLVM_SUPPORT_ERRNO_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available.  Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+std::string StrError();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+std::string StrError(int errnum);
+
+}  // namespace sys
+}  // namespace llvm
+
+#endif  // LLVM_SYSTEM_ERRNO_H
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
new file mode 100644
index 0000000..9afd52d
--- /dev/null
+++ b/include/llvm/Support/ErrorHandling.h
@@ -0,0 +1,106 @@
+//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- 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 an API used to indicate fatal error conditions.  Non-fatal
+// errors (most of them) should be handled through LLVMContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRORHANDLING_H
+#define LLVM_SUPPORT_ERRORHANDLING_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include <string>
+
+namespace llvm {
+  class Twine;
+
+  /// An error handler callback.
+  typedef void (*fatal_error_handler_t)(void *user_data,
+                                        const std::string& reason,
+                                        bool gen_crash_diag);
+
+  /// install_fatal_error_handler - Installs a new error handler to be used
+  /// whenever a serious (non-recoverable) error is encountered by LLVM.
+  ///
+  /// If no error handler is installed the default is to print the error message
+  /// to stderr, and call exit(1).  If an error handler is installed then it is
+  /// the handler's responsibility to log the message, it will no longer be
+  /// printed to stderr.  If the error handler returns, then exit(1) will be
+  /// called.
+  ///
+  /// It is dangerous to naively use an error handler which throws an exception.
+  /// Even though some applications desire to gracefully recover from arbitrary
+  /// faults, blindly throwing exceptions through unfamiliar code isn't a way to
+  /// achieve this.
+  ///
+  /// \param user_data - An argument which will be passed to the install error
+  /// handler.
+  void install_fatal_error_handler(fatal_error_handler_t handler,
+                                   void *user_data = nullptr);
+
+  /// Restores default error handling behaviour.
+  void remove_fatal_error_handler();
+
+  /// ScopedFatalErrorHandler - This is a simple helper class which just
+  /// calls install_fatal_error_handler in its constructor and
+  /// remove_fatal_error_handler in its destructor.
+  struct ScopedFatalErrorHandler {
+    explicit ScopedFatalErrorHandler(fatal_error_handler_t handler,
+                                     void *user_data = nullptr) {
+      install_fatal_error_handler(handler, user_data);
+    }
+
+    ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
+  };
+
+  /// Reports a serious error, calling any installed error handler. These
+  /// functions are intended to be used for error conditions which are outside
+  /// the control of the compiler (I/O errors, invalid user input, etc.)
+  ///
+  /// If no error handler is installed the default is to print the message to
+  /// standard error, followed by a newline.
+  /// After the error handler is called this function will call exit(1), it 
+  /// does not return.
+  LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason,
+                                                  bool gen_crash_diag = true);
+  LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason,
+                                                  bool gen_crash_diag = true);
+  LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason,
+                                                  bool gen_crash_diag = true);
+  LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason,
+                                                  bool gen_crash_diag = true);
+
+  /// This function calls abort(), and prints the optional message to stderr.
+  /// Use the llvm_unreachable macro (that adds location info), instead of
+  /// calling this function directly.
+  LLVM_ATTRIBUTE_NORETURN void
+  llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr,
+                            unsigned line=0);
+}
+
+/// Marks that the current location is not supposed to be reachable.
+/// In !NDEBUG builds, prints the message and location info to stderr.
+/// In NDEBUG builds, becomes an optimizer hint that the current location
+/// is not supposed to be reachable.  On compilers that don't support
+/// such hints, prints a reduced message instead.
+///
+/// Use this instead of assert(0).  It conveys intent more clearly and
+/// allows compilers to omit some unnecessary code.
+#ifndef NDEBUG
+#define llvm_unreachable(msg) \
+  ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
+#elif defined(LLVM_BUILTIN_UNREACHABLE)
+#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
+#else
+#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
+#endif
+
+#endif
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
new file mode 100644
index 0000000..0742a2d
--- /dev/null
+++ b/include/llvm/Support/ErrorOr.h
@@ -0,0 +1,277 @@
+//===- llvm/Support/ErrorOr.h - Error Smart Pointer -----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Provides ErrorOr<T> smart pointer.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERROR_OR_H
+#define LLVM_SUPPORT_ERROR_OR_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/AlignOf.h"
+#include <cassert>
+#include <system_error>
+#include <type_traits>
+
+namespace llvm {
+template<class T, class V>
+typename std::enable_if< std::is_constructible<T, V>::value
+                       , typename std::remove_reference<V>::type>::type &&
+ moveIfMoveConstructible(V &Val) {
+  return std::move(Val);
+}
+
+template<class T, class V>
+typename std::enable_if< !std::is_constructible<T, V>::value
+                       , typename std::remove_reference<V>::type>::type &
+moveIfMoveConstructible(V &Val) {
+  return Val;
+}
+
+/// \brief Stores a reference that can be changed.
+template <typename T>
+class ReferenceStorage {
+  T *Storage;
+
+public:
+  ReferenceStorage(T &Ref) : Storage(&Ref) {}
+
+  operator T &() const { return *Storage; }
+  T &get() const { return *Storage; }
+};
+
+/// \brief Represents either an error or a value T.
+///
+/// ErrorOr<T> is a pointer-like class that represents the result of an
+/// operation. The result is either an error, or a value of type T. This is
+/// designed to emulate the usage of returning a pointer where nullptr indicates
+/// failure. However instead of just knowing that the operation failed, we also
+/// have an error_code and optional user data that describes why it failed.
+///
+/// It is used like the following.
+/// \code
+///   ErrorOr<Buffer> getBuffer();
+///
+///   auto buffer = getBuffer();
+///   if (error_code ec = buffer.getError())
+///     return ec;
+///   buffer->write("adena");
+/// \endcode
+///
+///
+/// An implicit conversion to bool provides a way to check if there was an
+/// error. The unary * and -> operators provide pointer like access to the
+/// value. Accessing the value when there is an error has undefined behavior.
+///
+/// When T is a reference type the behaivor is slightly different. The reference
+/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
+/// there is special handling to make operator -> work as if T was not a
+/// reference.
+///
+/// T cannot be a rvalue reference.
+template<class T>
+class ErrorOr {
+  template <class OtherT> friend class ErrorOr;
+  static const bool isRef = std::is_reference<T>::value;
+  typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
+
+public:
+  typedef typename std::conditional<isRef, wrap, T>::type storage_type;
+
+private:
+  typedef typename std::remove_reference<T>::type &reference;
+  typedef const typename std::remove_reference<T>::type &const_reference;
+  typedef typename std::remove_reference<T>::type *pointer;
+
+public:
+  template <class E>
+  ErrorOr(E ErrorCode,
+          typename std::enable_if<std::is_error_code_enum<E>::value ||
+                                      std::is_error_condition_enum<E>::value,
+                                  void *>::type = 0)
+      : HasError(true) {
+    new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
+  }
+
+  ErrorOr(std::error_code EC) : HasError(true) {
+    new (getErrorStorage()) std::error_code(EC);
+  }
+
+  ErrorOr(T Val) : HasError(false) {
+    new (getStorage()) storage_type(moveIfMoveConstructible<storage_type>(Val));
+  }
+
+  ErrorOr(const ErrorOr &Other) {
+    copyConstruct(Other);
+  }
+
+  template <class OtherT>
+  ErrorOr(const ErrorOr<OtherT> &Other) {
+    copyConstruct(Other);
+  }
+
+  ErrorOr &operator =(const ErrorOr &Other) {
+    copyAssign(Other);
+    return *this;
+  }
+
+  template <class OtherT>
+  ErrorOr &operator =(const ErrorOr<OtherT> &Other) {
+    copyAssign(Other);
+    return *this;
+  }
+
+  ErrorOr(ErrorOr &&Other) {
+    moveConstruct(std::move(Other));
+  }
+
+  template <class OtherT>
+  ErrorOr(ErrorOr<OtherT> &&Other) {
+    moveConstruct(std::move(Other));
+  }
+
+  ErrorOr &operator =(ErrorOr &&Other) {
+    moveAssign(std::move(Other));
+    return *this;
+  }
+
+  template <class OtherT>
+  ErrorOr &operator =(ErrorOr<OtherT> &&Other) {
+    moveAssign(std::move(Other));
+    return *this;
+  }
+
+  ~ErrorOr() {
+    if (!HasError)
+      getStorage()->~storage_type();
+  }
+
+  /// \brief Return false if there is an error.
+  LLVM_EXPLICIT operator bool() const {
+    return !HasError;
+  }
+
+  reference get() { return *getStorage(); }
+  const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
+
+  std::error_code getError() const {
+    return HasError ? *getErrorStorage() : std::error_code();
+  }
+
+  pointer operator ->() {
+    return toPointer(getStorage());
+  }
+
+  reference operator *() {
+    return *getStorage();
+  }
+
+private:
+  template <class OtherT>
+  void copyConstruct(const ErrorOr<OtherT> &Other) {
+    if (!Other.HasError) {
+      // Get the other value.
+      HasError = false;
+      new (getStorage()) storage_type(*Other.getStorage());
+    } else {
+      // Get other's error.
+      HasError = true;
+      new (getErrorStorage()) std::error_code(Other.getError());
+    }
+  }
+
+  template <class T1>
+  static bool compareThisIfSameType(const T1 &a, const T1 &b) {
+    return &a == &b;
+  }
+
+  template <class T1, class T2>
+  static bool compareThisIfSameType(const T1 &a, const T2 &b) {
+    return false;
+  }
+
+  template <class OtherT>
+  void copyAssign(const ErrorOr<OtherT> &Other) {
+    if (compareThisIfSameType(*this, Other))
+      return;
+
+    this->~ErrorOr();
+    new (this) ErrorOr(Other);
+  }
+
+  template <class OtherT>
+  void moveConstruct(ErrorOr<OtherT> &&Other) {
+    if (!Other.HasError) {
+      // Get the other value.
+      HasError = false;
+      new (getStorage()) storage_type(std::move(*Other.getStorage()));
+    } else {
+      // Get other's error.
+      HasError = true;
+      new (getErrorStorage()) std::error_code(Other.getError());
+    }
+  }
+
+  template <class OtherT>
+  void moveAssign(ErrorOr<OtherT> &&Other) {
+    if (compareThisIfSameType(*this, Other))
+      return;
+
+    this->~ErrorOr();
+    new (this) ErrorOr(std::move(Other));
+  }
+
+  pointer toPointer(pointer Val) {
+    return Val;
+  }
+
+  pointer toPointer(wrap *Val) {
+    return &Val->get();
+  }
+
+  storage_type *getStorage() {
+    assert(!HasError && "Cannot get value when an error exists!");
+    return reinterpret_cast<storage_type*>(TStorage.buffer);
+  }
+
+  const storage_type *getStorage() const {
+    assert(!HasError && "Cannot get value when an error exists!");
+    return reinterpret_cast<const storage_type*>(TStorage.buffer);
+  }
+
+  std::error_code *getErrorStorage() {
+    assert(HasError && "Cannot get error when a value exists!");
+    return reinterpret_cast<std::error_code *>(ErrorStorage.buffer);
+  }
+
+  const std::error_code *getErrorStorage() const {
+    return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
+  }
+
+
+  union {
+    AlignedCharArrayUnion<storage_type> TStorage;
+    AlignedCharArrayUnion<std::error_code> ErrorStorage;
+  };
+  bool HasError : 1;
+};
+
+template <class T, class E>
+typename std::enable_if<std::is_error_code_enum<E>::value ||
+                            std::is_error_condition_enum<E>::value,
+                        bool>::type
+operator==(ErrorOr<T> &Err, E Code) {
+  return std::error_code(Err) == Code;
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
new file mode 100644
index 0000000..0a9a979
--- /dev/null
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -0,0 +1,89 @@
+//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility for creating a in-memory buffer that will be written to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/FileSystem.h"
+
+namespace llvm {
+/// FileOutputBuffer - This interface provides simple way to create an in-memory
+/// buffer which will be written to a file. During the lifetime of these
+/// objects, the content or existence of the specified file is undefined. That
+/// is, creating an OutputBuffer for a file may immediately remove the file.
+/// If the FileOutputBuffer is committed, the target file's content will become
+/// the buffer content at the time of the commit.  If the FileOutputBuffer is
+/// not committed, the file will be deleted in the FileOutputBuffer destructor.
+class FileOutputBuffer {
+public:
+
+  enum  {
+    F_executable = 1  /// set the 'x' bit on the resulting file
+  };
+
+  /// Factory method to create an OutputBuffer object which manages a read/write
+  /// buffer of the specified size. When committed, the buffer will be written
+  /// to the file at the specified path.
+  static std::error_code create(StringRef FilePath, size_t Size,
+                                std::unique_ptr<FileOutputBuffer> &Result,
+                                unsigned Flags = 0);
+
+  /// Returns a pointer to the start of the buffer.
+  uint8_t *getBufferStart() {
+    return (uint8_t*)Region->data();
+  }
+
+  /// Returns a pointer to the end of the buffer.
+  uint8_t *getBufferEnd() {
+    return (uint8_t*)Region->data() + Region->size();
+  }
+
+  /// Returns size of the buffer.
+  size_t getBufferSize() const {
+    return Region->size();
+  }
+
+  /// Returns path where file will show up if buffer is committed.
+  StringRef getPath() const {
+    return FinalPath;
+  }
+
+  /// Flushes the content of the buffer to its file and deallocates the
+  /// buffer.  If commit() is not called before this object's destructor
+  /// is called, the file is deleted in the destructor. The optional parameter
+  /// is used if it turns out you want the file size to be smaller than
+  /// initially requested.
+  std::error_code commit(int64_t NewSmallerSize = -1);
+
+  /// If this object was previously committed, the destructor just deletes
+  /// this object.  If this object was not committed, the destructor
+  /// deallocates the buffer and the target file is never written.
+  ~FileOutputBuffer();
+
+private:
+  FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
+  FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION;
+
+  FileOutputBuffer(llvm::sys::fs::mapped_file_region *R,
+                   StringRef Path, StringRef TempPath);
+
+  std::unique_ptr<llvm::sys::fs::mapped_file_region> Region;
+  SmallString<128>    FinalPath;
+  SmallString<128>    TempPath;
+};
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
new file mode 100644
index 0000000..556701c
--- /dev/null
+++ b/include/llvm/Support/FileSystem.h
@@ -0,0 +1,918 @@
+//===- llvm/Support/FileSystem.h - File System OS Concept -------*- 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 llvm::sys::fs namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+// All functions return an error_code and their actual work via the last out
+// argument. The out argument is defined if and only if errc::success is
+// returned. A function may return any error code in the generic or system
+// category. However, they shall be equivalent to any error conditions listed
+// in each functions respective documentation if the condition applies. [ note:
+// this does not guarantee that error_code will be in the set of explicitly
+// listed codes, but it does guarantee that if any of the explicitly listed
+// errors occur, the correct error_code will be used ]. All functions may
+// return errc::not_enough_memory if there is not enough memory to complete the
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILESYSTEM_H
+#define LLVM_SUPPORT_FILESYSTEM_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TimeValue.h"
+#include <ctime>
+#include <iterator>
+#include <stack>
+#include <string>
+#include <system_error>
+#include <tuple>
+#include <vector>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+namespace llvm {
+namespace sys {
+namespace fs {
+
+/// An enumeration for the file system's view of the type.
+enum class file_type {
+  status_error,
+  file_not_found,
+  regular_file,
+  directory_file,
+  symlink_file,
+  block_file,
+  character_file,
+  fifo_file,
+  socket_file,
+  type_unknown
+};
+
+/// space_info - Self explanatory.
+struct space_info {
+  uint64_t capacity;
+  uint64_t free;
+  uint64_t available;
+};
+
+enum perms {
+  no_perms = 0,
+  owner_read = 0400,
+  owner_write = 0200,
+  owner_exe = 0100,
+  owner_all = owner_read | owner_write | owner_exe,
+  group_read = 040,
+  group_write = 020,
+  group_exe = 010,
+  group_all = group_read | group_write | group_exe,
+  others_read = 04,
+  others_write = 02,
+  others_exe = 01,
+  others_all = others_read | others_write | others_exe,
+  all_read = owner_read | group_read | others_read,
+  all_write = owner_write | group_write | others_write,
+  all_exe = owner_exe | group_exe | others_exe,
+  all_all = owner_all | group_all | others_all,
+  set_uid_on_exe = 04000,
+  set_gid_on_exe = 02000,
+  sticky_bit = 01000,
+  perms_not_known = 0xFFFF
+};
+
+// Helper functions so that you can use & and | to manipulate perms bits:
+inline perms operator|(perms l , perms r) {
+  return static_cast<perms>(
+             static_cast<unsigned short>(l) | static_cast<unsigned short>(r)); 
+}
+inline perms operator&(perms l , perms r) {
+  return static_cast<perms>(
+             static_cast<unsigned short>(l) & static_cast<unsigned short>(r)); 
+}
+inline perms &operator|=(perms &l, perms r) {
+  l = l | r; 
+  return l; 
+}
+inline perms &operator&=(perms &l, perms r) {
+  l = l & r; 
+  return l; 
+}
+inline perms operator~(perms x) {
+  return static_cast<perms>(~static_cast<unsigned short>(x));
+}
+
+class UniqueID {
+  uint64_t Device;
+  uint64_t File;
+
+public:
+  UniqueID() {}
+  UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {}
+  bool operator==(const UniqueID &Other) const {
+    return Device == Other.Device && File == Other.File;
+  }
+  bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
+  bool operator<(const UniqueID &Other) const {
+    return std::tie(Device, File) < std::tie(Other.Device, Other.File);
+  }
+  uint64_t getDevice() const { return Device; }
+  uint64_t getFile() const { return File; }
+};
+
+/// file_status - Represents the result of a call to stat and friends. It has
+///               a platform-specific member to store the result.
+class file_status
+{
+  #if defined(LLVM_ON_UNIX)
+  dev_t fs_st_dev;
+  ino_t fs_st_ino;
+  time_t fs_st_mtime;
+  uid_t fs_st_uid;
+  gid_t fs_st_gid;
+  off_t fs_st_size;
+  #elif defined (LLVM_ON_WIN32)
+  uint32_t LastWriteTimeHigh;
+  uint32_t LastWriteTimeLow;
+  uint32_t VolumeSerialNumber;
+  uint32_t FileSizeHigh;
+  uint32_t FileSizeLow;
+  uint32_t FileIndexHigh;
+  uint32_t FileIndexLow;
+  #endif
+  friend bool equivalent(file_status A, file_status B);
+  file_type Type;
+  perms Perms;
+public:
+  #if defined(LLVM_ON_UNIX)
+    file_status() : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+        fs_st_uid(0), fs_st_gid(0), fs_st_size(0),
+        Type(file_type::status_error), Perms(perms_not_known) {}
+
+    file_status(file_type Type) : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+        fs_st_uid(0), fs_st_gid(0), fs_st_size(0), Type(Type),
+        Perms(perms_not_known) {}
+
+    file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime,
+                uid_t UID, gid_t GID, off_t Size)
+        : fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID),
+          fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {}
+  #elif defined(LLVM_ON_WIN32)
+    file_status() : LastWriteTimeHigh(0), LastWriteTimeLow(0),
+        VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
+        FileIndexHigh(0), FileIndexLow(0), Type(file_type::status_error),
+        Perms(perms_not_known) {}
+
+    file_status(file_type Type) : LastWriteTimeHigh(0), LastWriteTimeLow(0),
+        VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
+        FileIndexHigh(0), FileIndexLow(0), Type(Type),
+        Perms(perms_not_known) {}
+
+    file_status(file_type Type, uint32_t LastWriteTimeHigh,
+                uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
+                uint32_t FileSizeHigh, uint32_t FileSizeLow,
+                uint32_t FileIndexHigh, uint32_t FileIndexLow)
+        : LastWriteTimeHigh(LastWriteTimeHigh),
+          LastWriteTimeLow(LastWriteTimeLow),
+          VolumeSerialNumber(VolumeSerialNumber), FileSizeHigh(FileSizeHigh),
+          FileSizeLow(FileSizeLow), FileIndexHigh(FileIndexHigh),
+          FileIndexLow(FileIndexLow), Type(Type), Perms(perms_not_known) {}
+  #endif
+
+  // getters
+  file_type type() const { return Type; }
+  perms permissions() const { return Perms; }
+  TimeValue getLastModificationTime() const;
+  UniqueID getUniqueID() const;
+
+  #if defined(LLVM_ON_UNIX)
+  uint32_t getUser() const { return fs_st_uid; }
+  uint32_t getGroup() const { return fs_st_gid; }
+  uint64_t getSize() const { return fs_st_size; }
+  #elif defined (LLVM_ON_WIN32)
+  uint32_t getUser() const {
+    return 9999; // Not applicable to Windows, so...
+  }
+  uint32_t getGroup() const {
+    return 9999; // Not applicable to Windows, so...
+  }
+  uint64_t getSize() const {
+    return (uint64_t(FileSizeHigh) << 32) + FileSizeLow;
+  }
+  #endif
+
+  // setters
+  void type(file_type v) { Type = v; }
+  void permissions(perms p) { Perms = p; }
+};
+
+/// file_magic - An "enum class" enumeration of file types based on magic (the first
+///         N bytes of the file).
+struct file_magic {
+  enum Impl {
+    unknown = 0,              ///< Unrecognized file
+    bitcode,                  ///< Bitcode file
+    archive,                  ///< ar style archive file
+    elf_relocatable,          ///< ELF Relocatable object file
+    elf_executable,           ///< ELF Executable image
+    elf_shared_object,        ///< ELF dynamically linked shared lib
+    elf_core,                 ///< ELF core image
+    macho_object,             ///< Mach-O Object file
+    macho_executable,         ///< Mach-O Executable
+    macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
+    macho_core,               ///< Mach-O Core File
+    macho_preload_executable, ///< Mach-O Preloaded Executable
+    macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
+    macho_dynamic_linker,     ///< The Mach-O dynamic linker
+    macho_bundle,             ///< Mach-O Bundle file
+    macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
+    macho_dsym_companion,     ///< Mach-O dSYM companion file
+    macho_universal_binary,   ///< Mach-O universal binary
+    coff_object,              ///< COFF object file
+    coff_import_library,      ///< COFF import library
+    pecoff_executable,        ///< PECOFF executable file
+    windows_resource          ///< Windows compiled resource file (.rc)
+  };
+
+  bool is_object() const {
+    return V == unknown ? false : true;
+  }
+
+  file_magic() : V(unknown) {}
+  file_magic(Impl V) : V(V) {}
+  operator Impl() const { return V; }
+
+private:
+  Impl V;
+};
+
+/// @}
+/// @name Physical Operators
+/// @{
+
+/// @brief Make \a path an absolute path.
+///
+/// Makes \a path absolute using the current directory if it is not already. An
+/// empty \a path will result in the current directory.
+///
+/// /absolute/path   => /absolute/path
+/// relative/../path => <current-directory>/relative/../path
+///
+/// @param path A path that is modified to be an absolute path.
+/// @returns errc::success if \a path has been made absolute, otherwise a
+///          platform-specific error_code.
+std::error_code make_absolute(SmallVectorImpl<char> &path);
+
+/// @brief Normalize path separators in \a Path
+///
+/// If the path contains any '\' separators, they are transformed into '/'.
+/// This is particularly useful when cross-compiling Windows on Linux, but is
+/// safe to invoke on Windows, which accepts both characters as a path
+/// separator.
+std::error_code normalize_separators(SmallVectorImpl<char> &Path);
+
+/// @brief Create all the non-existent directories in path.
+///
+/// @param path Directories to create.
+/// @returns errc::success if is_directory(path), otherwise a platform
+///          specific error_code. If IgnoreExisting is false, also returns
+///          error if the directory already existed.
+std::error_code create_directories(const Twine &path,
+                                   bool IgnoreExisting = true);
+
+/// @brief Create the directory in path.
+///
+/// @param path Directory to create.
+/// @returns errc::success if is_directory(path), otherwise a platform
+///          specific error_code. If IgnoreExisting is false, also returns
+///          error if the directory already existed.
+std::error_code create_directory(const Twine &path, bool IgnoreExisting = true);
+
+/// @brief Create a link from \a from to \a to.
+///
+/// The link may be a soft or a hard link, depending on the platform. The caller
+/// may not assume which one. Currently on windows it creates a hard link since
+/// soft links require extra privileges. On unix, it creates a soft link since
+/// hard links don't work on SMB file systems.
+///
+/// @param to The path to hard link to.
+/// @param from The path to hard link from. This is created.
+/// @returns errc::success if the link was created, otherwise a platform
+/// specific error_code.
+std::error_code create_link(const Twine &to, const Twine &from);
+
+/// @brief Get the current path.
+///
+/// @param result Holds the current path on return.
+/// @returns errc::success if the current path has been stored in result,
+///          otherwise a platform-specific error_code.
+std::error_code current_path(SmallVectorImpl<char> &result);
+
+/// @brief Remove path. Equivalent to POSIX remove().
+///
+/// @param path Input path.
+/// @returns errc::success if path has been removed or didn't exist, otherwise a
+///          platform-specific error code. If IgnoreNonExisting is false, also
+///          returns error if the file didn't exist.
+std::error_code remove(const Twine &path, bool IgnoreNonExisting = true);
+
+/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
+///
+/// @param from The path to rename from.
+/// @param to The path to rename to. This is created.
+std::error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Copy the contents of \a From to \a To.
+///
+/// @param From The path to copy from.
+/// @param To The path to copy to. This is created.
+std::error_code copy_file(const Twine &From, const Twine &To);
+
+/// @brief Resize path to size. File is resized as if by POSIX truncate().
+///
+/// @param path Input path.
+/// @param size Size to resize to.
+/// @returns errc::success if \a path has been resized to \a size, otherwise a
+///          platform-specific error_code.
+std::error_code resize_file(const Twine &path, uint64_t size);
+
+/// @}
+/// @name Physical Observers
+/// @{
+
+/// @brief Does file exist?
+///
+/// @param status A file_status previously returned from stat.
+/// @returns True if the file represented by status exists, false if it does
+///          not.
+bool exists(file_status status);
+
+/// @brief Does file exist?
+///
+/// @param path Input path.
+/// @param result Set to true if the file represented by status exists, false if
+///               it does not. Undefined otherwise.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code exists(const Twine &path, bool &result);
+
+/// @brief Simpler version of exists for clients that don't need to
+///        differentiate between an error and false.
+inline bool exists(const Twine &path) {
+  bool result;
+  return !exists(path, result) && result;
+}
+
+/// @brief Can we execute this file?
+///
+/// @param Path Input path.
+/// @returns True if we can execute it, false otherwise.
+bool can_execute(const Twine &Path);
+
+/// @brief Can we write this file?
+///
+/// @param Path Input path.
+/// @returns True if we can write to it, false otherwise.
+bool can_write(const Twine &Path);
+
+/// @brief Do file_status's represent the same thing?
+///
+/// @param A Input file_status.
+/// @param B Input file_status.
+///
+/// assert(status_known(A) || status_known(B));
+///
+/// @returns True if A and B both represent the same file system entity, false
+///          otherwise.
+bool equivalent(file_status A, file_status B);
+
+/// @brief Do paths represent the same thing?
+///
+/// assert(status_known(A) || status_known(B));
+///
+/// @param A Input path A.
+/// @param B Input path B.
+/// @param result Set to true if stat(A) and stat(B) have the same device and
+///               inode (or equivalent).
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code equivalent(const Twine &A, const Twine &B, bool &result);
+
+/// @brief Simpler version of equivalent for clients that don't need to
+///        differentiate between an error and false.
+inline bool equivalent(const Twine &A, const Twine &B) {
+  bool result;
+  return !equivalent(A, B, result) && result;
+}
+
+/// @brief Does status represent a directory?
+///
+/// @param status A file_status previously returned from status.
+/// @returns status.type() == file_type::directory_file.
+bool is_directory(file_status status);
+
+/// @brief Is path a directory?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a directory, false if it is not.
+///               Undefined otherwise.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code is_directory(const Twine &path, bool &result);
+
+/// @brief Simpler version of is_directory for clients that don't need to
+///        differentiate between an error and false.
+inline bool is_directory(const Twine &Path) {
+  bool Result;
+  return !is_directory(Path, Result) && Result;
+}
+
+/// @brief Does status represent a regular file?
+///
+/// @param status A file_status previously returned from status.
+/// @returns status_known(status) && status.type() == file_type::regular_file.
+bool is_regular_file(file_status status);
+
+/// @brief Is path a regular file?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path is a regular file, false if it is not.
+///               Undefined otherwise.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code is_regular_file(const Twine &path, bool &result);
+
+/// @brief Simpler version of is_regular_file for clients that don't need to
+///        differentiate between an error and false.
+inline bool is_regular_file(const Twine &Path) {
+  bool Result;
+  if (is_regular_file(Path, Result))
+    return false;
+  return Result;
+}
+
+/// @brief Does this status represent something that exists but is not a
+///        directory, regular file, or symlink?
+///
+/// @param status A file_status previously returned from status.
+/// @returns exists(s) && !is_regular_file(s) && !is_directory(s)
+bool is_other(file_status status);
+
+/// @brief Is path something that exists but is not a directory,
+///        regular file, or symlink?
+///
+/// @param path Input path.
+/// @param result Set to true if \a path exists, but is not a directory, regular
+///               file, or a symlink, false if it does not. Undefined otherwise.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code is_other(const Twine &path, bool &result);
+
+/// @brief Get file status as if by POSIX stat().
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code status(const Twine &path, file_status &result);
+
+/// @brief A version for when a file descriptor is already available.
+std::error_code status(int FD, file_status &Result);
+
+/// @brief Get file size.
+///
+/// @param Path Input path.
+/// @param Result Set to the size of the file in \a Path.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+inline std::error_code file_size(const Twine &Path, uint64_t &Result) {
+  file_status Status;
+  std::error_code EC = status(Path, Status);
+  if (EC)
+    return EC;
+  Result = Status.getSize();
+  return std::error_code();
+}
+
+/// @brief Set the file modification and access time.
+///
+/// @returns errc::success if the file times were successfully set, otherwise a
+///          platform-specific error_code or errc::function_not_supported on
+///          platforms where the functionality isn't available.
+std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
+
+/// @brief Is status available?
+///
+/// @param s Input file status.
+/// @returns True if status() != status_error.
+bool status_known(file_status s);
+
+/// @brief Is status available?
+///
+/// @param path Input path.
+/// @param result Set to true if status() != status_error.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code status_known(const Twine &path, bool &result);
+
+/// @brief Create a uniquely named file.
+///
+/// Generates a unique path suitable for a temporary file and then opens it as a
+/// file. The name is based on \a model with '%' replaced by a random char in
+/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
+/// directory will be prepended.
+///
+/// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s
+///
+/// This is an atomic operation. Either the file is created and opened, or the
+/// file system is left untouched.
+///
+/// The intendend use is for files that are to be kept, possibly after
+/// renaming them. For example, when running 'clang -c foo.o', the file can
+/// be first created as foo-abc123.o and then renamed.
+///
+/// @param Model Name to base unique path off of.
+/// @param ResultFD Set to the opened file's file descriptor.
+/// @param ResultPath Set to the opened file's absolute path.
+/// @returns errc::success if Result{FD,Path} have been successfully set,
+///          otherwise a platform-specific error_code.
+std::error_code createUniqueFile(const Twine &Model, int &ResultFD,
+                                 SmallVectorImpl<char> &ResultPath,
+                                 unsigned Mode = all_read | all_write);
+
+/// @brief Simpler version for clients that don't want an open file.
+std::error_code createUniqueFile(const Twine &Model,
+                                 SmallVectorImpl<char> &ResultPath);
+
+/// @brief Create a file in the system temporary directory.
+///
+/// The filename is of the form prefix-random_chars.suffix. Since the directory
+/// is not know to the caller, Prefix and Suffix cannot have path separators.
+/// The files are created with mode 0600.
+///
+/// This should be used for things like a temporary .s that is removed after
+/// running the assembler.
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+                                    int &ResultFD,
+                                    SmallVectorImpl<char> &ResultPath);
+
+/// @brief Simpler version for clients that don't want an open file.
+std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
+                                    SmallVectorImpl<char> &ResultPath);
+
+std::error_code createUniqueDirectory(const Twine &Prefix,
+                                      SmallVectorImpl<char> &ResultPath);
+
+enum OpenFlags : unsigned {
+  F_None = 0,
+
+  /// F_Excl - When opening a file, this flag makes raw_fd_ostream
+  /// report an error if the file already exists.
+  F_Excl = 1,
+
+  /// F_Append - When opening a file, if it already exists append to the
+  /// existing file instead of returning an error.  This may not be specified
+  /// with F_Excl.
+  F_Append = 2,
+
+  /// The file should be opened in text mode on platforms that make this
+  /// distinction.
+  F_Text = 4,
+
+  /// Open the file for read and write.
+  F_RW = 8
+};
+
+inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
+  return OpenFlags(unsigned(A) | unsigned(B));
+}
+
+inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) {
+  A = A | B;
+  return A;
+}
+
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+                                 OpenFlags Flags, unsigned Mode = 0666);
+
+std::error_code openFileForRead(const Twine &Name, int &ResultFD);
+
+/// @brief Identify the type of a binary file based on how magical it is.
+file_magic identify_magic(StringRef magic);
+
+/// @brief Get and identify \a path's type based on its content.
+///
+/// @param path Input path.
+/// @param result Set to the type of file, or file_magic::unknown.
+/// @returns errc::success if result has been successfully set, otherwise a
+///          platform-specific error_code.
+std::error_code identify_magic(const Twine &path, file_magic &result);
+
+std::error_code getUniqueID(const Twine Path, UniqueID &Result);
+
+/// This class represents a memory mapped file. It is based on
+/// boost::iostreams::mapped_file.
+class mapped_file_region {
+  mapped_file_region() LLVM_DELETED_FUNCTION;
+  mapped_file_region(mapped_file_region&) LLVM_DELETED_FUNCTION;
+  mapped_file_region &operator =(mapped_file_region&) LLVM_DELETED_FUNCTION;
+
+public:
+  enum mapmode {
+    readonly, ///< May only access map via const_data as read only.
+    readwrite, ///< May access map via data and modify it. Written to path.
+    priv ///< May modify via data, but changes are lost on destruction.
+  };
+
+private:
+  /// Platform-specific mapping state.
+  mapmode Mode;
+  uint64_t Size;
+  void *Mapping;
+#ifdef LLVM_ON_WIN32
+  int FileDescriptor;
+  void *FileHandle;
+  void *FileMappingHandle;
+#endif
+
+  std::error_code init(int FD, bool CloseFD, uint64_t Offset);
+
+public:
+  typedef char char_type;
+
+  mapped_file_region(mapped_file_region&&);
+  mapped_file_region &operator =(mapped_file_region&&);
+
+  /// Construct a mapped_file_region at \a path starting at \a offset of length
+  /// \a length and with access \a mode.
+  ///
+  /// \param path Path to the file to map. If it does not exist it will be
+  ///             created.
+  /// \param mode How to map the memory.
+  /// \param length Number of bytes to map in starting at \a offset. If the file
+  ///               is shorter than this, it will be extended. If \a length is
+  ///               0, the entire file will be mapped.
+  /// \param offset Byte offset from the beginning of the file where the map
+  ///               should begin. Must be a multiple of
+  ///               mapped_file_region::alignment().
+  /// \param ec This is set to errc::success if the map was constructed
+  ///           successfully. Otherwise it is set to a platform dependent error.
+  mapped_file_region(const Twine &path, mapmode mode, uint64_t length,
+                     uint64_t offset, std::error_code &ec);
+
+  /// \param fd An open file descriptor to map. mapped_file_region takes
+  ///   ownership if closefd is true. It must have been opended in the correct
+  ///   mode.
+  mapped_file_region(int fd, bool closefd, mapmode mode, uint64_t length,
+                     uint64_t offset, std::error_code &ec);
+
+  ~mapped_file_region();
+
+  mapmode flags() const;
+  uint64_t size() const;
+  char *data() const;
+
+  /// Get a const view of the data. Modifying this memory has undefined
+  /// behavior.
+  const char *const_data() const;
+
+  /// \returns The minimum alignment offset must be.
+  static int alignment();
+};
+
+/// Return the path to the main executable, given the value of argv[0] from
+/// program startup and the address of main itself. In extremis, this function
+/// may fail and return an empty path.
+std::string getMainExecutable(const char *argv0, void *MainExecAddr);
+
+/// @}
+/// @name Iterators
+/// @{
+
+/// directory_entry - A single entry in a directory. Caches the status either
+/// from the result of the iteration syscall, or the first time status is
+/// called.
+class directory_entry {
+  std::string Path;
+  mutable file_status Status;
+
+public:
+  explicit directory_entry(const Twine &path, file_status st = file_status())
+    : Path(path.str())
+    , Status(st) {}
+
+  directory_entry() {}
+
+  void assign(const Twine &path, file_status st = file_status()) {
+    Path = path.str();
+    Status = st;
+  }
+
+  void replace_filename(const Twine &filename, file_status st = file_status());
+
+  const std::string &path() const { return Path; }
+  std::error_code status(file_status &result) const;
+
+  bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
+  bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
+  bool operator< (const directory_entry& rhs) const;
+  bool operator<=(const directory_entry& rhs) const;
+  bool operator> (const directory_entry& rhs) const;
+  bool operator>=(const directory_entry& rhs) const;
+};
+
+namespace detail {
+  struct DirIterState;
+
+  std::error_code directory_iterator_construct(DirIterState &, StringRef);
+  std::error_code directory_iterator_increment(DirIterState &);
+  std::error_code directory_iterator_destruct(DirIterState &);
+
+  /// DirIterState - Keeps state for the directory_iterator. It is reference
+  /// counted in order to preserve InputIterator semantics on copy.
+  struct DirIterState : public RefCountedBase<DirIterState> {
+    DirIterState()
+      : IterationHandle(0) {}
+
+    ~DirIterState() {
+      directory_iterator_destruct(*this);
+    }
+
+    intptr_t IterationHandle;
+    directory_entry CurrentEntry;
+  };
+}
+
+/// directory_iterator - Iterates through the entries in path. There is no
+/// operator++ because we need an error_code. If it's really needed we can make
+/// it call report_fatal_error on error.
+class directory_iterator {
+  IntrusiveRefCntPtr<detail::DirIterState> State;
+
+public:
+  explicit directory_iterator(const Twine &path, std::error_code &ec) {
+    State = new detail::DirIterState;
+    SmallString<128> path_storage;
+    ec = detail::directory_iterator_construct(*State,
+            path.toStringRef(path_storage));
+  }
+
+  explicit directory_iterator(const directory_entry &de, std::error_code &ec) {
+    State = new detail::DirIterState;
+    ec = detail::directory_iterator_construct(*State, de.path());
+  }
+
+  /// Construct end iterator.
+  directory_iterator() : State(nullptr) {}
+
+  // No operator++ because we need error_code.
+  directory_iterator &increment(std::error_code &ec) {
+    ec = directory_iterator_increment(*State);
+    return *this;
+  }
+
+  const directory_entry &operator*() const { return State->CurrentEntry; }
+  const directory_entry *operator->() const { return &State->CurrentEntry; }
+
+  bool operator==(const directory_iterator &RHS) const {
+    if (State == RHS.State)
+      return true;
+    if (!RHS.State)
+      return State->CurrentEntry == directory_entry();
+    if (!State)
+      return RHS.State->CurrentEntry == directory_entry();
+    return State->CurrentEntry == RHS.State->CurrentEntry;
+  }
+
+  bool operator!=(const directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+  // Other members as required by
+  // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+namespace detail {
+  /// RecDirIterState - Keeps state for the recursive_directory_iterator. It is
+  /// reference counted in order to preserve InputIterator semantics on copy.
+  struct RecDirIterState : public RefCountedBase<RecDirIterState> {
+    RecDirIterState()
+      : Level(0)
+      , HasNoPushRequest(false) {}
+
+    std::stack<directory_iterator, std::vector<directory_iterator> > Stack;
+    uint16_t Level;
+    bool HasNoPushRequest;
+  };
+}
+
+/// recursive_directory_iterator - Same as directory_iterator except for it
+/// recurses down into child directories.
+class recursive_directory_iterator {
+  IntrusiveRefCntPtr<detail::RecDirIterState> State;
+
+public:
+  recursive_directory_iterator() {}
+  explicit recursive_directory_iterator(const Twine &path, std::error_code &ec)
+      : State(new detail::RecDirIterState) {
+    State->Stack.push(directory_iterator(path, ec));
+    if (State->Stack.top() == directory_iterator())
+      State.reset();
+  }
+  // No operator++ because we need error_code.
+  recursive_directory_iterator &increment(std::error_code &ec) {
+    const directory_iterator end_itr;
+
+    if (State->HasNoPushRequest)
+      State->HasNoPushRequest = false;
+    else {
+      file_status st;
+      if ((ec = State->Stack.top()->status(st))) return *this;
+      if (is_directory(st)) {
+        State->Stack.push(directory_iterator(*State->Stack.top(), ec));
+        if (ec) return *this;
+        if (State->Stack.top() != end_itr) {
+          ++State->Level;
+          return *this;
+        }
+        State->Stack.pop();
+      }
+    }
+
+    while (!State->Stack.empty()
+           && State->Stack.top().increment(ec) == end_itr) {
+      State->Stack.pop();
+      --State->Level;
+    }
+
+    // Check if we are done. If so, create an end iterator.
+    if (State->Stack.empty())
+      State.reset();
+
+    return *this;
+  }
+
+  const directory_entry &operator*() const { return *State->Stack.top(); }
+  const directory_entry *operator->() const { return &*State->Stack.top(); }
+
+  // observers
+  /// Gets the current level. Starting path is at level 0.
+  int level() const { return State->Level; }
+
+  /// Returns true if no_push has been called for this directory_entry.
+  bool no_push_request() const { return State->HasNoPushRequest; }
+
+  // modifiers
+  /// Goes up one level if Level > 0.
+  void pop() {
+    assert(State && "Cannot pop an end iterator!");
+    assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
+
+    const directory_iterator end_itr;
+    std::error_code ec;
+    do {
+      if (ec)
+        report_fatal_error("Error incrementing directory iterator.");
+      State->Stack.pop();
+      --State->Level;
+    } while (!State->Stack.empty()
+             && State->Stack.top().increment(ec) == end_itr);
+
+    // Check if we are done. If so, create an end iterator.
+    if (State->Stack.empty())
+      State.reset();
+  }
+
+  /// Does not go down into the current directory_entry.
+  void no_push() { State->HasNoPushRequest = true; }
+
+  bool operator==(const recursive_directory_iterator &RHS) const {
+    return State == RHS.State;
+  }
+
+  bool operator!=(const recursive_directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+  // Other members as required by
+  // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// @}
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
new file mode 100644
index 0000000..3f2f176
--- /dev/null
+++ b/include/llvm/Support/FileUtilities.h
@@ -0,0 +1,78 @@
+//===- llvm/Support/FileUtilities.h - File System Utilities -----*- 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 family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEUTILITIES_H
+#define LLVM_SUPPORT_FILEUTILITIES_H
+
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+
+  /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
+  /// the files match, 1 if they are different, and 2 if there is a file error.
+  /// This function allows you to specify an absolute and relative FP error that
+  /// is allowed to exist.  If you specify a string to fill in for the error
+  /// option, it will set the string to an error message if an error occurs, or
+  /// if the files are different.
+  ///
+  int DiffFilesWithTolerance(StringRef FileA,
+                             StringRef FileB,
+                             double AbsTol, double RelTol,
+                             std::string *Error = nullptr);
+
+
+  /// FileRemover - This class is a simple object meant to be stack allocated.
+  /// If an exception is thrown from a region, the object removes the filename
+  /// specified (if deleteIt is true).
+  ///
+  class FileRemover {
+    SmallString<128> Filename;
+    bool DeleteIt;
+  public:
+    FileRemover() : DeleteIt(false) {}
+
+    explicit FileRemover(const Twine& filename, bool deleteIt = true)
+      : DeleteIt(deleteIt) {
+      filename.toVector(Filename);
+    }
+
+    ~FileRemover() {
+      if (DeleteIt) {
+        // Ignore problems deleting the file.
+        sys::fs::remove(Filename.str());
+      }
+    }
+
+    /// setFile - Give ownership of the file to the FileRemover so it will
+    /// be removed when the object is destroyed.  If the FileRemover already
+    /// had ownership of a file, remove it first.
+    void setFile(const Twine& filename, bool deleteIt = true) {
+      if (DeleteIt) {
+        // Ignore problems deleting the file.
+        sys::fs::remove(Filename.str());
+      }
+
+      Filename.clear();
+      filename.toVector(Filename);
+      DeleteIt = deleteIt;
+    }
+
+    /// releaseFile - Take ownership of the file away from the FileRemover so it
+    /// will not be removed when the object is destroyed.
+    void releaseFile() { DeleteIt = false; }
+  };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
new file mode 100644
index 0000000..b713cc7
--- /dev/null
+++ b/include/llvm/Support/Format.h
@@ -0,0 +1,230 @@
+//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
+//
+//                     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 format() function, which can be used with other
+// LLVM subsystems to provide printf-style formatting.  This gives all the power
+// and risk of printf.  This can be used like this (with raw_ostreams as an
+// example):
+//
+//    OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
+//
+// Or if you prefer:
+//
+//  OS << format("mynumber: %4.5f\n", 1234.412);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMAT_H
+#define LLVM_SUPPORT_FORMAT_H
+
+#include <cassert>
+#include <cstdio>
+#ifdef _MSC_VER
+// FIXME: This define is wrong:
+//  - _snprintf does not guarantee that trailing null is always added - if
+//    there is no space for null, it does not report any error.
+//  - According to C++ standard, snprintf should be visible in the 'std' 
+//    namespace - this define makes this impossible.
+#define snprintf _snprintf
+#endif
+
+namespace llvm {
+
+/// This is a helper class used for handling formatted output.  It is the
+/// abstract base class of a templated derived class.
+class format_object_base {
+protected:
+  const char *Fmt;
+  virtual void home(); // Out of line virtual method.
+
+  /// Call snprintf() for this object, on the given buffer and size.
+  virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
+
+public:
+  format_object_base(const char *fmt) : Fmt(fmt) {}
+  virtual ~format_object_base() {}
+
+  /// Format the object into the specified buffer.  On success, this returns
+  /// the length of the formatted string.  If the buffer is too small, this
+  /// returns a length to retry with, which will be larger than BufferSize.
+  unsigned print(char *Buffer, unsigned BufferSize) const {
+    assert(BufferSize && "Invalid buffer size!");
+
+    // Print the string, leaving room for the terminating null.
+    int N = snprint(Buffer, BufferSize);
+
+    // VC++ and old GlibC return negative on overflow, just double the size.
+    if (N < 0)
+      return BufferSize * 2;
+
+    // Other implementations yield number of bytes needed, not including the
+    // final '\0'.
+    if (unsigned(N) >= BufferSize)
+      return N + 1;
+
+    // Otherwise N is the length of output (not including the final '\0').
+    return N;
+  }
+};
+
+/// These are templated helper classes used by the format function that
+/// capture the object to be formated and the format string. When actually
+/// printed, this synthesizes the string into a temporary buffer provided and
+/// returns whether or not it is big enough.
+
+template <typename T>
+class format_object1 : public format_object_base {
+  T Val;
+public:
+  format_object1(const char *fmt, const T &val)
+    : format_object_base(fmt), Val(val) {
+  }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val);
+  }
+};
+
+template <typename T1, typename T2>
+class format_object2 : public format_object_base {
+  T1 Val1;
+  T2 Val2;
+public:
+  format_object2(const char *fmt, const T1 &val1, const T2 &val2)
+  : format_object_base(fmt), Val1(val1), Val2(val2) {
+  }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
+  }
+};
+
+template <typename T1, typename T2, typename T3>
+class format_object3 : public format_object_base {
+  T1 Val1;
+  T2 Val2;
+  T3 Val3;
+public:
+  format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3)
+    : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
+  }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
+  }
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class format_object4 : public format_object_base {
+  T1 Val1;
+  T2 Val2;
+  T3 Val3;
+  T4 Val4;
+public:
+  format_object4(const char *fmt, const T1 &val1, const T2 &val2,
+                 const T3 &val3, const T4 &val4)
+    : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
+  }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
+  }
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class format_object5 : public format_object_base {
+  T1 Val1;
+  T2 Val2;
+  T3 Val3;
+  T4 Val4;
+  T5 Val5;
+public:
+  format_object5(const char *fmt, const T1 &val1, const T2 &val2,
+                 const T3 &val3, const T4 &val4, const T5 &val5)
+    : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4),
+      Val5(val5) {
+  }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
+  }
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6>
+class format_object6 : public format_object_base {
+  T1 Val1;
+  T2 Val2;
+  T3 Val3;
+  T4 Val4;
+  T5 Val5;
+  T6 Val6;
+public:
+  format_object6(const char *Fmt, const T1 &Val1, const T2 &Val2,
+                 const T3 &Val3, const T4 &Val4, const T5 &Val5, const T6 &Val6)
+    : format_object_base(Fmt), Val1(Val1), Val2(Val2), Val3(Val3), Val4(Val4),
+      Val5(Val5), Val6(Val6) { }
+
+  int snprint(char *Buffer, unsigned BufferSize) const override {
+    return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5, Val6);
+  }
+};
+
+/// These are helper functions used to produce formatted output.  They use
+/// template type deduction to construct the appropriate instance of the
+/// format_object class to simplify their construction.
+///
+/// This is typically used like:
+/// \code
+///   OS << format("%0.4f", myfloat) << '\n';
+/// \endcode
+
+template <typename T>
+inline format_object1<T> format(const char *Fmt, const T &Val) {
+  return format_object1<T>(Fmt, Val);
+}
+
+template <typename T1, typename T2>
+inline format_object2<T1, T2> format(const char *Fmt, const T1 &Val1,
+                                     const T2 &Val2) {
+  return format_object2<T1, T2>(Fmt, Val1, Val2);
+}
+
+template <typename T1, typename T2, typename T3>
+  inline format_object3<T1, T2, T3> format(const char *Fmt, const T1 &Val1,
+                                           const T2 &Val2, const T3 &Val3) {
+  return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1,
+                                             const T2 &Val2, const T3 &Val3,
+                                             const T4 &Val4) {
+  return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1,
+                                             const T2 &Val2, const T3 &Val3,
+                                             const T4 &Val4, const T5 &Val5) {
+  return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6>
+inline format_object6<T1, T2, T3, T4, T5, T6>
+format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3,
+       const T4 &Val4, const T5 &Val5, const T6 &Val6) {
+  return format_object6<T1, T2, T3, T4, T5, T6>(Fmt, Val1, Val2, Val3, Val4,
+                                                Val5, Val6);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
new file mode 100644
index 0000000..8137daa
--- /dev/null
+++ b/include/llvm/Support/FormattedStream.h
@@ -0,0 +1,182 @@
+//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains raw_ostream implementations for streams to do
+// things like pretty-print comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
+#define LLVM_SUPPORT_FORMATTEDSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <utility>
+
+namespace llvm {
+
+/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
+/// of line and column position, allowing padding out to specific column
+/// boundaries and querying the number of lines written to the stream.
+///
+class formatted_raw_ostream : public raw_ostream {
+public:
+  /// DELETE_STREAM - Tell the destructor to delete the held stream.
+  ///
+  static const bool DELETE_STREAM = true;
+
+  /// PRESERVE_STREAM - Tell the destructor to not delete the held
+  /// stream.
+  ///
+  static const bool PRESERVE_STREAM = false;
+
+private:
+  /// TheStream - The real stream we output to. We set it to be
+  /// unbuffered, since we're already doing our own buffering.
+  ///
+  raw_ostream *TheStream;
+
+  /// DeleteStream - Do we need to delete TheStream in the
+  /// destructor?
+  ///
+  bool DeleteStream;
+
+  /// Position - The current output column and line of the data that's
+  /// been flushed and the portion of the buffer that's been
+  /// scanned.  The line and column scheme is zero-based.
+  ///
+  std::pair<unsigned, unsigned> Position;
+
+  /// Scanned - This points to one past the last character in the
+  /// buffer we've scanned.
+  ///
+  const char *Scanned;
+
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  /// current_pos - Return the current position within the stream,
+  /// not counting the bytes currently in the buffer.
+  uint64_t current_pos() const override {
+    // Our current position in the stream is all the contents which have been
+    // written to the underlying stream (*not* the current position of the
+    // underlying stream).
+    return TheStream->tell();
+  }
+
+  /// ComputePosition - Examine the given output buffer and figure out the new
+  /// position after output.
+  ///
+  void ComputePosition(const char *Ptr, size_t size);
+
+public:
+  /// formatted_raw_ostream - Open the specified file for
+  /// writing. If an error occurs, information about the error is
+  /// put into ErrorInfo, and the stream should be immediately
+  /// destroyed; the string will be empty if no error occurred.
+  ///
+  /// As a side effect, the given Stream is set to be Unbuffered.
+  /// This is because formatted_raw_ostream does its own buffering,
+  /// so it doesn't want another layer of buffering to be happening
+  /// underneath it.
+  ///
+  formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) 
+    : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+    setStream(Stream, Delete);
+  }
+  explicit formatted_raw_ostream()
+    : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+    Scanned = nullptr;
+  }
+
+  ~formatted_raw_ostream() {
+    flush();
+    releaseStream();
+  }
+
+  void setStream(raw_ostream &Stream, bool Delete = false) {
+    releaseStream();
+
+    TheStream = &Stream;
+    DeleteStream = Delete;
+
+    // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+    // own buffering, and it doesn't need or want TheStream to do another
+    // layer of buffering underneath. Resize the buffer to what TheStream
+    // had been using, and tell TheStream not to do its own buffering.
+    if (size_t BufferSize = TheStream->GetBufferSize())
+      SetBufferSize(BufferSize);
+    else
+      SetUnbuffered();
+    TheStream->SetUnbuffered();
+
+    Scanned = nullptr;
+  }
+
+  /// PadToColumn - Align the output to some column number.  If the current
+  /// column is already equal to or more than NewCol, PadToColumn inserts one
+  /// space.
+  ///
+  /// \param NewCol - The column to move to.
+  formatted_raw_ostream &PadToColumn(unsigned NewCol);
+
+  /// getColumn - Return the column number
+  unsigned getColumn() { return Position.first; }
+
+  /// getLine - Return the line number
+  unsigned getLine() { return Position.second; }
+
+  raw_ostream &resetColor() override {
+    TheStream->resetColor();
+    return *this;
+  }
+
+  raw_ostream &reverseColor() override {
+    TheStream->reverseColor();
+    return *this;
+  }
+
+  raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
+    TheStream->changeColor(Color, Bold, BG);
+    return *this;
+  }
+
+  bool is_displayed() const override {
+    return TheStream->is_displayed();
+  }
+
+private:
+  void releaseStream() {
+    // Delete the stream if needed. Otherwise, transfer the buffer
+    // settings from this raw_ostream back to the underlying stream.
+    if (!TheStream)
+      return;
+    if (DeleteStream)
+      delete TheStream;
+    else if (size_t BufferSize = GetBufferSize())
+      TheStream->SetBufferSize(BufferSize);
+    else
+      TheStream->SetUnbuffered();
+  }
+};
+
+/// fouts() - This returns a reference to a formatted_raw_ostream for
+/// standard output.  Use it like: fouts() << "foo" << "bar";
+formatted_raw_ostream &fouts();
+
+/// ferrs() - This returns a reference to a formatted_raw_ostream for
+/// standard error.  Use it like: ferrs() << "foo" << "bar";
+formatted_raw_ostream &ferrs();
+
+/// fdbgs() - This returns a reference to a formatted_raw_ostream for
+/// debug output.  Use it like: fdbgs() << "foo" << "bar";
+formatted_raw_ostream &fdbgs();
+
+} // end llvm namespace
+
+
+#endif
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
new file mode 100644
index 0000000..0cb6cfd
--- /dev/null
+++ b/include/llvm/Support/GCOV.h
@@ -0,0 +1,429 @@
+//===- GCOV.h - LLVM coverage tool ----------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header provides the interface to read and write coverage files that
+// use 'gcov' format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GCOV_H
+#define LLVM_SUPPORT_GCOV_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class GCOVFunction;
+class GCOVBlock;
+class FileInfo;
+
+namespace GCOV {
+  enum GCOVVersion {
+    V402,
+    V404
+  };
+} // end GCOV namespace
+
+/// GCOVOptions - A struct for passing gcov options between functions.
+struct GCOVOptions {
+  GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N)
+      : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
+        PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {}
+
+  bool AllBlocks;
+  bool BranchInfo;
+  bool BranchCount;
+  bool FuncCoverage;
+  bool PreservePaths;
+  bool UncondBranch;
+  bool LongFileNames;
+  bool NoOutput;
+};
+
+/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
+/// read operations.
+class GCOVBuffer {
+public:
+  GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
+  
+  /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
+  bool readGCNOFormat() {
+    StringRef File = Buffer->getBuffer().slice(0, 4);
+    if (File != "oncg") {
+      errs() << "Unexpected file type: " << File << ".\n";
+      return false;
+    }
+    Cursor = 4;
+    return true;
+  }
+
+  /// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
+  bool readGCDAFormat() {
+    StringRef File = Buffer->getBuffer().slice(0, 4);
+    if (File != "adcg") {
+      errs() << "Unexpected file type: " << File << ".\n";
+      return false;
+    }
+    Cursor = 4;
+    return true;
+  }
+
+  /// readGCOVVersion - Read GCOV version.
+  bool readGCOVVersion(GCOV::GCOVVersion &Version) {
+    StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (VersionStr == "*204") {
+      Cursor += 4;
+      Version = GCOV::V402;
+      return true;
+    }
+    if (VersionStr == "*404") {
+      Cursor += 4;
+      Version = GCOV::V404;
+      return true;
+    }
+    errs() << "Unexpected version: " << VersionStr << ".\n";
+    return false;
+  }
+
+  /// readFunctionTag - If cursor points to a function tag then increment the
+  /// cursor and return true otherwise return false.
+  bool readFunctionTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() || 
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\0' || Tag[3] != '\1') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readBlockTag - If cursor points to a block tag then increment the
+  /// cursor and return true otherwise return false.
+  bool readBlockTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() || 
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\x41' || Tag[3] != '\x01') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readEdgeTag - If cursor points to an edge tag then increment the
+  /// cursor and return true otherwise return false.
+  bool readEdgeTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() || 
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\x43' || Tag[3] != '\x01') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readLineTag - If cursor points to a line tag then increment the
+  /// cursor and return true otherwise return false.
+  bool readLineTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() || 
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\x45' || Tag[3] != '\x01') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readArcTag - If cursor points to an gcda arc tag then increment the
+  /// cursor and return true otherwise return false.
+  bool readArcTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() || 
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\xa1' || Tag[3] != '\1') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readObjectTag - If cursor points to an object summary tag then increment
+  /// the cursor and return true otherwise return false.
+  bool readObjectTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() ||
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\0' || Tag[3] != '\xa1') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  /// readProgramTag - If cursor points to a program summary tag then increment
+  /// the cursor and return true otherwise return false.
+  bool readProgramTag() {
+    StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    if (Tag.empty() ||
+        Tag[0] != '\0' || Tag[1] != '\0' ||
+        Tag[2] != '\0' || Tag[3] != '\xa3') {
+      return false;
+    }
+    Cursor += 4;
+    return true;
+  }
+
+  bool readInt(uint32_t &Val) {
+    if (Buffer->getBuffer().size() < Cursor+4) {
+      errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
+      return false;
+    }
+    StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
+    Cursor += 4;
+    Val = *(const uint32_t *)(Str.data());
+    return true;
+  }
+
+  bool readInt64(uint64_t &Val) {
+    uint32_t Lo, Hi;
+    if (!readInt(Lo) || !readInt(Hi)) return false;
+    Val = ((uint64_t)Hi << 32) | Lo;
+    return true;
+  }
+
+  bool readString(StringRef &Str) {
+    uint32_t Len = 0;
+    // Keep reading until we find a non-zero length. This emulates gcov's
+    // behaviour, which appears to do the same.
+    while (Len == 0)
+      if (!readInt(Len)) return false;
+    Len *= 4;
+    if (Buffer->getBuffer().size() < Cursor+Len) {
+      errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
+      return false;
+    }
+    Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
+    Cursor += Len;
+    return true;
+  }
+
+  uint64_t getCursor() const { return Cursor; }
+  void advanceCursor(uint32_t n) { Cursor += n*4; }
+private:
+  MemoryBuffer *Buffer;
+  uint64_t Cursor;
+};
+
+/// GCOVFile - Collects coverage information for one pair of coverage file
+/// (.gcno and .gcda).
+class GCOVFile {
+public:
+  GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
+               ProgramCount(0) {}
+  bool readGCNO(GCOVBuffer &Buffer);
+  bool readGCDA(GCOVBuffer &Buffer);
+  uint32_t getChecksum() const { return Checksum; }
+  void dump() const;
+  void collectLineCounts(FileInfo &FI);
+private:
+  bool GCNOInitialized;
+  GCOV::GCOVVersion Version;
+  uint32_t Checksum;
+  SmallVector<std::unique_ptr<GCOVFunction>, 16> Functions;
+  uint32_t RunCount;
+  uint32_t ProgramCount;
+};
+
+/// GCOVEdge - Collects edge information.
+struct GCOVEdge {
+  GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D), Count(0) {}
+
+  GCOVBlock &Src;
+  GCOVBlock &Dst;
+  uint64_t Count;
+};
+
+/// GCOVFunction - Collects function information.
+class GCOVFunction {
+public:
+  typedef SmallVectorImpl<std::unique_ptr<GCOVBlock>>::const_iterator
+  BlockIterator;
+
+  GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
+  bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+  bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+  StringRef getName() const { return Name; }
+  StringRef getFilename() const { return Filename; }
+  size_t getNumBlocks() const { return Blocks.size(); }
+  uint64_t getEntryCount() const;
+  uint64_t getExitCount() const;
+
+  BlockIterator block_begin() const { return Blocks.begin(); }
+  BlockIterator block_end() const { return Blocks.end(); }
+
+  void dump() const;
+  void collectLineCounts(FileInfo &FI);
+private:
+  GCOVFile &Parent;
+  uint32_t Ident;
+  uint32_t Checksum;
+  uint32_t LineNumber;
+  StringRef Name;
+  StringRef Filename;
+  SmallVector<std::unique_ptr<GCOVBlock>, 16> Blocks;
+  SmallVector<std::unique_ptr<GCOVEdge>, 16> Edges;
+};
+
+/// GCOVBlock - Collects block information.
+class GCOVBlock {
+  struct EdgeWeight {
+    EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
+
+    GCOVBlock *Dst;
+    uint64_t Count;
+  };
+
+  struct SortDstEdgesFunctor {
+    bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) {
+      return E1->Dst.Number < E2->Dst.Number;
+    }
+  };
+public:
+  typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
+
+  GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
+    DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
+  ~GCOVBlock();
+  const GCOVFunction &getParent() const { return Parent; }
+  void addLine(uint32_t N) { Lines.push_back(N); }
+  uint32_t getLastLine() const { return Lines.back(); }
+  void addCount(size_t DstEdgeNo, uint64_t N);
+  uint64_t getCount() const { return Counter; }
+
+  void addSrcEdge(GCOVEdge *Edge) {
+    assert(&Edge->Dst == this); // up to caller to ensure edge is valid
+    SrcEdges.push_back(Edge);
+  }
+  void addDstEdge(GCOVEdge *Edge) {
+    assert(&Edge->Src == this); // up to caller to ensure edge is valid
+    // Check if adding this edge causes list to become unsorted.
+    if (DstEdges.size() && DstEdges.back()->Dst.Number > Edge->Dst.Number)
+      DstEdgesAreSorted = false;
+    DstEdges.push_back(Edge);
+  }
+  size_t getNumSrcEdges() const { return SrcEdges.size(); }
+  size_t getNumDstEdges() const { return DstEdges.size(); }
+  void sortDstEdges();
+
+  EdgeIterator src_begin() const { return SrcEdges.begin(); }
+  EdgeIterator src_end() const { return SrcEdges.end(); }
+  EdgeIterator dst_begin() const { return DstEdges.begin(); }
+  EdgeIterator dst_end() const { return DstEdges.end(); }
+
+  void dump() const;
+  void collectLineCounts(FileInfo &FI);
+private:
+  GCOVFunction &Parent;
+  uint32_t Number;
+  uint64_t Counter;
+  bool DstEdgesAreSorted;
+  SmallVector<GCOVEdge *, 16> SrcEdges;
+  SmallVector<GCOVEdge *, 16> DstEdges;
+  SmallVector<uint32_t, 16> Lines;
+};
+
+class FileInfo {
+  // It is unlikely--but possible--for multiple functions to be on the same line.
+  // Therefore this typedef allows LineData.Functions to store multiple functions
+  // per instance. This is rare, however, so optimize for the common case.
+  typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
+  typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
+  typedef SmallVector<const GCOVBlock *, 4> BlockVector;
+  typedef DenseMap<uint32_t, BlockVector> BlockLines;
+
+  struct LineData {
+    LineData() : LastLine(0) {}
+    BlockLines Blocks;
+    FunctionLines Functions;
+    uint32_t LastLine;
+  };
+
+  struct GCOVCoverage {
+    GCOVCoverage(StringRef Name) :
+      Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
+      BranchesTaken(0) {}
+
+    StringRef Name;
+
+    uint32_t LogicalLines;
+    uint32_t LinesExec;
+
+    uint32_t Branches;
+    uint32_t BranchesExec;
+    uint32_t BranchesTaken;
+  };
+public:
+  FileInfo(const GCOVOptions &Options) :
+    Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
+
+  void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
+    if (Line > LineInfo[Filename].LastLine)
+      LineInfo[Filename].LastLine = Line;
+    LineInfo[Filename].Blocks[Line-1].push_back(Block);
+  }
+  void addFunctionLine(StringRef Filename, uint32_t Line,
+                       const GCOVFunction *Function) {
+    if (Line > LineInfo[Filename].LastLine)
+      LineInfo[Filename].LastLine = Line;
+    LineInfo[Filename].Functions[Line-1].push_back(Function);
+  }
+  void setRunCount(uint32_t Runs) { RunCount = Runs; }
+  void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
+  void print(StringRef MainFilename, StringRef GCNOFile, StringRef GCDAFile);
+
+private:
+  std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
+  std::unique_ptr<raw_ostream> openCoveragePath(StringRef CoveragePath);
+  void printFunctionSummary(raw_ostream &OS,
+                            const FunctionVector &Funcs) const;
+  void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
+                      uint32_t LineIndex, uint32_t &BlockNo) const;
+  void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
+                       GCOVCoverage &Coverage, uint32_t &EdgeNo);
+  void printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo,
+                             uint64_t Count) const;
+
+  void printCoverage(const GCOVCoverage &Coverage) const;
+  void printFuncCoverage() const;
+  void printFileCoverage() const;
+
+  const GCOVOptions &Options;
+  StringMap<LineData> LineInfo;
+  uint32_t RunCount;
+  uint32_t ProgramCount;
+
+  typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4>
+      FileCoverageList;
+  typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap;
+
+  FileCoverageList FileCoverages;
+  FuncCoverageMap FuncCoverages;
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
new file mode 100644
index 0000000..876ab6e
--- /dev/null
+++ b/include/llvm/Support/GenericDomTree.h
@@ -0,0 +1,736 @@
+//===- GenericDomTree.h - Generic dominator trees for graphs ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines a set of templates that efficiently compute a dominator
+/// tree over a generic graph. This is used typically in LLVM for fast
+/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
+/// graph types.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominatorBase - Base class that other, more interesting dominator analyses
+/// inherit from.
+///
+template <class NodeT>
+class DominatorBase {
+protected:
+  std::vector<NodeT*> Roots;
+  const bool IsPostDominators;
+  inline explicit DominatorBase(bool isPostDom) :
+    Roots(), IsPostDominators(isPostDom) {}
+public:
+
+  /// getRoots - Return the root blocks of the current CFG.  This may include
+  /// multiple blocks if we are computing post dominators.  For forward
+  /// dominators, this will always be a single block (the entry node).
+  ///
+  inline const std::vector<NodeT*> &getRoots() const { return Roots; }
+
+  /// isPostDominator - Returns true if analysis based of postdoms
+  ///
+  bool isPostDominator() const { return IsPostDominators; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// DomTreeNodeBase - Dominator Tree Node
+template<class NodeT> class DominatorTreeBase;
+struct PostDominatorTree;
+
+template <class NodeT>
+class DomTreeNodeBase {
+  NodeT *TheBB;
+  DomTreeNodeBase<NodeT> *IDom;
+  std::vector<DomTreeNodeBase<NodeT> *> Children;
+  mutable int DFSNumIn, DFSNumOut;
+
+  template<class N> friend class DominatorTreeBase;
+  friend struct PostDominatorTree;
+public:
+  typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
+  typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
+                   const_iterator;
+
+  iterator begin()             { return Children.begin(); }
+  iterator end()               { return Children.end(); }
+  const_iterator begin() const { return Children.begin(); }
+  const_iterator end()   const { return Children.end(); }
+
+  NodeT *getBlock() const { return TheBB; }
+  DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
+  const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
+    return Children;
+  }
+
+  DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
+    : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
+
+  DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
+    Children.push_back(C);
+    return C;
+  }
+
+  size_t getNumChildren() const {
+    return Children.size();
+  }
+
+  void clearAllChildren() {
+    Children.clear();
+  }
+
+  bool compare(const DomTreeNodeBase<NodeT> *Other) const {
+    if (getNumChildren() != Other->getNumChildren())
+      return true;
+
+    SmallPtrSet<const NodeT *, 4> OtherChildren;
+    for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
+      const NodeT *Nd = (*I)->getBlock();
+      OtherChildren.insert(Nd);
+    }
+
+    for (const_iterator I = begin(), E = end(); I != E; ++I) {
+      const NodeT *N = (*I)->getBlock();
+      if (OtherChildren.count(N) == 0)
+        return true;
+    }
+    return false;
+  }
+
+  void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
+    assert(IDom && "No immediate dominator?");
+    if (IDom != NewIDom) {
+      typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+                  std::find(IDom->Children.begin(), IDom->Children.end(), this);
+      assert(I != IDom->Children.end() &&
+             "Not in immediate dominator children set!");
+      // I am no longer your child...
+      IDom->Children.erase(I);
+
+      // Switch to new dominator
+      IDom = NewIDom;
+      IDom->Children.push_back(this);
+    }
+  }
+
+  /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
+  /// not call them.
+  unsigned getDFSNumIn() const { return DFSNumIn; }
+  unsigned getDFSNumOut() const { return DFSNumOut; }
+private:
+  // Return true if this node is dominated by other. Use this only if DFS info
+  // is valid.
+  bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
+    return this->DFSNumIn >= other->DFSNumIn &&
+      this->DFSNumOut <= other->DFSNumOut;
+  }
+};
+
+template<class NodeT>
+inline raw_ostream &operator<<(raw_ostream &o,
+                               const DomTreeNodeBase<NodeT> *Node) {
+  if (Node->getBlock())
+    Node->getBlock()->printAsOperand(o, false);
+  else
+    o << " <<exit node>>";
+
+  o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+
+  return o << "\n";
+}
+
+template<class NodeT>
+inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
+                         unsigned Lev) {
+  o.indent(2*Lev) << "[" << Lev << "] " << N;
+  for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
+       E = N->end(); I != E; ++I)
+    PrintDomTree<NodeT>(*I, o, Lev+1);
+}
+
+//===----------------------------------------------------------------------===//
+/// DominatorTree - Calculate the immediate dominator tree for a function.
+///
+
+template<class FuncT, class N>
+void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+               FuncT& F);
+
+template<class NodeT>
+class DominatorTreeBase : public DominatorBase<NodeT> {
+  bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
+                               const DomTreeNodeBase<NodeT> *B) const {
+    assert(A != B);
+    assert(isReachableFromEntry(B));
+    assert(isReachableFromEntry(A));
+
+    const DomTreeNodeBase<NodeT> *IDom;
+    while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
+      B = IDom;   // Walk up the tree
+    return IDom != nullptr;
+  }
+
+protected:
+  typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
+  DomTreeNodeMapType DomTreeNodes;
+  DomTreeNodeBase<NodeT> *RootNode;
+
+  mutable bool DFSInfoValid;
+  mutable unsigned int SlowQueries;
+  // Information record used during immediate dominators computation.
+  struct InfoRec {
+    unsigned DFSNum;
+    unsigned Parent;
+    unsigned Semi;
+    NodeT *Label;
+
+    InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {}
+  };
+
+  DenseMap<NodeT*, NodeT*> IDoms;
+
+  // Vertex - Map the DFS number to the NodeT*
+  std::vector<NodeT*> Vertex;
+
+  // Info - Collection of information used during the computation of idoms.
+  DenseMap<NodeT*, InfoRec> Info;
+
+  void reset() {
+    for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
+           E = DomTreeNodes.end(); I != E; ++I)
+      delete I->second;
+    DomTreeNodes.clear();
+    IDoms.clear();
+    this->Roots.clear();
+    Vertex.clear();
+    RootNode = nullptr;
+  }
+
+  // NewBB is split and now it has one successor. Update dominator tree to
+  // reflect this change.
+  template<class N, class GraphT>
+  void Split(DominatorTreeBase<typename GraphT::NodeType>& DT,
+             typename GraphT::NodeType* NewBB) {
+    assert(std::distance(GraphT::child_begin(NewBB),
+                         GraphT::child_end(NewBB)) == 1 &&
+           "NewBB should have a single successor!");
+    typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB);
+
+    std::vector<typename GraphT::NodeType*> PredBlocks;
+    typedef GraphTraits<Inverse<N> > InvTraits;
+    for (typename InvTraits::ChildIteratorType PI =
+         InvTraits::child_begin(NewBB),
+         PE = InvTraits::child_end(NewBB); PI != PE; ++PI)
+      PredBlocks.push_back(*PI);
+
+    assert(!PredBlocks.empty() && "No predblocks?");
+
+    bool NewBBDominatesNewBBSucc = true;
+    for (typename InvTraits::ChildIteratorType PI =
+         InvTraits::child_begin(NewBBSucc),
+         E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) {
+      typename InvTraits::NodeType *ND = *PI;
+      if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
+          DT.isReachableFromEntry(ND)) {
+        NewBBDominatesNewBBSucc = false;
+        break;
+      }
+    }
+
+    // Find NewBB's immediate dominator and create new dominator tree node for
+    // NewBB.
+    NodeT *NewBBIDom = nullptr;
+    unsigned i = 0;
+    for (i = 0; i < PredBlocks.size(); ++i)
+      if (DT.isReachableFromEntry(PredBlocks[i])) {
+        NewBBIDom = PredBlocks[i];
+        break;
+      }
+
+    // It's possible that none of the predecessors of NewBB are reachable;
+    // in that case, NewBB itself is unreachable, so nothing needs to be
+    // changed.
+    if (!NewBBIDom)
+      return;
+
+    for (i = i + 1; i < PredBlocks.size(); ++i) {
+      if (DT.isReachableFromEntry(PredBlocks[i]))
+        NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
+    }
+
+    // Create the new dominator tree node... and set the idom of NewBB.
+    DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
+
+    // If NewBB strictly dominates other blocks, then it is now the immediate
+    // dominator of NewBBSucc.  Update the dominator tree as appropriate.
+    if (NewBBDominatesNewBBSucc) {
+      DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
+      DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
+    }
+  }
+
+public:
+  explicit DominatorTreeBase(bool isPostDom)
+    : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+  virtual ~DominatorTreeBase() { reset(); }
+
+  /// compare - Return false if the other dominator tree base matches this
+  /// dominator tree base. Otherwise return true.
+  bool compare(const DominatorTreeBase &Other) const {
+
+    const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
+    if (DomTreeNodes.size() != OtherDomTreeNodes.size())
+      return true;
+
+    for (typename DomTreeNodeMapType::const_iterator
+           I = this->DomTreeNodes.begin(),
+           E = this->DomTreeNodes.end(); I != E; ++I) {
+      NodeT *BB = I->first;
+      typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB);
+      if (OI == OtherDomTreeNodes.end())
+        return true;
+
+      DomTreeNodeBase<NodeT>* MyNd = I->second;
+      DomTreeNodeBase<NodeT>* OtherNd = OI->second;
+
+      if (MyNd->compare(OtherNd))
+        return true;
+    }
+
+    return false;
+  }
+
+  virtual void releaseMemory() { reset(); }
+
+  /// getNode - return the (Post)DominatorTree node for the specified basic
+  /// block.  This is the same as using operator[] on this class.
+  ///
+  inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
+    return DomTreeNodes.lookup(BB);
+  }
+
+  inline DomTreeNodeBase<NodeT> *operator[](NodeT *BB) const {
+    return getNode(BB);
+  }
+
+  /// getRootNode - This returns the entry node for the CFG of the function.  If
+  /// this tree represents the post-dominance relations for a function, however,
+  /// this root may be a node with the block == NULL.  This is the case when
+  /// there are multiple exit nodes from a particular function.  Consumers of
+  /// post-dominance information must be capable of dealing with this
+  /// possibility.
+  ///
+  DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
+  const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
+
+  /// Get all nodes dominated by R, including R itself.
+  void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
+    Result.clear();
+    const DomTreeNodeBase<NodeT> *RN = getNode(R);
+    if (!RN)
+      return; // If R is unreachable, it will not be present in the DOM tree.
+    SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
+    WL.push_back(RN);
+
+    while (!WL.empty()) {
+      const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();
+      Result.push_back(N->getBlock());
+      WL.append(N->begin(), N->end());
+    }
+  }
+
+  /// properlyDominates - Returns true iff A dominates B and A != B.
+  /// Note that this is not a constant time operation!
+  ///
+  bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
+                         const DomTreeNodeBase<NodeT> *B) const {
+    if (!A || !B)
+      return false;
+    if (A == B)
+      return false;
+    return dominates(A, B);
+  }
+
+  bool properlyDominates(const NodeT *A, const NodeT *B) const;
+
+  /// isReachableFromEntry - Return true if A is dominated by the entry
+  /// block of the function containing it.
+  bool isReachableFromEntry(const NodeT* A) const {
+    assert(!this->isPostDominator() &&
+           "This is not implemented for post dominators");
+    return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
+  }
+
+  inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const {
+    return A;
+  }
+
+  /// dominates - Returns true iff A dominates B.  Note that this is not a
+  /// constant time operation!
+  ///
+  inline bool dominates(const DomTreeNodeBase<NodeT> *A,
+                        const DomTreeNodeBase<NodeT> *B) const {
+    // A node trivially dominates itself.
+    if (B == A)
+      return true;
+
+    // An unreachable node is dominated by anything.
+    if (!isReachableFromEntry(B))
+      return true;
+
+    // And dominates nothing.
+    if (!isReachableFromEntry(A))
+      return false;
+
+    // Compare the result of the tree walk and the dfs numbers, if expensive
+    // checks are enabled.
+#ifdef XDEBUG
+    assert((!DFSInfoValid ||
+            (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
+           "Tree walk disagrees with dfs numbers!");
+#endif
+
+    if (DFSInfoValid)
+      return B->DominatedBy(A);
+
+    // If we end up with too many slow queries, just update the
+    // DFS numbers on the theory that we are going to keep querying.
+    SlowQueries++;
+    if (SlowQueries > 32) {
+      updateDFSNumbers();
+      return B->DominatedBy(A);
+    }
+
+    return dominatedBySlowTreeWalk(A, B);
+  }
+
+  bool dominates(const NodeT *A, const NodeT *B) const;
+
+  NodeT *getRoot() const {
+    assert(this->Roots.size() == 1 && "Should always have entry node!");
+    return this->Roots[0];
+  }
+
+  /// findNearestCommonDominator - Find nearest common dominator basic block
+  /// for basic block A and B. If there is no such block then return NULL.
+  NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
+    assert(A->getParent() == B->getParent() &&
+           "Two blocks are not in same function");
+
+    // If either A or B is a entry block then it is nearest common dominator
+    // (for forward-dominators).
+    if (!this->isPostDominator()) {
+      NodeT &Entry = A->getParent()->front();
+      if (A == &Entry || B == &Entry)
+        return &Entry;
+    }
+
+    // If B dominates A then B is nearest common dominator.
+    if (dominates(B, A))
+      return B;
+
+    // If A dominates B then A is nearest common dominator.
+    if (dominates(A, B))
+      return A;
+
+    DomTreeNodeBase<NodeT> *NodeA = getNode(A);
+    DomTreeNodeBase<NodeT> *NodeB = getNode(B);
+
+    // If we have DFS info, then we can avoid all allocations by just querying
+    // it from each IDom. Note that because we call 'dominates' twice above, we
+    // expect to call through this code at most 16 times in a row without
+    // building valid DFS information. This is important as below is a *very*
+    // slow tree walk.
+    if (DFSInfoValid) {
+      DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+      while (IDomA) {
+        if (NodeB->DominatedBy(IDomA))
+          return IDomA->getBlock();
+        IDomA = IDomA->getIDom();
+      }
+      return nullptr;
+    }
+
+    // Collect NodeA dominators set.
+    SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
+    NodeADoms.insert(NodeA);
+    DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+    while (IDomA) {
+      NodeADoms.insert(IDomA);
+      IDomA = IDomA->getIDom();
+    }
+
+    // Walk NodeB immediate dominators chain and find common dominator node.
+    DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();
+    while (IDomB) {
+      if (NodeADoms.count(IDomB) != 0)
+        return IDomB->getBlock();
+
+      IDomB = IDomB->getIDom();
+    }
+
+    return nullptr;
+  }
+
+  const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
+    // Cast away the const qualifiers here. This is ok since
+    // const is re-introduced on the return type.
+    return findNearestCommonDominator(const_cast<NodeT *>(A),
+                                      const_cast<NodeT *>(B));
+  }
+
+  //===--------------------------------------------------------------------===//
+  // API to update (Post)DominatorTree information based on modifications to
+  // the CFG...
+
+  /// addNewBlock - Add a new node to the dominator tree information.  This
+  /// creates a new node as a child of DomBB dominator node,linking it into
+  /// the children list of the immediate dominator.
+  DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
+    assert(getNode(BB) == nullptr && "Block already in dominator tree!");
+    DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
+    assert(IDomNode && "Not immediate dominator specified for block!");
+    DFSInfoValid = false;
+    return DomTreeNodes[BB] =
+      IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
+  }
+
+  /// changeImmediateDominator - This method is used to update the dominator
+  /// tree information when a node's immediate dominator changes.
+  ///
+  void changeImmediateDominator(DomTreeNodeBase<NodeT> *N,
+                                DomTreeNodeBase<NodeT> *NewIDom) {
+    assert(N && NewIDom && "Cannot change null node pointers!");
+    DFSInfoValid = false;
+    N->setIDom(NewIDom);
+  }
+
+  void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
+    changeImmediateDominator(getNode(BB), getNode(NewBB));
+  }
+
+  /// eraseNode - Removes a node from the dominator tree. Block must not
+  /// dominate any other blocks. Removes node from its immediate dominator's
+  /// children list. Deletes dominator node associated with basic block BB.
+  void eraseNode(NodeT *BB) {
+    DomTreeNodeBase<NodeT> *Node = getNode(BB);
+    assert(Node && "Removing node that isn't in dominator tree.");
+    assert(Node->getChildren().empty() && "Node is not a leaf node.");
+
+      // Remove node from immediate dominator's children list.
+    DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
+    if (IDom) {
+      typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+        std::find(IDom->Children.begin(), IDom->Children.end(), Node);
+      assert(I != IDom->Children.end() &&
+             "Not in immediate dominator children set!");
+      // I am no longer your child...
+      IDom->Children.erase(I);
+    }
+
+    DomTreeNodes.erase(BB);
+    delete Node;
+  }
+
+  /// removeNode - Removes a node from the dominator tree.  Block must not
+  /// dominate any other blocks.  Invalidates any node pointing to removed
+  /// block.
+  void removeNode(NodeT *BB) {
+    assert(getNode(BB) && "Removing node that isn't in dominator tree.");
+    DomTreeNodes.erase(BB);
+  }
+
+  /// splitBlock - BB is split and now it has one successor. Update dominator
+  /// tree to reflect this change.
+  void splitBlock(NodeT* NewBB) {
+    if (this->IsPostDominators)
+      this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB);
+    else
+      this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB);
+  }
+
+  /// print - Convert to human readable form
+  ///
+  void print(raw_ostream &o) const {
+    o << "=============================--------------------------------\n";
+    if (this->isPostDominator())
+      o << "Inorder PostDominator Tree: ";
+    else
+      o << "Inorder Dominator Tree: ";
+    if (!this->DFSInfoValid)
+      o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
+    o << "\n";
+
+    // The postdom tree can have a null root if there are no returns.
+    if (getRootNode())
+      PrintDomTree<NodeT>(getRootNode(), o, 1);
+  }
+
+protected:
+  template<class GraphT>
+  friend typename GraphT::NodeType* Eval(
+                               DominatorTreeBase<typename GraphT::NodeType>& DT,
+                                         typename GraphT::NodeType* V,
+                                         unsigned LastLinked);
+
+  template<class GraphT>
+  friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+                          typename GraphT::NodeType* V,
+                          unsigned N);
+
+  template<class FuncT, class N>
+  friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+                        FuncT& F);
+
+  /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
+  /// dominator tree in dfs order.
+  void updateDFSNumbers() const {
+    unsigned DFSNum = 0;
+
+    SmallVector<std::pair<const DomTreeNodeBase<NodeT>*,
+                typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack;
+
+    const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
+
+    if (!ThisRoot)
+      return;
+
+    // Even in the case of multiple exits that form the post dominator root
+    // nodes, do not iterate over all exits, but start from the virtual root
+    // node. Otherwise bbs, that are not post dominated by any exit but by the
+    // virtual root node, will never be assigned a DFS number.
+    WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
+    ThisRoot->DFSNumIn = DFSNum++;
+
+    while (!WorkStack.empty()) {
+      const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+      typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
+        WorkStack.back().second;
+
+      // If we visited all of the children of this node, "recurse" back up the
+      // stack setting the DFOutNum.
+      if (ChildIt == Node->end()) {
+        Node->DFSNumOut = DFSNum++;
+        WorkStack.pop_back();
+      } else {
+        // Otherwise, recursively visit this child.
+        const DomTreeNodeBase<NodeT> *Child = *ChildIt;
+        ++WorkStack.back().second;
+
+        WorkStack.push_back(std::make_pair(Child, Child->begin()));
+        Child->DFSNumIn = DFSNum++;
+      }
+    }
+
+    SlowQueries = 0;
+    DFSInfoValid = true;
+  }
+
+  DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
+    if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
+      return Node;
+
+    // Haven't calculated this node yet?  Get or calculate the node for the
+    // immediate dominator.
+    NodeT *IDom = getIDom(BB);
+
+    assert(IDom || this->DomTreeNodes[nullptr]);
+    DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+    // Add a new tree node for this NodeT, and link it as a child of
+    // IDomNode
+    DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
+    return this->DomTreeNodes[BB] = IDomNode->addChild(C);
+  }
+
+  inline NodeT *getIDom(NodeT *BB) const {
+    return IDoms.lookup(BB);
+  }
+
+  inline void addRoot(NodeT* BB) {
+    this->Roots.push_back(BB);
+  }
+
+public:
+  /// recalculate - compute a dominator tree for the given function
+  template<class FT>
+  void recalculate(FT& F) {
+    typedef GraphTraits<FT*> TraitsTy;
+    reset();
+    this->Vertex.push_back(nullptr);
+
+    if (!this->IsPostDominators) {
+      // Initialize root
+      NodeT *entry = TraitsTy::getEntryNode(&F);
+      this->Roots.push_back(entry);
+      this->IDoms[entry] = nullptr;
+      this->DomTreeNodes[entry] = nullptr;
+
+      Calculate<FT, NodeT*>(*this, F);
+    } else {
+      // Initialize the roots list
+      for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
+                                        E = TraitsTy::nodes_end(&F); I != E; ++I) {
+        if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
+          addRoot(I);
+
+        // Prepopulate maps so that we don't get iterator invalidation issues later.
+        this->IDoms[I] = nullptr;
+        this->DomTreeNodes[I] = nullptr;
+      }
+
+      Calculate<FT, Inverse<NodeT*> >(*this, F);
+    }
+  }
+};
+
+// These two functions are declared out of line as a workaround for building
+// with old (< r147295) versions of clang because of pr11642.
+template<class NodeT>
+bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
+  if (A == B)
+    return true;
+
+  // Cast away the const qualifiers here. This is ok since
+  // this function doesn't actually return the values returned
+  // from getNode.
+  return dominates(getNode(const_cast<NodeT *>(A)),
+                   getNode(const_cast<NodeT *>(B)));
+}
+template<class NodeT>
+bool
+DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const {
+  if (A == B)
+    return false;
+
+  // Cast away the const qualifiers here. This is ok since
+  // this function doesn't actually return the values returned
+  // from getNode.
+  return dominates(getNode(const_cast<NodeT *>(A)),
+                   getNode(const_cast<NodeT *>(B)));
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h
new file mode 100644
index 0000000..bcba5e0
--- /dev/null
+++ b/include/llvm/Support/GenericDomTreeConstruction.h
@@ -0,0 +1,289 @@
+//===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Generic dominator tree construction - This file provides routines to
+/// construct immediate dominator information for a flow-graph based on the
+/// algorithm described in this document:
+///
+///   A Fast Algorithm for Finding Dominators in a Flowgraph
+///   T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
+///
+/// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
+/// out that the theoretically slower O(n*log(n)) implementation is actually
+/// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
+///
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/GenericDomTree.h"
+
+namespace llvm {
+
+template<class GraphT>
+unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+                 typename GraphT::NodeType* V, unsigned N) {
+  // This is more understandable as a recursive algorithm, but we can't use the
+  // recursive algorithm due to stack depth issues.  Keep it here for
+  // documentation purposes.
+#if 0
+  InfoRec &VInfo = DT.Info[DT.Roots[i]];
+  VInfo.DFSNum = VInfo.Semi = ++N;
+  VInfo.Label = V;
+
+  Vertex.push_back(V);        // Vertex[n] = V;
+
+  for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
+    InfoRec &SuccVInfo = DT.Info[*SI];
+    if (SuccVInfo.Semi == 0) {
+      SuccVInfo.Parent = V;
+      N = DTDFSPass(DT, *SI, N);
+    }
+  }
+#else
+  bool IsChildOfArtificialExit = (N != 0);
+
+  SmallVector<std::pair<typename GraphT::NodeType*,
+                        typename GraphT::ChildIteratorType>, 32> Worklist;
+  Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
+  while (!Worklist.empty()) {
+    typename GraphT::NodeType* BB = Worklist.back().first;
+    typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
+
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+                                                                    DT.Info[BB];
+
+    // First time we visited this BB?
+    if (NextSucc == GraphT::child_begin(BB)) {
+      BBInfo.DFSNum = BBInfo.Semi = ++N;
+      BBInfo.Label = BB;
+
+      DT.Vertex.push_back(BB);       // Vertex[n] = V;
+
+      if (IsChildOfArtificialExit)
+        BBInfo.Parent = 1;
+
+      IsChildOfArtificialExit = false;
+    }
+
+    // store the DFS number of the current BB - the reference to BBInfo might
+    // get invalidated when processing the successors.
+    unsigned BBDFSNum = BBInfo.DFSNum;
+
+    // If we are done with this block, remove it from the worklist.
+    if (NextSucc == GraphT::child_end(BB)) {
+      Worklist.pop_back();
+      continue;
+    }
+
+    // Increment the successor number for the next time we get to it.
+    ++Worklist.back().second;
+    
+    // Visit the successor next, if it isn't already visited.
+    typename GraphT::NodeType* Succ = *NextSucc;
+
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
+                                                                  DT.Info[Succ];
+    if (SuccVInfo.Semi == 0) {
+      SuccVInfo.Parent = BBDFSNum;
+      Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
+    }
+  }
+#endif
+    return N;
+}
+
+template<class GraphT>
+typename GraphT::NodeType* 
+Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
+     typename GraphT::NodeType *VIn, unsigned LastLinked) {
+  typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
+                                                                  DT.Info[VIn];
+  if (VInInfo.DFSNum < LastLinked)
+    return VIn;
+
+  SmallVector<typename GraphT::NodeType*, 32> Work;
+  SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
+
+  if (VInInfo.Parent >= LastLinked)
+    Work.push_back(VIn);
+  
+  while (!Work.empty()) {
+    typename GraphT::NodeType* V = Work.back();
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
+                                                                     DT.Info[V];
+    typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
+
+    // Process Ancestor first
+    if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) {
+      Work.push_back(VAncestor);
+      continue;
+    } 
+    Work.pop_back(); 
+
+    // Update VInfo based on Ancestor info
+    if (VInfo.Parent < LastLinked)
+      continue;
+
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
+                                                             DT.Info[VAncestor];
+    typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
+    typename GraphT::NodeType* VLabel = VInfo.Label;
+    if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
+      VInfo.Label = VAncestorLabel;
+    VInfo.Parent = VAInfo.Parent;
+  }
+
+  return VInInfo.Label;
+}
+
+template<class FuncT, class NodeT>
+void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
+               FuncT& F) {
+  typedef GraphTraits<NodeT> GraphT;
+
+  unsigned N = 0;
+  bool MultipleRoots = (DT.Roots.size() > 1);
+  if (MultipleRoots) {
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+        DT.Info[nullptr];
+    BBInfo.DFSNum = BBInfo.Semi = ++N;
+    BBInfo.Label = nullptr;
+
+    DT.Vertex.push_back(nullptr);       // Vertex[n] = V;
+  }
+
+  // Step #1: Number blocks in depth-first order and initialize variables used
+  // in later stages of the algorithm.
+  for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
+       i != e; ++i)
+    N = DFSPass<GraphT>(DT, DT.Roots[i], N);
+
+  // it might be that some blocks did not get a DFS number (e.g., blocks of 
+  // infinite loops). In these cases an artificial exit node is required.
+  MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
+
+  // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
+  // bucket for each vertex. However, this is unnecessary, because each vertex
+  // is only placed into a single bucket (that of its semidominator), and each
+  // vertex's bucket is processed before it is added to any bucket itself.
+  //
+  // Instead of using a bucket per vertex, we use a single array Buckets that
+  // has two purposes. Before the vertex V with preorder number i is processed,
+  // Buckets[i] stores the index of the first element in V's bucket. After V's
+  // bucket is processed, Buckets[i] stores the index of the next element in the
+  // bucket containing V, if any.
+  SmallVector<unsigned, 32> Buckets;
+  Buckets.resize(N + 1);
+  for (unsigned i = 1; i <= N; ++i)
+    Buckets[i] = i;
+
+  for (unsigned i = N; i >= 2; --i) {
+    typename GraphT::NodeType* W = DT.Vertex[i];
+    typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
+                                                                     DT.Info[W];
+
+    // Step #2: Implicitly define the immediate dominator of vertices
+    for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
+      typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+      typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
+      DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+    }
+
+    // Step #3: Calculate the semidominators of all vertices
+
+    // initialize the semi dominator to point to the parent node
+    WInfo.Semi = WInfo.Parent;
+    typedef GraphTraits<Inverse<NodeT> > InvTraits;
+    for (typename InvTraits::ChildIteratorType CI =
+         InvTraits::child_begin(W),
+         E = InvTraits::child_end(W); CI != E; ++CI) {
+      typename InvTraits::NodeType *N = *CI;
+      if (DT.Info.count(N)) {  // Only if this predecessor is reachable!
+        unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
+        if (SemiU < WInfo.Semi)
+          WInfo.Semi = SemiU;
+      }
+    }
+
+    // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
+    // necessarily parent(V). In this case, set idom(V) here and avoid placing
+    // V into a bucket.
+    if (WInfo.Semi == WInfo.Parent) {
+      DT.IDoms[W] = DT.Vertex[WInfo.Parent];
+    } else {
+      Buckets[i] = Buckets[WInfo.Semi];
+      Buckets[WInfo.Semi] = i;
+    }
+  }
+
+  if (N >= 1) {
+    typename GraphT::NodeType* Root = DT.Vertex[1];
+    for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
+      typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+      DT.IDoms[V] = Root;
+    }
+  }
+
+  // Step #4: Explicitly define the immediate dominator of each vertex
+  for (unsigned i = 2; i <= N; ++i) {
+    typename GraphT::NodeType* W = DT.Vertex[i];
+    typename GraphT::NodeType*& WIDom = DT.IDoms[W];
+    if (WIDom != DT.Vertex[DT.Info[W].Semi])
+      WIDom = DT.IDoms[WIDom];
+  }
+
+  if (DT.Roots.empty()) return;
+
+  // Add a node for the root.  This node might be the actual root, if there is
+  // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
+  // which postdominates all real exits if there are multiple exit blocks, or
+  // an infinite loop.
+  typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr;
+
+  DT.DomTreeNodes[Root] = DT.RootNode =
+                  new DomTreeNodeBase<typename GraphT::NodeType>(Root, nullptr);
+
+  // Loop over all of the reachable blocks in the function...
+  for (unsigned i = 2; i <= N; ++i) {
+    typename GraphT::NodeType* W = DT.Vertex[i];
+
+    DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
+    if (BBNode) continue;  // Haven't calculated this node yet?
+
+    typename GraphT::NodeType* ImmDom = DT.getIDom(W);
+
+    assert(ImmDom || DT.DomTreeNodes[nullptr]);
+
+    // Get or calculate the node for the immediate dominator
+    DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
+                                                     DT.getNodeForBlock(ImmDom);
+
+    // Add a new tree node for this BasicBlock, and link it as a child of
+    // IDomNode
+    DomTreeNodeBase<typename GraphT::NodeType> *C =
+                    new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
+    DT.DomTreeNodes[W] = IDomNode->addChild(C);
+  }
+
+  // Free temporary memory used to construct idom's
+  DT.IDoms.clear();
+  DT.Info.clear();
+  std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
+
+  DT.updateDFSNumbers();
+}
+
+}
+
+#endif
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
new file mode 100644
index 0000000..2f02aa7
--- /dev/null
+++ b/include/llvm/Support/GraphWriter.h
@@ -0,0 +1,362 @@
+//===-- llvm/Support/GraphWriter.h - Write graph to a .dot 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 defines a simple interface that can be used to print out generic
+// LLVM graphs to ".dot" files.  "dot" is a tool that is part of the AT&T
+// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
+// be used to turn the files output by this interface into a variety of
+// different graphics formats.
+//
+// Graphs do not need to implement any interface past what is already required
+// by the GraphTraits template, but they can choose to implement specializations
+// of the DOTGraphTraits template if they want to customize the graphs output in
+// any way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GRAPHWRITER_H
+#define LLVM_SUPPORT_GRAPHWRITER_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+namespace DOT {  // Private functions...
+  std::string EscapeString(const std::string &Label);
+
+  /// \brief Get a color string for this node number. Simply round-robin selects
+  /// from a reasonable number of colors.
+  StringRef getColorString(unsigned NodeNumber);
+}
+
+namespace GraphProgram {
+   enum Name {
+      DOT,
+      FDP,
+      NEATO,
+      TWOPI,
+      CIRCO
+   };
+}
+
+bool DisplayGraph(StringRef Filename, bool wait = true,
+                  GraphProgram::Name program = GraphProgram::DOT);
+
+template<typename GraphType>
+class GraphWriter {
+  raw_ostream &O;
+  const GraphType &G;
+
+  typedef DOTGraphTraits<GraphType>           DOTTraits;
+  typedef GraphTraits<GraphType>              GTraits;
+  typedef typename GTraits::NodeType          NodeType;
+  typedef typename GTraits::nodes_iterator    node_iterator;
+  typedef typename GTraits::ChildIteratorType child_iterator;
+  DOTTraits DTraits;
+
+  // Writes the edge labels of the node to O and returns true if there are any
+  // edge labels not equal to the empty string "".
+  bool getEdgeSourceLabels(raw_ostream &O, NodeType *Node) {
+    child_iterator EI = GTraits::child_begin(Node);
+    child_iterator EE = GTraits::child_end(Node);
+    bool hasEdgeSourceLabels = false;
+
+    for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
+      std::string label = DTraits.getEdgeSourceLabel(Node, EI);
+
+      if (label.empty())
+        continue;
+
+      hasEdgeSourceLabels = true;
+
+      if (i)
+        O << "|";
+
+      O << "<s" << i << ">" << DOT::EscapeString(label);
+    }
+
+    if (EI != EE && hasEdgeSourceLabels)
+      O << "|<s64>truncated...";
+
+    return hasEdgeSourceLabels;
+  }
+
+public:
+  GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
+    DTraits = DOTTraits(SN);
+  }
+
+  void writeGraph(const std::string &Title = "") {
+    // Output the header for the graph...
+    writeHeader(Title);
+
+    // Emit all of the nodes in the graph...
+    writeNodes();
+
+    // Output any customizations on the graph
+    DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, *this);
+
+    // Output the end of the graph
+    writeFooter();
+  }
+
+  void writeHeader(const std::string &Title) {
+    std::string GraphName = DTraits.getGraphName(G);
+
+    if (!Title.empty())
+      O << "digraph \"" << DOT::EscapeString(Title) << "\" {\n";
+    else if (!GraphName.empty())
+      O << "digraph \"" << DOT::EscapeString(GraphName) << "\" {\n";
+    else
+      O << "digraph unnamed {\n";
+
+    if (DTraits.renderGraphFromBottomUp())
+      O << "\trankdir=\"BT\";\n";
+
+    if (!Title.empty())
+      O << "\tlabel=\"" << DOT::EscapeString(Title) << "\";\n";
+    else if (!GraphName.empty())
+      O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
+    O << DTraits.getGraphProperties(G);
+    O << "\n";
+  }
+
+  void writeFooter() {
+    // Finish off the graph
+    O << "}\n";
+  }
+
+  void writeNodes() {
+    // Loop over the graph, printing it out...
+    for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
+         I != E; ++I)
+      if (!isNodeHidden(*I))
+        writeNode(*I);
+  }
+
+  bool isNodeHidden(NodeType &Node) {
+    return isNodeHidden(&Node);
+  }
+
+  bool isNodeHidden(NodeType *const *Node) {
+    return isNodeHidden(*Node);
+  }
+
+  bool isNodeHidden(NodeType *Node) {
+    return DTraits.isNodeHidden(Node);
+  }
+
+  void writeNode(NodeType& Node) {
+    writeNode(&Node);
+  }
+
+  void writeNode(NodeType *const *Node) {
+    writeNode(*Node);
+  }
+
+  void writeNode(NodeType *Node) {
+    std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
+
+    O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,";
+    if (!NodeAttributes.empty()) O << NodeAttributes << ",";
+    O << "label=\"{";
+
+    if (!DTraits.renderGraphFromBottomUp()) {
+      O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
+
+      // If we should include the address of the node in the label, do so now.
+      if (DTraits.hasNodeAddressLabel(Node, G))
+        O << "|" << static_cast<const void*>(Node);
+
+      std::string NodeDesc = DTraits.getNodeDescription(Node, G);
+      if (!NodeDesc.empty())
+        O << "|" << DOT::EscapeString(NodeDesc);
+    }
+
+    std::string edgeSourceLabels;
+    raw_string_ostream EdgeSourceLabels(edgeSourceLabels);
+    bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
+
+    if (hasEdgeSourceLabels) {
+      if (!DTraits.renderGraphFromBottomUp()) O << "|";
+
+      O << "{" << EdgeSourceLabels.str() << "}";
+
+      if (DTraits.renderGraphFromBottomUp()) O << "|";
+    }
+
+    if (DTraits.renderGraphFromBottomUp()) {
+      O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
+
+      // If we should include the address of the node in the label, do so now.
+      if (DTraits.hasNodeAddressLabel(Node, G))
+        O << "|" << static_cast<const void*>(Node);
+
+      std::string NodeDesc = DTraits.getNodeDescription(Node, G);
+      if (!NodeDesc.empty())
+        O << "|" << DOT::EscapeString(NodeDesc);
+    }
+
+    if (DTraits.hasEdgeDestLabels()) {
+      O << "|{";
+
+      unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
+      for (; i != e && i != 64; ++i) {
+        if (i) O << "|";
+        O << "<d" << i << ">"
+          << DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i));
+      }
+
+      if (i != e)
+        O << "|<d64>truncated...";
+      O << "}";
+    }
+
+    O << "}\"];\n";   // Finish printing the "node" line
+
+    // Output all of the edges now
+    child_iterator EI = GTraits::child_begin(Node);
+    child_iterator EE = GTraits::child_end(Node);
+    for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
+      if (!DTraits.isNodeHidden(*EI))
+        writeEdge(Node, i, EI);
+    for (; EI != EE; ++EI)
+      if (!DTraits.isNodeHidden(*EI))
+        writeEdge(Node, 64, EI);
+  }
+
+  void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
+    if (NodeType *TargetNode = *EI) {
+      int DestPort = -1;
+      if (DTraits.edgeTargetsEdgeSource(Node, EI)) {
+        child_iterator TargetIt = DTraits.getEdgeTarget(Node, EI);
+
+        // Figure out which edge this targets...
+        unsigned Offset =
+          (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
+        DestPort = static_cast<int>(Offset);
+      }
+
+      if (DTraits.getEdgeSourceLabel(Node, EI).empty())
+        edgeidx = -1;
+
+      emitEdge(static_cast<const void*>(Node), edgeidx,
+               static_cast<const void*>(TargetNode), DestPort,
+               DTraits.getEdgeAttributes(Node, EI, G));
+    }
+  }
+
+  /// emitSimpleNode - Outputs a simple (non-record) node
+  void emitSimpleNode(const void *ID, const std::string &Attr,
+                   const std::string &Label, unsigned NumEdgeSources = 0,
+                   const std::vector<std::string> *EdgeSourceLabels = nullptr) {
+    O << "\tNode" << ID << "[ ";
+    if (!Attr.empty())
+      O << Attr << ",";
+    O << " label =\"";
+    if (NumEdgeSources) O << "{";
+    O << DOT::EscapeString(Label);
+    if (NumEdgeSources) {
+      O << "|{";
+
+      for (unsigned i = 0; i != NumEdgeSources; ++i) {
+        if (i) O << "|";
+        O << "<s" << i << ">";
+        if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]);
+      }
+      O << "}}";
+    }
+    O << "\"];\n";
+  }
+
+  /// emitEdge - Output an edge from a simple node into the graph...
+  void emitEdge(const void *SrcNodeID, int SrcNodePort,
+                const void *DestNodeID, int DestNodePort,
+                const std::string &Attrs) {
+    if (SrcNodePort  > 64) return;             // Eminating from truncated part?
+    if (DestNodePort > 64) DestNodePort = 64;  // Targeting the truncated part?
+
+    O << "\tNode" << SrcNodeID;
+    if (SrcNodePort >= 0)
+      O << ":s" << SrcNodePort;
+    O << " -> Node" << DestNodeID;
+    if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels())
+      O << ":d" << DestNodePort;
+
+    if (!Attrs.empty())
+      O << "[" << Attrs << "]";
+    O << ";\n";
+  }
+
+  /// getOStream - Get the raw output stream into the graph file. Useful to
+  /// write fancy things using addCustomGraphFeatures().
+  raw_ostream &getOStream() {
+    return O;
+  }
+};
+
+template<typename GraphType>
+raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
+                        bool ShortNames = false,
+                        const Twine &Title = "") {
+  // Start the graph emission process...
+  GraphWriter<GraphType> W(O, G, ShortNames);
+
+  // Emit the graph.
+  W.writeGraph(Title.str());
+
+  return O;
+}
+
+std::string createGraphFilename(const Twine &Name, int &FD);
+
+template <typename GraphType>
+std::string WriteGraph(const GraphType &G, const Twine &Name,
+                       bool ShortNames = false, const Twine &Title = "") {
+  int FD;
+  // Windows can't always handle long paths, so limit the length of the name.
+  std::string N = Name.str();
+  N = N.substr(0, std::min<std::size_t>(N.size(), 140));
+  std::string Filename = createGraphFilename(N, FD);
+  raw_fd_ostream O(FD, /*shouldClose=*/ true);
+
+  if (FD == -1) {
+    errs() << "error opening file '" << Filename << "' for writing!\n";
+    return "";
+  }
+
+  llvm::WriteGraph(O, G, ShortNames, Title);
+  errs() << " done. \n";
+
+  return Filename;
+}
+
+/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
+/// then cleanup.  For use from the debugger.
+///
+template<typename GraphType>
+void ViewGraph(const GraphType &G, const Twine &Name,
+               bool ShortNames = false, const Twine &Title = "",
+               GraphProgram::Name Program = GraphProgram::DOT) {
+  std::string Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
+
+  if (Filename.empty())
+    return;
+
+  DisplayGraph(Filename, true, Program);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
new file mode 100644
index 0000000..8f4bf3c
--- /dev/null
+++ b/include/llvm/Support/Host.h
@@ -0,0 +1,74 @@
+//===- llvm/Support/Host.h - Host machine characteristics --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for querying the nature of the host machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_HOST_H
+#define LLVM_SUPPORT_HOST_H
+
+#include "llvm/ADT/StringMap.h"
+
+#if defined(__linux__) || defined(__GNU__)
+#include <endian.h>
+#else
+#if !defined(BYTE_ORDER) && !defined(LLVM_ON_WIN32)
+#include <machine/endian.h>
+#endif
+#endif
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+  static const bool IsBigEndianHost = true;
+#else
+  static const bool IsBigEndianHost = false;
+#endif
+
+  static const bool IsLittleEndianHost = !IsBigEndianHost;
+
+  /// getDefaultTargetTriple() - Return the default target triple the compiler
+  /// has been configured to produce code for.
+  ///
+  /// The target triple is a string in the format of:
+  ///   CPU_TYPE-VENDOR-OPERATING_SYSTEM
+  /// or
+  ///   CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
+  std::string getDefaultTargetTriple();
+
+  /// getProcessTriple() - Return an appropriate target triple for generating
+  /// code to be loaded into the current process, e.g. when using the JIT.
+  std::string getProcessTriple();
+
+  /// getHostCPUName - Get the LLVM name for the host CPU. The particular format
+  /// of the name is target dependent, and suitable for passing as -mcpu to the
+  /// target which matches the host.
+  ///
+  /// \return - The host CPU name, or empty if the CPU could not be determined.
+  StringRef getHostCPUName();
+
+  /// getHostCPUFeatures - Get the LLVM names for the host CPU features.
+  /// The particular format of the names are target dependent, and suitable for
+  /// passing as -mattr to the target which matches the host.
+  ///
+  /// \param Features - A string mapping feature names to either
+  /// true (if enabled) or false (if disabled). This routine makes no guarantees
+  /// about exactly which features may appear in this map, except that they are
+  /// all valid LLVM feature names.
+  ///
+  /// \return - True on success.
+  bool getHostCPUFeatures(StringMap<bool> &Features);
+}
+}
+
+#endif
diff --git a/include/llvm/Support/IncludeFile.h b/include/llvm/Support/IncludeFile.h
new file mode 100644
index 0000000..2067e34
--- /dev/null
+++ b/include/llvm/Support/IncludeFile.h
@@ -0,0 +1,79 @@
+//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- 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 FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
+// macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INCLUDEFILE_H
+#define LLVM_SUPPORT_INCLUDEFILE_H
+
+/// This macro is the public interface that IncludeFile.h exports. This gives
+/// us the option to implement the "link the definition" capability in any
+/// manner that we choose. All header files that depend on a specific .cpp
+/// file being linked at run time should use this macro instead of the
+/// IncludeFile class directly.
+///
+/// For example, foo.h would use:<br/>
+/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
+///
+/// And, foo.cp would use:<br/>
+/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
+#ifdef __GNUC__
+// If the `used' attribute is available, use it to create a variable
+// with an initializer that will force the linking of the defining file.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+  namespace llvm { \
+    extern const char name ## LinkVar; \
+    __attribute__((used)) static const char *const name ## LinkObj = \
+      &name ## LinkVar; \
+  }
+#else
+// Otherwise use a constructor call.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+  namespace llvm { \
+    extern const char name ## LinkVar; \
+    static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
+  }
+#endif
+
+/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
+/// be used in a .cpp file to define the name referenced in a header file that
+/// will cause linkage of the .cpp file. It should only be used at extern level.
+#define DEFINING_FILE_FOR(name) \
+  namespace llvm { const char name ## LinkVar = 0; }
+
+namespace llvm {
+
+/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header.  This is solely
+/// to overcome problems linking .a files and not getting the implementation
+/// of compilation units we need. This is commonly an issue with the various
+/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
+/// they link faster and provide the smallest executables. However, sometimes
+/// those executables are too small, if the program doesn't reference something
+/// that might be needed, especially by a loaded share object. This little class
+/// helps to resolve that problem. The basic strategy is to use this class in
+/// a header file and pass the address of a variable to the constructor. If the
+/// variable is defined in the header file's corresponding .cpp file then all
+/// tools/libraries that \#include the header file will require the .cpp as
+/// well.
+/// For example:<br/>
+/// <tt>extern int LinkMyCodeStub;</tt><br/>
+/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
+/// @brief Class to ensure linking of corresponding object file.
+struct IncludeFile {
+  explicit IncludeFile(const void *);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
new file mode 100644
index 0000000..ea76c9b
--- /dev/null
+++ b/include/llvm/Support/LEB128.h
@@ -0,0 +1,101 @@
+//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- 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 some utility functions for encoding SLEB128 and
+// ULEB128 values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LEB128_H
+#define LLVM_SUPPORT_LEB128_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// Utility function to encode a SLEB128 value to an output stream.
+inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
+  bool More;
+  do {
+    uint8_t Byte = Value & 0x7f;
+    // NOTE: this assumes that this signed shift is an arithmetic right shift.
+    Value >>= 7;
+    More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
+              ((Value == -1) && ((Byte & 0x40) != 0))));
+    if (More)
+      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
+    OS << char(Byte);
+  } while (More);
+}
+
+/// Utility function to encode a ULEB128 value to an output stream.
+inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
+                          unsigned Padding = 0) {
+  do {
+    uint8_t Byte = Value & 0x7f;
+    Value >>= 7;
+    if (Value != 0 || Padding != 0)
+      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
+    OS << char(Byte);
+  } while (Value != 0);
+
+  // Pad with 0x80 and emit a null byte at the end.
+  if (Padding != 0) {
+    for (; Padding != 1; --Padding)
+      OS << '\x80';
+    OS << '\x00';
+  }
+}
+
+/// Utility function to encode a ULEB128 value to a buffer. Returns
+/// the length in bytes of the encoded value.
+inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
+                              unsigned Padding = 0) {
+  uint8_t *orig_p = p;
+  do {
+    uint8_t Byte = Value & 0x7f;
+    Value >>= 7;
+    if (Value != 0 || Padding != 0)
+      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
+    *p++ = Byte;
+  } while (Value != 0);
+
+  // Pad with 0x80 and emit a null byte at the end.
+  if (Padding != 0) {
+    for (; Padding != 1; --Padding)
+      *p++ = '\x80';
+    *p++ = '\x00';
+  }
+  return (unsigned)(p - orig_p);
+}
+
+
+/// Utility function to decode a ULEB128 value.
+inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) {
+  const uint8_t *orig_p = p;
+  uint64_t Value = 0;
+  unsigned Shift = 0;
+  do {
+    Value += (*p & 0x7f) << Shift;
+    Shift += 7;
+  } while (*p++ >= 128);
+  if (n)
+    *n = (unsigned)(p - orig_p);
+  return Value;
+}
+
+/// Utility function to get the size of the ULEB128-encoded value.
+extern unsigned getULEB128Size(uint64_t Value);
+
+/// Utility function to get the size of the SLEB128-encoded value.
+extern unsigned getSLEB128Size(int64_t Value);
+
+}  // namespace llvm
+
+#endif  // LLVM_SYSTEM_LEB128_H
diff --git a/include/llvm/Support/LICENSE.TXT b/include/llvm/Support/LICENSE.TXT
new file mode 100644
index 0000000..3479b3f
--- /dev/null
+++ b/include/llvm/Support/LICENSE.TXT
@@ -0,0 +1,6 @@
+LLVM System Interface Library
+-------------------------------------------------------------------------------
+The LLVM System Interface Library is licensed under the Illinois Open Source
+License and has the following additional copyright:
+
+Copyright (C) 2004 eXtensible Systems, Inc.
diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h
new file mode 100644
index 0000000..2a58262
--- /dev/null
+++ b/include/llvm/Support/LineIterator.h
@@ -0,0 +1,85 @@
+//===- LineIterator.h - Iterator to read a text buffer's lines --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LINEITERATOR_H__
+#define LLVM_SUPPORT_LINEITERATOR_H__
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include <iterator>
+
+namespace llvm {
+
+class MemoryBuffer;
+
+/// \brief A forward iterator which reads non-blank text lines from a buffer.
+///
+/// This class provides a forward iterator interface for reading one line at
+/// a time from a buffer. When default constructed the iterator will be the
+/// "end" iterator.
+///
+/// The iterator also is aware of what line number it is currently processing
+/// and can strip comment lines given the comment-starting character.
+///
+/// Note that this iterator requires the buffer to be nul terminated.
+class line_iterator
+    : public std::iterator<std::forward_iterator_tag, StringRef> {
+  const MemoryBuffer *Buffer;
+  char CommentMarker;
+
+  unsigned LineNumber;
+  StringRef CurrentLine;
+
+public:
+  /// \brief Default construct an "end" iterator.
+  line_iterator() : Buffer(nullptr) {}
+
+  /// \brief Construct a new iterator around some memory buffer.
+  explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
+
+  /// \brief Return true if we've reached EOF or are an "end" iterator.
+  bool is_at_eof() const { return !Buffer; }
+
+  /// \brief Return true if we're an "end" iterator or have reached EOF.
+  bool is_at_end() const { return is_at_eof(); }
+
+  /// \brief Return the current line number. May return any number at EOF.
+  int64_t line_number() const { return LineNumber; }
+
+  /// \brief Advance to the next (non-empty, non-comment) line.
+  line_iterator &operator++() {
+    advance();
+    return *this;
+  }
+  line_iterator operator++(int) {
+    line_iterator tmp(*this);
+    advance();
+    return tmp;
+  }
+
+  /// \brief Get the current line as a \c StringRef.
+  StringRef operator*() const { return CurrentLine; }
+  const StringRef *operator->() const { return &CurrentLine; }
+
+  friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
+    return LHS.Buffer == RHS.Buffer &&
+           LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
+  }
+
+  friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
+    return !(LHS == RHS);
+  }
+
+private:
+  /// \brief Advance the iterator to the next line.
+  void advance();
+};
+}
+
+#endif // LLVM_SUPPORT_LINEITERATOR_H__
diff --git a/include/llvm/Support/Locale.h b/include/llvm/Support/Locale.h
new file mode 100644
index 0000000..b384d58
--- /dev/null
+++ b/include/llvm/Support/Locale.h
@@ -0,0 +1,17 @@
+#ifndef LLVM_SUPPORT_LOCALE_H
+#define LLVM_SUPPORT_LOCALE_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace sys {
+namespace locale {
+
+int columnWidth(StringRef s);
+bool isPrint(int c);
+
+}
+}
+}
+
+#endif // LLVM_SUPPORT_LOCALE_H
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
new file mode 100644
index 0000000..61c65da
--- /dev/null
+++ b/include/llvm/Support/LockFileManager.h
@@ -0,0 +1,84 @@
+//===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
+#define LLVM_SUPPORT_LOCKFILEMANAGER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include <system_error>
+#include <utility> // for std::pair
+
+namespace llvm {
+/// \brief Class that manages the creation of a lock file to aid
+/// implicit coordination between different processes.
+///
+/// The implicit coordination works by creating a ".lock" file alongside
+/// the file that we're coordinating for, using the atomicity of the file
+/// system to ensure that only a single process can create that ".lock" file.
+/// When the lock file is removed, the owning process has finished the
+/// operation.
+class LockFileManager {
+public:
+  /// \brief Describes the state of a lock file.
+  enum LockFileState {
+    /// \brief The lock file has been created and is owned by this instance
+    /// of the object.
+    LFS_Owned,
+    /// \brief The lock file already exists and is owned by some other
+    /// instance.
+    LFS_Shared,
+    /// \brief An error occurred while trying to create or find the lock
+    /// file.
+    LFS_Error
+  };
+
+  /// \brief Describes the result of waiting for the owner to release the lock.
+  enum WaitForUnlockResult {
+    /// \brief The lock was released successfully.
+    Res_Success,
+    /// \brief Owner died while holding the lock.
+    Res_OwnerDied,
+    /// \brief Reached timeout while waiting for the owner to release the lock.
+    Res_Timeout
+  };
+
+private:
+  SmallString<128> FileName;
+  SmallString<128> LockFileName;
+  SmallString<128> UniqueLockFileName;
+
+  Optional<std::pair<std::string, int> > Owner;
+  Optional<std::error_code> Error;
+
+  LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
+  LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
+
+  static Optional<std::pair<std::string, int> >
+  readLockFile(StringRef LockFileName);
+
+  static bool processStillExecuting(StringRef Hostname, int PID);
+
+public:
+
+  LockFileManager(StringRef FileName);
+  ~LockFileManager();
+
+  /// \brief Determine the state of the lock file.
+  LockFileState getState() const;
+
+  operator LockFileState() const { return getState(); }
+
+  /// \brief For a shared lock, wait until the owner releases the lock.
+  WaitForUnlockResult waitForUnlock();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h
new file mode 100644
index 0000000..4eb8507
--- /dev/null
+++ b/include/llvm/Support/MD5.h
@@ -0,0 +1,70 @@
+/*
+ * This code is derived from (original license follows):
+ *
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See md5.c for more information.
+ */
+
+#ifndef LLVM_SYSTEM_MD5_H
+#define LLVM_SYSTEM_MD5_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MD5 {
+  // Any 32-bit or wider unsigned integer data type will do.
+  typedef uint32_t MD5_u32plus;
+
+  MD5_u32plus a, b, c, d;
+  MD5_u32plus hi, lo;
+  uint8_t buffer[64];
+  MD5_u32plus block[16];
+
+public:
+  typedef uint8_t MD5Result[16];
+
+  MD5();
+
+  /// \brief Updates the hash for the byte stream provided.
+  void update(ArrayRef<uint8_t> Data);
+
+  /// \brief Updates the hash for the StringRef provided.
+  void update(StringRef Str);
+
+  /// \brief Finishes off the hash and puts the result in result.
+  void final(MD5Result &result);
+
+  /// \brief Translates the bytes in \p Res to a hex string that is
+  /// deposited into \p Str. The result will be of length 32.
+  static void stringifyResult(MD5Result &Res, SmallString<32> &Str);
+
+private:
+  const uint8_t *body(ArrayRef<uint8_t> Data);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
new file mode 100644
index 0000000..90df1f4
--- /dev/null
+++ b/include/llvm/Support/MachO.h
@@ -0,0 +1,1322 @@
+//===-- llvm/Support/MachO.h - The MachO file format ------------*- 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 manifest constants for the MachO object file format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MACHO_H
+#define LLVM_SUPPORT_MACHO_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
+
+namespace llvm {
+  namespace MachO {
+    // Enums from <mach-o/loader.h>
+    enum : uint32_t {
+      // Constants for the "magic" field in llvm::MachO::mach_header and
+      // llvm::MachO::mach_header_64
+      MH_MAGIC    = 0xFEEDFACEu,
+      MH_CIGAM    = 0xCEFAEDFEu,
+      MH_MAGIC_64 = 0xFEEDFACFu,
+      MH_CIGAM_64 = 0xCFFAEDFEu,
+      FAT_MAGIC   = 0xCAFEBABEu,
+      FAT_CIGAM   = 0xBEBAFECAu
+    };
+
+    enum HeaderFileType {
+      // Constants for the "filetype" field in llvm::MachO::mach_header and
+      // llvm::MachO::mach_header_64
+      MH_OBJECT      = 0x1u,
+      MH_EXECUTE     = 0x2u,
+      MH_FVMLIB      = 0x3u,
+      MH_CORE        = 0x4u,
+      MH_PRELOAD     = 0x5u,
+      MH_DYLIB       = 0x6u,
+      MH_DYLINKER    = 0x7u,
+      MH_BUNDLE      = 0x8u,
+      MH_DYLIB_STUB  = 0x9u,
+      MH_DSYM        = 0xAu,
+      MH_KEXT_BUNDLE = 0xBu
+    };
+
+    enum {
+      // Constant bits for the "flags" field in llvm::MachO::mach_header and
+      // llvm::MachO::mach_header_64
+      MH_NOUNDEFS                = 0x00000001u,
+      MH_INCRLINK                = 0x00000002u,
+      MH_DYLDLINK                = 0x00000004u,
+      MH_BINDATLOAD              = 0x00000008u,
+      MH_PREBOUND                = 0x00000010u,
+      MH_SPLIT_SEGS              = 0x00000020u,
+      MH_LAZY_INIT               = 0x00000040u,
+      MH_TWOLEVEL                = 0x00000080u,
+      MH_FORCE_FLAT              = 0x00000100u,
+      MH_NOMULTIDEFS             = 0x00000200u,
+      MH_NOFIXPREBINDING         = 0x00000400u,
+      MH_PREBINDABLE             = 0x00000800u,
+      MH_ALLMODSBOUND            = 0x00001000u,
+      MH_SUBSECTIONS_VIA_SYMBOLS = 0x00002000u,
+      MH_CANONICAL               = 0x00004000u,
+      MH_WEAK_DEFINES            = 0x00008000u,
+      MH_BINDS_TO_WEAK           = 0x00010000u,
+      MH_ALLOW_STACK_EXECUTION   = 0x00020000u,
+      MH_ROOT_SAFE               = 0x00040000u,
+      MH_SETUID_SAFE             = 0x00080000u,
+      MH_NO_REEXPORTED_DYLIBS    = 0x00100000u,
+      MH_PIE                     = 0x00200000u,
+      MH_DEAD_STRIPPABLE_DYLIB   = 0x00400000u
+    };
+
+    enum : uint32_t {
+      // Flags for the "cmd" field in llvm::MachO::load_command
+      LC_REQ_DYLD    = 0x80000000u
+    };
+
+    enum LoadCommandType : uint32_t {
+      // Constants for the "cmd" field in llvm::MachO::load_command
+      LC_SEGMENT              = 0x00000001u,
+      LC_SYMTAB               = 0x00000002u,
+      LC_SYMSEG               = 0x00000003u,
+      LC_THREAD               = 0x00000004u,
+      LC_UNIXTHREAD           = 0x00000005u,
+      LC_LOADFVMLIB           = 0x00000006u,
+      LC_IDFVMLIB             = 0x00000007u,
+      LC_IDENT                = 0x00000008u,
+      LC_FVMFILE              = 0x00000009u,
+      LC_PREPAGE              = 0x0000000Au,
+      LC_DYSYMTAB             = 0x0000000Bu,
+      LC_LOAD_DYLIB           = 0x0000000Cu,
+      LC_ID_DYLIB             = 0x0000000Du,
+      LC_LOAD_DYLINKER        = 0x0000000Eu,
+      LC_ID_DYLINKER          = 0x0000000Fu,
+      LC_PREBOUND_DYLIB       = 0x00000010u,
+      LC_ROUTINES             = 0x00000011u,
+      LC_SUB_FRAMEWORK        = 0x00000012u,
+      LC_SUB_UMBRELLA         = 0x00000013u,
+      LC_SUB_CLIENT           = 0x00000014u,
+      LC_SUB_LIBRARY          = 0x00000015u,
+      LC_TWOLEVEL_HINTS       = 0x00000016u,
+      LC_PREBIND_CKSUM        = 0x00000017u,
+      LC_LOAD_WEAK_DYLIB      = 0x80000018u,
+      LC_SEGMENT_64           = 0x00000019u,
+      LC_ROUTINES_64          = 0x0000001Au,
+      LC_UUID                 = 0x0000001Bu,
+      LC_RPATH                = 0x8000001Cu,
+      LC_CODE_SIGNATURE       = 0x0000001Du,
+      LC_SEGMENT_SPLIT_INFO   = 0x0000001Eu,
+      LC_REEXPORT_DYLIB       = 0x8000001Fu,
+      LC_LAZY_LOAD_DYLIB      = 0x00000020u,
+      LC_ENCRYPTION_INFO      = 0x00000021u,
+      LC_DYLD_INFO            = 0x00000022u,
+      LC_DYLD_INFO_ONLY       = 0x80000022u,
+      LC_LOAD_UPWARD_DYLIB    = 0x80000023u,
+      LC_VERSION_MIN_MACOSX   = 0x00000024u,
+      LC_VERSION_MIN_IPHONEOS = 0x00000025u,
+      LC_FUNCTION_STARTS      = 0x00000026u,
+      LC_DYLD_ENVIRONMENT     = 0x00000027u,
+      LC_MAIN                 = 0x80000028u,
+      LC_DATA_IN_CODE         = 0x00000029u,
+      LC_SOURCE_VERSION       = 0x0000002Au,
+      LC_DYLIB_CODE_SIGN_DRS  = 0x0000002Bu,
+      //                        0x0000002Cu,
+      LC_LINKER_OPTIONS       = 0x0000002Du,
+      LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
+    };
+
+    enum : uint32_t {
+      // Constant bits for the "flags" field in llvm::MachO::segment_command
+      SG_HIGHVM              = 0x1u,
+      SG_FVMLIB              = 0x2u,
+      SG_NORELOC             = 0x4u,
+      SG_PROTECTED_VERSION_1 = 0x8u,
+
+
+      // Constant masks for the "flags" field in llvm::MachO::section and
+      // llvm::MachO::section_64
+      SECTION_TYPE           = 0x000000ffu, // SECTION_TYPE
+      SECTION_ATTRIBUTES     = 0xffffff00u, // SECTION_ATTRIBUTES
+      SECTION_ATTRIBUTES_USR = 0xff000000u, // SECTION_ATTRIBUTES_USR
+      SECTION_ATTRIBUTES_SYS = 0x00ffff00u  // SECTION_ATTRIBUTES_SYS
+    };
+
+    /// These are the section type and attributes fields.  A MachO section can
+    /// have only one Type, but can have any of the attributes specified.
+    enum SectionType : uint32_t {
+      // Constant masks for the "flags[7:0]" field in llvm::MachO::section and
+      // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
+
+      /// S_REGULAR - Regular section.
+      S_REGULAR                             = 0x00u,
+      /// S_ZEROFILL - Zero fill on demand section.
+      S_ZEROFILL                            = 0x01u,
+      /// S_CSTRING_LITERALS - Section with literal C strings.
+      S_CSTRING_LITERALS                    = 0x02u,
+      /// S_4BYTE_LITERALS - Section with 4 byte literals.
+      S_4BYTE_LITERALS                      = 0x03u,
+      /// S_8BYTE_LITERALS - Section with 8 byte literals.
+      S_8BYTE_LITERALS                      = 0x04u,
+      /// S_LITERAL_POINTERS - Section with pointers to literals.
+      S_LITERAL_POINTERS                    = 0x05u,
+      /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
+      S_NON_LAZY_SYMBOL_POINTERS            = 0x06u,
+      /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
+      S_LAZY_SYMBOL_POINTERS                = 0x07u,
+      /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
+      /// the Reserved2 field.
+      S_SYMBOL_STUBS                        = 0x08u,
+      /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
+      /// initialization.
+      S_MOD_INIT_FUNC_POINTERS              = 0x09u,
+      /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
+      /// termination.
+      S_MOD_TERM_FUNC_POINTERS              = 0x0au,
+      /// S_COALESCED - Section contains symbols that are to be coalesced.
+      S_COALESCED                           = 0x0bu,
+      /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
+      /// gigabytes).
+      S_GB_ZEROFILL                         = 0x0cu,
+      /// S_INTERPOSING - Section with only pairs of function pointers for
+      /// interposing.
+      S_INTERPOSING                         = 0x0du,
+      /// S_16BYTE_LITERALS - Section with only 16 byte literals.
+      S_16BYTE_LITERALS                     = 0x0eu,
+      /// S_DTRACE_DOF - Section contains DTrace Object Format.
+      S_DTRACE_DOF                          = 0x0fu,
+      /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
+      /// lazy loaded dylibs.
+      S_LAZY_DYLIB_SYMBOL_POINTERS          = 0x10u,
+      /// S_THREAD_LOCAL_REGULAR - Thread local data section.
+      S_THREAD_LOCAL_REGULAR                = 0x11u,
+      /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
+      S_THREAD_LOCAL_ZEROFILL               = 0x12u,
+      /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable
+      /// structure data.
+      S_THREAD_LOCAL_VARIABLES              = 0x13u,
+      /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread
+      /// local structures.
+      S_THREAD_LOCAL_VARIABLE_POINTERS      = 0x14u,
+      /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
+      /// variable initialization pointers to functions.
+      S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
+
+      LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
+    };
+
+    enum : uint32_t {
+      // Constant masks for the "flags[31:24]" field in llvm::MachO::section and
+      // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
+
+      /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
+      /// instructions.
+      S_ATTR_PURE_INSTRUCTIONS   = 0x80000000u,
+      /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
+      /// in a ranlib table of contents.
+      S_ATTR_NO_TOC              = 0x40000000u,
+      /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
+      /// in files with the MY_DYLDLINK flag.
+      S_ATTR_STRIP_STATIC_SYMS   = 0x20000000u,
+      /// S_ATTR_NO_DEAD_STRIP - No dead stripping.
+      S_ATTR_NO_DEAD_STRIP       = 0x10000000u,
+      /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
+      S_ATTR_LIVE_SUPPORT        = 0x08000000u,
+      /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
+      /// dyld.
+      S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
+      /// S_ATTR_DEBUG - A debug section.
+      S_ATTR_DEBUG               = 0x02000000u,
+
+      // Constant masks for the "flags[23:8]" field in llvm::MachO::section and
+      // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
+
+      /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
+      S_ATTR_SOME_INSTRUCTIONS   = 0x00000400u,
+      /// S_ATTR_EXT_RELOC - Section has external relocation entries.
+      S_ATTR_EXT_RELOC           = 0x00000200u,
+      /// S_ATTR_LOC_RELOC - Section has local relocation entries.
+      S_ATTR_LOC_RELOC           = 0x00000100u,
+
+      // Constant masks for the value of an indirect symbol in an indirect
+      // symbol table
+      INDIRECT_SYMBOL_LOCAL = 0x80000000u,
+      INDIRECT_SYMBOL_ABS   = 0x40000000u
+    };
+
+    enum DataRegionType {
+      // Constants for the "kind" field in a data_in_code_entry structure
+      DICE_KIND_DATA             = 1u,
+      DICE_KIND_JUMP_TABLE8      = 2u,
+      DICE_KIND_JUMP_TABLE16     = 3u,
+      DICE_KIND_JUMP_TABLE32     = 4u,
+      DICE_KIND_ABS_JUMP_TABLE32 = 5u
+    };
+
+    enum RebaseType {
+      REBASE_TYPE_POINTER         = 1u,
+      REBASE_TYPE_TEXT_ABSOLUTE32 = 2u,
+      REBASE_TYPE_TEXT_PCREL32    = 3u
+    };
+
+    enum {
+      REBASE_OPCODE_MASK    = 0xF0u,
+      REBASE_IMMEDIATE_MASK = 0x0Fu
+    };
+
+    enum RebaseOpcode {
+      REBASE_OPCODE_DONE                               = 0x00u,
+      REBASE_OPCODE_SET_TYPE_IMM                       = 0x10u,
+      REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB        = 0x20u,
+      REBASE_OPCODE_ADD_ADDR_ULEB                      = 0x30u,
+      REBASE_OPCODE_ADD_ADDR_IMM_SCALED                = 0x40u,
+      REBASE_OPCODE_DO_REBASE_IMM_TIMES                = 0x50u,
+      REBASE_OPCODE_DO_REBASE_ULEB_TIMES               = 0x60u,
+      REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB            = 0x70u,
+      REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
+    };
+
+    enum BindType {
+      BIND_TYPE_POINTER         = 1u,
+      BIND_TYPE_TEXT_ABSOLUTE32 = 2u,
+      BIND_TYPE_TEXT_PCREL32    = 3u
+    };
+
+    enum BindSpecialDylib {
+      BIND_SPECIAL_DYLIB_SELF            =  0,
+      BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
+      BIND_SPECIAL_DYLIB_FLAT_LOOKUP     = -2
+    };
+
+    enum {
+      BIND_SYMBOL_FLAGS_WEAK_IMPORT         = 0x1u,
+      BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION = 0x8u,
+
+      BIND_OPCODE_MASK                      = 0xF0u,
+      BIND_IMMEDIATE_MASK                   = 0x0Fu
+    };
+
+    enum BindOpcode {
+      BIND_OPCODE_DONE                             = 0x00u,
+      BIND_OPCODE_SET_DYLIB_ORDINAL_IMM            = 0x10u,
+      BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB           = 0x20u,
+      BIND_OPCODE_SET_DYLIB_SPECIAL_IMM            = 0x30u,
+      BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM    = 0x40u,
+      BIND_OPCODE_SET_TYPE_IMM                     = 0x50u,
+      BIND_OPCODE_SET_ADDEND_SLEB                  = 0x60u,
+      BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB      = 0x70u,
+      BIND_OPCODE_ADD_ADDR_ULEB                    = 0x80u,
+      BIND_OPCODE_DO_BIND                          = 0x90u,
+      BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB            = 0xA0u,
+      BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED      = 0xB0u,
+      BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u
+    };
+
+    enum {
+      EXPORT_SYMBOL_FLAGS_KIND_MASK           = 0x03u,
+      EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION     = 0x04u,
+      EXPORT_SYMBOL_FLAGS_REEXPORT            = 0x08u,
+      EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER   = 0x10u
+    };
+
+    enum ExportSymbolKind {
+      EXPORT_SYMBOL_FLAGS_KIND_REGULAR        = 0x00u,
+      EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL   = 0x01u
+    };
+
+
+    enum {
+      // Constant masks for the "n_type" field in llvm::MachO::nlist and
+      // llvm::MachO::nlist_64
+      N_STAB = 0xe0,
+      N_PEXT = 0x10,
+      N_TYPE = 0x0e,
+      N_EXT  = 0x01
+    };
+
+    enum NListType {
+      // Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
+      // llvm::MachO::nlist_64
+      N_UNDF = 0x0u,
+      N_ABS  = 0x2u,
+      N_SECT = 0xeu,
+      N_PBUD = 0xcu,
+      N_INDR = 0xau
+    };
+
+    enum SectionOrdinal {
+      // Constants for the "n_sect" field in llvm::MachO::nlist and
+      // llvm::MachO::nlist_64
+      NO_SECT  = 0u,
+      MAX_SECT = 0xffu
+    };
+
+    enum {
+      // Constant masks for the "n_desc" field in llvm::MachO::nlist and
+      // llvm::MachO::nlist_64
+      // The low 3 bits are the for the REFERENCE_TYPE.
+      REFERENCE_TYPE                            = 0x7,
+      REFERENCE_FLAG_UNDEFINED_NON_LAZY         = 0,
+      REFERENCE_FLAG_UNDEFINED_LAZY             = 1,
+      REFERENCE_FLAG_DEFINED                    = 2,
+      REFERENCE_FLAG_PRIVATE_DEFINED            = 3,
+      REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
+      REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY     = 5,
+      // Flag bits (some overlap with the library ordinal bits).
+      N_ARM_THUMB_DEF   = 0x0008u,
+      REFERENCED_DYNAMICALLY = 0x0010u,
+      N_NO_DEAD_STRIP   = 0x0020u,
+      N_WEAK_REF        = 0x0040u,
+      N_WEAK_DEF        = 0x0080u,
+      N_SYMBOL_RESOLVER = 0x0100u,
+      N_ALT_ENTRY       = 0x0200u,
+      // For undefined symbols coming from libraries, see GET_LIBRARY_ORDINAL()
+      // as these are in the top 8 bits.
+      SELF_LIBRARY_ORDINAL   = 0x0,
+      MAX_LIBRARY_ORDINAL    = 0xfd,
+      DYNAMIC_LOOKUP_ORDINAL = 0xfe,
+      EXECUTABLE_ORDINAL     = 0xff 
+    };
+
+    enum StabType {
+      // Constant values for the "n_type" field in llvm::MachO::nlist and
+      // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0"
+      N_GSYM    = 0x20u,
+      N_FNAME   = 0x22u,
+      N_FUN     = 0x24u,
+      N_STSYM   = 0x26u,
+      N_LCSYM   = 0x28u,
+      N_BNSYM   = 0x2Eu,
+      N_PC      = 0x30u,
+      N_AST     = 0x32u,
+      N_OPT     = 0x3Cu,
+      N_RSYM    = 0x40u,
+      N_SLINE   = 0x44u,
+      N_ENSYM   = 0x4Eu,
+      N_SSYM    = 0x60u,
+      N_SO      = 0x64u,
+      N_OSO     = 0x66u,
+      N_LSYM    = 0x80u,
+      N_BINCL   = 0x82u,
+      N_SOL     = 0x84u,
+      N_PARAMS  = 0x86u,
+      N_VERSION = 0x88u,
+      N_OLEVEL  = 0x8Au,
+      N_PSYM    = 0xA0u,
+      N_EINCL   = 0xA2u,
+      N_ENTRY   = 0xA4u,
+      N_LBRAC   = 0xC0u,
+      N_EXCL    = 0xC2u,
+      N_RBRAC   = 0xE0u,
+      N_BCOMM   = 0xE2u,
+      N_ECOMM   = 0xE4u,
+      N_ECOML   = 0xE8u,
+      N_LENG    = 0xFEu
+    };
+
+    enum : uint32_t {
+      // Constant values for the r_symbolnum field in an
+      // llvm::MachO::relocation_info structure when r_extern is 0.
+      R_ABS = 0,
+
+      // Constant bits for the r_address field in an
+      // llvm::MachO::relocation_info structure.
+      R_SCATTERED = 0x80000000
+    };
+
+    enum RelocationInfoType {
+      // Constant values for the r_type field in an
+      // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+      // structure.
+      GENERIC_RELOC_VANILLA        = 0,
+      GENERIC_RELOC_PAIR           = 1,
+      GENERIC_RELOC_SECTDIFF       = 2,
+      GENERIC_RELOC_PB_LA_PTR      = 3,
+      GENERIC_RELOC_LOCAL_SECTDIFF = 4,
+      GENERIC_RELOC_TLV            = 5,
+
+      // Constant values for the r_type field in a PowerPC architecture
+      // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+      // structure.
+      PPC_RELOC_VANILLA            = GENERIC_RELOC_VANILLA,
+      PPC_RELOC_PAIR               = GENERIC_RELOC_PAIR,
+      PPC_RELOC_BR14               = 2,
+      PPC_RELOC_BR24               = 3,
+      PPC_RELOC_HI16               = 4,
+      PPC_RELOC_LO16               = 5,
+      PPC_RELOC_HA16               = 6,
+      PPC_RELOC_LO14               = 7,
+      PPC_RELOC_SECTDIFF           = 8,
+      PPC_RELOC_PB_LA_PTR          = 9,
+      PPC_RELOC_HI16_SECTDIFF      = 10,
+      PPC_RELOC_LO16_SECTDIFF      = 11,
+      PPC_RELOC_HA16_SECTDIFF      = 12,
+      PPC_RELOC_JBSR               = 13,
+      PPC_RELOC_LO14_SECTDIFF      = 14,
+      PPC_RELOC_LOCAL_SECTDIFF     = 15,
+
+      // Constant values for the r_type field in an ARM architecture
+      // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+      // structure.
+      ARM_RELOC_VANILLA            = GENERIC_RELOC_VANILLA,
+      ARM_RELOC_PAIR               = GENERIC_RELOC_PAIR,
+      ARM_RELOC_SECTDIFF           = GENERIC_RELOC_SECTDIFF,
+      ARM_RELOC_LOCAL_SECTDIFF     = 3,
+      ARM_RELOC_PB_LA_PTR          = 4,
+      ARM_RELOC_BR24               = 5,
+      ARM_THUMB_RELOC_BR22         = 6,
+      ARM_THUMB_32BIT_BRANCH       = 7, // obsolete
+      ARM_RELOC_HALF               = 8,
+      ARM_RELOC_HALF_SECTDIFF      = 9,
+
+      // Constant values for the r_type field in an ARM64 architecture
+      // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+      // structure.
+
+      // For pointers.
+      ARM64_RELOC_UNSIGNED            = 0,
+      // Must be followed by an ARM64_RELOC_UNSIGNED
+      ARM64_RELOC_SUBTRACTOR          = 1,
+      // A B/BL instruction with 26-bit displacement.
+      ARM64_RELOC_BRANCH26            = 2,
+      // PC-rel distance to page of target.
+      ARM64_RELOC_PAGE21              = 3,
+      // Offset within page, scaled by r_length.
+      ARM64_RELOC_PAGEOFF12           = 4,
+      // PC-rel distance to page of GOT slot.
+      ARM64_RELOC_GOT_LOAD_PAGE21     = 5,
+      // Offset within page of GOT slot, scaled by r_length.
+      ARM64_RELOC_GOT_LOAD_PAGEOFF12  = 6,
+      // For pointers to GOT slots.
+      ARM64_RELOC_POINTER_TO_GOT      = 7,
+      // PC-rel distance to page of TLVP slot.
+      ARM64_RELOC_TLVP_LOAD_PAGE21    = 8,
+      // Offset within page of TLVP slot, scaled by r_length.
+      ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9,
+      // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12.
+      ARM64_RELOC_ADDEND              = 10,
+
+
+      // Constant values for the r_type field in an x86_64 architecture
+      // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+      // structure
+      X86_64_RELOC_UNSIGNED        = 0,
+      X86_64_RELOC_SIGNED          = 1,
+      X86_64_RELOC_BRANCH          = 2,
+      X86_64_RELOC_GOT_LOAD        = 3,
+      X86_64_RELOC_GOT             = 4,
+      X86_64_RELOC_SUBTRACTOR      = 5,
+      X86_64_RELOC_SIGNED_1        = 6,
+      X86_64_RELOC_SIGNED_2        = 7,
+      X86_64_RELOC_SIGNED_4        = 8,
+      X86_64_RELOC_TLV             = 9
+    };
+
+    // Values for segment_command.initprot.
+    // From <mach/vm_prot.h>
+    enum {
+      VM_PROT_READ    = 0x1,
+      VM_PROT_WRITE   = 0x2,
+      VM_PROT_EXECUTE = 0x4
+    };
+
+
+    // Structs from <mach-o/loader.h>
+
+    struct mach_header {
+      uint32_t magic;
+      uint32_t cputype;
+      uint32_t cpusubtype;
+      uint32_t filetype;
+      uint32_t ncmds;
+      uint32_t sizeofcmds;
+      uint32_t flags;
+    };
+
+    struct mach_header_64 {
+      uint32_t magic;
+      uint32_t cputype;
+      uint32_t cpusubtype;
+      uint32_t filetype;
+      uint32_t ncmds;
+      uint32_t sizeofcmds;
+      uint32_t flags;
+      uint32_t reserved;
+    };
+
+    struct load_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+    };
+
+    struct segment_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      char segname[16];
+      uint32_t vmaddr;
+      uint32_t vmsize;
+      uint32_t fileoff;
+      uint32_t filesize;
+      uint32_t maxprot;
+      uint32_t initprot;
+      uint32_t nsects;
+      uint32_t flags;
+    };
+
+    struct segment_command_64 {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      char segname[16];
+      uint64_t vmaddr;
+      uint64_t vmsize;
+      uint64_t fileoff;
+      uint64_t filesize;
+      uint32_t maxprot;
+      uint32_t initprot;
+      uint32_t nsects;
+      uint32_t flags;
+    };
+
+    struct section {
+      char sectname[16];
+      char segname[16];
+      uint32_t addr;
+      uint32_t size;
+      uint32_t offset;
+      uint32_t align;
+      uint32_t reloff;
+      uint32_t nreloc;
+      uint32_t flags;
+      uint32_t reserved1;
+      uint32_t reserved2;
+    };
+
+    struct section_64 {
+      char sectname[16];
+      char segname[16];
+      uint64_t addr;
+      uint64_t size;
+      uint32_t offset;
+      uint32_t align;
+      uint32_t reloff;
+      uint32_t nreloc;
+      uint32_t flags;
+      uint32_t reserved1;
+      uint32_t reserved2;
+      uint32_t reserved3;
+    };
+
+    struct fvmlib {
+      uint32_t name;
+      uint32_t minor_version;
+      uint32_t header_addr;
+    };
+
+    struct fvmlib_command {
+      uint32_t  cmd;
+      uint32_t cmdsize;
+      struct fvmlib fvmlib;
+    };
+
+    struct dylib {
+      uint32_t name;
+      uint32_t timestamp;
+      uint32_t current_version;
+      uint32_t compatibility_version;
+    };
+
+    struct dylib_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      struct dylib dylib;
+    };
+
+    struct sub_framework_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t umbrella;
+    };
+
+    struct sub_client_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t client;
+    };
+
+    struct sub_umbrella_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t sub_umbrella;
+    };
+
+    struct sub_library_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t sub_library;
+    };
+
+    struct prebound_dylib_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t name;
+      uint32_t nmodules;
+      uint32_t linked_modules;
+    };
+
+    struct dylinker_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t name;
+    };
+
+    struct thread_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+    };
+
+    struct routines_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t init_address;
+      uint32_t init_module;
+      uint32_t reserved1;
+      uint32_t reserved2;
+      uint32_t reserved3;
+      uint32_t reserved4;
+      uint32_t reserved5;
+      uint32_t reserved6;
+    };
+
+    struct routines_command_64 {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint64_t init_address;
+      uint64_t init_module;
+      uint64_t reserved1;
+      uint64_t reserved2;
+      uint64_t reserved3;
+      uint64_t reserved4;
+      uint64_t reserved5;
+      uint64_t reserved6;
+    };
+
+    struct symtab_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t symoff;
+      uint32_t nsyms;
+      uint32_t stroff;
+      uint32_t strsize;
+    };
+
+    struct dysymtab_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t ilocalsym;
+      uint32_t nlocalsym;
+      uint32_t iextdefsym;
+      uint32_t nextdefsym;
+      uint32_t iundefsym;
+      uint32_t nundefsym;
+      uint32_t tocoff;
+      uint32_t ntoc;
+      uint32_t modtaboff;
+      uint32_t nmodtab;
+      uint32_t extrefsymoff;
+      uint32_t nextrefsyms;
+      uint32_t indirectsymoff;
+      uint32_t nindirectsyms;
+      uint32_t extreloff;
+      uint32_t nextrel;
+      uint32_t locreloff;
+      uint32_t nlocrel;
+    };
+
+    struct dylib_table_of_contents {
+      uint32_t symbol_index;
+      uint32_t module_index;
+    };
+
+    struct dylib_module {
+      uint32_t module_name;
+      uint32_t iextdefsym;
+      uint32_t nextdefsym;
+      uint32_t irefsym;
+      uint32_t nrefsym;
+      uint32_t ilocalsym;
+      uint32_t nlocalsym;
+      uint32_t iextrel;
+      uint32_t nextrel;
+      uint32_t iinit_iterm;
+      uint32_t ninit_nterm;
+      uint32_t objc_module_info_addr;
+      uint32_t objc_module_info_size;
+    };
+
+    struct dylib_module_64 {
+      uint32_t module_name;
+      uint32_t iextdefsym;
+      uint32_t nextdefsym;
+      uint32_t irefsym;
+      uint32_t nrefsym;
+      uint32_t ilocalsym;
+      uint32_t nlocalsym;
+      uint32_t iextrel;
+      uint32_t nextrel;
+      uint32_t iinit_iterm;
+      uint32_t ninit_nterm;
+      uint32_t objc_module_info_size;
+      uint64_t objc_module_info_addr;
+    };
+
+    struct dylib_reference {
+      uint32_t isym:24,
+               flags:8;
+    };
+
+
+    struct twolevel_hints_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t offset;
+      uint32_t nhints;
+    };
+
+    struct twolevel_hint {
+      uint32_t isub_image:8,
+               itoc:24;
+    };
+
+    struct prebind_cksum_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t cksum;
+    };
+
+    struct uuid_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint8_t uuid[16];
+    };
+
+    struct rpath_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t path;
+    };
+
+    struct linkedit_data_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t dataoff;
+      uint32_t datasize;
+    };
+
+    struct data_in_code_entry {
+      uint32_t offset;
+      uint16_t length;
+      uint16_t kind;
+    };
+
+    struct source_version_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint64_t version;
+    };
+
+    struct encryption_info_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t cryptoff;
+      uint32_t cryptsize;
+      uint32_t cryptid;
+    };
+
+    struct version_min_command {
+      uint32_t cmd;       // LC_VERSION_MIN_MACOSX or
+                          // LC_VERSION_MIN_IPHONEOS
+      uint32_t cmdsize;   // sizeof(struct version_min_command)
+      uint32_t version;   // X.Y.Z is encoded in nibbles xxxx.yy.zz
+      uint32_t reserved;
+    };
+
+    struct dyld_info_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t rebase_off;
+      uint32_t rebase_size;
+      uint32_t bind_off;
+      uint32_t bind_size;
+      uint32_t weak_bind_off;
+      uint32_t weak_bind_size;
+      uint32_t lazy_bind_off;
+      uint32_t lazy_bind_size;
+      uint32_t export_off;
+      uint32_t export_size;
+    };
+
+    struct linker_options_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t count;
+    };
+
+    struct symseg_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t offset;
+      uint32_t size;
+    };
+
+    struct ident_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+    };
+
+    struct fvmfile_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint32_t name;
+      uint32_t header_addr;
+    };
+
+    struct tlv_descriptor_32 {
+      uint32_t thunk;
+      uint32_t key;
+      uint32_t offset;
+    };
+
+    struct tlv_descriptor_64 {
+      uint64_t thunk;
+      uint64_t key;
+      uint64_t offset;
+    };
+
+    struct tlv_descriptor {
+      uintptr_t thunk;
+      uintptr_t key;
+      uintptr_t offset;
+    };
+
+    struct entry_point_command {
+      uint32_t cmd;
+      uint32_t cmdsize;
+      uint64_t entryoff;
+      uint64_t stacksize;
+    };
+
+
+    // Structs from <mach-o/fat.h>
+    struct fat_header {
+      uint32_t magic;
+      uint32_t nfat_arch;
+    };
+
+    struct fat_arch {
+      uint32_t cputype;
+      uint32_t cpusubtype;
+      uint32_t offset;
+      uint32_t size;
+      uint32_t align;
+    };
+
+    // Structs from <mach-o/reloc.h>
+    struct relocation_info {
+      int32_t r_address;
+      uint32_t r_symbolnum:24,
+               r_pcrel:1,
+               r_length:2,
+               r_extern:1,
+               r_type:4;
+    };
+
+    struct scattered_relocation_info {
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+      uint32_t r_scattered:1,
+               r_pcrel:1,
+               r_length:2,
+               r_type:4,
+               r_address:24;
+#else
+      uint32_t r_address:24,
+               r_type:4,
+               r_length:2,
+               r_pcrel:1,
+               r_scattered:1;
+#endif
+      int32_t r_value;
+    };
+
+    // Structs NOT from <mach-o/reloc.h>, but that make LLVM's life easier
+    struct any_relocation_info {
+      uint32_t r_word0, r_word1;
+    };
+
+    // Structs from <mach-o/nlist.h>
+    struct nlist_base {
+      uint32_t n_strx;
+      uint8_t n_type;
+      uint8_t n_sect;
+      uint16_t n_desc;
+    };
+
+    struct nlist {
+      uint32_t n_strx;
+      uint8_t n_type;
+      uint8_t n_sect;
+      int16_t n_desc;
+      uint32_t n_value;
+    };
+
+    struct nlist_64 {
+      uint32_t n_strx;
+      uint8_t n_type;
+      uint8_t n_sect;
+      uint16_t n_desc;
+      uint64_t n_value;
+    };
+
+
+    // Byte order swapping functions for MachO structs
+
+    inline void swapStruct(mach_header &mh) {
+      sys::swapByteOrder(mh.magic);
+      sys::swapByteOrder(mh.cputype);
+      sys::swapByteOrder(mh.cpusubtype);
+      sys::swapByteOrder(mh.filetype);
+      sys::swapByteOrder(mh.ncmds);
+      sys::swapByteOrder(mh.sizeofcmds);
+      sys::swapByteOrder(mh.flags);
+    }
+
+    inline void swapStruct(mach_header_64 &H) {
+      sys::swapByteOrder(H.magic);
+      sys::swapByteOrder(H.cputype);
+      sys::swapByteOrder(H.cpusubtype);
+      sys::swapByteOrder(H.filetype);
+      sys::swapByteOrder(H.ncmds);
+      sys::swapByteOrder(H.sizeofcmds);
+      sys::swapByteOrder(H.flags);
+      sys::swapByteOrder(H.reserved);
+    }
+
+    inline void swapStruct(load_command &lc) {
+      sys::swapByteOrder(lc.cmd);
+      sys::swapByteOrder(lc.cmdsize);
+    }
+
+    inline void swapStruct(symtab_command &lc) {
+      sys::swapByteOrder(lc.cmd);
+      sys::swapByteOrder(lc.cmdsize);
+      sys::swapByteOrder(lc.symoff);
+      sys::swapByteOrder(lc.nsyms);
+      sys::swapByteOrder(lc.stroff);
+      sys::swapByteOrder(lc.strsize);
+    }
+
+    inline void swapStruct(segment_command_64 &seg) {
+      sys::swapByteOrder(seg.cmd);
+      sys::swapByteOrder(seg.cmdsize);
+      sys::swapByteOrder(seg.vmaddr);
+      sys::swapByteOrder(seg.vmsize);
+      sys::swapByteOrder(seg.fileoff);
+      sys::swapByteOrder(seg.filesize);
+      sys::swapByteOrder(seg.maxprot);
+      sys::swapByteOrder(seg.initprot);
+      sys::swapByteOrder(seg.nsects);
+      sys::swapByteOrder(seg.flags);
+    }
+
+    inline void swapStruct(segment_command &seg) {
+      sys::swapByteOrder(seg.cmd);
+      sys::swapByteOrder(seg.cmdsize);
+      sys::swapByteOrder(seg.vmaddr);
+      sys::swapByteOrder(seg.vmsize);
+      sys::swapByteOrder(seg.fileoff);
+      sys::swapByteOrder(seg.filesize);
+      sys::swapByteOrder(seg.maxprot);
+      sys::swapByteOrder(seg.initprot);
+      sys::swapByteOrder(seg.nsects);
+      sys::swapByteOrder(seg.flags);
+    }
+
+    inline void swapStruct(section_64 &sect) {
+      sys::swapByteOrder(sect.addr);
+      sys::swapByteOrder(sect.size);
+      sys::swapByteOrder(sect.offset);
+      sys::swapByteOrder(sect.align);
+      sys::swapByteOrder(sect.reloff);
+      sys::swapByteOrder(sect.nreloc);
+      sys::swapByteOrder(sect.flags);
+      sys::swapByteOrder(sect.reserved1);
+      sys::swapByteOrder(sect.reserved2);
+    }
+
+    inline void swapStruct(section &sect) {
+      sys::swapByteOrder(sect.addr);
+      sys::swapByteOrder(sect.size);
+      sys::swapByteOrder(sect.offset);
+      sys::swapByteOrder(sect.align);
+      sys::swapByteOrder(sect.reloff);
+      sys::swapByteOrder(sect.nreloc);
+      sys::swapByteOrder(sect.flags);
+      sys::swapByteOrder(sect.reserved1);
+      sys::swapByteOrder(sect.reserved2);
+    }
+
+    inline void swapStruct(dyld_info_command &info) {
+      sys::swapByteOrder(info.cmd);
+      sys::swapByteOrder(info.cmdsize);
+      sys::swapByteOrder(info.rebase_off);
+      sys::swapByteOrder(info.rebase_size);
+      sys::swapByteOrder(info.bind_off);
+      sys::swapByteOrder(info.bind_size);
+      sys::swapByteOrder(info.weak_bind_off);
+      sys::swapByteOrder(info.weak_bind_size);
+      sys::swapByteOrder(info.lazy_bind_off);
+      sys::swapByteOrder(info.lazy_bind_size);
+      sys::swapByteOrder(info.export_off);
+      sys::swapByteOrder(info.export_size);
+    }
+
+    inline void swapStruct(dylib_command &d) {
+      sys::swapByteOrder(d.cmd);
+      sys::swapByteOrder(d.cmdsize);
+      sys::swapByteOrder(d.dylib.name);
+      sys::swapByteOrder(d.dylib.timestamp);
+      sys::swapByteOrder(d.dylib.current_version);
+      sys::swapByteOrder(d.dylib.compatibility_version);
+    }
+
+    inline void swapStruct(dylinker_command &d) {
+      sys::swapByteOrder(d.cmd);
+      sys::swapByteOrder(d.cmdsize);
+      sys::swapByteOrder(d.name);
+    }
+
+    inline void swapStruct(entry_point_command &e) {
+      sys::swapByteOrder(e.cmd);
+      sys::swapByteOrder(e.cmdsize);
+      sys::swapByteOrder(e.entryoff);
+      sys::swapByteOrder(e.stacksize);
+    }
+
+    inline void swapStruct(dysymtab_command &dst) {
+      sys::swapByteOrder(dst.cmd);
+      sys::swapByteOrder(dst.cmdsize);
+      sys::swapByteOrder(dst.ilocalsym);
+      sys::swapByteOrder(dst.nlocalsym);
+      sys::swapByteOrder(dst.iextdefsym);
+      sys::swapByteOrder(dst.nextdefsym);
+      sys::swapByteOrder(dst.iundefsym);
+      sys::swapByteOrder(dst.nundefsym);
+      sys::swapByteOrder(dst.tocoff);
+      sys::swapByteOrder(dst.ntoc);
+      sys::swapByteOrder(dst.modtaboff);
+      sys::swapByteOrder(dst.nmodtab);
+      sys::swapByteOrder(dst.extrefsymoff);
+      sys::swapByteOrder(dst.nextrefsyms);
+      sys::swapByteOrder(dst.indirectsymoff);
+      sys::swapByteOrder(dst.nindirectsyms);
+      sys::swapByteOrder(dst.extreloff);
+      sys::swapByteOrder(dst.nextrel);
+      sys::swapByteOrder(dst.locreloff);
+      sys::swapByteOrder(dst.nlocrel);
+    }
+
+    inline void swapStruct(any_relocation_info &reloc) {
+      sys::swapByteOrder(reloc.r_word0);
+      sys::swapByteOrder(reloc.r_word1);
+    }
+
+    inline void swapStruct(nlist_base &S) {
+      sys::swapByteOrder(S.n_strx);
+      sys::swapByteOrder(S.n_desc);
+    }
+
+    inline void swapStruct(nlist &sym) {
+      sys::swapByteOrder(sym.n_strx);
+      sys::swapByteOrder(sym.n_desc);
+      sys::swapByteOrder(sym.n_value);
+    }
+
+    inline void swapStruct(nlist_64 &sym) {
+      sys::swapByteOrder(sym.n_strx);
+      sys::swapByteOrder(sym.n_desc);
+      sys::swapByteOrder(sym.n_value);
+    }
+
+    inline void swapStruct(linkedit_data_command &C) {
+      sys::swapByteOrder(C.cmd);
+      sys::swapByteOrder(C.cmdsize);
+      sys::swapByteOrder(C.dataoff);
+      sys::swapByteOrder(C.datasize);
+    }
+
+    inline void swapStruct(linker_options_command &C) {
+      sys::swapByteOrder(C.cmd);
+      sys::swapByteOrder(C.cmdsize);
+      sys::swapByteOrder(C.count);
+    }
+
+    inline void swapStruct(version_min_command&C) {
+      sys::swapByteOrder(C.cmd);
+      sys::swapByteOrder(C.cmdsize);
+      sys::swapByteOrder(C.version);
+      sys::swapByteOrder(C.reserved);
+    }
+
+    inline void swapStruct(data_in_code_entry &C) {
+      sys::swapByteOrder(C.offset);
+      sys::swapByteOrder(C.length);
+      sys::swapByteOrder(C.kind);
+    }
+
+    inline void swapStruct(uint32_t &C) {
+      sys::swapByteOrder(C);
+    }
+
+    // Get/Set functions from <mach-o/nlist.h>
+
+    static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) {
+      return (((n_desc) >> 8u) & 0xffu);
+    }
+
+    static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal) {
+      n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
+    }
+
+    static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc) {
+      return (n_desc >> 8u) & 0x0fu;
+    }
+
+    static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align) {
+      n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
+    }
+
+    // Enums from <mach/machine.h>
+    enum : uint32_t {
+      // Capability bits used in the definition of cpu_type.
+      CPU_ARCH_MASK  = 0xff000000,   // Mask for architecture bits
+      CPU_ARCH_ABI64 = 0x01000000    // 64 bit ABI
+    };
+
+    // Constants for the cputype field.
+    enum CPUType {
+      CPU_TYPE_ANY       = -1,
+      CPU_TYPE_X86       = 7,
+      CPU_TYPE_I386      = CPU_TYPE_X86,
+      CPU_TYPE_X86_64    = CPU_TYPE_X86 | CPU_ARCH_ABI64,
+   /* CPU_TYPE_MIPS      = 8, */
+      CPU_TYPE_MC98000   = 10, // Old Motorola PowerPC
+      CPU_TYPE_ARM       = 12,
+      CPU_TYPE_ARM64     = CPU_TYPE_ARM | CPU_ARCH_ABI64,
+      CPU_TYPE_SPARC     = 14,
+      CPU_TYPE_POWERPC   = 18,
+      CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
+    };
+
+    enum : uint32_t {
+      // Capability bits used in the definition of cpusubtype.
+      CPU_SUBTYPE_MASK  = 0xff000000,   // Mask for architecture bits
+      CPU_SUBTYPE_LIB64 = 0x80000000,   // 64 bit libraries
+
+      // Special CPU subtype constants.
+      CPU_SUBTYPE_MULTIPLE = ~0u
+    };
+
+    // Constants for the cpusubtype field.
+    enum CPUSubTypeX86 {
+      CPU_SUBTYPE_I386_ALL       = 3,
+      CPU_SUBTYPE_386            = 3,
+      CPU_SUBTYPE_486            = 4,
+      CPU_SUBTYPE_486SX          = 0x84,
+      CPU_SUBTYPE_586            = 5,
+      CPU_SUBTYPE_PENT           = CPU_SUBTYPE_586,
+      CPU_SUBTYPE_PENTPRO        = 0x16,
+      CPU_SUBTYPE_PENTII_M3      = 0x36,
+      CPU_SUBTYPE_PENTII_M5      = 0x56,
+      CPU_SUBTYPE_CELERON        = 0x67,
+      CPU_SUBTYPE_CELERON_MOBILE = 0x77,
+      CPU_SUBTYPE_PENTIUM_3      = 0x08,
+      CPU_SUBTYPE_PENTIUM_3_M    = 0x18,
+      CPU_SUBTYPE_PENTIUM_3_XEON = 0x28,
+      CPU_SUBTYPE_PENTIUM_M      = 0x09,
+      CPU_SUBTYPE_PENTIUM_4      = 0x0a,
+      CPU_SUBTYPE_PENTIUM_4_M    = 0x1a,
+      CPU_SUBTYPE_ITANIUM        = 0x0b,
+      CPU_SUBTYPE_ITANIUM_2      = 0x1b,
+      CPU_SUBTYPE_XEON           = 0x0c,
+      CPU_SUBTYPE_XEON_MP        = 0x1c,
+
+      CPU_SUBTYPE_X86_ALL     = 3,
+      CPU_SUBTYPE_X86_64_ALL  = 3,
+      CPU_SUBTYPE_X86_ARCH1   = 4,
+      CPU_SUBTYPE_X86_64_H    = 8
+    };
+    static inline int CPU_SUBTYPE_INTEL(int Family, int Model) {
+      return Family | (Model << 4);
+    }
+    static inline int CPU_SUBTYPE_INTEL_FAMILY(CPUSubTypeX86 ST) {
+      return ((int)ST) & 0x0f;
+    }
+    static inline int CPU_SUBTYPE_INTEL_MODEL(CPUSubTypeX86 ST) {
+      return ((int)ST) >> 4;
+    }
+    enum {
+      CPU_SUBTYPE_INTEL_FAMILY_MAX = 15,
+      CPU_SUBTYPE_INTEL_MODEL_ALL  = 0
+    };
+
+    enum CPUSubTypeARM {
+      CPU_SUBTYPE_ARM_ALL     = 0,
+      CPU_SUBTYPE_ARM_V4T     = 5,
+      CPU_SUBTYPE_ARM_V6      = 6,
+      CPU_SUBTYPE_ARM_V5      = 7,
+      CPU_SUBTYPE_ARM_V5TEJ   = 7,
+      CPU_SUBTYPE_ARM_XSCALE  = 8,
+      CPU_SUBTYPE_ARM_V7      = 9,
+      //  unused  ARM_V7F     = 10,
+      CPU_SUBTYPE_ARM_V7S     = 11,
+      CPU_SUBTYPE_ARM_V7K     = 12,
+      CPU_SUBTYPE_ARM_V6M     = 14,
+      CPU_SUBTYPE_ARM_V7M     = 15,
+      CPU_SUBTYPE_ARM_V7EM    = 16
+    };
+
+    enum CPUSubTypeARM64 {
+      CPU_SUBTYPE_ARM64_ALL   = 0
+    };
+
+    enum CPUSubTypeSPARC {
+      CPU_SUBTYPE_SPARC_ALL   = 0
+    };
+
+    enum CPUSubTypePowerPC {
+      CPU_SUBTYPE_POWERPC_ALL   = 0,
+      CPU_SUBTYPE_POWERPC_601   = 1,
+      CPU_SUBTYPE_POWERPC_602   = 2,
+      CPU_SUBTYPE_POWERPC_603   = 3,
+      CPU_SUBTYPE_POWERPC_603e  = 4,
+      CPU_SUBTYPE_POWERPC_603ev = 5,
+      CPU_SUBTYPE_POWERPC_604   = 6,
+      CPU_SUBTYPE_POWERPC_604e  = 7,
+      CPU_SUBTYPE_POWERPC_620   = 8,
+      CPU_SUBTYPE_POWERPC_750   = 9,
+      CPU_SUBTYPE_POWERPC_7400  = 10,
+      CPU_SUBTYPE_POWERPC_7450  = 11,
+      CPU_SUBTYPE_POWERPC_970   = 100,
+
+      CPU_SUBTYPE_MC980000_ALL  = CPU_SUBTYPE_POWERPC_ALL,
+      CPU_SUBTYPE_MC98601       = CPU_SUBTYPE_POWERPC_601
+    };
+  } // end namespace MachO
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
new file mode 100644
index 0000000..d8fbfeb
--- /dev/null
+++ b/include/llvm/Support/ManagedStatic.h
@@ -0,0 +1,111 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global 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 the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/Valgrind.h"
+
+namespace llvm {
+
+/// object_creator - Helper method for ManagedStatic.
+template<class C>
+void* object_creator() {
+  return new C();
+}
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<typename T> struct object_deleter {
+  static void call(void * Ptr) { delete (T*)Ptr; }
+};
+template<typename T, size_t N> struct object_deleter<T[N]> {
+  static void call(void * Ptr) { delete[] (T*)Ptr; }
+};
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+  // This should only be used as a static variable, which guarantees that this
+  // will be zero initialized.
+  mutable void *Ptr;
+  mutable void (*DeleterFn)(void*);
+  mutable const ManagedStaticBase *Next;
+
+  void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
+public:
+  /// isConstructed - Return true if this object has not been created yet.
+  bool isConstructed() const { return Ptr != nullptr; }
+
+  void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+
+  // Accessors.
+  C &operator*() {
+    void* tmp = Ptr;
+    if (llvm_is_multithreaded()) sys::MemoryFence();
+    if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+    TsanHappensAfter(this);
+
+    return *static_cast<C*>(Ptr);
+  }
+  C *operator->() {
+    void* tmp = Ptr;
+    if (llvm_is_multithreaded()) sys::MemoryFence();
+    if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+    TsanHappensAfter(this);
+
+    return static_cast<C*>(Ptr);
+  }
+  const C &operator*() const {
+    void* tmp = Ptr;
+    if (llvm_is_multithreaded()) sys::MemoryFence();
+    if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+    TsanHappensAfter(this);
+
+    return *static_cast<C*>(Ptr);
+  }
+  const C *operator->() const {
+    void* tmp = Ptr;
+    if (llvm_is_multithreaded()) sys::MemoryFence();
+    if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+    TsanHappensAfter(this);
+
+    return static_cast<C*>(Ptr);
+  }
+};
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown();
+
+/// llvm_shutdown_obj - This is a simple helper class that calls
+/// llvm_shutdown() when it is destroyed.
+struct llvm_shutdown_obj {
+  llvm_shutdown_obj() { }
+  ~llvm_shutdown_obj() { llvm_shutdown(); }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
new file mode 100644
index 0000000..0abba62
--- /dev/null
+++ b/include/llvm/Support/MathExtras.h
@@ -0,0 +1,644 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MATHEXTRAS_H
+#define LLVM_SUPPORT_MATHEXTRAS_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <cassert>
+#include <cstring>
+#include <type_traits>
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#include <limits>
+#endif
+
+namespace llvm {
+/// \brief The behavior an operation has on an input of 0.
+enum ZeroBehavior {
+  /// \brief The returned value is undefined.
+  ZB_Undefined,
+  /// \brief The returned value is numeric_limits<T>::max()
+  ZB_Max,
+  /// \brief The returned value is numeric_limits<T>::digits
+  ZB_Width
+};
+
+/// \brief Count number of 0's from the least significant bit to the most
+///   stopping at the first 1.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
+///   valid arguments.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        !std::numeric_limits<T>::is_signed, std::size_t>::type
+countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+  (void)ZB;
+
+  if (!Val)
+    return std::numeric_limits<T>::digits;
+  if (Val & 0x1)
+    return 0;
+
+  // Bisection method.
+  std::size_t ZeroBits = 0;
+  T Shift = std::numeric_limits<T>::digits >> 1;
+  T Mask = std::numeric_limits<T>::max() >> Shift;
+  while (Shift) {
+    if ((Val & Mask) == 0) {
+      Val >>= Shift;
+      ZeroBits |= Shift;
+    }
+    Shift >>= 1;
+    Mask >>= Shift;
+  }
+  return ZeroBits;
+}
+
+// Disable signed.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        std::numeric_limits<T>::is_signed, std::size_t>::type
+countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
+
+#if __GNUC__ >= 4 || _MSC_VER
+template <>
+inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
+  if (ZB != ZB_Undefined && Val == 0)
+    return 32;
+
+#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0)
+  return __builtin_ctz(Val);
+#elif _MSC_VER
+  unsigned long Index;
+  _BitScanForward(&Index, Val);
+  return Index;
+#endif
+}
+
+#if !defined(_MSC_VER) || defined(_M_X64)
+template <>
+inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
+  if (ZB != ZB_Undefined && Val == 0)
+    return 64;
+
+#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0)
+  return __builtin_ctzll(Val);
+#elif _MSC_VER
+  unsigned long Index;
+  _BitScanForward64(&Index, Val);
+  return Index;
+#endif
+}
+#endif
+#endif
+
+/// \brief Count number of 0's from the most significant bit to the least
+///   stopping at the first 1.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
+///   valid arguments.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        !std::numeric_limits<T>::is_signed, std::size_t>::type
+countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+  (void)ZB;
+
+  if (!Val)
+    return std::numeric_limits<T>::digits;
+
+  // Bisection method.
+  std::size_t ZeroBits = 0;
+  for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
+    T Tmp = Val >> Shift;
+    if (Tmp)
+      Val = Tmp;
+    else
+      ZeroBits |= Shift;
+  }
+  return ZeroBits;
+}
+
+// Disable signed.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        std::numeric_limits<T>::is_signed, std::size_t>::type
+countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
+
+#if __GNUC__ >= 4 || _MSC_VER
+template <>
+inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) {
+  if (ZB != ZB_Undefined && Val == 0)
+    return 32;
+
+#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0)
+  return __builtin_clz(Val);
+#elif _MSC_VER
+  unsigned long Index;
+  _BitScanReverse(&Index, Val);
+  return Index ^ 31;
+#endif
+}
+
+#if !defined(_MSC_VER) || defined(_M_X64)
+template <>
+inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
+  if (ZB != ZB_Undefined && Val == 0)
+    return 64;
+
+#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0)
+  return __builtin_clzll(Val);
+#elif _MSC_VER
+  unsigned long Index;
+  _BitScanReverse64(&Index, Val);
+  return Index ^ 63;
+#endif
+}
+#endif
+#endif
+
+/// \brief Get the index of the first set bit starting from the least
+///   significant bit.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
+///   valid arguments.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                       !std::numeric_limits<T>::is_signed, T>::type
+findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
+  if (ZB == ZB_Max && Val == 0)
+    return std::numeric_limits<T>::max();
+
+  return countTrailingZeros(Val, ZB_Undefined);
+}
+
+// Disable signed.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        std::numeric_limits<T>::is_signed, T>::type
+findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
+
+/// \brief Get the index of the last set bit starting from the least
+///   significant bit.
+///
+/// Only unsigned integral types are allowed.
+///
+/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
+///   valid arguments.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        !std::numeric_limits<T>::is_signed, T>::type
+findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
+  if (ZB == ZB_Max && Val == 0)
+    return std::numeric_limits<T>::max();
+
+  // Use ^ instead of - because both gcc and llvm can remove the associated ^
+  // in the __builtin_clz intrinsic on x86.
+  return countLeadingZeros(Val, ZB_Undefined) ^
+         (std::numeric_limits<T>::digits - 1);
+}
+
+// Disable signed.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+                        std::numeric_limits<T>::is_signed, T>::type
+findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
+
+/// \brief Macro compressed bit reversal table for 256 bits.
+///
+/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
+static const unsigned char BitReverseTable256[256] = {
+#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64
+#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
+#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
+  R6(0), R6(2), R6(1), R6(3)
+#undef R2
+#undef R4
+#undef R6
+};
+
+/// \brief Reverse the bits in \p Val.
+template <typename T>
+T reverseBits(T Val) {
+  unsigned char in[sizeof(Val)];
+  unsigned char out[sizeof(Val)];
+  std::memcpy(in, &Val, sizeof(Val));
+  for (unsigned i = 0; i < sizeof(Val); ++i)
+    out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]];
+  std::memcpy(&Val, out, sizeof(Val));
+  return Val;
+}
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+inline uint32_t Hi_32(uint64_t Value) {
+  return static_cast<uint32_t>(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+inline uint32_t Lo_32(uint64_t Value) {
+  return static_cast<uint32_t>(Value);
+}
+
+/// Make_64 - This functions makes a 64-bit integer from a high / low pair of
+///           32-bit integers.
+inline uint64_t Make_64(uint32_t High, uint32_t Low) {
+  return ((uint64_t)High << 32) | (uint64_t)Low;
+}
+
+/// isInt - Checks if an integer fits into the given bit width.
+template<unsigned N>
+inline bool isInt(int64_t x) {
+  return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+// Template specializations to get better code for common cases.
+template<>
+inline bool isInt<8>(int64_t x) {
+  return static_cast<int8_t>(x) == x;
+}
+template<>
+inline bool isInt<16>(int64_t x) {
+  return static_cast<int16_t>(x) == x;
+}
+template<>
+inline bool isInt<32>(int64_t x) {
+  return static_cast<int32_t>(x) == x;
+}
+
+/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shifted
+///                     left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedInt(int64_t x) {
+  return isInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
+/// isUInt - Checks if an unsigned integer fits into the given bit width.
+template<unsigned N>
+inline bool isUInt(uint64_t x) {
+  return N >= 64 || x < (UINT64_C(1)<<(N));
+}
+// Template specializations to get better code for common cases.
+template<>
+inline bool isUInt<8>(uint64_t x) {
+  return static_cast<uint8_t>(x) == x;
+}
+template<>
+inline bool isUInt<16>(uint64_t x) {
+  return static_cast<uint16_t>(x) == x;
+}
+template<>
+inline bool isUInt<32>(uint64_t x) {
+  return static_cast<uint32_t>(x) == x;
+}
+
+/// isShiftedUInt<N,S> - Checks if a unsigned integer is an N bit number shifted
+///                     left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedUInt(uint64_t x) {
+  return isUInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
+/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
+/// bit width.
+inline bool isUIntN(unsigned N, uint64_t x) {
+  return x == (x & (~0ULL >> (64 - N)));
+}
+
+/// isIntN - Checks if an signed integer fits into the given (dynamic)
+/// bit width.
+inline bool isIntN(unsigned N, int64_t x) {
+  return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version).   Ex. isMask_32(0x0000FFFFU) == true.
+inline bool isMask_32(uint32_t Value) {
+  return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+inline bool isMask_64(uint64_t Value) {
+  return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+inline bool isShiftedMask_32(uint32_t Value) {
+  return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+inline bool isShiftedMask_64(uint64_t Value) {
+  return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+inline bool isPowerOf2_32(uint32_t Value) {
+  return Value && !(Value & (Value - 1));
+}
+
+/// isPowerOf2_64 - This function returns true if the argument is a power of two
+/// > 0 (64 bit edition.)
+inline bool isPowerOf2_64(uint64_t Value) {
+  return Value && !(Value & (Value - int64_t(1L)));
+}
+
+/// ByteSwap_16 - This function returns a byte-swapped representation of the
+/// 16-bit argument, Value.
+inline uint16_t ByteSwap_16(uint16_t Value) {
+  return sys::SwapByteOrder_16(Value);
+}
+
+/// ByteSwap_32 - This function returns a byte-swapped representation of the
+/// 32-bit argument, Value.
+inline uint32_t ByteSwap_32(uint32_t Value) {
+  return sys::SwapByteOrder_32(Value);
+}
+
+/// ByteSwap_64 - This function returns a byte-swapped representation of the
+/// 64-bit argument, Value.
+inline uint64_t ByteSwap_64(uint64_t Value) {
+  return sys::SwapByteOrder_64(Value);
+}
+
+/// CountLeadingOnes_32 - this function performs the operation of
+/// counting the number of ones from the most significant bit to the first zero
+/// bit.  Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountLeadingOnes_32(uint32_t Value) {
+  return countLeadingZeros(~Value);
+}
+
+/// CountLeadingOnes_64 - This function performs the operation
+/// of counting the number of ones from the most significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountLeadingOnes_64(uint64_t Value) {
+  return countLeadingZeros(~Value);
+}
+
+/// CountTrailingOnes_32 - this function performs the operation of
+/// counting the number of ones from the least significant bit to the first zero
+/// bit.  Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountTrailingOnes_32(uint32_t Value) {
+  return countTrailingZeros(~Value);
+}
+
+/// CountTrailingOnes_64 - This function performs the operation
+/// of counting the number of ones from the least significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountTrailingOnes_64(uint64_t Value) {
+  return countTrailingZeros(~Value);
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+  return __builtin_popcount(Value);
+#else
+  uint32_t v = Value - ((Value >> 1) & 0x55555555);
+  v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+  return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+  return __builtin_popcountll(Value);
+#else
+  uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+  v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+  v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+  return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+inline unsigned Log2_32(uint32_t Value) {
+  return 31 - countLeadingZeros(Value);
+}
+
+/// Log2_64 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64(uint64_t Value) {
+  return 63 - countLeadingZeros(Value);
+}
+
+/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 32 if the value is zero. (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+inline unsigned Log2_32_Ceil(uint32_t Value) {
+  return 32 - countLeadingZeros(Value - 1);
+}
+
+/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 64 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64_Ceil(uint64_t Value) {
+  return 64 - countLeadingZeros(Value - 1);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+  while (B) {
+    uint64_t T = B;
+    B = A % B;
+    A = T;
+  }
+  return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+inline double BitsToDouble(uint64_t Bits) {
+  union {
+    uint64_t L;
+    double D;
+  } T;
+  T.L = Bits;
+  return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+inline float BitsToFloat(uint32_t Bits) {
+  union {
+    uint32_t I;
+    float F;
+  } T;
+  T.I = Bits;
+  return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer.  Note that copying doubles around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint64_t DoubleToBits(double Double) {
+  union {
+    uint64_t L;
+    double D;
+  } T;
+  T.D = Double;
+  return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer.  Note that copying floats around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint32_t FloatToBits(float Float) {
+  union {
+    uint32_t I;
+    float F;
+  } T;
+  T.F = Float;
+  return T.I;
+}
+
+/// Platform-independent wrappers for the C99 isnan() function.
+int IsNAN(float f);
+int IsNAN(double d);
+
+/// Platform-independent wrappers for the C99 isinf() function.
+int IsInf(float f);
+int IsInf(double d);
+
+/// MinAlign - A and B are either alignments or offsets.  Return the minimum
+/// alignment that may be assumed after adding the two together.
+inline uint64_t MinAlign(uint64_t A, uint64_t B) {
+  // The largest power of 2 that divides both A and B.
+  //
+  // Replace "-Value" by "1+~Value" in the following commented code to avoid 
+  // MSVC warning C4146
+  //    return (A | B) & -(A | B);
+  return (A | B) & (1 + ~(A | B));
+}
+
+/// \brief Aligns \c Ptr to \c Alignment bytes, rounding up.
+///
+/// Alignment should be a power of two.  This method rounds up, so
+/// AlignPtr(7, 4) == 8 and AlignPtr(8, 4) == 8.
+inline char *alignPtr(char *Ptr, size_t Alignment) {
+  assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
+         "Alignment is not a power of two!");
+
+  return (char *)(((uintptr_t)Ptr + Alignment - 1) &
+                  ~(uintptr_t)(Alignment - 1));
+}
+
+/// NextPowerOf2 - Returns the next power of two (in 64-bits)
+/// that is strictly greater than A.  Returns zero on overflow.
+inline uint64_t NextPowerOf2(uint64_t A) {
+  A |= (A >> 1);
+  A |= (A >> 2);
+  A |= (A >> 4);
+  A |= (A >> 8);
+  A |= (A >> 16);
+  A |= (A >> 32);
+  return A + 1;
+}
+
+/// Returns the power of two which is less than or equal to the given value.
+/// Essentially, it is a floor operation across the domain of powers of two.
+inline uint64_t PowerOf2Floor(uint64_t A) {
+  if (!A) return 0;
+  return 1ull << (63 - countLeadingZeros(A, ZB_Undefined));
+}
+
+/// Returns the next integer (mod 2**64) that is greater than or equal to
+/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
+///
+/// Examples:
+/// \code
+///   RoundUpToAlignment(5, 8) = 8
+///   RoundUpToAlignment(17, 8) = 24
+///   RoundUpToAlignment(~0LL, 8) = 0
+/// \endcode
+inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) {
+  return ((Value + Align - 1) / Align) * Align;
+}
+
+/// Returns the offset to the next integer (mod 2**64) that is greater than
+/// or equal to \p Value and is a multiple of \p Align. \p Align must be
+/// non-zero.
+inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
+  return RoundUpToAlignment(Value, Align) - Value;
+}
+
+/// abs64 - absolute value of a 64-bit int.  Not all environments support
+/// "abs" on whatever their name for the 64-bit int type is.  The absolute
+/// value of the largest negative number is undefined, as with "abs".
+inline int64_t abs64(int64_t x) {
+  return (x < 0) ? -x : x;
+}
+
+/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
+/// Usage int32_t r = SignExtend32<5>(x);
+template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
+  return int32_t(x << (32 - B)) >> (32 - B);
+}
+
+/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
+/// Requires 0 < B <= 32.
+inline int32_t SignExtend32(uint32_t X, unsigned B) {
+  return int32_t(X << (32 - B)) >> (32 - B);
+}
+
+/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
+/// Usage int64_t r = SignExtend64<5>(x);
+template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
+  return int64_t(x << (64 - B)) >> (64 - B);
+}
+
+/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
+/// Requires 0 < B <= 64.
+inline int64_t SignExtend64(uint64_t X, unsigned B) {
+  return int64_t(X << (64 - B)) >> (64 - B);
+}
+
+#if defined(_MSC_VER)
+  // Visual Studio defines the HUGE_VAL class of macros using purposeful
+  // constant arithmetic overflow, which it then warns on when encountered.
+  const float huge_valf = std::numeric_limits<float>::infinity();
+#else
+  const float huge_valf = HUGE_VALF;
+#endif
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
new file mode 100644
index 0000000..b4305cb
--- /dev/null
+++ b/include/llvm/Support/Memory.h
@@ -0,0 +1,161 @@
+//===- llvm/Support/Memory.h - Memory Support --------------------*- 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 llvm::sys::Memory class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORY_H
+#define LLVM_SUPPORT_MEMORY_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+#include <system_error>
+
+namespace llvm {
+namespace sys {
+
+  /// This class encapsulates the notion of a memory block which has an address
+  /// and a size. It is used by the Memory class (a friend) as the result of
+  /// various memory allocation operations.
+  /// @see Memory
+  /// @brief Memory block abstraction.
+  class MemoryBlock {
+  public:
+    MemoryBlock() : Address(nullptr), Size(0) { }
+    MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
+    void *base() const { return Address; }
+    size_t size() const { return Size; }
+  private:
+    void *Address;    ///< Address of first byte of memory area
+    size_t Size;      ///< Size, in bytes of the memory area
+    friend class Memory;
+  };
+
+  /// This class provides various memory handling functions that manipulate
+  /// MemoryBlock instances.
+  /// @since 1.4
+  /// @brief An abstraction for memory operations.
+  class Memory {
+  public:
+    enum ProtectionFlags {
+      MF_READ  = 0x1000000,
+      MF_WRITE = 0x2000000,
+      MF_EXEC  = 0x4000000
+    };
+
+    /// This method allocates a block of memory that is suitable for loading
+    /// dynamically generated code (e.g. JIT). An attempt to allocate
+    /// \p NumBytes bytes of virtual memory is made.
+    /// \p NearBlock may point to an existing allocation in which case
+    /// an attempt is made to allocate more memory near the existing block.
+    /// The actual allocated address is not guaranteed to be near the requested
+    /// address.
+    /// \p Flags is used to set the initial protection flags for the block
+    /// of the memory.
+    /// \p EC [out] returns an object describing any error that occurs.
+    ///
+    /// This method may allocate more than the number of bytes requested.  The
+    /// actual number of bytes allocated is indicated in the returned
+    /// MemoryBlock.
+    ///
+    /// The start of the allocated block must be aligned with the
+    /// system allocation granularity (64K on Windows, page size on Linux).
+    /// If the address following \p NearBlock is not so aligned, it will be
+    /// rounded up to the next allocation granularity boundary.
+    ///
+    /// \r a non-null MemoryBlock if the function was successful, 
+    /// otherwise a null MemoryBlock is with \p EC describing the error.
+    ///
+    /// @brief Allocate mapped memory.
+    static MemoryBlock allocateMappedMemory(size_t NumBytes,
+                                            const MemoryBlock *const NearBlock,
+                                            unsigned Flags,
+                                            std::error_code &EC);
+
+    /// This method releases a block of memory that was allocated with the
+    /// allocateMappedMemory method. It should not be used to release any
+    /// memory block allocated any other way.
+    /// \p Block describes the memory to be released.
+    ///
+    /// \r error_success if the function was successful, or an error_code
+    /// describing the failure if an error occurred.
+    /// 
+    /// @brief Release mapped memory.
+    static std::error_code releaseMappedMemory(MemoryBlock &Block);
+
+    /// This method sets the protection flags for a block of memory to the
+    /// state specified by /p Flags.  The behavior is not specified if the
+    /// memory was not allocated using the allocateMappedMemory method.
+    /// \p Block describes the memory block to be protected.
+    /// \p Flags specifies the new protection state to be assigned to the block.
+    /// \p ErrMsg [out] returns a string describing any error that occurred.
+    ///
+    /// If \p Flags is MF_WRITE, the actual behavior varies
+    /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
+    /// target architecture (i.e. MF_WRITE -> MF_READ | MF_WRITE on i386).
+    ///
+    /// \r error_success if the function was successful, or an error_code
+    /// describing the failure if an error occurred.
+    ///
+    /// @brief Set memory protection state.
+    static std::error_code protectMappedMemory(const MemoryBlock &Block,
+                                               unsigned Flags);
+
+    /// This method allocates a block of Read/Write/Execute memory that is
+    /// suitable for executing dynamically generated code (e.g. JIT). An
+    /// attempt to allocate \p NumBytes bytes of virtual memory is made.
+    /// \p NearBlock may point to an existing allocation in which case
+    /// an attempt is made to allocate more memory near the existing block.
+    ///
+    /// On success, this returns a non-null memory block, otherwise it returns
+    /// a null memory block and fills in *ErrMsg.
+    ///
+    /// @brief Allocate Read/Write/Execute memory.
+    static MemoryBlock AllocateRWX(size_t NumBytes,
+                                   const MemoryBlock *NearBlock,
+                                   std::string *ErrMsg = nullptr);
+
+    /// This method releases a block of Read/Write/Execute memory that was
+    /// allocated with the AllocateRWX method. It should not be used to
+    /// release any memory block allocated any other way.
+    ///
+    /// On success, this returns false, otherwise it returns true and fills
+    /// in *ErrMsg.
+    /// @brief Release Read/Write/Execute memory.
+    static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr);
+
+
+    /// InvalidateInstructionCache - Before the JIT can run a block of code
+    /// that has been emitted it must invalidate the instruction cache on some
+    /// platforms.
+    static void InvalidateInstructionCache(const void *Addr, size_t Len);
+
+    /// setExecutable - Before the JIT can run a block of code, it has to be
+    /// given read and executable privilege. Return true if it is already r-x
+    /// or the system is able to change its previlege.
+    static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = nullptr);
+
+    /// setWritable - When adding to a block of code, the JIT may need
+    /// to mark a block of code as RW since the protections are on page
+    /// boundaries, and the JIT internal allocations are not page aligned.
+    static bool setWritable(MemoryBlock &M, std::string *ErrMsg = nullptr);
+
+    /// setRangeExecutable - Mark the page containing a range of addresses
+    /// as executable.
+    static bool setRangeExecutable(const void *Addr, size_t Size);
+
+    /// setRangeWritable - Mark the page containing a range of addresses
+    /// as writable.
+    static bool setRangeWritable(const void *Addr, size_t Size);
+  };
+}
+}
+
+#endif
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
new file mode 100644
index 0000000..147be47
--- /dev/null
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -0,0 +1,150 @@
+//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- 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 MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
+#define LLVM_SUPPORT_MEMORYBUFFER_H
+
+#include "llvm-c/Support.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorOr.h"
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+/// MemoryBuffer - This interface provides simple read-only access to a block
+/// of memory, and provides simple methods for reading files and standard input
+/// into a memory buffer.  In addition to basic access to the characters in the
+/// file, this interface guarantees you can read one character past the end of
+/// the file, and that this character will read as '\0'.
+///
+/// The '\0' guarantee is needed to support an optimization -- it's intended to
+/// be more efficient for clients which are reading all the data to stop
+/// reading when they encounter a '\0' than to continually check the file
+/// position to see if it has reached the end of the file.
+class MemoryBuffer {
+  const char *BufferStart; // Start of the buffer.
+  const char *BufferEnd;   // End of the buffer.
+
+  MemoryBuffer(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
+  MemoryBuffer &operator=(const MemoryBuffer &) LLVM_DELETED_FUNCTION;
+protected:
+  MemoryBuffer() {}
+  void init(const char *BufStart, const char *BufEnd,
+            bool RequiresNullTerminator);
+public:
+  virtual ~MemoryBuffer();
+
+  const char *getBufferStart() const { return BufferStart; }
+  const char *getBufferEnd() const   { return BufferEnd; }
+  size_t getBufferSize() const { return BufferEnd-BufferStart; }
+
+  StringRef getBuffer() const {
+    return StringRef(BufferStart, getBufferSize());
+  }
+
+  /// getBufferIdentifier - Return an identifier for this buffer, typically the
+  /// filename it was read from.
+  virtual const char *getBufferIdentifier() const {
+    return "Unknown buffer";
+  }
+
+  /// Open the specified file as a MemoryBuffer, returning a new MemoryBuffer
+  /// if successful, otherwise returning null. If FileSize is specified, this
+  /// means that the client knows that the file exists and that it has the
+  /// specified size.
+  ///
+  /// \param IsVolatileSize Set to true to indicate that the file size may be
+  /// changing, e.g. when libclang tries to parse while the user is
+  /// editing/updating the file.
+  static ErrorOr<std::unique_ptr<MemoryBuffer>>
+  getFile(Twine Filename, int64_t FileSize = -1,
+          bool RequiresNullTerminator = true, bool IsVolatileSize = false);
+
+  /// Given an already-open file descriptor, map some slice of it into a
+  /// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
+  /// Since this is in the middle of a file, the buffer is not null terminated.
+  ///
+  /// \param IsVolatileSize Set to true to indicate that the file size may be
+  /// changing, e.g. when libclang tries to parse while the user is
+  /// editing/updating the file.
+  static ErrorOr<std::unique_ptr<MemoryBuffer>>
+  getOpenFileSlice(int FD, const char *Filename, uint64_t MapSize,
+                   int64_t Offset, bool IsVolatileSize = false);
+
+  /// Given an already-open file descriptor, read the file and return a
+  /// MemoryBuffer.
+  ///
+  /// \param IsVolatileSize Set to true to indicate that the file size may be
+  /// changing, e.g. when libclang tries to parse while the user is
+  /// editing/updating the file.
+  static ErrorOr<std::unique_ptr<MemoryBuffer>>
+  getOpenFile(int FD, const char *Filename, uint64_t FileSize,
+              bool RequiresNullTerminator = true, bool IsVolatileSize = false);
+
+  /// getMemBuffer - Open the specified memory range as a MemoryBuffer.  Note
+  /// that InputData must be null terminated if RequiresNullTerminator is true.
+  static MemoryBuffer *getMemBuffer(StringRef InputData,
+                                    StringRef BufferName = "",
+                                    bool RequiresNullTerminator = true);
+
+  /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
+  /// copying the contents and taking ownership of it.  InputData does not
+  /// have to be null terminated.
+  static MemoryBuffer *getMemBufferCopy(StringRef InputData,
+                                        StringRef BufferName = "");
+
+  /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
+  /// is completely initialized to zeros.  Note that the caller should
+  /// initialize the memory allocated by this method.  The memory is owned by
+  /// the MemoryBuffer object.
+  static MemoryBuffer *getNewMemBuffer(size_t Size, StringRef BufferName = "");
+
+  /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
+  /// that is not initialized.  Note that the caller should initialize the
+  /// memory allocated by this method.  The memory is owned by the MemoryBuffer
+  /// object.
+  static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
+                                             StringRef BufferName = "");
+
+  /// Read all of stdin into a file buffer, and return it.
+  static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN();
+
+  /// Open the specified file as a MemoryBuffer, or open stdin if the Filename
+  /// is "-".
+  static ErrorOr<std::unique_ptr<MemoryBuffer>>
+  getFileOrSTDIN(StringRef Filename, int64_t FileSize = -1);
+
+  //===--------------------------------------------------------------------===//
+  // Provided for performance analysis.
+  //===--------------------------------------------------------------------===//
+
+  /// The kind of memory backing used to support the MemoryBuffer.
+  enum BufferKind {
+    MemoryBuffer_Malloc,
+    MemoryBuffer_MMap
+  };
+
+  /// Return information on the memory mechanism used to support the
+  /// MemoryBuffer.
+  virtual BufferKind getBufferKind() const = 0;  
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef)
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
new file mode 100644
index 0000000..17aa9d2
--- /dev/null
+++ b/include/llvm/Support/MemoryObject.h
@@ -0,0 +1,64 @@
+//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYOBJECT_H
+#define LLVM_SUPPORT_MEMORYOBJECT_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// MemoryObject - Abstract base class for contiguous addressable memory.
+///   Necessary for cases in which the memory is in another process, in a
+///   file, or on a remote machine.
+///   All size and offset parameters are uint64_ts, to allow 32-bit processes
+///   access to 64-bit address spaces.
+class MemoryObject {
+public:
+  /// Destructor      - Override as necessary.
+  virtual ~MemoryObject();
+
+  /// getBase         - Returns the lowest valid address in the region.
+  ///
+  /// @result         - The lowest valid address.
+  virtual uint64_t getBase() const = 0;
+
+  /// getExtent       - Returns the size of the region in bytes.  (The region is
+  ///                   contiguous, so the highest valid address of the region
+  ///                   is getBase() + getExtent() - 1).
+  ///
+  /// @result         - The size of the region.
+  virtual uint64_t getExtent() const = 0;
+
+  /// readByte        - Tries to read a single byte from the region.
+  ///
+  /// @param address  - The address of the byte, in the same space as getBase().
+  /// @param ptr      - A pointer to a byte to be filled in.  Must be non-NULL.
+  /// @result         - 0 if successful; -1 if not.  Failure may be due to a
+  ///                   bounds violation or an implementation-specific error.
+  virtual int readByte(uint64_t address, uint8_t *ptr) const = 0;
+
+  /// readBytes       - Tries to read a contiguous range of bytes from the
+  ///                   region, up to the end of the region.
+  ///                   You should override this function if there is a quicker
+  ///                   way than going back and forth with individual bytes.
+  ///
+  /// @param address  - The address of the first byte, in the same space as 
+  ///                   getBase().
+  /// @param size     - The number of bytes to copy.
+  /// @param buf      - A pointer to a buffer to be filled in.  Must be non-NULL
+  ///                   and large enough to hold size bytes.
+  /// @result         - 0 if successful; -1 if not.  Failure may be due to a
+  ///                   bounds violation or an implementation-specific error.
+  virtual int readBytes(uint64_t address, uint64_t size, uint8_t *buf) const;
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h
new file mode 100644
index 0000000..496a438
--- /dev/null
+++ b/include/llvm/Support/Mutex.h
@@ -0,0 +1,155 @@
+//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- 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 llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEX_H
+#define LLVM_SUPPORT_MUTEX_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+  namespace sys
+  {
+    /// @brief Platform agnostic Mutex class.
+    class MutexImpl
+    {
+    /// @name Constructors
+    /// @{
+    public:
+
+      /// Initializes the lock but doesn't acquire it. if \p recursive is set
+      /// to false, the lock will not be recursive which makes it cheaper but
+      /// also more likely to deadlock (same thread can't acquire more than
+      /// once).
+      /// @brief Default Constructor.
+      explicit MutexImpl(bool recursive = true);
+
+      /// Releases and removes the lock
+      /// @brief Destructor
+      ~MutexImpl();
+
+    /// @}
+    /// @name Methods
+    /// @{
+    public:
+
+      /// Attempts to unconditionally acquire the lock. If the lock is held by
+      /// another thread, this method will wait until it can acquire the lock.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally acquire the lock.
+      bool acquire();
+
+      /// Attempts to release the lock. If the lock is held by the current
+      /// thread, the lock is released allowing other threads to acquire the
+      /// lock.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally release the lock.
+      bool release();
+
+      /// Attempts to acquire the lock without blocking. If the lock is not
+      /// available, this function returns false quickly (without blocking). If
+      /// the lock is available, it is acquired.
+      /// @returns false if any kind of error occurs or the lock is not
+      /// available, true otherwise.
+      /// @brief Try to acquire the lock.
+      bool tryacquire();
+
+    //@}
+    /// @name Platform Dependent Data
+    /// @{
+    private:
+      void* data_; ///< We don't know what the data will be
+
+    /// @}
+    /// @name Do Not Implement
+    /// @{
+    private:
+      MutexImpl(const MutexImpl &) LLVM_DELETED_FUNCTION;
+      void operator=(const MutexImpl &) LLVM_DELETED_FUNCTION;
+    /// @}
+    };
+
+
+    /// SmartMutex - A mutex with a compile time constant parameter that
+    /// indicates whether this mutex should become a no-op when we're not
+    /// running in multithreaded mode.
+    template<bool mt_only>
+    class SmartMutex : public MutexImpl {
+      unsigned acquired;
+      bool recursive;
+    public:
+      explicit SmartMutex(bool rec = true) :
+        MutexImpl(rec), acquired(0), recursive(rec) { }
+
+      bool acquire() {
+        if (!mt_only || llvm_is_multithreaded()) {
+          return MutexImpl::acquire();
+        } else {
+          // Single-threaded debugging code.  This would be racy in
+          // multithreaded mode, but provides not sanity checks in single
+          // threaded mode.
+          assert((recursive || acquired == 0) && "Lock already acquired!!");
+          ++acquired;
+          return true;
+        }
+      }
+
+      bool release() {
+        if (!mt_only || llvm_is_multithreaded()) {
+          return MutexImpl::release();
+        } else {
+          // Single-threaded debugging code.  This would be racy in
+          // multithreaded mode, but provides not sanity checks in single
+          // threaded mode.
+          assert(((recursive && acquired) || (acquired == 1)) &&
+                 "Lock not acquired before release!");
+          --acquired;
+          return true;
+        }
+      }
+
+      bool tryacquire() {
+        if (!mt_only || llvm_is_multithreaded())
+          return MutexImpl::tryacquire();
+        else return true;
+      }
+
+      private:
+        SmartMutex(const SmartMutex<mt_only> & original);
+        void operator=(const SmartMutex<mt_only> &);
+    };
+
+    /// Mutex - A standard, always enforced mutex.
+    typedef SmartMutex<false> Mutex;
+
+    template<bool mt_only>
+    class SmartScopedLock  {
+      SmartMutex<mt_only>& mtx;
+
+    public:
+      SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
+        mtx.acquire();
+      }
+
+      ~SmartScopedLock() {
+        mtx.release();
+      }
+    };
+
+    typedef SmartScopedLock<false> ScopedLock;
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
new file mode 100644
index 0000000..6bb1622
--- /dev/null
+++ b/include/llvm/Support/MutexGuard.h
@@ -0,0 +1,41 @@
+//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- 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 guard for a block of code that ensures a Mutex is locked
+// upon construction and released upon destruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEXGUARD_H
+#define LLVM_SUPPORT_MUTEXGUARD_H
+
+#include "llvm/Support/Mutex.h"
+
+namespace llvm {
+  /// Instances of this class acquire a given Mutex Lock when constructed and
+  /// hold that lock until destruction. The intention is to instantiate one of
+  /// these on the stack at the top of some scope to be assured that C++
+  /// destruction of the object will always release the Mutex and thus avoid
+  /// a host of nasty multi-threading problems in the face of exceptions, etc.
+  /// @brief Guard a section of code with a Mutex.
+  class MutexGuard {
+    sys::Mutex &M;
+    MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION;
+    void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION;
+  public:
+    MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
+    ~MutexGuard() { M.release(); }
+    /// holds - Returns true if this locker instance holds the specified lock.
+    /// This is mostly used in assertions to validate that the correct mutex
+    /// is held.
+    bool holds(const sys::Mutex& lock) const { return &M == &lock; }
+  };
+}
+
+#endif // LLVM_SUPPORT_MUTEXGUARD_H
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
new file mode 100644
index 0000000..f6d43a4
--- /dev/null
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -0,0 +1,571 @@
+//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines facilities for reading and writing on-disk hash tables.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
+#define LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdlib>
+
+namespace llvm {
+
+/// \brief Generates an on disk hash table.
+///
+/// This needs an \c Info that handles storing values into the hash table's
+/// payload and computes the hash for a given key. This should provide the
+/// following interface:
+///
+/// \code
+/// class ExampleInfo {
+/// public:
+///   typedef ExampleKey key_type;   // Must be copy constructible
+///   typedef ExampleKey &key_type_ref;
+///   typedef ExampleData data_type; // Must be copy constructible
+///   typedef ExampleData &data_type_ref;
+///   typedef uint32_t hash_value_type; // The type the hash function returns.
+///   typedef uint32_t offset_type; // The type for offsets into the table.
+///
+///   /// Calculate the hash for Key
+///   static hash_value_type ComputeHash(key_type_ref Key);
+///   /// Return the lengths, in bytes, of the given Key/Data pair.
+///   static std::pair<offset_type, offset_type>
+///   EmitKeyDataLength(raw_ostream &Out, key_type_ref Key, data_type_ref Data);
+///   /// Write Key to Out.  KeyLen is the length from EmitKeyDataLength.
+///   static void EmitKey(raw_ostream &Out, key_type_ref Key,
+///                       offset_type KeyLen);
+///   /// Write Data to Out.  DataLen is the length from EmitKeyDataLength.
+///   static void EmitData(raw_ostream &Out, key_type_ref Key,
+///                        data_type_ref Data, offset_type DataLen);
+/// };
+/// \endcode
+template <typename Info> class OnDiskChainedHashTableGenerator {
+  /// \brief A single item in the hash table.
+  class Item {
+  public:
+    typename Info::key_type Key;
+    typename Info::data_type Data;
+    Item *Next;
+    const typename Info::hash_value_type Hash;
+
+    Item(typename Info::key_type_ref Key, typename Info::data_type_ref Data,
+         Info &InfoObj)
+        : Key(Key), Data(Data), Next(nullptr), Hash(InfoObj.ComputeHash(Key)) {}
+  };
+
+  typedef typename Info::offset_type offset_type;
+  offset_type NumBuckets;
+  offset_type NumEntries;
+  llvm::SpecificBumpPtrAllocator<Item> BA;
+
+  /// \brief A linked list of values in a particular hash bucket.
+  class Bucket {
+  public:
+    offset_type Off;
+    Item *Head;
+    unsigned Length;
+
+    Bucket() {}
+  };
+
+  Bucket *Buckets;
+
+private:
+  /// \brief Insert an item into the appropriate hash bucket.
+  void insert(Bucket *Buckets, size_t Size, Item *E) {
+    Bucket &B = Buckets[E->Hash & (Size - 1)];
+    E->Next = B.Head;
+    ++B.Length;
+    B.Head = E;
+  }
+
+  /// \brief Resize the hash table, moving the old entries into the new buckets.
+  void resize(size_t NewSize) {
+    Bucket *NewBuckets = (Bucket *)std::calloc(NewSize, sizeof(Bucket));
+    // Populate NewBuckets with the old entries.
+    for (size_t I = 0; I < NumBuckets; ++I)
+      for (Item *E = Buckets[I].Head; E;) {
+        Item *N = E->Next;
+        E->Next = nullptr;
+        insert(NewBuckets, NewSize, E);
+        E = N;
+      }
+
+    free(Buckets);
+    NumBuckets = NewSize;
+    Buckets = NewBuckets;
+  }
+
+public:
+  /// \brief Insert an entry into the table.
+  void insert(typename Info::key_type_ref Key,
+              typename Info::data_type_ref Data) {
+    Info InfoObj;
+    insert(Key, Data, InfoObj);
+  }
+
+  /// \brief Insert an entry into the table.
+  ///
+  /// Uses the provided Info instead of a stack allocated one.
+  void insert(typename Info::key_type_ref Key,
+              typename Info::data_type_ref Data, Info &InfoObj) {
+
+    ++NumEntries;
+    if (4 * NumEntries >= 3 * NumBuckets)
+      resize(NumBuckets * 2);
+    insert(Buckets, NumBuckets, new (BA.Allocate()) Item(Key, Data, InfoObj));
+  }
+
+  /// \brief Emit the table to Out, which must not be at offset 0.
+  offset_type Emit(raw_ostream &Out) {
+    Info InfoObj;
+    return Emit(Out, InfoObj);
+  }
+
+  /// \brief Emit the table to Out, which must not be at offset 0.
+  ///
+  /// Uses the provided Info instead of a stack allocated one.
+  offset_type Emit(raw_ostream &Out, Info &InfoObj) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
+
+    // Emit the payload of the table.
+    for (offset_type I = 0; I < NumBuckets; ++I) {
+      Bucket &B = Buckets[I];
+      if (!B.Head)
+        continue;
+
+      // Store the offset for the data of this bucket.
+      B.Off = Out.tell();
+      assert(B.Off && "Cannot write a bucket at offset 0. Please add padding.");
+
+      // Write out the number of items in the bucket.
+      LE.write<uint16_t>(B.Length);
+      assert(B.Length != 0 && "Bucket has a head but zero length?");
+
+      // Write out the entries in the bucket.
+      for (Item *I = B.Head; I; I = I->Next) {
+        LE.write<typename Info::hash_value_type>(I->Hash);
+        const std::pair<offset_type, offset_type> &Len =
+            InfoObj.EmitKeyDataLength(Out, I->Key, I->Data);
+        InfoObj.EmitKey(Out, I->Key, Len.first);
+        InfoObj.EmitData(Out, I->Key, I->Data, Len.second);
+      }
+    }
+
+    // Pad with zeros so that we can start the hashtable at an aligned address.
+    offset_type TableOff = Out.tell();
+    uint64_t N = llvm::OffsetToAlignment(TableOff, alignOf<offset_type>());
+    TableOff += N;
+    while (N--)
+      LE.write<uint8_t>(0);
+
+    // Emit the hashtable itself.
+    LE.write<offset_type>(NumBuckets);
+    LE.write<offset_type>(NumEntries);
+    for (offset_type I = 0; I < NumBuckets; ++I)
+      LE.write<offset_type>(Buckets[I].Off);
+
+    return TableOff;
+  }
+
+  OnDiskChainedHashTableGenerator() {
+    NumEntries = 0;
+    NumBuckets = 64;
+    // Note that we do not need to run the constructors of the individual
+    // Bucket objects since 'calloc' returns bytes that are all 0.
+    Buckets = (Bucket *)std::calloc(NumBuckets, sizeof(Bucket));
+  }
+
+  ~OnDiskChainedHashTableGenerator() { std::free(Buckets); }
+};
+
+/// \brief Provides lookup on an on disk hash table.
+///
+/// This needs an \c Info that handles reading values from the hash table's
+/// payload and computes the hash for a given key. This should provide the
+/// following interface:
+///
+/// \code
+/// class ExampleLookupInfo {
+/// public:
+///   typedef ExampleData data_type;
+///   typedef ExampleInternalKey internal_key_type; // The stored key type.
+///   typedef ExampleKey external_key_type; // The type to pass to find().
+///   typedef uint32_t hash_value_type; // The type the hash function returns.
+///   typedef uint32_t offset_type; // The type for offsets into the table.
+///
+///   /// Compare two keys for equality.
+///   static bool EqualKey(internal_key_type &Key1, internal_key_type &Key2);
+///   /// Calculate the hash for the given key.
+///   static hash_value_type ComputeHash(internal_key_type &IKey);
+///   /// Translate from the semantic type of a key in the hash table to the
+///   /// type that is actually stored and used for hashing and comparisons.
+///   /// The internal and external types are often the same, in which case this
+///   /// can simply return the passed in value.
+///   static const internal_key_type &GetInternalKey(external_key_type &EKey);
+///   /// Read the key and data length from Buffer, leaving it pointing at the
+///   /// following byte.
+///   static std::pair<offset_type, offset_type>
+///   ReadKeyDataLength(const unsigned char *&Buffer);
+///   /// Read the key from Buffer, given the KeyLen as reported from
+///   /// ReadKeyDataLength.
+///   const internal_key_type &ReadKey(const unsigned char *Buffer,
+///                                    offset_type KeyLen);
+///   /// Read the data for Key from Buffer, given the DataLen as reported from
+///   /// ReadKeyDataLength.
+///   data_type ReadData(StringRef Key, const unsigned char *Buffer,
+///                      offset_type DataLen);
+/// };
+/// \endcode
+template <typename Info> class OnDiskChainedHashTable {
+  const typename Info::offset_type NumBuckets;
+  const typename Info::offset_type NumEntries;
+  const unsigned char *const Buckets;
+  const unsigned char *const Base;
+  Info InfoObj;
+
+public:
+  typedef typename Info::internal_key_type internal_key_type;
+  typedef typename Info::external_key_type external_key_type;
+  typedef typename Info::data_type         data_type;
+  typedef typename Info::hash_value_type   hash_value_type;
+  typedef typename Info::offset_type       offset_type;
+
+  OnDiskChainedHashTable(offset_type NumBuckets, offset_type NumEntries,
+                         const unsigned char *Buckets,
+                         const unsigned char *Base,
+                         const Info &InfoObj = Info())
+      : NumBuckets(NumBuckets), NumEntries(NumEntries), Buckets(Buckets),
+        Base(Base), InfoObj(InfoObj) {
+    assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+           "'buckets' must have a 4-byte alignment");
+  }
+
+  offset_type getNumBuckets() const { return NumBuckets; }
+  offset_type getNumEntries() const { return NumEntries; }
+  const unsigned char *getBase() const { return Base; }
+  const unsigned char *getBuckets() const { return Buckets; }
+
+  bool isEmpty() const { return NumEntries == 0; }
+
+  class iterator {
+    internal_key_type Key;
+    const unsigned char *const Data;
+    const offset_type Len;
+    Info *InfoObj;
+
+  public:
+    iterator() : Data(nullptr), Len(0) {}
+    iterator(const internal_key_type K, const unsigned char *D, offset_type L,
+             Info *InfoObj)
+        : Key(K), Data(D), Len(L), InfoObj(InfoObj) {}
+
+    data_type operator*() const { return InfoObj->ReadData(Key, Data, Len); }
+    bool operator==(const iterator &X) const { return X.Data == Data; }
+    bool operator!=(const iterator &X) const { return X.Data != Data; }
+  };
+
+  /// \brief Look up the stored data for a particular key.
+  iterator find(const external_key_type &EKey, Info *InfoPtr = 0) {
+    if (!InfoPtr)
+      InfoPtr = &InfoObj;
+
+    using namespace llvm::support;
+    const internal_key_type &IKey = InfoObj.GetInternalKey(EKey);
+    hash_value_type KeyHash = InfoObj.ComputeHash(IKey);
+
+    // Each bucket is just an offset into the hash table file.
+    offset_type Idx = KeyHash & (NumBuckets - 1);
+    const unsigned char *Bucket = Buckets + sizeof(offset_type) * Idx;
+
+    offset_type Offset = endian::readNext<offset_type, little, aligned>(Bucket);
+    if (Offset == 0)
+      return iterator(); // Empty bucket.
+    const unsigned char *Items = Base + Offset;
+
+    // 'Items' starts with a 16-bit unsigned integer representing the
+    // number of items in this bucket.
+    unsigned Len = endian::readNext<uint16_t, little, unaligned>(Items);
+
+    for (unsigned i = 0; i < Len; ++i) {
+      // Read the hash.
+      hash_value_type ItemHash =
+          endian::readNext<hash_value_type, little, unaligned>(Items);
+
+      // Determine the length of the key and the data.
+      const std::pair<offset_type, offset_type> &L =
+          Info::ReadKeyDataLength(Items);
+      offset_type ItemLen = L.first + L.second;
+
+      // Compare the hashes.  If they are not the same, skip the entry entirely.
+      if (ItemHash != KeyHash) {
+        Items += ItemLen;
+        continue;
+      }
+
+      // Read the key.
+      const internal_key_type &X =
+          InfoPtr->ReadKey((const unsigned char *const)Items, L.first);
+
+      // If the key doesn't match just skip reading the value.
+      if (!InfoPtr->EqualKey(X, IKey)) {
+        Items += ItemLen;
+        continue;
+      }
+
+      // The key matches!
+      return iterator(X, Items + L.first, L.second, InfoPtr);
+    }
+
+    return iterator();
+  }
+
+  iterator end() const { return iterator(); }
+
+  Info &getInfoObj() { return InfoObj; }
+
+  /// \brief Create the hash table.
+  ///
+  /// \param Buckets is the beginning of the hash table itself, which follows
+  /// the payload of entire structure. This is the value returned by
+  /// OnDiskHashTableGenerator::Emit.
+  ///
+  /// \param Base is the point from which all offsets into the structure are
+  /// based. This is offset 0 in the stream that was used when Emitting the
+  /// table.
+  static OnDiskChainedHashTable *Create(const unsigned char *Buckets,
+                                        const unsigned char *const Base,
+                                        const Info &InfoObj = Info()) {
+    using namespace llvm::support;
+    assert(Buckets > Base);
+    assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+           "buckets should be 4-byte aligned.");
+
+    offset_type NumBuckets =
+        endian::readNext<offset_type, little, aligned>(Buckets);
+    offset_type NumEntries =
+        endian::readNext<offset_type, little, aligned>(Buckets);
+    return new OnDiskChainedHashTable<Info>(NumBuckets, NumEntries, Buckets,
+                                            Base, InfoObj);
+  }
+};
+
+/// \brief Provides lookup and iteration over an on disk hash table.
+///
+/// \copydetails llvm::OnDiskChainedHashTable
+template <typename Info>
+class OnDiskIterableChainedHashTable : public OnDiskChainedHashTable<Info> {
+  const unsigned char *Payload;
+
+public:
+  typedef OnDiskChainedHashTable<Info>          base_type;
+  typedef typename base_type::internal_key_type internal_key_type;
+  typedef typename base_type::external_key_type external_key_type;
+  typedef typename base_type::data_type         data_type;
+  typedef typename base_type::hash_value_type   hash_value_type;
+  typedef typename base_type::offset_type       offset_type;
+
+  OnDiskIterableChainedHashTable(offset_type NumBuckets, offset_type NumEntries,
+                                 const unsigned char *Buckets,
+                                 const unsigned char *Payload,
+                                 const unsigned char *Base,
+                                 const Info &InfoObj = Info())
+      : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj),
+        Payload(Payload) {}
+
+  /// \brief Iterates over all of the keys in the table.
+  class key_iterator {
+    const unsigned char *Ptr;
+    offset_type NumItemsInBucketLeft;
+    offset_type NumEntriesLeft;
+    Info *InfoObj;
+
+  public:
+    typedef external_key_type value_type;
+
+    key_iterator(const unsigned char *const Ptr, offset_type NumEntries,
+                 Info *InfoObj)
+        : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
+          InfoObj(InfoObj) {}
+    key_iterator()
+        : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0),
+          InfoObj(0) {}
+
+    friend bool operator==(const key_iterator &X, const key_iterator &Y) {
+      return X.NumEntriesLeft == Y.NumEntriesLeft;
+    }
+    friend bool operator!=(const key_iterator &X, const key_iterator &Y) {
+      return X.NumEntriesLeft != Y.NumEntriesLeft;
+    }
+
+    key_iterator &operator++() { // Preincrement
+      using namespace llvm::support;
+      if (!NumItemsInBucketLeft) {
+        // 'Items' starts with a 16-bit unsigned integer representing the
+        // number of items in this bucket.
+        NumItemsInBucketLeft =
+            endian::readNext<uint16_t, little, unaligned>(Ptr);
+      }
+      Ptr += sizeof(hash_value_type); // Skip the hash.
+      // Determine the length of the key and the data.
+      const std::pair<offset_type, offset_type> &L =
+          Info::ReadKeyDataLength(Ptr);
+      Ptr += L.first + L.second;
+      assert(NumItemsInBucketLeft);
+      --NumItemsInBucketLeft;
+      assert(NumEntriesLeft);
+      --NumEntriesLeft;
+      return *this;
+    }
+    key_iterator operator++(int) { // Postincrement
+      key_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    value_type operator*() const {
+      const unsigned char *LocalPtr = Ptr;
+      if (!NumItemsInBucketLeft)
+        LocalPtr += 2; // number of items in bucket
+      LocalPtr += sizeof(hash_value_type); // Skip the hash.
+
+      // Determine the length of the key and the data.
+      const std::pair<offset_type, offset_type> &L =
+          Info::ReadKeyDataLength(LocalPtr);
+
+      // Read the key.
+      const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first);
+      return InfoObj->GetExternalKey(Key);
+    }
+  };
+
+  key_iterator key_begin() {
+    return key_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
+  }
+  key_iterator key_end() { return key_iterator(); }
+
+  iterator_range<key_iterator> keys() {
+    return make_range(key_begin(), key_end());
+  }
+
+  /// \brief Iterates over all the entries in the table, returning the data.
+  class data_iterator {
+    const unsigned char *Ptr;
+    offset_type NumItemsInBucketLeft;
+    offset_type NumEntriesLeft;
+    Info *InfoObj;
+
+  public:
+    typedef data_type value_type;
+
+    data_iterator(const unsigned char *const Ptr, offset_type NumEntries,
+                  Info *InfoObj)
+        : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
+          InfoObj(InfoObj) {}
+    data_iterator()
+        : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0),
+          InfoObj(nullptr) {}
+
+    bool operator==(const data_iterator &X) const {
+      return X.NumEntriesLeft == NumEntriesLeft;
+    }
+    bool operator!=(const data_iterator &X) const {
+      return X.NumEntriesLeft != NumEntriesLeft;
+    }
+
+    data_iterator &operator++() { // Preincrement
+      using namespace llvm::support;
+      if (!NumItemsInBucketLeft) {
+        // 'Items' starts with a 16-bit unsigned integer representing the
+        // number of items in this bucket.
+        NumItemsInBucketLeft =
+            endian::readNext<uint16_t, little, unaligned>(Ptr);
+      }
+      Ptr += sizeof(hash_value_type); // Skip the hash.
+      // Determine the length of the key and the data.
+      const std::pair<offset_type, offset_type> &L =
+          Info::ReadKeyDataLength(Ptr);
+      Ptr += L.first + L.second;
+      assert(NumItemsInBucketLeft);
+      --NumItemsInBucketLeft;
+      assert(NumEntriesLeft);
+      --NumEntriesLeft;
+      return *this;
+    }
+    data_iterator operator++(int) { // Postincrement
+      data_iterator tmp = *this; ++*this; return tmp;
+    }
+
+    value_type operator*() const {
+      const unsigned char *LocalPtr = Ptr;
+      if (!NumItemsInBucketLeft)
+        LocalPtr += 2; // number of items in bucket
+      LocalPtr += sizeof(hash_value_type); // Skip the hash.
+
+      // Determine the length of the key and the data.
+      const std::pair<offset_type, offset_type> &L =
+          Info::ReadKeyDataLength(LocalPtr);
+
+      // Read the key.
+      const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first);
+      return InfoObj->ReadData(Key, LocalPtr + L.first, L.second);
+    }
+  };
+
+  data_iterator data_begin() {
+    return data_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
+  }
+  data_iterator data_end() { return data_iterator(); }
+
+  iterator_range<data_iterator> data() {
+    return make_range(data_begin(), data_end());
+  }
+
+  /// \brief Create the hash table.
+  ///
+  /// \param Buckets is the beginning of the hash table itself, which follows
+  /// the payload of entire structure. This is the value returned by
+  /// OnDiskHashTableGenerator::Emit.
+  ///
+  /// \param Payload is the beginning of the data contained in the table.  This
+  /// is Base plus any padding or header data that was stored, ie, the offset
+  /// that the stream was at when calling Emit.
+  ///
+  /// \param Base is the point from which all offsets into the structure are
+  /// based. This is offset 0 in the stream that was used when Emitting the
+  /// table.
+  static OnDiskIterableChainedHashTable *
+  Create(const unsigned char *Buckets, const unsigned char *const Payload,
+         const unsigned char *const Base, const Info &InfoObj = Info()) {
+    using namespace llvm::support;
+    assert(Buckets > Base);
+    assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+           "buckets should be 4-byte aligned.");
+
+    offset_type NumBuckets =
+        endian::readNext<offset_type, little, aligned>(Buckets);
+    offset_type NumEntries =
+        endian::readNext<offset_type, little, aligned>(Buckets);
+    return new OnDiskIterableChainedHashTable<Info>(
+        NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj);
+  }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
diff --git a/include/llvm/Support/OutputBuffer.h b/include/llvm/Support/OutputBuffer.h
new file mode 100644
index 0000000..6b98e99
--- /dev/null
+++ b/include/llvm/Support/OutputBuffer.h
@@ -0,0 +1,166 @@
+//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods to output values to a data buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
+#define LLVM_SUPPORT_OUTPUTBUFFER_H
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+  class OutputBuffer {
+    /// Output buffer.
+    std::vector<unsigned char> &Output;
+
+    /// is64Bit/isLittleEndian - This information is inferred from the target
+    /// machine directly, indicating what header values and flags to set.
+    bool is64Bit, isLittleEndian;
+  public:
+    OutputBuffer(std::vector<unsigned char> &Out,
+                 bool is64bit, bool le)
+      : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
+
+    // align - Emit padding into the file until the current output position is
+    // aligned to the specified power of two boundary.
+    void align(unsigned Boundary) {
+      assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+             "Must align to 2^k boundary");
+      size_t Size = Output.size();
+
+      if (Size & (Boundary - 1)) {
+        // Add padding to get alignment to the correct place.
+        size_t Pad = Boundary - (Size & (Boundary - 1));
+        Output.resize(Size + Pad);
+      }
+    }
+
+    //===------------------------------------------------------------------===//
+    // Out Functions - Output the specified value to the data buffer.
+
+    void outbyte(unsigned char X) {
+      Output.push_back(X);
+    }
+    void outhalf(unsigned short X) {
+      if (isLittleEndian) {
+        Output.push_back(X & 255);
+        Output.push_back(X >> 8);
+      } else {
+        Output.push_back(X >> 8);
+        Output.push_back(X & 255);
+      }
+    }
+    void outword(unsigned X) {
+      if (isLittleEndian) {
+        Output.push_back((X >>  0) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >> 24) & 255);
+      } else {
+        Output.push_back((X >> 24) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >>  0) & 255);
+      }
+    }
+    void outxword(uint64_t X) {
+      if (isLittleEndian) {
+        Output.push_back(unsigned(X >>  0) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 56) & 255);
+      } else {
+        Output.push_back(unsigned(X >> 56) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >>  0) & 255);
+      }
+    }
+    void outaddr32(unsigned X) {
+      outword(X);
+    }
+    void outaddr64(uint64_t X) {
+      outxword(X);
+    }
+    void outaddr(uint64_t X) {
+      if (!is64Bit)
+        outword((unsigned)X);
+      else
+        outxword(X);
+    }
+    void outstring(const std::string &S, unsigned Length) {
+      unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
+        ? static_cast<unsigned>(S.length()) : Length;
+      unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
+        ? Length - static_cast<unsigned>(S.length()) : 0;
+
+      for (unsigned i = 0; i < len_to_copy; ++i)
+        outbyte(S[i]);
+
+      for (unsigned i = 0; i < len_to_fill; ++i)
+        outbyte(0);
+    }
+
+    //===------------------------------------------------------------------===//
+    // Fix Functions - Replace an existing entry at an offset.
+
+    void fixhalf(unsigned short X, unsigned Offset) {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
+    }
+    void fixword(unsigned X, unsigned Offset) {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
+      P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
+      P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
+    }
+    void fixxword(uint64_t X, unsigned Offset) {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 56)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 48)) & 255;
+      P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255;
+      P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255;
+      P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255;
+      P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255;
+      P[6] = (X >> (isLittleEndian ? 48 :  8)) & 255;
+      P[7] = (X >> (isLittleEndian ? 56 :  0)) & 255;
+    }
+    void fixaddr(uint64_t X, unsigned Offset) {
+      if (!is64Bit)
+        fixword((unsigned)X, Offset);
+      else
+        fixxword(X, Offset);
+    }
+
+    unsigned char &operator[](unsigned Index) {
+      return Output[Index];
+    }
+    const unsigned char &operator[](unsigned Index) const {
+      return Output[Index];
+    }
+  };
+
+} // end llvm namespace
+
+#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
new file mode 100644
index 0000000..cf821f0
--- /dev/null
+++ b/include/llvm/Support/Path.h
@@ -0,0 +1,400 @@
+//===- llvm/Support/Path.h - Path Operating System Concept ------*- 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 llvm::sys::path namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATH_H
+#define LLVM_SUPPORT_PATH_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include <iterator>
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+/// @name Lexical Component Iterator
+/// @{
+
+/// @brief Path iterator.
+///
+/// This is a bidirectional iterator that iterates over the individual
+/// components in \a path. The forward traversal order is as follows:
+/// * The root-name element, if present.
+/// * The root-directory element, if present.
+/// * Each successive filename element, if present.
+/// * Dot, if one or more trailing non-root slash characters are present.
+/// The backwards traversal order is the reverse of forward traversal.
+///
+/// Iteration examples. Each component is separated by ',':
+/// @code
+///   /          => /
+///   /foo       => /,foo
+///   foo/       => foo,.
+///   /foo/bar   => /,foo,bar
+///   ../        => ..,.
+///   C:\foo\bar => C:,/,foo,bar
+/// @endcode
+class const_iterator {
+  StringRef Path;      ///< The entire path.
+  StringRef Component; ///< The current component. Not necessarily in Path.
+  size_t    Position;  ///< The iterators current position within Path.
+
+  // An end iterator has Position = Path.size() + 1.
+  friend const_iterator begin(StringRef path);
+  friend const_iterator end(StringRef path);
+
+public:
+  typedef const StringRef value_type;
+  typedef ptrdiff_t difference_type;
+  typedef value_type &reference;
+  typedef value_type *pointer;
+  typedef std::bidirectional_iterator_tag iterator_category;
+
+  reference operator*() const { return Component; }
+  pointer   operator->() const { return &Component; }
+  const_iterator &operator++();    // preincrement
+  const_iterator &operator++(int); // postincrement
+  const_iterator &operator--();    // predecrement
+  const_iterator &operator--(int); // postdecrement
+  bool operator==(const const_iterator &RHS) const;
+  bool operator!=(const const_iterator &RHS) const;
+
+  /// @brief Difference in bytes between this and RHS.
+  ptrdiff_t operator-(const const_iterator &RHS) const;
+};
+
+typedef std::reverse_iterator<const_iterator> reverse_iterator;
+
+/// @brief Get begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first component of \a path.
+const_iterator begin(StringRef path);
+
+/// @brief Get end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the end of \a path.
+const_iterator end(StringRef path);
+
+/// @brief Get reverse begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first reverse component of \a path.
+inline reverse_iterator rbegin(StringRef path) {
+  return reverse_iterator(end(path));
+}
+
+/// @brief Get reverse end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the reverse end of \a path.
+inline reverse_iterator rend(StringRef path) {
+  return reverse_iterator(begin(path));
+}
+
+/// @}
+/// @name Lexical Modifiers
+/// @{
+
+/// @brief Remove the last component from \a path unless it is the root dir.
+///
+/// @code
+///   directory/filename.cpp => directory/
+///   directory/             => directory
+///   filename.cpp           => <empty>
+///   /                      => /
+/// @endcode
+///
+/// @param path A path that is modified to not have a file component.
+void remove_filename(SmallVectorImpl<char> &path);
+
+/// @brief Replace the file extension of \a path with \a extension.
+///
+/// @code
+///   ./filename.cpp => ./filename.extension
+///   ./filename     => ./filename.extension
+///   ./             => ./.extension
+/// @endcode
+///
+/// @param path A path that has its extension replaced with \a extension.
+/// @param extension The extension to be added. It may be empty. It may also
+///                  optionally start with a '.', if it does not, one will be
+///                  prepended.
+void replace_extension(SmallVectorImpl<char> &path, const Twine &extension);
+
+/// @brief Append to path.
+///
+/// @code
+///   /foo  + bar/f => /foo/bar/f
+///   /foo/ + bar/f => /foo/bar/f
+///   foo   + bar/f => foo/bar/f
+/// @endcode
+///
+/// @param path Set to \a path + \a component.
+/// @param a The component to be appended to \a path.
+void append(SmallVectorImpl<char> &path, const Twine &a,
+                                         const Twine &b = "",
+                                         const Twine &c = "",
+                                         const Twine &d = "");
+
+/// @brief Append to path.
+///
+/// @code
+///   /foo  + [bar,f] => /foo/bar/f
+///   /foo/ + [bar,f] => /foo/bar/f
+///   foo   + [bar,f] => foo/bar/f
+/// @endcode
+///
+/// @param path Set to \a path + [\a begin, \a end).
+/// @param begin Start of components to append.
+/// @param end One past the end of components to append.
+void append(SmallVectorImpl<char> &path,
+            const_iterator begin, const_iterator end);
+
+/// @}
+/// @name Transforms (or some other better name)
+/// @{
+
+/// Convert path to the native form. This is used to give paths to users and
+/// operating system calls in the platform's normal way. For example, on Windows
+/// all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+/// @param result Holds the result of the transformation.
+void native(const Twine &path, SmallVectorImpl<char> &result);
+
+/// Convert path to the native form in place. This is used to give paths to
+/// users and operating system calls in the platform's normal way. For example,
+/// on Windows all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+void native(SmallVectorImpl<char> &path);
+
+/// @}
+/// @name Lexical Observers
+/// @{
+
+/// @brief Get root name.
+///
+/// @code
+///   //net/hello => //net
+///   c:/hello    => c: (on Windows, on other platforms nothing)
+///   /hello      => <empty>
+/// @endcode
+///
+/// @param path Input path.
+/// @result The root name of \a path if it has one, otherwise "".
+const StringRef root_name(StringRef path);
+
+/// @brief Get root directory.
+///
+/// @code
+///   /goo/hello => /
+///   c:/hello   => /
+///   d/file.txt => <empty>
+/// @endcode
+///
+/// @param path Input path.
+/// @result The root directory of \a path if it has one, otherwise
+///               "".
+const StringRef root_directory(StringRef path);
+  
+/// @brief Get root path.
+///
+/// Equivalent to root_name + root_directory.
+///
+/// @param path Input path.
+/// @result The root path of \a path if it has one, otherwise "".
+const StringRef root_path(StringRef path);
+
+/// @brief Get relative path.
+///
+/// @code
+///   C:\hello\world => hello\world
+///   foo/bar        => foo/bar
+///   /foo/bar       => foo/bar
+/// @endcode
+///
+/// @param path Input path.
+/// @result The path starting after root_path if one exists, otherwise "".
+const StringRef relative_path(StringRef path);
+
+/// @brief Get parent path.
+///
+/// @code
+///   /          => <empty>
+///   /foo       => /
+///   foo/../bar => foo/..
+/// @endcode
+///
+/// @param path Input path.
+/// @result The parent path of \a path if one exists, otherwise "".
+const StringRef parent_path(StringRef path);
+
+/// @brief Get filename.
+///
+/// @code
+///   /foo.txt    => foo.txt
+///   .          => .
+///   ..         => ..
+///   /          => /
+/// @endcode
+///
+/// @param path Input path.
+/// @result The filename part of \a path. This is defined as the last component
+///         of \a path.
+const StringRef filename(StringRef path);
+
+/// @brief Get stem.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename ending at (but not including) the last dot. Otherwise
+/// it is filename.
+///
+/// @code
+///   /foo/bar.txt => bar
+///   /foo/bar     => bar
+///   /foo/.txt    => <empty>
+///   /foo/.       => .
+///   /foo/..      => ..
+/// @endcode
+///
+/// @param path Input path.
+/// @result The stem of \a path.
+const StringRef stem(StringRef path);
+
+/// @brief Get extension.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// substring of filename starting at (and including) the last dot, and ending
+/// at the end of \a path. Otherwise "".
+///
+/// @code
+///   /foo/bar.txt => .txt
+///   /foo/bar     => <empty>
+///   /foo/.txt    => .txt
+/// @endcode
+///
+/// @param path Input path.
+/// @result The extension of \a path.
+const StringRef extension(StringRef path);
+
+/// @brief Check whether the given char is a path separator on the host OS.
+///
+/// @param value a character
+/// @result true if \a value is a path separator character on the host OS
+bool is_separator(char value);
+
+/// @brief Return the preferred separator for this platform.
+///
+/// @result StringRef of the preferred separator, null-terminated.
+const StringRef get_separator();
+
+/// @brief Get the typical temporary directory for the system, e.g., 
+/// "/var/tmp" or "C:/TEMP"
+///
+/// @param erasedOnReboot Whether to favor a path that is erased on reboot
+/// rather than one that potentially persists longer. This parameter will be
+/// ignored if the user or system has set the typical environment variable
+/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory.
+///
+/// @param result Holds the resulting path name.
+void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
+
+/// @brief Get the user's home directory.
+///
+/// @param result Holds the resulting path name.
+/// @result True if a home directory is set, false otherwise.
+bool home_directory(SmallVectorImpl<char> &result);
+
+/// @brief Has root name?
+///
+/// root_name != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root name, false otherwise.
+bool has_root_name(const Twine &path);
+
+/// @brief Has root directory?
+///
+/// root_directory != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root directory, false otherwise.
+bool has_root_directory(const Twine &path);
+
+/// @brief Has root path?
+///
+/// root_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root path, false otherwise.
+bool has_root_path(const Twine &path);
+
+/// @brief Has relative path?
+///
+/// relative_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a relative path, false otherwise.
+bool has_relative_path(const Twine &path);
+
+/// @brief Has parent path?
+///
+/// parent_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a parent path, false otherwise.
+bool has_parent_path(const Twine &path);
+
+/// @brief Has filename?
+///
+/// filename != ""
+///
+/// @param path Input path.
+/// @result True if the path has a filename, false otherwise.
+bool has_filename(const Twine &path);
+
+/// @brief Has stem?
+///
+/// stem != ""
+///
+/// @param path Input path.
+/// @result True if the path has a stem, false otherwise.
+bool has_stem(const Twine &path);
+
+/// @brief Has extension?
+///
+/// extension != ""
+///
+/// @param path Input path.
+/// @result True if the path has a extension, false otherwise.
+bool has_extension(const Twine &path);
+
+/// @brief Is path absolute?
+///
+/// @param path Input path.
+/// @result True if the path is absolute, false if it is not.
+bool is_absolute(const Twine &path);
+
+/// @brief Is path relative?
+///
+/// @param path Input path.
+/// @result True if the path is relative, false if it is not.
+bool is_relative(const Twine &path);
+
+} // end namespace path
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PluginLoader.h b/include/llvm/Support/PluginLoader.h
new file mode 100644
index 0000000..bdbb134
--- /dev/null
+++ b/include/llvm/Support/PluginLoader.h
@@ -0,0 +1,37 @@
+//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A tool can #include this file to get a -load option that allows the user to
+// load arbitrary shared objects into the tool's address space.  Note that this
+// header can only be included by a program ONCE, so it should never to used by
+// library authors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PLUGINLOADER_H
+#define LLVM_SUPPORT_PLUGINLOADER_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+  struct PluginLoader {
+    void operator=(const std::string &Filename);
+    static unsigned getNumPlugins();
+    static std::string& getPlugin(unsigned num);
+  };
+
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+  // This causes operator= above to be invoked for every -load option.
+  static cl::opt<PluginLoader, false, cl::parser<std::string> >
+    LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
+            cl::desc("Load the specified plugin"));
+#endif
+}
+
+#endif
diff --git a/include/llvm/Support/PointerLikeTypeTraits.h b/include/llvm/Support/PointerLikeTypeTraits.h
new file mode 100644
index 0000000..8370821
--- /dev/null
+++ b/include/llvm/Support/PointerLikeTypeTraits.h
@@ -0,0 +1,81 @@
+//===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- 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 PointerLikeTypeTraits class.  This allows data
+// structures to reason about pointers and other things that are pointer sized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  
+/// PointerLikeTypeTraits - This is a traits object that is used to handle
+/// pointer types and things that are just wrappers for pointers as a uniform
+/// entity.
+template <typename T>
+class PointerLikeTypeTraits {
+  // getAsVoidPointer
+  // getFromVoidPointer
+  // getNumLowBitsAvailable
+};
+
+// Provide PointerLikeTypeTraits for non-cvr pointers.
+template<typename T>
+class PointerLikeTypeTraits<T*> {
+public:
+  static inline void *getAsVoidPointer(T* P) { return P; }
+  static inline T *getFromVoidPointer(void *P) {
+    return static_cast<T*>(P);
+  }
+  
+  /// Note, we assume here that malloc returns objects at least 4-byte aligned.
+  /// However, this may be wrong, or pointers may be from something other than
+  /// malloc.  In this case, you should specialize this template to reduce this.
+  ///
+  /// All clients should use assertions to do a run-time check to ensure that
+  /// this is actually true.
+  enum { NumLowBitsAvailable = 2 };
+};
+  
+// Provide PointerLikeTypeTraits for const pointers.
+template<typename T>
+class PointerLikeTypeTraits<const T*> {
+  typedef PointerLikeTypeTraits<T*> NonConst;
+
+public:
+  static inline const void *getAsVoidPointer(const T* P) {
+    return NonConst::getAsVoidPointer(const_cast<T*>(P));
+  }
+  static inline const T *getFromVoidPointer(const void *P) {
+    return NonConst::getFromVoidPointer(const_cast<void*>(P));
+  }
+  enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+};
+
+// Provide PointerLikeTypeTraits for uintptr_t.
+template<>
+class PointerLikeTypeTraits<uintptr_t> {
+public:
+  static inline void *getAsVoidPointer(uintptr_t P) {
+    return reinterpret_cast<void*>(P);
+  }
+  static inline uintptr_t getFromVoidPointer(void *P) {
+    return reinterpret_cast<uintptr_t>(P);
+  }
+  // No bits are available!
+  enum { NumLowBitsAvailable = 0 };
+};
+  
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
new file mode 100644
index 0000000..914141a
--- /dev/null
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -0,0 +1,71 @@
+//===- llvm/Support/PrettyStackTrace.h - Pretty Crash Handling --*- 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 PrettyStackTraceEntry class, which is used to make
+// crashes give more contextual information about what the program was doing
+// when it crashed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H
+#define LLVM_SUPPORT_PRETTYSTACKTRACE_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class raw_ostream;
+
+  void EnablePrettyStackTrace();
+
+  /// PrettyStackTraceEntry - This class is used to represent a frame of the
+  /// "pretty" stack trace that is dumped when a program crashes. You can define
+  /// subclasses of this and declare them on the program stack: when they are
+  /// constructed and destructed, they will add their symbolic frames to a
+  /// virtual stack trace.  This gets dumped out if the program crashes.
+  class PrettyStackTraceEntry {
+    const PrettyStackTraceEntry *NextEntry;
+    PrettyStackTraceEntry(const PrettyStackTraceEntry &) LLVM_DELETED_FUNCTION;
+    void operator=(const PrettyStackTraceEntry&) LLVM_DELETED_FUNCTION;
+  public:
+    PrettyStackTraceEntry();
+    virtual ~PrettyStackTraceEntry();
+
+    /// print - Emit information about this stack frame to OS.
+    virtual void print(raw_ostream &OS) const = 0;
+
+    /// getNextEntry - Return the next entry in the list of frames.
+    const PrettyStackTraceEntry *getNextEntry() const { return NextEntry; }
+  };
+
+  /// PrettyStackTraceString - This object prints a specified string (which
+  /// should not contain newlines) to the stream as the stack trace when a crash
+  /// occurs.
+  class PrettyStackTraceString : public PrettyStackTraceEntry {
+    const char *Str;
+  public:
+    PrettyStackTraceString(const char *str) : Str(str) {}
+    void print(raw_ostream &OS) const override;
+  };
+
+  /// PrettyStackTraceProgram - This object prints a specified program arguments
+  /// to the stream as the stack trace when a crash occurs.
+  class PrettyStackTraceProgram : public PrettyStackTraceEntry {
+    int ArgC;
+    const char *const *ArgV;
+  public:
+    PrettyStackTraceProgram(int argc, const char * const*argv)
+      : ArgC(argc), ArgV(argv) {
+      EnablePrettyStackTrace();
+    }
+    void print(raw_ostream &OS) const override;
+  };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
new file mode 100644
index 0000000..30973de
--- /dev/null
+++ b/include/llvm/Support/Process.h
@@ -0,0 +1,273 @@
+//===- llvm/Support/Process.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Provides a library for accessing information about this process and other
+/// processes on the operating system. Also provides means of spawning
+/// subprocess for commands. The design of this library is modeled after the
+/// proposed design of the Boost.Process library, and is design specifically to
+/// follow the style of standard libraries and potentially become a proposal
+/// for a standard library.
+///
+/// This file declares the llvm::sys::Process class which contains a collection
+/// of legacy static interfaces for extracting various information about the
+/// current process. The goal is to migrate users of this API over to the new
+/// interfaces.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PROCESS_H
+#define LLVM_SUPPORT_PROCESS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/TimeValue.h"
+#include <system_error>
+
+namespace llvm {
+class StringRef;
+
+namespace sys {
+
+class self_process;
+
+/// \brief Generic base class which exposes information about an operating
+/// system process.
+///
+/// This base class is the core interface behind any OS process. It exposes
+/// methods to query for generic information about a particular process.
+///
+/// Subclasses implement this interface based on the mechanisms available, and
+/// can optionally expose more interfaces unique to certain process kinds.
+class process {
+protected:
+  /// \brief Only specific subclasses of process objects can be destroyed.
+  virtual ~process();
+
+public:
+  /// \brief Operating system specific type to identify a process.
+  ///
+  /// Note that the windows one is defined to 'unsigned long' as this is the
+  /// documented type for DWORD on windows, and we don't want to pull in the
+  /// Windows headers here.
+#if defined(LLVM_ON_UNIX)
+  typedef pid_t id_type;
+#elif defined(LLVM_ON_WIN32)
+  typedef unsigned long id_type; // Must match the type of DWORD.
+#else
+#error Unsupported operating system.
+#endif
+
+  /// \brief Get the operating system specific identifier for this process.
+  virtual id_type get_id() = 0;
+
+  /// \brief Get the user time consumed by this process.
+  ///
+  /// Note that this is often an approximation and may be zero on platforms
+  /// where we don't have good support for the functionality.
+  virtual TimeValue get_user_time() const = 0;
+
+  /// \brief Get the system time consumed by this process.
+  ///
+  /// Note that this is often an approximation and may be zero on platforms
+  /// where we don't have good support for the functionality.
+  virtual TimeValue get_system_time() const = 0;
+
+  /// \brief Get the wall time consumed by this process.
+  ///
+  /// Note that this is often an approximation and may be zero on platforms
+  /// where we don't have good support for the functionality.
+  virtual TimeValue get_wall_time() const = 0;
+
+  /// \name Static factory routines for processes.
+  /// @{
+
+  /// \brief Get the process object for the current process.
+  static self_process *get_self();
+
+  /// @}
+
+};
+
+/// \brief The specific class representing the current process.
+///
+/// The current process can both specialize the implementation of the routines
+/// and can expose certain information not available for other OS processes.
+class self_process : public process {
+  friend class process;
+
+  /// \brief Private destructor, as users shouldn't create objects of this
+  /// type.
+  virtual ~self_process();
+
+public:
+  id_type get_id() override;
+  TimeValue get_user_time() const override;
+  TimeValue get_system_time() const override;
+  TimeValue get_wall_time() const override;
+
+  /// \name Process configuration (sysconf on POSIX)
+  /// @{
+
+  /// \brief Get the virtual memory page size.
+  ///
+  /// Query the operating system for this process's page size.
+  size_t page_size() const { return PageSize; };
+
+  /// @}
+
+private:
+  /// \name Cached process state.
+  /// @{
+
+  /// \brief Cached page size, this cannot vary during the life of the process.
+  size_t PageSize;
+
+  /// @}
+
+  /// \brief Constructor, used by \c process::get_self() only.
+  self_process();
+};
+
+
+/// \brief A collection of legacy interfaces for querying information about the
+/// current executing process.
+class Process {
+public:
+  /// \brief Return process memory usage.
+  /// This static function will return the total amount of memory allocated
+  /// by the process. This only counts the memory allocated via the malloc,
+  /// calloc and realloc functions and includes any "free" holes in the
+  /// allocated space.
+  static size_t GetMallocUsage();
+
+  /// This static function will set \p user_time to the amount of CPU time
+  /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
+  /// time spent in system (kernel) mode.  If the operating system does not
+  /// support collection of these metrics, a zero TimeValue will be for both
+  /// values.
+  /// \param elapsed Returns the TimeValue::now() giving current time
+  /// \param user_time Returns the current amount of user time for the process
+  /// \param sys_time Returns the current amount of system time for the process
+  static void GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+                           TimeValue &sys_time);
+
+  /// This function makes the necessary calls to the operating system to
+  /// prevent core files or any other kind of large memory dumps that can
+  /// occur when a program fails.
+  /// @brief Prevent core file generation.
+  static void PreventCoreFiles();
+
+  // This function returns the environment variable \arg name's value as a UTF-8
+  // string. \arg Name is assumed to be in UTF-8 encoding too.
+  static Optional<std::string> GetEnv(StringRef name);
+
+  /// This function searches for an existing file in the list of directories
+  /// in a PATH like environment variable, and returns the first file found,
+  /// according to the order of the entries in the PATH like environment
+  /// variable.
+  static Optional<std::string> FindInEnvPath(const std::string& EnvName,
+                                             const std::string& FileName);
+
+  /// This function returns a SmallVector containing the arguments passed from
+  /// the operating system to the program.  This function expects to be handed
+  /// the vector passed in from main.
+  static std::error_code
+  GetArgumentVector(SmallVectorImpl<const char *> &Args,
+                    ArrayRef<const char *> ArgsFromMain,
+                    SpecificBumpPtrAllocator<char> &ArgAllocator);
+
+  /// This function determines if the standard input is connected directly
+  /// to a user's input (keyboard probably), rather than coming from a file
+  /// or pipe.
+  static bool StandardInIsUserInput();
+
+  /// This function determines if the standard output is connected to a
+  /// "tty" or "console" window. That is, the output would be displayed to
+  /// the user rather than being put on a pipe or stored in a file.
+  static bool StandardOutIsDisplayed();
+
+  /// This function determines if the standard error is connected to a
+  /// "tty" or "console" window. That is, the output would be displayed to
+  /// the user rather than being put on a pipe or stored in a file.
+  static bool StandardErrIsDisplayed();
+
+  /// This function determines if the given file descriptor is connected to
+  /// a "tty" or "console" window. That is, the output would be displayed to
+  /// the user rather than being put on a pipe or stored in a file.
+  static bool FileDescriptorIsDisplayed(int fd);
+
+  /// This function determines if the given file descriptor is displayd and
+  /// supports colors.
+  static bool FileDescriptorHasColors(int fd);
+
+  /// This function determines the number of columns in the window
+  /// if standard output is connected to a "tty" or "console"
+  /// window. If standard output is not connected to a tty or
+  /// console, or if the number of columns cannot be determined,
+  /// this routine returns zero.
+  static unsigned StandardOutColumns();
+
+  /// This function determines the number of columns in the window
+  /// if standard error is connected to a "tty" or "console"
+  /// window. If standard error is not connected to a tty or
+  /// console, or if the number of columns cannot be determined,
+  /// this routine returns zero.
+  static unsigned StandardErrColumns();
+
+  /// This function determines whether the terminal connected to standard
+  /// output supports colors. If standard output is not connected to a
+  /// terminal, this function returns false.
+  static bool StandardOutHasColors();
+
+  /// This function determines whether the terminal connected to standard
+  /// error supports colors. If standard error is not connected to a
+  /// terminal, this function returns false.
+  static bool StandardErrHasColors();
+
+  /// Enables or disables whether ANSI escape sequences are used to output
+  /// colors. This only has an effect on Windows.
+  /// Note: Setting this option is not thread-safe and should only be done
+  /// during initialization.
+  static void UseANSIEscapeCodes(bool enable);
+
+  /// Whether changing colors requires the output to be flushed.
+  /// This is needed on systems that don't support escape sequences for
+  /// changing colors.
+  static bool ColorNeedsFlush();
+
+  /// This function returns the colorcode escape sequences.
+  /// If ColorNeedsFlush() is true then this function will change the colors
+  /// and return an empty escape sequence. In that case it is the
+  /// responsibility of the client to flush the output stream prior to
+  /// calling this function.
+  static const char *OutputColor(char c, bool bold, bool bg);
+
+  /// Same as OutputColor, but only enables the bold attribute.
+  static const char *OutputBold(bool bg);
+
+  /// This function returns the escape sequence to reverse forground and
+  /// background colors.
+  static const char *OutputReverse();
+
+  /// Resets the terminals colors, or returns an escape sequence to do so.
+  static const char *ResetColor();
+
+  /// Get the result of a process wide random number generator. The
+  /// generator will be automatically seeded in non-deterministic fashion.
+  static unsigned GetRandomNumber();
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
new file mode 100644
index 0000000..51279a9
--- /dev/null
+++ b/include/llvm/Support/Program.h
@@ -0,0 +1,152 @@
+//===- llvm/Support/Program.h ------------------------------------*- 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 llvm::sys::Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PROGRAM_H
+#define LLVM_SUPPORT_PROGRAM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Path.h"
+#include <system_error>
+
+namespace llvm {
+namespace sys {
+
+  /// This is the OS-specific separator for PATH like environment variables:
+  // a colon on Unix or a semicolon on Windows.
+#if defined(LLVM_ON_UNIX)
+  const char EnvPathSeparator = ':';
+#elif defined (LLVM_ON_WIN32)
+  const char EnvPathSeparator = ';';
+#endif
+
+/// @brief This struct encapsulates information about a process.
+struct ProcessInfo {
+#if defined(LLVM_ON_UNIX)
+  typedef pid_t ProcessId;
+#elif defined(LLVM_ON_WIN32)
+  typedef unsigned long ProcessId; // Must match the type of DWORD on Windows.
+  typedef void * HANDLE; // Must match the type of HANDLE on Windows.
+  /// The handle to the process (available on Windows only).
+  HANDLE ProcessHandle;
+#else
+#error "ProcessInfo is not defined for this platform!"
+#endif
+
+  /// The process identifier.
+  ProcessId Pid;
+
+  /// The return code, set after execution.
+  int ReturnCode;
+
+  ProcessInfo();
+};
+
+  /// This function attempts to locate a program in the operating
+  /// system's file system using some pre-determined set of locations to search
+  /// (e.g. the PATH on Unix). Paths with slashes are returned unmodified.
+  ///
+  /// It does not perform hashing as a shell would but instead stats each PATH
+  /// entry individually so should generally be avoided. Core LLVM library
+  /// functions and options should instead require fully specified paths.
+  ///
+  /// @returns A string containing the path of the program or an empty string if
+  /// the program could not be found.
+  std::string FindProgramByName(const std::string& name);
+
+  // These functions change the specified standard stream (stdin or stdout) to
+  // binary mode. They return errc::success if the specified stream
+  // was changed. Otherwise a platform dependent error is returned.
+  std::error_code ChangeStdinToBinary();
+  std::error_code ChangeStdoutToBinary();
+
+  /// This function executes the program using the arguments provided.  The
+  /// invoked program will inherit the stdin, stdout, and stderr file
+  /// descriptors, the environment and other configuration settings of the
+  /// invoking program.
+  /// This function waits for the program to finish, so should be avoided in
+  /// library functions that aren't expected to block. Consider using
+  /// ExecuteNoWait() instead.
+  /// @returns an integer result code indicating the status of the program.
+  /// A zero or positive value indicates the result code of the program.
+  /// -1 indicates failure to execute
+  /// -2 indicates a crash during execution or timeout
+  int ExecuteAndWait(
+      StringRef Program, ///< Path of the program to be executed. It is
+      /// presumed this is the result of the FindProgramByName method.
+      const char **args, ///< A vector of strings that are passed to the
+      ///< program.  The first element should be the name of the program.
+      ///< The list *must* be terminated by a null char* entry.
+      const char **env = nullptr, ///< An optional vector of strings to use for
+      ///< the program's environment. If not provided, the current program's
+      ///< environment will be used.
+      const StringRef **redirects = nullptr, ///< An optional array of pointers
+      ///< to paths. If the array is null, no redirection is done. The array
+      ///< should have a size of at least three. The inferior process's
+      ///< stdin(0), stdout(1), and stderr(2) will be redirected to the
+      ///< corresponding paths.
+      ///< When an empty path is passed in, the corresponding file
+      ///< descriptor will be disconnected (ie, /dev/null'd) in a portable
+      ///< way.
+      unsigned secondsToWait = 0, ///< If non-zero, this specifies the amount
+      ///< of time to wait for the child process to exit. If the time
+      ///< expires, the child is killed and this call returns. If zero,
+      ///< this function will wait until the child finishes or forever if
+      ///< it doesn't.
+      unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
+      ///< of memory can be allocated by process. If memory usage will be
+      ///< higher limit, the child is killed and this call returns. If zero
+      ///< - no memory limit.
+      std::string *ErrMsg = nullptr, ///< If non-zero, provides a pointer to a
+      ///< string instance in which error messages will be returned. If the
+      ///< string is non-empty upon return an error occurred while invoking the
+      ///< program.
+      bool *ExecutionFailed = nullptr);
+
+  /// Similar to ExecuteAndWait, but returns immediately.
+  /// @returns The \see ProcessInfo of the newly launced process.
+  /// \note On Microsoft Windows systems, users will need to either call \see
+  /// Wait until the process finished execution or win32 CloseHandle() API on
+  /// ProcessInfo.ProcessHandle to avoid memory leaks.
+  ProcessInfo
+  ExecuteNoWait(StringRef Program, const char **args, const char **env = nullptr,
+                const StringRef **redirects = nullptr, unsigned memoryLimit = 0,
+                std::string *ErrMsg = nullptr, bool *ExecutionFailed = nullptr);
+
+  /// Return true if the given arguments fit within system-specific
+  /// argument length limits.
+  bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args);
+
+  /// This function waits for the process specified by \p PI to finish.
+  /// \returns A \see ProcessInfo struct with Pid set to:
+  /// \li The process id of the child process if the child process has changed
+  /// state.
+  /// \li 0 if the child process has not changed state.
+  /// \note Users of this function should always check the ReturnCode member of
+  /// the \see ProcessInfo returned from this function.
+  ProcessInfo Wait(
+      const ProcessInfo &PI, ///< The child process that should be waited on.
+      unsigned SecondsToWait, ///< If non-zero, this specifies the amount of
+      ///< time to wait for the child process to exit. If the time expires, the
+      ///< child is killed and this function returns. If zero, this function
+      ///< will perform a non-blocking wait on the child process.
+      bool WaitUntilTerminates, ///< If true, ignores \p SecondsToWait and waits
+      ///< until child has terminated.
+      std::string *ErrMsg = nullptr ///< If non-zero, provides a pointer to a
+      ///< string instance in which error messages will be returned. If the
+      ///< string is non-empty upon return an error occurred while invoking the
+      ///< program.
+      );
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h
new file mode 100644
index 0000000..935b307
--- /dev/null
+++ b/include/llvm/Support/RWMutex.h
@@ -0,0 +1,174 @@
+//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- 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 llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_RWMUTEX_H
+#define LLVM_SYSTEM_RWMUTEX_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+  namespace sys
+  {
+    /// @brief Platform agnostic RWMutex class.
+    class RWMutexImpl
+    {
+    /// @name Constructors
+    /// @{
+    public:
+
+      /// Initializes the lock but doesn't acquire it.
+      /// @brief Default Constructor.
+      explicit RWMutexImpl();
+
+      /// Releases and removes the lock
+      /// @brief Destructor
+      ~RWMutexImpl();
+
+    /// @}
+    /// @name Methods
+    /// @{
+    public:
+
+      /// Attempts to unconditionally acquire the lock in reader mode. If the
+      /// lock is held by a writer, this method will wait until it can acquire
+      /// the lock.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally acquire the lock in reader mode.
+      bool reader_acquire();
+
+      /// Attempts to release the lock in reader mode.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally release the lock in reader mode.
+      bool reader_release();
+
+      /// Attempts to unconditionally acquire the lock in reader mode. If the
+      /// lock is held by any readers, this method will wait until it can
+      /// acquire the lock.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally acquire the lock in writer mode.
+      bool writer_acquire();
+
+      /// Attempts to release the lock in writer mode.
+      /// @returns false if any kind of error occurs, true otherwise.
+      /// @brief Unconditionally release the lock in write mode.
+      bool writer_release();
+
+    //@}
+    /// @name Platform Dependent Data
+    /// @{
+    private:
+      void* data_; ///< We don't know what the data will be
+
+    /// @}
+    /// @name Do Not Implement
+    /// @{
+    private:
+      RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
+      void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
+    /// @}
+    };
+
+    /// SmartMutex - An R/W mutex with a compile time constant parameter that
+    /// indicates whether this mutex should become a no-op when we're not
+    /// running in multithreaded mode.
+    template<bool mt_only>
+    class SmartRWMutex : public RWMutexImpl {
+      unsigned readers, writers;
+    public:
+      explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+
+      bool reader_acquire() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::reader_acquire();
+
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        ++readers;
+        return true;
+      }
+
+      bool reader_release() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::reader_release();
+
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(readers > 0 && "Reader lock not acquired before release!");
+        --readers;
+        return true;
+      }
+
+      bool writer_acquire() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::writer_acquire();
+
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(writers == 0 && "Writer lock already acquired!");
+        ++writers;
+        return true;
+      }
+
+      bool writer_release() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::writer_release();
+
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(writers == 1 && "Writer lock not acquired before release!");
+        --writers;
+        return true;
+      }
+
+    private:
+      SmartRWMutex(const SmartRWMutex<mt_only> & original);
+      void operator=(const SmartRWMutex<mt_only> &);
+    };
+    typedef SmartRWMutex<false> RWMutex;
+
+    /// ScopedReader - RAII acquisition of a reader lock
+    template<bool mt_only>
+    struct SmartScopedReader {
+      SmartRWMutex<mt_only>& mutex;
+
+      explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+        mutex.reader_acquire();
+      }
+
+      ~SmartScopedReader() {
+        mutex.reader_release();
+      }
+    };
+    typedef SmartScopedReader<false> ScopedReader;
+
+    /// ScopedWriter - RAII acquisition of a writer lock
+    template<bool mt_only>
+    struct SmartScopedWriter {
+      SmartRWMutex<mt_only>& mutex;
+
+      explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+        mutex.writer_acquire();
+      }
+
+      ~SmartScopedWriter() {
+        mutex.writer_release();
+      }
+    };
+    typedef SmartScopedWriter<false> ScopedWriter;
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/RandomNumberGenerator.h b/include/llvm/Support/RandomNumberGenerator.h
new file mode 100644
index 0000000..cadc713
--- /dev/null
+++ b/include/llvm/Support/RandomNumberGenerator.h
@@ -0,0 +1,57 @@
+//==- llvm/Support/RandomNumberGenerator.h - RNG for diversity ---*- 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 an abstraction for random number generation (RNG).
+// Note that the current implementation is not cryptographically secure
+// as it uses the C++11 <random> facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
+#define LLVM_SUPPORT_RANDOMNUMBERGENERATOR_H_
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h" // Needed for uint64_t on Windows.
+#include <random>
+
+namespace llvm {
+
+/// A random number generator.
+/// Instances of this class should not be shared across threads.
+class RandomNumberGenerator {
+public:
+  /// Seeds and salts the underlying RNG engine. The salt of type StringRef
+  /// is passed into the constructor. The seed can be set on the command
+  /// line via -rng-seed=<uint64>.
+  /// The reason for the salt is to ensure different random streams even if
+  /// the same seed is used for multiple invocations of the compiler.
+  /// A good salt value should add additional entropy and be constant across
+  /// different machines (i.e., no paths) to allow for reproducible builds.
+  /// An instance of this class can be retrieved from the current Module.
+  /// \see Module::getRNG
+  RandomNumberGenerator(StringRef Salt);
+
+  /// Returns a random number in the range [0, Max).
+  uint64_t next(uint64_t Max);
+
+private:
+  // 64-bit Mersenne Twister by Matsumoto and Nishimura, 2000
+  // http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
+  std::mt19937_64 Generator;
+
+  // Noncopyable.
+  RandomNumberGenerator(const RandomNumberGenerator &other)
+      LLVM_DELETED_FUNCTION;
+  RandomNumberGenerator &
+  operator=(const RandomNumberGenerator &other) LLVM_DELETED_FUNCTION;
+};
+}
+
+#endif
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
new file mode 100644
index 0000000..e97f36a
--- /dev/null
+++ b/include/llvm/Support/Recycler.h
@@ -0,0 +1,128 @@
+//==- llvm/Support/Recycler.h - Recycling Allocator --------------*- 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 Recycler class template.  See the doxygen comment for
+// Recycler for more details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLER_H
+#define LLVM_SUPPORT_RECYCLER_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+
+/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
+/// printing statistics.
+///
+void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
+
+/// RecyclerStruct - Implementation detail for Recycler. This is a
+/// class that the recycler imposes on free'd memory to carve out
+/// next/prev pointers.
+struct RecyclerStruct {
+  RecyclerStruct *Prev, *Next;
+};
+
+template<>
+struct ilist_traits<RecyclerStruct> :
+    public ilist_default_traits<RecyclerStruct> {
+  static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
+  static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
+  static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
+  static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; }
+
+  mutable RecyclerStruct Sentinel;
+  RecyclerStruct *createSentinel() const {
+    return &Sentinel;
+  }
+  static void destroySentinel(RecyclerStruct *) {}
+
+  RecyclerStruct *provideInitialHead() const { return createSentinel(); }
+  RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); }
+  static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
+
+  static void deleteNode(RecyclerStruct *) {
+    llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!");
+  }
+};
+
+/// Recycler - This class manages a linked-list of deallocated nodes
+/// and facilitates reusing deallocated memory in place of allocating
+/// new memory.
+///
+template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class Recycler {
+  /// FreeList - Doubly-linked list of nodes that have deleted contents and
+  /// are not in active use.
+  ///
+  iplist<RecyclerStruct> FreeList;
+
+public:
+  ~Recycler() {
+    // If this fails, either the callee has lost track of some allocation,
+    // or the callee isn't tracking allocations and should just call
+    // clear() before deleting the Recycler.
+    assert(FreeList.empty() && "Non-empty recycler deleted!");
+  }
+
+  /// clear - Release all the tracked allocations to the allocator. The
+  /// recycler must be free of any tracked allocations before being
+  /// deleted; calling clear is one way to ensure this.
+  template<class AllocatorType>
+  void clear(AllocatorType &Allocator) {
+    while (!FreeList.empty()) {
+      T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin()));
+      Allocator.Deallocate(t);
+    }
+  }
+
+  /// Special case for BumpPtrAllocator which has an empty Deallocate()
+  /// function.
+  ///
+  /// There is no need to traverse the free list, pulling all the objects into
+  /// cache.
+  void clear(BumpPtrAllocator&) {
+    FreeList.clearAndLeakNodesUnsafely();
+  }
+
+  template<class SubClass, class AllocatorType>
+  SubClass *Allocate(AllocatorType &Allocator) {
+    static_assert(AlignOf<SubClass>::Alignment <= Align,
+                  "Recycler allocation alignment is less than object align!");
+    static_assert(sizeof(SubClass) <= Size,
+                  "Recycler allocation size is less than object size!");
+    return !FreeList.empty() ?
+           reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
+           static_cast<SubClass *>(Allocator.Allocate(Size, Align));
+  }
+
+  template<class AllocatorType>
+  T *Allocate(AllocatorType &Allocator) {
+    return Allocate<T>(Allocator);
+  }
+
+  template<class SubClass, class AllocatorType>
+  void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
+    FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element));
+  }
+
+  void PrintStats() {
+    PrintRecyclerStats(Size, Align, FreeList.size());
+  }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/RecyclingAllocator.h b/include/llvm/Support/RecyclingAllocator.h
new file mode 100644
index 0000000..001d1cf
--- /dev/null
+++ b/include/llvm/Support/RecyclingAllocator.h
@@ -0,0 +1,77 @@
+//==- llvm/Support/RecyclingAllocator.h - Recycling Allocator ----*- 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 RecyclingAllocator class.  See the doxygen comment for
+// RecyclingAllocator for more details on the implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+#define LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+
+#include "llvm/Support/Recycler.h"
+
+namespace llvm {
+
+/// RecyclingAllocator - This class wraps an Allocator, adding the
+/// functionality of recycling deleted objects.
+///
+template<class AllocatorType, class T,
+         size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class RecyclingAllocator {
+private:
+  /// Base - Implementation details.
+  ///
+  Recycler<T, Size, Align> Base;
+
+  /// Allocator - The wrapped allocator.
+  ///
+  AllocatorType Allocator;
+
+public:
+  ~RecyclingAllocator() { Base.clear(Allocator); }
+
+  /// Allocate - Return a pointer to storage for an object of type
+  /// SubClass. The storage may be either newly allocated or recycled.
+  ///
+  template<class SubClass>
+  SubClass *Allocate() { return Base.template Allocate<SubClass>(Allocator); }
+
+  T *Allocate() { return Base.Allocate(Allocator); }
+
+  /// Deallocate - Release storage for the pointed-to object. The
+  /// storage will be kept track of and may be recycled.
+  ///
+  template<class SubClass>
+  void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); }
+
+  void PrintStats() {
+    Allocator.PrintStats();
+    Base.PrintStats();
+  }
+};
+
+}
+
+template<class AllocatorType, class T, size_t Size, size_t Align>
+inline void *operator new(size_t size,
+                          llvm::RecyclingAllocator<AllocatorType,
+                                                   T, Size, Align> &Allocator) {
+  assert(size <= Size && "allocation size exceeded");
+  return Allocator.Allocate();
+}
+
+template<class AllocatorType, class T, size_t Size, size_t Align>
+inline void operator delete(void *E,
+                            llvm::RecyclingAllocator<AllocatorType,
+                                                     T, Size, Align> &A) {
+  A.Deallocate(E);
+}
+
+#endif
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
new file mode 100644
index 0000000..bf533ca
--- /dev/null
+++ b/include/llvm/Support/Regex.h
@@ -0,0 +1,106 @@
+//===-- Regex.h - Regular Expression matcher implementation -*- C++ -*-----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a POSIX regular expression matcher.  Both Basic and
+// Extended POSIX regular expressions (ERE) are supported.  EREs were extended
+// to support backreferences in matches.
+// This implementation also supports matching strings with embedded NUL chars.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGEX_H
+#define LLVM_SUPPORT_REGEX_H
+
+#include "llvm/Support/Compiler.h"
+#include <string>
+
+struct llvm_regex;
+
+namespace llvm {
+  class StringRef;
+  template<typename T> class SmallVectorImpl;
+
+  class Regex {
+  public:
+    enum {
+      NoFlags=0,
+      /// Compile for matching that ignores upper/lower case distinctions.
+      IgnoreCase=1,
+      /// Compile for newline-sensitive matching. With this flag '[^' bracket
+      /// expressions and '.' never match newline. A ^ anchor matches the
+      /// null string after any newline in the string in addition to its normal
+      /// function, and the $ anchor matches the null string before any
+      /// newline in the string in addition to its normal function.
+      Newline=2,
+      /// By default, the POSIX extended regular expression (ERE) syntax is
+      /// assumed. Pass this flag to turn on basic regular expressions (BRE)
+      /// instead.
+      BasicRegex=4
+    };
+
+    /// Compiles the given regular expression \p Regex.
+    Regex(StringRef Regex, unsigned Flags = NoFlags);
+    Regex(const Regex &) LLVM_DELETED_FUNCTION;
+    Regex &operator=(Regex regex) {
+      std::swap(preg, regex.preg);
+      std::swap(error, regex.error);
+      return *this;
+    }
+    Regex(Regex &&regex) {
+      preg = regex.preg;
+      error = regex.error;
+      regex.preg = nullptr;
+    }
+    ~Regex();
+
+    /// isValid - returns the error encountered during regex compilation, or
+    /// matching, if any.
+    bool isValid(std::string &Error);
+
+    /// getNumMatches - In a valid regex, return the number of parenthesized
+    /// matches it contains.  The number filled in by match will include this
+    /// many entries plus one for the whole regex (as element 0).
+    unsigned getNumMatches() const;
+
+    /// matches - Match the regex against a given \p String.
+    ///
+    /// \param Matches - If given, on a successful match this will be filled in
+    /// with references to the matched group expressions (inside \p String),
+    /// the first group is always the entire pattern.
+    ///
+    /// This returns true on a successful match.
+    bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = nullptr);
+
+    /// sub - Return the result of replacing the first match of the regex in
+    /// \p String with the \p Repl string. Backreferences like "\0" in the
+    /// replacement string are replaced with the appropriate match substring.
+    ///
+    /// Note that the replacement string has backslash escaping performed on
+    /// it. Invalid backreferences are ignored (replaced by empty strings).
+    ///
+    /// \param Error If non-null, any errors in the substitution (invalid
+    /// backreferences, trailing backslashes) will be recorded as a non-empty
+    /// string.
+    std::string sub(StringRef Repl, StringRef String,
+                    std::string *Error = nullptr);
+
+    /// \brief If this function returns true, ^Str$ is an extended regular
+    /// expression that matches Str and only Str.
+    static bool isLiteralERE(StringRef Str);
+
+    /// \brief Turn String into a regex by escaping its special characters.
+    static std::string escape(StringRef String);
+
+  private:
+    struct llvm_regex *preg;
+    int error;
+  };
+}
+
+#endif // LLVM_SUPPORT_REGEX_H
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
new file mode 100644
index 0000000..b0c2e89
--- /dev/null
+++ b/include/llvm/Support/Registry.h
@@ -0,0 +1,229 @@
+//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a registry template for discovering pluggable modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_H
+#define LLVM_SUPPORT_REGISTRY_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
+
+#include <memory>
+
+namespace llvm {
+  /// A simple registry entry which provides only a name, description, and
+  /// no-argument constructor.
+  template <typename T>
+  class SimpleRegistryEntry {
+    const char *Name, *Desc;
+    std::unique_ptr<T> (*Ctor)();
+
+  public:
+    SimpleRegistryEntry(const char *N, const char *D, std::unique_ptr<T> (*C)())
+      : Name(N), Desc(D), Ctor(C)
+    {}
+
+    const char *getName() const { return Name; }
+    const char *getDesc() const { return Desc; }
+    std::unique_ptr<T> instantiate() const { return Ctor(); }
+  };
+
+
+  /// Traits for registry entries. If using other than SimpleRegistryEntry, it
+  /// is necessary to define an alternate traits class.
+  template <typename T>
+  class RegistryTraits {
+    RegistryTraits() LLVM_DELETED_FUNCTION;
+
+  public:
+    typedef SimpleRegistryEntry<T> entry;
+
+    /// nameof/descof - Accessors for name and description of entries. These are
+    //                  used to generate help for command-line options.
+    static const char *nameof(const entry &Entry) { return Entry.getName(); }
+    static const char *descof(const entry &Entry) { return Entry.getDesc(); }
+  };
+
+
+  /// A global registry used in conjunction with static constructors to make
+  /// pluggable components (like targets or garbage collectors) "just work" when
+  /// linked with an executable.
+  template <typename T, typename U = RegistryTraits<T> >
+  class Registry {
+  public:
+    typedef U traits;
+    typedef typename U::entry entry;
+
+    class node;
+    class listener;
+    class iterator;
+
+  private:
+    Registry() LLVM_DELETED_FUNCTION;
+
+    static void Announce(const entry &E) {
+      for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
+        Cur->registered(E);
+    }
+
+    friend class node;
+    static node *Head, *Tail;
+
+    friend class listener;
+    static listener *ListenerHead, *ListenerTail;
+
+  public:
+    /// Node in linked list of entries.
+    ///
+    class node {
+      friend class iterator;
+
+      node *Next;
+      const entry& Val;
+
+    public:
+      node(const entry& V) : Next(nullptr), Val(V) {
+        if (Tail)
+          Tail->Next = this;
+        else
+          Head = this;
+        Tail = this;
+
+        Announce(V);
+      }
+    };
+
+
+    /// Iterators for registry entries.
+    ///
+    class iterator {
+      const node *Cur;
+
+    public:
+      explicit iterator(const node *N) : Cur(N) {}
+
+      bool operator==(const iterator &That) const { return Cur == That.Cur; }
+      bool operator!=(const iterator &That) const { return Cur != That.Cur; }
+      iterator &operator++() { Cur = Cur->Next; return *this; }
+      const entry &operator*() const { return Cur->Val; }
+      const entry *operator->() const { return &Cur->Val; }
+    };
+
+    static iterator begin() { return iterator(Head); }
+    static iterator end()   { return iterator(nullptr); }
+
+
+    /// Abstract base class for registry listeners, which are informed when new
+    /// entries are added to the registry. Simply subclass and instantiate:
+    ///
+    /// \code
+    ///   class CollectorPrinter : public Registry<Collector>::listener {
+    ///   protected:
+    ///     void registered(const Registry<Collector>::entry &e) {
+    ///       cerr << "collector now available: " << e->getName() << "\n";
+    ///     }
+    ///
+    ///   public:
+    ///     CollectorPrinter() { init(); }  // Print those already registered.
+    ///   };
+    ///
+    ///   CollectorPrinter Printer;
+    /// \endcode
+    class listener {
+      listener *Prev, *Next;
+
+      friend void Registry::Announce(const entry &E);
+
+    protected:
+      /// Called when an entry is added to the registry.
+      ///
+      virtual void registered(const entry &) = 0;
+
+      /// Calls 'registered' for each pre-existing entry.
+      ///
+      void init() {
+        for (iterator I = begin(), E = end(); I != E; ++I)
+          registered(*I);
+      }
+
+    public:
+      listener() : Prev(ListenerTail), Next(0) {
+        if (Prev)
+          Prev->Next = this;
+        else
+          ListenerHead = this;
+        ListenerTail = this;
+      }
+
+      virtual ~listener() {
+        if (Next)
+          Next->Prev = Prev;
+        else
+          ListenerTail = Prev;
+        if (Prev)
+          Prev->Next = Next;
+        else
+          ListenerHead = Next;
+      }
+    };
+
+
+    /// A static registration template. Use like such:
+    ///
+    ///   Registry<Collector>::Add<FancyGC>
+    ///   X("fancy-gc", "Newfangled garbage collector.");
+    ///
+    /// Use of this template requires that:
+    ///
+    ///  1. The registered subclass has a default constructor.
+    //
+    ///  2. The registry entry type has a constructor compatible with this
+    ///     signature:
+    ///
+    ///       entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
+    ///
+    /// If you have more elaborate requirements, then copy and modify.
+    ///
+    template <typename V>
+    class Add {
+      entry Entry;
+      node Node;
+
+      static std::unique_ptr<T> CtorFn() { return make_unique<V>(); }
+
+    public:
+      Add(const char *Name, const char *Desc)
+        : Entry(Name, Desc, CtorFn), Node(Entry) {}
+    };
+
+    /// Registry::Parser now lives in llvm/Support/RegistryParser.h.
+
+  };
+
+  // Since these are defined in a header file, plugins must be sure to export
+  // these symbols.
+
+  template <typename T, typename U>
+  typename Registry<T,U>::node *Registry<T,U>::Head;
+
+  template <typename T, typename U>
+  typename Registry<T,U>::node *Registry<T,U>::Tail;
+
+  template <typename T, typename U>
+  typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
+
+  template <typename T, typename U>
+  typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
+
+}
+
+#endif
diff --git a/include/llvm/Support/RegistryParser.h b/include/llvm/Support/RegistryParser.h
new file mode 100644
index 0000000..a6997b6
--- /dev/null
+++ b/include/llvm/Support/RegistryParser.h
@@ -0,0 +1,55 @@
+//=== RegistryParser.h - Linker-supported plugin registries -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a command-line parser for a registry.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRYPARSER_H
+#define LLVM_SUPPORT_REGISTRYPARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Registry.h"
+
+namespace llvm {
+
+  /// A command-line parser for a registry. Use like such:
+  ///
+  ///   static cl::opt<Registry<Collector>::entry, false,
+  ///                  RegistryParser<Collector> >
+  ///   GCOpt("gc", cl::desc("Garbage collector to use."),
+  ///               cl::value_desc());
+  ///
+  /// To make use of the value:
+  ///
+  ///   Collector *TheCollector = GCOpt->instantiate();
+  ///
+  template <typename T, typename U = RegistryTraits<T> >
+  class RegistryParser :
+  public cl::parser<const typename U::entry*>,
+    public Registry<T, U>::listener {
+    typedef U traits;
+    typedef typename U::entry entry;
+    typedef typename Registry<T, U>::listener listener;
+
+  protected:
+    void registered(const entry &E) {
+      addLiteralOption(traits::nameof(E), &E, traits::descof(E));
+    }
+
+  public:
+    void initialize(cl::Option &O) {
+      listener::init();
+      cl::parser<const typename U::entry*>::initialize(O);
+    }
+  };
+
+}
+
+#endif // LLVM_SUPPORT_REGISTRYPARSER_H
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
new file mode 100644
index 0000000..d5b4c57
--- /dev/null
+++ b/include/llvm/Support/SMLoc.h
@@ -0,0 +1,63 @@
+//===- SMLoc.h - Source location for use with diagnostics -------*- 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 SMLoc class.  This class encapsulates a location in
+// source code for use in diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SMLOC_H
+#define LLVM_SUPPORT_SMLOC_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// Represents a location in source code.
+class SMLoc {
+  const char *Ptr;
+public:
+  SMLoc() : Ptr(nullptr) {}
+
+  bool isValid() const { return Ptr != nullptr; }
+
+  bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
+  bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
+
+  const char *getPointer() const { return Ptr; }
+
+  static SMLoc getFromPointer(const char *Ptr) {
+    SMLoc L;
+    L.Ptr = Ptr;
+    return L;
+  }
+};
+
+/// Represents a range in source code.
+///
+/// SMRange is implemented using a half-open range, as is the convention in C++.
+/// In the string "abc", the range (1,3] represents the substring "bc", and the
+/// range (2,2] represents an empty range between the characters "b" and "c".
+class SMRange {
+public:
+  SMLoc Start, End;
+
+  SMRange() {}
+  SMRange(SMLoc St, SMLoc En) : Start(St), End(En) {
+    assert(Start.isValid() == End.isValid() &&
+           "Start and end should either both be valid or both be invalid!");
+  }
+  
+  bool isValid() const { return Start.isValid(); }
+};
+  
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Support/SaveAndRestore.h b/include/llvm/Support/SaveAndRestore.h
new file mode 100644
index 0000000..ef154ac
--- /dev/null
+++ b/include/llvm/Support/SaveAndRestore.h
@@ -0,0 +1,49 @@
+//===-- SaveAndRestore.h - Utility  -------------------------------*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file provides utility classes that use RAII to save and restore
+/// values.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H
+#define LLVM_SUPPORT_SAVEANDRESTORE_H
+
+namespace llvm {
+
+/// A utility class that uses RAII to save and restore the value of a variable.
+template <typename T> struct SaveAndRestore {
+  SaveAndRestore(T &X) : X(X), OldValue(X) {}
+  SaveAndRestore(T &X, const T &NewValue) : X(X), OldValue(X) {
+    X = NewValue;
+  }
+  ~SaveAndRestore() { X = OldValue; }
+  T get() { return OldValue; }
+
+private:
+  T &X;
+  T OldValue;
+};
+
+/// Similar to \c SaveAndRestore.  Operates only on bools; the old value of a
+/// variable is saved, and during the dstor the old value is or'ed with the new
+/// value.
+struct SaveOr {
+  SaveOr(bool &X) : X(X), OldValue(X) { X = false; }
+  ~SaveOr() { X |= OldValue; }
+
+private:
+  bool &X;
+  const bool OldValue;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/ScaledNumber.h b/include/llvm/Support/ScaledNumber.h
new file mode 100644
index 0000000..2bd7e74
--- /dev/null
+++ b/include/llvm/Support/ScaledNumber.h
@@ -0,0 +1,897 @@
+//===- llvm/Support/ScaledNumber.h - Support for scaled numbers -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions (and a class) useful for working with scaled
+// numbers -- in particular, pairs of integers where one represents digits and
+// another represents a scale.  The functions are helpers and live in the
+// namespace ScaledNumbers.  The class ScaledNumber is useful for modelling
+// certain cost metrics that need simple, integer-like semantics that are easy
+// to reason about.
+//
+// These might remind you of soft-floats.  If you want one of those, you're in
+// the wrong place.  Look at include/llvm/ADT/APFloat.h instead.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SCALEDNUMBER_H
+#define LLVM_SUPPORT_SCALEDNUMBER_H
+
+#include "llvm/Support/MathExtras.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace llvm {
+namespace ScaledNumbers {
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MaxScale = 16383;
+
+/// \brief Maximum scale; same as APFloat for easy debug printing.
+const int32_t MinScale = -16382;
+
+/// \brief Get the width of a number.
+template <class DigitsT> inline int getWidth() { return sizeof(DigitsT) * 8; }
+
+/// \brief Conditionally round up a scaled number.
+///
+/// Given \c Digits and \c Scale, round up iff \c ShouldRound is \c true.
+/// Always returns \c Scale unless there's an overflow, in which case it
+/// returns \c 1+Scale.
+///
+/// \pre adding 1 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getRounded(DigitsT Digits, int16_t Scale,
+                                              bool ShouldRound) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  if (ShouldRound)
+    if (!++Digits)
+      // Overflow.
+      return std::make_pair(DigitsT(1) << (getWidth<DigitsT>() - 1), Scale + 1);
+  return std::make_pair(Digits, Scale);
+}
+
+/// \brief Convenience helper for 32-bit rounding.
+inline std::pair<uint32_t, int16_t> getRounded32(uint32_t Digits, int16_t Scale,
+                                                 bool ShouldRound) {
+  return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Convenience helper for 64-bit rounding.
+inline std::pair<uint64_t, int16_t> getRounded64(uint64_t Digits, int16_t Scale,
+                                                 bool ShouldRound) {
+  return getRounded(Digits, Scale, ShouldRound);
+}
+
+/// \brief Adjust a 64-bit scaled number down to the appropriate width.
+///
+/// \pre Adding 64 to \c Scale will not overflow INT16_MAX.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getAdjusted(uint64_t Digits,
+                                               int16_t Scale = 0) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  const int Width = getWidth<DigitsT>();
+  if (Width == 64 || Digits <= std::numeric_limits<DigitsT>::max())
+    return std::make_pair(Digits, Scale);
+
+  // Shift right and round.
+  int Shift = 64 - Width - countLeadingZeros(Digits);
+  return getRounded<DigitsT>(Digits >> Shift, Scale + Shift,
+                             Digits & (UINT64_C(1) << (Shift - 1)));
+}
+
+/// \brief Convenience helper for adjusting to 32 bits.
+inline std::pair<uint32_t, int16_t> getAdjusted32(uint64_t Digits,
+                                                  int16_t Scale = 0) {
+  return getAdjusted<uint32_t>(Digits, Scale);
+}
+
+/// \brief Convenience helper for adjusting to 64 bits.
+inline std::pair<uint64_t, int16_t> getAdjusted64(uint64_t Digits,
+                                                  int16_t Scale = 0) {
+  return getAdjusted<uint64_t>(Digits, Scale);
+}
+
+/// \brief Multiply two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with four 64-bit integer multiplies.
+std::pair<uint64_t, int16_t> multiply64(uint64_t LHS, uint64_t RHS);
+
+/// \brief Multiply two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer multiply.
+template <class DigitsT>
+inline std::pair<DigitsT, int16_t> getProduct(DigitsT LHS, DigitsT RHS) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  if (getWidth<DigitsT>() <= 32 || (LHS <= UINT32_MAX && RHS <= UINT32_MAX))
+    return getAdjusted<DigitsT>(uint64_t(LHS) * RHS);
+
+  return multiply64(LHS, RHS);
+}
+
+/// \brief Convenience helper for 32-bit product.
+inline std::pair<uint32_t, int16_t> getProduct32(uint32_t LHS, uint32_t RHS) {
+  return getProduct(LHS, RHS);
+}
+
+/// \brief Convenience helper for 64-bit product.
+inline std::pair<uint64_t, int16_t> getProduct64(uint64_t LHS, uint64_t RHS) {
+  return getProduct(LHS, RHS);
+}
+
+/// \brief Divide two 64-bit integers to create a 64-bit scaled number.
+///
+/// Implemented with long division.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint64_t, int16_t> divide64(uint64_t Dividend, uint64_t Divisor);
+
+/// \brief Divide two 32-bit integers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// \pre \c Dividend and \c Divisor are non-zero.
+std::pair<uint32_t, int16_t> divide32(uint32_t Dividend, uint32_t Divisor);
+
+/// \brief Divide two 32-bit numbers to create a 32-bit scaled number.
+///
+/// Implemented with one 64-bit integer divide/remainder pair.
+///
+/// Returns \c (DigitsT_MAX, MaxScale) for divide-by-zero (0 for 0/0).
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getQuotient(DigitsT Dividend, DigitsT Divisor) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+  static_assert(sizeof(DigitsT) == 4 || sizeof(DigitsT) == 8,
+                "expected 32-bit or 64-bit digits");
+
+  // Check for zero.
+  if (!Dividend)
+    return std::make_pair(0, 0);
+  if (!Divisor)
+    return std::make_pair(std::numeric_limits<DigitsT>::max(), MaxScale);
+
+  if (getWidth<DigitsT>() == 64)
+    return divide64(Dividend, Divisor);
+  return divide32(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 32-bit quotient.
+inline std::pair<uint32_t, int16_t> getQuotient32(uint32_t Dividend,
+                                                  uint32_t Divisor) {
+  return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Convenience helper for 64-bit quotient.
+inline std::pair<uint64_t, int16_t> getQuotient64(uint64_t Dividend,
+                                                  uint64_t Divisor) {
+  return getQuotient(Dividend, Divisor);
+}
+
+/// \brief Implementation of getLg() and friends.
+///
+/// Returns the rounded lg of \c Digits*2^Scale and an int specifying whether
+/// this was rounded up (1), down (-1), or exact (0).
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT>
+inline std::pair<int32_t, int> getLgImpl(DigitsT Digits, int16_t Scale) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  if (!Digits)
+    return std::make_pair(INT32_MIN, 0);
+
+  // Get the floor of the lg of Digits.
+  int32_t LocalFloor = sizeof(Digits) * 8 - countLeadingZeros(Digits) - 1;
+
+  // Get the actual floor.
+  int32_t Floor = Scale + LocalFloor;
+  if (Digits == UINT64_C(1) << LocalFloor)
+    return std::make_pair(Floor, 0);
+
+  // Round based on the next digit.
+  assert(LocalFloor >= 1);
+  bool Round = Digits & UINT64_C(1) << (LocalFloor - 1);
+  return std::make_pair(Floor + Round, Round ? 1 : -1);
+}
+
+/// \brief Get the lg (rounded) of a scaled number.
+///
+/// Get the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLg(DigitsT Digits, int16_t Scale) {
+  return getLgImpl(Digits, Scale).first;
+}
+
+/// \brief Get the lg floor of a scaled number.
+///
+/// Get the floor of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgFloor(DigitsT Digits, int16_t Scale) {
+  auto Lg = getLgImpl(Digits, Scale);
+  return Lg.first - (Lg.second > 0);
+}
+
+/// \brief Get the lg ceiling of a scaled number.
+///
+/// Get the ceiling of the lg of \c Digits*2^Scale.
+///
+/// Returns \c INT32_MIN when \c Digits is zero.
+template <class DigitsT> int32_t getLgCeiling(DigitsT Digits, int16_t Scale) {
+  auto Lg = getLgImpl(Digits, Scale);
+  return Lg.first + (Lg.second < 0);
+}
+
+/// \brief Implementation for comparing scaled numbers.
+///
+/// Compare two 64-bit numbers with different scales.  Given that the scale of
+/// \c L is higher than that of \c R by \c ScaleDiff, compare them.  Return -1,
+/// 1, and 0 for less than, greater than, and equal, respectively.
+///
+/// \pre 0 <= ScaleDiff < 64.
+int compareImpl(uint64_t L, uint64_t R, int ScaleDiff);
+
+/// \brief Compare two scaled numbers.
+///
+/// Compare two scaled numbers.  Returns 0 for equal, -1 for less than, and 1
+/// for greater than.
+template <class DigitsT>
+int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  // Check for zero.
+  if (!LDigits)
+    return RDigits ? -1 : 0;
+  if (!RDigits)
+    return 1;
+
+  // Check for the scale.  Use getLgFloor to be sure that the scale difference
+  // is always lower than 64.
+  int32_t lgL = getLgFloor(LDigits, LScale), lgR = getLgFloor(RDigits, RScale);
+  if (lgL != lgR)
+    return lgL < lgR ? -1 : 1;
+
+  // Compare digits.
+  if (LScale < RScale)
+    return compareImpl(LDigits, RDigits, RScale - LScale);
+
+  return -compareImpl(RDigits, LDigits, LScale - RScale);
+}
+
+/// \brief Match scales of two numbers.
+///
+/// Given two scaled numbers, match up their scales.  Change the digits and
+/// scales in place.  Shift the digits as necessary to form equivalent numbers,
+/// losing precision only when necessary.
+///
+/// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of
+/// \c LScale (\c RScale) is unspecified.
+///
+/// As a convenience, returns the matching scale.  If the output value of one
+/// number is zero, returns the scale of the other.  If both are zero, which
+/// scale is returned is unspecifed.
+template <class DigitsT>
+int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits,
+                    int16_t &RScale) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  if (LScale < RScale)
+    // Swap arguments.
+    return matchScales(RDigits, RScale, LDigits, LScale);
+  if (!LDigits)
+    return RScale;
+  if (!RDigits || LScale == RScale)
+    return LScale;
+
+  // Now LScale > RScale.  Get the difference.
+  int32_t ScaleDiff = int32_t(LScale) - RScale;
+  if (ScaleDiff >= 2 * getWidth<DigitsT>()) {
+    // Don't bother shifting.  RDigits will get zero-ed out anyway.
+    RDigits = 0;
+    return LScale;
+  }
+
+  // Shift LDigits left as much as possible, then shift RDigits right.
+  int32_t ShiftL = std::min<int32_t>(countLeadingZeros(LDigits), ScaleDiff);
+  assert(ShiftL < getWidth<DigitsT>() && "can't shift more than width");
+
+  int32_t ShiftR = ScaleDiff - ShiftL;
+  if (ShiftR >= getWidth<DigitsT>()) {
+    // Don't bother shifting.  RDigits will get zero-ed out anyway.
+    RDigits = 0;
+    return LScale;
+  }
+
+  LDigits <<= ShiftL;
+  RDigits >>= ShiftR;
+
+  LScale -= ShiftL;
+  RScale += ShiftR;
+  assert(LScale == RScale && "scales should match");
+  return LScale;
+}
+
+/// \brief Get the sum of two scaled numbers.
+///
+/// Get the sum of two scaled numbers with as much precision as possible.
+///
+/// \pre Adding 1 to \c LScale (or \c RScale) will not overflow INT16_MAX.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getSum(DigitsT LDigits, int16_t LScale,
+                                   DigitsT RDigits, int16_t RScale) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  // Check inputs up front.  This is only relevent if addition overflows, but
+  // testing here should catch more bugs.
+  assert(LScale < INT16_MAX && "scale too large");
+  assert(RScale < INT16_MAX && "scale too large");
+
+  // Normalize digits to match scales.
+  int16_t Scale = matchScales(LDigits, LScale, RDigits, RScale);
+
+  // Compute sum.
+  DigitsT Sum = LDigits + RDigits;
+  if (Sum >= RDigits)
+    return std::make_pair(Sum, Scale);
+
+  // Adjust sum after arithmetic overflow.
+  DigitsT HighBit = DigitsT(1) << (getWidth<DigitsT>() - 1);
+  return std::make_pair(HighBit | Sum >> 1, Scale + 1);
+}
+
+/// \brief Convenience helper for 32-bit sum.
+inline std::pair<uint32_t, int16_t> getSum32(uint32_t LDigits, int16_t LScale,
+                                             uint32_t RDigits, int16_t RScale) {
+  return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit sum.
+inline std::pair<uint64_t, int16_t> getSum64(uint64_t LDigits, int16_t LScale,
+                                             uint64_t RDigits, int16_t RScale) {
+  return getSum(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Get the difference of two scaled numbers.
+///
+/// Get LHS minus RHS with as much precision as possible.
+///
+/// Returns \c (0, 0) if the RHS is larger than the LHS.
+template <class DigitsT>
+std::pair<DigitsT, int16_t> getDifference(DigitsT LDigits, int16_t LScale,
+                                          DigitsT RDigits, int16_t RScale) {
+  static_assert(!std::numeric_limits<DigitsT>::is_signed, "expected unsigned");
+
+  // Normalize digits to match scales.
+  const DigitsT SavedRDigits = RDigits;
+  const int16_t SavedRScale = RScale;
+  matchScales(LDigits, LScale, RDigits, RScale);
+
+  // Compute difference.
+  if (LDigits <= RDigits)
+    return std::make_pair(0, 0);
+  if (RDigits || !SavedRDigits)
+    return std::make_pair(LDigits - RDigits, LScale);
+
+  // Check if RDigits just barely lost its last bit.  E.g., for 32-bit:
+  //
+  //   1*2^32 - 1*2^0 == 0xffffffff != 1*2^32
+  const auto RLgFloor = getLgFloor(SavedRDigits, SavedRScale);
+  if (!compare(LDigits, LScale, DigitsT(1), RLgFloor + getWidth<DigitsT>()))
+    return std::make_pair(std::numeric_limits<DigitsT>::max(), RLgFloor);
+
+  return std::make_pair(LDigits, LScale);
+}
+
+/// \brief Convenience helper for 32-bit difference.
+inline std::pair<uint32_t, int16_t> getDifference32(uint32_t LDigits,
+                                                    int16_t LScale,
+                                                    uint32_t RDigits,
+                                                    int16_t RScale) {
+  return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+/// \brief Convenience helper for 64-bit difference.
+inline std::pair<uint64_t, int16_t> getDifference64(uint64_t LDigits,
+                                                    int16_t LScale,
+                                                    uint64_t RDigits,
+                                                    int16_t RScale) {
+  return getDifference(LDigits, LScale, RDigits, RScale);
+}
+
+} // end namespace ScaledNumbers
+} // end namespace llvm
+
+namespace llvm {
+
+class raw_ostream;
+class ScaledNumberBase {
+public:
+  static const int DefaultPrecision = 10;
+
+  static void dump(uint64_t D, int16_t E, int Width);
+  static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
+                            unsigned Precision);
+  static std::string toString(uint64_t D, int16_t E, int Width,
+                              unsigned Precision);
+  static int countLeadingZeros32(uint32_t N) { return countLeadingZeros(N); }
+  static int countLeadingZeros64(uint64_t N) { return countLeadingZeros(N); }
+  static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); }
+
+  static std::pair<uint64_t, bool> splitSigned(int64_t N) {
+    if (N >= 0)
+      return std::make_pair(N, false);
+    uint64_t Unsigned = N == INT64_MIN ? UINT64_C(1) << 63 : uint64_t(-N);
+    return std::make_pair(Unsigned, true);
+  }
+  static int64_t joinSigned(uint64_t U, bool IsNeg) {
+    if (U > uint64_t(INT64_MAX))
+      return IsNeg ? INT64_MIN : INT64_MAX;
+    return IsNeg ? -int64_t(U) : int64_t(U);
+  }
+};
+
+/// \brief Simple representation of a scaled number.
+///
+/// ScaledNumber is a number represented by digits and a scale.  It uses simple
+/// saturation arithmetic and every operation is well-defined for every value.
+/// It's somewhat similar in behaviour to a soft-float, but is *not* a
+/// replacement for one.  If you're doing numerics, look at \a APFloat instead.
+/// Nevertheless, we've found these semantics useful for modelling certain cost
+/// metrics.
+///
+/// The number is split into a signed scale and unsigned digits.  The number
+/// represented is \c getDigits()*2^getScale().  In this way, the digits are
+/// much like the mantissa in the x87 long double, but there is no canonical
+/// form so the same number can be represented by many bit representations.
+///
+/// ScaledNumber is templated on the underlying integer type for digits, which
+/// is expected to be unsigned.
+///
+/// Unlike APFloat, ScaledNumber does not model architecture floating point
+/// behaviour -- while this might make it a little faster and easier to reason
+/// about, it certainly makes it more dangerous for general numerics.
+///
+/// ScaledNumber is totally ordered.  However, there is no canonical form, so
+/// there are multiple representations of most scalars.  E.g.:
+///
+///     ScaledNumber(8u, 0) == ScaledNumber(4u, 1)
+///     ScaledNumber(4u, 1) == ScaledNumber(2u, 2)
+///     ScaledNumber(2u, 2) == ScaledNumber(1u, 3)
+///
+/// ScaledNumber implements most arithmetic operations.  Precision is kept
+/// where possible.  Uses simple saturation arithmetic, so that operations
+/// saturate to 0.0 or getLargest() rather than under or overflowing.  It has
+/// some extra arithmetic for unit inversion.  0.0/0.0 is defined to be 0.0.
+/// Any other division by 0.0 is defined to be getLargest().
+///
+/// As a convenience for modifying the exponent, left and right shifting are
+/// both implemented, and both interpret negative shifts as positive shifts in
+/// the opposite direction.
+///
+/// Scales are limited to the range accepted by x87 long double.  This makes
+/// it trivial to add functionality to convert to APFloat (this is already
+/// relied on for the implementation of printing).
+///
+/// Possible (and conflicting) future directions:
+///
+///  1. Turn this into a wrapper around \a APFloat.
+///  2. Share the algorithm implementations with \a APFloat.
+///  3. Allow \a ScaledNumber to represent a signed number.
+template <class DigitsT> class ScaledNumber : ScaledNumberBase {
+public:
+  static_assert(!std::numeric_limits<DigitsT>::is_signed,
+                "only unsigned floats supported");
+
+  typedef DigitsT DigitsType;
+
+private:
+  typedef std::numeric_limits<DigitsType> DigitsLimits;
+
+  static const int Width = sizeof(DigitsType) * 8;
+  static_assert(Width <= 64, "invalid integer width for digits");
+
+private:
+  DigitsType Digits;
+  int16_t Scale;
+
+public:
+  ScaledNumber() : Digits(0), Scale(0) {}
+
+  ScaledNumber(DigitsType Digits, int16_t Scale)
+      : Digits(Digits), Scale(Scale) {}
+
+private:
+  ScaledNumber(const std::pair<uint64_t, int16_t> &X)
+      : Digits(X.first), Scale(X.second) {}
+
+public:
+  static ScaledNumber getZero() { return ScaledNumber(0, 0); }
+  static ScaledNumber getOne() { return ScaledNumber(1, 0); }
+  static ScaledNumber getLargest() {
+    return ScaledNumber(DigitsLimits::max(), ScaledNumbers::MaxScale);
+  }
+  static ScaledNumber get(uint64_t N) { return adjustToWidth(N, 0); }
+  static ScaledNumber getInverse(uint64_t N) {
+    return get(N).invert();
+  }
+  static ScaledNumber getFraction(DigitsType N, DigitsType D) {
+    return getQuotient(N, D);
+  }
+
+  int16_t getScale() const { return Scale; }
+  DigitsType getDigits() const { return Digits; }
+
+  /// \brief Convert to the given integer type.
+  ///
+  /// Convert to \c IntT using simple saturating arithmetic, truncating if
+  /// necessary.
+  template <class IntT> IntT toInt() const;
+
+  bool isZero() const { return !Digits; }
+  bool isLargest() const { return *this == getLargest(); }
+  bool isOne() const {
+    if (Scale > 0 || Scale <= -Width)
+      return false;
+    return Digits == DigitsType(1) << -Scale;
+  }
+
+  /// \brief The log base 2, rounded.
+  ///
+  /// Get the lg of the scalar.  lg 0 is defined to be INT32_MIN.
+  int32_t lg() const { return ScaledNumbers::getLg(Digits, Scale); }
+
+  /// \brief The log base 2, rounded towards INT32_MIN.
+  ///
+  /// Get the lg floor.  lg 0 is defined to be INT32_MIN.
+  int32_t lgFloor() const { return ScaledNumbers::getLgFloor(Digits, Scale); }
+
+  /// \brief The log base 2, rounded towards INT32_MAX.
+  ///
+  /// Get the lg ceiling.  lg 0 is defined to be INT32_MIN.
+  int32_t lgCeiling() const {
+    return ScaledNumbers::getLgCeiling(Digits, Scale);
+  }
+
+  bool operator==(const ScaledNumber &X) const { return compare(X) == 0; }
+  bool operator<(const ScaledNumber &X) const { return compare(X) < 0; }
+  bool operator!=(const ScaledNumber &X) const { return compare(X) != 0; }
+  bool operator>(const ScaledNumber &X) const { return compare(X) > 0; }
+  bool operator<=(const ScaledNumber &X) const { return compare(X) <= 0; }
+  bool operator>=(const ScaledNumber &X) const { return compare(X) >= 0; }
+
+  bool operator!() const { return isZero(); }
+
+  /// \brief Convert to a decimal representation in a string.
+  ///
+  /// Convert to a string.  Uses scientific notation for very large/small
+  /// numbers.  Scientific notation is used roughly for numbers outside of the
+  /// range 2^-64 through 2^64.
+  ///
+  /// \c Precision indicates the number of decimal digits of precision to use;
+  /// 0 requests the maximum available.
+  ///
+  /// As a special case to make debugging easier, if the number is small enough
+  /// to convert without scientific notation and has more than \c Precision
+  /// digits before the decimal place, it's printed accurately to the first
+  /// digit past zero.  E.g., assuming 10 digits of precision:
+  ///
+  ///     98765432198.7654... => 98765432198.8
+  ///      8765432198.7654... =>  8765432198.8
+  ///       765432198.7654... =>   765432198.8
+  ///        65432198.7654... =>    65432198.77
+  ///         5432198.7654... =>     5432198.765
+  std::string toString(unsigned Precision = DefaultPrecision) {
+    return ScaledNumberBase::toString(Digits, Scale, Width, Precision);
+  }
+
+  /// \brief Print a decimal representation.
+  ///
+  /// Print a string.  See toString for documentation.
+  raw_ostream &print(raw_ostream &OS,
+                     unsigned Precision = DefaultPrecision) const {
+    return ScaledNumberBase::print(OS, Digits, Scale, Width, Precision);
+  }
+  void dump() const { return ScaledNumberBase::dump(Digits, Scale, Width); }
+
+  ScaledNumber &operator+=(const ScaledNumber &X) {
+    std::tie(Digits, Scale) =
+        ScaledNumbers::getSum(Digits, Scale, X.Digits, X.Scale);
+    // Check for exponent past MaxScale.
+    if (Scale > ScaledNumbers::MaxScale)
+      *this = getLargest();
+    return *this;
+  }
+  ScaledNumber &operator-=(const ScaledNumber &X) {
+    std::tie(Digits, Scale) =
+        ScaledNumbers::getDifference(Digits, Scale, X.Digits, X.Scale);
+    return *this;
+  }
+  ScaledNumber &operator*=(const ScaledNumber &X);
+  ScaledNumber &operator/=(const ScaledNumber &X);
+  ScaledNumber &operator<<=(int16_t Shift) {
+    shiftLeft(Shift);
+    return *this;
+  }
+  ScaledNumber &operator>>=(int16_t Shift) {
+    shiftRight(Shift);
+    return *this;
+  }
+
+private:
+  void shiftLeft(int32_t Shift);
+  void shiftRight(int32_t Shift);
+
+  /// \brief Adjust two floats to have matching exponents.
+  ///
+  /// Adjust \c this and \c X to have matching exponents.  Returns the new \c X
+  /// by value.  Does nothing if \a isZero() for either.
+  ///
+  /// The value that compares smaller will lose precision, and possibly become
+  /// \a isZero().
+  ScaledNumber matchScales(ScaledNumber X) {
+    ScaledNumbers::matchScales(Digits, Scale, X.Digits, X.Scale);
+    return X;
+  }
+
+public:
+  /// \brief Scale a large number accurately.
+  ///
+  /// Scale N (multiply it by this).  Uses full precision multiplication, even
+  /// if Width is smaller than 64, so information is not lost.
+  uint64_t scale(uint64_t N) const;
+  uint64_t scaleByInverse(uint64_t N) const {
+    // TODO: implement directly, rather than relying on inverse.  Inverse is
+    // expensive.
+    return inverse().scale(N);
+  }
+  int64_t scale(int64_t N) const {
+    std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+    return joinSigned(scale(Unsigned.first), Unsigned.second);
+  }
+  int64_t scaleByInverse(int64_t N) const {
+    std::pair<uint64_t, bool> Unsigned = splitSigned(N);
+    return joinSigned(scaleByInverse(Unsigned.first), Unsigned.second);
+  }
+
+  int compare(const ScaledNumber &X) const {
+    return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
+  }
+  int compareTo(uint64_t N) const {
+    ScaledNumber Scaled = get(N);
+    int Compare = compare(Scaled);
+    if (Width == 64 || Compare != 0)
+      return Compare;
+
+    // Check for precision loss.  We know *this == RoundTrip.
+    uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
+    return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
+  }
+  int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
+
+  ScaledNumber &invert() { return *this = ScaledNumber::get(1) / *this; }
+  ScaledNumber inverse() const { return ScaledNumber(*this).invert(); }
+
+private:
+  static ScaledNumber getProduct(DigitsType LHS, DigitsType RHS) {
+    return ScaledNumbers::getProduct(LHS, RHS);
+  }
+  static ScaledNumber getQuotient(DigitsType Dividend, DigitsType Divisor) {
+    return ScaledNumbers::getQuotient(Dividend, Divisor);
+  }
+
+  static int countLeadingZerosWidth(DigitsType Digits) {
+    if (Width == 64)
+      return countLeadingZeros64(Digits);
+    if (Width == 32)
+      return countLeadingZeros32(Digits);
+    return countLeadingZeros32(Digits) + Width - 32;
+  }
+
+  /// \brief Adjust a number to width, rounding up if necessary.
+  ///
+  /// Should only be called for \c Shift close to zero.
+  ///
+  /// \pre Shift >= MinScale && Shift + 64 <= MaxScale.
+  static ScaledNumber adjustToWidth(uint64_t N, int32_t Shift) {
+    assert(Shift >= ScaledNumbers::MinScale && "Shift should be close to 0");
+    assert(Shift <= ScaledNumbers::MaxScale - 64 &&
+           "Shift should be close to 0");
+    auto Adjusted = ScaledNumbers::getAdjusted<DigitsT>(N, Shift);
+    return Adjusted;
+  }
+
+  static ScaledNumber getRounded(ScaledNumber P, bool Round) {
+    // Saturate.
+    if (P.isLargest())
+      return P;
+
+    return ScaledNumbers::getRounded(P.Digits, P.Scale, Round);
+  }
+};
+
+#define SCALED_NUMBER_BOP(op, base)                                            \
+  template <class DigitsT>                                                     \
+  ScaledNumber<DigitsT> operator op(const ScaledNumber<DigitsT> &L,            \
+                                    const ScaledNumber<DigitsT> &R) {          \
+    return ScaledNumber<DigitsT>(L) base R;                                    \
+  }
+SCALED_NUMBER_BOP(+, += )
+SCALED_NUMBER_BOP(-, -= )
+SCALED_NUMBER_BOP(*, *= )
+SCALED_NUMBER_BOP(/, /= )
+SCALED_NUMBER_BOP(<<, <<= )
+SCALED_NUMBER_BOP(>>, >>= )
+#undef SCALED_NUMBER_BOP
+
+template <class DigitsT>
+raw_ostream &operator<<(raw_ostream &OS, const ScaledNumber<DigitsT> &X) {
+  return X.print(OS, 10);
+}
+
+#define SCALED_NUMBER_COMPARE_TO_TYPE(op, T1, T2)                              \
+  template <class DigitsT>                                                     \
+  bool operator op(const ScaledNumber<DigitsT> &L, T1 R) {                     \
+    return L.compareTo(T2(R)) op 0;                                            \
+  }                                                                            \
+  template <class DigitsT>                                                     \
+  bool operator op(T1 L, const ScaledNumber<DigitsT> &R) {                     \
+    return 0 op R.compareTo(T2(L));                                            \
+  }
+#define SCALED_NUMBER_COMPARE_TO(op)                                           \
+  SCALED_NUMBER_COMPARE_TO_TYPE(op, uint64_t, uint64_t)                        \
+  SCALED_NUMBER_COMPARE_TO_TYPE(op, uint32_t, uint64_t)                        \
+  SCALED_NUMBER_COMPARE_TO_TYPE(op, int64_t, int64_t)                          \
+  SCALED_NUMBER_COMPARE_TO_TYPE(op, int32_t, int64_t)
+SCALED_NUMBER_COMPARE_TO(< )
+SCALED_NUMBER_COMPARE_TO(> )
+SCALED_NUMBER_COMPARE_TO(== )
+SCALED_NUMBER_COMPARE_TO(!= )
+SCALED_NUMBER_COMPARE_TO(<= )
+SCALED_NUMBER_COMPARE_TO(>= )
+#undef SCALED_NUMBER_COMPARE_TO
+#undef SCALED_NUMBER_COMPARE_TO_TYPE
+
+template <class DigitsT>
+uint64_t ScaledNumber<DigitsT>::scale(uint64_t N) const {
+  if (Width == 64 || N <= DigitsLimits::max())
+    return (get(N) * *this).template toInt<uint64_t>();
+
+  // Defer to the 64-bit version.
+  return ScaledNumber<uint64_t>(Digits, Scale).scale(N);
+}
+
+template <class DigitsT>
+template <class IntT>
+IntT ScaledNumber<DigitsT>::toInt() const {
+  typedef std::numeric_limits<IntT> Limits;
+  if (*this < 1)
+    return 0;
+  if (*this >= Limits::max())
+    return Limits::max();
+
+  IntT N = Digits;
+  if (Scale > 0) {
+    assert(size_t(Scale) < sizeof(IntT) * 8);
+    return N << Scale;
+  }
+  if (Scale < 0) {
+    assert(size_t(-Scale) < sizeof(IntT) * 8);
+    return N >> -Scale;
+  }
+  return N;
+}
+
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator*=(const ScaledNumber &X) {
+  if (isZero())
+    return *this;
+  if (X.isZero())
+    return *this = X;
+
+  // Save the exponents.
+  int32_t Scales = int32_t(Scale) + int32_t(X.Scale);
+
+  // Get the raw product.
+  *this = getProduct(Digits, X.Digits);
+
+  // Combine with exponents.
+  return *this <<= Scales;
+}
+template <class DigitsT>
+ScaledNumber<DigitsT> &ScaledNumber<DigitsT>::
+operator/=(const ScaledNumber &X) {
+  if (isZero())
+    return *this;
+  if (X.isZero())
+    return *this = getLargest();
+
+  // Save the exponents.
+  int32_t Scales = int32_t(Scale) - int32_t(X.Scale);
+
+  // Get the raw quotient.
+  *this = getQuotient(Digits, X.Digits);
+
+  // Combine with exponents.
+  return *this <<= Scales;
+}
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftLeft(int32_t Shift) {
+  if (!Shift || isZero())
+    return;
+  assert(Shift != INT32_MIN);
+  if (Shift < 0) {
+    shiftRight(-Shift);
+    return;
+  }
+
+  // Shift as much as we can in the exponent.
+  int32_t ScaleShift = std::min(Shift, ScaledNumbers::MaxScale - Scale);
+  Scale += ScaleShift;
+  if (ScaleShift == Shift)
+    return;
+
+  // Check this late, since it's rare.
+  if (isLargest())
+    return;
+
+  // Shift the digits themselves.
+  Shift -= ScaleShift;
+  if (Shift > countLeadingZerosWidth(Digits)) {
+    // Saturate.
+    *this = getLargest();
+    return;
+  }
+
+  Digits <<= Shift;
+  return;
+}
+
+template <class DigitsT> void ScaledNumber<DigitsT>::shiftRight(int32_t Shift) {
+  if (!Shift || isZero())
+    return;
+  assert(Shift != INT32_MIN);
+  if (Shift < 0) {
+    shiftLeft(-Shift);
+    return;
+  }
+
+  // Shift as much as we can in the exponent.
+  int32_t ScaleShift = std::min(Shift, Scale - ScaledNumbers::MinScale);
+  Scale -= ScaleShift;
+  if (ScaleShift == Shift)
+    return;
+
+  // Shift the digits themselves.
+  Shift -= ScaleShift;
+  if (Shift >= Width) {
+    // Saturate.
+    *this = getZero();
+    return;
+  }
+
+  Digits >>= Shift;
+  return;
+}
+
+template <typename T> struct isPodLike;
+template <typename T> struct isPodLike<ScaledNumber<T>> {
+  static const bool value = true;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
new file mode 100644
index 0000000..6cbc1f6
--- /dev/null
+++ b/include/llvm/Support/Signals.h
@@ -0,0 +1,63 @@
+//===- llvm/Support/Signals.h - Signal Handling support ----------*- 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 some helpful functions for dealing with the possibility of
+// unix signals occurring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SIGNALS_H
+#define LLVM_SUPPORT_SIGNALS_H
+
+#include "llvm/Support/Path.h"
+#include <cstdio>
+
+namespace llvm {
+namespace sys {
+
+  /// This function runs all the registered interrupt handlers, including the
+  /// removal of files registered by RemoveFileOnSignal.
+  void RunInterruptHandlers();
+
+  /// This function registers signal handlers to ensure that if a signal gets
+  /// delivered that the named file is removed.
+  /// @brief Remove a file if a fatal signal occurs.
+  bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg = nullptr);
+
+  /// This function removes a file from the list of files to be removed on
+  /// signal delivery.
+  void DontRemoveFileOnSignal(StringRef Filename);
+
+  /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
+  /// process, print a stack trace and then exit.
+  /// @brief Print a stack trace if a fatal signal occurs.
+  void PrintStackTraceOnErrorSignal();
+
+  /// \brief Print the stack trace using the given \c FILE object.
+  void PrintStackTrace(FILE *);
+
+  /// AddSignalHandler - Add a function to be called when an abort/kill signal
+  /// is delivered to the process.  The handler can have a cookie passed to it
+  /// to identify what instance of the handler it is.
+  void AddSignalHandler(void (*FnPtr)(void *), void *Cookie);
+
+  /// This function registers a function to be called when the user "interrupts"
+  /// the program (typically by pressing ctrl-c).  When the user interrupts the
+  /// program, the specified interrupt function is called instead of the program
+  /// being killed, and the interrupt function automatically disabled.  Note
+  /// that interrupt functions are not allowed to call any non-reentrant
+  /// functions.  An null interrupt function pointer disables the current
+  /// installed function.  Note also that the handler may be executed on a
+  /// different thread on some platforms.
+  /// @brief Register a function to be called when ctrl-c is pressed.
+  void SetInterruptFunction(void (*IF)());
+} // End sys namespace
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Solaris.h b/include/llvm/Support/Solaris.h
new file mode 100644
index 0000000..b082285
--- /dev/null
+++ b/include/llvm/Support/Solaris.h
@@ -0,0 +1,49 @@
+/*===- llvm/Support/Solaris.h ------------------------------------*- C++ -*-===*
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *===----------------------------------------------------------------------===*
+ *
+ * This file contains portability fixes for Solaris hosts.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_SUPPORT_SOLARIS_H
+#define LLVM_SUPPORT_SOLARIS_H
+
+#include <sys/types.h>
+#include <sys/regset.h>
+
+/* Solaris doesn't have endian.h. SPARC is the only supported big-endian ISA. */
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#if defined(__sparc) || defined(__sparc__)
+#define BYTE_ORDER BIG_ENDIAN
+#else
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#undef CS
+#undef DS
+#undef ES
+#undef FS
+#undef GS
+#undef SS
+#undef EAX
+#undef ECX
+#undef EDX
+#undef EBX
+#undef ESP
+#undef EBP
+#undef ESI
+#undef EDI
+#undef EIP
+#undef UESP
+#undef EFL
+#undef ERR
+#undef TRAPNO
+
+#endif
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
new file mode 100644
index 0000000..4717553
--- /dev/null
+++ b/include/llvm/Support/SourceMgr.h
@@ -0,0 +1,279 @@
+//===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- 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 SMDiagnostic and SourceMgr classes.  This
+// provides a simple substrate for diagnostics, #include handling, and other low
+// level things for simple parsers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SOURCEMGR_H
+#define LLVM_SUPPORT_SOURCEMGR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/SMLoc.h"
+#include <string>
+
+namespace llvm {
+  class MemoryBuffer;
+  class SourceMgr;
+  class SMDiagnostic;
+  class SMFixIt;
+  class Twine;
+  class raw_ostream;
+
+/// This owns the files read by a parser, handles include stacks,
+/// and handles diagnostic wrangling.
+class SourceMgr {
+public:
+  enum DiagKind {
+    DK_Error,
+    DK_Warning,
+    DK_Note
+  };
+
+  /// Clients that want to handle their own diagnostics in a custom way can
+  /// register a function pointer+context as a diagnostic handler.
+  /// It gets called each time PrintMessage is invoked.
+  typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
+private:
+  struct SrcBuffer {
+    /// The memory buffer for the file.
+    MemoryBuffer *Buffer;
+
+    /// This is the location of the parent include, or null if at the top level.
+    SMLoc IncludeLoc;
+  };
+
+  /// This is all of the buffers that we are reading from.
+  std::vector<SrcBuffer> Buffers;
+
+  // This is the list of directories we should search for include files in.
+  std::vector<std::string> IncludeDirectories;
+
+  /// This is a cache for line number queries, its implementation is really
+  /// private to SourceMgr.cpp.
+  mutable void *LineNoCache;
+
+  DiagHandlerTy DiagHandler;
+  void *DiagContext;
+
+  bool isValidBufferID(unsigned i) const { return i && i <= Buffers.size(); }
+
+  SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
+  void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
+public:
+  SourceMgr()
+    : LineNoCache(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {}
+  ~SourceMgr();
+
+  void setIncludeDirs(const std::vector<std::string> &Dirs) {
+    IncludeDirectories = Dirs;
+  }
+
+  /// Specify a diagnostic handler to be invoked every time PrintMessage is
+  /// called. \p Ctx is passed into the handler when it is invoked.
+  void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
+    DiagHandler = DH;
+    DiagContext = Ctx;
+  }
+
+  DiagHandlerTy getDiagHandler() const { return DiagHandler; }
+  void *getDiagContext() const { return DiagContext; }
+
+  const SrcBuffer &getBufferInfo(unsigned i) const {
+    assert(isValidBufferID(i));
+    return Buffers[i - 1];
+  }
+
+  const MemoryBuffer *getMemoryBuffer(unsigned i) const {
+    assert(isValidBufferID(i));
+    return Buffers[i - 1].Buffer;
+  }
+
+  unsigned getNumBuffers() const {
+    return Buffers.size();
+  }
+
+  unsigned getMainFileID() const {
+    assert(getNumBuffers());
+    return 1;
+  }
+
+  SMLoc getParentIncludeLoc(unsigned i) const {
+    assert(isValidBufferID(i));
+    return Buffers[i - 1].IncludeLoc;
+  }
+
+  /// Add a new source buffer to this source manager. This takes ownership of
+  /// the memory buffer.
+  unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+    SrcBuffer NB;
+    NB.Buffer = F;
+    NB.IncludeLoc = IncludeLoc;
+    Buffers.push_back(NB);
+    return Buffers.size();
+  }
+
+  /// Search for a file with the specified name in the current directory or in
+  /// one of the IncludeDirs.
+  ///
+  /// If no file is found, this returns 0, otherwise it returns the buffer ID
+  /// of the stacked file. The full path to the included file can be found in
+  /// \p IncludedFile.
+  unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
+                          std::string &IncludedFile);
+
+  /// Return the ID of the buffer containing the specified location.
+  ///
+  /// 0 is returned if the buffer is not found.
+  unsigned FindBufferContainingLoc(SMLoc Loc) const;
+
+  /// Find the line number for the specified location in the specified file.
+  /// This is not a fast method.
+  unsigned FindLineNumber(SMLoc Loc, unsigned BufferID = 0) const {
+    return getLineAndColumn(Loc, BufferID).first;
+  }
+
+  /// Find the line and column number for the specified location in the
+  /// specified file. This is not a fast method.
+  std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
+                                                 unsigned BufferID = 0) const;
+
+  /// Emit a message about the specified location with the specified string.
+  ///
+  /// \param ShowColors Display colored messages if output is a terminal and
+  /// the default error handler is used.
+  void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
+                    const Twine &Msg,
+                    ArrayRef<SMRange> Ranges = None,
+                    ArrayRef<SMFixIt> FixIts = None,
+                    bool ShowColors = true) const;
+
+  /// Emits a diagnostic to llvm::errs().
+  void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+                    ArrayRef<SMRange> Ranges = None,
+                    ArrayRef<SMFixIt> FixIts = None,
+                    bool ShowColors = true) const;
+
+  /// Emits a manually-constructed diagnostic to the given output stream.
+  ///
+  /// \param ShowColors Display colored messages if output is a terminal and
+  /// the default error handler is used.
+  void PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic,
+                    bool ShowColors = true) const;
+
+  /// Return an SMDiagnostic at the specified location with the specified
+  /// string.
+  ///
+  /// \param Msg If non-null, the kind of message (e.g., "error") which is
+  /// prefixed to the message.
+  SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+                          ArrayRef<SMRange> Ranges = None,
+                          ArrayRef<SMFixIt> FixIts = None) const;
+
+  /// Prints the names of included files and the line of the file they were
+  /// included from. A diagnostic handler can use this before printing its
+  /// custom formatted message.
+  ///
+  /// \param IncludeLoc The location of the include.
+  /// \param OS the raw_ostream to print on.
+  void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
+};
+
+
+/// Represents a single fixit, a replacement of one range of text with another.
+class SMFixIt {
+  SMRange Range;
+
+  std::string Text;
+
+public:
+  // FIXME: Twine.str() is not very efficient.
+  SMFixIt(SMLoc Loc, const Twine &Insertion)
+    : Range(Loc, Loc), Text(Insertion.str()) {
+    assert(Loc.isValid());
+  }
+
+  // FIXME: Twine.str() is not very efficient.
+  SMFixIt(SMRange R, const Twine &Replacement)
+    : Range(R), Text(Replacement.str()) {
+    assert(R.isValid());
+  }
+
+  StringRef getText() const { return Text; }
+  SMRange getRange() const { return Range; }
+
+  bool operator<(const SMFixIt &Other) const {
+    if (Range.Start.getPointer() != Other.Range.Start.getPointer())
+      return Range.Start.getPointer() < Other.Range.Start.getPointer();
+    if (Range.End.getPointer() != Other.Range.End.getPointer())
+      return Range.End.getPointer() < Other.Range.End.getPointer();
+    return Text < Other.Text;
+  }
+};
+
+
+/// Instances of this class encapsulate one diagnostic report, allowing
+/// printing to a raw_ostream as a caret diagnostic.
+class SMDiagnostic {
+  const SourceMgr *SM;
+  SMLoc Loc;
+  std::string Filename;
+  int LineNo, ColumnNo;
+  SourceMgr::DiagKind Kind;
+  std::string Message, LineContents;
+  std::vector<std::pair<unsigned, unsigned> > Ranges;
+  SmallVector<SMFixIt, 4> FixIts;
+
+public:
+  // Null diagnostic.
+  SMDiagnostic()
+    : SM(nullptr), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
+  // Diagnostic with no location (e.g. file not found, command line arg error).
+  SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
+    : SM(nullptr), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
+      Message(Msg) {}
+
+  // Diagnostic with a location.
+  SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
+               int Line, int Col, SourceMgr::DiagKind Kind,
+               StringRef Msg, StringRef LineStr,
+               ArrayRef<std::pair<unsigned,unsigned> > Ranges,
+               ArrayRef<SMFixIt> FixIts = None);
+
+  const SourceMgr *getSourceMgr() const { return SM; }
+  SMLoc getLoc() const { return Loc; }
+  StringRef getFilename() const { return Filename; }
+  int getLineNo() const { return LineNo; }
+  int getColumnNo() const { return ColumnNo; }
+  SourceMgr::DiagKind getKind() const { return Kind; }
+  StringRef getMessage() const { return Message; }
+  StringRef getLineContents() const { return LineContents; }
+  ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
+    return Ranges;
+  }
+
+  void addFixIt(const SMFixIt &Hint) {
+    FixIts.push_back(Hint);
+  }
+
+  ArrayRef<SMFixIt> getFixIts() const {
+    return FixIts;
+  }
+
+  void print(const char *ProgName, raw_ostream &S,
+             bool ShowColors = true) const;
+};
+
+}  // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/SpecialCaseList.h b/include/llvm/Support/SpecialCaseList.h
new file mode 100644
index 0000000..098b9c7
--- /dev/null
+++ b/include/llvm/Support/SpecialCaseList.h
@@ -0,0 +1,96 @@
+//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class used to parse user-provided text files with
+// "special case lists" for code sanitizers. Such files are used to
+// define "ABI list" for DataFlowSanitizer and blacklists for another sanitizers
+// like AddressSanitizer or UndefinedBehaviorSanitizer.
+//
+// Empty lines and lines starting with "#" are ignored. All the rest lines
+// should have the form:
+//   section:wildcard_expression[=category]
+// If category is not specified, it is assumed to be empty string.
+// Definitions of "section" and "category" are sanitizer-specific. For example,
+// sanitizer blacklists support sections "src", "fun" and "global".
+// Wildcard expressions define, respectively, source files, functions or
+// globals which shouldn't be instrumented.
+// Examples of categories:
+//   "functional": used in DFSan to list functions with pure functional
+//                 semantics.
+//   "init": used in ASan blacklist to disable initialization-order bugs
+//           detection for certain globals or source files.
+// Full special case list file example:
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global:*global_with_initialization_issues*=init
+// type:*Namespace::ClassName*=init
+// src:file_with_tricky_code.cc
+// src:ignore-global-initializers-issues.cc=init
+//
+// # Functions with pure functional semantics:
+// fun:cos=functional
+// fun:sin=functional
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SPECIALCASELIST_H
+#define LLVM_SUPPORT_SPECIALCASELIST_H
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class MemoryBuffer;
+class Regex;
+class StringRef;
+
+class SpecialCaseList {
+ public:
+  /// Parses the special case list from a file. If Path is empty, returns
+  /// an empty special case list. On failure, returns 0 and writes an error
+  /// message to string.
+  static SpecialCaseList *create(const StringRef Path, std::string &Error);
+  /// Parses the special case list from a memory buffer. On failure, returns
+  /// 0 and writes an error message to string.
+  static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error);
+  /// Parses the special case list from a file. On failure, reports a fatal
+  /// error.
+  static SpecialCaseList *createOrDie(const StringRef Path);
+
+  ~SpecialCaseList();
+
+  /// Returns true, if special case list contains a line
+  /// \code
+  ///   @Section:<E>=@Category
+  /// \endcode
+  /// and @Query satisfies a wildcard expression <E>.
+  bool inSection(const StringRef Section, const StringRef Query,
+                 const StringRef Category = StringRef()) const;
+
+ private:
+  SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+  SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION;
+
+  struct Entry;
+  StringMap<StringMap<Entry> > Entries;
+
+  SpecialCaseList();
+  /// Parses just-constructed SpecialCaseList entries from a memory buffer.
+  bool parse(const MemoryBuffer *MB, std::string &Error);
+};
+
+}  // namespace llvm
+
+#endif  // LLVM_SUPPORT_SPECIALCASELIST_H
+
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
new file mode 100644
index 0000000..6e71ad4
--- /dev/null
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -0,0 +1,178 @@
+//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
+#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataStream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryObject.h"
+#include <cassert>
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+/// StreamableMemoryObject - Interface to data which might be streamed.
+/// Streamability has 2 important implications/restrictions. First, the data
+/// might not yet exist in memory when the request is made. This just means
+/// that readByte/readBytes might have to block or do some work to get it.
+/// More significantly, the exact size of the object might not be known until
+/// it has all been fetched. This means that to return the right result,
+/// getExtent must also wait for all the data to arrive; therefore it should
+/// not be called on objects which are actually streamed (this would defeat
+/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be
+/// used to test addresses without knowing the exact size of the stream.
+/// Finally, getPointer can be used instead of readBytes to avoid extra copying.
+class StreamableMemoryObject : public MemoryObject {
+ public:
+  /// Destructor      - Override as necessary.
+  virtual ~StreamableMemoryObject();
+
+  /// getBase         - Returns the lowest valid address in the region.
+  ///
+  /// @result         - The lowest valid address.
+  uint64_t getBase() const override = 0;
+
+  /// getExtent       - Returns the size of the region in bytes.  (The region is
+  ///                   contiguous, so the highest valid address of the region
+  ///                   is getBase() + getExtent() - 1).
+  ///                   May block until all bytes in the stream have been read
+  ///
+  /// @result         - The size of the region.
+  uint64_t getExtent() const override = 0;
+
+  /// readByte        - Tries to read a single byte from the region.
+  ///                   May block until (address - base) bytes have been read
+  /// @param address  - The address of the byte, in the same space as getBase().
+  /// @param ptr      - A pointer to a byte to be filled in.  Must be non-NULL.
+  /// @result         - 0 if successful; -1 if not.  Failure may be due to a
+  ///                   bounds violation or an implementation-specific error.
+  int readByte(uint64_t address, uint8_t *ptr) const override = 0;
+
+  /// readBytes       - Tries to read a contiguous range of bytes from the
+  ///                   region, up to the end of the region.
+  ///                   May block until (address - base + size) bytes have
+  ///                   been read. Additionally, StreamableMemoryObjects will
+  ///                   not do partial reads - if size bytes cannot be read,
+  ///                   readBytes will fail.
+  ///
+  /// @param address  - The address of the first byte, in the same space as
+  ///                   getBase().
+  /// @param size     - The number of bytes to copy.
+  /// @param buf      - A pointer to a buffer to be filled in.  Must be non-NULL
+  ///                   and large enough to hold size bytes.
+  /// @result         - 0 if successful; -1 if not.  Failure may be due to a
+  ///                   bounds violation or an implementation-specific error.
+  int readBytes(uint64_t address, uint64_t size,
+                uint8_t *buf) const override = 0;
+
+  /// getPointer  - Ensures that the requested data is in memory, and returns
+  ///               A pointer to it. More efficient than using readBytes if the
+  ///               data is already in memory.
+  ///               May block until (address - base + size) bytes have been read
+  /// @param address - address of the byte, in the same space as getBase()
+  /// @param size    - amount of data that must be available on return
+  /// @result        - valid pointer to the requested data
+  virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0;
+
+  /// isValidAddress - Returns true if the address is within the object
+  ///                  (i.e. between base and base + extent - 1 inclusive)
+  ///                  May block until (address - base) bytes have been read
+  /// @param address - address of the byte, in the same space as getBase()
+  /// @result        - true if the address may be read with readByte()
+  virtual bool isValidAddress(uint64_t address) const = 0;
+
+  /// isObjectEnd    - Returns true if the address is one past the end of the
+  ///                  object (i.e. if it is equal to base + extent)
+  ///                  May block until (address - base) bytes have been read
+  /// @param address - address of the byte, in the same space as getBase()
+  /// @result        - true if the address is equal to base + extent
+  virtual bool isObjectEnd(uint64_t address) const = 0;
+};
+
+/// StreamingMemoryObject - interface to data which is actually streamed from
+/// a DataStreamer. In addition to inherited members, it has the
+/// dropLeadingBytes and setKnownObjectSize methods which are not applicable
+/// to non-streamed objects.
+class StreamingMemoryObject : public StreamableMemoryObject {
+public:
+  StreamingMemoryObject(DataStreamer *streamer);
+  uint64_t getBase() const override { return 0; }
+  uint64_t getExtent() const override;
+  int readByte(uint64_t address, uint8_t *ptr) const override;
+  int readBytes(uint64_t address, uint64_t size,
+                uint8_t *buf) const override;
+  const uint8_t *getPointer(uint64_t address, uint64_t size) const override {
+    // This could be fixed by ensuring the bytes are fetched and making a copy,
+    // requiring that the bitcode size be known, or otherwise ensuring that
+    // the memory doesn't go away/get reallocated, but it's
+    // not currently necessary. Users that need the pointer don't stream.
+    llvm_unreachable("getPointer in streaming memory objects not allowed");
+    return nullptr;
+  }
+  bool isValidAddress(uint64_t address) const override;
+  bool isObjectEnd(uint64_t address) const override;
+
+  /// Drop s bytes from the front of the stream, pushing the positions of the
+  /// remaining bytes down by s. This is used to skip past the bitcode header,
+  /// since we don't know a priori if it's present, and we can't put bytes
+  /// back into the stream once we've read them.
+  bool dropLeadingBytes(size_t s);
+
+  /// If the data object size is known in advance, many of the operations can
+  /// be made more efficient, so this method should be called before reading
+  /// starts (although it can be called anytime).
+  void setKnownObjectSize(size_t size);
+
+private:
+  const static uint32_t kChunkSize = 4096 * 4;
+  mutable std::vector<unsigned char> Bytes;
+  std::unique_ptr<DataStreamer> Streamer;
+  mutable size_t BytesRead;   // Bytes read from stream
+  size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
+  mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
+  mutable bool EOFReached;
+
+  // Fetch enough bytes such that Pos can be read or EOF is reached
+  // (i.e. BytesRead > Pos). Return true if Pos can be read.
+  // Unlike most of the functions in BitcodeReader, returns true on success.
+  // Most of the requests will be small, but we fetch at kChunkSize bytes
+  // at a time to avoid making too many potentially expensive GetBytes calls
+  bool fetchToPos(size_t Pos) const {
+    if (EOFReached) return Pos < ObjectSize;
+    while (Pos >= BytesRead) {
+      Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
+      size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
+                                        kChunkSize);
+      BytesRead += bytes;
+      if (bytes < kChunkSize) {
+        assert((!ObjectSize || BytesRead >= Pos) &&
+               "Unexpected short read fetching bitcode");
+        if (BytesRead <= Pos) { // reached EOF/ran out of bytes
+          ObjectSize = BytesRead;
+          EOFReached = true;
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
+  void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION;
+};
+
+StreamableMemoryObject *getNonStreamedMemoryObject(
+    const unsigned char *Start, const unsigned char *End);
+
+}
+#endif  // STREAMABLEMEMORYOBJECT_H_
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
new file mode 100644
index 0000000..3e04653
--- /dev/null
+++ b/include/llvm/Support/StringPool.h
@@ -0,0 +1,140 @@
+//===-- StringPool.h - Interned string pool ---------------------*- 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 an interned string pool, which helps reduce the cost of
+// strings by using the same storage for identical strings.
+//
+// To intern a string:
+//
+//   StringPool Pool;
+//   PooledStringPtr Str = Pool.intern("wakka wakka");
+//
+// To use the value of an interned string, use operator bool and operator*:
+//
+//   if (Str)
+//     cerr << "the string is" << *Str << "\n";
+//
+// Pooled strings are immutable, but you can change a PooledStringPtr to point
+// to another instance. So that interned strings can eventually be freed,
+// strings in the string pool are reference-counted (automatically).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STRINGPOOL_H
+#define LLVM_SUPPORT_STRINGPOOL_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/StringMap.h"
+#include <cassert>
+#include <new>
+
+namespace llvm {
+
+  class PooledStringPtr;
+
+  /// StringPool - An interned string pool. Use the intern method to add a
+  /// string. Strings are removed automatically as PooledStringPtrs are
+  /// destroyed.
+  class StringPool {
+    /// PooledString - This is the value of an entry in the pool's interning
+    /// table.
+    struct PooledString {
+      StringPool *Pool;  ///< So the string can remove itself.
+      unsigned Refcount; ///< Number of referencing PooledStringPtrs.
+
+    public:
+      PooledString() : Pool(nullptr), Refcount(0) { }
+    };
+
+    friend class PooledStringPtr;
+
+    typedef StringMap<PooledString> table_t;
+    typedef StringMapEntry<PooledString> entry_t;
+    table_t InternTable;
+
+  public:
+    StringPool();
+    ~StringPool();
+
+    /// intern - Adds a string to the pool and returns a reference-counted
+    /// pointer to it. No additional memory is allocated if the string already
+    /// exists in the pool.
+    PooledStringPtr intern(StringRef Str);
+
+    /// empty - Checks whether the pool is empty. Returns true if so.
+    ///
+    inline bool empty() const { return InternTable.empty(); }
+  };
+
+  /// PooledStringPtr - A pointer to an interned string. Use operator bool to
+  /// test whether the pointer is valid, and operator * to get the string if so.
+  /// This is a lightweight value class with storage requirements equivalent to
+  /// a single pointer, but it does have reference-counting overhead when
+  /// copied.
+  class PooledStringPtr {
+    typedef StringPool::entry_t entry_t;
+    entry_t *S;
+
+  public:
+    PooledStringPtr() : S(nullptr) {}
+
+    explicit PooledStringPtr(entry_t *E) : S(E) {
+      if (S) ++S->getValue().Refcount;
+    }
+
+    PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
+      if (S) ++S->getValue().Refcount;
+    }
+
+    PooledStringPtr &operator=(const PooledStringPtr &That) {
+      if (S != That.S) {
+        clear();
+        S = That.S;
+        if (S) ++S->getValue().Refcount;
+      }
+      return *this;
+    }
+
+    void clear() {
+      if (!S)
+        return;
+      if (--S->getValue().Refcount == 0) {
+        S->getValue().Pool->InternTable.remove(S);
+        S->Destroy();
+      }
+      S = nullptr;
+    }
+
+    ~PooledStringPtr() { clear(); }
+
+    inline const char *begin() const {
+      assert(*this && "Attempt to dereference empty PooledStringPtr!");
+      return S->getKeyData();
+    }
+
+    inline const char *end() const {
+      assert(*this && "Attempt to dereference empty PooledStringPtr!");
+      return S->getKeyData() + S->getKeyLength();
+    }
+
+    inline unsigned size() const {
+      assert(*this && "Attempt to dereference empty PooledStringPtr!");
+      return S->getKeyLength();
+    }
+
+    inline const char *operator*() const { return begin(); }
+    inline LLVM_EXPLICIT operator bool() const { return S != nullptr; }
+
+    inline bool operator==(const PooledStringPtr &That) const { return S == That.S; }
+    inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
+  };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h
new file mode 100644
index 0000000..8a349ea
--- /dev/null
+++ b/include/llvm/Support/StringRefMemoryObject.h
@@ -0,0 +1,41 @@
+//===- llvm/Support/StringRefMemoryObject.h ---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the StringRefMemObject class, a simple
+// wrapper around StringRef implementing the MemoryObject interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H
+#define LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryObject.h"
+
+namespace llvm {
+
+/// StringRefMemoryObject - Simple StringRef-backed MemoryObject
+class StringRefMemoryObject : public MemoryObject {
+  StringRef Bytes;
+  uint64_t Base;
+public:
+  StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0)
+    : Bytes(Bytes), Base(Base) {}
+
+  uint64_t getBase() const override { return Base; }
+  uint64_t getExtent() const override { return Bytes.size(); }
+
+  int readByte(uint64_t Addr, uint8_t *Byte) const override;
+  int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const override;
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
new file mode 100644
index 0000000..340954f
--- /dev/null
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -0,0 +1,106 @@
+//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- 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 generic and optimized functions to swap the byte order of
+// an integral type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
+#define LLVM_SUPPORT_SWAPBYTEORDER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <limits>
+
+namespace llvm {
+namespace sys {
+
+/// SwapByteOrder_16 - This function returns a byte-swapped representation of
+/// the 16-bit argument.
+inline uint16_t SwapByteOrder_16(uint16_t value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+  // The DLL version of the runtime lacks these functions (bug!?), but in a
+  // release build they're replaced with BSWAP instructions anyway.
+  return _byteswap_ushort(value);
+#else
+  uint16_t Hi = value << 8;
+  uint16_t Lo = value >> 8;
+  return Hi | Lo;
+#endif
+}
+
+/// SwapByteOrder_32 - This function returns a byte-swapped representation of
+/// the 32-bit argument.
+inline uint32_t SwapByteOrder_32(uint32_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+  return __builtin_bswap32(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+  return _byteswap_ulong(value);
+#else
+  uint32_t Byte0 = value & 0x000000FF;
+  uint32_t Byte1 = value & 0x0000FF00;
+  uint32_t Byte2 = value & 0x00FF0000;
+  uint32_t Byte3 = value & 0xFF000000;
+  return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// SwapByteOrder_64 - This function returns a byte-swapped representation of
+/// the 64-bit argument.
+inline uint64_t SwapByteOrder_64(uint64_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+  return __builtin_bswap64(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+  return _byteswap_uint64(value);
+#else
+  uint64_t Hi = SwapByteOrder_32(uint32_t(value));
+  uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
+  return (Hi << 32) | Lo;
+#endif
+}
+
+inline unsigned char  getSwappedBytes(unsigned char C) { return C; }
+inline   signed char  getSwappedBytes(signed char C) { return C; }
+inline          char  getSwappedBytes(char C) { return C; }
+
+inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
+inline   signed short getSwappedBytes(  signed short C) { return SwapByteOrder_16(C); }
+
+inline unsigned int   getSwappedBytes(unsigned int   C) { return SwapByteOrder_32(C); }
+inline   signed int   getSwappedBytes(  signed int   C) { return SwapByteOrder_32(C); }
+
+#if __LONG_MAX__ == __INT_MAX__
+inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_32(C); }
+inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_32(C); }
+#elif __LONG_MAX__ == __LONG_LONG_MAX__
+inline unsigned long  getSwappedBytes(unsigned long  C) { return SwapByteOrder_64(C); }
+inline   signed long  getSwappedBytes(  signed long  C) { return SwapByteOrder_64(C); }
+#else
+#error "Unknown long size!"
+#endif
+
+inline unsigned long long getSwappedBytes(unsigned long long C) {
+  return SwapByteOrder_64(C);
+}
+inline signed long long getSwappedBytes(signed long long C) {
+  return SwapByteOrder_64(C);
+}
+
+template<typename T>
+inline void swapByteOrder(T &Value) {
+  Value = getSwappedBytes(Value);
+}
+
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
new file mode 100644
index 0000000..d2d08b2
--- /dev/null
+++ b/include/llvm/Support/SystemUtils.h
@@ -0,0 +1,34 @@
+//===- SystemUtils.h - Utilities to do low-level system stuff ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions used to do a variety of low-level, often
+// system-specific, tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
+#define LLVM_SUPPORT_SYSTEMUTILS_H
+
+#include <string>
+
+namespace llvm {
+  class raw_ostream;
+
+/// Determine if the raw_ostream provided is connected to a terminal. If so,
+/// generate a warning message to errs() advising against display of bitcode
+/// and return true. Otherwise just return false.
+/// @brief Check for output written to a console
+bool CheckBitcodeOutputToConsole(
+  raw_ostream &stream_to_check, ///< The stream to be checked
+  bool print_warning = true     ///< Control whether warnings are printed
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
new file mode 100644
index 0000000..5d5b86a
--- /dev/null
+++ b/include/llvm/Support/TargetRegistry.h
@@ -0,0 +1,1162 @@
+//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes the TargetRegistry interface, which tools can use to access
+// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
+// which have been registered.
+//
+// Target specific class implementations should register themselves using the
+// appropriate TargetRegistry interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
+#define LLVM_SUPPORT_TARGETREGISTRY_H
+
+#include "llvm-c/Disassembler.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/CodeGen.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+  class AsmPrinter;
+  class Module;
+  class MCAssembler;
+  class MCAsmBackend;
+  class MCAsmInfo;
+  class MCAsmParser;
+  class MCCodeEmitter;
+  class MCCodeGenInfo;
+  class MCContext;
+  class MCDisassembler;
+  class MCInstrAnalysis;
+  class MCInstPrinter;
+  class MCInstrInfo;
+  class MCRegisterInfo;
+  class MCStreamer;
+  class MCSubtargetInfo;
+  class MCSymbolizer;
+  class MCRelocationInfo;
+  class MCTargetAsmParser;
+  class MCTargetOptions;
+  class TargetMachine;
+  class TargetOptions;
+  class raw_ostream;
+  class formatted_raw_ostream;
+
+  MCStreamer *createNullStreamer(MCContext &Ctx);
+  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+                                bool isVerboseAsm, bool useDwarfDirectory,
+                                MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+                                MCAsmBackend *TAB, bool ShowInst);
+
+  MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
+
+  MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+                                   LLVMSymbolLookupCallback SymbolLookUp,
+                                   void *DisInfo,
+                                   MCContext *Ctx,
+                                   MCRelocationInfo *RelInfo);
+
+  /// Target - Wrapper for Target specific information.
+  ///
+  /// For registration purposes, this is a POD type so that targets can be
+  /// registered without the use of static constructors.
+  ///
+  /// Targets should implement a single global instance of this class (which
+  /// will be zero initialized), and pass that instance to the TargetRegistry as
+  /// part of their initialization.
+  class Target {
+  public:
+    friend struct TargetRegistry;
+
+    typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
+
+    typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
+                                            StringRef TT);
+    typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
+                                                    Reloc::Model RM,
+                                                    CodeModel::Model CM,
+                                                    CodeGenOpt::Level OL);
+    typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
+    typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
+    typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
+    typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
+                                                        StringRef CPU,
+                                                        StringRef Features);
+    typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
+                                                  StringRef TT,
+                                                  StringRef CPU,
+                                                  StringRef Features,
+                                                  const TargetOptions &Options,
+                                                  Reloc::Model RM,
+                                                  CodeModel::Model CM,
+                                                  CodeGenOpt::Level OL);
+    typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
+                                            MCStreamer &Streamer);
+    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
+                                                const MCRegisterInfo &MRI,
+                                                StringRef TT,
+                                                StringRef CPU);
+    typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
+        MCSubtargetInfo &STI,
+        MCAsmParser &P,
+        const MCInstrInfo &MII,
+        const MCTargetOptions &Options);
+    typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
+                                                    const MCSubtargetInfo &STI,
+                                                    MCContext &Ctx);
+    typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
+                                                  unsigned SyntaxVariant,
+                                                  const MCAsmInfo &MAI,
+                                                  const MCInstrInfo &MII,
+                                                  const MCRegisterInfo &MRI,
+                                                  const MCSubtargetInfo &STI);
+    typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+                                                  const MCRegisterInfo &MRI,
+                                                  const MCSubtargetInfo &STI,
+                                                  MCContext &Ctx);
+    typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
+                                                  StringRef TT,
+                                                  MCContext &Ctx,
+                                                  MCAsmBackend &TAB,
+                                                  raw_ostream &_OS,
+                                                  MCCodeEmitter *_Emitter,
+                                                  const MCSubtargetInfo &STI,
+                                                  bool RelaxAll,
+                                                  bool NoExecStack);
+    typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
+                                             formatted_raw_ostream &OS,
+                                             bool isVerboseAsm,
+                                             bool useDwarfDirectory,
+                                             MCInstPrinter *InstPrint,
+                                             MCCodeEmitter *CE,
+                                             MCAsmBackend *TAB,
+                                             bool ShowInst);
+    typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
+    typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
+                                                        MCContext &Ctx);
+    typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
+                                   LLVMOpInfoCallback GetOpInfo,
+                                   LLVMSymbolLookupCallback SymbolLookUp,
+                                   void *DisInfo,
+                                   MCContext *Ctx,
+                                   MCRelocationInfo *RelInfo);
+
+  private:
+    /// Next - The next registered target in the linked list, maintained by the
+    /// TargetRegistry.
+    Target *Next;
+
+    /// The target function for checking if an architecture is supported.
+    ArchMatchFnTy ArchMatchFn;
+
+    /// Name - The target name.
+    const char *Name;
+
+    /// ShortDesc - A short description of the target.
+    const char *ShortDesc;
+
+    /// HasJIT - Whether this target supports the JIT.
+    bool HasJIT;
+
+    /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
+    /// registered.
+    MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
+
+    /// MCCodeGenInfoCtorFn - Constructor function for this target's
+    /// MCCodeGenInfo, if registered.
+    MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
+
+    /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
+    /// if registered.
+    MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
+
+    /// MCInstrAnalysisCtorFn - Constructor function for this target's
+    /// MCInstrAnalysis, if registered.
+    MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
+
+    /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
+    /// if registered.
+    MCRegInfoCtorFnTy MCRegInfoCtorFn;
+
+    /// MCSubtargetInfoCtorFn - Constructor function for this target's
+    /// MCSubtargetInfo, if registered.
+    MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
+
+    /// TargetMachineCtorFn - Construction function for this target's
+    /// TargetMachine, if registered.
+    TargetMachineCtorTy TargetMachineCtorFn;
+
+    /// MCAsmBackendCtorFn - Construction function for this target's
+    /// MCAsmBackend, if registered.
+    MCAsmBackendCtorTy MCAsmBackendCtorFn;
+
+    /// MCAsmParserCtorFn - Construction function for this target's
+    /// MCTargetAsmParser, if registered.
+    MCAsmParserCtorTy MCAsmParserCtorFn;
+
+    /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
+    /// if registered.
+    AsmPrinterCtorTy AsmPrinterCtorFn;
+
+    /// MCDisassemblerCtorFn - Construction function for this target's
+    /// MCDisassembler, if registered.
+    MCDisassemblerCtorTy MCDisassemblerCtorFn;
+
+    /// MCInstPrinterCtorFn - Construction function for this target's
+    /// MCInstPrinter, if registered.
+    MCInstPrinterCtorTy MCInstPrinterCtorFn;
+
+    /// MCCodeEmitterCtorFn - Construction function for this target's
+    /// CodeEmitter, if registered.
+    MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
+
+    /// MCObjectStreamerCtorFn - Construction function for this target's
+    /// MCObjectStreamer, if registered.
+    MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
+
+    /// AsmStreamerCtorFn - Construction function for this target's
+    /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
+    AsmStreamerCtorTy AsmStreamerCtorFn;
+
+    /// Construction function for this target's NullStreamer, if registered
+    /// (default = llvm::createNullStreamer).
+    NullStreamerCtorTy NullStreamerCtorFn;
+
+    /// MCRelocationInfoCtorFn - Construction function for this target's
+    /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
+    MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
+
+    /// MCSymbolizerCtorFn - Construction function for this target's
+    /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
+    MCSymbolizerCtorTy MCSymbolizerCtorFn;
+
+  public:
+    Target()
+        : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
+          MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
+
+    /// @name Target Information
+    /// @{
+
+    // getNext - Return the next registered target.
+    const Target *getNext() const { return Next; }
+
+    /// getName - Get the target name.
+    const char *getName() const { return Name; }
+
+    /// getShortDescription - Get a short description of the target.
+    const char *getShortDescription() const { return ShortDesc; }
+
+    /// @}
+    /// @name Feature Predicates
+    /// @{
+
+    /// hasJIT - Check if this targets supports the just-in-time compilation.
+    bool hasJIT() const { return HasJIT; }
+
+    /// hasTargetMachine - Check if this target supports code generation.
+    bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
+
+    /// hasMCAsmBackend - Check if this target supports .o generation.
+    bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
+
+    /// @}
+    /// @name Feature Constructors
+    /// @{
+
+    /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
+    /// target triple.
+    ///
+    /// \param Triple This argument is used to determine the target machine
+    /// feature set; it should always be provided. Generally this should be
+    /// either the target triple from the module, or the target triple of the
+    /// host if that does not exist.
+    MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
+                               StringRef Triple) const {
+      if (!MCAsmInfoCtorFn)
+        return nullptr;
+      return MCAsmInfoCtorFn(MRI, Triple);
+    }
+
+    /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
+    ///
+    MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
+                                       CodeModel::Model CM,
+                                       CodeGenOpt::Level OL) const {
+      if (!MCCodeGenInfoCtorFn)
+        return nullptr;
+      return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
+    }
+
+    /// createMCInstrInfo - Create a MCInstrInfo implementation.
+    ///
+    MCInstrInfo *createMCInstrInfo() const {
+      if (!MCInstrInfoCtorFn)
+        return nullptr;
+      return MCInstrInfoCtorFn();
+    }
+
+    /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
+    ///
+    MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
+      if (!MCInstrAnalysisCtorFn)
+        return nullptr;
+      return MCInstrAnalysisCtorFn(Info);
+    }
+
+    /// createMCRegInfo - Create a MCRegisterInfo implementation.
+    ///
+    MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
+      if (!MCRegInfoCtorFn)
+        return nullptr;
+      return MCRegInfoCtorFn(Triple);
+    }
+
+    /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
+    ///
+    /// \param Triple This argument is used to determine the target machine
+    /// feature set; it should always be provided. Generally this should be
+    /// either the target triple from the module, or the target triple of the
+    /// host if that does not exist.
+    /// \param CPU This specifies the name of the target CPU.
+    /// \param Features This specifies the string representation of the
+    /// additional target features.
+    MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
+                                           StringRef Features) const {
+      if (!MCSubtargetInfoCtorFn)
+        return nullptr;
+      return MCSubtargetInfoCtorFn(Triple, CPU, Features);
+    }
+
+    /// createTargetMachine - Create a target specific machine implementation
+    /// for the specified \p Triple.
+    ///
+    /// \param Triple This argument is used to determine the target machine
+    /// feature set; it should always be provided. Generally this should be
+    /// either the target triple from the module, or the target triple of the
+    /// host if that does not exist.
+    TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
+                             StringRef Features, const TargetOptions &Options,
+                             Reloc::Model RM = Reloc::Default,
+                             CodeModel::Model CM = CodeModel::Default,
+                             CodeGenOpt::Level OL = CodeGenOpt::Default) const {
+      if (!TargetMachineCtorFn)
+        return nullptr;
+      return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
+                                 RM, CM, OL);
+    }
+
+    /// createMCAsmBackend - Create a target specific assembly parser.
+    ///
+    /// \param Triple The target triple string.
+    MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
+                                     StringRef Triple, StringRef CPU) const {
+      if (!MCAsmBackendCtorFn)
+        return nullptr;
+      return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
+    }
+
+    /// createMCAsmParser - Create a target specific assembly parser.
+    ///
+    /// \param Parser The target independent parser implementation to use for
+    /// parsing and lexing.
+    MCTargetAsmParser *createMCAsmParser(
+        MCSubtargetInfo &STI,
+        MCAsmParser &Parser,
+        const MCInstrInfo &MII,
+        const MCTargetOptions &Options) const {
+      if (!MCAsmParserCtorFn)
+        return nullptr;
+      return MCAsmParserCtorFn(STI, Parser, MII, Options);
+    }
+
+    /// createAsmPrinter - Create a target specific assembly printer pass.  This
+    /// takes ownership of the MCStreamer object.
+    AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
+      if (!AsmPrinterCtorFn)
+        return nullptr;
+      return AsmPrinterCtorFn(TM, Streamer);
+    }
+
+    MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
+                                         MCContext &Ctx) const {
+      if (!MCDisassemblerCtorFn)
+        return nullptr;
+      return MCDisassemblerCtorFn(*this, STI, Ctx);
+    }
+
+    MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
+                                       const MCAsmInfo &MAI,
+                                       const MCInstrInfo &MII,
+                                       const MCRegisterInfo &MRI,
+                                       const MCSubtargetInfo &STI) const {
+      if (!MCInstPrinterCtorFn)
+        return nullptr;
+      return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
+    }
+
+
+    /// createMCCodeEmitter - Create a target specific code emitter.
+    MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+                                       const MCRegisterInfo &MRI,
+                                       const MCSubtargetInfo &STI,
+                                       MCContext &Ctx) const {
+      if (!MCCodeEmitterCtorFn)
+        return nullptr;
+      return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
+    }
+
+    /// createMCObjectStreamer - Create a target specific MCStreamer.
+    ///
+    /// \param TT The target triple.
+    /// \param Ctx The target context.
+    /// \param TAB The target assembler backend object. Takes ownership.
+    /// \param _OS The stream object.
+    /// \param _Emitter The target independent assembler object.Takes ownership.
+    /// \param RelaxAll Relax all fixups?
+    /// \param NoExecStack Mark file as not needing a executable stack.
+    MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
+                                       MCAsmBackend &TAB,
+                                       raw_ostream &_OS,
+                                       MCCodeEmitter *_Emitter,
+                                       const MCSubtargetInfo &STI,
+                                       bool RelaxAll,
+                                       bool NoExecStack) const {
+      if (!MCObjectStreamerCtorFn)
+        return nullptr;
+      return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
+                                    RelaxAll, NoExecStack);
+    }
+
+    /// createAsmStreamer - Create a target specific MCStreamer.
+    MCStreamer *createAsmStreamer(MCContext &Ctx,
+                                  formatted_raw_ostream &OS,
+                                  bool isVerboseAsm,
+                                  bool useDwarfDirectory,
+                                  MCInstPrinter *InstPrint,
+                                  MCCodeEmitter *CE,
+                                  MCAsmBackend *TAB,
+                                  bool ShowInst) const {
+      if (AsmStreamerCtorFn)
+        return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
+                                 InstPrint, CE, TAB, ShowInst);
+      return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
+                                     InstPrint, CE, TAB, ShowInst);
+    }
+
+    MCStreamer *createNullStreamer(MCContext &Ctx) const {
+      if (NullStreamerCtorFn)
+        return NullStreamerCtorFn(Ctx);
+      return llvm::createNullStreamer(Ctx);
+    }
+
+    /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
+    ///
+    /// \param TT The target triple.
+    /// \param Ctx The target context.
+    MCRelocationInfo *
+      createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
+      MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
+                                      ? MCRelocationInfoCtorFn
+                                      : llvm::createMCRelocationInfo;
+      return Fn(TT, Ctx);
+    }
+
+    /// createMCSymbolizer - Create a target specific MCSymbolizer.
+    ///
+    /// \param TT The target triple.
+    /// \param GetOpInfo The function to get the symbolic information for operands.
+    /// \param SymbolLookUp The function to lookup a symbol name.
+    /// \param DisInfo The pointer to the block of symbolic information for above call
+    /// back.
+    /// \param Ctx The target context.
+    /// \param RelInfo The relocation information for this target. Takes ownership.
+    MCSymbolizer *
+    createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+                       LLVMSymbolLookupCallback SymbolLookUp,
+                       void *DisInfo,
+                       MCContext *Ctx, MCRelocationInfo *RelInfo) const {
+      MCSymbolizerCtorTy Fn =
+          MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
+      return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo);
+    }
+
+    /// @}
+  };
+
+  /// TargetRegistry - Generic interface to target specific features.
+  struct TargetRegistry {
+    class iterator {
+      const Target *Current;
+      explicit iterator(Target *T) : Current(T) {}
+      friend struct TargetRegistry;
+    public:
+      iterator() : Current(nullptr) {}
+
+      bool operator==(const iterator &x) const {
+        return Current == x.Current;
+      }
+      bool operator!=(const iterator &x) const {
+        return !operator==(x);
+      }
+
+      // Iterator traversal: forward iteration only
+      iterator &operator++() {          // Preincrement
+        assert(Current && "Cannot increment end iterator!");
+        Current = Current->getNext();
+        return *this;
+      }
+      iterator operator++(int) {        // Postincrement
+        iterator tmp = *this;
+        ++*this;
+        return tmp;
+      }
+
+      const Target &operator*() const {
+        assert(Current && "Cannot dereference end iterator!");
+        return *Current;
+      }
+
+      const Target *operator->() const {
+        return &operator*();
+      }
+    };
+
+    /// printRegisteredTargetsForVersion - Print the registered targets
+    /// appropriately for inclusion in a tool's version output.
+    static void printRegisteredTargetsForVersion();
+
+    /// @name Registry Access
+    /// @{
+
+    static iterator begin();
+
+    static iterator end() { return iterator(); }
+
+    /// lookupTarget - Lookup a target based on a target triple.
+    ///
+    /// \param Triple - The triple to use for finding a target.
+    /// \param Error - On failure, an error string describing why no target was
+    /// found.
+    static const Target *lookupTarget(const std::string &Triple,
+                                      std::string &Error);
+
+    /// lookupTarget - Lookup a target based on an architecture name
+    /// and a target triple.  If the architecture name is non-empty,
+    /// then the lookup is done by architecture.  Otherwise, the target
+    /// triple is used.
+    ///
+    /// \param ArchName - The architecture to use for finding a target.
+    /// \param TheTriple - The triple to use for finding a target.  The
+    /// triple is updated with canonical architecture name if a lookup
+    /// by architecture is done.
+    /// \param Error - On failure, an error string describing why no target was
+    /// found.
+    static const Target *lookupTarget(const std::string &ArchName,
+                                      Triple &TheTriple,
+                                      std::string &Error);
+
+    /// @}
+    /// @name Target Registration
+    /// @{
+
+    /// RegisterTarget - Register the given target. Attempts to register a
+    /// target which has already been registered will be ignored.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Name - The target name. This should be a static string.
+    /// @param ShortDesc - A short target description. This should be a static
+    /// string.
+    /// @param ArchMatchFn - The arch match checking function for this target.
+    /// @param HasJIT - Whether the target supports JIT code
+    /// generation.
+    static void RegisterTarget(Target &T,
+                               const char *Name,
+                               const char *ShortDesc,
+                               Target::ArchMatchFnTy ArchMatchFn,
+                               bool HasJIT = false);
+
+    /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCAsmInfo for the target.
+    static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+      T.MCAsmInfoCtorFn = Fn;
+    }
+
+    /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCCodeGenInfo for the target.
+    static void RegisterMCCodeGenInfo(Target &T,
+                                     Target::MCCodeGenInfoCtorFnTy Fn) {
+      T.MCCodeGenInfoCtorFn = Fn;
+    }
+
+    /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCInstrInfo for the target.
+    static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+      T.MCInstrInfoCtorFn = Fn;
+    }
+
+    /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
+    /// the given target.
+    static void RegisterMCInstrAnalysis(Target &T,
+                                        Target::MCInstrAnalysisCtorFnTy Fn) {
+      T.MCInstrAnalysisCtorFn = Fn;
+    }
+
+    /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCRegisterInfo for the target.
+    static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+      T.MCRegInfoCtorFn = Fn;
+    }
+
+    /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
+    /// the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCSubtargetInfo for the target.
+    static void RegisterMCSubtargetInfo(Target &T,
+                                        Target::MCSubtargetInfoCtorFnTy Fn) {
+      T.MCSubtargetInfoCtorFn = Fn;
+    }
+
+    /// RegisterTargetMachine - Register a TargetMachine implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a TargetMachine for the target.
+    static void RegisterTargetMachine(Target &T,
+                                      Target::TargetMachineCtorTy Fn) {
+      T.TargetMachineCtorFn = Fn;
+    }
+
+    /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an AsmBackend for the target.
+    static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
+      T.MCAsmBackendCtorFn = Fn;
+    }
+
+    /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
+    /// the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCTargetAsmParser for the target.
+    static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
+      T.MCAsmParserCtorFn = Fn;
+    }
+
+    /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
+    /// target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an AsmPrinter for the target.
+    static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
+      T.AsmPrinterCtorFn = Fn;
+    }
+
+    /// RegisterMCDisassembler - Register a MCDisassembler implementation for
+    /// the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCDisassembler for the target.
+    static void RegisterMCDisassembler(Target &T,
+                                       Target::MCDisassemblerCtorTy Fn) {
+      T.MCDisassemblerCtorFn = Fn;
+    }
+
+    /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCInstPrinter for the target.
+    static void RegisterMCInstPrinter(Target &T,
+                                      Target::MCInstPrinterCtorTy Fn) {
+      T.MCInstPrinterCtorFn = Fn;
+    }
+
+    /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCCodeEmitter for the target.
+    static void RegisterMCCodeEmitter(Target &T,
+                                      Target::MCCodeEmitterCtorTy Fn) {
+      T.MCCodeEmitterCtorFn = Fn;
+    }
+
+    /// RegisterMCObjectStreamer - Register a object code MCStreamer
+    /// implementation for the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCStreamer for the target.
+    static void RegisterMCObjectStreamer(Target &T,
+                                         Target::MCObjectStreamerCtorTy Fn) {
+      T.MCObjectStreamerCtorFn = Fn;
+    }
+
+    /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
+    /// for the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCStreamer for the target.
+    static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
+      T.AsmStreamerCtorFn = Fn;
+    }
+
+    static void RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
+      T.NullStreamerCtorFn = Fn;
+    }
+
+    /// RegisterMCRelocationInfo - Register an MCRelocationInfo
+    /// implementation for the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCRelocationInfo for the target.
+    static void RegisterMCRelocationInfo(Target &T,
+                                         Target::MCRelocationInfoCtorTy Fn) {
+      T.MCRelocationInfoCtorFn = Fn;
+    }
+
+    /// RegisterMCSymbolizer - Register an MCSymbolizer
+    /// implementation for the given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct an MCSymbolizer for the target.
+    static void RegisterMCSymbolizer(Target &T,
+                                     Target::MCSymbolizerCtorTy Fn) {
+      T.MCSymbolizerCtorFn = Fn;
+    }
+
+    /// @}
+  };
+
+
+  //===--------------------------------------------------------------------===//
+
+  /// RegisterTarget - Helper template for registering a target, for use in the
+  /// target's initialization function. Usage:
+  ///
+  ///
+  /// Target TheFooTarget; // The global target instance.
+  ///
+  /// extern "C" void LLVMInitializeFooTargetInfo() {
+  ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
+  /// }
+  template<Triple::ArchType TargetArchType = Triple::UnknownArch,
+           bool HasJIT = false>
+  struct RegisterTarget {
+    RegisterTarget(Target &T, const char *Name, const char *Desc) {
+      TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
+    }
+
+    static bool getArchMatch(Triple::ArchType Arch) {
+      return Arch == TargetArchType;
+    }
+  };
+
+  /// RegisterMCAsmInfo - Helper template for registering a target assembly info
+  /// implementation.  This invokes the static "Create" method on the class to
+  /// actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
+  /// }
+  template<class MCAsmInfoImpl>
+  struct RegisterMCAsmInfo {
+    RegisterMCAsmInfo(Target &T) {
+      TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
+    }
+  private:
+    static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
+      return new MCAsmInfoImpl(TT);
+    }
+
+  };
+
+  /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
+  /// implementation.  This invokes the specified function to do the
+  /// construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCAsmInfoFn {
+    RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCAsmInfo(T, Fn);
+    }
+  };
+
+  /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
+  /// implementation.  This invokes the static "Create" method on the class
+  /// to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
+  /// }
+  template<class MCCodeGenInfoImpl>
+  struct RegisterMCCodeGenInfo {
+    RegisterMCCodeGenInfo(Target &T) {
+      TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
+    }
+  private:
+    static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
+                                    CodeModel::Model /*CM*/,
+                                    CodeGenOpt::Level /*OL*/) {
+      return new MCCodeGenInfoImpl();
+    }
+  };
+
+  /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
+  /// info implementation.  This invokes the specified function to do the
+  /// construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCCodeGenInfoFn {
+    RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
+    }
+  };
+
+  /// RegisterMCInstrInfo - Helper template for registering a target instruction
+  /// info implementation.  This invokes the static "Create" method on the class
+  /// to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
+  /// }
+  template<class MCInstrInfoImpl>
+  struct RegisterMCInstrInfo {
+    RegisterMCInstrInfo(Target &T) {
+      TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
+    }
+  private:
+    static MCInstrInfo *Allocator() {
+      return new MCInstrInfoImpl();
+    }
+  };
+
+  /// RegisterMCInstrInfoFn - Helper template for registering a target
+  /// instruction info implementation.  This invokes the specified function to
+  /// do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCInstrInfoFn {
+    RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCInstrInfo(T, Fn);
+    }
+  };
+
+  /// RegisterMCInstrAnalysis - Helper template for registering a target
+  /// instruction analyzer implementation.  This invokes the static "Create"
+  /// method on the class to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
+  /// }
+  template<class MCInstrAnalysisImpl>
+  struct RegisterMCInstrAnalysis {
+    RegisterMCInstrAnalysis(Target &T) {
+      TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
+    }
+  private:
+    static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
+      return new MCInstrAnalysisImpl(Info);
+    }
+  };
+
+  /// RegisterMCInstrAnalysisFn - Helper template for registering a target
+  /// instruction analyzer implementation.  This invokes the specified function
+  /// to do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCInstrAnalysisFn {
+    RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
+      TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
+    }
+  };
+
+  /// RegisterMCRegInfo - Helper template for registering a target register info
+  /// implementation.  This invokes the static "Create" method on the class to
+  /// actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
+  /// }
+  template<class MCRegisterInfoImpl>
+  struct RegisterMCRegInfo {
+    RegisterMCRegInfo(Target &T) {
+      TargetRegistry::RegisterMCRegInfo(T, &Allocator);
+    }
+  private:
+    static MCRegisterInfo *Allocator(StringRef /*TT*/) {
+      return new MCRegisterInfoImpl();
+    }
+  };
+
+  /// RegisterMCRegInfoFn - Helper template for registering a target register
+  /// info implementation.  This invokes the specified function to do the
+  /// construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCRegInfoFn {
+    RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCRegInfo(T, Fn);
+    }
+  };
+
+  /// RegisterMCSubtargetInfo - Helper template for registering a target
+  /// subtarget info implementation.  This invokes the static "Create" method
+  /// on the class to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
+  /// }
+  template<class MCSubtargetInfoImpl>
+  struct RegisterMCSubtargetInfo {
+    RegisterMCSubtargetInfo(Target &T) {
+      TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
+    }
+  private:
+    static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
+                                      StringRef /*FS*/) {
+      return new MCSubtargetInfoImpl();
+    }
+  };
+
+  /// RegisterMCSubtargetInfoFn - Helper template for registering a target
+  /// subtarget info implementation.  This invokes the specified function to
+  /// do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCSubtargetInfoFn {
+    RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
+    }
+  };
+
+  /// RegisterTargetMachine - Helper template for registering a target machine
+  /// implementation, for use in the target machine initialization
+  /// function. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
+  /// }
+  template<class TargetMachineImpl>
+  struct RegisterTargetMachine {
+    RegisterTargetMachine(Target &T) {
+      TargetRegistry::RegisterTargetMachine(T, &Allocator);
+    }
+
+  private:
+    static TargetMachine *Allocator(const Target &T, StringRef TT,
+                                    StringRef CPU, StringRef FS,
+                                    const TargetOptions &Options,
+                                    Reloc::Model RM,
+                                    CodeModel::Model CM,
+                                    CodeGenOpt::Level OL) {
+      return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
+    }
+  };
+
+  /// RegisterMCAsmBackend - Helper template for registering a target specific
+  /// assembler backend. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooMCAsmBackend() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
+  /// }
+  template<class MCAsmBackendImpl>
+  struct RegisterMCAsmBackend {
+    RegisterMCAsmBackend(Target &T) {
+      TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
+    }
+
+  private:
+    static MCAsmBackend *Allocator(const Target &T,
+                                   const MCRegisterInfo &MRI,
+                                   StringRef Triple, StringRef CPU) {
+      return new MCAsmBackendImpl(T, MRI, Triple, CPU);
+    }
+  };
+
+  /// RegisterMCAsmParser - Helper template for registering a target specific
+  /// assembly parser, for use in the target machine initialization
+  /// function. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooMCAsmParser() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
+  /// }
+  template<class MCAsmParserImpl>
+  struct RegisterMCAsmParser {
+    RegisterMCAsmParser(Target &T) {
+      TargetRegistry::RegisterMCAsmParser(T, &Allocator);
+    }
+
+  private:
+    static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
+                                        const MCInstrInfo &MII,
+                                        const MCTargetOptions &Options) {
+      return new MCAsmParserImpl(STI, P, MII, Options);
+    }
+  };
+
+  /// RegisterAsmPrinter - Helper template for registering a target specific
+  /// assembly printer, for use in the target machine initialization
+  /// function. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooAsmPrinter() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
+  /// }
+  template<class AsmPrinterImpl>
+  struct RegisterAsmPrinter {
+    RegisterAsmPrinter(Target &T) {
+      TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+    }
+
+  private:
+    static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
+      return new AsmPrinterImpl(TM, Streamer);
+    }
+  };
+
+  /// RegisterMCCodeEmitter - Helper template for registering a target specific
+  /// machine code emitter, for use in the target initialization
+  /// function. Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
+  /// }
+  template<class MCCodeEmitterImpl>
+  struct RegisterMCCodeEmitter {
+    RegisterMCCodeEmitter(Target &T) {
+      TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
+    }
+
+  private:
+    static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
+                                    const MCRegisterInfo &/*MRI*/,
+                                    const MCSubtargetInfo &/*STI*/,
+                                    MCContext &/*Ctx*/) {
+      return new MCCodeEmitterImpl();
+    }
+  };
+
+}
+
+#endif
diff --git a/include/llvm/Support/TargetSelect.h b/include/llvm/Support/TargetSelect.h
new file mode 100644
index 0000000..a86e953
--- /dev/null
+++ b/include/llvm/Support/TargetSelect.h
@@ -0,0 +1,166 @@
+//===- TargetSelect.h - Target Selection & Registration ---------*- 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 utilities to make sure that certain classes of targets are
+// linked into the main application executable, and initialize them as
+// appropriate.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETSELECT_H
+#define LLVM_SUPPORT_TARGETSELECT_H
+
+#include "llvm/Config/llvm-config.h"
+
+extern "C" {
+  // Declare all of the target-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+  
+  // Declare all of the target-MC-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+  
+  // Declare all of the available assembly printer initialization functions.
+#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+
+  // Declare all of the available assembly parser initialization functions.
+#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+
+  // Declare all of the available disassembler initialization functions.
+#define LLVM_DISASSEMBLER(TargetName) \
+  void LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+}
+
+namespace llvm {
+  /// InitializeAllTargetInfos - The main program should call this function if
+  /// it wants access to all available targets that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargetInfos() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+  }
+  
+  /// InitializeAllTargets - The main program should call this function if it
+  /// wants access to all available target machines that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargets() {
+    // FIXME: Remove this, clients should do it.
+    InitializeAllTargetInfos();
+
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+  }
+  
+  /// InitializeAllTargetMCs - The main program should call this function if it
+  /// wants access to all available target MC that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllTargetMCs() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+  }
+  
+  /// InitializeAllAsmPrinters - The main program should call this function if
+  /// it wants all asm printers that LLVM is configured to support, to make them
+  /// available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllAsmPrinters() {
+#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+  }
+  
+  /// InitializeAllAsmParsers - The main program should call this function if it
+  /// wants all asm parsers that LLVM is configured to support, to make them
+  /// available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllAsmParsers() {
+#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+  }
+  
+  /// InitializeAllDisassemblers - The main program should call this function if
+  /// it wants all disassemblers that LLVM is configured to support, to make
+  /// them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllDisassemblers() {
+#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+  }
+  
+  /// InitializeNativeTarget - The main program should call this function to
+  /// initialize the native target corresponding to the host.  This is useful 
+  /// for JIT applications to ensure that the target gets linked in correctly.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline bool InitializeNativeTarget() {
+  // If we have a native target, initialize it to ensure it is linked in.
+#ifdef LLVM_NATIVE_TARGET
+    LLVM_NATIVE_TARGETINFO();
+    LLVM_NATIVE_TARGET();
+    LLVM_NATIVE_TARGETMC();
+    return false;
+#else
+    return true;
+#endif
+  }  
+
+  /// InitializeNativeTargetAsmPrinter - The main program should call
+  /// this function to initialize the native target asm printer.
+  inline bool InitializeNativeTargetAsmPrinter() {
+  // If we have a native target, initialize the corresponding asm printer.
+#ifdef LLVM_NATIVE_ASMPRINTER
+    LLVM_NATIVE_ASMPRINTER();
+    return false;
+#else
+    return true;
+#endif
+  }  
+
+  /// InitializeNativeTargetAsmParser - The main program should call
+  /// this function to initialize the native target asm parser.
+  inline bool InitializeNativeTargetAsmParser() {
+  // If we have a native target, initialize the corresponding asm parser.
+#ifdef LLVM_NATIVE_ASMPARSER
+    LLVM_NATIVE_ASMPARSER();
+    return false;
+#else
+    return true;
+#endif
+  }  
+
+  /// InitializeNativeTargetDisassembler - The main program should call
+  /// this function to initialize the native target disassembler.
+  inline bool InitializeNativeTargetDisassembler() {
+  // If we have a native target, initialize the corresponding disassembler.
+#ifdef LLVM_NATIVE_DISASSEMBLER
+    LLVM_NATIVE_DISASSEMBLER();
+    return false;
+#else
+    return true;
+#endif
+  }  
+
+}
+
+#endif
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
new file mode 100644
index 0000000..7518626
--- /dev/null
+++ b/include/llvm/Support/ThreadLocal.h
@@ -0,0 +1,63 @@
+//===- llvm/Support/ThreadLocal.h - Thread Local Data ------------*- 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 llvm::sys::ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_THREADLOCAL_H
+#define LLVM_SUPPORT_THREADLOCAL_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm {
+  namespace sys {
+    // ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
+    // YOU SHOULD NEVER USE THIS DIRECTLY.
+    class ThreadLocalImpl {
+      typedef uint64_t ThreadLocalDataTy;
+      /// \brief Platform-specific thread local data.
+      ///
+      /// This is embedded in the class and we avoid malloc'ing/free'ing it,
+      /// to make this class more safe for use along with CrashRecoveryContext.
+      union {
+        char data[sizeof(ThreadLocalDataTy)];
+        ThreadLocalDataTy align_data;
+      };
+    public:
+      ThreadLocalImpl();
+      virtual ~ThreadLocalImpl();
+      void setInstance(const void* d);
+      const void* getInstance();
+      void removeInstance();
+    };
+
+    /// ThreadLocal - A class used to abstract thread-local storage.  It holds,
+    /// for each thread, a pointer a single object of type T.
+    template<class T>
+    class ThreadLocal : public ThreadLocalImpl {
+    public:
+      ThreadLocal() : ThreadLocalImpl() { }
+
+      /// get - Fetches a pointer to the object associated with the current
+      /// thread.  If no object has yet been associated, it returns NULL;
+      T* get() { return static_cast<T*>(getInstance()); }
+
+      // set - Associates a pointer to an object with the current thread.
+      void set(T* d) { setInstance(d); }
+
+      // erase - Removes the pointer associated with the current thread.
+      void erase() { removeInstance(); }
+    };
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
new file mode 100644
index 0000000..7e87584
--- /dev/null
+++ b/include/llvm/Support/Threading.h
@@ -0,0 +1,38 @@
+//===-- llvm/Support/Threading.h - Control multithreading mode --*- 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 helper functions for running LLVM in a multi-threaded
+// environment.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_THREADING_H
+#define LLVM_SUPPORT_THREADING_H
+
+namespace llvm {
+  /// Returns true if LLVM is compiled with support for multi-threading, and
+  /// false otherwise.
+  bool llvm_is_multithreaded();
+
+  /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
+  /// thread, passing it the provided \p UserData.
+  ///
+  /// This function does not guarantee that the code will actually be executed
+  /// on a separate thread or honoring the requested stack size, but tries to do
+  /// so where system support is available.
+  ///
+  /// \param UserFn - The callback to execute.
+  /// \param UserData - An argument to pass to the callback function.
+  /// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
+  /// the thread stack.
+  void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
+                              unsigned RequestedStackSize = 0);
+}
+
+#endif
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
new file mode 100644
index 0000000..ee0e286
--- /dev/null
+++ b/include/llvm/Support/TimeValue.h
@@ -0,0 +1,376 @@
+//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This header file declares the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMEVALUE_H
+#define LLVM_SUPPORT_TIMEVALUE_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+  /// This class is used where a precise fixed point in time is required. The
+  /// range of TimeValue spans many hundreds of billions of years both past and
+  /// present.  The precision of TimeValue is to the nanosecond. However, the
+  /// actual precision of its values will be determined by the resolution of
+  /// the system clock. The TimeValue class is used in conjunction with several
+  /// other lib/System interfaces to specify the time at which a call should
+  /// timeout, etc.
+  /// @since 1.4
+  /// @brief Provides an abstraction for a fixed point in time.
+  class TimeValue {
+
+  /// @name Constants
+  /// @{
+  public:
+
+    /// A constant TimeValue representing the smallest time
+    /// value permissible by the class. MinTime is some point
+    /// in the distant past, about 300 billion years BCE.
+    /// @brief The smallest possible time value.
+    static const TimeValue MinTime;
+
+    /// A constant TimeValue representing the largest time
+    /// value permissible by the class. MaxTime is some point
+    /// in the distant future, about 300 billion years AD.
+    /// @brief The largest possible time value.
+    static const TimeValue MaxTime;
+
+    /// A constant TimeValue representing the base time,
+    /// or zero time of 00:00:00 (midnight) January 1st, 2000.
+    /// @brief 00:00:00 Jan 1, 2000 UTC.
+    static const TimeValue ZeroTime;
+
+    /// A constant TimeValue for the Posix base time which is
+    /// 00:00:00 (midnight) January 1st, 1970.
+    /// @brief 00:00:00 Jan 1, 1970 UTC.
+    static const TimeValue PosixZeroTime;
+
+    /// A constant TimeValue for the Win32 base time which is
+    /// 00:00:00 (midnight) January 1st, 1601.
+    /// @brief 00:00:00 Jan 1, 1601 UTC.
+    static const TimeValue Win32ZeroTime;
+
+  /// @}
+  /// @name Types
+  /// @{
+  public:
+    typedef int64_t SecondsType;    ///< Type used for representing seconds.
+    typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds.
+
+    enum TimeConversions {
+      NANOSECONDS_PER_SECOND = 1000000000,  ///< One Billion
+      MICROSECONDS_PER_SECOND = 1000000,    ///< One Million
+      MILLISECONDS_PER_SECOND = 1000,       ///< One Thousand
+      NANOSECONDS_PER_MICROSECOND = 1000,   ///< One Thousand
+      NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
+      NANOSECONDS_PER_WIN32_TICK = 100      ///< Win32 tick is 10^7 Hz (10ns)
+    };
+
+  /// @}
+  /// @name Constructors
+  /// @{
+  public:
+    /// \brief Default construct a time value, initializing to ZeroTime.
+    TimeValue() : seconds_(0), nanos_(0) {}
+
+    /// Caller provides the exact value in seconds and nanoseconds. The
+    /// \p nanos argument defaults to zero for convenience.
+    /// @brief Explicit constructor
+    explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
+      : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
+
+    /// Caller provides the exact value as a double in seconds with the
+    /// fractional part representing nanoseconds.
+    /// @brief Double Constructor.
+    explicit TimeValue( double new_time )
+      : seconds_( 0 ) , nanos_ ( 0 ) {
+      SecondsType integer_part = static_cast<SecondsType>( new_time );
+      seconds_ = integer_part;
+      nanos_ = static_cast<NanoSecondsType>( (new_time -
+               static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
+      this->normalize();
+    }
+
+    /// This is a static constructor that returns a TimeValue that represents
+    /// the current time.
+    /// @brief Creates a TimeValue with the current time (UTC).
+    static TimeValue now();
+
+  /// @}
+  /// @name Operators
+  /// @{
+  public:
+    /// Add \p that to \p this.
+    /// @returns this
+    /// @brief Incrementing assignment operator.
+    TimeValue& operator += (const TimeValue& that ) {
+      this->seconds_ += that.seconds_  ;
+      this->nanos_ += that.nanos_ ;
+      this->normalize();
+      return *this;
+    }
+
+    /// Subtract \p that from \p this.
+    /// @returns this
+    /// @brief Decrementing assignment operator.
+    TimeValue& operator -= (const TimeValue &that ) {
+      this->seconds_ -= that.seconds_ ;
+      this->nanos_ -= that.nanos_ ;
+      this->normalize();
+      return *this;
+    }
+
+    /// Determine if \p this is less than \p that.
+    /// @returns True iff *this < that.
+    /// @brief True if this < that.
+    int operator < (const TimeValue &that) const { return that > *this; }
+
+    /// Determine if \p this is greather than \p that.
+    /// @returns True iff *this > that.
+    /// @brief True if this > that.
+    int operator > (const TimeValue &that) const {
+      if ( this->seconds_ > that.seconds_ ) {
+          return 1;
+      } else if ( this->seconds_ == that.seconds_ ) {
+          if ( this->nanos_ > that.nanos_ ) return 1;
+      }
+      return 0;
+    }
+
+    /// Determine if \p this is less than or equal to \p that.
+    /// @returns True iff *this <= that.
+    /// @brief True if this <= that.
+    int operator <= (const TimeValue &that) const { return that >= *this; }
+
+    /// Determine if \p this is greater than or equal to \p that.
+    /// @returns True iff *this >= that.
+    int operator >= (const TimeValue &that) const {
+      if ( this->seconds_ > that.seconds_ ) {
+          return 1;
+      } else if ( this->seconds_ == that.seconds_ ) {
+          if ( this->nanos_ >= that.nanos_ ) return 1;
+      }
+      return 0;
+    }
+
+    /// Determines if two TimeValue objects represent the same moment in time.
+    /// @returns True iff *this == that.
+    int operator == (const TimeValue &that) const {
+      return (this->seconds_ == that.seconds_) &&
+             (this->nanos_ == that.nanos_);
+    }
+
+    /// Determines if two TimeValue objects represent times that are not the
+    /// same.
+    /// @returns True iff *this != that.
+    int operator != (const TimeValue &that) const { return !(*this == that); }
+
+    /// Adds two TimeValue objects together.
+    /// @returns The sum of the two operands as a new TimeValue
+    /// @brief Addition operator.
+    friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
+
+    /// Subtracts two TimeValue objects.
+    /// @returns The difference of the two operands as a new TimeValue
+    /// @brief Subtraction operator.
+    friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
+
+  /// @}
+  /// @name Accessors
+  /// @{
+  public:
+
+    /// Returns only the seconds component of the TimeValue. The nanoseconds
+    /// portion is ignored. No rounding is performed.
+    /// @brief Retrieve the seconds component
+    SecondsType seconds() const { return seconds_; }
+
+    /// Returns only the nanoseconds component of the TimeValue. The seconds
+    /// portion is ignored.
+    /// @brief Retrieve the nanoseconds component.
+    NanoSecondsType nanoseconds() const { return nanos_; }
+
+    /// Returns only the fractional portion of the TimeValue rounded down to the
+    /// nearest microsecond (divide by one thousand).
+    /// @brief Retrieve the fractional part as microseconds;
+    uint32_t microseconds() const {
+      return nanos_ / NANOSECONDS_PER_MICROSECOND;
+    }
+
+    /// Returns only the fractional portion of the TimeValue rounded down to the
+    /// nearest millisecond (divide by one million).
+    /// @brief Retrieve the fractional part as milliseconds;
+    uint32_t milliseconds() const {
+      return nanos_ / NANOSECONDS_PER_MILLISECOND;
+    }
+
+    /// Returns the TimeValue as a number of microseconds. Note that the value
+    /// returned can overflow because the range of a uint64_t is smaller than
+    /// the range of a TimeValue. Nevertheless, this is useful on some operating
+    /// systems and is therefore provided.
+    /// @brief Convert to a number of microseconds (can overflow)
+    uint64_t usec() const {
+      return seconds_ * MICROSECONDS_PER_SECOND +
+             ( nanos_ / NANOSECONDS_PER_MICROSECOND );
+    }
+
+    /// Returns the TimeValue as a number of milliseconds. Note that the value
+    /// returned can overflow because the range of a uint64_t is smaller than
+    /// the range of a TimeValue. Nevertheless, this is useful on some operating
+    /// systems and is therefore provided.
+    /// @brief Convert to a number of milliseconds (can overflow)
+    uint64_t msec() const {
+      return seconds_ * MILLISECONDS_PER_SECOND +
+             ( nanos_ / NANOSECONDS_PER_MILLISECOND );
+    }
+
+    /// Converts the TimeValue into the corresponding number of seconds
+    /// since the epoch (00:00:00 Jan 1,1970).
+    uint64_t toEpochTime() const {
+      return seconds_ - PosixZeroTimeSeconds;
+    }
+
+    /// Converts the TimeValue into the corresponding number of "ticks" for
+    /// Win32 platforms, correcting for the difference in Win32 zero time.
+    /// @brief Convert to Win32's FILETIME
+    /// (100ns intervals since 00:00:00 Jan 1, 1601 UTC)
+    uint64_t toWin32Time() const {
+      uint64_t result = (uint64_t)10000000 * (seconds_ - Win32ZeroTimeSeconds);
+      result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
+      return result;
+    }
+
+    /// Provides the seconds and nanoseconds as results in its arguments after
+    /// correction for the Posix zero time.
+    /// @brief Convert to timespec time (ala POSIX.1b)
+    void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
+      seconds = seconds_ - PosixZeroTimeSeconds;
+      nanos = nanos_;
+    }
+
+    /// Provides conversion of the TimeValue into a readable time & date.
+    /// @returns std::string containing the readable time value
+    /// @brief Convert time to a string.
+    std::string str() const;
+
+  /// @}
+  /// @name Mutators
+  /// @{
+  public:
+    /// The seconds component of the TimeValue is set to \p sec without
+    /// modifying the nanoseconds part.  This is useful for whole second
+    /// arithmetic.
+    /// @brief Set the seconds component.
+    void seconds (SecondsType sec ) {
+      this->seconds_ = sec;
+      this->normalize();
+    }
+
+    /// The nanoseconds component of the TimeValue is set to \p nanos without
+    /// modifying the seconds part. This is useful for basic computations
+    /// involving just the nanoseconds portion. Note that the TimeValue will be
+    /// normalized after this call so that the fractional (nanoseconds) portion
+    /// will have the smallest equivalent value.
+    /// @brief Set the nanoseconds component using a number of nanoseconds.
+    void nanoseconds ( NanoSecondsType nanos ) {
+      this->nanos_ = nanos;
+      this->normalize();
+    }
+
+    /// The seconds component remains unchanged.
+    /// @brief Set the nanoseconds component using a number of microseconds.
+    void microseconds ( int32_t micros ) {
+      this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
+      this->normalize();
+    }
+
+    /// The seconds component remains unchanged.
+    /// @brief Set the nanoseconds component using a number of milliseconds.
+    void milliseconds ( int32_t millis ) {
+      this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
+      this->normalize();
+    }
+
+    /// @brief Converts from microsecond format to TimeValue format
+    void usec( int64_t microseconds ) {
+      this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
+      this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
+        NANOSECONDS_PER_MICROSECOND;
+      this->normalize();
+    }
+
+    /// @brief Converts from millisecond format to TimeValue format
+    void msec( int64_t milliseconds ) {
+      this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
+      this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
+        NANOSECONDS_PER_MILLISECOND;
+      this->normalize();
+    }
+
+    /// Converts the \p seconds argument from PosixTime to the corresponding
+    /// TimeValue and assigns that value to \p this.
+    /// @brief Convert seconds form PosixTime to TimeValue
+    void fromEpochTime( SecondsType seconds ) {
+      seconds_ = seconds + PosixZeroTimeSeconds;
+      nanos_ = 0;
+      this->normalize();
+    }
+
+    /// Converts the \p win32Time argument from Windows FILETIME to the
+    /// corresponding TimeValue and assigns that value to \p this.
+    /// @brief Convert seconds form Windows FILETIME to TimeValue
+    void fromWin32Time( uint64_t win32Time ) {
+      this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds;
+      this->nanos_ = NanoSecondsType(win32Time  % 10000000) * 100;
+    }
+
+  /// @}
+  /// @name Implementation
+  /// @{
+  private:
+    /// This causes the values to be represented so that the fractional
+    /// part is minimized, possibly incrementing the seconds part.
+    /// @brief Normalize to canonical form.
+    void normalize();
+
+  /// @}
+  /// @name Data
+  /// @{
+  private:
+    /// Store the values as a <timeval>.
+    SecondsType      seconds_;///< Stores the seconds part of the TimeVal
+    NanoSecondsType  nanos_;  ///< Stores the nanoseconds part of the TimeVal
+
+    static const SecondsType PosixZeroTimeSeconds;
+    static const SecondsType Win32ZeroTimeSeconds;
+  /// @}
+
+  };
+
+inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
+  TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
+  sum.normalize ();
+  return sum;
+}
+
+inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
+  TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
+  difference.normalize ();
+  return difference;
+}
+
+}
+}
+
+#endif
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
new file mode 100644
index 0000000..45c1828
--- /dev/null
+++ b/include/llvm/Support/Timer.h
@@ -0,0 +1,190 @@
+//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMER_H
+#define LLVM_SUPPORT_TIMER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class Timer;
+class TimerGroup;
+class raw_ostream;
+
+class TimeRecord {
+  double WallTime;       // Wall clock time elapsed in seconds
+  double UserTime;       // User time elapsed
+  double SystemTime;     // System time elapsed
+  ssize_t MemUsed;       // Memory allocated (in bytes)
+public:
+  TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
+  
+  /// getCurrentTime - Get the current time and memory usage.  If Start is true
+  /// we get the memory usage before the time, otherwise we get time before
+  /// memory usage.  This matters if the time to get the memory usage is
+  /// significant and shouldn't be counted as part of a duration.
+  static TimeRecord getCurrentTime(bool Start = true);
+  
+  double getProcessTime() const { return UserTime+SystemTime; }
+  double getUserTime() const { return UserTime; }
+  double getSystemTime() const { return SystemTime; }
+  double getWallTime() const { return WallTime; }
+  ssize_t getMemUsed() const { return MemUsed; }
+  
+  
+  // operator< - Allow sorting.
+  bool operator<(const TimeRecord &T) const {
+    // Sort by Wall Time elapsed, as it is the only thing really accurate
+    return WallTime < T.WallTime;
+  }
+  
+  void operator+=(const TimeRecord &RHS) {
+    WallTime   += RHS.WallTime;
+    UserTime   += RHS.UserTime;
+    SystemTime += RHS.SystemTime;
+    MemUsed    += RHS.MemUsed;
+  }
+  void operator-=(const TimeRecord &RHS) {
+    WallTime   -= RHS.WallTime;
+    UserTime   -= RHS.UserTime;
+    SystemTime -= RHS.SystemTime;
+    MemUsed    -= RHS.MemUsed;
+  }
+  
+  /// print - Print the current timer to standard error, and reset the "Started"
+  /// flag.
+  void print(const TimeRecord &Total, raw_ostream &OS) const;
+};
+  
+/// Timer - This class is used to track the amount of time spent between
+/// invocations of its startTimer()/stopTimer() methods.  Given appropriate OS
+/// support it can also keep track of the RSS of the program at various points.
+/// By default, the Timer will print the amount of time it has captured to
+/// standard error when the last timer is destroyed, otherwise it is printed
+/// when its TimerGroup is destroyed.  Timers do not print their information
+/// if they are never started.
+///
+class Timer {
+  TimeRecord Time;
+  std::string Name;      // The name of this time variable.
+  bool Started;          // Has this time variable ever been started?
+  TimerGroup *TG;        // The TimerGroup this Timer is in.
+  
+  Timer **Prev, *Next;   // Doubly linked list of timers in the group.
+public:
+  explicit Timer(StringRef N) : TG(nullptr) { init(N); }
+  Timer(StringRef N, TimerGroup &tg) : TG(nullptr) { init(N, tg); }
+  Timer(const Timer &RHS) : TG(nullptr) {
+    assert(!RHS.TG && "Can only copy uninitialized timers");
+  }
+  const Timer &operator=(const Timer &T) {
+    assert(!TG && !T.TG && "Can only assign uninit timers");
+    return *this;
+  }
+  ~Timer();
+
+  // Create an uninitialized timer, client must use 'init'.
+  explicit Timer() : TG(nullptr) {}
+  void init(StringRef N);
+  void init(StringRef N, TimerGroup &tg);
+  
+  const std::string &getName() const { return Name; }
+  bool isInitialized() const { return TG != nullptr; }
+  
+  /// startTimer - Start the timer running.  Time between calls to
+  /// startTimer/stopTimer is counted by the Timer class.  Note that these calls
+  /// must be correctly paired.
+  ///
+  void startTimer();
+
+  /// stopTimer - Stop the timer.
+  ///
+  void stopTimer();
+
+private:
+  friend class TimerGroup;
+};
+
+
+/// The TimeRegion class is used as a helper class to call the startTimer() and
+/// stopTimer() methods of the Timer class.  When the object is constructed, it
+/// starts the timer specified as its argument.  When it is destroyed, it stops
+/// the relevant timer.  This makes it easy to time a region of code.
+///
+class TimeRegion {
+  Timer *T;
+  TimeRegion(const TimeRegion &) LLVM_DELETED_FUNCTION;
+public:
+  explicit TimeRegion(Timer &t) : T(&t) {
+    T->startTimer();
+  }
+  explicit TimeRegion(Timer *t) : T(t) {
+    if (T) T->startTimer();
+  }
+  ~TimeRegion() {
+    if (T) T->stopTimer();
+  }
+};
+
+
+/// NamedRegionTimer - This class is basically a combination of TimeRegion and
+/// Timer.  It allows you to declare a new timer, AND specify the region to
+/// time, all in one statement.  All timers with the same name are merged.  This
+/// is primarily used for debugging and for hunting performance problems.
+///
+struct NamedRegionTimer : public TimeRegion {
+  explicit NamedRegionTimer(StringRef Name,
+                            bool Enabled = true);
+  explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
+                            bool Enabled = true);
+};
+
+
+/// The TimerGroup class is used to group together related timers into a single
+/// report that is printed when the TimerGroup is destroyed.  It is illegal to
+/// destroy a TimerGroup object before all of the Timers in it are gone.  A
+/// TimerGroup can be specified for a newly created timer in its constructor.
+///
+class TimerGroup {
+  std::string Name;
+  Timer *FirstTimer;   // First timer in the group.
+  std::vector<std::pair<TimeRecord, std::string> > TimersToPrint;
+  
+  TimerGroup **Prev, *Next; // Doubly linked list of TimerGroup's.
+  TimerGroup(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
+  void operator=(const TimerGroup &TG) LLVM_DELETED_FUNCTION;
+public:
+  explicit TimerGroup(StringRef name);
+  ~TimerGroup();
+
+  void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
+
+  /// print - Print any started timers in this group and zero them.
+  void print(raw_ostream &OS);
+  
+  /// printAll - This static method prints all timers and clears them all out.
+  static void printAll(raw_ostream &OS);
+  
+private:
+  friend class Timer;
+  void addTimer(Timer &T);
+  void removeTimer(Timer &T);
+  void PrintQueuedTimers(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
new file mode 100644
index 0000000..88f8ccc
--- /dev/null
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -0,0 +1,64 @@
+//===- ToolOutputFile.h - Output files for compiler-like tools -----------===//
+//
+//                     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 tool_output_file class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
+#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// tool_output_file - This class contains a raw_fd_ostream and adds a
+/// few extra features commonly needed for compiler-like tool output files:
+///   - The file is automatically deleted if the process is killed.
+///   - The file is automatically deleted when the tool_output_file
+///     object is destroyed unless the client calls keep().
+class tool_output_file {
+  /// Installer - This class is declared before the raw_fd_ostream so that
+  /// it is constructed before the raw_fd_ostream is constructed and
+  /// destructed after the raw_fd_ostream is destructed. It installs
+  /// cleanups in its constructor and uninstalls them in its destructor.
+  class CleanupInstaller {
+    /// Filename - The name of the file.
+    std::string Filename;
+  public:
+    /// Keep - The flag which indicates whether we should not delete the file.
+    bool Keep;
+
+    explicit CleanupInstaller(const char *filename);
+    ~CleanupInstaller();
+  } Installer;
+
+  /// OS - The contained stream. This is intentionally declared after
+  /// Installer.
+  raw_fd_ostream OS;
+
+public:
+  /// tool_output_file - This constructor's arguments are passed to
+  /// to raw_fd_ostream's constructor.
+  tool_output_file(const char *filename, std::string &ErrorInfo,
+                   sys::fs::OpenFlags Flags);
+
+  tool_output_file(const char *Filename, int FD);
+
+  /// os - Return the contained raw_fd_ostream.
+  raw_fd_ostream &os() { return OS; }
+
+  /// keep - Indicate that the tool's job wrt this output file has been
+  /// successful and the file should not be deleted.
+  void keep() { Installer.Keep = true; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Unicode.h b/include/llvm/Support/Unicode.h
new file mode 100644
index 0000000..f668a5b
--- /dev/null
+++ b/include/llvm/Support/Unicode.h
@@ -0,0 +1,67 @@
+//===- llvm/Support/Unicode.h - Unicode character properties  -*- 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 functions that allow querying certain properties of Unicode
+// characters.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_UNICODE_H
+#define LLVM_SUPPORT_UNICODE_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace sys {
+namespace unicode {
+
+enum ColumnWidthErrors {
+  ErrorInvalidUTF8 = -2,
+  ErrorNonPrintableCharacter = -1
+};
+
+/// Determines if a character is likely to be displayed correctly on the
+/// terminal. Exact implementation would have to depend on the specific
+/// terminal, so we define the semantic that should be suitable for generic case
+/// of a terminal capable to output Unicode characters.
+///
+/// All characters from the Unicode code point range are considered printable
+/// except for:
+///   * C0 and C1 control character ranges;
+///   * default ignorable code points as per 5.21 of
+///     http://www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf
+///     except for U+00AD SOFT HYPHEN, as it's actually displayed on most
+///     terminals;
+///   * format characters (category = Cf);
+///   * surrogates (category = Cs);
+///   * unassigned characters (category = Cn).
+/// \return true if the character is considered printable.
+bool isPrintable(int UCS);
+
+/// Gets the number of positions the UTF8-encoded \p Text is likely to occupy
+/// when output on a terminal ("character width"). This depends on the
+/// implementation of the terminal, and there's no standard definition of
+/// character width.
+///
+/// The implementation defines it in a way that is expected to be compatible
+/// with a generic Unicode-capable terminal.
+///
+/// \return Character width:
+///   * ErrorNonPrintableCharacter (-1) if \p Text contains non-printable
+///     characters (as identified by isPrintable);
+///   * 0 for each non-spacing and enclosing combining mark;
+///   * 2 for each CJK character excluding halfwidth forms;
+///   * 1 for each of the remaining characters.
+int columnWidthUTF8(StringRef Text);
+
+} // namespace unicode
+} // namespace sys
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
new file mode 100644
index 0000000..79137bf
--- /dev/null
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -0,0 +1,99 @@
+//===--- UnicodeCharRanges.h - Types and functions for character ranges ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_UNICODECHARRANGES_H
+#define LLVM_SUPPORT_UNICODECHARRANGES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+namespace sys {
+
+#define DEBUG_TYPE "unicode"
+
+/// \brief Represents a closed range of Unicode code points [Lower, Upper].
+struct UnicodeCharRange {
+  uint32_t Lower;
+  uint32_t Upper;
+};
+
+inline bool operator<(uint32_t Value, UnicodeCharRange Range) {
+  return Value < Range.Lower;
+}
+inline bool operator<(UnicodeCharRange Range, uint32_t Value) {
+  return Range.Upper < Value;
+}
+
+/// \brief Holds a reference to an ordered array of UnicodeCharRange and allows
+/// to quickly check if a code point is contained in the set represented by this
+/// array.
+class UnicodeCharSet {
+public:
+  typedef ArrayRef<UnicodeCharRange> CharRanges;
+
+  /// \brief Constructs a UnicodeCharSet instance from an array of
+  /// UnicodeCharRanges.
+  ///
+  /// Array pointed by \p Ranges should have the lifetime at least as long as
+  /// the UnicodeCharSet instance, and should not change. Array is validated by
+  /// the constructor, so it makes sense to create as few UnicodeCharSet
+  /// instances per each array of ranges, as possible.
+  UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {
+    assert(rangesAreValid());
+  }
+
+  /// \brief Returns true if the character set contains the Unicode code point
+  /// \p C.
+  bool contains(uint32_t C) const {
+    return std::binary_search(Ranges.begin(), Ranges.end(), C);
+  }
+
+private:
+  /// \brief Returns true if each of the ranges is a proper closed range
+  /// [min, max], and if the ranges themselves are ordered and non-overlapping.
+  bool rangesAreValid() const {
+    uint32_t Prev = 0;
+    for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
+         I != E; ++I) {
+      if (I != Ranges.begin() && Prev >= I->Lower) {
+        DEBUG(dbgs() << "Upper bound 0x");
+        DEBUG(dbgs().write_hex(Prev));
+        DEBUG(dbgs() << " should be less than succeeding lower bound 0x");
+        DEBUG(dbgs().write_hex(I->Lower) << "\n");
+        return false;
+      }
+      if (I->Upper < I->Lower) {
+        DEBUG(dbgs() << "Upper bound 0x");
+        DEBUG(dbgs().write_hex(I->Lower));
+        DEBUG(dbgs() << " should not be less than lower bound 0x");
+        DEBUG(dbgs().write_hex(I->Upper) << "\n");
+        return false;
+      }
+      Prev = I->Upper;
+    }
+
+    return true;
+  }
+
+  const CharRanges Ranges;
+};
+
+#undef DEBUG_TYPE // "unicode"
+
+} // namespace sys
+} // namespace llvm
+
+
+#endif // LLVM_SUPPORT_UNICODECHARRANGES_H
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
new file mode 100644
index 0000000..cebf75c
--- /dev/null
+++ b/include/llvm/Support/Valgrind.h
@@ -0,0 +1,73 @@
+//===- llvm/Support/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for communicating with a valgrind instance this program is running
+// under.  These are all no-ops unless LLVM was configured on a system with the
+// valgrind headers installed and valgrind is controlling this process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_VALGRIND_H
+#define LLVM_SUPPORT_VALGRIND_H
+
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
+#include <stddef.h>
+
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact
+// functions by name.
+extern "C" {
+void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
+void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
+void AnnotateIgnoreWritesBegin(const char *file, int line);
+void AnnotateIgnoreWritesEnd(const char *file, int line);
+}
+#endif
+
+namespace llvm {
+namespace sys {
+  // True if Valgrind is controlling this process.
+  bool RunningOnValgrind();
+
+  // Discard valgrind's translation of code in the range [Addr .. Addr + Len).
+  // Otherwise valgrind may continue to execute the old version of the code.
+  void ValgrindDiscardTranslations(const void *Addr, size_t Len);
+
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+  // Thread Sanitizer is a valgrind tool that finds races in code.
+  // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
+
+  // This marker is used to define a happens-before arc. The race detector will
+  // infer an arc from the begin to the end when they share the same pointer
+  // argument.
+  #define TsanHappensBefore(cv) \
+    AnnotateHappensBefore(__FILE__, __LINE__, cv)
+
+  // This marker defines the destination of a happens-before arc.
+  #define TsanHappensAfter(cv) \
+    AnnotateHappensAfter(__FILE__, __LINE__, cv)
+
+  // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
+  #define TsanIgnoreWritesBegin() \
+    AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
+
+  // Resume checking for racy writes.
+  #define TsanIgnoreWritesEnd() \
+    AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
+#else
+  #define TsanHappensBefore(cv)
+  #define TsanHappensAfter(cv)
+  #define TsanIgnoreWritesBegin()
+  #define TsanIgnoreWritesEnd()
+#endif
+}
+}
+
+#endif
diff --git a/include/llvm/Support/Watchdog.h b/include/llvm/Support/Watchdog.h
new file mode 100644
index 0000000..b58496b
--- /dev/null
+++ b/include/llvm/Support/Watchdog.h
@@ -0,0 +1,38 @@
+//===--- Watchdog.h - Watchdog timer ----------------------------*- 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 llvm::sys::Watchdog class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WATCHDOG_H
+#define LLVM_SUPPORT_WATCHDOG_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  namespace sys {
+
+    /// This class provides an abstraction for a timeout around an operation
+    /// that must complete in a given amount of time. Failure to complete before
+    /// the timeout is an unrecoverable situation and no mechanisms to attempt
+    /// to handle it are provided.
+    class Watchdog {
+    public:
+      Watchdog(unsigned int seconds);
+      ~Watchdog();
+    private:
+      // Noncopyable.
+      Watchdog(const Watchdog &other) LLVM_DELETED_FUNCTION;
+      Watchdog &operator=(const Watchdog &other) LLVM_DELETED_FUNCTION;
+    };
+  }
+}
+
+#endif
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
new file mode 100644
index 0000000..7ca218e
--- /dev/null
+++ b/include/llvm/Support/Win64EH.h
@@ -0,0 +1,147 @@
+//===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants and structures used for implementing
+// exception handling on Win64 platforms. For more information, see
+// http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WIN64EH_H
+#define LLVM_SUPPORT_WIN64EH_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace Win64EH {
+
+/// UnwindOpcodes - Enumeration whose values specify a single operation in
+/// the prolog of a function.
+enum UnwindOpcodes {
+  UOP_PushNonVol = 0,
+  UOP_AllocLarge,
+  UOP_AllocSmall,
+  UOP_SetFPReg,
+  UOP_SaveNonVol,
+  UOP_SaveNonVolBig,
+  UOP_SaveXMM128 = 8,
+  UOP_SaveXMM128Big,
+  UOP_PushMachFrame
+};
+
+/// UnwindCode - This union describes a single operation in a function prolog,
+/// or part thereof.
+union UnwindCode {
+  struct {
+    support::ulittle8_t CodeOffset;
+    support::ulittle8_t UnwindOpAndOpInfo;
+  } u;
+  support::ulittle16_t FrameOffset;
+
+  uint8_t getUnwindOp() const {
+    return u.UnwindOpAndOpInfo & 0x0F;
+  }
+  uint8_t getOpInfo() const {
+    return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
+  }
+};
+
+enum {
+  /// UNW_ExceptionHandler - Specifies that this function has an exception
+  /// handler.
+  UNW_ExceptionHandler = 0x01,
+  /// UNW_TerminateHandler - Specifies that this function has a termination
+  /// handler.
+  UNW_TerminateHandler = 0x02,
+  /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
+  /// another one.
+  UNW_ChainInfo = 0x04
+};
+
+/// RuntimeFunction - An entry in the table of functions with unwind info.
+struct RuntimeFunction {
+  support::ulittle32_t StartAddress;
+  support::ulittle32_t EndAddress;
+  support::ulittle32_t UnwindInfoOffset;
+};
+
+/// UnwindInfo - An entry in the exception table.
+struct UnwindInfo {
+  support::ulittle8_t VersionAndFlags;
+  support::ulittle8_t PrologSize;
+  support::ulittle8_t NumCodes;
+  support::ulittle8_t FrameRegisterAndOffset;
+  UnwindCode UnwindCodes[1];
+
+  uint8_t getVersion() const {
+    return VersionAndFlags & 0x07;
+  }
+  uint8_t getFlags() const {
+    return (VersionAndFlags >> 3) & 0x1f;
+  }
+  uint8_t getFrameRegister() const {
+    return FrameRegisterAndOffset & 0x0f;
+  }
+  uint8_t getFrameOffset() const {
+    return (FrameRegisterAndOffset >> 4) & 0x0f;
+  }
+
+  // The data after unwindCodes depends on flags.
+  // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
+  // the address of the language-specific exception handler.
+  // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
+  // the chained unwind info.
+  // For more information please see MSDN at:
+  // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
+
+  /// \brief Return pointer to language specific data part of UnwindInfo.
+  void *getLanguageSpecificData() {
+    return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
+  }
+
+  /// \brief Return pointer to language specific data part of UnwindInfo.
+  const void *getLanguageSpecificData() const {
+    return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
+  }
+
+  /// \brief Return image-relative offset of language-specific exception handler.
+  uint32_t getLanguageSpecificHandlerOffset() const {
+    return *reinterpret_cast<const support::ulittle32_t *>(
+               getLanguageSpecificData());
+  }
+
+  /// \brief Set image-relative offset of language-specific exception handler.
+  void setLanguageSpecificHandlerOffset(uint32_t offset) {
+    *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
+        offset;
+  }
+
+  /// \brief Return pointer to exception-specific data.
+  void *getExceptionData() {
+    return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
+                                                  getLanguageSpecificData())+1);
+  }
+
+  /// \brief Return pointer to chained unwind info.
+  RuntimeFunction *getChainedFunctionEntry() {
+    return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+  }
+
+  /// \brief Return pointer to chained unwind info.
+  const RuntimeFunction *getChainedFunctionEntry() const {
+    return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
+  }
+};
+
+
+} // End of namespace Win64EH
+} // End of namespace llvm
+
+#endif
diff --git a/include/llvm/Support/WindowsError.h b/include/llvm/Support/WindowsError.h
new file mode 100644
index 0000000..0e909a0
--- /dev/null
+++ b/include/llvm/Support/WindowsError.h
@@ -0,0 +1,19 @@
+//===-- WindowsError.h - Support for mapping windows errors to posix-------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WINDOWS_ERROR_H
+#define LLVM_SUPPORT_WINDOWS_ERROR_H
+
+#include <system_error>
+
+namespace llvm {
+std::error_code mapWindowsError(unsigned EV);
+}
+
+#endif
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
new file mode 100644
index 0000000..c39874c
--- /dev/null
+++ b/include/llvm/Support/YAMLParser.h
@@ -0,0 +1,557 @@
+//===--- YAMLParser.h - Simple YAML parser --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This is a YAML 1.2 parser.
+//
+//  See http://www.yaml.org/spec/1.2/spec.html for the full standard.
+//
+//  This currently does not implement the following:
+//    * Multi-line literal folding.
+//    * Tag resolution.
+//    * UTF-16.
+//    * BOMs anywhere other than the first Unicode scalar value in the file.
+//
+//  The most important class here is Stream. This represents a YAML stream with
+//  0, 1, or many documents.
+//
+//  SourceMgr sm;
+//  StringRef input = getInput();
+//  yaml::Stream stream(input, sm);
+//
+//  for (yaml::document_iterator di = stream.begin(), de = stream.end();
+//       di != de; ++di) {
+//    yaml::Node *n = di->getRoot();
+//    if (n) {
+//      // Do something with n...
+//    } else
+//      break;
+//  }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAMLPARSER_H
+#define LLVM_SUPPORT_YAMLPARSER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/SMLoc.h"
+#include <limits>
+#include <map>
+#include <utility>
+
+namespace llvm {
+class MemoryBuffer;
+class SourceMgr;
+class raw_ostream;
+class Twine;
+
+namespace yaml {
+
+class document_iterator;
+class Document;
+class Node;
+class Scanner;
+struct Token;
+
+/// \brief Dump all the tokens in this stream to OS.
+/// \returns true if there was an error, false otherwise.
+bool dumpTokens(StringRef Input, raw_ostream &);
+
+/// \brief Scans all tokens in input without outputting anything. This is used
+///        for benchmarking the tokenizer.
+/// \returns true if there was an error, false otherwise.
+bool scanTokens(StringRef Input);
+
+/// \brief Escape \a Input for a double quoted scalar.
+std::string escape(StringRef Input);
+
+/// \brief This class represents a YAML stream potentially containing multiple
+///        documents.
+class Stream {
+public:
+  /// \brief This keeps a reference to the string referenced by \p Input.
+  Stream(StringRef Input, SourceMgr &);
+
+  /// \brief This takes ownership of \p InputBuffer.
+  Stream(MemoryBuffer *InputBuffer, SourceMgr &);
+  ~Stream();
+
+  document_iterator begin();
+  document_iterator end();
+  void skip();
+  bool failed();
+  bool validate() {
+    skip();
+    return !failed();
+  }
+
+  void printError(Node *N, const Twine &Msg);
+
+private:
+  std::unique_ptr<Scanner> scanner;
+  std::unique_ptr<Document> CurrentDoc;
+
+  friend class Document;
+};
+
+/// \brief Abstract base class for all Nodes.
+class Node {
+  virtual void anchor();
+
+public:
+  enum NodeKind {
+    NK_Null,
+    NK_Scalar,
+    NK_KeyValue,
+    NK_Mapping,
+    NK_Sequence,
+    NK_Alias
+  };
+
+  Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
+       StringRef Tag);
+
+  /// \brief Get the value of the anchor attached to this node. If it does not
+  ///        have one, getAnchor().size() will be 0.
+  StringRef getAnchor() const { return Anchor; }
+
+  /// \brief Get the tag as it was written in the document. This does not
+  ///   perform tag resolution.
+  StringRef getRawTag() const { return Tag; }
+
+  /// \brief Get the verbatium tag for a given Node. This performs tag resoluton
+  ///   and substitution.
+  std::string getVerbatimTag() const;
+
+  SMRange getSourceRange() const { return SourceRange; }
+  void setSourceRange(SMRange SR) { SourceRange = SR; }
+
+  // These functions forward to Document and Scanner.
+  Token &peekNext();
+  Token getNext();
+  Node *parseBlockNode();
+  BumpPtrAllocator &getAllocator();
+  void setError(const Twine &Message, Token &Location) const;
+  bool failed() const;
+
+  virtual void skip() {}
+
+  unsigned int getType() const { return TypeID; }
+
+  void *operator new(size_t Size, BumpPtrAllocator &Alloc,
+                     size_t Alignment = 16) throw() {
+    return Alloc.Allocate(Size, Alignment);
+  }
+
+  void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t Size) throw() {
+    Alloc.Deallocate(Ptr, Size);
+  }
+
+protected:
+  std::unique_ptr<Document> &Doc;
+  SMRange SourceRange;
+
+  void operator delete(void *) throw() {}
+
+  virtual ~Node() {}
+
+private:
+  unsigned int TypeID;
+  StringRef Anchor;
+  /// \brief The tag as typed in the document.
+  StringRef Tag;
+};
+
+/// \brief A null value.
+///
+/// Example:
+///   !!null null
+class NullNode : public Node {
+  void anchor() override;
+
+public:
+  NullNode(std::unique_ptr<Document> &D)
+      : Node(NK_Null, D, StringRef(), StringRef()) {}
+
+  static inline bool classof(const Node *N) { return N->getType() == NK_Null; }
+};
+
+/// \brief A scalar node is an opaque datum that can be presented as a
+///        series of zero or more Unicode scalar values.
+///
+/// Example:
+///   Adena
+class ScalarNode : public Node {
+  void anchor() override;
+
+public:
+  ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
+             StringRef Val)
+      : Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
+    SMLoc Start = SMLoc::getFromPointer(Val.begin());
+    SMLoc End = SMLoc::getFromPointer(Val.end());
+    SourceRange = SMRange(Start, End);
+  }
+
+  // Return Value without any escaping or folding or other fun YAML stuff. This
+  // is the exact bytes that are contained in the file (after conversion to
+  // utf8).
+  StringRef getRawValue() const { return Value; }
+
+  /// \brief Gets the value of this node as a StringRef.
+  ///
+  /// \param Storage is used to store the content of the returned StringRef iff
+  ///        it requires any modification from how it appeared in the source.
+  ///        This happens with escaped characters and multi-line literals.
+  StringRef getValue(SmallVectorImpl<char> &Storage) const;
+
+  static inline bool classof(const Node *N) {
+    return N->getType() == NK_Scalar;
+  }
+
+private:
+  StringRef Value;
+
+  StringRef unescapeDoubleQuoted(StringRef UnquotedValue,
+                                 StringRef::size_type Start,
+                                 SmallVectorImpl<char> &Storage) const;
+};
+
+/// \brief A key and value pair. While not technically a Node under the YAML
+///        representation graph, it is easier to treat them this way.
+///
+/// TODO: Consider making this not a child of Node.
+///
+/// Example:
+///   Section: .text
+class KeyValueNode : public Node {
+  void anchor() override;
+
+public:
+  KeyValueNode(std::unique_ptr<Document> &D)
+      : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr),
+        Value(nullptr) {}
+
+  /// \brief Parse and return the key.
+  ///
+  /// This may be called multiple times.
+  ///
+  /// \returns The key, or nullptr if failed() == true.
+  Node *getKey();
+
+  /// \brief Parse and return the value.
+  ///
+  /// This may be called multiple times.
+  ///
+  /// \returns The value, or nullptr if failed() == true.
+  Node *getValue();
+
+  void skip() override {
+    getKey()->skip();
+    getValue()->skip();
+  }
+
+  static inline bool classof(const Node *N) {
+    return N->getType() == NK_KeyValue;
+  }
+
+private:
+  Node *Key;
+  Node *Value;
+};
+
+/// \brief This is an iterator abstraction over YAML collections shared by both
+///        sequences and maps.
+///
+/// BaseT must have a ValueT* member named CurrentEntry and a member function
+/// increment() which must set CurrentEntry to 0 to create an end iterator.
+template <class BaseT, class ValueT>
+class basic_collection_iterator
+    : public std::iterator<std::forward_iterator_tag, ValueT> {
+public:
+  basic_collection_iterator() : Base(nullptr) {}
+  basic_collection_iterator(BaseT *B) : Base(B) {}
+
+  ValueT *operator->() const {
+    assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+    return Base->CurrentEntry;
+  }
+
+  ValueT &operator*() const {
+    assert(Base && Base->CurrentEntry &&
+           "Attempted to dereference end iterator!");
+    return *Base->CurrentEntry;
+  }
+
+  operator ValueT *() const {
+    assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+    return Base->CurrentEntry;
+  }
+
+  bool operator!=(const basic_collection_iterator &Other) const {
+    if (Base != Other.Base)
+      return true;
+    return (Base && Other.Base) &&
+           Base->CurrentEntry != Other.Base->CurrentEntry;
+  }
+
+  basic_collection_iterator &operator++() {
+    assert(Base && "Attempted to advance iterator past end!");
+    Base->increment();
+    // Create an end iterator.
+    if (!Base->CurrentEntry)
+      Base = nullptr;
+    return *this;
+  }
+
+private:
+  BaseT *Base;
+};
+
+// The following two templates are used for both MappingNode and Sequence Node.
+template <class CollectionType>
+typename CollectionType::iterator begin(CollectionType &C) {
+  assert(C.IsAtBeginning && "You may only iterate over a collection once!");
+  C.IsAtBeginning = false;
+  typename CollectionType::iterator ret(&C);
+  ++ret;
+  return ret;
+}
+
+template <class CollectionType> void skip(CollectionType &C) {
+  // TODO: support skipping from the middle of a parsed collection ;/
+  assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
+  if (C.IsAtBeginning)
+    for (typename CollectionType::iterator i = begin(C), e = C.end(); i != e;
+         ++i)
+      i->skip();
+}
+
+/// \brief Represents a YAML map created from either a block map for a flow map.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+///   Name: _main
+///   Scope: Global
+class MappingNode : public Node {
+  void anchor() override;
+
+public:
+  enum MappingType {
+    MT_Block,
+    MT_Flow,
+    MT_Inline ///< An inline mapping node is used for "[key: value]".
+  };
+
+  MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
+              MappingType MT)
+      : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
+        IsAtEnd(false), CurrentEntry(nullptr) {}
+
+  friend class basic_collection_iterator<MappingNode, KeyValueNode>;
+  typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
+  template <class T> friend typename T::iterator yaml::begin(T &);
+  template <class T> friend void yaml::skip(T &);
+
+  iterator begin() { return yaml::begin(*this); }
+
+  iterator end() { return iterator(); }
+
+  void skip() override { yaml::skip(*this); }
+
+  static inline bool classof(const Node *N) {
+    return N->getType() == NK_Mapping;
+  }
+
+private:
+  MappingType Type;
+  bool IsAtBeginning;
+  bool IsAtEnd;
+  KeyValueNode *CurrentEntry;
+
+  void increment();
+};
+
+/// \brief Represents a YAML sequence created from either a block sequence for a
+///        flow sequence.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+///   - Hello
+///   - World
+class SequenceNode : public Node {
+  void anchor() override;
+
+public:
+  enum SequenceType {
+    ST_Block,
+    ST_Flow,
+    // Use for:
+    //
+    // key:
+    // - val1
+    // - val2
+    //
+    // As a BlockMappingEntry and BlockEnd are not created in this case.
+    ST_Indentless
+  };
+
+  SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
+               SequenceType ST)
+      : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
+        IsAtEnd(false),
+        WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
+        CurrentEntry(nullptr) {}
+
+  friend class basic_collection_iterator<SequenceNode, Node>;
+  typedef basic_collection_iterator<SequenceNode, Node> iterator;
+  template <class T> friend typename T::iterator yaml::begin(T &);
+  template <class T> friend void yaml::skip(T &);
+
+  void increment();
+
+  iterator begin() { return yaml::begin(*this); }
+
+  iterator end() { return iterator(); }
+
+  void skip() override { yaml::skip(*this); }
+
+  static inline bool classof(const Node *N) {
+    return N->getType() == NK_Sequence;
+  }
+
+private:
+  SequenceType SeqType;
+  bool IsAtBeginning;
+  bool IsAtEnd;
+  bool WasPreviousTokenFlowEntry;
+  Node *CurrentEntry;
+};
+
+/// \brief Represents an alias to a Node with an anchor.
+///
+/// Example:
+///   *AnchorName
+class AliasNode : public Node {
+  void anchor() override;
+
+public:
+  AliasNode(std::unique_ptr<Document> &D, StringRef Val)
+      : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
+
+  StringRef getName() const { return Name; }
+  Node *getTarget();
+
+  static inline bool classof(const Node *N) { return N->getType() == NK_Alias; }
+
+private:
+  StringRef Name;
+};
+
+/// \brief A YAML Stream is a sequence of Documents. A document contains a root
+///        node.
+class Document {
+public:
+  /// \brief Root for parsing a node. Returns a single node.
+  Node *parseBlockNode();
+
+  Document(Stream &ParentStream);
+
+  /// \brief Finish parsing the current document and return true if there are
+  ///        more. Return false otherwise.
+  bool skip();
+
+  /// \brief Parse and return the root level node.
+  Node *getRoot() {
+    if (Root)
+      return Root;
+    return Root = parseBlockNode();
+  }
+
+  const std::map<StringRef, StringRef> &getTagMap() const { return TagMap; }
+
+private:
+  friend class Node;
+  friend class document_iterator;
+
+  /// \brief Stream to read tokens from.
+  Stream &stream;
+
+  /// \brief Used to allocate nodes to. All are destroyed without calling their
+  ///        destructor when the document is destroyed.
+  BumpPtrAllocator NodeAllocator;
+
+  /// \brief The root node. Used to support skipping a partially parsed
+  ///        document.
+  Node *Root;
+
+  /// \brief Maps tag prefixes to their expansion.
+  std::map<StringRef, StringRef> TagMap;
+
+  Token &peekNext();
+  Token getNext();
+  void setError(const Twine &Message, Token &Location) const;
+  bool failed() const;
+
+  /// \brief Parse %BLAH directives and return true if any were encountered.
+  bool parseDirectives();
+
+  /// \brief Parse %YAML
+  void parseYAMLDirective();
+
+  /// \brief Parse %TAG
+  void parseTAGDirective();
+
+  /// \brief Consume the next token and error if it is not \a TK.
+  bool expectToken(int TK);
+};
+
+/// \brief Iterator abstraction for Documents over a Stream.
+class document_iterator {
+public:
+  document_iterator() : Doc(nullptr) {}
+  document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
+
+  bool operator==(const document_iterator &Other) {
+    if (isAtEnd() || Other.isAtEnd())
+      return isAtEnd() && Other.isAtEnd();
+
+    return Doc == Other.Doc;
+  }
+  bool operator!=(const document_iterator &Other) { return !(*this == Other); }
+
+  document_iterator operator++() {
+    assert(Doc && "incrementing iterator past the end.");
+    if (!(*Doc)->skip()) {
+      Doc->reset(nullptr);
+    } else {
+      Stream &S = (*Doc)->stream;
+      Doc->reset(new Document(S));
+    }
+    return *this;
+  }
+
+  Document &operator*() { return *Doc->get(); }
+
+  std::unique_ptr<Document> &operator->() { return *Doc; }
+
+private:
+  bool isAtEnd() const { return !Doc || !*Doc; }
+
+  std::unique_ptr<Document> *Doc;
+};
+
+} // End namespace yaml.
+
+} // End namespace llvm.
+
+#endif
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
new file mode 100644
index 0000000..a23faf6
--- /dev/null
+++ b/include/llvm/Support/YAMLTraits.h
@@ -0,0 +1,1294 @@
+//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAMLTRAITS_H
+#define LLVM_SUPPORT_YAMLTRAITS_H
+
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include <system_error>
+
+namespace llvm {
+namespace yaml {
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML mapping.  For example:
+///
+///     struct MappingTraits<MyStruct> {
+///       static void mapping(IO &io, MyStruct &s) {
+///         io.mapRequired("name", s.name);
+///         io.mapRequired("size", s.size);
+///         io.mapOptional("age",  s.age);
+///       }
+///     };
+template<class T>
+struct MappingTraits {
+  // Must provide:
+  // static void mapping(IO &io, T &fields);
+  // Optionally may provide:
+  // static StringRef validate(IO &io, T &fields);
+};
+
+
+/// This class should be specialized by any integral type that converts
+/// to/from a YAML scalar where there is a one-to-one mapping between
+/// in-memory values and a string in YAML.  For example:
+///
+///     struct ScalarEnumerationTraits<Colors> {
+///         static void enumeration(IO &io, Colors &value) {
+///           io.enumCase(value, "red",   cRed);
+///           io.enumCase(value, "blue",  cBlue);
+///           io.enumCase(value, "green", cGreen);
+///         }
+///       };
+template<typename T>
+struct ScalarEnumerationTraits {
+  // Must provide:
+  // static void enumeration(IO &io, T &value);
+};
+
+
+/// This class should be specialized by any integer type that is a union
+/// of bit values and the YAML representation is a flow sequence of
+/// strings.  For example:
+///
+///      struct ScalarBitSetTraits<MyFlags> {
+///        static void bitset(IO &io, MyFlags &value) {
+///          io.bitSetCase(value, "big",   flagBig);
+///          io.bitSetCase(value, "flat",  flagFlat);
+///          io.bitSetCase(value, "round", flagRound);
+///        }
+///      };
+template<typename T>
+struct ScalarBitSetTraits {
+  // Must provide:
+  // static void bitset(IO &io, T &value);
+};
+
+
+/// This class should be specialized by type that requires custom conversion
+/// to/from a yaml scalar.  For example:
+///
+///    template<>
+///    struct ScalarTraits<MyType> {
+///      static void output(const MyType &val, void*, llvm::raw_ostream &out) {
+///        // stream out custom formatting
+///        out << llvm::format("%x", val);
+///      }
+///      static StringRef input(StringRef scalar, void*, MyType &value) {
+///        // parse scalar and set `value`
+///        // return empty string on success, or error string
+///        return StringRef();
+///      }
+///      static bool mustQuote(StringRef) { return true; }
+///    };
+template<typename T>
+struct ScalarTraits {
+  // Must provide:
+  //
+  // Function to write the value as a string:
+  //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
+  //
+  // Function to convert a string to a value.  Returns the empty
+  // StringRef on success or an error string if string is malformed:
+  //static StringRef input(StringRef scalar, void *ctxt, T &value);
+  //
+  // Function to determine if the value should be quoted.
+  //static bool mustQuote(StringRef);
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a YAML sequence.  For example:
+///
+///    template<>
+///    struct SequenceTraits< std::vector<MyType> > {
+///      static size_t size(IO &io, std::vector<MyType> &seq) {
+///        return seq.size();
+///      }
+///      static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
+///        if ( index >= seq.size() )
+///          seq.resize(index+1);
+///        return seq[index];
+///      }
+///    };
+template<typename T>
+struct SequenceTraits {
+  // Must provide:
+  // static size_t size(IO &io, T &seq);
+  // static T::value_type& element(IO &io, T &seq, size_t index);
+  //
+  // The following is option and will cause generated YAML to use
+  // a flow sequence (e.g. [a,b,c]).
+  // static const bool flow = true;
+};
+
+
+/// This class should be specialized by any type that needs to be converted
+/// to/from a list of YAML documents.
+template<typename T>
+struct DocumentListTraits {
+  // Must provide:
+  // static size_t size(IO &io, T &seq);
+  // static T::value_type& element(IO &io, T &seq, size_t index);
+};
+
+
+// Only used by compiler if both template types are the same
+template <typename T, T>
+struct SameType;
+
+// Only used for better diagnostics of missing traits
+template <typename T>
+struct MissingTrait;
+
+
+
+// Test if ScalarEnumerationTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarEnumerationTraits
+{
+  typedef void (*Signature_enumeration)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_enumeration, &U::enumeration>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value =
+    (sizeof(test<ScalarEnumerationTraits<T> >(nullptr)) == 1);
+};
+
+
+// Test if ScalarBitSetTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarBitSetTraits
+{
+  typedef void (*Signature_bitset)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_bitset, &U::bitset>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(nullptr)) == 1);
+};
+
+
+// Test if ScalarTraits<T> is defined on type T.
+template <class T>
+struct has_ScalarTraits
+{
+  typedef StringRef (*Signature_input)(StringRef, void*, T&);
+  typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
+  typedef bool (*Signature_mustQuote)(StringRef);
+
+  template <typename U>
+  static char test(SameType<Signature_input, &U::input> *,
+                   SameType<Signature_output, &U::output> *,
+                   SameType<Signature_mustQuote, &U::mustQuote> *);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value =
+      (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
+};
+
+
+// Test if MappingTraits<T> is defined on type T.
+template <class T>
+struct has_MappingTraits
+{
+  typedef void (*Signature_mapping)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_mapping, &U::mapping>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
+};
+
+// Test if MappingTraits<T>::validate() is defined on type T.
+template <class T>
+struct has_MappingValidateTraits
+{
+  typedef StringRef (*Signature_validate)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_validate, &U::validate>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
+};
+
+
+
+// Test if SequenceTraits<T> is defined on type T.
+template <class T>
+struct has_SequenceMethodTraits
+{
+  typedef size_t (*Signature_size)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_size, &U::size>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value =  (sizeof(test<SequenceTraits<T> >(nullptr)) == 1);
+};
+
+
+// has_FlowTraits<int> will cause an error with some compilers because
+// it subclasses int.  Using this wrapper only instantiates the
+// real has_FlowTraits only if the template type is a class.
+template <typename T, bool Enabled = std::is_class<T>::value>
+class has_FlowTraits
+{
+public:
+   static const bool value = false;
+};
+
+// Some older gcc compilers don't support straight forward tests
+// for members, so test for ambiguity cause by the base and derived
+// classes both defining the member.
+template <class T>
+struct has_FlowTraits<T, true>
+{
+  struct Fallback { bool flow; };
+  struct Derived : T, Fallback { };
+
+  template<typename C>
+  static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
+
+  template<typename C>
+  static char (&f(...))[2];
+
+public:
+  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
+};
+
+
+
+// Test if SequenceTraits<T> is defined on type T
+template<typename T>
+struct has_SequenceTraits : public std::integral_constant<bool,
+                                      has_SequenceMethodTraits<T>::value > { };
+
+
+// Test if DocumentListTraits<T> is defined on type T
+template <class T>
+struct has_DocumentListTraits
+{
+  typedef size_t (*Signature_size)(class IO&, T&);
+
+  template <typename U>
+  static char test(SameType<Signature_size, &U::size>*);
+
+  template <typename U>
+  static double test(...);
+
+public:
+  static bool const value = (sizeof(test<DocumentListTraits<T> >(nullptr))==1);
+};
+
+inline bool isNumber(StringRef S) {
+  static const char OctalChars[] = "01234567";
+  if (S.startswith("0") &&
+      S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
+    return true;
+
+  if (S.startswith("0o") &&
+      S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
+    return true;
+
+  static const char HexChars[] = "0123456789abcdefABCDEF";
+  if (S.startswith("0x") &&
+      S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
+    return true;
+
+  static const char DecChars[] = "0123456789";
+  if (S.find_first_not_of(DecChars) == StringRef::npos)
+    return true;
+
+  if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
+    return true;
+
+  Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
+  if (FloatMatcher.match(S))
+    return true;
+
+  return false;
+}
+
+inline bool isNumeric(StringRef S) {
+  if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
+    return true;
+
+  if (isNumber(S))
+    return true;
+
+  if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
+    return true;
+
+  return false;
+}
+
+inline bool isNull(StringRef S) {
+  return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
+         S.equals("~");
+}
+
+inline bool isBool(StringRef S) {
+  return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
+         S.equals("false") || S.equals("False") || S.equals("FALSE");
+}
+
+inline bool needsQuotes(StringRef S) {
+  if (S.empty())
+    return true;
+  if (isspace(S.front()) || isspace(S.back()))
+    return true;
+  if (S.front() == ',')
+    return true;
+
+  static const char ScalarSafeChars[] =
+      "abcdefghijklmnopqrstuvwxyz"
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
+  if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
+    return true;
+
+  if (isNull(S))
+    return true;
+  if (isBool(S))
+    return true;
+  if (isNumeric(S))
+    return true;
+
+  return false;
+}
+
+
+template<typename T>
+struct missingTraits : public std::integral_constant<bool,
+                                         !has_ScalarEnumerationTraits<T>::value
+                                      && !has_ScalarBitSetTraits<T>::value
+                                      && !has_ScalarTraits<T>::value
+                                      && !has_MappingTraits<T>::value
+                                      && !has_SequenceTraits<T>::value
+                                      && !has_DocumentListTraits<T>::value >  {};
+
+template<typename T>
+struct validatedMappingTraits : public std::integral_constant<bool,
+                                       has_MappingTraits<T>::value
+                                    && has_MappingValidateTraits<T>::value> {};
+
+template<typename T>
+struct unvalidatedMappingTraits : public std::integral_constant<bool,
+                                        has_MappingTraits<T>::value
+                                    && !has_MappingValidateTraits<T>::value> {};
+// Base class for Input and Output.
+class IO {
+public:
+
+  IO(void *Ctxt=nullptr);
+  virtual ~IO();
+
+  virtual bool outputting() = 0;
+
+  virtual unsigned beginSequence() = 0;
+  virtual bool preflightElement(unsigned, void *&) = 0;
+  virtual void postflightElement(void*) = 0;
+  virtual void endSequence() = 0;
+  virtual bool canElideEmptySequence() = 0;
+
+  virtual unsigned beginFlowSequence() = 0;
+  virtual bool preflightFlowElement(unsigned, void *&) = 0;
+  virtual void postflightFlowElement(void*) = 0;
+  virtual void endFlowSequence() = 0;
+
+  virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
+  virtual void beginMapping() = 0;
+  virtual void endMapping() = 0;
+  virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
+  virtual void postflightKey(void*) = 0;
+
+  virtual void beginEnumScalar() = 0;
+  virtual bool matchEnumScalar(const char*, bool) = 0;
+  virtual void endEnumScalar() = 0;
+
+  virtual bool beginBitSetScalar(bool &) = 0;
+  virtual bool bitSetMatch(const char*, bool) = 0;
+  virtual void endBitSetScalar() = 0;
+
+  virtual void scalarString(StringRef &, bool) = 0;
+
+  virtual void setError(const Twine &) = 0;
+
+  template <typename T>
+  void enumCase(T &Val, const char* Str, const T ConstVal) {
+    if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
+      Val = ConstVal;
+    }
+  }
+
+  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+  template <typename T>
+  void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
+    if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
+      Val = ConstVal;
+    }
+  }
+
+  template <typename T>
+  void bitSetCase(T &Val, const char* Str, const T ConstVal) {
+    if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+      Val = Val | ConstVal;
+    }
+  }
+
+  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
+  template <typename T>
+  void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
+    if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
+      Val = Val | ConstVal;
+    }
+  }
+
+  template <typename T>
+  void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
+    if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+      Val = Val | ConstVal;
+  }
+
+  template <typename T>
+  void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
+                        uint32_t Mask) {
+    if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+      Val = Val | ConstVal;
+  }
+
+  void *getContext();
+  void setContext(void *);
+
+  template <typename T>
+  void mapRequired(const char* Key, T& Val) {
+    this->processKey(Key, Val, true);
+  }
+
+  template <typename T>
+  typename std::enable_if<has_SequenceTraits<T>::value,void>::type
+  mapOptional(const char* Key, T& Val) {
+    // omit key/value instead of outputting empty sequence
+    if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) )
+      return;
+    this->processKey(Key, Val, false);
+  }
+
+  template <typename T>
+  void mapOptional(const char* Key, Optional<T> &Val) {
+    processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
+  }
+
+  template <typename T>
+  typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
+  mapOptional(const char* Key, T& Val) {
+    this->processKey(Key, Val, false);
+  }
+
+  template <typename T>
+  void mapOptional(const char* Key, T& Val, const T& Default) {
+    this->processKeyWithDefault(Key, Val, Default, false);
+  }
+  
+private:
+  template <typename T>
+  void processKeyWithDefault(const char *Key, Optional<T> &Val,
+                             const Optional<T> &DefaultValue, bool Required) {
+    assert(DefaultValue.hasValue() == false &&
+           "Optional<T> shouldn't have a value!");
+    void *SaveInfo;
+    bool UseDefault;
+    const bool sameAsDefault = outputting() && !Val.hasValue();
+    if (!outputting() && !Val.hasValue())
+      Val = T();
+    if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+                           SaveInfo)) {
+      yamlize(*this, Val.getValue(), Required);
+      this->postflightKey(SaveInfo);
+    } else {
+      if (UseDefault)
+        Val = DefaultValue;
+    }
+  }
+
+  template <typename T>
+  void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
+                                                                bool Required) {
+    void *SaveInfo;
+    bool UseDefault;
+    const bool sameAsDefault = outputting() && Val == DefaultValue;
+    if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+                                                                  SaveInfo) ) {
+      yamlize(*this, Val, Required);
+      this->postflightKey(SaveInfo);
+    }
+    else {
+      if ( UseDefault )
+        Val = DefaultValue;
+    }
+  }
+
+  template <typename T>
+  void processKey(const char *Key, T &Val, bool Required) {
+    void *SaveInfo;
+    bool UseDefault;
+    if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
+      yamlize(*this, Val, Required);
+      this->postflightKey(SaveInfo);
+    }
+  }
+
+private:
+  void  *Ctxt;
+};
+
+
+
+template<typename T>
+typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+  io.beginEnumScalar();
+  ScalarEnumerationTraits<T>::enumeration(io, Val);
+  io.endEnumScalar();
+}
+
+template<typename T>
+typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+  bool DoClear;
+  if ( io.beginBitSetScalar(DoClear) ) {
+    if ( DoClear )
+      Val = static_cast<T>(0);
+    ScalarBitSetTraits<T>::bitset(io, Val);
+    io.endBitSetScalar();
+  }
+}
+
+
+template<typename T>
+typename std::enable_if<has_ScalarTraits<T>::value,void>::type
+yamlize(IO &io, T &Val, bool) {
+  if ( io.outputting() ) {
+    std::string Storage;
+    llvm::raw_string_ostream Buffer(Storage);
+    ScalarTraits<T>::output(Val, io.getContext(), Buffer);
+    StringRef Str = Buffer.str();
+    io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
+  }
+  else {
+    StringRef Str;
+    io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
+    StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
+    if ( !Result.empty() ) {
+      io.setError(llvm::Twine(Result));
+    }
+  }
+}
+
+
+template<typename T>
+typename std::enable_if<validatedMappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+  io.beginMapping();
+  if (io.outputting()) {
+    StringRef Err = MappingTraits<T>::validate(io, Val);
+    if (!Err.empty()) {
+      llvm::errs() << Err << "\n";
+      assert(Err.empty() && "invalid struct trying to be written as yaml");
+    }
+  }
+  MappingTraits<T>::mapping(io, Val);
+  if (!io.outputting()) {
+    StringRef Err = MappingTraits<T>::validate(io, Val);
+    if (!Err.empty())
+      io.setError(Err);
+  }
+  io.endMapping();
+}
+
+template<typename T>
+typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+  io.beginMapping();
+  MappingTraits<T>::mapping(io, Val);
+  io.endMapping();
+}
+
+template<typename T>
+typename std::enable_if<missingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+}
+
+template<typename T>
+typename std::enable_if<has_SequenceTraits<T>::value,void>::type
+yamlize(IO &io, T &Seq, bool) {
+  if ( has_FlowTraits< SequenceTraits<T> >::value ) {
+    unsigned incnt = io.beginFlowSequence();
+    unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+    for(unsigned i=0; i < count; ++i) {
+      void *SaveInfo;
+      if ( io.preflightFlowElement(i, SaveInfo) ) {
+        yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+        io.postflightFlowElement(SaveInfo);
+      }
+    }
+    io.endFlowSequence();
+  }
+  else {
+    unsigned incnt = io.beginSequence();
+    unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
+    for(unsigned i=0; i < count; ++i) {
+      void *SaveInfo;
+      if ( io.preflightElement(i, SaveInfo) ) {
+        yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
+        io.postflightElement(SaveInfo);
+      }
+    }
+    io.endSequence();
+  }
+}
+
+
+template<>
+struct ScalarTraits<bool> {
+  static void output(const bool &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, bool &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<StringRef> {
+  static void output(const StringRef &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, StringRef &);
+  static bool mustQuote(StringRef S) { return needsQuotes(S); }
+};
+ 
+template<>
+struct ScalarTraits<std::string> {
+  static void output(const std::string &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, std::string &);
+  static bool mustQuote(StringRef S) { return needsQuotes(S); }
+};
+
+template<>
+struct ScalarTraits<uint8_t> {
+  static void output(const uint8_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, uint8_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<uint16_t> {
+  static void output(const uint16_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, uint16_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<uint32_t> {
+  static void output(const uint32_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, uint32_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<uint64_t> {
+  static void output(const uint64_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, uint64_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<int8_t> {
+  static void output(const int8_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, int8_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<int16_t> {
+  static void output(const int16_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, int16_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<int32_t> {
+  static void output(const int32_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, int32_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<int64_t> {
+  static void output(const int64_t &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, int64_t &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<float> {
+  static void output(const float &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, float &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<double> {
+  static void output(const double &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, double &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalization {
+  MappingNormalization(IO &i_o, TFinal &Obj)
+      : io(i_o), BufPtr(nullptr), Result(Obj) {
+    if ( io.outputting() ) {
+      BufPtr = new (&Buffer) TNorm(io, Obj);
+    }
+    else {
+      BufPtr = new (&Buffer) TNorm(io);
+    }
+  }
+
+  ~MappingNormalization() {
+    if ( ! io.outputting() ) {
+      Result = BufPtr->denormalize(io);
+    }
+    BufPtr->~TNorm();
+  }
+
+  TNorm* operator->() { return BufPtr; }
+
+private:
+  typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+  Storage       Buffer;
+  IO           &io;
+  TNorm        *BufPtr;
+  TFinal       &Result;
+};
+
+
+
+// Utility for use within MappingTraits<>::mapping() method
+// to [de]normalize an object for use with YAML conversion.
+template <typename TNorm, typename TFinal>
+struct MappingNormalizationHeap {
+  MappingNormalizationHeap(IO &i_o, TFinal &Obj)
+    : io(i_o), BufPtr(NULL), Result(Obj) {
+    if ( io.outputting() ) {
+      BufPtr = new (&Buffer) TNorm(io, Obj);
+    }
+    else {
+      BufPtr = new TNorm(io);
+    }
+  }
+
+  ~MappingNormalizationHeap() {
+    if ( io.outputting() ) {
+      BufPtr->~TNorm();
+    }
+    else {
+      Result = BufPtr->denormalize(io);
+    }
+  }
+
+  TNorm* operator->() { return BufPtr; }
+
+private:
+  typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
+
+  Storage       Buffer;
+  IO           &io;
+  TNorm        *BufPtr;
+  TFinal       &Result;
+};
+
+
+
+///
+/// The Input class is used to parse a yaml document into in-memory structs
+/// and vectors.
+///
+/// It works by using YAMLParser to do a syntax parse of the entire yaml
+/// document, then the Input class builds a graph of HNodes which wraps
+/// each yaml Node.  The extra layer is buffering.  The low level yaml
+/// parser only lets you look at each node once.  The buffering layer lets
+/// you search and interate multiple times.  This is necessary because
+/// the mapRequired() method calls may not be in the same order
+/// as the keys in the document.
+///
+class Input : public IO {
+public:
+  // Construct a yaml Input object from a StringRef and optional
+  // user-data. The DiagHandler can be specified to provide
+  // alternative error reporting.
+  Input(StringRef InputContent,
+        void *Ctxt = nullptr,
+        SourceMgr::DiagHandlerTy DiagHandler = nullptr,
+        void *DiagHandlerCtxt = nullptr);
+  ~Input();
+
+  // Check if there was an syntax or semantic error during parsing.
+  std::error_code error();
+
+private:
+  bool outputting() override;
+  bool mapTag(StringRef, bool) override;
+  void beginMapping() override;
+  void endMapping() override;
+  bool preflightKey(const char *, bool, bool, bool &, void *&) override;
+  void postflightKey(void *) override;
+  unsigned beginSequence() override;
+  void endSequence() override;
+  bool preflightElement(unsigned index, void *&) override;
+  void postflightElement(void *) override;
+  unsigned beginFlowSequence() override;
+  bool preflightFlowElement(unsigned , void *&) override;
+  void postflightFlowElement(void *) override;
+  void endFlowSequence() override;
+  void beginEnumScalar() override;
+  bool matchEnumScalar(const char*, bool) override;
+  void endEnumScalar() override;
+  bool beginBitSetScalar(bool &) override;
+  bool bitSetMatch(const char *, bool ) override;
+  void endBitSetScalar() override;
+  void scalarString(StringRef &, bool) override;
+  void setError(const Twine &message) override;
+  bool canElideEmptySequence() override;
+
+  class HNode {
+    virtual void anchor();
+  public:
+    HNode(Node *n) : _node(n) { }
+    virtual ~HNode() { }
+    static inline bool classof(const HNode *) { return true; }
+
+    Node *_node;
+  };
+
+  class EmptyHNode : public HNode {
+    void anchor() override;
+  public:
+    EmptyHNode(Node *n) : HNode(n) { }
+    static inline bool classof(const HNode *n) {
+      return NullNode::classof(n->_node);
+    }
+    static inline bool classof(const EmptyHNode *) { return true; }
+  };
+
+  class ScalarHNode : public HNode {
+    void anchor() override;
+  public:
+    ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
+
+    StringRef value() const { return _value; }
+
+    static inline bool classof(const HNode *n) {
+      return ScalarNode::classof(n->_node);
+    }
+    static inline bool classof(const ScalarHNode *) { return true; }
+  protected:
+    StringRef _value;
+  };
+
+  class MapHNode : public HNode {
+  public:
+    MapHNode(Node *n) : HNode(n) { }
+    virtual ~MapHNode();
+
+    static inline bool classof(const HNode *n) {
+      return MappingNode::classof(n->_node);
+    }
+    static inline bool classof(const MapHNode *) { return true; }
+
+    typedef llvm::StringMap<HNode*> NameToNode;
+
+    bool isValidKey(StringRef key);
+
+    NameToNode                        Mapping;
+    llvm::SmallVector<const char*, 6> ValidKeys;
+  };
+
+  class SequenceHNode : public HNode {
+  public:
+    SequenceHNode(Node *n) : HNode(n) { }
+    virtual ~SequenceHNode();
+
+    static inline bool classof(const HNode *n) {
+      return SequenceNode::classof(n->_node);
+    }
+    static inline bool classof(const SequenceHNode *) { return true; }
+
+    std::vector<HNode*> Entries;
+  };
+
+  Input::HNode *createHNodes(Node *node);
+  void setError(HNode *hnode, const Twine &message);
+  void setError(Node *node, const Twine &message);
+
+
+public:
+  // These are only used by operator>>. They could be private
+  // if those templated things could be made friends.
+  bool setCurrentDocument();
+  bool nextDocument();
+
+private:
+  llvm::SourceMgr                     SrcMgr; // must be before Strm
+  std::unique_ptr<llvm::yaml::Stream> Strm;
+  std::unique_ptr<HNode>              TopNode;
+  std::error_code                     EC;
+  llvm::BumpPtrAllocator              StringAllocator;
+  llvm::yaml::document_iterator       DocIterator;
+  std::vector<bool>                   BitValuesUsed;
+  HNode                              *CurrentNode;
+  bool                                ScalarMatchFound;
+};
+
+
+
+
+///
+/// The Output class is used to generate a yaml document from in-memory structs
+/// and vectors.
+///
+class Output : public IO {
+public:
+  Output(llvm::raw_ostream &, void *Ctxt=nullptr);
+  virtual ~Output();
+
+  bool outputting() override;
+  bool mapTag(StringRef, bool) override;
+  void beginMapping() override;
+  void endMapping() override;
+  bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
+  void postflightKey(void *) override;
+  unsigned beginSequence() override;
+  void endSequence() override;
+  bool preflightElement(unsigned, void *&) override;
+  void postflightElement(void *) override;
+  unsigned beginFlowSequence() override;
+  bool preflightFlowElement(unsigned, void *&) override;
+  void postflightFlowElement(void *) override;
+  void endFlowSequence() override;
+  void beginEnumScalar() override;
+  bool matchEnumScalar(const char*, bool) override;
+  void endEnumScalar() override;
+  bool beginBitSetScalar(bool &) override;
+  bool bitSetMatch(const char *, bool ) override;
+  void endBitSetScalar() override;
+  void scalarString(StringRef &, bool) override;
+  void setError(const Twine &message) override;
+  bool canElideEmptySequence() override;
+public:
+  // These are only used by operator<<. They could be private
+  // if that templated operator could be made a friend.
+  void beginDocuments();
+  bool preflightDocument(unsigned);
+  void postflightDocument();
+  void endDocuments();
+
+private:
+  void output(StringRef s);
+  void outputUpToEndOfLine(StringRef s);
+  void newLineCheck();
+  void outputNewLine();
+  void paddedKey(StringRef key);
+
+  enum InState { inSeq, inFlowSeq, inMapFirstKey, inMapOtherKey };
+
+  llvm::raw_ostream       &Out;
+  SmallVector<InState, 8>  StateStack;
+  int                      Column;
+  int                      ColumnAtFlowStart;
+  bool                     NeedBitValueComma;
+  bool                     NeedFlowSequenceComma;
+  bool                     EnumerationMatchFound;
+  bool                     NeedsNewLine;
+};
+
+
+
+
+/// YAML I/O does conversion based on types. But often native data types
+/// are just a typedef of built in intergral types (e.g. int).  But the C++
+/// type matching system sees through the typedef and all the typedefed types
+/// look like a built in type. This will cause the generic YAML I/O conversion
+/// to be used. To provide better control over the YAML conversion, you can
+/// use this macro instead of typedef.  It will create a class with one field
+/// and automatic conversion operators to and from the base type.
+/// Based on BOOST_STRONG_TYPEDEF
+#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
+    struct _type {                                                             \
+        _type() { }                                                            \
+        _type(const _base v) : value(v) { }                                    \
+        _type(const _type &v) : value(v.value) {}                              \
+        _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\
+        _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
+        operator const _base & () const { return value; }                      \
+        bool operator==(const _type &rhs) const { return value == rhs.value; } \
+        bool operator==(const _base &rhs) const { return value == rhs; }       \
+        bool operator<(const _type &rhs) const { return value < rhs.value; }   \
+        _base value;                                                           \
+    };
+
+
+
+///
+/// Use these types instead of uintXX_t in any mapping to have
+/// its yaml output formatted as hexadecimal.
+///
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
+LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
+
+
+template<>
+struct ScalarTraits<Hex8> {
+  static void output(const Hex8 &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, Hex8 &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<Hex16> {
+  static void output(const Hex16 &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, Hex16 &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<Hex32> {
+  static void output(const Hex32 &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, Hex32 &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template<>
+struct ScalarTraits<Hex64> {
+  static void output(const Hex64 &, void*, llvm::raw_ostream &);
+  static StringRef input(StringRef, void*, Hex64 &);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+
+// Define non-member operator>> so that Input can stream in a document list.
+template <typename T>
+inline
+typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
+operator>>(Input &yin, T &docList) {
+  int i = 0;
+  while ( yin.setCurrentDocument() ) {
+    yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true);
+    if ( yin.error() )
+      return yin;
+    yin.nextDocument();
+    ++i;
+  }
+  return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a map as a document.
+template <typename T>
+inline
+typename std::enable_if<has_MappingTraits<T>::value, Input &>::type
+operator>>(Input &yin, T &docMap) {
+  yin.setCurrentDocument();
+  yamlize(yin, docMap, true);
+  return yin;
+}
+
+// Define non-member operator>> so that Input can stream in a sequence as
+// a document.
+template <typename T>
+inline
+typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
+operator>>(Input &yin, T &docSeq) {
+  if (yin.setCurrentDocument())
+    yamlize(yin, docSeq, true);
+  return yin;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename std::enable_if<missingTraits<T>::value, Input &>::type
+operator>>(Input &yin, T &docSeq) {
+  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+  return yin;
+}
+
+
+// Define non-member operator<< so that Output can stream out document list.
+template <typename T>
+inline
+typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
+operator<<(Output &yout, T &docList) {
+  yout.beginDocuments();
+  const size_t count = DocumentListTraits<T>::size(yout, docList);
+  for(size_t i=0; i < count; ++i) {
+    if ( yout.preflightDocument(i) ) {
+      yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true);
+      yout.postflightDocument();
+    }
+  }
+  yout.endDocuments();
+  return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a map.
+template <typename T>
+inline
+typename std::enable_if<has_MappingTraits<T>::value, Output &>::type
+operator<<(Output &yout, T &map) {
+  yout.beginDocuments();
+  if ( yout.preflightDocument(0) ) {
+    yamlize(yout, map, true);
+    yout.postflightDocument();
+  }
+  yout.endDocuments();
+  return yout;
+}
+
+// Define non-member operator<< so that Output can stream out a sequence.
+template <typename T>
+inline
+typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
+operator<<(Output &yout, T &seq) {
+  yout.beginDocuments();
+  if ( yout.preflightDocument(0) ) {
+    yamlize(yout, seq, true);
+    yout.postflightDocument();
+  }
+  yout.endDocuments();
+  return yout;
+}
+
+// Provide better error message about types missing a trait specialization
+template <typename T>
+inline
+typename std::enable_if<missingTraits<T>::value, Output &>::type
+operator<<(Output &yout, T &seq) {
+  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
+  return yout;
+}
+
+
+} // namespace yaml
+} // namespace llvm
+
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML sequence.
+#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type)                                 \
+  namespace llvm {                                                          \
+  namespace yaml {                                                          \
+    template<>                                                              \
+    struct SequenceTraits< std::vector<_type> > {                           \
+      static size_t size(IO &io, std::vector<_type> &seq) {                 \
+        return seq.size();                                                  \
+      }                                                                     \
+      static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+        if ( index >= seq.size() )                                          \
+          seq.resize(index+1);                                              \
+        return seq[index];                                                  \
+      }                                                                     \
+    };                                                                      \
+  }                                                                         \
+  }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML flow sequence.
+#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type)                            \
+  namespace llvm {                                                          \
+  namespace yaml {                                                          \
+    template<>                                                              \
+    struct SequenceTraits< std::vector<_type> > {                           \
+      static size_t size(IO &io, std::vector<_type> &seq) {                 \
+        return seq.size();                                                  \
+      }                                                                     \
+      static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+        (void)flow; /* Remove this workaround after PR17897 is fixed */     \
+        if ( index >= seq.size() )                                          \
+          seq.resize(index+1);                                              \
+        return seq[index];                                                  \
+      }                                                                     \
+      static const bool flow = true;                                        \
+    };                                                                      \
+  }                                                                         \
+  }
+
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML document list.
+#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                            \
+  namespace llvm {                                                          \
+  namespace yaml {                                                          \
+    template<>                                                              \
+    struct DocumentListTraits< std::vector<_type> > {                       \
+      static size_t size(IO &io, std::vector<_type> &seq) {                 \
+        return seq.size();                                                  \
+      }                                                                     \
+      static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+        if ( index >= seq.size() )                                          \
+          seq.resize(index+1);                                              \
+        return seq[index];                                                  \
+      }                                                                     \
+    };                                                                      \
+  }                                                                         \
+  }
+
+
+
+#endif // LLVM_SUPPORT_YAMLTRAITS_H
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
new file mode 100644
index 0000000..ee7b89f
--- /dev/null
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -0,0 +1,171 @@
+//===-- llvm/Support/circular_raw_ostream.h - Buffered streams --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains raw_ostream implementations for streams to do circular
+// buffering of their output.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
+#define LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm 
+{
+  /// circular_raw_ostream - A raw_ostream which *can* save its data
+  /// to a circular buffer, or can pass it through directly to an
+  /// underlying stream if specified with a buffer of zero.
+  ///
+  class circular_raw_ostream : public raw_ostream {
+  public:
+    /// TAKE_OWNERSHIP - Tell this stream that it owns the underlying
+    /// stream and is responsible for cleanup, memory management
+    /// issues, etc.
+    ///
+    static const bool TAKE_OWNERSHIP = true;
+
+    /// REFERENCE_ONLY - Tell this stream it should not manage the
+    /// held stream.
+    ///
+    static const bool REFERENCE_ONLY = false;
+
+  private:
+    /// TheStream - The real stream we output to. We set it to be
+    /// unbuffered, since we're already doing our own buffering.
+    ///
+    raw_ostream *TheStream;
+
+    /// OwnsStream - Are we responsible for managing the underlying
+    /// stream?
+    ///
+    bool OwnsStream;
+
+    /// BufferSize - The size of the buffer in bytes.
+    ///
+    size_t BufferSize;
+
+    /// BufferArray - The actual buffer storage.
+    ///
+    char *BufferArray;
+
+    /// Cur - Pointer to the current output point in BufferArray.
+    ///
+    char *Cur;
+
+    /// Filled - Indicate whether the buffer has been completely
+    /// filled.  This helps avoid garbage output.
+    ///
+    bool Filled;
+
+    /// Banner - A pointer to a banner to print before dumping the
+    /// log.
+    ///
+    const char *Banner;
+
+    /// flushBuffer - Dump the contents of the buffer to Stream.
+    ///
+    void flushBuffer() {
+      if (Filled)
+        // Write the older portion of the buffer.
+        TheStream->write(Cur, BufferArray + BufferSize - Cur);
+      // Write the newer portion of the buffer.
+      TheStream->write(BufferArray, Cur - BufferArray);
+      Cur = BufferArray;
+      Filled = false;
+    }
+
+    void write_impl(const char *Ptr, size_t Size) override;
+
+    /// current_pos - Return the current position within the stream,
+    /// not counting the bytes currently in the buffer.
+    ///
+    uint64_t current_pos() const override {
+      // This has the same effect as calling TheStream.current_pos(),
+      // but that interface is private.
+      return TheStream->tell() - TheStream->GetNumBytesInBuffer();
+    }
+
+  public:
+    /// circular_raw_ostream - Construct an optionally
+    /// circular-buffered stream, handing it an underlying stream to
+    /// do the "real" output.
+    ///
+    /// As a side effect, if BuffSize is nonzero, the given Stream is
+    /// set to be Unbuffered.  This is because circular_raw_ostream
+    /// does its own buffering, so it doesn't want another layer of
+    /// buffering to be happening underneath it.
+    ///
+    /// "Owns" tells the circular_raw_ostream whether it is
+    /// responsible for managing the held stream, doing memory
+    /// management of it, etc.
+    ///
+    circular_raw_ostream(raw_ostream &Stream, const char *Header,
+                         size_t BuffSize = 0, bool Owns = REFERENCE_ONLY) 
+        : raw_ostream(/*unbuffered*/true),
+            TheStream(nullptr),
+            OwnsStream(Owns),
+            BufferSize(BuffSize),
+            BufferArray(nullptr),
+            Filled(false),
+            Banner(Header) {
+      if (BufferSize != 0)
+        BufferArray = new char[BufferSize];
+      Cur = BufferArray;
+      setStream(Stream, Owns);
+    }
+    explicit circular_raw_ostream()
+        : raw_ostream(/*unbuffered*/true),
+            TheStream(nullptr),
+            OwnsStream(REFERENCE_ONLY),
+            BufferArray(nullptr),
+            Filled(false),
+            Banner("") {
+      Cur = BufferArray;
+    }
+
+    ~circular_raw_ostream() {
+      flush();
+      flushBufferWithBanner();
+      releaseStream();
+      delete[] BufferArray;
+    }
+
+    /// setStream - Tell the circular_raw_ostream to output a
+    /// different stream.  "Owns" tells circular_raw_ostream whether
+    /// it should take responsibility for managing the underlying
+    /// stream.
+    ///
+    void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) {
+      releaseStream();
+      TheStream = &Stream;
+      OwnsStream = Owns;
+    }
+
+    /// flushBufferWithBanner - Force output of the buffer along with
+    /// a small header.
+    ///
+    void flushBufferWithBanner();
+
+  private:
+    /// releaseStream - Delete the held stream if needed. Otherwise,
+    /// transfer the buffer settings from this circular_raw_ostream
+    /// back to the underlying stream.
+    ///
+    void releaseStream() {
+      if (!TheStream)
+        return;
+      if (OwnsStream)
+        delete TheStream;
+    }
+  };
+} // end llvm namespace
+
+
+#endif
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
new file mode 100644
index 0000000..04cf3b6
--- /dev/null
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -0,0 +1,42 @@
+//===- raw_os_ostream.h - std::ostream adaptor for raw_ostream --*- 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 raw_os_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OS_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OS_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <iosfwd>
+
+namespace llvm {
+
+/// raw_os_ostream - A raw_ostream that writes to an std::ostream.  This is a
+/// simple adaptor class.  It does not check for output errors; clients should
+/// use the underlying stream to detect errors.
+class raw_os_ostream : public raw_ostream {
+  std::ostream &OS;
+
+  /// write_impl - See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  uint64_t current_pos() const override;
+
+public:
+  raw_os_ostream(std::ostream &O) : OS(O) {}
+  ~raw_os_ostream();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
new file mode 100644
index 0000000..34fbe08
--- /dev/null
+++ b/include/llvm/Support/raw_ostream.h
@@ -0,0 +1,498 @@
+//===--- raw_ostream.h - Raw output stream ----------------------*- 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 raw_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OSTREAM_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+  class format_object_base;
+  template <typename T>
+  class SmallVectorImpl;
+
+  namespace sys {
+    namespace fs {
+      enum OpenFlags : unsigned;
+    }
+  }
+
+/// raw_ostream - This class implements an extremely fast bulk output stream
+/// that can *only* output to a stream.  It does not support seeking, reopening,
+/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
+/// a chunk at a time.
+class raw_ostream {
+private:
+  void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION;
+  raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION;
+
+  /// The buffer is handled in such a way that the buffer is
+  /// uninitialized, unbuffered, or out of space when OutBufCur >=
+  /// OutBufEnd. Thus a single comparison suffices to determine if we
+  /// need to take the slow path to write a single character.
+  ///
+  /// The buffer is in one of three states:
+  ///  1. Unbuffered (BufferMode == Unbuffered)
+  ///  1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0).
+  ///  2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 &&
+  ///               OutBufEnd - OutBufStart >= 1).
+  ///
+  /// If buffered, then the raw_ostream owns the buffer if (BufferMode ==
+  /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is
+  /// managed by the subclass.
+  ///
+  /// If a subclass installs an external buffer using SetBuffer then it can wait
+  /// for a \see write_impl() call to handle the data which has been put into
+  /// this buffer.
+  char *OutBufStart, *OutBufEnd, *OutBufCur;
+
+  enum BufferKind {
+    Unbuffered = 0,
+    InternalBuffer,
+    ExternalBuffer
+  } BufferMode;
+
+public:
+  // color order matches ANSI escape sequence, don't change
+  enum Colors {
+    BLACK=0,
+    RED,
+    GREEN,
+    YELLOW,
+    BLUE,
+    MAGENTA,
+    CYAN,
+    WHITE,
+    SAVEDCOLOR
+  };
+
+  explicit raw_ostream(bool unbuffered=false)
+    : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
+    // Start out ready to flush.
+    OutBufStart = OutBufEnd = OutBufCur = nullptr;
+  }
+
+  virtual ~raw_ostream();
+
+  /// tell - Return the current offset with the file.
+  uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
+
+  //===--------------------------------------------------------------------===//
+  // Configuration Interface
+  //===--------------------------------------------------------------------===//
+
+  /// SetBuffered - Set the stream to be buffered, with an automatically
+  /// determined buffer size.
+  void SetBuffered();
+
+  /// SetBufferSize - Set the stream to be buffered, using the
+  /// specified buffer size.
+  void SetBufferSize(size_t Size) {
+    flush();
+    SetBufferAndMode(new char[Size], Size, InternalBuffer);
+  }
+
+  size_t GetBufferSize() const {
+    // If we're supposed to be buffered but haven't actually gotten around
+    // to allocating the buffer yet, return the value that would be used.
+    if (BufferMode != Unbuffered && OutBufStart == nullptr)
+      return preferred_buffer_size();
+
+    // Otherwise just return the size of the allocated buffer.
+    return OutBufEnd - OutBufStart;
+  }
+
+  /// SetUnbuffered - Set the stream to be unbuffered. When
+  /// unbuffered, the stream will flush after every write. This routine
+  /// will also flush the buffer immediately when the stream is being
+  /// set to unbuffered.
+  void SetUnbuffered() {
+    flush();
+    SetBufferAndMode(nullptr, 0, Unbuffered);
+  }
+
+  size_t GetNumBytesInBuffer() const {
+    return OutBufCur - OutBufStart;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Data Output Interface
+  //===--------------------------------------------------------------------===//
+
+  void flush() {
+    if (OutBufCur != OutBufStart)
+      flush_nonempty();
+  }
+
+  raw_ostream &operator<<(char C) {
+    if (OutBufCur >= OutBufEnd)
+      return write(C);
+    *OutBufCur++ = C;
+    return *this;
+  }
+
+  raw_ostream &operator<<(unsigned char C) {
+    if (OutBufCur >= OutBufEnd)
+      return write(C);
+    *OutBufCur++ = C;
+    return *this;
+  }
+
+  raw_ostream &operator<<(signed char C) {
+    if (OutBufCur >= OutBufEnd)
+      return write(C);
+    *OutBufCur++ = C;
+    return *this;
+  }
+
+  raw_ostream &operator<<(StringRef Str) {
+    // Inline fast path, particularly for strings with a known length.
+    size_t Size = Str.size();
+
+    // Make sure we can use the fast path.
+    if (Size > (size_t)(OutBufEnd - OutBufCur))
+      return write(Str.data(), Size);
+
+    memcpy(OutBufCur, Str.data(), Size);
+    OutBufCur += Size;
+    return *this;
+  }
+
+  raw_ostream &operator<<(const char *Str) {
+    // Inline fast path, particularly for constant strings where a sufficiently
+    // smart compiler will simplify strlen.
+
+    return this->operator<<(StringRef(Str));
+  }
+
+  raw_ostream &operator<<(const std::string &Str) {
+    // Avoid the fast path, it would only increase code size for a marginal win.
+    return write(Str.data(), Str.length());
+  }
+
+  raw_ostream &operator<<(unsigned long N);
+  raw_ostream &operator<<(long N);
+  raw_ostream &operator<<(unsigned long long N);
+  raw_ostream &operator<<(long long N);
+  raw_ostream &operator<<(const void *P);
+  raw_ostream &operator<<(unsigned int N) {
+    return this->operator<<(static_cast<unsigned long>(N));
+  }
+
+  raw_ostream &operator<<(int N) {
+    return this->operator<<(static_cast<long>(N));
+  }
+
+  raw_ostream &operator<<(double N);
+
+  /// write_hex - Output \p N in hexadecimal, without any prefix or padding.
+  raw_ostream &write_hex(unsigned long long N);
+
+  /// write_escaped - Output \p Str, turning '\\', '\t', '\n', '"', and
+  /// anything that doesn't satisfy std::isprint into an escape sequence.
+  raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
+
+  raw_ostream &write(unsigned char C);
+  raw_ostream &write(const char *Ptr, size_t Size);
+
+  // Formatted output, see the format() function in Support/Format.h.
+  raw_ostream &operator<<(const format_object_base &Fmt);
+
+  /// indent - Insert 'NumSpaces' spaces.
+  raw_ostream &indent(unsigned NumSpaces);
+
+
+  /// Changes the foreground color of text that will be output from this point
+  /// forward.
+  /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
+  /// change only the bold attribute, and keep colors untouched
+  /// @param Bold bold/brighter text, default false
+  /// @param BG if true change the background, default: change foreground
+  /// @returns itself so it can be used within << invocations
+  virtual raw_ostream &changeColor(enum Colors Color,
+                                   bool Bold = false,
+                                   bool BG = false) {
+    (void)Color;
+    (void)Bold;
+    (void)BG;
+    return *this;
+  }
+
+  /// Resets the colors to terminal defaults. Call this when you are done
+  /// outputting colored text, or before program exit.
+  virtual raw_ostream &resetColor() { return *this; }
+
+  /// Reverses the forground and background colors.
+  virtual raw_ostream &reverseColor() { return *this; }
+
+  /// This function determines if this stream is connected to a "tty" or
+  /// "console" window. That is, the output would be displayed to the user
+  /// rather than being put on a pipe or stored in a file.
+  virtual bool is_displayed() const { return false; }
+
+  /// This function determines if this stream is displayed and supports colors.
+  virtual bool has_colors() const { return is_displayed(); }
+
+  //===--------------------------------------------------------------------===//
+  // Subclass Interface
+  //===--------------------------------------------------------------------===//
+
+private:
+  /// write_impl - The is the piece of the class that is implemented
+  /// by subclasses.  This writes the \p Size bytes starting at
+  /// \p Ptr to the underlying stream.
+  ///
+  /// This function is guaranteed to only be called at a point at which it is
+  /// safe for the subclass to install a new buffer via SetBuffer.
+  ///
+  /// \param Ptr The start of the data to be written. For buffered streams this
+  /// is guaranteed to be the start of the buffer.
+  ///
+  /// \param Size The number of bytes to be written.
+  ///
+  /// \invariant { Size > 0 }
+  virtual void write_impl(const char *Ptr, size_t Size) = 0;
+
+  // An out of line virtual method to provide a home for the class vtable.
+  virtual void handle();
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  virtual uint64_t current_pos() const = 0;
+
+protected:
+  /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is
+  /// intended for use only by subclasses which can arrange for the output to go
+  /// directly into the desired output buffer, instead of being copied on each
+  /// flush.
+  void SetBuffer(char *BufferStart, size_t Size) {
+    SetBufferAndMode(BufferStart, Size, ExternalBuffer);
+  }
+
+  /// preferred_buffer_size - Return an efficient buffer size for the
+  /// underlying output mechanism.
+  virtual size_t preferred_buffer_size() const;
+
+  /// getBufferStart - Return the beginning of the current stream buffer, or 0
+  /// if the stream is unbuffered.
+  const char *getBufferStart() const { return OutBufStart; }
+
+  //===--------------------------------------------------------------------===//
+  // Private Interface
+  //===--------------------------------------------------------------------===//
+private:
+  /// SetBufferAndMode - Install the given buffer and mode.
+  void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
+
+  /// flush_nonempty - Flush the current buffer, which is known to be
+  /// non-empty. This outputs the currently buffered data and resets
+  /// the buffer to empty.
+  void flush_nonempty();
+
+  /// copy_to_buffer - Copy data into the buffer. Size must not be
+  /// greater than the number of unused bytes in the buffer.
+  void copy_to_buffer(const char *Ptr, size_t Size);
+};
+
+//===----------------------------------------------------------------------===//
+// File Output Streams
+//===----------------------------------------------------------------------===//
+
+/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
+///
+class raw_fd_ostream : public raw_ostream {
+  int FD;
+  bool ShouldClose;
+
+  /// Error This flag is true if an error of any kind has been detected.
+  ///
+  bool Error;
+
+  /// Controls whether the stream should attempt to use atomic writes, when
+  /// possible.
+  bool UseAtomicWrites;
+
+  uint64_t pos;
+
+  /// write_impl - See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  uint64_t current_pos() const override { return pos; }
+
+  /// preferred_buffer_size - Determine an efficient buffer size.
+  size_t preferred_buffer_size() const override;
+
+  /// error_detected - Set the flag indicating that an output error has
+  /// been encountered.
+  void error_detected() { Error = true; }
+
+public:
+  /// raw_fd_ostream - Open the specified file for writing. If an error occurs,
+  /// information about the error is put into ErrorInfo, and the stream should
+  /// be immediately destroyed; the string will be empty if no error occurred.
+  /// This allows optional flags to control how the file will be opened.
+  ///
+  /// As a special case, if Filename is "-", then the stream will use
+  /// STDOUT_FILENO instead of opening a file. Note that it will still consider
+  /// itself to own the file descriptor. In particular, it will close the
+  /// file descriptor when it is done (this is necessary to detect
+  /// output errors).
+  raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
+                 sys::fs::OpenFlags Flags);
+
+  /// raw_fd_ostream ctor - FD is the file descriptor that this writes to.  If
+  /// ShouldClose is true, this closes the file when the stream is destroyed.
+  raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
+
+  ~raw_fd_ostream();
+
+  /// close - Manually flush the stream and close the file.
+  /// Note that this does not call fsync.
+  void close();
+
+  /// seek - Flushes the stream and repositions the underlying file descriptor
+  /// position to the offset specified from the beginning of the file.
+  uint64_t seek(uint64_t off);
+
+  /// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
+  /// individual output routines where possible.
+  ///
+  /// Note that because raw_ostream's are typically buffered, this flag is only
+  /// sensible when used on unbuffered streams which will flush their output
+  /// immediately.
+  void SetUseAtomicWrites(bool Value) {
+    UseAtomicWrites = Value;
+  }
+
+  raw_ostream &changeColor(enum Colors colors, bool bold=false,
+                           bool bg=false) override;
+  raw_ostream &resetColor() override;
+
+  raw_ostream &reverseColor() override;
+
+  bool is_displayed() const override;
+
+  bool has_colors() const override;
+
+  /// has_error - Return the value of the flag in this raw_fd_ostream indicating
+  /// whether an output error has been encountered.
+  /// This doesn't implicitly flush any pending output.  Also, it doesn't
+  /// guarantee to detect all errors unless the stream has been closed.
+  bool has_error() const {
+    return Error;
+  }
+
+  /// clear_error - Set the flag read by has_error() to false. If the error
+  /// flag is set at the time when this raw_ostream's destructor is called,
+  /// report_fatal_error is called to report the error. Use clear_error()
+  /// after handling the error to avoid this behavior.
+  ///
+  ///   "Errors should never pass silently.
+  ///    Unless explicitly silenced."
+  ///      - from The Zen of Python, by Tim Peters
+  ///
+  void clear_error() {
+    Error = false;
+  }
+};
+
+/// outs() - This returns a reference to a raw_ostream for standard output.
+/// Use it like: outs() << "foo" << "bar";
+raw_ostream &outs();
+
+/// errs() - This returns a reference to a raw_ostream for standard error.
+/// Use it like: errs() << "foo" << "bar";
+raw_ostream &errs();
+
+/// nulls() - This returns a reference to a raw_ostream which simply discards
+/// output.
+raw_ostream &nulls();
+
+//===----------------------------------------------------------------------===//
+// Output Stream Adaptors
+//===----------------------------------------------------------------------===//
+
+/// raw_string_ostream - A raw_ostream that writes to an std::string.  This is a
+/// simple adaptor class. This class does not encounter output errors.
+class raw_string_ostream : public raw_ostream {
+  std::string &OS;
+
+  /// write_impl - See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  uint64_t current_pos() const override { return OS.size(); }
+public:
+  explicit raw_string_ostream(std::string &O) : OS(O) {}
+  ~raw_string_ostream();
+
+  /// str - Flushes the stream contents to the target string and returns
+  ///  the string's reference.
+  std::string& str() {
+    flush();
+    return OS;
+  }
+};
+
+/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
+/// SmallString.  This is a simple adaptor class. This class does not
+/// encounter output errors.
+class raw_svector_ostream : public raw_ostream {
+  SmallVectorImpl<char> &OS;
+
+  /// write_impl - See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  uint64_t current_pos() const override;
+public:
+  /// Construct a new raw_svector_ostream.
+  ///
+  /// \param O The vector to write to; this should generally have at least 128
+  /// bytes free to avoid any extraneous memory overhead.
+  explicit raw_svector_ostream(SmallVectorImpl<char> &O);
+  ~raw_svector_ostream();
+
+  /// resync - This is called when the SmallVector we're appending to is changed
+  /// outside of the raw_svector_ostream's control.  It is only safe to do this
+  /// if the raw_svector_ostream has previously been flushed.
+  void resync();
+
+  /// str - Flushes the stream contents to the target vector and return a
+  /// StringRef for the vector contents.
+  StringRef str();
+};
+
+/// raw_null_ostream - A raw_ostream that discards all output.
+class raw_null_ostream : public raw_ostream {
+  /// write_impl - See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t size) override;
+
+  /// current_pos - Return the current position within the stream, not
+  /// counting the bytes currently in the buffer.
+  uint64_t current_pos() const override;
+
+public:
+  explicit raw_null_ostream() {}
+  ~raw_null_ostream();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
new file mode 100644
index 0000000..70953a9
--- /dev/null
+++ b/include/llvm/Support/type_traits.h
@@ -0,0 +1,92 @@
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- 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 additions to the standard type_traits library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
+#define LLVM_SUPPORT_TYPE_TRAITS_H
+
+#include <type_traits>
+#include <utility>
+
+#ifndef __has_feature
+#define LLVM_DEFINED_HAS_FEATURE
+#define __has_feature(x) 0
+#endif
+
+namespace llvm {
+
+/// isPodLike - This is a type trait that is used to determine whether a given
+/// type can be copied around with memcpy instead of running ctors etc.
+template <typename T>
+struct isPodLike {
+#if __has_feature(is_trivially_copyable)
+  // If the compiler supports the is_trivially_copyable trait use it, as it
+  // matches the definition of isPodLike closely.
+  static const bool value = __is_trivially_copyable(T);
+#else
+  // If we don't know anything else, we can (at least) assume that all non-class
+  // types are PODs.
+  static const bool value = !std::is_class<T>::value;
+#endif
+};
+
+// std::pair's are pod-like if their elements are.
+template<typename T, typename U>
+struct isPodLike<std::pair<T, U> > {
+  static const bool value = isPodLike<T>::value && isPodLike<U>::value;
+};
+
+/// \brief Metafunction that determines whether the given type is either an
+/// integral type or an enumeration type.
+///
+/// Note that this accepts potentially more integral types than is_integral
+/// because it is based on merely being convertible implicitly to an integral
+/// type.
+template <typename T> class is_integral_or_enum {
+  typedef typename std::remove_reference<T>::type UnderlyingT;
+
+public:
+  static const bool value =
+      !std::is_class<UnderlyingT>::value && // Filter conversion operators.
+      !std::is_pointer<UnderlyingT>::value &&
+      !std::is_floating_point<UnderlyingT>::value &&
+      std::is_convertible<UnderlyingT, unsigned long long>::value;
+};
+
+/// \brief If T is a pointer, just return it. If it is not, return T&.
+template<typename T, typename Enable = void>
+struct add_lvalue_reference_if_not_pointer { typedef T &type; };
+
+template <typename T>
+struct add_lvalue_reference_if_not_pointer<
+    T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+  typedef T type;
+};
+
+/// \brief If T is a pointer to X, return a pointer to const X. If it is not,
+/// return const T.
+template<typename T, typename Enable = void>
+struct add_const_past_pointer { typedef const T type; };
+
+template <typename T>
+struct add_const_past_pointer<
+    T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+  typedef const typename std::remove_pointer<T>::type *type;
+};
+
+}
+
+#ifdef LLVM_DEFINED_HAS_FEATURE
+#undef __has_feature
+#endif
+
+#endif
diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h
new file mode 100644
index 0000000..3df658d
--- /dev/null
+++ b/include/llvm/TableGen/Error.h
@@ -0,0 +1,39 @@
+//===- llvm/TableGen/Error.h - tblgen error handling helpers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains error handling helper routines to pretty-print diagnostic
+// messages from tblgen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_ERROR_H
+#define LLVM_TABLEGEN_ERROR_H
+
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+
+void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg);
+void PrintWarning(const char *Loc, const Twine &Msg);
+void PrintWarning(const Twine &Msg);
+
+void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
+void PrintError(const char *Loc, const Twine &Msg);
+void PrintError(const Twine &Msg);
+
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc,
+                                             const Twine &Msg);
+
+extern SourceMgr SrcMgr;
+extern unsigned ErrorsPrinted;
+
+} // end namespace "llvm"
+
+#endif
diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h
new file mode 100644
index 0000000..866b986
--- /dev/null
+++ b/include/llvm/TableGen/Main.h
@@ -0,0 +1,28 @@
+//===- llvm/TableGen/Main.h - tblgen entry point ----------------*- 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 common entry point for tblgen tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_MAIN_H
+#define LLVM_TABLEGEN_MAIN_H
+
+namespace llvm {
+
+class RecordKeeper;
+class raw_ostream;
+/// \brief Perform the action using Records, and write output to OS.
+/// \returns true on error, false otherwise
+typedef bool TableGenMainFn(raw_ostream &OS, RecordKeeper &Records);
+
+int TableGenMain(char *argv0, TableGenMainFn *MainFn);
+}
+
+#endif
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
new file mode 100644
index 0000000..36464d7
--- /dev/null
+++ b/include/llvm/TableGen/Record.h
@@ -0,0 +1,1824 @@
+//===- llvm/TableGen/Record.h - Classes for 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 LLVM_TABLEGEN_RECORD_H
+#define LLVM_TABLEGEN_RECORD_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.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 DagRecTy;
+class RecordRecTy;
+
+// Init subclasses.
+class Init;
+class UnsetInit;
+class BitInit;
+class BitsInit;
+class IntInit;
+class StringInit;
+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;
+class RecordKeeper;
+
+//===----------------------------------------------------------------------===//
+//  Type Classes
+//===----------------------------------------------------------------------===//
+
+class RecTy {
+public:
+  /// \brief Subclass discriminator (for dyn_cast<> et al.)
+  enum RecTyKind {
+    BitRecTyKind,
+    BitsRecTyKind,
+    IntRecTyKind,
+    StringRecTyKind,
+    ListRecTyKind,
+    DagRecTyKind,
+    RecordRecTyKind
+  };
+
+private:
+  RecTyKind Kind;
+  ListRecTy *ListTy;
+  virtual void anchor();
+
+public:
+  RecTyKind getRecTyKind() const { return Kind; }
+
+  RecTy(RecTyKind K) : Kind(K), ListTy(nullptr) {}
+  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;
+
+  /// getListTy - Returns the type representing list<this>.
+  ListRecTy *getListTy();
+
+public:   // These methods should only be called from subclasses of Init
+  virtual Init *convertValue( UnsetInit *UI) { return nullptr; }
+  virtual Init *convertValue(   BitInit *BI) { return nullptr; }
+  virtual Init *convertValue(  BitsInit *BI) { return nullptr; }
+  virtual Init *convertValue(   IntInit *II) { return nullptr; }
+  virtual Init *convertValue(StringInit *SI) { return nullptr; }
+  virtual Init *convertValue(  ListInit *LI) { return nullptr; }
+  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(VarBitInit *VB) { return nullptr; }
+  virtual Init *convertValue(   DefInit *DI) { return nullptr; }
+  virtual Init *convertValue(   DagInit *DI) { return nullptr; }
+  virtual Init *convertValue( TypedInit *TI) { return nullptr; }
+  virtual Init *convertValue(   VarInit *VI) {
+    return convertValue((TypedInit*)VI);
+  }
+  virtual Init *convertValue( FieldInit *FI) {
+    return convertValue((TypedInit*)FI);
+  }
+
+public:
+  virtual bool baseClassOf(const RecTy*) const;
+};
+
+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 {
+  static BitRecTy Shared;
+  BitRecTy() : RecTy(BitRecTyKind) {}
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == BitRecTyKind;
+  }
+
+  static BitRecTy *get() { return &Shared; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override { return (Init*)BI; }
+  Init *convertValue(  BitsInit *BI) override;
+  Init *convertValue(   IntInit *II) override;
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue(VarBitInit *VB) override { return (Init*)VB; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override { return "bit"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+  bool baseClassOf(const RecTy*) const override;
+};
+
+/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
+///
+class BitsRecTy : public RecTy {
+  unsigned Size;
+  explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == BitsRecTyKind;
+  }
+
+  static BitsRecTy *get(unsigned Sz);
+
+  unsigned getNumBits() const { return Size; }
+
+  Init *convertValue( UnsetInit *UI) override;
+  Init *convertValue(   BitInit *UI) override;
+  Init *convertValue(  BitsInit *BI) override;
+  Init *convertValue(   IntInit *II) override;
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue(  UnOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue(TernOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+  bool baseClassOf(const RecTy*) const override;
+};
+
+/// IntRecTy - 'int' - Represent an integer value of no particular size
+///
+class IntRecTy : public RecTy {
+  static IntRecTy Shared;
+  IntRecTy() : RecTy(IntRecTyKind) {}
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == IntRecTyKind;
+  }
+
+  static IntRecTy *get() { return &Shared; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override;
+  Init *convertValue(  BitsInit *BI) override;
+  Init *convertValue(   IntInit *II) override { return (Init*)II; }
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue( UnOpInit *UI)  override { return RecTy::convertValue(UI);}
+  Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override { return "int"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+
+  bool baseClassOf(const RecTy*) const override;
+};
+
+/// StringRecTy - 'string' - Represent an string value
+///
+class StringRecTy : public RecTy {
+  static StringRecTy Shared;
+  StringRecTy() : RecTy(StringRecTyKind) {}
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == StringRecTyKind;
+  }
+
+  static StringRecTy *get() { return &Shared; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override { return nullptr; }
+  Init *convertValue(  BitsInit *BI) override { return nullptr; }
+  Init *convertValue(   IntInit *II) override { return nullptr; }
+  Init *convertValue(StringInit *SI) override { return (Init*)SI; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue( UnOpInit *BO) override;
+  Init *convertValue( BinOpInit *BO) override;
+  Init *convertValue( TernOpInit *BO) override {return RecTy::convertValue(BO);}
+
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override { return "string"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+};
+
+/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
+/// the specified type.
+///
+class ListRecTy : public RecTy {
+  RecTy *Ty;
+  explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
+  friend ListRecTy *RecTy::getListTy();
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == ListRecTyKind;
+  }
+
+  static ListRecTy *get(RecTy *T) { return T->getListTy(); }
+  RecTy *getElementType() const { return Ty; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override { return nullptr; }
+  Init *convertValue(  BitsInit *BI) override { return nullptr; }
+  Init *convertValue(   IntInit *II) override { return nullptr; }
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override;
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue(  UnOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue(TernOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+
+  bool baseClassOf(const RecTy*) const override;
+};
+
+/// DagRecTy - 'dag' - Represent a dag fragment
+///
+class DagRecTy : public RecTy {
+  static DagRecTy Shared;
+  DagRecTy() : RecTy(DagRecTyKind) {}
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == DagRecTyKind;
+  }
+
+  static DagRecTy *get() { return &Shared; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override { return nullptr; }
+  Init *convertValue(  BitsInit *BI) override { return nullptr; }
+  Init *convertValue(   IntInit *II) override { return nullptr; }
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue(   DefInit *DI) override { return nullptr; }
+  Init *convertValue( UnOpInit *BO) override;
+  Init *convertValue( BinOpInit *BO) override;
+  Init *convertValue( TernOpInit *BO) override {return RecTy::convertValue(BO);}
+  Init *convertValue(   DagInit *CI) override { return (Init*)CI; }
+  Init *convertValue( TypedInit *TI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override { return "dag"; }
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+};
+
+/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
+/// (R32 X = EAX).
+///
+class RecordRecTy : public RecTy {
+  Record *Rec;
+  explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
+  friend class Record;
+
+public:
+  static bool classof(const RecTy *RT) {
+    return RT->getRecTyKind() == RecordRecTyKind;
+  }
+
+  static RecordRecTy *get(Record *R);
+
+  Record *getRecord() const { return Rec; }
+
+  Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+  Init *convertValue(   BitInit *BI) override { return nullptr; }
+  Init *convertValue(  BitsInit *BI) override { return nullptr; }
+  Init *convertValue(   IntInit *II) override { return nullptr; }
+  Init *convertValue(StringInit *SI) override { return nullptr; }
+  Init *convertValue(  ListInit *LI) override { return nullptr; }
+  Init *convertValue(VarBitInit *VB) override { return nullptr; }
+  Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+  Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+  Init *convertValue(   DefInit *DI) override;
+  Init *convertValue(   DagInit *DI) override { return nullptr; }
+  Init *convertValue( TypedInit *VI) override;
+  Init *convertValue(   VarInit *VI) override { return RecTy::convertValue(VI);}
+  Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+  std::string getAsString() const override;
+
+  bool typeIsConvertibleTo(const RecTy *RHS) const override {
+    return RHS->baseClassOf(this);
+  }
+  bool baseClassOf(const RecTy*) const override;
+};
+
+/// 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
+//===----------------------------------------------------------------------===//
+
+class Init {
+protected:
+  /// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.)
+  ///
+  /// This enum is laid out by a preorder traversal of the inheritance
+  /// hierarchy, and does not contain an entry for abstract classes, as per
+  /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst.
+  ///
+  /// We also explicitly include "first" and "last" values for each
+  /// interior node of the inheritance tree, to make it easier to read the
+  /// corresponding classof().
+  ///
+  /// We could pack these a bit tighter by not having the IK_FirstXXXInit
+  /// and IK_LastXXXInit be their own values, but that would degrade
+  /// readability for really no benefit.
+  enum InitKind {
+    IK_BitInit,
+    IK_BitsInit,
+    IK_FirstTypedInit,
+    IK_DagInit,
+    IK_DefInit,
+    IK_FieldInit,
+    IK_IntInit,
+    IK_ListInit,
+    IK_FirstOpInit,
+    IK_BinOpInit,
+    IK_TernOpInit,
+    IK_UnOpInit,
+    IK_LastOpInit,
+    IK_StringInit,
+    IK_VarInit,
+    IK_VarListElementInit,
+    IK_LastTypedInit,
+    IK_UnsetInit,
+    IK_VarBitInit
+  };
+
+private:
+  const InitKind Kind;
+  Init(const Init &) LLVM_DELETED_FUNCTION;
+  Init &operator=(const Init &) LLVM_DELETED_FUNCTION;
+  virtual void anchor();
+
+public:
+  InitKind getKind() const { return Kind; }
+
+protected:
+  explicit Init(InitKind K) : Kind(K) {}
+
+public:
+  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;
+  /// getAsUnquotedString - Convert this value to a string form,
+  /// without adding quote markers.  This primaruly affects
+  /// StringInits where we will not surround the string value with
+  /// quotes.
+  virtual std::string getAsUnquotedString() const { return getAsString(); }
+
+  /// 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) const = 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) const {
+    return nullptr;
+  }
+
+  /// 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) const {
+    return nullptr;
+  }
+
+  /// 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 nullptr;
+  }
+
+  /// 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 nullptr;
+  }
+
+  /// 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) const {
+    return const_cast<Init *>(this);
+  }
+
+  /// getBit - This method is used to return the initializer for the specified
+  /// bit.
+  virtual Init *getBit(unsigned Bit) const = 0;
+
+  /// getBitVar - This method is used to retrieve the initializer for bit
+  /// reference. For non-VarBitInit, it simply returns itself.
+  virtual Init *getBitVar() const { return const_cast<Init*>(this); }
+
+  /// getBitNum - This method is used to retrieve the bit number of a bit
+  /// reference. For non-VarBitInit, it simply returns 0.
+  virtual unsigned getBitNum() const { return 0; }
+};
+
+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;
+
+  TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION;
+  TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION;
+
+protected:
+  explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {}
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() >= IK_FirstTypedInit &&
+           I->getKind() <= IK_LastTypedInit;
+  }
+  RecTy *getType() const { return Ty; }
+
+  Init *
+  convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
+  Init *
+  convertInitListSlice(const std::vector<unsigned> &Elements) const override;
+
+  /// 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.
+  ///
+  RecTy *getFieldType(const std::string &FieldName) const override;
+
+  /// 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) const = 0;
+};
+
+/// UnsetInit - ? - Represents an uninitialized value
+///
+class UnsetInit : public Init {
+  UnsetInit() : Init(IK_UnsetInit) {}
+  UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION;
+  UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_UnsetInit;
+  }
+  static UnsetInit *get();
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<UnsetInit *>(this));
+  }
+
+  Init *getBit(unsigned Bit) const override {
+    return const_cast<UnsetInit*>(this);
+  }
+
+  bool isComplete() const override { return false; }
+  std::string getAsString() const override { return "?"; }
+};
+
+/// BitInit - true/false - Represent a concrete initializer for a bit.
+///
+class BitInit : public Init {
+  bool Value;
+
+  explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
+  BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION;
+  BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_BitInit;
+  }
+  static BitInit *get(bool V);
+
+  bool getValue() const { return Value; }
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<BitInit *>(this));
+  }
+
+  Init *getBit(unsigned Bit) const override {
+    assert(Bit < 1 && "Bit index out of range!");
+    return const_cast<BitInit*>(this);
+  }
+
+  std::string getAsString() const override { 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, public FoldingSetNode {
+  std::vector<Init*> Bits;
+
+  BitsInit(ArrayRef<Init *> Range)
+    : Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {}
+
+  BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION;
+  BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_BitsInit;
+  }
+  static BitsInit *get(ArrayRef<Init *> Range);
+
+  void Profile(FoldingSetNodeID &ID) const;
+
+  unsigned getNumBits() const { return Bits.size(); }
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<BitsInit *>(this));
+  }
+  Init *
+  convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
+
+  bool isComplete() const override {
+    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;
+  }
+  std::string getAsString() const override;
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  Init *getBit(unsigned Bit) const override {
+    assert(Bit < Bits.size() && "Bit index out of range!");
+    return Bits[Bit];
+  }
+};
+
+/// IntInit - 7 - Represent an initialization by a literal integer value.
+///
+class IntInit : public TypedInit {
+  int64_t Value;
+
+  explicit IntInit(int64_t V)
+    : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
+
+  IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION;
+  IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_IntInit;
+  }
+  static IntInit *get(int64_t V);
+
+  int64_t getValue() const { return Value; }
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<IntInit *>(this));
+  }
+  Init *
+  convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
+
+  std::string getAsString() const override;
+
+  /// 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.
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override {
+    llvm_unreachable("Illegal element reference off int");
+  }
+
+  Init *getBit(unsigned Bit) const override {
+    return BitInit::get((Value & (1ULL << Bit)) != 0);
+  }
+};
+
+/// StringInit - "foo" - Represent an initialization by a string value.
+///
+class StringInit : public TypedInit {
+  std::string Value;
+
+  explicit StringInit(const std::string &V)
+    : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
+
+  StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION;
+  StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION;
+  void anchor() override;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_StringInit;
+  }
+  static StringInit *get(StringRef);
+
+  const std::string &getValue() const { return Value; }
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<StringInit *>(this));
+  }
+
+  std::string getAsString() const override { return "\"" + Value + "\""; }
+  std::string getAsUnquotedString() const override { return Value; }
+
+  /// 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.
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override {
+    llvm_unreachable("Illegal element reference off string");
+  }
+
+  Init *getBit(unsigned Bit) const override {
+    llvm_unreachable("Illegal bit reference off string");
+  }
+};
+
+/// ListInit - [AL, AH, CL] - Represent a list of defs
+///
+class ListInit : public TypedInit, public FoldingSetNode {
+  std::vector<Init*> Values;
+
+public:
+  typedef std::vector<Init*>::const_iterator const_iterator;
+
+private:
+  explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
+    : TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
+      Values(Range.begin(), Range.end()) {}
+
+  ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION;
+  ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_ListInit;
+  }
+  static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
+
+  void Profile(FoldingSetNodeID &ID) const;
+
+  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) const override;
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<ListInit *>(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.
+  ///
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override;
+
+  ArrayRef<Init*> getValues() const { return Values; }
+
+  inline const_iterator begin() const { return Values.begin(); }
+  inline const_iterator end  () const { return Values.end();   }
+
+  inline size_t         size () const { return Values.size();  }
+  inline bool           empty() const { return Values.empty(); }
+
+  /// 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.
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override;
+
+  Init *getBit(unsigned Bit) const override {
+    llvm_unreachable("Illegal bit reference off list");
+  }
+};
+
+/// OpInit - Base class for operators
+///
+class OpInit : public TypedInit {
+  OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION;
+  OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION;
+
+protected:
+  explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {}
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() >= IK_FirstOpInit &&
+           I->getKind() <= IK_LastOpInit;
+  }
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
+
+  virtual int getNumOperands() const = 0;
+  virtual Init *getOperand(int i) const = 0;
+
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<OpInit *>(this));
+  }
+
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override;
+
+  Init *getBit(unsigned Bit) const override;
+};
+
+/// UnOpInit - !op (X) - Transform an init.
+///
+class UnOpInit : public OpInit {
+public:
+  enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
+
+private:
+  UnaryOp Opc;
+  Init *LHS;
+
+  UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
+    : OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {}
+
+  UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
+  UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_UnOpInit;
+  }
+  static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  OpInit *clone(std::vector<Init *> &Operands) const override {
+    assert(Operands.size() == 1 &&
+           "Wrong number of operands for unary operation");
+    return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
+  }
+
+  int getNumOperands() const override { return 1; }
+  Init *getOperand(int i) const override {
+    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) const override;
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override;
+};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public OpInit {
+public:
+  enum BinaryOp { ADD, SHL, SRA, SRL, LISTCONCAT, STRCONCAT, CONCAT, EQ };
+
+private:
+  BinaryOp Opc;
+  Init *LHS, *RHS;
+
+  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+      OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
+
+  BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
+  BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_BinOpInit;
+  }
+  static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
+                        RecTy *Type);
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  OpInit *clone(std::vector<Init *> &Operands) const override {
+    assert(Operands.size() == 2 &&
+           "Wrong number of operands for binary operation");
+    return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
+  }
+
+  int getNumOperands() const override { return 2; }
+  Init *getOperand(int i) const override {
+    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) const override;
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override;
+};
+
+/// 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;
+
+  TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
+             RecTy *Type) :
+      OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
+
+  TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
+  TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_TernOpInit;
+  }
+  static TernOpInit *get(TernaryOp opc, Init *lhs,
+                         Init *mhs, Init *rhs,
+                         RecTy *Type);
+
+  // Clone - Clone this operator, replacing arguments with the new list
+  OpInit *clone(std::vector<Init *> &Operands) const override {
+    assert(Operands.size() == 3 &&
+           "Wrong number of operands for ternary operation");
+    return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
+                           getType());
+  }
+
+  int getNumOperands() const override { return 3; }
+  Init *getOperand(int i) const override {
+    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) const override;
+
+  bool isComplete() const override { return false; }
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override;
+};
+
+/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
+///
+class VarInit : public TypedInit {
+  Init *VarName;
+
+  explicit VarInit(const std::string &VN, RecTy *T)
+      : TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {}
+  explicit VarInit(Init *VN, RecTy *T)
+      : TypedInit(IK_VarInit, T), VarName(VN) {}
+
+  VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION;
+  VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_VarInit;
+  }
+  static VarInit *get(const std::string &VN, RecTy *T);
+  static VarInit *get(Init *VN, RecTy *T);
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<VarInit *>(this));
+  }
+
+  const std::string &getName() const;
+  Init *getNameInit() const { return VarName; }
+  std::string getNameInitAsString() const {
+    return getNameInit()->getAsUnquotedString();
+  }
+
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override;
+
+  RecTy *getFieldType(const std::string &FieldName) const override;
+  Init *getFieldInit(Record &R, const RecordVal *RV,
+                     const std::string &FieldName) const override;
+
+  /// 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.
+  ///
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  Init *getBit(unsigned Bit) const override;
+
+  std::string getAsString() const override { return getName(); }
+};
+
+/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
+///
+class VarBitInit : public Init {
+  TypedInit *TI;
+  unsigned Bit;
+
+  VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) {
+    assert(T->getType() &&
+           (isa<IntRecTy>(T->getType()) ||
+            (isa<BitsRecTy>(T->getType()) &&
+             cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
+           "Illegal VarBitInit expression!");
+  }
+
+  VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
+  VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_VarBitInit;
+  }
+  static VarBitInit *get(TypedInit *T, unsigned B);
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<VarBitInit *>(this));
+  }
+
+  Init *getBitVar() const override { return TI; }
+  unsigned getBitNum() const override { return Bit; }
+
+  std::string getAsString() const override;
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  Init *getBit(unsigned B) const override {
+    assert(B < 1 && "Bit index out of range!");
+    return const_cast<VarBitInit*>(this);
+  }
+};
+
+/// VarListElementInit - List[4] - Represent access to one element of a var or
+/// field.
+class VarListElementInit : public TypedInit {
+  TypedInit *TI;
+  unsigned Element;
+
+  VarListElementInit(TypedInit *T, unsigned E)
+      : TypedInit(IK_VarListElementInit,
+                  cast<ListRecTy>(T->getType())->getElementType()),
+        TI(T), Element(E) {
+    assert(T->getType() && isa<ListRecTy>(T->getType()) &&
+           "Illegal VarBitInit expression!");
+  }
+
+  VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
+  void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_VarListElementInit;
+  }
+  static VarListElementInit *get(TypedInit *T, unsigned E);
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<VarListElementInit *>(this));
+  }
+
+  TypedInit *getVariable() const { return TI; }
+  unsigned getElementNum() const { return Element; }
+
+  /// 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.
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override;
+
+  std::string getAsString() const override;
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  Init *getBit(unsigned Bit) const override;
+};
+
+/// DefInit - AL - Represent a reference to a 'def' in the description
+///
+class DefInit : public TypedInit {
+  Record *Def;
+
+  DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {}
+  friend class Record;
+
+  DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION;
+  DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_DefInit;
+  }
+  static DefInit *get(Record*);
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<DefInit *>(this));
+  }
+
+  Record *getDef() const { return Def; }
+
+  //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+  RecTy *getFieldType(const std::string &FieldName) const override;
+  Init *getFieldInit(Record &R, const RecordVal *RV,
+                     const std::string &FieldName) const override;
+
+  std::string getAsString() const override;
+
+  Init *getBit(unsigned Bit) const override {
+    llvm_unreachable("Illegal bit reference off def");
+  }
+
+  /// 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.
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override {
+    llvm_unreachable("Illegal element reference off def");
+  }
+};
+
+/// 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
+
+  FieldInit(Init *R, const std::string &FN)
+      : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
+    assert(getType() && "FieldInit with non-record type!");
+  }
+
+  FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION;
+  FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_FieldInit;
+  }
+  static FieldInit *get(Init *R, const std::string &FN);
+  static FieldInit *get(Init *R, const Init *FN);
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<FieldInit *>(this));
+  }
+
+  Init *getBit(unsigned Bit) const override;
+
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override;
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override {
+    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, public FoldingSetNode {
+  Init *Val;
+  std::string ValName;
+  std::vector<Init*> Args;
+  std::vector<std::string> ArgNames;
+
+  DagInit(Init *V, const std::string &VN,
+          ArrayRef<Init *> ArgRange,
+          ArrayRef<std::string> NameRange)
+      : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
+          Args(ArgRange.begin(), ArgRange.end()),
+          ArgNames(NameRange.begin(), NameRange.end()) {}
+
+  DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION;
+  DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION;
+
+public:
+  static bool classof(const Init *I) {
+    return I->getKind() == IK_DagInit;
+  }
+  static DagInit *get(Init *V, const std::string &VN,
+                      ArrayRef<Init *> ArgRange,
+                      ArrayRef<std::string> NameRange);
+  static DagInit *get(Init *V, const std::string &VN,
+                      const std::vector<
+                        std::pair<Init*, std::string> > &args);
+
+  void Profile(FoldingSetNodeID &ID) const;
+
+  Init *convertInitializerTo(RecTy *Ty) const override {
+    return Ty->convertValue(const_cast<DagInit *>(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];
+  }
+
+  Init *resolveReferences(Record &R, const RecordVal *RV) const override;
+
+  std::string getAsString() const override;
+
+  typedef std::vector<Init*>::const_iterator       const_arg_iterator;
+  typedef std::vector<std::string>::const_iterator const_name_iterator;
+
+  inline const_arg_iterator  arg_begin() const { return Args.begin(); }
+  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 const_name_iterator name_begin() const { return ArgNames.begin(); }
+  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(); }
+
+  Init *getBit(unsigned Bit) const override {
+    llvm_unreachable("Illegal bit reference off dag");
+  }
+
+  Init *resolveListElementReference(Record &R, const RecordVal *RV,
+                                    unsigned Elt) const override {
+    llvm_unreachable("Illegal element reference off dag");
+  }
+};
+
+//===----------------------------------------------------------------------===//
+//  High-Level Classes
+//===----------------------------------------------------------------------===//
+
+class RecordVal {
+  Init *Name;
+  RecTy *Ty;
+  unsigned Prefix;
+  Init *Value;
+
+public:
+  RecordVal(Init *N, RecTy *T, unsigned P);
+  RecordVal(const std::string &N, RecTy *T, unsigned P);
+
+  const std::string &getName() const;
+  const Init *getNameInit() const { return Name; }
+  std::string getNameInitAsString() const {
+    return getNameInit()->getAsUnquotedString();
+  }
+
+  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 == nullptr;
+    }
+    Value = nullptr;
+    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;
+  Init *Name;
+  // Location where record was instantiated, followed by the location of
+  // multiclass prototypes used.
+  SmallVector<SMLoc, 4> Locs;
+  std::vector<Init *> TemplateArgs;
+  std::vector<RecordVal> Values;
+  std::vector<Record *> SuperClasses;
+  std::vector<SMRange> SuperClassRanges;
+
+  // Tracks Record instances. Not owned by Record.
+  RecordKeeper &TrackedRecords;
+
+  DefInit *TheInit;
+  bool IsAnonymous;
+
+  void init();
+  void checkName();
+
+public:
+  // Constructs a record.
+  explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
+                  RecordKeeper &records, bool Anonymous = false) :
+    ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()),
+    TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous) {
+    init();
+  }
+  explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
+                  bool Anonymous = false) :
+    ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
+    TrackedRecords(records), TheInit(nullptr), IsAnonymous(Anonymous) {
+    init();
+  }
+
+  // When copy-constructing a Record, we must still guarantee a globally unique
+  // ID number.  All other fields can be copied normally.
+  Record(const Record &O) :
+    ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
+    Values(O.Values), SuperClasses(O.SuperClasses),
+    SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
+    TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { }
+
+  ~Record() {}
+
+  static unsigned getNewUID() { return LastID++; }
+
+  unsigned getID() const { return ID; }
+
+  const std::string &getName() const;
+  Init *getNameInit() const {
+    return Name;
+  }
+  const std::string getNameInitAsString() const {
+    return getNameInit()->getAsUnquotedString();
+  }
+
+  void setName(Init *Name);               // Also updates RecordKeeper.
+  void setName(const std::string &Name);  // Also updates RecordKeeper.
+
+  ArrayRef<SMLoc> getLoc() const { return Locs; }
+
+  /// get the corresponding DefInit.
+  DefInit *getDefInit();
+
+  const std::vector<Init *> &getTemplateArgs() const {
+    return TemplateArgs;
+  }
+  const std::vector<RecordVal> &getValues() const { return Values; }
+  const std::vector<Record*>   &getSuperClasses() const { return SuperClasses; }
+  ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
+
+  bool isTemplateArg(Init *Name) const {
+    for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
+      if (TemplateArgs[i] == Name) return true;
+    return false;
+  }
+  bool isTemplateArg(StringRef Name) const {
+    return isTemplateArg(StringInit::get(Name.str()));
+  }
+
+  const RecordVal *getValue(const Init *Name) const {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getNameInit() == Name) return &Values[i];
+    return nullptr;
+  }
+  const RecordVal *getValue(StringRef Name) const {
+    return getValue(StringInit::get(Name));
+  }
+  RecordVal *getValue(const Init *Name) {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getNameInit() == Name) return &Values[i];
+    return nullptr;
+  }
+  RecordVal *getValue(StringRef Name) {
+    return getValue(StringInit::get(Name));
+  }
+
+  void addTemplateArg(Init *Name) {
+    assert(!isTemplateArg(Name) && "Template arg already defined!");
+    TemplateArgs.push_back(Name);
+  }
+  void addTemplateArg(StringRef Name) {
+    addTemplateArg(StringInit::get(Name.str()));
+  }
+
+  void addValue(const RecordVal &RV) {
+    assert(getValue(RV.getNameInit()) == nullptr && "Value already added!");
+    Values.push_back(RV);
+    if (Values.size() > 1)
+      // Keep NAME at the end of the list.  It makes record dumps a
+      // bit prettier and allows TableGen tests to be written more
+      // naturally.  Tests can use CHECK-NEXT to look for Record
+      // fields they expect to see after a def.  They can't do that if
+      // NAME is the first Record field.
+      std::swap(Values[Values.size() - 2], Values[Values.size() - 1]);
+  }
+
+  void removeValue(Init *Name) {
+    for (unsigned i = 0, e = Values.size(); i != e; ++i)
+      if (Values[i].getNameInit() == Name) {
+        Values.erase(Values.begin()+i);
+        return;
+      }
+    llvm_unreachable("Cannot remove an entry that does not exist!");
+  }
+
+  void removeValue(StringRef Name) {
+    removeValue(StringInit::get(Name.str()));
+  }
+
+  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]->getNameInitAsString() == Name)
+        return true;
+    return false;
+  }
+
+  void addSuperClass(Record *R, SMRange Range) {
+    assert(!isSubClassOf(R) && "Already subclassing record!");
+    SuperClasses.push_back(R);
+    SuperClassRanges.push_back(Range);
+  }
+
+  /// 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(nullptr); }
+
+  /// 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);
+
+  RecordKeeper &getRecords() const {
+    return TrackedRecords;
+  }
+
+  bool isAnonymous() const {
+    return IsAnonymous;
+  }
+
+  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;
+
+  /// Return true if the named field is unset.
+  bool isValueUnset(StringRef FieldName) const {
+    return getValueInit(FieldName) == UnsetInit::get();
+  }
+
+  /// 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;
+
+  /// getValueAsListOfStrings - This method looks up the specified field and
+  /// returns its value as a vector of strings, throwing an exception if the
+  /// field does not exist or if the value is not the right type.
+  ///
+  std::vector<std::string> getValueAsListOfStrings(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;
+
+  /// getValueAsBitOrUnset - This method looks up the specified field and
+  /// returns its value as a bit. If the field is unset, sets Unset to true and
+  /// returns false.
+  ///
+  bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) 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;
+};
+
+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, RecordKeeper &Records) :
+    Rec(Name, Loc, Records) {}
+};
+
+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() ? nullptr : I->second;
+  }
+  Record *getDef(const std::string &Name) const {
+    std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
+    return I == Defs.end() ? nullptr : I->second;
+  }
+  void addClass(Record *R) {
+    bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second;
+    (void)Ins;
+    assert(Ins && "Class already exists");
+  }
+  void addDef(Record *R) {
+    bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second;
+    (void)Ins;
+    assert(Ins && "Record already exists");
+  }
+
+  /// 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;
+  }
+};
+
+/// LessRecordByID - Sorting predicate to sort record pointers by their
+/// unique ID. If you just need a deterministic order, use this, since it
+/// just compares two `unsigned`; the other sorting predicates require
+/// string manipulation.
+struct LessRecordByID {
+  bool operator()(const Record *LHS, const Record *RHS) const {
+    return LHS->getID() < RHS->getID();
+  }
+};
+
+/// 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");
+  }
+};
+
+struct LessRecordRegister {
+  static size_t min(size_t a, size_t b) { return a < b ? a : b; }
+  static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; }
+
+  struct RecordParts {
+    SmallVector<std::pair< bool, StringRef>, 4> Parts;
+
+    RecordParts(StringRef Rec) {
+      if (Rec.empty())
+        return;
+
+      size_t Len = 0;
+      const char *Start = Rec.data();
+      const char *Curr = Start;
+      bool isDigitPart = ascii_isdigit(Curr[0]);
+      for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
+        bool isDigit = ascii_isdigit(Curr[I]);
+        if (isDigit != isDigitPart) {
+          Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
+          Len = 0;
+          Start = &Curr[I];
+          isDigitPart = ascii_isdigit(Curr[I]);
+        }
+      }
+      // Push the last part.
+      Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
+    }
+
+    size_t size() { return Parts.size(); }
+
+    std::pair<bool, StringRef> getPart(size_t i) {
+      assert (i < Parts.size() && "Invalid idx!");
+      return Parts[i];
+    }
+  };
+
+  bool operator()(const Record *Rec1, const Record *Rec2) const {
+    RecordParts LHSParts(StringRef(Rec1->getName()));
+    RecordParts RHSParts(StringRef(Rec2->getName()));
+
+    size_t LHSNumParts = LHSParts.size();
+    size_t RHSNumParts = RHSParts.size();
+    assert (LHSNumParts && RHSNumParts && "Expected at least one part!");
+
+    if (LHSNumParts != RHSNumParts)
+      return LHSNumParts < RHSNumParts;
+
+    // We expect the registers to be of the form [_a-zA-z]+([0-9]*[_a-zA-Z]*)*.
+    for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
+      std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
+      std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
+      // Expect even part to always be alpha.
+      assert (LHSPart.first == false && RHSPart.first == false &&
+              "Expected both parts to be alpha.");
+      if (int Res = LHSPart.second.compare(RHSPart.second))
+        return Res < 0;
+    }
+    for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
+      std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
+      std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
+      // Expect odd part to always be numeric.
+      assert (LHSPart.first == true && RHSPart.first == true &&
+              "Expected both parts to be numeric.");
+      if (LHSPart.second.size() != RHSPart.second.size())
+        return LHSPart.second.size() < RHSPart.second.size();
+
+      unsigned LHSVal, RHSVal;
+
+      bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
+      assert(!LHSFailed && "Unable to convert LHS to integer.");
+      bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
+      assert(!RHSFailed && "Unable to convert RHS to integer.");
+
+      if (LHSVal != RHSVal)
+        return LHSVal < RHSVal;
+    }
+    return LHSNumParts < RHSNumParts;
+  }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
+
+/// QualifyName - Return an Init with a qualifier prefix referring
+/// to CurRec's name.
+Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
+                  Init *Name, const std::string &Scoper);
+
+/// QualifyName - Return an Init with a qualifier prefix referring
+/// to CurRec's name.
+Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
+                  const std::string &Name, const std::string &Scoper);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/TableGen/SetTheory.h b/include/llvm/TableGen/SetTheory.h
new file mode 100644
index 0000000..5baed79
--- /dev/null
+++ b/include/llvm/TableGen/SetTheory.h
@@ -0,0 +1,142 @@
+//===- SetTheory.h - Generate ordered sets from DAG expressions -*- C++ -*-===//
+//
+//                     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 SetTheory class that computes ordered sets of
+// Records from DAG expressions.  Operators for standard set operations are
+// predefined, and it is possible to add special purpose set operators as well.
+//
+// The user may define named sets as Records of predefined classes. Set
+// expanders can be added to a SetTheory instance to teach it how to find the
+// elements of such a named set.
+//
+// These are the predefined operators. The argument lists can be individual
+// elements (defs), other sets (defs of expandable classes), lists, or DAG
+// expressions that are evaluated recursively.
+//
+// - (add S1, S2 ...) Union sets. This is also how sets are created from element
+//   lists.
+//
+// - (sub S1, S2, ...) Set difference. Every element in S1 except for the
+//   elements in S2, ...
+//
+// - (and S1, S2) Set intersection. Every element in S1 that is also in S2.
+//
+// - (shl S, N) Shift left. Remove the first N elements from S.
+//
+// - (trunc S, N) Truncate. The first N elements of S.
+//
+// - (rotl S, N) Rotate left. Same as (add (shl S, N), (trunc S, N)).
+//
+// - (rotr S, N) Rotate right.
+//
+// - (decimate S, N) Decimate S by picking every N'th element, starting with
+//   the first one. For instance, (decimate S, 2) returns the even elements of
+//   S.
+//
+// - (sequence "Format", From, To) Generate a sequence of defs with printf.
+//   For instance, (sequence "R%u", 0, 3) -> [ R0, R1, R2, R3 ]
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SETTHEORY_H
+#define SETTHEORY_H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/SourceMgr.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class DagInit;
+class Init;
+class Record;
+class RecordKeeper;
+
+class SetTheory {
+public:
+  typedef std::vector<Record*> RecVec;
+  typedef SmallSetVector<Record*, 16> RecSet;
+
+  /// Operator - A callback representing a DAG operator.
+  class Operator {
+    virtual void anchor();
+  public:
+    virtual ~Operator() {}
+
+    /// apply - Apply this operator to Expr's arguments and insert the result
+    /// in Elts.
+    virtual void apply(SetTheory&, DagInit *Expr, RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) =0;
+  };
+
+  /// Expander - A callback function that can transform a Record representing a
+  /// set into a fully expanded list of elements. Expanders provide a way for
+  /// users to define named sets that can be used in DAG expressions.
+  class Expander {
+    virtual void anchor();
+  public:
+    virtual ~Expander() {}
+
+    virtual void expand(SetTheory&, Record*, RecSet &Elts) =0;
+  };
+
+private:
+  // Map set defs to their fully expanded contents. This serves as a memoization
+  // cache and it makes it possible to return const references on queries.
+  typedef std::map<Record*, RecVec> ExpandMap;
+  ExpandMap Expansions;
+
+  // Known DAG operators by name.
+  StringMap<Operator*> Operators;
+
+  // Typed expanders by class name.
+  StringMap<Expander*> Expanders;
+
+public:
+  /// Create a SetTheory instance with only the standard operators.
+  SetTheory();
+
+  /// addExpander - Add an expander for Records with the named super class.
+  void addExpander(StringRef ClassName, Expander*);
+
+  /// addFieldExpander - Add an expander for ClassName that simply evaluates
+  /// FieldName in the Record to get the set elements.  That is all that is
+  /// needed for a class like:
+  ///
+  ///   class Set<dag d> {
+  ///     dag Elts = d;
+  ///   }
+  ///
+  void addFieldExpander(StringRef ClassName, StringRef FieldName);
+
+  /// addOperator - Add a DAG operator.
+  void addOperator(StringRef Name, Operator*);
+
+  /// evaluate - Evaluate Expr and append the resulting set to Elts.
+  void evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc);
+
+  /// evaluate - Evaluate a sequence of Inits and append to Elts.
+  template<typename Iter>
+  void evaluate(Iter begin, Iter end, RecSet &Elts, ArrayRef<SMLoc> Loc) {
+    while (begin != end)
+      evaluate(*begin++, Elts, Loc);
+  }
+
+  /// expand - Expand a record into a set of elements if possible.  Return a
+  /// pointer to the expanded elements, or NULL if Set cannot be expanded
+  /// further.
+  const RecVec *expand(Record *Set);
+};
+
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h
new file mode 100644
index 0000000..b438779
--- /dev/null
+++ b/include/llvm/TableGen/StringMatcher.h
@@ -0,0 +1,54 @@
+//===- StringMatcher.h - Generate a matcher for input strings ---*- C++ -*-===//
+//
+//                     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 StringMatcher class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_STRINGMATCHER_H
+#define LLVM_TABLEGEN_STRINGMATCHER_H
+
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class raw_ostream;
+
+/// StringMatcher - 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.
+///
+class StringMatcher {
+public:
+  typedef std::pair<std::string, std::string> StringPair;
+
+private:
+  StringRef StrVariableName;
+  const std::vector<StringPair> &Matches;
+  raw_ostream &OS;
+
+public:
+  StringMatcher(StringRef strVariableName, 
+                const std::vector<StringPair> &matches, raw_ostream &os)
+    : StrVariableName(strVariableName), Matches(matches), OS(os) {}
+
+  void Emit(unsigned Indent = 0) const;
+
+private:
+  bool EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
+                                unsigned CharNo, unsigned IndentCount) const;
+};
+
+} // end llvm namespace.
+
+#endif
diff --git a/include/llvm/TableGen/StringToOffsetTable.h b/include/llvm/TableGen/StringToOffsetTable.h
new file mode 100644
index 0000000..c924bd8
--- /dev/null
+++ b/include/llvm/TableGen/StringToOffsetTable.h
@@ -0,0 +1,83 @@
+//===- 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/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cctype>
+
+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, bool appendZero = true) {
+    StringMapEntry<unsigned> &Entry = StringOffset.GetOrCreateValue(Str, -1U);
+    if (Entry.getValue() == -1U) {
+      // Add the string to the aggregate if this is the first time found.
+      Entry.setValue(AggregateString.size());
+      AggregateString.append(Str.begin(), Str.end());
+      if (appendZero)
+        AggregateString += '\0';
+    }
+
+    return Entry.getValue();
+  }
+
+  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/include/llvm/TableGen/TableGenBackend.h b/include/llvm/TableGen/TableGenBackend.h
new file mode 100644
index 0000000..3e4f3cc
--- /dev/null
+++ b/include/llvm/TableGen/TableGenBackend.h
@@ -0,0 +1,29 @@
+//===- llvm/TableGen/TableGenBackend.h - Backend utilities ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Useful utilities for TableGen backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_TABLEGENBACKEND_H
+#define LLVM_TABLEGEN_TABLEGENBACKEND_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+/// emitSourceFileHeader - Output an LLVM style file header to the specified
+/// raw_ostream.
+void emitSourceFileHeader(StringRef Desc, raw_ostream &OS);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/CostTable.h b/include/llvm/Target/CostTable.h
new file mode 100644
index 0000000..34f6041
--- /dev/null
+++ b/include/llvm/Target/CostTable.h
@@ -0,0 +1,81 @@
+//===-- CostTable.h - Instruction Cost Table handling -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Cost tables and simple lookup functions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_COSTTABLE_H_
+#define LLVM_TARGET_COSTTABLE_H_
+
+namespace llvm {
+
+/// Cost Table Entry
+template <class TypeTy>
+struct CostTblEntry {
+  int ISD;
+  TypeTy Type;
+  unsigned Cost;
+};
+
+/// Find in cost table, TypeTy must be comparable to CompareTy by ==
+template <class TypeTy, class CompareTy>
+int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, unsigned len, int ISD,
+                    CompareTy Ty) {
+  for (unsigned int i = 0; i < len; ++i)
+    if (ISD == Tbl[i].ISD && Ty == Tbl[i].Type)
+      return i;
+
+  // Could not find an entry.
+  return -1;
+}
+
+/// Find in cost table, TypeTy must be comparable to CompareTy by ==
+template <class TypeTy, class CompareTy, unsigned N>
+int CostTableLookup(const CostTblEntry<TypeTy>(&Tbl)[N], int ISD,
+                    CompareTy Ty) {
+  return CostTableLookup(Tbl, N, ISD, Ty);
+}
+
+/// Type Conversion Cost Table
+template <class TypeTy>
+struct TypeConversionCostTblEntry {
+  int ISD;
+  TypeTy Dst;
+  TypeTy Src;
+  unsigned Cost;
+};
+
+/// Find in type conversion cost table, TypeTy must be comparable to CompareTy
+/// by ==
+template <class TypeTy, class CompareTy>
+int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl,
+                           unsigned len, int ISD, CompareTy Dst,
+                           CompareTy Src) {
+  for (unsigned int i = 0; i < len; ++i)
+    if (ISD == Tbl[i].ISD && Src == Tbl[i].Src && Dst == Tbl[i].Dst)
+      return i;
+
+  // Could not find an entry.
+  return -1;
+}
+
+/// Find in type conversion cost table, TypeTy must be comparable to CompareTy
+/// by ==
+template <class TypeTy, class CompareTy, unsigned N>
+int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy>(&Tbl)[N],
+                           int ISD, CompareTy Dst, CompareTy Src) {
+  return ConvertCostTableLookup(Tbl, N, ISD, Dst, Src);
+}
+
+} // namespace llvm
+
+
+#endif /* LLVM_TARGET_COSTTABLE_H_ */
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
new file mode 100644
index 0000000..f77cc7a
--- /dev/null
+++ b/include/llvm/Target/Target.td
@@ -0,0 +1,1148 @@
+//===- Target.td - Target Independent TableGen interface ---*- tablegen -*-===//
+//
+//                     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 target-independent interfaces which should be
+// implemented by each target which is using a TableGen based code generator.
+//
+//===----------------------------------------------------------------------===//
+
+// Include all information about LLVM intrinsics.
+include "llvm/IR/Intrinsics.td"
+
+//===----------------------------------------------------------------------===//
+// Register file description - These classes are used to fill in the target
+// description classes.
+
+class RegisterClass; // Forward def
+
+// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
+class SubRegIndex<int size, int offset = 0> {
+  string Namespace = "";
+
+  // Size - Size (in bits) of the sub-registers represented by this index.
+  int Size = size;
+
+  // Offset - Offset of the first bit that is part of this sub-register index.
+  // Set it to -1 if the same index is used to represent sub-registers that can
+  // be at different offsets (for example when using an index to access an
+  // element in a register tuple).
+  int Offset = offset;
+
+  // ComposedOf - A list of two SubRegIndex instances, [A, B].
+  // This indicates that this SubRegIndex is the result of composing A and B.
+  // See ComposedSubRegIndex.
+  list<SubRegIndex> ComposedOf = [];
+
+  // CoveringSubRegIndices - A list of two or more sub-register indexes that
+  // cover this sub-register.
+  //
+  // This field should normally be left blank as TableGen can infer it.
+  //
+  // TableGen automatically detects sub-registers that straddle the registers
+  // in the SubRegs field of a Register definition. For example:
+  //
+  //   Q0    = dsub_0 -> D0, dsub_1 -> D1
+  //   Q1    = dsub_0 -> D2, dsub_1 -> D3
+  //   D1_D2 = dsub_0 -> D1, dsub_1 -> D2
+  //   QQ0   = qsub_0 -> Q0, qsub_1 -> Q1
+  //
+  // TableGen will infer that D1_D2 is a sub-register of QQ0. It will be given
+  // the synthetic index dsub_1_dsub_2 unless some SubRegIndex is defined with
+  // CoveringSubRegIndices = [dsub_1, dsub_2].
+  list<SubRegIndex> CoveringSubRegIndices = [];
+}
+
+// ComposedSubRegIndex - A sub-register that is the result of composing A and B.
+// Offset is set to the sum of A and B's Offsets. Size is set to B's Size.
+class ComposedSubRegIndex<SubRegIndex A, SubRegIndex B>
+  : SubRegIndex<B.Size, !if(!eq(A.Offset, -1), -1,
+                        !if(!eq(B.Offset, -1), -1,
+                            !add(A.Offset, B.Offset)))> {
+  // See SubRegIndex.
+  let ComposedOf = [A, B];
+}
+
+// RegAltNameIndex - The alternate name set to use for register operands of
+// this register class when printing.
+class RegAltNameIndex {
+  string Namespace = "";
+}
+def NoRegAltName : RegAltNameIndex;
+
+// Register - You should define one instance of this class for each register
+// in the target machine.  String n will become the "name" of the register.
+class Register<string n, list<string> altNames = []> {
+  string Namespace = "";
+  string AsmName = n;
+  list<string> AltNames = altNames;
+
+  // Aliases - A list of registers that this register overlaps with.  A read or
+  // modification of this register can potentially read or modify the aliased
+  // registers.
+  list<Register> Aliases = [];
+
+  // SubRegs - A list of registers that are parts of this register. Note these
+  // are "immediate" sub-registers and the registers within the list do not
+  // themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
+  // not [AX, AH, AL].
+  list<Register> SubRegs = [];
+
+  // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used
+  // to address it. Sub-sub-register indices are automatically inherited from
+  // SubRegs.
+  list<SubRegIndex> SubRegIndices = [];
+
+  // RegAltNameIndices - The alternate name indices which are valid for this
+  // register.
+  list<RegAltNameIndex> RegAltNameIndices = [];
+
+  // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register.
+  // These values can be determined by locating the <target>.h file in the
+  // directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES.  The
+  // order of these names correspond to the enumeration used by gcc.  A value of
+  // -1 indicates that the gcc number is undefined and -2 that register number
+  // is invalid for this mode/flavour.
+  list<int> DwarfNumbers = [];
+
+  // CostPerUse - Additional cost of instructions using this register compared
+  // to other registers in its class. The register allocator will try to
+  // minimize the number of instructions using a register with a CostPerUse.
+  // This is used by the x86-64 and ARM Thumb targets where some registers
+  // require larger instruction encodings.
+  int CostPerUse = 0;
+
+  // CoveredBySubRegs - When this bit is set, the value of this register is
+  // completely determined by the value of its sub-registers.  For example, the
+  // x86 register AX is covered by its sub-registers AL and AH, but EAX is not
+  // covered by its sub-register AX.
+  bit CoveredBySubRegs = 0;
+
+  // HWEncoding - The target specific hardware encoding for this register.
+  bits<16> HWEncoding = 0;
+}
+
+// RegisterWithSubRegs - This can be used to define instances of Register which
+// need to specify sub-registers.
+// List "subregs" specifies which registers are sub-registers to this one. This
+// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
+// This allows the code generator to be careful not to put two values with
+// overlapping live ranges into registers which alias.
+class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
+  let SubRegs = subregs;
+}
+
+// DAGOperand - An empty base class that unifies RegisterClass's and other forms
+// of Operand's that are legal as type qualifiers in DAG patterns.  This should
+// only ever be used for defining multiclasses that are polymorphic over both
+// RegisterClass's and other Operand's.
+class DAGOperand { }
+
+// RegisterClass - Now that all of the registers are defined, and aliases
+// between registers are defined, specify which registers belong to which
+// register classes.  This also defines the default allocation order of
+// registers by register allocators.
+//
+class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
+                    dag regList, RegAltNameIndex idx = NoRegAltName>
+  : DAGOperand {
+  string Namespace = namespace;
+
+  // RegType - Specify the list ValueType of the registers in this register
+  // class.  Note that all registers in a register class must have the same
+  // ValueTypes.  This is a list because some targets permit storing different
+  // types in same register, for example vector values with 128-bit total size,
+  // but different count/size of items, like SSE on x86.
+  //
+  list<ValueType> RegTypes = regTypes;
+
+  // Size - Specify the spill size in bits of the registers.  A default value of
+  // zero lets tablgen pick an appropriate size.
+  int Size = 0;
+
+  // Alignment - Specify the alignment required of the registers when they are
+  // stored or loaded to memory.
+  //
+  int Alignment = alignment;
+
+  // CopyCost - This value is used to specify the cost of copying a value
+  // between two registers in this register class. The default value is one
+  // meaning it takes a single instruction to perform the copying. A negative
+  // value means copying is extremely expensive or impossible.
+  int CopyCost = 1;
+
+  // MemberList - Specify which registers are in this class.  If the
+  // allocation_order_* method are not specified, this also defines the order of
+  // allocation used by the register allocator.
+  //
+  dag MemberList = regList;
+
+  // AltNameIndex - The alternate register name to use when printing operands
+  // of this register class. Every register in the register class must have
+  // a valid alternate name for the given index.
+  RegAltNameIndex altNameIndex = idx;
+
+  // isAllocatable - Specify that the register class can be used for virtual
+  // registers and register allocation.  Some register classes are only used to
+  // model instruction operand constraints, and should have isAllocatable = 0.
+  bit isAllocatable = 1;
+
+  // AltOrders - List of alternative allocation orders. The default order is
+  // MemberList itself, and that is good enough for most targets since the
+  // register allocators automatically remove reserved registers and move
+  // callee-saved registers to the end.
+  list<dag> AltOrders = [];
+
+  // AltOrderSelect - The body of a function that selects the allocation order
+  // to use in a given machine function. The code will be inserted in a
+  // function like this:
+  //
+  //   static inline unsigned f(const MachineFunction &MF) { ... }
+  //
+  // The function should return 0 to select the default order defined by
+  // MemberList, 1 to select the first AltOrders entry and so on.
+  code AltOrderSelect = [{}];
+}
+
+// The memberList in a RegisterClass is a dag of set operations. TableGen
+// evaluates these set operations and expand them into register lists. These
+// are the most common operation, see test/TableGen/SetTheory.td for more
+// examples of what is possible:
+//
+// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a
+// register class, or a sub-expression. This is also the way to simply list
+// registers.
+//
+// (sub GPR, SP) - Set difference. Subtract the last arguments from the first.
+//
+// (and GPR, CSR) - Set intersection. All registers from the first set that are
+// also in the second set.
+//
+// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
+// numbered registers.  Takes an optional 4th operand which is a stride to use
+// when generating the sequence.
+//
+// (shl GPR, 4) - Remove the first N elements.
+//
+// (trunc GPR, 4) - Truncate after the first N elements.
+//
+// (rotl GPR, 1) - Rotate N places to the left.
+//
+// (rotr GPR, 1) - Rotate N places to the right.
+//
+// (decimate GPR, 2) - Pick every N'th element, starting with the first.
+//
+// (interleave A, B, ...) - Interleave the elements from each argument list.
+//
+// All of these operators work on ordered sets, not lists. That means
+// duplicates are removed from sub-expressions.
+
+// Set operators. The rest is defined in TargetSelectionDAG.td.
+def sequence;
+def decimate;
+def interleave;
+
+// RegisterTuples - Automatically generate super-registers by forming tuples of
+// sub-registers. This is useful for modeling register sequence constraints
+// with pseudo-registers that are larger than the architectural registers.
+//
+// The sub-register lists are zipped together:
+//
+//   def EvenOdd : RegisterTuples<[sube, subo], [(add R0, R2), (add R1, R3)]>;
+//
+// Generates the same registers as:
+//
+//   let SubRegIndices = [sube, subo] in {
+//     def R0_R1 : RegisterWithSubRegs<"", [R0, R1]>;
+//     def R2_R3 : RegisterWithSubRegs<"", [R2, R3]>;
+//   }
+//
+// The generated pseudo-registers inherit super-classes and fields from their
+// first sub-register. Most fields from the Register class are inferred, and
+// the AsmName and Dwarf numbers are cleared.
+//
+// RegisterTuples instances can be used in other set operations to form
+// register classes and so on. This is the only way of using the generated
+// registers.
+class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> {
+  // SubRegs - N lists of registers to be zipped up. Super-registers are
+  // synthesized from the first element of each SubRegs list, the second
+  // element and so on.
+  list<dag> SubRegs = Regs;
+
+  // SubRegIndices - N SubRegIndex instances. This provides the names of the
+  // sub-registers in the synthesized super-registers.
+  list<SubRegIndex> SubRegIndices = Indices;
+}
+
+
+//===----------------------------------------------------------------------===//
+// DwarfRegNum - This class provides a mapping of the llvm register enumeration
+// to the register numbering used by gcc and gdb.  These values are used by a
+// debug information writer to describe where values may be located during
+// execution.
+class DwarfRegNum<list<int> Numbers> {
+  // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register.
+  // These values can be determined by locating the <target>.h file in the
+  // directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES.  The
+  // order of these names correspond to the enumeration used by gcc.  A value of
+  // -1 indicates that the gcc number is undefined and -2 that register number
+  // is invalid for this mode/flavour.
+  list<int> DwarfNumbers = Numbers;
+}
+
+// DwarfRegAlias - This class declares that a given register uses the same dwarf
+// numbers as another one. This is useful for making it clear that the two
+// registers do have the same number. It also lets us build a mapping
+// from dwarf register number to llvm register.
+class DwarfRegAlias<Register reg> {
+      Register DwarfAlias = reg;
+}
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for scheduling
+//
+include "llvm/Target/TargetSchedule.td"
+
+class Predicate; // Forward def
+
+//===----------------------------------------------------------------------===//
+// Instruction set description - These classes correspond to the C++ classes in
+// the Target/TargetInstrInfo.h file.
+//
+class Instruction {
+  string Namespace = "";
+
+  dag OutOperandList;       // An dag containing the MI def operand list.
+  dag InOperandList;        // An dag containing the MI use operand list.
+  string AsmString = "";    // The .s format to print the instruction with.
+
+  // Pattern - Set to the DAG pattern for this instruction, if we know of one,
+  // otherwise, uninitialized.
+  list<dag> Pattern;
+
+  // The follow state will eventually be inferred automatically from the
+  // instruction pattern.
+
+  list<Register> Uses = []; // Default to using no non-operand registers
+  list<Register> Defs = []; // Default to modifying no non-operand registers
+
+  // Predicates - List of predicates which will be turned into isel matching
+  // code.
+  list<Predicate> Predicates = [];
+
+  // Size - Size of encoded instruction, or zero if the size cannot be determined
+  // from the opcode.
+  int Size = 0;
+
+  // DecoderNamespace - The "namespace" in which this instruction exists, on
+  // targets like ARM which multiple ISA namespaces exist.
+  string DecoderNamespace = "";
+
+  // Code size, for instruction selection.
+  // FIXME: What does this actually mean?
+  int CodeSize = 0;
+
+  // Added complexity passed onto matching pattern.
+  int AddedComplexity  = 0;
+
+  // These bits capture information about the high-level semantics of the
+  // instruction.
+  bit isReturn     = 0;     // Is this instruction a return instruction?
+  bit isBranch     = 0;     // Is this instruction a branch instruction?
+  bit isIndirectBranch = 0; // Is this instruction an indirect branch?
+  bit isCompare    = 0;     // Is this instruction a comparison instruction?
+  bit isMoveImm    = 0;     // Is this instruction a move immediate instruction?
+  bit isBitcast    = 0;     // Is this instruction a bitcast instruction?
+  bit isSelect     = 0;     // Is this instruction a select instruction?
+  bit isBarrier    = 0;     // Can control flow fall through this instruction?
+  bit isCall       = 0;     // Is this instruction a call instruction?
+  bit canFoldAsLoad = 0;    // Can this be folded as a simple memory operand?
+  bit mayLoad      = ?;     // Is it possible for this inst to read memory?
+  bit mayStore     = ?;     // Is it possible for this inst to write memory?
+  bit isConvertibleToThreeAddress = 0;  // Can this 2-addr instruction promote?
+  bit isCommutable = 0;     // Is this 3 operand instruction commutable?
+  bit isTerminator = 0;     // Is this part of the terminator for a basic block?
+  bit isReMaterializable = 0; // Is this instruction re-materializable?
+  bit isPredicable = 0;     // Is this instruction predicable?
+  bit hasDelaySlot = 0;     // Does this instruction have an delay slot?
+  bit usesCustomInserter = 0; // Pseudo instr needing special help.
+  bit hasPostISelHook = 0;  // To be *adjusted* after isel by target hook.
+  bit hasCtrlDep   = 0;     // Does this instruction r/w ctrl-flow chains?
+  bit isNotDuplicable = 0;  // Is it unsafe to duplicate this instruction?
+  bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
+  bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
+  bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
+  bit isPseudo     = 0;     // Is this instruction a pseudo-instruction?
+                            // If so, won't have encoding information for
+                            // the [MC]CodeEmitter stuff.
+
+  // Side effect flags - When set, the flags have these meanings:
+  //
+  //  hasSideEffects - The instruction has side effects that are not
+  //    captured by any operands of the instruction or other flags.
+  //
+  //  neverHasSideEffects (deprecated) - Set on an instruction with no pattern
+  //    if it has no side effects. This is now equivalent to setting
+  //    "hasSideEffects = 0".
+  bit hasSideEffects = ?;
+  bit neverHasSideEffects = 0;
+
+  // Is this instruction a "real" instruction (with a distinct machine
+  // encoding), or is it a pseudo instruction used for codegen modeling
+  // purposes.
+  // FIXME: For now this is distinct from isPseudo, above, as code-gen-only
+  // instructions can (and often do) still have encoding information
+  // associated with them. Once we've migrated all of them over to true
+  // pseudo-instructions that are lowered to real instructions prior to
+  // the printer/emitter, we can remove this attribute and just use isPseudo.
+  //
+  // The intended use is:
+  // isPseudo: Does not have encoding information and should be expanded,
+  //   at the latest, during lowering to MCInst.
+  //
+  // isCodeGenOnly: Does have encoding information and can go through to the
+  //   CodeEmitter unchanged, but duplicates a canonical instruction
+  //   definition's encoding and should be ignored when constructing the
+  //   assembler match tables.
+  bit isCodeGenOnly = 0;
+
+  // Is this instruction a pseudo instruction for use by the assembler parser.
+  bit isAsmParserOnly = 0;
+
+  InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
+
+  // Scheduling information from TargetSchedule.td.
+  list<SchedReadWrite> SchedRW;
+
+  string Constraints = "";  // OperandConstraint, e.g. $src = $dst.
+
+  /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not
+  /// be encoded into the output machineinstr.
+  string DisableEncoding = "";
+
+  string PostEncoderMethod = "";
+  string DecoderMethod = "";
+
+  /// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
+  bits<64> TSFlags = 0;
+
+  ///@name Assembler Parser Support
+  ///@{
+
+  string AsmMatchConverter = "";
+
+  /// TwoOperandAliasConstraint - Enable TableGen to auto-generate a
+  /// two-operand matcher inst-alias for a three operand instruction.
+  /// For example, the arm instruction "add r3, r3, r5" can be written
+  /// as "add r3, r5". The constraint is of the same form as a tied-operand
+  /// constraint. For example, "$Rn = $Rd".
+  string TwoOperandAliasConstraint = "";
+
+  ///@}
+
+  /// UseNamedOperandTable - If set, the operand indices of this instruction
+  /// can be queried via the getNamedOperandIdx() function which is generated
+  /// by TableGen.
+  bit UseNamedOperandTable = 0;
+}
+
+/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
+/// Which instruction it expands to and how the operands map from the
+/// pseudo.
+class PseudoInstExpansion<dag Result> {
+  dag ResultInst = Result;     // The instruction to generate.
+  bit isPseudo = 1;
+}
+
+/// Predicates - These are extra conditionals which are turned into instruction
+/// selector matching code. Currently each predicate is just a string.
+class Predicate<string cond> {
+  string CondString = cond;
+
+  /// AssemblerMatcherPredicate - If this feature can be used by the assembler
+  /// matcher, this is true.  Targets should set this by inheriting their
+  /// feature from the AssemblerPredicate class in addition to Predicate.
+  bit AssemblerMatcherPredicate = 0;
+
+  /// AssemblerCondString - Name of the subtarget feature being tested used
+  /// as alternative condition string used for assembler matcher.
+  /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0".
+  ///      "!ModeThumb" is translated to "(Bits & ModeThumb) == 0".
+  /// It can also list multiple features separated by ",".
+  /// e.g. "ModeThumb,FeatureThumb2" is translated to
+  ///      "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
+  string AssemblerCondString = "";
+
+  /// PredicateName - User-level name to use for the predicate. Mainly for use
+  /// in diagnostics such as missing feature errors in the asm matcher.
+  string PredicateName = "";
+}
+
+/// NoHonorSignDependentRounding - This predicate is true if support for
+/// sign-dependent-rounding is not enabled.
+def NoHonorSignDependentRounding
+ : Predicate<"!TM.Options.HonorSignDependentRoundingFPMath()">;
+
+class Requires<list<Predicate> preds> {
+  list<Predicate> Predicates = preds;
+}
+
+/// ops definition - This is just a simple marker used to identify the operand
+/// list for an instruction. outs and ins are identical both syntactically and
+/// semanticallyr; they are used to define def operands and use operands to
+/// improve readibility. This should be used like this:
+///     (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar.
+def ops;
+def outs;
+def ins;
+
+/// variable_ops definition - Mark this instruction as taking a variable number
+/// of operands.
+def variable_ops;
+
+
+/// PointerLikeRegClass - Values that are designed to have pointer width are
+/// derived from this.  TableGen treats the register class as having a symbolic
+/// type that it doesn't know, and resolves the actual regclass to use by using
+/// the TargetRegisterInfo::getPointerRegClass() hook at codegen time.
+class PointerLikeRegClass<int Kind> {
+  int RegClassKind = Kind;
+}
+
+
+/// ptr_rc definition - Mark this operand as being a pointer value whose
+/// register class is resolved dynamically via a callback to TargetInstrInfo.
+/// FIXME: We should probably change this to a class which contain a list of
+/// flags. But currently we have but one flag.
+def ptr_rc : PointerLikeRegClass<0>;
+
+/// unknown definition - Mark this operand as being of unknown type, causing
+/// it to be resolved by inference in the context it is used.
+class unknown_class;
+def unknown : unknown_class;
+
+/// AsmOperandClass - Representation for the kinds of operands which the target
+/// specific parser can create and the assembly matcher may need to distinguish.
+///
+/// Operand classes are used to define the order in which instructions are
+/// matched, to ensure that the instruction which gets matched for any
+/// particular list of operands is deterministic.
+///
+/// The target specific parser must be able to classify a parsed operand into a
+/// unique class which does not partially overlap with any other classes. It can
+/// match a subset of some other class, in which case the super class field
+/// should be defined.
+class AsmOperandClass {
+  /// The name to use for this class, which should be usable as an enum value.
+  string Name = ?;
+
+  /// The super classes of this operand.
+  list<AsmOperandClass> SuperClasses = [];
+
+  /// The name of the method on the target specific operand to call to test
+  /// whether the operand is an instance of this class. If not set, this will
+  /// default to "isFoo", where Foo is the AsmOperandClass name. The method
+  /// signature should be:
+  ///   bool isFoo() const;
+  string PredicateMethod = ?;
+
+  /// The name of the method on the target specific operand to call to add the
+  /// target specific operand to an MCInst. If not set, this will default to
+  /// "addFooOperands", where Foo is the AsmOperandClass name. The method
+  /// signature should be:
+  ///   void addFooOperands(MCInst &Inst, unsigned N) const;
+  string RenderMethod = ?;
+
+  /// The name of the method on the target specific operand to call to custom
+  /// handle the operand parsing. This is useful when the operands do not relate
+  /// to immediates or registers and are very instruction specific (as flags to
+  /// set in a processor register, coprocessor number, ...).
+  string ParserMethod = ?;
+
+  // The diagnostic type to present when referencing this operand in a
+  // match failure error message. By default, use a generic "invalid operand"
+  // diagnostic. The target AsmParser maps these codes to text.
+  string DiagnosticType = "";
+}
+
+def ImmAsmOperand : AsmOperandClass {
+  let Name = "Imm";
+}
+
+/// Operand Types - These provide the built-in operand types that may be used
+/// by a target.  Targets can optionally provide their own operand types as
+/// needed, though this should not be needed for RISC targets.
+class Operand<ValueType ty> : DAGOperand {
+  ValueType Type = ty;
+  string PrintMethod = "printOperand";
+  string EncoderMethod = "";
+  string DecoderMethod = "";
+  string AsmOperandLowerMethod = ?;
+  string OperandType = "OPERAND_UNKNOWN";
+  dag MIOperandInfo = (ops);
+
+  // MCOperandPredicate - Optionally, a code fragment operating on
+  // const MCOperand &MCOp, and returning a bool, to indicate if
+  // the value of MCOp is valid for the specific subclass of Operand
+  code MCOperandPredicate;
+
+  // ParserMatchClass - The "match class" that operands of this type fit
+  // in. Match classes are used to define the order in which instructions are
+  // match, to ensure that which instructions gets matched is deterministic.
+  //
+  // The target specific parser must be able to classify an parsed operand into
+  // a unique class, which does not partially overlap with any other classes. It
+  // can match a subset of some other class, in which case the AsmOperandClass
+  // should declare the other operand as one of its super classes.
+  AsmOperandClass ParserMatchClass = ImmAsmOperand;
+}
+
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand">
+  : DAGOperand {
+  // RegClass - The register class of the operand.
+  RegisterClass RegClass = regclass;
+  // PrintMethod - The target method to call to print register operands of
+  // this type. The method normally will just use an alt-name index to look
+  // up the name to print. Default to the generic printOperand().
+  string PrintMethod = pm;
+  // ParserMatchClass - The "match class" that operands of this type fit
+  // in. Match classes are used to define the order in which instructions are
+  // match, to ensure that which instructions gets matched is deterministic.
+  //
+  // The target specific parser must be able to classify an parsed operand into
+  // a unique class, which does not partially overlap with any other classes. It
+  // can match a subset of some other class, in which case the AsmOperandClass
+  // should declare the other operand as one of its super classes.
+  AsmOperandClass ParserMatchClass;
+}
+
+let OperandType = "OPERAND_IMMEDIATE" in {
+def i1imm  : Operand<i1>;
+def i8imm  : Operand<i8>;
+def i16imm : Operand<i16>;
+def i32imm : Operand<i32>;
+def i64imm : Operand<i64>;
+
+def f32imm : Operand<f32>;
+def f64imm : Operand<f64>;
+}
+
+/// zero_reg definition - Special node to stand for the zero register.
+///
+def zero_reg;
+
+/// All operands which the MC layer classifies as predicates should inherit from
+/// this class in some manner. This is already handled for the most commonly
+/// used PredicateOperand, but may be useful in other circumstances.
+class PredicateOp;
+
+/// OperandWithDefaultOps - This Operand class can be used as the parent class
+/// for an Operand that needs to be initialized with a default value if
+/// no value is supplied in a pattern.  This class can be used to simplify the
+/// pattern definitions for instructions that have target specific flags
+/// encoded as immediate operands.
+class OperandWithDefaultOps<ValueType ty, dag defaultops>
+  : Operand<ty> {
+  dag DefaultOps = defaultops;
+}
+
+/// PredicateOperand - This can be used to define a predicate operand for an
+/// instruction.  OpTypes specifies the MIOperandInfo for the operand, and
+/// AlwaysVal specifies the value of this predicate when set to "always
+/// execute".
+class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
+  : OperandWithDefaultOps<ty, AlwaysVal>, PredicateOp {
+  let MIOperandInfo = OpTypes;
+}
+
+/// OptionalDefOperand - This is used to define a optional definition operand
+/// for an instruction. DefaultOps is the register the operand represents if
+/// none is supplied, e.g. zero_reg.
+class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
+  : OperandWithDefaultOps<ty, defaultops> {
+  let MIOperandInfo = OpTypes;
+}
+
+
+// InstrInfo - This class should only be instantiated once to provide parameters
+// which are global to the target machine.
+//
+class InstrInfo {
+  // Target can specify its instructions in either big or little-endian formats.
+  // For instance, while both Sparc and PowerPC are big-endian platforms, the
+  // Sparc manual specifies its instructions in the format [31..0] (big), while
+  // PowerPC specifies them using the format [0..31] (little).
+  bit isLittleEndianEncoding = 0;
+
+  // The instruction properties mayLoad, mayStore, and hasSideEffects are unset
+  // by default, and TableGen will infer their value from the instruction
+  // pattern when possible.
+  //
+  // Normally, TableGen will issue an error it it can't infer the value of a
+  // property that hasn't been set explicitly. When guessInstructionProperties
+  // is set, it will guess a safe value instead.
+  //
+  // This option is a temporary migration help. It will go away.
+  bit guessInstructionProperties = 1;
+
+  // TableGen's instruction encoder generator has support for matching operands
+  // to bit-field variables both by name and by position. While matching by
+  // name is preferred, this is currently not possible for complex operands,
+  // and some targets still reply on the positional encoding rules. When
+  // generating a decoder for such targets, the positional encoding rules must
+  // be used by the decoder generator as well.
+  //
+  // This option is temporary; it will go away once the TableGen decoder
+  // generator has better support for complex operands and targets have
+  // migrated away from using positionally encoded operands.
+  bit decodePositionallyEncodedOperands = 0;
+
+  // When set, this indicates that there will be no overlap between those
+  // operands that are matched by ordering (positional operands) and those
+  // matched by name.
+  //
+  // This option is temporary; it will go away once the TableGen decoder
+  // generator has better support for complex operands and targets have
+  // migrated away from using positionally encoded operands.
+  bit noNamedPositionallyEncodedOperands = 0;
+}
+
+// Standard Pseudo Instructions.
+// This list must match TargetOpcodes.h and CodeGenTarget.cpp.
+// Only these instructions are allowed in the TargetOpcode namespace.
+let isCodeGenOnly = 1, isPseudo = 1, Namespace = "TargetOpcode" in {
+def PHI : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "PHINODE";
+}
+def INLINEASM : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "";
+  let neverHasSideEffects = 1;  // Note side effect is encoded in an operand.
+}
+def CFI_INSTRUCTION : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i32imm:$id);
+  let AsmString = "";
+  let hasCtrlDep = 1;
+  let isNotDuplicable = 1;
+}
+def EH_LABEL : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i32imm:$id);
+  let AsmString = "";
+  let hasCtrlDep = 1;
+  let isNotDuplicable = 1;
+}
+def GC_LABEL : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i32imm:$id);
+  let AsmString = "";
+  let hasCtrlDep = 1;
+  let isNotDuplicable = 1;
+}
+def KILL : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+}
+def EXTRACT_SUBREG : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+}
+def INSERT_SUBREG : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+  let Constraints = "$supersrc = $dst";
+}
+def IMPLICIT_DEF : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+  let isReMaterializable = 1;
+  let isAsCheapAsAMove = 1;
+}
+def SUBREG_TO_REG : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+}
+def COPY_TO_REGCLASS : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins unknown:$src, i32imm:$regclass);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+  let isAsCheapAsAMove = 1;
+}
+def DBG_VALUE : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "DBG_VALUE";
+  let neverHasSideEffects = 1;
+}
+def REG_SEQUENCE : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+  let isAsCheapAsAMove = 1;
+}
+def COPY : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins unknown:$src);
+  let AsmString = "";
+  let neverHasSideEffects = 1;
+  let isAsCheapAsAMove = 1;
+}
+def BUNDLE : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins variable_ops);
+  let AsmString = "BUNDLE";
+}
+def LIFETIME_START : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i32imm:$id);
+  let AsmString = "LIFETIME_START";
+  let neverHasSideEffects = 1;
+}
+def LIFETIME_END : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i32imm:$id);
+  let AsmString = "LIFETIME_END";
+  let neverHasSideEffects = 1;
+}
+def STACKMAP : Instruction {
+  let OutOperandList = (outs);
+  let InOperandList = (ins i64imm:$id, i32imm:$nbytes, variable_ops);
+  let isCall = 1;
+  let mayLoad = 1;
+  let usesCustomInserter = 1;
+}
+def PATCHPOINT : Instruction {
+  let OutOperandList = (outs unknown:$dst);
+  let InOperandList = (ins i64imm:$id, i32imm:$nbytes, unknown:$callee,
+                       i32imm:$nargs, i32imm:$cc, variable_ops);
+  let isCall = 1;
+  let mayLoad = 1;
+  let usesCustomInserter = 1;
+}
+}
+
+//===----------------------------------------------------------------------===//
+// AsmParser - This class can be implemented by targets that wish to implement
+// .s file parsing.
+//
+// Subtargets can have multiple different assembly parsers (e.g. AT&T vs Intel
+// syntax on X86 for example).
+//
+class AsmParser {
+  // AsmParserClassName - This specifies the suffix to use for the asmparser
+  // class.  Generated AsmParser classes are always prefixed with the target
+  // name.
+  string AsmParserClassName  = "AsmParser";
+
+  // AsmParserInstCleanup - If non-empty, this is the name of a custom member
+  // function of the AsmParser class to call on every matched instruction.
+  // This can be used to perform target specific instruction post-processing.
+  string AsmParserInstCleanup  = "";
+
+  // ShouldEmitMatchRegisterName - Set to false if the target needs a hand
+  // written register name matcher
+  bit ShouldEmitMatchRegisterName = 1;
+
+  /// Does the instruction mnemonic allow '.'
+  bit MnemonicContainsDot = 0;
+}
+def DefaultAsmParser : AsmParser;
+
+//===----------------------------------------------------------------------===//
+// AsmParserVariant - Subtargets can have multiple different assembly parsers
+// (e.g. AT&T vs Intel syntax on X86 for example). This class can be
+// implemented by targets to describe such variants.
+//
+class AsmParserVariant {
+  // Variant - AsmParsers can be of multiple different variants.  Variants are
+  // used to support targets that need to parser multiple formats for the
+  // assembly language.
+  int Variant = 0;
+
+  // Name - The AsmParser variant name (e.g., AT&T vs Intel).
+  string Name = "";
+
+  // CommentDelimiter - If given, the delimiter string used to recognize
+  // comments which are hard coded in the .td assembler strings for individual
+  // instructions.
+  string CommentDelimiter = "";
+
+  // RegisterPrefix - If given, the token prefix which indicates a register
+  // token. This is used by the matcher to automatically recognize hard coded
+  // register tokens as constrained registers, instead of tokens, for the
+  // purposes of matching.
+  string RegisterPrefix = "";
+}
+def DefaultAsmParserVariant : AsmParserVariant;
+
+/// AssemblerPredicate - This is a Predicate that can be used when the assembler
+/// matches instructions and aliases.
+class AssemblerPredicate<string cond, string name = ""> {
+  bit AssemblerMatcherPredicate = 1;
+  string AssemblerCondString = cond;
+  string PredicateName = name;
+}
+
+/// TokenAlias - This class allows targets to define assembler token
+/// operand aliases. That is, a token literal operand which is equivalent
+/// to another, canonical, token literal. For example, ARM allows:
+///   vmov.u32 s4, #0  -> vmov.i32, #0
+/// 'u32' is a more specific designator for the 32-bit integer type specifier
+/// and is legal for any instruction which accepts 'i32' as a datatype suffix.
+///   def : TokenAlias<".u32", ".i32">;
+///
+/// This works by marking the match class of 'From' as a subclass of the
+/// match class of 'To'.
+class TokenAlias<string From, string To> {
+  string FromToken = From;
+  string ToToken = To;
+}
+
+/// MnemonicAlias - This class allows targets to define assembler mnemonic
+/// aliases.  This should be used when all forms of one mnemonic are accepted
+/// with a different mnemonic.  For example, X86 allows:
+///   sal %al, 1    -> shl %al, 1
+///   sal %ax, %cl  -> shl %ax, %cl
+///   sal %eax, %cl -> shl %eax, %cl
+/// etc.  Though "sal" is accepted with many forms, all of them are directly
+/// translated to a shl, so it can be handled with (in the case of X86, it
+/// actually has one for each suffix as well):
+///   def : MnemonicAlias<"sal", "shl">;
+///
+/// Mnemonic aliases are mapped before any other translation in the match phase,
+/// and do allow Requires predicates, e.g.:
+///
+///  def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
+///  def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
+///
+/// Mnemonic aliases can also be constrained to specific variants, e.g.:
+///
+///  def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
+///
+/// If no variant (e.g., "att" or "intel") is specified then the alias is
+/// applied unconditionally.
+class MnemonicAlias<string From, string To, string VariantName = ""> {
+  string FromMnemonic = From;
+  string ToMnemonic = To;
+  string AsmVariantName = VariantName;
+
+  // Predicates - Predicates that must be true for this remapping to happen.
+  list<Predicate> Predicates = [];
+}
+
+/// InstAlias - This defines an alternate assembly syntax that is allowed to
+/// match an instruction that has a different (more canonical) assembly
+/// representation.
+class InstAlias<string Asm, dag Result, int Emit = 1> {
+  string AsmString = Asm;      // The .s format to match the instruction with.
+  dag ResultInst = Result;     // The MCInst to generate.
+
+  // This determines which order the InstPrinter detects aliases for
+  // printing. A larger value makes the alias more likely to be
+  // emitted. The Instruction's own definition is notionally 0.5, so 0
+  // disables printing and 1 enables it if there are no conflicting aliases.
+  int EmitPriority = Emit;
+
+  // Predicates - Predicates that must be true for this to match.
+  list<Predicate> Predicates = [];
+}
+
+//===----------------------------------------------------------------------===//
+// AsmWriter - This class can be implemented by targets that need to customize
+// the format of the .s file writer.
+//
+// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax
+// on X86 for example).
+//
+class AsmWriter {
+  // AsmWriterClassName - This specifies the suffix to use for the asmwriter
+  // class.  Generated AsmWriter classes are always prefixed with the target
+  // name.
+  string AsmWriterClassName  = "InstPrinter";
+
+  // Variant - AsmWriters can be of multiple different variants.  Variants are
+  // used to support targets that need to emit assembly code in ways that are
+  // mostly the same for different targets, but have minor differences in
+  // syntax.  If the asmstring contains {|} characters in them, this integer
+  // will specify which alternative to use.  For example "{x|y|z}" with Variant
+  // == 1, will expand to "y".
+  int Variant = 0;
+
+  // OperandSpacing - Space between operand columns.
+  int OperandSpacing = -1;
+}
+def DefaultAsmWriter : AsmWriter;
+
+
+//===----------------------------------------------------------------------===//
+// Target - This class contains the "global" target information
+//
+class Target {
+  // InstructionSet - Instruction set description for this target.
+  InstrInfo InstructionSet;
+
+  // AssemblyParsers - The AsmParser instances available for this target.
+  list<AsmParser> AssemblyParsers = [DefaultAsmParser];
+
+  /// AssemblyParserVariants - The AsmParserVariant instances available for
+  /// this target.
+  list<AsmParserVariant> AssemblyParserVariants = [DefaultAsmParserVariant];
+
+  // AssemblyWriters - The AsmWriter instances available for this target.
+  list<AsmWriter> AssemblyWriters = [DefaultAsmWriter];
+}
+
+//===----------------------------------------------------------------------===//
+// SubtargetFeature - A characteristic of the chip set.
+//
+class SubtargetFeature<string n, string a,  string v, string d,
+                       list<SubtargetFeature> i = []> {
+  // Name - Feature name.  Used by command line (-mattr=) to determine the
+  // appropriate target chip.
+  //
+  string Name = n;
+
+  // Attribute - Attribute to be set by feature.
+  //
+  string Attribute = a;
+
+  // Value - Value the attribute to be set to by feature.
+  //
+  string Value = v;
+
+  // Desc - Feature description.  Used by command line (-mattr=) to display help
+  // information.
+  //
+  string Desc = d;
+
+  // Implies - Features that this feature implies are present. If one of those
+  // features isn't set, then this one shouldn't be set either.
+  //
+  list<SubtargetFeature> Implies = i;
+}
+
+/// Specifies a Subtarget feature that this instruction is deprecated on.
+class Deprecated<SubtargetFeature dep> {
+  SubtargetFeature DeprecatedFeatureMask = dep;
+}
+
+/// A custom predicate used to determine if an instruction is
+/// deprecated or not.
+class ComplexDeprecationPredicate<string dep> {
+  string ComplexDeprecationPredicate = dep;
+}
+
+//===----------------------------------------------------------------------===//
+// Processor chip sets - These values represent each of the chip sets supported
+// by the scheduler.  Each Processor definition requires corresponding
+// instruction itineraries.
+//
+class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
+  // Name - Chip set name.  Used by command line (-mcpu=) to determine the
+  // appropriate target chip.
+  //
+  string Name = n;
+
+  // SchedModel - The machine model for scheduling and instruction cost.
+  //
+  SchedMachineModel SchedModel = NoSchedModel;
+
+  // ProcItin - The scheduling information for the target processor.
+  //
+  ProcessorItineraries ProcItin = pi;
+
+  // Features - list of
+  list<SubtargetFeature> Features = f;
+}
+
+// ProcessorModel allows subtargets to specify the more general
+// SchedMachineModel instead if a ProcessorItinerary. Subtargets will
+// gradually move to this newer form.
+//
+// Although this class always passes NoItineraries to the Processor
+// class, the SchedMachineModel may still define valid Itineraries.
+class ProcessorModel<string n, SchedMachineModel m, list<SubtargetFeature> f>
+  : Processor<n, NoItineraries, f> {
+  let SchedModel = m;
+}
+
+//===----------------------------------------------------------------------===//
+// InstrMapping - This class is used to create mapping tables to relate
+// instructions with each other based on the values specified in RowFields,
+// ColFields, KeyCol and ValueCols.
+//
+class InstrMapping {
+  // FilterClass - Used to limit search space only to the instructions that
+  // define the relationship modeled by this InstrMapping record.
+  string FilterClass;
+
+  // RowFields - List of fields/attributes that should be same for all the
+  // instructions in a row of the relation table. Think of this as a set of
+  // properties shared by all the instructions related by this relationship
+  // model and is used to categorize instructions into subgroups. For instance,
+  // if we want to define a relation that maps 'Add' instruction to its
+  // predicated forms, we can define RowFields like this:
+  //
+  // let RowFields = BaseOp
+  // All add instruction predicated/non-predicated will have to set their BaseOp
+  // to the same value.
+  //
+  // def Add: { let BaseOp = 'ADD'; let predSense = 'nopred' }
+  // def Add_predtrue: { let BaseOp = 'ADD'; let predSense = 'true' }
+  // def Add_predfalse: { let BaseOp = 'ADD'; let predSense = 'false'  }
+  list<string> RowFields = [];
+
+  // List of fields/attributes that are same for all the instructions
+  // in a column of the relation table.
+  // Ex: let ColFields = 'predSense' -- It means that the columns are arranged
+  // based on the 'predSense' values. All the instruction in a specific
+  // column have the same value and it is fixed for the column according
+  // to the values set in 'ValueCols'.
+  list<string> ColFields = [];
+
+  // Values for the fields/attributes listed in 'ColFields'.
+  // Ex: let KeyCol = 'nopred' -- It means that the key instruction (instruction
+  // that models this relation) should be non-predicated.
+  // In the example above, 'Add' is the key instruction.
+  list<string> KeyCol = [];
+
+  // List of values for the fields/attributes listed in 'ColFields', one for
+  // each column in the relation table.
+  //
+  // Ex: let ValueCols = [['true'],['false']] -- It adds two columns in the
+  // table. First column requires all the instructions to have predSense
+  // set to 'true' and second column requires it to be 'false'.
+  list<list<string> > ValueCols = [];
+}
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for calling conventions.
+//
+include "llvm/Target/TargetCallingConv.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for DAG isel generation.
+//
+include "llvm/Target/TargetSelectionDAG.td"
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
new file mode 100644
index 0000000..a0f2674
--- /dev/null
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -0,0 +1,185 @@
+//===-- llvm/Target/TargetCallingConv.h - Calling Convention ----*- 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 types for working with calling-convention information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
+#define LLVM_TARGET_TARGETCALLINGCONV_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <string>
+
+namespace llvm {
+
+namespace ISD {
+  struct ArgFlagsTy {
+  private:
+    static const uint64_t NoFlagSet      = 0ULL;
+    static const uint64_t ZExt           = 1ULL<<0;  ///< Zero extended
+    static const uint64_t ZExtOffs       = 0;
+    static const uint64_t SExt           = 1ULL<<1;  ///< Sign extended
+    static const uint64_t SExtOffs       = 1;
+    static const uint64_t InReg          = 1ULL<<2;  ///< Passed in register
+    static const uint64_t InRegOffs      = 2;
+    static const uint64_t SRet           = 1ULL<<3;  ///< Hidden struct-ret ptr
+    static const uint64_t SRetOffs       = 3;
+    static const uint64_t ByVal          = 1ULL<<4;  ///< Struct passed by value
+    static const uint64_t ByValOffs      = 4;
+    static const uint64_t Nest           = 1ULL<<5;  ///< Nested fn static chain
+    static const uint64_t NestOffs       = 5;
+    static const uint64_t Returned       = 1ULL<<6;  ///< Always returned
+    static const uint64_t ReturnedOffs   = 6;
+    static const uint64_t ByValAlign     = 0xFULL<<7; ///< Struct alignment
+    static const uint64_t ByValAlignOffs = 7;
+    static const uint64_t Split          = 1ULL<<11;
+    static const uint64_t SplitOffs      = 11;
+    static const uint64_t InAlloca       = 1ULL<<12; ///< Passed with inalloca
+    static const uint64_t InAllocaOffs   = 12;
+    static const uint64_t OrigAlign      = 0x1FULL<<27;
+    static const uint64_t OrigAlignOffs  = 27;
+    static const uint64_t ByValSize      = 0x3fffffffULL<<32; ///< Struct size
+    static const uint64_t ByValSizeOffs  = 32;
+    static const uint64_t InConsecutiveRegsLast      = 0x1ULL<<62; ///< Struct size
+    static const uint64_t InConsecutiveRegsLastOffs  = 62;
+    static const uint64_t InConsecutiveRegs      = 0x1ULL<<63; ///< Struct size
+    static const uint64_t InConsecutiveRegsOffs  = 63;
+
+    static const uint64_t One            = 1ULL; ///< 1 of this type, for shifts
+
+    uint64_t Flags;
+  public:
+    ArgFlagsTy() : Flags(0) { }
+
+    bool isZExt()      const { return Flags & ZExt; }
+    void setZExt()     { Flags |= One << ZExtOffs; }
+
+    bool isSExt()      const { return Flags & SExt; }
+    void setSExt()     { Flags |= One << SExtOffs; }
+
+    bool isInReg()     const { return Flags & InReg; }
+    void setInReg()    { Flags |= One << InRegOffs; }
+
+    bool isSRet()      const { return Flags & SRet; }
+    void setSRet()     { Flags |= One << SRetOffs; }
+
+    bool isByVal()     const { return Flags & ByVal; }
+    void setByVal()    { Flags |= One << ByValOffs; }
+
+    bool isInAlloca()  const { return Flags & InAlloca; }
+    void setInAlloca() { Flags |= One << InAllocaOffs; }
+
+    bool isNest()      const { return Flags & Nest; }
+    void setNest()     { Flags |= One << NestOffs; }
+
+    bool isReturned()  const { return Flags & Returned; }
+    void setReturned() { Flags |= One << ReturnedOffs; }
+
+    bool isInConsecutiveRegs()  const { return Flags & InConsecutiveRegs; }
+    void setInConsecutiveRegs() { Flags |= One << InConsecutiveRegsOffs; }
+
+    bool isInConsecutiveRegsLast()  const { return Flags & InConsecutiveRegsLast; }
+    void setInConsecutiveRegsLast() { Flags |= One << InConsecutiveRegsLastOffs; }
+
+    unsigned getByValAlign() const {
+      return (unsigned)
+        ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
+    }
+    void setByValAlign(unsigned A) {
+      Flags = (Flags & ~ByValAlign) |
+        (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
+    }
+
+    bool isSplit()   const { return Flags & Split; }
+    void setSplit()  { Flags |= One << SplitOffs; }
+
+    unsigned getOrigAlign() const {
+      return (unsigned)
+        ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
+    }
+    void setOrigAlign(unsigned A) {
+      Flags = (Flags & ~OrigAlign) |
+        (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
+    }
+
+    unsigned getByValSize() const {
+      return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
+    }
+    void setByValSize(unsigned S) {
+      Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
+    }
+
+    /// getRawBits - Represent the flags as a bunch of bits.
+    uint64_t getRawBits() const { return Flags; }
+  };
+
+  /// InputArg - This struct carries flags and type information about a
+  /// single incoming (formal) argument or incoming (from the perspective
+  /// of the caller) return value virtual register.
+  ///
+  struct InputArg {
+    ArgFlagsTy Flags;
+    MVT VT;
+    EVT ArgVT;
+    bool Used;
+
+    /// Index original Function's argument.
+    unsigned OrigArgIndex;
+
+    /// Offset in bytes of current input value relative to the beginning of
+    /// original argument. E.g. if argument was splitted into four 32 bit
+    /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
+    unsigned PartOffset;
+
+    InputArg() : VT(MVT::Other), Used(false) {}
+    InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
+             unsigned origIdx, unsigned partOffs)
+      : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
+      VT = vt.getSimpleVT();
+      ArgVT = argvt;
+    }
+  };
+
+  /// OutputArg - This struct carries flags and a value for a
+  /// single outgoing (actual) argument or outgoing (from the perspective
+  /// of the caller) return value virtual register.
+  ///
+  struct OutputArg {
+    ArgFlagsTy Flags;
+    MVT VT;
+    EVT ArgVT;
+
+    /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
+    bool IsFixed;
+
+    /// Index original Function's argument.
+    unsigned OrigArgIndex;
+
+    /// Offset in bytes of current output value relative to the beginning of
+    /// original argument. E.g. if argument was splitted into four 32 bit
+    /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
+    unsigned PartOffset;
+
+    OutputArg() : IsFixed(false) {}
+    OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
+              unsigned origIdx, unsigned partOffs)
+      : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
+        PartOffset(partOffs) {
+      VT = vt.getSimpleVT();
+      ArgVT = argvt;
+    }
+  };
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
new file mode 100644
index 0000000..2e766c4
--- /dev/null
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -0,0 +1,177 @@
+//===- TargetCallingConv.td - Target Calling Conventions ---*- tablegen -*-===//
+// 
+//                     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 target-independent interfaces with which targets
+// describe their calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+class CCAction;
+class CallingConv;
+
+/// CCCustom - Calls a custom arg handling function.
+class CCCustom<string fn> : CCAction {
+  string FuncName = fn;
+}
+
+/// CCPredicateAction - Instances of this class check some predicate, then
+/// delegate to another action if the predicate is true.
+class CCPredicateAction<CCAction A> : CCAction {
+  CCAction SubAction = A;
+}
+
+/// CCIfType - If the current argument is one of the specified types, apply
+/// Action A.
+class CCIfType<list<ValueType> vts, CCAction A> : CCPredicateAction<A> {
+  list<ValueType> VTs = vts;
+}
+
+/// CCIf - If the predicate matches, apply A.
+class CCIf<string predicate, CCAction A> : CCPredicateAction<A> {
+  string Predicate = predicate;
+}
+
+/// CCIfByVal - If the current argument has ByVal parameter attribute, apply
+/// Action A.
+class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> {
+}
+
+/// CCIfConsecutiveRegs - If the current argument has InConsecutiveRegs
+/// parameter attribute, apply Action A.
+class CCIfConsecutiveRegs<CCAction A> : CCIf<"ArgFlags.isInConsecutiveRegs()", A> {
+}
+
+/// CCIfCC - Match if the current calling convention is 'CC'.
+class CCIfCC<string CC, CCAction A>
+  : CCIf<!strconcat("State.getCallingConv() == ", CC), A> {}
+
+/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply
+/// the specified action.
+class CCIfInReg<CCAction A> : CCIf<"ArgFlags.isInReg()", A> {}
+
+/// CCIfNest - If this argument is marked with the 'nest' attribute, apply
+/// the specified action.
+class CCIfNest<CCAction A> : CCIf<"ArgFlags.isNest()", A> {}
+
+/// CCIfSplit - If this argument is marked with the 'split' attribute, apply
+/// the specified action.
+class CCIfSplit<CCAction A> : CCIf<"ArgFlags.isSplit()", A> {}
+
+/// CCIfSRet - If this argument is marked with the 'sret' attribute, apply
+/// the specified action.
+class CCIfSRet<CCAction A> : CCIf<"ArgFlags.isSRet()", A> {}
+
+/// CCIfVarArg - If the current function is vararg - apply the action
+class CCIfVarArg<CCAction A> : CCIf<"State.isVarArg()", A> {}
+
+/// CCIfNotVarArg - If the current function is not vararg - apply the action
+class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
+
+/// CCAssignToReg - This action matches if there is a register in the specified
+/// list that is still available.  If so, it assigns the value to the first
+/// available register and succeeds.
+class CCAssignToReg<list<Register> regList> : CCAction {
+  list<Register> RegList = regList;
+}
+
+/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers
+/// which became shadowed, when some register is used.
+class CCAssignToRegWithShadow<list<Register> regList,
+                              list<Register> shadowList> : CCAction {
+  list<Register> RegList = regList;
+  list<Register> ShadowRegList = shadowList;
+}
+
+/// CCAssignToStack - This action always matches: it assigns the value to a
+/// stack slot of the specified size and alignment on the stack.  If size is
+/// zero then the ABI size is used; if align is zero then the ABI alignment
+/// is used - these may depend on the target or subtarget.
+class CCAssignToStack<int size, int align> : CCAction {
+  int Size = size;
+  int Align = align;
+}
+
+/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of
+/// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this
+/// shadows ALL of the registers in shadowList.
+class CCAssignToStackWithShadow<int size,
+                                int align,
+                                list<Register> shadowList> : CCAction {
+  int Size = size;
+  int Align = align;
+  list<Register> ShadowRegList = shadowList;
+}
+
+/// CCPassByVal - This action always matches: it assigns the value to a stack
+/// slot to implement ByVal aggregate parameter passing. Size and alignment
+/// specify the minimum size and alignment for the stack slot.
+class CCPassByVal<int size, int align> : CCAction {
+  int Size = size;
+  int Align = align;
+}
+
+/// CCPromoteToType - If applied, this promotes the specified current value to
+/// the specified type.
+class CCPromoteToType<ValueType destTy> : CCAction {
+  ValueType DestTy = destTy;
+}
+
+/// CCPromoteToUpperBitsInType - If applied, this promotes the specified current
+/// value to the specified type and shifts the value into the upper bits.
+class CCPromoteToUpperBitsInType<ValueType destTy> : CCAction {
+  ValueType DestTy = destTy;
+}
+
+/// CCBitConvertToType - If applied, this bitconverts the specified current
+/// value to the specified type.
+class CCBitConvertToType<ValueType destTy> : CCAction {
+  ValueType DestTy = destTy;
+}
+
+/// CCPassIndirect - If applied, this stores the value to stack and passes the pointer
+/// as normal argument.
+class CCPassIndirect<ValueType destTy> : CCAction {
+  ValueType DestTy = destTy;
+}
+
+/// CCDelegateTo - This action invokes the specified sub-calling-convention.  It
+/// is successful if the specified CC matches.
+class CCDelegateTo<CallingConv cc> : CCAction {
+  CallingConv CC = cc;
+}
+
+/// CallingConv - An instance of this is used to define each calling convention
+/// that the target supports.
+class CallingConv<list<CCAction> actions> {
+  list<CCAction> Actions = actions;
+  bit Custom = 0;
+}
+
+/// CustomCallingConv - An instance of this is used to declare calling
+/// conventions that are implemented using a custom function of the same name.
+class CustomCallingConv : CallingConv<[]> {
+  let Custom = 1;
+}
+
+/// CalleeSavedRegs - A list of callee saved registers for a given calling
+/// convention.  The order of registers is used by PrologEpilogInsertion when
+/// allocation stack slots for saved registers.
+///
+/// For each CalleeSavedRegs def, TableGen will emit a FOO_SaveList array for
+/// returning from getCalleeSavedRegs(), and a FOO_RegMask bit mask suitable for
+/// returning from getCallPreservedMask().
+class CalleeSavedRegs<dag saves> {
+  dag SaveList = saves;
+
+  // Registers that are also preserved across function calls, but should not be
+  // included in the generated FOO_SaveList array. These registers will be
+  // included in the FOO_RegMask bit mask. This can be used for registers that
+  // are saved automatically, like the SPARC register windows.
+  dag OtherPreserved;
+}
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
new file mode 100644
index 0000000..bfddd06
--- /dev/null
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -0,0 +1,237 @@
+//===-- llvm/Target/TargetFrameLowering.h ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to describe the layout of a stack frame on the target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
+#define LLVM_TARGET_TARGETFRAMELOWERING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include <utility>
+#include <vector>
+
+namespace llvm {
+  class CalleeSavedInfo;
+  class MachineFunction;
+  class RegScavenger;
+
+/// Information about stack frame layout on the target.  It holds the direction
+/// of stack growth, the known stack alignment on entry to each function, and
+/// the offset to the locals area.
+///
+/// The offset to the local area is the offset from the stack pointer on
+/// function entry to the first location where function data (local variables,
+/// spill locations) can be stored.
+class TargetFrameLowering {
+public:
+  enum StackDirection {
+    StackGrowsUp,        // Adding to the stack increases the stack address
+    StackGrowsDown       // Adding to the stack decreases the stack address
+  };
+
+  // Maps a callee saved register to a stack slot with a fixed offset.
+  struct SpillSlot {
+    unsigned Reg;
+    int Offset; // Offset relative to stack pointer on function entry.
+  };
+private:
+  StackDirection StackDir;
+  unsigned StackAlignment;
+  unsigned TransientStackAlignment;
+  int LocalAreaOffset;
+  bool StackRealignable;
+public:
+  TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
+                      unsigned TransAl = 1, bool StackReal = true)
+    : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
+      LocalAreaOffset(LAO), StackRealignable(StackReal) {}
+
+  virtual ~TargetFrameLowering();
+
+  // These methods return information that describes the abstract stack layout
+  // of the target machine.
+
+  /// getStackGrowthDirection - Return the direction the stack grows
+  ///
+  StackDirection getStackGrowthDirection() const { return StackDir; }
+
+  /// getStackAlignment - This method returns the number of bytes to which the
+  /// stack pointer must be aligned on entry to a function.  Typically, this
+  /// is the largest alignment for any data object in the target.
+  ///
+  unsigned getStackAlignment() const { return StackAlignment; }
+
+  /// getTransientStackAlignment - This method returns the number of bytes to
+  /// which the stack pointer must be aligned at all times, even between
+  /// calls.
+  ///
+  unsigned getTransientStackAlignment() const {
+    return TransientStackAlignment;
+  }
+
+  /// isStackRealignable - This method returns whether the stack can be
+  /// realigned.
+  bool isStackRealignable() const {
+    return StackRealignable;
+  }
+
+  /// getOffsetOfLocalArea - This method returns the offset of the local area
+  /// from the stack pointer on entrance to a function.
+  ///
+  int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+
+  /// isFPCloseToIncomingSP - Return true if the frame pointer is close to
+  /// the incoming stack pointer, false if it is close to the post-prologue
+  /// stack pointer.
+  virtual bool isFPCloseToIncomingSP() const { return true; }
+
+  /// assignCalleeSavedSpillSlots - Allows target to override spill slot
+  /// assignment logic.  If implemented, assignCalleeSavedSpillSlots() should
+  /// assign frame slots to all CSI entries and return true.  If this method
+  /// returns false, spill slots will be assigned using generic implementation.
+  /// assignCalleeSavedSpillSlots() may add, delete or rearrange elements of
+  /// CSI.
+  virtual bool
+  assignCalleeSavedSpillSlots(MachineFunction &MF,
+                              const TargetRegisterInfo *TRI,
+                              std::vector<CalleeSavedInfo> &CSI) const {
+    return false;
+  }
+
+  /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
+  /// pairs, that contains an entry for each callee saved register that must be
+  /// spilled to a particular stack location if it is spilled.
+  ///
+  /// Each entry in this array contains a <register,offset> pair, indicating the
+  /// fixed offset from the incoming stack pointer that each register should be
+  /// spilled at. If a register is not listed here, the code generator is
+  /// allowed to spill it anywhere it chooses.
+  ///
+  virtual const SpillSlot *
+  getCalleeSavedSpillSlots(unsigned &NumEntries) const {
+    NumEntries = 0;
+    return nullptr;
+  }
+
+  /// targetHandlesStackFrameRounding - Returns true if the target is
+  /// responsible for rounding up the stack frame (probably at emitPrologue
+  /// time).
+  virtual bool targetHandlesStackFrameRounding() const {
+    return false;
+  }
+
+  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+  /// the function.
+  virtual void emitPrologue(MachineFunction &MF) const = 0;
+  virtual void emitEpilogue(MachineFunction &MF,
+                            MachineBasicBlock &MBB) const = 0;
+
+  /// Adjust the prologue to have the function use segmented stacks. This works
+  /// by adding a check even before the "normal" function prologue.
+  virtual void adjustForSegmentedStacks(MachineFunction &MF) const { }
+
+  /// Adjust the prologue to add Erlang Run-Time System (ERTS) specific code in
+  /// the assembly prologue to explicitly handle the stack.
+  virtual void adjustForHiPEPrologue(MachineFunction &MF) const { }
+
+  /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
+  /// saved registers and returns true if it isn't possible / profitable to do
+  /// so by issuing a series of store instructions via
+  /// storeRegToStackSlot(). Returns false otherwise.
+  virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                         MachineBasicBlock::iterator MI,
+                                        const std::vector<CalleeSavedInfo> &CSI,
+                                         const TargetRegisterInfo *TRI) const {
+    return false;
+  }
+
+  /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+  /// saved registers and returns true if it isn't possible / profitable to do
+  /// so by issuing a series of load instructions via loadRegToStackSlot().
+  /// Returns false otherwise.
+  virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                           MachineBasicBlock::iterator MI,
+                                        const std::vector<CalleeSavedInfo> &CSI,
+                                        const TargetRegisterInfo *TRI) const {
+    return false;
+  }
+
+  /// hasFP - Return true if the specified function should have a dedicated
+  /// frame pointer register. For most targets this is true only if the function
+  /// has variable sized allocas or if frame pointer elimination is disabled.
+  virtual bool hasFP(const MachineFunction &MF) const = 0;
+
+  /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+  /// not required, we reserve argument space for call sites in the function
+  /// immediately on entry to the current function. This eliminates the need for
+  /// add/sub sp brackets around call sites. Returns true if the call frame is
+  /// included as part of the stack frame.
+  virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
+    return !hasFP(MF);
+  }
+
+  /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
+  /// call frame pseudo ops before doing frame index elimination. This is
+  /// possible only when frame index references between the pseudos won't
+  /// need adjusting for the call frame adjustments. Normally, that's true
+  /// if the function has a reserved call frame or a frame pointer. Some
+  /// targets (Thumb2, for example) may have more complicated criteria,
+  /// however, and can override this behavior.
+  virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
+    return hasReservedCallFrame(MF) || hasFP(MF);
+  }
+
+  /// getFrameIndexOffset - Returns the displacement from the frame register to
+  /// the stack frame of the specified index.
+  virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
+
+  /// getFrameIndexReference - This method should return the base register
+  /// and offset used to reference a frame index location. The offset is
+  /// returned directly, and the base register is returned via FrameReg.
+  virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
+                                     unsigned &FrameReg) const;
+
+  /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+  /// before PrologEpilogInserter scans the physical registers used to determine
+  /// what callee saved registers should be spilled. This method is optional.
+  virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+                                             RegScavenger *RS = nullptr) const {
+
+  }
+
+  /// processFunctionBeforeFrameFinalized - This method is called immediately
+  /// before the specified function's frame layout (MF.getFrameInfo()) is
+  /// finalized.  Once the frame is finalized, MO_FrameIndex operands are
+  /// replaced with direct constants.  This method is optional.
+  ///
+  virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF,
+                                             RegScavenger *RS = nullptr) const {
+  }
+
+  /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
+  /// code insertion to eliminate call frame setup and destroy pseudo
+  /// instructions (but only if the Target is using them).  It is responsible
+  /// for eliminating these instructions, replacing them with concrete
+  /// instructions.  This method need only be implemented if using call frame
+  /// setup/destroy pseudo instructions.
+  ///
+  virtual void
+  eliminateCallFramePseudoInstr(MachineFunction &MF,
+                                MachineBasicBlock &MBB,
+                                MachineBasicBlock::iterator MI) const {
+    llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
+                     "target!");
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
new file mode 100644
index 0000000..87e7c14
--- /dev/null
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -0,0 +1,1031 @@
+//===-- llvm/Target/TargetInstrInfo.h - Instruction 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 describes the target machine instruction set to the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINSTRINFO_H
+#define LLVM_TARGET_TARGETINSTRINFO_H
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/MC/MCInstrInfo.h"
+
+namespace llvm {
+
+class InstrItineraryData;
+class LiveVariables;
+class MCAsmInfo;
+class MachineMemOperand;
+class MachineRegisterInfo;
+class MDNode;
+class MCInst;
+class MCSchedModel;
+class MCSymbolRefExpr;
+class SDNode;
+class ScheduleHazardRecognizer;
+class SelectionDAG;
+class ScheduleDAG;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class BranchProbability;
+class TargetSubtargetInfo;
+
+template<class T> class SmallVectorImpl;
+
+
+//---------------------------------------------------------------------------
+///
+/// TargetInstrInfo - Interface to description of machine instruction set
+///
+class TargetInstrInfo : public MCInstrInfo {
+  TargetInstrInfo(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetInstrInfo &) LLVM_DELETED_FUNCTION;
+public:
+  TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1)
+    : CallFrameSetupOpcode(CFSetupOpcode),
+      CallFrameDestroyOpcode(CFDestroyOpcode) {
+  }
+
+  virtual ~TargetInstrInfo();
+
+  /// getRegClass - Givem a machine instruction descriptor, returns the register
+  /// class constraint for OpNum, or NULL.
+  const TargetRegisterClass *getRegClass(const MCInstrDesc &TID,
+                                         unsigned OpNum,
+                                         const TargetRegisterInfo *TRI,
+                                         const MachineFunction &MF) const;
+
+  /// isTriviallyReMaterializable - Return true if the instruction is trivially
+  /// rematerializable, meaning it has no side effects and requires no operands
+  /// that aren't always available.
+  bool isTriviallyReMaterializable(const MachineInstr *MI,
+                                   AliasAnalysis *AA = nullptr) const {
+    return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
+           (MI->getDesc().isRematerializable() &&
+            (isReallyTriviallyReMaterializable(MI, AA) ||
+             isReallyTriviallyReMaterializableGeneric(MI, AA)));
+  }
+
+protected:
+  /// isReallyTriviallyReMaterializable - For instructions with opcodes for
+  /// which the M_REMATERIALIZABLE flag is set, this hook lets the target
+  /// specify whether the instruction is actually trivially rematerializable,
+  /// taking into consideration its operands. This predicate must return false
+  /// if the instruction has any side effects other than producing a value, or
+  /// if it requres any address registers that are not always available.
+  virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
+                                                 AliasAnalysis *AA) const {
+    return false;
+  }
+
+private:
+  /// isReallyTriviallyReMaterializableGeneric - For instructions with opcodes
+  /// for which the M_REMATERIALIZABLE flag is set and the target hook
+  /// isReallyTriviallyReMaterializable returns false, this function does
+  /// target-independent tests to determine if the instruction is really
+  /// trivially rematerializable.
+  bool isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
+                                                AliasAnalysis *AA) const;
+
+public:
+  /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
+  /// frame setup/destroy instructions if they exist (-1 otherwise).  Some
+  /// targets use pseudo instructions in order to abstract away the difference
+  /// between operating with a frame pointer and operating without, through the
+  /// use of these two instructions.
+  ///
+  int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
+  int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+
+  /// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
+  /// extension instruction. That is, it's like a copy where it's legal for the
+  /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
+  /// true, then it's expected the pre-extension value is available as a subreg
+  /// of the result register. This also returns the sub-register index in
+  /// SubIdx.
+  virtual bool isCoalescableExtInstr(const MachineInstr &MI,
+                                     unsigned &SrcReg, unsigned &DstReg,
+                                     unsigned &SubIdx) const {
+    return false;
+  }
+
+  /// isLoadFromStackSlot - If the specified machine instruction is a direct
+  /// load from a stack slot, return the virtual or physical register number of
+  /// the destination along with the FrameIndex of the loaded stack slot.  If
+  /// not, return 0.  This predicate must return 0 if the instruction has
+  /// any side effects other than loading from the stack slot.
+  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
+                                       int &FrameIndex) const {
+    return 0;
+  }
+
+  /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
+  /// stack locations as well.  This uses a heuristic so it isn't
+  /// reliable for correctness.
+  virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
+                                             int &FrameIndex) const {
+    return 0;
+  }
+
+  /// hasLoadFromStackSlot - If the specified machine instruction has
+  /// a load from a stack slot, return true along with the FrameIndex
+  /// of the loaded stack slot and the machine mem operand containing
+  /// the reference.  If not, return false.  Unlike
+  /// isLoadFromStackSlot, this returns true for any instructions that
+  /// loads from the stack.  This is just a hint, as some cases may be
+  /// missed.
+  virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
+                                    const MachineMemOperand *&MMO,
+                                    int &FrameIndex) const;
+
+  /// isStoreToStackSlot - If the specified machine instruction is a direct
+  /// store to a stack slot, return the virtual or physical register number of
+  /// the source reg along with the FrameIndex of the loaded stack slot.  If
+  /// not, return 0.  This predicate must return 0 if the instruction has
+  /// any side effects other than storing to the stack slot.
+  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
+                                      int &FrameIndex) const {
+    return 0;
+  }
+
+  /// isStoreToStackSlotPostFE - Check for post-frame ptr elimination
+  /// stack locations as well.  This uses a heuristic so it isn't
+  /// reliable for correctness.
+  virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI,
+                                            int &FrameIndex) const {
+    return 0;
+  }
+
+  /// hasStoreToStackSlot - If the specified machine instruction has a
+  /// store to a stack slot, return true along with the FrameIndex of
+  /// the loaded stack slot and the machine mem operand containing the
+  /// reference.  If not, return false.  Unlike isStoreToStackSlot,
+  /// this returns true for any instructions that stores to the
+  /// stack.  This is just a hint, as some cases may be missed.
+  virtual bool hasStoreToStackSlot(const MachineInstr *MI,
+                                   const MachineMemOperand *&MMO,
+                                   int &FrameIndex) const;
+
+  /// isStackSlotCopy - Return true if the specified machine instruction
+  /// is a copy of one stack slot to another and has no other effect.
+  /// Provide the identity of the two frame indices.
+  virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
+                               int &SrcFrameIndex) const {
+    return false;
+  }
+
+  /// Compute the size in bytes and offset within a stack slot of a spilled
+  /// register or subregister.
+  ///
+  /// \param [out] Size in bytes of the spilled value.
+  /// \param [out] Offset in bytes within the stack slot.
+  /// \returns true if both Size and Offset are successfully computed.
+  ///
+  /// Not all subregisters have computable spill slots. For example,
+  /// subregisters registers may not be byte-sized, and a pair of discontiguous
+  /// subregisters has no single offset.
+  ///
+  /// Targets with nontrivial bigendian implementations may need to override
+  /// this, particularly to support spilled vector registers.
+  virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
+                                 unsigned &Size, unsigned &Offset,
+                                 const TargetMachine *TM) const;
+
+  /// reMaterialize - Re-issue the specified 'original' instruction at the
+  /// specific location targeting a new destination register.
+  /// The register in Orig->getOperand(0).getReg() will be substituted by
+  /// DestReg:SubIdx. Any existing subreg index is preserved or composed with
+  /// SubIdx.
+  virtual void reMaterialize(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator MI,
+                             unsigned DestReg, unsigned SubIdx,
+                             const MachineInstr *Orig,
+                             const TargetRegisterInfo &TRI) const;
+
+  /// duplicate - Create a duplicate of the Orig instruction in MF. This is like
+  /// MachineFunction::CloneMachineInstr(), but the target may update operands
+  /// that are required to be unique.
+  ///
+  /// The instruction must be duplicable as indicated by isNotDuplicable().
+  virtual MachineInstr *duplicate(MachineInstr *Orig,
+                                  MachineFunction &MF) const;
+
+  /// convertToThreeAddress - This method must be implemented by targets that
+  /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target
+  /// may be able to convert a two-address instruction into one or more true
+  /// three-address instructions on demand.  This allows the X86 target (for
+  /// example) to convert ADD and SHL instructions into LEA instructions if they
+  /// would require register copies due to two-addressness.
+  ///
+  /// This method returns a null pointer if the transformation cannot be
+  /// performed, otherwise it returns the last new instruction.
+  ///
+  virtual MachineInstr *
+  convertToThreeAddress(MachineFunction::iterator &MFI,
+                   MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const {
+    return nullptr;
+  }
+
+  /// commuteInstruction - If a target has any instructions that are
+  /// commutable but require converting to different instructions or making
+  /// non-trivial changes to commute them, this method can overloaded to do
+  /// that.  The default implementation simply swaps the commutable operands.
+  /// If NewMI is false, MI is modified in place and returned; otherwise, a
+  /// new machine instruction is created and returned.  Do not call this
+  /// method for a non-commutable instruction, but there may be some cases
+  /// where this method fails and returns null.
+  virtual MachineInstr *commuteInstruction(MachineInstr *MI,
+                                           bool NewMI = false) const;
+
+  /// findCommutedOpIndices - If specified MI is commutable, return the two
+  /// operand indices that would swap value. Return false if the instruction
+  /// is not in a form which this routine understands.
+  virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+                                     unsigned &SrcOpIdx2) const;
+
+  /// produceSameValue - Return true if two machine instructions would produce
+  /// identical values. By default, this is only true when the two instructions
+  /// are deemed identical except for defs. If this function is called when the
+  /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for
+  /// aggressive checks.
+  virtual bool produceSameValue(const MachineInstr *MI0,
+                                const MachineInstr *MI1,
+                                const MachineRegisterInfo *MRI = nullptr) const;
+
+  /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
+  /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
+  /// implemented for a target).  Upon success, this returns false and returns
+  /// with the following information in various cases:
+  ///
+  /// 1. If this block ends with no branches (it just falls through to its succ)
+  ///    just return false, leaving TBB/FBB null.
+  /// 2. If this block ends with only an unconditional branch, it sets TBB to be
+  ///    the destination block.
+  /// 3. If this block ends with a conditional branch and it falls through to a
+  ///    successor block, it sets TBB to be the branch destination block and a
+  ///    list of operands that evaluate the condition. These operands can be
+  ///    passed to other TargetInstrInfo methods to create new branches.
+  /// 4. If this block ends with a conditional branch followed by an
+  ///    unconditional branch, it returns the 'true' destination in TBB, the
+  ///    'false' destination in FBB, and a list of operands that evaluate the
+  ///    condition.  These operands can be passed to other TargetInstrInfo
+  ///    methods to create new branches.
+  ///
+  /// Note that RemoveBranch and InsertBranch must be implemented to support
+  /// cases where this method returns success.
+  ///
+  /// If AllowModify is true, then this routine is allowed to modify the basic
+  /// block (e.g. delete instructions after the unconditional branch).
+  ///
+  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
+                             MachineBasicBlock *&FBB,
+                             SmallVectorImpl<MachineOperand> &Cond,
+                             bool AllowModify = false) const {
+    return true;
+  }
+
+  /// RemoveBranch - Remove the branching code at the end of the specific MBB.
+  /// This is only invoked in cases where AnalyzeBranch returns success. It
+  /// returns the number of instructions that were removed.
+  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!");
+  }
+
+  /// InsertBranch - Insert branch code into the end of the specified
+  /// MachineBasicBlock.  The operands to this method are the same as those
+  /// returned by AnalyzeBranch.  This is only invoked in cases where
+  /// AnalyzeBranch returns success. It returns the number of instructions
+  /// inserted.
+  ///
+  /// It is also invoked by tail merging to add unconditional branches in
+  /// cases where AnalyzeBranch doesn't apply because there was no original
+  /// branch to analyze.  At least this much must be implemented, else tail
+  /// merging needs to be disabled.
+  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+                                MachineBasicBlock *FBB,
+                                const SmallVectorImpl<MachineOperand> &Cond,
+                                DebugLoc DL) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!");
+  }
+
+  /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
+  /// after it, replacing it with an unconditional branch to NewDest. This is
+  /// used by the tail merging pass.
+  virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
+                                       MachineBasicBlock *NewDest) const;
+
+  /// getUnconditionalBranch - Get an instruction that performs an unconditional
+  /// branch to the given symbol.
+  virtual void
+  getUnconditionalBranch(MCInst &MI,
+                         const MCSymbolRefExpr *BranchTarget) const {
+    llvm_unreachable("Target didn't implement "
+                     "TargetInstrInfo::getUnconditionalBranch!");
+  }
+
+  /// getTrap - Get a machine trap instruction
+  virtual void getTrap(MCInst &MI) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::getTrap!");
+  }
+
+  /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
+  /// block at the specified instruction (i.e. instruction would be the start
+  /// of a new basic block).
+  virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator MBBI) const {
+    return true;
+  }
+
+  /// isProfitableToIfCvt - Return true if it's profitable to predicate
+  /// instructions with accumulated instruction latency of "NumCycles"
+  /// of the specified basic block, where the probability of the instructions
+  /// being executed is given by Probability, and Confidence is a measure
+  /// of our confidence that it will be properly predicted.
+  virtual
+  bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
+                           unsigned ExtraPredCycles,
+                           const BranchProbability &Probability) const {
+    return false;
+  }
+
+  /// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
+  /// checks for the case where two basic blocks from true and false path
+  /// of a if-then-else (diamond) are predicated on mutally exclusive
+  /// predicates, where the probability of the true path being taken is given
+  /// by Probability, and Confidence is a measure of our confidence that it
+  /// will be properly predicted.
+  virtual bool
+  isProfitableToIfCvt(MachineBasicBlock &TMBB,
+                      unsigned NumTCycles, unsigned ExtraTCycles,
+                      MachineBasicBlock &FMBB,
+                      unsigned NumFCycles, unsigned ExtraFCycles,
+                      const BranchProbability &Probability) const {
+    return false;
+  }
+
+  /// isProfitableToDupForIfCvt - Return true if it's profitable for
+  /// if-converter to duplicate instructions of specified accumulated
+  /// instruction latencies in the specified MBB to enable if-conversion.
+  /// The probability of the instructions being executed is given by
+  /// Probability, and Confidence is a measure of our confidence that it
+  /// will be properly predicted.
+  virtual bool
+  isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
+                            const BranchProbability &Probability) const {
+    return false;
+  }
+
+  /// isProfitableToUnpredicate - Return true if it's profitable to unpredicate
+  /// one side of a 'diamond', i.e. two sides of if-else predicated on mutually
+  /// exclusive predicates.
+  /// e.g.
+  ///   subeq  r0, r1, #1
+  ///   addne  r0, r1, #1
+  /// =>
+  ///   sub    r0, r1, #1
+  ///   addne  r0, r1, #1
+  ///
+  /// This may be profitable is conditional instructions are always executed.
+  virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
+                                         MachineBasicBlock &FMBB) const {
+    return false;
+  }
+
+  /// canInsertSelect - Return true if it is possible to insert a select
+  /// instruction that chooses between TrueReg and FalseReg based on the
+  /// condition code in Cond.
+  ///
+  /// When successful, also return the latency in cycles from TrueReg,
+  /// FalseReg, and Cond to the destination register. In most cases, a select
+  /// instruction will be 1 cycle, so CondCycles = TrueCycles = FalseCycles = 1
+  ///
+  /// Some x86 implementations have 2-cycle cmov instructions.
+  ///
+  /// @param MBB         Block where select instruction would be inserted.
+  /// @param Cond        Condition returned by AnalyzeBranch.
+  /// @param TrueReg     Virtual register to select when Cond is true.
+  /// @param FalseReg    Virtual register to select when Cond is false.
+  /// @param CondCycles  Latency from Cond+Branch to select output.
+  /// @param TrueCycles  Latency from TrueReg to select output.
+  /// @param FalseCycles Latency from FalseReg to select output.
+  virtual bool canInsertSelect(const MachineBasicBlock &MBB,
+                               const SmallVectorImpl<MachineOperand> &Cond,
+                               unsigned TrueReg, unsigned FalseReg,
+                               int &CondCycles,
+                               int &TrueCycles, int &FalseCycles) const {
+    return false;
+  }
+
+  /// insertSelect - Insert a select instruction into MBB before I that will
+  /// copy TrueReg to DstReg when Cond is true, and FalseReg to DstReg when
+  /// Cond is false.
+  ///
+  /// This function can only be called after canInsertSelect() returned true.
+  /// The condition in Cond comes from AnalyzeBranch, and it can be assumed
+  /// that the same flags or registers required by Cond are available at the
+  /// insertion point.
+  ///
+  /// @param MBB      Block where select instruction should be inserted.
+  /// @param I        Insertion point.
+  /// @param DL       Source location for debugging.
+  /// @param DstReg   Virtual register to be defined by select instruction.
+  /// @param Cond     Condition as computed by AnalyzeBranch.
+  /// @param TrueReg  Virtual register to copy when Cond is true.
+  /// @param FalseReg Virtual register to copy when Cons is false.
+  virtual void insertSelect(MachineBasicBlock &MBB,
+                            MachineBasicBlock::iterator I, DebugLoc DL,
+                            unsigned DstReg,
+                            const SmallVectorImpl<MachineOperand> &Cond,
+                            unsigned TrueReg, unsigned FalseReg) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
+  }
+
+  /// analyzeSelect - Analyze the given select instruction, returning true if
+  /// it cannot be understood. It is assumed that MI->isSelect() is true.
+  ///
+  /// When successful, return the controlling condition and the operands that
+  /// determine the true and false result values.
+  ///
+  ///   Result = SELECT Cond, TrueOp, FalseOp
+  ///
+  /// Some targets can optimize select instructions, for example by predicating
+  /// the instruction defining one of the operands. Such targets should set
+  /// Optimizable.
+  ///
+  /// @param         MI Select instruction to analyze.
+  /// @param Cond    Condition controlling the select.
+  /// @param TrueOp  Operand number of the value selected when Cond is true.
+  /// @param FalseOp Operand number of the value selected when Cond is false.
+  /// @param Optimizable Returned as true if MI is optimizable.
+  /// @returns False on success.
+  virtual bool analyzeSelect(const MachineInstr *MI,
+                             SmallVectorImpl<MachineOperand> &Cond,
+                             unsigned &TrueOp, unsigned &FalseOp,
+                             bool &Optimizable) const {
+    assert(MI && MI->getDesc().isSelect() && "MI must be a select instruction");
+    return true;
+  }
+
+  /// optimizeSelect - Given a select instruction that was understood by
+  /// analyzeSelect and returned Optimizable = true, attempt to optimize MI by
+  /// merging it with one of its operands. Returns NULL on failure.
+  ///
+  /// When successful, returns the new select instruction. The client is
+  /// responsible for deleting MI.
+  ///
+  /// If both sides of the select can be optimized, PreferFalse is used to pick
+  /// a side.
+  ///
+  /// @param MI          Optimizable select instruction.
+  /// @param PreferFalse Try to optimize FalseOp instead of TrueOp.
+  /// @returns Optimized instruction or NULL.
+  virtual MachineInstr *optimizeSelect(MachineInstr *MI,
+                                       bool PreferFalse = false) const {
+    // This function must be implemented if Optimizable is ever set.
+    llvm_unreachable("Target must implement TargetInstrInfo::optimizeSelect!");
+  }
+
+  /// copyPhysReg - Emit instructions to copy a pair of physical registers.
+  ///
+  /// This function should support copies within any legal register class as
+  /// well as any cross-class copies created during instruction selection.
+  ///
+  /// The source and destination registers may overlap, which may require a
+  /// careful implementation when multiple copy instructions are required for
+  /// large registers. See for example the ARM target.
+  virtual void copyPhysReg(MachineBasicBlock &MBB,
+                           MachineBasicBlock::iterator MI, DebugLoc DL,
+                           unsigned DestReg, unsigned SrcReg,
+                           bool KillSrc) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!");
+  }
+
+  /// storeRegToStackSlot - Store the specified register of the given register
+  /// class to the specified stack frame index. The store instruction is to be
+  /// added to the given machine basic block before the specified machine
+  /// instruction. If isKill is true, the register operand is the last use and
+  /// must be marked kill.
+  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator MI,
+                                   unsigned SrcReg, bool isKill, int FrameIndex,
+                                   const TargetRegisterClass *RC,
+                                   const TargetRegisterInfo *TRI) const {
+    llvm_unreachable("Target didn't implement "
+                     "TargetInstrInfo::storeRegToStackSlot!");
+  }
+
+  /// loadRegFromStackSlot - Load the specified register of the given register
+  /// class from the specified stack frame index. The load instruction is to be
+  /// added to the given machine basic block before the specified machine
+  /// instruction.
+  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
+                                    MachineBasicBlock::iterator MI,
+                                    unsigned DestReg, int FrameIndex,
+                                    const TargetRegisterClass *RC,
+                                    const TargetRegisterInfo *TRI) const {
+    llvm_unreachable("Target didn't implement "
+                     "TargetInstrInfo::loadRegFromStackSlot!");
+  }
+
+  /// expandPostRAPseudo - This function is called for all pseudo instructions
+  /// that remain after register allocation. Many pseudo instructions are
+  /// created to help register allocation. This is the place to convert them
+  /// into real instructions. The target can edit MI in place, or it can insert
+  /// new instructions and erase MI. The function should return true if
+  /// anything was changed.
+  virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
+    return false;
+  }
+
+  /// foldMemoryOperand - Attempt to fold a load or store of the specified stack
+  /// slot into the specified machine instruction for the specified operand(s).
+  /// If this is possible, a new instruction is returned with the specified
+  /// operand folded, otherwise NULL is returned.
+  /// The new instruction is inserted before MI, and the client is responsible
+  /// for removing the old instruction.
+  MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
+                                  const SmallVectorImpl<unsigned> &Ops,
+                                  int FrameIndex) const;
+
+  /// foldMemoryOperand - Same as the previous version except it allows folding
+  /// of any load and store from / to any address, not just from a specific
+  /// stack slot.
+  MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
+                                  const SmallVectorImpl<unsigned> &Ops,
+                                  MachineInstr* LoadMI) const;
+
+protected:
+  /// foldMemoryOperandImpl - Target-dependent implementation for
+  /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+  /// take care of adding a MachineMemOperand to the newly created instruction.
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                          MachineInstr* MI,
+                                          const SmallVectorImpl<unsigned> &Ops,
+                                          int FrameIndex) const {
+    return nullptr;
+  }
+
+  /// foldMemoryOperandImpl - Target-dependent implementation for
+  /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+  /// take care of adding a MachineMemOperand to the newly created instruction.
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                              MachineInstr* MI,
+                                          const SmallVectorImpl<unsigned> &Ops,
+                                              MachineInstr* LoadMI) const {
+    return nullptr;
+  }
+
+public:
+  /// canFoldMemoryOperand - Returns true for the specified load / store if
+  /// folding is possible.
+  virtual
+  bool canFoldMemoryOperand(const MachineInstr *MI,
+                            const SmallVectorImpl<unsigned> &Ops) const;
+
+  /// unfoldMemoryOperand - Separate a single instruction which folded a load or
+  /// a store or a load and a store into two or more instruction. If this is
+  /// possible, returns true as well as the new instructions by reference.
+  virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
+                                unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
+                                 SmallVectorImpl<MachineInstr*> &NewMIs) const{
+    return false;
+  }
+
+  virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
+                                   SmallVectorImpl<SDNode*> &NewNodes) const {
+    return false;
+  }
+
+  /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new
+  /// instruction after load / store are unfolded from an instruction of the
+  /// specified opcode. It returns zero if the specified unfolding is not
+  /// possible. If LoadRegIndex is non-null, it is filled in with the operand
+  /// index of the operand which will hold the register holding the loaded
+  /// value.
+  virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
+                                      bool UnfoldLoad, bool UnfoldStore,
+                                      unsigned *LoadRegIndex = nullptr) const {
+    return 0;
+  }
+
+  /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+  /// to determine if two loads are loading from the same base address. It
+  /// should only return true if the base pointers are the same and the
+  /// only differences between the two addresses are the offset. It also returns
+  /// the offsets by reference.
+  virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+                                    int64_t &Offset1, int64_t &Offset2) const {
+    return false;
+  }
+
+  /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+  /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should
+  /// be scheduled togther. On some targets if two loads are loading from
+  /// addresses in the same cache line, it's better if they are scheduled
+  /// together. This function takes two integers that represent the load offsets
+  /// from the common base address. It returns true if it decides it's desirable
+  /// to schedule the two loads together. "NumLoads" is the number of loads that
+  /// have already been scheduled after Load1.
+  virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+                                       int64_t Offset1, int64_t Offset2,
+                                       unsigned NumLoads) const {
+    return false;
+  }
+
+  /// \brief Get the base register and byte offset of a load/store instr.
+  virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
+                                    unsigned &BaseReg, unsigned &Offset,
+                                    const TargetRegisterInfo *TRI) const {
+    return false;
+  }
+
+  virtual bool enableClusterLoads() const { return false; }
+
+  virtual bool shouldClusterLoads(MachineInstr *FirstLdSt,
+                                  MachineInstr *SecondLdSt,
+                                  unsigned NumLoads) const {
+    return false;
+  }
+
+  /// \brief Can this target fuse the given instructions if they are scheduled
+  /// adjacent.
+  virtual bool shouldScheduleAdjacent(MachineInstr* First,
+                                      MachineInstr *Second) const {
+    return false;
+  }
+
+  /// ReverseBranchCondition - Reverses the branch condition of the specified
+  /// condition list, returning false on success and true if it cannot be
+  /// reversed.
+  virtual
+  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
+    return true;
+  }
+
+  /// insertNoop - Insert a noop into the instruction stream at the specified
+  /// point.
+  virtual void insertNoop(MachineBasicBlock &MBB,
+                          MachineBasicBlock::iterator MI) const;
+
+
+  /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+  virtual void getNoopForMachoTarget(MCInst &NopInst) const {
+    // Default to just using 'nop' string.
+  }
+
+
+  /// isPredicated - Returns true if the instruction is already predicated.
+  ///
+  virtual bool isPredicated(const MachineInstr *MI) const {
+    return false;
+  }
+
+  /// isUnpredicatedTerminator - Returns true if the instruction is a
+  /// terminator instruction that has not been predicated.
+  virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
+
+  /// PredicateInstruction - Convert the instruction into a predicated
+  /// instruction. It returns true if the operation was successful.
+  virtual
+  bool PredicateInstruction(MachineInstr *MI,
+                        const SmallVectorImpl<MachineOperand> &Pred) const;
+
+  /// SubsumesPredicate - Returns true if the first specified predicate
+  /// subsumes the second, e.g. GE subsumes GT.
+  virtual
+  bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
+                         const SmallVectorImpl<MachineOperand> &Pred2) const {
+    return false;
+  }
+
+  /// DefinesPredicate - If the specified instruction defines any predicate
+  /// or condition code register(s) used for predication, returns true as well
+  /// as the definition predicate(s) by reference.
+  virtual bool DefinesPredicate(MachineInstr *MI,
+                                std::vector<MachineOperand> &Pred) const {
+    return false;
+  }
+
+  /// isPredicable - Return true if the specified instruction can be predicated.
+  /// By default, this returns true for every instruction with a
+  /// PredicateOperand.
+  virtual bool isPredicable(MachineInstr *MI) const {
+    return MI->getDesc().isPredicable();
+  }
+
+  /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
+  /// instruction that defines the specified register class.
+  virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
+    return true;
+  }
+
+  /// isSchedulingBoundary - Test if the given instruction should be
+  /// considered a scheduling boundary. This primarily includes labels and
+  /// terminators.
+  virtual bool isSchedulingBoundary(const MachineInstr *MI,
+                                    const MachineBasicBlock *MBB,
+                                    const MachineFunction &MF) const;
+
+  /// Measure the specified inline asm to determine an approximation of its
+  /// length.
+  virtual unsigned getInlineAsmLength(const char *Str,
+                                      const MCAsmInfo &MAI) const;
+
+  /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer to
+  /// use for this target when scheduling the machine instructions before
+  /// register allocation.
+  virtual ScheduleHazardRecognizer*
+  CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
+                               const ScheduleDAG *DAG) const;
+
+  /// CreateTargetMIHazardRecognizer - Allocate and return a hazard recognizer
+  /// to use for this target when scheduling the machine instructions before
+  /// register allocation.
+  virtual ScheduleHazardRecognizer*
+  CreateTargetMIHazardRecognizer(const InstrItineraryData*,
+                                 const ScheduleDAG *DAG) const;
+
+  /// CreateTargetPostRAHazardRecognizer - Allocate and return a hazard
+  /// recognizer to use for this target when scheduling the machine instructions
+  /// after register allocation.
+  virtual ScheduleHazardRecognizer*
+  CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+                                     const ScheduleDAG *DAG) const;
+
+  /// Provide a global flag for disabling the PreRA hazard recognizer that
+  /// targets may choose to honor.
+  bool usePreRAHazardRecognizer() const;
+
+  /// analyzeCompare - For a comparison instruction, return the source registers
+  /// in SrcReg and SrcReg2 if having two register operands, and the value it
+  /// compares against in CmpValue. Return true if the comparison instruction
+  /// can be analyzed.
+  virtual bool analyzeCompare(const MachineInstr *MI,
+                              unsigned &SrcReg, unsigned &SrcReg2,
+                              int &Mask, int &Value) const {
+    return false;
+  }
+
+  /// optimizeCompareInstr - See if the comparison instruction can be converted
+  /// into something more efficient. E.g., on ARM most instructions can set the
+  /// flags register, obviating the need for a separate CMP.
+  virtual bool optimizeCompareInstr(MachineInstr *CmpInstr,
+                                    unsigned SrcReg, unsigned SrcReg2,
+                                    int Mask, int Value,
+                                    const MachineRegisterInfo *MRI) const {
+    return false;
+  }
+
+  /// optimizeLoadInstr - Try to remove the load by folding it to a register
+  /// operand at the use. We fold the load instructions if and only if the
+  /// def and use are in the same BB. We only look at one load and see
+  /// whether it can be folded into MI. FoldAsLoadDefReg is the virtual register
+  /// defined by the load we are trying to fold. DefMI returns the machine
+  /// instruction that defines FoldAsLoadDefReg, and the function returns
+  /// the machine instruction generated due to folding.
+  virtual MachineInstr* optimizeLoadInstr(MachineInstr *MI,
+                        const MachineRegisterInfo *MRI,
+                        unsigned &FoldAsLoadDefReg,
+                        MachineInstr *&DefMI) const {
+    return nullptr;
+  }
+
+  /// FoldImmediate - 'Reg' is known to be defined by a move immediate
+  /// instruction, try to fold the immediate into the use instruction.
+  /// If MRI->hasOneNonDBGUse(Reg) is true, and this function returns true,
+  /// then the caller may assume that DefMI has been erased from its parent
+  /// block. The caller may assume that it will not be erased by this
+  /// function otherwise.
+  virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
+                             unsigned Reg, MachineRegisterInfo *MRI) const {
+    return false;
+  }
+
+  /// getNumMicroOps - Return the number of u-operations the given machine
+  /// instruction will be decoded to on the target cpu. The itinerary's
+  /// IssueWidth is the number of microops that can be dispatched each
+  /// cycle. An instruction with zero microops takes no dispatch resources.
+  virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
+                                  const MachineInstr *MI) const;
+
+  /// isZeroCost - Return true for pseudo instructions that don't consume any
+  /// machine resources in their current form. These are common cases that the
+  /// scheduler should consider free, rather than conservatively handling them
+  /// as instructions with no itinerary.
+  bool isZeroCost(unsigned Opcode) const {
+    return Opcode <= TargetOpcode::COPY;
+  }
+
+  virtual int getOperandLatency(const InstrItineraryData *ItinData,
+                                SDNode *DefNode, unsigned DefIdx,
+                                SDNode *UseNode, unsigned UseIdx) const;
+
+  /// getOperandLatency - Compute and return the use operand latency of a given
+  /// pair of def and use.
+  /// In most cases, the static scheduling itinerary was enough to determine the
+  /// operand latency. But it may not be possible for instructions with variable
+  /// number of defs / uses.
+  ///
+  /// This is a raw interface to the itinerary that may be directly overriden by
+  /// a target. Use computeOperandLatency to get the best estimate of latency.
+  virtual int getOperandLatency(const InstrItineraryData *ItinData,
+                                const MachineInstr *DefMI, unsigned DefIdx,
+                                const MachineInstr *UseMI,
+                                unsigned UseIdx) const;
+
+  /// computeOperandLatency - Compute and return the latency of the given data
+  /// dependent def and use when the operand indices are already known.
+  unsigned computeOperandLatency(const InstrItineraryData *ItinData,
+                                 const MachineInstr *DefMI, unsigned DefIdx,
+                                 const MachineInstr *UseMI, unsigned UseIdx)
+    const;
+
+  /// getInstrLatency - Compute the instruction latency of a given instruction.
+  /// If the instruction has higher cost when predicated, it's returned via
+  /// PredCost.
+  virtual unsigned getInstrLatency(const InstrItineraryData *ItinData,
+                                   const MachineInstr *MI,
+                                   unsigned *PredCost = nullptr) const;
+
+  virtual unsigned getPredicationCost(const MachineInstr *MI) const;
+
+  virtual int getInstrLatency(const InstrItineraryData *ItinData,
+                              SDNode *Node) const;
+
+  /// Return the default expected latency for a def based on it's opcode.
+  unsigned defaultDefLatency(const MCSchedModel *SchedModel,
+                             const MachineInstr *DefMI) const;
+
+  int computeDefOperandLatency(const InstrItineraryData *ItinData,
+                               const MachineInstr *DefMI) const;
+
+  /// isHighLatencyDef - Return true if this opcode has high latency to its
+  /// result.
+  virtual bool isHighLatencyDef(int opc) const { return false; }
+
+  /// hasHighOperandLatency - Compute operand latency between a def of 'Reg'
+  /// and an use in the current loop, return true if the target considered
+  /// it 'high'. This is used by optimization passes such as machine LICM to
+  /// determine whether it makes sense to hoist an instruction out even in
+  /// high register pressure situation.
+  virtual
+  bool hasHighOperandLatency(const InstrItineraryData *ItinData,
+                             const MachineRegisterInfo *MRI,
+                             const MachineInstr *DefMI, unsigned DefIdx,
+                             const MachineInstr *UseMI, unsigned UseIdx) const {
+    return false;
+  }
+
+  /// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true
+  /// if the target considered it 'low'.
+  virtual
+  bool hasLowDefLatency(const InstrItineraryData *ItinData,
+                        const MachineInstr *DefMI, unsigned DefIdx) const;
+
+  /// verifyInstruction - Perform target specific instruction verification.
+  virtual
+  bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const {
+    return true;
+  }
+
+  /// getExecutionDomain - Return the current execution domain and bit mask of
+  /// possible domains for instruction.
+  ///
+  /// Some micro-architectures have multiple execution domains, and multiple
+  /// opcodes that perform the same operation in different domains.  For
+  /// example, the x86 architecture provides the por, orps, and orpd
+  /// instructions that all do the same thing.  There is a latency penalty if a
+  /// register is written in one domain and read in another.
+  ///
+  /// This function returns a pair (domain, mask) containing the execution
+  /// domain of MI, and a bit mask of possible domains.  The setExecutionDomain
+  /// function can be used to change the opcode to one of the domains in the
+  /// bit mask.  Instructions whose execution domain can't be changed should
+  /// return a 0 mask.
+  ///
+  /// The execution domain numbers don't have any special meaning except domain
+  /// 0 is used for instructions that are not associated with any interesting
+  /// execution domain.
+  ///
+  virtual std::pair<uint16_t, uint16_t>
+  getExecutionDomain(const MachineInstr *MI) const {
+    return std::make_pair(0, 0);
+  }
+
+  /// setExecutionDomain - Change the opcode of MI to execute in Domain.
+  ///
+  /// The bit (1 << Domain) must be set in the mask returned from
+  /// getExecutionDomain(MI).
+  ///
+  virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {}
+
+
+  /// getPartialRegUpdateClearance - Returns the preferred minimum clearance
+  /// before an instruction with an unwanted partial register update.
+  ///
+  /// Some instructions only write part of a register, and implicitly need to
+  /// read the other parts of the register.  This may cause unwanted stalls
+  /// preventing otherwise unrelated instructions from executing in parallel in
+  /// an out-of-order CPU.
+  ///
+  /// For example, the x86 instruction cvtsi2ss writes its result to bits
+  /// [31:0] of the destination xmm register. Bits [127:32] are unaffected, so
+  /// the instruction needs to wait for the old value of the register to become
+  /// available:
+  ///
+  ///   addps %xmm1, %xmm0
+  ///   movaps %xmm0, (%rax)
+  ///   cvtsi2ss %rbx, %xmm0
+  ///
+  /// In the code above, the cvtsi2ss instruction needs to wait for the addps
+  /// instruction before it can issue, even though the high bits of %xmm0
+  /// probably aren't needed.
+  ///
+  /// This hook returns the preferred clearance before MI, measured in
+  /// instructions.  Other defs of MI's operand OpNum are avoided in the last N
+  /// instructions before MI.  It should only return a positive value for
+  /// unwanted dependencies.  If the old bits of the defined register have
+  /// useful values, or if MI is determined to otherwise read the dependency,
+  /// the hook should return 0.
+  ///
+  /// The unwanted dependency may be handled by:
+  ///
+  /// 1. Allocating the same register for an MI def and use.  That makes the
+  ///    unwanted dependency identical to a required dependency.
+  ///
+  /// 2. Allocating a register for the def that has no defs in the previous N
+  ///    instructions.
+  ///
+  /// 3. Calling breakPartialRegDependency() with the same arguments.  This
+  ///    allows the target to insert a dependency breaking instruction.
+  ///
+  virtual unsigned
+  getPartialRegUpdateClearance(const MachineInstr *MI, unsigned OpNum,
+                               const TargetRegisterInfo *TRI) const {
+    // The default implementation returns 0 for no partial register dependency.
+    return 0;
+  }
+
+  /// \brief Return the minimum clearance before an instruction that reads an
+  /// unused register.
+  ///
+  /// For example, AVX instructions may copy part of an register operand into
+  /// the unused high bits of the destination register.
+  ///
+  /// vcvtsi2sdq %rax, %xmm0<undef>, %xmm14
+  ///
+  /// In the code above, vcvtsi2sdq copies %xmm0[127:64] into %xmm14 creating a
+  /// false dependence on any previous write to %xmm0.
+  ///
+  /// This hook works similarly to getPartialRegUpdateClearance, except that it
+  /// does not take an operand index. Instead sets \p OpNum to the index of the
+  /// unused register.
+  virtual unsigned getUndefRegClearance(const MachineInstr *MI, unsigned &OpNum,
+                                        const TargetRegisterInfo *TRI) const {
+    // The default implementation returns 0 for no undef register dependency.
+    return 0;
+  }
+
+  /// breakPartialRegDependency - Insert a dependency-breaking instruction
+  /// before MI to eliminate an unwanted dependency on OpNum.
+  ///
+  /// If it wasn't possible to avoid a def in the last N instructions before MI
+  /// (see getPartialRegUpdateClearance), this hook will be called to break the
+  /// unwanted dependency.
+  ///
+  /// On x86, an xorps instruction can be used as a dependency breaker:
+  ///
+  ///   addps %xmm1, %xmm0
+  ///   movaps %xmm0, (%rax)
+  ///   xorps %xmm0, %xmm0
+  ///   cvtsi2ss %rbx, %xmm0
+  ///
+  /// An <imp-kill> operand should be added to MI if an instruction was
+  /// inserted.  This ties the instructions together in the post-ra scheduler.
+  ///
+  virtual void
+  breakPartialRegDependency(MachineBasicBlock::iterator MI, unsigned OpNum,
+                            const TargetRegisterInfo *TRI) const {}
+
+  /// Create machine specific model for scheduling.
+  virtual DFAPacketizer*
+    CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) const {
+    return nullptr;
+  }
+
+private:
+  int CallFrameSetupOpcode, CallFrameDestroyOpcode;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h
new file mode 100644
index 0000000..6de264e
--- /dev/null
+++ b/include/llvm/Target/TargetIntrinsicInfo.h
@@ -0,0 +1,65 @@
+//===-- llvm/Target/TargetIntrinsicInfo.h - Instruction 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 describes the target intrinsic instructions to the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINTRINSICINFO_H
+#define LLVM_TARGET_TARGETINTRINSICINFO_H
+
+#include "llvm/Support/Compiler.h"
+#include <string>
+
+namespace llvm {
+
+class Function;
+class Module;
+class Type;
+
+//---------------------------------------------------------------------------
+///
+/// TargetIntrinsicInfo - Interface to description of machine instruction set
+///
+class TargetIntrinsicInfo {
+  TargetIntrinsicInfo(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetIntrinsicInfo &) LLVM_DELETED_FUNCTION;
+public:
+  TargetIntrinsicInfo();
+  virtual ~TargetIntrinsicInfo();
+
+  /// Return the name of a target intrinsic, e.g. "llvm.bfin.ssync".
+  /// The Tys and numTys parameters are for intrinsics with overloaded types
+  /// (e.g., those using iAny or fAny). For a declaration for an overloaded
+  /// intrinsic, Tys should point to an array of numTys pointers to Type,
+  /// and must provide exactly one type for each overloaded type in the
+  /// intrinsic.
+  virtual std::string getName(unsigned IID, Type **Tys = nullptr,
+                              unsigned numTys = 0) const = 0;
+
+  /// Look up target intrinsic by name. Return intrinsic ID or 0 for unknown
+  /// names.
+  virtual unsigned lookupName(const char *Name, unsigned Len) const =0;
+
+  /// Return the target intrinsic ID of a function, or 0.
+  virtual unsigned getIntrinsicID(Function *F) const;
+
+  /// Returns true if the intrinsic can be overloaded.
+  virtual bool isOverloaded(unsigned IID) const = 0;
+  
+  /// Create or insert an LLVM Function declaration for an intrinsic,
+  /// and return it. The Tys and numTys are for intrinsics with overloaded
+  /// types. See above for more information.
+  virtual Function *getDeclaration(Module *M, unsigned ID, Type **Tys = nullptr,
+                                   unsigned numTys = 0) const = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetItinerary.td b/include/llvm/Target/TargetItinerary.td
new file mode 100644
index 0000000..cc74006
--- /dev/null
+++ b/include/llvm/Target/TargetItinerary.td
@@ -0,0 +1,136 @@
+//===- TargetItinerary.td - Target Itinierary Description --*- tablegen -*-===//
+//
+//                     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 target-independent scheduling interfaces
+// which should be implemented by each target that uses instruction
+// itineraries for scheduling. Itineraries are details reservation
+// tables for each instruction class. They are most appropriate for
+// in-order machine with complicated scheduling or bundling constraints.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Processor functional unit - These values represent the function units
+// available across all chip sets for the target.  Eg., IntUnit, FPUnit, ...
+// These may be independent values for each chip set or may be shared across
+// all chip sets of the target.  Each functional unit is treated as a resource
+// during scheduling and has an affect instruction order based on availability
+// during a time interval.
+//
+class FuncUnit;
+
+//===----------------------------------------------------------------------===//
+// Pipeline bypass / forwarding - These values specifies the symbolic names of
+// pipeline bypasses which can be used to forward results of instructions
+// that are forwarded to uses.
+class Bypass;
+def NoBypass : Bypass;
+
+class ReservationKind<bits<1> val> {
+  int Value = val;
+}
+
+def Required : ReservationKind<0>;
+def Reserved : ReservationKind<1>;
+
+//===----------------------------------------------------------------------===//
+// Instruction stage - These values represent a non-pipelined step in
+// the execution of an instruction.  Cycles represents the number of
+// discrete time slots needed to complete the stage.  Units represent
+// the choice of functional units that can be used to complete the
+// stage.  Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+// cycles should elapse from the start of this stage to the start of
+// the next stage in the itinerary.  For example:
+//
+// A stage is specified in one of two ways:
+//
+//   InstrStage<1, [FU_x, FU_y]>     - TimeInc defaults to Cycles
+//   InstrStage<1, [FU_x, FU_y], 0>  - TimeInc explicit
+//
+
+class InstrStage<int cycles, list<FuncUnit> units,
+                 int timeinc = -1,
+                 ReservationKind kind = Required> {
+  int Cycles          = cycles;       // length of stage in machine cycles
+  list<FuncUnit> Units = units;       // choice of functional units
+  int TimeInc         = timeinc;      // cycles till start of next stage
+  int Kind            = kind.Value;   // kind of FU reservation
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary - An itinerary represents a sequential series of steps
+// required to complete an instruction.  Itineraries are represented as lists of
+// instruction stages.
+//
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary classes - These values represent 'named' instruction
+// itinerary.  Using named itineraries simplifies managing groups of
+// instructions across chip sets.  An instruction uses the same itinerary class
+// across all chip sets.  Thus a new chip set can be added without modifying
+// instruction information.
+//
+class InstrItinClass;
+def NoItinerary : InstrItinClass;
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary data - These values provide a runtime map of an
+// instruction itinerary class (name) to its itinerary data.
+//
+// NumMicroOps represents the number of micro-operations that each instruction
+// in the class are decoded to. If the number is zero, then it means the
+// instruction can decode into variable number of micro-ops and it must be
+// determined dynamically. This directly relates to the itineraries
+// global IssueWidth property, which constrains the number of microops
+// that can issue per cycle.
+//
+// OperandCycles are optional "cycle counts". They specify the cycle after
+// instruction issue the values which correspond to specific operand indices
+// are defined or read. Bypasses are optional "pipeline forwarding pathes", if
+// a def by an instruction is available on a specific bypass and the use can
+// read from the same bypass, then the operand use latency is reduced by one.
+//
+//  InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>,
+//                               InstrStage<1, [A9_AGU]>],
+//                              [3, 1], [A9_LdBypass]>,
+//  InstrItinData<IIC_iMVNr   , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>],
+//                              [1, 1], [NoBypass, A9_LdBypass]>,
+//
+// In this example, the instruction of IIC_iLoadi reads its input on cycle 1
+// (after issue) and the result of the load is available on cycle 3. The result
+// is available via forwarding path A9_LdBypass. If it's used by the first
+// source operand of instructions of IIC_iMVNr class, then the operand latency
+// is reduced by 1.
+class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
+                    list<int> operandcycles = [],
+                    list<Bypass> bypasses = [], int uops = 1> {
+  InstrItinClass TheClass = Class;
+  int NumMicroOps = uops;
+  list<InstrStage> Stages = stages;
+  list<int> OperandCycles = operandcycles;
+  list<Bypass> Bypasses = bypasses;
+}
+
+//===----------------------------------------------------------------------===//
+// Processor itineraries - These values represent the set of all itinerary
+// classes for a given chip set.
+//
+// Set property values to -1 to use the default.
+// See InstrItineraryProps for comments and defaults.
+class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
+                           list<InstrItinData> iid> {
+  list<FuncUnit> FU = fu;
+  list<Bypass> BP = bp;
+  list<InstrItinData> IID = iid;
+}
+
+// NoItineraries - A marker that can be used by processors without schedule
+// info. Subtargets using NoItineraries can bypass the scheduler's
+// expensive HazardRecognizer because no reservation table is needed.
+def NoItineraries : ProcessorItineraries<[], [], []>;
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
new file mode 100644
index 0000000..f9bd0fb
--- /dev/null
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -0,0 +1,137 @@
+//===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an abstract interface used by the Just-In-Time code
+// generator to perform target-specific activities, such as emitting stubs.  If
+// a TargetMachine supports JIT code generation, it should provide one of these
+// objects through the getJITInfo() method.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETJITINFO_H
+#define LLVM_TARGET_TARGETJITINFO_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+  class Function;
+  class GlobalValue;
+  class JITCodeEmitter;
+  class MachineRelocation;
+
+  /// TargetJITInfo - Target specific information required by the Just-In-Time
+  /// code generator.
+  class TargetJITInfo {
+    virtual void anchor();
+  public:
+    virtual ~TargetJITInfo() {}
+
+    /// replaceMachineCodeForFunction - Make it so that calling the function
+    /// whose machine code is at OLD turns into a call to NEW, perhaps by
+    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
+    /// code.
+    ///
+    virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
+
+    /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
+    /// to emit an indirect symbol which contains the address of the specified
+    /// ptr.
+    virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
+                                             JITCodeEmitter &JCE) {
+      llvm_unreachable("This target doesn't implement "
+                       "emitGlobalValueIndirectSym!");
+    }
+
+    /// Records the required size and alignment for a call stub in bytes.
+    struct StubLayout {
+      size_t Size;
+      size_t Alignment;
+    };
+    /// Returns the maximum size and alignment for a call stub on this target.
+    virtual StubLayout getStubLayout() {
+      llvm_unreachable("This target doesn't implement getStubLayout!");
+    }
+
+    /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
+    /// small native function that simply calls the function at the specified
+    /// address.  The JITCodeEmitter must already have storage allocated for the
+    /// stub.  Return the address of the resultant function, which may have been
+    /// aligned from the address the JCE was set up to emit at.
+    virtual void *emitFunctionStub(const Function* F, void *Target,
+                                   JITCodeEmitter &JCE) {
+      llvm_unreachable("This target doesn't implement emitFunctionStub!");
+    }
+
+    /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
+    /// specific basic block.
+    virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) {
+      llvm_unreachable("This target doesn't implement getPICJumpTableEntry!");
+    }
+
+    /// LazyResolverFn - This typedef is used to represent the function that
+    /// unresolved call points should invoke.  This is a target specific
+    /// function that knows how to walk the stack and find out which stub the
+    /// call is coming from.
+    typedef void (*LazyResolverFn)();
+
+    /// JITCompilerFn - This typedef is used to represent the JIT function that
+    /// lazily compiles the function corresponding to a stub.  The JIT keeps
+    /// track of the mapping between stubs and LLVM Functions, the target
+    /// provides the ability to figure out the address of a stub that is called
+    /// by the LazyResolverFn.
+    typedef void* (*JITCompilerFn)(void *);
+
+    /// getLazyResolverFunction - This method is used to initialize the JIT,
+    /// giving the target the function that should be used to compile a
+    /// function, and giving the JIT the target function used to do the lazy
+    /// resolving.
+    virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
+      llvm_unreachable("Not implemented for this target!");
+    }
+
+    /// relocate - Before the JIT can run a block of code that has been emitted,
+    /// it must rewrite the code to contain the actual addresses of any
+    /// referenced global symbols.
+    virtual void relocate(void *Function, MachineRelocation *MR,
+                          unsigned NumRelocs, unsigned char* GOTBase) {
+      assert(NumRelocs == 0 && "This target does not have relocations!");
+    }
+    
+
+    /// allocateThreadLocalMemory - Each target has its own way of
+    /// handling thread local variables. This method returns a value only
+    /// meaningful to the target.
+    virtual char* allocateThreadLocalMemory(size_t size) {
+      llvm_unreachable("This target does not implement thread local storage!");
+    }
+
+    /// needsGOT - Allows a target to specify that it would like the
+    /// JIT to manage a GOT for it.
+    bool needsGOT() const { return useGOT; }
+
+    /// hasCustomConstantPool - Allows a target to specify that constant
+    /// pool address resolution is handled by the target.
+    virtual bool hasCustomConstantPool() const { return false; }
+
+    /// hasCustomJumpTables - Allows a target to specify that jumptables
+    /// are emitted by the target.
+    virtual bool hasCustomJumpTables() const { return false; }
+
+    /// allocateSeparateGVMemory - If true, globals should be placed in
+    /// separately allocated heap memory rather than in the same
+    /// code memory allocated by JITCodeEmitter.
+    virtual bool allocateSeparateGVMemory() const { return false; }
+  protected:
+    bool useGOT;
+  };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
new file mode 100644
index 0000000..d4f9f23
--- /dev/null
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -0,0 +1,779 @@
+//===-- llvm/Target/TargetLibraryInfo.h - Library information ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
+#define LLVM_TARGET_TARGETLIBRARYINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+  class Triple;
+
+  namespace LibFunc {
+    enum Func {
+      /// int _IO_getc(_IO_FILE * __fp);
+      under_IO_getc,
+      /// int _IO_putc(int __c, _IO_FILE * __fp);
+      under_IO_putc,
+      /// void operator delete[](void*);
+      ZdaPv,
+      /// void operator delete[](void*, nothrow);
+      ZdaPvRKSt9nothrow_t,
+      /// void operator delete(void*);
+      ZdlPv,
+      /// void operator delete(void*, nothrow);
+      ZdlPvRKSt9nothrow_t,
+      /// void *new[](unsigned int);
+      Znaj,
+      /// void *new[](unsigned int, nothrow);
+      ZnajRKSt9nothrow_t,
+      /// void *new[](unsigned long);
+      Znam,
+      /// void *new[](unsigned long, nothrow);
+      ZnamRKSt9nothrow_t,
+      /// void *new(unsigned int);
+      Znwj,
+      /// void *new(unsigned int, nothrow);
+      ZnwjRKSt9nothrow_t,
+      /// void *new(unsigned long);
+      Znwm,
+      /// void *new(unsigned long, nothrow);
+      ZnwmRKSt9nothrow_t,
+      /// double __cospi(double x);
+      cospi,
+      /// float __cospif(float x);
+      cospif,
+      /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
+      cxa_atexit,
+      /// void __cxa_guard_abort(guard_t *guard);
+      /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
+      cxa_guard_abort,      
+      /// int __cxa_guard_acquire(guard_t *guard);
+      cxa_guard_acquire,
+      /// void __cxa_guard_release(guard_t *guard);
+      cxa_guard_release,
+      /// int __isoc99_scanf (const char *format, ...)
+      dunder_isoc99_scanf,
+      /// int __isoc99_sscanf(const char *s, const char *format, ...)
+      dunder_isoc99_sscanf,
+      /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
+      memcpy_chk,
+      /// double __sincospi_stret(double x);
+      sincospi_stret,
+      /// float __sincospif_stret(float x);
+      sincospif_stret,
+      /// double __sinpi(double x);
+      sinpi,
+      /// float __sinpif(float x);
+      sinpif,
+      /// double __sqrt_finite(double x);
+      sqrt_finite,
+      /// float __sqrt_finite(float x);
+      sqrtf_finite,
+      /// long double __sqrt_finite(long double x);
+      sqrtl_finite,
+      /// char * __strdup(const char *s);
+      dunder_strdup,
+      /// char *__strndup(const char *s, size_t n);
+      dunder_strndup,
+      /// char * __strtok_r(char *s, const char *delim, char **save_ptr);
+      dunder_strtok_r,
+      /// int abs(int j);
+      abs,
+      /// int access(const char *path, int amode);
+      access,
+      /// double acos(double x);
+      acos,
+      /// float acosf(float x);
+      acosf,
+      /// double acosh(double x);
+      acosh,
+      /// float acoshf(float x);
+      acoshf,
+      /// long double acoshl(long double x);
+      acoshl,
+      /// long double acosl(long double x);
+      acosl,
+      /// double asin(double x);
+      asin,
+      /// float asinf(float x);
+      asinf,
+      /// double asinh(double x);
+      asinh,
+      /// float asinhf(float x);
+      asinhf,
+      /// long double asinhl(long double x);
+      asinhl,
+      /// long double asinl(long double x);
+      asinl,
+      /// double atan(double x);
+      atan,
+      /// double atan2(double y, double x);
+      atan2,
+      /// float atan2f(float y, float x);
+      atan2f,
+      /// long double atan2l(long double y, long double x);
+      atan2l,
+      /// float atanf(float x);
+      atanf,
+      /// double atanh(double x);
+      atanh,
+      /// float atanhf(float x);
+      atanhf,
+      /// long double atanhl(long double x);
+      atanhl,
+      /// long double atanl(long double x);
+      atanl,
+      /// double atof(const char *str);
+      atof,
+      /// int atoi(const char *str);
+      atoi,
+      /// long atol(const char *str);
+      atol,
+      /// long long atoll(const char *nptr);
+      atoll,
+      /// int bcmp(const void *s1, const void *s2, size_t n);
+      bcmp,
+      /// void bcopy(const void *s1, void *s2, size_t n);
+      bcopy,
+      /// void bzero(void *s, size_t n);
+      bzero,
+      /// void *calloc(size_t count, size_t size);
+      calloc,
+      /// double cbrt(double x);
+      cbrt,
+      /// float cbrtf(float x);
+      cbrtf,
+      /// long double cbrtl(long double x);
+      cbrtl,
+      /// double ceil(double x);
+      ceil,
+      /// float ceilf(float x);
+      ceilf,
+      /// long double ceill(long double x);
+      ceill,
+      /// int chmod(const char *path, mode_t mode);
+      chmod,
+      /// int chown(const char *path, uid_t owner, gid_t group);
+      chown,
+      /// void clearerr(FILE *stream);
+      clearerr,
+      /// int closedir(DIR *dirp);
+      closedir,
+      /// double copysign(double x, double y);
+      copysign,
+      /// float copysignf(float x, float y);
+      copysignf,
+      /// long double copysignl(long double x, long double y);
+      copysignl,
+      /// double cos(double x);
+      cos,
+      /// float cosf(float x);
+      cosf,
+      /// double cosh(double x);
+      cosh,
+      /// float coshf(float x);
+      coshf,
+      /// long double coshl(long double x);
+      coshl,
+      /// long double cosl(long double x);
+      cosl,
+      /// char *ctermid(char *s);
+      ctermid,
+      /// double exp(double x);
+      exp,
+      /// double exp10(double x);
+      exp10,
+      /// float exp10f(float x);
+      exp10f,
+      /// long double exp10l(long double x);
+      exp10l,
+      /// double exp2(double x);
+      exp2,
+      /// float exp2f(float x);
+      exp2f,
+      /// long double exp2l(long double x);
+      exp2l,
+      /// float expf(float x);
+      expf,
+      /// long double expl(long double x);
+      expl,
+      /// double expm1(double x);
+      expm1,
+      /// float expm1f(float x);
+      expm1f,
+      /// long double expm1l(long double x);
+      expm1l,
+      /// double fabs(double x);
+      fabs,
+      /// float fabsf(float x);
+      fabsf,
+      /// long double fabsl(long double x);
+      fabsl,
+      /// int fclose(FILE *stream);
+      fclose,
+      /// FILE *fdopen(int fildes, const char *mode);
+      fdopen,
+      /// int feof(FILE *stream);
+      feof,
+      /// int ferror(FILE *stream);
+      ferror,
+      /// int fflush(FILE *stream);
+      fflush,
+      /// int ffs(int i);
+      ffs,
+      /// int ffsl(long int i);
+      ffsl,
+      /// int ffsll(long long int i);
+      ffsll,
+      /// int fgetc(FILE *stream);
+      fgetc,
+      /// int fgetpos(FILE *stream, fpos_t *pos);
+      fgetpos,
+      /// char *fgets(char *s, int n, FILE *stream);
+      fgets,
+      /// int fileno(FILE *stream);
+      fileno,
+      /// int fiprintf(FILE *stream, const char *format, ...);
+      fiprintf,
+      /// void flockfile(FILE *file);
+      flockfile,
+      /// double floor(double x);
+      floor,
+      /// float floorf(float x);
+      floorf,
+      /// long double floorl(long double x);
+      floorl,
+      /// double fmax(double x, double y);
+      fmax,
+      /// float fmaxf(float x, float y);
+      fmaxf,
+      /// long double fmaxl(long double x, long double y);
+      fmaxl,
+      /// double fmin(double x, double y);
+      fmin,
+      /// float fminf(float x, float y);
+      fminf,
+      /// long double fminl(long double x, long double y);
+      fminl,
+      /// double fmod(double x, double y);
+      fmod,
+      /// float fmodf(float x, float y);
+      fmodf,
+      /// long double fmodl(long double x, long double y);
+      fmodl,
+      /// FILE *fopen(const char *filename, const char *mode);
+      fopen,
+      /// FILE *fopen64(const char *filename, const char *opentype)
+      fopen64,
+      /// int fprintf(FILE *stream, const char *format, ...);
+      fprintf,
+      /// int fputc(int c, FILE *stream);
+      fputc,
+      /// int fputs(const char *s, FILE *stream);
+      fputs,
+      /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
+      fread,
+      /// void free(void *ptr);
+      free,
+      /// double frexp(double num, int *exp);
+      frexp,
+      /// float frexpf(float num, int *exp);
+      frexpf,
+      /// long double frexpl(long double num, int *exp);
+      frexpl,
+      /// int fscanf(FILE *stream, const char *format, ... );
+      fscanf,
+      /// int fseek(FILE *stream, long offset, int whence);
+      fseek,
+      /// int fseeko(FILE *stream, off_t offset, int whence);
+      fseeko,
+      /// int fseeko64(FILE *stream, off64_t offset, int whence)
+      fseeko64,
+      /// int fsetpos(FILE *stream, const fpos_t *pos);
+      fsetpos,
+      /// int fstat(int fildes, struct stat *buf);
+      fstat,
+      /// int fstat64(int filedes, struct stat64 *buf)
+      fstat64,
+      /// int fstatvfs(int fildes, struct statvfs *buf);
+      fstatvfs,
+      /// int fstatvfs64(int fildes, struct statvfs64 *buf);
+      fstatvfs64,
+      /// long ftell(FILE *stream);
+      ftell,
+      /// off_t ftello(FILE *stream);
+      ftello,
+      /// off64_t ftello64(FILE *stream)
+      ftello64,
+      /// int ftrylockfile(FILE *file);
+      ftrylockfile,
+      /// void funlockfile(FILE *file);
+      funlockfile,
+      /// size_t fwrite(const void *ptr, size_t size, size_t nitems,
+      /// FILE *stream);
+      fwrite,
+      /// int getc(FILE *stream);
+      getc,
+      /// int getc_unlocked(FILE *stream);
+      getc_unlocked,
+      /// int getchar(void);
+      getchar,
+      /// char *getenv(const char *name);
+      getenv,
+      /// int getitimer(int which, struct itimerval *value);
+      getitimer,
+      /// int getlogin_r(char *name, size_t namesize);
+      getlogin_r,
+      /// struct passwd *getpwnam(const char *name);
+      getpwnam,
+      /// char *gets(char *s);
+      gets,
+      /// int gettimeofday(struct timeval *tp, void *tzp);
+      gettimeofday,
+      /// uint32_t htonl(uint32_t hostlong);
+      htonl,
+      /// uint16_t htons(uint16_t hostshort);
+      htons,
+      /// int iprintf(const char *format, ...);
+      iprintf,
+      /// int isascii(int c);
+      isascii,
+      /// int isdigit(int c);
+      isdigit,
+      /// long int labs(long int j);
+      labs,
+      /// int lchown(const char *path, uid_t owner, gid_t group);
+      lchown,
+      /// double ldexp(double x, int n);
+      ldexp,
+      /// float ldexpf(float x, int n);
+      ldexpf,
+      /// long double ldexpl(long double x, int n);
+      ldexpl,
+      /// long long int llabs(long long int j);
+      llabs,
+      /// double log(double x);
+      log,
+      /// double log10(double x);
+      log10,
+      /// float log10f(float x);
+      log10f,
+      /// long double log10l(long double x);
+      log10l,
+      /// double log1p(double x);
+      log1p,
+      /// float log1pf(float x);
+      log1pf,
+      /// long double log1pl(long double x);
+      log1pl,
+      /// double log2(double x);
+      log2,
+      /// float log2f(float x);
+      log2f,
+      /// double long double log2l(long double x);
+      log2l,
+      /// double logb(double x);
+      logb,
+      /// float logbf(float x);
+      logbf,
+      /// long double logbl(long double x);
+      logbl,
+      /// float logf(float x);
+      logf,
+      /// long double logl(long double x);
+      logl,
+      /// int lstat(const char *path, struct stat *buf);
+      lstat,
+      /// int lstat64(const char *path, struct stat64 *buf);
+      lstat64,
+      /// void *malloc(size_t size);
+      malloc,
+      /// void *memalign(size_t boundary, size_t size);
+      memalign,
+      /// void *memccpy(void *s1, const void *s2, int c, size_t n);
+      memccpy,
+      /// void *memchr(const void *s, int c, size_t n);
+      memchr,
+      /// int memcmp(const void *s1, const void *s2, size_t n);
+      memcmp,
+      /// void *memcpy(void *s1, const void *s2, size_t n);
+      memcpy,
+      /// void *memmove(void *s1, const void *s2, size_t n);
+      memmove,
+      // void *memrchr(const void *s, int c, size_t n);
+      memrchr,
+      /// void *memset(void *b, int c, size_t len);
+      memset,
+      /// void memset_pattern16(void *b, const void *pattern16, size_t len);
+      memset_pattern16,
+      /// int mkdir(const char *path, mode_t mode);
+      mkdir,
+      /// time_t mktime(struct tm *timeptr);
+      mktime,
+      /// double modf(double x, double *iptr);
+      modf,
+      /// float modff(float, float *iptr);
+      modff,
+      /// long double modfl(long double value, long double *iptr);
+      modfl,
+      /// double nearbyint(double x);
+      nearbyint,
+      /// float nearbyintf(float x);
+      nearbyintf,
+      /// long double nearbyintl(long double x);
+      nearbyintl,
+      /// uint32_t ntohl(uint32_t netlong);
+      ntohl,
+      /// uint16_t ntohs(uint16_t netshort);
+      ntohs,
+      /// int open(const char *path, int oflag, ... );
+      open,
+      /// int open64(const char *filename, int flags[, mode_t mode])
+      open64,
+      /// DIR *opendir(const char *dirname);
+      opendir,
+      /// int pclose(FILE *stream);
+      pclose,
+      /// void perror(const char *s);
+      perror,
+      /// FILE *popen(const char *command, const char *mode);
+      popen,
+      /// int posix_memalign(void **memptr, size_t alignment, size_t size);
+      posix_memalign,
+      /// double pow(double x, double y);
+      pow,
+      /// float powf(float x, float y);
+      powf,
+      /// long double powl(long double x, long double y);
+      powl,
+      /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
+      pread,
+      /// int printf(const char *format, ...);
+      printf,
+      /// int putc(int c, FILE *stream);
+      putc,
+      /// int putchar(int c);
+      putchar,
+      /// int puts(const char *s);
+      puts,
+      /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
+      ///                off_t offset);
+      pwrite,
+      /// void qsort(void *base, size_t nel, size_t width,
+      ///            int (*compar)(const void *, const void *));
+      qsort,
+      /// ssize_t read(int fildes, void *buf, size_t nbyte);
+      read,
+      /// ssize_t readlink(const char *path, char *buf, size_t bufsize);
+      readlink,
+      /// void *realloc(void *ptr, size_t size);
+      realloc,
+      /// void *reallocf(void *ptr, size_t size);
+      reallocf,
+      /// char *realpath(const char *file_name, char *resolved_name);
+      realpath,
+      /// int remove(const char *path);
+      remove,
+      /// int rename(const char *old, const char *new);
+      rename,
+      /// void rewind(FILE *stream);
+      rewind,
+      /// double rint(double x);
+      rint,
+      /// float rintf(float x);
+      rintf,
+      /// long double rintl(long double x);
+      rintl,
+      /// int rmdir(const char *path);
+      rmdir,
+      /// double round(double x);
+      round,
+      /// float roundf(float x);
+      roundf,
+      /// long double roundl(long double x);
+      roundl,
+      /// int scanf(const char *restrict format, ... );
+      scanf,
+      /// void setbuf(FILE *stream, char *buf);
+      setbuf,
+      /// int setitimer(int which, const struct itimerval *value,
+      ///               struct itimerval *ovalue);
+      setitimer,
+      /// int setvbuf(FILE *stream, char *buf, int type, size_t size);
+      setvbuf,
+      /// double sin(double x);
+      sin,
+      /// float sinf(float x);
+      sinf,
+      /// double sinh(double x);
+      sinh,
+      /// float sinhf(float x);
+      sinhf,
+      /// long double sinhl(long double x);
+      sinhl,
+      /// long double sinl(long double x);
+      sinl,
+      /// int siprintf(char *str, const char *format, ...);
+      siprintf,
+      /// int snprintf(char *s, size_t n, const char *format, ...);
+      snprintf,
+      /// int sprintf(char *str, const char *format, ...);
+      sprintf,
+      /// double sqrt(double x);
+      sqrt,
+      /// float sqrtf(float x);
+      sqrtf,
+      /// long double sqrtl(long double x);
+      sqrtl,
+      /// int sscanf(const char *s, const char *format, ... );
+      sscanf,
+      /// int stat(const char *path, struct stat *buf);
+      stat,
+      /// int stat64(const char *path, struct stat64 *buf);
+      stat64,
+      /// int statvfs(const char *path, struct statvfs *buf);
+      statvfs,
+      /// int statvfs64(const char *path, struct statvfs64 *buf)
+      statvfs64,
+      /// char *stpcpy(char *s1, const char *s2);
+      stpcpy,
+      /// char *stpncpy(char *s1, const char *s2, size_t n);
+      stpncpy,
+      /// int strcasecmp(const char *s1, const char *s2);
+      strcasecmp,
+      /// char *strcat(char *s1, const char *s2);
+      strcat,
+      /// char *strchr(const char *s, int c);
+      strchr,
+      /// int strcmp(const char *s1, const char *s2);
+      strcmp,
+      /// int strcoll(const char *s1, const char *s2);
+      strcoll,
+      /// char *strcpy(char *s1, const char *s2);
+      strcpy,
+      /// size_t strcspn(const char *s1, const char *s2);
+      strcspn,
+      /// char *strdup(const char *s1);
+      strdup,
+      /// size_t strlen(const char *s);
+      strlen,
+      /// int strncasecmp(const char *s1, const char *s2, size_t n);
+      strncasecmp,
+      /// char *strncat(char *s1, const char *s2, size_t n);
+      strncat,
+      /// int strncmp(const char *s1, const char *s2, size_t n);
+      strncmp,
+      /// char *strncpy(char *s1, const char *s2, size_t n);
+      strncpy,
+      /// char *strndup(const char *s1, size_t n);
+      strndup,
+      /// size_t strnlen(const char *s, size_t maxlen);
+      strnlen,
+      /// char *strpbrk(const char *s1, const char *s2);
+      strpbrk,
+      /// char *strrchr(const char *s, int c);
+      strrchr,
+      /// size_t strspn(const char *s1, const char *s2);
+      strspn,
+      /// char *strstr(const char *s1, const char *s2);
+      strstr,
+      /// double strtod(const char *nptr, char **endptr);
+      strtod,
+      /// float strtof(const char *nptr, char **endptr);
+      strtof,
+      // char *strtok(char *s1, const char *s2);
+      strtok,
+      // char *strtok_r(char *s, const char *sep, char **lasts);
+      strtok_r,
+      /// long int strtol(const char *nptr, char **endptr, int base);
+      strtol,
+      /// long double strtold(const char *nptr, char **endptr);
+      strtold,
+      /// long long int strtoll(const char *nptr, char **endptr, int base);
+      strtoll,
+      /// unsigned long int strtoul(const char *nptr, char **endptr, int base);
+      strtoul,
+      /// unsigned long long int strtoull(const char *nptr, char **endptr,
+      ///                                 int base);
+      strtoull,
+      /// size_t strxfrm(char *s1, const char *s2, size_t n);
+      strxfrm,
+      /// int system(const char *command);
+      system,
+      /// double tan(double x);
+      tan,
+      /// float tanf(float x);
+      tanf,
+      /// double tanh(double x);
+      tanh,
+      /// float tanhf(float x);
+      tanhf,
+      /// long double tanhl(long double x);
+      tanhl,
+      /// long double tanl(long double x);
+      tanl,
+      /// clock_t times(struct tms *buffer);
+      times,
+      /// FILE *tmpfile(void);
+      tmpfile,
+      /// FILE *tmpfile64(void)
+      tmpfile64,
+      /// int toascii(int c);
+      toascii,
+      /// double trunc(double x);
+      trunc,
+      /// float truncf(float x);
+      truncf,
+      /// long double truncl(long double x);
+      truncl,
+      /// int uname(struct utsname *name);
+      uname,
+      /// int ungetc(int c, FILE *stream);
+      ungetc,
+      /// int unlink(const char *path);
+      unlink,
+      /// int unsetenv(const char *name);
+      unsetenv,
+      /// int utime(const char *path, const struct utimbuf *times);
+      utime,
+      /// int utimes(const char *path, const struct timeval times[2]);
+      utimes,
+      /// void *valloc(size_t size);
+      valloc,
+      /// int vfprintf(FILE *stream, const char *format, va_list ap);
+      vfprintf,
+      /// int vfscanf(FILE *stream, const char *format, va_list arg);
+      vfscanf,
+      /// int vprintf(const char *restrict format, va_list ap);
+      vprintf,
+      /// int vscanf(const char *format, va_list arg);
+      vscanf,
+      /// int vsnprintf(char *s, size_t n, const char *format, va_list ap);
+      vsnprintf,
+      /// int vsprintf(char *s, const char *format, va_list ap);
+      vsprintf,
+      /// int vsscanf(const char *s, const char *format, va_list arg);
+      vsscanf,
+      /// ssize_t write(int fildes, const void *buf, size_t nbyte);
+      write,
+
+      NumLibFuncs
+    };
+  }
+
+/// TargetLibraryInfo - This immutable pass captures information about what
+/// library functions are available for the current target, and allows a
+/// frontend to disable optimizations through -fno-builtin etc.
+class TargetLibraryInfo : public ImmutablePass {
+  virtual void anchor();
+  unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
+  llvm::DenseMap<unsigned, std::string> CustomNames;
+  static const char* StandardNames[LibFunc::NumLibFuncs];
+
+  enum AvailabilityState {
+    StandardName = 3, // (memset to all ones)
+    CustomName = 1,
+    Unavailable = 0  // (memset to all zeros)
+  };
+  void setState(LibFunc::Func F, AvailabilityState State) {
+    AvailableArray[F/4] &= ~(3 << 2*(F&3));
+    AvailableArray[F/4] |= State << 2*(F&3);
+  }
+  AvailabilityState getState(LibFunc::Func F) const {
+    return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
+  }
+
+public:
+  static char ID;
+  TargetLibraryInfo();
+  TargetLibraryInfo(const Triple &T);
+  explicit TargetLibraryInfo(const TargetLibraryInfo &TLI);
+  
+  /// getLibFunc - Search for a particular function name.  If it is one of the
+  /// known library functions, return true and set F to the corresponding value.
+  bool getLibFunc(StringRef funcName, LibFunc::Func &F) const;
+
+  /// has - This function is used by optimizations that want to match on or form
+  /// a given library function.
+  bool has(LibFunc::Func F) const {
+    return getState(F) != Unavailable;
+  }
+
+  /// hasOptimizedCodeGen - Return true if the function is both available as
+  /// a builtin and a candidate for optimized code generation.
+  bool hasOptimizedCodeGen(LibFunc::Func F) const {
+    if (getState(F) == Unavailable)
+      return false;
+    switch (F) {
+    default: break;
+    case LibFunc::copysign:  case LibFunc::copysignf:  case LibFunc::copysignl:
+    case LibFunc::fabs:      case LibFunc::fabsf:      case LibFunc::fabsl:
+    case LibFunc::sin:       case LibFunc::sinf:       case LibFunc::sinl:
+    case LibFunc::cos:       case LibFunc::cosf:       case LibFunc::cosl:
+    case LibFunc::sqrt:      case LibFunc::sqrtf:      case LibFunc::sqrtl:
+    case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
+                                                  case LibFunc::sqrtl_finite:
+    case LibFunc::fmax:      case LibFunc::fmaxf:      case LibFunc::fmaxl:
+    case LibFunc::fmin:      case LibFunc::fminf:      case LibFunc::fminl:
+    case LibFunc::floor:     case LibFunc::floorf:     case LibFunc::floorl:
+    case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
+    case LibFunc::ceil:      case LibFunc::ceilf:      case LibFunc::ceill:
+    case LibFunc::rint:      case LibFunc::rintf:      case LibFunc::rintl:
+    case LibFunc::round:     case LibFunc::roundf:     case LibFunc::roundl:
+    case LibFunc::trunc:     case LibFunc::truncf:     case LibFunc::truncl:
+    case LibFunc::log2:      case LibFunc::log2f:      case LibFunc::log2l:
+    case LibFunc::exp2:      case LibFunc::exp2f:      case LibFunc::exp2l:
+    case LibFunc::memcmp:    case LibFunc::strcmp:     case LibFunc::strcpy:
+    case LibFunc::stpcpy:    case LibFunc::strlen:     case LibFunc::strnlen:
+    case LibFunc::memchr:
+      return true;
+    }
+    return false;
+  }
+
+  StringRef getName(LibFunc::Func F) const {
+    AvailabilityState State = getState(F);
+    if (State == Unavailable)
+      return StringRef();
+    if (State == StandardName)
+      return StandardNames[F];
+    assert(State == CustomName);
+    return CustomNames.find(F)->second;
+  }
+
+  /// setUnavailable - this can be used by whatever sets up TargetLibraryInfo to
+  /// ban use of specific library functions.
+  void setUnavailable(LibFunc::Func F) {
+    setState(F, Unavailable);
+  }
+
+  void setAvailable(LibFunc::Func F) {
+    setState(F, StandardName);
+  }
+
+  void setAvailableWithName(LibFunc::Func F, StringRef Name) {
+    if (StandardNames[F] != Name) {
+      setState(F, CustomName);
+      CustomNames[F] = Name;
+      assert(CustomNames.find(F) != CustomNames.end());
+    } else {
+      setState(F, StandardName);
+    }
+  }
+
+  /// disableAllFunctions - This disables all builtins, which is used for
+  /// options like -fno-builtin.
+  void disableAllFunctions();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
new file mode 100644
index 0000000..ea9a48e
--- /dev/null
+++ b/include/llvm/Target/TargetLowering.h
@@ -0,0 +1,2603 @@
+//===-- llvm/Target/TargetLowering.h - Target Lowering Info -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes how to lower LLVM code to machine code.  This has two
+/// main components:
+///
+///  1. Which ValueTypes are natively supported by the target.
+///  2. Which operations are supported for supported ValueTypes.
+///  3. Cost thresholds for alternative implementations of certain operations.
+///
+/// In addition it has a few other components, like information about FP
+/// immediates.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERING_H
+#define LLVM_TARGET_TARGETLOWERING_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/DAGCombine.h"
+#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Target/TargetCallingConv.h"
+#include "llvm/Target/TargetMachine.h"
+#include <climits>
+#include <map>
+#include <vector>
+
+namespace llvm {
+  class CallInst;
+  class CCState;
+  class FastISel;
+  class FunctionLoweringInfo;
+  class ImmutableCallSite;
+  class IntrinsicInst;
+  class MachineBasicBlock;
+  class MachineFunction;
+  class MachineInstr;
+  class MachineJumpTableInfo;
+  class Mangler;
+  class MCContext;
+  class MCExpr;
+  class MCSymbol;
+  template<typename T> class SmallVectorImpl;
+  class DataLayout;
+  class TargetRegisterClass;
+  class TargetLibraryInfo;
+  class TargetLoweringObjectFile;
+  class Value;
+
+  namespace Sched {
+    enum Preference {
+      None,             // No preference
+      Source,           // Follow source order.
+      RegPressure,      // Scheduling for lowest register pressure.
+      Hybrid,           // Scheduling for both latency and register pressure.
+      ILP,              // Scheduling for ILP in low register pressure mode.
+      VLIW              // Scheduling for VLIW targets.
+    };
+  }
+
+/// This base class for TargetLowering contains the SelectionDAG-independent
+/// parts that can be used from the rest of CodeGen.
+class TargetLoweringBase {
+  TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+
+public:
+  /// This enum indicates whether operations are valid for a target, and if not,
+  /// what action should be used to make them valid.
+  enum LegalizeAction {
+    Legal,      // The target natively supports this operation.
+    Promote,    // This operation should be executed in a larger type.
+    Expand,     // Try to expand this to other ops, otherwise use a libcall.
+    Custom      // Use the LowerOperation hook to implement custom lowering.
+  };
+
+  /// This enum indicates whether a types are legal for a target, and if not,
+  /// what action should be used to make them valid.
+  enum LegalizeTypeAction {
+    TypeLegal,           // The target natively supports this type.
+    TypePromoteInteger,  // Replace this integer with a larger one.
+    TypeExpandInteger,   // Split this integer into two of half the size.
+    TypeSoftenFloat,     // Convert this float to a same size integer type.
+    TypeExpandFloat,     // Split this float into two of half the size.
+    TypeScalarizeVector, // Replace this one-element vector with its element.
+    TypeSplitVector,     // Split this vector into two of half the size.
+    TypeWidenVector      // This vector should be widened into a larger vector.
+  };
+
+  /// LegalizeKind holds the legalization kind that needs to happen to EVT
+  /// in order to type-legalize it.
+  typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
+
+  /// Enum that describes how the target represents true/false values.
+  enum BooleanContent {
+    UndefinedBooleanContent,    // Only bit 0 counts, the rest can hold garbage.
+    ZeroOrOneBooleanContent,        // All bits zero except for bit 0.
+    ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
+  };
+
+  /// Enum that describes what type of support for selects the target has.
+  enum SelectSupportKind {
+    ScalarValSelect,      // The target supports scalar selects (ex: cmov).
+    ScalarCondVectorVal,  // The target supports selects with a scalar condition
+                          // and vector values (ex: cmov).
+    VectorMaskSelect      // The target supports vector selects with a vector
+                          // mask (ex: x86 blends).
+  };
+
+  static ISD::NodeType getExtendForContent(BooleanContent Content) {
+    switch (Content) {
+    case UndefinedBooleanContent:
+      // Extend by adding rubbish bits.
+      return ISD::ANY_EXTEND;
+    case ZeroOrOneBooleanContent:
+      // Extend by adding zero bits.
+      return ISD::ZERO_EXTEND;
+    case ZeroOrNegativeOneBooleanContent:
+      // Extend by copying the sign bit.
+      return ISD::SIGN_EXTEND;
+    }
+    llvm_unreachable("Invalid content kind");
+  }
+
+  /// NOTE: The constructor takes ownership of TLOF.
+  explicit TargetLoweringBase(const TargetMachine &TM,
+                              const TargetLoweringObjectFile *TLOF);
+  virtual ~TargetLoweringBase();
+
+protected:
+  /// \brief Initialize all of the actions to default values.
+  void initActions();
+
+public:
+  const TargetMachine &getTargetMachine() const { return TM; }
+  const DataLayout *getDataLayout() const { return DL; }
+  const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
+
+  bool isBigEndian() const { return !IsLittleEndian; }
+  bool isLittleEndian() const { return IsLittleEndian; }
+
+  /// Return the pointer type for the given address space, defaults to
+  /// the pointer type from the data layout.
+  /// FIXME: The default needs to be removed once all the code is updated.
+  virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const;
+  unsigned getPointerSizeInBits(uint32_t AS = 0) const;
+  unsigned getPointerTypeSizeInBits(Type *Ty) const;
+  virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
+
+  EVT getShiftAmountTy(EVT LHSTy) const;
+
+  /// Returns the type to be used for the index operand of:
+  /// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT,
+  /// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR
+  virtual MVT getVectorIdxTy() const {
+    return getPointerTy();
+  }
+
+  /// Return true if the select operation is expensive for this target.
+  bool isSelectExpensive() const { return SelectIsExpensive; }
+
+  virtual bool isSelectSupported(SelectSupportKind /*kind*/) const {
+    return true;
+  }
+
+  /// Return true if multiple condition registers are available.
+  bool hasMultipleConditionRegisters() const {
+    return HasMultipleConditionRegisters;
+  }
+
+  /// Return true if the target has BitExtract instructions.
+  bool hasExtractBitsInsn() const { return HasExtractBitsInsn; }
+
+  /// Return the preferred vector type legalization action.
+  virtual TargetLoweringBase::LegalizeTypeAction
+  getPreferredVectorAction(EVT VT) const {
+    // The default action for one element vectors is to scalarize
+    if (VT.getVectorNumElements() == 1)
+      return TypeScalarizeVector;
+    // The default action for other vectors is to promote
+    return TypePromoteInteger;
+  }
+
+  // There are two general methods for expanding a BUILD_VECTOR node:
+  //  1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
+  //     them together.
+  //  2. Build the vector on the stack and then load it.
+  // If this function returns true, then method (1) will be used, subject to
+  // the constraint that all of the necessary shuffles are legal (as determined
+  // by isShuffleMaskLegal). If this function returns false, then method (2) is
+  // always used. The vector type, and the number of defined values, are
+  // provided.
+  virtual bool
+  shouldExpandBuildVectorWithShuffles(EVT /* VT */,
+                                      unsigned DefinedValues) const {
+    return DefinedValues < 3;
+  }
+
+  /// Return true if integer divide is usually cheaper than a sequence of
+  /// several shifts, adds, and multiplies for this target.
+  bool isIntDivCheap() const { return IntDivIsCheap; }
+
+  /// Returns true if target has indicated at least one type should be bypassed.
+  bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); }
+
+  /// Returns map of slow types for division or remainder with corresponding
+  /// fast types
+  const DenseMap<unsigned int, unsigned int> &getBypassSlowDivWidths() const {
+    return BypassSlowDivWidths;
+  }
+
+  /// Return true if pow2 div is cheaper than a chain of srl/add/sra.
+  bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+
+  /// Return true if Flow Control is an expensive operation that should be
+  /// avoided.
+  bool isJumpExpensive() const { return JumpIsExpensive; }
+
+  /// Return true if selects are only cheaper than branches if the branch is
+  /// unlikely to be predicted right.
+  bool isPredictableSelectExpensive() const {
+    return PredictableSelectIsExpensive;
+  }
+
+  /// isLoadBitCastBeneficial() - Return true if the following transform
+  /// is beneficial.
+  /// fold (conv (load x)) -> (load (conv*)x)
+  /// On architectures that don't natively support some vector loads efficiently,
+  /// casting the load to a smaller vector of larger types and loading
+  /// is more efficient, however, this can be undone by optimizations in
+  /// dag combiner.
+  virtual bool isLoadBitCastBeneficial(EVT /* Load */, EVT /* Bitcast */) const {
+    return true;
+  }
+
+  /// \brief Return if the target supports combining a
+  /// chain like:
+  /// \code
+  ///   %andResult = and %val1, #imm-with-one-bit-set;
+  ///   %icmpResult = icmp %andResult, 0
+  ///   br i1 %icmpResult, label %dest1, label %dest2
+  /// \endcode
+  /// into a single machine instruction of a form like:
+  /// \code
+  ///   brOnBitSet %register, #bitNumber, dest
+  /// \endcode
+  bool isMaskAndBranchFoldingLegal() const {
+    return MaskAndBranchFoldingIsLegal;
+  }
+
+  /// Return the ValueType of the result of SETCC operations.  Also used to
+  /// obtain the target's preferred type for the condition operand of SELECT and
+  /// BRCOND nodes.  In the case of BRCOND the argument passed is MVT::Other
+  /// since there are no other operands to get a type hint from.
+  virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
+
+  /// Return the ValueType for comparison libcalls. Comparions libcalls include
+  /// floating point comparion calls, and Ordered/Unordered check calls on
+  /// floating point numbers.
+  virtual
+  MVT::SimpleValueType getCmpLibcallReturnType() const;
+
+  /// For targets without i1 registers, this gives the nature of the high-bits
+  /// of boolean values held in types wider than i1.
+  ///
+  /// "Boolean values" are special true/false values produced by nodes like
+  /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND.
+  /// Not to be confused with general values promoted from i1.  Some cpus
+  /// distinguish between vectors of boolean and scalars; the isVec parameter
+  /// selects between the two kinds.  For example on X86 a scalar boolean should
+  /// be zero extended from i1, while the elements of a vector of booleans
+  /// should be sign extended from i1.
+  ///
+  /// Some cpus also treat floating point types the same way as they treat
+  /// vectors instead of the way they treat scalars.
+  BooleanContent getBooleanContents(bool isVec, bool isFloat) const {
+    if (isVec)
+      return BooleanVectorContents;
+    return isFloat ? BooleanFloatContents : BooleanContents;
+  }
+
+  BooleanContent getBooleanContents(EVT Type) const {
+    return getBooleanContents(Type.isVector(), Type.isFloatingPoint());
+  }
+
+  /// Return target scheduling preference.
+  Sched::Preference getSchedulingPreference() const {
+    return SchedPreferenceInfo;
+  }
+
+  /// Some scheduler, e.g. hybrid, can switch to different scheduling heuristics
+  /// for different nodes. This function returns the preference (or none) for
+  /// the given node.
+  virtual Sched::Preference getSchedulingPreference(SDNode *) const {
+    return Sched::None;
+  }
+
+  /// Return the register class that should be used for the specified value
+  /// type.
+  virtual const TargetRegisterClass *getRegClassFor(MVT VT) const {
+    const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];
+    assert(RC && "This value type is not natively supported!");
+    return RC;
+  }
+
+  /// Return the 'representative' register class for the specified value
+  /// type.
+  ///
+  /// The 'representative' register class is the largest legal super-reg
+  /// register class for the register class of the value type.  For example, on
+  /// i386 the rep register class for i8, i16, and i32 are GR32; while the rep
+  /// register class is GR64 on x86_64.
+  virtual const TargetRegisterClass *getRepRegClassFor(MVT VT) const {
+    const TargetRegisterClass *RC = RepRegClassForVT[VT.SimpleTy];
+    return RC;
+  }
+
+  /// Return the cost of the 'representative' register class for the specified
+  /// value type.
+  virtual uint8_t getRepRegClassCostFor(MVT VT) const {
+    return RepRegClassCostForVT[VT.SimpleTy];
+  }
+
+  /// Return true if the target has native support for the specified value type.
+  /// This means that it has a register that directly holds it without
+  /// promotions or expansions.
+  bool isTypeLegal(EVT VT) const {
+    assert(!VT.isSimple() ||
+           (unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
+    return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != nullptr;
+  }
+
+  class ValueTypeActionImpl {
+    /// ValueTypeActions - For each value type, keep a LegalizeTypeAction enum
+    /// that indicates how instruction selection should deal with the type.
+    uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
+
+  public:
+    ValueTypeActionImpl() {
+      std::fill(std::begin(ValueTypeActions), std::end(ValueTypeActions), 0);
+    }
+
+    LegalizeTypeAction getTypeAction(MVT VT) const {
+      return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
+    }
+
+    void setTypeAction(MVT VT, LegalizeTypeAction Action) {
+      unsigned I = VT.SimpleTy;
+      ValueTypeActions[I] = Action;
+    }
+  };
+
+  const ValueTypeActionImpl &getValueTypeActions() const {
+    return ValueTypeActions;
+  }
+
+  /// Return how we should legalize values of this type, either it is already
+  /// legal (return 'Legal') or we need to promote it to a larger type (return
+  /// 'Promote'), or we need to expand it into multiple registers of smaller
+  /// integer type (return 'Expand').  'Custom' is not an option.
+  LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const {
+    return getTypeConversion(Context, VT).first;
+  }
+  LegalizeTypeAction getTypeAction(MVT VT) const {
+    return ValueTypeActions.getTypeAction(VT);
+  }
+
+  /// For types supported by the target, this is an identity function.  For
+  /// types that must be promoted to larger types, this returns the larger type
+  /// to promote to.  For integer types that are larger than the largest integer
+  /// register, this contains one step in the expansion to get to the smaller
+  /// register. For illegal floating point types, this returns the integer type
+  /// to transform to.
+  EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const {
+    return getTypeConversion(Context, VT).second;
+  }
+
+  /// For types supported by the target, this is an identity function.  For
+  /// types that must be expanded (i.e. integer types that are larger than the
+  /// largest integer register or illegal floating point types), this returns
+  /// the largest legal type it will be expanded to.
+  EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const {
+    assert(!VT.isVector());
+    while (true) {
+      switch (getTypeAction(Context, VT)) {
+      case TypeLegal:
+        return VT;
+      case TypeExpandInteger:
+        VT = getTypeToTransformTo(Context, VT);
+        break;
+      default:
+        llvm_unreachable("Type is not legal nor is it to be expanded!");
+      }
+    }
+  }
+
+  /// Vector types are broken down into some number of legal first class types.
+  /// For example, EVT::v8f32 maps to 2 EVT::v4f32 with Altivec or SSE1, or 8
+  /// promoted EVT::f64 values with the X86 FP stack.  Similarly, EVT::v2i64
+  /// turns into 4 EVT::i32 values with both PPC and X86.
+  ///
+  /// This method returns the number of registers needed, and the VT for each
+  /// register.  It also returns the VT and quantity of the intermediate values
+  /// before they are promoted/expanded.
+  unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
+                                  EVT &IntermediateVT,
+                                  unsigned &NumIntermediates,
+                                  MVT &RegisterVT) const;
+
+  struct IntrinsicInfo {
+    unsigned     opc;         // target opcode
+    EVT          memVT;       // memory VT
+    const Value* ptrVal;      // value representing memory location
+    int          offset;      // offset off of ptrVal
+    unsigned     align;       // alignment
+    bool         vol;         // is volatile?
+    bool         readMem;     // reads memory?
+    bool         writeMem;    // writes memory?
+  };
+
+  /// Given an intrinsic, checks if on the target the intrinsic will need to map
+  /// to a MemIntrinsicNode (touches memory). If this is the case, it returns
+  /// true and store the intrinsic information into the IntrinsicInfo that was
+  /// passed to the function.
+  virtual bool getTgtMemIntrinsic(IntrinsicInfo &, const CallInst &,
+                                  unsigned /*Intrinsic*/) const {
+    return false;
+  }
+
+  /// Returns true if the target can instruction select the specified FP
+  /// immediate natively. If false, the legalizer will materialize the FP
+  /// immediate as a load from a constant pool.
+  virtual bool isFPImmLegal(const APFloat &/*Imm*/, EVT /*VT*/) const {
+    return false;
+  }
+
+  /// Targets can use this to indicate that they only support *some*
+  /// VECTOR_SHUFFLE operations, those with specific masks.  By default, if a
+  /// target supports the VECTOR_SHUFFLE node, all mask values are assumed to be
+  /// legal.
+  virtual bool isShuffleMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
+                                  EVT /*VT*/) const {
+    return true;
+  }
+
+  /// Returns true if the operation can trap for the value type.
+  ///
+  /// VT must be a legal type. By default, we optimistically assume most
+  /// operations don't trap except for divide and remainder.
+  virtual bool canOpTrap(unsigned Op, EVT VT) const;
+
+  /// Similar to isShuffleMaskLegal. This is used by Targets can use this to
+  /// indicate if there is a suitable VECTOR_SHUFFLE that can be used to replace
+  /// a VAND with a constant pool entry.
+  virtual bool isVectorClearMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
+                                      EVT /*VT*/) const {
+    return false;
+  }
+
+  /// Return how this operation should be treated: either it is legal, needs to
+  /// be promoted to a larger size, needs to be expanded to some other code
+  /// sequence, or the target has a custom expander for it.
+  LegalizeAction getOperationAction(unsigned Op, EVT VT) const {
+    if (VT.isExtended()) return Expand;
+    // If a target-specific SDNode requires legalization, require the target
+    // to provide custom legalization for it.
+    if (Op > array_lengthof(OpActions[0])) return Custom;
+    unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
+    return (LegalizeAction)OpActions[I][Op];
+  }
+
+  /// Return true if the specified operation is legal on this target or can be
+  /// made legal with custom lowering. This is used to help guide high-level
+  /// lowering decisions.
+  bool isOperationLegalOrCustom(unsigned Op, EVT VT) const {
+    return (VT == MVT::Other || isTypeLegal(VT)) &&
+      (getOperationAction(Op, VT) == Legal ||
+       getOperationAction(Op, VT) == Custom);
+  }
+
+  /// Return true if the specified operation is legal on this target or can be
+  /// made legal using promotion. This is used to help guide high-level lowering
+  /// decisions.
+  bool isOperationLegalOrPromote(unsigned Op, EVT VT) const {
+    return (VT == MVT::Other || isTypeLegal(VT)) &&
+      (getOperationAction(Op, VT) == Legal ||
+       getOperationAction(Op, VT) == Promote);
+  }
+
+  /// Return true if the specified operation is illegal on this target or
+  /// unlikely to be made legal with custom lowering. This is used to help guide
+  /// high-level lowering decisions.
+  bool isOperationExpand(unsigned Op, EVT VT) const {
+    return (!isTypeLegal(VT) || getOperationAction(Op, VT) == Expand);
+  }
+
+  /// Return true if the specified operation is legal on this target.
+  bool isOperationLegal(unsigned Op, EVT VT) const {
+    return (VT == MVT::Other || isTypeLegal(VT)) &&
+           getOperationAction(Op, VT) == Legal;
+  }
+
+  /// Return how this load with extension should be treated: either it is legal,
+  /// needs to be promoted to a larger size, needs to be expanded to some other
+  /// code sequence, or the target has a custom expander for it.
+  LegalizeAction getLoadExtAction(unsigned ExtType, MVT VT) const {
+    assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    return (LegalizeAction)LoadExtActions[VT.SimpleTy][ExtType];
+  }
+
+  /// Return true if the specified load with extension is legal on this target.
+  bool isLoadExtLegal(unsigned ExtType, EVT VT) const {
+    return VT.isSimple() &&
+      getLoadExtAction(ExtType, VT.getSimpleVT()) == Legal;
+  }
+
+  /// Return how this store with truncation should be treated: either it is
+  /// legal, needs to be promoted to a larger size, needs to be expanded to some
+  /// other code sequence, or the target has a custom expander for it.
+  LegalizeAction getTruncStoreAction(MVT ValVT, MVT MemVT) const {
+    assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    return (LegalizeAction)TruncStoreActions[ValVT.SimpleTy]
+                                            [MemVT.SimpleTy];
+  }
+
+  /// Return true if the specified store with truncation is legal on this
+  /// target.
+  bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const {
+    return isTypeLegal(ValVT) && MemVT.isSimple() &&
+      getTruncStoreAction(ValVT.getSimpleVT(), MemVT.getSimpleVT()) == Legal;
+  }
+
+  /// Return how the indexed load should be treated: either it is legal, needs
+  /// to be promoted to a larger size, needs to be expanded to some other code
+  /// sequence, or the target has a custom expander for it.
+  LegalizeAction
+  getIndexedLoadAction(unsigned IdxMode, MVT VT) const {
+    assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    unsigned Ty = (unsigned)VT.SimpleTy;
+    return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
+  }
+
+  /// Return true if the specified indexed load is legal on this target.
+  bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
+    return VT.isSimple() &&
+      (getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Legal ||
+       getIndexedLoadAction(IdxMode, VT.getSimpleVT()) == Custom);
+  }
+
+  /// Return how the indexed store should be treated: either it is legal, needs
+  /// to be promoted to a larger size, needs to be expanded to some other code
+  /// sequence, or the target has a custom expander for it.
+  LegalizeAction
+  getIndexedStoreAction(unsigned IdxMode, MVT VT) const {
+    assert(IdxMode < ISD::LAST_INDEXED_MODE && VT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    unsigned Ty = (unsigned)VT.SimpleTy;
+    return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
+  }
+
+  /// Return true if the specified indexed load is legal on this target.
+  bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
+    return VT.isSimple() &&
+      (getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Legal ||
+       getIndexedStoreAction(IdxMode, VT.getSimpleVT()) == Custom);
+  }
+
+  /// Return how the condition code should be treated: either it is legal, needs
+  /// to be expanded to some other code sequence, or the target has a custom
+  /// expander for it.
+  LegalizeAction
+  getCondCodeAction(ISD::CondCode CC, MVT VT) const {
+    assert((unsigned)CC < array_lengthof(CondCodeActions) &&
+           ((unsigned)VT.SimpleTy >> 4) < array_lengthof(CondCodeActions[0]) &&
+           "Table isn't big enough!");
+    // See setCondCodeAction for how this is encoded.
+    uint32_t Shift = 2 * (VT.SimpleTy & 0xF);
+    uint32_t Value = CondCodeActions[CC][VT.SimpleTy >> 4];
+    LegalizeAction Action = (LegalizeAction) ((Value >> Shift) & 0x3);
+    assert(Action != Promote && "Can't promote condition code!");
+    return Action;
+  }
+
+  /// Return true if the specified condition code is legal on this target.
+  bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+    return
+      getCondCodeAction(CC, VT) == Legal ||
+      getCondCodeAction(CC, VT) == Custom;
+  }
+
+
+  /// If the action for this operation is to promote, this method returns the
+  /// ValueType to promote to.
+  MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
+    assert(getOperationAction(Op, VT) == Promote &&
+           "This operation isn't promoted!");
+
+    // See if this has an explicit type specified.
+    std::map<std::pair<unsigned, MVT::SimpleValueType>,
+             MVT::SimpleValueType>::const_iterator PTTI =
+      PromoteToType.find(std::make_pair(Op, VT.SimpleTy));
+    if (PTTI != PromoteToType.end()) return PTTI->second;
+
+    assert((VT.isInteger() || VT.isFloatingPoint()) &&
+           "Cannot autopromote this type, add it with AddPromotedToType.");
+
+    MVT NVT = VT;
+    do {
+      NVT = (MVT::SimpleValueType)(NVT.SimpleTy+1);
+      assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
+             "Didn't find type to promote to!");
+    } while (!isTypeLegal(NVT) ||
+              getOperationAction(Op, NVT) == Promote);
+    return NVT;
+  }
+
+  /// Return the EVT corresponding to this LLVM type.  This is fixed by the LLVM
+  /// operations except for the pointer size.  If AllowUnknown is true, this
+  /// will return MVT::Other for types with no EVT counterpart (e.g. structs),
+  /// otherwise it will assert.
+  EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
+    // Lower scalar pointers to native pointer types.
+    if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+      return getPointerTy(PTy->getAddressSpace());
+
+    if (Ty->isVectorTy()) {
+      VectorType *VTy = cast<VectorType>(Ty);
+      Type *Elm = VTy->getElementType();
+      // Lower vectors of pointers to native pointer types.
+      if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
+        EVT PointerTy(getPointerTy(PT->getAddressSpace()));
+        Elm = PointerTy.getTypeForEVT(Ty->getContext());
+      }
+
+      return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
+                       VTy->getNumElements());
+    }
+    return EVT::getEVT(Ty, AllowUnknown);
+  }
+
+  /// Return the MVT corresponding to this LLVM type. See getValueType.
+  MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const {
+    return getValueType(Ty, AllowUnknown).getSimpleVT();
+  }
+
+  /// Return the desired alignment for ByVal or InAlloca aggregate function
+  /// arguments in the caller parameter area.  This is the actual alignment, not
+  /// its logarithm.
+  virtual unsigned getByValTypeAlignment(Type *Ty) const;
+
+  /// Return the type of registers that this ValueType will eventually require.
+  MVT getRegisterType(MVT VT) const {
+    assert((unsigned)VT.SimpleTy < array_lengthof(RegisterTypeForVT));
+    return RegisterTypeForVT[VT.SimpleTy];
+  }
+
+  /// Return the type of registers that this ValueType will eventually require.
+  MVT getRegisterType(LLVMContext &Context, EVT VT) const {
+    if (VT.isSimple()) {
+      assert((unsigned)VT.getSimpleVT().SimpleTy <
+                array_lengthof(RegisterTypeForVT));
+      return RegisterTypeForVT[VT.getSimpleVT().SimpleTy];
+    }
+    if (VT.isVector()) {
+      EVT VT1;
+      MVT RegisterVT;
+      unsigned NumIntermediates;
+      (void)getVectorTypeBreakdown(Context, VT, VT1,
+                                   NumIntermediates, RegisterVT);
+      return RegisterVT;
+    }
+    if (VT.isInteger()) {
+      return getRegisterType(Context, getTypeToTransformTo(Context, VT));
+    }
+    llvm_unreachable("Unsupported extended type!");
+  }
+
+  /// Return the number of registers that this ValueType will eventually
+  /// require.
+  ///
+  /// This is one for any types promoted to live in larger registers, but may be
+  /// more than one for types (like i64) that are split into pieces.  For types
+  /// like i140, which are first promoted then expanded, it is the number of
+  /// registers needed to hold all the bits of the original type.  For an i140
+  /// on a 32 bit machine this means 5 registers.
+  unsigned getNumRegisters(LLVMContext &Context, EVT VT) const {
+    if (VT.isSimple()) {
+      assert((unsigned)VT.getSimpleVT().SimpleTy <
+                array_lengthof(NumRegistersForVT));
+      return NumRegistersForVT[VT.getSimpleVT().SimpleTy];
+    }
+    if (VT.isVector()) {
+      EVT VT1;
+      MVT VT2;
+      unsigned NumIntermediates;
+      return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2);
+    }
+    if (VT.isInteger()) {
+      unsigned BitWidth = VT.getSizeInBits();
+      unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits();
+      return (BitWidth + RegWidth - 1) / RegWidth;
+    }
+    llvm_unreachable("Unsupported extended type!");
+  }
+
+  /// If true, then instruction selection should seek to shrink the FP constant
+  /// of the specified type to a smaller type in order to save space and / or
+  /// reduce runtime.
+  virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
+
+  /// When splitting a value of the specified type into parts, does the Lo
+  /// or Hi part come first?  This usually follows the endianness, except
+  /// for ppcf128, where the Hi part always comes first.
+  bool hasBigEndianPartOrdering(EVT VT) const {
+    return isBigEndian() || VT == MVT::ppcf128;
+  }
+
+  /// If true, the target has custom DAG combine transformations that it can
+  /// perform for the specified node.
+  bool hasTargetDAGCombine(ISD::NodeType NT) const {
+    assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
+    return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7));
+  }
+
+  /// \brief Get maximum # of store operations permitted for llvm.memset
+  ///
+  /// This function returns the maximum number of store operations permitted
+  /// to replace a call to llvm.memset. The value is set by the target at the
+  /// performance threshold for such a replacement. If OptSize is true,
+  /// return the limit for functions that have OptSize attribute.
+  unsigned getMaxStoresPerMemset(bool OptSize) const {
+    return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset;
+  }
+
+  /// \brief Get maximum # of store operations permitted for llvm.memcpy
+  ///
+  /// This function returns the maximum number of store operations permitted
+  /// to replace a call to llvm.memcpy. The value is set by the target at the
+  /// performance threshold for such a replacement. If OptSize is true,
+  /// return the limit for functions that have OptSize attribute.
+  unsigned getMaxStoresPerMemcpy(bool OptSize) const {
+    return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy;
+  }
+
+  /// \brief Get maximum # of store operations permitted for llvm.memmove
+  ///
+  /// This function returns the maximum number of store operations permitted
+  /// to replace a call to llvm.memmove. The value is set by the target at the
+  /// performance threshold for such a replacement. If OptSize is true,
+  /// return the limit for functions that have OptSize attribute.
+  unsigned getMaxStoresPerMemmove(bool OptSize) const {
+    return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove;
+  }
+
+  /// \brief Determine if the target supports unaligned memory accesses.
+  ///
+  /// This function returns true if the target allows unaligned memory accesses
+  /// of the specified type in the given address space. If true, it also returns
+  /// whether the unaligned memory access is "fast" in the third argument by
+  /// reference. This is used, for example, in situations where an array
+  /// copy/move/set is converted to a sequence of store operations. Its use
+  /// helps to ensure that such replacements don't generate code that causes an
+  /// alignment error (trap) on the target machine.
+  virtual bool allowsUnalignedMemoryAccesses(EVT,
+                                             unsigned AddrSpace = 0,
+                                             bool * /*Fast*/ = nullptr) const {
+    return false;
+  }
+
+  /// Returns the target specific optimal type for load and store operations as
+  /// a result of memset, memcpy, and memmove lowering.
+  ///
+  /// If DstAlign is zero that means it's safe to destination alignment can
+  /// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
+  /// a need to check it against alignment requirement, probably because the
+  /// source does not need to be loaded. If 'IsMemset' is true, that means it's
+  /// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
+  /// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
+  /// does not need to be loaded.  It returns EVT::Other if the type should be
+  /// determined using generic target-independent logic.
+  virtual EVT getOptimalMemOpType(uint64_t /*Size*/,
+                                  unsigned /*DstAlign*/, unsigned /*SrcAlign*/,
+                                  bool /*IsMemset*/,
+                                  bool /*ZeroMemset*/,
+                                  bool /*MemcpyStrSrc*/,
+                                  MachineFunction &/*MF*/) const {
+    return MVT::Other;
+  }
+
+  /// Returns true if it's safe to use load / store of the specified type to
+  /// expand memcpy / memset inline.
+  ///
+  /// This is mostly true for all types except for some special cases. For
+  /// example, on X86 targets without SSE2 f64 load / store are done with fldl /
+  /// fstpl which also does type conversion. Note the specified type doesn't
+  /// have to be legal as the hook is used before type legalization.
+  virtual bool isSafeMemOpType(MVT /*VT*/) const { return true; }
+
+  /// Determine if we should use _setjmp or setjmp to implement llvm.setjmp.
+  bool usesUnderscoreSetJmp() const {
+    return UseUnderscoreSetJmp;
+  }
+
+  /// Determine if we should use _longjmp or longjmp to implement llvm.longjmp.
+  bool usesUnderscoreLongJmp() const {
+    return UseUnderscoreLongJmp;
+  }
+
+  /// Return whether the target can generate code for jump tables.
+  bool supportJumpTables() const {
+    return SupportJumpTables;
+  }
+
+  /// Return integer threshold on number of blocks to use jump tables rather
+  /// than if sequence.
+  int getMinimumJumpTableEntries() const {
+    return MinimumJumpTableEntries;
+  }
+
+  /// If a physical register, this specifies the register that
+  /// llvm.savestack/llvm.restorestack should save and restore.
+  unsigned getStackPointerRegisterToSaveRestore() const {
+    return StackPointerRegisterToSaveRestore;
+  }
+
+  /// If a physical register, this returns the register that receives the
+  /// exception address on entry to a landing pad.
+  unsigned getExceptionPointerRegister() const {
+    return ExceptionPointerRegister;
+  }
+
+  /// If a physical register, this returns the register that receives the
+  /// exception typeid on entry to a landing pad.
+  unsigned getExceptionSelectorRegister() const {
+    return ExceptionSelectorRegister;
+  }
+
+  /// Returns the target's jmp_buf size in bytes (if never set, the default is
+  /// 200)
+  unsigned getJumpBufSize() const {
+    return JumpBufSize;
+  }
+
+  /// Returns the target's jmp_buf alignment in bytes (if never set, the default
+  /// is 0)
+  unsigned getJumpBufAlignment() const {
+    return JumpBufAlignment;
+  }
+
+  /// Return the minimum stack alignment of an argument.
+  unsigned getMinStackArgumentAlignment() const {
+    return MinStackArgumentAlignment;
+  }
+
+  /// Return the minimum function alignment.
+  unsigned getMinFunctionAlignment() const {
+    return MinFunctionAlignment;
+  }
+
+  /// Return the preferred function alignment.
+  unsigned getPrefFunctionAlignment() const {
+    return PrefFunctionAlignment;
+  }
+
+  /// Return the preferred loop alignment.
+  unsigned getPrefLoopAlignment() const {
+    return PrefLoopAlignment;
+  }
+
+  /// Return whether the DAG builder should automatically insert fences and
+  /// reduce ordering for atomics.
+  bool getInsertFencesForAtomic() const {
+    return InsertFencesForAtomic;
+  }
+
+  /// Return true if the target stores stack protector cookies at a fixed offset
+  /// in some non-standard address space, and populates the address space and
+  /// offset as appropriate.
+  virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/,
+                                      unsigned &/*Offset*/) const {
+    return false;
+  }
+
+  /// Returns the maximal possible offset which can be used for loads / stores
+  /// from the global.
+  virtual unsigned getMaximalGlobalOffset() const {
+    return 0;
+  }
+
+  /// Returns true if a cast between SrcAS and DestAS is a noop.
+  virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
+    return false;
+  }
+
+  //===--------------------------------------------------------------------===//
+  /// \name Helpers for TargetTransformInfo implementations
+  /// @{
+
+  /// Get the ISD node that corresponds to the Instruction class opcode.
+  int InstructionOpcodeToISD(unsigned Opcode) const;
+
+  /// Estimate the cost of type-legalization and the legalized type.
+  std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
+
+  /// @}
+
+  //===--------------------------------------------------------------------===//
+  /// \name Helpers for load-linked/store-conditional atomic expansion.
+  /// @{
+
+  /// Perform a load-linked operation on Addr, returning a "Value *" with the
+  /// corresponding pointee type. This may entail some non-trivial operations to
+  /// truncate or reconstruct types that will be illegal in the backend. See
+  /// ARMISelLowering for an example implementation.
+  virtual Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
+                                AtomicOrdering Ord) const {
+    llvm_unreachable("Load linked unimplemented on this target");
+  }
+
+  /// Perform a store-conditional operation to Addr. Return the status of the
+  /// store. This should be 0 if the store succeeded, non-zero otherwise.
+  virtual Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
+                                      Value *Addr, AtomicOrdering Ord) const {
+    llvm_unreachable("Store conditional unimplemented on this target");
+  }
+
+  /// Return true if the given (atomic) instruction should be expanded by the
+  /// IR-level AtomicExpandLoadLinked pass into a loop involving
+  /// load-linked/store-conditional pairs. Atomic stores will be expanded in the
+  /// same way as "atomic xchg" operations which ignore their output if needed.
+  virtual bool shouldExpandAtomicInIR(Instruction *Inst) const {
+    return false;
+  }
+
+
+  //===--------------------------------------------------------------------===//
+  // TargetLowering Configuration Methods - These methods should be invoked by
+  // the derived class constructor to configure this object for the target.
+  //
+
+  /// \brief Reset the operation actions based on target options.
+  virtual void resetOperationActions() {}
+
+protected:
+  /// Specify how the target extends the result of integer and floating point
+  /// boolean values from i1 to a wider type.  See getBooleanContents.
+  void setBooleanContents(BooleanContent Ty) {
+    BooleanContents = Ty;
+    BooleanFloatContents = Ty;
+  }
+
+  /// Specify how the target extends the result of integer and floating point
+  /// boolean values from i1 to a wider type.  See getBooleanContents.
+  void setBooleanContents(BooleanContent IntTy, BooleanContent FloatTy) {
+    BooleanContents = IntTy;
+    BooleanFloatContents = FloatTy;
+  }
+
+  /// Specify how the target extends the result of a vector boolean value from a
+  /// vector of i1 to a wider type.  See getBooleanContents.
+  void setBooleanVectorContents(BooleanContent Ty) {
+    BooleanVectorContents = Ty;
+  }
+
+  /// Specify the target scheduling preference.
+  void setSchedulingPreference(Sched::Preference Pref) {
+    SchedPreferenceInfo = Pref;
+  }
+
+  /// Indicate whether this target prefers to use _setjmp to implement
+  /// llvm.setjmp or the version without _.  Defaults to false.
+  void setUseUnderscoreSetJmp(bool Val) {
+    UseUnderscoreSetJmp = Val;
+  }
+
+  /// Indicate whether this target prefers to use _longjmp to implement
+  /// llvm.longjmp or the version without _.  Defaults to false.
+  void setUseUnderscoreLongJmp(bool Val) {
+    UseUnderscoreLongJmp = Val;
+  }
+
+  /// Indicate whether the target can generate code for jump tables.
+  void setSupportJumpTables(bool Val) {
+    SupportJumpTables = Val;
+  }
+
+  /// Indicate the number of blocks to generate jump tables rather than if
+  /// sequence.
+  void setMinimumJumpTableEntries(int Val) {
+    MinimumJumpTableEntries = Val;
+  }
+
+  /// If set to a physical register, this specifies the register that
+  /// llvm.savestack/llvm.restorestack should save and restore.
+  void setStackPointerRegisterToSaveRestore(unsigned R) {
+    StackPointerRegisterToSaveRestore = R;
+  }
+
+  /// If set to a physical register, this sets the register that receives the
+  /// exception address on entry to a landing pad.
+  void setExceptionPointerRegister(unsigned R) {
+    ExceptionPointerRegister = R;
+  }
+
+  /// If set to a physical register, this sets the register that receives the
+  /// exception typeid on entry to a landing pad.
+  void setExceptionSelectorRegister(unsigned R) {
+    ExceptionSelectorRegister = R;
+  }
+
+  /// Tells the code generator not to expand operations into sequences that use
+  /// the select operations if possible.
+  void setSelectIsExpensive(bool isExpensive = true) {
+    SelectIsExpensive = isExpensive;
+  }
+
+  /// Tells the code generator that the target has multiple (allocatable)
+  /// condition registers that can be used to store the results of comparisons
+  /// for use by selects and conditional branches. With multiple condition
+  /// registers, the code generator will not aggressively sink comparisons into
+  /// the blocks of their users.
+  void setHasMultipleConditionRegisters(bool hasManyRegs = true) {
+    HasMultipleConditionRegisters = hasManyRegs;
+  }
+
+  /// Tells the code generator that the target has BitExtract instructions.
+  /// The code generator will aggressively sink "shift"s into the blocks of
+  /// their users if the users will generate "and" instructions which can be
+  /// combined with "shift" to BitExtract instructions.
+  void setHasExtractBitsInsn(bool hasExtractInsn = true) {
+    HasExtractBitsInsn = hasExtractInsn;
+  }
+
+  /// Tells the code generator not to expand sequence of operations into a
+  /// separate sequences that increases the amount of flow control.
+  void setJumpIsExpensive(bool isExpensive = true) {
+    JumpIsExpensive = isExpensive;
+  }
+
+  /// Tells the code generator that integer divide is expensive, and if
+  /// possible, should be replaced by an alternate sequence of instructions not
+  /// containing an integer divide.
+  void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
+
+  /// Tells the code generator which bitwidths to bypass.
+  void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
+    BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
+  }
+
+  /// Tells the code generator that it shouldn't generate srl/add/sra for a
+  /// signed divide by power of two, and let the target handle it.
+  void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
+
+  /// Add the specified register class as an available regclass for the
+  /// specified value type. This indicates the selector can handle values of
+  /// that class natively.
+  void addRegisterClass(MVT VT, const TargetRegisterClass *RC) {
+    assert((unsigned)VT.SimpleTy < array_lengthof(RegClassForVT));
+    AvailableRegClasses.push_back(std::make_pair(VT, RC));
+    RegClassForVT[VT.SimpleTy] = RC;
+  }
+
+  /// Remove all register classes.
+  void clearRegisterClasses() {
+    memset(RegClassForVT, 0,MVT::LAST_VALUETYPE * sizeof(TargetRegisterClass*));
+
+    AvailableRegClasses.clear();
+  }
+
+  /// \brief Remove all operation actions.
+  void clearOperationActions() {
+  }
+
+  /// Return the largest legal super-reg register class of the register class
+  /// for the specified type and its associated "cost".
+  virtual std::pair<const TargetRegisterClass*, uint8_t>
+  findRepresentativeClass(MVT VT) const;
+
+  /// Once all of the register classes are added, this allows us to compute
+  /// derived properties we expose.
+  void computeRegisterProperties();
+
+  /// Indicate that the specified operation does not work with the specified
+  /// type and indicate what to do about it.
+  void setOperationAction(unsigned Op, MVT VT,
+                          LegalizeAction Action) {
+    assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+    OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
+  }
+
+  /// Indicate that the specified load with extension does not work with the
+  /// specified type and indicate what to do about it.
+  void setLoadExtAction(unsigned ExtType, MVT VT,
+                        LegalizeAction Action) {
+    assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
+  }
+
+  /// Indicate that the specified truncating store does not work with the
+  /// specified type and indicate what to do about it.
+  void setTruncStoreAction(MVT ValVT, MVT MemVT,
+                           LegalizeAction Action) {
+    assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
+           "Table isn't big enough!");
+    TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
+  }
+
+  /// Indicate that the specified indexed load does or does not work with the
+  /// specified type and indicate what to do abort it.
+  ///
+  /// NOTE: All indexed mode loads are initialized to Expand in
+  /// TargetLowering.cpp
+  void setIndexedLoadAction(unsigned IdxMode, MVT VT,
+                            LegalizeAction Action) {
+    assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+           (unsigned)Action < 0xf && "Table isn't big enough!");
+    // Load action are kept in the upper half.
+    IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0;
+    IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4;
+  }
+
+  /// Indicate that the specified indexed store does or does not work with the
+  /// specified type and indicate what to do about it.
+  ///
+  /// NOTE: All indexed mode stores are initialized to Expand in
+  /// TargetLowering.cpp
+  void setIndexedStoreAction(unsigned IdxMode, MVT VT,
+                             LegalizeAction Action) {
+    assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+           (unsigned)Action < 0xf && "Table isn't big enough!");
+    // Store action are kept in the lower half.
+    IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f;
+    IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action);
+  }
+
+  /// Indicate that the specified condition code is or isn't supported on the
+  /// target and indicate what to do about it.
+  void setCondCodeAction(ISD::CondCode CC, MVT VT,
+                         LegalizeAction Action) {
+    assert(VT < MVT::LAST_VALUETYPE &&
+           (unsigned)CC < array_lengthof(CondCodeActions) &&
+           "Table isn't big enough!");
+    /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 32-bit
+    /// value and the upper 27 bits index into the second dimension of the array
+    /// to select what 32-bit value to use.
+    uint32_t Shift = 2 * (VT.SimpleTy & 0xF);
+    CondCodeActions[CC][VT.SimpleTy >> 4] &= ~((uint32_t)0x3 << Shift);
+    CondCodeActions[CC][VT.SimpleTy >> 4] |= (uint32_t)Action << Shift;
+  }
+
+  /// If Opc/OrigVT is specified as being promoted, the promotion code defaults
+  /// to trying a larger integer/fp until it can find one that works. If that
+  /// default is insufficient, this method can be used by the target to override
+  /// the default.
+  void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT) {
+    PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy;
+  }
+
+  /// Targets should invoke this method for each target independent node that
+  /// they want to provide a custom DAG combiner for by implementing the
+  /// PerformDAGCombine virtual method.
+  void setTargetDAGCombine(ISD::NodeType NT) {
+    assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
+    TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
+  }
+
+  /// Set the target's required jmp_buf buffer size (in bytes); default is 200
+  void setJumpBufSize(unsigned Size) {
+    JumpBufSize = Size;
+  }
+
+  /// Set the target's required jmp_buf buffer alignment (in bytes); default is
+  /// 0
+  void setJumpBufAlignment(unsigned Align) {
+    JumpBufAlignment = Align;
+  }
+
+  /// Set the target's minimum function alignment (in log2(bytes))
+  void setMinFunctionAlignment(unsigned Align) {
+    MinFunctionAlignment = Align;
+  }
+
+  /// Set the target's preferred function alignment.  This should be set if
+  /// there is a performance benefit to higher-than-minimum alignment (in
+  /// log2(bytes))
+  void setPrefFunctionAlignment(unsigned Align) {
+    PrefFunctionAlignment = Align;
+  }
+
+  /// Set the target's preferred loop alignment. Default alignment is zero, it
+  /// means the target does not care about loop alignment.  The alignment is
+  /// specified in log2(bytes).
+  void setPrefLoopAlignment(unsigned Align) {
+    PrefLoopAlignment = Align;
+  }
+
+  /// Set the minimum stack alignment of an argument (in log2(bytes)).
+  void setMinStackArgumentAlignment(unsigned Align) {
+    MinStackArgumentAlignment = Align;
+  }
+
+  /// Set if the DAG builder should automatically insert fences and reduce the
+  /// order of atomic memory operations to Monotonic.
+  void setInsertFencesForAtomic(bool fence) {
+    InsertFencesForAtomic = fence;
+  }
+
+public:
+  //===--------------------------------------------------------------------===//
+  // Addressing mode description hooks (used by LSR etc).
+  //
+
+  /// CodeGenPrepare sinks address calculations into the same BB as Load/Store
+  /// instructions reading the address. This allows as much computation as
+  /// possible to be done in the address mode for that operand. This hook lets
+  /// targets also pass back when this should be done on intrinsics which
+  /// load/store.
+  virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/,
+                                    SmallVectorImpl<Value*> &/*Ops*/,
+                                    Type *&/*AccessTy*/) const {
+    return false;
+  }
+
+  /// This represents an addressing mode of:
+  ///    BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
+  /// If BaseGV is null,  there is no BaseGV.
+  /// If BaseOffs is zero, there is no base offset.
+  /// If HasBaseReg is false, there is no base register.
+  /// If Scale is zero, there is no ScaleReg.  Scale of 1 indicates a reg with
+  /// no scale.
+  struct AddrMode {
+    GlobalValue *BaseGV;
+    int64_t      BaseOffs;
+    bool         HasBaseReg;
+    int64_t      Scale;
+    AddrMode() : BaseGV(nullptr), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+  };
+
+  /// Return true if the addressing mode represented by AM is legal for this
+  /// target, for a load/store of the specified type.
+  ///
+  /// The type may be VoidTy, in which case only return true if the addressing
+  /// mode is legal for a load/store of any legal type.  TODO: Handle
+  /// pre/postinc as well.
+  virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const;
+
+  /// \brief Return the cost of the scaling factor used in the addressing mode
+  /// represented by AM for this target, for a load/store of the specified type.
+  ///
+  /// If the AM is supported, the return value must be >= 0.
+  /// If the AM is not supported, it returns a negative value.
+  /// TODO: Handle pre/postinc as well.
+  virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty) const {
+    // Default: assume that any scaling factor used in a legal AM is free.
+    if (isLegalAddressingMode(AM, Ty)) return 0;
+    return -1;
+  }
+
+  /// Return true if the specified immediate is legal icmp immediate, that is
+  /// the target has icmp instructions which can compare a register against the
+  /// immediate without having to materialize the immediate into a register.
+  virtual bool isLegalICmpImmediate(int64_t) const {
+    return true;
+  }
+
+  /// Return true if the specified immediate is legal add immediate, that is the
+  /// target has add instructions which can add a register with the immediate
+  /// without having to materialize the immediate into a register.
+  virtual bool isLegalAddImmediate(int64_t) const {
+    return true;
+  }
+
+  /// Return true if it's significantly cheaper to shift a vector by a uniform
+  /// scalar than by an amount which will vary across each lane. On x86, for
+  /// example, there is a "psllw" instruction for the former case, but no simple
+  /// instruction for a general "a << b" operation on vectors.
+  virtual bool isVectorShiftByScalarCheap(Type *Ty) const {
+    return false;
+  }
+
+  /// Return true if it's free to truncate a value of type Ty1 to type
+  /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
+  /// by referencing its sub-register AX.
+  virtual bool isTruncateFree(Type * /*Ty1*/, Type * /*Ty2*/) const {
+    return false;
+  }
+
+  /// Return true if a truncation from Ty1 to Ty2 is permitted when deciding
+  /// whether a call is in tail position. Typically this means that both results
+  /// would be assigned to the same register or stack slot, but it could mean
+  /// the target performs adequate checks of its own before proceeding with the
+  /// tail call.
+  virtual bool allowTruncateForTailCall(Type * /*Ty1*/, Type * /*Ty2*/) const {
+    return false;
+  }
+
+  virtual bool isTruncateFree(EVT /*VT1*/, EVT /*VT2*/) const {
+    return false;
+  }
+
+  /// Return true if any actual instruction that defines a value of type Ty1
+  /// implicitly zero-extends the value to Ty2 in the result register.
+  ///
+  /// This does not necessarily include registers defined in unknown ways, such
+  /// as incoming arguments, or copies from unknown virtual registers. Also, if
+  /// isTruncateFree(Ty2, Ty1) is true, this does not necessarily apply to
+  /// truncate instructions. e.g. on x86-64, all instructions that define 32-bit
+  /// values implicit zero-extend the result out to 64 bits.
+  virtual bool isZExtFree(Type * /*Ty1*/, Type * /*Ty2*/) const {
+    return false;
+  }
+
+  virtual bool isZExtFree(EVT /*VT1*/, EVT /*VT2*/) const {
+    return false;
+  }
+
+  /// Return true if the target supplies and combines to a paired load
+  /// two loaded values of type LoadedType next to each other in memory.
+  /// RequiredAlignment gives the minimal alignment constraints that must be met
+  /// to be able to select this paired load.
+  ///
+  /// This information is *not* used to generate actual paired loads, but it is
+  /// used to generate a sequence of loads that is easier to combine into a
+  /// paired load.
+  /// For instance, something like this:
+  /// a = load i64* addr
+  /// b = trunc i64 a to i32
+  /// c = lshr i64 a, 32
+  /// d = trunc i64 c to i32
+  /// will be optimized into:
+  /// b = load i32* addr1
+  /// d = load i32* addr2
+  /// Where addr1 = addr2 +/- sizeof(i32).
+  ///
+  /// In other words, unless the target performs a post-isel load combining,
+  /// this information should not be provided because it will generate more
+  /// loads.
+  virtual bool hasPairedLoad(Type * /*LoadedType*/,
+                             unsigned & /*RequiredAligment*/) const {
+    return false;
+  }
+
+  virtual bool hasPairedLoad(EVT /*LoadedType*/,
+                             unsigned & /*RequiredAligment*/) const {
+    return false;
+  }
+
+  /// Return true if zero-extending the specific node Val to type VT2 is free
+  /// (either because it's implicitly zero-extended such as ARM ldrb / ldrh or
+  /// because it's folded such as X86 zero-extending loads).
+  virtual bool isZExtFree(SDValue Val, EVT VT2) const {
+    return isZExtFree(Val.getValueType(), VT2);
+  }
+
+  /// Return true if an fneg operation is free to the point where it is never
+  /// worthwhile to replace it with a bitwise operation.
+  virtual bool isFNegFree(EVT VT) const {
+    assert(VT.isFloatingPoint());
+    return false;
+  }
+
+  /// Return true if an fabs operation is free to the point where it is never
+  /// worthwhile to replace it with a bitwise operation.
+  virtual bool isFAbsFree(EVT VT) const {
+    assert(VT.isFloatingPoint());
+    return false;
+  }
+
+  /// Return true if an FMA operation is faster than a pair of fmul and fadd
+  /// instructions. fmuladd intrinsics will be expanded to FMAs when this method
+  /// returns true, otherwise fmuladd is expanded to fmul + fadd.
+  ///
+  /// NOTE: This may be called before legalization on types for which FMAs are
+  /// not legal, but should return true if those types will eventually legalize
+  /// to types that support FMAs. After legalization, it will only be called on
+  /// types that support FMAs (via Legal or Custom actions)
+  virtual bool isFMAFasterThanFMulAndFAdd(EVT) const {
+    return false;
+  }
+
+  /// Return true if it's profitable to narrow operations of type VT1 to
+  /// VT2. e.g. on x86, it's profitable to narrow from i32 to i8 but not from
+  /// i32 to i16.
+  virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const {
+    return false;
+  }
+
+  /// \brief Return true if it is beneficial to convert a load of a constant to
+  /// just the constant itself.
+  /// On some targets it might be more efficient to use a combination of
+  /// arithmetic instructions to materialize the constant instead of loading it
+  /// from a constant pool.
+  virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
+                                                 Type *Ty) const {
+    return false;
+  }
+  //===--------------------------------------------------------------------===//
+  // Runtime Library hooks
+  //
+
+  /// Rename the default libcall routine name for the specified libcall.
+  void setLibcallName(RTLIB::Libcall Call, const char *Name) {
+    LibcallRoutineNames[Call] = Name;
+  }
+
+  /// Get the libcall routine name for the specified libcall.
+  const char *getLibcallName(RTLIB::Libcall Call) const {
+    return LibcallRoutineNames[Call];
+  }
+
+  /// Override the default CondCode to be used to test the result of the
+  /// comparison libcall against zero.
+  void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) {
+    CmpLibcallCCs[Call] = CC;
+  }
+
+  /// Get the CondCode that's to be used to test the result of the comparison
+  /// libcall against zero.
+  ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const {
+    return CmpLibcallCCs[Call];
+  }
+
+  /// Set the CallingConv that should be used for the specified libcall.
+  void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
+    LibcallCallingConvs[Call] = CC;
+  }
+
+  /// Get the CallingConv that should be used for the specified libcall.
+  CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
+    return LibcallCallingConvs[Call];
+  }
+
+private:
+  const TargetMachine &TM;
+  const DataLayout *DL;
+  const TargetLoweringObjectFile &TLOF;
+
+  /// True if this is a little endian target.
+  bool IsLittleEndian;
+
+  /// Tells the code generator not to expand operations into sequences that use
+  /// the select operations if possible.
+  bool SelectIsExpensive;
+
+  /// Tells the code generator that the target has multiple (allocatable)
+  /// condition registers that can be used to store the results of comparisons
+  /// for use by selects and conditional branches. With multiple condition
+  /// registers, the code generator will not aggressively sink comparisons into
+  /// the blocks of their users.
+  bool HasMultipleConditionRegisters;
+
+  /// Tells the code generator that the target has BitExtract instructions.
+  /// The code generator will aggressively sink "shift"s into the blocks of
+  /// their users if the users will generate "and" instructions which can be
+  /// combined with "shift" to BitExtract instructions.
+  bool HasExtractBitsInsn;
+
+  /// Tells the code generator not to expand integer divides by constants into a
+  /// sequence of muls, adds, and shifts.  This is a hack until a real cost
+  /// model is in place.  If we ever optimize for size, this will be set to true
+  /// unconditionally.
+  bool IntDivIsCheap;
+
+  /// Tells the code generator to bypass slow divide or remainder
+  /// instructions. For example, BypassSlowDivWidths[32,8] tells the code
+  /// generator to bypass 32-bit integer div/rem with an 8-bit unsigned integer
+  /// div/rem when the operands are positive and less than 256.
+  DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
+
+  /// Tells the code generator that it shouldn't generate srl/add/sra for a
+  /// signed divide by power of two, and let the target handle it.
+  bool Pow2DivIsCheap;
+
+  /// Tells the code generator that it shouldn't generate extra flow control
+  /// instructions and should attempt to combine flow control instructions via
+  /// predication.
+  bool JumpIsExpensive;
+
+  /// This target prefers to use _setjmp to implement llvm.setjmp.
+  ///
+  /// Defaults to false.
+  bool UseUnderscoreSetJmp;
+
+  /// This target prefers to use _longjmp to implement llvm.longjmp.
+  ///
+  /// Defaults to false.
+  bool UseUnderscoreLongJmp;
+
+  /// Whether the target can generate code for jumptables.  If it's not true,
+  /// then each jumptable must be lowered into if-then-else's.
+  bool SupportJumpTables;
+
+  /// Number of blocks threshold to use jump tables.
+  int MinimumJumpTableEntries;
+
+  /// Information about the contents of the high-bits in boolean values held in
+  /// a type wider than i1. See getBooleanContents.
+  BooleanContent BooleanContents;
+
+  /// Information about the contents of the high-bits in boolean values held in
+  /// a type wider than i1. See getBooleanContents.
+  BooleanContent BooleanFloatContents;
+
+  /// Information about the contents of the high-bits in boolean vector values
+  /// when the element type is wider than i1. See getBooleanContents.
+  BooleanContent BooleanVectorContents;
+
+  /// The target scheduling preference: shortest possible total cycles or lowest
+  /// register usage.
+  Sched::Preference SchedPreferenceInfo;
+
+  /// The size, in bytes, of the target's jmp_buf buffers
+  unsigned JumpBufSize;
+
+  /// The alignment, in bytes, of the target's jmp_buf buffers
+  unsigned JumpBufAlignment;
+
+  /// The minimum alignment that any argument on the stack needs to have.
+  unsigned MinStackArgumentAlignment;
+
+  /// The minimum function alignment (used when optimizing for size, and to
+  /// prevent explicitly provided alignment from leading to incorrect code).
+  unsigned MinFunctionAlignment;
+
+  /// The preferred function alignment (used when alignment unspecified and
+  /// optimizing for speed).
+  unsigned PrefFunctionAlignment;
+
+  /// The preferred loop alignment.
+  unsigned PrefLoopAlignment;
+
+  /// Whether the DAG builder should automatically insert fences and reduce
+  /// ordering for atomics.  (This will be set for for most architectures with
+  /// weak memory ordering.)
+  bool InsertFencesForAtomic;
+
+  /// If set to a physical register, this specifies the register that
+  /// llvm.savestack/llvm.restorestack should save and restore.
+  unsigned StackPointerRegisterToSaveRestore;
+
+  /// If set to a physical register, this specifies the register that receives
+  /// the exception address on entry to a landing pad.
+  unsigned ExceptionPointerRegister;
+
+  /// If set to a physical register, this specifies the register that receives
+  /// the exception typeid on entry to a landing pad.
+  unsigned ExceptionSelectorRegister;
+
+  /// This indicates the default register class to use for each ValueType the
+  /// target supports natively.
+  const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
+  unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
+  MVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
+
+  /// This indicates the "representative" register class to use for each
+  /// ValueType the target supports natively. This information is used by the
+  /// scheduler to track register pressure. By default, the representative
+  /// register class is the largest legal super-reg register class of the
+  /// register class of the specified type. e.g. On x86, i8, i16, and i32's
+  /// representative class would be GR32.
+  const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE];
+
+  /// This indicates the "cost" of the "representative" register class for each
+  /// ValueType. The cost is used by the scheduler to approximate register
+  /// pressure.
+  uint8_t RepRegClassCostForVT[MVT::LAST_VALUETYPE];
+
+  /// For any value types we are promoting or expanding, this contains the value
+  /// type that we are changing to.  For Expanded types, this contains one step
+  /// of the expand (e.g. i64 -> i32), even if there are multiple steps required
+  /// (e.g. i64 -> i16).  For types natively supported by the system, this holds
+  /// the same type (e.g. i32 -> i32).
+  MVT TransformToType[MVT::LAST_VALUETYPE];
+
+  /// For each operation and each value type, keep a LegalizeAction that
+  /// indicates how instruction selection should deal with the operation.  Most
+  /// operations are Legal (aka, supported natively by the target), but
+  /// operations that are not should be described.  Note that operations on
+  /// non-legal value types are not described here.
+  uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
+
+  /// For each load extension type and each value type, keep a LegalizeAction
+  /// that indicates how instruction selection should deal with a load of a
+  /// specific value type and extension type.
+  uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
+
+  /// For each value type pair keep a LegalizeAction that indicates whether a
+  /// truncating store of a specific value type and truncating type is legal.
+  uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
+
+  /// For each indexed mode and each value type, keep a pair of LegalizeAction
+  /// that indicates how instruction selection should deal with the load /
+  /// store.
+  ///
+  /// The first dimension is the value_type for the reference. The second
+  /// dimension represents the various modes for load store.
+  uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE];
+
+  /// For each condition code (ISD::CondCode) keep a LegalizeAction that
+  /// indicates how instruction selection should deal with the condition code.
+  ///
+  /// Because each CC action takes up 2 bits, we need to have the array size be
+  /// large enough to fit all of the value types. This can be done by rounding
+  /// up the MVT::LAST_VALUETYPE value to the next multiple of 16.
+  uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 15) / 16];
+
+  ValueTypeActionImpl ValueTypeActions;
+
+public:
+  LegalizeKind
+  getTypeConversion(LLVMContext &Context, EVT VT) const {
+    // If this is a simple type, use the ComputeRegisterProp mechanism.
+    if (VT.isSimple()) {
+      MVT SVT = VT.getSimpleVT();
+      assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType));
+      MVT NVT = TransformToType[SVT.SimpleTy];
+      LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT);
+
+      assert(
+        (LA == TypeLegal || LA == TypeSoftenFloat ||
+         ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger)
+         && "Promote may not follow Expand or Promote");
+
+      if (LA == TypeSplitVector)
+        return LegalizeKind(LA, EVT::getVectorVT(Context,
+                                                 SVT.getVectorElementType(),
+                                                 SVT.getVectorNumElements()/2));
+      if (LA == TypeScalarizeVector)
+        return LegalizeKind(LA, SVT.getVectorElementType());
+      return LegalizeKind(LA, NVT);
+    }
+
+    // Handle Extended Scalar Types.
+    if (!VT.isVector()) {
+      assert(VT.isInteger() && "Float types must be simple");
+      unsigned BitSize = VT.getSizeInBits();
+      // First promote to a power-of-two size, then expand if necessary.
+      if (BitSize < 8 || !isPowerOf2_32(BitSize)) {
+        EVT NVT = VT.getRoundIntegerType(Context);
+        assert(NVT != VT && "Unable to round integer VT");
+        LegalizeKind NextStep = getTypeConversion(Context, NVT);
+        // Avoid multi-step promotion.
+        if (NextStep.first == TypePromoteInteger) return NextStep;
+        // Return rounded integer type.
+        return LegalizeKind(TypePromoteInteger, NVT);
+      }
+
+      return LegalizeKind(TypeExpandInteger,
+                          EVT::getIntegerVT(Context, VT.getSizeInBits()/2));
+    }
+
+    // Handle vector types.
+    unsigned NumElts = VT.getVectorNumElements();
+    EVT EltVT = VT.getVectorElementType();
+
+    // Vectors with only one element are always scalarized.
+    if (NumElts == 1)
+      return LegalizeKind(TypeScalarizeVector, EltVT);
+
+    // Try to widen vector elements until the element type is a power of two and
+    // promote it to a legal type later on, for example:
+    // <3 x i8> -> <4 x i8> -> <4 x i32>
+    if (EltVT.isInteger()) {
+      // Vectors with a number of elements that is not a power of two are always
+      // widened, for example <3 x i8> -> <4 x i8>.
+      if (!VT.isPow2VectorType()) {
+        NumElts = (unsigned)NextPowerOf2(NumElts);
+        EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts);
+        return LegalizeKind(TypeWidenVector, NVT);
+      }
+
+      // Examine the element type.
+      LegalizeKind LK = getTypeConversion(Context, EltVT);
+
+      // If type is to be expanded, split the vector.
+      //  <4 x i140> -> <2 x i140>
+      if (LK.first == TypeExpandInteger)
+        return LegalizeKind(TypeSplitVector,
+                            EVT::getVectorVT(Context, EltVT, NumElts / 2));
+
+      // Promote the integer element types until a legal vector type is found
+      // or until the element integer type is too big. If a legal type was not
+      // found, fallback to the usual mechanism of widening/splitting the
+      // vector.
+      EVT OldEltVT = EltVT;
+      while (1) {
+        // Increase the bitwidth of the element to the next pow-of-two
+        // (which is greater than 8 bits).
+        EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits()
+                                 ).getRoundIntegerType(Context);
+
+        // Stop trying when getting a non-simple element type.
+        // Note that vector elements may be greater than legal vector element
+        // types. Example: X86 XMM registers hold 64bit element on 32bit
+        // systems.
+        if (!EltVT.isSimple()) break;
+
+        // Build a new vector type and check if it is legal.
+        MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
+        // Found a legal promoted vector type.
+        if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal)
+          return LegalizeKind(TypePromoteInteger,
+                              EVT::getVectorVT(Context, EltVT, NumElts));
+      }
+
+      // Reset the type to the unexpanded type if we did not find a legal vector
+      // type with a promoted vector element type.
+      EltVT = OldEltVT;
+    }
+
+    // Try to widen the vector until a legal type is found.
+    // If there is no wider legal type, split the vector.
+    while (1) {
+      // Round up to the next power of 2.
+      NumElts = (unsigned)NextPowerOf2(NumElts);
+
+      // If there is no simple vector type with this many elements then there
+      // cannot be a larger legal vector type.  Note that this assumes that
+      // there are no skipped intermediate vector types in the simple types.
+      if (!EltVT.isSimple()) break;
+      MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
+      if (LargerVector == MVT()) break;
+
+      // If this type is legal then widen the vector.
+      if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal)
+        return LegalizeKind(TypeWidenVector, LargerVector);
+    }
+
+    // Widen odd vectors to next power of two.
+    if (!VT.isPow2VectorType()) {
+      EVT NVT = VT.getPow2VectorType(Context);
+      return LegalizeKind(TypeWidenVector, NVT);
+    }
+
+    // Vectors with illegal element types are expanded.
+    EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2);
+    return LegalizeKind(TypeSplitVector, NVT);
+  }
+
+private:
+  std::vector<std::pair<MVT, const TargetRegisterClass*> > AvailableRegClasses;
+
+  /// Targets can specify ISD nodes that they would like PerformDAGCombine
+  /// callbacks for by calling setTargetDAGCombine(), which sets a bit in this
+  /// array.
+  unsigned char
+  TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT];
+
+  /// For operations that must be promoted to a specific type, this holds the
+  /// destination type.  This map should be sparse, so don't hold it as an
+  /// array.
+  ///
+  /// Targets add entries to this map with AddPromotedToType(..), clients access
+  /// this with getTypeToPromoteTo(..).
+  std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
+    PromoteToType;
+
+  /// Stores the name each libcall.
+  const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL];
+
+  /// The ISD::CondCode that should be used to test the result of each of the
+  /// comparison libcall against zero.
+  ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
+
+  /// Stores the CallingConv that should be used for each libcall.
+  CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
+
+protected:
+  /// \brief Specify maximum number of store instructions per memset call.
+  ///
+  /// When lowering \@llvm.memset this field specifies the maximum number of
+  /// store operations that may be substituted for the call to memset. Targets
+  /// must set this value based on the cost threshold for that target. Targets
+  /// should assume that the memset will be done using as many of the largest
+  /// store operations first, followed by smaller ones, if necessary, per
+  /// alignment restrictions. For example, storing 9 bytes on a 32-bit machine
+  /// with 16-bit alignment would result in four 2-byte stores and one 1-byte
+  /// store.  This only applies to setting a constant array of a constant size.
+  unsigned MaxStoresPerMemset;
+
+  /// Maximum number of stores operations that may be substituted for the call
+  /// to memset, used for functions with OptSize attribute.
+  unsigned MaxStoresPerMemsetOptSize;
+
+  /// \brief Specify maximum bytes of store instructions per memcpy call.
+  ///
+  /// When lowering \@llvm.memcpy this field specifies the maximum number of
+  /// store operations that may be substituted for a call to memcpy. Targets
+  /// must set this value based on the cost threshold for that target. Targets
+  /// should assume that the memcpy will be done using as many of the largest
+  /// store operations first, followed by smaller ones, if necessary, per
+  /// alignment restrictions. For example, storing 7 bytes on a 32-bit machine
+  /// with 32-bit alignment would result in one 4-byte store, a one 2-byte store
+  /// and one 1-byte store. This only applies to copying a constant array of
+  /// constant size.
+  unsigned MaxStoresPerMemcpy;
+
+  /// Maximum number of store operations that may be substituted for a call to
+  /// memcpy, used for functions with OptSize attribute.
+  unsigned MaxStoresPerMemcpyOptSize;
+
+  /// \brief Specify maximum bytes of store instructions per memmove call.
+  ///
+  /// When lowering \@llvm.memmove this field specifies the maximum number of
+  /// store instructions that may be substituted for a call to memmove. Targets
+  /// must set this value based on the cost threshold for that target. Targets
+  /// should assume that the memmove will be done using as many of the largest
+  /// store operations first, followed by smaller ones, if necessary, per
+  /// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
+  /// with 8-bit alignment would result in nine 1-byte stores.  This only
+  /// applies to copying a constant array of constant size.
+  unsigned MaxStoresPerMemmove;
+
+  /// Maximum number of store instructions that may be substituted for a call to
+  /// memmove, used for functions with OpSize attribute.
+  unsigned MaxStoresPerMemmoveOptSize;
+
+  /// Tells the code generator that select is more expensive than a branch if
+  /// the branch is usually predicted right.
+  bool PredictableSelectIsExpensive;
+
+  /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding
+  /// a mask of a single bit, a compare, and a branch into a single instruction.
+  bool MaskAndBranchFoldingIsLegal;
+
+protected:
+  /// Return true if the value types that can be represented by the specified
+  /// register class are all legal.
+  bool isLegalRC(const TargetRegisterClass *RC) const;
+
+  /// Replace/modify any TargetFrameIndex operands with a targte-dependent
+  /// sequence of memory operands that is recognized by PrologEpilogInserter.
+  MachineBasicBlock *emitPatchPoint(MachineInstr *MI, MachineBasicBlock *MBB) const;
+};
+
+/// This class defines information used to lower LLVM code to legal SelectionDAG
+/// operators that the target instruction selector can accept natively.
+///
+/// This class also defines callbacks that targets must implement to lower
+/// target-specific constructs to SelectionDAG operators.
+class TargetLowering : public TargetLoweringBase {
+  TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
+
+public:
+  /// NOTE: The constructor takes ownership of TLOF.
+  explicit TargetLowering(const TargetMachine &TM,
+                          const TargetLoweringObjectFile *TLOF);
+
+  /// Returns true by value, base pointer and offset pointer and addressing mode
+  /// by reference if the node's address can be legally represented as
+  /// pre-indexed load / store address.
+  virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
+                                         SDValue &/*Offset*/,
+                                         ISD::MemIndexedMode &/*AM*/,
+                                         SelectionDAG &/*DAG*/) const {
+    return false;
+  }
+
+  /// Returns true by value, base pointer and offset pointer and addressing mode
+  /// by reference if this node can be combined with a load / store to form a
+  /// post-indexed load / store.
+  virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
+                                          SDValue &/*Base*/,
+                                          SDValue &/*Offset*/,
+                                          ISD::MemIndexedMode &/*AM*/,
+                                          SelectionDAG &/*DAG*/) const {
+    return false;
+  }
+
+  /// Return the entry encoding for a jump table in the current function.  The
+  /// returned value is a member of the MachineJumpTableInfo::JTEntryKind enum.
+  virtual unsigned getJumpTableEncoding() const;
+
+  virtual const MCExpr *
+  LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
+                            const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
+                            MCContext &/*Ctx*/) const {
+    llvm_unreachable("Need to implement this hook if target has custom JTIs");
+  }
+
+  /// Returns relocation base for the given PIC jumptable.
+  virtual SDValue getPICJumpTableRelocBase(SDValue Table,
+                                           SelectionDAG &DAG) const;
+
+  /// This returns the relocation base for the given PIC jumptable, the same as
+  /// getPICJumpTableRelocBase, but as an MCExpr.
+  virtual const MCExpr *
+  getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+                               unsigned JTI, MCContext &Ctx) const;
+
+  /// Return true if folding a constant offset with the given GlobalAddress is
+  /// legal.  It is frequently not legal in PIC relocation models.
+  virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
+  bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
+                            SDValue &Chain) const;
+
+  void softenSetCCOperands(SelectionDAG &DAG, EVT VT,
+                           SDValue &NewLHS, SDValue &NewRHS,
+                           ISD::CondCode &CCCode, SDLoc DL) const;
+
+  /// Returns a pair of (return value, chain).
+  std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC,
+                                          EVT RetVT, const SDValue *Ops,
+                                          unsigned NumOps, bool isSigned,
+                                          SDLoc dl, bool doesNotReturn = false,
+                                          bool isReturnValueUsed = true) const;
+
+  //===--------------------------------------------------------------------===//
+  // TargetLowering Optimization Methods
+  //
+
+  /// A convenience struct that encapsulates a DAG, and two SDValues for
+  /// returning information from TargetLowering to its clients that want to
+  /// combine.
+  struct TargetLoweringOpt {
+    SelectionDAG &DAG;
+    bool LegalTys;
+    bool LegalOps;
+    SDValue Old;
+    SDValue New;
+
+    explicit TargetLoweringOpt(SelectionDAG &InDAG,
+                               bool LT, bool LO) :
+      DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+
+    bool LegalTypes() const { return LegalTys; }
+    bool LegalOperations() const { return LegalOps; }
+
+    bool CombineTo(SDValue O, SDValue N) {
+      Old = O;
+      New = N;
+      return true;
+    }
+
+    /// Check to see if the specified operand of the specified instruction is a
+    /// constant integer.  If so, check to see if there are any bits set in the
+    /// constant that are not demanded.  If so, shrink the constant and return
+    /// true.
+    bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
+
+    /// Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.  This
+    /// uses isZExtFree and ZERO_EXTEND for the widening cast, but it could be
+    /// generalized for targets with other types of implicit widening casts.
+    bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+                          SDLoc dl);
+  };
+
+  /// Look at Op.  At this point, we know that only the DemandedMask bits of the
+  /// result of Op are ever used downstream.  If we can use this information to
+  /// simplify Op, create a new simplified DAG node and return true, returning
+  /// the original and new nodes in Old and New.  Otherwise, analyze the
+  /// expression and return a mask of KnownOne and KnownZero bits for the
+  /// expression (used to simplify the caller).  The KnownZero/One bits may only
+  /// be accurate for those bits in the DemandedMask.
+  bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
+                            APInt &KnownZero, APInt &KnownOne,
+                            TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+
+  /// Determine which of the bits specified in Mask are known to be either zero
+  /// or one and return them in the KnownZero/KnownOne bitsets.
+  virtual void computeKnownBitsForTargetNode(const SDValue Op,
+                                             APInt &KnownZero,
+                                             APInt &KnownOne,
+                                             const SelectionDAG &DAG,
+                                             unsigned Depth = 0) const;
+
+  /// This method can be implemented by targets that want to expose additional
+  /// information about sign bits to the DAG Combiner.
+  virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+                                                   const SelectionDAG &DAG,
+                                                   unsigned Depth = 0) const;
+
+  struct DAGCombinerInfo {
+    void *DC;  // The DAG Combiner object.
+    CombineLevel Level;
+    bool CalledByLegalizer;
+  public:
+    SelectionDAG &DAG;
+
+    DAGCombinerInfo(SelectionDAG &dag, CombineLevel level,  bool cl, void *dc)
+      : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
+
+    bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
+    bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
+    bool isAfterLegalizeVectorOps() const {
+      return Level == AfterLegalizeDAG;
+    }
+    CombineLevel getDAGCombineLevel() { return Level; }
+    bool isCalledByLegalizer() const { return CalledByLegalizer; }
+
+    void AddToWorklist(SDNode *N);
+    void RemoveFromWorklist(SDNode *N);
+    SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+                      bool AddTo = true);
+    SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+    SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
+
+    void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
+  };
+
+  /// Return if the N is a constant or constant vector equal to the true value
+  /// from getBooleanContents().
+  bool isConstTrueVal(const SDNode *N) const;
+
+  /// Return if the N is a constant or constant vector equal to the false value
+  /// from getBooleanContents().
+  bool isConstFalseVal(const SDNode *N) const;
+
+  /// Try to simplify a setcc built with the specified operands and cc. If it is
+  /// unable to simplify it, return a null SDValue.
+  SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
+                          ISD::CondCode Cond, bool foldBooleans,
+                          DAGCombinerInfo &DCI, SDLoc dl) const;
+
+  /// Returns true (and the GlobalValue and the offset) if the node is a
+  /// GlobalAddress + offset.
+  virtual bool
+  isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
+
+  /// This method will be invoked for all target nodes and for any
+  /// target-independent nodes that the target has registered with invoke it
+  /// for.
+  ///
+  /// The semantics are as follows:
+  /// Return Value:
+  ///   SDValue.Val == 0   - No change was made
+  ///   SDValue.Val == N   - N was replaced, is dead, and is already handled.
+  ///   otherwise          - N should be replaced by the returned Operand.
+  ///
+  /// In addition, methods provided by DAGCombinerInfo may be used to perform
+  /// more complex transformations.
+  ///
+  virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+
+  /// Return true if it is profitable to move a following shift through this
+  //  node, adjusting any immediate operands as necessary to preserve semantics.
+  //  This transformation may not be desirable if it disrupts a particularly
+  //  auspicious target-specific tree (e.g. bitfield extraction in AArch64).
+  //  By default, it returns true.
+  virtual bool isDesirableToCommuteWithShift(const SDNode *N /*Op*/) const {
+    return true;
+  }
+
+  /// Return true if the target has native support for the specified value type
+  /// and it is 'desirable' to use the type for the given node type. e.g. On x86
+  /// i16 is legal, but undesirable since i16 instruction encodings are longer
+  /// and some i16 instructions are slow.
+  virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
+    // By default, assume all legal types are desirable.
+    return isTypeLegal(VT);
+  }
+
+  /// Return true if it is profitable for dag combiner to transform a floating
+  /// point op of specified opcode to a equivalent op of an integer
+  /// type. e.g. f32 load -> i32 load can be profitable on ARM.
+  virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/,
+                                                 EVT /*VT*/) const {
+    return false;
+  }
+
+  /// This method query the target whether it is beneficial for dag combiner to
+  /// promote the specified node. If true, it should return the desired
+  /// promotion type by reference.
+  virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
+    return false;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Lowering methods - These methods must be implemented by targets so that
+  // the SelectionDAGBuilder code knows how to lower these.
+  //
+
+  /// This hook must be implemented to lower the incoming (formal) arguments,
+  /// described by the Ins array, into the specified DAG. The implementation
+  /// should fill in the InVals array with legal-type argument values, and
+  /// return the resulting token chain value.
+  ///
+  virtual SDValue
+    LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+                         bool /*isVarArg*/,
+                         const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
+                         SDLoc /*dl*/, SelectionDAG &/*DAG*/,
+                         SmallVectorImpl<SDValue> &/*InVals*/) const {
+    llvm_unreachable("Not Implemented");
+  }
+
+  struct ArgListEntry {
+    SDValue Node;
+    Type* Ty;
+    bool isSExt     : 1;
+    bool isZExt     : 1;
+    bool isInReg    : 1;
+    bool isSRet     : 1;
+    bool isNest     : 1;
+    bool isByVal    : 1;
+    bool isInAlloca : 1;
+    bool isReturned : 1;
+    uint16_t Alignment;
+
+    ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
+      isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
+      isReturned(false), Alignment(0) { }
+
+    void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
+  };
+  typedef std::vector<ArgListEntry> ArgListTy;
+
+  /// This structure contains all information that is necessary for lowering
+  /// calls. It is passed to TLI::LowerCallTo when the SelectionDAG builder
+  /// needs to lower a call, and targets will see this struct in their LowerCall
+  /// implementation.
+  struct CallLoweringInfo {
+    SDValue Chain;
+    Type *RetTy;
+    bool RetSExt           : 1;
+    bool RetZExt           : 1;
+    bool IsVarArg          : 1;
+    bool IsInReg           : 1;
+    bool DoesNotReturn     : 1;
+    bool IsReturnValueUsed : 1;
+
+    // IsTailCall should be modified by implementations of
+    // TargetLowering::LowerCall that perform tail call conversions.
+    bool IsTailCall;
+
+    unsigned NumFixedArgs;
+    CallingConv::ID CallConv;
+    SDValue Callee;
+    ArgListTy Args;
+    SelectionDAG &DAG;
+    SDLoc DL;
+    ImmutableCallSite *CS;
+    SmallVector<ISD::OutputArg, 32> Outs;
+    SmallVector<SDValue, 32> OutVals;
+    SmallVector<ISD::InputArg, 32> Ins;
+
+    CallLoweringInfo(SelectionDAG &DAG)
+      : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false),
+        IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true),
+        IsTailCall(false), NumFixedArgs(-1), CallConv(CallingConv::C),
+        DAG(DAG), CS(nullptr) {}
+
+    CallLoweringInfo &setDebugLoc(SDLoc dl) {
+      DL = dl;
+      return *this;
+    }
+
+    CallLoweringInfo &setChain(SDValue InChain) {
+      Chain = InChain;
+      return *this;
+    }
+
+    CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultType,
+                                SDValue Target, ArgListTy &&ArgsList,
+                                unsigned FixedArgs = -1) {
+      RetTy = ResultType;
+      Callee = Target;
+      CallConv = CC;
+      NumFixedArgs =
+        (FixedArgs == static_cast<unsigned>(-1) ? Args.size() : FixedArgs);
+      Args = std::move(ArgsList);
+      return *this;
+    }
+
+    CallLoweringInfo &setCallee(Type *ResultType, FunctionType *FTy,
+                                SDValue Target, ArgListTy &&ArgsList,
+                                ImmutableCallSite &Call) {
+      RetTy = ResultType;
+
+      IsInReg = Call.paramHasAttr(0, Attribute::InReg);
+      DoesNotReturn = Call.doesNotReturn();
+      IsVarArg = FTy->isVarArg();
+      IsReturnValueUsed = !Call.getInstruction()->use_empty();
+      RetSExt = Call.paramHasAttr(0, Attribute::SExt);
+      RetZExt = Call.paramHasAttr(0, Attribute::ZExt);
+
+      Callee = Target;
+
+      CallConv = Call.getCallingConv();
+      NumFixedArgs = FTy->getNumParams();
+      Args = std::move(ArgsList);
+
+      CS = &Call;
+
+      return *this;
+    }
+
+    CallLoweringInfo &setInRegister(bool Value = true) {
+      IsInReg = Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setNoReturn(bool Value = true) {
+      DoesNotReturn = Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setVarArg(bool Value = true) {
+      IsVarArg = Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setTailCall(bool Value = true) {
+      IsTailCall = Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setDiscardResult(bool Value = true) {
+      IsReturnValueUsed = !Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setSExtResult(bool Value = true) {
+      RetSExt = Value;
+      return *this;
+    }
+
+    CallLoweringInfo &setZExtResult(bool Value = true) {
+      RetZExt = Value;
+      return *this;
+    }
+
+    ArgListTy &getArgs() {
+      return Args;
+    }
+  };
+
+  /// This function lowers an abstract call to a function into an actual call.
+  /// This returns a pair of operands.  The first element is the return value
+  /// for the function (if RetTy is not VoidTy).  The second element is the
+  /// outgoing token chain. It calls LowerCall to do the actual lowering.
+  std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
+
+  /// This hook must be implemented to lower calls into the the specified
+  /// DAG. The outgoing arguments to the call are described by the Outs array,
+  /// and the values to be returned by the call are described by the Ins
+  /// array. The implementation should fill in the InVals array with legal-type
+  /// return values from the call, and return the resulting token chain value.
+  virtual SDValue
+    LowerCall(CallLoweringInfo &/*CLI*/,
+              SmallVectorImpl<SDValue> &/*InVals*/) const {
+    llvm_unreachable("Not Implemented");
+  }
+
+  /// Target-specific cleanup for formal ByVal parameters.
+  virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
+
+  /// This hook should be implemented to check whether the return values
+  /// described by the Outs array can fit into the return registers.  If false
+  /// is returned, an sret-demotion is performed.
+  virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
+                              MachineFunction &/*MF*/, bool /*isVarArg*/,
+               const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+               LLVMContext &/*Context*/) const
+  {
+    // Return true by default to get preexisting behavior.
+    return true;
+  }
+
+  /// This hook must be implemented to lower outgoing return values, described
+  /// by the Outs array, into the specified DAG. The implementation should
+  /// return the resulting token chain value.
+  virtual SDValue
+    LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+                bool /*isVarArg*/,
+                const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+                const SmallVectorImpl<SDValue> &/*OutVals*/,
+                SDLoc /*dl*/, SelectionDAG &/*DAG*/) const {
+    llvm_unreachable("Not Implemented");
+  }
+
+  /// Return true if result of the specified node is used by a return node
+  /// only. It also compute and return the input chain for the tail call.
+  ///
+  /// This is used to determine whether it is possible to codegen a libcall as
+  /// tail call at legalization time.
+  virtual bool isUsedByReturnOnly(SDNode *, SDValue &/*Chain*/) const {
+    return false;
+  }
+
+  /// Return true if the target may be able emit the call instruction as a tail
+  /// call. This is used by optimization passes to determine if it's profitable
+  /// to duplicate return instructions to enable tailcall optimization.
+  virtual bool mayBeEmittedAsTailCall(CallInst *) const {
+    return false;
+  }
+
+  /// Return the builtin name for the __builtin___clear_cache intrinsic
+  /// Default is to invoke the clear cache library call
+  virtual const char * getClearCacheBuiltinName() const {
+    return "__clear_cache";
+  }
+
+  /// Return the register ID of the name passed in. Used by named register
+  /// global variables extension. There is no target-independent behaviour
+  /// so the default action is to bail.
+  virtual unsigned getRegisterByName(const char* RegName, EVT VT) const {
+    report_fatal_error("Named registers not implemented for this target");
+  }
+
+  /// Return the type that should be used to zero or sign extend a
+  /// zeroext/signext integer argument or return value.  FIXME: Most C calling
+  /// convention requires the return type to be promoted, but this is not true
+  /// all the time, e.g. i1 on x86-64. It is also not necessary for non-C
+  /// calling conventions. The frontend should handle this and include all of
+  /// the necessary information.
+  virtual MVT getTypeForExtArgOrReturn(MVT VT,
+                                       ISD::NodeType /*ExtendKind*/) const {
+    MVT MinVT = getRegisterType(MVT::i32);
+    return VT.bitsLT(MinVT) ? MinVT : VT;
+  }
+
+  /// For some targets, an LLVM struct type must be broken down into multiple
+  /// simple types, but the calling convention specifies that the entire struct
+  /// must be passed in a block of consecutive registers.
+  virtual bool
+  functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv,
+                                            bool isVarArg) const {
+    return false;
+  }
+
+  /// Returns a 0 terminated array of registers that can be safely used as
+  /// scratch registers.
+  virtual const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const {
+    return nullptr;
+  }
+
+  /// This callback is used to prepare for a volatile or atomic load.
+  /// It takes a chain node as input and returns the chain for the load itself.
+  ///
+  /// Having a callback like this is necessary for targets like SystemZ,
+  /// which allows a CPU to reuse the result of a previous load indefinitely,
+  /// even if a cache-coherent store is performed by another CPU.  The default
+  /// implementation does nothing.
+  virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
+                                              SelectionDAG &DAG) const {
+    return Chain;
+  }
+
+  /// This callback is invoked by the type legalizer to legalize nodes with an
+  /// illegal operand type but legal result types.  It replaces the
+  /// LowerOperation callback in the type Legalizer.  The reason we can not do
+  /// away with LowerOperation entirely is that LegalizeDAG isn't yet ready to
+  /// use this callback.
+  ///
+  /// TODO: Consider merging with ReplaceNodeResults.
+  ///
+  /// The target places new result values for the node in Results (their number
+  /// and types must exactly match those of the original return values of
+  /// the node), or leaves Results empty, which indicates that the node is not
+  /// to be custom lowered after all.
+  /// The default implementation calls LowerOperation.
+  virtual void LowerOperationWrapper(SDNode *N,
+                                     SmallVectorImpl<SDValue> &Results,
+                                     SelectionDAG &DAG) const;
+
+  /// This callback is invoked for operations that are unsupported by the
+  /// target, which are registered to use 'custom' lowering, and whose defined
+  /// values are all legal.  If the target has no operations that require custom
+  /// lowering, it need not implement this.  The default implementation of this
+  /// aborts.
+  virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+
+  /// This callback is invoked when a node result type is illegal for the
+  /// target, and the operation was registered to use 'custom' lowering for that
+  /// result type.  The target places new result values for the node in Results
+  /// (their number and types must exactly match those of the original return
+  /// values of the node), or leaves Results empty, which indicates that the
+  /// node is not to be custom lowered after all.
+  ///
+  /// If the target has no operations that require custom lowering, it need not
+  /// implement this.  The default implementation aborts.
+  virtual void ReplaceNodeResults(SDNode * /*N*/,
+                                  SmallVectorImpl<SDValue> &/*Results*/,
+                                  SelectionDAG &/*DAG*/) const {
+    llvm_unreachable("ReplaceNodeResults not implemented for this target!");
+  }
+
+  /// This method returns the name of a target specific DAG node.
+  virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+  /// This method returns a target specific FastISel object, or null if the
+  /// target does not support "fast" ISel.
+  virtual FastISel *createFastISel(FunctionLoweringInfo &,
+                                   const TargetLibraryInfo *) const {
+    return nullptr;
+  }
+
+
+  bool verifyReturnAddressArgumentIsConstant(SDValue Op,
+                                             SelectionDAG &DAG) const;
+
+  //===--------------------------------------------------------------------===//
+  // Inline Asm Support hooks
+  //
+
+  /// This hook allows the target to expand an inline asm call to be explicit
+  /// llvm code if it wants to.  This is useful for turning simple inline asms
+  /// into LLVM intrinsics, which gives the compiler more information about the
+  /// behavior of the code.
+  virtual bool ExpandInlineAsm(CallInst *) const {
+    return false;
+  }
+
+  enum ConstraintType {
+    C_Register,            // Constraint represents specific register(s).
+    C_RegisterClass,       // Constraint represents any of register(s) in class.
+    C_Memory,              // Memory constraint.
+    C_Other,               // Something else.
+    C_Unknown              // Unsupported constraint.
+  };
+
+  enum ConstraintWeight {
+    // Generic weights.
+    CW_Invalid  = -1,     // No match.
+    CW_Okay     = 0,      // Acceptable.
+    CW_Good     = 1,      // Good weight.
+    CW_Better   = 2,      // Better weight.
+    CW_Best     = 3,      // Best weight.
+
+    // Well-known weights.
+    CW_SpecificReg  = CW_Okay,    // Specific register operands.
+    CW_Register     = CW_Good,    // Register operands.
+    CW_Memory       = CW_Better,  // Memory operands.
+    CW_Constant     = CW_Best,    // Constant operand.
+    CW_Default      = CW_Okay     // Default or don't know type.
+  };
+
+  /// This contains information for each constraint that we are lowering.
+  struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
+    /// This contains the actual string for the code, like "m".  TargetLowering
+    /// picks the 'best' code from ConstraintInfo::Codes that most closely
+    /// matches the operand.
+    std::string ConstraintCode;
+
+    /// Information about the constraint code, e.g. Register, RegisterClass,
+    /// Memory, Other, Unknown.
+    TargetLowering::ConstraintType ConstraintType;
+
+    /// If this is the result output operand or a clobber, this is null,
+    /// otherwise it is the incoming operand to the CallInst.  This gets
+    /// modified as the asm is processed.
+    Value *CallOperandVal;
+
+    /// The ValueType for the operand value.
+    MVT ConstraintVT;
+
+    /// Return true of this is an input operand that is a matching constraint
+    /// like "4".
+    bool isMatchingInputConstraint() const;
+
+    /// If this is an input matching constraint, this method returns the output
+    /// operand it matches.
+    unsigned getMatchedOperand() const;
+
+    /// Copy constructor for copying from a ConstraintInfo.
+    AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
+      : InlineAsm::ConstraintInfo(info),
+        ConstraintType(TargetLowering::C_Unknown),
+        CallOperandVal(nullptr), ConstraintVT(MVT::Other) {
+    }
+  };
+
+  typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
+
+  /// Split up the constraint string from the inline assembly value into the
+  /// specific constraints and their prefixes, and also tie in the associated
+  /// operand values.  If this returns an empty vector, and if the constraint
+  /// string itself isn't empty, there was an error parsing.
+  virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
+
+  /// Examine constraint type and operand type and determine a weight value.
+  /// The operand object must already have been set up with the operand type.
+  virtual ConstraintWeight getMultipleConstraintMatchWeight(
+      AsmOperandInfo &info, int maIndex) const;
+
+  /// Examine constraint string and operand type and determine a weight value.
+  /// The operand object must already have been set up with the operand type.
+  virtual ConstraintWeight getSingleConstraintMatchWeight(
+      AsmOperandInfo &info, const char *constraint) const;
+
+  /// Determines the constraint code and constraint type to use for the specific
+  /// AsmOperandInfo, setting OpInfo.ConstraintCode and OpInfo.ConstraintType.
+  /// If the actual operand being passed in is available, it can be passed in as
+  /// Op, otherwise an empty SDValue can be passed.
+  virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
+                                      SDValue Op,
+                                      SelectionDAG *DAG = nullptr) const;
+
+  /// Given a constraint, return the type of constraint it is for this target.
+  virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+
+  /// Given a physical register constraint (e.g.  {edx}), return the register
+  /// number and the register class for the register.
+  ///
+  /// Given a register class constraint, like 'r', if this corresponds directly
+  /// to an LLVM register class, return a register of 0 and the register class
+  /// pointer.
+  ///
+  /// This should only be used for C_Register constraints.  On error, this
+  /// returns a register number of 0 and a null register class pointer..
+  virtual std::pair<unsigned, const TargetRegisterClass*>
+    getRegForInlineAsmConstraint(const std::string &Constraint,
+                                 MVT VT) const;
+
+  /// Try to replace an X constraint, which matches anything, with another that
+  /// has more specific requirements based on the type of the corresponding
+  /// operand.  This returns null if there is no replacement to make.
+  virtual const char *LowerXConstraint(EVT ConstraintVT) const;
+
+  /// Lower the specified operand into the Ops vector.  If it is invalid, don't
+  /// add anything to Ops.
+  virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
+                                            std::vector<SDValue> &Ops,
+                                            SelectionDAG &DAG) const;
+
+  //===--------------------------------------------------------------------===//
+  // Div utility functions
+  //
+  SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl,
+                         SelectionDAG &DAG) const;
+  SDValue BuildSDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
+                    bool IsAfterLegalization,
+                    std::vector<SDNode *> *Created) const;
+  SDValue BuildUDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
+                    bool IsAfterLegalization,
+                    std::vector<SDNode *> *Created) const;
+
+  //===--------------------------------------------------------------------===//
+  // Legalization utility functions
+  //
+
+  /// Expand a MUL into two nodes.  One that computes the high bits of
+  /// the result and one that computes the low bits.
+  /// \param HiLoVT The value type to use for the Lo and Hi nodes.
+  /// \param LL Low bits of the LHS of the MUL.  You can use this parameter
+  ///        if you want to control how low bits are extracted from the LHS.
+  /// \param LH High bits of the LHS of the MUL.  See LL for meaning.
+  /// \param RL Low bits of the RHS of the MUL.  See LL for meaning
+  /// \param RH High bits of the RHS of the MUL.  See LL for meaning.
+  /// \returns true if the node has been expanded. false if it has not
+  bool expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT,
+                 SelectionDAG &DAG, SDValue LL = SDValue(),
+                 SDValue LH = SDValue(), SDValue RL = SDValue(),
+                 SDValue RH = SDValue()) const;
+
+  /// Expand float(f32) to SINT(i64) conversion
+  /// \param N Node to expand
+  /// \param Result output after conversion
+  /// \returns True, if the expansion was successful, false otherwise
+  bool expandFP_TO_SINT(SDNode *N, SDValue &Result, SelectionDAG &DAG) const;
+
+  //===--------------------------------------------------------------------===//
+  // Instruction Emitting Hooks
+  //
+
+  /// This method should be implemented by targets that mark instructions with
+  /// the 'usesCustomInserter' flag.  These instructions are special in various
+  /// ways, which require special support to insert.  The specified MachineInstr
+  /// is created but not inserted into any basic blocks, and this method is
+  /// called to expand it into a sequence of instructions, potentially also
+  /// creating new basic blocks and control flow.
+  virtual MachineBasicBlock *
+    EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
+
+  /// This method should be implemented by targets that mark instructions with
+  /// the 'hasPostISelHook' flag. These instructions must be adjusted after
+  /// instruction selection by target hooks.  e.g. To fill in optional defs for
+  /// ARM 's' setting instructions.
+  virtual void
+  AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
+};
+
+/// Given an LLVM IR type and return type attributes, compute the return value
+/// EVTs and flags, and optionally also the offsets, if the return value is
+/// being lowered to memory.
+void GetReturnInfo(Type* ReturnType, AttributeSet attr,
+                   SmallVectorImpl<ISD::OutputArg> &Outs,
+                   const TargetLowering &TLI);
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
new file mode 100644
index 0000000..7c32a5e
--- /dev/null
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -0,0 +1,168 @@
+//===-- llvm/Target/TargetLoweringObjectFile.h - Object 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 implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/SectionKind.h"
+
+namespace llvm {
+  class MachineModuleInfo;
+  class Mangler;
+  class MCContext;
+  class MCExpr;
+  class MCSection;
+  class MCSymbol;
+  class MCSymbolRefExpr;
+  class MCStreamer;
+  class ConstantExpr;
+  class GlobalValue;
+  class TargetMachine;
+
+class TargetLoweringObjectFile : public MCObjectFileInfo {
+  MCContext *Ctx;
+  const DataLayout *DL;
+
+  TargetLoweringObjectFile(
+    const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
+
+public:
+  MCContext &getContext() const { return *Ctx; }
+
+  TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr) {}
+
+  virtual ~TargetLoweringObjectFile();
+
+  /// This method must be called before any actual lowering is done.  This
+  /// specifies the current context for codegen, and gives the lowering
+  /// implementations a chance to set up their default sections.
+  virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
+
+  virtual void emitPersonalityValue(MCStreamer &Streamer,
+                                    const TargetMachine &TM,
+                                    const MCSymbol *Sym) const;
+
+  /// Extract the dependent library name from a linker option string. Returns
+  /// StringRef() if the option does not specify a library.
+  virtual StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const {
+    return StringRef();
+  }
+
+  /// Emit the module flags that the platform cares about.
+  virtual void emitModuleFlags(MCStreamer &Streamer,
+                               ArrayRef<Module::ModuleFlagEntry> Flags,
+                               Mangler &Mang, const TargetMachine &TM) const {}
+
+  /// Given a constant with the SectionKind, return a section that it should be
+  /// placed in.
+  virtual const MCSection *getSectionForConstant(SectionKind Kind,
+                                                 const Constant *C) const;
+
+  /// Classify the specified global variable into a set of target independent
+  /// categories embodied in SectionKind.
+  static SectionKind getKindForGlobal(const GlobalValue *GV,
+                                      const TargetMachine &TM);
+
+  /// This method computes the appropriate section to emit the specified global
+  /// variable or function definition. This should not be passed external (or
+  /// available externally) globals.
+  const MCSection *SectionForGlobal(const GlobalValue *GV,
+                                    SectionKind Kind, Mangler &Mang,
+                                    const TargetMachine &TM) const;
+
+  /// This method computes the appropriate section to emit the specified global
+  /// variable or function definition. This should not be passed external (or
+  /// available externally) globals.
+  const MCSection *SectionForGlobal(const GlobalValue *GV,
+                                    Mangler &Mang,
+                                    const TargetMachine &TM) const {
+    return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
+  }
+
+  /// Targets should implement this method to assign a section to globals with
+  /// an explicit section specfied. The implementation of this method can
+  /// assume that GV->hasSection() is true.
+  virtual const MCSection *
+  getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+                           Mangler &Mang, const TargetMachine &TM) const = 0;
+
+  /// Allow the target to completely override section assignment of a global.
+  virtual const MCSection *getSpecialCasedSectionGlobals(const GlobalValue *GV,
+                                                         SectionKind Kind,
+                                                         Mangler &Mang) const {
+    return nullptr;
+  }
+
+  /// Return an MCExpr to use for a reference to the specified global variable
+  /// from exception handling information.
+  virtual const MCExpr *
+  getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+                          Mangler &Mang, const TargetMachine &TM,
+                          MachineModuleInfo *MMI, MCStreamer &Streamer) const;
+
+  /// Return the MCSymbol for a private symbol with global value name as its
+  /// base, with the specified suffix.
+  MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
+                                         StringRef Suffix, Mangler &Mang,
+                                         const TargetMachine &TM) const;
+
+  // The symbol that gets passed to .cfi_personality.
+  virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
+                                            Mangler &Mang,
+                                            const TargetMachine &TM,
+                                            MachineModuleInfo *MMI) const;
+
+  const MCExpr *
+  getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
+                    MCStreamer &Streamer) const;
+
+  virtual const MCSection *getStaticCtorSection(unsigned Priority,
+                                                const MCSymbol *KeySym) const {
+    return StaticCtorSection;
+  }
+
+  virtual const MCSection *getStaticDtorSection(unsigned Priority,
+                                                const MCSymbol *KeySym) const {
+    return StaticDtorSection;
+  }
+
+  /// \brief Create a symbol reference to describe the given TLS variable when
+  /// emitting the address in debug info.
+  virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
+
+  virtual const MCExpr *
+  getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang,
+                              const TargetMachine &TM) const {
+    return nullptr;
+  }
+
+  /// \brief True if the section is atomized using the symbols in it.
+  /// This is false if the section is not atomized at all (most ELF sections) or
+  /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
+  /// example).
+  virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
+
+protected:
+  virtual const MCSection *
+  SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                         Mangler &Mang, const TargetMachine &TM) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
new file mode 100644
index 0000000..b263c57
--- /dev/null
+++ b/include/llvm/Target/TargetMachine.h
@@ -0,0 +1,322 @@
+//===-- llvm/Target/TargetMachine.h - Target Information --------*- 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 TargetMachine and LLVMTargetMachine classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETMACHINE_H
+#define LLVM_TARGET_TARGETMACHINE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/TargetOptions.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+class InstrItineraryData;
+class JITCodeEmitter;
+class GlobalValue;
+class Mangler;
+class MCAsmInfo;
+class MCCodeGenInfo;
+class MCContext;
+class MCSymbol;
+class Target;
+class DataLayout;
+class TargetLibraryInfo;
+class TargetFrameLowering;
+class TargetInstrInfo;
+class TargetIntrinsicInfo;
+class TargetJITInfo;
+class TargetLowering;
+class TargetPassConfig;
+class TargetRegisterInfo;
+class TargetSelectionDAGInfo;
+class TargetSubtargetInfo;
+class ScalarTargetTransformInfo;
+class VectorTargetTransformInfo;
+class formatted_raw_ostream;
+class raw_ostream;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+}
+using legacy::PassManagerBase;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetMachine - Primary interface to the complete machine description for
+/// the target machine.  All target-specific information should be accessible
+/// through this interface.
+///
+class TargetMachine {
+  TargetMachine(const TargetMachine &) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetMachine &) LLVM_DELETED_FUNCTION;
+protected: // Can only create subclasses.
+  TargetMachine(const Target &T, StringRef TargetTriple,
+                StringRef CPU, StringRef FS, const TargetOptions &Options);
+
+  /// TheTarget - The Target that this machine was created for.
+  const Target &TheTarget;
+
+  /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target
+  /// feature strings the TargetMachine instance is created with.
+  std::string TargetTriple;
+  std::string TargetCPU;
+  std::string TargetFS;
+
+  /// CodeGenInfo - Low level target information such as relocation model.
+  /// Non-const to allow resetting optimization level per-function.
+  MCCodeGenInfo *CodeGenInfo;
+
+  /// AsmInfo - Contains target specific asm information.
+  ///
+  const MCAsmInfo *AsmInfo;
+
+  unsigned RequireStructuredCFG : 1;
+
+public:
+  virtual ~TargetMachine();
+
+  const Target &getTarget() const { return TheTarget; }
+
+  const StringRef getTargetTriple() const { return TargetTriple; }
+  const StringRef getTargetCPU() const { return TargetCPU; }
+  const StringRef getTargetFeatureString() const { return TargetFS; }
+
+  /// getSubtargetImpl - virtual method implemented by subclasses that returns
+  /// a reference to that target's TargetSubtargetInfo-derived member variable.
+  virtual const TargetSubtargetInfo *getSubtargetImpl() const {
+    return nullptr;
+  }
+
+  mutable TargetOptions Options;
+
+  /// \brief Reset the target options based on the function's attributes.
+  void resetTargetOptions(const MachineFunction *MF) const;
+
+  // Interfaces to the major aspects of target machine information:
+  //
+  // -- Instruction opcode and operand information
+  // -- Pipelines and scheduling information
+  // -- Stack frame information
+  // -- Selection DAG lowering information
+  //
+  // N.B. These objects may change during compilation. It's not safe to cache
+  // them between functions.
+  virtual const TargetInstrInfo  *getInstrInfo() const { return nullptr; }
+  virtual const TargetFrameLowering *getFrameLowering() const {
+    return nullptr;
+  }
+  virtual const TargetLowering *getTargetLowering() const { return nullptr; }
+  virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const {
+    return nullptr;
+  }
+  virtual const DataLayout *getDataLayout() const { return nullptr; }
+
+  /// getMCAsmInfo - Return target specific asm information.
+  ///
+  const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
+
+  /// getSubtarget - This method returns a pointer to the specified type of
+  /// TargetSubtargetInfo.  In debug builds, it verifies that the object being
+  /// returned is of the correct type.
+  template<typename STC> const STC &getSubtarget() const {
+    return *static_cast<const STC*>(getSubtargetImpl());
+  }
+
+  /// getRegisterInfo - If register information is available, return it.  If
+  /// not, return null.  This is kept separate from RegInfo until RegInfo has
+  /// details of graph coloring register allocation removed from it.
+  ///
+  virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; }
+
+  /// getIntrinsicInfo - If intrinsic information is available, return it.  If
+  /// not, return null.
+  ///
+  virtual const TargetIntrinsicInfo *getIntrinsicInfo() const { return nullptr;}
+
+  /// getJITInfo - If this target supports a JIT, return information for it,
+  /// otherwise return null.
+  ///
+  virtual TargetJITInfo *getJITInfo() { return nullptr; }
+
+  /// getInstrItineraryData - Returns instruction itinerary data for the target
+  /// or specific subtarget.
+  ///
+  virtual const InstrItineraryData *getInstrItineraryData() const {
+    return nullptr;
+  }
+
+  bool requiresStructuredCFG() const { return RequireStructuredCFG; }
+  void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; }
+
+  /// getRelocationModel - Returns the code generation relocation model. The
+  /// choices are static, PIC, and dynamic-no-pic, and target default.
+  Reloc::Model getRelocationModel() const;
+
+  /// getCodeModel - Returns the code model. The choices are small, kernel,
+  /// medium, large, and target default.
+  CodeModel::Model getCodeModel() const;
+
+  /// getTLSModel - Returns the TLS model which should be used for the given
+  /// global variable.
+  TLSModel::Model getTLSModel(const GlobalValue *GV) const;
+
+  /// getOptLevel - Returns the optimization level: None, Less,
+  /// Default, or Aggressive.
+  CodeGenOpt::Level getOptLevel() const;
+
+  /// \brief Overrides the optimization level.
+  void setOptLevel(CodeGenOpt::Level Level) const;
+
+  void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
+
+  bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
+
+  /// getAsmVerbosityDefault - Returns the default value of asm verbosity.
+  ///
+  bool getAsmVerbosityDefault() const ;
+
+  /// setAsmVerbosityDefault - Set the default value of asm verbosity. Default
+  /// is false.
+  void setAsmVerbosityDefault(bool);
+
+  /// getDataSections - Return true if data objects should be emitted into their
+  /// own section, corresponds to -fdata-sections.
+  bool getDataSections() const;
+
+  /// getFunctionSections - Return true if functions should be emitted into
+  /// their own section, corresponding to -ffunction-sections.
+  bool getFunctionSections() const;
+
+  /// setDataSections - Set if the data are emit into separate sections.
+  void setDataSections(bool);
+
+  /// setFunctionSections - Set if the functions are emit into separate
+  /// sections.
+  void setFunctionSections(bool);
+
+  /// \brief Register analysis passes for this target with a pass manager.
+  virtual void addAnalysisPasses(PassManagerBase &) {}
+
+  /// CodeGenFileType - These enums are meant to be passed into
+  /// addPassesToEmitFile to indicate what type of file to emit, and returned by
+  /// it to indicate what type of file could actually be made.
+  enum CodeGenFileType {
+    CGFT_AssemblyFile,
+    CGFT_ObjectFile,
+    CGFT_Null         // Do not emit any output.
+  };
+
+  /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+  /// specified file emitted.  Typically this will involve several steps of code
+  /// generation.  This method should return true if emission of this file type
+  /// is not supported, or false on success.
+  virtual bool addPassesToEmitFile(PassManagerBase &,
+                                   formatted_raw_ostream &,
+                                   CodeGenFileType,
+                                   bool /*DisableVerify*/ = true,
+                                   AnalysisID /*StartAfter*/ = nullptr,
+                                   AnalysisID /*StopAfter*/ = nullptr) {
+    return true;
+  }
+
+  /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+  /// get machine code emitted.  This uses a JITCodeEmitter object to handle
+  /// actually outputting the machine code and resolving things like the address
+  /// of functions.  This method returns true if machine code emission is
+  /// not supported.
+  ///
+  virtual bool addPassesToEmitMachineCode(PassManagerBase &,
+                                          JITCodeEmitter &,
+                                          bool /*DisableVerify*/ = true) {
+    return true;
+  }
+
+  /// addPassesToEmitMC - Add passes to the specified pass manager to get
+  /// machine code emitted with the MCJIT. This method returns true if machine
+  /// code is not supported. It fills the MCContext Ctx pointer which can be
+  /// used to build custom MCStreamer.
+  ///
+  virtual bool addPassesToEmitMC(PassManagerBase &,
+                                 MCContext *&,
+                                 raw_ostream &,
+                                 bool /*DisableVerify*/ = true) {
+    return true;
+  }
+
+  void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,
+                         Mangler &Mang, bool MayAlwaysUsePrivate = false) const;
+  MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const;
+};
+
+/// LLVMTargetMachine - This class describes a target machine that is
+/// implemented with the LLVM target-independent code generator.
+///
+class LLVMTargetMachine : public TargetMachine {
+protected: // Can only create subclasses.
+  LLVMTargetMachine(const Target &T, StringRef TargetTriple,
+                    StringRef CPU, StringRef FS, TargetOptions Options,
+                    Reloc::Model RM, CodeModel::Model CM,
+                    CodeGenOpt::Level OL);
+
+  void initAsmInfo();
+public:
+  /// \brief Register analysis passes for this target with a pass manager.
+  ///
+  /// This registers target independent analysis passes.
+  void addAnalysisPasses(PassManagerBase &PM) override;
+
+  /// createPassConfig - Create a pass configuration object to be used by
+  /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
+  virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
+
+  /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+  /// specified file emitted.  Typically this will involve several steps of code
+  /// generation.
+  bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+                           CodeGenFileType FileType, bool DisableVerify = true,
+                           AnalysisID StartAfter = nullptr,
+                           AnalysisID StopAfter = nullptr) override;
+
+  /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+  /// get machine code emitted.  This uses a JITCodeEmitter object to handle
+  /// actually outputting the machine code and resolving things like the address
+  /// of functions.  This method returns true if machine code emission is
+  /// not supported.
+  ///
+  bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE,
+                                  bool DisableVerify = true) override;
+
+  /// addPassesToEmitMC - Add passes to the specified pass manager to get
+  /// machine code emitted with the MCJIT. This method returns true if machine
+  /// code is not supported. It fills the MCContext Ctx pointer which can be
+  /// used to build custom MCStreamer.
+  ///
+  bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
+                         raw_ostream &OS, bool DisableVerify = true) override;
+
+  /// addCodeEmitter - This pass should be overridden by the target to add a
+  /// code emitter, if supported.  If this is not supported, 'true' should be
+  /// returned.
+  virtual bool addCodeEmitter(PassManagerBase &,
+                              JITCodeEmitter &) {
+    return true;
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
new file mode 100644
index 0000000..abb3eca
--- /dev/null
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -0,0 +1,112 @@
+//===-- llvm/Target/TargetOpcodes.h - Target Indep Opcodes ------*- 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 target independent instruction opcodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPCODES_H
+#define LLVM_TARGET_TARGETOPCODES_H
+
+namespace llvm {
+
+/// Invariant opcodes: All instruction sets have these as their low opcodes.
+///
+/// Every instruction defined here must also appear in Target.td and the order
+/// must be the same as in CodeGenTarget.cpp.
+///
+namespace TargetOpcode {
+enum {
+  PHI = 0,
+  INLINEASM = 1,
+  CFI_INSTRUCTION = 2,
+  EH_LABEL = 3,
+  GC_LABEL = 4,
+
+  /// KILL - This instruction is a noop that is used only to adjust the
+  /// liveness of registers. This can be useful when dealing with
+  /// sub-registers.
+  KILL = 5,
+
+  /// EXTRACT_SUBREG - This instruction takes two operands: a register
+  /// that has subregisters, and a subregister index. It returns the
+  /// extracted subregister value. This is commonly used to implement
+  /// truncation operations on target architectures which support it.
+  EXTRACT_SUBREG = 6,
+
+  /// INSERT_SUBREG - This instruction takes three operands: a register that
+  /// has subregisters, a register providing an insert value, and a
+  /// subregister index. It returns the value of the first register with the
+  /// value of the second register inserted. The first register is often
+  /// defined by an IMPLICIT_DEF, because it is commonly used to implement
+  /// anyext operations on target architectures which support it.
+  INSERT_SUBREG = 7,
+
+  /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
+  IMPLICIT_DEF = 8,
+
+  /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that
+  /// the first operand is an immediate integer constant. This constant is
+  /// often zero, because it is commonly used to assert that the instruction
+  /// defining the register implicitly clears the high bits.
+  SUBREG_TO_REG = 9,
+
+  /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
+  /// register-to-register copy into a specific register class. This is only
+  /// used between instruction selection and MachineInstr creation, before
+  /// virtual registers have been created for all the instructions, and it's
+  /// only needed in cases where the register classes implied by the
+  /// instructions are insufficient. It is emitted as a COPY MachineInstr.
+  COPY_TO_REGCLASS = 10,
+
+  /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
+  DBG_VALUE = 11,
+
+  /// REG_SEQUENCE - This variadic instruction is used to form a register that
+  /// represents a consecutive sequence of sub-registers. It's used as a
+  /// register coalescing / allocation aid and must be eliminated before code
+  /// emission.
+  // In SDNode form, the first operand encodes the register class created by
+  // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
+  // pair.  Once it has been lowered to a MachineInstr, the regclass operand
+  // is no longer present.
+  /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
+  /// After register coalescing references of v1024 should be replace with
+  /// v1027:3, v1025 with v1027:4, etc.
+  REG_SEQUENCE = 12,
+
+  /// COPY - Target-independent register copy. This instruction can also be
+  /// used to copy between subregisters of virtual registers.
+  COPY = 13,
+
+  /// BUNDLE - This instruction represents an instruction bundle. Instructions
+  /// which immediately follow a BUNDLE instruction which are marked with
+  /// 'InsideBundle' flag are inside the bundle.
+  BUNDLE = 14,
+
+  /// Lifetime markers.
+  LIFETIME_START = 15,
+  LIFETIME_END = 16,
+
+  /// A Stackmap instruction captures the location of live variables at its
+  /// position in the instruction stream. It is followed by a shadow of bytes
+  /// that must lie within the function and not contain another stackmap.
+  STACKMAP = 17,
+
+  /// Patchable call instruction - this instruction represents a call to a
+  /// constant address, followed by a series of NOPs. It is intended to
+  /// support optimizations for dynamic languages (such as javascript) that
+  /// rewrite calls to runtimes with more efficient code sequences.
+  /// This also implies a stack map.
+  PATCHPOINT = 18
+};
+} // end namespace TargetOpcode
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
new file mode 100644
index 0000000..922fae5
--- /dev/null
+++ b/include/llvm/Target/TargetOptions.h
@@ -0,0 +1,263 @@
+//===-- llvm/Target/TargetOptions.h - Target Options ------------*- 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 command line option flags that are shared across various
+// targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPTIONS_H
+#define LLVM_TARGET_TARGETOPTIONS_H
+
+#include "llvm/MC/MCTargetOptions.h"
+#include <string>
+
+namespace llvm {
+  class MachineFunction;
+  class StringRef;
+
+  // Possible float ABI settings. Used with FloatABIType in TargetOptions.h.
+  namespace FloatABI {
+    enum ABIType {
+      Default, // Target-specific (either soft or hard depending on triple,etc).
+      Soft, // Soft float.
+      Hard  // Hard float.
+    };
+  }
+
+  namespace FPOpFusion {
+    enum FPOpFusionMode {
+      Fast,     // Enable fusion of FP ops wherever it's profitable.
+      Standard, // Only allow fusion of 'blessed' ops (currently just fmuladd).
+      Strict    // Never fuse FP-ops.
+    };
+  }
+
+  namespace JumpTable {
+    enum JumpTableType {
+      Single,          // Use a single table for all indirect jumptable calls.
+      Arity,           // Use one table per number of function parameters.
+      Simplified,      // Use one table per function type, with types projected
+                       // into 4 types: pointer to non-function, struct,
+                       // primitive, and function pointer.
+      Full             // Use one table per unique function type
+    };
+  }
+
+  class TargetOptions {
+  public:
+    TargetOptions()
+        : PrintMachineCode(false), NoFramePointerElim(false),
+          LessPreciseFPMADOption(false), UnsafeFPMath(false),
+          NoInfsFPMath(false), NoNaNsFPMath(false),
+          HonorSignDependentRoundingFPMathOption(false), UseSoftFloat(false),
+          NoZerosInBSS(false), JITEmitDebugInfo(false),
+          JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false),
+          DisableTailCalls(false), StackAlignmentOverride(0),
+          EnableFastISel(false), PositionIndependentExecutable(false),
+          UseInitArray(false), DisableIntegratedAS(false),
+          CompressDebugSections(false), FunctionSections(false),
+          DataSections(false), TrapUnreachable(false), TrapFuncName(""),
+          FloatABIType(FloatABI::Default),
+          AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single) {}
+
+    /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
+    /// option is specified on the command line, and should enable debugging
+    /// output from the code generator.
+    unsigned PrintMachineCode : 1;
+
+    /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is
+    /// specified on the command line.  If the target supports the frame pointer
+    /// elimination optimization, this option should disable it.
+    unsigned NoFramePointerElim : 1;
+
+    /// DisableFramePointerElim - This returns true if frame pointer elimination
+    /// optimization should be disabled for the given machine function.
+    bool DisableFramePointerElim(const MachineFunction &MF) const;
+
+    /// LessPreciseFPMAD - This flag is enabled when the
+    /// -enable-fp-mad is specified on the command line.  When this flag is off
+    /// (the default), the code generator is not allowed to generate mad
+    /// (multiply add) if the result is "less precise" than doing those
+    /// operations individually.
+    unsigned LessPreciseFPMADOption : 1;
+    bool LessPreciseFPMAD() const;
+
+    /// UnsafeFPMath - This flag is enabled when the
+    /// -enable-unsafe-fp-math flag is specified on the command line.  When
+    /// this flag is off (the default), the code generator is not allowed to
+    /// produce results that are "less precise" than IEEE allows.  This includes
+    /// use of X86 instructions like FSIN and FCOS instead of libcalls.
+    /// UnsafeFPMath implies LessPreciseFPMAD.
+    unsigned UnsafeFPMath : 1;
+
+    /// NoInfsFPMath - This flag is enabled when the
+    /// -enable-no-infs-fp-math flag is specified on the command line. When
+    /// this flag is off (the default), the code generator is not allowed to
+    /// assume the FP arithmetic arguments and results are never +-Infs.
+    unsigned NoInfsFPMath : 1;
+
+    /// NoNaNsFPMath - This flag is enabled when the
+    /// -enable-no-nans-fp-math flag is specified on the command line. When
+    /// this flag is off (the default), the code generator is not allowed to
+    /// assume the FP arithmetic arguments and results are never NaNs.
+    unsigned NoNaNsFPMath : 1;
+
+    /// HonorSignDependentRoundingFPMath - This returns true when the
+    /// -enable-sign-dependent-rounding-fp-math is specified.  If this returns
+    /// false (the default), the code generator is allowed to assume that the
+    /// rounding behavior is the default (round-to-zero for all floating point
+    /// to integer conversions, and round-to-nearest for all other arithmetic
+    /// truncations).  If this is enabled (set to true), the code generator must
+    /// assume that the rounding mode may dynamically change.
+    unsigned HonorSignDependentRoundingFPMathOption : 1;
+    bool HonorSignDependentRoundingFPMath() const;
+
+    /// UseSoftFloat - This flag is enabled when the -soft-float flag is
+    /// specified on the command line.  When this flag is on, the code generator
+    /// will generate libcalls to the software floating point library instead of
+    /// target FP instructions.
+    unsigned UseSoftFloat : 1;
+
+    /// NoZerosInBSS - By default some codegens place zero-initialized data to
+    /// .bss section. This flag disables such behaviour (necessary, e.g. for
+    /// crt*.o compiling).
+    unsigned NoZerosInBSS : 1;
+
+    /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit
+    /// debug information and notify a debugger about it.
+    unsigned JITEmitDebugInfo : 1;
+
+    /// JITEmitDebugInfoToDisk - This flag indicates that the JIT should write
+    /// the object files generated by the JITEmitDebugInfo flag to disk.  This
+    /// flag is hidden and is only for debugging the debug info.
+    unsigned JITEmitDebugInfoToDisk : 1;
+
+    /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
+    /// specified on the commandline. When the flag is on, participating targets
+    /// will perform tail call optimization on all calls which use the fastcc
+    /// calling convention and which satisfy certain target-independent
+    /// criteria (being at the end of a function, having the same return type
+    /// as their parent function, etc.), using an alternate ABI if necessary.
+    unsigned GuaranteedTailCallOpt : 1;
+
+    /// DisableTailCalls - This flag controls whether we will use tail calls.
+    /// Disabling them may be useful to maintain a correct call stack.
+    unsigned DisableTailCalls : 1;
+
+    /// StackAlignmentOverride - Override default stack alignment for target.
+    unsigned StackAlignmentOverride;
+
+    /// EnableFastISel - This flag enables fast-path instruction selection
+    /// which trades away generated code quality in favor of reducing
+    /// compile time.
+    unsigned EnableFastISel : 1;
+
+    /// PositionIndependentExecutable - This flag indicates whether the code
+    /// will eventually be linked into a single executable, despite the PIC
+    /// relocation model being in use. It's value is undefined (and irrelevant)
+    /// if the relocation model is anything other than PIC.
+    unsigned PositionIndependentExecutable : 1;
+
+    /// UseInitArray - Use .init_array instead of .ctors for static
+    /// constructors.
+    unsigned UseInitArray : 1;
+
+    /// Disable the integrated assembler.
+    unsigned DisableIntegratedAS : 1;
+
+    /// Compress DWARF debug sections.
+    unsigned CompressDebugSections : 1;
+
+    /// Emit functions into separate sections.
+    unsigned FunctionSections : 1;
+
+    /// Emit data into separate sections.
+    unsigned DataSections : 1;
+
+    /// Emit target-specific trap instruction for 'unreachable' IR instructions.
+    unsigned TrapUnreachable : 1;
+
+    /// getTrapFunctionName - If this returns a non-empty string, this means
+    /// isel should lower Intrinsic::trap to a call to the specified function
+    /// name instead of an ISD::TRAP node.
+    std::string TrapFuncName;
+    StringRef getTrapFunctionName() const;
+
+    /// FloatABIType - This setting is set by -float-abi=xxx option is specfied
+    /// on the command line. This setting may either be Default, Soft, or Hard.
+    /// Default selects the target's default behavior. Soft selects the ABI for
+    /// UseSoftFloat, but does not indicate that FP hardware may not be used.
+    /// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
+    /// Hard presumes that the normal FP ABI is used.
+    FloatABI::ABIType FloatABIType;
+
+    /// AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
+    /// This controls the creation of fused FP ops that store intermediate
+    /// results in higher precision than IEEE allows (E.g. FMAs).
+    ///
+    /// Fast mode - allows formation of fused FP ops whenever they're
+    /// profitable.
+    /// Standard mode - allow fusion only for 'blessed' FP ops. At present the
+    /// only blessed op is the fmuladd intrinsic. In the future more blessed ops
+    /// may be added.
+    /// Strict mode - allow fusion only if/when it can be proven that the excess
+    /// precision won't effect the result.
+    ///
+    /// Note: This option only controls formation of fused ops by the
+    /// optimizers.  Fused operations that are explicitly specified (e.g. FMA
+    /// via the llvm.fma.* intrinsic) will always be honored, regardless of
+    /// the value of this option.
+    FPOpFusion::FPOpFusionMode AllowFPOpFusion;
+
+    /// JTType - This flag specifies the type of jump-instruction table to
+    /// create for functions that have the jumptable attribute.
+    JumpTable::JumpTableType JTType;
+
+    /// Machine level options.
+    MCTargetOptions MCOptions;
+  };
+
+// Comparison operators:
+
+
+inline bool operator==(const TargetOptions &LHS,
+                       const TargetOptions &RHS) {
+#define ARE_EQUAL(X) LHS.X == RHS.X
+  return
+    ARE_EQUAL(UnsafeFPMath) &&
+    ARE_EQUAL(NoInfsFPMath) &&
+    ARE_EQUAL(NoNaNsFPMath) &&
+    ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
+    ARE_EQUAL(UseSoftFloat) &&
+    ARE_EQUAL(NoZerosInBSS) &&
+    ARE_EQUAL(JITEmitDebugInfo) &&
+    ARE_EQUAL(JITEmitDebugInfoToDisk) &&
+    ARE_EQUAL(GuaranteedTailCallOpt) &&
+    ARE_EQUAL(DisableTailCalls) &&
+    ARE_EQUAL(StackAlignmentOverride) &&
+    ARE_EQUAL(EnableFastISel) &&
+    ARE_EQUAL(PositionIndependentExecutable) &&
+    ARE_EQUAL(UseInitArray) &&
+    ARE_EQUAL(TrapUnreachable) &&
+    ARE_EQUAL(TrapFuncName) &&
+    ARE_EQUAL(FloatABIType) &&
+    ARE_EQUAL(AllowFPOpFusion) &&
+    ARE_EQUAL(MCOptions);
+#undef ARE_EQUAL
+}
+
+inline bool operator!=(const TargetOptions &LHS,
+                       const TargetOptions &RHS) {
+  return !(LHS == RHS);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
new file mode 100644
index 0000000..5dda8bd
--- /dev/null
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -0,0 +1,963 @@
+//=== Target/TargetRegisterInfo.h - Target Register Information -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file.  This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
+#define LLVM_TARGET_TARGETREGISTERINFO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include <cassert>
+#include <functional>
+
+namespace llvm {
+
+class BitVector;
+class MachineFunction;
+class RegScavenger;
+template<class T> class SmallVectorImpl;
+class VirtRegMap;
+class raw_ostream;
+
+class TargetRegisterClass {
+public:
+  typedef const MCPhysReg* iterator;
+  typedef const MCPhysReg* const_iterator;
+  typedef const MVT::SimpleValueType* vt_iterator;
+  typedef const TargetRegisterClass* const * sc_iterator;
+
+  // Instance variables filled by tablegen, do not use!
+  const MCRegisterClass *MC;
+  const vt_iterator VTs;
+  const uint32_t *SubClassMask;
+  const uint16_t *SuperRegIndices;
+  const sc_iterator SuperClasses;
+  ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
+
+  /// getID() - Return the register class ID number.
+  ///
+  unsigned getID() const { return MC->getID(); }
+
+  /// getName() - Return the register class name for debugging.
+  ///
+  const char *getName() const { return MC->getName(); }
+
+  /// begin/end - Return all of the registers in this class.
+  ///
+  iterator       begin() const { return MC->begin(); }
+  iterator         end() const { return MC->end(); }
+
+  /// getNumRegs - Return the number of registers in this class.
+  ///
+  unsigned getNumRegs() const { return MC->getNumRegs(); }
+
+  /// getRegister - Return the specified register in the class.
+  ///
+  unsigned getRegister(unsigned i) const {
+    return MC->getRegister(i);
+  }
+
+  /// contains - Return true if the specified register is included in this
+  /// register class.  This does not include virtual registers.
+  bool contains(unsigned Reg) const {
+    return MC->contains(Reg);
+  }
+
+  /// contains - Return true if both registers are in this class.
+  bool contains(unsigned Reg1, unsigned Reg2) const {
+    return MC->contains(Reg1, Reg2);
+  }
+
+  /// getSize - Return the size of the register in bytes, which is also the size
+  /// of a stack slot allocated to hold a spilled copy of this register.
+  unsigned getSize() const { return MC->getSize(); }
+
+  /// getAlignment - Return the minimum required alignment for a register of
+  /// this class.
+  unsigned getAlignment() const { return MC->getAlignment(); }
+
+  /// getCopyCost - Return the cost of copying a value between two registers in
+  /// this class. A negative number means the register class is very expensive
+  /// to copy e.g. status flag register classes.
+  int getCopyCost() const { return MC->getCopyCost(); }
+
+  /// isAllocatable - Return true if this register class may be used to create
+  /// virtual registers.
+  bool isAllocatable() const { return MC->isAllocatable(); }
+
+  /// hasType - return true if this TargetRegisterClass has the ValueType vt.
+  ///
+  bool hasType(EVT vt) const {
+    for(int i = 0; VTs[i] != MVT::Other; ++i)
+      if (EVT(VTs[i]) == vt)
+        return true;
+    return false;
+  }
+
+  /// vt_begin / vt_end - Loop over all of the value types that can be
+  /// represented by values in this register class.
+  vt_iterator vt_begin() const {
+    return VTs;
+  }
+
+  vt_iterator vt_end() const {
+    vt_iterator I = VTs;
+    while (*I != MVT::Other) ++I;
+    return I;
+  }
+
+  /// hasSubClass - return true if the specified TargetRegisterClass
+  /// is a proper sub-class of this TargetRegisterClass.
+  bool hasSubClass(const TargetRegisterClass *RC) const {
+    return RC != this && hasSubClassEq(RC);
+  }
+
+  /// hasSubClassEq - Returns true if RC is a sub-class of or equal to this
+  /// class.
+  bool hasSubClassEq(const TargetRegisterClass *RC) const {
+    unsigned ID = RC->getID();
+    return (SubClassMask[ID / 32] >> (ID % 32)) & 1;
+  }
+
+  /// hasSuperClass - return true if the specified TargetRegisterClass is a
+  /// proper super-class of this TargetRegisterClass.
+  bool hasSuperClass(const TargetRegisterClass *RC) const {
+    return RC->hasSubClass(this);
+  }
+
+  /// hasSuperClassEq - Returns true if RC is a super-class of or equal to this
+  /// class.
+  bool hasSuperClassEq(const TargetRegisterClass *RC) const {
+    return RC->hasSubClassEq(this);
+  }
+
+  /// getSubClassMask - Returns a bit vector of subclasses, including this one.
+  /// The vector is indexed by class IDs, see hasSubClassEq() above for how to
+  /// use it.
+  const uint32_t *getSubClassMask() const {
+    return SubClassMask;
+  }
+
+  /// getSuperRegIndices - Returns a 0-terminated list of sub-register indices
+  /// that project some super-register class into this register class. The list
+  /// has an entry for each Idx such that:
+  ///
+  ///   There exists SuperRC where:
+  ///     For all Reg in SuperRC:
+  ///       this->contains(Reg:Idx)
+  ///
+  const uint16_t *getSuperRegIndices() const {
+    return SuperRegIndices;
+  }
+
+  /// getSuperClasses - Returns a NULL terminated list of super-classes.  The
+  /// classes are ordered by ID which is also a topological ordering from large
+  /// to small classes.  The list does NOT include the current class.
+  sc_iterator getSuperClasses() const {
+    return SuperClasses;
+  }
+
+  /// isASubClass - return true if this TargetRegisterClass is a subset
+  /// class of at least one other TargetRegisterClass.
+  bool isASubClass() const {
+    return SuperClasses[0] != nullptr;
+  }
+
+  /// getRawAllocationOrder - Returns the preferred order for allocating
+  /// registers from this register class in MF. The raw order comes directly
+  /// from the .td file and may include reserved registers that are not
+  /// allocatable. Register allocators should also make sure to allocate
+  /// callee-saved registers only after all the volatiles are used. The
+  /// RegisterClassInfo class provides filtered allocation orders with
+  /// callee-saved registers moved to the end.
+  ///
+  /// The MachineFunction argument can be used to tune the allocatable
+  /// registers based on the characteristics of the function, subtarget, or
+  /// other criteria.
+  ///
+  /// By default, this method returns all registers in the class.
+  ///
+  ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const {
+    return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
+  }
+};
+
+/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about
+/// registers. These are used by codegen, not by MC.
+struct TargetRegisterInfoDesc {
+  unsigned CostPerUse;          // Extra cost of instructions using register.
+  bool inAllocatableClass;      // Register belongs to an allocatable regclass.
+};
+
+/// Each TargetRegisterClass has a per register weight, and weight
+/// limit which must be less than the limits of its pressure sets.
+struct RegClassWeight {
+  unsigned RegWeight;
+  unsigned WeightLimit;
+};
+
+/// TargetRegisterInfo base class - We assume that the target defines a static
+/// array of TargetRegisterDesc objects that represent all of the machine
+/// registers that the target has.  As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+class TargetRegisterInfo : public MCRegisterInfo {
+public:
+  typedef const TargetRegisterClass * const * regclass_iterator;
+private:
+  const TargetRegisterInfoDesc *InfoDesc;     // Extra desc array for codegen
+  const char *const *SubRegIndexNames;        // Names of subreg indexes.
+  // Pointer to array of lane masks, one per sub-reg index.
+  const unsigned *SubRegIndexLaneMasks;
+
+  regclass_iterator RegClassBegin, RegClassEnd;   // List of regclasses
+  unsigned CoveringLanes;
+
+protected:
+  TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
+                     regclass_iterator RegClassBegin,
+                     regclass_iterator RegClassEnd,
+                     const char *const *SRINames,
+                     const unsigned *SRILaneMasks,
+                     unsigned CoveringLanes);
+  virtual ~TargetRegisterInfo();
+public:
+
+  // Register numbers can represent physical registers, virtual registers, and
+  // sometimes stack slots. The unsigned values are divided into these ranges:
+  //
+  //   0           Not a register, can be used as a sentinel.
+  //   [1;2^30)    Physical registers assigned by TableGen.
+  //   [2^30;2^31) Stack slots. (Rarely used.)
+  //   [2^31;2^32) Virtual registers assigned by MachineRegisterInfo.
+  //
+  // Further sentinels can be allocated from the small negative integers.
+  // DenseMapInfo<unsigned> uses -1u and -2u.
+
+  /// isStackSlot - Sometimes it is useful the be able to store a non-negative
+  /// frame index in a variable that normally holds a register. isStackSlot()
+  /// returns true if Reg is in the range used for stack slots.
+  ///
+  /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack
+  /// slots, so if a variable may contains a stack slot, always check
+  /// isStackSlot() first.
+  ///
+  static bool isStackSlot(unsigned Reg) {
+    return int(Reg) >= (1 << 30);
+  }
+
+  /// stackSlot2Index - Compute the frame index from a register value
+  /// representing a stack slot.
+  static int stackSlot2Index(unsigned Reg) {
+    assert(isStackSlot(Reg) && "Not a stack slot");
+    return int(Reg - (1u << 30));
+  }
+
+  /// index2StackSlot - Convert a non-negative frame index to a stack slot
+  /// register value.
+  static unsigned index2StackSlot(int FI) {
+    assert(FI >= 0 && "Cannot hold a negative frame index.");
+    return FI + (1u << 30);
+  }
+
+  /// isPhysicalRegister - Return true if the specified register number is in
+  /// the physical register namespace.
+  static bool isPhysicalRegister(unsigned Reg) {
+    assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+    return int(Reg) > 0;
+  }
+
+  /// isVirtualRegister - Return true if the specified register number is in
+  /// the virtual register namespace.
+  static bool isVirtualRegister(unsigned Reg) {
+    assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+    return int(Reg) < 0;
+  }
+
+  /// virtReg2Index - Convert a virtual register number to a 0-based index.
+  /// The first virtual register in a function will get the index 0.
+  static unsigned virtReg2Index(unsigned Reg) {
+    assert(isVirtualRegister(Reg) && "Not a virtual register");
+    return Reg & ~(1u << 31);
+  }
+
+  /// index2VirtReg - Convert a 0-based index to a virtual register number.
+  /// This is the inverse operation of VirtReg2IndexFunctor below.
+  static unsigned index2VirtReg(unsigned Index) {
+    return Index | (1u << 31);
+  }
+
+  /// getMinimalPhysRegClass - Returns the Register Class of a physical
+  /// register of the given type, picking the most sub register class of
+  /// the right type that contains this physreg.
+  const TargetRegisterClass *
+    getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const;
+
+  /// getAllocatableClass - Return the maximal subclass of the given register
+  /// class that is alloctable, or NULL.
+  const TargetRegisterClass *
+    getAllocatableClass(const TargetRegisterClass *RC) const;
+
+  /// getAllocatableSet - Returns a bitset indexed by register number
+  /// indicating if a register is allocatable or not. If a register class is
+  /// specified, returns the subset for the class.
+  BitVector getAllocatableSet(const MachineFunction &MF,
+                              const TargetRegisterClass *RC = nullptr) const;
+
+  /// getCostPerUse - Return the additional cost of using this register instead
+  /// of other registers in its class.
+  unsigned getCostPerUse(unsigned RegNo) const {
+    return InfoDesc[RegNo].CostPerUse;
+  }
+
+  /// isInAllocatableClass - Return true if the register is in the allocation
+  /// of any register class.
+  bool isInAllocatableClass(unsigned RegNo) const {
+    return InfoDesc[RegNo].inAllocatableClass;
+  }
+
+  /// getSubRegIndexName - Return the human-readable symbolic target-specific
+  /// name for the specified SubRegIndex.
+  const char *getSubRegIndexName(unsigned SubIdx) const {
+    assert(SubIdx && SubIdx < getNumSubRegIndices() &&
+           "This is not a subregister index");
+    return SubRegIndexNames[SubIdx-1];
+  }
+
+  /// getSubRegIndexLaneMask - Return a bitmask representing the parts of a
+  /// register that are covered by SubIdx.
+  ///
+  /// Lane masks for sub-register indices are similar to register units for
+  /// physical registers. The individual bits in a lane mask can't be assigned
+  /// any specific meaning. They can be used to check if two sub-register
+  /// indices overlap.
+  ///
+  /// If the target has a register such that:
+  ///
+  ///   getSubReg(Reg, A) overlaps getSubReg(Reg, B)
+  ///
+  /// then:
+  ///
+  ///   getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0
+  ///
+  /// The converse is not necessarily true. If two lane masks have a common
+  /// bit, the corresponding sub-registers may not overlap, but it can be
+  /// assumed that they usually will.
+  unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
+    // SubIdx == 0 is allowed, it has the lane mask ~0u.
+    assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
+    return SubRegIndexLaneMasks[SubIdx];
+  }
+
+  /// The lane masks returned by getSubRegIndexLaneMask() above can only be
+  /// used to determine if sub-registers overlap - they can't be used to
+  /// determine if a set of sub-registers completely cover another
+  /// sub-register.
+  ///
+  /// The X86 general purpose registers have two lanes corresponding to the
+  /// sub_8bit and sub_8bit_hi sub-registers. Both sub_32bit and sub_16bit have
+  /// lane masks '3', but the sub_16bit sub-register doesn't fully cover the
+  /// sub_32bit sub-register.
+  ///
+  /// On the other hand, the ARM NEON lanes fully cover their registers: The
+  /// dsub_0 sub-register is completely covered by the ssub_0 and ssub_1 lanes.
+  /// This is related to the CoveredBySubRegs property on register definitions.
+  ///
+  /// This function returns a bit mask of lanes that completely cover their
+  /// sub-registers. More precisely, given:
+  ///
+  ///   Covering = getCoveringLanes();
+  ///   MaskA = getSubRegIndexLaneMask(SubA);
+  ///   MaskB = getSubRegIndexLaneMask(SubB);
+  ///
+  /// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by
+  /// SubB.
+  unsigned getCoveringLanes() const { return CoveringLanes; }
+
+  /// regsOverlap - Returns true if the two registers are equal or alias each
+  /// other. The registers may be virtual register.
+  bool regsOverlap(unsigned regA, unsigned regB) const {
+    if (regA == regB) return true;
+    if (isVirtualRegister(regA) || isVirtualRegister(regB))
+      return false;
+
+    // Regunits are numerically ordered. Find a common unit.
+    MCRegUnitIterator RUA(regA, this);
+    MCRegUnitIterator RUB(regB, this);
+    do {
+      if (*RUA == *RUB) return true;
+      if (*RUA < *RUB) ++RUA;
+      else             ++RUB;
+    } while (RUA.isValid() && RUB.isValid());
+    return false;
+  }
+
+  /// hasRegUnit - Returns true if Reg contains RegUnit.
+  bool hasRegUnit(unsigned Reg, unsigned RegUnit) const {
+    for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units)
+      if (*Units == RegUnit)
+        return true;
+    return false;
+  }
+
+  /// getCalleeSavedRegs - Return a null-terminated list of all of the
+  /// callee saved registers on this target. The register should be in the
+  /// order of desired callee-save stack frame offset. The first register is
+  /// closest to the incoming stack pointer if stack grows down, and vice versa.
+  ///
+  virtual const MCPhysReg*
+  getCalleeSavedRegs(const MachineFunction *MF = nullptr) const = 0;
+
+  /// getCallPreservedMask - Return a mask of call-preserved registers for the
+  /// given calling convention on the current sub-target.  The mask should
+  /// include all call-preserved aliases.  This is used by the register
+  /// allocator to determine which registers can be live across a call.
+  ///
+  /// The mask is an array containing (TRI::getNumRegs()+31)/32 entries.
+  /// A set bit indicates that all bits of the corresponding register are
+  /// preserved across the function call.  The bit mask is expected to be
+  /// sub-register complete, i.e. if A is preserved, so are all its
+  /// sub-registers.
+  ///
+  /// Bits are numbered from the LSB, so the bit for physical register Reg can
+  /// be found as (Mask[Reg / 32] >> Reg % 32) & 1.
+  ///
+  /// A NULL pointer means that no register mask will be used, and call
+  /// instructions should use implicit-def operands to indicate call clobbered
+  /// registers.
+  ///
+  virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const {
+    // The default mask clobbers everything.  All targets should override.
+    return nullptr;
+  }
+
+  /// getReservedRegs - Returns a bitset indexed by physical register number
+  /// indicating if a register is a special register that has particular uses
+  /// and should be considered unavailable at all times, e.g. SP, RA. This is
+  /// used by register scavenger to determine what registers are free.
+  virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+
+  /// getMatchingSuperReg - Return a super-register of the specified register
+  /// Reg so its sub-register of index SubIdx is Reg.
+  unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
+                               const TargetRegisterClass *RC) const {
+    return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
+  }
+
+  /// getMatchingSuperRegClass - Return a subclass of the specified register
+  /// class A so that each register in it has a sub-register of the
+  /// specified sub-register index which is in the specified register class B.
+  ///
+  /// TableGen will synthesize missing A sub-classes.
+  virtual const TargetRegisterClass *
+  getMatchingSuperRegClass(const TargetRegisterClass *A,
+                           const TargetRegisterClass *B, unsigned Idx) const;
+
+  /// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
+  /// supports the sub-register index Idx.
+  /// If no such sub-class exists, return NULL.
+  /// If all registers in RC already have an Idx sub-register, return RC.
+  ///
+  /// TableGen generates a version of this function that is good enough in most
+  /// cases.  Targets can override if they have constraints that TableGen
+  /// doesn't understand.  For example, the x86 sub_8bit sub-register index is
+  /// supported by the full GR32 register class in 64-bit mode, but only by the
+  /// GR32_ABCD regiister class in 32-bit mode.
+  ///
+  /// TableGen will synthesize missing RC sub-classes.
+  virtual const TargetRegisterClass *
+  getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const {
+    assert(Idx == 0 && "Target has no sub-registers");
+    return RC;
+  }
+
+  /// composeSubRegIndices - Return the subregister index you get from composing
+  /// two subregister indices.
+  ///
+  /// The special null sub-register index composes as the identity.
+  ///
+  /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
+  /// returns c. Note that composeSubRegIndices does not tell you about illegal
+  /// compositions. If R does not have a subreg a, or R:a does not have a subreg
+  /// b, composeSubRegIndices doesn't tell you.
+  ///
+  /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has
+  /// ssub_0:S0 - ssub_3:S3 subregs.
+  /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
+  ///
+  unsigned composeSubRegIndices(unsigned a, unsigned b) const {
+    if (!a) return b;
+    if (!b) return a;
+    return composeSubRegIndicesImpl(a, b);
+  }
+
+protected:
+  /// Overridden by TableGen in targets that have sub-registers.
+  virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
+    llvm_unreachable("Target has no sub-registers");
+  }
+
+public:
+  /// getCommonSuperRegClass - Find a common super-register class if it exists.
+  ///
+  /// Find a register class, SuperRC and two sub-register indices, PreA and
+  /// PreB, such that:
+  ///
+  ///   1. PreA + SubA == PreB + SubB  (using composeSubRegIndices()), and
+  ///
+  ///   2. For all Reg in SuperRC: Reg:PreA in RCA and Reg:PreB in RCB, and
+  ///
+  ///   3. SuperRC->getSize() >= max(RCA->getSize(), RCB->getSize()).
+  ///
+  /// SuperRC will be chosen such that no super-class of SuperRC satisfies the
+  /// requirements, and there is no register class with a smaller spill size
+  /// that satisfies the requirements.
+  ///
+  /// SubA and SubB must not be 0. Use getMatchingSuperRegClass() instead.
+  ///
+  /// Either of the PreA and PreB sub-register indices may be returned as 0. In
+  /// that case, the returned register class will be a sub-class of the
+  /// corresponding argument register class.
+  ///
+  /// The function returns NULL if no register class can be found.
+  ///
+  const TargetRegisterClass*
+  getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
+                         const TargetRegisterClass *RCB, unsigned SubB,
+                         unsigned &PreA, unsigned &PreB) const;
+
+  //===--------------------------------------------------------------------===//
+  // Register Class Information
+  //
+
+  /// Register class iterators
+  ///
+  regclass_iterator regclass_begin() const { return RegClassBegin; }
+  regclass_iterator regclass_end() const { return RegClassEnd; }
+
+  unsigned getNumRegClasses() const {
+    return (unsigned)(regclass_end()-regclass_begin());
+  }
+
+  /// getRegClass - Returns the register class associated with the enumeration
+  /// value.  See class MCOperandInfo.
+  const TargetRegisterClass *getRegClass(unsigned i) const {
+    assert(i < getNumRegClasses() && "Register Class ID out of range");
+    return RegClassBegin[i];
+  }
+
+  /// getCommonSubClass - find the largest common subclass of A and B. Return
+  /// NULL if there is no common subclass.
+  const TargetRegisterClass *
+  getCommonSubClass(const TargetRegisterClass *A,
+                    const TargetRegisterClass *B) const;
+
+  /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
+  /// values.  If a target supports multiple different pointer register classes,
+  /// kind specifies which one is indicated.
+  virtual const TargetRegisterClass *
+  getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const {
+    llvm_unreachable("Target didn't implement getPointerRegClass!");
+  }
+
+  /// getCrossCopyRegClass - Returns a legal register class to copy a register
+  /// in the specified class to or from. If it is possible to copy the register
+  /// directly without using a cross register class copy, return the specified
+  /// RC. Returns NULL if it is not possible to copy between a two registers of
+  /// the specified class.
+  virtual const TargetRegisterClass *
+  getCrossCopyRegClass(const TargetRegisterClass *RC) const {
+    return RC;
+  }
+
+  /// getLargestLegalSuperClass - Returns the largest super class of RC that is
+  /// legal to use in the current sub-target and has the same spill size.
+  /// The returned register class can be used to create virtual registers which
+  /// means that all its registers can be copied and spilled.
+  virtual const TargetRegisterClass*
+  getLargestLegalSuperClass(const TargetRegisterClass *RC) const {
+    /// The default implementation is very conservative and doesn't allow the
+    /// register allocator to inflate register classes.
+    return RC;
+  }
+
+  /// getRegPressureLimit - Return the register pressure "high water mark" for
+  /// the specific register class. The scheduler is in high register pressure
+  /// mode (for the specific register class) if it goes over the limit.
+  ///
+  /// Note: this is the old register pressure model that relies on a manually
+  /// specified representative register class per value type.
+  virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC,
+                                       MachineFunction &MF) const {
+    return 0;
+  }
+
+  /// Get the weight in units of pressure for this register class.
+  virtual const RegClassWeight &getRegClassWeight(
+    const TargetRegisterClass *RC) const = 0;
+
+  /// Get the weight in units of pressure for this register unit.
+  virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0;
+
+  /// Get the number of dimensions of register pressure.
+  virtual unsigned getNumRegPressureSets() const = 0;
+
+  /// Get the name of this register unit pressure set.
+  virtual const char *getRegPressureSetName(unsigned Idx) const = 0;
+
+  /// Get the register unit pressure limit for this dimension.
+  /// This limit must be adjusted dynamically for reserved registers.
+  virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
+
+  /// Get the dimensions of register pressure impacted by this register class.
+  /// Returns a -1 terminated array of pressure set IDs.
+  virtual const int *getRegClassPressureSets(
+    const TargetRegisterClass *RC) const = 0;
+
+  /// Get the dimensions of register pressure impacted by this register unit.
+  /// Returns a -1 terminated array of pressure set IDs.
+  virtual const int *getRegUnitPressureSets(unsigned RegUnit) const = 0;
+
+  /// Get a list of 'hint' registers that the register allocator should try
+  /// first when allocating a physical register for the virtual register
+  /// VirtReg. These registers are effectively moved to the front of the
+  /// allocation order.
+  ///
+  /// The Order argument is the allocation order for VirtReg's register class
+  /// as returned from RegisterClassInfo::getOrder(). The hint registers must
+  /// come from Order, and they must not be reserved.
+  ///
+  /// The default implementation of this function can resolve
+  /// target-independent hints provided to MRI::setRegAllocationHint with
+  /// HintType == 0. Targets that override this function should defer to the
+  /// default implementation if they have no reason to change the allocation
+  /// order for VirtReg. There may be target-independent hints.
+  virtual void getRegAllocationHints(unsigned VirtReg,
+                                     ArrayRef<MCPhysReg> Order,
+                                     SmallVectorImpl<MCPhysReg> &Hints,
+                                     const MachineFunction &MF,
+                                     const VirtRegMap *VRM = nullptr) const;
+
+  /// avoidWriteAfterWrite - Return true if the register allocator should avoid
+  /// writing a register from RC in two consecutive instructions.
+  /// This can avoid pipeline stalls on certain architectures.
+  /// It does cause increased register pressure, though.
+  virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
+    return false;
+  }
+
+  /// UpdateRegAllocHint - A callback to allow target a chance to update
+  /// register allocation hints when a register is "changed" (e.g. coalesced)
+  /// to another register. e.g. On ARM, some virtual registers should target
+  /// register pairs, if one of pair is coalesced to another register, the
+  /// allocation hint of the other half of the pair should be changed to point
+  /// to the new register.
+  virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+                                  MachineFunction &MF) const {
+    // Do nothing.
+  }
+
+  /// Allow the target to reverse allocation order of local live ranges. This
+  /// will generally allocate shorter local live ranges first. For targets with
+  /// many registers, this could reduce regalloc compile time by a large
+  /// factor. It is disabled by default for three reasons:
+  /// (1) Top-down allocation is simpler and easier to debug for targets that
+  /// don't benefit from reversing the order.
+  /// (2) Bottom-up allocation could result in poor evicition decisions on some
+  /// targets affecting the performance of compiled code.
+  /// (3) Bottom-up allocation is no longer guaranteed to optimally color.
+  virtual bool reverseLocalAssignment() const { return false; }
+
+  /// Allow the target to override register assignment heuristics based on the
+  /// live range size. If this returns false, then local live ranges are always
+  /// assigned in order regardless of their size. This is a temporary hook for
+  /// debugging downstream codegen failures exposed by regalloc.
+  virtual bool mayOverrideLocalAssignment() const { return true; }
+
+  /// Allow the target to override the cost of using a callee-saved register for
+  /// the first time. Default value of 0 means we will use a callee-saved
+  /// register if it is available.
+  virtual unsigned getCSRFirstUseCost() const { return 0; }
+
+  /// requiresRegisterScavenging - returns true if the target requires (and can
+  /// make use of) the register scavenger.
+  virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
+    return false;
+  }
+
+  /// useFPForScavengingIndex - returns true if the target wants to use
+  /// frame pointer based accesses to spill to the scavenger emergency spill
+  /// slot.
+  virtual bool useFPForScavengingIndex(const MachineFunction &MF) const {
+    return true;
+  }
+
+  /// requiresFrameIndexScavenging - returns true if the target requires post
+  /// PEI scavenging of registers for materializing frame index constants.
+  virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const {
+    return false;
+  }
+
+  /// requiresVirtualBaseRegisters - Returns true if the target wants the
+  /// LocalStackAllocation pass to be run and virtual base registers
+  /// used for more efficient stack access.
+  virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const {
+    return false;
+  }
+
+  /// hasReservedSpillSlot - Return true if target has reserved a spill slot in
+  /// the stack frame of the given function for the specified register. e.g. On
+  /// x86, if the frame register is required, the first fixed stack object is
+  /// reserved as its spill slot. This tells PEI not to create a new stack frame
+  /// object for the given register. It should be called only after
+  /// processFunctionBeforeCalleeSavedScan().
+  virtual bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
+                                    int &FrameIdx) const {
+    return false;
+  }
+
+  /// trackLivenessAfterRegAlloc - returns true if the live-ins should be tracked
+  /// after register allocation.
+  virtual bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
+    return false;
+  }
+
+  /// needsStackRealignment - true if storage within the function requires the
+  /// stack pointer to be aligned more than the normal calling convention calls
+  /// for.
+  virtual bool needsStackRealignment(const MachineFunction &MF) const {
+    return false;
+  }
+
+  /// getFrameIndexInstrOffset - Get the offset from the referenced frame
+  /// index in the instruction, if there is one.
+  virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
+                                           int Idx) const {
+    return 0;
+  }
+
+  /// needsFrameBaseReg - Returns true if the instruction's frame index
+  /// reference would be better served by a base register other than FP
+  /// or SP. Used by LocalStackFrameAllocation to determine which frame index
+  /// references it should create new base registers for.
+  virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
+    return false;
+  }
+
+  /// materializeFrameBaseRegister - Insert defining instruction(s) for
+  /// BaseReg to be a pointer to FrameIdx before insertion point I.
+  virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
+                                            unsigned BaseReg, int FrameIdx,
+                                            int64_t Offset) const {
+    llvm_unreachable("materializeFrameBaseRegister does not exist on this "
+                     "target");
+  }
+
+  /// resolveFrameIndex - Resolve a frame index operand of an instruction
+  /// to reference the indicated base register plus offset instead.
+  virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
+                                 int64_t Offset) const {
+    llvm_unreachable("resolveFrameIndex does not exist on this target");
+  }
+
+  /// isFrameOffsetLegal - Determine whether a given offset immediate is
+  /// encodable to resolve a frame index.
+  virtual bool isFrameOffsetLegal(const MachineInstr *MI,
+                                  int64_t Offset) const {
+    llvm_unreachable("isFrameOffsetLegal does not exist on this target");
+  }
+
+
+  /// saveScavengerRegister - Spill the register so it can be used by the
+  /// register scavenger. Return true if the register was spilled, false
+  /// otherwise. If this function does not spill the register, the scavenger
+  /// will instead spill it to the emergency spill slot.
+  ///
+  virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator I,
+                                     MachineBasicBlock::iterator &UseMI,
+                                     const TargetRegisterClass *RC,
+                                     unsigned Reg) const {
+    return false;
+  }
+
+  /// eliminateFrameIndex - This method must be overriden to eliminate abstract
+  /// frame indices from instructions which may use them.  The instruction
+  /// referenced by the iterator contains an MO_FrameIndex operand which must be
+  /// eliminated by this method.  This method may modify or replace the
+  /// specified instruction, as long as it keeps the iterator pointing at the
+  /// finished product.  SPAdj is the SP adjustment due to call frame setup
+  /// instruction.  FIOperandNum is the FI operand number.
+  virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+                                   int SPAdj, unsigned FIOperandNum,
+                                   RegScavenger *RS = nullptr) const = 0;
+
+  //===--------------------------------------------------------------------===//
+  /// Subtarget Hooks
+
+  /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true.
+  virtual bool shouldCoalesce(MachineInstr *MI,
+                              const TargetRegisterClass *SrcRC,
+                              unsigned SubReg,
+                              const TargetRegisterClass *DstRC,
+                              unsigned DstSubReg,
+                              const TargetRegisterClass *NewRC) const
+  { return true; }
+
+  //===--------------------------------------------------------------------===//
+  /// Debug information queries.
+
+  /// getFrameRegister - This method should return the register used as a base
+  /// for values allocated in the current stack frame.
+  virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
+};
+
+
+//===----------------------------------------------------------------------===//
+//                           SuperRegClassIterator
+//===----------------------------------------------------------------------===//
+//
+// Iterate over the possible super-registers for a given register class. The
+// iterator will visit a list of pairs (Idx, Mask) corresponding to the
+// possible classes of super-registers.
+//
+// Each bit mask will have at least one set bit, and each set bit in Mask
+// corresponds to a SuperRC such that:
+//
+//   For all Reg in SuperRC: Reg:Idx is in RC.
+//
+// The iterator can include (O, RC->getSubClassMask()) as the first entry which
+// also satisfies the above requirement, assuming Reg:0 == Reg.
+//
+class SuperRegClassIterator {
+  const unsigned RCMaskWords;
+  unsigned SubReg;
+  const uint16_t *Idx;
+  const uint32_t *Mask;
+
+public:
+  /// Create a SuperRegClassIterator that visits all the super-register classes
+  /// of RC. When IncludeSelf is set, also include the (0, sub-classes) entry.
+  SuperRegClassIterator(const TargetRegisterClass *RC,
+                        const TargetRegisterInfo *TRI,
+                        bool IncludeSelf = false)
+    : RCMaskWords((TRI->getNumRegClasses() + 31) / 32),
+      SubReg(0),
+      Idx(RC->getSuperRegIndices()),
+      Mask(RC->getSubClassMask()) {
+    if (!IncludeSelf)
+      ++*this;
+  }
+
+  /// Returns true if this iterator is still pointing at a valid entry.
+  bool isValid() const { return Idx; }
+
+  /// Returns the current sub-register index.
+  unsigned getSubReg() const { return SubReg; }
+
+  /// Returns the bit mask if register classes that getSubReg() projects into
+  /// RC.
+  const uint32_t *getMask() const { return Mask; }
+
+  /// Advance iterator to the next entry.
+  void operator++() {
+    assert(isValid() && "Cannot move iterator past end.");
+    Mask += RCMaskWords;
+    SubReg = *Idx++;
+    if (!SubReg)
+      Idx = nullptr;
+  }
+};
+
+// This is useful when building IndexedMaps keyed on virtual registers
+struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
+  unsigned operator()(unsigned Reg) const {
+    return TargetRegisterInfo::virtReg2Index(Reg);
+  }
+};
+
+/// PrintReg - Helper class for printing registers on a raw_ostream.
+/// Prints virtual and physical registers with or without a TRI instance.
+///
+/// The format is:
+///   %noreg          - NoRegister
+///   %vreg5          - a virtual register.
+///   %vreg5:sub_8bit - a virtual register with sub-register index (with TRI).
+///   %EAX            - a physical register
+///   %physreg17      - a physical register when no TRI instance given.
+///
+/// Usage: OS << PrintReg(Reg, TRI) << '\n';
+///
+class PrintReg {
+  const TargetRegisterInfo *TRI;
+  unsigned Reg;
+  unsigned SubIdx;
+public:
+  explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = nullptr,
+                    unsigned subidx = 0)
+    : TRI(tri), Reg(reg), SubIdx(subidx) {}
+  void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
+  PR.print(OS);
+  return OS;
+}
+
+/// PrintRegUnit - Helper class for printing register units on a raw_ostream.
+///
+/// Register units are named after their root registers:
+///
+///   AL      - Single root.
+///   FP0~ST7 - Dual roots.
+///
+/// Usage: OS << PrintRegUnit(Unit, TRI) << '\n';
+///
+class PrintRegUnit {
+protected:
+  const TargetRegisterInfo *TRI;
+  unsigned Unit;
+public:
+  PrintRegUnit(unsigned unit, const TargetRegisterInfo *tri)
+    : TRI(tri), Unit(unit) {}
+  void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) {
+  PR.print(OS);
+  return OS;
+}
+
+/// PrintVRegOrUnit - It is often convenient to track virtual registers and
+/// physical register units in the same list.
+class PrintVRegOrUnit : protected PrintRegUnit {
+public:
+  PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *tri)
+    : PrintRegUnit(VRegOrUnit, tri) {}
+  void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS,
+                                      const PrintVRegOrUnit &PR) {
+  PR.print(OS);
+  return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
new file mode 100644
index 0000000..89db37c
--- /dev/null
+++ b/include/llvm/Target/TargetSchedule.td
@@ -0,0 +1,419 @@
+//===- TargetSchedule.td - Target Independent Scheduling ---*- tablegen -*-===//
+//
+//                     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 target-independent scheduling interfaces which should
+// be implemented by each target which is using TableGen based scheduling.
+//
+// The SchedMachineModel is defined by subtargets for three categories of data:
+// 1. Basic properties for coarse grained instruction cost model.
+// 2. Scheduler Read/Write resources for simple per-opcode cost model.
+// 3. Instruction itineraties for detailed reservation tables.
+//
+// (1) Basic properties are defined by the SchedMachineModel
+// class. Target hooks allow subtargets to associate opcodes with
+// those properties.
+//
+// (2) A per-operand machine model can be implemented in any
+// combination of the following ways:
+//
+// A. Associate per-operand SchedReadWrite types with Instructions by
+// modifying the Instruction definition to inherit from Sched. For
+// each subtarget, define WriteRes and ReadAdvance to associate
+// processor resources and latency with each SchedReadWrite type.
+//
+// B. In each instruction definition, name an ItineraryClass. For each
+// subtarget, define ItinRW entries to map ItineraryClass to
+// per-operand SchedReadWrite types. Unlike method A, these types may
+// be subtarget specific and can be directly associated with resources
+// by defining SchedWriteRes and SchedReadAdvance.
+//
+// C. In the subtarget, map SchedReadWrite types to specific
+// opcodes. This overrides any SchedReadWrite types or
+// ItineraryClasses defined by the Instruction. As in method B, the
+// subtarget can directly associate resources with SchedReadWrite
+// types by defining SchedWriteRes and SchedReadAdvance.
+//
+// D. In either the target or subtarget, define SchedWriteVariant or
+// SchedReadVariant to map one SchedReadWrite type onto another
+// sequence of SchedReadWrite types. This allows dynamic selection of
+// an instruction's machine model via custom C++ code. It also allows
+// a machine-independent SchedReadWrite type to map to a sequence of
+// machine-dependent types.
+//
+// (3) A per-pipeline-stage machine model can be implemented by providing
+// Itineraries in addition to mapping instructions to ItineraryClasses.
+//===----------------------------------------------------------------------===//
+
+// Include legacy support for instruction itineraries.
+include "llvm/Target/TargetItinerary.td"
+
+class Instruction; // Forward def
+
+// DAG operator that interprets the DAG args as Instruction defs.
+def instrs;
+
+// DAG operator that interprets each DAG arg as a regex pattern for
+// matching Instruction opcode names.
+// The regex must match the beginning of the opcode (as in Python re.match).
+// To avoid matching prefixes, append '$' to the pattern.
+def instregex;
+
+// Define the SchedMachineModel and provide basic properties for
+// coarse grained instruction cost model. Default values for the
+// properties are defined in MCSchedModel. A value of "-1" in the
+// target description's SchedMachineModel indicates that the property
+// is not overriden by the target.
+//
+// Target hooks allow subtargets to associate LoadLatency and
+// HighLatency with groups of opcodes.
+//
+// See MCSchedule.h for detailed comments.
+class SchedMachineModel {
+  int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
+  int MinLatency = -1; // Determines which instructions are allowed in a group.
+                       // (-1) inorder (0) ooo, (1): inorder +var latencies.
+  int MicroOpBufferSize = -1; // Max micro-ops that can be buffered.
+  int LoopMicroOpBufferSize = -1; // Max micro-ops that can be buffered for
+                                  // optimized loop dispatch/execution.
+  int LoadLatency = -1; // Cycles for loads to access the cache.
+  int HighLatency = -1; // Approximation of cycles for "high latency" ops.
+  int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
+
+  // Per-cycle resources tables.
+  ProcessorItineraries Itineraries = NoItineraries;
+
+  bit PostRAScheduler = 0; // Enable Post RegAlloc Scheduler pass.
+
+  // Subtargets that define a model for only a subset of instructions
+  // that have a scheduling class (itinerary class or SchedRW list)
+  // and may actually be generated for that subtarget must clear this
+  // bit. Otherwise, the scheduler considers an unmodelled opcode to
+  // be an error. This should only be set during initial bringup,
+  // or there will be no way to catch simple errors in the model
+  // resulting from changes to the instruction definitions.
+  bit CompleteModel = 1;
+
+  bit NoModel = 0; // Special tag to indicate missing machine model.
+}
+
+def NoSchedModel : SchedMachineModel {
+  let NoModel = 1;
+}
+
+// Define a kind of processor resource that may be common across
+// similar subtargets.
+class ProcResourceKind;
+
+// Define a number of interchangeable processor resources. NumUnits
+// determines the throughput of instructions that require the resource.
+//
+// An optional Super resource may be given to model these resources as
+// a subset of the more general super resources. Using one of these
+// resources implies using one of the super resoruces.
+//
+// ProcResourceUnits normally model a few buffered resources within an
+// out-of-order engine. Buffered resources may be held for multiple
+// clock cycles, but the scheduler does not pin them to a particular
+// clock cycle relative to instruction dispatch. Setting BufferSize=0
+// changes this to an in-order issue/dispatch resource. In this case,
+// the scheduler counts down from the cycle that the instruction
+// issues in-order, forcing a stall whenever a subsequent instruction
+// requires the same resource until the number of ResourceCyles
+// specified in WriteRes expire. Setting BufferSize=1 changes this to
+// an in-order latency resource. In this case, the scheduler models
+// producer/consumer stalls between instructions that use the
+// resource.
+//
+// Examples (all assume an out-of-order engine):
+//
+// Use BufferSize = -1 for "issue ports" fed by a unified reservation
+// station. Here the size of the reservation station is modeled by
+// MicroOpBufferSize, which should be the minimum size of either the
+// register rename pool, unified reservation station, or reorder
+// buffer.
+//
+// Use BufferSize = 0 for resources that force "dispatch/issue
+// groups". (Different processors define dispath/issue
+// differently. Here we refer to stage between decoding into micro-ops
+// and moving them into a reservation station.) Normally NumMicroOps
+// is sufficient to limit dispatch/issue groups. However, some
+// processors can form groups of with only certain combinitions of
+// instruction types. e.g. POWER7.
+//
+// Use BufferSize = 1 for in-order execution units. This is used for
+// an in-order pipeline within an out-of-order core where scheduling
+// dependent operations back-to-back is guaranteed to cause a
+// bubble. e.g. Cortex-a9 floating-point.
+//
+// Use BufferSize > 1 for out-of-order executions units with a
+// separate reservation station. This simply models the size of the
+// reservation station.
+//
+// To model both dispatch/issue groups and in-order execution units,
+// create two types of units, one with BufferSize=0 and one with
+// BufferSize=1.
+//
+// SchedModel ties these units to a processor for any stand-alone defs
+// of this class. Instances of subclass ProcResource will be automatically
+// attached to a processor, so SchedModel is not needed.
+class ProcResourceUnits<ProcResourceKind kind, int num> {
+  ProcResourceKind Kind = kind;
+  int NumUnits = num;
+  ProcResourceKind Super = ?;
+  int BufferSize = -1;
+  SchedMachineModel SchedModel = ?;
+}
+
+// EponymousProcResourceKind helps implement ProcResourceUnits by
+// allowing a ProcResourceUnits definition to reference itself. It
+// should not be referenced anywhere else.
+def EponymousProcResourceKind : ProcResourceKind;
+
+// Subtargets typically define processor resource kind and number of
+// units in one place.
+class ProcResource<int num> : ProcResourceKind,
+  ProcResourceUnits<EponymousProcResourceKind, num>;
+
+class ProcResGroup<list<ProcResource> resources> : ProcResourceKind {
+  list<ProcResource> Resources = resources;
+  SchedMachineModel SchedModel = ?;
+  int BufferSize = -1;
+}
+
+// A target architecture may define SchedReadWrite types and associate
+// them with instruction operands.
+class SchedReadWrite;
+
+// List the per-operand types that map to the machine model of an
+// instruction. One SchedWrite type must be listed for each explicit
+// def operand in order. Additional SchedWrite types may optionally be
+// listed for implicit def operands.  SchedRead types may optionally
+// be listed for use operands in order. The order of defs relative to
+// uses is insignificant. This way, the same SchedReadWrite list may
+// be used for multiple forms of an operation. For example, a
+// two-address instruction could have two tied operands or single
+// operand that both reads and writes a reg. In both cases we have a
+// single SchedWrite and single SchedRead in any order.
+class Sched<list<SchedReadWrite> schedrw> {
+  list<SchedReadWrite> SchedRW = schedrw;
+}
+
+// Define a scheduler resource associated with a def operand.
+class SchedWrite : SchedReadWrite;
+def NoWrite : SchedWrite;
+
+// Define a scheduler resource associated with a use operand.
+class SchedRead  : SchedReadWrite;
+
+// Define a SchedWrite that is modeled as a sequence of other
+// SchedWrites with additive latency. This allows a single operand to
+// be mapped the resources composed from a set of previously defined
+// SchedWrites.
+//
+// If the final write in this sequence is a SchedWriteVariant marked
+// Variadic, then the list of prior writes are distributed across all
+// operands after resolving the predicate for the final write.
+//
+// SchedModel silences warnings but is ignored.
+class WriteSequence<list<SchedWrite> writes, int rep = 1> : SchedWrite {
+  list<SchedWrite> Writes = writes;
+  int Repeat = rep;
+  SchedMachineModel SchedModel = ?;
+}
+
+// Define values common to WriteRes and SchedWriteRes.
+//
+// SchedModel ties these resources to a processor.
+class ProcWriteResources<list<ProcResourceKind> resources> {
+  list<ProcResourceKind> ProcResources = resources;
+  list<int> ResourceCycles = [];
+  int Latency = 1;
+  int NumMicroOps = 1;
+  bit BeginGroup = 0;
+  bit EndGroup = 0;
+  // Allow a processor to mark some scheduling classes as unsupported
+  // for stronger verification.
+  bit Unsupported = 0;
+  SchedMachineModel SchedModel = ?;
+}
+
+// Define the resources and latency of a SchedWrite. This will be used
+// directly by targets that have no itinerary classes. In this case,
+// SchedWrite is defined by the target, while WriteResources is
+// defined by the subtarget, and maps the SchedWrite to processor
+// resources.
+//
+// If a target already has itinerary classes, SchedWriteResources can
+// be used instead to define subtarget specific SchedWrites and map
+// them to processor resources in one place. Then ItinRW can map
+// itinerary classes to the subtarget's SchedWrites.
+//
+// ProcResources indicates the set of resources consumed by the write.
+// Optionally, ResourceCycles indicates the number of cycles the
+// resource is consumed. Each ResourceCycles item is paired with the
+// ProcResource item at the same position in its list. Since
+// ResourceCycles are rarely specialized, the list may be
+// incomplete. By default, resources are consumed for a single cycle,
+// regardless of latency, which models a fully pipelined processing
+// unit. A value of 0 for ResourceCycles means that the resource must
+// be available but is not consumed, which is only relevant for
+// unbuffered resources.
+//
+// By default, each SchedWrite takes one micro-op, which is counted
+// against the processor's IssueWidth limit. If an instruction can
+// write multiple registers with a single micro-op, the subtarget
+// should define one of the writes to be zero micro-ops. If a
+// subtarget requires multiple micro-ops to write a single result, it
+// should either override the write's NumMicroOps to be greater than 1
+// or require additional writes. Extra writes can be required either
+// by defining a WriteSequence, or simply listing extra writes in the
+// instruction's list of writers beyond the number of "def"
+// operands. The scheduler assumes that all micro-ops must be
+// dispatched in the same cycle. These micro-ops may be required to
+// begin or end the current dispatch group.
+class WriteRes<SchedWrite write, list<ProcResourceKind> resources>
+  : ProcWriteResources<resources> {
+  SchedWrite WriteType = write;
+}
+
+// Directly name a set of WriteResources defining a new SchedWrite
+// type at the same time. This class is unaware of its SchedModel so
+// must be referenced by InstRW or ItinRW.
+class SchedWriteRes<list<ProcResourceKind> resources> : SchedWrite,
+  ProcWriteResources<resources>;
+
+// Define values common to ReadAdvance and SchedReadAdvance.
+//
+// SchedModel ties these resources to a processor.
+class ProcReadAdvance<int cycles, list<SchedWrite> writes = []> {
+  int Cycles = cycles;
+  list<SchedWrite> ValidWrites = writes;
+  // Allow a processor to mark some scheduling classes as unsupported
+  // for stronger verification.
+  bit Unsupported = 0;
+  SchedMachineModel SchedModel = ?;
+}
+
+// A processor may define a ReadAdvance associated with a SchedRead
+// to reduce latency of a prior write by N cycles. A negative advance
+// effectively increases latency, which may be used for cross-domain
+// stalls.
+//
+// A ReadAdvance may be associated with a list of SchedWrites
+// to implement pipeline bypass. The Writes list may be empty to
+// indicate operands that are always read this number of Cycles later
+// than a normal register read, allowing the read's parent instruction
+// to issue earlier relative to the writer.
+class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []>
+  : ProcReadAdvance<cycles, writes> {
+  SchedRead ReadType = read;
+}
+
+// Directly associate a new SchedRead type with a delay and optional
+// pipeline bypess. For use with InstRW or ItinRW.
+class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead,
+  ProcReadAdvance<cycles, writes>;
+
+// Define SchedRead defaults. Reads seldom need special treatment.
+def ReadDefault : SchedRead;
+def NoReadAdvance : SchedReadAdvance<0>;
+
+// Define shared code that will be in the same scope as all
+// SchedPredicates. Available variables are:
+// (const MachineInstr *MI, const TargetSchedModel *SchedModel)
+class PredicateProlog<code c> {
+  code Code = c;
+}
+
+// Define a predicate to determine which SchedVariant applies to a
+// particular MachineInstr. The code snippet is used as an
+// if-statement's expression. Available variables are MI, SchedModel,
+// and anything defined in a PredicateProlog.
+//
+// SchedModel silences warnings but is ignored.
+class SchedPredicate<code pred> {
+  SchedMachineModel SchedModel = ?;
+  code Predicate = pred;
+}
+def NoSchedPred : SchedPredicate<[{true}]>;
+
+// Associate a predicate with a list of SchedReadWrites. By default,
+// the selected SchedReadWrites are still associated with a single
+// operand and assumed to execute sequentially with additive
+// latency. However, if the parent SchedWriteVariant or
+// SchedReadVariant is marked "Variadic", then each Selected
+// SchedReadWrite is mapped in place to the instruction's variadic
+// operands. In this case, latency is not additive. If the current Variant
+// is already part of a Sequence, then that entire chain leading up to
+// the Variant is distributed over the variadic operands.
+class SchedVar<SchedPredicate pred, list<SchedReadWrite> selected> {
+  SchedPredicate Predicate = pred;
+  list<SchedReadWrite> Selected = selected;
+}
+
+// SchedModel silences warnings but is ignored.
+class SchedVariant<list<SchedVar> variants> {
+  list<SchedVar> Variants = variants;
+  bit Variadic = 0;
+  SchedMachineModel SchedModel = ?;
+}
+
+// A SchedWriteVariant is a single SchedWrite type that maps to a list
+// of SchedWrite types under the conditions defined by its predicates.
+//
+// A Variadic write is expanded to cover multiple "def" operands. The
+// SchedVariant's Expansion list is then interpreted as one write
+// per-operand instead of the usual sequential writes feeding a single
+// operand.
+class SchedWriteVariant<list<SchedVar> variants> : SchedWrite,
+  SchedVariant<variants> {
+}
+
+// A SchedReadVariant is a single SchedRead type that maps to a list
+// of SchedRead types under the conditions defined by its predicates.
+//
+// A Variadic write is expanded to cover multiple "readsReg" operands as
+// explained above.
+class SchedReadVariant<list<SchedVar> variants> : SchedRead,
+  SchedVariant<variants> {
+}
+
+// Map a set of opcodes to a list of SchedReadWrite types. This allows
+// the subtarget to easily override specific operations.
+//
+// SchedModel ties this opcode mapping to a processor.
+class InstRW<list<SchedReadWrite> rw, dag instrlist> {
+  list<SchedReadWrite> OperandReadWrites = rw;
+  dag Instrs = instrlist;
+  SchedMachineModel SchedModel = ?;
+}
+
+// Map a set of itinerary classes to SchedReadWrite resources. This is
+// used to bootstrap a target (e.g. ARM) when itineraries already
+// exist and changing InstrInfo is undesirable.
+//
+// SchedModel ties this ItineraryClass mapping to a processor.
+class ItinRW<list<SchedReadWrite> rw, list<InstrItinClass> iic> {
+  list<InstrItinClass> MatchedItinClasses = iic;
+  list<SchedReadWrite> OperandReadWrites = rw;
+  SchedMachineModel SchedModel = ?;
+}
+
+// Alias a target-defined SchedReadWrite to a processor specific
+// SchedReadWrite. This allows a subtarget to easily map a
+// SchedReadWrite type onto a WriteSequence, SchedWriteVariant, or
+// SchedReadVariant.
+//
+// SchedModel will usually be provided by surrounding let statement
+// and ties this SchedAlias mapping to a processor.
+class SchedAlias<SchedReadWrite match, SchedReadWrite alias> {
+  SchedReadWrite MatchRW = match;
+  SchedReadWrite AliasRW = alias;
+  SchedMachineModel SchedModel = ?;
+}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
new file mode 100644
index 0000000..2d822de
--- /dev/null
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -0,0 +1,1042 @@
+//===- TargetSelectionDAG.td - Common code for DAG isels ---*- tablegen -*-===//
+//
+//                     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 target-independent interfaces used by SelectionDAG
+// instruction selection generators.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Type Constraint definitions.
+//
+// Note that the semantics of these constraints are hard coded into tblgen.  To
+// modify or add constraints, you have to hack tblgen.
+//
+
+class SDTypeConstraint<int opnum> {
+  int OperandNum = opnum;
+}
+
+// SDTCisVT - The specified operand has exactly this VT.
+class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
+  ValueType VT = vt;
+}
+
+class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisInt - The specified operand has integer type.
+class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisFP - The specified operand has floating-point type.
+class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisVec - The specified operand has a vector type.
+class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisSameAs - The two specified operands have identical types.
+class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
+  int OtherOperandNum = OtherOp;
+}
+
+// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is
+// smaller than the 'Other' operand.
+class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
+  int OtherOperandNum = OtherOp;
+}
+
+class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{
+  int BigOperandNum = BigOp;
+}
+
+/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
+/// type as the element type of OtherOp, which is a vector type.
+class SDTCisEltOfVec<int ThisOp, int OtherOp>
+  : SDTypeConstraint<ThisOp> {
+  int OtherOpNum = OtherOp;
+}
+
+/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type
+/// with length less that of OtherOp, which is a vector type.
+class SDTCisSubVecOfVec<int ThisOp, int OtherOp>
+  : SDTypeConstraint<ThisOp> {
+  int OtherOpNum = OtherOp;
+}
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Type Profile definitions.
+//
+// These use the constraints defined above to describe the type requirements of
+// the various nodes.  These are not hard coded into tblgen, allowing targets to
+// add their own if needed.
+//
+
+// SDTypeProfile - This profile describes the type requirements of a Selection
+// DAG node.
+class SDTypeProfile<int numresults, int numoperands,
+                    list<SDTypeConstraint> constraints> {
+  int NumResults = numresults;
+  int NumOperands = numoperands;
+  list<SDTypeConstraint> Constraints = constraints;
+}
+
+// Builtin profiles.
+def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>;         // for 'imm'.
+def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>;          // for 'fpimm'.
+def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;       // for '&g'.
+def SDTOther  : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'.
+def SDTUNDEF  : SDTypeProfile<1, 0, []>;                     // for 'undef'.
+def SDTUnaryOp  : SDTypeProfile<1, 1, []>;                   // for bitconvert.
+
+def SDTIntBinOp : SDTypeProfile<1, 2, [     // add, and, or, xor, udiv, etc.
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>
+]>;
+def SDTIntShiftOp : SDTypeProfile<1, 2, [   // shl, sra, srl
+  SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>
+]>;
+def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0>
+]>;
+
+def SDTFPBinOp : SDTypeProfile<1, 2, [      // fadd, fmul, etc.
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
+]>;
+def SDTFPSignOp : SDTypeProfile<1, 2, [     // fcopysign.
+  SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2>
+]>;
+def SDTFPTernaryOp : SDTypeProfile<1, 3, [  // fmadd, fnmsub, etc.
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0>
+]>;
+def SDTIntUnaryOp : SDTypeProfile<1, 1, [   // ctlz
+  SDTCisSameAs<0, 1>, SDTCisInt<0>
+]>;
+def SDTIntExtendOp : SDTypeProfile<1, 1, [  // sext, zext, anyext
+  SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>
+]>;
+def SDTIntTruncOp  : SDTypeProfile<1, 1, [  // trunc
+  SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>
+]>;
+def SDTFPUnaryOp  : SDTypeProfile<1, 1, [   // fneg, fsqrt, etc
+  SDTCisSameAs<0, 1>, SDTCisFP<0>
+]>;
+def SDTFPRoundOp  : SDTypeProfile<1, 1, [   // fround
+  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>
+]>;
+def SDTFPExtendOp  : SDTypeProfile<1, 1, [  // fextend
+  SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
+]>;
+def SDTIntToFPOp : SDTypeProfile<1, 1, [    // [su]int_to_fp
+  SDTCisFP<0>, SDTCisInt<1>
+]>;
+def SDTFPToIntOp : SDTypeProfile<1, 1, [    // fp_to_[su]int
+  SDTCisInt<0>, SDTCisFP<1>
+]>;
+def SDTExtInreg : SDTypeProfile<1, 2, [     // sext_inreg
+  SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
+  SDTCisVTSmallerThanOp<2, 1>
+]>;
+
+def SDTSetCC : SDTypeProfile<1, 3, [        // setcc
+  SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
+]>;
+
+def SDTSelect : SDTypeProfile<1, 3, [       // select
+  SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
+]>;
+
+def SDTVSelect : SDTypeProfile<1, 3, [       // vselect
+  SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
+]>;
+
+def SDTSelectCC : SDTypeProfile<1, 5, [     // select_cc
+  SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>,
+  SDTCisVT<5, OtherVT>
+]>;
+
+def SDTBr : SDTypeProfile<0, 1, [           // br
+  SDTCisVT<0, OtherVT>
+]>;
+
+def SDTBrcond : SDTypeProfile<0, 2, [       // brcond
+  SDTCisInt<0>, SDTCisVT<1, OtherVT>
+]>;
+
+def SDTBrind : SDTypeProfile<0, 1, [        // brind
+  SDTCisPtrTy<0>
+]>;
+
+def SDTNone : SDTypeProfile<0, 0, []>;      // ret, trap
+
+def SDTLoad : SDTypeProfile<1, 1, [         // load
+  SDTCisPtrTy<1>
+]>;
+
+def SDTStore : SDTypeProfile<0, 2, [        // store
+  SDTCisPtrTy<1>
+]>;
+
+def SDTIStore : SDTypeProfile<1, 3, [       // indexed store
+  SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3>
+]>;
+
+def SDTVecShuffle : SDTypeProfile<1, 2, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
+]>;
+def SDTVecExtract : SDTypeProfile<1, 2, [   // vector extract
+  SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2>
+]>;
+def SDTVecInsert : SDTypeProfile<1, 3, [    // vector insert
+  SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
+]>;
+
+def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
+  SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
+]>;
+def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
+  SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
+]>;
+
+def SDTPrefetch : SDTypeProfile<0, 4, [     // prefetch
+  SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1>
+]>;
+
+def SDTMemBarrier : SDTypeProfile<0, 5, [   // memory barrier
+  SDTCisSameAs<0,1>,  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisSameAs<0,4>,
+  SDTCisInt<0>
+]>;
+def SDTAtomicFence : SDTypeProfile<0, 2, [
+  SDTCisSameAs<0,1>, SDTCisPtrTy<0>
+]>;
+def SDTAtomic3 : SDTypeProfile<1, 3, [
+  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+def SDTAtomic2 : SDTypeProfile<1, 2, [
+  SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+def SDTAtomicStore : SDTypeProfile<0, 2, [
+  SDTCisPtrTy<0>, SDTCisInt<1>
+]>;
+def SDTAtomicLoad : SDTypeProfile<1, 1, [
+  SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+
+def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
+  SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
+]>;
+
+class SDCallSeqStart<list<SDTypeConstraint> constraints> :
+        SDTypeProfile<0, 1, constraints>;
+class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
+        SDTypeProfile<0, 2, constraints>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node Properties.
+//
+// Note: These are hard coded into tblgen.
+//
+class SDNodeProperty;
+def SDNPCommutative : SDNodeProperty;   // X op Y == Y op X
+def SDNPAssociative : SDNodeProperty;   // (X op Y) op Z == X op (Y op Z)
+def SDNPHasChain    : SDNodeProperty;   // R/W chain operand and result
+def SDNPOutGlue     : SDNodeProperty;   // Write a flag result
+def SDNPInGlue      : SDNodeProperty;   // Read a flag operand
+def SDNPOptInGlue   : SDNodeProperty;   // Optionally read a flag operand
+def SDNPMayStore    : SDNodeProperty;   // May write to memory, sets 'mayStore'.
+def SDNPMayLoad     : SDNodeProperty;   // May read memory, sets 'mayLoad'.
+def SDNPSideEffect  : SDNodeProperty;   // Sets 'HasUnmodelledSideEffects'.
+def SDNPMemOperand  : SDNodeProperty;   // Touches memory, has assoc MemOperand
+def SDNPVariadic    : SDNodeProperty;   // Node has variable arguments.
+def SDNPWantRoot    : SDNodeProperty;   // ComplexPattern gets the root of match
+def SDNPWantParent  : SDNodeProperty;   // ComplexPattern gets the parent
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Operations
+class SDPatternOperator;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node definitions.
+//
+class SDNode<string opcode, SDTypeProfile typeprof,
+             list<SDNodeProperty> props = [], string sdclass = "SDNode">
+             : SDPatternOperator {
+  string Opcode  = opcode;
+  string SDClass = sdclass;
+  list<SDNodeProperty> Properties = props;
+  SDTypeProfile TypeProfile = typeprof;
+}
+
+// Special TableGen-recognized dag nodes
+def set;
+def implicit;
+def node;
+def srcvalue;
+
+def imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
+def timm       : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">;
+def fpimm      : SDNode<"ISD::ConstantFP", SDTFPLeaf  , [], "ConstantFPSDNode">;
+def vt         : SDNode<"ISD::VALUETYPE" , SDTOther   , [], "VTSDNode">;
+def bb         : SDNode<"ISD::BasicBlock", SDTOther   , [], "BasicBlockSDNode">;
+def cond       : SDNode<"ISD::CONDCODE"  , SDTOther   , [], "CondCodeSDNode">;
+def undef      : SDNode<"ISD::UNDEF"     , SDTUNDEF   , []>;
+def globaladdr : SDNode<"ISD::GlobalAddress",         SDTPtrLeaf, [],
+                        "GlobalAddressSDNode">;
+def tglobaladdr : SDNode<"ISD::TargetGlobalAddress",  SDTPtrLeaf, [],
+                         "GlobalAddressSDNode">;
+def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress",         SDTPtrLeaf, [],
+                          "GlobalAddressSDNode">;
+def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress",  SDTPtrLeaf, [],
+                           "GlobalAddressSDNode">;
+def constpool   : SDNode<"ISD::ConstantPool",         SDTPtrLeaf, [],
+                         "ConstantPoolSDNode">;
+def tconstpool  : SDNode<"ISD::TargetConstantPool",   SDTPtrLeaf, [],
+                         "ConstantPoolSDNode">;
+def jumptable   : SDNode<"ISD::JumpTable",            SDTPtrLeaf, [],
+                         "JumpTableSDNode">;
+def tjumptable  : SDNode<"ISD::TargetJumpTable",      SDTPtrLeaf, [],
+                         "JumpTableSDNode">;
+def frameindex  : SDNode<"ISD::FrameIndex",           SDTPtrLeaf, [],
+                         "FrameIndexSDNode">;
+def tframeindex : SDNode<"ISD::TargetFrameIndex",     SDTPtrLeaf, [],
+                         "FrameIndexSDNode">;
+def externalsym : SDNode<"ISD::ExternalSymbol",       SDTPtrLeaf, [],
+                         "ExternalSymbolSDNode">;
+def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [],
+                         "ExternalSymbolSDNode">;
+def blockaddress : SDNode<"ISD::BlockAddress",        SDTPtrLeaf, [],
+                         "BlockAddressSDNode">;
+def tblockaddress: SDNode<"ISD::TargetBlockAddress",  SDTPtrLeaf, [],
+                         "BlockAddressSDNode">;
+
+def add        : SDNode<"ISD::ADD"       , SDTIntBinOp   ,
+                        [SDNPCommutative, SDNPAssociative]>;
+def sub        : SDNode<"ISD::SUB"       , SDTIntBinOp>;
+def mul        : SDNode<"ISD::MUL"       , SDTIntBinOp,
+                        [SDNPCommutative, SDNPAssociative]>;
+def mulhs      : SDNode<"ISD::MULHS"     , SDTIntBinOp, [SDNPCommutative]>;
+def mulhu      : SDNode<"ISD::MULHU"     , SDTIntBinOp, [SDNPCommutative]>;
+def smullohi   : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
+def umullohi   : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
+def sdiv       : SDNode<"ISD::SDIV"      , SDTIntBinOp>;
+def udiv       : SDNode<"ISD::UDIV"      , SDTIntBinOp>;
+def srem       : SDNode<"ISD::SREM"      , SDTIntBinOp>;
+def urem       : SDNode<"ISD::UREM"      , SDTIntBinOp>;
+def sdivrem    : SDNode<"ISD::SDIVREM"   , SDTIntBinHiLoOp>;
+def udivrem    : SDNode<"ISD::UDIVREM"   , SDTIntBinHiLoOp>;
+def srl        : SDNode<"ISD::SRL"       , SDTIntShiftOp>;
+def sra        : SDNode<"ISD::SRA"       , SDTIntShiftOp>;
+def shl        : SDNode<"ISD::SHL"       , SDTIntShiftOp>;
+def rotl       : SDNode<"ISD::ROTL"      , SDTIntShiftOp>;
+def rotr       : SDNode<"ISD::ROTR"      , SDTIntShiftOp>;
+def and        : SDNode<"ISD::AND"       , SDTIntBinOp,
+                        [SDNPCommutative, SDNPAssociative]>;
+def or         : SDNode<"ISD::OR"        , SDTIntBinOp,
+                        [SDNPCommutative, SDNPAssociative]>;
+def xor        : SDNode<"ISD::XOR"       , SDTIntBinOp,
+                        [SDNPCommutative, SDNPAssociative]>;
+def addc       : SDNode<"ISD::ADDC"      , SDTIntBinOp,
+                        [SDNPCommutative, SDNPOutGlue]>;
+def adde       : SDNode<"ISD::ADDE"      , SDTIntBinOp,
+                        [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>;
+def subc       : SDNode<"ISD::SUBC"      , SDTIntBinOp,
+                        [SDNPOutGlue]>;
+def sube       : SDNode<"ISD::SUBE"      , SDTIntBinOp,
+                        [SDNPOutGlue, SDNPInGlue]>;
+
+def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
+def bswap      : SDNode<"ISD::BSWAP"      , SDTIntUnaryOp>;
+def ctlz       : SDNode<"ISD::CTLZ"       , SDTIntUnaryOp>;
+def cttz       : SDNode<"ISD::CTTZ"       , SDTIntUnaryOp>;
+def ctpop      : SDNode<"ISD::CTPOP"      , SDTIntUnaryOp>;
+def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntUnaryOp>;
+def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntUnaryOp>;
+def sext       : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
+def zext       : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
+def anyext     : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
+def trunc      : SDNode<"ISD::TRUNCATE"   , SDTIntTruncOp>;
+def bitconvert : SDNode<"ISD::BITCAST"    , SDTUnaryOp>;
+def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
+def insertelt  : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
+
+def fadd       : SDNode<"ISD::FADD"       , SDTFPBinOp, [SDNPCommutative]>;
+def fsub       : SDNode<"ISD::FSUB"       , SDTFPBinOp>;
+def fmul       : SDNode<"ISD::FMUL"       , SDTFPBinOp, [SDNPCommutative]>;
+def fdiv       : SDNode<"ISD::FDIV"       , SDTFPBinOp>;
+def frem       : SDNode<"ISD::FREM"       , SDTFPBinOp>;
+def fma        : SDNode<"ISD::FMA"        , SDTFPTernaryOp>;
+def fabs       : SDNode<"ISD::FABS"       , SDTFPUnaryOp>;
+def fgetsign   : SDNode<"ISD::FGETSIGN"   , SDTFPToIntOp>;
+def fneg       : SDNode<"ISD::FNEG"       , SDTFPUnaryOp>;
+def fsqrt      : SDNode<"ISD::FSQRT"      , SDTFPUnaryOp>;
+def fsin       : SDNode<"ISD::FSIN"       , SDTFPUnaryOp>;
+def fcos       : SDNode<"ISD::FCOS"       , SDTFPUnaryOp>;
+def fexp2      : SDNode<"ISD::FEXP2"      , SDTFPUnaryOp>;
+def fpow       : SDNode<"ISD::FPOW"       , SDTFPBinOp>;
+def flog2      : SDNode<"ISD::FLOG2"      , SDTFPUnaryOp>;
+def frint      : SDNode<"ISD::FRINT"      , SDTFPUnaryOp>;
+def ftrunc     : SDNode<"ISD::FTRUNC"     , SDTFPUnaryOp>;
+def fceil      : SDNode<"ISD::FCEIL"      , SDTFPUnaryOp>;
+def ffloor     : SDNode<"ISD::FFLOOR"     , SDTFPUnaryOp>;
+def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
+def frnd       : SDNode<"ISD::FROUND"     , SDTFPUnaryOp>;
+
+def fround     : SDNode<"ISD::FP_ROUND"   , SDTFPRoundOp>;
+def fextend    : SDNode<"ISD::FP_EXTEND"  , SDTFPExtendOp>;
+def fcopysign  : SDNode<"ISD::FCOPYSIGN"  , SDTFPSignOp>;
+
+def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
+def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
+def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
+def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
+def f16_to_fp  : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>;
+def fp_to_f16  : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>;
+
+def setcc      : SDNode<"ISD::SETCC"      , SDTSetCC>;
+def select     : SDNode<"ISD::SELECT"     , SDTSelect>;
+def vselect    : SDNode<"ISD::VSELECT"    , SDTVSelect>;
+def selectcc   : SDNode<"ISD::SELECT_CC"  , SDTSelectCC>;
+
+def brcond     : SDNode<"ISD::BRCOND"     , SDTBrcond, [SDNPHasChain]>;
+def brind      : SDNode<"ISD::BRIND"      , SDTBrind,  [SDNPHasChain]>;
+def br         : SDNode<"ISD::BR"         , SDTBr,     [SDNPHasChain]>;
+def trap       : SDNode<"ISD::TRAP"       , SDTNone,
+                        [SDNPHasChain, SDNPSideEffect]>;
+def debugtrap  : SDNode<"ISD::DEBUGTRAP"  , SDTNone,
+                        [SDNPHasChain, SDNPSideEffect]>;
+
+def prefetch   : SDNode<"ISD::PREFETCH"   , SDTPrefetch,
+                        [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+                         SDNPMemOperand]>;
+
+def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf,
+                     [SDNPHasChain, SDNPSideEffect]>;
+
+def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence,
+                          [SDNPHasChain, SDNPSideEffect]>;
+
+def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap     : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or  : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2,
+                    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load      : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
+                    [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_store     : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore,
+                    [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+
+// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
+// and truncst (see below).
+def ld         : SDNode<"ISD::LOAD"       , SDTLoad,
+                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def st         : SDNode<"ISD::STORE"      , SDTStore,
+                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def ist        : SDNode<"ISD::STORE"      , SDTIStore,
+                        [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+
+def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
+def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
+def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
+                              []>;
+def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
+    SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
+def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
+    SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
+def concat_vectors : SDNode<"ISD::CONCAT_VECTORS",
+    SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>;
+
+// This operator does not do subvector type checking.  The ARM
+// backend, at least, needs it.
+def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
+    SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>, 
+    []>;
+
+// This operator does subvector type checking.
+def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
+def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>;
+
+// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
+// these internally.  Don't reference these directly.
+def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
+                            SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
+                            [SDNPHasChain]>;
+def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
+                               SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
+                               [SDNPHasChain]>;
+def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
+                                SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
+
+// Do not use cvt directly. Use cvt forms below
+def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
+
+def SDT_assertext : SDTypeProfile<1, 1,
+  [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
+def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>;
+def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>;
+
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Condition Codes
+
+class CondCode; // ISD::CondCode enums
+def SETOEQ : CondCode; def SETOGT : CondCode;
+def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode;
+def SETONE : CondCode; def SETO   : CondCode; def SETUO  : CondCode;
+def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode;
+def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode;
+
+def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode;
+def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode;
+
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node Transformation Functions.
+//
+// This mechanism allows targets to manipulate nodes in the output DAG once a
+// match has been formed.  This is typically used to manipulate immediate
+// values.
+//
+class SDNodeXForm<SDNode opc, code xformFunction> {
+  SDNode Opcode = opc;
+  code XFormFunction = xformFunction;
+}
+
+def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
+
+//===----------------------------------------------------------------------===//
+// PatPred Subclasses.
+//
+// These allow specifying different sorts of predicates that control whether a
+// node is matched.
+//
+class PatPred;
+
+class CodePatPred<code predicate> : PatPred {
+  code PredicateCode = predicate;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Fragments.
+//
+// Pattern fragments are reusable chunks of dags that match specific things.
+// They can take arguments and have C++ predicates that control whether they
+// match.  They are intended to make the patterns for common instructions more
+// compact and readable.
+//
+
+/// PatFrag - Represents a pattern fragment.  This can match something on the
+/// DAG, from a single node to multiple nested other fragments.
+///
+class PatFrag<dag ops, dag frag, code pred = [{}],
+              SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
+  dag Operands = ops;
+  dag Fragment = frag;
+  code PredicateCode = pred;
+  code ImmediateCode = [{}];
+  SDNodeXForm OperandTransform = xform;
+}
+
+// OutPatFrag is a pattern fragment that is used as part of an output pattern
+// (not an input pattern). These do not have predicates or transforms, but are
+// used to avoid repeated subexpressions in output patterns.
+class OutPatFrag<dag ops, dag frag>
+ : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>;
+
+// PatLeaf's are pattern fragments that have no operands.  This is just a helper
+// to define immediates and other common things concisely.
+class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
+ : PatFrag<(ops), frag, pred, xform>;
+
+
+// ImmLeaf is a pattern fragment with a constraint on the immediate.  The
+// constraint is a function that is run on the immediate (always with the value
+// sign extended out to an int64_t) as Imm.  For example:
+//
+//  def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
+//
+// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
+// is preferred over using PatLeaf because it allows the code generator to
+// reason more about the constraint.
+//
+// If FastIsel should ignore all instructions that have an operand of this type,
+// the FastIselShouldIgnore flag can be set.  This is an optimization to reduce
+// the code size of the generated fast instruction selector.
+class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
+  : PatFrag<(ops), (vt imm), [{}], xform> {
+  let ImmediateCode = pred;
+  bit FastIselShouldIgnore = 0;
+}
+
+
+// Leaf fragments.
+
+def vtInt      : PatLeaf<(vt),  [{ return N->getVT().isInteger(); }]>;
+def vtFP       : PatLeaf<(vt),  [{ return N->getVT().isFloatingPoint(); }]>;
+
+def immAllOnesV: PatLeaf<(build_vector), [{
+  return ISD::isBuildVectorAllOnes(N);
+}]>;
+def immAllZerosV: PatLeaf<(build_vector), [{
+  return ISD::isBuildVectorAllZeros(N);
+}]>;
+
+
+
+// Other helper fragments.
+def not  : PatFrag<(ops node:$in), (xor node:$in, -1)>;
+def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
+def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
+
+// null_frag - The null pattern operator is used in multiclass instantiations
+// which accept an SDPatternOperator for use in matching patterns for internal
+// definitions. When expanding a pattern, if the null fragment is referenced
+// in the expansion, the pattern is discarded and it is as-if '[]' had been
+// specified. This allows multiclasses to have the isel patterns be optional.
+def null_frag : SDPatternOperator;
+
+// load fragments.
+def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
+  return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+}]>;
+
+// extending load fragments.
+def extload   : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+}]>;
+def sextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+}]>;
+def zextload  : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+}]>;
+
+def extloadi1  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def extloadi8  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+def sextloadi1  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def sextloadi8  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def zextloadi1  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def zextloadi8  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def extloadvi1  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def extloadvi8  : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f32;
+}]>;
+def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f64;
+}]>;
+
+def sextloadvi1  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def sextloadvi8  : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
+def zextloadvi1  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def zextloadvi8  : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+  return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
+// store fragments.
+def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
+                             (st node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def store : PatFrag<(ops node:$val, node:$ptr),
+                    (unindexedstore node:$val, node:$ptr), [{
+  return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
+// truncstore fragments.
+def truncstore : PatFrag<(ops node:$val, node:$ptr),
+                         (unindexedstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
+                           (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
+                            (truncstore node:$val, node:$ptr), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+// indexed store fragments.
+def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
+                     (ist node:$val, node:$base, node:$offset), [{
+  return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
+def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
+                        (istore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+
+def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
+                          (ist node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+                          (itruncstore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                            (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                            (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (pre_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+
+def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
+                         (istore node:$val, node:$ptr, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+
+def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+                           (itruncstore node:$val, node:$base, node:$offset), [{
+  ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+  return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                             (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+                              (post_truncst node:$val, node:$base, node:$offset), [{
+  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+
+// setcc convenience fragments.
+def setoeq : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETOEQ)>;
+def setogt : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETOGT)>;
+def setoge : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETOGE)>;
+def setolt : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETOLT)>;
+def setole : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETOLE)>;
+def setone : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETONE)>;
+def seto   : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETO)>;
+def setuo  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETUO)>;
+def setueq : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETUEQ)>;
+def setugt : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETUGT)>;
+def setuge : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETUGE)>;
+def setult : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETULT)>;
+def setule : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETULE)>;
+def setune : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETUNE)>;
+def seteq  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETEQ)>;
+def setgt  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETGT)>;
+def setge  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETGE)>;
+def setlt  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETLT)>;
+def setle  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETLE)>;
+def setne  : PatFrag<(ops node:$lhs, node:$rhs),
+                     (setcc node:$lhs, node:$rhs, SETNE)>;
+
+def atomic_cmp_swap_8 :
+  PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+          (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def atomic_cmp_swap_16 :
+  PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+          (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def atomic_cmp_swap_32 :
+  PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+          (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def atomic_cmp_swap_64 :
+  PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+          (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+multiclass binary_atomic_op<SDNode atomic_op> {
+  def _8 : PatFrag<(ops node:$ptr, node:$val),
+                   (atomic_op node:$ptr, node:$val), [{
+    return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+  }]>;
+  def _16 : PatFrag<(ops node:$ptr, node:$val),
+                   (atomic_op node:$ptr, node:$val), [{
+    return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+  }]>;
+  def _32 : PatFrag<(ops node:$ptr, node:$val),
+                   (atomic_op node:$ptr, node:$val), [{
+    return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+  }]>;
+  def _64 : PatFrag<(ops node:$ptr, node:$val),
+                   (atomic_op node:$ptr, node:$val), [{
+    return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+  }]>;
+}
+
+defm atomic_load_add  : binary_atomic_op<atomic_load_add>;
+defm atomic_swap      : binary_atomic_op<atomic_swap>;
+defm atomic_load_sub  : binary_atomic_op<atomic_load_sub>;
+defm atomic_load_and  : binary_atomic_op<atomic_load_and>;
+defm atomic_load_or   : binary_atomic_op<atomic_load_or>;
+defm atomic_load_xor  : binary_atomic_op<atomic_load_xor>;
+defm atomic_load_nand : binary_atomic_op<atomic_load_nand>;
+defm atomic_load_min  : binary_atomic_op<atomic_load_min>;
+defm atomic_load_max  : binary_atomic_op<atomic_load_max>;
+defm atomic_load_umin : binary_atomic_op<atomic_load_umin>;
+defm atomic_load_umax : binary_atomic_op<atomic_load_umax>;
+defm atomic_store     : binary_atomic_op<atomic_store>;
+
+def atomic_load_8 :
+  PatFrag<(ops node:$ptr),
+          (atomic_load node:$ptr), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def atomic_load_16 :
+  PatFrag<(ops node:$ptr),
+          (atomic_load node:$ptr), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def atomic_load_32 :
+  PatFrag<(ops node:$ptr),
+          (atomic_load node:$ptr), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def atomic_load_64 :
+  PatFrag<(ops node:$ptr),
+          (atomic_load node:$ptr), [{
+  return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG CONVERT_RNDSAT patterns
+
+def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FF;
+    }]>;
+
+def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SS;
+    }]>;
+
+def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SU;
+    }]>;
+
+def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_US;
+    }]>;
+
+def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UU;
+    }]>;
+
+def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SF;
+    }]>;
+
+def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UF;
+    }]>;
+
+def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FS;
+    }]>;
+
+def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+    (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+       return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FU;
+    }]>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Support.
+//
+// Patterns are what are actually matched against by the target-flavored
+// instruction selection DAG.  Instructions defined by the target implicitly
+// define patterns in most cases, but patterns can also be explicitly added when
+// an operation is defined by a sequence of instructions (e.g. loading a large
+// immediate value on RISC targets that do not support immediates as large as
+// their GPRs).
+//
+
+class Pattern<dag patternToMatch, list<dag> resultInstrs> {
+  dag             PatternToMatch  = patternToMatch;
+  list<dag>       ResultInstrs    = resultInstrs;
+  list<Predicate> Predicates      = [];  // See class Instruction in Target.td.
+  int             AddedComplexity = 0;   // See class Instruction in Target.td.
+}
+
+// Pat - A simple (but common) form of a pattern, which produces a simple result
+// not needing a full list.
+class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
+
+//===----------------------------------------------------------------------===//
+// Complex pattern definitions.
+//
+
+// Complex patterns, e.g. X86 addressing mode, requires pattern matching code
+// in C++. NumOperands is the number of operands returned by the select function;
+// SelectFunc is the name of the function used to pattern match the max. pattern;
+// RootNodes are the list of possible root nodes of the sub-dags to match.
+// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
+//
+class ComplexPattern<ValueType ty, int numops, string fn,
+                     list<SDNode> roots = [], list<SDNodeProperty> props = []> {
+  ValueType Ty = ty;
+  int NumOperands = numops;
+  string SelectFunc = fn;
+  list<SDNode> RootNodes = roots;
+  list<SDNodeProperty> Properties = props;
+}
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
new file mode 100644
index 0000000..78a2db1
--- /dev/null
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -0,0 +1,169 @@
+//==-- llvm/Target/TargetSelectionDAGInfo.h - SelectionDAG 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 declares the TargetSelectionDAGInfo class, which targets can
+// subclass to parameterize the SelectionDAG lowering and instruction
+// selection process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H
+#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+
+class DataLayout;
+class TargetMachine;
+
+//===----------------------------------------------------------------------===//
+/// TargetSelectionDAGInfo - Targets can subclass this to parameterize the
+/// SelectionDAG lowering and instruction selection process.
+///
+class TargetSelectionDAGInfo {
+  TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
+
+  const DataLayout *DL;
+
+protected:
+  const DataLayout *getDataLayout() const { return DL; }
+
+public:
+  explicit TargetSelectionDAGInfo(const DataLayout *DL);
+  virtual ~TargetSelectionDAGInfo();
+
+  /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
+  /// memcpy. This can be used by targets to provide code sequences for cases
+  /// that don't fit the target's parameters for simple loads/stores and can be
+  /// more efficient than using a library call. This function can return a null
+  /// SDValue if the target declines to use custom code and a different
+  /// lowering strategy should be used.
+  /// 
+  /// If AlwaysInline is true, the size is constant and the target should not
+  /// emit any calls and is strongly encouraged to attempt to emit inline code
+  /// even if it is beyond the usual threshold because this intrinsic is being
+  /// expanded in a place where calls are not feasible (e.g. within the prologue
+  /// for another call). If the target chooses to decline an AlwaysInline
+  /// request here, legalize will resort to using simple loads and stores.
+  virtual SDValue
+  EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc dl,
+                          SDValue Chain,
+                          SDValue Op1, SDValue Op2,
+                          SDValue Op3, unsigned Align, bool isVolatile,
+                          bool AlwaysInline,
+                          MachinePointerInfo DstPtrInfo,
+                          MachinePointerInfo SrcPtrInfo) const {
+    return SDValue();
+  }
+
+  /// EmitTargetCodeForMemmove - Emit target-specific code that performs a
+  /// memmove. This can be used by targets to provide code sequences for cases
+  /// that don't fit the target's parameters for simple loads/stores and can be
+  /// more efficient than using a library call. This function can return a null
+  /// SDValue if the target declines to use custom code and a different
+  /// lowering strategy should be used.
+  virtual SDValue
+  EmitTargetCodeForMemmove(SelectionDAG &DAG, SDLoc dl,
+                           SDValue Chain,
+                           SDValue Op1, SDValue Op2,
+                           SDValue Op3, unsigned Align, bool isVolatile,
+                           MachinePointerInfo DstPtrInfo,
+                           MachinePointerInfo SrcPtrInfo) const {
+    return SDValue();
+  }
+
+  /// EmitTargetCodeForMemset - Emit target-specific code that performs a
+  /// memset. This can be used by targets to provide code sequences for cases
+  /// that don't fit the target's parameters for simple stores and can be more
+  /// efficient than using a library call. This function can return a null
+  /// SDValue if the target declines to use custom code and a different
+  /// lowering strategy should be used.
+  virtual SDValue
+  EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc dl,
+                          SDValue Chain,
+                          SDValue Op1, SDValue Op2,
+                          SDValue Op3, unsigned Align, bool isVolatile,
+                          MachinePointerInfo DstPtrInfo) const {
+    return SDValue();
+  }
+
+  /// EmitTargetCodeForMemcmp - Emit target-specific code that performs a
+  /// memcmp, in cases where that is faster than a libcall.  The first
+  /// returned SDValue is the result of the memcmp and the second is
+  /// the chain.  Both SDValues can be null if a normal libcall should
+  /// be used.
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForMemcmp(SelectionDAG &DAG, SDLoc dl,
+                          SDValue Chain,
+                          SDValue Op1, SDValue Op2,
+                          SDValue Op3, MachinePointerInfo Op1PtrInfo,
+                          MachinePointerInfo Op2PtrInfo) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+
+  /// EmitTargetCodeForMemchr - Emit target-specific code that performs a
+  /// memchr, in cases where that is faster than a libcall.  The first
+  /// returned SDValue is the result of the memchr and the second is
+  /// the chain.  Both SDValues can be null if a normal libcall should
+  /// be used.
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForMemchr(SelectionDAG &DAG, SDLoc dl, SDValue Chain,
+                          SDValue Src, SDValue Char, SDValue Length,
+                          MachinePointerInfo SrcPtrInfo) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+
+  /// EmitTargetCodeForStrcpy - Emit target-specific code that performs a
+  /// strcpy or stpcpy, in cases where that is faster than a libcall.
+  /// The first returned SDValue is the result of the copy (the start
+  /// of the destination string for strcpy, a pointer to the null terminator
+  /// for stpcpy) and the second is the chain.  Both SDValues can be null
+  /// if a normal libcall should be used.
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+                          SDValue Dest, SDValue Src,
+                          MachinePointerInfo DestPtrInfo,
+                          MachinePointerInfo SrcPtrInfo,
+                          bool isStpcpy) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+
+  /// EmitTargetCodeForStrcmp - Emit target-specific code that performs a
+  /// strcmp, in cases where that is faster than a libcall.  The first
+  /// returned SDValue is the result of the strcmp and the second is
+  /// the chain.  Both SDValues can be null if a normal libcall should
+  /// be used.
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc dl,
+                          SDValue Chain,
+                          SDValue Op1, SDValue Op2,
+                          MachinePointerInfo Op1PtrInfo,
+                          MachinePointerInfo Op2PtrInfo) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+                          SDValue Src, MachinePointerInfo SrcPtrInfo) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+
+  virtual std::pair<SDValue, SDValue>
+  EmitTargetCodeForStrnlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+                           SDValue Src, SDValue MaxLength,
+                           MachinePointerInfo SrcPtrInfo) const {
+    return std::make_pair(SDValue(), SDValue());
+  }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
new file mode 100644
index 0000000..86e303e
--- /dev/null
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -0,0 +1,133 @@
+//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H
+#define LLVM_TARGET_TARGETSUBTARGETINFO_H
+
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+
+class MachineFunction;
+class MachineInstr;
+class SDep;
+class SUnit;
+class TargetRegisterClass;
+class TargetSchedModel;
+struct MachineSchedPolicy;
+template <typename T> class SmallVectorImpl;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetSubtargetInfo - Generic base class for all target subtargets.  All
+/// Target-specific options that control code generation and printing should
+/// be exposed through a TargetSubtargetInfo-derived class.
+///
+class TargetSubtargetInfo : public MCSubtargetInfo {
+  TargetSubtargetInfo(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
+  void operator=(const TargetSubtargetInfo&) LLVM_DELETED_FUNCTION;
+protected: // Can only create subclasses...
+  TargetSubtargetInfo();
+public:
+  // AntiDepBreakMode - Type of anti-dependence breaking that should
+  // be performed before post-RA scheduling.
+  typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
+  typedef SmallVectorImpl<const TargetRegisterClass*> RegClassVector;
+
+  virtual ~TargetSubtargetInfo();
+
+  /// Resolve a SchedClass at runtime, where SchedClass identifies an
+  /// MCSchedClassDesc with the isVariant property. This may return the ID of
+  /// another variant SchedClass, but repeated invocation must quickly terminate
+  /// in a nonvariant SchedClass.
+  virtual unsigned resolveSchedClass(unsigned SchedClass, const MachineInstr *MI,
+                                     const TargetSchedModel* SchedModel) const {
+    return 0;
+  }
+
+  /// \brief Temporary API to test migration to MI scheduler.
+  bool useMachineScheduler() const;
+
+  /// \brief True if the subtarget should run MachineScheduler after aggressive
+  /// coalescing.
+  ///
+  /// This currently replaces the SelectionDAG scheduler with the "source" order
+  /// scheduler. It does not yet disable the postRA scheduler.
+  virtual bool enableMachineScheduler() const;
+
+  /// \brief True if the subtarget should run PostMachineScheduler.
+  ///
+  /// This only takes effect if the target has configured the
+  /// PostMachineScheduler pass to run, or if the global cl::opt flag,
+  /// MISchedPostRA, is set.
+  virtual bool enablePostMachineScheduler() const;
+
+  /// \brief True if the subtarget should run the atomic expansion pass.
+  virtual bool enableAtomicExpandLoadLinked() const;
+
+  /// \brief Override generic scheduling policy within a region.
+  ///
+  /// This is a convenient way for targets that don't provide any custom
+  /// scheduling heuristics (no custom MachineSchedStrategy) to make
+  /// changes to the generic scheduling policy.
+  virtual void overrideSchedPolicy(MachineSchedPolicy &Policy,
+                                   MachineInstr *begin,
+                                   MachineInstr *end,
+                                   unsigned NumRegionInstrs) const {}
+
+  // \brief Perform target specific adjustments to the latency of a schedule
+  // dependency.
+  virtual void adjustSchedDependency(SUnit *def, SUnit *use,
+                                     SDep& dep) const { }
+  
+  // For use with PostRAScheduling: get the anti-dependence breaking that should
+  // be performed before post-RA scheduling.
+  virtual AntiDepBreakMode getAntiDepBreakMode() const {
+    return ANTIDEP_NONE;
+  }
+  
+  // For use with PostRAScheduling: in CriticalPathRCs, return any register
+  // classes that should only be considered for anti-dependence breaking if they
+  // are on the critical path.
+  virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
+    return CriticalPathRCs.clear();
+  }
+  
+  // For use with PostRAScheduling: get the minimum optimization level needed
+  // to enable post-RA scheduling.
+  virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const {
+    return CodeGenOpt::Default;
+  }
+  
+  /// \brief True if the subtarget should run the local reassignment
+  /// heuristic of the register allocator.
+  /// This heuristic may be compile time intensive, \p OptLevel provides
+  /// a finer grain to tune the register allocator.
+  virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const;
+
+  /// \brief Enable use of alias analysis during code generation (during MI
+  /// scheduling, DAGCombine, etc.).
+  virtual bool useAA() const;
+
+  /// \brief Enable the use of the early if conversion pass.
+  virtual bool enableEarlyIfConversion() const { return false; }
+
+  /// \brief Reset the features for the subtarget.
+  virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
new file mode 100644
index 0000000..ce1a7d6
--- /dev/null
+++ b/include/llvm/Transforms/IPO.h
@@ -0,0 +1,204 @@
+//===- llvm/Transforms/IPO.h - Interprocedural Transformations --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the IPO transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_H
+#define LLVM_TRANSFORMS_IPO_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+
+class ModulePass;
+class Pass;
+class Function;
+class BasicBlock;
+class GlobalValue;
+
+//===----------------------------------------------------------------------===//
+//
+// These functions removes symbols from functions and modules.  If OnlyDebugInfo
+// is true, only debugging information is removed from the module.
+//
+ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false);
+
+//===----------------------------------------------------------------------===//
+//
+// These functions strips symbols from functions and modules.
+// Only debugging information is not stripped.
+//
+ModulePass *createStripNonDebugSymbolsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// These pass removes llvm.dbg.declare intrinsics.
+ModulePass *createStripDebugDeclarePass();
+
+//===----------------------------------------------------------------------===//
+//
+// These pass removes unused symbols' debug info.
+ModulePass *createStripDeadDebugInfoPass();
+
+//===----------------------------------------------------------------------===//
+/// createConstantMergePass - This function returns a new pass that merges
+/// duplicate global constants together into a single constant that is shared.
+/// This is useful because some passes (ie TraceValues) insert a lot of string
+/// constants into the program, regardless of whether or not they duplicate an
+/// existing string.
+///
+ModulePass *createConstantMergePass();
+
+//===----------------------------------------------------------------------===//
+/// createGlobalOptimizerPass - This function returns a new pass that optimizes
+/// non-address taken internal globals.
+///
+ModulePass *createGlobalOptimizerPass();
+
+//===----------------------------------------------------------------------===//
+/// createGlobalDCEPass - This transform is designed to eliminate unreachable
+/// internal globals (functions or global variables)
+///
+ModulePass *createGlobalDCEPass();
+
+//===----------------------------------------------------------------------===//
+/// createGVExtractionPass - If deleteFn is true, this pass deletes
+/// the specified global values. Otherwise, it deletes as much of the module as
+/// possible, except for the global values specified.
+///
+ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
+                                   deleteFn = false);
+
+//===----------------------------------------------------------------------===//
+/// createFunctionInliningPass - Return a new pass object that uses a heuristic
+/// to inline direct function calls to small functions.
+///
+/// The Threshold can be passed directly, or asked to be computed from the
+/// given optimization and size optimization arguments.
+///
+/// The -inline-threshold command line option takes precedence over the
+/// threshold given here.
+Pass *createFunctionInliningPass();
+Pass *createFunctionInliningPass(int Threshold);
+Pass *createFunctionInliningPass(unsigned OptLevel, unsigned SizeOptLevel);
+
+//===----------------------------------------------------------------------===//
+/// createAlwaysInlinerPass - Return a new pass object that inlines only
+/// functions that are marked as "always_inline".
+Pass *createAlwaysInlinerPass();
+Pass *createAlwaysInlinerPass(bool InsertLifetime);
+
+//===----------------------------------------------------------------------===//
+/// createPruneEHPass - Return a new pass object which transforms invoke
+/// instructions into calls, if the callee can _not_ unwind the stack.
+///
+Pass *createPruneEHPass();
+
+//===----------------------------------------------------------------------===//
+/// createInternalizePass - This pass loops over all of the functions in the
+/// input module, internalizing all globals (functions and variables) it can.
+////
+/// The symbols in \p ExportList are never internalized.
+///
+/// The symbol in DSOList are internalized if it is safe to drop them from
+/// the symbol table.
+///
+/// Note that commandline options that are used with the above function are not
+/// used now!
+ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);
+/// createInternalizePass - Same as above, but with an empty exportList.
+ModulePass *createInternalizePass();
+
+//===----------------------------------------------------------------------===//
+/// createDeadArgEliminationPass - This pass removes arguments from functions
+/// which are not used by the body of the function.
+///
+ModulePass *createDeadArgEliminationPass();
+
+/// DeadArgHacking pass - Same as DAE, but delete arguments of external
+/// functions as well.  This is definitely not safe, and should only be used by
+/// bugpoint.
+ModulePass *createDeadArgHackingPass();
+
+//===----------------------------------------------------------------------===//
+/// createArgumentPromotionPass - This pass promotes "by reference" arguments to
+/// be passed by value if the number of elements passed is smaller or
+/// equal to maxElements (maxElements == 0 means always promote).
+///
+Pass *createArgumentPromotionPass(unsigned maxElements = 3);
+
+//===----------------------------------------------------------------------===//
+/// createIPConstantPropagationPass - This pass propagates constants from call
+/// sites into the bodies of functions.
+///
+ModulePass *createIPConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+/// createIPSCCPPass - This pass propagates constants from call sites into the
+/// bodies of functions, and keeps track of whether basic blocks are executable
+/// in the process.
+///
+ModulePass *createIPSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+/// createLoopExtractorPass - This pass extracts all natural loops from the
+/// program into a function if it can.
+///
+Pass *createLoopExtractorPass();
+
+/// createSingleLoopExtractorPass - This pass extracts one natural loop from the
+/// program into a function if it can.  This is used by bugpoint.
+///
+Pass *createSingleLoopExtractorPass();
+
+/// createBlockExtractorPass - This pass extracts all blocks (except those
+/// specified in the argument list) from the functions in the module.
+///
+ModulePass *createBlockExtractorPass();
+
+/// createStripDeadPrototypesPass - This pass removes any function declarations
+/// (prototypes) that are not used.
+ModulePass *createStripDeadPrototypesPass();
+
+//===----------------------------------------------------------------------===//
+/// createFunctionAttrsPass - This pass discovers functions that do not access
+/// memory, or only read memory, and gives them the readnone/readonly attribute.
+/// It also discovers function arguments that are not captured by the function
+/// and marks them with the nocapture attribute.
+///
+Pass *createFunctionAttrsPass();
+
+//===----------------------------------------------------------------------===//
+/// createMergeFunctionsPass - This pass discovers identical functions and
+/// collapses them.
+///
+ModulePass *createMergeFunctionsPass();
+
+//===----------------------------------------------------------------------===//
+/// createPartialInliningPass - This pass inlines parts of functions.
+///
+ModulePass *createPartialInliningPass();
+
+//===----------------------------------------------------------------------===//
+// createMetaRenamerPass - Rename everything with metasyntatic names.
+//
+ModulePass *createMetaRenamerPass();
+
+//===----------------------------------------------------------------------===//
+/// createBarrierNoopPass - This pass is purely a module pass barrier in a pass
+/// manager.
+ModulePass *createBarrierNoopPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
new file mode 100644
index 0000000..6a644ad
--- /dev/null
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -0,0 +1,91 @@
+//===- InlinerPass.h - Code common to all inliners --------------*- 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 simple policy-based bottom-up inliner.  This file
+// implements all of the boring mechanics of the bottom-up inlining, while the
+// subclass determines WHAT to inline, which is the much more interesting
+// component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H
+#define LLVM_TRANSFORMS_IPO_INLINERPASS_H
+
+#include "llvm/Analysis/CallGraphSCCPass.h"
+
+namespace llvm {
+  class CallSite;
+  class DataLayout;
+  class InlineCost;
+  template<class PtrType, unsigned SmallSize>
+  class SmallPtrSet;
+
+/// Inliner - This class contains all of the helper code which is used to
+/// perform the inlining operations that do not depend on the policy.
+///
+struct Inliner : public CallGraphSCCPass {
+  explicit Inliner(char &ID);
+  explicit Inliner(char &ID, int Threshold, bool InsertLifetime);
+
+  /// getAnalysisUsage - For this class, we declare that we require and preserve
+  /// the call graph.  If the derived class implements this method, it should
+  /// always explicitly call the implementation here.
+  void getAnalysisUsage(AnalysisUsage &Info) const override;
+
+  // Main run interface method, this implements the interface required by the
+  // Pass class.
+  bool runOnSCC(CallGraphSCC &SCC) override;
+
+  using llvm::Pass::doFinalization;
+  // doFinalization - Remove now-dead linkonce functions at the end of
+  // processing to avoid breaking the SCC traversal.
+  bool doFinalization(CallGraph &CG) override;
+
+  /// This method returns the value specified by the -inline-threshold value,
+  /// specified on the command line.  This is typically not directly needed.
+  ///
+  unsigned getInlineThreshold() const { return InlineThreshold; }
+
+  /// Calculate the inline threshold for given Caller. This threshold is lower
+  /// if the caller is marked with OptimizeForSize and -inline-threshold is not
+  /// given on the comand line. It is higher if the callee is marked with the
+  /// inlinehint attribute.
+  ///
+  unsigned getInlineThreshold(CallSite CS) const;
+
+  /// getInlineCost - This method must be implemented by the subclass to
+  /// determine the cost of inlining the specified call site.  If the cost
+  /// returned is greater than the current inline threshold, the call site is
+  /// not inlined.
+  ///
+  virtual InlineCost getInlineCost(CallSite CS) = 0;
+
+  /// removeDeadFunctions - Remove dead functions.
+  ///
+  /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
+  /// which restricts it to deleting functions with an 'AlwaysInline'
+  /// attribute. This is useful for the InlineAlways pass that only wants to
+  /// deal with that subset of the functions.
+  bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
+
+private:
+  // InlineThreshold - Cache the value here for easy access.
+  unsigned InlineThreshold;
+
+  // InsertLifetime - Insert @llvm.lifetime intrinsics.
+  bool InsertLifetime;
+
+  /// shouldInline - Return true if the inliner should attempt to
+  /// inline at the given CallSite.
+  bool shouldInline(CallSite CS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
new file mode 100644
index 0000000..50877d0
--- /dev/null
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -0,0 +1,163 @@
+// llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- 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 PassManagerBuilder class, which is used to set up a
+// "standard" optimization sequence suitable for languages like C and C++.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+
+#include <vector>
+
+namespace llvm {
+class TargetLibraryInfo;
+class Pass;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
+class FunctionPassManager;
+}
+using legacy::PassManagerBase;
+using legacy::FunctionPassManager;
+
+/// PassManagerBuilder - This class is used to set up a standard optimization
+/// sequence for languages like C and C++, allowing some APIs to customize the
+/// pass sequence in various ways. A simple example of using it would be:
+///
+///  PassManagerBuilder Builder;
+///  Builder.OptLevel = 2;
+///  Builder.populateFunctionPassManager(FPM);
+///  Builder.populateModulePassManager(MPM);
+///
+/// In addition to setting up the basic passes, PassManagerBuilder allows
+/// frontends to vend a plugin API, where plugins are allowed to add extensions
+/// to the default pass manager.  They do this by specifying where in the pass
+/// pipeline they want to be added, along with a callback function that adds
+/// the pass(es).  For example, a plugin that wanted to add a loop optimization
+/// could do something like this:
+///
+/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
+///   if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
+///     PM.add(createMyAwesomePass());
+/// }
+///   ...
+///   Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
+///                        addMyLoopPass);
+///   ...
+class PassManagerBuilder {
+public:
+  /// Extensions are passed the builder itself (so they can see how it is
+  /// configured) as well as the pass manager to add stuff to.
+  typedef void (*ExtensionFn)(const PassManagerBuilder &Builder,
+                              PassManagerBase &PM);
+  enum ExtensionPointTy {
+    /// EP_EarlyAsPossible - This extension point allows adding passes before
+    /// any other transformations, allowing them to see the code as it is coming
+    /// out of the frontend.
+    EP_EarlyAsPossible,
+
+    /// EP_ModuleOptimizerEarly - This extension point allows adding passes
+    /// just before the main module-level optimization passes.
+    EP_ModuleOptimizerEarly,
+
+    /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
+    /// the end of the loop optimizer.
+    EP_LoopOptimizerEnd,
+
+    /// EP_ScalarOptimizerLate - This extension point allows adding optimization
+    /// passes after most of the main optimizations, but before the last
+    /// cleanup-ish optimizations.
+    EP_ScalarOptimizerLate,
+
+    /// EP_OptimizerLast -- This extension point allows adding passes that
+    /// run after everything else.
+    EP_OptimizerLast,
+
+    /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
+    /// should not be disabled by O0 optimization level. The passes will be
+    /// inserted after the inlining pass.
+    EP_EnabledOnOptLevel0,
+
+    /// EP_Peephole - This extension point allows adding passes that perform
+    /// peephole optimizations similar to the instruction combiner. These passes
+    /// will be inserted after each instance of the instruction combiner pass.
+    EP_Peephole,
+  };
+
+  /// The Optimization Level - Specify the basic optimization level.
+  ///    0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
+  unsigned OptLevel;
+
+  /// SizeLevel - How much we're optimizing for size.
+  ///    0 = none, 1 = -Os, 2 = -Oz
+  unsigned SizeLevel;
+
+  /// LibraryInfo - Specifies information about the runtime library for the
+  /// optimizer.  If this is non-null, it is added to both the function and
+  /// per-module pass pipeline.
+  TargetLibraryInfo *LibraryInfo;
+
+  /// Inliner - Specifies the inliner to use.  If this is non-null, it is
+  /// added to the per-module passes.
+  Pass *Inliner;
+
+  bool DisableTailCalls;
+  bool DisableUnitAtATime;
+  bool DisableUnrollLoops;
+  bool BBVectorize;
+  bool SLPVectorize;
+  bool LoopVectorize;
+  bool RerollLoops;
+  bool LoadCombine;
+
+private:
+  /// ExtensionList - This is list of all of the extensions that are registered.
+  std::vector<std::pair<ExtensionPointTy, ExtensionFn> > Extensions;
+
+public:
+  PassManagerBuilder();
+  ~PassManagerBuilder();
+  /// Adds an extension that will be used by all PassManagerBuilder instances.
+  /// This is intended to be used by plugins, to register a set of
+  /// optimisations to run automatically.
+  static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+  void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+
+private:
+  void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const;
+  void addInitialAliasAnalysisPasses(PassManagerBase &PM) const;
+
+public:
+  /// populateFunctionPassManager - This fills in the function pass manager,
+  /// which is expected to be run on each function immediately as it is
+  /// generated.  The idea is to reduce the size of the IR in memory.
+  void populateFunctionPassManager(FunctionPassManager &FPM);
+
+  /// populateModulePassManager - This sets up the primary pass manager.
+  void populateModulePassManager(PassManagerBase &MPM);
+  void populateLTOPassManager(PassManagerBase &PM, bool Internalize,
+                              bool RunInliner, bool DisableGVNLoadPRE = false);
+};
+
+/// Registers a function for adding a standard set of passes.  This should be
+/// used by optimizer plugins to allow all front ends to transparently use
+/// them.  Create a static instance of this class in your plugin, providing a
+/// private function that the PassManagerBuilder can use to add your passes.
+struct RegisterStandardPasses {
+  RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
+                         PassManagerBuilder::ExtensionFn Fn) {
+    PassManagerBuilder::addGlobalExtension(Ty, Fn);
+  }
+};
+
+} // end namespace llvm
+#endif
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
new file mode 100644
index 0000000..c6a339b
--- /dev/null
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -0,0 +1,126 @@
+//===- Transforms/Instrumentation.h - Instrumentation passes ----*- 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 constructor functions for instrumentation passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_H
+
+#include "llvm/ADT/StringRef.h"
+
+#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
+inline void *getDFSanArgTLSPtrForJIT() {
+  extern __thread __attribute__((tls_model("initial-exec")))
+    void *__dfsan_arg_tls;
+  return (void *)&__dfsan_arg_tls;
+}
+
+inline void *getDFSanRetValTLSPtrForJIT() {
+  extern __thread __attribute__((tls_model("initial-exec")))
+    void *__dfsan_retval_tls;
+  return (void *)&__dfsan_retval_tls;
+}
+#endif
+
+namespace llvm {
+
+class ModulePass;
+class FunctionPass;
+
+// Insert GCOV profiling instrumentation
+struct GCOVOptions {
+  static GCOVOptions getDefault();
+
+  // Specify whether to emit .gcno files.
+  bool EmitNotes;
+
+  // Specify whether to modify the program to emit .gcda files when run.
+  bool EmitData;
+
+  // A four-byte version string. The meaning of a version string is described in
+  // gcc's gcov-io.h
+  char Version[4];
+
+  // Emit a "cfg checksum" that follows the "line number checksum" of a
+  // function. This affects both .gcno and .gcda files.
+  bool UseCfgChecksum;
+
+  // Add the 'noredzone' attribute to added runtime library calls.
+  bool NoRedZone;
+
+  // Emit the name of the function in the .gcda files. This is redundant, as
+  // the function identifier can be used to find the name from the .gcno file.
+  bool FunctionNamesInData;
+};
+ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
+                                   GCOVOptions::getDefault());
+
+// Insert AddressSanitizer (address sanity checking) instrumentation
+FunctionPass *createAddressSanitizerFunctionPass();
+ModulePass *createAddressSanitizerModulePass();
+
+// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
+FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0);
+
+// Insert ThreadSanitizer (race detection) instrumentation
+FunctionPass *createThreadSanitizerPass();
+
+// Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation
+ModulePass *createDataFlowSanitizerPass(StringRef ABIListFile = StringRef(),
+                                        void *(*getArgTLS)() = nullptr,
+                                        void *(*getRetValTLS)() = nullptr);
+
+#if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
+inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile =
+                                                         StringRef()) {
+  return createDataFlowSanitizerPass(ABIListFile, getDFSanArgTLSPtrForJIT,
+                                     getDFSanRetValTLSPtrForJIT);
+}
+#endif
+
+// BoundsChecking - This pass instruments the code to perform run-time bounds
+// checking on loads, stores, and other memory intrinsics.
+FunctionPass *createBoundsCheckingPass();
+
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB (or
+///                     GDB) and generate a file with the LLVM IR to be
+///                     displayed in the debugger.
+///
+/// Existing debug metadata is preserved (but may be modified) in order to allow
+/// accessing variables in the original source. The line table and file
+/// information is modified to correspond to the lines in the LLVM IR. If
+/// Filename and Directory are empty, a file name is generated based on existing
+/// debug information. If no debug information is available, a temporary file
+/// name is generated.
+///
+/// @param HideDebugIntrinsics  Omit debug intrinsics in emitted IR source file.
+/// @param HideDebugMetadata    Omit debug metadata in emitted IR source file.
+/// @param Directory            Embed this directory in the debug information.
+/// @param Filename             Embed this file name in the debug information.
+ModulePass *createDebugIRPass(bool HideDebugIntrinsics,
+                              bool HideDebugMetadata,
+                              StringRef Directory = StringRef(),
+                              StringRef Filename = StringRef());
+
+/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB
+///                     (or GDB) with an existing IR file on disk. When creating
+///                     a DebugIR pass with this function, no source file is
+///                     output to disk and the existing one is unmodified. Debug
+///                     metadata in the Module is created/updated to point to
+///                     the existing textual IR file on disk.
+/// NOTE: If the IR file to be debugged is not on disk, use the version of this
+///       function with parameters in order to generate the file that will be
+///       seen by the debugger.
+ModulePass *createDebugIRPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/ObjCARC.h b/include/llvm/Transforms/ObjCARC.h
new file mode 100644
index 0000000..1897adc
--- /dev/null
+++ b/include/llvm/Transforms/ObjCARC.h
@@ -0,0 +1,48 @@
+//===-- ObjCARC.h - ObjCARC Scalar Transformations --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the ObjCARC Scalar Transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_OBJCARC_H
+#define LLVM_TRANSFORMS_OBJCARC_H
+
+namespace llvm {
+
+class Pass;
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCAPElim - ObjC ARC autorelease pool elimination.
+//
+Pass *createObjCARCAPElimPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCExpand - ObjC ARC preliminary simplifications.
+//
+Pass *createObjCARCExpandPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCContract - Late ObjC ARC cleanups.
+//
+Pass *createObjCARCContractPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCOpt - ObjC ARC optimization.
+//
+Pass *createObjCARCOptPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
new file mode 100644
index 0000000..413134e
--- /dev/null
+++ b/include/llvm/Transforms/Scalar.h
@@ -0,0 +1,400 @@
+//===-- Scalar.h - Scalar Transformations -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the Scalar transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_H
+#define LLVM_TRANSFORMS_SCALAR_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class BasicBlockPass;
+class FunctionPass;
+class Pass;
+class GetElementPtrInst;
+class PassInfo;
+class TerminatorInst;
+class TargetLowering;
+class TargetMachine;
+
+//===----------------------------------------------------------------------===//
+//
+// ConstantPropagation - A worklist driven constant propagation pass
+//
+FunctionPass *createConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SCCP - Sparse conditional constant propagation.
+//
+FunctionPass *createSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadInstElimination - This pass quickly removes trivially dead instructions
+// without modifying the CFG of the function.  It is a BasicBlockPass, so it
+// runs efficiently when queued next to other BasicBlockPass's.
+//
+Pass *createDeadInstEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadCodeElimination - This pass is more powerful than DeadInstElimination,
+// because it is worklist driven that can potentially revisit instructions when
+// their other instructions become dead, to eliminate chains of dead
+// computations.
+//
+FunctionPass *createDeadCodeEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadStoreElimination - This pass deletes stores that are post-dominated by
+// must-aliased stores and are not loaded used between the stores.
+//
+FunctionPass *createDeadStoreEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AggressiveDCE - This pass uses the SSA based Aggressive DCE algorithm.  This
+// algorithm assumes instructions are dead until proven otherwise, which makes
+// it more successful are removing non-obviously dead instructions.
+//
+FunctionPass *createAggressiveDCEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SROA - Replace aggregates or pieces of aggregates with scalar SSA values.
+//
+FunctionPass *createSROAPass(bool RequiresDomTree = true);
+
+//===----------------------------------------------------------------------===//
+//
+// ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas
+// if possible.
+//
+FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1,
+                                             bool UseDomTree = true,
+                                             signed StructMemberThreshold = -1,
+                                             signed ArrayElementThreshold = -1,
+                                             signed ScalarLoadThreshold = -1);
+
+//===----------------------------------------------------------------------===//
+//
+// InductionVariableSimplify - Transform induction variables in a program to all
+// use a single canonical induction variable per loop.
+//
+Pass *createIndVarSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionCombining - Combine instructions to form fewer, simple
+// instructions. This pass does not modify the CFG, and has a tendency to make
+// instructions dead, so a subsequent DCE pass is useful.
+//
+// This pass combines things like:
+//    %Y = add int 1, %X
+//    %Z = add int 1, %Y
+// into:
+//    %Z = add int 2, %X
+//
+FunctionPass *createInstructionCombiningPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LICM - This pass is a loop invariant code motion and memory promotion pass.
+//
+Pass *createLICMPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
+// a loop's canonical induction variable as one of their indices.
+//
+Pass *createLoopStrengthReducePass();
+
+Pass *createGlobalMergePass(const TargetMachine *TM = nullptr);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnswitch - This pass is a simple loop unswitching pass.
+//
+Pass *createLoopUnswitchPass(bool OptimizeForSize = false);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopInstSimplify - This pass simplifies instructions in a loop's body.
+//
+Pass *createLoopInstSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnroll - This pass is a simple loop unrolling pass.
+//
+Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
+                           int AllowPartial = -1, int Runtime = -1);
+// Create an unrolling pass for full unrolling only.
+Pass *createSimpleLoopUnrollPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopReroll - This pass is a simple loop rerolling pass.
+//
+Pass *createLoopRerollPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopRotate - This pass is a simple loop rotating pass.
+//
+Pass *createLoopRotatePass(int MaxHeaderSize = -1);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopIdiom - This pass recognizes and replaces idioms in loops.
+//
+Pass *createLoopIdiomPass();
+
+//===----------------------------------------------------------------------===//
+//
+// PromoteMemoryToRegister - This pass is used to promote memory references to
+// be register references. A simple example of the transformation performed by
+// this pass is:
+//
+//        FROM CODE                           TO CODE
+//   %X = alloca i32, i32 1                 ret i32 42
+//   store i32 42, i32 *%X
+//   %Y = load i32* %X
+//   ret i32 %Y
+//
+FunctionPass *createPromoteMemoryToRegisterPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DemoteRegisterToMemoryPass - This pass is used to demote registers to memory
+// references. In basically undoes the PromoteMemoryToRegister pass to make cfg
+// hacking easier.
+//
+FunctionPass *createDemoteRegisterToMemoryPass();
+extern char &DemoteRegisterToMemoryID;
+
+//===----------------------------------------------------------------------===//
+//
+// Reassociate - This pass reassociates commutative expressions in an order that
+// is designed to promote better constant propagation, GCSE, LICM, PRE...
+//
+// For example:  4 + (x + 5)  ->  x + (4 + 5)
+//
+FunctionPass *createReassociatePass();
+
+//===----------------------------------------------------------------------===//
+//
+// JumpThreading - Thread control through mult-pred/multi-succ blocks where some
+// preds always go to some succ.
+//
+FunctionPass *createJumpThreadingPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
+// simplify terminator instructions, etc...
+//
+FunctionPass *createCFGSimplificationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// FlattenCFG - flatten CFG, reduce number of conditional branches by using
+// parallel-and and parallel-or mode, etc...
+//
+FunctionPass *createFlattenCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFG Structurization - Remove irreducible control flow
+//
+Pass *createStructurizeCFGPass();
+
+//===----------------------------------------------------------------------===//
+//
+// BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
+// a dummy basic block. This pass may be "required" by passes that cannot deal
+// with critical edges. For this usage, a pass must call:
+//
+//   AU.addRequiredID(BreakCriticalEdgesID);
+//
+// This pass obviously invalidates the CFG, but can update forward dominator
+// (set, immediate dominators, tree, and frontier) information.
+//
+FunctionPass *createBreakCriticalEdgesPass();
+extern char &BreakCriticalEdgesID;
+
+//===----------------------------------------------------------------------===//
+//
+// LoopSimplify - Insert Pre-header blocks into the CFG for every function in
+// the module.  This pass updates dominator information, loop information, and
+// does not add critical edges to the CFG.
+//
+//   AU.addRequiredID(LoopSimplifyID);
+//
+Pass *createLoopSimplifyPass();
+extern char &LoopSimplifyID;
+
+//===----------------------------------------------------------------------===//
+//
+// TailCallElimination - This pass eliminates call instructions to the current
+// function which occur immediately before return instructions.
+//
+FunctionPass *createTailCallEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerSwitch - This pass converts SwitchInst instructions into a sequence of
+// chained binary branch instructions.
+//
+FunctionPass *createLowerSwitchPass();
+extern char &LowerSwitchID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerInvoke - This pass removes invoke instructions, converting them to call
+// instructions.
+//
+FunctionPass *createLowerInvokePass();
+extern char &LowerInvokePassID;
+
+//===----------------------------------------------------------------------===//
+//
+// LCSSA - This pass inserts phi nodes at loop boundaries to simplify other loop
+// optimizations.
+//
+Pass *createLCSSAPass();
+extern char &LCSSAID;
+
+//===----------------------------------------------------------------------===//
+//
+// EarlyCSE - This pass performs a simple and fast CSE pass over the dominator
+// tree.
+//
+FunctionPass *createEarlyCSEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// MergedLoadStoreMotion - This pass merges loads and stores in diamonds. Loads
+// are hoisted into the header, while stores sink into the footer.
+//
+FunctionPass *createMergedLoadStoreMotionPass();
+
+//===----------------------------------------------------------------------===//
+//
+// GVN - This pass performs global value numbering and redundant load
+// elimination cotemporaneously.
+//
+FunctionPass *createGVNPass(bool NoLoads = false);
+
+//===----------------------------------------------------------------------===//
+//
+// MemCpyOpt - This pass performs optimizations related to eliminating memcpy
+// calls and/or combining multiple stores into memset's.
+//
+FunctionPass *createMemCpyOptPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopDeletion - This pass performs DCE of non-infinite loops that it
+// can prove are dead.
+//
+Pass *createLoopDeletionPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ConstantHoisting - This pass prepares a function for expensive constants.
+//
+FunctionPass *createConstantHoistingPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionNamer - Give any unnamed non-void instructions "tmp" names.
+//
+FunctionPass *createInstructionNamerPass();
+extern char &InstructionNamerID;
+
+//===----------------------------------------------------------------------===//
+//
+// Sink - Code Sinking
+//
+FunctionPass *createSinkingPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerAtomic - Lower atomic intrinsics to non-atomic form
+//
+Pass *createLowerAtomicPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ValuePropagation - Propagate CFG-derived value information
+//
+Pass *createCorrelatedValuePropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionSimplifier - Remove redundant instructions.
+//
+FunctionPass *createInstructionSimplifierPass();
+extern char &InstructionSimplifierID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerExpectIntrinsics - Removes llvm.expect intrinsics and creates
+// "block_weights" metadata.
+FunctionPass *createLowerExpectIntrinsicPass();
+
+//===----------------------------------------------------------------------===//
+//
+// PartiallyInlineLibCalls - Tries to inline the fast path of library
+// calls such as sqrt.
+//
+FunctionPass *createPartiallyInlineLibCallsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SampleProfilePass - Loads sample profile data from disk and generates
+// IR metadata to reflect the profile.
+FunctionPass *createSampleProfileLoaderPass();
+FunctionPass *createSampleProfileLoaderPass(StringRef Name);
+
+//===----------------------------------------------------------------------===//
+//
+// ScalarizerPass - Converts vector operations into scalar operations
+//
+FunctionPass *createScalarizerPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AddDiscriminators - Add DWARF path discriminators to the IR.
+FunctionPass *createAddDiscriminatorsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SeparateConstOffsetFromGEP - Split GEPs for better CSE
+//
+FunctionPass *createSeparateConstOffsetFromGEPPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoadCombine - Combine loads into bigger loads.
+//
+BasicBlockPass *createLoadCombinePass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/ASanStackFrameLayout.h b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
new file mode 100644
index 0000000..4e4f02c
--- /dev/null
+++ b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
@@ -0,0 +1,64 @@
+//===- ASanStackFrameLayout.h - ComputeASanStackFrameLayout -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines ComputeASanStackFrameLayout and auxiliary data structs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class AllocaInst;
+
+// These magic constants should be the same as in
+// in asan_internal.h from ASan runtime in compiler-rt.
+static const int kAsanStackLeftRedzoneMagic = 0xf1;
+static const int kAsanStackMidRedzoneMagic = 0xf2;
+static const int kAsanStackRightRedzoneMagic = 0xf3;
+
+// Input/output data struct for ComputeASanStackFrameLayout.
+struct ASanStackVariableDescription {
+  const char *Name;  // Name of the variable that will be displayed by asan
+                     // if a stack-related bug is reported.
+  uint64_t Size;     // Size of the variable in bytes.
+  size_t Alignment;  // Alignment of the variable (power of 2).
+  AllocaInst *AI;    // The actual AllocaInst.
+  size_t Offset;     // Offset from the beginning of the frame;
+                     // set by ComputeASanStackFrameLayout.
+};
+
+// Output data struct for ComputeASanStackFrameLayout.
+struct ASanStackFrameLayout {
+  // Frame description, see DescribeAddressIfStack in ASan runtime.
+  SmallString<64> DescriptionString;
+  // The contents of the shadow memory for the stack frame that we need
+  // to set at function entry.
+  SmallVector<uint8_t, 64> ShadowBytes;
+  size_t FrameAlignment;  // Alignment for the entire frame.
+  size_t FrameSize;       // Size of the frame in bytes.
+};
+
+void ComputeASanStackFrameLayout(
+    // The array of stack variables. The elements may get reordered and changed.
+    SmallVectorImpl<ASanStackVariableDescription> &Vars,
+    // AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64.
+    size_t Granularity,
+    // The minimal size of the left-most redzone (header).
+    // At least 4 pointer sizes, power of 2, and >= Granularity.
+    // The resulting FrameSize should be multiple of MinHeaderSize.
+    size_t MinHeaderSize,
+    // The result is put here.
+    ASanStackFrameLayout *Layout);
+
+} // llvm namespace
+
+#endif  // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
new file mode 100644
index 0000000..bcafda6
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -0,0 +1,242 @@
+//===-- Transform/Utils/BasicBlockUtils.h - BasicBlock Utils ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform manipulations on basic blocks, and
+// instructions contained within basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
+#define LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
+
+// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class DominatorTree;
+class Instruction;
+class MDNode;
+class Pass;
+class ReturnInst;
+class TargetLibraryInfo;
+class TerminatorInst;
+
+/// DeleteDeadBlock - Delete the specified block, which must have no
+/// predecessors.
+void DeleteDeadBlock(BasicBlock *BB);
+
+/// FoldSingleEntryPHINodes - We know that BB has one predecessor.  If there are
+/// any single-entry PHI nodes in it, fold them away.  This handles the case
+/// when all entries to the PHI nodes in a block are guaranteed equal, such as
+/// when the block has exactly one predecessor.
+void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = nullptr);
+
+/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
+/// is dead. Also recursively delete any operands that become dead as
+/// a result. This includes tracing the def-use list from the PHI to see if
+/// it is ultimately unused or if it reaches an unused cycle. Return true
+/// if any PHIs were deleted.
+bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr);
+
+/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
+/// if possible.  The return value indicates success or failure.
+bool MergeBlockIntoPredecessor(BasicBlock *BB, Pass *P = nullptr);
+
+// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
+// with a value, then remove and delete the original instruction.
+//
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+                          BasicBlock::iterator &BI, Value *V);
+
+// ReplaceInstWithInst - Replace the instruction specified by BI with the
+// instruction specified by I.  The original instruction is deleted and BI is
+// updated to point to the new instruction.
+//
+void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
+                         BasicBlock::iterator &BI, Instruction *I);
+
+// ReplaceInstWithInst - Replace the instruction specified by From with the
+// instruction specified by To.
+//
+void ReplaceInstWithInst(Instruction *From, Instruction *To);
+
+/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
+/// split the critical edge.  This will update DominatorTree and
+/// DominatorFrontier information if it is available, thus calling this pass
+/// will not invalidate either of them. This returns the new block if the edge
+/// was split, null otherwise.
+///
+/// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the
+/// specified successor will be merged into the same critical edge block.
+/// This is most commonly interesting with switch instructions, which may
+/// have many edges to any one destination.  This ensures that all edges to that
+/// dest go to one block instead of each going to a different block, but isn't
+/// the standard definition of a "critical edge".
+///
+/// It is invalid to call this function on a critical edge that starts at an
+/// IndirectBrInst.  Splitting these edges will almost always create an invalid
+/// program because the address of the new block won't be the one that is jumped
+/// to.
+///
+BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
+                              Pass *P = nullptr,
+                              bool MergeIdenticalEdges = false,
+                              bool DontDeleteUselessPHIs = false,
+                              bool SplitLandingPads = false);
+
+inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
+                                     Pass *P = nullptr) {
+  return SplitCriticalEdge(BB->getTerminator(), SI.getSuccessorIndex(), P);
+}
+
+/// SplitCriticalEdge - If the edge from *PI to BB is not critical, return
+/// false.  Otherwise, split all edges between the two blocks and return true.
+/// This updates all of the same analyses as the other SplitCriticalEdge
+/// function.  If P is specified, it updates the analyses
+/// described above.
+inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI,
+                              Pass *P = nullptr) {
+  bool MadeChange = false;
+  TerminatorInst *TI = (*PI)->getTerminator();
+  for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
+    if (TI->getSuccessor(i) == Succ)
+      MadeChange |= !!SplitCriticalEdge(TI, i, P);
+  return MadeChange;
+}
+
+/// SplitCriticalEdge - If an edge from Src to Dst is critical, split the edge
+/// and return true, otherwise return false.  This method requires that there be
+/// an edge between the two blocks.  If P is specified, it updates the analyses
+/// described above.
+inline BasicBlock *SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst,
+                                     Pass *P = nullptr,
+                                     bool MergeIdenticalEdges = false,
+                                     bool DontDeleteUselessPHIs = false) {
+  TerminatorInst *TI = Src->getTerminator();
+  unsigned i = 0;
+  while (1) {
+    assert(i != TI->getNumSuccessors() && "Edge doesn't exist!");
+    if (TI->getSuccessor(i) == Dst)
+      return SplitCriticalEdge(TI, i, P, MergeIdenticalEdges,
+                               DontDeleteUselessPHIs);
+    ++i;
+  }
+}
+
+/// SplitEdge -  Split the edge connecting specified block. Pass P must
+/// not be NULL.
+BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P);
+
+/// SplitBlock - Split the specified block at the specified instruction - every
+/// thing before SplitPt stays in Old and everything starting with SplitPt moves
+/// to a new block.  The two blocks are joined by an unconditional branch and
+/// the loop info is updated.
+///
+BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
+
+/// SplitBlockPredecessors - This method transforms BB by introducing a new
+/// basic block into the function, and moving some of the predecessors of BB to
+/// be predecessors of the new block.  The new predecessors are indicated by the
+/// Preds array, which has NumPreds elements in it.  The new block is given a
+/// suffix of 'Suffix'.  This function returns the new block.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses.
+/// In particular, it does not preserve LoopSimplify (because it's
+/// complicated to handle the case where one of the edges being split
+/// is an exit of a loop with other exits).
+///
+BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock*> Preds,
+                                   const char *Suffix, Pass *P = nullptr);
+
+/// SplitLandingPadPredecessors - This method transforms the landing pad,
+/// OrigBB, by introducing two new basic blocks into the function. One of those
+/// new basic blocks gets the predecessors listed in Preds. The other basic
+/// block gets the remaining predecessors of OrigBB. The landingpad instruction
+/// OrigBB is clone into both of the new basic blocks. The new blocks are given
+/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular,
+/// it does not preserve LoopSimplify (because it's complicated to handle the
+/// case where one of the edges being split is an exit of a loop with other
+/// exits).
+///
+void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds,
+                                 const char *Suffix, const char *Suffix2,
+                                 Pass *P, SmallVectorImpl<BasicBlock*> &NewBBs);
+
+/// FoldReturnIntoUncondBranch - This method duplicates the specified return
+/// instruction into a predecessor which ends in an unconditional branch. If
+/// the return instruction returns a value defined by a PHI, propagate the
+/// right value into the return. It returns the new return instruction in the
+/// predecessor.
+ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
+                                       BasicBlock *Pred);
+
+/// SplitBlockAndInsertIfThen - Split the containing block at the
+/// specified instruction - everything before and including SplitBefore stays
+/// in the old basic block, and everything after SplitBefore is moved to a
+/// new block. The two blocks are connected by a conditional branch
+/// (with value of Cmp being the condition).
+/// Before:
+///   Head
+///   SplitBefore
+///   Tail
+/// After:
+///   Head
+///   if (Cond)
+///     ThenBlock
+///   SplitBefore
+///   Tail
+///
+/// If Unreachable is true, then ThenBlock ends with
+/// UnreachableInst, otherwise it branches to Tail.
+/// Returns the NewBasicBlock's terminator.
+///
+/// Updates DT if given.
+TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
+                                          bool Unreachable,
+                                          MDNode *BranchWeights = nullptr,
+                                          DominatorTree *DT = nullptr);
+
+/// SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen,
+/// but also creates the ElseBlock.
+/// Before:
+///   Head
+///   SplitBefore
+///   Tail
+/// After:
+///   Head
+///   if (Cond)
+///     ThenBlock
+///   else
+///     ElseBlock
+///   SplitBefore
+///   Tail
+void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
+                                   TerminatorInst **ThenTerm,
+                                   TerminatorInst **ElseTerm,
+                                   MDNode *BranchWeights = nullptr);
+
+///
+/// GetIfCondition - Check whether BB is the merge point of a if-region.
+/// If so, return the boolean condition that determines which entry into
+/// BB will be taken.  Also, return by references the block that will be
+/// entered from if the condition is true, and the block that will be
+/// entered if the condition is false.
+Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
+                      BasicBlock *&IfFalse);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
new file mode 100644
index 0000000..1e407fb
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -0,0 +1,134 @@
+//===- BuildLibCalls.h - Utility builder for libcalls -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to build some C language libcalls for
+// optimization passes that need to call the various functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
+#define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
+
+#include "llvm/IR/IRBuilder.h"
+
+namespace llvm {
+  class Value;
+  class DataLayout;
+  class TargetLibraryInfo;
+
+  /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
+  Value *CastToCStr(Value *V, IRBuilder<> &B);
+
+  /// EmitStrLen - Emit a call to the strlen function to the builder, for the
+  /// specified pointer.  Ptr is required to be some pointer type, and the
+  /// return value has 'intptr_t' type.
+  Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
+                    const TargetLibraryInfo *TLI);
+
+  /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
+  /// specified pointer.  Ptr is required to be some pointer type, MaxLen must
+  /// be of size_t type, and the return value has 'intptr_t' type.
+  Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
+                     const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// EmitStrChr - Emit a call to the strchr function to the builder, for the
+  /// specified pointer and character.  Ptr is required to be some pointer type,
+  /// and the return value has 'i8*' type.
+  Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD,
+                    const TargetLibraryInfo *TLI);
+
+  /// EmitStrNCmp - Emit a call to the strncmp function to the builder.
+  Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+                     const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+  /// specified pointer arguments.
+  Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+                    const DataLayout *TD, const TargetLibraryInfo *TLI,
+                    StringRef Name = "strcpy");
+
+  /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
+  /// specified pointer arguments and length.
+  Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
+                     const DataLayout *TD, const TargetLibraryInfo *TLI,
+                     StringRef Name = "strncpy");
+
+  /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
+  /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
+  /// are pointers.
+  Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
+                       IRBuilder<> &B, const DataLayout *TD,
+                       const TargetLibraryInfo *TLI);
+
+  /// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
+  /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
+  Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
+                    const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// EmitMemCmp - Emit a call to the memcmp function.
+  Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+                    const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
+  /// (e.g.  'floor').  This function is known to take a single of type matching
+  /// 'Op' and returns one value with the same type.  If 'Op' is a long double,
+  /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f'
+  /// suffix.
+  Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
+                              const AttributeSet &Attrs);
+
+  /// EmitUnaryFloatFnCall - Emit a call to the binary function named 'Name'
+  /// (e.g. 'fmin').  This function is known to take type matching 'Op1' and
+  /// 'Op2' and return one value with the same type.  If 'Op1/Op2' are long
+  /// double, 'l' is added as the suffix of name, if 'Op1/Op2' are float, we
+  /// add a 'f' suffix.
+  Value *EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
+                                  IRBuilder<> &B, const AttributeSet &Attrs);
+
+  /// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
+  /// is an integer.
+  Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
+                     const TargetLibraryInfo *TLI);
+
+  /// EmitPutS - Emit a call to the puts function.  This assumes that Str is
+  /// some pointer.
+  Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
+                  const TargetLibraryInfo *TLI);
+
+  /// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
+  /// an i32, and File is a pointer to FILE.
+  Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+                   const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// EmitFPutS - Emit a call to the puts function.  Str is required to be a
+  /// pointer and File is a pointer to FILE.
+  Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD,
+                   const TargetLibraryInfo *TLI);
+
+  /// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
+  /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
+  Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
+                    const DataLayout *TD, const TargetLibraryInfo *TLI);
+
+  /// SimplifyFortifiedLibCalls - Helper class for folding checked library
+  /// calls (e.g. __strcpy_chk) into their unchecked counterparts.
+  class SimplifyFortifiedLibCalls {
+  protected:
+    CallInst *CI;
+    virtual void replaceCall(Value *With) = 0;
+    virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
+                            bool isString) const = 0;
+
+  public:
+    virtual ~SimplifyFortifiedLibCalls();
+    bool fold(CallInst *CI, const DataLayout *TD, const TargetLibraryInfo *TLI);
+  };
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h
new file mode 100644
index 0000000..0d081c0
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -0,0 +1,34 @@
+//===- llvm/Transforms/Utils/BypassSlowDivision.h --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an optimization for div and rem on architectures that
+// execute short instructions significantly faster than longer instructions.
+// For example, on Intel Atom 32-bit divides are slow enough that during
+// runtime it is profitable to check the value of the operands, and if they are
+// positive and less than 256 use an unsigned 8-bit divide.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
+#define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Function.h"
+
+namespace llvm {
+
+/// This optimization identifies DIV instructions that can be
+/// profitably bypassed and carried out with a shorter, faster divide.
+bool bypassSlowDivision(Function &F,
+                        Function::iterator &I,
+                        const DenseMap<unsigned int, unsigned int> &BypassWidth);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
new file mode 100644
index 0000000..bdf50dd
--- /dev/null
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -0,0 +1,198 @@
+//===- Cloning.h - Clone various parts of LLVM programs ---------*- 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 various functions that are used to clone chunks of LLVM
+// code for various purposes.  This varies from copying whole modules into new
+// modules, to cloning functions with different arguments, to inlining
+// functions, to copying basic blocks to support loop unrolling or superblock
+// formation, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CLONING_H
+#define LLVM_TRANSFORMS_UTILS_CLONING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueMap.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+
+namespace llvm {
+
+class Module;
+class Function;
+class Instruction;
+class Pass;
+class LPPassManager;
+class BasicBlock;
+class Value;
+class CallInst;
+class InvokeInst;
+class ReturnInst;
+class CallSite;
+class Trace;
+class CallGraph;
+class DataLayout;
+class Loop;
+class LoopInfo;
+class AllocaInst;
+
+/// CloneModule - Return an exact copy of the specified module
+///
+Module *CloneModule(const Module *M);
+Module *CloneModule(const Module *M, ValueToValueMapTy &VMap);
+
+/// ClonedCodeInfo - This struct can be used to capture information about code
+/// being cloned, while it is being cloned.
+struct ClonedCodeInfo {
+  /// ContainsCalls - This is set to true if the cloned code contains a normal
+  /// call instruction.
+  bool ContainsCalls;
+
+  /// ContainsDynamicAllocas - This is set to true if the cloned code contains
+  /// a 'dynamic' alloca.  Dynamic allocas are allocas that are either not in
+  /// the entry block or they are in the entry block but are not a constant
+  /// size.
+  bool ContainsDynamicAllocas;
+
+  ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {}
+};
+
+/// CloneBasicBlock - Return a copy of the specified basic block, but without
+/// embedding the block into a particular function.  The block returned is an
+/// exact copy of the specified basic block, without any remapping having been
+/// performed.  Because of this, this is only suitable for applications where
+/// the basic block will be inserted into the same function that it was cloned
+/// from (loop unrolling would use this, for example).
+///
+/// Also, note that this function makes a direct copy of the basic block, and
+/// can thus produce illegal LLVM code.  In particular, it will copy any PHI
+/// nodes from the original block, even though there are no predecessors for the
+/// newly cloned block (thus, phi nodes will have to be updated).  Also, this
+/// block will branch to the old successors of the original block: these
+/// successors will have to have any PHI nodes updated to account for the new
+/// incoming edges.
+///
+/// The correlation between instructions in the source and result basic blocks
+/// is recorded in the VMap map.
+///
+/// If you have a particular suffix you'd like to use to add to any cloned
+/// names, specify it as the optional third parameter.
+///
+/// If you would like the basic block to be auto-inserted into the end of a
+/// function, you can specify it as the optional fourth parameter.
+///
+/// If you would like to collect additional information about the cloned
+/// function, you can specify a ClonedCodeInfo object with the optional fifth
+/// parameter.
+///
+BasicBlock *CloneBasicBlock(const BasicBlock *BB,
+                            ValueToValueMapTy &VMap,
+                            const Twine &NameSuffix = "", Function *F = nullptr,
+                            ClonedCodeInfo *CodeInfo = nullptr);
+
+/// CloneFunction - Return a copy of the specified function, but without
+/// embedding the function into another module.  Also, any references specified
+/// in the VMap are changed to refer to their mapped value instead of the
+/// original one.  If any of the arguments to the function are in the VMap,
+/// the arguments are deleted from the resultant function.  The VMap is
+/// updated to include mappings from all of the instructions and basicblocks in
+/// the function from their old to new values.  The final argument captures
+/// information about the cloned code if non-null.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings, and debug info metadata will not be cloned.
+///
+Function *CloneFunction(const Function *F,
+                        ValueToValueMapTy &VMap,
+                        bool ModuleLevelChanges,
+                        ClonedCodeInfo *CodeInfo = nullptr);
+
+/// Clone OldFunc into NewFunc, transforming the old arguments into references
+/// to VMap values.  Note that if NewFunc already has basic blocks, the ones
+/// cloned into it will be added to the end of the function.  This function
+/// fills in a list of return instructions, and can optionally remap types
+/// and/or append the specified suffix to all values cloned.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings.
+///
+void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
+                       ValueToValueMapTy &VMap,
+                       bool ModuleLevelChanges,
+                       SmallVectorImpl<ReturnInst*> &Returns,
+                       const char *NameSuffix = "",
+                       ClonedCodeInfo *CodeInfo = nullptr,
+                       ValueMapTypeRemapper *TypeMapper = nullptr,
+                       ValueMaterializer *Materializer = nullptr);
+
+/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
+/// except that it does some simple constant prop and DCE on the fly.  The
+/// effect of this is to copy significantly less code in cases where (for
+/// example) a function call with constant arguments is inlined, and those
+/// constant arguments cause a significant amount of code in the callee to be
+/// dead.  Since this doesn't produce an exactly copy of the input, it can't be
+/// used for things like CloneFunction or CloneModule.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings.
+///
+void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
+                               ValueToValueMapTy &VMap,
+                               bool ModuleLevelChanges,
+                               SmallVectorImpl<ReturnInst*> &Returns,
+                               const char *NameSuffix = "",
+                               ClonedCodeInfo *CodeInfo = nullptr,
+                               const DataLayout *DL = nullptr,
+                               Instruction *TheCall = nullptr);
+
+/// InlineFunctionInfo - This class captures the data input to the
+/// InlineFunction call, and records the auxiliary results produced by it.
+class InlineFunctionInfo {
+public:
+  explicit InlineFunctionInfo(CallGraph *cg = nullptr, const DataLayout *DL = nullptr)
+    : CG(cg), DL(DL) {}
+
+  /// CG - If non-null, InlineFunction will update the callgraph to reflect the
+  /// changes it makes.
+  CallGraph *CG;
+  const DataLayout *DL;
+
+  /// StaticAllocas - InlineFunction fills this in with all static allocas that
+  /// get copied into the caller.
+  SmallVector<AllocaInst*, 4> StaticAllocas;
+
+  /// InlinedCalls - InlineFunction fills this in with callsites that were
+  /// inlined from the callee.  This is only filled in if CG is non-null.
+  SmallVector<WeakVH, 8> InlinedCalls;
+
+  void reset() {
+    StaticAllocas.clear();
+    InlinedCalls.clear();
+  }
+};
+
+/// InlineFunction - This function inlines the called function into the basic
+/// block of the caller.  This returns false if it is not possible to inline
+/// this call.  The program is still in a well defined state if this occurs
+/// though.
+///
+/// Note that this only does one level of inlining.  For example, if the
+/// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
+/// exists in the instruction stream.  Similarly this will inline a recursive
+/// function by one level.
+///
+bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
new file mode 100644
index 0000000..73c15e4
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
@@ -0,0 +1,65 @@
+//===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds routines to help analyse compare instructions
+// and fold them into constants or other compare instructions
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
+#define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
+
+#include "llvm/IR/InstrTypes.h"
+
+namespace llvm {
+  class ICmpInst;
+  class Value;
+
+  /// getICmpCode - Encode a icmp predicate into a three bit mask.  These bits
+  /// are carefully arranged to allow folding of expressions such as:
+  ///
+  ///      (A < B) | (A > B) --> (A != B)
+  ///
+  /// Note that this is only valid if the first and second predicates have the
+  /// same sign. Is illegal to do: (A u< B) | (A s> B)
+  ///
+  /// Three bits are used to represent the condition, as follows:
+  ///   0  A > B
+  ///   1  A == B
+  ///   2  A < B
+  ///
+  /// <=>  Value  Definition
+  /// 000     0   Always false
+  /// 001     1   A >  B
+  /// 010     2   A == B
+  /// 011     3   A >= B
+  /// 100     4   A <  B
+  /// 101     5   A != B
+  /// 110     6   A <= B
+  /// 111     7   Always true
+  ///
+  unsigned getICmpCode(const ICmpInst *ICI, bool InvertPred = false);
+
+  /// getICmpValue - This is the complement of getICmpCode, which turns an
+  /// opcode and two operands into either a constant true or false, or the
+  /// predicate for a new ICmp instruction. The sign is passed in to determine
+  /// which kind of predicate to use in the new icmp instruction.
+  /// Non-NULL return value will be a true or false constant.
+  /// NULL return means a new ICmp is needed.  The predicate for which is
+  /// output in NewICmpPred.
+  Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
+                      CmpInst::Predicate &NewICmpPred);
+
+  /// PredicatesFoldable - Return true if both predicates match sign or if at
+  /// least one of them is an equality comparison (which is signless).
+  bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2);
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
new file mode 100644
index 0000000..6b41e82
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -0,0 +1,126 @@
+//===-- Transform/Utils/CodeExtractor.h - Code extraction util --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A utility to support extracting code from one function into its own
+// stand-alone function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+#define LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace llvm {
+  class BasicBlock;
+  class DominatorTree;
+  class Function;
+  class Loop;
+  class Module;
+  class RegionNode;
+  class Type;
+  class Value;
+
+  /// \brief Utility class for extracting code into a new function.
+  ///
+  /// This utility provides a simple interface for extracting some sequence of
+  /// code into its own function, replacing it with a call to that function. It
+  /// also provides various methods to query about the nature and result of
+  /// such a transformation.
+  ///
+  /// The rough algorithm used is:
+  /// 1) Find both the inputs and outputs for the extracted region.
+  /// 2) Pass the inputs as arguments, remapping them within the extracted
+  ///    function to arguments.
+  /// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas
+  ///    as arguments, and inserting stores to the arguments for any scalars.
+  class CodeExtractor {
+    typedef SetVector<Value *> ValueSet;
+
+    // Various bits of state computed on construction.
+    DominatorTree *const DT;
+    const bool AggregateArgs;
+
+    // Bits of intermediate state computed at various phases of extraction.
+    SetVector<BasicBlock *> Blocks;
+    unsigned NumExitBlocks;
+    Type *RetTy;
+
+  public:
+    /// \brief Create a code extractor for a single basic block.
+    ///
+    /// In this formation, we don't require a dominator tree. The given basic
+    /// block is set up for extraction.
+    CodeExtractor(BasicBlock *BB, bool AggregateArgs = false);
+
+    /// \brief Create a code extractor for a sequence of blocks.
+    ///
+    /// Given a sequence of basic blocks where the first block in the sequence
+    /// dominates the rest, prepare a code extractor object for pulling this
+    /// sequence out into its new function. When a DominatorTree is also given,
+    /// extra checking and transformations are enabled.
+    CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
+                  bool AggregateArgs = false);
+
+    /// \brief Create a code extractor for a loop body.
+    ///
+    /// Behaves just like the generic code sequence constructor, but uses the
+    /// block sequence of the loop.
+    CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs = false);
+
+    /// \brief Create a code extractor for a region node.
+    ///
+    /// Behaves just like the generic code sequence constructor, but uses the
+    /// block sequence of the region node passed in.
+    CodeExtractor(DominatorTree &DT, const RegionNode &RN,
+                  bool AggregateArgs = false);
+
+    /// \brief Perform the extraction, returning the new function.
+    ///
+    /// Returns zero when called on a CodeExtractor instance where isEligible
+    /// returns false.
+    Function *extractCodeRegion();
+
+    /// \brief Test whether this code extractor is eligible.
+    ///
+    /// Based on the blocks used when constructing the code extractor,
+    /// determine whether it is eligible for extraction.
+    bool isEligible() const { return !Blocks.empty(); }
+
+    /// \brief Compute the set of input values and output values for the code.
+    ///
+    /// These can be used either when performing the extraction or to evaluate
+    /// the expected size of a call to the extracted function. Note that this
+    /// work cannot be cached between the two as once we decide to extract
+    /// a code sequence, that sequence is modified, including changing these
+    /// sets, before extraction occurs. These modifications won't have any
+    /// significant impact on the cost however.
+    void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs) const;
+
+  private:
+    void severSplitPHINodes(BasicBlock *&Header);
+    void splitReturnBlocks();
+
+    Function *constructFunction(const ValueSet &inputs,
+                                const ValueSet &outputs,
+                                BasicBlock *header,
+                                BasicBlock *newRootNode, BasicBlock *newHeader,
+                                Function *oldFunction, Module *M);
+
+    void moveCodeToFunction(Function *newFunction);
+
+    void emitCallAndSwitchStatement(Function *newFunction,
+                                    BasicBlock *newHeader,
+                                    ValueSet &inputs,
+                                    ValueSet &outputs);
+  };
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/CtorUtils.h b/include/llvm/Transforms/Utils/CtorUtils.h
new file mode 100644
index 0000000..81e7b95
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CtorUtils.h
@@ -0,0 +1,32 @@
+//===- CtorUtils.h - Helpers for working with global_ctors ------*- 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 functions that are used to process llvm.global_ctors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
+#define LLVM_TRANSFORMS_UTILS_CTOR_UTILS_H
+
+#include "llvm/ADT/STLExtras.h"
+
+namespace llvm {
+
+class GlobalVariable;
+class Function;
+class Module;
+
+/// Call "ShouldRemove" for every entry in M's global_ctor list and remove the
+/// entries for which it returns true.  Return true if anything changed.
+bool optimizeGlobalCtorsList(Module &M,
+                             function_ref<bool(Function *)> ShouldRemove);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/GlobalStatus.h b/include/llvm/Transforms/Utils/GlobalStatus.h
new file mode 100644
index 0000000..c366095
--- /dev/null
+++ b/include/llvm/Transforms/Utils/GlobalStatus.h
@@ -0,0 +1,82 @@
+//===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
+#define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
+
+#include "llvm/IR/Instructions.h"
+
+namespace llvm {
+class Value;
+class Function;
+
+/// It is safe to destroy a constant iff it is only used by constants itself.
+/// Note that constants cannot be cyclic, so this test is pretty easy to
+/// implement recursively.
+///
+bool isSafeToDestroyConstant(const Constant *C);
+
+/// As we analyze each global, keep track of some information about it.  If we
+/// find out that the address of the global is taken, none of this info will be
+/// accurate.
+struct GlobalStatus {
+  /// True if the global's address is used in a comparison.
+  bool IsCompared;
+
+  /// True if the global is ever loaded.  If the global isn't ever loaded it
+  /// can be deleted.
+  bool IsLoaded;
+
+  /// Keep track of what stores to the global look like.
+  enum StoredType {
+    /// There is no store to this global.  It can thus be marked constant.
+    NotStored,
+
+    /// This global is stored to, but the only thing stored is the constant it
+    /// was initialized with. This is only tracked for scalar globals.
+    InitializerStored,
+
+    /// This global is stored to, but only its initializer and one other value
+    /// is ever stored to it.  If this global isStoredOnce, we track the value
+    /// stored to it in StoredOnceValue below.  This is only tracked for scalar
+    /// globals.
+    StoredOnce,
+
+    /// This global is stored to by multiple values or something else that we
+    /// cannot track.
+    Stored
+  } StoredType;
+
+  /// If only one value (besides the initializer constant) is ever stored to
+  /// this global, keep track of what value it is.
+  Value *StoredOnceValue;
+
+  /// These start out null/false.  When the first accessing function is noticed,
+  /// it is recorded. When a second different accessing function is noticed,
+  /// HasMultipleAccessingFunctions is set to true.
+  const Function *AccessingFunction;
+  bool HasMultipleAccessingFunctions;
+
+  /// Set to true if this global has a user that is not an instruction (e.g. a
+  /// constant expr or GV initializer).
+  bool HasNonInstructionUser;
+
+  /// Set to the strongest atomic ordering requirement.
+  AtomicOrdering Ordering;
+
+  /// Look at all uses of the global and fill in the GlobalStatus structure.  If
+  /// the global has its address taken, return true to indicate we can't do
+  /// anything with it.
+  static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
+
+  GlobalStatus();
+};
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h
new file mode 100644
index 0000000..0ec3321
--- /dev/null
+++ b/include/llvm/Transforms/Utils/IntegerDivision.h
@@ -0,0 +1,73 @@
+//===- llvm/Transforms/Utils/IntegerDivision.h ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains an implementation of 32bit and 64bit scalar integer
+// division for targets that don't have native support. It's largely derived
+// from compiler-rt's implementations of __udivsi3 and __udivmoddi4,
+// but hand-tuned for targets that prefer less control flow.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
+#define LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
+
+namespace llvm {
+  class BinaryOperator;
+}
+
+namespace llvm {
+
+  /// Generate code to calculate the remainder of two integers, replacing Rem
+  /// with the generated code. This currently generates code using the udiv
+  /// expansion, but future work includes generating more specialized code,
+  /// e.g. when more information about the operands are known. Implements both
+  /// 32bit and 64bit scalar division.
+  ///
+  /// @brief Replace Rem with generated code.
+  bool expandRemainder(BinaryOperator *Rem);
+
+  /// Generate code to divide two integers, replacing Div with the generated
+  /// code. This currently generates code similarly to compiler-rt's
+  /// implementations, but future work includes generating more specialized code
+  /// when more information about the operands are known. Implements both
+  /// 32bit and 64bit scalar division.
+  ///
+  /// @brief Replace Div with generated code.
+  bool expandDivision(BinaryOperator* Div);
+
+  /// Generate code to calculate the remainder of two integers, replacing Rem
+  /// with the generated code. Uses ExpandReminder with a 32bit Rem which
+  /// makes it useful for targets with little or no support for less than
+  /// 32 bit arithmetic.
+  ///
+  /// @brief Replace Rem with generated code.
+  bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
+
+  /// Generate code to calculate the remainder of two integers, replacing Rem
+  /// with the generated code. Uses ExpandReminder with a 64bit Rem.
+  ///
+  /// @brief Replace Rem with generated code.
+  bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
+
+  /// Generate code to divide two integers, replacing Div with the generated
+  /// code. Uses ExpandDivision with a 32bit Div which makes it useful for
+  /// targets with little or no support for less than 32 bit arithmetic.
+  ///
+  /// @brief Replace Rem with generated code.
+  bool expandDivisionUpTo32Bits(BinaryOperator *Div);
+
+  /// Generate code to divide two integers, replacing Div with the generated
+  /// code. Uses ExpandDivision with a 64bit Div.
+  ///
+  /// @brief Replace Rem with generated code.
+  bool expandDivisionUpTo64Bits(BinaryOperator *Div);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
new file mode 100644
index 0000000..c0c6906
--- /dev/null
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -0,0 +1,280 @@
+//===-- Local.h - Functions to perform local transformations ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform various local transformations to the
+// program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
+#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Operator.h"
+
+namespace llvm {
+
+class User;
+class BasicBlock;
+class Function;
+class BranchInst;
+class Instruction;
+class DbgDeclareInst;
+class StoreInst;
+class LoadInst;
+class Value;
+class Pass;
+class PHINode;
+class AllocaInst;
+class ConstantExpr;
+class DataLayout;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+class DIBuilder;
+class AliasAnalysis;
+
+template<typename T> class SmallVectorImpl;
+
+//===----------------------------------------------------------------------===//
+//  Local constant propagation.
+//
+
+/// ConstantFoldTerminator - If a terminator instruction is predicated on a
+/// constant value, convert it into an unconditional branch to the constant
+/// destination.  This is a nontrivial operation because the successors of this
+/// basic block must have their PHI nodes updated.
+/// Also calls RecursivelyDeleteTriviallyDeadInstructions() on any branch/switch
+/// conditions and indirectbr addresses this might make dead if
+/// DeleteDeadConditions is true.
+bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false,
+                            const TargetLibraryInfo *TLI = nullptr);
+
+//===----------------------------------------------------------------------===//
+//  Local dead code elimination.
+//
+
+/// isInstructionTriviallyDead - Return true if the result produced by the
+/// instruction is not used, and the instruction has no side effects.
+///
+bool isInstructionTriviallyDead(Instruction *I,
+                                const TargetLibraryInfo *TLI = nullptr);
+
+/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
+/// trivially dead instruction, delete it.  If that makes any of its operands
+/// trivially dead, delete them too, recursively.  Return true if any
+/// instructions were deleted.
+bool RecursivelyDeleteTriviallyDeadInstructions(Value *V,
+                                        const TargetLibraryInfo *TLI = nullptr);
+
+/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
+/// dead PHI node, due to being a def-use chain of single-use nodes that
+/// either forms a cycle or is terminated by a trivially dead instruction,
+/// delete it.  If that makes any of its operands trivially dead, delete them
+/// too, recursively.  Return true if a change was made.
+bool RecursivelyDeleteDeadPHINode(PHINode *PN,
+                                  const TargetLibraryInfo *TLI = nullptr);
+
+/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
+/// simplify any instructions in it and recursively delete dead instructions.
+///
+/// This returns true if it changed the code, note that it can delete
+/// instructions in other blocks as well in this block.
+bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
+                                 const TargetLibraryInfo *TLI = nullptr);
+
+//===----------------------------------------------------------------------===//
+//  Control Flow Graph Restructuring.
+//
+
+/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this
+/// method is called when we're about to delete Pred as a predecessor of BB.  If
+/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred.
+///
+/// Unlike the removePredecessor method, this attempts to simplify uses of PHI
+/// nodes that collapse into identity values.  For example, if we have:
+///   x = phi(1, 0, 0, 0)
+///   y = and x, z
+///
+/// .. and delete the predecessor corresponding to the '1', this will attempt to
+/// recursively fold the 'and' to 0.
+void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
+                                  DataLayout *TD = nullptr);
+
+/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
+/// predecessor is known to have one successor (BB!).  Eliminate the edge
+/// between them, moving the instructions in the predecessor into BB.  This
+/// deletes the predecessor block.
+///
+void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = nullptr);
+
+/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an
+/// unconditional branch, and contains no instructions other than PHI nodes,
+/// potential debug intrinsics and the branch.  If possible, eliminate BB by
+/// rewriting all the predecessors to branch to the successor block and return
+/// true.  If we can't transform, return false.
+bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
+
+/// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI
+/// nodes in this block. This doesn't try to be clever about PHI nodes
+/// which differ only in the order of the incoming values, but instcombine
+/// orders them so it usually won't matter.
+///
+bool EliminateDuplicatePHINodes(BasicBlock *BB);
+
+/// SimplifyCFG - This function is used to do simplification of a CFG.  For
+/// example, it adjusts branches to branches to eliminate the extra hop, it
+/// eliminates unreachable basic blocks, and does other "peephole" optimization
+/// of the CFG.  It returns true if a modification was made, possibly deleting
+/// the basic block that was pointed to.
+///
+bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
+                 const DataLayout *TD = nullptr);
+
+/// FlatternCFG - This function is used to flatten a CFG.  For
+/// example, it uses parallel-and and parallel-or mode to collapse
+//  if-conditions and merge if-regions with identical statements.
+///
+bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
+
+/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
+/// and if a predecessor branches to us and one of our successors, fold the
+/// setcc into the predecessor and use logical operations to pick the right
+/// destination.
+bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr);
+
+/// DemoteRegToStack - This function takes a virtual register computed by an
+/// Instruction and replaces it with a slot in the stack frame, allocated via
+/// alloca.  This allows the CFG to be changed around without fear of
+/// invalidating the SSA information for the value.  It returns the pointer to
+/// the alloca inserted to create a stack slot for X.
+///
+AllocaInst *DemoteRegToStack(Instruction &X,
+                             bool VolatileLoads = false,
+                             Instruction *AllocaPoint = nullptr);
+
+/// DemotePHIToStack - This function takes a virtual register computed by a phi
+/// node and replaces it with a slot in the stack frame, allocated via alloca.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
+AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
+
+/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
+/// we can determine, return it, otherwise return 0.  If PrefAlign is specified,
+/// and it is more than the alignment of the ultimate object, see if we can
+/// increase the alignment of the ultimate object, making this check succeed.
+unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
+                                    const DataLayout *TD = nullptr);
+
+/// getKnownAlignment - Try to infer an alignment for the specified pointer.
+static inline unsigned getKnownAlignment(Value *V,
+                                         const DataLayout *TD = nullptr) {
+  return getOrEnforceKnownAlignment(V, 0, TD);
+}
+
+/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
+/// code necessary to compute the offset from the base pointer (without adding
+/// in the base pointer).  Return the result as a signed integer of intptr size.
+/// When NoAssumptions is true, no assumptions about index computation not
+/// overflowing is made.
+template<typename IRBuilderTy>
+Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
+                     bool NoAssumptions = false) {
+  GEPOperator *GEPOp = cast<GEPOperator>(GEP);
+  Type *IntPtrTy = TD.getIntPtrType(GEP->getType());
+  Value *Result = Constant::getNullValue(IntPtrTy);
+
+  // If the GEP is inbounds, we know that none of the addressing operations will
+  // overflow in an unsigned sense.
+  bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
+
+  // Build a mask for high order bits.
+  unsigned IntPtrWidth = IntPtrTy->getScalarType()->getIntegerBitWidth();
+  uint64_t PtrSizeMask = ~0ULL >> (64 - IntPtrWidth);
+
+  gep_type_iterator GTI = gep_type_begin(GEP);
+  for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
+       ++i, ++GTI) {
+    Value *Op = *i;
+    uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
+    if (Constant *OpC = dyn_cast<Constant>(Op)) {
+      if (OpC->isZeroValue())
+        continue;
+
+      // Handle a struct index, which adds its field offset to the pointer.
+      if (StructType *STy = dyn_cast<StructType>(*GTI)) {
+        if (OpC->getType()->isVectorTy())
+          OpC = OpC->getSplatValue();
+
+        uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
+        Size = TD.getStructLayout(STy)->getElementOffset(OpValue);
+
+        if (Size)
+          Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
+                                      GEP->getName()+".offs");
+        continue;
+      }
+
+      Constant *Scale = ConstantInt::get(IntPtrTy, Size);
+      Constant *OC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
+      Scale = ConstantExpr::getMul(OC, Scale, isInBounds/*NUW*/);
+      // Emit an add instruction.
+      Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
+      continue;
+    }
+    // Convert to correct type.
+    if (Op->getType() != IntPtrTy)
+      Op = Builder->CreateIntCast(Op, IntPtrTy, true, Op->getName()+".c");
+    if (Size != 1) {
+      // We'll let instcombine(mul) convert this to a shl if possible.
+      Op = Builder->CreateMul(Op, ConstantInt::get(IntPtrTy, Size),
+                              GEP->getName()+".idx", isInBounds /*NUW*/);
+    }
+
+    // Emit an add instruction.
+    Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
+  }
+  return Result;
+}
+
+///===---------------------------------------------------------------------===//
+///  Dbg Intrinsic utilities
+///
+
+/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
+/// that has an associated llvm.dbg.decl intrinsic.
+bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+                                     StoreInst *SI, DIBuilder &Builder);
+
+/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
+/// that has an associated llvm.dbg.decl intrinsic.
+bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+                                     LoadInst *LI, DIBuilder &Builder);
+
+/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set
+/// of llvm.dbg.value intrinsics.
+bool LowerDbgDeclare(Function &F);
+
+/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic corresponding to
+/// an alloca, if any.
+DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
+
+/// replaceDbgDeclareForAlloca - Replaces llvm.dbg.declare instruction when
+/// alloca is replaced with a new value.
+bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
+                                DIBuilder &Builder);
+
+/// \brief Remove all blocks that can not be reached from the function's entry.
+///
+/// Returns true if any basic block was removed.
+bool removeUnreachableBlocks(Function &F);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
new file mode 100644
index 0000000..7e3a74a
--- /dev/null
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -0,0 +1,65 @@
+//===- llvm/Transforms/Utils/LoopUtils.h - Loop utilities -*- 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 some loop transformation utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
+#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
+
+namespace llvm {
+class AliasAnalysis;
+class BasicBlock;
+class DataLayout;
+class DominatorTree;
+class Loop;
+class LoopInfo;
+class Pass;
+class ScalarEvolution;
+
+BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
+
+/// \brief Simplify each loop in a loop nest recursively.
+///
+/// This takes a potentially un-simplified loop L (and its children) and turns
+/// it into a simplified loop nest with preheaders and single backedges. It
+/// will optionally update \c AliasAnalysis and \c ScalarEvolution analyses if
+/// passed into it.
+bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
+                  AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr,
+                  const DataLayout *DL = nullptr);
+
+/// \brief Put loop into LCSSA form.
+///
+/// Looks at all instructions in the loop which have uses outside of the
+/// current loop. For each, an LCSSA PHI node is inserted and the uses outside
+/// the loop are rewritten to use this node.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = nullptr);
+
+/// \brief Put a loop nest into LCSSA form.
+///
+/// This recursively forms LCSSA for a loop nest.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSARecursively(Loop &L, DominatorTree &DT,
+                          ScalarEvolution *SE = nullptr);
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
new file mode 100644
index 0000000..98a19ed
--- /dev/null
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -0,0 +1,41 @@
+//===-- ModuleUtils.h - Functions to manipulate Modules ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform manipulations on Modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
+#define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
+
+namespace llvm {
+
+class Module;
+class Function;
+class GlobalValue;
+class GlobalVariable;
+template <class PtrType, unsigned SmallSize> class SmallPtrSet;
+
+/// Append F to the list of global ctors of module M with the given Priority.
+/// This wraps the function in the appropriate structure and stores it along
+/// side other global constructors. For details see
+/// http://llvm.org/docs/LangRef.html#intg_global_ctors
+void appendToGlobalCtors(Module &M, Function *F, int Priority);
+
+/// Same as appendToGlobalCtors(), but for global dtors.
+void appendToGlobalDtors(Module &M, Function *F, int Priority);
+
+/// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
+/// the initializer elements of that global in Set and return the global itself.
+GlobalVariable *collectUsedGlobalVariables(Module &M,
+                                           SmallPtrSet<GlobalValue *, 8> &Set,
+                                           bool CompilerUsed);
+} // End llvm namespace
+
+#endif //  LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
new file mode 100644
index 0000000..c83fedb
--- /dev/null
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -0,0 +1,48 @@
+//===- PromoteMemToReg.h - Promote Allocas to Scalars -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to promote alloca instructions to SSA
+// registers, by using the SSA construction algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+#define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+
+class AllocaInst;
+class DominatorTree;
+class AliasSetTracker;
+
+/// \brief Return true if this alloca is legal for promotion.
+///
+/// This is true if there are only loads, stores, and lifetime markers
+/// (transitively) using this alloca. This also enforces that there is only
+/// ever one layer of bitcasts or GEPs between the alloca and the lifetime
+/// markers.
+bool isAllocaPromotable(const AllocaInst *AI);
+
+/// \brief Promote the specified list of alloca instructions into scalar
+/// registers, inserting PHI nodes as appropriate.
+///
+/// This function makes use of DominanceFrontier information.  This function
+/// does not modify the CFG of the function at all.  All allocas must be from
+/// the same function.
+///
+/// If AST is specified, the specified tracker is updated to reflect changes
+/// made to the IR.
+void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
+                     AliasSetTracker *AST = nullptr);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h
new file mode 100644
index 0000000..7874a5f
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -0,0 +1,177 @@
+//===-- SSAUpdater.h - Unstructured SSA Update Tool -------------*- 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 SSAUpdater class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
+#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+  class BasicBlock;
+  class Instruction;
+  class LoadInst;
+  template<typename T> class SmallVectorImpl;
+  template<typename T> class SSAUpdaterTraits;
+  class PHINode;
+  class Type;
+  class Use;
+  class Value;
+
+/// \brief Helper class for SSA formation on a set of values defined in
+/// multiple blocks.
+///
+/// This is used when code duplication or another unstructured
+/// transformation wants to rewrite a set of uses of one value with uses of a
+/// set of values.
+class SSAUpdater {
+  friend class SSAUpdaterTraits<SSAUpdater>;
+
+private:
+  /// This keeps track of which value to use on a per-block basis. When we
+  /// insert PHI nodes, we keep track of them here.
+  //typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
+  void *AV;
+
+  /// ProtoType holds the type of the values being rewritten.
+  Type *ProtoType;
+
+  /// PHI nodes are given a name based on ProtoName.
+  std::string ProtoName;
+
+  /// If this is non-null, the SSAUpdater adds all PHI nodes that it creates to
+  /// the vector.
+  SmallVectorImpl<PHINode*> *InsertedPHIs;
+
+public:
+  /// If InsertedPHIs is specified, it will be filled
+  /// in with all PHI Nodes created by rewriting.
+  explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = nullptr);
+  ~SSAUpdater();
+
+  /// \brief Reset this object to get ready for a new set of SSA updates with
+  /// type 'Ty'.
+  ///
+  /// PHI nodes get a name based on 'Name'.
+  void Initialize(Type *Ty, StringRef Name);
+
+  /// \brief Indicate that a rewritten value is available in the specified block
+  /// with the specified value.
+  void AddAvailableValue(BasicBlock *BB, Value *V);
+
+  /// \brief Return true if the SSAUpdater already has a value for the specified
+  /// block.
+  bool HasValueForBlock(BasicBlock *BB) const;
+
+  /// \brief Construct SSA form, materializing a value that is live at the end
+  /// of the specified block.
+  Value *GetValueAtEndOfBlock(BasicBlock *BB);
+
+  /// \brief Construct SSA form, materializing a value that is live in the
+  /// middle of the specified block.
+  ///
+  /// \c GetValueInMiddleOfBlock is the same as \c GetValueAtEndOfBlock except
+  /// in one important case: if there is a definition of the rewritten value
+  /// after the 'use' in BB.  Consider code like this:
+  ///
+  /// \code
+  ///      X1 = ...
+  ///   SomeBB:
+  ///      use(X)
+  ///      X2 = ...
+  ///      br Cond, SomeBB, OutBB
+  /// \endcode
+  ///
+  /// In this case, there are two values (X1 and X2) added to the AvailableVals
+  /// set by the client of the rewriter, and those values are both live out of
+  /// their respective blocks.  However, the use of X happens in the *middle* of
+  /// a block.  Because of this, we need to insert a new PHI node in SomeBB to
+  /// merge the appropriate values, and this value isn't live out of the block.
+  Value *GetValueInMiddleOfBlock(BasicBlock *BB);
+
+  /// \brief Rewrite a use of the symbolic value.
+  ///
+  /// This handles PHI nodes, which use their value in the corresponding
+  /// predecessor. Note that this will not work if the use is supposed to be
+  /// rewritten to a value defined in the same block as the use, but above it.
+  /// Any 'AddAvailableValue's added for the use's block will be considered to
+  /// be below it.
+  void RewriteUse(Use &U);
+
+  /// \brief Rewrite a use like \c RewriteUse but handling in-block definitions.
+  ///
+  /// This version of the method can rewrite uses in the same block as
+  /// a definition, because it assumes that all uses of a value are below any
+  /// inserted values.
+  void RewriteUseAfterInsertions(Use &U);
+
+private:
+  Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
+
+  void operator=(const SSAUpdater&) LLVM_DELETED_FUNCTION;
+  SSAUpdater(const SSAUpdater&) LLVM_DELETED_FUNCTION;
+};
+
+/// \brief Helper class for promoting a collection of loads and stores into SSA
+/// Form using the SSAUpdater.
+///
+/// This handles complexities that SSAUpdater doesn't, such as multiple loads
+/// and stores in one block.
+///
+/// Clients of this class are expected to subclass this and implement the
+/// virtual methods.
+class LoadAndStorePromoter {
+protected:
+  SSAUpdater &SSA;
+
+public:
+  LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts,
+                       SSAUpdater &S, StringRef Name = StringRef());
+  virtual ~LoadAndStorePromoter() {}
+
+  /// \brief This does the promotion.
+  ///
+  /// Insts is a list of loads and stores to promote, and Name is the basename
+  /// for the PHIs to insert. After this is complete, the loads and stores are
+  /// removed from the code.
+  void run(const SmallVectorImpl<Instruction*> &Insts) const;
+
+  /// \brief Return true if the specified instruction is in the Inst list.
+  ///
+  /// The Insts list is the one passed into the constructor. Clients should
+  /// implement this with a more efficient version if possible.
+  virtual bool isInstInList(Instruction *I,
+                            const SmallVectorImpl<Instruction*> &Insts) const;
+
+  /// \brief This hook is invoked after all the stores are found and inserted as
+  /// available values.
+  virtual void doExtraRewritesBeforeFinalDeletion() const {
+  }
+
+  /// \brief Clients can choose to implement this to get notified right before
+  /// a load is RAUW'd another value.
+  virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
+  }
+
+  /// \brief Called before each instruction is deleted.
+  virtual void instructionDeleted(Instruction *I) const {
+  }
+
+  /// \brief Called to update debug info associated with the instruction.
+  virtual void updateDebugInfo(Instruction *I) const {
+  }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
new file mode 100644
index 0000000..ed0841c
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -0,0 +1,460 @@
+//===-- SSAUpdaterImpl.h - SSA Updater Implementation -----------*- 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 a template that implements the core algorithm for the
+// SSAUpdater and MachineSSAUpdater.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm {
+
+#define DEBUG_TYPE "ssaupdater"
+
+class CastInst;
+class PHINode;
+template<typename T> class SSAUpdaterTraits;
+
+template<typename UpdaterT>
+class SSAUpdaterImpl {
+private:
+  UpdaterT *Updater;
+
+  typedef SSAUpdaterTraits<UpdaterT> Traits;
+  typedef typename Traits::BlkT BlkT;
+  typedef typename Traits::ValT ValT;
+  typedef typename Traits::PhiT PhiT;
+
+  /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
+  /// The predecessors of each block are cached here since pred_iterator is
+  /// slow and we need to iterate over the blocks at least a few times.
+  class BBInfo {
+  public:
+    BlkT *BB;          // Back-pointer to the corresponding block.
+    ValT AvailableVal; // Value to use in this block.
+    BBInfo *DefBB;     // Block that defines the available value.
+    int BlkNum;        // Postorder number.
+    BBInfo *IDom;      // Immediate dominator.
+    unsigned NumPreds; // Number of predecessor blocks.
+    BBInfo **Preds;    // Array[NumPreds] of predecessor blocks.
+    PhiT *PHITag;      // Marker for existing PHIs that match.
+
+    BBInfo(BlkT *ThisBB, ValT V)
+      : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr), BlkNum(0),
+        IDom(nullptr), NumPreds(0), Preds(nullptr), PHITag(nullptr) {}
+  };
+
+  typedef DenseMap<BlkT*, ValT> AvailableValsTy;
+  AvailableValsTy *AvailableVals;
+
+  SmallVectorImpl<PhiT*> *InsertedPHIs;
+
+  typedef SmallVectorImpl<BBInfo*> BlockListTy;
+  typedef DenseMap<BlkT*, BBInfo*> BBMapTy;
+  BBMapTy BBMap;
+  BumpPtrAllocator Allocator;
+
+public:
+  explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
+                          SmallVectorImpl<PhiT*> *Ins) :
+    Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
+
+  /// GetValue - Check to see if AvailableVals has an entry for the specified
+  /// BB and if so, return it.  If not, construct SSA form by first
+  /// calculating the required placement of PHIs and then inserting new PHIs
+  /// where needed.
+  ValT GetValue(BlkT *BB) {
+    SmallVector<BBInfo*, 100> BlockList;
+    BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
+
+    // Special case: bail out if BB is unreachable.
+    if (BlockList.size() == 0) {
+      ValT V = Traits::GetUndefVal(BB, Updater);
+      (*AvailableVals)[BB] = V;
+      return V;
+    }
+
+    FindDominators(&BlockList, PseudoEntry);
+    FindPHIPlacement(&BlockList);
+    FindAvailableVals(&BlockList);
+
+    return BBMap[BB]->DefBB->AvailableVal;
+  }
+
+  /// BuildBlockList - Starting from the specified basic block, traverse back
+  /// through its predecessors until reaching blocks with known values.
+  /// Create BBInfo structures for the blocks and append them to the block
+  /// list.
+  BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
+    SmallVector<BBInfo*, 10> RootList;
+    SmallVector<BBInfo*, 64> WorkList;
+
+    BBInfo *Info = new (Allocator) BBInfo(BB, 0);
+    BBMap[BB] = Info;
+    WorkList.push_back(Info);
+
+    // Search backward from BB, creating BBInfos along the way and stopping
+    // when reaching blocks that define the value.  Record those defining
+    // blocks on the RootList.
+    SmallVector<BlkT*, 10> Preds;
+    while (!WorkList.empty()) {
+      Info = WorkList.pop_back_val();
+      Preds.clear();
+      Traits::FindPredecessorBlocks(Info->BB, &Preds);
+      Info->NumPreds = Preds.size();
+      if (Info->NumPreds == 0)
+        Info->Preds = nullptr;
+      else
+        Info->Preds = static_cast<BBInfo**>
+          (Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
+                              AlignOf<BBInfo*>::Alignment));
+
+      for (unsigned p = 0; p != Info->NumPreds; ++p) {
+        BlkT *Pred = Preds[p];
+        // Check if BBMap already has a BBInfo for the predecessor block.
+        typename BBMapTy::value_type &BBMapBucket =
+          BBMap.FindAndConstruct(Pred);
+        if (BBMapBucket.second) {
+          Info->Preds[p] = BBMapBucket.second;
+          continue;
+        }
+
+        // Create a new BBInfo for the predecessor.
+        ValT PredVal = AvailableVals->lookup(Pred);
+        BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
+        BBMapBucket.second = PredInfo;
+        Info->Preds[p] = PredInfo;
+
+        if (PredInfo->AvailableVal) {
+          RootList.push_back(PredInfo);
+          continue;
+        }
+        WorkList.push_back(PredInfo);
+      }
+    }
+
+    // Now that we know what blocks are backwards-reachable from the starting
+    // block, do a forward depth-first traversal to assign postorder numbers
+    // to those blocks.
+    BBInfo *PseudoEntry = new (Allocator) BBInfo(nullptr, 0);
+    unsigned BlkNum = 1;
+
+    // Initialize the worklist with the roots from the backward traversal.
+    while (!RootList.empty()) {
+      Info = RootList.pop_back_val();
+      Info->IDom = PseudoEntry;
+      Info->BlkNum = -1;
+      WorkList.push_back(Info);
+    }
+
+    while (!WorkList.empty()) {
+      Info = WorkList.back();
+
+      if (Info->BlkNum == -2) {
+        // All the successors have been handled; assign the postorder number.
+        Info->BlkNum = BlkNum++;
+        // If not a root, put it on the BlockList.
+        if (!Info->AvailableVal)
+          BlockList->push_back(Info);
+        WorkList.pop_back();
+        continue;
+      }
+
+      // Leave this entry on the worklist, but set its BlkNum to mark that its
+      // successors have been put on the worklist.  When it returns to the top
+      // the list, after handling its successors, it will be assigned a
+      // number.
+      Info->BlkNum = -2;
+
+      // Add unvisited successors to the work list.
+      for (typename Traits::BlkSucc_iterator SI =
+             Traits::BlkSucc_begin(Info->BB),
+             E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
+        BBInfo *SuccInfo = BBMap[*SI];
+        if (!SuccInfo || SuccInfo->BlkNum)
+          continue;
+        SuccInfo->BlkNum = -1;
+        WorkList.push_back(SuccInfo);
+      }
+    }
+    PseudoEntry->BlkNum = BlkNum;
+    return PseudoEntry;
+  }
+
+  /// IntersectDominators - This is the dataflow lattice "meet" operation for
+  /// finding dominators.  Given two basic blocks, it walks up the dominator
+  /// tree until it finds a common dominator of both.  It uses the postorder
+  /// number of the blocks to determine how to do that.
+  BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
+    while (Blk1 != Blk2) {
+      while (Blk1->BlkNum < Blk2->BlkNum) {
+        Blk1 = Blk1->IDom;
+        if (!Blk1)
+          return Blk2;
+      }
+      while (Blk2->BlkNum < Blk1->BlkNum) {
+        Blk2 = Blk2->IDom;
+        if (!Blk2)
+          return Blk1;
+      }
+    }
+    return Blk1;
+  }
+
+  /// FindDominators - Calculate the dominator tree for the subset of the CFG
+  /// corresponding to the basic blocks on the BlockList.  This uses the
+  /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
+  /// and Kennedy, published in Software--Practice and Experience, 2001,
+  /// 4:1-10.  Because the CFG subset does not include any edges leading into
+  /// blocks that define the value, the results are not the usual dominator
+  /// tree.  The CFG subset has a single pseudo-entry node with edges to a set
+  /// of root nodes for blocks that define the value.  The dominators for this
+  /// subset CFG are not the standard dominators but they are adequate for
+  /// placing PHIs within the subset CFG.
+  void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
+    bool Changed;
+    do {
+      Changed = false;
+      // Iterate over the list in reverse order, i.e., forward on CFG edges.
+      for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+             E = BlockList->rend(); I != E; ++I) {
+        BBInfo *Info = *I;
+        BBInfo *NewIDom = nullptr;
+
+        // Iterate through the block's predecessors.
+        for (unsigned p = 0; p != Info->NumPreds; ++p) {
+          BBInfo *Pred = Info->Preds[p];
+
+          // Treat an unreachable predecessor as a definition with 'undef'.
+          if (Pred->BlkNum == 0) {
+            Pred->AvailableVal = Traits::GetUndefVal(Pred->BB, Updater);
+            (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
+            Pred->DefBB = Pred;
+            Pred->BlkNum = PseudoEntry->BlkNum;
+            PseudoEntry->BlkNum++;
+          }
+
+          if (!NewIDom)
+            NewIDom = Pred;
+          else
+            NewIDom = IntersectDominators(NewIDom, Pred);
+        }
+
+        // Check if the IDom value has changed.
+        if (NewIDom && NewIDom != Info->IDom) {
+          Info->IDom = NewIDom;
+          Changed = true;
+        }
+      }
+    } while (Changed);
+  }
+
+  /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
+  /// any blocks containing definitions of the value.  If one is found, then
+  /// the successor of Pred is in the dominance frontier for the definition,
+  /// and this function returns true.
+  bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
+    for (; Pred != IDom; Pred = Pred->IDom) {
+      if (Pred->DefBB == Pred)
+        return true;
+    }
+    return false;
+  }
+
+  /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
+  /// of the known definitions.  Iteratively add PHIs in the dom frontiers
+  /// until nothing changes.  Along the way, keep track of the nearest
+  /// dominating definitions for non-PHI blocks.
+  void FindPHIPlacement(BlockListTy *BlockList) {
+    bool Changed;
+    do {
+      Changed = false;
+      // Iterate over the list in reverse order, i.e., forward on CFG edges.
+      for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+             E = BlockList->rend(); I != E; ++I) {
+        BBInfo *Info = *I;
+
+        // If this block already needs a PHI, there is nothing to do here.
+        if (Info->DefBB == Info)
+          continue;
+
+        // Default to use the same def as the immediate dominator.
+        BBInfo *NewDefBB = Info->IDom->DefBB;
+        for (unsigned p = 0; p != Info->NumPreds; ++p) {
+          if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
+            // Need a PHI here.
+            NewDefBB = Info;
+            break;
+          }
+        }
+
+        // Check if anything changed.
+        if (NewDefBB != Info->DefBB) {
+          Info->DefBB = NewDefBB;
+          Changed = true;
+        }
+      }
+    } while (Changed);
+  }
+
+  /// FindAvailableVal - If this block requires a PHI, first check if an
+  /// existing PHI matches the PHI placement and reaching definitions computed
+  /// earlier, and if not, create a new PHI.  Visit all the block's
+  /// predecessors to calculate the available value for each one and fill in
+  /// the incoming values for a new PHI.
+  void FindAvailableVals(BlockListTy *BlockList) {
+    // Go through the worklist in forward order (i.e., backward through the CFG)
+    // and check if existing PHIs can be used.  If not, create empty PHIs where
+    // they are needed.
+    for (typename BlockListTy::iterator I = BlockList->begin(),
+           E = BlockList->end(); I != E; ++I) {
+      BBInfo *Info = *I;
+      // Check if there needs to be a PHI in BB.
+      if (Info->DefBB != Info)
+        continue;
+
+      // Look for an existing PHI.
+      FindExistingPHI(Info->BB, BlockList);
+      if (Info->AvailableVal)
+        continue;
+
+      ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
+      Info->AvailableVal = PHI;
+      (*AvailableVals)[Info->BB] = PHI;
+    }
+
+    // Now go back through the worklist in reverse order to fill in the
+    // arguments for any new PHIs added in the forward traversal.
+    for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+           E = BlockList->rend(); I != E; ++I) {
+      BBInfo *Info = *I;
+
+      if (Info->DefBB != Info) {
+        // Record the available value at join nodes to speed up subsequent
+        // uses of this SSAUpdater for the same value.
+        if (Info->NumPreds > 1)
+          (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
+        continue;
+      }
+
+      // Check if this block contains a newly added PHI.
+      PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
+      if (!PHI)
+        continue;
+
+      // Iterate through the block's predecessors.
+      for (unsigned p = 0; p != Info->NumPreds; ++p) {
+        BBInfo *PredInfo = Info->Preds[p];
+        BlkT *Pred = PredInfo->BB;
+        // Skip to the nearest preceding definition.
+        if (PredInfo->DefBB != PredInfo)
+          PredInfo = PredInfo->DefBB;
+        Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
+      }
+
+      DEBUG(dbgs() << "  Inserted PHI: " << *PHI << "\n");
+
+      // If the client wants to know about all new instructions, tell it.
+      if (InsertedPHIs) InsertedPHIs->push_back(PHI);
+    }
+  }
+
+  /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
+  /// them match what is needed.
+  void FindExistingPHI(BlkT *BB, BlockListTy *BlockList) {
+    for (typename BlkT::iterator BBI = BB->begin(), BBE = BB->end();
+         BBI != BBE; ++BBI) {
+      PhiT *SomePHI = Traits::InstrIsPHI(BBI);
+      if (!SomePHI)
+        break;
+      if (CheckIfPHIMatches(SomePHI)) {
+        RecordMatchingPHIs(BlockList);
+        break;
+      }
+      // Match failed: clear all the PHITag values.
+      for (typename BlockListTy::iterator I = BlockList->begin(),
+             E = BlockList->end(); I != E; ++I)
+        (*I)->PHITag = nullptr;
+    }
+  }
+
+  /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
+  /// in the BBMap.
+  bool CheckIfPHIMatches(PhiT *PHI) {
+    SmallVector<PhiT*, 20> WorkList;
+    WorkList.push_back(PHI);
+
+    // Mark that the block containing this PHI has been visited.
+    BBMap[PHI->getParent()]->PHITag = PHI;
+
+    while (!WorkList.empty()) {
+      PHI = WorkList.pop_back_val();
+
+      // Iterate through the PHI's incoming values.
+      for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
+             E = Traits::PHI_end(PHI); I != E; ++I) {
+        ValT IncomingVal = I.getIncomingValue();
+        BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
+        // Skip to the nearest preceding definition.
+        if (PredInfo->DefBB != PredInfo)
+          PredInfo = PredInfo->DefBB;
+
+        // Check if it matches the expected value.
+        if (PredInfo->AvailableVal) {
+          if (IncomingVal == PredInfo->AvailableVal)
+            continue;
+          return false;
+        }
+
+        // Check if the value is a PHI in the correct block.
+        PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
+        if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
+          return false;
+
+        // If this block has already been visited, check if this PHI matches.
+        if (PredInfo->PHITag) {
+          if (IncomingPHIVal == PredInfo->PHITag)
+            continue;
+          return false;
+        }
+        PredInfo->PHITag = IncomingPHIVal;
+
+        WorkList.push_back(IncomingPHIVal);
+      }
+    }
+    return true;
+  }
+
+  /// RecordMatchingPHIs - For each PHI node that matches, record it in both
+  /// the BBMap and the AvailableVals mapping.
+  void RecordMatchingPHIs(BlockListTy *BlockList) {
+    for (typename BlockListTy::iterator I = BlockList->begin(),
+           E = BlockList->end(); I != E; ++I)
+      if (PhiT *PHI = (*I)->PHITag) {
+        BlkT *BB = PHI->getParent();
+        ValT PHIVal = Traits::GetPHIValue(PHI);
+        (*AvailableVals)[BB] = PHIVal;
+        BBMap[BB]->AvailableVal = PHIVal;
+      }
+  }
+};
+
+#undef DEBUG_TYPE // "ssaupdater"
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h
new file mode 100644
index 0000000..dcb1d67
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -0,0 +1,70 @@
+//===-- llvm/Transforms/Utils/SimplifyIndVar.h - Indvar Utils ---*- 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 in interface for induction variable simplification. It does
+// not define any actual pass or policy, but provides a single function to
+// simplify a loop's induction variables based on ScalarEvolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+class CastInst;
+class DominatorTree;
+class IVUsers;
+class Loop;
+class LPPassManager;
+class PHINode;
+class ScalarEvolution;
+
+/// Interface for visiting interesting IV users that are recognized but not
+/// simplified by this utility.
+class IVVisitor {
+protected:
+  const DominatorTree *DT;
+  bool ShouldSplitOverflowIntrinsics;
+
+  virtual void anchor();
+
+public:
+  IVVisitor(): DT(nullptr), ShouldSplitOverflowIntrinsics(false) {}
+  virtual ~IVVisitor() {}
+
+  const DominatorTree *getDomTree() const { return DT; }
+
+  bool shouldSplitOverflowInstrinsics() const {
+    return ShouldSplitOverflowIntrinsics;
+  }
+  void setSplitOverflowIntrinsics() {
+    ShouldSplitOverflowIntrinsics = true;
+    assert(DT && "Splitting overflow intrinsics requires a DomTree.");
+  }
+
+  virtual void visitCast(CastInst *Cast) = 0;
+};
+
+/// simplifyUsersOfIV - Simplify instructions that use this induction variable
+/// by using ScalarEvolution to analyze the IV's recurrence.
+bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM,
+                       SmallVectorImpl<WeakVH> &Dead, IVVisitor *V = nullptr);
+
+/// SimplifyLoopIVs - Simplify users of induction variables within this
+/// loop. This does not actually change or add IVs.
+bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, LPPassManager *LPM,
+                     SmallVectorImpl<WeakVH> &Dead);
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
new file mode 100644
index 0000000..a2a5f9a
--- /dev/null
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -0,0 +1,54 @@
+//===- SimplifyLibCalls.h - Library call simplifier -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to build some C language libcalls for
+// optimization passes that need to call the various functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+
+namespace llvm {
+  class Value;
+  class CallInst;
+  class DataLayout;
+  class Instruction;
+  class TargetLibraryInfo;
+  class LibCallSimplifierImpl;
+
+  /// LibCallSimplifier - This class implements a collection of optimizations
+  /// that replace well formed calls to library functions with a more optimal
+  /// form.  For example, replacing 'printf("Hello!")' with 'puts("Hello!")'.
+  class LibCallSimplifier {
+    /// Impl - A pointer to the actual implementation of the library call
+    /// simplifier.
+    LibCallSimplifierImpl *Impl;
+
+  public:
+    LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
+                      bool UnsafeFPShrink);
+    virtual ~LibCallSimplifier();
+
+    /// optimizeCall - Take the given call instruction and return a more
+    /// optimal value to replace the instruction with or 0 if a more
+    /// optimal form can't be found.  Note that the returned value may
+    /// be equal to the instruction being optimized.  In this case all
+    /// other instructions that use the given instruction were modified
+    /// and the given instruction is dead.
+    Value *optimizeCall(CallInst *CI);
+
+    /// replaceAllUsesWith - This method is used when the library call
+    /// simplifier needs to replace instructions other than the library
+    /// call being modified.
+    virtual void replaceAllUsesWith(Instruction *I, Value *With) const;
+  };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
new file mode 100644
index 0000000..7ac2572
--- /dev/null
+++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -0,0 +1,52 @@
+//===-- UnifyFunctionExitNodes.h - Ensure fn's have one return --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to ensure that functions have at most one return and one
+// unwind instruction in them.  Additionally, it keeps track of which node is
+// the new exit node of the CFG.  If there are no return or unwind instructions
+// in the function, the getReturnBlock/getUnwindBlock methods will return a null
+// pointer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+#define LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+struct UnifyFunctionExitNodes : public FunctionPass {
+  BasicBlock *ReturnBlock, *UnwindBlock, *UnreachableBlock;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+  UnifyFunctionExitNodes() : FunctionPass(ID),
+                             ReturnBlock(nullptr), UnwindBlock(nullptr) {
+    initializeUnifyFunctionExitNodesPass(*PassRegistry::getPassRegistry());
+  }
+
+  // We can preserve non-critical-edgeness when we unify function exit nodes
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  // getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistent)
+  // return, unwind, or unreachable  basic blocks in the CFG.
+  //
+  BasicBlock *getReturnBlock() const { return ReturnBlock; }
+  BasicBlock *getUnwindBlock() const { return UnwindBlock; }
+  BasicBlock *getUnreachableBlock() const { return UnreachableBlock; }
+
+  bool runOnFunction(Function &F) override;
+};
+
+Pass *createUnifyFunctionExitNodesPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
new file mode 100644
index 0000000..aaadd7d
--- /dev/null
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -0,0 +1,34 @@
+//===- llvm/Transforms/Utils/UnrollLoop.h - Unrolling utilities -*- 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 some loop unrolling utilities. It does not define any
+// actual pass or policy, but provides a single function to perform loop
+// unrolling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
+#define LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
+
+namespace llvm {
+
+class Loop;
+class LoopInfo;
+class LPPassManager;
+class Pass;
+
+bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
+                unsigned TripMultiple, LoopInfo *LI, Pass *PP,
+                LPPassManager *LPM);
+
+bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
+                             LPPassManager* LPM);
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
new file mode 100644
index 0000000..5774763
--- /dev/null
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -0,0 +1,98 @@
+//===- ValueMapper.h - Remapping for constants and metadata -----*- 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 MapValue interface which is used by various parts of
+// the Transforms/Utils library to implement cloning and linking facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
+#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
+
+#include "llvm/IR/ValueMap.h"
+
+namespace llvm {
+  class Value;
+  class Instruction;
+  typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
+
+  /// ValueMapTypeRemapper - This is a class that can be implemented by clients
+  /// to remap types when cloning constants and instructions.
+  class ValueMapTypeRemapper {
+    virtual void anchor();  // Out of line method.
+  public:
+    virtual ~ValueMapTypeRemapper() {}
+
+    /// remapType - The client should implement this method if they want to
+    /// remap types while mapping values.
+    virtual Type *remapType(Type *SrcTy) = 0;
+  };
+
+  /// ValueMaterializer - This is a class that can be implemented by clients
+  /// to materialize Values on demand.
+  class ValueMaterializer {
+    virtual void anchor(); // Out of line method.
+  public:
+    virtual ~ValueMaterializer() {}
+
+    /// materializeValueFor - The client should implement this method if they
+    /// want to generate a mapped Value on demand. For example, if linking
+    /// lazily.
+    virtual Value *materializeValueFor(Value *V) = 0;
+  };
+
+  /// RemapFlags - These are flags that the value mapping APIs allow.
+  enum RemapFlags {
+    RF_None = 0,
+
+    /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that
+    /// only local values within a function (such as an instruction or argument)
+    /// are mapped, not global values like functions and global metadata.
+    RF_NoModuleLevelChanges = 1,
+
+    /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores
+    /// entries that are not in the value map.  If it is unset, it aborts if an
+    /// operand is asked to be remapped which doesn't exist in the mapping.
+    RF_IgnoreMissingEntries = 2
+  };
+
+  static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
+    return RemapFlags(unsigned(LHS)|unsigned(RHS));
+  }
+
+  Value *MapValue(const Value *V, ValueToValueMapTy &VM,
+                  RemapFlags Flags = RF_None,
+                  ValueMapTypeRemapper *TypeMapper = nullptr,
+                  ValueMaterializer *Materializer = nullptr);
+
+  void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
+                        RemapFlags Flags = RF_None,
+                        ValueMapTypeRemapper *TypeMapper = nullptr,
+                        ValueMaterializer *Materializer = nullptr);
+
+  /// MapValue - provide versions that preserve type safety for MDNode and
+  /// Constants.
+  inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM,
+                          RemapFlags Flags = RF_None,
+                          ValueMapTypeRemapper *TypeMapper = nullptr,
+                          ValueMaterializer *Materializer = nullptr) {
+    return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper,
+                                 Materializer));
+  }
+  inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
+                            RemapFlags Flags = RF_None,
+                            ValueMapTypeRemapper *TypeMapper = nullptr,
+                            ValueMaterializer *Materializer = nullptr) {
+    return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper,
+                                   Materializer));
+  }
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/VectorUtils.h b/include/llvm/Transforms/Utils/VectorUtils.h
new file mode 100644
index 0000000..44a7149
--- /dev/null
+++ b/include/llvm/Transforms/Utils/VectorUtils.h
@@ -0,0 +1,195 @@
+//===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- 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 some vectorizer utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
+#define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+
+namespace llvm {
+
+/// \brief Identify if the intrinsic is trivially vectorizable.
+///
+/// This method returns true if the intrinsic's argument types are all
+/// scalars for the scalar form of the intrinsic and all vectors for
+/// the vector form of the intrinsic.
+static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
+  switch (ID) {
+  case Intrinsic::sqrt:
+  case Intrinsic::sin:
+  case Intrinsic::cos:
+  case Intrinsic::exp:
+  case Intrinsic::exp2:
+  case Intrinsic::log:
+  case Intrinsic::log10:
+  case Intrinsic::log2:
+  case Intrinsic::fabs:
+  case Intrinsic::copysign:
+  case Intrinsic::floor:
+  case Intrinsic::ceil:
+  case Intrinsic::trunc:
+  case Intrinsic::rint:
+  case Intrinsic::nearbyint:
+  case Intrinsic::round:
+  case Intrinsic::bswap:
+  case Intrinsic::ctpop:
+  case Intrinsic::pow:
+  case Intrinsic::fma:
+  case Intrinsic::fmuladd:
+  case Intrinsic::ctlz:
+  case Intrinsic::cttz:
+  case Intrinsic::powi:
+    return true;
+  default:
+    return false;
+  }
+}
+
+static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
+                                         unsigned ScalarOpdIdx) {
+  switch (ID) {
+    case Intrinsic::ctlz:
+    case Intrinsic::cttz:
+    case Intrinsic::powi:
+      return (ScalarOpdIdx == 1);
+    default:
+      return false;
+  }
+}
+
+static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
+                                              Intrinsic::ID ValidIntrinsicID) {
+  if (I.getNumArgOperands() != 1 ||
+      !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
+      I.getType() != I.getArgOperand(0)->getType() ||
+      !I.onlyReadsMemory())
+    return Intrinsic::not_intrinsic;
+
+  return ValidIntrinsicID;
+}
+
+static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
+                                               Intrinsic::ID ValidIntrinsicID) {
+  if (I.getNumArgOperands() != 2 ||
+      !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
+      !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
+      I.getType() != I.getArgOperand(0)->getType() ||
+      I.getType() != I.getArgOperand(1)->getType() ||
+      !I.onlyReadsMemory())
+    return Intrinsic::not_intrinsic;
+
+  return ValidIntrinsicID;
+}
+
+static Intrinsic::ID
+getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
+  // If we have an intrinsic call, check if it is trivially vectorizable.
+  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
+    Intrinsic::ID ID = II->getIntrinsicID();
+    if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
+        ID == Intrinsic::lifetime_end)
+      return ID;
+    else
+      return Intrinsic::not_intrinsic;
+  }
+
+  if (!TLI)
+    return Intrinsic::not_intrinsic;
+
+  LibFunc::Func Func;
+  Function *F = CI->getCalledFunction();
+  // We're going to make assumptions on the semantics of the functions, check
+  // that the target knows that it's available in this environment and it does
+  // not have local linkage.
+  if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
+    return Intrinsic::not_intrinsic;
+
+  // Otherwise check if we have a call to a function that can be turned into a
+  // vector intrinsic.
+  switch (Func) {
+  default:
+    break;
+  case LibFunc::sin:
+  case LibFunc::sinf:
+  case LibFunc::sinl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::sin);
+  case LibFunc::cos:
+  case LibFunc::cosf:
+  case LibFunc::cosl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::cos);
+  case LibFunc::exp:
+  case LibFunc::expf:
+  case LibFunc::expl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::exp);
+  case LibFunc::exp2:
+  case LibFunc::exp2f:
+  case LibFunc::exp2l:
+    return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
+  case LibFunc::log:
+  case LibFunc::logf:
+  case LibFunc::logl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::log);
+  case LibFunc::log10:
+  case LibFunc::log10f:
+  case LibFunc::log10l:
+    return checkUnaryFloatSignature(*CI, Intrinsic::log10);
+  case LibFunc::log2:
+  case LibFunc::log2f:
+  case LibFunc::log2l:
+    return checkUnaryFloatSignature(*CI, Intrinsic::log2);
+  case LibFunc::fabs:
+  case LibFunc::fabsf:
+  case LibFunc::fabsl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
+  case LibFunc::copysign:
+  case LibFunc::copysignf:
+  case LibFunc::copysignl:
+    return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
+  case LibFunc::floor:
+  case LibFunc::floorf:
+  case LibFunc::floorl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::floor);
+  case LibFunc::ceil:
+  case LibFunc::ceilf:
+  case LibFunc::ceill:
+    return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
+  case LibFunc::trunc:
+  case LibFunc::truncf:
+  case LibFunc::truncl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
+  case LibFunc::rint:
+  case LibFunc::rintf:
+  case LibFunc::rintl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::rint);
+  case LibFunc::nearbyint:
+  case LibFunc::nearbyintf:
+  case LibFunc::nearbyintl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
+  case LibFunc::round:
+  case LibFunc::roundf:
+  case LibFunc::roundl:
+    return checkUnaryFloatSignature(*CI, Intrinsic::round);
+  case LibFunc::pow:
+  case LibFunc::powf:
+  case LibFunc::powl:
+    return checkBinaryFloatSignature(*CI, Intrinsic::pow);
+  }
+
+  return Intrinsic::not_intrinsic;
+}
+
+} // llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
new file mode 100644
index 0000000..aec3993
--- /dev/null
+++ b/include/llvm/Transforms/Vectorize.h
@@ -0,0 +1,144 @@
+//===-- Vectorize.h - Vectorization Transformations -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the Vectorize transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_H
+#define LLVM_TRANSFORMS_VECTORIZE_H
+
+namespace llvm {
+class BasicBlock;
+class BasicBlockPass;
+class Pass;
+
+//===----------------------------------------------------------------------===//
+/// @brief Vectorize configuration.
+struct VectorizeConfig {
+  //===--------------------------------------------------------------------===//
+  // Target architecture related parameters
+
+  /// @brief The size of the native vector registers.
+  unsigned VectorBits;
+
+  /// @brief Vectorize boolean values.
+  bool VectorizeBools;
+
+  /// @brief Vectorize integer values.
+  bool VectorizeInts;
+
+  /// @brief Vectorize floating-point values.
+  bool VectorizeFloats;
+
+  /// @brief Vectorize pointer values.
+  bool VectorizePointers;
+
+  /// @brief Vectorize casting (conversion) operations.
+  bool VectorizeCasts;
+
+  /// @brief Vectorize floating-point math intrinsics.
+  bool VectorizeMath;
+
+  /// @brief Vectorize bit intrinsics.
+  bool VectorizeBitManipulations;
+
+  /// @brief Vectorize the fused-multiply-add intrinsic.
+  bool VectorizeFMA;
+
+  /// @brief Vectorize select instructions.
+  bool VectorizeSelect;
+
+  /// @brief Vectorize comparison instructions.
+  bool VectorizeCmp;
+
+  /// @brief Vectorize getelementptr instructions.
+  bool VectorizeGEP;
+
+  /// @brief Vectorize loads and stores.
+  bool VectorizeMemOps;
+
+  /// @brief Only generate aligned loads and stores.
+  bool AlignedOnly;
+
+  //===--------------------------------------------------------------------===//
+  // Misc parameters
+
+  /// @brief The required chain depth for vectorization.
+  unsigned ReqChainDepth;
+
+  /// @brief The maximum search distance for instruction pairs.
+  unsigned SearchLimit;
+
+  /// @brief The maximum number of candidate pairs with which to use a full
+  ///        cycle check.
+  unsigned MaxCandPairsForCycleCheck;
+
+  /// @brief Replicating one element to a pair breaks the chain.
+  bool SplatBreaksChain;
+
+  /// @brief The maximum number of pairable instructions per group.
+  unsigned MaxInsts;
+
+  /// @brief The maximum number of candidate instruction pairs per group.
+  unsigned MaxPairs;
+
+  /// @brief The maximum number of pairing iterations.
+  unsigned MaxIter;
+
+  /// @brief Don't try to form odd-length vectors.
+  bool Pow2LenOnly;
+
+  /// @brief Don't boost the chain-depth contribution of loads and stores.
+  bool NoMemOpBoost;
+
+  /// @brief Use a fast instruction dependency analysis.
+  bool FastDep;
+
+  /// @brief Initialize the VectorizeConfig from command line options.
+  VectorizeConfig();
+};
+
+//===----------------------------------------------------------------------===//
+//
+// BBVectorize - A basic-block vectorization pass.
+//
+BasicBlockPass *
+createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
+
+//===----------------------------------------------------------------------===//
+//
+// LoopVectorize - Create a loop vectorization pass.
+//
+Pass *createLoopVectorizePass(bool NoUnrolling = false,
+                              bool AlwaysVectorize = true);
+
+//===----------------------------------------------------------------------===//
+//
+// SLPVectorizer - Create a bottom-up SLP vectorizer pass.
+//
+Pass *createSLPVectorizerPass();
+
+//===----------------------------------------------------------------------===//
+/// @brief Vectorize the BasicBlock.
+///
+/// @param BB The BasicBlock to be vectorized
+/// @param P  The current running pass, should require AliasAnalysis and
+///           ScalarEvolution. After the vectorization, AliasAnalysis,
+///           ScalarEvolution and CFG are preserved.
+///
+/// @return True if the BB is changed, false otherwise.
+///
+bool vectorizeBasicBlock(Pass *P, BasicBlock &BB,
+                         const VectorizeConfig &C = VectorizeConfig());
+
+} // End llvm namespace
+
+#endif
diff --git a/include/unwind.h b/include/unwind.h
new file mode 100644
index 0000000..dd82bc9
--- /dev/null
+++ b/include/unwind.h
@@ -0,0 +1,357 @@
+//===------------------------------- unwind.h -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//
+// C++ ABI Level 1 ABI documented at:
+//   http://mentorembedded.github.io/cxx-abi/abi-eh.html
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __UNWIND_H__
+#define __UNWIND_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#if defined(__APPLE__)
+#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable ))
+#else
+#define LIBUNWIND_UNAVAIL
+#endif
+
+// FIXME: This is also in cxxabi.h and libunwind.h, can we consolidate?
+#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \
+    !defined(__ARM_DWARF_EH__) && !defined(__APPLE__)
+#define LIBCXXABI_ARM_EHABI 1
+#else
+#define LIBCXXABI_ARM_EHABI 0
+#endif
+
+typedef enum {
+  _URC_NO_REASON = 0,
+  _URC_OK = 0,
+  _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+  _URC_FATAL_PHASE2_ERROR = 2,
+  _URC_FATAL_PHASE1_ERROR = 3,
+  _URC_NORMAL_STOP = 4,
+  _URC_END_OF_STACK = 5,
+  _URC_HANDLER_FOUND = 6,
+  _URC_INSTALL_CONTEXT = 7,
+  _URC_CONTINUE_UNWIND = 8,
+#if LIBCXXABI_ARM_EHABI
+  _URC_FAILURE = 9
+#endif
+} _Unwind_Reason_Code;
+
+typedef enum {
+  _UA_SEARCH_PHASE = 1,
+  _UA_CLEANUP_PHASE = 2,
+  _UA_HANDLER_FRAME = 4,
+  _UA_FORCE_UNWIND = 8,
+  _UA_END_OF_STACK = 16 // gcc extension to C++ ABI
+} _Unwind_Action;
+
+typedef struct _Unwind_Context _Unwind_Context;   // opaque
+
+#if LIBCXXABI_ARM_EHABI
+typedef uint32_t _Unwind_State;
+
+static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME   = 0;
+static const _Unwind_State _US_UNWIND_FRAME_STARTING  = 1;
+static const _Unwind_State _US_UNWIND_FRAME_RESUME    = 2;
+
+typedef uint32_t _Unwind_EHT_Header;
+
+struct _Unwind_Control_Block;
+typedef struct _Unwind_Control_Block _Unwind_Control_Block;
+typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
+
+struct _Unwind_Control_Block {
+  uint64_t exception_class;
+  void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*);
+
+  /* Unwinder cache, private fields for the unwinder's use */
+  struct {
+    uint32_t reserved1; /* init reserved1 to 0, then don't touch */
+    uint32_t reserved2;
+    uint32_t reserved3;
+    uint32_t reserved4;
+    uint32_t reserved5;
+  } unwinder_cache;
+
+  /* Propagation barrier cache (valid after phase 1): */
+  struct {
+    uint32_t sp;
+    uint32_t bitpattern[5];
+  } barrier_cache;
+
+  /* Cleanup cache (preserved over cleanup): */
+  struct {
+    uint32_t bitpattern[4];
+  } cleanup_cache;
+
+  /* Pr cache (for pr's benefit): */
+  struct {
+    uint32_t fnstart; /* function start address */
+    _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */
+    uint32_t additional;
+    uint32_t reserved1;
+  } pr_cache;
+
+  long long int :0; /* Enforce the 8-byte alignment */
+};
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+      (_Unwind_State state,
+       _Unwind_Exception* exceptionObject,
+       struct _Unwind_Context* context);
+
+typedef _Unwind_Reason_Code (*__personality_routine)
+      (_Unwind_State state,
+       _Unwind_Exception* exceptionObject,
+       struct _Unwind_Context* context);
+#else
+struct _Unwind_Context;   // opaque
+struct _Unwind_Exception; // forward declaration
+typedef struct _Unwind_Exception _Unwind_Exception;
+
+struct _Unwind_Exception {
+  uint64_t exception_class;
+  void (*exception_cleanup)(_Unwind_Reason_Code reason,
+                            _Unwind_Exception *exc);
+  uintptr_t private_1; // non-zero means forced unwind
+  uintptr_t private_2; // holds sp that phase1 found for phase2 to use
+#if !__LP64__
+  // The gcc implementation of _Unwind_Exception used attribute mode on the
+  // above fields which had the side effect of causing this whole struct to 
+  // round up to 32 bytes in size. To be more explicit, we add pad fields 
+  // added for binary compatibility.
+  uint32_t reserved[3];
+#endif
+};
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
+    (int version,
+     _Unwind_Action actions,
+     uint64_t exceptionClass,
+     _Unwind_Exception* exceptionObject,
+     struct _Unwind_Context* context,
+     void* stop_parameter );
+
+typedef _Unwind_Reason_Code (*__personality_routine)
+      (int version,
+       _Unwind_Action actions,
+       uint64_t exceptionClass,
+       _Unwind_Exception* exceptionObject,
+       struct _Unwind_Context* context);
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// The following are the base functions documented by the C++ ABI
+//
+#if __USING_SJLJ_EXCEPTIONS__
+extern _Unwind_Reason_Code
+    _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object);
+extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object);
+#else
+extern _Unwind_Reason_Code
+    _Unwind_RaiseException(_Unwind_Exception *exception_object);
+extern void _Unwind_Resume(_Unwind_Exception *exception_object);
+#endif
+extern void _Unwind_DeleteException(_Unwind_Exception *exception_object);
+
+#if LIBCXXABI_ARM_EHABI
+typedef enum {
+  _UVRSC_CORE = 0, /* integer register */
+  _UVRSC_VFP = 1, /* vfp */
+  _UVRSC_WMMXD = 3, /* Intel WMMX data register */
+  _UVRSC_WMMXC = 4 /* Intel WMMX control register */
+} _Unwind_VRS_RegClass;
+
+typedef enum {
+  _UVRSD_UINT32 = 0,
+  _UVRSD_VFPX = 1,
+  _UVRSD_UINT64 = 3,
+  _UVRSD_FLOAT = 4,
+  _UVRSD_DOUBLE = 5
+} _Unwind_VRS_DataRepresentation;
+
+typedef enum {
+  _UVRSR_OK = 0,
+  _UVRSR_NOT_IMPLEMENTED = 1,
+  _UVRSR_FAILED = 2
+} _Unwind_VRS_Result;
+
+extern void _Unwind_Complete(_Unwind_Exception* exception_object);
+
+extern _Unwind_VRS_Result
+_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+                uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+                void *valuep);
+
+extern _Unwind_VRS_Result
+_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+                uint32_t regno, _Unwind_VRS_DataRepresentation representation,
+                void *valuep);
+
+extern _Unwind_VRS_Result
+_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
+                uint32_t discriminator,
+                _Unwind_VRS_DataRepresentation representation);
+
+static inline uintptr_t _Unwind_GetGR(struct _Unwind_Context* context,
+                                      int index) {
+  uintptr_t value = 0;
+  _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
+  return value;
+}
+
+static inline void _Unwind_SetGR(struct _Unwind_Context* context, int index,
+                                 uintptr_t new_value) {
+  _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index,
+                  _UVRSD_UINT32, &new_value);
+}
+
+static inline uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) {
+  // remove the thumb-bit before returning
+  return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1));
+}
+
+static inline void _Unwind_SetIP(struct _Unwind_Context* context,
+                                 uintptr_t new_value) {
+  uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
+  _Unwind_SetGR(context, 15, new_value | thumb_bit);
+}
+#else
+extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
+extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
+                          uintptr_t new_value);
+extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
+extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
+#endif
+
+extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
+extern uintptr_t
+    _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
+#if __USING_SJLJ_EXCEPTIONS__
+extern _Unwind_Reason_Code
+    _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object,
+                              _Unwind_Stop_Fn stop, void *stop_parameter);
+#else
+extern _Unwind_Reason_Code
+    _Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
+                         _Unwind_Stop_Fn stop, void *stop_parameter);
+#endif
+
+#if __USING_SJLJ_EXCEPTIONS__
+typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t;
+extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc);
+extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc);
+#endif
+
+//
+// The following are semi-suppoted extensions to the C++ ABI
+//
+
+//
+//  called by __cxa_rethrow().
+//
+#if __USING_SJLJ_EXCEPTIONS__
+extern _Unwind_Reason_Code
+    _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object);
+#else
+extern _Unwind_Reason_Code
+    _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object);
+#endif
+
+// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the
+// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack
+// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON.
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
+                                                void *);
+extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
+
+// _Unwind_GetCFA is a gcc extension that can be called from within a
+// personality handler to get the CFA (stack pointer before call) of 
+// current frame.
+extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *);
+
+
+// _Unwind_GetIPInfo is a gcc extension that can be called from within a
+// personality handler.  Similar to _Unwind_GetIP() but also returns in
+// *ipBefore a non-zero value if the instruction pointer is at or before the
+// instruction causing the unwind. Normally, in a function call, the IP returned
+// is the return address which is after the call instruction and may be past the
+// end of the function containing the call instruction.
+extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
+                                   int *ipBefore);
+
+
+// __register_frame() is used with dynamically generated code to register the
+// FDE for a generated (JIT) code.  The FDE must use pc-rel addressing to point
+// to its function and optional LSDA.  
+// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and 
+// 10.5 it was buggy and did not actually register the FDE with the unwinder.  
+// In 10.6 and later it does register properly.
+extern void __register_frame(const void *fde);
+extern void __deregister_frame(const void *fde);
+
+// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has
+// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind
+// info" which the runtime uses in preference to dwarf unwind info.  This 
+// function will only work if the target function has an FDE but no compact 
+// unwind info.
+struct dwarf_eh_bases {
+  uintptr_t tbase;
+  uintptr_t dbase;
+  uintptr_t func;
+};
+extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *);
+
+
+// This function attempts to find the start (address of first instruction) of
+// a function given an address inside the function.  It only works if the
+// function has an FDE (dwarf unwind info).
+// This function is unimplemented on Mac OS X 10.6 and later.  Instead, use
+// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result.
+extern void *_Unwind_FindEnclosingFunction(void *pc);
+
+// Mac OS X does not support text-rel and data-rel addressing so these functions
+// are unimplemented
+extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context)
+    LIBUNWIND_UNAVAIL;
+extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context)
+    LIBUNWIND_UNAVAIL;
+
+// Mac OS X 10.4 and 10.5 had implementations of these functions in
+// libgcc_s.dylib, but they never worked.  
+/// These functions are no longer available on Mac OS X.
+extern void __register_frame_info_bases(const void *fde, void *ob, void *tb,
+                                        void *db) LIBUNWIND_UNAVAIL;
+extern void __register_frame_info(const void *fde, void *ob)
+    LIBUNWIND_UNAVAIL;
+extern void __register_frame_info_table_bases(const void *fde, void *ob,
+                                              void *tb, void *db)
+    LIBUNWIND_UNAVAIL;
+extern void __register_frame_info_table(const void *fde, void *ob)
+    LIBUNWIND_UNAVAIL;
+extern void __register_frame_table(const void *fde)
+    LIBUNWIND_UNAVAIL;
+extern void *__deregister_frame_info(const void *fde)
+    LIBUNWIND_UNAVAIL;
+extern void *__deregister_frame_info_bases(const void *fde)
+    LIBUNWIND_UNAVAIL;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __UNWIND_H__
diff --git a/install-clang/.dockerignore b/install-clang/.dockerignore
new file mode 100644
index 0000000..3110309
--- /dev/null
+++ b/install-clang/.dockerignore
@@ -0,0 +1,2 @@
+.git
+install.*.log
diff --git a/install-clang/Dockerfile b/install-clang/Dockerfile
new file mode 100644
index 0000000..64374f0
--- /dev/null
+++ b/install-clang/Dockerfile
@@ -0,0 +1,21 @@
+
+FROM        ubuntu:trusty
+MAINTAINER  Robin Sommer <robin@icir.org>
+
+# Setup environment.
+ENV PATH /opt/llvm/bin:$PATH
+
+# Default command on startup.
+CMD bash
+
+# Setup packages.
+RUN apt-get update && apt-get -y install cmake git build-essential vim python
+
+# Copy install-clang over.
+ADD . /opt/install-clang
+
+# Compile and install LLVM/clang. We delete the source directory to
+# avoid committing it to the image.
+RUN /opt/install-clang/install-clang -j 4 -C /opt/llvm
+
+
diff --git a/install-clang/Makefile b/install-clang/Makefile
new file mode 100644
index 0000000..5c2ff13
--- /dev/null
+++ b/install-clang/Makefile
@@ -0,0 +1,16 @@
+
+IMAGE="rsmmr/clang:3.5"
+
+all:
+
+# Note, building the Docker image needs the default image size increased.
+# On Fedora: add "--storage-opt dm.basesize=30G" to /etc/sysconfig/docker.
+
+docker-build:
+	docker build -t ${IMAGE} .
+
+docker-run:
+	docker run -i -t ${IMAGE}
+
+docker-push:
+	docker push ${IMAGE}
diff --git a/install-clang/README.md b/install-clang/README.md
new file mode 100644
index 0000000..22a7949
--- /dev/null
+++ b/install-clang/README.md
@@ -0,0 +1,124 @@
+install-clang
+=============
+
+This script installs self-contained standalone versions of [clang][1],
+[LLVM][2], [libc++][3], and [compiler-rt][4] on Darwin, FreeBSD, and Linux,
+including linking clang and LLVM themselves against libc++ as well. The
+script keeps all of the installation within a given target prefix (e.g.,
+`/opt/llvm`), and hence separate from any already installed compilers,
+libraries, and include files. In particular, you can later deinstall
+everything easily by just deleting, e.g., `/opt/llvm`. Furthermore, as
+long as the prefix path is writable, the installation doesn't need root
+privileges.
+
+If you have used older version of the script before, see News below
+for changes.
+
+Usage
+-----
+
+To see the available options, use `-h`:
+
+    > ./install-clang -h
+    Usage: install-clang [<options>] <install-prefix>
+
+    Available options:
+        -A         enables assertions in LLVM libraries
+        -b         build type (Release, Debug, RelWithDebInfo) [default: RelWithDebInfo]
+        -c         skip cloning repositories, assume they are in place
+        -h|-?      display this help
+        -j <n>     build with <n> threads in parallel [default: 1]
+        -m         use git/master instead of preconfigured versions
+        -s <stage> begin build from <stage> [0, 1, 2]
+        -u         update an existing build in <prefix> instead of installing new
+
+    Environment variables:
+        CC         path to the C compiler for bootstrapping
+        CXX        path to the C++ compiler for bootstrapping
+
+For example, to build Clang on a machine with multiple cores and
+install it in `/opt/llvm`, you can use:
+
+    > ./install-clang -j 16 /opt/llvm
+
+Once finished, just prefix your PATH with `<prefix>/bin` and you're
+ready to use the new binaries:
+
+    > clang++ --std=c++11 --stdlib=libc++ test.cc -o a.out && ./a.out
+    Hello, Clang!
+
+By default, install-clang currently installs the 3.5 release branches
+of the relevant llvm.org projects. Adding `-m` on the command line
+instructs the script to use the current git master versions instead.
+The script downloads all the sources from the corresponding git
+repositories and compiles the pieces as needed. Other OSs than Darwin,
+FreeBSD, and Linux are not currently supported.
+
+The script also has an update option `-u` that allows for catching up
+with upstream repository changes without doing the complete
+compile/install-from-scratch cycle again. Note, however, that unless
+coupled with `-m`, this flag has no immediate effect since the git
+versions to use are hardcoded to the LLVM/clang release versions.
+
+Doing a self-contained clang/LLVM installation is a bit more messy
+than one would hope because the projects make assumptions about
+specific system-wide installation paths to use. The install-clang
+script captures some trial-and-error I (and others) went through to
+get an independent setup working. It compiles clang/LLVM up to three
+times, bootstrapping things with the system compiler as it goes. It
+also patches some of the LLVM projects to incorporate the installation
+prefix into configuration and search paths, and also fixes/tweaks a few
+other things as well.
+
+Docker
+------
+
+install-clang comes with a Dockerfile to build a Docker image, based
+on Ubuntu, with clang/LLVM then in /opt/llvm:
+
+    # make docker-build && make docker-run
+    [... get a beer ...]
+    root@f39b941f177c:/# clang --version
+    clang version 3.5.0
+    Target: x86_64-unknown-linux-gnu
+    Thread model: posix
+    root@f39b941f177c:/# which clang
+    /opt/llvm/bin/clang
+
+A prebuilt image is available at
+https://registry.hub.docker.com/u/rsmmr/clang.
+
+News
+----
+
+The install-clang script for LLVM 3.5 comes with a few changes
+compared to earlier version:
+
+* The script now supports FreeBSD as well. (Contributed by Matthias
+  Vallentin).
+
+* The script now generally shared libraries for LLVM and clang, rather
+  than static ones.
+
+* As libc++abi now works well on Linux as well, we use it generally
+  and no longer support libcxxrt.
+
+* There are now command line options to select build mode and
+  assertions explicitly.
+
+* There's no 3rd phase anymore building assertion-enabled LLVM
+  libraries, as changing compilation options isn't useful with shared
+  libraries.
+
+* In return, there's a phase 0 now if the system compiler isn't a
+  clang; libc++abi needs clang that for its initial compilation
+  already.
+
+* There's now a Dockerfile to build an image with clang/LLVM in
+  /opt/llvm.
+
+[1]: http://clang.llvm.org
+[2]: http://www.llvm.org
+[3]: http://libcxx.llvm.org
+[4]: http://compiler-rt.llvm.org
+[5]: http://libcxxabi.llvm.org
diff --git a/install-clang/a.out b/install-clang/a.out
new file mode 100755
index 0000000..99361df
--- /dev/null
+++ b/install-clang/a.out
Binary files differ
diff --git a/install-clang/install-clang b/install-clang/install-clang
new file mode 100755
index 0000000..cdef3d3
--- /dev/null
+++ b/install-clang/install-clang
@@ -0,0 +1,472 @@
+#! /usr/bin/env bash
+#
+# TODO:
+#    - Try adding lldb once again.
+
+OS=`uname`
+if [ "$OS" == "Linux" ]; then
+    triple=""
+    soext="so"
+    somask="so.%s"
+    addl_ldflags="-ldl"
+    addl_cmake=""
+
+elif [ "$OS" == "FreeBSD" ]; then
+    triple=""
+    soext="so"
+    somask="so.%s"
+    addl_ldflags=""
+    addl_cmake=""
+
+elif [ "$OS" == "Darwin" ]; then
+    triple="-apple-"
+    soext="dylib"
+    somask="%d.dylib"
+    addl_ldflags=""
+    addl_cmake="-DCMAKE_OSX_ARCHITECTURES=x86_64;i386"
+
+else
+    echo "OS $OS not supported by this script."
+    exit 1
+fi
+
+if [ -n "$CC" ]; then
+    cc=$CC
+elif which clang > /dev/null 2>&1; then
+    cc=clang
+elif which gcc > /dev/null 2>&1; then
+    cc=gcc
+else
+    echo could not find clang or gcc in '$PATH'
+    exit 1
+fi
+
+if [ -n "$CXX" ]; then
+    cxx=$CXX
+elif which clang++ > /dev/null 2>&1; then
+    cxx=clang++
+elif which g++ > /dev/null 2>&1; then
+    cxx=g++
+else
+    echo could not find clang++ or g++ in '$PATH'
+    exit 1
+fi
+
+use_master=0
+perform_clone=1            # If 0, skip the cloning (for testing only).
+perform_stage1=1           # If 0, skip the 1st bootstrap stage (for testing only).
+perform_stage2=1           # If 0, skip the 2nd stage compiling LLVM/clang against libc++ (for testing only).
+perform_lldb_build=0       # If 1, attempt to build LLDB.
+perform_lld_build=0        # If 1, attempt to build LLDB.
+perform_extra_build=1      # If 1, attempt to build clang-extra tools.
+perform_cleanup=0          # If 1, delete all source and build directories.
+assertions=off             # If "on", enable LLVM assertions.
+parallelism=1              # The value X to pass to make -j X to build in parallel.
+buildtype=RelWithDebInfo   # LLVM/clang build type.
+mode=install               # Install from scratch.
+targets=host               # LLVM_TARGETS_TO_BUILD ("all" builds them all).
+
+if eval ${cxx} --version | grep -q clang; then
+    perform_stage0=0
+    have_clang=1
+else
+    perform_stage0=1
+    have_clang=0
+fi
+
+usage()
+{
+    printf "Usage: %s [<options>] <install-prefix>\n" $(basename $0)
+    echo ""
+    echo "Available options:"
+    echo "    -A         enables assertions in LLVM libraries"
+    echo "    -b         build type (Release, Debug, RelWithDebInfo) [default: ${buildtype}]"
+    echo "    -c         skip cloning repositories, assume they are in place"
+    echo "    -C         clean up after build by deleting the LLVM/clang source/build directories"
+    echo "    -h|-?      display this help"
+    echo "    -j <n>     build with <n> threads in parallel [default: ${parallelism}]"
+    echo "    -m         use git/master instead of preconfigured versions"
+    echo "    -s <stage> begin build from <stage> [0, 1, 2]"
+    echo "    -u         update an existing build in <prefix> instead of installing new"
+    echo ""
+    echo "Environment variables:"
+    echo "    CC         path to the C compiler for bootstrapping"
+    echo "    CXX        path to the C++ compiler for bootstrapping"
+}
+
+while getopts "Ab::j:lms:ucCh?" opt ; do
+    case "$opt" in
+        c)
+            perform_clone=0
+            ;;
+        C)
+            perform_cleanup=1
+            ;;
+        h|\?)
+            usage
+            exit 0
+            ;;
+        j)
+            parallelism=$OPTARG
+            ;;
+        m)
+            use_master=1
+            ;;
+        s)
+            if [ "$OPTARG" == "0" ]; then
+                perform_stage0=1
+                perform_stage1=1
+                perform_stage2=1
+            elif [ "$OPTARG" == "1" ]; then
+                perform_stage0=0
+                perform_stage1=1
+                perform_stage2=1
+            elif [ "$OPTARG" == "2" ]; then
+                perform_stage0=0
+                perform_stage1=0
+                perform_stage2=1
+            else
+                echo 'stage parameter must be in [0,1,2].'
+                exit 1
+            fi
+            ;;
+        u)
+            mode=update
+            ;;
+
+        A)
+            assertions=on
+            ;;
+
+        b)
+            buildtype=$OPTARG
+            ;;
+
+    esac
+done
+
+shift $(expr $OPTIND - 1)
+prefix=`echo $1 | sed 's#/$##'`
+shift
+
+if [ "${use_master}" != "1" ]; then
+    # git version to checkout.
+    version_llvm=release_35
+    version_clang=release_35
+    version_libcxx=release_35
+    version_compilerrt=release_35
+    version_libcxxabi=239a032       # No 3.5 branch. Hardcoding.
+    version_lldb=master             # No 3.5 branch. Probably won't work.
+    version_lld=master              # No 3.5 branch. Probably won't work.
+    version_extra=release_35
+
+    cherrypick="projects/libcxx 0c6d1a88 e515bbda f2e8c0454"  # Fix linking against in-tree libc++abi.
+    cherrypick="$cherrypick;/ 168d0c143"  # Correctly add libc++abi to project list.
+    cherrypick="$cherrypick;/ d9aaca0ec"  # Fix libc++abi build on FreeBSD.
+
+else
+    # git version to checkout.
+    version_llvm=master
+    version_clang=master
+    version_libcxx=master
+    version_compilerrt=master
+    version_libcxxabi=master
+    version_lldb=master
+    version_lld=master
+    version_extra=master
+fi
+
+if [ "$mode" == "" -o "$prefix" == "" ]; then
+    usage
+    exit 1
+fi
+
+if [ ! -d $prefix ]; then
+    if [ "$mode" == "install" ]; then
+        if ! mkdir -p $prefix; then
+            echo failed to create directory $prefix
+            exit 1
+        fi
+    else
+        echo $prefix does not exist
+        exit 1
+    fi
+fi
+
+#### Copy all output to log file.
+log=install.$$.log
+echo "Recording log in $log ..."
+exec > >(tee $log) # Requires fdescfs mounted to /dev/fd on FreeBSD.
+exec 2>&1
+
+#### Set paths and environment.
+
+unset CFLAGS
+unset CXXFLAGS
+unset CPPFLAGS
+unset LDFLAGS
+unset LD_LIBRARY_PATH
+unset DYLD_LIBRARY_PATH
+
+# Built libraries with RTTI.
+export REQUIRES_RTTI=1
+export PATH=$prefix/bin:$PATH
+
+src="$prefix/src/llvm"
+src_libcxxabi=${src}/projects/libcxxabi
+src_libcxx=${src}/projects/libcxx
+src_compilerrt=${src}/projects/compiler-rt
+src_lldb=${src}/lldb
+src_lld=${src}/lld
+libcxx_include=$prefix/include/c++/v1
+libcxx_lib=$prefix/lib
+default_includes=${libcxx_include}:/usr/include
+
+mkdir -p $libcxx_include
+
+function st
+{
+    eval echo \$\{$1_stage${stage}\}
+}
+
+function add_include_path
+{
+    include=$1
+    search_patch=$2
+
+    path=`find "${search_patch}" | grep "${include}$" | awk '{print length, $0;}' | sort -n | head -1 | awk '{printf("%s", $2)}'`
+
+    if [ "$path" != "" ]; then
+        path=`echo -n ${path} | sed "s#${include}##g"`
+        if [ "${default_includes}" = "" ]; then
+            echo -n "${path}"
+        else
+            echo -n "${default_includes}:${path}"
+        fi
+    fi
+}
+
+function apply_patch
+{
+    patch=$1
+    base=`basename $patch`
+
+    cwd=`pwd`
+
+    cd $src
+
+    if basename "$patch" | grep -q -- '--'; then
+        dir=`echo $base | awk -v src=$src -F '--' '{printf("%s/%s/%s", src, $1, $2);}'`
+        if [ ! -d "$dir" ]; then
+            return
+        fi
+
+        cd $dir
+    fi
+
+    cat $patch | git am -3
+}
+
+#### Clone reposistories.
+
+export GIT_COMMITTER_EMAIL="`whoami`@localhost"
+export GIT_COMMITTER_NAME="`whoami`"
+
+d=`dirname $0`
+patches=`cd $d; pwd`/patches
+
+if [ "${perform_clone}" == "1" ]; then
+
+    # Get/update the repositories.
+    if [ "$mode" == "install" ]; then
+
+        test -d $src && echo "$src already exists, aborting" && exit 1
+        mkdir -p $src
+
+        echo Changing directory to `dirname $src` for installing  ...
+        cd `dirname $src`
+
+        git clone http://llvm.org/git/llvm.git `basename $src`
+
+        ( cd $src/tools && git clone http://llvm.org/git/clang.git )
+        ( cd $src/projects && git clone http://llvm.org/git/libcxx )
+        ( cd $src/projects && git clone http://llvm.org/git/compiler-rt )
+
+        ( cd $src && git checkout -q ${version_llvm} )
+        ( cd $src/tools/clang && git checkout -q ${version_clang}  )
+        ( cd ${src_libcxx} && git checkout -q ${version_libcxx} )
+        ( cd ${src_compilerrt} && git checkout -q ${version_compilerrt} )
+
+        ( cd $src/projects && git clone http://llvm.org/git/libcxxabi )
+        ( cd ${src_libcxxabi} && git checkout -q ${version_libcxxabi} )
+
+        if [ "${perform_extra_build}" == "1" ]; then
+            ( cd $src/tools && git clone http://llvm.org/git/clang-tools-extra.git extra )
+            ( cd $src/tools/extra && git checkout -q ${version_extra} )
+        fi
+
+        if [ "${perform_lldb_build}" == "1" ]; then
+            ( cd `dirname ${src_lldb}` && git clone http://llvm.org/git/lldb `basename ${src_lldb}`)
+            ( cd ${src_lldb} && git checkout -q ${version_lldb}  )
+        fi
+
+        if [ "${perform_lld_build}" == "1" ]; then
+            ( cd `dirname ${src_lld}` && git clone http://llvm.org/git/lld `basename ${src_lld}`)
+            ( cd ${src_lld} && git checkout -q ${version_lld}  )
+        fi
+
+    else
+        echo Changing directory to `dirname $src` for updating ...
+        cd `dirname $src`
+
+        ( cd ${src} && git pull --rebase )
+        ( cd ${src}/tools/clang && git pull --rebase )
+        ( cd ${src_libcxx} && git pull --rebase )
+        ( cd ${src_compilerrt} && git pull --rebase )
+
+        ( cd $src && git checkout -q ${version_llvm} )
+        ( cd $src/tools/clang && git checkout -q ${version_clang}  )
+        ( cd ${src_libcxx} && git checkout -q ${version_libcxx} )
+        ( cd ${src_compilerrt} && git checkout -q ${version_compilerrt} )
+
+        ( cd ${src_libcxxabi} && git pull --rebase )
+        ( cd ${src_libcxxabi} && git checkout -q ${version_libcxxabi} )
+
+        if [ "${perform_extra_build}" == "1" ]; then
+            ( cd $src/tools/extra && git pull --rebase )
+            ( cd $src/tools/extra && git checkout -q ${version_extra} )
+        fi
+
+        if [ "${perform_lldb_build}" == "1" ]; then
+            ( cd ${src_lldb} && git pull --rebase )
+            ( cd ${src_lldb} && git checkout -q ${version_lldb}  )
+        fi
+
+        if [ "${perform_lld_build}" == "1" ]; then
+            ( cd ${src_lld} && git pull --rebase )
+            ( cd ${src_lld} && git checkout -q ${version_lld}  )
+        fi
+    fi
+
+    # Cherry pick additional commits from master.
+    echo "${cherrypick}" | awk -v RS=\; '{print}' | while read line; do
+        if [ "$line" != "" ]; then
+            repo=`echo $line | cut -d ' ' -f 1`
+            commits=`echo $line | cut -d ' ' -f 2-`
+            echo "Cherry-picking $commits in $repo"
+            ( cd ${src}/$repo \
+              && git cherry-pick --strategy=recursive -X theirs $commits )
+        fi
+    done
+
+    # Apply any patches we might need.
+    for i in $patches/*; do
+        apply_patch $i
+    done
+
+    echo === Done applying patches
+
+fi
+
+if [ "$OS" == "Darwin" ]; then
+    CMAKE_stage1="-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++"
+
+elif [ "$OS" == "Linux" ] || [ "$OS" == "FreeBSD" ]; then
+    CMAKE_stage1="-DLIBCXX_LIBCXXABI_WHOLE_ARCHIVE=on -DLIBCXXABI_ENABLE_SHARED=off -DBUILD_SHARED_LIBS=on"
+    CMAKE_stage2=$CMAKE_stage1
+    CMAKE_stage3=$CMAKE_stage1
+
+    default_includes=`add_include_path features.h /usr/include`
+    default_includes=`add_include_path sys/cdefs.h /usr/include`
+
+else
+    echo "OS $OS not supported"
+    exit 1
+fi
+
+CMAKE_common="-DBUILD_SHARED_LIBS=on -DLLVM_TARGETS_TO_BUILD=${targets}"
+CMAKE_stage0="${CMAKE_common} ${CMAKE_stage0} -DLLVM_INCLUDE_TOOLS=bootstrap-only  -DLLVM_EXTERNAL_LIBCXX_BUILD=off -DLLVM_EXTERNAL_LIBCXXABI_BUILD=off -DLLVM_EXTERNAL_COMPILER_RT_BUILD=off"
+CMAKE_stage1="${CMAKE_common} ${CMAKE_stage1} -DLLVM_INCLUDE_TOOLS=bootstrap-only -DLLVM_ENABLE_ASSERTIONS=${assertions} -DLLVM_EXTERNAL_LIBCXXABI_BUILD=on"
+CMAKE_stage2="${CMAKE_common} ${CMAKE_stage2} -DLLVM_ENABLE_ASSERTIONS=${assertions}"
+
+#### Configure the stages.
+
+# Stage 0 options. Get us a clang.
+
+CC_stage0="$cc"
+CXX_stage0="$cxx"
+CXXFLAGS_stage0=""
+CMAKE_stage0="${CMAKE_stage0}"
+BUILD_TYPE_stage0=${buildtype}
+
+# Stage 1 options. Compile against standard libraries.
+
+if [ "${have_clang}" == "1" ]; then
+    CC_stage1="$cc"
+    CXX_stage1="$cxx"
+else
+    CC_stage1=$prefix/bin/clang
+    CXX_stage1=$prefix/bin/clang++
+fi
+
+CXXFLAGS_stage1=""
+BUILD_TYPE_stage1=${buildtype}
+
+# Stage 2 options. Compile against our own libraries.
+
+CC_stage2=$prefix/bin/clang
+CXX_stage2=$prefix/bin/clang++
+CFLAGS_stage2="-stdlib=libc++"
+CXXFLAGS_stage2="-stdlib=libc++"
+CMAKE_stage2="${CMAKE_stage2}"
+BUILD_TYPE_stage2=${buildtype}
+
+#### Compile the stages.
+
+echo Changing directory to $src ...
+cd $src
+
+for stage in 0 1 2; do
+     if [ "`st perform`" == "0" ]; then
+         continue
+     fi
+
+     echo ===
+     echo === Building LLVM/clang, stage ${stage} ...
+     echo ===
+
+     ( cd $src &&\
+       mkdir -p build-stage${stage} && \
+       cd build-stage${stage} && \
+       CC=`st CC` \
+       CXX=`st CXX` \
+       CFLAGS="`st CFLAGS`" \
+       CXXFLAGS="`st CXXFLAGS`" \
+       LDFLAGS="${addl_ldflags}" \
+       cmake -DCMAKE_BUILD_TYPE=`st BUILD_TYPE` \
+             -DLLVM_REQUIRES_RTTI=1 \
+             -DCMAKE_INSTALL_PREFIX=${prefix} \
+             -DC_INCLUDE_DIRS=${default_includes} \
+             ${addl_cmake} \
+             `st CMAKE` \
+             .. && \
+       make -j $parallelism && \
+       make install \
+     )
+
+    if [ "$?" != "0" ] ; then
+        echo ===
+        echo === Faild building LLVM/clang at stage ${stage}
+        echo ===
+        exit 1
+    fi
+done
+
+if [ "${perform_cleanup}" == "1" ]; then
+    echo Deleting $src ...
+    rm -rf "${src}"
+fi
+
+echo "===="
+echo "==== Complete log in $log"
+echo "===="
diff --git a/install-clang/install.14910.log b/install-clang/install.14910.log
new file mode 100644
index 0000000..2594815
--- /dev/null
+++ b/install-clang/install.14910.log
Binary files differ
diff --git a/install-clang/install.3658.log b/install-clang/install.3658.log
new file mode 100644
index 0000000..05ba55e
--- /dev/null
+++ b/install-clang/install.3658.log
Binary files differ
diff --git a/install-clang/install.71242.log b/install-clang/install.71242.log
new file mode 100644
index 0000000..c6b3039
--- /dev/null
+++ b/install-clang/install.71242.log
Binary files differ
diff --git a/install-clang/patches/fix-external-project-order.patch b/install-clang/patches/fix-external-project-order.patch
new file mode 100644
index 0000000..fcc02c7
--- /dev/null
+++ b/install-clang/patches/fix-external-project-order.patch
@@ -0,0 +1,26 @@
+From 250cda2614351358859a004824c8689e454a91a0 Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Mon, 1 Dec 2014 08:06:49 -0800
+Subject: [PATCH] Fix order of add_llvm_external_project calls.
+
+---
+ projects/CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt
+index 8d244fd..5aaf03f 100644
+--- a/projects/CMakeLists.txt
++++ b/projects/CMakeLists.txt
+@@ -19,8 +19,8 @@ if(${LLVM_BUILD_RUNTIME})
+   # MSVC isn't quite working with libc++ yet, disable it until issues are
+   # fixed.
+   if(NOT MSVC)
+-    add_llvm_external_project(libcxx)
+     add_llvm_external_project(libcxxabi)
++    add_llvm_external_project(libcxx)
+   endif()
+   if(NOT LLVM_BUILD_EXTERNAL_COMPILER_RT)
+     add_llvm_external_project(compiler-rt)
+-- 
+2.2.0
+
diff --git a/install-clang/patches/projects--compiler-rt--link-fix.patch b/install-clang/patches/projects--compiler-rt--link-fix.patch
new file mode 100644
index 0000000..39498c4
--- /dev/null
+++ b/install-clang/patches/projects--compiler-rt--link-fix.patch
@@ -0,0 +1,32 @@
+From 6515d9951bb68a7028e56e37ea6255a940c7ebf2 Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Sun, 15 Jun 2014 20:02:25 -0700
+Subject: [PATCH] Disable iossim build to fix linker errors.
+
+When attempting to build the address sanitizer for the iOS simulator,
+we run into an architecture mismatch between dependent shared
+libraries, such as libc++.dylib.
+
+Disabling the iOS simulator build fixes the issue.
+---
+ CMakeLists.txt | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3b52403..3571aa1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -341,7 +341,9 @@ if(APPLE)
+          MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
+   set(SANITIZER_COMMON_SUPPORTED_DARWIN_OS osx)
+   if (IOSSIM_SDK_DIR AND NOT MACOSX_VERSION_MIN_FLAG)
+-    list(APPEND SANITIZER_COMMON_SUPPORTED_DARWIN_OS iossim)
++    # Disable iOS Simulator build because it clashes with the architecture of
++    # dependent libraries, such libc++abi and libc++.
++    # list(APPEND SANITIZER_COMMON_SUPPORTED_DARWIN_OS iossim)
+   endif()
+ 
+   if(COMPILER_RT_USES_LIBCXX)
+-- 
+1.9.3
+
diff --git a/install-clang/patches/projects--libcxx--libcxxabi-symbols.patch b/install-clang/patches/projects--libcxx--libcxxabi-symbols.patch
new file mode 100644
index 0000000..167d8e9
--- /dev/null
+++ b/install-clang/patches/projects--libcxx--libcxxabi-symbols.patch
@@ -0,0 +1,32 @@
+From 4f3cbfe81887dde86fe009e5dcc5fb124ba625f8 Mon Sep 17 00:00:00 2001
+From: Matthias Vallentin <vallentin@icir.org>
+Date: Fri, 20 Dec 2013 12:17:03 -0800
+Subject: [PATCH] Use all symbols of the static libc++abi library.
+
+When linking libc++ with our static version of libc+abi, we would like to
+include all symbols that applications may need in the future and not just those
+used by libc++.
+---
+ lib/CMakeLists.txt |    6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index cec0bee..bc3bd5c 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -36,7 +36,11 @@ if (DEFINED LIBCXX_CXX_ABI_DEPS)
+ endif()
+ 
+ # Generate library list.
+-set(libraries ${LIBCXX_CXX_ABI_LIBRARIES})
++if (LIBCXX_LIBCXXABI_WHOLE_ARCHIVE)
++  set(libraries -Wl,--whole-archive ${LIBCXX_CXX_ABI_LIBRARIES} -Wl,--no-whole-archive)
++else()
++  set(libraries ${LIBCXX_CXX_ABI_LIBRARIES})
++endif()
+ append_if(libraries LIBCXX_HAS_PTHREAD_LIB pthread)
+ append_if(libraries LIBCXX_HAS_C_LIB c)
+ append_if(libraries LIBCXX_HAS_M_LIB m)
+-- 
+1.7.6.4
+
diff --git a/install-clang/patches/projects--libcxx--prefix.diff b/install-clang/patches/projects--libcxx--prefix.diff
new file mode 100644
index 0000000..53b4637
--- /dev/null
+++ b/install-clang/patches/projects--libcxx--prefix.diff
@@ -0,0 +1,58 @@
+From c6c2c1b5f079c9f3d26a820ff375b729f253b5b1 Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Mon, 1 Sep 2014 09:02:33 -0700
+Subject: [PATCH] Adapting library's install_name on Darwin to installation
+ prefix.
+
+---
+ lib/CMakeLists.txt | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
+index be8df5c..53c98ac 100644
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -59,8 +59,8 @@ if ( APPLE )
+     list(APPEND link_flags
+       "-compatibility_version 1"
+       "-current_version ${LIBCXX_VERSION}"
+-      "-install_name /usr/lib/libc++.1.dylib"
+-      "-Wl,-reexport_library,/usr/lib/libc++abi.dylib"
++      "-install_name ${CMAKE_INSTALL_PREFIX}/lib/libc++.1.dylib"
++      "-Wl,-reexport_library,${CMAKE_INSTALL_PREFIX}/lib/libc++abi.dylib"
+       "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
+       "/usr/lib/libSystem.B.dylib")
+   else()
+@@ -75,16 +75,18 @@ if ( APPLE )
+           "-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib")
+       endif()
+     else()
+-      set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
++      get_property(abiloc TARGET cxxabi PROPERTY LOCATION)
++      set(OSX_RE_EXPORT_LINE "-Wl,-reexport_library,${abiloc}")
+     endif()
+ 
+     list(APPEND link_flags
+       "-compatibility_version 1"
+-      "-install_name /usr/lib/libc++.1.dylib"
++      "-install_name ${CMAKE_INSTALL_PREFIX}/lib/libc++.1.dylib"
+       "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
+       "${OSX_RE_EXPORT_LINE}"
+       "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp"
+-      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp")
++      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp"
++      "-nodefaultlibs")
+   endif()
+ endif()
+ 
+@@ -97,6 +99,7 @@ set_target_properties(cxx
+     OUTPUT_NAME   "c++"
+     VERSION       "1.0"
+     SOVERSION     "1"
++    INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
+   )
+ 
+ install(TARGETS cxx
+-- 
+2.1.0
+
diff --git a/install-clang/patches/projects--libcxxabi--prefix.diff b/install-clang/patches/projects--libcxxabi--prefix.diff
new file mode 100644
index 0000000..0fb1767
--- /dev/null
+++ b/install-clang/patches/projects--libcxxabi--prefix.diff
@@ -0,0 +1,41 @@
+From 9505f69390ddde3ff45b0f52180d59ae7ae9b37e Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Mon, 1 Sep 2014 08:31:32 -0700
+Subject: [PATCH] Adapting library's install_name on Darwin to installation
+ prefix.
+
+---
+ src/CMakeLists.txt | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index 774ef27..4e581a0 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -67,12 +67,13 @@ if ( APPLE )
+     list(APPEND link_flags
+       "-compatibility_version 1"
+       "-current_version 1"
+-      "-install_name /usr/lib/libc++abi.1.dylib"
++      "-install_name ${CMAKE_INSTALL_PREFIX}/lib/libc++abi.1.dylib"
+       "/usr/lib/libSystem.B.dylib")
+   else()
+     list(APPEND link_flags
+       "-compatibility_version 1"
+-      "-install_name /usr/lib/libc++abi.1.dylib")
++      "-install_name ${CMAKE_INSTALL_PREFIX}/lib/libc++abi.1.dylib"
++      "-nodefaultlibs")
+   endif()
+ endif()
+ 
+@@ -86,6 +87,7 @@ set_target_properties(cxxabi
+     OUTPUT_NAME   "c++abi"
+     VERSION       "1.0"
+     SOVERSION     "1"
++    INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
+   )
+ 
+ install(TARGETS cxxabi
+-- 
+2.1.0
+
diff --git a/install-clang/patches/projects--libcxxabi--unwind_h.patch b/install-clang/patches/projects--libcxxabi--unwind_h.patch
new file mode 100644
index 0000000..802088f
--- /dev/null
+++ b/install-clang/patches/projects--libcxxabi--unwind_h.patch
@@ -0,0 +1,22 @@
+From 70f15c92e786e27e94b0db95a5a335513997163a Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Sat, 25 Oct 2014 15:07:27 -0700
+Subject: [PATCH] Install unwind headers into $prefix/include.
+
+---
+ CMakeLists.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 6815b0d..60bb67e 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -255,3 +255,5 @@ if(NOT LIBCXXABI_ENABLE_SHARED)
+ else()
+   add_subdirectory(test)
+ endif()
++
++install(FILES include/libunwind.h include/unwind.h DESTINATION include/)
+-- 
+1.9.3
+
diff --git a/install-clang/patches/stackmaps-for-elf.ec9de4677ac61.patch b/install-clang/patches/stackmaps-for-elf.ec9de4677ac61.patch
new file mode 100644
index 0000000..43506e8
--- /dev/null
+++ b/install-clang/patches/stackmaps-for-elf.ec9de4677ac61.patch
@@ -0,0 +1,52 @@
+From ec9de4677ac61f2164d7c80cae5da0008189efa3 Mon Sep 17 00:00:00 2001
+From: Philip Reames <listmail@philipreames.com>
+Date: Fri, 1 Aug 2014 18:47:09 +0000
+Subject: [PATCH] Add support for StackMap section for ELF/Linux systems
+
+This patch adds code to emits the StackMap section on ELF systems. This section is required to support llvm.experimental.stackmap and llvm.experimental.patchpoint intrinsics.
+
+Reviewers: ributzka, echristo
+
+Differential Revision: http://reviews.llvm.org/D4574
+
+
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214538 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ lib/MC/MCObjectFileInfo.cpp      | 6 ++++++
+ lib/Target/X86/X86AsmPrinter.cpp | 2 ++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
+index df5787c..da707d8 100644
+--- a/lib/MC/MCObjectFileInfo.cpp
++++ b/lib/MC/MCObjectFileInfo.cpp
+@@ -583,6 +583,12 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
+   DwarfAddrSection =
+     Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
+                        SectionKind::getMetadata());
++
++  StackMapSection =
++    Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS,
++                       ELF::SHF_ALLOC,
++                       SectionKind::getMetadata());
++
+ }
+ 
+ 
+diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
+index 3c22e88..fc0d408 100644
+--- a/lib/Target/X86/X86AsmPrinter.cpp
++++ b/lib/Target/X86/X86AsmPrinter.cpp
+@@ -736,6 +736,8 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
+       }
+       Stubs.clear();
+     }
++
++    SM.serializeToStackMapSection();
+   }
+ }
+ 
+-- 
+1.9.3
+
diff --git a/install-clang/patches/tools--clang--freebsd-include.patch b/install-clang/patches/tools--clang--freebsd-include.patch
new file mode 100644
index 0000000..0bb48de
--- /dev/null
+++ b/install-clang/patches/tools--clang--freebsd-include.patch
@@ -0,0 +1,31 @@
+From 2f0413250e91c44b4e42a5334f00b7b937600076 Mon Sep 17 00:00:00 2001
+From: Matthias Vallentin <vallentin@icir.org>
+Date: Wed, 5 Nov 2014 13:32:12 -0800
+Subject: Remove hard-coded /usr prefix on FreeBSD.
+
+The toolchain used to hardcode /usr/include/c++/v1 as default include
+path on FreeBSD, which breaks because that path exists already and
+contains an outdated set of standard library includes.
+
+The correct include path must be relative to the prefix, which this
+patch adjusts.
+---
+ lib/Driver/ToolChains.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
+index b46f69d..2309b2d 100644
+--- a/lib/Driver/ToolChains.cpp
++++ b/lib/Driver/ToolChains.cpp
+@@ -2561,7 +2561,7 @@ void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+   switch (GetCXXStdlibType(DriverArgs)) {
+   case ToolChain::CST_Libcxx:
+     addSystemInclude(DriverArgs, CC1Args,
+-                     getDriver().SysRoot + "/usr/include/c++/v1");
++                     getDriver().Dir + "/../include/c++/v1");
+     break;
+   case ToolChain::CST_Libstdcxx:
+     addSystemInclude(DriverArgs, CC1Args,
+-- 
+2.1.2
+
diff --git a/install-clang/patches/tools--clang--include-path.patch b/install-clang/patches/tools--clang--include-path.patch
new file mode 100644
index 0000000..e07707f
--- /dev/null
+++ b/install-clang/patches/tools--clang--include-path.patch
@@ -0,0 +1,28 @@
+From e24fe0eee01e9218bdb40e82c1238d99ac2b4bf5 Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Sun, 26 Oct 2014 12:18:44 -0700
+Subject: [PATCH] Adding $prefix/include to list of standard include paths.
+
+---
+ lib/Driver/Tools.cpp | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
+index f1cbf50..ac345ab 100644
+--- a/lib/Driver/Tools.cpp
++++ b/lib/Driver/Tools.cpp
+@@ -449,6 +449,11 @@ void Clang::AddPreprocessingOptions(Compilation &C,
+   // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
+   addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
+ 
++  if (!Args.hasArg(options::OPT_nostdlibinc)) {
++    CmdArgs.push_back("-internal-isystem");
++    CmdArgs.push_back(Args.MakeArgString(D.Dir + "/../include"));
++  }
++
+   // Add C++ include arguments, if needed.
+   if (types::isCXX(Inputs[0].getType()))
+     getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
+-- 
+1.9.3
+
diff --git a/install-clang/patches/tools--clang--linker-args.patch b/install-clang/patches/tools--clang--linker-args.patch
new file mode 100644
index 0000000..e6c4705
--- /dev/null
+++ b/install-clang/patches/tools--clang--linker-args.patch
@@ -0,0 +1,50 @@
+From d69bb4b646428fb4b177cd61e467f975d77277da Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Sun, 15 Jun 2014 19:57:19 -0700
+Subject: Adapting linker arguments.
+
+ - Adding -L<prefix>/lib to default linker arguments.
+ - On Linux and FreeBSD, and -rpath.
+ - Fix FreeBSD builtin library search paths.
+---
+ lib/Driver/ToolChains.cpp | 3 +++
+ lib/Driver/Tools.cpp      | 9 +++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
+index 2309b2d..db59c01 100644
+--- a/lib/Driver/ToolChains.cpp
++++ b/lib/Driver/ToolChains.cpp
+@@ -2524,6 +2524,9 @@ void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
+ 
+ FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+   : Generic_ELF(D, Triple, Args) {
++  // Look in the prefix before going into /usr/lib. Otherwise we'll wind up
++  // with the wrong libc++.
++  getFilePaths().push_back(getDriver().Dir + "/../lib");
+ 
+   // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
+   // back to '/usr/lib' if it doesn't exist.
+diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
+index 9a5b361..32228fd 100644
+--- a/lib/Driver/Tools.cpp
++++ b/lib/Driver/Tools.cpp
+@@ -214,6 +214,15 @@ static void AddLinkerInputs(const ToolChain &TC,
+   //                and only supported on native toolchains.
+   if (!TC.isCrossCompiling())
+     addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
++
++  if (!TC.isCrossCompiling()) {
++    CmdArgs.push_back(Args.MakeArgString("-L" + D.InstalledDir + "/../lib"));
++
++    auto os = TC.getTriple().getOS();
++    if (os == llvm::Triple::Linux || os == llvm::Triple::FreeBSD)
++      CmdArgs.push_back(Args.MakeArgString("-rpath=" + D.InstalledDir + "/../lib"));
++  }
++
+ }
+ 
+ /// \brief Determine whether Objective-C automated reference counting is
+-- 
+2.1.2
+
diff --git a/install-clang/patches/tools--extra--tidy-fix.patch b/install-clang/patches/tools--extra--tidy-fix.patch
new file mode 100644
index 0000000..b8fbf2a
--- /dev/null
+++ b/install-clang/patches/tools--extra--tidy-fix.patch
@@ -0,0 +1,25 @@
+From ea2e20772d693e4aceb129c4b4286d8aa17d25b8 Mon Sep 17 00:00:00 2001
+From: Robin Sommer <robin@icir.org>
+Date: Mon, 27 Oct 2014 18:43:05 -0700
+Subject: [PATCH] Fixing compile problem.
+
+---
+ clang-tidy/ClangTidy.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/clang-tidy/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp
+index 98a5c61..f0bbd90 100644
+--- a/clang-tidy/ClangTidy.cpp
++++ b/clang-tidy/ClangTidy.cpp
+@@ -58,7 +58,7 @@ static StringRef StaticAnalyzerChecks[] = {
+ #define GET_CHECKERS
+ #define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN)       \
+   FULLNAME,
+-#include "../../../lib/StaticAnalyzer/Checkers/Checkers.inc"
++#include "../../../tools/clang/lib/StaticAnalyzer/Checkers/Checkers.inc"
+ #undef CHECKER
+ #undef GET_CHECKERS
+ };
+-- 
+1.9.3
+
diff --git a/install-clang/test.cc b/install-clang/test.cc
new file mode 100644
index 0000000..ff4733b
--- /dev/null
+++ b/install-clang/test.cc
@@ -0,0 +1,9 @@
+
+#include <algorithm>
+#include <iostream>
+
+int main(int argc, char** argv)
+{
+    std::cout << "Hello, Clang!" << std::endl;
+    return 1;
+}
diff --git a/install-clang/testit b/install-clang/testit
new file mode 100755
index 0000000..a93d4ad
--- /dev/null
+++ b/install-clang/testit
@@ -0,0 +1,9 @@
+#! /usr/bin/env bash
+
+if [ $# != 1 ]; then
+    echo "usage: $0 <install-prefix>"
+    exit 1
+fi
+
+$1/bin/clang++ --std=c++11 --stdlib=libc++ test.cc -o a.out && ./a.out
+#rm -f a.out
diff --git a/lib/BugpointPasses.dylib b/lib/BugpointPasses.dylib
new file mode 100755
index 0000000..387ef8b
--- /dev/null
+++ b/lib/BugpointPasses.dylib
Binary files differ
diff --git a/lib/LLVMHello.dylib b/lib/LLVMHello.dylib
new file mode 100755
index 0000000..efa8e96
--- /dev/null
+++ b/lib/LLVMHello.dylib
Binary files differ
diff --git a/lib/clang/3.5.2/asan_blacklist.txt b/lib/clang/3.5.2/asan_blacklist.txt
new file mode 100644
index 0000000..c25921f
--- /dev/null
+++ b/lib/clang/3.5.2/asan_blacklist.txt
@@ -0,0 +1,13 @@
+# Blacklist for AddressSanitizer. Turns off instrumentation of particular
+# functions or sources. Use with care. You may set location of blacklist
+# at compile-time using -fsanitize-blacklist=<path> flag.
+
+# Example usage:
+# fun:*bad_function_name*
+# src:file_with_tricky_code.cc
+# global:*global_with_bad_access_or_initialization*
+# global:*global_with_initialization_issues*=init
+# type:*Namespace::ClassName*=init
+
+# Stack buffer overflow in VC/INCLUDE/xlocnum, see http://goo.gl/L4qqUG
+fun:*_Find_elem@*@std*
diff --git a/lib/clang/3.5.2/include/Intrin.h b/lib/clang/3.5.2/include/Intrin.h
new file mode 100644
index 0000000..13e105e
--- /dev/null
+++ b/lib/clang/3.5.2/include/Intrin.h
@@ -0,0 +1,1014 @@
+/* ===-------- Intrin.h ---------------------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+/* Only include this if we're compiling for the windows platform. */
+#ifndef _MSC_VER
+#include_next <Intrin.h>
+#else
+
+#ifndef __INTRIN_H
+#define __INTRIN_H
+
+/* First include the standard intrinsics. */
+#if defined(__i386__) || defined(__x86_64__)
+#include <x86intrin.h>
+#endif
+
+/* For the definition of jmp_buf. */
+#if __STDC_HOSTED__
+#include <setjmp.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__MMX__)
+/* And the random ones that aren't in those files. */
+__m64 _m_from_float(float);
+__m64 _m_from_int(int _l);
+void _m_prefetch(void *);
+float _m_to_float(__m64);
+int _m_to_int(__m64 _M);
+#endif
+
+/* Other assorted instruction intrinsics. */
+void __addfsbyte(unsigned long, unsigned char);
+void __addfsdword(unsigned long, unsigned long);
+void __addfsword(unsigned long, unsigned short);
+void __code_seg(const char *);
+static __inline__
+void __cpuid(int[4], int);
+static __inline__
+void __cpuidex(int[4], int, int);
+void __debugbreak(void);
+__int64 __emul(int, int);
+unsigned __int64 __emulu(unsigned int, unsigned int);
+void __cdecl __fastfail(unsigned int);
+unsigned int __getcallerseflags(void);
+static __inline__
+void __halt(void);
+unsigned char __inbyte(unsigned short);
+void __inbytestring(unsigned short, unsigned char *, unsigned long);
+void __incfsbyte(unsigned long);
+void __incfsdword(unsigned long);
+void __incfsword(unsigned long);
+unsigned long __indword(unsigned short);
+void __indwordstring(unsigned short, unsigned long *, unsigned long);
+void __int2c(void);
+void __invlpg(void *);
+unsigned short __inword(unsigned short);
+void __inwordstring(unsigned short, unsigned short *, unsigned long);
+void __lidt(void *);
+unsigned __int64 __ll_lshift(unsigned __int64, int);
+__int64 __ll_rshift(__int64, int);
+void __llwpcb(void *);
+unsigned char __lwpins32(unsigned int, unsigned int, unsigned int);
+void __lwpval32(unsigned int, unsigned int, unsigned int);
+unsigned int __lzcnt(unsigned int);
+unsigned short __lzcnt16(unsigned short);
+static __inline__
+void __movsb(unsigned char *, unsigned char const *, size_t);
+static __inline__
+void __movsd(unsigned long *, unsigned long const *, size_t);
+static __inline__
+void __movsw(unsigned short *, unsigned short const *, size_t);
+void __nop(void);
+void __nvreg_restore_fence(void);
+void __nvreg_save_fence(void);
+void __outbyte(unsigned short, unsigned char);
+void __outbytestring(unsigned short, unsigned char *, unsigned long);
+void __outdword(unsigned short, unsigned long);
+void __outdwordstring(unsigned short, unsigned long *, unsigned long);
+void __outword(unsigned short, unsigned short);
+void __outwordstring(unsigned short, unsigned short *, unsigned long);
+static __inline__
+unsigned int __popcnt(unsigned int);
+static __inline__
+unsigned short __popcnt16(unsigned short);
+unsigned long __readcr0(void);
+unsigned long __readcr2(void);
+static __inline__
+unsigned long __readcr3(void);
+unsigned long __readcr4(void);
+unsigned long __readcr8(void);
+unsigned int __readdr(unsigned int);
+#ifdef __i386__
+static __inline__
+unsigned char __readfsbyte(unsigned long);
+static __inline__
+unsigned long __readfsdword(unsigned long);
+static __inline__
+unsigned __int64 __readfsqword(unsigned long);
+static __inline__
+unsigned short __readfsword(unsigned long);
+#endif
+static __inline__
+unsigned __int64 __readmsr(unsigned long);
+unsigned __int64 __readpmc(unsigned long);
+unsigned long __segmentlimit(unsigned long);
+void __sidt(void *);
+void *__slwpcb(void);
+static __inline__
+void __stosb(unsigned char *, unsigned char, size_t);
+static __inline__
+void __stosd(unsigned long *, unsigned long, size_t);
+static __inline__
+void __stosw(unsigned short *, unsigned short, size_t);
+void __svm_clgi(void);
+void __svm_invlpga(void *, int);
+void __svm_skinit(int);
+void __svm_stgi(void);
+void __svm_vmload(size_t);
+void __svm_vmrun(size_t);
+void __svm_vmsave(size_t);
+void __ud2(void);
+unsigned __int64 __ull_rshift(unsigned __int64, int);
+void __vmx_off(void);
+void __vmx_vmptrst(unsigned __int64 *);
+void __wbinvd(void);
+void __writecr0(unsigned int);
+static __inline__
+void __writecr3(unsigned int);
+void __writecr4(unsigned int);
+void __writecr8(unsigned int);
+void __writedr(unsigned int, unsigned int);
+void __writefsbyte(unsigned long, unsigned char);
+void __writefsdword(unsigned long, unsigned long);
+void __writefsqword(unsigned long, unsigned __int64);
+void __writefsword(unsigned long, unsigned short);
+void __writemsr(unsigned long, unsigned __int64);
+static __inline__
+void *_AddressOfReturnAddress(void);
+unsigned int _andn_u32(unsigned int, unsigned int);
+unsigned int _bextr_u32(unsigned int, unsigned int, unsigned int);
+unsigned int _bextri_u32(unsigned int, unsigned int);
+static __inline__
+unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
+static __inline__
+unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
+static __inline__
+unsigned char _bittest(long const *, long);
+static __inline__
+unsigned char _bittestandcomplement(long *, long);
+static __inline__
+unsigned char _bittestandreset(long *, long);
+static __inline__
+unsigned char _bittestandset(long *, long);
+unsigned int _blcfill_u32(unsigned int);
+unsigned int _blci_u32(unsigned int);
+unsigned int _blcic_u32(unsigned int);
+unsigned int _blcmsk_u32(unsigned int);
+unsigned int _blcs_u32(unsigned int);
+unsigned int _blsfill_u32(unsigned int);
+unsigned int _blsi_u32(unsigned int);
+unsigned int _blsic_u32(unsigned int);
+unsigned int _blsmsk_u32(unsigned int);
+unsigned int _blsr_u32(unsigned int);
+unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
+unsigned long __cdecl _byteswap_ulong(unsigned long);
+unsigned short __cdecl _byteswap_ushort(unsigned short);
+unsigned _bzhi_u32(unsigned int, unsigned int);
+void __cdecl _disable(void);
+void __cdecl _enable(void);
+void __cdecl _fxrstor(void const *);
+void __cdecl _fxsave(void *);
+long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
+static __inline__
+long _InterlockedAnd(long volatile *_Value, long _Mask);
+static __inline__
+short _InterlockedAnd16(short volatile *_Value, short _Mask);
+static __inline__
+char _InterlockedAnd8(char volatile *_Value, char _Mask);
+unsigned char _interlockedbittestandreset(long volatile *, long);
+static __inline__
+unsigned char _interlockedbittestandset(long volatile *, long);
+static __inline__
+long __cdecl _InterlockedCompareExchange(long volatile *_Destination,
+                                         long _Exchange, long _Comparand);
+long _InterlockedCompareExchange_HLEAcquire(long volatile *, long, long);
+long _InterlockedCompareExchange_HLERelease(long volatile *, long, long);
+static __inline__
+short _InterlockedCompareExchange16(short volatile *_Destination,
+                                    short _Exchange, short _Comparand);
+static __inline__
+__int64 _InterlockedCompareExchange64(__int64 volatile *_Destination,
+                                      __int64 _Exchange, __int64 _Comparand);
+__int64 _InterlockedcompareExchange64_HLEAcquire(__int64 volatile *, __int64,
+                                                 __int64);
+__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64,
+                                                 __int64);
+static __inline__
+char _InterlockedCompareExchange8(char volatile *_Destination, char _Exchange,
+                                  char _Comparand);
+void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *,
+                                                    void *);
+void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *,
+                                                    void *);
+static __inline__
+long __cdecl _InterlockedDecrement(long volatile *_Addend);
+static __inline__
+short _InterlockedDecrement16(short volatile *_Addend);
+long _InterlockedExchange(long volatile *_Target, long _Value);
+static __inline__
+short _InterlockedExchange16(short volatile *_Target, short _Value);
+static __inline__
+char _InterlockedExchange8(char volatile *_Target, char _Value);
+static __inline__
+long __cdecl _InterlockedExchangeAdd(long volatile *_Addend, long _Value);
+long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
+long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
+static __inline__
+short _InterlockedExchangeAdd16(short volatile *_Addend, short _Value);
+__int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
+__int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
+static __inline__
+char _InterlockedExchangeAdd8(char volatile *_Addend, char _Value);
+static __inline__
+long __cdecl _InterlockedIncrement(long volatile *_Addend);
+static __inline__
+short _InterlockedIncrement16(short volatile *_Addend);
+static __inline__
+long _InterlockedOr(long volatile *_Value, long _Mask);
+static __inline__
+short _InterlockedOr16(short volatile *_Value, short _Mask);
+static __inline__
+char _InterlockedOr8(char volatile *_Value, char _Mask);
+static __inline__
+long _InterlockedXor(long volatile *_Value, long _Mask);
+static __inline__
+short _InterlockedXor16(short volatile *_Value, short _Mask);
+static __inline__
+char _InterlockedXor8(char volatile *_Value, char _Mask);
+void __cdecl _invpcid(unsigned int, void *);
+static __inline__
+unsigned long __cdecl _lrotl(unsigned long, int);
+static __inline__
+unsigned long __cdecl _lrotr(unsigned long, int);
+static __inline__
+unsigned int _lzcnt_u32(unsigned int);
+static __inline__
+void _ReadBarrier(void);
+static __inline__
+void _ReadWriteBarrier(void);
+static __inline__
+void *_ReturnAddress(void);
+unsigned int _rorx_u32(unsigned int, const unsigned int);
+int __cdecl _rdrand16_step(unsigned short *);
+int __cdecl _rdrand32_step(unsigned int *);
+static __inline__
+unsigned int __cdecl _rotl(unsigned int _Value, int _Shift);
+static __inline__
+unsigned short _rotl16(unsigned short _Value, unsigned char _Shift);
+static __inline__
+unsigned __int64 __cdecl _rotl64(unsigned __int64 _Value, int _Shift);
+static __inline__
+unsigned char _rotl8(unsigned char _Value, unsigned char _Shift);
+static __inline__
+unsigned int __cdecl _rotr(unsigned int _Value, int _Shift);
+static __inline__
+unsigned short _rotr16(unsigned short _Value, unsigned char _Shift);
+static __inline__
+unsigned __int64 __cdecl _rotr64(unsigned __int64 _Value, int _Shift);
+static __inline__
+unsigned char _rotr8(unsigned char _Value, unsigned char _Shift);
+int _sarx_i32(int, unsigned int);
+#if __STDC_HOSTED__
+int __cdecl _setjmp(jmp_buf);
+#endif
+unsigned int _shlx_u32(unsigned int, unsigned int);
+unsigned int _shrx_u32(unsigned int, unsigned int);
+void _Store_HLERelease(long volatile *, long);
+void _Store64_HLERelease(__int64 volatile *, __int64);
+void _StorePointer_HLERelease(void *volatile *, void *);
+unsigned int _t1mskc_u32(unsigned int);
+unsigned int _tzcnt_u32(unsigned int);
+unsigned int _tzmsk_u32(unsigned int);
+static __inline__
+void _WriteBarrier(void);
+void _xabort(const unsigned int imm);
+unsigned __int32 xbegin(void);
+void _xend(void);
+static __inline__
+unsigned __int64 __cdecl _xgetbv(unsigned int);
+void __cdecl _xrstor(void const *, unsigned __int64);
+void __cdecl _xsave(void *, unsigned __int64);
+void __cdecl _xsaveopt(void *, unsigned __int64);
+void __cdecl _xsetbv(unsigned int, unsigned __int64);
+unsigned char _xtest(void);
+
+/* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */
+#ifdef __x86_64__
+void __addgsbyte(unsigned long, unsigned char);
+void __addgsdword(unsigned long, unsigned long);
+void __addgsqword(unsigned long, unsigned __int64);
+void __addgsword(unsigned long, unsigned short);
+static __inline__
+void __faststorefence(void);
+void __incgsbyte(unsigned long);
+void __incgsdword(unsigned long);
+void __incgsqword(unsigned long);
+void __incgsword(unsigned long);
+unsigned char __lwpins64(unsigned __int64, unsigned int, unsigned int);
+void __lwpval64(unsigned __int64, unsigned int, unsigned int);
+unsigned __int64 __lzcnt64(unsigned __int64);
+static __inline__
+void __movsq(unsigned long long *, unsigned long long const *, size_t);
+__int64 __mulh(__int64, __int64);
+static __inline__
+unsigned __int64 __popcnt64(unsigned __int64);
+static __inline__
+unsigned char __readgsbyte(unsigned long);
+static __inline__
+unsigned long __readgsdword(unsigned long);
+static __inline__
+unsigned __int64 __readgsqword(unsigned long);
+unsigned short __readgsword(unsigned long);
+unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
+                                unsigned __int64 _HighPart,
+                                unsigned char _Shift);
+unsigned __int64 __shiftright128(unsigned __int64 _LowPart,
+                                 unsigned __int64 _HighPart,
+                                 unsigned char _Shift);
+static __inline__
+void __stosq(unsigned __int64 *, unsigned __int64, size_t);
+unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
+unsigned char __vmx_on(unsigned __int64 *);
+unsigned char __vmx_vmclear(unsigned __int64 *);
+unsigned char __vmx_vmlaunch(void);
+unsigned char __vmx_vmptrld(unsigned __int64 *);
+unsigned char __vmx_vmread(size_t, size_t *);
+unsigned char __vmx_vmresume(void);
+unsigned char __vmx_vmwrite(size_t, size_t);
+void __writegsbyte(unsigned long, unsigned char);
+void __writegsdword(unsigned long, unsigned long);
+void __writegsqword(unsigned long, unsigned __int64);
+void __writegsword(unsigned long, unsigned short);
+unsigned __int64 _andn_u64(unsigned __int64, unsigned __int64);
+unsigned __int64 _bextr_u64(unsigned __int64, unsigned int, unsigned int);
+unsigned __int64 _bextri_u64(unsigned __int64, unsigned int);
+static __inline__
+unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
+static __inline__
+unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
+static __inline__
+unsigned char _bittest64(__int64 const *, __int64);
+static __inline__
+unsigned char _bittestandcomplement64(__int64 *, __int64);
+static __inline__
+unsigned char _bittestandreset64(__int64 *, __int64);
+static __inline__
+unsigned char _bittestandset64(__int64 *, __int64);
+unsigned __int64 _blcfill_u64(unsigned __int64);
+unsigned __int64 _blci_u64(unsigned __int64);
+unsigned __int64 _blcic_u64(unsigned __int64);
+unsigned __int64 _blcmsk_u64(unsigned __int64);
+unsigned __int64 _blcs_u64(unsigned __int64);
+unsigned __int64 _blsfill_u64(unsigned __int64);
+unsigned __int64 _blsi_u64(unsigned __int64);
+unsigned __int64 _blsic_u64(unsigned __int64);
+unsigned __int64 _blsmsk_u64(unsigned __int64);
+unsigned __int64 _blsr_u64(unsigned __int64);
+unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
+unsigned __int64 _bzhi_u64(unsigned __int64, unsigned int);
+void __cdecl _fxrstor64(void const *);
+void __cdecl _fxsave64(void *);
+long _InterlockedAnd_np(long volatile *_Value, long _Mask);
+short _InterlockedAnd16_np(short volatile *_Value, short _Mask);
+__int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
+char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
+unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
+static __inline__
+unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
+long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange,
+                                    long _Comparand);
+unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination,
+                                             __int64 _ExchangeHigh,
+                                             __int64 _ExchangeLow,
+                                             __int64 *_CompareandResult);
+unsigned char _InterlockedCompareExchange128_np(__int64 volatile *_Destination,
+                                                __int64 _ExchangeHigh,
+                                                __int64 _ExchangeLow,
+                                                __int64 *_ComparandResult);
+short _InterlockedCompareExchange16_np(short volatile *_Destination,
+                                       short _Exchange, short _Comparand);
+__int64 _InterlockedCompareExchange64_HLEAcquire(__int64 volatile *, __int64,
+                                                 __int64);
+__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64,
+                                                 __int64);
+__int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
+                                         __int64 _Exchange, __int64 _Comparand);
+void *_InterlockedCompareExchangePointer(void *volatile *_Destination,
+                                         void *_Exchange, void *_Comparand);
+void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
+                                            void *_Exchange, void *_Comparand);
+static __inline__
+__int64 _InterlockedDecrement64(__int64 volatile *_Addend);
+static __inline__
+__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
+static __inline__
+__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
+void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value);
+static __inline__
+__int64 _InterlockedIncrement64(__int64 volatile *_Addend);
+long _InterlockedOr_np(long volatile *_Value, long _Mask);
+short _InterlockedOr16_np(short volatile *_Value, short _Mask);
+static __inline__
+__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask);
+__int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
+char _InterlockedOr8_np(char volatile *_Value, char _Mask);
+long _InterlockedXor_np(long volatile *_Value, long _Mask);
+short _InterlockedXor16_np(short volatile *_Value, short _Mask);
+static __inline__
+__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask);
+__int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask);
+char _InterlockedXor8_np(char volatile *_Value, char _Mask);
+static __inline__
+unsigned __int64 _lzcnt_u64(unsigned __int64);
+__int64 _mul128(__int64 _Multiplier, __int64 _Multiplicand,
+                __int64 *_HighProduct);
+unsigned int __cdecl _readfsbase_u32(void);
+unsigned __int64 __cdecl _readfsbase_u64(void);
+unsigned int __cdecl _readgsbase_u32(void);
+unsigned __int64 __cdecl _readgsbase_u64(void);
+unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
+__int64 _sarx_i64(__int64, unsigned int);
+#if __STDC_HOSTED__
+int __cdecl _setjmpex(jmp_buf);
+#endif
+unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
+unsigned __int64 shrx_u64(unsigned __int64, unsigned int);
+unsigned __int64 _tzcnt_u64(unsigned __int64);
+unsigned __int64 _tzmsk_u64(unsigned __int64);
+unsigned __int64 _umul128(unsigned __int64 _Multiplier,
+                          unsigned __int64 _Multiplicand,
+                          unsigned __int64 *_HighProduct);
+void __cdecl _writefsbase_u32(unsigned int);
+void _cdecl _writefsbase_u64(unsigned __int64);
+void __cdecl _writegsbase_u32(unsigned int);
+void __cdecl _writegsbase_u64(unsigned __int64);
+void __cdecl _xrstor64(void const *, unsigned __int64);
+void __cdecl _xsave64(void *, unsigned __int64);
+void __cdecl _xsaveopt64(void *, unsigned __int64);
+
+#endif /* __x86_64__ */
+
+/*----------------------------------------------------------------------------*\
+|* Bit Twiddling
+\*----------------------------------------------------------------------------*/
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_rotl8(unsigned char _Value, unsigned char _Shift) {
+  _Shift &= 0x7;
+  return _Shift ? (_Value << _Shift) | (_Value >> (8 - _Shift)) : _Value;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_rotr8(unsigned char _Value, unsigned char _Shift) {
+  _Shift &= 0x7;
+  return _Shift ? (_Value >> _Shift) | (_Value << (8 - _Shift)) : _Value;
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+_rotl16(unsigned short _Value, unsigned char _Shift) {
+  _Shift &= 0xf;
+  return _Shift ? (_Value << _Shift) | (_Value >> (16 - _Shift)) : _Value;
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+_rotr16(unsigned short _Value, unsigned char _Shift) {
+  _Shift &= 0xf;
+  return _Shift ? (_Value >> _Shift) | (_Value << (16 - _Shift)) : _Value;
+}
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_rotl(unsigned int _Value, int _Shift) {
+  _Shift &= 0x1f;
+  return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value;
+}
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_rotr(unsigned int _Value, int _Shift) {
+  _Shift &= 0x1f;
+  return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value;
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+_lrotl(unsigned long _Value, int _Shift) {
+  _Shift &= 0x1f;
+  return _Shift ? (_Value << _Shift) | (_Value >> (32 - _Shift)) : _Value;
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+_lrotr(unsigned long _Value, int _Shift) {
+  _Shift &= 0x1f;
+  return _Shift ? (_Value >> _Shift) | (_Value << (32 - _Shift)) : _Value;
+}
+static
+__inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+_rotl64(unsigned __int64 _Value, int _Shift) {
+  _Shift &= 0x3f;
+  return _Shift ? (_Value << _Shift) | (_Value >> (64 - _Shift)) : _Value;
+}
+static
+__inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+_rotr64(unsigned __int64 _Value, int _Shift) {
+  _Shift &= 0x3f;
+  return _Shift ? (_Value >> _Shift) | (_Value << (64 - _Shift)) : _Value;
+}
+/*----------------------------------------------------------------------------*\
+|* Bit Counting and Testing
+\*----------------------------------------------------------------------------*/
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_BitScanForward(unsigned long *_Index, unsigned long _Mask) {
+  if (!_Mask)
+    return 0;
+  *_Index = __builtin_ctzl(_Mask);
+  return 1;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_BitScanReverse(unsigned long *_Index, unsigned long _Mask) {
+  if (!_Mask)
+    return 0;
+  *_Index = 31 - __builtin_clzl(_Mask);
+  return 1;
+}
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_lzcnt_u32(unsigned int a) {
+  if (!a)
+    return 32;
+  return __builtin_clzl(a);
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__popcnt16(unsigned short value) {
+  return __builtin_popcount((int)value);
+}
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__popcnt(unsigned int value) {
+  return __builtin_popcount(value);
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittest(long const *a, long b) {
+  return (*a >> b) & 1;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandcomplement(long *a, long b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a ^ (1 << b);
+  return x;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandreset(long *a, long b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a & ~(1 << b);
+  return x;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandset(long *a, long b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a | (1 << b);
+  return x;
+}
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_interlockedbittestandset(long volatile *__BitBase, long __BitPos) {
+  unsigned char __Res;
+  __asm__ ("xor %0, %0\n"
+           "lock bts %2, %1\n"
+           "setc %0\n"
+           : "=r" (__Res), "+m"(*__BitBase)
+           : "Ir"(__BitPos));
+  return __Res;
+}
+#endif
+#ifdef __x86_64__
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) {
+  if (!_Mask)
+    return 0;
+  *_Index = __builtin_ctzll(_Mask);
+  return 1;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask) {
+  if (!_Mask)
+    return 0;
+  *_Index = 63 - __builtin_clzll(_Mask);
+  return 1;
+}
+static
+__inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+_lzcnt_u64(unsigned __int64 a) {
+  if (!a)
+    return 64;
+  return __builtin_clzll(a);
+}
+static __inline__
+unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+ __popcnt64(unsigned __int64 value) {
+  return __builtin_popcountll(value);
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittest64(__int64 const *a, __int64 b) {
+  return (*a >> b) & 1;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandcomplement64(__int64 *a, __int64 b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a ^ (1ll << b);
+  return x;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandreset64(__int64 *a, __int64 b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a & ~(1ll << b);
+  return x;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_bittestandset64(__int64 *a, __int64 b) {
+  unsigned char x = (*a >> b) & 1;
+  *a = *a | (1ll << b);
+  return x;
+}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_interlockedbittestandset64(__int64 volatile *__BitBase, __int64 __BitPos) {
+  unsigned char __Res;
+  __asm__ ("xor %0, %0\n"
+           "lock bts %2, %1\n"
+           "setc %0\n"
+           : "=r" (__Res), "+m"(*__BitBase)
+           : "Ir"(__BitPos));
+  return __Res;
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Exchange Add
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeAdd8(char volatile *_Addend, char _Value) {
+  return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeAdd16(short volatile *_Addend, short _Value) {
+  return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) {
+  return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Exchange Sub
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeSub8(char volatile *_Subend, char _Value) {
+  return __atomic_sub_fetch(_Subend, _Value, 0) + _Value;
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeSub16(short volatile *_Subend, short _Value) {
+  return __atomic_sub_fetch(_Subend, _Value, 0) + _Value;
+}
+static __inline__ long __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeSub(long volatile *_Subend, long _Value) {
+  return __atomic_sub_fetch(_Subend, _Value, 0) + _Value;
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value) {
+  return __atomic_sub_fetch(_Subend, _Value, 0) + _Value;
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Increment
+\*----------------------------------------------------------------------------*/
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedIncrement16(short volatile *_Value) {
+  return __atomic_add_fetch(_Value, 1, 0);
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedIncrement64(__int64 volatile *_Value) {
+  return __atomic_add_fetch(_Value, 1, 0);
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Decrement
+\*----------------------------------------------------------------------------*/
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedDecrement16(short volatile *_Value) {
+  return __atomic_sub_fetch(_Value, 1, 0);
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedDecrement64(__int64 volatile *_Value) {
+  return __atomic_sub_fetch(_Value, 1, 0);
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked And
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedAnd8(char volatile *_Value, char _Mask) {
+  return __atomic_and_fetch(_Value, _Mask, 0);
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedAnd16(short volatile *_Value, short _Mask) {
+  return __atomic_and_fetch(_Value, _Mask, 0);
+}
+static __inline__ long __attribute__((__always_inline__, __nodebug__))
+_InterlockedAnd(long volatile *_Value, long _Mask) {
+  return __atomic_and_fetch(_Value, _Mask, 0);
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask) {
+  return __atomic_and_fetch(_Value, _Mask, 0);
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Or
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedOr8(char volatile *_Value, char _Mask) {
+  return __atomic_or_fetch(_Value, _Mask, 0);
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedOr16(short volatile *_Value, short _Mask) {
+  return __atomic_or_fetch(_Value, _Mask, 0);
+}
+static __inline__ long __attribute__((__always_inline__, __nodebug__))
+_InterlockedOr(long volatile *_Value, long _Mask) {
+  return __atomic_or_fetch(_Value, _Mask, 0);
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedOr64(__int64 volatile *_Value, __int64 _Mask) {
+  return __atomic_or_fetch(_Value, _Mask, 0);
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Xor
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedXor8(char volatile *_Value, char _Mask) {
+  return __atomic_xor_fetch(_Value, _Mask, 0);
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedXor16(short volatile *_Value, short _Mask) {
+  return __atomic_xor_fetch(_Value, _Mask, 0);
+}
+static __inline__ long __attribute__((__always_inline__, __nodebug__))
+_InterlockedXor(long volatile *_Value, long _Mask) {
+  return __atomic_xor_fetch(_Value, _Mask, 0);
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedXor64(__int64 volatile *_Value, __int64 _Mask) {
+  return __atomic_xor_fetch(_Value, _Mask, 0);
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Exchange
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchange8(char volatile *_Target, char _Value) {
+  __atomic_exchange(_Target, &_Value, &_Value, 0);
+  return _Value;
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchange16(short volatile *_Target, short _Value) {
+  __atomic_exchange(_Target, &_Value, &_Value, 0);
+  return _Value;
+}
+#ifdef __x86_64__
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedExchange64(__int64 volatile *_Target, __int64 _Value) {
+  __atomic_exchange(_Target, &_Value, &_Value, 0);
+  return _Value;
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* Interlocked Compare Exchange
+\*----------------------------------------------------------------------------*/
+static __inline__ char __attribute__((__always_inline__, __nodebug__))
+_InterlockedCompareExchange8(char volatile *_Destination,
+                             char _Exchange, char _Comparand) {
+  __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
+  return _Comparand;
+}
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedCompareExchange16(short volatile *_Destination,
+                              short _Exchange, short _Comparand) {
+  __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
+  return _Comparand;
+}
+static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
+_InterlockedCompareExchange64(__int64 volatile *_Destination,
+                              __int64 _Exchange, __int64 _Comparand) {
+  __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
+  return _Comparand;
+}
+/*----------------------------------------------------------------------------*\
+|* Barriers
+\*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__attribute__((deprecated("use other intrinsics or C++11 atomics instead")))
+_ReadWriteBarrier(void) {
+  __asm__ volatile ("" : : : "memory");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__attribute__((deprecated("use other intrinsics or C++11 atomics instead")))
+_ReadBarrier(void) {
+  __asm__ volatile ("" : : : "memory");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__attribute__((deprecated("use other intrinsics or C++11 atomics instead")))
+_WriteBarrier(void) {
+  __asm__ volatile ("" : : : "memory");
+}
+#endif
+#ifdef __x86_64__
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__faststorefence(void) {
+  __asm__ volatile("lock orq $0, (%%rsp)" : : : "memory");
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* readfs, readgs
+|* (Pointers in address space #256 and #257 are relative to the GS and FS
+|* segment registers, respectively.)
+\*----------------------------------------------------------------------------*/
+#define __ptr_to_addr_space(__addr_space_nbr, __type, __offset)              \
+    ((volatile __type __attribute__((__address_space__(__addr_space_nbr)))*) \
+    (__offset))
+
+#ifdef __i386__
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__readfsbyte(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned char, __offset);
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+__readfsdword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned long, __offset);
+}
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readfsqword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned __int64, __offset);
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__readfsword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned short, __offset);
+}
+#endif
+#ifdef __x86_64__
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__readgsbyte(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned char, __offset);
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+__readgsdword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned long, __offset);
+}
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readgsqword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned __int64, __offset);
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__readgsword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned short, __offset);
+}
+#endif
+#undef __ptr_to_addr_space
+/*----------------------------------------------------------------------------*\
+|* movs, stos
+\*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
+  __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
+  __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
+  __asm__("rep movsh" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosb(unsigned char *__dst, unsigned char __x, size_t __n) {
+  __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
+  __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
+  __asm__("rep stosh" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+#endif
+#ifdef __x86_64__
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
+  __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
+  __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+#endif
+
+/*----------------------------------------------------------------------------*\
+|* Misc
+\*----------------------------------------------------------------------------*/
+static __inline__ void * __attribute__((__always_inline__, __nodebug__))
+_AddressOfReturnAddress(void) {
+  return (void*)((char*)__builtin_frame_address(0) + sizeof(void*));
+}
+static __inline__ void * __attribute__((__always_inline__, __nodebug__))
+_ReturnAddress(void) {
+  return __builtin_return_address(0);
+}
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__cpuid(int __info[4], int __level) {
+  __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
+                   : "a"(__level));
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__cpuidex(int __info[4], int __level, int __ecx) {
+  __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
+                   : "a"(__level), "c"(__ecx));
+}
+static __inline__ unsigned __int64 __cdecl __attribute__((__always_inline__, __nodebug__))
+_xgetbv(unsigned int __xcr_no) {
+  unsigned int __eax, __edx;
+  __asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no));
+  return ((unsigned __int64)__edx << 32) | __eax;
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__halt(void) {
+  __asm__ volatile ("hlt");
+}
+#endif
+
+/*----------------------------------------------------------------------------*\
+|* Privileged intrinsics
+\*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readmsr(unsigned long __register) {
+  // Loads the contents of a 64-bit model specific register (MSR) specified in
+  // the ECX register into registers EDX:EAX. The EDX register is loaded with
+  // the high-order 32 bits of the MSR and the EAX register is loaded with the
+  // low-order 32 bits. If less than 64 bits are implemented in the MSR being
+  // read, the values returned to EDX:EAX in unimplemented bit locations are
+  // undefined.
+  unsigned long __edx;
+  unsigned long __eax;
+  __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
+  return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
+}
+
+static __inline__ unsigned long __attribute__((always_inline, __nodebug__))
+__readcr3(void) {
+  unsigned long __cr3_val;
+  __asm__ __volatile__ ("mov %%cr3, %0" : "=q"(__cr3_val) : : "memory");
+  return __cr3_val;
+}
+
+static __inline__ void __attribute__((always_inline, __nodebug__))
+__writecr3(unsigned int __cr3_val) {
+  __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory");
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INTRIN_H */
+#endif /* _MSC_VER */
diff --git a/lib/clang/3.5.2/include/__wmmintrin_aes.h b/lib/clang/3.5.2/include/__wmmintrin_aes.h
new file mode 100644
index 0000000..2bfa027
--- /dev/null
+++ b/lib/clang/3.5.2/include/__wmmintrin_aes.h
@@ -0,0 +1,67 @@
+/*===---- __wmmintrin_aes.h - AES intrinsics -------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+#ifndef _WMMINTRIN_AES_H
+#define _WMMINTRIN_AES_H
+
+#include <emmintrin.h>
+
+#if !defined (__AES__)
+#  error "AES instructions not enabled"
+#else
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesenc_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesenc128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesenclast_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesenclast128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesdec_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesdec128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesdeclast_si128(__m128i __V, __m128i __R)
+{
+  return (__m128i)__builtin_ia32_aesdeclast128(__V, __R);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_aesimc_si128(__m128i __V)
+{
+  return (__m128i)__builtin_ia32_aesimc128(__V);
+}
+
+#define _mm_aeskeygenassist_si128(C, R) \
+  __builtin_ia32_aeskeygenassist128((C), (R))
+
+#endif
+
+#endif  /* _WMMINTRIN_AES_H */
diff --git a/lib/clang/3.5.2/include/__wmmintrin_pclmul.h b/lib/clang/3.5.2/include/__wmmintrin_pclmul.h
new file mode 100644
index 0000000..8d1f1b7
--- /dev/null
+++ b/lib/clang/3.5.2/include/__wmmintrin_pclmul.h
@@ -0,0 +1,34 @@
+/*===---- __wmmintrin_pclmul.h - AES intrinsics ----------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+#ifndef _WMMINTRIN_PCLMUL_H
+#define _WMMINTRIN_PCLMUL_H
+
+#if !defined (__PCLMUL__)
+# error "PCLMUL instruction is not enabled"
+#else
+#define _mm_clmulepi64_si128(__X, __Y, __I) \
+  ((__m128i)__builtin_ia32_pclmulqdq128((__v2di)(__m128i)(__X), \
+                                        (__v2di)(__m128i)(__Y), (char)(__I)))
+#endif
+
+#endif /* _WMMINTRIN_PCLMUL_H */
diff --git a/lib/clang/3.5.2/include/altivec.h b/lib/clang/3.5.2/include/altivec.h
new file mode 100644
index 0000000..f9fc64a
--- /dev/null
+++ b/lib/clang/3.5.2/include/altivec.h
@@ -0,0 +1,12285 @@
+/*===---- altivec.h - Standard header for type generic math ---------------===*\
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __ALTIVEC_H
+#define __ALTIVEC_H
+
+#ifndef __ALTIVEC__
+#error "AltiVec support not enabled"
+#endif
+
+/* constants for mapping CR6 bits to predicate result. */
+
+#define __CR6_EQ     0
+#define __CR6_EQ_REV 1
+#define __CR6_LT     2
+#define __CR6_LT_REV 3
+
+#define __ATTRS_o_ai __attribute__((__overloadable__, __always_inline__))
+
+static vector signed char __ATTRS_o_ai
+vec_perm(vector signed char __a, vector signed char __b, vector unsigned char __c);
+
+static vector unsigned char __ATTRS_o_ai
+vec_perm(vector unsigned char __a,
+         vector unsigned char __b,
+         vector unsigned char __c);
+
+static vector bool char __ATTRS_o_ai
+vec_perm(vector bool char __a, vector bool char __b, vector unsigned char __c);
+
+static vector short __ATTRS_o_ai
+vec_perm(vector short __a, vector short __b, vector unsigned char __c);
+
+static vector unsigned short __ATTRS_o_ai
+vec_perm(vector unsigned short __a,
+         vector unsigned short __b,
+         vector unsigned char __c);
+
+static vector bool short __ATTRS_o_ai
+vec_perm(vector bool short __a, vector bool short __b, vector unsigned char __c);
+
+static vector pixel __ATTRS_o_ai
+vec_perm(vector pixel __a, vector pixel __b, vector unsigned char __c);
+
+static vector int __ATTRS_o_ai
+vec_perm(vector int __a, vector int __b, vector unsigned char __c);
+
+static vector unsigned int __ATTRS_o_ai
+vec_perm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c);
+
+static vector bool int __ATTRS_o_ai
+vec_perm(vector bool int __a, vector bool int __b, vector unsigned char __c);
+
+static vector float __ATTRS_o_ai
+vec_perm(vector float __a, vector float __b, vector unsigned char __c);
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char __a, vector unsigned char __b);
+
+/* vec_abs */
+
+#define __builtin_altivec_abs_v16qi vec_abs
+#define __builtin_altivec_abs_v8hi  vec_abs
+#define __builtin_altivec_abs_v4si  vec_abs
+
+static vector signed char __ATTRS_o_ai
+vec_abs(vector signed char __a)
+{
+  return __builtin_altivec_vmaxsb(__a, -__a);
+}
+
+static vector signed short __ATTRS_o_ai
+vec_abs(vector signed short __a)
+{
+  return __builtin_altivec_vmaxsh(__a, -__a);
+}
+
+static vector signed int __ATTRS_o_ai
+vec_abs(vector signed int __a)
+{
+  return __builtin_altivec_vmaxsw(__a, -__a);
+}
+
+static vector float __ATTRS_o_ai
+vec_abs(vector float __a)
+{
+  vector unsigned int __res = (vector unsigned int)__a
+                            & (vector unsigned int)(0x7FFFFFFF);
+  return (vector float)__res;
+}
+
+/* vec_abss */
+
+#define __builtin_altivec_abss_v16qi vec_abss
+#define __builtin_altivec_abss_v8hi  vec_abss
+#define __builtin_altivec_abss_v4si  vec_abss
+
+static vector signed char __ATTRS_o_ai
+vec_abss(vector signed char __a)
+{
+  return __builtin_altivec_vmaxsb
+           (__a, __builtin_altivec_vsubsbs((vector signed char)(0), __a));
+}
+
+static vector signed short __ATTRS_o_ai
+vec_abss(vector signed short __a)
+{
+  return __builtin_altivec_vmaxsh
+           (__a, __builtin_altivec_vsubshs((vector signed short)(0), __a));
+}
+
+static vector signed int __ATTRS_o_ai
+vec_abss(vector signed int __a)
+{
+  return __builtin_altivec_vmaxsw
+           (__a, __builtin_altivec_vsubsws((vector signed int)(0), __a));
+}
+
+/* vec_add */
+
+static vector signed char __ATTRS_o_ai
+vec_add(vector signed char __a, vector signed char __b)
+{
+  return __a + __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_add(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a + __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_add(vector signed char __a, vector bool char __b)
+{
+  return __a + (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_add(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_add(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a + __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_add(vector unsigned char __a, vector bool char __b)
+{
+  return __a + (vector unsigned char)__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_add(vector short __a, vector short __b)
+{
+  return __a + __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_add(vector bool short __a, vector short __b)
+{
+  return (vector short)__a + __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_add(vector short __a, vector bool short __b)
+{
+  return __a + (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_add(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_add(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a + __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_add(vector unsigned short __a, vector bool short __b)
+{
+  return __a + (vector unsigned short)__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_add(vector int __a, vector int __b)
+{
+  return __a + __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_add(vector bool int __a, vector int __b)
+{
+  return (vector int)__a + __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_add(vector int __a, vector bool int __b)
+{
+  return __a + (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_add(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_add(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a + __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_add(vector unsigned int __a, vector bool int __b)
+{
+  return __a + (vector unsigned int)__b;
+}
+
+static vector float __ATTRS_o_ai
+vec_add(vector float __a, vector float __b)
+{
+  return __a + __b;
+}
+
+/* vec_vaddubm */
+
+#define __builtin_altivec_vaddubm vec_vaddubm
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector signed char __a, vector signed char __b)
+{
+  return __a + __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a + __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddubm(vector signed char __a, vector bool char __b)
+{
+  return __a + (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a + __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubm(vector unsigned char __a, vector bool char __b)
+{
+  return __a + (vector unsigned char)__b;
+}
+
+/* vec_vadduhm */
+
+#define __builtin_altivec_vadduhm vec_vadduhm
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector short __a, vector short __b)
+{
+  return __a + __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector bool short __a, vector short __b)
+{
+  return (vector short)__a + __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vadduhm(vector short __a, vector bool short __b)
+{
+  return __a + (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a + __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhm(vector unsigned short __a, vector bool short __b)
+{
+  return __a + (vector unsigned short)__b;
+}
+
+/* vec_vadduwm */
+
+#define __builtin_altivec_vadduwm vec_vadduwm
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector int __a, vector int __b)
+{
+  return __a + __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector bool int __a, vector int __b)
+{
+  return (vector int)__a + __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vadduwm(vector int __a, vector bool int __b)
+{
+  return __a + (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a + __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a + __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduwm(vector unsigned int __a, vector bool int __b)
+{
+  return __a + (vector unsigned int)__b;
+}
+
+/* vec_vaddfp */
+
+#define __builtin_altivec_vaddfp  vec_vaddfp
+
+static vector float __attribute__((__always_inline__))
+vec_vaddfp(vector float __a, vector float __b)
+{
+  return __a + __b;
+}
+
+/* vec_addc */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_addc(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vaddcuw(__a, __b);
+}
+
+/* vec_vaddcuw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vaddcuw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vaddcuw(__a, __b);
+}
+
+/* vec_adds */
+
+static vector signed char __ATTRS_o_ai
+vec_adds(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vaddsbs(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_adds(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vaddsbs((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_adds(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vaddsbs(__a, (vector signed char)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_adds(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vaddubs(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_adds(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vaddubs((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_adds(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vaddubs(__a, (vector unsigned char)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_adds(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vaddshs(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_adds(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vaddshs((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_adds(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vaddshs(__a, (vector short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_adds(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vadduhs(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_adds(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vadduhs((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_adds(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vadduhs(__a, (vector unsigned short)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_adds(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vaddsws(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_adds(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vaddsws((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_adds(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vaddsws(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_adds(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vadduws(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_adds(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vadduws((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_adds(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vadduws(__a, (vector unsigned int)__b);
+}
+
+/* vec_vaddsbs */
+
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vaddsbs(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vaddsbs((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vaddsbs(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vaddsbs(__a, (vector signed char)__b);
+}
+
+/* vec_vaddubs */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vaddubs(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vaddubs((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vaddubs(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vaddubs(__a, (vector unsigned char)__b);
+}
+
+/* vec_vaddshs */
+
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vaddshs(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vaddshs((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vaddshs(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vaddshs(__a, (vector short)__b);
+}
+
+/* vec_vadduhs */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vadduhs(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vadduhs((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vadduhs(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vadduhs(__a, (vector unsigned short)__b);
+}
+
+/* vec_vaddsws */
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vaddsws(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vaddsws((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vaddsws(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vaddsws(__a, (vector int)__b);
+}
+
+/* vec_vadduws */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vadduws(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vadduws((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vadduws(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vadduws(__a, (vector unsigned int)__b);
+}
+
+/* vec_and */
+
+#define __builtin_altivec_vand vec_and
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector signed char __a, vector signed char __b)
+{
+  return __a & __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a & __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_and(vector signed char __a, vector bool char __b)
+{
+  return __a & (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a & __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_and(vector unsigned char __a, vector bool char __b)
+{
+  return __a & (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_and(vector bool char __a, vector bool char __b)
+{
+  return __a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector short __a, vector short __b)
+{
+  return __a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector bool short __a, vector short __b)
+{
+  return (vector short)__a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_and(vector short __a, vector bool short __b)
+{
+  return __a & (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a & __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_and(vector unsigned short __a, vector bool short __b)
+{
+  return __a & (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_and(vector bool short __a, vector bool short __b)
+{
+  return __a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector int __a, vector int __b)
+{
+  return __a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector bool int __a, vector int __b)
+{
+  return (vector int)__a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_and(vector int __a, vector bool int __b)
+{
+  return __a & (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a & __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_and(vector unsigned int __a, vector bool int __b)
+{
+  return __a & (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_and(vector bool int __a, vector bool int __b)
+{
+  return __a & __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_and(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_vand */
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector signed char __a, vector signed char __b)
+{
+  return __a & __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a & __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vand(vector signed char __a, vector bool char __b)
+{
+  return __a & (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a & __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vand(vector unsigned char __a, vector bool char __b)
+{
+  return __a & (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vand(vector bool char __a, vector bool char __b)
+{
+  return __a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector short __a, vector short __b)
+{
+  return __a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector bool short __a, vector short __b)
+{
+  return (vector short)__a & __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vand(vector short __a, vector bool short __b)
+{
+  return __a & (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a & __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vand(vector unsigned short __a, vector bool short __b)
+{
+  return __a & (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vand(vector bool short __a, vector bool short __b)
+{
+  return __a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector int __a, vector int __b)
+{
+  return __a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector bool int __a, vector int __b)
+{
+  return (vector int)__a & __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vand(vector int __a, vector bool int __b)
+{
+  return __a & (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a & __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a & __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vand(vector unsigned int __a, vector bool int __b)
+{
+  return __a & (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vand(vector bool int __a, vector bool int __b)
+{
+  return __a & __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vand(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_andc */
+
+#define __builtin_altivec_vandc vec_andc
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector signed char __a, vector signed char __b)
+{
+  return __a & ~__b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a & ~__b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_andc(vector signed char __a, vector bool char __b)
+{
+  return __a & ~(vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a & ~__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_andc(vector unsigned char __a, vector bool char __b)
+{
+  return __a & ~(vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_andc(vector bool char __a, vector bool char __b)
+{
+  return __a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector short __a, vector short __b)
+{
+  return __a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector bool short __a, vector short __b)
+{
+  return (vector short)__a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_andc(vector short __a, vector bool short __b)
+{
+  return __a & ~(vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a & ~__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_andc(vector unsigned short __a, vector bool short __b)
+{
+  return __a & ~(vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_andc(vector bool short __a, vector bool short __b)
+{
+  return __a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector int __a, vector int __b)
+{
+  return __a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector bool int __a, vector int __b)
+{
+  return (vector int)__a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_andc(vector int __a, vector bool int __b)
+{
+  return __a & ~(vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a & ~__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_andc(vector unsigned int __a, vector bool int __b)
+{
+  return __a & ~(vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_andc(vector bool int __a, vector bool int __b)
+{
+  return __a & ~__b;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_andc(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_vandc */
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector signed char __a, vector signed char __b)
+{
+  return __a & ~__b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a & ~__b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vandc(vector signed char __a, vector bool char __b)
+{
+  return __a & ~(vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a & ~__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vandc(vector unsigned char __a, vector bool char __b)
+{
+  return __a & ~(vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vandc(vector bool char __a, vector bool char __b)
+{
+  return __a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector short __a, vector short __b)
+{
+  return __a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector bool short __a, vector short __b)
+{
+  return (vector short)__a & ~__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vandc(vector short __a, vector bool short __b)
+{
+  return __a & ~(vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a & ~__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vandc(vector unsigned short __a, vector bool short __b)
+{
+  return __a & ~(vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vandc(vector bool short __a, vector bool short __b)
+{
+  return __a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector int __a, vector int __b)
+{
+  return __a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector bool int __a, vector int __b)
+{
+  return (vector int)__a & ~__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vandc(vector int __a, vector bool int __b)
+{
+  return __a & ~(vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a & ~__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a & ~__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vandc(vector unsigned int __a, vector bool int __b)
+{
+  return __a & ~(vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vandc(vector bool int __a, vector bool int __b)
+{
+  return __a & ~__b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vandc(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a & ~(vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_avg */
+
+static vector signed char __ATTRS_o_ai
+vec_avg(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vavgsb(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_avg(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vavgub(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_avg(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vavgsh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_avg(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vavguh(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_avg(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vavgsw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_avg(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vavguw(__a, __b);
+}
+
+/* vec_vavgsb */
+
+static vector signed char __attribute__((__always_inline__))
+vec_vavgsb(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vavgsb(__a, __b);
+}
+
+/* vec_vavgub */
+
+static vector unsigned char __attribute__((__always_inline__))
+vec_vavgub(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vavgub(__a, __b);
+}
+
+/* vec_vavgsh */
+
+static vector short __attribute__((__always_inline__))
+vec_vavgsh(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vavgsh(__a, __b);
+}
+
+/* vec_vavguh */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vavguh(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vavguh(__a, __b);
+}
+
+/* vec_vavgsw */
+
+static vector int __attribute__((__always_inline__))
+vec_vavgsw(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vavgsw(__a, __b);
+}
+
+/* vec_vavguw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vavguw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vavguw(__a, __b);
+}
+
+/* vec_ceil */
+
+static vector float __attribute__((__always_inline__))
+vec_ceil(vector float __a)
+{
+  return __builtin_altivec_vrfip(__a);
+}
+
+/* vec_vrfip */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfip(vector float __a)
+{
+  return __builtin_altivec_vrfip(__a);
+}
+
+/* vec_cmpb */
+
+static vector int __attribute__((__always_inline__))
+vec_cmpb(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpbfp(__a, __b);
+}
+
+/* vec_vcmpbfp */
+
+static vector int __attribute__((__always_inline__))
+vec_vcmpbfp(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpbfp(__a, __b);
+}
+
+/* vec_cmpeq */
+
+static vector bool char __ATTRS_o_ai
+vec_cmpeq(vector signed char __a, vector signed char __b)
+{
+  return (vector bool char)
+    __builtin_altivec_vcmpequb((vector char)__a, (vector char)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_cmpeq(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector bool char)
+    __builtin_altivec_vcmpequb((vector char)__a, (vector char)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmpeq(vector short __a, vector short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpequh(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmpeq(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector bool short)
+    __builtin_altivec_vcmpequh((vector short)__a, (vector short)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpeq(vector int __a, vector int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpequw(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpeq(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector bool int)
+    __builtin_altivec_vcmpequw((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpeq(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpeqfp(__a, __b);
+}
+
+/* vec_cmpge */
+
+static vector bool int __attribute__((__always_inline__))
+vec_cmpge(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b);
+}
+
+/* vec_vcmpgefp */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgefp(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b);
+}
+
+/* vec_cmpgt */
+
+static vector bool char __ATTRS_o_ai
+vec_cmpgt(vector signed char __a, vector signed char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtsb(__a, __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_cmpgt(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtub(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmpgt(vector short __a, vector short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtsh(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmpgt(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtuh(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpgt(vector int __a, vector int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtsw(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpgt(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtuw(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmpgt(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtfp(__a, __b);
+}
+
+/* vec_vcmpgtsb */
+
+static vector bool char __attribute__((__always_inline__))
+vec_vcmpgtsb(vector signed char __a, vector signed char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtsb(__a, __b);
+}
+
+/* vec_vcmpgtub */
+
+static vector bool char __attribute__((__always_inline__))
+vec_vcmpgtub(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtub(__a, __b);
+}
+
+/* vec_vcmpgtsh */
+
+static vector bool short __attribute__((__always_inline__))
+vec_vcmpgtsh(vector short __a, vector short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtsh(__a, __b);
+}
+
+/* vec_vcmpgtuh */
+
+static vector bool short __attribute__((__always_inline__))
+vec_vcmpgtuh(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtuh(__a, __b);
+}
+
+/* vec_vcmpgtsw */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtsw(vector int __a, vector int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtsw(__a, __b);
+}
+
+/* vec_vcmpgtuw */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtuw(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtuw(__a, __b);
+}
+
+/* vec_vcmpgtfp */
+
+static vector bool int __attribute__((__always_inline__))
+vec_vcmpgtfp(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtfp(__a, __b);
+}
+
+/* vec_cmple */
+
+static vector bool int __attribute__((__always_inline__))
+vec_cmple(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgefp(__b, __a);
+}
+
+/* vec_cmplt */
+
+static vector bool char __ATTRS_o_ai
+vec_cmplt(vector signed char __a, vector signed char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtsb(__b, __a);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_cmplt(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vcmpgtub(__b, __a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmplt(vector short __a, vector short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtsh(__b, __a);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_cmplt(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vcmpgtuh(__b, __a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmplt(vector int __a, vector int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtsw(__b, __a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmplt(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtuw(__b, __a);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_cmplt(vector float __a, vector float __b)
+{
+  return (vector bool int)__builtin_altivec_vcmpgtfp(__b, __a);
+}
+
+/* vec_ctf */
+
+static vector float __ATTRS_o_ai
+vec_ctf(vector int __a, int __b)
+{
+  return __builtin_altivec_vcfsx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ctf(vector unsigned int __a, int __b)
+{
+  return __builtin_altivec_vcfux((vector int)__a, __b);
+}
+
+/* vec_vcfsx */
+
+static vector float __attribute__((__always_inline__))
+vec_vcfsx(vector int __a, int __b)
+{
+  return __builtin_altivec_vcfsx(__a, __b);
+}
+
+/* vec_vcfux */
+
+static vector float __attribute__((__always_inline__))
+vec_vcfux(vector unsigned int __a, int __b)
+{
+  return __builtin_altivec_vcfux((vector int)__a, __b);
+}
+
+/* vec_cts */
+
+static vector int __attribute__((__always_inline__))
+vec_cts(vector float __a, int __b)
+{
+  return __builtin_altivec_vctsxs(__a, __b);
+}
+
+/* vec_vctsxs */
+
+static vector int __attribute__((__always_inline__))
+vec_vctsxs(vector float __a, int __b)
+{
+  return __builtin_altivec_vctsxs(__a, __b);
+}
+
+/* vec_ctu */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_ctu(vector float __a, int __b)
+{
+  return __builtin_altivec_vctuxs(__a, __b);
+}
+
+/* vec_vctuxs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vctuxs(vector float __a, int __b)
+{
+  return __builtin_altivec_vctuxs(__a, __b);
+}
+
+/* vec_dss */
+
+static void __attribute__((__always_inline__))
+vec_dss(int __a)
+{
+  __builtin_altivec_dss(__a);
+}
+
+/* vec_dssall */
+
+static void __attribute__((__always_inline__))
+vec_dssall(void)
+{
+  __builtin_altivec_dssall();
+}
+
+/* vec_dst */
+
+static void __attribute__((__always_inline__))
+vec_dst(const void *__a, int __b, int __c)
+{
+  __builtin_altivec_dst(__a, __b, __c);
+}
+
+/* vec_dstst */
+
+static void __attribute__((__always_inline__))
+vec_dstst(const void *__a, int __b, int __c)
+{
+  __builtin_altivec_dstst(__a, __b, __c);
+}
+
+/* vec_dststt */
+
+static void __attribute__((__always_inline__))
+vec_dststt(const void *__a, int __b, int __c)
+{
+  __builtin_altivec_dststt(__a, __b, __c);
+}
+
+/* vec_dstt */
+
+static void __attribute__((__always_inline__))
+vec_dstt(const void *__a, int __b, int __c)
+{
+  __builtin_altivec_dstt(__a, __b, __c);
+}
+
+/* vec_expte */
+
+static vector float __attribute__((__always_inline__))
+vec_expte(vector float __a)
+{
+  return __builtin_altivec_vexptefp(__a);
+}
+
+/* vec_vexptefp */
+
+static vector float __attribute__((__always_inline__))
+vec_vexptefp(vector float __a)
+{
+  return __builtin_altivec_vexptefp(__a);
+}
+
+/* vec_floor */
+
+static vector float __attribute__((__always_inline__))
+vec_floor(vector float __a)
+{
+  return __builtin_altivec_vrfim(__a);
+}
+
+/* vec_vrfim */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfim(vector float __a)
+{
+  return __builtin_altivec_vrfim(__a);
+}
+
+/* vec_ld */
+
+static vector signed char __ATTRS_o_ai
+vec_ld(int __a, const vector signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_ld(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ld(int __a, const vector unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ld(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_ld(int __a, const vector bool char *__b)
+{
+  return (vector bool char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ld(int __a, const vector short *__b)
+{
+  return (vector short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ld(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ld(int __a, const vector unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ld(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_ld(int __a, const vector bool short *__b)
+{
+  return (vector bool short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_ld(int __a, const vector pixel *__b)
+{
+  return (vector pixel)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ld(int __a, const vector int *__b)
+{
+  return (vector int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ld(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ld(int __a, const vector unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ld(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_ld(int __a, const vector bool int *__b)
+{
+  return (vector bool int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ld(int __a, const vector float *__b)
+{
+  return (vector float)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ld(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvx(__a, __b);
+}
+
+/* vec_lvx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvx(int __a, const vector signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvx(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvx(int __a, const vector unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvx(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvx(int __a, const vector bool char *__b)
+{
+  return (vector bool char)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvx(int __a, const vector short *__b)
+{
+  return (vector short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvx(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvx(int __a, const vector unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvx(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvx(int __a, const vector bool short *__b)
+{
+  return (vector bool short)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvx(int __a, const vector pixel *__b)
+{
+  return (vector pixel)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvx(int __a, const vector int *__b)
+{
+  return (vector int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvx(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvx(int __a, const vector unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvx(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvx(int __a, const vector bool int *__b)
+{
+  return (vector bool int)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvx(int __a, const vector float *__b)
+{
+  return (vector float)__builtin_altivec_lvx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvx(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvx(__a, __b);
+}
+
+/* vec_lde */
+
+static vector signed char __ATTRS_o_ai
+vec_lde(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvebx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lde(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvebx(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lde(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvehx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lde(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvehx(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lde(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvewx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lde(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvewx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lde(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvewx(__a, __b);
+}
+
+/* vec_lvebx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvebx(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvebx(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvebx(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvebx(__a, __b);
+}
+
+/* vec_lvehx */
+
+static vector short __ATTRS_o_ai
+vec_lvehx(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvehx(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvehx(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvehx(__a, __b);
+}
+
+/* vec_lvewx */
+
+static vector int __ATTRS_o_ai
+vec_lvewx(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvewx(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvewx(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvewx(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvewx(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvewx(__a, __b);
+}
+
+/* vec_ldl */
+
+static vector signed char __ATTRS_o_ai
+vec_ldl(int __a, const vector signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_ldl(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ldl(int __a, const vector unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_ldl(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_ldl(int __a, const vector bool char *__b)
+{
+  return (vector bool char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ldl(int __a, const vector short *__b)
+{
+  return (vector short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_ldl(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ldl(int __a, const vector unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_ldl(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_ldl(int __a, const vector bool short *__b)
+{
+  return (vector bool short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_ldl(int __a, const vector pixel *__b)
+{
+  return (vector pixel short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ldl(int __a, const vector int *__b)
+{
+  return (vector int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_ldl(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ldl(int __a, const vector unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_ldl(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_ldl(int __a, const vector bool int *__b)
+{
+  return (vector bool int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ldl(int __a, const vector float *__b)
+{
+  return (vector float)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_ldl(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvxl(__a, __b);
+}
+
+/* vec_lvxl */
+
+static vector signed char __ATTRS_o_ai
+vec_lvxl(int __a, const vector signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvxl(int __a, const signed char *__b)
+{
+  return (vector signed char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvxl(int __a, const vector unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvxl(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvxl(int __a, const vector bool char *__b)
+{
+  return (vector bool char)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvxl(int __a, const vector short *__b)
+{
+  return (vector short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_lvxl(int __a, const short *__b)
+{
+  return (vector short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvxl(int __a, const vector unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvxl(int __a, const unsigned short *__b)
+{
+  return (vector unsigned short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvxl(int __a, const vector bool short *__b)
+{
+  return (vector bool short)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvxl(int __a, const vector pixel *__b)
+{
+  return (vector pixel)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvxl(int __a, const vector int *__b)
+{
+  return (vector int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_lvxl(int __a, const int *__b)
+{
+  return (vector int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvxl(int __a, const vector unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvxl(int __a, const unsigned int *__b)
+{
+  return (vector unsigned int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvxl(int __a, const vector bool int *__b)
+{
+  return (vector bool int)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvxl(int __a, const vector float *__b)
+{
+  return (vector float)__builtin_altivec_lvxl(__a, __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_lvxl(int __a, const float *__b)
+{
+  return (vector float)__builtin_altivec_lvxl(__a, __b);
+}
+
+/* vec_loge */
+
+static vector float __attribute__((__always_inline__))
+vec_loge(vector float __a)
+{
+  return __builtin_altivec_vlogefp(__a);
+}
+
+/* vec_vlogefp */
+
+static vector float __attribute__((__always_inline__))
+vec_vlogefp(vector float __a)
+{
+  return __builtin_altivec_vlogefp(__a);
+}
+
+/* vec_lvsl */
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const signed char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const short *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const unsigned short *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const int *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const unsigned int *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsl(int __a, const float *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsl(__a, __b);
+}
+
+/* vec_lvsr */
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const signed char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const unsigned char *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const short *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const unsigned short *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const int *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const unsigned int *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvsr(int __a, const float *__b)
+{
+  return (vector unsigned char)__builtin_altivec_lvsr(__a, __b);
+}
+
+/* vec_madd */
+
+static vector float __attribute__((__always_inline__))
+vec_madd(vector float __a, vector float __b, vector float __c)
+{
+  return __builtin_altivec_vmaddfp(__a, __b, __c);
+}
+
+/* vec_vmaddfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vmaddfp(vector float __a, vector float __b, vector float __c)
+{
+  return __builtin_altivec_vmaddfp(__a, __b, __c);
+}
+
+/* vec_madds */
+
+static vector signed short __attribute__((__always_inline__))
+vec_madds(vector signed short __a, vector signed short __b, vector signed short __c)
+{
+  return __builtin_altivec_vmhaddshs(__a, __b, __c);
+}
+
+/* vec_vmhaddshs */
+static vector signed short __attribute__((__always_inline__))
+vec_vmhaddshs(vector signed short __a,
+              vector signed short __b,
+              vector signed short __c)
+{
+  return __builtin_altivec_vmhaddshs(__a, __b, __c);
+}
+
+/* vec_max */
+
+static vector signed char __ATTRS_o_ai
+vec_max(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vmaxsb(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_max(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vmaxsb((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_max(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vmaxsb(__a, (vector signed char)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_max(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vmaxub(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_max(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vmaxub((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_max(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vmaxub(__a, (vector unsigned char)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_max(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vmaxsh(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_max(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vmaxsh((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_max(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vmaxsh(__a, (vector short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_max(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vmaxuh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_max(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vmaxuh((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_max(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vmaxuh(__a, (vector unsigned short)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_max(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vmaxsw(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_max(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vmaxsw((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_max(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vmaxsw(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_max(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vmaxuw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_max(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vmaxuw((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_max(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vmaxuw(__a, (vector unsigned int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_max(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vmaxfp(__a, __b);
+}
+
+/* vec_vmaxsb */
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vmaxsb(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vmaxsb((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vmaxsb(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vmaxsb(__a, (vector signed char)__b);
+}
+
+/* vec_vmaxub */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vmaxub(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vmaxub((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmaxub(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vmaxub(__a, (vector unsigned char)__b);
+}
+
+/* vec_vmaxsh */
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vmaxsh(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vmaxsh((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vmaxsh(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vmaxsh(__a, (vector short)__b);
+}
+
+/* vec_vmaxuh */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vmaxuh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vmaxuh((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmaxuh(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vmaxuh(__a, (vector unsigned short)__b);
+}
+
+/* vec_vmaxsw */
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vmaxsw(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vmaxsw((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vmaxsw(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vmaxsw(__a, (vector int)__b);
+}
+
+/* vec_vmaxuw */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vmaxuw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vmaxuw((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmaxuw(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vmaxuw(__a, (vector unsigned int)__b);
+}
+
+/* vec_vmaxfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vmaxfp(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vmaxfp(__a, __b);
+}
+
+/* vec_mergeh */
+
+static vector signed char __ATTRS_o_ai
+vec_mergeh(vector signed char __a, vector signed char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_mergeh(vector unsigned char __a, vector unsigned char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_mergeh(vector bool char __a, vector bool char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector short __ATTRS_o_ai
+vec_mergeh(vector short __a, vector short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mergeh(vector unsigned short __a, vector unsigned short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_mergeh(vector bool short __a, vector bool short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_mergeh(vector pixel __a, vector pixel __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector int __ATTRS_o_ai
+vec_mergeh(vector int __a, vector int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mergeh(vector unsigned int __a, vector unsigned int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_mergeh(vector bool int __a, vector bool int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector float __ATTRS_o_ai
+vec_mergeh(vector float __a, vector float __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+/* vec_vmrghb */
+
+#define __builtin_altivec_vmrghb vec_vmrghb
+
+static vector signed char __ATTRS_o_ai
+vec_vmrghb(vector signed char __a, vector signed char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmrghb(vector unsigned char __a, vector unsigned char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vmrghb(vector bool char __a, vector bool char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x10, 0x01, 0x11, 0x02, 0x12, 0x03, 0x13, 
+     0x04, 0x14, 0x05, 0x15, 0x06, 0x16, 0x07, 0x17));
+}
+
+/* vec_vmrghh */
+
+#define __builtin_altivec_vmrghh vec_vmrghh
+
+static vector short __ATTRS_o_ai
+vec_vmrghh(vector short __a, vector short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmrghh(vector unsigned short __a, vector unsigned short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vmrghh(vector bool short __a, vector bool short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vmrghh(vector pixel __a, vector pixel __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13,
+     0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17));
+}
+
+/* vec_vmrghw */
+
+#define __builtin_altivec_vmrghw vec_vmrghw
+
+static vector int __ATTRS_o_ai
+vec_vmrghw(vector int __a, vector int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmrghw(vector unsigned int __a, vector unsigned int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vmrghw(vector bool int __a, vector bool int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+static vector float __ATTRS_o_ai
+vec_vmrghw(vector float __a, vector float __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
+     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17));
+}
+
+/* vec_mergel */
+
+static vector signed char __ATTRS_o_ai
+vec_mergel(vector signed char __a, vector signed char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_mergel(vector unsigned char __a, vector unsigned char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_mergel(vector bool char __a, vector bool char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector short __ATTRS_o_ai
+vec_mergel(vector short __a, vector short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mergel(vector unsigned short __a, vector unsigned short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_mergel(vector bool short __a, vector bool short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_mergel(vector pixel __a, vector pixel __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector int __ATTRS_o_ai
+vec_mergel(vector int __a, vector int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mergel(vector unsigned int __a, vector unsigned int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_mergel(vector bool int __a, vector bool int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector float __ATTRS_o_ai
+vec_mergel(vector float __a, vector float __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+/* vec_vmrglb */
+
+#define __builtin_altivec_vmrglb vec_vmrglb
+
+static vector signed char __ATTRS_o_ai
+vec_vmrglb(vector signed char __a, vector signed char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vmrglb(vector unsigned char __a, vector unsigned char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vmrglb(vector bool char __a, vector bool char __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x18, 0x09, 0x19, 0x0A, 0x1A, 0x0B, 0x1B, 
+     0x0C, 0x1C, 0x0D, 0x1D, 0x0E, 0x1E, 0x0F, 0x1F));
+}
+
+/* vec_vmrglh */
+
+#define __builtin_altivec_vmrglh vec_vmrglh
+
+static vector short __ATTRS_o_ai
+vec_vmrglh(vector short __a, vector short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmrglh(vector unsigned short __a, vector unsigned short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vmrglh(vector bool short __a, vector bool short __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vmrglh(vector pixel __a, vector pixel __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x18, 0x19, 0x0A, 0x0B, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x1C, 0x1D, 0x0E, 0x0F, 0x1E, 0x1F));
+}
+
+/* vec_vmrglw */
+
+#define __builtin_altivec_vmrglw vec_vmrglw
+
+static vector int __ATTRS_o_ai
+vec_vmrglw(vector int __a, vector int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vmrglw(vector unsigned int __a, vector unsigned int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vmrglw(vector bool int __a, vector bool int __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+static vector float __ATTRS_o_ai
+vec_vmrglw(vector float __a, vector float __b)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
+     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F));
+}
+
+/* vec_mfvscr */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_mfvscr(void)
+{
+  return __builtin_altivec_mfvscr();
+}
+
+/* vec_min */
+
+static vector signed char __ATTRS_o_ai
+vec_min(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vminsb(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_min(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vminsb((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_min(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vminsb(__a, (vector signed char)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_min(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vminub(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_min(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vminub((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_min(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vminub(__a, (vector unsigned char)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_min(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vminsh(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_min(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vminsh((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_min(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vminsh(__a, (vector short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_min(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vminuh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_min(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vminuh((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_min(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vminuh(__a, (vector unsigned short)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_min(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vminsw(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_min(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vminsw((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_min(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vminsw(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_min(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vminuw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_min(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vminuw((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_min(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vminuw(__a, (vector unsigned int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_min(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vminfp(__a, __b);
+}
+
+/* vec_vminsb */
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vminsb(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vminsb((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vminsb(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vminsb(__a, (vector signed char)__b);
+}
+
+/* vec_vminub */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vminub(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vminub((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vminub(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vminub(__a, (vector unsigned char)__b);
+}
+
+/* vec_vminsh */
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vminsh(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vminsh((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vminsh(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vminsh(__a, (vector short)__b);
+}
+
+/* vec_vminuh */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vminuh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vminuh((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vminuh(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vminuh(__a, (vector unsigned short)__b);
+}
+
+/* vec_vminsw */
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vminsw(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vminsw((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vminsw(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vminsw(__a, (vector int)__b);
+}
+
+/* vec_vminuw */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vminuw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vminuw((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vminuw(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vminuw(__a, (vector unsigned int)__b);
+}
+
+/* vec_vminfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vminfp(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vminfp(__a, __b);
+}
+
+/* vec_mladd */
+
+#define __builtin_altivec_vmladduhm vec_mladd
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector short __a, vector short __b, vector short __c)
+{
+  return __a * __b + __c;
+}
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector short __a, vector unsigned short __b, vector unsigned short __c)
+{
+  return __a * (vector short)__b + (vector short)__c;
+}
+
+static vector short __ATTRS_o_ai
+vec_mladd(vector unsigned short __a, vector short __b, vector short __c)
+{
+  return (vector short)__a * __b + __c;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mladd(vector unsigned short __a,
+          vector unsigned short __b,
+          vector unsigned short __c)
+{
+  return __a * __b + __c;
+}
+
+/* vec_vmladduhm */
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector short __a, vector short __b, vector short __c)
+{
+  return __a * __b + __c;
+}
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector short __a, vector unsigned short __b, vector unsigned short __c)
+{
+  return __a * (vector short)__b + (vector short)__c;
+}
+
+static vector short __ATTRS_o_ai
+vec_vmladduhm(vector unsigned short __a, vector short __b, vector short __c)
+{
+  return (vector short)__a * __b + __c;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vmladduhm(vector unsigned short __a,
+              vector unsigned short __b,
+              vector unsigned short __c)
+{
+  return __a * __b + __c;
+}
+
+/* vec_mradds */
+
+static vector short __attribute__((__always_inline__))
+vec_mradds(vector short __a, vector short __b, vector short __c)
+{
+  return __builtin_altivec_vmhraddshs(__a, __b, __c);
+}
+
+/* vec_vmhraddshs */
+
+static vector short __attribute__((__always_inline__))
+vec_vmhraddshs(vector short __a, vector short __b, vector short __c)
+{
+  return __builtin_altivec_vmhraddshs(__a, __b, __c);
+}
+
+/* vec_msum */
+
+static vector int __ATTRS_o_ai
+vec_msum(vector signed char __a, vector unsigned char __b, vector int __c)
+{
+  return __builtin_altivec_vmsummbm(__a, __b, __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msum(vector unsigned char __a, vector unsigned char __b, vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumubm(__a, __b, __c);
+}
+
+static vector int __ATTRS_o_ai
+vec_msum(vector short __a, vector short __b, vector int __c)
+{
+  return __builtin_altivec_vmsumshm(__a, __b, __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msum(vector unsigned short __a,
+         vector unsigned short __b,
+         vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumuhm(__a, __b, __c);
+}
+
+/* vec_vmsummbm */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsummbm(vector signed char __a, vector unsigned char __b, vector int __c)
+{
+  return __builtin_altivec_vmsummbm(__a, __b, __c);
+}
+
+/* vec_vmsumubm */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumubm(vector unsigned char __a,
+             vector unsigned char __b,
+             vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumubm(__a, __b, __c);
+}
+
+/* vec_vmsumshm */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsumshm(vector short __a, vector short __b, vector int __c)
+{
+  return __builtin_altivec_vmsumshm(__a, __b, __c);
+}
+
+/* vec_vmsumuhm */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumuhm(vector unsigned short __a,
+             vector unsigned short __b,
+             vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumuhm(__a, __b, __c);
+}
+
+/* vec_msums */
+
+static vector int __ATTRS_o_ai
+vec_msums(vector short __a, vector short __b, vector int __c)
+{
+  return __builtin_altivec_vmsumshs(__a, __b, __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_msums(vector unsigned short __a,
+          vector unsigned short __b,
+          vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumuhs(__a, __b, __c);
+}
+
+/* vec_vmsumshs */
+
+static vector int __attribute__((__always_inline__))
+vec_vmsumshs(vector short __a, vector short __b, vector int __c)
+{
+  return __builtin_altivec_vmsumshs(__a, __b, __c);
+}
+
+/* vec_vmsumuhs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmsumuhs(vector unsigned short __a,
+             vector unsigned short __b,
+             vector unsigned int __c)
+{
+  return __builtin_altivec_vmsumuhs(__a, __b, __c);
+}
+
+/* vec_mtvscr */
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector signed char __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned char __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool char __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector short __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned short __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool short __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector pixel __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector int __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector unsigned int __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector bool int __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+static void __ATTRS_o_ai
+vec_mtvscr(vector float __a)
+{
+  __builtin_altivec_mtvscr((vector int)__a);
+}
+
+/* The vmulos* and vmules* instructions have a big endian bias, so
+   we must reverse the meaning of "even" and "odd" for little endian.  */
+
+/* vec_mule */
+
+static vector short __ATTRS_o_ai
+vec_mule(vector signed char __a, vector signed char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
+  return __builtin_altivec_vmulesb(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mule(vector unsigned char __a, vector unsigned char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
+  return __builtin_altivec_vmuleub(__a, __b);
+#endif
+}
+
+static vector int __ATTRS_o_ai
+vec_mule(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
+  return __builtin_altivec_vmulesh(__a, __b);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mule(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
+  return __builtin_altivec_vmuleuh(__a, __b);
+#endif
+}
+
+/* vec_vmulesb */
+
+static vector short __attribute__((__always_inline__))
+vec_vmulesb(vector signed char __a, vector signed char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
+  return __builtin_altivec_vmulesb(__a, __b);
+#endif
+}
+
+/* vec_vmuleub */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vmuleub(vector unsigned char __a, vector unsigned char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
+  return __builtin_altivec_vmuleub(__a, __b);
+#endif
+}
+
+/* vec_vmulesh */
+
+static vector int __attribute__((__always_inline__))
+vec_vmulesh(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
+  return __builtin_altivec_vmulesh(__a, __b);
+#endif
+}
+
+/* vec_vmuleuh */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmuleuh(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
+  return __builtin_altivec_vmuleuh(__a, __b);
+#endif
+}
+
+/* vec_mulo */
+
+static vector short __ATTRS_o_ai
+vec_mulo(vector signed char __a, vector signed char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
+  return __builtin_altivec_vmulosb(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_mulo(vector unsigned char __a, vector unsigned char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
+  return __builtin_altivec_vmuloub(__a, __b);
+#endif
+}
+
+static vector int __ATTRS_o_ai
+vec_mulo(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
+  return __builtin_altivec_vmulosh(__a, __b);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_mulo(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
+  return __builtin_altivec_vmulouh(__a, __b);
+#endif
+}
+
+/* vec_vmulosb */
+
+static vector short __attribute__((__always_inline__))
+vec_vmulosb(vector signed char __a, vector signed char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
+  return __builtin_altivec_vmulosb(__a, __b);
+#endif
+}
+
+/* vec_vmuloub */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vmuloub(vector unsigned char __a, vector unsigned char __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
+  return __builtin_altivec_vmuloub(__a, __b);
+#endif
+}
+
+/* vec_vmulosh */
+
+static vector int __attribute__((__always_inline__))
+vec_vmulosh(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
+  return __builtin_altivec_vmulosh(__a, __b);
+#endif
+}
+
+/* vec_vmulouh */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vmulouh(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
+  return __builtin_altivec_vmulouh(__a, __b);
+#endif
+}
+
+/* vec_nmsub */
+
+static vector float __attribute__((__always_inline__))
+vec_nmsub(vector float __a, vector float __b, vector float __c)
+{
+  return __builtin_altivec_vnmsubfp(__a, __b, __c);
+}
+
+/* vec_vnmsubfp */
+
+static vector float __attribute__((__always_inline__))
+vec_vnmsubfp(vector float __a, vector float __b, vector float __c)
+{
+  return __builtin_altivec_vnmsubfp(__a, __b, __c);
+}
+
+/* vec_nor */
+
+#define __builtin_altivec_vnor vec_nor
+
+static vector signed char __ATTRS_o_ai
+vec_nor(vector signed char __a, vector signed char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_nor(vector unsigned char __a, vector unsigned char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_nor(vector bool char __a, vector bool char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_nor(vector short __a, vector short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_nor(vector unsigned short __a, vector unsigned short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_nor(vector bool short __a, vector bool short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_nor(vector int __a, vector int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_nor(vector unsigned int __a, vector unsigned int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_nor(vector bool int __a, vector bool int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_nor(vector float __a, vector float __b)
+{
+  vector unsigned int __res = ~((vector unsigned int)__a | (vector unsigned int)__b);
+  return (vector float)__res;
+}
+
+/* vec_vnor */
+
+static vector signed char __ATTRS_o_ai
+vec_vnor(vector signed char __a, vector signed char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vnor(vector unsigned char __a, vector unsigned char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vnor(vector bool char __a, vector bool char __b)
+{
+  return ~(__a | __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vnor(vector short __a, vector short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vnor(vector unsigned short __a, vector unsigned short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vnor(vector bool short __a, vector bool short __b)
+{
+  return ~(__a | __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vnor(vector int __a, vector int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vnor(vector unsigned int __a, vector unsigned int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vnor(vector bool int __a, vector bool int __b)
+{
+  return ~(__a | __b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vnor(vector float __a, vector float __b)
+{
+  vector unsigned int __res = ~((vector unsigned int)__a | (vector unsigned int)__b);
+  return (vector float)__res;
+}
+
+/* vec_or */
+
+#define __builtin_altivec_vor vec_or
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector signed char __a, vector signed char __b)
+{
+  return __a | __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a | __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_or(vector signed char __a, vector bool char __b)
+{
+  return __a | (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a | __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_or(vector unsigned char __a, vector bool char __b)
+{
+  return __a | (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_or(vector bool char __a, vector bool char __b)
+{
+  return __a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector short __a, vector short __b)
+{
+  return __a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector bool short __a, vector short __b)
+{
+  return (vector short)__a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_or(vector short __a, vector bool short __b)
+{
+  return __a | (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a | __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_or(vector unsigned short __a, vector bool short __b)
+{
+  return __a | (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_or(vector bool short __a, vector bool short __b)
+{
+  return __a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector int __a, vector int __b)
+{
+  return __a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector bool int __a, vector int __b)
+{
+  return (vector int)__a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_or(vector int __a, vector bool int __b)
+{
+  return __a | (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a | __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_or(vector unsigned int __a, vector bool int __b)
+{
+  return __a | (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_or(vector bool int __a, vector bool int __b)
+{
+  return __a | __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_or(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_vor */
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector signed char __a, vector signed char __b)
+{
+  return __a | __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a | __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vor(vector signed char __a, vector bool char __b)
+{
+  return __a | (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a | __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vor(vector unsigned char __a, vector bool char __b)
+{
+  return __a | (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vor(vector bool char __a, vector bool char __b)
+{
+  return __a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector short __a, vector short __b)
+{
+  return __a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector bool short __a, vector short __b)
+{
+  return (vector short)__a | __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vor(vector short __a, vector bool short __b)
+{
+  return __a | (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a | __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vor(vector unsigned short __a, vector bool short __b)
+{
+  return __a | (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vor(vector bool short __a, vector bool short __b)
+{
+  return __a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector int __a, vector int __b)
+{
+  return __a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector bool int __a, vector int __b)
+{
+  return (vector int)__a | __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vor(vector int __a, vector bool int __b)
+{
+  return __a | (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a | __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a | __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vor(vector unsigned int __a, vector bool int __b)
+{
+  return __a | (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vor(vector bool int __a, vector bool int __b)
+{
+  return __a | __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vor(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a | (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_pack */
+
+/* The various vector pack instructions have a big-endian bias, so for
+   little endian we must handle reversed element numbering.  */
+
+static vector signed char __ATTRS_o_ai
+vec_pack(vector signed short __a, vector signed short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_pack(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+static vector bool char __ATTRS_o_ai
+vec_pack(vector bool short __a, vector bool short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+static vector short __ATTRS_o_ai
+vec_pack(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_pack(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_pack(vector bool int __a, vector bool int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+/* vec_vpkuhum */
+
+#define __builtin_altivec_vpkuhum vec_vpkuhum
+
+static vector signed char __ATTRS_o_ai
+vec_vpkuhum(vector signed short __a, vector signed short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkuhum(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vpkuhum(vector bool short __a, vector bool short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
+     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
+}
+
+/* vec_vpkuwum */
+
+#define __builtin_altivec_vpkuwum vec_vpkuwum
+
+static vector short __ATTRS_o_ai
+vec_vpkuwum(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkuwum(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vpkuwum(vector bool int __a, vector bool int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
+     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
+}
+
+/* vec_packpx */
+
+static vector pixel __attribute__((__always_inline__))
+vec_packpx(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
+  return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
+}
+
+/* vec_vpkpx */
+
+static vector pixel __attribute__((__always_inline__))
+vec_vpkpx(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
+  return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
+}
+
+/* vec_packs */
+
+static vector signed char __ATTRS_o_ai
+vec_packs(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
+  return __builtin_altivec_vpkshss(__a, __b);
+#endif
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_packs(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
+  return __builtin_altivec_vpkuhus(__a, __b);
+#endif
+}
+
+static vector signed short __ATTRS_o_ai
+vec_packs(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
+  return __builtin_altivec_vpkswss(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packs(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
+  return __builtin_altivec_vpkuwus(__a, __b);
+#endif
+}
+
+/* vec_vpkshss */
+
+static vector signed char __attribute__((__always_inline__))
+vec_vpkshss(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
+  return __builtin_altivec_vpkshss(__a, __b);
+#endif
+}
+
+/* vec_vpkuhus */
+
+static vector unsigned char __attribute__((__always_inline__))
+vec_vpkuhus(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
+  return __builtin_altivec_vpkuhus(__a, __b);
+#endif
+}
+
+/* vec_vpkswss */
+
+static vector signed short __attribute__((__always_inline__))
+vec_vpkswss(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
+  return __builtin_altivec_vpkswss(__a, __b);
+#endif
+}
+
+/* vec_vpkuwus */
+
+static vector unsigned short __attribute__((__always_inline__))
+vec_vpkuwus(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
+  return __builtin_altivec_vpkuwus(__a, __b);
+#endif
+}
+
+/* vec_packsu */
+
+static vector unsigned char __ATTRS_o_ai
+vec_packsu(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
+  return __builtin_altivec_vpkshus(__a, __b);
+#endif
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_packsu(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
+  return __builtin_altivec_vpkuhus(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packsu(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
+  return __builtin_altivec_vpkswus(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_packsu(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
+  return __builtin_altivec_vpkuwus(__a, __b);
+#endif
+}
+
+/* vec_vpkshus */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkshus(vector short __a, vector short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
+  return __builtin_altivec_vpkshus(__a, __b);
+#endif
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vpkshus(vector unsigned short __a, vector unsigned short __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
+  return __builtin_altivec_vpkuhus(__a, __b);
+#endif
+}
+
+/* vec_vpkswus */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkswus(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
+  return __builtin_altivec_vpkswus(__a, __b);
+#endif
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vpkswus(vector unsigned int __a, vector unsigned int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
+  return __builtin_altivec_vpkuwus(__a, __b);
+#endif
+}
+
+/* vec_perm */
+
+// The vperm instruction is defined architecturally with a big-endian bias.
+// For little endian, we swap the input operands and invert the permute
+// control vector.  Only the rightmost 5 bits matter, so we could use
+// a vector of all 31s instead of all 255s to perform the inversion.
+// However, when the PCV is not a constant, using 255 has an advantage
+// in that the vec_xor can be recognized as a vec_nor (and for P8 and
+// later, possibly a vec_nand).
+
+vector signed char __ATTRS_o_ai
+vec_perm(vector signed char __a, vector signed char __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector signed char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector signed char)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector unsigned char __ATTRS_o_ai
+vec_perm(vector unsigned char __a,
+         vector unsigned char __b,
+         vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector unsigned char)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector bool char __ATTRS_o_ai
+vec_perm(vector bool char __a, vector bool char __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector bool char)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector short __ATTRS_o_ai
+vec_perm(vector short __a, vector short __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector short)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector unsigned short __ATTRS_o_ai
+vec_perm(vector unsigned short __a,
+         vector unsigned short __b,
+         vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector unsigned short)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector bool short __ATTRS_o_ai
+vec_perm(vector bool short __a, vector bool short __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector bool short)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector pixel __ATTRS_o_ai
+vec_perm(vector pixel __a, vector pixel __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector pixel)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector pixel)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector int __ATTRS_o_ai
+vec_perm(vector int __a, vector int __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector int)__builtin_altivec_vperm_4si(__b, __a, __d);
+#else
+  return (vector int)__builtin_altivec_vperm_4si(__a, __b, __c);
+#endif
+}
+
+vector unsigned int __ATTRS_o_ai
+vec_perm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector unsigned int)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector bool int __ATTRS_o_ai
+vec_perm(vector bool int __a, vector bool int __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector bool int)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+vector float __ATTRS_o_ai
+vec_perm(vector float __a, vector float __b, vector unsigned char __c)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector float)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
+  return (vector float)
+           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
+}
+
+/* vec_vperm */
+
+static vector signed char __ATTRS_o_ai
+vec_vperm(vector signed char __a, vector signed char __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vperm(vector unsigned char __a,
+          vector unsigned char __b,
+          vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vperm(vector bool char __a, vector bool char __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector short __ATTRS_o_ai
+vec_vperm(vector short __a, vector short __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vperm(vector unsigned short __a,
+          vector unsigned short __b,
+          vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vperm(vector bool short __a, vector bool short __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vperm(vector pixel __a, vector pixel __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector int __ATTRS_o_ai
+vec_vperm(vector int __a, vector int __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vperm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vperm(vector bool int __a, vector bool int __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+static vector float __ATTRS_o_ai
+vec_vperm(vector float __a, vector float __b, vector unsigned char __c)
+{
+  return vec_perm(__a, __b, __c);
+}
+
+/* vec_re */
+
+static vector float __attribute__((__always_inline__))
+vec_re(vector float __a)
+{
+  return __builtin_altivec_vrefp(__a);
+}
+
+/* vec_vrefp */
+
+static vector float __attribute__((__always_inline__))
+vec_vrefp(vector float __a)
+{
+  return __builtin_altivec_vrefp(__a);
+}
+
+/* vec_rl */
+
+static vector signed char __ATTRS_o_ai
+vec_rl(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)__builtin_altivec_vrlb((vector char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_rl(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__builtin_altivec_vrlb((vector char)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_rl(vector short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vrlh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_rl(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__builtin_altivec_vrlh((vector short)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_rl(vector int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vrlw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_rl(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__builtin_altivec_vrlw((vector int)__a, __b);
+}
+
+/* vec_vrlb */
+
+static vector signed char __ATTRS_o_ai
+vec_vrlb(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)__builtin_altivec_vrlb((vector char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vrlb(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__builtin_altivec_vrlb((vector char)__a, __b);
+}
+
+/* vec_vrlh */
+
+static vector short __ATTRS_o_ai
+vec_vrlh(vector short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vrlh(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vrlh(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__builtin_altivec_vrlh((vector short)__a, __b);
+}
+
+/* vec_vrlw */
+
+static vector int __ATTRS_o_ai
+vec_vrlw(vector int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vrlw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vrlw(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__builtin_altivec_vrlw((vector int)__a, __b);
+}
+
+/* vec_round */
+
+static vector float __attribute__((__always_inline__))
+vec_round(vector float __a)
+{
+  return __builtin_altivec_vrfin(__a);
+}
+
+/* vec_vrfin */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfin(vector float __a)
+{
+  return __builtin_altivec_vrfin(__a);
+}
+
+/* vec_rsqrte */
+
+static __vector float __attribute__((__always_inline__))
+vec_rsqrte(vector float __a)
+{
+  return __builtin_altivec_vrsqrtefp(__a);
+}
+
+/* vec_vrsqrtefp */
+
+static __vector float __attribute__((__always_inline__))
+vec_vrsqrtefp(vector float __a)
+{
+  return __builtin_altivec_vrsqrtefp(__a);
+}
+
+/* vec_sel */
+
+#define __builtin_altivec_vsel_4si vec_sel
+
+static vector signed char __ATTRS_o_ai
+vec_sel(vector signed char __a, vector signed char __b, vector unsigned char __c)
+{
+  return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sel(vector signed char __a, vector signed char __b, vector bool char __c)
+{
+  return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sel(vector unsigned char __a, vector unsigned char __b, vector unsigned char __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sel(vector unsigned char __a, vector unsigned char __b, vector bool char __c)
+{
+  return (__a & ~(vector unsigned char)__c) | (__b & (vector unsigned char)__c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sel(vector bool char __a, vector bool char __b, vector unsigned char __c)
+{
+  return (__a & ~(vector bool char)__c) | (__b & (vector bool char)__c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sel(vector bool char __a, vector bool char __b, vector bool char __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector short __ATTRS_o_ai
+vec_sel(vector short __a, vector short __b, vector unsigned short __c)
+{
+  return (__a & ~(vector short)__c) | (__b & (vector short)__c);
+}
+
+static vector short __ATTRS_o_ai
+vec_sel(vector short __a, vector short __b, vector bool short __c)
+{
+  return (__a & ~(vector short)__c) | (__b & (vector short)__c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sel(vector unsigned short __a,
+        vector unsigned short __b,
+        vector unsigned short __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sel(vector unsigned short __a, vector unsigned short __b, vector bool short __c)
+{
+  return (__a & ~(vector unsigned short)__c) | (__b & (vector unsigned short)__c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sel(vector bool short __a, vector bool short __b, vector unsigned short __c)
+{
+  return (__a & ~(vector bool short)__c) | (__b & (vector bool short)__c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sel(vector bool short __a, vector bool short __b, vector bool short __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector int __ATTRS_o_ai
+vec_sel(vector int __a, vector int __b, vector unsigned int __c)
+{
+  return (__a & ~(vector int)__c) | (__b & (vector int)__c);
+}
+
+static vector int __ATTRS_o_ai
+vec_sel(vector int __a, vector int __b, vector bool int __c)
+{
+  return (__a & ~(vector int)__c) | (__b & (vector int)__c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sel(vector unsigned int __a, vector unsigned int __b, vector unsigned int __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sel(vector unsigned int __a, vector unsigned int __b, vector bool int __c)
+{
+  return (__a & ~(vector unsigned int)__c) | (__b & (vector unsigned int)__c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sel(vector bool int __a, vector bool int __b, vector unsigned int __c)
+{
+  return (__a & ~(vector bool int)__c) | (__b & (vector bool int)__c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sel(vector bool int __a, vector bool int __b, vector bool int __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector float __ATTRS_o_ai
+vec_sel(vector float __a, vector float __b, vector unsigned int __c)
+{
+  vector int __res = ((vector int)__a & ~(vector int)__c)
+                   | ((vector int)__b & (vector int)__c);
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_sel(vector float __a, vector float __b, vector bool int __c)
+{
+  vector int __res = ((vector int)__a & ~(vector int)__c)
+                   | ((vector int)__b & (vector int)__c);
+  return (vector float)__res;
+}
+
+/* vec_vsel */
+
+static vector signed char __ATTRS_o_ai
+vec_vsel(vector signed char __a, vector signed char __b, vector unsigned char __c)
+{
+  return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsel(vector signed char __a, vector signed char __b, vector bool char __c)
+{
+  return (__a & ~(vector signed char)__c) | (__b & (vector signed char)__c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsel(vector unsigned char __a, vector unsigned char __b, vector unsigned char __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsel(vector unsigned char __a, vector unsigned char __b, vector bool char __c)
+{
+  return (__a & ~(vector unsigned char)__c) | (__b & (vector unsigned char)__c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsel(vector bool char __a, vector bool char __b, vector unsigned char __c)
+{
+  return (__a & ~(vector bool char)__c) | (__b & (vector bool char)__c);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsel(vector bool char __a, vector bool char __b, vector bool char __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsel(vector short __a, vector short __b, vector unsigned short __c)
+{
+  return (__a & ~(vector short)__c) | (__b & (vector short)__c);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsel(vector short __a, vector short __b, vector bool short __c)
+{
+  return (__a & ~(vector short)__c) | (__b & (vector short)__c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsel(vector unsigned short __a,
+         vector unsigned short __b,
+         vector unsigned short __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsel(vector unsigned short __a, vector unsigned short __b, vector bool short __c)
+{
+  return (__a & ~(vector unsigned short)__c) | (__b & (vector unsigned short)__c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsel(vector bool short __a, vector bool short __b, vector unsigned short __c)
+{
+  return (__a & ~(vector bool short)__c) | (__b & (vector bool short)__c);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsel(vector bool short __a, vector bool short __b, vector bool short __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsel(vector int __a, vector int __b, vector unsigned int __c)
+{
+  return (__a & ~(vector int)__c) | (__b & (vector int)__c);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsel(vector int __a, vector int __b, vector bool int __c)
+{
+  return (__a & ~(vector int)__c) | (__b & (vector int)__c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsel(vector unsigned int __a, vector unsigned int __b, vector unsigned int __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsel(vector unsigned int __a, vector unsigned int __b, vector bool int __c)
+{
+  return (__a & ~(vector unsigned int)__c) | (__b & (vector unsigned int)__c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsel(vector bool int __a, vector bool int __b, vector unsigned int __c)
+{
+  return (__a & ~(vector bool int)__c) | (__b & (vector bool int)__c);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsel(vector bool int __a, vector bool int __b, vector bool int __c)
+{
+  return (__a & ~__c) | (__b & __c);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsel(vector float __a, vector float __b, vector unsigned int __c)
+{
+  vector int __res = ((vector int)__a & ~(vector int)__c)
+                   | ((vector int)__b & (vector int)__c);
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vsel(vector float __a, vector float __b, vector bool int __c)
+{
+  vector int __res = ((vector int)__a & ~(vector int)__c)
+                   | ((vector int)__b & (vector int)__c);
+  return (vector float)__res;
+}
+
+/* vec_sl */
+
+static vector signed char __ATTRS_o_ai
+vec_sl(vector signed char __a, vector unsigned char __b)
+{
+  return __a << (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sl(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a << __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sl(vector short __a, vector unsigned short __b)
+{
+  return __a << (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sl(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a << __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sl(vector int __a, vector unsigned int __b)
+{
+  return __a << (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sl(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a << __b;
+}
+
+/* vec_vslb */
+
+#define __builtin_altivec_vslb vec_vslb
+
+static vector signed char __ATTRS_o_ai
+vec_vslb(vector signed char __a, vector unsigned char __b)
+{
+  return vec_sl(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslb(vector unsigned char __a, vector unsigned char __b)
+{
+  return vec_sl(__a, __b);
+}
+
+/* vec_vslh */
+
+#define __builtin_altivec_vslh vec_vslh
+
+static vector short __ATTRS_o_ai
+vec_vslh(vector short __a, vector unsigned short __b)
+{
+  return vec_sl(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslh(vector unsigned short __a, vector unsigned short __b)
+{
+  return vec_sl(__a, __b);
+}
+
+/* vec_vslw */
+
+#define __builtin_altivec_vslw vec_vslw
+
+static vector int __ATTRS_o_ai
+vec_vslw(vector int __a, vector unsigned int __b)
+{
+  return vec_sl(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslw(vector unsigned int __a, vector unsigned int __b)
+{
+  return vec_sl(__a, __b);
+}
+
+/* vec_sld */
+
+#define __builtin_altivec_vsldoi_4si vec_sld
+
+static vector signed char __ATTRS_o_ai
+vec_sld(vector signed char __a, vector signed char __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sld(vector unsigned char __a, vector unsigned char __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector short __ATTRS_o_ai
+vec_sld(vector short __a, vector short __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sld(vector unsigned short __a, vector unsigned short __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sld(vector pixel __a, vector pixel __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector int __ATTRS_o_ai
+vec_sld(vector int __a, vector int __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sld(vector unsigned int __a, vector unsigned int __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector float __ATTRS_o_ai
+vec_sld(vector float __a, vector float __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+/* vec_vsldoi */
+
+static vector signed char __ATTRS_o_ai
+vec_vsldoi(vector signed char __a, vector signed char __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsldoi(vector unsigned char __a, vector unsigned char __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector short __ATTRS_o_ai
+vec_vsldoi(vector short __a, vector short __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsldoi(vector unsigned short __a, vector unsigned short __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsldoi(vector pixel __a, vector pixel __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector int __ATTRS_o_ai
+vec_vsldoi(vector int __a, vector int __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsldoi(vector unsigned int __a, vector unsigned int __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+static vector float __ATTRS_o_ai
+vec_vsldoi(vector float __a, vector float __b, unsigned char __c)
+{
+  return vec_perm(__a, __b, (vector unsigned char)
+    (__c,   __c+1, __c+2,  __c+3,  __c+4,  __c+5,  __c+6,  __c+7,
+     __c+8, __c+9, __c+10, __c+11, __c+12, __c+13, __c+14, __c+15));
+}
+
+/* vec_sll */
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char __a, vector unsigned short __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sll(vector signed char __a, vector unsigned int __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char __a, vector unsigned short __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sll(vector unsigned char __a, vector unsigned int __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char __a, vector unsigned short __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_sll(vector bool char __a, vector unsigned int __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short __a, vector unsigned short __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sll(vector short __a, vector unsigned int __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sll(vector unsigned short __a, vector unsigned int __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short __a, vector unsigned char __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_sll(vector bool short __a, vector unsigned int __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel __a, vector unsigned short __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sll(vector pixel __a, vector unsigned int __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int __a, vector unsigned short __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sll(vector int __a, vector unsigned int __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int __a, vector unsigned short __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sll(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int __a, vector unsigned char __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int __a, vector unsigned short __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_sll(vector bool int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+/* vec_vsl */
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char __a, vector unsigned short __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsl(vector signed char __a, vector unsigned int __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char __a, vector unsigned short __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsl(vector unsigned char __a, vector unsigned int __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char __a, vector unsigned short __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsl(vector bool char __a, vector unsigned int __b)
+{
+  return (vector bool char)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short __a, vector unsigned short __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsl(vector short __a, vector unsigned int __b)
+{
+  return (vector short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsl(vector unsigned short __a, vector unsigned int __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short __a, vector unsigned char __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsl(vector bool short __a, vector unsigned int __b)
+{
+  return (vector bool short)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel __a, vector unsigned short __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsl(vector pixel __a, vector unsigned int __b)
+{
+  return (vector pixel)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int __a, vector unsigned short __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsl(vector int __a, vector unsigned int __b)
+{
+  return (vector int)__builtin_altivec_vsl(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int __a, vector unsigned short __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsl(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int __a, vector unsigned char __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int __a, vector unsigned short __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsl(vector bool int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vsl((vector int)__a, (vector int)__b);
+}
+
+/* vec_slo */
+
+static vector signed char __ATTRS_o_ai
+vec_slo(vector signed char __a, vector signed char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_slo(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_slo(vector unsigned char __a, vector signed char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_slo(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_slo(vector short __a, vector signed char __b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_slo(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_slo(vector unsigned short __a, vector signed char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_slo(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_slo(vector pixel __a, vector signed char __b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_slo(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_slo(vector int __a, vector signed char __b)
+{
+  return (vector int)__builtin_altivec_vslo(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_slo(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vslo(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_slo(vector unsigned int __a, vector signed char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_slo(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_slo(vector float __a, vector signed char __b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_slo(vector float __a, vector unsigned char __b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+/* vec_vslo */
+
+static vector signed char __ATTRS_o_ai
+vec_vslo(vector signed char __a, vector signed char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vslo(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslo(vector unsigned char __a, vector signed char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vslo(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vslo(vector short __a, vector signed char __b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vslo(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslo(vector unsigned short __a, vector signed char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vslo(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vslo(vector pixel __a, vector signed char __b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vslo(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vslo(vector int __a, vector signed char __b)
+{
+  return (vector int)__builtin_altivec_vslo(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vslo(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vslo(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslo(vector unsigned int __a, vector signed char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vslo(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vslo(vector float __a, vector signed char __b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vslo(vector float __a, vector unsigned char __b)
+{
+  return (vector float)__builtin_altivec_vslo((vector int)__a, (vector int)__b);
+}
+
+/* vec_splat */
+
+static vector signed char __ATTRS_o_ai
+vec_splat(vector signed char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_splat(vector unsigned char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_splat(vector bool char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+static vector short __ATTRS_o_ai
+vec_splat(vector short __a, unsigned char __b)
+{ 
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_splat(vector unsigned short __a, unsigned char __b)
+{ 
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_splat(vector bool short __a, unsigned char __b)
+{ 
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_splat(vector pixel __a, unsigned char __b)
+{ 
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector int __ATTRS_o_ai
+vec_splat(vector int __a, unsigned char __b)
+{ 
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_splat(vector unsigned int __a, unsigned char __b)
+{ 
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_splat(vector bool int __a, unsigned char __b)
+{ 
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector float __ATTRS_o_ai
+vec_splat(vector float __a, unsigned char __b)
+{ 
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+/* vec_vspltb */
+
+#define __builtin_altivec_vspltb vec_vspltb
+
+static vector signed char __ATTRS_o_ai
+vec_vspltb(vector signed char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vspltb(vector unsigned char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vspltb(vector bool char __a, unsigned char __b)
+{
+  return vec_perm(__a, __a, (vector unsigned char)(__b));
+}
+
+/* vec_vsplth */
+
+#define __builtin_altivec_vsplth vec_vsplth
+
+static vector short __ATTRS_o_ai
+vec_vsplth(vector short __a, unsigned char __b)
+{
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsplth(vector unsigned short __a, unsigned char __b)
+{
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsplth(vector bool short __a, unsigned char __b)
+{
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsplth(vector pixel __a, unsigned char __b)
+{
+  __b *= 2;
+  unsigned char b1=__b+1;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1, __b, b1));
+}
+
+/* vec_vspltw */
+
+#define __builtin_altivec_vspltw vec_vspltw
+
+static vector int __ATTRS_o_ai
+vec_vspltw(vector int __a, unsigned char __b)
+{
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vspltw(vector unsigned int __a, unsigned char __b)
+{
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vspltw(vector bool int __a, unsigned char __b)
+{
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+static vector float __ATTRS_o_ai
+vec_vspltw(vector float __a, unsigned char __b)
+{
+  __b *= 4;
+  unsigned char b1=__b+1, b2=__b+2, b3=__b+3;
+  return vec_perm(__a, __a, (vector unsigned char)
+    (__b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3, __b, b1, b2, b3));
+}
+
+/* vec_splat_s8 */
+
+#define __builtin_altivec_vspltisb vec_splat_s8
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector signed char __ATTRS_o_ai
+vec_splat_s8(signed char __a)
+{
+  return (vector signed char)(__a);
+}
+
+/* vec_vspltisb */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector signed char __ATTRS_o_ai
+vec_vspltisb(signed char __a)
+{
+  return (vector signed char)(__a);
+}
+
+/* vec_splat_s16 */
+
+#define __builtin_altivec_vspltish vec_splat_s16
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector short __ATTRS_o_ai
+vec_splat_s16(signed char __a)
+{
+  return (vector short)(__a);
+}
+
+/* vec_vspltish */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector short __ATTRS_o_ai
+vec_vspltish(signed char __a)
+{
+  return (vector short)(__a);
+}
+
+/* vec_splat_s32 */
+
+#define __builtin_altivec_vspltisw vec_splat_s32
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector int __ATTRS_o_ai
+vec_splat_s32(signed char __a)
+{
+  return (vector int)(__a);
+}
+
+/* vec_vspltisw */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector int __ATTRS_o_ai
+vec_vspltisw(signed char __a)
+{
+  return (vector int)(__a);
+}
+
+/* vec_splat_u8 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned char __ATTRS_o_ai
+vec_splat_u8(unsigned char __a)
+{
+  return (vector unsigned char)(__a);
+}
+
+/* vec_splat_u16 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned short __ATTRS_o_ai
+vec_splat_u16(signed char __a)
+{
+  return (vector unsigned short)(__a);
+}
+
+/* vec_splat_u32 */
+
+// FIXME: parameter should be treated as 5-bit signed literal
+static vector unsigned int __ATTRS_o_ai
+vec_splat_u32(signed char __a)
+{
+  return (vector unsigned int)(__a);
+}
+
+/* vec_sr */
+
+static vector signed char __ATTRS_o_ai
+vec_sr(vector signed char __a, vector unsigned char __b)
+{
+  return __a >> (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sr(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a >> __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sr(vector short __a, vector unsigned short __b)
+{
+  return __a >> (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sr(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a >> __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sr(vector int __a, vector unsigned int __b)
+{
+  return __a >> (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sr(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a >> __b;
+}
+
+/* vec_vsrb */
+
+#define __builtin_altivec_vsrb vec_vsrb
+
+static vector signed char __ATTRS_o_ai
+vec_vsrb(vector signed char __a, vector unsigned char __b)
+{
+  return __a >> (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsrb(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a >> __b;
+}
+
+/* vec_vsrh */
+
+#define __builtin_altivec_vsrh vec_vsrh
+
+static vector short __ATTRS_o_ai
+vec_vsrh(vector short __a, vector unsigned short __b)
+{
+  return __a >> (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsrh(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a >> __b;
+}
+
+/* vec_vsrw */
+
+#define __builtin_altivec_vsrw vec_vsrw
+
+static vector int __ATTRS_o_ai
+vec_vsrw(vector int __a, vector unsigned int __b)
+{
+  return __a >> (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsrw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a >> __b;
+}
+
+/* vec_sra */
+
+static vector signed char __ATTRS_o_ai
+vec_sra(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)__builtin_altivec_vsrab((vector char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sra(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__builtin_altivec_vsrab((vector char)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sra(vector short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsrah(__a, (vector unsigned short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sra(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__builtin_altivec_vsrah((vector short)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sra(vector int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsraw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sra(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__builtin_altivec_vsraw((vector int)__a, __b);
+}
+
+/* vec_vsrab */
+
+static vector signed char __ATTRS_o_ai
+vec_vsrab(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)__builtin_altivec_vsrab((vector char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsrab(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__builtin_altivec_vsrab((vector char)__a, __b);
+}
+
+/* vec_vsrah */
+
+static vector short __ATTRS_o_ai
+vec_vsrah(vector short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsrah(__a, (vector unsigned short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsrah(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__builtin_altivec_vsrah((vector short)__a, __b);
+}
+
+/* vec_vsraw */
+
+static vector int __ATTRS_o_ai
+vec_vsraw(vector int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsraw(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsraw(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__builtin_altivec_vsraw((vector int)__a, __b);
+}
+
+/* vec_srl */
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char __a, vector unsigned short __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_srl(vector signed char __a, vector unsigned int __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char __a, vector unsigned short __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_srl(vector unsigned char __a, vector unsigned int __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char __a, vector unsigned short __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_srl(vector bool char __a, vector unsigned int __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short __a, vector unsigned short __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_srl(vector short __a, vector unsigned int __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_srl(vector unsigned short __a, vector unsigned int __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short __a, vector unsigned char __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_srl(vector bool short __a, vector unsigned int __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel __a, vector unsigned short __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_srl(vector pixel __a, vector unsigned int __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int __a, vector unsigned short __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_srl(vector int __a, vector unsigned int __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int __a, vector unsigned short __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_srl(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int __a, vector unsigned char __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int __a, vector unsigned short __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_srl(vector bool int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+/* vec_vsr */
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char __a, vector unsigned short __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsr(vector signed char __a, vector unsigned int __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char __a, vector unsigned short __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsr(vector unsigned char __a, vector unsigned int __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char __a, vector unsigned char __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char __a, vector unsigned short __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vsr(vector bool char __a, vector unsigned int __b)
+{
+  return (vector bool char)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short __a, vector unsigned short __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsr(vector short __a, vector unsigned int __b)
+{
+  return (vector short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsr(vector unsigned short __a, vector unsigned int __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short __a, vector unsigned char __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short __a, vector unsigned short __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vsr(vector bool short __a, vector unsigned int __b)
+{
+  return (vector bool short)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel __a, vector unsigned short __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsr(vector pixel __a, vector unsigned int __b)
+{
+  return (vector pixel)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int __a, vector unsigned short __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsr(vector int __a, vector unsigned int __b)
+{
+  return (vector int)__builtin_altivec_vsr(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int __a, vector unsigned short __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsr(vector unsigned int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int __a, vector unsigned char __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int __a, vector unsigned short __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vsr(vector bool int __a, vector unsigned int __b)
+{
+  return (vector bool int)__builtin_altivec_vsr((vector int)__a, (vector int)__b);
+}
+
+/* vec_sro */
+
+static vector signed char __ATTRS_o_ai
+vec_sro(vector signed char __a, vector signed char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sro(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sro(vector unsigned char __a, vector signed char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sro(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sro(vector short __a, vector signed char __b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_sro(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sro(vector unsigned short __a, vector signed char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sro(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sro(vector pixel __a, vector signed char __b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_sro(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sro(vector int __a, vector signed char __b)
+{
+  return (vector int)__builtin_altivec_vsro(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sro(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsro(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sro(vector unsigned int __a, vector signed char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sro(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_sro(vector float __a, vector signed char __b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_sro(vector float __a, vector unsigned char __b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+/* vec_vsro */
+
+static vector signed char __ATTRS_o_ai
+vec_vsro(vector signed char __a, vector signed char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsro(vector signed char __a, vector unsigned char __b)
+{
+  return (vector signed char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsro(vector unsigned char __a, vector signed char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsro(vector unsigned char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsro(vector short __a, vector signed char __b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsro(vector short __a, vector unsigned char __b)
+{
+  return (vector short)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsro(vector unsigned short __a, vector signed char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsro(vector unsigned short __a, vector unsigned char __b)
+{
+  return (vector unsigned short)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsro(vector pixel __a, vector signed char __b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector pixel __ATTRS_o_ai
+vec_vsro(vector pixel __a, vector unsigned char __b)
+{
+  return (vector pixel)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsro(vector int __a, vector signed char __b)
+{
+  return (vector int)__builtin_altivec_vsro(__a, (vector int)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsro(vector int __a, vector unsigned char __b)
+{
+  return (vector int)__builtin_altivec_vsro(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsro(vector unsigned int __a, vector signed char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsro(vector unsigned int __a, vector unsigned char __b)
+{
+  return (vector unsigned int)
+           __builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsro(vector float __a, vector signed char __b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+static vector float __ATTRS_o_ai
+vec_vsro(vector float __a, vector unsigned char __b)
+{
+  return (vector float)__builtin_altivec_vsro((vector int)__a, (vector int)__b);
+}
+
+/* vec_st */
+
+static void __ATTRS_o_ai
+vec_st(vector signed char __a, int __b, vector signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool char __a, int __b, vector bool char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector short __a, int __b, vector short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool short __a, int __b, vector bool short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector pixel __a, int __b, vector pixel *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector int __a, int __b, vector int *__c)
+{
+  __builtin_altivec_stvx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector bool int __a, int __b, vector bool int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector float __a, int __b, vector float *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_st(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+/* vec_stvx */
+
+static void __ATTRS_o_ai
+vec_stvx(vector signed char __a, int __b, vector signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool char __a, int __b, vector bool char *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector short __a, int __b, vector short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool short __a, int __b, vector bool short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector pixel __a, int __b, vector pixel *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector int __a, int __b, vector int *__c)
+{
+  __builtin_altivec_stvx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector bool int __a, int __b, vector bool int *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector float __a, int __b, vector float *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvx(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvx((vector int)__a, __b, __c);
+}
+
+/* vec_ste */
+
+static void __ATTRS_o_ai
+vec_ste(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvewx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_ste(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+/* vec_stvebx */
+
+static void __ATTRS_o_ai
+vec_stvebx(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvebx(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvebx((vector char)__a, __b, __c);
+}
+
+/* vec_stvehx */
+
+static void __ATTRS_o_ai
+vec_stvehx(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvehx(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvehx((vector short)__a, __b, __c);
+}
+
+/* vec_stvewx */
+
+static void __ATTRS_o_ai
+vec_stvewx(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvewx(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvewx(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvewx((vector int)__a, __b, __c);
+}
+
+/* vec_stl */
+
+static void __ATTRS_o_ai
+vec_stl(vector signed char __a, int __b, vector signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool char __a, int __b, vector bool char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector short __a, int __b, vector short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool short __a, int __b, vector bool short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector pixel __a, int __b, vector pixel *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector int __a, int __b, vector int *__c)
+{
+  __builtin_altivec_stvxl(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvxl(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector bool int __a, int __b, vector bool int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector float __a, int __b, vector float *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stl(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+/* vec_stvxl */
+
+static void __ATTRS_o_ai
+vec_stvxl(vector signed char __a, int __b, vector signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector signed char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char __a, int __b, signed char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char __a, int __b, unsigned char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool char __a, int __b, vector bool char *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector short __a, int __b, vector short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool short __a, int __b, vector bool short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel __a, int __b, short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel __a, int __b, unsigned short *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector pixel __a, int __b, vector pixel *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector int __a, int __b, vector int *__c)
+{
+  __builtin_altivec_stvxl(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvxl(__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int __a, int __b, int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int __a, int __b, unsigned int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector bool int __a, int __b, vector bool int *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector float __a, int __b, vector float *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvxl(vector float __a, int __b, float *__c)
+{
+  __builtin_altivec_stvxl((vector int)__a, __b, __c);
+}
+
+/* vec_sub */
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector signed char __a, vector signed char __b)
+{
+  return __a - __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a - __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_sub(vector signed char __a, vector bool char __b)
+{
+  return __a - (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a - __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_sub(vector unsigned char __a, vector bool char __b)
+{
+  return __a - (vector unsigned char)__b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector short __a, vector short __b)
+{
+  return __a - __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector bool short __a, vector short __b)
+{
+  return (vector short)__a - __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_sub(vector short __a, vector bool short __b)
+{
+  return __a - (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a - __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_sub(vector unsigned short __a, vector bool short __b)
+{
+  return __a - (vector unsigned short)__b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector int __a, vector int __b)
+{
+  return __a - __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector bool int __a, vector int __b)
+{
+  return (vector int)__a - __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_sub(vector int __a, vector bool int __b)
+{
+  return __a - (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a - __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sub(vector unsigned int __a, vector bool int __b)
+{
+  return __a - (vector unsigned int)__b;
+}
+
+static vector float __ATTRS_o_ai
+vec_sub(vector float __a, vector float __b)
+{
+  return __a - __b;
+}
+
+/* vec_vsububm */
+
+#define __builtin_altivec_vsububm vec_vsububm
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector signed char __a, vector signed char __b)
+{
+  return __a - __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a - __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsububm(vector signed char __a, vector bool char __b)
+{
+  return __a - (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a - __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububm(vector unsigned char __a, vector bool char __b)
+{
+  return __a - (vector unsigned char)__b;
+}
+
+/* vec_vsubuhm */
+
+#define __builtin_altivec_vsubuhm vec_vsubuhm
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector short __a, vector short __b)
+{
+  return __a - __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector bool short __a, vector short __b)
+{
+  return (vector short)__a - __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubuhm(vector short __a, vector bool short __b)
+{
+  return __a - (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a - __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhm(vector unsigned short __a, vector bool short __b)
+{
+  return __a - (vector unsigned short)__b;
+}
+
+/* vec_vsubuwm */
+
+#define __builtin_altivec_vsubuwm vec_vsubuwm
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector int __a, vector int __b)
+{
+  return __a - __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector bool int __a, vector int __b)
+{
+  return (vector int)__a - __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubuwm(vector int __a, vector bool int __b)
+{
+  return __a - (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a - __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a - __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuwm(vector unsigned int __a, vector bool int __b)
+{
+  return __a - (vector unsigned int)__b;
+}
+
+/* vec_vsubfp */
+
+#define __builtin_altivec_vsubfp vec_vsubfp
+
+static vector float __attribute__((__always_inline__))
+vec_vsubfp(vector float __a, vector float __b)
+{
+  return __a - __b;
+}
+
+/* vec_subc */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_subc(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubcuw(__a, __b);
+}
+
+/* vec_vsubcuw */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vsubcuw(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubcuw(__a, __b);
+}
+
+/* vec_subs */
+
+static vector signed char __ATTRS_o_ai
+vec_subs(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vsubsbs(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_subs(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vsubsbs((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_subs(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vsubsbs(__a, (vector signed char)__b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_subs(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vsububs(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_subs(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vsububs((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_subs(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vsububs(__a, (vector unsigned char)__b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vsubshs(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vsubshs((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_subs(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vsubshs(__a, (vector short)__b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_subs(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsubuhs(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_subs(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsubuhs((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_subs(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vsubuhs(__a, (vector unsigned short)__b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vsubsws(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vsubsws((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_subs(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vsubsws(__a, (vector int)__b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubuws(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubuws((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_subs(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vsubuws(__a, (vector unsigned int)__b);
+}
+
+/* vec_vsubsbs */
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vsubsbs(__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vsubsbs((vector signed char)__a, __b);
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vsubsbs(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vsubsbs(__a, (vector signed char)__b);
+}
+
+/* vec_vsububs */
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vsububs(__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vsububs((vector unsigned char)__a, __b);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vsububs(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vsububs(__a, (vector unsigned char)__b);
+}
+
+/* vec_vsubshs */
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vsubshs(__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vsubshs((vector short)__a, __b);
+}
+
+static vector short __ATTRS_o_ai
+vec_vsubshs(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vsubshs(__a, (vector short)__b);
+}
+
+/* vec_vsubuhs */
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsubuhs(__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vsubuhs((vector unsigned short)__a, __b);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vsubuhs(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vsubuhs(__a, (vector unsigned short)__b);
+}
+
+/* vec_vsubsws */
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vsubsws(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vsubsws((vector int)__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_vsubsws(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vsubsws(__a, (vector int)__b);
+}
+
+/* vec_vsubuws */
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubuws(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsubuws((vector unsigned int)__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vsubuws(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vsubuws(__a, (vector unsigned int)__b);
+}
+
+/* vec_sum4s */
+
+static vector int __ATTRS_o_ai
+vec_sum4s(vector signed char __a, vector int __b)
+{
+  return __builtin_altivec_vsum4sbs(__a, __b);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_sum4s(vector unsigned char __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsum4ubs(__a, __b);
+}
+
+static vector int __ATTRS_o_ai
+vec_sum4s(vector signed short __a, vector int __b)
+{
+  return __builtin_altivec_vsum4shs(__a, __b);
+}
+
+/* vec_vsum4sbs */
+
+static vector int __attribute__((__always_inline__))
+vec_vsum4sbs(vector signed char __a, vector int __b)
+{
+  return __builtin_altivec_vsum4sbs(__a, __b);
+}
+
+/* vec_vsum4ubs */
+
+static vector unsigned int __attribute__((__always_inline__))
+vec_vsum4ubs(vector unsigned char __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vsum4ubs(__a, __b);
+}
+
+/* vec_vsum4shs */
+
+static vector int __attribute__((__always_inline__))
+vec_vsum4shs(vector signed short __a, vector int __b)
+{
+  return __builtin_altivec_vsum4shs(__a, __b);
+}
+
+/* vec_sum2s */
+
+/* The vsum2sws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian elements
+   1 and 3 (little-endian element 0 and 2).  For ease of porting the
+   programmer wants elements 1 and 3 in both cases, so for little
+   endian we must perform some permutes.  */
+
+static vector signed int __attribute__((__always_inline__))
+vec_sum2s(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
+  return __builtin_altivec_vsum2sws(__a, __b);
+#endif
+}
+
+/* vec_vsum2sws */
+
+static vector signed int __attribute__((__always_inline__))
+vec_vsum2sws(vector int __a, vector int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
+  return __builtin_altivec_vsum2sws(__a, __b);
+#endif
+}
+
+/* vec_sums */
+
+/* The vsumsws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian element 3
+   (little-endian element 0).  For ease of porting the programmer
+   wants element 3 in both cases, so for little endian we must perform
+   some permutes.  */
+
+static vector signed int __attribute__((__always_inline__))
+vec_sums(vector signed int __a, vector signed int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)vec_splat(__b, 3);
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)(0, 0, 0, __b[0]);
+#else
+  return __builtin_altivec_vsumsws(__a, __b);
+#endif
+}
+
+/* vec_vsumsws */
+
+static vector signed int __attribute__((__always_inline__))
+vec_vsumsws(vector signed int __a, vector signed int __b)
+{
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)vec_splat(__b, 3);
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)(0, 0, 0, __b[0]);
+#else
+  return __builtin_altivec_vsumsws(__a, __b);
+#endif
+}
+
+/* vec_trunc */
+
+static vector float __attribute__((__always_inline__))
+vec_trunc(vector float __a)
+{
+  return __builtin_altivec_vrfiz(__a);
+}
+
+/* vec_vrfiz */
+
+static vector float __attribute__((__always_inline__))
+vec_vrfiz(vector float __a)
+{
+  return __builtin_altivec_vrfiz(__a);
+}
+
+/* vec_unpackh */
+
+/* The vector unpack instructions all have a big-endian bias, so for
+   little endian we must reverse the meanings of "high" and "low."  */
+
+static vector short __ATTRS_o_ai
+vec_unpackh(vector signed char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_unpackh(vector bool char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
+}
+
+static vector int __ATTRS_o_ai
+vec_unpackh(vector short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
+  return __builtin_altivec_vupkhsh(__a);
+#endif
+}
+
+static vector bool int __ATTRS_o_ai
+vec_unpackh(vector bool short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_unpackh(vector pixel __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
+}
+
+/* vec_vupkhsb */
+
+static vector short __ATTRS_o_ai
+vec_vupkhsb(vector signed char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vupkhsb(vector bool char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
+}
+
+/* vec_vupkhsh */
+
+static vector int __ATTRS_o_ai
+vec_vupkhsh(vector short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
+  return __builtin_altivec_vupkhsh(__a);
+#endif
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vupkhsh(vector bool short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vupkhsh(vector pixel __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
+}
+
+/* vec_unpackl */
+
+static vector short __ATTRS_o_ai
+vec_unpackl(vector signed char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
+  return __builtin_altivec_vupklsb((vector char)__a);
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_unpackl(vector bool char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
+}
+
+static vector int __ATTRS_o_ai
+vec_unpackl(vector short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
+  return __builtin_altivec_vupklsh(__a);
+#endif
+}
+
+static vector bool int __ATTRS_o_ai
+vec_unpackl(vector bool short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_unpackl(vector pixel __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
+}
+
+/* vec_vupklsb */
+
+static vector short __ATTRS_o_ai
+vec_vupklsb(vector signed char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
+  return __builtin_altivec_vupklsb((vector char)__a);
+#endif
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vupklsb(vector bool char __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
+}
+
+/* vec_vupklsh */
+
+static vector int __ATTRS_o_ai
+vec_vupklsh(vector short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
+  return __builtin_altivec_vupklsh(__a);
+#endif
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vupklsh(vector bool short __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vupklsh(vector pixel __a)
+{
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
+}
+
+/* vec_xor */
+
+#define __builtin_altivec_vxor vec_xor
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector signed char __a, vector signed char __b)
+{
+  return __a ^ __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a ^ __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_xor(vector signed char __a, vector bool char __b)
+{
+  return __a ^ (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a ^ __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char __a, vector bool char __b)
+{
+  return __a ^ (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_xor(vector bool char __a, vector bool char __b)
+{
+  return __a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector short __a, vector short __b)
+{
+  return __a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector bool short __a, vector short __b)
+{
+  return (vector short)__a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_xor(vector short __a, vector bool short __b)
+{
+  return __a ^ (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a ^ __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_xor(vector unsigned short __a, vector bool short __b)
+{
+  return __a ^ (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_xor(vector bool short __a, vector bool short __b)
+{
+  return __a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector int __a, vector int __b)
+{
+  return __a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector bool int __a, vector int __b)
+{
+  return (vector int)__a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_xor(vector int __a, vector bool int __b)
+{
+  return __a ^ (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a ^ __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_xor(vector unsigned int __a, vector bool int __b)
+{
+  return __a ^ (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_xor(vector bool int __a, vector bool int __b)
+{
+  return __a ^ __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_xor(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* vec_vxor */
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector signed char __a, vector signed char __b)
+{
+  return __a ^ __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector bool char __a, vector signed char __b)
+{
+  return (vector signed char)__a ^ __b;
+}
+
+static vector signed char __ATTRS_o_ai
+vec_vxor(vector signed char __a, vector bool char __b)
+{
+  return __a ^ (vector signed char)__b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector unsigned char __a, vector unsigned char __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector bool char __a, vector unsigned char __b)
+{
+  return (vector unsigned char)__a ^ __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_vxor(vector unsigned char __a, vector bool char __b)
+{
+  return __a ^ (vector unsigned char)__b;
+}
+
+static vector bool char __ATTRS_o_ai
+vec_vxor(vector bool char __a, vector bool char __b)
+{
+  return __a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector short __a, vector short __b)
+{
+  return __a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector bool short __a, vector short __b)
+{
+  return (vector short)__a ^ __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_vxor(vector short __a, vector bool short __b)
+{
+  return __a ^ (vector short)__b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector unsigned short __a, vector unsigned short __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector bool short __a, vector unsigned short __b)
+{
+  return (vector unsigned short)__a ^ __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_vxor(vector unsigned short __a, vector bool short __b)
+{
+  return __a ^ (vector unsigned short)__b;
+}
+
+static vector bool short __ATTRS_o_ai
+vec_vxor(vector bool short __a, vector bool short __b)
+{
+  return __a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector int __a, vector int __b)
+{
+  return __a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector bool int __a, vector int __b)
+{
+  return (vector int)__a ^ __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_vxor(vector int __a, vector bool int __b)
+{
+  return __a ^ (vector int)__b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector unsigned int __a, vector unsigned int __b)
+{
+  return __a ^ __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector bool int __a, vector unsigned int __b)
+{
+  return (vector unsigned int)__a ^ __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_vxor(vector unsigned int __a, vector bool int __b)
+{
+  return __a ^ (vector unsigned int)__b;
+}
+
+static vector bool int __ATTRS_o_ai
+vec_vxor(vector bool int __a, vector bool int __b)
+{
+  return __a ^ __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector float __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector bool int __a, vector float __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+static vector float __ATTRS_o_ai
+vec_vxor(vector float __a, vector bool int __b)
+{
+  vector unsigned int __res = (vector unsigned int)__a ^ (vector unsigned int)__b;
+  return (vector float)__res;
+}
+
+/* ------------------------ extensions for CBEA ----------------------------- */
+
+/* vec_extract */
+
+static signed char __ATTRS_o_ai
+vec_extract(vector signed char __a, int __b)
+{
+  return __a[__b];
+}
+
+static unsigned char __ATTRS_o_ai
+vec_extract(vector unsigned char __a, int __b)
+{
+  return __a[__b];
+}
+
+static short __ATTRS_o_ai
+vec_extract(vector short __a, int __b)
+{
+  return __a[__b];
+}
+
+static unsigned short __ATTRS_o_ai
+vec_extract(vector unsigned short __a, int __b)
+{
+  return __a[__b];
+}
+
+static int __ATTRS_o_ai
+vec_extract(vector int __a, int __b)
+{
+  return __a[__b];
+}
+
+static unsigned int __ATTRS_o_ai
+vec_extract(vector unsigned int __a, int __b)
+{
+  return __a[__b];
+}
+
+static float __ATTRS_o_ai
+vec_extract(vector float __a, int __b)
+{
+  return __a[__b];
+}
+
+/* vec_insert */
+
+static vector signed char __ATTRS_o_ai
+vec_insert(signed char __a, vector signed char __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_insert(unsigned char __a, vector unsigned char __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector short __ATTRS_o_ai
+vec_insert(short __a, vector short __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_insert(unsigned short __a, vector unsigned short __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector int __ATTRS_o_ai
+vec_insert(int __a, vector int __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_insert(unsigned int __a, vector unsigned int __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+static vector float __ATTRS_o_ai
+vec_insert(float __a, vector float __b, int __c)
+{
+  __b[__c] = __a;
+  return __b;
+}
+
+/* vec_lvlx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvlx(int __a, const signed char *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector signed char)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvlx(int __a, const vector signed char *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector signed char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvlx(int __a, const unsigned char *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned char)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvlx(int __a, const vector unsigned char *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvlx(int __a, const vector bool char *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector bool char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvlx(int __a, const short *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector short)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvlx(int __a, const vector short *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvlx(int __a, const unsigned short *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned short)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvlx(int __a, const vector unsigned short *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvlx(int __a, const vector bool short *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector bool short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvlx(int __a, const vector pixel *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector pixel)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvlx(int __a, const int *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector int)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvlx(int __a, const vector int *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvlx(int __a, const unsigned int *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned int)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvlx(int __a, const vector unsigned int *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector unsigned int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvlx(int __a, const vector bool int *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector bool int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvlx(int __a, const float *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector float)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvlx(int __a, const vector float *__b)
+{
+  return vec_perm(vec_ld(__a, __b),
+                  (vector float)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+/* vec_lvlxl */
+
+static vector signed char __ATTRS_o_ai
+vec_lvlxl(int __a, const signed char *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector signed char)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvlxl(int __a, const vector signed char *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector signed char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvlxl(int __a, const unsigned char *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned char)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvlxl(int __a, const vector unsigned char *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvlxl(int __a, const vector bool char *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector bool char)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvlxl(int __a, const short *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector short)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvlxl(int __a, const vector short *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvlxl(int __a, const unsigned short *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned short)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvlxl(int __a, const vector unsigned short *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvlxl(int __a, const vector bool short *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector bool short)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvlxl(int __a, const vector pixel *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector pixel)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvlxl(int __a, const int *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector int)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvlxl(int __a, const vector int *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvlxl(int __a, const unsigned int *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned int)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvlxl(int __a, const vector unsigned int *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector unsigned int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvlxl(int __a, const vector bool int *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector bool int)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvlxl(int __a, const float *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector float)(0),
+                  vec_lvsl(__a, __b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvlxl(int __a, vector float *__b)
+{
+  return vec_perm(vec_ldl(__a, __b),
+                  (vector float)(0),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+/* vec_lvrx */
+
+static vector signed char __ATTRS_o_ai
+vec_lvrx(int __a, const signed char *__b)
+{
+  return vec_perm((vector signed char)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvrx(int __a, const vector signed char *__b)
+{
+  return vec_perm((vector signed char)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvrx(int __a, const unsigned char *__b)
+{
+  return vec_perm((vector unsigned char)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvrx(int __a, const vector unsigned char *__b)
+{
+  return vec_perm((vector unsigned char)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvrx(int __a, const vector bool char *__b)
+{
+  return vec_perm((vector bool char)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvrx(int __a, const short *__b)
+{
+  return vec_perm((vector short)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvrx(int __a, const vector short *__b)
+{
+  return vec_perm((vector short)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvrx(int __a, const unsigned short *__b)
+{
+  return vec_perm((vector unsigned short)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvrx(int __a, const vector unsigned short *__b)
+{
+  return vec_perm((vector unsigned short)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvrx(int __a, const vector bool short *__b)
+{
+  return vec_perm((vector bool short)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvrx(int __a, const vector pixel *__b)
+{
+  return vec_perm((vector pixel)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvrx(int __a, const int *__b)
+{
+  return vec_perm((vector int)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvrx(int __a, const vector int *__b)
+{
+  return vec_perm((vector int)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvrx(int __a, const unsigned int *__b)
+{
+  return vec_perm((vector unsigned int)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvrx(int __a, const vector unsigned int *__b)
+{
+  return vec_perm((vector unsigned int)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvrx(int __a, const vector bool int *__b)
+{
+  return vec_perm((vector bool int)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvrx(int __a, const float *__b)
+{
+  return vec_perm((vector float)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvrx(int __a, const vector float *__b)
+{
+  return vec_perm((vector float)(0),
+                  vec_ld(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+/* vec_lvrxl */
+
+static vector signed char __ATTRS_o_ai
+vec_lvrxl(int __a, const signed char *__b)
+{
+  return vec_perm((vector signed char)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector signed char __ATTRS_o_ai
+vec_lvrxl(int __a, const vector signed char *__b)
+{
+  return vec_perm((vector signed char)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvrxl(int __a, const unsigned char *__b)
+{
+  return vec_perm((vector unsigned char)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_lvrxl(int __a, const vector unsigned char *__b)
+{
+  return vec_perm((vector unsigned char)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool char __ATTRS_o_ai
+vec_lvrxl(int __a, const vector bool char *__b)
+{
+  return vec_perm((vector bool char)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvrxl(int __a, const short *__b)
+{
+  return vec_perm((vector short)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector short __ATTRS_o_ai
+vec_lvrxl(int __a, const vector short *__b)
+{
+  return vec_perm((vector short)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvrxl(int __a, const unsigned short *__b)
+{
+  return vec_perm((vector unsigned short)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_lvrxl(int __a, const vector unsigned short *__b)
+{
+  return vec_perm((vector unsigned short)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool short __ATTRS_o_ai
+vec_lvrxl(int __a, const vector bool short *__b)
+{
+  return vec_perm((vector bool short)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector pixel __ATTRS_o_ai
+vec_lvrxl(int __a, const vector pixel *__b)
+{
+  return vec_perm((vector pixel)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvrxl(int __a, const int *__b)
+{
+  return vec_perm((vector int)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector int __ATTRS_o_ai
+vec_lvrxl(int __a, const vector int *__b)
+{
+  return vec_perm((vector int)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvrxl(int __a, const unsigned int *__b)
+{
+  return vec_perm((vector unsigned int)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_lvrxl(int __a, const vector unsigned int *__b)
+{
+  return vec_perm((vector unsigned int)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector bool int __ATTRS_o_ai
+vec_lvrxl(int __a, const vector bool int *__b)
+{
+  return vec_perm((vector bool int)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvrxl(int __a, const float *__b)
+{
+  return vec_perm((vector float)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, __b));
+}
+
+static vector float __ATTRS_o_ai
+vec_lvrxl(int __a, const vector float *__b)
+{
+  return vec_perm((vector float)(0),
+                  vec_ldl(__a, __b),
+                  vec_lvsl(__a, (unsigned char *)__b));
+}
+
+/* vec_stvlx */
+
+static void __ATTRS_o_ai
+vec_stvlx(vector signed char __a, int __b, signed char *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector signed char __a, int __b, vector signed char *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector bool char __a, int __b, vector bool char *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector short __a, int __b, short *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector short __a, int __b, vector short *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector bool short __a, int __b, vector bool short *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector pixel __a, int __b, vector pixel *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector int __a, int __b, int *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector int __a, int __b, vector int *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector bool int __a, int __b, vector bool int *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlx(vector float __a, int __b, vector float *__c)
+{
+  return vec_st(vec_perm(vec_lvrx(__b, __c),
+                         __a,
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+/* vec_stvlxl */
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector signed char __a, int __b, signed char *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector signed char __a, int __b, vector signed char *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector bool char __a, int __b, vector bool char *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector short __a, int __b, short *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector short __a, int __b, vector short *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector bool short __a, int __b, vector bool short *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector pixel __a, int __b, vector pixel *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector int __a, int __b, int *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector int __a, int __b, vector int *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector bool int __a, int __b, vector bool int *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvlxl(vector float __a, int __b, vector float *__c)
+{
+  return vec_stl(vec_perm(vec_lvrx(__b, __c),
+                          __a,
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+/* vec_stvrx */
+
+static void __ATTRS_o_ai
+vec_stvrx(vector signed char __a, int __b, signed char *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector signed char __a, int __b, vector signed char *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector bool char __a, int __b, vector bool char *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector short __a, int __b, short *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector short __a, int __b, vector short *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector bool short __a, int __b, vector bool short *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector pixel __a, int __b, vector pixel *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector int __a, int __b, int *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector int __a, int __b, vector int *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, __c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector bool int __a, int __b, vector bool int *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrx(vector float __a, int __b, vector float *__c)
+{
+  return vec_st(vec_perm(__a,
+                         vec_lvlx(__b, __c),
+                         vec_lvsr(__b, (unsigned char *)__c)),
+                __b, __c);
+}
+
+/* vec_stvrxl */
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector signed char __a, int __b, signed char *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector signed char __a, int __b, vector signed char *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned char __a, int __b, unsigned char *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned char __a, int __b, vector unsigned char *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector bool char __a, int __b, vector bool char *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector short __a, int __b, short *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector short __a, int __b, vector short *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned short __a, int __b, unsigned short *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned short __a, int __b, vector unsigned short *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector bool short __a, int __b, vector bool short *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector pixel __a, int __b, vector pixel *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector int __a, int __b, int *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector int __a, int __b, vector int *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned int __a, int __b, unsigned int *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, __c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector unsigned int __a, int __b, vector unsigned int *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector bool int __a, int __b, vector bool int *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+static void __ATTRS_o_ai
+vec_stvrxl(vector float __a, int __b, vector float *__c)
+{
+  return vec_stl(vec_perm(__a,
+                          vec_lvlx(__b, __c),
+                          vec_lvsr(__b, (unsigned char *)__c)),
+                 __b, __c);
+}
+
+/* vec_promote */
+
+static vector signed char __ATTRS_o_ai
+vec_promote(signed char __a, int __b)
+{
+  vector signed char __res = (vector signed char)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_promote(unsigned char __a, int __b)
+{
+  vector unsigned char __res = (vector unsigned char)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector short __ATTRS_o_ai
+vec_promote(short __a, int __b)
+{
+  vector short __res = (vector short)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_promote(unsigned short __a, int __b)
+{
+  vector unsigned short __res = (vector unsigned short)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector int __ATTRS_o_ai
+vec_promote(int __a, int __b)
+{
+  vector int __res = (vector int)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_promote(unsigned int __a, int __b)
+{
+  vector unsigned int __res = (vector unsigned int)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+static vector float __ATTRS_o_ai
+vec_promote(float __a, int __b)
+{
+  vector float __res = (vector float)(0);
+  __res[__b] = __a;
+  return __res;
+}
+
+/* vec_splats */
+
+static vector signed char __ATTRS_o_ai
+vec_splats(signed char __a)
+{
+  return (vector signed char)(__a);
+}
+
+static vector unsigned char __ATTRS_o_ai
+vec_splats(unsigned char __a)
+{
+  return (vector unsigned char)(__a);
+}
+
+static vector short __ATTRS_o_ai
+vec_splats(short __a)
+{
+  return (vector short)(__a);
+}
+
+static vector unsigned short __ATTRS_o_ai
+vec_splats(unsigned short __a)
+{
+  return (vector unsigned short)(__a);
+}
+
+static vector int __ATTRS_o_ai
+vec_splats(int __a)
+{
+  return (vector int)(__a);
+}
+
+static vector unsigned int __ATTRS_o_ai
+vec_splats(unsigned int __a)
+{
+  return (vector unsigned int)(__a);
+}
+
+static vector float __ATTRS_o_ai
+vec_splats(float __a)
+{
+  return (vector float)(__a);
+}
+
+/* ----------------------------- predicates --------------------------------- */
+
+/* vec_all_eq */
+
+static int __ATTRS_o_ai
+vec_all_eq(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_LT, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned short __a, vector unsigned short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned short __a, vector bool short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool short __a, vector short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool short __a, vector unsigned short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool short __a, vector bool short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector pixel __a, vector pixel __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_LT, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_eq(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT, __a, __b);
+}
+
+/* vec_all_ge */
+
+static int __ATTRS_o_ai
+vec_all_ge(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, (vector signed char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __b, (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, (vector short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __b, (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, (vector int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __b, (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_ge(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT, __a, __b);
+}
+
+/* vec_all_gt */
+
+static int __ATTRS_o_ai
+vec_all_gt(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __a, (vector signed char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, __a, (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __a, (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __a, (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_gt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __a, __b);
+}
+
+/* vec_all_in */
+
+static int __attribute__((__always_inline__))
+vec_all_in(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpbfp_p(__CR6_EQ, __a, __b);
+}
+
+/* vec_all_le */
+
+static int __ATTRS_o_ai
+vec_all_le(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ, __a, (vector signed char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, __a, (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ, (vector unsigned char)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, __a, (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ, (vector unsigned short)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, __a, (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ, (vector unsigned int)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_le(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT, __b, __a);
+}
+
+/* vec_all_lt */
+
+static int __ATTRS_o_ai
+vec_all_lt(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT, (vector signed char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, (vector unsigned char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT, __b, (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT, (vector short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, (vector unsigned short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT, __b, (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT, (vector int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, (vector unsigned int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT, __b, (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_all_lt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __b, __a);
+}
+
+/* vec_all_nan */
+
+static int __attribute__((__always_inline__))
+vec_all_nan(vector float __a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __a);
+}
+
+/* vec_all_ne */
+
+static int __ATTRS_o_ai
+vec_all_ne(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpequb_p(__CR6_EQ, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned short __a, vector unsigned short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned short __a, vector bool short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool short __a, vector short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool short __a, vector unsigned short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool short __a, vector bool short __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector pixel __a, vector pixel __b)
+{
+  return
+    __builtin_altivec_vcmpequh_p(__CR6_EQ, (vector short)__a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_all_ne(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __b);
+}
+
+/* vec_all_nge */
+
+static int __attribute__((__always_inline__))
+vec_all_nge(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ, __a, __b);
+}
+
+/* vec_all_ngt */
+
+static int __attribute__((__always_inline__))
+vec_all_ngt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, __a, __b);
+}
+
+/* vec_all_nle */
+
+static int __attribute__((__always_inline__))
+vec_all_nle(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ, __b, __a);
+}
+
+/* vec_all_nlt */
+
+static int __attribute__((__always_inline__))
+vec_all_nlt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, __b, __a);
+}
+
+/* vec_all_numeric */
+
+static int __attribute__((__always_inline__))
+vec_all_numeric(vector float __a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT, __a, __a);
+}
+
+/* vec_any_eq */
+
+static int __ATTRS_o_ai
+vec_any_eq(vector signed char __a, vector signed char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector signed char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned char __a, vector unsigned char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool char __a, vector signed char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool char __a, vector unsigned char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_EQ_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, 
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, 
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector pixel __a, vector pixel __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_EQ_REV, 
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned int __a, vector unsigned int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector unsigned int __a, vector bool int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool int __a, vector int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool int __a, vector unsigned int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector bool int __a, vector bool int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_EQ_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_eq(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __b);
+}
+
+/* vec_any_ge */
+
+static int __ATTRS_o_ai
+vec_any_ge(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, (vector signed char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __b, (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, (vector short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned short __a, vector bool short __b)
+{
+  return
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short __a, vector unsigned short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __b, (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, (vector int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __b, (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_ge(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __a, __b);
+}
+
+/* vec_any_gt */
+
+static int __ATTRS_o_ai
+vec_any_gt(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __a, (vector signed char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned char __a, vector bool char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __a, (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char __a, vector unsigned char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned short __a, vector bool short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __a, (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short __a, vector unsigned short __b)
+{
+  return
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __a, (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_gt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __a, __b);
+}
+
+/* vec_any_le */
+
+static int __ATTRS_o_ai
+vec_any_le(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_LT_REV, __a, (vector signed char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned char __a, vector bool char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, __a, (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char __a, vector unsigned char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_LT_REV, (vector unsigned char)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_LT_REV,
+                                      (vector unsigned char)__a,
+                                      (vector unsigned char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_LT_REV, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned short __a, vector bool short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, __a, (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short __a, vector unsigned short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV, (vector unsigned short)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_LT_REV,
+                                      (vector unsigned short)__a,
+                                      (vector unsigned short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_LT_REV, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, __a, (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV, (vector unsigned int)__a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_LT_REV,
+                                      (vector unsigned int)__a,
+                                      (vector unsigned int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_le(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __b, __a);
+}
+
+/* vec_any_lt */
+
+static int __ATTRS_o_ai
+vec_any_lt(vector signed char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector signed char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtsb_p(__CR6_EQ_REV, (vector signed char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned char __a, vector unsigned char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned char __a, vector bool char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, (vector unsigned char)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char __a, vector signed char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char __a, vector unsigned char __b)
+{
+  return 
+    __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV, __b, (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool char __a, vector bool char __b)
+{
+  return __builtin_altivec_vcmpgtub_p(__CR6_EQ_REV,
+                                      (vector unsigned char)__b,
+                                      (vector unsigned char)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtsh_p(__CR6_EQ_REV, (vector short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned short __a, vector bool short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, (vector unsigned short)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short __a, vector unsigned short __b)
+{
+  return 
+    __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV, __b, (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpgtuh_p(__CR6_EQ_REV,
+                                      (vector unsigned short)__b,
+                                      (vector unsigned short)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtsw_p(__CR6_EQ_REV, (vector int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector unsigned int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, (vector unsigned int)__b, __a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int __a, vector unsigned int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV, __b, (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector bool int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpgtuw_p(__CR6_EQ_REV,
+                                      (vector unsigned int)__b,
+                                      (vector unsigned int)__a);
+}
+
+static int __ATTRS_o_ai
+vec_any_lt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __b, __a);
+}
+
+/* vec_any_nan */
+
+static int __attribute__((__always_inline__))
+vec_any_nan(vector float __a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __a);
+}
+
+/* vec_any_ne */
+
+static int __ATTRS_o_ai
+vec_any_ne(vector signed char __a, vector signed char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector signed char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned char __a, vector unsigned char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool char __a, vector signed char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool char __a, vector unsigned char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool char __a, vector bool char __b)
+{
+  return
+    __builtin_altivec_vcmpequb_p(__CR6_LT_REV, (vector char)__a, (vector char)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, __a, (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV, 
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool short __a, vector short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool short __a, vector unsigned short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool short __a, vector bool short __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector pixel __a, vector pixel __b)
+{
+  return __builtin_altivec_vcmpequh_p(__CR6_LT_REV,
+                                      (vector short)__a,
+                                      (vector short)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector int __a, vector int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, __a, __b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector int __a, vector bool int __b)
+{
+  return __builtin_altivec_vcmpequw_p(__CR6_LT_REV, __a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned int __a, vector unsigned int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector unsigned int __a, vector bool int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool int __a, vector int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool int __a, vector unsigned int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector bool int __a, vector bool int __b)
+{
+  return
+    __builtin_altivec_vcmpequw_p(__CR6_LT_REV, (vector int)__a, (vector int)__b);
+}
+
+static int __ATTRS_o_ai
+vec_any_ne(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __b);
+}
+
+/* vec_any_nge */
+
+static int __attribute__((__always_inline__))
+vec_any_nge(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __a, __b);
+}
+
+/* vec_any_ngt */
+
+static int __attribute__((__always_inline__))
+vec_any_ngt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __a, __b);
+}
+
+/* vec_any_nle */
+
+static int __attribute__((__always_inline__))
+vec_any_nle(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgefp_p(__CR6_LT_REV, __b, __a);
+}
+
+/* vec_any_nlt */
+
+static int __attribute__((__always_inline__))
+vec_any_nlt(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpgtfp_p(__CR6_LT_REV, __b, __a);
+}
+
+/* vec_any_numeric */
+
+static int __attribute__((__always_inline__))
+vec_any_numeric(vector float __a)
+{
+  return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __a);
+}
+
+/* vec_any_out */
+
+static int __attribute__((__always_inline__))
+vec_any_out(vector float __a, vector float __b)
+{
+  return __builtin_altivec_vcmpbfp_p(__CR6_EQ_REV, __a, __b);
+}
+
+#undef __ATTRS_o_ai
+
+#endif /* __ALTIVEC_H */
diff --git a/lib/clang/3.5.2/include/ammintrin.h b/lib/clang/3.5.2/include/ammintrin.h
new file mode 100644
index 0000000..d87b9cd
--- /dev/null
+++ b/lib/clang/3.5.2/include/ammintrin.h
@@ -0,0 +1,68 @@
+/*===---- ammintrin.h - SSE4a intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __AMMINTRIN_H
+#define __AMMINTRIN_H
+
+#ifndef __SSE4A__
+#error "SSE4A instruction set not enabled"
+#else
+
+#include <pmmintrin.h>
+
+#define _mm_extracti_si64(x, len, idx) \
+  ((__m128i)__builtin_ia32_extrqi((__v2di)(__m128i)(x), \
+                                  (char)(len), (char)(idx)))
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_extract_si64(__m128i __x, __m128i __y)
+{
+  return (__m128i)__builtin_ia32_extrq((__v2di)__x, (__v16qi)__y);
+}
+
+#define _mm_inserti_si64(x, y, len, idx) \
+  ((__m128i)__builtin_ia32_insertqi((__v2di)(__m128i)(x), \
+                                    (__v2di)(__m128i)(y), \
+                                    (char)(len), (char)(idx)))
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_insert_si64(__m128i __x, __m128i __y)
+{
+  return (__m128i)__builtin_ia32_insertq((__v2di)__x, (__v2di)__y);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_sd(double *__p, __m128d __a)
+{
+  __builtin_ia32_movntsd(__p, (__v2df)__a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_ss(float *__p, __m128 __a)
+{
+  __builtin_ia32_movntss(__p, (__v4sf)__a);
+}
+
+#endif /* __SSE4A__ */
+
+#endif /* __AMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/arm_acle.h b/lib/clang/3.5.2/include/arm_acle.h
new file mode 100644
index 0000000..a0fd689
--- /dev/null
+++ b/lib/clang/3.5.2/include/arm_acle.h
@@ -0,0 +1,191 @@
+/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ARM_ACLE_H
+#define __ARM_ACLE_H
+
+#ifndef __ARM_ACLE
+#error "ACLE intrinsics support not enabled."
+#endif
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
+/* 8.3 Memory barriers */
+#if !defined(_MSC_VER)
+#define __dmb(i) __builtin_arm_dmb(i)
+#define __dsb(i) __builtin_arm_dsb(i)
+#define __isb(i) __builtin_arm_isb(i)
+#endif
+
+/* 8.4 Hints */
+
+#if !defined(_MSC_VER)
+static __inline__ void __attribute__((always_inline, nodebug)) __wfi(void) {
+  __builtin_arm_wfi();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __wfe(void) {
+  __builtin_arm_wfe();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __sev(void) {
+  __builtin_arm_sev();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __sevl(void) {
+  __builtin_arm_sevl();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __yield(void) {
+  __builtin_arm_yield();
+}
+#endif
+
+/* 8.7 NOP */
+static __inline__ void __attribute__((always_inline, nodebug)) __nop(void) {
+  __builtin_arm_nop();
+}
+
+/* 9 DATA-PROCESSING INTRINSICS */
+/* 9.2 Miscellaneous data-processing intrinsics */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __clz(uint32_t t) {
+  return __builtin_clz(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __clzl(unsigned long t) {
+  return __builtin_clzl(t);
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __clzll(uint64_t t) {
+#if __SIZEOF_LONG_LONG__ == 8
+  return __builtin_clzll(t);
+#else
+  return __builtin_clzl(t);
+#endif
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __rev(uint32_t t) {
+  return __builtin_bswap32(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __revl(unsigned long t) {
+#if __SIZEOF_LONG__ == 4
+  return __builtin_bswap32(t);
+#else
+  return __builtin_bswap64(t);
+#endif
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __revll(uint64_t t) {
+  return __builtin_bswap64(t);
+}
+
+/*
+ * 9.4 Saturating intrinsics
+ *
+ * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
+ * intrinsics are implemented and the flag is enabled.
+ */
+/* 9.4.1 Width-specified saturation intrinsics */
+#if __ARM_32BIT_STATE
+#define __ssat(x, y) __builtin_arm_ssat(x, y)
+#define __usat(x, y) __builtin_arm_usat(x, y)
+#endif
+
+/* 9.4.2 Saturating addition and subtraction intrinsics */
+#if __ARM_32BIT_STATE
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qadd(int32_t t, int32_t v) {
+  return __builtin_arm_qadd(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qsub(int32_t t, int32_t v) {
+  return __builtin_arm_qsub(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+__qdbl(int32_t t) {
+  return __builtin_arm_qadd(t, t);
+}
+#endif
+
+/* 9.7 CRC32 intrinsics */
+#if __ARM_FEATURE_CRC32
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32b(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32b(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32h(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32h(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32w(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32w(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32d(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32d(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cb(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32cb(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32ch(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32ch(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cw(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32cw(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cd(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32cd(a, b);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ARM_ACLE_H */
diff --git a/lib/clang/3.5.2/include/arm_neon.h b/lib/clang/3.5.2/include/arm_neon.h
new file mode 100644
index 0000000..7978aa0
--- /dev/null
+++ b/lib/clang/3.5.2/include/arm_neon.h
@@ -0,0 +1,68382 @@
+/*===---- arm_neon.h - ARM Neon intrinsics ---------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ARM_NEON_H
+#define __ARM_NEON_H
+
+#if !defined(__ARM_NEON)
+#error "NEON support not enabled"
+#endif
+
+#include <stdint.h>
+
+typedef float float32_t;
+typedef __fp16 float16_t;
+#ifdef __aarch64__
+typedef double float64_t;
+#endif
+
+#ifdef __aarch64__
+typedef uint8_t poly8_t;
+typedef uint16_t poly16_t;
+typedef uint64_t poly64_t;
+typedef __uint128_t poly128_t;
+#else
+typedef int8_t poly8_t;
+typedef int16_t poly16_t;
+#endif
+typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t;
+typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
+typedef __attribute__((neon_vector_type(4))) int16_t int16x4_t;
+typedef __attribute__((neon_vector_type(8))) int16_t int16x8_t;
+typedef __attribute__((neon_vector_type(2))) int32_t int32x2_t;
+typedef __attribute__((neon_vector_type(4))) int32_t int32x4_t;
+typedef __attribute__((neon_vector_type(1))) int64_t int64x1_t;
+typedef __attribute__((neon_vector_type(2))) int64_t int64x2_t;
+typedef __attribute__((neon_vector_type(8))) uint8_t uint8x8_t;
+typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
+typedef __attribute__((neon_vector_type(4))) uint16_t uint16x4_t;
+typedef __attribute__((neon_vector_type(8))) uint16_t uint16x8_t;
+typedef __attribute__((neon_vector_type(2))) uint32_t uint32x2_t;
+typedef __attribute__((neon_vector_type(4))) uint32_t uint32x4_t;
+typedef __attribute__((neon_vector_type(1))) uint64_t uint64x1_t;
+typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t;
+typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t;
+typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t;
+typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t;
+typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
+#ifdef __aarch64__
+typedef __attribute__((neon_vector_type(1))) float64_t float64x1_t;
+typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t;
+#endif
+typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t;
+typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
+typedef __attribute__((neon_polyvector_type(4))) poly16_t poly16x4_t;
+typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
+#ifdef __aarch64__
+typedef __attribute__((neon_polyvector_type(1))) poly64_t poly64x1_t;
+typedef __attribute__((neon_polyvector_type(2))) poly64_t poly64x2_t;
+#endif
+
+typedef struct int8x8x2_t {
+  int8x8_t val[2];
+} int8x8x2_t;
+
+typedef struct int8x16x2_t {
+  int8x16_t val[2];
+} int8x16x2_t;
+
+typedef struct int16x4x2_t {
+  int16x4_t val[2];
+} int16x4x2_t;
+
+typedef struct int16x8x2_t {
+  int16x8_t val[2];
+} int16x8x2_t;
+
+typedef struct int32x2x2_t {
+  int32x2_t val[2];
+} int32x2x2_t;
+
+typedef struct int32x4x2_t {
+  int32x4_t val[2];
+} int32x4x2_t;
+
+typedef struct int64x1x2_t {
+  int64x1_t val[2];
+} int64x1x2_t;
+
+typedef struct int64x2x2_t {
+  int64x2_t val[2];
+} int64x2x2_t;
+
+typedef struct uint8x8x2_t {
+  uint8x8_t val[2];
+} uint8x8x2_t;
+
+typedef struct uint8x16x2_t {
+  uint8x16_t val[2];
+} uint8x16x2_t;
+
+typedef struct uint16x4x2_t {
+  uint16x4_t val[2];
+} uint16x4x2_t;
+
+typedef struct uint16x8x2_t {
+  uint16x8_t val[2];
+} uint16x8x2_t;
+
+typedef struct uint32x2x2_t {
+  uint32x2_t val[2];
+} uint32x2x2_t;
+
+typedef struct uint32x4x2_t {
+  uint32x4_t val[2];
+} uint32x4x2_t;
+
+typedef struct uint64x1x2_t {
+  uint64x1_t val[2];
+} uint64x1x2_t;
+
+typedef struct uint64x2x2_t {
+  uint64x2_t val[2];
+} uint64x2x2_t;
+
+typedef struct float16x4x2_t {
+  float16x4_t val[2];
+} float16x4x2_t;
+
+typedef struct float16x8x2_t {
+  float16x8_t val[2];
+} float16x8x2_t;
+
+typedef struct float32x2x2_t {
+  float32x2_t val[2];
+} float32x2x2_t;
+
+typedef struct float32x4x2_t {
+  float32x4_t val[2];
+} float32x4x2_t;
+
+#ifdef __aarch64__
+typedef struct float64x1x2_t {
+  float64x1_t val[2];
+} float64x1x2_t;
+
+typedef struct float64x2x2_t {
+  float64x2_t val[2];
+} float64x2x2_t;
+
+#endif
+typedef struct poly8x8x2_t {
+  poly8x8_t val[2];
+} poly8x8x2_t;
+
+typedef struct poly8x16x2_t {
+  poly8x16_t val[2];
+} poly8x16x2_t;
+
+typedef struct poly16x4x2_t {
+  poly16x4_t val[2];
+} poly16x4x2_t;
+
+typedef struct poly16x8x2_t {
+  poly16x8_t val[2];
+} poly16x8x2_t;
+
+#ifdef __aarch64__
+typedef struct poly64x1x2_t {
+  poly64x1_t val[2];
+} poly64x1x2_t;
+
+typedef struct poly64x2x2_t {
+  poly64x2_t val[2];
+} poly64x2x2_t;
+
+#endif
+typedef struct int8x8x3_t {
+  int8x8_t val[3];
+} int8x8x3_t;
+
+typedef struct int8x16x3_t {
+  int8x16_t val[3];
+} int8x16x3_t;
+
+typedef struct int16x4x3_t {
+  int16x4_t val[3];
+} int16x4x3_t;
+
+typedef struct int16x8x3_t {
+  int16x8_t val[3];
+} int16x8x3_t;
+
+typedef struct int32x2x3_t {
+  int32x2_t val[3];
+} int32x2x3_t;
+
+typedef struct int32x4x3_t {
+  int32x4_t val[3];
+} int32x4x3_t;
+
+typedef struct int64x1x3_t {
+  int64x1_t val[3];
+} int64x1x3_t;
+
+typedef struct int64x2x3_t {
+  int64x2_t val[3];
+} int64x2x3_t;
+
+typedef struct uint8x8x3_t {
+  uint8x8_t val[3];
+} uint8x8x3_t;
+
+typedef struct uint8x16x3_t {
+  uint8x16_t val[3];
+} uint8x16x3_t;
+
+typedef struct uint16x4x3_t {
+  uint16x4_t val[3];
+} uint16x4x3_t;
+
+typedef struct uint16x8x3_t {
+  uint16x8_t val[3];
+} uint16x8x3_t;
+
+typedef struct uint32x2x3_t {
+  uint32x2_t val[3];
+} uint32x2x3_t;
+
+typedef struct uint32x4x3_t {
+  uint32x4_t val[3];
+} uint32x4x3_t;
+
+typedef struct uint64x1x3_t {
+  uint64x1_t val[3];
+} uint64x1x3_t;
+
+typedef struct uint64x2x3_t {
+  uint64x2_t val[3];
+} uint64x2x3_t;
+
+typedef struct float16x4x3_t {
+  float16x4_t val[3];
+} float16x4x3_t;
+
+typedef struct float16x8x3_t {
+  float16x8_t val[3];
+} float16x8x3_t;
+
+typedef struct float32x2x3_t {
+  float32x2_t val[3];
+} float32x2x3_t;
+
+typedef struct float32x4x3_t {
+  float32x4_t val[3];
+} float32x4x3_t;
+
+#ifdef __aarch64__
+typedef struct float64x1x3_t {
+  float64x1_t val[3];
+} float64x1x3_t;
+
+typedef struct float64x2x3_t {
+  float64x2_t val[3];
+} float64x2x3_t;
+
+#endif
+typedef struct poly8x8x3_t {
+  poly8x8_t val[3];
+} poly8x8x3_t;
+
+typedef struct poly8x16x3_t {
+  poly8x16_t val[3];
+} poly8x16x3_t;
+
+typedef struct poly16x4x3_t {
+  poly16x4_t val[3];
+} poly16x4x3_t;
+
+typedef struct poly16x8x3_t {
+  poly16x8_t val[3];
+} poly16x8x3_t;
+
+#ifdef __aarch64__
+typedef struct poly64x1x3_t {
+  poly64x1_t val[3];
+} poly64x1x3_t;
+
+typedef struct poly64x2x3_t {
+  poly64x2_t val[3];
+} poly64x2x3_t;
+
+#endif
+typedef struct int8x8x4_t {
+  int8x8_t val[4];
+} int8x8x4_t;
+
+typedef struct int8x16x4_t {
+  int8x16_t val[4];
+} int8x16x4_t;
+
+typedef struct int16x4x4_t {
+  int16x4_t val[4];
+} int16x4x4_t;
+
+typedef struct int16x8x4_t {
+  int16x8_t val[4];
+} int16x8x4_t;
+
+typedef struct int32x2x4_t {
+  int32x2_t val[4];
+} int32x2x4_t;
+
+typedef struct int32x4x4_t {
+  int32x4_t val[4];
+} int32x4x4_t;
+
+typedef struct int64x1x4_t {
+  int64x1_t val[4];
+} int64x1x4_t;
+
+typedef struct int64x2x4_t {
+  int64x2_t val[4];
+} int64x2x4_t;
+
+typedef struct uint8x8x4_t {
+  uint8x8_t val[4];
+} uint8x8x4_t;
+
+typedef struct uint8x16x4_t {
+  uint8x16_t val[4];
+} uint8x16x4_t;
+
+typedef struct uint16x4x4_t {
+  uint16x4_t val[4];
+} uint16x4x4_t;
+
+typedef struct uint16x8x4_t {
+  uint16x8_t val[4];
+} uint16x8x4_t;
+
+typedef struct uint32x2x4_t {
+  uint32x2_t val[4];
+} uint32x2x4_t;
+
+typedef struct uint32x4x4_t {
+  uint32x4_t val[4];
+} uint32x4x4_t;
+
+typedef struct uint64x1x4_t {
+  uint64x1_t val[4];
+} uint64x1x4_t;
+
+typedef struct uint64x2x4_t {
+  uint64x2_t val[4];
+} uint64x2x4_t;
+
+typedef struct float16x4x4_t {
+  float16x4_t val[4];
+} float16x4x4_t;
+
+typedef struct float16x8x4_t {
+  float16x8_t val[4];
+} float16x8x4_t;
+
+typedef struct float32x2x4_t {
+  float32x2_t val[4];
+} float32x2x4_t;
+
+typedef struct float32x4x4_t {
+  float32x4_t val[4];
+} float32x4x4_t;
+
+#ifdef __aarch64__
+typedef struct float64x1x4_t {
+  float64x1_t val[4];
+} float64x1x4_t;
+
+typedef struct float64x2x4_t {
+  float64x2_t val[4];
+} float64x2x4_t;
+
+#endif
+typedef struct poly8x8x4_t {
+  poly8x8_t val[4];
+} poly8x8x4_t;
+
+typedef struct poly8x16x4_t {
+  poly8x16_t val[4];
+} poly8x16x4_t;
+
+typedef struct poly16x4x4_t {
+  poly16x4_t val[4];
+} poly16x4x4_t;
+
+typedef struct poly16x8x4_t {
+  poly16x8_t val[4];
+} poly16x8x4_t;
+
+#ifdef __aarch64__
+typedef struct poly64x1x4_t {
+  poly64x1_t val[4];
+} poly64x1x4_t;
+
+typedef struct poly64x2x4_t {
+  poly64x2_t val[4];
+} poly64x2x4_t;
+
+#endif
+
+#define __ai static inline __attribute__((__always_inline__, __nodebug__))
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vabdq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vabdq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x16_t __noswap_vabdq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabdq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vabdq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vabdq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabdq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vabdq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vabdq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vabdq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vabdq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x16_t __noswap_vabdq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vabdq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vabdq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabdq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vabdq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vabdq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabdq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vabdq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vabdq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vabd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vabd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vabd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vabd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vabd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vabd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vabd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vabd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vabd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vabd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vabd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vabd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vabd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vabd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vabd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vabd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vabd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vabd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vabd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vabd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vabd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vabsq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vabsq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vabsq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vabsq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabsq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vabsq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabsq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vabsq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vabs_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vabs_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vabs_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vabs_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vabs_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vabs_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vabs_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vabs_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vabs_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vabs_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vabs_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vabs_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vabs_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vabs_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vabs_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vabs_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vaddq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai float32x4_t vaddq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vadd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai float32x2_t vadd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vaddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vaddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vaddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vaddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vaddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vaddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vaddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vaddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vaddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vaddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vaddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vaddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vaddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vaddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vaddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vaddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vaddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vaddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vaddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vandq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vandq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vandq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vandq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vandq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vandq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vandq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vandq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vandq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vandq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vandq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vandq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vandq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vandq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vandq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vandq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vand_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vand_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vand_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vand_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vand_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vand_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vand_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vand_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vand_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vand_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vand_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vand_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vand_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vand_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vand_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 & __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vand_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 & __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vbicq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vbicq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vbicq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vbicq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vbicq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vbicq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vbicq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vbicq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vbicq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vbicq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vbicq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vbicq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vbicq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vbicq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vbicq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vbicq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vbic_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vbic_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vbic_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vbic_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vbic_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vbic_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vbic_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vbic_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vbic_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vbic_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vbic_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vbic_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vbic_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vbic_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vbic_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 & ~__p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vbic_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 & ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vbsl_p8(uint8x8_t __p0, poly8x8_t __p1, poly8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vbsl_p8(uint8x8_t __p0, poly8x8_t __p1, poly8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vbsl_p16(uint16x4_t __p0, poly16x4_t __p1, poly16x4_t __p2) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 5);
+  return __ret;
+}
+#else
+__ai poly16x4_t vbsl_p16(uint16x4_t __p0, poly16x4_t __p1, poly16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vbslq_p8(uint8x16_t __p0, poly8x16_t __p1, poly8x16_t __p2) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vbslq_p8(uint8x16_t __p0, poly8x16_t __p1, poly8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vbslq_p16(uint16x8_t __p0, poly16x8_t __p1, poly16x8_t __p2) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 37);
+  return __ret;
+}
+#else
+__ai poly16x8_t vbslq_p16(uint16x8_t __p0, poly16x8_t __p1, poly16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 37);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vbslq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vbslq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vbslq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vbslq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vbslq_u64(uint64x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vbslq_u64(uint64x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vbslq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vbslq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vbslq_s8(uint8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vbslq_s8(uint8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vbslq_f32(uint32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vbslq_f32(uint32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vbslq_s32(uint32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vbslq_s32(uint32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vbslq_s64(uint64x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vbslq_s64(uint64x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vbslq_s16(uint16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vbslq_s16(uint16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vbsl_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vbsl_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vbsl_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vbsl_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vbsl_u64(uint64x1_t __p0, uint64x1_t __p1, uint64x1_t __p2) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vbsl_u64(uint64x1_t __p0, uint64x1_t __p1, uint64x1_t __p2) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vbsl_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vbsl_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vbsl_s8(uint8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vbsl_s8(uint8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vbsl_f32(uint32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vbsl_f32(uint32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vbsl_s32(uint32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vbsl_s32(uint32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vbsl_s64(uint64x1_t __p0, int64x1_t __p1, int64x1_t __p2) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vbsl_s64(uint64x1_t __p0, int64x1_t __p1, int64x1_t __p2) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vbsl_s16(uint16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vbsl_s16(uint16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vbsl_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcageq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcageq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcageq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcageq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcage_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcage_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcage_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcage_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcagtq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcagtq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcagtq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcagtq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcagt_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcagt_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcagt_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcagt_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcaleq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcaleq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcaleq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcaleq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcale_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcale_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcale_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcale_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcaltq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcaltq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcaltq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcaltq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcalt_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcalt_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcalt_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcalt_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceq_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceq_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vceqq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vceqq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vceqq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vceqq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceq_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceq_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceq_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceq_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vceq_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vceq_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceq_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceq_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceq_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceq_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceq_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceq_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vceq_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vceq_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgeq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgeq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgeq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgeq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgeq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgeq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgeq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgeq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgeq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgeq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgeq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgeq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgeq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgeq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcge_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcge_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcge_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcge_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcge_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcge_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcge_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcge_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcge_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcge_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcge_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcge_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcge_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcge_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgtq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgtq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgtq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgtq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgtq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgtq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgtq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgtq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgtq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgtq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgtq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgtq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgtq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgtq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcgt_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcgt_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgt_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgt_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcgt_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcgt_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcgt_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcgt_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgt_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgt_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgt_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgt_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcgt_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcgt_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcleq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcleq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcleq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcleq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcleq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcleq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcleq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcleq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcleq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcleq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcleq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcleq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcleq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcleq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcle_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcle_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcle_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcle_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcle_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcle_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcle_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcle_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcle_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcle_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcle_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcle_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcle_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcle_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vclsq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vclsq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vclsq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vclsq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vclsq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vclsq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vclsq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vclsq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vclsq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vclsq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vclsq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vclsq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vcls_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vcls_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vcls_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vcls_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcls_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcls_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcls_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcls_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vcls_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vcls_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vcls_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vcls_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcltq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcltq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcltq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcltq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcltq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcltq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcltq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcltq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcltq_f32(float32x4_t __p0, float32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcltq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcltq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcltq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcltq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcltq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vclt_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vclt_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclt_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclt_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vclt_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vclt_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vclt_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint8x8_t vclt_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclt_f32(float32x2_t __p0, float32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclt_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclt_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclt_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vclt_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint16x4_t vclt_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vclzq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vclzq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vclzq_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vclzq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vclzq_u16(uint16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vclzq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vclzq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vclzq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vclzq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vclzq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vclzq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vclzq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vclzq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vclzq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vclz_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vclz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vclz_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclz_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclz_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vclz_u16(uint16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vclz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vclz_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vclz_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vclz_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vclz_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vclz_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vclz_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vclz_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vclz_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vclz_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vclz_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vclz_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vcnt_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vcnt_v((int8x8_t)__p0, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vcnt_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vcnt_v((int8x8_t)__rev0, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vcntq_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vcntq_v((int8x16_t)__p0, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vcntq_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vcntq_v((int8x16_t)__rev0, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcntq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcntq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcntq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcntq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vcntq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vcntq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vcntq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vcntq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcnt_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcnt_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcnt_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcnt_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vcnt_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vcnt_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vcnt_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vcnt_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vcombine_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai poly8x16_t vcombine_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vcombine_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai poly16x8_t vcombine_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcombine_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcombine_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x16_t __noswap_vcombine_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcombine_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcombine_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vcombine_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcombine_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcombine_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcombine_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcombine_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vcombine_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vcombine_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai int8x16_t vcombine_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x16_t __noswap_vcombine_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcombine_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai float32x4_t vcombine_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float32x4_t __noswap_vcombine_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vcombine_f16(float16x4_t __p0, float16x4_t __p1) {
+  float16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai float16x8_t vcombine_f16(float16x4_t __p0, float16x4_t __p1) {
+  float16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float16x8_t __noswap_vcombine_f16(float16x4_t __p0, float16x4_t __p1) {
+  float16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcombine_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai int32x4_t vcombine_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vcombine_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcombine_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  return __ret;
+}
+#else
+__ai int64x2_t vcombine_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vcombine_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai int16x8_t vcombine_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vcombine_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vcreate_p8(uint64_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vcreate_p8(uint64_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vcreate_p16(uint64_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vcreate_p16(uint64_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcreate_u8(uint64_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcreate_u8(uint64_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcreate_u32(uint64_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcreate_u32(uint64_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcreate_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcreate_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcreate_u16(uint64_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcreate_u16(uint64_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vcreate_s8(uint64_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vcreate_s8(uint64_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vcreate_f32(uint64_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vcreate_f32(uint64_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vcreate_f16(uint64_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vcreate_f16(uint64_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcreate_s32(uint64_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vcreate_s32(uint64_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcreate_s64(uint64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vcreate_s64(uint64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vcreate_s16(uint64_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vcreate_s16(uint64_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vcvt_f16_f32(float32x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x16_t)__p0, 8);
+  return __ret;
+}
+#else
+__ai float16x4_t vcvt_f16_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float16x4_t __ret;
+  __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x16_t)__rev0, 8);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float16x4_t __noswap_vcvt_f16_f32(float32x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t) __builtin_neon_vcvt_f16_v((int8x16_t)__p0, 8);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvtq_f32_u32(uint32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvtq_f32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai float32x4_t vcvtq_f32_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvtq_f32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvtq_f32_s32(int32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvtq_f32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai float32x4_t vcvtq_f32_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvtq_f32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vcvt_f32_u32(uint32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai float32x2_t vcvt_f32_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vcvt_f32_s32(int32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai float32x2_t vcvt_f32_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvt_f32_f16(float16x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvt_f32_f16((int8x8_t)__p0, 8);
+  return __ret;
+}
+#else
+__ai float32x4_t vcvt_f32_f16(float16x4_t __p0) {
+  float16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvt_f32_f16((int8x8_t)__rev0, 8);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float32x4_t __noswap_vcvt_f32_f16(float16x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vcvt_f32_f16((int8x8_t)__p0, 8);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vcvtq_n_f32_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vcvtq_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vcvtq_n_f32_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vcvtq_n_f32_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vcvtq_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vcvtq_n_f32_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vcvt_n_f32_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vcvt_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vcvt_n_f32_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vcvt_n_f32_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vcvt_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vcvt_n_f32_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vcvtq_n_s32_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vcvtq_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vcvtq_n_s32_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vcvt_n_s32_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vcvt_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vcvt_n_s32_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vcvtq_n_u32_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vcvtq_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vcvtq_n_u32_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vcvt_n_u32_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vcvt_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vcvt_n_u32_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcvtq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtq_s32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vcvtq_s32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtq_s32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcvt_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvt_s32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcvt_s32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvt_s32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcvtq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtq_u32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcvtq_u32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtq_u32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcvt_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvt_u32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcvt_u32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvt_u32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vdup_n_p8(poly8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly8x8_t vdup_n_p8(poly8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vdup_n_p16(poly16_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly16x4_t vdup_n_p16(poly16_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vdupq_n_p8(poly8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly8x16_t vdupq_n_p8(poly8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vdupq_n_p16(poly16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly16x8_t vdupq_n_p16(poly16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vdupq_n_u8(uint8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint8x16_t vdupq_n_u8(uint8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vdupq_n_u32(uint32_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint32x4_t vdupq_n_u32(uint32_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vdupq_n_u64(uint64_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai uint64x2_t vdupq_n_u64(uint64_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vdupq_n_u16(uint16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint16x8_t vdupq_n_u16(uint16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vdupq_n_s8(int8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int8x16_t vdupq_n_s8(int8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vdupq_n_f32(float32_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai float32x4_t vdupq_n_f32(float32_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) {__s0, __s0, __s0, __s0, __s0, __s0, __s0, __s0}; \
+  __ret; \
+})
+#else
+#define vdupq_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) {__s0, __s0, __s0, __s0, __s0, __s0, __s0, __s0}; \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vdupq_n_s32(int32_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int32x4_t vdupq_n_s32(int32_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vdupq_n_s64(int64_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai int64x2_t vdupq_n_s64(int64_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vdupq_n_s16(int16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int16x8_t vdupq_n_s16(int16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vdup_n_u8(uint8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint8x8_t vdup_n_u8(uint8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vdup_n_u32(uint32_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai uint32x2_t vdup_n_u32(uint32_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vdup_n_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai uint64x1_t vdup_n_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vdup_n_u16(uint16_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint16x4_t vdup_n_u16(uint16_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vdup_n_s8(int8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int8x8_t vdup_n_s8(int8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vdup_n_f32(float32_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai float32x2_t vdup_n_f32(float32_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) {__s0, __s0, __s0, __s0}; \
+  __ret; \
+})
+#else
+#define vdup_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) {__s0, __s0, __s0, __s0}; \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vdup_n_s32(int32_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai int32x2_t vdup_n_s32(int32_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vdup_n_s64(int64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai int64x1_t vdup_n_s64(int64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vdup_n_s16(int16_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int16x4_t vdup_n_s16(int16_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t veorq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t veorq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t veorq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t veorq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t veorq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t veorq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t veorq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t veorq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t veorq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t veorq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t veorq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t veorq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t veorq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int64x2_t veorq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t veorq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t veorq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t veor_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t veor_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t veor_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t veor_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t veor_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t veor_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t veor_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t veor_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t veor_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t veor_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t veor_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t veor_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t veor_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int64x1_t veor_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t veor_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 ^ __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t veor_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 ^ __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 4); \
+  __ret; \
+})
+#else
+#define vext_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 5); \
+  __ret; \
+})
+#else
+#define vext_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 36); \
+  __ret; \
+})
+#else
+#define vextq_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 37); \
+  __ret; \
+})
+#else
+#define vextq_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vextq_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vextq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vextq_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vextq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vextq_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 41); \
+  __ret; \
+})
+#else
+#define vextq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vextq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vextq_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vextq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vext_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vext_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vext_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vext_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vext_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 9); \
+  __ret; \
+})
+#else
+#define vext_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vext_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vext_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vext_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vext_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vfmaq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vfmaq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmaq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float32x4_t __noswap_vfmaq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 41);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vfma_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vfma_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfma_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vfma_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 9);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vget_high_p8(poly8x16_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai poly8x8_t vget_high_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai poly8x8_t __noswap_vget_high_p8(poly8x16_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vget_high_p16(poly16x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai poly16x4_t vget_high_p16(poly16x8_t __p0) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vget_high_u8(uint8x16_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai uint8x8_t vget_high_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vget_high_u8(uint8x16_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vget_high_u32(uint32x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#else
+__ai uint32x2_t vget_high_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vget_high_u32(uint32x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vget_high_u64(uint64x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vget_high_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vget_high_u16(uint16x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai uint16x4_t vget_high_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vget_high_u16(uint16x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vget_high_s8(int8x16_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#else
+__ai int8x8_t vget_high_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 8, 9, 10, 11, 12, 13, 14, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vget_high_s8(int8x16_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 8, 9, 10, 11, 12, 13, 14, 15);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vget_high_f32(float32x4_t __p0) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#else
+__ai float32x2_t vget_high_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vget_high_f32(float32x4_t __p0) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vget_high_f16(float16x8_t __p0) {
+  float16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai float16x4_t vget_high_f16(float16x8_t __p0) {
+  float16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  float16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float16x4_t __noswap_vget_high_f16(float16x8_t __p0) {
+  float16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vget_high_s32(int32x4_t __p0) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#else
+__ai int32x2_t vget_high_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vget_high_s32(int32x4_t __p0) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 2, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vget_high_s64(int64x2_t __p0) {
+  int64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1);
+  return __ret;
+}
+#else
+__ai int64x1_t vget_high_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vget_high_s16(int16x8_t __p0) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai int16x4_t vget_high_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vget_high_s16(int16x8_t __p0) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 4, 5, 6, 7);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vget_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vget_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vgetq_lane_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vgetq_lane_f32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vgetq_lane_f32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vgetq_lane_f32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vgetq_lane_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vget_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vget_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vget_lane_i32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vget_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vget_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vget_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vget_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vget_lane_f32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vget_lane_f32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vget_lane_f32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vget_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vget_lane_i32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vget_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vget_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vget_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vget_low_p8(poly8x16_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai poly8x8_t vget_low_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vget_low_p16(poly16x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai poly16x4_t vget_low_p16(poly16x8_t __p0) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vget_low_u8(uint8x16_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai uint8x8_t vget_low_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vget_low_u32(uint32x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1);
+  return __ret;
+}
+#else
+__ai uint32x2_t vget_low_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vget_low_u64(uint64x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vget_low_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vget_low_u16(uint16x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai uint16x4_t vget_low_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vget_low_s8(int8x16_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3, 4, 5, 6, 7);
+  return __ret;
+}
+#else
+__ai int8x8_t vget_low_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3, 4, 5, 6, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vget_low_f32(float32x4_t __p0) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1);
+  return __ret;
+}
+#else
+__ai float32x2_t vget_low_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vget_low_f16(float16x8_t __p0) {
+  float16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai float16x4_t vget_low_f16(float16x8_t __p0) {
+  float16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  float16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vget_low_s32(int32x4_t __p0) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1);
+  return __ret;
+}
+#else
+__ai int32x2_t vget_low_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vget_low_s64(int64x2_t __p0) {
+  int64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0);
+  return __ret;
+}
+#else
+__ai int64x1_t vget_low_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vget_low_s16(int16x8_t __p0) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0, 1, 2, 3);
+  return __ret;
+}
+#else
+__ai int16x4_t vget_low_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0, 1, 2, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vhaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vhaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vhaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vhaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vhaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vhaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vhaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vhaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vhaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vhaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vhaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vhaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vhadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vhadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vhadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vhadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vhadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vhadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vhadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vhadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vhadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vhadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vhadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vhadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vhsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vhsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vhsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vhsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vhsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vhsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vhsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vhsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vhsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vhsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vhsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vhsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vhsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vhsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vhsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vhsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vhsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vhsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vhsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vhsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vhsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vhsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vhsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vhsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vhsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vhsub_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vhsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vhsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p8(__p0) __extension__ ({ \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_v(__p0, 4); \
+  __ret; \
+})
+#else
+#define vld1_p8(__p0) __extension__ ({ \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_v(__p0, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p16(__p0) __extension__ ({ \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_v(__p0, 5); \
+  __ret; \
+})
+#else
+#define vld1_p16(__p0) __extension__ ({ \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_v(__p0, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p8(__p0) __extension__ ({ \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_v(__p0, 36); \
+  __ret; \
+})
+#else
+#define vld1q_p8(__p0) __extension__ ({ \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_v(__p0, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p16(__p0) __extension__ ({ \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_v(__p0, 37); \
+  __ret; \
+})
+#else
+#define vld1q_p16(__p0) __extension__ ({ \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_v(__p0, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u8(__p0) __extension__ ({ \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_v(__p0, 48); \
+  __ret; \
+})
+#else
+#define vld1q_u8(__p0) __extension__ ({ \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_v(__p0, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u32(__p0) __extension__ ({ \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_v(__p0, 50); \
+  __ret; \
+})
+#else
+#define vld1q_u32(__p0) __extension__ ({ \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_v(__p0, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u64(__p0) __extension__ ({ \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_v(__p0, 51); \
+  __ret; \
+})
+#else
+#define vld1q_u64(__p0) __extension__ ({ \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_v(__p0, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u16(__p0) __extension__ ({ \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_v(__p0, 49); \
+  __ret; \
+})
+#else
+#define vld1q_u16(__p0) __extension__ ({ \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_v(__p0, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s8(__p0) __extension__ ({ \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_v(__p0, 32); \
+  __ret; \
+})
+#else
+#define vld1q_s8(__p0) __extension__ ({ \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_v(__p0, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f32(__p0) __extension__ ({ \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_v(__p0, 41); \
+  __ret; \
+})
+#else
+#define vld1q_f32(__p0) __extension__ ({ \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_v(__p0, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f16(__p0) __extension__ ({ \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_v(__p0, 40); \
+  __ret; \
+})
+#else
+#define vld1q_f16(__p0) __extension__ ({ \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_v(__p0, 40); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s32(__p0) __extension__ ({ \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_v(__p0, 34); \
+  __ret; \
+})
+#else
+#define vld1q_s32(__p0) __extension__ ({ \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_v(__p0, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s64(__p0) __extension__ ({ \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_v(__p0, 35); \
+  __ret; \
+})
+#else
+#define vld1q_s64(__p0) __extension__ ({ \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_v(__p0, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s16(__p0) __extension__ ({ \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_v(__p0, 33); \
+  __ret; \
+})
+#else
+#define vld1q_s16(__p0) __extension__ ({ \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_v(__p0, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u8(__p0) __extension__ ({ \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_v(__p0, 16); \
+  __ret; \
+})
+#else
+#define vld1_u8(__p0) __extension__ ({ \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_v(__p0, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u32(__p0) __extension__ ({ \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_v(__p0, 18); \
+  __ret; \
+})
+#else
+#define vld1_u32(__p0) __extension__ ({ \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_v(__p0, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u64(__p0) __extension__ ({ \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_v(__p0, 19); \
+  __ret; \
+})
+#else
+#define vld1_u64(__p0) __extension__ ({ \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_v(__p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u16(__p0) __extension__ ({ \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_v(__p0, 17); \
+  __ret; \
+})
+#else
+#define vld1_u16(__p0) __extension__ ({ \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_v(__p0, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s8(__p0) __extension__ ({ \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_v(__p0, 0); \
+  __ret; \
+})
+#else
+#define vld1_s8(__p0) __extension__ ({ \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_v(__p0, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f32(__p0) __extension__ ({ \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_v(__p0, 9); \
+  __ret; \
+})
+#else
+#define vld1_f32(__p0) __extension__ ({ \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_v(__p0, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f16(__p0) __extension__ ({ \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_v(__p0, 8); \
+  __ret; \
+})
+#else
+#define vld1_f16(__p0) __extension__ ({ \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_v(__p0, 8); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s32(__p0) __extension__ ({ \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_v(__p0, 2); \
+  __ret; \
+})
+#else
+#define vld1_s32(__p0) __extension__ ({ \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_v(__p0, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s64(__p0) __extension__ ({ \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_v(__p0, 3); \
+  __ret; \
+})
+#else
+#define vld1_s64(__p0) __extension__ ({ \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_v(__p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s16(__p0) __extension__ ({ \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_v(__p0, 1); \
+  __ret; \
+})
+#else
+#define vld1_s16(__p0) __extension__ ({ \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_v(__p0, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_p8(__p0) __extension__ ({ \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_dup_v(__p0, 4); \
+  __ret; \
+})
+#else
+#define vld1_dup_p8(__p0) __extension__ ({ \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_dup_v(__p0, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_p16(__p0) __extension__ ({ \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_dup_v(__p0, 5); \
+  __ret; \
+})
+#else
+#define vld1_dup_p16(__p0) __extension__ ({ \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_dup_v(__p0, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_p8(__p0) __extension__ ({ \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_dup_v(__p0, 36); \
+  __ret; \
+})
+#else
+#define vld1q_dup_p8(__p0) __extension__ ({ \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_dup_v(__p0, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_p16(__p0) __extension__ ({ \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_dup_v(__p0, 37); \
+  __ret; \
+})
+#else
+#define vld1q_dup_p16(__p0) __extension__ ({ \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_dup_v(__p0, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_u8(__p0) __extension__ ({ \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_dup_v(__p0, 48); \
+  __ret; \
+})
+#else
+#define vld1q_dup_u8(__p0) __extension__ ({ \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_dup_v(__p0, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_u32(__p0) __extension__ ({ \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_dup_v(__p0, 50); \
+  __ret; \
+})
+#else
+#define vld1q_dup_u32(__p0) __extension__ ({ \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_dup_v(__p0, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_u64(__p0) __extension__ ({ \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_dup_v(__p0, 51); \
+  __ret; \
+})
+#else
+#define vld1q_dup_u64(__p0) __extension__ ({ \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_dup_v(__p0, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_u16(__p0) __extension__ ({ \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_dup_v(__p0, 49); \
+  __ret; \
+})
+#else
+#define vld1q_dup_u16(__p0) __extension__ ({ \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_dup_v(__p0, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_s8(__p0) __extension__ ({ \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_dup_v(__p0, 32); \
+  __ret; \
+})
+#else
+#define vld1q_dup_s8(__p0) __extension__ ({ \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_dup_v(__p0, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_f32(__p0) __extension__ ({ \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_dup_v(__p0, 41); \
+  __ret; \
+})
+#else
+#define vld1q_dup_f32(__p0) __extension__ ({ \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_dup_v(__p0, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_f16(__p0) __extension__ ({ \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_dup_v(__p0, 40); \
+  __ret; \
+})
+#else
+#define vld1q_dup_f16(__p0) __extension__ ({ \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_dup_v(__p0, 40); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_s32(__p0) __extension__ ({ \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_dup_v(__p0, 34); \
+  __ret; \
+})
+#else
+#define vld1q_dup_s32(__p0) __extension__ ({ \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_dup_v(__p0, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_s64(__p0) __extension__ ({ \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_dup_v(__p0, 35); \
+  __ret; \
+})
+#else
+#define vld1q_dup_s64(__p0) __extension__ ({ \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_dup_v(__p0, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_s16(__p0) __extension__ ({ \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_dup_v(__p0, 33); \
+  __ret; \
+})
+#else
+#define vld1q_dup_s16(__p0) __extension__ ({ \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_dup_v(__p0, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_u8(__p0) __extension__ ({ \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_dup_v(__p0, 16); \
+  __ret; \
+})
+#else
+#define vld1_dup_u8(__p0) __extension__ ({ \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_dup_v(__p0, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_u32(__p0) __extension__ ({ \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_dup_v(__p0, 18); \
+  __ret; \
+})
+#else
+#define vld1_dup_u32(__p0) __extension__ ({ \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_dup_v(__p0, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_u64(__p0) __extension__ ({ \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_dup_v(__p0, 19); \
+  __ret; \
+})
+#else
+#define vld1_dup_u64(__p0) __extension__ ({ \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_dup_v(__p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_u16(__p0) __extension__ ({ \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_dup_v(__p0, 17); \
+  __ret; \
+})
+#else
+#define vld1_dup_u16(__p0) __extension__ ({ \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_dup_v(__p0, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_s8(__p0) __extension__ ({ \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_dup_v(__p0, 0); \
+  __ret; \
+})
+#else
+#define vld1_dup_s8(__p0) __extension__ ({ \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_dup_v(__p0, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_f32(__p0) __extension__ ({ \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_dup_v(__p0, 9); \
+  __ret; \
+})
+#else
+#define vld1_dup_f32(__p0) __extension__ ({ \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_dup_v(__p0, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_f16(__p0) __extension__ ({ \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_dup_v(__p0, 8); \
+  __ret; \
+})
+#else
+#define vld1_dup_f16(__p0) __extension__ ({ \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_dup_v(__p0, 8); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_s32(__p0) __extension__ ({ \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_dup_v(__p0, 2); \
+  __ret; \
+})
+#else
+#define vld1_dup_s32(__p0) __extension__ ({ \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_dup_v(__p0, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_s64(__p0) __extension__ ({ \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_dup_v(__p0, 3); \
+  __ret; \
+})
+#else
+#define vld1_dup_s64(__p0) __extension__ ({ \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_dup_v(__p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_s16(__p0) __extension__ ({ \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_dup_v(__p0, 1); \
+  __ret; \
+})
+#else
+#define vld1_dup_s16(__p0) __extension__ ({ \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_dup_v(__p0, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 4); \
+  __ret; \
+})
+#else
+#define vld1_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 5); \
+  __ret; \
+})
+#else
+#define vld1_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 36); \
+  __ret; \
+})
+#else
+#define vld1q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 37); \
+  __ret; \
+})
+#else
+#define vld1q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vld1q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vld1q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vld1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vld1q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vld1q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 41); \
+  __ret; \
+})
+#else
+#define vld1q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 40); \
+  __ret; \
+})
+#else
+#define vld1q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  float16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 40); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vld1q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vld1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vld1q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vld1_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vld1_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vld1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vld1_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vld1_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 9); \
+  __ret; \
+})
+#else
+#define vld1_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 8); \
+  __ret; \
+})
+#else
+#define vld1_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  float16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 8); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vld1_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vld1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vld1_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_p8(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld2_p8(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_p16(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld2_p16(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_p8(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld2q_p8(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_p16(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld2q_p16(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_u8(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld2q_u8(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_u32(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld2q_u32(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_u16(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld2q_u16(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_s8(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld2q_s8(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_f32(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld2q_f32(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_f16(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld2q_f16(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_s32(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld2q_s32(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_s16(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld2q_s16(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_u8(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld2_u8(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_u32(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld2_u32(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_u64(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld2_u64(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_u16(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld2_u16(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_s8(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld2_s8(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_f32(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld2_f32(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_f16(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld2_f16(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_s32(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld2_s32(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_s64(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld2_s64(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_s16(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld2_s16(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_p8(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld2_dup_p8(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_p16(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld2_dup_p16(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_u8(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld2_dup_u8(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_u32(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld2_dup_u32(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_u64(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld2_dup_u64(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_u16(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld2_dup_u16(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_s8(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld2_dup_s8(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_f32(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld2_dup_f32(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_f16(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld2_dup_f16(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_s32(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld2_dup_s32(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_s64(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld2_dup_s64(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_s16(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld2_dup_s16(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 4); \
+  __ret; \
+})
+#else
+#define vld2_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  poly8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 5); \
+  __ret; \
+})
+#else
+#define vld2_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  poly16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 37); \
+  __ret; \
+})
+#else
+#define vld2q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  poly16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 50); \
+  __ret; \
+})
+#else
+#define vld2q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  uint32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 49); \
+  __ret; \
+})
+#else
+#define vld2q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  uint16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 41); \
+  __ret; \
+})
+#else
+#define vld2q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  float32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 40); \
+  __ret; \
+})
+#else
+#define vld2q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  float16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 34); \
+  __ret; \
+})
+#else
+#define vld2q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  int32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 33); \
+  __ret; \
+})
+#else
+#define vld2q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  int16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 16); \
+  __ret; \
+})
+#else
+#define vld2_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  uint8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 18); \
+  __ret; \
+})
+#else
+#define vld2_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  uint32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 17); \
+  __ret; \
+})
+#else
+#define vld2_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  uint16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 0); \
+  __ret; \
+})
+#else
+#define vld2_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  int8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 9); \
+  __ret; \
+})
+#else
+#define vld2_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  float32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 8); \
+  __ret; \
+})
+#else
+#define vld2_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  float16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 2); \
+  __ret; \
+})
+#else
+#define vld2_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  int32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 1); \
+  __ret; \
+})
+#else
+#define vld2_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  int16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_p8(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld3_p8(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_p16(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld3_p16(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_p8(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld3q_p8(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_p16(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld3q_p16(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_u8(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld3q_u8(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_u32(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld3q_u32(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_u16(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld3q_u16(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_s8(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld3q_s8(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_f32(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld3q_f32(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_f16(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld3q_f16(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_s32(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld3q_s32(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_s16(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld3q_s16(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_u8(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld3_u8(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_u32(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld3_u32(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_u64(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld3_u64(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_u16(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld3_u16(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_s8(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld3_s8(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_f32(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld3_f32(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_f16(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld3_f16(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_s32(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld3_s32(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_s64(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld3_s64(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_s16(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld3_s16(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_p8(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld3_dup_p8(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_p16(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld3_dup_p16(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_u8(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld3_dup_u8(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_u32(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld3_dup_u32(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_u64(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld3_dup_u64(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_u16(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld3_dup_u16(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_s8(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld3_dup_s8(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_f32(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld3_dup_f32(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_f16(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld3_dup_f16(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_s32(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld3_dup_s32(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_s64(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld3_dup_s64(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_s16(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld3_dup_s16(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 4); \
+  __ret; \
+})
+#else
+#define vld3_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  poly8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 5); \
+  __ret; \
+})
+#else
+#define vld3_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  poly16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 37); \
+  __ret; \
+})
+#else
+#define vld3q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  poly16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 50); \
+  __ret; \
+})
+#else
+#define vld3q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  uint32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 49); \
+  __ret; \
+})
+#else
+#define vld3q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  uint16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 41); \
+  __ret; \
+})
+#else
+#define vld3q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  float32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 40); \
+  __ret; \
+})
+#else
+#define vld3q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  float16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 34); \
+  __ret; \
+})
+#else
+#define vld3q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  int32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 33); \
+  __ret; \
+})
+#else
+#define vld3q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  int16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 16); \
+  __ret; \
+})
+#else
+#define vld3_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  uint8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 18); \
+  __ret; \
+})
+#else
+#define vld3_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  uint32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 17); \
+  __ret; \
+})
+#else
+#define vld3_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  uint16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 0); \
+  __ret; \
+})
+#else
+#define vld3_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  int8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 9); \
+  __ret; \
+})
+#else
+#define vld3_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  float32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 8); \
+  __ret; \
+})
+#else
+#define vld3_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  float16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 2); \
+  __ret; \
+})
+#else
+#define vld3_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  int32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 1); \
+  __ret; \
+})
+#else
+#define vld3_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  int16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_p8(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld4_p8(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_p16(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld4_p16(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_p8(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld4q_p8(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_p16(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld4q_p16(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_u8(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld4q_u8(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_u32(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld4q_u32(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_u16(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld4q_u16(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_s8(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld4q_s8(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_f32(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld4q_f32(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_f16(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld4q_f16(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_s32(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld4q_s32(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_s16(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld4q_s16(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_u8(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld4_u8(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_u32(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld4_u32(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_u64(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld4_u64(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_u16(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld4_u16(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_s8(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld4_s8(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_f32(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld4_f32(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_f16(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld4_f16(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_s32(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld4_s32(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_s64(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld4_s64(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_s16(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld4_s16(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_p8(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld4_dup_p8(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_p16(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld4_dup_p16(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_u8(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld4_dup_u8(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_u32(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld4_dup_u32(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_u64(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld4_dup_u64(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_u16(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld4_dup_u16(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_s8(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld4_dup_s8(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_f32(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld4_dup_f32(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_f16(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld4_dup_f16(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_s32(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld4_dup_s32(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_s64(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld4_dup_s64(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_s16(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld4_dup_s16(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 4); \
+  __ret; \
+})
+#else
+#define vld4_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  poly8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 5); \
+  __ret; \
+})
+#else
+#define vld4_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  poly16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 37); \
+  __ret; \
+})
+#else
+#define vld4q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  poly16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 50); \
+  __ret; \
+})
+#else
+#define vld4q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  uint32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 49); \
+  __ret; \
+})
+#else
+#define vld4q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  uint16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 41); \
+  __ret; \
+})
+#else
+#define vld4q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  float32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 40); \
+  __ret; \
+})
+#else
+#define vld4q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  float16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 34); \
+  __ret; \
+})
+#else
+#define vld4q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  int32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 33); \
+  __ret; \
+})
+#else
+#define vld4q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  int16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 16); \
+  __ret; \
+})
+#else
+#define vld4_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  uint8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 18); \
+  __ret; \
+})
+#else
+#define vld4_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  uint32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 17); \
+  __ret; \
+})
+#else
+#define vld4_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  uint16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 0); \
+  __ret; \
+})
+#else
+#define vld4_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  int8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 9); \
+  __ret; \
+})
+#else
+#define vld4_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  float32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 8); \
+  __ret; \
+})
+#else
+#define vld4_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  float16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 2); \
+  __ret; \
+})
+#else
+#define vld4_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  int32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 1); \
+  __ret; \
+})
+#else
+#define vld4_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  int16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmaxq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vmaxq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmaxq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmaxq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmaxq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vmaxq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmaxq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vmaxq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmaxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vmaxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmaxq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vmaxq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmaxq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vmaxq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmax_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vmax_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmax_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vmax_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmax_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vmax_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmax_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vmax_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmax_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vmax_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmax_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vmax_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmax_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vmax_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vminq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vminq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vminq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vminq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vminq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vminq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vminq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vminq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vminq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vminq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vminq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vminq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vminq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vminq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmin_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vmin_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmin_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vmin_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmin_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vmin_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmin_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vmin_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmin_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vmin_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmin_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vmin_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmin_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vmin_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmlaq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint8x16_t vmlaq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlaq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlaq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlaq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlaq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmlaq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int8x16_t vmlaq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmlaq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float32x4_t vmlaq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlaq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int32x4_t vmlaq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlaq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int16x8_t vmlaq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmla_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint8x8_t vmla_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmla_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint32x2_t vmla_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmla_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint16x4_t vmla_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmla_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int8x8_t vmla_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmla_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float32x2_t vmla_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmla_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int32x2_t vmla_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmla_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int16x4_t vmla_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x8_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x8_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlaq_n_u32(uint32x4_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + __p1 * (uint32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlaq_n_u32(uint32x4_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __rev1 * (uint32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlaq_n_u16(uint16x8_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + __p1 * (uint16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlaq_n_u16(uint16x8_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __rev1 * (uint16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmlaq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __ret;
+  __ret = __p0 + __p1 * (float32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai float32x4_t vmlaq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 + __rev1 * (float32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlaq_n_s32(int32x4_t __p0, int32x4_t __p1, int32_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + __p1 * (int32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int32x4_t vmlaq_n_s32(int32x4_t __p0, int32x4_t __p1, int32_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __rev1 * (int32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlaq_n_s16(int16x8_t __p0, int16x8_t __p1, int16_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + __p1 * (int16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int16x8_t vmlaq_n_s16(int16x8_t __p0, int16x8_t __p1, int16_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __rev1 * (int16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmla_n_u32(uint32x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint32x2_t __ret;
+  __ret = __p0 + __p1 * (uint32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai uint32x2_t vmla_n_u32(uint32x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 + __rev1 * (uint32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmla_n_u16(uint16x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint16x4_t __ret;
+  __ret = __p0 + __p1 * (uint16x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint16x4_t vmla_n_u16(uint16x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 + __rev1 * (uint16x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmla_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __ret;
+  __ret = __p0 + __p1 * (float32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai float32x2_t vmla_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 + __rev1 * (float32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmla_n_s32(int32x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int32x2_t __ret;
+  __ret = __p0 + __p1 * (int32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai int32x2_t vmla_n_s32(int32x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 + __rev1 * (int32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmla_n_s16(int16x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int16x4_t __ret;
+  __ret = __p0 + __p1 * (int16x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int16x4_t vmla_n_s16(int16x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 + __rev1 * (int16x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmlsq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint8x16_t vmlsq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlsq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlsq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmlsq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int8x16_t vmlsq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmlsq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float32x4_t vmlsq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlsq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int16x8_t vmlsq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmls_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint8x8_t vmls_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmls_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint32x2_t vmls_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmls_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai uint16x4_t vmls_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmls_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int8x8_t vmls_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmls_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float32x2_t vmls_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmls_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int32x2_t vmls_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmls_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai int16x4_t vmls_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x8_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x8_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsq_n_u32(uint32x4_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - __p1 * (uint32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsq_n_u32(uint32x4_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __rev1 * (uint32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlsq_n_u16(uint16x8_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 - __p1 * (uint16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlsq_n_u16(uint16x8_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __rev1 * (uint16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmlsq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __ret;
+  __ret = __p0 - __p1 * (float32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai float32x4_t vmlsq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 - __rev1 * (float32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsq_n_s32(int32x4_t __p0, int32x4_t __p1, int32_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - __p1 * (int32x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsq_n_s32(int32x4_t __p0, int32x4_t __p1, int32_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __rev1 * (int32x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlsq_n_s16(int16x8_t __p0, int16x8_t __p1, int16_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 - __p1 * (int16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int16x8_t vmlsq_n_s16(int16x8_t __p0, int16x8_t __p1, int16_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __rev1 * (int16x8_t) {__p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmls_n_u32(uint32x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint32x2_t __ret;
+  __ret = __p0 - __p1 * (uint32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai uint32x2_t vmls_n_u32(uint32x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 - __rev1 * (uint32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmls_n_u16(uint16x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint16x4_t __ret;
+  __ret = __p0 - __p1 * (uint16x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai uint16x4_t vmls_n_u16(uint16x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 - __rev1 * (uint16x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmls_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __ret;
+  __ret = __p0 - __p1 * (float32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai float32x2_t vmls_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 - __rev1 * (float32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmls_n_s32(int32x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int32x2_t __ret;
+  __ret = __p0 - __p1 * (int32x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai int32x2_t vmls_n_s32(int32x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 - __rev1 * (int32x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmls_n_s16(int16x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int16x4_t __ret;
+  __ret = __p0 - __p1 * (int16x4_t) {__p2, __p2, __p2, __p2};
+  return __ret;
+}
+#else
+__ai int16x4_t vmls_n_s16(int16x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 - __rev1 * (int16x4_t) {__p2, __p2, __p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vmov_n_p8(poly8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly8x8_t vmov_n_p8(poly8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vmov_n_p16(poly16_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly16x4_t vmov_n_p16(poly16_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vmovq_n_p8(poly8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly8x16_t vmovq_n_p8(poly8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vmovq_n_p16(poly16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai poly16x8_t vmovq_n_p16(poly16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmovq_n_u8(uint8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint8x16_t vmovq_n_u8(uint8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmovq_n_u32(uint32_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint32x4_t vmovq_n_u32(uint32_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmovq_n_u64(uint64_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai uint64x2_t vmovq_n_u64(uint64_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmovq_n_u16(uint16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint16x8_t vmovq_n_u16(uint16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmovq_n_s8(int8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int8x16_t vmovq_n_s8(int8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmovq_n_f32(float32_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai float32x4_t vmovq_n_f32(float32_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmovq_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) {__s0, __s0, __s0, __s0, __s0, __s0, __s0, __s0}; \
+  __ret; \
+})
+#else
+#define vmovq_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = (float16x8_t) {__s0, __s0, __s0, __s0, __s0, __s0, __s0, __s0}; \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmovq_n_s32(int32_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int32x4_t vmovq_n_s32(int32_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmovq_n_s64(int64_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai int64x2_t vmovq_n_s64(int64_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmovq_n_s16(int16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int16x8_t vmovq_n_s16(int16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmov_n_u8(uint8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint8x8_t vmov_n_u8(uint8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmov_n_u32(uint32_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai uint32x2_t vmov_n_u32(uint32_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vmov_n_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai uint64x1_t vmov_n_u64(uint64_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmov_n_u16(uint16_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai uint16x4_t vmov_n_u16(uint16_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmov_n_s8(int8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int8x8_t vmov_n_s8(int8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) {__p0, __p0, __p0, __p0, __p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmov_n_f32(float32_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai float32x2_t vmov_n_f32(float32_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmov_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) {__s0, __s0, __s0, __s0}; \
+  __ret; \
+})
+#else
+#define vmov_n_f16(__p0) __extension__ ({ \
+  float16_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = (float16x4_t) {__s0, __s0, __s0, __s0}; \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmov_n_s32(int32_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai int32x2_t vmov_n_s32(int32_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vmov_n_s64(int64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai int64x1_t vmov_n_s64(int64_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmov_n_s16(int16_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) {__p0, __p0, __p0, __p0};
+  return __ret;
+}
+#else
+__ai int16x4_t vmov_n_s16(int16_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) {__p0, __p0, __p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmovl_u8(uint8x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vmovl_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vmovl_u8(uint8x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 49);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmovl_u32(uint32x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmovl_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmovl_u32(uint32x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 51);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmovl_u16(uint16x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmovl_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmovl_u16(uint16x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 50);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmovl_s8(int8x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vmovl_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vmovl_s8(int8x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 33);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmovl_s32(int32x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vmovl_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmovl_s32(int32x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmovl_s16(int16x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vmovl_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmovl_v((int8x8_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmovl_s16(int16x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmovl_v((int8x8_t)__p0, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmovn_u32(uint32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vmovn_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vmovn_u32(uint32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmovn_u64(uint64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vmovn_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vmovn_u64(uint64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmovn_u16(uint16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vmovn_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vmovn_u16(uint16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmovn_s32(int32x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vmovn_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vmovn_s32(int32x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmovn_s64(int64x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vmovn_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vmovn_s64(int64x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmovn_s16(int16x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vmovn_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmovn_v((int8x16_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vmovn_s16(int16x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vmovn_v((int8x16_t)__p0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmulq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vmulq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmulq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vmulq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmulq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vmulq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmulq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vmulq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmulq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai float32x4_t vmulq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmulq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vmulq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmulq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vmulq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmul_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vmul_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmul_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vmul_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmul_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vmul_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmul_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vmul_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmul_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai float32x2_t vmul_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmul_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vmul_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmul_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vmul_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vmul_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vmul_v((int8x8_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vmul_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vmul_v((int8x8_t)__rev0, (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vmulq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vmulq_v((int8x16_t)__p0, (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vmulq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vmulq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmulq_n_u32(uint32x4_t __p0, uint32_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 * (uint32x4_t) {__p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai uint32x4_t vmulq_n_u32(uint32x4_t __p0, uint32_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 * (uint32x4_t) {__p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmulq_n_u16(uint16x8_t __p0, uint16_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 * (uint16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai uint16x8_t vmulq_n_u16(uint16x8_t __p0, uint16_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 * (uint16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmulq_n_f32(float32x4_t __p0, float32_t __p1) {
+  float32x4_t __ret;
+  __ret = __p0 * (float32x4_t) {__p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai float32x4_t vmulq_n_f32(float32x4_t __p0, float32_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 * (float32x4_t) {__p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmulq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 * (int32x4_t) {__p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai int32x4_t vmulq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 * (int32x4_t) {__p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmulq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 * (int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai int16x8_t vmulq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 * (int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmul_n_u32(uint32x2_t __p0, uint32_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 * (uint32x2_t) {__p1, __p1};
+  return __ret;
+}
+#else
+__ai uint32x2_t vmul_n_u32(uint32x2_t __p0, uint32_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 * (uint32x2_t) {__p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmul_n_u16(uint16x4_t __p0, uint16_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 * (uint16x4_t) {__p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai uint16x4_t vmul_n_u16(uint16x4_t __p0, uint16_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 * (uint16x4_t) {__p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmul_n_f32(float32x2_t __p0, float32_t __p1) {
+  float32x2_t __ret;
+  __ret = __p0 * (float32x2_t) {__p1, __p1};
+  return __ret;
+}
+#else
+__ai float32x2_t vmul_n_f32(float32x2_t __p0, float32_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 * (float32x2_t) {__p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmul_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 * (int32x2_t) {__p1, __p1};
+  return __ret;
+}
+#else
+__ai int32x2_t vmul_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 * (int32x2_t) {__p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmul_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 * (int16x4_t) {__p1, __p1, __p1, __p1};
+  return __ret;
+}
+#else
+__ai int16x4_t vmul_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 * (int16x4_t) {__p1, __p1, __p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vmull_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 37);
+  return __ret;
+}
+#else
+__ai poly16x8_t vmull_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 37);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai poly16x8_t __noswap_vmull_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 37);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmull_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vmull_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vmull_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 49);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmull_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmull_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmull_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 51);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmull_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmull_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmull_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 50);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmull_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vmull_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vmull_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 33);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)__p1, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = vmull_u32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __noswap_vmull_u32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = vmull_u16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __noswap_vmull_u16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vmull_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vmull_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vmull_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vmull_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmull_n_u32(uint32x2_t __p0, uint32_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(uint32x2_t) {__p1, __p1}, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmull_n_u32(uint32x2_t __p0, uint32_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)(uint32x2_t) {__p1, __p1}, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmull_n_u32(uint32x2_t __p0, uint32_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(uint32x2_t) {__p1, __p1}, 51);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmull_n_u16(uint16x4_t __p0, uint16_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(uint16x4_t) {__p1, __p1, __p1, __p1}, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmull_n_u16(uint16x4_t __p0, uint16_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)(uint16x4_t) {__p1, __p1, __p1, __p1}, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmull_n_u16(uint16x4_t __p0, uint16_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(uint16x4_t) {__p1, __p1, __p1, __p1}, 50);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__rev0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vmull_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vmvn_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai poly8x8_t vmvn_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vmvnq_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai poly8x16_t vmvnq_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmvnq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint8x16_t vmvnq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmvnq_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint32x4_t vmvnq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmvnq_u16(uint16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint16x8_t vmvnq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmvnq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int8x16_t vmvnq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmvnq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int32x4_t vmvnq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmvnq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int16x8_t vmvnq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vmvn_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint8x8_t vmvn_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vmvn_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint32x2_t vmvn_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vmvn_u16(uint16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai uint16x4_t vmvn_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vmvn_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int8x8_t vmvn_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vmvn_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int32x2_t vmvn_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vmvn_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = ~__p0;
+  return __ret;
+}
+#else
+__ai int16x4_t vmvn_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = ~__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vnegq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int8x16_t vnegq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vnegq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai float32x4_t vnegq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vnegq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int32x4_t vnegq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vnegq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int16x8_t vnegq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vneg_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int8x8_t vneg_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vneg_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai float32x2_t vneg_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vneg_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int32x2_t vneg_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vneg_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int16x4_t vneg_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vornq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vornq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vornq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vornq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vornq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vornq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vornq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vornq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vornq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vornq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vornq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vornq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vornq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vornq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vornq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vornq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vorn_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vorn_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vorn_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vorn_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vorn_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vorn_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vorn_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vorn_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vorn_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vorn_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vorn_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vorn_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vorn_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vorn_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vorn_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 | ~__p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vorn_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 | ~__rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vorrq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vorrq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vorrq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vorrq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vorrq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vorrq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vorrq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vorrq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vorrq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vorrq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vorrq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vorrq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vorrq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vorrq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vorrq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vorrq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vorr_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vorr_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vorr_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vorr_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vorr_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vorr_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vorr_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vorr_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vorr_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vorr_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vorr_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vorr_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vorr_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vorr_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vorr_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 | __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vorr_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 | __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vpadalq_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vpadalq_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vpadalq_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vpadalq_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vpadalq_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vpadalq_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vpadalq_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vpadalq_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vpadalq_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vpadalq_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vpadalq_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpadalq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vpadalq_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpadalq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vpadal_u8(uint16x4_t __p0, uint8x8_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vpadal_u8(uint16x4_t __p0, uint8x8_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpadal_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vpadal_u32(uint64x1_t __p0, uint32x2_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vpadal_u32(uint64x1_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__rev1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vpadal_u16(uint32x2_t __p0, uint16x4_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vpadal_u16(uint32x2_t __p0, uint16x4_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpadal_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vpadal_s8(int16x4_t __p0, int8x8_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vpadal_s8(int16x4_t __p0, int8x8_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpadal_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vpadal_s32(int64x1_t __p0, int32x2_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vpadal_s32(int64x1_t __p0, int32x2_t __p1) {
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__rev1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vpadal_s16(int32x2_t __p0, int16x4_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpadal_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vpadal_s16(int32x2_t __p0, int16x4_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpadal_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vpadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vpadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vpadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vpadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vpadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vpadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vpadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vpadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vpadd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vpadd_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vpadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vpadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vpadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpadd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vpadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vpaddlq_u8(uint8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vpaddlq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vpaddlq_u32(uint32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vpaddlq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vpaddlq_u16(uint16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vpaddlq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vpaddlq_s8(int8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vpaddlq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vpaddlq_s32(int32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vpaddlq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vpaddlq_s16(int16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpaddlq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vpaddlq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpaddlq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vpaddl_u8(uint8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vpaddl_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vpaddl_u32(uint32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vpaddl_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vpaddl_u16(uint16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vpaddl_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vpaddl_s8(int8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vpaddl_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vpaddl_s32(int32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vpaddl_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vpaddl_s16(int16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpaddl_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vpaddl_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpaddl_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vpmax_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vpmax_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vpmax_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vpmax_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vpmax_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vpmax_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vpmax_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vpmax_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vpmax_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vpmax_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vpmax_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vpmax_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vpmax_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpmax_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vpmax_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpmax_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vpmin_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vpmin_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vpmin_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vpmin_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vpmin_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vpmin_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vpmin_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vpmin_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vpmin_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vpmin_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vpmin_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vpmin_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vpmin_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpmin_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vpmin_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vpmin_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqabsq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqabsq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqabsq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqabsq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqabsq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqabsq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqabsq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqabsq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqabsq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqabsq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqabsq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqabsq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqabs_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqabs_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqabs_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqabs_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqabs_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqabs_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqabs_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqabs_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqabs_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqabs_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqabs_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqabs_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vqaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vqaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vqaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vqaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vqaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vqaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vqadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vqadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlal_s32(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlal_s32(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlal_s16(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlal_s16(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlal_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlsl_s32(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlsl_s32(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlsl_s16(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlsl_s16(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int32x2_t) {__p2, __p2}, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__rev0, (int8x8_t)__rev1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmlsl_v((int8x16_t)__p0, (int8x8_t)__p1, (int8x8_t)(int16x4_t) {__p2, __p2, __p2, __p2}, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmulhq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqdmulhq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vqdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqdmulh_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vqdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqdmulh_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vqdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmulhq_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulhq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmulhq_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = vqdmulhq_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulhq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __noswap_vqdmulhq_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulh_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = vqdmulh_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulh_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __noswap_vqdmulh_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulh_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = vqdmulh_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulh_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __noswap_vqdmulh_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmulhq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)(int32x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmulhq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmulhq_v((int8x16_t)__rev0, (int8x16_t)(int32x4_t) {__p1, __p1, __p1, __p1}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqdmulhq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqdmulhq_v((int8x16_t)__p0, (int8x16_t)(int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1}, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqdmulhq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqdmulhq_v((int8x16_t)__rev0, (int8x16_t)(int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1}, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqdmulh_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqdmulh_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqdmulh_v((int8x8_t)__rev0, (int8x8_t)(int32x2_t) {__p1, __p1}, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqdmulh_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqdmulh_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqdmulh_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqdmulh_v((int8x8_t)__rev0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmull_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)__p1, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__rev0, (int8x8_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmull_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)__p1, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vqdmull_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmull_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmull_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmull_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__rev0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vqdmull_n_s32(int32x2_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 35);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__rev0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqdmull_n_s16(int16x4_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqdmull_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqmovn_u32(uint32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqmovn_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vqmovn_u32(uint32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqmovn_u64(uint64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqmovn_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vqmovn_u64(uint64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqmovn_u16(uint16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqmovn_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vqmovn_u16(uint16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqmovn_s32(int32x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqmovn_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vqmovn_s32(int32x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqmovn_s64(int64x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqmovn_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vqmovn_s64(int64x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqmovn_s16(int16x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqmovn_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vqmovn_s16(int16x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqmovn_v((int8x16_t)__p0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqmovun_s32(int32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqmovun_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovun_v((int8x16_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vqmovun_s32(int32x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqmovun_s64(int64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqmovun_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovun_v((int8x16_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vqmovun_s64(int64x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqmovun_s16(int16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqmovun_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovun_v((int8x16_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vqmovun_s16(int16x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqmovun_v((int8x16_t)__p0, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqnegq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqnegq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqnegq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqnegq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqnegq_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqnegq_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqnegq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqnegq_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqnegq_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqnegq_v((int8x16_t)__p0, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqnegq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqnegq_v((int8x16_t)__rev0, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqneg_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqneg_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqneg_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqneg_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqneg_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqneg_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqneg_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqneg_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqneg_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqneg_v((int8x8_t)__p0, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqneg_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqneg_v((int8x8_t)__rev0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqrdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqrdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vqrdmulhq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqrdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqrdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vqrdmulhq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqrdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqrdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrdmulh_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vqrdmulh_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqrdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqrdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrdmulh_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vqrdmulh_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqrdmulhq_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulhq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqrdmulhq_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = vqrdmulhq_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulhq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __noswap_vqrdmulhq_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulh_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = vqrdmulh_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulh_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __noswap_vqrdmulh_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulh_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = vqrdmulh_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulh_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __noswap_vqrdmulh_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqrdmulhq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)(int32x4_t) {__p1, __p1, __p1, __p1}, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqrdmulhq_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__rev0, (int8x16_t)(int32x4_t) {__p1, __p1, __p1, __p1}, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqrdmulhq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__p0, (int8x16_t)(int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1}, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqrdmulhq_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrdmulhq_v((int8x16_t)__rev0, (int8x16_t)(int16x8_t) {__p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1}, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqrdmulh_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)(int32x2_t) {__p1, __p1}, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqrdmulh_n_s32(int32x2_t __p0, int32_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrdmulh_v((int8x8_t)__rev0, (int8x8_t)(int32x2_t) {__p1, __p1}, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqrdmulh_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrdmulh_v((int8x8_t)__p0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqrdmulh_n_s16(int16x4_t __p0, int16_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrdmulh_v((int8x8_t)__rev0, (int8x8_t)(int16x4_t) {__p1, __p1, __p1, __p1}, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqrshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqrshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vqrshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vqrshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vqrshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vqrshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vqrshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vqrshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqrshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqrshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqrshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqrshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqrshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqrshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqrshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqrshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqrshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqrshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqrshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqrshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vqrshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vqrshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqrshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqrshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqrshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqrshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqrshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqrshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqrshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqrshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqrshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqrshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vqrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqrshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqrshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqrshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqrshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqrshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqrshrun_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vqshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vqshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vqshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vqshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vqshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vqshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vqshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vqshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqshl_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 48); \
+  __ret; \
+})
+#else
+#define vqshlq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vqshlq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vqshlq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vqshlq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 32); \
+  __ret; \
+})
+#else
+#define vqshlq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vqshlq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vqshlq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vqshlq_n_v((int8x16_t)__s0, __p1, 33); \
+  __ret; \
+})
+#else
+#define vqshlq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vqshlq_n_v((int8x16_t)__rev0, __p1, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqshl_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqshl_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vqshl_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqshl_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vqshl_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vqshl_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vqshl_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshl_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqshl_n_v((int8x8_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vqshl_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqshl_n_v((int8x8_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshluq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vqshluq_n_v((int8x16_t)__s0, __p1, 48); \
+  __ret; \
+})
+#else
+#define vqshluq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vqshluq_n_v((int8x16_t)__rev0, __p1, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshluq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vqshluq_n_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vqshluq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vqshluq_n_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshluq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vqshluq_n_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vqshluq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vqshluq_n_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshluq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vqshluq_n_v((int8x16_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vqshluq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vqshluq_n_v((int8x16_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlu_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshlu_n_v((int8x8_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqshlu_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshlu_n_v((int8x8_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlu_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshlu_n_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqshlu_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshlu_n_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlu_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vqshlu_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vqshlu_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vqshlu_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlu_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshlu_n_v((int8x8_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqshlu_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshlu_n_v((int8x8_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vqshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vqshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vqshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vqshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vqshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrun_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrun_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vqshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrun_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrun_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vqshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrun_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vqshrun_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vqshrun_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vqsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vqsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vqsubq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vqsubq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vqsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vqsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vqsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqsubq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqsubq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqsubq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vqsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vqsubq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vqsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vqsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vqsub_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vqsub_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vqsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vqsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vqsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vqsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqsub_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqsub_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vqsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqsub_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vqsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vqsub_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vraddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vraddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vraddhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vraddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vraddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vraddhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vraddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vraddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vraddhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vraddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vraddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vraddhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vraddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vraddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vraddhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vraddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vraddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vraddhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vraddhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrecpeq_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrecpeq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vrecpeq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrecpeq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrecpeq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrecpeq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrecpeq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrecpeq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrecpe_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrecpe_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrecpe_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrecpe_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrecpe_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrecpe_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrecpe_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrecpe_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrecpsq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrecpsq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrecpsq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrecpsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrecps_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrecps_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrecps_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrecps_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vrev16_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai poly8x8_t vrev16_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vrev16q_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  return __ret;
+}
+#else
+__ai poly8x16_t vrev16q_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrev16q_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrev16q_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrev16q_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  return __ret;
+}
+#else
+__ai int8x16_t vrev16q_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrev16_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrev16_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrev16_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai int8x8_t vrev16_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vrev32_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vrev32_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vrev32_p16(poly16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai poly16x4_t vrev32_p16(poly16x4_t __p0) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vrev32q_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  return __ret;
+}
+#else
+__ai poly8x16_t vrev32q_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vrev32q_p16(poly16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai poly16x8_t vrev32q_p16(poly16x8_t __p0) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrev32q_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrev32q_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vrev32q_u16(uint16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai uint16x8_t vrev32q_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrev32q_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  return __ret;
+}
+#else
+__ai int8x16_t vrev32q_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vrev32q_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2, 5, 4, 7, 6);
+  return __ret;
+}
+#else
+__ai int16x8_t vrev32q_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2, 5, 4, 7, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrev32_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrev32_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vrev32_u16(uint16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai uint16x4_t vrev32_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrev32_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai int8x8_t vrev32_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vrev32_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai int16x4_t vrev32_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vrev64_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vrev64_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vrev64_p16(poly16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vrev64_p16(poly16x4_t __p0) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vrev64q_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  return __ret;
+}
+#else
+__ai poly8x16_t vrev64q_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vrev64q_p16(poly16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai poly16x8_t vrev64q_p16(poly16x8_t __p0) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrev64q_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrev64q_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrev64q_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vrev64q_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vrev64q_u16(uint16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai uint16x8_t vrev64q_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrev64q_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  return __ret;
+}
+#else
+__ai int8x16_t vrev64q_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrev64q_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai float32x4_t vrev64q_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vrev64q_s32(int32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0, 3, 2);
+  return __ret;
+}
+#else
+__ai int32x4_t vrev64q_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0, 3, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vrev64q_s16(int16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0, 7, 6, 5, 4);
+  return __ret;
+}
+#else
+__ai int16x8_t vrev64q_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0, 7, 6, 5, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrev64_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrev64_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrev64_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrev64_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vrev64_u16(uint16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vrev64_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrev64_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vrev64_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrev64_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0);
+  return __ret;
+}
+#else
+__ai float32x2_t vrev64_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vrev64_s32(int32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1, 0);
+  return __ret;
+}
+#else
+__ai int32x2_t vrev64_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vrev64_s16(int16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  return __ret;
+}
+#else
+__ai int16x4_t vrev64_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 3, 2, 1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrhaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrhaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrhaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vrhaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vrhaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vrhaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrhaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vrhaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vrhaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vrhaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vrhaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vrhaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vrhaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vrhaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrhadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrhadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrhadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrhadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vrhadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vrhadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrhadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vrhadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vrhadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vrhadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vrhadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrhadd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vrhadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrhadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vrshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vrshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vrshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vrshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vrshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vrshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vrshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vrshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vrshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vrshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vrshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vrshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vrshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vrshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vrshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vrshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vrshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vrshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vrshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vrshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vrshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vrshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vrshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vrshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrshl_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vrshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 48); \
+  __ret; \
+})
+#else
+#define vrshrq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vrshrq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vrshrq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vrshrq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 32); \
+  __ret; \
+})
+#else
+#define vrshrq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vrshrq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vrshrq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vrshrq_n_v((int8x16_t)__s0, __p1, 33); \
+  __ret; \
+})
+#else
+#define vrshrq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vrshrq_n_v((int8x16_t)__rev0, __p1, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vrshr_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vrshr_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vrshr_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vrshr_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vrshr_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vrshr_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vrshr_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshr_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrshr_n_v((int8x8_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vrshr_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrshr_n_v((int8x8_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vrshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrsqrteq_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrsqrteq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vrsqrteq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vrsqrteq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrsqrteq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrsqrteq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrsqrteq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrsqrteq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrsqrte_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrsqrte_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrsqrte_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrsqrte_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrsqrte_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrsqrte_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrsqrte_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrsqrte_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrsqrtsq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrsqrtsq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrsqrts_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrsqrts_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrsqrts_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrsqrts_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vrsraq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vrsraq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vrsraq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vrsraq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vrsraq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vrsraq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vrsraq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsraq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vrsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vrsraq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vrsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vrsra_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vrsra_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vrsra_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vrsra_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vrsra_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vrsra_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vrsra_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsra_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vrsra_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vrsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vrsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vrsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vrsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vrsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vrsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vrsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vrsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vrsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vrsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vrsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vrsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vrsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vrsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vrsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vrsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsetq_lane_i8(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vsetq_lane_f32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vsetq_lane_f32(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vsetq_lane_f32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsetq_lane_i32(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsetq_lane_i16(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#define __noswap_vset_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vset_lane_i8(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vset_lane_f32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vset_lane_f32(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vset_lane_f32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vset_lane_i32(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#define __noswap_vset_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vset_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vset_lane_i16(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vshlq_u8(uint8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vshlq_u32(uint32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vshlq_u64(uint64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vshlq_u16(uint16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vshlq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vshlq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vshlq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vshlq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vshlq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vshlq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vshl_u8(uint8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vshl_u32(uint32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vshl_u64(uint64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vshl_u16(uint16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vshl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vshl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vshl_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vshl_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vshl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vshl_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 48); \
+  __ret; \
+})
+#else
+#define vshlq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vshlq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vshlq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vshlq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 32); \
+  __ret; \
+})
+#else
+#define vshlq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vshlq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vshlq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshlq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshlq_n_v((int8x16_t)__s0, __p1, 33); \
+  __ret; \
+})
+#else
+#define vshlq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshlq_n_v((int8x16_t)__rev0, __p1, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vshl_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vshl_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vshl_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vshl_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vshl_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vshl_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vshl_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshl_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshl_n_v((int8x8_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vshl_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshl_n_v((int8x8_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vshll_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 49); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vshll_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 51); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vshll_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 50); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 33); \
+  __ret; \
+})
+#else
+#define vshll_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 33); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vshll_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 35); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vshll_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshll_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshll_n_v((int8x8_t)__s0, __p1, 34); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 48); \
+  __ret; \
+})
+#else
+#define vshrq_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 50); \
+  __ret; \
+})
+#else
+#define vshrq_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vshrq_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 49); \
+  __ret; \
+})
+#else
+#define vshrq_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 32); \
+  __ret; \
+})
+#else
+#define vshrq_n_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 34); \
+  __ret; \
+})
+#else
+#define vshrq_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vshrq_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshrq_n_v((int8x16_t)__s0, __p1, 33); \
+  __ret; \
+})
+#else
+#define vshrq_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vshrq_n_v((int8x16_t)__rev0, __p1, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vshr_n_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vshr_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vshr_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vshr_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vshr_n_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vshr_n_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vshr_n_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshr_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshr_n_v((int8x8_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vshr_n_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshr_n_v((int8x8_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#else
+#define vshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 17); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#else
+#define vshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 18); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#else
+#define vshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 16); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#else
+#define vshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#else
+#define vshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#else
+#define vshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__rev0, __p1, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vshrn_n_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vshrn_n_v((int8x16_t)__s0, __p1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 4); \
+  __ret; \
+})
+#else
+#define vsli_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 5); \
+  __ret; \
+})
+#else
+#define vsli_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 36); \
+  __ret; \
+})
+#else
+#define vsliq_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 37); \
+  __ret; \
+})
+#else
+#define vsliq_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vsliq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vsliq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vsliq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vsliq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vsliq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vsliq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vsliq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vsliq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vsli_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vsli_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vsli_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vsli_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vsli_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vsli_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vsli_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vsli_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsli_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vsraq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vsraq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vsraq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vsraq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vsraq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vsraq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vsraq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsraq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsraq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vsraq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsraq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vsra_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vsra_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vsra_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vsra_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vsra_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vsra_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vsra_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsra_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsra_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vsra_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsra_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 4); \
+  __ret; \
+})
+#else
+#define vsri_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = (poly8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 4); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 5); \
+  __ret; \
+})
+#else
+#define vsri_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = (poly16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 5); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 36); \
+  __ret; \
+})
+#else
+#define vsriq_n_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = (poly8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 36); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 37); \
+  __ret; \
+})
+#else
+#define vsriq_n_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = (poly16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 37); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 48); \
+  __ret; \
+})
+#else
+#define vsriq_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = (uint8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 48); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 50); \
+  __ret; \
+})
+#else
+#define vsriq_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = (uint32x4_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 50); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 51); \
+  __ret; \
+})
+#else
+#define vsriq_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 49); \
+  __ret; \
+})
+#else
+#define vsriq_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = (uint16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 49); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 32); \
+  __ret; \
+})
+#else
+#define vsriq_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = (int8x16_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 32); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 34); \
+  __ret; \
+})
+#else
+#define vsriq_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = (int32x4_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 34); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 35); \
+  __ret; \
+})
+#else
+#define vsriq_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 33); \
+  __ret; \
+})
+#else
+#define vsriq_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = (int16x8_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 33); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 16); \
+  __ret; \
+})
+#else
+#define vsri_n_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = (uint8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 16); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 18); \
+  __ret; \
+})
+#else
+#define vsri_n_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = (uint32x2_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 18); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#else
+#define vsri_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64x1_t __s1 = __p1; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 17); \
+  __ret; \
+})
+#else
+#define vsri_n_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = (uint16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 17); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 0); \
+  __ret; \
+})
+#else
+#define vsri_n_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = (int8x8_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 0); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 2); \
+  __ret; \
+})
+#else
+#define vsri_n_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __ret; \
+  __ret = (int32x2_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#else
+#define vsri_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64x1_t __s1 = __p1; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 1); \
+  __ret; \
+})
+#else
+#define vsri_n_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = (int16x4_t) __builtin_neon_vsri_n_v((int8x8_t)__rev0, (int8x8_t)__rev1, __p2, 1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 4); \
+})
+#else
+#define vst1_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 5); \
+})
+#else
+#define vst1_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 36); \
+})
+#else
+#define vst1q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 37); \
+})
+#else
+#define vst1q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 48); \
+})
+#else
+#define vst1q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 50); \
+})
+#else
+#define vst1q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 51); \
+})
+#else
+#define vst1q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 49); \
+})
+#else
+#define vst1q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 32); \
+})
+#else
+#define vst1q_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 41); \
+})
+#else
+#define vst1q_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 40); \
+})
+#else
+#define vst1q_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  float16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 34); \
+})
+#else
+#define vst1q_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 35); \
+})
+#else
+#define vst1q_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 33); \
+})
+#else
+#define vst1q_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 16); \
+})
+#else
+#define vst1_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 18); \
+})
+#else
+#define vst1_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 19); \
+})
+#else
+#define vst1_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 17); \
+})
+#else
+#define vst1_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 0); \
+})
+#else
+#define vst1_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 9); \
+})
+#else
+#define vst1_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 8); \
+})
+#else
+#define vst1_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  float16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 2); \
+})
+#else
+#define vst1_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 3); \
+})
+#else
+#define vst1_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 1); \
+})
+#else
+#define vst1_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__rev1, 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 4); \
+})
+#else
+#define vst1_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8_t __s1 = __p1; \
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 5); \
+})
+#else
+#define vst1_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4_t __s1 = __p1; \
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 36); \
+})
+#else
+#define vst1q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16_t __s1 = __p1; \
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 37); \
+})
+#else
+#define vst1q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8_t __s1 = __p1; \
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 48); \
+})
+#else
+#define vst1q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16_t __s1 = __p1; \
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 50); \
+})
+#else
+#define vst1q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 51); \
+})
+#else
+#define vst1q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2_t __s1 = __p1; \
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 49); \
+})
+#else
+#define vst1q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 32); \
+})
+#else
+#define vst1q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16_t __s1 = __p1; \
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 41); \
+})
+#else
+#define vst1q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 40); \
+})
+#else
+#define vst1q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8_t __s1 = __p1; \
+  float16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 34); \
+})
+#else
+#define vst1q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 35); \
+})
+#else
+#define vst1q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2_t __s1 = __p1; \
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 33); \
+})
+#else
+#define vst1q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 16); \
+})
+#else
+#define vst1_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8_t __s1 = __p1; \
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 18); \
+})
+#else
+#define vst1_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 19); \
+})
+#else
+#define vst1_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 17); \
+})
+#else
+#define vst1_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 0); \
+})
+#else
+#define vst1_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8_t __s1 = __p1; \
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 9); \
+})
+#else
+#define vst1_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 8); \
+})
+#else
+#define vst1_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4_t __s1 = __p1; \
+  float16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 2); \
+})
+#else
+#define vst1_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 3); \
+})
+#else
+#define vst1_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 1); \
+})
+#else
+#define vst1_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__rev1, __p2, 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 4); \
+})
+#else
+#define vst2_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  poly8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 5); \
+})
+#else
+#define vst2_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  poly16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 36); \
+})
+#else
+#define vst2q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  poly8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 37); \
+})
+#else
+#define vst2q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  poly16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 48); \
+})
+#else
+#define vst2q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  uint8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 50); \
+})
+#else
+#define vst2q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  uint32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 49); \
+})
+#else
+#define vst2q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  uint16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 32); \
+})
+#else
+#define vst2q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  int8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 41); \
+})
+#else
+#define vst2q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  float32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 40); \
+})
+#else
+#define vst2q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  float16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 34); \
+})
+#else
+#define vst2q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  int32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 33); \
+})
+#else
+#define vst2q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  int16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 16); \
+})
+#else
+#define vst2_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  uint8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 18); \
+})
+#else
+#define vst2_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  uint32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 19); \
+})
+#else
+#define vst2_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 17); \
+})
+#else
+#define vst2_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  uint16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_s8(__p0, __p1) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 0); \
+})
+#else
+#define vst2_s8(__p0, __p1) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  int8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_f32(__p0, __p1) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 9); \
+})
+#else
+#define vst2_f32(__p0, __p1) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  float32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_v(__p0, __rev1.val[0], __rev1.val[1], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_f16(__p0, __p1) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 8); \
+})
+#else
+#define vst2_f16(__p0, __p1) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  float16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, __rev1.val[0], __rev1.val[1], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_s32(__p0, __p1) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 2); \
+})
+#else
+#define vst2_s32(__p0, __p1) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  int32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_v(__p0, __rev1.val[0], __rev1.val[1], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_s64(__p0, __p1) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 3); \
+})
+#else
+#define vst2_s64(__p0, __p1) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_s16(__p0, __p1) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 1); \
+})
+#else
+#define vst2_s16(__p0, __p1) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  int16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_v(__p0, __rev1.val[0], __rev1.val[1], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 4); \
+})
+#else
+#define vst2_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  poly8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 5); \
+})
+#else
+#define vst2_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  poly16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 37); \
+})
+#else
+#define vst2q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  poly16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 50); \
+})
+#else
+#define vst2q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  uint32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 49); \
+})
+#else
+#define vst2q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  uint16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 41); \
+})
+#else
+#define vst2q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  float32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 40); \
+})
+#else
+#define vst2q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  float16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 34); \
+})
+#else
+#define vst2q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  int32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 33); \
+})
+#else
+#define vst2q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  int16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 16); \
+})
+#else
+#define vst2_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  uint8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 18); \
+})
+#else
+#define vst2_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  uint32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 17); \
+})
+#else
+#define vst2_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  uint16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 0); \
+})
+#else
+#define vst2_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  int8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], __p2, 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 9); \
+})
+#else
+#define vst2_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  float32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 8); \
+})
+#else
+#define vst2_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  float16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 2); \
+})
+#else
+#define vst2_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  int32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 1); \
+})
+#else
+#define vst2_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  int16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst2_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 4); \
+})
+#else
+#define vst3_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  poly8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 5); \
+})
+#else
+#define vst3_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  poly16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 36); \
+})
+#else
+#define vst3q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  poly8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 37); \
+})
+#else
+#define vst3q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  poly16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 48); \
+})
+#else
+#define vst3q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  uint8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 50); \
+})
+#else
+#define vst3q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  uint32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 49); \
+})
+#else
+#define vst3q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  uint16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 32); \
+})
+#else
+#define vst3q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  int8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 41); \
+})
+#else
+#define vst3q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  float32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 40); \
+})
+#else
+#define vst3q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  float16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 34); \
+})
+#else
+#define vst3q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  int32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 33); \
+})
+#else
+#define vst3q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  int16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 16); \
+})
+#else
+#define vst3_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  uint8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 18); \
+})
+#else
+#define vst3_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  uint32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 19); \
+})
+#else
+#define vst3_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 17); \
+})
+#else
+#define vst3_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  uint16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_s8(__p0, __p1) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 0); \
+})
+#else
+#define vst3_s8(__p0, __p1) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  int8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_f32(__p0, __p1) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 9); \
+})
+#else
+#define vst3_f32(__p0, __p1) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  float32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_f16(__p0, __p1) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 8); \
+})
+#else
+#define vst3_f16(__p0, __p1) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  float16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_s32(__p0, __p1) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 2); \
+})
+#else
+#define vst3_s32(__p0, __p1) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  int32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_s64(__p0, __p1) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 3); \
+})
+#else
+#define vst3_s64(__p0, __p1) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_s16(__p0, __p1) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 1); \
+})
+#else
+#define vst3_s16(__p0, __p1) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  int16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 4); \
+})
+#else
+#define vst3_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  poly8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 5); \
+})
+#else
+#define vst3_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  poly16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 37); \
+})
+#else
+#define vst3q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  poly16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 50); \
+})
+#else
+#define vst3q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  uint32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 49); \
+})
+#else
+#define vst3q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  uint16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 41); \
+})
+#else
+#define vst3q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  float32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 40); \
+})
+#else
+#define vst3q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  float16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 34); \
+})
+#else
+#define vst3q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  int32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 33); \
+})
+#else
+#define vst3q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  int16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 16); \
+})
+#else
+#define vst3_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  uint8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 18); \
+})
+#else
+#define vst3_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  uint32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 17); \
+})
+#else
+#define vst3_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  uint16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 0); \
+})
+#else
+#define vst3_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  int8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], __p2, 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 9); \
+})
+#else
+#define vst3_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  float32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 8); \
+})
+#else
+#define vst3_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  float16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 2); \
+})
+#else
+#define vst3_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  int32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 1); \
+})
+#else
+#define vst3_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  int16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst3_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 4); \
+})
+#else
+#define vst4_p8(__p0, __p1) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  poly8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 5); \
+})
+#else
+#define vst4_p16(__p0, __p1) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  poly16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 36); \
+})
+#else
+#define vst4q_p8(__p0, __p1) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  poly8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 37); \
+})
+#else
+#define vst4q_p16(__p0, __p1) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  poly16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 48); \
+})
+#else
+#define vst4q_u8(__p0, __p1) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  uint8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 50); \
+})
+#else
+#define vst4q_u32(__p0, __p1) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  uint32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 49); \
+})
+#else
+#define vst4q_u16(__p0, __p1) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  uint16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 32); \
+})
+#else
+#define vst4q_s8(__p0, __p1) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  int8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 41); \
+})
+#else
+#define vst4q_f32(__p0, __p1) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  float32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 40); \
+})
+#else
+#define vst4q_f16(__p0, __p1) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  float16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 34); \
+})
+#else
+#define vst4q_s32(__p0, __p1) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  int32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 33); \
+})
+#else
+#define vst4q_s16(__p0, __p1) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  int16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 16); \
+})
+#else
+#define vst4_u8(__p0, __p1) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  uint8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 18); \
+})
+#else
+#define vst4_u32(__p0, __p1) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  uint32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 19); \
+})
+#else
+#define vst4_u64(__p0, __p1) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 17); \
+})
+#else
+#define vst4_u16(__p0, __p1) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  uint16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_s8(__p0, __p1) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 0); \
+})
+#else
+#define vst4_s8(__p0, __p1) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  int8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_f32(__p0, __p1) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 9); \
+})
+#else
+#define vst4_f32(__p0, __p1) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  float32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_f16(__p0, __p1) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 8); \
+})
+#else
+#define vst4_f16(__p0, __p1) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  float16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_s32(__p0, __p1) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 2); \
+})
+#else
+#define vst4_s32(__p0, __p1) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  int32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_s64(__p0, __p1) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 3); \
+})
+#else
+#define vst4_s64(__p0, __p1) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_s16(__p0, __p1) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 1); \
+})
+#else
+#define vst4_s16(__p0, __p1) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  int16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 4); \
+})
+#else
+#define vst4_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  poly8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 5); \
+})
+#else
+#define vst4_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  poly16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 37); \
+})
+#else
+#define vst4q_lane_p16(__p0, __p1, __p2) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  poly16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 50); \
+})
+#else
+#define vst4q_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  uint32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 49); \
+})
+#else
+#define vst4q_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  uint16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 41); \
+})
+#else
+#define vst4q_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  float32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 40); \
+})
+#else
+#define vst4q_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  float16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 34); \
+})
+#else
+#define vst4q_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  int32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 33); \
+})
+#else
+#define vst4q_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  int16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 16); \
+})
+#else
+#define vst4_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  uint8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 18); \
+})
+#else
+#define vst4_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  uint32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 17); \
+})
+#else
+#define vst4_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  uint16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 0); \
+})
+#else
+#define vst4_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  int8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], __p2, 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 9); \
+})
+#else
+#define vst4_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  float32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 8); \
+})
+#else
+#define vst4_lane_f16(__p0, __p1, __p2) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  float16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 2); \
+})
+#else
+#define vst4_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  int32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 1); \
+})
+#else
+#define vst4_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  int16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst4_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint8x16_t vsubq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsubq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint64x2_t vsubq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int8x16_t vsubq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vsubq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai float32x4_t vsubq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int32x4_t vsubq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vsubq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int64x2_t vsubq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int16x8_t vsubq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint8x8_t vsub_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint32x2_t vsub_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vsub_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint64x1_t vsub_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai uint16x4_t vsub_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int8x8_t vsub_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vsub_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai float32x2_t vsub_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int32x2_t vsub_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vsub_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int64x1_t vsub_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai int16x4_t vsub_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x4_t __noswap_vsubhn_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 17);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint32x2_t __noswap_vsubhn_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 18);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint8x8_t __noswap_vsubhn_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 16);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x4_t __noswap_vsubhn_s32(int32x4_t __p0, int32x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int32x2_t __noswap_vsubhn_s64(int64x2_t __p0, int64x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__rev0, (int8x16_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int8x8_t __noswap_vsubhn_s16(int16x8_t __p0, int16x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vsubhn_v((int8x16_t)__p0, (int8x16_t)__p1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = vmovl_u8(__p0) - vmovl_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmovl_u8(__rev0) - __noswap_vmovl_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsubl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmovl_u32(__p0) - vmovl_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vsubl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmovl_u32(__rev0) - __noswap_vmovl_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmovl_u16(__p0) - vmovl_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmovl_u16(__rev0) - __noswap_vmovl_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = vmovl_s8(__p0) - vmovl_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vsubl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmovl_s8(__rev0) - __noswap_vmovl_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vsubl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = vmovl_s32(__p0) - vmovl_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vsubl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmovl_s32(__rev0) - __noswap_vmovl_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = vmovl_s16(__p0) - vmovl_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vsubl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmovl_s16(__rev0) - __noswap_vmovl_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubw_u8(uint16x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 - vmovl_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubw_u8(uint16x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __noswap_vmovl_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsubw_u32(uint64x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 - vmovl_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vsubw_u32(uint64x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 - __noswap_vmovl_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubw_u16(uint32x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 - vmovl_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubw_u16(uint32x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __noswap_vmovl_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubw_s8(int16x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 - vmovl_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vsubw_s8(int16x8_t __p0, int8x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __noswap_vmovl_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vsubw_s32(int64x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 - vmovl_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vsubw_s32(int64x2_t __p0, int32x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 - __noswap_vmovl_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubw_s16(int32x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 - vmovl_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vsubw_s16(int32x4_t __p0, int16x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __noswap_vmovl_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbl1_p8(poly8x8_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbl1_p8(poly8x8_t __p0, uint8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__rev0, (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbl1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbl1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbl1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbl1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl1_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbl2_p8(poly8x8x2_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbl2_p8(poly8x8x2_t __p0, uint8x8_t __p1) {
+  poly8x8x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbl2_u8(uint8x8x2_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbl2_u8(uint8x8x2_t __p0, uint8x8_t __p1) {
+  uint8x8x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbl2_s8(int8x8x2_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbl2_s8(int8x8x2_t __p0, int8x8_t __p1) {
+  int8x8x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl2_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbl3_p8(poly8x8x3_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbl3_p8(poly8x8x3_t __p0, uint8x8_t __p1) {
+  poly8x8x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbl3_u8(uint8x8x3_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbl3_u8(uint8x8x3_t __p0, uint8x8_t __p1) {
+  uint8x8x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbl3_s8(int8x8x3_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbl3_s8(int8x8x3_t __p0, int8x8_t __p1) {
+  int8x8x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl3_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbl4_p8(poly8x8x4_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p0.val[3], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbl4_p8(poly8x8x4_t __p0, uint8x8_t __p1) {
+  poly8x8x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev0.val[3], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbl4_u8(uint8x8x4_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p0.val[3], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbl4_u8(uint8x8x4_t __p0, uint8x8_t __p1) {
+  uint8x8x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev0.val[3], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbl4_s8(int8x8x4_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__p0.val[0], (int8x8_t)__p0.val[1], (int8x8_t)__p0.val[2], (int8x8_t)__p0.val[3], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbl4_s8(int8x8x4_t __p0, int8x8_t __p1) {
+  int8x8x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbl4_v((int8x8_t)__rev0.val[0], (int8x8_t)__rev0.val[1], (int8x8_t)__rev0.val[2], (int8x8_t)__rev0.val[3], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbx1_p8(poly8x8_t __p0, poly8x8_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbx1_p8(poly8x8_t __p0, poly8x8_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbx1_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbx1_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbx1_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbx1_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx1_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbx2_p8(poly8x8_t __p0, poly8x8x2_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbx2_p8(poly8x8_t __p0, poly8x8x2_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbx2_u8(uint8x8_t __p0, uint8x8x2_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbx2_u8(uint8x8_t __p0, uint8x8x2_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbx2_s8(int8x8_t __p0, int8x8x2_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbx2_s8(int8x8_t __p0, int8x8x2_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx2_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbx3_p8(poly8x8_t __p0, poly8x8x3_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbx3_p8(poly8x8_t __p0, poly8x8x3_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbx3_u8(uint8x8_t __p0, uint8x8x3_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbx3_u8(uint8x8_t __p0, uint8x8x3_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbx3_s8(int8x8_t __p0, int8x8x3_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbx3_s8(int8x8_t __p0, int8x8x3_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx3_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtbx4_p8(poly8x8_t __p0, poly8x8x4_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p1.val[3], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtbx4_p8(poly8x8_t __p0, poly8x8x4_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtbx4_u8(uint8x8_t __p0, uint8x8x4_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p1.val[3], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtbx4_u8(uint8x8_t __p0, uint8x8x4_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtbx4_s8(int8x8_t __p0, int8x8x4_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__p0, (int8x8_t)__p1.val[0], (int8x8_t)__p1.val[1], (int8x8_t)__p1.val[2], (int8x8_t)__p1.val[3], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vtbx4_s8(int8x8_t __p0, int8x8x4_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vtbx4_v((int8x8_t)__rev0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8x2_t vtrn_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8x2_t vtrn_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 4);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4x2_t vtrn_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 5);
+  return __ret;
+}
+#else
+__ai poly16x4x2_t vtrn_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 5);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16x2_t vtrnq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16x2_t vtrnq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 36);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8x2_t vtrnq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 37);
+  return __ret;
+}
+#else
+__ai poly16x8x2_t vtrnq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 37);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16x2_t vtrnq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16x2_t vtrnq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4x2_t vtrnq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4x2_t vtrnq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8x2_t vtrnq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8x2_t vtrnq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16x2_t vtrnq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16x2_t vtrnq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4x2_t vtrnq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4x2_t vtrnq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4x2_t vtrnq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4x2_t vtrnq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8x2_t vtrnq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8x2_t vtrnq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8x2_t __ret;
+  __builtin_neon_vtrnq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8x2_t vtrn_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8x2_t vtrn_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2x2_t vtrn_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2x2_t vtrn_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4x2_t vtrn_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4x2_t vtrn_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8x2_t vtrn_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8x2_t vtrn_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2x2_t vtrn_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2x2_t vtrn_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2x2_t vtrn_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2x2_t vtrn_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4x2_t vtrn_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4x2_t vtrn_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4x2_t __ret;
+  __builtin_neon_vtrn_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtst_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtst_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vtst_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vtst_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vtstq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vtstq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vtstq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vtstq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vtstq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vtstq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vtstq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vtstq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vtstq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vtstq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vtstq_s8(int8x16_t __p0, int8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vtstq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vtstq_s32(int32x4_t __p0, int32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vtstq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vtstq_s16(int16x8_t __p0, int16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vtstq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtst_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtst_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vtst_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vtst_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vtst_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vtst_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtst_s8(int8x8_t __p0, int8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtst_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vtst_s32(int32x2_t __p0, int32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vtst_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vtst_s16(int16x4_t __p0, int16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vtst_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vtst_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8x2_t vuzp_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8x2_t vuzp_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 4);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4x2_t vuzp_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 5);
+  return __ret;
+}
+#else
+__ai poly16x4x2_t vuzp_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 5);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16x2_t vuzpq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16x2_t vuzpq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 36);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8x2_t vuzpq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 37);
+  return __ret;
+}
+#else
+__ai poly16x8x2_t vuzpq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 37);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16x2_t vuzpq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16x2_t vuzpq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4x2_t vuzpq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4x2_t vuzpq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8x2_t vuzpq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8x2_t vuzpq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16x2_t vuzpq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16x2_t vuzpq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4x2_t vuzpq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4x2_t vuzpq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4x2_t vuzpq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4x2_t vuzpq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8x2_t vuzpq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8x2_t vuzpq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8x2_t __ret;
+  __builtin_neon_vuzpq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8x2_t vuzp_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8x2_t vuzp_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2x2_t vuzp_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2x2_t vuzp_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4x2_t vuzp_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4x2_t vuzp_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8x2_t vuzp_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8x2_t vuzp_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2x2_t vuzp_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2x2_t vuzp_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2x2_t vuzp_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2x2_t vuzp_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4x2_t vuzp_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4x2_t vuzp_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4x2_t __ret;
+  __builtin_neon_vuzp_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8x2_t vzip_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8x2_t vzip_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 4);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4x2_t vzip_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 5);
+  return __ret;
+}
+#else
+__ai poly16x4x2_t vzip_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 5);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16x2_t vzipq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16x2_t vzipq_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 36);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8x2_t vzipq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 37);
+  return __ret;
+}
+#else
+__ai poly16x8x2_t vzipq_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 37);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16x2_t vzipq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16x2_t vzipq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4x2_t vzipq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4x2_t vzipq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8x2_t vzipq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8x2_t vzipq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16x2_t vzipq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16x2_t vzipq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4x2_t vzipq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4x2_t vzipq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4x2_t vzipq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4x2_t vzipq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8x2_t vzipq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8x2_t vzipq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8x2_t __ret;
+  __builtin_neon_vzipq_v(&__ret, (int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8x2_t vzip_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8x2_t vzip_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2x2_t vzip_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2x2_t vzip_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4x2_t vzip_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4x2_t vzip_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8x2_t vzip_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8x2_t vzip_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2x2_t vzip_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2x2_t vzip_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2x2_t vzip_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2x2_t vzip_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4x2_t vzip_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4x2_t vzip_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4x2_t __ret;
+  __builtin_neon_vzip_v(&__ret, (int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0);
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#if !defined(__aarch64__)
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_p16(poly16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_p16(poly16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u8(uint8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u8(uint8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u32(uint32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u32(uint32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u64(uint64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u64(uint64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u16(uint16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u16(uint16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s8(int8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s8(int8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_f32(float32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_f32(float32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_f16(float16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_f16(float16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s32(int32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s32(int32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s64(int64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s64(int64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s16(int16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s16(int16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_p8(poly8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_p8(poly8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u8(uint8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u8(uint8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u32(uint32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u32(uint32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u64(uint64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u64(uint64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u16(uint16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u16(uint16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s8(int8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s8(int8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_f32(float32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_f32(float32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_f16(float16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_f16(float16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s32(int32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s32(int32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s64(int64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s64(int64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s16(int16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s16(int16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_p16(poly16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_p16(poly16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u8(uint8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u8(uint8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u32(uint32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u32(uint32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u64(uint64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u64(uint64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u16(uint16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u16(uint16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s8(int8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s8(int8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_f32(float32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_f32(float32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_f16(float16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_f16(float16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s32(int32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s32(int32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s64(int64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s64(int64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s16(int16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s16(int16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_p8(poly8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_p8(poly8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u8(uint8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u8(uint8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u32(uint32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u32(uint32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u64(uint64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u64(uint64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u16(uint16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u16(uint16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s8(int8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s8(int8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_f32(float32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_f32(float32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_f16(float16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_f16(float16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s32(int32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s32(int32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s64(int64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s64(int64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s16(int16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s16(int16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p8(poly8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p8(poly8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p16(poly16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p16(poly16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u32(uint32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u32(uint32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u64(uint64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u64(uint64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u16(uint16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u16(uint16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_f32(float32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_f32(float32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_f16(float16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_f16(float16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s32(int32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s32(int32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s64(int64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s64(int64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s16(int16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s16(int16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p8(poly8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p8(poly8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p16(poly16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p16(poly16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u8(uint8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u8(uint8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u64(uint64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u64(uint64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u16(uint16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u16(uint16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s8(int8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s8(int8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_f16(float16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_f16(float16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s64(int64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s64(int64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s16(int16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s16(int16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p8(poly8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p8(poly8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p16(poly16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p16(poly16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u8(uint8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u8(uint8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u32(uint32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u32(uint32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u16(uint16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u16(uint16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s8(int8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s8(int8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_f32(float32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_f32(float32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_f16(float16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_f16(float16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s32(int32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s32(int32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s16(int16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s16(int16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p8(poly8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p8(poly8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p16(poly16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p16(poly16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u8(uint8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u8(uint8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u32(uint32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u32(uint32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u64(uint64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u64(uint64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s8(int8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s8(int8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_f32(float32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_f32(float32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_f16(float16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_f16(float16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s32(int32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s32(int32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s64(int64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s64(int64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p8(poly8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p8(poly8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p16(poly16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p16(poly16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u8(uint8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u8(uint8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u32(uint32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u32(uint32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u64(uint64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u64(uint64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u16(uint16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u16(uint16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_f32(float32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_f32(float32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_f16(float16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_f16(float16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s32(int32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s32(int32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s64(int64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s64(int64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s16(int16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s16(int16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p8(poly8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p8(poly8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p16(poly16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p16(poly16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u8(uint8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u8(uint8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u32(uint32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u32(uint32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u64(uint64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u64(uint64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u16(uint16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u16(uint16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s8(int8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s8(int8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_f16(float16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_f16(float16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s32(int32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s32(int32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s64(int64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s64(int64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s16(int16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s16(int16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p8(poly8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p8(poly8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p16(poly16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p16(poly16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u8(uint8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u8(uint8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u32(uint32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u32(uint32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u64(uint64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u64(uint64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u16(uint16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u16(uint16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s8(int8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s8(int8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_f32(float32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_f32(float32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s32(int32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s32(int32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s64(int64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s64(int64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s16(int16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s16(int16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p8(poly8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p8(poly8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p16(poly16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p16(poly16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u8(uint8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u8(uint8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u32(uint32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u32(uint32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u64(uint64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u64(uint64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u16(uint16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u16(uint16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s8(int8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s8(int8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_f16(float16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_f16(float16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s64(int64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s64(int64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s16(int16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s16(int16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p8(poly8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p8(poly8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p16(poly16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p16(poly16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u8(uint8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u8(uint8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u32(uint32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u32(uint32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u64(uint64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u64(uint64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u16(uint16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u16(uint16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s8(int8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s8(int8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_f32(float32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_f32(float32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_f16(float16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_f16(float16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s32(int32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s32(int32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s16(int16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s16(int16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p8(poly8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p8(poly8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p16(poly16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p16(poly16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u8(uint8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u8(uint8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u32(uint32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u32(uint32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u64(uint64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u64(uint64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u16(uint16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u16(uint16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s8(int8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s8(int8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_f32(float32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_f32(float32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_f16(float16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_f16(float16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s32(int32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s32(int32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s64(int64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s64(int64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_p8(poly8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_p8(poly8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_p16(poly16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_p16(poly16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u32(uint32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u32(uint32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u64(uint64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u64(uint64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u16(uint16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u16(uint16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_f32(float32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_f32(float32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_f16(float16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_f16(float16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s32(int32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s32(int32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s64(int64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s64(int64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s16(int16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s16(int16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_p8(poly8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_p8(poly8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_p16(poly16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_p16(poly16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u8(uint8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u8(uint8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u64(uint64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u64(uint64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u16(uint16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u16(uint16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s8(int8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s8(int8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_f16(float16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_f16(float16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s64(int64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s64(int64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s16(int16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s16(int16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_p8(poly8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_p8(poly8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_p16(poly16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_p16(poly16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u8(uint8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u8(uint8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u32(uint32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u32(uint32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u16(uint16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u16(uint16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s8(int8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s8(int8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_f32(float32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_f32(float32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_f16(float16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_f16(float16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s32(int32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s32(int32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s16(int16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s16(int16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_p8(poly8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_p8(poly8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_p16(poly16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_p16(poly16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u8(uint8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u8(uint8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u32(uint32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u32(uint32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u64(uint64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u64(uint64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s8(int8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s8(int8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_f32(float32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_f32(float32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_f16(float16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_f16(float16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s32(int32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s32(int32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s64(int64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s64(int64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_p8(poly8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_p8(poly8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_p16(poly16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_p16(poly16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u8(uint8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u8(uint8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u32(uint32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u32(uint32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u64(uint64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u64(uint64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u16(uint16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u16(uint16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_f32(float32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_f32(float32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_f16(float16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_f16(float16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s32(int32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s32(int32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s64(int64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s64(int64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s16(int16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s16(int16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_p8(poly8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_p8(poly8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_p16(poly16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_p16(poly16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u8(uint8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u8(uint8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u32(uint32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u32(uint32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u64(uint64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u64(uint64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u16(uint16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u16(uint16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s8(int8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s8(int8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_f16(float16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_f16(float16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s32(int32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s32(int32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s64(int64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s64(int64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s16(int16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s16(int16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_p8(poly8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_p8(poly8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_p16(poly16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_p16(poly16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u8(uint8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u8(uint8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u32(uint32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u32(uint32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u64(uint64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u64(uint64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u16(uint16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u16(uint16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s8(int8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s8(int8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_f32(float32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_f32(float32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s32(int32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s32(int32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s64(int64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s64(int64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s16(int16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s16(int16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_p8(poly8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_p8(poly8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_p16(poly16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_p16(poly16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u8(uint8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u8(uint8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u32(uint32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u32(uint32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u64(uint64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u64(uint64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u16(uint16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u16(uint16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s8(int8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s8(int8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_f16(float16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_f16(float16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s64(int64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s64(int64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s16(int16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s16(int16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_p8(poly8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_p8(poly8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_p16(poly16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_p16(poly16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u8(uint8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u8(uint8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u32(uint32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u32(uint32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u64(uint64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u64(uint64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u16(uint16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u16(uint16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s8(int8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s8(int8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_f32(float32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_f32(float32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_f16(float16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_f16(float16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s32(int32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s32(int32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s16(int16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s16(int16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_p8(poly8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_p8(poly8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_p16(poly16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_p16(poly16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u32(uint32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u32(uint32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u64(uint64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u64(uint64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u16(uint16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u16(uint16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s8(int8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s8(int8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_f32(float32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_f32(float32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_f16(float16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_f16(float16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s32(int32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s32(int32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s64(int64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s64(int64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#endif
+#if __ARM_ARCH >= 8
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcvtaq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtaq_s32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vcvtaq_s32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtaq_s32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcvta_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvta_s32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcvta_s32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvta_s32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcvtaq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtaq_u32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcvtaq_u32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtaq_u32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcvta_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvta_u32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcvta_u32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvta_u32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcvtmq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtmq_s32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vcvtmq_s32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtmq_s32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcvtm_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtm_s32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcvtm_s32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtm_s32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcvtmq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtmq_u32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcvtmq_u32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtmq_u32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcvtm_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtm_u32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcvtm_u32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtm_u32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcvtnq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtnq_s32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vcvtnq_s32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtnq_s32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcvtn_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtn_s32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcvtn_s32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtn_s32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcvtnq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtnq_u32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcvtnq_u32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtnq_u32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcvtn_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtn_u32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcvtn_u32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtn_u32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vcvtpq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtpq_s32_v((int8x16_t)__p0, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vcvtpq_s32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vcvtpq_s32_v((int8x16_t)__rev0, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vcvtp_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtp_s32_v((int8x8_t)__p0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vcvtp_s32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vcvtp_s32_v((int8x8_t)__rev0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcvtpq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtpq_u32_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcvtpq_u32_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcvtpq_u32_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcvtp_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtp_u32_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcvtp_u32_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcvtp_u32_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#endif
+#if __ARM_ARCH >= 8 && defined(__aarch64__)
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcvtaq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtaq_s64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vcvtaq_s64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtaq_s64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcvta_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvta_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vcvta_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvta_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcvtaq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtaq_u64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcvtaq_u64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtaq_u64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcvta_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvta_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcvta_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvta_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcvtmq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtmq_s64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vcvtmq_s64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtmq_s64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcvtm_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtm_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vcvtm_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtm_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcvtmq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtmq_u64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcvtmq_u64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtmq_u64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcvtm_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtm_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcvtm_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtm_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcvtnq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtnq_s64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vcvtnq_s64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtnq_s64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcvtn_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtn_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vcvtn_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtn_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcvtnq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtnq_u64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcvtnq_u64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtnq_u64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcvtn_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtn_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcvtn_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtn_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcvtpq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtpq_s64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vcvtpq_s64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtpq_s64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcvtp_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtp_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vcvtp_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvtp_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcvtpq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtpq_u64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcvtpq_u64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtpq_u64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcvtp_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtp_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcvtp_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvtp_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_p64(poly64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_p64(poly64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_p16(poly16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_p16(poly16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u8(uint8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u8(uint8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u32(uint32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u32(uint32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u64(uint64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u64(uint64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_u16(uint16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_u16(uint16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s8(int8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s8(int8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_f64(float64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_f64(float64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_f32(float32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_f32(float32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_f16(float16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_f16(float16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s32(int32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s32(int32x2_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s64(int64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s64(int64x1_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vreinterpret_p8_s16(int16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x8_t vreinterpret_p8_s16(int16x4_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_p8(poly8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_p8(poly8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_p16(poly16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_p16(poly16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_u8(uint8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_u8(uint8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_u32(uint32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_u32(uint32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_u64(uint64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_u64(uint64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_u16(uint16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_u16(uint16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_s8(int8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_s8(int8x8_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_f64(float64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_f64(float64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_f32(float32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_f32(float32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_f16(float16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_f16(float16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_s32(int32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_s32(int32x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_s64(int64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_s64(int64x1_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vreinterpret_p64_s16(int16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vreinterpret_p64_s16(int16x4_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_p8(poly8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_p8(poly8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_p64(poly64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_p64(poly64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u8(uint8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u8(uint8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u32(uint32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u32(uint32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u64(uint64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u64(uint64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_u16(uint16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_u16(uint16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s8(int8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s8(int8x8_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_f64(float64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_f64(float64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_f32(float32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_f32(float32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_f16(float16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_f16(float16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s32(int32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s32(int32x2_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s64(int64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s64(int64x1_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vreinterpret_p16_s16(int16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x4_t vreinterpret_p16_s16(int16x4_t __p0) {
+  poly16x4_t __ret;
+  __ret = (poly16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_p128(poly128_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_p128(poly128_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_p64(poly64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_p64(poly64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_p16(poly16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_p16(poly16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u8(uint8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u8(uint8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u32(uint32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u32(uint32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u64(uint64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u64(uint64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_u16(uint16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_u16(uint16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s8(int8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s8(int8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_f64(float64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_f64(float64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_f32(float32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_f32(float32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_f16(float16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_f16(float16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s32(int32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s32(int32x4_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s64(int64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s64(int64x2_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vreinterpretq_p8_s16(int16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly8x16_t vreinterpretq_p8_s16(int16x8_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_p8(poly8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_p8(poly8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_p64(poly64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_p64(poly64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_p16(poly16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_p16(poly16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_u8(uint8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_u8(uint8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_u32(uint32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_u32(uint32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_u64(uint64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_u64(uint64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_u16(uint16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_u16(uint16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_s8(int8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_s8(int8x16_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_f64(float64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_f64(float64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_f32(float32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_f32(float32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_f16(float16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_f16(float16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_s32(int32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_s32(int32x4_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_s64(int64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_s64(int64x2_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vreinterpretq_p128_s16(int16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly128_t vreinterpretq_p128_s16(int16x8_t __p0) {
+  poly128_t __ret;
+  __ret = (poly128_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_p8(poly8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_p8(poly8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_p128(poly128_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_p128(poly128_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_p16(poly16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_p16(poly16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_u8(uint8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_u8(uint8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_u32(uint32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_u32(uint32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_u64(uint64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_u64(uint64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_u16(uint16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_u16(uint16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_s8(int8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_s8(int8x16_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_f64(float64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_f64(float64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_f32(float32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_f32(float32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_f16(float16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_f16(float16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_s32(int32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_s32(int32x4_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_s64(int64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_s64(int64x2_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vreinterpretq_p64_s16(int16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x2_t vreinterpretq_p64_s16(int16x8_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_p8(poly8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_p8(poly8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_p128(poly128_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_p128(poly128_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_p64(poly64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_p64(poly64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u8(uint8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u8(uint8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u32(uint32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u32(uint32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u64(uint64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u64(uint64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_u16(uint16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_u16(uint16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s8(int8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s8(int8x16_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_f64(float64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_f64(float64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_f32(float32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_f32(float32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_f16(float16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_f16(float16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s32(int32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s32(int32x4_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s64(int64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s64(int64x2_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vreinterpretq_p16_s16(int16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly16x8_t vreinterpretq_p16_s16(int16x8_t __p0) {
+  poly16x8_t __ret;
+  __ret = (poly16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p8(poly8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p8(poly8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p128(poly128_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p128(poly128_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p64(poly64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p64(poly64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_p16(poly16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_p16(poly16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u32(uint32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u32(uint32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u64(uint64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u64(uint64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_u16(uint16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_u16(uint16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_f64(float64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_f64(float64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_f32(float32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_f32(float32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_f16(float16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_f16(float16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s32(int32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s32(int32x4_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s64(int64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s64(int64x2_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vreinterpretq_u8_s16(int16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x16_t vreinterpretq_u8_s16(int16x8_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p8(poly8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p8(poly8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p128(poly128_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p128(poly128_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p64(poly64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p64(poly64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_p16(poly16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_p16(poly16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u8(uint8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u8(uint8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u64(uint64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u64(uint64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_u16(uint16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_u16(uint16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s8(int8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s8(int8x16_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_f64(float64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_f64(float64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_f16(float16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_f16(float16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s64(int64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s64(int64x2_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vreinterpretq_u32_s16(int16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x4_t vreinterpretq_u32_s16(int16x8_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p8(poly8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p8(poly8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p128(poly128_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p128(poly128_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p64(poly64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p64(poly64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_p16(poly16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_p16(poly16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u8(uint8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u8(uint8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u32(uint32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u32(uint32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_u16(uint16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_u16(uint16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s8(int8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s8(int8x16_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_f32(float32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_f32(float32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_f16(float16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_f16(float16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s32(int32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s32(int32x4_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vreinterpretq_u64_s16(int16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x2_t vreinterpretq_u64_s16(int16x8_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p8(poly8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p8(poly8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p128(poly128_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p128(poly128_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p64(poly64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p64(poly64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_p16(poly16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_p16(poly16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u8(uint8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u8(uint8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u32(uint32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u32(uint32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_u64(uint64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_u64(uint64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s8(int8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s8(int8x16_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_f64(float64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_f64(float64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_f32(float32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_f32(float32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_f16(float16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_f16(float16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s32(int32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s32(int32x4_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s64(int64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s64(int64x2_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vreinterpretq_u16_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x8_t vreinterpretq_u16_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p8(poly8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p8(poly8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p128(poly128_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p128(poly128_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p64(poly64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p64(poly64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_p16(poly16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_p16(poly16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u8(uint8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u8(uint8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u32(uint32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u32(uint32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u64(uint64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u64(uint64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_u16(uint16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_u16(uint16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_f64(float64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_f64(float64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_f32(float32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_f32(float32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_f16(float16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_f16(float16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s32(int32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s32(int32x4_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s64(int64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s64(int64x2_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vreinterpretq_s8_s16(int16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x16_t vreinterpretq_s8_s16(int16x8_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_p8(poly8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_p8(poly8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_p128(poly128_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_p128(poly128_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_p64(poly64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_p64(poly64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_p16(poly16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_p16(poly16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_u8(uint8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_u8(uint8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_u32(uint32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_u32(uint32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_u64(uint64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_u64(uint64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_u16(uint16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_u16(uint16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_s8(int8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_s8(int8x16_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_f32(float32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_f32(float32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_f16(float16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_f16(float16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_s32(int32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_s32(int32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_s64(int64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_s64(int64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vreinterpretq_f64_s16(int16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x2_t vreinterpretq_f64_s16(int16x8_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p8(poly8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p8(poly8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p128(poly128_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p128(poly128_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p64(poly64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p64(poly64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_p16(poly16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_p16(poly16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u8(uint8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u8(uint8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u32(uint32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u32(uint32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u64(uint64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u64(uint64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_u16(uint16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_u16(uint16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s8(int8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s8(int8x16_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_f64(float64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_f64(float64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_f16(float16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_f16(float16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s32(int32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s32(int32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s64(int64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s64(int64x2_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vreinterpretq_f32_s16(int16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x4_t vreinterpretq_f32_s16(int16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p8(poly8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p8(poly8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p128(poly128_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p128(poly128_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p64(poly64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p64(poly64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_p16(poly16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_p16(poly16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u8(uint8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u8(uint8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u32(uint32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u32(uint32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u64(uint64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u64(uint64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_u16(uint16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_u16(uint16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s8(int8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s8(int8x16_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_f64(float64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_f64(float64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_f32(float32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_f32(float32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s32(int32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s32(int32x4_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s64(int64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s64(int64x2_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vreinterpretq_f16_s16(int16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x8_t vreinterpretq_f16_s16(int16x8_t __p0) {
+  float16x8_t __ret;
+  __ret = (float16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p8(poly8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p8(poly8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p128(poly128_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p128(poly128_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p64(poly64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p64(poly64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_p16(poly16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_p16(poly16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u8(uint8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u8(uint8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u32(uint32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u32(uint32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u64(uint64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u64(uint64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_u16(uint16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_u16(uint16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s8(int8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s8(int8x16_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_f64(float64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_f64(float64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_f32(float32x4_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_f16(float16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_f16(float16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s64(int64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s64(int64x2_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vreinterpretq_s32_s16(int16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x4_t vreinterpretq_s32_s16(int16x8_t __p0) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p8(poly8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p8(poly8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p128(poly128_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p128(poly128_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p64(poly64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p64(poly64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_p16(poly16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_p16(poly16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u8(uint8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u8(uint8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u32(uint32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u32(uint32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u64(uint64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u64(uint64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_u16(uint16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_u16(uint16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s8(int8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s8(int8x16_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_f32(float32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_f32(float32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_f16(float16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_f16(float16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s32(int32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s32(int32x4_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vreinterpretq_s64_s16(int16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x2_t vreinterpretq_s64_s16(int16x8_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p8(poly8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p8(poly8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p128(poly128_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p128(poly128_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p64(poly64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p64(poly64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_p16(poly16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_p16(poly16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u8(uint8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u8(uint8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u32(uint32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u32(uint32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u64(uint64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u64(uint64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_u16(uint16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_u16(uint16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s8(int8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s8(int8x16_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_f64(float64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_f64(float64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_f32(float32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_f32(float32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_f16(float16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_f16(float16x8_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s32(int32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s32(int32x4_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vreinterpretq_s16_s64(int64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x8_t vreinterpretq_s16_s64(int64x2_t __p0) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_p8(poly8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_p8(poly8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_p64(poly64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_p64(poly64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_p16(poly16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_p16(poly16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u32(uint32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u32(uint32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u64(uint64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u64(uint64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_u16(uint16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_u16(uint16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_f64(float64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_f64(float64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_f32(float32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_f32(float32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_f16(float16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_f16(float16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s32(int32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s32(int32x2_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s64(int64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s64(int64x1_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vreinterpret_u8_s16(int16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint8x8_t vreinterpret_u8_s16(int16x4_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_p8(poly8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_p8(poly8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_p64(poly64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_p64(poly64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_p16(poly16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_p16(poly16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u8(uint8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u8(uint8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u64(uint64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u64(uint64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_u16(uint16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_u16(uint16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s8(int8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s8(int8x8_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_f64(float64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_f64(float64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_f16(float16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_f16(float16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s64(int64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s64(int64x1_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vreinterpret_u32_s16(int16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint32x2_t vreinterpret_u32_s16(int16x4_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_p8(poly8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_p8(poly8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_p64(poly64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_p64(poly64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_p16(poly16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_p16(poly16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u8(uint8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u8(uint8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u32(uint32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u32(uint32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_u16(uint16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_u16(uint16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s8(int8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s8(int8x8_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_f32(float32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_f32(float32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_f16(float16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_f16(float16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s32(int32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s32(int32x2_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vreinterpret_u64_s16(int16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint64x1_t vreinterpret_u64_s16(int16x4_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_p8(poly8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_p8(poly8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_p64(poly64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_p64(poly64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_p16(poly16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_p16(poly16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u8(uint8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u8(uint8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u32(uint32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u32(uint32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_u64(uint64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_u64(uint64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s8(int8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s8(int8x8_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_f64(float64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_f64(float64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_f32(float32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_f32(float32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_f16(float16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_f16(float16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s32(int32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s32(int32x2_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s64(int64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s64(int64x1_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vreinterpret_u16_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai uint16x4_t vreinterpret_u16_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_p8(poly8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_p8(poly8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_p64(poly64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_p64(poly64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_p16(poly16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_p16(poly16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u8(uint8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u8(uint8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u32(uint32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u32(uint32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u64(uint64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u64(uint64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_u16(uint16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_u16(uint16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_f64(float64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_f64(float64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_f32(float32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_f32(float32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_f16(float16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_f16(float16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s32(int32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s32(int32x2_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s64(int64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s64(int64x1_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vreinterpret_s8_s16(int16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#else
+__ai int8x8_t vreinterpret_s8_s16(int16x4_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_p8(poly8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_p8(poly8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_p64(poly64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_p64(poly64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_p16(poly16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_p16(poly16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_u8(uint8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_u8(uint8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_u32(uint32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_u32(uint32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_u64(uint64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_u64(uint64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_u16(uint16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_u16(uint16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_s8(int8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_s8(int8x8_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_f32(float32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_f32(float32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_f16(float16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_f16(float16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_s32(int32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_s32(int32x2_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_s64(int64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_s64(int64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vreinterpret_f64_s16(int16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vreinterpret_f64_s16(int16x4_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_p8(poly8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_p8(poly8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_p64(poly64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_p64(poly64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_p16(poly16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_p16(poly16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u8(uint8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u8(uint8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u32(uint32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u32(uint32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u64(uint64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u64(uint64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_u16(uint16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_u16(uint16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s8(int8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s8(int8x8_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_f64(float64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_f64(float64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_f16(float16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_f16(float16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s32(int32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s32(int32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s64(int64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s64(int64x1_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vreinterpret_f32_s16(int16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai float32x2_t vreinterpret_f32_s16(int16x4_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_p8(poly8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_p8(poly8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_p64(poly64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_p64(poly64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_p16(poly16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_p16(poly16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u8(uint8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u8(uint8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u32(uint32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u32(uint32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u64(uint64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u64(uint64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_u16(uint16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_u16(uint16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s8(int8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s8(int8x8_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_f64(float64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_f64(float64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_f32(float32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_f32(float32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s32(int32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s32(int32x2_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s64(int64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s64(int64x1_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x4_t vreinterpret_f16_s16(int16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai float16x4_t vreinterpret_f16_s16(int16x4_t __p0) {
+  float16x4_t __ret;
+  __ret = (float16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_p8(poly8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_p8(poly8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_p64(poly64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_p64(poly64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_p16(poly16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_p16(poly16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u8(uint8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u8(uint8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u32(uint32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u32(uint32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u64(uint64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u64(uint64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_u16(uint16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_u16(uint16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s8(int8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s8(int8x8_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_f64(float64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_f64(float64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_f32(float32x2_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_f16(float16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_f16(float16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s64(int64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s64(int64x1_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vreinterpret_s32_s16(int16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#else
+__ai int32x2_t vreinterpret_s32_s16(int16x4_t __p0) {
+  int32x2_t __ret;
+  __ret = (int32x2_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_p8(poly8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_p8(poly8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_p64(poly64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_p64(poly64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_p16(poly16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_p16(poly16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u8(uint8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u8(uint8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u32(uint32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u32(uint32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u64(uint64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u64(uint64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_u16(uint16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_u16(uint16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s8(int8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s8(int8x8_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_f32(float32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_f32(float32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_f16(float16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_f16(float16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s32(int32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s32(int32x2_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vreinterpret_s64_s16(int16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai int64x1_t vreinterpret_s64_s16(int16x4_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_p8(poly8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_p8(poly8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_p64(poly64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_p64(poly64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_p16(poly16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_p16(poly16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u32(uint32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u32(uint32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u64(uint64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u64(uint64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_u16(uint16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_u16(uint16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s8(int8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s8(int8x8_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_f64(float64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_f64(float64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_f32(float32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_f32(float32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_f16(float16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_f16(float16x4_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s32(int32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s32(int32x2_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vreinterpret_s16_s64(int64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#else
+__ai int16x4_t vreinterpret_s16_s64(int64x1_t __p0) {
+  int16x4_t __ret;
+  __ret = (int16x4_t)(__p0);
+  return __ret;
+}
+#endif
+
+#endif
+#if __ARM_FEATURE_CRYPTO
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaesdq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesdq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vaesdq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaeseq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaeseq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vaeseq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaeseq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaesimcq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesimcq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vaesimcq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesimcq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaesmcq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesmcq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vaesmcq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vaesmcq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha1cq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1cq_u32((int8x16_t)__p0, __p1, (int8x16_t)__p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha1cq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1cq_u32((int8x16_t)__rev0, __p1, (int8x16_t)__rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vsha1h_u32(uint32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vsha1h_u32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vsha1h_u32(uint32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vsha1h_u32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha1mq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1mq_u32((int8x16_t)__p0, __p1, (int8x16_t)__p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha1mq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1mq_u32((int8x16_t)__rev0, __p1, (int8x16_t)__rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha1pq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1pq_u32((int8x16_t)__p0, __p1, (int8x16_t)__p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha1pq_u32(uint32x4_t __p0, uint32_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1pq_u32((int8x16_t)__rev0, __p1, (int8x16_t)__rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha1su0q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1su0q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha1su0q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1su0q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha1su1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1su1q_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha1su1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha1su1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha256hq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256hq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha256hq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256hq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha256h2q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256h2q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha256h2q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256h2q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha256su0q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256su0q_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha256su0q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256su0q_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsha256su1q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256su1q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsha256su1q_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsha256su1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#endif
+#if defined(__aarch64__)
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vabdq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vabdq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vabdq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vabdq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vabd_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vabd_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vabd_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vabdd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vabdd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float64_t vabdd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vabdd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vabds_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vabds_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float32_t vabds_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vabds_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vabsq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vabsq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vabsq_s64(int64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vabsq_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vabsq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vabsq_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vabs_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vabs_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vabs_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vabs_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vabs_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vabs_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vabs_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vabs_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vabsd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vabsd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vabsd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vabsd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vaddq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai float64x2_t vaddq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 + __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vadd_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#else
+__ai float64x1_t vadd_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 + __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vaddhn_u32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vaddhn_u32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vaddhn_u64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vaddhn_u64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vaddhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vaddhn_u16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint8x16_t vaddhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vaddhn_u16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vaddhn_s32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vaddhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vaddhn_s32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vaddhn_s64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vaddhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vaddhn_s64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vaddhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vaddhn_s16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int8x16_t vaddhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vaddhn_s16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vaddlvq_u8(uint8x16_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddlvq_u8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vaddlvq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddlvq_u8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vaddlvq_u32(uint32x4_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddlvq_u32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vaddlvq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddlvq_u32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vaddlvq_u16(uint16x8_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddlvq_u16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vaddlvq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddlvq_u16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vaddlvq_s8(int8x16_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddlvq_s8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vaddlvq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddlvq_s8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vaddlvq_s32(int32x4_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddlvq_s32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int64_t vaddlvq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddlvq_s32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vaddlvq_s16(int16x8_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddlvq_s16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vaddlvq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddlvq_s16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vaddlv_u8(uint8x8_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddlv_u8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vaddlv_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddlv_u8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vaddlv_u32(uint32x2_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddlv_u32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vaddlv_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddlv_u32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vaddlv_u16(uint16x4_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddlv_u16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vaddlv_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddlv_u16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vaddlv_s8(int8x8_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddlv_s8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vaddlv_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddlv_s8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vaddlv_s32(int32x2_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddlv_s32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int64_t vaddlv_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddlv_s32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vaddlv_s16(int16x4_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddlv_s16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vaddlv_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddlv_s16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vaddvq_u8(uint8x16_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vaddvq_u8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vaddvq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vaddvq_u8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vaddvq_u32(uint32x4_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddvq_u32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vaddvq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddvq_u32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vaddvq_u64(uint64x2_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddvq_u64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vaddvq_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vaddvq_u64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vaddvq_u16(uint16x8_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddvq_u16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vaddvq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddvq_u16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vaddvq_s8(int8x16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vaddvq_s8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vaddvq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vaddvq_s8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vaddvq_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vaddvq_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vaddvq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vaddvq_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vaddvq_f32(float32x4_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vaddvq_f32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vaddvq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vaddvq_f32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vaddvq_s32(int32x4_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddvq_s32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vaddvq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddvq_s32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vaddvq_s64(int64x2_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddvq_s64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int64_t vaddvq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vaddvq_s64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vaddvq_s16(int16x8_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddvq_s16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vaddvq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddvq_s16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vaddv_u8(uint8x8_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vaddv_u8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vaddv_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vaddv_u8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vaddv_u32(uint32x2_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddv_u32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vaddv_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vaddv_u32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vaddv_u16(uint16x4_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddv_u16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vaddv_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vaddv_u16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vaddv_s8(int8x8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vaddv_s8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vaddv_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vaddv_s8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vaddv_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vaddv_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vaddv_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vaddv_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vaddv_s32(int32x2_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddv_s32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vaddv_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vaddv_s32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vaddv_s16(int16x4_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddv_s16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vaddv_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vaddv_s16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vbsl_p64(uint64x1_t __p0, poly64x1_t __p1, poly64x1_t __p2) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 6);
+  return __ret;
+}
+#else
+__ai poly64x1_t vbsl_p64(uint64x1_t __p0, poly64x1_t __p1, poly64x1_t __p2) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 6);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vbslq_p64(uint64x2_t __p0, poly64x2_t __p1, poly64x2_t __p2) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 38);
+  return __ret;
+}
+#else
+__ai poly64x2_t vbslq_p64(uint64x2_t __p0, poly64x2_t __p1, poly64x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  poly64x2_t __ret;
+  __ret = (poly64x2_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 38);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vbslq_f64(uint64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vbslq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vbslq_f64(uint64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vbslq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vbsl_f64(uint64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vbsl_f64(uint64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vbsl_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcageq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcageq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcageq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcageq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcage_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcage_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcage_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcage_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcaged_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaged_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcaged_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaged_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcages_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcages_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcages_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcages_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcagtq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcagtq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcagtq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcagtq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcagt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcagt_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcagt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcagt_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcagtd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcagtd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcagtd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcagtd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcagts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcagts_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcagts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcagts_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcaleq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcaleq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcaleq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcaleq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcale_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcale_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcale_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcale_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcaled_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaled_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcaled_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaled_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcales_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcales_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcales_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcales_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcaltq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcaltq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcaltq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcaltq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcalt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcalt_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcalt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcalt_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcaltd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaltd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcaltd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcaltd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcalts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcalts_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcalts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcalts_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceq_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceq_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqq_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqq_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 == __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceq_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceq_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceq_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceq_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceq_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceq_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 == __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vceqd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vceqd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vceqd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vceqd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vceqd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vceqd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vceqd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vceqd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vceqs_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vceqs_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vceqs_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vceqs_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceqz_p8(poly8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceqz_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceqz_p64(poly64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceqz_p64(poly64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vceqz_p16(poly16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vceqz_p16(poly16x4_t __p0) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqzq_p8(poly8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqzq_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqzq_p64(poly64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqzq_p64(poly64x2_t __p0) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vceqzq_p16(poly16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vceqzq_p16(poly16x8_t __p0) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqzq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqzq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqzq_u32(uint32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqzq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqzq_u64(uint64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqzq_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vceqzq_u16(uint16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vceqzq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vceqzq_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vceqzq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqzq_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqzq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqzq_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqzq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vceqzq_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vceqzq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vceqzq_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vceqzq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vceqzq_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vceqzq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vceqzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceqz_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceqz_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceqz_u32(uint32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceqz_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceqz_u64(uint64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceqz_u64(uint64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vceqz_u16(uint16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vceqz_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vceqz_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vceqz_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceqz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceqz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceqz_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceqz_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vceqz_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vceqz_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vceqz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vceqz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vceqz_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vceqz_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vceqz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vceqzd_u64(uint64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqzd_u64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vceqzd_u64(uint64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqzd_u64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vceqzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vceqzd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vceqzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vceqzd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vceqzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqzd_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vceqzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vceqzd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vceqzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vceqzs_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vceqzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vceqzs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgeq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgeq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgeq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgeq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgeq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgeq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 >= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcge_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcge_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcge_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcge_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcge_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcge_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 >= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcged_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcged_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vcged_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcged_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcged_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcged_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcged_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcged_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcged_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcged_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcged_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcged_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcges_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcges_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcges_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcges_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgezq_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgezq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgezq_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgezq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgezq_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgezq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgezq_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgezq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgezq_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgezq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgezq_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcgezq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgezq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcgezq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcgez_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcgez_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcgez_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgez_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgez_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgez_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgez_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgez_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgez_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgez_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgez_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgez_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgez_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcgez_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcgez_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcgez_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcgez_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcgezd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgezd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcgezd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgezd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcgezd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgezd_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcgezd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgezd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcgezs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgezs_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcgezs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgezs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgtq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgtq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgtq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgtq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgtq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgtq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 > __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgt_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgt_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgt_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgt_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 > __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcgtd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgtd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vcgtd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgtd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcgtd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcgtd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcgtd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcgtd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcgts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgts_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcgts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgts_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcgtzq_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcgtzq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgtzq_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgtzq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgtzq_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgtzq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcgtzq_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcgtzq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcgtzq_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcgtzq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcgtzq_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcgtzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcgtzq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcgtzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcgtz_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcgtz_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcgtz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgtz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgtz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgtz_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgtz_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgtz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcgtz_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcgtz_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcgtz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcgtz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcgtz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcgtz_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcgtz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcgtz_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcgtz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcgtzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgtzd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcgtzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcgtzd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcgtzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtzd_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcgtzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcgtzd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcgtzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgtzs_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcgtzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcgtzs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcleq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcleq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcleq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcleq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcleq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcleq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 <= __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcle_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcle_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcle_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcle_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcle_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcle_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 <= __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcled_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcled_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcled_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcled_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcled_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcled_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vcled_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcled_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcled_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcled_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcled_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcled_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcles_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcles_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vcles_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcles_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vclezq_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vclezq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vclezq_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vclezq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vclezq_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vclezq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vclezq_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vclezq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vclezq_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vclezq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vclezq_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vclezq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vclezq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vclezq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vclez_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vclez_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vclez_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vclez_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vclez_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vclez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vclez_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vclez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclez_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclez_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclez_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclez_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vclez_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclez_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vclez_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vclez_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vclez_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vclez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vclez_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vclez_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vclez_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vclez_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vclez_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vclez_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vclezd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vclezd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vclezd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vclezd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vclezd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vclezd_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vclezd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vclezd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vclezs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vclezs_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vclezs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vclezs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcltq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcltq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcltq_f64(float64x2_t __p0, float64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcltq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcltq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcltq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__rev0 < __rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vclt_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vclt_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vclt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vclt_f64(float64x1_t __p0, float64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vclt_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#else
+__ai uint64x1_t vclt_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t)(__p0 < __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcltd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcltd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcltd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcltd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vcltd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcltd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcltd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vcltd_f64(float64_t __p0, float64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vclts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vclts_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vclts_f32(float32_t __p0, float32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vclts_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vcltzq_s8(int8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vcltzq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcltzq_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcltzq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcltzq_f32(float32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcltzq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vcltzq_s32(int32x4_t __p0) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vcltzq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcltzq_s64(int64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcltzq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vcltzq_s16(int16x8_t __p0) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcltzq_v((int8x16_t)__p0, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vcltzq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vcltzq_v((int8x16_t)__rev0, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vcltz_s8(int8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vcltz_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vcltz_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcltz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcltz_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcltz_f32(float32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcltz_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcltz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vcltz_s32(int32x2_t __p0) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vcltz_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vcltz_v((int8x8_t)__rev0, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcltz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcltz_s64(int64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vcltz_s16(int16x4_t __p0) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcltz_v((int8x8_t)__p0, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vcltz_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vcltz_v((int8x8_t)__rev0, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcltzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcltzd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcltzd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcltzd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcltzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltzd_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcltzd_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcltzd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcltzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcltzs_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcltzs_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcltzs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vcombine_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  return __ret;
+}
+#else
+__ai poly64x2_t vcombine_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vcombine_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  return __ret;
+}
+#else
+__ai float64x2_t vcombine_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_p8(__p0_0, __p1_0, __p2_0, __p3_0) __extension__ ({ \
+  poly8x16_t __s0_0 = __p0_0; \
+  poly8x8_t __s2_0 = __p2_0; \
+  poly8x16_t __ret_0; \
+  __ret_0 = vsetq_lane_p8(vget_lane_p8(__s2_0, __p3_0), __s0_0, __p1_0); \
+  __ret_0; \
+})
+#else
+#define vcopyq_lane_p8(__p0_1, __p1_1, __p2_1, __p3_1) __extension__ ({ \
+  poly8x16_t __s0_1 = __p0_1; \
+  poly8x8_t __s2_1 = __p2_1; \
+  poly8x16_t __rev0_1;  __rev0_1 = __builtin_shufflevector(__s0_1, __s0_1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __rev2_1;  __rev2_1 = __builtin_shufflevector(__s2_1, __s2_1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret_1; \
+  __ret_1 = __noswap_vsetq_lane_p8(__noswap_vget_lane_p8(__rev2_1, __p3_1), __rev0_1, __p1_1); \
+  __ret_1 = __builtin_shufflevector(__ret_1, __ret_1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_1; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_p16(__p0_2, __p1_2, __p2_2, __p3_2) __extension__ ({ \
+  poly16x8_t __s0_2 = __p0_2; \
+  poly16x4_t __s2_2 = __p2_2; \
+  poly16x8_t __ret_2; \
+  __ret_2 = vsetq_lane_p16(vget_lane_p16(__s2_2, __p3_2), __s0_2, __p1_2); \
+  __ret_2; \
+})
+#else
+#define vcopyq_lane_p16(__p0_3, __p1_3, __p2_3, __p3_3) __extension__ ({ \
+  poly16x8_t __s0_3 = __p0_3; \
+  poly16x4_t __s2_3 = __p2_3; \
+  poly16x8_t __rev0_3;  __rev0_3 = __builtin_shufflevector(__s0_3, __s0_3, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x4_t __rev2_3;  __rev2_3 = __builtin_shufflevector(__s2_3, __s2_3, 3, 2, 1, 0); \
+  poly16x8_t __ret_3; \
+  __ret_3 = __noswap_vsetq_lane_p16(__noswap_vget_lane_p16(__rev2_3, __p3_3), __rev0_3, __p1_3); \
+  __ret_3 = __builtin_shufflevector(__ret_3, __ret_3, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_3; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_u8(__p0_4, __p1_4, __p2_4, __p3_4) __extension__ ({ \
+  uint8x16_t __s0_4 = __p0_4; \
+  uint8x8_t __s2_4 = __p2_4; \
+  uint8x16_t __ret_4; \
+  __ret_4 = vsetq_lane_u8(vget_lane_u8(__s2_4, __p3_4), __s0_4, __p1_4); \
+  __ret_4; \
+})
+#else
+#define vcopyq_lane_u8(__p0_5, __p1_5, __p2_5, __p3_5) __extension__ ({ \
+  uint8x16_t __s0_5 = __p0_5; \
+  uint8x8_t __s2_5 = __p2_5; \
+  uint8x16_t __rev0_5;  __rev0_5 = __builtin_shufflevector(__s0_5, __s0_5, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev2_5;  __rev2_5 = __builtin_shufflevector(__s2_5, __s2_5, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_5; \
+  __ret_5 = __noswap_vsetq_lane_u8(__noswap_vget_lane_u8(__rev2_5, __p3_5), __rev0_5, __p1_5); \
+  __ret_5 = __builtin_shufflevector(__ret_5, __ret_5, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_5; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_u32(__p0_6, __p1_6, __p2_6, __p3_6) __extension__ ({ \
+  uint32x4_t __s0_6 = __p0_6; \
+  uint32x2_t __s2_6 = __p2_6; \
+  uint32x4_t __ret_6; \
+  __ret_6 = vsetq_lane_u32(vget_lane_u32(__s2_6, __p3_6), __s0_6, __p1_6); \
+  __ret_6; \
+})
+#else
+#define vcopyq_lane_u32(__p0_7, __p1_7, __p2_7, __p3_7) __extension__ ({ \
+  uint32x4_t __s0_7 = __p0_7; \
+  uint32x2_t __s2_7 = __p2_7; \
+  uint32x4_t __rev0_7;  __rev0_7 = __builtin_shufflevector(__s0_7, __s0_7, 3, 2, 1, 0); \
+  uint32x2_t __rev2_7;  __rev2_7 = __builtin_shufflevector(__s2_7, __s2_7, 1, 0); \
+  uint32x4_t __ret_7; \
+  __ret_7 = __noswap_vsetq_lane_u32(__noswap_vget_lane_u32(__rev2_7, __p3_7), __rev0_7, __p1_7); \
+  __ret_7 = __builtin_shufflevector(__ret_7, __ret_7, 3, 2, 1, 0); \
+  __ret_7; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_u64(__p0_8, __p1_8, __p2_8, __p3_8) __extension__ ({ \
+  uint64x2_t __s0_8 = __p0_8; \
+  uint64x1_t __s2_8 = __p2_8; \
+  uint64x2_t __ret_8; \
+  __ret_8 = vsetq_lane_u64(vget_lane_u64(__s2_8, __p3_8), __s0_8, __p1_8); \
+  __ret_8; \
+})
+#else
+#define vcopyq_lane_u64(__p0_9, __p1_9, __p2_9, __p3_9) __extension__ ({ \
+  uint64x2_t __s0_9 = __p0_9; \
+  uint64x1_t __s2_9 = __p2_9; \
+  uint64x2_t __rev0_9;  __rev0_9 = __builtin_shufflevector(__s0_9, __s0_9, 1, 0); \
+  uint64x2_t __ret_9; \
+  __ret_9 = __noswap_vsetq_lane_u64(__noswap_vget_lane_u64(__s2_9, __p3_9), __rev0_9, __p1_9); \
+  __ret_9 = __builtin_shufflevector(__ret_9, __ret_9, 1, 0); \
+  __ret_9; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_u16(__p0_10, __p1_10, __p2_10, __p3_10) __extension__ ({ \
+  uint16x8_t __s0_10 = __p0_10; \
+  uint16x4_t __s2_10 = __p2_10; \
+  uint16x8_t __ret_10; \
+  __ret_10 = vsetq_lane_u16(vget_lane_u16(__s2_10, __p3_10), __s0_10, __p1_10); \
+  __ret_10; \
+})
+#else
+#define vcopyq_lane_u16(__p0_11, __p1_11, __p2_11, __p3_11) __extension__ ({ \
+  uint16x8_t __s0_11 = __p0_11; \
+  uint16x4_t __s2_11 = __p2_11; \
+  uint16x8_t __rev0_11;  __rev0_11 = __builtin_shufflevector(__s0_11, __s0_11, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev2_11;  __rev2_11 = __builtin_shufflevector(__s2_11, __s2_11, 3, 2, 1, 0); \
+  uint16x8_t __ret_11; \
+  __ret_11 = __noswap_vsetq_lane_u16(__noswap_vget_lane_u16(__rev2_11, __p3_11), __rev0_11, __p1_11); \
+  __ret_11 = __builtin_shufflevector(__ret_11, __ret_11, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_11; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_s8(__p0_12, __p1_12, __p2_12, __p3_12) __extension__ ({ \
+  int8x16_t __s0_12 = __p0_12; \
+  int8x8_t __s2_12 = __p2_12; \
+  int8x16_t __ret_12; \
+  __ret_12 = vsetq_lane_s8(vget_lane_s8(__s2_12, __p3_12), __s0_12, __p1_12); \
+  __ret_12; \
+})
+#else
+#define vcopyq_lane_s8(__p0_13, __p1_13, __p2_13, __p3_13) __extension__ ({ \
+  int8x16_t __s0_13 = __p0_13; \
+  int8x8_t __s2_13 = __p2_13; \
+  int8x16_t __rev0_13;  __rev0_13 = __builtin_shufflevector(__s0_13, __s0_13, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev2_13;  __rev2_13 = __builtin_shufflevector(__s2_13, __s2_13, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_13; \
+  __ret_13 = __noswap_vsetq_lane_s8(__noswap_vget_lane_s8(__rev2_13, __p3_13), __rev0_13, __p1_13); \
+  __ret_13 = __builtin_shufflevector(__ret_13, __ret_13, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_13; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_f32(__p0_14, __p1_14, __p2_14, __p3_14) __extension__ ({ \
+  float32x4_t __s0_14 = __p0_14; \
+  float32x2_t __s2_14 = __p2_14; \
+  float32x4_t __ret_14; \
+  __ret_14 = vsetq_lane_f32(vget_lane_f32(__s2_14, __p3_14), __s0_14, __p1_14); \
+  __ret_14; \
+})
+#else
+#define vcopyq_lane_f32(__p0_15, __p1_15, __p2_15, __p3_15) __extension__ ({ \
+  float32x4_t __s0_15 = __p0_15; \
+  float32x2_t __s2_15 = __p2_15; \
+  float32x4_t __rev0_15;  __rev0_15 = __builtin_shufflevector(__s0_15, __s0_15, 3, 2, 1, 0); \
+  float32x2_t __rev2_15;  __rev2_15 = __builtin_shufflevector(__s2_15, __s2_15, 1, 0); \
+  float32x4_t __ret_15; \
+  __ret_15 = __noswap_vsetq_lane_f32(__noswap_vget_lane_f32(__rev2_15, __p3_15), __rev0_15, __p1_15); \
+  __ret_15 = __builtin_shufflevector(__ret_15, __ret_15, 3, 2, 1, 0); \
+  __ret_15; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_s32(__p0_16, __p1_16, __p2_16, __p3_16) __extension__ ({ \
+  int32x4_t __s0_16 = __p0_16; \
+  int32x2_t __s2_16 = __p2_16; \
+  int32x4_t __ret_16; \
+  __ret_16 = vsetq_lane_s32(vget_lane_s32(__s2_16, __p3_16), __s0_16, __p1_16); \
+  __ret_16; \
+})
+#else
+#define vcopyq_lane_s32(__p0_17, __p1_17, __p2_17, __p3_17) __extension__ ({ \
+  int32x4_t __s0_17 = __p0_17; \
+  int32x2_t __s2_17 = __p2_17; \
+  int32x4_t __rev0_17;  __rev0_17 = __builtin_shufflevector(__s0_17, __s0_17, 3, 2, 1, 0); \
+  int32x2_t __rev2_17;  __rev2_17 = __builtin_shufflevector(__s2_17, __s2_17, 1, 0); \
+  int32x4_t __ret_17; \
+  __ret_17 = __noswap_vsetq_lane_s32(__noswap_vget_lane_s32(__rev2_17, __p3_17), __rev0_17, __p1_17); \
+  __ret_17 = __builtin_shufflevector(__ret_17, __ret_17, 3, 2, 1, 0); \
+  __ret_17; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_s64(__p0_18, __p1_18, __p2_18, __p3_18) __extension__ ({ \
+  int64x2_t __s0_18 = __p0_18; \
+  int64x1_t __s2_18 = __p2_18; \
+  int64x2_t __ret_18; \
+  __ret_18 = vsetq_lane_s64(vget_lane_s64(__s2_18, __p3_18), __s0_18, __p1_18); \
+  __ret_18; \
+})
+#else
+#define vcopyq_lane_s64(__p0_19, __p1_19, __p2_19, __p3_19) __extension__ ({ \
+  int64x2_t __s0_19 = __p0_19; \
+  int64x1_t __s2_19 = __p2_19; \
+  int64x2_t __rev0_19;  __rev0_19 = __builtin_shufflevector(__s0_19, __s0_19, 1, 0); \
+  int64x2_t __ret_19; \
+  __ret_19 = __noswap_vsetq_lane_s64(__noswap_vget_lane_s64(__s2_19, __p3_19), __rev0_19, __p1_19); \
+  __ret_19 = __builtin_shufflevector(__ret_19, __ret_19, 1, 0); \
+  __ret_19; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_s16(__p0_20, __p1_20, __p2_20, __p3_20) __extension__ ({ \
+  int16x8_t __s0_20 = __p0_20; \
+  int16x4_t __s2_20 = __p2_20; \
+  int16x8_t __ret_20; \
+  __ret_20 = vsetq_lane_s16(vget_lane_s16(__s2_20, __p3_20), __s0_20, __p1_20); \
+  __ret_20; \
+})
+#else
+#define vcopyq_lane_s16(__p0_21, __p1_21, __p2_21, __p3_21) __extension__ ({ \
+  int16x8_t __s0_21 = __p0_21; \
+  int16x4_t __s2_21 = __p2_21; \
+  int16x8_t __rev0_21;  __rev0_21 = __builtin_shufflevector(__s0_21, __s0_21, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2_21;  __rev2_21 = __builtin_shufflevector(__s2_21, __s2_21, 3, 2, 1, 0); \
+  int16x8_t __ret_21; \
+  __ret_21 = __noswap_vsetq_lane_s16(__noswap_vget_lane_s16(__rev2_21, __p3_21), __rev0_21, __p1_21); \
+  __ret_21 = __builtin_shufflevector(__ret_21, __ret_21, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_21; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_p8(__p0_22, __p1_22, __p2_22, __p3_22) __extension__ ({ \
+  poly8x8_t __s0_22 = __p0_22; \
+  poly8x8_t __s2_22 = __p2_22; \
+  poly8x8_t __ret_22; \
+  __ret_22 = vset_lane_p8(vget_lane_p8(__s2_22, __p3_22), __s0_22, __p1_22); \
+  __ret_22; \
+})
+#else
+#define vcopy_lane_p8(__p0_23, __p1_23, __p2_23, __p3_23) __extension__ ({ \
+  poly8x8_t __s0_23 = __p0_23; \
+  poly8x8_t __s2_23 = __p2_23; \
+  poly8x8_t __rev0_23;  __rev0_23 = __builtin_shufflevector(__s0_23, __s0_23, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __rev2_23;  __rev2_23 = __builtin_shufflevector(__s2_23, __s2_23, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret_23; \
+  __ret_23 = __noswap_vset_lane_p8(__noswap_vget_lane_p8(__rev2_23, __p3_23), __rev0_23, __p1_23); \
+  __ret_23 = __builtin_shufflevector(__ret_23, __ret_23, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_23; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_p16(__p0_24, __p1_24, __p2_24, __p3_24) __extension__ ({ \
+  poly16x4_t __s0_24 = __p0_24; \
+  poly16x4_t __s2_24 = __p2_24; \
+  poly16x4_t __ret_24; \
+  __ret_24 = vset_lane_p16(vget_lane_p16(__s2_24, __p3_24), __s0_24, __p1_24); \
+  __ret_24; \
+})
+#else
+#define vcopy_lane_p16(__p0_25, __p1_25, __p2_25, __p3_25) __extension__ ({ \
+  poly16x4_t __s0_25 = __p0_25; \
+  poly16x4_t __s2_25 = __p2_25; \
+  poly16x4_t __rev0_25;  __rev0_25 = __builtin_shufflevector(__s0_25, __s0_25, 3, 2, 1, 0); \
+  poly16x4_t __rev2_25;  __rev2_25 = __builtin_shufflevector(__s2_25, __s2_25, 3, 2, 1, 0); \
+  poly16x4_t __ret_25; \
+  __ret_25 = __noswap_vset_lane_p16(__noswap_vget_lane_p16(__rev2_25, __p3_25), __rev0_25, __p1_25); \
+  __ret_25 = __builtin_shufflevector(__ret_25, __ret_25, 3, 2, 1, 0); \
+  __ret_25; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_u8(__p0_26, __p1_26, __p2_26, __p3_26) __extension__ ({ \
+  uint8x8_t __s0_26 = __p0_26; \
+  uint8x8_t __s2_26 = __p2_26; \
+  uint8x8_t __ret_26; \
+  __ret_26 = vset_lane_u8(vget_lane_u8(__s2_26, __p3_26), __s0_26, __p1_26); \
+  __ret_26; \
+})
+#else
+#define vcopy_lane_u8(__p0_27, __p1_27, __p2_27, __p3_27) __extension__ ({ \
+  uint8x8_t __s0_27 = __p0_27; \
+  uint8x8_t __s2_27 = __p2_27; \
+  uint8x8_t __rev0_27;  __rev0_27 = __builtin_shufflevector(__s0_27, __s0_27, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __rev2_27;  __rev2_27 = __builtin_shufflevector(__s2_27, __s2_27, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret_27; \
+  __ret_27 = __noswap_vset_lane_u8(__noswap_vget_lane_u8(__rev2_27, __p3_27), __rev0_27, __p1_27); \
+  __ret_27 = __builtin_shufflevector(__ret_27, __ret_27, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_27; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_u32(__p0_28, __p1_28, __p2_28, __p3_28) __extension__ ({ \
+  uint32x2_t __s0_28 = __p0_28; \
+  uint32x2_t __s2_28 = __p2_28; \
+  uint32x2_t __ret_28; \
+  __ret_28 = vset_lane_u32(vget_lane_u32(__s2_28, __p3_28), __s0_28, __p1_28); \
+  __ret_28; \
+})
+#else
+#define vcopy_lane_u32(__p0_29, __p1_29, __p2_29, __p3_29) __extension__ ({ \
+  uint32x2_t __s0_29 = __p0_29; \
+  uint32x2_t __s2_29 = __p2_29; \
+  uint32x2_t __rev0_29;  __rev0_29 = __builtin_shufflevector(__s0_29, __s0_29, 1, 0); \
+  uint32x2_t __rev2_29;  __rev2_29 = __builtin_shufflevector(__s2_29, __s2_29, 1, 0); \
+  uint32x2_t __ret_29; \
+  __ret_29 = __noswap_vset_lane_u32(__noswap_vget_lane_u32(__rev2_29, __p3_29), __rev0_29, __p1_29); \
+  __ret_29 = __builtin_shufflevector(__ret_29, __ret_29, 1, 0); \
+  __ret_29; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_u64(__p0_30, __p1_30, __p2_30, __p3_30) __extension__ ({ \
+  uint64x1_t __s0_30 = __p0_30; \
+  uint64x1_t __s2_30 = __p2_30; \
+  uint64x1_t __ret_30; \
+  __ret_30 = vset_lane_u64(vget_lane_u64(__s2_30, __p3_30), __s0_30, __p1_30); \
+  __ret_30; \
+})
+#else
+#define vcopy_lane_u64(__p0_31, __p1_31, __p2_31, __p3_31) __extension__ ({ \
+  uint64x1_t __s0_31 = __p0_31; \
+  uint64x1_t __s2_31 = __p2_31; \
+  uint64x1_t __ret_31; \
+  __ret_31 = __noswap_vset_lane_u64(__noswap_vget_lane_u64(__s2_31, __p3_31), __s0_31, __p1_31); \
+  __ret_31; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_u16(__p0_32, __p1_32, __p2_32, __p3_32) __extension__ ({ \
+  uint16x4_t __s0_32 = __p0_32; \
+  uint16x4_t __s2_32 = __p2_32; \
+  uint16x4_t __ret_32; \
+  __ret_32 = vset_lane_u16(vget_lane_u16(__s2_32, __p3_32), __s0_32, __p1_32); \
+  __ret_32; \
+})
+#else
+#define vcopy_lane_u16(__p0_33, __p1_33, __p2_33, __p3_33) __extension__ ({ \
+  uint16x4_t __s0_33 = __p0_33; \
+  uint16x4_t __s2_33 = __p2_33; \
+  uint16x4_t __rev0_33;  __rev0_33 = __builtin_shufflevector(__s0_33, __s0_33, 3, 2, 1, 0); \
+  uint16x4_t __rev2_33;  __rev2_33 = __builtin_shufflevector(__s2_33, __s2_33, 3, 2, 1, 0); \
+  uint16x4_t __ret_33; \
+  __ret_33 = __noswap_vset_lane_u16(__noswap_vget_lane_u16(__rev2_33, __p3_33), __rev0_33, __p1_33); \
+  __ret_33 = __builtin_shufflevector(__ret_33, __ret_33, 3, 2, 1, 0); \
+  __ret_33; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_s8(__p0_34, __p1_34, __p2_34, __p3_34) __extension__ ({ \
+  int8x8_t __s0_34 = __p0_34; \
+  int8x8_t __s2_34 = __p2_34; \
+  int8x8_t __ret_34; \
+  __ret_34 = vset_lane_s8(vget_lane_s8(__s2_34, __p3_34), __s0_34, __p1_34); \
+  __ret_34; \
+})
+#else
+#define vcopy_lane_s8(__p0_35, __p1_35, __p2_35, __p3_35) __extension__ ({ \
+  int8x8_t __s0_35 = __p0_35; \
+  int8x8_t __s2_35 = __p2_35; \
+  int8x8_t __rev0_35;  __rev0_35 = __builtin_shufflevector(__s0_35, __s0_35, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __rev2_35;  __rev2_35 = __builtin_shufflevector(__s2_35, __s2_35, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret_35; \
+  __ret_35 = __noswap_vset_lane_s8(__noswap_vget_lane_s8(__rev2_35, __p3_35), __rev0_35, __p1_35); \
+  __ret_35 = __builtin_shufflevector(__ret_35, __ret_35, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_35; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_f32(__p0_36, __p1_36, __p2_36, __p3_36) __extension__ ({ \
+  float32x2_t __s0_36 = __p0_36; \
+  float32x2_t __s2_36 = __p2_36; \
+  float32x2_t __ret_36; \
+  __ret_36 = vset_lane_f32(vget_lane_f32(__s2_36, __p3_36), __s0_36, __p1_36); \
+  __ret_36; \
+})
+#else
+#define vcopy_lane_f32(__p0_37, __p1_37, __p2_37, __p3_37) __extension__ ({ \
+  float32x2_t __s0_37 = __p0_37; \
+  float32x2_t __s2_37 = __p2_37; \
+  float32x2_t __rev0_37;  __rev0_37 = __builtin_shufflevector(__s0_37, __s0_37, 1, 0); \
+  float32x2_t __rev2_37;  __rev2_37 = __builtin_shufflevector(__s2_37, __s2_37, 1, 0); \
+  float32x2_t __ret_37; \
+  __ret_37 = __noswap_vset_lane_f32(__noswap_vget_lane_f32(__rev2_37, __p3_37), __rev0_37, __p1_37); \
+  __ret_37 = __builtin_shufflevector(__ret_37, __ret_37, 1, 0); \
+  __ret_37; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_s32(__p0_38, __p1_38, __p2_38, __p3_38) __extension__ ({ \
+  int32x2_t __s0_38 = __p0_38; \
+  int32x2_t __s2_38 = __p2_38; \
+  int32x2_t __ret_38; \
+  __ret_38 = vset_lane_s32(vget_lane_s32(__s2_38, __p3_38), __s0_38, __p1_38); \
+  __ret_38; \
+})
+#else
+#define vcopy_lane_s32(__p0_39, __p1_39, __p2_39, __p3_39) __extension__ ({ \
+  int32x2_t __s0_39 = __p0_39; \
+  int32x2_t __s2_39 = __p2_39; \
+  int32x2_t __rev0_39;  __rev0_39 = __builtin_shufflevector(__s0_39, __s0_39, 1, 0); \
+  int32x2_t __rev2_39;  __rev2_39 = __builtin_shufflevector(__s2_39, __s2_39, 1, 0); \
+  int32x2_t __ret_39; \
+  __ret_39 = __noswap_vset_lane_s32(__noswap_vget_lane_s32(__rev2_39, __p3_39), __rev0_39, __p1_39); \
+  __ret_39 = __builtin_shufflevector(__ret_39, __ret_39, 1, 0); \
+  __ret_39; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_s64(__p0_40, __p1_40, __p2_40, __p3_40) __extension__ ({ \
+  int64x1_t __s0_40 = __p0_40; \
+  int64x1_t __s2_40 = __p2_40; \
+  int64x1_t __ret_40; \
+  __ret_40 = vset_lane_s64(vget_lane_s64(__s2_40, __p3_40), __s0_40, __p1_40); \
+  __ret_40; \
+})
+#else
+#define vcopy_lane_s64(__p0_41, __p1_41, __p2_41, __p3_41) __extension__ ({ \
+  int64x1_t __s0_41 = __p0_41; \
+  int64x1_t __s2_41 = __p2_41; \
+  int64x1_t __ret_41; \
+  __ret_41 = __noswap_vset_lane_s64(__noswap_vget_lane_s64(__s2_41, __p3_41), __s0_41, __p1_41); \
+  __ret_41; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_s16(__p0_42, __p1_42, __p2_42, __p3_42) __extension__ ({ \
+  int16x4_t __s0_42 = __p0_42; \
+  int16x4_t __s2_42 = __p2_42; \
+  int16x4_t __ret_42; \
+  __ret_42 = vset_lane_s16(vget_lane_s16(__s2_42, __p3_42), __s0_42, __p1_42); \
+  __ret_42; \
+})
+#else
+#define vcopy_lane_s16(__p0_43, __p1_43, __p2_43, __p3_43) __extension__ ({ \
+  int16x4_t __s0_43 = __p0_43; \
+  int16x4_t __s2_43 = __p2_43; \
+  int16x4_t __rev0_43;  __rev0_43 = __builtin_shufflevector(__s0_43, __s0_43, 3, 2, 1, 0); \
+  int16x4_t __rev2_43;  __rev2_43 = __builtin_shufflevector(__s2_43, __s2_43, 3, 2, 1, 0); \
+  int16x4_t __ret_43; \
+  __ret_43 = __noswap_vset_lane_s16(__noswap_vget_lane_s16(__rev2_43, __p3_43), __rev0_43, __p1_43); \
+  __ret_43 = __builtin_shufflevector(__ret_43, __ret_43, 3, 2, 1, 0); \
+  __ret_43; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_p8(__p0_44, __p1_44, __p2_44, __p3_44) __extension__ ({ \
+  poly8x16_t __s0_44 = __p0_44; \
+  poly8x16_t __s2_44 = __p2_44; \
+  poly8x16_t __ret_44; \
+  __ret_44 = vsetq_lane_p8(vgetq_lane_p8(__s2_44, __p3_44), __s0_44, __p1_44); \
+  __ret_44; \
+})
+#else
+#define vcopyq_laneq_p8(__p0_45, __p1_45, __p2_45, __p3_45) __extension__ ({ \
+  poly8x16_t __s0_45 = __p0_45; \
+  poly8x16_t __s2_45 = __p2_45; \
+  poly8x16_t __rev0_45;  __rev0_45 = __builtin_shufflevector(__s0_45, __s0_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __rev2_45;  __rev2_45 = __builtin_shufflevector(__s2_45, __s2_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret_45; \
+  __ret_45 = __noswap_vsetq_lane_p8(__noswap_vgetq_lane_p8(__rev2_45, __p3_45), __rev0_45, __p1_45); \
+  __ret_45 = __builtin_shufflevector(__ret_45, __ret_45, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_45; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_p16(__p0_46, __p1_46, __p2_46, __p3_46) __extension__ ({ \
+  poly16x8_t __s0_46 = __p0_46; \
+  poly16x8_t __s2_46 = __p2_46; \
+  poly16x8_t __ret_46; \
+  __ret_46 = vsetq_lane_p16(vgetq_lane_p16(__s2_46, __p3_46), __s0_46, __p1_46); \
+  __ret_46; \
+})
+#else
+#define vcopyq_laneq_p16(__p0_47, __p1_47, __p2_47, __p3_47) __extension__ ({ \
+  poly16x8_t __s0_47 = __p0_47; \
+  poly16x8_t __s2_47 = __p2_47; \
+  poly16x8_t __rev0_47;  __rev0_47 = __builtin_shufflevector(__s0_47, __s0_47, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __rev2_47;  __rev2_47 = __builtin_shufflevector(__s2_47, __s2_47, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret_47; \
+  __ret_47 = __noswap_vsetq_lane_p16(__noswap_vgetq_lane_p16(__rev2_47, __p3_47), __rev0_47, __p1_47); \
+  __ret_47 = __builtin_shufflevector(__ret_47, __ret_47, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_47; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_u8(__p0_48, __p1_48, __p2_48, __p3_48) __extension__ ({ \
+  uint8x16_t __s0_48 = __p0_48; \
+  uint8x16_t __s2_48 = __p2_48; \
+  uint8x16_t __ret_48; \
+  __ret_48 = vsetq_lane_u8(vgetq_lane_u8(__s2_48, __p3_48), __s0_48, __p1_48); \
+  __ret_48; \
+})
+#else
+#define vcopyq_laneq_u8(__p0_49, __p1_49, __p2_49, __p3_49) __extension__ ({ \
+  uint8x16_t __s0_49 = __p0_49; \
+  uint8x16_t __s2_49 = __p2_49; \
+  uint8x16_t __rev0_49;  __rev0_49 = __builtin_shufflevector(__s0_49, __s0_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev2_49;  __rev2_49 = __builtin_shufflevector(__s2_49, __s2_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_49; \
+  __ret_49 = __noswap_vsetq_lane_u8(__noswap_vgetq_lane_u8(__rev2_49, __p3_49), __rev0_49, __p1_49); \
+  __ret_49 = __builtin_shufflevector(__ret_49, __ret_49, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_49; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_u32(__p0_50, __p1_50, __p2_50, __p3_50) __extension__ ({ \
+  uint32x4_t __s0_50 = __p0_50; \
+  uint32x4_t __s2_50 = __p2_50; \
+  uint32x4_t __ret_50; \
+  __ret_50 = vsetq_lane_u32(vgetq_lane_u32(__s2_50, __p3_50), __s0_50, __p1_50); \
+  __ret_50; \
+})
+#else
+#define vcopyq_laneq_u32(__p0_51, __p1_51, __p2_51, __p3_51) __extension__ ({ \
+  uint32x4_t __s0_51 = __p0_51; \
+  uint32x4_t __s2_51 = __p2_51; \
+  uint32x4_t __rev0_51;  __rev0_51 = __builtin_shufflevector(__s0_51, __s0_51, 3, 2, 1, 0); \
+  uint32x4_t __rev2_51;  __rev2_51 = __builtin_shufflevector(__s2_51, __s2_51, 3, 2, 1, 0); \
+  uint32x4_t __ret_51; \
+  __ret_51 = __noswap_vsetq_lane_u32(__noswap_vgetq_lane_u32(__rev2_51, __p3_51), __rev0_51, __p1_51); \
+  __ret_51 = __builtin_shufflevector(__ret_51, __ret_51, 3, 2, 1, 0); \
+  __ret_51; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_u64(__p0_52, __p1_52, __p2_52, __p3_52) __extension__ ({ \
+  uint64x2_t __s0_52 = __p0_52; \
+  uint64x2_t __s2_52 = __p2_52; \
+  uint64x2_t __ret_52; \
+  __ret_52 = vsetq_lane_u64(vgetq_lane_u64(__s2_52, __p3_52), __s0_52, __p1_52); \
+  __ret_52; \
+})
+#else
+#define vcopyq_laneq_u64(__p0_53, __p1_53, __p2_53, __p3_53) __extension__ ({ \
+  uint64x2_t __s0_53 = __p0_53; \
+  uint64x2_t __s2_53 = __p2_53; \
+  uint64x2_t __rev0_53;  __rev0_53 = __builtin_shufflevector(__s0_53, __s0_53, 1, 0); \
+  uint64x2_t __rev2_53;  __rev2_53 = __builtin_shufflevector(__s2_53, __s2_53, 1, 0); \
+  uint64x2_t __ret_53; \
+  __ret_53 = __noswap_vsetq_lane_u64(__noswap_vgetq_lane_u64(__rev2_53, __p3_53), __rev0_53, __p1_53); \
+  __ret_53 = __builtin_shufflevector(__ret_53, __ret_53, 1, 0); \
+  __ret_53; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_u16(__p0_54, __p1_54, __p2_54, __p3_54) __extension__ ({ \
+  uint16x8_t __s0_54 = __p0_54; \
+  uint16x8_t __s2_54 = __p2_54; \
+  uint16x8_t __ret_54; \
+  __ret_54 = vsetq_lane_u16(vgetq_lane_u16(__s2_54, __p3_54), __s0_54, __p1_54); \
+  __ret_54; \
+})
+#else
+#define vcopyq_laneq_u16(__p0_55, __p1_55, __p2_55, __p3_55) __extension__ ({ \
+  uint16x8_t __s0_55 = __p0_55; \
+  uint16x8_t __s2_55 = __p2_55; \
+  uint16x8_t __rev0_55;  __rev0_55 = __builtin_shufflevector(__s0_55, __s0_55, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev2_55;  __rev2_55 = __builtin_shufflevector(__s2_55, __s2_55, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret_55; \
+  __ret_55 = __noswap_vsetq_lane_u16(__noswap_vgetq_lane_u16(__rev2_55, __p3_55), __rev0_55, __p1_55); \
+  __ret_55 = __builtin_shufflevector(__ret_55, __ret_55, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_55; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_s8(__p0_56, __p1_56, __p2_56, __p3_56) __extension__ ({ \
+  int8x16_t __s0_56 = __p0_56; \
+  int8x16_t __s2_56 = __p2_56; \
+  int8x16_t __ret_56; \
+  __ret_56 = vsetq_lane_s8(vgetq_lane_s8(__s2_56, __p3_56), __s0_56, __p1_56); \
+  __ret_56; \
+})
+#else
+#define vcopyq_laneq_s8(__p0_57, __p1_57, __p2_57, __p3_57) __extension__ ({ \
+  int8x16_t __s0_57 = __p0_57; \
+  int8x16_t __s2_57 = __p2_57; \
+  int8x16_t __rev0_57;  __rev0_57 = __builtin_shufflevector(__s0_57, __s0_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev2_57;  __rev2_57 = __builtin_shufflevector(__s2_57, __s2_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_57; \
+  __ret_57 = __noswap_vsetq_lane_s8(__noswap_vgetq_lane_s8(__rev2_57, __p3_57), __rev0_57, __p1_57); \
+  __ret_57 = __builtin_shufflevector(__ret_57, __ret_57, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_57; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_f32(__p0_58, __p1_58, __p2_58, __p3_58) __extension__ ({ \
+  float32x4_t __s0_58 = __p0_58; \
+  float32x4_t __s2_58 = __p2_58; \
+  float32x4_t __ret_58; \
+  __ret_58 = vsetq_lane_f32(vgetq_lane_f32(__s2_58, __p3_58), __s0_58, __p1_58); \
+  __ret_58; \
+})
+#else
+#define vcopyq_laneq_f32(__p0_59, __p1_59, __p2_59, __p3_59) __extension__ ({ \
+  float32x4_t __s0_59 = __p0_59; \
+  float32x4_t __s2_59 = __p2_59; \
+  float32x4_t __rev0_59;  __rev0_59 = __builtin_shufflevector(__s0_59, __s0_59, 3, 2, 1, 0); \
+  float32x4_t __rev2_59;  __rev2_59 = __builtin_shufflevector(__s2_59, __s2_59, 3, 2, 1, 0); \
+  float32x4_t __ret_59; \
+  __ret_59 = __noswap_vsetq_lane_f32(__noswap_vgetq_lane_f32(__rev2_59, __p3_59), __rev0_59, __p1_59); \
+  __ret_59 = __builtin_shufflevector(__ret_59, __ret_59, 3, 2, 1, 0); \
+  __ret_59; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_s32(__p0_60, __p1_60, __p2_60, __p3_60) __extension__ ({ \
+  int32x4_t __s0_60 = __p0_60; \
+  int32x4_t __s2_60 = __p2_60; \
+  int32x4_t __ret_60; \
+  __ret_60 = vsetq_lane_s32(vgetq_lane_s32(__s2_60, __p3_60), __s0_60, __p1_60); \
+  __ret_60; \
+})
+#else
+#define vcopyq_laneq_s32(__p0_61, __p1_61, __p2_61, __p3_61) __extension__ ({ \
+  int32x4_t __s0_61 = __p0_61; \
+  int32x4_t __s2_61 = __p2_61; \
+  int32x4_t __rev0_61;  __rev0_61 = __builtin_shufflevector(__s0_61, __s0_61, 3, 2, 1, 0); \
+  int32x4_t __rev2_61;  __rev2_61 = __builtin_shufflevector(__s2_61, __s2_61, 3, 2, 1, 0); \
+  int32x4_t __ret_61; \
+  __ret_61 = __noswap_vsetq_lane_s32(__noswap_vgetq_lane_s32(__rev2_61, __p3_61), __rev0_61, __p1_61); \
+  __ret_61 = __builtin_shufflevector(__ret_61, __ret_61, 3, 2, 1, 0); \
+  __ret_61; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_s64(__p0_62, __p1_62, __p2_62, __p3_62) __extension__ ({ \
+  int64x2_t __s0_62 = __p0_62; \
+  int64x2_t __s2_62 = __p2_62; \
+  int64x2_t __ret_62; \
+  __ret_62 = vsetq_lane_s64(vgetq_lane_s64(__s2_62, __p3_62), __s0_62, __p1_62); \
+  __ret_62; \
+})
+#else
+#define vcopyq_laneq_s64(__p0_63, __p1_63, __p2_63, __p3_63) __extension__ ({ \
+  int64x2_t __s0_63 = __p0_63; \
+  int64x2_t __s2_63 = __p2_63; \
+  int64x2_t __rev0_63;  __rev0_63 = __builtin_shufflevector(__s0_63, __s0_63, 1, 0); \
+  int64x2_t __rev2_63;  __rev2_63 = __builtin_shufflevector(__s2_63, __s2_63, 1, 0); \
+  int64x2_t __ret_63; \
+  __ret_63 = __noswap_vsetq_lane_s64(__noswap_vgetq_lane_s64(__rev2_63, __p3_63), __rev0_63, __p1_63); \
+  __ret_63 = __builtin_shufflevector(__ret_63, __ret_63, 1, 0); \
+  __ret_63; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_s16(__p0_64, __p1_64, __p2_64, __p3_64) __extension__ ({ \
+  int16x8_t __s0_64 = __p0_64; \
+  int16x8_t __s2_64 = __p2_64; \
+  int16x8_t __ret_64; \
+  __ret_64 = vsetq_lane_s16(vgetq_lane_s16(__s2_64, __p3_64), __s0_64, __p1_64); \
+  __ret_64; \
+})
+#else
+#define vcopyq_laneq_s16(__p0_65, __p1_65, __p2_65, __p3_65) __extension__ ({ \
+  int16x8_t __s0_65 = __p0_65; \
+  int16x8_t __s2_65 = __p2_65; \
+  int16x8_t __rev0_65;  __rev0_65 = __builtin_shufflevector(__s0_65, __s0_65, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2_65;  __rev2_65 = __builtin_shufflevector(__s2_65, __s2_65, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret_65; \
+  __ret_65 = __noswap_vsetq_lane_s16(__noswap_vgetq_lane_s16(__rev2_65, __p3_65), __rev0_65, __p1_65); \
+  __ret_65 = __builtin_shufflevector(__ret_65, __ret_65, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_65; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_p8(__p0_66, __p1_66, __p2_66, __p3_66) __extension__ ({ \
+  poly8x8_t __s0_66 = __p0_66; \
+  poly8x16_t __s2_66 = __p2_66; \
+  poly8x8_t __ret_66; \
+  __ret_66 = vset_lane_p8(vgetq_lane_p8(__s2_66, __p3_66), __s0_66, __p1_66); \
+  __ret_66; \
+})
+#else
+#define vcopy_laneq_p8(__p0_67, __p1_67, __p2_67, __p3_67) __extension__ ({ \
+  poly8x8_t __s0_67 = __p0_67; \
+  poly8x16_t __s2_67 = __p2_67; \
+  poly8x8_t __rev0_67;  __rev0_67 = __builtin_shufflevector(__s0_67, __s0_67, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __rev2_67;  __rev2_67 = __builtin_shufflevector(__s2_67, __s2_67, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret_67; \
+  __ret_67 = __noswap_vset_lane_p8(__noswap_vgetq_lane_p8(__rev2_67, __p3_67), __rev0_67, __p1_67); \
+  __ret_67 = __builtin_shufflevector(__ret_67, __ret_67, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_67; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_p16(__p0_68, __p1_68, __p2_68, __p3_68) __extension__ ({ \
+  poly16x4_t __s0_68 = __p0_68; \
+  poly16x8_t __s2_68 = __p2_68; \
+  poly16x4_t __ret_68; \
+  __ret_68 = vset_lane_p16(vgetq_lane_p16(__s2_68, __p3_68), __s0_68, __p1_68); \
+  __ret_68; \
+})
+#else
+#define vcopy_laneq_p16(__p0_69, __p1_69, __p2_69, __p3_69) __extension__ ({ \
+  poly16x4_t __s0_69 = __p0_69; \
+  poly16x8_t __s2_69 = __p2_69; \
+  poly16x4_t __rev0_69;  __rev0_69 = __builtin_shufflevector(__s0_69, __s0_69, 3, 2, 1, 0); \
+  poly16x8_t __rev2_69;  __rev2_69 = __builtin_shufflevector(__s2_69, __s2_69, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x4_t __ret_69; \
+  __ret_69 = __noswap_vset_lane_p16(__noswap_vgetq_lane_p16(__rev2_69, __p3_69), __rev0_69, __p1_69); \
+  __ret_69 = __builtin_shufflevector(__ret_69, __ret_69, 3, 2, 1, 0); \
+  __ret_69; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_u8(__p0_70, __p1_70, __p2_70, __p3_70) __extension__ ({ \
+  uint8x8_t __s0_70 = __p0_70; \
+  uint8x16_t __s2_70 = __p2_70; \
+  uint8x8_t __ret_70; \
+  __ret_70 = vset_lane_u8(vgetq_lane_u8(__s2_70, __p3_70), __s0_70, __p1_70); \
+  __ret_70; \
+})
+#else
+#define vcopy_laneq_u8(__p0_71, __p1_71, __p2_71, __p3_71) __extension__ ({ \
+  uint8x8_t __s0_71 = __p0_71; \
+  uint8x16_t __s2_71 = __p2_71; \
+  uint8x8_t __rev0_71;  __rev0_71 = __builtin_shufflevector(__s0_71, __s0_71, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __rev2_71;  __rev2_71 = __builtin_shufflevector(__s2_71, __s2_71, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret_71; \
+  __ret_71 = __noswap_vset_lane_u8(__noswap_vgetq_lane_u8(__rev2_71, __p3_71), __rev0_71, __p1_71); \
+  __ret_71 = __builtin_shufflevector(__ret_71, __ret_71, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_71; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_u32(__p0_72, __p1_72, __p2_72, __p3_72) __extension__ ({ \
+  uint32x2_t __s0_72 = __p0_72; \
+  uint32x4_t __s2_72 = __p2_72; \
+  uint32x2_t __ret_72; \
+  __ret_72 = vset_lane_u32(vgetq_lane_u32(__s2_72, __p3_72), __s0_72, __p1_72); \
+  __ret_72; \
+})
+#else
+#define vcopy_laneq_u32(__p0_73, __p1_73, __p2_73, __p3_73) __extension__ ({ \
+  uint32x2_t __s0_73 = __p0_73; \
+  uint32x4_t __s2_73 = __p2_73; \
+  uint32x2_t __rev0_73;  __rev0_73 = __builtin_shufflevector(__s0_73, __s0_73, 1, 0); \
+  uint32x4_t __rev2_73;  __rev2_73 = __builtin_shufflevector(__s2_73, __s2_73, 3, 2, 1, 0); \
+  uint32x2_t __ret_73; \
+  __ret_73 = __noswap_vset_lane_u32(__noswap_vgetq_lane_u32(__rev2_73, __p3_73), __rev0_73, __p1_73); \
+  __ret_73 = __builtin_shufflevector(__ret_73, __ret_73, 1, 0); \
+  __ret_73; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_u64(__p0_74, __p1_74, __p2_74, __p3_74) __extension__ ({ \
+  uint64x1_t __s0_74 = __p0_74; \
+  uint64x2_t __s2_74 = __p2_74; \
+  uint64x1_t __ret_74; \
+  __ret_74 = vset_lane_u64(vgetq_lane_u64(__s2_74, __p3_74), __s0_74, __p1_74); \
+  __ret_74; \
+})
+#else
+#define vcopy_laneq_u64(__p0_75, __p1_75, __p2_75, __p3_75) __extension__ ({ \
+  uint64x1_t __s0_75 = __p0_75; \
+  uint64x2_t __s2_75 = __p2_75; \
+  uint64x2_t __rev2_75;  __rev2_75 = __builtin_shufflevector(__s2_75, __s2_75, 1, 0); \
+  uint64x1_t __ret_75; \
+  __ret_75 = __noswap_vset_lane_u64(__noswap_vgetq_lane_u64(__rev2_75, __p3_75), __s0_75, __p1_75); \
+  __ret_75; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_u16(__p0_76, __p1_76, __p2_76, __p3_76) __extension__ ({ \
+  uint16x4_t __s0_76 = __p0_76; \
+  uint16x8_t __s2_76 = __p2_76; \
+  uint16x4_t __ret_76; \
+  __ret_76 = vset_lane_u16(vgetq_lane_u16(__s2_76, __p3_76), __s0_76, __p1_76); \
+  __ret_76; \
+})
+#else
+#define vcopy_laneq_u16(__p0_77, __p1_77, __p2_77, __p3_77) __extension__ ({ \
+  uint16x4_t __s0_77 = __p0_77; \
+  uint16x8_t __s2_77 = __p2_77; \
+  uint16x4_t __rev0_77;  __rev0_77 = __builtin_shufflevector(__s0_77, __s0_77, 3, 2, 1, 0); \
+  uint16x8_t __rev2_77;  __rev2_77 = __builtin_shufflevector(__s2_77, __s2_77, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __ret_77; \
+  __ret_77 = __noswap_vset_lane_u16(__noswap_vgetq_lane_u16(__rev2_77, __p3_77), __rev0_77, __p1_77); \
+  __ret_77 = __builtin_shufflevector(__ret_77, __ret_77, 3, 2, 1, 0); \
+  __ret_77; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_s8(__p0_78, __p1_78, __p2_78, __p3_78) __extension__ ({ \
+  int8x8_t __s0_78 = __p0_78; \
+  int8x16_t __s2_78 = __p2_78; \
+  int8x8_t __ret_78; \
+  __ret_78 = vset_lane_s8(vgetq_lane_s8(__s2_78, __p3_78), __s0_78, __p1_78); \
+  __ret_78; \
+})
+#else
+#define vcopy_laneq_s8(__p0_79, __p1_79, __p2_79, __p3_79) __extension__ ({ \
+  int8x8_t __s0_79 = __p0_79; \
+  int8x16_t __s2_79 = __p2_79; \
+  int8x8_t __rev0_79;  __rev0_79 = __builtin_shufflevector(__s0_79, __s0_79, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __rev2_79;  __rev2_79 = __builtin_shufflevector(__s2_79, __s2_79, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret_79; \
+  __ret_79 = __noswap_vset_lane_s8(__noswap_vgetq_lane_s8(__rev2_79, __p3_79), __rev0_79, __p1_79); \
+  __ret_79 = __builtin_shufflevector(__ret_79, __ret_79, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_79; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_f32(__p0_80, __p1_80, __p2_80, __p3_80) __extension__ ({ \
+  float32x2_t __s0_80 = __p0_80; \
+  float32x4_t __s2_80 = __p2_80; \
+  float32x2_t __ret_80; \
+  __ret_80 = vset_lane_f32(vgetq_lane_f32(__s2_80, __p3_80), __s0_80, __p1_80); \
+  __ret_80; \
+})
+#else
+#define vcopy_laneq_f32(__p0_81, __p1_81, __p2_81, __p3_81) __extension__ ({ \
+  float32x2_t __s0_81 = __p0_81; \
+  float32x4_t __s2_81 = __p2_81; \
+  float32x2_t __rev0_81;  __rev0_81 = __builtin_shufflevector(__s0_81, __s0_81, 1, 0); \
+  float32x4_t __rev2_81;  __rev2_81 = __builtin_shufflevector(__s2_81, __s2_81, 3, 2, 1, 0); \
+  float32x2_t __ret_81; \
+  __ret_81 = __noswap_vset_lane_f32(__noswap_vgetq_lane_f32(__rev2_81, __p3_81), __rev0_81, __p1_81); \
+  __ret_81 = __builtin_shufflevector(__ret_81, __ret_81, 1, 0); \
+  __ret_81; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_s32(__p0_82, __p1_82, __p2_82, __p3_82) __extension__ ({ \
+  int32x2_t __s0_82 = __p0_82; \
+  int32x4_t __s2_82 = __p2_82; \
+  int32x2_t __ret_82; \
+  __ret_82 = vset_lane_s32(vgetq_lane_s32(__s2_82, __p3_82), __s0_82, __p1_82); \
+  __ret_82; \
+})
+#else
+#define vcopy_laneq_s32(__p0_83, __p1_83, __p2_83, __p3_83) __extension__ ({ \
+  int32x2_t __s0_83 = __p0_83; \
+  int32x4_t __s2_83 = __p2_83; \
+  int32x2_t __rev0_83;  __rev0_83 = __builtin_shufflevector(__s0_83, __s0_83, 1, 0); \
+  int32x4_t __rev2_83;  __rev2_83 = __builtin_shufflevector(__s2_83, __s2_83, 3, 2, 1, 0); \
+  int32x2_t __ret_83; \
+  __ret_83 = __noswap_vset_lane_s32(__noswap_vgetq_lane_s32(__rev2_83, __p3_83), __rev0_83, __p1_83); \
+  __ret_83 = __builtin_shufflevector(__ret_83, __ret_83, 1, 0); \
+  __ret_83; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_s64(__p0_84, __p1_84, __p2_84, __p3_84) __extension__ ({ \
+  int64x1_t __s0_84 = __p0_84; \
+  int64x2_t __s2_84 = __p2_84; \
+  int64x1_t __ret_84; \
+  __ret_84 = vset_lane_s64(vgetq_lane_s64(__s2_84, __p3_84), __s0_84, __p1_84); \
+  __ret_84; \
+})
+#else
+#define vcopy_laneq_s64(__p0_85, __p1_85, __p2_85, __p3_85) __extension__ ({ \
+  int64x1_t __s0_85 = __p0_85; \
+  int64x2_t __s2_85 = __p2_85; \
+  int64x2_t __rev2_85;  __rev2_85 = __builtin_shufflevector(__s2_85, __s2_85, 1, 0); \
+  int64x1_t __ret_85; \
+  __ret_85 = __noswap_vset_lane_s64(__noswap_vgetq_lane_s64(__rev2_85, __p3_85), __s0_85, __p1_85); \
+  __ret_85; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_s16(__p0_86, __p1_86, __p2_86, __p3_86) __extension__ ({ \
+  int16x4_t __s0_86 = __p0_86; \
+  int16x8_t __s2_86 = __p2_86; \
+  int16x4_t __ret_86; \
+  __ret_86 = vset_lane_s16(vgetq_lane_s16(__s2_86, __p3_86), __s0_86, __p1_86); \
+  __ret_86; \
+})
+#else
+#define vcopy_laneq_s16(__p0_87, __p1_87, __p2_87, __p3_87) __extension__ ({ \
+  int16x4_t __s0_87 = __p0_87; \
+  int16x8_t __s2_87 = __p2_87; \
+  int16x4_t __rev0_87;  __rev0_87 = __builtin_shufflevector(__s0_87, __s0_87, 3, 2, 1, 0); \
+  int16x8_t __rev2_87;  __rev2_87 = __builtin_shufflevector(__s2_87, __s2_87, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret_87; \
+  __ret_87 = __noswap_vset_lane_s16(__noswap_vgetq_lane_s16(__rev2_87, __p3_87), __rev0_87, __p1_87); \
+  __ret_87 = __builtin_shufflevector(__ret_87, __ret_87, 3, 2, 1, 0); \
+  __ret_87; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vcreate_p64(uint64_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vcreate_p64(uint64_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vcreate_f64(uint64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#else
+__ai float64x1_t vcreate_f64(uint64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t)(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vcvts_f32_s32(int32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvts_f32_s32(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vcvts_f32_s32(int32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvts_f32_s32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vcvts_f32_u32(uint32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvts_f32_u32(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vcvts_f32_u32(uint32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvts_f32_u32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vcvt_f32_f64(float64x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_f64((int8x16_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vcvt_f32_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_f64((int8x16_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vcvt_f32_f64(float64x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvt_f32_f64((int8x16_t)__p0, 9);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vcvtd_f64_s64(int64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vcvtd_f64_s64(__p0);
+  return __ret;
+}
+#else
+__ai float64_t vcvtd_f64_s64(int64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vcvtd_f64_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vcvtd_f64_u64(uint64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vcvtd_f64_u64(__p0);
+  return __ret;
+}
+#else
+__ai float64_t vcvtd_f64_u64(uint64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vcvtd_f64_u64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vcvtq_f64_u64(uint64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvtq_f64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai float64x2_t vcvtq_f64_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvtq_f64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vcvtq_f64_s64(int64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvtq_f64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai float64x2_t vcvtq_f64_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvtq_f64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vcvt_f64_u64(uint64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vcvt_f64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai float64x1_t vcvt_f64_u64(uint64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vcvt_f64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vcvt_f64_s64(int64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vcvt_f64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai float64x1_t vcvt_f64_s64(int64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vcvt_f64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vcvt_f64_f32(float32x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvt_f64_f32((int8x8_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vcvt_f64_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvt_f64_f32((int8x8_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float64x2_t __noswap_vcvt_f64_f32(float32x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vcvt_f64_f32((int8x8_t)__p0, 42);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float16x8_t vcvt_high_f16_f32(float16x4_t __p0, float32x4_t __p1) {
+  float16x8_t __ret;
+  __ret = vcombine_f16(__p0, vcvt_f16_f32(__p1));
+  return __ret;
+}
+#else
+__ai float16x8_t vcvt_high_f16_f32(float16x4_t __p0, float32x4_t __p1) {
+  float16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float16x8_t __ret;
+  __ret = __noswap_vcombine_f16(__rev0, __noswap_vcvt_f16_f32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvt_high_f32_f16(float16x8_t __p0) {
+  float32x4_t __ret;
+  __ret = vcvt_f32_f16(vget_high_f16(__p0));
+  return __ret;
+}
+#else
+__ai float32x4_t vcvt_high_f32_f16(float16x8_t __p0) {
+  float16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __noswap_vcvt_f32_f16(__noswap_vget_high_f16(__rev0));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvt_high_f32_f64(float32x2_t __p0, float64x2_t __p1) {
+  float32x4_t __ret;
+  __ret = vcombine_f32(__p0, vcvt_f32_f64(__p1));
+  return __ret;
+}
+#else
+__ai float32x4_t vcvt_high_f32_f64(float32x2_t __p0, float64x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x4_t __ret;
+  __ret = __noswap_vcombine_f32(__rev0, __noswap_vcvt_f32_f64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vcvt_high_f64_f32(float32x4_t __p0) {
+  float64x2_t __ret;
+  __ret = vcvt_f64_f32(vget_high_f32(__p0));
+  return __ret;
+}
+#else
+__ai float64x2_t vcvt_high_f64_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float64x2_t __ret;
+  __ret = __noswap_vcvt_f64_f32(__noswap_vget_high_f32(__rev0));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvts_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vcvts_n_f32_u32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvts_n_f32_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vcvts_n_f32_u32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvts_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vcvts_n_f32_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvts_n_f32_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vcvts_n_f32_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vcvtq_n_f64_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vcvtq_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vcvtq_n_f64_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vcvtq_n_f64_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vcvtq_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vcvtq_n_f64_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vcvt_n_f64_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vcvt_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vcvt_n_f64_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vcvt_n_f64_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vcvt_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vcvt_n_f64_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtd_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vcvtd_n_f64_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvtd_n_f64_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vcvtd_n_f64_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtd_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vcvtd_n_f64_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvtd_n_f64_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vcvtd_n_f64_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvts_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vcvts_n_s32_f32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvts_n_s32_f32(__p0, __p1) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vcvts_n_s32_f32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vcvtq_n_s64_v((int8x16_t)__s0, __p1, 35); \
+  __ret; \
+})
+#else
+#define vcvtq_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = (int64x2_t) __builtin_neon_vcvtq_n_s64_v((int8x16_t)__rev0, __p1, 35); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vcvt_n_s64_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#else
+#define vcvt_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = (int64x1_t) __builtin_neon_vcvt_n_s64_v((int8x8_t)__s0, __p1, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtd_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vcvtd_n_s64_f64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvtd_n_s64_f64(__p0, __p1) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vcvtd_n_s64_f64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvts_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vcvts_n_u32_f32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvts_n_u32_f32(__p0, __p1) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vcvts_n_u32_f32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtq_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vcvtq_n_u64_v((int8x16_t)__s0, __p1, 51); \
+  __ret; \
+})
+#else
+#define vcvtq_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = (uint64x2_t) __builtin_neon_vcvtq_n_u64_v((int8x16_t)__rev0, __p1, 51); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvt_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vcvt_n_u64_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#else
+#define vcvt_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = (uint64x1_t) __builtin_neon_vcvt_n_u64_v((int8x8_t)__s0, __p1, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcvtd_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vcvtd_n_u64_f64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vcvtd_n_u64_f64(__p0, __p1) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vcvtd_n_u64_f64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vcvts_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvts_s32_f32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vcvts_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvts_s32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcvtd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtd_s64_f64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcvtd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtd_s64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vcvtq_s64_f64(float64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtq_s64_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vcvtq_s64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vcvtq_s64_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vcvt_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvt_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vcvt_s64_f64(float64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vcvt_s64_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcvts_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvts_u32_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcvts_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvts_u32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcvtd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtd_u64_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcvtd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtd_u64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vcvtq_u64_f64(float64x2_t __p0) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtq_u64_v((int8x16_t)__p0, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vcvtq_u64_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vcvtq_u64_v((int8x16_t)__rev0, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vcvt_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvt_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vcvt_u64_f64(float64x1_t __p0) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vcvt_u64_v((int8x8_t)__p0, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vcvtas_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtas_s32_f32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vcvtas_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtas_s32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcvtad_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtad_s64_f64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcvtad_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtad_s64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcvtas_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtas_u32_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcvtas_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtas_u32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcvtad_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtad_u64_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcvtad_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtad_u64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vcvtms_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtms_s32_f32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vcvtms_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtms_s32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcvtmd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtmd_s64_f64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcvtmd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtmd_s64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcvtms_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtms_u32_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcvtms_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtms_u32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcvtmd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtmd_u64_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcvtmd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtmd_u64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vcvtns_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtns_s32_f32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vcvtns_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtns_s32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcvtnd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtnd_s64_f64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcvtnd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtnd_s64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcvtns_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtns_u32_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcvtns_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtns_u32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcvtnd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtnd_u64_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcvtnd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtnd_u64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vcvtps_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtps_s32_f32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vcvtps_s32_f32(float32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vcvtps_s32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vcvtpd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtpd_s64_f64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vcvtpd_s64_f64(float64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vcvtpd_s64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vcvtps_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtps_u32_f32(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vcvtps_u32_f32(float32_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vcvtps_u32_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vcvtpd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtpd_u64_f64(__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vcvtpd_u64_f64(float64_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vcvtpd_u64_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vcvtxd_f32_f64(float64_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvtxd_f32_f64(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vcvtxd_f32_f64(float64_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vcvtxd_f32_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vcvtx_f32_f64(float64x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvtx_f32_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float32x2_t vcvtx_f32_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvtx_f32_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vcvtx_f32_f64(float64x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vcvtx_f32_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vcvtx_high_f32_f64(float32x2_t __p0, float64x2_t __p1) {
+  float32x4_t __ret;
+  __ret = vcombine_f32(__p0, vcvtx_f32_f64(__p1));
+  return __ret;
+}
+#else
+__ai float32x4_t vcvtx_high_f32_f64(float32x2_t __p0, float64x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x4_t __ret;
+  __ret = __noswap_vcombine_f32(__rev0, __noswap_vcvtx_f32_f64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vdivq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __p0 / __p1;
+  return __ret;
+}
+#else
+__ai float64x2_t vdivq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 / __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vdivq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __p0 / __p1;
+  return __ret;
+}
+#else
+__ai float32x4_t vdivq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __rev0 / __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vdiv_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 / __p1;
+  return __ret;
+}
+#else
+__ai float64x1_t vdiv_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 / __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vdiv_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __p0 / __p1;
+  return __ret;
+}
+#else
+__ai float32x2_t vdiv_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __rev0 / __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_lane_p8(__p0, __p1) __extension__ ({ \
+  poly8x8_t __s0 = __p0; \
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_lane_p16(__p0, __p1) __extension__ ({ \
+  poly16x4_t __s0 = __p0; \
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_lane_u8(__p0, __p1) __extension__ ({ \
+  uint8x8_t __s0 = __p0; \
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vdups_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_lane_u32(__p0, __p1) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vdups_lane_i32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vdupd_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_lane_u64(__p0, __p1) __extension__ ({ \
+  uint64x1_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vdupd_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_lane_u16(__p0, __p1) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_lane_s8(__p0, __p1) __extension__ ({ \
+  int8x8_t __s0 = __p0; \
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vdupb_lane_i8((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vdupd_lane_f64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vdupd_lane_f64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vdups_lane_f32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_lane_f32(__p0, __p1) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vdups_lane_f32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vdups_lane_i32((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_lane_s32(__p0, __p1) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vdups_lane_i32((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vdupd_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_lane_s64(__p0, __p1) __extension__ ({ \
+  int64x1_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vdupd_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_lane_s16(__p0, __p1) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vduph_lane_i16((int8x8_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_lane_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_lane_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s0 = __p0; \
+  float16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_lane_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_lane_f16(__p0, __p1) __extension__ ({ \
+  float16x4_t __s0 = __p0; \
+  float16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8_t __ret; \
+  __ret = (poly8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16_t __ret; \
+  __ret = (poly16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vdups_laneq_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vdups_laneq_i32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vdupd_laneq_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vdupd_laneq_i64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupb_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupb_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vdupb_laneq_i8((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vdupd_laneq_f64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vdupd_laneq_f64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vdups_laneq_f32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vdups_laneq_f32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdups_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vdups_laneq_i32((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdups_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vdups_laneq_i32((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupd_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vdupd_laneq_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vdupd_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vdupd_laneq_i64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vduph_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vduph_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vduph_laneq_i16((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64x1_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_p8(__p0, __p1) __extension__ ({ \
+  poly8x16_t __s0 = __p0; \
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_p16(__p0, __p1) __extension__ ({ \
+  poly16x8_t __s0 = __p0; \
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s0 = __p0; \
+  float16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s0 = __p0; \
+  float16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdupq_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdupq_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_u8(__p0, __p1) __extension__ ({ \
+  uint8x16_t __s0 = __p0; \
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_u32(__p0, __p1) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_u64(__p0, __p1) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint64x1_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_u16(__p0, __p1) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x8_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_s8(__p0, __p1) __extension__ ({ \
+  int8x16_t __s0 = __p0; \
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x8_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x1_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_f32(__p0, __p1) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s0 = __p0; \
+  float16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_f16(__p0, __p1) __extension__ ({ \
+  float16x8_t __s0 = __p0; \
+  float16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_s32(__p0, __p1) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x1_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_s64(__p0, __p1) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int64x1_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vdup_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __ret; \
+  __ret = __builtin_shufflevector(__s0, __s0, __p1, __p1, __p1, __p1); \
+  __ret; \
+})
+#else
+#define vdup_laneq_s16(__p0, __p1) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __builtin_shufflevector(__rev0, __rev0, __p1, __p1, __p1, __p1); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vdup_n_p64(poly64_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai poly64x1_t vdup_n_p64(poly64_t __p0) {
+  poly64x1_t __ret;
+  __ret = (poly64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vdupq_n_p64(poly64_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai poly64x2_t vdupq_n_p64(poly64_t __p0) {
+  poly64x2_t __ret;
+  __ret = (poly64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vdupq_n_f64(float64_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai float64x2_t vdupq_n_f64(float64_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vdup_n_f64(float64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai float64x1_t vdup_n_f64(float64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#else
+#define vext_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 38); \
+  __ret; \
+})
+#else
+#define vextq_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vextq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vextq_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 42); \
+  __ret; \
+})
+#else
+#define vextq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vextq_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vext_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#else
+#define vext_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vext_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vfmaq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vfmaq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmaq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float64x2_t __noswap_vfmaq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmaq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 42);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vfma_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vfma_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vfma_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmad_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_lane_f64(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vfmad_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_lane_f64(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#define __noswap_vfmad_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_lane_f64(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmas_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_lane_f32(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vfmas_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_lane_f32(__s0, __s1, (int8x8_t)__rev2, __p3); \
+  __ret; \
+})
+#define __noswap_vfmas_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_lane_f32(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmaq_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 42); \
+  __ret; \
+})
+#else
+#define vfmaq_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__s2, __p3, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfmaq_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 42); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmaq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 41); \
+  __ret; \
+})
+#else
+#define vfmaq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__rev2, __p3, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfmaq_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_lane_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x8_t)__s2, __p3, 41); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfma_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 10); \
+  __ret; \
+})
+#else
+#define vfma_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 10); \
+  __ret; \
+})
+#define __noswap_vfma_lane_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __s2 = __p2; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfma_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 9); \
+  __ret; \
+})
+#else
+#define vfma_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_lane_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, __p3, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfma_lane_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_lane_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x8_t)__s2, __p3, 9); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmad_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_laneq_f64(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vfmad_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_laneq_f64(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#define __noswap_vfmad_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vfmad_laneq_f64(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmas_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_laneq_f32(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vfmas_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_laneq_f32(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#define __noswap_vfmas_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32_t __s0 = __p0; \
+  float32_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32_t __ret; \
+  __ret = (float32_t) __builtin_neon_vfmas_laneq_f32(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmaq_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 42); \
+  __ret; \
+})
+#else
+#define vfmaq_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, __p3, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfmaq_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 42); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmaq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 41); \
+  __ret; \
+})
+#else
+#define vfmaq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, __p3, 41); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfmaq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = (float32x4_t) __builtin_neon_vfmaq_laneq_v((int8x16_t)__s0, (int8x16_t)__s1, (int8x16_t)__s2, __p3, 41); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfma_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 10); \
+  __ret; \
+})
+#else
+#define vfma_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__rev2, __p3, 10); \
+  __ret; \
+})
+#define __noswap_vfma_laneq_f64(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __s2 = __p2; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfma_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 9); \
+  __ret; \
+})
+#else
+#define vfma_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_laneq_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x16_t)__rev2, __p3, 9); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vfma_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = (float32x2_t) __builtin_neon_vfma_laneq_v((int8x8_t)__s0, (int8x8_t)__s1, (int8x16_t)__s2, __p3, 9); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vfmaq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __ret;
+  __ret = vfmaq_f64(__p0, __p1, (float64x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai float64x2_t vfmaq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __noswap_vfmaq_f64(__rev0, __rev1, (float64x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vfmaq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __ret;
+  __ret = vfmaq_f32(__p0, __p1, (float32x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai float32x4_t vfmaq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __noswap_vfmaq_f32(__rev0, __rev1, (float32x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vfma_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __ret;
+  __ret = vfma_f32(__p0, __p1, (float32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai float32x2_t vfma_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __noswap_vfma_f32(__rev0, __rev1, (float32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vfmsq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmsq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vfmsq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float64x2_t __noswap_vfmsq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vfmsq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 42);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vfmsq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmsq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vfmsq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float32x4_t __noswap_vfmsq_f32(float32x4_t __p0, float32x4_t __p1, float32x4_t __p2) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vfmsq_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 41);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vfms_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vfms_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vfms_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vfms_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vfms_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfms_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vfms_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfms_v((int8x8_t)__rev0, (int8x8_t)__rev1, (int8x8_t)__rev2, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vfms_f32(float32x2_t __p0, float32x2_t __p1, float32x2_t __p2) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vfms_v((int8x8_t)__p0, (int8x8_t)__p1, (int8x8_t)__p2, 9);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsd_lane_f64(__p0_88, __p1_88, __p2_88, __p3_88) __extension__ ({ \
+  float64_t __s0_88 = __p0_88; \
+  float64_t __s1_88 = __p1_88; \
+  float64x1_t __s2_88 = __p2_88; \
+  float64_t __ret_88; \
+  __ret_88 = vfmad_lane_f64(__s0_88, __s1_88, -__s2_88, __p3_88); \
+  __ret_88; \
+})
+#else
+#define vfmsd_lane_f64(__p0_89, __p1_89, __p2_89, __p3_89) __extension__ ({ \
+  float64_t __s0_89 = __p0_89; \
+  float64_t __s1_89 = __p1_89; \
+  float64x1_t __s2_89 = __p2_89; \
+  float64_t __ret_89; \
+  __ret_89 = __noswap_vfmad_lane_f64(__s0_89, __s1_89, -__s2_89, __p3_89); \
+  __ret_89; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmss_lane_f32(__p0_90, __p1_90, __p2_90, __p3_90) __extension__ ({ \
+  float32_t __s0_90 = __p0_90; \
+  float32_t __s1_90 = __p1_90; \
+  float32x2_t __s2_90 = __p2_90; \
+  float32_t __ret_90; \
+  __ret_90 = vfmas_lane_f32(__s0_90, __s1_90, -__s2_90, __p3_90); \
+  __ret_90; \
+})
+#else
+#define vfmss_lane_f32(__p0_91, __p1_91, __p2_91, __p3_91) __extension__ ({ \
+  float32_t __s0_91 = __p0_91; \
+  float32_t __s1_91 = __p1_91; \
+  float32x2_t __s2_91 = __p2_91; \
+  float32x2_t __rev2_91;  __rev2_91 = __builtin_shufflevector(__s2_91, __s2_91, 1, 0); \
+  float32_t __ret_91; \
+  __ret_91 = __noswap_vfmas_lane_f32(__s0_91, __s1_91, -__rev2_91, __p3_91); \
+  __ret_91; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsq_lane_f64(__p0_92, __p1_92, __p2_92, __p3_92) __extension__ ({ \
+  float64x2_t __s0_92 = __p0_92; \
+  float64x2_t __s1_92 = __p1_92; \
+  float64x1_t __s2_92 = __p2_92; \
+  float64x2_t __ret_92; \
+  __ret_92 = vfmaq_lane_f64(__s0_92, __s1_92, -__s2_92, __p3_92); \
+  __ret_92; \
+})
+#else
+#define vfmsq_lane_f64(__p0_93, __p1_93, __p2_93, __p3_93) __extension__ ({ \
+  float64x2_t __s0_93 = __p0_93; \
+  float64x2_t __s1_93 = __p1_93; \
+  float64x1_t __s2_93 = __p2_93; \
+  float64x2_t __rev0_93;  __rev0_93 = __builtin_shufflevector(__s0_93, __s0_93, 1, 0); \
+  float64x2_t __rev1_93;  __rev1_93 = __builtin_shufflevector(__s1_93, __s1_93, 1, 0); \
+  float64x2_t __ret_93; \
+  __ret_93 = __noswap_vfmaq_lane_f64(__rev0_93, __rev1_93, -__s2_93, __p3_93); \
+  __ret_93 = __builtin_shufflevector(__ret_93, __ret_93, 1, 0); \
+  __ret_93; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsq_lane_f32(__p0_94, __p1_94, __p2_94, __p3_94) __extension__ ({ \
+  float32x4_t __s0_94 = __p0_94; \
+  float32x4_t __s1_94 = __p1_94; \
+  float32x2_t __s2_94 = __p2_94; \
+  float32x4_t __ret_94; \
+  __ret_94 = vfmaq_lane_f32(__s0_94, __s1_94, -__s2_94, __p3_94); \
+  __ret_94; \
+})
+#else
+#define vfmsq_lane_f32(__p0_95, __p1_95, __p2_95, __p3_95) __extension__ ({ \
+  float32x4_t __s0_95 = __p0_95; \
+  float32x4_t __s1_95 = __p1_95; \
+  float32x2_t __s2_95 = __p2_95; \
+  float32x4_t __rev0_95;  __rev0_95 = __builtin_shufflevector(__s0_95, __s0_95, 3, 2, 1, 0); \
+  float32x4_t __rev1_95;  __rev1_95 = __builtin_shufflevector(__s1_95, __s1_95, 3, 2, 1, 0); \
+  float32x2_t __rev2_95;  __rev2_95 = __builtin_shufflevector(__s2_95, __s2_95, 1, 0); \
+  float32x4_t __ret_95; \
+  __ret_95 = __noswap_vfmaq_lane_f32(__rev0_95, __rev1_95, -__rev2_95, __p3_95); \
+  __ret_95 = __builtin_shufflevector(__ret_95, __ret_95, 3, 2, 1, 0); \
+  __ret_95; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfms_lane_f64(__p0_96, __p1_96, __p2_96, __p3_96) __extension__ ({ \
+  float64x1_t __s0_96 = __p0_96; \
+  float64x1_t __s1_96 = __p1_96; \
+  float64x1_t __s2_96 = __p2_96; \
+  float64x1_t __ret_96; \
+  __ret_96 = vfma_lane_f64(__s0_96, __s1_96, -__s2_96, __p3_96); \
+  __ret_96; \
+})
+#else
+#define vfms_lane_f64(__p0_97, __p1_97, __p2_97, __p3_97) __extension__ ({ \
+  float64x1_t __s0_97 = __p0_97; \
+  float64x1_t __s1_97 = __p1_97; \
+  float64x1_t __s2_97 = __p2_97; \
+  float64x1_t __ret_97; \
+  __ret_97 = __noswap_vfma_lane_f64(__s0_97, __s1_97, -__s2_97, __p3_97); \
+  __ret_97; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfms_lane_f32(__p0_98, __p1_98, __p2_98, __p3_98) __extension__ ({ \
+  float32x2_t __s0_98 = __p0_98; \
+  float32x2_t __s1_98 = __p1_98; \
+  float32x2_t __s2_98 = __p2_98; \
+  float32x2_t __ret_98; \
+  __ret_98 = vfma_lane_f32(__s0_98, __s1_98, -__s2_98, __p3_98); \
+  __ret_98; \
+})
+#else
+#define vfms_lane_f32(__p0_99, __p1_99, __p2_99, __p3_99) __extension__ ({ \
+  float32x2_t __s0_99 = __p0_99; \
+  float32x2_t __s1_99 = __p1_99; \
+  float32x2_t __s2_99 = __p2_99; \
+  float32x2_t __rev0_99;  __rev0_99 = __builtin_shufflevector(__s0_99, __s0_99, 1, 0); \
+  float32x2_t __rev1_99;  __rev1_99 = __builtin_shufflevector(__s1_99, __s1_99, 1, 0); \
+  float32x2_t __rev2_99;  __rev2_99 = __builtin_shufflevector(__s2_99, __s2_99, 1, 0); \
+  float32x2_t __ret_99; \
+  __ret_99 = __noswap_vfma_lane_f32(__rev0_99, __rev1_99, -__rev2_99, __p3_99); \
+  __ret_99 = __builtin_shufflevector(__ret_99, __ret_99, 1, 0); \
+  __ret_99; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsd_laneq_f64(__p0_100, __p1_100, __p2_100, __p3_100) __extension__ ({ \
+  float64_t __s0_100 = __p0_100; \
+  float64_t __s1_100 = __p1_100; \
+  float64x2_t __s2_100 = __p2_100; \
+  float64_t __ret_100; \
+  __ret_100 = vfmad_laneq_f64(__s0_100, __s1_100, -__s2_100, __p3_100); \
+  __ret_100; \
+})
+#else
+#define vfmsd_laneq_f64(__p0_101, __p1_101, __p2_101, __p3_101) __extension__ ({ \
+  float64_t __s0_101 = __p0_101; \
+  float64_t __s1_101 = __p1_101; \
+  float64x2_t __s2_101 = __p2_101; \
+  float64x2_t __rev2_101;  __rev2_101 = __builtin_shufflevector(__s2_101, __s2_101, 1, 0); \
+  float64_t __ret_101; \
+  __ret_101 = __noswap_vfmad_laneq_f64(__s0_101, __s1_101, -__rev2_101, __p3_101); \
+  __ret_101; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmss_laneq_f32(__p0_102, __p1_102, __p2_102, __p3_102) __extension__ ({ \
+  float32_t __s0_102 = __p0_102; \
+  float32_t __s1_102 = __p1_102; \
+  float32x4_t __s2_102 = __p2_102; \
+  float32_t __ret_102; \
+  __ret_102 = vfmas_laneq_f32(__s0_102, __s1_102, -__s2_102, __p3_102); \
+  __ret_102; \
+})
+#else
+#define vfmss_laneq_f32(__p0_103, __p1_103, __p2_103, __p3_103) __extension__ ({ \
+  float32_t __s0_103 = __p0_103; \
+  float32_t __s1_103 = __p1_103; \
+  float32x4_t __s2_103 = __p2_103; \
+  float32x4_t __rev2_103;  __rev2_103 = __builtin_shufflevector(__s2_103, __s2_103, 3, 2, 1, 0); \
+  float32_t __ret_103; \
+  __ret_103 = __noswap_vfmas_laneq_f32(__s0_103, __s1_103, -__rev2_103, __p3_103); \
+  __ret_103; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsq_laneq_f64(__p0_104, __p1_104, __p2_104, __p3_104) __extension__ ({ \
+  float64x2_t __s0_104 = __p0_104; \
+  float64x2_t __s1_104 = __p1_104; \
+  float64x2_t __s2_104 = __p2_104; \
+  float64x2_t __ret_104; \
+  __ret_104 = vfmaq_laneq_f64(__s0_104, __s1_104, -__s2_104, __p3_104); \
+  __ret_104; \
+})
+#else
+#define vfmsq_laneq_f64(__p0_105, __p1_105, __p2_105, __p3_105) __extension__ ({ \
+  float64x2_t __s0_105 = __p0_105; \
+  float64x2_t __s1_105 = __p1_105; \
+  float64x2_t __s2_105 = __p2_105; \
+  float64x2_t __rev0_105;  __rev0_105 = __builtin_shufflevector(__s0_105, __s0_105, 1, 0); \
+  float64x2_t __rev1_105;  __rev1_105 = __builtin_shufflevector(__s1_105, __s1_105, 1, 0); \
+  float64x2_t __rev2_105;  __rev2_105 = __builtin_shufflevector(__s2_105, __s2_105, 1, 0); \
+  float64x2_t __ret_105; \
+  __ret_105 = __noswap_vfmaq_laneq_f64(__rev0_105, __rev1_105, -__rev2_105, __p3_105); \
+  __ret_105 = __builtin_shufflevector(__ret_105, __ret_105, 1, 0); \
+  __ret_105; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfmsq_laneq_f32(__p0_106, __p1_106, __p2_106, __p3_106) __extension__ ({ \
+  float32x4_t __s0_106 = __p0_106; \
+  float32x4_t __s1_106 = __p1_106; \
+  float32x4_t __s2_106 = __p2_106; \
+  float32x4_t __ret_106; \
+  __ret_106 = vfmaq_laneq_f32(__s0_106, __s1_106, -__s2_106, __p3_106); \
+  __ret_106; \
+})
+#else
+#define vfmsq_laneq_f32(__p0_107, __p1_107, __p2_107, __p3_107) __extension__ ({ \
+  float32x4_t __s0_107 = __p0_107; \
+  float32x4_t __s1_107 = __p1_107; \
+  float32x4_t __s2_107 = __p2_107; \
+  float32x4_t __rev0_107;  __rev0_107 = __builtin_shufflevector(__s0_107, __s0_107, 3, 2, 1, 0); \
+  float32x4_t __rev1_107;  __rev1_107 = __builtin_shufflevector(__s1_107, __s1_107, 3, 2, 1, 0); \
+  float32x4_t __rev2_107;  __rev2_107 = __builtin_shufflevector(__s2_107, __s2_107, 3, 2, 1, 0); \
+  float32x4_t __ret_107; \
+  __ret_107 = __noswap_vfmaq_laneq_f32(__rev0_107, __rev1_107, -__rev2_107, __p3_107); \
+  __ret_107 = __builtin_shufflevector(__ret_107, __ret_107, 3, 2, 1, 0); \
+  __ret_107; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfms_laneq_f64(__p0_108, __p1_108, __p2_108, __p3_108) __extension__ ({ \
+  float64x1_t __s0_108 = __p0_108; \
+  float64x1_t __s1_108 = __p1_108; \
+  float64x2_t __s2_108 = __p2_108; \
+  float64x1_t __ret_108; \
+  __ret_108 = vfma_laneq_f64(__s0_108, __s1_108, -__s2_108, __p3_108); \
+  __ret_108; \
+})
+#else
+#define vfms_laneq_f64(__p0_109, __p1_109, __p2_109, __p3_109) __extension__ ({ \
+  float64x1_t __s0_109 = __p0_109; \
+  float64x1_t __s1_109 = __p1_109; \
+  float64x2_t __s2_109 = __p2_109; \
+  float64x2_t __rev2_109;  __rev2_109 = __builtin_shufflevector(__s2_109, __s2_109, 1, 0); \
+  float64x1_t __ret_109; \
+  __ret_109 = __noswap_vfma_laneq_f64(__s0_109, __s1_109, -__rev2_109, __p3_109); \
+  __ret_109; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vfms_laneq_f32(__p0_110, __p1_110, __p2_110, __p3_110) __extension__ ({ \
+  float32x2_t __s0_110 = __p0_110; \
+  float32x2_t __s1_110 = __p1_110; \
+  float32x4_t __s2_110 = __p2_110; \
+  float32x2_t __ret_110; \
+  __ret_110 = vfma_laneq_f32(__s0_110, __s1_110, -__s2_110, __p3_110); \
+  __ret_110; \
+})
+#else
+#define vfms_laneq_f32(__p0_111, __p1_111, __p2_111, __p3_111) __extension__ ({ \
+  float32x2_t __s0_111 = __p0_111; \
+  float32x2_t __s1_111 = __p1_111; \
+  float32x4_t __s2_111 = __p2_111; \
+  float32x2_t __rev0_111;  __rev0_111 = __builtin_shufflevector(__s0_111, __s0_111, 1, 0); \
+  float32x2_t __rev1_111;  __rev1_111 = __builtin_shufflevector(__s1_111, __s1_111, 1, 0); \
+  float32x4_t __rev2_111;  __rev2_111 = __builtin_shufflevector(__s2_111, __s2_111, 3, 2, 1, 0); \
+  float32x2_t __ret_111; \
+  __ret_111 = __noswap_vfma_laneq_f32(__rev0_111, __rev1_111, -__rev2_111, __p3_111); \
+  __ret_111 = __builtin_shufflevector(__ret_111, __ret_111, 1, 0); \
+  __ret_111; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vfmsq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __ret;
+  __ret = vfmsq_f64(__p0, __p1, (float64x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai float64x2_t vfmsq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __noswap_vfmsq_f64(__rev0, __rev1, (float64x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vfmsq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __ret;
+  __ret = vfmsq_f32(__p0, __p1, (float32x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai float32x4_t vfmsq_n_f32(float32x4_t __p0, float32x4_t __p1, float32_t __p2) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __noswap_vfmsq_f32(__rev0, __rev1, (float32x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vfms_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __ret;
+  __ret = vfms_f32(__p0, __p1, (float32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai float32x2_t vfms_n_f32(float32x2_t __p0, float32x2_t __p1, float32_t __p2) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __noswap_vfms_f32(__rev0, __rev1, (float32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vget_high_p64(poly64x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1);
+  return __ret;
+}
+#else
+__ai poly64x1_t vget_high_p64(poly64x2_t __p0) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1);
+  return __ret;
+}
+__ai poly64x1_t __noswap_vget_high_p64(poly64x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vget_high_f64(float64x2_t __p0) {
+  float64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 1);
+  return __ret;
+}
+#else
+__ai float64x1_t vget_high_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vget_lane_i64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64_t __ret; \
+  __ret = (poly64_t) __builtin_neon_vgetq_lane_i64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vgetq_lane_f64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vgetq_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vgetq_lane_f64((int8x16_t)__rev0, __p1); \
+  __ret; \
+})
+#define __noswap_vgetq_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vgetq_lane_f64((int8x16_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vget_lane_f64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#else
+#define vget_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vget_lane_f64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#define __noswap_vget_lane_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64_t __ret; \
+  __ret = (float64_t) __builtin_neon_vget_lane_f64((int8x8_t)__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vget_lane_f16(__p0_112, __p1_112) __extension__ ({ \
+  float16x4_t __s0_112 = __p0_112; \
+  float16_t __ret_112; \
+float16x4_t __reint_112 = __s0_112; \
+int16_t __reint1_112 = vget_lane_s16(*(int16x4_t *) &__reint_112, __p1_112); \
+  __ret_112 = *(float16_t *) &__reint1_112; \
+  __ret_112; \
+})
+#else
+#define vget_lane_f16(__p0_113, __p1_113) __extension__ ({ \
+  float16x4_t __s0_113 = __p0_113; \
+  float16x4_t __rev0_113;  __rev0_113 = __builtin_shufflevector(__s0_113, __s0_113, 3, 2, 1, 0); \
+  float16_t __ret_113; \
+float16x4_t __reint_113 = __rev0_113; \
+int16_t __reint1_113 = __noswap_vget_lane_s16(*(int16x4_t *) &__reint_113, __p1_113); \
+  __ret_113 = *(float16_t *) &__reint1_113; \
+  __ret_113; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vgetq_lane_f16(__p0_114, __p1_114) __extension__ ({ \
+  float16x8_t __s0_114 = __p0_114; \
+  float16_t __ret_114; \
+float16x8_t __reint_114 = __s0_114; \
+int16_t __reint1_114 = vgetq_lane_s16(*(int16x8_t *) &__reint_114, __p1_114); \
+  __ret_114 = *(float16_t *) &__reint1_114; \
+  __ret_114; \
+})
+#else
+#define vgetq_lane_f16(__p0_115, __p1_115) __extension__ ({ \
+  float16x8_t __s0_115 = __p0_115; \
+  float16x8_t __rev0_115;  __rev0_115 = __builtin_shufflevector(__s0_115, __s0_115, 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16_t __ret_115; \
+float16x8_t __reint_115 = __rev0_115; \
+int16_t __reint1_115 = __noswap_vgetq_lane_s16(*(int16x8_t *) &__reint_115, __p1_115); \
+  __ret_115 = *(float16_t *) &__reint1_115; \
+  __ret_115; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x1_t vget_low_p64(poly64x2_t __p0) {
+  poly64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0);
+  return __ret;
+}
+#else
+__ai poly64x1_t vget_low_p64(poly64x2_t __p0) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vget_low_f64(float64x2_t __p0) {
+  float64x1_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p0, 0);
+  return __ret;
+}
+#else
+__ai float64x1_t vget_low_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x1_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev0, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p64(__p0) __extension__ ({ \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_v(__p0, 6); \
+  __ret; \
+})
+#else
+#define vld1_p64(__p0) __extension__ ({ \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_v(__p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p64(__p0) __extension__ ({ \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_v(__p0, 38); \
+  __ret; \
+})
+#else
+#define vld1q_p64(__p0) __extension__ ({ \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_v(__p0, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f64(__p0) __extension__ ({ \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_v(__p0, 42); \
+  __ret; \
+})
+#else
+#define vld1q_f64(__p0) __extension__ ({ \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_v(__p0, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f64(__p0) __extension__ ({ \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_v(__p0, 10); \
+  __ret; \
+})
+#else
+#define vld1_f64(__p0) __extension__ ({ \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_v(__p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_p64(__p0) __extension__ ({ \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_dup_v(__p0, 6); \
+  __ret; \
+})
+#else
+#define vld1_dup_p64(__p0) __extension__ ({ \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_dup_v(__p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_p64(__p0) __extension__ ({ \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_dup_v(__p0, 38); \
+  __ret; \
+})
+#else
+#define vld1q_dup_p64(__p0) __extension__ ({ \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_dup_v(__p0, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_dup_f64(__p0) __extension__ ({ \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_dup_v(__p0, 42); \
+  __ret; \
+})
+#else
+#define vld1q_dup_f64(__p0) __extension__ ({ \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_dup_v(__p0, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_dup_f64(__p0) __extension__ ({ \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_dup_v(__p0, 10); \
+  __ret; \
+})
+#else
+#define vld1_dup_f64(__p0) __extension__ ({ \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_dup_v(__p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#else
+#define vld1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 38); \
+  __ret; \
+})
+#else
+#define vld1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__s1, __p2, 42); \
+  __ret; \
+})
+#else
+#define vld1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vld1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 42); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#else
+#define vld1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vld1_lane_v(__p0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p8_x2(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld1_p8_x2(__p0) __extension__ ({ \
+  poly8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p64_x2(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld1_p64_x2(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p16_x2(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld1_p16_x2(__p0) __extension__ ({ \
+  poly16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p8_x2(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld1q_p8_x2(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p64_x2(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld1q_p64_x2(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p16_x2(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld1q_p16_x2(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u8_x2(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld1q_u8_x2(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u32_x2(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld1q_u32_x2(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u64_x2(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld1q_u64_x2(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u16_x2(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld1q_u16_x2(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s8_x2(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld1q_s8_x2(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f64_x2(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld1q_f64_x2(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f32_x2(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld1q_f32_x2(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f16_x2(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld1q_f16_x2(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s32_x2(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld1q_s32_x2(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s64_x2(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld1q_s64_x2(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s16_x2(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld1q_s16_x2(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld1q_x2_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u8_x2(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld1_u8_x2(__p0) __extension__ ({ \
+  uint8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u32_x2(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld1_u32_x2(__p0) __extension__ ({ \
+  uint32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u64_x2(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld1_u64_x2(__p0) __extension__ ({ \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u16_x2(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld1_u16_x2(__p0) __extension__ ({ \
+  uint16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s8_x2(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld1_s8_x2(__p0) __extension__ ({ \
+  int8x8x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f64_x2(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld1_f64_x2(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f32_x2(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld1_f32_x2(__p0) __extension__ ({ \
+  float32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f16_x2(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld1_f16_x2(__p0) __extension__ ({ \
+  float16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s32_x2(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld1_s32_x2(__p0) __extension__ ({ \
+  int32x2x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s64_x2(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld1_s64_x2(__p0) __extension__ ({ \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s16_x2(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld1_s16_x2(__p0) __extension__ ({ \
+  int16x4x2_t __ret; \
+  __builtin_neon_vld1_x2_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p8_x3(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld1_p8_x3(__p0) __extension__ ({ \
+  poly8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p64_x3(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld1_p64_x3(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p16_x3(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld1_p16_x3(__p0) __extension__ ({ \
+  poly16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p8_x3(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld1q_p8_x3(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p64_x3(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld1q_p64_x3(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p16_x3(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld1q_p16_x3(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u8_x3(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld1q_u8_x3(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u32_x3(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld1q_u32_x3(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u64_x3(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld1q_u64_x3(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u16_x3(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld1q_u16_x3(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s8_x3(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld1q_s8_x3(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f64_x3(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld1q_f64_x3(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f32_x3(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld1q_f32_x3(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f16_x3(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld1q_f16_x3(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s32_x3(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld1q_s32_x3(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s64_x3(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld1q_s64_x3(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s16_x3(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld1q_s16_x3(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld1q_x3_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u8_x3(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld1_u8_x3(__p0) __extension__ ({ \
+  uint8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u32_x3(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld1_u32_x3(__p0) __extension__ ({ \
+  uint32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u64_x3(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld1_u64_x3(__p0) __extension__ ({ \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u16_x3(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld1_u16_x3(__p0) __extension__ ({ \
+  uint16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s8_x3(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld1_s8_x3(__p0) __extension__ ({ \
+  int8x8x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f64_x3(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld1_f64_x3(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f32_x3(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld1_f32_x3(__p0) __extension__ ({ \
+  float32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f16_x3(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld1_f16_x3(__p0) __extension__ ({ \
+  float16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s32_x3(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld1_s32_x3(__p0) __extension__ ({ \
+  int32x2x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s64_x3(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld1_s64_x3(__p0) __extension__ ({ \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s16_x3(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld1_s16_x3(__p0) __extension__ ({ \
+  int16x4x3_t __ret; \
+  __builtin_neon_vld1_x3_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p8_x4(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 4); \
+  __ret; \
+})
+#else
+#define vld1_p8_x4(__p0) __extension__ ({ \
+  poly8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 4); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p64_x4(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld1_p64_x4(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_p16_x4(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 5); \
+  __ret; \
+})
+#else
+#define vld1_p16_x4(__p0) __extension__ ({ \
+  poly16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 5); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p8_x4(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld1q_p8_x4(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p64_x4(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld1q_p64_x4(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_p16_x4(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld1q_p16_x4(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u8_x4(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld1q_u8_x4(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u32_x4(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld1q_u32_x4(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u64_x4(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld1q_u64_x4(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_u16_x4(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld1q_u16_x4(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s8_x4(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld1q_s8_x4(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f64_x4(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld1q_f64_x4(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f32_x4(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld1q_f32_x4(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_f16_x4(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld1q_f16_x4(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s32_x4(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld1q_s32_x4(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s64_x4(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld1q_s64_x4(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1q_s16_x4(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld1q_s16_x4(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld1q_x4_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u8_x4(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 16); \
+  __ret; \
+})
+#else
+#define vld1_u8_x4(__p0) __extension__ ({ \
+  uint8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 16); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u32_x4(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 18); \
+  __ret; \
+})
+#else
+#define vld1_u32_x4(__p0) __extension__ ({ \
+  uint32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 18); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u64_x4(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#else
+#define vld1_u64_x4(__p0) __extension__ ({ \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_u16_x4(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 17); \
+  __ret; \
+})
+#else
+#define vld1_u16_x4(__p0) __extension__ ({ \
+  uint16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 17); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s8_x4(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 0); \
+  __ret; \
+})
+#else
+#define vld1_s8_x4(__p0) __extension__ ({ \
+  int8x8x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 0); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f64_x4(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld1_f64_x4(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f32_x4(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 9); \
+  __ret; \
+})
+#else
+#define vld1_f32_x4(__p0) __extension__ ({ \
+  float32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 9); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_f16_x4(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 8); \
+  __ret; \
+})
+#else
+#define vld1_f16_x4(__p0) __extension__ ({ \
+  float16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 8); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s32_x4(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 2); \
+  __ret; \
+})
+#else
+#define vld1_s32_x4(__p0) __extension__ ({ \
+  int32x2x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 2); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s64_x4(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#else
+#define vld1_s64_x4(__p0) __extension__ ({ \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld1_s16_x4(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 1); \
+  __ret; \
+})
+#else
+#define vld1_s16_x4(__p0) __extension__ ({ \
+  int16x4x4_t __ret; \
+  __builtin_neon_vld1_x4_v(&__ret, __p0, 1); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_p64(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld2_p64(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_p64(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld2q_p64(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_u64(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld2q_u64(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_f64(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld2q_f64(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_s64(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld2q_s64(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_f64(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld2_f64(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_p64(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld2_dup_p64(__p0) __extension__ ({ \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld2q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld2q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld2q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld2q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld2q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld2q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld2q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_s8(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld2q_dup_s8(__p0) __extension__ ({ \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_f64(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld2q_dup_f64(__p0) __extension__ ({ \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_f32(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld2q_dup_f32(__p0) __extension__ ({ \
+  float32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_f16(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld2q_dup_f16(__p0) __extension__ ({ \
+  float16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_s32(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld2q_dup_s32(__p0) __extension__ ({ \
+  int32x4x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_s64(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld2q_dup_s64(__p0) __extension__ ({ \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_dup_s16(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld2q_dup_s16(__p0) __extension__ ({ \
+  int16x8x2_t __ret; \
+  __builtin_neon_vld2q_dup_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_dup_f64(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld2_dup_f64(__p0) __extension__ ({ \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 6); \
+  __ret; \
+})
+#else
+#define vld2_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  poly64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 36); \
+  __ret; \
+})
+#else
+#define vld2q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  poly8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 38); \
+  __ret; \
+})
+#else
+#define vld2q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  poly64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  poly64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 48); \
+  __ret; \
+})
+#else
+#define vld2q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  uint8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 51); \
+  __ret; \
+})
+#else
+#define vld2q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  uint64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  uint64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 32); \
+  __ret; \
+})
+#else
+#define vld2q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  int8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 42); \
+  __ret; \
+})
+#else
+#define vld2q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  float64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  float64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 35); \
+  __ret; \
+})
+#else
+#define vld2q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  int64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  int64x2x2_t __ret; \
+  __builtin_neon_vld2q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __p2, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 19); \
+  __ret; \
+})
+#else
+#define vld2_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  uint64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 10); \
+  __ret; \
+})
+#else
+#define vld2_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  float64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld2_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 3); \
+  __ret; \
+})
+#else
+#define vld2_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  int64x1x2_t __ret; \
+  __builtin_neon_vld2_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_p64(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld3_p64(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_p64(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld3q_p64(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_u64(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld3q_u64(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_f64(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld3q_f64(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_s64(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld3q_s64(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_f64(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld3_f64(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_p64(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld3_dup_p64(__p0) __extension__ ({ \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld3q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld3q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld3q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld3q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld3q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld3q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld3q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_s8(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld3q_dup_s8(__p0) __extension__ ({ \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_f64(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld3q_dup_f64(__p0) __extension__ ({ \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_f32(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld3q_dup_f32(__p0) __extension__ ({ \
+  float32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_f16(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld3q_dup_f16(__p0) __extension__ ({ \
+  float16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_s32(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld3q_dup_s32(__p0) __extension__ ({ \
+  int32x4x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_s64(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld3q_dup_s64(__p0) __extension__ ({ \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_dup_s16(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld3q_dup_s16(__p0) __extension__ ({ \
+  int16x8x3_t __ret; \
+  __builtin_neon_vld3q_dup_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_dup_f64(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld3_dup_f64(__p0) __extension__ ({ \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 6); \
+  __ret; \
+})
+#else
+#define vld3_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  poly64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 36); \
+  __ret; \
+})
+#else
+#define vld3q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  poly8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 38); \
+  __ret; \
+})
+#else
+#define vld3q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  poly64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  poly64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 48); \
+  __ret; \
+})
+#else
+#define vld3q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  uint8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 51); \
+  __ret; \
+})
+#else
+#define vld3q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  uint64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  uint64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 32); \
+  __ret; \
+})
+#else
+#define vld3q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  int8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 42); \
+  __ret; \
+})
+#else
+#define vld3q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  float64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  float64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 35); \
+  __ret; \
+})
+#else
+#define vld3q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  int64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  int64x2x3_t __ret; \
+  __builtin_neon_vld3q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 19); \
+  __ret; \
+})
+#else
+#define vld3_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  uint64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 10); \
+  __ret; \
+})
+#else
+#define vld3_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  float64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld3_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 3); \
+  __ret; \
+})
+#else
+#define vld3_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  int64x1x3_t __ret; \
+  __builtin_neon_vld3_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_p64(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld4_p64(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_p64(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld4q_p64(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_u64(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld4q_u64(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_f64(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld4q_f64(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_s64(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld4q_s64(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_f64(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld4_f64(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_p64(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#else
+#define vld4_dup_p64(__p0) __extension__ ({ \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 36); \
+  __ret; \
+})
+#else
+#define vld4q_dup_p8(__p0) __extension__ ({ \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 38); \
+  __ret; \
+})
+#else
+#define vld4q_dup_p64(__p0) __extension__ ({ \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 37); \
+  __ret; \
+})
+#else
+#define vld4q_dup_p16(__p0) __extension__ ({ \
+  poly16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 37); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 48); \
+  __ret; \
+})
+#else
+#define vld4q_dup_u8(__p0) __extension__ ({ \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 50); \
+  __ret; \
+})
+#else
+#define vld4q_dup_u32(__p0) __extension__ ({ \
+  uint32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 50); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 51); \
+  __ret; \
+})
+#else
+#define vld4q_dup_u64(__p0) __extension__ ({ \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 49); \
+  __ret; \
+})
+#else
+#define vld4q_dup_u16(__p0) __extension__ ({ \
+  uint16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 49); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_s8(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 32); \
+  __ret; \
+})
+#else
+#define vld4q_dup_s8(__p0) __extension__ ({ \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_f64(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 42); \
+  __ret; \
+})
+#else
+#define vld4q_dup_f64(__p0) __extension__ ({ \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_f32(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 41); \
+  __ret; \
+})
+#else
+#define vld4q_dup_f32(__p0) __extension__ ({ \
+  float32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 41); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_f16(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 40); \
+  __ret; \
+})
+#else
+#define vld4q_dup_f16(__p0) __extension__ ({ \
+  float16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 40); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_s32(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 34); \
+  __ret; \
+})
+#else
+#define vld4q_dup_s32(__p0) __extension__ ({ \
+  int32x4x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 34); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_s64(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 35); \
+  __ret; \
+})
+#else
+#define vld4q_dup_s64(__p0) __extension__ ({ \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_dup_s16(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 33); \
+  __ret; \
+})
+#else
+#define vld4q_dup_s16(__p0) __extension__ ({ \
+  int16x8x4_t __ret; \
+  __builtin_neon_vld4q_dup_v(&__ret, __p0, 33); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_dup_f64(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#else
+#define vld4_dup_f64(__p0) __extension__ ({ \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_dup_v(&__ret, __p0, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 6); \
+  __ret; \
+})
+#else
+#define vld4_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  poly64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 36); \
+  __ret; \
+})
+#else
+#define vld4q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  poly8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  poly8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 36); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 38); \
+  __ret; \
+})
+#else
+#define vld4q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  poly64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  poly64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 38); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 48); \
+  __ret; \
+})
+#else
+#define vld4q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  uint8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 48); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 51); \
+  __ret; \
+})
+#else
+#define vld4q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  uint64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  uint64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 51); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 32); \
+  __ret; \
+})
+#else
+#define vld4q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  int8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 32); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 42); \
+  __ret; \
+})
+#else
+#define vld4q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  float64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  float64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 42); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 35); \
+  __ret; \
+})
+#else
+#define vld4q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  int64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  int64x2x4_t __ret; \
+  __builtin_neon_vld4q_lane_v(&__ret, __p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 35); \
+ \
+  __ret.val[0] = __builtin_shufflevector(__ret.val[0], __ret.val[0], 1, 0); \
+  __ret.val[1] = __builtin_shufflevector(__ret.val[1], __ret.val[1], 1, 0); \
+  __ret.val[2] = __builtin_shufflevector(__ret.val[2], __ret.val[2], 1, 0); \
+  __ret.val[3] = __builtin_shufflevector(__ret.val[3], __ret.val[3], 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 19); \
+  __ret; \
+})
+#else
+#define vld4_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  uint64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 19); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 10); \
+  __ret; \
+})
+#else
+#define vld4_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  float64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vld4_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 3); \
+  __ret; \
+})
+#else
+#define vld4_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  int64x1x4_t __ret; \
+  __builtin_neon_vld4_lane_v(&__ret, __p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vldrq_p128(__p0) __extension__ ({ \
+  poly128_t __ret; \
+  __ret = (poly128_t) __builtin_neon_vldrq_p128(__p0); \
+  __ret; \
+})
+#else
+#define vldrq_p128(__p0) __extension__ ({ \
+  poly128_t __ret; \
+  __ret = (poly128_t) __builtin_neon_vldrq_p128(__p0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmaxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vmaxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmax_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vmax_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmax_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmaxnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vmaxnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmaxnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vmaxnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmaxnm_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vmaxnm_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmaxnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vmaxnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmaxnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vmaxnmvq_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmaxnmvq_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vmaxnmvq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmaxnmvq_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vmaxnmvq_f32(float32x4_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxnmvq_f32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vmaxnmvq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxnmvq_f32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vmaxnmv_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxnmv_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vmaxnmv_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxnmv_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vmaxvq_u8(uint8x16_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vmaxvq_u8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vmaxvq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vmaxvq_u8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vmaxvq_u32(uint32x4_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vmaxvq_u32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vmaxvq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vmaxvq_u32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vmaxvq_u16(uint16x8_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vmaxvq_u16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vmaxvq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vmaxvq_u16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vmaxvq_s8(int8x16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vmaxvq_s8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vmaxvq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vmaxvq_s8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vmaxvq_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmaxvq_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vmaxvq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmaxvq_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vmaxvq_f32(float32x4_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxvq_f32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vmaxvq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxvq_f32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vmaxvq_s32(int32x4_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vmaxvq_s32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vmaxvq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vmaxvq_s32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vmaxvq_s16(int16x8_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vmaxvq_s16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vmaxvq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vmaxvq_s16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vmaxv_u8(uint8x8_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vmaxv_u8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vmaxv_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vmaxv_u8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vmaxv_u32(uint32x2_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vmaxv_u32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vmaxv_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vmaxv_u32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vmaxv_u16(uint16x4_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vmaxv_u16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vmaxv_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vmaxv_u16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vmaxv_s8(int8x8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vmaxv_s8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vmaxv_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vmaxv_s8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vmaxv_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxv_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vmaxv_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmaxv_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vmaxv_s32(int32x2_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vmaxv_s32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vmaxv_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vmaxv_s32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vmaxv_s16(int16x4_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vmaxv_s16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vmaxv_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vmaxv_s16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vminq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vminq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vminq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmin_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vmin_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmin_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vminnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vminnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vminnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vminnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vminnm_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vminnm_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vminnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vminnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vminnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vminnmvq_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vminnmvq_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vminnmvq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vminnmvq_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vminnmvq_f32(float32x4_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminnmvq_f32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vminnmvq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminnmvq_f32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vminnmv_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminnmv_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vminnmv_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminnmv_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vminvq_u8(uint8x16_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vminvq_u8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vminvq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vminvq_u8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vminvq_u32(uint32x4_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vminvq_u32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vminvq_u32(uint32x4_t __p0) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vminvq_u32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vminvq_u16(uint16x8_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vminvq_u16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vminvq_u16(uint16x8_t __p0) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vminvq_u16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vminvq_s8(int8x16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vminvq_s8((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vminvq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vminvq_s8((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vminvq_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vminvq_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vminvq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vminvq_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vminvq_f32(float32x4_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminvq_f32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vminvq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminvq_f32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vminvq_s32(int32x4_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vminvq_s32((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vminvq_s32(int32x4_t __p0) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vminvq_s32((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vminvq_s16(int16x8_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vminvq_s16((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vminvq_s16(int16x8_t __p0) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vminvq_s16((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vminv_u8(uint8x8_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vminv_u8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vminv_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vminv_u8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vminv_u32(uint32x2_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vminv_u32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vminv_u32(uint32x2_t __p0) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vminv_u32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vminv_u16(uint16x4_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vminv_u16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vminv_u16(uint16x4_t __p0) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vminv_u16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vminv_s8(int8x8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vminv_s8((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int8_t vminv_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vminv_s8((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vminv_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminv_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vminv_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vminv_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vminv_s32(int32x2_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vminv_s32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int32_t vminv_s32(int32x2_t __p0) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vminv_s32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vminv_s16(int16x4_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vminv_s16((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai int16_t vminv_s16(int16x4_t __p0) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vminv_s16((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmlaq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float64x2_t vmlaq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 + __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmla_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float64x1_t vmla_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = __p0 + __p1 * __p2;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x8_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlaq_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlaq_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x2_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmla_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x4_t __ret; \
+  __ret = __s0 + __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmla_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 + __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmlaq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __ret;
+  __ret = __p0 + __p1 * (float64x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai float64x2_t vmlaq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 + __rev1 * (float64x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 + vmull_u32(vget_high_u32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u32(__noswap_vget_high_u32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + vmull_u16(vget_high_u16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u16(__noswap_vget_high_u16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 + vmull_s32(vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s32(__noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + vmull_s16(vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s16(__noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 + vmull_u32(vget_high_u32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u32(__noswap_vget_high_u32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + vmull_u16(vget_high_u16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u16(__noswap_vget_high_u16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 + vmull_s32(vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s32(__noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + vmull_s16(vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s16(__noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 + vmull_u32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + vmull_u16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 + vmull_s32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + vmull_s16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmlsq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float64x2_t vmlsq_f64(float64x2_t __p0, float64x2_t __p1, float64x2_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 - __rev1 * __rev2;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmls_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#else
+__ai float64x1_t vmls_f64(float64x1_t __p0, float64x1_t __p1, float64x1_t __p2) {
+  float64x1_t __ret;
+  __ret = __p0 - __p1 * __p2;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x8_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsq_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmlsq_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_laneq_f32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __s2 = __p2; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x2_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmls_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x4_t __ret; \
+  __ret = __s0 - __s1 * __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3); \
+  __ret; \
+})
+#else
+#define vmls_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 - __rev1 * __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmlsq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __ret;
+  __ret = __p0 - __p1 * (float64x2_t) {__p2, __p2};
+  return __ret;
+}
+#else
+__ai float64x2_t vmlsq_n_f64(float64x2_t __p0, float64x2_t __p1, float64_t __p2) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 - __rev1 * (float64x2_t) {__p2, __p2};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 - vmull_u32(vget_high_u32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u32(__noswap_vget_high_u32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - vmull_u16(vget_high_u16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u16(__noswap_vget_high_u16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 - vmull_s32(vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s32(__noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - vmull_s16(vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s16(__noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 - vmull_u32(vget_high_u32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u32(__noswap_vget_high_u32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - vmull_u16(vget_high_u16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u16(__noswap_vget_high_u16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 - vmull_s32(vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s32(__noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - vmull_s16(vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s16(__noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 - vmull_u32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_laneq_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - vmull_u16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_laneq_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 - vmull_s32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - vmull_s16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmovq_n_f64(float64_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) {__p0, __p0};
+  return __ret;
+}
+#else
+__ai float64x2_t vmovq_n_f64(float64_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) {__p0, __p0};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmov_n_f64(float64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) {__p0};
+  return __ret;
+}
+#else
+__ai float64x1_t vmov_n_f64(float64_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) {__p0};
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_116) {
+  uint16x8_t __ret_116;
+  uint8x8_t __a1_116 = vget_high_u8(__p0_116);
+  __ret_116 = (uint16x8_t)(vshll_n_u8(__a1_116, 0));
+  return __ret_116;
+}
+#else
+__ai uint16x8_t vmovl_high_u8(uint8x16_t __p0_117) {
+  uint8x16_t __rev0_117;  __rev0_117 = __builtin_shufflevector(__p0_117, __p0_117, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret_117;
+  uint8x8_t __a1_117 = __noswap_vget_high_u8(__rev0_117);
+  __ret_117 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_117, 0));
+  __ret_117 = __builtin_shufflevector(__ret_117, __ret_117, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret_117;
+}
+__ai uint16x8_t __noswap_vmovl_high_u8(uint8x16_t __p0_118) {
+  uint16x8_t __ret_118;
+  uint8x8_t __a1_118 = __noswap_vget_high_u8(__p0_118);
+  __ret_118 = (uint16x8_t)(__noswap_vshll_n_u8(__a1_118, 0));
+  return __ret_118;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_119) {
+  uint64x2_t __ret_119;
+  uint32x2_t __a1_119 = vget_high_u32(__p0_119);
+  __ret_119 = (uint64x2_t)(vshll_n_u32(__a1_119, 0));
+  return __ret_119;
+}
+#else
+__ai uint64x2_t vmovl_high_u32(uint32x4_t __p0_120) {
+  uint32x4_t __rev0_120;  __rev0_120 = __builtin_shufflevector(__p0_120, __p0_120, 3, 2, 1, 0);
+  uint64x2_t __ret_120;
+  uint32x2_t __a1_120 = __noswap_vget_high_u32(__rev0_120);
+  __ret_120 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_120, 0));
+  __ret_120 = __builtin_shufflevector(__ret_120, __ret_120, 1, 0);
+  return __ret_120;
+}
+__ai uint64x2_t __noswap_vmovl_high_u32(uint32x4_t __p0_121) {
+  uint64x2_t __ret_121;
+  uint32x2_t __a1_121 = __noswap_vget_high_u32(__p0_121);
+  __ret_121 = (uint64x2_t)(__noswap_vshll_n_u32(__a1_121, 0));
+  return __ret_121;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_122) {
+  uint32x4_t __ret_122;
+  uint16x4_t __a1_122 = vget_high_u16(__p0_122);
+  __ret_122 = (uint32x4_t)(vshll_n_u16(__a1_122, 0));
+  return __ret_122;
+}
+#else
+__ai uint32x4_t vmovl_high_u16(uint16x8_t __p0_123) {
+  uint16x8_t __rev0_123;  __rev0_123 = __builtin_shufflevector(__p0_123, __p0_123, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret_123;
+  uint16x4_t __a1_123 = __noswap_vget_high_u16(__rev0_123);
+  __ret_123 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_123, 0));
+  __ret_123 = __builtin_shufflevector(__ret_123, __ret_123, 3, 2, 1, 0);
+  return __ret_123;
+}
+__ai uint32x4_t __noswap_vmovl_high_u16(uint16x8_t __p0_124) {
+  uint32x4_t __ret_124;
+  uint16x4_t __a1_124 = __noswap_vget_high_u16(__p0_124);
+  __ret_124 = (uint32x4_t)(__noswap_vshll_n_u16(__a1_124, 0));
+  return __ret_124;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmovl_high_s8(int8x16_t __p0_125) {
+  int16x8_t __ret_125;
+  int8x8_t __a1_125 = vget_high_s8(__p0_125);
+  __ret_125 = (int16x8_t)(vshll_n_s8(__a1_125, 0));
+  return __ret_125;
+}
+#else
+__ai int16x8_t vmovl_high_s8(int8x16_t __p0_126) {
+  int8x16_t __rev0_126;  __rev0_126 = __builtin_shufflevector(__p0_126, __p0_126, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret_126;
+  int8x8_t __a1_126 = __noswap_vget_high_s8(__rev0_126);
+  __ret_126 = (int16x8_t)(__noswap_vshll_n_s8(__a1_126, 0));
+  __ret_126 = __builtin_shufflevector(__ret_126, __ret_126, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret_126;
+}
+__ai int16x8_t __noswap_vmovl_high_s8(int8x16_t __p0_127) {
+  int16x8_t __ret_127;
+  int8x8_t __a1_127 = __noswap_vget_high_s8(__p0_127);
+  __ret_127 = (int16x8_t)(__noswap_vshll_n_s8(__a1_127, 0));
+  return __ret_127;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmovl_high_s32(int32x4_t __p0_128) {
+  int64x2_t __ret_128;
+  int32x2_t __a1_128 = vget_high_s32(__p0_128);
+  __ret_128 = (int64x2_t)(vshll_n_s32(__a1_128, 0));
+  return __ret_128;
+}
+#else
+__ai int64x2_t vmovl_high_s32(int32x4_t __p0_129) {
+  int32x4_t __rev0_129;  __rev0_129 = __builtin_shufflevector(__p0_129, __p0_129, 3, 2, 1, 0);
+  int64x2_t __ret_129;
+  int32x2_t __a1_129 = __noswap_vget_high_s32(__rev0_129);
+  __ret_129 = (int64x2_t)(__noswap_vshll_n_s32(__a1_129, 0));
+  __ret_129 = __builtin_shufflevector(__ret_129, __ret_129, 1, 0);
+  return __ret_129;
+}
+__ai int64x2_t __noswap_vmovl_high_s32(int32x4_t __p0_130) {
+  int64x2_t __ret_130;
+  int32x2_t __a1_130 = __noswap_vget_high_s32(__p0_130);
+  __ret_130 = (int64x2_t)(__noswap_vshll_n_s32(__a1_130, 0));
+  return __ret_130;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmovl_high_s16(int16x8_t __p0_131) {
+  int32x4_t __ret_131;
+  int16x4_t __a1_131 = vget_high_s16(__p0_131);
+  __ret_131 = (int32x4_t)(vshll_n_s16(__a1_131, 0));
+  return __ret_131;
+}
+#else
+__ai int32x4_t vmovl_high_s16(int16x8_t __p0_132) {
+  int16x8_t __rev0_132;  __rev0_132 = __builtin_shufflevector(__p0_132, __p0_132, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret_132;
+  int16x4_t __a1_132 = __noswap_vget_high_s16(__rev0_132);
+  __ret_132 = (int32x4_t)(__noswap_vshll_n_s16(__a1_132, 0));
+  __ret_132 = __builtin_shufflevector(__ret_132, __ret_132, 3, 2, 1, 0);
+  return __ret_132;
+}
+__ai int32x4_t __noswap_vmovl_high_s16(int16x8_t __p0_133) {
+  int32x4_t __ret_133;
+  int16x4_t __a1_133 = __noswap_vget_high_s16(__p0_133);
+  __ret_133 = (int32x4_t)(__noswap_vshll_n_s16(__a1_133, 0));
+  return __ret_133;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmovn_high_u32(uint16x4_t __p0, uint32x4_t __p1) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vmovn_u32(__p1));
+  return __ret;
+}
+#else
+__ai uint16x8_t vmovn_high_u32(uint16x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vmovn_u32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmovn_high_u64(uint32x2_t __p0, uint64x2_t __p1) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vmovn_u64(__p1));
+  return __ret;
+}
+#else
+__ai uint32x4_t vmovn_high_u64(uint32x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vmovn_u64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vmovn_high_u16(uint8x8_t __p0, uint16x8_t __p1) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vmovn_u16(__p1));
+  return __ret;
+}
+#else
+__ai uint8x16_t vmovn_high_u16(uint8x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vmovn_u16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmovn_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vmovn_s32(__p1));
+  return __ret;
+}
+#else
+__ai int16x8_t vmovn_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vmovn_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmovn_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vmovn_s64(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vmovn_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vmovn_s64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vmovn_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vmovn_s16(__p1));
+  return __ret;
+}
+#else
+__ai int8x16_t vmovn_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vmovn_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmulq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai float64x2_t vmulq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 * __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmul_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#else
+__ai float64x1_t vmul_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 * __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmuld_lane_f64(__p0_134, __p1_134, __p2_134) __extension__ ({ \
+  float64_t __s0_134 = __p0_134; \
+  float64x1_t __s1_134 = __p1_134; \
+  float64_t __ret_134; \
+  __ret_134 = __s0_134 * vget_lane_f64(__s1_134, __p2_134); \
+  __ret_134; \
+})
+#else
+#define vmuld_lane_f64(__p0_135, __p1_135, __p2_135) __extension__ ({ \
+  float64_t __s0_135 = __p0_135; \
+  float64x1_t __s1_135 = __p1_135; \
+  float64_t __ret_135; \
+  __ret_135 = __s0_135 * __noswap_vget_lane_f64(__s1_135, __p2_135); \
+  __ret_135; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmuls_lane_f32(__p0_136, __p1_136, __p2_136) __extension__ ({ \
+  float32_t __s0_136 = __p0_136; \
+  float32x2_t __s1_136 = __p1_136; \
+  float32_t __ret_136; \
+  __ret_136 = __s0_136 * vget_lane_f32(__s1_136, __p2_136); \
+  __ret_136; \
+})
+#else
+#define vmuls_lane_f32(__p0_137, __p1_137, __p2_137) __extension__ ({ \
+  float32_t __s0_137 = __p0_137; \
+  float32x2_t __s1_137 = __p1_137; \
+  float32x2_t __rev1_137;  __rev1_137 = __builtin_shufflevector(__s1_137, __s1_137, 1, 0); \
+  float32_t __ret_137; \
+  __ret_137 = __s0_137 * __noswap_vget_lane_f32(__rev1_137, __p2_137); \
+  __ret_137; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vmul_lane_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#else
+#define vmul_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vmul_lane_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmuld_laneq_f64(__p0_138, __p1_138, __p2_138) __extension__ ({ \
+  float64_t __s0_138 = __p0_138; \
+  float64x2_t __s1_138 = __p1_138; \
+  float64_t __ret_138; \
+  __ret_138 = __s0_138 * vgetq_lane_f64(__s1_138, __p2_138); \
+  __ret_138; \
+})
+#else
+#define vmuld_laneq_f64(__p0_139, __p1_139, __p2_139) __extension__ ({ \
+  float64_t __s0_139 = __p0_139; \
+  float64x2_t __s1_139 = __p1_139; \
+  float64x2_t __rev1_139;  __rev1_139 = __builtin_shufflevector(__s1_139, __s1_139, 1, 0); \
+  float64_t __ret_139; \
+  __ret_139 = __s0_139 * __noswap_vgetq_lane_f64(__rev1_139, __p2_139); \
+  __ret_139; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmuls_laneq_f32(__p0_140, __p1_140, __p2_140) __extension__ ({ \
+  float32_t __s0_140 = __p0_140; \
+  float32x4_t __s1_140 = __p1_140; \
+  float32_t __ret_140; \
+  __ret_140 = __s0_140 * vgetq_lane_f32(__s1_140, __p2_140); \
+  __ret_140; \
+})
+#else
+#define vmuls_laneq_f32(__p0_141, __p1_141, __p2_141) __extension__ ({ \
+  float32_t __s0_141 = __p0_141; \
+  float32x4_t __s1_141 = __p1_141; \
+  float32x4_t __rev1_141;  __rev1_141 = __builtin_shufflevector(__s1_141, __s1_141, 3, 2, 1, 0); \
+  float32_t __ret_141; \
+  __ret_141 = __s0_141 * __noswap_vgetq_lane_f32(__rev1_141, __p2_141); \
+  __ret_141; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vmul_laneq_v((int8x8_t)__s0, (int8x16_t)__s1, __p2, 10); \
+  __ret; \
+})
+#else
+#define vmul_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vmul_laneq_v((int8x8_t)__s0, (int8x16_t)__rev1, __p2, 10); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmulq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmul_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = __s0 * __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2); \
+  __ret; \
+})
+#else
+#define vmul_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __rev0 * __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmul_n_f64(float64x1_t __p0, float64_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmul_n_f64((int8x8_t)__p0, __p1);
+  return __ret;
+}
+#else
+__ai float64x1_t vmul_n_f64(float64x1_t __p0, float64_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmul_n_f64((int8x8_t)__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmulq_n_f64(float64x2_t __p0, float64_t __p1) {
+  float64x2_t __ret;
+  __ret = __p0 * (float64x2_t) {__p1, __p1};
+  return __ret;
+}
+#else
+__ai float64x2_t vmulq_n_f64(float64x2_t __p0, float64_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 * (float64x2_t) {__p1, __p1};
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vmull_p64(poly64_t __p0, poly64_t __p1) {
+  poly128_t __ret;
+  __ret = (poly128_t) __builtin_neon_vmull_p64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai poly128_t vmull_p64(poly64_t __p0, poly64_t __p1) {
+  poly128_t __ret;
+  __ret = (poly128_t) __builtin_neon_vmull_p64(__p0, __p1);
+  return __ret;
+}
+__ai poly128_t __noswap_vmull_p64(poly64_t __p0, poly64_t __p1) {
+  poly128_t __ret;
+  __ret = (poly128_t) __builtin_neon_vmull_p64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vmull_high_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly16x8_t __ret;
+  __ret = vmull_p8(vget_high_p8(__p0), vget_high_p8(__p1));
+  return __ret;
+}
+#else
+__ai poly16x8_t vmull_high_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __noswap_vmull_p8(__noswap_vget_high_p8(__rev0), __noswap_vget_high_p8(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmull_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = vmull_u8(vget_high_u8(__p0), vget_high_u8(__p1));
+  return __ret;
+}
+#else
+__ai uint16x8_t vmull_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmull_u8(__noswap_vget_high_u8(__rev0), __noswap_vget_high_u8(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmull_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmull_u32(vget_high_u32(__p0), vget_high_u32(__p1));
+  return __ret;
+}
+#else
+__ai uint64x2_t vmull_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmull_u32(__noswap_vget_high_u32(__rev0), __noswap_vget_high_u32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmull_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmull_u16(vget_high_u16(__p0), vget_high_u16(__p1));
+  return __ret;
+}
+#else
+__ai uint32x4_t vmull_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmull_u16(__noswap_vget_high_u16(__rev0), __noswap_vget_high_u16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmull_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = vmull_s8(vget_high_s8(__p0), vget_high_s8(__p1));
+  return __ret;
+}
+#else
+__ai int16x8_t vmull_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmull_s8(__noswap_vget_high_s8(__rev0), __noswap_vget_high_s8(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmull_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = vmull_s32(vget_high_s32(__p0), vget_high_s32(__p1));
+  return __ret;
+}
+#else
+__ai int64x2_t vmull_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmull_s32(__noswap_vget_high_s32(__rev0), __noswap_vget_high_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmull_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = vmull_s16(vget_high_s16(__p0), vget_high_s16(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vmull_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmull_s16(__noswap_vget_high_s16(__rev0), __noswap_vget_high_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly128_t vmull_high_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly128_t __ret;
+  __ret = vmull_p64((poly64_t)(vget_high_p64(__p0)), (poly64_t)(vget_high_p64(__p1)));
+  return __ret;
+}
+#else
+__ai poly128_t vmull_high_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly128_t __ret;
+  __ret = __noswap_vmull_p64((poly64_t)(__noswap_vget_high_p64(__rev0)), (poly64_t)(__noswap_vget_high_p64(__rev1)));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = vmull_u32(vget_high_u32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_lane_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __noswap_vmull_u32(__noswap_vget_high_u32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = vmull_u16(vget_high_u16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_lane_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __noswap_vmull_u16(__noswap_vget_high_u16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vmull_s32(vget_high_s32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vmull_s32(__noswap_vget_high_s32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vmull_s16(vget_high_s16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vmull_s16(__noswap_vget_high_s16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = vmull_u32(vget_high_u32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __noswap_vmull_u32(__noswap_vget_high_u32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = vmull_u16(vget_high_u16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x8_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __noswap_vmull_u16(__noswap_vget_high_u16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vmull_s32(vget_high_s32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vmull_s32(__noswap_vget_high_s32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_high_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vmull_s16(vget_high_s16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_high_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vmull_s16(__noswap_vget_high_s16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmull_high_n_u32(uint32x4_t __p0, uint32_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmull_n_u32(vget_high_u32(__p0), __p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmull_high_n_u32(uint32x4_t __p0, uint32_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmull_n_u32(__noswap_vget_high_u32(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmull_high_n_u16(uint16x8_t __p0, uint16_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmull_n_u16(vget_high_u16(__p0), __p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmull_high_n_u16(uint16x8_t __p0, uint16_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmull_n_u16(__noswap_vget_high_u16(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmull_high_n_s32(int32x4_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = vmull_n_s32(vget_high_s32(__p0), __p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vmull_high_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmull_n_s32(__noswap_vget_high_s32(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmull_high_n_s16(int16x8_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = vmull_n_s16(vget_high_s16(__p0), __p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vmull_high_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmull_n_s16(__noswap_vget_high_s16(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint64x2_t __ret; \
+  __ret = vmull_u32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_laneq_u32(__p0, __p1, __p2) __extension__ ({ \
+  uint32x2_t __s0 = __p0; \
+  uint32x4_t __s1 = __p1; \
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __noswap_vmull_u32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint32x4_t __ret; \
+  __ret = vmull_u16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_laneq_u16(__p0, __p1, __p2) __extension__ ({ \
+  uint16x4_t __s0 = __p0; \
+  uint16x8_t __s1 = __p1; \
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __noswap_vmull_u16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vmull_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vmull_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmull_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vmull_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmull_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vmull_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vmulxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vmulxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmulxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float64x2_t __noswap_vmulxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vmulxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vmulxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmulxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai float32x4_t __noswap_vmulxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vmulxq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vmulx_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vmulx_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vmulx_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vmulx_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmulx_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai float32x2_t __noswap_vmulx_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vmulx_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vmulxd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmulxd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float64_t vmulxd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmulxd_f64(__p0, __p1);
+  return __ret;
+}
+__ai float64_t __noswap_vmulxd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vmulxd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vmulxs_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmulxs_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float32_t vmulxs_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmulxs_f32(__p0, __p1);
+  return __ret;
+}
+__ai float32_t __noswap_vmulxs_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vmulxs_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxd_lane_f64(__p0_142, __p1_142, __p2_142) __extension__ ({ \
+  float64_t __s0_142 = __p0_142; \
+  float64x1_t __s1_142 = __p1_142; \
+  float64_t __ret_142; \
+  __ret_142 = vmulxd_f64(__s0_142, vget_lane_f64(__s1_142, __p2_142)); \
+  __ret_142; \
+})
+#else
+#define vmulxd_lane_f64(__p0_143, __p1_143, __p2_143) __extension__ ({ \
+  float64_t __s0_143 = __p0_143; \
+  float64x1_t __s1_143 = __p1_143; \
+  float64_t __ret_143; \
+  __ret_143 = __noswap_vmulxd_f64(__s0_143, __noswap_vget_lane_f64(__s1_143, __p2_143)); \
+  __ret_143; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxs_lane_f32(__p0_144, __p1_144, __p2_144) __extension__ ({ \
+  float32_t __s0_144 = __p0_144; \
+  float32x2_t __s1_144 = __p1_144; \
+  float32_t __ret_144; \
+  __ret_144 = vmulxs_f32(__s0_144, vget_lane_f32(__s1_144, __p2_144)); \
+  __ret_144; \
+})
+#else
+#define vmulxs_lane_f32(__p0_145, __p1_145, __p2_145) __extension__ ({ \
+  float32_t __s0_145 = __p0_145; \
+  float32x2_t __s1_145 = __p1_145; \
+  float32x2_t __rev1_145;  __rev1_145 = __builtin_shufflevector(__s1_145, __s1_145, 1, 0); \
+  float32_t __ret_145; \
+  __ret_145 = __noswap_vmulxs_f32(__s0_145, __noswap_vget_lane_f32(__rev1_145, __p2_145)); \
+  __ret_145; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = vmulxq_f64(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulxq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __ret; \
+  __ret = __noswap_vmulxq_f64(__rev0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = vmulxq_f32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulxq_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __noswap_vmulxq_f32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulx_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = vmulx_f32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulx_lane_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x2_t __s1 = __p1; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __noswap_vmulx_f32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxd_laneq_f64(__p0_146, __p1_146, __p2_146) __extension__ ({ \
+  float64_t __s0_146 = __p0_146; \
+  float64x2_t __s1_146 = __p1_146; \
+  float64_t __ret_146; \
+  __ret_146 = vmulxd_f64(__s0_146, vgetq_lane_f64(__s1_146, __p2_146)); \
+  __ret_146; \
+})
+#else
+#define vmulxd_laneq_f64(__p0_147, __p1_147, __p2_147) __extension__ ({ \
+  float64_t __s0_147 = __p0_147; \
+  float64x2_t __s1_147 = __p1_147; \
+  float64x2_t __rev1_147;  __rev1_147 = __builtin_shufflevector(__s1_147, __s1_147, 1, 0); \
+  float64_t __ret_147; \
+  __ret_147 = __noswap_vmulxd_f64(__s0_147, __noswap_vgetq_lane_f64(__rev1_147, __p2_147)); \
+  __ret_147; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxs_laneq_f32(__p0_148, __p1_148, __p2_148) __extension__ ({ \
+  float32_t __s0_148 = __p0_148; \
+  float32x4_t __s1_148 = __p1_148; \
+  float32_t __ret_148; \
+  __ret_148 = vmulxs_f32(__s0_148, vgetq_lane_f32(__s1_148, __p2_148)); \
+  __ret_148; \
+})
+#else
+#define vmulxs_laneq_f32(__p0_149, __p1_149, __p2_149) __extension__ ({ \
+  float32_t __s0_149 = __p0_149; \
+  float32x4_t __s1_149 = __p1_149; \
+  float32x4_t __rev1_149;  __rev1_149 = __builtin_shufflevector(__s1_149, __s1_149, 3, 2, 1, 0); \
+  float32_t __ret_149; \
+  __ret_149 = __noswap_vmulxs_f32(__s0_149, __noswap_vgetq_lane_f32(__rev1_149, __p2_149)); \
+  __ret_149; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxq_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = vmulxq_f64(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulxq_laneq_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = __noswap_vmulxq_f64(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulxq_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __ret; \
+  __ret = vmulxq_f32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulxq_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x4_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x4_t __ret; \
+  __ret = __noswap_vmulxq_f32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulx_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __ret; \
+  __ret = vmulx_f32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vmulx_laneq_f32(__p0, __p1, __p2) __extension__ ({ \
+  float32x2_t __s0 = __p0; \
+  float32x4_t __s1 = __p1; \
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  float32x2_t __ret; \
+  __ret = __noswap_vmulx_f32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vnegq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai float64x2_t vnegq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vnegq_s64(int64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int64x2_t vnegq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = -__rev0;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vneg_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai float64x1_t vneg_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vneg_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#else
+__ai int64x1_t vneg_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = -__p0;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vnegd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vnegd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vnegd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vnegd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vpaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vpaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vpaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vpaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vpaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vpaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vpaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vpaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vpaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vpaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vpaddq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vpaddq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vpaddq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vpaddq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vpaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vpaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vpaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vpaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vpaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vpaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vpaddd_u64(uint64x2_t __p0) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vpaddd_u64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai uint64_t vpaddd_u64(uint64x2_t __p0) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vpaddd_u64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vpaddd_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpaddd_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vpaddd_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpaddd_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vpaddd_s64(int64x2_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vpaddd_s64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai int64_t vpaddd_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vpaddd_s64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vpadds_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpadds_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vpadds_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpadds_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vpmaxq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vpmaxq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vpmaxq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vpmaxq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vpmaxq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vpmaxq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vpmaxq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vpmaxq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vpmaxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vpmaxq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vpmaxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vpmaxq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vpmaxq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vpmaxq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vpmaxq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vpmaxq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpmaxq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vpmaxqd_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpmaxqd_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vpmaxqd_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpmaxqd_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vpmaxs_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmaxs_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vpmaxs_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmaxs_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vpmaxnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vpmaxnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vpmaxnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vpmaxnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpmaxnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vpmaxnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmaxnm_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vpmaxnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpmaxnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vpmaxnmqd_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpmaxnmqd_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vpmaxnmqd_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpmaxnmqd_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vpmaxnms_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmaxnms_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vpmaxnms_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmaxnms_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vpminq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vpminq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vpminq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vpminq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vpminq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vpminq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vpminq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vpminq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vpminq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vpminq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vpminq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vpminq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vpminq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vpminq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vpminq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpminq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vpminq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vpminq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vpminqd_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpminqd_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vpminqd_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpminqd_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vpmins_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmins_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vpmins_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpmins_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vpminnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vpminnmq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vpminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vpminnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpminnmq_v((int8x16_t)__p0, (int8x16_t)__p1, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vpminnmq_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vpminnmq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vpminnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpminnm_v((int8x8_t)__p0, (int8x8_t)__p1, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vpminnm_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vpminnm_v((int8x8_t)__rev0, (int8x8_t)__rev1, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vpminnmqd_f64(float64x2_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpminnmqd_f64((int8x16_t)__p0);
+  return __ret;
+}
+#else
+__ai float64_t vpminnmqd_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vpminnmqd_f64((int8x16_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vpminnms_f32(float32x2_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpminnms_f32((int8x8_t)__p0);
+  return __ret;
+}
+#else
+__ai float32_t vpminnms_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vpminnms_f32((int8x8_t)__rev0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqabsq_s64(int64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqabsq_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqabsq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqabsq_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqabs_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqabs_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqabs_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqabs_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqabsb_s8(int8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqabsb_s8(__p0);
+  return __ret;
+}
+#else
+__ai int8_t vqabsb_s8(int8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqabsb_s8(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqabss_s32(int32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqabss_s32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vqabss_s32(int32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqabss_s32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqabsd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqabsd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vqabsd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqabsd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqabsh_s16(int16_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqabsh_s16(__p0);
+  return __ret;
+}
+#else
+__ai int16_t vqabsh_s16(int16_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqabsh_s16(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vqaddb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqaddb_u8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint8_t vqaddb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqaddb_u8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vqadds_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqadds_u32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vqadds_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqadds_u32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vqaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqaddd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vqaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqaddd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vqaddh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqaddh_u16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint16_t vqaddh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqaddh_u16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqaddb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqaddb_s8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int8_t vqaddb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqaddb_s8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqadds_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqadds_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqadds_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqadds_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqaddd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vqaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqaddd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqaddh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqaddh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqaddh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqaddh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqdmlals_s32(int64_t __p0, int32_t __p1, int32_t __p2) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmlals_s32(__p0, __p1, __p2);
+  return __ret;
+}
+#else
+__ai int64_t vqdmlals_s32(int64_t __p0, int32_t __p1, int32_t __p2) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmlals_s32(__p0, __p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqdmlalh_s16(int32_t __p0, int16_t __p1, int16_t __p2) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmlalh_s16(__p0, __p1, __p2);
+  return __ret;
+}
+#else
+__ai int32_t vqdmlalh_s16(int32_t __p0, int16_t __p1, int16_t __p2) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmlalh_s16(__p0, __p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __ret;
+  __ret = vqdmlal_s32(__p0, vget_high_s32(__p1), vget_high_s32(__p2));
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmlal_s32(__rev0, __noswap_vget_high_s32(__rev1), __noswap_vget_high_s32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __ret;
+  __ret = vqdmlal_s16(__p0, vget_high_s16(__p1), vget_high_s16(__p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmlal_s16(__rev0, __noswap_vget_high_s16(__rev1), __noswap_vget_high_s16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlal_s32(__s0, vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlal_s32(__rev0, __noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlal_s16(__s0, vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlal_s16(__rev0, __noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlal_s32(__s0, vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlal_s32(__rev0, __noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlal_s16(__s0, vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlal_s16(__rev0, __noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlal_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = vqdmlal_n_s32(__p0, vget_high_s32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlal_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmlal_n_s32(__rev0, __noswap_vget_high_s32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlal_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = vqdmlal_n_s16(__p0, vget_high_s16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlal_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmlal_n_s16(__rev0, __noswap_vget_high_s16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlals_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlals_lane_s32(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlals_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlals_lane_s32(__s0, __s1, (int8x8_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlalh_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlalh_lane_s16(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlalh_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlalh_lane_s16(__s0, __s1, (int8x8_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlals_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlals_laneq_s32(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlals_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlals_laneq_s32(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlalh_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlalh_laneq_s16(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlalh_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlalh_laneq_s16(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlal_s32(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlal_s32(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlal_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlal_s16(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlal_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlal_s16(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqdmlsls_s32(int64_t __p0, int32_t __p1, int32_t __p2) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmlsls_s32(__p0, __p1, __p2);
+  return __ret;
+}
+#else
+__ai int64_t vqdmlsls_s32(int64_t __p0, int32_t __p1, int32_t __p2) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmlsls_s32(__p0, __p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqdmlslh_s16(int32_t __p0, int16_t __p1, int16_t __p2) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmlslh_s16(__p0, __p1, __p2);
+  return __ret;
+}
+#else
+__ai int32_t vqdmlslh_s16(int32_t __p0, int16_t __p1, int16_t __p2) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmlslh_s16(__p0, __p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlsl_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __ret;
+  __ret = vqdmlsl_s32(__p0, vget_high_s32(__p1), vget_high_s32(__p2));
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlsl_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmlsl_s32(__rev0, __noswap_vget_high_s32(__rev1), __noswap_vget_high_s32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlsl_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __ret;
+  __ret = vqdmlsl_s16(__p0, vget_high_s16(__p1), vget_high_s16(__p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlsl_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmlsl_s16(__rev0, __noswap_vget_high_s16(__rev1), __noswap_vget_high_s16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlsl_s32(__s0, vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_high_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlsl_s32(__rev0, __noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlsl_s16(__s0, vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_high_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlsl_s16(__rev0, __noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlsl_s32(__s0, vget_high_s32(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_high_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlsl_s32(__rev0, __noswap_vget_high_s32(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlsl_s16(__s0, vget_high_s16(__s1), __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_high_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlsl_s16(__rev0, __noswap_vget_high_s16(__rev1), __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmlsl_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = vqdmlsl_n_s32(__p0, vget_high_s32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmlsl_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmlsl_n_s32(__rev0, __noswap_vget_high_s32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmlsl_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = vqdmlsl_n_s16(__p0, vget_high_s16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmlsl_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmlsl_n_s16(__rev0, __noswap_vget_high_s16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsls_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlsls_lane_s32(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlsls_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlsls_lane_s32(__s0, __s1, (int8x8_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlslh_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlslh_lane_s16(__s0, __s1, (int8x8_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlslh_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlslh_lane_s16(__s0, __s1, (int8x8_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsls_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlsls_laneq_s32(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlsls_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqdmlsls_laneq_s32(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlslh_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlslh_laneq_s16(__s0, __s1, (int8x16_t)__s2, __p3); \
+  __ret; \
+})
+#else
+#define vqdmlslh_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqdmlslh_laneq_s16(__s0, __s1, (int8x16_t)__rev2, __p3); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = vqdmlsl_s32(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_laneq_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmlsl_s32(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmlsl_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = vqdmlsl_s16(__s0, __s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vqdmlsl_laneq_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmlsl_s16(__rev0, __rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+__ai int32_t __noswap_vqdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+__ai int16_t __noswap_vqdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhs_lane_s32(__p0_150, __p1_150, __p2_150) __extension__ ({ \
+  int32_t __s0_150 = __p0_150; \
+  int32x2_t __s1_150 = __p1_150; \
+  int32_t __ret_150; \
+  __ret_150 = vqdmulhs_s32(__s0_150, vget_lane_s32(__s1_150, __p2_150)); \
+  __ret_150; \
+})
+#else
+#define vqdmulhs_lane_s32(__p0_151, __p1_151, __p2_151) __extension__ ({ \
+  int32_t __s0_151 = __p0_151; \
+  int32x2_t __s1_151 = __p1_151; \
+  int32x2_t __rev1_151;  __rev1_151 = __builtin_shufflevector(__s1_151, __s1_151, 1, 0); \
+  int32_t __ret_151; \
+  __ret_151 = __noswap_vqdmulhs_s32(__s0_151, __noswap_vget_lane_s32(__rev1_151, __p2_151)); \
+  __ret_151; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhh_lane_s16(__p0_152, __p1_152, __p2_152) __extension__ ({ \
+  int16_t __s0_152 = __p0_152; \
+  int16x4_t __s1_152 = __p1_152; \
+  int16_t __ret_152; \
+  __ret_152 = vqdmulhh_s16(__s0_152, vget_lane_s16(__s1_152, __p2_152)); \
+  __ret_152; \
+})
+#else
+#define vqdmulhh_lane_s16(__p0_153, __p1_153, __p2_153) __extension__ ({ \
+  int16_t __s0_153 = __p0_153; \
+  int16x4_t __s1_153 = __p1_153; \
+  int16x4_t __rev1_153;  __rev1_153 = __builtin_shufflevector(__s1_153, __s1_153, 3, 2, 1, 0); \
+  int16_t __ret_153; \
+  __ret_153 = __noswap_vqdmulhh_s16(__s0_153, __noswap_vget_lane_s16(__rev1_153, __p2_153)); \
+  __ret_153; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhs_laneq_s32(__p0_154, __p1_154, __p2_154) __extension__ ({ \
+  int32_t __s0_154 = __p0_154; \
+  int32x4_t __s1_154 = __p1_154; \
+  int32_t __ret_154; \
+  __ret_154 = vqdmulhs_s32(__s0_154, vgetq_lane_s32(__s1_154, __p2_154)); \
+  __ret_154; \
+})
+#else
+#define vqdmulhs_laneq_s32(__p0_155, __p1_155, __p2_155) __extension__ ({ \
+  int32_t __s0_155 = __p0_155; \
+  int32x4_t __s1_155 = __p1_155; \
+  int32x4_t __rev1_155;  __rev1_155 = __builtin_shufflevector(__s1_155, __s1_155, 3, 2, 1, 0); \
+  int32_t __ret_155; \
+  __ret_155 = __noswap_vqdmulhs_s32(__s0_155, __noswap_vgetq_lane_s32(__rev1_155, __p2_155)); \
+  __ret_155; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhh_laneq_s16(__p0_156, __p1_156, __p2_156) __extension__ ({ \
+  int16_t __s0_156 = __p0_156; \
+  int16x8_t __s1_156 = __p1_156; \
+  int16_t __ret_156; \
+  __ret_156 = vqdmulhh_s16(__s0_156, vgetq_lane_s16(__s1_156, __p2_156)); \
+  __ret_156; \
+})
+#else
+#define vqdmulhh_laneq_s16(__p0_157, __p1_157, __p2_157) __extension__ ({ \
+  int16_t __s0_157 = __p0_157; \
+  int16x8_t __s1_157 = __p1_157; \
+  int16x8_t __rev1_157;  __rev1_157 = __builtin_shufflevector(__s1_157, __s1_157, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16_t __ret_157; \
+  __ret_157 = __noswap_vqdmulhh_s16(__s0_157, __noswap_vgetq_lane_s16(__rev1_157, __p2_157)); \
+  __ret_157; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmulhq_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulhq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmulhq_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulhq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = vqdmulhq_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulhq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __noswap_vqdmulhq_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulh_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = vqdmulh_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulh_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __noswap_vqdmulh_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulh_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = vqdmulh_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmulh_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __noswap_vqdmulh_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqdmulls_s32(int32_t __p0, int32_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmulls_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vqdmulls_s32(int32_t __p0, int32_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmulls_s32(__p0, __p1);
+  return __ret;
+}
+__ai int64_t __noswap_vqdmulls_s32(int32_t __p0, int32_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqdmulls_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqdmullh_s16(int16_t __p0, int16_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmullh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqdmullh_s16(int16_t __p0, int16_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmullh_s16(__p0, __p1);
+  return __ret;
+}
+__ai int32_t __noswap_vqdmullh_s16(int16_t __p0, int16_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqdmullh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmull_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = vqdmull_s32(vget_high_s32(__p0), vget_high_s32(__p1));
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmull_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmull_s32(__noswap_vget_high_s32(__rev0), __noswap_vget_high_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmull_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = vqdmull_s16(vget_high_s16(__p0), vget_high_s16(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmull_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmull_s16(__noswap_vget_high_s16(__rev0), __noswap_vget_high_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_high_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vqdmull_s32(vget_high_s32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_high_lane_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmull_s32(__noswap_vget_high_s32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_high_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmull_s16(vget_high_s16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_high_lane_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmull_s16(__noswap_vget_high_s16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_high_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vqdmull_s32(vget_high_s32(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_high_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmull_s32(__noswap_vget_high_s32(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_high_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmull_s16(vget_high_s16(__s0), __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_high_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmull_s16(__noswap_vget_high_s16(__rev0), __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqdmull_high_n_s32(int32x4_t __p0, int32_t __p1) {
+  int64x2_t __ret;
+  __ret = vqdmull_n_s32(vget_high_s32(__p0), __p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vqdmull_high_n_s32(int32x4_t __p0, int32_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vqdmull_n_s32(__noswap_vget_high_s32(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqdmull_high_n_s16(int16x8_t __p0, int16_t __p1) {
+  int32x4_t __ret;
+  __ret = vqdmull_n_s16(vget_high_s16(__p0), __p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vqdmull_high_n_s16(int16x8_t __p0, int16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vqdmull_n_s16(__noswap_vget_high_s16(__rev0), __p1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulls_lane_s32(__p0_158, __p1_158, __p2_158) __extension__ ({ \
+  int32_t __s0_158 = __p0_158; \
+  int32x2_t __s1_158 = __p1_158; \
+  int64_t __ret_158; \
+  __ret_158 = vqdmulls_s32(__s0_158, vget_lane_s32(__s1_158, __p2_158)); \
+  __ret_158; \
+})
+#else
+#define vqdmulls_lane_s32(__p0_159, __p1_159, __p2_159) __extension__ ({ \
+  int32_t __s0_159 = __p0_159; \
+  int32x2_t __s1_159 = __p1_159; \
+  int32x2_t __rev1_159;  __rev1_159 = __builtin_shufflevector(__s1_159, __s1_159, 1, 0); \
+  int64_t __ret_159; \
+  __ret_159 = __noswap_vqdmulls_s32(__s0_159, __noswap_vget_lane_s32(__rev1_159, __p2_159)); \
+  __ret_159; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmullh_lane_s16(__p0_160, __p1_160, __p2_160) __extension__ ({ \
+  int16_t __s0_160 = __p0_160; \
+  int16x4_t __s1_160 = __p1_160; \
+  int32_t __ret_160; \
+  __ret_160 = vqdmullh_s16(__s0_160, vget_lane_s16(__s1_160, __p2_160)); \
+  __ret_160; \
+})
+#else
+#define vqdmullh_lane_s16(__p0_161, __p1_161, __p2_161) __extension__ ({ \
+  int16_t __s0_161 = __p0_161; \
+  int16x4_t __s1_161 = __p1_161; \
+  int16x4_t __rev1_161;  __rev1_161 = __builtin_shufflevector(__s1_161, __s1_161, 3, 2, 1, 0); \
+  int32_t __ret_161; \
+  __ret_161 = __noswap_vqdmullh_s16(__s0_161, __noswap_vget_lane_s16(__rev1_161, __p2_161)); \
+  __ret_161; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmulls_laneq_s32(__p0_162, __p1_162, __p2_162) __extension__ ({ \
+  int32_t __s0_162 = __p0_162; \
+  int32x4_t __s1_162 = __p1_162; \
+  int64_t __ret_162; \
+  __ret_162 = vqdmulls_s32(__s0_162, vgetq_lane_s32(__s1_162, __p2_162)); \
+  __ret_162; \
+})
+#else
+#define vqdmulls_laneq_s32(__p0_163, __p1_163, __p2_163) __extension__ ({ \
+  int32_t __s0_163 = __p0_163; \
+  int32x4_t __s1_163 = __p1_163; \
+  int32x4_t __rev1_163;  __rev1_163 = __builtin_shufflevector(__s1_163, __s1_163, 3, 2, 1, 0); \
+  int64_t __ret_163; \
+  __ret_163 = __noswap_vqdmulls_s32(__s0_163, __noswap_vgetq_lane_s32(__rev1_163, __p2_163)); \
+  __ret_163; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmullh_laneq_s16(__p0_164, __p1_164, __p2_164) __extension__ ({ \
+  int16_t __s0_164 = __p0_164; \
+  int16x8_t __s1_164 = __p1_164; \
+  int32_t __ret_164; \
+  __ret_164 = vqdmullh_s16(__s0_164, vgetq_lane_s16(__s1_164, __p2_164)); \
+  __ret_164; \
+})
+#else
+#define vqdmullh_laneq_s16(__p0_165, __p1_165, __p2_165) __extension__ ({ \
+  int16_t __s0_165 = __p0_165; \
+  int16x8_t __s1_165 = __p1_165; \
+  int16x8_t __rev1_165;  __rev1_165 = __builtin_shufflevector(__s1_165, __s1_165, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32_t __ret_165; \
+  __ret_165 = __noswap_vqdmullh_s16(__s0_165, __noswap_vgetq_lane_s16(__rev1_165, __p2_165)); \
+  __ret_165; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int64x2_t __ret; \
+  __ret = vqdmull_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __noswap_vqdmull_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqdmull_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqdmull_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqdmull_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqdmull_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqmovns_s32(int32_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqmovns_s32(__p0);
+  return __ret;
+}
+#else
+__ai int16_t vqmovns_s32(int32_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqmovns_s32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqmovnd_s64(int64_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqmovnd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vqmovnd_s64(int64_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqmovnd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqmovnh_s16(int16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqmovnh_s16(__p0);
+  return __ret;
+}
+#else
+__ai int8_t vqmovnh_s16(int16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqmovnh_s16(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vqmovns_u32(uint32_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqmovns_u32(__p0);
+  return __ret;
+}
+#else
+__ai uint16_t vqmovns_u32(uint32_t __p0) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqmovns_u32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vqmovnd_u64(uint64_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqmovnd_u64(__p0);
+  return __ret;
+}
+#else
+__ai uint32_t vqmovnd_u64(uint64_t __p0) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqmovnd_u64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vqmovnh_u16(uint16_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqmovnh_u16(__p0);
+  return __ret;
+}
+#else
+__ai uint8_t vqmovnh_u16(uint16_t __p0) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqmovnh_u16(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vqmovn_high_u32(uint16x4_t __p0, uint32x4_t __p1) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vqmovn_u32(__p1));
+  return __ret;
+}
+#else
+__ai uint16x8_t vqmovn_high_u32(uint16x4_t __p0, uint32x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vqmovn_u32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vqmovn_high_u64(uint32x2_t __p0, uint64x2_t __p1) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vqmovn_u64(__p1));
+  return __ret;
+}
+#else
+__ai uint32x4_t vqmovn_high_u64(uint32x2_t __p0, uint64x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vqmovn_u64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqmovn_high_u16(uint8x8_t __p0, uint16x8_t __p1) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vqmovn_u16(__p1));
+  return __ret;
+}
+#else
+__ai uint8x16_t vqmovn_high_u16(uint8x8_t __p0, uint16x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vqmovn_u16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqmovn_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vqmovn_s32(__p1));
+  return __ret;
+}
+#else
+__ai int16x8_t vqmovn_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vqmovn_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqmovn_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vqmovn_s64(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vqmovn_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vqmovn_s64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqmovn_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vqmovn_s16(__p1));
+  return __ret;
+}
+#else
+__ai int8x16_t vqmovn_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vqmovn_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqmovuns_s32(int32_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqmovuns_s32(__p0);
+  return __ret;
+}
+#else
+__ai int16_t vqmovuns_s32(int32_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqmovuns_s32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqmovund_s64(int64_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqmovund_s64(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vqmovund_s64(int64_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqmovund_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqmovunh_s16(int16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqmovunh_s16(__p0);
+  return __ret;
+}
+#else
+__ai int8_t vqmovunh_s16(int16_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqmovunh_s16(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vqmovun_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x8_t __ret;
+  __ret = vcombine_u16((uint16x4_t)(__p0), vqmovun_s32(__p1));
+  return __ret;
+}
+#else
+__ai int16x8_t vqmovun_high_s32(int16x4_t __p0, int32x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_u16((uint16x4_t)(__rev0), __noswap_vqmovun_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vqmovun_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x4_t __ret;
+  __ret = vcombine_u32((uint32x2_t)(__p0), vqmovun_s64(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vqmovun_high_s64(int32x2_t __p0, int64x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_u32((uint32x2_t)(__rev0), __noswap_vqmovun_s64(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqmovun_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x16_t __ret;
+  __ret = vcombine_u8((uint8x8_t)(__p0), vqmovun_s16(__p1));
+  return __ret;
+}
+#else
+__ai int8x16_t vqmovun_high_s16(int8x8_t __p0, int16x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_u8((uint8x8_t)(__rev0), __noswap_vqmovun_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vqnegq_s64(int64x2_t __p0) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqnegq_v((int8x16_t)__p0, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vqnegq_s64(int64x2_t __p0) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vqnegq_v((int8x16_t)__rev0, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vqneg_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqneg_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vqneg_s64(int64x1_t __p0) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vqneg_v((int8x8_t)__p0, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqnegb_s8(int8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqnegb_s8(__p0);
+  return __ret;
+}
+#else
+__ai int8_t vqnegb_s8(int8_t __p0) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqnegb_s8(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqnegs_s32(int32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqnegs_s32(__p0);
+  return __ret;
+}
+#else
+__ai int32_t vqnegs_s32(int32_t __p0) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqnegs_s32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqnegd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqnegd_s64(__p0);
+  return __ret;
+}
+#else
+__ai int64_t vqnegd_s64(int64_t __p0) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqnegd_s64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqnegh_s16(int16_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqnegh_s16(__p0);
+  return __ret;
+}
+#else
+__ai int16_t vqnegh_s16(int16_t __p0) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqnegh_s16(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqrdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqrdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqrdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqrdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+__ai int32_t __noswap_vqrdmulhs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqrdmulhs_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqrdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqrdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqrdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqrdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+__ai int16_t __noswap_vqrdmulhh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqrdmulhh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhs_lane_s32(__p0_166, __p1_166, __p2_166) __extension__ ({ \
+  int32_t __s0_166 = __p0_166; \
+  int32x2_t __s1_166 = __p1_166; \
+  int32_t __ret_166; \
+  __ret_166 = vqrdmulhs_s32(__s0_166, vget_lane_s32(__s1_166, __p2_166)); \
+  __ret_166; \
+})
+#else
+#define vqrdmulhs_lane_s32(__p0_167, __p1_167, __p2_167) __extension__ ({ \
+  int32_t __s0_167 = __p0_167; \
+  int32x2_t __s1_167 = __p1_167; \
+  int32x2_t __rev1_167;  __rev1_167 = __builtin_shufflevector(__s1_167, __s1_167, 1, 0); \
+  int32_t __ret_167; \
+  __ret_167 = __noswap_vqrdmulhs_s32(__s0_167, __noswap_vget_lane_s32(__rev1_167, __p2_167)); \
+  __ret_167; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhh_lane_s16(__p0_168, __p1_168, __p2_168) __extension__ ({ \
+  int16_t __s0_168 = __p0_168; \
+  int16x4_t __s1_168 = __p1_168; \
+  int16_t __ret_168; \
+  __ret_168 = vqrdmulhh_s16(__s0_168, vget_lane_s16(__s1_168, __p2_168)); \
+  __ret_168; \
+})
+#else
+#define vqrdmulhh_lane_s16(__p0_169, __p1_169, __p2_169) __extension__ ({ \
+  int16_t __s0_169 = __p0_169; \
+  int16x4_t __s1_169 = __p1_169; \
+  int16x4_t __rev1_169;  __rev1_169 = __builtin_shufflevector(__s1_169, __s1_169, 3, 2, 1, 0); \
+  int16_t __ret_169; \
+  __ret_169 = __noswap_vqrdmulhh_s16(__s0_169, __noswap_vget_lane_s16(__rev1_169, __p2_169)); \
+  __ret_169; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhs_laneq_s32(__p0_170, __p1_170, __p2_170) __extension__ ({ \
+  int32_t __s0_170 = __p0_170; \
+  int32x4_t __s1_170 = __p1_170; \
+  int32_t __ret_170; \
+  __ret_170 = vqrdmulhs_s32(__s0_170, vgetq_lane_s32(__s1_170, __p2_170)); \
+  __ret_170; \
+})
+#else
+#define vqrdmulhs_laneq_s32(__p0_171, __p1_171, __p2_171) __extension__ ({ \
+  int32_t __s0_171 = __p0_171; \
+  int32x4_t __s1_171 = __p1_171; \
+  int32x4_t __rev1_171;  __rev1_171 = __builtin_shufflevector(__s1_171, __s1_171, 3, 2, 1, 0); \
+  int32_t __ret_171; \
+  __ret_171 = __noswap_vqrdmulhs_s32(__s0_171, __noswap_vgetq_lane_s32(__rev1_171, __p2_171)); \
+  __ret_171; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhh_laneq_s16(__p0_172, __p1_172, __p2_172) __extension__ ({ \
+  int16_t __s0_172 = __p0_172; \
+  int16x8_t __s1_172 = __p1_172; \
+  int16_t __ret_172; \
+  __ret_172 = vqrdmulhh_s16(__s0_172, vgetq_lane_s16(__s1_172, __p2_172)); \
+  __ret_172; \
+})
+#else
+#define vqrdmulhh_laneq_s16(__p0_173, __p1_173, __p2_173) __extension__ ({ \
+  int16_t __s0_173 = __p0_173; \
+  int16x8_t __s1_173 = __p1_173; \
+  int16x8_t __rev1_173;  __rev1_173 = __builtin_shufflevector(__s1_173, __s1_173, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16_t __ret_173; \
+  __ret_173 = __noswap_vqrdmulhh_s16(__s0_173, __noswap_vgetq_lane_s16(__rev1_173, __p2_173)); \
+  __ret_173; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __ret; \
+  __ret = vqrdmulhq_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulhq_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __noswap_vqrdmulhq_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulhq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __ret; \
+  __ret = vqrdmulhq_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulhq_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x8_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret; \
+  __ret = __noswap_vqrdmulhq_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulh_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __ret; \
+  __ret = vqrdmulh_s32(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulh_laneq_s32(__p0, __p1, __p2) __extension__ ({ \
+  int32x2_t __s0 = __p0; \
+  int32x4_t __s1 = __p1; \
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int32x2_t __ret; \
+  __ret = __noswap_vqrdmulh_s32(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrdmulh_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __ret; \
+  __ret = vqrdmulh_s16(__s0, __builtin_shufflevector(__s1, __s1, __p2, __p2, __p2, __p2)); \
+  __ret; \
+})
+#else
+#define vqrdmulh_laneq_s16(__p0, __p1, __p2) __extension__ ({ \
+  int16x4_t __s0 = __p0; \
+  int16x8_t __s1 = __p1; \
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x4_t __ret; \
+  __ret = __noswap_vqrdmulh_s16(__rev0, __builtin_shufflevector(__rev1, __rev1, __p2, __p2, __p2, __p2)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vqrshlb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqrshlb_u8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint8_t vqrshlb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqrshlb_u8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vqrshls_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqrshls_u32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vqrshls_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqrshls_u32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vqrshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqrshld_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vqrshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqrshld_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vqrshlh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqrshlh_u16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint16_t vqrshlh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqrshlh_u16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqrshlb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqrshlb_s8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int8_t vqrshlb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqrshlb_s8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqrshls_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqrshls_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqrshls_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqrshls_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqrshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqrshld_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vqrshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqrshld_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqrshlh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqrshlh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqrshlh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqrshlh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_u32(__p0_174, __p1_174, __p2_174) __extension__ ({ \
+  uint16x4_t __s0_174 = __p0_174; \
+  uint32x4_t __s1_174 = __p1_174; \
+  uint16x8_t __ret_174; \
+  __ret_174 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_174), (uint16x4_t)(vqrshrn_n_u32(__s1_174, __p2_174)))); \
+  __ret_174; \
+})
+#else
+#define vqrshrn_high_n_u32(__p0_175, __p1_175, __p2_175) __extension__ ({ \
+  uint16x4_t __s0_175 = __p0_175; \
+  uint32x4_t __s1_175 = __p1_175; \
+  uint16x4_t __rev0_175;  __rev0_175 = __builtin_shufflevector(__s0_175, __s0_175, 3, 2, 1, 0); \
+  uint32x4_t __rev1_175;  __rev1_175 = __builtin_shufflevector(__s1_175, __s1_175, 3, 2, 1, 0); \
+  uint16x8_t __ret_175; \
+  __ret_175 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_175), (uint16x4_t)(__noswap_vqrshrn_n_u32(__rev1_175, __p2_175)))); \
+  __ret_175 = __builtin_shufflevector(__ret_175, __ret_175, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_175; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_u64(__p0_176, __p1_176, __p2_176) __extension__ ({ \
+  uint32x2_t __s0_176 = __p0_176; \
+  uint64x2_t __s1_176 = __p1_176; \
+  uint32x4_t __ret_176; \
+  __ret_176 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_176), (uint32x2_t)(vqrshrn_n_u64(__s1_176, __p2_176)))); \
+  __ret_176; \
+})
+#else
+#define vqrshrn_high_n_u64(__p0_177, __p1_177, __p2_177) __extension__ ({ \
+  uint32x2_t __s0_177 = __p0_177; \
+  uint64x2_t __s1_177 = __p1_177; \
+  uint32x2_t __rev0_177;  __rev0_177 = __builtin_shufflevector(__s0_177, __s0_177, 1, 0); \
+  uint64x2_t __rev1_177;  __rev1_177 = __builtin_shufflevector(__s1_177, __s1_177, 1, 0); \
+  uint32x4_t __ret_177; \
+  __ret_177 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_177), (uint32x2_t)(__noswap_vqrshrn_n_u64(__rev1_177, __p2_177)))); \
+  __ret_177 = __builtin_shufflevector(__ret_177, __ret_177, 3, 2, 1, 0); \
+  __ret_177; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_u16(__p0_178, __p1_178, __p2_178) __extension__ ({ \
+  uint8x8_t __s0_178 = __p0_178; \
+  uint16x8_t __s1_178 = __p1_178; \
+  uint8x16_t __ret_178; \
+  __ret_178 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_178), (uint8x8_t)(vqrshrn_n_u16(__s1_178, __p2_178)))); \
+  __ret_178; \
+})
+#else
+#define vqrshrn_high_n_u16(__p0_179, __p1_179, __p2_179) __extension__ ({ \
+  uint8x8_t __s0_179 = __p0_179; \
+  uint16x8_t __s1_179 = __p1_179; \
+  uint8x8_t __rev0_179;  __rev0_179 = __builtin_shufflevector(__s0_179, __s0_179, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1_179;  __rev1_179 = __builtin_shufflevector(__s1_179, __s1_179, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_179; \
+  __ret_179 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_179), (uint8x8_t)(__noswap_vqrshrn_n_u16(__rev1_179, __p2_179)))); \
+  __ret_179 = __builtin_shufflevector(__ret_179, __ret_179, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_179; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_s32(__p0_180, __p1_180, __p2_180) __extension__ ({ \
+  int16x4_t __s0_180 = __p0_180; \
+  int32x4_t __s1_180 = __p1_180; \
+  int16x8_t __ret_180; \
+  __ret_180 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_180), (int16x4_t)(vqrshrn_n_s32(__s1_180, __p2_180)))); \
+  __ret_180; \
+})
+#else
+#define vqrshrn_high_n_s32(__p0_181, __p1_181, __p2_181) __extension__ ({ \
+  int16x4_t __s0_181 = __p0_181; \
+  int32x4_t __s1_181 = __p1_181; \
+  int16x4_t __rev0_181;  __rev0_181 = __builtin_shufflevector(__s0_181, __s0_181, 3, 2, 1, 0); \
+  int32x4_t __rev1_181;  __rev1_181 = __builtin_shufflevector(__s1_181, __s1_181, 3, 2, 1, 0); \
+  int16x8_t __ret_181; \
+  __ret_181 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_181), (int16x4_t)(__noswap_vqrshrn_n_s32(__rev1_181, __p2_181)))); \
+  __ret_181 = __builtin_shufflevector(__ret_181, __ret_181, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_181; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_s64(__p0_182, __p1_182, __p2_182) __extension__ ({ \
+  int32x2_t __s0_182 = __p0_182; \
+  int64x2_t __s1_182 = __p1_182; \
+  int32x4_t __ret_182; \
+  __ret_182 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_182), (int32x2_t)(vqrshrn_n_s64(__s1_182, __p2_182)))); \
+  __ret_182; \
+})
+#else
+#define vqrshrn_high_n_s64(__p0_183, __p1_183, __p2_183) __extension__ ({ \
+  int32x2_t __s0_183 = __p0_183; \
+  int64x2_t __s1_183 = __p1_183; \
+  int32x2_t __rev0_183;  __rev0_183 = __builtin_shufflevector(__s0_183, __s0_183, 1, 0); \
+  int64x2_t __rev1_183;  __rev1_183 = __builtin_shufflevector(__s1_183, __s1_183, 1, 0); \
+  int32x4_t __ret_183; \
+  __ret_183 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_183), (int32x2_t)(__noswap_vqrshrn_n_s64(__rev1_183, __p2_183)))); \
+  __ret_183 = __builtin_shufflevector(__ret_183, __ret_183, 3, 2, 1, 0); \
+  __ret_183; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrn_high_n_s16(__p0_184, __p1_184, __p2_184) __extension__ ({ \
+  int8x8_t __s0_184 = __p0_184; \
+  int16x8_t __s1_184 = __p1_184; \
+  int8x16_t __ret_184; \
+  __ret_184 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_184), (int8x8_t)(vqrshrn_n_s16(__s1_184, __p2_184)))); \
+  __ret_184; \
+})
+#else
+#define vqrshrn_high_n_s16(__p0_185, __p1_185, __p2_185) __extension__ ({ \
+  int8x8_t __s0_185 = __p0_185; \
+  int16x8_t __s1_185 = __p1_185; \
+  int8x8_t __rev0_185;  __rev0_185 = __builtin_shufflevector(__s0_185, __s0_185, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_185;  __rev1_185 = __builtin_shufflevector(__s1_185, __s1_185, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_185; \
+  __ret_185 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_185), (int8x8_t)(__noswap_vqrshrn_n_s16(__rev1_185, __p2_185)))); \
+  __ret_185 = __builtin_shufflevector(__ret_185, __ret_185, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_185; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrns_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqrshrns_n_u32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrns_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqrshrns_n_u32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrnd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqrshrnd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrnd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqrshrnd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrnh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqrshrnh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrnh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqrshrnh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqrshrns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqrshrns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrnd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqrshrnd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrnd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqrshrnd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrnh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqrshrnh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrnh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqrshrnh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_high_n_s32(__p0_186, __p1_186, __p2_186) __extension__ ({ \
+  int16x4_t __s0_186 = __p0_186; \
+  int32x4_t __s1_186 = __p1_186; \
+  int16x8_t __ret_186; \
+  __ret_186 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_186), (int16x4_t)(vqrshrun_n_s32(__s1_186, __p2_186)))); \
+  __ret_186; \
+})
+#else
+#define vqrshrun_high_n_s32(__p0_187, __p1_187, __p2_187) __extension__ ({ \
+  int16x4_t __s0_187 = __p0_187; \
+  int32x4_t __s1_187 = __p1_187; \
+  int16x4_t __rev0_187;  __rev0_187 = __builtin_shufflevector(__s0_187, __s0_187, 3, 2, 1, 0); \
+  int32x4_t __rev1_187;  __rev1_187 = __builtin_shufflevector(__s1_187, __s1_187, 3, 2, 1, 0); \
+  int16x8_t __ret_187; \
+  __ret_187 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_187), (int16x4_t)(__noswap_vqrshrun_n_s32(__rev1_187, __p2_187)))); \
+  __ret_187 = __builtin_shufflevector(__ret_187, __ret_187, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_187; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_high_n_s64(__p0_188, __p1_188, __p2_188) __extension__ ({ \
+  int32x2_t __s0_188 = __p0_188; \
+  int64x2_t __s1_188 = __p1_188; \
+  int32x4_t __ret_188; \
+  __ret_188 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_188), (int32x2_t)(vqrshrun_n_s64(__s1_188, __p2_188)))); \
+  __ret_188; \
+})
+#else
+#define vqrshrun_high_n_s64(__p0_189, __p1_189, __p2_189) __extension__ ({ \
+  int32x2_t __s0_189 = __p0_189; \
+  int64x2_t __s1_189 = __p1_189; \
+  int32x2_t __rev0_189;  __rev0_189 = __builtin_shufflevector(__s0_189, __s0_189, 1, 0); \
+  int64x2_t __rev1_189;  __rev1_189 = __builtin_shufflevector(__s1_189, __s1_189, 1, 0); \
+  int32x4_t __ret_189; \
+  __ret_189 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_189), (int32x2_t)(__noswap_vqrshrun_n_s64(__rev1_189, __p2_189)))); \
+  __ret_189 = __builtin_shufflevector(__ret_189, __ret_189, 3, 2, 1, 0); \
+  __ret_189; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrun_high_n_s16(__p0_190, __p1_190, __p2_190) __extension__ ({ \
+  int8x8_t __s0_190 = __p0_190; \
+  int16x8_t __s1_190 = __p1_190; \
+  int8x16_t __ret_190; \
+  __ret_190 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_190), (int8x8_t)(vqrshrun_n_s16(__s1_190, __p2_190)))); \
+  __ret_190; \
+})
+#else
+#define vqrshrun_high_n_s16(__p0_191, __p1_191, __p2_191) __extension__ ({ \
+  int8x8_t __s0_191 = __p0_191; \
+  int16x8_t __s1_191 = __p1_191; \
+  int8x8_t __rev0_191;  __rev0_191 = __builtin_shufflevector(__s0_191, __s0_191, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_191;  __rev1_191 = __builtin_shufflevector(__s1_191, __s1_191, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_191; \
+  __ret_191 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_191), (int8x8_t)(__noswap_vqrshrun_n_s16(__rev1_191, __p2_191)))); \
+  __ret_191 = __builtin_shufflevector(__ret_191, __ret_191, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_191; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshruns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqrshruns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshruns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqrshruns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrund_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqrshrund_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrund_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqrshrund_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqrshrunh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqrshrunh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqrshrunh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqrshrunh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vqshlb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqshlb_u8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint8_t vqshlb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqshlb_u8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vqshls_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqshls_u32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vqshls_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqshls_u32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vqshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqshld_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vqshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqshld_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vqshlh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqshlh_u16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint16_t vqshlh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqshlh_u16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqshlb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqshlb_s8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int8_t vqshlb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqshlb_s8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqshls_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqshls_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqshls_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqshls_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqshld_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vqshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqshld_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqshlh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqshlh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqshlh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqshlh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlb_n_u8(__p0, __p1) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqshlb_n_u8(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlb_n_u8(__p0, __p1) __extension__ ({ \
+  uint8_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqshlb_n_u8(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshls_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqshls_n_u32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshls_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqshls_n_u32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshld_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vqshld_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshld_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vqshld_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqshlh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqshlh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlb_n_s8(__p0, __p1) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshlb_n_s8(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlb_n_s8(__p0, __p1) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshlb_n_s8(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshls_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshls_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshls_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshls_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshld_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqshld_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshld_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqshld_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshlh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshlh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlub_n_s8(__p0, __p1) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshlub_n_s8(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlub_n_s8(__p0, __p1) __extension__ ({ \
+  int8_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshlub_n_s8(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlus_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshlus_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlus_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshlus_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshlud_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqshlud_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshlud_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vqshlud_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshluh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshluh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshluh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshluh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_u32(__p0_192, __p1_192, __p2_192) __extension__ ({ \
+  uint16x4_t __s0_192 = __p0_192; \
+  uint32x4_t __s1_192 = __p1_192; \
+  uint16x8_t __ret_192; \
+  __ret_192 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_192), (uint16x4_t)(vqshrn_n_u32(__s1_192, __p2_192)))); \
+  __ret_192; \
+})
+#else
+#define vqshrn_high_n_u32(__p0_193, __p1_193, __p2_193) __extension__ ({ \
+  uint16x4_t __s0_193 = __p0_193; \
+  uint32x4_t __s1_193 = __p1_193; \
+  uint16x4_t __rev0_193;  __rev0_193 = __builtin_shufflevector(__s0_193, __s0_193, 3, 2, 1, 0); \
+  uint32x4_t __rev1_193;  __rev1_193 = __builtin_shufflevector(__s1_193, __s1_193, 3, 2, 1, 0); \
+  uint16x8_t __ret_193; \
+  __ret_193 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_193), (uint16x4_t)(__noswap_vqshrn_n_u32(__rev1_193, __p2_193)))); \
+  __ret_193 = __builtin_shufflevector(__ret_193, __ret_193, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_193; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_u64(__p0_194, __p1_194, __p2_194) __extension__ ({ \
+  uint32x2_t __s0_194 = __p0_194; \
+  uint64x2_t __s1_194 = __p1_194; \
+  uint32x4_t __ret_194; \
+  __ret_194 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_194), (uint32x2_t)(vqshrn_n_u64(__s1_194, __p2_194)))); \
+  __ret_194; \
+})
+#else
+#define vqshrn_high_n_u64(__p0_195, __p1_195, __p2_195) __extension__ ({ \
+  uint32x2_t __s0_195 = __p0_195; \
+  uint64x2_t __s1_195 = __p1_195; \
+  uint32x2_t __rev0_195;  __rev0_195 = __builtin_shufflevector(__s0_195, __s0_195, 1, 0); \
+  uint64x2_t __rev1_195;  __rev1_195 = __builtin_shufflevector(__s1_195, __s1_195, 1, 0); \
+  uint32x4_t __ret_195; \
+  __ret_195 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_195), (uint32x2_t)(__noswap_vqshrn_n_u64(__rev1_195, __p2_195)))); \
+  __ret_195 = __builtin_shufflevector(__ret_195, __ret_195, 3, 2, 1, 0); \
+  __ret_195; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_u16(__p0_196, __p1_196, __p2_196) __extension__ ({ \
+  uint8x8_t __s0_196 = __p0_196; \
+  uint16x8_t __s1_196 = __p1_196; \
+  uint8x16_t __ret_196; \
+  __ret_196 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_196), (uint8x8_t)(vqshrn_n_u16(__s1_196, __p2_196)))); \
+  __ret_196; \
+})
+#else
+#define vqshrn_high_n_u16(__p0_197, __p1_197, __p2_197) __extension__ ({ \
+  uint8x8_t __s0_197 = __p0_197; \
+  uint16x8_t __s1_197 = __p1_197; \
+  uint8x8_t __rev0_197;  __rev0_197 = __builtin_shufflevector(__s0_197, __s0_197, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1_197;  __rev1_197 = __builtin_shufflevector(__s1_197, __s1_197, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_197; \
+  __ret_197 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_197), (uint8x8_t)(__noswap_vqshrn_n_u16(__rev1_197, __p2_197)))); \
+  __ret_197 = __builtin_shufflevector(__ret_197, __ret_197, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_197; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_s32(__p0_198, __p1_198, __p2_198) __extension__ ({ \
+  int16x4_t __s0_198 = __p0_198; \
+  int32x4_t __s1_198 = __p1_198; \
+  int16x8_t __ret_198; \
+  __ret_198 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_198), (int16x4_t)(vqshrn_n_s32(__s1_198, __p2_198)))); \
+  __ret_198; \
+})
+#else
+#define vqshrn_high_n_s32(__p0_199, __p1_199, __p2_199) __extension__ ({ \
+  int16x4_t __s0_199 = __p0_199; \
+  int32x4_t __s1_199 = __p1_199; \
+  int16x4_t __rev0_199;  __rev0_199 = __builtin_shufflevector(__s0_199, __s0_199, 3, 2, 1, 0); \
+  int32x4_t __rev1_199;  __rev1_199 = __builtin_shufflevector(__s1_199, __s1_199, 3, 2, 1, 0); \
+  int16x8_t __ret_199; \
+  __ret_199 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_199), (int16x4_t)(__noswap_vqshrn_n_s32(__rev1_199, __p2_199)))); \
+  __ret_199 = __builtin_shufflevector(__ret_199, __ret_199, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_199; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_s64(__p0_200, __p1_200, __p2_200) __extension__ ({ \
+  int32x2_t __s0_200 = __p0_200; \
+  int64x2_t __s1_200 = __p1_200; \
+  int32x4_t __ret_200; \
+  __ret_200 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_200), (int32x2_t)(vqshrn_n_s64(__s1_200, __p2_200)))); \
+  __ret_200; \
+})
+#else
+#define vqshrn_high_n_s64(__p0_201, __p1_201, __p2_201) __extension__ ({ \
+  int32x2_t __s0_201 = __p0_201; \
+  int64x2_t __s1_201 = __p1_201; \
+  int32x2_t __rev0_201;  __rev0_201 = __builtin_shufflevector(__s0_201, __s0_201, 1, 0); \
+  int64x2_t __rev1_201;  __rev1_201 = __builtin_shufflevector(__s1_201, __s1_201, 1, 0); \
+  int32x4_t __ret_201; \
+  __ret_201 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_201), (int32x2_t)(__noswap_vqshrn_n_s64(__rev1_201, __p2_201)))); \
+  __ret_201 = __builtin_shufflevector(__ret_201, __ret_201, 3, 2, 1, 0); \
+  __ret_201; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrn_high_n_s16(__p0_202, __p1_202, __p2_202) __extension__ ({ \
+  int8x8_t __s0_202 = __p0_202; \
+  int16x8_t __s1_202 = __p1_202; \
+  int8x16_t __ret_202; \
+  __ret_202 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_202), (int8x8_t)(vqshrn_n_s16(__s1_202, __p2_202)))); \
+  __ret_202; \
+})
+#else
+#define vqshrn_high_n_s16(__p0_203, __p1_203, __p2_203) __extension__ ({ \
+  int8x8_t __s0_203 = __p0_203; \
+  int16x8_t __s1_203 = __p1_203; \
+  int8x8_t __rev0_203;  __rev0_203 = __builtin_shufflevector(__s0_203, __s0_203, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_203;  __rev1_203 = __builtin_shufflevector(__s1_203, __s1_203, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_203; \
+  __ret_203 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_203), (int8x8_t)(__noswap_vqshrn_n_s16(__rev1_203, __p2_203)))); \
+  __ret_203 = __builtin_shufflevector(__ret_203, __ret_203, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_203; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrns_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqshrns_n_u32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrns_n_u32(__p0, __p1) __extension__ ({ \
+  uint32_t __s0 = __p0; \
+  uint16_t __ret; \
+  __ret = (uint16_t) __builtin_neon_vqshrns_n_u32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrnd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqshrnd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrnd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint32_t __ret; \
+  __ret = (uint32_t) __builtin_neon_vqshrnd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrnh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqshrnh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrnh_n_u16(__p0, __p1) __extension__ ({ \
+  uint16_t __s0 = __p0; \
+  uint8_t __ret; \
+  __ret = (uint8_t) __builtin_neon_vqshrnh_n_u16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshrns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshrns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrnd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshrnd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrnd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshrnd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrnh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshrnh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrnh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshrnh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_high_n_s32(__p0_204, __p1_204, __p2_204) __extension__ ({ \
+  int16x4_t __s0_204 = __p0_204; \
+  int32x4_t __s1_204 = __p1_204; \
+  int16x8_t __ret_204; \
+  __ret_204 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_204), (int16x4_t)(vqshrun_n_s32(__s1_204, __p2_204)))); \
+  __ret_204; \
+})
+#else
+#define vqshrun_high_n_s32(__p0_205, __p1_205, __p2_205) __extension__ ({ \
+  int16x4_t __s0_205 = __p0_205; \
+  int32x4_t __s1_205 = __p1_205; \
+  int16x4_t __rev0_205;  __rev0_205 = __builtin_shufflevector(__s0_205, __s0_205, 3, 2, 1, 0); \
+  int32x4_t __rev1_205;  __rev1_205 = __builtin_shufflevector(__s1_205, __s1_205, 3, 2, 1, 0); \
+  int16x8_t __ret_205; \
+  __ret_205 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_205), (int16x4_t)(__noswap_vqshrun_n_s32(__rev1_205, __p2_205)))); \
+  __ret_205 = __builtin_shufflevector(__ret_205, __ret_205, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_205; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_high_n_s64(__p0_206, __p1_206, __p2_206) __extension__ ({ \
+  int32x2_t __s0_206 = __p0_206; \
+  int64x2_t __s1_206 = __p1_206; \
+  int32x4_t __ret_206; \
+  __ret_206 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_206), (int32x2_t)(vqshrun_n_s64(__s1_206, __p2_206)))); \
+  __ret_206; \
+})
+#else
+#define vqshrun_high_n_s64(__p0_207, __p1_207, __p2_207) __extension__ ({ \
+  int32x2_t __s0_207 = __p0_207; \
+  int64x2_t __s1_207 = __p1_207; \
+  int32x2_t __rev0_207;  __rev0_207 = __builtin_shufflevector(__s0_207, __s0_207, 1, 0); \
+  int64x2_t __rev1_207;  __rev1_207 = __builtin_shufflevector(__s1_207, __s1_207, 1, 0); \
+  int32x4_t __ret_207; \
+  __ret_207 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_207), (int32x2_t)(__noswap_vqshrun_n_s64(__rev1_207, __p2_207)))); \
+  __ret_207 = __builtin_shufflevector(__ret_207, __ret_207, 3, 2, 1, 0); \
+  __ret_207; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrun_high_n_s16(__p0_208, __p1_208, __p2_208) __extension__ ({ \
+  int8x8_t __s0_208 = __p0_208; \
+  int16x8_t __s1_208 = __p1_208; \
+  int8x16_t __ret_208; \
+  __ret_208 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_208), (int8x8_t)(vqshrun_n_s16(__s1_208, __p2_208)))); \
+  __ret_208; \
+})
+#else
+#define vqshrun_high_n_s16(__p0_209, __p1_209, __p2_209) __extension__ ({ \
+  int8x8_t __s0_209 = __p0_209; \
+  int16x8_t __s1_209 = __p1_209; \
+  int8x8_t __rev0_209;  __rev0_209 = __builtin_shufflevector(__s0_209, __s0_209, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_209;  __rev1_209 = __builtin_shufflevector(__s1_209, __s1_209, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_209; \
+  __ret_209 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_209), (int8x8_t)(__noswap_vqshrun_n_s16(__rev1_209, __p2_209)))); \
+  __ret_209 = __builtin_shufflevector(__ret_209, __ret_209, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_209; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshruns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshruns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshruns_n_s32(__p0, __p1) __extension__ ({ \
+  int32_t __s0 = __p0; \
+  int16_t __ret; \
+  __ret = (int16_t) __builtin_neon_vqshruns_n_s32(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrund_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshrund_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrund_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int32_t __ret; \
+  __ret = (int32_t) __builtin_neon_vqshrund_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vqshrunh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshrunh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vqshrunh_n_s16(__p0, __p1) __extension__ ({ \
+  int16_t __s0 = __p0; \
+  int8_t __ret; \
+  __ret = (int8_t) __builtin_neon_vqshrunh_n_s16(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vqsubb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqsubb_u8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint8_t vqsubb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vqsubb_u8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vqsubs_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqsubs_u32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vqsubs_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vqsubs_u32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vqsubd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqsubd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vqsubd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vqsubd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vqsubh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqsubh_u16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint16_t vqsubh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vqsubh_u16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vqsubb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqsubb_s8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int8_t vqsubb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vqsubb_s8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vqsubs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqsubs_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vqsubs_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vqsubs_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vqsubd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqsubd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vqsubd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vqsubd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vqsubh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqsubh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vqsubh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vqsubh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbl1_p8(poly8x16_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__p0, (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbl1_p8(poly8x16_t __p0, uint8x8_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__rev0, (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbl1q_p8(poly8x16_t __p0, uint8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__p0, (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbl1q_p8(poly8x16_t __p0, uint8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbl1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbl1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbl1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbl1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbl1_u8(uint8x16_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbl1_u8(uint8x16_t __p0, uint8x8_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbl1_s8(int8x16_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbl1_s8(int8x16_t __p0, int8x8_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl1_v((int8x16_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbl2_p8(poly8x16x2_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbl2_p8(poly8x16x2_t __p0, uint8x8_t __p1) {
+  poly8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbl2q_p8(poly8x16x2_t __p0, uint8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbl2q_p8(poly8x16x2_t __p0, uint8x16_t __p1) {
+  poly8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev1, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbl2q_u8(uint8x16x2_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbl2q_u8(uint8x16x2_t __p0, uint8x16_t __p1) {
+  uint8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbl2q_s8(int8x16x2_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbl2q_s8(int8x16x2_t __p0, int8x16_t __p1) {
+  int8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl2q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbl2_u8(uint8x16x2_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbl2_u8(uint8x16x2_t __p0, uint8x8_t __p1) {
+  uint8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbl2_s8(int8x16x2_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbl2_s8(int8x16x2_t __p0, int8x8_t __p1) {
+  int8x16x2_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl2_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbl3_p8(poly8x16x3_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbl3_p8(poly8x16x3_t __p0, uint8x8_t __p1) {
+  poly8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbl3q_p8(poly8x16x3_t __p0, uint8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbl3q_p8(poly8x16x3_t __p0, uint8x16_t __p1) {
+  poly8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev1, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbl3q_u8(uint8x16x3_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbl3q_u8(uint8x16x3_t __p0, uint8x16_t __p1) {
+  uint8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbl3q_s8(int8x16x3_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbl3q_s8(int8x16x3_t __p0, int8x16_t __p1) {
+  int8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl3q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbl3_u8(uint8x16x3_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbl3_u8(uint8x16x3_t __p0, uint8x8_t __p1) {
+  uint8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbl3_s8(int8x16x3_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbl3_s8(int8x16x3_t __p0, int8x8_t __p1) {
+  int8x16x3_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl3_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbl4_p8(poly8x16x4_t __p0, uint8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x8_t)__p1, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbl4_p8(poly8x16x4_t __p0, uint8x8_t __p1) {
+  poly8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x8_t)__rev1, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbl4q_p8(poly8x16x4_t __p0, uint8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x16_t)__p1, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbl4q_p8(poly8x16x4_t __p0, uint8x16_t __p1) {
+  poly8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x16_t)__rev1, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbl4q_u8(uint8x16x4_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbl4q_u8(uint8x16x4_t __p0, uint8x16_t __p1) {
+  uint8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbl4q_s8(int8x16x4_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbl4q_s8(int8x16x4_t __p0, int8x16_t __p1) {
+  int8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbl4q_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbl4_u8(uint8x16x4_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbl4_u8(uint8x16x4_t __p0, uint8x8_t __p1) {
+  uint8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbl4_s8(int8x16x4_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__p0.val[0], (int8x16_t)__p0.val[1], (int8x16_t)__p0.val[2], (int8x16_t)__p0.val[3], (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbl4_s8(int8x16x4_t __p0, int8x8_t __p1) {
+  int8x16x4_t __rev0;
+  __rev0.val[0] = __builtin_shufflevector(__p0.val[0], __p0.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[1] = __builtin_shufflevector(__p0.val[1], __p0.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[2] = __builtin_shufflevector(__p0.val[2], __p0.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev0.val[3] = __builtin_shufflevector(__p0.val[3], __p0.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbl4_v((int8x16_t)__rev0.val[0], (int8x16_t)__rev0.val[1], (int8x16_t)__rev0.val[2], (int8x16_t)__rev0.val[3], (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbx1_p8(poly8x8_t __p0, poly8x16_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__p0, (int8x16_t)__p1, (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbx1_p8(poly8x8_t __p0, poly8x16_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbx1q_p8(poly8x16_t __p0, poly8x16_t __p1, uint8x16_t __p2) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbx1q_p8(poly8x16_t __p0, poly8x16_t __p1, uint8x16_t __p2) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbx1q_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbx1q_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbx1q_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__p0, (int8x16_t)__p1, (int8x16_t)__p2, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbx1q_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx1q_v((int8x16_t)__rev0, (int8x16_t)__rev1, (int8x16_t)__rev2, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbx1_u8(uint8x8_t __p0, uint8x16_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__p0, (int8x16_t)__p1, (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbx1_u8(uint8x8_t __p0, uint8x16_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbx1_s8(int8x8_t __p0, int8x16_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__p0, (int8x16_t)__p1, (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbx1_s8(int8x8_t __p0, int8x16_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx1_v((int8x8_t)__rev0, (int8x16_t)__rev1, (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbx2_p8(poly8x8_t __p0, poly8x16x2_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbx2_p8(poly8x8_t __p0, poly8x16x2_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbx2q_p8(poly8x16_t __p0, poly8x16x2_t __p1, uint8x16_t __p2) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p2, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbx2q_p8(poly8x16_t __p0, poly8x16x2_t __p1, uint8x16_t __p2) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev2, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbx2q_u8(uint8x16_t __p0, uint8x16x2_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p2, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbx2q_u8(uint8x16_t __p0, uint8x16x2_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev2, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbx2q_s8(int8x16_t __p0, int8x16x2_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p2, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbx2q_s8(int8x16_t __p0, int8x16x2_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx2q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev2, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbx2_u8(uint8x8_t __p0, uint8x16x2_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbx2_u8(uint8x8_t __p0, uint8x16x2_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbx2_s8(int8x8_t __p0, int8x16x2_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbx2_s8(int8x8_t __p0, int8x16x2_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x2_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx2_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbx3_p8(poly8x8_t __p0, poly8x16x3_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbx3_p8(poly8x8_t __p0, poly8x16x3_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbx3q_p8(poly8x16_t __p0, poly8x16x3_t __p1, uint8x16_t __p2) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p2, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbx3q_p8(poly8x16_t __p0, poly8x16x3_t __p1, uint8x16_t __p2) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev2, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbx3q_u8(uint8x16_t __p0, uint8x16x3_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p2, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbx3q_u8(uint8x16_t __p0, uint8x16x3_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev2, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbx3q_s8(int8x16_t __p0, int8x16x3_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p2, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbx3q_s8(int8x16_t __p0, int8x16x3_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx3q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev2, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbx3_u8(uint8x8_t __p0, uint8x16x3_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbx3_u8(uint8x8_t __p0, uint8x16x3_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbx3_s8(int8x8_t __p0, int8x16x3_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbx3_s8(int8x8_t __p0, int8x16x3_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x3_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx3_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vqtbx4_p8(poly8x8_t __p0, poly8x16x4_t __p1, uint8x8_t __p2) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x8_t)__p2, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vqtbx4_p8(poly8x8_t __p0, poly8x16x4_t __p1, uint8x8_t __p2) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x8_t)__rev2, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vqtbx4q_p8(poly8x16_t __p0, poly8x16x4_t __p1, uint8x16_t __p2) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x16_t)__p2, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vqtbx4q_p8(poly8x16_t __p0, poly8x16x4_t __p1, uint8x16_t __p2) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x16_t)__rev2, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vqtbx4q_u8(uint8x16_t __p0, uint8x16x4_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x16_t)__p2, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vqtbx4q_u8(uint8x16_t __p0, uint8x16x4_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x16_t)__rev2, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vqtbx4q_s8(int8x16_t __p0, int8x16x4_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x16_t)__p2, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vqtbx4q_s8(int8x16_t __p0, int8x16x4_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vqtbx4q_v((int8x16_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x16_t)__rev2, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vqtbx4_u8(uint8x8_t __p0, uint8x16x4_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x8_t)__p2, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vqtbx4_u8(uint8x8_t __p0, uint8x16x4_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x8_t)__rev2, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vqtbx4_s8(int8x8_t __p0, int8x16x4_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__p0, (int8x16_t)__p1.val[0], (int8x16_t)__p1.val[1], (int8x16_t)__p1.val[2], (int8x16_t)__p1.val[3], (int8x8_t)__p2, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vqtbx4_s8(int8x8_t __p0, int8x16x4_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16x4_t __rev1;
+  __rev1.val[0] = __builtin_shufflevector(__p1.val[0], __p1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[1] = __builtin_shufflevector(__p1.val[1], __p1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[2] = __builtin_shufflevector(__p1.val[2], __p1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  __rev1.val[3] = __builtin_shufflevector(__p1.val[3], __p1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vqtbx4_v((int8x8_t)__rev0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], (int8x8_t)__rev2, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vraddhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vraddhn_u32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vraddhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vraddhn_u32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vraddhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vraddhn_u64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vraddhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vraddhn_u64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vraddhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vraddhn_u16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint8x16_t vraddhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vraddhn_u16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vraddhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vraddhn_s32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vraddhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vraddhn_s32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vraddhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vraddhn_s64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vraddhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vraddhn_s64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vraddhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vraddhn_s16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int8x16_t vraddhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vraddhn_s16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vrbit_p8(poly8x8_t __p0) {
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vrbit_v((int8x8_t)__p0, 4);
+  return __ret;
+}
+#else
+__ai poly8x8_t vrbit_p8(poly8x8_t __p0) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = (poly8x8_t) __builtin_neon_vrbit_v((int8x8_t)__rev0, 4);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vrbitq_p8(poly8x16_t __p0) {
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__p0, 36);
+  return __ret;
+}
+#else
+__ai poly8x16_t vrbitq_p8(poly8x16_t __p0) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = (poly8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__rev0, 36);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrbitq_u8(uint8x16_t __p0) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__p0, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vrbitq_u8(uint8x16_t __p0) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__rev0, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrbitq_s8(int8x16_t __p0) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__p0, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vrbitq_s8(int8x16_t __p0) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vrbitq_v((int8x16_t)__rev0, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vrbit_u8(uint8x8_t __p0) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrbit_v((int8x8_t)__p0, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vrbit_u8(uint8x8_t __p0) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vrbit_v((int8x8_t)__rev0, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vrbit_s8(int8x8_t __p0) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrbit_v((int8x8_t)__p0, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vrbit_s8(int8x8_t __p0) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vrbit_v((int8x8_t)__rev0, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrecpeq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrecpeq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrecpeq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrecpeq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrecpe_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrecpe_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrecpe_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrecpe_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vrecped_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecped_f64(__p0);
+  return __ret;
+}
+#else
+__ai float64_t vrecped_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecped_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vrecpes_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpes_f32(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vrecpes_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpes_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrecpsq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrecpsq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrecpsq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrecpsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrecps_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrecps_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrecps_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrecps_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vrecpsd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecpsd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float64_t vrecpsd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecpsd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vrecpss_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpss_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float32_t vrecpss_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpss_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vrecpxd_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecpxd_f64(__p0);
+  return __ret;
+}
+#else
+__ai float64_t vrecpxd_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrecpxd_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vrecpxs_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpxs_f32(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vrecpxs_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrecpxs_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrnd_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrnd_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrnd_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrnd_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrnd_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrnd_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrnd_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrnd_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndaq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndaq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndaq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndaq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndaq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndaq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndaq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndaq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrnda_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrnda_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrnda_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrnda_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrnda_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrnda_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrnda_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrnda_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndiq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndiq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndiq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndiq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndiq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndiq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndiq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndiq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrndi_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndi_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrndi_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndi_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrndi_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndi_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrndi_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndi_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndmq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndmq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndmq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndmq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndmq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndmq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndmq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndmq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrndm_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndm_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrndm_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndm_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrndm_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndm_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrndm_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndm_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndnq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndnq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndnq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndnq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndnq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndnq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndnq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndnq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrndn_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndn_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrndn_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndn_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrndn_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndn_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrndn_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndn_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndpq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndpq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndpq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndpq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndpq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndpq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndpq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndpq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrndp_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndp_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrndp_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndp_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrndp_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndp_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrndp_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndp_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrndxq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndxq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrndxq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrndxq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vrndxq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndxq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vrndxq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vrndxq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrndx_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndx_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrndx_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrndx_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vrndx_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndx_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vrndx_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vrndx_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vrshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vrshld_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vrshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vrshld_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vrshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vrshld_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vrshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vrshld_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vrshrd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vrshrd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vrshrd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vrshrd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vrshrd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vrshrd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_u32(__p0_210, __p1_210, __p2_210) __extension__ ({ \
+  uint16x4_t __s0_210 = __p0_210; \
+  uint32x4_t __s1_210 = __p1_210; \
+  uint16x8_t __ret_210; \
+  __ret_210 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_210), (uint16x4_t)(vrshrn_n_u32(__s1_210, __p2_210)))); \
+  __ret_210; \
+})
+#else
+#define vrshrn_high_n_u32(__p0_211, __p1_211, __p2_211) __extension__ ({ \
+  uint16x4_t __s0_211 = __p0_211; \
+  uint32x4_t __s1_211 = __p1_211; \
+  uint16x4_t __rev0_211;  __rev0_211 = __builtin_shufflevector(__s0_211, __s0_211, 3, 2, 1, 0); \
+  uint32x4_t __rev1_211;  __rev1_211 = __builtin_shufflevector(__s1_211, __s1_211, 3, 2, 1, 0); \
+  uint16x8_t __ret_211; \
+  __ret_211 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_211), (uint16x4_t)(__noswap_vrshrn_n_u32(__rev1_211, __p2_211)))); \
+  __ret_211 = __builtin_shufflevector(__ret_211, __ret_211, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_211; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_u64(__p0_212, __p1_212, __p2_212) __extension__ ({ \
+  uint32x2_t __s0_212 = __p0_212; \
+  uint64x2_t __s1_212 = __p1_212; \
+  uint32x4_t __ret_212; \
+  __ret_212 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_212), (uint32x2_t)(vrshrn_n_u64(__s1_212, __p2_212)))); \
+  __ret_212; \
+})
+#else
+#define vrshrn_high_n_u64(__p0_213, __p1_213, __p2_213) __extension__ ({ \
+  uint32x2_t __s0_213 = __p0_213; \
+  uint64x2_t __s1_213 = __p1_213; \
+  uint32x2_t __rev0_213;  __rev0_213 = __builtin_shufflevector(__s0_213, __s0_213, 1, 0); \
+  uint64x2_t __rev1_213;  __rev1_213 = __builtin_shufflevector(__s1_213, __s1_213, 1, 0); \
+  uint32x4_t __ret_213; \
+  __ret_213 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_213), (uint32x2_t)(__noswap_vrshrn_n_u64(__rev1_213, __p2_213)))); \
+  __ret_213 = __builtin_shufflevector(__ret_213, __ret_213, 3, 2, 1, 0); \
+  __ret_213; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_u16(__p0_214, __p1_214, __p2_214) __extension__ ({ \
+  uint8x8_t __s0_214 = __p0_214; \
+  uint16x8_t __s1_214 = __p1_214; \
+  uint8x16_t __ret_214; \
+  __ret_214 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_214), (uint8x8_t)(vrshrn_n_u16(__s1_214, __p2_214)))); \
+  __ret_214; \
+})
+#else
+#define vrshrn_high_n_u16(__p0_215, __p1_215, __p2_215) __extension__ ({ \
+  uint8x8_t __s0_215 = __p0_215; \
+  uint16x8_t __s1_215 = __p1_215; \
+  uint8x8_t __rev0_215;  __rev0_215 = __builtin_shufflevector(__s0_215, __s0_215, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1_215;  __rev1_215 = __builtin_shufflevector(__s1_215, __s1_215, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_215; \
+  __ret_215 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_215), (uint8x8_t)(__noswap_vrshrn_n_u16(__rev1_215, __p2_215)))); \
+  __ret_215 = __builtin_shufflevector(__ret_215, __ret_215, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_215; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_s32(__p0_216, __p1_216, __p2_216) __extension__ ({ \
+  int16x4_t __s0_216 = __p0_216; \
+  int32x4_t __s1_216 = __p1_216; \
+  int16x8_t __ret_216; \
+  __ret_216 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_216), (int16x4_t)(vrshrn_n_s32(__s1_216, __p2_216)))); \
+  __ret_216; \
+})
+#else
+#define vrshrn_high_n_s32(__p0_217, __p1_217, __p2_217) __extension__ ({ \
+  int16x4_t __s0_217 = __p0_217; \
+  int32x4_t __s1_217 = __p1_217; \
+  int16x4_t __rev0_217;  __rev0_217 = __builtin_shufflevector(__s0_217, __s0_217, 3, 2, 1, 0); \
+  int32x4_t __rev1_217;  __rev1_217 = __builtin_shufflevector(__s1_217, __s1_217, 3, 2, 1, 0); \
+  int16x8_t __ret_217; \
+  __ret_217 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_217), (int16x4_t)(__noswap_vrshrn_n_s32(__rev1_217, __p2_217)))); \
+  __ret_217 = __builtin_shufflevector(__ret_217, __ret_217, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_217; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_s64(__p0_218, __p1_218, __p2_218) __extension__ ({ \
+  int32x2_t __s0_218 = __p0_218; \
+  int64x2_t __s1_218 = __p1_218; \
+  int32x4_t __ret_218; \
+  __ret_218 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_218), (int32x2_t)(vrshrn_n_s64(__s1_218, __p2_218)))); \
+  __ret_218; \
+})
+#else
+#define vrshrn_high_n_s64(__p0_219, __p1_219, __p2_219) __extension__ ({ \
+  int32x2_t __s0_219 = __p0_219; \
+  int64x2_t __s1_219 = __p1_219; \
+  int32x2_t __rev0_219;  __rev0_219 = __builtin_shufflevector(__s0_219, __s0_219, 1, 0); \
+  int64x2_t __rev1_219;  __rev1_219 = __builtin_shufflevector(__s1_219, __s1_219, 1, 0); \
+  int32x4_t __ret_219; \
+  __ret_219 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_219), (int32x2_t)(__noswap_vrshrn_n_s64(__rev1_219, __p2_219)))); \
+  __ret_219 = __builtin_shufflevector(__ret_219, __ret_219, 3, 2, 1, 0); \
+  __ret_219; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrshrn_high_n_s16(__p0_220, __p1_220, __p2_220) __extension__ ({ \
+  int8x8_t __s0_220 = __p0_220; \
+  int16x8_t __s1_220 = __p1_220; \
+  int8x16_t __ret_220; \
+  __ret_220 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_220), (int8x8_t)(vrshrn_n_s16(__s1_220, __p2_220)))); \
+  __ret_220; \
+})
+#else
+#define vrshrn_high_n_s16(__p0_221, __p1_221, __p2_221) __extension__ ({ \
+  int8x8_t __s0_221 = __p0_221; \
+  int16x8_t __s1_221 = __p1_221; \
+  int8x8_t __rev0_221;  __rev0_221 = __builtin_shufflevector(__s0_221, __s0_221, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_221;  __rev1_221 = __builtin_shufflevector(__s1_221, __s1_221, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_221; \
+  __ret_221 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_221), (int8x8_t)(__noswap_vrshrn_n_s16(__rev1_221, __p2_221)))); \
+  __ret_221 = __builtin_shufflevector(__ret_221, __ret_221, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_221; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrsqrteq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrsqrteq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrsqrteq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrsqrteq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrsqrte_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrsqrte_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrsqrte_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrsqrte_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vrsqrted_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrsqrted_f64(__p0);
+  return __ret;
+}
+#else
+__ai float64_t vrsqrted_f64(float64_t __p0) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrsqrted_f64(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vrsqrtes_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrsqrtes_f32(__p0);
+  return __ret;
+}
+#else
+__ai float32_t vrsqrtes_f32(float32_t __p0) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrsqrtes_f32(__p0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vrsqrtsq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__p0, (int8x16_t)__p1, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vrsqrtsq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vrsqrtsq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vrsqrts_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrsqrts_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vrsqrts_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vrsqrts_v((int8x8_t)__p0, (int8x8_t)__p1, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64_t vrsqrtsd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrsqrtsd_f64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float64_t vrsqrtsd_f64(float64_t __p0, float64_t __p1) {
+  float64_t __ret;
+  __ret = (float64_t) __builtin_neon_vrsqrtsd_f64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32_t vrsqrtss_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrsqrtss_f32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai float32_t vrsqrtss_f32(float32_t __p0, float32_t __p1) {
+  float32_t __ret;
+  __ret = (float32_t) __builtin_neon_vrsqrtss_f32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsrad_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vrsrad_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vrsrad_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vrsrad_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vrsrad_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vrsrad_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vrsrad_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vrsrad_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vrsubhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vrsubhn_u32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vrsubhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vrsubhn_u32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vrsubhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vrsubhn_u64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vrsubhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vrsubhn_u64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vrsubhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vrsubhn_u16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint8x16_t vrsubhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vrsubhn_u16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vrsubhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vrsubhn_s32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vrsubhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vrsubhn_s32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vrsubhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vrsubhn_s64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vrsubhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vrsubhn_s64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vrsubhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vrsubhn_s16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int8x16_t vrsubhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vrsubhn_s16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_f16(__p0_222, __p1_222, __p2_222) __extension__ ({ \
+  float16_t __s0_222 = __p0_222; \
+  float16x4_t __s1_222 = __p1_222; \
+  float16x4_t __ret_222; \
+float16_t __reint_222 = __s0_222; \
+float16x4_t __reint1_222 = __s1_222; \
+int16x4_t __reint2_222 = vset_lane_s16(*(int16_t *) &__reint_222, *(int16x4_t *) &__reint1_222, __p2_222); \
+  __ret_222 = *(float16x4_t *) &__reint2_222; \
+  __ret_222; \
+})
+#else
+#define vset_lane_f16(__p0_223, __p1_223, __p2_223) __extension__ ({ \
+  float16_t __s0_223 = __p0_223; \
+  float16x4_t __s1_223 = __p1_223; \
+  float16x4_t __rev1_223;  __rev1_223 = __builtin_shufflevector(__s1_223, __s1_223, 3, 2, 1, 0); \
+  float16x4_t __ret_223; \
+float16_t __reint_223 = __s0_223; \
+float16x4_t __reint1_223 = __rev1_223; \
+int16x4_t __reint2_223 = __noswap_vset_lane_s16(*(int16_t *) &__reint_223, *(int16x4_t *) &__reint1_223, __p2_223); \
+  __ret_223 = *(float16x4_t *) &__reint2_223; \
+  __ret_223 = __builtin_shufflevector(__ret_223, __ret_223, 3, 2, 1, 0); \
+  __ret_223; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_f16(__p0_224, __p1_224, __p2_224) __extension__ ({ \
+  float16_t __s0_224 = __p0_224; \
+  float16x8_t __s1_224 = __p1_224; \
+  float16x8_t __ret_224; \
+float16_t __reint_224 = __s0_224; \
+float16x8_t __reint1_224 = __s1_224; \
+int16x8_t __reint2_224 = vsetq_lane_s16(*(int16_t *) &__reint_224, *(int16x8_t *) &__reint1_224, __p2_224); \
+  __ret_224 = *(float16x8_t *) &__reint2_224; \
+  __ret_224; \
+})
+#else
+#define vsetq_lane_f16(__p0_225, __p1_225, __p2_225) __extension__ ({ \
+  float16_t __s0_225 = __p0_225; \
+  float16x8_t __s1_225 = __p1_225; \
+  float16x8_t __rev1_225;  __rev1_225 = __builtin_shufflevector(__s1_225, __s1_225, 7, 6, 5, 4, 3, 2, 1, 0); \
+  float16x8_t __ret_225; \
+float16_t __reint_225 = __s0_225; \
+float16x8_t __reint1_225 = __rev1_225; \
+int16x8_t __reint2_225 = __noswap_vsetq_lane_s16(*(int16_t *) &__reint_225, *(int16x8_t *) &__reint1_225, __p2_225); \
+  __ret_225 = *(float16x8_t *) &__reint2_225; \
+  __ret_225 = __builtin_shufflevector(__ret_225, __ret_225, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_225; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#define __noswap_vset_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vset_lane_i64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsetq_lane_i64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsetq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vsetq_lane_f64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vsetq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vsetq_lane_f64(__s0, (int8x16_t)__rev1, __p2); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#define __noswap_vsetq_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __ret; \
+  __ret = (float64x2_t) __builtin_neon_vsetq_lane_f64(__s0, (int8x16_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vset_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vset_lane_f64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#else
+#define vset_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vset_lane_f64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#define __noswap_vset_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64_t __s0 = __p0; \
+  float64x1_t __s1 = __p1; \
+  float64x1_t __ret; \
+  __ret = (float64x1_t) __builtin_neon_vset_lane_f64(__s0, (int8x8_t)__s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vshld_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vshld_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vshld_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vshld_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vshld_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vshld_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshld_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vshld_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vshld_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vshld_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshld_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vshld_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vshld_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vshld_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_u8(__p0_226, __p1_226) __extension__ ({ \
+  uint8x16_t __s0_226 = __p0_226; \
+  uint16x8_t __ret_226; \
+  __ret_226 = (uint16x8_t)(vshll_n_u8(vget_high_u8(__s0_226), __p1_226)); \
+  __ret_226; \
+})
+#else
+#define vshll_high_n_u8(__p0_227, __p1_227) __extension__ ({ \
+  uint8x16_t __s0_227 = __p0_227; \
+  uint8x16_t __rev0_227;  __rev0_227 = __builtin_shufflevector(__s0_227, __s0_227, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __ret_227; \
+  __ret_227 = (uint16x8_t)(__noswap_vshll_n_u8(__noswap_vget_high_u8(__rev0_227), __p1_227)); \
+  __ret_227 = __builtin_shufflevector(__ret_227, __ret_227, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_227; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_u32(__p0_228, __p1_228) __extension__ ({ \
+  uint32x4_t __s0_228 = __p0_228; \
+  uint64x2_t __ret_228; \
+  __ret_228 = (uint64x2_t)(vshll_n_u32(vget_high_u32(__s0_228), __p1_228)); \
+  __ret_228; \
+})
+#else
+#define vshll_high_n_u32(__p0_229, __p1_229) __extension__ ({ \
+  uint32x4_t __s0_229 = __p0_229; \
+  uint32x4_t __rev0_229;  __rev0_229 = __builtin_shufflevector(__s0_229, __s0_229, 3, 2, 1, 0); \
+  uint64x2_t __ret_229; \
+  __ret_229 = (uint64x2_t)(__noswap_vshll_n_u32(__noswap_vget_high_u32(__rev0_229), __p1_229)); \
+  __ret_229 = __builtin_shufflevector(__ret_229, __ret_229, 1, 0); \
+  __ret_229; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_u16(__p0_230, __p1_230) __extension__ ({ \
+  uint16x8_t __s0_230 = __p0_230; \
+  uint32x4_t __ret_230; \
+  __ret_230 = (uint32x4_t)(vshll_n_u16(vget_high_u16(__s0_230), __p1_230)); \
+  __ret_230; \
+})
+#else
+#define vshll_high_n_u16(__p0_231, __p1_231) __extension__ ({ \
+  uint16x8_t __s0_231 = __p0_231; \
+  uint16x8_t __rev0_231;  __rev0_231 = __builtin_shufflevector(__s0_231, __s0_231, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint32x4_t __ret_231; \
+  __ret_231 = (uint32x4_t)(__noswap_vshll_n_u16(__noswap_vget_high_u16(__rev0_231), __p1_231)); \
+  __ret_231 = __builtin_shufflevector(__ret_231, __ret_231, 3, 2, 1, 0); \
+  __ret_231; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_s8(__p0_232, __p1_232) __extension__ ({ \
+  int8x16_t __s0_232 = __p0_232; \
+  int16x8_t __ret_232; \
+  __ret_232 = (int16x8_t)(vshll_n_s8(vget_high_s8(__s0_232), __p1_232)); \
+  __ret_232; \
+})
+#else
+#define vshll_high_n_s8(__p0_233, __p1_233) __extension__ ({ \
+  int8x16_t __s0_233 = __p0_233; \
+  int8x16_t __rev0_233;  __rev0_233 = __builtin_shufflevector(__s0_233, __s0_233, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __ret_233; \
+  __ret_233 = (int16x8_t)(__noswap_vshll_n_s8(__noswap_vget_high_s8(__rev0_233), __p1_233)); \
+  __ret_233 = __builtin_shufflevector(__ret_233, __ret_233, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_233; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_s32(__p0_234, __p1_234) __extension__ ({ \
+  int32x4_t __s0_234 = __p0_234; \
+  int64x2_t __ret_234; \
+  __ret_234 = (int64x2_t)(vshll_n_s32(vget_high_s32(__s0_234), __p1_234)); \
+  __ret_234; \
+})
+#else
+#define vshll_high_n_s32(__p0_235, __p1_235) __extension__ ({ \
+  int32x4_t __s0_235 = __p0_235; \
+  int32x4_t __rev0_235;  __rev0_235 = __builtin_shufflevector(__s0_235, __s0_235, 3, 2, 1, 0); \
+  int64x2_t __ret_235; \
+  __ret_235 = (int64x2_t)(__noswap_vshll_n_s32(__noswap_vget_high_s32(__rev0_235), __p1_235)); \
+  __ret_235 = __builtin_shufflevector(__ret_235, __ret_235, 1, 0); \
+  __ret_235; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshll_high_n_s16(__p0_236, __p1_236) __extension__ ({ \
+  int16x8_t __s0_236 = __p0_236; \
+  int32x4_t __ret_236; \
+  __ret_236 = (int32x4_t)(vshll_n_s16(vget_high_s16(__s0_236), __p1_236)); \
+  __ret_236; \
+})
+#else
+#define vshll_high_n_s16(__p0_237, __p1_237) __extension__ ({ \
+  int16x8_t __s0_237 = __p0_237; \
+  int16x8_t __rev0_237;  __rev0_237 = __builtin_shufflevector(__s0_237, __s0_237, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int32x4_t __ret_237; \
+  __ret_237 = (int32x4_t)(__noswap_vshll_n_s16(__noswap_vget_high_s16(__rev0_237), __p1_237)); \
+  __ret_237 = __builtin_shufflevector(__ret_237, __ret_237, 3, 2, 1, 0); \
+  __ret_237; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vshrd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vshrd_n_u64(__p0, __p1) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vshrd_n_u64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vshrd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#else
+#define vshrd_n_s64(__p0, __p1) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vshrd_n_s64(__s0, __p1); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_u32(__p0_238, __p1_238, __p2_238) __extension__ ({ \
+  uint16x4_t __s0_238 = __p0_238; \
+  uint32x4_t __s1_238 = __p1_238; \
+  uint16x8_t __ret_238; \
+  __ret_238 = (uint16x8_t)(vcombine_u16((uint16x4_t)(__s0_238), (uint16x4_t)(vshrn_n_u32(__s1_238, __p2_238)))); \
+  __ret_238; \
+})
+#else
+#define vshrn_high_n_u32(__p0_239, __p1_239, __p2_239) __extension__ ({ \
+  uint16x4_t __s0_239 = __p0_239; \
+  uint32x4_t __s1_239 = __p1_239; \
+  uint16x4_t __rev0_239;  __rev0_239 = __builtin_shufflevector(__s0_239, __s0_239, 3, 2, 1, 0); \
+  uint32x4_t __rev1_239;  __rev1_239 = __builtin_shufflevector(__s1_239, __s1_239, 3, 2, 1, 0); \
+  uint16x8_t __ret_239; \
+  __ret_239 = (uint16x8_t)(__noswap_vcombine_u16((uint16x4_t)(__rev0_239), (uint16x4_t)(__noswap_vshrn_n_u32(__rev1_239, __p2_239)))); \
+  __ret_239 = __builtin_shufflevector(__ret_239, __ret_239, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_239; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_u64(__p0_240, __p1_240, __p2_240) __extension__ ({ \
+  uint32x2_t __s0_240 = __p0_240; \
+  uint64x2_t __s1_240 = __p1_240; \
+  uint32x4_t __ret_240; \
+  __ret_240 = (uint32x4_t)(vcombine_u32((uint32x2_t)(__s0_240), (uint32x2_t)(vshrn_n_u64(__s1_240, __p2_240)))); \
+  __ret_240; \
+})
+#else
+#define vshrn_high_n_u64(__p0_241, __p1_241, __p2_241) __extension__ ({ \
+  uint32x2_t __s0_241 = __p0_241; \
+  uint64x2_t __s1_241 = __p1_241; \
+  uint32x2_t __rev0_241;  __rev0_241 = __builtin_shufflevector(__s0_241, __s0_241, 1, 0); \
+  uint64x2_t __rev1_241;  __rev1_241 = __builtin_shufflevector(__s1_241, __s1_241, 1, 0); \
+  uint32x4_t __ret_241; \
+  __ret_241 = (uint32x4_t)(__noswap_vcombine_u32((uint32x2_t)(__rev0_241), (uint32x2_t)(__noswap_vshrn_n_u64(__rev1_241, __p2_241)))); \
+  __ret_241 = __builtin_shufflevector(__ret_241, __ret_241, 3, 2, 1, 0); \
+  __ret_241; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_u16(__p0_242, __p1_242, __p2_242) __extension__ ({ \
+  uint8x8_t __s0_242 = __p0_242; \
+  uint16x8_t __s1_242 = __p1_242; \
+  uint8x16_t __ret_242; \
+  __ret_242 = (uint8x16_t)(vcombine_u8((uint8x8_t)(__s0_242), (uint8x8_t)(vshrn_n_u16(__s1_242, __p2_242)))); \
+  __ret_242; \
+})
+#else
+#define vshrn_high_n_u16(__p0_243, __p1_243, __p2_243) __extension__ ({ \
+  uint8x8_t __s0_243 = __p0_243; \
+  uint16x8_t __s1_243 = __p1_243; \
+  uint8x8_t __rev0_243;  __rev0_243 = __builtin_shufflevector(__s0_243, __s0_243, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint16x8_t __rev1_243;  __rev1_243 = __builtin_shufflevector(__s1_243, __s1_243, 7, 6, 5, 4, 3, 2, 1, 0); \
+  uint8x16_t __ret_243; \
+  __ret_243 = (uint8x16_t)(__noswap_vcombine_u8((uint8x8_t)(__rev0_243), (uint8x8_t)(__noswap_vshrn_n_u16(__rev1_243, __p2_243)))); \
+  __ret_243 = __builtin_shufflevector(__ret_243, __ret_243, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_243; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_s32(__p0_244, __p1_244, __p2_244) __extension__ ({ \
+  int16x4_t __s0_244 = __p0_244; \
+  int32x4_t __s1_244 = __p1_244; \
+  int16x8_t __ret_244; \
+  __ret_244 = (int16x8_t)(vcombine_s16((int16x4_t)(__s0_244), (int16x4_t)(vshrn_n_s32(__s1_244, __p2_244)))); \
+  __ret_244; \
+})
+#else
+#define vshrn_high_n_s32(__p0_245, __p1_245, __p2_245) __extension__ ({ \
+  int16x4_t __s0_245 = __p0_245; \
+  int32x4_t __s1_245 = __p1_245; \
+  int16x4_t __rev0_245;  __rev0_245 = __builtin_shufflevector(__s0_245, __s0_245, 3, 2, 1, 0); \
+  int32x4_t __rev1_245;  __rev1_245 = __builtin_shufflevector(__s1_245, __s1_245, 3, 2, 1, 0); \
+  int16x8_t __ret_245; \
+  __ret_245 = (int16x8_t)(__noswap_vcombine_s16((int16x4_t)(__rev0_245), (int16x4_t)(__noswap_vshrn_n_s32(__rev1_245, __p2_245)))); \
+  __ret_245 = __builtin_shufflevector(__ret_245, __ret_245, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_245; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_s64(__p0_246, __p1_246, __p2_246) __extension__ ({ \
+  int32x2_t __s0_246 = __p0_246; \
+  int64x2_t __s1_246 = __p1_246; \
+  int32x4_t __ret_246; \
+  __ret_246 = (int32x4_t)(vcombine_s32((int32x2_t)(__s0_246), (int32x2_t)(vshrn_n_s64(__s1_246, __p2_246)))); \
+  __ret_246; \
+})
+#else
+#define vshrn_high_n_s64(__p0_247, __p1_247, __p2_247) __extension__ ({ \
+  int32x2_t __s0_247 = __p0_247; \
+  int64x2_t __s1_247 = __p1_247; \
+  int32x2_t __rev0_247;  __rev0_247 = __builtin_shufflevector(__s0_247, __s0_247, 1, 0); \
+  int64x2_t __rev1_247;  __rev1_247 = __builtin_shufflevector(__s1_247, __s1_247, 1, 0); \
+  int32x4_t __ret_247; \
+  __ret_247 = (int32x4_t)(__noswap_vcombine_s32((int32x2_t)(__rev0_247), (int32x2_t)(__noswap_vshrn_n_s64(__rev1_247, __p2_247)))); \
+  __ret_247 = __builtin_shufflevector(__ret_247, __ret_247, 3, 2, 1, 0); \
+  __ret_247; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vshrn_high_n_s16(__p0_248, __p1_248, __p2_248) __extension__ ({ \
+  int8x8_t __s0_248 = __p0_248; \
+  int16x8_t __s1_248 = __p1_248; \
+  int8x16_t __ret_248; \
+  __ret_248 = (int8x16_t)(vcombine_s8((int8x8_t)(__s0_248), (int8x8_t)(vshrn_n_s16(__s1_248, __p2_248)))); \
+  __ret_248; \
+})
+#else
+#define vshrn_high_n_s16(__p0_249, __p1_249, __p2_249) __extension__ ({ \
+  int8x8_t __s0_249 = __p0_249; \
+  int16x8_t __s1_249 = __p1_249; \
+  int8x8_t __rev0_249;  __rev0_249 = __builtin_shufflevector(__s0_249, __s0_249, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int16x8_t __rev1_249;  __rev1_249 = __builtin_shufflevector(__s1_249, __s1_249, 7, 6, 5, 4, 3, 2, 1, 0); \
+  int8x16_t __ret_249; \
+  __ret_249 = (int8x16_t)(__noswap_vcombine_s8((int8x8_t)(__rev0_249), (int8x8_t)(__noswap_vshrn_n_s16(__rev1_249, __p2_249)))); \
+  __ret_249 = __builtin_shufflevector(__ret_249, __ret_249, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __ret_249; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vslid_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vslid_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vslid_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vslid_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vslid_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vslid_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vslid_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vslid_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsli_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#else
+#define vsli_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vsli_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsliq_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 38); \
+  __ret; \
+})
+#else
+#define vsliq_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsliq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8_t vsqaddb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vsqaddb_u8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint8_t vsqaddb_u8(uint8_t __p0, uint8_t __p1) {
+  uint8_t __ret;
+  __ret = (uint8_t) __builtin_neon_vsqaddb_u8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32_t vsqadds_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vsqadds_u32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint32_t vsqadds_u32(uint32_t __p0, uint32_t __p1) {
+  uint32_t __ret;
+  __ret = (uint32_t) __builtin_neon_vsqadds_u32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vsqaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vsqaddd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vsqaddd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vsqaddd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16_t vsqaddh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vsqaddh_u16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint16_t vsqaddh_u16(uint16_t __p0, uint16_t __p1) {
+  uint16_t __ret;
+  __ret = (uint16_t) __builtin_neon_vsqaddh_u16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vsqaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vsqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 48);
+  return __ret;
+}
+#else
+__ai uint8x16_t vsqaddq_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = (uint8x16_t) __builtin_neon_vsqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 48);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsqaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 50);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsqaddq_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t) __builtin_neon_vsqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 50);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsqaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vsqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vsqaddq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vsqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsqaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vsqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 49);
+  return __ret;
+}
+#else
+__ai uint16x8_t vsqaddq_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t) __builtin_neon_vsqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 49);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vsqadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vsqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 16);
+  return __ret;
+}
+#else
+__ai uint8x8_t vsqadd_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = (uint8x8_t) __builtin_neon_vsqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 16);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vsqadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vsqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 18);
+  return __ret;
+}
+#else
+__ai uint32x2_t vsqadd_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = (uint32x2_t) __builtin_neon_vsqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 18);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vsqadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vsqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vsqadd_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vsqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vsqadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vsqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 17);
+  return __ret;
+}
+#else
+__ai uint16x4_t vsqadd_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = (uint16x4_t) __builtin_neon_vsqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 17);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vsqrtq_f64(float64x2_t __p0) {
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vsqrtq_v((int8x16_t)__p0, 42);
+  return __ret;
+}
+#else
+__ai float64x2_t vsqrtq_f64(float64x2_t __p0) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __ret;
+  __ret = (float64x2_t) __builtin_neon_vsqrtq_v((int8x16_t)__rev0, 42);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vsqrtq_f32(float32x4_t __p0) {
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vsqrtq_v((int8x16_t)__p0, 41);
+  return __ret;
+}
+#else
+__ai float32x4_t vsqrtq_f32(float32x4_t __p0) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = (float32x4_t) __builtin_neon_vsqrtq_v((int8x16_t)__rev0, 41);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vsqrt_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vsqrt_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#else
+__ai float64x1_t vsqrt_f64(float64x1_t __p0) {
+  float64x1_t __ret;
+  __ret = (float64x1_t) __builtin_neon_vsqrt_v((int8x8_t)__p0, 10);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vsqrt_f32(float32x2_t __p0) {
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vsqrt_v((int8x8_t)__p0, 9);
+  return __ret;
+}
+#else
+__ai float32x2_t vsqrt_f32(float32x2_t __p0) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __ret;
+  __ret = (float32x2_t) __builtin_neon_vsqrt_v((int8x8_t)__rev0, 9);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsrad_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vsrad_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vsrad_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vsrad_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsrad_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vsrad_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vsrad_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vsrad_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsrid_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vsrid_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vsrid_n_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64_t __s0 = __p0; \
+  uint64_t __s1 = __p1; \
+  uint64_t __ret; \
+  __ret = (uint64_t) __builtin_neon_vsrid_n_u64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsrid_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vsrid_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#else
+#define vsrid_n_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64_t __s0 = __p0; \
+  int64_t __s1 = __p1; \
+  int64_t __ret; \
+  __ret = (int64_t) __builtin_neon_vsrid_n_s64(__s0, __s1, __p2); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsri_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#else
+#define vsri_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s0 = __p0; \
+  poly64x1_t __s1 = __p1; \
+  poly64x1_t __ret; \
+  __ret = (poly64x1_t) __builtin_neon_vsri_n_v((int8x8_t)__s0, (int8x8_t)__s1, __p2, 6); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vsriq_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__s0, (int8x16_t)__s1, __p2, 38); \
+  __ret; \
+})
+#else
+#define vsriq_n_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s0 = __p0; \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  poly64x2_t __ret; \
+  __ret = (poly64x2_t) __builtin_neon_vsriq_n_v((int8x16_t)__rev0, (int8x16_t)__rev1, __p2, 38); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 6); \
+})
+#else
+#define vst1_p64(__p0, __p1) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 38); \
+})
+#else
+#define vst1q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__s1, 42); \
+})
+#else
+#define vst1q_f64(__p0, __p1) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_v(__p0, (int8x16_t)__rev1, 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 10); \
+})
+#else
+#define vst1_f64(__p0, __p1) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_v(__p0, (int8x8_t)__s1, 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 6); \
+})
+#else
+#define vst1_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 38); \
+})
+#else
+#define vst1q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2_t __s1 = __p1; \
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__s1, __p2, 42); \
+})
+#else
+#define vst1q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2_t __s1 = __p1; \
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  __builtin_neon_vst1q_lane_v(__p0, (int8x16_t)__rev1, __p2, 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 10); \
+})
+#else
+#define vst1_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1_t __s1 = __p1; \
+  __builtin_neon_vst1_lane_v(__p0, (int8x8_t)__s1, __p2, 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p8_x2(__p0, __p1) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 4); \
+})
+#else
+#define vst1_p8_x2(__p0, __p1) __extension__ ({ \
+  poly8x8x2_t __s1 = __p1; \
+  poly8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p64_x2(__p0, __p1) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 6); \
+})
+#else
+#define vst1_p64_x2(__p0, __p1) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p16_x2(__p0, __p1) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 5); \
+})
+#else
+#define vst1_p16_x2(__p0, __p1) __extension__ ({ \
+  poly16x4x2_t __s1 = __p1; \
+  poly16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p8_x2(__p0, __p1) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 36); \
+})
+#else
+#define vst1q_p8_x2(__p0, __p1) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  poly8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p64_x2(__p0, __p1) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 38); \
+})
+#else
+#define vst1q_p64_x2(__p0, __p1) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  poly64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p16_x2(__p0, __p1) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 37); \
+})
+#else
+#define vst1q_p16_x2(__p0, __p1) __extension__ ({ \
+  poly16x8x2_t __s1 = __p1; \
+  poly16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u8_x2(__p0, __p1) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 48); \
+})
+#else
+#define vst1q_u8_x2(__p0, __p1) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  uint8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u32_x2(__p0, __p1) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 50); \
+})
+#else
+#define vst1q_u32_x2(__p0, __p1) __extension__ ({ \
+  uint32x4x2_t __s1 = __p1; \
+  uint32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u64_x2(__p0, __p1) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 51); \
+})
+#else
+#define vst1q_u64_x2(__p0, __p1) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  uint64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u16_x2(__p0, __p1) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 49); \
+})
+#else
+#define vst1q_u16_x2(__p0, __p1) __extension__ ({ \
+  uint16x8x2_t __s1 = __p1; \
+  uint16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s8_x2(__p0, __p1) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 32); \
+})
+#else
+#define vst1q_s8_x2(__p0, __p1) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  int8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f64_x2(__p0, __p1) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 42); \
+})
+#else
+#define vst1q_f64_x2(__p0, __p1) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  float64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f32_x2(__p0, __p1) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 41); \
+})
+#else
+#define vst1q_f32_x2(__p0, __p1) __extension__ ({ \
+  float32x4x2_t __s1 = __p1; \
+  float32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f16_x2(__p0, __p1) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 40); \
+})
+#else
+#define vst1q_f16_x2(__p0, __p1) __extension__ ({ \
+  float16x8x2_t __s1 = __p1; \
+  float16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s32_x2(__p0, __p1) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 34); \
+})
+#else
+#define vst1q_s32_x2(__p0, __p1) __extension__ ({ \
+  int32x4x2_t __s1 = __p1; \
+  int32x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s64_x2(__p0, __p1) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 35); \
+})
+#else
+#define vst1q_s64_x2(__p0, __p1) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  int64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s16_x2(__p0, __p1) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1q_x2_v(__p0, __s1.val[0], __s1.val[1], 33); \
+})
+#else
+#define vst1q_s16_x2(__p0, __p1) __extension__ ({ \
+  int16x8x2_t __s1 = __p1; \
+  int16x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x2_v(__p0, __rev1.val[0], __rev1.val[1], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u8_x2(__p0, __p1) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 16); \
+})
+#else
+#define vst1_u8_x2(__p0, __p1) __extension__ ({ \
+  uint8x8x2_t __s1 = __p1; \
+  uint8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u32_x2(__p0, __p1) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 18); \
+})
+#else
+#define vst1_u32_x2(__p0, __p1) __extension__ ({ \
+  uint32x2x2_t __s1 = __p1; \
+  uint32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u64_x2(__p0, __p1) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 19); \
+})
+#else
+#define vst1_u64_x2(__p0, __p1) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u16_x2(__p0, __p1) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 17); \
+})
+#else
+#define vst1_u16_x2(__p0, __p1) __extension__ ({ \
+  uint16x4x2_t __s1 = __p1; \
+  uint16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s8_x2(__p0, __p1) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 0); \
+})
+#else
+#define vst1_s8_x2(__p0, __p1) __extension__ ({ \
+  int8x8x2_t __s1 = __p1; \
+  int8x8x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f64_x2(__p0, __p1) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 10); \
+})
+#else
+#define vst1_f64_x2(__p0, __p1) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f32_x2(__p0, __p1) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 9); \
+})
+#else
+#define vst1_f32_x2(__p0, __p1) __extension__ ({ \
+  float32x2x2_t __s1 = __p1; \
+  float32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, __rev1.val[0], __rev1.val[1], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f16_x2(__p0, __p1) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 8); \
+})
+#else
+#define vst1_f16_x2(__p0, __p1) __extension__ ({ \
+  float16x4x2_t __s1 = __p1; \
+  float16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, __rev1.val[0], __rev1.val[1], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s32_x2(__p0, __p1) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 2); \
+})
+#else
+#define vst1_s32_x2(__p0, __p1) __extension__ ({ \
+  int32x2x2_t __s1 = __p1; \
+  int32x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, __rev1.val[0], __rev1.val[1], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s64_x2(__p0, __p1) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 3); \
+})
+#else
+#define vst1_s64_x2(__p0, __p1) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s16_x2(__p0, __p1) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  __builtin_neon_vst1_x2_v(__p0, __s1.val[0], __s1.val[1], 1); \
+})
+#else
+#define vst1_s16_x2(__p0, __p1) __extension__ ({ \
+  int16x4x2_t __s1 = __p1; \
+  int16x4x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x2_v(__p0, __rev1.val[0], __rev1.val[1], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p8_x3(__p0, __p1) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 4); \
+})
+#else
+#define vst1_p8_x3(__p0, __p1) __extension__ ({ \
+  poly8x8x3_t __s1 = __p1; \
+  poly8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p64_x3(__p0, __p1) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 6); \
+})
+#else
+#define vst1_p64_x3(__p0, __p1) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p16_x3(__p0, __p1) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 5); \
+})
+#else
+#define vst1_p16_x3(__p0, __p1) __extension__ ({ \
+  poly16x4x3_t __s1 = __p1; \
+  poly16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p8_x3(__p0, __p1) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 36); \
+})
+#else
+#define vst1q_p8_x3(__p0, __p1) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  poly8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p64_x3(__p0, __p1) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 38); \
+})
+#else
+#define vst1q_p64_x3(__p0, __p1) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  poly64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p16_x3(__p0, __p1) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 37); \
+})
+#else
+#define vst1q_p16_x3(__p0, __p1) __extension__ ({ \
+  poly16x8x3_t __s1 = __p1; \
+  poly16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u8_x3(__p0, __p1) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 48); \
+})
+#else
+#define vst1q_u8_x3(__p0, __p1) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  uint8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u32_x3(__p0, __p1) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 50); \
+})
+#else
+#define vst1q_u32_x3(__p0, __p1) __extension__ ({ \
+  uint32x4x3_t __s1 = __p1; \
+  uint32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u64_x3(__p0, __p1) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 51); \
+})
+#else
+#define vst1q_u64_x3(__p0, __p1) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  uint64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u16_x3(__p0, __p1) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 49); \
+})
+#else
+#define vst1q_u16_x3(__p0, __p1) __extension__ ({ \
+  uint16x8x3_t __s1 = __p1; \
+  uint16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s8_x3(__p0, __p1) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 32); \
+})
+#else
+#define vst1q_s8_x3(__p0, __p1) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  int8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f64_x3(__p0, __p1) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 42); \
+})
+#else
+#define vst1q_f64_x3(__p0, __p1) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  float64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f32_x3(__p0, __p1) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 41); \
+})
+#else
+#define vst1q_f32_x3(__p0, __p1) __extension__ ({ \
+  float32x4x3_t __s1 = __p1; \
+  float32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f16_x3(__p0, __p1) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 40); \
+})
+#else
+#define vst1q_f16_x3(__p0, __p1) __extension__ ({ \
+  float16x8x3_t __s1 = __p1; \
+  float16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s32_x3(__p0, __p1) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 34); \
+})
+#else
+#define vst1q_s32_x3(__p0, __p1) __extension__ ({ \
+  int32x4x3_t __s1 = __p1; \
+  int32x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s64_x3(__p0, __p1) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 35); \
+})
+#else
+#define vst1q_s64_x3(__p0, __p1) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  int64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s16_x3(__p0, __p1) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1q_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 33); \
+})
+#else
+#define vst1q_s16_x3(__p0, __p1) __extension__ ({ \
+  int16x8x3_t __s1 = __p1; \
+  int16x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u8_x3(__p0, __p1) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 16); \
+})
+#else
+#define vst1_u8_x3(__p0, __p1) __extension__ ({ \
+  uint8x8x3_t __s1 = __p1; \
+  uint8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u32_x3(__p0, __p1) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 18); \
+})
+#else
+#define vst1_u32_x3(__p0, __p1) __extension__ ({ \
+  uint32x2x3_t __s1 = __p1; \
+  uint32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u64_x3(__p0, __p1) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 19); \
+})
+#else
+#define vst1_u64_x3(__p0, __p1) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u16_x3(__p0, __p1) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 17); \
+})
+#else
+#define vst1_u16_x3(__p0, __p1) __extension__ ({ \
+  uint16x4x3_t __s1 = __p1; \
+  uint16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s8_x3(__p0, __p1) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 0); \
+})
+#else
+#define vst1_s8_x3(__p0, __p1) __extension__ ({ \
+  int8x8x3_t __s1 = __p1; \
+  int8x8x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f64_x3(__p0, __p1) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 10); \
+})
+#else
+#define vst1_f64_x3(__p0, __p1) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f32_x3(__p0, __p1) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 9); \
+})
+#else
+#define vst1_f32_x3(__p0, __p1) __extension__ ({ \
+  float32x2x3_t __s1 = __p1; \
+  float32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f16_x3(__p0, __p1) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 8); \
+})
+#else
+#define vst1_f16_x3(__p0, __p1) __extension__ ({ \
+  float16x4x3_t __s1 = __p1; \
+  float16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s32_x3(__p0, __p1) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 2); \
+})
+#else
+#define vst1_s32_x3(__p0, __p1) __extension__ ({ \
+  int32x2x3_t __s1 = __p1; \
+  int32x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s64_x3(__p0, __p1) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 3); \
+})
+#else
+#define vst1_s64_x3(__p0, __p1) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s16_x3(__p0, __p1) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  __builtin_neon_vst1_x3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 1); \
+})
+#else
+#define vst1_s16_x3(__p0, __p1) __extension__ ({ \
+  int16x4x3_t __s1 = __p1; \
+  int16x4x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x3_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p8_x4(__p0, __p1) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 4); \
+})
+#else
+#define vst1_p8_x4(__p0, __p1) __extension__ ({ \
+  poly8x8x4_t __s1 = __p1; \
+  poly8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 4); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p64_x4(__p0, __p1) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 6); \
+})
+#else
+#define vst1_p64_x4(__p0, __p1) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_p16_x4(__p0, __p1) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 5); \
+})
+#else
+#define vst1_p16_x4(__p0, __p1) __extension__ ({ \
+  poly16x4x4_t __s1 = __p1; \
+  poly16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 5); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p8_x4(__p0, __p1) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 36); \
+})
+#else
+#define vst1q_p8_x4(__p0, __p1) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  poly8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p64_x4(__p0, __p1) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 38); \
+})
+#else
+#define vst1q_p64_x4(__p0, __p1) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  poly64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_p16_x4(__p0, __p1) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 37); \
+})
+#else
+#define vst1q_p16_x4(__p0, __p1) __extension__ ({ \
+  poly16x8x4_t __s1 = __p1; \
+  poly16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 37); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u8_x4(__p0, __p1) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 48); \
+})
+#else
+#define vst1q_u8_x4(__p0, __p1) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  uint8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u32_x4(__p0, __p1) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 50); \
+})
+#else
+#define vst1q_u32_x4(__p0, __p1) __extension__ ({ \
+  uint32x4x4_t __s1 = __p1; \
+  uint32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 50); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u64_x4(__p0, __p1) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 51); \
+})
+#else
+#define vst1q_u64_x4(__p0, __p1) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  uint64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_u16_x4(__p0, __p1) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 49); \
+})
+#else
+#define vst1q_u16_x4(__p0, __p1) __extension__ ({ \
+  uint16x8x4_t __s1 = __p1; \
+  uint16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 49); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s8_x4(__p0, __p1) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 32); \
+})
+#else
+#define vst1q_s8_x4(__p0, __p1) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  int8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f64_x4(__p0, __p1) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 42); \
+})
+#else
+#define vst1q_f64_x4(__p0, __p1) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  float64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f32_x4(__p0, __p1) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 41); \
+})
+#else
+#define vst1q_f32_x4(__p0, __p1) __extension__ ({ \
+  float32x4x4_t __s1 = __p1; \
+  float32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 41); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_f16_x4(__p0, __p1) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 40); \
+})
+#else
+#define vst1q_f16_x4(__p0, __p1) __extension__ ({ \
+  float16x8x4_t __s1 = __p1; \
+  float16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 40); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s32_x4(__p0, __p1) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 34); \
+})
+#else
+#define vst1q_s32_x4(__p0, __p1) __extension__ ({ \
+  int32x4x4_t __s1 = __p1; \
+  int32x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 34); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s64_x4(__p0, __p1) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 35); \
+})
+#else
+#define vst1q_s64_x4(__p0, __p1) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  int64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1q_s16_x4(__p0, __p1) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1q_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 33); \
+})
+#else
+#define vst1q_s16_x4(__p0, __p1) __extension__ ({ \
+  int16x8x4_t __s1 = __p1; \
+  int16x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1q_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 33); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u8_x4(__p0, __p1) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 16); \
+})
+#else
+#define vst1_u8_x4(__p0, __p1) __extension__ ({ \
+  uint8x8x4_t __s1 = __p1; \
+  uint8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 16); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u32_x4(__p0, __p1) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 18); \
+})
+#else
+#define vst1_u32_x4(__p0, __p1) __extension__ ({ \
+  uint32x2x4_t __s1 = __p1; \
+  uint32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 18); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u64_x4(__p0, __p1) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 19); \
+})
+#else
+#define vst1_u64_x4(__p0, __p1) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_u16_x4(__p0, __p1) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 17); \
+})
+#else
+#define vst1_u16_x4(__p0, __p1) __extension__ ({ \
+  uint16x4x4_t __s1 = __p1; \
+  uint16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 17); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s8_x4(__p0, __p1) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 0); \
+})
+#else
+#define vst1_s8_x4(__p0, __p1) __extension__ ({ \
+  int8x8x4_t __s1 = __p1; \
+  int8x8x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, (int8x8_t)__rev1.val[0], (int8x8_t)__rev1.val[1], (int8x8_t)__rev1.val[2], (int8x8_t)__rev1.val[3], 0); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f64_x4(__p0, __p1) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 10); \
+})
+#else
+#define vst1_f64_x4(__p0, __p1) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f32_x4(__p0, __p1) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 9); \
+})
+#else
+#define vst1_f32_x4(__p0, __p1) __extension__ ({ \
+  float32x2x4_t __s1 = __p1; \
+  float32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 9); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_f16_x4(__p0, __p1) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 8); \
+})
+#else
+#define vst1_f16_x4(__p0, __p1) __extension__ ({ \
+  float16x4x4_t __s1 = __p1; \
+  float16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 8); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s32_x4(__p0, __p1) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 2); \
+})
+#else
+#define vst1_s32_x4(__p0, __p1) __extension__ ({ \
+  int32x2x4_t __s1 = __p1; \
+  int32x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 2); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s64_x4(__p0, __p1) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 3); \
+})
+#else
+#define vst1_s64_x4(__p0, __p1) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst1_s16_x4(__p0, __p1) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  __builtin_neon_vst1_x4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 1); \
+})
+#else
+#define vst1_s16_x4(__p0, __p1) __extension__ ({ \
+  int16x4x4_t __s1 = __p1; \
+  int16x4x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 3, 2, 1, 0); \
+  __builtin_neon_vst1_x4_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 6); \
+})
+#else
+#define vst2_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 38); \
+})
+#else
+#define vst2q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  poly64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], 51); \
+})
+#else
+#define vst2q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  uint64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 42); \
+})
+#else
+#define vst2q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  float64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_v(__p0, __s1.val[0], __s1.val[1], 35); \
+})
+#else
+#define vst2q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  int64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_v(__p0, __rev1.val[0], __rev1.val[1], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_f64(__p0, __p1) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 10); \
+})
+#else
+#define vst2_f64(__p0, __p1) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_v(__p0, __s1.val[0], __s1.val[1], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 6); \
+})
+#else
+#define vst2_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 36); \
+})
+#else
+#define vst2q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x2_t __s1 = __p1; \
+  poly8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 38); \
+})
+#else
+#define vst2q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x2_t __s1 = __p1; \
+  poly64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 48); \
+})
+#else
+#define vst2q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x2_t __s1 = __p1; \
+  uint8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 51); \
+})
+#else
+#define vst2q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x2_t __s1 = __p1; \
+  uint64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], __p2, 32); \
+})
+#else
+#define vst2q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x2_t __s1 = __p1; \
+  int8x16x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], __p2, 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 42); \
+})
+#else
+#define vst2q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x2_t __s1 = __p1; \
+  float64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  __builtin_neon_vst2q_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 35); \
+})
+#else
+#define vst2q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x2_t __s1 = __p1; \
+  int64x2x2_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __builtin_neon_vst2q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __p2, 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 19); \
+})
+#else
+#define vst2_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], __p2, 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 10); \
+})
+#else
+#define vst2_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst2_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 3); \
+})
+#else
+#define vst2_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x2_t __s1 = __p1; \
+  __builtin_neon_vst2_lane_v(__p0, __s1.val[0], __s1.val[1], __p2, 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 6); \
+})
+#else
+#define vst3_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 38); \
+})
+#else
+#define vst3q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  poly64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], 51); \
+})
+#else
+#define vst3q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  uint64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 42); \
+})
+#else
+#define vst3q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  float64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 35); \
+})
+#else
+#define vst3q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  int64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_f64(__p0, __p1) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 10); \
+})
+#else
+#define vst3_f64(__p0, __p1) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 6); \
+})
+#else
+#define vst3_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 36); \
+})
+#else
+#define vst3q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x3_t __s1 = __p1; \
+  poly8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 38); \
+})
+#else
+#define vst3q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x3_t __s1 = __p1; \
+  poly64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 48); \
+})
+#else
+#define vst3q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x3_t __s1 = __p1; \
+  uint8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 51); \
+})
+#else
+#define vst3q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x3_t __s1 = __p1; \
+  uint64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], __p2, 32); \
+})
+#else
+#define vst3q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x3_t __s1 = __p1; \
+  int8x16x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], __p2, 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 42); \
+})
+#else
+#define vst3q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x3_t __s1 = __p1; \
+  float64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  __builtin_neon_vst3q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 35); \
+})
+#else
+#define vst3q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x3_t __s1 = __p1; \
+  int64x2x3_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __builtin_neon_vst3q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __p2, 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 19); \
+})
+#else
+#define vst3_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], __p2, 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 10); \
+})
+#else
+#define vst3_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst3_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 3); \
+})
+#else
+#define vst3_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x3_t __s1 = __p1; \
+  __builtin_neon_vst3_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __p2, 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 6); \
+})
+#else
+#define vst4_p64(__p0, __p1) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 38); \
+})
+#else
+#define vst4q_p64(__p0, __p1) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  poly64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], 51); \
+})
+#else
+#define vst4q_u64(__p0, __p1) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  uint64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 42); \
+})
+#else
+#define vst4q_f64(__p0, __p1) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  float64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 35); \
+})
+#else
+#define vst4q_s64(__p0, __p1) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  int64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_f64(__p0, __p1) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 10); \
+})
+#else
+#define vst4_f64(__p0, __p1) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 6); \
+})
+#else
+#define vst4_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 6); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 36); \
+})
+#else
+#define vst4q_lane_p8(__p0, __p1, __p2) __extension__ ({ \
+  poly8x16x4_t __s1 = __p1; \
+  poly8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 36); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 38); \
+})
+#else
+#define vst4q_lane_p64(__p0, __p1, __p2) __extension__ ({ \
+  poly64x2x4_t __s1 = __p1; \
+  poly64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 38); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 48); \
+})
+#else
+#define vst4q_lane_u8(__p0, __p1, __p2) __extension__ ({ \
+  uint8x16x4_t __s1 = __p1; \
+  uint8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 48); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 51); \
+})
+#else
+#define vst4q_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x2x4_t __s1 = __p1; \
+  uint64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 51); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__s1.val[0], (int8x16_t)__s1.val[1], (int8x16_t)__s1.val[2], (int8x16_t)__s1.val[3], __p2, 32); \
+})
+#else
+#define vst4q_lane_s8(__p0, __p1, __p2) __extension__ ({ \
+  int8x16x4_t __s1 = __p1; \
+  int8x16x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, (int8x16_t)__rev1.val[0], (int8x16_t)__rev1.val[1], (int8x16_t)__rev1.val[2], (int8x16_t)__rev1.val[3], __p2, 32); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 42); \
+})
+#else
+#define vst4q_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x2x4_t __s1 = __p1; \
+  float64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 42); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  __builtin_neon_vst4q_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 35); \
+})
+#else
+#define vst4q_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x2x4_t __s1 = __p1; \
+  int64x2x4_t __rev1; \
+  __rev1.val[0] = __builtin_shufflevector(__s1.val[0], __s1.val[0], 1, 0); \
+  __rev1.val[1] = __builtin_shufflevector(__s1.val[1], __s1.val[1], 1, 0); \
+  __rev1.val[2] = __builtin_shufflevector(__s1.val[2], __s1.val[2], 1, 0); \
+  __rev1.val[3] = __builtin_shufflevector(__s1.val[3], __s1.val[3], 1, 0); \
+  __builtin_neon_vst4q_lane_v(__p0, __rev1.val[0], __rev1.val[1], __rev1.val[2], __rev1.val[3], __p2, 35); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 19); \
+})
+#else
+#define vst4_lane_u64(__p0, __p1, __p2) __extension__ ({ \
+  uint64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, (int8x8_t)__s1.val[0], (int8x8_t)__s1.val[1], (int8x8_t)__s1.val[2], (int8x8_t)__s1.val[3], __p2, 19); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 10); \
+})
+#else
+#define vst4_lane_f64(__p0, __p1, __p2) __extension__ ({ \
+  float64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 10); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vst4_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 3); \
+})
+#else
+#define vst4_lane_s64(__p0, __p1, __p2) __extension__ ({ \
+  int64x1x4_t __s1 = __p1; \
+  __builtin_neon_vst4_lane_v(__p0, __s1.val[0], __s1.val[1], __s1.val[2], __s1.val[3], __p2, 3); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vstrq_p128(__p0, __p1) __extension__ ({ \
+  poly128_t __s1 = __p1; \
+  __builtin_neon_vstrq_p128(__p0, __s1); \
+})
+#else
+#define vstrq_p128(__p0, __p1) __extension__ ({ \
+  poly128_t __s1 = __p1; \
+  __builtin_neon_vstrq_p128(__p0, __s1); \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vsubd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vsubd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vsubd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vsubd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vsubd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vsubd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vsubd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vsubd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vsubq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai float64x2_t vsubq_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __rev0 - __rev1;
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x1_t vsub_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#else
+__ai float64x1_t vsub_f64(float64x1_t __p0, float64x1_t __p1) {
+  float64x1_t __ret;
+  __ret = __p0 - __p1;
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x8_t __ret;
+  __ret = vcombine_u16(__p0, vsubhn_u32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubhn_high_u32(uint16x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vcombine_u16(__rev0, __noswap_vsubhn_u32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x4_t __ret;
+  __ret = vcombine_u32(__p0, vsubhn_u64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubhn_high_u64(uint32x2_t __p0, uint64x2_t __p1, uint64x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vcombine_u32(__rev0, __noswap_vsubhn_u64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vsubhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x16_t __ret;
+  __ret = vcombine_u8(__p0, vsubhn_u16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai uint8x16_t vsubhn_high_u16(uint8x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __noswap_vcombine_u8(__rev0, __noswap_vsubhn_u16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x8_t __ret;
+  __ret = vcombine_s16(__p0, vsubhn_s32(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vsubhn_high_s32(int16x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vcombine_s16(__rev0, __noswap_vsubhn_s32(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x4_t __ret;
+  __ret = vcombine_s32(__p0, vsubhn_s64(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vsubhn_high_s64(int32x2_t __p0, int64x2_t __p1, int64x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vcombine_s32(__rev0, __noswap_vsubhn_s64(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vsubhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x16_t __ret;
+  __ret = vcombine_s8(__p0, vsubhn_s16(__p1, __p2));
+  return __ret;
+}
+#else
+__ai int8x16_t vsubhn_high_s16(int8x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __noswap_vcombine_s8(__rev0, __noswap_vsubhn_s16(__rev1, __rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = vmovl_high_u8(__p0) - vmovl_high_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmovl_high_u8(__rev0) - __noswap_vmovl_high_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsubl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmovl_high_u32(__p0) - vmovl_high_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vsubl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmovl_high_u32(__rev0) - __noswap_vmovl_high_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmovl_high_u16(__p0) - vmovl_high_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmovl_high_u16(__rev0) - __noswap_vmovl_high_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = vmovl_high_s8(__p0) - vmovl_high_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vsubl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmovl_high_s8(__rev0) - __noswap_vmovl_high_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vsubl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = vmovl_high_s32(__p0) - vmovl_high_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vsubl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmovl_high_s32(__rev0) - __noswap_vmovl_high_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = vmovl_high_s16(__p0) - vmovl_high_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vsubl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmovl_high_s16(__rev0) - __noswap_vmovl_high_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vsubw_high_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 - vmovl_high_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vsubw_high_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vsubw_high_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 - vmovl_high_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vsubw_high_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vsubw_high_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 - vmovl_high_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vsubw_high_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vsubw_high_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 - vmovl_high_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vsubw_high_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vsubw_high_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 - vmovl_high_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vsubw_high_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vsubw_high_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 - vmovl_high_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vsubw_high_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __noswap_vmovl_high_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtrn1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtrn1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vtrn1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai poly16x4_t vtrn1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vtrn1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  return __ret;
+}
+#else
+__ai poly8x16_t vtrn1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vtrn1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai poly64x2_t vtrn1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vtrn1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai poly16x8_t vtrn1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vtrn1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  return __ret;
+}
+#else
+__ai uint8x16_t vtrn1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vtrn1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai uint32x4_t vtrn1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vtrn1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vtrn1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vtrn1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai uint16x8_t vtrn1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vtrn1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  return __ret;
+}
+#else
+__ai int8x16_t vtrn1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vtrn1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float64x2_t vtrn1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vtrn1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai float32x4_t vtrn1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vtrn1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai int32x4_t vtrn1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vtrn1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int64x2_t vtrn1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vtrn1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai int16x8_t vtrn1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtrn1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtrn1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vtrn1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint32x2_t vtrn1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vtrn1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai uint16x4_t vtrn1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtrn1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 2, 10, 4, 12, 6, 14);
+  return __ret;
+}
+#else
+__ai int8x8_t vtrn1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 2, 10, 4, 12, 6, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vtrn1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float32x2_t vtrn1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vtrn1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vtrn1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vtrn1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 2, 6);
+  return __ret;
+}
+#else
+__ai int16x4_t vtrn1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 2, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vtrn2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai poly8x8_t vtrn2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vtrn2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai poly16x4_t vtrn2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vtrn2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  return __ret;
+}
+#else
+__ai poly8x16_t vtrn2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vtrn2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai poly64x2_t vtrn2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vtrn2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai poly16x8_t vtrn2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vtrn2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  return __ret;
+}
+#else
+__ai uint8x16_t vtrn2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vtrn2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai uint32x4_t vtrn2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vtrn2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint64x2_t vtrn2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vtrn2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai uint16x8_t vtrn2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vtrn2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  return __ret;
+}
+#else
+__ai int8x16_t vtrn2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vtrn2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float64x2_t vtrn2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vtrn2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai float32x4_t vtrn2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vtrn2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai int32x4_t vtrn2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vtrn2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int64x2_t vtrn2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vtrn2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai int16x8_t vtrn2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vtrn2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai uint8x8_t vtrn2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vtrn2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint32x2_t vtrn2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vtrn2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai uint16x4_t vtrn2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vtrn2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 9, 3, 11, 5, 13, 7, 15);
+  return __ret;
+}
+#else
+__ai int8x8_t vtrn2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 9, 3, 11, 5, 13, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vtrn2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float32x2_t vtrn2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vtrn2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int32x2_t vtrn2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vtrn2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 5, 3, 7);
+  return __ret;
+}
+#else
+__ai int16x4_t vtrn2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 5, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vtst_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vtst_p64(poly64x1_t __p0, poly64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vtstq_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vtstq_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vtstq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vtstq_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vtstq_s64(int64x2_t __p0, int64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__p0, (int8x16_t)__p1, 51);
+  return __ret;
+}
+#else
+__ai uint64x2_t vtstq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t) __builtin_neon_vtstq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 51);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vtst_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vtst_u64(uint64x1_t __p0, uint64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x1_t vtst_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#else
+__ai uint64x1_t vtst_s64(int64x1_t __p0, int64x1_t __p1) {
+  uint64x1_t __ret;
+  __ret = (uint64x1_t) __builtin_neon_vtst_v((int8x8_t)__p0, (int8x8_t)__p1, 19);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64_t vtstd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vtstd_u64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai uint64_t vtstd_u64(uint64_t __p0, uint64_t __p1) {
+  uint64_t __ret;
+  __ret = (uint64_t) __builtin_neon_vtstd_u64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vtstd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vtstd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vtstd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vtstd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8_t vuqaddb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vuqaddb_s8(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int8_t vuqaddb_s8(int8_t __p0, int8_t __p1) {
+  int8_t __ret;
+  __ret = (int8_t) __builtin_neon_vuqaddb_s8(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32_t vuqadds_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vuqadds_s32(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int32_t vuqadds_s32(int32_t __p0, int32_t __p1) {
+  int32_t __ret;
+  __ret = (int32_t) __builtin_neon_vuqadds_s32(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64_t vuqaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vuqaddd_s64(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int64_t vuqaddd_s64(int64_t __p0, int64_t __p1) {
+  int64_t __ret;
+  __ret = (int64_t) __builtin_neon_vuqaddd_s64(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16_t vuqaddh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vuqaddh_s16(__p0, __p1);
+  return __ret;
+}
+#else
+__ai int16_t vuqaddh_s16(int16_t __p0, int16_t __p1) {
+  int16_t __ret;
+  __ret = (int16_t) __builtin_neon_vuqaddh_s16(__p0, __p1);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vuqaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vuqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 32);
+  return __ret;
+}
+#else
+__ai int8x16_t vuqaddq_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = (int8x16_t) __builtin_neon_vuqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 32);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vuqaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vuqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 34);
+  return __ret;
+}
+#else
+__ai int32x4_t vuqaddq_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t) __builtin_neon_vuqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 34);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vuqaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vuqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 35);
+  return __ret;
+}
+#else
+__ai int64x2_t vuqaddq_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t) __builtin_neon_vuqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 35);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vuqaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vuqaddq_v((int8x16_t)__p0, (int8x16_t)__p1, 33);
+  return __ret;
+}
+#else
+__ai int16x8_t vuqaddq_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t) __builtin_neon_vuqaddq_v((int8x16_t)__rev0, (int8x16_t)__rev1, 33);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vuqadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vuqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 0);
+  return __ret;
+}
+#else
+__ai int8x8_t vuqadd_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = (int8x8_t) __builtin_neon_vuqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 0);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vuqadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vuqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vuqadd_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = (int32x2_t) __builtin_neon_vuqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x1_t vuqadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vuqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#else
+__ai int64x1_t vuqadd_s64(int64x1_t __p0, int64x1_t __p1) {
+  int64x1_t __ret;
+  __ret = (int64x1_t) __builtin_neon_vuqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 3);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vuqadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vuqadd_v((int8x8_t)__p0, (int8x8_t)__p1, 1);
+  return __ret;
+}
+#else
+__ai int16x4_t vuqadd_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = (int16x4_t) __builtin_neon_vuqadd_v((int8x8_t)__rev0, (int8x8_t)__rev1, 1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vuzp1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai poly8x8_t vuzp1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vuzp1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai poly16x4_t vuzp1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vuzp1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  return __ret;
+}
+#else
+__ai poly8x16_t vuzp1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vuzp1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai poly64x2_t vuzp1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vuzp1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai poly16x8_t vuzp1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vuzp1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  return __ret;
+}
+#else
+__ai uint8x16_t vuzp1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vuzp1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai uint32x4_t vuzp1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vuzp1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vuzp1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vuzp1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai uint16x8_t vuzp1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vuzp1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  return __ret;
+}
+#else
+__ai int8x16_t vuzp1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vuzp1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float64x2_t vuzp1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vuzp1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai float32x4_t vuzp1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vuzp1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai int32x4_t vuzp1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vuzp1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int64x2_t vuzp1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vuzp1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai int16x8_t vuzp1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vuzp1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai uint8x8_t vuzp1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vuzp1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint32x2_t vuzp1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vuzp1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai uint16x4_t vuzp1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vuzp1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6, 8, 10, 12, 14);
+  return __ret;
+}
+#else
+__ai int8x8_t vuzp1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6, 8, 10, 12, 14);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vuzp1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float32x2_t vuzp1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vuzp1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vuzp1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vuzp1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2, 4, 6);
+  return __ret;
+}
+#else
+__ai int16x4_t vuzp1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2, 4, 6);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vuzp2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai poly8x8_t vuzp2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vuzp2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai poly16x4_t vuzp2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vuzp2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  return __ret;
+}
+#else
+__ai poly8x16_t vuzp2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vuzp2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai poly64x2_t vuzp2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vuzp2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai poly16x8_t vuzp2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vuzp2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  return __ret;
+}
+#else
+__ai uint8x16_t vuzp2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vuzp2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai uint32x4_t vuzp2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vuzp2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint64x2_t vuzp2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vuzp2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai uint16x8_t vuzp2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vuzp2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  return __ret;
+}
+#else
+__ai int8x16_t vuzp2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vuzp2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float64x2_t vuzp2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vuzp2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai float32x4_t vuzp2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vuzp2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai int32x4_t vuzp2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vuzp2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int64x2_t vuzp2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vuzp2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai int16x8_t vuzp2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vuzp2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai uint8x8_t vuzp2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vuzp2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint32x2_t vuzp2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vuzp2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai uint16x4_t vuzp2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vuzp2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7, 9, 11, 13, 15);
+  return __ret;
+}
+#else
+__ai int8x8_t vuzp2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7, 9, 11, 13, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vuzp2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float32x2_t vuzp2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vuzp2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int32x2_t vuzp2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vuzp2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3, 5, 7);
+  return __ret;
+}
+#else
+__ai int16x4_t vuzp2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3, 5, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vzip1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai poly8x8_t vzip1_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vzip1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai poly16x4_t vzip1_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vzip1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  return __ret;
+}
+#else
+__ai poly8x16_t vzip1q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vzip1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai poly64x2_t vzip1q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vzip1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai poly16x8_t vzip1q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vzip1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  return __ret;
+}
+#else
+__ai uint8x16_t vzip1q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vzip1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai uint32x4_t vzip1q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vzip1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vzip1q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vzip1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai uint16x8_t vzip1q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vzip1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  return __ret;
+}
+#else
+__ai int8x16_t vzip1q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vzip1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float64x2_t vzip1q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vzip1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai float32x4_t vzip1q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vzip1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai int32x4_t vzip1q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vzip1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int64x2_t vzip1q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vzip1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai int16x8_t vzip1q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vzip1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai uint8x8_t vzip1_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vzip1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai uint32x2_t vzip1_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vzip1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai uint16x4_t vzip1_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vzip1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 8, 1, 9, 2, 10, 3, 11);
+  return __ret;
+}
+#else
+__ai int8x8_t vzip1_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 8, 1, 9, 2, 10, 3, 11);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vzip1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai float32x2_t vzip1_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vzip1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 2);
+  return __ret;
+}
+#else
+__ai int32x2_t vzip1_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vzip1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 0, 4, 1, 5);
+  return __ret;
+}
+#else
+__ai int16x4_t vzip1_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 0, 4, 1, 5);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x8_t vzip2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai poly8x8_t vzip2_p8(poly8x8_t __p0, poly8x8_t __p1) {
+  poly8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x4_t vzip2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai poly16x4_t vzip2_p16(poly16x4_t __p0, poly16x4_t __p1) {
+  poly16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  poly16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  poly16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly8x16_t vzip2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  return __ret;
+}
+#else
+__ai poly8x16_t vzip2q_p8(poly8x16_t __p0, poly8x16_t __p1) {
+  poly8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly64x2_t vzip2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai poly64x2_t vzip2q_p64(poly64x2_t __p0, poly64x2_t __p1) {
+  poly64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  poly64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  poly64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai poly16x8_t vzip2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai poly16x8_t vzip2q_p16(poly16x8_t __p0, poly16x8_t __p1) {
+  poly16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  poly16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vzip2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  return __ret;
+}
+#else
+__ai uint8x16_t vzip2q_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vzip2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai uint32x4_t vzip2q_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vzip2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint64x2_t vzip2q_u64(uint64x2_t __p0, uint64x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vzip2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai uint16x8_t vzip2q_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vzip2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  return __ret;
+}
+#else
+__ai int8x16_t vzip2q_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float64x2_t vzip2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float64x2_t vzip2q_f64(float64x2_t __p0, float64x2_t __p1) {
+  float64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x4_t vzip2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai float32x4_t vzip2q_f32(float32x4_t __p0, float32x4_t __p1) {
+  float32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  float32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  float32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vzip2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai int32x4_t vzip2q_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vzip2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int64x2_t vzip2q_s64(int64x2_t __p0, int64x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int64x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vzip2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai int16x8_t vzip2q_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vzip2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai uint8x8_t vzip2_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vzip2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai uint32x2_t vzip2_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vzip2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai uint16x4_t vzip2_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vzip2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 4, 12, 5, 13, 6, 14, 7, 15);
+  return __ret;
+}
+#else
+__ai int8x8_t vzip2_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 4, 12, 5, 13, 6, 14, 7, 15);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai float32x2_t vzip2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai float32x2_t vzip2_f32(float32x2_t __p0, float32x2_t __p1) {
+  float32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  float32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  float32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vzip2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 1, 3);
+  return __ret;
+}
+#else
+__ai int32x2_t vzip2_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 1, 3);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vzip2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__p0, __p1, 2, 6, 3, 7);
+  return __ret;
+}
+#else
+__ai int16x4_t vzip2_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __builtin_shufflevector(__rev0, __rev1, 2, 6, 3, 7);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#endif
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x16_t vabaq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __ret;
+  __ret = __p0 + vabdq_u8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint8x16_t vabaq_u8(uint8x16_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __ret;
+  __ret = __rev0 + __noswap_vabdq_u8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabaq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + vabdq_u32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vabaq_u32(uint32x4_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vabdq_u32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabaq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + vabdq_u16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint16x8_t vabaq_u16(uint16x8_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __noswap_vabdq_u16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x16_t vabaq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __ret;
+  __ret = __p0 + vabdq_s8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int8x16_t vabaq_s8(int8x16_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __ret;
+  __ret = __rev0 + __noswap_vabdq_s8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabaq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + vabdq_s32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vabaq_s32(int32x4_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vabdq_s32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabaq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + vabdq_s16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int16x8_t vabaq_s16(int16x8_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __noswap_vabdq_s16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint8x8_t vaba_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __ret;
+  __ret = __p0 + vabd_u8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint8x8_t vaba_u8(uint8x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __ret;
+  __ret = __rev0 + __noswap_vabd_u8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x2_t vaba_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __ret;
+  __ret = __p0 + vabd_u32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint32x2_t vaba_u32(uint32x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint32x2_t __ret;
+  __ret = __rev0 + __noswap_vabd_u32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x4_t vaba_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __ret;
+  __ret = __p0 + vabd_u16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint16x4_t vaba_u16(uint16x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint16x4_t __ret;
+  __ret = __rev0 + __noswap_vabd_u16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int8x8_t vaba_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __ret;
+  __ret = __p0 + vabd_s8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int8x8_t vaba_s8(int8x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __ret;
+  __ret = __rev0 + __noswap_vabd_s8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x2_t vaba_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __ret;
+  __ret = __p0 + vabd_s32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int32x2_t vaba_s32(int32x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int32x2_t __ret;
+  __ret = __rev0 + __noswap_vabd_s32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x4_t vaba_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __ret;
+  __ret = __p0 + vabd_s16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int16x4_t vaba_s16(int16x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int16x4_t __ret;
+  __ret = __rev0 + __noswap_vabd_s16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabdl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(vmovl_u8((uint8x8_t)(vabd_u8(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai uint16x8_t vabdl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__noswap_vmovl_u8((uint8x8_t)(__noswap_vabd_u8(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vabdl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = (uint16x8_t)(__noswap_vmovl_u8((uint8x8_t)(__noswap_vabd_u8(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vabdl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(vmovl_u32((uint32x2_t)(vabd_u32(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai uint64x2_t vabdl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__noswap_vmovl_u32((uint32x2_t)(__noswap_vabd_u32(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vabdl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = (uint64x2_t)(__noswap_vmovl_u32((uint32x2_t)(__noswap_vabd_u32(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabdl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(vmovl_u16((uint16x4_t)(vabd_u16(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai uint32x4_t vabdl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__noswap_vmovl_u16((uint16x4_t)(__noswap_vabd_u16(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vabdl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = (uint32x4_t)(__noswap_vmovl_u16((uint16x4_t)(__noswap_vabd_u16(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabdl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(vmovl_u8((uint8x8_t)(vabd_s8(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai int16x8_t vabdl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__noswap_vmovl_u8((uint8x8_t)(__noswap_vabd_s8(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vabdl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = (int16x8_t)(__noswap_vmovl_u8((uint8x8_t)(__noswap_vabd_s8(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vabdl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(vmovl_u32((uint32x2_t)(vabd_s32(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai int64x2_t vabdl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__noswap_vmovl_u32((uint32x2_t)(__noswap_vabd_s32(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vabdl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = (int64x2_t)(__noswap_vmovl_u32((uint32x2_t)(__noswap_vabd_s32(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabdl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(vmovl_u16((uint16x4_t)(vabd_s16(__p0, __p1))));
+  return __ret;
+}
+#else
+__ai int32x4_t vabdl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__noswap_vmovl_u16((uint16x4_t)(__noswap_vabd_s16(__rev0, __rev1))));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vabdl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = (int32x4_t)(__noswap_vmovl_u16((uint16x4_t)(__noswap_vabd_s16(__p0, __p1))));
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = vmovl_u8(__p0) + vmovl_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddl_u8(uint8x8_t __p0, uint8x8_t __p1) {
+  uint8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmovl_u8(__rev0) + __noswap_vmovl_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vaddl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmovl_u32(__p0) + vmovl_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vaddl_u32(uint32x2_t __p0, uint32x2_t __p1) {
+  uint32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmovl_u32(__rev0) + __noswap_vmovl_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmovl_u16(__p0) + vmovl_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddl_u16(uint16x4_t __p0, uint16x4_t __p1) {
+  uint16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmovl_u16(__rev0) + __noswap_vmovl_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = vmovl_s8(__p0) + vmovl_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vaddl_s8(int8x8_t __p0, int8x8_t __p1) {
+  int8x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmovl_s8(__rev0) + __noswap_vmovl_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vaddl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = vmovl_s32(__p0) + vmovl_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vaddl_s32(int32x2_t __p0, int32x2_t __p1) {
+  int32x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmovl_s32(__rev0) + __noswap_vmovl_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = vmovl_s16(__p0) + vmovl_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vaddl_s16(int16x4_t __p0, int16x4_t __p1) {
+  int16x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmovl_s16(__rev0) + __noswap_vmovl_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddw_u8(uint16x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 + vmovl_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddw_u8(uint16x8_t __p0, uint8x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __noswap_vmovl_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vaddw_u32(uint64x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 + vmovl_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vaddw_u32(uint64x2_t __p0, uint32x2_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __noswap_vmovl_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddw_u16(uint32x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 + vmovl_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddw_u16(uint32x4_t __p0, uint16x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vmovl_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddw_s8(int16x8_t __p0, int8x8_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 + vmovl_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vaddw_s8(int16x8_t __p0, int8x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __noswap_vmovl_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vaddw_s32(int64x2_t __p0, int32x2_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 + vmovl_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vaddw_s32(int64x2_t __p0, int32x2_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __noswap_vmovl_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddw_s16(int32x4_t __p0, int16x4_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 + vmovl_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vaddw_s16(int32x4_t __p0, int16x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vmovl_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + vmull_u8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __noswap_vmull_u8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vmlal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + __noswap_vmull_u8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + vmull_u32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __noswap_vmull_u32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmlal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + __noswap_vmull_u32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + vmull_u16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vmull_u16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmlal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + __noswap_vmull_u16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + vmull_s8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int16x8_t vmlal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __noswap_vmull_s8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vmlal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + __noswap_vmull_s8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + vmull_s32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __noswap_vmull_s32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmlal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + __noswap_vmull_s32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + vmull_s16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vmull_s16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmlal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + __noswap_vmull_s16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 + vmull_u32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 + vmull_u16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_u16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 + vmull_s32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlal_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 + vmull_s16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlal_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 + __noswap_vmull_s16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlal_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + vmull_u32(__p1, (uint32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlal_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __noswap_vmull_u32(__rev1, (uint32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmlal_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + __noswap_vmull_u32(__p1, (uint32x2_t) {__p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlal_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + vmull_u16(__p1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlal_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vmull_u16(__rev1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmlal_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + __noswap_vmull_u16(__p1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + vmull_s32(__p1, (int32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai int64x2_t vmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __noswap_vmull_s32(__rev1, (int32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmlal_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + __noswap_vmull_s32(__p1, (int32x2_t) {__p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + vmull_s16(__p1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai int32x4_t vmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vmull_s16(__rev1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmlal_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + __noswap_vmull_s16(__p1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlsl_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 - vmull_u8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlsl_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 - __noswap_vmull_u8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vmlsl_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 - __noswap_vmull_u8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlsl_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 - vmull_u32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlsl_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 - __noswap_vmull_u32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmlsl_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 - __noswap_vmull_u32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsl_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - vmull_u16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsl_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __noswap_vmull_u16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmlsl_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - __noswap_vmull_u16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlsl_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 - vmull_s8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int16x8_t vmlsl_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 - __noswap_vmull_s8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vmlsl_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 - __noswap_vmull_s8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 - vmull_s32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 - __noswap_vmull_s32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmlsl_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 - __noswap_vmull_s32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - vmull_s16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __noswap_vmull_s16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmlsl_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - __noswap_vmull_s16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __ret; \
+  __ret = __s0 - vmull_u32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_lane_u32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint64x2_t __s0 = __p0; \
+  uint32x2_t __s1 = __p1; \
+  uint32x2_t __s2 = __p2; \
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  uint64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __ret; \
+  __ret = __s0 - vmull_u16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_lane_u16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  uint32x4_t __s0 = __p0; \
+  uint16x4_t __s1 = __p1; \
+  uint16x4_t __s2 = __p2; \
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  uint32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_u16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __ret; \
+  __ret = __s0 - vmull_s32(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_lane_s32(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int64x2_t __s0 = __p0; \
+  int32x2_t __s1 = __p1; \
+  int32x2_t __s2 = __p2; \
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 1, 0); \
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 1, 0); \
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 1, 0); \
+  int64x2_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s32(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmlsl_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __ret; \
+  __ret = __s0 - vmull_s16(__s1, __builtin_shufflevector(__s2, __s2, __p3, __p3, __p3, __p3)); \
+  __ret; \
+})
+#else
+#define vmlsl_lane_s16(__p0, __p1, __p2, __p3) __extension__ ({ \
+  int32x4_t __s0 = __p0; \
+  int16x4_t __s1 = __p1; \
+  int16x4_t __s2 = __p2; \
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__s0, __s0, 3, 2, 1, 0); \
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__s1, __s1, 3, 2, 1, 0); \
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__s2, __s2, 3, 2, 1, 0); \
+  int32x4_t __ret; \
+  __ret = __rev0 - __noswap_vmull_s16(__rev1, __builtin_shufflevector(__rev2, __rev2, __p3, __p3, __p3, __p3)); \
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0); \
+  __ret; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlsl_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 - vmull_u32(__p1, (uint32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlsl_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 - __noswap_vmull_u32(__rev1, (uint32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vmlsl_n_u32(uint64x2_t __p0, uint32x2_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 - __noswap_vmull_u32(__p1, (uint32x2_t) {__p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsl_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - vmull_u16(__p1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsl_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 - __noswap_vmull_u16(__rev1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vmlsl_n_u16(uint32x4_t __p0, uint16x4_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 - __noswap_vmull_u16(__p1, (uint16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 - vmull_s32(__p1, (int32x2_t) {__p2, __p2});
+  return __ret;
+}
+#else
+__ai int64x2_t vmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 - __noswap_vmull_s32(__rev1, (int32x2_t) {__p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vmlsl_n_s32(int64x2_t __p0, int32x2_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 - __noswap_vmull_s32(__p1, (int32x2_t) {__p2, __p2});
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - vmull_s16(__p1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 - __noswap_vmull_s16(__rev1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vmlsl_n_s16(int32x4_t __p0, int16x4_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 - __noswap_vmull_s16(__p1, (int16x4_t) {__p2, __p2, __p2, __p2});
+  return __ret;
+}
+#endif
+
+#if defined(__aarch64__)
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabdl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = vabdl_u8(vget_high_u8(__p0), vget_high_u8(__p1));
+  return __ret;
+}
+#else
+__ai uint16x8_t vabdl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vabdl_u8(__noswap_vget_high_u8(__rev0), __noswap_vget_high_u8(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vabdl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = vabdl_u32(vget_high_u32(__p0), vget_high_u32(__p1));
+  return __ret;
+}
+#else
+__ai uint64x2_t vabdl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vabdl_u32(__noswap_vget_high_u32(__rev0), __noswap_vget_high_u32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabdl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = vabdl_u16(vget_high_u16(__p0), vget_high_u16(__p1));
+  return __ret;
+}
+#else
+__ai uint32x4_t vabdl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vabdl_u16(__noswap_vget_high_u16(__rev0), __noswap_vget_high_u16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabdl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = vabdl_s8(vget_high_s8(__p0), vget_high_s8(__p1));
+  return __ret;
+}
+#else
+__ai int16x8_t vabdl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vabdl_s8(__noswap_vget_high_s8(__rev0), __noswap_vget_high_s8(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vabdl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = vabdl_s32(vget_high_s32(__p0), vget_high_s32(__p1));
+  return __ret;
+}
+#else
+__ai int64x2_t vabdl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vabdl_s32(__noswap_vget_high_s32(__rev0), __noswap_vget_high_s32(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabdl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = vabdl_s16(vget_high_s16(__p0), vget_high_s16(__p1));
+  return __ret;
+}
+#else
+__ai int32x4_t vabdl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vabdl_s16(__noswap_vget_high_s16(__rev0), __noswap_vget_high_s16(__rev1));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = vmovl_high_u8(__p0) + vmovl_high_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddl_high_u8(uint8x16_t __p0, uint8x16_t __p1) {
+  uint8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmovl_high_u8(__rev0) + __noswap_vmovl_high_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vaddl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = vmovl_high_u32(__p0) + vmovl_high_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vaddl_high_u32(uint32x4_t __p0, uint32x4_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmovl_high_u32(__rev0) + __noswap_vmovl_high_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = vmovl_high_u16(__p0) + vmovl_high_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddl_high_u16(uint16x8_t __p0, uint16x8_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmovl_high_u16(__rev0) + __noswap_vmovl_high_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = vmovl_high_s8(__p0) + vmovl_high_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vaddl_high_s8(int8x16_t __p0, int8x16_t __p1) {
+  int8x16_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmovl_high_s8(__rev0) + __noswap_vmovl_high_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vaddl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = vmovl_high_s32(__p0) + vmovl_high_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vaddl_high_s32(int32x4_t __p0, int32x4_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmovl_high_s32(__rev0) + __noswap_vmovl_high_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = vmovl_high_s16(__p0) + vmovl_high_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vaddl_high_s16(int16x8_t __p0, int16x8_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmovl_high_s16(__rev0) + __noswap_vmovl_high_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vaddw_high_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __ret;
+  __ret = __p0 + vmovl_high_u8(__p1);
+  return __ret;
+}
+#else
+__ai uint16x8_t vaddw_high_u8(uint16x8_t __p0, uint8x16_t __p1) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_u8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vaddw_high_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __ret;
+  __ret = __p0 + vmovl_high_u32(__p1);
+  return __ret;
+}
+#else
+__ai uint64x2_t vaddw_high_u32(uint64x2_t __p0, uint32x4_t __p1) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_u32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vaddw_high_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __ret;
+  __ret = __p0 + vmovl_high_u16(__p1);
+  return __ret;
+}
+#else
+__ai uint32x4_t vaddw_high_u16(uint32x4_t __p0, uint16x8_t __p1) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_u16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vaddw_high_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __ret;
+  __ret = __p0 + vmovl_high_s8(__p1);
+  return __ret;
+}
+#else
+__ai int16x8_t vaddw_high_s8(int16x8_t __p0, int8x16_t __p1) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_s8(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vaddw_high_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __ret;
+  __ret = __p0 + vmovl_high_s32(__p1);
+  return __ret;
+}
+#else
+__ai int64x2_t vaddw_high_s32(int64x2_t __p0, int32x4_t __p1) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_s32(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vaddw_high_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __ret;
+  __ret = __p0 + vmovl_high_s16(__p1);
+  return __ret;
+}
+#else
+__ai int32x4_t vaddw_high_s16(int32x4_t __p0, int16x8_t __p1) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vmovl_high_s16(__rev1);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_p64(__p0_250, __p1_250, __p2_250, __p3_250) __extension__ ({ \
+  poly64x2_t __s0_250 = __p0_250; \
+  poly64x1_t __s2_250 = __p2_250; \
+  poly64x2_t __ret_250; \
+  __ret_250 = vsetq_lane_p64(vget_lane_p64(__s2_250, __p3_250), __s0_250, __p1_250); \
+  __ret_250; \
+})
+#else
+#define vcopyq_lane_p64(__p0_251, __p1_251, __p2_251, __p3_251) __extension__ ({ \
+  poly64x2_t __s0_251 = __p0_251; \
+  poly64x1_t __s2_251 = __p2_251; \
+  poly64x2_t __rev0_251;  __rev0_251 = __builtin_shufflevector(__s0_251, __s0_251, 1, 0); \
+  poly64x2_t __ret_251; \
+  __ret_251 = __noswap_vsetq_lane_p64(__noswap_vget_lane_p64(__s2_251, __p3_251), __rev0_251, __p1_251); \
+  __ret_251 = __builtin_shufflevector(__ret_251, __ret_251, 1, 0); \
+  __ret_251; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_lane_f64(__p0_252, __p1_252, __p2_252, __p3_252) __extension__ ({ \
+  float64x2_t __s0_252 = __p0_252; \
+  float64x1_t __s2_252 = __p2_252; \
+  float64x2_t __ret_252; \
+  __ret_252 = vsetq_lane_f64(vget_lane_f64(__s2_252, __p3_252), __s0_252, __p1_252); \
+  __ret_252; \
+})
+#else
+#define vcopyq_lane_f64(__p0_253, __p1_253, __p2_253, __p3_253) __extension__ ({ \
+  float64x2_t __s0_253 = __p0_253; \
+  float64x1_t __s2_253 = __p2_253; \
+  float64x2_t __rev0_253;  __rev0_253 = __builtin_shufflevector(__s0_253, __s0_253, 1, 0); \
+  float64x2_t __ret_253; \
+  __ret_253 = __noswap_vsetq_lane_f64(__noswap_vget_lane_f64(__s2_253, __p3_253), __rev0_253, __p1_253); \
+  __ret_253 = __builtin_shufflevector(__ret_253, __ret_253, 1, 0); \
+  __ret_253; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_p64(__p0_254, __p1_254, __p2_254, __p3_254) __extension__ ({ \
+  poly64x1_t __s0_254 = __p0_254; \
+  poly64x1_t __s2_254 = __p2_254; \
+  poly64x1_t __ret_254; \
+  __ret_254 = vset_lane_p64(vget_lane_p64(__s2_254, __p3_254), __s0_254, __p1_254); \
+  __ret_254; \
+})
+#else
+#define vcopy_lane_p64(__p0_255, __p1_255, __p2_255, __p3_255) __extension__ ({ \
+  poly64x1_t __s0_255 = __p0_255; \
+  poly64x1_t __s2_255 = __p2_255; \
+  poly64x1_t __ret_255; \
+  __ret_255 = __noswap_vset_lane_p64(__noswap_vget_lane_p64(__s2_255, __p3_255), __s0_255, __p1_255); \
+  __ret_255; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_lane_f64(__p0_256, __p1_256, __p2_256, __p3_256) __extension__ ({ \
+  float64x1_t __s0_256 = __p0_256; \
+  float64x1_t __s2_256 = __p2_256; \
+  float64x1_t __ret_256; \
+  __ret_256 = vset_lane_f64(vget_lane_f64(__s2_256, __p3_256), __s0_256, __p1_256); \
+  __ret_256; \
+})
+#else
+#define vcopy_lane_f64(__p0_257, __p1_257, __p2_257, __p3_257) __extension__ ({ \
+  float64x1_t __s0_257 = __p0_257; \
+  float64x1_t __s2_257 = __p2_257; \
+  float64x1_t __ret_257; \
+  __ret_257 = __noswap_vset_lane_f64(__noswap_vget_lane_f64(__s2_257, __p3_257), __s0_257, __p1_257); \
+  __ret_257; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_p64(__p0_258, __p1_258, __p2_258, __p3_258) __extension__ ({ \
+  poly64x2_t __s0_258 = __p0_258; \
+  poly64x2_t __s2_258 = __p2_258; \
+  poly64x2_t __ret_258; \
+  __ret_258 = vsetq_lane_p64(vgetq_lane_p64(__s2_258, __p3_258), __s0_258, __p1_258); \
+  __ret_258; \
+})
+#else
+#define vcopyq_laneq_p64(__p0_259, __p1_259, __p2_259, __p3_259) __extension__ ({ \
+  poly64x2_t __s0_259 = __p0_259; \
+  poly64x2_t __s2_259 = __p2_259; \
+  poly64x2_t __rev0_259;  __rev0_259 = __builtin_shufflevector(__s0_259, __s0_259, 1, 0); \
+  poly64x2_t __rev2_259;  __rev2_259 = __builtin_shufflevector(__s2_259, __s2_259, 1, 0); \
+  poly64x2_t __ret_259; \
+  __ret_259 = __noswap_vsetq_lane_p64(__noswap_vgetq_lane_p64(__rev2_259, __p3_259), __rev0_259, __p1_259); \
+  __ret_259 = __builtin_shufflevector(__ret_259, __ret_259, 1, 0); \
+  __ret_259; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopyq_laneq_f64(__p0_260, __p1_260, __p2_260, __p3_260) __extension__ ({ \
+  float64x2_t __s0_260 = __p0_260; \
+  float64x2_t __s2_260 = __p2_260; \
+  float64x2_t __ret_260; \
+  __ret_260 = vsetq_lane_f64(vgetq_lane_f64(__s2_260, __p3_260), __s0_260, __p1_260); \
+  __ret_260; \
+})
+#else
+#define vcopyq_laneq_f64(__p0_261, __p1_261, __p2_261, __p3_261) __extension__ ({ \
+  float64x2_t __s0_261 = __p0_261; \
+  float64x2_t __s2_261 = __p2_261; \
+  float64x2_t __rev0_261;  __rev0_261 = __builtin_shufflevector(__s0_261, __s0_261, 1, 0); \
+  float64x2_t __rev2_261;  __rev2_261 = __builtin_shufflevector(__s2_261, __s2_261, 1, 0); \
+  float64x2_t __ret_261; \
+  __ret_261 = __noswap_vsetq_lane_f64(__noswap_vgetq_lane_f64(__rev2_261, __p3_261), __rev0_261, __p1_261); \
+  __ret_261 = __builtin_shufflevector(__ret_261, __ret_261, 1, 0); \
+  __ret_261; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_p64(__p0_262, __p1_262, __p2_262, __p3_262) __extension__ ({ \
+  poly64x1_t __s0_262 = __p0_262; \
+  poly64x2_t __s2_262 = __p2_262; \
+  poly64x1_t __ret_262; \
+  __ret_262 = vset_lane_p64(vgetq_lane_p64(__s2_262, __p3_262), __s0_262, __p1_262); \
+  __ret_262; \
+})
+#else
+#define vcopy_laneq_p64(__p0_263, __p1_263, __p2_263, __p3_263) __extension__ ({ \
+  poly64x1_t __s0_263 = __p0_263; \
+  poly64x2_t __s2_263 = __p2_263; \
+  poly64x2_t __rev2_263;  __rev2_263 = __builtin_shufflevector(__s2_263, __s2_263, 1, 0); \
+  poly64x1_t __ret_263; \
+  __ret_263 = __noswap_vset_lane_p64(__noswap_vgetq_lane_p64(__rev2_263, __p3_263), __s0_263, __p1_263); \
+  __ret_263; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vcopy_laneq_f64(__p0_264, __p1_264, __p2_264, __p3_264) __extension__ ({ \
+  float64x1_t __s0_264 = __p0_264; \
+  float64x2_t __s2_264 = __p2_264; \
+  float64x1_t __ret_264; \
+  __ret_264 = vset_lane_f64(vgetq_lane_f64(__s2_264, __p3_264), __s0_264, __p1_264); \
+  __ret_264; \
+})
+#else
+#define vcopy_laneq_f64(__p0_265, __p1_265, __p2_265, __p3_265) __extension__ ({ \
+  float64x1_t __s0_265 = __p0_265; \
+  float64x2_t __s2_265 = __p2_265; \
+  float64x2_t __rev2_265;  __rev2_265 = __builtin_shufflevector(__s2_265, __s2_265, 1, 0); \
+  float64x1_t __ret_265; \
+  __ret_265 = __noswap_vset_lane_f64(__noswap_vgetq_lane_f64(__rev2_265, __p3_265), __s0_265, __p1_265); \
+  __ret_265; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlal_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __ret;
+  __ret = vmlal_u8(__p0, vget_high_u8(__p1), vget_high_u8(__p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlal_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmlal_u8(__rev0, __noswap_vget_high_u8(__rev1), __noswap_vget_high_u8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlal_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __ret;
+  __ret = vmlal_u32(__p0, vget_high_u32(__p1), vget_high_u32(__p2));
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlal_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmlal_u32(__rev0, __noswap_vget_high_u32(__rev1), __noswap_vget_high_u32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlal_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __ret;
+  __ret = vmlal_u16(__p0, vget_high_u16(__p1), vget_high_u16(__p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlal_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmlal_u16(__rev0, __noswap_vget_high_u16(__rev1), __noswap_vget_high_u16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlal_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __ret;
+  __ret = vmlal_s8(__p0, vget_high_s8(__p1), vget_high_s8(__p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vmlal_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmlal_s8(__rev0, __noswap_vget_high_s8(__rev1), __noswap_vget_high_s8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __ret;
+  __ret = vmlal_s32(__p0, vget_high_s32(__p1), vget_high_s32(__p2));
+  return __ret;
+}
+#else
+__ai int64x2_t vmlal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmlal_s32(__rev0, __noswap_vget_high_s32(__rev1), __noswap_vget_high_s32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __ret;
+  __ret = vmlal_s16(__p0, vget_high_s16(__p1), vget_high_s16(__p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vmlal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmlal_s16(__rev0, __noswap_vget_high_s16(__rev1), __noswap_vget_high_s16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlal_high_n_u32(uint64x2_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = vmlal_n_u32(__p0, vget_high_u32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlal_high_n_u32(uint64x2_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmlal_n_u32(__rev0, __noswap_vget_high_u32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlal_high_n_u16(uint32x4_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = vmlal_n_u16(__p0, vget_high_u16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlal_high_n_u16(uint32x4_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmlal_n_u16(__rev0, __noswap_vget_high_u16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlal_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = vmlal_n_s32(__p0, vget_high_s32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vmlal_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmlal_n_s32(__rev0, __noswap_vget_high_s32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlal_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = vmlal_n_s16(__p0, vget_high_s16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vmlal_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmlal_n_s16(__rev0, __noswap_vget_high_s16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vmlsl_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __ret;
+  __ret = vmlsl_u8(__p0, vget_high_u8(__p1), vget_high_u8(__p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vmlsl_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vmlsl_u8(__rev0, __noswap_vget_high_u8(__rev1), __noswap_vget_high_u8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlsl_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __ret;
+  __ret = vmlsl_u32(__p0, vget_high_u32(__p1), vget_high_u32(__p2));
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlsl_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmlsl_u32(__rev0, __noswap_vget_high_u32(__rev1), __noswap_vget_high_u32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsl_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __ret;
+  __ret = vmlsl_u16(__p0, vget_high_u16(__p1), vget_high_u16(__p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsl_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmlsl_u16(__rev0, __noswap_vget_high_u16(__rev1), __noswap_vget_high_u16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vmlsl_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __ret;
+  __ret = vmlsl_s8(__p0, vget_high_s8(__p1), vget_high_s8(__p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vmlsl_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vmlsl_s8(__rev0, __noswap_vget_high_s8(__rev1), __noswap_vget_high_s8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlsl_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __ret;
+  __ret = vmlsl_s32(__p0, vget_high_s32(__p1), vget_high_s32(__p2));
+  return __ret;
+}
+#else
+__ai int64x2_t vmlsl_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmlsl_s32(__rev0, __noswap_vget_high_s32(__rev1), __noswap_vget_high_s32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsl_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __ret;
+  __ret = vmlsl_s16(__p0, vget_high_s16(__p1), vget_high_s16(__p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsl_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmlsl_s16(__rev0, __noswap_vget_high_s16(__rev1), __noswap_vget_high_s16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vmlsl_high_n_u32(uint64x2_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint64x2_t __ret;
+  __ret = vmlsl_n_u32(__p0, vget_high_u32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vmlsl_high_n_u32(uint64x2_t __p0, uint32x4_t __p1, uint32_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vmlsl_n_u32(__rev0, __noswap_vget_high_u32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vmlsl_high_n_u16(uint32x4_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint32x4_t __ret;
+  __ret = vmlsl_n_u16(__p0, vget_high_u16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vmlsl_high_n_u16(uint32x4_t __p0, uint16x8_t __p1, uint16_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vmlsl_n_u16(__rev0, __noswap_vget_high_u16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vmlsl_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __ret;
+  __ret = vmlsl_n_s32(__p0, vget_high_s32(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vmlsl_high_n_s32(int64x2_t __p0, int32x4_t __p1, int32_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vmlsl_n_s32(__rev0, __noswap_vget_high_s32(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vmlsl_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __ret;
+  __ret = vmlsl_n_s16(__p0, vget_high_s16(__p1), __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vmlsl_high_n_s16(int32x4_t __p0, int16x8_t __p1, int16_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vmlsl_n_s16(__rev0, __noswap_vget_high_s16(__rev1), __p2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulx_lane_f64(__p0_266, __p1_266, __p2_266) __extension__ ({ \
+  float64x1_t __s0_266 = __p0_266; \
+  float64x1_t __s1_266 = __p1_266; \
+  float64x1_t __ret_266; \
+  float64_t __x_266 = vget_lane_f64(__s0_266, 0); \
+  float64_t __y_266 = vget_lane_f64(__s1_266, __p2_266); \
+  float64_t __z_266 = vmulxd_f64(__x_266, __y_266); \
+  __ret_266 = vset_lane_f64(__z_266, __s0_266, __p2_266); \
+  __ret_266; \
+})
+#else
+#define vmulx_lane_f64(__p0_267, __p1_267, __p2_267) __extension__ ({ \
+  float64x1_t __s0_267 = __p0_267; \
+  float64x1_t __s1_267 = __p1_267; \
+  float64x1_t __ret_267; \
+  float64_t __x_267 = __noswap_vget_lane_f64(__s0_267, 0); \
+  float64_t __y_267 = __noswap_vget_lane_f64(__s1_267, __p2_267); \
+  float64_t __z_267 = __noswap_vmulxd_f64(__x_267, __y_267); \
+  __ret_267 = __noswap_vset_lane_f64(__z_267, __s0_267, __p2_267); \
+  __ret_267; \
+})
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define vmulx_laneq_f64(__p0_268, __p1_268, __p2_268) __extension__ ({ \
+  float64x1_t __s0_268 = __p0_268; \
+  float64x2_t __s1_268 = __p1_268; \
+  float64x1_t __ret_268; \
+  float64_t __x_268 = vget_lane_f64(__s0_268, 0); \
+  float64_t __y_268 = vgetq_lane_f64(__s1_268, __p2_268); \
+  float64_t __z_268 = vmulxd_f64(__x_268, __y_268); \
+  __ret_268 = vset_lane_f64(__z_268, __s0_268, 0); \
+  __ret_268; \
+})
+#else
+#define vmulx_laneq_f64(__p0_269, __p1_269, __p2_269) __extension__ ({ \
+  float64x1_t __s0_269 = __p0_269; \
+  float64x2_t __s1_269 = __p1_269; \
+  float64x2_t __rev1_269;  __rev1_269 = __builtin_shufflevector(__s1_269, __s1_269, 1, 0); \
+  float64x1_t __ret_269; \
+  float64_t __x_269 = __noswap_vget_lane_f64(__s0_269, 0); \
+  float64_t __y_269 = __noswap_vgetq_lane_f64(__rev1_269, __p2_269); \
+  float64_t __z_269 = __noswap_vmulxd_f64(__x_269, __y_269); \
+  __ret_269 = __noswap_vset_lane_f64(__z_269, __s0_269, 0); \
+  __ret_269; \
+})
+#endif
+
+#endif
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + vabdl_u8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint16x8_t vabal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __rev0 + __noswap_vabdl_u8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint16x8_t __noswap_vabal_u8(uint16x8_t __p0, uint8x8_t __p1, uint8x8_t __p2) {
+  uint16x8_t __ret;
+  __ret = __p0 + __noswap_vabdl_u8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vabal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + vabdl_u32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint64x2_t vabal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  uint32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __rev0 + __noswap_vabdl_u32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai uint64x2_t __noswap_vabal_u32(uint64x2_t __p0, uint32x2_t __p1, uint32x2_t __p2) {
+  uint64x2_t __ret;
+  __ret = __p0 + __noswap_vabdl_u32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + vabdl_u16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai uint32x4_t vabal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __rev0 + __noswap_vabdl_u16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai uint32x4_t __noswap_vabal_u16(uint32x4_t __p0, uint16x4_t __p1, uint16x4_t __p2) {
+  uint32x4_t __ret;
+  __ret = __p0 + __noswap_vabdl_u16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + vabdl_s8(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int16x8_t vabal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __rev0 + __noswap_vabdl_s8(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int16x8_t __noswap_vabal_s8(int16x8_t __p0, int8x8_t __p1, int8x8_t __p2) {
+  int16x8_t __ret;
+  __ret = __p0 + __noswap_vabdl_s8(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vabal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + vabdl_s32(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int64x2_t vabal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x2_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 1, 0);
+  int32x2_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 1, 0);
+  int64x2_t __ret;
+  __ret = __rev0 + __noswap_vabdl_s32(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+__ai int64x2_t __noswap_vabal_s32(int64x2_t __p0, int32x2_t __p1, int32x2_t __p2) {
+  int64x2_t __ret;
+  __ret = __p0 + __noswap_vabdl_s32(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + vabdl_s16(__p1, __p2);
+  return __ret;
+}
+#else
+__ai int32x4_t vabal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int16x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __rev0 + __noswap_vabdl_s16(__rev1, __rev2);
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+__ai int32x4_t __noswap_vabal_s16(int32x4_t __p0, int16x4_t __p1, int16x4_t __p2) {
+  int32x4_t __ret;
+  __ret = __p0 + __noswap_vabdl_s16(__p1, __p2);
+  return __ret;
+}
+#endif
+
+#if defined(__aarch64__)
+#ifdef __LITTLE_ENDIAN__
+__ai uint16x8_t vabal_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __ret;
+  __ret = vabal_u8(__p0, vget_high_u8(__p1), vget_high_u8(__p2));
+  return __ret;
+}
+#else
+__ai uint16x8_t vabal_high_u8(uint16x8_t __p0, uint8x16_t __p1, uint8x16_t __p2) {
+  uint16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __ret;
+  __ret = __noswap_vabal_u8(__rev0, __noswap_vget_high_u8(__rev1), __noswap_vget_high_u8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint64x2_t vabal_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __ret;
+  __ret = vabal_u32(__p0, vget_high_u32(__p1), vget_high_u32(__p2));
+  return __ret;
+}
+#else
+__ai uint64x2_t vabal_high_u32(uint64x2_t __p0, uint32x4_t __p1, uint32x4_t __p2) {
+  uint64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  uint32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  uint32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  uint64x2_t __ret;
+  __ret = __noswap_vabal_u32(__rev0, __noswap_vget_high_u32(__rev1), __noswap_vget_high_u32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai uint32x4_t vabal_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __ret;
+  __ret = vabal_u16(__p0, vget_high_u16(__p1), vget_high_u16(__p2));
+  return __ret;
+}
+#else
+__ai uint32x4_t vabal_high_u16(uint32x4_t __p0, uint16x8_t __p1, uint16x8_t __p2) {
+  uint32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  uint16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  uint32x4_t __ret;
+  __ret = __noswap_vabal_u16(__rev0, __noswap_vget_high_u16(__rev1), __noswap_vget_high_u16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int16x8_t vabal_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __ret;
+  __ret = vabal_s8(__p0, vget_high_s8(__p1), vget_high_s8(__p2));
+  return __ret;
+}
+#else
+__ai int16x8_t vabal_high_s8(int16x8_t __p0, int8x16_t __p1, int8x16_t __p2) {
+  int16x8_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int8x16_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __ret;
+  __ret = __noswap_vabal_s8(__rev0, __noswap_vget_high_s8(__rev1), __noswap_vget_high_s8(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 7, 6, 5, 4, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int64x2_t vabal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __ret;
+  __ret = vabal_s32(__p0, vget_high_s32(__p1), vget_high_s32(__p2));
+  return __ret;
+}
+#else
+__ai int64x2_t vabal_high_s32(int64x2_t __p0, int32x4_t __p1, int32x4_t __p2) {
+  int64x2_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 1, 0);
+  int32x4_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 3, 2, 1, 0);
+  int32x4_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 3, 2, 1, 0);
+  int64x2_t __ret;
+  __ret = __noswap_vabal_s32(__rev0, __noswap_vget_high_s32(__rev1), __noswap_vget_high_s32(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 1, 0);
+  return __ret;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+__ai int32x4_t vabal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __ret;
+  __ret = vabal_s16(__p0, vget_high_s16(__p1), vget_high_s16(__p2));
+  return __ret;
+}
+#else
+__ai int32x4_t vabal_high_s16(int32x4_t __p0, int16x8_t __p1, int16x8_t __p2) {
+  int32x4_t __rev0;  __rev0 = __builtin_shufflevector(__p0, __p0, 3, 2, 1, 0);
+  int16x8_t __rev1;  __rev1 = __builtin_shufflevector(__p1, __p1, 7, 6, 5, 4, 3, 2, 1, 0);
+  int16x8_t __rev2;  __rev2 = __builtin_shufflevector(__p2, __p2, 7, 6, 5, 4, 3, 2, 1, 0);
+  int32x4_t __ret;
+  __ret = __noswap_vabal_s16(__rev0, __noswap_vget_high_s16(__rev1), __noswap_vget_high_s16(__rev2));
+  __ret = __builtin_shufflevector(__ret, __ret, 3, 2, 1, 0);
+  return __ret;
+}
+#endif
+
+#endif
+
+#undef __ai
+
+#endif /* __ARM_NEON_H */
diff --git a/lib/clang/3.5.2/include/avx2intrin.h b/lib/clang/3.5.2/include/avx2intrin.h
new file mode 100644
index 0000000..394fdfe
--- /dev/null
+++ b/lib/clang/3.5.2/include/avx2intrin.h
@@ -0,0 +1,1234 @@
+/*===---- avx2intrin.h - AVX2 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <avx2intrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __AVX2INTRIN_H
+#define __AVX2INTRIN_H
+
+/* SSE4 Multiple Packed Sums of Absolute Difference.  */
+#define _mm256_mpsadbw_epu8(X, Y, M) __builtin_ia32_mpsadbw256((X), (Y), (M))
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_abs_epi8(__m256i __a)
+{
+    return (__m256i)__builtin_ia32_pabsb256((__v32qi)__a);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_abs_epi16(__m256i __a)
+{
+    return (__m256i)__builtin_ia32_pabsw256((__v16hi)__a);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_abs_epi32(__m256i __a)
+{
+    return (__m256i)__builtin_ia32_pabsd256((__v8si)__a);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_packs_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_packsswb256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_packs_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_packssdw256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_packus_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_packuswb256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_packus_epi32(__m256i __V1, __m256i __V2)
+{
+  return (__m256i) __builtin_ia32_packusdw256((__v8si)__V1, (__v8si)__V2);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_add_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v32qi)__a + (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_add_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v16hi)__a + (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_add_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v8si)__a + (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_add_epi64(__m256i __a, __m256i __b)
+{
+  return __a + __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_adds_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_paddsb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_adds_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_paddsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_adds_epu8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_paddusb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_adds_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_paddusw256((__v16hi)__a, (__v16hi)__b);
+}
+
+#define _mm256_alignr_epi8(a, b, n) __extension__ ({ \
+  __m256i __a = (a); \
+  __m256i __b = (b); \
+  (__m256i)__builtin_ia32_palignr256((__v32qi)__a, (__v32qi)__b, (n)); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_and_si256(__m256i __a, __m256i __b)
+{
+  return __a & __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_andnot_si256(__m256i __a, __m256i __b)
+{
+  return ~__a & __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_avg_epu8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pavgb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_avg_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pavgw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_blendv_epi8(__m256i __V1, __m256i __V2, __m256i __M)
+{
+  return (__m256i)__builtin_ia32_pblendvb256((__v32qi)__V1, (__v32qi)__V2,
+                                              (__v32qi)__M);
+}
+
+#define _mm256_blend_epi16(V1, V2, M) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m256i __V2 = (V2); \
+  (__m256d)__builtin_shufflevector((__v16hi)__V1, (__v16hi)__V2, \
+                                   (((M) & 0x01) ? 16 : 0), \
+                                   (((M) & 0x02) ? 17 : 1), \
+                                   (((M) & 0x04) ? 18 : 2), \
+                                   (((M) & 0x08) ? 19 : 3), \
+                                   (((M) & 0x10) ? 20 : 4), \
+                                   (((M) & 0x20) ? 21 : 5), \
+                                   (((M) & 0x40) ? 22 : 6), \
+                                   (((M) & 0x80) ? 23 : 7), \
+                                   (((M) & 0x01) ? 24 : 8), \
+                                   (((M) & 0x02) ? 25 : 9), \
+                                   (((M) & 0x04) ? 26 : 10), \
+                                   (((M) & 0x08) ? 27 : 11), \
+                                   (((M) & 0x10) ? 28 : 12), \
+                                   (((M) & 0x20) ? 29 : 13), \
+                                   (((M) & 0x40) ? 30 : 14), \
+                                   (((M) & 0x80) ? 31 : 15)); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpeq_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v32qi)__a == (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpeq_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v16hi)__a == (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpeq_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v8si)__a == (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpeq_epi64(__m256i __a, __m256i __b)
+{
+  return (__m256i)(__a == __b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpgt_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v32qi)__a > (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpgt_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v16hi)__a > (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpgt_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v8si)__a > (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmpgt_epi64(__m256i __a, __m256i __b)
+{
+  return (__m256i)(__a > __b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phaddw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_epi32(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phaddd256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hadds_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phaddsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phsubw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_epi32(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phsubd256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_hsubs_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_phsubsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_maddubs_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_pmaddubsw256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_madd_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaddwd256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxsb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxsd256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epu8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxub256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxuw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_max_epu32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmaxud256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminsb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminsd256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epu8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminub256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminuw256 ((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_min_epu32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pminud256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm256_movemask_epi8(__m256i __a)
+{
+  return __builtin_ia32_pmovmskb256((__v32qi)__a);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi8_epi16(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxbw256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi8_epi32(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxbd256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi8_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxbq256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi16_epi32(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxwd256((__v8hi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi16_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxwq256((__v8hi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi32_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovsxdq256((__v4si)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu8_epi16(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxbw256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu8_epi32(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxbd256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu8_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxbq256((__v16qi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu16_epi32(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxwd256((__v8hi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu16_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxwq256((__v8hi)__V);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepu32_epi64(__m128i __V)
+{
+  return (__m256i)__builtin_ia32_pmovzxdq256((__v4si)__V);
+}
+
+static __inline__  __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmuldq256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mulhrs_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmulhrsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mulhi_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmulhuw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mulhi_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pmulhw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mullo_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v16hi)__a * (__v16hi)__b);
+}
+
+static __inline__  __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mullo_epi32 (__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v8si)__a * (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_epu32(__m256i __a, __m256i __b)
+{
+  return __builtin_ia32_pmuludq256((__v8si)__a, (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_or_si256(__m256i __a, __m256i __b)
+{
+  return __a | __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sad_epu8(__m256i __a, __m256i __b)
+{
+  return __builtin_ia32_psadbw256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_shuffle_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_pshufb256((__v32qi)__a, (__v32qi)__b);
+}
+
+#define _mm256_shuffle_epi32(a, imm) __extension__ ({ \
+  __m256i __a = (a); \
+  (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)_mm256_set1_epi32(0), \
+                                   (imm) & 0x3, ((imm) & 0xc) >> 2, \
+                                   ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \
+                                   4 + (((imm) & 0x03) >> 0), \
+                                   4 + (((imm) & 0x0c) >> 2), \
+                                   4 + (((imm) & 0x30) >> 4), \
+                                   4 + (((imm) & 0xc0) >> 6)); })
+
+#define _mm256_shufflehi_epi16(a, imm) __extension__ ({ \
+  __m256i __a = (a); \
+  (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)_mm256_set1_epi16(0), \
+                                   0, 1, 2, 3, \
+                                   4 + (((imm) & 0x03) >> 0), \
+                                   4 + (((imm) & 0x0c) >> 2), \
+                                   4 + (((imm) & 0x30) >> 4), \
+                                   4 + (((imm) & 0xc0) >> 6), \
+                                   8, 9, 10, 11, \
+                                   12 + (((imm) & 0x03) >> 0), \
+                                   12 + (((imm) & 0x0c) >> 2), \
+                                   12 + (((imm) & 0x30) >> 4), \
+                                   12 + (((imm) & 0xc0) >> 6)); })
+
+#define _mm256_shufflelo_epi16(a, imm) __extension__ ({ \
+  __m256i __a = (a); \
+  (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)_mm256_set1_epi16(0), \
+                                   (imm) & 0x3,((imm) & 0xc) >> 2, \
+                                   ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \
+                                   4, 5, 6, 7, \
+                                   8 + (((imm) & 0x03) >> 0), \
+                                   8 + (((imm) & 0x0c) >> 2), \
+                                   8 + (((imm) & 0x30) >> 4), \
+                                   8 + (((imm) & 0xc0) >> 6), \
+                                   12, 13, 14, 15); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sign_epi8(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_psignb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sign_epi16(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_psignw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sign_epi32(__m256i __a, __m256i __b)
+{
+    return (__m256i)__builtin_ia32_psignd256((__v8si)__a, (__v8si)__b);
+}
+
+#define _mm256_slli_si256(a, count) __extension__ ({ \
+  __m256i __a = (a); \
+  (__m256i)__builtin_ia32_pslldqi256(__a, (count)*8); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_slli_epi16(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_psllwi256((__v16hi)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sll_epi16(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_psllw256((__v16hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_slli_epi32(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_pslldi256((__v8si)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sll_epi32(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_pslld256((__v8si)__a, (__v4si)__count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_slli_epi64(__m256i __a, int __count)
+{
+  return __builtin_ia32_psllqi256(__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sll_epi64(__m256i __a, __m128i __count)
+{
+  return __builtin_ia32_psllq256(__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srai_epi16(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_psrawi256((__v16hi)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sra_epi16(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_psraw256((__v16hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srai_epi32(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_psradi256((__v8si)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sra_epi32(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_psrad256((__v8si)__a, (__v4si)__count);
+}
+
+#define _mm256_srli_si256(a, count) __extension__ ({ \
+  __m256i __a = (a); \
+  (__m256i)__builtin_ia32_psrldqi256(__a, (count)*8); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srli_epi16(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_psrlwi256((__v16hi)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srl_epi16(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_psrlw256((__v16hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srli_epi32(__m256i __a, int __count)
+{
+  return (__m256i)__builtin_ia32_psrldi256((__v8si)__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srl_epi32(__m256i __a, __m128i __count)
+{
+  return (__m256i)__builtin_ia32_psrld256((__v8si)__a, (__v4si)__count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srli_epi64(__m256i __a, int __count)
+{
+  return __builtin_ia32_psrlqi256(__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srl_epi64(__m256i __a, __m128i __count)
+{
+  return __builtin_ia32_psrlq256(__a, __count);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v32qi)__a - (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v16hi)__a - (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)((__v8si)__a - (__v8si)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_epi64(__m256i __a, __m256i __b)
+{
+  return __a - __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_subs_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_psubsb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_subs_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_psubsw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_subs_epu8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_psubusb256((__v32qi)__a, (__v32qi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_subs_epu16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_psubusw256((__v16hi)__a, (__v16hi)__b);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 8, 32+8, 9, 32+9, 10, 32+10, 11, 32+11, 12, 32+12, 13, 32+13, 14, 32+14, 15, 32+15, 24, 32+24, 25, 32+25, 26, 32+26, 27, 32+27, 28, 32+28, 29, 32+29, 30, 32+30, 31, 32+31);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 2, 8+2, 3, 8+3, 6, 8+6, 7, 8+7);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_epi64(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector(__a, __b, 1, 4+1, 3, 4+3);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_epi8(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v32qi)__a, (__v32qi)__b, 0, 32+0, 1, 32+1, 2, 32+2, 3, 32+3, 4, 32+4, 5, 32+5, 6, 32+6, 7, 32+7, 16, 32+16, 17, 32+17, 18, 32+18, 19, 32+19, 20, 32+20, 21, 32+21, 22, 32+22, 23, 32+23);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_epi16(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v16hi)__a, (__v16hi)__b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector((__v8si)__a, (__v8si)__b, 0, 8+0, 1, 8+1, 4, 8+4, 5, 8+5);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_epi64(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_shufflevector(__a, __b, 0, 4+0, 2, 4+2);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_xor_si256(__m256i __a, __m256i __b)
+{
+  return __a ^ __b;
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_load_si256(__m256i *__V)
+{
+  return (__m256i)__builtin_ia32_movntdqa256((__v4di *)__V);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_broadcastss_ps(__m128 __X)
+{
+  return (__m128)__builtin_ia32_vbroadcastss_ps((__v4sf)__X);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastss_ps(__m128 __X)
+{
+  return (__m256)__builtin_ia32_vbroadcastss_ps256((__v4sf)__X);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastsd_pd(__m128d __X)
+{
+  return (__m256d)__builtin_ia32_vbroadcastsd_pd256((__v2df)__X);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastsi128_si256(__m128i __X)
+{
+  return (__m256i)__builtin_ia32_vbroadcastsi256(__X);
+}
+
+#define _mm_blend_epi32(V1, V2, M) __extension__ ({ \
+  __m128i __V1 = (V1); \
+  __m128i __V2 = (V2); \
+  (__m128i)__builtin_shufflevector((__v4si)__V1, (__v4si)__V2, \
+                                   (((M) & 0x01) ? 4 : 0), \
+                                   (((M) & 0x02) ? 5 : 1), \
+                                   (((M) & 0x04) ? 6 : 2), \
+                                   (((M) & 0x08) ? 7 : 3)); })
+
+#define _mm256_blend_epi32(V1, V2, M) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m256i __V2 = (V2); \
+  (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \
+                                   (((M) & 0x01) ?  8 : 0), \
+                                   (((M) & 0x02) ?  9 : 1), \
+                                   (((M) & 0x04) ? 10 : 2), \
+                                   (((M) & 0x08) ? 11 : 3), \
+                                   (((M) & 0x10) ? 12 : 4), \
+                                   (((M) & 0x20) ? 13 : 5), \
+                                   (((M) & 0x40) ? 14 : 6), \
+                                   (((M) & 0x80) ? 15 : 7)); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastb_epi8(__m128i __X)
+{
+  return (__m256i)__builtin_ia32_pbroadcastb256((__v16qi)__X);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastw_epi16(__m128i __X)
+{
+  return (__m256i)__builtin_ia32_pbroadcastw256((__v8hi)__X);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastd_epi32(__m128i __X)
+{
+  return (__m256i)__builtin_ia32_pbroadcastd256((__v4si)__X);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcastq_epi64(__m128i __X)
+{
+  return (__m256i)__builtin_ia32_pbroadcastq256(__X);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_broadcastb_epi8(__m128i __X)
+{
+  return (__m128i)__builtin_ia32_pbroadcastb128((__v16qi)__X);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_broadcastw_epi16(__m128i __X)
+{
+  return (__m128i)__builtin_ia32_pbroadcastw128((__v8hi)__X);
+}
+
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_broadcastd_epi32(__m128i __X)
+{
+  return (__m128i)__builtin_ia32_pbroadcastd128((__v4si)__X);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_broadcastq_epi64(__m128i __X)
+{
+  return (__m128i)__builtin_ia32_pbroadcastq128(__X);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar8x32_epi32(__m256i __a, __m256i __b)
+{
+  return (__m256i)__builtin_ia32_permvarsi256((__v8si)__a, (__v8si)__b);
+}
+
+#define _mm256_permute4x64_pd(V, M) __extension__ ({ \
+  __m256d __V = (V); \
+  (__m256d)__builtin_shufflevector((__v4df)__V, (__v4df) _mm256_setzero_pd(), \
+                                   (M) & 0x3, ((M) & 0xc) >> 2, \
+                                   ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); })
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar8x32_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_permvarsf256((__v8sf)__a, (__v8sf)__b);
+}
+
+#define _mm256_permute4x64_epi64(V, M) __extension__ ({ \
+  __m256i __V = (V); \
+  (__m256i)__builtin_shufflevector((__v4di)__V, (__v4di) _mm256_setzero_si256(), \
+                                   (M) & 0x3, ((M) & 0xc) >> 2, \
+                                   ((M) & 0x30) >> 4, ((M) & 0xc0) >> 6); })
+
+#define _mm256_permute2x128_si256(V1, V2, M) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m256i __V2 = (V2); \
+  (__m256i)__builtin_ia32_permti256(__V1, __V2, (M)); })
+
+#define _mm256_extracti128_si256(A, O) __extension__ ({ \
+  __m256i __A = (A); \
+  (__m128i)__builtin_ia32_extract128i256(__A, (O)); })
+
+#define _mm256_inserti128_si256(V1, V2, O) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m128i __V2 = (V2); \
+  (__m256i)__builtin_ia32_insert128i256(__V1, __V2, (O)); })
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_epi32(int const *__X, __m256i __M)
+{
+  return (__m256i)__builtin_ia32_maskloadd256((const __v8si *)__X, (__v8si)__M);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_epi64(long long const *__X, __m256i __M)
+{
+  return (__m256i)__builtin_ia32_maskloadq256((const __v4di *)__X, __M);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_epi32(int const *__X, __m128i __M)
+{
+  return (__m128i)__builtin_ia32_maskloadd((const __v4si *)__X, (__v4si)__M);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_epi64(long long const *__X, __m128i __M)
+{
+  return (__m128i)__builtin_ia32_maskloadq((const __v2di *)__X, (__v2di)__M);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_epi32(int *__X, __m256i __M, __m256i __Y)
+{
+  __builtin_ia32_maskstored256((__v8si *)__X, (__v8si)__M, (__v8si)__Y);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_epi64(long long *__X, __m256i __M, __m256i __Y)
+{
+  __builtin_ia32_maskstoreq256((__v4di *)__X, __M, __Y);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_epi32(int *__X, __m128i __M, __m128i __Y)
+{
+  __builtin_ia32_maskstored((__v4si *)__X, (__v4si)__M, (__v4si)__Y);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_epi64(long long *__X, __m128i __M, __m128i __Y)
+{
+  __builtin_ia32_maskstoreq(( __v2di *)__X, __M, __Y);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sllv_epi32(__m256i __X, __m256i __Y)
+{
+  return (__m256i)__builtin_ia32_psllv8si((__v8si)__X, (__v8si)__Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sllv_epi32(__m128i __X, __m128i __Y)
+{
+  return (__m128i)__builtin_ia32_psllv4si((__v4si)__X, (__v4si)__Y);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_sllv_epi64(__m256i __X, __m256i __Y)
+{
+  return (__m256i)__builtin_ia32_psllv4di(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sllv_epi64(__m128i __X, __m128i __Y)
+{
+  return (__m128i)__builtin_ia32_psllv2di(__X, __Y);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srav_epi32(__m256i __X, __m256i __Y)
+{
+  return (__m256i)__builtin_ia32_psrav8si((__v8si)__X, (__v8si)__Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srav_epi32(__m128i __X, __m128i __Y)
+{
+  return (__m128i)__builtin_ia32_psrav4si((__v4si)__X, (__v4si)__Y);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srlv_epi32(__m256i __X, __m256i __Y)
+{
+  return (__m256i)__builtin_ia32_psrlv8si((__v8si)__X, (__v8si)__Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srlv_epi32(__m128i __X, __m128i __Y)
+{
+  return (__m128i)__builtin_ia32_psrlv4si((__v4si)__X, (__v4si)__Y);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_srlv_epi64(__m256i __X, __m256i __Y)
+{
+  return (__m256i)__builtin_ia32_psrlv4di(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srlv_epi64(__m128i __X, __m128i __Y)
+{
+  return (__m128i)__builtin_ia32_psrlv2di(__X, __Y);
+}
+
+#define _mm_mask_i32gather_pd(a, m, i, mask, s) __extension__ ({ \
+  __m128d __a = (a); \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  __m128d __mask = (mask); \
+  (__m128d)__builtin_ia32_gatherd_pd((__v2df)__a, (const __v2df *)__m, \
+             (__v4si)__i, (__v2df)__mask, (s)); })
+
+#define _mm256_mask_i32gather_pd(a, m, i, mask, s) __extension__ ({ \
+  __m256d __a = (a); \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  __m256d __mask = (mask); \
+  (__m256d)__builtin_ia32_gatherd_pd256((__v4df)__a, (const __v4df *)__m, \
+             (__v4si)__i, (__v4df)__mask, (s)); })
+
+#define _mm_mask_i64gather_pd(a, m, i, mask, s) __extension__ ({ \
+  __m128d __a = (a); \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  __m128d __mask = (mask); \
+  (__m128d)__builtin_ia32_gatherq_pd((__v2df)__a, (const __v2df *)__m, \
+             (__v2di)__i, (__v2df)__mask, (s)); })
+
+#define _mm256_mask_i64gather_pd(a, m, i, mask, s) __extension__ ({ \
+  __m256d __a = (a); \
+  double const *__m = (m); \
+  __m256i __i = (i); \
+  __m256d __mask = (mask); \
+  (__m256d)__builtin_ia32_gatherq_pd256((__v4df)__a, (const __v4df *)__m, \
+             (__v4di)__i, (__v4df)__mask, (s)); })
+
+#define _mm_mask_i32gather_ps(a, m, i, mask, s) __extension__ ({ \
+  __m128 __a = (a); \
+  float const *__m = (m); \
+  __m128i __i = (i); \
+  __m128 __mask = (mask); \
+  (__m128)__builtin_ia32_gatherd_ps((__v4sf)__a, (const __v4sf *)__m, \
+            (__v4si)__i, (__v4sf)__mask, (s)); })
+
+#define _mm256_mask_i32gather_ps(a, m, i, mask, s) __extension__ ({ \
+  __m256 __a = (a); \
+  float const *__m = (m); \
+  __m256i __i = (i); \
+  __m256 __mask = (mask); \
+  (__m256)__builtin_ia32_gatherd_ps256((__v8sf)__a, (const __v8sf *)__m, \
+            (__v8si)__i, (__v8sf)__mask, (s)); })
+
+#define _mm_mask_i64gather_ps(a, m, i, mask, s) __extension__ ({ \
+  __m128 __a = (a); \
+  float const *__m = (m); \
+  __m128i __i = (i); \
+  __m128 __mask = (mask); \
+  (__m128)__builtin_ia32_gatherq_ps((__v4sf)__a, (const __v4sf *)__m, \
+            (__v2di)__i, (__v4sf)__mask, (s)); })
+
+#define _mm256_mask_i64gather_ps(a, m, i, mask, s) __extension__ ({ \
+  __m128 __a = (a); \
+  float const *__m = (m); \
+  __m256i __i = (i); \
+  __m128 __mask = (mask); \
+  (__m128)__builtin_ia32_gatherq_ps256((__v4sf)__a, (const __v4sf *)__m, \
+            (__v4di)__i, (__v4sf)__mask, (s)); })
+
+#define _mm_mask_i32gather_epi32(a, m, i, mask, s) __extension__ ({ \
+  __m128i __a = (a); \
+  int const *__m = (m); \
+  __m128i __i = (i); \
+  __m128i __mask = (mask); \
+  (__m128i)__builtin_ia32_gatherd_d((__v4si)__a, (const __v4si *)__m, \
+            (__v4si)__i, (__v4si)__mask, (s)); })
+
+#define _mm256_mask_i32gather_epi32(a, m, i, mask, s) __extension__ ({ \
+  __m256i __a = (a); \
+  int const *__m = (m); \
+  __m256i __i = (i); \
+  __m256i __mask = (mask); \
+  (__m256i)__builtin_ia32_gatherd_d256((__v8si)__a, (const __v8si *)__m, \
+            (__v8si)__i, (__v8si)__mask, (s)); })
+
+#define _mm_mask_i64gather_epi32(a, m, i, mask, s) __extension__ ({ \
+  __m128i __a = (a); \
+  int const *__m = (m); \
+  __m128i __i = (i); \
+  __m128i __mask = (mask); \
+  (__m128i)__builtin_ia32_gatherq_d((__v4si)__a, (const __v4si *)__m, \
+            (__v2di)__i, (__v4si)__mask, (s)); })
+
+#define _mm256_mask_i64gather_epi32(a, m, i, mask, s) __extension__ ({ \
+  __m128i __a = (a); \
+  int const *__m = (m); \
+  __m256i __i = (i); \
+  __m128i __mask = (mask); \
+  (__m128i)__builtin_ia32_gatherq_d256((__v4si)__a, (const __v4si *)__m, \
+            (__v4di)__i, (__v4si)__mask, (s)); })
+
+#define _mm_mask_i32gather_epi64(a, m, i, mask, s) __extension__ ({ \
+  __m128i __a = (a); \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  __m128i __mask = (mask); \
+  (__m128i)__builtin_ia32_gatherd_q((__v2di)__a, (const __v2di *)__m, \
+             (__v4si)__i, (__v2di)__mask, (s)); })
+
+#define _mm256_mask_i32gather_epi64(a, m, i, mask, s) __extension__ ({ \
+  __m256i __a = (a); \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  __m256i __mask = (mask); \
+  (__m256i)__builtin_ia32_gatherd_q256((__v4di)__a, (const __v4di *)__m, \
+             (__v4si)__i, (__v4di)__mask, (s)); })
+
+#define _mm_mask_i64gather_epi64(a, m, i, mask, s) __extension__ ({ \
+  __m128i __a = (a); \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  __m128i __mask = (mask); \
+  (__m128i)__builtin_ia32_gatherq_q((__v2di)__a, (const __v2di *)__m, \
+             (__v2di)__i, (__v2di)__mask, (s)); })
+
+#define _mm256_mask_i64gather_epi64(a, m, i, mask, s) __extension__ ({ \
+  __m256i __a = (a); \
+  long long const *__m = (m); \
+  __m256i __i = (i); \
+  __m256i __mask = (mask); \
+  (__m256i)__builtin_ia32_gatherq_q256((__v4di)__a, (const __v4di *)__m, \
+             (__v4di)__i, (__v4di)__mask, (s)); })
+
+#define _mm_i32gather_pd(m, i, s) __extension__ ({ \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128d)__builtin_ia32_gatherd_pd((__v2df)_mm_setzero_pd(), \
+             (const __v2df *)__m, (__v4si)__i, \
+             (__v2df)_mm_set1_pd((double)(long long int)-1), (s)); })
+
+#define _mm256_i32gather_pd(m, i, s) __extension__ ({ \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  (__m256d)__builtin_ia32_gatherd_pd256((__v4df)_mm256_setzero_pd(), \
+             (const __v4df *)__m, (__v4si)__i, \
+             (__v4df)_mm256_set1_pd((double)(long long int)-1), (s)); })
+
+#define _mm_i64gather_pd(m, i, s) __extension__ ({ \
+  double const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128d)__builtin_ia32_gatherq_pd((__v2df)_mm_setzero_pd(), \
+             (const __v2df *)__m, (__v2di)__i, \
+             (__v2df)_mm_set1_pd((double)(long long int)-1), (s)); })
+
+#define _mm256_i64gather_pd(m, i, s) __extension__ ({ \
+  double const *__m = (m); \
+  __m256i __i = (i); \
+  (__m256d)__builtin_ia32_gatherq_pd256((__v4df)_mm256_setzero_pd(), \
+             (const __v4df *)__m, (__v4di)__i, \
+             (__v4df)_mm256_set1_pd((double)(long long int)-1), (s)); })
+
+#define _mm_i32gather_ps(m, i, s) __extension__ ({ \
+  float const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128)__builtin_ia32_gatherd_ps((__v4sf)_mm_setzero_ps(), \
+             (const __v4sf *)__m, (__v4si)__i, \
+             (__v4sf)_mm_set1_ps((float)(int)-1), (s)); })
+
+#define _mm256_i32gather_ps(m, i, s) __extension__ ({ \
+  float const *__m = (m); \
+  __m256i __i = (i); \
+  (__m256)__builtin_ia32_gatherd_ps256((__v8sf)_mm256_setzero_ps(), \
+             (const __v8sf *)__m, (__v8si)__i, \
+             (__v8sf)_mm256_set1_ps((float)(int)-1), (s)); })
+
+#define _mm_i64gather_ps(m, i, s) __extension__ ({ \
+  float const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128)__builtin_ia32_gatherq_ps((__v4sf)_mm_setzero_ps(), \
+             (const __v4sf *)__m, (__v2di)__i, \
+             (__v4sf)_mm_set1_ps((float)(int)-1), (s)); })
+
+#define _mm256_i64gather_ps(m, i, s) __extension__ ({ \
+  float const *__m = (m); \
+  __m256i __i = (i); \
+  (__m128)__builtin_ia32_gatherq_ps256((__v4sf)_mm_setzero_ps(), \
+             (const __v4sf *)__m, (__v4di)__i, \
+             (__v4sf)_mm_set1_ps((float)(int)-1), (s)); })
+
+#define _mm_i32gather_epi32(m, i, s) __extension__ ({ \
+  int const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128i)__builtin_ia32_gatherd_d((__v4si)_mm_setzero_si128(), \
+            (const __v4si *)__m, (__v4si)__i, \
+            (__v4si)_mm_set1_epi32(-1), (s)); })
+
+#define _mm256_i32gather_epi32(m, i, s) __extension__ ({ \
+  int const *__m = (m); \
+  __m256i __i = (i); \
+  (__m256i)__builtin_ia32_gatherd_d256((__v8si)_mm256_setzero_si256(), \
+            (const __v8si *)__m, (__v8si)__i, \
+            (__v8si)_mm256_set1_epi32(-1), (s)); })
+
+#define _mm_i64gather_epi32(m, i, s) __extension__ ({ \
+  int const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128i)__builtin_ia32_gatherq_d((__v4si)_mm_setzero_si128(), \
+            (const __v4si *)__m, (__v2di)__i, \
+            (__v4si)_mm_set1_epi32(-1), (s)); })
+
+#define _mm256_i64gather_epi32(m, i, s) __extension__ ({ \
+  int const *__m = (m); \
+  __m256i __i = (i); \
+  (__m128i)__builtin_ia32_gatherq_d256((__v4si)_mm_setzero_si128(), \
+            (const __v4si *)__m, (__v4di)__i, \
+            (__v4si)_mm_set1_epi32(-1), (s)); })
+
+#define _mm_i32gather_epi64(m, i, s) __extension__ ({ \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128i)__builtin_ia32_gatherd_q((__v2di)_mm_setzero_si128(), \
+             (const __v2di *)__m, (__v4si)__i, \
+             (__v2di)_mm_set1_epi64x(-1), (s)); })
+
+#define _mm256_i32gather_epi64(m, i, s) __extension__ ({ \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  (__m256i)__builtin_ia32_gatherd_q256((__v4di)_mm256_setzero_si256(), \
+             (const __v4di *)__m, (__v4si)__i, \
+             (__v4di)_mm256_set1_epi64x(-1), (s)); })
+
+#define _mm_i64gather_epi64(m, i, s) __extension__ ({ \
+  long long const *__m = (m); \
+  __m128i __i = (i); \
+  (__m128i)__builtin_ia32_gatherq_q((__v2di)_mm_setzero_si128(), \
+             (const __v2di *)__m, (__v2di)__i, \
+             (__v2di)_mm_set1_epi64x(-1), (s)); })
+
+#define _mm256_i64gather_epi64(m, i, s) __extension__ ({ \
+  long long const *__m = (m); \
+  __m256i __i = (i); \
+  (__m256i)__builtin_ia32_gatherq_q256((__v4di)_mm256_setzero_si256(), \
+             (const __v4di *)__m, (__v4di)__i, \
+             (__v4di)_mm256_set1_epi64x(-1), (s)); })
+
+#endif /* __AVX2INTRIN_H */
diff --git a/lib/clang/3.5.2/include/avxintrin.h b/lib/clang/3.5.2/include/avxintrin.h
new file mode 100644
index 0000000..4e1044a
--- /dev/null
+++ b/lib/clang/3.5.2/include/avxintrin.h
@@ -0,0 +1,1239 @@
+/*===---- avxintrin.h - AVX intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <avxintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __AVXINTRIN_H
+#define __AVXINTRIN_H
+
+typedef double __v4df __attribute__ ((__vector_size__ (32)));
+typedef float __v8sf __attribute__ ((__vector_size__ (32)));
+typedef long long __v4di __attribute__ ((__vector_size__ (32)));
+typedef int __v8si __attribute__ ((__vector_size__ (32)));
+typedef short __v16hi __attribute__ ((__vector_size__ (32)));
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+
+typedef float __m256 __attribute__ ((__vector_size__ (32)));
+typedef double __m256d __attribute__((__vector_size__(32)));
+typedef long long __m256i __attribute__((__vector_size__(32)));
+
+/* Arithmetic */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_add_pd(__m256d __a, __m256d __b)
+{
+  return __a+__b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_add_ps(__m256 __a, __m256 __b)
+{
+  return __a+__b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_pd(__m256d __a, __m256d __b)
+{
+  return __a-__b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_sub_ps(__m256 __a, __m256 __b)
+{
+  return __a-__b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_addsub_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)__builtin_ia32_addsubpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_addsub_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_addsubps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_div_pd(__m256d __a, __m256d __b)
+{
+  return __a / __b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_div_ps(__m256 __a, __m256 __b)
+{
+  return __a / __b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_max_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)__builtin_ia32_maxpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_max_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_maxps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_min_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)__builtin_ia32_minpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_min_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_minps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_pd(__m256d __a, __m256d __b)
+{
+  return __a * __b;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_mul_ps(__m256 __a, __m256 __b)
+{
+  return __a * __b;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_sqrt_pd(__m256d __a)
+{
+  return (__m256d)__builtin_ia32_sqrtpd256((__v4df)__a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_sqrt_ps(__m256 __a)
+{
+  return (__m256)__builtin_ia32_sqrtps256((__v8sf)__a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_rsqrt_ps(__m256 __a)
+{
+  return (__m256)__builtin_ia32_rsqrtps256((__v8sf)__a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_rcp_ps(__m256 __a)
+{
+  return (__m256)__builtin_ia32_rcpps256((__v8sf)__a);
+}
+
+#define _mm256_round_pd(V, M) __extension__ ({ \
+    __m256d __V = (V); \
+    (__m256d)__builtin_ia32_roundpd256((__v4df)__V, (M)); })
+
+#define _mm256_round_ps(V, M) __extension__ ({ \
+  __m256 __V = (V); \
+  (__m256)__builtin_ia32_roundps256((__v8sf)__V, (M)); })
+
+#define _mm256_ceil_pd(V)  _mm256_round_pd((V), _MM_FROUND_CEIL)
+#define _mm256_floor_pd(V) _mm256_round_pd((V), _MM_FROUND_FLOOR)
+#define _mm256_ceil_ps(V)  _mm256_round_ps((V), _MM_FROUND_CEIL)
+#define _mm256_floor_ps(V) _mm256_round_ps((V), _MM_FROUND_FLOOR)
+
+/* Logical */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_and_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)((__v4di)__a & (__v4di)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_and_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)((__v8si)__a & (__v8si)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_andnot_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)(~(__v4di)__a & (__v4di)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_andnot_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)(~(__v8si)__a & (__v8si)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_or_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)((__v4di)__a | (__v4di)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_or_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)((__v8si)__a | (__v8si)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_xor_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)((__v4di)__a ^ (__v4di)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_xor_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)((__v8si)__a ^ (__v8si)__b);
+}
+
+/* Horizontal arithmetic */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)__builtin_ia32_haddpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_hadd_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_haddps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_pd(__m256d __a, __m256d __b)
+{
+  return (__m256d)__builtin_ia32_hsubpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_hsub_ps(__m256 __a, __m256 __b)
+{
+  return (__m256)__builtin_ia32_hsubps256((__v8sf)__a, (__v8sf)__b);
+}
+
+/* Vector permutations */
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_permutevar_pd(__m128d __a, __m128i __c)
+{
+  return (__m128d)__builtin_ia32_vpermilvarpd((__v2df)__a, (__v2di)__c);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar_pd(__m256d __a, __m256i __c)
+{
+  return (__m256d)__builtin_ia32_vpermilvarpd256((__v4df)__a, (__v4di)__c);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_permutevar_ps(__m128 __a, __m128i __c)
+{
+  return (__m128)__builtin_ia32_vpermilvarps((__v4sf)__a, (__v4si)__c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_permutevar_ps(__m256 __a, __m256i __c)
+{
+  return (__m256)__builtin_ia32_vpermilvarps256((__v8sf)__a,
+						  (__v8si)__c);
+}
+
+#define _mm_permute_pd(A, C) __extension__ ({ \
+  __m128d __A = (A); \
+  (__m128d)__builtin_shufflevector((__v2df)__A, (__v2df) _mm_setzero_pd(), \
+                                   (C) & 0x1, ((C) & 0x2) >> 1); })
+
+#define _mm256_permute_pd(A, C) __extension__ ({ \
+  __m256d __A = (A); \
+  (__m256d)__builtin_shufflevector((__v4df)__A, (__v4df) _mm256_setzero_pd(), \
+                                   (C) & 0x1, ((C) & 0x2) >> 1, \
+                                   2 + (((C) & 0x4) >> 2), \
+                                   2 + (((C) & 0x8) >> 3)); })
+
+#define _mm_permute_ps(A, C) __extension__ ({ \
+  __m128 __A = (A); \
+  (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \
+                                   (C) & 0x3, ((C) & 0xc) >> 2, \
+                                   ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6); })
+
+#define _mm256_permute_ps(A, C) __extension__ ({ \
+  __m256 __A = (A); \
+  (__m256)__builtin_shufflevector((__v8sf)__A, (__v8sf) _mm256_setzero_ps(), \
+                                  (C) & 0x3, ((C) & 0xc) >> 2, \
+                                  ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6, \
+                                  4 + (((C) & 0x03) >> 0), \
+                                  4 + (((C) & 0x0c) >> 2), \
+                                  4 + (((C) & 0x30) >> 4), \
+                                  4 + (((C) & 0xc0) >> 6)); })
+
+#define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \
+  __m256d __V1 = (V1); \
+  __m256d __V2 = (V2); \
+  (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)__V1, (__v4df)__V2, (M)); })
+
+#define _mm256_permute2f128_ps(V1, V2, M) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m256 __V2 = (V2); \
+  (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)__V1, (__v8sf)__V2, (M)); })
+
+#define _mm256_permute2f128_si256(V1, V2, M) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m256i __V2 = (V2); \
+  (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)__V1, (__v8si)__V2, (M)); })
+
+/* Vector Blend */
+#define _mm256_blend_pd(V1, V2, M) __extension__ ({ \
+  __m256d __V1 = (V1); \
+  __m256d __V2 = (V2); \
+  (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \
+                                   (((M) & 0x01) ? 4 : 0), \
+                                   (((M) & 0x02) ? 5 : 1), \
+                                   (((M) & 0x04) ? 6 : 2), \
+                                   (((M) & 0x08) ? 7 : 3)); })
+
+#define _mm256_blend_ps(V1, V2, M) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m256 __V2 = (V2); \
+  (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \
+                                  (((M) & 0x01) ?  8 : 0), \
+                                  (((M) & 0x02) ?  9 : 1), \
+                                  (((M) & 0x04) ? 10 : 2), \
+                                  (((M) & 0x08) ? 11 : 3), \
+                                  (((M) & 0x10) ? 12 : 4), \
+                                  (((M) & 0x20) ? 13 : 5), \
+                                  (((M) & 0x40) ? 14 : 6), \
+                                  (((M) & 0x80) ? 15 : 7)); })
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_blendv_pd(__m256d __a, __m256d __b, __m256d __c)
+{
+  return (__m256d)__builtin_ia32_blendvpd256(
+    (__v4df)__a, (__v4df)__b, (__v4df)__c);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
+{
+  return (__m256)__builtin_ia32_blendvps256(
+    (__v8sf)__a, (__v8sf)__b, (__v8sf)__c);
+}
+
+/* Vector Dot Product */
+#define _mm256_dp_ps(V1, V2, M) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m256 __V2 = (V2); \
+  (__m256)__builtin_ia32_dpps256((__v8sf)__V1, (__v8sf)__V2, (M)); })
+
+/* Vector shuffle */
+#define _mm256_shuffle_ps(a, b, mask) __extension__ ({ \
+        __m256 __a = (a); \
+        __m256 __b = (b); \
+        (__m256)__builtin_shufflevector((__v8sf)__a, (__v8sf)__b, \
+        (mask) & 0x3,                ((mask) & 0xc) >> 2, \
+        (((mask) & 0x30) >> 4) + 8,  (((mask) & 0xc0) >> 6) + 8, \
+        ((mask) & 0x3) + 4,          (((mask) & 0xc) >> 2) + 4, \
+        (((mask) & 0x30) >> 4) + 12, (((mask) & 0xc0) >> 6) + 12); })
+
+#define _mm256_shuffle_pd(a, b, mask) __extension__ ({ \
+        __m256d __a = (a); \
+        __m256d __b = (b); \
+        (__m256d)__builtin_shufflevector((__v4df)__a, (__v4df)__b, \
+        (mask) & 0x1, \
+        (((mask) & 0x2) >> 1) + 4, \
+        (((mask) & 0x4) >> 2) + 2, \
+        (((mask) & 0x8) >> 3) + 6); })
+
+/* Compare */
+#define _CMP_EQ_OQ    0x00 /* Equal (ordered, non-signaling)  */
+#define _CMP_LT_OS    0x01 /* Less-than (ordered, signaling)  */
+#define _CMP_LE_OS    0x02 /* Less-than-or-equal (ordered, signaling)  */
+#define _CMP_UNORD_Q  0x03 /* Unordered (non-signaling)  */
+#define _CMP_NEQ_UQ   0x04 /* Not-equal (unordered, non-signaling)  */
+#define _CMP_NLT_US   0x05 /* Not-less-than (unordered, signaling)  */
+#define _CMP_NLE_US   0x06 /* Not-less-than-or-equal (unordered, signaling)  */
+#define _CMP_ORD_Q    0x07 /* Ordered (nonsignaling)   */
+#define _CMP_EQ_UQ    0x08 /* Equal (unordered, non-signaling)  */
+#define _CMP_NGE_US   0x09 /* Not-greater-than-or-equal (unord, signaling)  */
+#define _CMP_NGT_US   0x0a /* Not-greater-than (unordered, signaling)  */
+#define _CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling)  */
+#define _CMP_NEQ_OQ   0x0c /* Not-equal (ordered, non-signaling)  */
+#define _CMP_GE_OS    0x0d /* Greater-than-or-equal (ordered, signaling)  */
+#define _CMP_GT_OS    0x0e /* Greater-than (ordered, signaling)  */
+#define _CMP_TRUE_UQ  0x0f /* True (unordered, non-signaling)  */
+#define _CMP_EQ_OS    0x10 /* Equal (ordered, signaling)  */
+#define _CMP_LT_OQ    0x11 /* Less-than (ordered, non-signaling)  */
+#define _CMP_LE_OQ    0x12 /* Less-than-or-equal (ordered, non-signaling)  */
+#define _CMP_UNORD_S  0x13 /* Unordered (signaling)  */
+#define _CMP_NEQ_US   0x14 /* Not-equal (unordered, signaling)  */
+#define _CMP_NLT_UQ   0x15 /* Not-less-than (unordered, non-signaling)  */
+#define _CMP_NLE_UQ   0x16 /* Not-less-than-or-equal (unord, non-signaling)  */
+#define _CMP_ORD_S    0x17 /* Ordered (signaling)  */
+#define _CMP_EQ_US    0x18 /* Equal (unordered, signaling)  */
+#define _CMP_NGE_UQ   0x19 /* Not-greater-than-or-equal (unord, non-sign)  */
+#define _CMP_NGT_UQ   0x1a /* Not-greater-than (unordered, non-signaling)  */
+#define _CMP_FALSE_OS 0x1b /* False (ordered, signaling)  */
+#define _CMP_NEQ_OS   0x1c /* Not-equal (ordered, signaling)  */
+#define _CMP_GE_OQ    0x1d /* Greater-than-or-equal (ordered, non-signaling)  */
+#define _CMP_GT_OQ    0x1e /* Greater-than (ordered, non-signaling)  */
+#define _CMP_TRUE_US  0x1f /* True (unordered, signaling)  */
+
+#define _mm_cmp_pd(a, b, c) __extension__ ({ \
+  __m128d __a = (a); \
+  __m128d __b = (b); \
+  (__m128d)__builtin_ia32_cmppd((__v2df)__a, (__v2df)__b, (c)); })
+
+#define _mm_cmp_ps(a, b, c) __extension__ ({ \
+  __m128 __a = (a); \
+  __m128 __b = (b); \
+  (__m128)__builtin_ia32_cmpps((__v4sf)__a, (__v4sf)__b, (c)); })
+
+#define _mm256_cmp_pd(a, b, c) __extension__ ({ \
+  __m256d __a = (a); \
+  __m256d __b = (b); \
+  (__m256d)__builtin_ia32_cmppd256((__v4df)__a, (__v4df)__b, (c)); })
+
+#define _mm256_cmp_ps(a, b, c) __extension__ ({ \
+  __m256 __a = (a); \
+  __m256 __b = (b); \
+  (__m256)__builtin_ia32_cmpps256((__v8sf)__a, (__v8sf)__b, (c)); })
+
+#define _mm_cmp_sd(a, b, c) __extension__ ({ \
+  __m128d __a = (a); \
+  __m128d __b = (b); \
+  (__m128d)__builtin_ia32_cmpsd((__v2df)__a, (__v2df)__b, (c)); })
+
+#define _mm_cmp_ss(a, b, c) __extension__ ({ \
+  __m128 __a = (a); \
+  __m128 __b = (b); \
+  (__m128)__builtin_ia32_cmpss((__v4sf)__a, (__v4sf)__b, (c)); })
+
+/* Vector extract */
+#define _mm256_extractf128_pd(A, O) __extension__ ({ \
+  __m256d __A = (A); \
+  (__m128d)__builtin_ia32_vextractf128_pd256((__v4df)__A, (O)); })
+
+#define _mm256_extractf128_ps(A, O) __extension__ ({ \
+  __m256 __A = (A); \
+  (__m128)__builtin_ia32_vextractf128_ps256((__v8sf)__A, (O)); })
+
+#define _mm256_extractf128_si256(A, O) __extension__ ({ \
+  __m256i __A = (A); \
+  (__m128i)__builtin_ia32_vextractf128_si256((__v8si)__A, (O)); })
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi32(__m256i __a, int const __imm)
+{
+  __v8si __b = (__v8si)__a;
+  return __b[__imm & 7];
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi16(__m256i __a, int const __imm)
+{
+  __v16hi __b = (__v16hi)__a;
+  return __b[__imm & 15];
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi8(__m256i __a, int const __imm)
+{
+  __v32qi __b = (__v32qi)__a;
+  return __b[__imm & 31];
+}
+
+#ifdef __x86_64__
+static __inline long long  __attribute__((__always_inline__, __nodebug__))
+_mm256_extract_epi64(__m256i __a, const int __imm)
+{
+  __v4di __b = (__v4di)__a;
+  return __b[__imm & 3];
+}
+#endif
+
+/* Vector insert */
+#define _mm256_insertf128_pd(V1, V2, O) __extension__ ({ \
+  __m256d __V1 = (V1); \
+  __m128d __V2 = (V2); \
+  (__m256d)__builtin_ia32_vinsertf128_pd256((__v4df)__V1, (__v2df)__V2, (O)); })
+
+#define _mm256_insertf128_ps(V1, V2, O) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m128 __V2 = (V2); \
+  (__m256)__builtin_ia32_vinsertf128_ps256((__v8sf)__V1, (__v4sf)__V2, (O)); })
+
+#define _mm256_insertf128_si256(V1, V2, O) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m128i __V2 = (V2); \
+  (__m256i)__builtin_ia32_vinsertf128_si256((__v8si)__V1, (__v4si)__V2, (O)); })
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi32(__m256i __a, int __b, int const __imm)
+{
+  __v8si __c = (__v8si)__a;
+  __c[__imm & 7] = __b;
+  return (__m256i)__c;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi16(__m256i __a, int __b, int const __imm)
+{
+  __v16hi __c = (__v16hi)__a;
+  __c[__imm & 15] = __b;
+  return (__m256i)__c;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi8(__m256i __a, int __b, int const __imm)
+{
+  __v32qi __c = (__v32qi)__a;
+  __c[__imm & 31] = __b;
+  return (__m256i)__c;
+}
+
+#ifdef __x86_64__
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_insert_epi64(__m256i __a, int __b, int const __imm)
+{
+  __v4di __c = (__v4di)__a;
+  __c[__imm & 3] = __b;
+  return (__m256i)__c;
+}
+#endif
+
+/* Conversion */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi32_pd(__m128i __a)
+{
+  return (__m256d)__builtin_ia32_cvtdq2pd256((__v4si) __a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtepi32_ps(__m256i __a)
+{
+  return (__m256)__builtin_ia32_cvtdq2ps256((__v8si) __a);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtpd_ps(__m256d __a)
+{
+  return (__m128)__builtin_ia32_cvtpd2ps256((__v4df) __a);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtps_epi32(__m256 __a)
+{
+  return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) __a);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtps_pd(__m128 __a)
+{
+  return (__m256d)__builtin_ia32_cvtps2pd256((__v4sf) __a);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvttpd_epi32(__m256d __a)
+{
+  return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtpd_epi32(__m256d __a)
+{
+  return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cvttps_epi32(__m256 __a)
+{
+  return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) __a);
+}
+
+/* Vector replicate */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_movehdup_ps(__m256 __a)
+{
+  return __builtin_shufflevector(__a, __a, 1, 1, 3, 3, 5, 5, 7, 7);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_moveldup_ps(__m256 __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 0, 2, 2, 4, 4, 6, 6);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_movedup_pd(__m256d __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 0, 2, 2);
+}
+
+/* Unpack and Interleave */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_pd(__m256d __a, __m256d __b)
+{
+  return __builtin_shufflevector(__a, __b, 1, 5, 1+2, 5+2);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_pd(__m256d __a, __m256d __b)
+{
+  return __builtin_shufflevector(__a, __b, 0, 4, 0+2, 4+2);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_unpackhi_ps(__m256 __a, __m256 __b)
+{
+  return __builtin_shufflevector(__a, __b, 2, 10, 2+1, 10+1, 6, 14, 6+1, 14+1);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_unpacklo_ps(__m256 __a, __m256 __b)
+{
+  return __builtin_shufflevector(__a, __b, 0, 8, 0+1, 8+1, 4, 12, 4+1, 12+1);
+}
+
+/* Bit Test */
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_vtestzpd((__v2df)__a, (__v2df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_vtestcpd((__v2df)__a, (__v2df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_vtestnzcpd((__v2df)__a, (__v2df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_vtestzps((__v4sf)__a, (__v4sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_vtestcps((__v4sf)__a, (__v4sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_vtestnzcps((__v4sf)__a, (__v4sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_pd(__m256d __a, __m256d __b)
+{
+  return __builtin_ia32_vtestzpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_pd(__m256d __a, __m256d __b)
+{
+  return __builtin_ia32_vtestcpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_pd(__m256d __a, __m256d __b)
+{
+  return __builtin_ia32_vtestnzcpd256((__v4df)__a, (__v4df)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_ps(__m256 __a, __m256 __b)
+{
+  return __builtin_ia32_vtestzps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_ps(__m256 __a, __m256 __b)
+{
+  return __builtin_ia32_vtestcps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_ps(__m256 __a, __m256 __b)
+{
+  return __builtin_ia32_vtestnzcps256((__v8sf)__a, (__v8sf)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testz_si256(__m256i __a, __m256i __b)
+{
+  return __builtin_ia32_ptestz256((__v4di)__a, (__v4di)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testc_si256(__m256i __a, __m256i __b)
+{
+  return __builtin_ia32_ptestc256((__v4di)__a, (__v4di)__b);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_testnzc_si256(__m256i __a, __m256i __b)
+{
+  return __builtin_ia32_ptestnzc256((__v4di)__a, (__v4di)__b);
+}
+
+/* Vector extract sign mask */
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_movemask_pd(__m256d __a)
+{
+  return __builtin_ia32_movmskpd256((__v4df)__a);
+}
+
+static __inline int __attribute__((__always_inline__, __nodebug__))
+_mm256_movemask_ps(__m256 __a)
+{
+  return __builtin_ia32_movmskps256((__v8sf)__a);
+}
+
+/* Vector __zero */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_zeroall(void)
+{
+  __builtin_ia32_vzeroall();
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_zeroupper(void)
+{
+  __builtin_ia32_vzeroupper();
+}
+
+/* Vector load with broadcast */
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_broadcast_ss(float const *__a)
+{
+  float __f = *__a;
+  return (__m128)(__v4sf){ __f, __f, __f, __f };
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_sd(double const *__a)
+{
+  double __d = *__a;
+  return (__m256d)(__v4df){ __d, __d, __d, __d };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_ss(float const *__a)
+{
+  float __f = *__a;
+  return (__m256)(__v8sf){ __f, __f, __f, __f, __f, __f, __f, __f };
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_pd(__m128d const *__a)
+{
+  return (__m256d)__builtin_ia32_vbroadcastf128_pd256(__a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_broadcast_ps(__m128 const *__a)
+{
+  return (__m256)__builtin_ia32_vbroadcastf128_ps256(__a);
+}
+
+/* SIMD load ops */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_load_pd(double const *__p)
+{
+  return *(__m256d *)__p;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_load_ps(float const *__p)
+{
+  return *(__m256 *)__p;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_pd(double const *__p)
+{
+  struct __loadu_pd {
+    __m256d __v;
+  } __attribute__((packed, may_alias));
+  return ((struct __loadu_pd*)__p)->__v;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_ps(float const *__p)
+{
+  struct __loadu_ps {
+    __m256 __v;
+  } __attribute__((packed, may_alias));
+  return ((struct __loadu_ps*)__p)->__v;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_load_si256(__m256i const *__p)
+{
+  return *__p;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu_si256(__m256i const *__p)
+{
+  struct __loadu_si256 {
+    __m256i __v;
+  } __attribute__((packed, may_alias));
+  return ((struct __loadu_si256*)__p)->__v;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_lddqu_si256(__m256i const *__p)
+{
+  return (__m256i)__builtin_ia32_lddqu256((char const *)__p);
+}
+
+/* SIMD store ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_pd(double *__p, __m256d __a)
+{
+  *(__m256d *)__p = __a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_ps(float *__p, __m256 __a)
+{
+  *(__m256 *)__p = __a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_pd(double *__p, __m256d __a)
+{
+  __builtin_ia32_storeupd256(__p, (__v4df)__a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_ps(float *__p, __m256 __a)
+{
+  __builtin_ia32_storeups256(__p, (__v8sf)__a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_store_si256(__m256i *__p, __m256i __a)
+{
+  *__p = __a;
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu_si256(__m256i *__p, __m256i __a)
+{
+  __builtin_ia32_storedqu256((char *)__p, (__v32qi)__a);
+}
+
+/* Conditional load ops */
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_pd(double const *__p, __m128d __m)
+{
+  return (__m128d)__builtin_ia32_maskloadpd((const __v2df *)__p, (__v2df)__m);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_pd(double const *__p, __m256d __m)
+{
+  return (__m256d)__builtin_ia32_maskloadpd256((const __v4df *)__p,
+                                               (__v4df)__m);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_maskload_ps(float const *__p, __m128 __m)
+{
+  return (__m128)__builtin_ia32_maskloadps((const __v4sf *)__p, (__v4sf)__m);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_maskload_ps(float const *__p, __m256 __m)
+{
+  return (__m256)__builtin_ia32_maskloadps256((const __v8sf *)__p, (__v8sf)__m);
+}
+
+/* Conditional store ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_ps(float *__p, __m256 __m, __m256 __a)
+{
+  __builtin_ia32_maskstoreps256((__v8sf *)__p, (__v8sf)__m, (__v8sf)__a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_pd(double *__p, __m128d __m, __m128d __a)
+{
+  __builtin_ia32_maskstorepd((__v2df *)__p, (__v2df)__m, (__v2df)__a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_maskstore_pd(double *__p, __m256d __m, __m256d __a)
+{
+  __builtin_ia32_maskstorepd256((__v4df *)__p, (__v4df)__m, (__v4df)__a);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm_maskstore_ps(float *__p, __m128 __m, __m128 __a)
+{
+  __builtin_ia32_maskstoreps((__v4sf *)__p, (__v4sf)__m, (__v4sf)__a);
+}
+
+/* Cacheability support ops */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_si256(__m256i *__a, __m256i __b)
+{
+  __builtin_ia32_movntdq256((__v4di *)__a, (__v4di)__b);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_pd(double *__a, __m256d __b)
+{
+  __builtin_ia32_movntpd256(__a, (__v4df)__b);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_stream_ps(float *__p, __m256 __a)
+{
+  __builtin_ia32_movntps256(__p, (__v8sf)__a);
+}
+
+/* Create vectors */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_set_pd(double __a, double __b, double __c, double __d)
+{
+  return (__m256d){ __d, __c, __b, __a };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_set_ps(float __a, float __b, float __c, float __d,
+	            float __e, float __f, float __g, float __h)
+{
+  return (__m256){ __h, __g, __f, __e, __d, __c, __b, __a };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi32(int __i0, int __i1, int __i2, int __i3,
+		             int __i4, int __i5, int __i6, int __i7)
+{
+  return (__m256i)(__v8si){ __i7, __i6, __i5, __i4, __i3, __i2, __i1, __i0 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi16(short __w15, short __w14, short __w13, short __w12,
+		             short __w11, short __w10, short __w09, short __w08,
+		             short __w07, short __w06, short __w05, short __w04,
+		             short __w03, short __w02, short __w01, short __w00)
+{
+  return (__m256i)(__v16hi){ __w00, __w01, __w02, __w03, __w04, __w05, __w06,
+    __w07, __w08, __w09, __w10, __w11, __w12, __w13, __w14, __w15 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi8(char __b31, char __b30, char __b29, char __b28,
+		            char __b27, char __b26, char __b25, char __b24,
+		            char __b23, char __b22, char __b21, char __b20,
+		            char __b19, char __b18, char __b17, char __b16,
+		            char __b15, char __b14, char __b13, char __b12,
+		            char __b11, char __b10, char __b09, char __b08,
+		            char __b07, char __b06, char __b05, char __b04,
+		            char __b03, char __b02, char __b01, char __b00)
+{
+  return (__m256i)(__v32qi){
+    __b00, __b01, __b02, __b03, __b04, __b05, __b06, __b07,
+    __b08, __b09, __b10, __b11, __b12, __b13, __b14, __b15,
+    __b16, __b17, __b18, __b19, __b20, __b21, __b22, __b23,
+    __b24, __b25, __b26, __b27, __b28, __b29, __b30, __b31
+  };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set_epi64x(long long __a, long long __b, long long __c, long long __d)
+{
+  return (__m256i)(__v4di){ __d, __c, __b, __a };
+}
+
+/* Create vectors with elements in reverse order */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_pd(double __a, double __b, double __c, double __d)
+{
+  return (__m256d){ __a, __b, __c, __d };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_ps(float __a, float __b, float __c, float __d,
+		           float __e, float __f, float __g, float __h)
+{
+  return (__m256){ __a, __b, __c, __d, __e, __f, __g, __h };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi32(int __i0, int __i1, int __i2, int __i3,
+		              int __i4, int __i5, int __i6, int __i7)
+{
+  return (__m256i)(__v8si){ __i0, __i1, __i2, __i3, __i4, __i5, __i6, __i7 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi16(short __w15, short __w14, short __w13, short __w12,
+		   short __w11, short __w10, short __w09, short __w08,
+		   short __w07, short __w06, short __w05, short __w04,
+		   short __w03, short __w02, short __w01, short __w00)
+{
+  return (__m256i)(__v16hi){ __w15, __w14, __w13, __w12, __w11, __w10, __w09,
+    __w08, __w07, __w06, __w05, __w04, __w03, __w02, __w01, __w00 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi8(char __b31, char __b30, char __b29, char __b28,
+		             char __b27, char __b26, char __b25, char __b24,
+		             char __b23, char __b22, char __b21, char __b20,
+		             char __b19, char __b18, char __b17, char __b16,
+		             char __b15, char __b14, char __b13, char __b12,
+		             char __b11, char __b10, char __b09, char __b08,
+		             char __b07, char __b06, char __b05, char __b04,
+		             char __b03, char __b02, char __b01, char __b00)
+{
+  return (__m256i)(__v32qi){
+    __b31, __b30, __b29, __b28, __b27, __b26, __b25, __b24,
+		__b23, __b22, __b21, __b20, __b19, __b18, __b17, __b16,
+		__b15, __b14, __b13, __b12, __b11, __b10, __b09, __b08,
+		__b07, __b06, __b05, __b04, __b03, __b02, __b01, __b00 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setr_epi64x(long long __a, long long __b, long long __c, long long __d)
+{
+  return (__m256i)(__v4di){ __a, __b, __c, __d };
+}
+
+/* Create vectors with repeated elements */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_pd(double __w)
+{
+  return (__m256d){ __w, __w, __w, __w };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_ps(float __w)
+{
+  return (__m256){ __w, __w, __w, __w, __w, __w, __w, __w };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi32(int __i)
+{
+  return (__m256i)(__v8si){ __i, __i, __i, __i, __i, __i, __i, __i };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi16(short __w)
+{
+  return (__m256i)(__v16hi){ __w, __w, __w, __w, __w, __w, __w, __w, __w, __w,
+    __w, __w, __w, __w, __w, __w };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi8(char __b)
+{
+  return (__m256i)(__v32qi){ __b, __b, __b, __b, __b, __b, __b, __b, __b, __b,
+    __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b,
+    __b, __b, __b, __b, __b, __b, __b };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_set1_epi64x(long long __q)
+{
+  return (__m256i)(__v4di){ __q, __q, __q, __q };
+}
+
+/* Create __zeroed vectors */
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_pd(void)
+{
+  return (__m256d){ 0, 0, 0, 0 };
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_ps(void)
+{
+  return (__m256){ 0, 0, 0, 0, 0, 0, 0, 0 };
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_setzero_si256(void)
+{
+  return (__m256i){ 0LL, 0LL, 0LL, 0LL };
+}
+
+/* Cast between vector types */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd_ps(__m256d __a)
+{
+  return (__m256)__a;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd_si256(__m256d __a)
+{
+  return (__m256i)__a;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castps_pd(__m256 __a)
+{
+  return (__m256d)__a;
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castps_si256(__m256 __a)
+{
+  return (__m256i)__a;
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_ps(__m256i __a)
+{
+  return (__m256)__a;
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_pd(__m256i __a)
+{
+  return (__m256d)__a;
+}
+
+static __inline __m128d __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd256_pd128(__m256d __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1);
+}
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm256_castps256_ps128(__m256 __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1, 2, 3);
+}
+
+static __inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi256_si128(__m256i __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_castpd128_pd256(__m128d __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1, -1, -1);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_castps128_ps256(__m128 __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1, 2, 3, -1, -1, -1, -1);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_castsi128_si256(__m128i __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 1, -1, -1);
+}
+
+/* SIMD load ops (unaligned) */
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu2_m128(float const *__addr_hi, float const *__addr_lo)
+{
+  struct __loadu_ps {
+    __m128 __v;
+  } __attribute__((__packed__, __may_alias__));
+
+  __m256 __v256 = _mm256_castps128_ps256(((struct __loadu_ps*)__addr_lo)->__v);
+  return _mm256_insertf128_ps(__v256, ((struct __loadu_ps*)__addr_hi)->__v, 1);
+}
+
+static __inline __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu2_m128d(double const *__addr_hi, double const *__addr_lo)
+{
+  struct __loadu_pd {
+    __m128d __v;
+  } __attribute__((__packed__, __may_alias__));
+  
+  __m256d __v256 = _mm256_castpd128_pd256(((struct __loadu_pd*)__addr_lo)->__v);
+  return _mm256_insertf128_pd(__v256, ((struct __loadu_pd*)__addr_hi)->__v, 1);
+}
+
+static __inline __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_loadu2_m128i(__m128i const *__addr_hi, __m128i const *__addr_lo)
+{
+  struct __loadu_si128 {
+    __m128i __v;
+  } __attribute__((packed, may_alias));
+  __m256i __v256 = _mm256_castsi128_si256(
+    ((struct __loadu_si128*)__addr_lo)->__v);
+  return _mm256_insertf128_si256(__v256,
+                                 ((struct __loadu_si128*)__addr_hi)->__v, 1);
+}
+
+/* SIMD store ops (unaligned) */
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu2_m128(float *__addr_hi, float *__addr_lo, __m256 __a)
+{
+  __m128 __v128;
+
+  __v128 = _mm256_castps256_ps128(__a);
+  __builtin_ia32_storeups(__addr_lo, __v128);
+  __v128 = _mm256_extractf128_ps(__a, 1);
+  __builtin_ia32_storeups(__addr_hi, __v128);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu2_m128d(double *__addr_hi, double *__addr_lo, __m256d __a)
+{
+  __m128d __v128;
+
+  __v128 = _mm256_castpd256_pd128(__a);
+  __builtin_ia32_storeupd(__addr_lo, __v128);
+  __v128 = _mm256_extractf128_pd(__a, 1);
+  __builtin_ia32_storeupd(__addr_hi, __v128);
+}
+
+static __inline void __attribute__((__always_inline__, __nodebug__))
+_mm256_storeu2_m128i(__m128i *__addr_hi, __m128i *__addr_lo, __m256i __a)
+{
+  __m128i __v128;
+
+  __v128 = _mm256_castsi256_si128(__a);
+  __builtin_ia32_storedqu((char *)__addr_lo, (__v16qi)__v128);
+  __v128 = _mm256_extractf128_si256(__a, 1);
+  __builtin_ia32_storedqu((char *)__addr_hi, (__v16qi)__v128);
+}
+
+#endif /* __AVXINTRIN_H */
diff --git a/lib/clang/3.5.2/include/bmi2intrin.h b/lib/clang/3.5.2/include/bmi2intrin.h
new file mode 100644
index 0000000..a05cfad
--- /dev/null
+++ b/lib/clang/3.5.2/include/bmi2intrin.h
@@ -0,0 +1,94 @@
+/*===---- bmi2intrin.h - BMI2 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
+#error "Never use <bmi2intrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __BMI2__
+# error "BMI2 instruction set not enabled"
+#endif /* __BMI2__ */
+
+#ifndef __BMI2INTRIN_H
+#define __BMI2INTRIN_H
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_bzhi_u32(unsigned int __X, unsigned int __Y)
+{
+  return __builtin_ia32_bzhi_si(__X, __Y);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_pdep_u32(unsigned int __X, unsigned int __Y)
+{
+  return __builtin_ia32_pdep_si(__X, __Y);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_pext_u32(unsigned int __X, unsigned int __Y)
+{
+  return __builtin_ia32_pext_si(__X, __Y);
+}
+
+#ifdef  __x86_64__
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_bzhi_u64(unsigned long long __X, unsigned long long __Y)
+{
+  return __builtin_ia32_bzhi_di(__X, __Y);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_pdep_u64(unsigned long long __X, unsigned long long __Y)
+{
+  return __builtin_ia32_pdep_di(__X, __Y);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_pext_u64(unsigned long long __X, unsigned long long __Y)
+{
+  return __builtin_ia32_pext_di(__X, __Y);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_mulx_u64 (unsigned long long __X, unsigned long long __Y,
+	   unsigned long long *__P)
+{
+  unsigned __int128 __res = (unsigned __int128) __X * __Y;
+  *__P = (unsigned long long) (__res >> 64);
+  return (unsigned long long) __res;
+}
+
+#else /* !__x86_64__ */
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P)
+{
+  unsigned long long __res = (unsigned long long) __X * __Y;
+  *__P = (unsigned int) (__res >> 32);
+  return (unsigned int) __res;
+}
+
+#endif /* !__x86_64__  */
+
+#endif /* __BMI2INTRIN_H */
diff --git a/lib/clang/3.5.2/include/bmiintrin.h b/lib/clang/3.5.2/include/bmiintrin.h
new file mode 100644
index 0000000..43c4a5e
--- /dev/null
+++ b/lib/clang/3.5.2/include/bmiintrin.h
@@ -0,0 +1,148 @@
+/*===---- bmiintrin.h - BMI intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
+#error "Never use <bmiintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __BMI__
+# error "BMI instruction set not enabled"
+#endif /* __BMI__ */
+
+#ifndef __BMIINTRIN_H
+#define __BMIINTRIN_H
+
+#define _tzcnt_u16(a)     (__tzcnt_u16((a)))
+#define _andn_u32(a, b)   (__andn_u32((a), (b)))
+/* _bextr_u32 != __bextr_u32 */
+#define _blsi_u32(a)      (__blsi_u32((a)))
+#define _blsmsk_u32(a)    (__blsmsk_u32((a)))
+#define _blsr_u32(a)      (__blsr_u32((a)))
+#define _tzcnt_u32(a)     (__tzcnt_u32((a)))
+
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__tzcnt_u16(unsigned short __X)
+{
+  return __builtin_ctzs(__X);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__andn_u32(unsigned int __X, unsigned int __Y)
+{
+  return ~__X & __Y;
+}
+
+/* AMD-specified, double-leading-underscore version of BEXTR */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__bextr_u32(unsigned int __X, unsigned int __Y)
+{
+  return __builtin_ia32_bextr_u32(__X, __Y);
+}
+
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blsi_u32(unsigned int __X)
+{
+  return __X & -__X;
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blsmsk_u32(unsigned int __X)
+{
+  return __X ^ (__X - 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blsr_u32(unsigned int __X)
+{
+  return __X & (__X - 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__tzcnt_u32(unsigned int __X)
+{
+  return __builtin_ctz(__X);
+}
+
+#ifdef __x86_64__
+
+#define _andn_u64(a, b)   (__andn_u64((a), (b)))
+/* _bextr_u64 != __bextr_u64 */
+#define _blsi_u64(a)      (__blsi_u64((a)))
+#define _blsmsk_u64(a)    (__blsmsk_u64((a)))
+#define _blsr_u64(a)      (__blsr_u64((a)))
+#define _tzcnt_u64(a)     (__tzcnt_u64((a)))
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__andn_u64 (unsigned long long __X, unsigned long long __Y)
+{
+  return ~__X & __Y;
+}
+
+/* AMD-specified, double-leading-underscore version of BEXTR */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__bextr_u64(unsigned long long __X, unsigned long long __Y)
+{
+  return __builtin_ia32_bextr_u64(__X, __Y);
+}
+
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__blsi_u64(unsigned long long __X)
+{
+  return __X & -__X;
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__blsmsk_u64(unsigned long long __X)
+{
+  return __X ^ (__X - 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__blsr_u64(unsigned long long __X)
+{
+  return __X & (__X - 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__tzcnt_u64(unsigned long long __X)
+{
+  return __builtin_ctzll(__X);
+}
+
+#endif /* __x86_64__ */
+
+#endif /* __BMIINTRIN_H */
diff --git a/lib/clang/3.5.2/include/cpuid.h b/lib/clang/3.5.2/include/cpuid.h
new file mode 100644
index 0000000..f9254e9
--- /dev/null
+++ b/lib/clang/3.5.2/include/cpuid.h
@@ -0,0 +1,157 @@
+/*===---- cpuid.h - X86 cpu model detection --------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !(__x86_64__ || __i386__)
+#error this header is for x86 only
+#endif
+
+/* Features in %ecx for level 1 */
+#define bit_SSE3        0x00000001
+#define bit_PCLMULQDQ   0x00000002
+#define bit_DTES64      0x00000004
+#define bit_MONITOR     0x00000008
+#define bit_DSCPL       0x00000010
+#define bit_VMX         0x00000020
+#define bit_SMX         0x00000040
+#define bit_EIST        0x00000080
+#define bit_TM2         0x00000100
+#define bit_SSSE3       0x00000200
+#define bit_CNXTID      0x00000400
+#define bit_FMA         0x00001000
+#define bit_CMPXCHG16B  0x00002000
+#define bit_xTPR        0x00004000
+#define bit_PDCM        0x00008000
+#define bit_PCID        0x00020000
+#define bit_DCA         0x00040000
+#define bit_SSE41       0x00080000
+#define bit_SSE42       0x00100000
+#define bit_x2APIC      0x00200000
+#define bit_MOVBE       0x00400000
+#define bit_POPCNT      0x00800000
+#define bit_TSCDeadline 0x01000000
+#define bit_AESNI       0x02000000
+#define bit_XSAVE       0x04000000
+#define bit_OSXSAVE     0x08000000
+#define bit_AVX         0x10000000
+#define bit_RDRAND      0x40000000
+
+/* Features in %edx for level 1 */
+#define bit_FPU         0x00000001
+#define bit_VME         0x00000002
+#define bit_DE          0x00000004
+#define bit_PSE         0x00000008
+#define bit_TSC         0x00000010
+#define bit_MSR         0x00000020
+#define bit_PAE         0x00000040
+#define bit_MCE         0x00000080
+#define bit_CX8         0x00000100
+#define bit_APIC        0x00000200
+#define bit_SEP         0x00000800
+#define bit_MTRR        0x00001000
+#define bit_PGE         0x00002000
+#define bit_MCA         0x00004000
+#define bit_CMOV        0x00008000
+#define bit_PAT         0x00010000
+#define bit_PSE36       0x00020000
+#define bit_PSN         0x00040000
+#define bit_CLFSH       0x00080000
+#define bit_DS          0x00200000
+#define bit_ACPI        0x00400000
+#define bit_MMX         0x00800000
+#define bit_FXSR        0x01000000
+#define bit_FXSAVE      bit_FXSR    /* for gcc compat */
+#define bit_SSE         0x02000000
+#define bit_SSE2        0x04000000
+#define bit_SS          0x08000000
+#define bit_HTT         0x10000000
+#define bit_TM          0x20000000
+#define bit_PBE         0x80000000
+
+/* Features in %ebx for level 7 sub-leaf 0 */
+#define bit_FSGSBASE    0x00000001
+#define bit_SMEP        0x00000080
+#define bit_ENH_MOVSB   0x00000200
+
+/* PIC on i386 uses %ebx, so preserve it. */
+#if __i386__
+#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \
+    __asm("  pushl  %%ebx\n" \
+          "  cpuid\n" \
+          "  mov    %%ebx,%1\n" \
+          "  popl   %%ebx" \
+        : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \
+        : "0"(__level))
+
+#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \
+    __asm("  pushl  %%ebx\n" \
+          "  cpuid\n" \
+          "  mov    %%ebx,%1\n" \
+          "  popl   %%ebx" \
+        : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \
+        : "0"(__level), "2"(__count))
+#else
+#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \
+    __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \
+                  : "0"(__level))
+
+#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \
+    __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \
+                  : "0"(__level), "2"(__count))
+#endif
+
+static __inline int __get_cpuid (unsigned int __level, unsigned int *__eax,
+                                 unsigned int *__ebx, unsigned int *__ecx,
+                                 unsigned int *__edx) {
+    __cpuid(__level, *__eax, *__ebx, *__ecx, *__edx);
+    return 1;
+}
+
+static __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig)
+{
+    unsigned int __eax, __ebx, __ecx, __edx;
+#if __i386__
+    int __cpuid_supported;
+
+    __asm("  pushfl\n"
+          "  popl   %%eax\n"
+          "  movl   %%eax,%%ecx\n"
+          "  xorl   $0x00200000,%%eax\n"
+          "  pushl  %%eax\n"
+          "  popfl\n"
+          "  pushfl\n"
+          "  popl   %%eax\n"
+          "  movl   $0,%0\n"
+          "  cmpl   %%eax,%%ecx\n"
+          "  je     1f\n"
+          "  movl   $1,%0\n"
+          "1:"
+        : "=r" (__cpuid_supported) : : "eax", "ecx");
+    if (!__cpuid_supported)
+        return 0;
+#endif
+
+    __cpuid(__level, __eax, __ebx, __ecx, __edx);
+    if (__sig)
+        *__sig = __ebx;
+    return __eax;
+}
diff --git a/lib/clang/3.5.2/include/emmintrin.h b/lib/clang/3.5.2/include/emmintrin.h
new file mode 100644
index 0000000..b3f8569
--- /dev/null
+++ b/lib/clang/3.5.2/include/emmintrin.h
@@ -0,0 +1,1451 @@
+/*===---- emmintrin.h - SSE2 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __EMMINTRIN_H
+#define __EMMINTRIN_H
+
+#ifndef __SSE2__
+#error "SSE2 instruction set not enabled"
+#else
+
+#include <xmmintrin.h>
+
+typedef double __m128d __attribute__((__vector_size__(16)));
+typedef long long __m128i __attribute__((__vector_size__(16)));
+
+/* Type defines.  */
+typedef double __v2df __attribute__ ((__vector_size__ (16)));
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
+typedef short __v8hi __attribute__((__vector_size__(16)));
+typedef char __v16qi __attribute__((__vector_size__(16)));
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_add_sd(__m128d __a, __m128d __b)
+{
+  __a[0] += __b[0];
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_add_pd(__m128d __a, __m128d __b)
+{
+  return __a + __b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sub_sd(__m128d __a, __m128d __b)
+{
+  __a[0] -= __b[0];
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pd(__m128d __a, __m128d __b)
+{
+  return __a - __b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_mul_sd(__m128d __a, __m128d __b)
+{
+  __a[0] *= __b[0];
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_mul_pd(__m128d __a, __m128d __b)
+{
+  return __a * __b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_div_sd(__m128d __a, __m128d __b)
+{
+  __a[0] /= __b[0];
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_div_pd(__m128d __a, __m128d __b)
+{
+  return __a / __b;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_sd(__m128d __a, __m128d __b)
+{
+  __m128d __c = __builtin_ia32_sqrtsd(__b);
+  return (__m128d) { __c[0], __a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_pd(__m128d __a)
+{
+  return __builtin_ia32_sqrtpd(__a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_min_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_minsd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_min_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_minpd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_max_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_maxsd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_max_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_maxpd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_and_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)((__v4si)__a & (__v4si)__b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)(~(__v4si)__a & (__v4si)__b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_or_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)((__v4si)__a | (__v4si)__b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_xor_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)((__v4si)__a ^ (__v4si)__b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 0);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__b, __a, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__b, __a, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 7);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 3);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 4);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__a, __b, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__b, __a, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_pd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmppd(__b, __a, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 0);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_sd(__m128d __a, __m128d __b)
+{
+  __m128d __c = __builtin_ia32_cmpsd(__b, __a, 1);
+  return (__m128d) { __c[0], __a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_sd(__m128d __a, __m128d __b)
+{
+  __m128d __c = __builtin_ia32_cmpsd(__b, __a, 2);
+  return (__m128d) { __c[0], __a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 7);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 3);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 4);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 5);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d)__builtin_ia32_cmpsd(__a, __b, 6);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_sd(__m128d __a, __m128d __b)
+{
+  __m128d __c = __builtin_ia32_cmpsd(__b, __a, 5);
+  return (__m128d) { __c[0], __a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_sd(__m128d __a, __m128d __b)
+{
+  __m128d __c = __builtin_ia32_cmpsd(__b, __a, 6);
+  return (__m128d) { __c[0], __a[1] };
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comieq_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdeq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comilt_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdlt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comile_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdle(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comigt_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdgt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comige_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdge(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comineq_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_comisdneq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomieq_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdeq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomilt_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdlt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomile_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdle(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomigt_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdgt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomige_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdge(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomineq_sd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_ucomisdneq(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_ps(__m128d __a)
+{
+  return __builtin_ia32_cvtpd2ps(__a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pd(__m128 __a)
+{
+  return __builtin_ia32_cvtps2pd(__a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_pd(__m128i __a)
+{
+  return __builtin_ia32_cvtdq2pd((__v4si)__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_epi32(__m128d __a)
+{
+  return __builtin_ia32_cvtpd2dq(__a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_si32(__m128d __a)
+{
+  return __builtin_ia32_cvtsd2si(__a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_ss(__m128 __a, __m128d __b)
+{
+  __a[0] = __b[0];
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_sd(__m128d __a, int __b)
+{
+  __a[0] = __b;
+  return __a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_sd(__m128d __a, __m128 __b)
+{
+  __a[0] = __b[0];
+  return __a;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvttpd_epi32(__m128d __a)
+{
+  return (__m128i)__builtin_ia32_cvttpd2dq(__a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvttsd_si32(__m128d __a)
+{
+  return __a[0];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpd_pi32(__m128d __a)
+{
+  return (__m64)__builtin_ia32_cvtpd2pi(__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvttpd_pi32(__m128d __a)
+{
+  return (__m64)__builtin_ia32_cvttpd2pi(__a);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32_pd(__m64 __a)
+{
+  return __builtin_ia32_cvtpi2pd((__v2si)__a);
+}
+
+static __inline__ double __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_f64(__m128d __a)
+{
+  return __a[0];
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load_pd(double const *__dp)
+{
+  return *(__m128d*)__dp;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load1_pd(double const *__dp)
+{
+  struct __mm_load1_pd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  double __u = ((struct __mm_load1_pd_struct*)__dp)->__u;
+  return (__m128d){ __u, __u };
+}
+
+#define        _mm_load_pd1(dp)        _mm_load1_pd(dp)
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadr_pd(double const *__dp)
+{
+  __m128d __u = *(__m128d*)__dp;
+  return __builtin_shufflevector(__u, __u, 1, 0);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_pd(double const *__dp)
+{
+  struct __loadu_pd {
+    __m128d __v;
+  } __attribute__((packed, may_alias));
+  return ((struct __loadu_pd*)__dp)->__v;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_load_sd(double const *__dp)
+{
+  struct __mm_load_sd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  double __u = ((struct __mm_load_sd_struct*)__dp)->__u;
+  return (__m128d){ __u, 0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadh_pd(__m128d __a, double const *__dp)
+{
+  struct __mm_loadh_pd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  double __u = ((struct __mm_loadh_pd_struct*)__dp)->__u;
+  return (__m128d){ __a[0], __u };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_pd(__m128d __a, double const *__dp)
+{
+  struct __mm_loadl_pd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  double __u = ((struct __mm_loadl_pd_struct*)__dp)->__u;
+  return (__m128d){ __u, __a[1] };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set_sd(double __w)
+{
+  return (__m128d){ __w, 0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pd(double __w)
+{
+  return (__m128d){ __w, __w };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_set_pd(double __w, double __x)
+{
+  return (__m128d){ __x, __w };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pd(double __w, double __x)
+{
+  return (__m128d){ __w, __x };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_pd(void)
+{
+  return (__m128d){ 0, 0 };
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_move_sd(__m128d __a, __m128d __b)
+{
+  return (__m128d){ __b[0], __a[1] };
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_sd(double *__dp, __m128d __a)
+{
+  struct __mm_store_sd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store_sd_struct*)__dp)->__u = __a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store1_pd(double *__dp, __m128d __a)
+{
+  struct __mm_store1_pd_struct {
+    double __u[2];
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store1_pd_struct*)__dp)->__u[0] = __a[0];
+  ((struct __mm_store1_pd_struct*)__dp)->__u[1] = __a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_pd(double *__dp, __m128d __a)
+{
+  *(__m128d *)__dp = __a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_pd(double *__dp, __m128d __a)
+{
+  __builtin_ia32_storeupd(__dp, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storer_pd(double *__dp, __m128d __a)
+{
+  __a = __builtin_shufflevector(__a, __a, 1, 0);
+  *(__m128d *)__dp = __a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeh_pd(double *__dp, __m128d __a)
+{
+  struct __mm_storeh_pd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_storeh_pd_struct*)__dp)->__u = __a[1];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storel_pd(double *__dp, __m128d __a)
+{
+  struct __mm_storeh_pd_struct {
+    double __u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_storeh_pd_struct*)__dp)->__u = __a[0];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v16qi)__a + (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v8hi)__a + (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v4si)__a + (__v4si)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_si64(__m64 __a, __m64 __b)
+{
+  return __a + __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_add_epi64(__m128i __a, __m128i __b)
+{
+  return __a + __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_paddsb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_paddsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epu8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_paddusb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_adds_epu16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_paddusw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_avg_epu8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pavgb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_avg_epu16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pavgw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_madd_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pmaddwd128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pmaxsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pmaxub128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pminsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pminub128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pmulhw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_epu16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_pmulhuw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v8hi)__a * (__v8hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_su32(__m64 __a, __m64 __b)
+{
+  return __builtin_ia32_pmuludq((__v2si)__a, (__v2si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mul_epu32(__m128i __a, __m128i __b)
+{
+  return __builtin_ia32_pmuludq128((__v4si)__a, (__v4si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sad_epu8(__m128i __a, __m128i __b)
+{
+  return __builtin_ia32_psadbw128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v16qi)__a - (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v8hi)__a - (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v4si)__a - (__v4si)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_si64(__m64 __a, __m64 __b)
+{
+  return __a - __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sub_epi64(__m128i __a, __m128i __b)
+{
+  return __a - __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_psubsb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_psubsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epu8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_psubusb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_subs_epu16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_psubusw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_and_si128(__m128i __a, __m128i __b)
+{
+  return __a & __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_si128(__m128i __a, __m128i __b)
+{
+  return ~__a & __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_or_si128(__m128i __a, __m128i __b)
+{
+  return __a | __b;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_xor_si128(__m128i __a, __m128i __b)
+{
+  return __a ^ __b;
+}
+
+#define _mm_slli_si128(a, count) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128i __a = (a); \
+   _Pragma("clang diagnostic pop"); \
+  (__m128i)__builtin_ia32_pslldqi128(__a, (count)*8); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi16(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_psllwi128((__v8hi)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi16(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_psllw128((__v8hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi32(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_pslldi128((__v4si)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi32(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_pslld128((__v4si)__a, (__v4si)__count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_slli_epi64(__m128i __a, int __count)
+{
+  return __builtin_ia32_psllqi128(__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sll_epi64(__m128i __a, __m128i __count)
+{
+  return __builtin_ia32_psllq128(__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srai_epi16(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_psrawi128((__v8hi)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sra_epi16(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_psraw128((__v8hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srai_epi32(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_psradi128((__v4si)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sra_epi32(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_psrad128((__v4si)__a, (__v4si)__count);
+}
+
+
+#define _mm_srli_si128(a, count) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128i __a = (a); \
+  _Pragma("clang diagnostic pop"); \
+  (__m128i)__builtin_ia32_psrldqi128(__a, (count)*8); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi16(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_psrlwi128((__v8hi)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi16(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_psrlw128((__v8hi)__a, (__v8hi)__count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi32(__m128i __a, int __count)
+{
+  return (__m128i)__builtin_ia32_psrldi128((__v4si)__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi32(__m128i __a, __m128i __count)
+{
+  return (__m128i)__builtin_ia32_psrld128((__v4si)__a, (__v4si)__count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srli_epi64(__m128i __a, int __count)
+{
+  return __builtin_ia32_psrlqi128(__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_srl_epi64(__m128i __a, __m128i __count)
+{
+  return __builtin_ia32_psrlq128(__a, __count);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v16qi)__a == (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v8hi)__a == (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v4si)__a == (__v4si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi8(__m128i __a, __m128i __b)
+{
+  /* This function always performs a signed comparison, but __v16qi is a char
+     which may be signed or unsigned. */
+  typedef signed char __v16qs __attribute__((__vector_size__(16)));
+  return (__m128i)((__v16qs)__a > (__v16qs)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v8hi)__a > (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)((__v4si)__a > (__v4si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi8(__m128i __a, __m128i __b)
+{
+  return _mm_cmpgt_epi8(__b, __a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi16(__m128i __a, __m128i __b)
+{
+  return _mm_cmpgt_epi16(__b, __a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_epi32(__m128i __a, __m128i __b)
+{
+  return _mm_cmpgt_epi32(__b, __a);
+}
+
+#ifdef __x86_64__
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_sd(__m128d __a, long long __b)
+{
+  __a[0] = __b;
+  return __a;
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsd_si64(__m128d __a)
+{
+  return __builtin_ia32_cvtsd2si64(__a);
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvttsd_si64(__m128d __a)
+{
+  return __a[0];
+}
+#endif
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_ps(__m128i __a)
+{
+  return __builtin_ia32_cvtdq2ps((__v4si)__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_epi32(__m128 __a)
+{
+  return (__m128i)__builtin_ia32_cvtps2dq(__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvttps_epi32(__m128 __a)
+{
+  return (__m128i)__builtin_ia32_cvttps2dq(__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_si128(int __a)
+{
+  return (__m128i)(__v4si){ __a, 0, 0, 0 };
+}
+
+#ifdef __x86_64__
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_si128(long long __a)
+{
+  return (__m128i){ __a, 0 };
+}
+#endif
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi128_si32(__m128i __a)
+{
+  __v4si __b = (__v4si)__a;
+  return __b[0];
+}
+
+#ifdef __x86_64__
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi128_si64(__m128i __a)
+{
+  return __a[0];
+}
+#endif
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_load_si128(__m128i const *__p)
+{
+  return *__p;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_si128(__m128i const *__p)
+{
+  struct __loadu_si128 {
+    __m128i __v;
+  } __attribute__((packed, may_alias));
+  return ((struct __loadu_si128*)__p)->__v;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_epi64(__m128i const *__p)
+{
+  struct __mm_loadl_epi64_struct {
+    long long __u;
+  } __attribute__((__packed__, __may_alias__));
+  return (__m128i) { ((struct __mm_loadl_epi64_struct*)__p)->__u, 0};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi64x(long long q1, long long q0)
+{
+  return (__m128i){ q0, q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi64(__m64 q1, __m64 q0)
+{
+  return (__m128i){ (long long)q0, (long long)q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi32(int i3, int i2, int i1, int i0)
+{
+  return (__m128i)(__v4si){ i0, i1, i2, i3};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi16(short w7, short w6, short w5, short w4, short w3, short w2, short w1, short w0)
+{
+  return (__m128i)(__v8hi){ w0, w1, w2, w3, w4, w5, w6, w7 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set_epi8(char b15, char b14, char b13, char b12, char b11, char b10, char b9, char b8, char b7, char b6, char b5, char b4, char b3, char b2, char b1, char b0)
+{
+  return (__m128i)(__v16qi){ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi64x(long long __q)
+{
+  return (__m128i){ __q, __q };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi64(__m64 __q)
+{
+  return (__m128i){ (long long)__q, (long long)__q };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi32(int __i)
+{
+  return (__m128i)(__v4si){ __i, __i, __i, __i };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi16(short __w)
+{
+  return (__m128i)(__v8hi){ __w, __w, __w, __w, __w, __w, __w, __w };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_set1_epi8(char __b)
+{
+  return (__m128i)(__v16qi){ __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b, __b };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi64(__m64 q0, __m64 q1)
+{
+  return (__m128i){ (long long)q0, (long long)q1 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi32(int i0, int i1, int i2, int i3)
+{
+  return (__m128i)(__v4si){ i0, i1, i2, i3};
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi16(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7)
+{
+  return (__m128i)(__v8hi){ w0, w1, w2, w3, w4, w5, w6, w7 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setr_epi8(char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9, char b10, char b11, char b12, char b13, char b14, char b15)
+{
+  return (__m128i)(__v16qi){ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_si128(void)
+{
+  return (__m128i){ 0LL, 0LL };
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_si128(__m128i *__p, __m128i __b)
+{
+  *__p = __b;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_si128(__m128i *__p, __m128i __b)
+{
+  __builtin_ia32_storedqu((char *)__p, (__v16qi)__b);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskmoveu_si128(__m128i __d, __m128i __n, char *__p)
+{
+  __builtin_ia32_maskmovdqu((__v16qi)__d, (__v16qi)__n, __p);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storel_epi64(__m128i *__p, __m128i __a)
+{
+  struct __mm_storel_epi64_struct {
+    long long __u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_storel_epi64_struct*)__p)->__u = __a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_pd(double *__p, __m128d __a)
+{
+  __builtin_ia32_movntpd(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_si128(__m128i *__p, __m128i __a)
+{
+  __builtin_ia32_movntdq(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_si32(int *__p, int __a)
+{
+  __builtin_ia32_movnti(__p, __a);
+}
+
+#ifdef __x86_64__
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_si64(long long *__p, long long __a)
+{
+  __builtin_ia32_movnti64(__p, __a);
+}
+#endif
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_clflush(void const *__p)
+{
+  __builtin_ia32_clflush(__p);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_lfence(void)
+{
+  __builtin_ia32_lfence();
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_mfence(void)
+{
+  __builtin_ia32_mfence();
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packs_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_packsswb128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packs_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_packssdw128((__v4si)__a, (__v4si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packus_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_ia32_packuswb128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_extract_epi16(__m128i __a, int __imm)
+{
+  __v8hi __b = (__v8hi)__a;
+  return (unsigned short)__b[__imm & 7];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_insert_epi16(__m128i __a, int __b, int __imm)
+{
+  __v8hi __c = (__v8hi)__a;
+  __c[__imm & 7] = __b;
+  return (__m128i)__c;
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_epi8(__m128i __a)
+{
+  return __builtin_ia32_pmovmskb128((__v16qi)__a);
+}
+
+#define _mm_shuffle_epi32(a, imm) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128i __a = (a); \
+  _Pragma("clang diagnostic pop"); \
+  (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si) _mm_set1_epi32(0), \
+                                   (imm) & 0x3, ((imm) & 0xc) >> 2, \
+                                   ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6); })
+
+#define _mm_shufflelo_epi16(a, imm) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128i __a = (a); \
+  _Pragma("clang diagnostic pop"); \
+  (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi) _mm_set1_epi16(0), \
+                                   (imm) & 0x3, ((imm) & 0xc) >> 2, \
+                                   ((imm) & 0x30) >> 4, ((imm) & 0xc0) >> 6, \
+                                   4, 5, 6, 7); })
+
+#define _mm_shufflehi_epi16(a, imm) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128i __a = (a); \
+  _Pragma("clang diagnostic pop"); \
+  (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi) _mm_set1_epi16(0), \
+                                   0, 1, 2, 3, \
+                                   4 + (((imm) & 0x03) >> 0), \
+                                   4 + (((imm) & 0x0c) >> 2), \
+                                   4 + (((imm) & 0x30) >> 4), \
+                                   4 + (((imm) & 0xc0) >> 6)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v16qi)__a, (__v16qi)__b, 8, 16+8, 9, 16+9, 10, 16+10, 11, 16+11, 12, 16+12, 13, 16+13, 14, 16+14, 15, 16+15);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi)__b, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 2, 4+2, 3, 4+3);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_epi64(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector(__a, __b, 1, 2+1);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi8(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v16qi)__a, (__v16qi)__b, 0, 16+0, 1, 16+1, 2, 16+2, 3, 16+3, 4, 16+4, 5, 16+5, 6, 16+6, 7, 16+7);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi16(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v8hi)__a, (__v8hi)__b, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi32(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector((__v4si)__a, (__v4si)__b, 0, 4+0, 1, 4+1);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_epi64(__m128i __a, __m128i __b)
+{
+  return (__m128i)__builtin_shufflevector(__a, __b, 0, 2+0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_movepi64_pi64(__m128i __a)
+{
+  return (__m64)__a[0];
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_movpi64_epi64(__m64 __a)
+{
+  return (__m128i){ (long long)__a, 0 };
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_move_epi64(__m128i __a)
+{
+  return __builtin_shufflevector(__a, (__m128i){ 0 }, 0, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_shufflevector(__a, __b, 1, 2+1);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_shufflevector(__a, __b, 0, 2+0);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_pd(__m128d __a)
+{
+  return __builtin_ia32_movmskpd(__a);
+}
+
+#define _mm_shuffle_pd(a, b, i) __extension__ ({ \
+  _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\""); \
+  __m128d __a = (a); \
+  __m128d __b = (b); \
+  _Pragma("clang diagnostic pop"); \
+  __builtin_shufflevector(__a, __b, (i) & 1, (((i) & 2) >> 1) + 2); })
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_castpd_ps(__m128d __a)
+{
+  return (__m128)__a;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_castpd_si128(__m128d __a)
+{
+  return (__m128i)__a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_castps_pd(__m128 __a)
+{
+  return (__m128d)__a;
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_castps_si128(__m128 __a)
+{
+  return (__m128i)__a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_castsi128_ps(__m128i __a)
+{
+  return (__m128)__a;
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_castsi128_pd(__m128i __a)
+{
+  return (__m128d)__a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_pause(void)
+{
+  __asm__ volatile ("pause");
+}
+
+#define _MM_SHUFFLE2(x, y) (((x) << 1) | (y))
+
+#endif /* __SSE2__ */
+
+#endif /* __EMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/f16cintrin.h b/lib/clang/3.5.2/include/f16cintrin.h
new file mode 100644
index 0000000..f3614c0
--- /dev/null
+++ b/lib/clang/3.5.2/include/f16cintrin.h
@@ -0,0 +1,58 @@
+/*===---- f16cintrin.h - F16C intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
+#error "Never use <f16cintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __F16C__
+# error "F16C instruction is not enabled"
+#endif /* __F16C__ */
+
+#ifndef __F16CINTRIN_H
+#define __F16CINTRIN_H
+
+typedef float __v8sf __attribute__ ((__vector_size__ (32)));
+typedef float __m256 __attribute__ ((__vector_size__ (32)));
+
+#define _mm_cvtps_ph(a, imm) __extension__ ({ \
+  __m128 __a = (a); \
+ (__m128i)__builtin_ia32_vcvtps2ph((__v4sf)__a, (imm)); })
+
+#define _mm256_cvtps_ph(a, imm) __extension__ ({ \
+  __m256 __a = (a); \
+ (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)__a, (imm)); })
+
+static __inline __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtph_ps(__m128i __a)
+{
+  return (__m128)__builtin_ia32_vcvtph2ps((__v8hi)__a);
+}
+
+static __inline __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_cvtph_ps(__m128i __a)
+{
+  return (__m256)__builtin_ia32_vcvtph2ps256((__v8hi)__a);
+}
+
+#endif /* __F16CINTRIN_H */
diff --git a/lib/clang/3.5.2/include/float.h b/lib/clang/3.5.2/include/float.h
new file mode 100644
index 0000000..02ef6bf
--- /dev/null
+++ b/lib/clang/3.5.2/include/float.h
@@ -0,0 +1,124 @@
+/*===---- float.h - Characteristics of floating point types ----------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __FLOAT_H
+#define __FLOAT_H
+
+/* If we're on MinGW, fall back to the system's float.h, which might have
+ * additional definitions provided for Windows.
+ * For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx
+ */
+#if (defined(__MINGW32__) || defined(_MSC_VER)) && \
+    __has_include_next(<float.h>)
+#  include_next <float.h>
+
+/* Undefine anything that we'll be redefining below. */
+#  undef FLT_EVAL_METHOD
+#  undef FLT_ROUNDS
+#  undef FLT_RADIX
+#  undef FLT_MANT_DIG
+#  undef DBL_MANT_DIG
+#  undef LDBL_MANT_DIG
+#  undef DECIMAL_DIG
+#  undef FLT_DIG
+#  undef DBL_DIG
+#  undef LDBL_DIG
+#  undef FLT_MIN_EXP
+#  undef DBL_MIN_EXP
+#  undef LDBL_MIN_EXP
+#  undef FLT_MIN_10_EXP
+#  undef DBL_MIN_10_EXP
+#  undef LDBL_MIN_10_EXP
+#  undef FLT_MAX_EXP
+#  undef DBL_MAX_EXP
+#  undef LDBL_MAX_EXP
+#  undef FLT_MAX_10_EXP
+#  undef DBL_MAX_10_EXP
+#  undef LDBL_MAX_10_EXP
+#  undef FLT_MAX
+#  undef DBL_MAX
+#  undef LDBL_MAX
+#  undef FLT_EPSILON
+#  undef DBL_EPSILON
+#  undef LDBL_EPSILON
+#  undef FLT_MIN
+#  undef DBL_MIN
+#  undef LDBL_MIN
+#  if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+#    undef FLT_TRUE_MIN
+#    undef DBL_TRUE_MIN
+#    undef LDBL_TRUE_MIN
+#  endif
+#endif
+
+/* Characteristics of floating point types, C99 5.2.4.2.2 */
+
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#define FLT_ROUNDS (__builtin_flt_rounds())
+#define FLT_RADIX __FLT_RADIX__
+
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#define DECIMAL_DIG __DECIMAL_DIG__
+
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+#  define FLT_TRUE_MIN __FLT_DENORM_MIN__
+#  define DBL_TRUE_MIN __DBL_DENORM_MIN__
+#  define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+#endif
+
+#endif /* __FLOAT_H */
diff --git a/lib/clang/3.5.2/include/fma4intrin.h b/lib/clang/3.5.2/include/fma4intrin.h
new file mode 100644
index 0000000..c30920d
--- /dev/null
+++ b/lib/clang/3.5.2/include/fma4intrin.h
@@ -0,0 +1,231 @@
+/*===---- fma4intrin.h - FMA4 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86INTRIN_H
+#error "Never use <fma4intrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __FMA4INTRIN_H
+#define __FMA4INTRIN_H
+
+#ifndef __FMA4__
+# error "FMA4 instruction set is not enabled"
+#else
+
+#include <pmmintrin.h>
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_macc_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_macc_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_macc_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_macc_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_msub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_msub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_msub_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_msub_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_nmacc_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_nmacc_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmaddpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_nmacc_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmaddss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_nmacc_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmaddsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_nmsub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_nmsub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_nmsub_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmsubss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_nmsub_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmsubsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_maddsub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_maddsub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_msubadd_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_msubadd_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubaddpd(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_macc_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_macc_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmaddpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_msub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_msub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_nmacc_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfnmaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_nmacc_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfnmaddpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_nmsub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfnmsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_nmsub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfnmsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_maddsub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmaddsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_maddsub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmaddsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_msubadd_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmsubaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_msubadd_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmsubaddpd256(__A, __B, __C);
+}
+
+#endif /* __FMA4__ */
+
+#endif /* __FMA4INTRIN_H */
diff --git a/lib/clang/3.5.2/include/fmaintrin.h b/lib/clang/3.5.2/include/fmaintrin.h
new file mode 100644
index 0000000..6bfd5a8
--- /dev/null
+++ b/lib/clang/3.5.2/include/fmaintrin.h
@@ -0,0 +1,229 @@
+/*===---- fma4intrin.h - FMA4 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <fmaintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __FMAINTRIN_H
+#define __FMAINTRIN_H
+
+#ifndef __FMA__
+# error "FMA instruction set is not enabled"
+#else
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmadd_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmadd_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmadd_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmadd_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmsub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmsub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmsub_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmsub_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fnmadd_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fnmadd_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmaddpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fnmadd_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmaddss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fnmadd_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmaddsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fnmsub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fnmsub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fnmsub_ss(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfnmsubss(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fnmsub_sd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfnmsubsd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmaddsub_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmaddsubps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmaddsub_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmaddsubpd(__A, __B, __C);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_fmsubadd_ps(__m128 __A, __m128 __B, __m128 __C)
+{
+  return (__m128)__builtin_ia32_vfmsubaddps(__A, __B, __C);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_fmsubadd_pd(__m128d __A, __m128d __B, __m128d __C)
+{
+  return (__m128d)__builtin_ia32_vfmsubaddpd(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fmadd_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fmadd_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmaddpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fmsub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fmsub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fnmadd_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfnmaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fnmadd_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfnmaddpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fnmsub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfnmsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fnmsub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfnmsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fmaddsub_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmaddsubps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fmaddsub_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmaddsubpd256(__A, __B, __C);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_fmsubadd_ps(__m256 __A, __m256 __B, __m256 __C)
+{
+  return (__m256)__builtin_ia32_vfmsubaddps256(__A, __B, __C);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_fmsubadd_pd(__m256d __A, __m256d __B, __m256d __C)
+{
+  return (__m256d)__builtin_ia32_vfmsubaddpd256(__A, __B, __C);
+}
+
+#endif /* __FMA__ */
+
+#endif /* __FMAINTRIN_H */
diff --git a/lib/clang/3.5.2/include/ia32intrin.h b/lib/clang/3.5.2/include/ia32intrin.h
new file mode 100644
index 0000000..5adf3f1
--- /dev/null
+++ b/lib/clang/3.5.2/include/ia32intrin.h
@@ -0,0 +1,101 @@
+/* ===-------- ia32intrin.h ---------------------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86INTRIN_H
+#error "Never use <ia32intrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __IA32INTRIN_H
+#define __IA32INTRIN_H
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__readeflags(void)
+{
+  unsigned long long __res = 0;
+  __asm__ __volatile__ ("pushf\n\t"
+                        "popq %0\n"
+                        :"=r"(__res)
+                        :
+                        :
+                       );
+  return __res;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__writeeflags(unsigned long long __f)
+{
+  __asm__ __volatile__ ("pushq %0\n\t"
+                        "popf\n"
+                        :
+                        :"r"(__f)
+                        :"flags"
+                       );
+}
+
+#else /* !__x86_64__ */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__readeflags(void)
+{
+  unsigned int __res = 0;
+  __asm__ __volatile__ ("pushf\n\t"
+                        "popl %0\n"
+                        :"=r"(__res)
+                        :
+                        :
+                       );
+  return __res;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__writeeflags(unsigned int __f)
+{
+  __asm__ __volatile__ ("pushl %0\n\t"
+                        "popf\n"
+                        :
+                        :"r"(__f)
+                        :"flags"
+                       );
+}
+#endif /* !__x86_64__ */
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdpmc(int __A) {
+  return __builtin_ia32_rdpmc(__A);
+}
+
+/* __rdtsc */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdtsc(void) {
+  return __builtin_ia32_rdtsc();
+}
+
+/* __rdtscp */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdtscp(unsigned int *__A) {
+  return __builtin_ia32_rdtscp(__A);
+}
+
+#define _rdtsc() __rdtsc()
+
+#endif /* __IA32INTRIN_H */
diff --git a/lib/clang/3.5.2/include/immintrin.h b/lib/clang/3.5.2/include/immintrin.h
new file mode 100644
index 0000000..df4bea8
--- /dev/null
+++ b/lib/clang/3.5.2/include/immintrin.h
@@ -0,0 +1,118 @@
+/*===---- immintrin.h - Intel intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#define __IMMINTRIN_H
+
+#ifdef __MMX__
+#include <mmintrin.h>
+#endif
+
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#ifdef __SSE3__
+#include <pmmintrin.h>
+#endif
+
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#if defined (__SSE4_2__) || defined (__SSE4_1__)
+#include <smmintrin.h>
+#endif
+
+#if defined (__AES__) || defined (__PCLMUL__)
+#include <wmmintrin.h>
+#endif
+
+#ifdef __AVX__
+#include <avxintrin.h>
+#endif
+
+#ifdef __AVX2__
+#include <avx2intrin.h>
+#endif
+
+#ifdef __BMI__
+#include <bmiintrin.h>
+#endif
+
+#ifdef __BMI2__
+#include <bmi2intrin.h>
+#endif
+
+#ifdef __LZCNT__
+#include <lzcntintrin.h>
+#endif
+
+#ifdef __FMA__
+#include <fmaintrin.h>
+#endif
+
+#ifdef __RDRND__
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdrand16_step(unsigned short *__p)
+{
+  return __builtin_ia32_rdrand16_step(__p);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdrand32_step(unsigned int *__p)
+{
+  return __builtin_ia32_rdrand32_step(__p);
+}
+
+#ifdef __x86_64__
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdrand64_step(unsigned long long *__p)
+{
+  return __builtin_ia32_rdrand64_step(__p);
+}
+#endif
+#endif /* __RDRND__ */
+
+#ifdef __RTM__
+#include <rtmintrin.h>
+#endif
+
+/* FIXME: check __HLE__ as well when HLE is supported. */
+#if defined (__RTM__)
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_xtest(void)
+{
+  return __builtin_ia32_xtest();
+}
+#endif
+
+#ifdef __SHA__
+#include <shaintrin.h>
+#endif
+
+#endif /* __IMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/iso646.h b/lib/clang/3.5.2/include/iso646.h
new file mode 100644
index 0000000..dca13c5
--- /dev/null
+++ b/lib/clang/3.5.2/include/iso646.h
@@ -0,0 +1,43 @@
+/*===---- iso646.h - Standard header for alternate spellings of operators---===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ISO646_H
+#define __ISO646_H
+
+#ifndef __cplusplus
+#define and    &&
+#define and_eq &=
+#define bitand &
+#define bitor  |
+#define compl  ~
+#define not    !
+#define not_eq !=
+#define or     ||
+#define or_eq  |=
+#define xor    ^
+#define xor_eq ^=
+#endif
+
+#endif /* __ISO646_H */
diff --git a/lib/clang/3.5.2/include/limits.h b/lib/clang/3.5.2/include/limits.h
new file mode 100644
index 0000000..f04187c
--- /dev/null
+++ b/lib/clang/3.5.2/include/limits.h
@@ -0,0 +1,118 @@
+/*===---- limits.h - Standard header for integer sizes --------------------===*\
+ *
+ * Copyright (c) 2009 Chris Lattner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __CLANG_LIMITS_H
+#define __CLANG_LIMITS_H
+
+/* The system's limits.h may, in turn, try to #include_next GCC's limits.h.
+   Avert this #include_next madness. */
+#if defined __GNUC__ && !defined _GCC_LIMITS_H_
+#define _GCC_LIMITS_H_
+#endif
+
+/* System headers include a number of constants from POSIX in <limits.h>.
+   Include it if we're hosted. */
+#if __STDC_HOSTED__ && __has_include_next(<limits.h>)
+#include_next <limits.h>
+#endif
+
+/* Many system headers try to "help us out" by defining these.  No really, we
+   know how big each datatype is. */
+#undef  SCHAR_MIN
+#undef  SCHAR_MAX
+#undef  UCHAR_MAX
+#undef  SHRT_MIN
+#undef  SHRT_MAX
+#undef  USHRT_MAX
+#undef  INT_MIN
+#undef  INT_MAX
+#undef  UINT_MAX
+#undef  LONG_MIN
+#undef  LONG_MAX
+#undef  ULONG_MAX
+
+#undef  CHAR_BIT
+#undef  CHAR_MIN
+#undef  CHAR_MAX
+
+/* C90/99 5.2.4.2.1 */
+#define SCHAR_MAX __SCHAR_MAX__
+#define SHRT_MAX  __SHRT_MAX__
+#define INT_MAX   __INT_MAX__
+#define LONG_MAX  __LONG_MAX__
+
+#define SCHAR_MIN (-__SCHAR_MAX__-1)
+#define SHRT_MIN  (-__SHRT_MAX__ -1)
+#define INT_MIN   (-__INT_MAX__  -1)
+#define LONG_MIN  (-__LONG_MAX__ -1L)
+
+#define UCHAR_MAX (__SCHAR_MAX__*2  +1)
+#define USHRT_MAX (__SHRT_MAX__ *2  +1)
+#define UINT_MAX  (__INT_MAX__  *2U +1U)
+#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
+
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 1
+#endif
+
+#define CHAR_BIT  __CHAR_BIT__
+
+#ifdef __CHAR_UNSIGNED__  /* -funsigned-char */
+#define CHAR_MIN 0
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX __SCHAR_MAX__
+#endif
+
+/* C99 5.2.4.2.1: Added long long.
+   C++11 18.3.3.2: same contents as the Standard C Library header <limits.h>.
+ */
+#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
+
+#undef  LLONG_MIN
+#undef  LLONG_MAX
+#undef  ULLONG_MAX
+
+#define LLONG_MAX  __LONG_LONG_MAX__
+#define LLONG_MIN  (-__LONG_LONG_MAX__-1LL)
+#define ULLONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL)
+#endif
+
+/* LONG_LONG_MIN/LONG_LONG_MAX/ULONG_LONG_MAX are a GNU extension.  It's too bad
+   that we don't have something like #pragma poison that could be used to
+   deprecate a macro - the code should just use LLONG_MAX and friends.
+ */
+#if defined(__GNU_LIBRARY__) ? defined(__USE_GNU) : !defined(__STRICT_ANSI__)
+
+#undef   LONG_LONG_MIN
+#undef   LONG_LONG_MAX
+#undef   ULONG_LONG_MAX
+
+#define LONG_LONG_MAX  __LONG_LONG_MAX__
+#define LONG_LONG_MIN  (-__LONG_LONG_MAX__-1LL)
+#define ULONG_LONG_MAX (__LONG_LONG_MAX__*2ULL+1ULL)
+#endif
+
+#endif /* __CLANG_LIMITS_H */
diff --git a/lib/clang/3.5.2/include/lzcntintrin.h b/lib/clang/3.5.2/include/lzcntintrin.h
new file mode 100644
index 0000000..62ab5ca
--- /dev/null
+++ b/lib/clang/3.5.2/include/lzcntintrin.h
@@ -0,0 +1,55 @@
+/*===---- lzcntintrin.h - LZCNT intrinsics ---------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H
+#error "Never use <lzcntintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __LZCNT__
+# error "LZCNT instruction is not enabled"
+#endif /* __LZCNT__ */
+
+#ifndef __LZCNTINTRIN_H
+#define __LZCNTINTRIN_H
+
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__lzcnt16(unsigned short __X)
+{
+  return __builtin_clzs(__X);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__lzcnt32(unsigned int __X)
+{
+  return __builtin_clz(__X);
+}
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__lzcnt64(unsigned long long __X)
+{
+  return __builtin_clzll(__X);
+}
+#endif
+
+#endif /* __LZCNTINTRIN_H */
diff --git a/lib/clang/3.5.2/include/mm3dnow.h b/lib/clang/3.5.2/include/mm3dnow.h
new file mode 100644
index 0000000..5242d99
--- /dev/null
+++ b/lib/clang/3.5.2/include/mm3dnow.h
@@ -0,0 +1,162 @@
+/*===---- mm3dnow.h - 3DNow! intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _MM3DNOW_H_INCLUDED
+#define _MM3DNOW_H_INCLUDED
+
+#include <mmintrin.h>
+#include <prfchwintrin.h>
+
+typedef float __v2sf __attribute__((__vector_size__(8)));
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_femms() {
+  __builtin_ia32_femms();
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pavgusb(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pavgusb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pf2id(__m64 __m) {
+  return (__m64)__builtin_ia32_pf2id((__v2sf)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfacc(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfacc((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfadd(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfadd((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfcmpeq(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfcmpeq((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfcmpge(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfcmpge((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfcmpgt(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfcmpgt((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfmax(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfmax((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfmin(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfmin((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfmul(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfmul((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfrcp(__m64 __m) {
+  return (__m64)__builtin_ia32_pfrcp((__v2sf)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfrcpit1(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfrcpit1((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfrcpit2(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfrcpit2((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfrsqrt(__m64 __m) {
+  return (__m64)__builtin_ia32_pfrsqrt((__v2sf)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfrsqrtit1(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfrsqit1((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfsub(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfsub((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfsubr(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfsubr((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pi2fd(__m64 __m) {
+  return (__m64)__builtin_ia32_pi2fd((__v2si)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pmulhrw(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pmulhrw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pf2iw(__m64 __m) {
+  return (__m64)__builtin_ia32_pf2iw((__v2sf)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfnacc(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfnacc((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pfpnacc(__m64 __m1, __m64 __m2) {
+  return (__m64)__builtin_ia32_pfpnacc((__v2sf)__m1, (__v2sf)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pi2fw(__m64 __m) {
+  return (__m64)__builtin_ia32_pi2fw((__v2si)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pswapdsf(__m64 __m) {
+  return (__m64)__builtin_ia32_pswapdsf((__v2sf)__m);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_m_pswapdsi(__m64 __m) {
+  return (__m64)__builtin_ia32_pswapdsi((__v2si)__m);
+}
+
+#endif
diff --git a/lib/clang/3.5.2/include/mm_malloc.h b/lib/clang/3.5.2/include/mm_malloc.h
new file mode 100644
index 0000000..305afd3
--- /dev/null
+++ b/lib/clang/3.5.2/include/mm_malloc.h
@@ -0,0 +1,75 @@
+/*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __MM_MALLOC_H
+#define __MM_MALLOC_H
+
+#include <stdlib.h>
+
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#ifndef __cplusplus
+extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
+#else
+// Some systems (e.g. those with GNU libc) declare posix_memalign with an
+// exception specifier. Via an "egregious workaround" in
+// Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid
+// redeclaration of glibc's declaration.
+extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
+#endif
+#endif
+
+#if !(defined(_WIN32) && defined(_mm_malloc))
+static __inline__ void *__attribute__((__always_inline__, __nodebug__,
+                                       __malloc__))
+_mm_malloc(size_t __size, size_t __align)
+{
+  if (__align == 1) {
+    return malloc(__size);
+  }
+
+  if (!(__align & (__align - 1)) && __align < sizeof(void *))
+    __align = sizeof(void *);
+
+  void *__mallocedMemory;
+#if defined(__MINGW32__)
+  __mallocedMemory = __mingw_aligned_malloc(__size, __align);
+#elif defined(_WIN32)
+  __mallocedMemory = _aligned_malloc(__size, __align);
+#else
+  if (posix_memalign(&__mallocedMemory, __align, __size))
+    return 0;
+#endif
+
+  return __mallocedMemory;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_free(void *__p)
+{
+  free(__p);
+}
+#endif
+
+#endif /* __MM_MALLOC_H */
diff --git a/lib/clang/3.5.2/include/mmintrin.h b/lib/clang/3.5.2/include/mmintrin.h
new file mode 100644
index 0000000..986870a
--- /dev/null
+++ b/lib/clang/3.5.2/include/mmintrin.h
@@ -0,0 +1,503 @@
+/*===---- mmintrin.h - MMX intrinsics --------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __MMINTRIN_H
+#define __MMINTRIN_H
+
+#ifndef __MMX__
+#error "MMX instruction set not enabled"
+#else
+
+typedef long long __m64 __attribute__((__vector_size__(8)));
+
+typedef int __v2si __attribute__((__vector_size__(8)));
+typedef short __v4hi __attribute__((__vector_size__(8)));
+typedef char __v8qi __attribute__((__vector_size__(8)));
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_empty(void)
+{
+    __builtin_ia32_emms();
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_si64(int __i)
+{
+    return (__m64)__builtin_ia32_vec_init_v2si(__i, 0);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_si32(__m64 __m)
+{
+    return __builtin_ia32_vec_ext_v2si((__v2si)__m, 0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_m64(long long __i)
+{
+    return (__m64)__i;
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtm64_si64(__m64 __m)
+{
+    return (long long)__m;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packsswb((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packssdw((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_packs_pu16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_packuswb((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpckhbw((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpckhwd((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpckhdq((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpcklbw((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpcklwd((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_punpckldq((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_paddb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_paddw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_add_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_paddd((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pi8(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddsb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_paddsw((__v4hi)__m1, (__v4hi)__m2);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pu8(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddusb((__v8qi)__m1, (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_adds_pu16(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_paddusw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubb((__v8qi)__m1, (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubw((__v4hi)__m1, (__v4hi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubd((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubsb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubsw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pu8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubusb((__v8qi)__m1, (__v8qi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_subs_pu16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_psubusw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_madd_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pmaddwd((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pmulhw((__v4hi)__m1, (__v4hi)__m2);
+}
+ 
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_pi16(__m64 __m1, __m64 __m2) 
+{
+    return (__m64)__builtin_ia32_pmullw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psllw((__v4hi)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psllwi((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_pslld((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_pslldi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sll_si64(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psllq(__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_slli_si64(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psllqi(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sra_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psraw((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srai_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrawi((__v4hi)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sra_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrad((__v2si)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srai_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psradi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_pi16(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrlw((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_pi16(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrlwi((__v4hi)__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_pi32(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrld((__v2si)__m, __count);       
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_pi32(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrldi((__v2si)__m, __count);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srl_si64(__m64 __m, __m64 __count)
+{
+    return (__m64)__builtin_ia32_psrlq(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_srli_si64(__m64 __m, int __count)
+{
+    return (__m64)__builtin_ia32_psrlqi(__m, __count);    
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_and_si64(__m64 __m1, __m64 __m2)
+{
+    return __builtin_ia32_pand(__m1, __m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_si64(__m64 __m1, __m64 __m2)
+{
+    return __builtin_ia32_pandn(__m1, __m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_or_si64(__m64 __m1, __m64 __m2)
+{
+    return __builtin_ia32_por(__m1, __m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_xor_si64(__m64 __m1, __m64 __m2)
+{
+    return __builtin_ia32_pxor(__m1, __m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpeqb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpeqw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpeqd((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpgtb((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpgtw((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_pi32(__m64 __m1, __m64 __m2)
+{
+    return (__m64)__builtin_ia32_pcmpgtd((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setzero_si64(void)
+{
+    return (__m64){ 0LL };
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi32(int __i1, int __i0)
+{
+    return (__m64)__builtin_ia32_vec_init_v2si(__i0, __i1);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi16(short __s3, short __s2, short __s1, short __s0)
+{
+    return (__m64)__builtin_ia32_vec_init_v4hi(__s0, __s1, __s2, __s3);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3, char __b2,
+            char __b1, char __b0)
+{
+    return (__m64)__builtin_ia32_vec_init_v8qi(__b0, __b1, __b2, __b3,
+                                               __b4, __b5, __b6, __b7);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi32(int __i)
+{
+    return _mm_set_pi32(__i, __i);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi16(short __w)
+{
+    return _mm_set_pi16(__w, __w, __w, __w);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_pi8(char __b)
+{
+    return _mm_set_pi8(__b, __b, __b, __b, __b, __b, __b, __b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi32(int __i0, int __i1)
+{
+    return _mm_set_pi32(__i1, __i0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi16(short __w0, short __w1, short __w2, short __w3)
+{
+    return _mm_set_pi16(__w3, __w2, __w1, __w0);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_pi8(char __b0, char __b1, char __b2, char __b3, char __b4, char __b5,
+             char __b6, char __b7)
+{
+    return _mm_set_pi8(__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0);
+}
+
+
+/* Aliases for compatibility. */
+#define _m_empty _mm_empty
+#define _m_from_int _mm_cvtsi32_si64
+#define _m_to_int _mm_cvtsi64_si32
+#define _m_packsswb _mm_packs_pi16
+#define _m_packssdw _mm_packs_pi32
+#define _m_packuswb _mm_packs_pu16
+#define _m_punpckhbw _mm_unpackhi_pi8
+#define _m_punpckhwd _mm_unpackhi_pi16
+#define _m_punpckhdq _mm_unpackhi_pi32
+#define _m_punpcklbw _mm_unpacklo_pi8
+#define _m_punpcklwd _mm_unpacklo_pi16
+#define _m_punpckldq _mm_unpacklo_pi32
+#define _m_paddb _mm_add_pi8
+#define _m_paddw _mm_add_pi16
+#define _m_paddd _mm_add_pi32
+#define _m_paddsb _mm_adds_pi8
+#define _m_paddsw _mm_adds_pi16
+#define _m_paddusb _mm_adds_pu8
+#define _m_paddusw _mm_adds_pu16
+#define _m_psubb _mm_sub_pi8
+#define _m_psubw _mm_sub_pi16
+#define _m_psubd _mm_sub_pi32
+#define _m_psubsb _mm_subs_pi8
+#define _m_psubsw _mm_subs_pi16
+#define _m_psubusb _mm_subs_pu8
+#define _m_psubusw _mm_subs_pu16
+#define _m_pmaddwd _mm_madd_pi16
+#define _m_pmulhw _mm_mulhi_pi16
+#define _m_pmullw _mm_mullo_pi16
+#define _m_psllw _mm_sll_pi16
+#define _m_psllwi _mm_slli_pi16
+#define _m_pslld _mm_sll_pi32
+#define _m_pslldi _mm_slli_pi32
+#define _m_psllq _mm_sll_si64
+#define _m_psllqi _mm_slli_si64
+#define _m_psraw _mm_sra_pi16
+#define _m_psrawi _mm_srai_pi16
+#define _m_psrad _mm_sra_pi32
+#define _m_psradi _mm_srai_pi32
+#define _m_psrlw _mm_srl_pi16
+#define _m_psrlwi _mm_srli_pi16
+#define _m_psrld _mm_srl_pi32
+#define _m_psrldi _mm_srli_pi32
+#define _m_psrlq _mm_srl_si64
+#define _m_psrlqi _mm_srli_si64
+#define _m_pand _mm_and_si64
+#define _m_pandn _mm_andnot_si64
+#define _m_por _mm_or_si64
+#define _m_pxor _mm_xor_si64
+#define _m_pcmpeqb _mm_cmpeq_pi8
+#define _m_pcmpeqw _mm_cmpeq_pi16
+#define _m_pcmpeqd _mm_cmpeq_pi32
+#define _m_pcmpgtb _mm_cmpgt_pi8
+#define _m_pcmpgtw _mm_cmpgt_pi16
+#define _m_pcmpgtd _mm_cmpgt_pi32
+
+#endif /* __MMX__ */
+
+#endif /* __MMINTRIN_H */
+
diff --git a/lib/clang/3.5.2/include/module.modulemap b/lib/clang/3.5.2/include/module.modulemap
new file mode 100644
index 0000000..9f7944d
--- /dev/null
+++ b/lib/clang/3.5.2/include/module.modulemap
@@ -0,0 +1,156 @@
+module _Builtin_intrinsics [system] {
+  explicit module altivec {
+    requires altivec
+    header "altivec.h"
+  }
+
+  explicit module arm {
+    requires arm
+
+    explicit module neon {
+      requires neon
+      header "arm_neon.h"
+      export *
+    }
+  }
+
+  explicit module intel {
+    requires x86
+    export *
+
+    header "immintrin.h"
+    header "x86intrin.h"
+
+    explicit module mm_malloc {
+      header "mm_malloc.h"
+      export * // note: for <stdlib.h> dependency
+    }
+
+    explicit module cpuid {
+      requires x86
+      header "cpuid.h"
+    }
+
+    explicit module mmx {
+      requires mmx
+      header "mmintrin.h"
+    }
+
+    explicit module f16c {
+      requires f16c
+      header "f16cintrin.h"
+    }
+
+    explicit module sse {
+      requires sse
+      export mmx
+      export * // note: for hackish <emmintrin.h> dependency
+      header "xmmintrin.h"
+    }
+
+    explicit module sse2 {
+      requires sse2
+      export sse
+      header "emmintrin.h"
+    }
+
+    explicit module sse3 {
+      requires sse3
+      export sse2
+      header "pmmintrin.h"
+    }
+
+    explicit module ssse3 {
+      requires ssse3
+      export sse3
+      header "tmmintrin.h"
+    }
+
+    explicit module sse4_1 {
+      requires sse41
+      export ssse3
+      header "smmintrin.h"
+    }
+
+    explicit module sse4_2 {
+      requires sse42
+      export sse4_1
+      header "nmmintrin.h"
+    }
+
+    explicit module sse4a {
+      requires sse4a
+      export sse3
+      header "ammintrin.h"
+    }
+
+    explicit module avx {
+      requires avx
+      export sse4_2
+      header "avxintrin.h"
+    }
+
+    explicit module avx2 {
+      requires avx2
+      export avx
+      header "avx2intrin.h"
+    }
+
+    explicit module bmi {
+      requires bmi
+      header "bmiintrin.h"
+    }
+
+    explicit module bmi2 {
+      requires bmi2
+      header "bmi2intrin.h"
+    }
+
+    explicit module fma {
+      requires fma
+      header "fmaintrin.h"
+    }
+
+    explicit module fma4 {
+      requires fma4
+      export sse3
+      header "fma4intrin.h"
+    }
+
+    explicit module lzcnt {
+      requires lzcnt
+      header "lzcntintrin.h"
+    }
+
+    explicit module popcnt {
+      requires popcnt
+      header "popcntintrin.h"
+    }
+
+    explicit module mm3dnow {
+      requires mm3dnow
+      header "mm3dnow.h"
+    }
+
+    explicit module xop {
+      requires xop
+      export fma4
+      header "xopintrin.h"
+    }
+
+    explicit module aes_pclmul {
+      requires aes, pclmul
+      header "wmmintrin.h"
+    }
+
+    explicit module aes {
+      requires aes
+      header "__wmmintrin_aes.h"
+    }
+
+    explicit module pclmul {
+      requires pclmul
+      header "__wmmintrin_pclmul.h"
+    }
+  }
+}
diff --git a/lib/clang/3.5.2/include/nmmintrin.h b/lib/clang/3.5.2/include/nmmintrin.h
new file mode 100644
index 0000000..f12622d
--- /dev/null
+++ b/lib/clang/3.5.2/include/nmmintrin.h
@@ -0,0 +1,35 @@
+/*===---- nmmintrin.h - SSE4 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _NMMINTRIN_H
+#define _NMMINTRIN_H
+
+#ifndef __SSE4_2__
+#error "SSE4.2 instruction set not enabled"
+#else
+
+/* To match expectations of gcc we put the sse4.2 definitions into smmintrin.h,
+   just include it now then.  */
+#include <smmintrin.h>
+#endif /* __SSE4_2__ */
+#endif /* _NMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/pmmintrin.h b/lib/clang/3.5.2/include/pmmintrin.h
new file mode 100644
index 0000000..6f1fc32
--- /dev/null
+++ b/lib/clang/3.5.2/include/pmmintrin.h
@@ -0,0 +1,117 @@
+/*===---- pmmintrin.h - SSE3 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __PMMINTRIN_H
+#define __PMMINTRIN_H
+
+#ifndef __SSE3__
+#error "SSE3 instruction set not enabled"
+#else
+
+#include <emmintrin.h>
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_lddqu_si128(__m128i const *__p)
+{
+  return (__m128i)__builtin_ia32_lddqu((char const *)__p);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_addsub_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_addsubps(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_haddps(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_hsubps(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movehdup_ps(__m128 __a)
+{
+  return __builtin_shufflevector(__a, __a, 1, 1, 3, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_moveldup_ps(__m128 __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 0, 2, 2);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_addsub_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_addsubpd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_haddpd(__a, __b);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pd(__m128d __a, __m128d __b)
+{
+  return __builtin_ia32_hsubpd(__a, __b);
+}
+
+#define        _mm_loaddup_pd(dp)        _mm_load1_pd(dp)
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_movedup_pd(__m128d __a)
+{
+  return __builtin_shufflevector(__a, __a, 0, 0);
+}
+
+#define _MM_DENORMALS_ZERO_ON   (0x0040)
+#define _MM_DENORMALS_ZERO_OFF  (0x0000)
+
+#define _MM_DENORMALS_ZERO_MASK (0x0040)
+
+#define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)
+#define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x)))
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_monitor(void const *__p, unsigned __extensions, unsigned __hints)
+{
+  __builtin_ia32_monitor((void *)__p, __extensions, __hints);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_mwait(unsigned __extensions, unsigned __hints)
+{
+  __builtin_ia32_mwait(__extensions, __hints);
+}
+
+#endif /* __SSE3__ */
+
+#endif /* __PMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/popcntintrin.h b/lib/clang/3.5.2/include/popcntintrin.h
new file mode 100644
index 0000000..d439daa
--- /dev/null
+++ b/lib/clang/3.5.2/include/popcntintrin.h
@@ -0,0 +1,45 @@
+/*===---- popcntintrin.h - POPCNT intrinsics -------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __POPCNT__
+#error "POPCNT instruction set not enabled"
+#endif
+
+#ifndef _POPCNTINTRIN_H
+#define _POPCNTINTRIN_H
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_popcnt_u32(unsigned int __A)
+{
+  return __builtin_popcount(__A);
+}
+
+#ifdef __x86_64__
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_popcnt_u64(unsigned long long __A)
+{
+  return __builtin_popcountll(__A);
+}
+#endif /* __x86_64__ */
+
+#endif /* _POPCNTINTRIN_H */
diff --git a/lib/clang/3.5.2/include/prfchwintrin.h b/lib/clang/3.5.2/include/prfchwintrin.h
new file mode 100644
index 0000000..9825bd8
--- /dev/null
+++ b/lib/clang/3.5.2/include/prfchwintrin.h
@@ -0,0 +1,39 @@
+/*===---- prfchwintrin.h - PREFETCHW intrinsic -----------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined(__X86INTRIN_H) && !defined(_MM3DNOW_H_INCLUDED)
+#error "Never use <prfchwintrin.h> directly; include <x86intrin.h> or <mm3dnow.h> instead."
+#endif
+
+#ifndef __PRFCHWINTRIN_H
+#define __PRFCHWINTRIN_H
+
+#if defined(__PRFCHW__) || defined(__3dNOW__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_m_prefetchw(void *__P)
+{
+  __builtin_prefetch (__P, 1, 3 /* _MM_HINT_T0 */);
+}
+#endif
+
+#endif /* __PRFCHWINTRIN_H */
diff --git a/lib/clang/3.5.2/include/rdseedintrin.h b/lib/clang/3.5.2/include/rdseedintrin.h
new file mode 100644
index 0000000..0fef1fa
--- /dev/null
+++ b/lib/clang/3.5.2/include/rdseedintrin.h
@@ -0,0 +1,52 @@
+/*===---- rdseedintrin.h - RDSEED intrinsics -------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86INTRIN_H
+#error "Never use <rdseedintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __RDSEEDINTRIN_H
+#define __RDSEEDINTRIN_H
+
+#ifdef __RDSEED__
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdseed16_step(unsigned short *__p)
+{
+  return __builtin_ia32_rdseed16_step(__p);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdseed32_step(unsigned int *__p)
+{
+  return __builtin_ia32_rdseed32_step(__p);
+}
+
+#ifdef __x86_64__
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_rdseed64_step(unsigned long long *__p)
+{
+  return __builtin_ia32_rdseed64_step(__p);
+}
+#endif
+#endif /* __RDSEED__ */
+#endif /* __RDSEEDINTRIN_H */
diff --git a/lib/clang/3.5.2/include/rtmintrin.h b/lib/clang/3.5.2/include/rtmintrin.h
new file mode 100644
index 0000000..26149ca
--- /dev/null
+++ b/lib/clang/3.5.2/include/rtmintrin.h
@@ -0,0 +1,54 @@
+/*===---- rtmintrin.h - RTM intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <rtmintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __RTMINTRIN_H
+#define __RTMINTRIN_H
+
+#define _XBEGIN_STARTED   (~0u)
+#define _XABORT_EXPLICIT  (1 << 0)
+#define _XABORT_RETRY     (1 << 1)
+#define _XABORT_CONFLICT  (1 << 2)
+#define _XABORT_CAPACITY  (1 << 3)
+#define _XABORT_DEBUG     (1 << 4)
+#define _XABORT_NESTED    (1 << 5)
+#define _XABORT_CODE(x)   (((x) >> 24) & 0xFF)
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_xbegin(void)
+{
+  return __builtin_ia32_xbegin();
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_xend(void)
+{
+  __builtin_ia32_xend();
+}
+
+#define _xabort(imm) __builtin_ia32_xabort((imm))
+
+#endif /* __RTMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/sanitizer/allocator_interface.h b/lib/clang/3.5.2/include/sanitizer/allocator_interface.h
new file mode 100644
index 0000000..ab251f8
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/allocator_interface.h
@@ -0,0 +1,66 @@
+//===-- allocator_interface.h ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Public interface header for allocator used in sanitizers (ASan/TSan/MSan).
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_ALLOCATOR_INTERFACE_H
+#define SANITIZER_ALLOCATOR_INTERFACE_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  /* Returns the estimated number of bytes that will be reserved by allocator
+     for request of "size" bytes. If allocator can't allocate that much
+     memory, returns the maximal possible allocation size, otherwise returns
+     "size". */
+  size_t __sanitizer_get_estimated_allocated_size(size_t size);
+
+  /* Returns true if p was returned by the allocator and
+     is not yet freed. */
+  int __sanitizer_get_ownership(const volatile void *p);
+
+  /* Returns the number of bytes reserved for the pointer p.
+     Requires (get_ownership(p) == true) or (p == 0). */
+  size_t __sanitizer_get_allocated_size(const volatile void *p);
+
+  /* Number of bytes, allocated and not yet freed by the application. */
+  size_t __sanitizer_get_current_allocated_bytes();
+
+  /* Number of bytes, mmaped by the allocator to fulfill allocation requests.
+     Generally, for request of X bytes, allocator can reserve and add to free
+     lists a large number of chunks of size X to use them for future requests.
+     All these chunks count toward the heap size. Currently, allocator never
+     releases memory to OS (instead, it just puts freed chunks to free
+     lists). */
+  size_t __sanitizer_get_heap_size();
+
+  /* Number of bytes, mmaped by the allocator, which can be used to fulfill
+     allocation requests. When a user program frees memory chunk, it can first
+     fall into quarantine and will count toward __sanitizer_get_free_bytes()
+     later. */
+  size_t __sanitizer_get_free_bytes();
+
+  /* Number of bytes in unmapped pages, that are released to OS. Currently,
+     always returns 0. */
+  size_t __sanitizer_get_unmapped_bytes();
+
+  /* Malloc hooks that may be optionally provided by user.
+     __sanitizer_malloc_hook(ptr, size) is called immediately after
+       allocation of "size" bytes, which returned "ptr".
+     __sanitizer_free_hook(ptr) is called immediately before
+       deallocation of "ptr". */
+  void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);
+  void __sanitizer_free_hook(const volatile void *ptr);
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/lib/clang/3.5.2/include/sanitizer/asan_interface.h b/lib/clang/3.5.2/include/sanitizer/asan_interface.h
new file mode 100644
index 0000000..e8163cf
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/asan_interface.h
@@ -0,0 +1,179 @@
+//===-- sanitizer/asan_interface.h ------------------------------*- 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 a part of AddressSanitizer.
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_ASAN_INTERFACE_H
+#define SANITIZER_ASAN_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  // Marks memory region [addr, addr+size) as unaddressable.
+  // This memory must be previously allocated by the user program. Accessing
+  // addresses in this region from instrumented code is forbidden until
+  // this region is unpoisoned. This function is not guaranteed to poison
+  // the whole region - it may poison only subregion of [addr, addr+size) due
+  // to ASan alignment restrictions.
+  // Method is NOT thread-safe in the sense that no two threads can
+  // (un)poison memory in the same memory region simultaneously.
+  void __asan_poison_memory_region(void const volatile *addr, size_t size);
+  // Marks memory region [addr, addr+size) as addressable.
+  // This memory must be previously allocated by the user program. Accessing
+  // addresses in this region is allowed until this region is poisoned again.
+  // This function may unpoison a superregion of [addr, addr+size) due to
+  // ASan alignment restrictions.
+  // Method is NOT thread-safe in the sense that no two threads can
+  // (un)poison memory in the same memory region simultaneously.
+  void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+
+// User code should use macros instead of functions.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+#define ASAN_POISON_MEMORY_REGION(addr, size) \
+  __asan_poison_memory_region((addr), (size))
+#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
+  __asan_unpoison_memory_region((addr), (size))
+#else
+#define ASAN_POISON_MEMORY_REGION(addr, size) \
+  ((void)(addr), (void)(size))
+#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
+  ((void)(addr), (void)(size))
+#endif
+
+  // Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this
+  // address will result in error report from AddressSanitizer).
+  // Otherwise returns 0.
+  int __asan_address_is_poisoned(void const volatile *addr);
+
+  // If at least on byte in [beg, beg+size) is poisoned, return the address
+  // of the first such byte. Otherwise return 0.
+  void *__asan_region_is_poisoned(void *beg, size_t size);
+
+  // Print the description of addr (useful when debugging in gdb).
+  void __asan_describe_address(void *addr);
+
+  // Useful for calling from the debugger to get the allocation stack trace
+  // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
+  // returns the number of stored frames or 0 on error.
+  size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
+                                int *thread_id);
+
+  // Useful for calling from the debugger to get the free stack trace
+  // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
+  // returns the number of stored frames or 0 on error.
+  size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
+                               int *thread_id);
+
+  // Useful for calling from the debugger to get the current shadow memory
+  // mapping.
+  void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
+
+  // This is an internal function that is called to report an error.
+  // However it is still a part of the interface because users may want to
+  // set a breakpoint on this function in a debugger.
+  void __asan_report_error(void *pc, void *bp, void *sp,
+                           void *addr, int is_write, size_t access_size);
+
+  // Sets the exit code to use when reporting an error.
+  // Returns the old value.
+  int __asan_set_error_exit_code(int exit_code);
+
+  // Sets the callback to be called right before death on error.
+  // Passing 0 will unset the callback.
+  void __asan_set_death_callback(void (*callback)(void));
+
+  void __asan_set_error_report_callback(void (*callback)(const char*));
+
+  // User may provide function that would be called right when ASan detects
+  // an error. This can be used to notice cases when ASan detects an error, but
+  // the program crashes before ASan report is printed.
+  void __asan_on_error();
+
+  // Returns the estimated number of bytes that will be reserved by allocator
+  // for request of "size" bytes. If ASan allocator can't allocate that much
+  // memory, returns the maximal possible allocation size, otherwise returns
+  // "size".
+  /* DEPRECATED: Use __sanitizer_get_estimated_allocated_size instead. */
+  size_t __asan_get_estimated_allocated_size(size_t size);
+
+  // Returns 1 if p was returned by the ASan allocator and is not yet freed.
+  // Otherwise returns 0.
+  /* DEPRECATED: Use __sanitizer_get_ownership instead. */
+  int __asan_get_ownership(const void *p);
+
+  // Returns the number of bytes reserved for the pointer p.
+  // Requires (get_ownership(p) == true) or (p == 0).
+  /* DEPRECATED: Use __sanitizer_get_allocated_size instead. */
+  size_t __asan_get_allocated_size(const void *p);
+
+  // Number of bytes, allocated and not yet freed by the application.
+  /* DEPRECATED: Use __sanitizer_get_current_allocated_bytes instead. */
+  size_t __asan_get_current_allocated_bytes();
+
+  // Number of bytes, mmaped by asan allocator to fulfill allocation requests.
+  // Generally, for request of X bytes, allocator can reserve and add to free
+  // lists a large number of chunks of size X to use them for future requests.
+  // All these chunks count toward the heap size. Currently, allocator never
+  // releases memory to OS (instead, it just puts freed chunks to free lists).
+  /* DEPRECATED: Use __sanitizer_get_heap_size instead. */
+  size_t __asan_get_heap_size();
+
+  // Number of bytes, mmaped by asan allocator, which can be used to fulfill
+  // allocation requests. When a user program frees memory chunk, it can first
+  // fall into quarantine and will count toward __asan_get_free_bytes() later.
+  /* DEPRECATED: Use __sanitizer_get_free_bytes instead. */
+  size_t __asan_get_free_bytes();
+
+  // Number of bytes in unmapped pages, that are released to OS. Currently,
+  // always returns 0.
+  /* DEPRECATED: Use __sanitizer_get_unmapped_bytes instead. */
+  size_t __asan_get_unmapped_bytes();
+
+  // Prints accumulated stats to stderr. Used for debugging.
+  void __asan_print_accumulated_stats();
+
+  // This function may be optionally provided by user and should return
+  // a string containing ASan runtime options. See asan_flags.h for details.
+  const char* __asan_default_options();
+
+  // Malloc hooks that may be optionally provided by user.
+  // __asan_malloc_hook(ptr, size) is called immediately after
+  //   allocation of "size" bytes, which returned "ptr".
+  // __asan_free_hook(ptr) is called immediately before
+  //   deallocation of "ptr".
+  /* DEPRECATED: Use __sanitizer_malloc_hook / __sanitizer_free_hook instead. */
+  void __asan_malloc_hook(void *ptr, size_t size);
+  void __asan_free_hook(void *ptr);
+
+  // The following 2 functions facilitate garbage collection in presence of
+  // asan's fake stack.
+
+  // Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.
+  // Returns NULL if the current thread does not have a fake stack.
+  void *__asan_get_current_fake_stack();
+
+  // If fake_stack is non-NULL and addr belongs to a fake frame in
+  // fake_stack, returns the address on real stack that corresponds to
+  // the fake frame and sets beg/end to the boundaries of this fake frame.
+  // Otherwise returns NULL and does not touch beg/end.
+  // If beg/end are NULL, they are not touched.
+  // This function may be called from a thread other than the owner of
+  // fake_stack, but the owner thread need to be alive.
+  void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
+                                     void **end);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // SANITIZER_ASAN_INTERFACE_H
diff --git a/lib/clang/3.5.2/include/sanitizer/common_interface_defs.h b/lib/clang/3.5.2/include/sanitizer/common_interface_defs.h
new file mode 100644
index 0000000..082a931
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/common_interface_defs.h
@@ -0,0 +1,124 @@
+//===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common part of the public sanitizer interface.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_COMMON_INTERFACE_DEFS_H
+#define SANITIZER_COMMON_INTERFACE_DEFS_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+// GCC does not understand __has_feature.
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  // Arguments for __sanitizer_sandbox_on_notify() below.
+  typedef struct {
+    // Enable sandbox support in sanitizer coverage.
+    int coverage_sandboxed;
+    // File descriptor to write coverage data to. If -1 is passed, a file will
+    // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
+    // effect if coverage_sandboxed == 0.
+    intptr_t coverage_fd;
+    // If non-zero, split the coverage data into well-formed blocks. This is
+    // useful when coverage_fd is a socket descriptor. Each block will contain
+    // a header, allowing data from multiple processes to be sent over the same
+    // socket.
+    unsigned int coverage_max_block_size;
+  } __sanitizer_sandbox_arguments;
+
+  // Tell the tools to write their reports to "path.<pid>" instead of stderr.
+  void __sanitizer_set_report_path(const char *path);
+
+  // Notify the tools that the sandbox is going to be turned on. The reserved
+  // parameter will be used in the future to hold a structure with functions
+  // that the tools may call to bypass the sandbox.
+  void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
+
+  // This function is called by the tool when it has just finished reporting
+  // an error. 'error_summary' is a one-line string that summarizes
+  // the error message. This function can be overridden by the client.
+  void __sanitizer_report_error_summary(const char *error_summary);
+
+  // Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen
+  // in unaligned loads/stores. In order to find such bugs reliably one needs
+  // to replace plain unaligned loads/stores with these calls.
+  uint16_t __sanitizer_unaligned_load16(const void *p);
+  uint32_t __sanitizer_unaligned_load32(const void *p);
+  uint64_t __sanitizer_unaligned_load64(const void *p);
+  void __sanitizer_unaligned_store16(void *p, uint16_t x);
+  void __sanitizer_unaligned_store32(void *p, uint32_t x);
+  void __sanitizer_unaligned_store64(void *p, uint64_t x);
+
+  // Initialize coverage.
+  void __sanitizer_cov_init();
+  // Record and dump coverage info.
+  void __sanitizer_cov_dump();
+  // Open <name>.sancov.packed in the coverage directory and return the file
+  // descriptor. Returns -1 on failure, or if coverage dumping is disabled.
+  // This is intended for use by sandboxing code.
+  intptr_t __sanitizer_maybe_open_cov_file(const char *name);
+
+  // Annotate the current state of a contiguous container, such as
+  // std::vector, std::string or similar.
+  // A contiguous container is a container that keeps all of its elements
+  // in a contiguous region of memory. The container owns the region of memory
+  // [beg, end); the memory [beg, mid) is used to store the current elements
+  // and the memory [mid, end) is reserved for future elements;
+  // beg <= mid <= end. For example, in "std::vector<> v"
+  //   beg = &v[0];
+  //   end = beg + v.capacity() * sizeof(v[0]);
+  //   mid = beg + v.size()     * sizeof(v[0]);
+  //
+  // This annotation tells the Sanitizer tool about the current state of the
+  // container so that the tool can report errors when memory from [mid, end)
+  // is accessed. Insert this annotation into methods like push_back/pop_back.
+  // Supply the old and the new values of mid (old_mid/new_mid).
+  // In the initial state mid == end and so should be the final
+  // state when the container is destroyed or when it reallocates the storage.
+  //
+  // Use with caution and don't use for anything other than vector-like classes.
+  //
+  // For AddressSanitizer, 'beg' should be 8-aligned and 'end' should
+  // be either 8-aligned or it should point to the end of a separate heap-,
+  // stack-, or global- allocated buffer. I.e. the following will not work:
+  //   int64_t x[2];  // 16 bytes, 8-aligned.
+  //   char *beg = (char *)&x[0];
+  //   char *end = beg + 12;  // Not 8 aligned, not the end of the buffer.
+  // This however will work fine:
+  //   int32_t x[3];  // 12 bytes, but 8-aligned under AddressSanitizer.
+  //   char *beg = (char*)&x[0];
+  //   char *end = beg + 12;  // Not 8-aligned, but is the end of the buffer.
+  void __sanitizer_annotate_contiguous_container(const void *beg,
+                                                 const void *end,
+                                                 const void *old_mid,
+                                                 const void *new_mid);
+  // Returns true if the contiguous container [beg, end) ir properly poisoned
+  // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
+  //  - [beg, mid) is addressable,
+  //  - [mid, end) is unaddressable.
+  // Full verification requires O(end-beg) time; this function tries to avoid
+  // such complexity by touching only parts of the container around beg/mid/end.
+  int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
+                                              const void *end);
+
+  // Print the stack trace leading to this call. Useful for debugging user code.
+  void __sanitizer_print_stack_trace();
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // SANITIZER_COMMON_INTERFACE_DEFS_H
diff --git a/lib/clang/3.5.2/include/sanitizer/dfsan_interface.h b/lib/clang/3.5.2/include/sanitizer/dfsan_interface.h
new file mode 100644
index 0000000..bcd4ae0
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/dfsan_interface.h
@@ -0,0 +1,98 @@
+//===-- dfsan_interface.h -------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of DataFlowSanitizer.
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef DFSAN_INTERFACE_H
+#define DFSAN_INTERFACE_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint16_t dfsan_label;
+
+/// Stores information associated with a specific label identifier.  A label
+/// may be a base label created using dfsan_create_label, with associated
+/// text description and user data, or an automatically created union label,
+/// which represents the union of two label identifiers (which may themselves
+/// be base or union labels).
+struct dfsan_label_info {
+  // Fields for union labels, set to 0 for base labels.
+  dfsan_label l1;
+  dfsan_label l2;
+
+  // Fields for base labels.
+  const char *desc;
+  void *userdata;
+};
+
+/// Signature of the callback argument to dfsan_set_write_callback().
+typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count);
+
+/// Computes the union of \c l1 and \c l2, possibly creating a union label in
+/// the process.
+dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
+
+/// Creates and returns a base label with the given description and user data.
+dfsan_label dfsan_create_label(const char *desc, void *userdata);
+
+/// Sets the label for each address in [addr,addr+size) to \c label.
+void dfsan_set_label(dfsan_label label, void *addr, size_t size);
+
+/// Sets the label for each address in [addr,addr+size) to the union of the
+/// current label for that address and \c label.
+void dfsan_add_label(dfsan_label label, void *addr, size_t size);
+
+/// Retrieves the label associated with the given data.
+///
+/// The type of 'data' is arbitrary.  The function accepts a value of any type,
+/// which can be truncated or extended (implicitly or explicitly) as necessary.
+/// The truncation/extension operations will preserve the label of the original
+/// value.
+dfsan_label dfsan_get_label(long data);
+
+/// Retrieves the label associated with the data at the given address.
+dfsan_label dfsan_read_label(const void *addr, size_t size);
+
+/// Retrieves a pointer to the dfsan_label_info struct for the given label.
+const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);
+
+/// Returns whether the given label label contains the label elem.
+int dfsan_has_label(dfsan_label label, dfsan_label elem);
+
+/// If the given label label contains a label with the description desc, returns
+/// that label, else returns 0.
+dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
+
+/// Returns the number of labels allocated.
+size_t dfsan_get_label_count(void);
+
+/// Sets a callback to be invoked on calls to write().  The callback is invoked
+/// before the write is done.  The write is not guaranteed to succeed when the
+/// callback executes.  Pass in NULL to remove any callback.
+void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback);
+
+#ifdef __cplusplus
+}  // extern "C"
+
+template <typename T>
+void dfsan_set_label(dfsan_label label, T &data) {  // NOLINT
+  dfsan_set_label(label, (void *)&data, sizeof(T));
+}
+
+#endif
+
+#endif  // DFSAN_INTERFACE_H
diff --git a/lib/clang/3.5.2/include/sanitizer/linux_syscall_hooks.h b/lib/clang/3.5.2/include/sanitizer/linux_syscall_hooks.h
new file mode 100644
index 0000000..89867c1
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/linux_syscall_hooks.h
@@ -0,0 +1,3070 @@
+//===-- linux_syscall_hooks.h ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of public sanitizer interface.
+//
+// System call handlers.
+//
+// Interface methods declared in this header implement pre- and post- syscall
+// actions for the active sanitizer.
+// Usage:
+//   __sanitizer_syscall_pre_getfoo(...args...);
+//   long res = syscall(__NR_getfoo, ...args...);
+//   __sanitizer_syscall_post_getfoo(res, ...args...);
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_LINUX_SYSCALL_HOOKS_H
+#define SANITIZER_LINUX_SYSCALL_HOOKS_H
+
+#define __sanitizer_syscall_pre_time(tloc) \
+  __sanitizer_syscall_pre_impl_time((long)(tloc))
+#define __sanitizer_syscall_post_time(res, tloc) \
+  __sanitizer_syscall_post_impl_time(res, (long)(tloc))
+#define __sanitizer_syscall_pre_stime(tptr) \
+  __sanitizer_syscall_pre_impl_stime((long)(tptr))
+#define __sanitizer_syscall_post_stime(res, tptr) \
+  __sanitizer_syscall_post_impl_stime(res, (long)(tptr))
+#define __sanitizer_syscall_pre_gettimeofday(tv, tz) \
+  __sanitizer_syscall_pre_impl_gettimeofday((long)(tv), (long)(tz))
+#define __sanitizer_syscall_post_gettimeofday(res, tv, tz) \
+  __sanitizer_syscall_post_impl_gettimeofday(res, (long)(tv), (long)(tz))
+#define __sanitizer_syscall_pre_settimeofday(tv, tz) \
+  __sanitizer_syscall_pre_impl_settimeofday((long)(tv), (long)(tz))
+#define __sanitizer_syscall_post_settimeofday(res, tv, tz) \
+  __sanitizer_syscall_post_impl_settimeofday(res, (long)(tv), (long)(tz))
+#define __sanitizer_syscall_pre_adjtimex(txc_p) \
+  __sanitizer_syscall_pre_impl_adjtimex((long)(txc_p))
+#define __sanitizer_syscall_post_adjtimex(res, txc_p) \
+  __sanitizer_syscall_post_impl_adjtimex(res, (long)(txc_p))
+#define __sanitizer_syscall_pre_times(tbuf) \
+  __sanitizer_syscall_pre_impl_times((long)(tbuf))
+#define __sanitizer_syscall_post_times(res, tbuf) \
+  __sanitizer_syscall_post_impl_times(res, (long)(tbuf))
+#define __sanitizer_syscall_pre_gettid() __sanitizer_syscall_pre_impl_gettid()
+#define __sanitizer_syscall_post_gettid(res) \
+  __sanitizer_syscall_post_impl_gettid(res)
+#define __sanitizer_syscall_pre_nanosleep(rqtp, rmtp) \
+  __sanitizer_syscall_pre_impl_nanosleep((long)(rqtp), (long)(rmtp))
+#define __sanitizer_syscall_post_nanosleep(res, rqtp, rmtp) \
+  __sanitizer_syscall_post_impl_nanosleep(res, (long)(rqtp), (long)(rmtp))
+#define __sanitizer_syscall_pre_alarm(seconds) \
+  __sanitizer_syscall_pre_impl_alarm((long)(seconds))
+#define __sanitizer_syscall_post_alarm(res, seconds) \
+  __sanitizer_syscall_post_impl_alarm(res, (long)(seconds))
+#define __sanitizer_syscall_pre_getpid() __sanitizer_syscall_pre_impl_getpid()
+#define __sanitizer_syscall_post_getpid(res) \
+  __sanitizer_syscall_post_impl_getpid(res)
+#define __sanitizer_syscall_pre_getppid() __sanitizer_syscall_pre_impl_getppid()
+#define __sanitizer_syscall_post_getppid(res) \
+  __sanitizer_syscall_post_impl_getppid(res)
+#define __sanitizer_syscall_pre_getuid() __sanitizer_syscall_pre_impl_getuid()
+#define __sanitizer_syscall_post_getuid(res) \
+  __sanitizer_syscall_post_impl_getuid(res)
+#define __sanitizer_syscall_pre_geteuid() __sanitizer_syscall_pre_impl_geteuid()
+#define __sanitizer_syscall_post_geteuid(res) \
+  __sanitizer_syscall_post_impl_geteuid(res)
+#define __sanitizer_syscall_pre_getgid() __sanitizer_syscall_pre_impl_getgid()
+#define __sanitizer_syscall_post_getgid(res) \
+  __sanitizer_syscall_post_impl_getgid(res)
+#define __sanitizer_syscall_pre_getegid() __sanitizer_syscall_pre_impl_getegid()
+#define __sanitizer_syscall_post_getegid(res) \
+  __sanitizer_syscall_post_impl_getegid(res)
+#define __sanitizer_syscall_pre_getresuid(ruid, euid, suid)          \
+  __sanitizer_syscall_pre_impl_getresuid((long)(ruid), (long)(euid), \
+                                         (long)(suid))
+#define __sanitizer_syscall_post_getresuid(res, ruid, euid, suid)          \
+  __sanitizer_syscall_post_impl_getresuid(res, (long)(ruid), (long)(euid), \
+                                          (long)(suid))
+#define __sanitizer_syscall_pre_getresgid(rgid, egid, sgid)          \
+  __sanitizer_syscall_pre_impl_getresgid((long)(rgid), (long)(egid), \
+                                         (long)(sgid))
+#define __sanitizer_syscall_post_getresgid(res, rgid, egid, sgid)          \
+  __sanitizer_syscall_post_impl_getresgid(res, (long)(rgid), (long)(egid), \
+                                          (long)(sgid))
+#define __sanitizer_syscall_pre_getpgid(pid) \
+  __sanitizer_syscall_pre_impl_getpgid((long)(pid))
+#define __sanitizer_syscall_post_getpgid(res, pid) \
+  __sanitizer_syscall_post_impl_getpgid(res, (long)(pid))
+#define __sanitizer_syscall_pre_getpgrp() __sanitizer_syscall_pre_impl_getpgrp()
+#define __sanitizer_syscall_post_getpgrp(res) \
+  __sanitizer_syscall_post_impl_getpgrp(res)
+#define __sanitizer_syscall_pre_getsid(pid) \
+  __sanitizer_syscall_pre_impl_getsid((long)(pid))
+#define __sanitizer_syscall_post_getsid(res, pid) \
+  __sanitizer_syscall_post_impl_getsid(res, (long)(pid))
+#define __sanitizer_syscall_pre_getgroups(gidsetsize, grouplist) \
+  __sanitizer_syscall_pre_impl_getgroups((long)(gidsetsize), (long)(grouplist))
+#define __sanitizer_syscall_post_getgroups(res, gidsetsize, grouplist) \
+  __sanitizer_syscall_post_impl_getgroups(res, (long)(gidsetsize),     \
+                                          (long)(grouplist))
+#define __sanitizer_syscall_pre_setregid(rgid, egid) \
+  __sanitizer_syscall_pre_impl_setregid((long)(rgid), (long)(egid))
+#define __sanitizer_syscall_post_setregid(res, rgid, egid) \
+  __sanitizer_syscall_post_impl_setregid(res, (long)(rgid), (long)(egid))
+#define __sanitizer_syscall_pre_setgid(gid) \
+  __sanitizer_syscall_pre_impl_setgid((long)(gid))
+#define __sanitizer_syscall_post_setgid(res, gid) \
+  __sanitizer_syscall_post_impl_setgid(res, (long)(gid))
+#define __sanitizer_syscall_pre_setreuid(ruid, euid) \
+  __sanitizer_syscall_pre_impl_setreuid((long)(ruid), (long)(euid))
+#define __sanitizer_syscall_post_setreuid(res, ruid, euid) \
+  __sanitizer_syscall_post_impl_setreuid(res, (long)(ruid), (long)(euid))
+#define __sanitizer_syscall_pre_setuid(uid) \
+  __sanitizer_syscall_pre_impl_setuid((long)(uid))
+#define __sanitizer_syscall_post_setuid(res, uid) \
+  __sanitizer_syscall_post_impl_setuid(res, (long)(uid))
+#define __sanitizer_syscall_pre_setresuid(ruid, euid, suid)          \
+  __sanitizer_syscall_pre_impl_setresuid((long)(ruid), (long)(euid), \
+                                         (long)(suid))
+#define __sanitizer_syscall_post_setresuid(res, ruid, euid, suid)          \
+  __sanitizer_syscall_post_impl_setresuid(res, (long)(ruid), (long)(euid), \
+                                          (long)(suid))
+#define __sanitizer_syscall_pre_setresgid(rgid, egid, sgid)          \
+  __sanitizer_syscall_pre_impl_setresgid((long)(rgid), (long)(egid), \
+                                         (long)(sgid))
+#define __sanitizer_syscall_post_setresgid(res, rgid, egid, sgid)          \
+  __sanitizer_syscall_post_impl_setresgid(res, (long)(rgid), (long)(egid), \
+                                          (long)(sgid))
+#define __sanitizer_syscall_pre_setfsuid(uid) \
+  __sanitizer_syscall_pre_impl_setfsuid((long)(uid))
+#define __sanitizer_syscall_post_setfsuid(res, uid) \
+  __sanitizer_syscall_post_impl_setfsuid(res, (long)(uid))
+#define __sanitizer_syscall_pre_setfsgid(gid) \
+  __sanitizer_syscall_pre_impl_setfsgid((long)(gid))
+#define __sanitizer_syscall_post_setfsgid(res, gid) \
+  __sanitizer_syscall_post_impl_setfsgid(res, (long)(gid))
+#define __sanitizer_syscall_pre_setpgid(pid, pgid) \
+  __sanitizer_syscall_pre_impl_setpgid((long)(pid), (long)(pgid))
+#define __sanitizer_syscall_post_setpgid(res, pid, pgid) \
+  __sanitizer_syscall_post_impl_setpgid(res, (long)(pid), (long)(pgid))
+#define __sanitizer_syscall_pre_setsid() __sanitizer_syscall_pre_impl_setsid()
+#define __sanitizer_syscall_post_setsid(res) \
+  __sanitizer_syscall_post_impl_setsid(res)
+#define __sanitizer_syscall_pre_setgroups(gidsetsize, grouplist) \
+  __sanitizer_syscall_pre_impl_setgroups((long)(gidsetsize), (long)(grouplist))
+#define __sanitizer_syscall_post_setgroups(res, gidsetsize, grouplist) \
+  __sanitizer_syscall_post_impl_setgroups(res, (long)(gidsetsize),     \
+                                          (long)(grouplist))
+#define __sanitizer_syscall_pre_acct(name) \
+  __sanitizer_syscall_pre_impl_acct((long)(name))
+#define __sanitizer_syscall_post_acct(res, name) \
+  __sanitizer_syscall_post_impl_acct(res, (long)(name))
+#define __sanitizer_syscall_pre_capget(header, dataptr) \
+  __sanitizer_syscall_pre_impl_capget((long)(header), (long)(dataptr))
+#define __sanitizer_syscall_post_capget(res, header, dataptr) \
+  __sanitizer_syscall_post_impl_capget(res, (long)(header), (long)(dataptr))
+#define __sanitizer_syscall_pre_capset(header, data) \
+  __sanitizer_syscall_pre_impl_capset((long)(header), (long)(data))
+#define __sanitizer_syscall_post_capset(res, header, data) \
+  __sanitizer_syscall_post_impl_capset(res, (long)(header), (long)(data))
+#define __sanitizer_syscall_pre_personality(personality) \
+  __sanitizer_syscall_pre_impl_personality((long)(personality))
+#define __sanitizer_syscall_post_personality(res, personality) \
+  __sanitizer_syscall_post_impl_personality(res, (long)(personality))
+#define __sanitizer_syscall_pre_sigpending(set) \
+  __sanitizer_syscall_pre_impl_sigpending((long)(set))
+#define __sanitizer_syscall_post_sigpending(res, set) \
+  __sanitizer_syscall_post_impl_sigpending(res, (long)(set))
+#define __sanitizer_syscall_pre_sigprocmask(how, set, oset)          \
+  __sanitizer_syscall_pre_impl_sigprocmask((long)(how), (long)(set), \
+                                           (long)(oset))
+#define __sanitizer_syscall_post_sigprocmask(res, how, set, oset)          \
+  __sanitizer_syscall_post_impl_sigprocmask(res, (long)(how), (long)(set), \
+                                            (long)(oset))
+#define __sanitizer_syscall_pre_getitimer(which, value) \
+  __sanitizer_syscall_pre_impl_getitimer((long)(which), (long)(value))
+#define __sanitizer_syscall_post_getitimer(res, which, value) \
+  __sanitizer_syscall_post_impl_getitimer(res, (long)(which), (long)(value))
+#define __sanitizer_syscall_pre_setitimer(which, value, ovalue)        \
+  __sanitizer_syscall_pre_impl_setitimer((long)(which), (long)(value), \
+                                         (long)(ovalue))
+#define __sanitizer_syscall_post_setitimer(res, which, value, ovalue)        \
+  __sanitizer_syscall_post_impl_setitimer(res, (long)(which), (long)(value), \
+                                          (long)(ovalue))
+#define __sanitizer_syscall_pre_timer_create(which_clock, timer_event_spec, \
+                                             created_timer_id)              \
+  __sanitizer_syscall_pre_impl_timer_create(                                \
+      (long)(which_clock), (long)(timer_event_spec), (long)(created_timer_id))
+#define __sanitizer_syscall_post_timer_create(                         \
+    res, which_clock, timer_event_spec, created_timer_id)              \
+  __sanitizer_syscall_post_impl_timer_create(res, (long)(which_clock), \
+                                             (long)(timer_event_spec), \
+                                             (long)(created_timer_id))
+#define __sanitizer_syscall_pre_timer_gettime(timer_id, setting) \
+  __sanitizer_syscall_pre_impl_timer_gettime((long)(timer_id), (long)(setting))
+#define __sanitizer_syscall_post_timer_gettime(res, timer_id, setting) \
+  __sanitizer_syscall_post_impl_timer_gettime(res, (long)(timer_id),   \
+                                              (long)(setting))
+#define __sanitizer_syscall_pre_timer_getoverrun(timer_id) \
+  __sanitizer_syscall_pre_impl_timer_getoverrun((long)(timer_id))
+#define __sanitizer_syscall_post_timer_getoverrun(res, timer_id) \
+  __sanitizer_syscall_post_impl_timer_getoverrun(res, (long)(timer_id))
+#define __sanitizer_syscall_pre_timer_settime(timer_id, flags, new_setting,   \
+                                              old_setting)                    \
+  __sanitizer_syscall_pre_impl_timer_settime((long)(timer_id), (long)(flags), \
+                                             (long)(new_setting),             \
+                                             (long)(old_setting))
+#define __sanitizer_syscall_post_timer_settime(res, timer_id, flags,     \
+                                               new_setting, old_setting) \
+  __sanitizer_syscall_post_impl_timer_settime(                           \
+      res, (long)(timer_id), (long)(flags), (long)(new_setting),         \
+      (long)(old_setting))
+#define __sanitizer_syscall_pre_timer_delete(timer_id) \
+  __sanitizer_syscall_pre_impl_timer_delete((long)(timer_id))
+#define __sanitizer_syscall_post_timer_delete(res, timer_id) \
+  __sanitizer_syscall_post_impl_timer_delete(res, (long)(timer_id))
+#define __sanitizer_syscall_pre_clock_settime(which_clock, tp) \
+  __sanitizer_syscall_pre_impl_clock_settime((long)(which_clock), (long)(tp))
+#define __sanitizer_syscall_post_clock_settime(res, which_clock, tp)    \
+  __sanitizer_syscall_post_impl_clock_settime(res, (long)(which_clock), \
+                                              (long)(tp))
+#define __sanitizer_syscall_pre_clock_gettime(which_clock, tp) \
+  __sanitizer_syscall_pre_impl_clock_gettime((long)(which_clock), (long)(tp))
+#define __sanitizer_syscall_post_clock_gettime(res, which_clock, tp)    \
+  __sanitizer_syscall_post_impl_clock_gettime(res, (long)(which_clock), \
+                                              (long)(tp))
+#define __sanitizer_syscall_pre_clock_adjtime(which_clock, tx) \
+  __sanitizer_syscall_pre_impl_clock_adjtime((long)(which_clock), (long)(tx))
+#define __sanitizer_syscall_post_clock_adjtime(res, which_clock, tx)    \
+  __sanitizer_syscall_post_impl_clock_adjtime(res, (long)(which_clock), \
+                                              (long)(tx))
+#define __sanitizer_syscall_pre_clock_getres(which_clock, tp) \
+  __sanitizer_syscall_pre_impl_clock_getres((long)(which_clock), (long)(tp))
+#define __sanitizer_syscall_post_clock_getres(res, which_clock, tp)    \
+  __sanitizer_syscall_post_impl_clock_getres(res, (long)(which_clock), \
+                                             (long)(tp))
+#define __sanitizer_syscall_pre_clock_nanosleep(which_clock, flags, rqtp, \
+                                                rmtp)                     \
+  __sanitizer_syscall_pre_impl_clock_nanosleep(                           \
+      (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp))
+#define __sanitizer_syscall_post_clock_nanosleep(res, which_clock, flags, \
+                                                 rqtp, rmtp)              \
+  __sanitizer_syscall_post_impl_clock_nanosleep(                          \
+      res, (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp))
+#define __sanitizer_syscall_pre_nice(increment) \
+  __sanitizer_syscall_pre_impl_nice((long)(increment))
+#define __sanitizer_syscall_post_nice(res, increment) \
+  __sanitizer_syscall_post_impl_nice(res, (long)(increment))
+#define __sanitizer_syscall_pre_sched_setscheduler(pid, policy, param)         \
+  __sanitizer_syscall_pre_impl_sched_setscheduler((long)(pid), (long)(policy), \
+                                                  (long)(param))
+#define __sanitizer_syscall_post_sched_setscheduler(res, pid, policy, param) \
+  __sanitizer_syscall_post_impl_sched_setscheduler(                          \
+      res, (long)(pid), (long)(policy), (long)(param))
+#define __sanitizer_syscall_pre_sched_setparam(pid, param) \
+  __sanitizer_syscall_pre_impl_sched_setparam((long)(pid), (long)(param))
+#define __sanitizer_syscall_post_sched_setparam(res, pid, param) \
+  __sanitizer_syscall_post_impl_sched_setparam(res, (long)(pid), (long)(param))
+#define __sanitizer_syscall_pre_sched_getscheduler(pid) \
+  __sanitizer_syscall_pre_impl_sched_getscheduler((long)(pid))
+#define __sanitizer_syscall_post_sched_getscheduler(res, pid) \
+  __sanitizer_syscall_post_impl_sched_getscheduler(res, (long)(pid))
+#define __sanitizer_syscall_pre_sched_getparam(pid, param) \
+  __sanitizer_syscall_pre_impl_sched_getparam((long)(pid), (long)(param))
+#define __sanitizer_syscall_post_sched_getparam(res, pid, param) \
+  __sanitizer_syscall_post_impl_sched_getparam(res, (long)(pid), (long)(param))
+#define __sanitizer_syscall_pre_sched_setaffinity(pid, len, user_mask_ptr) \
+  __sanitizer_syscall_pre_impl_sched_setaffinity((long)(pid), (long)(len), \
+                                                 (long)(user_mask_ptr))
+#define __sanitizer_syscall_post_sched_setaffinity(res, pid, len, \
+                                                   user_mask_ptr) \
+  __sanitizer_syscall_post_impl_sched_setaffinity(                \
+      res, (long)(pid), (long)(len), (long)(user_mask_ptr))
+#define __sanitizer_syscall_pre_sched_getaffinity(pid, len, user_mask_ptr) \
+  __sanitizer_syscall_pre_impl_sched_getaffinity((long)(pid), (long)(len), \
+                                                 (long)(user_mask_ptr))
+#define __sanitizer_syscall_post_sched_getaffinity(res, pid, len, \
+                                                   user_mask_ptr) \
+  __sanitizer_syscall_post_impl_sched_getaffinity(                \
+      res, (long)(pid), (long)(len), (long)(user_mask_ptr))
+#define __sanitizer_syscall_pre_sched_yield() \
+  __sanitizer_syscall_pre_impl_sched_yield()
+#define __sanitizer_syscall_post_sched_yield(res) \
+  __sanitizer_syscall_post_impl_sched_yield(res)
+#define __sanitizer_syscall_pre_sched_get_priority_max(policy) \
+  __sanitizer_syscall_pre_impl_sched_get_priority_max((long)(policy))
+#define __sanitizer_syscall_post_sched_get_priority_max(res, policy) \
+  __sanitizer_syscall_post_impl_sched_get_priority_max(res, (long)(policy))
+#define __sanitizer_syscall_pre_sched_get_priority_min(policy) \
+  __sanitizer_syscall_pre_impl_sched_get_priority_min((long)(policy))
+#define __sanitizer_syscall_post_sched_get_priority_min(res, policy) \
+  __sanitizer_syscall_post_impl_sched_get_priority_min(res, (long)(policy))
+#define __sanitizer_syscall_pre_sched_rr_get_interval(pid, interval) \
+  __sanitizer_syscall_pre_impl_sched_rr_get_interval((long)(pid),    \
+                                                     (long)(interval))
+#define __sanitizer_syscall_post_sched_rr_get_interval(res, pid, interval) \
+  __sanitizer_syscall_post_impl_sched_rr_get_interval(res, (long)(pid),    \
+                                                      (long)(interval))
+#define __sanitizer_syscall_pre_setpriority(which, who, niceval)       \
+  __sanitizer_syscall_pre_impl_setpriority((long)(which), (long)(who), \
+                                           (long)(niceval))
+#define __sanitizer_syscall_post_setpriority(res, which, who, niceval)       \
+  __sanitizer_syscall_post_impl_setpriority(res, (long)(which), (long)(who), \
+                                            (long)(niceval))
+#define __sanitizer_syscall_pre_getpriority(which, who) \
+  __sanitizer_syscall_pre_impl_getpriority((long)(which), (long)(who))
+#define __sanitizer_syscall_post_getpriority(res, which, who) \
+  __sanitizer_syscall_post_impl_getpriority(res, (long)(which), (long)(who))
+#define __sanitizer_syscall_pre_shutdown(arg0, arg1) \
+  __sanitizer_syscall_pre_impl_shutdown((long)(arg0), (long)(arg1))
+#define __sanitizer_syscall_post_shutdown(res, arg0, arg1) \
+  __sanitizer_syscall_post_impl_shutdown(res, (long)(arg0), (long)(arg1))
+#define __sanitizer_syscall_pre_reboot(magic1, magic2, cmd, arg)      \
+  __sanitizer_syscall_pre_impl_reboot((long)(magic1), (long)(magic2), \
+                                      (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_post_reboot(res, magic1, magic2, cmd, arg)      \
+  __sanitizer_syscall_post_impl_reboot(res, (long)(magic1), (long)(magic2), \
+                                       (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_pre_restart_syscall() \
+  __sanitizer_syscall_pre_impl_restart_syscall()
+#define __sanitizer_syscall_post_restart_syscall(res) \
+  __sanitizer_syscall_post_impl_restart_syscall(res)
+#define __sanitizer_syscall_pre_kexec_load(entry, nr_segments, segments,      \
+                                           flags)                             \
+  __sanitizer_syscall_pre_impl_kexec_load((long)(entry), (long)(nr_segments), \
+                                          (long)(segments), (long)(flags))
+#define __sanitizer_syscall_post_kexec_load(res, entry, nr_segments, segments, \
+                                            flags)                             \
+  __sanitizer_syscall_post_impl_kexec_load(res, (long)(entry),                 \
+                                           (long)(nr_segments),                \
+                                           (long)(segments), (long)(flags))
+#define __sanitizer_syscall_pre_exit(error_code) \
+  __sanitizer_syscall_pre_impl_exit((long)(error_code))
+#define __sanitizer_syscall_post_exit(res, error_code) \
+  __sanitizer_syscall_post_impl_exit(res, (long)(error_code))
+#define __sanitizer_syscall_pre_exit_group(error_code) \
+  __sanitizer_syscall_pre_impl_exit_group((long)(error_code))
+#define __sanitizer_syscall_post_exit_group(res, error_code) \
+  __sanitizer_syscall_post_impl_exit_group(res, (long)(error_code))
+#define __sanitizer_syscall_pre_wait4(pid, stat_addr, options, ru)   \
+  __sanitizer_syscall_pre_impl_wait4((long)(pid), (long)(stat_addr), \
+                                     (long)(options), (long)(ru))
+#define __sanitizer_syscall_post_wait4(res, pid, stat_addr, options, ru)   \
+  __sanitizer_syscall_post_impl_wait4(res, (long)(pid), (long)(stat_addr), \
+                                      (long)(options), (long)(ru))
+#define __sanitizer_syscall_pre_waitid(which, pid, infop, options, ru) \
+  __sanitizer_syscall_pre_impl_waitid(                                 \
+      (long)(which), (long)(pid), (long)(infop), (long)(options), (long)(ru))
+#define __sanitizer_syscall_post_waitid(res, which, pid, infop, options, ru) \
+  __sanitizer_syscall_post_impl_waitid(res, (long)(which), (long)(pid),      \
+                                       (long)(infop), (long)(options),       \
+                                       (long)(ru))
+#define __sanitizer_syscall_pre_waitpid(pid, stat_addr, options)       \
+  __sanitizer_syscall_pre_impl_waitpid((long)(pid), (long)(stat_addr), \
+                                       (long)(options))
+#define __sanitizer_syscall_post_waitpid(res, pid, stat_addr, options)       \
+  __sanitizer_syscall_post_impl_waitpid(res, (long)(pid), (long)(stat_addr), \
+                                        (long)(options))
+#define __sanitizer_syscall_pre_set_tid_address(tidptr) \
+  __sanitizer_syscall_pre_impl_set_tid_address((long)(tidptr))
+#define __sanitizer_syscall_post_set_tid_address(res, tidptr) \
+  __sanitizer_syscall_post_impl_set_tid_address(res, (long)(tidptr))
+#define __sanitizer_syscall_pre_init_module(umod, len, uargs)         \
+  __sanitizer_syscall_pre_impl_init_module((long)(umod), (long)(len), \
+                                           (long)(uargs))
+#define __sanitizer_syscall_post_init_module(res, umod, len, uargs)         \
+  __sanitizer_syscall_post_impl_init_module(res, (long)(umod), (long)(len), \
+                                            (long)(uargs))
+#define __sanitizer_syscall_pre_delete_module(name_user, flags) \
+  __sanitizer_syscall_pre_impl_delete_module((long)(name_user), (long)(flags))
+#define __sanitizer_syscall_post_delete_module(res, name_user, flags) \
+  __sanitizer_syscall_post_impl_delete_module(res, (long)(name_user), \
+                                              (long)(flags))
+#define __sanitizer_syscall_pre_rt_sigprocmask(how, set, oset, sigsetsize) \
+  __sanitizer_syscall_pre_impl_rt_sigprocmask(                             \
+      (long)(how), (long)(set), (long)(oset), (long)(sigsetsize))
+#define __sanitizer_syscall_post_rt_sigprocmask(res, how, set, oset, \
+                                                sigsetsize)          \
+  __sanitizer_syscall_post_impl_rt_sigprocmask(                      \
+      res, (long)(how), (long)(set), (long)(oset), (long)(sigsetsize))
+#define __sanitizer_syscall_pre_rt_sigpending(set, sigsetsize) \
+  __sanitizer_syscall_pre_impl_rt_sigpending((long)(set), (long)(sigsetsize))
+#define __sanitizer_syscall_post_rt_sigpending(res, set, sigsetsize) \
+  __sanitizer_syscall_post_impl_rt_sigpending(res, (long)(set),      \
+                                              (long)(sigsetsize))
+#define __sanitizer_syscall_pre_rt_sigtimedwait(uthese, uinfo, uts, \
+                                                sigsetsize)         \
+  __sanitizer_syscall_pre_impl_rt_sigtimedwait(                     \
+      (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize))
+#define __sanitizer_syscall_post_rt_sigtimedwait(res, uthese, uinfo, uts, \
+                                                 sigsetsize)              \
+  __sanitizer_syscall_post_impl_rt_sigtimedwait(                          \
+      res, (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize))
+#define __sanitizer_syscall_pre_rt_tgsigqueueinfo(tgid, pid, sig, uinfo)    \
+  __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo((long)(tgid), (long)(pid), \
+                                                 (long)(sig), (long)(uinfo))
+#define __sanitizer_syscall_post_rt_tgsigqueueinfo(res, tgid, pid, sig, uinfo) \
+  __sanitizer_syscall_post_impl_rt_tgsigqueueinfo(                             \
+      res, (long)(tgid), (long)(pid), (long)(sig), (long)(uinfo))
+#define __sanitizer_syscall_pre_kill(pid, sig) \
+  __sanitizer_syscall_pre_impl_kill((long)(pid), (long)(sig))
+#define __sanitizer_syscall_post_kill(res, pid, sig) \
+  __sanitizer_syscall_post_impl_kill(res, (long)(pid), (long)(sig))
+#define __sanitizer_syscall_pre_tgkill(tgid, pid, sig) \
+  __sanitizer_syscall_pre_impl_tgkill((long)(tgid), (long)(pid), (long)(sig))
+#define __sanitizer_syscall_post_tgkill(res, tgid, pid, sig)           \
+  __sanitizer_syscall_post_impl_tgkill(res, (long)(tgid), (long)(pid), \
+                                       (long)(sig))
+#define __sanitizer_syscall_pre_tkill(pid, sig) \
+  __sanitizer_syscall_pre_impl_tkill((long)(pid), (long)(sig))
+#define __sanitizer_syscall_post_tkill(res, pid, sig) \
+  __sanitizer_syscall_post_impl_tkill(res, (long)(pid), (long)(sig))
+#define __sanitizer_syscall_pre_rt_sigqueueinfo(pid, sig, uinfo)         \
+  __sanitizer_syscall_pre_impl_rt_sigqueueinfo((long)(pid), (long)(sig), \
+                                               (long)(uinfo))
+#define __sanitizer_syscall_post_rt_sigqueueinfo(res, pid, sig, uinfo)         \
+  __sanitizer_syscall_post_impl_rt_sigqueueinfo(res, (long)(pid), (long)(sig), \
+                                                (long)(uinfo))
+#define __sanitizer_syscall_pre_sgetmask() \
+  __sanitizer_syscall_pre_impl_sgetmask()
+#define __sanitizer_syscall_post_sgetmask(res) \
+  __sanitizer_syscall_post_impl_sgetmask(res)
+#define __sanitizer_syscall_pre_ssetmask(newmask) \
+  __sanitizer_syscall_pre_impl_ssetmask((long)(newmask))
+#define __sanitizer_syscall_post_ssetmask(res, newmask) \
+  __sanitizer_syscall_post_impl_ssetmask(res, (long)(newmask))
+#define __sanitizer_syscall_pre_signal(sig, handler) \
+  __sanitizer_syscall_pre_impl_signal((long)(sig), (long)(handler))
+#define __sanitizer_syscall_post_signal(res, sig, handler) \
+  __sanitizer_syscall_post_impl_signal(res, (long)(sig), (long)(handler))
+#define __sanitizer_syscall_pre_pause() __sanitizer_syscall_pre_impl_pause()
+#define __sanitizer_syscall_post_pause(res) \
+  __sanitizer_syscall_post_impl_pause(res)
+#define __sanitizer_syscall_pre_sync() __sanitizer_syscall_pre_impl_sync()
+#define __sanitizer_syscall_post_sync(res) \
+  __sanitizer_syscall_post_impl_sync(res)
+#define __sanitizer_syscall_pre_fsync(fd) \
+  __sanitizer_syscall_pre_impl_fsync((long)(fd))
+#define __sanitizer_syscall_post_fsync(res, fd) \
+  __sanitizer_syscall_post_impl_fsync(res, (long)(fd))
+#define __sanitizer_syscall_pre_fdatasync(fd) \
+  __sanitizer_syscall_pre_impl_fdatasync((long)(fd))
+#define __sanitizer_syscall_post_fdatasync(res, fd) \
+  __sanitizer_syscall_post_impl_fdatasync(res, (long)(fd))
+#define __sanitizer_syscall_pre_bdflush(func, data) \
+  __sanitizer_syscall_pre_impl_bdflush((long)(func), (long)(data))
+#define __sanitizer_syscall_post_bdflush(res, func, data) \
+  __sanitizer_syscall_post_impl_bdflush(res, (long)(func), (long)(data))
+#define __sanitizer_syscall_pre_mount(dev_name, dir_name, type, flags, data) \
+  __sanitizer_syscall_pre_impl_mount((long)(dev_name), (long)(dir_name),     \
+                                     (long)(type), (long)(flags),            \
+                                     (long)(data))
+#define __sanitizer_syscall_post_mount(res, dev_name, dir_name, type, flags,   \
+                                       data)                                   \
+  __sanitizer_syscall_post_impl_mount(res, (long)(dev_name), (long)(dir_name), \
+                                      (long)(type), (long)(flags),             \
+                                      (long)(data))
+#define __sanitizer_syscall_pre_umount(name, flags) \
+  __sanitizer_syscall_pre_impl_umount((long)(name), (long)(flags))
+#define __sanitizer_syscall_post_umount(res, name, flags) \
+  __sanitizer_syscall_post_impl_umount(res, (long)(name), (long)(flags))
+#define __sanitizer_syscall_pre_oldumount(name) \
+  __sanitizer_syscall_pre_impl_oldumount((long)(name))
+#define __sanitizer_syscall_post_oldumount(res, name) \
+  __sanitizer_syscall_post_impl_oldumount(res, (long)(name))
+#define __sanitizer_syscall_pre_truncate(path, length) \
+  __sanitizer_syscall_pre_impl_truncate((long)(path), (long)(length))
+#define __sanitizer_syscall_post_truncate(res, path, length) \
+  __sanitizer_syscall_post_impl_truncate(res, (long)(path), (long)(length))
+#define __sanitizer_syscall_pre_ftruncate(fd, length) \
+  __sanitizer_syscall_pre_impl_ftruncate((long)(fd), (long)(length))
+#define __sanitizer_syscall_post_ftruncate(res, fd, length) \
+  __sanitizer_syscall_post_impl_ftruncate(res, (long)(fd), (long)(length))
+#define __sanitizer_syscall_pre_stat(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_stat((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_stat(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_stat(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_statfs(path, buf) \
+  __sanitizer_syscall_pre_impl_statfs((long)(path), (long)(buf))
+#define __sanitizer_syscall_post_statfs(res, path, buf) \
+  __sanitizer_syscall_post_impl_statfs(res, (long)(path), (long)(buf))
+#define __sanitizer_syscall_pre_statfs64(path, sz, buf) \
+  __sanitizer_syscall_pre_impl_statfs64((long)(path), (long)(sz), (long)(buf))
+#define __sanitizer_syscall_post_statfs64(res, path, sz, buf)           \
+  __sanitizer_syscall_post_impl_statfs64(res, (long)(path), (long)(sz), \
+                                         (long)(buf))
+#define __sanitizer_syscall_pre_fstatfs(fd, buf) \
+  __sanitizer_syscall_pre_impl_fstatfs((long)(fd), (long)(buf))
+#define __sanitizer_syscall_post_fstatfs(res, fd, buf) \
+  __sanitizer_syscall_post_impl_fstatfs(res, (long)(fd), (long)(buf))
+#define __sanitizer_syscall_pre_fstatfs64(fd, sz, buf) \
+  __sanitizer_syscall_pre_impl_fstatfs64((long)(fd), (long)(sz), (long)(buf))
+#define __sanitizer_syscall_post_fstatfs64(res, fd, sz, buf)           \
+  __sanitizer_syscall_post_impl_fstatfs64(res, (long)(fd), (long)(sz), \
+                                          (long)(buf))
+#define __sanitizer_syscall_pre_lstat(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_lstat((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_lstat(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_lstat(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_fstat(fd, statbuf) \
+  __sanitizer_syscall_pre_impl_fstat((long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_post_fstat(res, fd, statbuf) \
+  __sanitizer_syscall_post_impl_fstat(res, (long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_pre_newstat(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_newstat((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_newstat(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_newstat(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_newlstat(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_newlstat((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_newlstat(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_newlstat(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_newfstat(fd, statbuf) \
+  __sanitizer_syscall_pre_impl_newfstat((long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_post_newfstat(res, fd, statbuf) \
+  __sanitizer_syscall_post_impl_newfstat(res, (long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_pre_ustat(dev, ubuf) \
+  __sanitizer_syscall_pre_impl_ustat((long)(dev), (long)(ubuf))
+#define __sanitizer_syscall_post_ustat(res, dev, ubuf) \
+  __sanitizer_syscall_post_impl_ustat(res, (long)(dev), (long)(ubuf))
+#define __sanitizer_syscall_pre_stat64(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_stat64((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_stat64(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_stat64(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_fstat64(fd, statbuf) \
+  __sanitizer_syscall_pre_impl_fstat64((long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_post_fstat64(res, fd, statbuf) \
+  __sanitizer_syscall_post_impl_fstat64(res, (long)(fd), (long)(statbuf))
+#define __sanitizer_syscall_pre_lstat64(filename, statbuf) \
+  __sanitizer_syscall_pre_impl_lstat64((long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_post_lstat64(res, filename, statbuf) \
+  __sanitizer_syscall_post_impl_lstat64(res, (long)(filename), (long)(statbuf))
+#define __sanitizer_syscall_pre_setxattr(path, name, value, size, flags) \
+  __sanitizer_syscall_pre_impl_setxattr(                                 \
+      (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags))
+#define __sanitizer_syscall_post_setxattr(res, path, name, value, size, flags) \
+  __sanitizer_syscall_post_impl_setxattr(res, (long)(path), (long)(name),      \
+                                         (long)(value), (long)(size),          \
+                                         (long)(flags))
+#define __sanitizer_syscall_pre_lsetxattr(path, name, value, size, flags) \
+  __sanitizer_syscall_pre_impl_lsetxattr(                                 \
+      (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags))
+#define __sanitizer_syscall_post_lsetxattr(res, path, name, value, size,   \
+                                           flags)                          \
+  __sanitizer_syscall_post_impl_lsetxattr(res, (long)(path), (long)(name), \
+                                          (long)(value), (long)(size),     \
+                                          (long)(flags))
+#define __sanitizer_syscall_pre_fsetxattr(fd, name, value, size, flags) \
+  __sanitizer_syscall_pre_impl_fsetxattr(                               \
+      (long)(fd), (long)(name), (long)(value), (long)(size), (long)(flags))
+#define __sanitizer_syscall_post_fsetxattr(res, fd, name, value, size, flags) \
+  __sanitizer_syscall_post_impl_fsetxattr(res, (long)(fd), (long)(name),      \
+                                          (long)(value), (long)(size),        \
+                                          (long)(flags))
+#define __sanitizer_syscall_pre_getxattr(path, name, value, size)   \
+  __sanitizer_syscall_pre_impl_getxattr((long)(path), (long)(name), \
+                                        (long)(value), (long)(size))
+#define __sanitizer_syscall_post_getxattr(res, path, name, value, size)   \
+  __sanitizer_syscall_post_impl_getxattr(res, (long)(path), (long)(name), \
+                                         (long)(value), (long)(size))
+#define __sanitizer_syscall_pre_lgetxattr(path, name, value, size)   \
+  __sanitizer_syscall_pre_impl_lgetxattr((long)(path), (long)(name), \
+                                         (long)(value), (long)(size))
+#define __sanitizer_syscall_post_lgetxattr(res, path, name, value, size)   \
+  __sanitizer_syscall_post_impl_lgetxattr(res, (long)(path), (long)(name), \
+                                          (long)(value), (long)(size))
+#define __sanitizer_syscall_pre_fgetxattr(fd, name, value, size)   \
+  __sanitizer_syscall_pre_impl_fgetxattr((long)(fd), (long)(name), \
+                                         (long)(value), (long)(size))
+#define __sanitizer_syscall_post_fgetxattr(res, fd, name, value, size)   \
+  __sanitizer_syscall_post_impl_fgetxattr(res, (long)(fd), (long)(name), \
+                                          (long)(value), (long)(size))
+#define __sanitizer_syscall_pre_listxattr(path, list, size)          \
+  __sanitizer_syscall_pre_impl_listxattr((long)(path), (long)(list), \
+                                         (long)(size))
+#define __sanitizer_syscall_post_listxattr(res, path, list, size)          \
+  __sanitizer_syscall_post_impl_listxattr(res, (long)(path), (long)(list), \
+                                          (long)(size))
+#define __sanitizer_syscall_pre_llistxattr(path, list, size)          \
+  __sanitizer_syscall_pre_impl_llistxattr((long)(path), (long)(list), \
+                                          (long)(size))
+#define __sanitizer_syscall_post_llistxattr(res, path, list, size)          \
+  __sanitizer_syscall_post_impl_llistxattr(res, (long)(path), (long)(list), \
+                                           (long)(size))
+#define __sanitizer_syscall_pre_flistxattr(fd, list, size)          \
+  __sanitizer_syscall_pre_impl_flistxattr((long)(fd), (long)(list), \
+                                          (long)(size))
+#define __sanitizer_syscall_post_flistxattr(res, fd, list, size)          \
+  __sanitizer_syscall_post_impl_flistxattr(res, (long)(fd), (long)(list), \
+                                           (long)(size))
+#define __sanitizer_syscall_pre_removexattr(path, name) \
+  __sanitizer_syscall_pre_impl_removexattr((long)(path), (long)(name))
+#define __sanitizer_syscall_post_removexattr(res, path, name) \
+  __sanitizer_syscall_post_impl_removexattr(res, (long)(path), (long)(name))
+#define __sanitizer_syscall_pre_lremovexattr(path, name) \
+  __sanitizer_syscall_pre_impl_lremovexattr((long)(path), (long)(name))
+#define __sanitizer_syscall_post_lremovexattr(res, path, name) \
+  __sanitizer_syscall_post_impl_lremovexattr(res, (long)(path), (long)(name))
+#define __sanitizer_syscall_pre_fremovexattr(fd, name) \
+  __sanitizer_syscall_pre_impl_fremovexattr((long)(fd), (long)(name))
+#define __sanitizer_syscall_post_fremovexattr(res, fd, name) \
+  __sanitizer_syscall_post_impl_fremovexattr(res, (long)(fd), (long)(name))
+#define __sanitizer_syscall_pre_brk(brk) \
+  __sanitizer_syscall_pre_impl_brk((long)(brk))
+#define __sanitizer_syscall_post_brk(res, brk) \
+  __sanitizer_syscall_post_impl_brk(res, (long)(brk))
+#define __sanitizer_syscall_pre_mprotect(start, len, prot)          \
+  __sanitizer_syscall_pre_impl_mprotect((long)(start), (long)(len), \
+                                        (long)(prot))
+#define __sanitizer_syscall_post_mprotect(res, start, len, prot)          \
+  __sanitizer_syscall_post_impl_mprotect(res, (long)(start), (long)(len), \
+                                         (long)(prot))
+#define __sanitizer_syscall_pre_mremap(addr, old_len, new_len, flags, \
+                                       new_addr)                      \
+  __sanitizer_syscall_pre_impl_mremap((long)(addr), (long)(old_len),  \
+                                      (long)(new_len), (long)(flags), \
+                                      (long)(new_addr))
+#define __sanitizer_syscall_post_mremap(res, addr, old_len, new_len, flags, \
+                                        new_addr)                           \
+  __sanitizer_syscall_post_impl_mremap(res, (long)(addr), (long)(old_len),  \
+                                       (long)(new_len), (long)(flags),      \
+                                       (long)(new_addr))
+#define __sanitizer_syscall_pre_remap_file_pages(start, size, prot, pgoff, \
+                                                 flags)                    \
+  __sanitizer_syscall_pre_impl_remap_file_pages(                           \
+      (long)(start), (long)(size), (long)(prot), (long)(pgoff), (long)(flags))
+#define __sanitizer_syscall_post_remap_file_pages(res, start, size, prot,    \
+                                                  pgoff, flags)              \
+  __sanitizer_syscall_post_impl_remap_file_pages(res, (long)(start),         \
+                                                 (long)(size), (long)(prot), \
+                                                 (long)(pgoff), (long)(flags))
+#define __sanitizer_syscall_pre_msync(start, len, flags) \
+  __sanitizer_syscall_pre_impl_msync((long)(start), (long)(len), (long)(flags))
+#define __sanitizer_syscall_post_msync(res, start, len, flags)         \
+  __sanitizer_syscall_post_impl_msync(res, (long)(start), (long)(len), \
+                                      (long)(flags))
+#define __sanitizer_syscall_pre_munmap(addr, len) \
+  __sanitizer_syscall_pre_impl_munmap((long)(addr), (long)(len))
+#define __sanitizer_syscall_post_munmap(res, addr, len) \
+  __sanitizer_syscall_post_impl_munmap(res, (long)(addr), (long)(len))
+#define __sanitizer_syscall_pre_mlock(start, len) \
+  __sanitizer_syscall_pre_impl_mlock((long)(start), (long)(len))
+#define __sanitizer_syscall_post_mlock(res, start, len) \
+  __sanitizer_syscall_post_impl_mlock(res, (long)(start), (long)(len))
+#define __sanitizer_syscall_pre_munlock(start, len) \
+  __sanitizer_syscall_pre_impl_munlock((long)(start), (long)(len))
+#define __sanitizer_syscall_post_munlock(res, start, len) \
+  __sanitizer_syscall_post_impl_munlock(res, (long)(start), (long)(len))
+#define __sanitizer_syscall_pre_mlockall(flags) \
+  __sanitizer_syscall_pre_impl_mlockall((long)(flags))
+#define __sanitizer_syscall_post_mlockall(res, flags) \
+  __sanitizer_syscall_post_impl_mlockall(res, (long)(flags))
+#define __sanitizer_syscall_pre_munlockall() \
+  __sanitizer_syscall_pre_impl_munlockall()
+#define __sanitizer_syscall_post_munlockall(res) \
+  __sanitizer_syscall_post_impl_munlockall(res)
+#define __sanitizer_syscall_pre_madvise(start, len, behavior)      \
+  __sanitizer_syscall_pre_impl_madvise((long)(start), (long)(len), \
+                                       (long)(behavior))
+#define __sanitizer_syscall_post_madvise(res, start, len, behavior)      \
+  __sanitizer_syscall_post_impl_madvise(res, (long)(start), (long)(len), \
+                                        (long)(behavior))
+#define __sanitizer_syscall_pre_mincore(start, len, vec) \
+  __sanitizer_syscall_pre_impl_mincore((long)(start), (long)(len), (long)(vec))
+#define __sanitizer_syscall_post_mincore(res, start, len, vec)           \
+  __sanitizer_syscall_post_impl_mincore(res, (long)(start), (long)(len), \
+                                        (long)(vec))
+#define __sanitizer_syscall_pre_pivot_root(new_root, put_old) \
+  __sanitizer_syscall_pre_impl_pivot_root((long)(new_root), (long)(put_old))
+#define __sanitizer_syscall_post_pivot_root(res, new_root, put_old) \
+  __sanitizer_syscall_post_impl_pivot_root(res, (long)(new_root),   \
+                                           (long)(put_old))
+#define __sanitizer_syscall_pre_chroot(filename) \
+  __sanitizer_syscall_pre_impl_chroot((long)(filename))
+#define __sanitizer_syscall_post_chroot(res, filename) \
+  __sanitizer_syscall_post_impl_chroot(res, (long)(filename))
+#define __sanitizer_syscall_pre_mknod(filename, mode, dev)           \
+  __sanitizer_syscall_pre_impl_mknod((long)(filename), (long)(mode), \
+                                     (long)(dev))
+#define __sanitizer_syscall_post_mknod(res, filename, mode, dev)           \
+  __sanitizer_syscall_post_impl_mknod(res, (long)(filename), (long)(mode), \
+                                      (long)(dev))
+#define __sanitizer_syscall_pre_link(oldname, newname) \
+  __sanitizer_syscall_pre_impl_link((long)(oldname), (long)(newname))
+#define __sanitizer_syscall_post_link(res, oldname, newname) \
+  __sanitizer_syscall_post_impl_link(res, (long)(oldname), (long)(newname))
+#define __sanitizer_syscall_pre_symlink(old, new_) \
+  __sanitizer_syscall_pre_impl_symlink((long)(old), (long)(new_))
+#define __sanitizer_syscall_post_symlink(res, old, new_) \
+  __sanitizer_syscall_post_impl_symlink(res, (long)(old), (long)(new_))
+#define __sanitizer_syscall_pre_unlink(pathname) \
+  __sanitizer_syscall_pre_impl_unlink((long)(pathname))
+#define __sanitizer_syscall_post_unlink(res, pathname) \
+  __sanitizer_syscall_post_impl_unlink(res, (long)(pathname))
+#define __sanitizer_syscall_pre_rename(oldname, newname) \
+  __sanitizer_syscall_pre_impl_rename((long)(oldname), (long)(newname))
+#define __sanitizer_syscall_post_rename(res, oldname, newname) \
+  __sanitizer_syscall_post_impl_rename(res, (long)(oldname), (long)(newname))
+#define __sanitizer_syscall_pre_chmod(filename, mode) \
+  __sanitizer_syscall_pre_impl_chmod((long)(filename), (long)(mode))
+#define __sanitizer_syscall_post_chmod(res, filename, mode) \
+  __sanitizer_syscall_post_impl_chmod(res, (long)(filename), (long)(mode))
+#define __sanitizer_syscall_pre_fchmod(fd, mode) \
+  __sanitizer_syscall_pre_impl_fchmod((long)(fd), (long)(mode))
+#define __sanitizer_syscall_post_fchmod(res, fd, mode) \
+  __sanitizer_syscall_post_impl_fchmod(res, (long)(fd), (long)(mode))
+#define __sanitizer_syscall_pre_fcntl(fd, cmd, arg) \
+  __sanitizer_syscall_pre_impl_fcntl((long)(fd), (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_post_fcntl(res, fd, cmd, arg) \
+  __sanitizer_syscall_post_impl_fcntl(res, (long)(fd), (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_pre_fcntl64(fd, cmd, arg) \
+  __sanitizer_syscall_pre_impl_fcntl64((long)(fd), (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_post_fcntl64(res, fd, cmd, arg)           \
+  __sanitizer_syscall_post_impl_fcntl64(res, (long)(fd), (long)(cmd), \
+                                        (long)(arg))
+#define __sanitizer_syscall_pre_pipe(fildes) \
+  __sanitizer_syscall_pre_impl_pipe((long)(fildes))
+#define __sanitizer_syscall_post_pipe(res, fildes) \
+  __sanitizer_syscall_post_impl_pipe(res, (long)(fildes))
+#define __sanitizer_syscall_pre_pipe2(fildes, flags) \
+  __sanitizer_syscall_pre_impl_pipe2((long)(fildes), (long)(flags))
+#define __sanitizer_syscall_post_pipe2(res, fildes, flags) \
+  __sanitizer_syscall_post_impl_pipe2(res, (long)(fildes), (long)(flags))
+#define __sanitizer_syscall_pre_dup(fildes) \
+  __sanitizer_syscall_pre_impl_dup((long)(fildes))
+#define __sanitizer_syscall_post_dup(res, fildes) \
+  __sanitizer_syscall_post_impl_dup(res, (long)(fildes))
+#define __sanitizer_syscall_pre_dup2(oldfd, newfd) \
+  __sanitizer_syscall_pre_impl_dup2((long)(oldfd), (long)(newfd))
+#define __sanitizer_syscall_post_dup2(res, oldfd, newfd) \
+  __sanitizer_syscall_post_impl_dup2(res, (long)(oldfd), (long)(newfd))
+#define __sanitizer_syscall_pre_dup3(oldfd, newfd, flags) \
+  __sanitizer_syscall_pre_impl_dup3((long)(oldfd), (long)(newfd), (long)(flags))
+#define __sanitizer_syscall_post_dup3(res, oldfd, newfd, flags)         \
+  __sanitizer_syscall_post_impl_dup3(res, (long)(oldfd), (long)(newfd), \
+                                     (long)(flags))
+#define __sanitizer_syscall_pre_ioperm(from, num, on) \
+  __sanitizer_syscall_pre_impl_ioperm((long)(from), (long)(num), (long)(on))
+#define __sanitizer_syscall_post_ioperm(res, from, num, on)            \
+  __sanitizer_syscall_post_impl_ioperm(res, (long)(from), (long)(num), \
+                                       (long)(on))
+#define __sanitizer_syscall_pre_ioctl(fd, cmd, arg) \
+  __sanitizer_syscall_pre_impl_ioctl((long)(fd), (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_post_ioctl(res, fd, cmd, arg) \
+  __sanitizer_syscall_post_impl_ioctl(res, (long)(fd), (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_pre_flock(fd, cmd) \
+  __sanitizer_syscall_pre_impl_flock((long)(fd), (long)(cmd))
+#define __sanitizer_syscall_post_flock(res, fd, cmd) \
+  __sanitizer_syscall_post_impl_flock(res, (long)(fd), (long)(cmd))
+#define __sanitizer_syscall_pre_io_setup(nr_reqs, ctx) \
+  __sanitizer_syscall_pre_impl_io_setup((long)(nr_reqs), (long)(ctx))
+#define __sanitizer_syscall_post_io_setup(res, nr_reqs, ctx) \
+  __sanitizer_syscall_post_impl_io_setup(res, (long)(nr_reqs), (long)(ctx))
+#define __sanitizer_syscall_pre_io_destroy(ctx) \
+  __sanitizer_syscall_pre_impl_io_destroy((long)(ctx))
+#define __sanitizer_syscall_post_io_destroy(res, ctx) \
+  __sanitizer_syscall_post_impl_io_destroy(res, (long)(ctx))
+#define __sanitizer_syscall_pre_io_getevents(ctx_id, min_nr, nr, events,    \
+                                             timeout)                       \
+  __sanitizer_syscall_pre_impl_io_getevents((long)(ctx_id), (long)(min_nr), \
+                                            (long)(nr), (long)(events),     \
+                                            (long)(timeout))
+#define __sanitizer_syscall_post_io_getevents(res, ctx_id, min_nr, nr, events, \
+                                              timeout)                         \
+  __sanitizer_syscall_post_impl_io_getevents(res, (long)(ctx_id),              \
+                                             (long)(min_nr), (long)(nr),       \
+                                             (long)(events), (long)(timeout))
+#define __sanitizer_syscall_pre_io_submit(ctx_id, arg1, arg2)          \
+  __sanitizer_syscall_pre_impl_io_submit((long)(ctx_id), (long)(arg1), \
+                                         (long)(arg2))
+#define __sanitizer_syscall_post_io_submit(res, ctx_id, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_io_submit(res, (long)(ctx_id), (long)(arg1), \
+                                          (long)(arg2))
+#define __sanitizer_syscall_pre_io_cancel(ctx_id, iocb, result)        \
+  __sanitizer_syscall_pre_impl_io_cancel((long)(ctx_id), (long)(iocb), \
+                                         (long)(result))
+#define __sanitizer_syscall_post_io_cancel(res, ctx_id, iocb, result)        \
+  __sanitizer_syscall_post_impl_io_cancel(res, (long)(ctx_id), (long)(iocb), \
+                                          (long)(result))
+#define __sanitizer_syscall_pre_sendfile(out_fd, in_fd, offset, count) \
+  __sanitizer_syscall_pre_impl_sendfile((long)(out_fd), (long)(in_fd), \
+                                        (long)(offset), (long)(count))
+#define __sanitizer_syscall_post_sendfile(res, out_fd, in_fd, offset, count) \
+  __sanitizer_syscall_post_impl_sendfile(res, (long)(out_fd), (long)(in_fd), \
+                                         (long)(offset), (long)(count))
+#define __sanitizer_syscall_pre_sendfile64(out_fd, in_fd, offset, count) \
+  __sanitizer_syscall_pre_impl_sendfile64((long)(out_fd), (long)(in_fd), \
+                                          (long)(offset), (long)(count))
+#define __sanitizer_syscall_post_sendfile64(res, out_fd, in_fd, offset, count) \
+  __sanitizer_syscall_post_impl_sendfile64(res, (long)(out_fd), (long)(in_fd), \
+                                           (long)(offset), (long)(count))
+#define __sanitizer_syscall_pre_readlink(path, buf, bufsiz)        \
+  __sanitizer_syscall_pre_impl_readlink((long)(path), (long)(buf), \
+                                        (long)(bufsiz))
+#define __sanitizer_syscall_post_readlink(res, path, buf, bufsiz)        \
+  __sanitizer_syscall_post_impl_readlink(res, (long)(path), (long)(buf), \
+                                         (long)(bufsiz))
+#define __sanitizer_syscall_pre_creat(pathname, mode) \
+  __sanitizer_syscall_pre_impl_creat((long)(pathname), (long)(mode))
+#define __sanitizer_syscall_post_creat(res, pathname, mode) \
+  __sanitizer_syscall_post_impl_creat(res, (long)(pathname), (long)(mode))
+#define __sanitizer_syscall_pre_open(filename, flags, mode)          \
+  __sanitizer_syscall_pre_impl_open((long)(filename), (long)(flags), \
+                                    (long)(mode))
+#define __sanitizer_syscall_post_open(res, filename, flags, mode)          \
+  __sanitizer_syscall_post_impl_open(res, (long)(filename), (long)(flags), \
+                                     (long)(mode))
+#define __sanitizer_syscall_pre_close(fd) \
+  __sanitizer_syscall_pre_impl_close((long)(fd))
+#define __sanitizer_syscall_post_close(res, fd) \
+  __sanitizer_syscall_post_impl_close(res, (long)(fd))
+#define __sanitizer_syscall_pre_access(filename, mode) \
+  __sanitizer_syscall_pre_impl_access((long)(filename), (long)(mode))
+#define __sanitizer_syscall_post_access(res, filename, mode) \
+  __sanitizer_syscall_post_impl_access(res, (long)(filename), (long)(mode))
+#define __sanitizer_syscall_pre_vhangup() __sanitizer_syscall_pre_impl_vhangup()
+#define __sanitizer_syscall_post_vhangup(res) \
+  __sanitizer_syscall_post_impl_vhangup(res)
+#define __sanitizer_syscall_pre_chown(filename, user, group)         \
+  __sanitizer_syscall_pre_impl_chown((long)(filename), (long)(user), \
+                                     (long)(group))
+#define __sanitizer_syscall_post_chown(res, filename, user, group)         \
+  __sanitizer_syscall_post_impl_chown(res, (long)(filename), (long)(user), \
+                                      (long)(group))
+#define __sanitizer_syscall_pre_lchown(filename, user, group)         \
+  __sanitizer_syscall_pre_impl_lchown((long)(filename), (long)(user), \
+                                      (long)(group))
+#define __sanitizer_syscall_post_lchown(res, filename, user, group)         \
+  __sanitizer_syscall_post_impl_lchown(res, (long)(filename), (long)(user), \
+                                       (long)(group))
+#define __sanitizer_syscall_pre_fchown(fd, user, group) \
+  __sanitizer_syscall_pre_impl_fchown((long)(fd), (long)(user), (long)(group))
+#define __sanitizer_syscall_post_fchown(res, fd, user, group)         \
+  __sanitizer_syscall_post_impl_fchown(res, (long)(fd), (long)(user), \
+                                       (long)(group))
+#define __sanitizer_syscall_pre_chown16(filename, user, group)       \
+  __sanitizer_syscall_pre_impl_chown16((long)(filename), (long)user, \
+                                       (long)group)
+#define __sanitizer_syscall_post_chown16(res, filename, user, group)       \
+  __sanitizer_syscall_post_impl_chown16(res, (long)(filename), (long)user, \
+                                        (long)group)
+#define __sanitizer_syscall_pre_lchown16(filename, user, group)       \
+  __sanitizer_syscall_pre_impl_lchown16((long)(filename), (long)user, \
+                                        (long)group)
+#define __sanitizer_syscall_post_lchown16(res, filename, user, group)       \
+  __sanitizer_syscall_post_impl_lchown16(res, (long)(filename), (long)user, \
+                                         (long)group)
+#define __sanitizer_syscall_pre_fchown16(fd, user, group) \
+  __sanitizer_syscall_pre_impl_fchown16((long)(fd), (long)user, (long)group)
+#define __sanitizer_syscall_post_fchown16(res, fd, user, group)       \
+  __sanitizer_syscall_post_impl_fchown16(res, (long)(fd), (long)user, \
+                                         (long)group)
+#define __sanitizer_syscall_pre_setregid16(rgid, egid) \
+  __sanitizer_syscall_pre_impl_setregid16((long)rgid, (long)egid)
+#define __sanitizer_syscall_post_setregid16(res, rgid, egid) \
+  __sanitizer_syscall_post_impl_setregid16(res, (long)rgid, (long)egid)
+#define __sanitizer_syscall_pre_setgid16(gid) \
+  __sanitizer_syscall_pre_impl_setgid16((long)gid)
+#define __sanitizer_syscall_post_setgid16(res, gid) \
+  __sanitizer_syscall_post_impl_setgid16(res, (long)gid)
+#define __sanitizer_syscall_pre_setreuid16(ruid, euid) \
+  __sanitizer_syscall_pre_impl_setreuid16((long)ruid, (long)euid)
+#define __sanitizer_syscall_post_setreuid16(res, ruid, euid) \
+  __sanitizer_syscall_post_impl_setreuid16(res, (long)ruid, (long)euid)
+#define __sanitizer_syscall_pre_setuid16(uid) \
+  __sanitizer_syscall_pre_impl_setuid16((long)uid)
+#define __sanitizer_syscall_post_setuid16(res, uid) \
+  __sanitizer_syscall_post_impl_setuid16(res, (long)uid)
+#define __sanitizer_syscall_pre_setresuid16(ruid, euid, suid) \
+  __sanitizer_syscall_pre_impl_setresuid16((long)ruid, (long)euid, (long)suid)
+#define __sanitizer_syscall_post_setresuid16(res, ruid, euid, suid)      \
+  __sanitizer_syscall_post_impl_setresuid16(res, (long)ruid, (long)euid, \
+                                            (long)suid)
+#define __sanitizer_syscall_pre_getresuid16(ruid, euid, suid)          \
+  __sanitizer_syscall_pre_impl_getresuid16((long)(ruid), (long)(euid), \
+                                           (long)(suid))
+#define __sanitizer_syscall_post_getresuid16(res, ruid, euid, suid)          \
+  __sanitizer_syscall_post_impl_getresuid16(res, (long)(ruid), (long)(euid), \
+                                            (long)(suid))
+#define __sanitizer_syscall_pre_setresgid16(rgid, egid, sgid) \
+  __sanitizer_syscall_pre_impl_setresgid16((long)rgid, (long)egid, (long)sgid)
+#define __sanitizer_syscall_post_setresgid16(res, rgid, egid, sgid)      \
+  __sanitizer_syscall_post_impl_setresgid16(res, (long)rgid, (long)egid, \
+                                            (long)sgid)
+#define __sanitizer_syscall_pre_getresgid16(rgid, egid, sgid)          \
+  __sanitizer_syscall_pre_impl_getresgid16((long)(rgid), (long)(egid), \
+                                           (long)(sgid))
+#define __sanitizer_syscall_post_getresgid16(res, rgid, egid, sgid)          \
+  __sanitizer_syscall_post_impl_getresgid16(res, (long)(rgid), (long)(egid), \
+                                            (long)(sgid))
+#define __sanitizer_syscall_pre_setfsuid16(uid) \
+  __sanitizer_syscall_pre_impl_setfsuid16((long)uid)
+#define __sanitizer_syscall_post_setfsuid16(res, uid) \
+  __sanitizer_syscall_post_impl_setfsuid16(res, (long)uid)
+#define __sanitizer_syscall_pre_setfsgid16(gid) \
+  __sanitizer_syscall_pre_impl_setfsgid16((long)gid)
+#define __sanitizer_syscall_post_setfsgid16(res, gid) \
+  __sanitizer_syscall_post_impl_setfsgid16(res, (long)gid)
+#define __sanitizer_syscall_pre_getgroups16(gidsetsize, grouplist) \
+  __sanitizer_syscall_pre_impl_getgroups16((long)(gidsetsize),     \
+                                           (long)(grouplist))
+#define __sanitizer_syscall_post_getgroups16(res, gidsetsize, grouplist) \
+  __sanitizer_syscall_post_impl_getgroups16(res, (long)(gidsetsize),     \
+                                            (long)(grouplist))
+#define __sanitizer_syscall_pre_setgroups16(gidsetsize, grouplist) \
+  __sanitizer_syscall_pre_impl_setgroups16((long)(gidsetsize),     \
+                                           (long)(grouplist))
+#define __sanitizer_syscall_post_setgroups16(res, gidsetsize, grouplist) \
+  __sanitizer_syscall_post_impl_setgroups16(res, (long)(gidsetsize),     \
+                                            (long)(grouplist))
+#define __sanitizer_syscall_pre_getuid16() \
+  __sanitizer_syscall_pre_impl_getuid16()
+#define __sanitizer_syscall_post_getuid16(res) \
+  __sanitizer_syscall_post_impl_getuid16(res)
+#define __sanitizer_syscall_pre_geteuid16() \
+  __sanitizer_syscall_pre_impl_geteuid16()
+#define __sanitizer_syscall_post_geteuid16(res) \
+  __sanitizer_syscall_post_impl_geteuid16(res)
+#define __sanitizer_syscall_pre_getgid16() \
+  __sanitizer_syscall_pre_impl_getgid16()
+#define __sanitizer_syscall_post_getgid16(res) \
+  __sanitizer_syscall_post_impl_getgid16(res)
+#define __sanitizer_syscall_pre_getegid16() \
+  __sanitizer_syscall_pre_impl_getegid16()
+#define __sanitizer_syscall_post_getegid16(res) \
+  __sanitizer_syscall_post_impl_getegid16(res)
+#define __sanitizer_syscall_pre_utime(filename, times) \
+  __sanitizer_syscall_pre_impl_utime((long)(filename), (long)(times))
+#define __sanitizer_syscall_post_utime(res, filename, times) \
+  __sanitizer_syscall_post_impl_utime(res, (long)(filename), (long)(times))
+#define __sanitizer_syscall_pre_utimes(filename, utimes) \
+  __sanitizer_syscall_pre_impl_utimes((long)(filename), (long)(utimes))
+#define __sanitizer_syscall_post_utimes(res, filename, utimes) \
+  __sanitizer_syscall_post_impl_utimes(res, (long)(filename), (long)(utimes))
+#define __sanitizer_syscall_pre_lseek(fd, offset, origin) \
+  __sanitizer_syscall_pre_impl_lseek((long)(fd), (long)(offset), (long)(origin))
+#define __sanitizer_syscall_post_lseek(res, fd, offset, origin)        \
+  __sanitizer_syscall_post_impl_lseek(res, (long)(fd), (long)(offset), \
+                                      (long)(origin))
+#define __sanitizer_syscall_pre_llseek(fd, offset_high, offset_low, result, \
+                                       origin)                              \
+  __sanitizer_syscall_pre_impl_llseek((long)(fd), (long)(offset_high),      \
+                                      (long)(offset_low), (long)(result),   \
+                                      (long)(origin))
+#define __sanitizer_syscall_post_llseek(res, fd, offset_high, offset_low,    \
+                                        result, origin)                      \
+  __sanitizer_syscall_post_impl_llseek(res, (long)(fd), (long)(offset_high), \
+                                       (long)(offset_low), (long)(result),   \
+                                       (long)(origin))
+#define __sanitizer_syscall_pre_read(fd, buf, count) \
+  __sanitizer_syscall_pre_impl_read((long)(fd), (long)(buf), (long)(count))
+#define __sanitizer_syscall_post_read(res, fd, buf, count)         \
+  __sanitizer_syscall_post_impl_read(res, (long)(fd), (long)(buf), \
+                                     (long)(count))
+#define __sanitizer_syscall_pre_readv(fd, vec, vlen) \
+  __sanitizer_syscall_pre_impl_readv((long)(fd), (long)(vec), (long)(vlen))
+#define __sanitizer_syscall_post_readv(res, fd, vec, vlen)          \
+  __sanitizer_syscall_post_impl_readv(res, (long)(fd), (long)(vec), \
+                                      (long)(vlen))
+#define __sanitizer_syscall_pre_write(fd, buf, count) \
+  __sanitizer_syscall_pre_impl_write((long)(fd), (long)(buf), (long)(count))
+#define __sanitizer_syscall_post_write(res, fd, buf, count)         \
+  __sanitizer_syscall_post_impl_write(res, (long)(fd), (long)(buf), \
+                                      (long)(count))
+#define __sanitizer_syscall_pre_writev(fd, vec, vlen) \
+  __sanitizer_syscall_pre_impl_writev((long)(fd), (long)(vec), (long)(vlen))
+#define __sanitizer_syscall_post_writev(res, fd, vec, vlen)          \
+  __sanitizer_syscall_post_impl_writev(res, (long)(fd), (long)(vec), \
+                                       (long)(vlen))
+
+#ifdef _LP64
+#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos)                   \
+  __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \
+                                       (long)(pos))
+#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos)    \
+  __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf), \
+                                        (long)(count), (long)(pos))
+#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos)    \
+  __sanitizer_syscall_pre_impl_pwrite64((long)(fd), (long)(buf), \
+                                        (long)(count), (long)(pos))
+#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos)    \
+  __sanitizer_syscall_post_impl_pwrite64(res, (long)(fd), (long)(buf), \
+                                         (long)(count), (long)(pos))
+#else
+#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos0, pos1)            \
+  __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \
+                                       (long)(pos0), (long)(pos1))
+#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos0, pos1) \
+  __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf),     \
+                                        (long)(count), (long)(pos0), \
+                                        (long)(pos1))
+#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos0, pos1) \
+  __sanitizer_syscall_pre_impl_pwrite64(                             \
+      (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1))
+#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos0, pos1) \
+  __sanitizer_syscall_post_impl_pwrite64(                                  \
+      res, (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1))
+#endif
+
+#define __sanitizer_syscall_pre_preadv(fd, vec, vlen, pos_l, pos_h)          \
+  __sanitizer_syscall_pre_impl_preadv((long)(fd), (long)(vec), (long)(vlen), \
+                                      (long)(pos_l), (long)(pos_h))
+#define __sanitizer_syscall_post_preadv(res, fd, vec, vlen, pos_l, pos_h) \
+  __sanitizer_syscall_post_impl_preadv(res, (long)(fd), (long)(vec),      \
+                                       (long)(vlen), (long)(pos_l),       \
+                                       (long)(pos_h))
+#define __sanitizer_syscall_pre_pwritev(fd, vec, vlen, pos_l, pos_h)          \
+  __sanitizer_syscall_pre_impl_pwritev((long)(fd), (long)(vec), (long)(vlen), \
+                                       (long)(pos_l), (long)(pos_h))
+#define __sanitizer_syscall_post_pwritev(res, fd, vec, vlen, pos_l, pos_h) \
+  __sanitizer_syscall_post_impl_pwritev(res, (long)(fd), (long)(vec),      \
+                                        (long)(vlen), (long)(pos_l),       \
+                                        (long)(pos_h))
+#define __sanitizer_syscall_pre_getcwd(buf, size) \
+  __sanitizer_syscall_pre_impl_getcwd((long)(buf), (long)(size))
+#define __sanitizer_syscall_post_getcwd(res, buf, size) \
+  __sanitizer_syscall_post_impl_getcwd(res, (long)(buf), (long)(size))
+#define __sanitizer_syscall_pre_mkdir(pathname, mode) \
+  __sanitizer_syscall_pre_impl_mkdir((long)(pathname), (long)(mode))
+#define __sanitizer_syscall_post_mkdir(res, pathname, mode) \
+  __sanitizer_syscall_post_impl_mkdir(res, (long)(pathname), (long)(mode))
+#define __sanitizer_syscall_pre_chdir(filename) \
+  __sanitizer_syscall_pre_impl_chdir((long)(filename))
+#define __sanitizer_syscall_post_chdir(res, filename) \
+  __sanitizer_syscall_post_impl_chdir(res, (long)(filename))
+#define __sanitizer_syscall_pre_fchdir(fd) \
+  __sanitizer_syscall_pre_impl_fchdir((long)(fd))
+#define __sanitizer_syscall_post_fchdir(res, fd) \
+  __sanitizer_syscall_post_impl_fchdir(res, (long)(fd))
+#define __sanitizer_syscall_pre_rmdir(pathname) \
+  __sanitizer_syscall_pre_impl_rmdir((long)(pathname))
+#define __sanitizer_syscall_post_rmdir(res, pathname) \
+  __sanitizer_syscall_post_impl_rmdir(res, (long)(pathname))
+#define __sanitizer_syscall_pre_lookup_dcookie(cookie64, buf, len)           \
+  __sanitizer_syscall_pre_impl_lookup_dcookie((long)(cookie64), (long)(buf), \
+                                              (long)(len))
+#define __sanitizer_syscall_post_lookup_dcookie(res, cookie64, buf, len) \
+  __sanitizer_syscall_post_impl_lookup_dcookie(res, (long)(cookie64),    \
+                                               (long)(buf), (long)(len))
+#define __sanitizer_syscall_pre_quotactl(cmd, special, id, addr)      \
+  __sanitizer_syscall_pre_impl_quotactl((long)(cmd), (long)(special), \
+                                        (long)(id), (long)(addr))
+#define __sanitizer_syscall_post_quotactl(res, cmd, special, id, addr)      \
+  __sanitizer_syscall_post_impl_quotactl(res, (long)(cmd), (long)(special), \
+                                         (long)(id), (long)(addr))
+#define __sanitizer_syscall_pre_getdents(fd, dirent, count)         \
+  __sanitizer_syscall_pre_impl_getdents((long)(fd), (long)(dirent), \
+                                        (long)(count))
+#define __sanitizer_syscall_post_getdents(res, fd, dirent, count)         \
+  __sanitizer_syscall_post_impl_getdents(res, (long)(fd), (long)(dirent), \
+                                         (long)(count))
+#define __sanitizer_syscall_pre_getdents64(fd, dirent, count)         \
+  __sanitizer_syscall_pre_impl_getdents64((long)(fd), (long)(dirent), \
+                                          (long)(count))
+#define __sanitizer_syscall_post_getdents64(res, fd, dirent, count)         \
+  __sanitizer_syscall_post_impl_getdents64(res, (long)(fd), (long)(dirent), \
+                                           (long)(count))
+#define __sanitizer_syscall_pre_setsockopt(fd, level, optname, optval, optlen) \
+  __sanitizer_syscall_pre_impl_setsockopt((long)(fd), (long)(level),           \
+                                          (long)(optname), (long)(optval),     \
+                                          (long)(optlen))
+#define __sanitizer_syscall_post_setsockopt(res, fd, level, optname, optval, \
+                                            optlen)                          \
+  __sanitizer_syscall_post_impl_setsockopt(res, (long)(fd), (long)(level),   \
+                                           (long)(optname), (long)(optval),  \
+                                           (long)(optlen))
+#define __sanitizer_syscall_pre_getsockopt(fd, level, optname, optval, optlen) \
+  __sanitizer_syscall_pre_impl_getsockopt((long)(fd), (long)(level),           \
+                                          (long)(optname), (long)(optval),     \
+                                          (long)(optlen))
+#define __sanitizer_syscall_post_getsockopt(res, fd, level, optname, optval, \
+                                            optlen)                          \
+  __sanitizer_syscall_post_impl_getsockopt(res, (long)(fd), (long)(level),   \
+                                           (long)(optname), (long)(optval),  \
+                                           (long)(optlen))
+#define __sanitizer_syscall_pre_bind(arg0, arg1, arg2) \
+  __sanitizer_syscall_pre_impl_bind((long)(arg0), (long)(arg1), (long)(arg2))
+#define __sanitizer_syscall_post_bind(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_bind(res, (long)(arg0), (long)(arg1), \
+                                     (long)(arg2))
+#define __sanitizer_syscall_pre_connect(arg0, arg1, arg2) \
+  __sanitizer_syscall_pre_impl_connect((long)(arg0), (long)(arg1), (long)(arg2))
+#define __sanitizer_syscall_post_connect(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_connect(res, (long)(arg0), (long)(arg1), \
+                                        (long)(arg2))
+#define __sanitizer_syscall_pre_accept(arg0, arg1, arg2) \
+  __sanitizer_syscall_pre_impl_accept((long)(arg0), (long)(arg1), (long)(arg2))
+#define __sanitizer_syscall_post_accept(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_accept(res, (long)(arg0), (long)(arg1), \
+                                       (long)(arg2))
+#define __sanitizer_syscall_pre_accept4(arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_pre_impl_accept4((long)(arg0), (long)(arg1), \
+                                       (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_post_accept4(res, arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_post_impl_accept4(res, (long)(arg0), (long)(arg1), \
+                                        (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_pre_getsockname(arg0, arg1, arg2)          \
+  __sanitizer_syscall_pre_impl_getsockname((long)(arg0), (long)(arg1), \
+                                           (long)(arg2))
+#define __sanitizer_syscall_post_getsockname(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_getsockname(res, (long)(arg0), (long)(arg1), \
+                                            (long)(arg2))
+#define __sanitizer_syscall_pre_getpeername(arg0, arg1, arg2)          \
+  __sanitizer_syscall_pre_impl_getpeername((long)(arg0), (long)(arg1), \
+                                           (long)(arg2))
+#define __sanitizer_syscall_post_getpeername(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_getpeername(res, (long)(arg0), (long)(arg1), \
+                                            (long)(arg2))
+#define __sanitizer_syscall_pre_send(arg0, arg1, arg2, arg3)                  \
+  __sanitizer_syscall_pre_impl_send((long)(arg0), (long)(arg1), (long)(arg2), \
+                                    (long)(arg3))
+#define __sanitizer_syscall_post_send(res, arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_post_impl_send(res, (long)(arg0), (long)(arg1), \
+                                     (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_pre_sendto(arg0, arg1, arg2, arg3, arg4, arg5) \
+  __sanitizer_syscall_pre_impl_sendto((long)(arg0), (long)(arg1),          \
+                                      (long)(arg2), (long)(arg3),          \
+                                      (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_post_sendto(res, arg0, arg1, arg2, arg3, arg4, \
+                                        arg5)                              \
+  __sanitizer_syscall_post_impl_sendto(res, (long)(arg0), (long)(arg1),    \
+                                       (long)(arg2), (long)(arg3),         \
+                                       (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_pre_sendmsg(fd, msg, flags) \
+  __sanitizer_syscall_pre_impl_sendmsg((long)(fd), (long)(msg), (long)(flags))
+#define __sanitizer_syscall_post_sendmsg(res, fd, msg, flags)         \
+  __sanitizer_syscall_post_impl_sendmsg(res, (long)(fd), (long)(msg), \
+                                        (long)(flags))
+#define __sanitizer_syscall_pre_sendmmsg(fd, msg, vlen, flags)                 \
+  __sanitizer_syscall_pre_impl_sendmmsg((long)(fd), (long)(msg), (long)(vlen), \
+                                        (long)(flags))
+#define __sanitizer_syscall_post_sendmmsg(res, fd, msg, vlen, flags)   \
+  __sanitizer_syscall_post_impl_sendmmsg(res, (long)(fd), (long)(msg), \
+                                         (long)(vlen), (long)(flags))
+#define __sanitizer_syscall_pre_recv(arg0, arg1, arg2, arg3)                  \
+  __sanitizer_syscall_pre_impl_recv((long)(arg0), (long)(arg1), (long)(arg2), \
+                                    (long)(arg3))
+#define __sanitizer_syscall_post_recv(res, arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_post_impl_recv(res, (long)(arg0), (long)(arg1), \
+                                     (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_pre_recvfrom(arg0, arg1, arg2, arg3, arg4, arg5) \
+  __sanitizer_syscall_pre_impl_recvfrom((long)(arg0), (long)(arg1),          \
+                                        (long)(arg2), (long)(arg3),          \
+                                        (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_post_recvfrom(res, arg0, arg1, arg2, arg3, arg4, \
+                                          arg5)                              \
+  __sanitizer_syscall_post_impl_recvfrom(res, (long)(arg0), (long)(arg1),    \
+                                         (long)(arg2), (long)(arg3),         \
+                                         (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_pre_recvmsg(fd, msg, flags) \
+  __sanitizer_syscall_pre_impl_recvmsg((long)(fd), (long)(msg), (long)(flags))
+#define __sanitizer_syscall_post_recvmsg(res, fd, msg, flags)         \
+  __sanitizer_syscall_post_impl_recvmsg(res, (long)(fd), (long)(msg), \
+                                        (long)(flags))
+#define __sanitizer_syscall_pre_recvmmsg(fd, msg, vlen, flags, timeout)        \
+  __sanitizer_syscall_pre_impl_recvmmsg((long)(fd), (long)(msg), (long)(vlen), \
+                                        (long)(flags), (long)(timeout))
+#define __sanitizer_syscall_post_recvmmsg(res, fd, msg, vlen, flags, timeout) \
+  __sanitizer_syscall_post_impl_recvmmsg(res, (long)(fd), (long)(msg),        \
+                                         (long)(vlen), (long)(flags),         \
+                                         (long)(timeout))
+#define __sanitizer_syscall_pre_socket(arg0, arg1, arg2) \
+  __sanitizer_syscall_pre_impl_socket((long)(arg0), (long)(arg1), (long)(arg2))
+#define __sanitizer_syscall_post_socket(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_socket(res, (long)(arg0), (long)(arg1), \
+                                       (long)(arg2))
+#define __sanitizer_syscall_pre_socketpair(arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_pre_impl_socketpair((long)(arg0), (long)(arg1), \
+                                          (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_post_socketpair(res, arg0, arg1, arg2, arg3)    \
+  __sanitizer_syscall_post_impl_socketpair(res, (long)(arg0), (long)(arg1), \
+                                           (long)(arg2), (long)(arg3))
+#define __sanitizer_syscall_pre_socketcall(call, args) \
+  __sanitizer_syscall_pre_impl_socketcall((long)(call), (long)(args))
+#define __sanitizer_syscall_post_socketcall(res, call, args) \
+  __sanitizer_syscall_post_impl_socketcall(res, (long)(call), (long)(args))
+#define __sanitizer_syscall_pre_listen(arg0, arg1) \
+  __sanitizer_syscall_pre_impl_listen((long)(arg0), (long)(arg1))
+#define __sanitizer_syscall_post_listen(res, arg0, arg1) \
+  __sanitizer_syscall_post_impl_listen(res, (long)(arg0), (long)(arg1))
+#define __sanitizer_syscall_pre_poll(ufds, nfds, timeout) \
+  __sanitizer_syscall_pre_impl_poll((long)(ufds), (long)(nfds), (long)(timeout))
+#define __sanitizer_syscall_post_poll(res, ufds, nfds, timeout)       \
+  __sanitizer_syscall_post_impl_poll(res, (long)(ufds), (long)(nfds), \
+                                     (long)(timeout))
+#define __sanitizer_syscall_pre_select(n, inp, outp, exp, tvp)              \
+  __sanitizer_syscall_pre_impl_select((long)(n), (long)(inp), (long)(outp), \
+                                      (long)(exp), (long)(tvp))
+#define __sanitizer_syscall_post_select(res, n, inp, outp, exp, tvp) \
+  __sanitizer_syscall_post_impl_select(res, (long)(n), (long)(inp),  \
+                                       (long)(outp), (long)(exp), (long)(tvp))
+#define __sanitizer_syscall_pre_old_select(arg) \
+  __sanitizer_syscall_pre_impl_old_select((long)(arg))
+#define __sanitizer_syscall_post_old_select(res, arg) \
+  __sanitizer_syscall_post_impl_old_select(res, (long)(arg))
+#define __sanitizer_syscall_pre_epoll_create(size) \
+  __sanitizer_syscall_pre_impl_epoll_create((long)(size))
+#define __sanitizer_syscall_post_epoll_create(res, size) \
+  __sanitizer_syscall_post_impl_epoll_create(res, (long)(size))
+#define __sanitizer_syscall_pre_epoll_create1(flags) \
+  __sanitizer_syscall_pre_impl_epoll_create1((long)(flags))
+#define __sanitizer_syscall_post_epoll_create1(res, flags) \
+  __sanitizer_syscall_post_impl_epoll_create1(res, (long)(flags))
+#define __sanitizer_syscall_pre_epoll_ctl(epfd, op, fd, event)                 \
+  __sanitizer_syscall_pre_impl_epoll_ctl((long)(epfd), (long)(op), (long)(fd), \
+                                         (long)(event))
+#define __sanitizer_syscall_post_epoll_ctl(res, epfd, op, fd, event)     \
+  __sanitizer_syscall_post_impl_epoll_ctl(res, (long)(epfd), (long)(op), \
+                                          (long)(fd), (long)(event))
+#define __sanitizer_syscall_pre_epoll_wait(epfd, events, maxevents, timeout) \
+  __sanitizer_syscall_pre_impl_epoll_wait((long)(epfd), (long)(events),      \
+                                          (long)(maxevents), (long)(timeout))
+#define __sanitizer_syscall_post_epoll_wait(res, epfd, events, maxevents,     \
+                                            timeout)                          \
+  __sanitizer_syscall_post_impl_epoll_wait(res, (long)(epfd), (long)(events), \
+                                           (long)(maxevents), (long)(timeout))
+#define __sanitizer_syscall_pre_epoll_pwait(epfd, events, maxevents, timeout, \
+                                            sigmask, sigsetsize)              \
+  __sanitizer_syscall_pre_impl_epoll_pwait(                                   \
+      (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout),       \
+      (long)(sigmask), (long)(sigsetsize))
+#define __sanitizer_syscall_post_epoll_pwait(res, epfd, events, maxevents,   \
+                                             timeout, sigmask, sigsetsize)   \
+  __sanitizer_syscall_post_impl_epoll_pwait(                                 \
+      res, (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \
+      (long)(sigmask), (long)(sigsetsize))
+#define __sanitizer_syscall_pre_gethostname(name, len) \
+  __sanitizer_syscall_pre_impl_gethostname((long)(name), (long)(len))
+#define __sanitizer_syscall_post_gethostname(res, name, len) \
+  __sanitizer_syscall_post_impl_gethostname(res, (long)(name), (long)(len))
+#define __sanitizer_syscall_pre_sethostname(name, len) \
+  __sanitizer_syscall_pre_impl_sethostname((long)(name), (long)(len))
+#define __sanitizer_syscall_post_sethostname(res, name, len) \
+  __sanitizer_syscall_post_impl_sethostname(res, (long)(name), (long)(len))
+#define __sanitizer_syscall_pre_setdomainname(name, len) \
+  __sanitizer_syscall_pre_impl_setdomainname((long)(name), (long)(len))
+#define __sanitizer_syscall_post_setdomainname(res, name, len) \
+  __sanitizer_syscall_post_impl_setdomainname(res, (long)(name), (long)(len))
+#define __sanitizer_syscall_pre_newuname(name) \
+  __sanitizer_syscall_pre_impl_newuname((long)(name))
+#define __sanitizer_syscall_post_newuname(res, name) \
+  __sanitizer_syscall_post_impl_newuname(res, (long)(name))
+#define __sanitizer_syscall_pre_uname(arg0) \
+  __sanitizer_syscall_pre_impl_uname((long)(arg0))
+#define __sanitizer_syscall_post_uname(res, arg0) \
+  __sanitizer_syscall_post_impl_uname(res, (long)(arg0))
+#define __sanitizer_syscall_pre_olduname(arg0) \
+  __sanitizer_syscall_pre_impl_olduname((long)(arg0))
+#define __sanitizer_syscall_post_olduname(res, arg0) \
+  __sanitizer_syscall_post_impl_olduname(res, (long)(arg0))
+#define __sanitizer_syscall_pre_getrlimit(resource, rlim) \
+  __sanitizer_syscall_pre_impl_getrlimit((long)(resource), (long)(rlim))
+#define __sanitizer_syscall_post_getrlimit(res, resource, rlim) \
+  __sanitizer_syscall_post_impl_getrlimit(res, (long)(resource), (long)(rlim))
+#define __sanitizer_syscall_pre_old_getrlimit(resource, rlim) \
+  __sanitizer_syscall_pre_impl_old_getrlimit((long)(resource), (long)(rlim))
+#define __sanitizer_syscall_post_old_getrlimit(res, resource, rlim)  \
+  __sanitizer_syscall_post_impl_old_getrlimit(res, (long)(resource), \
+                                              (long)(rlim))
+#define __sanitizer_syscall_pre_setrlimit(resource, rlim) \
+  __sanitizer_syscall_pre_impl_setrlimit((long)(resource), (long)(rlim))
+#define __sanitizer_syscall_post_setrlimit(res, resource, rlim) \
+  __sanitizer_syscall_post_impl_setrlimit(res, (long)(resource), (long)(rlim))
+#define __sanitizer_syscall_pre_prlimit64(pid, resource, new_rlim, old_rlim) \
+  __sanitizer_syscall_pre_impl_prlimit64((long)(pid), (long)(resource),      \
+                                         (long)(new_rlim), (long)(old_rlim))
+#define __sanitizer_syscall_post_prlimit64(res, pid, resource, new_rlim,      \
+                                           old_rlim)                          \
+  __sanitizer_syscall_post_impl_prlimit64(res, (long)(pid), (long)(resource), \
+                                          (long)(new_rlim), (long)(old_rlim))
+#define __sanitizer_syscall_pre_getrusage(who, ru) \
+  __sanitizer_syscall_pre_impl_getrusage((long)(who), (long)(ru))
+#define __sanitizer_syscall_post_getrusage(res, who, ru) \
+  __sanitizer_syscall_post_impl_getrusage(res, (long)(who), (long)(ru))
+#define __sanitizer_syscall_pre_umask(mask) \
+  __sanitizer_syscall_pre_impl_umask((long)(mask))
+#define __sanitizer_syscall_post_umask(res, mask) \
+  __sanitizer_syscall_post_impl_umask(res, (long)(mask))
+#define __sanitizer_syscall_pre_msgget(key, msgflg) \
+  __sanitizer_syscall_pre_impl_msgget((long)(key), (long)(msgflg))
+#define __sanitizer_syscall_post_msgget(res, key, msgflg) \
+  __sanitizer_syscall_post_impl_msgget(res, (long)(key), (long)(msgflg))
+#define __sanitizer_syscall_pre_msgsnd(msqid, msgp, msgsz, msgflg) \
+  __sanitizer_syscall_pre_impl_msgsnd((long)(msqid), (long)(msgp), \
+                                      (long)(msgsz), (long)(msgflg))
+#define __sanitizer_syscall_post_msgsnd(res, msqid, msgp, msgsz, msgflg) \
+  __sanitizer_syscall_post_impl_msgsnd(res, (long)(msqid), (long)(msgp), \
+                                       (long)(msgsz), (long)(msgflg))
+#define __sanitizer_syscall_pre_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) \
+  __sanitizer_syscall_pre_impl_msgrcv((long)(msqid), (long)(msgp),         \
+                                      (long)(msgsz), (long)(msgtyp),       \
+                                      (long)(msgflg))
+#define __sanitizer_syscall_post_msgrcv(res, msqid, msgp, msgsz, msgtyp, \
+                                        msgflg)                          \
+  __sanitizer_syscall_post_impl_msgrcv(res, (long)(msqid), (long)(msgp), \
+                                       (long)(msgsz), (long)(msgtyp),    \
+                                       (long)(msgflg))
+#define __sanitizer_syscall_pre_msgctl(msqid, cmd, buf) \
+  __sanitizer_syscall_pre_impl_msgctl((long)(msqid), (long)(cmd), (long)(buf))
+#define __sanitizer_syscall_post_msgctl(res, msqid, cmd, buf)           \
+  __sanitizer_syscall_post_impl_msgctl(res, (long)(msqid), (long)(cmd), \
+                                       (long)(buf))
+#define __sanitizer_syscall_pre_semget(key, nsems, semflg)        \
+  __sanitizer_syscall_pre_impl_semget((long)(key), (long)(nsems), \
+                                      (long)(semflg))
+#define __sanitizer_syscall_post_semget(res, key, nsems, semflg)        \
+  __sanitizer_syscall_post_impl_semget(res, (long)(key), (long)(nsems), \
+                                       (long)(semflg))
+#define __sanitizer_syscall_pre_semop(semid, sops, nsops) \
+  __sanitizer_syscall_pre_impl_semop((long)(semid), (long)(sops), (long)(nsops))
+#define __sanitizer_syscall_post_semop(res, semid, sops, nsops)         \
+  __sanitizer_syscall_post_impl_semop(res, (long)(semid), (long)(sops), \
+                                      (long)(nsops))
+#define __sanitizer_syscall_pre_semctl(semid, semnum, cmd, arg)      \
+  __sanitizer_syscall_pre_impl_semctl((long)(semid), (long)(semnum), \
+                                      (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_post_semctl(res, semid, semnum, cmd, arg)      \
+  __sanitizer_syscall_post_impl_semctl(res, (long)(semid), (long)(semnum), \
+                                       (long)(cmd), (long)(arg))
+#define __sanitizer_syscall_pre_semtimedop(semid, sops, nsops, timeout) \
+  __sanitizer_syscall_pre_impl_semtimedop((long)(semid), (long)(sops),  \
+                                          (long)(nsops), (long)(timeout))
+#define __sanitizer_syscall_post_semtimedop(res, semid, sops, nsops, timeout) \
+  __sanitizer_syscall_post_impl_semtimedop(res, (long)(semid), (long)(sops),  \
+                                           (long)(nsops), (long)(timeout))
+#define __sanitizer_syscall_pre_shmat(shmid, shmaddr, shmflg)        \
+  __sanitizer_syscall_pre_impl_shmat((long)(shmid), (long)(shmaddr), \
+                                     (long)(shmflg))
+#define __sanitizer_syscall_post_shmat(res, shmid, shmaddr, shmflg)        \
+  __sanitizer_syscall_post_impl_shmat(res, (long)(shmid), (long)(shmaddr), \
+                                      (long)(shmflg))
+#define __sanitizer_syscall_pre_shmget(key, size, flag) \
+  __sanitizer_syscall_pre_impl_shmget((long)(key), (long)(size), (long)(flag))
+#define __sanitizer_syscall_post_shmget(res, key, size, flag)          \
+  __sanitizer_syscall_post_impl_shmget(res, (long)(key), (long)(size), \
+                                       (long)(flag))
+#define __sanitizer_syscall_pre_shmdt(shmaddr) \
+  __sanitizer_syscall_pre_impl_shmdt((long)(shmaddr))
+#define __sanitizer_syscall_post_shmdt(res, shmaddr) \
+  __sanitizer_syscall_post_impl_shmdt(res, (long)(shmaddr))
+#define __sanitizer_syscall_pre_shmctl(shmid, cmd, buf) \
+  __sanitizer_syscall_pre_impl_shmctl((long)(shmid), (long)(cmd), (long)(buf))
+#define __sanitizer_syscall_post_shmctl(res, shmid, cmd, buf)           \
+  __sanitizer_syscall_post_impl_shmctl(res, (long)(shmid), (long)(cmd), \
+                                       (long)(buf))
+#define __sanitizer_syscall_pre_ipc(call, first, second, third, ptr, fifth)    \
+  __sanitizer_syscall_pre_impl_ipc((long)(call), (long)(first),                \
+                                   (long)(second), (long)(third), (long)(ptr), \
+                                   (long)(fifth))
+#define __sanitizer_syscall_post_ipc(res, call, first, second, third, ptr, \
+                                     fifth)                                \
+  __sanitizer_syscall_post_impl_ipc(res, (long)(call), (long)(first),      \
+                                    (long)(second), (long)(third),         \
+                                    (long)(ptr), (long)(fifth))
+#define __sanitizer_syscall_pre_mq_open(name, oflag, mode, attr)    \
+  __sanitizer_syscall_pre_impl_mq_open((long)(name), (long)(oflag), \
+                                       (long)(mode), (long)(attr))
+#define __sanitizer_syscall_post_mq_open(res, name, oflag, mode, attr)    \
+  __sanitizer_syscall_post_impl_mq_open(res, (long)(name), (long)(oflag), \
+                                        (long)(mode), (long)(attr))
+#define __sanitizer_syscall_pre_mq_unlink(name) \
+  __sanitizer_syscall_pre_impl_mq_unlink((long)(name))
+#define __sanitizer_syscall_post_mq_unlink(res, name) \
+  __sanitizer_syscall_post_impl_mq_unlink(res, (long)(name))
+#define __sanitizer_syscall_pre_mq_timedsend(mqdes, msg_ptr, msg_len,          \
+                                             msg_prio, abs_timeout)            \
+  __sanitizer_syscall_pre_impl_mq_timedsend((long)(mqdes), (long)(msg_ptr),    \
+                                            (long)(msg_len), (long)(msg_prio), \
+                                            (long)(abs_timeout))
+#define __sanitizer_syscall_post_mq_timedsend(res, mqdes, msg_ptr, msg_len,   \
+                                              msg_prio, abs_timeout)          \
+  __sanitizer_syscall_post_impl_mq_timedsend(                                 \
+      res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \
+      (long)(abs_timeout))
+#define __sanitizer_syscall_pre_mq_timedreceive(mqdes, msg_ptr, msg_len, \
+                                                msg_prio, abs_timeout)   \
+  __sanitizer_syscall_pre_impl_mq_timedreceive(                          \
+      (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \
+      (long)(abs_timeout))
+#define __sanitizer_syscall_post_mq_timedreceive(res, mqdes, msg_ptr, msg_len, \
+                                                 msg_prio, abs_timeout)        \
+  __sanitizer_syscall_post_impl_mq_timedreceive(                               \
+      res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio),  \
+      (long)(abs_timeout))
+#define __sanitizer_syscall_pre_mq_notify(mqdes, notification) \
+  __sanitizer_syscall_pre_impl_mq_notify((long)(mqdes), (long)(notification))
+#define __sanitizer_syscall_post_mq_notify(res, mqdes, notification) \
+  __sanitizer_syscall_post_impl_mq_notify(res, (long)(mqdes),        \
+                                          (long)(notification))
+#define __sanitizer_syscall_pre_mq_getsetattr(mqdes, mqstat, omqstat)       \
+  __sanitizer_syscall_pre_impl_mq_getsetattr((long)(mqdes), (long)(mqstat), \
+                                             (long)(omqstat))
+#define __sanitizer_syscall_post_mq_getsetattr(res, mqdes, mqstat, omqstat) \
+  __sanitizer_syscall_post_impl_mq_getsetattr(res, (long)(mqdes),           \
+                                              (long)(mqstat), (long)(omqstat))
+#define __sanitizer_syscall_pre_pciconfig_iobase(which, bus, devfn)         \
+  __sanitizer_syscall_pre_impl_pciconfig_iobase((long)(which), (long)(bus), \
+                                                (long)(devfn))
+#define __sanitizer_syscall_post_pciconfig_iobase(res, which, bus, devfn) \
+  __sanitizer_syscall_post_impl_pciconfig_iobase(res, (long)(which),      \
+                                                 (long)(bus), (long)(devfn))
+#define __sanitizer_syscall_pre_pciconfig_read(bus, dfn, off, len, buf) \
+  __sanitizer_syscall_pre_impl_pciconfig_read(                          \
+      (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))
+#define __sanitizer_syscall_post_pciconfig_read(res, bus, dfn, off, len, buf) \
+  __sanitizer_syscall_post_impl_pciconfig_read(                               \
+      res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))
+#define __sanitizer_syscall_pre_pciconfig_write(bus, dfn, off, len, buf) \
+  __sanitizer_syscall_pre_impl_pciconfig_write(                          \
+      (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))
+#define __sanitizer_syscall_post_pciconfig_write(res, bus, dfn, off, len, buf) \
+  __sanitizer_syscall_post_impl_pciconfig_write(                               \
+      res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf))
+#define __sanitizer_syscall_pre_swapon(specialfile, swap_flags) \
+  __sanitizer_syscall_pre_impl_swapon((long)(specialfile), (long)(swap_flags))
+#define __sanitizer_syscall_post_swapon(res, specialfile, swap_flags) \
+  __sanitizer_syscall_post_impl_swapon(res, (long)(specialfile),      \
+                                       (long)(swap_flags))
+#define __sanitizer_syscall_pre_swapoff(specialfile) \
+  __sanitizer_syscall_pre_impl_swapoff((long)(specialfile))
+#define __sanitizer_syscall_post_swapoff(res, specialfile) \
+  __sanitizer_syscall_post_impl_swapoff(res, (long)(specialfile))
+#define __sanitizer_syscall_pre_sysctl(args) \
+  __sanitizer_syscall_pre_impl_sysctl((long)(args))
+#define __sanitizer_syscall_post_sysctl(res, args) \
+  __sanitizer_syscall_post_impl_sysctl(res, (long)(args))
+#define __sanitizer_syscall_pre_sysinfo(info) \
+  __sanitizer_syscall_pre_impl_sysinfo((long)(info))
+#define __sanitizer_syscall_post_sysinfo(res, info) \
+  __sanitizer_syscall_post_impl_sysinfo(res, (long)(info))
+#define __sanitizer_syscall_pre_sysfs(option, arg1, arg2) \
+  __sanitizer_syscall_pre_impl_sysfs((long)(option), (long)(arg1), (long)(arg2))
+#define __sanitizer_syscall_post_sysfs(res, option, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_sysfs(res, (long)(option), (long)(arg1), \
+                                      (long)(arg2))
+#define __sanitizer_syscall_pre_syslog(type, buf, len) \
+  __sanitizer_syscall_pre_impl_syslog((long)(type), (long)(buf), (long)(len))
+#define __sanitizer_syscall_post_syslog(res, type, buf, len)           \
+  __sanitizer_syscall_post_impl_syslog(res, (long)(type), (long)(buf), \
+                                       (long)(len))
+#define __sanitizer_syscall_pre_uselib(library) \
+  __sanitizer_syscall_pre_impl_uselib((long)(library))
+#define __sanitizer_syscall_post_uselib(res, library) \
+  __sanitizer_syscall_post_impl_uselib(res, (long)(library))
+#define __sanitizer_syscall_pre_ni_syscall() \
+  __sanitizer_syscall_pre_impl_ni_syscall()
+#define __sanitizer_syscall_post_ni_syscall(res) \
+  __sanitizer_syscall_post_impl_ni_syscall(res)
+#define __sanitizer_syscall_pre_ptrace(request, pid, addr, data)    \
+  __sanitizer_syscall_pre_impl_ptrace((long)(request), (long)(pid), \
+                                      (long)(addr), (long)(data))
+#define __sanitizer_syscall_post_ptrace(res, request, pid, addr, data)    \
+  __sanitizer_syscall_post_impl_ptrace(res, (long)(request), (long)(pid), \
+                                       (long)(addr), (long)(data))
+#define __sanitizer_syscall_pre_add_key(_type, _description, _payload, plen, \
+                                        destringid)                          \
+  __sanitizer_syscall_pre_impl_add_key((long)(_type), (long)(_description),  \
+                                       (long)(_payload), (long)(plen),       \
+                                       (long)(destringid))
+#define __sanitizer_syscall_post_add_key(res, _type, _description, _payload, \
+                                         plen, destringid)                   \
+  __sanitizer_syscall_post_impl_add_key(                                     \
+      res, (long)(_type), (long)(_description), (long)(_payload),            \
+      (long)(plen), (long)(destringid))
+#define __sanitizer_syscall_pre_request_key(_type, _description,       \
+                                            _callout_info, destringid) \
+  __sanitizer_syscall_pre_impl_request_key(                            \
+      (long)(_type), (long)(_description), (long)(_callout_info),      \
+      (long)(destringid))
+#define __sanitizer_syscall_post_request_key(res, _type, _description,  \
+                                             _callout_info, destringid) \
+  __sanitizer_syscall_post_impl_request_key(                            \
+      res, (long)(_type), (long)(_description), (long)(_callout_info),  \
+      (long)(destringid))
+#define __sanitizer_syscall_pre_keyctl(cmd, arg2, arg3, arg4, arg5)            \
+  __sanitizer_syscall_pre_impl_keyctl((long)(cmd), (long)(arg2), (long)(arg3), \
+                                      (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_post_keyctl(res, cmd, arg2, arg3, arg4, arg5) \
+  __sanitizer_syscall_post_impl_keyctl(res, (long)(cmd), (long)(arg2),    \
+                                       (long)(arg3), (long)(arg4),        \
+                                       (long)(arg5))
+#define __sanitizer_syscall_pre_ioprio_set(which, who, ioprio)        \
+  __sanitizer_syscall_pre_impl_ioprio_set((long)(which), (long)(who), \
+                                          (long)(ioprio))
+#define __sanitizer_syscall_post_ioprio_set(res, which, who, ioprio)        \
+  __sanitizer_syscall_post_impl_ioprio_set(res, (long)(which), (long)(who), \
+                                           (long)(ioprio))
+#define __sanitizer_syscall_pre_ioprio_get(which, who) \
+  __sanitizer_syscall_pre_impl_ioprio_get((long)(which), (long)(who))
+#define __sanitizer_syscall_post_ioprio_get(res, which, who) \
+  __sanitizer_syscall_post_impl_ioprio_get(res, (long)(which), (long)(who))
+#define __sanitizer_syscall_pre_set_mempolicy(mode, nmask, maxnode)       \
+  __sanitizer_syscall_pre_impl_set_mempolicy((long)(mode), (long)(nmask), \
+                                             (long)(maxnode))
+#define __sanitizer_syscall_post_set_mempolicy(res, mode, nmask, maxnode) \
+  __sanitizer_syscall_post_impl_set_mempolicy(res, (long)(mode),          \
+                                              (long)(nmask), (long)(maxnode))
+#define __sanitizer_syscall_pre_migrate_pages(pid, maxnode, from, to)      \
+  __sanitizer_syscall_pre_impl_migrate_pages((long)(pid), (long)(maxnode), \
+                                             (long)(from), (long)(to))
+#define __sanitizer_syscall_post_migrate_pages(res, pid, maxnode, from, to) \
+  __sanitizer_syscall_post_impl_migrate_pages(                              \
+      res, (long)(pid), (long)(maxnode), (long)(from), (long)(to))
+#define __sanitizer_syscall_pre_move_pages(pid, nr_pages, pages, nodes,  \
+                                           status, flags)                \
+  __sanitizer_syscall_pre_impl_move_pages((long)(pid), (long)(nr_pages), \
+                                          (long)(pages), (long)(nodes),  \
+                                          (long)(status), (long)(flags))
+#define __sanitizer_syscall_post_move_pages(res, pid, nr_pages, pages, nodes,  \
+                                            status, flags)                     \
+  __sanitizer_syscall_post_impl_move_pages(res, (long)(pid), (long)(nr_pages), \
+                                           (long)(pages), (long)(nodes),       \
+                                           (long)(status), (long)(flags))
+#define __sanitizer_syscall_pre_mbind(start, len, mode, nmask, maxnode, flags) \
+  __sanitizer_syscall_pre_impl_mbind((long)(start), (long)(len), (long)(mode), \
+                                     (long)(nmask), (long)(maxnode),           \
+                                     (long)(flags))
+#define __sanitizer_syscall_post_mbind(res, start, len, mode, nmask, maxnode, \
+                                       flags)                                 \
+  __sanitizer_syscall_post_impl_mbind(res, (long)(start), (long)(len),        \
+                                      (long)(mode), (long)(nmask),            \
+                                      (long)(maxnode), (long)(flags))
+#define __sanitizer_syscall_pre_get_mempolicy(policy, nmask, maxnode, addr, \
+                                              flags)                        \
+  __sanitizer_syscall_pre_impl_get_mempolicy((long)(policy), (long)(nmask), \
+                                             (long)(maxnode), (long)(addr), \
+                                             (long)(flags))
+#define __sanitizer_syscall_post_get_mempolicy(res, policy, nmask, maxnode,   \
+                                               addr, flags)                   \
+  __sanitizer_syscall_post_impl_get_mempolicy(res, (long)(policy),            \
+                                              (long)(nmask), (long)(maxnode), \
+                                              (long)(addr), (long)(flags))
+#define __sanitizer_syscall_pre_inotify_init() \
+  __sanitizer_syscall_pre_impl_inotify_init()
+#define __sanitizer_syscall_post_inotify_init(res) \
+  __sanitizer_syscall_post_impl_inotify_init(res)
+#define __sanitizer_syscall_pre_inotify_init1(flags) \
+  __sanitizer_syscall_pre_impl_inotify_init1((long)(flags))
+#define __sanitizer_syscall_post_inotify_init1(res, flags) \
+  __sanitizer_syscall_post_impl_inotify_init1(res, (long)(flags))
+#define __sanitizer_syscall_pre_inotify_add_watch(fd, path, mask)          \
+  __sanitizer_syscall_pre_impl_inotify_add_watch((long)(fd), (long)(path), \
+                                                 (long)(mask))
+#define __sanitizer_syscall_post_inotify_add_watch(res, fd, path, mask) \
+  __sanitizer_syscall_post_impl_inotify_add_watch(res, (long)(fd),      \
+                                                  (long)(path), (long)(mask))
+#define __sanitizer_syscall_pre_inotify_rm_watch(fd, wd) \
+  __sanitizer_syscall_pre_impl_inotify_rm_watch((long)(fd), (long)(wd))
+#define __sanitizer_syscall_post_inotify_rm_watch(res, fd, wd) \
+  __sanitizer_syscall_post_impl_inotify_rm_watch(res, (long)(fd), (long)(wd))
+#define __sanitizer_syscall_pre_spu_run(fd, unpc, ustatus)       \
+  __sanitizer_syscall_pre_impl_spu_run((long)(fd), (long)(unpc), \
+                                       (long)(ustatus))
+#define __sanitizer_syscall_post_spu_run(res, fd, unpc, ustatus)       \
+  __sanitizer_syscall_post_impl_spu_run(res, (long)(fd), (long)(unpc), \
+                                        (long)(ustatus))
+#define __sanitizer_syscall_pre_spu_create(name, flags, mode, fd)      \
+  __sanitizer_syscall_pre_impl_spu_create((long)(name), (long)(flags), \
+                                          (long)(mode), (long)(fd))
+#define __sanitizer_syscall_post_spu_create(res, name, flags, mode, fd)      \
+  __sanitizer_syscall_post_impl_spu_create(res, (long)(name), (long)(flags), \
+                                           (long)(mode), (long)(fd))
+#define __sanitizer_syscall_pre_mknodat(dfd, filename, mode, dev)     \
+  __sanitizer_syscall_pre_impl_mknodat((long)(dfd), (long)(filename), \
+                                       (long)(mode), (long)(dev))
+#define __sanitizer_syscall_post_mknodat(res, dfd, filename, mode, dev)     \
+  __sanitizer_syscall_post_impl_mknodat(res, (long)(dfd), (long)(filename), \
+                                        (long)(mode), (long)(dev))
+#define __sanitizer_syscall_pre_mkdirat(dfd, pathname, mode)          \
+  __sanitizer_syscall_pre_impl_mkdirat((long)(dfd), (long)(pathname), \
+                                       (long)(mode))
+#define __sanitizer_syscall_post_mkdirat(res, dfd, pathname, mode)          \
+  __sanitizer_syscall_post_impl_mkdirat(res, (long)(dfd), (long)(pathname), \
+                                        (long)(mode))
+#define __sanitizer_syscall_pre_unlinkat(dfd, pathname, flag)          \
+  __sanitizer_syscall_pre_impl_unlinkat((long)(dfd), (long)(pathname), \
+                                        (long)(flag))
+#define __sanitizer_syscall_post_unlinkat(res, dfd, pathname, flag)          \
+  __sanitizer_syscall_post_impl_unlinkat(res, (long)(dfd), (long)(pathname), \
+                                         (long)(flag))
+#define __sanitizer_syscall_pre_symlinkat(oldname, newdfd, newname)       \
+  __sanitizer_syscall_pre_impl_symlinkat((long)(oldname), (long)(newdfd), \
+                                         (long)(newname))
+#define __sanitizer_syscall_post_symlinkat(res, oldname, newdfd, newname) \
+  __sanitizer_syscall_post_impl_symlinkat(res, (long)(oldname),           \
+                                          (long)(newdfd), (long)(newname))
+#define __sanitizer_syscall_pre_linkat(olddfd, oldname, newdfd, newname, \
+                                       flags)                            \
+  __sanitizer_syscall_pre_impl_linkat((long)(olddfd), (long)(oldname),   \
+                                      (long)(newdfd), (long)(newname),   \
+                                      (long)(flags))
+#define __sanitizer_syscall_post_linkat(res, olddfd, oldname, newdfd, newname, \
+                                        flags)                                 \
+  __sanitizer_syscall_post_impl_linkat(res, (long)(olddfd), (long)(oldname),   \
+                                       (long)(newdfd), (long)(newname),        \
+                                       (long)(flags))
+#define __sanitizer_syscall_pre_renameat(olddfd, oldname, newdfd, newname) \
+  __sanitizer_syscall_pre_impl_renameat((long)(olddfd), (long)(oldname),   \
+                                        (long)(newdfd), (long)(newname))
+#define __sanitizer_syscall_post_renameat(res, olddfd, oldname, newdfd,        \
+                                          newname)                             \
+  __sanitizer_syscall_post_impl_renameat(res, (long)(olddfd), (long)(oldname), \
+                                         (long)(newdfd), (long)(newname))
+#define __sanitizer_syscall_pre_futimesat(dfd, filename, utimes)        \
+  __sanitizer_syscall_pre_impl_futimesat((long)(dfd), (long)(filename), \
+                                         (long)(utimes))
+#define __sanitizer_syscall_post_futimesat(res, dfd, filename, utimes)        \
+  __sanitizer_syscall_post_impl_futimesat(res, (long)(dfd), (long)(filename), \
+                                          (long)(utimes))
+#define __sanitizer_syscall_pre_faccessat(dfd, filename, mode)          \
+  __sanitizer_syscall_pre_impl_faccessat((long)(dfd), (long)(filename), \
+                                         (long)(mode))
+#define __sanitizer_syscall_post_faccessat(res, dfd, filename, mode)          \
+  __sanitizer_syscall_post_impl_faccessat(res, (long)(dfd), (long)(filename), \
+                                          (long)(mode))
+#define __sanitizer_syscall_pre_fchmodat(dfd, filename, mode)          \
+  __sanitizer_syscall_pre_impl_fchmodat((long)(dfd), (long)(filename), \
+                                        (long)(mode))
+#define __sanitizer_syscall_post_fchmodat(res, dfd, filename, mode)          \
+  __sanitizer_syscall_post_impl_fchmodat(res, (long)(dfd), (long)(filename), \
+                                         (long)(mode))
+#define __sanitizer_syscall_pre_fchownat(dfd, filename, user, group, flag) \
+  __sanitizer_syscall_pre_impl_fchownat((long)(dfd), (long)(filename),     \
+                                        (long)(user), (long)(group),       \
+                                        (long)(flag))
+#define __sanitizer_syscall_post_fchownat(res, dfd, filename, user, group,   \
+                                          flag)                              \
+  __sanitizer_syscall_post_impl_fchownat(res, (long)(dfd), (long)(filename), \
+                                         (long)(user), (long)(group),        \
+                                         (long)(flag))
+#define __sanitizer_syscall_pre_openat(dfd, filename, flags, mode)   \
+  __sanitizer_syscall_pre_impl_openat((long)(dfd), (long)(filename), \
+                                      (long)(flags), (long)(mode))
+#define __sanitizer_syscall_post_openat(res, dfd, filename, flags, mode)   \
+  __sanitizer_syscall_post_impl_openat(res, (long)(dfd), (long)(filename), \
+                                       (long)(flags), (long)(mode))
+#define __sanitizer_syscall_pre_newfstatat(dfd, filename, statbuf, flag) \
+  __sanitizer_syscall_pre_impl_newfstatat((long)(dfd), (long)(filename), \
+                                          (long)(statbuf), (long)(flag))
+#define __sanitizer_syscall_post_newfstatat(res, dfd, filename, statbuf, flag) \
+  __sanitizer_syscall_post_impl_newfstatat(res, (long)(dfd), (long)(filename), \
+                                           (long)(statbuf), (long)(flag))
+#define __sanitizer_syscall_pre_fstatat64(dfd, filename, statbuf, flag) \
+  __sanitizer_syscall_pre_impl_fstatat64((long)(dfd), (long)(filename), \
+                                         (long)(statbuf), (long)(flag))
+#define __sanitizer_syscall_post_fstatat64(res, dfd, filename, statbuf, flag) \
+  __sanitizer_syscall_post_impl_fstatat64(res, (long)(dfd), (long)(filename), \
+                                          (long)(statbuf), (long)(flag))
+#define __sanitizer_syscall_pre_readlinkat(dfd, path, buf, bufsiz)   \
+  __sanitizer_syscall_pre_impl_readlinkat((long)(dfd), (long)(path), \
+                                          (long)(buf), (long)(bufsiz))
+#define __sanitizer_syscall_post_readlinkat(res, dfd, path, buf, bufsiz)   \
+  __sanitizer_syscall_post_impl_readlinkat(res, (long)(dfd), (long)(path), \
+                                           (long)(buf), (long)(bufsiz))
+#define __sanitizer_syscall_pre_utimensat(dfd, filename, utimes, flags) \
+  __sanitizer_syscall_pre_impl_utimensat((long)(dfd), (long)(filename), \
+                                         (long)(utimes), (long)(flags))
+#define __sanitizer_syscall_post_utimensat(res, dfd, filename, utimes, flags) \
+  __sanitizer_syscall_post_impl_utimensat(res, (long)(dfd), (long)(filename), \
+                                          (long)(utimes), (long)(flags))
+#define __sanitizer_syscall_pre_unshare(unshare_flags) \
+  __sanitizer_syscall_pre_impl_unshare((long)(unshare_flags))
+#define __sanitizer_syscall_post_unshare(res, unshare_flags) \
+  __sanitizer_syscall_post_impl_unshare(res, (long)(unshare_flags))
+#define __sanitizer_syscall_pre_splice(fd_in, off_in, fd_out, off_out, len, \
+                                       flags)                               \
+  __sanitizer_syscall_pre_impl_splice((long)(fd_in), (long)(off_in),        \
+                                      (long)(fd_out), (long)(off_out),      \
+                                      (long)(len), (long)(flags))
+#define __sanitizer_syscall_post_splice(res, fd_in, off_in, fd_out, off_out, \
+                                        len, flags)                          \
+  __sanitizer_syscall_post_impl_splice(res, (long)(fd_in), (long)(off_in),   \
+                                       (long)(fd_out), (long)(off_out),      \
+                                       (long)(len), (long)(flags))
+#define __sanitizer_syscall_pre_vmsplice(fd, iov, nr_segs, flags) \
+  __sanitizer_syscall_pre_impl_vmsplice((long)(fd), (long)(iov),  \
+                                        (long)(nr_segs), (long)(flags))
+#define __sanitizer_syscall_post_vmsplice(res, fd, iov, nr_segs, flags) \
+  __sanitizer_syscall_post_impl_vmsplice(res, (long)(fd), (long)(iov),  \
+                                         (long)(nr_segs), (long)(flags))
+#define __sanitizer_syscall_pre_tee(fdin, fdout, len, flags)                 \
+  __sanitizer_syscall_pre_impl_tee((long)(fdin), (long)(fdout), (long)(len), \
+                                   (long)(flags))
+#define __sanitizer_syscall_post_tee(res, fdin, fdout, len, flags)    \
+  __sanitizer_syscall_post_impl_tee(res, (long)(fdin), (long)(fdout), \
+                                    (long)(len), (long)(flags))
+#define __sanitizer_syscall_pre_get_robust_list(pid, head_ptr, len_ptr)       \
+  __sanitizer_syscall_pre_impl_get_robust_list((long)(pid), (long)(head_ptr), \
+                                               (long)(len_ptr))
+#define __sanitizer_syscall_post_get_robust_list(res, pid, head_ptr, len_ptr) \
+  __sanitizer_syscall_post_impl_get_robust_list(                              \
+      res, (long)(pid), (long)(head_ptr), (long)(len_ptr))
+#define __sanitizer_syscall_pre_set_robust_list(head, len) \
+  __sanitizer_syscall_pre_impl_set_robust_list((long)(head), (long)(len))
+#define __sanitizer_syscall_post_set_robust_list(res, head, len) \
+  __sanitizer_syscall_post_impl_set_robust_list(res, (long)(head), (long)(len))
+#define __sanitizer_syscall_pre_getcpu(cpu, node, cache) \
+  __sanitizer_syscall_pre_impl_getcpu((long)(cpu), (long)(node), (long)(cache))
+#define __sanitizer_syscall_post_getcpu(res, cpu, node, cache)         \
+  __sanitizer_syscall_post_impl_getcpu(res, (long)(cpu), (long)(node), \
+                                       (long)(cache))
+#define __sanitizer_syscall_pre_signalfd(ufd, user_mask, sizemask)      \
+  __sanitizer_syscall_pre_impl_signalfd((long)(ufd), (long)(user_mask), \
+                                        (long)(sizemask))
+#define __sanitizer_syscall_post_signalfd(res, ufd, user_mask, sizemask)      \
+  __sanitizer_syscall_post_impl_signalfd(res, (long)(ufd), (long)(user_mask), \
+                                         (long)(sizemask))
+#define __sanitizer_syscall_pre_signalfd4(ufd, user_mask, sizemask, flags) \
+  __sanitizer_syscall_pre_impl_signalfd4((long)(ufd), (long)(user_mask),   \
+                                         (long)(sizemask), (long)(flags))
+#define __sanitizer_syscall_post_signalfd4(res, ufd, user_mask, sizemask,      \
+                                           flags)                              \
+  __sanitizer_syscall_post_impl_signalfd4(res, (long)(ufd), (long)(user_mask), \
+                                          (long)(sizemask), (long)(flags))
+#define __sanitizer_syscall_pre_timerfd_create(clockid, flags) \
+  __sanitizer_syscall_pre_impl_timerfd_create((long)(clockid), (long)(flags))
+#define __sanitizer_syscall_post_timerfd_create(res, clockid, flags) \
+  __sanitizer_syscall_post_impl_timerfd_create(res, (long)(clockid), \
+                                               (long)(flags))
+#define __sanitizer_syscall_pre_timerfd_settime(ufd, flags, utmr, otmr)    \
+  __sanitizer_syscall_pre_impl_timerfd_settime((long)(ufd), (long)(flags), \
+                                               (long)(utmr), (long)(otmr))
+#define __sanitizer_syscall_post_timerfd_settime(res, ufd, flags, utmr, otmr) \
+  __sanitizer_syscall_post_impl_timerfd_settime(                              \
+      res, (long)(ufd), (long)(flags), (long)(utmr), (long)(otmr))
+#define __sanitizer_syscall_pre_timerfd_gettime(ufd, otmr) \
+  __sanitizer_syscall_pre_impl_timerfd_gettime((long)(ufd), (long)(otmr))
+#define __sanitizer_syscall_post_timerfd_gettime(res, ufd, otmr) \
+  __sanitizer_syscall_post_impl_timerfd_gettime(res, (long)(ufd), (long)(otmr))
+#define __sanitizer_syscall_pre_eventfd(count) \
+  __sanitizer_syscall_pre_impl_eventfd((long)(count))
+#define __sanitizer_syscall_post_eventfd(res, count) \
+  __sanitizer_syscall_post_impl_eventfd(res, (long)(count))
+#define __sanitizer_syscall_pre_eventfd2(count, flags) \
+  __sanitizer_syscall_pre_impl_eventfd2((long)(count), (long)(flags))
+#define __sanitizer_syscall_post_eventfd2(res, count, flags) \
+  __sanitizer_syscall_post_impl_eventfd2(res, (long)(count), (long)(flags))
+#define __sanitizer_syscall_pre_old_readdir(arg0, arg1, arg2)          \
+  __sanitizer_syscall_pre_impl_old_readdir((long)(arg0), (long)(arg1), \
+                                           (long)(arg2))
+#define __sanitizer_syscall_post_old_readdir(res, arg0, arg1, arg2)          \
+  __sanitizer_syscall_post_impl_old_readdir(res, (long)(arg0), (long)(arg1), \
+                                            (long)(arg2))
+#define __sanitizer_syscall_pre_pselect6(arg0, arg1, arg2, arg3, arg4, arg5) \
+  __sanitizer_syscall_pre_impl_pselect6((long)(arg0), (long)(arg1),          \
+                                        (long)(arg2), (long)(arg3),          \
+                                        (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_post_pselect6(res, arg0, arg1, arg2, arg3, arg4, \
+                                          arg5)                              \
+  __sanitizer_syscall_post_impl_pselect6(res, (long)(arg0), (long)(arg1),    \
+                                         (long)(arg2), (long)(arg3),         \
+                                         (long)(arg4), (long)(arg5))
+#define __sanitizer_syscall_pre_ppoll(arg0, arg1, arg2, arg3, arg4)            \
+  __sanitizer_syscall_pre_impl_ppoll((long)(arg0), (long)(arg1), (long)(arg2), \
+                                     (long)(arg3), (long)(arg4))
+#define __sanitizer_syscall_post_ppoll(res, arg0, arg1, arg2, arg3, arg4) \
+  __sanitizer_syscall_post_impl_ppoll(res, (long)(arg0), (long)(arg1),    \
+                                      (long)(arg2), (long)(arg3),         \
+                                      (long)(arg4))
+#define __sanitizer_syscall_pre_syncfs(fd) \
+  __sanitizer_syscall_pre_impl_syncfs((long)(fd))
+#define __sanitizer_syscall_post_syncfs(res, fd) \
+  __sanitizer_syscall_post_impl_syncfs(res, (long)(fd))
+#define __sanitizer_syscall_pre_perf_event_open(attr_uptr, pid, cpu, group_fd, \
+                                                flags)                         \
+  __sanitizer_syscall_pre_impl_perf_event_open((long)(attr_uptr), (long)(pid), \
+                                               (long)(cpu), (long)(group_fd),  \
+                                               (long)(flags))
+#define __sanitizer_syscall_post_perf_event_open(res, attr_uptr, pid, cpu, \
+                                                 group_fd, flags)          \
+  __sanitizer_syscall_post_impl_perf_event_open(                           \
+      res, (long)(attr_uptr), (long)(pid), (long)(cpu), (long)(group_fd),  \
+      (long)(flags))
+#define __sanitizer_syscall_pre_mmap_pgoff(addr, len, prot, flags, fd, pgoff) \
+  __sanitizer_syscall_pre_impl_mmap_pgoff((long)(addr), (long)(len),          \
+                                          (long)(prot), (long)(flags),        \
+                                          (long)(fd), (long)(pgoff))
+#define __sanitizer_syscall_post_mmap_pgoff(res, addr, len, prot, flags, fd, \
+                                            pgoff)                           \
+  __sanitizer_syscall_post_impl_mmap_pgoff(res, (long)(addr), (long)(len),   \
+                                           (long)(prot), (long)(flags),      \
+                                           (long)(fd), (long)(pgoff))
+#define __sanitizer_syscall_pre_old_mmap(arg) \
+  __sanitizer_syscall_pre_impl_old_mmap((long)(arg))
+#define __sanitizer_syscall_post_old_mmap(res, arg) \
+  __sanitizer_syscall_post_impl_old_mmap(res, (long)(arg))
+#define __sanitizer_syscall_pre_name_to_handle_at(dfd, name, handle, mnt_id, \
+                                                  flag)                      \
+  __sanitizer_syscall_pre_impl_name_to_handle_at(                            \
+      (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id), (long)(flag))
+#define __sanitizer_syscall_post_name_to_handle_at(res, dfd, name, handle, \
+                                                   mnt_id, flag)           \
+  __sanitizer_syscall_post_impl_name_to_handle_at(                         \
+      res, (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id),      \
+      (long)(flag))
+#define __sanitizer_syscall_pre_open_by_handle_at(mountdirfd, handle, flags) \
+  __sanitizer_syscall_pre_impl_open_by_handle_at(                            \
+      (long)(mountdirfd), (long)(handle), (long)(flags))
+#define __sanitizer_syscall_post_open_by_handle_at(res, mountdirfd, handle, \
+                                                   flags)                   \
+  __sanitizer_syscall_post_impl_open_by_handle_at(                          \
+      res, (long)(mountdirfd), (long)(handle), (long)(flags))
+#define __sanitizer_syscall_pre_setns(fd, nstype) \
+  __sanitizer_syscall_pre_impl_setns((long)(fd), (long)(nstype))
+#define __sanitizer_syscall_post_setns(res, fd, nstype) \
+  __sanitizer_syscall_post_impl_setns(res, (long)(fd), (long)(nstype))
+#define __sanitizer_syscall_pre_process_vm_readv(pid, lvec, liovcnt, rvec, \
+                                                 riovcnt, flags)           \
+  __sanitizer_syscall_pre_impl_process_vm_readv(                           \
+      (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),            \
+      (long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_post_process_vm_readv(res, pid, lvec, liovcnt, \
+                                                  rvec, riovcnt, flags)    \
+  __sanitizer_syscall_post_impl_process_vm_readv(                          \
+      res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),       \
+      (long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_pre_process_vm_writev(pid, lvec, liovcnt, rvec, \
+                                                  riovcnt, flags)           \
+  __sanitizer_syscall_pre_impl_process_vm_writev(                           \
+      (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),             \
+      (long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_post_process_vm_writev(res, pid, lvec, liovcnt, \
+                                                   rvec, riovcnt, flags)    \
+  __sanitizer_syscall_post_impl_process_vm_writev(                          \
+      res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec),        \
+      (long)(riovcnt), (long)(flags))
+#define __sanitizer_syscall_pre_fork() \
+  __sanitizer_syscall_pre_impl_fork()
+#define __sanitizer_syscall_post_fork(res) \
+  __sanitizer_syscall_post_impl_fork(res)
+#define __sanitizer_syscall_pre_vfork() \
+  __sanitizer_syscall_pre_impl_vfork()
+#define __sanitizer_syscall_post_vfork(res) \
+  __sanitizer_syscall_post_impl_vfork(res)
+
+// And now a few syscalls we don't handle yet.
+#define __sanitizer_syscall_pre_afs_syscall(...)
+#define __sanitizer_syscall_pre_arch_prctl(...)
+#define __sanitizer_syscall_pre_break(...)
+#define __sanitizer_syscall_pre_chown32(...)
+#define __sanitizer_syscall_pre_clone(...)
+#define __sanitizer_syscall_pre_create_module(...)
+#define __sanitizer_syscall_pre_epoll_ctl_old(...)
+#define __sanitizer_syscall_pre_epoll_wait_old(...)
+#define __sanitizer_syscall_pre_execve(...)
+#define __sanitizer_syscall_pre_fadvise64(...)
+#define __sanitizer_syscall_pre_fadvise64_64(...)
+#define __sanitizer_syscall_pre_fallocate(...)
+#define __sanitizer_syscall_pre_fanotify_init(...)
+#define __sanitizer_syscall_pre_fanotify_mark(...)
+#define __sanitizer_syscall_pre_fchown32(...)
+#define __sanitizer_syscall_pre_ftime(...)
+#define __sanitizer_syscall_pre_ftruncate64(...)
+#define __sanitizer_syscall_pre_futex(...)
+#define __sanitizer_syscall_pre_getegid32(...)
+#define __sanitizer_syscall_pre_geteuid32(...)
+#define __sanitizer_syscall_pre_getgid32(...)
+#define __sanitizer_syscall_pre_getgroups32(...)
+#define __sanitizer_syscall_pre_get_kernel_syms(...)
+#define __sanitizer_syscall_pre_getpmsg(...)
+#define __sanitizer_syscall_pre_getresgid32(...)
+#define __sanitizer_syscall_pre_getresuid32(...)
+#define __sanitizer_syscall_pre_get_thread_area(...)
+#define __sanitizer_syscall_pre_getuid32(...)
+#define __sanitizer_syscall_pre_gtty(...)
+#define __sanitizer_syscall_pre_idle(...)
+#define __sanitizer_syscall_pre_iopl(...)
+#define __sanitizer_syscall_pre_lchown32(...)
+#define __sanitizer_syscall_pre__llseek(...)
+#define __sanitizer_syscall_pre_lock(...)
+#define __sanitizer_syscall_pre_madvise1(...)
+#define __sanitizer_syscall_pre_mmap(...)
+#define __sanitizer_syscall_pre_mmap2(...)
+#define __sanitizer_syscall_pre_modify_ldt(...)
+#define __sanitizer_syscall_pre_mpx(...)
+#define __sanitizer_syscall_pre__newselect(...)
+#define __sanitizer_syscall_pre_nfsservctl(...)
+#define __sanitizer_syscall_pre_oldfstat(...)
+#define __sanitizer_syscall_pre_oldlstat(...)
+#define __sanitizer_syscall_pre_oldolduname(...)
+#define __sanitizer_syscall_pre_oldstat(...)
+#define __sanitizer_syscall_pre_prctl(...)
+#define __sanitizer_syscall_pre_prof(...)
+#define __sanitizer_syscall_pre_profil(...)
+#define __sanitizer_syscall_pre_putpmsg(...)
+#define __sanitizer_syscall_pre_query_module(...)
+#define __sanitizer_syscall_pre_readahead(...)
+#define __sanitizer_syscall_pre_readdir(...)
+#define __sanitizer_syscall_pre_rt_sigaction(...)
+#define __sanitizer_syscall_pre_rt_sigreturn(...)
+#define __sanitizer_syscall_pre_rt_sigsuspend(...)
+#define __sanitizer_syscall_pre_security(...)
+#define __sanitizer_syscall_pre_setfsgid32(...)
+#define __sanitizer_syscall_pre_setfsuid32(...)
+#define __sanitizer_syscall_pre_setgid32(...)
+#define __sanitizer_syscall_pre_setgroups32(...)
+#define __sanitizer_syscall_pre_setregid32(...)
+#define __sanitizer_syscall_pre_setresgid32(...)
+#define __sanitizer_syscall_pre_setresuid32(...)
+#define __sanitizer_syscall_pre_setreuid32(...)
+#define __sanitizer_syscall_pre_set_thread_area(...)
+#define __sanitizer_syscall_pre_setuid32(...)
+#define __sanitizer_syscall_pre_sigaction(...)
+#define __sanitizer_syscall_pre_sigaltstack(...)
+#define __sanitizer_syscall_pre_sigreturn(...)
+#define __sanitizer_syscall_pre_sigsuspend(...)
+#define __sanitizer_syscall_pre_stty(...)
+#define __sanitizer_syscall_pre_sync_file_range(...)
+#define __sanitizer_syscall_pre__sysctl(...)
+#define __sanitizer_syscall_pre_truncate64(...)
+#define __sanitizer_syscall_pre_tuxcall(...)
+#define __sanitizer_syscall_pre_ugetrlimit(...)
+#define __sanitizer_syscall_pre_ulimit(...)
+#define __sanitizer_syscall_pre_umount2(...)
+#define __sanitizer_syscall_pre_vm86(...)
+#define __sanitizer_syscall_pre_vm86old(...)
+#define __sanitizer_syscall_pre_vserver(...)
+
+#define __sanitizer_syscall_post_afs_syscall(res, ...)
+#define __sanitizer_syscall_post_arch_prctl(res, ...)
+#define __sanitizer_syscall_post_break(res, ...)
+#define __sanitizer_syscall_post_chown32(res, ...)
+#define __sanitizer_syscall_post_clone(res, ...)
+#define __sanitizer_syscall_post_create_module(res, ...)
+#define __sanitizer_syscall_post_epoll_ctl_old(res, ...)
+#define __sanitizer_syscall_post_epoll_wait_old(res, ...)
+#define __sanitizer_syscall_post_execve(res, ...)
+#define __sanitizer_syscall_post_fadvise64(res, ...)
+#define __sanitizer_syscall_post_fadvise64_64(res, ...)
+#define __sanitizer_syscall_post_fallocate(res, ...)
+#define __sanitizer_syscall_post_fanotify_init(res, ...)
+#define __sanitizer_syscall_post_fanotify_mark(res, ...)
+#define __sanitizer_syscall_post_fchown32(res, ...)
+#define __sanitizer_syscall_post_ftime(res, ...)
+#define __sanitizer_syscall_post_ftruncate64(res, ...)
+#define __sanitizer_syscall_post_futex(res, ...)
+#define __sanitizer_syscall_post_getegid32(res, ...)
+#define __sanitizer_syscall_post_geteuid32(res, ...)
+#define __sanitizer_syscall_post_getgid32(res, ...)
+#define __sanitizer_syscall_post_getgroups32(res, ...)
+#define __sanitizer_syscall_post_get_kernel_syms(res, ...)
+#define __sanitizer_syscall_post_getpmsg(res, ...)
+#define __sanitizer_syscall_post_getresgid32(res, ...)
+#define __sanitizer_syscall_post_getresuid32(res, ...)
+#define __sanitizer_syscall_post_get_thread_area(res, ...)
+#define __sanitizer_syscall_post_getuid32(res, ...)
+#define __sanitizer_syscall_post_gtty(res, ...)
+#define __sanitizer_syscall_post_idle(res, ...)
+#define __sanitizer_syscall_post_iopl(res, ...)
+#define __sanitizer_syscall_post_lchown32(res, ...)
+#define __sanitizer_syscall_post__llseek(res, ...)
+#define __sanitizer_syscall_post_lock(res, ...)
+#define __sanitizer_syscall_post_madvise1(res, ...)
+#define __sanitizer_syscall_post_mmap2(res, ...)
+#define __sanitizer_syscall_post_mmap(res, ...)
+#define __sanitizer_syscall_post_modify_ldt(res, ...)
+#define __sanitizer_syscall_post_mpx(res, ...)
+#define __sanitizer_syscall_post__newselect(res, ...)
+#define __sanitizer_syscall_post_nfsservctl(res, ...)
+#define __sanitizer_syscall_post_oldfstat(res, ...)
+#define __sanitizer_syscall_post_oldlstat(res, ...)
+#define __sanitizer_syscall_post_oldolduname(res, ...)
+#define __sanitizer_syscall_post_oldstat(res, ...)
+#define __sanitizer_syscall_post_prctl(res, ...)
+#define __sanitizer_syscall_post_profil(res, ...)
+#define __sanitizer_syscall_post_prof(res, ...)
+#define __sanitizer_syscall_post_putpmsg(res, ...)
+#define __sanitizer_syscall_post_query_module(res, ...)
+#define __sanitizer_syscall_post_readahead(res, ...)
+#define __sanitizer_syscall_post_readdir(res, ...)
+#define __sanitizer_syscall_post_rt_sigaction(res, ...)
+#define __sanitizer_syscall_post_rt_sigreturn(res, ...)
+#define __sanitizer_syscall_post_rt_sigsuspend(res, ...)
+#define __sanitizer_syscall_post_security(res, ...)
+#define __sanitizer_syscall_post_setfsgid32(res, ...)
+#define __sanitizer_syscall_post_setfsuid32(res, ...)
+#define __sanitizer_syscall_post_setgid32(res, ...)
+#define __sanitizer_syscall_post_setgroups32(res, ...)
+#define __sanitizer_syscall_post_setregid32(res, ...)
+#define __sanitizer_syscall_post_setresgid32(res, ...)
+#define __sanitizer_syscall_post_setresuid32(res, ...)
+#define __sanitizer_syscall_post_setreuid32(res, ...)
+#define __sanitizer_syscall_post_set_thread_area(res, ...)
+#define __sanitizer_syscall_post_setuid32(res, ...)
+#define __sanitizer_syscall_post_sigaction(res, ...)
+#define __sanitizer_syscall_post_sigaltstack(res, ...)
+#define __sanitizer_syscall_post_sigreturn(res, ...)
+#define __sanitizer_syscall_post_sigsuspend(res, ...)
+#define __sanitizer_syscall_post_stty(res, ...)
+#define __sanitizer_syscall_post_sync_file_range(res, ...)
+#define __sanitizer_syscall_post__sysctl(res, ...)
+#define __sanitizer_syscall_post_truncate64(res, ...)
+#define __sanitizer_syscall_post_tuxcall(res, ...)
+#define __sanitizer_syscall_post_ugetrlimit(res, ...)
+#define __sanitizer_syscall_post_ulimit(res, ...)
+#define __sanitizer_syscall_post_umount2(res, ...)
+#define __sanitizer_syscall_post_vm86old(res, ...)
+#define __sanitizer_syscall_post_vm86(res, ...)
+#define __sanitizer_syscall_post_vserver(res, ...)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Private declarations. Do not call directly from user code. Use macros above.
+void __sanitizer_syscall_pre_impl_time(long tloc);
+void __sanitizer_syscall_post_impl_time(long res, long tloc);
+void __sanitizer_syscall_pre_impl_stime(long tptr);
+void __sanitizer_syscall_post_impl_stime(long res, long tptr);
+void __sanitizer_syscall_pre_impl_gettimeofday(long tv, long tz);
+void __sanitizer_syscall_post_impl_gettimeofday(long res, long tv, long tz);
+void __sanitizer_syscall_pre_impl_settimeofday(long tv, long tz);
+void __sanitizer_syscall_post_impl_settimeofday(long res, long tv, long tz);
+void __sanitizer_syscall_pre_impl_adjtimex(long txc_p);
+void __sanitizer_syscall_post_impl_adjtimex(long res, long txc_p);
+void __sanitizer_syscall_pre_impl_times(long tbuf);
+void __sanitizer_syscall_post_impl_times(long res, long tbuf);
+void __sanitizer_syscall_pre_impl_gettid();
+void __sanitizer_syscall_post_impl_gettid(long res);
+void __sanitizer_syscall_pre_impl_nanosleep(long rqtp, long rmtp);
+void __sanitizer_syscall_post_impl_nanosleep(long res, long rqtp, long rmtp);
+void __sanitizer_syscall_pre_impl_alarm(long seconds);
+void __sanitizer_syscall_post_impl_alarm(long res, long seconds);
+void __sanitizer_syscall_pre_impl_getpid();
+void __sanitizer_syscall_post_impl_getpid(long res);
+void __sanitizer_syscall_pre_impl_getppid();
+void __sanitizer_syscall_post_impl_getppid(long res);
+void __sanitizer_syscall_pre_impl_getuid();
+void __sanitizer_syscall_post_impl_getuid(long res);
+void __sanitizer_syscall_pre_impl_geteuid();
+void __sanitizer_syscall_post_impl_geteuid(long res);
+void __sanitizer_syscall_pre_impl_getgid();
+void __sanitizer_syscall_post_impl_getgid(long res);
+void __sanitizer_syscall_pre_impl_getegid();
+void __sanitizer_syscall_post_impl_getegid(long res);
+void __sanitizer_syscall_pre_impl_getresuid(long ruid, long euid, long suid);
+void __sanitizer_syscall_post_impl_getresuid(long res, long ruid, long euid,
+                                             long suid);
+void __sanitizer_syscall_pre_impl_getresgid(long rgid, long egid, long sgid);
+void __sanitizer_syscall_post_impl_getresgid(long res, long rgid, long egid,
+                                             long sgid);
+void __sanitizer_syscall_pre_impl_getpgid(long pid);
+void __sanitizer_syscall_post_impl_getpgid(long res, long pid);
+void __sanitizer_syscall_pre_impl_getpgrp();
+void __sanitizer_syscall_post_impl_getpgrp(long res);
+void __sanitizer_syscall_pre_impl_getsid(long pid);
+void __sanitizer_syscall_post_impl_getsid(long res, long pid);
+void __sanitizer_syscall_pre_impl_getgroups(long gidsetsize, long grouplist);
+void __sanitizer_syscall_post_impl_getgroups(long res, long gidsetsize,
+                                             long grouplist);
+void __sanitizer_syscall_pre_impl_setregid(long rgid, long egid);
+void __sanitizer_syscall_post_impl_setregid(long res, long rgid, long egid);
+void __sanitizer_syscall_pre_impl_setgid(long gid);
+void __sanitizer_syscall_post_impl_setgid(long res, long gid);
+void __sanitizer_syscall_pre_impl_setreuid(long ruid, long euid);
+void __sanitizer_syscall_post_impl_setreuid(long res, long ruid, long euid);
+void __sanitizer_syscall_pre_impl_setuid(long uid);
+void __sanitizer_syscall_post_impl_setuid(long res, long uid);
+void __sanitizer_syscall_pre_impl_setresuid(long ruid, long euid, long suid);
+void __sanitizer_syscall_post_impl_setresuid(long res, long ruid, long euid,
+                                             long suid);
+void __sanitizer_syscall_pre_impl_setresgid(long rgid, long egid, long sgid);
+void __sanitizer_syscall_post_impl_setresgid(long res, long rgid, long egid,
+                                             long sgid);
+void __sanitizer_syscall_pre_impl_setfsuid(long uid);
+void __sanitizer_syscall_post_impl_setfsuid(long res, long uid);
+void __sanitizer_syscall_pre_impl_setfsgid(long gid);
+void __sanitizer_syscall_post_impl_setfsgid(long res, long gid);
+void __sanitizer_syscall_pre_impl_setpgid(long pid, long pgid);
+void __sanitizer_syscall_post_impl_setpgid(long res, long pid, long pgid);
+void __sanitizer_syscall_pre_impl_setsid();
+void __sanitizer_syscall_post_impl_setsid(long res);
+void __sanitizer_syscall_pre_impl_setgroups(long gidsetsize, long grouplist);
+void __sanitizer_syscall_post_impl_setgroups(long res, long gidsetsize,
+                                             long grouplist);
+void __sanitizer_syscall_pre_impl_acct(long name);
+void __sanitizer_syscall_post_impl_acct(long res, long name);
+void __sanitizer_syscall_pre_impl_capget(long header, long dataptr);
+void __sanitizer_syscall_post_impl_capget(long res, long header, long dataptr);
+void __sanitizer_syscall_pre_impl_capset(long header, long data);
+void __sanitizer_syscall_post_impl_capset(long res, long header, long data);
+void __sanitizer_syscall_pre_impl_personality(long personality);
+void __sanitizer_syscall_post_impl_personality(long res, long personality);
+void __sanitizer_syscall_pre_impl_sigpending(long set);
+void __sanitizer_syscall_post_impl_sigpending(long res, long set);
+void __sanitizer_syscall_pre_impl_sigprocmask(long how, long set, long oset);
+void __sanitizer_syscall_post_impl_sigprocmask(long res, long how, long set,
+                                               long oset);
+void __sanitizer_syscall_pre_impl_getitimer(long which, long value);
+void __sanitizer_syscall_post_impl_getitimer(long res, long which, long value);
+void __sanitizer_syscall_pre_impl_setitimer(long which, long value,
+                                            long ovalue);
+void __sanitizer_syscall_post_impl_setitimer(long res, long which, long value,
+                                             long ovalue);
+void __sanitizer_syscall_pre_impl_timer_create(long which_clock,
+                                               long timer_event_spec,
+                                               long created_timer_id);
+void __sanitizer_syscall_post_impl_timer_create(long res, long which_clock,
+                                                long timer_event_spec,
+                                                long created_timer_id);
+void __sanitizer_syscall_pre_impl_timer_gettime(long timer_id, long setting);
+void __sanitizer_syscall_post_impl_timer_gettime(long res, long timer_id,
+                                                 long setting);
+void __sanitizer_syscall_pre_impl_timer_getoverrun(long timer_id);
+void __sanitizer_syscall_post_impl_timer_getoverrun(long res, long timer_id);
+void __sanitizer_syscall_pre_impl_timer_settime(long timer_id, long flags,
+                                                long new_setting,
+                                                long old_setting);
+void __sanitizer_syscall_post_impl_timer_settime(long res, long timer_id,
+                                                 long flags, long new_setting,
+                                                 long old_setting);
+void __sanitizer_syscall_pre_impl_timer_delete(long timer_id);
+void __sanitizer_syscall_post_impl_timer_delete(long res, long timer_id);
+void __sanitizer_syscall_pre_impl_clock_settime(long which_clock, long tp);
+void __sanitizer_syscall_post_impl_clock_settime(long res, long which_clock,
+                                                 long tp);
+void __sanitizer_syscall_pre_impl_clock_gettime(long which_clock, long tp);
+void __sanitizer_syscall_post_impl_clock_gettime(long res, long which_clock,
+                                                 long tp);
+void __sanitizer_syscall_pre_impl_clock_adjtime(long which_clock, long tx);
+void __sanitizer_syscall_post_impl_clock_adjtime(long res, long which_clock,
+                                                 long tx);
+void __sanitizer_syscall_pre_impl_clock_getres(long which_clock, long tp);
+void __sanitizer_syscall_post_impl_clock_getres(long res, long which_clock,
+                                                long tp);
+void __sanitizer_syscall_pre_impl_clock_nanosleep(long which_clock, long flags,
+                                                  long rqtp, long rmtp);
+void __sanitizer_syscall_post_impl_clock_nanosleep(long res, long which_clock,
+                                                   long flags, long rqtp,
+                                                   long rmtp);
+void __sanitizer_syscall_pre_impl_nice(long increment);
+void __sanitizer_syscall_post_impl_nice(long res, long increment);
+void __sanitizer_syscall_pre_impl_sched_setscheduler(long pid, long policy,
+                                                     long param);
+void __sanitizer_syscall_post_impl_sched_setscheduler(long res, long pid,
+                                                      long policy, long param);
+void __sanitizer_syscall_pre_impl_sched_setparam(long pid, long param);
+void __sanitizer_syscall_post_impl_sched_setparam(long res, long pid,
+                                                  long param);
+void __sanitizer_syscall_pre_impl_sched_getscheduler(long pid);
+void __sanitizer_syscall_post_impl_sched_getscheduler(long res, long pid);
+void __sanitizer_syscall_pre_impl_sched_getparam(long pid, long param);
+void __sanitizer_syscall_post_impl_sched_getparam(long res, long pid,
+                                                  long param);
+void __sanitizer_syscall_pre_impl_sched_setaffinity(long pid, long len,
+                                                    long user_mask_ptr);
+void __sanitizer_syscall_post_impl_sched_setaffinity(long res, long pid,
+                                                     long len,
+                                                     long user_mask_ptr);
+void __sanitizer_syscall_pre_impl_sched_getaffinity(long pid, long len,
+                                                    long user_mask_ptr);
+void __sanitizer_syscall_post_impl_sched_getaffinity(long res, long pid,
+                                                     long len,
+                                                     long user_mask_ptr);
+void __sanitizer_syscall_pre_impl_sched_yield();
+void __sanitizer_syscall_post_impl_sched_yield(long res);
+void __sanitizer_syscall_pre_impl_sched_get_priority_max(long policy);
+void __sanitizer_syscall_post_impl_sched_get_priority_max(long res,
+                                                          long policy);
+void __sanitizer_syscall_pre_impl_sched_get_priority_min(long policy);
+void __sanitizer_syscall_post_impl_sched_get_priority_min(long res,
+                                                          long policy);
+void __sanitizer_syscall_pre_impl_sched_rr_get_interval(long pid,
+                                                        long interval);
+void __sanitizer_syscall_post_impl_sched_rr_get_interval(long res, long pid,
+                                                         long interval);
+void __sanitizer_syscall_pre_impl_setpriority(long which, long who,
+                                              long niceval);
+void __sanitizer_syscall_post_impl_setpriority(long res, long which, long who,
+                                               long niceval);
+void __sanitizer_syscall_pre_impl_getpriority(long which, long who);
+void __sanitizer_syscall_post_impl_getpriority(long res, long which, long who);
+void __sanitizer_syscall_pre_impl_shutdown(long arg0, long arg1);
+void __sanitizer_syscall_post_impl_shutdown(long res, long arg0, long arg1);
+void __sanitizer_syscall_pre_impl_reboot(long magic1, long magic2, long cmd,
+                                         long arg);
+void __sanitizer_syscall_post_impl_reboot(long res, long magic1, long magic2,
+                                          long cmd, long arg);
+void __sanitizer_syscall_pre_impl_restart_syscall();
+void __sanitizer_syscall_post_impl_restart_syscall(long res);
+void __sanitizer_syscall_pre_impl_kexec_load(long entry, long nr_segments,
+                                             long segments, long flags);
+void __sanitizer_syscall_post_impl_kexec_load(long res, long entry,
+                                              long nr_segments, long segments,
+                                              long flags);
+void __sanitizer_syscall_pre_impl_exit(long error_code);
+void __sanitizer_syscall_post_impl_exit(long res, long error_code);
+void __sanitizer_syscall_pre_impl_exit_group(long error_code);
+void __sanitizer_syscall_post_impl_exit_group(long res, long error_code);
+void __sanitizer_syscall_pre_impl_wait4(long pid, long stat_addr, long options,
+                                        long ru);
+void __sanitizer_syscall_post_impl_wait4(long res, long pid, long stat_addr,
+                                         long options, long ru);
+void __sanitizer_syscall_pre_impl_waitid(long which, long pid, long infop,
+                                         long options, long ru);
+void __sanitizer_syscall_post_impl_waitid(long res, long which, long pid,
+                                          long infop, long options, long ru);
+void __sanitizer_syscall_pre_impl_waitpid(long pid, long stat_addr,
+                                          long options);
+void __sanitizer_syscall_post_impl_waitpid(long res, long pid, long stat_addr,
+                                           long options);
+void __sanitizer_syscall_pre_impl_set_tid_address(long tidptr);
+void __sanitizer_syscall_post_impl_set_tid_address(long res, long tidptr);
+void __sanitizer_syscall_pre_impl_init_module(long umod, long len, long uargs);
+void __sanitizer_syscall_post_impl_init_module(long res, long umod, long len,
+                                               long uargs);
+void __sanitizer_syscall_pre_impl_delete_module(long name_user, long flags);
+void __sanitizer_syscall_post_impl_delete_module(long res, long name_user,
+                                                 long flags);
+void __sanitizer_syscall_pre_impl_rt_sigprocmask(long how, long set, long oset,
+                                                 long sigsetsize);
+void __sanitizer_syscall_post_impl_rt_sigprocmask(long res, long how, long set,
+                                                  long oset, long sigsetsize);
+void __sanitizer_syscall_pre_impl_rt_sigpending(long set, long sigsetsize);
+void __sanitizer_syscall_post_impl_rt_sigpending(long res, long set,
+                                                 long sigsetsize);
+void __sanitizer_syscall_pre_impl_rt_sigtimedwait(long uthese, long uinfo,
+                                                  long uts, long sigsetsize);
+void __sanitizer_syscall_post_impl_rt_sigtimedwait(long res, long uthese,
+                                                   long uinfo, long uts,
+                                                   long sigsetsize);
+void __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo(long tgid, long pid,
+                                                    long sig, long uinfo);
+void __sanitizer_syscall_post_impl_rt_tgsigqueueinfo(long res, long tgid,
+                                                     long pid, long sig,
+                                                     long uinfo);
+void __sanitizer_syscall_pre_impl_kill(long pid, long sig);
+void __sanitizer_syscall_post_impl_kill(long res, long pid, long sig);
+void __sanitizer_syscall_pre_impl_tgkill(long tgid, long pid, long sig);
+void __sanitizer_syscall_post_impl_tgkill(long res, long tgid, long pid,
+                                          long sig);
+void __sanitizer_syscall_pre_impl_tkill(long pid, long sig);
+void __sanitizer_syscall_post_impl_tkill(long res, long pid, long sig);
+void __sanitizer_syscall_pre_impl_rt_sigqueueinfo(long pid, long sig,
+                                                  long uinfo);
+void __sanitizer_syscall_post_impl_rt_sigqueueinfo(long res, long pid, long sig,
+                                                   long uinfo);
+void __sanitizer_syscall_pre_impl_sgetmask();
+void __sanitizer_syscall_post_impl_sgetmask(long res);
+void __sanitizer_syscall_pre_impl_ssetmask(long newmask);
+void __sanitizer_syscall_post_impl_ssetmask(long res, long newmask);
+void __sanitizer_syscall_pre_impl_signal(long sig, long handler);
+void __sanitizer_syscall_post_impl_signal(long res, long sig, long handler);
+void __sanitizer_syscall_pre_impl_pause();
+void __sanitizer_syscall_post_impl_pause(long res);
+void __sanitizer_syscall_pre_impl_sync();
+void __sanitizer_syscall_post_impl_sync(long res);
+void __sanitizer_syscall_pre_impl_fsync(long fd);
+void __sanitizer_syscall_post_impl_fsync(long res, long fd);
+void __sanitizer_syscall_pre_impl_fdatasync(long fd);
+void __sanitizer_syscall_post_impl_fdatasync(long res, long fd);
+void __sanitizer_syscall_pre_impl_bdflush(long func, long data);
+void __sanitizer_syscall_post_impl_bdflush(long res, long func, long data);
+void __sanitizer_syscall_pre_impl_mount(long dev_name, long dir_name, long type,
+                                        long flags, long data);
+void __sanitizer_syscall_post_impl_mount(long res, long dev_name, long dir_name,
+                                         long type, long flags, long data);
+void __sanitizer_syscall_pre_impl_umount(long name, long flags);
+void __sanitizer_syscall_post_impl_umount(long res, long name, long flags);
+void __sanitizer_syscall_pre_impl_oldumount(long name);
+void __sanitizer_syscall_post_impl_oldumount(long res, long name);
+void __sanitizer_syscall_pre_impl_truncate(long path, long length);
+void __sanitizer_syscall_post_impl_truncate(long res, long path, long length);
+void __sanitizer_syscall_pre_impl_ftruncate(long fd, long length);
+void __sanitizer_syscall_post_impl_ftruncate(long res, long fd, long length);
+void __sanitizer_syscall_pre_impl_stat(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_stat(long res, long filename, long statbuf);
+void __sanitizer_syscall_pre_impl_statfs(long path, long buf);
+void __sanitizer_syscall_post_impl_statfs(long res, long path, long buf);
+void __sanitizer_syscall_pre_impl_statfs64(long path, long sz, long buf);
+void __sanitizer_syscall_post_impl_statfs64(long res, long path, long sz,
+                                            long buf);
+void __sanitizer_syscall_pre_impl_fstatfs(long fd, long buf);
+void __sanitizer_syscall_post_impl_fstatfs(long res, long fd, long buf);
+void __sanitizer_syscall_pre_impl_fstatfs64(long fd, long sz, long buf);
+void __sanitizer_syscall_post_impl_fstatfs64(long res, long fd, long sz,
+                                             long buf);
+void __sanitizer_syscall_pre_impl_lstat(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_lstat(long res, long filename, long statbuf);
+void __sanitizer_syscall_pre_impl_fstat(long fd, long statbuf);
+void __sanitizer_syscall_post_impl_fstat(long res, long fd, long statbuf);
+void __sanitizer_syscall_pre_impl_newstat(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_newstat(long res, long filename,
+                                           long statbuf);
+void __sanitizer_syscall_pre_impl_newlstat(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_newlstat(long res, long filename,
+                                            long statbuf);
+void __sanitizer_syscall_pre_impl_newfstat(long fd, long statbuf);
+void __sanitizer_syscall_post_impl_newfstat(long res, long fd, long statbuf);
+void __sanitizer_syscall_pre_impl_ustat(long dev, long ubuf);
+void __sanitizer_syscall_post_impl_ustat(long res, long dev, long ubuf);
+void __sanitizer_syscall_pre_impl_stat64(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_stat64(long res, long filename,
+                                          long statbuf);
+void __sanitizer_syscall_pre_impl_fstat64(long fd, long statbuf);
+void __sanitizer_syscall_post_impl_fstat64(long res, long fd, long statbuf);
+void __sanitizer_syscall_pre_impl_lstat64(long filename, long statbuf);
+void __sanitizer_syscall_post_impl_lstat64(long res, long filename,
+                                           long statbuf);
+void __sanitizer_syscall_pre_impl_setxattr(long path, long name, long value,
+                                           long size, long flags);
+void __sanitizer_syscall_post_impl_setxattr(long res, long path, long name,
+                                            long value, long size, long flags);
+void __sanitizer_syscall_pre_impl_lsetxattr(long path, long name, long value,
+                                            long size, long flags);
+void __sanitizer_syscall_post_impl_lsetxattr(long res, long path, long name,
+                                             long value, long size, long flags);
+void __sanitizer_syscall_pre_impl_fsetxattr(long fd, long name, long value,
+                                            long size, long flags);
+void __sanitizer_syscall_post_impl_fsetxattr(long res, long fd, long name,
+                                             long value, long size, long flags);
+void __sanitizer_syscall_pre_impl_getxattr(long path, long name, long value,
+                                           long size);
+void __sanitizer_syscall_post_impl_getxattr(long res, long path, long name,
+                                            long value, long size);
+void __sanitizer_syscall_pre_impl_lgetxattr(long path, long name, long value,
+                                            long size);
+void __sanitizer_syscall_post_impl_lgetxattr(long res, long path, long name,
+                                             long value, long size);
+void __sanitizer_syscall_pre_impl_fgetxattr(long fd, long name, long value,
+                                            long size);
+void __sanitizer_syscall_post_impl_fgetxattr(long res, long fd, long name,
+                                             long value, long size);
+void __sanitizer_syscall_pre_impl_listxattr(long path, long list, long size);
+void __sanitizer_syscall_post_impl_listxattr(long res, long path, long list,
+                                             long size);
+void __sanitizer_syscall_pre_impl_llistxattr(long path, long list, long size);
+void __sanitizer_syscall_post_impl_llistxattr(long res, long path, long list,
+                                              long size);
+void __sanitizer_syscall_pre_impl_flistxattr(long fd, long list, long size);
+void __sanitizer_syscall_post_impl_flistxattr(long res, long fd, long list,
+                                              long size);
+void __sanitizer_syscall_pre_impl_removexattr(long path, long name);
+void __sanitizer_syscall_post_impl_removexattr(long res, long path, long name);
+void __sanitizer_syscall_pre_impl_lremovexattr(long path, long name);
+void __sanitizer_syscall_post_impl_lremovexattr(long res, long path, long name);
+void __sanitizer_syscall_pre_impl_fremovexattr(long fd, long name);
+void __sanitizer_syscall_post_impl_fremovexattr(long res, long fd, long name);
+void __sanitizer_syscall_pre_impl_brk(long brk);
+void __sanitizer_syscall_post_impl_brk(long res, long brk);
+void __sanitizer_syscall_pre_impl_mprotect(long start, long len, long prot);
+void __sanitizer_syscall_post_impl_mprotect(long res, long start, long len,
+                                            long prot);
+void __sanitizer_syscall_pre_impl_mremap(long addr, long old_len, long new_len,
+                                         long flags, long new_addr);
+void __sanitizer_syscall_post_impl_mremap(long res, long addr, long old_len,
+                                          long new_len, long flags,
+                                          long new_addr);
+void __sanitizer_syscall_pre_impl_remap_file_pages(long start, long size,
+                                                   long prot, long pgoff,
+                                                   long flags);
+void __sanitizer_syscall_post_impl_remap_file_pages(long res, long start,
+                                                    long size, long prot,
+                                                    long pgoff, long flags);
+void __sanitizer_syscall_pre_impl_msync(long start, long len, long flags);
+void __sanitizer_syscall_post_impl_msync(long res, long start, long len,
+                                         long flags);
+void __sanitizer_syscall_pre_impl_munmap(long addr, long len);
+void __sanitizer_syscall_post_impl_munmap(long res, long addr, long len);
+void __sanitizer_syscall_pre_impl_mlock(long start, long len);
+void __sanitizer_syscall_post_impl_mlock(long res, long start, long len);
+void __sanitizer_syscall_pre_impl_munlock(long start, long len);
+void __sanitizer_syscall_post_impl_munlock(long res, long start, long len);
+void __sanitizer_syscall_pre_impl_mlockall(long flags);
+void __sanitizer_syscall_post_impl_mlockall(long res, long flags);
+void __sanitizer_syscall_pre_impl_munlockall();
+void __sanitizer_syscall_post_impl_munlockall(long res);
+void __sanitizer_syscall_pre_impl_madvise(long start, long len, long behavior);
+void __sanitizer_syscall_post_impl_madvise(long res, long start, long len,
+                                           long behavior);
+void __sanitizer_syscall_pre_impl_mincore(long start, long len, long vec);
+void __sanitizer_syscall_post_impl_mincore(long res, long start, long len,
+                                           long vec);
+void __sanitizer_syscall_pre_impl_pivot_root(long new_root, long put_old);
+void __sanitizer_syscall_post_impl_pivot_root(long res, long new_root,
+                                              long put_old);
+void __sanitizer_syscall_pre_impl_chroot(long filename);
+void __sanitizer_syscall_post_impl_chroot(long res, long filename);
+void __sanitizer_syscall_pre_impl_mknod(long filename, long mode, long dev);
+void __sanitizer_syscall_post_impl_mknod(long res, long filename, long mode,
+                                         long dev);
+void __sanitizer_syscall_pre_impl_link(long oldname, long newname);
+void __sanitizer_syscall_post_impl_link(long res, long oldname, long newname);
+void __sanitizer_syscall_pre_impl_symlink(long old, long new_);
+void __sanitizer_syscall_post_impl_symlink(long res, long old, long new_);
+void __sanitizer_syscall_pre_impl_unlink(long pathname);
+void __sanitizer_syscall_post_impl_unlink(long res, long pathname);
+void __sanitizer_syscall_pre_impl_rename(long oldname, long newname);
+void __sanitizer_syscall_post_impl_rename(long res, long oldname, long newname);
+void __sanitizer_syscall_pre_impl_chmod(long filename, long mode);
+void __sanitizer_syscall_post_impl_chmod(long res, long filename, long mode);
+void __sanitizer_syscall_pre_impl_fchmod(long fd, long mode);
+void __sanitizer_syscall_post_impl_fchmod(long res, long fd, long mode);
+void __sanitizer_syscall_pre_impl_fcntl(long fd, long cmd, long arg);
+void __sanitizer_syscall_post_impl_fcntl(long res, long fd, long cmd, long arg);
+void __sanitizer_syscall_pre_impl_fcntl64(long fd, long cmd, long arg);
+void __sanitizer_syscall_post_impl_fcntl64(long res, long fd, long cmd,
+                                           long arg);
+void __sanitizer_syscall_pre_impl_pipe(long fildes);
+void __sanitizer_syscall_post_impl_pipe(long res, long fildes);
+void __sanitizer_syscall_pre_impl_pipe2(long fildes, long flags);
+void __sanitizer_syscall_post_impl_pipe2(long res, long fildes, long flags);
+void __sanitizer_syscall_pre_impl_dup(long fildes);
+void __sanitizer_syscall_post_impl_dup(long res, long fildes);
+void __sanitizer_syscall_pre_impl_dup2(long oldfd, long newfd);
+void __sanitizer_syscall_post_impl_dup2(long res, long oldfd, long newfd);
+void __sanitizer_syscall_pre_impl_dup3(long oldfd, long newfd, long flags);
+void __sanitizer_syscall_post_impl_dup3(long res, long oldfd, long newfd,
+                                        long flags);
+void __sanitizer_syscall_pre_impl_ioperm(long from, long num, long on);
+void __sanitizer_syscall_post_impl_ioperm(long res, long from, long num,
+                                          long on);
+void __sanitizer_syscall_pre_impl_ioctl(long fd, long cmd, long arg);
+void __sanitizer_syscall_post_impl_ioctl(long res, long fd, long cmd, long arg);
+void __sanitizer_syscall_pre_impl_flock(long fd, long cmd);
+void __sanitizer_syscall_post_impl_flock(long res, long fd, long cmd);
+void __sanitizer_syscall_pre_impl_io_setup(long nr_reqs, long ctx);
+void __sanitizer_syscall_post_impl_io_setup(long res, long nr_reqs, long ctx);
+void __sanitizer_syscall_pre_impl_io_destroy(long ctx);
+void __sanitizer_syscall_post_impl_io_destroy(long res, long ctx);
+void __sanitizer_syscall_pre_impl_io_getevents(long ctx_id, long min_nr,
+                                               long nr, long events,
+                                               long timeout);
+void __sanitizer_syscall_post_impl_io_getevents(long res, long ctx_id,
+                                                long min_nr, long nr,
+                                                long events, long timeout);
+void __sanitizer_syscall_pre_impl_io_submit(long ctx_id, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_io_submit(long res, long ctx_id, long arg1,
+                                             long arg2);
+void __sanitizer_syscall_pre_impl_io_cancel(long ctx_id, long iocb,
+                                            long result);
+void __sanitizer_syscall_post_impl_io_cancel(long res, long ctx_id, long iocb,
+                                             long result);
+void __sanitizer_syscall_pre_impl_sendfile(long out_fd, long in_fd, long offset,
+                                           long count);
+void __sanitizer_syscall_post_impl_sendfile(long res, long out_fd, long in_fd,
+                                            long offset, long count);
+void __sanitizer_syscall_pre_impl_sendfile64(long out_fd, long in_fd,
+                                             long offset, long count);
+void __sanitizer_syscall_post_impl_sendfile64(long res, long out_fd, long in_fd,
+                                              long offset, long count);
+void __sanitizer_syscall_pre_impl_readlink(long path, long buf, long bufsiz);
+void __sanitizer_syscall_post_impl_readlink(long res, long path, long buf,
+                                            long bufsiz);
+void __sanitizer_syscall_pre_impl_creat(long pathname, long mode);
+void __sanitizer_syscall_post_impl_creat(long res, long pathname, long mode);
+void __sanitizer_syscall_pre_impl_open(long filename, long flags, long mode);
+void __sanitizer_syscall_post_impl_open(long res, long filename, long flags,
+                                        long mode);
+void __sanitizer_syscall_pre_impl_close(long fd);
+void __sanitizer_syscall_post_impl_close(long res, long fd);
+void __sanitizer_syscall_pre_impl_access(long filename, long mode);
+void __sanitizer_syscall_post_impl_access(long res, long filename, long mode);
+void __sanitizer_syscall_pre_impl_vhangup();
+void __sanitizer_syscall_post_impl_vhangup(long res);
+void __sanitizer_syscall_pre_impl_chown(long filename, long user, long group);
+void __sanitizer_syscall_post_impl_chown(long res, long filename, long user,
+                                         long group);
+void __sanitizer_syscall_pre_impl_lchown(long filename, long user, long group);
+void __sanitizer_syscall_post_impl_lchown(long res, long filename, long user,
+                                          long group);
+void __sanitizer_syscall_pre_impl_fchown(long fd, long user, long group);
+void __sanitizer_syscall_post_impl_fchown(long res, long fd, long user,
+                                          long group);
+void __sanitizer_syscall_pre_impl_chown16(long filename, long user, long group);
+void __sanitizer_syscall_post_impl_chown16(long res, long filename, long user,
+                                           long group);
+void __sanitizer_syscall_pre_impl_lchown16(long filename, long user,
+                                           long group);
+void __sanitizer_syscall_post_impl_lchown16(long res, long filename, long user,
+                                            long group);
+void __sanitizer_syscall_pre_impl_fchown16(long fd, long user, long group);
+void __sanitizer_syscall_post_impl_fchown16(long res, long fd, long user,
+                                            long group);
+void __sanitizer_syscall_pre_impl_setregid16(long rgid, long egid);
+void __sanitizer_syscall_post_impl_setregid16(long res, long rgid, long egid);
+void __sanitizer_syscall_pre_impl_setgid16(long gid);
+void __sanitizer_syscall_post_impl_setgid16(long res, long gid);
+void __sanitizer_syscall_pre_impl_setreuid16(long ruid, long euid);
+void __sanitizer_syscall_post_impl_setreuid16(long res, long ruid, long euid);
+void __sanitizer_syscall_pre_impl_setuid16(long uid);
+void __sanitizer_syscall_post_impl_setuid16(long res, long uid);
+void __sanitizer_syscall_pre_impl_setresuid16(long ruid, long euid, long suid);
+void __sanitizer_syscall_post_impl_setresuid16(long res, long ruid, long euid,
+                                               long suid);
+void __sanitizer_syscall_pre_impl_getresuid16(long ruid, long euid, long suid);
+void __sanitizer_syscall_post_impl_getresuid16(long res, long ruid, long euid,
+                                               long suid);
+void __sanitizer_syscall_pre_impl_setresgid16(long rgid, long egid, long sgid);
+void __sanitizer_syscall_post_impl_setresgid16(long res, long rgid, long egid,
+                                               long sgid);
+void __sanitizer_syscall_pre_impl_getresgid16(long rgid, long egid, long sgid);
+void __sanitizer_syscall_post_impl_getresgid16(long res, long rgid, long egid,
+                                               long sgid);
+void __sanitizer_syscall_pre_impl_setfsuid16(long uid);
+void __sanitizer_syscall_post_impl_setfsuid16(long res, long uid);
+void __sanitizer_syscall_pre_impl_setfsgid16(long gid);
+void __sanitizer_syscall_post_impl_setfsgid16(long res, long gid);
+void __sanitizer_syscall_pre_impl_getgroups16(long gidsetsize, long grouplist);
+void __sanitizer_syscall_post_impl_getgroups16(long res, long gidsetsize,
+                                               long grouplist);
+void __sanitizer_syscall_pre_impl_setgroups16(long gidsetsize, long grouplist);
+void __sanitizer_syscall_post_impl_setgroups16(long res, long gidsetsize,
+                                               long grouplist);
+void __sanitizer_syscall_pre_impl_getuid16();
+void __sanitizer_syscall_post_impl_getuid16(long res);
+void __sanitizer_syscall_pre_impl_geteuid16();
+void __sanitizer_syscall_post_impl_geteuid16(long res);
+void __sanitizer_syscall_pre_impl_getgid16();
+void __sanitizer_syscall_post_impl_getgid16(long res);
+void __sanitizer_syscall_pre_impl_getegid16();
+void __sanitizer_syscall_post_impl_getegid16(long res);
+void __sanitizer_syscall_pre_impl_utime(long filename, long times);
+void __sanitizer_syscall_post_impl_utime(long res, long filename, long times);
+void __sanitizer_syscall_pre_impl_utimes(long filename, long utimes);
+void __sanitizer_syscall_post_impl_utimes(long res, long filename, long utimes);
+void __sanitizer_syscall_pre_impl_lseek(long fd, long offset, long origin);
+void __sanitizer_syscall_post_impl_lseek(long res, long fd, long offset,
+                                         long origin);
+void __sanitizer_syscall_pre_impl_llseek(long fd, long offset_high,
+                                         long offset_low, long result,
+                                         long origin);
+void __sanitizer_syscall_post_impl_llseek(long res, long fd, long offset_high,
+                                          long offset_low, long result,
+                                          long origin);
+void __sanitizer_syscall_pre_impl_read(long fd, long buf, long count);
+void __sanitizer_syscall_post_impl_read(long res, long fd, long buf,
+                                        long count);
+void __sanitizer_syscall_pre_impl_readv(long fd, long vec, long vlen);
+void __sanitizer_syscall_post_impl_readv(long res, long fd, long vec,
+                                         long vlen);
+void __sanitizer_syscall_pre_impl_write(long fd, long buf, long count);
+void __sanitizer_syscall_post_impl_write(long res, long fd, long buf,
+                                         long count);
+void __sanitizer_syscall_pre_impl_writev(long fd, long vec, long vlen);
+void __sanitizer_syscall_post_impl_writev(long res, long fd, long vec,
+                                          long vlen);
+
+#ifdef _LP64
+void __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count,
+                                          long pos);
+void __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf,
+                                           long count, long pos);
+void __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count,
+                                           long pos);
+void __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf,
+                                            long count, long pos);
+#else
+void __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count,
+                                          long pos0, long pos1);
+void __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf,
+                                           long count, long pos0, long pos1);
+void __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count,
+                                           long pos0, long pos1);
+void __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf,
+                                            long count, long pos0, long pos1);
+#endif
+
+void __sanitizer_syscall_pre_impl_preadv(long fd, long vec, long vlen,
+                                         long pos_l, long pos_h);
+void __sanitizer_syscall_post_impl_preadv(long res, long fd, long vec,
+                                          long vlen, long pos_l, long pos_h);
+void __sanitizer_syscall_pre_impl_pwritev(long fd, long vec, long vlen,
+                                          long pos_l, long pos_h);
+void __sanitizer_syscall_post_impl_pwritev(long res, long fd, long vec,
+                                           long vlen, long pos_l, long pos_h);
+void __sanitizer_syscall_pre_impl_getcwd(long buf, long size);
+void __sanitizer_syscall_post_impl_getcwd(long res, long buf, long size);
+void __sanitizer_syscall_pre_impl_mkdir(long pathname, long mode);
+void __sanitizer_syscall_post_impl_mkdir(long res, long pathname, long mode);
+void __sanitizer_syscall_pre_impl_chdir(long filename);
+void __sanitizer_syscall_post_impl_chdir(long res, long filename);
+void __sanitizer_syscall_pre_impl_fchdir(long fd);
+void __sanitizer_syscall_post_impl_fchdir(long res, long fd);
+void __sanitizer_syscall_pre_impl_rmdir(long pathname);
+void __sanitizer_syscall_post_impl_rmdir(long res, long pathname);
+void __sanitizer_syscall_pre_impl_lookup_dcookie(long cookie64, long buf,
+                                                 long len);
+void __sanitizer_syscall_post_impl_lookup_dcookie(long res, long cookie64,
+                                                  long buf, long len);
+void __sanitizer_syscall_pre_impl_quotactl(long cmd, long special, long id,
+                                           long addr);
+void __sanitizer_syscall_post_impl_quotactl(long res, long cmd, long special,
+                                            long id, long addr);
+void __sanitizer_syscall_pre_impl_getdents(long fd, long dirent, long count);
+void __sanitizer_syscall_post_impl_getdents(long res, long fd, long dirent,
+                                            long count);
+void __sanitizer_syscall_pre_impl_getdents64(long fd, long dirent, long count);
+void __sanitizer_syscall_post_impl_getdents64(long res, long fd, long dirent,
+                                              long count);
+void __sanitizer_syscall_pre_impl_setsockopt(long fd, long level, long optname,
+                                             long optval, long optlen);
+void __sanitizer_syscall_post_impl_setsockopt(long res, long fd, long level,
+                                              long optname, long optval,
+                                              long optlen);
+void __sanitizer_syscall_pre_impl_getsockopt(long fd, long level, long optname,
+                                             long optval, long optlen);
+void __sanitizer_syscall_post_impl_getsockopt(long res, long fd, long level,
+                                              long optname, long optval,
+                                              long optlen);
+void __sanitizer_syscall_pre_impl_bind(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_bind(long res, long arg0, long arg1,
+                                        long arg2);
+void __sanitizer_syscall_pre_impl_connect(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_connect(long res, long arg0, long arg1,
+                                           long arg2);
+void __sanitizer_syscall_pre_impl_accept(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_accept(long res, long arg0, long arg1,
+                                          long arg2);
+void __sanitizer_syscall_pre_impl_accept4(long arg0, long arg1, long arg2,
+                                          long arg3);
+void __sanitizer_syscall_post_impl_accept4(long res, long arg0, long arg1,
+                                           long arg2, long arg3);
+void __sanitizer_syscall_pre_impl_getsockname(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_getsockname(long res, long arg0, long arg1,
+                                               long arg2);
+void __sanitizer_syscall_pre_impl_getpeername(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_getpeername(long res, long arg0, long arg1,
+                                               long arg2);
+void __sanitizer_syscall_pre_impl_send(long arg0, long arg1, long arg2,
+                                       long arg3);
+void __sanitizer_syscall_post_impl_send(long res, long arg0, long arg1,
+                                        long arg2, long arg3);
+void __sanitizer_syscall_pre_impl_sendto(long arg0, long arg1, long arg2,
+                                         long arg3, long arg4, long arg5);
+void __sanitizer_syscall_post_impl_sendto(long res, long arg0, long arg1,
+                                          long arg2, long arg3, long arg4,
+                                          long arg5);
+void __sanitizer_syscall_pre_impl_sendmsg(long fd, long msg, long flags);
+void __sanitizer_syscall_post_impl_sendmsg(long res, long fd, long msg,
+                                           long flags);
+void __sanitizer_syscall_pre_impl_sendmmsg(long fd, long msg, long vlen,
+                                           long flags);
+void __sanitizer_syscall_post_impl_sendmmsg(long res, long fd, long msg,
+                                            long vlen, long flags);
+void __sanitizer_syscall_pre_impl_recv(long arg0, long arg1, long arg2,
+                                       long arg3);
+void __sanitizer_syscall_post_impl_recv(long res, long arg0, long arg1,
+                                        long arg2, long arg3);
+void __sanitizer_syscall_pre_impl_recvfrom(long arg0, long arg1, long arg2,
+                                           long arg3, long arg4, long arg5);
+void __sanitizer_syscall_post_impl_recvfrom(long res, long arg0, long arg1,
+                                            long arg2, long arg3, long arg4,
+                                            long arg5);
+void __sanitizer_syscall_pre_impl_recvmsg(long fd, long msg, long flags);
+void __sanitizer_syscall_post_impl_recvmsg(long res, long fd, long msg,
+                                           long flags);
+void __sanitizer_syscall_pre_impl_recvmmsg(long fd, long msg, long vlen,
+                                           long flags, long timeout);
+void __sanitizer_syscall_post_impl_recvmmsg(long res, long fd, long msg,
+                                            long vlen, long flags,
+                                            long timeout);
+void __sanitizer_syscall_pre_impl_socket(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_socket(long res, long arg0, long arg1,
+                                          long arg2);
+void __sanitizer_syscall_pre_impl_socketpair(long arg0, long arg1, long arg2,
+                                             long arg3);
+void __sanitizer_syscall_post_impl_socketpair(long res, long arg0, long arg1,
+                                              long arg2, long arg3);
+void __sanitizer_syscall_pre_impl_socketcall(long call, long args);
+void __sanitizer_syscall_post_impl_socketcall(long res, long call, long args);
+void __sanitizer_syscall_pre_impl_listen(long arg0, long arg1);
+void __sanitizer_syscall_post_impl_listen(long res, long arg0, long arg1);
+void __sanitizer_syscall_pre_impl_poll(long ufds, long nfds, long timeout);
+void __sanitizer_syscall_post_impl_poll(long res, long ufds, long nfds,
+                                        long timeout);
+void __sanitizer_syscall_pre_impl_select(long n, long inp, long outp, long exp,
+                                         long tvp);
+void __sanitizer_syscall_post_impl_select(long res, long n, long inp, long outp,
+                                          long exp, long tvp);
+void __sanitizer_syscall_pre_impl_old_select(long arg);
+void __sanitizer_syscall_post_impl_old_select(long res, long arg);
+void __sanitizer_syscall_pre_impl_epoll_create(long size);
+void __sanitizer_syscall_post_impl_epoll_create(long res, long size);
+void __sanitizer_syscall_pre_impl_epoll_create1(long flags);
+void __sanitizer_syscall_post_impl_epoll_create1(long res, long flags);
+void __sanitizer_syscall_pre_impl_epoll_ctl(long epfd, long op, long fd,
+                                            long event);
+void __sanitizer_syscall_post_impl_epoll_ctl(long res, long epfd, long op,
+                                             long fd, long event);
+void __sanitizer_syscall_pre_impl_epoll_wait(long epfd, long events,
+                                             long maxevents, long timeout);
+void __sanitizer_syscall_post_impl_epoll_wait(long res, long epfd, long events,
+                                              long maxevents, long timeout);
+void __sanitizer_syscall_pre_impl_epoll_pwait(long epfd, long events,
+                                              long maxevents, long timeout,
+                                              long sigmask, long sigsetsize);
+void __sanitizer_syscall_post_impl_epoll_pwait(long res, long epfd, long events,
+                                               long maxevents, long timeout,
+                                               long sigmask, long sigsetsize);
+void __sanitizer_syscall_pre_impl_gethostname(long name, long len);
+void __sanitizer_syscall_post_impl_gethostname(long res, long name, long len);
+void __sanitizer_syscall_pre_impl_sethostname(long name, long len);
+void __sanitizer_syscall_post_impl_sethostname(long res, long name, long len);
+void __sanitizer_syscall_pre_impl_setdomainname(long name, long len);
+void __sanitizer_syscall_post_impl_setdomainname(long res, long name, long len);
+void __sanitizer_syscall_pre_impl_newuname(long name);
+void __sanitizer_syscall_post_impl_newuname(long res, long name);
+void __sanitizer_syscall_pre_impl_uname(long arg0);
+void __sanitizer_syscall_post_impl_uname(long res, long arg0);
+void __sanitizer_syscall_pre_impl_olduname(long arg0);
+void __sanitizer_syscall_post_impl_olduname(long res, long arg0);
+void __sanitizer_syscall_pre_impl_getrlimit(long resource, long rlim);
+void __sanitizer_syscall_post_impl_getrlimit(long res, long resource,
+                                             long rlim);
+void __sanitizer_syscall_pre_impl_old_getrlimit(long resource, long rlim);
+void __sanitizer_syscall_post_impl_old_getrlimit(long res, long resource,
+                                                 long rlim);
+void __sanitizer_syscall_pre_impl_setrlimit(long resource, long rlim);
+void __sanitizer_syscall_post_impl_setrlimit(long res, long resource,
+                                             long rlim);
+void __sanitizer_syscall_pre_impl_prlimit64(long pid, long resource,
+                                            long new_rlim, long old_rlim);
+void __sanitizer_syscall_post_impl_prlimit64(long res, long pid, long resource,
+                                             long new_rlim, long old_rlim);
+void __sanitizer_syscall_pre_impl_getrusage(long who, long ru);
+void __sanitizer_syscall_post_impl_getrusage(long res, long who, long ru);
+void __sanitizer_syscall_pre_impl_umask(long mask);
+void __sanitizer_syscall_post_impl_umask(long res, long mask);
+void __sanitizer_syscall_pre_impl_msgget(long key, long msgflg);
+void __sanitizer_syscall_post_impl_msgget(long res, long key, long msgflg);
+void __sanitizer_syscall_pre_impl_msgsnd(long msqid, long msgp, long msgsz,
+                                         long msgflg);
+void __sanitizer_syscall_post_impl_msgsnd(long res, long msqid, long msgp,
+                                          long msgsz, long msgflg);
+void __sanitizer_syscall_pre_impl_msgrcv(long msqid, long msgp, long msgsz,
+                                         long msgtyp, long msgflg);
+void __sanitizer_syscall_post_impl_msgrcv(long res, long msqid, long msgp,
+                                          long msgsz, long msgtyp, long msgflg);
+void __sanitizer_syscall_pre_impl_msgctl(long msqid, long cmd, long buf);
+void __sanitizer_syscall_post_impl_msgctl(long res, long msqid, long cmd,
+                                          long buf);
+void __sanitizer_syscall_pre_impl_semget(long key, long nsems, long semflg);
+void __sanitizer_syscall_post_impl_semget(long res, long key, long nsems,
+                                          long semflg);
+void __sanitizer_syscall_pre_impl_semop(long semid, long sops, long nsops);
+void __sanitizer_syscall_post_impl_semop(long res, long semid, long sops,
+                                         long nsops);
+void __sanitizer_syscall_pre_impl_semctl(long semid, long semnum, long cmd,
+                                         long arg);
+void __sanitizer_syscall_post_impl_semctl(long res, long semid, long semnum,
+                                          long cmd, long arg);
+void __sanitizer_syscall_pre_impl_semtimedop(long semid, long sops, long nsops,
+                                             long timeout);
+void __sanitizer_syscall_post_impl_semtimedop(long res, long semid, long sops,
+                                              long nsops, long timeout);
+void __sanitizer_syscall_pre_impl_shmat(long shmid, long shmaddr, long shmflg);
+void __sanitizer_syscall_post_impl_shmat(long res, long shmid, long shmaddr,
+                                         long shmflg);
+void __sanitizer_syscall_pre_impl_shmget(long key, long size, long flag);
+void __sanitizer_syscall_post_impl_shmget(long res, long key, long size,
+                                          long flag);
+void __sanitizer_syscall_pre_impl_shmdt(long shmaddr);
+void __sanitizer_syscall_post_impl_shmdt(long res, long shmaddr);
+void __sanitizer_syscall_pre_impl_shmctl(long shmid, long cmd, long buf);
+void __sanitizer_syscall_post_impl_shmctl(long res, long shmid, long cmd,
+                                          long buf);
+void __sanitizer_syscall_pre_impl_ipc(long call, long first, long second,
+                                      long third, long ptr, long fifth);
+void __sanitizer_syscall_post_impl_ipc(long res, long call, long first,
+                                       long second, long third, long ptr,
+                                       long fifth);
+void __sanitizer_syscall_pre_impl_mq_open(long name, long oflag, long mode,
+                                          long attr);
+void __sanitizer_syscall_post_impl_mq_open(long res, long name, long oflag,
+                                           long mode, long attr);
+void __sanitizer_syscall_pre_impl_mq_unlink(long name);
+void __sanitizer_syscall_post_impl_mq_unlink(long res, long name);
+void __sanitizer_syscall_pre_impl_mq_timedsend(long mqdes, long msg_ptr,
+                                               long msg_len, long msg_prio,
+                                               long abs_timeout);
+void __sanitizer_syscall_post_impl_mq_timedsend(long res, long mqdes,
+                                                long msg_ptr, long msg_len,
+                                                long msg_prio,
+                                                long abs_timeout);
+void __sanitizer_syscall_pre_impl_mq_timedreceive(long mqdes, long msg_ptr,
+                                                  long msg_len, long msg_prio,
+                                                  long abs_timeout);
+void __sanitizer_syscall_post_impl_mq_timedreceive(long res, long mqdes,
+                                                   long msg_ptr, long msg_len,
+                                                   long msg_prio,
+                                                   long abs_timeout);
+void __sanitizer_syscall_pre_impl_mq_notify(long mqdes, long notification);
+void __sanitizer_syscall_post_impl_mq_notify(long res, long mqdes,
+                                             long notification);
+void __sanitizer_syscall_pre_impl_mq_getsetattr(long mqdes, long mqstat,
+                                                long omqstat);
+void __sanitizer_syscall_post_impl_mq_getsetattr(long res, long mqdes,
+                                                 long mqstat, long omqstat);
+void __sanitizer_syscall_pre_impl_pciconfig_iobase(long which, long bus,
+                                                   long devfn);
+void __sanitizer_syscall_post_impl_pciconfig_iobase(long res, long which,
+                                                    long bus, long devfn);
+void __sanitizer_syscall_pre_impl_pciconfig_read(long bus, long dfn, long off,
+                                                 long len, long buf);
+void __sanitizer_syscall_post_impl_pciconfig_read(long res, long bus, long dfn,
+                                                  long off, long len, long buf);
+void __sanitizer_syscall_pre_impl_pciconfig_write(long bus, long dfn, long off,
+                                                  long len, long buf);
+void __sanitizer_syscall_post_impl_pciconfig_write(long res, long bus, long dfn,
+                                                   long off, long len,
+                                                   long buf);
+void __sanitizer_syscall_pre_impl_swapon(long specialfile, long swap_flags);
+void __sanitizer_syscall_post_impl_swapon(long res, long specialfile,
+                                          long swap_flags);
+void __sanitizer_syscall_pre_impl_swapoff(long specialfile);
+void __sanitizer_syscall_post_impl_swapoff(long res, long specialfile);
+void __sanitizer_syscall_pre_impl_sysctl(long args);
+void __sanitizer_syscall_post_impl_sysctl(long res, long args);
+void __sanitizer_syscall_pre_impl_sysinfo(long info);
+void __sanitizer_syscall_post_impl_sysinfo(long res, long info);
+void __sanitizer_syscall_pre_impl_sysfs(long option, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_sysfs(long res, long option, long arg1,
+                                         long arg2);
+void __sanitizer_syscall_pre_impl_syslog(long type, long buf, long len);
+void __sanitizer_syscall_post_impl_syslog(long res, long type, long buf,
+                                          long len);
+void __sanitizer_syscall_pre_impl_uselib(long library);
+void __sanitizer_syscall_post_impl_uselib(long res, long library);
+void __sanitizer_syscall_pre_impl_ni_syscall();
+void __sanitizer_syscall_post_impl_ni_syscall(long res);
+void __sanitizer_syscall_pre_impl_ptrace(long request, long pid, long addr,
+                                         long data);
+void __sanitizer_syscall_post_impl_ptrace(long res, long request, long pid,
+                                          long addr, long data);
+void __sanitizer_syscall_pre_impl_add_key(long _type, long _description,
+                                          long _payload, long plen,
+                                          long destringid);
+void __sanitizer_syscall_post_impl_add_key(long res, long _type,
+                                           long _description, long _payload,
+                                           long plen, long destringid);
+void __sanitizer_syscall_pre_impl_request_key(long _type, long _description,
+                                              long _callout_info,
+                                              long destringid);
+void __sanitizer_syscall_post_impl_request_key(long res, long _type,
+                                               long _description,
+                                               long _callout_info,
+                                               long destringid);
+void __sanitizer_syscall_pre_impl_keyctl(long cmd, long arg2, long arg3,
+                                         long arg4, long arg5);
+void __sanitizer_syscall_post_impl_keyctl(long res, long cmd, long arg2,
+                                          long arg3, long arg4, long arg5);
+void __sanitizer_syscall_pre_impl_ioprio_set(long which, long who, long ioprio);
+void __sanitizer_syscall_post_impl_ioprio_set(long res, long which, long who,
+                                              long ioprio);
+void __sanitizer_syscall_pre_impl_ioprio_get(long which, long who);
+void __sanitizer_syscall_post_impl_ioprio_get(long res, long which, long who);
+void __sanitizer_syscall_pre_impl_set_mempolicy(long mode, long nmask,
+                                                long maxnode);
+void __sanitizer_syscall_post_impl_set_mempolicy(long res, long mode,
+                                                 long nmask, long maxnode);
+void __sanitizer_syscall_pre_impl_migrate_pages(long pid, long maxnode,
+                                                long from, long to);
+void __sanitizer_syscall_post_impl_migrate_pages(long res, long pid,
+                                                 long maxnode, long from,
+                                                 long to);
+void __sanitizer_syscall_pre_impl_move_pages(long pid, long nr_pages,
+                                             long pages, long nodes,
+                                             long status, long flags);
+void __sanitizer_syscall_post_impl_move_pages(long res, long pid, long nr_pages,
+                                              long pages, long nodes,
+                                              long status, long flags);
+void __sanitizer_syscall_pre_impl_mbind(long start, long len, long mode,
+                                        long nmask, long maxnode, long flags);
+void __sanitizer_syscall_post_impl_mbind(long res, long start, long len,
+                                         long mode, long nmask, long maxnode,
+                                         long flags);
+void __sanitizer_syscall_pre_impl_get_mempolicy(long policy, long nmask,
+                                                long maxnode, long addr,
+                                                long flags);
+void __sanitizer_syscall_post_impl_get_mempolicy(long res, long policy,
+                                                 long nmask, long maxnode,
+                                                 long addr, long flags);
+void __sanitizer_syscall_pre_impl_inotify_init();
+void __sanitizer_syscall_post_impl_inotify_init(long res);
+void __sanitizer_syscall_pre_impl_inotify_init1(long flags);
+void __sanitizer_syscall_post_impl_inotify_init1(long res, long flags);
+void __sanitizer_syscall_pre_impl_inotify_add_watch(long fd, long path,
+                                                    long mask);
+void __sanitizer_syscall_post_impl_inotify_add_watch(long res, long fd,
+                                                     long path, long mask);
+void __sanitizer_syscall_pre_impl_inotify_rm_watch(long fd, long wd);
+void __sanitizer_syscall_post_impl_inotify_rm_watch(long res, long fd, long wd);
+void __sanitizer_syscall_pre_impl_spu_run(long fd, long unpc, long ustatus);
+void __sanitizer_syscall_post_impl_spu_run(long res, long fd, long unpc,
+                                           long ustatus);
+void __sanitizer_syscall_pre_impl_spu_create(long name, long flags, long mode,
+                                             long fd);
+void __sanitizer_syscall_post_impl_spu_create(long res, long name, long flags,
+                                              long mode, long fd);
+void __sanitizer_syscall_pre_impl_mknodat(long dfd, long filename, long mode,
+                                          long dev);
+void __sanitizer_syscall_post_impl_mknodat(long res, long dfd, long filename,
+                                           long mode, long dev);
+void __sanitizer_syscall_pre_impl_mkdirat(long dfd, long pathname, long mode);
+void __sanitizer_syscall_post_impl_mkdirat(long res, long dfd, long pathname,
+                                           long mode);
+void __sanitizer_syscall_pre_impl_unlinkat(long dfd, long pathname, long flag);
+void __sanitizer_syscall_post_impl_unlinkat(long res, long dfd, long pathname,
+                                            long flag);
+void __sanitizer_syscall_pre_impl_symlinkat(long oldname, long newdfd,
+                                            long newname);
+void __sanitizer_syscall_post_impl_symlinkat(long res, long oldname,
+                                             long newdfd, long newname);
+void __sanitizer_syscall_pre_impl_linkat(long olddfd, long oldname, long newdfd,
+                                         long newname, long flags);
+void __sanitizer_syscall_post_impl_linkat(long res, long olddfd, long oldname,
+                                          long newdfd, long newname,
+                                          long flags);
+void __sanitizer_syscall_pre_impl_renameat(long olddfd, long oldname,
+                                           long newdfd, long newname);
+void __sanitizer_syscall_post_impl_renameat(long res, long olddfd, long oldname,
+                                            long newdfd, long newname);
+void __sanitizer_syscall_pre_impl_futimesat(long dfd, long filename,
+                                            long utimes);
+void __sanitizer_syscall_post_impl_futimesat(long res, long dfd, long filename,
+                                             long utimes);
+void __sanitizer_syscall_pre_impl_faccessat(long dfd, long filename, long mode);
+void __sanitizer_syscall_post_impl_faccessat(long res, long dfd, long filename,
+                                             long mode);
+void __sanitizer_syscall_pre_impl_fchmodat(long dfd, long filename, long mode);
+void __sanitizer_syscall_post_impl_fchmodat(long res, long dfd, long filename,
+                                            long mode);
+void __sanitizer_syscall_pre_impl_fchownat(long dfd, long filename, long user,
+                                           long group, long flag);
+void __sanitizer_syscall_post_impl_fchownat(long res, long dfd, long filename,
+                                            long user, long group, long flag);
+void __sanitizer_syscall_pre_impl_openat(long dfd, long filename, long flags,
+                                         long mode);
+void __sanitizer_syscall_post_impl_openat(long res, long dfd, long filename,
+                                          long flags, long mode);
+void __sanitizer_syscall_pre_impl_newfstatat(long dfd, long filename,
+                                             long statbuf, long flag);
+void __sanitizer_syscall_post_impl_newfstatat(long res, long dfd, long filename,
+                                              long statbuf, long flag);
+void __sanitizer_syscall_pre_impl_fstatat64(long dfd, long filename,
+                                            long statbuf, long flag);
+void __sanitizer_syscall_post_impl_fstatat64(long res, long dfd, long filename,
+                                             long statbuf, long flag);
+void __sanitizer_syscall_pre_impl_readlinkat(long dfd, long path, long buf,
+                                             long bufsiz);
+void __sanitizer_syscall_post_impl_readlinkat(long res, long dfd, long path,
+                                              long buf, long bufsiz);
+void __sanitizer_syscall_pre_impl_utimensat(long dfd, long filename,
+                                            long utimes, long flags);
+void __sanitizer_syscall_post_impl_utimensat(long res, long dfd, long filename,
+                                             long utimes, long flags);
+void __sanitizer_syscall_pre_impl_unshare(long unshare_flags);
+void __sanitizer_syscall_post_impl_unshare(long res, long unshare_flags);
+void __sanitizer_syscall_pre_impl_splice(long fd_in, long off_in, long fd_out,
+                                         long off_out, long len, long flags);
+void __sanitizer_syscall_post_impl_splice(long res, long fd_in, long off_in,
+                                          long fd_out, long off_out, long len,
+                                          long flags);
+void __sanitizer_syscall_pre_impl_vmsplice(long fd, long iov, long nr_segs,
+                                           long flags);
+void __sanitizer_syscall_post_impl_vmsplice(long res, long fd, long iov,
+                                            long nr_segs, long flags);
+void __sanitizer_syscall_pre_impl_tee(long fdin, long fdout, long len,
+                                      long flags);
+void __sanitizer_syscall_post_impl_tee(long res, long fdin, long fdout,
+                                       long len, long flags);
+void __sanitizer_syscall_pre_impl_get_robust_list(long pid, long head_ptr,
+                                                  long len_ptr);
+void __sanitizer_syscall_post_impl_get_robust_list(long res, long pid,
+                                                   long head_ptr, long len_ptr);
+void __sanitizer_syscall_pre_impl_set_robust_list(long head, long len);
+void __sanitizer_syscall_post_impl_set_robust_list(long res, long head,
+                                                   long len);
+void __sanitizer_syscall_pre_impl_getcpu(long cpu, long node, long cache);
+void __sanitizer_syscall_post_impl_getcpu(long res, long cpu, long node,
+                                          long cache);
+void __sanitizer_syscall_pre_impl_signalfd(long ufd, long user_mask,
+                                           long sizemask);
+void __sanitizer_syscall_post_impl_signalfd(long res, long ufd, long user_mask,
+                                            long sizemask);
+void __sanitizer_syscall_pre_impl_signalfd4(long ufd, long user_mask,
+                                            long sizemask, long flags);
+void __sanitizer_syscall_post_impl_signalfd4(long res, long ufd, long user_mask,
+                                             long sizemask, long flags);
+void __sanitizer_syscall_pre_impl_timerfd_create(long clockid, long flags);
+void __sanitizer_syscall_post_impl_timerfd_create(long res, long clockid,
+                                                  long flags);
+void __sanitizer_syscall_pre_impl_timerfd_settime(long ufd, long flags,
+                                                  long utmr, long otmr);
+void __sanitizer_syscall_post_impl_timerfd_settime(long res, long ufd,
+                                                   long flags, long utmr,
+                                                   long otmr);
+void __sanitizer_syscall_pre_impl_timerfd_gettime(long ufd, long otmr);
+void __sanitizer_syscall_post_impl_timerfd_gettime(long res, long ufd,
+                                                   long otmr);
+void __sanitizer_syscall_pre_impl_eventfd(long count);
+void __sanitizer_syscall_post_impl_eventfd(long res, long count);
+void __sanitizer_syscall_pre_impl_eventfd2(long count, long flags);
+void __sanitizer_syscall_post_impl_eventfd2(long res, long count, long flags);
+void __sanitizer_syscall_pre_impl_old_readdir(long arg0, long arg1, long arg2);
+void __sanitizer_syscall_post_impl_old_readdir(long res, long arg0, long arg1,
+                                               long arg2);
+void __sanitizer_syscall_pre_impl_pselect6(long arg0, long arg1, long arg2,
+                                           long arg3, long arg4, long arg5);
+void __sanitizer_syscall_post_impl_pselect6(long res, long arg0, long arg1,
+                                            long arg2, long arg3, long arg4,
+                                            long arg5);
+void __sanitizer_syscall_pre_impl_ppoll(long arg0, long arg1, long arg2,
+                                        long arg3, long arg4);
+void __sanitizer_syscall_post_impl_ppoll(long res, long arg0, long arg1,
+                                         long arg2, long arg3, long arg4);
+void __sanitizer_syscall_pre_impl_fanotify_init(long flags, long event_f_flags);
+void __sanitizer_syscall_post_impl_fanotify_init(long res, long flags,
+                                                 long event_f_flags);
+void __sanitizer_syscall_pre_impl_fanotify_mark(long fanotify_fd, long flags,
+                                                long mask, long fd,
+                                                long pathname);
+void __sanitizer_syscall_post_impl_fanotify_mark(long res, long fanotify_fd,
+                                                 long flags, long mask, long fd,
+                                                 long pathname);
+void __sanitizer_syscall_pre_impl_syncfs(long fd);
+void __sanitizer_syscall_post_impl_syncfs(long res, long fd);
+void __sanitizer_syscall_pre_impl_perf_event_open(long attr_uptr, long pid,
+                                                  long cpu, long group_fd,
+                                                  long flags);
+void __sanitizer_syscall_post_impl_perf_event_open(long res, long attr_uptr,
+                                                   long pid, long cpu,
+                                                   long group_fd, long flags);
+void __sanitizer_syscall_pre_impl_mmap_pgoff(long addr, long len, long prot,
+                                             long flags, long fd, long pgoff);
+void __sanitizer_syscall_post_impl_mmap_pgoff(long res, long addr, long len,
+                                              long prot, long flags, long fd,
+                                              long pgoff);
+void __sanitizer_syscall_pre_impl_old_mmap(long arg);
+void __sanitizer_syscall_post_impl_old_mmap(long res, long arg);
+void __sanitizer_syscall_pre_impl_name_to_handle_at(long dfd, long name,
+                                                    long handle, long mnt_id,
+                                                    long flag);
+void __sanitizer_syscall_post_impl_name_to_handle_at(long res, long dfd,
+                                                     long name, long handle,
+                                                     long mnt_id, long flag);
+void __sanitizer_syscall_pre_impl_open_by_handle_at(long mountdirfd,
+                                                    long handle, long flags);
+void __sanitizer_syscall_post_impl_open_by_handle_at(long res, long mountdirfd,
+                                                     long handle, long flags);
+void __sanitizer_syscall_pre_impl_setns(long fd, long nstype);
+void __sanitizer_syscall_post_impl_setns(long res, long fd, long nstype);
+void __sanitizer_syscall_pre_impl_process_vm_readv(long pid, long lvec,
+                                                   long liovcnt, long rvec,
+                                                   long riovcnt, long flags);
+void __sanitizer_syscall_post_impl_process_vm_readv(long res, long pid,
+                                                    long lvec, long liovcnt,
+                                                    long rvec, long riovcnt,
+                                                    long flags);
+void __sanitizer_syscall_pre_impl_process_vm_writev(long pid, long lvec,
+                                                    long liovcnt, long rvec,
+                                                    long riovcnt, long flags);
+void __sanitizer_syscall_post_impl_process_vm_writev(long res, long pid,
+                                                     long lvec, long liovcnt,
+                                                     long rvec, long riovcnt,
+                                                     long flags);
+void __sanitizer_syscall_pre_impl_fork();
+void __sanitizer_syscall_post_impl_fork(long res);
+void __sanitizer_syscall_pre_impl_vfork();
+void __sanitizer_syscall_post_impl_vfork(long res);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // SANITIZER_LINUX_SYSCALL_HOOKS_H
diff --git a/lib/clang/3.5.2/include/sanitizer/lsan_interface.h b/lib/clang/3.5.2/include/sanitizer/lsan_interface.h
new file mode 100644
index 0000000..46d2668
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/lsan_interface.h
@@ -0,0 +1,73 @@
+//===-- sanitizer/lsan_interface.h ------------------------------*- 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 a part of LeakSanitizer.
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_LSAN_INTERFACE_H
+#define SANITIZER_LSAN_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  // Allocations made between calls to __lsan_disable() and __lsan_enable() will
+  // be treated as non-leaks. Disable/enable pairs may be nested.
+  void __lsan_disable();
+  void __lsan_enable();
+
+  // The heap object into which p points will be treated as a non-leak.
+  void __lsan_ignore_object(const void *p);
+
+  // Memory regions registered through this interface will be treated as sources
+  // of live pointers during leak checking. Useful if you store pointers in
+  // mapped memory.
+  // Points of note:
+  // - __lsan_unregister_root_region() must be called with the same pointer and
+  // size that have earlier been passed to __lsan_register_root_region()
+  // - LSan will skip any inaccessible memory when scanning a root region. E.g.,
+  // if you map memory within a larger region that you have mprotect'ed, you can
+  // register the entire large region.
+  // - the implementation is not optimized for performance. This interface is
+  // intended to be used for a small number of relatively static regions.
+  void __lsan_register_root_region(const void *p, size_t size);
+  void __lsan_unregister_root_region(const void *p, size_t size);
+
+  // Calling this function makes LSan enter the leak checking phase immediately.
+  // Use this if normal end-of-process leak checking happens too late (e.g. if
+  // you have intentional memory leaks in your shutdown code). Calling this
+  // function overrides end-of-process leak checking; it must be called at
+  // most once per process. This function will terminate the process if there
+  // are memory leaks and the exit_code flag is non-zero.
+  void __lsan_do_leak_check();
+
+  // The user may optionally provide this function to disallow leak checking
+  // for the program it is linked into (if the return value is non-zero). This
+  // function must be defined as returning a constant value; any behavior beyond
+  // that is unsupported.
+  int __lsan_is_turned_off();
+
+  // This function may be optionally provided by the user and should return
+  // a string containing LSan suppressions.
+  const char *__lsan_default_suppressions();
+#ifdef __cplusplus
+}  // extern "C"
+
+namespace __lsan {
+class ScopedDisabler {
+ public:
+  ScopedDisabler() { __lsan_disable(); }
+  ~ScopedDisabler() { __lsan_enable(); }
+};
+}  // namespace __lsan
+#endif
+
+#endif  // SANITIZER_LSAN_INTERFACE_H
diff --git a/lib/clang/3.5.2/include/sanitizer/msan_interface.h b/lib/clang/3.5.2/include/sanitizer/msan_interface.h
new file mode 100644
index 0000000..f6a62be
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/msan_interface.h
@@ -0,0 +1,154 @@
+//===-- msan_interface.h --------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of MemorySanitizer.
+//
+// Public interface header.
+//===----------------------------------------------------------------------===//
+#ifndef MSAN_INTERFACE_H
+#define MSAN_INTERFACE_H
+
+#include <sanitizer/common_interface_defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  /* Set raw origin for the memory range. */
+  void __msan_set_origin(const volatile void *a, size_t size, uint32_t origin);
+
+  /* Get raw origin for an address. */
+  uint32_t __msan_get_origin(const volatile void *a);
+
+  /* Returns non-zero if tracking origins. */
+  int __msan_get_track_origins();
+
+  /* Returns the origin id of the latest UMR in the calling thread. */
+  uint32_t __msan_get_umr_origin();
+
+  /* Make memory region fully initialized (without changing its contents). */
+  void __msan_unpoison(const volatile void *a, size_t size);
+
+  /* Make a null-terminated string fully initialized (without changing its
+     contents). */
+  void __msan_unpoison_string(const volatile char *a);
+
+  /* Make memory region fully uninitialized (without changing its contents). */
+  void __msan_poison(const volatile void *a, size_t size);
+
+  /* Make memory region partially uninitialized (without changing its contents).
+   */
+  void __msan_partial_poison(const volatile void *data, void *shadow,
+                             size_t size);
+
+  /* Returns the offset of the first (at least partially) poisoned byte in the
+     memory range, or -1 if the whole range is good. */
+  intptr_t __msan_test_shadow(const volatile void *x, size_t size);
+
+  /* Checks that memory range is fully initialized, and reports an error if it
+   * is not. */
+  void __msan_check_mem_is_initialized(const volatile void *x, size_t size);
+
+  /* Set exit code when error(s) were detected.
+     Value of 0 means don't change the program exit code. */
+  void __msan_set_exit_code(int exit_code);
+
+  /* For testing:
+     __msan_set_expect_umr(1);
+     ... some buggy code ...
+     __msan_set_expect_umr(0);
+     The last line will verify that a UMR happened. */
+  void __msan_set_expect_umr(int expect_umr);
+
+  /* Change the value of keep_going flag. Non-zero value means don't terminate
+     program execution when an error is detected. This will not affect error in
+     modules that were compiled without the corresponding compiler flag. */
+  void __msan_set_keep_going(int keep_going);
+
+  /* Print shadow and origin for the memory range to stderr in a human-readable
+     format. */
+  void __msan_print_shadow(const volatile void *x, size_t size);
+
+  /* Print shadow for the memory range to stderr in a minimalistic
+     human-readable format. */
+  void __msan_dump_shadow(const volatile void *x, size_t size);
+
+  /* Returns true if running under a dynamic tool (DynamoRio-based). */
+  int  __msan_has_dynamic_component();
+
+  /* Tell MSan about newly allocated memory (ex.: custom allocator).
+     Memory will be marked uninitialized, with origin at the call site. */
+  void __msan_allocated_memory(const volatile void* data, size_t size);
+
+  /* This function may be optionally provided by user and should return
+     a string containing Msan runtime options. See msan_flags.h for details. */
+  const char* __msan_default_options();
+
+  /* Sets the callback to be called right before death on error.
+     Passing 0 will unset the callback. */
+  void __msan_set_death_callback(void (*callback)(void));
+
+  /***********************************/
+  /* Allocator statistics interface. */
+
+  /* Returns the estimated number of bytes that will be reserved by allocator
+     for request of "size" bytes. If Msan allocator can't allocate that much
+     memory, returns the maximal possible allocation size, otherwise returns
+     "size". */
+  /* DEPRECATED: Use __sanitizer_get_estimated_allocated_size instead. */
+  size_t __msan_get_estimated_allocated_size(size_t size);
+
+  /* Returns true if p was returned by the Msan allocator and
+     is not yet freed. */
+  /* DEPRECATED: Use __sanitizer_get_ownership instead. */
+  int __msan_get_ownership(const volatile void *p);
+
+  /* Returns the number of bytes reserved for the pointer p.
+     Requires (get_ownership(p) == true) or (p == 0). */
+  /* DEPRECATED: Use __sanitizer_get_allocated_size instead. */
+  size_t __msan_get_allocated_size(const volatile void *p);
+
+  /* Number of bytes, allocated and not yet freed by the application. */
+  /* DEPRECATED: Use __sanitizer_get_current_allocated_bytes instead. */
+  size_t __msan_get_current_allocated_bytes();
+
+  /* Number of bytes, mmaped by msan allocator to fulfill allocation requests.
+     Generally, for request of X bytes, allocator can reserve and add to free
+     lists a large number of chunks of size X to use them for future requests.
+     All these chunks count toward the heap size. Currently, allocator never
+     releases memory to OS (instead, it just puts freed chunks to free
+     lists). */
+  /* DEPRECATED: Use __sanitizer_get_heap_size instead. */
+  size_t __msan_get_heap_size();
+
+  /* Number of bytes, mmaped by msan allocator, which can be used to fulfill
+     allocation requests. When a user program frees memory chunk, it can first
+     fall into quarantine and will count toward __msan_get_free_bytes()
+     later. */
+  /* DEPRECATED: Use __sanitizer_get_free_bytes instead. */
+  size_t __msan_get_free_bytes();
+
+  /* Number of bytes in unmapped pages, that are released to OS. Currently,
+     always returns 0. */
+  /* DEPRECATED: Use __sanitizer_get_unmapped_bytes instead. */
+  size_t __msan_get_unmapped_bytes();
+
+  /* Malloc hooks that may be optionally provided by user.
+     __msan_malloc_hook(ptr, size) is called immediately after
+       allocation of "size" bytes, which returned "ptr".
+     __msan_free_hook(ptr) is called immediately before
+       deallocation of "ptr". */
+  /* DEPRECATED: Use __sanitizer_malloc_hook / __sanitizer_free_hook instead. */
+  void __msan_malloc_hook(const volatile void *ptr, size_t size);
+  void __msan_free_hook(const volatile void *ptr);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/lib/clang/3.5.2/include/sanitizer/tsan_interface_atomic.h b/lib/clang/3.5.2/include/sanitizer/tsan_interface_atomic.h
new file mode 100644
index 0000000..4ea77d2
--- /dev/null
+++ b/lib/clang/3.5.2/include/sanitizer/tsan_interface_atomic.h
@@ -0,0 +1,222 @@
+//===-- tsan_interface_atomic.h ---------------------------------*- 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 a part of ThreadSanitizer (TSan), a race detector.
+//
+// Public interface header for TSan atomics.
+//===----------------------------------------------------------------------===//
+#ifndef TSAN_INTERFACE_ATOMIC_H
+#define TSAN_INTERFACE_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef char     __tsan_atomic8;
+typedef short    __tsan_atomic16;  // NOLINT
+typedef int      __tsan_atomic32;
+typedef long     __tsan_atomic64;  // NOLINT
+#if defined(__SIZEOF_INT128__) \
+    || (__clang_major__ * 100 + __clang_minor__ >= 302)
+__extension__ typedef __int128 __tsan_atomic128;
+# define __TSAN_HAS_INT128 1
+#else
+# define __TSAN_HAS_INT128 0
+#endif
+
+// Part of ABI, do not change.
+// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup
+typedef enum {
+  __tsan_memory_order_relaxed,
+  __tsan_memory_order_consume,
+  __tsan_memory_order_acquire,
+  __tsan_memory_order_release,
+  __tsan_memory_order_acq_rel,
+  __tsan_memory_order_seq_cst
+} __tsan_memory_order;
+
+__tsan_atomic8 __tsan_atomic8_load(const volatile __tsan_atomic8 *a,
+    __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_load(const volatile __tsan_atomic16 *a,
+    __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_load(const volatile __tsan_atomic32 *a,
+    __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_load(const volatile __tsan_atomic64 *a,
+    __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_load(const volatile __tsan_atomic128 *a,
+    __tsan_memory_order mo);
+#endif
+
+void __tsan_atomic8_store(volatile __tsan_atomic8 *a, __tsan_atomic8 v,
+    __tsan_memory_order mo);
+void __tsan_atomic16_store(volatile __tsan_atomic16 *a, __tsan_atomic16 v,
+    __tsan_memory_order mo);
+void __tsan_atomic32_store(volatile __tsan_atomic32 *a, __tsan_atomic32 v,
+    __tsan_memory_order mo);
+void __tsan_atomic64_store(volatile __tsan_atomic64 *a, __tsan_atomic64 v,
+    __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+void __tsan_atomic128_store(volatile __tsan_atomic128 *a, __tsan_atomic128 v,
+    __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_exchange(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_exchange(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_exchange(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_exchange(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_exchange(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_add(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_add(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_add(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_add(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_add(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_sub(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_sub(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_sub(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_sub(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_sub(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_and(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_and(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_and(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_and(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_and(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_or(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_or(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_or(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_or(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_or(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_xor(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_xor(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_xor(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_xor(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_xor(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_fetch_nand(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 v, __tsan_memory_order mo);
+__tsan_atomic16 __tsan_atomic16_fetch_nand(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 v, __tsan_memory_order mo);
+__tsan_atomic32 __tsan_atomic32_fetch_nand(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 v, __tsan_memory_order mo);
+__tsan_atomic64 __tsan_atomic64_fetch_nand(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 v, __tsan_memory_order mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_fetch_nand(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 v, __tsan_memory_order mo);
+#endif
+
+int __tsan_atomic8_compare_exchange_weak(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic16_compare_exchange_weak(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic32_compare_exchange_weak(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic64_compare_exchange_weak(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+#if __TSAN_HAS_INT128
+int __tsan_atomic128_compare_exchange_weak(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+#endif
+
+int __tsan_atomic8_compare_exchange_strong(volatile __tsan_atomic8 *a,
+    __tsan_atomic8 *c, __tsan_atomic8 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic16_compare_exchange_strong(volatile __tsan_atomic16 *a,
+    __tsan_atomic16 *c, __tsan_atomic16 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic32_compare_exchange_strong(volatile __tsan_atomic32 *a,
+    __tsan_atomic32 *c, __tsan_atomic32 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+int __tsan_atomic64_compare_exchange_strong(volatile __tsan_atomic64 *a,
+    __tsan_atomic64 *c, __tsan_atomic64 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+#if __TSAN_HAS_INT128
+int __tsan_atomic128_compare_exchange_strong(volatile __tsan_atomic128 *a,
+    __tsan_atomic128 *c, __tsan_atomic128 v, __tsan_memory_order mo,
+    __tsan_memory_order fail_mo);
+#endif
+
+__tsan_atomic8 __tsan_atomic8_compare_exchange_val(
+    volatile __tsan_atomic8 *a, __tsan_atomic8 c, __tsan_atomic8 v,
+    __tsan_memory_order mo, __tsan_memory_order fail_mo);
+__tsan_atomic16 __tsan_atomic16_compare_exchange_val(
+    volatile __tsan_atomic16 *a, __tsan_atomic16 c, __tsan_atomic16 v,
+    __tsan_memory_order mo, __tsan_memory_order fail_mo);
+__tsan_atomic32 __tsan_atomic32_compare_exchange_val(
+    volatile __tsan_atomic32 *a, __tsan_atomic32 c, __tsan_atomic32 v,
+    __tsan_memory_order mo, __tsan_memory_order fail_mo);
+__tsan_atomic64 __tsan_atomic64_compare_exchange_val(
+    volatile __tsan_atomic64 *a, __tsan_atomic64 c, __tsan_atomic64 v,
+    __tsan_memory_order mo, __tsan_memory_order fail_mo);
+#if __TSAN_HAS_INT128
+__tsan_atomic128 __tsan_atomic128_compare_exchange_val(
+    volatile __tsan_atomic128 *a, __tsan_atomic128 c, __tsan_atomic128 v,
+    __tsan_memory_order mo, __tsan_memory_order fail_mo);
+#endif
+
+void __tsan_atomic_thread_fence(__tsan_memory_order mo);
+void __tsan_atomic_signal_fence(__tsan_memory_order mo);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // TSAN_INTERFACE_ATOMIC_H
diff --git a/lib/clang/3.5.2/include/shaintrin.h b/lib/clang/3.5.2/include/shaintrin.h
new file mode 100644
index 0000000..66ed055
--- /dev/null
+++ b/lib/clang/3.5.2/include/shaintrin.h
@@ -0,0 +1,74 @@
+/*===---- shaintrin.h - SHA intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use <shaintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __SHAINTRIN_H
+#define __SHAINTRIN_H
+
+#if !defined (__SHA__)
+#  error "SHA instructions not enabled"
+#endif
+
+#define _mm_sha1rnds4_epu32(V1, V2, M) __extension__ ({ \
+  __builtin_ia32_sha1rnds4((V1), (V2), (M)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha1nexte_epu32(__m128i __X, __m128i __Y)
+{
+  return __builtin_ia32_sha1nexte(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha1msg1_epu32(__m128i __X, __m128i __Y)
+{
+  return __builtin_ia32_sha1msg1(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha1msg2_epu32(__m128i __X, __m128i __Y)
+{
+  return __builtin_ia32_sha1msg2(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha256rnds2_epu32(__m128i __X, __m128i __Y, __m128i __Z)
+{
+  return __builtin_ia32_sha256rnds2(__X, __Y, __Z);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha256msg1_epu32(__m128i __X, __m128i __Y)
+{
+  return __builtin_ia32_sha256msg1(__X, __Y);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha256msg2_epu32(__m128i __X, __m128i __Y)
+{
+  return __builtin_ia32_sha256msg2(__X, __Y);
+}
+
+#endif /* __SHAINTRIN_H */
diff --git a/lib/clang/3.5.2/include/smmintrin.h b/lib/clang/3.5.2/include/smmintrin.h
new file mode 100644
index 0000000..6e35734
--- /dev/null
+++ b/lib/clang/3.5.2/include/smmintrin.h
@@ -0,0 +1,482 @@
+/*===---- smmintrin.h - SSE4 intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _SMMINTRIN_H
+#define _SMMINTRIN_H
+
+#ifndef __SSE4_1__
+#error "SSE4.1 instruction set not enabled"
+#else
+
+#include <tmmintrin.h>
+
+/* SSE4 Rounding macros. */
+#define _MM_FROUND_TO_NEAREST_INT    0x00
+#define _MM_FROUND_TO_NEG_INF        0x01
+#define _MM_FROUND_TO_POS_INF        0x02
+#define _MM_FROUND_TO_ZERO           0x03
+#define _MM_FROUND_CUR_DIRECTION     0x04
+
+#define _MM_FROUND_RAISE_EXC         0x00
+#define _MM_FROUND_NO_EXC            0x08
+
+#define _MM_FROUND_NINT      (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEAREST_INT)
+#define _MM_FROUND_FLOOR     (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_NEG_INF)
+#define _MM_FROUND_CEIL      (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_POS_INF)
+#define _MM_FROUND_TRUNC     (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_ZERO)
+#define _MM_FROUND_RINT      (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
+#define _MM_FROUND_NEARBYINT (_MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTION)
+
+#define _mm_ceil_ps(X)       _mm_round_ps((X), _MM_FROUND_CEIL)
+#define _mm_ceil_pd(X)       _mm_round_pd((X), _MM_FROUND_CEIL)
+#define _mm_ceil_ss(X, Y)    _mm_round_ss((X), (Y), _MM_FROUND_CEIL)
+#define _mm_ceil_sd(X, Y)    _mm_round_sd((X), (Y), _MM_FROUND_CEIL)
+
+#define _mm_floor_ps(X)      _mm_round_ps((X), _MM_FROUND_FLOOR)
+#define _mm_floor_pd(X)      _mm_round_pd((X), _MM_FROUND_FLOOR)
+#define _mm_floor_ss(X, Y)   _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
+#define _mm_floor_sd(X, Y)   _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
+
+#define _mm_round_ps(X, M) __extension__ ({ \
+  __m128 __X = (X); \
+  (__m128) __builtin_ia32_roundps((__v4sf)__X, (M)); })
+
+#define _mm_round_ss(X, Y, M) __extension__ ({ \
+  __m128 __X = (X); \
+  __m128 __Y = (Y); \
+  (__m128) __builtin_ia32_roundss((__v4sf)__X, (__v4sf)__Y, (M)); })
+
+#define _mm_round_pd(X, M) __extension__ ({ \
+  __m128d __X = (X); \
+  (__m128d) __builtin_ia32_roundpd((__v2df)__X, (M)); })
+
+#define _mm_round_sd(X, Y, M) __extension__ ({ \
+  __m128d __X = (X); \
+  __m128d __Y = (Y); \
+  (__m128d) __builtin_ia32_roundsd((__v2df)__X, (__v2df)__Y, (M)); })
+
+/* SSE4 Packed Blending Intrinsics.  */
+#define _mm_blend_pd(V1, V2, M) __extension__ ({ \
+  __m128d __V1 = (V1); \
+  __m128d __V2 = (V2); \
+  (__m128d)__builtin_shufflevector((__v2df)__V1, (__v2df)__V2, \
+                                   (((M) & 0x01) ? 2 : 0), \
+                                   (((M) & 0x02) ? 3 : 1)); })
+
+#define _mm_blend_ps(V1, V2, M) __extension__ ({ \
+  __m128 __V1 = (V1); \
+  __m128 __V2 = (V2); \
+  (__m128)__builtin_shufflevector((__v4sf)__V1, (__v4sf)__V2, \
+                                  (((M) & 0x01) ? 4 : 0), \
+                                  (((M) & 0x02) ? 5 : 1), \
+                                  (((M) & 0x04) ? 6 : 2), \
+                                  (((M) & 0x08) ? 7 : 3)); })
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
+{
+  return (__m128d) __builtin_ia32_blendvpd ((__v2df)__V1, (__v2df)__V2,
+                                            (__v2df)__M);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M)
+{
+  return (__m128) __builtin_ia32_blendvps ((__v4sf)__V1, (__v4sf)__V2,
+                                           (__v4sf)__M);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
+{
+  return (__m128i) __builtin_ia32_pblendvb128 ((__v16qi)__V1, (__v16qi)__V2,
+                                               (__v16qi)__M);
+}
+
+#define _mm_blend_epi16(V1, V2, M) __extension__ ({ \
+  __m128i __V1 = (V1); \
+  __m128i __V2 = (V2); \
+  (__m128i)__builtin_shufflevector((__v8hi)__V1, (__v8hi)__V2, \
+                                   (((M) & 0x01) ?  8 : 0), \
+                                   (((M) & 0x02) ?  9 : 1), \
+                                   (((M) & 0x04) ? 10 : 2), \
+                                   (((M) & 0x08) ? 11 : 3), \
+                                   (((M) & 0x10) ? 12 : 4), \
+                                   (((M) & 0x20) ? 13 : 5), \
+                                   (((M) & 0x40) ? 14 : 6), \
+                                   (((M) & 0x80) ? 15 : 7)); })
+
+/* SSE4 Dword Multiply Instructions.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) ((__v4si)__V1 * (__v4si)__V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mul_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__V1, (__v4si)__V2);
+}
+
+/* SSE4 Floating Point Dot Product Instructions.  */
+#define _mm_dp_ps(X, Y, M) __extension__ ({ \
+  __m128 __X = (X); \
+  __m128 __Y = (Y); \
+  (__m128) __builtin_ia32_dpps((__v4sf)__X, (__v4sf)__Y, (M)); })
+
+#define _mm_dp_pd(X, Y, M) __extension__ ({\
+  __m128d __X = (X); \
+  __m128d __Y = (Y); \
+  (__m128d) __builtin_ia32_dppd((__v2df)__X, (__v2df)__Y, (M)); })
+
+/* SSE4 Streaming Load Hint Instruction.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_stream_load_si128 (__m128i *__V)
+{
+  return (__m128i) __builtin_ia32_movntdqa ((__v2di *) __V);
+}
+
+/* SSE4 Packed Integer Min/Max Instructions.  */
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi8 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi8 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu16 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu16 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2);
+}
+
+static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu32 (__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_pmaxud128((__v4si) __V1, (__v4si) __V2);
+}
+
+/* SSE4 Insertion and Extraction from XMM Register Instructions.  */
+#define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N))
+#define _mm_extract_ps(X, N) (__extension__                      \
+                              ({ union { int __i; float __f; } __t;  \
+                                 __v4sf __a = (__v4sf)(X);       \
+                                 __t.__f = __a[(N) & 3];                 \
+                                 __t.__i;}))
+
+/* Miscellaneous insert and extract macros.  */
+/* Extract a single-precision float from X at index N into D.  */
+#define _MM_EXTRACT_FLOAT(D, X, N) (__extension__ ({ __v4sf __a = (__v4sf)(X); \
+                                                    (D) = __a[N]; }))
+                                                    
+/* Or together 2 sets of indexes (X and Y) with the zeroing bits (Z) to create
+   an index suitable for _mm_insert_ps.  */
+#define _MM_MK_INSERTPS_NDX(X, Y, Z) (((X) << 6) | ((Y) << 4) | (Z))
+                                           
+/* Extract a float from X at index N into the first index of the return.  */
+#define _MM_PICK_OUT_PS(X, N) _mm_insert_ps (_mm_setzero_ps(), (X),   \
+                                             _MM_MK_INSERTPS_NDX((N), 0, 0x0e))
+                                             
+/* Insert int into packed integer array at index.  */
+#define _mm_insert_epi8(X, I, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \
+                                                   __a[(N) & 15] = (I);             \
+                                                   __a;}))
+#define _mm_insert_epi32(X, I, N) (__extension__ ({ __v4si __a = (__v4si)(X); \
+                                                    __a[(N) & 3] = (I);           \
+                                                    __a;}))
+#ifdef __x86_64__
+#define _mm_insert_epi64(X, I, N) (__extension__ ({ __v2di __a = (__v2di)(X); \
+                                                    __a[(N) & 1] = (I);           \
+                                                    __a;}))
+#endif /* __x86_64__ */
+
+/* Extract int from packed integer array at index.  This returns the element
+ * as a zero extended value, so it is unsigned.
+ */
+#define _mm_extract_epi8(X, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \
+                                                 (int)(unsigned char) \
+                                                     __a[(N) & 15];}))
+#define _mm_extract_epi32(X, N) (__extension__ ({ __v4si __a = (__v4si)(X); \
+                                                  __a[(N) & 3];}))
+#ifdef __x86_64__
+#define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)(X); \
+                                                  __a[(N) & 1];}))
+#endif /* __x86_64 */
+
+/* SSE4 128-bit Packed Integer Comparisons.  */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testz_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestz128((__v2di)__M, (__v2di)__V);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testc_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestc128((__v2di)__M, (__v2di)__V);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_testnzc_si128(__m128i __M, __m128i __V)
+{
+  return __builtin_ia32_ptestnzc128((__v2di)__M, (__v2di)__V);
+}
+
+#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V)))
+#define _mm_test_mix_ones_zeros(M, V) _mm_testnzc_si128((M), (V))
+#define _mm_test_all_zeros(M, V) _mm_testz_si128 ((M), (V))
+
+/* SSE4 64-bit Packed Integer Comparisons.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_epi64(__m128i __V1, __m128i __V2)
+{
+  return (__m128i)((__v2di)__V1 == (__v2di)__V2);
+}
+
+/* SSE4 Packed Integer Sign-Extension.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbw128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbd128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi8_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxbq128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi16_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxwd128((__v8hi) __V); 
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi16_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxwq128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepi32_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovsxdq128((__v4si)__V);
+}
+
+/* SSE4 Packed Integer Zero-Extension.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbw128((__v16qi) __V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbd128((__v16qi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu8_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxbq128((__v16qi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu16_epi32(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxwd128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu16_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxwq128((__v8hi)__V);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cvtepu32_epi64(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_pmovzxdq128((__v4si)__V);
+}
+
+/* SSE4 Pack with Unsigned Saturation.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_packus_epi32(__m128i __V1, __m128i __V2)
+{
+  return (__m128i) __builtin_ia32_packusdw128((__v4si)__V1, (__v4si)__V2);
+}
+
+/* SSE4 Multiple Packed Sums of Absolute Difference.  */
+#define _mm_mpsadbw_epu8(X, Y, M) __extension__ ({ \
+  __m128i __X = (X); \
+  __m128i __Y = (Y); \
+  (__m128i) __builtin_ia32_mpsadbw128((__v16qi)__X, (__v16qi)__Y, (M)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_minpos_epu16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_phminposuw128((__v8hi)__V);
+}
+
+/* These definitions are normally in nmmintrin.h, but gcc puts them in here
+   so we'll do the same.  */
+#ifdef __SSE4_2__
+
+/* These specify the type of data that we're comparing.  */
+#define _SIDD_UBYTE_OPS                 0x00
+#define _SIDD_UWORD_OPS                 0x01
+#define _SIDD_SBYTE_OPS                 0x02
+#define _SIDD_SWORD_OPS                 0x03
+
+/* These specify the type of comparison operation.  */
+#define _SIDD_CMP_EQUAL_ANY             0x00
+#define _SIDD_CMP_RANGES                0x04
+#define _SIDD_CMP_EQUAL_EACH            0x08
+#define _SIDD_CMP_EQUAL_ORDERED         0x0c
+
+/* These macros specify the polarity of the operation.  */
+#define _SIDD_POSITIVE_POLARITY         0x00
+#define _SIDD_NEGATIVE_POLARITY         0x10
+#define _SIDD_MASKED_POSITIVE_POLARITY  0x20
+#define _SIDD_MASKED_NEGATIVE_POLARITY  0x30
+
+/* These macros are used in _mm_cmpXstri() to specify the return.  */
+#define _SIDD_LEAST_SIGNIFICANT         0x00
+#define _SIDD_MOST_SIGNIFICANT          0x40
+
+/* These macros are used in _mm_cmpXstri() to specify the return.  */
+#define _SIDD_BIT_MASK                  0x00
+#define _SIDD_UNIT_MASK                 0x40
+
+/* SSE4.2 Packed Comparison Intrinsics.  */
+#define _mm_cmpistrm(A, B, M) __builtin_ia32_pcmpistrm128((A), (B), (M))
+#define _mm_cmpistri(A, B, M) __builtin_ia32_pcmpistri128((A), (B), (M))
+
+#define _mm_cmpestrm(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestrm128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestri(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestri128((A), (LA), (B), (LB), (M))
+     
+/* SSE4.2 Packed Comparison Intrinsics and EFlag Reading.  */
+#define _mm_cmpistra(A, B, M) \
+     __builtin_ia32_pcmpistria128((A), (B), (M))
+#define _mm_cmpistrc(A, B, M) \
+     __builtin_ia32_pcmpistric128((A), (B), (M))
+#define _mm_cmpistro(A, B, M) \
+     __builtin_ia32_pcmpistrio128((A), (B), (M))
+#define _mm_cmpistrs(A, B, M) \
+     __builtin_ia32_pcmpistris128((A), (B), (M))
+#define _mm_cmpistrz(A, B, M) \
+     __builtin_ia32_pcmpistriz128((A), (B), (M))
+
+#define _mm_cmpestra(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestria128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrc(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestric128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestro(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestrio128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrs(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestris128((A), (LA), (B), (LB), (M))
+#define _mm_cmpestrz(A, LA, B, LB, M) \
+     __builtin_ia32_pcmpestriz128((A), (LA), (B), (LB), (M))
+
+/* SSE4.2 Compare Packed Data -- Greater Than.  */
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_epi64(__m128i __V1, __m128i __V2)
+{
+  return (__m128i)((__v2di)__V1 > (__v2di)__V2);
+}
+
+/* SSE4.2 Accumulate CRC32.  */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u8(unsigned int __C, unsigned char __D)
+{
+  return __builtin_ia32_crc32qi(__C, __D);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u16(unsigned int __C, unsigned short __D)
+{
+  return __builtin_ia32_crc32hi(__C, __D);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u32(unsigned int __C, unsigned int __D)
+{
+  return __builtin_ia32_crc32si(__C, __D);
+}
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_mm_crc32_u64(unsigned long long __C, unsigned long long __D)
+{
+  return __builtin_ia32_crc32di(__C, __D);
+}
+#endif /* __x86_64__ */
+
+#ifdef __POPCNT__
+#include <popcntintrin.h>
+#endif
+
+#endif /* __SSE4_2__ */
+#endif /* __SSE4_1__ */
+
+#endif /* _SMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/stdalign.h b/lib/clang/3.5.2/include/stdalign.h
new file mode 100644
index 0000000..3738d12
--- /dev/null
+++ b/lib/clang/3.5.2/include/stdalign.h
@@ -0,0 +1,35 @@
+/*===---- stdalign.h - Standard header for alignment ------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDALIGN_H
+#define __STDALIGN_H
+
+#ifndef __cplusplus
+#define alignas _Alignas
+#define alignof _Alignof
+#endif
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif /* __STDALIGN_H */
diff --git a/lib/clang/3.5.2/include/stdarg.h b/lib/clang/3.5.2/include/stdarg.h
new file mode 100644
index 0000000..a57e183
--- /dev/null
+++ b/lib/clang/3.5.2/include/stdarg.h
@@ -0,0 +1,52 @@
+/*===---- stdarg.h - Variable argument handling ----------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDARG_H
+#define __STDARG_H
+
+#ifndef _VA_LIST
+typedef __builtin_va_list va_list;
+#define _VA_LIST
+#endif
+#define va_start(ap, param) __builtin_va_start(ap, param)
+#define va_end(ap)          __builtin_va_end(ap)
+#define va_arg(ap, type)    __builtin_va_arg(ap, type)
+
+/* GCC always defines __va_copy, but does not define va_copy unless in c99 mode
+ * or -ansi is not specified, since it was not part of C90.
+ */
+#define __va_copy(d,s) __builtin_va_copy(d,s)
+
+#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
+#define va_copy(dest, src)  __builtin_va_copy(dest, src)
+#endif
+
+/* Hack required to make standard headers work, at least on Ubuntu */
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST 1
+#endif
+typedef __builtin_va_list __gnuc_va_list;
+
+#endif /* __STDARG_H */
diff --git a/lib/clang/3.5.2/include/stdbool.h b/lib/clang/3.5.2/include/stdbool.h
new file mode 100644
index 0000000..0467893
--- /dev/null
+++ b/lib/clang/3.5.2/include/stdbool.h
@@ -0,0 +1,44 @@
+/*===---- stdbool.h - Standard header for booleans -------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDBOOL_H
+#define __STDBOOL_H
+
+/* Don't define bool, true, and false in C++, except as a GNU extension. */
+#ifndef __cplusplus
+#define bool _Bool
+#define true 1
+#define false 0
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
+/* Define _Bool, bool, false, true as a GNU extension. */
+#define _Bool bool
+#define bool  bool
+#define false false
+#define true  true
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* __STDBOOL_H */
diff --git a/lib/clang/3.5.2/include/stddef.h b/lib/clang/3.5.2/include/stddef.h
new file mode 100644
index 0000000..2dfe0a2
--- /dev/null
+++ b/lib/clang/3.5.2/include/stddef.h
@@ -0,0 +1,146 @@
+/*===---- stddef.h - Basic type definitions --------------------------------===
+ *
+ * Copyright (c) 2008 Eli Friedman
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) ||                       \
+    defined(__need_size_t) || defined(__need_wchar_t) ||                       \
+    defined(__need_NULL) || defined(__need_wint_t)
+
+#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) &&                   \
+    !defined(__need_wchar_t) && !defined(__need_NULL) &&                       \
+    !defined(__need_wint_t)
+#define __STDDEF_H
+#define __need_ptrdiff_t
+#define __need_size_t
+#define __need_wchar_t
+#define __need_NULL
+/* __need_wint_t is intentionally not defined here. */
+#endif
+
+#if defined(__need_ptrdiff_t)
+#if !defined(_PTRDIFF_T) || __has_feature(modules)
+/* Always define ptrdiff_t when modules are available. */
+#if !__has_feature(modules)
+#define _PTRDIFF_T
+#endif
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif
+#undef __need_ptrdiff_t
+#endif /* defined(__need_ptrdiff_t) */
+
+#if defined(__need_size_t)
+#if !defined(_SIZE_T) || __has_feature(modules)
+/* Always define size_t when modules are available. */
+#if !__has_feature(modules)
+#define _SIZE_T
+#endif
+typedef __SIZE_TYPE__ size_t;
+#endif
+#undef __need_size_t
+#endif /*defined(__need_size_t) */
+
+#if defined(__STDDEF_H)
+/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
+ * enabled. */
+#if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
+     !defined(_RSIZE_T)) || __has_feature(modules)
+/* Always define rsize_t when modules are available. */
+#if !__has_feature(modules)
+#define _RSIZE_T
+#endif
+typedef __SIZE_TYPE__ rsize_t;
+#endif
+#endif /* defined(__STDDEF_H) */
+
+#if defined(__need_wchar_t)
+#ifndef __cplusplus
+/* Always define wchar_t when modules are available. */
+#if !defined(_WCHAR_T) || __has_feature(modules)
+#if !__has_feature(modules)
+#define _WCHAR_T
+#if defined(_MSC_EXTENSIONS)
+#define _WCHAR_T_DEFINED
+#endif
+#endif
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+#endif
+#undef __need_wchar_t
+#endif /* defined(__need_wchar_t) */
+
+#if defined(__need_NULL)
+#undef NULL
+#ifdef __cplusplus
+#  if !defined(__MINGW32__) && !defined(_MSC_VER)
+#    define NULL __null
+#  else
+#    define NULL 0
+#  endif
+#else
+#  define NULL ((void*)0)
+#endif
+#ifdef __cplusplus
+#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
+namespace std { typedef decltype(nullptr) nullptr_t; }
+using ::std::nullptr_t;
+#endif
+#endif
+#undef __need_NULL
+#endif /* defined(__need_NULL) */
+
+#if defined(__STDDEF_H)
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) || __has_feature(modules)
+#ifndef _MSC_VER
+typedef struct {
+  long long __clang_max_align_nonce1
+      __attribute__((__aligned__(__alignof__(long long))));
+  long double __clang_max_align_nonce2
+      __attribute__((__aligned__(__alignof__(long double))));
+} max_align_t;
+#else
+typedef double max_align_t;
+#endif
+#define __CLANG_MAX_ALIGN_T_DEFINED
+#endif
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
+#endif  /* __STDDEF_H */
+
+/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
+__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
+#if defined(__need_wint_t)
+/* Always define wint_t when modules are available. */
+#if !defined(_WINT_T) || __has_feature(modules)
+#if !__has_feature(modules)
+#define _WINT_T
+#endif
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif /* __need_wint_t */
+
+#endif
diff --git a/lib/clang/3.5.2/include/stdint.h b/lib/clang/3.5.2/include/stdint.h
new file mode 100644
index 0000000..0303db9
--- /dev/null
+++ b/lib/clang/3.5.2/include/stdint.h
@@ -0,0 +1,707 @@
+/*===---- stdint.h - Standard header for sized integer types --------------===*\
+ *
+ * Copyright (c) 2009 Chris Lattner
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __CLANG_STDINT_H
+#define __CLANG_STDINT_H
+
+/* If we're hosted, fall back to the system's stdint.h, which might have
+ * additional definitions.
+ */
+#if __STDC_HOSTED__ && __has_include_next(<stdint.h>)
+
+// C99 7.18.3 Limits of other integer types
+//
+//  Footnote 219, 220: C++ implementations should define these macros only when
+//  __STDC_LIMIT_MACROS is defined before <stdint.h> is included.
+//
+//  Footnote 222: C++ implementations should define these macros only when
+//  __STDC_CONSTANT_MACROS is defined before <stdint.h> is included.
+//
+// C++11 [cstdint.syn]p2:
+//
+//  The macros defined by <cstdint> are provided unconditionally. In particular,
+//  the symbols __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS (mentioned in
+//  footnotes 219, 220, and 222 in the C standard) play no role in C++.
+//
+// C11 removed the problematic footnotes.
+//
+// Work around this inconsistency by always defining those macros in C++ mode,
+// so that a C library implementation which follows the C99 standard can be
+// used in C++.
+# ifdef __cplusplus
+#  if !defined(__STDC_LIMIT_MACROS)
+#   define __STDC_LIMIT_MACROS
+#   define __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+#  endif
+#  if !defined(__STDC_CONSTANT_MACROS)
+#   define __STDC_CONSTANT_MACROS
+#   define __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+#  endif
+# endif
+
+# include_next <stdint.h>
+
+# ifdef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+#  undef __STDC_LIMIT_MACROS
+#  undef __STDC_LIMIT_MACROS_DEFINED_BY_CLANG
+# endif
+# ifdef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+#  undef __STDC_CONSTANT_MACROS
+#  undef __STDC_CONSTANT_MACROS_DEFINED_BY_CLANG
+# endif
+
+#else
+
+/* C99 7.18.1.1 Exact-width integer types.
+ * C99 7.18.1.2 Minimum-width integer types.
+ * C99 7.18.1.3 Fastest minimum-width integer types.
+ *
+ * The standard requires that exact-width type be defined for 8-, 16-, 32-, and 
+ * 64-bit types if they are implemented. Other exact width types are optional.
+ * This implementation defines an exact-width types for every integer width
+ * that is represented in the standard integer types.
+ *
+ * The standard also requires minimum-width types be defined for 8-, 16-, 32-,
+ * and 64-bit widths regardless of whether there are corresponding exact-width
+ * types. 
+ *
+ * To accommodate targets that are missing types that are exactly 8, 16, 32, or
+ * 64 bits wide, this implementation takes an approach of cascading
+ * redefintions, redefining __int_leastN_t to successively smaller exact-width
+ * types. It is therefore important that the types are defined in order of
+ * descending widths.
+ *
+ * We currently assume that the minimum-width types and the fastest
+ * minimum-width types are the same. This is allowed by the standard, but is
+ * suboptimal.
+ *
+ * In violation of the standard, some targets do not implement a type that is
+ * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit).  
+ * To accommodate these targets, a required minimum-width type is only
+ * defined if there exists an exact-width type of equal or greater width.
+ */
+
+#ifdef __INT64_TYPE__
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
+typedef __UINT64_TYPE__ uint64_t;
+# define __int_least64_t int64_t
+# define __uint_least64_t uint64_t
+# define __int_least32_t int64_t
+# define __uint_least32_t uint64_t
+# define __int_least16_t int64_t
+# define __uint_least16_t uint64_t
+# define __int_least8_t int64_t
+# define __uint_least8_t uint64_t
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+typedef __INT56_TYPE__ int56_t;
+typedef __UINT56_TYPE__ uint56_t;
+typedef int56_t int_least56_t;
+typedef uint56_t uint_least56_t;
+typedef int56_t int_fast56_t;
+typedef uint56_t uint_fast56_t;
+# define __int_least32_t int56_t
+# define __uint_least32_t uint56_t
+# define __int_least16_t int56_t
+# define __uint_least16_t uint56_t
+# define __int_least8_t int56_t
+# define __uint_least8_t uint56_t
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+typedef __INT48_TYPE__ int48_t;
+typedef __UINT48_TYPE__ uint48_t;
+typedef int48_t int_least48_t;
+typedef uint48_t uint_least48_t;
+typedef int48_t int_fast48_t;
+typedef uint48_t uint_fast48_t;
+# define __int_least32_t int48_t
+# define __uint_least32_t uint48_t
+# define __int_least16_t int48_t
+# define __uint_least16_t uint48_t
+# define __int_least8_t int48_t
+# define __uint_least8_t uint48_t
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+typedef __INT40_TYPE__ int40_t;
+typedef __UINT40_TYPE__ uint40_t;
+typedef int40_t int_least40_t;
+typedef uint40_t uint_least40_t;
+typedef int40_t int_fast40_t;
+typedef uint40_t uint_fast40_t;
+# define __int_least32_t int40_t
+# define __uint_least32_t uint40_t
+# define __int_least16_t int40_t
+# define __uint_least16_t uint40_t
+# define __int_least8_t int40_t
+# define __uint_least8_t uint40_t
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+
+# ifndef __uint32_t_defined  /* more glibc compatibility */
+# define __uint32_t_defined
+typedef __UINT32_TYPE__ uint32_t;
+# endif /* __uint32_t_defined */
+
+# define __int_least32_t int32_t
+# define __uint_least32_t uint32_t
+# define __int_least16_t int32_t
+# define __uint_least16_t uint32_t
+# define __int_least8_t int32_t
+# define __uint_least8_t uint32_t
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+typedef __INT24_TYPE__ int24_t;
+typedef __UINT24_TYPE__ uint24_t;
+typedef int24_t int_least24_t;
+typedef uint24_t uint_least24_t;
+typedef int24_t int_fast24_t;
+typedef uint24_t uint_fast24_t;
+# define __int_least16_t int24_t
+# define __uint_least16_t uint24_t
+# define __int_least8_t int24_t
+# define __uint_least8_t uint24_t
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
+typedef __UINT16_TYPE__ uint16_t;
+# define __int_least16_t int16_t
+# define __uint_least16_t uint16_t
+# define __int_least8_t int16_t
+# define __uint_least8_t uint16_t
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
+typedef __INT8_TYPE__ int8_t;
+#endif /* __int8_t_defined */
+typedef __UINT8_TYPE__ uint8_t;
+# define __int_least8_t int8_t
+# define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
+/* prevent glibc sys/types.h from defining conflicting types */
+#ifndef __int8_t_defined  
+# define __int8_t_defined
+#endif /* __int8_t_defined */
+
+/* C99 7.18.1.4 Integer types capable of holding object pointers.
+ */
+#define __stdint_join3(a,b,c) a ## b ## c
+
+#define  __intn_t(n) __stdint_join3( int, n, _t)
+#define __uintn_t(n) __stdint_join3(uint, n, _t)
+
+#ifndef _INTPTR_T
+#ifndef __intptr_t_defined
+typedef  __intn_t(__INTPTR_WIDTH__)  intptr_t;
+#define __intptr_t_defined
+#define _INTPTR_T
+#endif
+#endif
+
+#ifndef _UINTPTR_T
+typedef __uintn_t(__INTPTR_WIDTH__) uintptr_t;
+#define _UINTPTR_T
+#endif
+
+/* C99 7.18.1.5 Greatest-width integer types.
+ */
+typedef __INTMAX_TYPE__  intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+
+/* C99 7.18.4 Macros for minimum-width integer constants.
+ *
+ * The standard requires that integer constant macros be defined for all the
+ * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width
+ * types are required, the corresponding integer constant macros are defined 
+ * here. This implementation also defines minimum-width types for every other
+ * integer width that the target implements, so corresponding macros are 
+ * defined below, too.
+ *
+ * These macros are defined using the same successive-shrinking approach as
+ * the type definitions above. It is likewise important that macros are defined
+ * in order of decending width.
+ *
+ * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#define __int_c_join(a, b) a ## b
+#define __int_c(v, suffix) __int_c_join(v, suffix)
+#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
+
+
+#ifdef __INT64_TYPE__
+# ifdef __INT64_C_SUFFIX__
+#  define __int64_c_suffix __INT64_C_SUFFIX__
+#  define __int32_c_suffix __INT64_C_SUFFIX__
+#  define __int16_c_suffix __INT64_C_SUFFIX__
+#  define  __int8_c_suffix __INT64_C_SUFFIX__
+# else
+#  undef __int64_c_suffix
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT64_C_SUFFIX__ */
+#endif /* __INT64_TYPE__ */
+
+#ifdef __int_least64_t
+# ifdef __int64_c_suffix
+#  define INT64_C(v) __int_c(v, __int64_c_suffix)
+#  define UINT64_C(v) __uint_c(v, __int64_c_suffix)
+# else
+#  define INT64_C(v) v
+#  define UINT64_C(v) v ## U
+# endif /* __int64_c_suffix */
+#endif /* __int_least64_t */
+
+
+#ifdef __INT56_TYPE__
+# ifdef __INT56_C_SUFFIX__
+#  define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__)
+#  define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__)
+#  define __int32_c_suffix __INT56_C_SUFFIX__
+#  define __int16_c_suffix __INT56_C_SUFFIX__
+#  define __int8_c_suffix  __INT56_C_SUFFIX__
+# else
+#  define INT56_C(v) v
+#  define UINT56_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT56_C_SUFFIX__ */
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+# ifdef __INT48_C_SUFFIX__
+#  define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__)
+#  define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__)
+#  define __int32_c_suffix __INT48_C_SUFFIX__
+#  define __int16_c_suffix __INT48_C_SUFFIX__
+#  define __int8_c_suffix  __INT48_C_SUFFIX__
+# else
+#  define INT48_C(v) v
+#  define UINT48_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT48_C_SUFFIX__ */
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+# ifdef __INT40_C_SUFFIX__
+#  define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__)
+#  define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__)
+#  define __int32_c_suffix __INT40_C_SUFFIX__
+#  define __int16_c_suffix __INT40_C_SUFFIX__
+#  define __int8_c_suffix  __INT40_C_SUFFIX__
+# else
+#  define INT40_C(v) v
+#  define UINT40_C(v) v ## U
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT40_C_SUFFIX__ */
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# ifdef __INT32_C_SUFFIX__
+#  define __int32_c_suffix __INT32_C_SUFFIX__
+#  define __int16_c_suffix __INT32_C_SUFFIX__
+#  define __int8_c_suffix  __INT32_C_SUFFIX__
+#else
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT32_C_SUFFIX__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+# ifdef __int32_c_suffix
+#  define INT32_C(v) __int_c(v, __int32_c_suffix)
+#  define UINT32_C(v) __uint_c(v, __int32_c_suffix)
+# else
+#  define INT32_C(v) v
+#  define UINT32_C(v) v ## U
+# endif /* __int32_c_suffix */
+#endif /* __int_least32_t */
+
+
+#ifdef __INT24_TYPE__
+# ifdef __INT24_C_SUFFIX__
+#  define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__)
+#  define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__)
+#  define __int16_c_suffix __INT24_C_SUFFIX__
+#  define __int8_c_suffix  __INT24_C_SUFFIX__
+# else
+#  define INT24_C(v) v
+#  define UINT24_C(v) v ## U
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT24_C_SUFFIX__ */
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+# ifdef __INT16_C_SUFFIX__
+#  define __int16_c_suffix __INT16_C_SUFFIX__
+#  define __int8_c_suffix  __INT16_C_SUFFIX__
+#else
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT16_C_SUFFIX__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+# ifdef __int16_c_suffix
+#  define INT16_C(v) __int_c(v, __int16_c_suffix)
+#  define UINT16_C(v) __uint_c(v, __int16_c_suffix)
+# else
+#  define INT16_C(v) v
+#  define UINT16_C(v) v ## U
+# endif /* __int16_c_suffix */
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+# ifdef __INT8_C_SUFFIX__
+#  define __int8_c_suffix __INT8_C_SUFFIX__
+#else
+#  undef  __int8_c_suffix
+# endif /* __INT8_C_SUFFIX__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+# ifdef __int8_c_suffix
+#  define INT8_C(v) __int_c(v, __int8_c_suffix)
+#  define UINT8_C(v) __uint_c(v, __int8_c_suffix)
+# else
+#  define INT8_C(v) v
+#  define UINT8_C(v) v ## U
+# endif /* __int8_c_suffix */
+#endif /* __int_least8_t */
+
+
+/* C99 7.18.2.1 Limits of exact-width integer types. 
+ * C99 7.18.2.2 Limits of minimum-width integer types.
+ * C99 7.18.2.3 Limits of fastest minimum-width integer types.
+ *
+ * The presence of limit macros are completely optional in C99.  This
+ * implementation defines limits for all of the types (exact- and
+ * minimum-width) that it defines above, using the limits of the minimum-width
+ * type for any types that do not have exact-width representations.
+ *
+ * As in the type definitions, this section takes an approach of
+ * successive-shrinking to determine which limits to use for the standard (8,
+ * 16, 32, 64) bit widths when they don't have exact representations. It is
+ * therefore important that the defintions be kept in order of decending
+ * widths.
+ *
+ * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the
+ * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
+ */
+
+#ifdef __INT64_TYPE__
+# define INT64_MAX           INT64_C( 9223372036854775807)
+# define INT64_MIN         (-INT64_C( 9223372036854775807)-1)
+# define UINT64_MAX         UINT64_C(18446744073709551615)
+# define __INT_LEAST64_MIN   INT64_MIN
+# define __INT_LEAST64_MAX   INT64_MAX
+# define __UINT_LEAST64_MAX UINT64_MAX
+# define __INT_LEAST32_MIN   INT64_MIN
+# define __INT_LEAST32_MAX   INT64_MAX
+# define __UINT_LEAST32_MAX UINT64_MAX
+# define __INT_LEAST16_MIN   INT64_MIN
+# define __INT_LEAST16_MAX   INT64_MAX
+# define __UINT_LEAST16_MAX UINT64_MAX
+# define __INT_LEAST8_MIN    INT64_MIN
+# define __INT_LEAST8_MAX    INT64_MAX
+# define __UINT_LEAST8_MAX  UINT64_MAX
+#endif /* __INT64_TYPE__ */
+
+#ifdef __INT_LEAST64_MIN
+# define INT_LEAST64_MIN   __INT_LEAST64_MIN
+# define INT_LEAST64_MAX   __INT_LEAST64_MAX
+# define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+# define INT_FAST64_MIN    __INT_LEAST64_MIN
+# define INT_FAST64_MAX    __INT_LEAST64_MAX
+# define UINT_FAST64_MAX  __UINT_LEAST64_MAX
+#endif /* __INT_LEAST64_MIN */
+
+
+#ifdef __INT56_TYPE__
+# define INT56_MAX           INT56_C(36028797018963967)
+# define INT56_MIN         (-INT56_C(36028797018963967)-1)
+# define UINT56_MAX         UINT56_C(72057594037927935)
+# define INT_LEAST56_MIN     INT56_MIN
+# define INT_LEAST56_MAX     INT56_MAX
+# define UINT_LEAST56_MAX   UINT56_MAX
+# define INT_FAST56_MIN      INT56_MIN
+# define INT_FAST56_MAX      INT56_MAX
+# define UINT_FAST56_MAX    UINT56_MAX
+# define __INT_LEAST32_MIN   INT56_MIN
+# define __INT_LEAST32_MAX   INT56_MAX
+# define __UINT_LEAST32_MAX UINT56_MAX
+# define __INT_LEAST16_MIN   INT56_MIN
+# define __INT_LEAST16_MAX   INT56_MAX
+# define __UINT_LEAST16_MAX UINT56_MAX
+# define __INT_LEAST8_MIN    INT56_MIN
+# define __INT_LEAST8_MAX    INT56_MAX
+# define __UINT_LEAST8_MAX  UINT56_MAX
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+# define INT48_MAX           INT48_C(140737488355327)
+# define INT48_MIN         (-INT48_C(140737488355327)-1)
+# define UINT48_MAX         UINT48_C(281474976710655)
+# define INT_LEAST48_MIN     INT48_MIN
+# define INT_LEAST48_MAX     INT48_MAX
+# define UINT_LEAST48_MAX   UINT48_MAX
+# define INT_FAST48_MIN      INT48_MIN
+# define INT_FAST48_MAX      INT48_MAX
+# define UINT_FAST48_MAX    UINT48_MAX
+# define __INT_LEAST32_MIN   INT48_MIN
+# define __INT_LEAST32_MAX   INT48_MAX
+# define __UINT_LEAST32_MAX UINT48_MAX
+# define __INT_LEAST16_MIN   INT48_MIN
+# define __INT_LEAST16_MAX   INT48_MAX
+# define __UINT_LEAST16_MAX UINT48_MAX
+# define __INT_LEAST8_MIN    INT48_MIN
+# define __INT_LEAST8_MAX    INT48_MAX
+# define __UINT_LEAST8_MAX  UINT48_MAX
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+# define INT40_MAX           INT40_C(549755813887)
+# define INT40_MIN         (-INT40_C(549755813887)-1)
+# define UINT40_MAX         UINT40_C(1099511627775)
+# define INT_LEAST40_MIN     INT40_MIN
+# define INT_LEAST40_MAX     INT40_MAX
+# define UINT_LEAST40_MAX   UINT40_MAX
+# define INT_FAST40_MIN      INT40_MIN
+# define INT_FAST40_MAX      INT40_MAX
+# define UINT_FAST40_MAX    UINT40_MAX
+# define __INT_LEAST32_MIN   INT40_MIN
+# define __INT_LEAST32_MAX   INT40_MAX
+# define __UINT_LEAST32_MAX UINT40_MAX
+# define __INT_LEAST16_MIN   INT40_MIN
+# define __INT_LEAST16_MAX   INT40_MAX
+# define __UINT_LEAST16_MAX UINT40_MAX
+# define __INT_LEAST8_MIN    INT40_MIN
+# define __INT_LEAST8_MAX    INT40_MAX
+# define __UINT_LEAST8_MAX  UINT40_MAX
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# define INT32_MAX           INT32_C(2147483647)
+# define INT32_MIN         (-INT32_C(2147483647)-1)
+# define UINT32_MAX         UINT32_C(4294967295)
+# define __INT_LEAST32_MIN   INT32_MIN
+# define __INT_LEAST32_MAX   INT32_MAX
+# define __UINT_LEAST32_MAX UINT32_MAX
+# define __INT_LEAST16_MIN   INT32_MIN
+# define __INT_LEAST16_MAX   INT32_MAX
+# define __UINT_LEAST16_MAX UINT32_MAX
+# define __INT_LEAST8_MIN    INT32_MIN
+# define __INT_LEAST8_MAX    INT32_MAX
+# define __UINT_LEAST8_MAX  UINT32_MAX
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT_LEAST32_MIN
+# define INT_LEAST32_MIN   __INT_LEAST32_MIN
+# define INT_LEAST32_MAX   __INT_LEAST32_MAX
+# define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+# define INT_FAST32_MIN    __INT_LEAST32_MIN
+# define INT_FAST32_MAX    __INT_LEAST32_MAX
+# define UINT_FAST32_MAX  __UINT_LEAST32_MAX
+#endif /* __INT_LEAST32_MIN */
+
+
+#ifdef __INT24_TYPE__
+# define INT24_MAX           INT24_C(8388607)
+# define INT24_MIN         (-INT24_C(8388607)-1)
+# define UINT24_MAX         UINT24_C(16777215)
+# define INT_LEAST24_MIN     INT24_MIN
+# define INT_LEAST24_MAX     INT24_MAX
+# define UINT_LEAST24_MAX   UINT24_MAX
+# define INT_FAST24_MIN      INT24_MIN
+# define INT_FAST24_MAX      INT24_MAX
+# define UINT_FAST24_MAX    UINT24_MAX
+# define __INT_LEAST16_MIN   INT24_MIN
+# define __INT_LEAST16_MAX   INT24_MAX
+# define __UINT_LEAST16_MAX UINT24_MAX
+# define __INT_LEAST8_MIN    INT24_MIN
+# define __INT_LEAST8_MAX    INT24_MAX
+# define __UINT_LEAST8_MAX  UINT24_MAX
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+#define INT16_MAX            INT16_C(32767)
+#define INT16_MIN          (-INT16_C(32767)-1)
+#define UINT16_MAX          UINT16_C(65535)
+# define __INT_LEAST16_MIN   INT16_MIN
+# define __INT_LEAST16_MAX   INT16_MAX
+# define __UINT_LEAST16_MAX UINT16_MAX
+# define __INT_LEAST8_MIN    INT16_MIN
+# define __INT_LEAST8_MAX    INT16_MAX
+# define __UINT_LEAST8_MAX  UINT16_MAX
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT_LEAST16_MIN
+# define INT_LEAST16_MIN   __INT_LEAST16_MIN
+# define INT_LEAST16_MAX   __INT_LEAST16_MAX
+# define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+# define INT_FAST16_MIN    __INT_LEAST16_MIN
+# define INT_FAST16_MAX    __INT_LEAST16_MAX
+# define UINT_FAST16_MAX  __UINT_LEAST16_MAX
+#endif /* __INT_LEAST16_MIN */
+
+
+#ifdef __INT8_TYPE__
+# define INT8_MAX            INT8_C(127)
+# define INT8_MIN          (-INT8_C(127)-1)
+# define UINT8_MAX          UINT8_C(255)
+# define __INT_LEAST8_MIN    INT8_MIN
+# define __INT_LEAST8_MAX    INT8_MAX
+# define __UINT_LEAST8_MAX  UINT8_MAX
+#endif /* __INT8_TYPE__ */
+
+#ifdef __INT_LEAST8_MIN
+# define INT_LEAST8_MIN   __INT_LEAST8_MIN
+# define INT_LEAST8_MAX   __INT_LEAST8_MAX
+# define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+# define INT_FAST8_MIN    __INT_LEAST8_MIN
+# define INT_FAST8_MAX    __INT_LEAST8_MAX
+# define UINT_FAST8_MAX  __UINT_LEAST8_MAX
+#endif /* __INT_LEAST8_MIN */
+
+/* Some utility macros */
+#define  __INTN_MIN(n)  __stdint_join3( INT, n, _MIN)
+#define  __INTN_MAX(n)  __stdint_join3( INT, n, _MAX)
+#define __UINTN_MAX(n)  __stdint_join3(UINT, n, _MAX)
+#define  __INTN_C(n, v) __stdint_join3( INT, n, _C(v))
+#define __UINTN_C(n, v) __stdint_join3(UINT, n, _C(v))
+
+/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
+/* C99 7.18.3 Limits of other integer types. */
+
+#define  INTPTR_MIN  __INTN_MIN(__INTPTR_WIDTH__)
+#define  INTPTR_MAX  __INTN_MAX(__INTPTR_WIDTH__)
+#define UINTPTR_MAX __UINTN_MAX(__INTPTR_WIDTH__)
+#define PTRDIFF_MIN  __INTN_MIN(__PTRDIFF_WIDTH__)
+#define PTRDIFF_MAX  __INTN_MAX(__PTRDIFF_WIDTH__)
+#define    SIZE_MAX __UINTN_MAX(__SIZE_WIDTH__)
+
+/* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__
+ * is enabled. */
+#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
+#define   RSIZE_MAX            (SIZE_MAX >> 1)
+#endif
+
+/* C99 7.18.2.5 Limits of greatest-width integer types. */
+#define INTMAX_MIN   __INTN_MIN(__INTMAX_WIDTH__)
+#define INTMAX_MAX   __INTN_MAX(__INTMAX_WIDTH__)
+#define UINTMAX_MAX __UINTN_MAX(__INTMAX_WIDTH__)
+
+/* C99 7.18.3 Limits of other integer types. */
+#define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__)
+#define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__)
+#ifdef __WINT_UNSIGNED__
+# define WINT_MIN       __UINTN_C(__WINT_WIDTH__, 0)
+# define WINT_MAX       __UINTN_MAX(__WINT_WIDTH__)
+#else
+# define WINT_MIN       __INTN_MIN(__WINT_WIDTH__)
+# define WINT_MAX       __INTN_MAX(__WINT_WIDTH__)
+#endif
+
+#ifndef WCHAR_MAX
+# define WCHAR_MAX __WCHAR_MAX__
+#endif
+#ifndef WCHAR_MIN
+# if __WCHAR_MAX__ == __INTN_MAX(__WCHAR_WIDTH__)
+#  define WCHAR_MIN __INTN_MIN(__WCHAR_WIDTH__)
+# else
+#  define WCHAR_MIN __UINTN_C(__WCHAR_WIDTH__, 0)
+# endif
+#endif
+
+/* 7.18.4.2 Macros for greatest-width integer constants. */
+#define INTMAX_C(v)   __INTN_C(__INTMAX_WIDTH__, v)
+#define UINTMAX_C(v) __UINTN_C(__INTMAX_WIDTH__, v)
+
+#endif /* __STDC_HOSTED__ */
+#endif /* __CLANG_STDINT_H */
diff --git a/lib/clang/3.5.2/include/stdnoreturn.h b/lib/clang/3.5.2/include/stdnoreturn.h
new file mode 100644
index 0000000..a7a301d
--- /dev/null
+++ b/lib/clang/3.5.2/include/stdnoreturn.h
@@ -0,0 +1,30 @@
+/*===---- stdnoreturn.h - Standard header for noreturn macro ---------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDNORETURN_H
+#define __STDNORETURN_H
+
+#define noreturn _Noreturn
+#define __noreturn_is_defined 1
+
+#endif /* __STDNORETURN_H */
diff --git a/lib/clang/3.5.2/include/tbmintrin.h b/lib/clang/3.5.2/include/tbmintrin.h
new file mode 100644
index 0000000..f95e34f
--- /dev/null
+++ b/lib/clang/3.5.2/include/tbmintrin.h
@@ -0,0 +1,158 @@
+/*===---- tbmintrin.h - TBM intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __TBM__
+#error "TBM instruction set is not enabled"
+#endif
+
+#ifndef __X86INTRIN_H
+#error "Never use <tbmintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __TBMINTRIN_H
+#define __TBMINTRIN_H
+
+#define __bextri_u32(a, b) (__builtin_ia32_bextri_u32((a), (b)))
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blcfill_u32(unsigned int a)
+{
+  return a & (a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blci_u32(unsigned int a)
+{
+  return a | ~(a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blcic_u32(unsigned int a)
+{
+  return ~a & (a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blcmsk_u32(unsigned int a)
+{
+  return a ^ (a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blcs_u32(unsigned int a)
+{
+  return a | (a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blsfill_u32(unsigned int a)
+{
+  return a | (a - 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__blsic_u32(unsigned int a)
+{
+  return ~a | (a - 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__t1mskc_u32(unsigned int a)
+{
+  return ~a | (a + 1);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__tzmsk_u32(unsigned int a)
+{
+  return ~a & (a - 1);
+}
+
+#ifdef __x86_64__
+#define __bextri_u64(a, b) (__builtin_ia32_bextri_u64((a), (int)(b)))
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blcfill_u64(unsigned long long a)
+{
+  return a & (a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blci_u64(unsigned long long a)
+{
+  return a | ~(a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blcic_u64(unsigned long long a)
+{
+  return ~a & (a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blcmsk_u64(unsigned long long a)
+{
+  return a ^ (a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blcs_u64(unsigned long long a)
+{
+  return a | (a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blsfill_u64(unsigned long long a)
+{
+  return a | (a - 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__blsic_u64(unsigned long long a)
+{
+  return ~a | (a - 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__t1mskc_u64(unsigned long long a)
+{
+  return ~a | (a + 1);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__,
+                                                    __nodebug__))
+__tzmsk_u64(unsigned long long a)
+{
+  return ~a & (a - 1);
+}
+#endif
+
+#endif /* __TBMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/tgmath.h b/lib/clang/3.5.2/include/tgmath.h
new file mode 100644
index 0000000..a48e267
--- /dev/null
+++ b/lib/clang/3.5.2/include/tgmath.h
@@ -0,0 +1,1374 @@
+/*===---- tgmath.h - Standard header for type generic math ----------------===*\
+ *
+ * Copyright (c) 2009 Howard Hinnant
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#ifndef __TGMATH_H
+#define __TGMATH_H
+
+/* C99 7.22 Type-generic math <tgmath.h>. */
+#include <math.h>
+
+/* C++ handles type genericity with overloading in math.h. */
+#ifndef __cplusplus
+#include <complex.h>
+
+#define _TG_ATTRSp __attribute__((__overloadable__))
+#define _TG_ATTRS __attribute__((__overloadable__, __always_inline__))
+
+// promotion
+
+typedef void _Argument_type_is_not_arithmetic;
+static _Argument_type_is_not_arithmetic __tg_promote(...)
+  __attribute__((__unavailable__,__overloadable__));
+static double               _TG_ATTRSp __tg_promote(int);
+static double               _TG_ATTRSp __tg_promote(unsigned int);
+static double               _TG_ATTRSp __tg_promote(long);
+static double               _TG_ATTRSp __tg_promote(unsigned long);
+static double               _TG_ATTRSp __tg_promote(long long);
+static double               _TG_ATTRSp __tg_promote(unsigned long long);
+static float                _TG_ATTRSp __tg_promote(float);
+static double               _TG_ATTRSp __tg_promote(double);
+static long double          _TG_ATTRSp __tg_promote(long double);
+static float _Complex       _TG_ATTRSp __tg_promote(float _Complex);
+static double _Complex      _TG_ATTRSp __tg_promote(double _Complex);
+static long double _Complex _TG_ATTRSp __tg_promote(long double _Complex);
+
+#define __tg_promote1(__x)           (__typeof__(__tg_promote(__x)))
+#define __tg_promote2(__x, __y)      (__typeof__(__tg_promote(__x) + \
+                                                 __tg_promote(__y)))
+#define __tg_promote3(__x, __y, __z) (__typeof__(__tg_promote(__x) + \
+                                                 __tg_promote(__y) + \
+                                                 __tg_promote(__z)))
+
+// acos
+
+static float
+    _TG_ATTRS
+    __tg_acos(float __x) {return acosf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_acos(double __x) {return acos(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_acos(long double __x) {return acosl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_acos(float _Complex __x) {return cacosf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_acos(double _Complex __x) {return cacos(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_acos(long double _Complex __x) {return cacosl(__x);}
+
+#undef acos
+#define acos(__x) __tg_acos(__tg_promote1((__x))(__x))
+
+// asin
+
+static float
+    _TG_ATTRS
+    __tg_asin(float __x) {return asinf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_asin(double __x) {return asin(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_asin(long double __x) {return asinl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_asin(float _Complex __x) {return casinf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_asin(double _Complex __x) {return casin(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_asin(long double _Complex __x) {return casinl(__x);}
+
+#undef asin
+#define asin(__x) __tg_asin(__tg_promote1((__x))(__x))
+
+// atan
+
+static float
+    _TG_ATTRS
+    __tg_atan(float __x) {return atanf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_atan(double __x) {return atan(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_atan(long double __x) {return atanl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_atan(float _Complex __x) {return catanf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_atan(double _Complex __x) {return catan(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_atan(long double _Complex __x) {return catanl(__x);}
+
+#undef atan
+#define atan(__x) __tg_atan(__tg_promote1((__x))(__x))
+
+// acosh
+
+static float
+    _TG_ATTRS
+    __tg_acosh(float __x) {return acoshf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_acosh(double __x) {return acosh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_acosh(long double __x) {return acoshl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_acosh(float _Complex __x) {return cacoshf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_acosh(double _Complex __x) {return cacosh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_acosh(long double _Complex __x) {return cacoshl(__x);}
+
+#undef acosh
+#define acosh(__x) __tg_acosh(__tg_promote1((__x))(__x))
+
+// asinh
+
+static float
+    _TG_ATTRS
+    __tg_asinh(float __x) {return asinhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_asinh(double __x) {return asinh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_asinh(long double __x) {return asinhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_asinh(float _Complex __x) {return casinhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_asinh(double _Complex __x) {return casinh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_asinh(long double _Complex __x) {return casinhl(__x);}
+
+#undef asinh
+#define asinh(__x) __tg_asinh(__tg_promote1((__x))(__x))
+
+// atanh
+
+static float
+    _TG_ATTRS
+    __tg_atanh(float __x) {return atanhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_atanh(double __x) {return atanh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_atanh(long double __x) {return atanhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_atanh(float _Complex __x) {return catanhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_atanh(double _Complex __x) {return catanh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_atanh(long double _Complex __x) {return catanhl(__x);}
+
+#undef atanh
+#define atanh(__x) __tg_atanh(__tg_promote1((__x))(__x))
+
+// cos
+
+static float
+    _TG_ATTRS
+    __tg_cos(float __x) {return cosf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cos(double __x) {return cos(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cos(long double __x) {return cosl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cos(float _Complex __x) {return ccosf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cos(double _Complex __x) {return ccos(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cos(long double _Complex __x) {return ccosl(__x);}
+
+#undef cos
+#define cos(__x) __tg_cos(__tg_promote1((__x))(__x))
+
+// sin
+
+static float
+    _TG_ATTRS
+    __tg_sin(float __x) {return sinf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sin(double __x) {return sin(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sin(long double __x) {return sinl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sin(float _Complex __x) {return csinf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sin(double _Complex __x) {return csin(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sin(long double _Complex __x) {return csinl(__x);}
+
+#undef sin
+#define sin(__x) __tg_sin(__tg_promote1((__x))(__x))
+
+// tan
+
+static float
+    _TG_ATTRS
+    __tg_tan(float __x) {return tanf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tan(double __x) {return tan(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tan(long double __x) {return tanl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_tan(float _Complex __x) {return ctanf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_tan(double _Complex __x) {return ctan(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_tan(long double _Complex __x) {return ctanl(__x);}
+
+#undef tan
+#define tan(__x) __tg_tan(__tg_promote1((__x))(__x))
+
+// cosh
+
+static float
+    _TG_ATTRS
+    __tg_cosh(float __x) {return coshf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cosh(double __x) {return cosh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cosh(long double __x) {return coshl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cosh(float _Complex __x) {return ccoshf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cosh(double _Complex __x) {return ccosh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cosh(long double _Complex __x) {return ccoshl(__x);}
+
+#undef cosh
+#define cosh(__x) __tg_cosh(__tg_promote1((__x))(__x))
+
+// sinh
+
+static float
+    _TG_ATTRS
+    __tg_sinh(float __x) {return sinhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sinh(double __x) {return sinh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sinh(long double __x) {return sinhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sinh(float _Complex __x) {return csinhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sinh(double _Complex __x) {return csinh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sinh(long double _Complex __x) {return csinhl(__x);}
+
+#undef sinh
+#define sinh(__x) __tg_sinh(__tg_promote1((__x))(__x))
+
+// tanh
+
+static float
+    _TG_ATTRS
+    __tg_tanh(float __x) {return tanhf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tanh(double __x) {return tanh(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tanh(long double __x) {return tanhl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_tanh(float _Complex __x) {return ctanhf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_tanh(double _Complex __x) {return ctanh(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_tanh(long double _Complex __x) {return ctanhl(__x);}
+
+#undef tanh
+#define tanh(__x) __tg_tanh(__tg_promote1((__x))(__x))
+
+// exp
+
+static float
+    _TG_ATTRS
+    __tg_exp(float __x) {return expf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_exp(double __x) {return exp(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_exp(long double __x) {return expl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_exp(float _Complex __x) {return cexpf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_exp(double _Complex __x) {return cexp(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_exp(long double _Complex __x) {return cexpl(__x);}
+
+#undef exp
+#define exp(__x) __tg_exp(__tg_promote1((__x))(__x))
+
+// log
+
+static float
+    _TG_ATTRS
+    __tg_log(float __x) {return logf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log(double __x) {return log(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log(long double __x) {return logl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_log(float _Complex __x) {return clogf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_log(double _Complex __x) {return clog(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_log(long double _Complex __x) {return clogl(__x);}
+
+#undef log
+#define log(__x) __tg_log(__tg_promote1((__x))(__x))
+
+// pow
+
+static float
+    _TG_ATTRS
+    __tg_pow(float __x, float __y) {return powf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_pow(double __x, double __y) {return pow(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_pow(long double __x, long double __y) {return powl(__x, __y);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_pow(float _Complex __x, float _Complex __y) {return cpowf(__x, __y);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_pow(double _Complex __x, double _Complex __y) {return cpow(__x, __y);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_pow(long double _Complex __x, long double _Complex __y) 
+    {return cpowl(__x, __y);}
+
+#undef pow
+#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \
+                               __tg_promote2((__x), (__y))(__y))
+
+// sqrt
+
+static float
+    _TG_ATTRS
+    __tg_sqrt(float __x) {return sqrtf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_sqrt(double __x) {return sqrt(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_sqrt(long double __x) {return sqrtl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_sqrt(float _Complex __x) {return csqrtf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_sqrt(double _Complex __x) {return csqrt(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_sqrt(long double _Complex __x) {return csqrtl(__x);}
+
+#undef sqrt
+#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x))
+
+// fabs
+
+static float
+    _TG_ATTRS
+    __tg_fabs(float __x) {return fabsf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_fabs(double __x) {return fabs(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_fabs(long double __x) {return fabsl(__x);}
+
+static float
+    _TG_ATTRS
+    __tg_fabs(float _Complex __x) {return cabsf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_fabs(double _Complex __x) {return cabs(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_fabs(long double _Complex __x) {return cabsl(__x);}
+
+#undef fabs
+#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x))
+
+// atan2
+
+static float
+    _TG_ATTRS
+    __tg_atan2(float __x, float __y) {return atan2f(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_atan2(double __x, double __y) {return atan2(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_atan2(long double __x, long double __y) {return atan2l(__x, __y);}
+
+#undef atan2
+#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \
+                                   __tg_promote2((__x), (__y))(__y))
+
+// cbrt
+
+static float
+    _TG_ATTRS
+    __tg_cbrt(float __x) {return cbrtf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cbrt(double __x) {return cbrt(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cbrt(long double __x) {return cbrtl(__x);}
+
+#undef cbrt
+#define cbrt(__x) __tg_cbrt(__tg_promote1((__x))(__x))
+
+// ceil
+
+static float
+    _TG_ATTRS
+    __tg_ceil(float __x) {return ceilf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_ceil(double __x) {return ceil(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_ceil(long double __x) {return ceill(__x);}
+
+#undef ceil
+#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x))
+
+// copysign
+
+static float
+    _TG_ATTRS
+    __tg_copysign(float __x, float __y) {return copysignf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_copysign(double __x, double __y) {return copysign(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_copysign(long double __x, long double __y) {return copysignl(__x, __y);}
+
+#undef copysign
+#define copysign(__x, __y) __tg_copysign(__tg_promote2((__x), (__y))(__x), \
+                                         __tg_promote2((__x), (__y))(__y))
+
+// erf
+
+static float
+    _TG_ATTRS
+    __tg_erf(float __x) {return erff(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_erf(double __x) {return erf(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_erf(long double __x) {return erfl(__x);}
+
+#undef erf
+#define erf(__x) __tg_erf(__tg_promote1((__x))(__x))
+
+// erfc
+
+static float
+    _TG_ATTRS
+    __tg_erfc(float __x) {return erfcf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_erfc(double __x) {return erfc(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_erfc(long double __x) {return erfcl(__x);}
+
+#undef erfc
+#define erfc(__x) __tg_erfc(__tg_promote1((__x))(__x))
+
+// exp2
+
+static float
+    _TG_ATTRS
+    __tg_exp2(float __x) {return exp2f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_exp2(double __x) {return exp2(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_exp2(long double __x) {return exp2l(__x);}
+
+#undef exp2
+#define exp2(__x) __tg_exp2(__tg_promote1((__x))(__x))
+
+// expm1
+
+static float
+    _TG_ATTRS
+    __tg_expm1(float __x) {return expm1f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_expm1(double __x) {return expm1(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_expm1(long double __x) {return expm1l(__x);}
+
+#undef expm1
+#define expm1(__x) __tg_expm1(__tg_promote1((__x))(__x))
+
+// fdim
+
+static float
+    _TG_ATTRS
+    __tg_fdim(float __x, float __y) {return fdimf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fdim(double __x, double __y) {return fdim(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fdim(long double __x, long double __y) {return fdiml(__x, __y);}
+
+#undef fdim
+#define fdim(__x, __y) __tg_fdim(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// floor
+
+static float
+    _TG_ATTRS
+    __tg_floor(float __x) {return floorf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_floor(double __x) {return floor(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_floor(long double __x) {return floorl(__x);}
+
+#undef floor
+#define floor(__x) __tg_floor(__tg_promote1((__x))(__x))
+
+// fma
+
+static float
+    _TG_ATTRS
+    __tg_fma(float __x, float __y, float __z)
+    {return fmaf(__x, __y, __z);}
+
+static double
+    _TG_ATTRS
+    __tg_fma(double __x, double __y, double __z)
+    {return fma(__x, __y, __z);}
+
+static long double
+    _TG_ATTRS
+    __tg_fma(long double __x,long double __y, long double __z)
+    {return fmal(__x, __y, __z);}
+
+#undef fma
+#define fma(__x, __y, __z)                                \
+        __tg_fma(__tg_promote3((__x), (__y), (__z))(__x), \
+                 __tg_promote3((__x), (__y), (__z))(__y), \
+                 __tg_promote3((__x), (__y), (__z))(__z))
+
+// fmax
+
+static float
+    _TG_ATTRS
+    __tg_fmax(float __x, float __y) {return fmaxf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmax(double __x, double __y) {return fmax(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmax(long double __x, long double __y) {return fmaxl(__x, __y);}
+
+#undef fmax
+#define fmax(__x, __y) __tg_fmax(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// fmin
+
+static float
+    _TG_ATTRS
+    __tg_fmin(float __x, float __y) {return fminf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmin(double __x, double __y) {return fmin(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmin(long double __x, long double __y) {return fminl(__x, __y);}
+
+#undef fmin
+#define fmin(__x, __y) __tg_fmin(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// fmod
+
+static float
+    _TG_ATTRS
+    __tg_fmod(float __x, float __y) {return fmodf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_fmod(double __x, double __y) {return fmod(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_fmod(long double __x, long double __y) {return fmodl(__x, __y);}
+
+#undef fmod
+#define fmod(__x, __y) __tg_fmod(__tg_promote2((__x), (__y))(__x), \
+                                 __tg_promote2((__x), (__y))(__y))
+
+// frexp
+
+static float
+    _TG_ATTRS
+    __tg_frexp(float __x, int* __y) {return frexpf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_frexp(double __x, int* __y) {return frexp(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_frexp(long double __x, int* __y) {return frexpl(__x, __y);}
+
+#undef frexp
+#define frexp(__x, __y) __tg_frexp(__tg_promote1((__x))(__x), __y)
+
+// hypot
+
+static float
+    _TG_ATTRS
+    __tg_hypot(float __x, float __y) {return hypotf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_hypot(double __x, double __y) {return hypot(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_hypot(long double __x, long double __y) {return hypotl(__x, __y);}
+
+#undef hypot
+#define hypot(__x, __y) __tg_hypot(__tg_promote2((__x), (__y))(__x), \
+                                   __tg_promote2((__x), (__y))(__y))
+
+// ilogb
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(float __x) {return ilogbf(__x);}
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(double __x) {return ilogb(__x);}
+
+static int
+    _TG_ATTRS
+    __tg_ilogb(long double __x) {return ilogbl(__x);}
+
+#undef ilogb
+#define ilogb(__x) __tg_ilogb(__tg_promote1((__x))(__x))
+
+// ldexp
+
+static float
+    _TG_ATTRS
+    __tg_ldexp(float __x, int __y) {return ldexpf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_ldexp(double __x, int __y) {return ldexp(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_ldexp(long double __x, int __y) {return ldexpl(__x, __y);}
+
+#undef ldexp
+#define ldexp(__x, __y) __tg_ldexp(__tg_promote1((__x))(__x), __y)
+
+// lgamma
+
+static float
+    _TG_ATTRS
+    __tg_lgamma(float __x) {return lgammaf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_lgamma(double __x) {return lgamma(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_lgamma(long double __x) {return lgammal(__x);}
+
+#undef lgamma
+#define lgamma(__x) __tg_lgamma(__tg_promote1((__x))(__x))
+
+// llrint
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(float __x) {return llrintf(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(double __x) {return llrint(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llrint(long double __x) {return llrintl(__x);}
+
+#undef llrint
+#define llrint(__x) __tg_llrint(__tg_promote1((__x))(__x))
+
+// llround
+
+static long long
+    _TG_ATTRS
+    __tg_llround(float __x) {return llroundf(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llround(double __x) {return llround(__x);}
+
+static long long
+    _TG_ATTRS
+    __tg_llround(long double __x) {return llroundl(__x);}
+
+#undef llround
+#define llround(__x) __tg_llround(__tg_promote1((__x))(__x))
+
+// log10
+
+static float
+    _TG_ATTRS
+    __tg_log10(float __x) {return log10f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log10(double __x) {return log10(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log10(long double __x) {return log10l(__x);}
+
+#undef log10
+#define log10(__x) __tg_log10(__tg_promote1((__x))(__x))
+
+// log1p
+
+static float
+    _TG_ATTRS
+    __tg_log1p(float __x) {return log1pf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log1p(double __x) {return log1p(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log1p(long double __x) {return log1pl(__x);}
+
+#undef log1p
+#define log1p(__x) __tg_log1p(__tg_promote1((__x))(__x))
+
+// log2
+
+static float
+    _TG_ATTRS
+    __tg_log2(float __x) {return log2f(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_log2(double __x) {return log2(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_log2(long double __x) {return log2l(__x);}
+
+#undef log2
+#define log2(__x) __tg_log2(__tg_promote1((__x))(__x))
+
+// logb
+
+static float
+    _TG_ATTRS
+    __tg_logb(float __x) {return logbf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_logb(double __x) {return logb(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_logb(long double __x) {return logbl(__x);}
+
+#undef logb
+#define logb(__x) __tg_logb(__tg_promote1((__x))(__x))
+
+// lrint
+
+static long
+    _TG_ATTRS
+    __tg_lrint(float __x) {return lrintf(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lrint(double __x) {return lrint(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lrint(long double __x) {return lrintl(__x);}
+
+#undef lrint
+#define lrint(__x) __tg_lrint(__tg_promote1((__x))(__x))
+
+// lround
+
+static long
+    _TG_ATTRS
+    __tg_lround(float __x) {return lroundf(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lround(double __x) {return lround(__x);}
+
+static long
+    _TG_ATTRS
+    __tg_lround(long double __x) {return lroundl(__x);}
+
+#undef lround
+#define lround(__x) __tg_lround(__tg_promote1((__x))(__x))
+
+// nearbyint
+
+static float
+    _TG_ATTRS
+    __tg_nearbyint(float __x) {return nearbyintf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_nearbyint(double __x) {return nearbyint(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_nearbyint(long double __x) {return nearbyintl(__x);}
+
+#undef nearbyint
+#define nearbyint(__x) __tg_nearbyint(__tg_promote1((__x))(__x))
+
+// nextafter
+
+static float
+    _TG_ATTRS
+    __tg_nextafter(float __x, float __y) {return nextafterf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_nextafter(double __x, double __y) {return nextafter(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_nextafter(long double __x, long double __y) {return nextafterl(__x, __y);}
+
+#undef nextafter
+#define nextafter(__x, __y) __tg_nextafter(__tg_promote2((__x), (__y))(__x), \
+                                           __tg_promote2((__x), (__y))(__y))
+
+// nexttoward
+
+static float
+    _TG_ATTRS
+    __tg_nexttoward(float __x, long double __y) {return nexttowardf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_nexttoward(double __x, long double __y) {return nexttoward(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_nexttoward(long double __x, long double __y) {return nexttowardl(__x, __y);}
+
+#undef nexttoward
+#define nexttoward(__x, __y) __tg_nexttoward(__tg_promote1((__x))(__x), (__y))
+
+// remainder
+
+static float
+    _TG_ATTRS
+    __tg_remainder(float __x, float __y) {return remainderf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_remainder(double __x, double __y) {return remainder(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_remainder(long double __x, long double __y) {return remainderl(__x, __y);}
+
+#undef remainder
+#define remainder(__x, __y) __tg_remainder(__tg_promote2((__x), (__y))(__x), \
+                                           __tg_promote2((__x), (__y))(__y))
+
+// remquo
+
+static float
+    _TG_ATTRS
+    __tg_remquo(float __x, float __y, int* __z)
+    {return remquof(__x, __y, __z);}
+
+static double
+    _TG_ATTRS
+    __tg_remquo(double __x, double __y, int* __z)
+    {return remquo(__x, __y, __z);}
+
+static long double
+    _TG_ATTRS
+    __tg_remquo(long double __x,long double __y, int* __z)
+    {return remquol(__x, __y, __z);}
+
+#undef remquo
+#define remquo(__x, __y, __z)                         \
+        __tg_remquo(__tg_promote2((__x), (__y))(__x), \
+                    __tg_promote2((__x), (__y))(__y), \
+                    (__z))
+
+// rint
+
+static float
+    _TG_ATTRS
+    __tg_rint(float __x) {return rintf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_rint(double __x) {return rint(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_rint(long double __x) {return rintl(__x);}
+
+#undef rint
+#define rint(__x) __tg_rint(__tg_promote1((__x))(__x))
+
+// round
+
+static float
+    _TG_ATTRS
+    __tg_round(float __x) {return roundf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_round(double __x) {return round(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_round(long double __x) {return roundl(__x);}
+
+#undef round
+#define round(__x) __tg_round(__tg_promote1((__x))(__x))
+
+// scalbn
+
+static float
+    _TG_ATTRS
+    __tg_scalbn(float __x, int __y) {return scalbnf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_scalbn(double __x, int __y) {return scalbn(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_scalbn(long double __x, int __y) {return scalbnl(__x, __y);}
+
+#undef scalbn
+#define scalbn(__x, __y) __tg_scalbn(__tg_promote1((__x))(__x), __y)
+
+// scalbln
+
+static float
+    _TG_ATTRS
+    __tg_scalbln(float __x, long __y) {return scalblnf(__x, __y);}
+
+static double
+    _TG_ATTRS
+    __tg_scalbln(double __x, long __y) {return scalbln(__x, __y);}
+
+static long double
+    _TG_ATTRS
+    __tg_scalbln(long double __x, long __y) {return scalblnl(__x, __y);}
+
+#undef scalbln
+#define scalbln(__x, __y) __tg_scalbln(__tg_promote1((__x))(__x), __y)
+
+// tgamma
+
+static float
+    _TG_ATTRS
+    __tg_tgamma(float __x) {return tgammaf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_tgamma(double __x) {return tgamma(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_tgamma(long double __x) {return tgammal(__x);}
+
+#undef tgamma
+#define tgamma(__x) __tg_tgamma(__tg_promote1((__x))(__x))
+
+// trunc
+
+static float
+    _TG_ATTRS
+    __tg_trunc(float __x) {return truncf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_trunc(double __x) {return trunc(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_trunc(long double __x) {return truncl(__x);}
+
+#undef trunc
+#define trunc(__x) __tg_trunc(__tg_promote1((__x))(__x))
+
+// carg
+
+static float
+    _TG_ATTRS
+    __tg_carg(float __x) {return atan2f(0.F, __x);}
+
+static double
+    _TG_ATTRS
+    __tg_carg(double __x) {return atan2(0., __x);}
+
+static long double
+    _TG_ATTRS
+    __tg_carg(long double __x) {return atan2l(0.L, __x);}
+
+static float
+    _TG_ATTRS
+    __tg_carg(float _Complex __x) {return cargf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_carg(double _Complex __x) {return carg(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_carg(long double _Complex __x) {return cargl(__x);}
+
+#undef carg
+#define carg(__x) __tg_carg(__tg_promote1((__x))(__x))
+
+// cimag
+
+static float
+    _TG_ATTRS
+    __tg_cimag(float __x) {return 0;}
+
+static double
+    _TG_ATTRS
+    __tg_cimag(double __x) {return 0;}
+
+static long double
+    _TG_ATTRS
+    __tg_cimag(long double __x) {return 0;}
+
+static float
+    _TG_ATTRS
+    __tg_cimag(float _Complex __x) {return cimagf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_cimag(double _Complex __x) {return cimag(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_cimag(long double _Complex __x) {return cimagl(__x);}
+
+#undef cimag
+#define cimag(__x) __tg_cimag(__tg_promote1((__x))(__x))
+
+// conj
+
+static float _Complex
+    _TG_ATTRS
+    __tg_conj(float __x) {return __x;}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_conj(double __x) {return __x;}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_conj(long double __x) {return __x;}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_conj(float _Complex __x) {return conjf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_conj(double _Complex __x) {return conj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_conj(long double _Complex __x) {return conjl(__x);}
+
+#undef conj
+#define conj(__x) __tg_conj(__tg_promote1((__x))(__x))
+
+// cproj
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cproj(float __x) {return cprojf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cproj(double __x) {return cproj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cproj(long double __x) {return cprojl(__x);}
+
+static float _Complex
+    _TG_ATTRS
+    __tg_cproj(float _Complex __x) {return cprojf(__x);}
+
+static double _Complex
+    _TG_ATTRS
+    __tg_cproj(double _Complex __x) {return cproj(__x);}
+
+static long double _Complex
+    _TG_ATTRS
+    __tg_cproj(long double _Complex __x) {return cprojl(__x);}
+
+#undef cproj
+#define cproj(__x) __tg_cproj(__tg_promote1((__x))(__x))
+
+// creal
+
+static float
+    _TG_ATTRS
+    __tg_creal(float __x) {return __x;}
+
+static double
+    _TG_ATTRS
+    __tg_creal(double __x) {return __x;}
+
+static long double
+    _TG_ATTRS
+    __tg_creal(long double __x) {return __x;}
+
+static float
+    _TG_ATTRS
+    __tg_creal(float _Complex __x) {return crealf(__x);}
+
+static double
+    _TG_ATTRS
+    __tg_creal(double _Complex __x) {return creal(__x);}
+
+static long double
+    _TG_ATTRS
+    __tg_creal(long double _Complex __x) {return creall(__x);}
+
+#undef creal
+#define creal(__x) __tg_creal(__tg_promote1((__x))(__x))
+
+#undef _TG_ATTRSp
+#undef _TG_ATTRS
+
+#endif /* __cplusplus */
+#endif /* __TGMATH_H */
diff --git a/lib/clang/3.5.2/include/tmmintrin.h b/lib/clang/3.5.2/include/tmmintrin.h
new file mode 100644
index 0000000..4238f5b
--- /dev/null
+++ b/lib/clang/3.5.2/include/tmmintrin.h
@@ -0,0 +1,225 @@
+/*===---- tmmintrin.h - SSSE3 intrinsics -----------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __TMMINTRIN_H
+#define __TMMINTRIN_H
+
+#ifndef __SSSE3__
+#error "SSSE3 instruction set not enabled"
+#else
+
+#include <pmmintrin.h>
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi8(__m64 __a)
+{
+    return (__m64)__builtin_ia32_pabsb((__v8qi)__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi8(__m128i __a)
+{
+    return (__m128i)__builtin_ia32_pabsb128((__v16qi)__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi16(__m64 __a)
+{
+    return (__m64)__builtin_ia32_pabsw((__v4hi)__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi16(__m128i __a)
+{
+    return (__m128i)__builtin_ia32_pabsw128((__v8hi)__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_abs_pi32(__m64 __a)
+{
+    return (__m64)__builtin_ia32_pabsd((__v2si)__a);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_abs_epi32(__m128i __a)
+{
+    return (__m128i)__builtin_ia32_pabsd128((__v4si)__a);
+}
+
+#define _mm_alignr_epi8(a, b, n) __extension__ ({ \
+  __m128i __a = (a); \
+  __m128i __b = (b); \
+  (__m128i)__builtin_ia32_palignr128((__v16qi)__a, (__v16qi)__b, (n)); })
+
+#define _mm_alignr_pi8(a, b, n) __extension__ ({ \
+  __m64 __a = (a); \
+  __m64 __b = (b); \
+  (__m64)__builtin_ia32_palignr((__v8qi)__a, (__v8qi)__b, (n)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phaddw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_epi32(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phaddd128((__v4si)__a, (__v4si)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phaddw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadd_pi32(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phaddd((__v2si)__a, (__v2si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hadds_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phaddsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hadds_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phaddsw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phsubw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_epi32(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phsubd128((__v4si)__a, (__v4si)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phsubw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsub_pi32(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phsubd((__v2si)__a, (__v2si)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsubs_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_phsubsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_hsubs_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_phsubsw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maddubs_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_pmaddubsw128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_maddubs_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_pmaddubsw((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mulhrs_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_pmulhrsw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhrs_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_pmulhrsw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shuffle_epi8(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_pshufb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_shuffle_pi8(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_pshufb((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi8(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_psignb128((__v16qi)__a, (__v16qi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi16(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_psignw128((__v8hi)__a, (__v8hi)__b);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sign_epi32(__m128i __a, __m128i __b)
+{
+    return (__m128i)__builtin_ia32_psignd128((__v4si)__a, (__v4si)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi8(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_psignb((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi16(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_psignw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sign_pi32(__m64 __a, __m64 __b)
+{
+    return (__m64)__builtin_ia32_psignd((__v2si)__a, (__v2si)__b);
+}
+
+#endif /* __SSSE3__ */
+
+#endif /* __TMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/unwind.h b/lib/clang/3.5.2/include/unwind.h
new file mode 100644
index 0000000..685c1df
--- /dev/null
+++ b/lib/clang/3.5.2/include/unwind.h
@@ -0,0 +1,280 @@
+/*===---- unwind.h - Stack unwinding ----------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+/* See "Data Definitions for libgcc_s" in the Linux Standard Base.*/
+
+#ifndef __CLANG_UNWIND_H
+#define __CLANG_UNWIND_H
+
+#if __has_include_next(<unwind.h>)
+/* Darwin (from 11.x on) and libunwind provide an unwind.h. If that's available,
+ * use it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE,
+ * so define that around the include.*/
+# ifndef _GNU_SOURCE
+#  define _SHOULD_UNDEFINE_GNU_SOURCE
+#  define _GNU_SOURCE
+# endif
+// libunwind's unwind.h reflects the current visibility.  However, Mozilla
+// builds with -fvisibility=hidden and relies on gcc's unwind.h to reset the
+// visibility to default and export its contents.  gcc also allows users to
+// override its override by #defining HIDE_EXPORTS (but note, this only obeys
+// the user's -fvisibility setting; it doesn't hide any exports on its own).  We
+// imitate gcc's header here:
+# ifdef HIDE_EXPORTS
+#  include_next <unwind.h>
+# else
+#  pragma GCC visibility push(default)
+#  include_next <unwind.h>
+#  pragma GCC visibility pop
+# endif
+# ifdef _SHOULD_UNDEFINE_GNU_SOURCE
+#  undef _GNU_SOURCE
+#  undef _SHOULD_UNDEFINE_GNU_SOURCE
+# endif
+#else
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* It is a bit strange for a header to play with the visibility of the
+   symbols it declares, but this matches gcc's behavior and some programs
+   depend on it */
+#ifndef HIDE_EXPORTS
+#pragma GCC visibility push(default)
+#endif
+
+typedef uintptr_t _Unwind_Word;
+typedef intptr_t _Unwind_Sword;
+typedef uintptr_t _Unwind_Ptr;
+typedef uintptr_t _Unwind_Internal_Ptr;
+typedef uint64_t _Unwind_Exception_Class;
+
+typedef intptr_t _sleb128_t;
+typedef uintptr_t _uleb128_t;
+
+struct _Unwind_Context;
+struct _Unwind_Exception;
+typedef enum {
+  _URC_NO_REASON = 0,
+  _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+
+  _URC_FATAL_PHASE2_ERROR = 2,
+  _URC_FATAL_PHASE1_ERROR = 3,
+  _URC_NORMAL_STOP = 4,
+
+  _URC_END_OF_STACK = 5,
+  _URC_HANDLER_FOUND = 6,
+  _URC_INSTALL_CONTEXT = 7,
+  _URC_CONTINUE_UNWIND = 8
+} _Unwind_Reason_Code;
+
+typedef enum {
+  _UA_SEARCH_PHASE = 1,
+  _UA_CLEANUP_PHASE = 2,
+
+  _UA_HANDLER_FRAME = 4,
+  _UA_FORCE_UNWIND = 8,
+  _UA_END_OF_STACK = 16 /* gcc extension to C++ ABI */
+} _Unwind_Action;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
+                                             struct _Unwind_Exception *);
+
+struct _Unwind_Exception {
+  _Unwind_Exception_Class exception_class;
+  _Unwind_Exception_Cleanup_Fn exception_cleanup;
+  _Unwind_Word private_1;
+  _Unwind_Word private_2;
+  /* The Itanium ABI requires that _Unwind_Exception objects are "double-word
+   * aligned".  GCC has interpreted this to mean "use the maximum useful
+   * alignment for the target"; so do we. */
+} __attribute__((__aligned__));
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
+                                               _Unwind_Exception_Class,
+                                               struct _Unwind_Exception *,
+                                               struct _Unwind_Context *,
+                                               void *);
+
+typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
+    int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
+    struct _Unwind_Context *);
+typedef _Unwind_Personality_Fn __personality_routine;
+
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
+                                                void *);
+
+#if defined(__arm__) && !defined(__APPLE__)
+
+typedef enum {
+  _UVRSC_CORE = 0,        /* integer register */
+  _UVRSC_VFP = 1,         /* vfp */
+  _UVRSC_WMMXD = 3,       /* Intel WMMX data register */
+  _UVRSC_WMMXC = 4        /* Intel WMMX control register */
+} _Unwind_VRS_RegClass;
+
+typedef enum {
+  _UVRSD_UINT32 = 0,
+  _UVRSD_VFPX = 1,
+  _UVRSD_UINT64 = 3,
+  _UVRSD_FLOAT = 4,
+  _UVRSD_DOUBLE = 5
+} _Unwind_VRS_DataRepresentation;
+
+typedef enum {
+  _UVRSR_OK = 0,
+  _UVRSR_NOT_IMPLEMENTED = 1,
+  _UVRSR_FAILED = 2
+} _Unwind_VRS_Result;
+
+_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
+  _Unwind_VRS_RegClass __regclass,
+  uint32_t __regno,
+  _Unwind_VRS_DataRepresentation __representation,
+  void *__valuep);
+
+_Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *__context,
+  _Unwind_VRS_RegClass __regclass,
+  uint32_t __regno,
+  _Unwind_VRS_DataRepresentation __representation,
+  void *__valuep);
+
+static __inline__
+_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *__context, int __index) {
+  _Unwind_Word __value;
+  _Unwind_VRS_Get(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value);
+  return __value;
+}
+
+static __inline__
+void _Unwind_SetGR(struct _Unwind_Context *__context, int __index,
+                   _Unwind_Word __value) {
+  _Unwind_VRS_Set(__context, _UVRSC_CORE, __index, _UVRSD_UINT32, &__value);
+}
+
+static __inline__
+_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *__context) {
+  _Unwind_Word __ip = _Unwind_GetGR(__context, 15);
+  return __ip & ~(_Unwind_Word)(0x1); /* Remove thumb mode bit. */
+}
+
+static __inline__
+void _Unwind_SetIP(struct _Unwind_Context *__context, _Unwind_Word __value) {
+  _Unwind_Word __thumb_mode_bit = _Unwind_GetGR(__context, 15) & 0x1;
+  _Unwind_SetGR(__context, 15, __value | __thumb_mode_bit);
+}
+#else
+_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *, int);
+void _Unwind_SetGR(struct _Unwind_Context *, int, _Unwind_Word);
+
+_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *);
+void _Unwind_SetIP(struct _Unwind_Context *, _Unwind_Word);
+#endif
+
+
+_Unwind_Word _Unwind_GetIPInfo(struct _Unwind_Context *, int *);
+
+_Unwind_Word _Unwind_GetCFA(struct _Unwind_Context *);
+
+void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *);
+
+_Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
+
+/* DWARF EH functions; currently not available on Darwin/ARM */
+#if !defined(__APPLE__) || !defined(__arm__)
+
+_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
+_Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *,
+                                         _Unwind_Stop_Fn, void *);
+void _Unwind_DeleteException(struct _Unwind_Exception *);
+void _Unwind_Resume(struct _Unwind_Exception *);
+_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
+
+#endif
+
+_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
+
+/* setjmp(3)/longjmp(3) stuff */
+typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
+
+void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
+void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
+_Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
+_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,
+                                              _Unwind_Stop_Fn, void *);
+void _Unwind_SjLj_Resume(struct _Unwind_Exception *);
+_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
+
+void *_Unwind_FindEnclosingFunction(void *);
+
+#ifdef __APPLE__
+
+_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *)
+    __attribute__((unavailable));
+_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *)
+    __attribute__((unavailable));
+
+/* Darwin-specific functions */
+void __register_frame(const void *);
+void __deregister_frame(const void *);
+
+struct dwarf_eh_bases {
+  uintptr_t tbase;
+  uintptr_t dbase;
+  uintptr_t func;
+};
+void *_Unwind_Find_FDE(const void *, struct dwarf_eh_bases *);
+
+void __register_frame_info_bases(const void *, void *, void *, void *)
+  __attribute__((unavailable));
+void __register_frame_info(const void *, void *) __attribute__((unavailable));
+void __register_frame_info_table_bases(const void *, void*, void *, void *)
+  __attribute__((unavailable));
+void __register_frame_info_table(const void *, void *)
+  __attribute__((unavailable));
+void __register_frame_table(const void *) __attribute__((unavailable));
+void __deregister_frame_info(const void *) __attribute__((unavailable));
+void __deregister_frame_info_bases(const void *)__attribute__((unavailable));
+
+#else
+
+_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *);
+_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *);
+
+#endif
+
+
+#ifndef HIDE_EXPORTS
+#pragma GCC visibility pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif /* __CLANG_UNWIND_H */
diff --git a/lib/clang/3.5.2/include/varargs.h b/lib/clang/3.5.2/include/varargs.h
new file mode 100644
index 0000000..b5477d0
--- /dev/null
+++ b/lib/clang/3.5.2/include/varargs.h
@@ -0,0 +1,26 @@
+/*===---- varargs.h - Variable argument handling -------------------------------------===
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+*===-----------------------------------------------------------------------===
+*/
+#ifndef __VARARGS_H
+#define __VARARGS_H
+  #error "Please use <stdarg.h> instead of <varargs.h>"
+#endif
diff --git a/lib/clang/3.5.2/include/wmmintrin.h b/lib/clang/3.5.2/include/wmmintrin.h
new file mode 100644
index 0000000..369e3c2
--- /dev/null
+++ b/lib/clang/3.5.2/include/wmmintrin.h
@@ -0,0 +1,42 @@
+/*===---- wmmintrin.h - AES intrinsics ------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _WMMINTRIN_H
+#define _WMMINTRIN_H
+
+#include <emmintrin.h>
+
+#if !defined (__AES__) && !defined (__PCLMUL__)
+# error "AES/PCLMUL instructions not enabled"
+#else
+
+#ifdef __AES__
+#include <__wmmintrin_aes.h>
+#endif /* __AES__ */
+
+#ifdef __PCLMUL__
+#include <__wmmintrin_pclmul.h>
+#endif /* __PCLMUL__ */
+
+#endif /* __AES__ || __PCLMUL__ */
+#endif /* _WMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/x86intrin.h b/lib/clang/3.5.2/include/x86intrin.h
new file mode 100644
index 0000000..21a43da
--- /dev/null
+++ b/lib/clang/3.5.2/include/x86intrin.h
@@ -0,0 +1,81 @@
+/*===---- x86intrin.h - X86 intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86INTRIN_H
+#define __X86INTRIN_H
+
+#include <ia32intrin.h>
+
+#include <immintrin.h>
+
+#ifdef __3dNOW__
+#include <mm3dnow.h>
+#endif
+
+#ifdef __BMI__
+#include <bmiintrin.h>
+#endif
+
+#ifdef __BMI2__
+#include <bmi2intrin.h>
+#endif
+
+#ifdef __LZCNT__
+#include <lzcntintrin.h>
+#endif
+
+#ifdef __POPCNT__
+#include <popcntintrin.h>
+#endif
+
+#ifdef __RDSEED__
+#include <rdseedintrin.h>
+#endif
+
+#ifdef __PRFCHW__
+#include <prfchwintrin.h>
+#endif
+
+#ifdef __SSE4A__
+#include <ammintrin.h>
+#endif
+
+#ifdef __FMA4__
+#include <fma4intrin.h>
+#endif
+
+#ifdef __XOP__
+#include <xopintrin.h>
+#endif
+
+#ifdef __TBM__
+#include <tbmintrin.h>
+#endif
+
+#ifdef __F16C__
+#include <f16cintrin.h>
+#endif
+
+/* FIXME: LWP */
+
+#endif /* __X86INTRIN_H */
diff --git a/lib/clang/3.5.2/include/xmmintrin.h b/lib/clang/3.5.2/include/xmmintrin.h
new file mode 100644
index 0000000..c9befcb
--- /dev/null
+++ b/lib/clang/3.5.2/include/xmmintrin.h
@@ -0,0 +1,1003 @@
+/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+ 
+#ifndef __XMMINTRIN_H
+#define __XMMINTRIN_H
+ 
+#ifndef __SSE__
+#error "SSE instruction set not enabled"
+#else
+
+#include <mmintrin.h>
+
+typedef int __v4si __attribute__((__vector_size__(16)));
+typedef float __v4sf __attribute__((__vector_size__(16)));
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+/* This header should only be included in a hosted environment as it depends on
+ * a standard library to provide allocation routines. */
+#if __STDC_HOSTED__
+#include <mm_malloc.h>
+#endif
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_add_ss(__m128 __a, __m128 __b)
+{
+  __a[0] += __b[0];
+  return __a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_add_ps(__m128 __a, __m128 __b)
+{
+  return __a + __b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_ss(__m128 __a, __m128 __b)
+{
+  __a[0] -= __b[0];
+  return __a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sub_ps(__m128 __a, __m128 __b)
+{
+  return __a - __b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_ss(__m128 __a, __m128 __b)
+{
+  __a[0] *= __b[0];
+  return __a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_mul_ps(__m128 __a, __m128 __b)
+{
+  return __a * __b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_div_ss(__m128 __a, __m128 __b)
+{
+  __a[0] /= __b[0];
+  return __a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_div_ps(__m128 __a, __m128 __b)
+{
+  return __a / __b;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_ss(__m128 __a)
+{
+  __m128 __c = __builtin_ia32_sqrtss(__a);
+  return (__m128) { __c[0], __a[1], __a[2], __a[3] };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_sqrt_ps(__m128 __a)
+{
+  return __builtin_ia32_sqrtps(__a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rcp_ss(__m128 __a)
+{
+  __m128 __c = __builtin_ia32_rcpss(__a);
+  return (__m128) { __c[0], __a[1], __a[2], __a[3] };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rcp_ps(__m128 __a)
+{
+  return __builtin_ia32_rcpps(__a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rsqrt_ss(__m128 __a)
+{
+  __m128 __c = __builtin_ia32_rsqrtss(__a);
+  return (__m128) { __c[0], __a[1], __a[2], __a[3] };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_rsqrt_ps(__m128 __a)
+{
+  return __builtin_ia32_rsqrtps(__a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_min_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_minss(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_min_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_minps(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_max_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_maxss(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_max_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_maxps(__a, __b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_and_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)((__v4si)__a & (__v4si)__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_andnot_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)(~(__v4si)__a & (__v4si)__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_or_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)((__v4si)__a | (__v4si)__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_xor_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)((__v4si)__a ^ (__v4si)__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpeq_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmplt_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmple_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_shufflevector(__a,
+                                         __builtin_ia32_cmpss(__b, __a, 1),
+                                         4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpgt_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__b, __a, 1);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_shufflevector(__a,
+                                         __builtin_ia32_cmpss(__b, __a, 2),
+                                         4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpge_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__b, __a, 2);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 4);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpneq_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 4);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnlt_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnle_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_shufflevector(__a,
+                                         __builtin_ia32_cmpss(__b, __a, 5),
+                                         4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpngt_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__b, __a, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_shufflevector(__a,
+                                         __builtin_ia32_cmpss(__b, __a, 6),
+                                         4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpnge_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__b, __a, 6);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpord_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_ss(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpss(__a, __b, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cmpunord_ps(__m128 __a, __m128 __b)
+{
+  return (__m128)__builtin_ia32_cmpps(__a, __b, 3);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comieq_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comieq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comilt_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comilt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comile_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comile(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comigt_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comigt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comige_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comige(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_comineq_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_comineq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomieq_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomieq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomilt_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomilt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomile_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomile(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomigt_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomigt(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomige_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomige(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_ucomineq_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_ia32_ucomineq(__a, __b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_si32(__m128 __a)
+{
+  return __builtin_ia32_cvtss2si(__a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_ss2si(__m128 __a)
+{
+  return _mm_cvtss_si32(__a);
+}
+
+#ifdef __x86_64__
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_si64(__m128 __a)
+{
+  return __builtin_ia32_cvtss2si64(__a);
+}
+
+#endif
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi32(__m128 __a)
+{
+  return (__m64)__builtin_ia32_cvtps2pi(__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_ps2pi(__m128 __a)
+{
+  return _mm_cvtps_pi32(__a);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvttss_si32(__m128 __a)
+{
+  return __a[0];
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_cvtt_ss2si(__m128 __a)
+{
+  return _mm_cvttss_si32(__a);
+}
+
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+_mm_cvttss_si64(__m128 __a)
+{
+  return __a[0];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvttps_pi32(__m128 __a)
+{
+  return (__m64)__builtin_ia32_cvttps2pi(__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtt_ps2pi(__m128 __a)
+{
+  return _mm_cvttps_pi32(__a);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi32_ss(__m128 __a, int __b)
+{
+  __a[0] = __b;
+  return __a;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_si2ss(__m128 __a, int __b)
+{
+  return _mm_cvtsi32_ss(__a, __b);
+}
+
+#ifdef __x86_64__
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtsi64_ss(__m128 __a, long long __b)
+{
+  __a[0] = __b;
+  return __a;
+}
+
+#endif
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32_ps(__m128 __a, __m64 __b)
+{
+  return __builtin_ia32_cvtpi2ps(__a, (__v2si)__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvt_pi2ps(__m128 __a, __m64 __b)
+{
+  return _mm_cvtpi32_ps(__a, __b);
+}
+
+static __inline__ float __attribute__((__always_inline__, __nodebug__))
+_mm_cvtss_f32(__m128 __a)
+{
+  return __a[0];
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadh_pi(__m128 __a, const __m64 *__p)
+{
+  typedef float __mm_loadh_pi_v2f32 __attribute__((__vector_size__(8)));
+  struct __mm_loadh_pi_struct {
+    __mm_loadh_pi_v2f32 __u;
+  } __attribute__((__packed__, __may_alias__));
+  __mm_loadh_pi_v2f32 __b = ((struct __mm_loadh_pi_struct*)__p)->__u;
+  __m128 __bb = __builtin_shufflevector(__b, __b, 0, 1, 0, 1);
+  return __builtin_shufflevector(__a, __bb, 0, 1, 4, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadl_pi(__m128 __a, const __m64 *__p)
+{
+  typedef float __mm_loadl_pi_v2f32 __attribute__((__vector_size__(8)));
+  struct __mm_loadl_pi_struct {
+    __mm_loadl_pi_v2f32 __u;
+  } __attribute__((__packed__, __may_alias__));
+  __mm_loadl_pi_v2f32 __b = ((struct __mm_loadl_pi_struct*)__p)->__u;
+  __m128 __bb = __builtin_shufflevector(__b, __b, 0, 1, 0, 1);
+  return __builtin_shufflevector(__a, __bb, 4, 5, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load_ss(const float *__p)
+{
+  struct __mm_load_ss_struct {
+    float __u;
+  } __attribute__((__packed__, __may_alias__));
+  float __u = ((struct __mm_load_ss_struct*)__p)->__u;
+  return (__m128){ __u, 0, 0, 0 };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load1_ps(const float *__p)
+{
+  struct __mm_load1_ps_struct {
+    float __u;
+  } __attribute__((__packed__, __may_alias__));
+  float __u = ((struct __mm_load1_ps_struct*)__p)->__u;
+  return (__m128){ __u, __u, __u, __u };
+}
+
+#define        _mm_load_ps1(p) _mm_load1_ps(p)
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_load_ps(const float *__p)
+{
+  return *(__m128*)__p;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadu_ps(const float *__p)
+{
+  struct __loadu_ps {
+    __m128 __v;
+  } __attribute__((__packed__, __may_alias__));
+  return ((struct __loadu_ps*)__p)->__v;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_loadr_ps(const float *__p)
+{
+  __m128 __a = _mm_load_ps(__p);
+  return __builtin_shufflevector(__a, __a, 3, 2, 1, 0);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ss(float __w)
+{
+  return (__m128){ __w, 0, 0, 0 };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set1_ps(float __w)
+{
+  return (__m128){ __w, __w, __w, __w };
+}
+
+/* Microsoft specific. */
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ps1(float __w)
+{
+    return _mm_set1_ps(__w);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_set_ps(float __z, float __y, float __x, float __w)
+{
+  return (__m128){ __w, __x, __y, __z };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_setr_ps(float __z, float __y, float __x, float __w)
+{
+  return (__m128){ __z, __y, __x, __w };
+}
+
+static __inline__ __m128 __attribute__((__always_inline__))
+_mm_setzero_ps(void)
+{
+  return (__m128){ 0, 0, 0, 0 };
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_storeh_pi(__m64 *__p, __m128 __a)
+{
+  __builtin_ia32_storehps((__v2si *)__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_storel_pi(__m64 *__p, __m128 __a)
+{
+  __builtin_ia32_storelps((__v2si *)__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__))
+_mm_store_ss(float *__p, __m128 __a)
+{
+  struct __mm_store_ss_struct {
+    float __u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store_ss_struct*)__p)->__u = __a[0];
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storeu_ps(float *__p, __m128 __a)
+{
+  __builtin_ia32_storeups(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store1_ps(float *__p, __m128 __a)
+{
+  __a = __builtin_shufflevector(__a, __a, 0, 0, 0, 0);
+  _mm_storeu_ps(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_ps1(float *__p, __m128 __a)
+{
+    return _mm_store1_ps(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_store_ps(float *__p, __m128 __a)
+{
+  *(__m128 *)__p = __a;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_storer_ps(float *__p, __m128 __a)
+{
+  __a = __builtin_shufflevector(__a, __a, 3, 2, 1, 0);
+  _mm_store_ps(__p, __a);
+}
+
+#define _MM_HINT_T0 3
+#define _MM_HINT_T1 2
+#define _MM_HINT_T2 1
+#define _MM_HINT_NTA 0
+
+#ifndef _MSC_VER
+/* FIXME: We have to #define this because "sel" must be a constant integer, and
+   Sema doesn't do any form of constant propagation yet. */
+
+#define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel)))
+#endif
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_pi(__m64 *__p, __m64 __a)
+{
+  __builtin_ia32_movntq(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_stream_ps(float *__p, __m128 __a)
+{
+  __builtin_ia32_movntps(__p, __a);
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_sfence(void)
+{
+  __builtin_ia32_sfence();
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_extract_pi16(__m64 __a, int __n)
+{
+  __v4hi __b = (__v4hi)__a;
+  return (unsigned short)__b[__n & 3];
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_insert_pi16(__m64 __a, int __d, int __n)
+{
+   __v4hi __b = (__v4hi)__a;
+   __b[__n & 3] = __d;
+   return (__m64)__b;
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_max_pi16(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pmaxsw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_max_pu8(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pmaxub((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_min_pi16(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pminsw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_min_pu8(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pminub((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_pi8(__m64 __a)
+{
+  return __builtin_ia32_pmovmskb((__v8qi)__a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_mulhi_pu16(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pmulhuw((__v4hi)__a, (__v4hi)__b);
+}
+
+#define _mm_shuffle_pi16(a, n) __extension__ ({ \
+  __m64 __a = (a); \
+  (__m64)__builtin_ia32_pshufw((__v4hi)__a, (n)); })
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_maskmove_si64(__m64 __d, __m64 __n, char *__p)
+{
+  __builtin_ia32_maskmovq((__v8qi)__d, (__v8qi)__n, __p);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_avg_pu8(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pavgb((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_avg_pu16(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_pavgw((__v4hi)__a, (__v4hi)__b);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_sad_pu8(__m64 __a, __m64 __b)
+{
+  return (__m64)__builtin_ia32_psadbw((__v8qi)__a, (__v8qi)__b);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_mm_getcsr(void)
+{
+  return __builtin_ia32_stmxcsr();
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+_mm_setcsr(unsigned int __i)
+{
+  __builtin_ia32_ldmxcsr(__i);
+}
+
+#define _mm_shuffle_ps(a, b, mask) __extension__ ({ \
+  __m128 __a = (a); \
+  __m128 __b = (b); \
+  (__m128)__builtin_shufflevector((__v4sf)__a, (__v4sf)__b, \
+                                  (mask) & 0x3, ((mask) & 0xc) >> 2, \
+                                  (((mask) & 0x30) >> 4) + 4, \
+                                  (((mask) & 0xc0) >> 6) + 4); })
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_unpackhi_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_shufflevector(__a, __b, 2, 6, 3, 7);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_unpacklo_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_shufflevector(__a, __b, 0, 4, 1, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_move_ss(__m128 __a, __m128 __b)
+{
+  return __builtin_shufflevector(__a, __b, 4, 1, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movehl_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_shufflevector(__a, __b, 6, 7, 2, 3);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_movelh_ps(__m128 __a, __m128 __b)
+{
+  return __builtin_shufflevector(__a, __b, 0, 1, 4, 5);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi16_ps(__m64 __a)
+{
+  __m64 __b, __c;
+  __m128 __r;
+
+  __b = _mm_setzero_si64();
+  __b = _mm_cmpgt_pi16(__b, __a);
+  __c = _mm_unpackhi_pi16(__a, __b);
+  __r = _mm_setzero_ps();
+  __r = _mm_cvtpi32_ps(__r, __c);
+  __r = _mm_movelh_ps(__r, __r);
+  __c = _mm_unpacklo_pi16(__a, __b);
+  __r = _mm_cvtpi32_ps(__r, __c);
+
+  return __r;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpu16_ps(__m64 __a)
+{
+  __m64 __b, __c;
+  __m128 __r;
+
+  __b = _mm_setzero_si64();
+  __c = _mm_unpackhi_pi16(__a, __b);
+  __r = _mm_setzero_ps();
+  __r = _mm_cvtpi32_ps(__r, __c);
+  __r = _mm_movelh_ps(__r, __r);
+  __c = _mm_unpacklo_pi16(__a, __b);
+  __r = _mm_cvtpi32_ps(__r, __c);
+
+  return __r;
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi8_ps(__m64 __a)
+{
+  __m64 __b;
+  
+  __b = _mm_setzero_si64();
+  __b = _mm_cmpgt_pi8(__b, __a);
+  __b = _mm_unpacklo_pi8(__a, __b);
+
+  return _mm_cvtpi16_ps(__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpu8_ps(__m64 __a)
+{
+  __m64 __b;
+  
+  __b = _mm_setzero_si64();
+  __b = _mm_unpacklo_pi8(__a, __b);
+
+  return _mm_cvtpi16_ps(__b);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtpi32x2_ps(__m64 __a, __m64 __b)
+{
+  __m128 __c;
+  
+  __c = _mm_setzero_ps();
+  __c = _mm_cvtpi32_ps(__c, __b);
+  __c = _mm_movelh_ps(__c, __c);
+
+  return _mm_cvtpi32_ps(__c, __a);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi16(__m128 __a)
+{
+  __m64 __b, __c;
+  
+  __b = _mm_cvtps_pi32(__a);
+  __a = _mm_movehl_ps(__a, __a);
+  __c = _mm_cvtps_pi32(__a);
+  
+  return _mm_packs_pi32(__b, __c);
+}
+
+static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
+_mm_cvtps_pi8(__m128 __a)
+{
+  __m64 __b, __c;
+  
+  __b = _mm_cvtps_pi16(__a);
+  __c = _mm_setzero_si64();
+  
+  return _mm_packs_pi16(__b, __c);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_mm_movemask_ps(__m128 __a)
+{
+  return __builtin_ia32_movmskps(__a);
+}
+
+#define _MM_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
+
+#define _MM_EXCEPT_INVALID    (0x0001)
+#define _MM_EXCEPT_DENORM     (0x0002)
+#define _MM_EXCEPT_DIV_ZERO   (0x0004)
+#define _MM_EXCEPT_OVERFLOW   (0x0008)
+#define _MM_EXCEPT_UNDERFLOW  (0x0010)
+#define _MM_EXCEPT_INEXACT    (0x0020)
+#define _MM_EXCEPT_MASK       (0x003f)
+
+#define _MM_MASK_INVALID      (0x0080)
+#define _MM_MASK_DENORM       (0x0100)
+#define _MM_MASK_DIV_ZERO     (0x0200)
+#define _MM_MASK_OVERFLOW     (0x0400)
+#define _MM_MASK_UNDERFLOW    (0x0800)
+#define _MM_MASK_INEXACT      (0x1000)
+#define _MM_MASK_MASK         (0x1f80)
+
+#define _MM_ROUND_NEAREST     (0x0000)
+#define _MM_ROUND_DOWN        (0x2000)
+#define _MM_ROUND_UP          (0x4000)
+#define _MM_ROUND_TOWARD_ZERO (0x6000)
+#define _MM_ROUND_MASK        (0x6000)
+
+#define _MM_FLUSH_ZERO_MASK   (0x8000)
+#define _MM_FLUSH_ZERO_ON     (0x8000)
+#define _MM_FLUSH_ZERO_OFF    (0x0000)
+
+#define _MM_GET_EXCEPTION_MASK() (_mm_getcsr() & _MM_MASK_MASK)
+#define _MM_GET_EXCEPTION_STATE() (_mm_getcsr() & _MM_EXCEPT_MASK)
+#define _MM_GET_FLUSH_ZERO_MODE() (_mm_getcsr() & _MM_FLUSH_ZERO_MASK)
+#define _MM_GET_ROUNDING_MODE() (_mm_getcsr() & _MM_ROUND_MASK)
+
+#define _MM_SET_EXCEPTION_MASK(x) (_mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (x)))
+#define _MM_SET_EXCEPTION_STATE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_EXCEPT_MASK) | (x)))
+#define _MM_SET_FLUSH_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_FLUSH_ZERO_MASK) | (x)))
+#define _MM_SET_ROUNDING_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_ROUND_MASK) | (x)))
+
+#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \
+do { \
+  __m128 tmp3, tmp2, tmp1, tmp0; \
+  tmp0 = _mm_unpacklo_ps((row0), (row1)); \
+  tmp2 = _mm_unpacklo_ps((row2), (row3)); \
+  tmp1 = _mm_unpackhi_ps((row0), (row1)); \
+  tmp3 = _mm_unpackhi_ps((row2), (row3)); \
+  (row0) = _mm_movelh_ps(tmp0, tmp2); \
+  (row1) = _mm_movehl_ps(tmp2, tmp0); \
+  (row2) = _mm_movelh_ps(tmp1, tmp3); \
+  (row3) = _mm_movehl_ps(tmp3, tmp1); \
+} while (0)
+
+/* Aliases for compatibility. */
+#define _m_pextrw _mm_extract_pi16
+#define _m_pinsrw _mm_insert_pi16
+#define _m_pmaxsw _mm_max_pi16
+#define _m_pmaxub _mm_max_pu8
+#define _m_pminsw _mm_min_pi16
+#define _m_pminub _mm_min_pu8
+#define _m_pmovmskb _mm_movemask_pi8
+#define _m_pmulhuw _mm_mulhi_pu16
+#define _m_pshufw _mm_shuffle_pi16
+#define _m_maskmovq _mm_maskmove_si64
+#define _m_pavgb _mm_avg_pu8
+#define _m_pavgw _mm_avg_pu16
+#define _m_psadbw _mm_sad_pu8
+#define _m_ _mm_
+#define _m_ _mm_
+
+/* Ugly hack for backwards-compatibility (compatible with gcc) */
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#endif /* __SSE__ */
+
+#endif /* __XMMINTRIN_H */
diff --git a/lib/clang/3.5.2/include/xopintrin.h b/lib/clang/3.5.2/include/xopintrin.h
new file mode 100644
index 0000000..cc94ca0
--- /dev/null
+++ b/lib/clang/3.5.2/include/xopintrin.h
@@ -0,0 +1,804 @@
+/*===---- xopintrin.h - XOP intrinsics -------------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86INTRIN_H
+#error "Never use <xopintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __XOPINTRIN_H
+#define __XOPINTRIN_H
+
+#ifndef __XOP__
+# error "XOP instruction set is not enabled"
+#else
+
+#include <fma4intrin.h>
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacssww((__v8hi)__A, (__v8hi)__B, (__v8hi)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_macc_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacsww((__v8hi)__A, (__v8hi)__B, (__v8hi)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccsd_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacsswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccd_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccs_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacssdd((__v4si)__A, (__v4si)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_macc_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacsdd((__v4si)__A, (__v4si)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccslo_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacssdql((__v4si)__A, (__v4si)__B, (__v2di)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_macclo_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacsdql((__v4si)__A, (__v4si)__B, (__v2di)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maccshi_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacssdqh((__v4si)__A, (__v4si)__B, (__v2di)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_macchi_epi32(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmacsdqh((__v4si)__A, (__v4si)__B, (__v2di)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maddsd_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmadcsswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_maddd_epi16(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpmadcswd((__v8hi)__A, (__v8hi)__B, (__v4si)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddw_epi8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddbw((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddd_epi8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddbd((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epi8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddbq((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddd_epi16(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddwd((__v8hi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epi16(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddwq((__v8hi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epi32(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphadddq((__v4si)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddw_epu8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddubw((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddd_epu8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddubd((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epu8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddubq((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddd_epu16(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphadduwd((__v8hi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epu16(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphadduwq((__v8hi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_haddq_epu32(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphaddudq((__v4si)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsubw_epi8(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphsubbw((__v16qi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsubd_epi16(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphsubwd((__v8hi)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_hsubq_epi32(__m128i __A)
+{
+  return (__m128i)__builtin_ia32_vphsubdq((__v4si)__A);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_cmov_si128(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpcmov(__A, __B, __C);
+}
+
+static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
+_mm256_cmov_si256(__m256i __A, __m256i __B, __m256i __C)
+{
+  return (__m256i)__builtin_ia32_vpcmov_256(__A, __B, __C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_perm_epi8(__m128i __A, __m128i __B, __m128i __C)
+{
+  return (__m128i)__builtin_ia32_vpperm((__v16qi)__A, (__v16qi)__B, (__v16qi)__C);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_rot_epi8(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vprotb((__v16qi)__A, (__v16qi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_rot_epi16(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vprotw((__v8hi)__A, (__v8hi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_rot_epi32(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vprotd((__v4si)__A, (__v4si)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_rot_epi64(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vprotq((__v2di)__A, (__v2di)__B);
+}
+
+#define _mm_roti_epi8(A, N) __extension__ ({ \
+  __m128i __A = (A); \
+  (__m128i)__builtin_ia32_vprotbi((__v16qi)__A, (N)); })
+
+#define _mm_roti_epi16(A, N) __extension__ ({ \
+  __m128i __A = (A); \
+  (__m128i)__builtin_ia32_vprotwi((__v8hi)__A, (N)); })
+
+#define _mm_roti_epi32(A, N) __extension__ ({ \
+  __m128i __A = (A); \
+  (__m128i)__builtin_ia32_vprotdi((__v4si)__A, (N)); })
+
+#define _mm_roti_epi64(A, N) __extension__ ({ \
+  __m128i __A = (A); \
+  (__m128i)__builtin_ia32_vprotqi((__v2di)__A, (N)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shl_epi8(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshlb((__v16qi)__A, (__v16qi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shl_epi16(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshlw((__v8hi)__A, (__v8hi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shl_epi32(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshld((__v4si)__A, (__v4si)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_shl_epi64(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshlq((__v2di)__A, (__v2di)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha_epi8(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshab((__v16qi)__A, (__v16qi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha_epi16(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshaw((__v8hi)__A, (__v8hi)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha_epi32(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshad((__v4si)__A, (__v4si)__B);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_sha_epi64(__m128i __A, __m128i __B)
+{
+  return (__m128i)__builtin_ia32_vpshaq((__v2di)__A, (__v2di)__B);
+}
+
+#define _mm_com_epu8(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomub((__v16qi)__A, (__v16qi)__B, (N)); })
+
+#define _mm_com_epu16(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomuw((__v8hi)__A, (__v8hi)__B, (N)); })
+
+#define _mm_com_epu32(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomud((__v4si)__A, (__v4si)__B, (N)); })
+
+#define _mm_com_epu64(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomuq((__v2di)__A, (__v2di)__B, (N)); })
+
+#define _mm_com_epi8(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomb((__v16qi)__A, (__v16qi)__B, (N)); })
+
+#define _mm_com_epi16(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomw((__v8hi)__A, (__v8hi)__B, (N)); })
+
+#define _mm_com_epi32(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomd((__v4si)__A, (__v4si)__B, (N)); })
+
+#define _mm_com_epi64(A, B, N) __extension__ ({ \
+  __m128i __A = (A); \
+  __m128i __B = (B); \
+  (__m128i)__builtin_ia32_vpcomq((__v2di)__A, (__v2di)__B, (N)); })
+
+#define _MM_PCOMCTRL_LT    0
+#define _MM_PCOMCTRL_LE    1
+#define _MM_PCOMCTRL_GT    2
+#define _MM_PCOMCTRL_GE    3
+#define _MM_PCOMCTRL_EQ    4
+#define _MM_PCOMCTRL_NEQ   5
+#define _MM_PCOMCTRL_FALSE 6
+#define _MM_PCOMCTRL_TRUE  7
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epu8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu8(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epu16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu16(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epu32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu32(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epu64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epu64(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epi8(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi8(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epi16(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi16(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epi32(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi32(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comlt_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_LT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comle_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_LE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comgt_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_GT);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comge_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_GE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comeq_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_EQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comneq_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_NEQ);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comfalse_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_FALSE);
+}
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_comtrue_epi64(__m128i __A, __m128i __B)
+{
+  return _mm_com_epi64(__A, __B, _MM_PCOMCTRL_TRUE);
+}
+
+#define _mm_permute2_pd(X, Y, C, I) __extension__ ({ \
+  __m128d __X = (X); \
+  __m128d __Y = (Y); \
+  __m128i __C = (C); \
+  (__m128d)__builtin_ia32_vpermil2pd((__v2df)__X, (__v2df)__Y, \
+                                     (__v2di)__C, (I)); })
+
+#define _mm256_permute2_pd(X, Y, C, I) __extension__ ({ \
+  __m256d __X = (X); \
+  __m256d __Y = (Y); \
+  __m256i __C = (C); \
+  (__m256d)__builtin_ia32_vpermil2pd256((__v4df)__X, (__v4df)__Y, \
+                                        (__v4di)__C, (I)); })
+
+#define _mm_permute2_ps(X, Y, C, I) __extension__ ({ \
+  __m128 __X = (X); \
+  __m128 __Y = (Y); \
+  __m128i __C = (C); \
+  (__m128)__builtin_ia32_vpermil2ps((__v4sf)__X, (__v4sf)__Y, \
+                                    (__v4si)__C, (I)); })
+
+#define _mm256_permute2_ps(X, Y, C, I) __extension__ ({ \
+  __m256 __X = (X); \
+  __m256 __Y = (Y); \
+  __m256i __C = (C); \
+  (__m256)__builtin_ia32_vpermil2ps256((__v8sf)__X, (__v8sf)__Y, \
+                                       (__v8si)__C, (I)); })
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_frcz_ss(__m128 __A)
+{
+  return (__m128)__builtin_ia32_vfrczss((__v4sf)__A);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_frcz_sd(__m128d __A)
+{
+  return (__m128d)__builtin_ia32_vfrczsd((__v2df)__A);
+}
+
+static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
+_mm_frcz_ps(__m128 __A)
+{
+  return (__m128)__builtin_ia32_vfrczps((__v4sf)__A);
+}
+
+static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
+_mm_frcz_pd(__m128d __A)
+{
+  return (__m128d)__builtin_ia32_vfrczpd((__v2df)__A);
+}
+
+static __inline__ __m256 __attribute__((__always_inline__, __nodebug__))
+_mm256_frcz_ps(__m256 __A)
+{
+  return (__m256)__builtin_ia32_vfrczps256((__v8sf)__A);
+}
+
+static __inline__ __m256d __attribute__((__always_inline__, __nodebug__))
+_mm256_frcz_pd(__m256d __A)
+{
+  return (__m256d)__builtin_ia32_vfrczpd256((__v4df)__A);
+}
+
+#endif /* __XOP__ */
+
+#endif /* __XOPINTRIN_H */
diff --git a/lib/clang/3.5.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib b/lib/clang/3.5.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
new file mode 100755
index 0000000..bb71299
--- /dev/null
+++ b/lib/clang/3.5.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
Binary files differ
diff --git a/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-i386.a b/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-i386.a
new file mode 100644
index 0000000..1323e5d
--- /dev/null
+++ b/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-i386.a
Binary files differ
diff --git a/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-x86_64.a b/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-x86_64.a
new file mode 100644
index 0000000..aec2dd1
--- /dev/null
+++ b/lib/clang/3.5.2/lib/darwin/libclang_rt.builtins-x86_64.a
Binary files differ
diff --git a/lib/clang/3.5.2/lib/darwin/libclang_rt.profile_osx.a b/lib/clang/3.5.2/lib/darwin/libclang_rt.profile_osx.a
new file mode 100644
index 0000000..f25df56
--- /dev/null
+++ b/lib/clang/3.5.2/lib/darwin/libclang_rt.profile_osx.a
Binary files differ
diff --git a/lib/clang/3.5.2/lib/darwin/libclang_rt.ubsan_osx.a b/lib/clang/3.5.2/lib/darwin/libclang_rt.ubsan_osx.a
new file mode 100644
index 0000000..7d2a421
--- /dev/null
+++ b/lib/clang/3.5.2/lib/darwin/libclang_rt.ubsan_osx.a
Binary files differ
diff --git a/lib/libLLVMAnalysis.dylib b/lib/libLLVMAnalysis.dylib
new file mode 100755
index 0000000..a325bbc
--- /dev/null
+++ b/lib/libLLVMAnalysis.dylib
Binary files differ
diff --git a/lib/libLLVMAsmParser.dylib b/lib/libLLVMAsmParser.dylib
new file mode 100755
index 0000000..77941e0
--- /dev/null
+++ b/lib/libLLVMAsmParser.dylib
Binary files differ
diff --git a/lib/libLLVMAsmPrinter.dylib b/lib/libLLVMAsmPrinter.dylib
new file mode 100755
index 0000000..7eb8e06
--- /dev/null
+++ b/lib/libLLVMAsmPrinter.dylib
Binary files differ
diff --git a/lib/libLLVMBitReader.dylib b/lib/libLLVMBitReader.dylib
new file mode 100755
index 0000000..b092e53
--- /dev/null
+++ b/lib/libLLVMBitReader.dylib
Binary files differ
diff --git a/lib/libLLVMBitWriter.dylib b/lib/libLLVMBitWriter.dylib
new file mode 100755
index 0000000..8b4453f
--- /dev/null
+++ b/lib/libLLVMBitWriter.dylib
Binary files differ
diff --git a/lib/libLLVMCodeGen.dylib b/lib/libLLVMCodeGen.dylib
new file mode 100755
index 0000000..470165b
--- /dev/null
+++ b/lib/libLLVMCodeGen.dylib
Binary files differ
diff --git a/lib/libLLVMCore.dylib b/lib/libLLVMCore.dylib
new file mode 100755
index 0000000..fab3c5c
--- /dev/null
+++ b/lib/libLLVMCore.dylib
Binary files differ
diff --git a/lib/libLLVMDebugInfo.dylib b/lib/libLLVMDebugInfo.dylib
new file mode 100755
index 0000000..04f13d9
--- /dev/null
+++ b/lib/libLLVMDebugInfo.dylib
Binary files differ
diff --git a/lib/libLLVMExecutionEngine.dylib b/lib/libLLVMExecutionEngine.dylib
new file mode 100755
index 0000000..a633503
--- /dev/null
+++ b/lib/libLLVMExecutionEngine.dylib
Binary files differ
diff --git a/lib/libLLVMIRReader.dylib b/lib/libLLVMIRReader.dylib
new file mode 100755
index 0000000..9d80f3a
--- /dev/null
+++ b/lib/libLLVMIRReader.dylib
Binary files differ
diff --git a/lib/libLLVMInstCombine.dylib b/lib/libLLVMInstCombine.dylib
new file mode 100755
index 0000000..928128e
--- /dev/null
+++ b/lib/libLLVMInstCombine.dylib
Binary files differ
diff --git a/lib/libLLVMInstrumentation.dylib b/lib/libLLVMInstrumentation.dylib
new file mode 100755
index 0000000..0755ede
--- /dev/null
+++ b/lib/libLLVMInstrumentation.dylib
Binary files differ
diff --git a/lib/libLLVMInterpreter.dylib b/lib/libLLVMInterpreter.dylib
new file mode 100755
index 0000000..d7dcb14
--- /dev/null
+++ b/lib/libLLVMInterpreter.dylib
Binary files differ
diff --git a/lib/libLLVMJIT.dylib b/lib/libLLVMJIT.dylib
new file mode 100755
index 0000000..02f7395
--- /dev/null
+++ b/lib/libLLVMJIT.dylib
Binary files differ
diff --git a/lib/libLLVMLTO.dylib b/lib/libLLVMLTO.dylib
new file mode 100755
index 0000000..352ce8a
--- /dev/null
+++ b/lib/libLLVMLTO.dylib
Binary files differ
diff --git a/lib/libLLVMLineEditor.dylib b/lib/libLLVMLineEditor.dylib
new file mode 100755
index 0000000..8748e5a
--- /dev/null
+++ b/lib/libLLVMLineEditor.dylib
Binary files differ
diff --git a/lib/libLLVMLinker.dylib b/lib/libLLVMLinker.dylib
new file mode 100755
index 0000000..015c3ce
--- /dev/null
+++ b/lib/libLLVMLinker.dylib
Binary files differ
diff --git a/lib/libLLVMMC.dylib b/lib/libLLVMMC.dylib
new file mode 100755
index 0000000..1f3e058
--- /dev/null
+++ b/lib/libLLVMMC.dylib
Binary files differ
diff --git a/lib/libLLVMMCAnalysis.dylib b/lib/libLLVMMCAnalysis.dylib
new file mode 100755
index 0000000..23f9c99
--- /dev/null
+++ b/lib/libLLVMMCAnalysis.dylib
Binary files differ
diff --git a/lib/libLLVMMCDisassembler.dylib b/lib/libLLVMMCDisassembler.dylib
new file mode 100755
index 0000000..79b2292
--- /dev/null
+++ b/lib/libLLVMMCDisassembler.dylib
Binary files differ
diff --git a/lib/libLLVMMCJIT.dylib b/lib/libLLVMMCJIT.dylib
new file mode 100755
index 0000000..eb83b3f
--- /dev/null
+++ b/lib/libLLVMMCJIT.dylib
Binary files differ
diff --git a/lib/libLLVMMCParser.dylib b/lib/libLLVMMCParser.dylib
new file mode 100755
index 0000000..7e0e33e
--- /dev/null
+++ b/lib/libLLVMMCParser.dylib
Binary files differ
diff --git a/lib/libLLVMObjCARCOpts.dylib b/lib/libLLVMObjCARCOpts.dylib
new file mode 100755
index 0000000..32f6be2
--- /dev/null
+++ b/lib/libLLVMObjCARCOpts.dylib
Binary files differ
diff --git a/lib/libLLVMObject.dylib b/lib/libLLVMObject.dylib
new file mode 100755
index 0000000..70a4a4f
--- /dev/null
+++ b/lib/libLLVMObject.dylib
Binary files differ
diff --git a/lib/libLLVMOption.dylib b/lib/libLLVMOption.dylib
new file mode 100755
index 0000000..02b2036
--- /dev/null
+++ b/lib/libLLVMOption.dylib
Binary files differ
diff --git a/lib/libLLVMProfileData.dylib b/lib/libLLVMProfileData.dylib
new file mode 100755
index 0000000..66eac5b
--- /dev/null
+++ b/lib/libLLVMProfileData.dylib
Binary files differ
diff --git a/lib/libLLVMRuntimeDyld.dylib b/lib/libLLVMRuntimeDyld.dylib
new file mode 100755
index 0000000..0c92b5b
--- /dev/null
+++ b/lib/libLLVMRuntimeDyld.dylib
Binary files differ
diff --git a/lib/libLLVMScalarOpts.dylib b/lib/libLLVMScalarOpts.dylib
new file mode 100755
index 0000000..3f519fc
--- /dev/null
+++ b/lib/libLLVMScalarOpts.dylib
Binary files differ
diff --git a/lib/libLLVMSelectionDAG.dylib b/lib/libLLVMSelectionDAG.dylib
new file mode 100755
index 0000000..6a967c0
--- /dev/null
+++ b/lib/libLLVMSelectionDAG.dylib
Binary files differ
diff --git a/lib/libLLVMSupport.dylib b/lib/libLLVMSupport.dylib
new file mode 100755
index 0000000..1fa6c69
--- /dev/null
+++ b/lib/libLLVMSupport.dylib
Binary files differ
diff --git a/lib/libLLVMTableGen.dylib b/lib/libLLVMTableGen.dylib
new file mode 100755
index 0000000..ab0b0b1
--- /dev/null
+++ b/lib/libLLVMTableGen.dylib
Binary files differ
diff --git a/lib/libLLVMTarget.dylib b/lib/libLLVMTarget.dylib
new file mode 100755
index 0000000..16d314c
--- /dev/null
+++ b/lib/libLLVMTarget.dylib
Binary files differ
diff --git a/lib/libLLVMTransformUtils.dylib b/lib/libLLVMTransformUtils.dylib
new file mode 100755
index 0000000..1d049b1
--- /dev/null
+++ b/lib/libLLVMTransformUtils.dylib
Binary files differ
diff --git a/lib/libLLVMVectorize.dylib b/lib/libLLVMVectorize.dylib
new file mode 100755
index 0000000..59f67d3
--- /dev/null
+++ b/lib/libLLVMVectorize.dylib
Binary files differ
diff --git a/lib/libLLVMX86AsmParser.dylib b/lib/libLLVMX86AsmParser.dylib
new file mode 100755
index 0000000..d8f04ad
--- /dev/null
+++ b/lib/libLLVMX86AsmParser.dylib
Binary files differ
diff --git a/lib/libLLVMX86AsmPrinter.dylib b/lib/libLLVMX86AsmPrinter.dylib
new file mode 100755
index 0000000..b6db017
--- /dev/null
+++ b/lib/libLLVMX86AsmPrinter.dylib
Binary files differ
diff --git a/lib/libLLVMX86CodeGen.dylib b/lib/libLLVMX86CodeGen.dylib
new file mode 100755
index 0000000..aed491a
--- /dev/null
+++ b/lib/libLLVMX86CodeGen.dylib
Binary files differ
diff --git a/lib/libLLVMX86Desc.dylib b/lib/libLLVMX86Desc.dylib
new file mode 100755
index 0000000..bbee0d0
--- /dev/null
+++ b/lib/libLLVMX86Desc.dylib
Binary files differ
diff --git a/lib/libLLVMX86Disassembler.dylib b/lib/libLLVMX86Disassembler.dylib
new file mode 100755
index 0000000..62a3e84
--- /dev/null
+++ b/lib/libLLVMX86Disassembler.dylib
Binary files differ
diff --git a/lib/libLLVMX86Info.dylib b/lib/libLLVMX86Info.dylib
new file mode 100755
index 0000000..4a28f6c
--- /dev/null
+++ b/lib/libLLVMX86Info.dylib
Binary files differ
diff --git a/lib/libLLVMX86Utils.dylib b/lib/libLLVMX86Utils.dylib
new file mode 100755
index 0000000..a292864
--- /dev/null
+++ b/lib/libLLVMX86Utils.dylib
Binary files differ
diff --git a/lib/libLLVMipa.dylib b/lib/libLLVMipa.dylib
new file mode 100755
index 0000000..4dba0fd
--- /dev/null
+++ b/lib/libLLVMipa.dylib
Binary files differ
diff --git a/lib/libLLVMipo.dylib b/lib/libLLVMipo.dylib
new file mode 100755
index 0000000..f573cd6
--- /dev/null
+++ b/lib/libLLVMipo.dylib
Binary files differ
diff --git a/lib/libLTO.dylib b/lib/libLTO.dylib
new file mode 100755
index 0000000..d272987
--- /dev/null
+++ b/lib/libLTO.dylib
Binary files differ
diff --git a/lib/libc++.1.0.dylib b/lib/libc++.1.0.dylib
new file mode 100755
index 0000000..01f2b3d
--- /dev/null
+++ b/lib/libc++.1.0.dylib
Binary files differ
diff --git a/lib/libc++.1.dylib b/lib/libc++.1.dylib
new file mode 120000
index 0000000..ba19581
--- /dev/null
+++ b/lib/libc++.1.dylib
@@ -0,0 +1 @@
+libc++.1.0.dylib
\ No newline at end of file
diff --git a/lib/libc++.dylib b/lib/libc++.dylib
new file mode 120000
index 0000000..b88a46b
--- /dev/null
+++ b/lib/libc++.dylib
@@ -0,0 +1 @@
+libc++.1.dylib
\ No newline at end of file
diff --git a/lib/libc++abi.1.0.dylib b/lib/libc++abi.1.0.dylib
new file mode 100755
index 0000000..fd5d028
--- /dev/null
+++ b/lib/libc++abi.1.0.dylib
Binary files differ
diff --git a/lib/libc++abi.1.dylib b/lib/libc++abi.1.dylib
new file mode 120000
index 0000000..99de5c3
--- /dev/null
+++ b/lib/libc++abi.1.dylib
@@ -0,0 +1 @@
+libc++abi.1.0.dylib
\ No newline at end of file
diff --git a/lib/libc++abi.dylib b/lib/libc++abi.dylib
new file mode 120000
index 0000000..ae34b25
--- /dev/null
+++ b/lib/libc++abi.dylib
@@ -0,0 +1 @@
+libc++abi.1.dylib
\ No newline at end of file
diff --git a/lib/libclang.3.5.dylib b/lib/libclang.3.5.dylib
new file mode 100755
index 0000000..6f3abc8
--- /dev/null
+++ b/lib/libclang.3.5.dylib
Binary files differ
diff --git a/lib/libclang.dylib b/lib/libclang.dylib
new file mode 120000
index 0000000..6616f71
--- /dev/null
+++ b/lib/libclang.dylib
@@ -0,0 +1 @@
+libclang.3.5.dylib
\ No newline at end of file
diff --git a/lib/libclangARCMigrate.dylib b/lib/libclangARCMigrate.dylib
new file mode 100755
index 0000000..846878f
--- /dev/null
+++ b/lib/libclangARCMigrate.dylib
Binary files differ
diff --git a/lib/libclangAST.dylib b/lib/libclangAST.dylib
new file mode 100755
index 0000000..212035f
--- /dev/null
+++ b/lib/libclangAST.dylib
Binary files differ
diff --git a/lib/libclangASTMatchers.dylib b/lib/libclangASTMatchers.dylib
new file mode 100755
index 0000000..1d3de5c
--- /dev/null
+++ b/lib/libclangASTMatchers.dylib
Binary files differ
diff --git a/lib/libclangAnalysis.dylib b/lib/libclangAnalysis.dylib
new file mode 100755
index 0000000..bfda269
--- /dev/null
+++ b/lib/libclangAnalysis.dylib
Binary files differ
diff --git a/lib/libclangApplyReplacements.dylib b/lib/libclangApplyReplacements.dylib
new file mode 100755
index 0000000..95cfd92
--- /dev/null
+++ b/lib/libclangApplyReplacements.dylib
Binary files differ
diff --git a/lib/libclangBasic.dylib b/lib/libclangBasic.dylib
new file mode 100755
index 0000000..afcc245
--- /dev/null
+++ b/lib/libclangBasic.dylib
Binary files differ
diff --git a/lib/libclangCodeGen.dylib b/lib/libclangCodeGen.dylib
new file mode 100755
index 0000000..a520841
--- /dev/null
+++ b/lib/libclangCodeGen.dylib
Binary files differ
diff --git a/lib/libclangDriver.dylib b/lib/libclangDriver.dylib
new file mode 100755
index 0000000..18c9fa0
--- /dev/null
+++ b/lib/libclangDriver.dylib
Binary files differ
diff --git a/lib/libclangDynamicASTMatchers.dylib b/lib/libclangDynamicASTMatchers.dylib
new file mode 100755
index 0000000..85f618c
--- /dev/null
+++ b/lib/libclangDynamicASTMatchers.dylib
Binary files differ
diff --git a/lib/libclangEdit.dylib b/lib/libclangEdit.dylib
new file mode 100755
index 0000000..edd7c2d
--- /dev/null
+++ b/lib/libclangEdit.dylib
Binary files differ
diff --git a/lib/libclangFormat.dylib b/lib/libclangFormat.dylib
new file mode 100755
index 0000000..70d4042
--- /dev/null
+++ b/lib/libclangFormat.dylib
Binary files differ
diff --git a/lib/libclangFrontend.dylib b/lib/libclangFrontend.dylib
new file mode 100755
index 0000000..aaa8107
--- /dev/null
+++ b/lib/libclangFrontend.dylib
Binary files differ
diff --git a/lib/libclangFrontendTool.dylib b/lib/libclangFrontendTool.dylib
new file mode 100755
index 0000000..7901e9b
--- /dev/null
+++ b/lib/libclangFrontendTool.dylib
Binary files differ
diff --git a/lib/libclangIndex.dylib b/lib/libclangIndex.dylib
new file mode 100755
index 0000000..5161313
--- /dev/null
+++ b/lib/libclangIndex.dylib
Binary files differ
diff --git a/lib/libclangLex.dylib b/lib/libclangLex.dylib
new file mode 100755
index 0000000..0f99414
--- /dev/null
+++ b/lib/libclangLex.dylib
Binary files differ
diff --git a/lib/libclangParse.dylib b/lib/libclangParse.dylib
new file mode 100755
index 0000000..dca23dd
--- /dev/null
+++ b/lib/libclangParse.dylib
Binary files differ
diff --git a/lib/libclangQuery.dylib b/lib/libclangQuery.dylib
new file mode 100755
index 0000000..eae62d3
--- /dev/null
+++ b/lib/libclangQuery.dylib
Binary files differ
diff --git a/lib/libclangRewrite.dylib b/lib/libclangRewrite.dylib
new file mode 100755
index 0000000..17a4f21
--- /dev/null
+++ b/lib/libclangRewrite.dylib
Binary files differ
diff --git a/lib/libclangRewriteFrontend.dylib b/lib/libclangRewriteFrontend.dylib
new file mode 100755
index 0000000..1b1818a
--- /dev/null
+++ b/lib/libclangRewriteFrontend.dylib
Binary files differ
diff --git a/lib/libclangSema.dylib b/lib/libclangSema.dylib
new file mode 100755
index 0000000..ef8e579
--- /dev/null
+++ b/lib/libclangSema.dylib
Binary files differ
diff --git a/lib/libclangSerialization.dylib b/lib/libclangSerialization.dylib
new file mode 100755
index 0000000..d5365c5
--- /dev/null
+++ b/lib/libclangSerialization.dylib
Binary files differ
diff --git a/lib/libclangStaticAnalyzerCheckers.dylib b/lib/libclangStaticAnalyzerCheckers.dylib
new file mode 100755
index 0000000..898d8d9
--- /dev/null
+++ b/lib/libclangStaticAnalyzerCheckers.dylib
Binary files differ
diff --git a/lib/libclangStaticAnalyzerCore.dylib b/lib/libclangStaticAnalyzerCore.dylib
new file mode 100755
index 0000000..81a3850
--- /dev/null
+++ b/lib/libclangStaticAnalyzerCore.dylib
Binary files differ
diff --git a/lib/libclangStaticAnalyzerFrontend.dylib b/lib/libclangStaticAnalyzerFrontend.dylib
new file mode 100755
index 0000000..d016c33
--- /dev/null
+++ b/lib/libclangStaticAnalyzerFrontend.dylib
Binary files differ
diff --git a/lib/libclangTidy.dylib b/lib/libclangTidy.dylib
new file mode 100755
index 0000000..75dead3
--- /dev/null
+++ b/lib/libclangTidy.dylib
Binary files differ
diff --git a/lib/libclangTidyGoogleModule.dylib b/lib/libclangTidyGoogleModule.dylib
new file mode 100755
index 0000000..7ca0468
--- /dev/null
+++ b/lib/libclangTidyGoogleModule.dylib
Binary files differ
diff --git a/lib/libclangTidyLLVMModule.dylib b/lib/libclangTidyLLVMModule.dylib
new file mode 100755
index 0000000..a43042b
--- /dev/null
+++ b/lib/libclangTidyLLVMModule.dylib
Binary files differ
diff --git a/lib/libclangTidyMiscModule.dylib b/lib/libclangTidyMiscModule.dylib
new file mode 100755
index 0000000..3023405
--- /dev/null
+++ b/lib/libclangTidyMiscModule.dylib
Binary files differ
diff --git a/lib/libclangTooling.dylib b/lib/libclangTooling.dylib
new file mode 100755
index 0000000..de532bd
--- /dev/null
+++ b/lib/libclangTooling.dylib
Binary files differ
diff --git a/lib/libgtest.dylib b/lib/libgtest.dylib
new file mode 100755
index 0000000..1bb7277
--- /dev/null
+++ b/lib/libgtest.dylib
Binary files differ
diff --git a/lib/libgtest_main.dylib b/lib/libgtest_main.dylib
new file mode 100755
index 0000000..283e57d
--- /dev/null
+++ b/lib/libgtest_main.dylib
Binary files differ
diff --git a/lib/libmodernizeCore.dylib b/lib/libmodernizeCore.dylib
new file mode 100755
index 0000000..fef4e6d
--- /dev/null
+++ b/lib/libmodernizeCore.dylib
Binary files differ